diff --git a/.clang-format b/.clang-format index 253ff136..fb819bb6 100644 --- a/.clang-format +++ b/.clang-format @@ -1,36 +1,160 @@ --- +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: Left +AlignConsecutiveMacros: true +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - CONSTRUCT_EARLY + - DLL_CLASS_EXPORT + - DLL_CLASS_IMPORT + - DLL_EXPORT + - DLL_GLOBAL_EXPORT + - DLL_GLOBAL_IMPORT + - DLL_IMPORT + - EXPLICIT + - FASTCALL + - FMTFUNCTION + - FORCEINLINE + - FORCEINLINE_TEMPLATE + - MULTIPLE_INHERITANCE + - NOINLINE + - NO_VTABLE + - NULLTERMINATED + - PLATFORM_INTERFACE + - RESTRICT + - RESTRICT_FUNC + - SELECTANY + - SELECTOR + - SINGLE_INHERITANCE + - STDCALL + - TEMPLATE_SPEC_STATIC + - TEMPLATE_STATIC +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Allman +BreakBeforeConceptDeclarations: Always +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterComma +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 4 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +Cpp11BracedListStyle: true +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineBeforeAccessModifier: LogicalBlock +FixNamespaceComments: false +ForEachMacros: + - FOR_EACH_CURRENCY + - FOR_EACH_DICT + - FOR_EACH_DICT_FAST + - FOR_EACH_ENTLIST + - FOR_EACH_ENTLIST_HEAD + - FOR_EACH_HASHMAP + - FOR_EACH_HASHMAP_LRU + - FOR_EACH_HASHTABLE + - FOR_EACH_LL + - FOR_EACH_LL_BACK + - FOR_EACH_MAP + - FOR_EACH_MAP_BACK + - FOR_EACH_MAP_FAST + - FOR_EACH_OBJ + - FOR_EACH_PTR_ARRAY + - FOR_EACH_RBTREE_FAST + - FOR_EACH_SUBKEY + - FOR_EACH_TRUE_SUBKEY + - FOR_EACH_UTLRBTREE + - FOR_EACH_VALID_SPLITSCREEN_PLAYER + - FOR_EACH_VALUE + - FOR_EACH_VEC + - FOR_EACH_VEC_BACK +IncludeBlocks: Regroup +IncludeCategories: + - Regex: "cbase.h" + Priority: -1 + - Regex: "stdafx_client.h" + Priority: -1 + - Regex: "stdafx.h" + Priority: -1 + - Regex: "pch_tier0.h" + Priority: -1 + - Regex: "tier0/memdbgon.h" + Priority: 10000 + - Regex: ".*" + Priority: 1 +IndentCaseBlocks: true +IndentCaseLabels: false +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature Language: Cpp -BasedOnStyle: Microsoft -Standard: Cpp11 - -AlignOperands: false - -IndentCaseLabels: 'true' -IndentPPDirectives: BeforeHash -IndentWidth: '4' - -FixNamespaceComments: 'true' +MacroBlockBegin: "^BEGIN_.*|IMPLEMENT_NETWORKCLASS.*$|^IMPLEMENT_CLIENTCLASS.*$|^IMPLEMENT_SERVERCLASS.*$|^CLIENTEFFECT_REGISTER_BEGIN.*$" +MacroBlockEnd: "^END_.*$|^CLIENTEFFECT_REGISTER_END.*$" +MaxEmptyLinesToKeep: 1 NamespaceIndentation: All - -PointerAlignment: Right - -SortIncludes: 'false' - -TabWidth: '4' +PackConstructorInitializers: BinPack +PenaltyReturnTypeOnItsOwnLine: 1000000 +PointerAlignment: Right # todo: change to Left +PPIndentWidth: 1 +ReferenceAlignment: Right # todo: change to Left +ReflowComments: true +RequiresClausePosition: OwnLine +SeparateDefinitionBlocks: Always +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInConditionalStatement: true +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: true +SpacesInSquareBrackets: false +Standard: c++20 +StatementMacros: + - DECLARE_CLIENTCLASS + - DECLARE_CLIENTCLASS_NOBASE + - DECLARE_SERVERCLASS + - DECLARE_SERVERCLASS_NOBASE + - IMPLEMENT_CLIENTCLASS + - IMPLEMENT_SERVERCLASS + - NOTE_UNUSED +TabWidth: 4 UseTab: Always +UseCRLF: false +WhitespaceSensitiveMacros: + - MKSTRING -AccessModifierOffset: -4 - -SpacesInAngles: 'false' -SpacesInCStyleCastParentheses: 'false' -SpacesInConditionalStatement: 'true' -SpacesInContainerLiterals: 'false' -SpacesInParentheses: 'true' -SpacesInSquareBrackets: 'false' - -ReflowComments: 'false' - -PenaltyExcessCharacter: 0 --- Language: Proto DisableFormat: true \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..0759306c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ + +root = true + +[*] +insert_final_newline = false +indent_style = tab +indent_size = 4 +trim_trailing_whitespace = false diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 3ade2f32..00000000 --- a/LICENSE +++ /dev/null @@ -1,43 +0,0 @@ - SOURCE 1 SDK LICENSE - -Source SDK Copyright(c) Valve Corp. - -THIS DOCUMENT DESCRIBES A CONTRACT BETWEEN YOU AND VALVE -CORPORATION ("Valve"). PLEASE READ IT BEFORE DOWNLOADING OR USING -THE SOURCE ENGINE SDK ("SDK"). BY DOWNLOADING AND/OR USING THE -SOURCE ENGINE SDK YOU ACCEPT THIS LICENSE. IF YOU DO NOT AGREE TO -THE TERMS OF THIS LICENSE PLEASE DONT DOWNLOAD OR USE THE SDK. - - You may, free of charge, download and use the SDK to develop a modified Valve game -running on the Source engine. You may distribute your modified Valve game in source and -object code form, but only for free. Terms of use for Valve games are found in the Steam -Subscriber Agreement located here: http://store.steampowered.com/subscriber_agreement/ - - You may copy, modify, and distribute the SDK and any modifications you make to the -SDK in source and object code form, but only for free. Any distribution of this SDK must -include this LICENSE file and thirdpartylegalnotices.txt. - - Any distribution of the SDK or a substantial portion of the SDK must include the above -copyright notice and the following: - - DISCLAIMER OF WARRANTIES. THE SOURCE SDK AND ANY - OTHER MATERIAL DOWNLOADED BY LICENSEE IS PROVIDED - "AS IS". VALVE AND ITS SUPPLIERS DISCLAIM ALL - WARRANTIES WITH RESPECT TO THE SDK, EITHER EXPRESS - OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED - WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, - TITLE AND FITNESS FOR A PARTICULAR PURPOSE. - - LIMITATION OF LIABILITY. IN NO EVENT SHALL VALVE OR - ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER - (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF - BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF - BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) - ARISING OUT OF THE USE OF OR INABILITY TO USE THE - ENGINE AND/OR THE SDK, EVEN IF VALVE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - -If you would like to use the SDK for a commercial purpose, please contact Valve at -sourceengine@valvesoftware.com. diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..4769841c --- /dev/null +++ b/build.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source devtools/linux/env.sh + +export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' +export CLICOLOR_FORCE=1 +export TERM=xterm-256color + +alias gcc="gcc -fdiagnostics-color=auto" + +PROJECT=games + +CXXFLAGS="-w -fdiagnostics-color=always" make -f$PROJECT.mak + +popd || exit diff --git a/common/language.cpp b/common/language.cpp index 33877f60..16aeda32 100644 --- a/common/language.cpp +++ b/common/language.cpp @@ -56,7 +56,6 @@ static const Language_t s_LanguageNames[] = { "Brazilian", "brazilian", "#GameUI_Language_Brazilian", "pt_BR", k_Lang_Brazilian, 1046 } , { "Bulgarian", "bulgarian", "#GameUI_Language_Bulgarian", "bg_BG", k_Lang_Bulgarian, 1026 } , { "Greek", "greek", "#GameUI_Language_Greek", "el_GR", k_Lang_Greek, 1032 }, - { "Ukrainian", "ukrainian", "#GameUI_Language_Ukrainian", "uk_UA", k_Lang_Ukrainian, 1058 }, }; //----------------------------------------------------------------------------- diff --git a/common/language.h b/common/language.h index b16c492f..2337c236 100644 --- a/common/language.h +++ b/common/language.h @@ -40,7 +40,6 @@ enum ELanguage k_Lang_Brazilian, k_Lang_Bulgarian, k_Lang_Greek, - k_Lang_Ukrainian, k_Lang_MAX }; diff --git a/common/lzma/lzma.h b/common/lzma/lzma.h deleted file mode 100644 index 01bd1ef9..00000000 --- a/common/lzma/lzma.h +++ /dev/null @@ -1,53 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: LZMA Glue. Designed for Tool time Encoding/Decoding. -// -// LZMA Codec interface for engine. Based largely on LzmaUtil.c in SDK -// -// LZMA SDK 9.38 beta -// 2015-01-03 : Igor Pavlov : Public domain -// http://www.7-zip.org/ -// -//====================================================================================// - -#ifndef LZMA_H -#define LZMA_H - -#ifdef _WIN32 -#pragma once -#endif - -//----------------------------------------------------------------------------- -// These routines are designed for TOOL TIME encoding/decoding on the PC! -// They have not been made to encode/decode on the PPC and lack big endian awarnesss. -// Lightweight GAME TIME Decoding is part of tier1.lib, via CLZMA. -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Encoding glue. Returns non-null Compressed buffer if successful. -// Caller must free. -//----------------------------------------------------------------------------- -unsigned char *LZMA_Compress( -unsigned char *pInput, -unsigned int inputSize, -unsigned int *pOutputSize ); - -//----------------------------------------------------------------------------- -// Decoding glue. Returns TRUE if succesful. -//----------------------------------------------------------------------------- -bool LZMA_Uncompress( -unsigned char *pInput, -unsigned char **ppOutput, -unsigned int *pOutputSize ); - -//----------------------------------------------------------------------------- -// Decoding helper, returns TRUE if buffer is LZMA compressed. -//----------------------------------------------------------------------------- -bool LZMA_IsCompressed( unsigned char *pInput ); - -//----------------------------------------------------------------------------- -// Decoding helper, returns non-zero size of data when uncompressed, otherwise 0. -//----------------------------------------------------------------------------- -unsigned int LZMA_GetActualSize( unsigned char *pInput ); - -#endif diff --git a/common/studiobyteswap.cpp b/common/studiobyteswap.cpp index 7b2c992e..08e29711 100644 --- a/common/studiobyteswap.cpp +++ b/common/studiobyteswap.cpp @@ -891,8 +891,8 @@ void ByteswapAnimData( mstudioanimdesc_t *pAnimDesc, int section, byte *&pDataSr int iStartFrame = section * sectionFrames; int iEndFrame = (section + 1) * sectionFrames; - iStartFrame = min( iStartFrame, totalFrames - 1 ); - iEndFrame = min( iEndFrame, totalFrames - 1 ); + iStartFrame = MIN( iStartFrame, totalFrames - 1 ); + iEndFrame = MIN( iEndFrame, totalFrames - 1 ); totalFrames = iEndFrame - iStartFrame + 1; } @@ -1679,11 +1679,6 @@ int ByteswapMDLFile( void *pDestBase, void *pSrcBase, const int fileSize ) SET_INDEX_POINTERS( pData, pSequence, keyvalueindex ) WriteBuffer( pDataDest, pDataSrc, SrcNative( &pSequence->keyvaluesize ) ); - - /** ACTIVITY MODIFIERS **/ - - SET_INDEX_POINTERS( pData, pSequence, activitymodifierindex ) - WriteObjects( pDataDest, pDataSrc, SrcNative( &pSequence->numactivitymodifiers ) ); } /** TRANSITION GRAPH **/ @@ -2806,10 +2801,6 @@ BEGIN_BYTESWAP_DATADESC( mstudiomovement_t ) DEFINE_FIELD( position, FIELD_VECTOR ), END_BYTESWAP_DATADESC() -BEGIN_BYTESWAP_DATADESC( mstudioactivitymodifier_t ) - DEFINE_INDEX( sznameindex, FIELD_INTEGER ), -END_BYTESWAP_DATADESC() - BEGIN_BYTESWAP_DATADESC( mstudioseqdesc_t ) DEFINE_INDEX( baseptr, FIELD_INTEGER ), DEFINE_INDEX( szlabelindex, FIELD_INTEGER ), @@ -2849,9 +2840,7 @@ BEGIN_BYTESWAP_DATADESC( mstudioseqdesc_t ) DEFINE_INDEX( keyvalueindex, FIELD_INTEGER ), DEFINE_FIELD( keyvaluesize, FIELD_INTEGER ), DEFINE_INDEX( cycleposeindex, FIELD_INTEGER ), - DEFINE_INDEX( activitymodifierindex, FIELD_INTEGER ), - DEFINE_FIELD( numactivitymodifiers, FIELD_INTEGER ), - DEFINE_ARRAY( unused, FIELD_INTEGER, 5 ), // remove/add as appropriate (grow back to 8 ints on version change!) + DEFINE_ARRAY( unused, FIELD_INTEGER, 7 ), // remove/add as appropriate (grow back to 8 ints on version change!) END_BYTESWAP_DATADESC() BEGIN_BYTESWAP_DATADESC( mstudioevent_t ) diff --git a/createallprojects b/createallprojects new file mode 100755 index 00000000..21912042 --- /dev/null +++ b/createallprojects @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +cd "$(dirname "${BASH_SOURCE-$0}")" || exit +devtools/bin/vpc /vance +everything /mksln everything + +make -Bnwk -no-silent -j"$(nproc)" -feverything.mak | compiledb +#bear -- make -Bnwk -no-silent -j"$(nproc)" -feverything.mak + diff --git a/creategameprojects b/creategameprojects new file mode 100755 index 00000000..ca78c7fc --- /dev/null +++ b/creategameprojects @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +cd "$(dirname "${BASH_SOURCE-$0}")" || exit +devtools/bin/vpc /vance +game +shaders /mksln games + +make -Bnwk -no-silent -j"$(nproc)" -fgames.mak | compiledb +#bear -- make -Bnwk -no-silent -j"$(nproc)" -fgames.mak diff --git a/creategameprojects.bat b/creategameprojects.bat index 58fb6be5..7140ea9e 100644 --- a/creategameprojects.bat +++ b/creategameprojects.bat @@ -1,2 +1 @@ -devtools\bin\vpc.exe /vance +game +game_shader_dx9 /mksln games.sln -pause \ No newline at end of file +devtools\bin\vpc.exe /vance +game +shaders /mksln games.sln diff --git a/createmaptoolsprojects b/createmaptoolsprojects new file mode 100755 index 00000000..d467a88e --- /dev/null +++ b/createmaptoolsprojects @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +cd "$(dirname "${BASH_SOURCE-$0}")" || exit +devtools/bin/vpc /vance +maptools /mksln maptools + +make -Bnwk -no-silent -j"$(nproc)" -fmaptools.mak | compiledb +#bear -- make -Bnwk -no-silent -j"$(nproc)" -fmaptools.mak + diff --git a/createmaptoolsprojects.bat b/createmaptoolsprojects.bat new file mode 100644 index 00000000..e21a53ff --- /dev/null +++ b/createmaptoolsprojects.bat @@ -0,0 +1 @@ +devtools\bin\vpc.exe +maptools /mksln maptools.sln diff --git a/createshadersprojects b/createshadersprojects new file mode 100755 index 00000000..442cbc80 --- /dev/null +++ b/createshadersprojects @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +cd "$(dirname "${BASH_SOURCE-$0}")" || exit +devtools/bin/vpc /vance +shaders /mksln shaders + +make -Bnwk -no-silent -j"$(nproc)" -fshaders.mak | compiledb +#bear -- make -Bnwk -no-silent -j"$(nproc)" -fshaders.mak + diff --git a/createshadersprojects.bat b/createshadersprojects.bat new file mode 100644 index 00000000..684a70f4 --- /dev/null +++ b/createshadersprojects.bat @@ -0,0 +1 @@ +devtools\bin\vpc.exe /vance +shaders /mksln shaders.sln diff --git a/createtoolprojects.bat b/createtoolprojects.bat deleted file mode 100644 index ee476b5e..00000000 --- a/createtoolprojects.bat +++ /dev/null @@ -1,2 +0,0 @@ -devtools\bin\vpc.exe /vance +tools /mksln tools.sln -pause \ No newline at end of file diff --git a/devtools/bin/buildshaderlist.pl b/devtools/bin/buildshaderlist.pl deleted file mode 100644 index 98a4051f..00000000 --- a/devtools/bin/buildshaderlist.pl +++ /dev/null @@ -1,22 +0,0 @@ -use File::DosGlob; -@ARGV = map { - my @g = File::DosGlob::glob($_) if /[*?]/; - @g ? @g : $_; - } @ARGV; - -open FILE, ">__tmpshaderlist.txt"; - -foreach $arg (@ARGV) -{ - if( $arg =~ m/\.fxc$/i || $arg =~ m/\.vsh$/i || $arg =~ m/\.psh$/i ) - { - print $arg . "\n"; - print FILE $arg . "\n"; - } -} - -close FILE; - -system "buildshaders.bat __tmpshaderlist"; - -unlink "__tmpshaderlist.txt"; \ No newline at end of file diff --git a/devtools/bin/checkshaderchecksums.pl b/devtools/bin/checkshaderchecksums.pl deleted file mode 100644 index 26841cbe..00000000 --- a/devtools/bin/checkshaderchecksums.pl +++ /dev/null @@ -1,116 +0,0 @@ -use String::CRC32; -BEGIN {use File::Basename; push @INC, dirname($0); } -require "valve_perl_helpers.pl"; - -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 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 GetShaderBase -{ - my $shadername = shift; - if ( $shadername =~ m/-----(.*)$/i ) - { - return $1; - } - else - { - my $shadertype = &GetShaderType( $shadername ); - $shadername =~ s/\.$shadertype//i; - return $shadername; - } -} - -$g_x360 = 0; -$g_vcsext = ".vcs"; - -while( 1 ) -{ - $inputbase = shift; - - if( $inputbase =~ m/-x360/ ) - { - $g_x360 = 1; - $g_vcsext = ".360.vcs"; - } - else - { - last; - } -} - -# rip the txt off the end if it's there. -$inputbase =~ s/\.txt//i; - -my @srcfiles = &LoadShaderListFile( $inputbase ); - -foreach $srcfile ( @srcfiles ) -{ - my $shadertype = &GetShaderType( $srcfile ); - my $shaderbase = &GetShaderBase( $srcfile ); - my $shadersrc = &GetShaderSrc( $srcfile ); - my $vcsFileName = "..\\..\\..\\game\\hl2\\shaders\\$shadertype\\$shaderbase" . $g_vcsext; -# print "shadersrc: $shadersrc vcsFileName: $vcsFileName\n"; - - if( $g_x360 && ( $shaderbase =~ m/_ps20$/i ) ) - { - next; # skip _ps20 files for 360 - } - - &CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 1 ); -} diff --git a/devtools/bin/copyshaderincfiles.pl b/devtools/bin/copyshaderincfiles.pl deleted file mode 100644 index c3419e62..00000000 --- a/devtools/bin/copyshaderincfiles.pl +++ /dev/null @@ -1,75 +0,0 @@ -BEGIN {use File::Basename; push @INC, dirname($0); } -require "valve_perl_helpers.pl"; -use Cwd; -use String::CRC32; - -my $txtfilename = shift; -my $arg = shift; - -my $is360 = 0; -my $platformextension = ""; -if( $arg =~ m/-x360/i ) -{ - $is360 = 1; - $platformextension = ".360"; -} - -open TXTFILE, "<$txtfilename"; - -my $src; -my $dst; -while( $src = ) -{ - # get rid of comments - $src =~ s,//.*,,g; - - # skip blank lines - if( $src =~ m/^\s*$/ ) - { - next; - } - - # Get rid of newlines. - $src =~ s/\n//g; - - # Save off the shader source filename. - my $dst = $src; - - $dst =~ s/_tmp//gi; - - # Does the dst exist? - my $dstexists = -e $dst; - my $srcexists = -e $src; - # What are the time stamps for the src and dst? - my $srcmodtime = ( stat $src )[9]; - my $dstmodtime = ( stat $dst )[9]; - - # Open for edit or add if different than what is in perforce already. - if( !$dstexists || ( $srcmodtime != $dstmodtime ) ) - { - # Make the target writable if it exists - if( $dstexists ) - { - MakeFileWritable( $dst ); - } - - my $dir = $dst; - $dir =~ s,([^/\\]*$),,; # rip the filename off the end - my $filename = $1; - - # create the target directory if it doesn't exist - if( !$dstexists ) - { - &MakeDirHier( $dir, 0777 ); - } - - # copy the file to its targets. . . we want to see STDERR here if there is an error. - my $cmd = "copy $src $dst > nul"; -# print STDERR "$cmd\n"; - system $cmd; - - MakeFileReadOnly( $dst ); - } -} - -close TXTFILE; diff --git a/devtools/bin/copyshaders.pl b/devtools/bin/copyshaders.pl deleted file mode 100644 index cb849a84..00000000 --- a/devtools/bin/copyshaders.pl +++ /dev/null @@ -1,172 +0,0 @@ -BEGIN {use File::Basename; push @INC, dirname($0); } -require "valve_perl_helpers.pl"; -use Cwd; -use String::CRC32; - -sub ReadInputFileWithIncludes -{ - local( $filename ) = shift; - - local( *INPUT ); - local( $output ); - - open INPUT, "<$filename" || die; - - local( $line ); - local( $linenum ) = 1; - while( $line = ) - { - if( $line =~ m/\#include\s+\"(.*)\"/i ) - { - $output.= ReadInputFileWithIncludes( $1 ); - } - else - { - $output .= $line; - } - } - - close INPUT; - return $output; -} - -sub PatchCRC -{ - my $filename = shift; - my $crc = shift; -# print STDERR "PatchCRC( $filename, $crc )\n"; - local( *FP ); - open FP, "+<$filename" || die; - binmode( FP ); - seek FP, 6 * 4, 0; - my $uInt = "I"; - if( $filename =~ m/360/ ) - { - $uInt = "N"; - } - print FP pack $uInt, $crc; - close FP; -} - -my $txtfilename = shift; -my $arg = shift; - -my $is360 = 0; -my $platformextension = ""; -if( $arg =~ m/-x360/i ) -{ - $is360 = 1; - $platformextension = ".360"; -} - -# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist. -my $changelistnumber = `valve_p4_create_changelist.cmd ..\\..\\..\\game\\hl2\\shaders \"Shader Auto Checkout VCS\"`; -# Get rid of the newline -$changelistnumber =~ s/\n//g; - -my $changelistarg = ""; -if( $changelistnumber != 0 ) -{ - $changelistarg = "-c $changelistnumber" -} - -open TXTFILE, "<$txtfilename"; - -my $src; -my $dst; -while( $src = ) -{ - # get rid of comments - $src =~ s,//.*,,g; - - # skip blank lines - if( $src =~ m/^\s*$/ ) - { - next; - } - - # Get rid of newlines. - $src =~ s/\n//g; - - # Save off the shader source filename. - my $shadersrcfilename = $src; - $shadersrcfilename =~ s/-----.*$//; - # use only target basename. - $src =~ s/^.*-----//; - - # where the binary vcs file is - my $spath = ""; - - if ( $shadersrcfilename =~ m@\.fxc@i ) - { - $spath = "shaders\\fxc\\"; - } - if ( $shadersrcfilename =~ m@\.vsh@i ) - { - $spath = "shaders\\vsh\\"; - } - if ( $shadersrcfilename =~ m@\.psh@i ) - { - $spath = "shaders\\psh\\"; - } - - # make the source have path and extension - $src = $spath . $src . $platformextension . ".vcs"; - - # build the dest filename. - $dst = $src; - - $dst =~ s/shaders\\/..\\..\\..\\game\\hl2\\shaders\\/i; - - # Does the dst exist? - my $dstexists = -e $dst; - my $srcexists = -e $src; - # What are the time stamps for the src and dst? - my $srcmodtime = ( stat $src )[9]; - my $dstmodtime = ( stat $dst )[9]; - - # Write $dst to a file so that we can do perforce stuff to it later. - local( *VCSLIST ); - open VCSLIST, ">>vcslist.txt" || die; - print VCSLIST $dst . "\n"; - close VCSLIST; - - # Open for edit or add if different than what is in perforce already. - if( !$dstexists || ( $srcmodtime != $dstmodtime ) ) - { - if ( $srcexists && $shadersrcfilename =~ m@\.fxc@i ) - { - # Get the CRC for the source file. - my $srccode = ReadInputFileWithIncludes( $shadersrcfilename ); - my $crc = crc32( $srccode ); - - # Patch the source VCS file with the CRC32 of the source code used to build that file. - PatchCRC( $src, $crc ); - } - - # Make the target vcs writable if it exists - if( $dstexists ) - { - MakeFileWritable( $dst ); - } - - my $dir = $dst; - $dir =~ s,([^/\\]*$),,; # rip the filename off the end - my $filename = $1; - - # create the target directory if it doesn't exist - if( !$dstexists ) - { - &MakeDirHier( $dir, 0777 ); - } - - # copy the file to its targets. . . we want to see STDERR here if there is an error. - my $cmd = "copy $src $dst > nul"; -# print STDERR "$cmd\n"; - system $cmd; - - MakeFileReadOnly( $dst ); - } -} - -close TXTFILE; diff --git a/devtools/bin/d3dx9_33.dll b/devtools/bin/d3dx9_33.dll deleted file mode 100644 index a005f8fa..00000000 Binary files a/devtools/bin/d3dx9_33.dll and /dev/null differ diff --git a/devtools/bin/fix_particle_operator_names.pl b/devtools/bin/fix_particle_operator_names.pl deleted file mode 100644 index c0f5ee06..00000000 --- a/devtools/bin/fix_particle_operator_names.pl +++ /dev/null @@ -1,110 +0,0 @@ -#!perl -use File::Find; - -&BuildRemapTable; - -find(\&convert, "." ); - - -sub convert - { - return unless (/\.pcf$/i); - return if (/^tmp\.pcf$/i); - return if (/^tmp2\.pcf$/i); - return if (/360\.pcf$/i); - print STDERR "process ", $File::Find::name," ($_) dir=",`cd`," \n"; - my $fname=$_; - print `p4 edit $fname`; - print `dmxconvert -i $_ -o tmp.pcf -oe keyvalues2`; - open(TMP, "tmp.pcf" ) || return; - open(OUT, ">tmp2.pcf" ) || die; - while() - { - s/[\n\r]//g; - if ( (/^(\s*\"functionName\"\s*\"string\"\s*\")(.*)\"(.*)$/) && - length($map{$2}) ) - { - $_=$1.$map{$2}.'"'.$3; - } - if ( (/^(\s*\"name\"\s*\"string\"\s*\")(.*)\"(.*)$/) && - length($map{$2}) ) - { - $_=$1.$map{$2}.'"'.$3; - } - print OUT "$_\n"; - } - close OUT; - close TMP; - print `dmxconvert -i tmp2.pcf -o $fname -ie keyvalues2 -oe binary`; - unlink "tmp.pcf"; - unlink "tmp2.pcf"; -} - - - - - - - - - - - - -sub BuildRemapTable -{ - $map{"alpha_fade"}= "Alpha Fade and Decay"; - $map{"alpha_fade_in_random"}= "Alpha Fade In Random"; - $map{"alpha_fade_out_random"}= "Alpha Fade Out Random"; - $map{"basic_movement"}= "Movement Basic"; - $map{"color_fade"}= "Color Fade"; - $map{"controlpoint_light"}= "Color Light From Control Point"; - $map{"Dampen Movement Relative to Control Point"}= "Movement Dampen Relative to Control Point"; - $map{"Distance Between Control Points Scale"}= "Remap Distance Between Two Control Points to Scalar"; - $map{"Distance to Control Points Scale"}= "Remap Distance to Control Point to Scalar"; - $map{"lifespan_decay"}= "Lifespan Decay"; - $map{"lock to bone"}= "Movement Lock to Bone"; - $map{"postion_lock_to_controlpoint"}= "Movement Lock to Control Point"; - $map{"maintain position along path"}= "Movement Maintain Position Along Path"; - $map{"Match Particle Velocities"}= "Movement Match Particle Velocities"; - $map{"Max Velocity"}= "Movement Max Velocity"; - $map{"noise"}= "Noise Scalar"; - $map{"vector noise"}= "Noise Vector"; - $map{"oscillate_scalar"}= "Oscillate Scalar"; - $map{"oscillate_vector"}= "Oscillate Vector"; - $map{"Orient Rotation to 2D Direction"}= "Rotation Orient to 2D Direction"; - $map{"radius_scale"}= "Radius Scale"; - $map{"Random Cull"}= "Cull Random"; - $map{"remap_scalar"}= "Remap Scalar"; - $map{"rotation_movement"}= "Rotation Basic"; - $map{"rotation_spin"}= "Rotation Spin Roll"; - $map{"rotation_spin yaw"}= "Rotation Spin Yaw"; - $map{"alpha_random"}= "Alpha Random"; - $map{"color_random"}= "Color Random"; - $map{"create from parent particles"}= "Position From Parent Particles"; - $map{"Create In Hierarchy"}= "Position In CP Hierarchy"; - $map{"random position along path"}= "Position Along Path Random"; - $map{"random position on model"}= "Position on Model Random"; - $map{"sequential position along path"}= "Position Along Path Sequential"; - $map{"position_offset_random"}= "Position Modify Offset Random"; - $map{"position_warp_random"}= "Position Modify Warp Random"; - $map{"position_within_box"}= "Position Within Box Random"; - $map{"position_within_sphere"}= "Position Within Sphere Random"; - $map{"Inherit Velocity"}= "Velocity Inherit from Control Point"; - $map{"Initial Repulsion Velocity"}= "Velocity Repulse from World"; - $map{"Initial Velocity Noise"}= "Velocity Noise"; - $map{"Initial Scalar Noise"}= "Remap Noise to Scalar"; - $map{"Lifespan from distance to world"}= "Lifetime from Time to Impact"; - $map{"Pre-Age Noise"}= "Lifetime Pre-Age Noise"; - $map{"lifetime_random"}= "Lifetime Random"; - $map{"radius_random"}= "Radius Random"; - $map{"random yaw"}= "Rotation Yaw Random"; - $map{"Randomly Flip Yaw"}= "Rotation Yaw Flip Random"; - $map{"rotation_random"}= "Rotation Random"; - $map{"rotation_speed_random"}= "Rotation Speed Random"; - $map{"sequence_random"}= "Sequence Random"; - $map{"second_sequence_random"}= "Sequence Two Random"; - $map{"trail_length_random"}= "Trail Length Random"; - $map{"velocity_random"}= "Velocity Random"; -} - diff --git a/devtools/bin/fxc_prep.pl b/devtools/bin/fxc_prep.pl deleted file mode 100644 index 9f67ca50..00000000 --- a/devtools/bin/fxc_prep.pl +++ /dev/null @@ -1,949 +0,0 @@ -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 = ) - { -# 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; - diff --git a/devtools/bin/linux/ccache b/devtools/bin/linux/ccache old mode 100644 new mode 100755 index 99dd2b4a..5146484f Binary files a/devtools/bin/linux/ccache and b/devtools/bin/linux/ccache differ diff --git a/devtools/bin/osx32/ccache b/devtools/bin/osx32/ccache deleted file mode 100644 index 1b6a2e5f..00000000 Binary files a/devtools/bin/osx32/ccache and /dev/null differ diff --git a/devtools/bin/osx32/protoc b/devtools/bin/osx32/protoc deleted file mode 100644 index f111cb24..00000000 Binary files a/devtools/bin/osx32/protoc and /dev/null differ diff --git a/devtools/bin/osx32/xcode_ccache_wrapper b/devtools/bin/osx32/xcode_ccache_wrapper deleted file mode 100644 index 475f508f..00000000 --- a/devtools/bin/osx32/xcode_ccache_wrapper +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -exec $(dirname $0)/ccache "${DT_TOOLCHAIN_DIR}"/usr/bin/clang -Qunused-arguments "$@" diff --git a/devtools/bin/psh_prep.pl b/devtools/bin/psh_prep.pl deleted file mode 100644 index 1c44c41d..00000000 --- a/devtools/bin/psh_prep.pl +++ /dev/null @@ -1,333 +0,0 @@ -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 = ) -{ - 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( ) -{ - 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; - - diff --git a/devtools/bin/shaderinfo.pl b/devtools/bin/shaderinfo.pl deleted file mode 100644 index 57a81578..00000000 --- a/devtools/bin/shaderinfo.pl +++ /dev/null @@ -1,36 +0,0 @@ -#! perl - -my $fname=shift || die "format is shaderinfo blah.vcs"; - -open(SHADER, $fname) || die "can't open $fname"; -binmode SHADER; - -read(SHADER,$header,20); -($ver,$ntotal,$ndynamic,$flags,$centroidmask)=unpack("LLLLL",$header); - -#print "Version $ver total combos=$ntotal, num dynamic combos=$ndynamic,\n flags=$flags, centroid mask=$centroidmask\n"; - -read(SHADER,$refsize,4); -$refsize=unpack("L",$refsize); -#print "Size of reference shader for diffing=$refsize\n"; - -seek(SHADER,$refsize,1); - -$nskipped_combos=0; -for(1..$ntotal) - { - read(SHADER,$combodata,8); - ($ofs,$combosize)=unpack("LL",$combodata); - if ( $ofs == 0xffffffff) - { - $nskipped_combos++; - } - else - { - } - } -#print "$nskipped_combos skipped, for an actual total of ",$ntotal-$nskipped_combos,"\n"; -#print "Real to skipped ratio = ",($ntotal-$nskipped_combos)/$ntotal,"\n"; -# csv output - name, real combos, virtual combos, dynamic combos -my $real_combos=$ntotal-$nskipped_combos; -print "$fname,$real_combos,$ntotal,$ndynamic\n"; diff --git a/devtools/bin/splitdiff3.pl b/devtools/bin/splitdiff3.pl deleted file mode 100644 index ccba3a95..00000000 --- a/devtools/bin/splitdiff3.pl +++ /dev/null @@ -1,54 +0,0 @@ -$infilename = shift; -$outfilename1 = shift; -$outfilename2 = shift; -open INPUT, $infilename || die; -@input = ; -close INPUT; - -open MERGEDMINE, ">$outfilename1" || die; -open MERGEDTHEIRS, ">$outfilename2" || die; - -for( $i = 0; $i < scalar( @input ); $i++ ) -{ - $line = $input[$i]; - - if( $line =~ m/^(.*)<<<<<<>>>>>>/ ) - { - $first = $second = 0; - print MERGEDTHEIRS $1; - next; - } - - if( $first ) - { - print MERGEDMINE $line; - } - elsif( $second ) - { - print MERGEDTHEIRS $line; - } - else - { - print MERGEDMINE $line; - print MERGEDTHEIRS $line; - } -} - -close MERGEDMINE; -close MERGEDTHEIRS; diff --git a/devtools/bin/uniqifylist.pl b/devtools/bin/uniqifylist.pl deleted file mode 100644 index 1c3fd9c9..00000000 --- a/devtools/bin/uniqifylist.pl +++ /dev/null @@ -1,6 +0,0 @@ -foreach $_ (sort <> ) -{ - next if( defined( $prevline ) && $_ eq $prevline ); - $prevline = $_; - print; -} diff --git a/devtools/bin/updateshaders.pl b/devtools/bin/updateshaders.pl deleted file mode 100644 index 93f57ffd..00000000 --- a/devtools/bin/updateshaders.pl +++ /dev/null @@ -1,305 +0,0 @@ -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( ) - { - 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 $_; -} - diff --git a/devtools/bin/valve_perl_helpers.pl b/devtools/bin/valve_perl_helpers.pl deleted file mode 100644 index 9257767a..00000000 --- a/devtools/bin/valve_perl_helpers.pl +++ /dev/null @@ -1,558 +0,0 @@ -sub BackToForwardSlash -{ - my( $path ) = shift; - $path =~ s,\\,/,g; - return $path; -} - -sub RemoveFileName -{ - my( $in ) = shift; - $in = &BackToForwardSlash( $in ); - $in =~ s,/[^/]*$,,; - return $in; -} - -sub RemovePath -{ - my( $in ) = shift; - $in = &BackToForwardSlash( $in ); - $in =~ s,^(.*)/([^/]*)$,$2,; - return $in; -} - -sub MakeDirHier -{ - my( $in ) = shift; -# print "MakeDirHier( $in )\n"; - $in = &BackToForwardSlash( $in ); - my( @path ); - while( $in =~ m,/, ) # while $in still has a slash - { - my( $end ) = &RemovePath( $in ); - push @path, $end; -# print $in . "\n"; - $in = &RemoveFileName( $in ); - } - my( $i ); - my( $numelems ) = scalar( @path ); - my( $curpath ); - for( $i = $numelems - 1; $i >= 0; $i-- ) - { - $curpath .= "/" . $path[$i]; - my( $dir ) = $in . $curpath; - if( !stat $dir ) - { -# print "mkdir $dir\n"; - mkdir $dir, 0777; - } - } -} - -sub FileExists -{ - my $filename = shift; - my @statresult = stat $filename; - my $iswritable = @statresult != 0; - return $iswritable; -} - -sub MakeFileWritable -{ - my $filename = shift; - if ( &FileExists( $filename ) ) - { - chmod 0666, $filename || die; - } -} - -sub MakeFileReadOnly -{ - my $filename = shift; - chmod 0444, $filename || die; -} - -# Run a command and get stdout and stderr to an array -sub RunCommand -{ - my $cmd = shift; -# print STDERR "command: $cmd\n"; - system "$cmd > cmdout.txt 2>&1" || die; - local( *FILE ); - open FILE, "; -# print STDERR "command output: @output\n"; - close FILE; - unlink "cmdout.txt" || die; - return @output; -} - -sub PerforceEditOrAdd -{ - return; - my $filename = shift; - my $changelistarg = shift; - - # Is the file on the client? - my $cmd = "p4 fstat \"$filename\""; - my @p4output = &RunCommand( $cmd ); - my $p4output = join "", @p4output; - if( $p4output =~ m/no such file/ ) - { - # not on client. . add - my $cmd = "p4 add $changelistarg $filename"; - my @p4output = &RunCommand( $cmd ); - my $p4output = join "", @p4output; - if( $p4output =~ m/opened for add/ ) - { - print $p4output; - return; - } - print "ERROR: $p4output"; - return; - } - - # The file is known to be on the client at this point. - - # Is it open for edit? - if( $p4output =~ m/action edit/ ) - { - # Is is open for edit, let's see if it's still different. - # check for opened files that are not different from the revision in the depot. - my $cmd = "p4 diff -sr \"$filename\""; - my @p4output = &RunCommand( $cmd ); - my $outputstring = join "", @p4output; - # check for empty string - if( !( $outputstring =~ m/^\s*$/ ) ) - { - my $cmd = "p4 revert \"$filename\""; - my @p4output = &RunCommand( $cmd ); - my $outputstring = join "", @p4output; - print $outputstring; - return; - } - } - - # check for unopened files that are different from the revision in the depot. - my $cmd = "p4 diff -se \"$filename\""; - my @p4output = &RunCommand( $cmd ); - my $outputstring = join "", @p4output; - # check for empty string - if( $outputstring =~ m/^\s*$/ ) - { - &MakeFileReadOnly( $filename ); - return; - } - - # We need to edit the file since it is known to be different here. - my $cmd = "p4 edit $changelistarg \"$filename\""; - my @p4output = &RunCommand( $cmd ); - - my $line; - foreach $line ( @p4output ) - { - if( $line =~ m/not on client/ ) - { - #print "notonclient..."; - print "ERROR: @p4output\n"; - return; - } - if( $line =~ m/currently opened for edit/ ) - { - return; - } - if( $line =~ m/opened for edit/ ) - { - print $line; - } - } -} - -sub FileIsWritable -{ - local( $filename ) = shift; - local( @statresult ) = stat $filename; - local( $mode, $iswritable ); - $mode = oct( $statresult[2] ); - $iswritable = ( $mode & 2 ) != 0; - return $iswritable; -} - -sub TouchFile -{ - my $filename = shift; - if( !&FileExists( $filename ) ) - { - if( !open FILE, ">$filename" ) - { - die; - } - close FILE; - } - my $now = time; - local( *FILE ); - utime $now, $now, $filename; -} - -sub FileExistsInPerforce -{ - my $filename = shift; - my @output = &RunCommand( "p4 fstat $filename" ); - my $line; - foreach $line (@output) - { - if( $line =~ m/no such file/ ) - { - return 0; - } - } - return 1; -} - -sub PerforceWriteFile -{ - my $filename = shift; - my $filecontents = shift; -# my $changelistname = shift; - - # Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist. -# my $changelistnumber = `valve_p4_create_changelist.cmd . \"$changelistname\"`; - # Get rid of the newline -# $changelistnumber =~ s/\n//g; - -# my $changelistarg = ""; -# if( $changelistnumber != 0 ) -# { -# $changelistarg = "-c $changelistnumber" -# } - - # Make the target vcs writable if it exists - MakeFileWritable( $filename ); - - # Write the file. - local( *FP ); - open FP, ">$filename"; - print FP $filecontents; - close FP; - - # Do whatever needs to happen with perforce for this file. -# &PerforceEditOrAdd( $filename, $changelistarg ); -} - -sub WriteFile -{ - my $filename = shift; - my $filecontents = shift; - - # Make the target vcs writable if it exists - MakeFileWritable( $filename ); - - # Write the file. - local( *FP ); - open FP, ">$filename"; - print FP $filecontents; - close FP; -} - -sub PrintCleanPerforceOutput -{ - my $line; - while( $line = shift ) - { - if( $line =~ m/currently opened/i ) - { - next; - } - if( $line =~ m/already opened for edit/i ) - { - next; - } - if( $line =~ m/also opened/i ) - { - next; - } - if( $line =~ m/add of existing file/i ) - { - next; - } - print $line; - } -} - -# HACK!!!! Need to pass something in to do this rather than hard coding. -sub NormalizePerforceFilename -{ - my $line = shift; - - # remove newlines. - $line =~ s/\n//; - # downcase. - $line =~ tr/[A-Z]/[a-z]/; - # backslash to forwardslash - $line =~ s,\\,/,g; - - # for inc files HACK! - $line =~ s/^.*(fxctmp9.*)/$1/i; - $line =~ s/^.*(vshtmp9.*)/$1/i; - - # for vcs files. HACK! - $line =~ s,^.*game/hl2/shaders/,,i; - - return $line; -} - -sub MakeSureFileExists -{ - local( $filename ) = shift; - local( $testexists ) = shift; - local( $testwrite ) = shift; - - local( @statresult ) = stat $filename; - if( !@statresult && $testexists ) - { - die "$filename doesn't exist!\n"; - } - local( $mode, $iswritable ); - $mode = oct( $statresult[2] ); - $iswritable = ( $mode & 2 ) != 0; - if( !$iswritable && $testwrite ) - { - die "$filename isn't writable!\n"; - } -} - -sub LoadShaderListFile_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 LoadShaderListFile_GetShaderSrc -{ - my $shadername = shift; - if ( $shadername =~ m/^(.*)-----/i ) - { - return $1; - } - else - { - return $shadername; - } -} - -sub LoadShaderListFile_GetShaderBase -{ - my $shadername = shift; - if ( $shadername =~ m/-----(.*)$/i ) - { - return $1; - } - else - { - my $shadertype = &LoadShaderListFile_GetShaderType( $shadername ); - $shadername =~ s/\.$shadertype//i; - return $shadername; - } -} - -sub LoadShaderListFile -{ - my $inputbase = shift; - - my @srcfiles; - &MakeSureFileExists( "$inputbase.txt", 1, 0 ); - - open SHADERLISTFILE, "<$inputbase.txt" || die; - my $line; - while( $line = ) - { - $line =~ s/\/\/.*$//; # remove comments "//..." - $line =~ s/^\s*//; # trim leading whitespace - $line =~ s/\s*$//; # trim trailing whitespace - next if( $line =~ m/^\s*$/ ); - if( $line =~ m/\.fxc/ || $line =~ m/\.vsh/ || $line =~ m/\.psh/ ) - { - my $shaderbase = &LoadShaderListFile_GetShaderBase( $line ); - - if( $ENV{"DIRECTX_FORCE_MODEL"} =~ m/^30$/i ) # forcing all shaders to be ver. 30 - { - my $targetbase = $shaderbase; - $targetbase =~ s/_ps2x/_ps30/i; - $targetbase =~ s/_ps20b/_ps30/i; - $targetbase =~ s/_ps20/_ps30/i; - $targetbase =~ s/_vs20/_vs30/i; - $targetbase =~ s/_vsxx/_vs30/i; - push @srcfiles, ( $line . "-----" . $targetbase ); - } - else - { - if( $shaderbase =~ m/_ps2x/i ) - { - my $targetbase = $shaderbase; - $targetbase =~ s/_ps2x/_ps20/i; - push @srcfiles, ( $line . "-----" . $targetbase ); - - $targetbase = $shaderbase; - $targetbase =~ s/_ps2x/_ps20b/i; - push @srcfiles, ( $line . "-----" . $targetbase ); - } - elsif( $shaderbase =~ m/_vsxx/i ) - { - my $targetbase = $shaderbase; - $targetbase =~ s/_vsxx/_vs11/i; - push @srcfiles, ( $line . "-----" . $targetbase ); - - $targetbase = $shaderbase; - $targetbase =~ s/_vsxx/_vs20/i; - push @srcfiles, ( $line . "-----" . $targetbase ); - } - else - { - push @srcfiles, ( $line . "-----" . $shaderbase ); - } - } - } - } - close SHADERLISTFILE; - return @srcfiles; -} - -sub ReadInputFileWithIncludes -{ - local( $filename ) = shift; -# print STDERR "ReadInputFileWithIncludes: $filename\n"; - - local( *INPUT ); - local( $output ); - -# print STDERR "before open\n"; - open INPUT, "<$filename" || die; -# print STDERR "after open\n"; - - local( $line ); - while( $line = ) - { -# print STDERR $line; - if( $line =~ m/\#include\s+\"(.*)\"/i ) - { - $output.= ReadInputFileWithIncludes( $1 ); - } - else - { - $output .= $line; - } - } - - close INPUT; - return $output; -} - -sub GetCRCFromSourceFile -{ - my $filename = shift; - my $data = &ReadInputFileWithIncludes( $filename ); -# print STDERR $data; - $crc = crc32( $data ); -# print STDERR "GetCRCFromSourceFile: $crc\n"; - return $crc; -} - -sub GetCRCFromVCSFile -{ - my $filename = shift; -# print STDERR "GetCRCFromVCSFile $filename\n"; - local( *FP ); - open FP, "<$filename" || die "GetCRCFromVCSFile: can't open file $filename\n"; - binmode( FP ); - - # unpack arguments - my $sInt = "i"; - my $uInt = "I"; - if( $filename =~ m/\.360\./ ) - { - # Change arguments to "big endian long" - $sInt = "N"; - $uInt = "N"; - } - - my $header; - read FP, $header, 7 * 4 || die "updateshaders.pl:GetCRCFromVCSFile: can't read header for $filename\n"; - my $version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc; - ($version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc) = unpack "$sInt$sInt$sInt$uInt$uInt$uInt$uInt", $header; - unless( $version == 4 || $version == 5 || $version == 6 ) - { - print STDERR "ERROR: GetCRCFromVCSFile: $filename is version $version\n"; - return 0; - } -# print STDERR "version: $version\n"; -# print STDERR "numCombos: $numCombos\n"; -# print STDERR "numDynamicCombos: $numDynamicCombos\n"; -# print STDERR "flags: $flags\n"; -# print STDERR "centroidMask: $centroidMask\n"; -# print STDERR "refSize: $refSize\n"; -# print STDERR "GetCRCFromVCSFile: $crc\n"; - close( FP ); - return $crc; -} - -sub CheckCRCAgainstTarget -{ - my $srcFileName = shift; - my $vcsFileName = shift; - my $warn = shift; - - # Make sure both files exist. -# print STDERR "$srcFileName doesn't exist\n" if( !( -e $srcFileName ) ); -# print STDERR "$vcsFileName doesn't exist\n" if( !( -e $vcsFileName ) ); - if( !( -e $srcFileName ) ) - { - if( $warn ) - { - print "$srcFileName missing\n"; - } - return 0; - } - if( !( -e $vcsFileName ) ) - { - if( $warn ) - { - print "$vcsFileName missing\n"; - } - return 0; - } -# print STDERR "CheckCRCAgainstTarget( $srcFileName, $vcsFileName );\n"; -# print STDERR "vcsFileName: $vcsFileName\n"; -# print STDERR "vcsFileName: $srcFileName\n"; - my $vcsCRC = &GetCRCFromVCSFile( $vcsFileName ); - my $srcCRC = &GetCRCFromSourceFile( $srcFileName ); - if( $warn && ( $vcsCRC != $srcCRC ) ) - { - print "$vcsFileName checksum ($vcsCRC) != $srcFileName checksum: ($srcCRC)\n"; - } - -# return 0; # use this to skip crc checking. -# if( $vcsCRC == $srcCRC ) -# { -# print STDERR "CRC passed for $srcFileName $vcsFileName $vcsCRC\n"; -# } - return $vcsCRC == $srcCRC; -} - -1; diff --git a/devtools/bin/vpc b/devtools/bin/vpc old mode 100644 new mode 100755 diff --git a/devtools/bin/vpc.exe b/devtools/bin/vpc.exe index 8c4fd6aa..cab4902c 100644 Binary files a/devtools/bin/vpc.exe and b/devtools/bin/vpc.exe differ diff --git a/devtools/bin/vpc_linux b/devtools/bin/vpc_linux old mode 100644 new mode 100755 index e7680782..dfdf10bd Binary files a/devtools/bin/vpc_linux and b/devtools/bin/vpc_linux differ diff --git a/devtools/bin/vpc_osx b/devtools/bin/vpc_osx index 2827ae4b..19f2b842 100644 Binary files a/devtools/bin/vpc_osx and b/devtools/bin/vpc_osx differ diff --git a/devtools/bin/vsh_prep.pl b/devtools/bin/vsh_prep.pl deleted file mode 100644 index 8161c494..00000000 --- a/devtools/bin/vsh_prep.pl +++ /dev/null @@ -1,1106 +0,0 @@ -use String::CRC32; -BEGIN {use File::Basename; push @INC, dirname($0); } -require "valve_perl_helpers.pl"; - -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"; - if ( $min != $max ) - { - 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"; - if ( $min != $max ) - { -# 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_filename; - $basename =~ s/\.fxc//i; - $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, "\t$classname()\n"; - push @outputHeader, "\t{\n"; - for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ ) - { - $min = $dynamicDefineMin[$i]; - $max = $dynamicDefineMax[$i]; - - local( $name ) = @dynamicDefineNames[$i]; - local( $boolname ) = "m_b" . $name; - local( $varname ) = "m_n" . $name; - push @outputHeader, "#ifdef _DEBUG\n"; - if ( $min != $max ) - { - push @outputHeader, "\t\t$boolname = false;\n"; - } - else - { - push @outputHeader, "\t\t$boolname = true;\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( @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"; -} - -sub WriteStaticHelperClasses -{ - local( $basename ) = $fxc_filename; - $basename =~ s/\.fxc//i; - $basename =~ tr/A-Z/a-z/; - local( $classname ) = $basename . "_Static_Index"; - 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, "\t$classname()\n"; - push @outputHeader, "\t{\n"; - for( $i = 0; $i < scalar( @staticDefineNames ); $i++ ) - { - $min = $staticDefineMin[$i]; - $max = $staticDefineMax[$i]; - - local( $name ) = @staticDefineNames[$i]; - local( $boolname ) = "m_b" . $name; - local( $varname ) = "m_n" . $name; - - push @outputHeader, "#ifdef _DEBUG\n"; - if ( $min != $max ) - { - push @outputHeader, "\t\t$boolname = false;\n"; - } - else - { - push @outputHeader, "\t\t$boolname = true;\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"; -} - -sub CreateFuncToSetPerlVars -{ - local( $out ) = ""; - - $out .= "sub SetPerlVarsFunc\n"; - $out .= "{\n"; - $out .= " local( \$combo ) = shift;\n"; - $out .= " local( \$i );\n"; - local( $i ); - for( $i = 0; $i < scalar( @dynamicDefineNames ); \$i++ ) - { - $out .= " \$$dynamicDefineNames[$i] = \$combo % "; - $out .= ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) + $dynamicDefineMin[$i]; - $out .= ";\n"; - $out .= " \$combo = \$combo / " . ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) . ";\n"; - } - for( $i = 0; $i < scalar( @staticDefineNames ); \$i++ ) - { - $out .= " \$$staticDefineNames[$i] = \$combo % "; - $out .= ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) + $staticDefineMin[$i]; - $out .= ";\n"; - $out .= " \$combo = \$combo / " . ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) . ";\n"; - } - $out .= "}\n"; - -# print $out; - eval $out; -} - -# These sections can be interchanged to enable profiling. -#$ShowTimers = 1; -#use Time::HiRes; -#sub SampleTime() -#{ -# return Time::HiRes::time(); -#} - -$ShowTimers = 0; -sub SampleTime() { return 0; } - -$total_start_time = SampleTime(); - -# NOTE: These must match the same values in macros.vsh! -$vPos = "v0"; -$vBoneWeights = "v1"; -$vBoneIndices = "v2"; -$vNormal = "v3"; -if( $g_x360 ) -{ - $vPosFlex = "v4"; - $vNormalFlex = "v13"; -} -$vColor = "v5"; -$vSpecular = "v6"; -$vTexCoord0 = "v7"; -$vTexCoord1 = "v8"; -$vTexCoord2 = "v9"; -$vTexCoord3 = "v10"; -$vTangentS = "v11"; -$vTangentT = "v12"; -$vUserData = "v14"; - -sub ReadInputFileWithLineInfo -{ - local( $base_filename ) = shift; - - local( *INPUT ); - local( @output ); - - # Look in the stdshaders directory, followed by the current directory. - # (This is for the SDK, since some of its files are under stdshaders). - local( $filename ) = $base_filename; - if ( !-e $filename ) - { - $filename = "$g_SourceDir\\materialsystem\\stdshaders\\$base_filename"; - if ( !-e $filename ) - { - die "\nvsh_prep.pl ERROR: missing include file: $filename.\n\n"; - } - } - - open INPUT, "<$filename" || die; - - local( $line ); - local( $linenum ) = 1; - while( $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, &ReadInputFileWithLineInfo( $1 ); - } - else - { - push @output, $line . $postfix; - } - $linenum++; - } - - close INPUT; - return @output; -} - -sub ReadInputFileWithoutLineInfo -{ - local( $base_filename ) = shift; - - local( *INPUT ); - local( @output ); - - # Look in the stdshaders directory, followed by the current directory. - # (This is for the SDK, since some of its files are under stdshaders). - local( $filename ) = $base_filename; - if ( !-e $filename ) - { - $filename = "$g_SourceDir\\materialsystem\\stdshaders\\$base_filename"; - if ( !-e $filename ) - { - die "\nERROR: missing include file: $filename.\n\n"; - } - } - - open INPUT, "<$filename" || die; - - local( $line ); - while( $line = ) - { - if( $line =~ m/\#include\s+\"(.*)\"/i ) - { - push @output, &ReadInputFileWithoutLineInfo( $1 ); - } - else - { - push @output, $line; - } - } - - close INPUT; - return @output; -} - -sub IsPerl -{ - local( $line ) = shift; - if( $line =~ m/^\s*sub.*\,/ ) - { - return 0; - } - if( $line =~ m/^\#include/ || - $line =~ m/^\#define/ || - $line =~ m/^\#undef/ || - $line =~ m/^\#ifdef/ || - $line =~ m/^\#ifndef/ || - $line =~ m/^\#else/ || - $line =~ m/^\#endif/ || - $line =~ m/^\#error/ - ) - { - return 0; - } - if( $line =~ m/^\s*if\s*\(/ || - $line =~ m/^\s*else/ || - $line =~ m/^\s*elsif/ || - $line =~ m/^\s*for\s*\(/ || - $line =~ m/^\s*\{/ || - $line =~ m/^sub\s*/ || - $line =~ m/^\s*\}/ || - $line =~ m/^\s*\&/ || - $line =~ m/^\s*\#/ || - $line =~ m/^\s*\$/ || - $line =~ m/^\s*print/ || - $line =~ m/^\s*return/ || - $line =~ m/^\s*exit/ || - $line =~ m/^\s*die/ || - $line =~ m/^\s*eval/ || - $line =~ m/^\s*local/ || - $line =~ m/^\s*my\s+/ || - $line =~ m/^\s*@/ || - $line =~ m/^\s*alloc\s+/ || - $line =~ m/^\s*free\s+/ - ) - { - return 1; - } - return 0; -} - -# translate the output into something that takes us back to the source line -# that we care about in msdev -sub TranslateErrorMessages -{ - local( $origline ); - while( $origline = shift ) - { - if( $origline =~ m/(.*)\((\d+)\)\s*:\s*(.*)$/i ) - { - local( $filename ) = $1; - local( $linenum ) = $2; - local( $error ) = $3; - local( *FILE ); - open FILE, "<$filename" || die; - local( $i ); - local( $line ); - for( $i = 1; $i < $linenum; $i++ ) - { - $line = ; - } - if( $line =~ m/LINEINFO\((.*)\)\((.*)\)/ ) - { - print "$1\($2\) : $error\n"; - my $num = $linenum - 1; - print "$filename\($num\) : original error location\n"; - } - close FILE; - } - else - { - $origline =~ s/successful compile\!.*//gi; - if( !( $origline =~ m/^\s*$/ ) ) - { -# print "WTF: $origline\n"; - } - } - } -} - - -sub CountInstructions -{ - local( $line ); - local( $count ) = 0; - while( $line = shift ) - { - # get rid of comments - $line =~ s/;.*//gi; - $line =~ s/\/\/.*//gi; - # skip the vs1.1 statement - $line =~ s/^\s*vs.*//gi; - # if there's any text left, it's an instruction - if( $line =~ /\S/gi ) - { - $count++; - } - } - return $count; -} - - -%compiled = (); - -sub UsesRegister -{ - my $registerName = shift; - my $str = shift; - - # Cache a compiled RE for each register name. This makes UsesRegister about 2.5x faster. - if ( !$compiled{$registerName} ) - { - $compiled{$registerName} = qr/\b$registerName\b/; - } - - $ret = 0; - if( $str =~ /$compiled{$registerName}/gi ) - { - $ret = 1; - } - - return $ret; -} - -sub PadString -{ - local( $str ) = shift; - local( $desiredLen ) = shift; - local( $len ) = length $str; - while( $len < $desiredLen ) - { - $str .= " "; - $len++; - } - return $str; -} - -sub FixupAllocateFree -{ - local( $line ) = shift; - $line =~ s/\&AllocateRegister\s*\(\s*\\(\S+)\s*\)/&AllocateRegister( \\$1, \"\\$1\" )/g; - $line =~ s/\&FreeRegister\s*\(\s*\\(\S+)\s*\)/&FreeRegister( \\$1, \"\\$1\" )/g; - $line =~ s/alloc\s+(\S+)\s*/local( $1 ); &AllocateRegister( \\$1, \"\\$1\" );/g; - $line =~ s/free\s+(\S+)\s*/&FreeRegister( \\$1, \"\\$1\" );/g; - return $line; -} - -sub TranslateDXKeywords -{ - local( $line ) = shift; - $line =~ s/\bENDIF\b/endif/g; - $line =~ s/\bIF\b/if/g; - $line =~ s/\bELSE\b/else/g; - - return $line; -} - -# This is used to make the generated pl files all pretty. -sub GetLeadingWhiteSpace -{ - local( $str ) = shift; - if( $str =~ m/^;\S/ || $str =~ m/^; \S/ ) - { - return ""; - } - $str =~ s/^;/ /g; # count a leading ";" as whitespace as far as this is concerned. - $str =~ m/^(\s*)/; - return $1; -} - -$g_dx9 = 1; -$g_SourceDir = "..\\.."; - -while( 1 ) -{ - $filename = shift; - - if ( $filename =~ m/-source/i ) - { - $g_SourceDir = shift; - } - elsif( $filename =~ m/-x360/i ) - { - $g_x360 = 1; - } - else - { - last; - } -} - -$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 = ) -{ - 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; - - -if( $g_x360 ) -{ - $vshtmp = "vshtmp9_360_tmp"; -} -else -{ - $vshtmp = "vshtmp9_tmp"; -} - -if( !stat $vshtmp ) -{ - mkdir $vshtmp, 0777 || die $!; -} - -# suck in all files, including $include files. -@input = &ReadInputFileWithLineInfo( $filename ); - -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; -} - -# READ THE TOP OF THE FILE TO FIND SHADER COMBOS -foreach $_ ( @input ) -{ - next if( m/^\s*$/ ); -# 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 "\"$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; - if (/\[(.*)\]/) - { - $platforms=$1; - next if ( ($g_x360) && (!($platforms=~/XBOX/i)) ); - next if ( (!$g_x360) && (!($platforms=~/PC/i)) ); - } -# print "\"$name\" \"$min..$max\"\n"; - push @dynamicDefineNames, $name; - push @dynamicDefineMin, $min; - push @dynamicDefineMax, $max; - } -} - -# READ THE WHOLE FILE AND FIND SKIP STATEMENTS -foreach $_ ( @input ) -{ - if( m/^\s*\#\s*SKIP\s*\:\s*(.*\S+)\s*\; LINEINFO.*$/ ) - { - $perlskipcode .= "(" . $1 . ")||"; - push @perlskipcodeindividual, $1; - } -} -if( defined $perlskipcode ) -{ - $perlskipcode .= "0"; - $perlskipcode =~ s/\n//g; -} -else -{ - $perlskipcode = "0"; -} - -#print $perlskipcode . "\n"; - - -# Translate the input into a perl program that'll unroll everything and -# substitute variables. -while( $inputLine = shift @input ) -{ - $inputLine =~ s/\n//g; - # leave out lines that are only whitespace. - if( $inputLine =~ m/^\s*; LINEINFO.*$/ ) - { - next; - } - local( $inputLineNoLineNum ) = $inputLine; - $inputLineNoLineNum =~ s/; LINEINFO.*//gi; - if( &IsPerl( $inputLineNoLineNum ) ) - { - $inputLineNoLineNum = &FixupAllocateFree( $inputLineNoLineNum ); - push @outputProgram, $inputLineNoLineNum . "\n"; - } - else - { - # make asm lines that have quotes in them not barf. - $inputLine =~ s/\"/\\\"/g; - $inputLine = &TranslateDXKeywords( $inputLine ); - push @outputProgram, &GetLeadingWhiteSpace( $inputLine ) . "push \@output, \"" . - $inputLine . "\\n\";\n"; - } -} - -$outputProgram = join "", @outputProgram; - -$filename_base = $filename; -$filename_base =~ s/\.vsh//i; - -open DEBUGOUT, ">$vshtmp" . "/$filename_base.pl" || die; -print DEBUGOUT $outputProgram; -close DEBUGOUT; - -# Make a function called OutputProgram() -$bigProg = "sub OutputProgram { " . $outputProgram . "}"; -eval( $bigProg ); - - -#print $outputProgram; - -#push @finalheader, "// hack to force dependency checking\n"; -#push @finalheader, "\#ifdef NEVER\n"; -#push @finalheader, "\#include \"" . $filename_base . "\.vsh\"\n"; -#push @finalheader, "\#include \"..\\..\\devtools\\bin\\vsh_prep.pl\"\n"; -#push @finalheader, "\#endif\n"; - -%g_TimingBlocks = (); -$main_start_time = SampleTime(); - -$numCombos = &CalcNumCombos(); -$numDynamicCombos = &CalcNumDynamicCombos(); -#print "$numCombos total combos\n"; -#print "$numDynamicCombos dynamic combos\n"; -#print $numCombos / $numDynamicCombos . " static combos\n"; - -# Write out the C++ helper class for picking shader combos -$fxc_filename = $filename_base; -&WriteStaticHelperClasses(); -&WriteDynamicHelperClasses(); - -# Create a subroutine out of $perlskipcode -$perlskipfunc = "sub SkipCombo { return $perlskipcode; }\n"; -#print $perlskipfunc; - -eval $perlskipfunc; -&CreateFuncToSetPerlVars(); - -my $incfilename = "$vshtmp/$filename_base" . ".inc"; - -# Write the inc file that has indexing helpers, etc. -&WriteFile( $incfilename, join( "", @outputHeader ) ); - - -# Run the output program for all the combinations of bones and lights. -print "$filename_base.vsh\n"; -for( $i = 0; $i < $numCombos; $i++ ) -{ -# print "combo $i\n"; - &SetPerlVarsFunc( $i ); - local( $compileFailed ); - $ret = &SkipCombo; - if( !defined $ret ) - { - die "$@\n"; - } - if( $ret ) - { - # skip this combo! - $compileFailed = 1; - $numSkipped++; - next; - } - - $start = SampleTime(); - - $g_usesPos = 0; - $g_usesPosFlex = 0; - $g_usesBoneWeights = 0; - $g_usesBoneIndices = 0; - $g_usesNormal = 0; - $g_usesNormalFlex = 0; - $g_usesColor = 0; - $g_usesSpecular = 0; - $g_usesTexCoord0 = 0; - $g_usesTexCoord1 = 0; - $g_usesTexCoord2 = 0; - $g_usesTexCoord3 = 0; - $g_usesTangentS = 0; - $g_usesTangentT = 0; - $g_usesUserData = 0; - - undef @output; - - $g_TimingBlocks{"inner1"} += SampleTime() - $start; - - $eval_start_time = SampleTime(); - &OutputProgram(); - $eval_total_time += (SampleTime() - $eval_start_time); - - $start = SampleTime(); - - # Strip out comments once so we don't have to do it in all the UsesRegister calls. - @stripped = @output; - map - { - $_ =~ s/;.*//gi; - $_ =~ s/\/\/.*//gi; - } @stripped; - my $strippedStr = join( "", @stripped ); - - $g_TimingBlocks{"inner2"} += SampleTime() - $start; - - $start = SampleTime(); - - # Have to make another pass through after we know which v registers are used. . yuck. - $g_usesPos = &UsesRegister( $vPos, $strippedStr ); - if( $g_x360 ) - { - $g_usesPosFlex = &UsesRegister( $vPosFlex, $strippedStr ); - $g_usesNormalFlex = &UsesRegister( $vNormalFlex, $strippedStr ); - } - $g_usesBoneWeights = &UsesRegister( $vBoneWeights, $strippedStr ); - $g_usesBoneIndices = &UsesRegister( $vBoneIndices, $strippedStr ); - $g_usesNormal = &UsesRegister( $vNormal, $strippedStr ); - $g_usesColor = &UsesRegister( $vColor, $strippedStr ); - $g_usesSpecular = &UsesRegister( $vSpecular, $strippedStr ); - $g_usesTexCoord0 = &UsesRegister( $vTexCoord0, $strippedStr ); - $g_usesTexCoord1 = &UsesRegister( $vTexCoord1, $strippedStr ); - $g_usesTexCoord2 = &UsesRegister( $vTexCoord2, $strippedStr ); - $g_usesTexCoord3 = &UsesRegister( $vTexCoord3, $strippedStr ); - $g_usesTangentS = &UsesRegister( $vTangentS, $strippedStr ); - $g_usesTangentT = &UsesRegister( $vTangentT, $strippedStr ); - $g_usesUserData = &UsesRegister( $vUserData, $strippedStr ); - undef @output; - - $g_TimingBlocks{"inner2"} += SampleTime() - $start; - - $eval_start_time = SampleTime(); - # Running OutputProgram generates $outfilename - &OutputProgram(); - $eval_total_time += (SampleTime() - $eval_start_time); - - $start = SampleTime(); - - &CheckUnfreedRegisters(); - - for( $j = 0; $j < scalar( @output ); $j++ ) - { - # remove whitespace from the beginning of each line. - $output[$j] =~ s/^\s+//; - # remove LINEINFO from empty lines. - $output[$j] =~ s/^; LINEINFO.*//; - } - - $g_TimingBlocks{"inner3"} += SampleTime() - $start; - $start = SampleTime(); - - - $outfilename_base = $filename_base . "_" . $i; - - # $outfilename is the name of the file generated from executing the perl code - # for this shader. This file is generated once per combo. - # We will assemble this shader with vsa.exe. - $outfilename = "$vshtmp\\" . $outfilename_base . ".tmp"; - -# $outhdrfilename = "$vshtmp\\" . $outfilename_base . ".h"; -# unlink $outhdrfilename; - - open OUTPUT, ">$outfilename" || die; - print OUTPUT @output; - close OUTPUT; - - $g_TimingBlocks{"inner4"} += SampleTime() - $start; - $start = SampleTime(); - - local( $instructionCount ) = &CountInstructions( @output ); - $g_TimingBlocks{"inner5"} += SampleTime() - $start; - - local( $debug ); - - $debug = 1; -# for( $debug = 1; $debug >= 0; $debug-- ) - { - # assemble the vertex shader - unlink "shader$i.o"; - if( $g_x360 ) - { - $vsa = "..\\..\\x360xdk\\bin\\win32\\vsa"; - } - else - { - $vsa = "..\\..\\dx9sdk\\utilities\\vsa"; - } - $vsadebug = "$vsa /nologo /Foshader$i.o $outfilename"; - $vsanodebug = "$vsa /nologo /Foshader$i.o $outfilename"; - - $vsa_start_time = SampleTime(); - - if( $debug ) - { -# print $vsadebug . "\n"; - @vsaoutput = `$vsadebug 2>&1`; -# print @vsaoutput; - } - else - { - @vsaoutput = `$vsanodebug 2>&1`; - } - - $vsa_total_time += SampleTime() - $vsa_start_time; - - $start = SampleTime(); - - &TranslateErrorMessages( @vsaoutput ); - - $g_TimingBlocks{"inner6"} += SampleTime() - $start; - - push @finalheader, @hdr; - } -} - - -$main_total_time = SampleTime() - $main_start_time; - -# stick info about the shaders at the end of the inc file. -push @finalheader, "static PrecompiledShaderByteCode_t $filename_base" . "_vertex_shaders[] = {\n"; -for( $i = 0; $i < $numCombos; $i++ ) -{ - $outfilename_base = $filename_base . "_" . $i; - push @finalheader, "{ $outfilename_base, sizeof( $outfilename_base ) },\n"; -} -push @finalheader, "};\n"; - - -push @finalheader, "struct $filename_base" . "_VertexShader_t : public PrecompiledShader_t\n"; -push @finalheader, "{\n"; -push @finalheader, "\t$filename_base" . "_VertexShader_t()\n"; -push @finalheader, "\t{\n"; -push @finalheader, "\t\tm_nFlags = 0;\n"; - -$flags = 0; -#push @finalheader, "\t\tppVertexShaders = $filename_base" . "_vertex_shaders;\n"; -push @finalheader, "\t\tm_pByteCode = $filename_base" . "_vertex_shaders;\n"; -push @finalheader, "\t\tm_pName = \"$filename_base\";\n"; -push @finalheader, "\t\tm_nShaderCount = " . ( $maxNumBones + 1 ) * $totalFogCombos * $totalLightCombos . ";\n"; -push @finalheader, "\t\tm_nDynamicCombos = m_nShaderCount;\n"; -push @finalheader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n"; -push @finalheader, "\t}\n"; -push @finalheader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n"; -push @finalheader, "\t{\n"; -push @finalheader, "\t\treturn m_pByteCode[shaderID];\n"; -push @finalheader, "\t}\n"; -push @finalheader, "};\n"; -push @finalheader, "static $filename_base" . "_VertexShader_t $filename_base" . "_VertexShaderInstance;\n"; - -# Write the final header file with the compiled vertex shader programs. -$finalheadername = "$vshtmp\\" . $filename_base . ".inc"; -#print "writing $finalheadername\n"; -#open FINALHEADER, ">$finalheadername" || die; -#print FINALHEADER @finalheader; -#close FINALHEADER; - -&MakeDirHier( "shaders/vsh" ); - -my $vcsName = ""; -if( $g_x360 ) -{ - $vcsName = $filename_base . ".360.vcs"; -} -else -{ - $vcsName = $filename_base . ".vcs"; -} -open COMPILEDSHADER, ">shaders/vsh/$vcsName" || die; -binmode( COMPILEDSHADER ); - -# -# Write out the part of the header that we know. . we'll write the rest after writing the object code. -# - -# Pack arguments -my $sInt = "i"; -my $uInt = "I"; -if ( $g_x360 ) -{ - # Change arguments to "big endian long" - $sInt = "N"; - $uInt = "N"; -} - -my $undecoratedinput = join "", &ReadInputFileWithoutLineInfo( $filename ); -#print STDERR "undecoratedinput: $undecoratedinput\n"; -my $crc = crc32( $undecoratedinput ); -#print STDERR "crc for $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, $flags; -# centroid mask -print COMPILEDSHADER pack $uInt, 0; -# reference size -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" || die; - 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; - -$total_time = SampleTime() - $total_start_time; - -if ( $ShowTimers ) -{ - print "\n\n"; - print sprintf( "Main loop time : %0.4f sec, (%0.2f%%)\n", $main_total_time, 100*$main_total_time / $total_time ); - print sprintf( "Inner1 time : %0.4f sec, (%0.2f%%)\n", $inner1_total_time, 100*$inner1_total_time / $total_time ); - print sprintf( "VSA time : %0.4f sec, (%0.2f%%)\n", $vsa_total_time, 100*$vsa_total_time / $total_time ); - print sprintf( "eval() time : %0.4f sec, (%0.2f%%)\n", $eval_total_time, 100*$eval_total_time / $total_time ); - print sprintf( "UsesRegister time: %0.4f sec, (%0.2f%%)\n", $usesr_total_time, 100*$usesr_total_time / $total_time ); - - foreach $key ( keys %g_TimingBlocks ) - { - print sprintf( "$key time: %0.4f sec, (%0.2f%%)\n", $g_TimingBlocks{$key}, 100*$g_TimingBlocks{$key} / $total_time ); - } - - print sprintf( "Total time : %0.4f sec\n", $total_time ); -} - diff --git a/devtools/gcc9+support.cpp b/devtools/gcc9+support.cpp new file mode 100644 index 00000000..6ab7c971 --- /dev/null +++ b/devtools/gcc9+support.cpp @@ -0,0 +1,59 @@ +// compatibility with old ABI +#if __GNUC__ >= 9 +#include + +extern "C" double __pow_finite(double a, double b) +{ + return pow(a, b); +} + +extern "C" double __log_finite(double a) +{ + return log(a); +} + +extern "C" double __exp_finite(double a) +{ + return exp(a); +} + +extern "C" double __atan2_finite(double a, double b) +{ + return atan2(a, b); +} + +extern "C" double __atan2f_finite(double a, double b) +{ + return atan2f(a, b); +} + +extern "C" float __powf_finite(float a, float b) +{ + return powf(a, b); +} + +extern "C" float __logf_finite(float a) +{ + return logf(a); +} + +extern "C" float __expf_finite(float a) +{ + return expf(a); +} + +extern "C" float __acosf_finite(float a) +{ + return acosf(a); +} + +extern "C" double __asin_finite(double a) +{ + return asin(a); +} + +extern "C" double __acos_finite(double a) +{ + return acos(a); +} +#endif diff --git a/devtools/gendbg.sh b/devtools/gendbg.sh old mode 100644 new mode 100755 index 780533e8..3bf30781 --- a/devtools/gendbg.sh +++ b/devtools/gendbg.sh @@ -1,6 +1,6 @@ #!/bin/bash -OBJCOPY=$STEAM_RUNTIME_PATH/bin/objcopy +OBJCOPY=objcopy function usage { echo "$0 /path/to/input/file [-o /path/to/output/file ]" diff --git a/devtools/linux/env.sh b/devtools/linux/env.sh new file mode 100755 index 00000000..56339132 --- /dev/null +++ b/devtools/linux/env.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +pushd() +{ + command pushd "$@" > /dev/null || exit +} + +popd() +{ + command popd > /dev/null || exit +} + +source() +{ + command source "$@" > /dev/null +} + +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit + +export MOD="vance" + +export GAME_DIR="/steam/steamapps/common/Half-Life 2" +SRC_DIR="$(realpath ../..)" +export SRC_DIR +ROOT_DIR="$(realpath ../../..)" +export ROOT_DIR +MOD_DIR="$(realpath "$SRC_DIR/../game/$MOD")" +export MOD_DIR + +popd || exit diff --git a/devtools/linux/game-wine.sh b/devtools/linux/game-wine.sh new file mode 100644 index 00000000..5b6eaacf --- /dev/null +++ b/devtools/linux/game-wine.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source env.sh + +export LD_LIBRARY_PATH="$GAME_DIR/bin:$LD_LIBRARY_PATH" + +export WINEPREFIX="$MOD_DIR/.wine" +export WINEARCH="win64" +# Only use this when running engine-local binaries +export WINEPATH="$GAME_DIR/bin:$WINEPATH" + +if [ ! -d "$WINEPREFIX" ]; then + echo Creating Wine prefix... + mkdir -p "$WINEPREFIX" + + # Configure registry + run wine regedit "$SRC_DIR/devtools/linux/wine-theme.reg" + #run wine regedit "$SRC_DIR/devtools/linux/wine-breeze-dark.reg" +fi + +run() { + echo "run(): $*" + pushd "$GAME_DIR" || exit > /dev/null + eval "$*" + popd || exit > /dev/null +} + +popd || exit diff --git a/devtools/linux/gdb-sdl2-show-cursor-on-stop.py b/devtools/linux/gdb-sdl2-show-cursor-on-stop.py new file mode 100755 index 00000000..8d674120 --- /dev/null +++ b/devtools/linux/gdb-sdl2-show-cursor-on-stop.py @@ -0,0 +1,10 @@ +import gdb +from gdb.printing import PrettyPrinter + +""" +Hook up the "stop" event +""" +def stop_handler(event): + gdb.execute("sdl2-ungrab-cursor") + +gdb.events.stop.connect(stop_handler) diff --git a/devtools/linux/gdb-sdl2-show-cursor.py b/devtools/linux/gdb-sdl2-show-cursor.py new file mode 100755 index 00000000..fd3f17dc --- /dev/null +++ b/devtools/linux/gdb-sdl2-show-cursor.py @@ -0,0 +1,21 @@ +import gdb +from gdb.printing import PrettyPrinter + +""" +Simple command to show the cursor when debugging source +When the game crashes, the cursor will not be shown automatically. +""" +class SDL2ShowCursor(gdb.Command): + def __init__(self): + super(SDL2ShowCursor, self).__init__("sdl2-ungrab-cursor", gdb.COMMAND_USER) + + def invoke(self, arg, from_tty): + # I have literally no clue what is necessary or not + try: + gdb.execute("call (int)SDL_ShowCursor(1)") + gdb.execute("call (void)SDL_SetWindowGrab(g_SDLWindow, SDL_FALSE)") + gdb.execute("call (int)SDL_SetRelativeMouseMode(0)") + except: + pass + +SDL2ShowCursor() diff --git a/devtools/linux/hammer++.sh b/devtools/linux/hammer++.sh new file mode 100755 index 00000000..4229b884 --- /dev/null +++ b/devtools/linux/hammer++.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source tools-wine.sh + +EXE=\"$GAME_DIR/bin/hammerplusplus.exe\" +ARGS=(-nop4) + +echo Running command \"run wine "$CMD"\" +run "wine $EXE ${ARGS[*]}" + +popd || exit diff --git a/devtools/linux/hammer.sh b/devtools/linux/hammer.sh new file mode 100755 index 00000000..ce0fdd80 --- /dev/null +++ b/devtools/linux/hammer.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source tools-wine.sh + +EXE=\"$GAME_DIR/bin/hammer.exe\" +ARGS=(-nop4) + +echo Running command \"run wine "$CMD"\" +run "wine $EXE ${ARGS[*]}" + +popd || exit diff --git a/devtools/linux/tools-wine.sh b/devtools/linux/tools-wine.sh new file mode 100644 index 00000000..832aa974 --- /dev/null +++ b/devtools/linux/tools-wine.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source env.sh + +export WINEPREFIX="$SRC_DIR/.wine" +export WINEARCH="win64" + +if [ ! -d "$WINEPREFIX" ]; then + echo Creating Wine prefix... + mkdir -p "$WINEPREFIX" + + wine64 wineboot --init + + # Configure registry + run wine regedit "$SRC_DIR/devtools/linux/wine-theme.reg" + run wine regedit "$SRC_DIR/devtools/linux/wine-breeze-dark.reg" + + # Install D3DCompiler for shadercompile + winetricks prefix="$WINEPREFIX" d3dcompiler_47 + + # Use Mono instead + # Install .NET Framework 2.0 for VTFEdit and GCFScape + #winetricks dotnet20sp2 + # Install .NET Framework 4.8 for Crowbar + #winetricks dotnet48 +fi + +run() { + echo "run(): $*" + eval "$*" +} + +popd || exit diff --git a/devtools/makefile_base_posix.mak b/devtools/makefile_base_posix.mak new file mode 100644 index 00000000..1942d6a4 --- /dev/null +++ b/devtools/makefile_base_posix.mak @@ -0,0 +1,500 @@ +# +# Base makefile for Linux and OSX +# +# !!!!! Note to future editors !!!!! +# +# before you make changes, make sure you grok: +# 1. the difference between =, :=, +=, and ?= +# 2. how and when this base makefile gets included in the generated makefile(s) +# ( see http://www.gnu.org/software/make/manual/make.html#Flavors ) +# +# Command line prefixes: +# - errors are ignored +# @ command is not printed to stdout before being executed +# + command is executed even if Make is invoked in "do not exec" mode + +OS := $(shell uname) +HOSTNAME := $(shell hostname) + +-include $(SRCROOT)/devtools/steam_def.mak +-include $(SRCROOT)/devtools/sourcesdk_def.mak + +# To build with clang, set the following in your environment: +# CC = clang +# CXX = clang++ + +ifeq ($(CFG), release) + # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3. + # There also was no speed difference running at 1280x1024. May 2012, mikesart. + # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3. + # -fno-omit-frame-pointer: need this for stack traces with perf. + OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops +else + OptimizerLevel_CompilerSpecific = -O0 + #-O1 -finline-functions +endif + +# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags" +ARCH_FLAGS = +BUILDING_MULTI_ARCH = 0 +# Preserve cflags set in environment +ENV_CFLAGS := $(CFLAGS) +ENV_CXXFLAGS := $(CXXFLAGS) +CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) )) +BASE_CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE +CFLAGS = $(BASE_CFLAGS) $(ENV_CFLAGS) +# In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive +# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+. +ifeq ($(CXX),clang++) + CXXFLAGS = $(CFLAGS) -std=gnu++0x -Wno-c++11-narrowing -Wno-dangling-else $(ENV_CXXFLAGS) +else +# !!! ABI COMPAT: -fabi-compat-version=2 is needed to generate the proper symbols for linking + CXXFLAGS = $(CFLAGS) -std=c++20 -fpermissive -fabi-compat-version=2 $(ENV_CXXFLAGS) +endif +DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE +LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel) +GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P) +MAP_FLAGS = + + +ifeq ($(STEAM_BRANCH),1) + WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof +else + WARN_FLAGS = -Wno-write-strings -Wno-multichar +endif + +WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security + + +ifeq ($(OS),Linux) + # We should always specify -Wl,--build-id, as documented at: + # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId + LDFLAGS += -Wl,--build-id + # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path. + # Dedicated server uses this. + ifeq ($(USE_VALVE_BINDIR),1) + # dedicated server flags + ifeq ($(TARGET_PLATFORM),linux64) + VALVE_BINDIR = /valve/bin64/ + MARCH_TARGET = nocona + else + VALVE_BINDIR = /valve/bin/ + MARCH_TARGET = pentium4 + endif + STRIP_FLAGS = + else + # linux desktop client flags + VALVE_BINDIR = + # If the steam-runtime is available, use it. We should just default to using it when + # buildbot and everyone has a bit of time to get it installed. + ifneq "$(wildcard /valve/steam-runtime/bin/)" "" + # The steam-runtime is incompatible with clang at this point, so disable it + # if clang is enabled. + ifneq ($(CXX),clang++) + VALVE_BINDIR = /valve/steam-runtime/bin/ + endif + endif + GCC_VER = + MARCH_TARGET = pentium4 + # On dedicated servers, some plugins depend on global variable symbols in addition to functions. + # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2. + STRIP_FLAGS = -x + endif + + ifeq ($(CXX),clang++) + # Clang does not support -mfpmath=sse because it uses whatever + # instruction set extensions are available by default. + SSE_GEN_FLAGS = -msse2 + else + SSE_GEN_FLAGS = -msse2 -mfpmath=sse + endif + + CCACHE := $(SRCROOT)/devtools/bin/linux/ccache + + ifeq ($(origin GCC_VER), undefined) + GCC_VER=-4.6 + endif + ifeq ($(origin AR), default) + AR = $(VALVE_BINDIR)ar crs + endif + ifeq ($(origin CC),default) + CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER) + endif + ifeq ($(origin CXX), default) + CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER) + endif + # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to + # a ccache quirk. Could also upgrade ccache. + # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html + ifeq ($(CC),clang) + CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments + endif + ifeq ($(CXX),clang++) + CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments + endif + LINK ?= $(CC) + + ifeq ($(TARGET_PLATFORM),linux64) + # nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2) + ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2 + LD_SO = ld-linux-x86_64.so.2 + LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a) + LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a) + else + # pentium4 = MMX, SSE, SSE2 - no SSE3 (added in prescott) # -msse3 -mfpmath=sse + ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=core2 $(SSE_GEN_FLAGS) + LD_SO = ld-linux.so.2 + LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LDFLAGS += -m32 + endif + + GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh + ifeq ($(CFG),release) + STRIP ?= strip $(STRIP_FLAGS) -S + # CFLAGS += -ffunction-sections -fdata-sections + # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections + else + STRIP ?= true + endif + VSIGN ?= true + + LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map + + SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined + + _WRAP := -Xlinker --wrap= + PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \ + $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \ + $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \ + $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \ + $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath + + LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread + + LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt + +endif + +ifeq ($(OS),Darwin) + CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache + MAC_SDK_VER ?= 10.6 + MAC_SDK := macosx$(MAC_SDK_VER) + SYSROOT := $(shell xcodebuild -sdk $(MAC_SDK) -version Path) + + ifneq ($(origin MAC_SDK_VER), file) + $(warning Attempting build with SDK version $(MAC_SDK_VER), only 10.6 is supported and recommended!) + endif + + ifeq ($(SYSROOT),) + FIRSTSDK := $(firstword $(sort $(shell xcodebuild -showsdks | grep macosx | sed 's/.*macosx//'))) + $(error Could not find SDK version $(MAC_SDK_VER). Install and configure Xcode 4.3, or build with: make MAC_SDK_VER=$(FIRSTSDK)) + endif + + ifeq ($(origin CC), default) + # Test to see if you have a compiler in the right place, if you + # don't abort with an error + CLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang) + ifeq ($(wildcard $(CLANG)),) + $(error Unable to find C compiler, install and configure Xcode 4.3) + endif + + CC := $(CCACHE) $(CLANG) -Qunused-arguments + endif + + ifeq ($(origin CXX), default) + CXXLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang++) + ifeq ($(wildcard $(CXXLANG)),) + $(error Unable to find C++ compiler, install and configure Xcode 4.3) + endif + + CXX := $(CCACHE) $(CXXLANG) -Qunused-arguments + endif + LINK ?= $(CXX) + + ifeq ($(origin AR), default) + AR := $(shell xcrun -sdk $(MAC_SDK) -find libtool) -static -o + endif + + ifeq ($(TARGET_PLATFORM),osx64) + ARCH_FLAGS += -arch x86_64 -m64 -march=core2 + else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags))) + ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2 + else + # dirty hack to build a universal binary - don't specify the architecture + ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2 + endif + + GEN_SYM ?= $(shell xcrun -sdk $(MAC_SDK) -find dsymutil) + ifeq ($(CFG),release) + STRIP ?= strip -S + else + STRIP ?= true + endif + ifeq ($(SOURCE_SDK), 1) + VSIGN ?= true + else + VSIGN ?= $(SRCROOT)/devtools/bin/vsign + endif + + CPPFLAGS += -I$(SYSROOT)/usr/include/malloc + CFLAGS += -isysroot $(SYSROOT) -mmacosx-version-min=10.5 -fasm-blocks + + LIB_START_EXE = -lm -ldl -lpthread + LIB_END_EXE = + + LIB_START_SHLIB = + LIB_END_SHLIB = + + SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + + ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE))) + SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + endif + +endif + +# +# Profile-directed optimizations. +# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%! +# +# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are. +# PROFILE_LINKER_FLAG=-fprofile-arcs +# PROFILE_COMPILER_FLAG=-fprofile-arcs +# +# Then, comment the above flags out again and rebuild with this flag uncommented: +# PROFILE_COMPILER_FLAG=-fprofile-use +# + +############################################################################# +# The compiler command lne for each src code file to compile +############################################################################# + +OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG) +CPP_TO_OBJ = $(CPPFILES:.cpp=.o) +CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o) +CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o) +MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o) +C_TO_OBJ = $(MM_TO_OBJ:.c=.o) +OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ))) + +ifeq ($(MAKE_VERBOSE),1) + QUIET_PREFIX = + QUIET_ECHO_POSTFIX = +else + QUIET_PREFIX = @ + QUIET_ECHO_POSTFIX = > /dev/null +endif + +ifeq ($(MAKE_CC_VERBOSE),1) +CC += -v +endif + +ifeq ($(CONFTYPE),lib) + LIB_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),dll) + SO_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),exe) + EXE_File = $(OUTPUTFILE) +endif + +# we generate dependencies as a side-effect of compilation now +GEN_DEP_FILE= + +PRE_COMPILE_FILE = + +POST_COMPILE_FILE = + +ifeq ($(BUILDING_MULTI_ARCH),1) + SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS)) + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \ + $(CXX) $(CXXFLAGS) -o $@ -c $< +else + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) ----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< +endif + +ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined" + P4_EDIT_START = chmod -R +w + P4_EDIT_END = || true + P4_REVERT_START = true + P4_REVERT_END = +else + ifndef P4_EDIT_CHANGELIST + # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default + # setting is best, but here is an alternate example: + # export P4_EDIT_CHANGELIST_CMD="echo 1424335" + # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed. + P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1 + P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD)) + endif + ifeq ($(P4_EDIT_CHANGELIST),) + # If we haven't found a changelist to check out to then create one. The name must match the one from a few + # lines above or else a new changelist will be created each time. + # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be + # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which + # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command. + P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ') + endif + + P4_EDIT_START := for f in + P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) + P4_REVERT_START := for f in + P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) +endif + +ifeq ($(CONFTYPE),dll) +all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE) + @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX) +else +all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE) + @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX) +endif + +.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile + + +rebuild : + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) + + +# Use the relink target to force to relink the project. +relink: RemoveOutputFile all + +RemoveOutputFile: + rm -f $(OUTPUTFILE) + + +# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file. +# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that. +SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + @echo "" + +RemoveSingleFile: + $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + +clean: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 revert $(OUTPUTFILE)"; \ + $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \ + fi; +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)" + $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END) +endif + + +# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the +# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave +# us with archive files that have extra unused symbols, and also potentially cause compilation errors +# when you rename a file and have many duplicate symbols. +cleanandremove: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) -rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \ + $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \ + fi; + $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT); +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)" + $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END) + $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE) +endif + + +# This just deletes the final targets so it'll do a relink next time we build. +cleantargets: + $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE) + + +$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS) + $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END); + $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES); + +SO_GameOutputFile = $(GAMEOUTPUTFILE) + +# Remove the target before installing a file over it; this prevents existing +# instances of the game from crashing due to the overwrite. +$(SO_GameOutputFile): $(SO_File) + $(QUIET_PREFIX) \ + $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END); + $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null; + $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \ + mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \ + cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \ + fi; + + +$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB); + $(VSIGN) -signvalve $(OUTPUTFILE); + + +$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING EXE $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\ + $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE); + + +tags: + etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx diff --git a/devtools/makefile_base_posix.mak.default b/devtools/makefile_base_posix.mak.default new file mode 100644 index 00000000..d86efb38 --- /dev/null +++ b/devtools/makefile_base_posix.mak.default @@ -0,0 +1,509 @@ +# +# Base makefile for Linux and OSX +# +# !!!!! Note to future editors !!!!! +# +# before you make changes, make sure you grok: +# 1. the difference between =, :=, +=, and ?= +# 2. how and when this base makefile gets included in the generated makefile(s) +# ( see http://www.gnu.org/software/make/manual/make.html#Flavors ) +# +# Command line prefixes: +# - errors are ignored +# @ command is not printed to stdout before being executed +# + command is executed even if Make is invoked in "do not exec" mode + +OS := $(shell uname) +HOSTNAME := $(shell hostname) + +-include $(SRCROOT)/devtools/steam_def.mak +-include $(SRCROOT)/devtools/sourcesdk_def.mak + +# To build with clang, set the following in your environment: +# CC = clang +# CXX = clang++ + +ifeq ($(CFG), release) + # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3. + # There also was no speed difference running at 1280x1024. May 2012, mikesart. + # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3. + # -fno-omit-frame-pointer: need this for stack traces with perf. + OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops +else + OptimizerLevel_CompilerSpecific = -O0 + #-O1 -finline-functions +endif + +# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags" +ARCH_FLAGS = +BUILDING_MULTI_ARCH = 0 +CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) )) +CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE +# In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive +# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+. +ifeq ($(CXX),clang++) + CXXFLAGS = $(CFLAGS) -std=gnu++0x -Wno-c++11-narrowing -Wno-dangling-else +else + CXXFLAGS = $(CFLAGS) -std=gnu++0x -fpermissive +endif +DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE +LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel) +GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P) +MAP_FLAGS = +Srv_GAMEOUTPUTFILE = +COPY_DLL_TO_SRV = 0 + + +ifeq ($(STEAM_BRANCH),1) + WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof +else + WARN_FLAGS = -Wno-write-strings -Wno-multichar +endif + +WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security + + +ifeq ($(OS),Linux) + # We should always specify -Wl,--build-id, as documented at: + # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId + LDFLAGS += -Wl,--build-id + # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path. + # Dedicated server uses this. + ifeq ($(USE_VALVE_BINDIR),1) + # dedicated server flags + ifeq ($(TARGET_PLATFORM),linux64) + VALVE_BINDIR = /valve/bin64/ + MARCH_TARGET = nocona + else + VALVE_BINDIR = /valve/bin/ + MARCH_TARGET = pentium4 + endif + STRIP_FLAGS = + else + # linux desktop client flags + VALVE_BINDIR = + # If the steam-runtime is available, use it. We should just default to using it when + # buildbot and everyone has a bit of time to get it installed. + ifneq "$(wildcard /valve/steam-runtime/bin/)" "" + # The steam-runtime is incompatible with clang at this point, so disable it + # if clang is enabled. + ifneq ($(CXX),clang++) + VALVE_BINDIR = /valve/steam-runtime/bin/ + endif + endif + GCC_VER = + MARCH_TARGET = pentium4 + # On dedicated servers, some plugins depend on global variable symbols in addition to functions. + # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2. + STRIP_FLAGS = -x + endif + + ifeq ($(CXX),clang++) + # Clang does not support -mfpmath=sse because it uses whatever + # instruction set extensions are available by default. + SSE_GEN_FLAGS = -msse2 + else + SSE_GEN_FLAGS = -msse2 -mfpmath=sse + endif + + CCACHE := $(SRCROOT)/devtools/bin/linux/ccache + + ifeq ($(origin GCC_VER), undefined) + GCC_VER=-4.6 + endif + ifeq ($(origin AR), default) + AR = $(VALVE_BINDIR)ar crs + endif + ifeq ($(origin CC),default) + CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER) + endif + ifeq ($(origin CXX), default) + CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER) + endif + # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to + # a ccache quirk. Could also upgrade ccache. + # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html + ifeq ($(CC),clang) + CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments + endif + ifeq ($(CXX),clang++) + CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments + endif + LINK ?= $(CC) + + ifeq ($(TARGET_PLATFORM),linux64) + # nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2) + ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2 + LD_SO = ld-linux-x86_64.so.2 + LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a) + LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a) + else + # pentium4 = MMX, SSE, SSE2 - no SSE3 (added in prescott) # -msse3 -mfpmath=sse + ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=core2 $(SSE_GEN_FLAGS) + LD_SO = ld-linux.so.2 + LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LDFLAGS += -m32 + endif + + GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh + ifeq ($(CFG),release) + STRIP ?= strip $(STRIP_FLAGS) -S + # CFLAGS += -ffunction-sections -fdata-sections + # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections + else + STRIP ?= true + endif + VSIGN ?= true + + ifeq ($(SOURCE_SDK), 1) + Srv_GAMEOUTPUTFILE := $(GAMEOUTPUTFILE:.so=_srv.so) + COPY_DLL_TO_SRV := 1 + endif + + LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map + + SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined + + _WRAP := -Xlinker --wrap= + PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \ + $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \ + $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \ + $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \ + $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath + + LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread + + LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt + +endif + +ifeq ($(OS),Darwin) + CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache + MAC_SDK_VER ?= 10.6 + MAC_SDK := macosx$(MAC_SDK_VER) + SYSROOT := $(shell xcodebuild -sdk $(MAC_SDK) -version Path) + + ifneq ($(origin MAC_SDK_VER), file) + $(warning Attempting build with SDK version $(MAC_SDK_VER), only 10.6 is supported and recommended!) + endif + + ifeq ($(SYSROOT),) + FIRSTSDK := $(firstword $(sort $(shell xcodebuild -showsdks | grep macosx | sed 's/.*macosx//'))) + $(error Could not find SDK version $(MAC_SDK_VER). Install and configure Xcode 4.3, or build with: make MAC_SDK_VER=$(FIRSTSDK)) + endif + + ifeq ($(origin CC), default) + # Test to see if you have a compiler in the right place, if you + # don't abort with an error + CLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang) + ifeq ($(wildcard $(CLANG)),) + $(error Unable to find C compiler, install and configure Xcode 4.3) + endif + + CC := $(CCACHE) $(CLANG) -Qunused-arguments + endif + + ifeq ($(origin CXX), default) + CXXLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang++) + ifeq ($(wildcard $(CXXLANG)),) + $(error Unable to find C++ compiler, install and configure Xcode 4.3) + endif + + CXX := $(CCACHE) $(CXXLANG) -Qunused-arguments + endif + LINK ?= $(CXX) + + ifeq ($(origin AR), default) + AR := $(shell xcrun -sdk $(MAC_SDK) -find libtool) -static -o + endif + + ifeq ($(TARGET_PLATFORM),osx64) + ARCH_FLAGS += -arch x86_64 -m64 -march=core2 + else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags))) + ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2 + else + # dirty hack to build a universal binary - don't specify the architecture + ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2 + endif + + GEN_SYM ?= $(shell xcrun -sdk $(MAC_SDK) -find dsymutil) + ifeq ($(CFG),release) + STRIP ?= strip -S + else + STRIP ?= true + endif + ifeq ($(SOURCE_SDK), 1) + VSIGN ?= true + else + VSIGN ?= $(SRCROOT)/devtools/bin/vsign + endif + + CPPFLAGS += -I$(SYSROOT)/usr/include/malloc + CFLAGS += -isysroot $(SYSROOT) -mmacosx-version-min=10.5 -fasm-blocks + + LIB_START_EXE = -lm -ldl -lpthread + LIB_END_EXE = + + LIB_START_SHLIB = + LIB_END_SHLIB = + + SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + + ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE))) + SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + endif + +endif + +# +# Profile-directed optimizations. +# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%! +# +# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are. +# PROFILE_LINKER_FLAG=-fprofile-arcs +# PROFILE_COMPILER_FLAG=-fprofile-arcs +# +# Then, comment the above flags out again and rebuild with this flag uncommented: +# PROFILE_COMPILER_FLAG=-fprofile-use +# + +############################################################################# +# The compiler command lne for each src code file to compile +############################################################################# + +OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG) +CPP_TO_OBJ = $(CPPFILES:.cpp=.o) +CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o) +CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o) +MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o) +C_TO_OBJ = $(MM_TO_OBJ:.c=.o) +OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ))) + +ifeq ($(MAKE_VERBOSE),1) + QUIET_PREFIX = + QUIET_ECHO_POSTFIX = +else + QUIET_PREFIX = @ + QUIET_ECHO_POSTFIX = > /dev/null +endif + +ifeq ($(MAKE_CC_VERBOSE),1) +CC += -v +endif + +ifeq ($(CONFTYPE),lib) + LIB_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),dll) + SO_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),exe) + EXE_File = $(OUTPUTFILE) +endif + +# we generate dependencies as a side-effect of compilation now +GEN_DEP_FILE= + +PRE_COMPILE_FILE = + +POST_COMPILE_FILE = + +ifeq ($(BUILDING_MULTI_ARCH),1) + SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS)) + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \ + $(CXX) $(CXXFLAGS) -o $@ -c $< +else + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) ----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< +endif + +ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined" + P4_EDIT_START = chmod -R +w + P4_EDIT_END = || true + P4_REVERT_START = true + P4_REVERT_END = +else + ifndef P4_EDIT_CHANGELIST + # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default + # setting is best, but here is an alternate example: + # export P4_EDIT_CHANGELIST_CMD="echo 1424335" + # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed. + P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1 + P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD)) + endif + ifeq ($(P4_EDIT_CHANGELIST),) + # If we haven't found a changelist to check out to then create one. The name must match the one from a few + # lines above or else a new changelist will be created each time. + # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be + # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which + # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command. + P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ') + endif + + P4_EDIT_START := for f in + P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) + P4_REVERT_START := for f in + P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) +endif + +ifeq ($(CONFTYPE),dll) +all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE) + @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX) +else +all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE) + @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX) +endif + +.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile + + +rebuild : + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) + + +# Use the relink target to force to relink the project. +relink: RemoveOutputFile all + +RemoveOutputFile: + rm -f $(OUTPUTFILE) + + +# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file. +# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that. +SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + @echo "" + +RemoveSingleFile: + $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + +clean: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 revert $(OUTPUTFILE)"; \ + $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \ + fi; +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)" + $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END) +endif + + +# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the +# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave +# us with archive files that have extra unused symbols, and also potentially cause compilation errors +# when you rename a file and have many duplicate symbols. +cleanandremove: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) -rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \ + $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \ + fi; + $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT); +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)" + $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END) + $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE) +endif + + +# This just deletes the final targets so it'll do a relink next time we build. +cleantargets: + $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE) + + +$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS) + $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END); + $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES); + +SO_GameOutputFile = $(GAMEOUTPUTFILE) + +# Remove the target before installing a file over it; this prevents existing +# instances of the game from crashing due to the overwrite. +$(SO_GameOutputFile): $(SO_File) + $(QUIET_PREFIX) \ + $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END); + $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null; + $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) if [ "$(COPY_DLL_TO_SRV)" = "1" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $(Srv_GAMEOUTPUTFILE) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + cp -v $(GAMEOUTPUTFILE) $(Srv_GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);\ + cp -v $(GAMEOUTPUTFILE)$(SYM_EXT) $(Srv_GAMEOUTPUTFILE)$(SYM_EXT) $(QUIET_ECHO_POSTFIX);\ + fi; + $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \ + mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \ + cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \ + fi; + + +$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB); + $(VSIGN) -signvalve $(OUTPUTFILE); + + +$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING EXE $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\ + $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE); + + +tags: + etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx diff --git a/devtools/makefile_base_posix.mak.gcc8 b/devtools/makefile_base_posix.mak.gcc8 new file mode 100644 index 00000000..97178245 --- /dev/null +++ b/devtools/makefile_base_posix.mak.gcc8 @@ -0,0 +1,507 @@ +# +# Base makefile for Linux and OSX +# +# !!!!! Note to future editors !!!!! +# +# before you make changes, make sure you grok: +# 1. the difference between =, :=, +=, and ?= +# 2. how and when this base makefile gets included in the generated makefile(s) +# ( see http://www.gnu.org/software/make/manual/make.html#Flavors ) +# +# Command line prefixes: +# - errors are ignored +# @ command is not printed to stdout before being executed +# + command is executed even if Make is invoked in "do not exec" mode + +OS := $(shell uname) +HOSTNAME := $(shell hostname) + +-include $(SRCROOT)/devtools/steam_def.mak +-include $(SRCROOT)/devtools/sourcesdk_def.mak + +# To build with clang, set the following in your environment: +# CC = clang +# CXX = clang++ + +ifeq ($(CFG), release) + # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3. + # There also was no speed difference running at 1280x1024. May 2012, mikesart. + # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3. + # -fno-omit-frame-pointer: need this for stack traces with perf. + OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops +else + OptimizerLevel_CompilerSpecific = -Og + #-O1 -finline-functions +endif + +# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags" +ARCH_FLAGS = -fabi-compat-version=2 -fabi-version=2 -fpic -fno-plt -fcf-protection=none -fno-stack-protector -fno-stack-clash-protection +BUILDING_MULTI_ARCH = 0 +CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) )) +CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE +# In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive +# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+. +ifeq ($(CXX),clang++) + CXXFLAGS = $(CFLAGS) -std=gnu++0x -Wno-c++11-narrowing -Wno-dangling-else +else + CXXFLAGS = $(CFLAGS) -std=gnu++0x -Wno-narrowing -fpermissive +endif +DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE -D_GLIBCXX_USE_CXX11_ABI=0 +LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel) -fuse-ld=gold +GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P) +MAP_FLAGS = +Srv_GAMEOUTPUTFILE = +COPY_DLL_TO_SRV = 0 + + +ifeq ($(STEAM_BRANCH),1) + WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof +else + WARN_FLAGS = -Wno-write-strings -Wno-multichar +endif + +WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security + + +ifeq ($(OS),Linux) + # We should always specify -Wl,--build-id, as documented at: + # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId + LDFLAGS += -Wl,--build-id + # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path. + # Dedicated server uses this. + ifeq ($(USE_VALVE_BINDIR),1) + # dedicated server flags + ifeq ($(TARGET_PLATFORM),linux64) + VALVE_BINDIR = /valve/bin64/ + else + VALVE_BINDIR = /valve/bin/ + endif + STRIP_FLAGS = + else + # linux desktop client flags + VALVE_BINDIR = + # If the steam-runtime is available, use it. We should just default to using it when + # buildbot and everyone has a bit of time to get it installed. + ifneq "$(wildcard /valve/steam-runtime/bin/)" "" + # The steam-runtime is incompatible with clang at this point, so disable it + # if clang is enabled. + ifneq ($(CXX),clang++) + VALVE_BINDIR = /valve/steam-runtime/bin/ + endif + endif + GCC_VER = + # On dedicated servers, some plugins depend on global variable symbols in addition to functions. + # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2. + STRIP_FLAGS = -x + endif + # nocona = MMX, SSE, SSE2, SSE3 + MARCH_TARGET = nocona + MTUNE_TARGET = generic + + ifeq ($(CXX),clang++) + # Clang does not support -mfpmath=sse because it uses whatever + # instruction set extensions are available by default. + SSE_GEN_FLAGS = -msse2 + else + SSE_GEN_FLAGS = -msse2 -mfpmath=sse + endif + + CCACHE := $(SRCROOT)/devtools/bin/linux/ccache + + ifeq ($(origin GCC_VER), undefined) + GCC_VER=-4.6 + endif + ifeq ($(origin AR), default) + AR = $(VALVE_BINDIR)ar crs + endif + ifeq ($(origin CC),default) + CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER) + endif + ifeq ($(origin CXX), default) + CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER) + endif + # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to + # a ccache quirk. Could also upgrade ccache. + # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html + ifeq ($(CC),clang) + CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments + endif + ifeq ($(CXX),clang++) + CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments + endif + LINK ?= $(CC) + + ifeq ($(TARGET_PLATFORM),linux64) + ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=$(MTUNE_TARGET) + LD_SO = ld-linux-x86_64.so.2 + LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a) + LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a) + else + ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=$(MTUNE_TARGET) + LD_SO = ld-linux.so.2 + LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) + LDFLAGS += -m32 + endif + + GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh + ifeq ($(CFG),release) + STRIP ?= strip $(STRIP_FLAGS) -S + # CFLAGS += -ffunction-sections -fdata-sections + # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections + else + STRIP ?= true + endif + VSIGN ?= true + + ifeq ($(SOURCE_SDK), 1) + Srv_GAMEOUTPUTFILE := $(GAMEOUTPUTFILE:.so=_srv.so) + COPY_DLL_TO_SRV := 1 + endif + + LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map + + SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined + + _WRAP := -Xlinker --wrap= + PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \ + $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \ + $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \ + $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \ + $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath + + LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread + + LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group + LIB_END_SHLIB = -Wl,--end-group $(SRCROOT)/devtools/gcc9+support.o -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt + +endif + +ifeq ($(OS),Darwin) + CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache + MAC_SDK_VER ?= 10.6 + MAC_SDK := macosx$(MAC_SDK_VER) + SYSROOT := $(shell xcodebuild -sdk $(MAC_SDK) -version Path) + + ifneq ($(origin MAC_SDK_VER), file) + $(warning Attempting build with SDK version $(MAC_SDK_VER), only 10.6 is supported and recommended!) + endif + + ifeq ($(SYSROOT),) + FIRSTSDK := $(firstword $(sort $(shell xcodebuild -showsdks | grep macosx | sed 's/.*macosx//'))) + $(error Could not find SDK version $(MAC_SDK_VER). Install and configure Xcode 4.3, or build with: make MAC_SDK_VER=$(FIRSTSDK)) + endif + + ifeq ($(origin CC), default) + # Test to see if you have a compiler in the right place, if you + # don't abort with an error + CLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang) + ifeq ($(wildcard $(CLANG)),) + $(error Unable to find C compiler, install and configure Xcode 4.3) + endif + + CC := $(CCACHE) $(CLANG) -Qunused-arguments + endif + + ifeq ($(origin CXX), default) + CXXLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang++) + ifeq ($(wildcard $(CXXLANG)),) + $(error Unable to find C++ compiler, install and configure Xcode 4.3) + endif + + CXX := $(CCACHE) $(CXXLANG) -Qunused-arguments + endif + LINK ?= $(CXX) + + ifeq ($(origin AR), default) + AR := $(shell xcrun -sdk $(MAC_SDK) -find libtool) -static -o + endif + + ifeq ($(TARGET_PLATFORM),osx64) + ARCH_FLAGS += -arch x86_64 -m64 -march=core2 + else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags))) + ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2 + else + # dirty hack to build a universal binary - don't specify the architecture + ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2 + endif + + GEN_SYM ?= $(shell xcrun -sdk $(MAC_SDK) -find dsymutil) + ifeq ($(CFG),release) + STRIP ?= strip -S + else + STRIP ?= true + endif + ifeq ($(SOURCE_SDK), 1) + VSIGN ?= true + else + VSIGN ?= $(SRCROOT)/devtools/bin/vsign + endif + + CPPFLAGS += -I$(SYSROOT)/usr/include/malloc + CFLAGS += -isysroot $(SYSROOT) -mmacosx-version-min=10.5 -fasm-blocks + + LIB_START_EXE = -lm -ldl -lpthread + LIB_END_EXE = + + LIB_START_SHLIB = + LIB_END_SHLIB = + + SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + + ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE))) + SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms + endif + +endif + +# +# Profile-directed optimizations. +# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%! +# +# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are. +# PROFILE_LINKER_FLAG=-fprofile-arcs +# PROFILE_COMPILER_FLAG=-fprofile-arcs +# +# Then, comment the above flags out again and rebuild with this flag uncommented: +# PROFILE_COMPILER_FLAG=-fprofile-use +# + +############################################################################# +# The compiler command lne for each src code file to compile +############################################################################# + +OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG) +CPP_TO_OBJ = $(CPPFILES:.cpp=.o) +CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o) +CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o) +MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o) +C_TO_OBJ = $(MM_TO_OBJ:.c=.o) +OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ))) + +ifeq ($(MAKE_VERBOSE),1) + QUIET_PREFIX = + QUIET_ECHO_POSTFIX = +else + QUIET_PREFIX = @ + QUIET_ECHO_POSTFIX = > /dev/null +endif + +ifeq ($(MAKE_CC_VERBOSE),1) +CC += -v +endif + +ifeq ($(CONFTYPE),lib) + LIB_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),dll) + SO_File = $(OUTPUTFILE) +endif + +ifeq ($(CONFTYPE),exe) + EXE_File = $(OUTPUTFILE) +endif + +# we generate dependencies as a side-effect of compilation now +GEN_DEP_FILE= + +PRE_COMPILE_FILE = + +POST_COMPILE_FILE = + +ifeq ($(BUILDING_MULTI_ARCH),1) + SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS)) + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \ + $(CXX) $(CXXFLAGS) -o $@ -c $< +else + COMPILE_FILE = \ + $(QUIET_PREFIX) \ + echo "---- $(lastword $(subst /, ,$<)) ----";\ + mkdir -p $(OBJ_DIR) && \ + $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< +endif + +ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined" + P4_EDIT_START = chmod -R +w + P4_EDIT_END = || true + P4_REVERT_START = true + P4_REVERT_END = +else + ifndef P4_EDIT_CHANGELIST + # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default + # setting is best, but here is an alternate example: + # export P4_EDIT_CHANGELIST_CMD="echo 1424335" + # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed. + P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1 + P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD)) + endif + ifeq ($(P4_EDIT_CHANGELIST),) + # If we haven't found a changelist to check out to then create one. The name must match the one from a few + # lines above or else a new changelist will be created each time. + # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be + # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which + # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command. + P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ') + endif + + P4_EDIT_START := for f in + P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) + P4_REVERT_START := for f in + P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) +endif + +ifeq ($(CONFTYPE),dll) +all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE) + @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX) +else +all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE) + @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX) +endif + +.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile + + +rebuild : + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove + $(MAKE) -f $(firstword $(MAKEFILE_LIST)) + + +# Use the relink target to force to relink the project. +relink: RemoveOutputFile all + +RemoveOutputFile: + rm -f $(OUTPUTFILE) + + +# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file. +# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that. +SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + @echo "" + +RemoveSingleFile: + $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o + +clean: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 revert $(OUTPUTFILE)"; \ + $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \ + fi; +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)" + $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END) +endif + + +# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the +# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave +# us with archive files that have extra unused symbols, and also potentially cause compilation errors +# when you rename a file and have many duplicate symbols. +cleanandremove: +ifneq "$(OBJ_DIR)" "" + $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" + $(QUIET_PREFIX) -rm -rf $(OBJ_DIR) +endif +ifneq "$(OUTPUTFILE)" "" + $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ + echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \ + $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \ + fi; + $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT); +endif +ifneq "$(OTHER_DEPENDENCIES)" "" + $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" + $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES) +endif +ifneq "$(GAMEOUTPUTFILE)" "" + $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)" + $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END) + $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE) +endif + + +# This just deletes the final targets so it'll do a relink next time we build. +cleantargets: + $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE) + + +$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS) + $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END); + $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES); + +SO_GameOutputFile = $(GAMEOUTPUTFILE) + +# Remove the target before installing a file over it; this prevents existing +# instances of the game from crashing due to the overwrite. +$(SO_GameOutputFile): $(SO_File) + $(QUIET_PREFIX) \ + $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END); + $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null; + $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE); + $(QUIET_PREFIX) if [ "$(COPY_DLL_TO_SRV)" = "1" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO $(Srv_GAMEOUTPUTFILE) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + cp -v $(GAMEOUTPUTFILE) $(Srv_GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);\ + cp -v $(GAMEOUTPUTFILE)$(SYM_EXT) $(Srv_GAMEOUTPUTFILE)$(SYM_EXT) $(QUIET_ECHO_POSTFIX);\ + fi; + $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \ + mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \ + cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \ + fi; + + +$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB); + $(VSIGN) -signvalve $(OUTPUTFILE); + + +$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) + $(QUIET_PREFIX) \ + echo "----" $(QUIET_ECHO_POSTFIX);\ + echo "---- LINKING EXE $@ [$(CFG)] ----";\ + echo "----" $(QUIET_ECHO_POSTFIX);\ + \ + $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\ + $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE); + $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); + $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE); + $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE); + $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE); + + +tags: + etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx diff --git a/devtools/shadercompile/ShaderCompile.exe b/devtools/shadercompile/ShaderCompile.exe new file mode 100644 index 00000000..e40175a6 Binary files /dev/null and b/devtools/shadercompile/ShaderCompile.exe differ diff --git a/devtools/shadercompile/buildshaders.py b/devtools/shadercompile/buildshaders.py new file mode 100755 index 00000000..6df2cacd --- /dev/null +++ b/devtools/shadercompile/buildshaders.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +import sys +import os +import shutil +import multiprocessing +import subprocess +from pathlib import Path + +MOD='vance' + +def process_shaders(input, threads=1, version="30", list=False, dynamic=False): + SHADERCOMPILE_PATH = str(Path(__file__).parent.absolute() / 'ShaderCompile.exe') + dirname = str(Path(input[0]).parent) + + args = [] + env = {} + + # For windows use the exe directly, otherwise use wine + if sys.platform == 'win32' or sys.platform == 'cygwin': + args += [SHADERCOMPILE_PATH] + else: + args += ['/usr/bin/wine', SHADERCOMPILE_PATH] + env['WINEPREFIX'] = os.environ['WINEPREFIX'] + env['WINEDEBUG'] = '-all' + + args += [ + '-threads', f'{threads}', + '-ver', f'{version}', + '-verbose_processor', + '-shaderpath', str(dirname) + ] + + if dynamic: + args += '-dynamic' + + # For each line in the file, compile that specific shader + if list: + for shader in input: + shader_args = args.copy() + shader_args += [shader] + + subprocess.run(args=shader_args, cwd=dirname, env=env) + else: + with open(input[0]) as fp: + lines = fp.readlines() + for l in lines: + # Nuke comments + shader = l.split('//', 1)[0].rstrip() + if len(shader) <= 0: + continue + + shader_args = args.copy() + shader_args += [shader] + + subprocess.run(args=shader_args, cwd=dirname, env=env) + + +def main(): + version = '20b' + use_list = False + jobs = multiprocessing.cpu_count() + dynamic = False + + args = sys.argv[1:] + + for arg in args: + match arg: + case '-20b': + args.remove(arg) + version = '20b' + case '-30': + args.remove(arg) + version = '30' + case '-l': + args.remove(arg) + use_list = True + case '-dynamic': + args.remove(arg) + dynamic = True + case _: + if arg.startswith("-j"): + args.remove(arg) + jobs = int(arg.removeprefix("-j")) + + input = args + if use_list and len(args) <= 1: + raise "No shaders to compile!" + + include_dir = Path('include') + shaders_dir = Path('shaders') + + if not include_dir.exists(): + os.mkdir(include_dir) + + if not shaders_dir.exists(): + os.mkdir(shaders_dir) + + process_shaders(input, jobs, version, use_list, dynamic) + + for file in shaders_dir.glob('fxc/*.vcs'): + dst = Path.cwd() / '../../../game' / MOD / 'shaders/fxc' / file.name + dst = dst.resolve() + shutil.copyfile(file, dst) + +if __name__ == '__main__': + main() diff --git a/devtools/shadercompile/d3dcompiler_47.dll b/devtools/shadercompile/d3dcompiler_47.dll new file mode 100644 index 00000000..b1202611 Binary files /dev/null and b/devtools/shadercompile/d3dcompiler_47.dll differ diff --git a/devtools/sourcesdk_def.mak b/devtools/sourcesdk_def.mak new file mode 100644 index 00000000..fc561ad7 --- /dev/null +++ b/devtools/sourcesdk_def.mak @@ -0,0 +1,3 @@ +#defines these macros so that we skip VSIGN and P4 steps in the SDK +SOURCE_SDK=1 +VALVE_NO_AUTO_P4=1 diff --git a/dx10sdk/Utilities/dx9_30/dx_proxy.dll b/dx10sdk/Utilities/dx9_30/dx_proxy.dll deleted file mode 100644 index f2da4d58..00000000 Binary files a/dx10sdk/Utilities/dx9_30/dx_proxy.dll and /dev/null differ diff --git a/dx9sdk/utilities/dx_proxy.dll b/dx9sdk/utilities/dx_proxy.dll deleted file mode 100644 index 2d181d6a..00000000 Binary files a/dx9sdk/utilities/dx_proxy.dll and /dev/null differ diff --git a/fgdlib/gamedata.cpp b/fgdlib/gamedata.cpp index f3689ee9..cac92d4a 100644 --- a/fgdlib/gamedata.cpp +++ b/fgdlib/gamedata.cpp @@ -12,6 +12,9 @@ #include "filesystem_tools.h" #include "tier1/strtools.h" #include "utlmap.h" +#ifdef MAPBASE +#include "fmtstr.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -480,8 +483,8 @@ bool GameData::ParseMapSize(TokenReader &tr) if (nMin != nMax) { - m_nMinMapCoord = min(nMin, nMax); - m_nMaxMapCoord = max(nMin, nMax); + m_nMinMapCoord = MIN(nMin, nMax); + m_nMaxMapCoord = MAX(nMin, nMax); } if (!GDSkipToken(tr, OPERATOR, ")")) @@ -579,6 +582,34 @@ GDclass *GameData::BeginInstanceRemap( const char *pszClassName, const char *psz return m_InstanceClass; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets up for additional instance remap fixes from Mapbase +//----------------------------------------------------------------------------- +void GameData::SetupInstanceRemapParams( int iStartNodes, int iStartBrushSide, bool bRemapVecLines ) +{ + // Set the numer of nodes in the level + m_InstanceStartAINodes = iStartNodes; + + // If we have a "nodeid" key, set it to ivNodeDest so it's properly recognized + // during AI node remapping + GDinputvariable *var = m_InstanceClass->VarForName( "nodeid" ); + if ( var ) + { + var->ForceSetType( ivNodeDest ); + } + + //--------------------------------------------- + + // Set the number of brush sides in the level + m_InstanceStartSide = iStartBrushSide; + + //--------------------------------------------- + + m_bRemapVecLines = bRemapVecLines; +} +#endif + enum tRemapOperation { @@ -586,6 +617,13 @@ enum tRemapOperation REMAP_POSITION, REMAP_ANGLE, REMAP_ANGLE_NEGATIVE_PITCH, +#ifdef MAPBASE + // Remaps the node ID for instance/manifest AI node support + REMAP_NODE_ID, + + // Remaps brush sides and sidelists + REMAP_SIDES, +#endif }; @@ -624,6 +662,12 @@ bool GameData::RemapKeyValue( const char *pszKey, const char *pszInValue, char * RemapOperation.Insert( ivOrigin, REMAP_POSITION ); RemapOperation.Insert( ivAxis, REMAP_ANGLE ); RemapOperation.Insert( ivAngleNegativePitch, REMAP_ANGLE_NEGATIVE_PITCH ); +#ifdef MAPBASE + RemapOperation.Insert( ivNodeDest, REMAP_NODE_ID ); + RemapOperation.Insert( ivSide, REMAP_SIDES ); + RemapOperation.Insert( ivSideList, REMAP_SIDES ); + RemapOperation.Insert( ivVecLine, REMAP_POSITION ); +#endif } if ( !m_InstanceClass ) @@ -657,6 +701,12 @@ bool GameData::RemapKeyValue( const char *pszKey, const char *pszInValue, char * case REMAP_POSITION: { +#ifdef MAPBASE + // Only remap ivVecLine if the keyvalue is enabled + if (KVType == ivVecLine && !m_bRemapVecLines) + break; +#endif + Vector inPoint( 0.0f, 0.0f, 0.0f ), outPoint; sscanf ( pszInValue, "%f %f %f", &inPoint.x, &inPoint.y, &inPoint.z ); @@ -697,6 +747,54 @@ bool GameData::RemapKeyValue( const char *pszKey, const char *pszInValue, char * sprintf( pszOutValue, "%g", -outAngles.x ); // just the pitch } break; + +#ifdef MAPBASE + case REMAP_NODE_ID: + { + int value = atoi( pszInValue ); + if (value == -1) + break; + + //Warning( " %s %s: Remapped %i to %i", m_InstanceClass->GetName(), KVVar->GetName(), value, value + m_InstanceStartAINodes ); + + value += m_InstanceStartAINodes; + + sprintf( pszOutValue, "%i", value ); + } + break; + + case REMAP_SIDES: + { + CUtlStringList sideList; + V_SplitString( pszInValue, " ", sideList ); + + // Convert sides + CUtlStringList newSideList; + for (int i = 0; i < sideList.Count(); i++) + { + int iSide = atoi( sideList[i] ); + + //Warning( " %s %s: Remapped %i to %i", m_InstanceClass->GetName(), KVVar->GetName(), iSide, iSide + m_InstanceStartSide ); + + iSide += m_InstanceStartSide; + + newSideList.AddToTail( const_cast( CNumStr( iSide ).String() ) ); + } + + // Initial side + strcpy( pszOutValue, newSideList[0] ); + + // Start at 1 for subsequent sides + for (int i = 1; i < newSideList.Count(); i++) + { + // Any subsequent sides are spaced + sprintf( pszOutValue, "%s %s", pszOutValue, newSideList[i] ); + } + + //Warning("Old side list: \"%s\", new side list: \"%s\"\n", pszInValue, pszOutValue); + } + break; +#endif } return ( strcmpi( pszInValue, pszOutValue ) != 0 ); @@ -715,7 +813,11 @@ bool GameData::RemapNameField( const char *pszInValue, char *pszOutValue, TNameF { strcpy( pszOutValue, pszInValue ); +#ifdef MAPBASE + if ( pszInValue[ 0 ] && pszInValue[ 0 ] != '@' && pszInValue[ 0 ] != '!' ) +#else if ( pszInValue[ 0 ] && pszInValue[ 0 ] != '@' ) +#endif { // ! at the start of a value means it is global and should not be remaped switch( NameFixup ) { diff --git a/game/client/C_Env_Projected_Texture.h b/game/client/C_Env_Projected_Texture.h index b15ea6ef..1ff10a00 100644 --- a/game/client/C_Env_Projected_Texture.h +++ b/game/client/C_Env_Projected_Texture.h @@ -13,6 +13,157 @@ #include "c_baseentity.h" #include "basetypes.h" +#include "c_light_manager.h" + +#ifdef ASW_PROJECTED_TEXTURES + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class C_EnvProjectedTexture : public C_BaseEntity +{ + DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + void SetMaterial( IMaterial *pMaterial ); + void SetLightColor( byte r, byte g, byte b, byte a ); + void SetSize( float flSize ); + void SetRotation( float flRotation ); + + virtual void OnDataChanged( DataUpdateType_t updateType ); + void ShutDownLightHandle( void ); + +#ifdef MAPBASE + virtual void Simulate(); +#else + virtual bool Simulate(); +#endif + + void UpdateLight( void ); + + C_EnvProjectedTexture(); + ~C_EnvProjectedTexture(); + + static void SetVisibleBBoxMinHeight( float flVisibleBBoxMinHeight ) { m_flVisibleBBoxMinHeight = flVisibleBBoxMinHeight; } + static float GetVisibleBBoxMinHeight( void ) { return m_flVisibleBBoxMinHeight; } + static C_EnvProjectedTexture *Create( ); + + virtual bool IsTransparent() { return false; } + virtual bool IsTwoPass() { return false; } + + virtual void UpdateOnRemove(); + + virtual void GetRenderBoundsWorldspace(Vector& mins, Vector& maxs) + { + if (m_bEnableVolumetrics) + { + mins = m_vecRenderBoundsMin; + maxs = m_vecRenderBoundsMax; + } + else + { + BaseClass::GetRenderBoundsWorldspace(mins, maxs); + } + } + + virtual void GetRenderBounds(Vector& mins, Vector& maxs) + { + if (m_bEnableVolumetrics) + { + mins = m_vecRenderBoundsMin - GetAbsOrigin(); + maxs = m_vecRenderBoundsMax - GetAbsOrigin(); + } + else + { + BaseClass::GetRenderBounds(mins, maxs); + } + } + + virtual bool ShouldDraw(void) { return false; } + + virtual bool ShouldReceiveProjectedTextures(int flags) { return false; } + + +private: + + inline bool IsBBoxVisible( void ); + bool IsBBoxVisible( Vector vecExtentsMin, + Vector vecExtentsMax ); + + void GetShadowViewSetup( CViewSetup &setup ); + void UpdateVolumetricsState(); + void RemoveVolumetrics(); + + Vector m_vecRenderBoundsMin, m_vecRenderBoundsMax; + ClientShadowHandle_t m_LightHandle; + bool m_bForceUpdate; + + EHANDLE m_hTargetEntity; +#ifdef MAPBASE + bool m_bDontFollowTarget; +#endif + + bool m_bState; + bool m_bAlwaysUpdate; + float m_flLightFOV; +#ifdef MAPBASE + float m_flLightHorFOV; +#endif + bool m_bEnableShadows; + bool m_bLightOnlyTarget; + bool m_bLightWorld; + bool m_bCameraSpace; + float m_flBrightnessScale; + color32 m_LightColor; + Vector m_CurrentLinearFloatLightColor; + float m_flCurrentLinearFloatLightAlpha; +#ifdef MAPBASE + float m_flCurrentBrightnessScale; +#endif + float m_flColorTransitionTime; + float m_flAmbient; + float m_flNearZ; + float m_flFarZ; + char m_SpotlightTextureName[ MAX_PATH ]; + CTextureReference m_SpotlightTexture; + int m_nSpotlightTextureFrame; + int m_nShadowQuality; +#ifdef MAPBASE + float m_flConstantAtten; + float m_flLinearAtten; + float m_flQuadraticAtten; + float m_flShadowAtten; + float m_flShadowFilter; + + bool m_bAlwaysDraw; + //bool m_bProjectedTextureVersion; +#endif + + Vector m_vecExtentsMin; + Vector m_vecExtentsMax; + + static float m_flVisibleBBoxMinHeight; + + bool m_bEnableVolumetrics; + bool m_bEnableVolumetricsLOD; + float m_flVolumetricsFadeDistance; + int m_iVolumetricsQuality; + float m_flVolumetricsMultiplier; + float m_flVolumetricsQualityBias; + int m_iCurrentVolumetricsSubDiv; + volume_light_t m_volumelight; + +}; + + + +bool C_EnvProjectedTexture::IsBBoxVisible( void ) +{ + return IsBBoxVisible( GetAbsOrigin() + m_vecExtentsMin, GetAbsOrigin() + m_vecExtentsMax ); +} + +#else //----------------------------------------------------------------------------- // Purpose: @@ -62,4 +213,6 @@ class C_EnvProjectedTexture : public C_BaseEntity C_EnvProjectedTexture* GetEnvProjectedTextureList(); +#endif + #endif // C_ENVPROJECTEDTEXTURE_H diff --git a/game/client/baseanimatedtextureproxy.cpp b/game/client/baseanimatedtextureproxy.cpp index b7151114..4365e866 100644 --- a/game/client/baseanimatedtextureproxy.cpp +++ b/game/client/baseanimatedtextureproxy.cpp @@ -11,8 +11,6 @@ #include "materialsystem/itexture.h" #include "tier1/KeyValues.h" #include "toolframework_client.h" -#include "tier0/minidump.h" -#include "tier0/stacktools.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -41,33 +39,25 @@ CBaseAnimatedTextureProxy::~CBaseAnimatedTextureProxy() bool CBaseAnimatedTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { char const* pAnimatedTextureVarName = pKeyValues->GetString( "animatedTextureVar" ); + if( !pAnimatedTextureVarName ) + return false; - if( pAnimatedTextureVarName ) - { - bool foundVar; + bool foundVar; + m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false ); + if( !foundVar ) + return false; - m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false ); - if( foundVar ) - { - char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" ); - - if( pAnimatedTextureFrameNumVarName ) - { - m_AnimatedTextureFrameNumVar = pMaterial->FindVar( pAnimatedTextureFrameNumVarName, &foundVar, false ); - - if( foundVar ) - { - m_FrameRate = pKeyValues->GetFloat( "animatedTextureFrameRate", 15 ); - m_WrapAnimation = !pKeyValues->GetInt( "animationNoWrap", 0 ); - return true; - } - } - } - } + char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" ); + if( !pAnimatedTextureFrameNumVarName ) + return false; - // Error - null out pointers. - Cleanup(); - 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() diff --git a/game/client/bsp_utils.cpp b/game/client/bsp_utils.cpp deleted file mode 100644 index c21c2ada..00000000 --- a/game/client/bsp_utils.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Exposes bsp tools to game for e.g. workshop use -// -// $NoKeywords: $ -//===========================================================================// - -#include "cbase.h" -#include -#include "filesystem.h" -#include "bsp_utils.h" -#include "utlbuffer.h" -#include "igamesystem.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -bool BSP_SyncRepack( const char *pszInputMapFile, - const char *pszOutputMapFile, - IBSPPack::eRepackBSPFlags eRepackFlags ) -{ - // load the bsppack dll - IBSPPack *libBSPPack = NULL; - CSysModule *pModule = g_pFullFileSystem->LoadModule( "bsppack" ); - if ( pModule ) - { - CreateInterfaceFn BSPPackFactory = Sys_GetFactory( pModule ); - if ( BSPPackFactory ) - { - libBSPPack = ( IBSPPack * )BSPPackFactory( IBSPPACK_VERSION_STRING, NULL ); - } - } - if( !libBSPPack ) - { - Warning( "Can't load bsppack library - unable to compress bsp\n" ); - return false; - } - - Msg( "Repacking %s -> %s\n", pszInputMapFile, pszOutputMapFile ); - - if ( !g_pFullFileSystem->FileExists( pszInputMapFile ) ) - { - Warning( "Couldn't open input file %s - BSP recompress failed\n", pszInputMapFile ); - return false; - } - - CUtlBuffer inputBuffer; - if ( !g_pFullFileSystem->ReadFile( pszInputMapFile, NULL, inputBuffer ) ) - { - Warning( "Couldn't read file %s - BSP compression failed\n", pszInputMapFile ); - return false; - } - - CUtlBuffer outputBuffer; - - if ( !libBSPPack->RepackBSP( inputBuffer, outputBuffer, eRepackFlags ) ) - { - Warning( "Internal error compressing BSP\n" ); - return false; - } - - g_pFullFileSystem->WriteFile( pszOutputMapFile, NULL, outputBuffer ); - - Msg( "Successfully repacked %s as %s -- %u -> %u bytes\n", - pszInputMapFile, pszOutputMapFile, inputBuffer.TellPut(), outputBuffer.TellPut() ); - - return true; -} - -// Helper to create a thread that calls SyncCompressMap, and clean it up when it exists -void BSP_BackgroundRepack( const char *pszInputMapFile, - const char *pszOutputMapFile, - IBSPPack::eRepackBSPFlags eRepackFlags ) -{ - // Make this a gamesystem and thread, so it can check for completion each frame and clean itself up. Run() is the - // background thread, Update() is the main thread tick. - class BackgroundBSPRepackThread : public CThread, public CAutoGameSystemPerFrame - { - public: - BackgroundBSPRepackThread( const char *pszInputFile, const char *pszOutputFile, IBSPPack::eRepackBSPFlags eRepackFlags ) - : m_strInput( pszInputFile ) - , m_strOutput( pszOutputFile ) - , m_eRepackFlags( eRepackFlags ) - { - Start(); - } - - // CThread job - returns 0 for success - virtual int Run() OVERRIDE - { - return BSP_SyncRepack( m_strInput.Get(), m_strOutput.Get(), m_eRepackFlags ) ? 0 : 1; - } - - // GameSystem - virtual const char* Name( void ) OVERRIDE { return "BackgroundBSPRepackThread"; } - - // Runs on main thread - void CheckFinished() - { - if ( !IsAlive() ) - { - // Thread finished - if ( GetResult() != 0 ) - { - Warning( "Map compression thread failed :(\n" ); - } - - // AutoGameSystem deregisters itself on destruction, we're done - delete this; - } - } - - #ifdef CLIENT_DLL - virtual void Update( float frametime ) OVERRIDE { CheckFinished(); } - #else // GAME DLL - virtual void FrameUpdatePostEntityThink() OVERRIDE { CheckFinished(); } - #endif - private: - CUtlString m_strInput; - CUtlString m_strOutput; - IBSPPack::eRepackBSPFlags m_eRepackFlags; - }; - - Msg( "Starting BSP repack job %s -> %s\n", pszInputMapFile, pszOutputMapFile ); - - // Deletes itself up when done - new BackgroundBSPRepackThread( pszInputMapFile, pszOutputMapFile, eRepackFlags ); -} - -CON_COMMAND( bsp_repack, "Repack and output a (re)compressed version of a bsp file" ) -{ -#ifdef GAME_DLL - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; -#endif - - // Handle -nocompress - bool bCompress = true; - const char *szInFilename = NULL; - const char *szOutFilename = NULL; - - if ( args.ArgC() == 4 && V_strcasecmp( args.Arg( 1 ), "-nocompress" ) == 0 ) - { - bCompress = false; - szInFilename = args.Arg( 2 ); - szOutFilename = args.Arg( 3 ); - } - else if ( args.ArgC() == 3 ) - { - szInFilename = args.Arg( 1 ); - szOutFilename = args.Arg( 2 ); - } - - if ( !szInFilename || !szOutFilename || !strlen( szInFilename ) || !strlen( szOutFilename ) ) - { - Msg( "Usage: bsp_repack [-nocompress] map.bsp output_map.bsp\n" ); - return; - } - - if ( bCompress ) - { - // Use default compress flags - BSP_BackgroundRepack( szInFilename, szOutFilename ); - } - else - { - // No compression - BSP_BackgroundRepack( szInFilename, szOutFilename, (IBSPPack::eRepackBSPFlags)0 ); - } -} diff --git a/game/client/bsp_utils.h b/game/client/bsp_utils.h deleted file mode 100644 index 1cdfaf50..00000000 --- a/game/client/bsp_utils.h +++ /dev/null @@ -1,21 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Exposes bsp tools to game for e.g. workshop use -// -// $NoKeywords: $ -//===========================================================================// - -#include "../utils/common/bsplib.h" -#include "ibsppack.h" - -// Loads bsppack module (IBSPPack) and calls RepackBSP() -bool BSP_SyncRepack( const char *pszInputMapFile, - const char *pszOutputMapFile, - IBSPPack::eRepackBSPFlags eRepackFlags = (IBSPPack::eRepackBSPFlags) ( IBSPPack::eRepackBSP_CompressLumps | - IBSPPack::eRepackBSP_CompressPackfile ) ); - -// Helper to spawn a background thread that runs SyncRepack -void BSP_BackgroundRepack( const char *pszInputMapFile, - const char *pszOutputMapFile, - IBSPPack::eRepackBSPFlags eRepackFlags = (IBSPPack::eRepackBSPFlags) ( IBSPPack::eRepackBSP_CompressLumps | - IBSPPack::eRepackBSP_CompressPackfile ) ); diff --git a/game/client/c_ai_basenpc.cpp b/game/client/c_ai_basenpc.cpp index 69b675b3..1b1e2e65 100644 --- a/game/client/c_ai_basenpc.cpp +++ b/game/client/c_ai_basenpc.cpp @@ -153,13 +153,9 @@ void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type ) } } -bool C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) +void C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) { - bool bRet = true; - - if ( !ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt ) ) - bRet = false; - + ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt ); GetRagdollCurSequenceWithDeathPose( this, pDeltaBones1, gpGlobals->curtime, m_iDeathPose, m_iDeathFrame ); float ragdollCreateTime = PhysGetSyncCreateTime(); if ( ragdollCreateTime != gpGlobals->curtime ) @@ -168,15 +164,11 @@ bool C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x // 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 - if ( !ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime ) ) - bRet = false; + ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime ); } else { - if ( !SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime ) ) - bRet = false; + SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime ); } - - return bRet; } diff --git a/game/client/c_ai_basenpc.h b/game/client/c_ai_basenpc.h index 834be64d..64636c45 100644 --- a/game/client/c_ai_basenpc.h +++ b/game/client/c_ai_basenpc.h @@ -14,7 +14,7 @@ #include "c_basecombatcharacter.h" -// NOTE: Moved all controller code into c_basestudiomodel +// NOTE: MOved all controller code into c_basestudiomodel class C_AI_BaseNPC : public C_BaseCombatCharacter { DECLARE_CLASS( C_AI_BaseNPC, C_BaseCombatCharacter ); @@ -29,7 +29,7 @@ class C_AI_BaseNPC : public C_BaseCombatCharacter bool ShouldAvoidObstacle( void ){ return m_bPerformAvoidance; } virtual bool AddRagdollToFadeQueue( void ) { return m_bFadeCorpse; } - virtual bool GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) OVERRIDE; + virtual void GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ); int GetDeathPose( void ) { return m_iDeathPose; } diff --git a/game/client/c_baseanimating.cpp b/game/client/c_baseanimating.cpp index 78bc38be..7afc4d22 100644 --- a/game/client/c_baseanimating.cpp +++ b/game/client/c_baseanimating.cpp @@ -54,6 +54,9 @@ #include "replay/replay_ragdoll.h" #include "studio_stats.h" #include "tier1/callqueue.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif #ifdef TF_CLIENT_DLL #include "c_tf_player.h" @@ -79,11 +82,6 @@ const float RUN_SPEED_ESTIMATE_SQR = 150.0f * 150.0f; static ConVar dbganimmodel( "dbganimmodel", "" ); #endif -#if defined( STAGING_ONLY ) - static ConVar dbg_bonestack_perturb( "dbg_bonestack_perturb", "0", 0); - static CInterlockedInt dbg_bonestack_reentrant_count = 0; -#endif // STAGING_ONLY - mstudioevent_t *GetEventIndexForSequence( mstudioseqdesc_t &seqdesc ); C_EntityDissolve *DissolveEffect( C_BaseEntity *pTarget, float flTime ); @@ -261,6 +259,9 @@ LINK_ENTITY_TO_CLASS( client_ragdoll, C_ClientRagdoll ); BEGIN_DATADESC( C_ClientRagdoll ) DEFINE_FIELD( m_bFadeOut, FIELD_BOOLEAN ), DEFINE_FIELD( m_bImportant, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_FIELD( m_flForcedRetireTime, FIELD_FLOAT ), +#endif DEFINE_FIELD( m_iCurrentFriction, FIELD_INTEGER ), DEFINE_FIELD( m_iMinFriction, FIELD_INTEGER ), DEFINE_FIELD( m_iMaxFriction, FIELD_INTEGER ), @@ -283,6 +284,94 @@ BEGIN_DATADESC( C_ClientRagdoll ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( C_ClientRagdoll, C_BaseAnimating, "Client-side ragdolls" ) + + DEFINE_SCRIPTFUNC_NAMED( SUB_Remove, "FadeOut", "Fades out the ragdoll and removes it from the client." ) + + // TODO: Proper shared ragdoll funcs? + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRagdollObject, "GetRagdollObject", "Gets the ragdoll object of the specified index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRagdollObjectCount, "GetRagdollObjectCount", "Gets the number of ragdoll objects on this ragdoll." ) + +END_SCRIPTDESC(); + +ScriptHook_t C_BaseAnimating::g_Hook_OnClientRagdoll; +ScriptHook_t C_BaseAnimating::g_Hook_FireEvent; +//ScriptHook_t C_BaseAnimating::g_Hook_BuildTransformations; +#endif + +BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-side" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPoseParameter, "GetPoseParameter", "Get the specified pose parameter's value" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" ) + DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptLookupAttachment, "LookupAttachment", "Get the named attachement id" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentOrigin, "GetAttachmentOrigin", "Get the attachement id's origin vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentAngles, "GetAttachmentAngles", "Get the attachement id's angles as a p,y,r vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentMatrix, "GetAttachmentMatrix", "Get the attachement id's matrix transform" ) + + DEFINE_SCRIPTFUNC( LookupBone, "Get the named bone id" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoneTransform, "GetBoneTransform", "Get the transform for the specified bone" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetBoneTransform, "SetBoneTransform", "Set the transform for the specified bone" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAttachEntityToBone, "AttachEntityToBone", "Attaches this entity to the specified target and bone. Also allows for optional local position offset" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptRemoveBoneAttachment, "RemoveBoneAttachment", "Removes the specified bone attachment" ) + //DEFINE_SCRIPTFUNC( RemoveBoneAttachments, "Removes all bone attachments" ) + DEFINE_SCRIPTFUNC( DestroyBoneAttachments, "Destroys all bone attachments" ) + DEFINE_SCRIPTFUNC( GetNumBoneAttachments, "Gets the number of bone attachments" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoneAttachment, "GetBoneAttachment", "Gets the specified bone attachment" ) + + DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup") + DEFINE_SCRIPTFUNC( GetBodygroup, "Gets a bodygroup" ) + DEFINE_SCRIPTFUNC( GetBodygroupName, "Gets a bodygroup name" ) + DEFINE_SCRIPTFUNC( FindBodygroupByName, "Finds a bodygroup by name" ) + DEFINE_SCRIPTFUNC( GetBodygroupCount, "Gets the number of models in a bodygroup" ) + DEFINE_SCRIPTFUNC( GetNumBodyGroups, "Gets the number of bodygroups" ) + + DEFINE_SCRIPTFUNC( GetSequence, "Gets the current sequence" ) + DEFINE_SCRIPTFUNC( SetSequence, "Sets the current sequence" ) + DEFINE_SCRIPTFUNC( SequenceLoops, "Does the current sequence loop?" ) + DEFINE_SCRIPTFUNC( LookupSequence, "Gets the index of the specified sequence name" ) + DEFINE_SCRIPTFUNC( LookupActivity, "Gets the ID of the specified activity name" ) + DEFINE_SCRIPTFUNC( GetSequenceName, "Gets the name of the specified sequence index" ) + DEFINE_SCRIPTFUNC( GetSequenceActivityName, "Gets the activity name of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceMoveDist, "GetSequenceMoveDist", "Gets the move distance of the specified sequence" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceActivity, "GetSequenceActivity", "Gets the activity ID of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSelectWeightedSequence, "SelectWeightedSequence", "Selects a sequence for the specified activity ID" ) + + DEFINE_SCRIPTFUNC( GetPlaybackRate, "" ) + DEFINE_SCRIPTFUNC( SetPlaybackRate, "" ) + DEFINE_SCRIPTFUNC( GetCycle, "" ) + DEFINE_SCRIPTFUNC( SetCycle, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSkin, "GetSkin", "Gets the model's skin" ) + DEFINE_SCRIPTFUNC( SetSkin, "Sets the model's skin" ) + + DEFINE_SCRIPTFUNC( GetForceBone, "Gets the entity's force bone, which is used to determine which bone a ragdoll should apply its force to." ) + DEFINE_SCRIPTFUNC( SetForceBone, "Sets the entity's force bone, which is used to determine which bone a ragdoll should apply its force to." ) + DEFINE_SCRIPTFUNC( GetRagdollForce, "Gets the entity's ragdoll force, which is used to apply velocity to a ragdoll." ) + DEFINE_SCRIPTFUNC( SetRagdollForce, "Sets the entity's ragdoll force, which is used to apply velocity to a ragdoll." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptBecomeRagdollOnClient, "BecomeRagdollOnClient", "" ) + DEFINE_SCRIPTFUNC( IsRagdoll, "" ) + + BEGIN_SCRIPTHOOK( C_BaseAnimating::g_Hook_OnClientRagdoll, "OnClientRagdoll", FIELD_VOID, "Called when this entity turns into a client-side ragdoll." ) + DEFINE_SCRIPTHOOK_PARAM( "ragdoll", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( C_BaseAnimating::g_Hook_FireEvent, "FireEvent", FIELD_BOOLEAN, "Called when handling animation events. Return false to cancel base handling." ) + DEFINE_SCRIPTHOOK_PARAM( "origin", FIELD_VECTOR ) + DEFINE_SCRIPTHOOK_PARAM( "angles", FIELD_VECTOR ) + DEFINE_SCRIPTHOOK_PARAM( "event", FIELD_INTEGER ) + DEFINE_SCRIPTHOOK_PARAM( "options", FIELD_CSTRING ) + END_SCRIPTHOOK() + + //BEGIN_SCRIPTHOOK( C_BaseAnimating::g_Hook_BuildTransformations, "BuildTransformations", FIELD_VOID, "Called when building bone transformations. Allows VScript to read/write any bone with Get/SetBoneTransform." ) + //END_SCRIPTHOOK() +#endif +END_SCRIPTDESC(); + C_ClientRagdoll::C_ClientRagdoll( bool bRestoring ) { m_iCurrentFriction = 0; @@ -291,6 +380,9 @@ C_ClientRagdoll::C_ClientRagdoll( bool bRestoring ) m_bFadeOut = false; m_bFadingOut = false; m_bImportant = false; +#ifdef MAPBASE + m_flForcedRetireTime = 0.0f; +#endif m_bNoModelParticles = false; SetClassname("client_ragdoll"); @@ -371,7 +463,11 @@ void C_ClientRagdoll::OnRestore( void ) if ( m_bFadeOut == true ) { +#ifdef MAPBASE + s_RagdollLRU.MoveToTopOfLRU( this, m_bImportant, m_flForcedRetireTime ); +#else s_RagdollLRU.MoveToTopOfLRU( this, m_bImportant ); +#endif } NoteRagdollCreationTick( this ); @@ -637,15 +733,30 @@ void C_ClientRagdoll::Release( void ) } ClientEntityList().RemoveEntity( GetClientHandle() ); - if ( CollisionProp()->GetPartitionHandle() != PARTITION_INVALID_HANDLE ) - { - partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() ); - } + partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() ); RemoveFromLeafSystem(); BaseClass::Release(); } +#ifdef MAPBASE_VSCRIPT +HSCRIPT C_ClientRagdoll::ScriptGetRagdollObject( int iIndex ) +{ + if (iIndex < 0 || iIndex > m_pRagdoll->RagdollBoneCount()) + { + Warning("%s GetRagdollObject: Index %i not valid (%i objects)\n", GetDebugName(), iIndex, m_pRagdoll->RagdollBoneCount()); + return NULL; + } + + return g_pScriptVM->RegisterInstance( m_pRagdoll->GetElement(iIndex) ); +} + +int C_ClientRagdoll::ScriptGetRagdollObjectCount() +{ + return m_pRagdoll->RagdollBoneCount(); +} +#endif + //----------------------------------------------------------------------------- // Incremented each frame in InvalidateModelBones. Models compare this value to what it // was last time they setup their bones to determine if they need to re-setup their bones. @@ -683,6 +794,10 @@ C_BaseAnimating::C_BaseAnimating() : m_nPrevSequence = -1; m_nRestoreSequence = -1; m_pRagdoll = NULL; + m_pClientsideRagdoll = NULL; +#ifdef MAPBASE + m_pServerRagdoll = NULL; +#endif m_builtRagdoll = false; m_hitboxBoneCacheHandle = 0; int i; @@ -752,25 +867,15 @@ C_BaseAnimating::~C_BaseAnimating() int i = g_PreviousBoneSetups.Find( this ); if ( i != -1 ) g_PreviousBoneSetups.FastRemove( i ); + RemoveFromClientSideAnimationList(); TermRopes(); - - Assert( !m_pRagdoll ); - delete m_pRagdollInfo; - m_pRagdollInfo = NULL; - + Assert(!m_pRagdoll); delete m_pIk; - m_pIk = NULL; - delete m_pBoneMergeCache; - m_pBoneMergeCache = NULL; - Studio_DestroyBoneCache( m_hitboxBoneCacheHandle ); - delete m_pJiggleBones; - m_pJiggleBones = NULL; - InvalidateMdlCache(); // Kill off anything bone attached to us. @@ -870,7 +975,7 @@ void C_BaseAnimating::UpdateRelevantInterpolatedVars() { MDLCACHE_CRITICAL_SECTION(); // Remove any interpolated vars that need to be removed. - if ( !IsMarkedForDeletion() && !GetPredictable() && !IsClientCreated() && GetModelPtr() && GetModelPtr()->SequencesAvailable() ) + if ( !GetPredictable() && !IsClientCreated() && GetModelPtr() && GetModelPtr()->SequencesAvailable() ) { AddBaseAnimatingInterpolatedVars(); } @@ -910,17 +1015,6 @@ void C_BaseAnimating::RemoveBaseAnimatingInterpolatedVars() } } -/* - From Ken: Lock() and Unlock() are render frame only, it’s just so the mdlcache - doesn’t toss the memory when it reshuffles the data, or at least used to. I - don't have any idea if mdlcache even does that anymore, but at one point it would - happily throw away the animation data if you ran out of memory on the - consoles. Jay adds: Ken is correct and the pointer should be valid until the end - of the frame lock (provided you are within a MDLCACHE_LOCK() block or whatever - - Jay also recommends running with a forced small cache size (1MB) to put maximum - pressure on the cache when testing changes. Look for datacache ConVar in datacache.cpp. - */ void C_BaseAnimating::LockStudioHdr() { Assert( m_hStudioHdr == MDLHANDLE_INVALID && m_pStudioHdr == NULL ); @@ -992,9 +1086,6 @@ void C_BaseAnimating::UnlockStudioHdr() mdlcache->UnlockStudioHdr( m_hStudioHdr ); } m_hStudioHdr = MDLHANDLE_INVALID; - - delete m_pStudioHdr; - m_pStudioHdr = NULL; } } @@ -1432,6 +1523,115 @@ float C_BaseAnimating::ClampCycle( float flCycle, bool isLooping ) return flCycle; } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: Returns the world location and world angles of an attachment to vscript caller +// Input : attachment name +// Output : location and angles +//----------------------------------------------------------------------------- +const Vector& C_BaseAnimating::ScriptGetAttachmentOrigin( int iAttachment ) +{ + + static Vector absOrigin; + static QAngle qa; + + C_BaseAnimating::GetAttachment( iAttachment, absOrigin, qa ); + + return absOrigin; +} + +const Vector& C_BaseAnimating::ScriptGetAttachmentAngles( int iAttachment ) +{ + + static Vector absOrigin; + static Vector absAngles; + static QAngle qa; + + C_BaseAnimating::GetAttachment( iAttachment, absOrigin, qa ); + absAngles.x = qa.x; + absAngles.y = qa.y; + absAngles.z = qa.z; + return absAngles; +} + +HSCRIPT C_BaseAnimating::ScriptGetAttachmentMatrix( int iAttachment ) +{ + static matrix3x4_t matrix; + + C_BaseAnimating::GetAttachment( iAttachment, matrix ); + return g_pScriptVM->RegisterInstance( &matrix ); +} + +void C_BaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ) +{ + matrix3x4_t *matTransform = HScriptToClass( hTransform ); + if (matTransform == NULL) + return; + + GetBoneTransform( iBone, *matTransform ); +} + +void C_BaseAnimating::ScriptSetBoneTransform( int iBone, HSCRIPT hTransform ) +{ + matrix3x4_t *matTransform = HScriptToClass( hTransform ); + if (matTransform == NULL) + return; + + MatrixCopy( *matTransform, GetBoneForWrite( iBone ) ); +} + +void C_BaseAnimating::ScriptAttachEntityToBone( HSCRIPT attachTarget, int boneIndexAttached, const Vector &bonePosition, const QAngle &boneAngles ) +{ + C_BaseEntity *pTarget = ToEnt( attachTarget ); + if (pTarget == NULL) + return; + + AttachEntityToBone( pTarget->GetBaseAnimating(), boneIndexAttached, bonePosition, boneAngles ); +} + +void C_BaseAnimating::ScriptRemoveBoneAttachment( HSCRIPT boneAttachment ) +{ + C_BaseEntity *pTarget = ToEnt( boneAttachment ); + if (pTarget == NULL) + return; + + RemoveBoneAttachment( pTarget->GetBaseAnimating() ); +} + +HSCRIPT C_BaseAnimating::ScriptGetBoneAttachment( int i ) +{ + return ToHScript( GetBoneAttachment( i ) ); +} + +HSCRIPT C_BaseAnimating::ScriptBecomeRagdollOnClient() +{ + C_BaseAnimating *pRagdoll = BecomeRagdollOnClient(); + if (!pRagdoll) + return NULL; + + return pRagdoll->GetScriptInstance(); +} + +float C_BaseAnimating::ScriptGetPoseParameter( const char* szName ) +{ + CStudioHdr* pHdr = GetModelPtr(); + if (pHdr == NULL) + return 0.0f; + + int iPoseParam = LookupPoseParameter( pHdr, szName ); + return GetPoseParameter( iPoseParam ); +} +#endif + +void C_BaseAnimating::ScriptSetPoseParameter(const char* szName, float fValue) +{ + CStudioHdr* pHdr = GetModelPtr(); + if (pHdr == NULL) + return; + + int iPoseParam = LookupPoseParameter(pHdr, szName); + SetPoseParameter(pHdr, iPoseParam, fValue); +} void C_BaseAnimating::GetCachedBoneMatrix( int boneIndex, matrix3x4_t &out ) { @@ -1543,21 +1743,10 @@ void C_BaseAnimating::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quater if (pbones[i].parent == -1) { ConcatTransforms( cameraTransform, bonematrix, goalMX ); - } + } else { - // If the parent bone has been scaled (like with BuildBigHeadTransformations) - // scale it back down so the jiggly bones show up non-scaled in the correct location. - matrix3x4_t parentMX = GetBone( pbones[i].parent ); - - float fScale = Square( parentMX[0][0] ) + Square( parentMX[1][0] ) + Square( parentMX[2][0] ); - if ( fScale > Square( 1.0001f ) ) - { - fScale = 1.0f / FastSqrt( fScale ); - MatrixScaleBy( fScale, parentMX ); - } - - ConcatTransforms( parentMX, bonematrix, goalMX ); + ConcatTransforms( GetBone( pbones[i].parent ), bonematrix, goalMX ); } // get jiggle properties from QC data @@ -1589,7 +1778,23 @@ void C_BaseAnimating::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quater } } - +#ifdef MAPBASE_VSCRIPT + //if (m_ScriptScope.IsInitialized() && g_Hook_BuildTransformations.CanRunInScope(m_ScriptScope)) + //{ + // int oldWritableBones = m_BoneAccessor.GetWritableBones(); + // int oldReadableBones = m_BoneAccessor.GetReadableBones(); + // m_BoneAccessor.SetWritableBones( BONE_USED_BY_ANYTHING ); + // m_BoneAccessor.SetReadableBones( BONE_USED_BY_ANYTHING ); + // + // // No parameters + // //ScriptVariant_t args[] = {}; + // //ScriptVariant_t returnValue; + // g_Hook_BuildTransformations.Call( m_ScriptScope, NULL, NULL /*&returnValue, args*/ ); + // + // m_BoneAccessor.SetWritableBones( oldWritableBones ); + // m_BoneAccessor.SetReadableBones( oldReadableBones ); + //} +#endif } //----------------------------------------------------------------------------- @@ -1795,6 +2000,10 @@ CollideType_t C_BaseAnimating::GetCollideType( void ) return BaseClass::GetCollideType(); } +#ifdef MAPBASE +ConVar ai_death_pose_enabled( "ai_death_pose_enabled", "1", FCVAR_NONE, "Toggles the death pose fix code, which cancels sequence transitions while a NPC is ragdolling." ); +#endif + //----------------------------------------------------------------------------- // Purpose: if the active sequence changes, keep track of the previous ones and decay them based on their decay rate //----------------------------------------------------------------------------- @@ -1811,6 +2020,14 @@ void C_BaseAnimating::MaintainSequenceTransitions( IBoneSetup &boneSetup, float return; } +#ifdef MAPBASE + if ( IsAboutToRagdoll() && ai_death_pose_enabled.GetBool() ) + { + m_nPrevNewSequenceParity = m_nNewSequenceParity; + return; + } +#endif + m_SequenceTransitioner.CheckForSequenceChange( boneSetup.GetStudioHdr(), GetSequence(), @@ -2038,10 +2255,10 @@ bool C_BaseAnimating::PutAttachment( int number, const matrix3x4_t &attachmentTo } -bool C_BaseAnimating::SetupBones_AttachmentHelper( CStudioHdr *hdr ) +void C_BaseAnimating::SetupBones_AttachmentHelper( CStudioHdr *hdr ) { - if ( !hdr ) - return false; + if ( !hdr || !hdr->GetNumAttachments() ) + return; // calculate attachment points matrix3x4_t world; @@ -2067,8 +2284,6 @@ bool C_BaseAnimating::SetupBones_AttachmentHelper( CStudioHdr *hdr ) FormatViewModelAttachment( i, world ); PutAttachment( i + 1, world ); } - - return true; } bool C_BaseAnimating::CalcAttachments() @@ -2259,36 +2474,18 @@ bool C_BaseAnimating::GetSoundSpatialization( SpatializationInfo_t& info ) return true; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- + bool C_BaseAnimating::IsViewModel() const { return false; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void C_BaseAnimating::UpdateOnRemove( void ) -{ - RemoveFromClientSideAnimationList( true ); - - BaseClass::UpdateOnRemove(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- bool C_BaseAnimating::IsMenuModel() const { return false; } // UNDONE: Seems kind of silly to have this when we also have the cached bones in C_BaseAnimating -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- CBoneCache *C_BaseAnimating::GetBoneCache( CStudioHdr *pStudioHdr ) { int boneMask = BONE_USED_BY_HITBOX; @@ -2610,14 +2807,29 @@ void C_BaseAnimating::CalculateIKLocks( float currentTime ) // debugoverlay->AddBoxOverlay( origin, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 255, 0, 0, 0, 0 ); - float d = (pTarget->est.pos - origin).Length(); + Vector vecDelta = (origin - pTarget->est.pos); + float d = vecDelta.Length(); if ( d >= flDist) continue; flDist = d; - pTarget->SetPos( origin ); - pTarget->SetAngles( angles ); +#ifdef MAPBASE + // For blending purposes, IK attachments should obey weight + if ( pTarget->est.flWeight < 1.0f ) + { + Quaternion qTarget; + AngleQuaternion( angles, qTarget ); + + QuaternionSlerp( pTarget->est.q, qTarget, pTarget->est.flWeight, pTarget->est.q ); + pTarget->SetPos( pTarget->est.pos + (vecDelta * pTarget->est.flWeight) ); + } + else +#endif + { + pTarget->SetPos( origin ); + pTarget->SetAngles( angles ); + } // debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 ); } @@ -2971,14 +3183,10 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i if( !( oldReadableBones & BONE_USED_BY_ATTACHMENT ) && ( boneMask & BONE_USED_BY_ATTACHMENT ) ) { - if ( !SetupBones_AttachmentHelper( hdr ) ) - { - DevWarning( 2, "SetupBones: SetupBones_AttachmentHelper failed.\n" ); - return false; - } + SetupBones_AttachmentHelper( hdr ); } } - + // Do they want to get at the bone transforms? If it's just making sure an aiment has // its bones setup, it doesn't need the transforms yet. if ( pBoneToWorldOut ) @@ -2989,7 +3197,7 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i } else { - ExecuteNTimes( 25, Warning( "SetupBones: invalid bone array size (%d - needs %d)\n", nMaxBones, m_CachedBoneData.Count() ) ); + Warning( "SetupBones: invalid bone array size (%d - needs %d)\n", nMaxBones, m_CachedBoneData.Count() ); return false; } } @@ -3056,9 +3264,6 @@ struct BoneAccess char const *tag; }; -// the modelcache critical section is insufficient for preventing us from getting into the bone cache at the same time. -// The bonecache itself is protected by a mutex, but the actual bone access stack needs to be protected separately. -static CThreadFastMutex g_BoneAccessMutex; static CUtlVector< BoneAccess > g_BoneAccessStack; static BoneAccess g_BoneAcessBase; @@ -3073,9 +3278,6 @@ bool C_BaseAnimating::IsBoneAccessAllowed() const // (static function) void C_BaseAnimating::PushAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels, char const *tagPush ) { - AUTO_LOCK( g_BoneAccessMutex ); - STAGING_ONLY_EXEC( ReentrancyVerifier rv( &dbg_bonestack_reentrant_count, dbg_bonestack_perturb.GetInt() ) ); - BoneAccess save = g_BoneAcessBase; g_BoneAccessStack.AddToTail( save ); @@ -3087,9 +3289,6 @@ void C_BaseAnimating::PushAllowBoneAccess( bool bAllowForNormalModels, bool bAll void C_BaseAnimating::PopBoneAccess( char const *tagPop ) { - AUTO_LOCK( g_BoneAccessMutex ); - STAGING_ONLY_EXEC( ReentrancyVerifier rv( &dbg_bonestack_reentrant_count, dbg_bonestack_perturb.GetInt() ) ); - // Validate that pop matches the push Assert( ( g_BoneAcessBase.tag == tagPop ) || ( g_BoneAcessBase.tag && g_BoneAcessBase.tag != ( char const * ) 1 && tagPop && tagPop != ( char const * ) 1 && !strcmp( g_BoneAcessBase.tag, tagPop ) ) ); int lastIndex = g_BoneAccessStack.Count() - 1; @@ -3137,6 +3336,17 @@ int C_BaseAnimating::DrawModel( int flags ) int drawn = 0; +#ifdef MAPBASE + if (m_iViewHideFlags > 0) + { + // Hide this entity if it's not supposed to be drawn in this view. + if (m_iViewHideFlags & (1 << CurrentViewID())) + { + return 0; + } + } +#endif + #ifdef TF_CLIENT_DLL ValidateModelIndex(); #endif @@ -3551,13 +3761,17 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr ) flEventCycle, gpGlobals->curtime ); } - + +#ifdef MAPBASE_VSCRIPT + if (ScriptHookFireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ) == false) + continue; +#endif FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ); } // Necessary to get the next loop working - m_flPrevEventCycle = flEventCycle - 0.001f; + m_flPrevEventCycle = -0.01; } for (int i = 0; i < (int)seqdesc.numevents; i++) @@ -3584,6 +3798,11 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr ) gpGlobals->curtime ); } +#ifdef MAPBASE_VSCRIPT + if (ScriptHookFireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ) == false) + continue; +#endif + FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ); } } @@ -3591,6 +3810,26 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr ) m_flPrevEventCycle = flEventCycle; } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool C_BaseAnimating::ScriptHookFireEvent( const Vector& origin, const QAngle& angles, int event, const char *options ) +{ + if (m_ScriptScope.IsInitialized() && g_Hook_FireEvent.CanRunInScope(m_ScriptScope)) + { + // origin, angles, event, options + ScriptVariant_t args[] = { origin, angles, event, options }; + ScriptVariant_t returnValue = true; + g_Hook_FireEvent.Call( m_ScriptScope, &returnValue, args ); + + return returnValue.m_bool; + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Parses a muzzle effect event and sends it out for drawing // Input : *options - event parameters in text format @@ -3604,10 +3843,10 @@ bool C_BaseAnimating::DispatchMuzzleEffect( const char *options, bool isFirstPer int weaponType = 0; // Get the first parameter - p = nexttoken( token, p, ' ' ); + p = nexttoken( token, p, ' ' , sizeof(token) ); // Find the weapon type - if ( token[0] ) + if ( token ) { //TODO: Parse the type from a list instead if ( Q_stricmp( token, "COMBINE" ) == 0 ) @@ -3648,12 +3887,12 @@ bool C_BaseAnimating::DispatchMuzzleEffect( const char *options, bool isFirstPer } // Get the second parameter - p = nexttoken( token, p, ' ' ); + p = nexttoken( token, p, ' ' , sizeof(token) ); int attachmentIndex = -1; // Find the attachment name - if ( token[0] ) + if ( token ) { attachmentIndex = LookupAttachment( token ); @@ -3759,26 +3998,30 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int // Get the particle effect name const char *p = options; - p = nexttoken(token, p, ' '); - - const char* mtoken = ModifyEventParticles( token ); - if ( !mtoken || mtoken[0] == '\0' ) - return; - Q_strncpy( szParticleEffect, mtoken, sizeof(szParticleEffect) ); + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + const char* mtoken = ModifyEventParticles( token ); + if ( !mtoken || mtoken[0] == '\0' ) + return; + Q_strncpy( szParticleEffect, mtoken, sizeof(szParticleEffect) ); + } // Get the attachment type - p = nexttoken(token, p, ' '); - - iAttachType = GetAttachTypeFromString( token ); - if ( iAttachType == -1 ) + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) { - Warning("Invalid attach type specified for particle effect anim event. Trying to spawn effect '%s' with attach type of '%s'\n", szParticleEffect, token ); - return; + iAttachType = GetAttachTypeFromString( token ); + if ( iAttachType == -1 ) + { + Warning("Invalid attach type specified for particle effect anim event. Trying to spawn effect '%s' with attach type of '%s'\n", szParticleEffect, token ); + return; + } } // Get the attachment point index - p = nexttoken(token, p, ' '); - if ( token[0] ) + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) { iAttachment = atoi(token); @@ -3897,18 +4140,33 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int // Eject brass case CL_EVENT_EJECTBRASS1: - if ( m_Attachments.Count() > 0 ) { - if ( MainViewOrigin().DistToSqr( GetAbsOrigin() ) < (256 * 256) ) + // Check if we're a weapon, if we belong to the local player, and if the local player is in third person - if all are true, don't do a muzzleflash in this instance, because + // we're using the view models dispatch for smoothness. + if ( dynamic_cast< C_BaseCombatWeapon *>(this) != NULL ) { - Vector attachOrigin; - QAngle attachAngles; - - if( GetAttachment( 2, attachOrigin, attachAngles ) ) + C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon *>(this); + if ( pWeapon && pWeapon->GetOwner() == C_BasePlayer::GetLocalPlayer() && ::input->CAM_IsThirdPerson() ) + break; + } + + if ( ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) ) + break; + + if ( m_Attachments.Count() > 0 ) + { + if ( MainViewOrigin().DistToSqr( GetAbsOrigin() ) < (256 * 256) ) { - tempents->EjectBrass( attachOrigin, attachAngles, GetAbsAngles(), atoi( options ) ); + Vector attachOrigin; + QAngle attachAngles; + + if( GetAttachment( 2, attachOrigin, attachAngles ) ) + { + tempents->EjectBrass( attachOrigin, attachAngles, GetAbsAngles(), atoi( options ) ); + } } } + break; } break; @@ -3922,6 +4180,36 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int case AE_NPC_MUZZLEFLASH: { // Send out the effect for an NPC +#if defined ( HL2MP ) || defined ( SDK_DLL ) // works for the modified CSS weapons included in the new template sdk. + // HL2MP - Make third person muzzleflashes as reliable as the first person ones + // while in third person the view model dispatches the muzzleflash event - note: the weapon models dispatch them too, but not frequently. + if ( IsViewModel() ) + { + C_BasePlayer *pPlayer = ToBasePlayer( dynamic_cast(this)->GetOwner() ); + if ( pPlayer && pPlayer == C_BasePlayer::GetLocalPlayer()) + { + if ( ::input->CAM_IsThirdPerson() ) + { + // Dispatch on the weapon - the player model doesn't have the attachments in hl2mp. + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + if ( !pWeapon ) + break; + pWeapon->DispatchMuzzleEffect( options, false ); + break; + } + } + } + + // Check if we're a weapon, if we belong to the local player, and if the local player is in third person - if all are true, don't do a muzzleflash in this instance, because + // we're using the view models dispatch for smoothness. + if ( dynamic_cast< C_BaseCombatWeapon *>(this) != NULL ) + { + C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon *>(this); + if ( pWeapon && pWeapon->GetOwner() == C_BasePlayer::GetLocalPlayer() && ::input->CAM_IsThirdPerson() ) + break; + } + +#endif DispatchMuzzleEffect( options, false ); break; } @@ -3974,19 +4262,26 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int case AE_CL_BODYGROUP_SET_VALUE: { - int value; - char token[256]; char szBodygroupName[256]; + int value = 0; + + char token[256]; const char *p = options; // Bodygroup Name - p = nexttoken(token, p, ' '); - Q_strncpy( szBodygroupName, token, sizeof(szBodygroupName) ); + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + Q_strncpy( szBodygroupName, token, sizeof(szBodygroupName) ); + } // Get the desired value - p = nexttoken(token, p, ' '); - value = token[0] ? atoi( token ) : 0; + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + value = atoi( token ); + } int index = FindBodygroupByName( szBodygroupName ); if ( index >= 0 ) @@ -4015,21 +4310,33 @@ void C_BaseAnimating::FireObsoleteEvent( const Vector& origin, const QAngle& ang // Obsolete. Use the AE_CL_CREATE_PARTICLE_EFFECT event instead, which uses the artist driven particle system & editor. case AE_CLIENT_EFFECT_ATTACH: { - int iAttachment; - int iParam; + int iAttachment = -1; + int iParam = 0; char token[128]; char effectFunc[128]; const char *p = options; - p = nexttoken(token, p, ' '); - Q_strncpy( effectFunc, token, sizeof(effectFunc) ); + p = nexttoken(token, p, ' ', sizeof(token)); + + if( token ) + { + Q_strncpy( effectFunc, token, sizeof(effectFunc) ); + } + + p = nexttoken(token, p, ' ', sizeof(token)); + + if( token ) + { + iAttachment = atoi(token); + } - p = nexttoken(token, p, ' '); - iAttachment = token[0] ? atoi(token) : -1; + p = nexttoken(token, p, ' ', sizeof(token)); - p = nexttoken(token, p, ' '); - iParam = token[0] ? atoi(token) : 0; + if( token ) + { + iParam = atoi(token); + } if ( iAttachment != -1 && m_Attachments.Count() >= iAttachment ) { @@ -4572,7 +4879,7 @@ void C_BaseAnimating::OnPreDataChanged( DataUpdateType_t updateType ) m_bLastClientSideFrameReset = m_bClientSideFrameReset; } -bool C_BaseAnimating::ForceSetupBonesAtTime( matrix3x4_t *pBonesOut, float flTime ) +void C_BaseAnimating::ForceSetupBonesAtTime( matrix3x4_t *pBonesOut, float flTime ) { // blow the cached prev bones InvalidateBoneCache(); @@ -4581,18 +4888,13 @@ bool C_BaseAnimating::ForceSetupBonesAtTime( matrix3x4_t *pBonesOut, float flTim Interpolate( flTime ); // Setup bone state at the given time - return SetupBones( pBonesOut, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, flTime ); + SetupBones( pBonesOut, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, flTime ); } -bool C_BaseAnimating::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) +void C_BaseAnimating::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) { - bool bSuccess = true; - - if ( !ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt ) ) - bSuccess = false; - if ( !ForceSetupBonesAtTime( pDeltaBones1, gpGlobals->curtime ) ) - bSuccess = false; - + ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt ); + ForceSetupBonesAtTime( pDeltaBones1, gpGlobals->curtime ); float ragdollCreateTime = PhysGetSyncCreateTime(); if ( ragdollCreateTime != gpGlobals->curtime ) { @@ -4600,15 +4902,18 @@ bool C_BaseAnimating::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matri // 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 - if ( !ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime ) ) - bSuccess = false; + ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime ); } else { memcpy( pCurrentBones, m_CachedBoneData.Base(), sizeof( matrix3x4_t ) * m_CachedBoneData.Count() ); } +} - return bSuccess; +C_ClientRagdoll *C_BaseAnimating::CreateClientRagdoll( bool bRestoring ) +{ + //DevMsg( "Creating ragdoll at tick %d\n", gpGlobals->tickcount ); + return new C_ClientRagdoll( bRestoring ); } C_BaseAnimating *C_BaseAnimating::CreateRagdollCopy() @@ -4616,7 +4921,7 @@ C_BaseAnimating *C_BaseAnimating::CreateRagdollCopy() //Adrian: We now create a separate entity that becomes this entity's ragdoll. //That way the server side version of this entity can go away. //Plus we can hook save/restore code to these ragdolls so they don't fall on restore anymore. - C_ClientRagdoll *pRagdoll = new C_ClientRagdoll( false ); + C_ClientRagdoll *pRagdoll = CreateClientRagdoll( false ); if ( pRagdoll == NULL ) return NULL; @@ -4667,6 +4972,14 @@ C_BaseAnimating *C_BaseAnimating::CreateRagdollCopy() pRagdoll->m_nForceBone = m_nForceBone; pRagdoll->SetNextClientThink( CLIENT_THINK_ALWAYS ); +#ifdef MAPBASE + pRagdoll->m_iViewHideFlags = m_iViewHideFlags; + + pRagdoll->m_fadeMinDist = m_fadeMinDist; + pRagdoll->m_fadeMaxDist = m_fadeMaxDist; + pRagdoll->m_flFadeScale = m_flFadeScale; +#endif + pRagdoll->SetModelName( AllocPooledString(pModelName) ); pRagdoll->SetModelScale( GetModelScale() ); return pRagdoll; @@ -4676,33 +4989,26 @@ C_BaseAnimating *C_BaseAnimating::BecomeRagdollOnClient() { MoveToLastReceivedPosition( true ); GetAbsOrigin(); + m_pClientsideRagdoll = CreateRagdollCopy(); - C_BaseAnimating *pRagdoll = CreateRagdollCopy(); - if ( pRagdoll ) - { - matrix3x4_t boneDelta0[MAXSTUDIOBONES]; - matrix3x4_t boneDelta1[MAXSTUDIOBONES]; - matrix3x4_t currentBones[MAXSTUDIOBONES]; - const float boneDt = 0.1f; - - bool bInitAsClient = false; - bool bInitBoneArrays = GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); - - if ( bInitBoneArrays ) - { - bInitAsClient = pRagdoll->InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); - } + matrix3x4_t boneDelta0[MAXSTUDIOBONES]; + matrix3x4_t boneDelta1[MAXSTUDIOBONES]; + matrix3x4_t currentBones[MAXSTUDIOBONES]; + const float boneDt = 0.1f; + GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); + m_pClientsideRagdoll->InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); - if ( !bInitAsClient || !bInitBoneArrays ) - { - Warning( "C_BaseAnimating::BecomeRagdollOnClient failed. pRagdoll:%p bInitBoneArrays:%d bInitAsClient:%d\n", - pRagdoll, bInitBoneArrays, bInitAsClient ); - pRagdoll->Release(); - return NULL; - } +#ifdef MAPBASE_VSCRIPT + // Hook for ragdolling + if (m_ScriptScope.IsInitialized() && g_Hook_OnClientRagdoll.CanRunInScope( m_ScriptScope )) + { + // ragdoll + ScriptVariant_t args[] = { ScriptVariant_t( m_pClientsideRagdoll->GetScriptInstance() ) }; + g_Hook_OnClientRagdoll.Call( m_ScriptScope, NULL, args ); } +#endif - return pRagdoll; + return m_pClientsideRagdoll; } bool C_BaseAnimating::InitAsClientRagdoll( const matrix3x4_t *pDeltaBones0, const matrix3x4_t *pDeltaBones1, const matrix3x4_t *pCurrentBonePosition, float boneDt, bool bFixedConstraints ) @@ -5168,6 +5474,11 @@ void C_BaseAnimating::StudioFrameAdvance() if ( flNewCycle < 0.0f || flNewCycle >= 1.0f ) { + if (flNewCycle >= 1.0f) + { + ReachedEndOfSequence(); + } + if ( IsSequenceLooping( hdr, GetSequence() ) ) { flNewCycle -= (int)(flNewCycle); @@ -5360,9 +5671,8 @@ float C_BaseAnimating::FrameAdvance( float flInterval ) // Stubs for weapon prediction void C_BaseAnimating::ResetSequenceInfo( void ) { - if ( GetSequence() == -1 ) + if (GetSequence() == -1) { - // This shouldn't happen. Setting m_nSequence blindly is a horrible coding practice. SetSequence( 0 ); } @@ -5374,7 +5684,7 @@ void C_BaseAnimating::ResetSequenceInfo( void ) CStudioHdr *pStudioHdr = GetModelPtr(); m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() ) * GetModelScale(); - m_bSequenceLoops = ( ( GetSequenceFlags( pStudioHdr, GetSequence() ) & STUDIO_LOOPING ) != 0 ); + m_bSequenceLoops = ((GetSequenceFlags( pStudioHdr, GetSequence() ) & STUDIO_LOOPING) != 0); // m_flAnimTime = gpGlobals->time; m_flPlaybackRate = 1.0; m_bSequenceFinished = false; @@ -5382,12 +5692,9 @@ void C_BaseAnimating::ResetSequenceInfo( void ) m_nNewSequenceParity = ( m_nNewSequenceParity + 1 ) & EF_PARITY_MASK; m_nResetEventsParity = ( m_nResetEventsParity + 1 ) & EF_PARITY_MASK; - + // FIXME: why is this called here? Nothing should have changed to make this nessesary - if ( pStudioHdr ) - { - SetEventIndexForSequence( pStudioHdr->pSeqdesc( GetSequence() ) ); - } + SetEventIndexForSequence( pStudioHdr->pSeqdesc( GetSequence() ) ); } //========================================================= @@ -5614,13 +5921,6 @@ int C_BaseAnimating::SelectWeightedSequence ( int activity ) } -int C_BaseAnimating::SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount ) -{ - Assert( activity != ACT_INVALID ); - Assert( GetModelPtr() ); - return GetModelPtr()->SelectWeightedSequenceFromModifiers( activity, pActivityModifiers, iModifierCount ); -} - //========================================================= //========================================================= int C_BaseAnimating::LookupPoseParameter( CStudioHdr *pstudiohdr, const char *szName ) @@ -6127,7 +6427,7 @@ void C_BaseAnimating::AddToClientSideAnimationList() UpdateRelevantInterpolatedVars(); } -void C_BaseAnimating::RemoveFromClientSideAnimationList( bool bBeingDestroyed /*= false*/ ) +void C_BaseAnimating::RemoveFromClientSideAnimationList() { // Not in list yet if ( INVALID_CLIENTSIDEANIMATION_LIST_HANDLE == m_ClientSideAnimationListHandle ) @@ -6158,10 +6458,7 @@ void C_BaseAnimating::RemoveFromClientSideAnimationList( bool bBeingDestroyed /* // Invalidate our handle no matter what. m_ClientSideAnimationListHandle = INVALID_CLIENTSIDEANIMATION_LIST_HANDLE; - if ( !bBeingDestroyed ) - { - UpdateRelevantInterpolatedVars(); - } + UpdateRelevantInterpolatedVars(); } diff --git a/game/client/c_baseanimating.h b/game/client/c_baseanimating.h index f1b0467c..24e33a3b 100644 --- a/game/client/c_baseanimating.h +++ b/game/client/c_baseanimating.h @@ -38,6 +38,7 @@ class C_BaseClientShader */ class IRagdoll; +class C_ClientRagdoll; class CIKContext; class CIKState; class ConVar; @@ -79,7 +80,7 @@ class CAttachmentData QAngle m_angRotation; Vector m_vOriginVelocity; int m_nLastFramecount : 31; - int m_bAnglesComputed : 1; + bool m_bAnglesComputed : 1; }; @@ -95,6 +96,7 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback DECLARE_CLIENTCLASS(); DECLARE_PREDICTABLE(); DECLARE_INTERPOLATION(); + DECLARE_ENT_SCRIPTDESC(); enum { @@ -163,6 +165,17 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback virtual void FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options ); virtual const char* ModifyEventParticles( const char* token ) { return token; } +#ifdef MAPBASE_VSCRIPT + bool ScriptHookFireEvent( const Vector& origin, const QAngle& angles, int event, const char *options ); +#endif + +#if defined ( SDK_DLL ) || defined ( HL2MP ) + virtual void ResetEventsParity() { m_nPrevResetEventsParity = -1; } // used to force animation events to function on players so the muzzleflashes and other events occur + // so new functions don't have to be made to parse the models like CSS does in ProcessMuzzleFlashEvent + // allows the multiplayer world weapon models to declare the muzzleflashes, and other effects like sp + // without the need to script it and add extra parsing code. +#endif + // Parses and distributes muzzle flash events virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson ); @@ -247,7 +260,7 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback void ForceClientSideAnimationOn(); void AddToClientSideAnimationList(); - void RemoveFromClientSideAnimationList( bool bBeingDestroyed = false ); + void RemoveFromClientSideAnimationList(); virtual bool IsSelfAnimating(); virtual void ResetLatched(); @@ -289,6 +302,7 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback bool IsRagdoll() const; bool IsAboutToRagdoll() const; virtual C_BaseAnimating *BecomeRagdollOnClient(); + virtual C_ClientRagdoll *CreateClientRagdoll( bool bRestoring = false ); C_BaseAnimating *CreateRagdollCopy(); bool InitAsClientRagdoll( const matrix3x4_t *pDeltaBones0, const matrix3x4_t *pDeltaBones1, const matrix3x4_t *pCurrentBonePosition, float boneDt, bool bFixedConstraints=false ); void IgniteRagdoll( C_BaseAnimating *pSource ); @@ -298,8 +312,8 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback virtual void Clear( void ); void ClearRagdoll(); void CreateUnragdollInfo( C_BaseAnimating *pRagdoll ); - bool ForceSetupBonesAtTime( matrix3x4_t *pBonesOut, float flTime ); - virtual bool GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ); + 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; } @@ -342,6 +356,8 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback void ClientSideAnimationChanged(); virtual unsigned int ComputeClientSideAnimationFlags(); + virtual void ReachedEndOfSequence() { return; } + virtual void ResetClientsideFrame( void ) { SetCycle( 0 ); } void SetCycle( float flCycle ); @@ -429,7 +445,6 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback // For prediction int SelectWeightedSequence ( int activity ); - int SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount ); void ResetSequenceInfo( void ); float SequenceDuration( void ); float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence ); @@ -445,8 +460,42 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback virtual bool ShouldResetSequenceOnNewModel( void ); virtual bool IsViewModel() const; - virtual void UpdateOnRemove( void ); +#ifdef MAPBASE_VSCRIPT + int ScriptLookupAttachment( const char *pAttachmentName ) { return LookupAttachment( pAttachmentName ); } + const Vector& ScriptGetAttachmentOrigin(int iAttachment); + const Vector& ScriptGetAttachmentAngles(int iAttachment); + HSCRIPT ScriptGetAttachmentMatrix(int iAttachment); + + void ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ); + void ScriptSetBoneTransform( int iBone, HSCRIPT hTransform ); + + void ScriptAttachEntityToBone( HSCRIPT attachTarget, int boneIndexAttached, const Vector &bonePosition, const QAngle &boneAngles ); + void ScriptRemoveBoneAttachment( HSCRIPT boneAttachment ); + HSCRIPT ScriptGetBoneAttachment( int i ); + + int ScriptGetSequenceActivity( int iSequence ) { return GetSequenceActivity( iSequence ); } + float ScriptGetSequenceMoveDist( int iSequence ) { return GetSequenceMoveDist( GetModelPtr(), iSequence ); } + int ScriptSelectWeightedSequence( int activity ) { return SelectWeightedSequence( (Activity)activity ); } + + // For VScript + int ScriptGetSkin() { return GetSkin(); } + void SetSkin( int iSkin ) { m_nSkin = iSkin; } + + int GetForceBone() { return m_nForceBone; } + void SetForceBone( int iBone ) { m_nForceBone = iBone; } + const Vector& GetRagdollForce() { return m_vecForce; } + void SetRagdollForce( const Vector &vecForce ) { m_vecForce = vecForce; } + + HSCRIPT ScriptBecomeRagdollOnClient(); + + static ScriptHook_t g_Hook_OnClientRagdoll; + static ScriptHook_t g_Hook_FireEvent; + //static ScriptHook_t g_Hook_BuildTransformations; // UNDONE: Thread access issues + + float ScriptGetPoseParameter(const char* szName); +#endif + void ScriptSetPoseParameter(const char* szName, float fValue); 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), @@ -482,6 +531,10 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback public: CRagdoll *m_pRagdoll; + C_BaseAnimating *m_pClientsideRagdoll; // From Alien Swarm SDK +#ifdef MAPBASE + C_BaseAnimating *m_pServerRagdoll; // Not from Alien Swarm SDK (note that this can exist without the entity having died) +#endif // Texture group to use int m_nSkin; @@ -607,7 +660,7 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback // Calculated attachment points CUtlVector m_Attachments; - bool SetupBones_AttachmentHelper( CStudioHdr *pStudioHdr ); + void SetupBones_AttachmentHelper( CStudioHdr *pStudioHdr ); EHANDLE m_hLightingOrigin; EHANDLE m_hLightingOriginRelative; @@ -653,6 +706,9 @@ class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify C_ClientRagdoll( bool bRestoring = true ); DECLARE_CLASS( C_ClientRagdoll, C_BaseAnimating ); DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif // inherited from IPVSNotify virtual void OnPVSStatusChanged( bool bInPVS ); @@ -674,8 +730,17 @@ class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify void FadeOut( void ); virtual float LastBoneChangedTime(); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetRagdollObject( int iIndex ); + int ScriptGetRagdollObjectCount(); +#endif + bool m_bFadeOut; bool m_bImportant; +#ifdef MAPBASE + // Required to save/restore Alien Swarm SDK ragdoll LRU forced fade + float m_flForcedRetireTime; +#endif float m_flEffectTime; private: @@ -760,12 +825,19 @@ inline CStudioHdr *C_BaseAnimating::GetModelPtr() const inline void C_BaseAnimating::InvalidateMdlCache() { - UnlockStudioHdr(); + if ( m_pStudioHdr ) + { + UnlockStudioHdr(); + delete m_pStudioHdr; + m_pStudioHdr = NULL; + } } -inline bool C_BaseAnimating::IsModelScaleFractional() const + +inline bool C_BaseAnimating::IsModelScaleFractional() const /// very fast way to ask if the model scale is < 1.0f { - return ( m_flModelScale < 1.0f ); + COMPILE_TIME_ASSERT( sizeof( m_flModelScale ) == sizeof( int ) ); + return *((const int *) &m_flModelScale) < 0x3f800000; } inline bool C_BaseAnimating::IsModelScaled() const diff --git a/game/client/c_basecombatcharacter.cpp b/game/client/c_basecombatcharacter.cpp index e98b8ec9..fb53b8ff 100644 --- a/game/client/c_basecombatcharacter.cpp +++ b/game/client/c_basecombatcharacter.cpp @@ -34,7 +34,6 @@ C_BaseCombatCharacter::C_BaseCombatCharacter() m_pGlowEffect = NULL; m_bGlowEnabled = false; m_bOldGlowEnabled = false; - m_bClientSideGlowEnabled = false; #endif // GLOWS_ENABLE } @@ -114,22 +113,6 @@ void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b ) *b = 0.76f; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -/* -void C_BaseCombatCharacter::EnableGlowEffect( float r, float g, float b ) -{ - // destroy the existing effect - if ( m_pGlowEffect ) - { - DestroyGlowEffect(); - } - - m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true ); -} -*/ - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -142,7 +125,7 @@ void C_BaseCombatCharacter::UpdateGlowEffect( void ) } // create a new effect - if ( m_bGlowEnabled || m_bClientSideGlowEnabled ) + if ( m_bGlowEnabled ) { float r, g, b; GetGlowEffectColor( &r, &g, &b ); @@ -176,6 +159,7 @@ 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 VANCE RecvPropEHandle( RECVINFO( m_hDeployingWeapon ) ), #endif @@ -197,7 +181,45 @@ BEGIN_PREDICTION_DATA( C_BaseCombatCharacter ) 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 ), + #ifdef VANCE DEFINE_PRED_FIELD( m_hDeployingWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), #endif + END_PREDICTION_DATA() + +#ifdef MAPBASE_VSCRIPT + +BEGIN_ENT_SCRIPTDESC( C_BaseCombatCharacter, CBaseEntity, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAmmoCount, "GetAmmoCount", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetActiveWeapon, "GetActiveWeapon", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeapon, "GetWeapon", "" ) +END_SCRIPTDESC(); + + +int C_BaseCombatCharacter::ScriptGetAmmoCount( int i ) +{ + Assert( i == -1 || i < MAX_AMMO_SLOTS ); + + if ( i < 0 || i >= MAX_AMMO_SLOTS ) + return NULL; + + return GetAmmoCount( i ); +} + +HSCRIPT C_BaseCombatCharacter::ScriptGetActiveWeapon() +{ + return ToHScript( GetActiveWeapon() ); +} + +HSCRIPT C_BaseCombatCharacter::ScriptGetWeapon( int i ) +{ + Assert( i >= 0 && i < MAX_WEAPONS ); + + if ( i < 0 || i >= MAX_WEAPONS ) + return NULL; + + return ToHScript( GetWeapon(i) ); +} + +#endif diff --git a/game/client/c_basecombatcharacter.h b/game/client/c_basecombatcharacter.h index 8e827fe4..b27e1bfa 100644 --- a/game/client/c_basecombatcharacter.h +++ b/game/client/c_basecombatcharacter.h @@ -29,6 +29,9 @@ class C_BaseCombatCharacter : public C_BaseFlex public: DECLARE_CLIENTCLASS(); DECLARE_PREDICTABLE(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif C_BaseCombatCharacter( void ); virtual ~C_BaseCombatCharacter( void ); @@ -97,21 +100,17 @@ class C_BaseCombatCharacter : public C_BaseFlex virtual void DoMuzzleFlash(); - CHandle m_hActiveWeapon; -#ifdef VANCE - CHandle m_hDeployingWeapon; - friend class C_BasePlayer; -#endif - #ifdef GLOWS_ENABLE CGlowObject *GetGlowObject( void ){ return m_pGlowEffect; } virtual void GetGlowEffectColor( float *r, float *g, float *b ); -// void EnableGlowEffect( float r, float g, float b ); - - void SetClientSideGlowEnabled( bool bEnabled ){ m_bClientSideGlowEnabled = bEnabled; UpdateGlowEffect(); } - bool IsClientSideGlowEnabled( void ){ return m_bClientSideGlowEnabled; } #endif // GLOWS_ENABLE +#ifdef MAPBASE_VSCRIPT + int ScriptGetAmmoCount( int i ); + HSCRIPT ScriptGetActiveWeapon(); + HSCRIPT ScriptGetWeapon( int i ); +#endif + public: float m_flNextAttack; @@ -131,15 +130,15 @@ class C_BaseCombatCharacter : public C_BaseFlex CNetworkArray( int, m_iAmmo, MAX_AMMO_TYPES ); CHandle m_hMyWeapons[MAX_WEAPONS]; -#ifndef VANCE CHandle< C_BaseCombatWeapon > m_hActiveWeapon; -#else - friend class C_ShowWeapon; // This allows CShowWeapon to access whatever it needs to update for the character + +#ifdef VANCE + CHandle m_hDeployingWeapon; + friend class C_BasePlayer; #endif #ifdef GLOWS_ENABLE - bool m_bClientSideGlowEnabled; // client-side only value used for spectator - bool m_bGlowEnabled; // networked value + bool m_bGlowEnabled; bool m_bOldGlowEnabled; CGlowObject *m_pGlowEffect; #endif // GLOWS_ENABLE diff --git a/game/client/c_basecombatweapon.cpp b/game/client/c_basecombatweapon.cpp index ef4c845e..3ae13cde 100644 --- a/game/client/c_basecombatweapon.cpp +++ b/game/client/c_basecombatweapon.cpp @@ -16,6 +16,9 @@ #include "tier1/KeyValues.h" #include "toolframework/itoolframework.h" #include "toolframework_client.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -82,6 +85,24 @@ static inline bool ShouldDrawLocalPlayerViewModel( void ) { #if defined( PORTAL ) return false; +#elif MAPBASE + // We shouldn't draw the viewmodel externally. + C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer(); + if (localplayer) + { + if (localplayer->m_bDrawPlayerModelExternally) + { + // If this isn't the main view, draw the weapon. + view_id_t viewID = CurrentViewID(); + if (viewID != VIEW_MAIN && viewID != VIEW_INTRO_CAMERA) + return false; + } + + // Since we already have the local player, check its own ShouldDrawThisPlayer() to avoid extra checks + return !localplayer->ShouldDrawThisPlayer(); + } + else + return false; #else return !C_BasePlayer::ShouldDrawLocalPlayer(); #endif @@ -104,9 +125,15 @@ void C_BaseCombatWeapon::OnRestore() int C_BaseCombatWeapon::GetWorldModelIndex( void ) { +#ifdef MAPBASE + int iIndex = GetOwner() ? m_iWorldModelIndex.Get() : m_iDroppedModelIndex.Get(); +#else + int iIndex = m_iWorldModelIndex.Get(); +#endif + if ( GameRules() ) { - const char *pBaseName = modelinfo->GetModelName( modelinfo->GetModel( m_iWorldModelIndex ) ); + const char *pBaseName = modelinfo->GetModelName( modelinfo->GetModel( iIndex ) ); const char *pTranslatedName = GameRules()->TranslateEffectForVisionFilter( "weapons", pBaseName ); if ( pTranslatedName != pBaseName ) @@ -115,7 +142,7 @@ int C_BaseCombatWeapon::GetWorldModelIndex( void ) } } - return m_iWorldModelIndex; + return iIndex; } //----------------------------------------------------------------------------- @@ -156,17 +183,11 @@ void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType ) } else // weapon carried by other player or not at all { - int overrideModelIndex = CalcOverrideModelIndex(); - if( overrideModelIndex != -1 && overrideModelIndex != GetModelIndex() ) - { - SetModelIndex( overrideModelIndex ); - } + // See comment below + EnsureCorrectRenderingModel(); } - if ( updateType == DATA_UPDATE_CREATED ) - { - UpdateVisibility(); - } + UpdateVisibility(); m_iOldState = m_iState; @@ -435,6 +456,12 @@ bool C_BaseCombatWeapon::ShouldDraw( void ) if ( !ShouldDrawLocalPlayerViewModel() ) return true; +#ifdef MAPBASE + // We're drawing this in non-main views, handle it in DrawModel() + if ( pLocalPlayer->m_bDrawPlayerModelExternally ) + return true; +#endif + // don't draw active weapon if not in some kind of 3rd person mode, the viewmodel will do that return false; } @@ -481,15 +508,44 @@ int C_BaseCombatWeapon::DrawModel( int flags ) // check if local player chases owner of this weapon in first person C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer(); - if ( localplayer && localplayer->IsObserver() && GetOwner() ) + if ( localplayer ) { - // don't draw weapon if chasing this guy as spectator - // we don't check that in ShouldDraw() since this may change - // without notification +#ifdef MAPBASE + if (localplayer->m_bDrawPlayerModelExternally) + { + // If this isn't the main view, draw the weapon. + view_id_t viewID = CurrentViewID(); + if ( (!localplayer->InFirstPersonView() || (viewID != VIEW_MAIN && viewID != VIEW_INTRO_CAMERA)) && (viewID != VIEW_SHADOW_DEPTH_TEXTURE || !localplayer->IsEffectActive(EF_DIMLIGHT)) ) + { + // TODO: Is this inefficient? + int nModelIndex = GetModelIndex(); + int nWorldModelIndex = GetWorldModelIndex(); + if (nModelIndex != nWorldModelIndex) + { + SetModelIndex(nWorldModelIndex); + } + + int iDraw = BaseClass::DrawModel(flags); + + if (nModelIndex != nWorldModelIndex) + { + SetModelIndex(nModelIndex); + } + + return iDraw; + } + } +#endif + if ( 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; + if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE && + localplayer->GetObserverTarget() == GetOwner() ) + return false; + } } return BaseClass::DrawModel( flags ); @@ -517,6 +573,35 @@ int C_BaseCombatWeapon::CalcOverrideModelIndex() } } +//----------------------------------------------------------------------------- +// 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() && + !ShouldDrawUsingViewModel() ) + { + 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 diff --git a/game/client/c_baseentity.cpp b/game/client/c_baseentity.cpp index 338f986c..43471e9d 100644 --- a/game/client/c_baseentity.cpp +++ b/game/client/c_baseentity.cpp @@ -40,6 +40,14 @@ #include "cdll_bounded_cvars.h" #include "inetchannelinfo.h" #include "proto_version.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif +#ifdef MAPBASE_VSCRIPT +#include "vscript_client.h" +#endif + +#include "gamestringpool.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -420,6 +428,143 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst ) RecvPropInt( RECVINFO(m_flAnimTime), 0, RecvProxy_AnimTime ), END_RECV_TABLE() +#ifdef MAPBASE_VSCRIPT +ScriptHook_t C_BaseEntity::g_Hook_UpdateOnRemove; +ScriptHook_t C_BaseEntity::g_Hook_ModifyEmitSoundParams; +#endif + +BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" ) + DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper ) + DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRight, "GetRightVector", "Get the right vector of the entity" ) + DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeam", "Gets this entity's team" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeft, "GetLeftVector", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeamNumber", SCRIPT_HIDE ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetUp, "GetUpVector", "Get the up vector of the entity" ) + +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( ValidateScriptScope, "Ensure that an entity's script scope has been created" ) + DEFINE_SCRIPTFUNC( GetOrCreatePrivateScriptScope, "Create and retrieve the script-side data associated with an entity" ) + DEFINE_SCRIPTFUNC( GetScriptScope, "Retrieve the script-side data associated with an entity" ) + + DEFINE_SCRIPTFUNC( GetHealth, "" ) + DEFINE_SCRIPTFUNC( GetMaxHealth, "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname." ) + + DEFINE_SCRIPTFUNC( GetClassname, "" ) + DEFINE_SCRIPTFUNC_NAMED( GetEntityName, "GetName", "" ) + + DEFINE_SCRIPTFUNC_NAMED( SetAbsOrigin, "SetOrigin", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetForward, "SetForwardVector", "Set the orientation of the entity to have this forward vector" ) + + DEFINE_SCRIPTFUNC( GetLocalOrigin, "GetLocalOrigin" ) + DEFINE_SCRIPTFUNC( SetLocalOrigin, "SetLocalOrigin" ) + DEFINE_SCRIPTFUNC( GetLocalAngles, "GetLocalAngles" ) + DEFINE_SCRIPTFUNC( SetLocalAngles, "SetLocalAngles" ) + + DEFINE_SCRIPTFUNC_NAMED( WorldSpaceCenter, "GetCenter", "Get vector to center of object - absolute coords" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEyePosition, "EyePosition", "Get vector to eye position - absolute coords" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEyeAngles, "EyeAngles", "Get eye pitch, yaw, roll as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( GetAbsAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( SetAbsAngles, "SetAngles", "Set entity pitch, yaw, roll" ) + + DEFINE_SCRIPTFUNC( SetSize, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysicsObject, "GetPhysicsObject", "Get the entity's physics object if it has one" ) + + DEFINE_SCRIPTFUNC( GetWaterLevel, "Get current level of water submergence" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetParent, "SetParent", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveParent, "GetMoveParent", "If in hierarchy, retrieves the entity's parent" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRootMoveParent, "GetRootMoveParent", "If in hierarchy, walks up the hierarchy to find the root parent" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFirstMoveChild, "FirstMoveChild", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptNextMovePeer, "NextMovePeer", "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptFollowEntity, "FollowEntity", "Begin following the specified entity. This makes this entity non-solid, parents it to the target entity, and teleports it to the specified entity's origin. The second parameter is whether or not to use bonemerging while following." ) + DEFINE_SCRIPTFUNC( StopFollowingEntity, "Stops following an entity if we're following one." ) + DEFINE_SCRIPTFUNC( IsFollowingEntity, "Returns true if this entity is following another entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFollowedEntity, "GetFollowedEntity", "Get the entity we're following." ) + + DEFINE_SCRIPTFUNC_NAMED( GetScriptOwnerEntity, "GetOwner", "Gets this entity's owner" ) + DEFINE_SCRIPTFUNC_NAMED( SetScriptOwnerEntity, "SetOwner", "Sets this entity's owner" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorVector, "GetRenderColorVector", "Get the render color as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorR, "GetRenderColorR", "Get the render color's R value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorG, "GetRenderColorG", "Get the render color's G value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorB, "GetRenderColorB", "Get the render color's B value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAlpha, "GetRenderAlpha", "Get the render color's alpha value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorVector, "SetRenderColorVector", "Set the render color as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColor, "SetRenderColor", "Set the render color" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorR, "SetRenderColorR", "Set the render color's R value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorG, "SetRenderColorG", "Set the render color's G value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorB, "SetRenderColorB", "Set the render color's B value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAlpha, "SetRenderAlpha", "Set the render color's alpha value" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRenderMode, "GetRenderMode", "Get render mode" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetRenderMode, "SetRenderMode", "Set render mode" ) + + DEFINE_SCRIPTFUNC( GetEffects, "Get effects" ) + DEFINE_SCRIPTFUNC( AddEffects, "Add effect(s)" ) + DEFINE_SCRIPTFUNC( RemoveEffects, "Remove effect(s)" ) + DEFINE_SCRIPTFUNC( ClearEffects, "Clear effect(s)" ) + DEFINE_SCRIPTFUNC( SetEffects, "Set effect(s)" ) + DEFINE_SCRIPTFUNC( IsEffectActive, "Check if an effect is active" ) + + DEFINE_SCRIPTFUNC( GetFlags, "Get flags" ) + DEFINE_SCRIPTFUNC( AddFlag, "Add flag" ) + DEFINE_SCRIPTFUNC( RemoveFlag, "Remove flag" ) + + DEFINE_SCRIPTFUNC( GetEFlags, "Get Eflags" ) + DEFINE_SCRIPTFUNC( AddEFlags, "Add Eflags" ) + DEFINE_SCRIPTFUNC( RemoveEFlags, "Remove Eflags" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveType, "GetMoveType", "Get the move type" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetMoveType, "SetMoveType", "Set the move type" ) + + DEFINE_SCRIPTFUNC( GetCollisionGroup, "Get the collision group" ) + DEFINE_SCRIPTFUNC( SetCollisionGroup, "Set the collision group" ) + + DEFINE_SCRIPTFUNC( GetSolidFlags, "Get solid flags" ) + DEFINE_SCRIPTFUNC( AddSolidFlags, "Add solid flags" ) + DEFINE_SCRIPTFUNC( RemoveSolidFlags, "Remove solid flags" ) + + DEFINE_SCRIPTFUNC( IsPlayer, "Returns true if this entity is a player." ) + DEFINE_SCRIPTFUNC( IsNPC, "Returns true if this entity is a NPC." ) + //DEFINE_SCRIPTFUNC( IsCombatCharacter, "Returns true if this entity is a combat character (player or NPC)." ) + DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." ) + DEFINE_SCRIPTFUNC( IsWorld, "Returns true if this entity is the world." ) + + DEFINE_SCRIPTFUNC( SetModel, "Set client-only entity model" ) + //DEFINE_SCRIPTFUNC_NAMED( ScriptInitializeAsClientEntity, "InitializeAsClientEntity", "" ) + DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "Remove clientside entity" ) + DEFINE_SCRIPTFUNC_NAMED( GetEntityIndex, "entindex", "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." ) + + + DEFINE_SIMPLE_SCRIPTHOOK( C_BaseEntity::g_Hook_UpdateOnRemove, "UpdateOnRemove", FIELD_VOID, "Called when the entity is being removed." ) + + BEGIN_SCRIPTHOOK( C_BaseEntity::g_Hook_ModifyEmitSoundParams, "ModifyEmitSoundParams", FIELD_VOID, "Called every time a sound is emitted on this entity, allowing for its parameters to be modified." ) + DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + +#endif // MAPBASE_VSCRIPT + +END_SCRIPTDESC(); #ifndef NO_ENTITY_PREDICTION BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_PredictableId ) @@ -451,6 +596,10 @@ BEGIN_RECV_TABLE_NOBASE(C_BaseEntity, DT_BaseEntity) RecvPropInt(RECVINFO(m_nRenderMode)), RecvPropInt(RECVINFO(m_nRenderFX)), RecvPropInt(RECVINFO(m_clrRender)), +#ifdef MAPBASE + RecvPropInt(RECVINFO(m_iViewHideFlags)), + RecvPropBool(RECVINFO(m_bDisableFlashlight)), +#endif RecvPropInt(RECVINFO(m_iTeamNum)), RecvPropInt(RECVINFO(m_CollisionGroup)), RecvPropFloat(RECVINFO(m_flElasticity)), @@ -460,6 +609,8 @@ BEGIN_RECV_TABLE_NOBASE(C_BaseEntity, DT_BaseEntity) RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ), RecvPropInt( RECVINFO( m_iParentAttachment ) ), + RecvPropString(RECVINFO(m_iName)), + RecvPropInt( "movetype", 0, SIZEOF_IGNORE, 0, RecvProxy_MoveType ), RecvPropInt( "movecollide", 0, SIZEOF_IGNORE, 0, RecvProxy_MoveCollide ), RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ), @@ -571,8 +722,7 @@ void SpewInterpolatedVar( CInterpolatedVar< Vector > *pVar ) { Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - Vector v0(0, 0, 0); - CApparentVelocity apparent(v0); + CApparentVelocity apparent; float prevtime = 0.0f; while ( 1 ) { @@ -595,8 +745,7 @@ void SpewInterpolatedVar( CInterpolatedVar< Vector > *pVar, float flNow, float f Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - Vector v0(0, 0, 0); - CApparentVelocity apparent(v0); + CApparentVelocity apparent; float newtime = 999999.0f; Vector newVec( 0, 0, 0 ); bool bSpew = true; @@ -664,7 +813,7 @@ void SpewInterpolatedVar( CInterpolatedVar< float > *pVar ) { Msg( "--------------------------------------------------\n" ); int i = pVar->GetHead(); - CApparentVelocity apparent(0.0f); + CApparentVelocity apparent; while ( 1 ) { float changetime; @@ -686,8 +835,7 @@ void GetInterpolatedVarTimeRange( CInterpolatedVar *pVar, float &flMin, float flMax = -1e23; int i = pVar->GetHead(); - Vector v0(0, 0, 0); - CApparentVelocity apparent(v0); + CApparentVelocity apparent; while ( 1 ) { float changetime; @@ -895,8 +1043,6 @@ C_BaseEntity::C_BaseEntity() : m_iv_angRotation( "C_BaseEntity::m_iv_angRotation" ), m_iv_vecVelocity( "C_BaseEntity::m_iv_vecVelocity" ) { - m_pAttributes = NULL; - AddVar( &m_vecOrigin, &m_iv_vecOrigin, LATCH_SIMULATION_VAR ); AddVar( &m_angRotation, &m_iv_angRotation, LATCH_SIMULATION_VAR ); // Removing this until we figure out why velocity introduces view hitching. @@ -1094,6 +1240,8 @@ bool C_BaseEntity::Init( int entnum, int iSerialNum ) m_nCreationTick = gpGlobals->tickcount; + m_hScriptInstance = NULL; + return true; } @@ -1150,13 +1298,6 @@ bool C_BaseEntity::InitializeAsClientEntityByIndex( int iIndex, RenderGroup_t re return true; } -void C_BaseEntity::TrackAngRotation( bool bTrack ) -{ - if ( bTrack ) - AddVar( &m_angRotation, &m_iv_angRotation, LATCH_SIMULATION_VAR ); - else - RemoveVar( &m_angRotation, false ); -} void C_BaseEntity::Term() { @@ -1171,6 +1312,7 @@ void C_BaseEntity::Term() g_Predictables.RemoveFromPredictablesList( GetClientHandle() ); } + // If it's play simulated, remove from simulation list if the player still exists... if ( IsPlayerSimulated() && C_BasePlayer::GetLocalPlayer() ) { @@ -1207,6 +1349,27 @@ void C_BaseEntity::Term() RemoveFromLeafSystem(); RemoveFromAimEntsList(); + + if ( m_hScriptInstance ) + { +#ifdef MAPBASE_VSCRIPT + if ( m_ScriptScope.IsInitialized() && g_Hook_UpdateOnRemove.CanRunInScope( m_ScriptScope ) ) + { + g_Hook_UpdateOnRemove.Call( m_ScriptScope, NULL, NULL ); + } +#endif + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + m_hScriptInstance = NULL; + +#ifdef MAPBASE_VSCRIPT + FOR_EACH_VEC( m_ScriptThinkFuncs, i ) + { + HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink; + if ( h ) g_pScriptVM->ReleaseScript( h ); + } + m_ScriptThinkFuncs.PurgeAndDeleteElements(); +#endif + } } @@ -1311,6 +1474,19 @@ bool C_BaseEntity::VPhysicsIsFlesh( void ) return false; } +//----------------------------------------------------------------------------- +// Returns the health fraction +//----------------------------------------------------------------------------- +float C_BaseEntity::HealthFraction() const +{ + if (GetMaxHealth() == 0) + return 1.0f; + + float flFraction = (float)GetHealth() / (float)GetMaxHealth(); + flFraction = clamp( flFraction, 0.0f, 1.0f ); + return flFraction; +} + //----------------------------------------------------------------------------- // Purpose: Retrieves the coordinate frame for this entity. @@ -1543,6 +1719,11 @@ bool C_BaseEntity::ShouldReceiveProjectedTextures( int flags ) if ( IsEffectActive( EF_NODRAW ) ) return false; +#ifdef MAPBASE + if ( m_bDisableFlashlight ) + return false; +#endif + if( flags & SHADOW_FLAGS_FLASHLIGHT ) { if ( GetRenderMode() > kRenderNormal && GetRenderColor().a == 0 ) @@ -1977,6 +2158,17 @@ int C_BaseEntity::DrawModel( int flags ) return drawn; } +#ifdef MAPBASE + if (m_iViewHideFlags > 0) + { + // Hide this entity if it's not supposed to be drawn in this view. + if (m_iViewHideFlags & (1 << CurrentViewID())) + { + return 0; + } + } +#endif + int modelType = modelinfo->GetModelType( model ); switch ( modelType ) { @@ -2466,36 +2658,37 @@ void C_BaseEntity::UnlinkFromHierarchy() void C_BaseEntity::ValidateModelIndex( void ) { #ifdef TF_CLIENT_DLL - if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_HALLOWEEN ) ) + if ( m_nModelIndexOverrides[VISION_MODE_NONE] > 0 ) { - if ( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] > 0 ) + if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_HALLOWEEN ) ) { - SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] ); - return; + if ( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] > 0 ) + { + SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_HALLOWEEN] ); + return; + } } - } - if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_PYRO ) ) - { - if ( m_nModelIndexOverrides[VISION_MODE_PYRO] > 0 ) + if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_PYRO ) ) { - SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_PYRO] ); - return; + if ( m_nModelIndexOverrides[VISION_MODE_PYRO] > 0 ) + { + SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_PYRO] ); + return; + } } - } - if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_ROME ) ) - { - if ( m_nModelIndexOverrides[VISION_MODE_ROME] > 0 ) + if ( IsLocalPlayerUsingVisionFilterFlags( TF_VISION_FILTER_ROME ) ) { - SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_ROME] ); - return; + if ( m_nModelIndexOverrides[VISION_MODE_ROME] > 0 ) + { + SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_ROME] ); + return; + } } - } - if ( m_nModelIndexOverrides[VISION_MODE_NONE] > 0 ) - { SetModelByIndex( m_nModelIndexOverrides[VISION_MODE_NONE] ); + return; } #endif @@ -2622,17 +2815,6 @@ void C_BaseEntity::PostDataUpdate( DataUpdateType_t updateType ) } } -//----------------------------------------------------------------------------- -// Purpose: Latch simulation values when the entity has not changed -//----------------------------------------------------------------------------- -void C_BaseEntity::OnDataUnchangedInPVS() -{ - Assert( m_hNetworkMoveParent.Get() || !m_hNetworkMoveParent.IsValid() ); - HierarchySetParent(m_hNetworkMoveParent); - - MarkMessageReceived(); -} - //----------------------------------------------------------------------------- // Purpose: // Input : *context - @@ -3750,7 +3932,7 @@ void C_BaseEntity::AddColoredDecal( const Vector& rayStart, const Vector& rayEnd case mod_brush: { - color32 cColor32 = { (byte)cColor.r(), (byte)cColor.g(), (byte)cColor.b(), (byte)cColor.a() }; + color32 cColor32 = { cColor.r(), cColor.g(), cColor.b(), cColor.a() }; effects->DecalColorShoot( decalIndex, index, model, GetAbsOrigin(), GetAbsAngles(), decalCenter, 0, 0, cColor32 ); } break; @@ -4750,9 +4932,15 @@ C_BaseEntity *C_BaseEntity::Instance( int iEnt ) } #ifdef WIN32 + +#if _MSC_VER < 1900 #pragma warning( push ) #include #pragma warning( pop ) +#else +#include +#endif + #endif //----------------------------------------------------------------------------- @@ -5990,6 +6178,9 @@ BEGIN_DATADESC_NO_BASE( C_BaseEntity ) DEFINE_FIELD( m_angAbsRotation, FIELD_VECTOR ), DEFINE_ARRAY( m_rgflCoordinateFrame, FIELD_FLOAT, 12 ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore) DEFINE_FIELD( m_fFlags, FIELD_INTEGER ), +#ifdef MAPBASE_VSCRIPT + DEFINE_FIELD( m_iszScriptId, FIELD_STRING ), +#endif END_DATADESC() //----------------------------------------------------------------------------- @@ -6306,9 +6497,6 @@ bool C_BaseEntity::ValidateEntityAttachedToPlayer( bool &bShouldRetry ) if ( FStrEq( pszModel, "models/flag/briefcase.mdl" ) ) return true; - if ( FStrEq( pszModel, "models/passtime/ball/passtime_ball.mdl" ) ) - return true; - if ( FStrEq( pszModel, "models/props_doomsday/australium_container.mdl" ) ) return true; @@ -6321,16 +6509,6 @@ bool C_BaseEntity::ValidateEntityAttachedToPlayer( bool &bShouldRetry ) if ( FStrEq( pszModel, "models/props_lakeside_event/bomb_temp_hat.mdl" ) ) return true; - - if ( FStrEq( pszModel, "models/props_moonbase/powersupply_flag.mdl" ) ) - return true; - - // The Halloween 2014 doomsday flag replacement - if ( FStrEq( pszModel, "models/flag/ticket_case.mdl" ) ) - return true; - - if ( FStrEq( pszModel, "models/weapons/c_models/c_grapple_proj/c_grapple_proj.mdl" ) ) - return true; } // Any entity that's not an item parented to a player is invalid. @@ -6447,6 +6625,187 @@ int C_BaseEntity::GetCreationTick() const return m_nCreationTick; } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::GetScriptInstance() +{ + if (!m_hScriptInstance) + { + if (m_iszScriptId == NULL_STRING) + { + char* szName = (char*)stackalloc(1024); + g_pScriptVM->GenerateUniqueKey((m_iName != NULL_STRING) ? STRING(GetEntityName()) : GetClassname(), szName, 1024); + m_iszScriptId = AllocPooledString(szName); + } + + m_hScriptInstance = g_pScriptVM->RegisterInstance(GetScriptDesc(), this); + g_pScriptVM->SetInstanceUniqeId(m_hScriptInstance, STRING(m_iszScriptId)); + } + return m_hScriptInstance; +} + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Using my edict, cook up a unique VScript scope that's private to me, and +// persistent. +//----------------------------------------------------------------------------- +bool C_BaseEntity::ValidateScriptScope() +{ + if (!m_ScriptScope.IsInitialized()) + { + if (scriptmanager == NULL) + { + ExecuteOnce(DevMsg("Cannot execute script because scripting is disabled (-scripting)\n")); + return false; + } + + if (g_pScriptVM == NULL) + { + ExecuteOnce(DevMsg(" Cannot execute script because there is no available VM\n")); + return false; + } + + // Force instance creation + GetScriptInstance(); + + EHANDLE hThis; + hThis.Set(this); + + bool bResult = m_ScriptScope.Init(STRING(m_iszScriptId)); + + if (!bResult) + { + DevMsg("%s couldn't create ScriptScope!\n", GetDebugName()); + return false; + } + g_pScriptVM->SetValue(m_ScriptScope, "self", GetScriptInstance()); + } + return true; +} + +//----------------------------------------------------------------------------- +// Returns true if the function was located and called. false otherwise. +// NOTE: Assumes the function takes no parameters at the moment. +//----------------------------------------------------------------------------- +bool C_BaseEntity::CallScriptFunction( const char* pFunctionName, ScriptVariant_t* pFunctionReturn ) +{ + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + + HSCRIPT hFunc = m_ScriptScope.LookupFunction(pFunctionName); + + if (hFunc) + { + m_ScriptScope.Call(hFunc, pFunctionReturn); + m_ScriptScope.ReleaseFunction(hFunc); + + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Gets a function handle +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::LookupScriptFunction( const char* pFunctionName ) +{ + if (!m_ScriptScope.IsInitialized()) + { + return NULL; + } + + return m_ScriptScope.LookupFunction(pFunctionName); +} + +//----------------------------------------------------------------------------- +// Calls and releases a function handle (ASSUMES SCRIPT SCOPE AND FUNCTION ARE VALID!) +//----------------------------------------------------------------------------- +bool C_BaseEntity::CallScriptFunctionHandle( HSCRIPT hFunc, ScriptVariant_t* pFunctionReturn ) +{ + m_ScriptScope.Call(hFunc, pFunctionReturn); + m_ScriptScope.ReleaseFunction(hFunc); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Load, compile, and run a script file from disk. +// Input : *pScriptFile - The filename of the script file. +// bUseRootScope - If true, runs this script in the root scope, not +// in this entity's private scope. +//----------------------------------------------------------------------------- +bool C_BaseEntity::RunScriptFile( const char* pScriptFile, bool bUseRootScope ) +{ + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + if (bUseRootScope) + { + return VScriptRunScript(pScriptFile); + } + else + { + return VScriptRunScript(pScriptFile, m_ScriptScope, true); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Compile and execute a discrete string of script source code +// Input : *pScriptText - A string containing script code to compile and run +//----------------------------------------------------------------------------- +bool C_BaseEntity::RunScript( const char* pScriptText, const char* pDebugFilename ) +{ + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + if (m_ScriptScope.Run(pScriptText, pDebugFilename) == SCRIPT_ERROR) + { + DevWarning(" Entity %s encountered an error in RunScript()\n", GetDebugName()); + } + + return true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::ScriptGetMoveParent( void ) +{ + return ToHScript( GetMoveParent() ); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::ScriptGetRootMoveParent() +{ + return ToHScript( GetRootMoveParent() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::ScriptFirstMoveChild( void ) +{ + return ToHScript( FirstMoveChild() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT C_BaseEntity::ScriptNextMovePeer( void ) +{ + return ToHScript( NextMovePeer() ); +} +#endif + //------------------------------------------------------------------------------ void CC_CL_Find_Ent( const CCommand& args ) { diff --git a/game/client/c_baseentity.h b/game/client/c_baseentity.h index b40aaa0e..8d3b3f0c 100644 --- a/game/client/c_baseentity.h +++ b/game/client/c_baseentity.h @@ -36,6 +36,9 @@ #include "toolframework/itoolentity.h" #include "tier0/threadtools.h" +#include "vscript/ivscript.h" +#include "vscript_shared.h" + class C_Team; class IPhysicsObject; class IClientVehicle; @@ -58,7 +61,6 @@ class C_BaseCombatCharacter; class CEntityMapData; class ConVar; class CDmgAccumulator; -class IHasAttributes; struct CSoundParameters; @@ -78,7 +80,7 @@ enum CollideType_t class VarMapEntry_t { - + public: unsigned short type; @@ -100,7 +102,7 @@ struct VarMapping_t float m_lastInterpolationTime; }; - + #define DECLARE_INTERPOLATION() @@ -159,6 +161,15 @@ struct thinkfunc_t int m_nLastThinkTick; }; +#ifdef MAPBASE_VSCRIPT +struct scriptthinkfunc_t +{ + float m_flNextThink; + HSCRIPT m_hfnThink; + unsigned m_iContextHash; +}; +#endif + #define CREATE_PREDICTED_ENTITY( className ) \ C_BaseEntity::CreatePredictedEntityByName( className, __FILE__, __LINE__ ); @@ -184,19 +195,21 @@ class C_BaseEntity : public IClientEntity DECLARE_DATADESC(); DECLARE_CLIENTCLASS(); DECLARE_PREDICTABLE(); + // script description + DECLARE_ENT_SCRIPTDESC(); C_BaseEntity(); virtual ~C_BaseEntity(); static C_BaseEntity *CreatePredictedEntityByName( const char *classname, const char *module, int line, bool persist = false ); - + // FireBullets uses shared code for prediction. virtual void FireBullets( const FireBulletsInfo_t &info ); - virtual void FireBulletProjectiles(const ProjectileBulletsInfo_t& info); + virtual void FireBulletProjectiles( const ProjectileBulletsInfo_t &info ); virtual void ModifyFireBulletsDamage( CTakeDamageInfo* dmgInfo ) {} virtual bool ShouldDrawUnderwaterBulletBubbles(); virtual bool ShouldDrawWaterImpacts( void ) { return true; } - virtual bool HandleShotImpactingWater( const FireBulletsInfo_t &info, + virtual bool HandleShotImpactingWater( const FireBulletsInfo_t &info, const Vector &vecEnd, ITraceFilter *pTraceFilter, Vector *pVecTracerDest ); virtual ITraceFilter* GetBeamTraceFilter( void ); virtual void DispatchTraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL ); @@ -229,10 +242,10 @@ class C_BaseEntity : public IClientEntity void Interp_SetupMappings( VarMapping_t *map ); - + // Returns 1 if there are no more changes (ie: we could call RemoveFromInterpolationList). int Interp_Interpolate( VarMapping_t *map, float currentTime ); - + void Interp_RestoreToLastNetworked( VarMapping_t *map ); void Interp_UpdateInterpolationAmounts( VarMapping_t *map ); void Interp_HierarchyUpdateInterpolationAmounts(); @@ -258,6 +271,35 @@ class C_BaseEntity : public IClientEntity string_t m_iClassname; +#ifdef MAPBASE_VSCRIPT + // VSCRIPT + bool ValidateScriptScope(); + bool CallScriptFunction( const char* pFunctionName, ScriptVariant_t* pFunctionReturn ); + + HSCRIPT GetOrCreatePrivateScriptScope(); + HSCRIPT GetScriptScope() { return m_ScriptScope; } + + HSCRIPT LookupScriptFunction(const char* pFunctionName); + bool CallScriptFunctionHandle(HSCRIPT hFunc, ScriptVariant_t* pFunctionReturn); + + bool RunScriptFile( const char* pScriptFile, bool bUseRootScope = false ); + bool RunScript( const char* pScriptText, const char* pDebugFilename = "C_BaseEntity::RunScript" ); +#endif + + HSCRIPT GetScriptOwnerEntity(); + virtual void SetScriptOwnerEntity(HSCRIPT pOwner); + + HSCRIPT GetScriptInstance(); + + HSCRIPT m_hScriptInstance; + string_t m_iszScriptId; +#ifdef MAPBASE_VSCRIPT + CScriptScope m_ScriptScope; + + static ScriptHook_t g_Hook_UpdateOnRemove; + static ScriptHook_t g_Hook_ModifyEmitSoundParams; +#endif + // IClientUnknown overrides. public: @@ -337,7 +379,6 @@ class C_BaseEntity : public IClientEntity // save out interpolated values virtual void PreDataUpdate( DataUpdateType_t updateType ); virtual void PostDataUpdate( DataUpdateType_t updateType ); - virtual void OnDataUnchangedInPVS(); virtual void ValidateModelIndex( void ); @@ -359,10 +400,15 @@ class C_BaseEntity : public IClientEntity bool IsMarkedForDeletion( void ); virtual int entindex( void ) const; - + +#ifdef MAPBASE_VSCRIPT + // "I don't know why but wrapping entindex() works, while calling it directly crashes." + inline int GetEntityIndex() const { return entindex(); } +#endif + // This works for client-only entities and returns the GetEntryIndex() of the entity's handle, // so the sound system can get an IClientEntity from it. - int GetSoundSourceIndex() const; + int GetSoundSourceIndex() const; // Server to client message received virtual void ReceiveMessage( int classID, bf_read &msg ); @@ -394,7 +440,7 @@ class C_BaseEntity : public IClientEntity CParticleProperty *ParticleProp(); const CParticleProperty *ParticleProp() const; - // Simply here for game shared + // Simply here for game shared bool IsFloating(); virtual bool ShouldSavePhysics(); @@ -414,7 +460,7 @@ class C_BaseEntity : public IClientEntity int RestoreDataDescBlock( IRestore &restore, datamap_t *dmap ); // Called after restoring data into prediction slots. This function is used in place of proxies - // on the variables, so if some variable like m_nModelIndex needs to update other state (like + // on the variables, so if some variable like m_nModelIndex needs to update other state (like // the model pointer), it is done here. void OnPostRestoreData(); @@ -512,14 +558,13 @@ class C_BaseEntity : public IClientEntity const Vector& WorldAlignSize( ) const; bool IsPointSized() const; - // Returns a radius of a sphere - // *centered at the world space center* bounding the collision representation + // Returns a radius of a sphere + // *centered at the world space center* bounding the collision representation // of the entity. NOTE: The world space center *may* move when the entity rotates. float BoundingRadius() const; // Used when the collision prop is told to ask game code for the world-space surrounding box virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ); - virtual float GetHealthBarHeightOffset() const { return 0.f; } // Returns the entity-to-world transform matrix3x4_t &EntityToWorldTransform(); @@ -532,7 +577,7 @@ class C_BaseEntity : public IClientEntity // This function gets your parent's transform. If you're parented to an attachment, // this calculates the attachment's transform and gives you that. // - // You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of + // You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of // pointing you right at a variable in your parent. matrix3x4_t& GetParentToWorldTransform( matrix3x4_t &tempMatrix ); @@ -615,7 +660,7 @@ class C_BaseEntity : public IClientEntity static HSOUNDSCRIPTHANDLE PrecacheScriptSound( const char *soundname ); static void PrefetchScriptSound( const char *soundname ); - // For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from + // For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from // the recipient list. static void RemoveRecipientsIfNotCloseCaptioning( C_RecipientFilter& filter ); static void EmitCloseCaption( IRecipientFilter& filter, int entindex, char const *token, CUtlVector< Vector >& soundorigins, float duration, bool warnifmissing = false ); @@ -636,20 +681,20 @@ class C_BaseEntity : public IClientEntity void UpdatePartitionListEntry(); - // This can be used to setup the entity as a client-only entity. + // This can be used to setup the entity as a client-only entity. // Override this to perform per-entity clientside setup virtual bool InitializeAsClientEntity( const char *pszModelName, RenderGroup_t renderGroup ); - + // This function gets called on all client entities once per simulation phase. // It dispatches events like OnDataChanged(), and calls the legacy function AddEntity(). - virtual void Simulate(); + virtual void Simulate(); - // This event is triggered during the simulation phase if an entity's data has changed. It is + // This event is triggered during the simulation phase if an entity's data has changed. It is // better to hook this instead of PostDataUpdate() because in PostDataUpdate(), server entity origins // are incorrect and attachment points can't be used. virtual void OnDataChanged( DataUpdateType_t type ); @@ -660,13 +705,13 @@ class C_BaseEntity : public IClientEntity bool IsStandable() const; bool IsBSPModel() const; - + // If this is a vehicle, returns the vehicle interface virtual IClientVehicle* GetClientVehicle() { return NULL; } // Returns the aiment render origin + angles virtual void GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles ); - + // get network origin from previous update virtual const Vector& GetOldOrigin(); @@ -690,8 +735,8 @@ class C_BaseEntity : public IClientEntity virtual bool ShouldDraw(); inline bool IsVisible() const { return m_hRender != INVALID_CLIENT_RENDER_HANDLE; } - virtual void UpdateVisibility(); - + void UpdateVisibility(); + // Returns true if the entity changes its position every frame on the server but it doesn't // set animtime. In that case, the client returns true here so it copies the server time to // animtime in OnDataChanged and the position history is correct for interpolation. @@ -713,7 +758,7 @@ class C_BaseEntity : public IClientEntity void Interp_Reset( VarMapping_t *map ); virtual void ResetLatched(); - + float GetInterpolationAmount( int flags ); float GetLastChangeTime( int flags ); @@ -747,8 +792,7 @@ class C_BaseEntity : public IClientEntity virtual void SetHealth(int iHealth) {} virtual int GetHealth() const { return 0; } virtual int GetMaxHealth() const { return 1; } - virtual bool IsVisibleToTargetID( void ) const { return false; } - virtual bool IsHealthBarVisible( void ) const { return false; } + virtual bool IsVisibleToTargetID( void ) { return false; } // Returns the health fraction float HealthFraction() const; @@ -770,7 +814,7 @@ class C_BaseEntity : public IClientEntity void AddToLeafSystem(); void AddToLeafSystem( RenderGroup_t group ); // remove entity form leaf system again - void RemoveFromLeafSystem(); + void RemoveFromLeafSystem(); // A method to apply a decal to an entity virtual void AddDecal( const Vector& rayStart, const Vector& rayEnd, @@ -846,7 +890,7 @@ class C_BaseEntity : public IClientEntity } void PhysicsDispatchThink( BASEPTR thinkFunc ); - + // Toggle the visualization of the entity's abs/bbox enum { @@ -863,7 +907,8 @@ class C_BaseEntity : public IClientEntity void SetSize( const Vector &vecMin, const Vector &vecMax ); // UTIL_SetSize( pev, mins, maxs ); char const *GetClassname( void ); char const *GetDebugName( void ); - static int PrecacheModel( const char *name ); + virtual const char *GetPlayerName() const { return NULL; } + static int PrecacheModel( const char *name ); static bool PrecacheSound( const char *name ); static void PrefetchSound( const char *name ); void Remove( ); // UTIL_Remove( this ); @@ -905,7 +950,7 @@ class C_BaseEntity : public IClientEntity virtual bool IsCurrentlyTouching( void ) const; virtual void StartTouch( C_BaseEntity *pOther ); - virtual void Touch( C_BaseEntity *pOther ); + virtual void Touch( C_BaseEntity *pOther ); virtual void EndTouch( C_BaseEntity *pOther ); void (C_BaseEntity ::*m_pfnTouch)( C_BaseEntity *pOther ); @@ -989,7 +1034,7 @@ class C_BaseEntity : public IClientEntity // Unlinks from hierarchy // Set the movement parent. Your local origin and angles will become relative to this parent. - // If iAttachment is a valid attachment on the parent, then your local origin and angles + // If iAttachment is a valid attachment on the parent, then your local origin and angles // are relative to the attachment on this entity. void SetParent( C_BaseEntity *pParentEntity, int iParentAttachment=0 ); @@ -1005,10 +1050,11 @@ class C_BaseEntity : public IClientEntity ///////////////// virtual bool IsPlayer( void ) const { return false; }; + virtual bool IsBot( void ) const { return ((GetFlags() & FL_FAKECLIENT) == FL_FAKECLIENT) ? true : false; } virtual bool IsBaseCombatCharacter( void ) { return false; }; virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; } virtual bool IsNPC( void ) { return false; } - C_AI_BaseNPC *MyNPCPointer( void ); + C_AI_BaseNPC *MyNPCPointer( void ); virtual bool IsNextBot() { return false; } // TF2 specific virtual bool IsBaseObject( void ) const { return false; } @@ -1022,7 +1068,12 @@ class C_BaseEntity : public IClientEntity virtual Vector EyePosition( void ); virtual const QAngle& EyeAngles( void ); // Direction of eyes virtual const QAngle& LocalEyeAngles( void ); // Direction of eyes in local space (pl.v_angle) - + +#ifdef MAPBASE + // Created for script_intro and info_player_view_proxy + virtual void GetEyePosition( Vector &vecOrigin, QAngle &angAngles ) { vecOrigin = EyePosition(); angAngles = EyeAngles(); } +#endif + // position of ears virtual Vector EarPosition( void ); @@ -1040,7 +1091,7 @@ class C_BaseEntity : public IClientEntity void SetGravity( float flGravity ); float GetGravity( void ) const; - // Sets the model from a model index + // Sets the model from a model index void SetModelByIndex( int nModelIndex ); // Set model... (NOTE: Should only be used by client-only entities @@ -1115,10 +1166,68 @@ class C_BaseEntity : public IClientEntity bool IsFollowingEntity(); CBaseEntity *GetFollowedEntity(); +#ifdef MAPBASE_VSCRIPT + void ScriptFollowEntity( HSCRIPT hBaseEntity, bool bBoneMerge ); + HSCRIPT ScriptGetFollowedEntity(); +#endif + // For shadows rendering the correct body + sequence... virtual int GetBody() { return 0; } virtual int GetSkin() { return 0; } + const Vector& ScriptGetForward(void) { static Vector vecForward; GetVectors(&vecForward, NULL, NULL); return vecForward; } +#ifdef MAPBASE_VSCRIPT + const Vector& ScriptGetRight(void) { static Vector vecRight; GetVectors(NULL, &vecRight, NULL); return vecRight; } +#endif + const Vector& ScriptGetLeft(void) { static Vector vecRight; GetVectors(NULL, &vecRight, NULL); return vecRight; } + + const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; } + +#ifdef MAPBASE_VSCRIPT + const char* ScriptGetModelName( void ) const { return STRING(GetModelName()); } + + void ScriptStopSound(const char* soundname); + void ScriptEmitSound(const char* soundname); + float ScriptSoundDuration(const char* soundname, const char* actormodel); + + void VScriptPrecacheScriptSound(const char* soundname); + + const Vector& ScriptEyePosition(void) { static Vector vec; vec = EyePosition(); return vec; } + const QAngle& ScriptEyeAngles(void) { static QAngle ang; ang = EyeAngles(); return ang; } + void ScriptSetForward( const Vector& v ) { QAngle angles; VectorAngles( v, angles ); SetAbsAngles( angles ); } + + const Vector& ScriptGetBoundingMins( void ) { return m_Collision.OBBMins(); } + const Vector& ScriptGetBoundingMaxs( void ) { return m_Collision.OBBMaxs(); } + + HSCRIPT ScriptEntityToWorldTransform( void ); + + HSCRIPT ScriptGetPhysicsObject( void ); + + void ScriptSetParent( HSCRIPT hParent, const char *szAttachment ); + HSCRIPT ScriptGetMoveParent( void ); + HSCRIPT ScriptGetRootMoveParent(); + HSCRIPT ScriptFirstMoveChild( void ); + HSCRIPT ScriptNextMovePeer( void ); + + const Vector& ScriptGetColorVector(); + int ScriptGetColorR() { return m_clrRender.GetR(); } + int ScriptGetColorG() { return m_clrRender.GetG(); } + int ScriptGetColorB() { return m_clrRender.GetB(); } + int ScriptGetAlpha() { return m_clrRender.GetA(); } + void ScriptSetColorVector( const Vector& vecColor ); + void ScriptSetColor( int r, int g, int b ); + void ScriptSetColorR( int iVal ) { SetRenderColorR( iVal ); } + void ScriptSetColorG( int iVal ) { SetRenderColorG( iVal ); } + void ScriptSetColorB( int iVal ) { SetRenderColorB( iVal ); } + void ScriptSetAlpha( int iVal ) { SetRenderColorA( iVal ); } + + int ScriptGetRenderMode() { return GetRenderMode(); } + void ScriptSetRenderMode( int nRenderMode ) { SetRenderMode( (RenderMode_t)nRenderMode ); } + + int ScriptGetMoveType() { return GetMoveType(); } + void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); } +#endif + // Stubs on client void NetworkStateManualMode( bool activate ) { } void NetworkStateChanged() { } @@ -1134,7 +1243,7 @@ class C_BaseEntity : public IClientEntity float GetLastThink( const char *szContext = NULL ); int GetNextThinkTick( const char *szContext = NULL ); int GetLastThinkTick( const char *szContext = NULL ); - + // These set entity flags (EFL_*) to help optimize queries void CheckHasThinkFunction( bool isThinkingHint = false ); void CheckHasGamePhysicsSimulation(); @@ -1156,11 +1265,11 @@ class C_BaseEntity : public IClientEntity #ifdef _DEBUG void FunctionCheck( void *pFunction, const char *name ); - ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) - { + ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, const char *name ) + { //COMPILE_TIME_ASSERT( sizeof(func) == 4 ); - m_pfnTouch = func; - //FunctionCheck( *(reinterpret_cast(&m_pfnTouch)), name ); + m_pfnTouch = func; + //FunctionCheck( *(reinterpret_cast(&m_pfnTouch)), name ); return func; } #endif @@ -1177,17 +1286,7 @@ class C_BaseEntity : public IClientEntity // Sets the origin + angles to match the last position received void MoveToLastReceivedPosition( bool force = false ); - // Return the IHasAttributes interface for this base entity. Removes the need for: - // dynamic_cast< IHasAttributes * >( pEntity ); - // Which is remarkably slow. - // GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses - // this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast. - inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; } - protected: - // NOTE: m_pAttributes needs to be set in the leaf class constructor. - IHasAttributes *m_pAttributes; - // Only meant to be called from subclasses void DestroyModelInstance(); @@ -1227,7 +1326,7 @@ class C_BaseEntity : public IClientEntity public: // Accessors for above - static int GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime = false ); + static int GetPredictionRandomSeed( void ); static void SetPredictionRandomSeed( const CUserCmd *cmd ); static C_BasePlayer *GetPredictionPlayer( void ); static void SetPredictionPlayer( C_BasePlayer *player ); @@ -1253,10 +1352,10 @@ class C_BaseEntity : public IClientEntity static void PushEnableAbsRecomputations( bool bEnable ); static void PopEnableAbsRecomputations(); - // This requires the abs recomputation stack to be empty and just sets the global state. + // This requires the abs recomputation stack to be empty and just sets the global state. // It should only be used at the scope of the frame loop. - static void EnableAbsRecomputations( bool bEnable ); - + static void EnableAbsRecomputations( bool bEnable ); + static bool IsAbsRecomputationsEnabled( void ); @@ -1276,10 +1375,11 @@ class C_BaseEntity : public IClientEntity void SetRenderMode( RenderMode_t nRenderMode, bool bForceUpdate = false ); RenderMode_t GetRenderMode() const; -public: + const char* GetEntityName(); +public: // Determine what entity this corresponds to - int index; + int index; // Render information unsigned char m_nRenderFX; @@ -1290,8 +1390,13 @@ class C_BaseEntity : public IClientEntity CNetworkColor32( m_clrRender ); +#ifdef MAPBASE + int m_iViewHideFlags; + bool m_bDisableFlashlight; +#endif + private: - + // Model for rendering const model_t *model; @@ -1302,7 +1407,7 @@ class C_BaseEntity : public IClientEntity float m_flSimulationTime; float m_flOldSimulationTime; - + float m_flCreateTime; byte m_ubInterpolationFrame; @@ -1328,7 +1433,7 @@ class C_BaseEntity : public IClientEntity // Should we interpolate this tick? (Used to be EF_NOINTERP) bool IsNoInterpolationFrame(); - // + // int m_nNextThinkTick; int m_nLastThinkTick; @@ -1357,7 +1462,7 @@ class C_BaseEntity : public IClientEntity #endif // used so we know when things are no longer touching - int touchStamp; + int touchStamp; // Called after predicted entity has been acknowledged so that no longer needed entity can // be deleted @@ -1395,7 +1500,6 @@ class C_BaseEntity : public IClientEntity virtual bool IsDeflectable() { return false; } - bool IsCombatCharacter() { return MyCombatCharacterPointer() == NULL ? false : true; } protected: int m_nFXComputeFrame; @@ -1416,7 +1520,7 @@ class C_BaseEntity : public IClientEntity protected: // pointer to the entity's physics object (vphysics.dll) - IPhysicsObject *m_pPhysicsObject; + IPhysicsObject *m_pPhysicsObject; #if !defined( NO_ENTITY_PREDICTION ) bool m_bPredictionEligible; @@ -1429,12 +1533,21 @@ class C_BaseEntity : public IClientEntity CUtlVector< thinkfunc_t > m_aThinkFunctions; int m_iCurrentThinkContext; +#ifdef MAPBASE_VSCRIPT +public: + void ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float time ); + void ScriptContextThink(); +private: + CUtlVector< scriptthinkfunc_t* > m_ScriptThinkFuncs; +public: +#endif + // Object eye position Vector m_vecViewOffset; #if defined(SIXENSE) Vector m_vecEyeOffset; - QAngle m_EyeAngleOffset; + QAngle m_EyeAngleOffset; #endif // Allow studio models to tell us what their m_nBody value is virtual int GetStudioBody( void ) { return 0; } @@ -1444,15 +1557,13 @@ class C_BaseEntity : public IClientEntity // a render handle, and is put into the spatial partition. bool InitializeAsClientEntityByIndex( int iIndex, RenderGroup_t renderGroup ); - void TrackAngRotation( bool bTrack ); - private: friend void OnRenderStart(); // Figure out the smoothly interpolated origin for all server entities. Happens right before // letting all entities simulate. static void InterpolateServerEntities(); - + // Check which entities want to be drawn and add them to the leaf system. static void AddVisibleEntities(); @@ -1506,7 +1617,7 @@ class C_BaseEntity : public IClientEntity // FIXME: REMOVE!!! void MoveToAimEnt( ); - + // Sets/Gets the next think based on context index void SetNextThink( int nContextIndex, float thinkTime ); void SetLastThink( int nContextIndex, float thinkTime ); @@ -1540,7 +1651,7 @@ class C_BaseEntity : public IClientEntity // Base velocity Vector m_vecBaseVelocity; - + // Gravity multiplier float m_flGravity; @@ -1598,7 +1709,7 @@ class C_BaseEntity : public IClientEntity // Friction. - float m_flFriction; + float m_flFriction; Vector m_vecAbsOrigin; @@ -1657,7 +1768,9 @@ class C_BaseEntity : public IClientEntity // The owner! EHANDLE m_hOwnerEntity; EHANDLE m_hEffectEntity; - + + char m_iName[MAX_PATH]; + // This is a random seed used by the networking code to allow client - side prediction code // randon number generators to spit out the same random numbers on both sides for a particular // usercmd input. @@ -1667,13 +1780,13 @@ class C_BaseEntity : public IClientEntity static bool s_bAbsRecomputationEnabled; static bool s_bInterpolate; - + int m_fDataObjectTypes; AimEntsListHandle_t m_AimEntsListHandle; int m_nCreationTick; - + public: float m_fRenderingClipPlane[4]; //world space clip plane when drawing bool m_bEnableRenderingClipPlane; //true to use the custom clip plane when drawing @@ -1684,7 +1797,7 @@ class C_BaseEntity : public IClientEntity void AddToInterpolationList(); void RemoveFromInterpolationList(); unsigned short m_InterpolationListEntry; // Entry into g_InterpolationList (or g_InterpolationList.InvalidIndex if not in the list). - + void AddToTeleportList(); void RemoveFromTeleportList(); unsigned short m_TeleportListEntry; @@ -1710,12 +1823,12 @@ class C_BaseEntity : public IClientEntity EXTERN_RECV_TABLE(DT_BaseEntity); inline bool FClassnameIs( C_BaseEntity *pEntity, const char *szClassname ) -{ +{ Assert( pEntity ); if ( pEntity == NULL ) return false; - return !strcmp( pEntity->GetClassname(), szClassname ) ? true : false; + return !strcmp( pEntity->GetClassname(), szClassname ) ? true : false; } #define SetThink( a ) ThinkSet( static_cast (a), 0, NULL ) @@ -1768,17 +1881,17 @@ inline bool C_BaseEntity::IsServerEntity( void ) // Inline methods //----------------------------------------------------------------------------- inline matrix3x4_t &C_BaseEntity::EntityToWorldTransform() -{ +{ Assert( s_bAbsQueriesValid ); CalcAbsolutePosition(); - return m_rgflCoordinateFrame; + return m_rgflCoordinateFrame; } inline const matrix3x4_t &C_BaseEntity::EntityToWorldTransform() const { Assert( s_bAbsQueriesValid ); const_cast(this)->CalcAbsolutePosition(); - return m_rgflCoordinateFrame; + return m_rgflCoordinateFrame; } inline const Vector& C_BaseEntity::GetNetworkOrigin() const @@ -1946,25 +2059,25 @@ inline bool CBaseEntity::IsPointSized() const //----------------------------------------------------------------------------- inline C_BaseEntity *C_BaseEntity::GetMoveParent( void ) const { - return m_pMoveParent; + return m_pMoveParent; } inline C_BaseEntity *C_BaseEntity::FirstMoveChild( void ) const { - return m_pMoveChild; + return m_pMoveChild; } inline C_BaseEntity *C_BaseEntity::NextMovePeer( void ) const { - return m_pMovePeer; + return m_pMovePeer; } //----------------------------------------------------------------------------- // Velocity //----------------------------------------------------------------------------- -inline const Vector& C_BaseEntity::GetLocalVelocity() const -{ - return m_vecVelocity; +inline const Vector& C_BaseEntity::GetLocalVelocity() const +{ + return m_vecVelocity; } inline const QAngle& C_BaseEntity::GetLocalAngularVelocity( ) const @@ -1972,29 +2085,29 @@ inline const QAngle& C_BaseEntity::GetLocalAngularVelocity( ) const return m_vecAngVelocity; } -inline const Vector& C_BaseEntity::GetBaseVelocity() const -{ - return m_vecBaseVelocity; +inline const Vector& C_BaseEntity::GetBaseVelocity() const +{ + return m_vecBaseVelocity; } -inline void C_BaseEntity::SetBaseVelocity( const Vector& v ) -{ - m_vecBaseVelocity = v; +inline void C_BaseEntity::SetBaseVelocity( const Vector& v ) +{ + m_vecBaseVelocity = v; } -inline void C_BaseEntity::SetFriction( float flFriction ) -{ - m_flFriction = flFriction; +inline void C_BaseEntity::SetFriction( float flFriction ) +{ + m_flFriction = flFriction; } -inline void C_BaseEntity::SetGravity( float flGravity ) -{ - m_flGravity = flGravity; +inline void C_BaseEntity::SetGravity( float flGravity ) +{ + m_flGravity = flGravity; } -inline float C_BaseEntity::GetGravity( void ) const -{ - return m_flGravity; +inline float C_BaseEntity::GetGravity( void ) const +{ + return m_flGravity; } inline int C_BaseEntity::GetWaterLevel() const @@ -2007,9 +2120,9 @@ inline void C_BaseEntity::SetWaterLevel( int nLevel ) m_nWaterLevel = nLevel; } -inline float C_BaseEntity::GetElasticity( void ) const -{ - return m_flElasticity; +inline float C_BaseEntity::GetElasticity( void ) const +{ + return m_flElasticity; } inline const color32 CBaseEntity::GetRenderColor() const @@ -2057,9 +2170,9 @@ inline RenderMode_t CBaseEntity::GetRenderMode() const //----------------------------------------------------------------------------- // checks to see if the entity is marked for deletion //----------------------------------------------------------------------------- -inline bool C_BaseEntity::IsMarkedForDeletion( void ) -{ - return (m_iEFlags & EFL_KILLME); +inline bool C_BaseEntity::IsMarkedForDeletion( void ) +{ + return (m_iEFlags & EFL_KILLME); } inline void C_BaseEntity::AddEFlags( int nEFlagMask ) @@ -2082,9 +2195,9 @@ inline unsigned char CBaseEntity::GetParentAttachment() const return m_iParentAttachment; } -inline ClientRenderHandle_t CBaseEntity::GetRenderHandle() const -{ - return m_hRender; +inline ClientRenderHandle_t CBaseEntity::GetRenderHandle() const +{ + return m_hRender; } inline ClientRenderHandle_t& CBaseEntity::RenderHandle() @@ -2094,24 +2207,24 @@ inline ClientRenderHandle_t& CBaseEntity::RenderHandle() #ifdef SIXENSE -inline const Vector& CBaseEntity::GetEyeOffset() const -{ - return m_vecEyeOffset; +inline const Vector& CBaseEntity::GetEyeOffset() const +{ + return m_vecEyeOffset; } -inline void CBaseEntity::SetEyeOffset( const Vector& v ) -{ - m_vecEyeOffset = v; +inline void CBaseEntity::SetEyeOffset( const Vector& v ) +{ + m_vecEyeOffset = v; } -inline const QAngle & CBaseEntity::GetEyeAngleOffset() const -{ - return m_EyeAngleOffset; +inline const QAngle & CBaseEntity::GetEyeAngleOffset() const +{ + return m_EyeAngleOffset; } -inline void CBaseEntity::SetEyeAngleOffset( const QAngle & qa ) -{ - m_EyeAngleOffset = qa; +inline void CBaseEntity::SetEyeAngleOffset( const QAngle & qa ) +{ + m_EyeAngleOffset = qa; } #endif @@ -2161,8 +2274,8 @@ inline bool C_BaseEntity::IsNoInterpolationFrame() } //----------------------------------------------------------------------------- -// Purpose: -// Input : handle - +// Purpose: +// Input : handle - // Output : inline void //----------------------------------------------------------------------------- inline void C_BaseEntity::SetToolHandle( HTOOLHANDLE handle ) @@ -2173,8 +2286,8 @@ inline void C_BaseEntity::SetToolHandle( HTOOLHANDLE handle ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : inline HTOOLHANDLE //----------------------------------------------------------------------------- inline HTOOLHANDLE C_BaseEntity::GetToolHandle() const @@ -2187,7 +2300,7 @@ inline HTOOLHANDLE C_BaseEntity::GetToolHandle() const } //----------------------------------------------------------------------------- -// +// //----------------------------------------------------------------------------- inline bool C_BaseEntity::IsEnabledInToolView() const { @@ -2199,8 +2312,8 @@ inline bool C_BaseEntity::IsEnabledInToolView() const } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : inline bool //----------------------------------------------------------------------------- inline bool C_BaseEntity::ShouldRecordInTools() const @@ -2212,6 +2325,12 @@ inline bool C_BaseEntity::ShouldRecordInTools() const #endif } +inline const char *C_BaseEntity::GetEntityName() +{ + return m_iName; +} + + C_BaseEntity *CreateEntityByName( const char *className ); #endif // C_BASEENTITY_H diff --git a/game/client/c_baseflex.cpp b/game/client/c_baseflex.cpp index 7e6c4bfc..6d0193cc 100644 --- a/game/client/c_baseflex.cpp +++ b/game/client/c_baseflex.cpp @@ -562,11 +562,11 @@ Vector C_BaseFlex::SetViewTarget( CStudioHdr *pStudioHdr ) m_iEyeUpdown = FindFlexController( "eyes_updown" ); m_iEyeRightleft = FindFlexController( "eyes_rightleft" ); - if ( m_iEyeUpdown != LocalFlexController_t(-1) ) + if ( m_iEyeUpdown != -1 ) { pStudioHdr->pFlexcontroller( m_iEyeUpdown )->localToGlobal = AddGlobalFlexController( "eyes_updown" ); } - if ( m_iEyeRightleft != LocalFlexController_t(-1) ) + if ( m_iEyeRightleft != -1 ) { pStudioHdr->pFlexcontroller( m_iEyeRightleft )->localToGlobal = AddGlobalFlexController( "eyes_rightleft" ); } @@ -594,13 +594,13 @@ Vector C_BaseFlex::SetViewTarget( CStudioHdr *pStudioHdr ) // calculate animated eye deflection Vector eyeDeflect; QAngle eyeAng( 0, 0, 0 ); - if ( m_iEyeUpdown != LocalFlexController_t(-1) ) + if ( m_iEyeUpdown != -1 ) { mstudioflexcontroller_t *pflex = pStudioHdr->pFlexcontroller( m_iEyeUpdown ); eyeAng.x = g_flexweight[ pflex->localToGlobal ]; } - if ( m_iEyeRightleft != LocalFlexController_t(-1) ) + if ( m_iEyeRightleft != -1 ) { mstudioflexcontroller_t *pflex = pStudioHdr->pFlexcontroller( m_iEyeRightleft ); eyeAng.y = g_flexweight[ pflex->localToGlobal ]; @@ -1057,7 +1057,7 @@ void C_BaseFlex::GetToolRecordingState( KeyValues *msg ) Vector viewtarget = m_viewtarget; // Use the unfiltered value // HACK HACK: Unmap eyes right/left amounts - if (m_iEyeUpdown != LocalFlexController_t(-1) && m_iEyeRightleft != LocalFlexController_t(-1)) + if (m_iEyeUpdown != -1 && m_iEyeRightleft != -1) { mstudioflexcontroller_t *flexupdown = hdr->pFlexcontroller( m_iEyeUpdown ); mstudioflexcontroller_t *flexrightleft = hdr->pFlexcontroller( m_iEyeRightleft ); @@ -1149,7 +1149,9 @@ void C_BaseFlex::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightC { // hack in an initialization LinkToGlobalFlexControllers( GetModelPtr() ); +#ifndef MAPBASE m_iBlink = AddGlobalFlexController( "UH" ); +#endif if ( SetupGlobalWeights( pBoneToWorld, nFlexWeightCount, pFlexWeights, pFlexDelayedWeights ) ) { @@ -1478,7 +1480,7 @@ bool C_BaseFlex::ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool can // expression - // duration - //----------------------------------------------------------------------------- -void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget, bool bClientSide ) +void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget, bool bClientSide, C_SceneEntity* pSceneEntity) { if ( !scene || !event ) { @@ -1503,6 +1505,7 @@ void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseE info.m_hTarget = pTarget; info.m_bStarted = false; info.m_bClientSide = bClientSide; + info.m_hSceneEntity = pSceneEntity; if (StartSceneEvent( &info, scene, event, actor, pTarget )) { diff --git a/game/client/c_baseflex.h b/game/client/c_baseflex.h index 71cee3d8..6d9f1b54 100644 --- a/game/client/c_baseflex.h +++ b/game/client/c_baseflex.h @@ -214,7 +214,7 @@ class C_BaseFlex : public C_BaseAnimatingOverlay, public IHasLocalToGlobalFlexSe 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 ); + void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false, C_SceneEntity* pSceneEntity = NULL); // Remove the event from the queue for this actor void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill ); diff --git a/game/client/c_baselesson.cpp b/game/client/c_baselesson.cpp new file mode 100644 index 00000000..ec01575b --- /dev/null +++ b/game/client/c_baselesson.cpp @@ -0,0 +1,3895 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Purpose: Client handler implementations for instruction players how to play +// +//=============================================================================// + +#include "cbase.h" + +#include "c_baselesson.h" +#include "c_gameinstructor.h" + +#include "hud_locator_target.h" +#include "c_world.h" +#include "iinput.h" +#include "ammodef.h" +#include "vprof.h" +#include "view.h" +#include "vstdlib/IKeyValuesSystem.h" +#ifdef MAPBASE +#include "usermessages.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//========================================================= +// Configuracin +//========================================================= + +#define LESSON_PRIORITY_MAX 1000 +#define LESSON_PRIORITY_NONE 0 +#define LESSON_MIN_TIME_ON_SCREEN_TO_MARK_DISPLAYED 1.5f +#define LESSON_MIN_TIME_BEFORE_LOCK_ALLOWED 0.1f +#define LESSON_DISTANCE_UPDATE_RATE 0.25f + +// See comments in UtlSymbol on why this is useful and how it works +IMPLEMENT_PRIVATE_SYMBOLTYPE( CGameInstructorSymbol ); + +extern ConVar gameinstructor_verbose; +extern ConVar gameinstructor_verbose_lesson; +extern ConVar gameinstructor_find_errors; + +#ifdef MAPBASE +// Mapbase was originally going to use a HL2-style default color (245,232,179). +// This is no longer the case, but mods are free to change this cvar in their config files. +ConVar gameinstructor_default_captioncolor( "gameinstructor_default_captioncolor", "255,255,255", FCVAR_NONE ); +ConVar gameinstructor_default_bindingcolor( "gameinstructor_default_bindingcolor", "0,0,0", FCVAR_NONE ); +#endif + +// +// CGameInstructorLesson +// + +Color CBaseLesson::m_rgbaVerboseHeader = Color( 255, 128, 64, 255 ); +Color CBaseLesson::m_rgbaVerbosePlain = Color( 64, 128, 255, 255 ); +Color CBaseLesson::m_rgbaVerboseName = Color( 255, 255, 255, 255 ); +Color CBaseLesson::m_rgbaVerboseOpen = Color( 0, 255, 0, 255 ); +Color CBaseLesson::m_rgbaVerboseClose = Color( 255, 0, 0, 255 ); +Color CBaseLesson::m_rgbaVerboseSuccess = Color( 255, 255, 0, 255 ); +Color CBaseLesson::m_rgbaVerboseUpdate = Color( 255, 0, 255, 255 ); + + +//========================================================= +// Constructor +//========================================================= +CBaseLesson::CBaseLesson( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity ) +{ + COMPILE_TIME_ASSERT( sizeof( CGameInstructorSymbol ) == sizeof( CUtlSymbol ) ); + + m_stringName = pchName; + m_stringReplaceKey = ""; + m_bIsDefaultHolder = bIsDefaultHolder; + m_bIsOpenOpportunity = bIsOpenOpportunity; + + Init(); +} + +//========================================================= +// Destructor +//========================================================= +CBaseLesson::~CBaseLesson() +{ + // Remove from root's children list + if ( m_pRoot ) + m_pRoot->m_OpenOpportunities.FindAndRemove(this); + + else + { + for ( int i = 0; i < m_OpenOpportunities.Count(); ++i ) + { + // Remove from children if they are still around + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + pLesson->m_pRoot = NULL; + } + } +} + +//========================================================= +//========================================================= +void CBaseLesson::AddPrerequisite( const char *pchLessonName ) +{ + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "\t%s: ", GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Adding prereq " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", pchLessonName ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + + const CBaseLesson *pPrerequisite = GetGameInstructor().GetLesson( pchLessonName ); + + if ( !pPrerequisite ) + { + DevWarning( "Prerequisite %s added by lesson %s doesn't exist!\n", pchLessonName, GetName() ); + return; + } + + m_Prerequisites.AddToTail(pPrerequisite); +} + +//========================================================= +//========================================================= +void CBaseLesson::SetRoot( CBaseLesson *pRoot ) +{ + m_pRoot = pRoot; + + if ( m_pRoot->m_OpenOpportunities.Find( this ) == -1 ) + m_pRoot->m_OpenOpportunities.AddToTail( this ); +} + +//========================================================= +//========================================================= +bool CBaseLesson::ShouldShowSpew() +{ + // @DEBUG + return true; + + if ( gameinstructor_verbose_lesson.GetString()[ 0 ] == '\0' ) + return false; + + return ( Q_stristr( GetName(), gameinstructor_verbose_lesson.GetString() ) != NULL ); +} + +//========================================================= +//========================================================= +bool CBaseLesson::NoPriority() const +{ + return ( m_iPriority == LESSON_PRIORITY_NONE ); +} + +//========================================================= +//========================================================= +bool CBaseLesson::IsLocked() const +{ + if ( m_fLockDuration == 0.0f ) + return false; + + if ( !IsInstructing() || !IsVisible() ) + return false; + + float fLockTime = m_fLockTime; + + if ( fLockTime == 0.0f ) + fLockTime = m_fStartTime; + + return ( gpGlobals->curtime > m_fStartTime + LESSON_MIN_TIME_BEFORE_LOCK_ALLOWED && gpGlobals->curtime < fLockTime + m_fLockDuration ); +} + +//========================================================= +//========================================================= +bool CBaseLesson::IsLearned() const +{ + if ( m_iDisplayLimit > 0 && m_iDisplayCount >= m_iDisplayLimit ) + return true; + + if ( m_iSuccessLimit > 0 && m_iSuccessCount >= m_iSuccessLimit ) + return true; + + return false; +} + +//========================================================= +//========================================================= +bool CBaseLesson::PrerequisitesHaveBeenMet() const +{ + for ( int i = 0; i < m_Prerequisites.Count(); ++i ) + { + if ( !m_Prerequisites[ i ]->IsLearned() ) + { + // Failed a prereq + return false; + } + } + + // All prereqs passed + return true; +} + +//========================================================= +//========================================================= +bool CBaseLesson::IsTimedOut() +{ + VPROF_BUDGET( "CBaseLesson::IsTimedOut", "GameInstructor" ); + + // Check for no timeout + if ( m_fTimeout == 0.0f ) + return false; + + float fStartTime = m_fStartTime; + + if ( GetRoot()->IsLearned() ) + { + if ( !m_bBumpWithTimeoutWhenLearned ) + { + // Time out instantly if we've learned this and don't want to keep it open for priority bumping + return true; + } + else + { + // It'll never be active, so lets use timeout based on when it was initialized + fStartTime = m_fInitTime; + } + } + + if ( !fStartTime ) + { + if ( !m_bCanTimeoutWhileInactive ) + { + return false; + } + + // Not active, so lets use timeout based on when it was initialized + fStartTime = m_fInitTime; + } + + bool bTimedOut = ( fStartTime + m_fTimeout < gpGlobals->curtime ); + + if ( bTimedOut ) + SetCloseReason( "Timed out." ); + + return bTimedOut; +} + +//========================================================= +//========================================================= +void CBaseLesson::ResetDisplaysAndSuccesses() +{ + m_iDisplayCount = 0; + m_bSuccessCounted = false; + m_iSuccessCount = 0; +} + +//========================================================= +//========================================================= +bool CBaseLesson::IncDisplayCount() +{ + if ( m_iDisplayCount < m_iDisplayLimit ) + { + m_iDisplayCount++; + return true; + } + + return false; +} + +//========================================================= +//========================================================= +bool CBaseLesson::IncSuccessCount() +{ + if ( m_iSuccessCount < m_iSuccessLimit ) + { + m_iSuccessCount++; + return true; + } + + return false; +} + +//========================================================= +//========================================================= +void CBaseLesson::Init() +{ + m_pRoot = NULL; + m_bSuccessCounted = false; + + SetCloseReason( "None given." ); + + m_iPriority = LESSON_PRIORITY_MAX; // Set to invalid value to ensure that it is actually set later on + m_iInstanceType = LESSON_INSTANCE_MULTIPLE; + m_iFixedInstancesMax = 1; + m_bReplaceOnlyWhenStopped = false; + m_iTeam = TEAM_ANY; + m_bOnlyKeyboard = false; + m_bOnlyGamepad = false; + + m_iDisplayLimit = 0; + m_iDisplayCount = 0; + m_bWasDisplayed = false; + + m_iSuccessLimit = 0; + m_iSuccessCount = 0; + + m_fLockDuration = 0.0f; + m_bCanOpenWhenDead = false; + m_bBumpWithTimeoutWhenLearned = false; + m_bCanTimeoutWhileInactive = false; + m_fTimeout = 0.0f; + + m_fInitTime = gpGlobals->curtime; + m_fStartTime = 0.0f; + m_fLockTime = 0.0f; + + m_fUpdateInterval = 0.5; + m_bHasPlayedSound = false; + + m_szStartSound = "Instructor.LessonStart"; + m_szLessonGroup = ""; + + m_iNumDelayedPlayerSwaps = 0; +} + +//========================================================= +//========================================================= +void CBaseLesson::TakePlaceOf( CBaseLesson *pLesson ) +{ + // Transfer over marked as displayed so a replaced lesson won't count as an extra display + m_bWasDisplayed = pLesson->m_bWasDisplayed; + pLesson->m_bWasDisplayed = false; +} + +//========================================================= +//========================================================= +void CBaseLesson::MarkSucceeded() +{ + if ( !m_bSuccessCounted ) + { + GetGameInstructor().MarkSucceeded( GetName() ); + m_bSuccessCounted = true; + } +} + +//========================================================= +//========================================================= +void CBaseLesson::CloseOpportunity( const char *pchReason ) +{ + SetCloseReason(pchReason); + m_bIsOpenOpportunity = false; +} + +//========================================================= +//========================================================= +bool CBaseLesson::DoDelayedPlayerSwaps() const +{ + // A bot has swapped places with a player or player with a bot... + // At the time of the actual swap there was no client representation for the new player... + // So that swap was queued up and now we're going to make things right! + while ( m_iNumDelayedPlayerSwaps ) + { + C_BasePlayer *pNewPlayer = UTIL_PlayerByUserId( m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps - 1 ].iNewUserID ); + + if ( !pNewPlayer ) + { + // There is still no client representation of the new player, we'll have to try again later + if ( gameinstructor_verbose.GetInt() > 1 ) + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tFailed delayed player swap!" ); + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 1 ) + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tSuccessful delayed player swap!" ); + + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps - 1 ].phHandleToChange->Set( pNewPlayer ); + m_iNumDelayedPlayerSwaps--; + } + + return true; +} + + +// +// CTextLesson +// + +//========================================================= +//========================================================= +void CTextLesson::Init() +{ + m_szDisplayText = ""; + m_szDisplayParamText = ""; + m_szBinding = ""; + m_szGamepadBinding = ""; +} + +//========================================================= +//========================================================= +void CTextLesson::Start() +{ + // TODO: Display some text + //m_szDisplayText +} + +//========================================================= +//========================================================= +void CTextLesson::Stop() +{ + // TODO: Clean up text +} + +// +// CIconLesson +// + +void CIconLesson::Init() +{ + m_hIconTarget = NULL; + m_szVguiTargetName = ""; + m_szVguiTargetLookup = ""; + m_nVguiTargetEdge = 0; + + m_hLocatorTarget = -1; + m_bFixedPosition = false; + m_bNoIconTarget = false; + m_bAllowNodrawTarget = false; + + m_bVisible = true; + m_bShowWhenOccluded = true; + m_bNoOffscreen = false; + m_bForceCaption = false; + + m_szOnscreenIcon = ""; + m_szOffscreenIcon = ""; + + m_flUpOffset = 0.0f; + m_flRelativeUpOffset = 0.0f; + m_fFixedPositionX = 0.0f; + m_fFixedPositionY = 0.0f; + + m_fRange = 0.0f; + m_fCurrentDistance = 0.0f; + + m_fOnScreenStartTime = 0.0f; + m_fUpdateDistanceTime = 0.0f; + + m_iFlags = LOCATOR_ICON_FX_NONE; +#ifdef MAPBASE + m_szCaptionColor = gameinstructor_default_captioncolor.GetString(); + + m_iIconTargetPos = ICON_TARGET_EYE_POSITION; + m_szHudHint = ""; +#else + m_szCaptionColor = "255,255,255";// Default to white +#endif +} + +//========================================================= +//========================================================= +void CIconLesson::Start() +{ + if ( !DoDelayedPlayerSwaps() ) + return; + + // Display some text + C_BaseEntity *pIconTarget = m_hIconTarget.Get(); + + if ( !pIconTarget ) + { + if ( !m_bNoIconTarget ) + { + // Wanted one, but couldn't get it + CloseOpportunity( "Icon Target handle went invalid before the lesson started!" ); + } + + return; + } + else + { + if ( ( pIconTarget->IsEffectActive( EF_NODRAW ) || pIconTarget->IsDormant() ) && !m_bAllowNodrawTarget ) + { + // We don't allow no draw entities + CloseOpportunity( "Icon Target is using effect NODRAW and allow_nodraw_target is false!" ); + return; + } + } + + CLocatorTarget *pLocatorTarget = NULL; + + if ( m_hLocatorTarget != -1 ) + { + // Lets try the handle that we've held on to + pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + + if ( !pLocatorTarget ) + { + // It's gone stale, get a new target + m_hLocatorTarget = Locator_AddTarget(); + pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + } + } + else + { + // Get a new target + m_hLocatorTarget = Locator_AddTarget(); + pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + } + + if( m_hLocatorTarget == -1 || !pLocatorTarget ) + { + CloseOpportunity( "Could not get a handle for new locator target. Too many targets in use!" ); + return; + } + + pLocatorTarget->AddIconEffects( m_iFlags ); + pLocatorTarget->SetCaptionColor( GetCaptionColorString() ); + UpdateLocatorTarget( pLocatorTarget, pIconTarget ); + + // Update occlusion data + Locator_ComputeTargetIconPositionFromHandle( m_hLocatorTarget ); +} + +//========================================================= +//========================================================= +void CIconLesson::Stop() +{ + if ( !DoDelayedPlayerSwaps() ) + return; + + if ( m_hLocatorTarget != -1 ) + Locator_RemoveTarget( m_hLocatorTarget ); + + m_fOnScreenStartTime = 0.0f; +} + +//========================================================= +//========================================================= +void CIconLesson::Update() +{ + if ( !DoDelayedPlayerSwaps() ) + return; + + C_BaseEntity *pIconTarget = m_hIconTarget.Get(); + + if ( !pIconTarget ) + { + if ( !m_bNoIconTarget ) + { + CloseOpportunity( "Lost our icon target handle returned NULL." ); + } + + return; + } + else + { + if ( ( pIconTarget->IsEffectActive( EF_NODRAW ) || pIconTarget->IsDormant() ) && !m_bAllowNodrawTarget ) + { + // We don't allow no draw entities + CloseOpportunity( "Icon Target is using effect NODRAW and allow_nodraw_target is false!" ); + return; + } + } + + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + if ( !pLocatorTarget ) + { + // Temp instrumentation to catch a bug - possibly calling Update without having called Start? + Warning( "Problem in lesson %s: Locator_GetTargetFromHandle returned null for handle %d.\n IsInstanceActive: %s. IsInstructing: %s. IsLearned: %s\n", + GetName(), m_hLocatorTarget, + (IsInstanceActive() ? "yes" : "no"), + (IsInstructing() ? "yes" : "no"), + (IsLearned() ? "yes" : "no") ); + CloseOpportunity( "Lost locator target handle." ); + return; + } + + UpdateLocatorTarget( pLocatorTarget, pIconTarget ); + C_BasePlayer *pLocalPlayer = GetGameInstructor().GetLocalPlayer(); + + // Check if it has been onscreen long enough to count as being displayed + if ( m_fOnScreenStartTime == 0.0f ) + { + if ( pLocatorTarget->IsOnScreen() && ( IsPresentComplete() || ( pLocatorTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_STATIC ) ) ) + { + // Is either static or has finished presenting and is on screen + m_fOnScreenStartTime = gpGlobals->curtime; + } + } + else + { + if ( !pLocatorTarget->IsOnScreen() ) + { + // Was visible before, but it isn't now + m_fOnScreenStartTime = 0.0f; + } + else if ( gpGlobals->curtime - m_fOnScreenStartTime >= LESSON_MIN_TIME_ON_SCREEN_TO_MARK_DISPLAYED ) + { + // Lesson on screen long enough to be counted as displayed + m_bWasDisplayed = true; + } + } + + if ( m_fUpdateDistanceTime < gpGlobals->curtime ) + { + // Update it's distance from the local player + C_BaseEntity *pTarget = m_hIconTarget.Get(); + + if ( !pLocalPlayer || !pTarget || pLocalPlayer == pTarget ) + { + m_fCurrentDistance = 0.0f; + } + else + { + m_fCurrentDistance = pLocalPlayer->EyePosition().DistTo( pTarget->WorldSpaceCenter() ); + } + + m_fUpdateDistanceTime = gpGlobals->curtime + LESSON_DISTANCE_UPDATE_RATE; + } +} + +void CIconLesson::UpdateInactive() +{ + if ( m_fUpdateDistanceTime < gpGlobals->curtime ) + { + if ( !DoDelayedPlayerSwaps() ) + { + return; + } + + C_BaseEntity *pIconTarget = m_hIconTarget.Get(); + + if ( !pIconTarget ) + { + if ( !m_bNoIconTarget ) + { + CloseOpportunity( "Lost our icon target handle returned NULL." ); + } + + m_fCurrentDistance = 0.0f; + return; + } + else + { + if ( ( pIconTarget->IsEffectActive( EF_NODRAW ) || pIconTarget->IsDormant() ) && !m_bAllowNodrawTarget ) + { + // We don't allow no draw entities + CloseOpportunity( "Icon Target is using effect NODRAW and allow_nodraw_target is false!" ); + return; + } + } + + // Update it's distance from the local player + C_BasePlayer *pLocalPlayer = GetGameInstructor().GetLocalPlayer(); + + if ( !pLocalPlayer || pLocalPlayer == pIconTarget ) + { + m_fCurrentDistance = 0.0f; + } + else + { + m_fCurrentDistance = pLocalPlayer->EyePosition().DistTo( pIconTarget->WorldSpaceCenter() ); + } + +#ifdef MAPBASE + if (m_szHudHint.String()[0] != '\0' && GetRoot()->IsLearned()) + { + DevMsg("Showing hint\n"); + CUtlBuffer msg_data; + msg_data.PutChar( 1 ); + msg_data.PutString( m_szHudHint.String() ); + bf_read msg( msg_data.Base(), msg_data.TellPut() ); + usermessages->DispatchUserMessage( usermessages->LookupUserMessage( "KeyHintText" ), msg ); + } +#endif + + m_fUpdateDistanceTime = gpGlobals->curtime + LESSON_DISTANCE_UPDATE_RATE; + } +} + +bool CIconLesson::ShouldDisplay() const +{ + VPROF_BUDGET( "CIconLesson::ShouldDisplay", "GameInstructor" ); + + if ( !DoDelayedPlayerSwaps() ) + { + return false; + } + + if ( m_fRange > 0.0f && m_fCurrentDistance > m_fRange ) + { + // Distance to target is more than the max range + return false; + } + + if ( !m_bShowWhenOccluded && m_hLocatorTarget >= 0 ) + { + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + + if ( pLocatorTarget && pLocatorTarget->IsOccluded() ) + { + // Target is occluded and doesn't want to be shown when occluded + return false; + } + } + + // Ok to display + return true; +} + +bool CIconLesson::IsVisible() const +{ + VPROF_BUDGET( "CIconLesson::IsVisible", "GameInstructor" ); + + if( m_hLocatorTarget == -1 ) + { + // If it doesn't want a target, it's "visible" otherwise we'll have to call it invisible + return m_bNoIconTarget; + } + + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + if ( !pLocatorTarget ) + { + return false; + } + + return pLocatorTarget->IsVisible(); +} + +void CIconLesson::SwapOutPlayers( int iOldUserID, int iNewUserID ) +{ + BaseClass::SwapOutPlayers( iOldUserID, iNewUserID ); + + if ( m_bNoIconTarget ) + return; + + // Get the player pointers from the user IDs + C_BasePlayer *pOldPlayer = UTIL_PlayerByUserId( iOldUserID ); + C_BasePlayer *pNewPlayer = UTIL_PlayerByUserId( iNewUserID ); + + if ( pOldPlayer == m_hIconTarget.Get() ) + { + if ( pNewPlayer ) + { + m_hIconTarget = pNewPlayer; + } + else + { + if ( m_iNumDelayedPlayerSwaps < MAX_DELAYED_PLAYER_SWAPS ) + { + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].phHandleToChange = &m_hIconTarget; + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].iNewUserID = iNewUserID; + ++m_iNumDelayedPlayerSwaps; + } + } + } +} + +void CIconLesson::TakePlaceOf( CBaseLesson *pLesson ) +{ + BaseClass::TakePlaceOf( pLesson ); + + const CIconLesson *pIconLesson = dynamic_cast( pLesson ); + + if ( pIconLesson ) + { + if ( pIconLesson->m_hLocatorTarget != -1 ) + { + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( pIconLesson->m_hLocatorTarget ); + + if ( pLocatorTarget ) + { + // This one draw right to the hud... use it's icon target handle + m_hLocatorTarget = pIconLesson->m_hLocatorTarget; + } + } + + m_fOnScreenStartTime = pIconLesson->m_fOnScreenStartTime; + } +} + +void CIconLesson::SetLocatorBinding( CLocatorTarget * pLocatorTarget ) +{ + if ( IsX360() /*|| input->ControllerModeActive()*/ ) + { + // Try to use gamepad bindings first + if ( m_szGamepadBinding.String()[ 0 ] != '\0' ) + { + // Found gamepad binds! + pLocatorTarget->SetBinding( m_szGamepadBinding.String() ); + } + else + { + // No gamepad binding, so fallback to the regular binding + pLocatorTarget->SetBinding( m_szBinding.String() ); + } + } + else + { + // Always use the regular binding when the gamepad is disabled + pLocatorTarget->SetBinding( m_szBinding.String() ); + } +} + +bool CIconLesson::IsPresentComplete() +{ + if ( m_hLocatorTarget == -1 ) + return false; + + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + + if ( !pLocatorTarget ) + return false; + + return !pLocatorTarget->IsPresenting(); +} + +void CIconLesson::PresentStart() +{ + if ( m_hLocatorTarget == -1 ) + return; + + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + + if ( !pLocatorTarget ) + return; + + pLocatorTarget->StartPresent(); +} + +void CIconLesson::PresentEnd() +{ + if ( m_hLocatorTarget == -1 ) + return; + + CLocatorTarget *pLocatorTarget = Locator_GetTargetFromHandle( m_hLocatorTarget ); + + if ( !pLocatorTarget ) + return; + + pLocatorTarget->EndPresent(); +} + +void CIconLesson::UpdateLocatorTarget( CLocatorTarget *pLocatorTarget, C_BaseEntity *pIconTarget ) +{ + if ( m_bFixedPosition ) + { + pLocatorTarget->m_bOriginInScreenspace = true; + pLocatorTarget->m_vecOrigin.x = m_fFixedPositionX; + pLocatorTarget->m_vecOrigin.y = m_fFixedPositionY; + pLocatorTarget->SetVguiTargetName( m_szVguiTargetName.String() ); + pLocatorTarget->SetVguiTargetLookup( m_szVguiTargetLookup.String() ); + pLocatorTarget->SetVguiTargetEdge( m_nVguiTargetEdge ); + } + else + { + pLocatorTarget->m_bOriginInScreenspace = false; +#ifdef MAPBASE + pLocatorTarget->m_vecOrigin = GetIconTargetPosition( pIconTarget ) + MainViewUp() * m_flRelativeUpOffset + Vector( 0.0f, 0.0f, m_flUpOffset ); +#else + pLocatorTarget->m_vecOrigin = pIconTarget->EyePosition() + MainViewUp() * m_flRelativeUpOffset + Vector( 0.0f, 0.0f, m_flUpOffset ); +#endif + pLocatorTarget->SetVguiTargetName( "" ); + } + + const char *pchDisplayParamText = m_szDisplayParamText.String(); +#ifdef INFESTED_DLL + char szCustomName[ 256 ]; +#endif + + // Check if the parameter is the be the player display name + if ( Q_stricmp( pchDisplayParamText, "use_name" ) == 0 ) + { + // Fix up the player display name + C_BasePlayer *pPlayer = ToBasePlayer( pIconTarget ); + if ( pPlayer ) + { + pchDisplayParamText = pPlayer->GetPlayerName(); + } + else + { + bool bNoName = true; + +#ifdef INFESTED_DLL + C_ASW_Marine *pMarine = dynamic_cast< C_ASW_Marine* >( pIconTarget ); + if ( pMarine ) + { + C_ASW_Marine_Resource *pMR = pMarine->GetMarineResource(); + if ( pMR ) + { + pMR->GetDisplayName( szCustomName, sizeof( szCustomName ) ); + pchDisplayParamText = szCustomName; + bNoName = false; + } + } +#endif + + if ( bNoName ) + { + // It's not a player! + pchDisplayParamText = ""; + } + } + } + + pLocatorTarget->SetCaptionText( m_szDisplayText.String(), pchDisplayParamText ); + SetLocatorBinding( pLocatorTarget ); + pLocatorTarget->SetOnscreenIconTextureName( m_szOnscreenIcon.String() ); + pLocatorTarget->SetOffscreenIconTextureName( m_szOffscreenIcon.String() ); + pLocatorTarget->SetVisible( m_bVisible ); + + C_BasePlayer *pLocalPlayer = GetGameInstructor().GetLocalPlayer(); + + if( !m_bFixedPosition && + ( ( pLocalPlayer != NULL && pLocalPlayer == m_hIconTarget ) || + GetClientWorldEntity() == m_hIconTarget ) ) + { + // Mark this icon as a static icon that draws in a fixed + // location on the hud rather than tracking an object + // in 3D space. + pLocatorTarget->AddIconEffects( LOCATOR_ICON_FX_STATIC ); + } + else + { + pLocatorTarget->AddIconEffects( LOCATOR_ICON_FX_NONE ); + } + + if ( m_bNoOffscreen ) + { + pLocatorTarget->AddIconEffects( LOCATOR_ICON_FX_NO_OFFSCREEN ); + } + else + { + pLocatorTarget->RemoveIconEffects( LOCATOR_ICON_FX_NO_OFFSCREEN ); + } + + if( m_bForceCaption || IsLocked() ) + { + pLocatorTarget->AddIconEffects( LOCATOR_ICON_FX_FORCE_CAPTION ); + } + else + { + pLocatorTarget->RemoveIconEffects( LOCATOR_ICON_FX_FORCE_CAPTION ); + } + + pLocatorTarget->Update(); + + if ( pLocatorTarget->m_bIsDrawing ) + { + if ( !m_bHasPlayedSound ) + { + GetGameInstructor().PlaySound( m_szStartSound.String() ); + m_bHasPlayedSound = true; + } + } +} + +#ifdef MAPBASE +Vector CIconLesson::GetIconTargetPosition( C_BaseEntity *pIconTarget ) +{ + switch (m_iIconTargetPos) + { + default: + case ICON_TARGET_EYE_POSITION: + return pIconTarget->EyePosition(); + + case ICON_TARGET_ORIGIN: + return pIconTarget->GetAbsOrigin(); + + case ICON_TARGET_CENTER: + return pIconTarget->WorldSpaceCenter(); + } +} +#endif + +// +// CScriptedIconLesson +// + +// Linking variables to scriptable entries is done here! +// The first parameter correlates to the case insensitive string name read from scripts. +// This macro generates code that passes this consistent variable data in to other macros +#define LESSON_VARIABLE_FACTORY \ + LESSON_VARIABLE_MACRO_EHANDLE( VOID, m_hLocalPlayer, EHANDLE ) \ + \ + LESSON_VARIABLE_MACRO_EHANDLE( LOCAL_PLAYER, m_hLocalPlayer, EHANDLE ) \ + LESSON_VARIABLE_MACRO( OUTPUT, m_fOutput, float ) \ + \ + LESSON_VARIABLE_MACRO_EHANDLE( ENTITY1, m_hEntity1, EHANDLE ) \ + LESSON_VARIABLE_MACRO_EHANDLE( ENTITY2, m_hEntity2, EHANDLE ) \ + LESSON_VARIABLE_MACRO_STRING( STRING1, m_szString1, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( STRING2, m_szString2, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO( INTEGER1, m_iInteger1, int ) \ + LESSON_VARIABLE_MACRO( INTEGER2, m_iInteger2, int ) \ + LESSON_VARIABLE_MACRO( FLOAT1, m_fFloat1, float ) \ + LESSON_VARIABLE_MACRO( FLOAT2, m_fFloat2, float ) \ + \ + LESSON_VARIABLE_MACRO_EHANDLE( ICON_TARGET, m_hIconTarget, EHANDLE ) \ + LESSON_VARIABLE_MACRO_STRING( VGUI_TARGET_NAME, m_szVguiTargetName, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( VGUI_TARGET_LOOKUP, m_szVguiTargetLookup, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO( VGUI_TARGET_EDGE, m_nVguiTargetEdge, int ) \ + LESSON_VARIABLE_MACRO( FIXED_POSITION_X, m_fFixedPositionX, float ) \ + LESSON_VARIABLE_MACRO( FIXED_POSITION_Y, m_fFixedPositionY, float ) \ + LESSON_VARIABLE_MACRO_BOOL( FIXED_POSITION, m_bFixedPosition, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( NO_ICON_TARGET, m_bNoIconTarget, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( ALLOW_NODRAW_TARGET, m_bAllowNodrawTarget, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( VISIBLE, m_bVisible, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( SHOW_WHEN_OCCLUDED, m_bShowWhenOccluded, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( NO_OFFSCREEN, m_bNoOffscreen, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( FORCE_CAPTION, m_bForceCaption, bool ) \ + LESSON_VARIABLE_MACRO_STRING( ONSCREEN_ICON, m_szOnscreenIcon, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( OFFSCREEN_ICON, m_szOffscreenIcon, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO( ICON_OFFSET, m_flUpOffset, float ) \ + LESSON_VARIABLE_MACRO( ICON_RELATIVE_OFFSET, m_flRelativeUpOffset, float ) \ + LESSON_VARIABLE_MACRO( RANGE, m_fRange, float ) \ + \ + LESSON_VARIABLE_MACRO( FLAGS, m_iFlags, int ) \ + LESSON_VARIABLE_MACRO_STRING( CAPTION_COLOR, m_szCaptionColor, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( GROUP, m_szLessonGroup, CGameInstructorSymbol ) \ + \ + LESSON_VARIABLE_MACRO_STRING( CAPTION, m_szDisplayText, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( CAPTION_PARAM, m_szDisplayParamText, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( BINDING, m_szBinding, CGameInstructorSymbol ) \ + LESSON_VARIABLE_MACRO_STRING( GAMEPAD_BINDING, m_szGamepadBinding, CGameInstructorSymbol ) \ + \ + LESSON_VARIABLE_MACRO( PRIORITY, m_iPriority, int ) \ + LESSON_VARIABLE_MACRO_STRING( REPLACE_KEY, m_stringReplaceKey, CGameInstructorSymbol ) \ + \ + LESSON_VARIABLE_MACRO( LOCK_DURATION, m_fLockDuration, float ) \ + LESSON_VARIABLE_MACRO_BOOL( CAN_OPEN_WHEN_DEAD, m_bCanOpenWhenDead, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( BUMP_WITH_TIMEOUT_WHEN_LEARNED, m_bBumpWithTimeoutWhenLearned, bool ) \ + LESSON_VARIABLE_MACRO_BOOL( CAN_TIMEOUT_WHILE_INACTIVE, m_bCanTimeoutWhileInactive, bool ) \ + LESSON_VARIABLE_MACRO( TIMEOUT, m_fTimeout, float ) \ + LESSON_VARIABLE_MACRO( UPDATE_INTERVAL, m_fUpdateInterval, float ) \ + LESSON_VARIABLE_MACRO_STRING( START_SOUND, m_szStartSound, CGameInstructorSymbol ) \ + \ + LESSON_VARIABLE_MACRO( ICON_TARGET_POS, m_iIconTargetPos, int ) \ + LESSON_VARIABLE_MACRO_STRING( HUD_HINT_AFTER_LEARNED, m_szHudHint, CGameInstructorSymbol ) \ + + +// Create keyvalues name symbol +#define LESSON_VARIABLE_SYMBOL( _varEnum, _varName, _varType ) static int g_n##_varEnum##Symbol; + +#define LESSON_VARIABLE_INIT_SYMBOL( _varEnum, _varName, _varType ) g_n##_varEnum##Symbol = KeyValuesSystem()->GetSymbolForString( #_varEnum ); + +#define LESSON_SCRIPT_STRING_ADD_TO_MAP( _varEnum, _varName, _varType ) g_NameToTypeMap.Insert( #_varEnum, LESSON_VARIABLE_##_varEnum ); + +// Create enum value +#define LESSON_VARIABLE_ENUM( _varEnum, _varName, _varType ) LESSON_VARIABLE_##_varEnum, + +// Init info call +#define LESSON_VARIABLE_INIT_INFO_CALL( _varEnum, _varName, _varType ) g_pLessonVariableInfo[ LESSON_VARIABLE_##_varEnum ].Init_##_varEnum(); + +// Init info +#define LESSON_VARIABLE_INIT_INFO( _varEnum, _varName, _varType ) \ + void Init_##_varEnum() \ + { \ + iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \ + varType = LessonParamTypeFromString( #_varType ); \ + } + +#define LESSON_VARIABLE_INIT_INFO_BOOL( _varEnum, _varName, _varType ) \ + void Init_##_varEnum() \ + { \ + iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \ + varType = FIELD_BOOLEAN; \ + } + +#define LESSON_VARIABLE_INIT_INFO_EHANDLE( _varEnum, _varName, _varType ) \ + void Init_##_varEnum() \ + { \ + iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \ + varType = FIELD_EHANDLE; \ + } + +#define LESSON_VARIABLE_INIT_INFO_STRING( _varEnum, _varName, _varType ) \ + void Init_##_varEnum() \ + { \ + iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \ + varType = FIELD_STRING; \ + } + +// Copy defaults into this scripted lesson into a new one +#define LESSON_VARIABLE_DEFAULT( _varEnum, _varName, _varType ) ( _varName = m_pDefaultHolder->_varName ); + +// Copy a variable from this scripted lesson into a new one +#define LESSON_VARIABLE_COPY( _varEnum, _varName, _varType ) ( pOpenLesson->_varName = _varName ); + +// Return the first param if pchName is the same as the second param +#define LESSON_SCRIPT_STRING( _type, _string ) \ + if ( Q_stricmp( pchName, _string ) == 0 )\ + {\ + return _type;\ + } + +// Wrapper for using this macro in the factory +#define LESSON_SCRIPT_STRING_GENERAL( _varEnum, _varName, _varType ) LESSON_SCRIPT_STRING( LESSON_VARIABLE_##_varEnum##, #_varEnum ) + +// Process the element action on this variable +#define PROCESS_LESSON_ACTION( _varEnum, _varName, _varType ) \ + case LESSON_VARIABLE_##_varEnum:\ + return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, _varName, &pLessonElement->szParam, eventParam_float ); + +#define PROCESS_LESSON_ACTION_EHANDLE( _varEnum, _varName, _varType ) \ + case LESSON_VARIABLE_##_varEnum:\ + return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, _varName, &pLessonElement->szParam, eventParam_float, eventParam_BaseEntity, eventParam_string ); + +#define PROCESS_LESSON_ACTION_STRING( _varEnum, _varName, _varType ) \ + case LESSON_VARIABLE_##_varEnum:\ + return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, &_varName, &pLessonElement->szParam, eventParam_string ); + +// Init the variable from the script (or a convar) +#define LESSON_VARIABLE_INIT( _varEnum, _varName, _varType ) \ + else if ( g_n##_varEnum##Symbol == pSubKey->GetNameSymbol() ) \ + { \ + const char *pchParam = pSubKey->GetString(); \ + if ( pchParam && StringHasPrefix( pchParam, "convar " ) ) \ + { \ + ConVarRef tempCVar( pchParam + Q_strlen( "convar " ) ); \ + if ( tempCVar.IsValid() ) \ + { \ + _varName = static_cast<_varType>( tempCVar.GetFloat() ); \ + } \ + else \ + { \ + _varName = static_cast<_varType>( 0.0f ); \ + } \ + } \ + else \ + { \ + _varName = static_cast<_varType>( pSubKey->GetFloat() ); \ + } \ + } + +#define LESSON_VARIABLE_INIT_BOOL( _varEnum, _varName, _varType ) \ + else if ( Q_stricmp( #_varEnum, pSubKey->GetName() ) == 0 ) \ + { \ + _varName = pSubKey->GetBool(); \ + } + +#define LESSON_VARIABLE_INIT_EHANDLE( _varEnum, _varName, _varType ) \ + else if ( g_n##_varEnum##Symbol == pSubKey->GetNameSymbol() ) \ + { \ + DevWarning( "Can't initialize an EHANDLE from the instructor lesson script." ); \ + } + +#define LESSON_VARIABLE_INIT_STRING( _varEnum, _varName, _varType ) \ + else if ( g_n##_varEnum##Symbol == pSubKey->GetNameSymbol() ) \ + { \ + const char *pchParam = pSubKey->GetString(); \ + if ( pchParam && StringHasPrefix( pchParam, "convar " ) ) \ + { \ + ConVarRef tempCVar( pchParam + Q_strlen( "convar " ) ); \ + if ( tempCVar.IsValid() ) \ + { \ + _varName = tempCVar.GetString(); \ + } \ + else \ + { \ + _varName = ""; \ + } \ + } \ + else \ + { \ + _varName = pSubKey->GetString(); \ + } \ + } + +// Gets a scripted variable by offset and casts it to the proper type +#define LESSON_VARIABLE_GET_FROM_OFFSET( _type, _offset ) *static_cast<_type*>( static_cast( static_cast( static_cast( this ) ) + _offset ) ) + + +// Enum of scripted variables +enum LessonVariable +{ + // Run enum macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_ENUM +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_ENUM +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_ENUM +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_ENUM + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + + LESSON_VARIABLE_TOTAL +}; + +// Declare the keyvalues symbols for the keynames +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_SYMBOL +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_SYMBOL +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_SYMBOL +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_SYMBOL + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + +// String lookup prototypes +LessonVariable LessonVariableFromString( const char *pchName, bool bWarnOnInvalidNames = true ); +_fieldtypes LessonParamTypeFromString( const char *pchName ); +int LessonActionFromString( const char *pchName ); + + +// This is used to get type info an variable offsets from the variable enumerated value +class LessonVariableInfo +{ +public: + + LessonVariableInfo() + : iOffset( 0 ), varType( FIELD_VOID ) + { + } + + // Run init info macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_INIT_INFO +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_INIT_INFO_BOOL +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_INIT_INFO_EHANDLE +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_INIT_INFO_STRING + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + +public: + + int iOffset; + _fieldtypes varType; +}; + +LessonVariableInfo g_pLessonVariableInfo[ LESSON_VARIABLE_TOTAL ]; + + +const LessonVariableInfo *GetLessonVariableInfo( int iLessonVariable ) +{ + Assert( iLessonVariable >= 0 && iLessonVariable < LESSON_VARIABLE_TOTAL ); + + if ( g_pLessonVariableInfo[ 0 ].varType == FIELD_VOID ) + { + // Run init info call macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_INIT_INFO_CALL +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_INIT_INFO_CALL +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_INIT_INFO_CALL +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_INIT_INFO_CALL + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + } + + return &(g_pLessonVariableInfo[ iLessonVariable ]); +} + +static CUtlDict< LessonVariable, int > g_NameToTypeMap; +static CUtlDict< fieldtype_t, int > g_TypeToParamTypeMap; +CUtlDict< int, int > CScriptedIconLesson::LessonActionMap; + +CScriptedIconLesson::~CScriptedIconLesson() +{ + if ( m_pDefaultHolder ) + { + delete m_pDefaultHolder; + m_pDefaultHolder = NULL; + } +} + + +void CScriptedIconLesson::Init() +{ + m_hLocalPlayer.Set( NULL ); + m_fOutput = 0.0f; + m_hEntity1.Set( NULL ); + m_hEntity2.Set( NULL ); + m_szString1 = ""; + m_szString2 = ""; + m_iInteger1 = 0; + m_iInteger2 = 0; + m_fFloat1 = 0.0f; + m_fFloat2 = 0.0f; + + m_fUpdateEventTime = 0.0f; + m_pDefaultHolder = NULL; + m_iScopeDepth = 0; + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Initializing scripted lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + if ( !IsDefaultHolder() ) + { + if ( !IsOpenOpportunity() ) + { + // Initialize from the key value file + InitFromKeys( GetGameInstructor().GetScriptKeys() ); + + if ( m_iPriority >= LESSON_PRIORITY_MAX ) + { + DevWarning( "Priority level not set for lesson: %s\n", GetName() ); + } + + // We use this to remember variable defaults to be reset before each open attempt + m_pDefaultHolder = new CScriptedIconLesson( GetName(), true, false ); + CScriptedIconLesson *pOpenLesson = m_pDefaultHolder; + + // Run copy macros on all default scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_COPY + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + + // Listen for open events + for ( int iLessonEvent = 0; iLessonEvent < m_OpenEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(m_OpenEvents[ iLessonEvent ]); + ListenForGameEvent( pLessonEvent->szEventName.String() ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tListen for open event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + } + + // Listen for close events + for ( int iLessonEvent = 0; iLessonEvent < m_CloseEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(m_CloseEvents[ iLessonEvent ]); + ListenForGameEvent( pLessonEvent->szEventName.String() ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tListen for close event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + } + + // Listen for success events + for ( int iLessonEvent = 0; iLessonEvent < m_SuccessEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(m_SuccessEvents[ iLessonEvent ]); + ListenForGameEvent( pLessonEvent->szEventName.String()); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tListen for success event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + } + } + else + { + // This is an open lesson! Get the root for reference + const CScriptedIconLesson *pLesson = static_cast( GetGameInstructor().GetLesson( GetName() ) ); + SetRoot( const_cast( pLesson ) ); + } + } +} + +void CScriptedIconLesson::InitPrerequisites() +{ + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Initializing prereqs for scripted lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + for ( int iPrerequisit = 0; iPrerequisit < m_PrerequisiteNames.Count(); ++iPrerequisit ) + { + const char *pPrerequisiteName = m_PrerequisiteNames[ iPrerequisit ].String(); + AddPrerequisite( pPrerequisiteName ); + } +} + +void CScriptedIconLesson::OnOpen() +{ + VPROF_BUDGET( "CScriptedIconLesson::OnOpen", "GameInstructor" ); + + if ( !DoDelayedPlayerSwaps() ) + { + return; + } + + const CScriptedIconLesson *pLesson = static_cast( GetRoot() ); + + // Process all update events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->m_OnOpenEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->m_OnOpenEvents[ iLessonEvent ]); + + if ( gameinstructor_verbose.GetInt() > 1 && ShouldShowSpew() ) + { + ConColorMsg( Color( 255, 128, 64, 255 ), "GAME INSTRUCTOR: " ); + ConColorMsg( Color( 64, 128, 255, 255 ), "OnOpen event " ); + ConColorMsg( Color( 0, 255, 0, 255 ), "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( Color( 64, 128, 255, 255 ), "received for lesson \"%s\"...\n", GetName() ); + } + + ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + BaseClass::OnOpen(); +} + +void CScriptedIconLesson::Update() +{ + VPROF_BUDGET( "CScriptedIconLesson::Update", "GameInstructor" ); + + if ( !DoDelayedPlayerSwaps() ) + { + return; + } + + const CScriptedIconLesson *pLesson = static_cast( GetRoot() ); + + if ( gpGlobals->curtime >= m_fUpdateEventTime ) + { + bool bShowSpew = ( gameinstructor_verbose.GetInt() > 1 && ShouldShowSpew() ); + + int iVerbose = gameinstructor_verbose.GetInt(); + if ( gameinstructor_verbose.GetInt() == 1 ) + { + // Force the verbose level from 1 to 0 for update events + gameinstructor_verbose.SetValue( 0 ); + } + + // Process all update events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->m_UpdateEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->m_UpdateEvents[ iLessonEvent ]); + + if ( bShowSpew ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Update event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseUpdate, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "received for lesson \"%s\"...\n", GetName() ); + } + + ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + gameinstructor_verbose.SetValue( iVerbose ); + + // Wait before doing update events again + m_fUpdateEventTime = gpGlobals->curtime + m_fUpdateInterval; + } + + BaseClass::Update(); +} + +void CScriptedIconLesson::SwapOutPlayers( int iOldUserID, int iNewUserID ) +{ + BaseClass::SwapOutPlayers( iOldUserID, iNewUserID ); + + // Get the player pointers from the user IDs + C_BasePlayer *pOldPlayer = UTIL_PlayerByUserId( iOldUserID ); + C_BasePlayer *pNewPlayer = UTIL_PlayerByUserId( iNewUserID ); + + if ( pOldPlayer == m_hEntity1.Get() ) + { + if ( pNewPlayer ) + { + m_hEntity1 = pNewPlayer; + } + else + { + if ( m_iNumDelayedPlayerSwaps < MAX_DELAYED_PLAYER_SWAPS ) + { + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].phHandleToChange = &m_hEntity1; + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].iNewUserID = iNewUserID; + ++m_iNumDelayedPlayerSwaps; + } + } + } + + if ( pOldPlayer == m_hEntity2.Get() ) + { + if ( pNewPlayer ) + { + m_hEntity2 = pNewPlayer; + } + else + { + + if ( m_iNumDelayedPlayerSwaps < MAX_DELAYED_PLAYER_SWAPS ) + { + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].phHandleToChange = &m_hEntity2; + m_pDelayedPlayerSwap[ m_iNumDelayedPlayerSwaps ].iNewUserID = iNewUserID; + ++m_iNumDelayedPlayerSwaps; + } + } + } +} + +void CScriptedIconLesson::FireGameEvent( IGameEvent *event ) +{ + VPROF_BUDGET( "CScriptedIconLesson::FireGameEvent", "GameInstructor" ); + + if ( m_bDisabled ) + return; + + if ( !DoDelayedPlayerSwaps() ) + { + return; + } + + if ( !C_BasePlayer::GetLocalPlayer() ) + return; + + // Check that this lesson is allowed for the current input device + if( m_bOnlyKeyboard /*&& input->ControllerModeActive()*/ ) + return; + + if( m_bOnlyGamepad /*&& !input->ControllerModeActive()*/ ) + return; + + // Check that this lesson is for the proper team + CBasePlayer *pLocalPlayer = GetGameInstructor().GetLocalPlayer(); + + if ( m_iTeam != TEAM_ANY && pLocalPlayer && pLocalPlayer->GetTeamNumber() != m_iTeam ) + { + // This lesson is intended for a different team + return; + } + + const char *name = event->GetName(); + + // Open events run on the root + ProcessOpenGameEvents( this, name, event ); + + // Close and success events run on the children + const CUtlVector < CBaseLesson * > *pChildren = GetChildren(); + for ( int iChild = 0; iChild < pChildren->Count(); ++iChild ) + { + CScriptedIconLesson *pScriptedChild = dynamic_cast( (*pChildren)[ iChild ] ); + + pScriptedChild->ProcessCloseGameEvents( this, name, event ); + pScriptedChild->ProcessSuccessGameEvents( this, name, event ); + } +} + +void CScriptedIconLesson::ProcessOpenGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ) +{ + if ( pRootLesson->InstanceType() == LESSON_INSTANCE_SINGLE_OPEN && GetGameInstructor().IsLessonOfSameTypeOpen( this ) ) + { + // We don't want more than one of this type, and there is already one open + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pRootLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "open events NOT processed (there is already an open lesson of this type).\n" ); + } + + return; + } + + for ( int iLessonEvent = 0; iLessonEvent < pRootLesson->m_OpenEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pRootLesson->m_OpenEvents[ iLessonEvent ]); + + if ( Q_strcmp( name, pLessonEvent->szEventName.String()) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Open event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "received for lesson \"%s\"...\n", GetName() ); + } + + if ( m_pDefaultHolder ) + { + // Run copy from default macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_DEFAULT +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_DEFAULT +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_DEFAULT +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_DEFAULT + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + } + + if ( ProcessElements( event, &(pLessonEvent->elements) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\tAll elements returned true. Opening!\n" ); + } + + MEM_ALLOC_CREDIT(); + CScriptedIconLesson *pOpenLesson = new CScriptedIconLesson( GetName(), false, true ); + + // Run copy macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_COPY +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_COPY + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + + if ( GetGameInstructor().OpenOpportunity( pOpenLesson ) ) + { + pOpenLesson->OnOpen(); + + if ( pRootLesson->InstanceType() == LESSON_INSTANCE_SINGLE_OPEN ) + { + // This one is open and we only want one! So, we're done. + // Other open events may be listening for the same events... skip them! + return; + } + } + } + } + } +} + +void CScriptedIconLesson::ProcessCloseGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ) +{ + for ( int iLessonEvent = 0; iLessonEvent < pRootLesson->m_CloseEvents.Count() && IsOpenOpportunity(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pRootLesson->m_CloseEvents[ iLessonEvent ]); + + if ( Q_strcmp( name, pLessonEvent->szEventName.String()) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Close event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "received for lesson \"%s\"...\n", GetName() ); + } + + if ( ProcessElements( event, &(pLessonEvent->elements) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tAll elements returned true. Closing!\n" ); + } + + CloseOpportunity( "Close event elements completed." ); + } + } + } +} + +void CScriptedIconLesson::ProcessSuccessGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ) +{ + for ( int iLessonEvent = 0; iLessonEvent < pRootLesson->m_SuccessEvents.Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pRootLesson->m_SuccessEvents[ iLessonEvent ]); + + if ( Q_strcmp( name, pLessonEvent->szEventName.String()) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Success event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "\"%s\"", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "received for lesson \"%s\"...\n", GetName() ); + } + + if ( ProcessElements( event, &(pLessonEvent->elements) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "\tAll elements returned true. Succeeding!\n" ); + } + + MarkSucceeded(); + } + } + } +} + +LessonVariable LessonVariableFromString( const char *pchName, bool bWarnOnInvalidNames ) +{ + int slot = g_NameToTypeMap.Find( pchName ); + if ( slot != g_NameToTypeMap.InvalidIndex() ) + return g_NameToTypeMap[ slot ]; + + if ( bWarnOnInvalidNames ) + { + AssertMsg( 0, "Invalid scripted lesson variable!" ); + DevWarning( "Invalid scripted lesson variable: %s\n", pchName ); + } + + return LESSON_VARIABLE_TOTAL; +} + +_fieldtypes LessonParamTypeFromString( const char *pchName ) +{ + int slot = g_TypeToParamTypeMap.Find( pchName ); + if ( slot != g_TypeToParamTypeMap.InvalidIndex() ) + return g_TypeToParamTypeMap[ slot ]; + + DevWarning( "Invalid scripted lesson variable/param type: %s\n", pchName ); + return FIELD_VOID; +} + +int LessonActionFromString( const char *pchName ) +{ + int slot = CScriptedIconLesson::LessonActionMap.Find( pchName ); + if ( slot != CScriptedIconLesson::LessonActionMap.InvalidIndex() ) + return CScriptedIconLesson::LessonActionMap[ slot ]; + + DevWarning( "Invalid scripted lesson action: %s\n", pchName ); + return LESSON_ACTION_NONE; +} + +void CScriptedIconLesson::InitElementsFromKeys( CUtlVector< LessonElement_t > *pLessonElements, KeyValues *pKey ) +{ + KeyValues *pSubKey = NULL; + for ( pSubKey = pKey->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() ) + { + char szSubKeyName[ 256 ]; + Q_strcpy( szSubKeyName, pSubKey->GetName() ); + + char *pchToken = strtok( szSubKeyName, " " ); + LessonVariable iVariable = LessonVariableFromString( pchToken ); + + pchToken = strtok ( NULL, "" ); + int iAction = LESSON_ACTION_NONE; + bool bNot = false; + bool bOptionalParam = false; + + if ( !pchToken || pchToken[ 0 ] == '\0' ) + { + DevWarning( "No action specified for variable: \"%s\"\n", pSubKey->GetName() ); + } + else + { + if ( pchToken[ 0 ] == '?' ) + { + pchToken++; + bOptionalParam = true; + } + + if ( pchToken[ 0 ] == '!' ) + { + pchToken++; + bNot = true; + } + + iAction = LessonActionFromString( pchToken ); + } + + Q_strcpy( szSubKeyName, pSubKey->GetString() ); + + pchToken = strtok( szSubKeyName, " " ); + _fieldtypes paramType = LessonParamTypeFromString( pchToken ); + + char *pchParam = ""; + + if ( paramType != FIELD_VOID ) + { + pchToken = strtok ( NULL, "" ); + pchParam = pchToken; + } + + if ( !pchParam ) + { + DevWarning( "No parameter specified for action: \"%s\"\n", pSubKey->GetName() ); + } + else + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t\tElement \"%s %s\" added.\n", pSubKey->GetName(), pSubKey->GetString() ); + } + + // See if our param is a scripted var + LessonVariable iParamVarIndex = LessonVariableFromString( pchParam, false ); + + pLessonElements->AddToTail( LessonElement_t( iVariable, iAction, bNot, bOptionalParam, pchParam, iParamVarIndex, paramType ) ); + } + } +} + +void CScriptedIconLesson::InitElementsFromElements( CUtlVector< LessonElement_t > *pLessonElements, const CUtlVector< LessonElement_t > *pLessonElements2 ) +{ + for ( int i = 0; i < pLessonElements2->Count(); ++i ) + { + pLessonElements->AddToTail( LessonElement_t( (*pLessonElements2)[ i ] ) ); + } +} + +void CScriptedIconLesson::InitFromKeys( KeyValues *pKey ) +{ + if ( !pKey ) + return; + + static int s_nInstanceTypeSymbol = KeyValuesSystem()->GetSymbolForString( "instance_type" ); + static int s_nReplaceKeySymbol = KeyValuesSystem()->GetSymbolForString( "replace_key" ); + static int s_nFixedInstancesMaxSymbol = KeyValuesSystem()->GetSymbolForString( "fixed_instances_max" ); + static int s_nReplaceOnlyWhenStopped = KeyValuesSystem()->GetSymbolForString( "replace_only_when_stopped" ); + static int s_nTeamSymbol = KeyValuesSystem()->GetSymbolForString( "team" ); + static int s_nOnlyKeyboardSymbol = KeyValuesSystem()->GetSymbolForString( "only_keyboard" ); + static int s_nOnlyGamepadSymbol = KeyValuesSystem()->GetSymbolForString( "only_gamepad" ); + static int s_nDisplayLimitSymbol = KeyValuesSystem()->GetSymbolForString( "display_limit" ); + static int s_nSuccessLimitSymbol = KeyValuesSystem()->GetSymbolForString( "success_limit" ); + static int s_nPreReqSymbol = KeyValuesSystem()->GetSymbolForString( "prereq" ); + static int s_nOpenSymbol = KeyValuesSystem()->GetSymbolForString( "open" ); + static int s_nCloseSymbol = KeyValuesSystem()->GetSymbolForString( "close" ); + static int s_nSuccessSymbol = KeyValuesSystem()->GetSymbolForString( "success" ); + static int s_nOnOpenSymbol = KeyValuesSystem()->GetSymbolForString( "onopen" ); + static int s_nUpdateSymbol = KeyValuesSystem()->GetSymbolForString( "update" ); + + KeyValues *pSubKey = NULL; + for ( pSubKey = pKey->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() ) + { + if ( pSubKey->GetNameSymbol() == s_nInstanceTypeSymbol ) + { + m_iInstanceType = LessonInstanceType( pSubKey->GetInt() ); + } + else if ( pSubKey->GetNameSymbol() == s_nReplaceKeySymbol ) + { + m_stringReplaceKey = pSubKey->GetString(); + } + else if ( pSubKey->GetNameSymbol() == s_nFixedInstancesMaxSymbol ) + { + m_iFixedInstancesMax = pSubKey->GetInt(); + } + else if ( pSubKey->GetNameSymbol() == s_nReplaceOnlyWhenStopped ) + { + m_bReplaceOnlyWhenStopped = pSubKey->GetBool(); + } + else if ( pSubKey->GetNameSymbol() == s_nTeamSymbol ) + { + m_iTeam = pSubKey->GetInt(); + } + else if ( pSubKey->GetNameSymbol() == s_nOnlyKeyboardSymbol ) + { + m_bOnlyKeyboard = pSubKey->GetBool(); + } + else if ( pSubKey->GetNameSymbol() == s_nOnlyGamepadSymbol ) + { + m_bOnlyGamepad = pSubKey->GetBool(); + } + else if ( pSubKey->GetNameSymbol() == s_nDisplayLimitSymbol ) + { + m_iDisplayLimit = pSubKey->GetInt(); + } + else if ( pSubKey->GetNameSymbol() == s_nSuccessLimitSymbol ) + { + m_iSuccessLimit = pSubKey->GetInt(); + } + else if ( pSubKey->GetNameSymbol() == s_nPreReqSymbol ) + { + CGameInstructorSymbol pName; + pName = pSubKey->GetString(); + m_PrerequisiteNames.AddToTail( pName ); + } + else if ( pSubKey->GetNameSymbol() == s_nOpenSymbol ) + { + KeyValues *pEventKey = NULL; + for ( pEventKey = pSubKey->GetFirstTrueSubKey(); pEventKey; pEventKey = pEventKey->GetNextTrueSubKey() ) + { + LessonEvent_t *pLessonEvent = AddOpenEvent(); + pLessonEvent->szEventName = pEventKey->GetName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tAdding open event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\" ", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + InitElementsFromKeys( &(pLessonEvent->elements), pEventKey ); + } + } + else if ( pSubKey->GetNameSymbol() == s_nCloseSymbol ) + { + KeyValues *pEventKey = NULL; + for ( pEventKey = pSubKey->GetFirstTrueSubKey(); pEventKey; pEventKey = pEventKey->GetNextTrueSubKey() ) + { + LessonEvent_t *pLessonEvent = AddCloseEvent(); + pLessonEvent->szEventName = pEventKey->GetName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tAdding close event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + InitElementsFromKeys( &(pLessonEvent->elements), pEventKey ); + } + } + else if ( pSubKey->GetNameSymbol() == s_nSuccessSymbol ) + { + KeyValues *pEventKey = NULL; + for ( pEventKey = pSubKey->GetFirstTrueSubKey(); pEventKey; pEventKey = pEventKey->GetNextTrueSubKey() ) + { + LessonEvent_t *pLessonEvent = AddSuccessEvent(); + pLessonEvent->szEventName = pEventKey->GetName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tAdding success event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "\"%s\" ", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + InitElementsFromKeys( &(pLessonEvent->elements), pEventKey ); + } + } + else if ( pSubKey->GetNameSymbol() == s_nOnOpenSymbol ) + { + KeyValues *pEventKey = NULL; + for ( pEventKey = pSubKey->GetFirstTrueSubKey(); pEventKey; pEventKey = pEventKey->GetNextTrueSubKey() ) + { + LessonEvent_t *pLessonEvent = AddOnOpenEvent(); + pLessonEvent->szEventName = pEventKey->GetName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tAdding onopen event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\" ", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + InitElementsFromKeys( &(pLessonEvent->elements), pEventKey ); + } + } + else if ( pSubKey->GetNameSymbol() == s_nUpdateSymbol ) + { + KeyValues *pEventKey = NULL; + for ( pEventKey = pSubKey->GetFirstTrueSubKey(); pEventKey; pEventKey = pEventKey->GetNextTrueSubKey() ) + { + LessonEvent_t *pLessonEvent = AddUpdateEvent(); + pLessonEvent->szEventName = pEventKey->GetName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tAdding update event " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseUpdate, "\"%s\" ", pLessonEvent->szEventName.String()); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "...\n" ); + } + + InitElementsFromKeys( &(pLessonEvent->elements), pEventKey ); + } + } + + // Run intialize from key macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_INIT +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_INIT_BOOL +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_INIT_EHANDLE +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_INIT_STRING + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + } +} + +bool CScriptedIconLesson::ProcessElements( IGameEvent *event, const CUtlVector< LessonElement_t > *pElements ) +{ + VPROF_BUDGET( "CScriptedIconLesson::ProcessElements", "GameInstructor" ); + + m_hLocalPlayer = GetGameInstructor().GetLocalPlayer(); + + bool bSuccess = true; + int nContinueScope = -1; + m_iScopeDepth = 0; + + if ( gameinstructor_find_errors.GetBool() ) + { + // Just run them all to check for errors! + for ( int iElement = 0; iElement < pElements->Count(); ++iElement ) + { + ProcessElement( event, &((*pElements)[ iElement ] ), false ); + } + + return false; + } + + // Process each element until a step fails + for ( int iElement = 0; iElement < pElements->Count(); ++iElement ) + { + if ( nContinueScope == m_iScopeDepth ) + { + nContinueScope = -1; + } + + if ( !ProcessElement( event, &((*pElements)[ iElement ]), nContinueScope != -1 ) ) + { + // This element failed + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tPrevious element returned false.\n" ); + } + + nContinueScope = m_iScopeDepth - 1; + + if ( nContinueScope < 0 ) + { + // No outer scope to worry about, we're done + bSuccess = false; + break; + } + } + } + + return bSuccess; +} + +bool CScriptedIconLesson::ProcessElement( IGameEvent *event, const LessonElement_t *pLessonElement, bool bInFailedScope ) +{ + VPROF_BUDGET( "CScriptedIconLesson::ProcessElement", "GameInstructor" ); + + if ( pLessonElement->iAction == LESSON_ACTION_SCOPE_IN ) + { + // Special case for closing (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tScopeIn()\n" ); + } + + m_iScopeDepth++; + return true; + } + else if ( pLessonElement->iAction == LESSON_ACTION_SCOPE_OUT ) + { + // Special case for closing (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tScopeOut()\n" ); + } + + m_iScopeDepth--; + return true; + } + + if ( bInFailedScope ) + { + // Only scope upkeep is done when we're in a failing scope... bail! + return true; + } + + if ( pLessonElement->iAction == LESSON_ACTION_CLOSE ) + { + // Special case for closing (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tCloseOpportunity()\n" ); + } + + CloseOpportunity( "Close action." ); + return true; + } + else if ( pLessonElement->iAction == LESSON_ACTION_SUCCESS ) + { + // Special case for succeeding (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tMarkSucceeded()\n" ); + } + + MarkSucceeded(); + return true; + } + else if ( pLessonElement->iAction == LESSON_ACTION_LOCK ) + { + // Special case for setting the starting point for the lesson to stay locked from (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tm_fLockTime = gpGlobals->curtime\n" ); + } + + m_fLockTime = gpGlobals->curtime; + return true; + } + else if ( pLessonElement->iAction == LESSON_ACTION_PRESENT_COMPLETE ) + { + // Special case for checking presentation status (we don't need variables for this) + bool bPresentComplete = IsPresentComplete(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tIsPresentComplete() " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%s ", ( bPresentComplete ) ? ( "true" ) : ( "false" ) ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( pLessonElement->bNot ) ? ( "!= true\n" ) : ( "== true\n" ) ); + } + + return ( pLessonElement->bNot ) ? ( !bPresentComplete ) : ( bPresentComplete ); + } + else if ( pLessonElement->iAction == LESSON_ACTION_PRESENT_START ) + { + // Special case for setting presentation status (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tPresentStart()\n" ); + } + + PresentStart(); + return true; + } + else if ( pLessonElement->iAction == LESSON_ACTION_PRESENT_END ) + { + // Special case for setting presentation status (we don't need variables for this) + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tPresentEnd()\n" ); + } + + PresentEnd(); + return true; + } + + // These values temporarily hold the parameter's value + const char *pParamName = pLessonElement->szParam.String(); + float eventParam_float = 0.0f; + char eventParam_string[ 256 ]; + eventParam_string[ 0 ] = '\0'; + C_BaseEntity *eventParam_BaseEntity = NULL; + + // Get the value from the event parameter based on its type + switch ( pLessonElement->paramType ) + { + case FIELD_FLOAT: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_FLOAT: + eventParam_float = LESSON_VARIABLE_GET_FROM_OFFSET( float, pInfo->iOffset ); + break; + case FIELD_INTEGER: + eventParam_float = static_cast( LESSON_VARIABLE_GET_FROM_OFFSET( int, pInfo->iOffset ) ); + break; + case FIELD_BOOLEAN: + eventParam_float = static_cast( LESSON_VARIABLE_GET_FROM_OFFSET( bool, pInfo->iOffset ) ); + break; + case FIELD_STRING: + eventParam_float = static_cast( atoi( &LESSON_VARIABLE_GET_FROM_OFFSET( CGameInstructorSymbol, pInfo->iOffset )->String() ) ); + break; + case FIELD_EHANDLE: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else if ( event && !(event->IsEmpty( pParamName )) ) + { + eventParam_float = event->GetFloat( pParamName ); + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else if ( ( pParamName[ 0 ] >= '0' && pParamName[ 0 ] <= '9' ) || pParamName[ 0 ] == '-' || pParamName[ 0 ] == '.' ) + { + // This param doesn't exist, try parsing the string + eventParam_float = Q_atof( pParamName ); + } + else + { + DevWarning( "Invalid event field name and not a float \"%s\".\n", pParamName ); + return false; + } + break; + + case FIELD_INTEGER: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_FLOAT: + eventParam_float = static_cast( LESSON_VARIABLE_GET_FROM_OFFSET( float, pInfo->iOffset ) ); + break; + case FIELD_INTEGER: + eventParam_float = LESSON_VARIABLE_GET_FROM_OFFSET( int, pInfo->iOffset ); + break; + case FIELD_BOOLEAN: + eventParam_float = static_cast( LESSON_VARIABLE_GET_FROM_OFFSET( bool, pInfo->iOffset ) ); + break; + case FIELD_STRING: + eventParam_float = atof( &LESSON_VARIABLE_GET_FROM_OFFSET( CGameInstructorSymbol, pInfo->iOffset )->String() ); + break; + case FIELD_EHANDLE: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else if ( event && !(event->IsEmpty( pParamName )) ) + { + eventParam_float = static_cast( event->GetInt( pParamName ) ); + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else if ( ( pParamName[ 0 ] >= '0' && pParamName[ 0 ] <= '9' ) || pParamName[ 0 ] == '-' ) + { + // This param doesn't exist, try parsing the string + eventParam_float = static_cast( Q_atoi( pParamName ) ); + } + else + { + DevWarning( "Invalid event field name and not an integer \"%s\".\n", pParamName ); + return false; + } + break; + + case FIELD_STRING: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_STRING: + Q_strncpy( eventParam_string, &LESSON_VARIABLE_GET_FROM_OFFSET( CGameInstructorSymbol, pInfo->iOffset )->String(), sizeof( eventParam_string ) ); + break; + case FIELD_FLOAT: + Q_snprintf( eventParam_string, sizeof( eventParam_string ), "%f", LESSON_VARIABLE_GET_FROM_OFFSET( float, pInfo->iOffset ) ); + break; + case FIELD_INTEGER: + Q_snprintf( eventParam_string, sizeof( eventParam_string ), "%i", LESSON_VARIABLE_GET_FROM_OFFSET( int, pInfo->iOffset ) ); + break; + case FIELD_BOOLEAN: + case FIELD_EHANDLE: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else + { + const char *pchEventString = NULL; + + if ( event && !(event->IsEmpty( pParamName )) ) + { + pchEventString = event->GetString( pParamName ); + } + + if ( pchEventString && pchEventString[0] ) + { + Q_strcpy( eventParam_string, pchEventString ); + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else + { + // This param doesn't exist, try parsing the string + Q_strncpy( eventParam_string, pParamName, sizeof( eventParam_string ) ); + } + } + break; + + case FIELD_BOOLEAN: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_FLOAT: + eventParam_float = ( ( LESSON_VARIABLE_GET_FROM_OFFSET( float, pInfo->iOffset ) ) ? ( 1.0f ) : ( 0.0f ) ); + break; + case FIELD_INTEGER: + eventParam_float = ( ( LESSON_VARIABLE_GET_FROM_OFFSET( int, pInfo->iOffset ) ) ? ( 1.0f ) : ( 0.0f ) ); + break; + case FIELD_BOOLEAN: + eventParam_float = ( ( LESSON_VARIABLE_GET_FROM_OFFSET( bool, pInfo->iOffset ) ) ? ( 1.0f ) : ( 0.0f ) ); + break; + case FIELD_EHANDLE: + case FIELD_STRING: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else if ( event && !(event->IsEmpty( pParamName )) ) + { + eventParam_float = ( event->GetBool( pParamName ) ) ? ( 1.0f ) : ( 0.0f ); + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else if ( pParamName[ 0 ] == '0' || pParamName[ 0 ] == '1' ) + { + // This param doesn't exist, try parsing the string + eventParam_float = Q_atof( pParamName ) != 0.0f; + } + else + { + DevWarning( "Invalid event field name and not an boolean \"%s\".\n", pParamName ); + return false; + } + break; + + case FIELD_CUSTOM: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_EHANDLE: + eventParam_BaseEntity = ( LESSON_VARIABLE_GET_FROM_OFFSET( EHANDLE, pInfo->iOffset ) ).Get(); + if ( !eventParam_BaseEntity ) + { + if ( pLessonElement->bOptionalParam ) + { + // Not having an entity is fine + return true; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tPlayer param \"%s\" returned NULL.\n", pParamName ); + } + return false; + } + break; + case FIELD_FLOAT: + case FIELD_INTEGER: + case FIELD_BOOLEAN: + case FIELD_STRING: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else if ( event && !(event->IsEmpty( pParamName )) ) + { + eventParam_BaseEntity = UTIL_PlayerByUserId( event->GetInt( pParamName ) ); + if ( !eventParam_BaseEntity ) + { + if ( pLessonElement->bOptionalParam ) + { + // Not having an entity is fine + return true; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tPlayer param \"%s\" returned NULL.\n", pParamName ); + } + return false; + } + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else if ( Q_stricmp( pParamName, "null" ) == 0 ) + { + // They explicitly want a null pointer + eventParam_BaseEntity = NULL; + } + else + { + DevWarning( "Invalid event field name \"%s\".\n", pParamName ); + return false; + } + break; + + case FIELD_EHANDLE: + if ( pLessonElement->iParamVarIndex < LESSON_VARIABLE_TOTAL ) + { + // The parameter is a scripted var + const LessonVariableInfo *pInfo = GetLessonVariableInfo( pLessonElement->iParamVarIndex ); + + switch ( pInfo->varType ) + { + case FIELD_EHANDLE: + eventParam_BaseEntity = ( LESSON_VARIABLE_GET_FROM_OFFSET( EHANDLE, pInfo->iOffset ) ).Get(); + if ( !eventParam_BaseEntity ) + { + if ( pLessonElement->bOptionalParam ) + { + // Not having an entity is fine + return true; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tEntity param \"%s\" returned NULL.\n", pParamName ); + } + return false; + } + break; + case FIELD_FLOAT: + case FIELD_INTEGER: + case FIELD_BOOLEAN: + case FIELD_STRING: + case FIELD_FUNCTION: + DevWarning( "Can't use this variable type with this parameter type in lesson script.\n" ); + break; + } + } + else if ( event && !(event->IsEmpty( pParamName )) ) + { + int iEntID = event->GetInt( pParamName ); + if ( iEntID >= NUM_ENT_ENTRIES ) + { + AssertMsg( 0, "Invalid entity ID used in game event field!" ); + DevWarning( "Invalid entity ID used in game event (%s) for param (%s).", event->GetName(), pParamName ); + return false; + } + + eventParam_BaseEntity = C_BaseEntity::Instance( iEntID ); + if ( !eventParam_BaseEntity ) + { + if ( pLessonElement->bOptionalParam ) + { + // Not having an entity is fine + return true; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tEntity param \"%s\" returned NULL.\n", pParamName ); + } + return false; + } + } + else if ( pLessonElement->bOptionalParam ) + { + // We don't want to interpret this and not finding the param is still ok + return true; + } + else if ( Q_stricmp( pParamName, "null" ) == 0 ) + { + // They explicitly want a null pointer + eventParam_BaseEntity = NULL; + } + else if ( Q_stricmp( pParamName, "world" ) == 0 ) + { + // They explicitly want the world + eventParam_BaseEntity = GetClientWorldEntity(); + } + else + { + DevWarning( "Invalid event field name \"%s\".\n", pParamName ); + return false; + } + break; + + case FIELD_EMBEDDED: + { + // The parameter is a convar + ConVarRef tempCVar( pParamName ); + if ( tempCVar.IsValid() ) + { + eventParam_float = tempCVar.GetFloat(); + Q_strncpy( eventParam_string, tempCVar.GetString(), sizeof( eventParam_string ) ); + } + else + { + DevWarning( "Invalid convar name \"%s\".\n", pParamName ); + return false; + } + } + break; + } + + // Do the action to the specified variable + switch ( pLessonElement->iVariable ) + { + // Run process action macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO PROCESS_LESSON_ACTION +#define LESSON_VARIABLE_MACRO_BOOL PROCESS_LESSON_ACTION +#define LESSON_VARIABLE_MACRO_EHANDLE PROCESS_LESSON_ACTION_EHANDLE +#define LESSON_VARIABLE_MACRO_STRING PROCESS_LESSON_ACTION_STRING + LESSON_VARIABLE_FACTORY; +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + } + + return true; +} + +bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const char *pchVarName, float &fVar, const CGameInstructorSymbol *pchParamName, float fParam ) +{ + switch ( iAction ) + { + case LESSON_ACTION_SET: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + fVar = fParam; + return true; + + case LESSON_ACTION_ADD: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] += [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + fVar += fParam; + return true; + + case LESSON_ACTION_SUBTRACT: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] -= [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + fVar -= fParam; + return true; + + case LESSON_ACTION_MULTIPLY: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] *= [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + fVar *= fParam; + return true; + + case LESSON_ACTION_IS: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f ", fVar ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + return ( bNot ) ? ( fVar != fParam ) : ( fVar == fParam ); + + case LESSON_ACTION_LESS_THAN: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f ", fVar ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + return ( bNot ) ? ( fVar >= fParam ) : ( fVar < fParam ); + + case LESSON_ACTION_HAS_BIT: + { + int iTemp1 = static_cast( fVar ); + int iTemp2 = ( 1 << static_cast( fParam ) ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t([%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "0x%X ", iTemp1 ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "& [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "0x%X", iTemp2 ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") == 0\n" ) : ( ") != 0\n" ) ); + } + + return ( bNot ) ? ( ( iTemp1 & iTemp2 ) == 0 ) : ( ( iTemp1 & iTemp2 ) != 0 ); + } + + case LESSON_ACTION_BIT_COUNT_IS: + { + int iTemp1 = UTIL_CountNumBitsSet( static_cast( fVar ) ); + int iTemp2 = static_cast( fParam ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tUTIL_CountNumBitsSet([%s]) ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", iTemp1 ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( " != [%s] " ) : ( " == [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp2 ); + } + + return ( bNot ) ? ( iTemp1 != iTemp2 ) : ( iTemp1 == iTemp2 ); + } + + case LESSON_ACTION_BIT_COUNT_LESS_THAN: + { + int iTemp1 = UTIL_CountNumBitsSet( static_cast( fVar ) ); + int iTemp2 = static_cast( fParam ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tUTIL_CountNumBitsSet([%s]) ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", iTemp1 ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( " >= [%s] " ) : ( " < [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp2 ); + } + + return ( bNot ) ? ( iTemp1 >= iTemp2 ) : ( iTemp1 < iTemp2 ); + } + } + + DevWarning( "Invalid lesson action type used with \"%s\" variable type.\n", pchVarName ); + + return false; +} + +bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const char *pchVarName, int &iVar, const CGameInstructorSymbol *pchParamName, float fParam ) +{ + float fTemp = static_cast( iVar ); + bool bRetVal = ProcessElementAction( iAction, bNot, pchVarName, fTemp, pchParamName, fParam ); + + iVar = static_cast( fTemp ); + return bRetVal; +} + +bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const char *pchVarName, bool &bVar, const CGameInstructorSymbol *pchParamName, float fParam ) +{ + float fTemp = ( bVar ) ? ( 1.0f ) : ( 0.0f ); + bool bRetVal = ProcessElementAction( iAction, bNot, pchVarName, fTemp, pchParamName, fParam ); + + bVar = ( fTemp != 0.0f ); + return bRetVal; +} + +bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam ) +{ + // First try to let the mod act on the action + /*bool bModHandled = false; + bool bModReturn = Mod_ProcessElementAction( iAction, bNot, pchVarName, hVar, pchParamName, fParam, pParam, pchParam, bModHandled ); + + if ( bModHandled ) + { + return bModReturn; + }*/ + + C_BaseEntity *pVar = hVar.Get(); + + switch ( iAction ) + { + case LESSON_ACTION_SET: + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = [%s]\n", pchVarName, pchParamName->String() ); + } + + hVar = pParam; + return true; + } + + case LESSON_ACTION_IS: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t[%s] != [%s]\n" ) : ( "\t[%s] == [%s]\n" ), pchVarName, pchParamName->String() ); + } + + return ( bNot ) ? ( pVar != pParam ) : ( pVar == pParam ); + + case LESSON_ACTION_GET_DISTANCE: + { + if ( !pVar || !pParam ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->DistTo( [%s] )", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "...\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle or Param handle returned NULL!\n" ); + } + + return false; + } + + C_BasePlayer *pVarPlayer = ( pVar->IsPlayer() ? static_cast< C_BasePlayer* >( pVar ) : NULL ); + C_BasePlayer *pParamPlayer = ( pParam->IsPlayer() ? static_cast< C_BasePlayer* >( pParam ) : NULL ); + + Vector vVarPos = ( pVarPlayer ? pVarPlayer->EyePosition() : pVar->WorldSpaceCenter() ); + Vector vParamPos = ( pParamPlayer ? pParamPlayer->EyePosition() : pParam->WorldSpaceCenter() ); + + m_fOutput = vVarPos.DistTo( vParamPos ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->DistTo( [%s] ) ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", m_fOutput ); + } + + return true; + } + + case LESSON_ACTION_GET_ANGULAR_DISTANCE: + { + if ( !pVar || !pParam ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->AngularDistTo( [%s] )", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "...\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle or Param handle returned NULL!\n" ); + } + + return false; + } + + C_BasePlayer *pVarPlayer = ( pVar->IsPlayer() ? static_cast< C_BasePlayer* >( pVar ) : NULL ); + C_BasePlayer *pParamPlayer = ( pParam->IsPlayer() ? static_cast< C_BasePlayer* >( pParam ) : NULL ); + + Vector vVarPos = ( pVarPlayer ? pVarPlayer->EyePosition() : pVar->WorldSpaceCenter() ); + Vector vParamPos = ( pParamPlayer ? pParamPlayer->EyePosition() : pParam->WorldSpaceCenter() ); + + Vector vVarToParam = vParamPos - vVarPos; + VectorNormalize( vVarToParam ); + + Vector vVarForward; + + if ( pVar->IsPlayer() ) + { + AngleVectors( static_cast< C_BasePlayer* >( pVar )->EyeAngles(), &vVarForward, NULL, NULL ); + } + else + { + pVar->GetVectors( &vVarForward, NULL, NULL ); + } + + // Set the distance in degrees + m_fOutput = ( vVarToParam.Dot( vVarForward ) - 1.0f ) * -90.0f; + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->AngularDistTo( [%s] ) ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", m_fOutput ); + } + + return true; + } + + case LESSON_ACTION_GET_PLAYER_DISPLAY_NAME: + { + int iTemp = static_cast( fParam ); + + if ( iTemp <= 0 || iTemp > 2 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcpy( [stringINVALID], [%s]->GetPlayerName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tParam selecting string is out of range!\n" ); + } + + return false; + } + + // Use string2 if it was specified, otherwise, use string1 + CGameInstructorSymbol *pString; + char const *pchParamNameTemp = NULL; + + if ( iTemp == 2 ) + { + pString = &m_szString2; + pchParamNameTemp = "string2"; + } + else + { + pString = &m_szString1; + pchParamNameTemp = "string1"; + } + + if ( !pVar ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcpy( [%s], [%s]->GetPlayerName() ", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle returned NULL!\n" ); + } + + return false; + } + + *pString = pVar->GetPlayerName(); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcpy( [%s], [%s]->GetPlayerName() ", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pString->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + return true; + } + + case LESSON_ACTION_CLASSNAME_IS: + { + if ( !pVar ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t!FClassnameIs( [%s] " ) : ( "\tFClassnameIs( [%s] " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "..." ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t!FClassnameIs( [%s] " ) : ( "\tFClassnameIs( [%s] " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%s", pVar->GetClassname() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + return ( bNot ) ? ( !FClassnameIs( pVar, pchParam ) ) : ( FClassnameIs( pVar, pchParam ) ); + } + + case LESSON_ACTION_TEAM_IS: + { + int iTemp = static_cast( fParam ); + + if ( !pVar ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetTeamNumber() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetTeamNumber() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", pVar->GetTeamNumber() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp ); + } + + return ( bNot ) ? ( pVar->GetTeamNumber() != iTemp ) : ( pVar->GetTeamNumber() == iTemp ); + } + + case LESSON_ACTION_MODELNAME_IS: + { + C_BaseAnimating *pBaseAnimating = dynamic_cast( pVar ); + + if ( !pBaseAnimating ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_stricmp( [%s]->ModelName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "..." ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") != 0\n" ) : ( ") == 0\n" ) ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseAnimating returned NULL!\n" ); + } + + return false; + } + + const char *pchModelName = "-no model-"; + CStudioHdr *pModel = pBaseAnimating->GetModelPtr(); + if ( pModel ) + { + const studiohdr_t *pRenderHDR = pModel->GetRenderHdr(); + if ( pRenderHDR ) + { + pchModelName = pRenderHDR->name; + } + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_stricmp( [%s]->ModelName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%s", pchModelName ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") != 0\n" ) : ( ") == 0\n" ) ); + } + + return ( bNot ) ? ( Q_stricmp( pchModelName, pchParam ) != 0 ) : ( Q_stricmp( pchModelName, pchParam ) == 0 ); + } + + case LESSON_ACTION_HEALTH_LESS_THAN: + { + int iTemp = static_cast( fParam ); + + if ( !pVar ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetHealth() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetHealth() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", pVar->GetHealth() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i\n", iTemp ); + } + + return ( bNot ) ? ( pVar->GetHealth() >= iTemp ) : ( pVar->GetHealth() < iTemp ); + } + + case LESSON_ACTION_HEALTH_PERCENTAGE_LESS_THAN: + { + if ( !pVar ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f ", pVar->HealthFraction() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam ); + } + + float fHealthPercentage = 1.0f; + + if ( pVar->GetMaxHealth() != 0.0f ) + { + fHealthPercentage = pVar->HealthFraction(); + } + + return ( bNot ) ? ( fHealthPercentage >= fParam ) : ( fHealthPercentage < fParam ); + } + + case LESSON_ACTION_GET_ACTIVE_WEAPON: + { + int iTemp = static_cast( fParam ); + + if ( iTemp <= 0 || iTemp > 2 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[entityINVALID] = [%s]->GetActiveWeapon()\n", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tParam selecting string is out of range!\n" ); + } + + return false; + } + + // Use entity2 if it was specified, otherwise, use entity1 + CHandle *pHandle; + + char const *pchParamNameTemp = NULL; + + if ( iTemp == 2 ) + { + pHandle = &m_hEntity2; + pchParamNameTemp = "entity2"; + } + else + { + pHandle = &m_hEntity1; + pchParamNameTemp = "entity1"; + } + + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = [%s]->GetActiveWeapon()", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + pHandle->Set( pBaseCombatCharacter->GetActiveWeapon() ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = [%s]->GetActiveWeapon()", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"\n", pchParam ); + } + + return true; + } + + case LESSON_ACTION_WEAPON_IS: + { + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->GetName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"\n", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + CBaseCombatWeapon *pBaseCombatWeapon = pBaseCombatCharacter->GetActiveWeapon(); + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->GetName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"\n", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetActiveWeapon returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->GetName() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pBaseCombatWeapon->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "!= [%s] " ) : ( "== [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"\n", pchParam ); + } + + return ( bNot ) ? ( Q_stricmp( pBaseCombatWeapon->GetName(), pchParam ) != 0 ) : ( Q_stricmp( pBaseCombatWeapon->GetName(), pchParam ) == 0 ); + } + + case LESSON_ACTION_WEAPON_HAS: + { + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->Weapon_OwnsThisType([%s] " ) : ( "\t[%s]->Weapon_OwnsThisType([%s] " ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->Weapon_OwnsThisType([%s] " ) : ( "\t[%s]->Weapon_OwnsThisType([%s] " ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + return ( bNot ) ? ( pBaseCombatCharacter->Weapon_OwnsThisType( pchParam ) == NULL ) : ( pBaseCombatCharacter->Weapon_OwnsThisType( pchParam ) != NULL ); + } + + case LESSON_ACTION_GET_ACTIVE_WEAPON_SLOT: + { + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->Weapon_GetActiveSlot() ...\n", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + C_BaseCombatWeapon *pWeapon = pBaseCombatCharacter->GetActiveWeapon(); + + if ( !pWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->Weapon_GetActiveSlot() ...\n", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetActiveWeapon returned NULL!\n" ); + } + + return false; + } + + // @TODO + /*m_fOutput = pBaseCombatCharacter->Weapon_GetSlot( pWeapon->GetWpnData().szClassName ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->Weapon_GetSlot() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", m_fOutput ); + }*/ + + return true; + } + + case LESSON_ACTION_GET_WEAPON_SLOT: + { + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->Weapon_GetSlot([%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ") ...\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + // @TODO + /*m_fOutput = pBaseCombatCharacter->Weapon_GetSlot( pchParam ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[output] = [%s]->Weapon_GetSlot([%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ") " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", m_fOutput ); + }*/ + + return true; + } + + case LESSON_ACTION_GET_WEAPON_IN_SLOT: + { + int nTemp = static_cast( fParam ); + + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[entity1] = [%s]->GetWeapon([%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%i\"", nTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + m_hEntity1 = pBaseCombatCharacter->GetWeapon( nTemp ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[entity1] = [%s]->GetWeapon([%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%i\"", nTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + return true; + } + + case LESSON_ACTION_CLIP_PERCENTAGE_LESS_THAN: + { + C_BaseCombatCharacter *pBaseCombatCharacter = NULL; + + if ( pVar ) + { + pBaseCombatCharacter = pVar->MyCombatCharacterPointer(); + } + + if ( !pBaseCombatCharacter ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->Clip1Percentage() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%.1f\n", fParam ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BaseCombatCharacter returned NULL!\n" ); + } + + return false; + } + + CBaseCombatWeapon *pBaseCombatWeapon = pBaseCombatCharacter->GetActiveWeapon(); + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->Clip1Percentage() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%.1f\n", fParam ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetActiveWeapon returned NULL!\n" ); + } + + return false; + } + + float fClip1Percentage = 100.0f; + + if ( pBaseCombatWeapon->UsesClipsForAmmo1() ) + { + fClip1Percentage = 100.0f * ( static_cast( pBaseCombatWeapon->Clip1() ) / static_cast( pBaseCombatWeapon->GetMaxClip1() ) ); + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetActiveWeapon()->Clip1Percentage() ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%.1f ", fClip1Percentage ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%.1f\n", fParam ); + } + + return ( bNot ) ? ( fClip1Percentage >= fParam ) : ( fClip1Percentage < fParam ); + } + + case LESSON_ACTION_WEAPON_AMMO_LOW: + { + int iTemp = static_cast( fParam ); + + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetWeaponInSlot( ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ")->AmmoPercentage() >= 30\n" ) : ( ")->AmmoPercentage() < 30\n" ) ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BasePlayer returned NULL!\n" ); + } + + return false; + } + + CBaseCombatWeapon *pBaseCombatWeapon = NULL; + + // Get the weapon in variable slot + for ( int iWeapon = 0; iWeapon < MAX_WEAPONS; iWeapon++ ) + { + CBaseCombatWeapon *pBaseCombatWeaponTemp = pBasePlayer->GetWeapon( iWeapon ); + if ( pBaseCombatWeaponTemp ) + { + if ( pBaseCombatWeaponTemp->GetSlot() == iTemp ) + { + pBaseCombatWeapon = pBaseCombatWeaponTemp; + break; + } + } + } + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetWeaponInSlot( ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ")->AmmoPercentage() >= 30\n" ) : ( ")->AmmoPercentage() < 30\n" ) ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetActiveWeapon returned NULL!\n" ); + } + + return false; + } + + // Check if the ammo is full + int iAmmoType = pBaseCombatWeapon->GetPrimaryAmmoType(); + int iMaxAmmo = GetAmmoDef()->MaxCarry( iAmmoType/*, pBasePlayer*/ ); + int iPlayerAmmo = pBasePlayer->GetAmmoCount( iAmmoType ); + + bool bAmmoLow = ( iPlayerAmmo < ( iMaxAmmo / 3 ) ); + + if ( bNot ) + { + bAmmoLow = !bAmmoLow; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->GetWeaponInSlot( ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ")->AmmoPercentage() >= 30 " ) : ( ")->AmmoPercentage() < 30 " ) ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bAmmoLow ) ? ( "true\n" ) : ( "false\n" ) ); + } + + return bAmmoLow; + } + + case LESSON_ACTION_WEAPON_AMMO_FULL: + { + int iTemp = static_cast( fParam ); + + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoFull()\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BasePlayer returned NULL!\n" ); + } + + return false; + } + + CBaseCombatWeapon *pBaseCombatWeapon = NULL; + + // Get the weapon in variable slot + for ( int iWeapon = 0; iWeapon < MAX_WEAPONS; iWeapon++ ) + { + CBaseCombatWeapon *pBaseCombatWeaponTemp = pBasePlayer->GetWeapon( iWeapon ); + if ( pBaseCombatWeaponTemp ) + { + if ( pBaseCombatWeaponTemp->GetSlot() == iTemp ) + { + pBaseCombatWeapon = pBaseCombatWeaponTemp; + break; + } + } + } + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoFull()\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetWeaponInSlot returned NULL!\n" ); + } + + return false; + } + + // Check if the ammo is full + int iAmmoType = pBaseCombatWeapon->GetPrimaryAmmoType(); + int iMaxAmmo = GetAmmoDef()->MaxCarry( iAmmoType/*, pBasePlayer*/ ); + int iPlayerAmmo = pBasePlayer->GetAmmoCount( iAmmoType ); + + bool bAmmoFull = ( iPlayerAmmo >= iMaxAmmo ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoFull() " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, ( bAmmoFull ) ? ( "true\n" ) : ( "false\n" ) ); + } + + return ( bNot ) ? ( !bAmmoFull ) : ( bAmmoFull ); + } + + case LESSON_ACTION_WEAPON_AMMO_EMPTY: + { + int iTemp = static_cast( fParam ); + + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoEmpty()\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BasePlayer returned NULL!\n" ); + } + + return false; + } + + CBaseCombatWeapon *pBaseCombatWeapon = NULL; + + // Get the weapon in variable slot + for ( int iWeapon = 0; iWeapon < MAX_WEAPONS; iWeapon++ ) + { + CBaseCombatWeapon *pBaseCombatWeaponTemp = pBasePlayer->GetWeapon( iWeapon ); + if ( pBaseCombatWeaponTemp ) + { + if ( pBaseCombatWeaponTemp->GetSlot() == iTemp ) + { + pBaseCombatWeapon = pBaseCombatWeaponTemp; + break; + } + } + } + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoEmpty()\n" ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar GetWeaponInSlot returned NULL!\n" ); + } + + return false; + } + + // Check if the ammo is empty + int iAmmoType = pBaseCombatWeapon->GetPrimaryAmmoType(); + int iPlayerAmmo = pBasePlayer->GetAmmoCount( iAmmoType ); + + bool bAmmoEmpty = ( iPlayerAmmo <= 0 ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->GetWeaponInSlot( " ) : ( "\t[%s]->GetWeaponInSlot( " ), pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "%i ", iTemp ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")->AmmoEmpty() " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, ( bAmmoEmpty ) ? ( "true" ) : ( "false" ) ); + ConColorMsg(CBaseLesson::m_rgbaVerbosePlain, " )\n" ); + } + + return ( bNot ) ? ( !bAmmoEmpty ) : ( bAmmoEmpty ); + } + + /*case LESSON_ACTION_WEAPON_CAN_USE: + { + C_BaseCombatWeapon *pBaseCombatWeapon = dynamic_cast( pParam ); + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->Weapon_CanUse([%s])\n" ) : ( "\t[%s]->Weapon_CanUse([%s])\n" ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as BasePlayer returned NULL!\n" ); + } + + return false; + } + + if ( !pBaseCombatWeapon ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->Weapon_CanUse([%s])\n" ) : ( "\t[%s]->Weapon_CanUse([%s])\n" ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tParam BaseCombatWeapon returned NULL!\n" ); + } + + return false; + } + + bool bCanEquip = pBasePlayer->Weapon_CanUse( pBaseCombatWeapon ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\t![%s]->Weapon_CanUse([%s]) " ) : ( "\t[%s]->Weapon_CanUse([%s]) " ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, ( bCanEquip ) ? ( "true\n" ) : ( "false\n" ) ); + } + + return ( bNot ) ? ( !bCanEquip ) : ( bCanEquip ); + }*/ + + case LESSON_ACTION_USE_TARGET_IS: + { + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\tC_BaseEntity::Instance([%s]->GetUseEntity()) != [%s]\n" ) : ( "\tC_BaseEntity::Instance([%s]->GetUseEntity()) == [%s]\n" ), pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as Player returned NULL!\n" ); + } + + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( "\tC_BaseEntity::Instance([%s]->GetUseEntity()) != [%s]\n" ) : ( "\tC_BaseEntity::Instance([%s]->GetUseEntity()) == [%s]\n" ), pchVarName, pchParamName->String() ); + } + + return ( bNot ) ? ( C_BaseEntity::Instance( pBasePlayer->GetUseEntity() ) != pParam ) : ( C_BaseEntity::Instance( pBasePlayer->GetUseEntity() ) == pParam ); + } + + case LESSON_ACTION_GET_USE_TARGET: + { + int iTemp = static_cast( fParam ); + + if ( iTemp <= 0 || iTemp > 2 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[entityINVALID] = C_BaseEntity::Instance([%s]->GetUseEntity())\n", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tParam selecting string is out of range!\n" ); + } + + return false; + } + + // Use entity2 if it was specified, otherwise, use entity1 + CHandle *pHandle; + char const *pchParamNameTemp = NULL; + + if ( iTemp == 2 ) + { + pHandle = &m_hEntity2; + pchParamNameTemp = "entity2"; + } + else + { + pHandle = &m_hEntity1; + pchParamNameTemp = "entity1"; + } + + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = C_BaseEntity::Instance([%s]->GetUseEntity())\n", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as Player returned NULL!\n" ); + } + + return false; + } + + pHandle->Set( C_BaseEntity::Instance( pBasePlayer->GetUseEntity() ) ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = C_BaseEntity::Instance([%s]->GetUseEntity())\n", pchParamNameTemp, pchVarName ); + } + + return true; + } + + /*case LESSON_ACTION_GET_POTENTIAL_USE_TARGET: + { + int iTemp = static_cast( fParam ); + + if ( iTemp <= 0 || iTemp > 2 ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[entityINVALID] = C_BaseEntity::Instance([%s]->GetPotentialUseEntity())\n", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tParam selecting string is out of range!\n" ); + } + + return false; + } + + // Use entity2 if it was specified, otherwise, use entity1 + CHandle *pHandle; + char const *pchParamNameTemp = NULL; + + if ( iTemp == 2 ) + { + pHandle = &m_hEntity2; + pchParamNameTemp = "entity2"; + } + else + { + pHandle = &m_hEntity1; + pchParamNameTemp = "entity1"; + } + + C_BasePlayer *pBasePlayer = ToBasePlayer( pVar ); + + if ( !pBasePlayer ) + { + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = C_BaseEntity::Instance([%s]->GetPotentialUseEntity())\n", pchParamNameTemp, pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\tVar handle as Player returned NULL!\n" ); + } + + return false; + } + + pHandle->Set( C_BaseEntity::Instance( pBasePlayer->GetPotentialUseEntity() ) ); + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s] = C_BaseEntity::Instance([%s]->GetPotentialUseEntity())\n", pchParamNameTemp, pchVarName ); + } + + return true; + }*/ + } + + DevWarning( "Invalid lesson action type used with \"%s\" variable type.\n", pchVarName ); + + return false; +} + +bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const char *pchVarName, CGameInstructorSymbol *pchVar, const CGameInstructorSymbol *pchParamName, const char *pchParam ) +{ + switch ( iAction ) + { + case LESSON_ACTION_REFERENCE_OPEN: + { + const CBaseLesson *pLesson = GetGameInstructor().GetLesson( pchParamName->String() ); + if ( !pLesson ) + { + DevWarning( "Invalid lesson specified: \"%s\".", pchParamName->String() ); + return false; + } + + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( Color( 64, 128, 255, 255 ), ( bNot ) ? ( "\t!( [\"%s\"]->IsInstanceActive() " ) : ( "\t( [\"%s\"]->IsInstanceActive() " ), pchParamName->String() ); + ConColorMsg( Color( 255, 255, 255, 255 ), "\"%s\"", (pLesson->IsInstanceActive() ? "true" : "false") ); + ConColorMsg( Color( 64, 128, 255, 255 ), " )\n" ); + } + + return ( bNot ) ? ( !pLesson->IsInstanceActive() ) : ( pLesson->IsInstanceActive() ); + } + + case LESSON_ACTION_SET: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcpy([%s], [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + *pchVar = pchParam; + return true; + + case LESSON_ACTION_ADD: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcat([%s], [%s] ", pchVarName, pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ")\n" ); + } + + char szTemp[ 256 ]; + Q_strncpy( szTemp, pchVar->String(), sizeof( szTemp ) ); + Q_strncat( szTemp, pchParam, sizeof( szTemp ) ); + + *pchVar = szTemp; + return true; + + case LESSON_ACTION_IS: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcmp([%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchVar->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") != 0\n" ) : ( ") == 0\n" ) ); + } + + return ( bNot ) ? ( Q_strcmp( pchVar->String(), pchParam ) != 0 ) : ( Q_strcmp( pchVar->String(), pchParam ) == 0 ); + + case LESSON_ACTION_HAS_PREFIX: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tStringHasPrefix([%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchVar->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") == false\n" ) : ( ") == true\n" ) ); + } + + return ( bNot ) ? ( !StringHasPrefix( pchVar->String(), pchParam ) ) : ( StringHasPrefix( pchVar->String(), pchParam ) ); + + case LESSON_ACTION_LESS_THAN: + if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() ) + { + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\tQ_strcmp([%s] ", pchVarName ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\"%s\"", pchVar->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ", [%s] ", pchParamName->String() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\"%s\"", pchParam ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ") >= 0\n" ) : ( ") < 0\n" ) ); + } + + return ( bNot ) ? ( Q_strcmp( pchVar->String(), pchParam ) >= 0 ) : ( Q_strcmp( pchVar->String(), pchParam ) < 0 ); + } + + DevWarning( "Invalid lesson action type used with \"%s\" variable type.\n", pchVarName ); + + return false; +} + +LessonEvent_t * CScriptedIconLesson::AddOpenEvent() +{ + int iNewLessonEvent = m_OpenEvents.AddToTail(); + return &(m_OpenEvents[ iNewLessonEvent ]); +} + +LessonEvent_t * CScriptedIconLesson::AddCloseEvent() +{ + int iNewLessonEvent = m_CloseEvents.AddToTail(); + return &(m_CloseEvents[ iNewLessonEvent ]); +} + +LessonEvent_t * CScriptedIconLesson::AddSuccessEvent() +{ + int iNewLessonEvent = m_SuccessEvents.AddToTail(); + return &(m_SuccessEvents[ iNewLessonEvent ]); +} + +LessonEvent_t * CScriptedIconLesson::AddOnOpenEvent() +{ + int iNewLessonEvent = m_OnOpenEvents.AddToTail(); + return &(m_OnOpenEvents[ iNewLessonEvent ]); +} + +LessonEvent_t * CScriptedIconLesson::AddUpdateEvent() +{ + int iNewLessonEvent = m_UpdateEvents.AddToTail(); + return &(m_UpdateEvents[ iNewLessonEvent ]); +} + +// Static method to init the keyvalues symbols used for comparisons +void CScriptedIconLesson::PreReadLessonsFromFile() +{ + static bool bFirstTime = true; + if ( !bFirstTime ) + return; + bFirstTime = false; + + // Run init info call macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_VARIABLE_INIT_SYMBOL +#define LESSON_VARIABLE_MACRO_BOOL LESSON_VARIABLE_INIT_SYMBOL +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_VARIABLE_INIT_SYMBOL +#define LESSON_VARIABLE_MACRO_STRING LESSON_VARIABLE_INIT_SYMBOL + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + + // And build the map of variable name to enum + // Run string to int macros on all scriptable variables (see: LESSON_VARIABLE_FACTORY definition) +#define LESSON_VARIABLE_MACRO LESSON_SCRIPT_STRING_ADD_TO_MAP +#define LESSON_VARIABLE_MACRO_BOOL LESSON_SCRIPT_STRING_ADD_TO_MAP +#define LESSON_VARIABLE_MACRO_EHANDLE LESSON_SCRIPT_STRING_ADD_TO_MAP +#define LESSON_VARIABLE_MACRO_STRING LESSON_SCRIPT_STRING_ADD_TO_MAP + LESSON_VARIABLE_FACTORY +#undef LESSON_VARIABLE_MACRO +#undef LESSON_VARIABLE_MACRO_BOOL +#undef LESSON_VARIABLE_MACRO_EHANDLE +#undef LESSON_VARIABLE_MACRO_STRING + + // Set up mapping of field types + g_TypeToParamTypeMap.Insert( "float", FIELD_FLOAT ); + g_TypeToParamTypeMap.Insert( "string", FIELD_STRING ); + g_TypeToParamTypeMap.Insert( "int", FIELD_INTEGER ); + g_TypeToParamTypeMap.Insert( "integer", FIELD_INTEGER ); + g_TypeToParamTypeMap.Insert( "short", FIELD_INTEGER ); + g_TypeToParamTypeMap.Insert( "long", FIELD_INTEGER ); + g_TypeToParamTypeMap.Insert( "bool", FIELD_BOOLEAN ); + g_TypeToParamTypeMap.Insert( "player", FIELD_CUSTOM ); + g_TypeToParamTypeMap.Insert( "entity", FIELD_EHANDLE ); + g_TypeToParamTypeMap.Insert( "convar", FIELD_EMBEDDED ); + g_TypeToParamTypeMap.Insert( "void", FIELD_VOID ); + + // Set up the lesson action map + + CScriptedIconLesson::LessonActionMap.Insert( "scope in", LESSON_ACTION_SCOPE_IN ); + CScriptedIconLesson::LessonActionMap.Insert( "scope out", LESSON_ACTION_SCOPE_OUT ); + CScriptedIconLesson::LessonActionMap.Insert( "close", LESSON_ACTION_CLOSE ); + CScriptedIconLesson::LessonActionMap.Insert( "success", LESSON_ACTION_SUCCESS ); + CScriptedIconLesson::LessonActionMap.Insert( "lock", LESSON_ACTION_LOCK ); + CScriptedIconLesson::LessonActionMap.Insert( "present complete", LESSON_ACTION_PRESENT_COMPLETE ); + CScriptedIconLesson::LessonActionMap.Insert( "present start", LESSON_ACTION_PRESENT_START ); + CScriptedIconLesson::LessonActionMap.Insert( "present end", LESSON_ACTION_PRESENT_END ); + + CScriptedIconLesson::LessonActionMap.Insert( "reference open", LESSON_ACTION_REFERENCE_OPEN ); + + CScriptedIconLesson::LessonActionMap.Insert( "set", LESSON_ACTION_SET ); + CScriptedIconLesson::LessonActionMap.Insert( "add", LESSON_ACTION_ADD ); + CScriptedIconLesson::LessonActionMap.Insert( "subtract", LESSON_ACTION_SUBTRACT ); + CScriptedIconLesson::LessonActionMap.Insert( "multiply", LESSON_ACTION_MULTIPLY ); + CScriptedIconLesson::LessonActionMap.Insert( "is", LESSON_ACTION_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "less than", LESSON_ACTION_LESS_THAN ); + CScriptedIconLesson::LessonActionMap.Insert( "has prefix", LESSON_ACTION_HAS_PREFIX ); + CScriptedIconLesson::LessonActionMap.Insert( "has bit", LESSON_ACTION_HAS_BIT ); + CScriptedIconLesson::LessonActionMap.Insert( "bit count is", LESSON_ACTION_BIT_COUNT_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "bit count less than", LESSON_ACTION_BIT_COUNT_LESS_THAN ); + + CScriptedIconLesson::LessonActionMap.Insert( "get distance", LESSON_ACTION_GET_DISTANCE ); + CScriptedIconLesson::LessonActionMap.Insert( "get angular distance", LESSON_ACTION_GET_ANGULAR_DISTANCE ); + CScriptedIconLesson::LessonActionMap.Insert( "get player display name", LESSON_ACTION_GET_PLAYER_DISPLAY_NAME ); + CScriptedIconLesson::LessonActionMap.Insert( "classname is", LESSON_ACTION_CLASSNAME_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "modelname is", LESSON_ACTION_MODELNAME_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "team is", LESSON_ACTION_TEAM_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "health less than", LESSON_ACTION_HEALTH_LESS_THAN ); + CScriptedIconLesson::LessonActionMap.Insert( "health percentage less than", LESSON_ACTION_HEALTH_PERCENTAGE_LESS_THAN ); + CScriptedIconLesson::LessonActionMap.Insert( "get active weapon", LESSON_ACTION_GET_ACTIVE_WEAPON ); + CScriptedIconLesson::LessonActionMap.Insert( "weapon is", LESSON_ACTION_WEAPON_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "weapon has", LESSON_ACTION_WEAPON_HAS ); + CScriptedIconLesson::LessonActionMap.Insert( "get active weapon slot", LESSON_ACTION_GET_ACTIVE_WEAPON_SLOT ); + CScriptedIconLesson::LessonActionMap.Insert( "get weapon slot", LESSON_ACTION_GET_WEAPON_SLOT ); + CScriptedIconLesson::LessonActionMap.Insert( "get weapon in slot", LESSON_ACTION_GET_WEAPON_IN_SLOT ); + CScriptedIconLesson::LessonActionMap.Insert( "clip percentage less than", LESSON_ACTION_CLIP_PERCENTAGE_LESS_THAN); + CScriptedIconLesson::LessonActionMap.Insert( "weapon ammo low", LESSON_ACTION_WEAPON_AMMO_LOW ); + CScriptedIconLesson::LessonActionMap.Insert( "weapon ammo full", LESSON_ACTION_WEAPON_AMMO_FULL ); + CScriptedIconLesson::LessonActionMap.Insert( "weapon ammo empty", LESSON_ACTION_WEAPON_AMMO_EMPTY ); + CScriptedIconLesson::LessonActionMap.Insert( "weapon can use", LESSON_ACTION_WEAPON_CAN_USE ); + CScriptedIconLesson::LessonActionMap.Insert( "use target is", LESSON_ACTION_USE_TARGET_IS ); + CScriptedIconLesson::LessonActionMap.Insert( "get use target", LESSON_ACTION_GET_USE_TARGET ); + CScriptedIconLesson::LessonActionMap.Insert( "get potential use target", LESSON_ACTION_GET_POTENTIAL_USE_TARGET ); + + // Add mod actions to the map + //Mod_PreReadLessonsFromFile(); +} diff --git a/game/client/c_baselesson.h b/game/client/c_baselesson.h new file mode 100644 index 00000000..b413d282 --- /dev/null +++ b/game/client/c_baselesson.h @@ -0,0 +1,460 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Purpose: Client handler for instruction players how to play +// +//=============================================================================// + +#ifndef _C_BASELESSON_H_ +#define _C_BASELESSON_H_ + + +#include "GameEventListener.h" +#include "hud_locator_target.h" + + +#define DECLARE_LESSON( _lessonClassName, _baseLessonClassName ) \ + typedef _baseLessonClassName BaseClass;\ + typedef _lessonClassName ThisClass;\ + _lessonClassName( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity )\ + : _baseLessonClassName( pchName, bIsDefaultHolder, bIsOpenOpportunity )\ + {\ + Init();\ + } + + +enum LessonInstanceType +{ + LESSON_INSTANCE_MULTIPLE, + LESSON_INSTANCE_SINGLE_OPEN, + LESSON_INSTANCE_FIXED_REPLACE, + LESSON_INSTANCE_SINGLE_ACTIVE, + + LESSON_INSTANCE_TYPE_TOTAL +}; + + +// This is used to solve a problem where bots can take the place of a player, where on or the other don't have valid entities on the client at the same time +#define MAX_DELAYED_PLAYER_SWAPS 8 + +struct delayed_player_swap_t +{ + CHandle *phHandleToChange; + int iNewUserID; + + delayed_player_swap_t( void ) + { + phHandleToChange = NULL; + iNewUserID = -1; + } +}; + + +abstract_class CBaseLesson : public CGameEventListener +{ +public: + CBaseLesson( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity ); + virtual ~CBaseLesson( void ); + + void AddPrerequisite( const char *pchLessonName ); + + const CGameInstructorSymbol& GetNameSymbol( void ) const { return m_stringName; } + const char * GetName( void ) const { return m_stringName.String(); } + int GetPriority( void ) const { return m_iPriority; } + const char * GetCloseReason( void ) const { return m_stringCloseReason.String(); } + void SetCloseReason( const char *pchReason ) { m_stringCloseReason = pchReason; } + + CBaseLesson* GetRoot( void ) const { return m_pRoot; } + void SetRoot( CBaseLesson *pRoot ); + const CUtlVector < CBaseLesson * >* GetChildren( void ) const { return &m_OpenOpportunities; } + + float GetInitTime( void ) { return m_fInitTime; } + void SetStartTime( void ) { m_fStartTime = gpGlobals->curtime; } + void ResetStartTime( void ) { m_fStartTime = 0.0f; m_bHasPlayedSound = false; } + + bool ShouldShowSpew( void ); + bool NoPriority( void ) const; + bool IsDefaultHolder( void ) const { return m_bIsDefaultHolder; } + bool IsOpenOpportunity( void ) const { return m_bIsOpenOpportunity; } + bool IsLocked( void ) const; + bool CanOpenWhenDead( void ) const { return m_bCanOpenWhenDead; } + bool IsInstructing( void ) const { return ( m_fStartTime > 0.0f ); } + bool IsLearned( void ) const; + bool PrerequisitesHaveBeenMet( void ) const; + bool IsTimedOut( void ); + + int InstanceType( void ) const { return m_iInstanceType; } + const CGameInstructorSymbol& GetReplaceKeySymbol( void ) const { return m_stringReplaceKey; } + const char* GetReplaceKey( void ) const { return m_stringReplaceKey.String(); } + int GetFixedInstancesMax( void ) const { return m_iFixedInstancesMax; } + bool ShouldReplaceOnlyWhenStopped( void ) const { return m_bReplaceOnlyWhenStopped; } + void SetInstanceActive( bool bInstanceActive ) { m_bInstanceActive = bInstanceActive; } + bool IsInstanceActive( void ) const { return m_bInstanceActive; } + + void ResetDisplaysAndSuccesses( void ); + bool IncDisplayCount( void ); + bool IncSuccessCount( void ); + void SetDisplayCount( int iDisplayCount ) { m_iDisplayCount = iDisplayCount; } + void SetSuccessCount( int iSuccessCount ) { m_iSuccessCount = iSuccessCount; } + int GetDisplayCount( void ) const { return m_iDisplayCount; } + int GetSuccessCount( void ) const { return m_iSuccessCount; } + int GetDisplayLimit( void ) const { return m_iDisplayLimit; } + int GetSuccessLimit( void ) const { return m_iSuccessLimit; } + + void Init( void ); // NOT virtual, each constructor calls their own + virtual void InitPrerequisites( void ) {}; + virtual void Start( void ) = 0; + virtual void Stop( void ) = 0; + virtual void OnOpen( void ) {}; + virtual void Update( void ) {}; + virtual void UpdateInactive( void ) {}; + + virtual bool ShouldDisplay( void ) const { return true; } + virtual bool IsVisible( void ) const { return true; } + virtual bool WasDisplayed( void ) const { return m_bWasDisplayed ? true : false; } + virtual void SwapOutPlayers( int iOldUserID, int iNewUserID ) {} + virtual void TakePlaceOf( CBaseLesson *pLesson ); + + const char *GetGroup() { return m_szLessonGroup.String(); } + void SetEnabled( bool bEnabled ) { m_bDisabled = !bEnabled; } + +protected: + void MarkSucceeded( void ); + void CloseOpportunity( const char *pchReason ); + bool DoDelayedPlayerSwaps( void ) const; + +private: + + CBaseLesson *m_pRoot; + CUtlVector < CBaseLesson * > m_OpenOpportunities; + CUtlVector < const CBaseLesson * > m_Prerequisites; + + CGameInstructorSymbol m_stringCloseReason; + CGameInstructorSymbol m_stringName; + + bool m_bInstanceActive : 1; + bool m_bSuccessCounted : 1; + bool m_bIsDefaultHolder : 1; + bool m_bIsOpenOpportunity : 1; + +protected: + LessonInstanceType m_iInstanceType; + + int m_iPriority; + CGameInstructorSymbol m_stringReplaceKey; + int m_iFixedInstancesMax; + bool m_bReplaceOnlyWhenStopped; + int m_iTeam; + bool m_bOnlyKeyboard; + bool m_bOnlyGamepad; + + int m_iDisplayLimit; + int m_iDisplayCount; + bool m_bWasDisplayed; + int m_iSuccessLimit; + int m_iSuccessCount; + + float m_fLockDuration; + float m_fTimeout; + float m_fInitTime; + float m_fStartTime; + float m_fLockTime; + float m_fUpdateInterval; + bool m_bHasPlayedSound; + + CGameInstructorSymbol m_szStartSound; + CGameInstructorSymbol m_szLessonGroup; + + bool m_bCanOpenWhenDead; + bool m_bBumpWithTimeoutWhenLearned; + bool m_bCanTimeoutWhileInactive; + bool m_bDisabled; + + // Right now we can only queue up 4 swaps... + // this number can be increased if more entity handle scripted variables are added + mutable delayed_player_swap_t m_pDelayedPlayerSwap[ MAX_DELAYED_PLAYER_SWAPS ]; + mutable int m_iNumDelayedPlayerSwaps; + +public: + + // Colors for console spew in verbose mode + static Color m_rgbaVerboseHeader; + static Color m_rgbaVerbosePlain; + static Color m_rgbaVerboseName; + static Color m_rgbaVerboseOpen; + static Color m_rgbaVerboseClose; + static Color m_rgbaVerboseSuccess; + static Color m_rgbaVerboseUpdate; +}; + + +class CTextLesson : public CBaseLesson +{ +public: + DECLARE_LESSON( CTextLesson, CBaseLesson ); + + void Init( void ); // NOT virtual, each constructor calls their own + virtual void Start( void ); + virtual void Stop( void ); + +protected: + + CGameInstructorSymbol m_szDisplayText; + CGameInstructorSymbol m_szDisplayParamText; + CGameInstructorSymbol m_szBinding; + CGameInstructorSymbol m_szGamepadBinding; +}; + + +class CIconLesson : public CTextLesson +{ +public: + DECLARE_LESSON( CIconLesson, CTextLesson ); + + void Init( void ); // NOT virtual, each constructor calls their own + virtual void Start( void ); + virtual void Stop( void ); + virtual void Update( void ); + virtual void UpdateInactive( void ); + + virtual bool ShouldDisplay( void ) const; + virtual bool IsVisible( void ) const; + virtual void SwapOutPlayers( int iOldUserID, int iNewUserID ); + virtual void TakePlaceOf( CBaseLesson *pLesson ); + + void SetLocatorBinding( CLocatorTarget * pLocatorTarget ); + + const char *GetCaptionColorString() { return m_szCaptionColor.String(); } + + bool IsPresentComplete( void ); + void PresentStart( void ); + void PresentEnd( void ); + +private: + virtual void UpdateLocatorTarget( CLocatorTarget *pLocatorTarget, C_BaseEntity *pIconTarget ); + +#ifdef MAPBASE + Vector GetIconTargetPosition( C_BaseEntity *pIconTarget ); +#endif + +protected: + CHandle m_hIconTarget; + CGameInstructorSymbol m_szVguiTargetName; + CGameInstructorSymbol m_szVguiTargetLookup; + int m_nVguiTargetEdge; + float m_flUpOffset; + float m_flRelativeUpOffset; + float m_fFixedPositionX; + float m_fFixedPositionY; + + int m_hLocatorTarget; + int m_iFlags; + + float m_fRange; + float m_fCurrentDistance; + float m_fOnScreenStartTime; + float m_fUpdateDistanceTime; + + CGameInstructorSymbol m_szOnscreenIcon; + CGameInstructorSymbol m_szOffscreenIcon; + CGameInstructorSymbol m_szCaptionColor; + + bool m_bFixedPosition; + bool m_bNoIconTarget; + bool m_bAllowNodrawTarget; + bool m_bVisible; + bool m_bShowWhenOccluded; + bool m_bNoOffscreen; + bool m_bForceCaption; + +#ifdef MAPBASE + int m_iIconTargetPos; + + enum + { + ICON_TARGET_EYE_POSITION, + ICON_TARGET_ORIGIN, + ICON_TARGET_CENTER, + }; + + CGameInstructorSymbol m_szHudHint; +#endif +}; + +enum LessonAction +{ + LESSON_ACTION_NONE, + + LESSON_ACTION_SCOPE_IN, + LESSON_ACTION_SCOPE_OUT, + LESSON_ACTION_CLOSE, + LESSON_ACTION_SUCCESS, + LESSON_ACTION_LOCK, + LESSON_ACTION_PRESENT_COMPLETE, + LESSON_ACTION_PRESENT_START, + LESSON_ACTION_PRESENT_END, + + LESSON_ACTION_REFERENCE_OPEN, + + LESSON_ACTION_SET, + LESSON_ACTION_ADD, + LESSON_ACTION_SUBTRACT, + LESSON_ACTION_MULTIPLY, + LESSON_ACTION_IS, + LESSON_ACTION_LESS_THAN, + LESSON_ACTION_HAS_PREFIX, + LESSON_ACTION_HAS_BIT, + LESSON_ACTION_BIT_COUNT_IS, + LESSON_ACTION_BIT_COUNT_LESS_THAN, + + LESSON_ACTION_GET_DISTANCE, + LESSON_ACTION_GET_ANGULAR_DISTANCE, + LESSON_ACTION_GET_PLAYER_DISPLAY_NAME, + LESSON_ACTION_CLASSNAME_IS, + LESSON_ACTION_MODELNAME_IS, + LESSON_ACTION_TEAM_IS, + LESSON_ACTION_HEALTH_LESS_THAN, + LESSON_ACTION_HEALTH_PERCENTAGE_LESS_THAN, + LESSON_ACTION_GET_ACTIVE_WEAPON, + LESSON_ACTION_WEAPON_IS, + LESSON_ACTION_WEAPON_HAS, + LESSON_ACTION_GET_ACTIVE_WEAPON_SLOT, + LESSON_ACTION_GET_WEAPON_SLOT, + LESSON_ACTION_GET_WEAPON_IN_SLOT, + LESSON_ACTION_CLIP_PERCENTAGE_LESS_THAN, + LESSON_ACTION_WEAPON_AMMO_LOW, + LESSON_ACTION_WEAPON_AMMO_FULL, + LESSON_ACTION_WEAPON_AMMO_EMPTY, + LESSON_ACTION_WEAPON_CAN_USE, + LESSON_ACTION_USE_TARGET_IS, + LESSON_ACTION_GET_USE_TARGET, + LESSON_ACTION_GET_POTENTIAL_USE_TARGET, + + // Enum continued in Mod_LessonAction + LESSON_ACTION_MOD_START, +}; + +struct LessonElement_t +{ + int iVariable; + int iParamVarIndex; + int iAction; + _fieldtypes paramType; + CGameInstructorSymbol szParam; + bool bNot : 1; + bool bOptionalParam : 1; + + LessonElement_t( int p_iVariable, int p_iAction, bool p_bNot, bool p_bOptionalParam, const char *pchParam, int p_iParamVarIndex, _fieldtypes p_paramType ) + { + iVariable = p_iVariable; + iAction = p_iAction; + bNot = p_bNot; + bOptionalParam = p_bOptionalParam; + szParam = pchParam; + iParamVarIndex = p_iParamVarIndex; + paramType = p_paramType; + } + + LessonElement_t( const LessonElement_t &p_LessonElement ) + { + iVariable = p_LessonElement.iVariable; + iAction = p_LessonElement.iAction; + bNot = p_LessonElement.bNot; + bOptionalParam = p_LessonElement.bOptionalParam; + szParam = p_LessonElement.szParam; + iParamVarIndex = p_LessonElement.iParamVarIndex; + paramType = p_LessonElement.paramType; + } +}; + +struct LessonEvent_t +{ + CUtlVector< LessonElement_t > elements; + CGameInstructorSymbol szEventName; +}; + +class CScriptedIconLesson : public CIconLesson +{ +public: + DECLARE_LESSON( CScriptedIconLesson, CIconLesson ) + + virtual ~CScriptedIconLesson( void ); + + static void PreReadLessonsFromFile( void ); + static void Mod_PreReadLessonsFromFile( void ); + + void Init( void ); // NOT virtual, each constructor calls their own + virtual void InitPrerequisites( void ); + virtual void OnOpen( void ); + virtual void Update( void ); + + virtual void SwapOutPlayers( int iOldUserID, int iNewUserID ); + + virtual void FireGameEvent( IGameEvent *event ); + virtual void ProcessOpenGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ); + virtual void ProcessCloseGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ); + virtual void ProcessSuccessGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event ); + + CUtlVector< LessonEvent_t >& GetOpenEvents( void ) { return m_OpenEvents; } + CUtlVector< LessonEvent_t >& GetCloseEvents( void ) { return m_CloseEvents; } + CUtlVector< LessonEvent_t >& GetSuccessEvents( void ) { return m_SuccessEvents; } + CUtlVector< LessonEvent_t >& GetOnOpenEvents( void ) { return m_OnOpenEvents; } + CUtlVector< LessonEvent_t >& GetUpdateEvents( void ) { return m_UpdateEvents; } + + bool ProcessElements( IGameEvent *event, const CUtlVector< LessonElement_t > *pElements ); + +private: + void InitElementsFromKeys( CUtlVector< LessonElement_t > *pLessonElements, KeyValues *pKey ); + void InitElementsFromElements( CUtlVector< LessonElement_t > *pLessonElements, const CUtlVector< LessonElement_t > *pLessonElements2 ); + + void InitFromKeys( KeyValues *pKey ); + + bool ProcessElement( IGameEvent *event, const LessonElement_t *pLessonElement, bool bInFailedScope ); + + bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, float &bVar, const CGameInstructorSymbol *pchParamName, float fParam ); + bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, int &bVar, const CGameInstructorSymbol *pchParamName, float fParam ); + bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, bool &bVar, const CGameInstructorSymbol *pchParamName, float fParam ); + bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam ); + bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, CGameInstructorSymbol *pchVar, const CGameInstructorSymbol *pchParamName, const char *pchParam ); + + // Implemented per mod so they can have custom actions + bool Mod_ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam, bool &bModHandled ); + + LessonEvent_t * AddOpenEvent( void ); + LessonEvent_t * AddCloseEvent( void ); + LessonEvent_t * AddSuccessEvent( void ); + LessonEvent_t * AddOnOpenEvent( void ); + LessonEvent_t * AddUpdateEvent( void ); + +private: + static CUtlDict< int, int > LessonActionMap; + + EHANDLE m_hLocalPlayer; + float m_fOutput; + CHandle m_hEntity1; + CHandle m_hEntity2; + CGameInstructorSymbol m_szString1; + CGameInstructorSymbol m_szString2; + int m_iInteger1; + int m_iInteger2; + float m_fFloat1; + float m_fFloat2; + + CUtlVector< CGameInstructorSymbol > m_PrerequisiteNames; + CUtlVector< LessonEvent_t > m_OpenEvents; + CUtlVector< LessonEvent_t > m_CloseEvents; + CUtlVector< LessonEvent_t > m_SuccessEvents; + CUtlVector< LessonEvent_t > m_OnOpenEvents; + CUtlVector< LessonEvent_t > m_UpdateEvents; + + float m_fUpdateEventTime; + CScriptedIconLesson *m_pDefaultHolder; + + int m_iScopeDepth; + + // Need this to get offsets to scripted variables + friend class LessonVariableInfo; + friend int LessonActionFromString( const char *pchName ); +}; + + +#endif // _C_BASELESSON_H_ diff --git a/game/client/c_baseplayer.cpp b/game/client/c_baseplayer.cpp index b87d6a35..9d97c7bf 100644 --- a/game/client/c_baseplayer.cpp +++ b/game/client/c_baseplayer.cpp @@ -54,6 +54,10 @@ #include "econ_wearable.h" #endif +#ifdef MAPBASE +#include "viewrender.h" +#endif + // NVNT haptics system interface #include "haptics/ihaptics.h" @@ -70,6 +74,7 @@ int g_nKillCamTarget1 = 0; int g_nKillCamTarget2 = 0; extern ConVar mp_forcecamera; // in gamevars_shared.h +extern ConVar r_flashlightfov; #define FLASHLIGHT_DISTANCE 1000 #define MAX_VGUI_INPUT_MODE_SPEED 30 @@ -122,9 +127,6 @@ ConVar demo_fov_override( "demo_fov_override", "0", FCVAR_CLIENTDLL | FCVAR_DONT ConVar cl_meathook_neck_pivot_ingame_up( "cl_meathook_neck_pivot_ingame_up", "7.0" ); ConVar cl_meathook_neck_pivot_ingame_fwd( "cl_meathook_neck_pivot_ingame_fwd", "3.0" ); -static ConVar cl_clean_textures_on_death( "cl_clean_textures_on_death", "0", FCVAR_DEVELOPMENTONLY, "If enabled, attempts to purge unused textures every time a freeze cam is shown" ); - - void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut ); void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut ); void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void *pOut ); @@ -132,6 +134,16 @@ void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void void RecvProxy_ObserverTarget( const CRecvProxyData *pData, void *pStruct, void *pOut ); void RecvProxy_ObserverMode ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#ifdef MAPBASE +// Needs to shift bits back +void RecvProxy_ShiftPlayerSpawnflags( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_BasePlayer *pPlayer = (C_BasePlayer *)pStruct; + + pPlayer->m_spawnflags = (pData->m_Value.m_Int) << 16; +} +#endif + // -------------------------------------------------------------------------------- // // RecvTable for CPlayerState. // -------------------------------------------------------------------------------- // @@ -179,6 +191,11 @@ BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local ) // 3d skybox data RecvPropInt(RECVINFO(m_skybox3d.scale)), RecvPropVector(RECVINFO(m_skybox3d.origin)), +#ifdef MAPBASE + RecvPropVector(RECVINFO(m_skybox3d.angles)), + RecvPropEHandle(RECVINFO(m_skybox3d.skycamera)), + RecvPropInt( RECVINFO( m_skybox3d.skycolor ), 0, RecvProxy_IntToColor32 ), +#endif RecvPropInt(RECVINFO(m_skybox3d.area)), // 3d skybox fog data @@ -190,6 +207,9 @@ BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local ) RecvPropFloat( RECVINFO( m_skybox3d.fog.start ) ), RecvPropFloat( RECVINFO( m_skybox3d.fog.end ) ), RecvPropFloat( RECVINFO( m_skybox3d.fog.maxdensity ) ), +#ifdef MAPBASE + RecvPropFloat( RECVINFO( m_skybox3d.fog.farz ) ), +#endif // fog data RecvPropEHandle( RECVINFO( m_PlayerFog.m_hCtrl ) ), @@ -206,6 +226,14 @@ BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local ) RecvPropInt( RECVINFO( m_audio.soundscapeIndex ) ), RecvPropInt( RECVINFO( m_audio.localBits ) ), RecvPropEHandle( RECVINFO( m_audio.ent ) ), + + //Tony; tonemap stuff! -- TODO! Optimize this with bit sizes from env_tonemap_controller. + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flTonemapScale ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flTonemapRate ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flBloomScale ) ), + + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flAutoExposureMin ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flAutoExposureMax ) ), END_RECV_TABLE() // -------------------------------------------------------------------------------- // @@ -248,6 +276,15 @@ END_RECV_TABLE() RecvPropInt ( RECVINFO( m_nWaterLevel ) ), RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )), +#ifdef MAPBASE + // Transmitted from the server for internal player spawnflags. + // See baseplayer_shared.h for more details. + RecvPropInt ( RECVINFO( m_spawnflags ), 0, RecvProxy_ShiftPlayerSpawnflags ), + + RecvPropBool ( RECVINFO( m_bDrawPlayerModelExternally ) ), + RecvPropBool ( RECVINFO( m_bInTriggerFall ) ), +#endif + END_RECV_TABLE() @@ -296,6 +333,11 @@ END_RECV_TABLE() RecvPropString( RECVINFO(m_szLastPlaceName) ), +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropEHandle( RECVINFO( m_hPostProcessCtrl ) ), // Send to everybody - for spectating + RecvPropEHandle( RECVINFO( m_hColorCorrectionCtrl ) ), // Send to everybody - for spectating +#endif + #if defined USES_ECON_ITEMS RecvPropUtlVector( RECVINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, RecvPropEHandle(NULL, 0, 0) ), #endif @@ -399,7 +441,10 @@ BEGIN_PREDICTION_DATA( C_BasePlayer ) END_PREDICTION_DATA() +// link this in each derived player class, like the server!! +#if 0 LINK_ENTITY_TO_CLASS( player, C_BasePlayer ); +#endif // -------------------------------------------------------------------------------- // // Functions. @@ -413,6 +458,8 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf m_vecOldViewAngles.Init(); #endif + m_pFlashlight = NULL; + m_pCurrentVguiScreen = NULL; m_pCurrentCommand = NULL; @@ -437,10 +484,6 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf m_bFiredWeapon = false; m_nForceVisionFilterFlags = 0; - m_nLocalPlayerVisionFlags = 0; - - ConVarRef scissor("r_flashlightscissor"); - scissor.SetValue("0"); ListenForGameEvent( "base_player_teleported" ); } @@ -454,10 +497,16 @@ C_BasePlayer::~C_BasePlayer() if ( this == s_pLocalPlayer ) { s_pLocalPlayer = NULL; + +#ifdef MAPBASE_VSCRIPT + if ( g_pScriptVM ) + { + g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL ); + } +#endif } - FlashlightEffectManager().TurnOffFlashlight(true); - m_bFlashlightEnabled = false; + delete m_pFlashlight; } @@ -547,7 +596,6 @@ CBaseEntity *C_BasePlayer::GetObserverTarget() const // returns players target o case OBS_MODE_FIXED: // view from a fixed camera position case OBS_MODE_IN_EYE: // follow a player in first person view case OBS_MODE_CHASE: // follow a player in third person view - case OBS_MODE_POI: // PASSTIME point of interest - game objective, big fight, anything interesting case OBS_MODE_ROAMING: // free roaming return m_hObserverTarget; break; @@ -642,7 +690,6 @@ int C_BasePlayer::GetObserverMode() const case OBS_MODE_FIXED: // view from a fixed camera position case OBS_MODE_IN_EYE: // follow a player in first person view case OBS_MODE_CHASE: // follow a player in third person view - case OBS_MODE_POI: // PASSTIME point of interest - game objective, big fight, anything interesting case OBS_MODE_ROAMING: // free roaming return m_iObserverMode; break; @@ -813,6 +860,14 @@ void C_BasePlayer::PostDataUpdate( DataUpdateType_t updateType ) // changed level, which would cause the snd_soundmixer to be left modified. ConVar *pVar = (ConVar *)cvar->FindVar( "snd_soundmixer" ); pVar->Revert(); + +#ifdef MAPBASE_VSCRIPT + // Moved here from LevelInitPostEntity, which is executed before local player is spawned. + if ( g_pScriptVM ) + { + g_pScriptVM->SetValue( "player", GetScriptInstance() ); + } +#endif } } @@ -888,10 +943,6 @@ void C_BasePlayer::PostDataUpdate( DataUpdateType_t updateType ) // Force the sound mixer to the freezecam mixer ConVar *pVar = (ConVar *)cvar->FindVar( "snd_soundmixer" ); pVar->SetValue( "FreezeCam_Only" ); - - // When we start, give unused textures an opportunity to unload - if ( cl_clean_textures_on_death.GetBool() ) - g_pMaterialSystem->UncacheUnusedMaterials( false ); } else if ( m_bWasFreezeFraming && GetObserverMode() != OBS_MODE_FREEZECAM ) { @@ -909,14 +960,6 @@ void C_BasePlayer::PostDataUpdate( DataUpdateType_t updateType ) m_nForceVisionFilterFlags = 0; CalculateVisionUsingCurrentFlags(); } - - // force calculate vision when the local vision flags changed - int nCurrentLocalPlayerVisionFlags = GetLocalPlayerVisionFilterFlags(); - if ( m_nLocalPlayerVisionFlags != nCurrentLocalPlayerVisionFlags ) - { - CalculateVisionUsingCurrentFlags(); - m_nLocalPlayerVisionFlags = nCurrentLocalPlayerVisionFlags; - } } // If we are updated while paused, allow the player origin to be snapped by the @@ -965,6 +1008,16 @@ void C_BasePlayer::OnRestore() input->ClearInputButton( IN_ATTACK | IN_ATTACK2 ); // GetButtonBits() has to be called for the above to take effect input->GetButtonBits( 0 ); + +#ifdef MAPBASE_VSCRIPT + // HACK: (03/25/09) Then the player goes across a transition it doesn't spawn and register + // it's instance. We're hacking around this for now, but this will go away when we get around to + // having entities cross transitions and keep their script state. + if ( g_pScriptVM ) + { + g_pScriptVM->SetValue( "player", GetScriptInstance() ); + } +#endif } // For ammo history icons to current value so they don't flash on level transtions @@ -1074,6 +1127,16 @@ void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd ) // If we're in vgui mode *and* we're holding down mouse buttons, // stay in vgui mode even if we're outside the screen bounds +#ifdef VGUI_SCREEN_FIX + if (m_pCurrentVguiScreen.Get() && (pCmd->buttons & (IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT))) + { + SetVGuiScreenButtonState( m_pCurrentVguiScreen.Get(), pCmd->buttons ); + + // Kill all attack inputs if we're in vgui screen mode + pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT); + return; + } +#else if (m_pCurrentVguiScreen.Get() && (pCmd->buttons & (IN_ATTACK | IN_ATTACK2)) ) { SetVGuiScreenButtonState( m_pCurrentVguiScreen.Get(), pCmd->buttons ); @@ -1082,6 +1145,7 @@ void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd ) pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2); return; } +#endif // We're not in vgui input mode if we're moving, or have hit a key // that will make us move... @@ -1203,7 +1267,12 @@ bool C_BasePlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd ) m_vecOldViewAngles = pCmd->viewangles; // Check to see if we're in vgui input mode... +#ifdef VGUI_SCREEN_FIX + if(pCmd->buttons & IN_VALIDVGUIINPUT) + DetermineVguiInputMode( pCmd ); +#else DetermineVguiInputMode( pCmd ); +#endif return true; } @@ -1217,95 +1286,66 @@ void C_BasePlayer::TeamChange( int iNewTeam ) // Base class does nothing } + //----------------------------------------------------------------------------- // Purpose: Creates, destroys, and updates the flashlight effect as needed. //----------------------------------------------------------------------------- void C_BasePlayer::UpdateFlashlight() { - // TERROR: if we're in-eye spectating, use that player's flashlight - C_BasePlayer *pFlashlightPlayer = this; - if ( !IsAlive() ) - { - if ( GetObserverMode() == OBS_MODE_IN_EYE ) - { - pFlashlightPlayer = ToBasePlayer( GetObserverTarget() ); - } - } - - if ( pFlashlightPlayer ) - { - FlashlightEffectManager().SetEntityIndex( pFlashlightPlayer->index ); - } - // The dim light is the flashlight. - if ( pFlashlightPlayer && pFlashlightPlayer->IsAlive() && pFlashlightPlayer->IsEffectActive( EF_DIMLIGHT ) ) + if ( IsEffectActive( EF_DIMLIGHT ) ) { - // Make sure we're using the proper flashlight texture - const char *pszTextureName = pFlashlightPlayer->GetFlashlightTextureName(); - if ( !m_bFlashlightEnabled ) - { - // Turned on the headlight; create it. - if ( pszTextureName ) - { - FlashlightEffectManager().TurnOnFlashlight( pFlashlightPlayer->index, pszTextureName, pFlashlightPlayer->GetFlashlightFOV(), - pFlashlightPlayer->GetFlashlightFarZ(), pFlashlightPlayer->GetFlashlightLinearAtten() ); - } - else - { - FlashlightEffectManager().TurnOnFlashlight( pFlashlightPlayer->index ); - } - m_bFlashlightEnabled = true; - } + // Turned on the headlight; create it. + FlashlightEffectManager().TurnOnFlashlight( index, GetFlashlightTextureName(), GetFlashlightFOV(), + GetFlashlightFarZ(), GetFlashlightLinearAtten() ); + } - else if ( m_bFlashlightEnabled ) + else { // Turned off the flashlight; delete it. FlashlightEffectManager().TurnOffFlashlight(); - m_bFlashlightEnabled = false; } - if ( pFlashlightPlayer && m_bFlashlightEnabled ) - { - Vector vecForward, vecRight, vecUp; - Vector vecPos; - //Check to see if we have an externally specified flashlight origin, if not, use eye vectors/render origin - if ( pFlashlightPlayer->m_vecFlashlightOrigin != vec3_origin && pFlashlightPlayer->m_vecFlashlightOrigin.IsValid() ) - { - vecPos = pFlashlightPlayer->m_vecFlashlightOrigin; - vecForward = pFlashlightPlayer->m_vecFlashlightForward; - vecRight = pFlashlightPlayer->m_vecFlashlightRight; - vecUp = pFlashlightPlayer->m_vecFlashlightUp; - } - else - { - EyeVectors( &vecForward, &vecRight, &vecUp ); - vecPos = GetRenderOrigin() + m_vecViewOffset; - } + Vector vecForward, vecRight, vecUp; + EyeVectors( &vecForward, &vecRight, &vecUp ); - // Update the light with the new position and direction. - FlashlightEffectManager().UpdateFlashlight( vecPos, vecForward, vecRight, vecUp, pFlashlightPlayer->GetFlashlightFOV(), - pFlashlightPlayer->CastsFlashlightShadows(), pFlashlightPlayer->GetFlashlightFarZ(), pFlashlightPlayer->GetFlashlightLinearAtten(), - pFlashlightPlayer->GetFlashlightTextureName() ); - } + // Update the light with the new position and direction. + FlashlightEffectManager().UpdateFlashlight( EyePosition(), vecForward, vecRight, vecUp, GetFlashlightFOV(), + CastsFlashlightShadows(), GetFlashlightFarZ(), GetFlashlightLinearAtten(), + GetFlashlightTextureName() ); } //----------------------------------------------------------------------------- -// Purpose: Creates player flashlight if it's active +// Purpose: Creates player flashlight if it's ative //----------------------------------------------------------------------------- -void C_BasePlayer::Flashlight(void) +void C_BasePlayer::Flashlight() { UpdateFlashlight(); -} + // Check for muzzle flash and apply to view model + C_BaseAnimating *ve = this; + if ( GetObserverMode() == OBS_MODE_IN_EYE ) + { + ve = dynamic_cast< C_BaseAnimating* >( GetObserverTarget() ); + } +} //----------------------------------------------------------------------------- // Purpose: Turns off flashlight if it's active (TERROR) //----------------------------------------------------------------------------- -void C_BasePlayer::TurnOffFlashlight(void) +void C_BasePlayer::TurnOffFlashlight() { FlashlightEffectManager().TurnOffFlashlight(); } +//----------------------------------------------------------------------------- +// Purpose: Turns off flashlight if it's active (TERROR) +//----------------------------------------------------------------------------- +float C_BasePlayer::GetFlashlightFOV() const +{ + return r_flashlightfov.GetFloat(); +} + //----------------------------------------------------------------------------- // Purpose: Engine is asking whether to add this player to the visible entities list @@ -1338,7 +1378,10 @@ void C_BasePlayer::AddEntity( void ) // Add in lighting effects CreateLightEffects(); - SetLocalAnglesDim(X_INDEX, 0); + +#ifdef MAPBASE + SetLocalAnglesDim( X_INDEX, 0 ); +#endif } extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz ); @@ -1445,11 +1488,35 @@ bool C_BasePlayer::ShouldInterpolate() bool C_BasePlayer::ShouldDraw() { +#ifdef MAPBASE + // We have to "always draw" a player with m_bDrawPlayerModelExternally in order to show up in whatever rendering list all of the views use, + // but we can't put this in ShouldDrawThisPlayer() because we would have no way of knowing if it stomps the other checks that draw the player model anyway. + // As a result, we have to put it here in the central ShouldDraw() function. DrawModel() makes sure we only draw in non-main views and nothing's drawing the model anyway. + return (ShouldDrawThisPlayer() || m_bDrawPlayerModelExternally) && BaseClass::ShouldDraw(); +#else return ShouldDrawThisPlayer() && BaseClass::ShouldDraw(); +#endif } int C_BasePlayer::DrawModel( int flags ) { +#ifdef MAPBASE + if (m_bDrawPlayerModelExternally) + { + // Draw the player in any view except the main or "intro" view, both of which are default first-person views. + // HACKHACK: Also don't draw in shadow depth textures if the player's flashlight is on, as that causes the playermodel to block it. + view_id_t viewID = CurrentViewID(); + if (viewID == VIEW_MAIN || viewID == VIEW_INTRO_CAMERA || (viewID == VIEW_SHADOW_DEPTH_TEXTURE && IsEffectActive(EF_DIMLIGHT))) + { + // Make sure the player model wouldn't draw anyway... + if (!ShouldDrawThisPlayer()) + return 0; + } + + return BaseClass::DrawModel( flags ); + } +#endif + #ifndef PORTAL // In Portal this check is already performed as part of // C_Portal_Player::DrawModel() @@ -1458,9 +1525,42 @@ int C_BasePlayer::DrawModel( int flags ) return 0; } #endif + return BaseClass::DrawModel( flags ); } +#ifdef MAPBASE +ConVar cl_player_allow_thirdperson_projtex( "cl_player_allow_thirdperson_projtex", "1", FCVAR_NONE, "Allows players to receive projected textures if they're non-local or in third person." ); +ConVar cl_player_allow_thirdperson_rttshadows( "cl_player_allow_thirdperson_rttshadows", "0", FCVAR_NONE, "Allows players to cast RTT shadows if they're non-local or in third person." ); +ConVar cl_player_allow_firstperson_projtex( "cl_player_allow_firstperson_projtex", "1", FCVAR_NONE, "Allows players to receive projected textures even if they're in first person." ); +ConVar cl_player_allow_firstperson_rttshadows( "cl_player_allow_firstperson_rttshadows", "0", FCVAR_NONE, "Allows players to cast RTT shadows even if they're in first person." ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ShadowType_t C_BasePlayer::ShadowCastType() +{ + if ( (!IsLocalPlayer() || ShouldDraw()) ? !cl_player_allow_thirdperson_rttshadows.GetBool() : !cl_player_allow_firstperson_rttshadows.GetBool() ) + return SHADOWS_NONE; + + if ( !IsVisible() ) + return SHADOWS_NONE; + + return SHADOWS_RENDER_TO_TEXTURE_DYNAMIC; +} + +//----------------------------------------------------------------------------- +// Should this object receive shadows? +//----------------------------------------------------------------------------- +bool C_BasePlayer::ShouldReceiveProjectedTextures( int flags ) +{ + if ( (!IsLocalPlayer() || ShouldDraw()) ? !cl_player_allow_thirdperson_projtex.GetBool() : !cl_player_allow_firstperson_projtex.GetBool() ) + return false; + + return BaseClass::ShouldReceiveProjectedTextures( flags ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1582,7 +1682,14 @@ void C_BasePlayer::CalcChaseCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& } } - if ( target && !target->IsPlayer() && target->IsNextBot() ) + // SDK TODO + if ( target && target->IsBaseTrain() ) + { + // if this is a train, we want to be back a little further so we can see more of it + flMaxDistance *= 2.5f; + m_flObserverChaseDistance = flMaxDistance; + } + else if ( target && !target->IsPlayer() && target->IsNextBot() ) { // if this is a boss, we want to be back a little further so we can see more of it flMaxDistance *= 2.5f; @@ -1915,6 +2022,12 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson ) } } } + else + { + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if ( pWeapon ) + pWeapon->ThirdPersonSwitch( bThirdperson ); + } } @@ -2138,7 +2251,7 @@ void C_BasePlayer::GetToolRecordingState( KeyValues *msg ) // then this code can (should!) be removed if ( state.m_bThirdPerson ) { - const Vector& cam_ofs = g_ThirdPersonManager.GetCameraOffsetAngles(); + Vector cam_ofs = g_ThirdPersonManager.GetCameraOffsetAngles(); QAngle camAngles; camAngles[ PITCH ] = cam_ofs[ PITCH ]; @@ -2654,7 +2767,7 @@ void C_BasePlayer::NotePredictionError( const Vector &vDelta ) // offset curtime and setup bones at that time using fake interpolation // fake interpolation means we don't have reliable interpolation history (the local player doesn't animate locally) // so we just modify cycle and origin directly and use that as a fake guess -bool C_BasePlayer::ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset ) +void C_BasePlayer::ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset ) { // we don't have any interpolation data, so fake it float cycle = m_flCycle; @@ -2669,37 +2782,30 @@ bool C_BasePlayer::ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOu m_flCycle = fmod( 10 + cycle + m_flPlaybackRate * curtimeOffset, 1.0f ); SetLocalOrigin( origin + curtimeOffset * GetLocalVelocity() ); // Setup bone state to extrapolate physics velocity - bool bSuccess = SetupBones( pBonesOut, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime + curtimeOffset ); + SetupBones( pBonesOut, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime + curtimeOffset ); m_flCycle = cycle; SetLocalOrigin( origin ); - return bSuccess; } -bool C_BasePlayer::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) +void C_BasePlayer::GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) { if ( !IsLocalPlayer() ) - return BaseClass::GetRagdollInitBoneArrays(pDeltaBones0, pDeltaBones1, pCurrentBones, boneDt); - - bool bSuccess = true; - - if ( !ForceSetupBonesAtTimeFakeInterpolation( pDeltaBones0, -boneDt ) ) - bSuccess = false; - if ( !ForceSetupBonesAtTimeFakeInterpolation( pDeltaBones1, 0 ) ) - bSuccess = false; - + { + BaseClass::GetRagdollInitBoneArrays(pDeltaBones0, pDeltaBones1, pCurrentBones, boneDt); + return; + } + ForceSetupBonesAtTimeFakeInterpolation( pDeltaBones0, -boneDt ); + ForceSetupBonesAtTimeFakeInterpolation( pDeltaBones1, 0 ); float ragdollCreateTime = PhysGetSyncCreateTime(); if ( ragdollCreateTime != gpGlobals->curtime ) { - if ( !ForceSetupBonesAtTimeFakeInterpolation( pCurrentBones, ragdollCreateTime - gpGlobals->curtime ) ) - bSuccess = false; + ForceSetupBonesAtTimeFakeInterpolation( pCurrentBones, ragdollCreateTime - gpGlobals->curtime ); } else { - if ( !SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime ) ) - bSuccess = false; + SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime ); } - return bSuccess; } @@ -2863,6 +2969,24 @@ void C_BasePlayer::UpdateFogBlend( void ) } } +#ifdef MAPBASE // From Alien Swarm SDK +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +C_PostProcessController* C_BasePlayer::GetActivePostProcessController() const +{ + return m_hPostProcessCtrl.Get(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +C_ColorCorrection* C_BasePlayer::GetActiveColorCorrection() const +{ + return m_hColorCorrectionCtrl.Get(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -2905,7 +3029,6 @@ void C_BasePlayer::UpdateWearables( void ) { pItem->ValidateModelIndex(); pItem->UpdateVisibility(); - pItem->CreateShadow(); } } } diff --git a/game/client/c_baseplayer.h b/game/client/c_baseplayer.h index 0efc79f5..00eab8fe 100644 --- a/game/client/c_baseplayer.h +++ b/game/client/c_baseplayer.h @@ -23,6 +23,10 @@ #include "hintsystem.h" #include "SoundEmitterSystem/isoundemittersystembase.h" #include "c_env_fog_controller.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "c_postprocesscontroller.h" +#include "c_colorcorrection.h" +#endif #include "igameevents.h" #include "GameEventListener.h" @@ -37,6 +41,7 @@ class C_BaseViewModel; class C_FuncLadder; class CFlashlightEffect; class C_EconWearable; +class C_PostProcessController; extern int g_nKillCamMode; extern int g_nKillCamTarget1; @@ -169,7 +174,7 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener virtual IRagdoll* GetRepresentativeRagdoll() const; // override the initial bone position for ragdolls - virtual bool GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) OVERRIDE; + 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 ); @@ -182,19 +187,19 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener virtual void TeamChange( int iNewTeam ); // Flashlight - void Flashlight(void); - virtual void UpdateFlashlight(void); - void TurnOffFlashlight(void); - virtual const char* GetFlashlightTextureName(void) const { return NULL; } - virtual float GetFlashlightFOV(void) const { return 0.0f; } - virtual float GetFlashlightFarZ(void) const { return 0.0f; } - virtual float GetFlashlightLinearAtten(void) const { return 0.0f; } - virtual bool CastsFlashlightShadows(void) const { return false; } - virtual void GetFlashlightOffset(const Vector& vecForward, const Vector& vecRight, const Vector& vecUp, Vector* pVecOffset) const; - Vector m_vecFlashlightOrigin; - Vector m_vecFlashlightForward; - Vector m_vecFlashlightUp; - Vector m_vecFlashlightRight; + void Flashlight(); + virtual void UpdateFlashlight(); + void TurnOffFlashlight(); + virtual const char *GetFlashlightTextureName() const { return "effects/flashlight002"; } + virtual float GetFlashlightFOV() const; + virtual float GetFlashlightFarZ() const { return 750.0f; } + virtual float GetFlashlightLinearAtten() const { return 100.0f; } + virtual bool CastsFlashlightShadows() { return true; } + virtual void GetFlashlightOffset( const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, Vector *pVecOffset ) const; + Vector m_vecFlashlightOrigin; + Vector m_vecFlashlightForward; + Vector m_vecFlashlightUp; + Vector m_vecFlashlightRight; // Weapon selection code virtual bool IsAllowedToSwitchWeapons( void ) { return !IsObserver(); } @@ -213,6 +218,11 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener void SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; } float MaxSpeed() const { return m_flMaxspeed; } +#ifdef MAPBASE + // See c_baseplayer.cpp + virtual ShadowType_t ShadowCastType(); + virtual bool ShouldReceiveProjectedTextures( int flags ); +#else // Should this object cast shadows? virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; } @@ -220,6 +230,7 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener { return false; } +#endif bool IsLocalPlayer( void ) const; @@ -390,6 +401,11 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener void UpdateFogController( void ); void UpdateFogBlend( void ); +#ifdef MAPBASE // From Alien Swarm SDK + C_PostProcessController* GetActivePostProcessController() const; + C_ColorCorrection* GetActiveColorCorrection() const; +#endif + float GetFOVTime( void ){ return m_flFOVTime; } virtual void OnAchievementAchieved( int iAchievement ) {} @@ -399,7 +415,7 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener #if defined USES_ECON_ITEMS // Wearables - virtual void UpdateWearables(); + void UpdateWearables(); C_EconWearable *GetWearable( int i ) { return m_hMyWearables[i]; } int GetNumWearables( void ) { return m_hMyWearables.Count(); } #endif @@ -454,20 +470,35 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener float m_flConstraintWidth; float m_flConstraintSpeedFactor; +#ifdef MAPBASE + // Transmitted from the server for internal player spawnflags. + // See baseplayer_shared.h for more details. + int m_spawnflags; + + inline bool HasSpawnFlags( int flags ) { return (m_spawnflags & flags) != 0; } + inline void RemoveSpawnFlags( int flags ) { m_spawnflags &= ~flags; } + inline void AddSpawnFlags( int flags ) { m_spawnflags |= flags; } + + // Allows the player's model to draw on non-main views, like monitors or mirrors. + bool m_bDrawPlayerModelExternally; + + bool m_bInTriggerFall; +#endif + protected: + //Tony; made all of these virtual so mods can override. virtual void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); - void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles, - float& zNear, float& zFar, float& fov ); + virtual 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 ); + virtual void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); virtual void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); virtual float GetDeathCamInterpolationTime(); virtual void CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); - void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov); + virtual 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... @@ -536,8 +567,9 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener bool m_bFiredWeapon; + // Player flashlight dynamic light pointers - bool m_bFlashlightEnabled; + CFlashlightEffect *m_pFlashlight; typedef CHandle CBaseCombatWeaponHandle; CNetworkVar( CBaseCombatWeaponHandle, m_hLastWeapon ); @@ -595,7 +627,7 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener 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; } - bool ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset ); + void ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset ); float m_flLaggedMovementValue; @@ -621,7 +653,6 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener float m_flNextAchievementAnnounceTime; int m_nForceVisionFilterFlags; // Force our vision filter to a specific setting - int m_nLocalPlayerVisionFlags; #if defined USES_ECON_ITEMS // Wearables @@ -639,6 +670,11 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener // One for left and one for right side of step StepSoundCache_t m_StepSoundCache[ 2 ]; +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkHandle( C_PostProcessController, m_hPostProcessCtrl ); // active postprocessing controller + CNetworkHandle( C_ColorCorrection, m_hColorCorrectionCtrl ); // active FXVolume color correction +#endif + public: const char *GetLastKnownPlaceName( void ) const { return m_szLastPlaceName; } // return the last nav place name the player occupied diff --git a/game/client/c_basetempentity.h b/game/client/c_basetempentity.h index 2f3740ea..d462461c 100644 --- a/game/client/c_basetempentity.h +++ b/game/client/c_basetempentity.h @@ -55,7 +55,6 @@ class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable virtual void NotifyShouldTransmit( ShouldTransmitState_t state ); virtual void PreDataUpdate( DataUpdateType_t updateType ); virtual void PostDataUpdate( DataUpdateType_t updateType ); - virtual void OnDataUnchangedInPVS( void ) { } virtual void OnPreDataChanged( DataUpdateType_t updateType ); virtual void OnDataChanged( DataUpdateType_t updateType ); virtual void SetDormant( bool bDormant ); diff --git a/game/client/c_baseviewmodel.cpp b/game/client/c_baseviewmodel.cpp index 28c804fb..6e73e155 100644 --- a/game/client/c_baseviewmodel.cpp +++ b/game/client/c_baseviewmodel.cpp @@ -18,9 +18,6 @@ #include "tools/bonelist.h" #include #include "hltvcamera.h" -#ifdef TF_CLIENT_DLL - #include "tf_weaponbase.h" -#endif #if defined( REPLAY_ENABLED ) #include "replay/replaycamera.h" @@ -35,7 +32,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#ifdef CSTRIKE_DLL +#if defined(CSTRIKE_DLL) || defined (MAPBASE) ConVar cl_righthand( "cl_righthand", "1", FCVAR_ARCHIVE, "Use right-handed view models." ); #endif @@ -56,8 +53,8 @@ void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ) // 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) - // NOTE: viewx was coming in as 0 when folks set their viewmodel_fov to 0 and show their weapon. - float factorX = viewx ? ( worldx / viewx ) : 0.0f; + float factorX = worldx / viewx; + float factorY = factorX; // Get the coordinates in the viewer's space. @@ -197,7 +194,7 @@ bool C_BaseViewModel::Interpolate( float currentTime ) bool C_BaseViewModel::ShouldFlipViewModel() { -#ifdef CSTRIKE_DLL +#if defined(CSTRIKE_DLL) || defined (MAPBASE) // If cl_righthand is set, then we want them all right-handed. CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); if ( pWeapon ) @@ -334,16 +331,6 @@ int C_BaseViewModel::DrawModel( int flags ) } } -#ifdef TF_CLIENT_DLL - CTFWeaponBase* pTFWeapon = dynamic_cast( pWeapon ); - if ( ( flags & STUDIO_RENDER ) && pTFWeapon && pTFWeapon->m_viewmodelStatTrakAddon ) - { - pTFWeapon->m_viewmodelStatTrakAddon->RemoveEffects( EF_NODRAW ); - pTFWeapon->m_viewmodelStatTrakAddon->DrawModel( flags ); - pTFWeapon->m_viewmodelStatTrakAddon->AddEffects( EF_NODRAW ); - } -#endif - return ret; } diff --git a/game/client/c_colorcorrection.cpp b/game/client/c_colorcorrection.cpp index 6960031d..12e29768 100644 --- a/game/client/c_colorcorrection.cpp +++ b/game/client/c_colorcorrection.cpp @@ -6,6 +6,7 @@ //===========================================================================// #include "cbase.h" +#include "c_colorcorrection.h" #include "filesystem.h" #include "cdll_client_int.h" #include "colorcorrectionmgr.h" @@ -17,45 +18,27 @@ static ConVar mat_colcorrection_disableentities( "mat_colcorrection_disableentities", "0", FCVAR_NONE, "Disable map color-correction entities" ); - -//------------------------------------------------------------------------------ -// Purpose : Color correction entity with radial falloff -//------------------------------------------------------------------------------ -class C_ColorCorrection : public C_BaseEntity -{ -public: - DECLARE_CLASS( C_ColorCorrection, C_BaseEntity ); - - DECLARE_CLIENTCLASS(); - - C_ColorCorrection(); - virtual ~C_ColorCorrection(); - - void OnDataChanged(DataUpdateType_t updateType); - bool ShouldDraw(); - - void ClientThink(); - -private: - Vector m_vecOrigin; - - float m_minFalloff; - float m_maxFalloff; - float m_flCurWeight; - char m_netLookupFilename[MAX_PATH]; - - bool m_bEnabled; - - ClientCCHandle_t m_CCHandle; -}; +#ifdef MAPBASE // From Alien Swarm SDK +static ConVar mat_colcorrection_forceentitiesclientside( "mat_colcorrection_forceentitiesclientside", "0", FCVAR_CHEAT, "Forces color correction entities to be updated on the client" ); +#endif IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection) RecvPropVector( RECVINFO(m_vecOrigin) ), RecvPropFloat( RECVINFO(m_minFalloff) ), RecvPropFloat( RECVINFO(m_maxFalloff) ), RecvPropFloat( RECVINFO(m_flCurWeight) ), +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropFloat( RECVINFO(m_flMaxWeight) ), + RecvPropFloat( RECVINFO(m_flFadeInDuration) ), + RecvPropFloat( RECVINFO(m_flFadeOutDuration) ), +#endif RecvPropString( RECVINFO(m_netLookupFilename) ), RecvPropBool( RECVINFO(m_bEnabled) ), +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropBool( RECVINFO(m_bMaster) ), + RecvPropBool( RECVINFO(m_bClientSide) ), + RecvPropBool( RECVINFO(m_bExclusive) ) +#endif END_RECV_TABLE() @@ -65,14 +48,43 @@ END_RECV_TABLE() //------------------------------------------------------------------------------ C_ColorCorrection::C_ColorCorrection() { +#ifdef MAPBASE // From Alien Swarm SDK + m_minFalloff = -1.0f; + m_maxFalloff = -1.0f; + m_flFadeInDuration = 0.0f; + m_flFadeOutDuration = 0.0f; + m_flCurWeight = 0.0f; + m_flMaxWeight = 1.0f; + m_netLookupFilename[0] = '\0'; + m_bEnabled = false; + m_bMaster = false; + m_bExclusive = false; +#endif m_CCHandle = INVALID_CLIENT_CCHANDLE; + +#ifdef MAPBASE // From Alien Swarm SDK + m_bFadingIn = false; + m_flFadeStartWeight = 0.0f; + m_flFadeStartTime = 0.0f; + m_flFadeDuration = 0.0f; +#endif } C_ColorCorrection::~C_ColorCorrection() { +#ifdef MAPBASE // From Alien Swarm SDK + g_pColorCorrectionMgr->RemoveColorCorrectionEntity( this, m_CCHandle ); +#else g_pColorCorrectionMgr->RemoveColorCorrection( m_CCHandle ); +#endif } +#ifdef MAPBASE // From Alien Swarm SDK +bool C_ColorCorrection::IsClientSide() const +{ + return m_bClientSide || mat_colcorrection_forceentitiesclientside.GetBool(); +} +#endif //------------------------------------------------------------------------------ // Purpose : @@ -87,11 +99,21 @@ void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType) { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) { +#ifdef MAPBASE // From Alien Swarm SDK + // forming a unique name without extension + char cleanName[MAX_PATH]; + V_StripExtension( m_netLookupFilename, cleanName, sizeof( cleanName ) ); + char name[MAX_PATH]; + Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() ); + + m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionEntity( this, name, m_netLookupFilename ); +#else char filename[MAX_PATH]; Q_strncpy( filename, m_netLookupFilename, MAX_PATH ); m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename ); SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER ); +#endif } } } @@ -104,6 +126,129 @@ bool C_ColorCorrection::ShouldDraw() return false; } +#ifdef MAPBASE // From Alien Swarm SDK +void C_ColorCorrection::Update( C_BasePlayer *pPlayer, float ccScale ) +{ + Assert( m_CCHandle != INVALID_CLIENT_CCHANDLE ); + + if ( mat_colcorrection_disableentities.GetInt() ) + { + // Allow the colorcorrectionui panel (or user) to turn off color-correction entities + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); + return; + } + + // fade weight on client + if ( IsClientSide() ) + { + m_flCurWeight = Lerp( GetFadeRatio(), m_flFadeStartWeight, m_bFadingIn ? m_flMaxWeight : 0.0f ); + } + + if( !m_bEnabled && m_flCurWeight == 0.0f ) + { + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive ); + return; + } + + Vector playerOrigin = pPlayer->GetAbsOrigin(); + + float weight = 0; + if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff ) + { + float dist = (playerOrigin - m_vecOrigin).Length(); + weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff); + if ( weight<0.0f ) weight = 0.0f; + if ( weight>1.0f ) weight = 1.0f; + } + + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_flCurWeight * ( 1.0 - weight ) * ccScale, m_bExclusive ); +} + +void C_ColorCorrection::EnableOnClient( bool bEnable, bool bSkipFade ) +{ + if ( !IsClientSide() ) + { + return; + } + + m_bFadingIn = bEnable; + + // initialize countdown timer + m_flFadeStartWeight = m_flCurWeight; + float flFadeTimeScale = 1.0f; + if ( m_flMaxWeight != 0.0f ) + { + flFadeTimeScale = m_flCurWeight / m_flMaxWeight; + } + + if ( m_bFadingIn ) + { + flFadeTimeScale = 1.0f - flFadeTimeScale; + } + + if ( bSkipFade ) + { + flFadeTimeScale = 0.0f; + } + + StartFade( flFadeTimeScale * ( m_bFadingIn ? m_flFadeInDuration : m_flFadeOutDuration ) ); + + // update the clientside weight once here, in case the fade duration is 0 + m_flCurWeight = Lerp( GetFadeRatio(), m_flFadeStartWeight, m_bFadingIn ? m_flMaxWeight : 0.0f ); +} + +Vector C_ColorCorrection::GetOrigin() +{ + return m_vecOrigin; +} + +float C_ColorCorrection::GetMinFalloff() +{ + return m_minFalloff; +} + +float C_ColorCorrection::GetMaxFalloff() +{ + return m_maxFalloff; +} + +void C_ColorCorrection::SetWeight( float fWeight ) +{ + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, fWeight, false ); +} + +void C_ColorCorrection::StartFade( float flDuration ) +{ + m_flFadeStartTime = gpGlobals->curtime; + m_flFadeDuration = MAX( flDuration, 0.0f ); +} + +float C_ColorCorrection::GetFadeRatio() const +{ + float flRatio = 1.0f; + + if ( m_flFadeDuration != 0.0f ) + { + flRatio = ( gpGlobals->curtime - m_flFadeStartTime ) / m_flFadeDuration; + flRatio = clamp( flRatio, 0.0f, 1.0f ); + } + return flRatio; +} + +bool C_ColorCorrection::IsFadeTimeElapsed() const +{ + return ( ( gpGlobals->curtime - m_flFadeStartTime ) > m_flFadeDuration ) || + ( ( gpGlobals->curtime - m_flFadeStartTime ) < 0.0f ); +} + +void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount ) +{ + for ( int i = 0; i < listCount; i++ ) + { + pList[i]->Update(pPlayer, ccScale); + } +} +#else void C_ColorCorrection::ClientThink() { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) @@ -141,6 +286,7 @@ void C_ColorCorrection::ClientThink() BaseClass::ClientThink(); } +#endif diff --git a/game/client/c_colorcorrection.h b/game/client/c_colorcorrection.h new file mode 100644 index 00000000..63149a0a --- /dev/null +++ b/game/client/c_colorcorrection.h @@ -0,0 +1,88 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: Color correction entity with simple radial falloff +// +//=============================================================================// + +#ifndef C_COLORCORRECTION_H +#define C_COLORCORRECTION_H +#ifdef _WIN32 +#pragma once +#endif + +#include "colorcorrectionmgr.h" + +//------------------------------------------------------------------------------ +// Purpose : Color correction entity with radial falloff +//------------------------------------------------------------------------------ +class C_ColorCorrection : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_ColorCorrection, C_BaseEntity ); + + DECLARE_CLIENTCLASS(); + + C_ColorCorrection(); + virtual ~C_ColorCorrection(); + + void OnDataChanged(DataUpdateType_t updateType); + bool ShouldDraw(); + +#ifdef MAPBASE // From Alien Swarm SDK + virtual void Update(C_BasePlayer *pPlayer, float ccScale); + + bool IsMaster() const { return m_bMaster; } + bool IsClientSide() const; + bool IsExclusive() const { return m_bExclusive; } + + void EnableOnClient( bool bEnable, bool bSkipFade = false ); + + Vector GetOrigin(); + float GetMinFalloff(); + float GetMaxFalloff(); + + void SetWeight( float fWeight ); + +protected: + void StartFade( float flDuration ); + float GetFadeRatio() const; + bool IsFadeTimeElapsed() const; +#else + void ClientThink(); + +private: +#endif + Vector m_vecOrigin; + + float m_minFalloff; + float m_maxFalloff; + float m_flCurWeight; + char m_netLookupFilename[MAX_PATH]; + + bool m_bEnabled; + +#ifdef MAPBASE // From Alien Swarm SDK + float m_flFadeInDuration; + float m_flFadeOutDuration; + float m_flMaxWeight; + + bool m_bMaster; + bool m_bClientSide; + bool m_bExclusive; + + bool m_bFadingIn; + float m_flFadeStartWeight; + float m_flFadeStartTime; + float m_flFadeDuration; +#endif + + ClientCCHandle_t m_CCHandle; +}; + +#endif diff --git a/game/client/c_colorcorrectionvolume.cpp b/game/client/c_colorcorrectionvolume.cpp index 4bbcea94..f7e33708 100644 --- a/game/client/c_colorcorrectionvolume.cpp +++ b/game/client/c_colorcorrectionvolume.cpp @@ -36,9 +36,26 @@ class C_ColorCorrectionVolume : public C_BaseEntity void OnDataChanged(DataUpdateType_t updateType); bool ShouldDraw(); +#ifdef MAPBASE // From Alien Swarm SDK + void Update( C_BasePlayer *pPlayer, float ccScale ); + + void StartTouch( C_BaseEntity *pOther ); + void EndTouch( C_BaseEntity *pOther ); +#else void ClientThink(); +#endif private: +#ifdef MAPBASE // From Alien Swarm SDK + float m_LastEnterWeight; + float m_LastEnterTime; + + float m_LastExitWeight; + float m_LastExitTime; + bool m_bEnabled; + float m_MaxWeight; + float m_FadeDuration; +#endif float m_Weight; char m_lookupFilename[MAX_PATH]; @@ -46,6 +63,11 @@ class C_ColorCorrectionVolume : public C_BaseEntity }; IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume) +#ifdef MAPBASE // From Alien Swarm SDK + RecvPropBool( RECVINFO( m_bEnabled ) ), + RecvPropFloat( RECVINFO( m_MaxWeight ) ), + RecvPropFloat( RECVINFO( m_FadeDuration ) ), +#endif RecvPropFloat( RECVINFO(m_Weight) ), RecvPropString( RECVINFO(m_lookupFilename) ), END_RECV_TABLE() @@ -82,11 +104,21 @@ void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType) { if ( m_CCHandle == INVALID_CLIENT_CCHANDLE ) { +#ifdef MAPBASE // From Alien Swarm SDK + // forming a unique name without extension + char cleanName[MAX_PATH]; + V_StripExtension( m_lookupFilename, cleanName, sizeof( cleanName ) ); + char name[MAX_PATH]; + Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() ); + + m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionVolume( this, name, m_lookupFilename ); +#else char filename[MAX_PATH]; Q_strncpy( filename, m_lookupFilename, MAX_PATH ); m_CCHandle = g_pColorCorrectionMgr->AddColorCorrection( filename ); SetNextClientThink( ( m_CCHandle != INVALID_CLIENT_CCHANDLE ) ? CLIENT_THINK_ALWAYS : CLIENT_THINK_NEVER ); +#endif } } } @@ -99,11 +131,95 @@ bool C_ColorCorrectionVolume::ShouldDraw() return false; } +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void C_ColorCorrectionVolume::StartTouch( CBaseEntity *pEntity ) +{ + m_LastEnterTime = gpGlobals->curtime; + m_LastEnterWeight = m_Weight; +} + + +//-------------------------------------------------------------------------------------------------------- +void C_ColorCorrectionVolume::EndTouch( CBaseEntity *pEntity ) +{ + m_LastExitTime = gpGlobals->curtime; + m_LastExitWeight = m_Weight; +} + + +void C_ColorCorrectionVolume::Update( C_BasePlayer *pPlayer, float ccScale ) +{ + if ( pPlayer ) + { + bool isTouching = CollisionProp()->IsPointInBounds( pPlayer->EyePosition() ); + bool wasTouching = m_LastEnterTime > m_LastExitTime; + + if ( isTouching && !wasTouching ) + { + StartTouch( pPlayer ); + } + else if ( !isTouching && wasTouching ) + { + EndTouch( pPlayer ); + } + } + + if( !m_bEnabled ) + { + m_Weight = 0.0f; + } + else + { + if( m_LastEnterTime > m_LastExitTime ) + { + // we most recently entered the volume + + if( m_Weight < 1.0f ) + { + float dt = gpGlobals->curtime - m_LastEnterTime; + float weight = m_LastEnterWeight + dt / ((1.0f-m_LastEnterWeight)*m_FadeDuration); + if( weight>1.0f ) + weight = 1.0f; + + m_Weight = weight; + } + } + else + { + // we most recently exitted the volume + + if( m_Weight > 0.0f ) + { + float dt = gpGlobals->curtime - m_LastExitTime; + float weight = (1.0f-m_LastExitWeight) + dt / (m_LastExitWeight*m_FadeDuration); + if( weight>1.0f ) + weight = 1.0f; + + m_Weight = 1.0f - weight; + } + } + } + + // Vector entityPosition = GetAbsOrigin(); + g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight * ccScale ); +} + + +void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount ) +{ + for ( int i = 0; i < listCount; i++ ) + { + pList[i]->Update(pPlayer, ccScale); + } +} +#else void C_ColorCorrectionVolume::ClientThink() { Vector entityPosition = GetAbsOrigin(); g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight ); } +#endif diff --git a/game/client/c_effects.cpp b/game/client/c_effects.cpp index 14a90a4c..39359529 100644 --- a/game/client/c_effects.cpp +++ b/game/client/c_effects.cpp @@ -1,11 +1,12 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // //=============================================================================// #include "cbase.h" +#include "c_effects.h" #include "c_tracer.h" #include "view.h" #include "initializer.h" @@ -22,6 +23,7 @@ #include "collisionutils.h" #include "tier0/vprof.h" #include "viewrender.h" +#include "raytrace.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -35,6 +37,15 @@ float g_flSplashLifetime = 0.5f; float g_flSplashAlpha = 0.3f; ConVar r_RainSplashPercentage( "r_RainSplashPercentage", "20", FCVAR_CHEAT ); // N% chance of a rain particle making a splash. +ConVar r_RainParticleDensity( "r_RainParticleDensity", "1", FCVAR_NONE, "Density of Particle Rain 0-1" ); + +#ifdef MAPBASE +ConVar r_RainParticleClampOffset_Rain( "r_RainParticleClampOffset_Rain", "120", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systems using the 'Particle Rain' type." ); +ConVar r_RainParticleClampOffset_Ash( "r_RainParticleClampOffset_Ash", "300", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systems using the 'Particle Ash' type." ); +ConVar r_RainParticleClampOffset_RainStorm( "r_RainParticleClampOffset_RainStorm", "112", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systems using the 'Particle Rain Storm' type." ); +ConVar r_RainParticleClampOffset_Snow( "r_RainParticleClampOffset_Snow", "300", FCVAR_NONE, "How far inward or outward to extrude clamped precipitation particle systems using the 'Particle Snow' type." ); +ConVar r_RainParticleClampDebug( "r_RainParticleClampDebug", "0", FCVAR_NONE, "Enables debug code for precipitation particle system clamping" ); +#endif float GUST_INTERVAL_MIN = 1; float GUST_INTERVAL_MAX = 2; @@ -53,158 +64,14 @@ ConVar r_RainSimulate( "r_RainSimulate", "1", FCVAR_CHEAT, "Enable/disable rain ConVar r_DrawRain( "r_DrawRain", "1", FCVAR_CHEAT, "Enable/disable rain rendering." ); ConVar r_RainProfile( "r_RainProfile", "0", FCVAR_CHEAT, "Enable/disable rain profiling." ); - -//Precahce the effects -CLIENTEFFECT_REGISTER_BEGIN( PrecachePrecipitation ) -CLIENTEFFECT_MATERIAL( "particle/rain" ) -CLIENTEFFECT_MATERIAL( "particle/snow" ) -CLIENTEFFECT_REGISTER_END() - -//----------------------------------------------------------------------------- -// Precipitation particle type -//----------------------------------------------------------------------------- - -class CPrecipitationParticle -{ -public: - Vector m_Pos; - Vector m_Velocity; - float m_SpawnTime; // Note: Tweak with this to change lifetime - float m_Mass; - float m_Ramp; - - float m_flCurLifetime; - float m_flMaxLifetime; -}; - - -class CClient_Precipitation; -static CUtlVector g_Precipitations; - -//=========== -// Snow fall -//=========== -class CSnowFallManager; -static CSnowFallManager *s_pSnowFallMgr = NULL; -bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity ); -void SnowFallManagerDestroy( void ); - -class AshDebrisEffect : public CSimpleEmitter -{ -public: - AshDebrisEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {} - - static AshDebrisEffect* Create( const char *pDebugName ); - - virtual float UpdateAlpha( const SimpleParticle *pParticle ); - virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta ); - -private: - AshDebrisEffect( const AshDebrisEffect & ); -}; - -//----------------------------------------------------------------------------- -// Precipitation base entity -//----------------------------------------------------------------------------- - -class CClient_Precipitation : public C_BaseEntity -{ -class CPrecipitationEffect; -friend class CClient_Precipitation::CPrecipitationEffect; - -public: - DECLARE_CLASS( CClient_Precipitation, C_BaseEntity ); - DECLARE_CLIENTCLASS(); - - CClient_Precipitation(); - virtual ~CClient_Precipitation(); - - // Inherited from C_BaseEntity - virtual void Precache( ); - - void Render(); - -private: - - // Creates a single particle - CPrecipitationParticle* CreateParticle(); - - virtual void OnDataChanged( DataUpdateType_t updateType ); - virtual void ClientThink(); - - void Simulate( float dt ); - - // Renders the particle - void RenderParticle( CPrecipitationParticle* pParticle, CMeshBuilder &mb ); - - void CreateWaterSplashes(); - - // Emits the actual particles - void EmitParticles( float fTimeDelta ); - - // Computes where we're gonna emit - bool ComputeEmissionArea( Vector& origin, Vector2D& size ); - - // Gets the tracer width and speed - float GetWidth() const; - float GetLength() const; - float GetSpeed() const; - - // Gets the remaining lifetime of the particle - float GetRemainingLifetime( CPrecipitationParticle* pParticle ) const; - - // Computes the wind vector - static void ComputeWindVector( ); - - // simulation methods - bool SimulateRain( CPrecipitationParticle* pParticle, float dt ); - bool SimulateSnow( CPrecipitationParticle* pParticle, float dt ); - - void CreateAshParticle( void ); - void CreateRainOrSnowParticle( Vector vSpawnPosition, Vector vVelocity ); - - // Information helpful in creating and rendering particles - IMaterial *m_MatHandle; // material used - - float m_Color[4]; // precip color - float m_Lifetime; // Precip lifetime - float m_InitialRamp; // Initial ramp value - float m_Speed; // Precip speed - float m_Width; // Tracer width - float m_Remainder; // particles we should render next time - PrecipitationType_t m_nPrecipType; // Precip type - float m_flHalfScreenWidth; // Precalculated each frame. - - float m_flDensity; - - // Some state used in rendering and simulation - // Used to modify the rain density and wind from the console - static ConVar s_raindensity; - static ConVar s_rainwidth; - static ConVar s_rainlength; - static ConVar s_rainspeed; - - static Vector s_WindVector; // Stores the wind speed vector - - CUtlLinkedList m_Particles; - CUtlVector m_Splashes; - - CSmartPtr m_pAshEmitter; - TimedEvent m_tAshParticleTimer; - TimedEvent m_tAshParticleTraceTimer; - bool m_bActiveAshEmitter; - Vector m_vAshSpawnOrigin; - - int m_iAshCount; - -private: - CClient_Precipitation( const CClient_Precipitation & ); // not defined, not accessible -}; - +CUtlVector< RayTracingEnvironment* > g_RayTraceEnvironments; // Just receive the normal data table stuff IMPLEMENT_CLIENTCLASS_DT(CClient_Precipitation, DT_Precipitation, CPrecipitation) - RecvPropInt( RECVINFO( m_nPrecipType ) ) + RecvPropInt( RECVINFO( m_nPrecipType ) ), +#ifdef MAPBASE + RecvPropInt( RECVINFO( m_spawnflags ) ), +#endif END_RECV_TABLE() static ConVar r_SnowEnable( "r_SnowEnable", "1", FCVAR_CHEAT, "Snow Enable" ); @@ -243,7 +110,7 @@ void DrawPrecipitation() //----------------------------------------------------------------------------- static bool IsInAir( const Vector& position ) { - int contents = enginetrace->GetPointContents( position ); + int contents = enginetrace->GetPointContents( position ); return (contents & CONTENTS_SOLID) == 0; } @@ -300,7 +167,7 @@ inline bool CClient_Precipitation::SimulateRain( CPrecipitationParticle* pPartic Vector vOldPos = pParticle->m_Pos; // Update position - VectorMA( pParticle->m_Pos, dt, pParticle->m_Velocity, + VectorMA( pParticle->m_Pos, dt, pParticle->m_Velocity, pParticle->m_Pos ); // wind blows rain around @@ -355,7 +222,7 @@ inline bool CClient_Precipitation::SimulateSnow( CPrecipitationParticle* pPartic if ( IsInAir( pParticle->m_Pos ) ) { // Update position - VectorMA( pParticle->m_Pos, dt, pParticle->m_Velocity, + VectorMA( pParticle->m_Pos, dt, pParticle->m_Velocity, pParticle->m_Pos ); // wind blows rain around @@ -396,6 +263,12 @@ inline bool CClient_Precipitation::SimulateSnow( CPrecipitationParticle* pPartic void CClient_Precipitation::Simulate( float dt ) { + if ( IsParticleRainType(m_nPrecipType) ) + { + CreateParticlePrecip(); + return; + } + // NOTE: When client-side prechaching works, we need to remove this Precache(); @@ -472,6 +345,9 @@ inline void CClient_Precipitation::RenderParticle( CPrecipitationParticle* pPart float scale; Vector start, delta; + if ( IsParticleRainType(m_nPrecipType) ) + return; + if ( m_nPrecipType == PRECIPITATION_TYPE_ASH ) return; @@ -485,7 +361,7 @@ inline void CClient_Precipitation::RenderParticle( CPrecipitationParticle* pPart scale = GetLength() * pParticle->m_Ramp; else scale = lifetimeRemaining * pParticle->m_Ramp; - + // NOTE: We need to do everything in screen space Vector3DMultiplyPosition( CurrentWorldToViewMatrix(), pParticle->m_Pos, start ); if ( start.z > -1 ) @@ -501,7 +377,7 @@ inline void CClient_Precipitation::RenderParticle( CPrecipitationParticle* pPart if ( pParticle->m_Mass > 1.0f ) { - SinCos( gpGlobals->curtime * M_PI * (1+pParticle->m_Mass * 0.1f) + + SinCos( gpGlobals->curtime * M_PI * (1+pParticle->m_Mass * 0.1f) + pParticle->m_Mass * 5.0f, &s , &c ); // only spiral particles with a mass > 1, so some fall straight down @@ -547,7 +423,7 @@ void CClient_Precipitation::CreateWaterSplashes() for ( int i=0; i < m_Splashes.Count(); i++ ) { Vector vSplash = m_Splashes[i]; - + if ( CurrentViewForward().Dot( vSplash - CurrentViewOrigin() ) > 1 ) { FX_WaterRipple( vSplash, g_flSplashScale, &g_vSplashColor, g_flSplashLifetime, g_flSplashAlpha ); @@ -562,6 +438,9 @@ void CClient_Precipitation::Render() if ( !r_DrawRain.GetInt() ) return; + if ( IsParticleRainType(m_nPrecipType) ) + return; + // Don't render in monitors or in reflections or refractions. if ( CurrentViewID() == VIEW_MONITOR ) return; @@ -578,12 +457,12 @@ void CClient_Precipitation::Render() // Create any queued up water splashes. CreateWaterSplashes(); - + CFastTimer timer; timer.Start(); CMatRenderContextPtr pRenderContext( materials ); - + // We want to do our calculations in view space. VMatrix tempView; pRenderContext->GetMatrix( MATERIAL_VIEW, &tempView ); @@ -632,7 +511,12 @@ CClient_Precipitation::CClient_Precipitation() : m_Remainder(0.0f) m_nPrecipType = PRECIPITATION_TYPE_RAIN; m_MatHandle = INVALID_MATERIAL_HANDLE; m_flHalfScreenWidth = 1; - + + m_pParticlePrecipInnerNear = NULL; + m_pParticlePrecipInnerFar = NULL; + m_pParticlePrecipOuter = NULL; + m_bActiveParticlePrecipEmitter = false; + g_Precipitations.AddToTail( this ); } @@ -660,6 +544,7 @@ void CClient_Precipitation::Precache( ) switch( m_nPrecipType ) { case PRECIPITATION_TYPE_SNOW: + PrecacheMaterial( "particle/snow" ); m_Speed = SNOW_SPEED; m_MatHandle = materials->FindMaterial( "particle/snow", TEXTURE_GROUP_CLIENT_EFFECTS ); m_InitialRamp = 0.6f; @@ -668,6 +553,7 @@ void CClient_Precipitation::Precache( ) case PRECIPITATION_TYPE_RAIN: Assert( m_nPrecipType == PRECIPITATION_TYPE_RAIN ); + PrecacheMaterial( "particle/rain" ); m_Speed = RAIN_SPEED; m_MatHandle = materials->FindMaterial( "particle/rain", TEXTURE_GROUP_CLIENT_EFFECTS ); m_InitialRamp = 1.0f; @@ -764,7 +650,7 @@ bool CClient_Precipitation::ComputeEmissionArea( Vector& origin, Vector2D& size float emissionHeight = MIN( vMaxs[2], pPlayer->GetAbsOrigin()[2] + 512 ); float distToFall = emissionHeight - pPlayer->GetAbsOrigin()[2]; float fallTime = distToFall / GetSpeed(); - + // Based on the windspeed, figure out the center point of the emission Vector2D center; center[0] = pPlayer->GetAbsOrigin()[0] - fallTime * s_WindVector[0]; @@ -795,8 +681,8 @@ bool CClient_Precipitation::ComputeEmissionArea( Vector& origin, Vector2D& size } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pDebugName - +// Purpose: +// Input : *pDebugName - // Output : AshDebrisEffect* //----------------------------------------------------------------------------- AshDebrisEffect* AshDebrisEffect::Create( const char *pDebugName ) @@ -805,9 +691,9 @@ AshDebrisEffect* AshDebrisEffect::Create( const char *pDebugName ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pParticle - -// timeDelta - +// Purpose: +// Input : *pParticle - +// timeDelta - // Output : float //----------------------------------------------------------------------------- float AshDebrisEffect::UpdateAlpha( const SimpleParticle *pParticle ) @@ -950,7 +836,7 @@ void CClient_Precipitation::CreateAshParticle( void ) m_iAshCount++; bool bEmberTime = false; - + if ( m_iAshCount >= 250 ) { bEmberTime = true; @@ -970,7 +856,7 @@ void CClient_Precipitation::CreateAshParticle( void ) pParticle = (SimpleParticle *) m_pAshEmitter->AddParticle( sizeof(SimpleParticle), hMaterial[iRandom], offset ); if (pParticle == NULL) - continue; + continue; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RemapVal( iRandomAltitude, 0, 128, 4, 8 ); @@ -1011,11 +897,402 @@ void CClient_Precipitation::CreateAshParticle( void ) } } +void CClient_Precipitation::PrecacheParticlePrecip( void ) +{ + if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLEASH ) + { + PrecacheParticleSystem( "ash" ); + PrecacheParticleSystem( "ash_outer" ); + } + else if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLESNOW ) + { + PrecacheParticleSystem( "snow" ); + PrecacheParticleSystem( "snow_outer" ); + } + else if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLERAINSTORM ) + { + PrecacheParticleSystem( "rain_storm" ); + PrecacheParticleSystem( "rain_storm_screen" ); + PrecacheParticleSystem( "rain_storm_outer" ); + } + else //default to rain + { + PrecacheParticleSystem( "rain" ); + PrecacheParticleSystem( "rain_outer" ); + } +} + +void CClient_Precipitation::CreateParticlePrecip( void ) +{ + if ( !m_bParticlePrecipInitialized ) + { + PrecacheParticlePrecip(); + InitializeParticlePrecip(); + } + + + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + + if ( pPlayer == NULL ) + return; + + // Make sure the emitter is setup + if ( !m_bActiveParticlePrecipEmitter ) + { + //Update 8 times per second. + m_tParticlePrecipTraceTimer.Init( 8 ); + DestroyInnerParticlePrecip(); + DestroyOuterParticlePrecip(); + m_bActiveParticlePrecipEmitter = true; + } + + UpdateParticlePrecip( pPlayer ); +} + +#ifdef MAPBASE +void CClient_Precipitation::ClampParticlePosition( Vector &vPlayerPos, Vector &vOffsetPos, Vector &vOffsetPosNear, Vector &vOffsetPosFar ) +{ + Vector mins, maxs; + modelinfo->GetModelBounds( GetModel(), mins, maxs ); + + // Account for precipitation height + maxs.z += 180; + + Vector vecOrigin; //= WorldSpaceCenter(); + VectorLerp( mins, maxs, 0.5f, vecOrigin ); + + maxs -= vecOrigin; + mins -= vecOrigin; + + //float flMax = r_RainParticleClampOffset.GetFloat(); + float flMax = 0; + switch (m_nPrecipType) + { + case PRECIPITATION_TYPE_PARTICLERAIN: + flMax = r_RainParticleClampOffset_Rain.GetFloat(); + break; + + case PRECIPITATION_TYPE_PARTICLEASH: + flMax = r_RainParticleClampOffset_Ash.GetFloat(); + break; + + case PRECIPITATION_TYPE_PARTICLERAINSTORM: + flMax = r_RainParticleClampOffset_RainStorm.GetFloat(); + break; + + case PRECIPITATION_TYPE_PARTICLESNOW: + flMax = r_RainParticleClampOffset_Snow.GetFloat(); + break; + } + + Vector addend( flMax, flMax, 0 ); + mins += addend; + maxs -= addend; + + if (flMax > 0) + { + // Unless this is extruding outwards, make sure the offset isn't inverting the bounds. + // This means precipitation triggers with bounds less than offset*2 will turn into a thin line + // and the involved precipitation will pretty much be spatial at all times, which is okay. + mins.x = clamp( mins.x, -FLT_MAX, -1 ); + mins.y = clamp( mins.y, -FLT_MAX, -1 ); + maxs.x = clamp( maxs.x, 1, FLT_MAX ); + maxs.y = clamp( maxs.y, 1, FLT_MAX ); + } + + if (r_RainParticleClampDebug.GetBool()) + debugoverlay->AddBoxOverlay( vecOrigin, mins, maxs, vec3_angle, 255, 0, 0, 128, 0.15f ); + + maxs += vecOrigin; + mins += vecOrigin; + + CalcClosestPointOnAABB( mins, maxs, vPlayerPos, vPlayerPos ); + CalcClosestPointOnAABB( mins, maxs, vOffsetPos, vOffsetPos ); + CalcClosestPointOnAABB( mins, maxs, vOffsetPosNear, vOffsetPosNear ); + CalcClosestPointOnAABB( mins, maxs, vOffsetPosFar, vOffsetPosFar ); +} +#endif + +void CClient_Precipitation::UpdateParticlePrecip( C_BasePlayer *pPlayer ) +{ + if ( !pPlayer ) + return; + + Vector vForward; + Vector vRight; + + pPlayer->GetVectors( &vForward, &vRight, NULL ); + vForward.z = 0.0f; + vForward.NormalizeInPlace(); + Vector vForward45Right = vForward + vRight; + Vector vForward45Left = vForward - vRight; + vForward45Right.NormalizeInPlace(); + vForward45Left.NormalizeInPlace(); + fltx4 TMax = ReplicateX4( 320.0f ); + SubFloat( TMax, 3 ) = FLT_MAX; + float curTime = gpGlobals->frametime; + + while ( m_tParticlePrecipTraceTimer.NextEvent( curTime ) ) + { + Vector vPlayerPos = pPlayer->EyePosition(); + Vector vOffsetPos = vPlayerPos + Vector ( 0, 0, 180 ); + Vector vOffsetPosNear = vPlayerPos + Vector ( 0, 0, 180 ) + ( vForward * 32 ); + Vector vOffsetPosFar = vPlayerPos + Vector ( 0, 0, 180 ) + ( vForward * 100 ); + +#ifdef MAPBASE + if (m_spawnflags & SF_PRECIP_PARTICLE_CLAMP) + { + ClampParticlePosition( vPlayerPos, vOffsetPos, vOffsetPosNear, vOffsetPosFar ); + } +#endif + + Vector vDensity = Vector( r_RainParticleDensity.GetFloat(), 0, 0 ) * m_flDensity; + + // Get the rain volume Ray Tracing Environment. Currently hard coded to 0, should have this lookup + RayTracingEnvironment *RtEnv = g_RayTraceEnvironments.Element( 0 ); + + // Our 4 Rays are forward, off to the left and right, and directly up. + // Use the first three to determine if there's generally visible rain where we're looking. + // The forth, straight up, tells us if we're standing inside a rain volume + // (based on the normal that we hit or if we miss entirely) + FourRays frRays; + FourVectors fvDirection; + fvDirection = FourVectors( vForward, vForward45Left, vForward45Right, Vector( 0, 0, 1 ) ); + frRays.direction = fvDirection; + frRays.origin.DuplicateVector( vPlayerPos ); + RayTracingResult Result; + + RtEnv->Trace4Rays( frRays, Four_Zeros, TMax, &Result ); + + i32x4 in4HitIds = LoadAlignedIntSIMD( Result.HitIds ); + fltx4 fl4HitIds = SignedIntConvertToFltSIMD ( in4HitIds ); + + fltx4 fl4Tolerance = ReplicateX4( 300.0f ); + // ignore upwards test for tolerance, as we may be below an area which is raining, but with it not visible in front of us + //SubFloat( fl4Tolerance, 3 ) = 0.0f; + + bool bInside = ( Result.HitIds[3] != -1 && Result.surface_normal.Vec( 3 ).z < 0.0f ); + bool bNearby = ( IsAnyNegative ( CmpGeSIMD ( fl4HitIds, Four_Zeros ) ) && IsAnyNegative( CmpGeSIMD( fl4Tolerance, Result.HitDistance ) ) ); + + if ( bInside || bNearby ) + { + //We can see a rain volume, but it's farther than 180 units away, only use far effect. + if ( !bInside && SubFloat( FindLowestSIMD3( Result.HitDistance ), 0 ) >= m_flParticleInnerDist ) + { + // Kill the inner rain if it's previously been in use + if ( m_pParticlePrecipInnerNear != nullptr ) + { + DestroyInnerParticlePrecip(); + } + // Update if we've already got systems, otherwise, create them. + if ( m_pParticlePrecipOuter != nullptr ) + { + m_pParticlePrecipOuter->SetControlPoint( 1, vOffsetPos ); + m_pParticlePrecipOuter->SetControlPoint( 3, vDensity ); + } + else + { + DispatchOuterParticlePrecip( pPlayer, vForward ); + } + } + else //We're close enough to use the near effect. + { + // Update if we've already got systems, otherwise, create them. +#ifdef MAPBASE + // The outer can now be suppressed without interfering with other functionality + if ( m_pParticlePrecipOuter != nullptr ) + { + m_pParticlePrecipOuter->SetControlPoint( 1, vOffsetPos ); + m_pParticlePrecipOuter->SetControlPoint( 3, vDensity ); + } + if ( m_pParticlePrecipInnerNear != nullptr && m_pParticlePrecipInnerFar != nullptr ) + { + m_pParticlePrecipInnerNear->SetControlPoint( 1, vOffsetPosNear ); + m_pParticlePrecipInnerFar->SetControlPoint( 1, vOffsetPosFar ); + m_pParticlePrecipInnerNear->SetControlPoint( 3, vDensity ); + m_pParticlePrecipInnerFar->SetControlPoint( 3, vDensity ); + } +#else + if ( m_pParticlePrecipInnerNear != NULL && m_pParticlePrecipInnerFar != NULL && m_pParticlePrecipOuter != NULL ) + { + m_pParticlePrecipOuter->SetControlPoint( 1, vOffsetPos ); + m_pParticlePrecipInnerNear->SetControlPoint( 1, vOffsetPosNear ); + m_pParticlePrecipInnerFar->SetControlPoint( 1, vOffsetPosFar ); + m_pParticlePrecipInnerNear->SetControlPoint( 3, vDensity ); + m_pParticlePrecipInnerFar->SetControlPoint( 3, vDensity ); + m_pParticlePrecipOuter->SetControlPoint( 3, vDensity ); + } +#endif + else + { + DispatchInnerParticlePrecip( pPlayer, vForward ); + } + } + } + else // No rain in the area, kill any leftover systems. + { + DestroyInnerParticlePrecip(); + DestroyOuterParticlePrecip(); + } + } +} + +void CClient_Precipitation::InitializeParticlePrecip( void ) +{ + //Set up which type of precipitation particle we'll use + if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLEASH ) + { + m_pParticleInnerNearDef = "ash"; + m_pParticleInnerFarDef = "ash"; + m_pParticleOuterDef = "ash_outer"; + m_flParticleInnerDist = 280.0; + } + else if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLESNOW ) + { + m_pParticleInnerNearDef = "snow"; + m_pParticleInnerFarDef = "snow"; + m_pParticleOuterDef = "snow_outer"; + m_flParticleInnerDist = 280.0; + } + else if ( m_nPrecipType == PRECIPITATION_TYPE_PARTICLERAINSTORM ) + { + m_pParticleInnerNearDef = "rain_storm"; + m_pParticleInnerFarDef = "rain_storm_screen"; + m_pParticleOuterDef = "rain_storm_outer"; + m_flParticleInnerDist = 0.0; + } + else //default to rain + { + m_pParticleInnerNearDef = "rain"; + m_pParticleInnerFarDef = "rain"; + m_pParticleOuterDef = "rain_outer"; + m_flParticleInnerDist = 180.0; + } + + Assert( m_pParticleInnerFarDef != NULL ); + + //We'll want to change this if/when we add more raytrace environments. + g_RayTraceEnvironments.PurgeAndDeleteElements(); + + // Sets up ray tracing environments for all func_precipitations and func_precipitation_blockers + RayTracingEnvironment *rtEnvRainEmission = new RayTracingEnvironment(); + g_RayTraceEnvironments.AddToTail( rtEnvRainEmission ); + RayTracingEnvironment *rtEnvRainBlocker = new RayTracingEnvironment(); + g_RayTraceEnvironments.AddToTail( rtEnvRainBlocker ); + + rtEnvRainEmission->Flags |= RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS; // save some ram + rtEnvRainBlocker->Flags |= RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS; // save some ram + + int nTriCount = 1; + for ( int i=0; iGetVCollide( volume->GetModelIndex() ); + + if ( !pCollide || pCollide->solidCount <= 0 ) + continue; + + Vector *outVerts; + int vertCount = physcollision->CreateDebugMesh( pCollide->solids[0], &outVerts ); + + if ( vertCount ) + { + for ( int j = 0; j < vertCount; j += 3 ) + { + rtEnvRainEmission->AddTriangle( nTriCount++, outVerts[j], outVerts[j + 1], outVerts[j + 2], Vector( 1, 1, 1 ) ); + } + } + physcollision->DestroyDebugMesh( vertCount, outVerts ); + } + rtEnvRainEmission->SetupAccelerationStructure(); + + m_bParticlePrecipInitialized = true; +} + +void CClient_Precipitation::DestroyInnerParticlePrecip( void ) +{ + if ( m_pParticlePrecipInnerFar != nullptr ) + { + m_pParticlePrecipInnerFar->StopEmission(); + m_pParticlePrecipInnerFar = NULL; + } + if ( m_pParticlePrecipInnerNear != nullptr ) + { + m_pParticlePrecipInnerNear->StopEmission(); + m_pParticlePrecipInnerNear = NULL; + } +} + +void CClient_Precipitation::DestroyOuterParticlePrecip( void ) +{ + if ( m_pParticlePrecipOuter != nullptr ) + { + m_pParticlePrecipOuter->StopEmission(); + m_pParticlePrecipOuter = NULL; + } +} + +void CClient_Precipitation::DispatchOuterParticlePrecip( C_BasePlayer *pPlayer, Vector vForward ) +{ + DestroyOuterParticlePrecip(); + +#ifdef MAPBASE + if (m_spawnflags & SF_PRECIP_PARTICLE_NO_OUTER) + return; +#endif + + Vector vDensity = Vector( r_RainParticleDensity.GetFloat(), 0, 0 ) * m_flDensity; + Vector vPlayerPos = pPlayer->EyePosition(); + + m_pParticlePrecipOuter = ParticleProp()->Create( m_pParticleOuterDef, PATTACH_ABSORIGIN_FOLLOW ); + m_pParticlePrecipOuter->SetControlPointEntity( 2, pPlayer ); + m_pParticlePrecipOuter->SetControlPoint( 1, vPlayerPos + Vector (0, 0, 180 ) ); + m_pParticlePrecipOuter->SetControlPoint( 3, vDensity ); +} + +void CClient_Precipitation::DispatchInnerParticlePrecip( C_BasePlayer *pPlayer, Vector vForward ) +{ + DestroyInnerParticlePrecip(); + DestroyOuterParticlePrecip(); + Vector vPlayerPos = pPlayer->EyePosition(); + Vector vOffsetPos = vPlayerPos + Vector ( 0, 0, 180 ); + Vector vOffsetPosNear = vPlayerPos + Vector ( 0, 0, 180 ) + ( vForward * 32 ); + Vector vOffsetPosFar = vPlayerPos + Vector ( 0, 0, 180 ) + ( vForward * m_flParticleInnerDist ); // 100.0 + Vector vDensity = Vector( r_RainParticleDensity.GetFloat(), 0, 0 ) * m_flDensity; + +#ifdef MAPBASE + if (m_spawnflags & SF_PRECIP_PARTICLE_CLAMP) + { + ClampParticlePosition( vPlayerPos, vOffsetPos, vOffsetPosNear, vOffsetPosFar ); + } +#endif + +#ifdef MAPBASE + if (!(m_spawnflags & SF_PRECIP_PARTICLE_NO_OUTER)) +#endif + { + m_pParticlePrecipOuter = ParticleProp()->Create( m_pParticleOuterDef, PATTACH_ABSORIGIN_FOLLOW ); + m_pParticlePrecipOuter->SetControlPointEntity( 2, pPlayer ); + m_pParticlePrecipOuter->SetControlPoint( 1, vOffsetPos ); + m_pParticlePrecipOuter->SetControlPoint( 3, vDensity ); + } + + m_pParticlePrecipInnerNear = ParticleProp()->Create( m_pParticleInnerNearDef, PATTACH_ABSORIGIN_FOLLOW ); + m_pParticlePrecipInnerFar = ParticleProp()->Create( m_pParticleInnerFarDef, PATTACH_ABSORIGIN_FOLLOW ); + m_pParticlePrecipInnerNear->SetControlPointEntity( 2, pPlayer ); + m_pParticlePrecipInnerFar->SetControlPointEntity( 2, pPlayer ); + m_pParticlePrecipInnerNear->SetControlPoint( 1, vOffsetPosNear ); + m_pParticlePrecipInnerFar->SetControlPoint( 1, vOffsetPosFar ); + m_pParticlePrecipInnerNear->SetControlPoint( 3, vDensity ); + m_pParticlePrecipInnerFar->SetControlPoint( 3, vDensity ); +} + void CClient_Precipitation::CreateRainOrSnowParticle( Vector vSpawnPosition, Vector vVelocity ) { // Create the particle CPrecipitationParticle* p = CreateParticle(); - if (!p) + if (!p) return; VectorCopy( vVelocity, p->m_Velocity ); @@ -1052,11 +1329,11 @@ void CClient_Precipitation::EmitParticles( float fTimeDelta ) // FIXME: Compute the precipitation density based on computational power float density = m_flDensity; - if (density > 0.01f) + if (density > 0.01f) density = 0.01f; // Compute number of particles to emit based on precip density and emission area and dt - float fParticles = size[0] * size[1] * density * fTimeDelta + m_Remainder; + float fParticles = size[0] * size[1] * density * fTimeDelta + m_Remainder; int cParticles = (int)fParticles; m_Remainder = fParticles - cParticles; @@ -1072,7 +1349,7 @@ void CClient_Precipitation::EmitParticles( float fTimeDelta ) vParticlePos[ 0 ] += size[ 0 ] * random->RandomFloat(0, 1); vParticlePos[ 1 ] += size[ 1 ] * random->RandomFloat(0, 1); - // Figure out where the particle should lie in Z by tracing a line from the player's height up to the + // Figure out where the particle should lie in Z by tracing a line from the player's height up to the // desired height and making sure it doesn't hit a wall. Vector vPlayerHeight = vParticlePos; vPlayerHeight.z = vPlayerCenter.z; @@ -1135,7 +1412,7 @@ class CPrecipHack : public CAutoGameSystemPerFrame } m_bLevelInitted = true; } - + virtual void LevelShutdownPreEntity() { if ( r_RainHack.GetInt() && g_pPrecipHackEnt ) @@ -1206,6 +1483,12 @@ BEGIN_RECV_TABLE_NOBASE(CEnvWindShared, DT_EnvWindShared) RecvPropFloat (RECVINFO(m_flStartTime)), RecvPropFloat (RECVINFO(m_flGustDuration)), // RecvPropInt (RECVINFO(m_iszGustSound)), +#ifdef MAPBASE + RecvPropFloat (RECVINFO(m_windRadius)), + RecvPropFloat (RECVINFO(m_windRadiusInner)), + RecvPropVector (RECVINFO(m_location)), + RecvPropFloat (RECVINFO(m_flTreeSwayScale)), +#endif END_RECV_TABLE() IMPLEMENT_CLIENTCLASS_DT( C_EnvWind, DT_EnvWind, CEnvWind ) @@ -1225,7 +1508,7 @@ void C_EnvWind::OnDataChanged( DataUpdateType_t updateType ) // Whenever we get an update, reset the entire state. // Note that the fields have already been stored by the datatables, // but there's still work to be done in the init block - m_EnvWindShared.Init( entindex(), m_EnvWindShared.m_iWindSeed, + m_EnvWindShared.Init( entindex(), m_EnvWindShared.m_iWindSeed, m_EnvWindShared.m_flStartTime, m_EnvWindShared.m_iInitialWindDir, m_EnvWindShared.m_flInitialWindSpeed ); @@ -1261,8 +1544,8 @@ class CEmberEmitter : public CSimpleEmitter //----------------------------------------------------------------------------- -// Purpose: -// Input : fTimeDelta - +// Purpose: +// Input : fTimeDelta - // Output : Vector //----------------------------------------------------------------------------- CEmberEmitter::CEmberEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) @@ -1293,9 +1576,9 @@ void CEmberEmitter::UpdateVelocity( SimpleParticle *pParticle, float timeDelta ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pParticle - -// timeDelta - +// Purpose: +// Input : *pParticle - +// timeDelta - //----------------------------------------------------------------------------- Vector CEmberEmitter::UpdateColor( const SimpleParticle *pParticle ) { @@ -1353,8 +1636,8 @@ IMPLEMENT_CLIENTCLASS_DT( C_Embers, DT_Embers, CEmbers ) END_RECV_TABLE() //----------------------------------------------------------------------------- -// Purpose: -// Input : bnewentity - +// Purpose: +// Input : bnewentity - //----------------------------------------------------------------------------- C_Embers::C_Embers() { @@ -1378,7 +1661,7 @@ void C_Embers::OnDataChanged( DataUpdateType_t updateType ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_Embers::ShouldDraw() @@ -1387,20 +1670,20 @@ bool C_Embers::ShouldDraw() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void C_Embers::Start( void ) { //Various setup info m_tParticleSpawn.Init( m_nDensity ); - + m_hMaterial = m_pEmitter->GetPMaterial( "particle/fire" ); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -void C_Embers::AddEntity( void ) +void C_Embers::AddEntity( void ) { if ( m_bEmit == false ) return; @@ -1414,12 +1697,12 @@ void C_Embers::AddEntity( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void C_Embers::SpawnEmber( void ) { Vector offset, mins, maxs; - + modelinfo->GetModelBounds( GetModel(), mins, maxs ); //Setup our spawn position @@ -1464,7 +1747,7 @@ void C_Embers::SpawnEmber( void ) } //----------------------------------------------------------------------------- -// Quadratic spline beam effect +// Quadratic spline beam effect //----------------------------------------------------------------------------- #include "beamdraw.h" @@ -1540,15 +1823,19 @@ class SnowFallEffect : public CSimpleEmitter pParticle->m_vecVelocity *= flSpeed; +#ifdef MAPBASE + Vector vecWindVelocity = GetWindspeedAtLocation( pParticle->m_Pos ); +#else Vector vecWindVelocity; GetWindspeedAtTime( gpGlobals->curtime, vecWindVelocity ); +#endif pParticle->m_vecVelocity += ( vecWindVelocity * r_SnowWindScale.GetFloat() ); } void SimulateParticles( CParticleSimulateIterator *pIterator ) { float timeDelta = pIterator->GetTimeDelta(); - + SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst(); while ( pParticle ) { @@ -1574,8 +1861,8 @@ class SnowFallEffect : public CSimpleEmitter } int GetParticleCount( void ) - { - return GetBinding().GetNumActiveParticles(); + { + return GetBinding().GetNumActiveParticles(); } void SetBounds( const Vector &vecMin, const Vector &vecMax ) @@ -1666,7 +1953,7 @@ class CSnowFallManager : public C_BaseEntity }; //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CSnowFallManager::CSnowFallManager( void ) { @@ -1681,7 +1968,7 @@ CSnowFallManager::CSnowFallManager( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CSnowFallManager::~CSnowFallManager( void ) { @@ -1689,7 +1976,7 @@ CSnowFallManager::~CSnowFallManager( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSnowFallManager::CreateEmitter( void ) @@ -1698,7 +1985,7 @@ bool CSnowFallManager::CreateEmitter( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSnowFallManager::SpawnClientEntity( void ) { @@ -1711,7 +1998,7 @@ void CSnowFallManager::SpawnClientEntity( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSnowFallManager::CreateSnowFallEmitter( void ) @@ -1723,7 +2010,7 @@ bool CSnowFallManager::CreateSnowFallEmitter( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSnowFallManager::ClientThink( void ) { @@ -1741,8 +2028,8 @@ void CSnowFallManager::ClientThink( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pSnowEntity - +// Purpose: +// Input : *pSnowEntity - //----------------------------------------------------------------------------- void CSnowFallManager::AddSnowFallEntity( CClient_Precipitation *pSnowEntity ) { @@ -1772,7 +2059,7 @@ void CSnowFallManager::AddSnowFallEntity( CClient_Precipitation *pSnowEntity ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSnowFallManager::UpdateBounds( const Vector &vecSnowMin, const Vector &vecSnowMax ) { @@ -1795,8 +2082,8 @@ void CSnowFallManager::UpdateBounds( const Vector &vecSnowMin, const Vector &vec } //----------------------------------------------------------------------------- -// Purpose: -// Input : &vecPoint - +// Purpose: +// Input : &vecPoint - // Output : int //----------------------------------------------------------------------------- int CSnowFallManager::StandingInSnowVolume( Vector &vecPoint ) @@ -1816,9 +2103,9 @@ int CSnowFallManager::StandingInSnowVolume( Vector &vecPoint ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &vecCenter - -// flRadius - +// Purpose: +// Input : &vecCenter - +// flRadius - //----------------------------------------------------------------------------- void CSnowFallManager::FindSnowVolumes( Vector &vecCenter, float flRadius, Vector &vecEyePos, Vector &vecForward ) { @@ -1847,7 +2134,7 @@ void CSnowFallManager::FindSnowVolumes( Vector &vecCenter, float flRadius, Vecto } } // Check to see if a snow volume is outside of the sphere radius, but is along line-of-sight. - else + else { CBaseTrace trace; Vector vecNewForward; @@ -1886,7 +2173,7 @@ void CSnowFallManager::FindSnowVolumes( Vector &vecCenter, float flRadius, Vecto } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSnowFallManager::CreateSnowFall( void ) { @@ -1976,12 +2263,12 @@ void CSnowFallManager::CreateSnowFall( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : flCurrentTime - -// flRadius - -// &vecEyePos - -// &vecForward - -// flZoomScale - +// Purpose: +// Input : flCurrentTime - +// flRadius - +// &vecEyePos - +// &vecForward - +// flZoomScale - //----------------------------------------------------------------------------- void CSnowFallManager::CreateSnowFallParticles( float flCurrentTime, float flRadius, const Vector &vecEyePos, const Vector &vecForward, float flZoomScale ) { @@ -1998,10 +2285,10 @@ void CSnowFallManager::CreateSnowFallParticles( float flCurrentTime, float flRad } //----------------------------------------------------------------------------- -// Purpose: -// Input : flCurrentTime - -// flRadius - -// flZoomScale - +// Purpose: +// Input : flCurrentTime - +// flRadius - +// flZoomScale - //----------------------------------------------------------------------------- void CSnowFallManager::CreateOutsideVolumeSnowParticles( float flCurrentTime, float flRadius, float flZoomScale ) { @@ -2034,12 +2321,12 @@ void CSnowFallManager::CreateOutsideVolumeSnowParticles( float flCurrentTime, fl } //----------------------------------------------------------------------------- -// Purpose: -// Input : flCurrentTime - -// flRadius - -// &vecEyePos - -// &vecForward - -// flZoomScale - +// Purpose: +// Input : flCurrentTime - +// flRadius - +// &vecEyePos - +// &vecForward - +// flZoomScale - //----------------------------------------------------------------------------- void CSnowFallManager::CreateInsideVolumeSnowParticles( float flCurrentTime, float flRadius, const Vector &vecEyePos, const Vector &vecForward, float flZoomScale ) { @@ -2085,8 +2372,8 @@ void CSnowFallManager::CreateInsideVolumeSnowParticles( float flCurrentTime, flo } //----------------------------------------------------------------------------- -// Purpose: -// Input : flRadius - +// Purpose: +// Input : flRadius - //----------------------------------------------------------------------------- void CSnowFallManager::CreateSnowParticlesSphere( float flRadius ) { @@ -2116,9 +2403,9 @@ void CSnowFallManager::CreateSnowParticlesSphere( float flRadius ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &vecEyePos - -// &vecForward - +// Purpose: +// Input : &vecEyePos - +// &vecForward - //----------------------------------------------------------------------------- void CSnowFallManager::CreateSnowParticlesRay( float flRadius, const Vector &vecEyePos, const Vector &vecForward ) { @@ -2160,10 +2447,10 @@ void CSnowFallManager::CreateSnowParticlesRay( float flRadius, const Vector &vec } void CSnowFallManager::CreateSnowFallParticle( const Vector &vecParticleSpawn, int iSnow ) -{ +{ SimpleParticle *pParticle = ( SimpleParticle* )m_pSnowFallEmitter->AddParticle( sizeof( SimpleParticle ), m_aSnow[iSnow].m_hMaterial, vecParticleSpawn ); if ( pParticle == NULL ) - return; + return; pParticle->m_flLifetime = 0.0f; pParticle->m_vecVelocity = Vector( RandomFloat( -5.0f, 5.0f ), RandomFloat( -5.0f, 5.0f ), ( RandomFloat( -25, -35 ) * r_SnowFallSpeed.GetFloat() ) ); @@ -2191,7 +2478,7 @@ void CSnowFallManager::CreateSnowFallParticle( const Vector &vecParticleSpawn, i } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity ) { @@ -2209,7 +2496,7 @@ bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void SnowFallManagerDestroy( void ) { diff --git a/game/client/c_effects.h b/game/client/c_effects.h index 27bb501e..5f7e02a5 100644 --- a/game/client/c_effects.h +++ b/game/client/c_effects.h @@ -10,9 +10,182 @@ #pragma once #endif +#include "cbase.h" +#include "precipitation_shared.h" // Draw rain effects. void DrawPrecipitation(); +//----------------------------------------------------------------------------- +// Precipitation particle type +//----------------------------------------------------------------------------- + +class CPrecipitationParticle +{ +public: + Vector m_Pos; + Vector m_Velocity; + float m_SpawnTime; // Note: Tweak with this to change lifetime + float m_Mass; + float m_Ramp; + + float m_flCurLifetime; + float m_flMaxLifetime; +}; + + +class CClient_Precipitation; +static CUtlVector g_Precipitations; + +//=========== +// Snow fall +//=========== +class CSnowFallManager; +static CSnowFallManager *s_pSnowFallMgr = NULL; +bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity ); +void SnowFallManagerDestroy( void ); + +class AshDebrisEffect : public CSimpleEmitter +{ +public: + AshDebrisEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {} + + static AshDebrisEffect* Create( const char *pDebugName ); + + virtual float UpdateAlpha( const SimpleParticle *pParticle ); + virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta ); + +private: + AshDebrisEffect( const AshDebrisEffect & ); +}; + +//----------------------------------------------------------------------------- +// Precipitation base entity +//----------------------------------------------------------------------------- + +class CClient_Precipitation : public C_BaseEntity +{ +class CPrecipitationEffect; +friend class CClient_Precipitation::CPrecipitationEffect; + +public: + DECLARE_CLASS( CClient_Precipitation, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + CClient_Precipitation(); + virtual ~CClient_Precipitation(); + + // Inherited from C_BaseEntity + virtual void Precache( ); + + void Render(); + +private: + + // Creates a single particle + CPrecipitationParticle* CreateParticle(); + + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual void ClientThink(); + + void Simulate( float dt ); + + // Renders the particle + void RenderParticle( CPrecipitationParticle* pParticle, CMeshBuilder &mb ); + + void CreateWaterSplashes(); + + // Emits the actual particles + void EmitParticles( float fTimeDelta ); + + // Computes where we're gonna emit + bool ComputeEmissionArea( Vector& origin, Vector2D& size ); + + // Gets the tracer width and speed + float GetWidth() const; + float GetLength() const; + float GetSpeed() const; + + // Gets the remaining lifetime of the particle + float GetRemainingLifetime( CPrecipitationParticle* pParticle ) const; + + // Computes the wind vector + static void ComputeWindVector( ); + + // simulation methods + bool SimulateRain( CPrecipitationParticle* pParticle, float dt ); + bool SimulateSnow( CPrecipitationParticle* pParticle, float dt ); + + void PrecacheParticlePrecip( void ); + void CreateParticlePrecip( void ); + void InitializeParticlePrecip( void ); + void DispatchOuterParticlePrecip( C_BasePlayer *pPlayer, Vector vForward ); + void DispatchInnerParticlePrecip( C_BasePlayer *pPlayer, Vector vForward ); + void DestroyOuterParticlePrecip( void ); + void DestroyInnerParticlePrecip( void ); + + void UpdateParticlePrecip( C_BasePlayer *pPlayer ); + +private: + void CreateAshParticle( void ); + void CreateRainOrSnowParticle( Vector vSpawnPosition, Vector vVelocity ); + +#ifdef MAPBASE + void ClampParticlePosition( Vector &vPlayerPos, Vector &vOffsetPos, Vector &vOffsetPosNear, Vector &vOffsetPosFar ); +#endif + + // Information helpful in creating and rendering particles + IMaterial *m_MatHandle; // material used + + float m_Color[4]; // precip color + float m_Lifetime; // Precip lifetime + float m_InitialRamp; // Initial ramp value + float m_Speed; // Precip speed + float m_Width; // Tracer width + float m_Remainder; // particles we should render next time + PrecipitationType_t m_nPrecipType; // Precip type + float m_flHalfScreenWidth; // Precalculated each frame. + + float m_flDensity; + +#ifdef MAPBASE + int m_spawnflags; +#endif + + // Some state used in rendering and simulation + // Used to modify the rain density and wind from the console + static ConVar s_raindensity; + static ConVar s_rainwidth; + static ConVar s_rainlength; + static ConVar s_rainspeed; + + static Vector s_WindVector; // Stores the wind speed vector + + CUtlLinkedList m_Particles; + CUtlVector m_Splashes; + + CSmartPtr m_pAshEmitter; + TimedEvent m_tAshParticleTimer; + TimedEvent m_tAshParticleTraceTimer; + bool m_bActiveAshEmitter; + Vector m_vAshSpawnOrigin; + + int m_iAshCount; + +protected: + float m_flParticleInnerDist; //The distance at which to start drawing the inner system + char *m_pParticleInnerNearDef; //Name of the first inner system + char *m_pParticleInnerFarDef; //Name of the second inner system + char *m_pParticleOuterDef; //Name of the outer system + HPARTICLEFFECT m_pParticlePrecipInnerNear; + HPARTICLEFFECT m_pParticlePrecipInnerFar; + HPARTICLEFFECT m_pParticlePrecipOuter; + TimedEvent m_tParticlePrecipTraceTimer; + bool m_bActiveParticlePrecipEmitter; + bool m_bParticlePrecipInitialized; + +private: + CClient_Precipitation( const CClient_Precipitation & ); // not defined, not accessible +}; #endif // C_EFFECTS_H diff --git a/game/client/c_entitydissolve.cpp b/game/client/c_entitydissolve.cpp index f61e2ac0..520425eb 100644 --- a/game/client/c_entitydissolve.cpp +++ b/game/client/c_entitydissolve.cpp @@ -24,12 +24,6 @@ // 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 //----------------------------------------------------------------------------- @@ -60,6 +54,14 @@ C_EntityDissolve::C_EntityDissolve( void ) m_vEffectColor = Vector( 255, 255, 255 ); } +void C_EntityDissolve::Precache() +{ + BaseClass::Precache(); + PrecacheMaterial( "effects/tesla_glow_noz" ); + PrecacheMaterial( "effects/spark" ); + PrecacheMaterial( "effects/combinemuzzle2" ); +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -575,10 +577,7 @@ void C_EntityDissolve::ClientThink( void ) #ifdef TF_CLIENT_DLL else { - // Hide the ragdoll -- don't actually delete it or else things get unhappy when - // we get a message from the server telling us to delete it - pEnt->AddEffects( EF_NODRAW ); - pEnt->ParticleProp()->StopEmission(); + pEnt->Release(); } #endif } diff --git a/game/client/c_entitydissolve.h b/game/client/c_entitydissolve.h index d440e0b6..6309512e 100644 --- a/game/client/c_entitydissolve.h +++ b/game/client/c_entitydissolve.h @@ -22,6 +22,7 @@ class C_EntityDissolve : public C_BaseEntity, public IMotionEvent C_EntityDissolve( void ); // Inherited from C_BaseEntity + virtual void Precache(); virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs ); virtual int DrawModel( int flags ); virtual bool ShouldDraw() { return true; } diff --git a/game/client/c_env_dof_controller.cpp b/game/client/c_env_dof_controller.cpp new file mode 100644 index 00000000..274820e7 --- /dev/null +++ b/game/client/c_env_dof_controller.cpp @@ -0,0 +1,88 @@ +//====== Copyright 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: Depth of field controller entity +// +//============================================================================= + +#include "cbase.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +extern bool g_bDOFEnabled; +extern float g_flDOFNearBlurDepth; +extern float g_flDOFNearFocusDepth; +extern float g_flDOFFarFocusDepth; +extern float g_flDOFFarBlurDepth; +extern float g_flDOFNearBlurRadius; +extern float g_flDOFFarBlurRadius; + +EHANDLE g_hDOFControllerInUse = NULL; + +class C_EnvDOFController : public C_BaseEntity +{ + DECLARE_CLASS( C_EnvDOFController, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + C_EnvDOFController(); + ~C_EnvDOFController(); + virtual void OnDataChanged( DataUpdateType_t updateType ); + +private: + bool m_bDOFEnabled; + float m_flNearBlurDepth; + float m_flNearFocusDepth; + float m_flFarFocusDepth; + float m_flFarBlurDepth; + float m_flNearBlurRadius; + float m_flFarBlurRadius; + +private: + C_EnvDOFController( const C_EnvDOFController & ); +}; + +IMPLEMENT_CLIENTCLASS_DT( C_EnvDOFController, DT_EnvDOFController, CEnvDOFController ) + RecvPropInt( RECVINFO(m_bDOFEnabled) ), + RecvPropFloat( RECVINFO(m_flNearBlurDepth) ), + RecvPropFloat( RECVINFO(m_flNearFocusDepth) ), + RecvPropFloat( RECVINFO(m_flFarFocusDepth) ), + RecvPropFloat( RECVINFO(m_flFarBlurDepth) ), + RecvPropFloat( RECVINFO(m_flNearBlurRadius) ), + RecvPropFloat( RECVINFO(m_flFarBlurRadius) ) +END_RECV_TABLE() + +C_EnvDOFController::C_EnvDOFController() +: m_bDOFEnabled( true ), + m_flNearBlurDepth( 20.0f ), + m_flNearFocusDepth( 100.0f ), + m_flFarFocusDepth( 250.0f ), + m_flFarBlurDepth( 1000.0f ), + m_flNearBlurRadius( 0.0f ), // no near blur by default + m_flFarBlurRadius( 5.0f ) +{ +} + +C_EnvDOFController::~C_EnvDOFController() +{ + if ( g_hDOFControllerInUse == this ) + { + g_bDOFEnabled = false; + } +} + +void C_EnvDOFController::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + g_bDOFEnabled = m_bDOFEnabled && ( ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ) ); + g_flDOFNearBlurDepth = m_flNearBlurDepth; + g_flDOFNearFocusDepth = m_flNearFocusDepth; + g_flDOFFarFocusDepth = m_flFarFocusDepth; + g_flDOFFarBlurDepth = m_flFarBlurDepth; + g_flDOFNearBlurRadius = m_flNearBlurRadius; + g_flDOFFarBlurRadius = m_flFarBlurRadius; + + g_hDOFControllerInUse = this; +} diff --git a/game/client/c_env_global_light.cpp b/game/client/c_env_global_light.cpp new file mode 100644 index 00000000..b143a79d --- /dev/null +++ b/game/client/c_env_global_light.cpp @@ -0,0 +1,348 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Sunlight shadow control entity. +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" + +#include "c_baseplayer.h" +#include "tier0/vprof.h" +#ifdef MAPBASE +#include "materialsystem/itexture.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +extern ConVar cl_sunlight_ortho_size; +extern ConVar cl_sunlight_depthbias; + +ConVar cl_globallight_freeze( "cl_globallight_freeze", "0" ); +#ifdef MAPBASE +// I imagine these values might've been designed for the ASW view. +// You can set these as KV anyway. +ConVar cl_globallight_xoffset( "cl_globallight_xoffset", "0" ); +ConVar cl_globallight_yoffset( "cl_globallight_yoffset", "0" ); + +static ConVar cl_globallight_slopescaledepthbias_shadowmap( "cl_globallight_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT ); +static ConVar cl_globallight_shadowfiltersize( "cl_globallight_shadowfiltersize", "0.1", FCVAR_CHEAT ); +static ConVar cl_globallight_depthbias_shadowmap( "cl_globallight_depthbias_shadowmap", "0.00001", FCVAR_CHEAT ); +static ConVar cl_globallight_depthres( "cl_globallight_depthres", "8192", FCVAR_CHEAT ); +#else +ConVar cl_globallight_xoffset( "cl_globallight_xoffset", "-800" ); +ConVar cl_globallight_yoffset( "cl_globallight_yoffset", "1600" ); +#endif + +//------------------------------------------------------------------------------ +// Purpose : Sunlights shadow control entity +//------------------------------------------------------------------------------ +class C_GlobalLight : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_GlobalLight, C_BaseEntity ); + + DECLARE_CLIENTCLASS(); + + virtual ~C_GlobalLight(); + + void OnDataChanged( DataUpdateType_t updateType ); + void Spawn(); + bool ShouldDraw(); + + void ClientThink(); + +private: + Vector m_shadowDirection; + bool m_bEnabled; + char m_TextureName[ MAX_PATH ]; +#ifdef MAPBASE + int m_nSpotlightTextureFrame; +#endif + CTextureReference m_SpotlightTexture; + color32 m_LightColor; +#ifdef MAPBASE + float m_flBrightnessScale; + float m_flCurrentBrightnessScale; +#endif + Vector m_CurrentLinearFloatLightColor; + float m_flCurrentLinearFloatLightAlpha; + float m_flColorTransitionTime; + float m_flSunDistance; + float m_flFOV; + float m_flNearZ; + float m_flNorthOffset; +#ifdef MAPBASE + float m_flEastOffset; + float m_flForwardOffset; + float m_flOrthoSize; +#endif + bool m_bEnableShadows; + bool m_bOldEnableShadows; + + static ClientShadowHandle_t m_LocalFlashlightHandle; +}; + + +ClientShadowHandle_t C_GlobalLight::m_LocalFlashlightHandle = CLIENTSHADOW_INVALID_HANDLE; + + +IMPLEMENT_CLIENTCLASS_DT(C_GlobalLight, DT_GlobalLight, CGlobalLight) + RecvPropVector(RECVINFO(m_shadowDirection)), + RecvPropBool(RECVINFO(m_bEnabled)), + RecvPropString(RECVINFO(m_TextureName)), +#ifdef MAPBASE + RecvPropInt(RECVINFO(m_nSpotlightTextureFrame)), +#endif + /*RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_Int32ToColor32),*/ + RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_IntToColor32), +#ifdef MAPBASE + RecvPropFloat(RECVINFO(m_flBrightnessScale)), +#endif + RecvPropFloat(RECVINFO(m_flColorTransitionTime)), + RecvPropFloat(RECVINFO(m_flSunDistance)), + RecvPropFloat(RECVINFO(m_flFOV)), + RecvPropFloat(RECVINFO(m_flNearZ)), + RecvPropFloat(RECVINFO(m_flNorthOffset)), +#ifdef MAPBASE + RecvPropFloat(RECVINFO(m_flEastOffset)), + RecvPropFloat(RECVINFO(m_flForwardOffset)), + RecvPropFloat(RECVINFO(m_flOrthoSize)), +#endif + RecvPropBool(RECVINFO(m_bEnableShadows)), +END_RECV_TABLE() + + +C_GlobalLight::~C_GlobalLight() +{ + if ( m_LocalFlashlightHandle != CLIENTSHADOW_INVALID_HANDLE ) + { + g_pClientShadowMgr->DestroyFlashlight( m_LocalFlashlightHandle ); + m_LocalFlashlightHandle = CLIENTSHADOW_INVALID_HANDLE; + } +} + +void C_GlobalLight::OnDataChanged( DataUpdateType_t updateType ) +{ + if ( updateType == DATA_UPDATE_CREATED ) + { + m_SpotlightTexture.Init( m_TextureName, TEXTURE_GROUP_OTHER, true ); + } +#ifdef MAPBASE + else //if ( updateType == DATA_UPDATE_DATATABLE_CHANGED ) + { + // It could've been changed via input + if( !FStrEq(m_SpotlightTexture->GetName(), m_TextureName) ) + { + m_SpotlightTexture.Init( m_TextureName, TEXTURE_GROUP_OTHER, true ); + } + } +#endif + + BaseClass::OnDataChanged( updateType ); +} + +void C_GlobalLight::Spawn() +{ + BaseClass::Spawn(); + + m_bOldEnableShadows = m_bEnableShadows; + + SetNextClientThink( CLIENT_THINK_ALWAYS ); +} + +//------------------------------------------------------------------------------ +// We don't draw... +//------------------------------------------------------------------------------ +bool C_GlobalLight::ShouldDraw() +{ + return false; +} + +void C_GlobalLight::ClientThink() +{ + VPROF("C_GlobalLight::ClientThink"); + + bool bSupressWorldLights = false; + + if ( cl_globallight_freeze.GetBool() == true ) + { + return; + } + + if ( m_bEnabled ) + { + Vector vLinearFloatLightColor( m_LightColor.r, m_LightColor.g, m_LightColor.b ); + float flLinearFloatLightAlpha = m_LightColor.a; + +#ifdef MAPBASE + if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha || m_flCurrentBrightnessScale != m_flBrightnessScale ) + { + if (m_flColorTransitionTime != 0.0f) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed ); + m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed ); + m_flCurrentBrightnessScale = Approach( m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed ); + } + else + { + // Just do it instantly + m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x; + m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y; + m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z; + m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha; + m_flCurrentBrightnessScale = m_flBrightnessScale; + } + } +#else + if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha ) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed ); + m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed ); + } +#endif + + FlashlightState_t state; + + Vector vDirection = m_shadowDirection; + VectorNormalize( vDirection ); + + //Vector vViewUp = Vector( 0.0f, 1.0f, 0.0f ); + Vector vSunDirection2D = vDirection; + vSunDirection2D.z = 0.0f; + + /*HACK_GETLOCALPLAYER_GUARD( "C_GlobalLight::ClientThink" );*/ + + if ( !C_BasePlayer::GetLocalPlayer() ) + return; + + Vector vPos; + QAngle EyeAngles; + float flZNear, flZFar, flFov; + + C_BasePlayer::GetLocalPlayer()->CalcView( vPos, EyeAngles, flZNear, flZFar, flFov ); +// Vector vPos = C_BasePlayer::GetLocalPlayer()->GetAbsOrigin(); + +// vPos = Vector( 0.0f, 0.0f, 500.0f ); + vPos = ( vPos + vSunDirection2D * m_flNorthOffset ) - vDirection * m_flSunDistance; +#ifdef MAPBASE + vPos += Vector( m_flEastOffset + cl_globallight_xoffset.GetFloat(), m_flForwardOffset + cl_globallight_yoffset.GetFloat(), 0.0f ); +#else + vPos += Vector( cl_globallight_xoffset.GetFloat(), cl_globallight_yoffset.GetFloat(), 0.0f ); +#endif + + QAngle angAngles; + VectorAngles( vDirection, angAngles ); + + Vector vForward, vRight, vUp; + AngleVectors( angAngles, &vForward, &vRight, &vUp ); + + state.m_fHorizontalFOVDegrees = m_flFOV; + state.m_fVerticalFOVDegrees = m_flFOV; + + state.m_vecLightOrigin = vPos; + BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation ); + + state.m_fQuadraticAtten = 0.0f; + state.m_fLinearAtten = m_flSunDistance * 2.0f; + state.m_fConstantAtten = 0.0f; + state.m_FarZAtten = m_flSunDistance * 2.0f; +#ifdef MAPBASE + float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f); + state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; + state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; + state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; +#else + state.m_Color[0] = m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * m_flCurrentLinearFloatLightAlpha; + state.m_Color[1] = m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * m_flCurrentLinearFloatLightAlpha; + state.m_Color[2] = m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * m_flCurrentLinearFloatLightAlpha; +#endif + state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; + state.m_NearZ = 4.0f; + state.m_FarZ = m_flSunDistance * 2.0f; + state.m_fBrightnessScale = 2.0f; + state.m_bGlobalLight = true; + +#ifdef MAPBASE + float flOrthoSize = m_flOrthoSize; +#else + float flOrthoSize = 1000.0f; +#endif + + if ( flOrthoSize > 0 ) + { + state.m_bOrtho = true; + state.m_fOrthoLeft = -flOrthoSize; + state.m_fOrthoTop = -flOrthoSize; + state.m_fOrthoRight = flOrthoSize; + state.m_fOrthoBottom = flOrthoSize; + } + else + { + state.m_bOrtho = false; + } + +#ifdef MAPBASE + //state.m_bDrawShadowFrustum = true; // Don't draw that huge debug thing + state.m_flShadowMapResolution = cl_globallight_depthres.GetFloat(); + state.m_flShadowFilterSize = cl_globallight_shadowfiltersize.GetFloat(); + state.m_flShadowSlopeScaleDepthBias = cl_globallight_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = cl_globallight_depthbias_shadowmap.GetFloat(); + state.m_bEnableShadows = m_bEnableShadows; + state.m_pSpotlightTexture = m_SpotlightTexture; + state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; +#else + state.m_bDrawShadowFrustum = true; + /*state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias();; + state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias();*/ + state.m_bEnableShadows = m_bEnableShadows; + state.m_pSpotlightTexture = m_SpotlightTexture; + state.m_nSpotlightTextureFrame = 0; +#endif + + state.m_nShadowQuality = 1; // Allow entity to affect shadow quality +// state.m_bShadowHighRes = true; + + if ( m_bOldEnableShadows != m_bEnableShadows ) + { + // If they change the shadow enable/disable, we need to make a new handle + if ( m_LocalFlashlightHandle != CLIENTSHADOW_INVALID_HANDLE ) + { + g_pClientShadowMgr->DestroyFlashlight( m_LocalFlashlightHandle ); + m_LocalFlashlightHandle = CLIENTSHADOW_INVALID_HANDLE; + } + + m_bOldEnableShadows = m_bEnableShadows; + } + + if( m_LocalFlashlightHandle == CLIENTSHADOW_INVALID_HANDLE ) + { + m_LocalFlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state ); + } + else + { + g_pClientShadowMgr->UpdateFlashlightState( m_LocalFlashlightHandle, state ); + g_pClientShadowMgr->UpdateProjectedTexture( m_LocalFlashlightHandle, true ); + } + + bSupressWorldLights = m_bEnableShadows; + } + else if ( m_LocalFlashlightHandle != CLIENTSHADOW_INVALID_HANDLE ) + { + g_pClientShadowMgr->DestroyFlashlight( m_LocalFlashlightHandle ); + m_LocalFlashlightHandle = CLIENTSHADOW_INVALID_HANDLE; + } + + g_pClientShadowMgr->SetShadowFromWorldLightsEnabled( !bSupressWorldLights ); + + BaseClass::ClientThink(); +} \ No newline at end of file diff --git a/game/client/c_env_projectedtexture.cpp b/game/client/c_env_projectedtexture.cpp index 2c13abf0..d309f945 100644 --- a/game/client/c_env_projectedtexture.cpp +++ b/game/client/c_env_projectedtexture.cpp @@ -5,6 +5,13 @@ //============================================================================= #include "cbase.h" +#ifdef ASW_PROJECTED_TEXTURES +#include "C_Env_Projected_Texture.h" +#include "vprof.h" +#endif +#ifdef MAPBASE +#include "materialsystem/itexture.h" +#endif #include "shareddefs.h" #include "materialsystem/imesh.h" #include "materialsystem/imaterial.h" @@ -13,63 +20,100 @@ #include "view_shared.h" #include "texture_group_names.h" #include "tier0/icommandline.h" -#include "vprof.h" -#include "c_light_manager.h" - -#include "c_env_projectedtexture.h" - -#include "materialsystem/itexture.h" -#include "view_scene.h" -#include "viewrender.h" -#include "debugoverlay_shared.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef ASW_PROJECTED_TEXTURES +extern ConVarRef mat_slopescaledepthbias_shadowmap; +extern ConVarRef mat_depthbias_shadowmap; + float C_EnvProjectedTexture::m_flVisibleBBoxMinHeight = -FLT_MAX; -extern ConVar mat_slopescaledepthbias_shadowmap; -static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.00001", FCVAR_CHEAT ); static ConVar r_projtex_filtersize( "r_projtex_filtersize", "1.0", 0 ); - static ConVar r_volumetrics_enabled("r_volumetrics_enabled", "1", FCVAR_ARCHIVE); -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvProjectedTexture ) RecvPropEHandle( RECVINFO( m_hTargetEntity ) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bDontFollowTarget )), +#endif RecvPropBool( RECVINFO( m_bState ) ), RecvPropBool( RECVINFO( m_bAlwaysUpdate ) ), RecvPropFloat( RECVINFO( m_flLightFOV ) ), +#ifdef MAPBASE + RecvPropFloat( RECVINFO( m_flLightHorFOV ) ), +#endif RecvPropBool( RECVINFO( m_bEnableShadows ) ), RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ), RecvPropBool( RECVINFO( m_bLightWorld ) ), RecvPropBool( RECVINFO( m_bCameraSpace ) ), - - RecvPropBool( RECVINFO( m_bEnableVolumetrics) ), - RecvPropBool( RECVINFO( m_bEnableVolumetricsLOD)), - RecvPropFloat( RECVINFO( m_flVolumetricsFadeDistance)), - RecvPropInt( RECVINFO( m_iVolumetricsQuality)), - RecvPropFloat( RECVINFO( m_flVolumetricsQualityBias)), - RecvPropFloat( RECVINFO( m_flVolumetricsMultiplier)), - - RecvPropVector( RECVINFO( m_LinearFloatLightColor ) ), - RecvPropInt( RECVINFO( m_nLinear ) ), - RecvPropInt( RECVINFO( m_nQuadratic ) ), - RecvPropInt( RECVINFO( m_nConstant ) ), - + RecvPropFloat( RECVINFO( m_flBrightnessScale ) ), + RecvPropInt( RECVINFO( m_LightColor ), 0, RecvProxy_IntToColor32 ), + RecvPropFloat( RECVINFO( m_flColorTransitionTime ) ), RecvPropFloat( RECVINFO( m_flAmbient ) ), RecvPropString( RECVINFO( m_SpotlightTextureName ) ), RecvPropInt( RECVINFO( m_nSpotlightTextureFrame ) ), RecvPropFloat( RECVINFO( m_flNearZ ) ), RecvPropFloat( RECVINFO( m_flFarZ ) ), RecvPropInt( RECVINFO( m_nShadowQuality ) ), +#ifdef MAPBASE + RecvPropFloat( RECVINFO( m_flConstantAtten ) ), + RecvPropFloat( RECVINFO( m_flLinearAtten ) ), + RecvPropFloat( RECVINFO( m_flQuadraticAtten ) ), + RecvPropFloat( RECVINFO( m_flShadowAtten ) ), + RecvPropFloat( RECVINFO( m_flShadowFilter ) ), + RecvPropBool( RECVINFO( m_bAlwaysDraw ) ), + + // Not needed on the client right now, change when it actually is needed + //RecvPropBool( RECVINFO( m_bProjectedTextureVersion ) ), +#endif END_RECV_TABLE() +C_EnvProjectedTexture *C_EnvProjectedTexture::Create( ) +{ + C_EnvProjectedTexture *pEnt = new C_EnvProjectedTexture(); + + pEnt->m_flNearZ = 4.0f; + pEnt->m_flFarZ = 2000.0f; +// strcpy( pEnt->m_SpotlightTextureName, "particle/rj" ); + pEnt->m_bLightWorld = true; + pEnt->m_bLightOnlyTarget = false; + pEnt->m_nShadowQuality = 1; + pEnt->m_flLightFOV = 10.0f; +#ifdef MAPBASE + pEnt->m_flLightHorFOV = 10.0f; +#endif + pEnt->m_LightColor.r = 255; + pEnt->m_LightColor.g = 255; + pEnt->m_LightColor.b = 255; + pEnt->m_LightColor.a = 255; + pEnt->m_bEnableShadows = false; + pEnt->m_flColorTransitionTime = 1.0f; + pEnt->m_bCameraSpace = false; + pEnt->SetAbsAngles( QAngle( 90, 0, 0 ) ); + pEnt->m_bAlwaysUpdate = true; + pEnt->m_bState = true; +#ifdef MAPBASE + pEnt->m_bAlwaysDraw = false; + pEnt->m_flConstantAtten = 0.0f; + pEnt->m_flLinearAtten = 100.0f; + pEnt->m_flQuadraticAtten = 0.0f; + pEnt->m_flShadowAtten = 0.0f; + pEnt->m_flShadowFilter = 0.5f; + //pEnt->m_bProjectedTextureVersion = 1; +#endif + + return pEnt; +} + C_EnvProjectedTexture::C_EnvProjectedTexture( void ) { m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; + m_bForceUpdate = true; +#ifndef MAPBASE + AddToEntityList( ENTITY_LIST_SIMULATE ); +#endif } C_EnvProjectedTexture::~C_EnvProjectedTexture( void ) @@ -87,6 +131,15 @@ void C_EnvProjectedTexture::ShutDownLightHandle( void ) } } + +void C_EnvProjectedTexture::SetLightColor( byte r, byte g, byte b, byte a ) +{ + m_LightColor.r = r; + m_LightColor.g = g; + m_LightColor.b = b; + m_LightColor.a = a; +} + //----------------------------------------------------------------------------- // Purpose: // Input : updateType - @@ -97,9 +150,19 @@ void C_EnvProjectedTexture::OnDataChanged( DataUpdateType_t updateType ) { m_SpotlightTexture.Init( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, true ); } +#ifdef MAPBASE + else //if ( updateType == DATA_UPDATE_DATATABLE_CHANGED ) + { + // It could've been changed via input + if( !FStrEq(m_SpotlightTexture->GetName(), m_SpotlightTextureName) ) + { + m_SpotlightTexture.Init( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, true ); + } + } +#endif m_bForceUpdate = true; - UpdateLight(false); + UpdateLight(); BaseClass::OnDataChanged( updateType ); } @@ -110,40 +173,89 @@ void C_EnvProjectedTexture::UpdateOnRemove() BaseClass::UpdateOnRemove(); } -void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) +static ConVar asw_perf_wtf("asw_perf_wtf", "0", FCVAR_DEVELOPMENTONLY, "Disable updating of projected shadow textures from UpdateLight" ); +void C_EnvProjectedTexture::UpdateLight( void ) { - VPROF( "C_EnvProjectedTexture::UpdateLight" ); + VPROF("C_EnvProjectedTexture::UpdateLight"); bool bVisible = true; - if (bForceUpdate) + Vector vLinearFloatLightColor( m_LightColor.r, m_LightColor.g, m_LightColor.b ); + float flLinearFloatLightAlpha = m_LightColor.a; + + if ( m_bAlwaysUpdate ) { m_bForceUpdate = true; } +#ifdef MAPBASE + if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha || m_flCurrentBrightnessScale != m_flBrightnessScale ) + { + if (m_flColorTransitionTime != 0.0f) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed ); + m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed ); + m_flCurrentBrightnessScale = Approach( m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed ); + } + else + { + // Just do it instantly + m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x; + m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y; + m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z; + m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha; + m_flCurrentBrightnessScale = m_flBrightnessScale; + } + + m_bForceUpdate = true; + } +#else + if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha ) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed ); + m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed ); + m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed ); + + m_bForceUpdate = true; + } +#endif + if ( !m_bForceUpdate ) { - bVisible = IsBBoxVisible(); + bVisible = IsBBoxVisible(); } if ( m_bState == false || !bVisible ) { + // Spotlight's extents aren't in view ShutDownLightHandle(); - RemoveVolumetrics(); + return; } if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE || m_hTargetEntity != NULL || m_bForceUpdate ) { Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); + FlashlightState_t state; +#ifdef MAPBASE + if ( m_hTargetEntity != NULL && !m_bDontFollowTarget ) +#else if ( m_hTargetEntity != NULL ) +#endif { if ( m_bCameraSpace ) { - const QAngle& angles = GetLocalAngles(); + const QAngle &angles = GetLocalAngles(); - C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); - if ( pPlayer ) + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if( pPlayer ) { const QAngle playerAngles = pPlayer->GetAbsAngles(); @@ -157,8 +269,8 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) VectorITransform( vPlayerRight, mRotMatrix, vRight ); VectorITransform( vPlayerUp, mRotMatrix, vUp ); - float dist = ( m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin() ).Length(); - vPos = m_hTargetEntity->GetAbsOrigin() - vForward * dist; + float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length(); + vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist; VectorNormalize( vForward ); VectorNormalize( vRight ); @@ -167,19 +279,23 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) } else { - // VXP: Fixing targeting - Vector vecToTarget; - QAngle vecAngles; - if ( m_hTargetEntity == NULL ) - { - vecAngles = GetAbsAngles(); - } - else - { - vecToTarget = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); - VectorAngles( vecToTarget, vecAngles ); - } - AngleVectors( vecAngles, &vForward, &vRight, &vUp ); + vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); + VectorNormalize( vForward ); + + // JasonM - unimplemented + Assert (0); + + //Quaternion q = DirectionToOrientation( dir ); + + + // + // JasonM - set up vRight, vUp + // + + // VectorNormalize( vRight ); + // VectorNormalize( vUp ); + + VectorVectors( vForward, vRight, vUp ); } } else @@ -187,33 +303,48 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp ); } - m_FlashlightState.m_fHorizontalFOVDegrees = m_flLightFOV; - m_FlashlightState.m_fVerticalFOVDegrees = m_flLightFOV; +#ifdef MAPBASE + float fHighFOV; + if( m_flLightFOV > m_flLightHorFOV ) + fHighFOV = m_flLightFOV; + else + fHighFOV = m_flLightHorFOV; + + state.m_fHorizontalFOVDegrees = m_flLightHorFOV; +#else + state.m_fHorizontalFOVDegrees = m_flLightFOV; +#endif + state.m_fVerticalFOVDegrees = m_flLightFOV; - m_FlashlightState.m_vecLightOrigin = vPos; - BasisToQuaternion( vForward, vRight, vUp, m_FlashlightState.m_quatOrientation ); + state.m_vecLightOrigin = vPos; + BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation ); + state.m_NearZ = m_flNearZ; + state.m_FarZ = m_flFarZ; // quickly check the proposed light's bbox against the view frustum to determine whether we // should bother to create it, if it doesn't exist, or cull it, if it does. -#pragma message( "OPTIMIZATION: this should be made SIMD" ) // get the half-widths of the near and far planes, // based on the FOV which is in degrees. Remember that // on planet Valve, x is forward, y left, and z up. - const float tanHalfAngle = tan( m_flLightFOV * ( M_PI / 180.0f ) * 0.5f ); +#ifdef MAPBASE + const float tanHalfAngle = tan( fHighFOV * ( M_PI/180.0f ) * 0.5f ); +#else + const float tanHalfAngle = tan( m_flLightFOV * ( M_PI/180.0f ) * 0.5f ); +#endif const float halfWidthNear = tanHalfAngle * m_flNearZ; const float halfWidthFar = tanHalfAngle * m_flFarZ; // now we can build coordinates in local space: the near rectangle is eg // (0, -halfWidthNear, -halfWidthNear), (0, halfWidthNear, -halfWidthNear), // (0, halfWidthNear, halfWidthNear), (0, -halfWidthNear, halfWidthNear) - VectorAligned vNearRect[ 4 ] = { - VectorAligned( m_flNearZ, -halfWidthNear, -halfWidthNear ), VectorAligned( m_flNearZ, halfWidthNear, -halfWidthNear ), - VectorAligned( m_flNearZ, halfWidthNear, halfWidthNear ), VectorAligned( m_flNearZ, -halfWidthNear, halfWidthNear ) + VectorAligned vNearRect[4] = { + VectorAligned( m_flNearZ, -halfWidthNear, -halfWidthNear), VectorAligned( m_flNearZ, halfWidthNear, -halfWidthNear), + VectorAligned( m_flNearZ, halfWidthNear, halfWidthNear), VectorAligned( m_flNearZ, -halfWidthNear, halfWidthNear) }; - VectorAligned vFarRect[ 4 ] = { - VectorAligned( m_flFarZ, -halfWidthFar, -halfWidthFar ), VectorAligned( m_flFarZ, halfWidthFar, -halfWidthFar ), - VectorAligned( m_flFarZ, halfWidthFar, halfWidthFar ), VectorAligned( m_flFarZ, -halfWidthFar, halfWidthFar ) + VectorAligned vFarRect[4] = { + VectorAligned( m_flFarZ, -halfWidthFar, -halfWidthFar), VectorAligned( m_flFarZ, halfWidthFar, -halfWidthFar), + VectorAligned( m_flFarZ, halfWidthFar, halfWidthFar), VectorAligned( m_flFarZ, -halfWidthFar, halfWidthFar) }; matrix3x4_t matOrientation( vForward, -vRight, vUp, vPos ); @@ -223,42 +354,42 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) kNEAR = 0, kFAR = 1, }; - VectorAligned vOutRects[ 2 ][ 4 ]; + VectorAligned vOutRects[2][4]; - for ( int i = 0; i < 4; ++i ) + for ( int i = 0 ; i < 4 ; ++i ) { - VectorTransform( vNearRect[ i ].Base(), matOrientation, vOutRects[ 0 ][ i ].Base() ); + VectorTransform( vNearRect[i].Base(), matOrientation, vOutRects[0][i].Base() ); } - for ( int i = 0; i < 4; ++i ) + for ( int i = 0 ; i < 4 ; ++i ) { - VectorTransform( vFarRect[ i ].Base(), matOrientation, vOutRects[ 1 ][ i ].Base() ); + VectorTransform( vFarRect[i].Base(), matOrientation, vOutRects[1][i].Base() ); } // now take the min and max extents for the bbox, and see if it is visible. - Vector mins = **vOutRects; - Vector maxs = **vOutRects; - for ( int i = 1; i < 8; ++i ) + Vector mins = **vOutRects; + Vector maxs = **vOutRects; + for ( int i = 1; i < 8 ; ++i ) { - VectorMin( mins, *( *vOutRects + i ), mins ); - VectorMax( maxs, *( *vOutRects + i ), maxs ); + VectorMin( mins, *(*vOutRects+i), mins ); + VectorMax( maxs, *(*vOutRects+i), maxs ); } #if 0 //for debugging the visibility frustum we just calculated - NDebugOverlay::Triangle( vOutRects[ 0 ][ 0 ], vOutRects[ 0 ][ 1 ], vOutRects[ 0 ][ 2 ], 255, 0, 0, 100, true, 0.0f ); //first tri - NDebugOverlay::Triangle( vOutRects[ 0 ][ 2 ], vOutRects[ 0 ][ 1 ], vOutRects[ 0 ][ 0 ], 255, 0, 0, 100, true, 0.0f ); //make it double sided - NDebugOverlay::Triangle( vOutRects[ 0 ][ 2 ], vOutRects[ 0 ][ 3 ], vOutRects[ 0 ][ 0 ], 255, 0, 0, 100, true, 0.0f ); //second tri - NDebugOverlay::Triangle( vOutRects[ 0 ][ 0 ], vOutRects[ 0 ][ 3 ], vOutRects[ 0 ][ 2 ], 255, 0, 0, 100, true, 0.0f ); //make it double sided + NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][1], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //first tri + NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][1], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //make it double sided + NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][3], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //second tri + NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][3], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //make it double sided - NDebugOverlay::Triangle( vOutRects[ 1 ][ 0 ], vOutRects[ 1 ][ 1 ], vOutRects[ 1 ][ 2 ], 0, 0, 255, 100, true, 0.0f ); //first tri - NDebugOverlay::Triangle( vOutRects[ 1 ][ 2 ], vOutRects[ 1 ][ 1 ], vOutRects[ 1 ][ 0 ], 0, 0, 255, 100, true, 0.0f ); //make it double sided - NDebugOverlay::Triangle( vOutRects[ 1 ][ 2 ], vOutRects[ 1 ][ 3 ], vOutRects[ 1 ][ 0 ], 0, 0, 255, 100, true, 0.0f ); //second tri - NDebugOverlay::Triangle( vOutRects[ 1 ][ 0 ], vOutRects[ 1 ][ 3 ], vOutRects[ 1 ][ 2 ], 0, 0, 255, 100, true, 0.0f ); //make it double sided + NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][1], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //first tri + NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][1], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //make it double sided + NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][3], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //second tri + NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][3], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //make it double sided NDebugOverlay::Box( vec3_origin, mins, maxs, 0, 255, 0, 100, 0.0f ); #endif - - bVisible = IsBBoxVisible( mins, maxs ); - if ( !bVisible ) + + bool bVisible = IsBBoxVisible( mins, maxs ); + if (!bVisible) { // Spotlight's extents aren't in view if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) @@ -269,37 +400,47 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) return; } - /*state.m_fQuadraticAtten = r_projtex_quadratic.GetInt(); //0 - state.m_fLinearAtten = r_projtex_linear.GetInt(); //100 - state.m_fConstantAtten = r_projtex_constant.GetInt(); //0*/ - - m_FlashlightState.m_fQuadraticAtten = m_nQuadratic; //0 - m_FlashlightState.m_fLinearAtten = m_nLinear; //100 - m_FlashlightState.m_fConstantAtten = m_nConstant; - - m_FlashlightState.m_Color[ 0 ] = m_LinearFloatLightColor.x; - m_FlashlightState.m_Color[ 1 ] = m_LinearFloatLightColor.y; - m_FlashlightState.m_Color[ 2 ] = m_LinearFloatLightColor.z; - m_FlashlightState.m_Color[ 3 ] = 0.0f; // fixme: need to make ambient work m_flAmbient; - m_FlashlightState.m_NearZ = m_flNearZ; - m_FlashlightState.m_FarZ = m_flFarZ; - //state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); - m_FlashlightState.m_flShadowSlopeScaleDepthBias = 4.0f; - //state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); - m_FlashlightState.m_flShadowDepthBias = 0.00001f; - m_FlashlightState.m_bEnableShadows = m_bEnableShadows; - //state.m_pSpotlightTexture = materials->FindTexture( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false ); - m_FlashlightState.m_pSpotlightTexture = m_SpotlightTexture; - m_FlashlightState.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; - - m_FlashlightState.m_flShadowAtten = 0.0f; // kind of like a fade out for the shadows - m_FlashlightState.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality - - m_FlashlightState.m_flShadowFilterSize = r_projtex_filtersize.GetFloat(); - - if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE ) + float flAlpha = m_flCurrentLinearFloatLightAlpha * ( 1.0f / 255.0f ); + +#ifdef MAPBASE + state.m_fConstantAtten = m_flConstantAtten; + state.m_fLinearAtten = m_flLinearAtten; + state.m_fQuadraticAtten = m_flQuadraticAtten; + state.m_FarZAtten = m_flFarZ; + state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; + state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; + state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale; + state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; + state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); + state.m_flShadowAtten = m_flShadowAtten; + state.m_flShadowFilterSize = m_flShadowFilter; +#else + state.m_fQuadraticAtten = 0.0; + state.m_fLinearAtten = 100; + state.m_fConstantAtten = 0.0f; + state.m_FarZAtten = m_flFarZ; + state.m_fBrightnessScale = m_flBrightnessScale; + state.m_Color[0] = m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha; + state.m_Color[1] = m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha; + state.m_Color[2] = m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha; + state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; + state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias(); + state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias(); +#endif + state.m_bEnableShadows = m_bEnableShadows; + state.m_pSpotlightTexture = m_SpotlightTexture; + state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; + + state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality + +#ifdef MAPBASE + state.m_bAlwaysDraw = m_bAlwaysDraw; +#endif + + if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE ) { - m_LightHandle = g_pClientShadowMgr->CreateFlashlight(m_FlashlightState); + m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state ); if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) { @@ -308,12 +449,7 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) } else { - if ( m_hTargetEntity != NULL || m_bForceUpdate == true ) - { - g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, m_FlashlightState); - } - - //g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); + g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); m_bForceUpdate = false; } @@ -323,7 +459,7 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) m_vecExtentsMax = m_vecExtentsMax - GetAbsOrigin(); } - if ( m_bLightOnlyTarget ) + if( m_bLightOnlyTarget ) { g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity ); } @@ -334,10 +470,10 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld ); - //if ( !m_bForceUpdate ) - //{ + if ( !asw_perf_wtf.GetBool() && !m_bForceUpdate ) + { g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); - //} + } if (m_bEnableVolumetrics && m_bEnableShadows) { @@ -378,18 +514,23 @@ void C_EnvProjectedTexture::UpdateLight(bool bForceUpdate) UpdateVolumetricsState(); } + } void C_EnvProjectedTexture::Simulate( void ) { - UpdateLight(GetMoveParent() != NULL); + UpdateLight(); BaseClass::Simulate(); - //return true; } bool C_EnvProjectedTexture::IsBBoxVisible( Vector vecExtentsMin, Vector vecExtentsMax ) { +#ifdef MAPBASE + if (m_bAlwaysDraw) + return true; +#endif + // Z position clamped to the min height (but must be less than the max) float flVisibleBBoxMinHeight = MIN( vecExtentsMax.z - 1.0f, m_flVisibleBBoxMinHeight ); vecExtentsMin.z = MAX( vecExtentsMin.z, flVisibleBBoxMinHeight ); @@ -398,9 +539,311 @@ bool C_EnvProjectedTexture::IsBBoxVisible( Vector vecExtentsMin, Vector vecExten return !engine->CullBox( vecExtentsMin, vecExtentsMax ); } +#else + +#ifndef MAPBASE +static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT ); +static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT ); +#else +static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "4", FCVAR_CHEAT ); +static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.00001", FCVAR_CHEAT ); +#endif + +//----------------------------------------------------------------------------- +// 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(); + +#ifdef MAPBASE + void UpdateLight(); +#else + void UpdateLight( bool bForceUpdate ); +#endif + + C_EnvProjectedTexture(); + ~C_EnvProjectedTexture(); + +private: + + ClientShadowHandle_t m_LightHandle; +#ifdef MAPBASE + bool m_bForceUpdate; +#endif + + EHANDLE m_hTargetEntity; + + bool m_bState; +#ifdef MAPBASE + bool m_bAlwaysUpdate; +#endif + 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 ) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bAlwaysUpdate ) ), +#endif + 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 ) +{ +#ifdef MAPBASE + m_bForceUpdate = true; + UpdateLight(); +#else + UpdateLight( true ); +#endif + BaseClass::OnDataChanged( updateType ); +} + +#ifndef MAPBASE +void C_EnvProjectedTexture::UpdateLight( bool bForceUpdate ) +#else +void C_EnvProjectedTexture::UpdateLight() +#endif +{ +#ifndef MAPBASE + if ( m_bState == false ) + { + if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) + { + ShutDownLightHandle(); + } + + return; + } +#else + if ( m_bAlwaysUpdate ) + { + m_bForceUpdate = true; + } + + if ( m_bState == false ) + { + // Spotlight's extents aren't in view + ShutDownLightHandle(); + + return; + } +#endif + +#ifdef MAPBASE + if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE || m_hTargetEntity != NULL || m_bForceUpdate ) + { +#endif + 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 + { +#ifndef MAPBASE + vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); + VectorNormalize( vForward ); +#else + // VXP: Fixing targeting + Vector vecToTarget; + QAngle vecAngles; + if (m_hTargetEntity == NULL) + { + vecAngles = GetAbsAngles(); + } + else + { + vecToTarget = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); + VectorAngles(vecToTarget, vecAngles); + } + AngleVectors(vecAngles, &vForward, &vRight, &vUp); +#endif + + // 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 + { +#ifndef MAPBASE + if ( m_hTargetEntity != NULL || bForceUpdate == true ) + { + g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); + } +#else + g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); + m_bForceUpdate = false; +#endif + } +#ifdef MAPBASE + } +#endif + + if( m_bLightOnlyTarget ) + { + g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity ); + } + else + { + g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, NULL ); + } + + g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld ); + +#ifndef MAPBASE + if ( bForceUpdate == false ) + { + g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); + } +#else + if ( !m_bForceUpdate ) + { + g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); + } +#endif +} + +void C_EnvProjectedTexture::Simulate( void ) +{ +#ifndef MAPBASE + UpdateLight( false ); +#else + UpdateLight(); +#endif + + BaseClass::Simulate(); +} + +#endif void C_EnvProjectedTexture::UpdateVolumetricsState() { +#if 0 if (!m_bState || !m_bEnableVolumetrics || !r_volumetrics_enabled.GetBool() || @@ -451,6 +894,7 @@ void C_EnvProjectedTexture::UpdateVolumetricsState() } return; +#endif } void C_EnvProjectedTexture::RemoveVolumetrics() @@ -458,8 +902,9 @@ void C_EnvProjectedTexture::RemoveVolumetrics() GetLightingManager()->RemoveLight(&m_volumelight); } -void C_EnvProjectedTexture::GetShadowViewSetup(CViewSetup& setup) +void C_EnvProjectedTexture::GetShadowViewSetup( CViewSetup &setup ) { +#if 0 setup.origin = m_FlashlightState.m_vecLightOrigin; QuaternionAngles(m_FlashlightState.m_quatOrientation, setup.angles); setup.fov = m_flLightFOV; @@ -468,6 +913,8 @@ void C_EnvProjectedTexture::GetShadowViewSetup(CViewSetup& setup) setup.m_bOrtho = false; setup.m_flAspectRatio = 1.0f; setup.x = setup.y = 0; - setup.width = m_FlashlightState.m_pSpotlightTexture ? m_FlashlightState.m_pSpotlightTexture->GetActualWidth() : 512; - setup.height = m_FlashlightState.m_pSpotlightTexture ? m_FlashlightState.m_pSpotlightTexture->GetActualHeight() : 512; -} \ No newline at end of file + setup.width = m_SpotlightTexture->GetActualWidth(); //m_FlashlightState.m_pSpotlightTexture ? m_FlashlightState.m_pSpotlightTexture->GetActualWidth() : 512; + setup.height = m_SpotlightTexture->GetActualHeight(); //m_FlashlightState.m_pSpotlightTexture ? m_FlashlightState.m_pSpotlightTexture->GetActualHeight() : 512; +#endif +} + diff --git a/game/client/c_env_projectedtexture.h b/game/client/c_env_projectedtexture.h deleted file mode 100644 index 5ee48cb9..00000000 --- a/game/client/c_env_projectedtexture.h +++ /dev/null @@ -1,144 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef C_ENVPROJECTED_TEXTURE_H -#define C_ENVPROJECTED_TEXTURE_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(); - - virtual void OnDataChanged( DataUpdateType_t updateType ); - void ShutDownLightHandle( void ); - - virtual void Simulate(); - - void UpdateLight( bool bForceUpdate ); - - C_EnvProjectedTexture(); - ~C_EnvProjectedTexture(); - - static void SetVisibleBBoxMinHeight( float flVisibleBBoxMinHeight ) { m_flVisibleBBoxMinHeight = flVisibleBBoxMinHeight; } - static float GetVisibleBBoxMinHeight( void ) { return m_flVisibleBBoxMinHeight; } - static C_EnvProjectedTexture *Create( ); - - virtual void UpdateOnRemove(); - - virtual bool IsTransparent() { return false; } - virtual bool IsTwoPass() { return false; } - - virtual void GetRenderBoundsWorldspace(Vector& mins, Vector& maxs) - { - if (m_bEnableVolumetrics) - { - mins = m_vecRenderBoundsMin; - maxs = m_vecRenderBoundsMax; - } - else - { - BaseClass::GetRenderBoundsWorldspace(mins, maxs); - } - } - - virtual void GetRenderBounds(Vector& mins, Vector& maxs) - { - if (m_bEnableVolumetrics) - { - mins = m_vecRenderBoundsMin - GetAbsOrigin(); - maxs = m_vecRenderBoundsMax - GetAbsOrigin(); - } - else - { - BaseClass::GetRenderBounds(mins, maxs); - } - } - - virtual bool ShouldDraw(void) { return false; } - - virtual bool ShouldReceiveProjectedTextures(int flags) { return false; } - -private: - inline bool IsBBoxVisible( void ); - bool IsBBoxVisible( Vector vecExtentsMin, - Vector vecExtentsMax ); - - void GetShadowViewSetup(CViewSetup& setup); - void UpdateVolumetricsState(); - void RemoveVolumetrics(); - - Vector m_vecRenderBoundsMin, m_vecRenderBoundsMax; - FlashlightState_t m_FlashlightState; - ClientShadowHandle_t m_LightHandle; - bool m_bForceUpdate; - - EHANDLE m_hTargetEntity; - - bool m_bState; - bool m_bAlwaysUpdate; - float m_flLightFOV; - bool m_bEnableShadows; - bool m_bLightOnlyTarget; - bool m_bLightWorld; - bool m_bCameraSpace; - - Vector m_LinearFloatLightColor; - int m_nLinear; - int m_nQuadratic; - int m_nConstant; - - float m_flAmbient; - float m_flNearZ; - float m_flFarZ; - char m_SpotlightTextureName[MAX_PATH]; - CTextureReference m_SpotlightTexture; - int m_nSpotlightTextureFrame; - int m_nShadowQuality; - - float m_fNearEdge; - float m_fFarEdge; - float m_fCutOn; - float m_fCutOff; - float m_fShearx; - float m_fSheary; - float m_fWidth; - float m_fWedge; - float m_fHeight; - float m_fHedge; - float m_fRoundness; - - Vector m_vecExtentsMin; - Vector m_vecExtentsMax; - - static float m_flVisibleBBoxMinHeight; - - bool m_bEnableVolumetrics; - bool m_bEnableVolumetricsLOD; - float m_flVolumetricsFadeDistance; - int m_iVolumetricsQuality; - float m_flVolumetricsMultiplier; - float m_flVolumetricsQualityBias; - int m_iCurrentVolumetricsSubDiv; - volume_light_t m_volumelight; -}; - -bool C_EnvProjectedTexture::IsBBoxVisible( void ) -{ - return IsBBoxVisible( GetAbsOrigin() + m_vecExtentsMin, GetAbsOrigin() + m_vecExtentsMax ); -} - -#endif // C_ENV_PROJECTED_TEXTURE_H \ No newline at end of file diff --git a/game/client/c_env_screenoverlay.cpp b/game/client/c_env_screenoverlay.cpp index 5496d453..a3125882 100644 --- a/game/client/c_env_screenoverlay.cpp +++ b/game/client/c_env_screenoverlay.cpp @@ -48,6 +48,9 @@ class C_EnvScreenOverlay : public C_BaseEntity int m_iCachedDesiredOverlay; int m_iCurrentOverlay; float m_flCurrentOverlayTime; +#ifdef MAPBASE + int m_iOverlayIndex; +#endif }; IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenOverlay, DT_EnvScreenOverlay, CEnvScreenOverlay ) @@ -56,6 +59,9 @@ IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenOverlay, DT_EnvScreenOverlay, CEnvScreenOve RecvPropFloat( RECVINFO( m_flStartTime ) ), RecvPropInt( RECVINFO( m_iDesiredOverlay ) ), RecvPropBool( RECVINFO( m_bIsActive ) ), +#ifdef MAPBASE + RecvPropInt( RECVINFO( m_iOverlayIndex ) ), +#endif END_RECV_TABLE() //----------------------------------------------------------------------------- @@ -77,7 +83,11 @@ void C_EnvScreenOverlay::PostDataUpdate( DataUpdateType_t updateType ) BaseClass::PostDataUpdate( updateType ); // If we have a start time now, start the overlays going +#ifdef MAPBASE + if ( m_bIsActive && m_flStartTime > 0 && (view->GetScreenOverlayMaterial() == NULL || (m_iOverlayIndex != -1 && view->GetIndexedScreenOverlayMaterial(m_iOverlayIndex) == NULL)) ) +#else if ( m_bIsActive && m_flStartTime > 0 && view->GetScreenOverlayMaterial() == NULL ) +#endif { StartOverlays(); } @@ -111,7 +121,16 @@ void C_EnvScreenOverlay::StopOverlays( void ) if ( m_bWasActive && !m_bIsActive ) { - view->SetScreenOverlayMaterial( NULL ); +#ifdef MAPBASE + if (m_iOverlayIndex != -1) + { + view->SetIndexedScreenOverlayMaterial( m_iOverlayIndex, NULL ); + } + else +#endif + { + view->SetScreenOverlayMaterial( NULL ); + } } } @@ -163,7 +182,16 @@ void C_EnvScreenOverlay::StartCurrentOverlay( void ) IMaterial *pMaterial = materials->FindMaterial( m_iszOverlayNames[m_iCurrentOverlay], TEXTURE_GROUP_CLIENT_EFFECTS, false ); if ( !IsErrorMaterial( pMaterial ) ) { - view->SetScreenOverlayMaterial( pMaterial ); +#ifdef MAPBASE + if (m_iOverlayIndex != -1) + { + view->SetIndexedScreenOverlayMaterial( m_iOverlayIndex, pMaterial ); + } + else +#endif + { + view->SetScreenOverlayMaterial( pMaterial ); + } } else { diff --git a/game/client/c_fire_smoke.cpp b/game/client/c_fire_smoke.cpp index 42e6f3ed..f4551a89 100644 --- a/game/client/c_fire_smoke.cpp +++ b/game/client/c_fire_smoke.cpp @@ -20,11 +20,6 @@ #include "tier0/memdbgon.h" -CLIENTEFFECT_REGISTER_BEGIN( SmokeStackMaterials ) - CLIENTEFFECT_MATERIAL( "particle/SmokeStack" ) -CLIENTEFFECT_REGISTER_END() - - //----------------------------------------------------------------------------- // Purpose: // Input : *pRecvProp - @@ -109,6 +104,12 @@ C_FireSmoke::~C_FireSmoke() } +void C_FireSmoke::Precache() +{ + BaseClass::Precache(); + PrecacheMaterial( "particle/SmokeStack" ); +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/client/c_fire_smoke.h b/game/client/c_fire_smoke.h index 9f7a94e1..368667c7 100644 --- a/game/client/c_fire_smoke.h +++ b/game/client/c_fire_smoke.h @@ -121,6 +121,8 @@ class C_FireSmoke : public C_BaseEntity C_FireSmoke(); ~C_FireSmoke(); + void Precache(); + void Start( void ); void Simulate( void ); diff --git a/game/client/c_func_dust.cpp b/game/client/c_func_dust.cpp index 94f114e4..c3c3d79d 100644 --- a/game/client/c_func_dust.cpp +++ b/game/client/c_func_dust.cpp @@ -88,8 +88,9 @@ void CDustEffect::RenderParticles( CParticleRenderIterator *pIterator ) void CDustEffect::SimulateParticles( CParticleSimulateIterator *pIterator ) { Vector vecWind; +#ifndef MAPBASE GetWindspeedAtTime( gpGlobals->curtime, vecWind ); - +#endif CFuncDustParticle *pParticle = (CFuncDustParticle*)pIterator->GetFirst(); while ( pParticle ) @@ -105,6 +106,9 @@ void CDustEffect::SimulateParticles( CParticleSimulateIterator *pIterator ) } else { +#ifdef MAPBASE + vecWind = GetWindspeedAtLocation( pParticle->m_Pos ); +#endif for ( int i = 0 ; i < 2 ; i++ ) { if ( pParticle->m_vVelocity[i] < vecWind[i] ) diff --git a/game/client/c_func_lod.cpp b/game/client/c_func_lod.cpp index 766cced3..89998824 100644 --- a/game/client/c_func_lod.cpp +++ b/game/client/c_func_lod.cpp @@ -30,6 +30,9 @@ class C_Func_LOD : public C_BaseEntity // These are documented in the server-side entity. public: float m_fDisappearDist; +#ifdef MAPBASE + float m_fDisappearMaxDist; +#endif }; @@ -43,6 +46,9 @@ ConVar lod_TransitionDist("lod_TransitionDist", "800"); // Datatable.. IMPLEMENT_CLIENTCLASS_DT(C_Func_LOD, DT_Func_LOD, CFunc_LOD) RecvPropFloat(RECVINFO(m_fDisappearDist)), +#ifdef MAPBASE + RecvPropFloat(RECVINFO(m_fDisappearMaxDist)), +#endif END_RECV_TABLE() @@ -54,6 +60,9 @@ END_RECV_TABLE() C_Func_LOD::C_Func_LOD() { m_fDisappearDist = 5000.0f; +#ifdef MAPBASE + m_fDisappearMaxDist = 0.0f; +#endif } //----------------------------------------------------------------------------- @@ -61,7 +70,11 @@ C_Func_LOD::C_Func_LOD() //----------------------------------------------------------------------------- unsigned char C_Func_LOD::GetClientSideFade() { +#ifdef MAPBASE + return UTIL_ComputeEntityFade( this, m_fDisappearDist, m_fDisappearDist + (m_fDisappearMaxDist != 0 ? m_fDisappearMaxDist : lod_TransitionDist.GetFloat()), 1.0f ); +#else return UTIL_ComputeEntityFade( this, m_fDisappearDist, m_fDisappearDist + lod_TransitionDist.GetFloat(), 1.0f ); +#endif } diff --git a/game/client/c_func_reflective_glass.cpp b/game/client/c_func_reflective_glass.cpp index 994d62ba..4e3040d3 100644 --- a/game/client/c_func_reflective_glass.cpp +++ b/game/client/c_func_reflective_glass.cpp @@ -6,6 +6,9 @@ //===========================================================================// #include "cbase.h" #include "view_shared.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -23,10 +26,27 @@ class C_FuncReflectiveGlass : public C_BaseEntity virtual bool ShouldDraw(); +#ifdef MAPBASE + virtual void OnDataChanged( DataUpdateType_t type ); + ITexture *ReflectionRenderTarget(); + ITexture *RefractionRenderTarget(); + + char m_iszReflectRenderTarget[64]; + char m_iszRefractRenderTarget[64]; + ITexture *m_pReflectRenderTarget; + ITexture *m_pRefractRenderTarget; +#endif + C_FuncReflectiveGlass *m_pNext; }; IMPLEMENT_CLIENTCLASS_DT( C_FuncReflectiveGlass, DT_FuncReflectiveGlass, CFuncReflectiveGlass ) + +#ifdef MAPBASE + RecvPropString( RECVINFO( m_iszReflectRenderTarget ) ), + RecvPropString( RECVINFO( m_iszRefractRenderTarget ) ), +#endif + END_RECV_TABLE() @@ -47,6 +67,11 @@ C_FuncReflectiveGlass* GetReflectiveGlassList() //----------------------------------------------------------------------------- C_FuncReflectiveGlass::C_FuncReflectiveGlass() { +#ifdef MAPBASE + m_iszReflectRenderTarget[0] = '\0'; + m_iszRefractRenderTarget[0] = '\0'; +#endif + g_ReflectiveGlassList.Insert( this ); } @@ -114,5 +139,111 @@ bool IsReflectiveGlassInView( const CViewSetup& view, cplane_t &plane ) return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Iterates through reflective glass instead of just picking one +//----------------------------------------------------------------------------- +C_BaseEntity *NextReflectiveGlass( C_BaseEntity *pStart, const CViewSetup& view, cplane_t &plane, + const Frustum_t &frustum, ITexture **pRenderTargets ) +{ + // Early out if no cameras + C_FuncReflectiveGlass *pReflectiveGlass = NULL; + if (!pStart) + pReflectiveGlass = GetReflectiveGlassList(); + else + pReflectiveGlass = ((C_FuncReflectiveGlass*)pStart)->m_pNext; + + cplane_t localPlane; + Vector vecOrigin, vecWorld, vecDelta; + for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) + { + if ( pReflectiveGlass->IsDormant() ) + continue; + + if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) ) + continue; + + Vector vecMins, vecMaxs; + pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); + if ( R_CullBox( vecMins, vecMaxs, frustum ) ) + continue; + + const model_t *pModel = pReflectiveGlass->GetModel(); + const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform(); + + int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); + for ( int i = 0; i < nCount; ++i ) + { + modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin ); + + MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space + VectorTransform( vecOrigin, mat, vecWorld ); + + if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane + continue; + + VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull + if ( vecDelta.Dot( plane.normal ) >= 0 ) + continue; + + if (pRenderTargets != NULL) + { + pRenderTargets[0] = pReflectiveGlass->ReflectionRenderTarget(); + pRenderTargets[1] = pReflectiveGlass->RefractionRenderTarget(); + } + + return pReflectiveGlass; + } + } + + return NULL; +} + +void C_FuncReflectiveGlass::OnDataChanged( DataUpdateType_t type ) +{ + // Reset render textures + m_pReflectRenderTarget = NULL; + m_pRefractRenderTarget = NULL; + + return BaseClass::OnDataChanged( type ); +} + +ITexture *C_FuncReflectiveGlass::ReflectionRenderTarget() +{ + if (m_iszReflectRenderTarget[0] != '\0') + { + if (!m_pReflectRenderTarget) + { + // We don't use a CTextureReference for this because we don't want to shut down the texture on removal/change + m_pReflectRenderTarget = materials->FindTexture( m_iszReflectRenderTarget, TEXTURE_GROUP_RENDER_TARGET ); + } + + if (m_pReflectRenderTarget) + return m_pReflectRenderTarget; + } + + return NULL; + //return GetWaterReflectionTexture(); +} + +ITexture *C_FuncReflectiveGlass::RefractionRenderTarget() +{ + if (m_iszRefractRenderTarget[0] != '\0') + { + if (!m_pRefractRenderTarget) + { + // We don't use a CTextureReference for this because we don't want to shut down the texture on removal/change + m_pRefractRenderTarget = materials->FindTexture( m_iszRefractRenderTarget, TEXTURE_GROUP_RENDER_TARGET ); + } + + if (m_pRefractRenderTarget) + return m_pRefractRenderTarget; + } + + return NULL; + //return GetWaterRefractionTexture(); +} +#endif + diff --git a/game/client/c_func_reflective_glass.h b/game/client/c_func_reflective_glass.h index 48e1491e..ab52ab88 100644 --- a/game/client/c_func_reflective_glass.h +++ b/game/client/c_func_reflective_glass.h @@ -21,6 +21,11 @@ class CViewSetup; //----------------------------------------------------------------------------- bool IsReflectiveGlassInView( const CViewSetup& view, cplane_t &plane ); +#ifdef MAPBASE +C_BaseEntity *NextReflectiveGlass( C_BaseEntity *pStart, const CViewSetup& view, cplane_t &plane, + const Frustum_t &frustum, ITexture **pRenderTargets = NULL ); +#endif + #endif // C_FUNC_REFLECTIVE_GLASS diff --git a/game/client/c_gameinstructor.cpp b/game/client/c_gameinstructor.cpp new file mode 100644 index 00000000..ff5f0e53 --- /dev/null +++ b/game/client/c_gameinstructor.cpp @@ -0,0 +1,1312 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Purpose: Client handler implementations for instruction players how to play +// +//=============================================================================// + +#include "cbase.h" + +#include "c_gameinstructor.h" +#include "c_baselesson.h" +#include "filesystem.h" +#include "vprof.h" +#include "ixboxsystem.h" +#include "tier0/icommandline.h" +#include "iclientmode.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//========================================================= +// Configuration +//========================================================= + +#define MOD_DIR "MOD" +#define GAMEINSTRUCTOR_SCRIPT_FILE "scripts/instructor_lessons.txt" +#define GAMEINSTRUCTOR_MOD_SCRIPT_FILE "scripts/mod_lessons.txt" + +// Game instructor auto game system instantiation +C_GameInstructor g_GameInstructor; +C_GameInstructor &GetGameInstructor() +{ + return g_GameInstructor; +} + +void GameInstructorEnable_ChangeCallback( IConVar *var, const char *pOldValue, float flOldValue ); +void SVGameInstructorDisable_ChangeCallback( IConVar *var, const char *pOldValue, float flOldValue ); + +extern ConVar sv_gameinstructor_disable; + +//========================================================= +// Comandos de consola +//========================================================= + +ConVar gameinstructor_verbose("gameinstructor_verbose", "0", FCVAR_CHEAT, "Set to 1 for standard debugging or 2 (in combo with gameinstructor_verbose_lesson) to show update actions."); +ConVar gameinstructor_verbose_lesson("gameinstructor_verbose_lesson", "", FCVAR_CHEAT, "Display more verbose information for lessons have this name." ); +ConVar gameinstructor_find_errors("gameinstructor_find_errors", "1", FCVAR_CHEAT, "Set to 1 and the game instructor will run EVERY scripted command to uncover errors." ); + +ConVar gameinstructor_enable( "gameinstructor_enable", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Display in game lessons that teach new players.", GameInstructorEnable_ChangeCallback ); +ConVar gameinstructor_start_sound_cooldown( "gameinstructor_start_sound_cooldown", "4.0", FCVAR_NONE, "Number of seconds forced between similar lesson start sounds." ); + +ConVar sv_gameinstructor_disable( "sv_gameinstructor_disable", "0", FCVAR_REPLICATED, "Force all clients to disable their game instructors.", SVGameInstructorDisable_ChangeCallback ); + +//========================================================= +// Activa o Desactiva el Instructor del lado del cliente. +//========================================================= +void EnableDisableInstructor() +{ + bool bEnabled = ( !sv_gameinstructor_disable.GetBool() && gameinstructor_enable.GetBool() ); + + // Game instructor has been enabled, so init it! + if ( bEnabled ) + GetGameInstructor().Init(); + + // Game instructor has been disabled, so shut it down! + else + GetGameInstructor().Shutdown(); +} + +//========================================================= +//========================================================= +void GameInstructorEnable_ChangeCallback( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if ( ( flOldValue != 0.0f ) != gameinstructor_enable.GetBool() ) + EnableDisableInstructor(); +} + +//========================================================= +//========================================================= +void SVGameInstructorDisable_ChangeCallback( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if ( !engine ) + return; + + EnableDisableInstructor(); +} + + +//========================================================= +// Initialize the Instructor +//========================================================= +bool C_GameInstructor::Init() +{ +// if ( &GetGameInstructor() == this ) + // return true; + + // Instructor deactivated, don't initialize. + if ( !gameinstructor_enable.GetBool() || sv_gameinstructor_disable.GetBool() ) + return true; + + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Initializing...\n" ); + } + + m_bNoDraw = false; + m_bHiddenDueToOtherElements = false; + + m_iCurrentPriority = 0; + m_hLastSpectatedPlayer = NULL; + m_bSpectatedPlayerChanged = false; + + m_szPreviousStartSound[0] = '\0'; + m_fNextStartSoundTime = 0; + + ReadLessonsFromFile( GAMEINSTRUCTOR_MOD_SCRIPT_FILE ); + ReadLessonsFromFile( GAMEINSTRUCTOR_SCRIPT_FILE ); + + InitLessonPrerequisites(); + ReadSaveData(); + + ListenForGameEvent("gameinstructor_draw"); + ListenForGameEvent("gameinstructor_nodraw"); + + ListenForGameEvent("round_end"); + ListenForGameEvent("round_start"); + ListenForGameEvent("player_death"); + ListenForGameEvent("player_team"); + ListenForGameEvent("player_disconnect"); + ListenForGameEvent("map_transition"); + ListenForGameEvent("game_newmap"); + ListenForGameEvent("set_instructor_group_enabled"); + + EvaluateLessonsForGameRules(); + return true; +} + +//========================================================= +// Shut down the instructor +//========================================================= +void C_GameInstructor::Shutdown() +{ + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Shutting down...\n" ); + } + + CloseAllOpenOpportunities(); + WriteSaveData(); + + // Removemos todas las lecciones. + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + if ( m_Lessons[ i ] ) + { + m_Lessons[ i ]->StopListeningForAllEvents(); + delete m_Lessons[ i ]; + m_Lessons[ i ] = NULL; + } + } + + m_Lessons.RemoveAll(); + m_LessonGroupConVarToggles.RemoveAll(); + + // Paramos de escuchar eventos. + StopListeningForAllEvents(); +} + +//========================================================= +//========================================================= +void C_GameInstructor::UpdateHiddenByOtherElements() +{ + //bool bHidden = Mod_HiddenByOtherElements(); + bool bHidden = false; + + if ( bHidden && !m_bHiddenDueToOtherElements ) + StopAllLessons(); + + m_bHiddenDueToOtherElements = bHidden; +} + +//========================================================= +//========================================================= +void C_GameInstructor::Update( float frametime ) +{ + VPROF_BUDGET( "C_GameInstructor::Update", "GameInstructor" ); + + UpdateHiddenByOtherElements(); + + // Instructor deactivated. + if ( !gameinstructor_enable.GetBool() || m_bNoDraw || m_bHiddenDueToOtherElements ) + return; + + if ( gameinstructor_find_errors.GetBool() ) + { + FindErrors(); + gameinstructor_find_errors.SetValue(0); + } + + if ( IsConsole() ) + { + // On X360 we want to save when they're not connected + // They aren't in game + if ( !engine->IsInGame() ) + WriteSaveData(); + else + { + const char *levelName = engine->GetLevelName(); + + // The are in game, but it's a background map + if ( levelName && levelName[0] && engine->IsLevelMainMenuBackground() ) + WriteSaveData(); + } + } + + if ( m_bSpectatedPlayerChanged ) + { + // Safe spot to clean out stale lessons if spectator changed + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Spectated player changed...\n" ); + } + + CloseAllOpenOpportunities(); + m_bSpectatedPlayerChanged = false; + } + + // Loop through all the lesson roots and reset their active status + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + CBaseLesson *pRootLesson = pLesson->GetRoot(); + + if ( pRootLesson->InstanceType() == LESSON_INSTANCE_SINGLE_ACTIVE ) + pRootLesson->SetInstanceActive(false); + } + + int iCurrentPriority = 0; + + // Loop through all the open lessons + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + + // This opportunity has closed + if ( !pLesson->IsOpenOpportunity() || pLesson->IsTimedOut() ) + { + CloseOpportunity( pLesson ); + continue; + } + + // Lesson should be displayed, so it can affect priority + CBaseLesson *pRootLesson = pLesson->GetRoot(); + bool bShouldDisplay = pLesson->ShouldDisplay(); + bool bIsLocked = pLesson->IsLocked(); + + if ( ( bShouldDisplay || bIsLocked ) && + ( pLesson->GetPriority() >= m_iCurrentPriority || pLesson->NoPriority() || bIsLocked ) && + ( pRootLesson && ( pRootLesson->InstanceType() != LESSON_INSTANCE_SINGLE_ACTIVE || !pRootLesson->IsInstanceActive() ) ) ) + { + // Lesson is at the highest priority level, isn't violating instance rules, and has met all the prerequisites + if ( UpdateActiveLesson( pLesson, pRootLesson ) || pRootLesson->IsLearned() ) + { + // Lesson is active + if ( pLesson->IsVisible() || pRootLesson->IsLearned() ) + { + pRootLesson->SetInstanceActive( true ); + + // This active or learned lesson has the highest priority so far + if ( iCurrentPriority < pLesson->GetPriority() && !pLesson->NoPriority() ) + iCurrentPriority = pLesson->GetPriority(); + } + } + else + { + // On second thought, this shouldn't have been displayed + bShouldDisplay = false; + } + } + else + { + // Lesson shouldn't be displayed right now + UpdateInactiveLesson( pLesson ); + } + } + + // Set the priority for next frame + if ( gameinstructor_verbose.GetInt() > 1 && m_iCurrentPriority != iCurrentPriority ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Priority changed from " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "%i ", m_iCurrentPriority ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "to " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "%i", iCurrentPriority ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + + m_iCurrentPriority = iCurrentPriority; +} + +//========================================================= +//========================================================= +void C_GameInstructor::FireGameEvent( IGameEvent *event ) +{ + VPROF_BUDGET( "C_GameInstructor::FireGameEvent", "GameInstructor" ); + const char *name = event->GetName(); + + if ( Q_strcmp( name, "gameinstructor_draw" ) == 0 ) + { + if ( m_bNoDraw ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Set to draw...\n" ); + } + + m_bNoDraw = false; + } + } + else if ( Q_strcmp( name, "gameinstructor_nodraw" ) == 0 ) + { + if ( !m_bNoDraw ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Set to not draw...\n" ); + } + + m_bNoDraw = true; + StopAllLessons(); + } + } + else if ( Q_strcmp( name, "round_end" ) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Round ended...\n" ); + } + + CloseAllOpenOpportunities(); + + if ( IsPC() ) + { + // Good place to backup our counts + WriteSaveData(); + } + } + else if ( Q_strcmp( name, "round_start" ) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Round started...\n" ); + } + + CloseAllOpenOpportunities(); + + EvaluateLessonsForGameRules(); + } + else if ( Q_strcmp( name, "player_death" ) == 0 ) + { + #if !defined(NO_STEAM) && defined(USE_CEG) + Steamworks_TestSecret(); + Steamworks_SelfCheck(); + #endif + + C_BasePlayer *pLocalPlayer = GetLocalPlayer(); + + if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player died...\n" ); + } + + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + CBaseLesson *pRootLesson = pLesson->GetRoot(); + + if ( !pRootLesson->CanOpenWhenDead() ) + CloseOpportunity( pLesson ); + } + } + } + else if ( Q_strcmp( name, "player_team" ) == 0 ) + { + C_BasePlayer *pLocalPlayer = GetLocalPlayer(); + + if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) && + ( event->GetInt( "team" ) != event->GetInt( "oldteam" ) || event->GetBool( "disconnect" ) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player changed team (or disconnected)...\n" ); + } + + CloseAllOpenOpportunities(); + } + + EvaluateLessonsForGameRules(); + } + else if ( Q_strcmp( name, "player_disconnect" ) == 0 ) + { + C_BasePlayer *pLocalPlayer = GetLocalPlayer(); + if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player disconnected...\n" ); + } + + CloseAllOpenOpportunities(); + } + } + else if ( Q_strcmp( name, "map_transition" ) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Map transition...\n" ); + } + + CloseAllOpenOpportunities(); + + if ( m_bNoDraw ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( Color( 255, 128, 64, 255 ), "[INSTRUCTOR]: " ); + ConColorMsg( Color( 64, 128, 255, 255 ), "Set to draw...\n" ); + } + + m_bNoDraw = false; + } + + if ( IsPC() ) + { + // Good place to backup our counts + WriteSaveData(); + } + } + else if ( Q_strcmp( name, "game_newmap" ) == 0 ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "New map...\n" ); + } + + CloseAllOpenOpportunities(); + + if ( m_bNoDraw ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( Color( 255, 128, 64, 255 ), "[INSTRUCTOR]: " ); + ConColorMsg( Color( 64, 128, 255, 255 ), "Set to draw...\n" ); + } + + m_bNoDraw = false; + } + + if ( IsPC() ) + { + // Good place to backup our counts + WriteSaveData(); + } + } + + else if ( Q_strcmp( name, "set_instructor_group_enabled" ) == 0 ) + { + const char *pszGroup = event->GetString( "group" ); + bool bEnabled = event->GetInt( "enabled" ) != 0; + + if ( pszGroup && pszGroup[0] ) + SetLessonGroupEnabled(pszGroup, bEnabled); + } +} + +//========================================================= +//========================================================= +void C_GameInstructor::DefineLesson( CBaseLesson *pLesson ) +{ + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseName, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "defined.\n" ); + } + + m_Lessons.AddToTail( pLesson ); +} + +//========================================================= +//========================================================= +const CBaseLesson * C_GameInstructor::GetLesson( const char *pchLessonName ) +{ + return GetLesson_Internal( pchLessonName ); +} + +//========================================================= +//========================================================= +bool C_GameInstructor::IsLessonOfSameTypeOpen( const CBaseLesson *pLesson ) const +{ + for ( int i = 0; i < m_OpenOpportunities.Count(); ++i ) + { + CBaseLesson *pOpenOpportunity = m_OpenOpportunities[ i ]; + + if ( pOpenOpportunity->GetNameSymbol() == pLesson->GetNameSymbol() ) + return true; + } + + return false; +} + +//========================================================= +//========================================================= +bool C_GameInstructor::ReadSaveData() +{ + // for external playtests, don't ever read in persisted instructor state, always start fresh + if ( CommandLine()->FindParm( "-playtest" ) ) + return true; + + if ( m_bHasLoadedSaveData ) + return true; + + // Always reset state first in case storage device + // was declined or ends up in faulty state + ResetDisplaysAndSuccesses(); + + m_bHasLoadedSaveData = true; + +#ifdef _X360 + DevMsg( "Read Game Instructor for splitscreen slot %d\n", m_nSplitScreenSlot ); + + if ( m_nSplitScreenSlot < 0 ) + return false; + + if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) + return false; + + int iController = XBX_GetUserId( m_nSplitScreenSlot ); + + if ( iController < 0 || XBX_GetUserIsGuest( iController ) ) + { + // Can't read data for guests + return false; + } + + DWORD nStorageDevice = XBX_GetStorageDeviceId( iController ); + if ( !XBX_DescribeStorageDevice( nStorageDevice ) ) + return false; +#endif + + char szFilename[_MAX_PATH]; + +#ifdef _X360 + if ( IsX360() ) + { + XBX_MakeStorageContainerRoot( iController, XBX_USER_SETTINGS_CONTAINER_DRIVE, szFilename, sizeof( szFilename ) ); + int nLen = strlen( szFilename ); + Q_snprintf( szFilename + nLen, sizeof( szFilename ) - nLen, ":\\game_instructor_counts.txt" ); + } + else +#endif + { + Q_snprintf( szFilename, sizeof( szFilename ), "save/game_instructor_counts.txt" ); + } + + KeyValues *data = new KeyValues( "Game Instructor Counts" ); + KeyValues::AutoDelete autoDelete(data); + + if ( data->LoadFromFile( g_pFullFileSystem, szFilename, NULL ) ) + { + int nVersion = 0; + + for ( KeyValues *pKey = data->GetFirstSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() ) + { + CBaseLesson *pLesson = GetLesson_Internal( pKey->GetName() ); + + if ( pLesson ) + { + pLesson->SetDisplayCount( pKey->GetInt( "display", 0 ) ); + pLesson->SetSuccessCount( pKey->GetInt( "success", 0 ) ); + + if ( Q_strcmp( pKey->GetName(), "version number" ) == 0 ) + { + nVersion = pLesson->GetSuccessCount(); + } + } + } + + CBaseLesson *pLessonVersionNumber = GetLesson_Internal( "version number" ); + if ( pLessonVersionNumber && !pLessonVersionNumber->IsLearned() ) + { + ResetDisplaysAndSuccesses(); + pLessonVersionNumber->SetSuccessCount( pLessonVersionNumber->GetSuccessLimit() ); + m_bDirtySaveData = true; + } + + + return true; + } + + // Couldn't read from the file + return false; +} + +//========================================================= +//========================================================= +bool C_GameInstructor::WriteSaveData() +{ + if ( engine->IsPlayingDemo() ) + return false; + + if ( !m_bDirtySaveData ) + return true; + +#ifdef _X360 + float flPlatTime = Plat_FloatTime(); + + static ConVarRef host_write_last_time( "host_write_last_time" ); + if ( host_write_last_time.IsValid() ) + { + float flTimeSinceLastWrite = flPlatTime - host_write_last_time.GetFloat(); + if ( flTimeSinceLastWrite < 3.5f ) + { + // Prevent writing to the same storage device twice in less than 3 second succession for TCR success! + // This happens after leaving a game in splitscreen. + //DevMsg( "Waiting to write Game Instructor for splitscreen slot %d... (%.1f seconds remain)\n", m_nSplitScreenSlot, 3.5f - flTimeSinceLastWrite ); + return false; + } + } +#endif + + // Always mark as clean state to avoid re-entry on + // subsequent frames when storage device might be + // in a yet-unmounted state. + m_bDirtySaveData = false; + +#ifdef _X360 + DevMsg( "Write Game Instructor for splitscreen slot %d at time: %.1f\n", m_nSplitScreenSlot, flPlatTime ); + + if ( m_nSplitScreenSlot < 0 ) + return false; + + if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) + return false; + + int iController = XBX_GetUserId( m_nSplitScreenSlot ); + + if ( iController < 0 || XBX_GetUserIsGuest( iController ) ) + { + // Can't save data for guests + return false; + } + + DWORD nStorageDevice = XBX_GetStorageDeviceId( iController ); + if ( !XBX_DescribeStorageDevice( nStorageDevice ) ) + return false; +#endif + + // Build key value data to save + KeyValues *data = new KeyValues( "Game Instructor Counts" ); + KeyValues::AutoDelete autoDelete(data); + + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + CBaseLesson *pLesson = m_Lessons[i]; + + int iDisplayCount = pLesson->GetDisplayCount(); + int iSuccessCount = pLesson->GetSuccessCount(); + + if ( iDisplayCount || iSuccessCount ) + { + // We've got some data worth saving + KeyValues *pKVData = new KeyValues( pLesson->GetName() ); + + if ( iDisplayCount ) + pKVData->SetInt( "display", iDisplayCount ); + + if ( iSuccessCount ) + pKVData->SetInt( "success", iSuccessCount ); + + data->AddSubKey( pKVData ); + } + } + + // Save it! + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + + data->RecursiveSaveToFile( buf, 0 ); + + char szFilename[_MAX_PATH]; + +#ifdef _X360 + if ( IsX360() ) + { + XBX_MakeStorageContainerRoot( iController, XBX_USER_SETTINGS_CONTAINER_DRIVE, szFilename, sizeof( szFilename ) ); + int nLen = strlen( szFilename ); + Q_snprintf( szFilename + nLen, sizeof( szFilename ) - nLen, ":\\game_instructor_counts.txt" ); + } + else +#endif + { + Q_snprintf( szFilename, sizeof( szFilename ), "save/game_instructor_counts.txt" ); + filesystem->CreateDirHierarchy( "save", "MOD" ); + } + + bool bWriteSuccess = filesystem->WriteFile( szFilename, MOD_DIR, buf ); + +#ifdef _X360 + if ( xboxsystem ) + { + xboxsystem->FinishContainerWrites( iController ); + } +#endif + + return bWriteSuccess; +} + +//========================================================= +//========================================================= +void C_GameInstructor::RefreshDisplaysAndSuccesses() +{ + m_bHasLoadedSaveData = false; + ReadSaveData(); +} + +//========================================================= +//========================================================= +void C_GameInstructor::ResetDisplaysAndSuccesses() +{ + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Reset all lesson display and success counts.\n" ); + } + + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + m_Lessons[ i ]->ResetDisplaysAndSuccesses(); + } + + m_bDirtySaveData = false; +} + +//========================================================= +//========================================================= +void C_GameInstructor::MarkDisplayed( const char *pchLessonName ) +{ + CBaseLesson *pLesson = GetLesson_Internal(pchLessonName); + + if ( !pLesson ) + return; + + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "marked as displayed.\n" ); + } + + if ( pLesson->IncDisplayCount() ) + m_bDirtySaveData = true; +} + +//========================================================= +//========================================================= +void C_GameInstructor::MarkSucceeded(const char *pchLessonName) +{ + CBaseLesson *pLesson = GetLesson_Internal(pchLessonName); + + if ( !pLesson ) + return; + + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseSuccess, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "marked as succeeded.\n" ); + } + + if ( pLesson->IncSuccessCount() ) + m_bDirtySaveData = true; +} + +//========================================================= +//========================================================= +void C_GameInstructor::PlaySound( const char *pchSoundName ) +{ + // emit alert sound + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + + if ( pLocalPlayer ) + { + // Local player exists + if ( pchSoundName[ 0 ] != '\0' && Q_strcmp( m_szPreviousStartSound, pchSoundName ) != 0 ) + { + Q_strcpy( m_szPreviousStartSound, pchSoundName ); + m_fNextStartSoundTime = 0.0f; + } + + if ( gpGlobals->curtime >= m_fNextStartSoundTime && pchSoundName[ 0 ] != '\0' ) + { + // A sound was specified, so play it! + pLocalPlayer->EmitSound( pchSoundName ); + m_fNextStartSoundTime = gpGlobals->curtime + gameinstructor_start_sound_cooldown.GetFloat(); + } + } +} + +//========================================================= +//========================================================= +bool C_GameInstructor::OpenOpportunity( CBaseLesson *pLesson ) +{ + // Get the root lesson + CBaseLesson *pRootLesson = pLesson->GetRoot(); + + if ( !pRootLesson ) + { + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "NOT opened (because root lesson could not be found).\n" ); + } + + delete pLesson; + return false; + } + + C_BasePlayer *pLocalPlayer = GetLocalPlayer(); + + if ( !pRootLesson->CanOpenWhenDead() && ( !pLocalPlayer || !pLocalPlayer->IsAlive() ) ) + { + // If the player is dead don't allow lessons that can't be opened when dead + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "NOT opened (because player is dead and can_open_when_dead not set).\n" ); + } + + delete pLesson; + return false; + } + + if ( !pRootLesson->PrerequisitesHaveBeenMet() ) + { + // If the prereqs haven't been met, don't open it + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "NOT opened (because prereqs haven't been met).\n" ); + } + + delete pLesson; + return false; + } + + if ( pRootLesson->InstanceType() == LESSON_INSTANCE_FIXED_REPLACE ) + { + CBaseLesson *pLessonToReplace = NULL; + CBaseLesson *pLastReplacableLesson = NULL; + + int iInstanceCount = 0; + + // Check how many are already open + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pOpenOpportunity = m_OpenOpportunities[ i ]; + + if ( pOpenOpportunity->GetNameSymbol() == pLesson->GetNameSymbol() && + pOpenOpportunity->GetReplaceKeySymbol() == pLesson->GetReplaceKeySymbol() ) + { + iInstanceCount++; + + if ( pRootLesson->ShouldReplaceOnlyWhenStopped() ) + { + if ( !pOpenOpportunity->IsInstructing() ) + { + pLastReplacableLesson = pOpenOpportunity; + } + } + else + { + pLastReplacableLesson = pOpenOpportunity; + } + + if ( iInstanceCount >= pRootLesson->GetFixedInstancesMax() ) + { + pLessonToReplace = pLastReplacableLesson; + break; + } + } + } + + if ( pLessonToReplace ) + { + // Take the place of the previous instance + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "replacing open lesson of same type.\n" ); + } + + pLesson->TakePlaceOf( pLessonToReplace ); + CloseOpportunity( pLessonToReplace ); + } + else if ( iInstanceCount >= pRootLesson->GetFixedInstancesMax() ) + { + // Don't add another lesson of this type + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "NOT opened (there is too many started lessons of this type).\n" ); + } + + delete pLesson; + return false; + } + } + + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "opened.\n" ); + } + + m_OpenOpportunities.AddToTail( pLesson ); + + return true; +} + +//========================================================= +//========================================================= +void C_GameInstructor::DumpOpenOpportunities() +{ + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Open lessons...\n" ); + + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + CBaseLesson *pRootLesson = pLesson->GetRoot(); + + Color color; + + if ( pLesson->IsInstructing() ) + { + // Green + color = CBaseLesson::m_rgbaVerboseOpen; + } + else if ( pRootLesson->IsLearned() && pLesson->GetPriority() >= m_iCurrentPriority ) + { + // Yellow + color = CBaseLesson::m_rgbaVerboseSuccess; + } + else + { + // Red + color = CBaseLesson::m_rgbaVerboseClose; + } + + ConColorMsg( color, "\t%s\n", pLesson->GetName() ); + } +} + +//========================================================= +//========================================================= +KeyValues * C_GameInstructor::GetScriptKeys() +{ + return m_pScriptKeys; +} + +//========================================================= +//========================================================= +C_BasePlayer * C_GameInstructor::GetLocalPlayer() +{ + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + + // If we're not a developer, don't do the special spectator hook ups + if ( !developer.GetBool() ) + return pLocalPlayer; + + // If there is no local player and we're not spectating, just return that + if ( !pLocalPlayer || pLocalPlayer->GetTeamNumber() != TEAM_SPECTATOR ) + return pLocalPlayer; + + // We're purely a spectator let's get lessons of the person we're spectating + C_BasePlayer *pSpectatedPlayer = NULL; + + if ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pLocalPlayer->GetObserverMode() == OBS_MODE_CHASE ) + pSpectatedPlayer = ToBasePlayer( pLocalPlayer->GetObserverTarget() ); + + if ( m_hLastSpectatedPlayer != pSpectatedPlayer ) + { + // We're spectating someone new! Close all the stale lessons! + m_bSpectatedPlayerChanged = true; + m_hLastSpectatedPlayer = pSpectatedPlayer; + } + + return pSpectatedPlayer; +} + +//========================================================= +//========================================================= +void C_GameInstructor::EvaluateLessonsForGameRules() +{ + // Enable everything by default + for ( int i = 0; i < m_Lessons.Count(); ++i ) + m_Lessons[ i ]->SetEnabled(true); + + // Then see if we should disable anything + for ( int nConVar = 0; nConVar < m_LessonGroupConVarToggles.Count(); ++nConVar ) + { + LessonGroupConVarToggle_t *pLessonGroupConVarToggle = &(m_LessonGroupConVarToggles[ nConVar ]); + + if ( pLessonGroupConVarToggle->var.IsValid() ) + { + if ( pLessonGroupConVarToggle->var.GetBool() ) + SetLessonGroupEnabled( pLessonGroupConVarToggle->szLessonGroupName, false ); + } + } +} + +//========================================================= +//========================================================= +void C_GameInstructor::SetLessonGroupEnabled( const char *pszGroup, bool bEnabled ) +{ + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + if ( !Q_stricmp(pszGroup, m_Lessons[i]->GetGroup()) ) + m_Lessons[i]->SetEnabled( bEnabled ); + } +} + +//========================================================= +//========================================================= +void C_GameInstructor::FindErrors() +{ + // Loop through all the lesson and run all their scripted actions + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + CScriptedIconLesson *pLesson = dynamic_cast( m_Lessons[ i ] ); + if ( pLesson ) + { + // Process all open events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->GetOpenEvents().Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->GetOpenEvents()[ iLessonEvent ]); + pLesson->ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + // Process all close events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->GetCloseEvents().Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->GetCloseEvents()[ iLessonEvent ]); + pLesson->ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + // Process all success events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->GetSuccessEvents().Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->GetSuccessEvents()[ iLessonEvent ]); + pLesson->ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + // Process all on open events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->GetOnOpenEvents().Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->GetOnOpenEvents()[ iLessonEvent ]); + pLesson->ProcessElements( NULL, &(pLessonEvent->elements) ); + } + + // Process all update events + for ( int iLessonEvent = 0; iLessonEvent < pLesson->GetUpdateEvents().Count(); ++iLessonEvent ) + { + const LessonEvent_t *pLessonEvent = &(pLesson->GetUpdateEvents()[ iLessonEvent ]); + pLesson->ProcessElements( NULL, &(pLessonEvent->elements) ); + } + } + } +} + +//========================================================= +//========================================================= +bool C_GameInstructor::UpdateActiveLesson( CBaseLesson *pLesson, const CBaseLesson *pRootLesson ) +{ + VPROF_BUDGET( "C_GameInstructor::UpdateActiveLesson", "GameInstructor" ); + + bool bIsOpen = pLesson->IsInstructing(); + + if ( !bIsOpen && !pRootLesson->IsLearned() ) + { + pLesson->SetStartTime(); + pLesson->Start(); + + // Check to see if it successfully started + bIsOpen = ( pLesson->IsOpenOpportunity() && pLesson->ShouldDisplay() ); + + if ( bIsOpen ) + { + // Lesson hasn't been started and hasn't been learned + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Started lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseOpen, "\"%s\"", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + } + else + { + pLesson->Stop(); + pLesson->ResetStartTime(); + } + } + + if ( bIsOpen ) + { + // Update the running lesson + pLesson->Update(); + return true; + } + else + { + pLesson->UpdateInactive(); + return false; + } +} + +//========================================================= +//========================================================= +void C_GameInstructor::UpdateInactiveLesson( CBaseLesson *pLesson ) +{ + VPROF_BUDGET( "C_GameInstructor::UpdateInactiveLesson", "GameInstructor" ); + + if ( pLesson->IsInstructing() ) + { + // Lesson hasn't been stopped + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Stopped lesson " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\"", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ".\n" ); + } + + pLesson->Stop(); + pLesson->ResetStartTime(); + } + + pLesson->UpdateInactive(); +} + +//========================================================= +//========================================================= +CBaseLesson * C_GameInstructor::GetLesson_Internal( const char *pchLessonName ) +{ + for ( int i = 0; i < m_Lessons.Count(); ++i ) + { + CBaseLesson *pLesson = m_Lessons[ i ]; + + if ( Q_strcmp( pLesson->GetName(), pchLessonName ) == 0 ) + { + return pLesson; + } + } + + return NULL; +} + +//========================================================= +//========================================================= +void C_GameInstructor::StopAllLessons() +{ + // Stop all the current lessons + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + UpdateInactiveLesson( pLesson ); + } +} + +//========================================================= +//========================================================= +void C_GameInstructor::CloseAllOpenOpportunities() +{ + // Clear out all the open opportunities + for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i ) + { + CBaseLesson *pLesson = m_OpenOpportunities[ i ]; + CloseOpportunity( pLesson ); + } + + Assert( m_OpenOpportunities.Count() == 0 ); +} + +//========================================================= +//========================================================= +void C_GameInstructor::CloseOpportunity( CBaseLesson *pLesson ) +{ + UpdateInactiveLesson( pLesson ); + + if ( pLesson->WasDisplayed() ) + MarkDisplayed( pLesson->GetName() ); + + if ( gameinstructor_verbose.GetInt() > 0 ) + { + ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "GAME INSTRUCTOR: " ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Opportunity " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "\"%s\" ", pLesson->GetName() ); + ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "closed for reason: " ); + ConColorMsg( CBaseLesson::m_rgbaVerboseClose, "%s\n", pLesson->GetCloseReason() ); + } + + pLesson->StopListeningForAllEvents(); + + m_OpenOpportunities.FindAndRemove( pLesson ); + delete pLesson; +} + +//========================================================= +//========================================================= +void C_GameInstructor::ReadLessonsFromFile( const char *pchFileName ) +{ + // Static init function + CScriptedIconLesson::PreReadLessonsFromFile(); + MEM_ALLOC_CREDIT(); + + KeyValues *pLessonKeys = new KeyValues("instructor_lessons"); + KeyValues::AutoDelete autoDelete(pLessonKeys); + + pLessonKeys->LoadFromFile(g_pFullFileSystem, pchFileName, NULL); + + for ( m_pScriptKeys = pLessonKeys->GetFirstTrueSubKey(); m_pScriptKeys; m_pScriptKeys = m_pScriptKeys->GetNextTrueSubKey() ) + { + if ( Q_stricmp(m_pScriptKeys->GetName(), "GroupConVarToggle") == 0 ) + { + // Add convar group toggler to the list + int nLessonGroupConVarToggle = m_LessonGroupConVarToggles.AddToTail( LessonGroupConVarToggle_t( m_pScriptKeys->GetString( "convar" ) ) ); + LessonGroupConVarToggle_t *pLessonGroupConVarToggle = &(m_LessonGroupConVarToggles[nLessonGroupConVarToggle]); + + Q_strcpy( pLessonGroupConVarToggle->szLessonGroupName, m_pScriptKeys->GetString("group") ); + continue; + } + + // Ensure that lessons aren't added twice + if ( GetLesson_Internal(m_pScriptKeys->GetName()) ) + { + DevWarning("Lesson \"%s\" defined twice!\n", m_pScriptKeys->GetName()); + continue; + } + + CScriptedIconLesson *pNewLesson = new CScriptedIconLesson(m_pScriptKeys->GetName(), false, false); + GetGameInstructor().DefineLesson(pNewLesson); + } + + m_pScriptKeys = NULL; +} + +//========================================================= +//========================================================= +void C_GameInstructor::InitLessonPrerequisites() +{ + for ( int i = 0; i < m_Lessons.Count(); ++i ) + m_Lessons[ i ]->InitPrerequisites(); +} + +//========================================================= +// Commands +//========================================================= + +CON_COMMAND_F( gameinstructor_reload_lessons, "Shuts down all open lessons and reloads them from the script file.", FCVAR_CHEAT ) +{ + GetGameInstructor().Shutdown(); + GetGameInstructor().Init(); +} + +CON_COMMAND_F( gameinstructor_reset_counts, "Resets all display and success counts to zero.", FCVAR_NONE ) +{ + GetGameInstructor().ResetDisplaysAndSuccesses(); +} + +CON_COMMAND_F( gameinstructor_dump_open_lessons, "Gives a list of all currently open lessons.", FCVAR_CHEAT ) +{ + GetGameInstructor().DumpOpenOpportunities(); +} diff --git a/game/client/c_gameinstructor.h b/game/client/c_gameinstructor.h new file mode 100644 index 00000000..14ae908c --- /dev/null +++ b/game/client/c_gameinstructor.h @@ -0,0 +1,118 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Purpose: Client handler for instruction players how to play +// +//=============================================================================// + +#ifndef _C_GAMEINSTRUCTOR_H_ +#define _C_GAMEINSTRUCTOR_H_ + + +#include "GameEventListener.h" +#include "vgui_controls/PHandle.h" + +class CBaseLesson; + + +struct LessonGroupConVarToggle_t +{ + ConVarRef var; + char szLessonGroupName[ 64 ]; + + LessonGroupConVarToggle_t( const char *pchConVarName ) : + var( pchConVarName ) + { + } +}; + + +class C_GameInstructor : public CAutoGameSystemPerFrame, public CGameEventListener +{ +public: + C_GameInstructor() : CAutoGameSystemPerFrame( "C_GameInstructor" ) + { + m_bHasLoadedSaveData = false; + m_bDirtySaveData = false; + } + + // Methods of IGameSystem + virtual bool Init( void ); + virtual void Shutdown( void ); + virtual void Update( float frametime ); + + void UpdateHiddenByOtherElements( void ); + bool Mod_HiddenByOtherElements( void ); + + virtual void FireGameEvent( IGameEvent *event ); + + void DefineLesson( CBaseLesson *pLesson ); + + const CBaseLesson * GetLesson( const char *pchLessonName ); + bool IsLessonOfSameTypeOpen( const CBaseLesson *pLesson ) const; + + bool ReadSaveData( void ); + bool WriteSaveData( void ); + void RefreshDisplaysAndSuccesses( void ); + void ResetDisplaysAndSuccesses( void ); + void MarkDisplayed( const char *pchLessonName ); + void MarkSucceeded( const char *pchLessonName ); + + void PlaySound( const char *pchSoundName ); + + bool OpenOpportunity( CBaseLesson *pLesson ); + + void DumpOpenOpportunities( void ); + + KeyValues * GetScriptKeys( void ); + C_BasePlayer * GetLocalPlayer( void ); + + void EvaluateLessonsForGameRules( void ); + void SetLessonGroupEnabled( const char *pszGroup, bool bEnabled ); + + // Mapbase needs this to be public for map-specific file system + void ReadLessonsFromFile( const char *pchFileName ); + +private: + void FindErrors( void ); + + bool UpdateActiveLesson( CBaseLesson *pLesson, const CBaseLesson *pRootLesson ); + void UpdateInactiveLesson( CBaseLesson *pLesson ); + + CBaseLesson * GetLesson_Internal( const char *pchLessonName ); + + void StopAllLessons( void ); + + void CloseAllOpenOpportunities( void ); + void CloseOpportunity( CBaseLesson *pLesson ); + + void InitLessonPrerequisites( void ); + +private: + CUtlVector < CBaseLesson* > m_Lessons; + CUtlVector < CBaseLesson* > m_OpenOpportunities; + + CUtlVector < LessonGroupConVarToggle_t > m_LessonGroupConVarToggles; + + KeyValues *m_pScriptKeys; + + bool m_bNoDraw; + bool m_bHiddenDueToOtherElements; + + int m_iCurrentPriority; + EHANDLE m_hLastSpectatedPlayer; + bool m_bSpectatedPlayerChanged; + + char m_szPreviousStartSound[ 128 ]; + float m_fNextStartSoundTime; + + bool m_bHasLoadedSaveData; + bool m_bDirtySaveData; +}; + +C_GameInstructor &GetGameInstructor(); + +void GameInstructor_Init(); +void GameInstructor_Shutdown(); + + +#endif // _C_GAMEINSTRUCTOR_H_ diff --git a/game/client/c_lightglow.cpp b/game/client/c_lightglow.cpp index 06f20a6c..501a2612 100644 --- a/game/client/c_lightglow.cpp +++ b/game/client/c_lightglow.cpp @@ -102,6 +102,10 @@ class C_LightGlow : public C_BaseEntity C_LightGlowOverlay m_Glow; float m_flGlowProxySize; + +#ifdef MAPBASE + bool m_bDisabled; +#endif }; static void RecvProxy_HDRColorScale( const CRecvProxyData *pData, void *pStruct, void *pOut ) @@ -123,6 +127,9 @@ IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_LightGlow, DT_LightGlow, CLightGlow ) RecvPropQAngles( RECVINFO_NAME( m_angNetworkAngles, m_angRotation ) ), RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ), RecvPropFloat(RECVINFO(m_flGlowProxySize)), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bDisabled ) ), +#endif RecvPropFloat("HDRColorScale", 0, SIZEOF_IGNORE, 0, RecvProxy_HDRColorScale), END_RECV_TABLE() @@ -202,7 +209,11 @@ void C_LightGlow::OnDataChanged( DataUpdateType_t updateType ) void C_LightGlow::ClientThink( void ) { Vector mins = GetAbsOrigin(); +#ifdef MAPBASE + if ( engine->IsBoxVisible( mins, mins ) && !m_bDisabled ) +#else if ( engine->IsBoxVisible( mins, mins ) ) +#endif { m_Glow.Activate(); } diff --git a/game/client/c_movie_display.cpp b/game/client/c_movie_display.cpp new file mode 100644 index 00000000..27327403 --- /dev/null +++ b/game/client/c_movie_display.cpp @@ -0,0 +1,27 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// +//=====================================================================================// +#include "cbase.h" +#include "c_movie_display.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +IMPLEMENT_CLIENTCLASS_DT( C_MovieDisplay, DT_MovieDisplay, CMovieDisplay ) + RecvPropBool( RECVINFO( m_bEnabled ) ), + RecvPropBool( RECVINFO( m_bLooping ) ), + RecvPropBool( RECVINFO( m_bMuted ) ), + RecvPropString( RECVINFO( m_szMovieFilename ) ), + RecvPropString( RECVINFO( m_szGroupName ) ), +END_RECV_TABLE() + +C_MovieDisplay::C_MovieDisplay() +{ +} + +C_MovieDisplay::~C_MovieDisplay() +{ +} diff --git a/game/client/c_movie_display.h b/game/client/c_movie_display.h new file mode 100644 index 00000000..55d0211f --- /dev/null +++ b/game/client/c_movie_display.h @@ -0,0 +1,36 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#ifndef C_MOVIE_DISPLAY_H +#define C_MOVIE_DISPLAY_H + +#include "cbase.h" + +class C_MovieDisplay : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_MovieDisplay, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + C_MovieDisplay(); + ~C_MovieDisplay(); + + bool IsEnabled( void ) const { return m_bEnabled; } + bool IsLooping( void ) const { return m_bLooping; } + bool IsMuted(void) const { return m_bMuted; } + + const char *GetMovieFilename( void ) const { return m_szMovieFilename; } + const char *GetGroupName( void ) const { return m_szGroupName; } + +private: + bool m_bEnabled; + bool m_bLooping; + bool m_bMuted; + char m_szMovieFilename[128]; + char m_szGroupName[128]; +}; + +#endif //C_MOVIE_DISPLAY_H \ No newline at end of file diff --git a/game/client/c_particle_system.cpp b/game/client/c_particle_system.cpp index e0aee808..a42fae76 100644 --- a/game/client/c_particle_system.cpp +++ b/game/client/c_particle_system.cpp @@ -32,6 +32,9 @@ class C_ParticleSystem : public C_BaseEntity protected: int m_iEffectIndex; bool m_bActive; +#ifdef MAPBASE + bool m_bDestroyImmediately; +#endif bool m_bOldActive; float m_flStartTime; // Time at which the effect started @@ -39,6 +42,7 @@ class C_ParticleSystem : public C_BaseEntity EHANDLE m_hControlPointEnts[kMAXCONTROLPOINTS]; + Vector m_vControlPointVecs[kMAXCONTROLPOINTS]; // SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ), unsigned char m_iControlPointParents[kMAXCONTROLPOINTS]; @@ -56,9 +60,13 @@ BEGIN_RECV_TABLE_NOBASE( C_ParticleSystem, DT_ParticleSystem ) RecvPropInt( RECVINFO( m_iEffectIndex ) ), RecvPropBool( RECVINFO( m_bActive ) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bDestroyImmediately ) ), +#endif RecvPropFloat( RECVINFO( m_flStartTime ) ), RecvPropArray3( RECVINFO_ARRAY(m_hControlPointEnts), RecvPropEHandle( RECVINFO( m_hControlPointEnts[0] ) ) ), + RecvPropArray3( RECVINFO_ARRAY(m_vControlPointVecs), RecvPropVector( RECVINFO( m_vControlPointVecs[0] ) ) ), RecvPropArray3( RECVINFO_ARRAY(m_iControlPointParents), RecvPropInt( RECVINFO(m_iControlPointParents[0]))), RecvPropBool( RECVINFO( m_bWeatherEffect ) ), END_RECV_TABLE(); @@ -108,9 +116,18 @@ void C_ParticleSystem::PostDataUpdate( DataUpdateType_t updateType ) SetNextClientThink( gpGlobals->curtime ); } else +#ifdef MAPBASE + { + if (!m_bDestroyImmediately) + ParticleProp()->StopEmission(); + else + ParticleProp()->StopEmissionAndDestroyImmediately(); + } +#else { ParticleProp()->StopEmission(); } +#endif } } } @@ -135,21 +152,41 @@ void C_ParticleSystem::ClientThink( void ) AssertMsg1( pEffect, "Particle system couldn't make %s", pszName ); if (pEffect) { - for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) + if (m_vControlPointVecs[0] != GetAbsOrigin() && m_hControlPointEnts[0] == NULL) { - CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); - if ( pOnEntity ) + // we are using info_particle_system_coordinate + for (int i = 0; i < kMAXCONTROLPOINTS; ++i) { - ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); - } + ParticleProp()->AddControlPoint(pEffect, i + 1, this, PATTACH_WORLDORIGIN, 0, m_vControlPointVecs[i] - GetAbsOrigin()); - AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , - "Particle system specified bogus control point parent (%d) for point %d.", - m_iControlPointParents[i], i ); + AssertMsg2(m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS, + "Particle system specified bogus control point parent (%d) for point %d.", + m_iControlPointParents[i], i); - if (m_iControlPointParents[i] != 0) + if (m_iControlPointParents[i] != 0) + { + pEffect->SetControlPointParent(i + 1, m_iControlPointParents[i]); + } + } + } + else + { + for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) { - pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); + CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); + if ( pOnEntity ) + { + ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); + } + + AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , + "Particle system specified bogus control point parent (%d) for point %d.", + m_iControlPointParents[i], i ); + + if (m_iControlPointParents[i] != 0) + { + pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); + } } } @@ -198,19 +235,12 @@ void ParticleEffectCallback( const CEffectData &data ) pEnt->ParticleProp()->StopEmission(); } - Vector vOffset = vec3_origin; - ParticleAttachment_t iAttachType = (ParticleAttachment_t)data.m_nDamageType; - if ( iAttachType == PATTACH_ABSORIGIN_FOLLOW || iAttachType == PATTACH_POINT_FOLLOW || iAttachType == PATTACH_ROOTBONE_FOLLOW ) - { - vOffset = data.m_vStart; - } - - pEffect = pEnt->ParticleProp()->Create( pszName, iAttachType, data.m_nAttachmentIndex, vOffset ); + pEffect = pEnt->ParticleProp()->Create( pszName, (ParticleAttachment_t)data.m_nDamageType, data.m_nAttachmentIndex ); AssertMsg2( pEffect.IsValid() && pEffect->IsValid(), "%s could not create particle effect %s", C_BaseEntity::Instance( data.m_hEntity )->GetDebugName(), pszName ); if ( pEffect.IsValid() && pEffect->IsValid() ) { - if ( iAttachType == PATTACH_CUSTOMORIGIN ) + if ( (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN ) { pEffect->SetSortOrigin( data.m_vOrigin ); pEffect->SetControlPoint( 0, data.m_vOrigin ); diff --git a/game/client/c_pixel_visibility.cpp b/game/client/c_pixel_visibility.cpp index 8ff507b1..340616fd 100644 --- a/game/client/c_pixel_visibility.cpp +++ b/game/client/c_pixel_visibility.cpp @@ -429,8 +429,10 @@ void CPixelVisibilityQuery::IssueQuery( IMatRenderContext *pRenderContext, float return; } } +#ifndef MAPBASE // Mapbase can also query visibility several times via multiple point_cameras, etc. #ifndef PORTAL // FIXME: In portal we query visibility multiple times per frame because of portal renders! Assert ( ( m_frameIssued != gpGlobals->framecount ) || UseVR() ); +#endif #endif m_frameIssued = gpGlobals->framecount; diff --git a/game/client/c_playerlocaldata.h b/game/client/c_playerlocaldata.h index 95b6d48d..1efb8021 100644 --- a/game/client/c_playerlocaldata.h +++ b/game/client/c_playerlocaldata.h @@ -75,6 +75,9 @@ class CPlayerLocalData bool m_bSlowMovement; + //Tony; added so tonemap controller can work in multiplayer with inputs. + tonemap_params_t m_TonemapParams; + }; #endif // C_PLAYERLOCALDATA_H diff --git a/game/client/c_point_camera.cpp b/game/client/c_point_camera.cpp index 3d6eaa15..30c109a3 100644 --- a/game/client/c_point_camera.cpp +++ b/game/client/c_point_camera.cpp @@ -25,6 +25,10 @@ IMPLEMENT_CLIENTCLASS_DT( C_PointCamera, DT_PointCamera, CPointCamera ) RecvPropFloat( RECVINFO( m_flFogMaxDensity ) ), RecvPropInt( RECVINFO( m_bActive ) ), RecvPropInt( RECVINFO( m_bUseScreenAspectRatio ) ), +#ifdef MAPBASE + RecvPropInt( RECVINFO( m_iSkyMode ) ), + RecvPropString( RECVINFO( m_iszRenderTarget ) ), +#endif END_RECV_TABLE() C_EntityClassList g_PointCameraList; @@ -40,6 +44,10 @@ C_PointCamera::C_PointCamera() m_bActive = false; m_bFogEnable = false; +#ifdef MAPBASE + m_iszRenderTarget[0] = '\0'; +#endif + g_PointCameraList.Insert( this ); } @@ -53,6 +61,16 @@ bool C_PointCamera::ShouldDraw() return false; } +void C_PointCamera::OnDataChanged( DataUpdateType_t type ) +{ +#ifdef MAPBASE + // Reset render texture + m_pRenderTarget = NULL; +#endif + + return BaseClass::OnDataChanged( type ); +} + float C_PointCamera::GetFOV() { return m_FOV; @@ -113,4 +131,31 @@ void C_PointCamera::GetToolRecordingState( KeyValues *msg ) msg->SetPtr( "monitor", &state ); } +#ifdef MAPBASE +extern ITexture *GetCameraTexture( void ); +extern void AddReleaseFunc( void ); + +ITexture *C_PointCamera::RenderTarget() +{ + if (m_iszRenderTarget[0] != '\0') + { + if (!m_pRenderTarget) + { + // We don't use a CTextureReference for this because we don't want to shut down the texture on removal/change + m_pRenderTarget = materials->FindTexture( m_iszRenderTarget, TEXTURE_GROUP_RENDER_TARGET ); + } + + if (m_pRenderTarget) + return m_pRenderTarget; + } + + return GetCameraTexture(); +} + +IMPLEMENT_CLIENTCLASS_DT( C_PointCameraOrtho, DT_PointCameraOrtho, CPointCameraOrtho ) + RecvPropInt( RECVINFO( m_bOrtho ) ), + RecvPropArray( RecvPropFloat( RECVINFO( m_OrthoDimensions[0] ) ), m_OrthoDimensions ), +END_RECV_TABLE() +#endif + diff --git a/game/client/c_point_camera.h b/game/client/c_point_camera.h index 8bca63af..c77e9c20 100644 --- a/game/client/c_point_camera.h +++ b/game/client/c_point_camera.h @@ -29,6 +29,9 @@ class C_PointCamera : public C_BaseEntity // C_BaseEntity. virtual bool ShouldDraw(); + // Mapbase uses this for m_iszRenderTarget + virtual void OnDataChanged( DataUpdateType_t type ); + float GetFOV(); float GetResolution(); bool IsFogEnabled(); @@ -37,6 +40,14 @@ class C_PointCamera : public C_BaseEntity float GetFogMaxDensity(); float GetFogEnd(); bool UseScreenAspectRatio() const { return m_bUseScreenAspectRatio; } +#ifdef MAPBASE + virtual bool IsOrtho() const { return false; } + virtual void GetOrthoDimensions(float &up, float &dn, float &lf, float &rt) const {} + + SkyboxVisibility_t SkyMode() { return m_iSkyMode; } + + ITexture *RenderTarget(); +#endif virtual void GetToolRecordingState( KeyValues *msg ); @@ -50,11 +61,37 @@ class C_PointCamera : public C_BaseEntity float m_flFogMaxDensity; bool m_bActive; bool m_bUseScreenAspectRatio; +#ifdef MAPBASE + SkyboxVisibility_t m_iSkyMode; + ITexture *m_pRenderTarget; + char m_iszRenderTarget[64]; +#endif public: C_PointCamera *m_pNext; }; +#ifdef MAPBASE +class C_PointCameraOrtho : public C_PointCamera +{ +public: + DECLARE_CLASS( C_PointCameraOrtho, C_PointCamera ); + DECLARE_CLIENTCLASS(); + +public: + bool IsOrtho() const { return m_bOrtho; } + void GetOrthoDimensions( float &up, float &dn, float &lf, float &rt ) const + { + up = m_OrthoDimensions[0], dn = m_OrthoDimensions[1]; + lf = m_OrthoDimensions[2], rt = m_OrthoDimensions[3]; + } + +private: + bool m_bOrtho; + float m_OrthoDimensions[4]; +}; +#endif + C_PointCamera *GetPointCameraList(); #endif // C_POINTCAMERA_H diff --git a/game/client/c_point_commentary_node.cpp b/game/client/c_point_commentary_node.cpp index 47ea96ef..d65896b5 100644 --- a/game/client/c_point_commentary_node.cpp +++ b/game/client/c_point_commentary_node.cpp @@ -18,6 +18,16 @@ #include "convar.h" #include "hud_closecaption.h" #include "in_buttons.h" +#ifdef MAPBASE +#include "vgui_controls/Label.h" +#include "vgui_controls/TextImage.h" +#include "vgui_controls/ImagePanel.h" +#include "vgui_controls/AnimationController.h" +#include "filesystem.h" +#include "scenefilecache/ISceneFileCache.h" +#include "choreoscene.h" +#include "c_sceneentity.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -37,6 +47,17 @@ bool IsInCommentaryMode( void ) static bool g_bTracingVsCommentaryNodes = false; +#ifdef MAPBASE +ConVar commentary_type_force( "commentary_type_force", "-1", FCVAR_NONE, "Forces all commentary nodes to use the specified type." ); +ConVar commentary_type_text_endtime( "commentary_type_text_endtime", "120" ); +ConVar commentary_type_image_endtime( "commentary_type_image_endtime", "120" ); +ConVar commentary_audio_element_below_cc( "commentary_audio_element_below_cc", "1", FCVAR_NONE, "Allows commentary audio elements to display even when CC is enabled (although this is done by inverting their Y axis)" ); +ConVar commentary_audio_element_below_cc_margin( "commentary_audio_element_below_cc_margin", "4" ); +ConVar commentary_combine_speaker_and_printname( "commentary_combine_speaker_and_printname", "1" ); +ConVar commentary_footnote_offset_x( "commentary_footnote_offset_x", "16" ); +ConVar commentary_footnote_offset_y( "commentary_footnote_offset_y", "8" ); +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -52,12 +73,28 @@ class CHudCommentary : public CHudElement, public vgui::Panel virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); void StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ); +#ifdef MAPBASE + void StartTextCommentary( C_PointCommentaryNode *pNode, const char *pszText, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ); + void StartImageCommentary( C_PointCommentaryNode *pNode, const char *pszImage, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ); + void StartSceneCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ); +#endif void StopCommentary( void ); bool IsTheActiveNode( C_PointCommentaryNode *pNode ) { return (pNode == m_hActiveNode); } +#ifdef MAPBASE + void FixupCommentaryLabels( const char *pszPrintName, const char *pszSpeakers, const char *pszFootnote ); + void RepositionAndFollowCloseCaption( int yOffset = 0 ); +#endif + // vgui overrides virtual void Paint( void ); virtual bool ShouldDraw( void ); +#ifdef MAPBASE + virtual void PerformLayout(); + void ResolveBounds( int width, int height ); + + virtual void LevelShutdown(); +#endif private: CHandle m_hActiveNode; @@ -68,6 +105,25 @@ class CHudCommentary : public CHudElement, public vgui::Panel wchar_t m_szCount[MAX_COUNT_STRING]; CMaterialReference m_matIcon; bool m_bHiding; +#ifdef MAPBASE + int m_iCommentaryType; + float m_flPanelScale; + float m_flOverrideX; + float m_flOverrideY; + + vgui::Label *m_pLabel; + vgui::ImagePanel *m_pImage; + vgui::HFont m_hFont; + + vgui::Label *m_pFootnoteLabel; + vgui::HFont m_hSmallFont; + + // HACKHACK: Needed as a failsafe to prevent desync + int m_iCCDefaultY; + float m_flCCAnimTime; + + bool m_bShouldRepositionSubtitles; +#endif // Painting CPanelAnimationVarAliasType( int, m_iBarX, "bar_xpos", "8", "proportional_int" ); @@ -84,24 +140,65 @@ class CHudCommentary : public CHudElement, public vgui::Panel CPanelAnimationVarAliasType( int, m_iIconTall, "icon_height", "8", "proportional_int" ); CPanelAnimationVarAliasType( int, m_nIconTextureId, "icon_texture", "vgui/hud/icon_commentary", "textureid" ); +#ifdef MAPBASE + CPanelAnimationVarAliasType( int, m_iTypeAudioX, "type_audio_xpos", "190", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeAudioY, "type_audio_ypos", "350", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeAudioW, "type_audio_wide", "380", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeAudioT, "type_audio_tall", "40", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextX, "type_text_xpos", "180", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextY, "type_text_ypos", "150", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextW, "type_text_wide", "400", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextT, "type_text_tall", "200", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextCountXFR, "type_text_count_xpos_from_right", "10", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextCountYFB, "type_text_count_ypos_from_bottom", "10", "proportional_int" ); + CPanelAnimationVar( Color, m_TextBackgroundColor, "BackgroundColorTextContent", "0 0 0 224" ); + CPanelAnimationVar( Color, m_TypeTextContentColor, "TextContentColor", "255 230 180 255" ); + CPanelAnimationVar( int, m_iTextBorderSpace, "type_text_border_space", "8" ); +#endif + CPanelAnimationVar( bool, m_bUseScriptBGColor, "use_script_bgcolor", "0" ); +#ifdef MAPBASE + CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "Panel.BgColor" ); + CPanelAnimationVar( Color, m_ForegroundColor, "ForegroundColor", "255 170 0 255" ); +#else CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "0 0 0 0" ); +#endif CPanelAnimationVar( Color, m_BGOverrideColor, "BackgroundOverrideColor", "Panel.BgColor" ); }; //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -class C_PointCommentaryNode : public C_BaseAnimating +class C_PointCommentaryNode : public C_BaseAnimating, public IChoreoEventCallback { DECLARE_CLASS( C_PointCommentaryNode, C_BaseAnimating ); public: DECLARE_CLIENTCLASS(); DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif virtual void OnPreDataChanged( DataUpdateType_t type ); virtual void OnDataChanged( DataUpdateType_t type ); + void StartAudioCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ); +#ifdef MAPBASE + void StartTextCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ); + void StartImageCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ); + void StartSceneCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ); + + // From IChoreoEventCallback + virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ); +#else + virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {} +#endif + virtual void EndEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {} + virtual void ProcessEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {} + virtual bool CheckEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) { return true; } + + void ClientThink(); + void OnRestore( void ) { BaseClass::OnRestore(); @@ -149,6 +246,11 @@ class C_PointCommentaryNode : public C_BaseAnimating { int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "commentary" ); gHUD.LockRenderGroup( iRenderGroup ); + +#ifdef MAPBASE + // Special commentary localization file (useful for things like text nodes or print names) + g_pVGuiLocalize->AddFile( "resource/commentary_%language%.txt", "MOD", true ); +#endif } if ( g_CommentaryNodes.Find(this) == g_CommentaryNodes.InvalidIndex() ) @@ -168,6 +270,22 @@ class C_PointCommentaryNode : public C_BaseAnimating } } +#ifdef MAPBASE_VSCRIPT // VScript funcs + bool IsActive() { return m_bActive; } + + int GetCommentaryType() { return m_iCommentaryType; } + void SetCommentaryType( int iType ) { m_iCommentaryType = iType; } + + const char *GetCommentaryFile() { return m_iszCommentaryFile; } + void SetCommentaryFile( const char *pszNewFile ) { Q_strncpy( m_iszCommentaryFile, pszNewFile, sizeof( m_iszCommentaryFile ) ); } + const char *GetSpeakers() { return m_iszSpeakers; } + void SetSpeakers( const char *pszSpeakers ) { Q_strncpy( m_iszSpeakers, pszSpeakers, sizeof( m_iszSpeakers ) ); } + const char *GetPrintName() { return m_iszPrintName; } + void SetPrintName( const char *pszPrintName ) { Q_strncpy( m_iszPrintName, pszPrintName, sizeof( m_iszPrintName ) ); } + const char *GetFootnote() { return m_iszFootnote; } + void SetFootnote( const char *pszFootnote ) { Q_strncpy( m_iszFootnote, pszFootnote, sizeof( m_iszFootnote ) ); } +#endif + public: // Data received from the server bool m_bActive; @@ -181,6 +299,22 @@ class C_PointCommentaryNode : public C_BaseAnimating CSoundPatch *m_sndCommentary; EHANDLE m_hViewPosition; bool m_bRestartAfterRestore; +#ifdef MAPBASE + char m_iszPrintName[MAX_SPEAKER_NAME]; + char m_iszFootnote[MAX_SPEAKER_NAME]; + int m_iCommentaryType; + float m_flPanelScale; + float m_flPanelX; + float m_flPanelY; + + CChoreoScene *m_pScene; + //CHandle m_hScene; + EHANDLE m_hSceneOrigin; +#endif + +#ifdef MAPBASE_VSCRIPT + static ScriptHook_t g_Hook_PreStartCommentaryClient; +#endif }; IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCommentaryNode) @@ -192,6 +326,14 @@ IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCo RecvPropInt( RECVINFO( m_iNodeNumber ) ), RecvPropInt( RECVINFO( m_iNodeNumberMax ) ), RecvPropEHandle( RECVINFO(m_hViewPosition) ), +#ifdef MAPBASE + RecvPropString( RECVINFO( m_iszPrintName ) ), + RecvPropString( RECVINFO( m_iszFootnote ) ), + RecvPropInt( RECVINFO( m_iCommentaryType ) ), + RecvPropFloat( RECVINFO( m_flPanelScale ) ), + RecvPropFloat( RECVINFO( m_flPanelX ) ), + RecvPropFloat( RECVINFO( m_flPanelY ) ), +#endif END_RECV_TABLE() BEGIN_DATADESC( C_PointCommentaryNode ) @@ -200,6 +342,28 @@ BEGIN_DATADESC( C_PointCommentaryNode ) DEFINE_SOUNDPATCH( m_sndCommentary ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +ScriptHook_t C_PointCommentaryNode::g_Hook_PreStartCommentaryClient; + +BEGIN_ENT_SCRIPTDESC( C_PointCommentaryNode, C_BaseAnimating, "Commentary nodes which play commentary in commentary mode." ) + + DEFINE_SCRIPTFUNC( IsActive, "" ) + DEFINE_SCRIPTFUNC( GetCommentaryFile, "" ) + DEFINE_SCRIPTFUNC( SetCommentaryFile, "" ) + DEFINE_SCRIPTFUNC( GetSpeakers, "" ) + DEFINE_SCRIPTFUNC( SetSpeakers, "" ) + DEFINE_SCRIPTFUNC( GetPrintName, "" ) + DEFINE_SCRIPTFUNC( SetPrintName, "" ) + DEFINE_SCRIPTFUNC( GetFootnote, "" ) + DEFINE_SCRIPTFUNC( SetFootnote, "" ) + DEFINE_SCRIPTFUNC( GetCommentaryType, "" ) + DEFINE_SCRIPTFUNC( SetCommentaryType, "" ) + + DEFINE_SIMPLE_SCRIPTHOOK( C_PointCommentaryNode::g_Hook_PreStartCommentaryClient, "PreStartCommentaryClient", FIELD_BOOLEAN, "Called just before commentary begins on the client. Use this to modify variables or commentary behavior before it begins. Returning false will prevent the commentary from starting." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -229,6 +393,22 @@ void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType ) C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( m_bActive && pPlayer ) { +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_PreStartCommentaryClient.CanRunInScope( m_ScriptScope )) + { + ScriptVariant_t functionReturn; + if (g_Hook_PreStartCommentaryClient.Call( m_ScriptScope, &functionReturn, NULL ) && functionReturn.m_type == FIELD_BOOLEAN) + { + // Don't play the commentary if it returned false + if (functionReturn.m_bool == false) + { + engine->ServerCmd( "commentary_finishnode\n" ); + return; + } + } + } +#endif + // Use the HDR / Non-HDR version based on whether we're running HDR or not char *pszCommentaryFile; if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE && m_iszCommentaryFileNoHDR && m_iszCommentaryFileNoHDR[0] ) @@ -245,71 +425,396 @@ void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType ) return; } - EmitSound_t es; - es.m_nChannel = CHAN_STATIC; - es.m_pSoundName = pszCommentaryFile; - es.m_SoundLevel = SNDLVL_GUNFIRE; - es.m_nFlags = SND_SHOULDPAUSE; +#ifdef MAPBASE + int iCommentaryType = m_iCommentaryType; + if (commentary_type_force.GetInt() != -1) + iCommentaryType = commentary_type_force.GetInt(); - CBaseEntity *pSoundEntity; - if ( m_hViewPosition ) + switch (iCommentaryType) { - pSoundEntity = m_hViewPosition; + case COMMENTARY_TYPE_TEXT: + StartTextCommentary( pszCommentaryFile, pPlayer ); + break; + + case COMMENTARY_TYPE_IMAGE: + StartImageCommentary( pszCommentaryFile, pPlayer ); + break; + + case COMMENTARY_TYPE_SCENE: + StartSceneCommentary( pszCommentaryFile, pPlayer ); + break; + + default: + case COMMENTARY_TYPE_AUDIO: + StartAudioCommentary( pszCommentaryFile, pPlayer ); + break; } - else if ( render->GetViewEntity() ) +#else + StartAudioCommentary( pszCommentaryFile, pPlayer ); +#endif + } + else if ( m_bWasActive ) + { + StopLoopingSounds(); + + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + if ( pHudCommentary->IsTheActiveNode(this) ) { - pSoundEntity = cl_entitylist->GetEnt( render->GetViewEntity() ); - es.m_SoundLevel = SNDLVL_NONE; + pHudCommentary->StopCommentary(); } - else + } + + m_bRestartAfterRestore = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::StartAudioCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ) +{ + EmitSound_t es; + es.m_nChannel = CHAN_STATIC; + es.m_pSoundName = pszCommentaryFile; + es.m_SoundLevel = SNDLVL_GUNFIRE; + es.m_nFlags = SND_SHOULDPAUSE; + + CBaseEntity *pSoundEntity; + if ( m_hViewPosition ) + { + pSoundEntity = m_hViewPosition; + } + else if ( render->GetViewEntity() ) + { + pSoundEntity = cl_entitylist->GetEnt( render->GetViewEntity() ); + es.m_SoundLevel = SNDLVL_NONE; + } + else + { + pSoundEntity = pPlayer; + } + CSingleUserRecipientFilter filter( pPlayer ); + m_sndCommentary = (CSoundEnvelopeController::GetController()).SoundCreate( filter, pSoundEntity->entindex(), es ); + if ( m_sndCommentary ) + { + (CSoundEnvelopeController::GetController()).SoundSetCloseCaptionDuration( m_sndCommentary, -1 ); + (CSoundEnvelopeController::GetController()).Play( m_sndCommentary, 1.0f, 100, m_flStartTime ); + } + + // Get the duration so we know when it finishes + float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; + bool bSubtitlesEnabled = false; + + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if ( pHudCloseCaption ) + { + // This is where we play the commentary close caption (and lock the other captions out). + // Also, if close captions are off we force a caption in non-English + if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) ) { - pSoundEntity = pPlayer; + // Clear the close caption element in preparation + pHudCloseCaption->Reset(); + + // Process the commentary caption + pHudCloseCaption->ProcessCaptionDirect( pszCommentaryFile, flDuration ); + + // Find the close caption hud element & lock it + pHudCloseCaption->Lock(); + + bSubtitlesEnabled = true; } - CSingleUserRecipientFilter filter( pPlayer ); - m_sndCommentary = (CSoundEnvelopeController::GetController()).SoundCreate( filter, pSoundEntity->entindex(), es ); - if ( m_sndCommentary ) + } + + char *pszSpeakers = m_iszSpeakers; + + // Tell the HUD element + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + pHudCommentary->StartCommentary( this, pszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::StartTextCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ) +{ + // Get the duration so we know when it finishes + //float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; + + // TODO: Determine from text length? + float flDuration = commentary_type_text_endtime.GetFloat(); + + // Tell the HUD element + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + pHudCommentary->StartTextCommentary( this, pszCommentaryFile, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::StartImageCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ) +{ + // Get the duration so we know when it finishes + //float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; + + float flDuration = commentary_type_image_endtime.GetFloat(); + + // Tell the HUD element + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + pHudCommentary->StartImageCommentary( this, pszCommentaryFile, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); +} + +extern CChoreoStringPool g_ChoreoStringPool; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::StartSceneCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer ) +{ + char loadfile[MAX_PATH]; + Q_strncpy( loadfile, pszCommentaryFile, sizeof( loadfile ) ); + Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) ); + Q_FixSlashes( loadfile ); + + // + // Raw scene file support + // + void *pBuffer = 0; + size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile ); + if ( bufsize > 0 ) + { + // Definitely in scenes.image + pBuffer = malloc( bufsize ); + if ( !scenefilecache->GetSceneData( pszCommentaryFile, (byte *)pBuffer, bufsize ) ) { - (CSoundEnvelopeController::GetController()).SoundSetCloseCaptionDuration( m_sndCommentary, -1 ); - (CSoundEnvelopeController::GetController()).Play( m_sndCommentary, 1.0f, 100, m_flStartTime ); + free( pBuffer ); } - // Get the duration so we know when it finishes - float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; - - CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); - if ( pHudCloseCaption ) + + if ( IsBufferBinaryVCD( (char*)pBuffer, bufsize ) ) { - // This is where we play the commentary close caption (and lock the other captions out). - // Also, if close captions are off we force a caption in non-English - if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) ) + m_pScene = new CChoreoScene( NULL ); + CUtlBuffer buf( pBuffer, bufsize, CUtlBuffer::READ_ONLY ); + if ( !m_pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) ) { - // Clear the close caption element in preparation - pHudCloseCaption->Reset(); + Warning( "Unable to restore scene '%s'\n", loadfile ); + delete m_pScene; + m_pScene = NULL; + } + } + } + else if (filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true )) + { + // Not in scenes.image, but it's a raw file + g_TokenProcessor.SetBuffer((char*)pBuffer); + m_pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf ); + } + + free( pBuffer ); + + if( m_pScene ) + { + m_pScene->SetPrintFunc( Scene_Printf ); + m_pScene->SetEventCallbackInterface( this ); + } + else + { + // Cancel commentary (TODO: clean up?) + return; + } - // Process the commentary caption - pHudCloseCaption->ProcessCaptionDirect( pszCommentaryFile, flDuration ); + int types[ 2 ]; + types[ 0 ] = CChoreoEvent::SPEAK; + //types[ 1 ] = CChoreoEvent::GENERIC; // TODO: Support for the game_text event? + m_pScene->RemoveEventsExceptTypes( types, 1 ); + + // Iterate events and precache necessary resources + for ( int i = 0; i < m_pScene->GetNumEvents(); i++ ) + { + CChoreoEvent *event = m_pScene->GetEvent( i ); + if ( !event ) + continue; - // Find the close caption hud element & lock it - pHudCloseCaption->Lock(); + // load any necessary data + switch (event->GetType() ) + { + default: + break; + case CChoreoEvent::SPEAK: + { + // Defined in SoundEmitterSystem.cpp + // NOTE: The script entries associated with .vcds are forced to preload to avoid + // loading hitches during triggering + CBaseEntity::PrecacheScriptSound( event->GetParameters() ); + + if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && + event->GetNumSlaves() > 0 ) + { + char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ]; + if ( event->GetPlaybackCloseCaptionToken( tok, sizeof( tok ) ) ) + { + CBaseEntity::PrecacheScriptSound( tok ); + } + } } + break; } + } + + PrecacheScriptSound( "AI_BaseNPC.SentenceStop" ); - // Tell the HUD element - CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); - pHudCommentary->StartCommentary( this, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); + if ( m_hViewPosition ) + { + m_hSceneOrigin = m_hViewPosition; } - else if ( m_bWasActive ) + else if ( render->GetViewEntity() ) { - StopLoopingSounds(); + m_hSceneOrigin = cl_entitylist->GetEnt( render->GetViewEntity() ); + } + else + { + m_hSceneOrigin = pPlayer; + } - CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); - if ( pHudCommentary->IsTheActiveNode(this) ) + // Get the duration so we know when it finishes + float flDuration = m_pScene->GetDuration(); + + // Add a tiny amount of time at the end to ensure audio doesn't get cut off + flDuration += 0.5f; + + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if ( pHudCloseCaption ) + { + // This is where we play the commentary close caption (and lock the other captions out). + // Also, if close captions are off we force a caption in non-English + if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) ) { - pHudCommentary->StopCommentary(); + // Clear the close caption element in preparation + pHudCloseCaption->Reset(); + + // Find the close caption hud element & lock it + pHudCloseCaption->Lock(); } } - m_bRestartAfterRestore = false; + // Tell the HUD element + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + pHudCommentary->StartSceneCommentary( this, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); + + // Start thinking for the scene + SetNextClientThink( CLIENT_THINK_ALWAYS ); +} + +//----------------------------------------------------------------------------- +// Purpose: All events are leading edge triggered +// Input : currenttime - +// *event - +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) +{ + Assert( event ); + + if ( !Q_stricmp( event->GetName(), "NULL" ) ) + { + return; + } + + //Msg("Starting event \"%s\" (%s)\n", event->GetName(), event->GetParameters()); + + // load any necessary data + switch (event->GetType() ) + { + default: + break; + case CChoreoEvent::SPEAK: + { + CSingleUserRecipientFilter filter( C_BasePlayer::GetLocalPlayer() ); + + CSoundParameters soundParams; + bool bSoundscript = (g_pSoundEmitterSystem->GetParametersForSound( event->GetParameters(), soundParams, GENDER_NONE, false )); + EmitSound_t es( soundParams ); + if (bSoundscript) + { + } + else + { + es.m_pSoundName = event->GetParameters(); + es.m_flVolume = 1; + } + + // TODO: This is supposed to make sure actors don't interrupt each other, but it doesn't seem to work + es.m_nChannel = CHAN_USER_BASE + scene->FindActorIndex( event->GetActor() ); + es.m_SoundLevel = SNDLVL_GUNFIRE; + es.m_nFlags = SND_SHOULDPAUSE; + + es.m_bEmitCloseCaption = false; + + // Just in case + if (!m_hSceneOrigin) + m_hSceneOrigin = C_BasePlayer::GetLocalPlayer(); + + EmitSound( filter, m_hSceneOrigin->entindex(), es ); + + // Close captioning only on master token no matter what... + // Also, if close captions are off we force a caption in non-English + if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) ) + { + char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ]; + bool validtoken = event->GetPlaybackCloseCaptionToken( tok, sizeof( tok ) ); + if ( validtoken ) + { + CRC32_t tokenCRC; + CRC32_Init( &tokenCRC ); + + char lowercase[ 256 ]; + Q_strncpy( lowercase, tok, sizeof( lowercase ) ); + Q_strlower( lowercase ); + + CRC32_ProcessBuffer( &tokenCRC, lowercase, Q_strlen( lowercase ) ); + CRC32_Final( &tokenCRC ); + + float endtime = event->GetLastSlaveEndTime(); + float durationShort = event->GetDuration(); + float durationLong = endtime - event->GetStartTime(); + float duration = MAX( durationShort, durationLong ); + + CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); + if ( hudCloseCaption ) + { + hudCloseCaption->ProcessCaptionDirect( lowercase, duration ); + } + } + + } + } + break; + // TODO: Support for the game_text event? + /* + case CChoreoEvent::GENERIC: + { + + } + break; + */ + } + + event->m_flPrevTime = currenttime; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointCommentaryNode::ClientThink() +{ + BaseClass::ClientThink(); + +#ifdef MAPBASE + if (m_iCommentaryType == COMMENTARY_TYPE_SCENE && m_pScene) + { + m_pScene->Think( gpGlobals->curtime - m_flStartTime ); + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +#endif } //----------------------------------------------------------------------------- @@ -322,6 +827,29 @@ void C_PointCommentaryNode::StopLoopingSounds( void ) (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndCommentary ); m_sndCommentary = NULL; } + +#ifdef MAPBASE + if ( m_pScene ) + { + // Must do this to terminate audio + if (m_hSceneOrigin) + { + CSingleUserRecipientFilter filter( C_BasePlayer::GetLocalPlayer() ); + + for (int i = 0; i < m_pScene->GetNumActors(); i++) + { + EmitSound_t es; + es.m_nChannel = CHAN_USER_BASE + i; + es.m_pSoundName = "common/null.wav"; + + EmitSound( filter, m_hSceneOrigin->entindex(), es ); + } + } + + delete m_pScene; + m_pScene = NULL; + } +#endif } //----------------------------------------------------------------------------- @@ -374,6 +902,17 @@ CHudCommentary::CHudCommentary( const char *name ) : vgui::Panel( NULL, "HudComm m_hActiveNode = NULL; m_bShouldPaint = true; + +#ifdef MAPBASE + m_pLabel = new vgui::Label( this, "HudCommentaryTextLabel", L"Textual commentary" ); + m_pImage = new vgui::ImagePanel( this, "HudCommentaryImagePanel" ); + m_pImage->SetShouldScaleImage( true ); + + m_pFootnoteLabel = new vgui::Label( this, "HudCommentaryFootnoteLabel", L"Commentary footnote" ); + + m_iCCDefaultY = 0; + m_flCCAnimTime = 0.0f; +#endif } void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme ) @@ -384,6 +923,14 @@ void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme ) { SetBgColor( m_BGOverrideColor ); } + +#ifdef MAPBASE + m_pLabel->SetPaintBackgroundType( 2 ); + m_pLabel->SetSize( 0, GetTall() ); + + m_pFootnoteLabel->SetPaintBackgroundType( 2 ); + m_pFootnoteLabel->SetSize( 0, GetTall() ); +#endif } //----------------------------------------------------------------------------- @@ -405,6 +952,17 @@ void CHudCommentary::Paint() if ( pHudCloseCaption ) { pHudCloseCaption->Reset(); + +#ifdef MAPBASE + // Reset close caption element if needed + if (pHudCloseCaption->IsUsingCommentaryDimensions()) + { + // Run this animation command instead of setting the position directly + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", m_iCCDefaultY, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL ); + + pHudCloseCaption->SetUsingCommentaryDimensions( false ); + } +#endif } } } @@ -413,6 +971,22 @@ void CHudCommentary::Paint() // Detect the end of the commentary if ( flPercentage >= 1 && m_hActiveNode ) { +#ifdef MAPBASE + // Ensure that the scene is terminated + if (m_iCommentaryType == COMMENTARY_TYPE_SCENE) + m_hActiveNode->StopLoopingSounds(); + + // Reset close caption element if needed + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions()) + { + // Run this animation command instead of setting the position directly + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", m_iCCDefaultY, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL ); + + pHudCloseCaption->SetUsingCommentaryDimensions( false ); + } +#endif + m_hActiveNode = NULL; g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HideCommentary" ); @@ -426,27 +1000,62 @@ void CHudCommentary::Paint() int x, y, wide, tall; GetBounds( x, y, wide, tall ); - int xOffset = m_iBarX; + int xOffset = m_iBarX; int yOffset = m_iBarY; // Find our fade based on our time shown - Color clr = Color( 255, 170, 0, GetAlpha() ); + Color clr = m_ForegroundColor; + +#ifdef MAPBASE + switch (m_iCommentaryType) + { + case COMMENTARY_TYPE_TEXT: + { + // Figure out the size before setting bounds + int lW, lT; + m_pLabel->GetContentSize( lW, lT ); + + lT += (m_iTextBorderSpace * 2); + + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + (m_iBarWide * m_flPanelScale), yOffset + (lT /** m_flPanelScale*/) ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + } break; + + case COMMENTARY_TYPE_IMAGE: + { + // Figure out the size before setting bounds + int iW, iT; + m_pImage->GetSize( iW, iT ); + //vgui::surface()->DrawGetTextureSize( m_pImage->GetImage()->GetID(), iW, iT ); + iW += (m_iTextBorderSpace * 2); + iT += (m_iTextBorderSpace * 2); + + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + iW, yOffset + iT ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + } break; + + default: + case COMMENTARY_TYPE_SCENE: + case COMMENTARY_TYPE_AUDIO: + { + // Draw the progress bar + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset+(m_iBarWide*m_flPanelScale), yOffset+m_iBarTall ); + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawFilledRect( xOffset+2, yOffset+2, xOffset+(int)(flPercentage*(m_iBarWide*m_flPanelScale))-2, yOffset+m_iBarTall-2 ); + } break; + } +#else // Draw the progress bar vgui::surface()->DrawSetColor( clr ); vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset+m_iBarWide, yOffset+m_iBarTall ); vgui::surface()->DrawSetColor( clr ); vgui::surface()->DrawFilledRect( xOffset+2, yOffset+2, xOffset+(int)(flPercentage*m_iBarWide)-2, yOffset+m_iBarTall-2 ); +#endif // Draw the speaker names - // Get our scheme and font information - vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); - if ( !hFont ) - { - hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); - } - vgui::surface()->DrawSetTextFont( hFont ); + vgui::surface()->DrawSetTextFont( m_hFont ); vgui::surface()->DrawSetTextColor( clr ); vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY ); vgui::surface()->DrawPrintText( m_szSpeakers, wcslen(m_szSpeakers) ); @@ -469,7 +1078,7 @@ void CHudCommentary::Paint() { int w, h; UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); - vgui::surface()->GetTextSize( hFont, wzFinal, w, h ); + vgui::surface()->GetTextSize( m_hFont, wzFinal, w, h ); vgui::surface()->DrawSetTextPos( m_iBarX + m_iBarWide - w, iY ); vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) ); } @@ -478,9 +1087,45 @@ void CHudCommentary::Paint() // Draw the commentary count // Determine our text size, and move that far in from the right hand size (plus the offset) int iCountWide, iCountTall; - vgui::surface()->GetTextSize( hFont, m_szCount, iCountWide, iCountTall ); + vgui::surface()->GetTextSize( m_hFont, m_szCount, iCountWide, iCountTall ); + +#ifdef MAPBASE + if (m_pFootnoteLabel->IsEnabled()) + { + // Raise the count's position so that it doesn't get in the way + //iCountTall *= 2; + + int x, y; + m_pFootnoteLabel->GetPos(x, y); + + // + // Draw a bullet next to each footnote + // + CUtlVector pLineCoords; + pLineCoords.AddToTail( 0 ); // First line + + m_pFootnoteLabel->GetTextImage()->GetNewlinePositions( &pLineCoords, true ); + + int iBulletX = x - commentary_footnote_offset_x.GetInt(); + int iBulletY = y; + + vgui::surface()->DrawSetTextFont( m_hFont ); + vgui::surface()->DrawSetTextColor( clr ); + + for (int i = 0; i < pLineCoords.Count(); i++) + { + vgui::surface()->DrawSetTextPos( iBulletX, iBulletY + pLineCoords[i] ); + vgui::surface()->DrawUnicodeChar( L'\u2022' ); + } + } + + if (m_iCommentaryType != COMMENTARY_TYPE_AUDIO && m_iCommentaryType != COMMENTARY_TYPE_SCENE) + vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, tall - m_iTypeTextCountYFB - iCountTall ); + else +#endif vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY ); - vgui::surface()->DrawPrintText( m_szCount, wcslen(m_szCount) ); + + vgui::surface()->DrawPrintText( m_szCount, wcslen( m_szCount ) ); // Draw the icon vgui::surface()->DrawSetColor( Color(255,170,0,GetAlpha()) ); @@ -496,52 +1141,370 @@ bool CHudCommentary::ShouldDraw() return ( m_hActiveNode || GetAlpha() > 0 ); } +#ifdef MAPBASE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CHudCommentary::Init( void ) -{ - m_matIcon.Init( "vgui/hud/icon_commentary", TEXTURE_GROUP_VGUI ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudCommentary::VidInit( void ) -{ - SetAlpha(0); - StopCommentary(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ) +void CHudCommentary::PerformLayout() { - if ( (flEndTime - flStartTime) <= 0 ) + BaseClass::PerformLayout(); + + // Don't do anything if we shouldn't draw + if (!m_hActiveNode) // !ShouldDraw() return; - m_hActiveNode = pNode; - m_flStartTime = flStartTime; - m_flEndTime = flEndTime; - m_bHiding = false; - g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof(m_szSpeakers) ); + int extraWidth = 0, extraHeight = 0; - // Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode) - ConVarRef pCVar( "closecaption" ); - if ( pCVar.IsValid() ) + // The dimensions of a progress bar, text card, etc. + int contentWidth = 0, contentHeight = 0; + + int xOffset = m_iBarX; + int yOffset = m_iBarY; + + // Footnotes can add more space to the bottom if they have newlines. + if (m_pFootnoteLabel->IsEnabled()) { - m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() ); + m_pFootnoteLabel->SetBounds( xOffset, yOffset, (float)(m_iBarWide * m_flPanelScale), GetTall() ); + + int iNoteWide, iNoteTall; + m_pFootnoteLabel->GetContentSize( iNoteWide, iNoteTall ); + + m_pFootnoteLabel->SetTall( iNoteTall ); + + extraHeight += iNoteTall; } - else + + switch (m_iCommentaryType) { - m_bShouldPaint = true; - } - SetPaintBackgroundEnabled( m_bShouldPaint ); + case COMMENTARY_TYPE_TEXT: + { + m_pLabel->SetBounds( + xOffset + m_iTextBorderSpace, yOffset + m_iTextBorderSpace, + (float)(m_iBarWide * m_flPanelScale) - m_iTextBorderSpace, GetTall() ); - char sz[MAX_COUNT_STRING]; - Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax ); - g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) ); + // Figure out the size before setting bounds + int lW, lT; + m_pLabel->GetContentSize( lW, lT ); + + //lT = (float)lT * m_flPanelScale; // Don't affect height when scaling + + m_pLabel->SetTall( lT ); + + lW += (m_iTextBorderSpace * 2); + lT += (m_iTextBorderSpace * 2); + + contentWidth = lW, contentHeight = lT; + + lW += (xOffset * 2); + lT += (yOffset * 2); + + ResolveBounds( lW + extraWidth, lT + extraHeight ); + } break; + + case COMMENTARY_TYPE_IMAGE: + { + // Figure out the size before setting bounds + int iW, iT; + //m_pImage->GetImage()->GetSize( iW, iT ); + vgui::surface()->DrawGetTextureSize( m_pImage->GetImage()->GetID(), iW, iT ); + if (iW <= 0) + iW = 1; + + int iTargetSize = (m_iBarWide - m_iTextBorderSpace); + iT *= (iTargetSize / iW); + iW = iTargetSize; + + iW = (float)iW * m_flPanelScale; + iT = (float)iT * m_flPanelScale; + + m_pImage->SetBounds( + xOffset + m_iTextBorderSpace, + yOffset + m_iTextBorderSpace, + iW, iT ); + + iW += (m_iTextBorderSpace * 2); + iT += (m_iTextBorderSpace * 2); + + contentWidth = iW, contentHeight = iT; + + iW += (xOffset * 2); + iT += (yOffset * 2); + + ResolveBounds( iW + extraWidth, iT + extraHeight ); + } break; + + default: + case COMMENTARY_TYPE_SCENE: + case COMMENTARY_TYPE_AUDIO: + + // Keep the box centered + SetBounds( m_iTypeAudioX, m_iTypeAudioY - extraHeight, m_iTypeAudioW + extraWidth, m_iTypeAudioT + extraHeight ); + + // Reposition the subtitles to be above the commentary dialog + if (m_bShouldRepositionSubtitles) + { + RepositionAndFollowCloseCaption( extraHeight ); + } + + contentWidth = (m_iBarWide * m_flPanelScale), contentHeight = m_iBarTall; + + break; + } + + // Move the footnote to be at the bottom + if (m_pFootnoteLabel->IsEnabled()) + { + m_pFootnoteLabel->SetPos( m_iSpeakersX + commentary_footnote_offset_x.GetInt(), yOffset+contentHeight+ commentary_footnote_offset_y.GetInt() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Resolves position on screen; Heavily borrows from CHudMessage::XPosition/YPosition +//----------------------------------------------------------------------------- +void CHudCommentary::ResolveBounds( int width, int height ) +{ + int xPos; + int yPos; + + // ====== X ====== + if ( m_flOverrideX == -1 ) + { + xPos = (ScreenWidth() - width) * 0.5f; + } + else + { + if ( m_flOverrideX < 0 ) + xPos = (1.0 + m_flOverrideX) * ScreenWidth() - width; // Align to right + else + xPos = m_flOverrideX * (ScreenWidth() - width); + } + + // Clamp to edge of screen + if ( xPos + width > ScreenWidth() ) + xPos = ScreenWidth() - width; + else if ( xPos < 0 ) + xPos = 0; + + // ====== Y ====== + if ( m_flOverrideY == -1 ) + { + yPos = (ScreenHeight() - height) * 0.5f; + } + else + { + if ( m_flOverrideY < 0 ) + yPos = (1.0 + m_flOverrideY) * ScreenHeight() - height; // Align to bottom + else + yPos = m_flOverrideY * (ScreenHeight() - height); + } + + // Clamp to edge of screen + if ( yPos + height > ScreenHeight() ) + yPos = ScreenHeight() - height; + else if ( yPos < 0 ) + yPos = 0; + + SetBounds( xPos, yPos, width, height ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::LevelShutdown( void ) +{ + if (m_iCCDefaultY != 0) + { + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions()) + { + int ccX, ccY; + pHudCloseCaption->GetPos( ccX, ccY ); + + if (m_iCCDefaultY != ccY) + { + DevMsg( "CHudCommentary had to reset misaligned CC element Y (%i) to default Y (%i)\n", ccY, m_iCCDefaultY ); + pHudCloseCaption->SetPos( ccX, m_iCCDefaultY ); + } + + pHudCloseCaption->SetUsingCommentaryDimensions( false ); + } + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::Init( void ) +{ + m_matIcon.Init( "vgui/hud/icon_commentary", TEXTURE_GROUP_VGUI ); + +#ifdef MAPBASE + SetProportional( true ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::VidInit( void ) +{ + SetAlpha(0); + StopCommentary(); +#ifdef MAPBASE + m_iCCDefaultY = 0; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ) +{ + if ( (flEndTime - flStartTime) <= 0 ) + return; + + m_hActiveNode = pNode; + m_flStartTime = flStartTime; + m_flEndTime = flEndTime; + m_bHiding = false; +#ifdef MAPBASE + m_iCommentaryType = COMMENTARY_TYPE_AUDIO; + m_flPanelScale = pNode->m_flPanelScale; + m_flOverrideX = pNode->m_flPanelX; + m_flOverrideY = pNode->m_flPanelY; +#endif + g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) ); + +#ifdef MAPBASE + SetBounds( m_iTypeAudioX, m_iTypeAudioY, m_iTypeAudioW, m_iTypeAudioT ); + SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_BackgroundColor ); + + m_pLabel->SetPaintEnabled( false ); + m_pImage->SetPaintEnabled( false ); + m_pImage->EvictImage(); + + m_pFootnoteLabel->SetEnabled( false ); + + // Get our scheme and font information + vgui::HScheme scheme = GetScheme(); + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); + if ( !m_hFont ) + { + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); + } + + m_hSmallFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentarySmall" ); + if ( !m_hSmallFont) + { + m_hSmallFont = m_hFont; + } +#endif + + // Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode) + ConVarRef pCVar( "closecaption" ); + if ( pCVar.IsValid() ) + { + m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() ); + } + else + { + m_bShouldPaint = true; + } + +#ifdef MAPBASE + if (!m_bShouldPaint && commentary_audio_element_below_cc.GetBool()) + { + m_bShouldPaint = true; + m_bShouldRepositionSubtitles = true; + + // Ensure we perform layout later + InvalidateLayout(); + } + else + m_bShouldRepositionSubtitles = false; + + FixupCommentaryLabels( pNode->m_iszPrintName, pNode->m_iszSpeakers, pNode->m_iszFootnote ); +#endif + + SetPaintBackgroundEnabled( m_bShouldPaint ); + + char sz[MAX_COUNT_STRING]; + Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax ); + g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) ); + + // If the commentary just started, play the commentary fade in. + if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" ); + } + else + { + // We're reloading a savegame that has an active commentary going in it. Don't fade in. + SetAlpha( 255 ); + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::StartTextCommentary( C_PointCommentaryNode *pNode, const char *pszText, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ) +{ + if ( (flEndTime - flStartTime) <= 0 ) + return; + + m_hActiveNode = pNode; + m_flStartTime = flStartTime; + m_flEndTime = flEndTime; + m_bHiding = false; + m_iCommentaryType = COMMENTARY_TYPE_TEXT; + m_flPanelScale = pNode->m_flPanelScale; + m_flOverrideX = pNode->m_flPanelX; + m_flOverrideY = pNode->m_flPanelY; + g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) ); + + SetBounds( m_iTypeTextX, m_iTypeTextY, m_iTypeTextW, m_iTypeTextT ); + SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_TextBackgroundColor ); + + // Get our scheme and font information + vgui::HScheme scheme = GetScheme(); + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); + if ( !m_hFont ) + { + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); + } + + m_hSmallFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentarySmall" ); + if ( !m_hSmallFont) + { + m_hSmallFont = m_hFont; + } + + m_pLabel->SetText( pszText ); + m_pLabel->SetFont( m_hFont ); + m_pLabel->SetWrap( true ); + m_pLabel->SetPaintEnabled( true ); + m_pLabel->SetPaintBackgroundEnabled( false ); + m_pLabel->SetPaintBorderEnabled( false ); + //m_pLabel->SizeToContents(); + m_pLabel->SetContentAlignment( vgui::Label::a_northwest ); + m_pLabel->SetFgColor( m_TypeTextContentColor ); + + m_pImage->SetPaintEnabled( false ); + m_pImage->EvictImage(); + + m_pFootnoteLabel->SetEnabled( false ); + + m_bShouldPaint = true; + + FixupCommentaryLabels( pNode->m_iszPrintName, pNode->m_iszSpeakers, pNode->m_iszFootnote ); + + SetPaintBackgroundEnabled( m_bShouldPaint ); + + char sz[MAX_COUNT_STRING]; + Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax ); + g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) ); // If the commentary just started, play the commentary fade in. if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 ) @@ -555,13 +1518,299 @@ void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpe } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::StartImageCommentary( C_PointCommentaryNode *pNode, const char *pszImage, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ) +{ + if ( (flEndTime - flStartTime) <= 0 ) + return; + + m_hActiveNode = pNode; + m_flStartTime = flStartTime; + m_flEndTime = flEndTime; + m_bHiding = false; + m_iCommentaryType = COMMENTARY_TYPE_IMAGE; + m_flPanelScale = pNode->m_flPanelScale; + m_flOverrideX = pNode->m_flPanelX; + m_flOverrideY = pNode->m_flPanelY; + g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) ); + + SetBounds( m_iTypeTextX, m_iTypeTextY, m_iTypeTextW, m_iTypeTextT ); + SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_TextBackgroundColor ); + + m_pLabel->SetPaintEnabled( false ); + + m_pImage->SetPaintEnabled( true ); + m_pImage->SetImage( pszImage ); + m_pImage->SetWide( m_iBarWide - m_iTextBorderSpace ); + + m_pFootnoteLabel->SetEnabled( false ); + + // Get our scheme and font information + vgui::HScheme scheme = GetScheme(); + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); + if ( !m_hFont ) + { + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); + } + + m_hSmallFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentarySmall" ); + if ( !m_hSmallFont) + { + m_hSmallFont = m_hFont; + } + + m_bShouldPaint = true; + + FixupCommentaryLabels( pNode->m_iszPrintName, pNode->m_iszSpeakers, pNode->m_iszFootnote ); + + SetPaintBackgroundEnabled( m_bShouldPaint ); + + char sz[MAX_COUNT_STRING]; + Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax ); + g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) ); + + // If the commentary just started, play the commentary fade in. + if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" ); + } + else + { + // We're reloading a savegame that has an active commentary going in it. Don't fade in. + SetAlpha( 255 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::StartSceneCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime ) +{ + if ( (flEndTime - flStartTime) <= 0 ) + return; + + m_hActiveNode = pNode; + m_flStartTime = flStartTime; + m_flEndTime = flEndTime; + m_bHiding = false; + m_iCommentaryType = COMMENTARY_TYPE_SCENE; + m_flPanelScale = pNode->m_flPanelScale; + m_flOverrideX = pNode->m_flPanelX; + m_flOverrideY = pNode->m_flPanelY; + g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) ); + + SetBounds( m_iTypeAudioX, m_iTypeAudioY, m_iTypeAudioW, m_iTypeAudioT ); + SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_BackgroundColor ); + + m_pLabel->SetPaintEnabled( false ); + m_pImage->SetPaintEnabled( false ); + m_pImage->EvictImage(); + + m_pFootnoteLabel->SetEnabled( false ); + + // Get our scheme and font information + vgui::HScheme scheme = GetScheme(); + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); + if ( !m_hFont ) + { + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); + } + + m_hSmallFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentarySmall" ); + if ( !m_hSmallFont) + { + m_hSmallFont = m_hFont; + } + + // Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode) + ConVarRef pCVar( "closecaption" ); + if ( pCVar.IsValid() ) + { + m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() ); + } + else + { + m_bShouldPaint = true; + } + + if (!m_bShouldPaint && commentary_audio_element_below_cc.GetBool()) + { + m_bShouldPaint = true; + m_bShouldRepositionSubtitles = true; + + // Ensure we perform layout later + InvalidateLayout(); + } + else + m_bShouldRepositionSubtitles = false; + + FixupCommentaryLabels( pNode->m_iszPrintName, pNode->m_iszSpeakers, pNode->m_iszFootnote ); + + SetPaintBackgroundEnabled( m_bShouldPaint ); + + char sz[MAX_COUNT_STRING]; + Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax ); + g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) ); + + // If the commentary just started, play the commentary fade in. + if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" ); + } + else + { + // We're reloading a savegame that has an active commentary going in it. Don't fade in. + SetAlpha( 255 ); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudCommentary::StopCommentary( void ) { m_hActiveNode = NULL; + +#ifdef MAPBASE + // Reset close caption element if needed + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions()) + { + // Run this animation command instead of setting the position directly + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", m_iCCDefaultY, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL ); + + pHudCloseCaption->SetUsingCommentaryDimensions( false ); + } +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::FixupCommentaryLabels( const char *pszPrintName, const char *pszSpeakers, const char *pszFootnote ) +{ + if (commentary_combine_speaker_and_printname.GetBool() && pszPrintName[0] != '\0') + { + wchar_t *pszLocal = g_pVGuiLocalize->Find( pszPrintName ); + if (m_szSpeakers[0] == '\0' || !m_bShouldPaint) // Use m_bShouldPaint as an indicator of whether or not we use subtitles + { + if (pszPrintName[0] == '#' && pszLocal) + wcsncpy( m_szSpeakers, pszLocal, sizeof( m_szSpeakers ) / sizeof( wchar_t ) ); + else + g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, m_szSpeakers, sizeof( m_szSpeakers ) ); + } + else + { + static wchar_t iszSpeakersLocalized[MAX_SPEAKER_NAME] = { 0 }; + static wchar_t iszPrintNameLocalized[MAX_SPEAKER_NAME] = { 0 }; + + wcsncpy( iszSpeakersLocalized, m_szSpeakers, sizeof( iszSpeakersLocalized ) / sizeof( wchar_t ) ); + + if (m_szSpeakers[0] == '#') + { + wchar_t *pwszSpeakers = g_pVGuiLocalize->Find( pszSpeakers ); + if (pwszSpeakers) + wcsncpy( iszSpeakersLocalized, pwszSpeakers, sizeof( iszSpeakersLocalized ) / sizeof( wchar_t ) ); + } + + if (pszPrintName[0] == '#' && pszLocal) + wcsncpy( iszPrintNameLocalized, pszLocal, sizeof( iszPrintNameLocalized ) / sizeof( wchar_t ) ); + else + g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, iszPrintNameLocalized, sizeof( iszPrintNameLocalized ) ); + + V_snwprintf( m_szSpeakers, sizeof( m_szSpeakers ), L"%ls ~ %ls", iszSpeakersLocalized, iszPrintNameLocalized ); + } + } + + if (pszFootnote[0] != '\0' && m_bShouldPaint) + { + m_pFootnoteLabel->SetText( pszFootnote ); + m_pFootnoteLabel->SetFont( m_hSmallFont ); + m_pFootnoteLabel->SetWrap( true ); + m_pFootnoteLabel->SetEnabled( true ); + m_pFootnoteLabel->SetPaintEnabled( true ); + m_pFootnoteLabel->SetPaintBackgroundEnabled( false ); + m_pFootnoteLabel->SetPaintBorderEnabled( false ); + //m_pFootnoteLabel->SizeToContents(); + m_pFootnoteLabel->SetContentAlignment( vgui::Label::a_northwest ); + m_pFootnoteLabel->SetFgColor( m_ForegroundColor ); + } + else + { + m_pFootnoteLabel->SetPaintEnabled( false ); + m_pFootnoteLabel->SetEnabled( false ); + } + + // Reset close caption element if it's still using commentary dimensions + // (fixes problems with switching from node to node) + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions()) + { + // Run this animation command instead of setting the position directly + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", m_iCCDefaultY, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL ); + + pHudCloseCaption->SetUsingCommentaryDimensions( false ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCommentary::RepositionAndFollowCloseCaption( int yOffset ) +{ + // Invert the Y axis + //SetPos( m_iTypeAudioX, ScreenHeight() - m_iTypeAudioY ); + + // Place underneath the close caption element + CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption ); + if (pHudCloseCaption /*&& !pHudCloseCaption->IsUsingCommentaryDimensions()*/) + { + int ccX, ccY; + pHudCloseCaption->GetPos( ccX, ccY ); + + // Save the default position in case we need to do a hard reset + // (this usually happens when players begin commentary before the CC element's return animation command is finished) + if (m_iCCDefaultY == 0) + { + m_iCCDefaultY = ccY; + } + + if (!pHudCloseCaption->IsUsingCommentaryDimensions()) + { + if (m_iCCDefaultY != ccY /*&& !pHudCloseCaption->IsUsingCommentaryDimensions()*/) + { + DevMsg( "CHudCommentary had to reset misaligned CC element Y (%i) to default Y (%i)\n", ccY, m_iCCDefaultY ); + ccY = m_iCCDefaultY; + } + + ccY -= m_iTypeAudioT; + + // Run this animation command instead of setting the position directly + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", ccY - yOffset, 0.0f, 0.2f, vgui::AnimationController::INTERPOLATOR_DEACCEL ); + //pHudCloseCaption->SetPos( ccX, ccY ); + m_flCCAnimTime = gpGlobals->curtime + 0.2f; + + pHudCloseCaption->SetUsingCommentaryDimensions( true ); + } + else if (gpGlobals->curtime > m_flCCAnimTime && ccY != m_iCCDefaultY - m_iTypeAudioT - yOffset) + { + DevMsg( "CHudCommentary had to correct misaligned CC element offset (%i != %i)\n", m_iCCDefaultY - ccY, yOffset ); + + g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", m_iCCDefaultY - m_iTypeAudioT - yOffset, 0.0f, 0.2f, vgui::AnimationController::INTERPOLATOR_DEACCEL ); + m_flCCAnimTime = gpGlobals->curtime + 0.2f; + } + + SetPos( ccX, ccY + pHudCloseCaption->GetTall() + commentary_audio_element_below_cc_margin.GetInt() ); + + m_flPanelScale = (float)pHudCloseCaption->GetWide() / (float)GetWide(); + SetWide( pHudCloseCaption->GetWide() ); + } } +#endif //----------------------------------------------------------------------------- // Purpose: diff --git a/game/client/c_postprocesscontroller.cpp b/game/client/c_postprocesscontroller.cpp new file mode 100644 index 00000000..91a2d1df --- /dev/null +++ b/game/client/c_postprocesscontroller.cpp @@ -0,0 +1,63 @@ +//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: stores map postprocess params +// +//============================================================================= +#include "cbase.h" +#include "c_postprocesscontroller.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +IMPLEMENT_CLIENTCLASS_DT( C_PostProcessController, DT_PostProcessController, CPostProcessController ) + RecvPropArray3( RECVINFO_NAME( m_PostProcessParameters.m_flParameters[0], m_flPostProcessParameters ), POST_PROCESS_PARAMETER_COUNT, RecvPropFloat( RECVINFO_NAME( m_PostProcessParameters.m_flParameters[0], m_flPostProcessParameters[0] ) ) ), + RecvPropBool( RECVINFO(m_bMaster) ) +END_RECV_TABLE() + +C_PostProcessController* C_PostProcessController::ms_pMasterController = nullptr; + +//----------------------------------------------------------------------------- +C_PostProcessController::C_PostProcessController() +: m_bMaster( false ) +{ + if ( ms_pMasterController == nullptr) + { + ms_pMasterController = this; + } +} + +//----------------------------------------------------------------------------- +C_PostProcessController::~C_PostProcessController() +{ + if ( ms_pMasterController == this ) + { + ms_pMasterController = nullptr; + } +} + +void C_PostProcessController::PostDataUpdate( DataUpdateType_t updateType ) +{ + BaseClass::PostDataUpdate( updateType ); + + if ( m_bMaster ) + { + ms_pMasterController = this; + } +} + +#ifdef MAPBASE +// Prevents parameters from fading after a save/restore +bool g_bPostProcessNeedsRestore = false; + +void C_PostProcessController::OnRestore() +{ + BaseClass::OnRestore(); + + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pPlayer && pPlayer->GetActivePostProcessController() == this ) + { + // Tell clientmode this is part of a save/restore + g_bPostProcessNeedsRestore = true; + } +} +#endif diff --git a/game/client/c_postprocesscontroller.h b/game/client/c_postprocesscontroller.h new file mode 100644 index 00000000..c07673f7 --- /dev/null +++ b/game/client/c_postprocesscontroller.h @@ -0,0 +1,33 @@ +#pragma once + +#include "postprocess_shared.h" + +//============================================================================= +// +// Class Postprocess Controller: +// +class C_PostProcessController : public C_BaseEntity +{ + DECLARE_CLASS( C_PostProcessController, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + C_PostProcessController(); + virtual ~C_PostProcessController(); + + virtual void PostDataUpdate( DataUpdateType_t updateType ); + + static C_PostProcessController* GetMasterController() { return ms_pMasterController; } + + PostProcessParameters_t m_PostProcessParameters; + +#ifdef MAPBASE + // Prevents fade time from being used in save/restore + virtual void OnRestore(); +#endif + +private: + bool m_bMaster; + + static C_PostProcessController* ms_pMasterController; +}; diff --git a/game/client/c_props.cpp b/game/client/c_props.cpp index 07f5710d..7981fe2c 100644 --- a/game/client/c_props.cpp +++ b/game/client/c_props.cpp @@ -24,6 +24,11 @@ BEGIN_NETWORK_TABLE( CDynamicProp, DT_DynamicProp ) RecvPropBool(RECVINFO(m_bUseHitboxesForRenderBox)), END_NETWORK_TABLE() +#ifdef MAPBASE_VSCRIPT +// Allows client-side VScript to create dynamic props via CreateProp() +LINK_ENTITY_TO_CLASS( prop_dynamic, C_DynamicProp ); +#endif + C_DynamicProp::C_DynamicProp( void ) { m_iCachedFrameCount = -1; diff --git a/game/client/c_rope.cpp b/game/client/c_rope.cpp index 0c84778c..30c6f284 100644 --- a/game/client/c_rope.cpp +++ b/game/client/c_rope.cpp @@ -12,7 +12,6 @@ #include "input.h" #ifdef TF_CLIENT_DLL #include "cdll_util.h" -#include "tf_gamerules.h" #endif #include "rope_helpers.h" #include "engine/ivmodelinfo.h" @@ -29,6 +28,14 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +static void PrecacheCable( void* ) +{ + PrecacheMaterial( "cable/rope_shadowdepth" ); +} +PRECACHE_REGISTER_FN( PrecacheCable ); +#endif + void RecvProxy_RecomputeSprings( const CRecvProxyData *pData, void *pStruct, void *pOut ) { // Have the regular proxy store the data. @@ -40,6 +47,9 @@ void RecvProxy_RecomputeSprings( const CRecvProxyData *pData, void *pStruct, voi IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_RopeKeyframe, DT_RopeKeyframe, CRopeKeyframe ) +#ifdef MAPBASE + RecvPropInt( RECVINFO( m_nChangeCount ) ), +#endif RecvPropInt( RECVINFO(m_iRopeMaterialModelIndex) ), RecvPropEHandle( RECVINFO(m_hStartPoint) ), RecvPropEHandle( RECVINFO(m_hEndPoint) ), @@ -63,6 +73,27 @@ IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_RopeKeyframe, DT_RopeKeyframe, CRopeKeyframe RecvPropInt( RECVINFO( m_iParentAttachment ) ), END_RECV_TABLE() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( C_RopeKeyframe, C_BaseEntity, "The clientside class of move_rope and keyframe_rope" ) + DEFINE_SCRIPTFUNC( GetNodePosition, "Gets the position of the specified node index" ) + DEFINE_SCRIPTFUNC( GetNumNodes, "Gets the number of nodes available" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetStartEntity, "GetStartEntity", "Gets the rope's start entity" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEndEntity, "GetEndEntity", "Gets the rope's end entity" ) + + DEFINE_SCRIPTFUNC( SetupHangDistance, "Sets the rope's hang distance" ) + DEFINE_SCRIPTFUNC( SetSlack, "Sets the rope's slack value (extra length)" ) + DEFINE_SCRIPTFUNC( GetRopeFlags, "Gets the rope's flags" ) + DEFINE_SCRIPTFUNC( SetRopeFlags, "Sets the rope's flags" ) + + DEFINE_SCRIPTFUNC( SetColorMod, "Sets the rope's color mod value" ) + + DEFINE_SCRIPTFUNC( ShakeRope, "Shakes the rope with the specified center, radius, and magnitude" ) + + DEFINE_SCRIPTFUNC( AnyPointsMoved, "Returns true if any points have moved recently" ) +END_SCRIPTDESC(); +#endif + #define ROPE_IMPULSE_SCALE 20 #define ROPE_IMPULSE_DECAY 0.95 @@ -81,7 +112,9 @@ static ConVar rope_smooth_maxalpha( "rope_smooth_maxalpha", "0.5", 0, "Alpha for static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); // get it from the engine static ConVar r_drawropes( "r_drawropes", "1", FCVAR_CHEAT ); +#ifndef MAPBASE static ConVar r_queued_ropes( "r_queued_ropes", "1" ); +#endif static ConVar r_ropetranslucent( "r_ropetranslucent", "1"); static ConVar r_rope_holiday_light_scale( "r_rope_holiday_light_scale", "0.055", FCVAR_DEVELOPMENTONLY ); static ConVar r_ropes_holiday_lights_allowed( "r_ropes_holiday_lights_allowed", "1", FCVAR_DEVELOPMENTONLY ); @@ -99,11 +132,17 @@ static ConVar rope_solid_minalpha( "rope_solid_minalpha", "0.0" ); static ConVar rope_solid_maxalpha( "rope_solid_maxalpha", "1" ); +#ifndef MAPBASE static CCycleCount g_RopeCollideTicks; static CCycleCount g_RopeDrawTicks; static CCycleCount g_RopeSimulateTicks; +#endif static int g_nRopePointsSimulated; +#ifdef MAPBASE +static IMaterial *g_pSplineCableShadowdepth = NULL; +#endif + // Active ropes. CUtlLinkedList g_Ropes; @@ -119,6 +158,7 @@ class CFullBrightLightValuesInit } } g_FullBrightLightValuesInit; +#ifndef MAPBASE // Precalculated info for rope subdivision. static Vector g_RopeSubdivs[MAX_ROPE_SUBDIVS][MAX_ROPE_SUBDIVS]; class CSubdivInit @@ -142,6 +182,7 @@ static int g_nBarbedSubdivs = 3; static Vector g_BarbedSubdivs[MAX_ROPE_SUBDIVS] = { Vector(1.5, 1.5*1.5, 1.5*1.5*1.5), Vector(-0.5, -0.5 * -0.5, -0.5*-0.5*-0.5), Vector(0.5, 0.5*0.5, 0.5*0.5*0.5) }; +#endif // This can be exposed through the entity if we ever care. static float g_flLockAmount = 0.1; @@ -149,7 +190,7 @@ static float g_flLockFalloff = 0.3; - +#ifndef MAPBASE class CQueuedRopeMemoryManager { public: @@ -194,7 +235,7 @@ class CQueuedRopeMemoryManager if( pReturn == NULL ) { int iMaxSize = m_QueuedRopeMemory[m_nCurrentStack].GetMaxSize(); - Warning( "Overflowed rope queued rendering memory stack. Needed %llu, have %d/%d\n", (uint64)bytes, iMaxSize - m_QueuedRopeMemory[m_nCurrentStack].GetUsed(), iMaxSize ); + Warning( "Overflowed rope queued rendering memory stack. Needed %d, have %d/%d\n", bytes, iMaxSize - m_QueuedRopeMemory[m_nCurrentStack].GetUsed(), iMaxSize ); pReturn = malloc( bytes ); m_DeleteOnSwitch[m_nCurrentStack].AddToTail( pReturn ); } @@ -219,6 +260,7 @@ struct RopeSegData_t // If this is less than rope_solid_minwidth and rope_solid_minalpha is 0, then we can avoid drawing.. float m_flMaxBackWidth; }; +#endif class CRopeManager : public IRopeManager { @@ -230,15 +272,18 @@ class CRopeManager : public IRopeManager void ResetRenderCache( void ); void AddToRenderCache( C_RopeKeyframe *pRope ); void DrawRenderCache( bool bShadowDepth ); +#ifndef MAPBASE void OnRenderStart( void ) { m_QueuedModeMemory.SwitchStack(); } +#endif void SetHolidayLightMode( bool bHoliday ) { m_bDrawHolidayLights = bHoliday; } bool IsHolidayLightMode( void ); int GetHolidayLightStyle( void ); +#ifndef MAPBASE private: struct RopeRenderData_t; public: @@ -246,26 +291,32 @@ class CRopeManager : public IRopeManager void ResetSegmentCache( int nMaxSegments ); RopeSegData_t *GetNextSegmentFromCache( void ); +#endif enum { MAX_ROPE_RENDERCACHE = 128 }; void RemoveRopeFromQueuedRenderCaches( C_RopeKeyframe *pRope ); +#ifndef MAPBASE private: void RenderNonSolidRopes( IMatRenderContext *pRenderContext, IMaterial *pMaterial, int nVertCount, int nIndexCount ); void RenderSolidRopes( IMatRenderContext *pRenderContext, IMaterial *pMaterial, int nVertCount, int nIndexCount, bool bRenderNonSolid ); +#endif private: struct RopeRenderData_t { IMaterial *m_pSolidMaterial; +#ifndef MAPBASE IMaterial *m_pBackMaterial; +#endif int m_nCacheCount; C_RopeKeyframe *m_aCache[MAX_ROPE_RENDERCACHE]; }; +#ifndef MAPBASE CUtlVector m_aRenderCache; int m_nSegmentCacheCount; CUtlVector m_aSegmentCache; @@ -275,20 +326,37 @@ class CRopeManager : public IRopeManager CQueuedRopeMemoryManager m_QueuedModeMemory; IMaterial* m_pDepthWriteMaterial; +#endif struct RopeQueuedRenderCache_t { RopeRenderData_t *pCaches; int iCacheCount; +#ifdef MAPBASE + CThreadFastMutex *m_pRopeDataMutex; +#endif RopeQueuedRenderCache_t( void ) : pCaches(NULL), iCacheCount(0) { }; }; +#ifdef MAPBASE + void DrawRenderCache_NonQueued( bool bShadowDepth, RopeRenderData_t *pRenderCache, int nRenderCacheCount, const Vector &vCurrentViewForward, const Vector &vCurrentViewOrigin, C_RopeKeyframe::BuildRopeQueuedData_t *pBuildRopeQueuedData, CThreadFastMutex *pRopeDataMutex ); +#else CUtlLinkedList m_RopeQueuedRenderCaches; +#endif bool m_bDrawHolidayLights; bool m_bHolidayInitialized; int m_nHolidayLightsStyle; + +#ifdef MAPBASE + CUtlVector m_aRenderCache; + + //in queued material system mode we need to store off data for later use. + IMaterial* m_pDepthWriteMaterial; + CUtlLinkedList m_RopeQueuedRenderCaches; + CThreadFastMutex m_RopeQueuedRenderCaches_Mutex; //mutex just for changing m_RopeQueuedRenderCaches +#endif }; static CRopeManager s_RopeManager; @@ -298,11 +366,12 @@ IRopeManager *RopeManager() return &s_RopeManager; } - +#ifndef MAPBASE inline bool ShouldUseFakeAA( IMaterial *pBackMaterial ) { return pBackMaterial && rope_smooth.GetInt() && engine->GetDXSupportLevel() > 70 && !g_pMaterialSystemHardwareConfig->IsAAEnabled(); } +#endif //----------------------------------------------------------------------------- @@ -311,8 +380,10 @@ inline bool ShouldUseFakeAA( IMaterial *pBackMaterial ) CRopeManager::CRopeManager() { m_aRenderCache.Purge(); +#ifndef MAPBASE m_aSegmentCache.Purge(); m_nSegmentCacheCount = 0; +#endif m_pDepthWriteMaterial = NULL; m_bDrawHolidayLights = false; m_bHolidayInitialized = false; @@ -324,6 +395,9 @@ CRopeManager::CRopeManager() //----------------------------------------------------------------------------- CRopeManager::~CRopeManager() { +#ifdef MAPBASE + m_aRenderCache.Purge(); +#else int nRenderCacheCount = m_aRenderCache.Count(); for ( int iRenderCache = 0; iRenderCache < nRenderCacheCount; ++iRenderCache ) { @@ -339,6 +413,7 @@ CRopeManager::~CRopeManager() m_aRenderCache.Purge(); m_aSegmentCache.Purge(); +#endif } //----------------------------------------------------------------------------- @@ -368,8 +443,12 @@ void CRopeManager::AddToRenderCache( C_RopeKeyframe *pRope ) int nRenderCacheCount = m_aRenderCache.Count(); for ( ; iRenderCache < nRenderCacheCount; ++iRenderCache ) { +#ifdef MAPBASE + if ( pRope->GetSolidMaterial() == m_aRenderCache[iRenderCache].m_pSolidMaterial ) +#else if ( ( pRope->GetSolidMaterial() == m_aRenderCache[iRenderCache].m_pSolidMaterial ) && ( pRope->GetBackMaterial() == m_aRenderCache[iRenderCache].m_pBackMaterial ) ) +#endif break; } @@ -379,6 +458,7 @@ void CRopeManager::AddToRenderCache( C_RopeKeyframe *pRope ) { int iRenderCache = m_aRenderCache.AddToTail(); m_aRenderCache[iRenderCache].m_pSolidMaterial = pRope->GetSolidMaterial(); +#ifndef MAPBASE if ( m_aRenderCache[iRenderCache].m_pSolidMaterial ) { m_aRenderCache[iRenderCache].m_pSolidMaterial->IncrementReferenceCount(); @@ -388,6 +468,7 @@ void CRopeManager::AddToRenderCache( C_RopeKeyframe *pRope ) { m_aRenderCache[iRenderCache].m_pBackMaterial->IncrementReferenceCount(); } +#endif m_aRenderCache[iRenderCache].m_nCacheCount = 0; } @@ -401,6 +482,257 @@ void CRopeManager::AddToRenderCache( C_RopeKeyframe *pRope ) ++m_aRenderCache[iRenderCache].m_nCacheCount; } +#ifdef MAPBASE +#define OUTPUT_2SPLINE_VERTS( t, u ) \ + meshBuilder.Color4ub( nRed, nGreen, nBlue, nAlpha ); \ + meshBuilder.Position3f( (t), u, 0 ); \ + meshBuilder.TexCoord4fv( 0, vecP0.Base() ); \ + meshBuilder.TexCoord4fv( 1, vecP1.Base() ); \ + meshBuilder.TexCoord4fv( 2, vecP2.Base() ); \ + meshBuilder.TexCoord4fv( 3, vecP3.Base() ); \ + meshBuilder.AdvanceVertexF(); \ + meshBuilder.Color4ub( nRed, nGreen, nBlue, nAlpha ); \ + meshBuilder.Position3f( (t), u, 1 ); \ + meshBuilder.TexCoord4fv( 0, vecP0.Base() ); \ + meshBuilder.TexCoord4fv( 1, vecP1.Base() ); \ + meshBuilder.TexCoord4fv( 2, vecP2.Base() ); \ + meshBuilder.TexCoord4fv( 3, vecP3.Base() ); \ + meshBuilder.AdvanceVertexF(); + + +void CRopeManager::DrawRenderCache_NonQueued( bool bShadowDepth, RopeRenderData_t *pRenderCache, int nRenderCacheCount, const Vector &vCurrentViewForward, const Vector &vCurrentViewOrigin, C_RopeKeyframe::BuildRopeQueuedData_t *pBuildRopeQueuedData, CThreadFastMutex *pRopeDataMutex ) +{ + VPROF_BUDGET( "CRopeManager::DrawRenderCache", VPROF_BUDGETGROUP_ROPES ); + + CThreadFastMutex dummyMutex; + if( pRopeDataMutex == NULL ) + pRopeDataMutex = &dummyMutex; + + if ( bShadowDepth && !m_pDepthWriteMaterial && g_pMaterialSystem ) + { + KeyValues *pVMTKeyValues = new KeyValues( "DepthWrite" ); + pVMTKeyValues->SetInt( "$no_fullbright", 1 ); + pVMTKeyValues->SetInt( "$alphatest", 0 ); + pVMTKeyValues->SetInt( "$nocull", 1 ); + m_pDepthWriteMaterial = g_pMaterialSystem->FindProceduralMaterial( "__DepthWrite01", TEXTURE_GROUP_OTHER, pVMTKeyValues ); + } + CMatRenderContextPtr pRenderContext( materials ); + + // UNDONE: needs to use the queued data + { + AUTO_LOCK_FM( *pRopeDataMutex ); + int defaultSubdiv = rope_subdiv.GetInt(); + for ( int iRenderCache = 0; iRenderCache < nRenderCacheCount; ++iRenderCache ) + { + int nCacheCount = pRenderCache[iRenderCache].m_nCacheCount; + + int nTotalVerts = 0; + int nTotalIndices = 0; + for ( int iCache = 0; iCache < nCacheCount; ++iCache ) + { + C_RopeKeyframe *pRope = pRenderCache[iRenderCache].m_aCache[iCache]; + if ( pRope ) + { + int segs = pRope->m_RopePhysics.NumNodes()-1; + int nSubdivCount = (pRope->m_Subdiv != 255 ? pRope->m_Subdiv : defaultSubdiv) + 1; + nTotalVerts += ((2 * nSubdivCount) * segs) + 2; + nTotalIndices += (6 * nSubdivCount) * segs; + } + } + if ( nTotalVerts == 0 ) + continue; + + IMaterial *pMaterial = bShadowDepth ? g_pSplineCableShadowdepth : pRenderCache[iRenderCache].m_pSolidMaterial; + + // Need to make sure that all rope materials use the splinerope shader since there are a lot of assumptions about how the shader interfaces with this code. + AssertOnce( V_strstr( pMaterial->GetShaderName(), "Cable" ) != NULL ); // splinerope + + pRenderContext->Bind( pMaterial ); + + int nMaxVertices = pRenderContext->GetMaxVerticesToRender( pMaterial ); + int nMaxIndices = pRenderContext->GetMaxIndicesToRender(); + + IMesh* pMesh = pRenderContext->GetDynamicMesh( true ); + CMeshBuilder meshBuilder; + int meshVertCount = MIN(nTotalVerts, nMaxVertices); + int meshIndexCount = MIN(nTotalIndices, nMaxIndices); + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, meshVertCount, meshIndexCount ); + int nCurIDX = 0; + + int availableVerts = meshVertCount; + int availableIndices = meshIndexCount; + float flLastU = 1.0f; + + for ( int iCache = 0; iCache < nCacheCount; ++iCache ) + { + C_RopeKeyframe *pRope = pRenderCache[iRenderCache].m_aCache[iCache]; + if ( pRope ) + { + CSimplePhysics::CNode *pNode = pRope->m_RopePhysics.GetFirstNode(); + int nSegmentsToRender = pRope->m_RopePhysics.NumNodes()-1; + if ( !nSegmentsToRender ) + continue; + + int nParticles = pRope->m_RopePhysics.NumNodes(); + int nSubdivCount = (pRope->m_Subdiv != 255 ? pRope->m_Subdiv : defaultSubdiv) + 1; + + int nNumIndicesPerSegment = 6 * nSubdivCount; + int nNumVerticesPerSegment = 2 * nSubdivCount; + + int nSegmentsAvailableInBuffer = MIN( ( availableVerts - 2 ) / nNumVerticesPerSegment, + ( availableIndices ) / nNumIndicesPerSegment ); + + int segmentsInBuffer = MIN(nSegmentsAvailableInBuffer,nSegmentsToRender); + availableIndices -= nNumIndicesPerSegment * segmentsInBuffer; + availableVerts -= 2 + (nNumVerticesPerSegment * segmentsInBuffer); + + float width = pRope->m_Width; + Vector vModColor = pRope->m_vColorMod; + Vector *pColors = pRope->m_LightValues; + + // Figure out texture scale. + float flPixelsPerInch = 4.0f / pRope->m_TextureScale; + // This is the total number of texels for the length of the whole rope. + float flTotalTexCoord = flPixelsPerInch * ( pRope->m_RopeLength + pRope->m_Slack + ROPESLACK_FUDGEFACTOR ); + int nTotalPoints = (nSegmentsToRender * (nSubdivCount-1)) + 1; + float flDU = ( flTotalTexCoord / nTotalPoints ) / ( float )pRope->m_TextureHeight; + float flU = pRope->m_flCurScroll; + float m_flTStep = 1.0f / float(nSubdivCount); + + bool bFirstPoint = true; + + // initialize first spline segment + Vector4D vecP1; + Vector4D vecP2; + vecP1.Init( pNode[0].m_vPredicted, pRope->m_Width ); + vecP2.Init( pNode[1].m_vPredicted, pRope->m_Width ); + Vector4D vecP0 = vecP1; + + uint8 nRed = 0; + uint8 nGreen = 0; + uint8 nBlue = 0; + uint8 nAlpha = 255; + + Vector4D vecDelta = vecP2; + vecDelta -= vecP1; + vecP0 -= vecDelta; + + Vector4D vecP3; + + if ( nParticles < 3 ) + { + vecP3 = vecP2; + vecP3 += vecDelta; + } + else + { + vecP3.Init( pNode[2].m_vPredicted, width ); + } + int nPnt = 3; + int nColor = 1; + Vector vColor0( pColors[0].x * vModColor.x, pColors[0].y * vModColor.y, pColors[0].z * vModColor.z ); + Vector vColor1( pColors[1].x * vModColor.x, pColors[1].y * vModColor.y, pColors[1].z * vModColor.z ); + + float flT = 0; + do + { + if ( ! nSegmentsAvailableInBuffer ) + { + meshBuilder.End(); + pMesh->Draw(); + nTotalVerts -= (meshVertCount - availableVerts); + nTotalIndices -= (meshIndexCount - availableIndices); + meshVertCount = MIN(nTotalVerts, nMaxVertices); + meshIndexCount = MIN(nTotalIndices, nMaxIndices); + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, meshVertCount, meshIndexCount ); + availableVerts = meshVertCount; + availableIndices = meshIndexCount; + // copy the last emitted points + OUTPUT_2SPLINE_VERTS( flT, flLastU ); + + nSegmentsAvailableInBuffer = MIN( ( availableVerts - 2 ) / nNumVerticesPerSegment, + availableIndices / nNumIndicesPerSegment ); + + nCurIDX = 0; + } + nSegmentsAvailableInBuffer--; + flT = 0.; + for( int nSlice = 0 ; nSlice < nSubdivCount; nSlice++ ) + { + float omt = 1.0f - flT; + nRed = FastFToC( (vColor0.x * omt) + (vColor1.x*flT) ); + nGreen = FastFToC( (vColor0.y * omt) + (vColor1.y*flT) ); + nBlue = FastFToC( (vColor0.z * omt) + (vColor1.z*flT) ); + OUTPUT_2SPLINE_VERTS( flT, flU ); + flT += m_flTStep; + flU += flDU; + if ( ! bFirstPoint ) + { + meshBuilder.FastIndex( nCurIDX ); + meshBuilder.FastIndex( nCurIDX+1 ); + meshBuilder.FastIndex( nCurIDX+2 ); + meshBuilder.FastIndex( nCurIDX+1 ); + meshBuilder.FastIndex( nCurIDX+3 ); + meshBuilder.FastIndex( nCurIDX+2 ); + nCurIDX += 2; + } + bFirstPoint = false; + } + // next segment + vColor0 = vColor1; + if ( nColor < nParticles-1 ) + { + nColor++; + vColor1.Init( pColors[nColor].x * vModColor.x, pColors[nColor].y * vModColor.y, pColors[nColor].z * vModColor.z ); + } + if ( nSegmentsToRender > 1 ) + { + vecP0 = vecP1; + vecP1 = vecP2; + vecP2 = vecP3; + + if ( nPnt < nParticles ) + { + vecP3.AsVector3D() = pNode[nPnt].m_vPredicted; + nPnt++; + } + else + { + // fake last point by extrapolating + vecP3 += vecP2; + vecP3 -= vecP1; + } + } + } while( --nSegmentsToRender ); + + // output last piece + OUTPUT_2SPLINE_VERTS( 1.0, flU ); + meshBuilder.FastIndex( nCurIDX ); + meshBuilder.FastIndex( nCurIDX+1 ); + meshBuilder.FastIndex( nCurIDX+2 ); + meshBuilder.FastIndex( nCurIDX+1 ); + meshBuilder.FastIndex( nCurIDX+3 ); + meshBuilder.FastIndex( nCurIDX+2 ); + nCurIDX += 4; + flLastU = flU; + } + } + + meshBuilder.End(); + pMesh->Draw(); + } + } + + m_RopeQueuedRenderCaches_Mutex.Lock(); + if( pBuildRopeQueuedData && (m_RopeQueuedRenderCaches.Count() != 0) ) + { + unsigned short iHeadIndex = m_RopeQueuedRenderCaches.Head(); + delete m_RopeQueuedRenderCaches[iHeadIndex].m_pRopeDataMutex; + m_RopeQueuedRenderCaches.Remove( iHeadIndex ); + } + m_RopeQueuedRenderCaches_Mutex.Unlock(); +} +#else void CRopeManager::DrawRenderCache_NonQueued( bool bShadowDepth, RopeRenderData_t *pRenderCache, int nRenderCacheCount, const Vector &vCurrentViewForward, const Vector &vCurrentViewOrigin, C_RopeKeyframe::BuildRopeQueuedData_t *pBuildRopeQueuedData ) { VPROF_BUDGET( "CRopeManager::DrawRenderCache", VPROF_BUDGETGROUP_ROPES ); @@ -519,6 +851,11 @@ void CRopeManager::DrawRenderCache_NonQueued( bool bShadowDepth, RopeRenderData_ m_RopeQueuedRenderCaches.Remove( m_RopeQueuedRenderCaches.Head() ); } } +#endif + +#ifdef MAPBASE +ConVar r_queued_ropes( "r_queued_ropes", "1" ); +#endif //----------------------------------------------------------------------------- // Purpose: @@ -530,15 +867,30 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) if( iRenderCacheCount == 0 ) return; +#ifdef MAPBASE + // Check to see if we want to render the ropes. + if( !r_drawropes.GetBool() ) + return; +#endif + Vector vForward = CurrentViewForward(); Vector vOrigin = CurrentViewOrigin(); +#ifdef MAPBASE + CMatRenderContextPtr pRenderContext(materials); +#endif ICallQueue *pCallQueue; +#ifdef MAPBASE + if( r_queued_ropes.GetBool() && (pCallQueue = pRenderContext->GetCallQueue()) != NULL ) +#else if( r_queued_ropes.GetBool() && (pCallQueue = materials->GetRenderContext()->GetCallQueue()) != NULL ) +#endif { //material queue available and desired CRopeManager::RopeRenderData_t *pRenderCache = m_aRenderCache.Base(); +#ifndef MAPBASE AUTO_LOCK( m_RenderCacheMutex ); +#endif int iRopeCount = 0; int iNodeCount = 0; @@ -564,7 +916,12 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) (iRopeCount * sizeof(C_RopeKeyframe::BuildRopeQueuedData_t)) + (iNodeCount * (sizeof(Vector) * 2)); +#ifdef MAPBASE + CMatRenderData< byte > rd(pRenderContext, iMemoryNeeded); + void *pMemory = rd.Base(); +#else void *pMemory = m_QueuedModeMemory.Alloc( iMemoryNeeded ); +#endif CRopeManager::RopeRenderData_t *pRenderCachesStart = (CRopeManager::RopeRenderData_t *)pMemory; C_RopeKeyframe::BuildRopeQueuedData_t *pBuildRopeQueuedDataStart = (C_RopeKeyframe::BuildRopeQueuedData_t *)(pRenderCachesStart + iRenderCacheCount); @@ -575,7 +932,11 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) RopeQueuedRenderCache_t cache; cache.pCaches = pRenderCachesStart; cache.iCacheCount = iRenderCacheCount; +#ifdef MAPBASE + cache.m_pRopeDataMutex = new CThreadFastMutex; +#else m_RopeQueuedRenderCaches.AddToTail( cache ); +#endif C_RopeKeyframe::BuildRopeQueuedData_t *pWriteRopeQueuedData = pBuildRopeQueuedDataStart; Vector *pVectorWrite = (Vector *)pVectorDataStart; @@ -588,7 +949,9 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) int iCacheCount = pReadCache->m_nCacheCount; pWriteCache->m_nCacheCount = 0; pWriteCache->m_pSolidMaterial = pReadCache->m_pSolidMaterial; +#ifndef MAPBASE pWriteCache->m_pBackMaterial = pReadCache->m_pBackMaterial; +#endif for( int j = 0; j != iCacheCount; ++j ) { C_RopeKeyframe *pRope = pReadCache->m_aCache[j]; @@ -619,6 +982,21 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) pVectorWrite += iNodes; //so we don't overwrite the light values with the next rope's predicted positions } } +#ifdef MAPBASE + m_RopeQueuedRenderCaches_Mutex.Lock(); + unsigned short iLLIndex = m_RopeQueuedRenderCaches.AddToTail( cache ); + CThreadFastMutex *pRopeDataMutex = m_RopeQueuedRenderCaches[iLLIndex].m_pRopeDataMutex; + m_RopeQueuedRenderCaches_Mutex.Unlock(); + + Assert( ((void *)pVectorWrite == (void *)(((uint8 *)pMemory) + iMemoryNeeded)) && ((void *)pWriteRopeQueuedData == (void *)pVectorDataStart)); + pCallQueue->QueueCall( this, &CRopeManager::DrawRenderCache_NonQueued, bShadowDepth, pRenderCachesStart, iRenderCacheCount, vForward, vOrigin, pBuildRopeQueuedDataStart, pRopeDataMutex ); + + if ( IsHolidayLightMode() ) + { + // With holiday lights we need to also build the ropes non-queued without rendering them + DrawRenderCache_NonQueued( bShadowDepth, m_aRenderCache.Base(), iRenderCacheCount, vForward, vOrigin, NULL, NULL ); + } +#else Assert( ((void *)pVectorWrite == (void *)(((uint8 *)pMemory) + iMemoryNeeded)) && ((void *)pWriteRopeQueuedData == (void *)pVectorDataStart)); pCallQueue->QueueCall( this, &CRopeManager::DrawRenderCache_NonQueued, bShadowDepth, pRenderCachesStart, iRenderCacheCount, vForward, vOrigin, pBuildRopeQueuedDataStart ); @@ -627,10 +1005,15 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) // With holiday lights we need to also build the ropes non-queued without rendering them DrawRenderCache_NonQueued( bShadowDepth, m_aRenderCache.Base(), iRenderCacheCount, vForward, vOrigin, NULL ); } +#endif } else { +#ifdef MAPBASE + DrawRenderCache_NonQueued( bShadowDepth, m_aRenderCache.Base(), iRenderCacheCount, vForward, vOrigin, NULL, NULL ); +#else DrawRenderCache_NonQueued( bShadowDepth, m_aRenderCache.Base(), iRenderCacheCount, vForward, vOrigin, NULL ); +#endif } } @@ -641,15 +1024,6 @@ bool CRopeManager::IsHolidayLightMode( void ) return false; } -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsPowerupMode() ) - { - // We don't want to draw the lights for the grapple. - // They get left behind for a while and look bad. - return false; - } -#endif - bool bDrawHolidayLights = false; #ifdef USES_ECON_ITEMS @@ -681,6 +1055,7 @@ int CRopeManager::GetHolidayLightStyle( void ) return m_nHolidayLightsStyle; } +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -804,13 +1179,18 @@ RopeSegData_t *CRopeManager::GetNextSegmentFromCache( void ) ++m_nSegmentCacheCount; return &m_aSegmentCache[m_nSegmentCacheCount-1]; } +#endif void CRopeManager::RemoveRopeFromQueuedRenderCaches( C_RopeKeyframe *pRope ) { //remove this rope from queued render caches +#ifdef MAPBASE + AUTO_LOCK_FM( m_RopeQueuedRenderCaches_Mutex ); +#else AUTO_LOCK( m_RenderCacheMutex ); +#endif int index = m_RopeQueuedRenderCaches.Head(); while( m_RopeQueuedRenderCaches.IsValidIndex( index ) ) { @@ -822,7 +1202,13 @@ void CRopeManager::RemoveRopeFromQueuedRenderCaches( C_RopeKeyframe *pRope ) { if( pCache->m_aCache[j] == pRope ) { +#ifdef MAPBASE + RenderCacheData.m_pRopeDataMutex->Lock(); pCache->m_aCache[j] = NULL; + RenderCacheData.m_pRopeDataMutex->Unlock(); +#else + pCache->m_aCache[j] = NULL; +#endif } } } @@ -839,9 +1225,11 @@ void CRopeManager::RemoveRopeFromQueuedRenderCaches( C_RopeKeyframe *pRope ) void Rope_ResetCounters() { +#ifndef MAPBASE g_RopeCollideTicks.Init(); g_RopeDrawTicks.Init(); g_RopeSimulateTicks.Init(); +#endif g_nRopePointsSimulated = 0; } @@ -885,8 +1273,12 @@ void C_RopeKeyframe::CPhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNo if( !m_pKeyframe->m_LinksTouchingSomething[iNode] && m_pKeyframe->m_bApplyWind) { +#ifdef MAPBASE + Vector vecWindVel = GetWindspeedAtLocation( m_pKeyframe->m_RopePhysics.GetNode( iNode )->m_vPos ); +#else Vector vecWindVel; GetWindspeedAtTime(gpGlobals->curtime, vecWindVel); +#endif if ( vecWindVel.LengthSqr() > 0 ) { Vector vecWindAccel; @@ -894,7 +1286,11 @@ void C_RopeKeyframe::CPhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNo } else { +#ifdef MAPBASE + if ( ( m_pKeyframe->m_flCurrentGustLifetime != 0.0f ) && ( m_pKeyframe->m_flCurrentGustTimer < m_pKeyframe->m_flCurrentGustLifetime ) ) +#else if (m_pKeyframe->m_flCurrentGustTimer < m_pKeyframe->m_flCurrentGustLifetime ) +#endif { float div = m_pKeyframe->m_flCurrentGustTimer / m_pKeyframe->m_flCurrentGustLifetime; float scale = 1 - cos( div * M_PI ); @@ -912,8 +1308,17 @@ void C_RopeKeyframe::CPhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNo } // Apply any instananeous forces and reset +#ifdef MAPBASE + *pAccel += ROPE_IMPULSE_SCALE * m_pKeyframe->m_vecImpulse; + m_pKeyframe->m_vecImpulse *= ROPE_IMPULSE_DECAY; + if ( m_pKeyframe->m_vecImpulse.LengthSqr() < 0.1f ) + { + m_pKeyframe->m_vecImpulse = vec3_origin; + } +#else *pAccel += ROPE_IMPULSE_SCALE * m_pKeyframe->m_flImpulse; m_pKeyframe->m_flImpulse *= ROPE_IMPULSE_DECAY; +#endif } @@ -950,21 +1355,31 @@ void C_RopeKeyframe::CPhysicsDelegate::ApplyConstraints( CSimplePhysics::CNode * { VPROF( "CPhysicsDelegate::ApplyConstraints" ); +#ifndef MAPBASE CTraceFilterWorldOnly traceFilter; +#endif // Collide with the world. if( ((m_pKeyframe->m_RopeFlags & ROPE_COLLIDE) && rope_collide.GetInt()) || (rope_collide.GetInt() == 2) ) { +#ifdef MAPBASE + CTraceFilterWorldOnly traceFilter; +#else CTimeAdder adder( &g_RopeCollideTicks ); +#endif for( int i=0; i < nNodes; i++ ) { CSimplePhysics::CNode *pNode = &pNodes[i]; int iIteration; +#ifdef MAPBASE + const int nIterations = 10; +#else int nIterations = 10; +#endif for( iIteration=0; iIteration < nIterations; iIteration++ ) { trace_t trace; @@ -982,7 +1397,11 @@ void C_RopeKeyframe::CPhysicsDelegate::ApplyConstraints( CSimplePhysics::CNode * } // Apply some friction. +#ifdef MAPBASE + const float flSlowFactor = 0.3f; +#else static float flSlowFactor = 0.3f; +#endif pNode->m_vPos -= (pNode->m_vPos - pNode->m_vPrevPos) * flSlowFactor; // Move it out along the face normal. @@ -1046,6 +1465,10 @@ C_RopeKeyframe::C_RopeKeyframe() m_vColorMod.Init( 1, 1, 1 ); m_nLinksTouchingSomething = 0; m_Subdiv = 255; // default to using the cvar +#ifdef MAPBASE + m_flCurrentGustLifetime = 0.0f; + m_flCurrentGustTimer = 0.0f; +#endif m_fLockedPoints = 0; m_fPrevLockedPoints = 0; @@ -1053,7 +1476,11 @@ C_RopeKeyframe::C_RopeKeyframe() m_iForcePointMoveCounter = 0; m_flCurScroll = m_flScrollSpeed = 0; m_TextureScale = 4; // 4:1 +#ifdef MAPBASE + m_vecImpulse.Init(); +#else m_flImpulse.Init(); +#endif g_Ropes.AddToTail( this ); } @@ -1064,11 +1491,13 @@ C_RopeKeyframe::~C_RopeKeyframe() s_RopeManager.RemoveRopeFromQueuedRenderCaches( this ); g_Ropes.FindAndRemove( this ); +#ifndef MAPBASE if ( m_pBackMaterial ) { m_pBackMaterial->DecrementReferenceCount(); m_pBackMaterial = NULL; } +#endif } @@ -1129,6 +1558,11 @@ C_RopeKeyframe* C_RopeKeyframe::CreateFromKeyValues( C_BaseAnimating *pEnt, KeyV pRope->m_RopeFlags |= ROPE_NO_GRAVITY; } +#ifdef MAPBASE + // Model ropes need wind to move + pRope->m_RopeFlags |= ROPE_USE_WIND; +#endif + pRope->m_RopeLength = pValues->GetInt( "Length" ); pRope->m_TextureScale = pValues->GetFloat( "TextureScale", pRope->m_TextureScale ); pRope->m_Slack = 0; @@ -1258,6 +1692,9 @@ void C_RopeKeyframe::RecomputeSprings() void C_RopeKeyframe::ShakeRope( const Vector &vCenter, float flRadius, float flMagnitude ) { // Sum up whatever it would apply to all of our points. +#ifdef MAPBASE + bool bWantsThink = false; +#endif for ( int i=0; i < m_nSegments; i++ ) { CSimplePhysics::CNode *pNode = m_RopePhysics.GetNode( i ); @@ -1267,9 +1704,21 @@ void C_RopeKeyframe::ShakeRope( const Vector &vCenter, float flRadius, float flM float flShakeAmount = 1.0f - flDist / flRadius; if ( flShakeAmount >= 0 ) { +#ifdef MAPBASE + m_vecImpulse.z += flShakeAmount * flMagnitude; + bWantsThink = true; +#else m_flImpulse.z += flShakeAmount * flMagnitude; +#endif } } + +#ifdef MAPBASE + if ( bWantsThink ) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +#endif } @@ -1278,6 +1727,9 @@ void C_RopeKeyframe::OnDataChanged( DataUpdateType_t updateType ) BaseClass::OnDataChanged( updateType ); m_bNewDataThisFrame = true; +#ifdef MAPBASE + SetNextClientThink( CLIENT_THINK_ALWAYS ); +#endif if( updateType != DATA_UPDATE_CREATED ) return; @@ -1296,7 +1748,11 @@ void C_RopeKeyframe::OnDataChanged( DataUpdateType_t updateType ) } else { +#ifdef MAPBASE + Q_strncpy( str, "missing_rope_material", sizeof( str ) ); +#else Q_strncpy( str, "asdf", sizeof( str ) ); +#endif } FinishInit( str ); @@ -1307,11 +1763,21 @@ void C_RopeKeyframe::FinishInit( const char *pMaterialName ) { // Get the material from the material system. m_pMaterial = materials->FindMaterial( pMaterialName, TEXTURE_GROUP_OTHER ); + +#ifdef MAPBASE + if ( !g_pSplineCableShadowdepth ) + { + g_pSplineCableShadowdepth = g_pMaterialSystem->FindMaterial( "cable/rope_shadowdepth", TEXTURE_GROUP_OTHER ); + g_pSplineCableShadowdepth->IncrementReferenceCount(); + } +#endif + if( m_pMaterial ) m_TextureHeight = m_pMaterial->GetMappingHeight(); else m_TextureHeight = 1; +#ifndef MAPBASE char backName[512]; Q_snprintf( backName, sizeof( backName ), "%s_back", pMaterialName ); @@ -1324,6 +1790,7 @@ void C_RopeKeyframe::FinishInit( const char *pMaterialName ) m_pBackMaterial->IncrementReferenceCount(); m_pBackMaterial->GetMappingWidth(); } +#endif // Init rope physics. m_nSegments = clamp( m_nSegments, 2, ROPE_MAX_SEGMENTS ); @@ -1402,10 +1869,24 @@ void C_RopeKeyframe::ClientThink() if( !InitRopePhysics() ) // init if not already return; +#ifdef MAPBASE + if( DetectRestingState( m_bApplyWind ) ) +#else if( !DetectRestingState( m_bApplyWind ) ) +#endif { +#ifdef MAPBASE + if ( ( m_RopeFlags & ROPE_USE_WIND ) == 0 ) + { + SetNextClientThink( CLIENT_THINK_NEVER ); + } + return; + } +#endif // Update the simulation. +#ifndef MAPBASE CTimeAdder adder( &g_RopeSimulateTicks ); +#endif RunRopeSimulation( gpGlobals->frametime ); @@ -1414,6 +1895,10 @@ void C_RopeKeyframe::ClientThink() m_bNewDataThisFrame = false; // Setup a new wind gust? +#ifdef MAPBASE + if ( m_bApplyWind ) + { +#endif m_flCurrentGustTimer += gpGlobals->frametime; m_flTimeToNextGust -= gpGlobals->frametime; if( m_flTimeToNextGust <= 0 ) @@ -1431,8 +1916,13 @@ void C_RopeKeyframe::ClientThink() m_flTimeToNextGust = RandomFloat( 3.0f, 4.0f ); } +#ifdef MAPBASE + } + UpdateBBox(); +#else UpdateBBox(); } +#endif } @@ -1553,18 +2043,62 @@ bool C_RopeKeyframe::GetAttachment( int number, Vector &origin, QAngle &angles ) return false; } +#ifdef MAPBASE +const Vector &C_RopeKeyframe::GetNodePosition( int index ) +{ + int nNodes = m_RopePhysics.NumNodes(); + if ( index >= nNodes || nNodes < 2 ) + { + Warning( "C_RopeKeyframe::GetNodePosition(): Invalid node index %i (number of nodes is %i)\n", index, nNodes ); + return vec3_origin; + } + + return m_RopePhysics.GetNode( index )->m_vPredicted; +} + +int C_RopeKeyframe::GetNumNodes() +{ + return m_RopePhysics.NumNodes(); +} +#endif + bool C_RopeKeyframe::AnyPointsMoved() { +#ifdef MAPBASE + int nNodeCount = m_RopePhysics.NumNodes(); + for( int i=0; i < nNodeCount; i++ ) +#else for( int i=0; i < m_RopePhysics.NumNodes(); i++ ) +#endif { CSimplePhysics::CNode *pNode = m_RopePhysics.GetNode( i ); +#ifdef MAPBASE + float flMoveDistSqr = pNode->m_vPos.DistToSqr( pNode->m_vPrevPos ); + if( flMoveDistSqr > 0.25f ) + { + if ( m_iForcePointMoveCounter < 5 ) + { + m_iForcePointMoveCounter = 5; + } + return true; + } +#else float flMoveDistSqr = (pNode->m_vPos - pNode->m_vPrevPos).LengthSqr(); if( flMoveDistSqr > 0.03f ) return true; +#endif } +#ifdef MAPBASE + if( m_iForcePointMoveCounter >= 0 ) + { + --m_iForcePointMoveCounter; + return true; + } +#else if( --m_iForcePointMoveCounter > 0 ) return true; +#endif return false; } @@ -1621,6 +2155,22 @@ bool C_RopeKeyframe::DetectRestingState( bool &bApplyWind ) Vector &vEnd1 = m_RopePhysics.GetFirstNode()->m_vPos; Vector &vEnd2 = m_RopePhysics.GetLastNode()->m_vPos; +#ifdef MAPBASE + if ( m_RopeFlags & ROPE_USE_WIND ) + { + // Don't apply wind if more than half of the nodes are touching something. + if( m_nLinksTouchingSomething < (m_RopePhysics.NumNodes() >> 1) ) + { + bApplyWind = CalcDistanceToLineSegment( MainViewOrigin(), vEnd1, vEnd2 ) < rope_wind_dist.GetFloat(); + } + } + + if ( m_vecPreviousImpulse != m_vecImpulse ) + { + m_vecPreviousImpulse = m_vecImpulse; + return false; + } +#else if ( !( m_RopeFlags & ROPE_NO_WIND ) ) { // Don't apply wind if more than half of the nodes are touching something. @@ -1634,6 +2184,7 @@ bool C_RopeKeyframe::DetectRestingState( bool &bApplyWind ) m_flPreviousImpulse = m_flImpulse; return false; } +#endif return !AnyPointsMoved() && !bApplyWind && !rope_shake.GetInt(); } @@ -1648,12 +2199,12 @@ struct catmull_t }; // bake out the terms of the catmull rom spline -void Catmull_Rom_Spline_Matrix( const Vector &vecP1, const Vector &vecP2, const Vector &vecP3, const Vector &vecP4, catmull_t &output ) +void Catmull_Rom_Spline_Matrix( const Vector &p1, const Vector &p2, const Vector &p3, const Vector &p4, catmull_t &output ) { - output.t3 = 0.5f * ( ( -1 * vecP1 ) + ( 3 * vecP2 ) + ( -3 * vecP3 ) + vecP4 ); // 0.5 t^3 * [ (-1*p1) + ( 3*p2) + (-3*p3) + p4 ] - output.t2 = 0.5f * ( ( 2 * vecP1 ) + ( -5 * vecP2 ) + ( 4 * vecP3 ) - vecP4 ); // 0.5 t^2 * [ ( 2*p1) + (-5*p2) + ( 4*p3) - p4 ] - output.t = 0.5f * ( ( -1 * vecP1 ) + vecP3 ); // 0.5 t * [ (-1*p1) + p3 ] - output.c = vecP2; // p2 + output.t3 = 0.5f * ((-1*p1) + (3*p2) + (-3*p3) + p4); // 0.5 t^3 * [ (-1*p1) + ( 3*p2) + (-3*p3) + p4 ] + output.t2 = 0.5f * ((2*p1) + (-5*p2) + (4*p3) - p4); // 0.5 t^2 * [ ( 2*p1) + (-5*p2) + ( 4*p3) - p4 ] + output.t = 0.5f * ((-1*p1) + p3); // 0.5 t * [ (-1*p1) + p3 ] + output.c = p2; // p2 } // evaluate one point on the spline, t is a vector of (t, t^2, t^3) @@ -1666,7 +2217,7 @@ inline void Catmull_Rom_Eval( const catmull_t &spline, const Vector &t, Vector & output = spline.c + (t.x * spline.t) + (t.y*spline.t2) + (t.z * spline.t3); } - +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1833,6 +2384,7 @@ void C_RopeKeyframe::BuildRope( RopeSegData_t *pSegmentData, const Vector &vCurr } } } +#endif void C_RopeKeyframe::UpdateBBox() { @@ -1920,7 +2472,11 @@ bool C_RopeKeyframe::CalculateEndPointAttachment( C_BaseEntity *pEnt, int iAttac if ( m_RopeFlags & ROPE_PLAYER_WPN_ATTACH ) { +#ifdef MAPBASE + C_BasePlayer *pPlayer = ToBasePlayer( pEnt ); +#else C_BasePlayer *pPlayer = dynamic_cast< C_BasePlayer* >( pEnt ); +#endif if ( pPlayer ) { C_BaseAnimating *pModel = pPlayer->GetRenderedWeaponModel(); @@ -1986,10 +2542,12 @@ IMaterial* C_RopeKeyframe::GetSolidMaterial( void ) return m_pMaterial; } +#ifndef MAPBASE IMaterial* C_RopeKeyframe::GetBackMaterial( void ) { return m_pBackMaterial; } +#endif bool C_RopeKeyframe::GetEndPointAttachment( int iPt, Vector &vPos, QAngle &angle ) { @@ -2008,7 +2566,7 @@ bool C_RopeKeyframe::GetEndPointAttachment( int iPt, Vector &vPos, QAngle &angle return true; } - +#ifndef MAPBASE // Look at the global cvar and recalculate rope subdivision data if necessary. Vector *C_RopeKeyframe::GetRopeSubdivVectors( int *nSubdivs ) { @@ -2032,6 +2590,7 @@ Vector *C_RopeKeyframe::GetRopeSubdivVectors( int *nSubdivs ) return g_RopeSubdivs[subdiv]; } } +#endif void C_RopeKeyframe::CalcLightValues() @@ -2080,7 +2639,13 @@ void C_RopeKeyframe::ReceiveMessage( int classID, bf_read &msg ) } // Read instantaneous fore data +#ifdef MAPBASE + m_vecImpulse.x = msg.ReadFloat(); + m_vecImpulse.y = msg.ReadFloat(); + m_vecImpulse.z = msg.ReadFloat(); +#else m_flImpulse.x = msg.ReadFloat(); m_flImpulse.y = msg.ReadFloat(); m_flImpulse.z = msg.ReadFloat(); +#endif } diff --git a/game/client/c_rope.h b/game/client/c_rope.h index f04372f9..204b412b 100644 --- a/game/client/c_rope.h +++ b/game/client/c_rope.h @@ -33,6 +33,9 @@ class C_RopeKeyframe : public C_BaseEntity DECLARE_CLASS( C_RopeKeyframe, C_BaseEntity ); DECLARE_CLIENTCLASS(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif private: @@ -107,7 +110,9 @@ class C_RopeKeyframe : public C_BaseEntity // Get the rope material data. IMaterial *GetSolidMaterial( void ); +#ifndef MAPBASE IMaterial *GetBackMaterial( void ); +#endif struct BuildRopeQueuedData_t { @@ -119,7 +124,11 @@ class C_RopeKeyframe : public C_BaseEntity float m_Slack; }; +#ifdef MAPBASE + void BuildRope( RopeSegData_t *pRopeSegment, const Vector &vCurrentViewForward, const Vector &vCurrentViewOrigin, BuildRopeQueuedData_t *pQueuedData ); +#else void BuildRope( RopeSegData_t *pRopeSegment, const Vector &vCurrentViewForward, const Vector &vCurrentViewOrigin, BuildRopeQueuedData_t *pQueuedData, bool bQueued ); +#endif // C_BaseEntity overrides. public: @@ -136,6 +145,11 @@ class C_RopeKeyframe : public C_BaseEntity virtual bool GetAttachment( int number, Vector &origin ); virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ); +#ifdef MAPBASE + const Vector &GetNodePosition( int index ); + int GetNumNodes(); +#endif + private: void FinishInit( const char *pMaterialName ); @@ -160,6 +174,11 @@ class C_RopeKeyframe : public C_BaseEntity void ReceiveMessage( int classID, bf_read &msg ); bool CalculateEndPointAttachment( C_BaseEntity *pEnt, int iAttachment, Vector &vPos, QAngle *pAngles ); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetStartEntity() { return ToHScript( GetStartEntity() ); } + HSCRIPT ScriptGetEndEntity() { return ToHScript( GetEndEntity() ); } +#endif + private: // Track which links touched something last frame. Used to prevent wind from gusting on them. @@ -196,19 +215,29 @@ class C_RopeKeyframe : public C_BaseEntity float m_TextureScale; // pixels per inch int m_fLockedPoints; // Which points are locked down. +#ifdef MAPBASE + int m_nChangeCount; +#endif float m_Width; CPhysicsDelegate m_PhysicsDelegate; IMaterial *m_pMaterial; +#ifndef MAPBASE IMaterial *m_pBackMaterial; // Optional translucent background material for the rope to help reduce aliasing. +#endif int m_TextureHeight; // Texture height, for texture scale calculations. // Instantaneous force +#ifdef MAPBASE + Vector m_vecImpulse; + Vector m_vecPreviousImpulse; +#else Vector m_flImpulse; Vector m_flPreviousImpulse; +#endif // Simulated wind gusts. float m_flCurrentGustTimer; @@ -250,7 +279,9 @@ abstract_class IRopeManager virtual void ResetRenderCache( void ) = 0; virtual void AddToRenderCache( C_RopeKeyframe *pRope ) = 0; virtual void DrawRenderCache( bool bShadowDepth ) = 0; +#ifndef MAPBASE virtual void OnRenderStart( void ) = 0; +#endif virtual void SetHolidayLightMode( bool bHoliday ) = 0; virtual bool IsHolidayLightMode( void ) = 0; virtual int GetHolidayLightStyle( void ) = 0; diff --git a/game/client/c_sceneentity.cpp b/game/client/c_sceneentity.cpp index abd211c0..f4c66cc7 100644 --- a/game/client/c_sceneentity.cpp +++ b/game/client/c_sceneentity.cpp @@ -214,12 +214,12 @@ void C_SceneEntity::SetupClientOnlyScene( const char *pszFilename, C_BaseFlex *p V_strcpy( szFilename, szSceneHWM ); } - Assert( szFilename[ 0 ] ); - if ( szFilename[ 0 ] ) + Assert( szFilename && szFilename[ 0 ] ); + if ( szFilename && szFilename[ 0 ] ) { LoadSceneFromFile( szFilename ); - - if ( !HushAsserts() ) + + if (!CommandLine()->FindParm("-hushasserts")) { Assert( m_pScene ); } @@ -257,7 +257,7 @@ void C_SceneEntity::SetupClientOnlyScene( const char *pszFilename, C_BaseFlex *p if ( m_hOwner.Get() ) { - if ( !HushAsserts() ) + if (!CommandLine()->FindParm("-hushasserts")) { Assert( m_pScene ); } @@ -335,8 +335,8 @@ void C_SceneEntity::PostDataUpdate( DataUpdateType_t updateType ) if ( updateType == DATA_UPDATE_CREATED ) { - Assert( szFilename[ 0 ] ); - if ( szFilename[ 0 ] ) + Assert( szFilename && szFilename[ 0 ] ); + if ( szFilename && szFilename[ 0 ] ) { LoadSceneFromFile( szFilename ); @@ -373,8 +373,6 @@ void C_SceneEntity::PostDataUpdate( DataUpdateType_t updateType ) SetNextClientThink( CLIENT_THINK_ALWAYS ); } - - m_bWasPlaying = !m_bIsPlayingBack; // force it to be "changed" } // Playback state changed... @@ -676,7 +674,7 @@ void C_SceneEntity::DispatchStartSpeak( CChoreoScene *scene, C_BaseFlex *actor, es.m_pSoundName = event->GetParameters(); EmitSound( filter, actor->entindex(), es ); - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); // Close captioning only on master token no matter what... if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER ) @@ -806,20 +804,72 @@ CChoreoStringPool g_ChoreoStringPool; CChoreoScene *C_SceneEntity::LoadScene( const char *filename ) { +#ifdef MAPBASE + char loadfile[MAX_PATH]; +#else char loadfile[ 512 ]; +#endif Q_strncpy( loadfile, filename, sizeof( loadfile ) ); Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) ); Q_FixSlashes( loadfile ); +#ifdef MAPBASE + // + // Raw scene file support + // + void *pBuffer = 0; + size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile ); + CChoreoScene *pScene = NULL; + if ( bufsize > 0 ) + { + // Definitely in scenes.image + pBuffer = malloc( bufsize ); + if ( !scenefilecache->GetSceneData( filename, (byte *)pBuffer, bufsize ) ) + { + free( pBuffer ); + return NULL; + } + + + if ( IsBufferBinaryVCD( (char*)pBuffer, bufsize ) ) + { + pScene = new CChoreoScene( this ); + CUtlBuffer buf( pBuffer, bufsize, CUtlBuffer::READ_ONLY ); + if ( !pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) ) + { + Warning( "Unable to restore scene '%s'\n", loadfile ); + delete pScene; + pScene = NULL; + } + } + } + else if (filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true )) + { + // Not in scenes.image, but it's a raw file + g_TokenProcessor.SetBuffer((char*)pBuffer); + pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf ); + } + else + { + // Abandon ship + return NULL; + } + + if(pScene) + { + pScene->SetPrintFunc( Scene_Printf ); + pScene->SetEventCallbackInterface( this ); + } +#else char *pBuffer = NULL; size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile ); if ( bufsize <= 0 ) return NULL; - pBuffer = new char[ bufsize ]; + pBuffer = malloc( bufsize ); if ( !scenefilecache->GetSceneData( filename, (byte *)pBuffer, bufsize ) ) { - delete[] pBuffer; + free( pBuffer ); return NULL; } @@ -845,8 +895,9 @@ CChoreoScene *C_SceneEntity::LoadScene( const char *filename ) g_TokenProcessor.SetBuffer( pBuffer ); pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf ); } +#endif - delete[] pBuffer; + free( pBuffer ); return pScene; } @@ -913,7 +964,7 @@ void C_SceneEntity::UnloadScene( void ) //----------------------------------------------------------------------------- void C_SceneEntity::DispatchStartFlexAnimation( CChoreoScene *scene, C_BaseFlex *actor, CChoreoEvent *event ) { - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -933,7 +984,7 @@ void C_SceneEntity::DispatchEndFlexAnimation( CChoreoScene *scene, C_BaseFlex *a //----------------------------------------------------------------------------- void C_SceneEntity::DispatchStartExpression( CChoreoScene *scene, C_BaseFlex *actor, CChoreoEvent *event ) { - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -957,7 +1008,7 @@ void C_SceneEntity::DispatchStartGesture( CChoreoScene *scene, C_BaseFlex *actor if ( !Q_stricmp( event->GetName(), "NULL" ) ) return; - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -972,7 +1023,7 @@ void C_SceneEntity::DispatchProcessGesture( CChoreoScene *scene, C_BaseFlex *act return; actor->RemoveSceneEvent( scene, event, false ); - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -995,7 +1046,7 @@ void C_SceneEntity::DispatchEndGesture( CChoreoScene *scene, C_BaseFlex *actor, //----------------------------------------------------------------------------- void C_SceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -1005,7 +1056,7 @@ void C_SceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor void C_SceneEntity::DispatchProcessSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { actor->RemoveSceneEvent( scene, event, false ); - actor->AddSceneEvent( scene, event, NULL, IsClientOnly() ); + actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this ); } //----------------------------------------------------------------------------- @@ -1108,7 +1159,7 @@ void C_SceneEntity::SetCurrentTime( float t, bool forceClientSync ) //----------------------------------------------------------------------------- void C_SceneEntity::PrefetchAnimBlocks( CChoreoScene *pScene ) { - if ( !HushAsserts() ) + if (!CommandLine()->FindParm("-hushasserts")) { Assert( pScene && m_bMultiplayer ); } @@ -1210,4 +1261,4 @@ void C_SceneEntity::PrefetchAnimBlocks( CChoreoScene *pScene ) return; Msg( "%d of %d animations resident\n", nResident, nChecked ); -} \ No newline at end of file +} diff --git a/game/client/c_shadowcontrol.cpp b/game/client/c_shadowcontrol.cpp index 80169241..c725a2ba 100644 --- a/game/client/c_shadowcontrol.cpp +++ b/game/client/c_shadowcontrol.cpp @@ -32,13 +32,24 @@ class C_ShadowControl : public C_BaseEntity color32 m_shadowColor; float m_flShadowMaxDist; bool m_bDisableShadows; +#ifdef MAPBASE + bool m_bEnableLocalLightShadows; +#endif }; IMPLEMENT_CLIENTCLASS_DT(C_ShadowControl, DT_ShadowControl, CShadowControl) RecvPropVector(RECVINFO(m_shadowDirection)), +#ifdef MAPBASE + /*RecvPropInt(RECVINFO(m_shadowColor), 0, RecvProxy_Int32ToColor32),*/ + RecvPropInt(RECVINFO(m_shadowColor), 0, RecvProxy_IntToColor32), +#else RecvPropInt(RECVINFO(m_shadowColor)), +#endif RecvPropFloat(RECVINFO(m_flShadowMaxDist)), RecvPropBool(RECVINFO(m_bDisableShadows)), +#ifdef MAPBASE + RecvPropBool(RECVINFO(m_bEnableLocalLightShadows)), +#endif END_RECV_TABLE() @@ -54,6 +65,9 @@ void C_ShadowControl::OnDataChanged(DataUpdateType_t updateType) g_pClientShadowMgr->SetShadowColor( m_shadowColor.r, m_shadowColor.g, m_shadowColor.b ); g_pClientShadowMgr->SetShadowDistance( m_flShadowMaxDist ); g_pClientShadowMgr->SetShadowsDisabled( m_bDisableShadows ); +#ifdef DYNAMIC_RTT_SHADOWS + g_pClientShadowMgr->SetShadowFromWorldLightsEnabled( m_bEnableLocalLightShadows ); +#endif } //------------------------------------------------------------------------------ diff --git a/game/client/c_slideshow_display.cpp b/game/client/c_slideshow_display.cpp index b721f4c3..90ee0a74 100644 --- a/game/client/c_slideshow_display.cpp +++ b/game/client/c_slideshow_display.cpp @@ -272,8 +272,8 @@ void C_SlideshowDisplay::BuildSlideShowImagesList( void ) if ( bLoaded ) { - char szKeywords[ 256 ] = {0}; - V_strcpy_safe( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) ); + char szKeywords[ 256 ]; + Q_strcpy( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) ); char *pchKeyword = szKeywords; @@ -306,7 +306,7 @@ void C_SlideshowDisplay::BuildSlideShowImagesList( void ) { // Couldn't find the list, so create it iList = m_SlideMaterialLists.AddToTail( new SlideMaterialList_t ); - V_strcpy_safe( m_SlideMaterialLists[iList]->szSlideKeyword, pchKeyword ); + Q_strcpy( m_SlideMaterialLists[ iList ]->szSlideKeyword, pchKeyword ); } // Add material index to this list @@ -329,7 +329,7 @@ void C_SlideshowDisplay::BuildSlideShowImagesList( void ) { // Couldn't find the generic list, so create it iList = m_SlideMaterialLists.AddToHead( new SlideMaterialList_t ); - V_strcpy_safe( m_SlideMaterialLists[iList]->szSlideKeyword, "" ); + Q_strcpy( m_SlideMaterialLists[ iList ]->szSlideKeyword, "" ); } // Add material index to this list diff --git a/game/client/c_soundscape.cpp b/game/client/c_soundscape.cpp index a9baa479..93a8aa2b 100644 --- a/game/client/c_soundscape.cpp +++ b/game/client/c_soundscape.cpp @@ -150,7 +150,7 @@ class C_SoundscapeSystem : public CBaseGameSystemPerFrame { Msg( "- %d: %s\n", i, m_soundscapes[i]->GetName() ); } - if ( m_forcedSoundscapeIndex >= 0 ) + if ( m_forcedSoundscapeIndex ) { Msg( "- PLAYING DEBUG SOUNDSCAPE: %d [%s]\n", m_forcedSoundscapeIndex, SoundscapeNameByIndex(m_forcedSoundscapeIndex) ); } @@ -207,6 +207,9 @@ class C_SoundscapeSystem : public CBaseGameSystemPerFrame // "dsp_volume" void ProcessDSPVolume( KeyValues *pKey, subsoundscapeparams_t ¶ms ); +#ifdef MAPBASE // Moved to public space + void AddSoundScapeFile( const char *filename ); +#endif private: @@ -215,7 +218,9 @@ class C_SoundscapeSystem : public CBaseGameSystemPerFrame return gpGlobals->framecount == m_nRestoreFrame ? true : false; } +#ifndef MAPBASE // Moved to public space void AddSoundScapeFile( const char *filename ); +#endif void TouchPlayLooping( KeyValues *pAmbient ); void TouchPlayRandom( KeyValues *pPlayRandom ); @@ -265,6 +270,13 @@ void Soundscape_Update( audioparams_t &audio ) g_SoundscapeSystem.UpdateAudioParams( audio ); } +#ifdef MAPBASE +void Soundscape_AddFile( const char *szFile ) +{ + g_SoundscapeSystem.AddSoundScapeFile(szFile); +} +#endif + #define SOUNDSCAPE_MANIFEST_FILE "scripts/soundscapes_manifest.txt" void C_SoundscapeSystem::AddSoundScapeFile( const char *filename ) @@ -310,6 +322,16 @@ bool C_SoundscapeSystem::Init() mapSoundscapeFilename = VarArgs( "scripts/soundscapes_%s.txt", mapname ); } +#ifdef MAPBASE + if (filesystem->FileExists(VarArgs("maps/%s_soundscapes.txt", mapname))) + { + // A Mapbase-specific file exists. Load that instead. + // Any additional soundscape files, like the original scripts/soundscapes version, + // could be loaded through #include and/or #base. + mapSoundscapeFilename = VarArgs("maps/%s_soundscapes.txt", mapname); + } +#endif + KeyValues *manifest = new KeyValues( SOUNDSCAPE_MANIFEST_FILE ); if ( filesystem->LoadKeyValues( *manifest, IFileSystem::TYPE_SOUNDSCAPE, SOUNDSCAPE_MANIFEST_FILE, "GAME" ) ) { diff --git a/game/client/c_soundscape.h b/game/client/c_soundscape.h index 8c5f45e9..b42d4b42 100644 --- a/game/client/c_soundscape.h +++ b/game/client/c_soundscape.h @@ -24,4 +24,8 @@ extern void Soundscape_Update( audioparams_t &audio ); // sounds are still playing when they're not. void Soundscape_OnStopAllSounds(); +#ifdef MAPBASE +void Soundscape_AddFile( const char *szFile ); +#endif + #endif // C_SOUNDSCAPE_H diff --git a/game/client/c_te_effect_dispatch.cpp b/game/client/c_te_effect_dispatch.cpp index 160e11b7..e0688a2d 100644 --- a/game/client/c_te_effect_dispatch.cpp +++ b/game/client/c_te_effect_dispatch.cpp @@ -179,6 +179,10 @@ void DispatchEffect( const char *pName, const CEffectData &data ) te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); } +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ) +{ + te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); +} //----------------------------------------------------------------------------- // Playback diff --git a/game/client/c_te_effect_dispatch.h b/game/client/c_te_effect_dispatch.h index 63fa6173..8abaaeab 100644 --- a/game/client/c_te_effect_dispatch.h +++ b/game/client/c_te_effect_dispatch.h @@ -42,5 +42,6 @@ class CClientEffectRegistration void DispatchEffectToCallback( const char *pEffectName, const CEffectData &m_EffectData ); void DispatchEffect( const char *pName, const CEffectData &data ); +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ); #endif // C_TE_EFFECT_DISPATCH_H diff --git a/game/client/c_te_largefunnel.cpp b/game/client/c_te_largefunnel.cpp index 25430db0..f8db20c4 100644 --- a/game/client/c_te_largefunnel.cpp +++ b/game/client/c_te_largefunnel.cpp @@ -64,7 +64,12 @@ void C_TELargeFunnel::CreateFunnel( void ) float ratio = 0.25; float invratio = 1 / ratio; +#ifdef MAPBASE + // Uh...figure out how to fix this PMaterialHandle hMaterial = pSimple->GetPMaterial( "sprites/flare6" ); +#else + PMaterialHandle hMaterial = pSimple->GetPMaterial( "sprites/flare6" ); +#endif for ( i = -256 ; i <= 256 ; i += 24 ) //24 from 32.. little more dense { diff --git a/game/client/c_te_legacytempents.cpp b/game/client/c_te_legacytempents.cpp index 14f6d0e8..8c7a8551 100644 --- a/game/client/c_te_legacytempents.cpp +++ b/game/client/c_te_legacytempents.cpp @@ -597,8 +597,12 @@ bool C_LocalTempEntity::Frame( float frametime, int framenumber ) if ( flags & FTENT_WINDBLOWN ) { +#ifdef MAPBASE + Vector vecWind = GetWindspeedAtLocation( GetAbsOrigin() ); +#else Vector vecWind; GetWindspeedAtTime( gpGlobals->curtime, vecWind ); +#endif for ( int i = 0 ; i < 2 ; i++ ) { @@ -1539,7 +1543,7 @@ void CTempEnts::BloodSprite( const Vector &org, int r, int g, int b, int a, int { C_LocalTempEntity *pTemp; int frameCount = modelinfo->GetModelFrameCount( model ); - color32 impactcolor = { (byte)r, (byte)g, (byte)b, (byte)a }; + color32 impactcolor = { r, g, b, a }; //Large, single blood sprite is a high-priority tent if ( ( pTemp = TempEntAllocHigh( org, model ) ) != NULL ) @@ -1829,6 +1833,9 @@ void CTempEnts::MuzzleFlash( const Vector& pos1, const QAngle& angles, int type, // UNDONE: These need their own effects/sprites. For now use the pistol // SMG1 +#if defined ( HL2MP ) // HACK for hl2mp, make the default muzzleflash the smg muzzleflash for weapons like the RPG that are using 'type 0' + default: +#endif // HL2MP case MUZZLEFLASH_SMG1: if ( firstPerson ) { @@ -1866,10 +1873,12 @@ void CTempEnts::MuzzleFlash( const Vector& pos1, const QAngle& angles, int type, } break; +#if !defined ( HL2MP ) // HACK for hl2mp, make the default muzzleflash the smg muzzleflash for weapons like the RPG that are using 'type 0' default: // There's no supported muzzle flash for the type specified! Assert(0); break; +#endif // HL2MP } #endif diff --git a/game/client/c_team_objectiveresource.h b/game/client/c_team_objectiveresource.h index 9cc431e2..b7139802 100644 --- a/game/client/c_team_objectiveresource.h +++ b/game/client/c_team_objectiveresource.h @@ -104,7 +104,7 @@ class C_BaseTeamObjectiveResource : public C_BaseEntity Assert( iCapper != TEAM_UNASSIGNED ); - return GetIconForTeam( index, iCapper ); + return GetIconForTeam( index, iCapper );; } // Icon for the specified team diff --git a/game/client/c_team_train_watcher.cpp b/game/client/c_team_train_watcher.cpp index e58aafb1..da3fa880 100644 --- a/game/client/c_team_train_watcher.cpp +++ b/game/client/c_team_train_watcher.cpp @@ -163,13 +163,18 @@ void C_TeamTrainWatcher::OnDataChanged( DataUpdateType_t updateType ) int nNumHills = ObjectiveResource()->GetNumNodeHillData( GetTeamNumber() ); if ( nNumHills > 0 ) { - float flStart = 0, flEnd = 0; + float flStart, flEnd; for ( int i = 0 ; i < nNumHills ; i++ ) { ObjectiveResource()->GetHillData( GetTeamNumber(), i, flStart, flEnd ); - - bool state = ( m_flTotalProgress >= flStart && m_flTotalProgress <= flEnd ); - ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, state ); + if ( m_flTotalProgress >= flStart && m_flTotalProgress<= flEnd ) + { + ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, true ); + } + else + { + ObjectiveResource()->SetTrainOnHill( GetTeamNumber(), i, false ); + } } } } diff --git a/game/client/c_vehicle_choreo_generic.cpp b/game/client/c_vehicle_choreo_generic.cpp index 52eba09e..82abc224 100644 --- a/game/client/c_vehicle_choreo_generic.cpp +++ b/game/client/c_vehicle_choreo_generic.cpp @@ -54,7 +54,12 @@ class C_PropVehicleChoreoGeneric : public C_DynamicProp, public IClientVehicle flFOV = m_flFOV; } virtual void DrawHudElements(); +#ifdef MAPBASE + virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return m_bAllowStandardWeapons; } + bool m_bAllowStandardWeapons; +#else virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; } +#endif virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ); virtual C_BaseCombatCharacter *GetPassenger( int nRole ); virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger ); @@ -107,6 +112,9 @@ IMPLEMENT_CLIENTCLASS_DT(C_PropVehicleChoreoGeneric, DT_PropVehicleChoreoGeneric RecvPropFloat( RECVINFO( m_vehicleView.flYawMax ) ), RecvPropFloat( RECVINFO( m_vehicleView.flPitchMin ) ), RecvPropFloat( RECVINFO( m_vehicleView.flPitchMax ) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bAllowStandardWeapons ) ), +#endif END_RECV_TABLE() diff --git a/game/client/c_vguiscreen.h b/game/client/c_vguiscreen.h index d304f5c9..71780093 100644 --- a/game/client/c_vguiscreen.h +++ b/game/client/c_vguiscreen.h @@ -112,6 +112,15 @@ class C_VGuiScreen : public C_BaseEntity C_BasePlayer *GetPlayerOwner( void ); bool IsInputOnlyToOwner( void ); +#ifdef MAPBASE + void GetSize( float &width, float &height ) const { width = m_flWidth; height = m_flHeight; } + void GetPixelSize( int &width, int &height ) const { width = m_nPixelWidth; height = m_nPixelHeight; } + void SetWidth( float flWidth ) { m_flWidth = flWidth; } + void SetHeight( float flHeight ) { m_flHeight = flHeight; } + void SetPixelWidth( int nWidth ) { m_nPixelWidth = nWidth; } + void SetPixelHeight( int nHeight ) { m_nPixelHeight = nHeight; } +#endif + private: // Vgui screen management void CreateVguiScreen( const char *pTypeName ); diff --git a/game/client/c_vote_controller.cpp b/game/client/c_vote_controller.cpp index e99372da..c900c27e 100644 --- a/game/client/c_vote_controller.cpp +++ b/game/client/c_vote_controller.cpp @@ -81,7 +81,7 @@ C_VoteController::~C_VoteController() void C_VoteController::ResetData() { m_iActiveIssueIndex = INVALID_ISSUE; - m_iOnlyTeamToVote = TEAM_UNASSIGNED; + m_iOnlyTeamToVote = TEAM_INVALID; for( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) { m_nVoteOptionCount[index] = 0; @@ -118,11 +118,9 @@ void C_VoteController::ClientThink() { if ( m_nPotentialVotes > 0 ) { -#ifdef STAGING_ONLY // Currently hard-coded to MAX_VOTE_COUNT options per issue DevMsg( "Votes: Option1 - %d, Option2 - %d, Option3 - %d, Option4 - %d, Option5 - %d\n", m_nVoteOptionCount[0], m_nVoteOptionCount[1], m_nVoteOptionCount[2], m_nVoteOptionCount[3], m_nVoteOptionCount[4] ); -#endif // STAGING_ONLY IGameEvent *event = gameeventmanager->CreateEvent( "vote_changed" ); if ( event ) diff --git a/game/client/c_world.cpp b/game/client/c_world.cpp index 3ae6bdcc..938db241 100644 --- a/game/client/c_world.cpp +++ b/game/client/c_world.cpp @@ -13,6 +13,9 @@ #include "ivieweffects.h" #include "shake.h" #include "eventlist.h" +#ifdef MAPBASE +#include "mapentities_shared.h" +#endif // NVNT haptic include for notification of world precache #include "haptics/haptic_utils.h" // memdbgon must be the last include file in a .cpp file!!! @@ -59,8 +62,15 @@ BEGIN_RECV_TABLE( C_World, DT_World ) RecvPropFloat(RECVINFO(m_flMinPropScreenSpaceWidth)), RecvPropString(RECVINFO(m_iszDetailSpriteMaterial)), RecvPropInt(RECVINFO(m_bColdWorld)), +#ifdef MAPBASE + RecvPropString(RECVINFO(m_iszChapterTitle)), +#endif END_RECV_TABLE() +#ifdef MAPBASE_VSCRIPT +extern bool VScriptClientInit(); +#endif + C_World::C_World( void ) { @@ -76,6 +86,11 @@ bool C_World::Init( int entnum, int iSerialNum ) ActivityList_Init(); EventList_Init(); +#ifdef MAPBASE_VSCRIPT + m_iScriptLanguageServer = SL_NONE; + m_iScriptLanguageClient = SL_NONE; +#endif + return BaseClass::Init( entnum, iSerialNum ); } @@ -184,6 +199,72 @@ void C_World::Spawn( void ) Precache(); } +//----------------------------------------------------------------------------- +// Parse data from a map file +//----------------------------------------------------------------------------- +bool C_World::KeyValue( const char *szKeyName, const char *szValue ) +{ +#ifdef MAPBASE_VSCRIPT + if ( FStrEq( szKeyName, "vscriptlanguage" ) ) + { + m_iScriptLanguageServer = atoi( szValue ); + } + else if ( FStrEq( szKeyName, "vscriptlanguage_client" ) ) + { + m_iScriptLanguageClient = atoi( szValue ); + } + else +#endif + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Parses worldspawn data from BSP on the client +//----------------------------------------------------------------------------- +void C_World::ParseWorldMapData( const char *pMapData ) +{ + char szTokenBuffer[MAPKEY_MAXLENGTH]; + for ( ; true; pMapData = MapEntity_SkipToNextEntity(pMapData, szTokenBuffer) ) + { + // + // Parse the opening brace. + // + char token[MAPKEY_MAXLENGTH]; + pMapData = MapEntity_ParseToken( pMapData, token ); + + // + // Check to see if we've finished or not. + // + if (!pMapData) + break; + + if (token[0] != '{') + { + Error( "MapEntity_ParseAllEntities: found %s when expecting {", token); + continue; + } + + CEntityMapData entData( (char*)pMapData ); + char className[MAPKEY_MAXLENGTH]; + + if (!entData.ExtractValue( "classname", className )) + { + Error( "classname missing from entity!\n" ); + } + + if ( !Q_strcmp( className, "worldspawn" ) ) + { + // Set up keyvalues. + ParseMapData( &entData ); + return; + } + } +} +#endif + C_World *GetClientWorldEntity() diff --git a/game/client/c_world.h b/game/client/c_world.h index 3cdbd6a0..12366490 100644 --- a/game/client/c_world.h +++ b/game/client/c_world.h @@ -31,6 +31,7 @@ class C_World : public C_BaseEntity virtual void Precache(); virtual void Spawn(); + virtual bool KeyValue( const char *szKeyName, const char *szValue ); // Don't worry about adding the world to the collision list; it's already there virtual CollideType_t GetCollideType( void ) { return ENTITY_SHOULD_NOT_COLLIDE; } @@ -41,6 +42,19 @@ class C_World : public C_BaseEntity float GetWaveHeight() const; const char *GetDetailSpriteMaterial() const; +#ifdef MAPBASE + // A special function which parses map data for the client world entity before LevelInitPreEntity(). + // This can be used to access keyvalues early and without transmitting from the server. + void ParseWorldMapData( const char *pMapData ); +#endif + +#ifdef MAPBASE_VSCRIPT + void ClientThink() { ScriptContextThink(); } + + // -2 = Use server language + ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); } +#endif + public: enum { @@ -56,6 +70,13 @@ class C_World : public C_BaseEntity float m_flMinPropScreenSpaceWidth; float m_flMaxPropScreenSpaceWidth; bool m_bColdWorld; +#ifdef MAPBASE + char m_iszChapterTitle[64]; +#endif +#ifdef MAPBASE_VSCRIPT + int m_iScriptLanguageServer; + int m_iScriptLanguageClient; +#endif private: void RegisterSharedActivities( void ); diff --git a/game/client/cbase.h b/game/client/cbase.h index 57e3260b..53322ca4 100644 --- a/game/client/cbase.h +++ b/game/client/cbase.h @@ -37,6 +37,10 @@ struct studiohdr_t; #include #include +#ifdef MAPBASE +#include "tier1/mapbase_con_groups.h" +#endif + // This is a precompiled header. Include a bunch of common stuff. // This is kind of ugly in that it adds a bunch of dependency where it isn't needed. diff --git a/game/client/cdll_bounded_cvars.cpp b/game/client/cdll_bounded_cvars.cpp index fa00db63..0928b774 100644 --- a/game/client/cdll_bounded_cvars.cpp +++ b/game/client/cdll_bounded_cvars.cpp @@ -133,7 +133,7 @@ float GetClientInterpAmount() } else { - if ( !HushAsserts() ) + if (!CommandLine()->FindParm("-hushasserts")) { AssertMsgOnce( false, "GetInterpolationAmount: can't get cl_updaterate cvar." ); } diff --git a/game/client/cdll_client_int.cpp b/game/client/cdll_client_int.cpp index a5ae65be..a17b5877 100644 --- a/game/client/cdll_client_int.cpp +++ b/game/client/cdll_client_int.cpp @@ -141,19 +141,17 @@ #if defined( TF_CLIENT_DLL ) #include "econ/tool_items/custom_texture_cache.h" - #endif #ifdef WORKSHOP_IMPORT_ENABLED #include "fbxsystem/fbxsystem.h" #endif +#ifdef MAPBASE_VSCRIPT +#include "vscript_client.h" +#endif #ifdef VANCE -// Discord RPC -#include "discord_rpc.h" -#include - #include "IDeferredExt.h" #endif @@ -179,10 +177,6 @@ extern vgui::IInputInternal *g_InputInternal; #include "sixense/in_sixense.h" #endif -/*#if defined( GAMEPADUI ) -#include "../gamepadui/igamepadui.h" -#endif // GAMEPADUI*/ - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -228,10 +222,11 @@ IEngineReplay *g_pEngineReplay = NULL; IEngineClientReplay *g_pEngineClientReplay = NULL; IReplaySystem *g_pReplay = NULL; #endif +#if defined( MAPBASE ) && defined( STEAM_RPC ) +IVEngineServer *serverengine = NULL; +#endif -/*#if defined(GAMEPADUI) -IGamepadUI* g_pGamepadUI = nullptr; -#endif // GAMEPADUI*/ +IScriptManager *scriptmanager = NULL; IHaptics* haptics = NULL;// NVNT haptics system interface singleton @@ -283,6 +278,8 @@ void ProcessCacheUsedMaterials() } } +void VGui_ClearVideoPanels(); + // String tables INetworkStringTable *g_pStringTableParticleEffectNames = NULL; INetworkStringTable *g_StringTableEffectDispatch = NULL; @@ -349,16 +346,17 @@ static ConVar s_CV_ShowParticleCounts("showparticlecounts", "0", 0, "Display num static ConVar s_cl_team("cl_team", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default team when joining a game"); static ConVar s_cl_class("cl_class", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default class when joining a game"); -#ifdef VANCE -// Discord RPC -static ConVar cl_discord_appid("cl_discord_appid", "549012876413632533", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT); -static int64_t startTimestamp = time(0); -#endif - #ifdef HL1MP_CLIENT_DLL static ConVar s_cl_load_hl1_content("cl_load_hl1_content", "0", FCVAR_ARCHIVE, "Mount the content from Half-Life: Source if possible"); #endif +#ifdef MAPBASE_RPC +// Mapbase stuff +extern void MapbaseRPC_Init(); +extern void MapbaseRPC_Shutdown(); +extern void MapbaseRPC_Update( int iType, const char *pMapName ); +#endif + // Physics system bool g_bLevelInitialized; @@ -367,24 +365,6 @@ class IClientPurchaseInterfaceV2 *g_pClientPurchaseInterface = (class IClientPur static ConVar *g_pcv_ThreadMode = NULL; -/*// GAMEPADUI TODO - put this somewhere better. (Madi) -#if defined( GAMEPADUI ) -const bool IsSteamDeck() -{ - if (CommandLine()->FindParm("-gamepadui")) - return true; - - if (CommandLine()->FindParm("-nogamepadui")) - return false; - - const char *pszSteamDeckEnv = getenv("SteamDeck"); - if (pszSteamDeckEnv && *pszSteamDeckEnv) - return atoi(pszSteamDeckEnv) != 0; - - return false; -} -#endif*/ - //----------------------------------------------------------------------------- // Purpose: interface for gameui to modify voice bans //----------------------------------------------------------------------------- @@ -610,8 +590,7 @@ void DisplayBoneSetupEnts() if ( pEnt->m_Count >= 3 ) { printInfo.color[0] = 1; - printInfo.color[1] = 0; - printInfo.color[2] = 0; + printInfo.color[1] = printInfo.color[2] = 0; } else if ( pEnt->m_Count == 2 ) { @@ -621,9 +600,7 @@ void DisplayBoneSetupEnts() } else { - printInfo.color[0] = 1; - printInfo.color[1] = 1; - printInfo.color[2] = 1; + printInfo.color[0] = printInfo.color[0] = printInfo.color[0] = 1; } engine->Con_NXPrintf( &printInfo, "%25s / %3d / %3d", pEnt->m_ModelName, pEnt->m_Count, pEnt->m_Index ); printInfo.index++; @@ -881,44 +858,6 @@ bool IsEngineThreaded() // Constructor //----------------------------------------------------------------------------- -#ifdef VANCE -//----------------------------------------------------------------------------- -// Discord RPC -//----------------------------------------------------------------------------- -static void HandleDiscordReady(const DiscordUser* connectedUser) -{ - DevMsg("Discord: Connected to user %s#%s - %s\n", - connectedUser->username, - connectedUser->discriminator, - connectedUser->userId); -} - -static void HandleDiscordDisconnected(int errcode, const char* message) -{ - DevMsg("Discord: Disconnected (%d: %s)\n", errcode, message); -} - -static void HandleDiscordError(int errcode, const char* message) -{ - DevMsg("Discord: Error (%d: %s)\n", errcode, message); -} - -static void HandleDiscordJoin(const char* secret) -{ - // Not implemented -} - -static void HandleDiscordSpectate(const char* secret) -{ - // Not implemented -} - -static void HandleDiscordJoinRequest(const DiscordUser* request) -{ - // Not implemented -} -#endif - CHLClient::CHLClient() { // Kinda bogus, but the logic in the engine is too convoluted to put it there @@ -926,6 +865,7 @@ CHLClient::CHLClient() } + extern IGameSystem *ViewportClientSystem(); @@ -1019,9 +959,28 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi return false; #endif +#if defined( MAPBASE ) && defined( STEAM_RPC ) + // Implements the server engine interface on the client. + // I'm extremely confused as to how this is even possible, but Saul Rennison's worldlight did it. + // If it's really this possible, why wasn't it available before? + // Hopefully there's no SP-only magic going on here, because I want to use this for RPC. + if ( (serverengine = (IVEngineServer*)appSystemFactory(INTERFACEVERSION_VENGINESERVER, NULL )) == NULL ) + return false; +#endif + if (!g_pMatSystemSurface) return false; + if ( !CommandLine()->CheckParm( "-noscripting") ) + { + scriptmanager = (IScriptManager *)appSystemFactory( VSCRIPT_INTERFACE_VERSION, NULL ); + + if (scriptmanager == nullptr) + { + scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL); + } + } + #ifdef WORKSHOP_IMPORT_ENABLED if ( !ConnectDataModel( appSystemFactory ) ) return false; @@ -1109,6 +1068,13 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi IGameSystem::Add( GetPredictionCopyTester() ); #endif +#ifdef VANCE + // Echoes; I deliberately moved this call to the start of + // this function, as ConnectDeferredExt() now handles + // overriding shaders as well. + ConnectDeferredExt(); +#endif + modemanager->Init( ); g_pClientMode->InitViewport(); @@ -1155,6 +1121,9 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi g_pGameSaveRestoreBlockSet->AddBlockHandler( GetEntitySaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->AddBlockHandler( GetPhysSaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->AddBlockHandler( GetViewEffectsRestoreBlockHandler() ); +#ifdef MAPBASE_VSCRIPT + g_pGameSaveRestoreBlockSet->AddBlockHandler( GetVScriptSaveRestoreBlockHandler() ); +#endif ClientWorldFactoryInit(); @@ -1168,35 +1137,12 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi HookHapticMessages(); // Always hook the messages #endif -#ifdef VANCE - // Discord RPC - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - - handlers.ready = HandleDiscordReady; - handlers.disconnected = HandleDiscordDisconnected; - handlers.errored = HandleDiscordError; - handlers.joinGame = HandleDiscordJoin; - handlers.spectateGame = HandleDiscordSpectate; - handlers.joinRequest = HandleDiscordJoinRequest; - - char appid[255]; - sprintf(appid, "%d", engine->GetAppID()); - Discord_Initialize(cl_discord_appid.GetString(), &handlers, 1, appid); - - if (!g_bTextMode) - { - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - - discordPresence.state = "In-Game"; - discordPresence.details = "Main Menu"; - discordPresence.startTimestamp = startTimestamp; - discordPresence.largeImageKey = "logo"; - Discord_UpdatePresence(&discordPresence); - } +#ifdef MAPBASE_RPC + MapbaseRPC_Init(); +#endif - ConnectDeferredExt(); +#ifdef MAPBASE + CommandLine()->AppendParm( "+r_hunkalloclightmaps", "0" ); #endif return true; @@ -1266,46 +1212,8 @@ void CHLClient::PostInit() } } #endif - -/*#if defined(GAMEPADUI) - if (IsSteamDeck()) - { - CSysModule* pGamepadUIModule = g_pFullFileSystem->LoadModule("gamepadui", "GAMEBIN", false); - if (pGamepadUIModule != nullptr) - { - GamepadUI_Log("Loaded gamepadui module.\n"); - - CreateInterfaceFn gamepaduiFactory = Sys_GetFactory(pGamepadUIModule); - if (gamepaduiFactory != nullptr) - { - g_pGamepadUI = (IGamepadUI*)gamepaduiFactory(GAMEPADUI_INTERFACE_VERSION, NULL); - if (g_pGamepadUI != nullptr) - { - GamepadUI_Log("Initializing IGamepadUI interface...\n"); - - factorylist_t factories; - FactoryList_Retrieve(factories); - g_pGamepadUI->Initialize(factories.appSystemFactory); - } - else - { - GamepadUI_Log("Unable to pull IGamepadUI interface.\n"); - } - } - else - { - GamepadUI_Log("Unable to get gamepadui factory.\n"); - } - } - else - { - GamepadUI_Log("Unable to load gamepadui module\n"); - } - } -#endif // GAMEPADUI*/ } - //----------------------------------------------------------------------------- // Purpose: Called when the client .dll is being dismissed //----------------------------------------------------------------------------- @@ -1316,22 +1224,23 @@ void CHLClient::Shutdown( void ) g_pAchievementsAndStatsInterface->ReleasePanel(); } -#ifdef VANCE - ShutdownDeferredExt(); -#endif - #ifdef SIXENSE g_pSixenseInput->Shutdown(); delete g_pSixenseInput; g_pSixenseInput = NULL; #endif + VGui_ClearVideoPanels(); + C_BaseAnimating::ShutdownBoneSetupThreadPool(); ClientWorldFactoryShutdown(); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetViewEffectsRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetPhysSaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetEntitySaveRestoreBlockHandler() ); +#ifdef MAPBASE_VSCRIPT + g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetVScriptSaveRestoreBlockHandler() ); +#endif ClientVoiceMgr_Shutdown(); @@ -1348,11 +1257,6 @@ void CHLClient::Shutdown( void ) UncacheAllMaterials(); IGameSystem::ShutdownAllSystems(); - -/*#if defined(GAMEPADUI) - if (g_pGamepadUI != nullptr) - g_pGamepadUI->Shutdown(); -#endif // GAMEPADUI*/ gHUD.Shutdown(); VGui_Shutdown(); @@ -1370,8 +1274,10 @@ void CHLClient::Shutdown( void ) DisconnectDataModel(); ShutdownFbx(); #endif - // Discord RPC - Discord_Shutdown(); + +#ifdef MAPBASE_RPC + MapbaseRPC_Shutdown(); +#endif // This call disconnects the VGui libraries which we rely on later in the shutdown path, so don't do it // DisconnectTier3Libraries( ); @@ -1451,14 +1357,8 @@ void CHLClient::HudUpdate( bool bActive ) g_pSixenseInput->SixenseFrame( 0, NULL ); } #endif - -/*#if defined(GAMEPADUI) - if (g_pGamepadUI != nullptr) - g_pGamepadUI->OnUpdate(frametime); -#endif // GAMEPADUI*/ } - //----------------------------------------------------------------------------- // Purpose: Called to restore to "non"HUD state. //----------------------------------------------------------------------------- @@ -1760,6 +1660,10 @@ void CHLClient::LevelInitPreEntity( char const* pMapName ) tempents->LevelInit(); ResetToneMapping(1.0); +#ifdef MAPBASE + GetClientWorldEntity()->ParseWorldMapData( engine->GetMapEntitiesString() ); +#endif + IGameSystem::LevelInitPreEntityAllSystems(pMapName); #ifdef USES_ECON_ITEMS @@ -1791,22 +1695,13 @@ void CHLClient::LevelInitPreEntity( char const* pMapName ) } #endif -#ifdef VANCE - // Discord RPC +#ifdef MAPBASE_RPC if (!g_bTextMode) { - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - - char buffer[256]; - discordPresence.state = "In-Game"; - sprintf(buffer, "Map: %s", pMapName); - discordPresence.details = buffer; - discordPresence.largeImageKey = "logo"; - Discord_UpdatePresence(&discordPresence); + MapbaseRPC_Update(RPCSTATE_LEVEL_INIT, pMapName); } #endif - + // Check low violence settings for this map g_RagdollLVManager.SetLowViolence( pMapName ); @@ -1819,15 +1714,9 @@ void CHLClient::LevelInitPreEntity( char const* pMapName ) CReplayRagdollRecorder::Instance().Init(); } #endif - -/*#if defined(GAMEPADUI) - if (g_pGamepadUI != nullptr) - g_pGamepadUI->OnLevelInitializePreEntity(); -#endif // GAMEPADUI*/ } - //----------------------------------------------------------------------------- // Purpose: Per level init //----------------------------------------------------------------------------- @@ -1836,12 +1725,6 @@ void CHLClient::LevelInitPostEntity( ) IGameSystem::LevelInitPostEntityAllSystems(); C_PhysPropClientside::RecreateAll(); internalCenterPrint->Clear(); - -/*#if defined(GAMEPADUI) - if (g_pGamepadUI != nullptr) - g_pGamepadUI->OnLevelInitializePostEntity(); -#endif // GAMEPADUI*/ - } //----------------------------------------------------------------------------- @@ -1908,25 +1791,12 @@ void CHLClient::LevelShutdown( void ) StopAllRumbleEffects(); -/*#if defined(GAMEPADUI) - if (g_pGamepadUI != nullptr) - g_pGamepadUI->OnLevelShutdown(); -#endif // GAMEPADUI*/ - gHUD.LevelShutdown(); - -#ifdef VANCE - // Discord RPC + +#ifdef MAPBASE_RPC if (!g_bTextMode) { - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - - discordPresence.state = "In-Game"; - discordPresence.details = "Main Menu"; - discordPresence.startTimestamp = startTimestamp; - discordPresence.largeImageKey = "logo"; - Discord_UpdatePresence(&discordPresence); + MapbaseRPC_Update(RPCSTATE_LEVEL_SHUTDOWN, NULL); } #endif @@ -2360,7 +2230,9 @@ void OnRenderStart() // are at the correct location view->OnRenderStart(); +#ifndef MAPBASE RopeManager()->OnRenderStart(); +#endif // This will place all entities in the correct position in world space and in the KD-tree C_BaseAnimating::UpdateClientSideAnimations(); @@ -2778,8 +2650,8 @@ void CHLClient::ClientAdjustStartSoundParams( StartSoundParams_t& params ) // Halloween voice futzery? else { - float flVoicePitchScale = 1.f; - CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pEntity, flVoicePitchScale, voice_pitch_scale ); + float flHeadScale = 1.f; + CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pEntity, flHeadScale, head_scale ); int iHalloweenVoiceSpell = 0; CALL_ATTRIB_HOOK_INT_ON_OTHER( pEntity, iHalloweenVoiceSpell, halloween_voice_modulation ); @@ -2787,9 +2659,17 @@ void CHLClient::ClientAdjustStartSoundParams( StartSoundParams_t& params ) { params.pitch *= 0.8f; } - else if( flVoicePitchScale != 1.f ) + else if( flHeadScale != 1.f ) { - params.pitch *= flVoicePitchScale; + // Big head, deep voice + if( flHeadScale > 1.f ) + { + params.pitch *= 0.8f; + } + else // Small head, high voice + { + params.pitch *= 1.3f; + } } } } diff --git a/game/client/cdll_client_int.h b/game/client/cdll_client_int.h index c2456332..5cbd087e 100644 --- a/game/client/cdll_client_int.h +++ b/game/client/cdll_client_int.h @@ -110,6 +110,9 @@ extern IReplayManager *g_pReplayManager; extern IReplayScreenshotManager *g_pReplayScreenshotManager; extern IEngineReplay *g_pEngineReplay; extern IEngineClientReplay *g_pEngineClientReplay; +#ifdef MAPBASE +extern IVEngineServer *serverengine; +#endif //============================================================================= // HPE_BEGIN @@ -177,4 +180,16 @@ extern CSteamID GetSteamIDForPlayerIndex( int iPlayerIndex ); #endif +#ifdef MAPBASE +// Mapbase RPC stuff +enum +{ + RPCSTATE_INIT, + RPCSTATE_LEVEL_INIT, + RPCSTATE_LEVEL_SHUTDOWN, + + RPCSTATE_UPDATE, +}; +#endif + #endif // CDLL_CLIENT_INT_H diff --git a/game/client/cdll_util.cpp b/game/client/cdll_util.cpp index 4e877530..5117eaa7 100644 --- a/game/client/cdll_util.cpp +++ b/game/client/cdll_util.cpp @@ -703,6 +703,24 @@ int UTIL_EntitiesAlongRay( C_BaseEntity **pList, int listMax, const Ray_t &ray, return rayEnum.GetCount(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Pass in an array of pointers and an array size, it fills the array and returns the number inserted +// Input : **pList - +// listMax - +// &point - +// flagMask - +// Output : int +//----------------------------------------------------------------------------- +int UTIL_EntitiesAtPoint( C_BaseEntity **pList, int listMax, const Vector &point, int flagMask, int partitionMask ) +{ + CFlaggedEntitiesEnum rayEnum( pList, listMax, flagMask ); + partition->EnumerateElementsAtPoint( partitionMask, point, false, &rayEnum ); + + return rayEnum.GetCount(); +} +#endif + CEntitySphereQuery::CEntitySphereQuery( const Vector ¢er, float radius, int flagMask, int partitionMask ) { m_listIndex = 0; @@ -729,11 +747,14 @@ CBaseEntity *CEntitySphereQuery::GetCurrentEntity() // sep - Character to use as separator. UNDONE: allow multiple separator chars // Output : Returns a pointer to the next token to be parsed. //----------------------------------------------------------------------------- -const char *nexttoken(char *token, const char *str, char sep) +const char *nexttoken(char *token, const char *str, char sep, size_t tokenLen) { if ((str == NULL) || (*str == '\0')) { - *token = '\0'; + if(tokenLen) + { + *token = '\0'; + } return(NULL); } @@ -741,11 +762,25 @@ const char *nexttoken(char *token, const char *str, char sep) // Copy everything up to the first separator into the return buffer. // Do not include separators in the return buffer. // - while ((*str != sep) && (*str != '\0')) + while ((*str != sep) && (*str != '\0') && (tokenLen > 1)) { *token++ = *str++; + tokenLen--; + } + + // + // If token is to big for return buffer, skip rest of token. + // + while ((*str != sep) && (*str != '\0')) + { + str++; + } + + if(tokenLen) + { + *token = '\0'; + tokenLen--; } - *token = '\0'; // // Advance the pointer unless we hit the end of the input string. diff --git a/game/client/cdll_util.h b/game/client/cdll_util.h index 64beb5fb..26332551 100644 --- a/game/client/cdll_util.h +++ b/game/client/cdll_util.h @@ -89,7 +89,7 @@ void NormalizeAngles( QAngle& angles ); void InterpolateAngles( const QAngle& start, const QAngle& end, QAngle& output, float frac ); void InterpolateVector( float frac, const Vector& src, const Vector& dest, Vector& output ); -const char *nexttoken(char *token, const char *str, char sep); +const char *nexttoken(char *token, const char *str, char sep, size_t tokenLen); //----------------------------------------------------------------------------- // Base light indices to avoid index collision @@ -119,6 +119,9 @@ void ClientPrint( C_BasePlayer *player, int msg_dest, const char *msg_name, cons int UTIL_EntitiesInBox( C_BaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask, int partitionMask = PARTITION_CLIENT_NON_STATIC_EDICTS ); int UTIL_EntitiesInSphere( C_BaseEntity **pList, int listMax, const Vector ¢er, float radius, int flagMask, int partitionMask = PARTITION_CLIENT_NON_STATIC_EDICTS ); int UTIL_EntitiesAlongRay( C_BaseEntity **pList, int listMax, const Ray_t &ray, int flagMask, int partitionMask = PARTITION_CLIENT_NON_STATIC_EDICTS ); +#ifdef MAPBASE +int UTIL_EntitiesAtPoint( C_BaseEntity **pList, int listMax, const Vector &point, int flagMask, int partitionMask = PARTITION_CLIENT_NON_STATIC_EDICTS ); +#endif // make this a fixed size so it just sits on the stack #define MAX_SPHERE_QUERY 256 @@ -161,7 +164,12 @@ T *_CreateEntity( T *newClass, const char *className ) // Misc useful inline bool FStrEq(const char *sz1, const char *sz2) { - return (sz1 == sz2 || V_stricmp(sz1, sz2) == 0); +#ifdef MAPBASE + // V_stricmp() already checks if the pointers are equal, so having a comparison here is pointless. + return ( V_stricmp(sz1, sz2) == 0 ); +#else + return ( sz1 == sz2 || V_stricmp(sz1, sz2) == 0 ); +#endif } // Given a vector, clamps the scalar axes to MAX_COORD_FLOAT ranges from worldsize.h diff --git a/game/client/client_base.vpc b/game/client/client_base.vpc index b1e5ae53..9eae51f1 100644 --- a/game/client/client_base.vpc +++ b/game/client/client_base.vpc @@ -18,6 +18,9 @@ $include "$SRCDIR\vpc_scripts\protobuf_builder.vpc" $Include "$SRCDIR\vpc_scripts\source_replay.vpc" [$TF] $Include "$SRCDIR\game\protobuf_include.vpc" +// Mapbase stuff +$Include "$SRCDIR\game\client\client_mapbase.vpc" [$MAPBASE] + $Configuration "Debug" { $General @@ -53,8 +56,9 @@ $Configuration { $AdditionalIncludeDirectories ".\;$BASE;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\shared;.\game_controls;$SRCDIR\thirdparty\sixensesdk\include" $PreprocessorDefinitions "$BASE;NO_STRING_T;CLIENT_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead" - $PreprocessorDefinitions "$BASE;fopen=dont_use_fopen" [$WIN32] - $PreprocessorDefinitions "$BASE;USE_WEBM_FOR_REPLAY;" [$LINUXALL] + $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;fopen=dont_use_fopen" [$WIN32] + $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;" [$OSXALL] + $PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;USE_WEBM_FOR_REPLAY;" [$LINUXALL] $PreprocessorDefinitions "$BASE;CURL_STATICLIB" [$WIN32 && $BUILD_REPLAY] $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" $Create/UsePCHThroughFile "cbase.h" @@ -489,6 +493,11 @@ $Project $File "viewrender.cpp" $File "$SRCDIR\game\shared\voice_banmgr.cpp" $File "$SRCDIR\game\shared\voice_status.cpp" + $File "vscript_client.cpp" + $File "vscript_client.h" + $File "vscript_client.nut" + $File "$SRCDIR\game\shared\vscript_shared.cpp" + $File "$SRCDIR\game\shared\vscript_shared.h" $File "warp_overlay.cpp" $File "WaterLODMaterialProxy.cpp" $File "$SRCDIR\game\shared\weapon_parse.cpp" @@ -527,7 +536,6 @@ $Project "$SRCDIR\public\dt_utlvector_recv.cpp" \ "$SRCDIR\public\filesystem_helpers.cpp" \ "$SRCDIR\public\interpolatortypes.cpp" \ - "$SRCDIR\game\shared\interval.cpp" \ "$SRCDIR\common\language.cpp" \ "$SRCDIR\public\networkvar.cpp" \ "$SRCDIR\common\randoverride.cpp" \ @@ -1098,6 +1106,7 @@ $Project $File "$SRCDIR\public\vgui_controls\WizardSubPanel.h" $File "$SRCDIR\public\worldsize.h" $File "$SRCDIR\public\zip_uncompressed.h" + $File "$SRCDIR\public\tier1\interval.h" //Haptics $File "$SRCDIR\public\haptics\ihaptics.h" [$WIN32] $File "$SRCDIR\public\haptics\haptic_utils.h" [$WIN32] @@ -1154,7 +1163,6 @@ $Project $File "$SRCDIR\game\shared\igamesystem.h" $File "$SRCDIR\game\shared\imovehelper.h" $File "$SRCDIR\game\shared\in_buttons.h" - $File "$SRCDIR\game\shared\interval.h" $File "$SRCDIR\game\shared\iplayeranimstate.h" $File "$SRCDIR\game\shared\ipredictionsystem.h" $File "$SRCDIR\game\shared\itempents.h" @@ -1252,8 +1260,10 @@ $Project $Lib vtf $ImpLib steam_api - $Libexternal $LIBCOMMON/libcrypto [$OSXALL] - $Libexternal "$SRCDIR\lib\common\$(CRYPTOPPDIR)\libcrypto" [$LINUXALL] + // Discord integration + $Lib "$LIBPUBLIC\discord-rpc" [$MAPBASE_RPC&&!$LINUXALL] + + $Lib $LIBCOMMON/libcrypto [$POSIX] $ImpLib "$LIBCOMMON\curl" [$OSXALL] @@ -1263,7 +1273,7 @@ $Project $Libexternal libz [$LINUXALL] $Libexternal "$LIBCOMMON/libcurl" [$LINUXALL] $Libexternal "$LIBCOMMON/libcurlssl" [$LINUXALL] - $Libexternal "$SRCDIR\lib\common\$(CRYPTOPPDIR)\libssl" [$LINUXALL] + $Libexternal "$LIBCOMMON/libssl" [$LINUXALL] } } diff --git a/game/client/client_episodic.vpc b/game/client/client_episodic.vpc new file mode 100644 index 00000000..3c6f20dd --- /dev/null +++ b/game/client/client_episodic.vpc @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------- +// CLIENT_EPISODIC.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "episodic" [!$SOURCESDK] +$Macro GAMENAME "mod_episodic" [$SOURCESDK] + +$Include "$SRCDIR\game\client\client_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories ".\hl2;.\hl2\elements;$SRCDIR\game\shared\hl2;$SRCDIR\game\shared\episodic;..\..\public;$BASE" + $PreprocessorDefinitions "$BASE;HL2_CLIENT_DLL;HL2_EPISODIC" + } +} + +$Project "Client (Episodic)" +{ + $Folder "Source Files" + { + $File "hud_chat.cpp" + $File "c_team_objectiveresource.cpp" + $File "c_team_objectiveresource.h" + + $Folder "HL2 DLL" + { + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" + $File "$SRCDIR\game\shared\episodic\achievements_ep1.cpp" + $File "$SRCDIR\game\shared\episodic\achievements_ep2.cpp" + $File "$SRCDIR\game\shared\episodic\achievements_epx.cpp" + $File "hl2\c_antlion_dust.cpp" + $File "hl2\c_ar2_explosion.cpp" + $File "hl2\c_barnacle.cpp" + $File "hl2\c_barney.cpp" + $File "hl2\c_basehelicopter.cpp" + $File "hl2\c_basehelicopter.h" + $File "hl2\c_basehlcombatweapon.cpp" + $File "hl2\c_basehlcombatweapon.h" + $File "hl2\c_basehlplayer.cpp" + $File "hl2\c_basehlplayer.h" + $File "hl2\c_citadel_effects.cpp" + $File "hl2\c_corpse.cpp" + $File "hl2\c_corpse.h" + $File "hl2\c_env_alyxtemp.cpp" + $File "hl2\c_env_headcrabcanister.cpp" + $File "hl2\c_env_starfield.cpp" + $File "hl2\c_func_tankmortar.cpp" + $File "hl2\c_hl2_playerlocaldata.cpp" + $File "hl2\c_hl2_playerlocaldata.h" + $File "hl2\c_info_teleporter_countdown.cpp" + $File "hl2\c_npc_antlionguard.cpp" + $File "hl2\c_npc_combinegunship.cpp" + $File "hl2\c_npc_manhack.cpp" + $File "hl2\c_npc_rollermine.cpp" + $File "hl2\c_plasma_beam_node.cpp" + $File "hl2\c_prop_combine_ball.cpp" + $File "hl2\c_prop_combine_ball.h" + $File "episodic\c_prop_scalable.cpp" + $File "hl2\c_rotorwash.cpp" + $File "hl2\c_script_intro.cpp" + $File "$SRCDIR\game\shared\script_intro_shared.cpp" + $File "hl2\c_strider.cpp" + $File "hl2\c_te_concussiveexplosion.cpp" + $File "hl2\c_te_flare.cpp" + $File "hl2\c_thumper_dust.cpp" + $File "hl2\c_vehicle_airboat.cpp" + $File "hl2\c_vehicle_cannon.cpp" + $File "hl2\c_vehicle_crane.cpp" + $File "hl2\c_vehicle_crane.h" + $File "episodic\c_vehicle_jeep_episodic.cpp" + $File "hl2\c_vehicle_prisoner_pod.cpp" + $File "episodic\c_vort_charge_token.cpp" + $File "hl2\c_weapon__stubs_hl2.cpp" + $File "hl2\c_weapon_crossbow.cpp" + $File "episodic\c_weapon_hopwire.cpp" + $File "hl2\c_weapon_physcannon.cpp" + $File "hl2\c_weapon_stunstick.cpp" [!$MAPBASE] // See client_mapbase.vpc + $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" + $File "hl2\clientmode_hlnormal.cpp" + $File "hl2\clientmode_hlnormal.h" + $File "death.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" + $File "$SRCDIR\game\shared\episodic\npc_advisor_shared.h" + $File "episodic\c_npc_advisor.cpp" + $File "episodic\episodic_screenspaceeffects.cpp" + $File "episodic\episodic_screenspaceeffects.h" + $File "episodic\flesh_internal_material_proxy.cpp" + $File "hl2\fx_antlion.cpp" + $File "hl2\fx_bugbait.cpp" + $File "hl2\fx_hl2_impacts.cpp" + $File "hl2\fx_hl2_tracers.cpp" + $File "hl2\hl2_clientmode.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" + $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" + $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" + $File "hl2\hl_in_main.cpp" + $File "hl2\hl_prediction.cpp" + $File "hl2\hud_ammo.cpp" + $File "hl2\hud_battery.cpp" + $File "hl2\hud_blood.cpp" + $File "hl2\hud_credits.cpp" + $File "hl2\hud_damageindicator.cpp" + $File "hl2\hud_flashlight.cpp" + $File "hl2\hud_locator.cpp" + $File "hl2\hud_health.cpp" + $File "hl2\hud_poisondamageindicator.cpp" + $File "hud_posture.cpp" + $File "hl2\hud_quickinfo.cpp" + $File "hl2\hud_radar.cpp" + $File "hl2\hud_radar.h" + $File "hud_squadstatus.cpp" + $File "hl2\hud_suitpower.cpp" + $File "hl2\hud_suitpower.h" + $File "hl2\hud_weaponselection.cpp" + $File "hl2\hud_zoom.cpp" + $File "hl2\shieldproxy.cpp" + $File "$SRCDIR\game\shared\hl2\survival_gamerules.cpp" + $File "hl2\vgui_rootpanel_hl2.cpp" + $File "episodic\c_npc_puppet.cpp" + } + } + +} diff --git a/game/client/client_hl2.vpc b/game/client/client_hl2.vpc new file mode 100644 index 00000000..b8f6f0ef --- /dev/null +++ b/game/client/client_hl2.vpc @@ -0,0 +1,117 @@ +//----------------------------------------------------------------------------- +// CLIENT_HL2.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "hl2" [!$SOURCESDK] +$Macro GAMENAME "mod_hl2" [$SOURCESDK] + +$Include "$SRCDIR\game\client\client_base.vpc" +$Include "$SRCDIR\game\protobuf_include.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories ".\hl2;.\hl2\elements;$SRCDIR\game\shared\hl2;$BASE" + $PreprocessorDefinitions "$BASE;HL2_CLIENT_DLL" + } +} + +$Project "Client (HL2)" +{ + $Folder "Source Files" + { + $File "hud_chat.cpp" + $File "c_team_objectiveresource.cpp" + $File "c_team_objectiveresource.h" + + $Folder "HL2 DLL" + { + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" + $File "$SRCDIR\game\shared\hl2\achievements_hl2.cpp" + $File "hl2\c_antlion_dust.cpp" + $File "hl2\c_ar2_explosion.cpp" + $File "hl2\c_barnacle.cpp" + $File "hl2\c_barney.cpp" + $File "hl2\c_basehelicopter.cpp" + $File "hl2\c_basehelicopter.h" + $File "hl2\c_basehlcombatweapon.cpp" + $File "hl2\c_basehlcombatweapon.h" + $File "hl2\c_basehlplayer.cpp" + $File "hl2\c_basehlplayer.h" + $File "hl2\c_citadel_effects.cpp" + $File "hl2\c_corpse.cpp" + $File "hl2\c_corpse.h" + $File "hl2\c_env_alyxtemp.cpp" + $File "hl2\c_env_headcrabcanister.cpp" + $File "hl2\c_env_starfield.cpp" + $File "hl2\c_func_tankmortar.cpp" + $File "hl2\c_hl2_playerlocaldata.cpp" + $File "hl2\c_hl2_playerlocaldata.h" + $File "hl2\c_info_teleporter_countdown.cpp" + $File "hl2\c_npc_antlionguard.cpp" + $File "hl2\c_npc_combinegunship.cpp" + $File "hl2\c_npc_manhack.cpp" + $File "hl2\c_npc_rollermine.cpp" + $File "hl2\c_plasma_beam_node.cpp" + $File "hl2\c_prop_combine_ball.cpp" + $File "hl2\c_prop_combine_ball.h" + $File "hl2\c_rotorwash.cpp" + $File "hl2\c_script_intro.cpp" + $File "$SRCDIR\game\shared\script_intro_shared.cpp" + $File "hl2\c_strider.cpp" + $File "hl2\c_te_concussiveexplosion.cpp" + $File "hl2\c_te_flare.cpp" + $File "hl2\c_thumper_dust.cpp" + $File "hl2\c_vehicle_airboat.cpp" + $File "hl2\c_vehicle_cannon.cpp" + $File "hl2\c_vehicle_crane.cpp" + $File "hl2\c_vehicle_crane.h" + $File "hl2\c_vehicle_prisoner_pod.cpp" + $File "hl2\c_weapon__stubs_hl2.cpp" + $File "hl2\c_weapon_crossbow.cpp" + $File "hl2\c_weapon_physcannon.cpp" + $File "hl2\c_weapon_stunstick.cpp" [!$MAPBASE] // See client_mapbase.vpc + $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" + $File "hl2\clientmode_hlnormal.cpp" + $File "hl2\clientmode_hlnormal.h" + $File "death.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" + $File "hl2\fx_antlion.cpp" + $File "hl2\fx_bugbait.cpp" + $File "hl2\fx_hl2_impacts.cpp" + $File "hl2\fx_hl2_tracers.cpp" + $File "hl2\hl2_clientmode.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" + $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" + $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" + $File "hl2\hl_in_main.cpp" + $File "hl2\hl_prediction.cpp" + $File "hl2\hud_ammo.cpp" + $File "hl2\hud_battery.cpp" + $File "hl2\hud_blood.cpp" + $File "hl2\hud_credits.cpp" + $File "hl2\hud_damageindicator.cpp" + $File "hl2\hud_flashlight.cpp" + $File "hl2\hud_health.cpp" + $File "hl2\hud_poisondamageindicator.cpp" + $File "hud_posture.cpp" + $File "hl2\hud_quickinfo.cpp" + $File "hud_squadstatus.cpp" + $File "hl2\hud_suitpower.cpp" + $File "hl2\hud_suitpower.h" + $File "hl2\hud_weaponselection.cpp" + $File "hl2\hud_zoom.cpp" + $File "hl2\shieldproxy.cpp" + $File "hl2\vgui_rootpanel_hl2.cpp" + $File "episodic\c_vort_charge_token.cpp" + } + } +} diff --git a/game/client/client_hl2mp.vpc b/game/client/client_hl2mp.vpc deleted file mode 100644 index 88e18a8e..00000000 --- a/game/client/client_hl2mp.vpc +++ /dev/null @@ -1,174 +0,0 @@ -//----------------------------------------------------------------------------- -// CLIENT_HL2MP.VPC -// -// Project Script -//----------------------------------------------------------------------------- - -$Macro SRCDIR "..\.." -$Macro GAMENAME "hl2mp" [!$SOURCESDK] -$Macro GAMENAME "mod_hl2mp" [$SOURCESDK] - -$Include "$SRCDIR\game\client\client_base.vpc" - -$Configuration -{ - $Compiler - { - $AdditionalIncludeDirectories "$BASE;hl2mp\ui,.\hl2mp,$SRCDIR\game\shared\hl2mp,.\hl2,.\hl2\elements,$SRCDIR\game\shared\hl2" - $PreprocessorDefinitions "$BASE;HL2MP;HL2_CLIENT_DLL" - } -} - -$Project "Client (HL2MP)" -{ - $Folder "Source Files" - { - -$File "$SRCDIR\game\shared\weapon_parse_default.cpp" - - $File "c_team_objectiveresource.cpp" - $File "c_team_objectiveresource.h" - $File "c_team_train_watcher.cpp" - $File "c_team_train_watcher.h" - $File "hud_voicestatus.cpp" - $File "$SRCDIR\game\shared\predicted_viewmodel.cpp" - $File "$SRCDIR\game\shared\predicted_viewmodel.h" - $File "$SRCDIR\game\shared\teamplay_round_timer.cpp" - $File "$SRCDIR\game\shared\teamplay_round_timer.h" - - $Folder "HL2 DLL" - { - $File "episodic\c_vort_charge_token.cpp" - $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" - $File "hl2\c_antlion_dust.cpp" - $File "hl2\c_ar2_explosion.cpp" - $File "hl2\c_barnacle.cpp" - $File "hl2\c_barney.cpp" - $File "hl2\c_basehelicopter.cpp" - $File "hl2\c_basehelicopter.h" - $File "hl2\c_basehlcombatweapon.cpp" - $File "hl2\c_basehlcombatweapon.h" - $File "hl2\c_basehlplayer.cpp" - $File "hl2\c_basehlplayer.h" - $File "hl2\c_citadel_effects.cpp" - $File "hl2\c_corpse.cpp" - $File "hl2\c_corpse.h" - $File "hl2\c_env_alyxtemp.cpp" - $File "hl2\c_env_headcrabcanister.cpp" - $File "hl2\c_env_starfield.cpp" - $File "hl2\c_func_tankmortar.cpp" - $File "hl2\c_hl2_playerlocaldata.cpp" - $File "hl2\c_hl2_playerlocaldata.h" - $File "hl2\c_info_teleporter_countdown.cpp" - $File "hl2\c_npc_antlionguard.cpp" - $File "hl2\c_npc_combinegunship.cpp" - $File "hl2\c_npc_manhack.cpp" - $File "hl2\c_npc_rollermine.cpp" - $File "hl2\c_plasma_beam_node.cpp" - $File "hl2\c_prop_combine_ball.cpp" - $File "hl2\c_prop_combine_ball.h" - $File "hl2\c_rotorwash.cpp" - $File "hl2\c_script_intro.cpp" - $File "$SRCDIR\game\shared\script_intro_shared.cpp" - $File "hl2\c_strider.cpp" - $File "hl2\c_te_concussiveexplosion.cpp" - $File "hl2\c_te_flare.cpp" - $File "hl2\c_thumper_dust.cpp" - $File "hl2\c_vehicle_airboat.cpp" - $File "hl2\c_vehicle_cannon.cpp" - $File "hl2\c_vehicle_crane.cpp" - $File "hl2\c_vehicle_crane.h" - $File "hl2\c_vehicle_prisoner_pod.cpp" - $File "hl2\c_weapon__stubs_hl2.cpp" - $File "hl2\c_weapon_crossbow.cpp" - $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" - $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" - $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" - $File "hl2\fx_antlion.cpp" - $File "hl2\fx_bugbait.cpp" - $File "hl2\fx_hl2_impacts.cpp" - $File "hl2\fx_hl2_tracers.cpp" - $File "hl2\hl2_clientmode.cpp" - $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" - $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" - $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" - $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" - $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" - $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" - $File "hl2\hl_in_main.cpp" - $File "hl2\hl_prediction.cpp" - $File "hl2\hud_ammo.cpp" - $File "hl2\hud_battery.cpp" - $File "hl2\hud_blood.cpp" - $File "hl2\hud_credits.cpp" - $File "hl2\hud_damageindicator.cpp" - $File "hl2\hud_flashlight.cpp" - $File "hl2\hud_health.cpp" - $File "hl2\hud_poisondamageindicator.cpp" - $File "hl2\hud_quickinfo.cpp" - $File "hud_squadstatus.cpp" - $File "hl2\hud_suitpower.cpp" - $File "hl2\hud_suitpower.h" - $File "hl2\hud_weaponselection.cpp" - $File "hl2\hud_zoom.cpp" - $File "hl2\shieldproxy.cpp" - $File "hl2\vgui_rootpanel_hl2.cpp" - } - - $Folder "HL2MP" - { - $File "hl2mp\c_hl2mp_player.cpp" - $File "hl2mp\c_hl2mp_player.h" - $File "hl2mp\c_te_hl2mp_shotgun_shot.cpp" - $File "hl2mp\clientmode_hl2mpnormal.cpp" - $File "hl2mp\clientmode_hl2mpnormal.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_gamerules.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_gamerules.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h" - - $Folder "Weapons" - { - $File "$SRCDIR\game\shared\hl2mp\weapon_357.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_ar2.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_ar2.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_crossbow.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_crowbar.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_frag.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase_machinegun.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase_machinegun.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasebasebludgeon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasehlmpcombatweapon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasehlmpcombatweapon.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_physcannon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_physcannon.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_pistol.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_rpg.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_rpg.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_shotgun.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_slam.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_slam.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_smg1.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.cpp" - } - - $Folder "UI" - { - $File "hl2mp\ui\backgroundpanel.cpp" - $File "hl2mp\ui\backgroundpanel.h" - $File "hl2mp\hl2mp_hud_chat.cpp" - $File "hl2mp\hl2mp_hud_chat.h" - $File "hl2mp\hl2mp_hud_target_id.cpp" - $File "hl2mp\hl2mp_hud_team.cpp" - $File "hl2mp\ui\hl2mpclientscoreboard.cpp" - $File "hl2mp\ui\hl2mpclientscoreboard.h" - $File "hl2mp\ui\hl2mptextwindow.cpp" - $File "hl2mp\ui\hl2mptextwindow.h" - $File "hl2mp\hud_deathnotice.cpp" - } - } - } -} diff --git a/game/client/client_mapbase.vpc b/game/client/client_mapbase.vpc new file mode 100644 index 00000000..f862e2fe --- /dev/null +++ b/game/client/client_mapbase.vpc @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// CLIENT_MAPBASE.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Configuration +{ + $Compiler + { + $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE" + + $PreprocessorDefinitions "$BASE;MAPBASE_RPC;DISCORD_RPC;STEAM_RPC" [$MAPBASE_RPC&&!$LINUXALL] + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] + $PreprocessorDefinitions "$BASE;NEW_RESPONSE_SYSTEM" [$NEW_RESPONSE_SYSTEM] + } +} + +$Project +{ + $Folder "Source Files" + { + $File "c_env_global_light.cpp" + $File "vance\worldlight.cpp" + $File "vance\worldlight.h" + $File "vance\vis.cpp" + $File "vance\vis.h" + $File "c_baselesson.cpp" + $File "c_baselesson.h" + $File "c_gameinstructor.cpp" + $File "c_gameinstructor.h" + $File "hud_locator_target.cpp" + $File "hud_locator_target.h" + $File "c_postprocesscontroller.cpp" + $File "c_postprocesscontroller.h" + $File "c_env_dof_controller.cpp" + $File "c_movie_display.cpp" + $File "c_movie_display.h" + $File "vgui_movie_display.cpp" + $File "convarproxy.cpp" + + $Folder "Mapbase" + { + $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp" + $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" + $File "$SRCDIR\game\shared\mapbase\MapEdit.h" + $File "$SRCDIR\game\shared\mapbase\matchers.cpp" + $File "$SRCDIR\game\shared\mapbase\matchers.h" + $File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.cpp" + $File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.h" + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_singletons.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_consts_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_consts_weapons.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\logic_script_client.cpp" [$MAPBASE_VSCRIPT] + + $File "mapbase\vscript_vgui.cpp" [$MAPBASE_VSCRIPT] + $File "mapbase\vscript_vgui.h" [$MAPBASE_VSCRIPT] + $File "mapbase\vscript_vgui.nut" [$MAPBASE_VSCRIPT] + + $File "mapbase\c_func_clientclip.cpp" + $File "mapbase\c_func_fake_worldportal.cpp" + $File "mapbase\c_func_fake_worldportal.h" + $File "mapbase\c_point_glow.cpp" + $File "mapbase\c_vgui_text_display.cpp" + $File "mapbase\mapbase_autocubemap.cpp" + } + + $Folder "HL2 DLL" + { + // Original stunstick files are conditional'd out in the HL2 VPCs + $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.cpp" + $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.h" + } + + $Folder "HL2MP" + { + $Folder "Weapons" + { + $File "$SRCDIR\game\shared\hl2mp\weapon_slam.cpp" + $File "$SRCDIR\game\shared\hl2mp\weapon_slam.h" + } + } + } + + $Folder "Link Libraries" + { + $Lib "vscript" [$MAPBASE_VSCRIPT] + $Lib "raytrace" + } +} diff --git a/game/client/client_vance.vpc b/game/client/client_vance.vpc index 9d9b7ad9..45faf5e5 100644 --- a/game/client/client_vance.vpc +++ b/game/client/client_vance.vpc @@ -27,22 +27,24 @@ $Project "Client (Vance)" $File "c_team_objectiveresource.h" $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h" -$File "$SRCDIR\game\shared\weapon_parse_default.cpp" + -$File "c_env_global_light.cpp" + -$File "c_env_global_light.h" + $File "vance\shader_override.cpp" + $File "vance\shader_override.h" + $Folder "VANCE" { $File "vance\hud_weaponselection.cpp" $File "vance\c_weapon_hacktool.cpp" $File "vance\c_weapon_sniper.cpp" - $File "vance\deferred_screenspace_effects.cpp" - $File "vance\deferred_screenspace_effects.h" - $File "vance\deferred_screenspace_effects_order.cpp" $File "vance\c_light_manager.cpp" $File "vance\c_lights_deferred.cpp" $File "vance\c_vance_player.cpp" $File "vance\c_vance_player.h" $File "vance\c_bobmodel.cpp" - $File "vance\c_bobmodel.h" + $File "vance\c_bobmodel.h" $File "vance\viewmodel_attachment.cpp" $File "vance\viewmodel_attachment.h" $File "vance\c_env_skydome.cpp" @@ -50,26 +52,28 @@ $Project "Client (Vance)" $File "vance\c_env_global_light.cpp" $File "vance\c_env_global_light.h" + $File "hl2\c_weapon__stubs_hl2.cpp" + $File "vance\deferred_material_passthru.h" $File "vance\deferred_material_replace.cpp" $File "vance\IDeferredExt_client.cpp" - + $File "$SRCDIR\game\shared\vance\vance_baseweapon_shared.cpp" $File "$SRCDIR\game\shared\vance\vance_baseweapon_shared.h" $File "$SRCDIR\game\shared\vance\vance_weapon_parse.cpp" $File "$SRCDIR\game\shared\vance\vance_weapon_parse.h" $File "$SRCDIR\game\shared\vance\vance_viewmodel.cpp" $File "$SRCDIR\game\shared\vance\vance_viewmodel.h" - $File "$SRCDIR\game\shared\vance\singleplayer_animstate.cpp" - $File "$SRCDIR\game\shared\vance\singleplayer_animstate.h" + //$File "$SRCDIR\game\shared\vance\singleplayer_animstate.cpp" + //$File "$SRCDIR\game\shared\vance\singleplayer_animstate.h" $File "$SRCDIR\game\shared\vance\vance_gamerules.cpp" $File "$SRCDIR\game\shared\vance\vance_gamerules.h" $File "$SRCDIR\game\shared\vance\vance_shareddefs.h" - + $File "$SRCDIR\game\shared\vance\weapon_akms.cpp" $File "$SRCDIR\game\shared\vance\weapon_melee.cpp" } - + $Folder "HL2 DLL" { $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" @@ -119,11 +123,10 @@ $Project "Client (Vance)" $File "episodic\c_vehicle_jeep_episodic.cpp" $File "hl2\c_vehicle_prisoner_pod.cpp" $File "episodic\c_vort_charge_token.cpp" - $File "hl2\c_weapon__stubs_hl2.cpp" $File "hl2\c_weapon_crossbow.cpp" $File "episodic\c_weapon_hopwire.cpp" $File "hl2\c_weapon_physcannon.cpp" - $File "hl2\c_weapon_stunstick.cpp" + $File "hl2\c_weapon_stunstick.cpp" [!$MAPBASE] // See client_mapbase.vpc $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" $File "hl2\clientmode_hlnormal.cpp" $File "hl2\clientmode_hlnormal.h" @@ -156,7 +159,7 @@ $Project "Client (Vance)" $File "hl2\hud_flashlight.cpp" $File "hl2\hud_locator.cpp" $File "hl2\hud_health.cpp" - $File "hl2\hud_poisondamageindicator.cpp" + $File "hl2\hud_poisondamageindicator.cpp" $File "hud_posture.cpp" $File "hl2\hud_quickinfo.cpp" $File "hl2\hud_radar.cpp" @@ -171,9 +174,4 @@ $Project "Client (Vance)" $File "episodic\c_npc_puppet.cpp" } } - - $Folder "Link Libraries" - { - $Lib "$LIBCOMMON/discord-rpc" - } } diff --git a/game/client/client_virtualreality.cpp b/game/client/client_virtualreality.cpp index 472fa6c1..af52b56e 100644 --- a/game/client/client_virtualreality.cpp +++ b/game/client/client_virtualreality.cpp @@ -213,7 +213,6 @@ void CalcFovFromProjection ( float *pFov, const VMatrix &proj ) Assert ( proj.m[3][2] == -1.0f ); Assert ( proj.m[3][3] == 0.0f ); - /* // The math here: // A view-space vector (x,y,z,1) is transformed by the projection matrix // / xscale 0 xoffset 0 \ @@ -228,7 +227,6 @@ void CalcFovFromProjection ( float *pFov, const VMatrix &proj ) // = xscale*(x/z) + xoffset (I flipped the signs of both sides) // => (+-1 - xoffset)/xscale = x/z // ...and x/z is tan(theta), and theta is the half-FOV. - */ float fov_px = 2.0f * RAD2DEG ( atanf ( fabsf ( ( 1.0f - xoffset ) / xscale ) ) ); float fov_nx = 2.0f * RAD2DEG ( atanf ( fabsf ( ( -1.0f - xoffset ) / xscale ) ) ); diff --git a/game/client/cliententitylist.cpp b/game/client/cliententitylist.cpp index 2f983e62..294d4ff1 100644 --- a/game/client/cliententitylist.cpp +++ b/game/client/cliententitylist.cpp @@ -354,67 +354,6 @@ void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) } -#if defined( STAGING_ONLY ) - -// Defined in tier1 / interface.cpp for Windows and native for POSIX platforms. -extern "C" int backtrace( void **buffer, int size ); - -static struct -{ - int entnum; - float time; - C_BaseEntity *pBaseEntity; - void *backtrace_addrs[ 16 ]; -} g_RemoveEntityBacktraces[ 1024 ]; -static uint32 g_RemoveEntityBacktracesIndex = 0; - -static void OnRemoveEntityBacktraceHook( int entnum, C_BaseEntity *pBaseEntity ) -{ - int index = g_RemoveEntityBacktracesIndex++; - if ( g_RemoveEntityBacktracesIndex >= ARRAYSIZE( g_RemoveEntityBacktraces ) ) - g_RemoveEntityBacktracesIndex = 0; - - g_RemoveEntityBacktraces[ index ].entnum = entnum; - g_RemoveEntityBacktraces[ index ].time = gpGlobals->curtime; - g_RemoveEntityBacktraces[ index ].pBaseEntity = pBaseEntity; - - memset( g_RemoveEntityBacktraces[ index ].backtrace_addrs, 0, sizeof( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); - backtrace( g_RemoveEntityBacktraces[ index ].backtrace_addrs, ARRAYSIZE( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); -} - -// Should help us track down CL_PreserveExistingEntity Host_Error() issues: -// 1. Set cl_removeentity_backtrace_capture to 1. -// 2. When error hits, run "cl_removeentity_backtrace_dump [entnum]". -// 3. In debugger, track down what functions the spewed addresses refer to. -static ConVar cl_removeentity_backtrace_capture( "cl_removeentity_backtrace_capture", "0", 0, - "For debugging. Capture backtraces for CClientEntityList::OnRemoveEntity calls." ); - -CON_COMMAND( cl_removeentity_backtrace_dump, "Dump backtraces for client OnRemoveEntity calls." ) -{ - if ( !cl_removeentity_backtrace_capture.GetBool() ) - { - Msg( "cl_removeentity_backtrace_dump error: cl_removeentity_backtrace_capture not enabled. Backtraces not captured.\n" ); - return; - } - - int entnum = ( args.ArgC() >= 2 ) ? atoi( args[ 1 ] ) : -1; - - for ( int i = 0; i < ARRAYSIZE( g_RemoveEntityBacktraces ); i++ ) - { - if ( g_RemoveEntityBacktraces[ i ].time && - ( entnum == -1 || g_RemoveEntityBacktraces[ i ].entnum == entnum ) ) - { - Msg( "%d: time:%.2f pBaseEntity:%p\n", g_RemoveEntityBacktraces[i].entnum, - g_RemoveEntityBacktraces[ i ].time, g_RemoveEntityBacktraces[ i ].pBaseEntity ); - for ( int j = 0; j < ARRAYSIZE( g_RemoveEntityBacktraces[ i ].backtrace_addrs ); j++ ) - { - Msg( " %p\n", g_RemoveEntityBacktraces[ i ].backtrace_addrs[ j ] ); - } - } - } -} - -#endif // STAGING_ONLY void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) { @@ -441,13 +380,6 @@ void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); -#if defined( STAGING_ONLY ) - if ( cl_removeentity_backtrace_capture.GetBool() ) - { - OnRemoveEntityBacktraceHook( entnum, pBaseEntity ); - } -#endif // STAGING_ONLY - if ( pBaseEntity ) { if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) @@ -570,4 +502,4 @@ C_BaseEntity* C_BaseEntityIterator::Next() } return NULL; -} +} \ No newline at end of file diff --git a/game/client/clientleafsystem.cpp b/game/client/clientleafsystem.cpp index fa3a0097..03d36cd5 100644 --- a/game/client/clientleafsystem.cpp +++ b/game/client/clientleafsystem.cpp @@ -189,12 +189,12 @@ class CClientLeafSystem : public IClientLeafSystem, public ISpatialLeafEnumerato void RemoveShadowFromLeaves( ClientLeafShadowHandle_t handle ); // Methods associated with the various bi-directional sets - static unsigned int& FirstRenderableInLeaf( int leaf ) + static unsigned short& FirstRenderableInLeaf( int leaf ) { return s_ClientLeafSystem.m_Leaf[leaf].m_FirstElement; } - static unsigned int& FirstLeafInRenderable( unsigned short renderable ) + static unsigned short& FirstLeafInRenderable( unsigned short renderable ) { return s_ClientLeafSystem.m_Renderables[renderable].m_LeafList; } @@ -248,8 +248,8 @@ class CClientLeafSystem : public IClientLeafSystem, public ISpatialLeafEnumerato int m_RenderFrame2; int m_EnumCount; // Have I been added to a particular shadow yet? int m_TranslucencyCalculated; - unsigned int m_LeafList; // What leafs is it in? - unsigned int m_RenderLeaf; // What leaf do I render in? + unsigned short m_LeafList; // What leafs is it in? + unsigned short m_RenderLeaf; // What leaf do I render in? unsigned char m_Flags; // rendering flags unsigned char m_RenderGroup; // RenderGroup_t type unsigned short m_FirstShadow; // The first shadow caster that cast on it @@ -260,7 +260,7 @@ class CClientLeafSystem : public IClientLeafSystem, public ISpatialLeafEnumerato // The leaf contains an index into a list of renderables struct ClientLeaf_t { - unsigned int m_FirstElement; + unsigned short m_FirstElement; unsigned short m_FirstShadow; unsigned short m_FirstDetailProp; @@ -302,7 +302,7 @@ class CClientLeafSystem : public IClientLeafSystem, public ISpatialLeafEnumerato CUtlLinkedList< ShadowInfo_t, ClientLeafShadowHandle_t, false, unsigned int > m_Shadows; // Maintains the list of all renderables in a particular leaf - CBidirectionalSet< int, ClientRenderHandle_t, unsigned int, unsigned int > m_RenderablesInLeaf; + CBidirectionalSet< int, ClientRenderHandle_t, unsigned short, unsigned int > m_RenderablesInLeaf; // Maintains a list of all shadows in a particular leaf CBidirectionalSet< int, ClientLeafShadowHandle_t, unsigned short, unsigned int > m_ShadowsInLeaf; @@ -343,8 +343,7 @@ void DefaultRenderBoundsWorldspace( IClientRenderable *pRenderable, Vector &absM { // Tracker 37433: This fixes a bug where if the stunstick is being wielded by a combine soldier, the fact that the stick was // attached to the soldier's hand would move it such that it would get frustum culled near the edge of the screen. - IClientUnknown *pUnk = pRenderable->GetIClientUnknown(); - C_BaseEntity *pEnt = pUnk->GetBaseEntity(); + C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity(); if ( pEnt && pEnt->IsFollowingEntity() ) { C_BaseEntity *pParent = pEnt->GetFollowedEntity(); @@ -630,7 +629,7 @@ void CClientLeafSystem::NewRenderable( IClientRenderable* pRenderable, RenderGro info.m_Flags = flags; info.m_RenderGroup = (unsigned char)type; info.m_EnumCount = 0; - info.m_RenderLeaf = m_RenderablesInLeaf.InvalidIndex(); + info.m_RenderLeaf = 0xFFFF; if ( IsViewModelRenderGroup( (RenderGroup_t)info.m_RenderGroup ) ) { AddToViewModelList( handle ); @@ -987,7 +986,7 @@ void CClientLeafSystem::AddShadowToLeaf( int leaf, ClientLeafShadowHandle_t shad m_ShadowsInLeaf.AddElementToBucket( leaf, shadow ); // Add the shadow exactly once to all renderables in the leaf - unsigned int i = m_RenderablesInLeaf.FirstElement( leaf ); + unsigned short i = m_RenderablesInLeaf.FirstElement( leaf ); while ( i != m_RenderablesInLeaf.InvalidIndex() ) { ClientRenderHandle_t renderable = m_RenderablesInLeaf.Element(i); @@ -1093,54 +1092,7 @@ void CClientLeafSystem::AddRenderableToLeaf( int leaf, ClientRenderHandle_t rend #ifdef VALIDATE_CLIENT_LEAF_SYSTEM m_RenderablesInLeaf.ValidateAddElementToBucket( leaf, renderable ); #endif - -#ifdef DUMP_RENDERABLE_LEAFS - static uint32 count = 0; - if (count < m_RenderablesInLeaf.NumAllocated()) - { - count = m_RenderablesInLeaf.NumAllocated(); - Msg("********** frame: %d count:%u ***************\n", gpGlobals->framecount, count ); - - if (count >= 20000) - { - for (int j = 0; j < m_RenderablesInLeaf.NumAllocated(); j++) - { - const ClientRenderHandle_t& renderable = m_RenderablesInLeaf.Element(j); - RenderableInfo_t& info = m_Renderables[renderable]; - - char pTemp[256]; - const char *pClassName = ""; - C_BaseEntity *pEnt = info.m_pRenderable->GetIClientUnknown()->GetBaseEntity(); - if ( pEnt ) - { - pClassName = pEnt->GetClassname(); - } - else - { - CNewParticleEffect *pEffect = dynamic_cast< CNewParticleEffect*>( info.m_pRenderable ); - if ( pEffect ) - { - Vector mins, maxs; - pEffect->GetRenderBounds(mins, maxs); - Q_snprintf( pTemp, sizeof(pTemp), "ps: %s %.2f,%.2f", pEffect->GetEffectName(), maxs.x - mins.x, maxs.y - mins.y ); - pClassName = pTemp; - } - else if ( dynamic_cast< CParticleEffectBinding* >( info.m_pRenderable ) ) - { - pClassName = ""; - } - } - - Msg(" %d: %p group:%d %s %d %d TransCalc:%d renderframe:%d\n", j, info.m_pRenderable, info.m_RenderGroup, pClassName, - info.m_LeafList, info.m_RenderLeaf, info.m_TranslucencyCalculated, info.m_RenderFrame); - } - - DebuggerBreak(); - } - } -#endif // DUMP_RENDERABLE_LEAFS - - m_RenderablesInLeaf.AddElementToBucket(leaf, renderable); + m_RenderablesInLeaf.AddElementToBucket( leaf, renderable ); if ( !ShouldRenderableReceiveShadow( renderable, SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK ) ) return; @@ -1392,7 +1344,7 @@ void CClientLeafSystem::ComputeTranslucentRenderLeaf( int count, const LeafIndex orderedList.AddToTail( LeafToMarker( leaf ) ); // iterate over all elements in this leaf - unsigned int idx = m_RenderablesInLeaf.FirstElement(leaf); + unsigned short idx = m_RenderablesInLeaf.FirstElement(leaf); while (idx != m_RenderablesInLeaf.InvalidIndex()) { RenderableInfo_t& info = m_Renderables[m_RenderablesInLeaf.Element(idx)]; @@ -1481,10 +1433,12 @@ inline void AddRenderableToRenderList( CClientRenderablesList &renderList, IClie pEntry->m_RenderHandle = renderHandle; curCount++; } +#ifndef MAPBASE // According to ficool2, this message can cause significant lag else { engine->Con_NPrintf( 10, "Warning: overflowed CClientRenderablesList group %d", group ); } +#endif } @@ -1560,7 +1514,7 @@ void CClientLeafSystem::CollateRenderablesInLeaf( int leaf, int worldListLeafInd AddRenderableToRenderList( *info.m_pRenderList, NULL, worldListLeafIndex, RENDER_GROUP_OPAQUE_ENTITY, NULL ); // Collate everything. - unsigned int idx = m_RenderablesInLeaf.FirstElement(leaf); + unsigned short idx = m_RenderablesInLeaf.FirstElement(leaf); for ( ;idx != m_RenderablesInLeaf.InvalidIndex(); idx = m_RenderablesInLeaf.NextElement(idx) ) { ClientRenderHandle_t handle = m_RenderablesInLeaf.Element(idx); diff --git a/game/client/clientleafsystem.h b/game/client/clientleafsystem.h index dd48ec0b..5caa8914 100644 --- a/game/client/clientleafsystem.h +++ b/game/client/clientleafsystem.h @@ -52,7 +52,11 @@ class CClientRenderablesList : public CRefCounted<> public: enum { +#ifdef MAPBASE + MAX_GROUP_ENTITIES = 16834 // According to ficool2, this limit is bogus/not enforced by the engine and can be "safely" raised. +#else MAX_GROUP_ENTITIES = 4096 +#endif }; struct CEntry diff --git a/game/client/clientmode_shared.cpp b/game/client/clientmode_shared.cpp index 622208a4..f2e6e31d 100644 --- a/game/client/clientmode_shared.cpp +++ b/game/client/clientmode_shared.cpp @@ -36,6 +36,7 @@ #include #include "hud_vote.h" #include "ienginevgui.h" +#include "viewpostprocess.h" #include "sourcevr/isourcevirtualreality.h" #if defined( _X360 ) #include "xbox/xbox_console.h" @@ -65,6 +66,10 @@ extern ConVar replay_rendersetting_renderglow; #include "econ_item_description.h" #endif +#ifdef GLOWS_ENABLE +#include "clienteffectprecachesystem.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -77,6 +82,9 @@ class CHudVote; static vgui::HContext s_hVGuiContext = DEFAULT_VGUI_CONTEXT; ConVar cl_drawhud( "cl_drawhud", "1", FCVAR_CHEAT, "Enable the rendering of the hud" ); +#ifdef DEMO_AUTORECORD +ConVar cl_autorecord("cl_autorecord", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Start recording demos automatically with an incremental name based on this value."); +#endif ConVar hud_takesshots( "hud_takesshots", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Auto-save a scoreboard screenshot at the end of a map." ); ConVar hud_freezecamhide( "hud_freezecamhide", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Hide the HUD during freeze-cam" ); ConVar cl_show_num_particle_systems( "cl_show_num_particle_systems", "0", FCVAR_CLIENTDLL, "Display the number of active particle systems." ); @@ -85,12 +93,13 @@ extern ConVar v_viewmodel_fov; extern ConVar voice_modenable; extern bool IsInCommentaryMode( void ); -extern const char* GetWearLocalizationString( float flWear ); -CON_COMMAND( cl_reload_localization_files, "Reloads all localization files" ) -{ - g_pVGuiLocalize->ReloadLocalizationFiles(); -} +#ifdef GLOWS_ENABLE +CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffectsGlow ) +CLIENTEFFECT_MATERIAL( "dev/glow_color" ) +CLIENTEFFECT_MATERIAL( "dev/halo_add_to_screen" ) +CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 ) +#endif #ifdef VOICE_VOX_ENABLE void VoxCallback( IConVar *var, const char *oldString, float oldFloat ) @@ -147,7 +156,7 @@ CON_COMMAND( hud_reloadscheme, "Reloads hud layout and animation scripts." ) if ( !mode ) return; - mode->ReloadScheme(true); + mode->ReloadScheme(); } #ifdef _DEBUG @@ -283,6 +292,12 @@ ClientModeShared::ClientModeShared() m_pWeaponSelection = NULL; m_nRootSize[ 0 ] = m_nRootSize[ 1 ] = -1; +#ifdef MAPBASE // From Alien Swarm SDK + m_pCurrentPostProcessController = NULL; + m_PostProcessLerpTimer.Invalidate(); + m_pCurrentColorCorrection = NULL; +#endif + #if defined( REPLAY_ENABLED ) m_pReplayReminderPanel = NULL; m_flReplayStartRecordTime = 0.0f; @@ -298,14 +313,8 @@ ClientModeShared::~ClientModeShared() delete m_pViewport; } -void ClientModeShared::ReloadScheme( bool flushLowLevel ) +void ClientModeShared::ReloadScheme( void ) { - // Invalidate the global cache first. - if (flushLowLevel) - { - KeyValuesSystem()->InvalidateCache(); - } - m_pViewport->ReloadScheme( "resource/ClientScheme.res" ); ClearKeyValuesCache(); } @@ -347,7 +356,7 @@ void ClientModeShared::Init() Assert( m_pReplayReminderPanel ); #endif - ListenForGameEvent( "player_connect_client" ); + ListenForGameEvent( "player_connect" ); ListenForGameEvent( "player_disconnect" ); ListenForGameEvent( "player_team" ); ListenForGameEvent( "server_cvar" ); @@ -433,7 +442,7 @@ void ClientModeShared::OverrideView( CViewSetup *pSetup ) if( ::input->CAM_IsThirdPerson() ) { - const Vector& cam_ofs = g_ThirdPersonManager.GetCameraOffsetAngles(); + Vector cam_ofs = g_ThirdPersonManager.GetCameraOffsetAngles(); Vector cam_ofs_distance = g_ThirdPersonManager.GetFinalCameraOffset(); cam_ofs_distance *= g_ThirdPersonManager.GetDistanceFraction(); @@ -482,17 +491,8 @@ bool ClientModeShared::ShouldDrawEntity(C_BaseEntity *pEnt) return true; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- bool ClientModeShared::ShouldDrawParticles( ) { -#ifdef TF_CLIENT_DLL - C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer(); - if ( pTFPlayer && !pTFPlayer->ShouldPlayerDrawParticles() ) - return false; -#endif // TF_CLIENT_DLL - return true; } @@ -611,6 +611,8 @@ void ClientModeShared::Update() m_pViewport->SetVisible( cl_drawhud.GetBool() ); } + UpdatePostProcessingEffects(); + UpdateRumbleEffects(); if ( cl_show_num_particle_systems.GetBool() ) @@ -636,6 +638,43 @@ void ClientModeShared::Update() } } +#ifdef MAPBASE // From Alien Swarm SDK +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void ClientModeShared::OnColorCorrectionWeightsReset( void ) +{ + C_ColorCorrection *pNewColorCorrection = NULL; + C_ColorCorrection *pOldColorCorrection = m_pCurrentColorCorrection; + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pPlayer ) + { + pNewColorCorrection = pPlayer->GetActiveColorCorrection(); + } + + if ( pNewColorCorrection != pOldColorCorrection ) + { + if ( pOldColorCorrection ) + { + pOldColorCorrection->EnableOnClient( false ); + } + if ( pNewColorCorrection ) + { + pNewColorCorrection->EnableOnClient( true, pOldColorCorrection == NULL ); + } + m_pCurrentColorCorrection = pNewColorCorrection; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float ClientModeShared::GetColorCorrectionScale( void ) const +{ + return 1.0f; +} +#endif + //----------------------------------------------------------------------------- // This processes all input before SV Move messages are sent //----------------------------------------------------------------------------- @@ -782,6 +821,10 @@ int ClientModeShared::HudElementKeyInput( int down, ButtonCode_t keynum, const c //----------------------------------------------------------------------------- bool ClientModeShared::DoPostScreenSpaceEffects( const CViewSetup *pSetup ) { +#ifdef GLOWS_ENABLE + g_GlowObjectManager.RenderGlowEffects( pSetup, 0 ); +#endif + #if defined( REPLAY_ENABLED ) if ( engine->IsPlayingDemo() ) { @@ -851,8 +894,54 @@ void ClientModeShared::LevelInit( const char *newmap ) // Reset any player explosion/shock effects CLocalPlayerFilter filter; enginesound->SetPlayerDSP( filter, 0, true ); + +#ifdef DEMO_AUTORECORD + AutoRecord(newmap); +#endif } +#ifdef DEMO_AUTORECORD +void ClientModeShared::AutoRecord(const char *map) +{ + if (!cl_autorecord.GetBool()) { + return; + } + + if (map == nullptr) { + Warning("null map in ClientModeShared::AutoRecord"); + return; + } + + // stop any demo to make sure they're saved + engine->ClientCmd("stop"); + + // KLEMS: sanitize space in client name because having to type "" while playing back lots of demos is annoying + ConVarRef name("name"); + char nameStr[128]; + memset(nameStr, 0, sizeof(nameStr)); + Q_snprintf(nameStr, sizeof(nameStr), "%s", name.GetString()); + int i = 0; + while (nameStr[i]) { + char c = nameStr[i]; + if (!( (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z'))) { + nameStr[i] = '_'; + } + i++; + } + nameStr[127] = 0; + + char cmd[256]; + Q_snprintf(cmd, sizeof(cmd), "record \"%s_%04d_%s\"", nameStr, cl_autorecord.GetInt(), map); + cl_autorecord.SetValue(cl_autorecord.GetInt() + 1); + engine->ClientCmd(cmd); + + // write to config to make sure the cvar is recorded + engine->ClientCmd("host_writeconfig"); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -871,6 +960,17 @@ void ClientModeShared::LevelShutdown( void ) s_hVGuiContext = DEFAULT_VGUI_CONTEXT; } +#ifdef MAPBASE + // Always reset post-processing on level unload + //if (m_pCurrentPostProcessController) + { + m_CurrentPostProcessParameters = PostProcessParameters_t(); + m_LerpEndPostProcessParameters = PostProcessParameters_t(); + m_pCurrentPostProcessController = NULL; + SetPostProcessParams( &m_CurrentPostProcessParameters ); + } +#endif + // Reset any player explosion/shock effects CLocalPlayerFilter filter; enginesound->SetPlayerDSP( filter, 0, true ); @@ -879,7 +979,7 @@ void ClientModeShared::LevelShutdown( void ) void ClientModeShared::Enable() { - vgui::VPANEL pRoot = VGui_GetClientDLLRootPanel(); + vgui::VPANEL pRoot = VGui_GetClientDLLRootPanel();; // Add our viewport to the root panel. if( pRoot != 0 ) @@ -906,7 +1006,7 @@ void ClientModeShared::Enable() void ClientModeShared::Disable() { - vgui::VPANEL pRoot = VGui_GetClientDLLRootPanel(); + vgui::VPANEL pRoot = VGui_GetClientDLLRootPanel();; // Remove our viewport from the root panel. if( pRoot != 0 ) @@ -935,7 +1035,7 @@ void ClientModeShared::Layout() m_pViewport->SetBounds(0, 0, wide, tall); if ( changed ) { - ReloadScheme(false); + ReloadScheme(); } } } @@ -945,6 +1045,69 @@ float ClientModeShared::GetViewModelFOV( void ) return v_viewmodel_fov.GetFloat(); } +#ifdef MAPBASE +extern bool g_bPostProcessNeedsRestore; +#endif + +void ClientModeShared::UpdatePostProcessingEffects() +{ + C_PostProcessController* pNewPostProcessController = NULL; + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + + if (pPlayer) + pNewPostProcessController = pPlayer->GetActivePostProcessController(); + + if (!pNewPostProcessController) + { + m_CurrentPostProcessParameters = PostProcessParameters_t(); + m_pCurrentPostProcessController = NULL; + SetPostProcessParams( &m_CurrentPostProcessParameters ); + return; + } + + if (pNewPostProcessController != m_pCurrentPostProcessController) + m_pCurrentPostProcessController = pNewPostProcessController; + + // Start a lerp timer if the parameters changed, regardless of whether the controller changed + if (m_LerpEndPostProcessParameters != pNewPostProcessController->m_PostProcessParameters) + { + m_LerpStartPostProcessParameters = m_CurrentPostProcessParameters; + m_LerpEndPostProcessParameters = pNewPostProcessController ? pNewPostProcessController->m_PostProcessParameters : m_CurrentPostProcessParameters; + + float flFadeTime = pNewPostProcessController ? pNewPostProcessController->m_PostProcessParameters.m_flParameters[PPPN_FADE_TIME] : 0.0f; + if (flFadeTime <= 0.0f) + { + flFadeTime = 0.001f; + } + + m_PostProcessLerpTimer.Start( flFadeTime ); + } +#ifdef MAPBASE + // HACKHACK: Needs to be checked here because OnRestore() doesn't seem to run before a lerp begins + else if (g_bPostProcessNeedsRestore) + { + // The player just loaded a saved game. + // Don't fade parameters from 0; instead, take what's already there and assume they were already active. + // (we have no way of knowing if they were in the middle of a lerp) + m_PostProcessLerpTimer.Invalidate(); + g_bPostProcessNeedsRestore = false; + } +#endif + + // Lerp between old and new parameters + float flLerpFactor = 1.0f - m_PostProcessLerpTimer.GetRemainingRatio(); + for (int nParameter = 0; nParameter < POST_PROCESS_PARAMETER_COUNT; ++nParameter) + { + m_CurrentPostProcessParameters.m_flParameters[nParameter] = + Lerp( + flLerpFactor, + m_LerpStartPostProcessParameters.m_flParameters[nParameter], + m_LerpEndPostProcessParameters.m_flParameters[nParameter] ); + } + + SetPostProcessParams( &m_CurrentPostProcessParameters ); +} + class CHudChat; bool PlayerNameNotSetYet( const char *pszName ) @@ -967,7 +1130,7 @@ void ClientModeShared::FireGameEvent( IGameEvent *event ) const char *eventname = event->GetName(); - if ( Q_strcmp( "player_connect_client", eventname ) == 0 ) + if ( Q_strcmp( "player_connect", eventname ) == 0 ) { if ( !hudChat ) return; @@ -1127,7 +1290,7 @@ void ClientModeShared::FireGameEvent( IGameEvent *event ) { CBasePlayer *pSpectatorTarget = UTIL_PlayerByIndex( GetSpectatorTarget() ); - if ( pSpectatorTarget && (GetSpectatorMode() == OBS_MODE_IN_EYE || GetSpectatorMode() == OBS_MODE_CHASE || GetSpectatorMode() == OBS_MODE_POI) ) + if ( pSpectatorTarget && (GetSpectatorMode() == OBS_MODE_IN_EYE || GetSpectatorMode() == OBS_MODE_CHASE) ) { if ( pSpectatorTarget->GetTeamNumber() == team ) { @@ -1136,7 +1299,7 @@ void ClientModeShared::FireGameEvent( IGameEvent *event ) } } - if ( team == 0 && GetLocalTeam() > 0 ) + if ( team == 0 && GetLocalTeam() ) { bValidTeam = false; } @@ -1234,14 +1397,10 @@ void ClientModeShared::FireGameEvent( IGameEvent *event ) entityquality_t iItemQuality = event->GetInt( "quality" ); int iMethod = event->GetInt( "method" ); int iItemDef = event->GetInt( "itemdef" ); - bool bIsStrange = event->GetInt( "isstrange" ); - bool bIsUnusual = event->GetInt( "isunusual" ); - float flWear = event->GetFloat( "wear" ); - C_BasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex ); const GameItemDefinition_t *pItemDefinition = dynamic_cast( GetItemSchema()->GetItemDefinition( iItemDef ) ); - if ( !pPlayer || !pItemDefinition || pItemDefinition->IsHidden() ) + if ( !pPlayer || !pItemDefinition ) return; if ( g_PR ) @@ -1261,101 +1420,19 @@ void ClientModeShared::FireGameEvent( IGameEvent *event ) _snwprintf( wszItemFound, ARRAYSIZE( wszItemFound ), L"%ls", g_pVGuiLocalize->Find( pszLocString ) ); wchar_t *colorMarker = wcsstr( wszItemFound, L"::" ); - const CEconItemRarityDefinition* pItemRarity = GetItemSchema()->GetRarityDefinition( pItemDefinition->GetRarity() ); - if ( colorMarker ) - { - if ( pItemRarity ) - { - attrib_colors_t colorRarity = pItemRarity->GetAttribColor(); - vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme ); - Color color = pScheme->GetColor( GetColorNameForAttribColor( colorRarity ), Color( 255, 255, 255, 255 ) ); - hudChat->SetCustomColor( color ); - } - else + { + const char *pszQualityColorString = EconQuality_GetColorString( (EEconItemQuality)iItemQuality ); + if ( pszQualityColorString ) { - const char *pszQualityColorString = EconQuality_GetColorString( (EEconItemQuality)iItemQuality ); - if ( pszQualityColorString ) - { - hudChat->SetCustomColor( pszQualityColorString ); - } + hudChat->SetCustomColor( pszQualityColorString ); + *(colorMarker+1) = COLOR_CUSTOM; } - - *(colorMarker+1) = COLOR_CUSTOM; } // TODO: Update the localization strings to only have two format parameters since that's all we need. wchar_t wszLocalizedString[256]; - g_pVGuiLocalize->ConstructString( - wszLocalizedString, - sizeof( wszLocalizedString ), - LOCCHAR( "%s1" ), - 1, - CEconItemLocalizedFullNameGenerator( GLocalizationProvider(), pItemDefinition, iItemQuality ).GetFullName() - ); - - locchar_t tempName[MAX_ITEM_NAME_LENGTH]; - if ( pItemRarity ) - { - // grade and Wear - loc_scpy_safe( tempName, wszLocalizedString ); - - const locchar_t *loc_WearText = LOCCHAR(""); - const char *pszTooltipText = "TFUI_InvTooltip_Rarity"; - - if ( !IsWearableSlot( pItemDefinition->GetDefaultLoadoutSlot() ) ) - { - loc_WearText = g_pVGuiLocalize->Find( GetWearLocalizationString( flWear ) ); - } - else - { - pszTooltipText = "TFUI_InvTooltip_RarityNoWear"; - } - - g_pVGuiLocalize->ConstructString( wszLocalizedString, - ARRAYSIZE( wszLocalizedString ) * sizeof( locchar_t ), - g_pVGuiLocalize->Find( pszTooltipText ), - 3, - g_pVGuiLocalize->Find( pItemRarity->GetLocKey() ), - tempName, - loc_WearText - ); - - if ( bIsUnusual ) - { - loc_scpy_safe( tempName, wszLocalizedString ); - - g_pVGuiLocalize->ConstructString( wszLocalizedString, - ARRAYSIZE( wszLocalizedString ) * sizeof( locchar_t ), - LOCCHAR( "%s1 %s2" ), - 2, - g_pVGuiLocalize->Find( "rarity4" ), - tempName - ); - } - - if ( bIsStrange ) - { - loc_scpy_safe( tempName, wszLocalizedString ); - - g_pVGuiLocalize->ConstructString( wszLocalizedString, - ARRAYSIZE( wszLocalizedString ) * sizeof( locchar_t ), - LOCCHAR( "%s1 %s2" ), - 2, - g_pVGuiLocalize->Find( "strange" ), - tempName - ); - } - } - - loc_scpy_safe( tempName, wszLocalizedString ); - g_pVGuiLocalize->ConstructString( - wszLocalizedString, - sizeof( wszLocalizedString ), - wszItemFound, - 3, - wszPlayerName, tempName, L"" ); + g_pVGuiLocalize->ConstructString( wszLocalizedString, sizeof( wszLocalizedString ), wszItemFound, 3, wszPlayerName, CEconItemLocalizedFullNameGenerator( GLocalizationProvider(), pItemDefinition, iItemQuality ).GetFullName(), L"" ); char szLocalized[256]; g_pVGuiLocalize->ConvertUnicodeToANSI( wszLocalizedString, szLocalized, sizeof( szLocalized ) ); diff --git a/game/client/clientmode_shared.h b/game/client/clientmode_shared.h index beef0ad9..20288db8 100644 --- a/game/client/clientmode_shared.h +++ b/game/client/clientmode_shared.h @@ -42,6 +42,10 @@ class CReplayReminderPanel; #define USERID2PLAYER(i) ToBasePlayer( ClientEntityList().GetEnt( engine->GetPlayerForUserID( i ) ) ) +#ifdef MAPBASE +#define DEMO_AUTORECORD 1 +#endif + extern IClientMode *GetClientModeNormal(); // must be implemented // This class implements client mode functionality common to HL2 and TF2. @@ -62,11 +66,15 @@ class ClientModeShared : public IClientMode, public CGameEventListener virtual void LevelInit( const char *newmap ); virtual void LevelShutdown( void ); +#ifdef DEMO_AUTORECORD + virtual void AutoRecord( const char *map ); +#endif + virtual void Enable(); virtual void Disable(); virtual void Layout(); - virtual void ReloadScheme( bool flushLowLevel ); + virtual void ReloadScheme( void ); virtual void OverrideView( CViewSetup *pSetup ); virtual bool ShouldDrawDetailObjects( ); virtual bool ShouldDrawEntity(C_BaseEntity *pEnt); @@ -83,6 +91,11 @@ class ClientModeShared : public IClientMode, public CGameEventListener virtual void ProcessInput(bool bActive); virtual bool CreateMove( float flInputSampleTime, CUserCmd *cmd ); virtual void Update(); +#ifdef MAPBASE // From Alien Swarm SDK + virtual void OnColorCorrectionWeightsReset( void ); + virtual float GetColorCorrectionScale( void ) const; + virtual void ClearCurrentColorCorrection() { m_pCurrentColorCorrection = NULL; } +#endif // Input virtual int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ); @@ -156,6 +169,17 @@ class ClientModeShared : public IClientMode, public CGameEventListener vgui::HCursor m_CursorNone; CBaseHudWeaponSelection *m_pWeaponSelection; int m_nRootSize[2]; + +#ifdef MAPBASE // From Alien Swarm SDK + void UpdatePostProcessingEffects(); + + const C_PostProcessController* m_pCurrentPostProcessController; + PostProcessParameters_t m_CurrentPostProcessParameters; + PostProcessParameters_t m_LerpStartPostProcessParameters, m_LerpEndPostProcessParameters; + CountdownTimer m_PostProcessLerpTimer; + + CHandle m_pCurrentColorCorrection; +#endif }; #endif // CLIENTMODE_NORMAL_H diff --git a/game/client/clientshadowmgr.cpp b/game/client/clientshadowmgr.cpp index f9217315..3a77b048 100644 --- a/game/client/clientshadowmgr.cpp +++ b/game/client/clientshadowmgr.cpp @@ -81,29 +81,61 @@ #include "toolframework_client.h" #include "bonetoworldarray.h" #include "cmodel.h" +#ifdef MAPBASE #include "renderparm.h" -#include "view.h" +#endif +#ifdef ASW_PROJECTED_TEXTURES +#include "flashlighteffect.h" +#endif +#ifdef DYNAMIC_RTT_SHADOWS +#include "debugoverlay_shared.h" +#include "worldlight.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -static ConVar r_flashlightdrawfrustum("r_flashlightdrawfrustum", "0"); -static ConVar r_flashlightmodels("r_flashlightmodels", "1"); -//static ConVar r_shadowrendertotexture("r_shadowrendertotexture", "0"); -static ConVar r_flashlight_version2("r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY); +static ConVar r_flashlightdrawfrustum( "r_flashlightdrawfrustum", "0" ); +static ConVar r_flashlightmodels( "r_flashlightmodels", "1" ); +static ConVar r_shadowrendertotexture( "r_shadowrendertotexture", "0" ); +#ifdef ASW_PROJECTED_TEXTURES +static ConVar r_shadow_lightpos_lerptime( "r_shadow_lightpos_lerptime", "0.5" ); +static ConVar r_shadowfromworldlights_debug( "r_shadowfromworldlights_debug", "0", FCVAR_CHEAT ); +static ConVar r_shadow_shortenfactor( "r_shadow_shortenfactor", "2" , 0, "Makes shadows cast from local lights shorter" ); +static ConVar r_shadow_mincastintensity( "r_shadow_mincastintensity", "0.3", FCVAR_CHEAT, "Minimum brightness of a light to be classed as shadow casting", true, 0, false, 0 ); +#endif +static ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); -ConVar r_flashlightdepthtexture("r_flashlightdepthtexture", "1"); +ConVar r_flashlightdepthtexture( "r_flashlightdepthtexture", "1" ); -ConVar r_flashlightdepthres("r_flashlightdepthres", "512"); +#if defined( _X360 ) +ConVar r_flashlightdepthres( "r_flashlightdepthres", "512" ); +#else +#ifdef MAPBASE +ConVar r_flashlightdepthres( "r_flashlightdepthres", "2048" ); +#else +ConVar r_flashlightdepthres( "r_flashlightdepthres", "1024" ); +#endif +#endif + +#ifdef ASW_PROJECTED_TEXTURES +ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "1" ); +#else +ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "0" ); +#endif -ConVar r_threaded_client_shadow_manager("r_threaded_client_shadow_manager", "0"); +#ifdef MAPBASE +ConVarRef mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap" ); +ConVarRef mat_depthbias_shadowmap( "mat_depthbias_shadowmap" ); +#endif #ifdef _WIN32 #pragma warning( disable: 4701 ) #endif // forward declarations -void ToolFramework_RecordMaterialParams(IMaterial* pMaterial); +void ToolFramework_RecordMaterialParams( IMaterial *pMaterial ); //----------------------------------------------------------------------------- @@ -131,26 +163,26 @@ class CTextureAllocator void DeallocateAllTextures(); // Allocate, deallocate texture - TextureHandle_t AllocateTexture(int w, int h); - void DeallocateTexture(TextureHandle_t h); + TextureHandle_t AllocateTexture( int w, int h ); + void DeallocateTexture( TextureHandle_t h ); // Mark texture as being used... (return true if re-render is needed) - bool UseTexture(TextureHandle_t h, bool bWillRedraw, float flArea); - bool HasValidTexture(TextureHandle_t h); + bool UseTexture( TextureHandle_t h, bool bWillRedraw, float flArea ); + bool HasValidTexture( TextureHandle_t h ); // Advance frame... void AdvanceFrame(); // Get at the location of the texture - void GetTextureRect(TextureHandle_t handle, int& x, int& y, int& w, int& h); + void GetTextureRect(TextureHandle_t handle, int& x, int& y, int& w, int& h ); // Get at the texture it's a part of - ITexture* GetTexture(); - + ITexture *GetTexture(); + // Get at the total texture size. - void GetTotalTextureSize(int& w, int& h); + void GetTotalTextureSize( int& w, int& h ); - void DebugPrintCache(void); + void DebugPrintCache( void ); private: typedef unsigned short FragmentHandle_t; @@ -158,18 +190,18 @@ class CTextureAllocator enum { INVALID_FRAGMENT_HANDLE = (FragmentHandle_t)~0, - TEXTURE_PAGE_SIZE = 1024, - MAX_TEXTURE_POWER = 8, + TEXTURE_PAGE_SIZE = 1024, + MAX_TEXTURE_POWER = 8, #if !defined( _X360 ) - MIN_TEXTURE_POWER = 4, + MIN_TEXTURE_POWER = 4, #else - MIN_TEXTURE_POWER = 5, // per resolve requirements to ensure 32x32 aligned offsets + MIN_TEXTURE_POWER = 5, // per resolve requirements to ensure 32x32 aligned offsets #endif - MAX_TEXTURE_SIZE = (1 << MAX_TEXTURE_POWER), - MIN_TEXTURE_SIZE = (1 << MIN_TEXTURE_POWER), - BLOCK_SIZE = MAX_TEXTURE_SIZE, - BLOCKS_PER_ROW = (TEXTURE_PAGE_SIZE / MAX_TEXTURE_SIZE), - BLOCK_COUNT = (BLOCKS_PER_ROW * BLOCKS_PER_ROW), + MAX_TEXTURE_SIZE = (1 << MAX_TEXTURE_POWER), + MIN_TEXTURE_SIZE = (1 << MIN_TEXTURE_POWER), + BLOCK_SIZE = MAX_TEXTURE_SIZE, + BLOCKS_PER_ROW = (TEXTURE_PAGE_SIZE / MAX_TEXTURE_SIZE), + BLOCK_COUNT = (BLOCKS_PER_ROW * BLOCKS_PER_ROW), }; struct TextureInfo_t @@ -200,22 +232,22 @@ class CTextureAllocator }; // Adds a block worth of fragments to the LRU - void AddBlockToLRU(int block); + void AddBlockToLRU( int block ); // Unlink fragment from cache - void UnlinkFragmentFromCache(Cache_t& cache, FragmentHandle_t fragment); + void UnlinkFragmentFromCache( Cache_t& cache, FragmentHandle_t fragment ); // Mark something as being used (MRU).. - void MarkUsed(FragmentHandle_t fragment); + void MarkUsed( FragmentHandle_t fragment ); // Mark something as being unused (LRU).. - void MarkUnused(FragmentHandle_t fragment); + void MarkUnused( FragmentHandle_t fragment ); // Disconnect texture from fragment - void DisconnectTextureFromFragment(FragmentHandle_t f); + void DisconnectTextureFromFragment( FragmentHandle_t f ); // Returns the size of a particular fragment - int GetFragmentPower(FragmentHandle_t f) const; + int GetFragmentPower( FragmentHandle_t f ) const; // Stores the actual texture we're writing into CTextureReference m_TexturePage; @@ -223,7 +255,7 @@ class CTextureAllocator CUtlLinkedList< TextureInfo_t, TextureHandle_t > m_Textures; CUtlMultiList< FragmentInfo_t, FragmentHandle_t > m_Fragments; - Cache_t m_Cache[MAX_TEXTURE_POWER + 1]; + Cache_t m_Cache[MAX_TEXTURE_POWER+1]; BlockInfo_t m_Blocks[BLOCK_COUNT]; unsigned int m_CurrentFrame; }; @@ -233,26 +265,26 @@ class CTextureAllocator //----------------------------------------------------------------------------- void CTextureAllocator::Init() { - for (int i = 0; i <= MAX_TEXTURE_POWER; ++i) + for ( int i = 0; i <= MAX_TEXTURE_POWER; ++i ) { m_Cache[i].m_List = m_Fragments.InvalidIndex(); } #if !defined( _X360 ) // don't need depth buffer for shadows - m_TexturePage.InitRenderTarget(TEXTURE_PAGE_SIZE, TEXTURE_PAGE_SIZE, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_ARGB8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_Shadows"); + m_TexturePage.InitRenderTarget( TEXTURE_PAGE_SIZE, TEXTURE_PAGE_SIZE, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_ARGB8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_Shadows" ); #else // unfortunate explicit management required for this render target // 32bpp edram is only largest shadow fragment, but resolved to actual shadow atlas // because full-res 1024x1024 shadow buffer is too large for EDRAM - m_TexturePage.InitRenderTargetTexture(TEXTURE_PAGE_SIZE, TEXTURE_PAGE_SIZE, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_ARGB8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_Shadows"); + m_TexturePage.InitRenderTargetTexture( TEXTURE_PAGE_SIZE, TEXTURE_PAGE_SIZE, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_ARGB8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_Shadows" ); // edram footprint is only 256x256x4 = 256K - m_TexturePage.InitRenderTargetSurface(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, IMAGE_FORMAT_ARGB8888, false); + m_TexturePage.InitRenderTargetSurface( MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, IMAGE_FORMAT_ARGB8888, false ); // due to texture/surface size mismatch, ensure texture page is entirely cleared translucent // otherwise border artifacts at edge of shadows due to pixel shader averaging of unwanted bits - m_TexturePage->ClearTexture(0, 0, 0, 0); + m_TexturePage->ClearTexture( 0, 0, 0, 0 ); #endif } @@ -275,21 +307,21 @@ void CTextureAllocator::Reset() // Set up the block sizes.... // FIXME: Improve heuristic?!? #if !defined( _X360 ) - m_Blocks[0].m_FragmentPower = MAX_TEXTURE_POWER - 4; // 128 cells at ExE resolution + m_Blocks[0].m_FragmentPower = MAX_TEXTURE_POWER-4; // 128 cells at ExE resolution #else - m_Blocks[0].m_FragmentPower = MAX_TEXTURE_POWER - 3; // 64 cells at DxD resolution + m_Blocks[0].m_FragmentPower = MAX_TEXTURE_POWER-3; // 64 cells at DxD resolution #endif - m_Blocks[1].m_FragmentPower = MAX_TEXTURE_POWER - 3; // 64 cells at DxD resolution - m_Blocks[2].m_FragmentPower = MAX_TEXTURE_POWER - 2; // 32 cells at CxC resolution - m_Blocks[3].m_FragmentPower = MAX_TEXTURE_POWER - 2; - m_Blocks[4].m_FragmentPower = MAX_TEXTURE_POWER - 1; // 24 cells at BxB resolution - m_Blocks[5].m_FragmentPower = MAX_TEXTURE_POWER - 1; - m_Blocks[6].m_FragmentPower = MAX_TEXTURE_POWER - 1; - m_Blocks[7].m_FragmentPower = MAX_TEXTURE_POWER - 1; - m_Blocks[8].m_FragmentPower = MAX_TEXTURE_POWER - 1; - m_Blocks[9].m_FragmentPower = MAX_TEXTURE_POWER - 1; + m_Blocks[1].m_FragmentPower = MAX_TEXTURE_POWER-3; // 64 cells at DxD resolution + m_Blocks[2].m_FragmentPower = MAX_TEXTURE_POWER-2; // 32 cells at CxC resolution + m_Blocks[3].m_FragmentPower = MAX_TEXTURE_POWER-2; + m_Blocks[4].m_FragmentPower = MAX_TEXTURE_POWER-1; // 24 cells at BxB resolution + m_Blocks[5].m_FragmentPower = MAX_TEXTURE_POWER-1; + m_Blocks[6].m_FragmentPower = MAX_TEXTURE_POWER-1; + m_Blocks[7].m_FragmentPower = MAX_TEXTURE_POWER-1; + m_Blocks[8].m_FragmentPower = MAX_TEXTURE_POWER-1; + m_Blocks[9].m_FragmentPower = MAX_TEXTURE_POWER-1; m_Blocks[10].m_FragmentPower = MAX_TEXTURE_POWER; // 6 cells at AxA resolution - m_Blocks[11].m_FragmentPower = MAX_TEXTURE_POWER; + m_Blocks[11].m_FragmentPower = MAX_TEXTURE_POWER; m_Blocks[12].m_FragmentPower = MAX_TEXTURE_POWER; m_Blocks[13].m_FragmentPower = MAX_TEXTURE_POWER; m_Blocks[14].m_FragmentPower = MAX_TEXTURE_POWER; @@ -297,16 +329,16 @@ void CTextureAllocator::Reset() // Initialize the LRU int i; - for (i = 0; i <= MAX_TEXTURE_POWER; ++i) + for ( i = 0; i <= MAX_TEXTURE_POWER; ++i ) { m_Cache[i].m_List = m_Fragments.CreateList(); } // Now that the block sizes are allocated, create LRUs for the various block sizes - for (i = 0; i < BLOCK_COUNT; ++i) + for ( i = 0; i < BLOCK_COUNT; ++i) { // Initialize LRU - AddBlockToLRU(i); + AddBlockToLRU( i ); } m_CurrentFrame = 0; @@ -316,7 +348,7 @@ void CTextureAllocator::DeallocateAllTextures() { m_Textures.Purge(); m_Fragments.Purge(); - for (int i = 0; i <= MAX_TEXTURE_POWER; ++i) + for ( int i = 0; i <= MAX_TEXTURE_POWER; ++i ) { m_Cache[i].m_List = m_Fragments.InvalidIndex(); } @@ -326,7 +358,7 @@ void CTextureAllocator::DeallocateAllTextures() //----------------------------------------------------------------------------- // Dump the state of the cache to debug out //----------------------------------------------------------------------------- -void CTextureAllocator::DebugPrintCache(void) +void CTextureAllocator::DebugPrintCache( void ) { // For each fragment int nNumFragments = m_Fragments.TotalCount(); @@ -334,20 +366,20 @@ void CTextureAllocator::DebugPrintCache(void) Warning("Fragments (%d):\n===============\n", nNumFragments); - for (int f = 0; f < nNumFragments; f++) + for ( int f = 0; f < nNumFragments; f++ ) { - if ((m_Fragments[f].m_FrameUsed != 0) && (m_Fragments[f].m_Texture != INVALID_TEXTURE_HANDLE)) - Warning("Fragment %d, Block: %d, Index: %d, Texture: %d Frame Used: %d\n", f, m_Fragments[f].m_Block, m_Fragments[f].m_Index, m_Fragments[f].m_Texture, m_Fragments[f].m_FrameUsed); + if ( ( m_Fragments[f].m_FrameUsed != 0 ) && ( m_Fragments[f].m_Texture != INVALID_TEXTURE_HANDLE ) ) + Warning("Fragment %d, Block: %d, Index: %d, Texture: %d Frame Used: %d\n", f, m_Fragments[f].m_Block, m_Fragments[f].m_Index, m_Fragments[f].m_Texture, m_Fragments[f].m_FrameUsed ); else nNumInvalidFragments++; } Warning("Invalid Fragments: %d\n", nNumInvalidFragments); - // for ( int c = 0; c <= MAX_TEXTURE_POWER; ++c ) - // { - // Warning("Cache Index (%d)\n", m_Cache[c].m_List); - // } +// for ( int c = 0; c <= MAX_TEXTURE_POWER; ++c ) +// { +// Warning("Cache Index (%d)\n", m_Cache[c].m_List); +// } } @@ -355,10 +387,10 @@ void CTextureAllocator::DebugPrintCache(void) //----------------------------------------------------------------------------- // Adds a block worth of fragments to the LRU //----------------------------------------------------------------------------- -void CTextureAllocator::AddBlockToLRU(int block) +void CTextureAllocator::AddBlockToLRU( int block ) { int power = m_Blocks[block].m_FragmentPower; - int size = (1 << power); + int size = (1 << power); // Compute the number of fragments in this block int fragmentCount = MAX_TEXTURE_SIZE / size; @@ -366,14 +398,14 @@ void CTextureAllocator::AddBlockToLRU(int block) // For each fragment, indicate which block it's a part of (and the index) // and then stick in at the top of the LRU - while (--fragmentCount >= 0) + while (--fragmentCount >= 0 ) { - FragmentHandle_t f = m_Fragments.Alloc(); + FragmentHandle_t f = m_Fragments.Alloc( ); m_Fragments[f].m_Block = block; m_Fragments[f].m_Index = fragmentCount; m_Fragments[f].m_Texture = INVALID_TEXTURE_HANDLE; m_Fragments[f].m_FrameUsed = 0xFFFFFFFF; - m_Fragments.LinkToHead(m_Cache[power].m_List, f); + m_Fragments.LinkToHead( m_Cache[power].m_List, f ); } } @@ -381,23 +413,23 @@ void CTextureAllocator::AddBlockToLRU(int block) //----------------------------------------------------------------------------- // Unlink fragment from cache //----------------------------------------------------------------------------- -void CTextureAllocator::UnlinkFragmentFromCache(Cache_t& cache, FragmentHandle_t fragment) +void CTextureAllocator::UnlinkFragmentFromCache( Cache_t& cache, FragmentHandle_t fragment ) { - m_Fragments.Unlink(cache.m_List, fragment); + m_Fragments.Unlink( cache.m_List, fragment); } //----------------------------------------------------------------------------- // Mark something as being used (MRU).. //----------------------------------------------------------------------------- -void CTextureAllocator::MarkUsed(FragmentHandle_t fragment) +void CTextureAllocator::MarkUsed( FragmentHandle_t fragment ) { int block = m_Fragments[fragment].m_Block; int power = m_Blocks[block].m_FragmentPower; // Hook it at the end of the LRU Cache_t& cache = m_Cache[power]; - m_Fragments.LinkToTail(cache.m_List, fragment); + m_Fragments.LinkToTail( cache.m_List, fragment ); m_Fragments[fragment].m_FrameUsed = m_CurrentFrame; } @@ -405,24 +437,24 @@ void CTextureAllocator::MarkUsed(FragmentHandle_t fragment) //----------------------------------------------------------------------------- // Mark something as being unused (LRU).. //----------------------------------------------------------------------------- -void CTextureAllocator::MarkUnused(FragmentHandle_t fragment) +void CTextureAllocator::MarkUnused( FragmentHandle_t fragment ) { int block = m_Fragments[fragment].m_Block; int power = m_Blocks[block].m_FragmentPower; // Hook it at the end of the LRU Cache_t& cache = m_Cache[power]; - m_Fragments.LinkToHead(cache.m_List, fragment); + m_Fragments.LinkToHead( cache.m_List, fragment ); } //----------------------------------------------------------------------------- // Allocate, deallocate texture //----------------------------------------------------------------------------- -TextureHandle_t CTextureAllocator::AllocateTexture(int w, int h) +TextureHandle_t CTextureAllocator::AllocateTexture( int w, int h ) { // Implementational detail for now - Assert(w == h); + Assert( w == h ); // Clamp texture size if (w < MIN_TEXTURE_SIZE) @@ -437,43 +469,43 @@ TextureHandle_t CTextureAllocator::AllocateTexture(int w, int h) // Find the power of two int power = 0; int size = 1; - while (size < w) + while(size < w) { size <<= 1; ++power; } - Assert(size == w); + Assert( size == w ); m_Textures[handle].m_Power = power; return handle; } -void CTextureAllocator::DeallocateTexture(TextureHandle_t h) +void CTextureAllocator::DeallocateTexture( TextureHandle_t h ) { - // Warning("Beginning of DeallocateTexture\n"); - // DebugPrintCache(); +// Warning("Beginning of DeallocateTexture\n"); +// DebugPrintCache(); if (m_Textures[h].m_Fragment != INVALID_FRAGMENT_HANDLE) { MarkUnused(m_Textures[h].m_Fragment); m_Fragments[m_Textures[h].m_Fragment].m_FrameUsed = 0xFFFFFFFF; // non-zero frame - DisconnectTextureFromFragment(m_Textures[h].m_Fragment); + DisconnectTextureFromFragment( m_Textures[h].m_Fragment ); } m_Textures.Remove(h); - // Warning("End of DeallocateTexture\n"); - // DebugPrintCache(); +// Warning("End of DeallocateTexture\n"); +// DebugPrintCache(); } //----------------------------------------------------------------------------- // Disconnect texture from fragment //----------------------------------------------------------------------------- -void CTextureAllocator::DisconnectTextureFromFragment(FragmentHandle_t f) +void CTextureAllocator::DisconnectTextureFromFragment( FragmentHandle_t f ) { - // Warning( "Beginning of DisconnectTextureFromFragment\n" ); - // DebugPrintCache(); +// Warning( "Beginning of DisconnectTextureFromFragment\n" ); +// DebugPrintCache(); FragmentInfo_t& info = m_Fragments[f]; if (info.m_Texture != INVALID_TEXTURE_HANDLE) @@ -483,15 +515,15 @@ void CTextureAllocator::DisconnectTextureFromFragment(FragmentHandle_t f) } - // Warning( "End of DisconnectTextureFromFragment\n" ); - // DebugPrintCache(); +// Warning( "End of DisconnectTextureFromFragment\n" ); +// DebugPrintCache(); } //----------------------------------------------------------------------------- // Do we have a valid texture assigned? //----------------------------------------------------------------------------- -bool CTextureAllocator::HasValidTexture(TextureHandle_t h) +bool CTextureAllocator::HasValidTexture( TextureHandle_t h ) { TextureInfo_t& info = m_Textures[h]; FragmentHandle_t currentFragment = info.m_Fragment; @@ -502,19 +534,19 @@ bool CTextureAllocator::HasValidTexture(TextureHandle_t h) //----------------------------------------------------------------------------- // Mark texture as being used... //----------------------------------------------------------------------------- -bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float flArea) +bool CTextureAllocator::UseTexture( TextureHandle_t h, bool bWillRedraw, float flArea ) { - // Warning( "Top of UseTexture\n" ); - // DebugPrintCache(); +// Warning( "Top of UseTexture\n" ); +// DebugPrintCache(); TextureInfo_t& info = m_Textures[h]; // spin up to the best fragment size int nDesiredPower = MIN_TEXTURE_POWER; int nDesiredWidth = MIN_TEXTURE_SIZE; - while ((nDesiredWidth * nDesiredWidth) < flArea) + while ( (nDesiredWidth * nDesiredWidth) < flArea ) { - if (nDesiredPower >= info.m_Power) + if ( nDesiredPower >= info.m_Power ) { nDesiredPower = info.m_Power; break; @@ -531,33 +563,33 @@ bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float fl { // If the current fragment is at or near the desired power, we're done nCurrentPower = GetFragmentPower(info.m_Fragment); - Assert(nCurrentPower <= info.m_Power); + Assert( nCurrentPower <= info.m_Power ); bool bShouldKeepTexture = (!bWillRedraw) && (nDesiredPower < 8) && (nDesiredPower - nCurrentPower <= 1); if ((nCurrentPower == nDesiredPower) || bShouldKeepTexture) { // Move to the back of the LRU - MarkUsed(currentFragment); + MarkUsed( currentFragment ); return false; } } - // Warning( "\n\nUseTexture B\n" ); - // DebugPrintCache(); +// Warning( "\n\nUseTexture B\n" ); +// DebugPrintCache(); - // Grab the LRU fragment from the appropriate cache - // If that fragment is connected to a texture, disconnect it. + // Grab the LRU fragment from the appropriate cache + // If that fragment is connected to a texture, disconnect it. int power = nDesiredPower; FragmentHandle_t f = INVALID_FRAGMENT_HANDLE; bool done = false; while (!done && power >= 0) { - f = m_Fragments.Head(m_Cache[power].m_List); - + f = m_Fragments.Head( m_Cache[power].m_List ); + // This represents an overflow condition (used too many textures of // the same size in a single frame). It that happens, just use a texture // of lower res. - if ((f != m_Fragments.InvalidIndex()) && (m_Fragments[f].m_FrameUsed != m_CurrentFrame)) + if ( (f != m_Fragments.InvalidIndex()) && (m_Fragments[f].m_FrameUsed != m_CurrentFrame) ) { done = true; } @@ -568,17 +600,17 @@ bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float fl } - // Warning( "\n\nUseTexture C\n" ); - // DebugPrintCache(); +// Warning( "\n\nUseTexture C\n" ); +// DebugPrintCache(); - // Ok, lets see if we're better off than we were... + // Ok, lets see if we're better off than we were... if (currentFragment != INVALID_FRAGMENT_HANDLE) { if (power <= nCurrentPower) { // Oops... we're not. Let's leave well enough alone // Move to the back of the LRU - MarkUsed(currentFragment); + MarkUsed( currentFragment ); return false; } else @@ -588,7 +620,7 @@ bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float fl } } - if (f == INVALID_FRAGMENT_HANDLE) + if ( f == INVALID_FRAGMENT_HANDLE ) { return false; } @@ -601,7 +633,7 @@ bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float fl m_Fragments[f].m_Texture = h; // Move to the back of the LRU - MarkUsed(f); + MarkUsed( f ); // Indicate we need a redraw return true; @@ -611,7 +643,7 @@ bool CTextureAllocator::UseTexture(TextureHandle_t h, bool bWillRedraw, float fl //----------------------------------------------------------------------------- // Returns the size of a particular fragment //----------------------------------------------------------------------------- -int CTextureAllocator::GetFragmentPower(FragmentHandle_t f) const +int CTextureAllocator::GetFragmentPower( FragmentHandle_t f ) const { return m_Blocks[m_Fragments[f].m_Block].m_FragmentPower; } @@ -639,7 +671,7 @@ ITexture* CTextureAllocator::GetTexture() //----------------------------------------------------------------------------- // Get at the total texture size. //----------------------------------------------------------------------------- -void CTextureAllocator::GetTotalTextureSize(int& w, int& h) +void CTextureAllocator::GetTotalTextureSize( int& w, int& h ) { w = h = TEXTURE_PAGE_SIZE; } @@ -648,10 +680,10 @@ void CTextureAllocator::GetTotalTextureSize(int& w, int& h) //----------------------------------------------------------------------------- // Returns the rectangle the texture lives in.. //----------------------------------------------------------------------------- -void CTextureAllocator::GetTextureRect(TextureHandle_t handle, int& x, int& y, int& w, int& h) +void CTextureAllocator::GetTextureRect(TextureHandle_t handle, int& x, int& y, int& w, int& h ) { TextureInfo_t& info = m_Textures[handle]; - Assert(info.m_Fragment != INVALID_FRAGMENT_HANDLE); + Assert( info.m_Fragment != INVALID_FRAGMENT_HANDLE ); // Compute the position of the fragment in the page FragmentInfo_t& fragment = m_Fragments[info.m_Fragment]; @@ -678,9 +710,9 @@ void CTextureAllocator::GetTextureRect(TextureHandle_t handle, int& x, int& y, i #define MAX_CLIP_PLANE_COUNT 4 #define SHADOW_CULL_TOLERANCE 0.5f -static ConVar r_shadows("r_shadows", "1"); // hook into engine's cvars.. +static ConVar r_shadows( "r_shadows", "1" ); // hook into engine's cvars.. static ConVar r_shadowmaxrendered("r_shadowmaxrendered", "32"); -static ConVar r_shadows_gamecontrol("r_shadows_gamecontrol", "-1", FCVAR_CHEAT); // hook into engine's cvars.. +static ConVar r_shadows_gamecontrol( "r_shadows_gamecontrol", "-1", FCVAR_CHEAT ); // hook into engine's cvars.. //----------------------------------------------------------------------------- // The class responsible for dealing with shadows on the client side @@ -692,7 +724,7 @@ class CClientShadowMgr : public IClientShadowMgr public: CClientShadowMgr(); - virtual char const* Name() { return "CCLientShadowMgr"; } + virtual char const *Name() { return "CCLientShadowMgr"; } // Inherited from IClientShadowMgr virtual bool Init(); @@ -706,100 +738,109 @@ class CClientShadowMgr : public IClientShadowMgr virtual bool IsPerFrame() { return true; } virtual void PreRender(); - virtual void Update(float frametime) { } + virtual void Update( float frametime ) { } virtual void PostRender() {} virtual void OnSave() {} virtual void OnRestore() {} virtual void SafeRemoveIfDesired() {} - virtual ClientShadowHandle_t CreateShadow(ClientEntityHandle_t entity, int flags); - virtual void DestroyShadow(ClientShadowHandle_t handle); + virtual ClientShadowHandle_t CreateShadow( ClientEntityHandle_t entity, int flags ); + virtual void DestroyShadow( ClientShadowHandle_t handle ); // Create flashlight (projected texture light source) - virtual ClientShadowHandle_t CreateFlashlight(const FlashlightState_t& lightState); - virtual void UpdateFlashlightState(ClientShadowHandle_t shadowHandle, const FlashlightState_t& lightState); - virtual void DestroyFlashlight(ClientShadowHandle_t shadowHandle); + virtual ClientShadowHandle_t CreateFlashlight( const FlashlightState_t &lightState ); + virtual void UpdateFlashlightState( ClientShadowHandle_t shadowHandle, const FlashlightState_t &lightState ); + virtual void DestroyFlashlight( ClientShadowHandle_t shadowHandle ); // Update a shadow - virtual void UpdateProjectedTexture(ClientShadowHandle_t handle, bool force); + virtual void UpdateProjectedTexture( ClientShadowHandle_t handle, bool force ); - void ComputeBoundingSphere(IClientRenderable* pRenderable, Vector& origin, float& radius); + void ComputeBoundingSphere( IClientRenderable* pRenderable, Vector& origin, float& radius ); - virtual void AddToDirtyShadowList(ClientShadowHandle_t handle, bool bForce); - virtual void AddToDirtyShadowList(IClientRenderable* pRenderable, bool force); + virtual void AddToDirtyShadowList( ClientShadowHandle_t handle, bool bForce ); + virtual void AddToDirtyShadowList( IClientRenderable *pRenderable, bool force ); // Marks the render-to-texture shadow as needing to be re-rendered - virtual void MarkRenderToTextureShadowDirty(ClientShadowHandle_t handle); + virtual void MarkRenderToTextureShadowDirty( ClientShadowHandle_t handle ); // deals with shadows being added to shadow receivers - void AddShadowToReceiver(ClientShadowHandle_t handle, - IClientRenderable* pRenderable, ShadowReceiver_t type); + void AddShadowToReceiver( ClientShadowHandle_t handle, + IClientRenderable* pRenderable, ShadowReceiver_t type ); // deals with shadows being added to shadow receivers - void RemoveAllShadowsFromReceiver(IClientRenderable* pRenderable, ShadowReceiver_t type); + void RemoveAllShadowsFromReceiver( IClientRenderable* pRenderable, ShadowReceiver_t type ); // Re-renders all shadow textures for shadow casters that lie in the leaf list - void ComputeShadowTextures(const CViewSetup& view, int leafCount, LeafIndex_t* pLeafList); + void ComputeShadowTextures( const CViewSetup &view, int leafCount, LeafIndex_t* pLeafList ); // Kicks off rendering into shadow depth maps (if any) - void ComputeShadowDepthTextures(const CViewSetup& view); - - void GetFrustumExtents(ClientShadowHandle_t handle, Vector& vecMin, Vector& vecMax); + void ComputeShadowDepthTextures( const CViewSetup &view ); // Frees shadow depth textures for use in subsequent view/frame void FreeShadowDepthTextures(); // Returns the shadow texture - ITexture* GetShadowTexture(unsigned short h); + ITexture* GetShadowTexture( unsigned short h ); // Returns shadow information - const ShadowInfo_t& GetShadowInfo(ClientShadowHandle_t h); + const ShadowInfo_t& GetShadowInfo( ClientShadowHandle_t h ); // Renders the shadow texture to screen... - void RenderShadowTexture(int w, int h); + void RenderShadowTexture( int w, int h ); // Sets the shadow direction - virtual void SetShadowDirection(const Vector& dir); - const Vector& GetShadowDirection() const; + virtual void SetShadowDirection( const Vector& dir ); + const Vector &GetShadowDirection() const; // Sets the shadow color - virtual void SetShadowColor(unsigned char r, unsigned char g, unsigned char b); - void GetShadowColor(unsigned char* r, unsigned char* g, unsigned char* b) const; + virtual void SetShadowColor( unsigned char r, unsigned char g, unsigned char b ); + void GetShadowColor( unsigned char *r, unsigned char *g, unsigned char *b ) const; // Sets the shadow distance - virtual void SetShadowDistance(float flMaxDistance); - float GetShadowDistance() const; + virtual void SetShadowDistance( float flMaxDistance ); + float GetShadowDistance( ) const; // Sets the screen area at which blobby shadows are always used - virtual void SetShadowBlobbyCutoffArea(float flMinArea); - float GetBlobbyCutoffArea() const; + virtual void SetShadowBlobbyCutoffArea( float flMinArea ); + float GetBlobbyCutoffArea( ) const; // Set the darkness falloff bias - virtual void SetFalloffBias(ClientShadowHandle_t handle, unsigned char ucBias); + virtual void SetFalloffBias( ClientShadowHandle_t handle, unsigned char ucBias ); void RestoreRenderState(); // Computes a rough bounding box encompassing the volume of the shadow - void ComputeShadowBBox(IClientRenderable* pRenderable, const Vector& vecAbsCenter, float flRadius, Vector* pAbsMins, Vector* pAbsMaxs); +#ifdef DYNAMIC_RTT_SHADOWS + void ComputeShadowBBox( IClientRenderable *pRenderable, ClientShadowHandle_t shadowHandle, const Vector &vecAbsCenter, float flRadius, Vector *pAbsMins, Vector *pAbsMaxs ); +#else + void ComputeShadowBBox( IClientRenderable *pRenderable, const Vector &vecAbsCenter, float flRadius, Vector *pAbsMins, Vector *pAbsMaxs ); +#endif - bool WillParentRenderBlobbyShadow(IClientRenderable* pRenderable); + bool WillParentRenderBlobbyShadow( IClientRenderable *pRenderable ); // Are we the child of a shadow with render-to-texture? - bool ShouldUseParentShadow(IClientRenderable* pRenderable); + bool ShouldUseParentShadow( IClientRenderable *pRenderable ); - void SetShadowsDisabled(bool bDisabled) - { - r_shadows_gamecontrol.SetValue(bDisabled != 1); + void SetShadowsDisabled( bool bDisabled ) + { + r_shadows_gamecontrol.SetValue( bDisabled != 1 ); } +#ifdef DYNAMIC_RTT_SHADOWS + // Toggle shadow casting from world light sources + virtual void SetShadowFromWorldLightsEnabled( bool bEnable ); + void SuppressShadowFromWorldLights( bool bSuppress ); + bool IsShadowingFromWorldLights() const { return m_bShadowFromWorldLights && !m_bSuppressShadowFromWorldLights; } +#endif + private: enum { - SHADOW_FLAGS_TEXTURE_DIRTY = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 1), - SHADOW_FLAGS_BRUSH_MODEL = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 2), + SHADOW_FLAGS_TEXTURE_DIRTY = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 1), + SHADOW_FLAGS_BRUSH_MODEL = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 2), SHADOW_FLAGS_USING_LOD_SHADOW = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 3), - SHADOW_FLAGS_LIGHT_WORLD = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 4), + SHADOW_FLAGS_LIGHT_WORLD = (CLIENT_SHADOW_FLAGS_LAST_FLAG << 4), }; struct ClientShadow_t @@ -810,8 +851,16 @@ class CClientShadowMgr : public IClientShadowMgr unsigned short m_Flags; VMatrix m_WorldToShadow; Vector2D m_WorldSize; +#ifdef DYNAMIC_RTT_SHADOWS + Vector m_ShadowDir; +#endif Vector m_LastOrigin; QAngle m_LastAngles; +#ifdef DYNAMIC_RTT_SHADOWS + Vector m_CurrentLightPos; // When shadowing from local lights, stores the position of the currently shadowing light + Vector m_TargetLightPos; // When shadowing from local lights, stores the position of the new shadowing light + float m_LightPosLerp; // Lerp progress when going from current to target light +#endif TextureHandle_t m_ShadowTexture; CTextureReference m_ShadowDepthTexture; int m_nRenderFrame; @@ -820,116 +869,107 @@ class CClientShadowMgr : public IClientShadowMgr private: // Shadow update functions - void UpdateStudioShadow(IClientRenderable* pRenderable, ClientShadowHandle_t handle); - void UpdateBrushShadow(IClientRenderable* pRenderable, ClientShadowHandle_t handle); - void UpdateShadow(ClientShadowHandle_t handle, bool force); + void UpdateStudioShadow( IClientRenderable *pRenderable, ClientShadowHandle_t handle ); + void UpdateBrushShadow( IClientRenderable *pRenderable, ClientShadowHandle_t handle ); + void UpdateShadow( ClientShadowHandle_t handle, bool force ); + +#ifdef DYNAMIC_RTT_SHADOWS + // Updates shadow cast direction when shadowing from world lights + void UpdateShadowDirectionFromLocalLightSource( ClientShadowHandle_t shadowHandle ); +#endif // Gets the entity whose shadow this shadow will render into - IClientRenderable* GetParentShadowEntity(ClientShadowHandle_t handle); + IClientRenderable *GetParentShadowEntity( ClientShadowHandle_t handle ); // Adds the child bounds to the bounding box - void AddChildBounds(matrix3x4_t& matWorldToBBox, IClientRenderable* pParent, Vector& vecMins, Vector& vecMaxs); + void AddChildBounds( matrix3x4_t &matWorldToBBox, IClientRenderable* pParent, Vector &vecMins, Vector &vecMaxs ); // Compute a bounds for the entity + children - void ComputeHierarchicalBounds(IClientRenderable* pRenderable, Vector& vecMins, Vector& vecMaxs); + void ComputeHierarchicalBounds( IClientRenderable *pRenderable, Vector &vecMins, Vector &vecMaxs ); // Builds matrices transforming from world space to shadow space - void BuildGeneralWorldToShadowMatrix(VMatrix& matWorldToShadow, - const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec); + void BuildGeneralWorldToShadowMatrix( VMatrix& matWorldToShadow, + const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec ); - void BuildWorldToShadowMatrix(VMatrix& matWorldToShadow, const Vector& origin, const Quaternion& quatOrientation); + void BuildWorldToShadowMatrix( VMatrix& matWorldToShadow, const Vector& origin, const Quaternion& quatOrientation ); - void BuildPerspectiveWorldToFlashlightMatrix(VMatrix& matWorldToShadow, const FlashlightState_t& flashlightState); + void BuildPerspectiveWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ); + +#ifdef ASW_PROJECTED_TEXTURES + void BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ); +#endif // Update a shadow - void UpdateProjectedTextureInternal(ClientShadowHandle_t handle, bool force); + void UpdateProjectedTextureInternal( ClientShadowHandle_t handle, bool force ); // Compute the shadow origin and attenuation start distance - float ComputeLocalShadowOrigin(IClientRenderable* pRenderable, - const Vector& mins, const Vector& maxs, const Vector& localShadowDir, float backupFactor, Vector& origin); + float ComputeLocalShadowOrigin( IClientRenderable* pRenderable, + const Vector& mins, const Vector& maxs, const Vector& localShadowDir, float backupFactor, Vector& origin ); // Remove a shadow from the dirty list - void RemoveShadowFromDirtyList(ClientShadowHandle_t handle); + void RemoveShadowFromDirtyList( ClientShadowHandle_t handle ); -public: // NOTE: this will ONLY return SHADOWS_NONE, SHADOWS_SIMPLE, or SHADOW_RENDER_TO_TEXTURE. - ShadowType_t GetActualShadowCastType(ClientShadowHandle_t handle) const; - ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ) { return m_Shadows[clienthandle].m_ShadowHandle; }; - int GetNumShadowDepthtextures() { return m_DepthTextureCache.Count(); } - CTextureReference GetShadowDepthTex( int num ) { return m_DepthTextureCache[num]; } - - virtual ShadowHandle_t GetShadowDepthHandle(int num) - { - if (num < 0 || num >= ARRAYSIZE(m_ActiveDepthTextureShadows)) - return SHADOW_HANDLE_INVALID; - - ClientShadowHandle_t handle = m_ActiveDepthTextureShadows[num]; - - if (handle == CLIENTSHADOW_INVALID_HANDLE) - return SHADOW_HANDLE_INVALID; - - return m_Shadows[handle].m_ShadowHandle; - } - - virtual ShadowHandle_t GetActiveDepthTextureHandle() { return m_ActiveDepthTextureHandle; } - -private: - ShadowType_t GetActualShadowCastType(IClientRenderable* pRenderable) const; + ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const; + ShadowType_t GetActualShadowCastType( IClientRenderable *pRenderable ) const; // Builds a simple blobby shadow - void BuildOrthoShadow(IClientRenderable* pRenderable, ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs); + void BuildOrthoShadow( IClientRenderable* pRenderable, ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs); // Builds a more complex shadow... - void BuildRenderToTextureShadow(IClientRenderable* pRenderable, - ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs); + void BuildRenderToTextureShadow( IClientRenderable* pRenderable, + ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs ); // Build a projected-texture flashlight - void BuildFlashlight(ClientShadowHandle_t handle); + void BuildFlashlight( ClientShadowHandle_t handle ); // Does all the lovely stuff we need to do to have render-to-texture shadows - void SetupRenderToTextureShadow(ClientShadowHandle_t h); - void CleanUpRenderToTextureShadow(ClientShadowHandle_t h); + void SetupRenderToTextureShadow( ClientShadowHandle_t h ); + void CleanUpRenderToTextureShadow( ClientShadowHandle_t h ); // Compute the extra shadow planes - void ComputeExtraClipPlanes(IClientRenderable* pRenderable, - ClientShadowHandle_t handle, const Vector* vec, - const Vector& mins, const Vector& maxs, const Vector& localShadowDir); + void ComputeExtraClipPlanes( IClientRenderable* pRenderable, + ClientShadowHandle_t handle, const Vector* vec, + const Vector& mins, const Vector& maxs, const Vector& localShadowDir ); // Set extra clip planes related to shadows... - void ClearExtraClipPlanes(ClientShadowHandle_t h); - void AddExtraClipPlane(ClientShadowHandle_t h, const Vector& normal, float dist); + void ClearExtraClipPlanes( ClientShadowHandle_t h ); + void AddExtraClipPlane( ClientShadowHandle_t h, const Vector& normal, float dist ); // Cull if the origin is on the wrong side of a shadow clip plane.... - bool CullReceiver(ClientShadowHandle_t handle, IClientRenderable* pRenderable, IClientRenderable* pSourceRenderable); + bool CullReceiver( ClientShadowHandle_t handle, IClientRenderable* pRenderable, IClientRenderable* pSourceRenderable ); - bool ComputeSeparatingPlane(IClientRenderable* pRend1, IClientRenderable* pRend2, cplane_t* pPlane); + bool ComputeSeparatingPlane( IClientRenderable* pRend1, IClientRenderable* pRend2, cplane_t* pPlane ); // Causes all shadows to be re-updated void UpdateAllShadows(); // One of these gets called with every shadow that potentially will need to re-render - bool DrawRenderToTextureShadow(unsigned short clientShadowHandle, float flArea); - void DrawRenderToTextureShadowLOD(unsigned short clientShadowHandle); + bool DrawRenderToTextureShadow( unsigned short clientShadowHandle, float flArea ); + void DrawRenderToTextureShadowLOD( unsigned short clientShadowHandle ); // Draws all children shadows into our own - bool DrawShadowHierarchy(IClientRenderable* pRenderable, const ClientShadow_t& shadow, bool bChild = false); + bool DrawShadowHierarchy( IClientRenderable *pRenderable, const ClientShadow_t &shadow, bool bChild = false ); // Setup stage for threading - bool BuildSetupListForRenderToTextureShadow(unsigned short clientShadowHandle, float flArea); - bool BuildSetupShadowHierarchy(IClientRenderable* pRenderable, const ClientShadow_t& shadow, bool bChild = false); + bool BuildSetupListForRenderToTextureShadow( unsigned short clientShadowHandle, float flArea ); + bool BuildSetupShadowHierarchy( IClientRenderable *pRenderable, const ClientShadow_t &shadow, bool bChild = false ); // Computes + sets the render-to-texture texcoords - void SetRenderToTextureShadowTexCoords(ShadowHandle_t handle, int x, int y, int w, int h); + void SetRenderToTextureShadowTexCoords( ShadowHandle_t handle, int x, int y, int w, int h ); // Visualization.... - void DrawRenderToTextureDebugInfo(IClientRenderable* pRenderable, const Vector& mins, const Vector& maxs); + void DrawRenderToTextureDebugInfo( IClientRenderable* pRenderable, const Vector& mins, const Vector& maxs ); // Advance frame void AdvanceFrame(); // Returns renderable-specific shadow info - float GetShadowDistance(IClientRenderable* pRenderable) const; - const Vector& GetShadowDirection(IClientRenderable* pRenderable) const; + float GetShadowDistance( IClientRenderable *pRenderable ) const; + const Vector &GetShadowDirection( IClientRenderable *pRenderable ) const; +#ifdef DYNAMIC_RTT_SHADOWS + const Vector &GetShadowDirection( ClientShadowHandle_t shadowHandle ) const; +#endif // Initialize, shutdown render-to-texture shadows void InitDepthTextureShadows(); @@ -939,34 +979,51 @@ class CClientShadowMgr : public IClientShadowMgr void InitRenderToTextureShadows(); void ShutdownRenderToTextureShadows(); - static bool ShadowHandleCompareFunc(const ClientShadowHandle_t& lhs, const ClientShadowHandle_t& rhs) + static bool ShadowHandleCompareFunc( const ClientShadowHandle_t& lhs, const ClientShadowHandle_t& rhs ) { return lhs < rhs; } - ClientShadowHandle_t CreateProjectedTexture(ClientEntityHandle_t entity, int flags); + ClientShadowHandle_t CreateProjectedTexture( ClientEntityHandle_t entity, int flags ); // Lock down the usage of a shadow depth texture...must be unlocked use on subsequent views / frames - bool LockShadowDepthTexture(CTextureReference* shadowDepthTexture); + bool LockShadowDepthTexture( CTextureReference *shadowDepthTexture ); void UnlockAllShadowDepthTextures(); // Set and clear flashlight target renderable - void SetFlashlightTarget(ClientShadowHandle_t shadowHandle, EHANDLE targetEntity); + void SetFlashlightTarget( ClientShadowHandle_t shadowHandle, EHANDLE targetEntity ); + +#ifdef ASW_PROJECTED_TEXTURES + // Get current frustum extents + void GetFrustumExtents( ClientShadowHandle_t handle, Vector &vecMin, Vector &vecMax ); +#endif // Set flashlight light world flag - void SetFlashlightLightWorld(ClientShadowHandle_t shadowHandle, bool bLightWorld); + void SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ); - bool IsFlashlightTarget(ClientShadowHandle_t shadowHandle, IClientRenderable* pRenderable); + bool IsFlashlightTarget( ClientShadowHandle_t shadowHandle, IClientRenderable *pRenderable ); // Builds a list of active shadows requiring shadow depth renders - int BuildActiveShadowDepthList(const CViewSetup& viewSetup, int nMaxDepthShadows, ClientShadowHandle_t* pActiveDepthShadows); + int BuildActiveShadowDepthList( const CViewSetup &viewSetup, int nMaxDepthShadows, ClientShadowHandle_t *pActiveDepthShadows ); + +#ifdef ASW_PROJECTED_TEXTURES + // Builds a list of active flashlights + int BuildActiveFlashlightList( const CViewSetup &viewSetup, int nMaxFlashlights, ClientShadowHandle_t *pActiveFlashlights ); +#endif // Sets the view's active flashlight render state - void SetViewFlashlightState(int nActiveFlashlightCount, ClientShadowHandle_t* pActiveFlashlights); + void SetViewFlashlightState( int nActiveFlashlightCount, ClientShadowHandle_t* pActiveFlashlights ); + +#ifdef DYNAMIC_RTT_SHADOWS + void UpdateDirtyShadow( ClientShadowHandle_t handle ); +#endif + +#ifdef VANCE + ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ) { return m_Shadows[clienthandle].m_ShadowHandle; } + int GetNumShadowDepthtextures() { return m_DepthTextureCache.Count(); } +#endif private: - ClientShadowHandle_t m_ActiveDepthTextureShadows[64]; - ShadowHandle_t m_ActiveDepthTextureHandle; Vector m_SimpleShadowDir; color32 m_AmbientLightColor; CMaterialReference m_SimpleShadow; @@ -985,7 +1042,9 @@ class CClientShadowMgr : public IClientShadowMgr CUtlRBTree< ClientShadowHandle_t, unsigned short > m_DirtyShadows; CUtlVector< ClientShadowHandle_t > m_TransparentShadows; +#ifdef ASW_PROJECTED_TEXTURES int m_nPrevFrameCount; +#endif // These members maintain current state of depth texturing (size and global active state) // If either changes in a frame, PreRender() will catch it and do the appropriate allocation, deallocation or reallocation @@ -996,11 +1055,18 @@ class CClientShadowMgr : public IClientShadowMgr CUtlVector< bool > m_DepthTextureCacheLocks; int m_nMaxDepthTextureShadows; +#ifdef DYNAMIC_RTT_SHADOWS + bool m_bShadowFromWorldLights; + bool m_bSuppressShadowFromWorldLights; +#endif + friend class CVisibleShadowList; friend class CVisibleShadowFrustumList; +#ifdef VANCE CTextureReference m_CascadedDepthTexture; CTextureReference m_CascadedColorTexture; +#endif }; //----------------------------------------------------------------------------- @@ -1025,14 +1091,14 @@ class CVisibleShadowList : public IClientLeafShadowEnum public: CVisibleShadowList(); - int FindShadows(const CViewSetup* pView, int nLeafCount, LeafIndex_t* pLeafList); + int FindShadows( const CViewSetup *pView, int nLeafCount, LeafIndex_t *pLeafList ); int GetVisibleShadowCount() const; - const VisibleShadowInfo_t& GetVisibleShadow(int i) const; + const VisibleShadowInfo_t &GetVisibleShadow( int i ) const; private: - void EnumShadow(unsigned short clientShadowHandle); - float ComputeScreenArea(const Vector& vecCenter, float r) const; + void EnumShadow( unsigned short clientShadowHandle ); + float ComputeScreenArea( const Vector &vecCenter, float r ) const; void PrioritySort(); CUtlVector m_ShadowsInView; @@ -1048,13 +1114,13 @@ static CVisibleShadowList s_VisibleShadowList; //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- -static CUtlVector s_NPCShadowBoneSetups; -static CUtlVector s_NonNPCShadowBoneSetups; +static CUtlVector s_NPCShadowBoneSetups; +static CUtlVector s_NonNPCShadowBoneSetups; //----------------------------------------------------------------------------- // CVisibleShadowList - Constructor and Accessors //----------------------------------------------------------------------------- -CVisibleShadowList::CVisibleShadowList() : m_ShadowsInView(0, 64), m_PriorityIndex(0, 64) +CVisibleShadowList::CVisibleShadowList() : m_ShadowsInView( 0, 64 ), m_PriorityIndex( 0, 64 ) { } @@ -1063,7 +1129,7 @@ int CVisibleShadowList::GetVisibleShadowCount() const return m_ShadowsInView.Count(); } -const VisibleShadowInfo_t& CVisibleShadowList::GetVisibleShadow(int i) const +const VisibleShadowInfo_t &CVisibleShadowList::GetVisibleShadow( int i ) const { return m_ShadowsInView[m_PriorityIndex[i]]; } @@ -1072,10 +1138,10 @@ const VisibleShadowInfo_t& CVisibleShadowList::GetVisibleShadow(int i) const //----------------------------------------------------------------------------- // CVisibleShadowList - Computes approximate screen area of the shadow //----------------------------------------------------------------------------- -float CVisibleShadowList::ComputeScreenArea(const Vector& vecCenter, float r) const +float CVisibleShadowList::ComputeScreenArea( const Vector &vecCenter, float r ) const { - CMatRenderContextPtr pRenderContext(materials); - float flScreenDiameter = pRenderContext->ComputePixelDiameterOfSphere(vecCenter, r); + CMatRenderContextPtr pRenderContext( materials ); + float flScreenDiameter = pRenderContext->ComputePixelDiameterOfSphere( vecCenter, r ); return flScreenDiameter * flScreenDiameter; } @@ -1083,54 +1149,60 @@ float CVisibleShadowList::ComputeScreenArea(const Vector& vecCenter, float r) co //----------------------------------------------------------------------------- // CVisibleShadowList - Visits every shadow in the list of leaves //----------------------------------------------------------------------------- -void CVisibleShadowList::EnumShadow(unsigned short clientShadowHandle) +void CVisibleShadowList::EnumShadow( unsigned short clientShadowHandle ) { CClientShadowMgr::ClientShadow_t& shadow = s_ClientShadowMgr.m_Shadows[clientShadowHandle]; // Don't bother if we rendered it this frame, no matter which view it was rendered for - if (shadow.m_nRenderFrame == gpGlobals->framecount) + if ( shadow.m_nRenderFrame == gpGlobals->framecount ) return; +#ifdef ASW_PROJECTED_TEXTURES // Don't bother with flashlights - if ((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) != 0) + if ( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) != 0 ) return; +#endif // We don't need to bother with it if it's not render-to-texture - if (s_ClientShadowMgr.GetActualShadowCastType(clientShadowHandle) != SHADOWS_RENDER_TO_TEXTURE) + if ( s_ClientShadowMgr.GetActualShadowCastType( clientShadowHandle ) != SHADOWS_RENDER_TO_TEXTURE ) return; // Don't bother with it if the shadow is totally transparent - const ShadowInfo_t& shadowInfo = shadowmgr->GetInfo(shadow.m_ShadowHandle); - if (shadowInfo.m_FalloffBias == 255) + const ShadowInfo_t &shadowInfo = shadowmgr->GetInfo( shadow.m_ShadowHandle ); + if ( shadowInfo.m_FalloffBias == 255 ) return; - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - Assert(pRenderable); + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + Assert( pRenderable ); // Don't bother with children of hierarchy; they will be drawn with their parents - if (s_ClientShadowMgr.ShouldUseParentShadow(pRenderable) || s_ClientShadowMgr.WillParentRenderBlobbyShadow(pRenderable)) + if ( s_ClientShadowMgr.ShouldUseParentShadow( pRenderable ) || s_ClientShadowMgr.WillParentRenderBlobbyShadow( pRenderable ) ) return; // Compute a sphere surrounding the shadow // FIXME: This doesn't account for children of hierarchy... too bad! Vector vecAbsCenter; float flRadius; - s_ClientShadowMgr.ComputeBoundingSphere(pRenderable, vecAbsCenter, flRadius); + s_ClientShadowMgr.ComputeBoundingSphere( pRenderable, vecAbsCenter, flRadius ); // Compute a box surrounding the shadow Vector vecAbsMins, vecAbsMaxs; - s_ClientShadowMgr.ComputeShadowBBox(pRenderable, vecAbsCenter, flRadius, &vecAbsMins, &vecAbsMaxs); +#ifdef DYNAMIC_RTT_SHADOWS + s_ClientShadowMgr.ComputeShadowBBox( pRenderable, shadow.m_ShadowHandle, vecAbsCenter, flRadius, &vecAbsMins, &vecAbsMaxs ); +#else + s_ClientShadowMgr.ComputeShadowBBox( pRenderable, vecAbsCenter, flRadius, &vecAbsMins, &vecAbsMaxs ); +#endif // FIXME: Add distance check here? // Make sure it's in the frustum. If it isn't it's not interesting - if (engine->CullBox(vecAbsMins, vecAbsMaxs)) + if (engine->CullBox( vecAbsMins, vecAbsMaxs )) return; - int i = m_ShadowsInView.AddToTail(); - VisibleShadowInfo_t& info = m_ShadowsInView[i]; + int i = m_ShadowsInView.AddToTail( ); + VisibleShadowInfo_t &info = m_ShadowsInView[i]; info.m_hShadow = clientShadowHandle; - m_ShadowsInView[i].m_flArea = ComputeScreenArea(vecAbsCenter, flRadius); + m_ShadowsInView[i].m_flArea = ComputeScreenArea( vecAbsCenter, flRadius ); // Har, har. When water is rendering (or any multipass technique), // we may well initially render from a viewpoint which doesn't include this shadow. @@ -1146,30 +1218,30 @@ void CVisibleShadowList::EnumShadow(unsigned short clientShadowHandle) void CVisibleShadowList::PrioritySort() { int nCount = m_ShadowsInView.Count(); - m_PriorityIndex.EnsureCapacity(nCount); + m_PriorityIndex.EnsureCapacity( nCount ); m_PriorityIndex.RemoveAll(); int i, j; - for (i = 0; i < nCount; ++i) + for ( i = 0; i < nCount; ++i ) { m_PriorityIndex.AddToTail(i); } - for (i = 0; i < nCount - 1; ++i) + for ( i = 0; i < nCount - 1; ++i ) { int nLargestInd = i; float flLargestArea = m_ShadowsInView[m_PriorityIndex[i]].m_flArea; - for (j = i + 1; j < nCount; ++j) + for ( j = i + 1; j < nCount; ++j ) { int nIndex = m_PriorityIndex[j]; - if (flLargestArea < m_ShadowsInView[nIndex].m_flArea) + if ( flLargestArea < m_ShadowsInView[nIndex].m_flArea ) { nLargestInd = j; flLargestArea = m_ShadowsInView[nIndex].m_flArea; } } - ::V_swap(m_PriorityIndex[i], m_PriorityIndex[nLargestInd]); + ::V_swap( m_PriorityIndex[i], m_PriorityIndex[nLargestInd] ); } } @@ -1177,12 +1249,12 @@ void CVisibleShadowList::PrioritySort() //----------------------------------------------------------------------------- // CVisibleShadowList - Main entry point for finding shadows in the leaf list //----------------------------------------------------------------------------- -int CVisibleShadowList::FindShadows(const CViewSetup* pView, int nLeafCount, LeafIndex_t* pLeafList) +int CVisibleShadowList::FindShadows( const CViewSetup *pView, int nLeafCount, LeafIndex_t *pLeafList ) { - VPROF_BUDGET("CVisibleShadowList::FindShadows", VPROF_BUDGETGROUP_SHADOW_RENDERING); + VPROF_BUDGET( "CVisibleShadowList::FindShadows", VPROF_BUDGETGROUP_SHADOW_RENDERING ); m_ShadowsInView.RemoveAll(); - ClientLeafSystem()->EnumerateShadowsInLeaves(nLeafCount, pLeafList, this); + ClientLeafSystem()->EnumerateShadowsInLeaves( nLeafCount, pLeafList, this ); int nCount = m_ShadowsInView.Count(); if (nCount != 0) { @@ -1197,40 +1269,45 @@ int CVisibleShadowList::FindShadows(const CViewSetup* pView, int nLeafCount, Lea // Constructor //----------------------------------------------------------------------------- CClientShadowMgr::CClientShadowMgr() : - m_DirtyShadows(0, 0, ShadowHandleCompareFunc), - m_nPrevFrameCount(-1), - m_RenderToTextureActive(false), - m_bDepthTextureActive(false) + m_DirtyShadows( 0, 0, ShadowHandleCompareFunc ), +#ifdef ASW_PROJECTED_TEXTURES + m_nPrevFrameCount( -1 ), +#endif + m_RenderToTextureActive( false ), +#ifdef DYNAMIC_RTT_SHADOWS + m_bShadowFromWorldLights( false ), + m_bSuppressShadowFromWorldLights( false ), +#endif + m_bDepthTextureActive( false ) { m_nDepthTextureResolution = r_flashlightdepthres.GetInt(); m_bThreaded = false; - m_ActiveDepthTextureHandle = SHADOW_HANDLE_INVALID; } //----------------------------------------------------------------------------- // Changes the shadow direction... //----------------------------------------------------------------------------- -CON_COMMAND_F(r_shadowdir, "Set shadow direction", FCVAR_CHEAT) +CON_COMMAND_F( r_shadowdir, "Set shadow direction", FCVAR_CHEAT ) { Vector dir; - if (args.ArgC() == 1) + if ( args.ArgC() == 1 ) { Vector dir = s_ClientShadowMgr.GetShadowDirection(); - Msg("%.2f %.2f %.2f\n", dir.x, dir.y, dir.z); + Msg( "%.2f %.2f %.2f\n", dir.x, dir.y, dir.z ); return; } - if (args.ArgC() == 4) + if ( args.ArgC() == 4 ) { - dir.x = atof(args[1]); - dir.y = atof(args[2]); - dir.z = atof(args[3]); + dir.x = atof( args[1] ); + dir.y = atof( args[2] ); + dir.z = atof( args[3] ); s_ClientShadowMgr.SetShadowDirection(dir); } } -CON_COMMAND_F(r_shadowangles, "Set shadow angles", FCVAR_CHEAT) +CON_COMMAND_F( r_shadowangles, "Set shadow angles", FCVAR_CHEAT ) { Vector dir; QAngle angles; @@ -1238,73 +1315,82 @@ CON_COMMAND_F(r_shadowangles, "Set shadow angles", FCVAR_CHEAT) { Vector dir = s_ClientShadowMgr.GetShadowDirection(); QAngle angles; - VectorAngles(dir, angles); - Msg("%.2f %.2f %.2f\n", angles.x, angles.y, angles.z); + VectorAngles( dir, angles ); + Msg( "%.2f %.2f %.2f\n", angles.x, angles.y, angles.z ); return; } if (args.ArgC() == 4) { - angles.x = atof(args[1]); - angles.y = atof(args[2]); - angles.z = atof(args[3]); - AngleVectors(angles, &dir); + angles.x = atof( args[1] ); + angles.y = atof( args[2] ); + angles.z = atof( args[3] ); + AngleVectors( angles, &dir ); s_ClientShadowMgr.SetShadowDirection(dir); } } -CON_COMMAND_F(r_shadowcolor, "Set shadow color", FCVAR_CHEAT) +CON_COMMAND_F( r_shadowcolor, "Set shadow color", FCVAR_CHEAT ) { if (args.ArgC() == 1) { unsigned char r, g, b; - s_ClientShadowMgr.GetShadowColor(&r, &g, &b); - Msg("Shadow color %d %d %d\n", r, g, b); + s_ClientShadowMgr.GetShadowColor( &r, &g, &b ); + Msg( "Shadow color %d %d %d\n", r, g, b ); return; } if (args.ArgC() == 4) { - int r = atoi(args[1]); - int g = atoi(args[2]); - int b = atoi(args[3]); + int r = atoi( args[1] ); + int g = atoi( args[2] ); + int b = atoi( args[3] ); s_ClientShadowMgr.SetShadowColor(r, g, b); } } -CON_COMMAND_F(r_shadowdist, "Set shadow distance", FCVAR_CHEAT) +CON_COMMAND_F( r_shadowdist, "Set shadow distance", FCVAR_CHEAT ) { if (args.ArgC() == 1) { - float flDist = s_ClientShadowMgr.GetShadowDistance(); - Msg("Shadow distance %.2f\n", flDist); + float flDist = s_ClientShadowMgr.GetShadowDistance( ); + Msg( "Shadow distance %.2f\n", flDist ); return; } if (args.ArgC() == 2) { - float flDistance = atof(args[1]); - s_ClientShadowMgr.SetShadowDistance(flDistance); + float flDistance = atof( args[1] ); + s_ClientShadowMgr.SetShadowDistance( flDistance ); } } -CON_COMMAND_F(r_shadowblobbycutoff, "some shadow stuff", FCVAR_CHEAT) +CON_COMMAND_F( r_shadowblobbycutoff, "some shadow stuff", FCVAR_CHEAT ) { if (args.ArgC() == 1) { - float flArea = s_ClientShadowMgr.GetBlobbyCutoffArea(); - Msg("Cutoff area %.2f\n", flArea); + float flArea = s_ClientShadowMgr.GetBlobbyCutoffArea( ); + Msg( "Cutoff area %.2f\n", flArea ); return; } if (args.ArgC() == 2) { - float flArea = atof(args[1]); - s_ClientShadowMgr.SetShadowBlobbyCutoffArea(flArea); + float flArea = atof( args[1] ); + s_ClientShadowMgr.SetShadowBlobbyCutoffArea( flArea ); } } -static void ShadowRestoreFunc(int nChangeFlags) +#ifdef DYNAMIC_RTT_SHADOWS +void OnShadowFromWorldLights( IConVar *var, const char *pOldValue, float flOldValue ); +static ConVar r_shadowfromworldlights( "r_shadowfromworldlights", "1", FCVAR_NONE, "Enable shadowing from world lights", OnShadowFromWorldLights ); +void OnShadowFromWorldLights( IConVar *var, const char *pOldValue, float flOldValue ) +{ + s_ClientShadowMgr.SuppressShadowFromWorldLights( !r_shadowfromworldlights.GetBool() ); +} +#endif + +static void ShadowRestoreFunc( int nChangeFlags ) { s_ClientShadowMgr.RestoreRenderState(); } @@ -1315,37 +1401,52 @@ static void ShadowRestoreFunc(int nChangeFlags) bool CClientShadowMgr::Init() { m_bRenderTargetNeedsClear = false; - m_SimpleShadow.Init("decals/simpleshadow", TEXTURE_GROUP_DECAL); + m_SimpleShadow.Init( "decals/simpleshadow", TEXTURE_GROUP_DECAL ); - Vector dir(0.1, 0.1, -1); + Vector dir( 0.1, 0.1, -1 ); SetShadowDirection(dir); - SetShadowDistance(50); + SetShadowDistance( 50 ); - SetShadowBlobbyCutoffArea(0.005); + SetShadowBlobbyCutoffArea( 0.005 ); - m_nMaxDepthTextureShadows = 6; // Maximum of 6 Projected Textures in one frame, a bit overkill +#ifndef MAPBASE + bool bTools = CommandLine()->CheckParm( "-tools" ) != NULL; + m_nMaxDepthTextureShadows = bTools ? 4 : 1; // Just one shadow depth texture in games, more in tools +#else + // 5 lets mappers use up to 4 shadow-casting projected textures, which is better than 3. + int iNumShadows = CommandLine()->ParmValue( "-numshadowtextures", 5 ); + m_nMaxDepthTextureShadows = iNumShadows; +#endif - bool bLowEnd = (g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80); + bool bLowEnd = ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 ); - bool bShadowrendertotexture = false; //r_shadowrendertotexture.GetBool(); - if (!bLowEnd && bShadowrendertotexture) + if ( !bLowEnd && r_shadowrendertotexture.GetBool() ) { InitRenderToTextureShadows(); } // If someone turned shadow depth mapping on but we can't do it, force it off - if (r_flashlightdepthtexture.GetBool() && !materials->SupportsShadowDepthTextures()) + if ( r_flashlightdepthtexture.GetBool() && !materials->SupportsShadowDepthTextures() ) { - r_flashlightdepthtexture.SetValue(0); - ShutdownDepthTextureShadows(); + r_flashlightdepthtexture.SetValue( 0 ); + ShutdownDepthTextureShadows(); } - if (!bLowEnd && r_flashlightdepthtexture.GetBool()) + if ( !bLowEnd && r_flashlightdepthtexture.GetBool() ) { InitDepthTextureShadows(); } - materials->AddRestoreFunc(ShadowRestoreFunc); + materials->AddRestoreFunc( ShadowRestoreFunc ); + +#ifdef MAPBASE + // These need to be referenced here since the cvars don't exist in the initial declaration + mat_slopescaledepthbias_shadowmap = ConVarRef( "mat_slopescaledepthbias_shadowmap" ); + mat_depthbias_shadowmap = ConVarRef( "mat_depthbias_shadowmap" ); + + mat_slopescaledepthbias_shadowmap.SetValue( "16" ); // Would do something like 2 here, but it causes citizens to look weird under flashlights + mat_depthbias_shadowmap.SetValue( "0.00005" ); +#endif return true; } @@ -1358,7 +1459,7 @@ void CClientShadowMgr::Shutdown() ShutdownDepthTextureShadows(); - materials->RemoveRestoreFunc(ShadowRestoreFunc); + materials->RemoveRestoreFunc( ShadowRestoreFunc ); } @@ -1367,81 +1468,111 @@ void CClientShadowMgr::Shutdown() //----------------------------------------------------------------------------- void CClientShadowMgr::InitDepthTextureShadows() { - VPROF_BUDGET("CClientShadowMgr::InitDepthTextureShadows", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - - // SAUL: start benchmark timer - CFastTimer timer; - timer.Start(); + VPROF_BUDGET( "CClientShadowMgr::InitDepthTextureShadows", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); +#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) + // SAUL: set m_nDepthTextureResolution to the depth resolution we want m_nDepthTextureResolution = r_flashlightdepthres.GetInt(); +#endif - if (!m_bDepthTextureActive) + if( !m_bDepthTextureActive ) { m_bDepthTextureActive = true; - ImageFormat dstFormat = IMAGE_FORMAT_NV_DST24; // NVidia depth texture format + ImageFormat dstFormat = materials->GetShadowDepthTextureFormat(); // Vendor-dependent depth texture format +#if !defined( _X360 ) ImageFormat nullFormat = materials->GetNullTextureFormat(); // Vendor-dependent null texture format (takes as little memory as possible) - +#endif materials->BeginRenderTargetAllocation(); - // using RT_SIZE_NO_CHANGE allows us to resize the projected texture past the depth buffer - m_DummyColorTexture.InitRenderTarget(r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), RT_SIZE_OFFSCREEN, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy"); +#if defined( _X360 ) + // For the 360, we'll be rendering depth directly into the dummy depth and Resolve()ing to the depth texture. + // only need the dummy surface, don't care about color results + m_DummyColorTexture.InitRenderTargetTexture( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), RT_SIZE_OFFSCREEN, IMAGE_FORMAT_BGR565, MATERIAL_RT_DEPTH_SHARED, false, "_rt_ShadowDummy" ); + m_DummyColorTexture.InitRenderTargetSurface( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), IMAGE_FORMAT_BGR565, true ); +#else +#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) + // SAUL: we want to create a render target of specific size, so use RT_SIZE_NO_CHANGE + m_DummyColorTexture.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_NO_CHANGE, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy" ); +#else + m_DummyColorTexture.InitRenderTarget( r_flashlightdepthres.GetInt(), r_flashlightdepthres.GetInt(), RT_SIZE_OFFSCREEN, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_ShadowDummy" ); +#endif +#endif // Create some number of depth-stencil textures m_DepthTextureCache.Purge(); m_DepthTextureCacheLocks.Purge(); - for (int i = 0; i < m_nMaxDepthTextureShadows; i++) + for( int i=0; i < m_nMaxDepthTextureShadows; i++ ) { CTextureReference depthTex; // Depth-stencil surface bool bFalse = false; char strRTName[64]; - Q_snprintf(strRTName, ARRAYSIZE(strRTName), "_rt_ShadowDepthTexture_%d", i); + Q_snprintf( strRTName, ARRAYSIZE( strRTName ), "_rt_ShadowDepthTexture_%d", i ); - depthTex.InitRenderTarget(m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_NO_CHANGE, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName); +#if defined( _X360 ) + // create a render target to use as a resolve target to get the shared depth buffer + // surface is effectively never used + depthTex.InitRenderTargetTexture( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_OFFSCREEN, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); + depthTex.InitRenderTargetSurface( 1, 1, dstFormat, false ); +#else +#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) + // SAUL: we want to create a *DEPTH TEXTURE* of specific size, so use RT_SIZE_NO_CHANGE and MATERIAL_RT_DEPTH_ONLY + // However, MATERIAL_RT_DEPTH_ONLY forces point filtering to be enabled which negatively affect PCF, so the standard MATERIAL_RT_DEPTH_NONE works better. + depthTex.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_NO_CHANGE, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); +#else + depthTex.InitRenderTarget( m_nDepthTextureResolution, m_nDepthTextureResolution, RT_SIZE_OFFSCREEN, dstFormat, MATERIAL_RT_DEPTH_NONE, false, strRTName ); +#endif +#endif - if (i == 0) +#if defined(MAPBASE) //&& !defined(ASW_PROJECTED_TEXTURES) + // SAUL: ensure the depth texture size wasn't changed + Assert(depthTex->GetActualWidth() == m_nDepthTextureResolution); +#endif + + if ( i == 0 ) { // Shadow may be resized during allocation (due to resolution constraints etc) m_nDepthTextureResolution = depthTex->GetActualWidth(); - r_flashlightdepthres.SetValue(m_nDepthTextureResolution); + r_flashlightdepthres.SetValue( m_nDepthTextureResolution ); } - Assert(depthTex->GetActualWidth() == m_nDepthTextureResolution); - - m_DepthTextureCache.AddToTail(depthTex); - m_DepthTextureCacheLocks.AddToTail(bFalse); + m_DepthTextureCache.AddToTail( depthTex ); + m_DepthTextureCacheLocks.AddToTail( bFalse ); } - +#ifdef VANCE const int iCadcadedShadowRes = 2048; m_CascadedColorTexture.InitRenderTarget(iCadcadedShadowRes * 4, iCadcadedShadowRes, RT_SIZE_NO_CHANGE, nullFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_CascadedShadowColor"); m_CascadedDepthTexture.InitRenderTarget(iCadcadedShadowRes * 4, iCadcadedShadowRes, RT_SIZE_NO_CHANGE, dstFormat, MATERIAL_RT_DEPTH_NONE, false, "_rt_CascadedShadowDepth"); materials->EndRenderTargetAllocation(); +#endif + + materials->EndRenderTargetAllocation(); } - timer.End(); - DevMsg("InitDepthTextureShadows took %.2f msec\n", timer.GetDuration().GetMillisecondsF()); } -void CClientShadowMgr::ShutdownDepthTextureShadows() +void CClientShadowMgr::ShutdownDepthTextureShadows() { - if (m_bDepthTextureActive) + if( m_bDepthTextureActive ) { // Shut down the dummy texture m_DummyColorTexture.Shutdown(); - while (m_DepthTextureCache.Count()) + while( m_DepthTextureCache.Count() ) { - m_DepthTextureCache[m_DepthTextureCache.Count() - 1].Shutdown(); + m_DepthTextureCache[ m_DepthTextureCache.Count()-1 ].Shutdown(); - m_DepthTextureCacheLocks.Remove(m_DepthTextureCache.Count() - 1); - m_DepthTextureCache.Remove(m_DepthTextureCache.Count() - 1); + m_DepthTextureCacheLocks.Remove( m_DepthTextureCache.Count()-1 ); + m_DepthTextureCache.Remove( m_DepthTextureCache.Count()-1 ); } +#ifdef VANCE m_CascadedDepthTexture.Shutdown(); m_CascadedColorTexture.Shutdown(); +#endif m_bDepthTextureActive = false; } @@ -1452,11 +1583,11 @@ void CClientShadowMgr::ShutdownDepthTextureShadows() //----------------------------------------------------------------------------- void CClientShadowMgr::InitRenderToTextureShadows() { - if (!m_RenderToTextureActive) + if ( !m_RenderToTextureActive ) { m_RenderToTextureActive = true; - m_RenderShadow.Init("decals/rendershadow", TEXTURE_GROUP_DECAL); - m_RenderModelShadow.Init("decals/rendermodelshadow", TEXTURE_GROUP_DECAL); + m_RenderShadow.Init( "decals/rendershadow", TEXTURE_GROUP_DECAL ); + m_RenderModelShadow.Init( "decals/rendermodelshadow", TEXTURE_GROUP_DECAL ); m_ShadowAllocator.Init(); m_ShadowAllocator.Reset(); @@ -1465,20 +1596,20 @@ void CClientShadowMgr::InitRenderToTextureShadows() float fr = (float)m_AmbientLightColor.r / 255.0f; float fg = (float)m_AmbientLightColor.g / 255.0f; float fb = (float)m_AmbientLightColor.b / 255.0f; - m_RenderShadow->ColorModulate(fr, fg, fb); - m_RenderModelShadow->ColorModulate(fr, fg, fb); + m_RenderShadow->ColorModulate( fr, fg, fb ); + m_RenderModelShadow->ColorModulate( fr, fg, fb ); // Iterate over all existing textures and allocate shadow textures - for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i)) + for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) { ClientShadow_t& shadow = m_Shadows[i]; - if (shadow.m_Flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE) + if ( shadow.m_Flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE ) { - SetupRenderToTextureShadow(i); - MarkRenderToTextureShadowDirty(i); + SetupRenderToTextureShadow( i ); + MarkRenderToTextureShadowDirty( i ); // Switch the material to use render-to-texture shadows - shadowmgr->SetShadowMaterial(shadow.m_ShadowHandle, m_RenderShadow, m_RenderModelShadow, (void*)(uintp)i); + shadowmgr->SetShadowMaterial( shadow.m_ShadowHandle, m_RenderShadow, m_RenderModelShadow, (void*)(uintp)i ); } } } @@ -1489,15 +1620,15 @@ void CClientShadowMgr::ShutdownRenderToTextureShadows() if (m_RenderToTextureActive) { // Iterate over all existing textures and deallocate shadow textures - for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i)) + for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) { - CleanUpRenderToTextureShadow(i); + CleanUpRenderToTextureShadow( i ); // Switch the material to use blobby shadows ClientShadow_t& shadow = m_Shadows[i]; - shadowmgr->SetShadowMaterial(shadow.m_ShadowHandle, m_SimpleShadow, m_SimpleShadow, (void*)CLIENTSHADOW_INVALID_HANDLE); - shadowmgr->SetShadowTexCoord(shadow.m_ShadowHandle, 0, 0, 1, 1); - ClearExtraClipPlanes(i); + shadowmgr->SetShadowMaterial( shadow.m_ShadowHandle, m_SimpleShadow, m_SimpleShadow, (void*)CLIENTSHADOW_INVALID_HANDLE ); + shadowmgr->SetShadowTexCoord( shadow.m_ShadowHandle, 0, 0, 1, 1 ); + ClearExtraClipPlanes( i ); } m_RenderShadow.Shutdown(); @@ -1517,19 +1648,19 @@ void CClientShadowMgr::ShutdownRenderToTextureShadows() //----------------------------------------------------------------------------- // Sets the shadow color //----------------------------------------------------------------------------- -void CClientShadowMgr::SetShadowColor(unsigned char r, unsigned char g, unsigned char b) +void CClientShadowMgr::SetShadowColor( unsigned char r, unsigned char g, unsigned char b ) { float fr = (float)r / 255.0f; float fg = (float)g / 255.0f; float fb = (float)b / 255.0f; // Hook the shadow color into the shadow materials - m_SimpleShadow->ColorModulate(fr, fg, fb); + m_SimpleShadow->ColorModulate( fr, fg, fb ); if (m_RenderToTextureActive) { - m_RenderShadow->ColorModulate(fr, fg, fb); - m_RenderModelShadow->ColorModulate(fr, fg, fb); + m_RenderShadow->ColorModulate( fr, fg, fb ); + m_RenderModelShadow->ColorModulate( fr, fg, fb ); } m_AmbientLightColor.r = r; @@ -1537,7 +1668,7 @@ void CClientShadowMgr::SetShadowColor(unsigned char r, unsigned char g, unsigned m_AmbientLightColor.b = b; } -void CClientShadowMgr::GetShadowColor(unsigned char* r, unsigned char* g, unsigned char* b) const +void CClientShadowMgr::GetShadowColor( unsigned char *r, unsigned char *g, unsigned char *b ) const { *r = m_AmbientLightColor.r; *g = m_AmbientLightColor.g; @@ -1552,10 +1683,19 @@ void CClientShadowMgr::LevelInitPreEntity() { m_bUpdatingDirtyShadows = false; +#ifdef DYNAMIC_RTT_SHADOWS + // Default setting for this, can be overridden by shadow control entities +#ifdef MAPBASE + SetShadowFromWorldLightsEnabled( false ); +#else + SetShadowFromWorldLightsEnabled( true ); +#endif +#endif + Vector ambientColor; - engine->GetAmbientLightColor(ambientColor); + engine->GetAmbientLightColor( ambientColor ); ambientColor *= 3; - ambientColor += Vector(0.3f, 0.3f, 0.3f); + ambientColor += Vector( 0.3f, 0.3f, 0.3f ); unsigned char r = ambientColor[0] > 1.0 ? 255 : 255 * ambientColor[0]; unsigned char g = ambientColor[1] > 1.0 ? 255 : 255 * ambientColor[1]; @@ -1564,7 +1704,7 @@ void CClientShadowMgr::LevelInitPreEntity() SetShadowColor(r, g, b); // Set up the texture allocator - if (m_RenderToTextureActive) + if ( m_RenderToTextureActive ) { m_ShadowAllocator.Reset(); m_bRenderTargetNeedsClear = true; @@ -1579,13 +1719,13 @@ void CClientShadowMgr::LevelShutdownPostEntity() { // All shadows *should* have been cleaned up when the entities went away // but, just in case.... - Assert(m_Shadows.Count() == 0); + Assert( m_Shadows.Count() == 0 ); ClientShadowHandle_t h = m_Shadows.Head(); while (h != CLIENTSHADOW_INVALID_HANDLE) { ClientShadowHandle_t next = m_Shadows.Next(h); - DestroyShadow(h); + DestroyShadow( h ); h = next; } @@ -1595,7 +1735,7 @@ void CClientShadowMgr::LevelShutdownPostEntity() m_ShadowAllocator.DeallocateAllTextures(); } - r_shadows_gamecontrol.SetValue(-1); + r_shadows_gamecontrol.SetValue( -1 ); } @@ -1606,12 +1746,12 @@ void CClientShadowMgr::RestoreRenderState() { // Mark all shadows dirty; they need to regenerate their state ClientShadowHandle_t h; - for (h = m_Shadows.Head(); h != m_Shadows.InvalidIndex(); h = m_Shadows.Next(h)) + for ( h = m_Shadows.Head(); h != m_Shadows.InvalidIndex(); h = m_Shadows.Next(h) ) { m_Shadows[h].m_Flags |= SHADOW_FLAGS_TEXTURE_DIRTY; } - SetShadowColor(m_AmbientLightColor.r, m_AmbientLightColor.g, m_AmbientLightColor.b); + SetShadowColor( m_AmbientLightColor.r, m_AmbientLightColor.g, m_AmbientLightColor.b ); m_bRenderTargetNeedsClear = true; } @@ -1619,29 +1759,29 @@ void CClientShadowMgr::RestoreRenderState() //----------------------------------------------------------------------------- // Does all the lovely stuff we need to do to have render-to-texture shadows //----------------------------------------------------------------------------- -void CClientShadowMgr::SetupRenderToTextureShadow(ClientShadowHandle_t h) +void CClientShadowMgr::SetupRenderToTextureShadow( ClientShadowHandle_t h ) { // First, compute how much texture memory we want to use. ClientShadow_t& shadow = m_Shadows[h]; - - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - if (!pRenderable) + + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + if ( !pRenderable ) return; Vector mins, maxs; - pRenderable->GetShadowRenderBounds(mins, maxs, GetActualShadowCastType(h)); + pRenderable->GetShadowRenderBounds( mins, maxs, GetActualShadowCastType( h ) ); // Compute the maximum dimension Vector size; - VectorSubtract(maxs, mins, size); - float maxSize = MAX(size.x, size.y); - maxSize = MAX(maxSize, size.z); + VectorSubtract( maxs, mins, size ); + float maxSize = MAX( size.x, size.y ); + maxSize = MAX( maxSize, size.z ); // Figure out the texture size // For now, we're going to assume a fixed number of shadow texels // per shadow-caster size; add in some extra space at the boundary. int texelCount = TEXEL_SIZE_PER_CASTER_SIZE * maxSize; - + // Pick the first power of 2 larger... int textureSize = 1; while (textureSize < texelCount) @@ -1649,16 +1789,16 @@ void CClientShadowMgr::SetupRenderToTextureShadow(ClientShadowHandle_t h) textureSize <<= 1; } - shadow.m_ShadowTexture = m_ShadowAllocator.AllocateTexture(textureSize, textureSize); + shadow.m_ShadowTexture = m_ShadowAllocator.AllocateTexture( textureSize, textureSize ); } -void CClientShadowMgr::CleanUpRenderToTextureShadow(ClientShadowHandle_t h) +void CClientShadowMgr::CleanUpRenderToTextureShadow( ClientShadowHandle_t h ) { ClientShadow_t& shadow = m_Shadows[h]; if (m_RenderToTextureActive && (shadow.m_Flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE)) { - m_ShadowAllocator.DeallocateTexture(shadow.m_ShadowTexture); + m_ShadowAllocator.DeallocateTexture( shadow.m_ShadowTexture ); shadow.m_ShadowTexture = INVALID_TEXTURE_HANDLE; } } @@ -1669,20 +1809,20 @@ void CClientShadowMgr::CleanUpRenderToTextureShadow(ClientShadowHandle_t h) //----------------------------------------------------------------------------- void CClientShadowMgr::UpdateAllShadows() { - for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i)) + for ( ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) { ClientShadow_t& shadow = m_Shadows[i]; // Don't bother with flashlights - if ((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) != 0) + if ( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) != 0 ) continue; - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - if (!pRenderable) + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + if ( !pRenderable ) continue; - Assert(pRenderable->GetShadowHandle() == i); - AddToDirtyShadowList(pRenderable, true); + Assert( pRenderable->GetShadowHandle() == i ); + AddToDirtyShadowList( pRenderable, true ); } } @@ -1690,22 +1830,22 @@ void CClientShadowMgr::UpdateAllShadows() //----------------------------------------------------------------------------- // Sets the shadow direction //----------------------------------------------------------------------------- -void CClientShadowMgr::SetShadowDirection(const Vector& dir) +void CClientShadowMgr::SetShadowDirection( const Vector& dir ) { - VectorCopy(dir, m_SimpleShadowDir); - VectorNormalize(m_SimpleShadowDir); + VectorCopy( dir, m_SimpleShadowDir ); + VectorNormalize( m_SimpleShadowDir ); - if (m_RenderToTextureActive) + if ( m_RenderToTextureActive ) { UpdateAllShadows(); } } -const Vector& CClientShadowMgr::GetShadowDirection() const +const Vector &CClientShadowMgr::GetShadowDirection() const { // This will cause blobby shadows to always project straight down - static Vector s_vecDown(0, 0, -1); - if (!m_RenderToTextureActive) + static Vector s_vecDown( 0, 0, -1 ); + if ( !m_RenderToTextureActive ) return s_vecDown; return m_SimpleShadowDir; @@ -1715,38 +1855,190 @@ const Vector& CClientShadowMgr::GetShadowDirection() const //----------------------------------------------------------------------------- // Gets shadow information for a particular renderable //----------------------------------------------------------------------------- -float CClientShadowMgr::GetShadowDistance(IClientRenderable* pRenderable) const +float CClientShadowMgr::GetShadowDistance( IClientRenderable *pRenderable ) const { float flDist = m_flShadowCastDist; // Allow the renderable to override the default - pRenderable->GetShadowCastDistance(&flDist, GetActualShadowCastType(pRenderable)); + pRenderable->GetShadowCastDistance( &flDist, GetActualShadowCastType( pRenderable ) ); return flDist; } -const Vector& CClientShadowMgr::GetShadowDirection(IClientRenderable* pRenderable) const +const Vector &CClientShadowMgr::GetShadowDirection( IClientRenderable *pRenderable ) const { - Vector& vecResult = AllocTempVector(); + Vector &vecResult = AllocTempVector(); vecResult = GetShadowDirection(); // Allow the renderable to override the default - pRenderable->GetShadowCastDirection(&vecResult, GetActualShadowCastType(pRenderable)); + pRenderable->GetShadowCastDirection( &vecResult, GetActualShadowCastType( pRenderable ) ); + + return vecResult; +} + +#ifdef DYNAMIC_RTT_SHADOWS +const Vector &CClientShadowMgr::GetShadowDirection( ClientShadowHandle_t shadowHandle ) const +{ + Assert( shadowHandle != CLIENTSHADOW_INVALID_HANDLE ); + + IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle( m_Shadows[shadowHandle].m_Entity ); + Assert( pRenderable ); + + if ( !IsShadowingFromWorldLights() ) + { + return GetShadowDirection( pRenderable ); + } + + Vector &vecResult = AllocTempVector(); + vecResult = m_Shadows[shadowHandle].m_ShadowDir; + + // Allow the renderable to override the default + pRenderable->GetShadowCastDirection( &vecResult, GetActualShadowCastType( pRenderable ) ); return vecResult; } +void CClientShadowMgr::UpdateShadowDirectionFromLocalLightSource( ClientShadowHandle_t shadowHandle ) +{ + Assert( shadowHandle != CLIENTSHADOW_INVALID_HANDLE ); + + ClientShadow_t& shadow = m_Shadows[shadowHandle]; + + IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + + // TODO: Figure out why this still gets hit + Assert( pRenderable ); + if ( !pRenderable ) + { + DevWarning( "%s(): Skipping shadow with invalid client renderable (shadow handle %d)\n", __FUNCTION__, shadowHandle ); + return; + } + + Vector bbMin, bbMax; + pRenderable->GetRenderBoundsWorldspace( bbMin, bbMax ); + Vector origin( 0.5f * ( bbMin + bbMax ) ); + origin.z = bbMin.z; // Putting origin at the bottom of the bounding box makes the shadows a little shorter + + Vector lightPos; + Vector lightBrightness; + + if ( shadow.m_LightPosLerp >= 1.0f ) // skip finding new light source if we're in the middle of a lerp + { + // Calculate minimum brightness squared + float flMinBrightnessSqr = r_shadow_mincastintensity.GetFloat(); + flMinBrightnessSqr *= flMinBrightnessSqr; + + if(g_pWorldLights->GetBrightestLightSource(pRenderable->GetRenderOrigin(), lightPos, lightBrightness) == false || + lightBrightness.LengthSqr() < flMinBrightnessSqr ) + { + // didn't find a light source at all, use default shadow direction + // TODO: Could switch to using blobby shadow in this case + lightPos.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + } + } + + if ( shadow.m_LightPosLerp == FLT_MAX ) // first light pos ever, just init + { + shadow.m_CurrentLightPos = lightPos; + shadow.m_TargetLightPos = lightPos; + shadow.m_LightPosLerp = 1.0f; + } + else if ( shadow.m_LightPosLerp < 1.0f ) + { + // We're in the middle of a lerp from current to target light. Finish it. + shadow.m_LightPosLerp += gpGlobals->frametime * 1.0f/r_shadow_lightpos_lerptime.GetFloat(); + shadow.m_LightPosLerp = clamp( shadow.m_LightPosLerp, 0.0f, 1.0f ); + + Vector currLightPos( shadow.m_CurrentLightPos ); + Vector targetLightPos( shadow.m_TargetLightPos ); + if ( currLightPos.x == FLT_MAX ) + { + currLightPos = origin - 200.0f * GetShadowDirection(); + } + if ( targetLightPos.x == FLT_MAX ) + { + targetLightPos = origin - 200.0f * GetShadowDirection(); + } + + // lerp light pos + Vector v1 = origin - shadow.m_CurrentLightPos; + v1.NormalizeInPlace(); + + Vector v2 = origin - shadow.m_TargetLightPos; + v2.NormalizeInPlace(); + + // SAULUNDONE: caused over top sweeping far too often +#if 0 + if ( v1.Dot( v2 ) < 0.0f ) + { + // if change in shadow angle is more than 90 degrees, lerp over the renderable's top to avoid long sweeping shadows + Vector fakeOverheadLightPos( origin.x, origin.y, origin.z + 200.0f ); + if( shadow.m_LightPosLerp < 0.5f ) + { + lightPos = Lerp( 2.0f * shadow.m_LightPosLerp, currLightPos, fakeOverheadLightPos ); + } + else + { + lightPos = Lerp( 2.0f * shadow.m_LightPosLerp - 1.0f, fakeOverheadLightPos, targetLightPos ); + } + } + else +#endif + { + lightPos = Lerp( shadow.m_LightPosLerp, currLightPos, targetLightPos ); + } + + if ( shadow.m_LightPosLerp >= 1.0f ) + { + shadow.m_CurrentLightPos = shadow.m_TargetLightPos; + } + } + else if ( shadow.m_LightPosLerp >= 1.0f ) + { + // check if we have a new closest light position and start a new lerp + float flDistSq = ( lightPos - shadow.m_CurrentLightPos ).LengthSqr(); + + if ( flDistSq > 1.0f ) + { + // light position has changed, which means we got a new light source. Initiate a lerp + shadow.m_TargetLightPos = lightPos; + shadow.m_LightPosLerp = 0.0f; + } + + lightPos = shadow.m_CurrentLightPos; + } + + if ( lightPos.x == FLT_MAX ) + { + lightPos = origin - 200.0f * GetShadowDirection(); + } + + Vector vecResult( origin - lightPos ); + vecResult.NormalizeInPlace(); + + vecResult.z *= r_shadow_shortenfactor.GetFloat(); + vecResult.NormalizeInPlace(); + + shadow.m_ShadowDir = vecResult; + + if ( r_shadowfromworldlights_debug.GetBool() ) + { + NDebugOverlay::Line( lightPos, origin, 255, 255, 0, false, 0.0f ); + } +} +#endif + //----------------------------------------------------------------------------- // Sets the shadow distance //----------------------------------------------------------------------------- -void CClientShadowMgr::SetShadowDistance(float flMaxDistance) +void CClientShadowMgr::SetShadowDistance( float flMaxDistance ) { m_flShadowCastDist = flMaxDistance; UpdateAllShadows(); } -float CClientShadowMgr::GetShadowDistance() const +float CClientShadowMgr::GetShadowDistance( ) const { return m_flShadowCastDist; } @@ -1755,12 +2047,12 @@ float CClientShadowMgr::GetShadowDistance() const //----------------------------------------------------------------------------- // Sets the screen area at which blobby shadows are always used //----------------------------------------------------------------------------- -void CClientShadowMgr::SetShadowBlobbyCutoffArea(float flMinArea) +void CClientShadowMgr::SetShadowBlobbyCutoffArea( float flMinArea ) { m_flMinShadowArea = flMinArea; } -float CClientShadowMgr::GetBlobbyCutoffArea() const +float CClientShadowMgr::GetBlobbyCutoffArea( ) const { return m_flMinShadowArea; } @@ -1768,15 +2060,15 @@ float CClientShadowMgr::GetBlobbyCutoffArea() const //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CClientShadowMgr::SetFalloffBias(ClientShadowHandle_t handle, unsigned char ucBias) +void CClientShadowMgr::SetFalloffBias( ClientShadowHandle_t handle, unsigned char ucBias ) { - shadowmgr->SetFalloffBias(m_Shadows[handle].m_ShadowHandle, ucBias); + shadowmgr->SetFalloffBias( m_Shadows[handle].m_ShadowHandle, ucBias ); } //----------------------------------------------------------------------------- // Returns the shadow texture //----------------------------------------------------------------------------- -ITexture* CClientShadowMgr::GetShadowTexture(unsigned short h) +ITexture* CClientShadowMgr::GetShadowTexture( unsigned short h ) { return m_ShadowAllocator.GetTexture(); } @@ -1785,44 +2077,44 @@ ITexture* CClientShadowMgr::GetShadowTexture(unsigned short h) //----------------------------------------------------------------------------- // Returns information needed by the model proxy //----------------------------------------------------------------------------- -const ShadowInfo_t& CClientShadowMgr::GetShadowInfo(ClientShadowHandle_t h) +const ShadowInfo_t& CClientShadowMgr::GetShadowInfo( ClientShadowHandle_t h ) { - return shadowmgr->GetInfo(m_Shadows[h].m_ShadowHandle); + return shadowmgr->GetInfo( m_Shadows[h].m_ShadowHandle ); } //----------------------------------------------------------------------------- // Renders the shadow texture to screen... //----------------------------------------------------------------------------- -void CClientShadowMgr::RenderShadowTexture(int w, int h) +void CClientShadowMgr::RenderShadowTexture( int w, int h ) { if (m_RenderToTextureActive) { - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->Bind(m_RenderShadow); - IMesh* pMesh = pRenderContext->GetDynamicMesh(true); + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( m_RenderShadow ); + IMesh* pMesh = pRenderContext->GetDynamicMesh( true ); CMeshBuilder meshBuilder; - meshBuilder.Begin(pMesh, MATERIAL_QUADS, 1); + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); - meshBuilder.Position3f(0.0f, 0.0f, 0.0f); - meshBuilder.TexCoord2f(0, 0.0f, 0.0f); - meshBuilder.Color4ub(0, 0, 0, 0); + meshBuilder.Position3f( 0.0f, 0.0f, 0.0f ); + meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.AdvanceVertex(); - meshBuilder.Position3f(w, 0.0f, 0.0f); - meshBuilder.TexCoord2f(0, 1.0f, 0.0f); - meshBuilder.Color4ub(0, 0, 0, 0); + meshBuilder.Position3f( w, 0.0f, 0.0f ); + meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.AdvanceVertex(); - meshBuilder.Position3f(w, h, 0.0f); - meshBuilder.TexCoord2f(0, 1.0f, 1.0f); - meshBuilder.Color4ub(0, 0, 0, 0); + meshBuilder.Position3f( w, h, 0.0f ); + meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.AdvanceVertex(); - meshBuilder.Position3f(0.0f, h, 0.0f); - meshBuilder.TexCoord2f(0, 0.0f, 1.0f); - meshBuilder.Color4ub(0, 0, 0, 0); + meshBuilder.Position3f( 0.0f, h, 0.0f ); + meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); @@ -1834,13 +2126,13 @@ void CClientShadowMgr::RenderShadowTexture(int w, int h) //----------------------------------------------------------------------------- // Create/destroy a shadow //----------------------------------------------------------------------------- -ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture(ClientEntityHandle_t entity, int flags) +ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture( ClientEntityHandle_t entity, int flags ) { // We need to know if it's a brush model for shadows - if (!(flags & SHADOW_FLAGS_FLASHLIGHT)) + if( !( flags & SHADOW_FLAGS_FLASHLIGHT ) ) { - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(entity); - int modelType = modelinfo->GetModelType(pRenderable->GetModel()); + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( entity ); + int modelType = modelinfo->GetModelType( pRenderable->GetModel() ); if (modelType == mod_brush) { flags |= SHADOW_FLAGS_BRUSH_MODEL; @@ -1850,20 +2142,26 @@ ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture(ClientEntityHandle ClientShadowHandle_t h = m_Shadows.AddToTail(); ClientShadow_t& shadow = m_Shadows[h]; shadow.m_Entity = entity; - shadow.m_ClientLeafShadowHandle = ClientLeafSystem()->AddShadow(h, flags); + shadow.m_ClientLeafShadowHandle = ClientLeafSystem()->AddShadow( h, flags ); shadow.m_Flags = flags; shadow.m_nRenderFrame = -1; - shadow.m_LastOrigin.Init(FLT_MAX, FLT_MAX, FLT_MAX); - shadow.m_LastAngles.Init(FLT_MAX, FLT_MAX, FLT_MAX); - Assert(((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) == 0) != - ((shadow.m_Flags & SHADOW_FLAGS_SHADOW) == 0)); +#ifdef DYNAMIC_RTT_SHADOWS + shadow.m_ShadowDir = GetShadowDirection(); + shadow.m_CurrentLightPos.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + shadow.m_TargetLightPos.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + shadow.m_LightPosLerp = FLT_MAX; +#endif + shadow.m_LastOrigin.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + shadow.m_LastAngles.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + Assert( ( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ) != + ( ( shadow.m_Flags & SHADOW_FLAGS_SHADOW ) == 0 ) ); // Set up the flags.... IMaterial* pShadowMaterial = m_SimpleShadow; IMaterial* pShadowModelMaterial = m_SimpleShadow; void* pShadowProxyData = (void*)CLIENTSHADOW_INVALID_HANDLE; - if (m_RenderToTextureActive && (flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE)) + if ( m_RenderToTextureActive && (flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE) ) { SetupRenderToTextureShadow(h); @@ -1872,15 +2170,24 @@ ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture(ClientEntityHandle pShadowProxyData = (void*)(uintp)h; } - if (flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE) +#ifdef ASW_PROJECTED_TEXTURES + if( ( flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) || ( flags & ( SHADOW_FLAGS_FLASHLIGHT ) ) ) + { + pShadowMaterial = NULL; // these materials aren't used for shadow depth texture shadows. + pShadowModelMaterial = NULL; + pShadowProxyData = (void*)(uintp)h; + } +#else + if( flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) { pShadowMaterial = m_RenderShadow; pShadowModelMaterial = m_RenderModelShadow; pShadowProxyData = (void*)(uintp)h; } +#endif int createShadowFlags; - if (flags & SHADOW_FLAGS_FLASHLIGHT) + if( flags & SHADOW_FLAGS_FLASHLIGHT ) { // don't use SHADOW_CACHE_VERTS with projective lightsources since we expect that they will change every frame. // FIXME: might want to make it cache optionally if it's an entity light that is static. @@ -1890,45 +2197,45 @@ ClientShadowHandle_t CClientShadowMgr::CreateProjectedTexture(ClientEntityHandle { createShadowFlags = SHADOW_CACHE_VERTS; } - shadow.m_ShadowHandle = shadowmgr->CreateShadowEx(pShadowMaterial, pShadowModelMaterial, pShadowProxyData, createShadowFlags); + shadow.m_ShadowHandle = shadowmgr->CreateShadowEx( pShadowMaterial, pShadowModelMaterial, pShadowProxyData, createShadowFlags ); return h; } -ClientShadowHandle_t CClientShadowMgr::CreateFlashlight(const FlashlightState_t& lightState) +ClientShadowHandle_t CClientShadowMgr::CreateFlashlight( const FlashlightState_t &lightState ) { // We don't really need a model entity handle for a projective light source, so use an invalid one. static ClientEntityHandle_t invalidHandle = INVALID_CLIENTENTITY_HANDLE; int shadowFlags = SHADOW_FLAGS_FLASHLIGHT | SHADOW_FLAGS_LIGHT_WORLD; - if (lightState.m_bEnableShadows && r_flashlightdepthtexture.GetBool()) + if( lightState.m_bEnableShadows && r_flashlightdepthtexture.GetBool() ) { shadowFlags |= SHADOW_FLAGS_USE_DEPTH_TEXTURE; } - ClientShadowHandle_t shadowHandle = CreateProjectedTexture(invalidHandle, shadowFlags); + ClientShadowHandle_t shadowHandle = CreateProjectedTexture( invalidHandle, shadowFlags ); - UpdateFlashlightState(shadowHandle, lightState); - UpdateProjectedTexture(shadowHandle, true); + UpdateFlashlightState( shadowHandle, lightState ); + UpdateProjectedTexture( shadowHandle, true ); return shadowHandle; } - -ClientShadowHandle_t CClientShadowMgr::CreateShadow(ClientEntityHandle_t entity, int flags) + +ClientShadowHandle_t CClientShadowMgr::CreateShadow( ClientEntityHandle_t entity, int flags ) { // We don't really need a model entity handle for a projective light source, so use an invalid one. flags &= ~SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK; flags |= SHADOW_FLAGS_SHADOW | SHADOW_FLAGS_TEXTURE_DIRTY; - ClientShadowHandle_t shadowHandle = CreateProjectedTexture(entity, flags); + ClientShadowHandle_t shadowHandle = CreateProjectedTexture( entity, flags ); - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(entity); - if (pRenderable) + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( entity ); + if ( pRenderable ) { - Assert(!pRenderable->IsShadowDirty()); - pRenderable->MarkShadowDirty(true); + Assert( !pRenderable->IsShadowDirty( ) ); + pRenderable->MarkShadowDirty( true ); } // NOTE: We *have* to call the version that takes a shadow handle // even if we have an entity because this entity hasn't set its shadow handle yet - AddToDirtyShadowList(shadowHandle, true); + AddToDirtyShadowList( shadowHandle, true ); return shadowHandle; } @@ -1936,37 +2243,55 @@ ClientShadowHandle_t CClientShadowMgr::CreateShadow(ClientEntityHandle_t entity, //----------------------------------------------------------------------------- // Updates the flashlight direction and re-computes surfaces it should lie on //----------------------------------------------------------------------------- -void CClientShadowMgr::UpdateFlashlightState(ClientShadowHandle_t shadowHandle, const FlashlightState_t& flashlightState) +void CClientShadowMgr::UpdateFlashlightState( ClientShadowHandle_t shadowHandle, const FlashlightState_t &flashlightState ) { - VPROF_BUDGET("CClientShadowMgr::UpdateFlashlightState", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::UpdateFlashlightState", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - //BuildPerspectiveWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); +#ifdef ASW_PROJECTED_TEXTURES + if( flashlightState.m_bEnableShadows && r_flashlightdepthtexture.GetBool() ) + { + m_Shadows[shadowHandle].m_Flags |= SHADOW_FLAGS_USE_DEPTH_TEXTURE; + } + else + { + m_Shadows[shadowHandle].m_Flags &= ~SHADOW_FLAGS_USE_DEPTH_TEXTURE; + } - ClientShadow_t& shadow = m_Shadows[shadowHandle]; - BuildPerspectiveWorldToFlashlightMatrix(shadow.m_WorldToShadow, flashlightState); - shadowmgr->UpdateFlashlightState(shadow.m_ShadowHandle, flashlightState); + if ( flashlightState.m_bOrtho ) + { + BuildOrthoWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); + } + else + { + BuildPerspectiveWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); + } +#else + BuildPerspectiveWorldToFlashlightMatrix( m_Shadows[shadowHandle].m_WorldToShadow, flashlightState ); +#endif + + shadowmgr->UpdateFlashlightState( m_Shadows[shadowHandle].m_ShadowHandle, flashlightState ); } -void CClientShadowMgr::DestroyFlashlight(ClientShadowHandle_t shadowHandle) +void CClientShadowMgr::DestroyFlashlight( ClientShadowHandle_t shadowHandle ) { - DestroyShadow(shadowHandle); + DestroyShadow( shadowHandle ); } //----------------------------------------------------------------------------- // Remove a shadow from the dirty list //----------------------------------------------------------------------------- -void CClientShadowMgr::RemoveShadowFromDirtyList(ClientShadowHandle_t handle) +void CClientShadowMgr::RemoveShadowFromDirtyList( ClientShadowHandle_t handle ) { - int idx = m_DirtyShadows.Find(handle); - if (idx != m_DirtyShadows.InvalidIndex()) + int idx = m_DirtyShadows.Find( handle ); + if ( idx != m_DirtyShadows.InvalidIndex() ) { // Clean up the shadow update bit. - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(m_Shadows[handle].m_Entity); - if (pRenderable) + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( m_Shadows[handle].m_Entity ); + if ( pRenderable ) { - pRenderable->MarkShadowDirty(false); + pRenderable->MarkShadowDirty( false ); } - m_DirtyShadows.RemoveAt(idx); + m_DirtyShadows.RemoveAt( idx ); } } @@ -1974,13 +2299,13 @@ void CClientShadowMgr::RemoveShadowFromDirtyList(ClientShadowHandle_t handle) //----------------------------------------------------------------------------- // Remove a shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::DestroyShadow(ClientShadowHandle_t handle) +void CClientShadowMgr::DestroyShadow( ClientShadowHandle_t handle ) { - Assert(m_Shadows.IsValidIndex(handle)); - RemoveShadowFromDirtyList(handle); - shadowmgr->DestroyShadow(m_Shadows[handle].m_ShadowHandle); - ClientLeafSystem()->RemoveShadow(m_Shadows[handle].m_ClientLeafShadowHandle); - CleanUpRenderToTextureShadow(handle); + Assert( m_Shadows.IsValidIndex(handle) ); + RemoveShadowFromDirtyList( handle ); + shadowmgr->DestroyShadow( m_Shadows[handle].m_ShadowHandle ); + ClientLeafSystem()->RemoveShadow( m_Shadows[handle].m_ClientLeafShadowHandle ); + CleanUpRenderToTextureShadow( handle ); m_Shadows.Remove(handle); } @@ -1988,24 +2313,24 @@ void CClientShadowMgr::DestroyShadow(ClientShadowHandle_t handle) //----------------------------------------------------------------------------- // Build the worldtotexture matrix //----------------------------------------------------------------------------- -void CClientShadowMgr::BuildGeneralWorldToShadowMatrix(VMatrix& matWorldToShadow, - const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec) +void CClientShadowMgr::BuildGeneralWorldToShadowMatrix( VMatrix& matWorldToShadow, + const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec ) { // We're assuming here that xvec + yvec aren't necessary perpendicular // The shadow->world matrix is pretty simple: // Just stick the origin in the translation component // and the vectors in the columns... - matWorldToShadow.SetBasisVectors(xvec, yvec, dir); - matWorldToShadow.SetTranslation(origin); + matWorldToShadow.SetBasisVectors( xvec, yvec, dir ); + matWorldToShadow.SetTranslation( origin ); matWorldToShadow[3][0] = matWorldToShadow[3][1] = matWorldToShadow[3][2] = 0.0f; matWorldToShadow[3][3] = 1.0f; // Now do a general inverse to get matWorldToShadow - MatrixInverseGeneral(matWorldToShadow, matWorldToShadow); + MatrixInverseGeneral( matWorldToShadow, matWorldToShadow ); } -void CClientShadowMgr::BuildWorldToShadowMatrix(VMatrix& matWorldToShadow, const Vector& origin, const Quaternion& quatOrientation) +void CClientShadowMgr::BuildWorldToShadowMatrix( VMatrix& matWorldToShadow, const Vector& origin, const Quaternion& quatOrientation ) { // The shadow->world matrix is pretty simple: // Just stick the origin in the translation component @@ -2013,59 +2338,93 @@ void CClientShadowMgr::BuildWorldToShadowMatrix(VMatrix& matWorldToShadow, const // The inverse of this transposes the rotational component // and the translational component = - (rotation transpose) * origin - matrix3x4_t matOrientation; - QuaternionMatrix(quatOrientation, matOrientation); // Convert quat to matrix3x4 - PositionMatrix(vec3_origin, matOrientation); // Zero out translation elements + matrix3x4_t matOrientation; + QuaternionMatrix( quatOrientation, matOrientation ); // Convert quat to matrix3x4 + PositionMatrix( vec3_origin, matOrientation ); // Zero out translation elements - VMatrix matBasis(matOrientation); // Convert matrix3x4 to VMatrix + VMatrix matBasis( matOrientation ); // Convert matrix3x4 to VMatrix Vector vForward, vLeft, vUp; - matBasis.GetBasisVectors(vForward, vLeft, vUp); - matBasis.SetForward(vLeft); // Bizarre vector flip inherited from earlier code, WTF? - matBasis.SetLeft(vUp); - matBasis.SetUp(vForward); + matBasis.GetBasisVectors( vForward, vLeft, vUp ); + matBasis.SetForward( vLeft ); // Bizarre vector flip inherited from earlier code, WTF? + matBasis.SetLeft( vUp ); + matBasis.SetUp( vForward ); matWorldToShadow = matBasis.Transpose(); // Transpose Vector translation; - Vector3DMultiply(matWorldToShadow, origin, translation); + Vector3DMultiply( matWorldToShadow, origin, translation ); translation *= -1.0f; - matWorldToShadow.SetTranslation(translation); + matWorldToShadow.SetTranslation( translation ); // The the bottom row. matWorldToShadow[3][0] = matWorldToShadow[3][1] = matWorldToShadow[3][2] = 0.0f; matWorldToShadow[3][3] = 1.0f; } -void CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix(VMatrix& matWorldToShadow, const FlashlightState_t& flashlightState) +void CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ) { - VPROF_BUDGET("CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); // Buildworld to shadow matrix, then perspective projection and concatenate VMatrix matWorldToShadowView, matPerspective; - BuildWorldToShadowMatrix(matWorldToShadowView, flashlightState.m_vecLightOrigin, - flashlightState.m_quatOrientation); + BuildWorldToShadowMatrix( matWorldToShadowView, flashlightState.m_vecLightOrigin, + flashlightState.m_quatOrientation ); + + MatrixBuildPerspective( matPerspective, flashlightState.m_fHorizontalFOVDegrees, + flashlightState.m_fVerticalFOVDegrees, + flashlightState.m_NearZ, flashlightState.m_FarZ ); - MatrixBuildPerspective(matPerspective, flashlightState.m_fHorizontalFOVDegrees, - flashlightState.m_fVerticalFOVDegrees, - flashlightState.m_NearZ, flashlightState.m_FarZ); + MatrixMultiply( matPerspective, matWorldToShadowView, matWorldToShadow ); +} + +#ifdef ASW_PROJECTED_TEXTURES +void CClientShadowMgr::BuildOrthoWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ) +{ + VPROF_BUDGET( "CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - MatrixMultiply(matPerspective, matWorldToShadowView, matWorldToShadow); + // Buildworld to shadow matrix, then perspective projection and concatenate + VMatrix matWorldToShadowView, matPerspective; + BuildWorldToShadowMatrix( matWorldToShadowView, flashlightState.m_vecLightOrigin, + flashlightState.m_quatOrientation ); + + MatrixBuildOrtho( matPerspective, + flashlightState.m_fOrthoLeft, flashlightState.m_fOrthoTop, flashlightState.m_fOrthoRight, flashlightState.m_fOrthoBottom, + flashlightState.m_NearZ, flashlightState.m_FarZ ); + + // Shift it z/y to 0 to -2 space + VMatrix addW; + addW.Identity(); + addW[0][3] = -1.0f; + addW[1][3] = -1.0f; + addW[2][3] = 0.0f; + MatrixMultiply( addW, matPerspective, matPerspective ); + + // Flip x/y to positive 0 to 1... flip z to negative + VMatrix scaleHalf; + scaleHalf.Identity(); + scaleHalf[0][0] = -0.5f; + scaleHalf[1][1] = -0.5f; + scaleHalf[2][2] = -1.0f; + MatrixMultiply( scaleHalf, matPerspective, matPerspective ); + + MatrixMultiply( matPerspective, matWorldToShadowView, matWorldToShadow ); } +#endif //----------------------------------------------------------------------------- // Compute the shadow origin and attenuation start distance //----------------------------------------------------------------------------- -float CClientShadowMgr::ComputeLocalShadowOrigin(IClientRenderable* pRenderable, - const Vector& mins, const Vector& maxs, const Vector& localShadowDir, float backupFactor, Vector& origin) +float CClientShadowMgr::ComputeLocalShadowOrigin( IClientRenderable* pRenderable, + const Vector& mins, const Vector& maxs, const Vector& localShadowDir, float backupFactor, Vector& origin ) { // Compute the centroid of the object... Vector vecCentroid; - VectorAdd(mins, maxs, vecCentroid); + VectorAdd( mins, maxs, vecCentroid ); vecCentroid *= 0.5f; Vector vecSize; - VectorSubtract(maxs, mins, vecSize); + VectorSubtract( maxs, mins, vecSize ); float flRadius = vecSize.Length() * 0.5f; // NOTE: The *origin* of the shadow cast is a point on a line passing through @@ -2086,11 +2445,11 @@ float CClientShadowMgr::ComputeLocalShadowOrigin(IClientRenderable* pRenderable, // of that with the localShadowDir. lastly, we're subtracting out the // centroid projection to give us a distance along the localShadowDir to // the front and back of the cube along the direction of the ray. - float centroidProjection = DotProduct(vecCentroid, localShadowDir); + float centroidProjection = DotProduct( vecCentroid, localShadowDir ); float minDist = -centroidProjection; for (int i = 0; i < 3; ++i) { - if (localShadowDir[i] > 0.0f) + if ( localShadowDir[i] > 0.0f ) { minDist += localShadowDir[i] * mins[i]; } @@ -2102,7 +2461,7 @@ float CClientShadowMgr::ComputeLocalShadowOrigin(IClientRenderable* pRenderable, minDist *= backupFactor; - VectorMA(vecCentroid, minDist, localShadowDir, origin); + VectorMA( vecCentroid, minDist, localShadowDir, origin ); return flRadius - minDist; } @@ -2111,9 +2470,9 @@ float CClientShadowMgr::ComputeLocalShadowOrigin(IClientRenderable* pRenderable, //----------------------------------------------------------------------------- // Sorts the components of a vector //----------------------------------------------------------------------------- -static inline void SortAbsVectorComponents(const Vector& src, int* pVecIdx) +static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx ) { - Vector absVec(fabs(src[0]), fabs(src[1]), fabs(src[2])); + Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) ); int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1; if (absVec[2] > absVec[maxIdx]) @@ -2122,7 +2481,7 @@ static inline void SortAbsVectorComponents(const Vector& src, int* pVecIdx) } // always choose something right-handed.... - switch (maxIdx) + switch( maxIdx ) { case 0: pVecIdx[0] = 1; @@ -2146,41 +2505,41 @@ static inline void SortAbsVectorComponents(const Vector& src, int* pVecIdx) //----------------------------------------------------------------------------- // Build the worldtotexture matrix //----------------------------------------------------------------------------- -static void BuildWorldToTextureMatrix(const VMatrix& matWorldToShadow, - const Vector2D& size, VMatrix& matWorldToTexture) +static void BuildWorldToTextureMatrix( const VMatrix& matWorldToShadow, + const Vector2D& size, VMatrix& matWorldToTexture ) { // Build a matrix that maps from shadow space to (u,v) coordinates VMatrix shadowToUnit; - MatrixBuildScale(shadowToUnit, 1.0f / size.x, 1.0f / size.y, 1.0f); + MatrixBuildScale( shadowToUnit, 1.0f / size.x, 1.0f / size.y, 1.0f ); shadowToUnit[0][3] = shadowToUnit[1][3] = 0.5f; // Store off the world to (u,v) transformation - MatrixMultiply(shadowToUnit, matWorldToShadow, matWorldToTexture); + MatrixMultiply( shadowToUnit, matWorldToShadow, matWorldToTexture ); } -static void BuildOrthoWorldToShadowMatrix(VMatrix& worldToShadow, - const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec) +static void BuildOrthoWorldToShadowMatrix( VMatrix& worldToShadow, + const Vector& origin, const Vector& dir, const Vector& xvec, const Vector& yvec ) { // This version is faster and assumes dir, xvec, yvec are perpendicular - AssertFloatEquals(DotProduct(dir, xvec), 0.0f, 1e-3); - AssertFloatEquals(DotProduct(dir, yvec), 0.0f, 1e-3); - AssertFloatEquals(DotProduct(xvec, yvec), 0.0f, 1e-3); + AssertFloatEquals( DotProduct( dir, xvec ), 0.0f, 1e-3 ); + AssertFloatEquals( DotProduct( dir, yvec ), 0.0f, 1e-3 ); + AssertFloatEquals( DotProduct( xvec, yvec ), 0.0f, 1e-3 ); // The shadow->world matrix is pretty simple: // Just stick the origin in the translation component // and the vectors in the columns... // The inverse of this transposes the rotational component // and the translational component = - (rotation transpose) * origin - worldToShadow.SetBasisVectors(xvec, yvec, dir); - MatrixTranspose(worldToShadow, worldToShadow); + worldToShadow.SetBasisVectors( xvec, yvec, dir ); + MatrixTranspose( worldToShadow, worldToShadow ); Vector translation; - Vector3DMultiply(worldToShadow, origin, translation); + Vector3DMultiply( worldToShadow, origin, translation ); translation *= -1.0f; - worldToShadow.SetTranslation(translation); + worldToShadow.SetTranslation( translation ); // The the bottom row. worldToShadow[3][0] = worldToShadow[3][1] = worldToShadow[3][2] = 0.0f; @@ -2191,40 +2550,40 @@ static void BuildOrthoWorldToShadowMatrix(VMatrix& worldToShadow, //----------------------------------------------------------------------------- // Set extra clip planes related to shadows... //----------------------------------------------------------------------------- -void CClientShadowMgr::ClearExtraClipPlanes(ClientShadowHandle_t h) +void CClientShadowMgr::ClearExtraClipPlanes( ClientShadowHandle_t h ) { - shadowmgr->ClearExtraClipPlanes(m_Shadows[h].m_ShadowHandle); + shadowmgr->ClearExtraClipPlanes( m_Shadows[h].m_ShadowHandle ); } -void CClientShadowMgr::AddExtraClipPlane(ClientShadowHandle_t h, const Vector& normal, float dist) +void CClientShadowMgr::AddExtraClipPlane( ClientShadowHandle_t h, const Vector& normal, float dist ) { - shadowmgr->AddExtraClipPlane(m_Shadows[h].m_ShadowHandle, normal, dist); + shadowmgr->AddExtraClipPlane( m_Shadows[h].m_ShadowHandle, normal, dist ); } //----------------------------------------------------------------------------- // Compute the extra shadow planes //----------------------------------------------------------------------------- -void CClientShadowMgr::ComputeExtraClipPlanes(IClientRenderable* pRenderable, - ClientShadowHandle_t handle, const Vector* vec, - const Vector& mins, const Vector& maxs, const Vector& localShadowDir) +void CClientShadowMgr::ComputeExtraClipPlanes( IClientRenderable* pRenderable, + ClientShadowHandle_t handle, const Vector* vec, + const Vector& mins, const Vector& maxs, const Vector& localShadowDir ) { // Compute the world-space position of the corner of the bounding box // that's got the highest dotproduct with the local shadow dir... - Vector origin = pRenderable->GetRenderOrigin(); + Vector origin = pRenderable->GetRenderOrigin( ); float dir[3]; int i; - for (i = 0; i < 3; ++i) + for ( i = 0; i < 3; ++i ) { if (localShadowDir[i] < 0.0f) { - VectorMA(origin, maxs[i], vec[i], origin); + VectorMA( origin, maxs[i], vec[i], origin ); dir[i] = 1; } else { - VectorMA(origin, mins[i], vec[i], origin); + VectorMA( origin, mins[i], vec[i], origin ); dir[i] = -1; } } @@ -2232,37 +2591,37 @@ void CClientShadowMgr::ComputeExtraClipPlanes(IClientRenderable* pRenderable, // Now that we have it, create 3 planes... Vector normal; ClearExtraClipPlanes(handle); - for (i = 0; i < 3; ++i) + for ( i = 0; i < 3; ++i ) { - VectorMultiply(vec[i], dir[i], normal); - float dist = DotProduct(normal, origin); - AddExtraClipPlane(handle, normal, dist); + VectorMultiply( vec[i], dir[i], normal ); + float dist = DotProduct( normal, origin ); + AddExtraClipPlane( handle, normal, dist ); } ClientShadow_t& shadow = m_Shadows[handle]; - C_BaseEntity* pEntity = ClientEntityList().GetBaseEntityFromHandle(shadow.m_Entity); - if (pEntity && pEntity->m_bEnableRenderingClipPlane) + C_BaseEntity *pEntity = ClientEntityList().GetBaseEntityFromHandle( shadow.m_Entity ); + if ( pEntity && pEntity->m_bEnableRenderingClipPlane ) { - normal[0] = -pEntity->m_fRenderingClipPlane[0]; - normal[1] = -pEntity->m_fRenderingClipPlane[1]; - normal[2] = -pEntity->m_fRenderingClipPlane[2]; - AddExtraClipPlane(handle, normal, -pEntity->m_fRenderingClipPlane[3] - 0.5f); + normal[ 0 ] = -pEntity->m_fRenderingClipPlane[ 0 ]; + normal[ 1 ] = -pEntity->m_fRenderingClipPlane[ 1 ]; + normal[ 2 ] = -pEntity->m_fRenderingClipPlane[ 2 ]; + AddExtraClipPlane( handle, normal, -pEntity->m_fRenderingClipPlane[ 3 ] - 0.5f ); } } -inline ShadowType_t CClientShadowMgr::GetActualShadowCastType(ClientShadowHandle_t handle) const +inline ShadowType_t CClientShadowMgr::GetActualShadowCastType( ClientShadowHandle_t handle ) const { - if (handle == CLIENTSHADOW_INVALID_HANDLE) + if ( handle == CLIENTSHADOW_INVALID_HANDLE ) { return SHADOWS_NONE; } - - if (m_Shadows[handle].m_Flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE) + + if ( m_Shadows[handle].m_Flags & SHADOW_FLAGS_USE_RENDER_TO_TEXTURE ) { - return (m_RenderToTextureActive ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_SIMPLE); + return ( m_RenderToTextureActive ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_SIMPLE ); } - else if (m_Shadows[handle].m_Flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE) + else if( m_Shadows[handle].m_Flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) { return SHADOWS_RENDER_TO_DEPTH_TEXTURE; } @@ -2272,9 +2631,9 @@ inline ShadowType_t CClientShadowMgr::GetActualShadowCastType(ClientShadowHandle } } -inline ShadowType_t CClientShadowMgr::GetActualShadowCastType(IClientRenderable* pEnt) const +inline ShadowType_t CClientShadowMgr::GetActualShadowCastType( IClientRenderable *pEnt ) const { - return GetActualShadowCastType(pEnt->GetShadowHandle()); + return GetActualShadowCastType( pEnt->GetShadowHandle() ); } @@ -2284,9 +2643,9 @@ inline ShadowType_t CClientShadowMgr::GetActualShadowCastType(IClientRenderable* class CShadowLeafEnum : public ISpatialLeafEnumerator { public: - bool EnumerateLeaf(int leaf, int context) + bool EnumerateLeaf( int leaf, int context ) { - m_LeafList.AddToTail(leaf); + m_LeafList.AddToTail( leaf ); return true; } @@ -2297,48 +2656,52 @@ class CShadowLeafEnum : public ISpatialLeafEnumerator //----------------------------------------------------------------------------- // Builds a list of leaves inside the shadow volume //----------------------------------------------------------------------------- -static void BuildShadowLeafList(CShadowLeafEnum* pEnum, const Vector& origin, - const Vector& dir, const Vector2D& size, float maxDist) +static void BuildShadowLeafList( CShadowLeafEnum *pEnum, const Vector& origin, + const Vector& dir, const Vector2D& size, float maxDist ) { Ray_t ray; - VectorCopy(origin, ray.m_Start); - VectorMultiply(dir, maxDist, ray.m_Delta); - ray.m_StartOffset.Init(0, 0, 0); + VectorCopy( origin, ray.m_Start ); + VectorMultiply( dir, maxDist, ray.m_Delta ); + ray.m_StartOffset.Init( 0, 0, 0 ); - float flRadius = sqrt(size.x * size.x + size.y * size.y) * 0.5f; - ray.m_Extents.Init(flRadius, flRadius, flRadius); + float flRadius = sqrt( size.x * size.x + size.y * size.y ) * 0.5f; + ray.m_Extents.Init( flRadius, flRadius, flRadius ); ray.m_IsRay = false; ray.m_IsSwept = true; ISpatialQuery* pQuery = engine->GetBSPTreeQuery(); - pQuery->EnumerateLeavesAlongRay(ray, pEnum, 0); + pQuery->EnumerateLeavesAlongRay( ray, pEnum, 0 ); } //----------------------------------------------------------------------------- // Builds a simple blobby shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::BuildOrthoShadow(IClientRenderable* pRenderable, - ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs) +void CClientShadowMgr::BuildOrthoShadow( IClientRenderable* pRenderable, + ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs) { // Get the object's basis Vector vec[3]; - AngleVectors(pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2]); + AngleVectors( pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2] ); vec[1] *= -1.0f; - Vector vecShadowDir = GetShadowDirection(pRenderable); +#ifdef DYNAMIC_RTT_SHADOWS + Vector vecShadowDir = GetShadowDirection( handle ); +#else + Vector vecShadowDir = GetShadowDirection( pRenderable ); +#endif // Project the shadow casting direction into the space of the object Vector localShadowDir; - localShadowDir[0] = DotProduct(vec[0], vecShadowDir); - localShadowDir[1] = DotProduct(vec[1], vecShadowDir); - localShadowDir[2] = DotProduct(vec[2], vecShadowDir); + localShadowDir[0] = DotProduct( vec[0], vecShadowDir ); + localShadowDir[1] = DotProduct( vec[1], vecShadowDir ); + localShadowDir[2] = DotProduct( vec[2], vecShadowDir ); // Figure out which vector has the largest component perpendicular // to the shadow handle... // Sort by how perpendicular it is int vecIdx[3]; - SortAbsVectorComponents(localShadowDir, vecIdx); + SortAbsVectorComponents( localShadowDir, vecIdx ); // Here's our shadow basis vectors; namely the ones that are // most perpendicular to the shadow casting direction @@ -2346,41 +2709,41 @@ void CClientShadowMgr::BuildOrthoShadow(IClientRenderable* pRenderable, Vector yvec = vec[vecIdx[1]]; // Project them into a plane perpendicular to the shadow direction - xvec -= vecShadowDir * DotProduct(vecShadowDir, xvec); - yvec -= vecShadowDir * DotProduct(vecShadowDir, yvec); - VectorNormalize(xvec); - VectorNormalize(yvec); + xvec -= vecShadowDir * DotProduct( vecShadowDir, xvec ); + yvec -= vecShadowDir * DotProduct( vecShadowDir, yvec ); + VectorNormalize( xvec ); + VectorNormalize( yvec ); // Compute the box size Vector boxSize; - VectorSubtract(maxs, mins, boxSize); + VectorSubtract( maxs, mins, 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]], xvec)); - size.y *= fabs(DotProduct(vec[vecIdx[1]], yvec)); + Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] ); + size.x *= fabs( DotProduct( vec[vecIdx[0]], xvec ) ); + size.y *= fabs( DotProduct( vec[vecIdx[1]], yvec ) ); // Add the third component into x and y - size.x += boxSize[vecIdx[2]] * fabs(DotProduct(vec[vecIdx[2]], xvec)); - size.y += boxSize[vecIdx[2]] * fabs(DotProduct(vec[vecIdx[2]], yvec)); + size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], xvec ) ); + size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], yvec ) ); // Bloat a bit, since the shadow wants to extend outside the model a bit size.x += 10.0f; size.y += 10.0f; // Clamp the minimum size - Vector2DMax(size, Vector2D(10.0f, 10.0f), size); + Vector2DMax( size, Vector2D(10.0f, 10.0f), size ); // Place the origin at the point with min dot product with shadow dir Vector org; - float falloffStart = ComputeLocalShadowOrigin(pRenderable, mins, maxs, localShadowDir, 2.0f, org); + float falloffStart = ComputeLocalShadowOrigin( pRenderable, mins, maxs, localShadowDir, 2.0f, org ); // Transform the local origin into world coordinates - Vector worldOrigin = pRenderable->GetRenderOrigin(); - VectorMA(worldOrigin, org.x, vec[0], worldOrigin); - VectorMA(worldOrigin, org.y, vec[1], worldOrigin); - VectorMA(worldOrigin, org.z, vec[2], worldOrigin); + Vector worldOrigin = pRenderable->GetRenderOrigin( ); + VectorMA( worldOrigin, org.x, vec[0], worldOrigin ); + VectorMA( worldOrigin, org.y, vec[1], worldOrigin ); + VectorMA( worldOrigin, org.z, vec[2], worldOrigin ); // FUNKY: A trick to reduce annoying texelization artifacts!? float dx = 1.0f / TEXEL_SIZE_PER_CASTER_SIZE; @@ -2390,101 +2753,105 @@ void CClientShadowMgr::BuildOrthoShadow(IClientRenderable* pRenderable, // NOTE: We gotta use the general matrix because xvec and yvec aren't perp VMatrix matWorldToShadow, matWorldToTexture; - BuildGeneralWorldToShadowMatrix(m_Shadows[handle].m_WorldToShadow, worldOrigin, vecShadowDir, xvec, yvec); - BuildWorldToTextureMatrix(m_Shadows[handle].m_WorldToShadow, size, matWorldToTexture); - Vector2DCopy(size, m_Shadows[handle].m_WorldSize); - + BuildGeneralWorldToShadowMatrix( m_Shadows[handle].m_WorldToShadow, worldOrigin, vecShadowDir, xvec, yvec ); + BuildWorldToTextureMatrix( m_Shadows[handle].m_WorldToShadow, size, matWorldToTexture ); + Vector2DCopy( size, m_Shadows[handle].m_WorldSize ); + // Compute the falloff attenuation // Area computation isn't exact since xvec is not perp to yvec, but close enough // float shadowArea = size.x * size.y; // The entity may be overriding our shadow cast distance - float flShadowCastDistance = GetShadowDistance(pRenderable); + float flShadowCastDistance = GetShadowDistance( pRenderable ); float maxHeight = flShadowCastDistance + falloffStart; //3.0f * sqrt( shadowArea ); CShadowLeafEnum leafList; - BuildShadowLeafList(&leafList, worldOrigin, vecShadowDir, size, maxHeight); + BuildShadowLeafList( &leafList, worldOrigin, vecShadowDir, size, maxHeight ); int nCount = leafList.m_LeafList.Count(); - const int* pLeafList = leafList.m_LeafList.Base(); + const int *pLeafList = leafList.m_LeafList.Base(); - shadowmgr->ProjectShadow(m_Shadows[handle].m_ShadowHandle, worldOrigin, - vecShadowDir, matWorldToTexture, size, nCount, pLeafList, maxHeight, falloffStart, MAX_FALLOFF_AMOUNT, pRenderable->GetRenderOrigin()); + shadowmgr->ProjectShadow( m_Shadows[handle].m_ShadowHandle, worldOrigin, + vecShadowDir, matWorldToTexture, size, nCount, pLeafList, maxHeight, falloffStart, MAX_FALLOFF_AMOUNT, pRenderable->GetRenderOrigin() ); // Compute extra clip planes to prevent poke-thru // FIXME!!!!!!!!!!!!!! Removing this for now since it seems to mess up the blobby shadows. +#ifdef ASW_PROJECTED_TEXTURES + ComputeExtraClipPlanes( pRenderable, handle, vec, mins, maxs, localShadowDir ); +#else // ComputeExtraClipPlanes( pEnt, handle, vec, mins, maxs, localShadowDir ); +#endif // Add the shadow to the client leaf system so it correctly marks // leafs as being affected by a particular shadow - ClientLeafSystem()->ProjectShadow(m_Shadows[handle].m_ClientLeafShadowHandle, nCount, pLeafList); + ClientLeafSystem()->ProjectShadow( m_Shadows[handle].m_ClientLeafShadowHandle, nCount, pLeafList ); } //----------------------------------------------------------------------------- // Visualization.... //----------------------------------------------------------------------------- -void CClientShadowMgr::DrawRenderToTextureDebugInfo(IClientRenderable* pRenderable, const Vector& mins, const Vector& maxs) -{ +void CClientShadowMgr::DrawRenderToTextureDebugInfo( IClientRenderable* pRenderable, const Vector& mins, const Vector& maxs ) +{ // Get the object's basis Vector vec[3]; - AngleVectors(pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2]); + AngleVectors( pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2] ); vec[1] *= -1.0f; Vector vecSize; - VectorSubtract(maxs, mins, vecSize); + VectorSubtract( maxs, mins, vecSize ); Vector vecOrigin = pRenderable->GetRenderOrigin(); Vector start, end, end2; - VectorMA(vecOrigin, mins.x, vec[0], start); - VectorMA(start, mins.y, vec[1], start); - VectorMA(start, mins.z, vec[2], start); - - VectorMA(start, vecSize.x, vec[0], end); - VectorMA(end, vecSize.z, vec[2], end2); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); - debugoverlay->AddLineOverlay(end2, end, 255, 0, 0, true, 0.01); + VectorMA( vecOrigin, mins.x, vec[0], start ); + VectorMA( start, mins.y, vec[1], start ); + VectorMA( start, mins.z, vec[2], start ); - VectorMA(start, vecSize.y, vec[1], end); - VectorMA(end, vecSize.z, vec[2], end2); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); - debugoverlay->AddLineOverlay(end2, end, 255, 0, 0, true, 0.01); + VectorMA( start, vecSize.x, vec[0], end ); + VectorMA( end, vecSize.z, vec[2], end2 ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); + debugoverlay->AddLineOverlay( end2, end, 255, 0, 0, true, 0.01 ); - VectorMA(start, vecSize.z, vec[2], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, vecSize.y, vec[1], end ); + VectorMA( end, vecSize.z, vec[2], end2 ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); + debugoverlay->AddLineOverlay( end2, end, 255, 0, 0, true, 0.01 ); + VectorMA( start, vecSize.z, vec[2], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); + start = end; - VectorMA(start, vecSize.x, vec[0], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, vecSize.x, vec[0], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - VectorMA(start, vecSize.y, vec[1], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, vecSize.y, vec[1], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - VectorMA(end, vecSize.x, vec[0], start); - VectorMA(start, -vecSize.x, vec[0], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( end, vecSize.x, vec[0], start ); + VectorMA( start, -vecSize.x, vec[0], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - VectorMA(start, -vecSize.y, vec[1], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, -vecSize.y, vec[1], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - VectorMA(start, -vecSize.z, vec[2], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, -vecSize.z, vec[2], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); start = end; - VectorMA(start, -vecSize.x, vec[0], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, -vecSize.x, vec[0], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - VectorMA(start, -vecSize.y, vec[1], end); - debugoverlay->AddLineOverlay(start, end, 255, 0, 0, true, 0.01); + VectorMA( start, -vecSize.y, vec[1], end ); + debugoverlay->AddLineOverlay( start, end, 255, 0, 0, true, 0.01 ); - C_BaseEntity* pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity(); - if (pEnt) + C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity(); + if ( pEnt ) { - debugoverlay->AddTextOverlay(vecOrigin, 0, "%d", pEnt->entindex()); + debugoverlay->AddTextOverlay( vecOrigin, 0, "%d", pEnt->entindex() ); } else { - debugoverlay->AddTextOverlay(vecOrigin, 0, "%X", (size_t)pRenderable); + debugoverlay->AddTextOverlay( vecOrigin, 0, "%X", (size_t)pRenderable ); } } @@ -2495,83 +2862,87 @@ extern ConVar cl_shadowtextureoverlaysize; //----------------------------------------------------------------------------- // Builds a more complex shadow... //----------------------------------------------------------------------------- -void CClientShadowMgr::BuildRenderToTextureShadow(IClientRenderable* pRenderable, - ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs) +void CClientShadowMgr::BuildRenderToTextureShadow( IClientRenderable* pRenderable, + ClientShadowHandle_t handle, const Vector& mins, const Vector& maxs) { - if (cl_drawshadowtexture.GetInt()) + if ( cl_drawshadowtexture.GetInt() ) { // Red wireframe bounding box around objects whose RTT shadows are being updated that frame - DrawRenderToTextureDebugInfo(pRenderable, mins, maxs); + DrawRenderToTextureDebugInfo( pRenderable, mins, maxs ); } // Get the object's basis Vector vec[3]; - AngleVectors(pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2]); + AngleVectors( pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2] ); vec[1] *= -1.0f; - Vector vecShadowDir = GetShadowDirection(pRenderable); +#ifdef DYNAMIC_RTT_SHADOWS + Vector vecShadowDir = GetShadowDirection( handle ); +#else + Vector vecShadowDir = GetShadowDirection( pRenderable ); +#endif - // Debugging aid - // const model_t *pModel = pRenderable->GetModel(); - // const char *pDebugName = modelinfo->GetModelName( pModel ); +// Debugging aid +// const model_t *pModel = pRenderable->GetModel(); +// const char *pDebugName = modelinfo->GetModelName( pModel ); - // Project the shadow casting direction into the space of the object + // Project the shadow casting direction into the space of the object Vector localShadowDir; - localShadowDir[0] = DotProduct(vec[0], vecShadowDir); - localShadowDir[1] = DotProduct(vec[1], vecShadowDir); - localShadowDir[2] = DotProduct(vec[2], vecShadowDir); + localShadowDir[0] = DotProduct( vec[0], vecShadowDir ); + localShadowDir[1] = DotProduct( vec[1], vecShadowDir ); + localShadowDir[2] = DotProduct( vec[2], vecShadowDir ); // Compute the box size Vector boxSize; - VectorSubtract(maxs, mins, boxSize); - + VectorSubtract( maxs, mins, boxSize ); + Vector yvec; float fProjMax = 0.0f; - for (int i = 0; i != 3; ++i) + for( int i = 0; i != 3; ++i ) { - Vector test = vec[i] - (vecShadowDir * DotProduct(vecShadowDir, vec[i])); + Vector test = vec[i] - ( vecShadowDir * DotProduct( vecShadowDir, vec[i] ) ); test *= boxSize[i]; //doing after the projection to simplify projection math float fLengthSqr = test.LengthSqr(); - if (fLengthSqr > fProjMax) + if( fLengthSqr > fProjMax ) { fProjMax = fLengthSqr; yvec = test; } - } + } - VectorNormalize(yvec); + VectorNormalize( yvec ); // Compute the x vector Vector xvec; - CrossProduct(yvec, vecShadowDir, xvec); + CrossProduct( yvec, vecShadowDir, xvec ); // 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; - size.x = boxSize.x * fabs(DotProduct(vec[0], xvec)) + - boxSize.y * fabs(DotProduct(vec[1], xvec)) + - boxSize.z * fabs(DotProduct(vec[2], xvec)); - size.y = boxSize.x * fabs(DotProduct(vec[0], yvec)) + - boxSize.y * fabs(DotProduct(vec[1], yvec)) + - boxSize.z * fabs(DotProduct(vec[2], yvec)); + size.x = boxSize.x * fabs( DotProduct( vec[0], xvec ) ) + + boxSize.y * fabs( DotProduct( vec[1], xvec ) ) + + boxSize.z * fabs( DotProduct( vec[2], xvec ) ); + size.y = boxSize.x * fabs( DotProduct( vec[0], yvec ) ) + + boxSize.y * fabs( DotProduct( vec[1], yvec ) ) + + boxSize.z * fabs( DotProduct( vec[2], yvec ) ); size.x += 2.0f * TEXEL_SIZE_PER_CASTER_SIZE; size.y += 2.0f * TEXEL_SIZE_PER_CASTER_SIZE; // Place the origin at the point with min dot product with shadow dir Vector org; - float falloffStart = ComputeLocalShadowOrigin(pRenderable, mins, maxs, localShadowDir, 1.0f, org); + float falloffStart = ComputeLocalShadowOrigin( pRenderable, mins, maxs, localShadowDir, 1.0f, org ); // Transform the local origin into world coordinates - Vector worldOrigin = pRenderable->GetRenderOrigin(); - VectorMA(worldOrigin, org.x, vec[0], worldOrigin); - VectorMA(worldOrigin, org.y, vec[1], worldOrigin); - VectorMA(worldOrigin, org.z, vec[2], worldOrigin); + Vector worldOrigin = pRenderable->GetRenderOrigin( ); + VectorMA( worldOrigin, org.x, vec[0], worldOrigin ); + VectorMA( worldOrigin, org.y, vec[1], worldOrigin ); + VectorMA( worldOrigin, org.z, vec[2], worldOrigin ); VMatrix matWorldToTexture; - BuildOrthoWorldToShadowMatrix(m_Shadows[handle].m_WorldToShadow, worldOrigin, vecShadowDir, xvec, yvec); - BuildWorldToTextureMatrix(m_Shadows[handle].m_WorldToShadow, size, matWorldToTexture); - Vector2DCopy(size, m_Shadows[handle].m_WorldSize); + BuildOrthoWorldToShadowMatrix( m_Shadows[handle].m_WorldToShadow, worldOrigin, vecShadowDir, xvec, yvec ); + BuildWorldToTextureMatrix( m_Shadows[handle].m_WorldToShadow, size, matWorldToTexture ); + Vector2DCopy( size, m_Shadows[handle].m_WorldSize ); // Compute the falloff attenuation // Area computation isn't exact since xvec is not perp to yvec, but close enough @@ -2579,160 +2950,153 @@ void CClientShadowMgr::BuildRenderToTextureShadow(IClientRenderable* pRenderable // float shadowArea = size.x * size.y; // The entity may be overriding our shadow cast distance - float flShadowCastDistance = GetShadowDistance(pRenderable); + float flShadowCastDistance = GetShadowDistance( pRenderable ); float maxHeight = flShadowCastDistance + falloffStart; //3.0f * sqrt( shadowArea ); CShadowLeafEnum leafList; - BuildShadowLeafList(&leafList, worldOrigin, vecShadowDir, size, maxHeight); + BuildShadowLeafList( &leafList, worldOrigin, vecShadowDir, size, maxHeight ); int nCount = leafList.m_LeafList.Count(); - const int* pLeafList = leafList.m_LeafList.Base(); + const int *pLeafList = leafList.m_LeafList.Base(); - shadowmgr->ProjectShadow(m_Shadows[handle].m_ShadowHandle, worldOrigin, - vecShadowDir, matWorldToTexture, size, nCount, pLeafList, maxHeight, falloffStart, MAX_FALLOFF_AMOUNT, pRenderable->GetRenderOrigin()); + shadowmgr->ProjectShadow( m_Shadows[handle].m_ShadowHandle, worldOrigin, + vecShadowDir, matWorldToTexture, size, nCount, pLeafList, maxHeight, falloffStart, MAX_FALLOFF_AMOUNT, pRenderable->GetRenderOrigin() ); // Compute extra clip planes to prevent poke-thru - ComputeExtraClipPlanes(pRenderable, handle, vec, mins, maxs, localShadowDir); + ComputeExtraClipPlanes( pRenderable, handle, vec, mins, maxs, localShadowDir ); // Add the shadow to the client leaf system so it correctly marks // leafs as being affected by a particular shadow - ClientLeafSystem()->ProjectShadow(m_Shadows[handle].m_ClientLeafShadowHandle, nCount, pLeafList); + ClientLeafSystem()->ProjectShadow( m_Shadows[handle].m_ClientLeafShadowHandle, nCount, pLeafList ); } -static void LineDrawHelper(const Vector& startShadowSpace, const Vector& endShadowSpace, - const VMatrix& shadowToWorld, unsigned char r = 255, unsigned char g = 255, - unsigned char b = 255) +static void LineDrawHelper( const Vector &startShadowSpace, const Vector &endShadowSpace, + const VMatrix &shadowToWorld, unsigned char r = 255, unsigned char g = 255, + unsigned char b = 255 ) { Vector startWorldSpace, endWorldSpace; - Vector3DMultiplyPositionProjective(shadowToWorld, startShadowSpace, startWorldSpace); - Vector3DMultiplyPositionProjective(shadowToWorld, endShadowSpace, endWorldSpace); + Vector3DMultiplyPositionProjective( shadowToWorld, startShadowSpace, startWorldSpace ); + Vector3DMultiplyPositionProjective( shadowToWorld, endShadowSpace, endWorldSpace ); - debugoverlay->AddLineOverlay(startWorldSpace + Vector(0.0f, 0.0f, 1.0f), - endWorldSpace + Vector(0.0f, 0.0f, 1.0f), r, g, b, false, -1); + debugoverlay->AddLineOverlay( startWorldSpace + Vector( 0.0f, 0.0f, 1.0f ), + endWorldSpace + Vector( 0.0f, 0.0f, 1.0f ), r, g, b, false, -1 ); } -static void DebugDrawFrustum(const Vector& vOrigin, const VMatrix& matWorldToFlashlight) +static void DebugDrawFrustum( const Vector &vOrigin, const VMatrix &matWorldToFlashlight ) { VMatrix flashlightToWorld; - MatrixInverseGeneral(matWorldToFlashlight, flashlightToWorld); - + MatrixInverseGeneral( matWorldToFlashlight, flashlightToWorld ); + // Draw boundaries of frustum - LineDrawHelper(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 1.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 1.0f, 0.0f), Vector(0.0f, 0.0f, 0.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(1.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(1.0f, 0.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(1.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 0.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(1.0f, 1.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 0.0f, 1.0f), Vector(1.0f, 0.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), flashlightToWorld, 255, 255, 255); - LineDrawHelper(Vector(0.0f, 1.0f, 0.0f), Vector(1.0f, 1.0f, 0.0f), flashlightToWorld, 255, 255, 255); + LineDrawHelper( Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 0.0f, 1.0f ), Vector( 0.0f, 1.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 1.0f, 1.0f ), Vector( 0.0f, 1.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 1.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 1.0f, 0.0f, 0.0f ), Vector( 1.0f, 0.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 1.0f, 0.0f, 1.0f ), Vector( 1.0f, 1.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 1.0f, 1.0f, 1.0f ), Vector( 1.0f, 1.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 1.0f, 1.0f, 0.0f ), Vector( 1.0f, 0.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 0.0f, 0.0f ), Vector( 1.0f, 0.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 0.0f, 1.0f ), Vector( 1.0f, 0.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 1.0f, 1.0f ), Vector( 1.0f, 1.0f, 1.0f ), flashlightToWorld, 255, 255, 255 ); + LineDrawHelper( Vector( 0.0f, 1.0f, 0.0f ), Vector( 1.0f, 1.0f, 0.0f ), flashlightToWorld, 255, 255, 255 ); // Draw RGB triad at front plane - LineDrawHelper(Vector(0.5f, 0.5f, 0.0f), Vector(1.0f, 0.5f, 0.0f), flashlightToWorld, 255, 0, 0); - LineDrawHelper(Vector(0.5f, 0.5f, 0.0f), Vector(0.5f, 1.0f, 0.0f), flashlightToWorld, 0, 255, 0); - LineDrawHelper(Vector(0.5f, 0.5f, 0.0f), Vector(0.5f, 0.5f, 0.35f), flashlightToWorld, 0, 0, 255); + LineDrawHelper( Vector( 0.5f, 0.5f, 0.0f ), Vector( 1.0f, 0.5f, 0.0f ), flashlightToWorld, 255, 0, 0 ); + LineDrawHelper( Vector( 0.5f, 0.5f, 0.0f ), Vector( 0.5f, 1.0f, 0.0f ), flashlightToWorld, 0, 255, 0 ); + LineDrawHelper( Vector( 0.5f, 0.5f, 0.0f ), Vector( 0.5f, 0.5f, 0.35f ), flashlightToWorld, 0, 0, 255 ); } //----------------------------------------------------------------------------- // Builds a list of leaves inside the flashlight volume //----------------------------------------------------------------------------- -static void BuildFlashlightLeafList(CShadowLeafEnum* pEnum, const VMatrix& worldToShadow) +static void BuildFlashlightLeafList( CShadowLeafEnum *pEnum, const VMatrix &worldToShadow ) { // Use an AABB around the frustum to enumerate leaves. Vector mins, maxs; - CalculateAABBFromProjectionMatrix(worldToShadow, &mins, &maxs); + CalculateAABBFromProjectionMatrix( worldToShadow, &mins, &maxs ); ISpatialQuery* pQuery = engine->GetBSPTreeQuery(); - pQuery->EnumerateLeavesInBox(mins, maxs, pEnum, 0); + pQuery->EnumerateLeavesInBox( mins, maxs, pEnum, 0 ); } -void CClientShadowMgr::BuildFlashlight(ClientShadowHandle_t handle) +void CClientShadowMgr::BuildFlashlight( ClientShadowHandle_t handle ) { // For the 360, we just draw flashlights with the main geometry // and bypass the entire shadow casting system. - ClientShadow_t& shadow = m_Shadows[handle]; - if (IsX360() || r_flashlight_version2.GetInt()) + ClientShadow_t &shadow = m_Shadows[handle]; + if ( IsX360() || r_flashlight_version2.GetInt() ) { // This will update the matrices, but not do work to add the flashlight to surfaces - shadowmgr->ProjectFlashlight(shadow.m_ShadowHandle, shadow.m_WorldToShadow, 0, NULL); + shadowmgr->ProjectFlashlight( shadow.m_ShadowHandle, shadow.m_WorldToShadow, 0, NULL ); return; } - VPROF_BUDGET("CClientShadowMgr::BuildFlashlight", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - - // Don't project the flashlight if the frustum AABB is not in our view - Vector mins, maxs; - CalculateAABBFromProjectionMatrix(shadow.m_WorldToShadow, &mins, &maxs); - - if (engine->CullBox(mins, maxs)) - return; + VPROF_BUDGET( "CClientShadowMgr::BuildFlashlight", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); bool bLightModels = r_flashlightmodels.GetBool(); bool bLightSpecificEntity = shadow.m_hTargetEntity.Get() != NULL; - bool bLightWorld = (shadow.m_Flags & SHADOW_FLAGS_LIGHT_WORLD) != 0; + bool bLightWorld = ( shadow.m_Flags & SHADOW_FLAGS_LIGHT_WORLD ) != 0; int nCount = 0; - const int* pLeafList = 0; + const int *pLeafList = 0; CShadowLeafEnum leafList; - if (bLightWorld || (bLightModels && !bLightSpecificEntity)) + if ( bLightWorld || ( bLightModels && !bLightSpecificEntity ) ) { - BuildFlashlightLeafList(&leafList, shadow.m_WorldToShadow); + BuildFlashlightLeafList( &leafList, shadow.m_WorldToShadow ); nCount = leafList.m_LeafList.Count(); pLeafList = leafList.m_LeafList.Base(); } - if (bLightWorld) + if( bLightWorld ) { - shadowmgr->ProjectFlashlight(shadow.m_ShadowHandle, shadow.m_WorldToShadow, nCount, pLeafList); + shadowmgr->ProjectFlashlight( shadow.m_ShadowHandle, shadow.m_WorldToShadow, nCount, pLeafList ); } else { // This should clear all models and surfaces from this shadow - shadowmgr->EnableShadow(shadow.m_ShadowHandle, false); - shadowmgr->EnableShadow(shadow.m_ShadowHandle, true); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, false ); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, true ); } - if (!bLightModels) + if ( !bLightModels ) return; - if (!bLightSpecificEntity) + if ( !bLightSpecificEntity ) { // Add the shadow to the client leaf system so it correctly marks // leafs as being affected by a particular shadow - ClientLeafSystem()->ProjectFlashlight(shadow.m_ClientLeafShadowHandle, nCount, pLeafList); + ClientLeafSystem()->ProjectFlashlight( shadow.m_ClientLeafShadowHandle, nCount, pLeafList ); return; } // We know what we are focused on, so just add the shadow directly to that receiver - Assert(shadow.m_hTargetEntity->GetModel()); + Assert( shadow.m_hTargetEntity->GetModel() ); - C_BaseEntity* pChild = shadow.m_hTargetEntity->FirstMoveChild(); - while (pChild) + C_BaseEntity *pChild = shadow.m_hTargetEntity->FirstMoveChild(); + while( pChild ) { - int modelType = modelinfo->GetModelType(pChild->GetModel()); + int modelType = modelinfo->GetModelType( pChild->GetModel() ); if (modelType == mod_brush) { - AddShadowToReceiver(handle, pChild, SHADOW_RECEIVER_BRUSH_MODEL); + AddShadowToReceiver( handle, pChild, SHADOW_RECEIVER_BRUSH_MODEL ); } - else if (modelType == mod_studio) + else if ( modelType == mod_studio ) { - AddShadowToReceiver(handle, pChild, SHADOW_RECEIVER_STUDIO_MODEL); + AddShadowToReceiver( handle, pChild, SHADOW_RECEIVER_STUDIO_MODEL ); } pChild = pChild->NextMovePeer(); } - int modelType = modelinfo->GetModelType(shadow.m_hTargetEntity->GetModel()); + int modelType = modelinfo->GetModelType( shadow.m_hTargetEntity->GetModel() ); if (modelType == mod_brush) { - AddShadowToReceiver(handle, shadow.m_hTargetEntity, SHADOW_RECEIVER_BRUSH_MODEL); + AddShadowToReceiver( handle, shadow.m_hTargetEntity, SHADOW_RECEIVER_BRUSH_MODEL ); } - else if (modelType == mod_studio) + else if ( modelType == mod_studio ) { - AddShadowToReceiver(handle, shadow.m_hTargetEntity, SHADOW_RECEIVER_STUDIO_MODEL); + AddShadowToReceiver( handle, shadow.m_hTargetEntity, SHADOW_RECEIVER_STUDIO_MODEL ); } } @@ -2740,27 +3104,27 @@ void CClientShadowMgr::BuildFlashlight(ClientShadowHandle_t handle) //----------------------------------------------------------------------------- // Adds the child bounds to the bounding box //----------------------------------------------------------------------------- -void CClientShadowMgr::AddChildBounds(matrix3x4_t& matWorldToBBox, IClientRenderable* pParent, Vector& vecMins, Vector& vecMaxs) +void CClientShadowMgr::AddChildBounds( matrix3x4_t &matWorldToBBox, IClientRenderable* pParent, Vector &vecMins, Vector &vecMaxs ) { Vector vecChildMins, vecChildMaxs; Vector vecNewChildMins, vecNewChildMaxs; matrix3x4_t childToBBox; - IClientRenderable* pChild = pParent->FirstShadowChild(); - while (pChild) + IClientRenderable *pChild = pParent->FirstShadowChild(); + while( pChild ) { // Transform the child bbox into the space of the main bbox // FIXME: Optimize this? - if (GetActualShadowCastType(pChild) != SHADOWS_NONE) + if ( GetActualShadowCastType( pChild ) != SHADOWS_NONE) { - pChild->GetShadowRenderBounds(vecChildMins, vecChildMaxs, SHADOWS_RENDER_TO_TEXTURE); - ConcatTransforms(matWorldToBBox, pChild->RenderableToWorldTransform(), childToBBox); - TransformAABB(childToBBox, vecChildMins, vecChildMaxs, vecNewChildMins, vecNewChildMaxs); - VectorMin(vecMins, vecNewChildMins, vecMins); - VectorMax(vecMaxs, vecNewChildMaxs, vecMaxs); + pChild->GetShadowRenderBounds( vecChildMins, vecChildMaxs, SHADOWS_RENDER_TO_TEXTURE ); + ConcatTransforms( matWorldToBBox, pChild->RenderableToWorldTransform(), childToBBox ); + TransformAABB( childToBBox, vecChildMins, vecChildMaxs, vecNewChildMins, vecNewChildMaxs ); + VectorMin( vecMins, vecNewChildMins, vecMins ); + VectorMax( vecMaxs, vecNewChildMaxs, vecMaxs ); } - AddChildBounds(matWorldToBBox, pChild, vecMins, vecMaxs); + AddChildBounds( matWorldToBBox, pChild, vecMins, vecMaxs ); pChild = pChild->NextShadowPeer(); } } @@ -2769,24 +3133,24 @@ void CClientShadowMgr::AddChildBounds(matrix3x4_t& matWorldToBBox, IClientRender //----------------------------------------------------------------------------- // Compute a bounds for the entity + children //----------------------------------------------------------------------------- -void CClientShadowMgr::ComputeHierarchicalBounds(IClientRenderable* pRenderable, Vector& vecMins, Vector& vecMaxs) +void CClientShadowMgr::ComputeHierarchicalBounds( IClientRenderable *pRenderable, Vector &vecMins, Vector &vecMaxs ) { - ShadowType_t shadowType = GetActualShadowCastType(pRenderable); + ShadowType_t shadowType = GetActualShadowCastType( pRenderable ); - pRenderable->GetShadowRenderBounds(vecMins, vecMaxs, shadowType); + pRenderable->GetShadowRenderBounds( vecMins, vecMaxs, shadowType ); // We could use a good solution for this in the regular PC build, since // it causes lots of extra bone setups for entities you can't see. - if (IsPC()) + if ( IsPC() ) { - IClientRenderable* pChild = pRenderable->FirstShadowChild(); + IClientRenderable *pChild = pRenderable->FirstShadowChild(); // Don't recurse down the tree when we hit a blobby shadow - if (pChild && shadowType != SHADOWS_SIMPLE) + if ( pChild && shadowType != SHADOWS_SIMPLE ) { matrix3x4_t matWorldToBBox; - MatrixInvert(pRenderable->RenderableToWorldTransform(), matWorldToBBox); - AddChildBounds(matWorldToBBox, pRenderable, vecMins, vecMaxs); + MatrixInvert( pRenderable->RenderableToWorldTransform(), matWorldToBBox ); + AddChildBounds( matWorldToBBox, pRenderable, vecMins, vecMaxs ); } } } @@ -2795,52 +3159,52 @@ void CClientShadowMgr::ComputeHierarchicalBounds(IClientRenderable* pRenderable, //----------------------------------------------------------------------------- // Shadow update functions //----------------------------------------------------------------------------- -void CClientShadowMgr::UpdateStudioShadow(IClientRenderable* pRenderable, ClientShadowHandle_t handle) +void CClientShadowMgr::UpdateStudioShadow( IClientRenderable *pRenderable, ClientShadowHandle_t handle ) { - if (!(m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT)) + if( !( m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT ) ) { Vector mins, maxs; - ComputeHierarchicalBounds(pRenderable, mins, maxs); + ComputeHierarchicalBounds( pRenderable, mins, maxs ); - ShadowType_t shadowType = GetActualShadowCastType(handle); - if (shadowType != SHADOWS_RENDER_TO_TEXTURE) + ShadowType_t shadowType = GetActualShadowCastType( handle ); + if ( shadowType != SHADOWS_RENDER_TO_TEXTURE ) { - BuildOrthoShadow(pRenderable, handle, mins, maxs); + BuildOrthoShadow( pRenderable, handle, mins, maxs ); } else { - BuildRenderToTextureShadow(pRenderable, handle, mins, maxs); + BuildRenderToTextureShadow( pRenderable, handle, mins, maxs ); } } else { - BuildFlashlight(handle); + BuildFlashlight( handle ); } } -void CClientShadowMgr::UpdateBrushShadow(IClientRenderable* pRenderable, ClientShadowHandle_t handle) +void CClientShadowMgr::UpdateBrushShadow( IClientRenderable *pRenderable, ClientShadowHandle_t handle ) { - if (!(m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT)) + if( !( m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT ) ) { // Compute the bounding box in the space of the shadow... Vector mins, maxs; - ComputeHierarchicalBounds(pRenderable, mins, maxs); + ComputeHierarchicalBounds( pRenderable, mins, maxs ); - ShadowType_t shadowType = GetActualShadowCastType(handle); - if (shadowType != SHADOWS_RENDER_TO_TEXTURE) + ShadowType_t shadowType = GetActualShadowCastType( handle ); + if ( shadowType != SHADOWS_RENDER_TO_TEXTURE ) { - BuildOrthoShadow(pRenderable, handle, mins, maxs); + BuildOrthoShadow( pRenderable, handle, mins, maxs ); } else { - BuildRenderToTextureShadow(pRenderable, handle, mins, maxs); + BuildRenderToTextureShadow( pRenderable, handle, mins, maxs ); } } else { - VPROF_BUDGET("CClientShadowMgr::UpdateBrushShadow", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::UpdateBrushShadow", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - BuildFlashlight(handle); + BuildFlashlight( handle ); } } @@ -2859,19 +3223,19 @@ static ConCommand r_shadowbreak("r_shadowbreak", ShadowBreak_f); #endif // _DEBUG -bool CClientShadowMgr::WillParentRenderBlobbyShadow(IClientRenderable* pRenderable) +bool CClientShadowMgr::WillParentRenderBlobbyShadow( IClientRenderable *pRenderable ) { - if (!pRenderable) + if ( !pRenderable ) return false; - IClientRenderable* pShadowParent = pRenderable->GetShadowParent(); - if (!pShadowParent) + IClientRenderable *pShadowParent = pRenderable->GetShadowParent(); + if ( !pShadowParent ) return false; // If there's *no* shadow casting type, then we want to see if we can render into its parent - ShadowType_t shadowType = GetActualShadowCastType(pShadowParent); - if (shadowType == SHADOWS_NONE) - return WillParentRenderBlobbyShadow(pShadowParent); + ShadowType_t shadowType = GetActualShadowCastType( pShadowParent ); + if ( shadowType == SHADOWS_NONE ) + return WillParentRenderBlobbyShadow( pShadowParent ); return shadowType == SHADOWS_SIMPLE; } @@ -2880,23 +3244,23 @@ bool CClientShadowMgr::WillParentRenderBlobbyShadow(IClientRenderable* pRenderab //----------------------------------------------------------------------------- // Are we the child of a shadow with render-to-texture? //----------------------------------------------------------------------------- -bool CClientShadowMgr::ShouldUseParentShadow(IClientRenderable* pRenderable) +bool CClientShadowMgr::ShouldUseParentShadow( IClientRenderable *pRenderable ) { - if (!pRenderable) + if ( !pRenderable ) return false; - IClientRenderable* pShadowParent = pRenderable->GetShadowParent(); - if (!pShadowParent) + IClientRenderable *pShadowParent = pRenderable->GetShadowParent(); + if ( !pShadowParent ) return false; // Can't render into the parent if the parent is blobby - ShadowType_t shadowType = GetActualShadowCastType(pShadowParent); - if (shadowType == SHADOWS_SIMPLE) + ShadowType_t shadowType = GetActualShadowCastType( pShadowParent ); + if ( shadowType == SHADOWS_SIMPLE ) return false; // If there's *no* shadow casting type, then we want to see if we can render into its parent - if (shadowType == SHADOWS_NONE) - return ShouldUseParentShadow(pShadowParent); + if ( shadowType == SHADOWS_NONE ) + return ShouldUseParentShadow( pShadowParent ); // Here, the parent uses a render-to-texture shadow return true; @@ -2908,9 +3272,14 @@ bool CClientShadowMgr::ShouldUseParentShadow(IClientRenderable* pRenderable) //----------------------------------------------------------------------------- void CClientShadowMgr::PreRender() { +#ifdef ASW_PROJECTED_TEXTURES + // only update shadows once per frame + if( gpGlobals->framecount == m_nPrevFrameCount ) + return; m_nPrevFrameCount = gpGlobals->framecount; +#endif - VPROF_BUDGET("CClientShadowMgr::PreRender", VPROF_BUDGETGROUP_SHADOW_RENDERING); + VPROF_BUDGET( "CClientShadowMgr::PreRender", VPROF_BUDGETGROUP_SHADOW_RENDERING ); MDLCACHE_CRITICAL_SECTION(); // @@ -2919,35 +3288,35 @@ void CClientShadowMgr::PreRender() { // VPROF scope - VPROF_BUDGET("CClientShadowMgr::PreRender", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::PreRender", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); // If someone turned shadow depth mapping on but we can't do it, force it off - if (r_flashlightdepthtexture.GetBool() && !materials->SupportsShadowDepthTextures()) + if ( r_flashlightdepthtexture.GetBool() && !materials->SupportsShadowDepthTextures() ) { - r_flashlightdepthtexture.SetValue(0); - ShutdownDepthTextureShadows(); + r_flashlightdepthtexture.SetValue( 0 ); + ShutdownDepthTextureShadows(); } - bool bDepthTextureActive = r_flashlightdepthtexture.GetBool(); + bool bDepthTextureActive = r_flashlightdepthtexture.GetBool(); int nDepthTextureResolution = r_flashlightdepthres.GetInt(); // If shadow depth texture size or enable/disable changed, do appropriate deallocation/(re)allocation - if ((bDepthTextureActive != m_bDepthTextureActive) || (nDepthTextureResolution != m_nDepthTextureResolution)) + if ( ( bDepthTextureActive != m_bDepthTextureActive ) || ( nDepthTextureResolution != m_nDepthTextureResolution ) ) { // If shadow depth texturing remains on, but resolution changed, shut down and reinitialize depth textures - if ((bDepthTextureActive == true) && (m_bDepthTextureActive == true) && - (nDepthTextureResolution != m_nDepthTextureResolution)) + if ( ( bDepthTextureActive == true ) && ( m_bDepthTextureActive == true ) && + ( nDepthTextureResolution != m_nDepthTextureResolution ) ) { - ShutdownDepthTextureShadows(); + ShutdownDepthTextureShadows(); InitDepthTextureShadows(); } else { - if (m_bDepthTextureActive && !bDepthTextureActive) // Turning off shadow depth texturing + if ( m_bDepthTextureActive && !bDepthTextureActive ) // Turning off shadow depth texturing { ShutdownDepthTextureShadows(); } - else if (bDepthTextureActive && !m_bDepthTextureActive) // Turning on shadow depth mapping + else if ( bDepthTextureActive && !m_bDepthTextureActive) // Turning on shadow depth mapping { InitDepthTextureShadows(); } @@ -2959,10 +3328,10 @@ void CClientShadowMgr::PreRender() // -- Render to Texture Shadows ----------------------- // - bool bRenderToTextureActive = false;// r_shadowrendertotexture.GetBool(); - if (bRenderToTextureActive != m_RenderToTextureActive) + bool bRenderToTextureActive = r_shadowrendertotexture.GetBool(); + if ( bRenderToTextureActive != m_RenderToTextureActive ) { - if (m_RenderToTextureActive) + if ( m_RenderToTextureActive ) { ShutdownRenderToTextureShadows(); } @@ -2978,44 +3347,62 @@ void CClientShadowMgr::PreRender() m_bUpdatingDirtyShadows = true; unsigned short i = m_DirtyShadows.FirstInorder(); - while (i != m_DirtyShadows.InvalidIndex()) + while ( i != m_DirtyShadows.InvalidIndex() ) { MDLCACHE_CRITICAL_SECTION(); - ClientShadowHandle_t& handle = m_DirtyShadows[i]; - Assert(m_Shadows.IsValidIndex(handle)); - UpdateProjectedTextureInternal(handle, false); + ClientShadowHandle_t& handle = m_DirtyShadows[ i ]; +#ifdef DYNAMIC_RTT_SHADOWS + UpdateDirtyShadow(handle); +#else + Assert( m_Shadows.IsValidIndex( handle ) ); + UpdateProjectedTextureInternal( handle, false ); +#endif i = m_DirtyShadows.NextInorder(i); } m_DirtyShadows.RemoveAll(); // Transparent shadows must remain dirty, since they were not re-projected int nCount = m_TransparentShadows.Count(); - for (int i = 0; i < nCount; ++i) + for ( int i = 0; i < nCount; ++i ) { - m_DirtyShadows.Insert(m_TransparentShadows[i]); + m_DirtyShadows.Insert( m_TransparentShadows[i] ); } m_TransparentShadows.RemoveAll(); m_bUpdatingDirtyShadows = false; } +#ifdef DYNAMIC_RTT_SHADOWS +//----------------------------------------------------------------------------- +// Updates a single dirty shadow +//----------------------------------------------------------------------------- +void CClientShadowMgr::UpdateDirtyShadow( ClientShadowHandle_t handle ) +{ + Assert( m_Shadows.IsValidIndex( handle ) ); + if ( IsShadowingFromWorldLights() ) + { + UpdateShadowDirectionFromLocalLightSource( handle ); + } + UpdateProjectedTextureInternal( handle, false ); +} +#endif //----------------------------------------------------------------------------- // Gets the entity whose shadow this shadow will render into //----------------------------------------------------------------------------- -IClientRenderable* CClientShadowMgr::GetParentShadowEntity(ClientShadowHandle_t handle) +IClientRenderable *CClientShadowMgr::GetParentShadowEntity( ClientShadowHandle_t handle ) { ClientShadow_t& shadow = m_Shadows[handle]; - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - if (pRenderable) + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + if ( pRenderable ) { - if (ShouldUseParentShadow(pRenderable)) + if ( ShouldUseParentShadow( pRenderable ) ) { - IClientRenderable* pParent = pRenderable->GetShadowParent(); - while (GetActualShadowCastType(pParent) == SHADOWS_NONE) + IClientRenderable *pParent = pRenderable->GetShadowParent(); + while ( GetActualShadowCastType( pParent ) == SHADOWS_NONE ) { pParent = pParent->GetShadowParent(); - Assert(pParent); + Assert( pParent ); } return pParent; } @@ -3027,31 +3414,31 @@ IClientRenderable* CClientShadowMgr::GetParentShadowEntity(ClientShadowHandle_t //----------------------------------------------------------------------------- // Marks a shadow as needing re-projection //----------------------------------------------------------------------------- -void CClientShadowMgr::AddToDirtyShadowList(ClientShadowHandle_t handle, bool bForce) +void CClientShadowMgr::AddToDirtyShadowList( ClientShadowHandle_t handle, bool bForce ) { // Don't add to the dirty shadow list while we're iterating over it // The only way this can happen is if a child is being rendered into a parent // shadow, and we don't need it to be added to the dirty list in that case. - if (m_bUpdatingDirtyShadows) + if ( m_bUpdatingDirtyShadows ) return; - if (handle == CLIENTSHADOW_INVALID_HANDLE) + if ( handle == CLIENTSHADOW_INVALID_HANDLE ) return; - Assert(m_DirtyShadows.Find(handle) == m_DirtyShadows.InvalidIndex()); - m_DirtyShadows.Insert(handle); + Assert( m_DirtyShadows.Find( handle ) == m_DirtyShadows.InvalidIndex() ); + m_DirtyShadows.Insert( handle ); // This pretty much guarantees we'll recompute the shadow - if (bForce) + if ( bForce ) { - m_Shadows[handle].m_LastAngles.Init(FLT_MAX, FLT_MAX, FLT_MAX); + m_Shadows[handle].m_LastAngles.Init( FLT_MAX, FLT_MAX, FLT_MAX ); } // If we use our parent shadow, then it's dirty too... - IClientRenderable* pParent = GetParentShadowEntity(handle); - if (pParent) + IClientRenderable *pParent = GetParentShadowEntity( handle ); + if ( pParent ) { - AddToDirtyShadowList(pParent, bForce); + AddToDirtyShadowList( pParent, bForce ); } } @@ -3059,40 +3446,40 @@ void CClientShadowMgr::AddToDirtyShadowList(ClientShadowHandle_t handle, bool bF //----------------------------------------------------------------------------- // Marks a shadow as needing re-projection //----------------------------------------------------------------------------- -void CClientShadowMgr::AddToDirtyShadowList(IClientRenderable* pRenderable, bool bForce) +void CClientShadowMgr::AddToDirtyShadowList( IClientRenderable *pRenderable, bool bForce ) { // Don't add to the dirty shadow list while we're iterating over it // The only way this can happen is if a child is being rendered into a parent // shadow, and we don't need it to be added to the dirty list in that case. - if (m_bUpdatingDirtyShadows) + if ( m_bUpdatingDirtyShadows ) return; // Are we already in the dirty list? - if (pRenderable->IsShadowDirty()) + if ( pRenderable->IsShadowDirty( ) ) return; ClientShadowHandle_t handle = pRenderable->GetShadowHandle(); - if (handle == CLIENTSHADOW_INVALID_HANDLE) + if ( handle == CLIENTSHADOW_INVALID_HANDLE ) return; #ifdef _DEBUG // Make sure everything's consistent - if (handle != CLIENTSHADOW_INVALID_HANDLE) + if ( handle != CLIENTSHADOW_INVALID_HANDLE ) { - IClientRenderable* pShadowRenderable = ClientEntityList().GetClientRenderableFromHandle(m_Shadows[handle].m_Entity); - Assert(pRenderable == pShadowRenderable); + IClientRenderable *pShadowRenderable = ClientEntityList().GetClientRenderableFromHandle( m_Shadows[handle].m_Entity ); + Assert( pRenderable == pShadowRenderable ); } #endif - pRenderable->MarkShadowDirty(true); - AddToDirtyShadowList(handle, bForce); + pRenderable->MarkShadowDirty( true ); + AddToDirtyShadowList( handle, bForce ); } //----------------------------------------------------------------------------- // Marks the render-to-texture shadow as needing to be re-rendered //----------------------------------------------------------------------------- -void CClientShadowMgr::MarkRenderToTextureShadowDirty(ClientShadowHandle_t handle) +void CClientShadowMgr::MarkRenderToTextureShadowDirty( ClientShadowHandle_t handle ) { // Don't add bogus handles! if (handle != CLIENTSHADOW_INVALID_HANDLE) @@ -3102,11 +3489,11 @@ void CClientShadowMgr::MarkRenderToTextureShadowDirty(ClientShadowHandle_t handl shadow.m_Flags |= SHADOW_FLAGS_TEXTURE_DIRTY; // If we use our parent shadow, then it's dirty too... - IClientRenderable* pParent = GetParentShadowEntity(handle); - if (pParent) + IClientRenderable *pParent = GetParentShadowEntity( handle ); + if ( pParent ) { ClientShadowHandle_t parentHandle = pParent->GetShadowHandle(); - if (parentHandle != CLIENTSHADOW_INVALID_HANDLE) + if ( parentHandle != CLIENTSHADOW_INVALID_HANDLE ) { m_Shadows[parentHandle].m_Flags |= SHADOW_FLAGS_TEXTURE_DIRTY; } @@ -3118,23 +3505,23 @@ void CClientShadowMgr::MarkRenderToTextureShadowDirty(ClientShadowHandle_t handl //----------------------------------------------------------------------------- // Update a shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::UpdateShadow(ClientShadowHandle_t handle, bool force) +void CClientShadowMgr::UpdateShadow( ClientShadowHandle_t handle, bool force ) { ClientShadow_t& shadow = m_Shadows[handle]; // Get the client entity.... - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - if (!pRenderable) + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + if ( !pRenderable ) { // Retire the shadow if the entity is gone - DestroyShadow(handle); + DestroyShadow( handle ); return; } // Don't bother if there's no model on the renderable - if (!pRenderable->GetModel()) + if ( !pRenderable->GetModel() ) { - pRenderable->MarkShadowDirty(false); + pRenderable->MarkShadowDirty( false ); return; } @@ -3142,11 +3529,11 @@ void CClientShadowMgr::UpdateShadow(ClientShadowHandle_t handle, bool force) // off by a frame. We could move the code in PreRender to occur after world // list building is done to fix this issue. // Don't bother with it if the shadow is totally transparent - const ShadowInfo_t& shadowInfo = shadowmgr->GetInfo(shadow.m_ShadowHandle); - if (shadowInfo.m_FalloffBias == 255) + const ShadowInfo_t &shadowInfo = shadowmgr->GetInfo( shadow.m_ShadowHandle ); + if ( shadowInfo.m_FalloffBias == 255 ) { - shadowmgr->EnableShadow(shadow.m_ShadowHandle, false); - m_TransparentShadows.AddToTail(handle); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, false ); + m_TransparentShadows.AddToTail( handle ); return; } @@ -3158,14 +3545,14 @@ void CClientShadowMgr::UpdateShadow(ClientShadowHandle_t handle, bool force) #endif // Hierarchical children shouldn't be projecting shadows... // Check to see if it's a child of an entity with a render-to-texture shadow... - if (ShouldUseParentShadow(pRenderable) || WillParentRenderBlobbyShadow(pRenderable)) + if ( ShouldUseParentShadow( pRenderable ) || WillParentRenderBlobbyShadow( pRenderable ) ) { - shadowmgr->EnableShadow(shadow.m_ShadowHandle, false); - pRenderable->MarkShadowDirty(false); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, false ); + pRenderable->MarkShadowDirty( false ); return; } - shadowmgr->EnableShadow(shadow.m_ShadowHandle, true); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, true ); // Figure out if the shadow moved... // Even though we have dirty bits, some entities @@ -3173,24 +3560,28 @@ void CClientShadowMgr::UpdateShadow(ClientShadowHandle_t handle, bool force) const Vector& origin = pRenderable->GetRenderOrigin(); const QAngle& angles = pRenderable->GetRenderAngles(); +#ifdef DYNAMIC_RTT_SHADOWS + if (force || (origin != shadow.m_LastOrigin) || (angles != shadow.m_LastAngles) || shadow.m_LightPosLerp < 1.0f) +#else if (force || (origin != shadow.m_LastOrigin) || (angles != shadow.m_LastAngles)) +#endif { // Store off the new pos/orientation - VectorCopy(origin, shadow.m_LastOrigin); - VectorCopy(angles, shadow.m_LastAngles); + VectorCopy( origin, shadow.m_LastOrigin ); + VectorCopy( angles, shadow.m_LastAngles ); - CMatRenderContextPtr pRenderContext(materials); - const model_t* pModel = pRenderable->GetModel(); + CMatRenderContextPtr pRenderContext( materials ); + const model_t *pModel = pRenderable->GetModel(); MaterialFogMode_t fogMode = pRenderContext->GetFogMode(); - pRenderContext->FogMode(MATERIAL_FOG_NONE); - switch (modelinfo->GetModelType(pModel)) + pRenderContext->FogMode( MATERIAL_FOG_NONE ); + switch( modelinfo->GetModelType( pModel ) ) { case mod_brush: - UpdateBrushShadow(pRenderable, handle); + UpdateBrushShadow( pRenderable, handle ); break; case mod_studio: - UpdateStudioShadow(pRenderable, handle); + UpdateStudioShadow( pRenderable, handle ); break; default: @@ -3198,40 +3589,40 @@ void CClientShadowMgr::UpdateShadow(ClientShadowHandle_t handle, bool force) Assert(0); break; } - pRenderContext->FogMode(fogMode); + pRenderContext->FogMode( fogMode ); } // NOTE: We can't do this earlier because pEnt->GetRenderOrigin() can // provoke a recomputation of render origin, which, for aiments, can cause everything // to be marked as dirty. So don't clear the flag until this point. - pRenderable->MarkShadowDirty(false); + pRenderable->MarkShadowDirty( false ); } //----------------------------------------------------------------------------- // Update a shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::UpdateProjectedTextureInternal(ClientShadowHandle_t handle, bool force) +void CClientShadowMgr::UpdateProjectedTextureInternal( ClientShadowHandle_t handle, bool force ) { ClientShadow_t& shadow = m_Shadows[handle]; - if (shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) + if( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) { - VPROF_BUDGET("CClientShadowMgr::UpdateProjectedTextureInternal", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::UpdateProjectedTextureInternal", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - Assert((shadow.m_Flags & SHADOW_FLAGS_SHADOW) == 0); + Assert( ( shadow.m_Flags & SHADOW_FLAGS_SHADOW ) == 0 ); ClientShadow_t& shadow = m_Shadows[handle]; - shadowmgr->EnableShadow(shadow.m_ShadowHandle, true); + shadowmgr->EnableShadow( shadow.m_ShadowHandle, true ); // FIXME: What's the difference between brush and model shadows for light projectors? Answer: nothing. - UpdateBrushShadow(NULL, handle); + UpdateBrushShadow( NULL, handle ); } else { - Assert(shadow.m_Flags & SHADOW_FLAGS_SHADOW); - Assert((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) == 0); - UpdateShadow(handle, force); + Assert( shadow.m_Flags & SHADOW_FLAGS_SHADOW ); + Assert( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ); + UpdateShadow( handle, force ); } } @@ -3239,72 +3630,76 @@ void CClientShadowMgr::UpdateProjectedTextureInternal(ClientShadowHandle_t handl //----------------------------------------------------------------------------- // Update a shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::UpdateProjectedTexture(ClientShadowHandle_t handle, bool force) +void CClientShadowMgr::UpdateProjectedTexture( ClientShadowHandle_t handle, bool force ) { - VPROF_BUDGET("CClientShadowMgr::UpdateProjectedTexture", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::UpdateProjectedTexture", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - if (handle == CLIENTSHADOW_INVALID_HANDLE) + if ( handle == CLIENTSHADOW_INVALID_HANDLE ) return; -#ifndef VANCE // NOTE: This can only work for flashlights, since UpdateProjectedTextureInternal // depends on the falloff offset to cull shadows. - ClientShadow_t& shadow = m_Shadows[handle]; - - if ((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) == 0) + ClientShadow_t &shadow = m_Shadows[ handle ]; + if( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ) { - Warning("CClientShadowMgr::UpdateProjectedTexture can only be used with flashlights!\n"); + Warning( "CClientShadowMgr::UpdateProjectedTexture can only be used with flashlights!\n" ); return; } -#endif // !VANCE - - UpdateProjectedTextureInternal(handle, force); - RemoveShadowFromDirtyList(handle); + UpdateProjectedTextureInternal( handle, force ); + RemoveShadowFromDirtyList( handle ); } - + //----------------------------------------------------------------------------- // Computes bounding sphere //----------------------------------------------------------------------------- -void CClientShadowMgr::ComputeBoundingSphere(IClientRenderable* pRenderable, Vector& origin, float& radius) +void CClientShadowMgr::ComputeBoundingSphere( IClientRenderable* pRenderable, Vector& origin, float& radius ) { - Assert(pRenderable); + Assert( pRenderable ); Vector mins, maxs; - pRenderable->GetShadowRenderBounds(mins, maxs, GetActualShadowCastType(pRenderable)); + pRenderable->GetShadowRenderBounds( mins, maxs, GetActualShadowCastType( pRenderable ) ); Vector size; - VectorSubtract(maxs, mins, size); + VectorSubtract( maxs, mins, size ); radius = size.Length() * 0.5f; // Compute centroid (local space) Vector centroid; - VectorAdd(mins, maxs, centroid); + VectorAdd( mins, maxs, centroid ); centroid *= 0.5f; // Transform centroid into world space Vector vec[3]; - AngleVectors(pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2]); + AngleVectors( pRenderable->GetRenderAngles(), &vec[0], &vec[1], &vec[2] ); vec[1] *= -1.0f; - VectorCopy(pRenderable->GetRenderOrigin(), origin); - VectorMA(origin, centroid.x, vec[0], origin); - VectorMA(origin, centroid.y, vec[1], origin); - VectorMA(origin, centroid.z, vec[2], origin); + VectorCopy( pRenderable->GetRenderOrigin(), origin ); + VectorMA( origin, centroid.x, vec[0], origin ); + VectorMA( origin, centroid.y, vec[1], origin ); + VectorMA( origin, centroid.z, vec[2], origin ); } //----------------------------------------------------------------------------- // Computes a rough AABB encompassing the volume of the shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::ComputeShadowBBox(IClientRenderable* pRenderable, const Vector& vecAbsCenter, float flRadius, Vector* pAbsMins, Vector* pAbsMaxs) +#ifdef DYNAMIC_RTT_SHADOWS +void CClientShadowMgr::ComputeShadowBBox( IClientRenderable *pRenderable, ClientShadowHandle_t shadowHandle, const Vector &vecAbsCenter, float flRadius, Vector *pAbsMins, Vector *pAbsMaxs ) +#else +void CClientShadowMgr::ComputeShadowBBox( IClientRenderable *pRenderable, const Vector &vecAbsCenter, float flRadius, Vector *pAbsMins, Vector *pAbsMaxs ) +#endif { // This is *really* rough. Basically we simply determine the // maximum shadow casting length and extrude the box by that distance - Vector vecShadowDir = GetShadowDirection(pRenderable); +#ifdef DYNAMIC_RTT_SHADOWS + Vector vecShadowDir = GetShadowDirection( shadowHandle ); +#else + Vector vecShadowDir = GetShadowDirection( pRenderable ); +#endif for (int i = 0; i < 3; ++i) { - float flShadowCastDistance = GetShadowDistance(pRenderable); + float flShadowCastDistance = GetShadowDistance( pRenderable ); float flDist = flShadowCastDistance * vecShadowDir[i]; if (vecShadowDir[i] < 0) @@ -3324,116 +3719,120 @@ void CClientShadowMgr::ComputeShadowBBox(IClientRenderable* pRenderable, const V //----------------------------------------------------------------------------- // Compute a separating axis... //----------------------------------------------------------------------------- -bool CClientShadowMgr::ComputeSeparatingPlane(IClientRenderable* pRend1, IClientRenderable* pRend2, cplane_t* pPlane) +bool CClientShadowMgr::ComputeSeparatingPlane( IClientRenderable* pRend1, IClientRenderable* pRend2, cplane_t* pPlane ) { Vector min1, max1, min2, max2; - pRend1->GetShadowRenderBounds(min1, max1, GetActualShadowCastType(pRend1)); - pRend2->GetShadowRenderBounds(min2, max2, GetActualShadowCastType(pRend2)); - return ::ComputeSeparatingPlane( + pRend1->GetShadowRenderBounds( min1, max1, GetActualShadowCastType( pRend1 ) ); + pRend2->GetShadowRenderBounds( min2, max2, GetActualShadowCastType( pRend2 ) ); + return ::ComputeSeparatingPlane( pRend1->GetRenderOrigin(), pRend1->GetRenderAngles(), min1, max1, pRend2->GetRenderOrigin(), pRend2->GetRenderAngles(), min2, max2, - 3.0f, pPlane); + 3.0f, pPlane ); } //----------------------------------------------------------------------------- // Cull shadows based on rough bounding volumes //----------------------------------------------------------------------------- -bool CClientShadowMgr::CullReceiver(ClientShadowHandle_t handle, IClientRenderable* pRenderable, - IClientRenderable* pSourceRenderable) +bool CClientShadowMgr::CullReceiver( ClientShadowHandle_t handle, IClientRenderable* pRenderable, + IClientRenderable* pSourceRenderable ) { // check flags here instead and assert !pSourceRenderable - if (m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT) + if( m_Shadows[handle].m_Flags & SHADOW_FLAGS_FLASHLIGHT ) { - VPROF_BUDGET("CClientShadowMgr::CullReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::CullReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - Assert(!pSourceRenderable); - const Frustum_t& frustum = shadowmgr->GetFlashlightFrustum(m_Shadows[handle].m_ShadowHandle); + Assert( !pSourceRenderable ); + const Frustum_t &frustum = shadowmgr->GetFlashlightFrustum( m_Shadows[handle].m_ShadowHandle ); Vector mins, maxs; - pRenderable->GetRenderBoundsWorldspace(mins, maxs); + pRenderable->GetRenderBoundsWorldspace( mins, maxs ); - return R_CullBox(mins, maxs, frustum); + return R_CullBox( mins, maxs, frustum ); } - Assert(pSourceRenderable); + Assert( pSourceRenderable ); // Compute a bounding sphere for the renderable Vector origin; float radius; - ComputeBoundingSphere(pRenderable, origin, radius); + ComputeBoundingSphere( pRenderable, origin, radius ); // Transform the sphere center into the space of the shadow Vector localOrigin; const ClientShadow_t& shadow = m_Shadows[handle]; - const ShadowInfo_t& info = shadowmgr->GetInfo(shadow.m_ShadowHandle); - Vector3DMultiplyPosition(shadow.m_WorldToShadow, origin, localOrigin); + const ShadowInfo_t& info = shadowmgr->GetInfo( shadow.m_ShadowHandle ); + Vector3DMultiplyPosition( shadow.m_WorldToShadow, origin, localOrigin ); // Compute a rough bounding box for the shadow (in shadow space) Vector shadowMin, shadowMax; - shadowMin.Init(-shadow.m_WorldSize.x * 0.5f, -shadow.m_WorldSize.y * 0.5f, 0); - shadowMax.Init(shadow.m_WorldSize.x * 0.5f, shadow.m_WorldSize.y * 0.5f, info.m_MaxDist); + shadowMin.Init( -shadow.m_WorldSize.x * 0.5f, -shadow.m_WorldSize.y * 0.5f, 0 ); + shadowMax.Init( shadow.m_WorldSize.x * 0.5f, shadow.m_WorldSize.y * 0.5f, info.m_MaxDist ); // If the bounding sphere doesn't intersect with the shadow volume, cull - if (!IsBoxIntersectingSphere(shadowMin, shadowMax, localOrigin, radius)) + if (!IsBoxIntersectingSphere( shadowMin, shadowMax, localOrigin, radius )) return true; Vector originSource; float radiusSource; - ComputeBoundingSphere(pSourceRenderable, originSource, radiusSource); + ComputeBoundingSphere( pSourceRenderable, originSource, radiusSource ); // Fast check for separating plane... bool foundSeparatingPlane = false; cplane_t plane; - if (!IsSphereIntersectingSphere(originSource, radiusSource, origin, radius)) + if (!IsSphereIntersectingSphere( originSource, radiusSource, origin, radius )) { foundSeparatingPlane = true; // the plane normal doesn't need to be normalized... - VectorSubtract(origin, originSource, plane.normal); + VectorSubtract( origin, originSource, plane.normal ); } else { - foundSeparatingPlane = ComputeSeparatingPlane(pRenderable, pSourceRenderable, &plane); + foundSeparatingPlane = ComputeSeparatingPlane( pRenderable, pSourceRenderable, &plane ); } if (foundSeparatingPlane) { // Compute which side of the plane the renderable is on.. - Vector vecShadowDir = GetShadowDirection(pSourceRenderable); - float shadowDot = DotProduct(vecShadowDir, plane.normal); - float receiverDot = DotProduct(plane.normal, origin); - float sourceDot = DotProduct(plane.normal, originSource); +#ifdef DYNAMIC_RTT_SHADOWS + Vector vecShadowDir = GetShadowDirection( handle ); +#else + Vector vecShadowDir = GetShadowDirection( pSourceRenderable ); +#endif + float shadowDot = DotProduct( vecShadowDir, plane.normal ); + float receiverDot = DotProduct( plane.normal, origin ); + float sourceDot = DotProduct( plane.normal, originSource ); if (shadowDot > 0.0f) { if (receiverDot <= sourceDot) { - // Vector dest; - // VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); - // debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 255, 0, true, 1.0f ); +// Vector dest; +// VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); +// debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 255, 0, true, 1.0f ); return true; } else { - // Vector dest; - // VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); - // debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 0, 0, true, 1.0f ); +// Vector dest; +// VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); +// debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 0, 0, true, 1.0f ); } } else { if (receiverDot >= sourceDot) { - // Vector dest; - // VectorMA( pSourceRenderable->GetRenderOrigin(), -50, plane.normal, dest ); - // debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 255, 0, true, 1.0f ); +// Vector dest; +// VectorMA( pSourceRenderable->GetRenderOrigin(), -50, plane.normal, dest ); +// debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 255, 0, true, 1.0f ); return true; } else { - // Vector dest; - // VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); - // debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 0, 0, true, 1.0f ); +// Vector dest; +// VectorMA( pSourceRenderable->GetRenderOrigin(), 50, plane.normal, dest ); +// debugoverlay->AddLineOverlay( pSourceRenderable->GetRenderOrigin(), dest, 255, 0, 0, true, 1.0f ); } } } @@ -3481,91 +3880,91 @@ bool CClientShadowMgr::CullReceiver(ClientShadowHandle_t handle, IClientRenderab //----------------------------------------------------------------------------- // deals with shadows being added to shadow receivers //----------------------------------------------------------------------------- -void CClientShadowMgr::AddShadowToReceiver(ClientShadowHandle_t handle, - IClientRenderable* pRenderable, ShadowReceiver_t type) +void CClientShadowMgr::AddShadowToReceiver( ClientShadowHandle_t handle, + IClientRenderable* pRenderable, ShadowReceiver_t type ) { - ClientShadow_t& shadow = m_Shadows[handle]; + ClientShadow_t &shadow = m_Shadows[handle]; // Don't add a shadow cast by an object to itself... - IClientRenderable* pSourceRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); + IClientRenderable* pSourceRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); // NOTE: if pSourceRenderable == NULL, the source is probably a flashlight since there is no entity. if (pSourceRenderable == pRenderable) return; // Don't bother if this renderable doesn't receive shadows or light from flashlights - if (!pRenderable->ShouldReceiveProjectedTextures(SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK)) + if( !pRenderable->ShouldReceiveProjectedTextures( SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK ) ) return; // Cull if the origin is on the wrong side of a shadow clip plane.... - if (CullReceiver(handle, pRenderable, pSourceRenderable)) + if ( CullReceiver( handle, pRenderable, pSourceRenderable ) ) return; // Do different things depending on the receiver type - switch (type) + switch( type ) { case SHADOW_RECEIVER_BRUSH_MODEL: - if (shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) + if( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) { - VPROF_BUDGET("CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - if ((!shadow.m_hTargetEntity) || IsFlashlightTarget(handle, pRenderable)) + if( (!shadow.m_hTargetEntity) || IsFlashlightTarget( handle, pRenderable ) ) { - shadowmgr->AddShadowToBrushModel(shadow.m_ShadowHandle, + shadowmgr->AddShadowToBrushModel( shadow.m_ShadowHandle, const_cast(pRenderable->GetModel()), - pRenderable->GetRenderOrigin(), pRenderable->GetRenderAngles()); + pRenderable->GetRenderOrigin(), pRenderable->GetRenderAngles() ); - shadowmgr->AddFlashlightRenderable(shadow.m_ShadowHandle, pRenderable); + shadowmgr->AddFlashlightRenderable( shadow.m_ShadowHandle, pRenderable ); } } else { - shadowmgr->AddShadowToBrushModel(shadow.m_ShadowHandle, + shadowmgr->AddShadowToBrushModel( shadow.m_ShadowHandle, const_cast(pRenderable->GetModel()), - pRenderable->GetRenderOrigin(), pRenderable->GetRenderAngles()); + pRenderable->GetRenderOrigin(), pRenderable->GetRenderAngles() ); } break; case SHADOW_RECEIVER_STATIC_PROP: // Don't add shadows to props if we're not using render-to-texture - if (GetActualShadowCastType(handle) == SHADOWS_RENDER_TO_TEXTURE) + if ( GetActualShadowCastType( handle ) == SHADOWS_RENDER_TO_TEXTURE ) { // Also don't add them unless an NPC or player casts them.. // They are wickedly expensive!!! - C_BaseEntity* pEnt = pSourceRenderable->GetIClientUnknown()->GetBaseEntity(); - if (pEnt && (pEnt->GetFlags() & (FL_NPC | FL_CLIENT))) + C_BaseEntity *pEnt = pSourceRenderable->GetIClientUnknown()->GetBaseEntity(); + if ( pEnt && ( pEnt->GetFlags() & (FL_NPC | FL_CLIENT)) ) { - staticpropmgr->AddShadowToStaticProp(shadow.m_ShadowHandle, pRenderable); + staticpropmgr->AddShadowToStaticProp( shadow.m_ShadowHandle, pRenderable ); } } - else if (shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) + else if( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) { - VPROF_BUDGET("CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - if ((!shadow.m_hTargetEntity) || IsFlashlightTarget(handle, pRenderable)) + if( (!shadow.m_hTargetEntity) || IsFlashlightTarget( handle, pRenderable ) ) { - staticpropmgr->AddShadowToStaticProp(shadow.m_ShadowHandle, pRenderable); + staticpropmgr->AddShadowToStaticProp( shadow.m_ShadowHandle, pRenderable ); - shadowmgr->AddFlashlightRenderable(shadow.m_ShadowHandle, pRenderable); + shadowmgr->AddFlashlightRenderable( shadow.m_ShadowHandle, pRenderable ); } } break; case SHADOW_RECEIVER_STUDIO_MODEL: - if (shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) + if( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) { - VPROF_BUDGET("CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); + VPROF_BUDGET( "CClientShadowMgr::AddShadowToReceiver", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); - if ((!shadow.m_hTargetEntity) || IsFlashlightTarget(handle, pRenderable)) + if( (!shadow.m_hTargetEntity) || IsFlashlightTarget( handle, pRenderable ) ) { pRenderable->CreateModelInstance(); - shadowmgr->AddShadowToModel(shadow.m_ShadowHandle, pRenderable->GetModelInstance()); - shadowmgr->AddFlashlightRenderable(shadow.m_ShadowHandle, pRenderable); + shadowmgr->AddShadowToModel( shadow.m_ShadowHandle, pRenderable->GetModelInstance() ); + shadowmgr->AddFlashlightRenderable( shadow.m_ShadowHandle, pRenderable ); } } break; - // default: +// default: } } @@ -3573,38 +3972,38 @@ void CClientShadowMgr::AddShadowToReceiver(ClientShadowHandle_t handle, //----------------------------------------------------------------------------- // deals with shadows being added to shadow receivers //----------------------------------------------------------------------------- -void CClientShadowMgr::RemoveAllShadowsFromReceiver( - IClientRenderable* pRenderable, ShadowReceiver_t type) +void CClientShadowMgr::RemoveAllShadowsFromReceiver( + IClientRenderable* pRenderable, ShadowReceiver_t type ) { // Don't bother if this renderable doesn't receive shadows - if (!pRenderable->ShouldReceiveProjectedTextures(SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK)) + if ( !pRenderable->ShouldReceiveProjectedTextures( SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK ) ) return; // Do different things depending on the receiver type - switch (type) + switch( type ) { case SHADOW_RECEIVER_BRUSH_MODEL: - { - model_t* pModel = const_cast(pRenderable->GetModel()); - shadowmgr->RemoveAllShadowsFromBrushModel(pModel); - } - break; + { + model_t* pModel = const_cast(pRenderable->GetModel()); + shadowmgr->RemoveAllShadowsFromBrushModel( pModel ); + } + break; case SHADOW_RECEIVER_STATIC_PROP: staticpropmgr->RemoveAllShadowsFromStaticProp(pRenderable); break; case SHADOW_RECEIVER_STUDIO_MODEL: - if (pRenderable && pRenderable->GetModelInstance() != MODEL_INSTANCE_INVALID) + if( pRenderable && pRenderable->GetModelInstance() != MODEL_INSTANCE_INVALID ) { - shadowmgr->RemoveAllShadowsFromModel(pRenderable->GetModelInstance()); + shadowmgr->RemoveAllShadowsFromModel( pRenderable->GetModelInstance() ); } break; - // default: - // // FIXME: How do deal with this stuff? Add a method to IClientRenderable? - // C_BaseEntity* pEnt = static_cast(pRenderable); - // pEnt->RemoveAllShadows(); +// default: +// // FIXME: How do deal with this stuff? Add a method to IClientRenderable? +// C_BaseEntity* pEnt = static_cast(pRenderable); +// pEnt->RemoveAllShadows(); } } @@ -3612,62 +4011,62 @@ void CClientShadowMgr::RemoveAllShadowsFromReceiver( //----------------------------------------------------------------------------- // Computes + sets the render-to-texture texcoords //----------------------------------------------------------------------------- -void CClientShadowMgr::SetRenderToTextureShadowTexCoords(ShadowHandle_t handle, int x, int y, int w, int h) +void CClientShadowMgr::SetRenderToTextureShadowTexCoords( ShadowHandle_t handle, int x, int y, int w, int h ) { // Let the shadow mgr know about the texture coordinates... // That way it'll be able to batch rendering better. int textureW, textureH; - m_ShadowAllocator.GetTotalTextureSize(textureW, textureH); + m_ShadowAllocator.GetTotalTextureSize( textureW, textureH ); // Go in a half-pixel to avoid blending with neighboring textures.. float u, v, du, dv; - u = ((float)x + 0.5f) / (float)textureW; - v = ((float)y + 0.5f) / (float)textureH; + u = ((float)x + 0.5f) / (float)textureW; + v = ((float)y + 0.5f) / (float)textureH; du = ((float)w - 1) / (float)textureW; dv = ((float)h - 1) / (float)textureH; - shadowmgr->SetShadowTexCoord(handle, u, v, du, dv); + shadowmgr->SetShadowTexCoord( handle, u, v, du, dv ); } //----------------------------------------------------------------------------- // Setup all children shadows //----------------------------------------------------------------------------- -bool CClientShadowMgr::BuildSetupShadowHierarchy(IClientRenderable* pRenderable, const ClientShadow_t& shadow, bool bChild) +bool CClientShadowMgr::BuildSetupShadowHierarchy( IClientRenderable *pRenderable, const ClientShadow_t &shadow, bool bChild ) { bool bDrewTexture = false; // Stop traversing when we hit a blobby shadow - ShadowType_t shadowType = GetActualShadowCastType(pRenderable); - if (pRenderable && shadowType == SHADOWS_SIMPLE) + ShadowType_t shadowType = GetActualShadowCastType( pRenderable ); + if ( pRenderable && shadowType == SHADOWS_SIMPLE ) return false; - if (!pRenderable || shadowType != SHADOWS_NONE) + if ( !pRenderable || shadowType != SHADOWS_NONE ) { bool bDrawModelShadow; - if (!bChild) + if ( !bChild ) { bDrawModelShadow = ((shadow.m_Flags & SHADOW_FLAGS_BRUSH_MODEL) == 0); } else { - int nModelType = modelinfo->GetModelType(pRenderable->GetModel()); + int nModelType = modelinfo->GetModelType( pRenderable->GetModel() ); bDrawModelShadow = nModelType == mod_studio; } - if (bDrawModelShadow) + if ( bDrawModelShadow ) { - C_BaseEntity* pEntity = pRenderable->GetIClientUnknown()->GetBaseEntity(); - if (pEntity) + C_BaseEntity *pEntity = pRenderable->GetIClientUnknown()->GetBaseEntity(); + if ( pEntity ) { - if (pEntity->IsNPC()) + if ( pEntity->IsNPC() ) { - s_NPCShadowBoneSetups.AddToTail(assert_cast(pEntity)); + s_NPCShadowBoneSetups.AddToTail( assert_cast( pEntity ) ); } - else if (pEntity->GetBaseAnimating()) + else if ( pEntity->GetBaseAnimating() ) { - s_NonNPCShadowBoneSetups.AddToTail(assert_cast(pEntity)); + s_NonNPCShadowBoneSetups.AddToTail( assert_cast( pEntity ) ); } } @@ -3675,13 +4074,13 @@ bool CClientShadowMgr::BuildSetupShadowHierarchy(IClientRenderable* pRenderable, } } - if (!pRenderable) + if ( !pRenderable ) return bDrewTexture; - IClientRenderable* pChild; - for (pChild = pRenderable->FirstShadowChild(); pChild; pChild = pChild->NextShadowPeer()) + IClientRenderable *pChild; + for ( pChild = pRenderable->FirstShadowChild(); pChild; pChild = pChild->NextShadowPeer() ) { - if (BuildSetupShadowHierarchy(pChild, shadow, true)) + if ( BuildSetupShadowHierarchy( pChild, shadow, true ) ) { bDrewTexture = true; } @@ -3692,55 +4091,55 @@ bool CClientShadowMgr::BuildSetupShadowHierarchy(IClientRenderable* pRenderable, //----------------------------------------------------------------------------- // Draws all children shadows into our own //----------------------------------------------------------------------------- -bool CClientShadowMgr::DrawShadowHierarchy(IClientRenderable* pRenderable, const ClientShadow_t& shadow, bool bChild) +bool CClientShadowMgr::DrawShadowHierarchy( IClientRenderable *pRenderable, const ClientShadow_t &shadow, bool bChild ) { bool bDrewTexture = false; // Stop traversing when we hit a blobby shadow - ShadowType_t shadowType = GetActualShadowCastType(pRenderable); - if (pRenderable && shadowType == SHADOWS_SIMPLE) + ShadowType_t shadowType = GetActualShadowCastType( pRenderable ); + if ( pRenderable && shadowType == SHADOWS_SIMPLE ) return false; - if (!pRenderable || shadowType != SHADOWS_NONE) + if ( !pRenderable || shadowType != SHADOWS_NONE ) { bool bDrawModelShadow; bool bDrawBrushShadow; - if (!bChild) + if ( !bChild ) { bDrawModelShadow = ((shadow.m_Flags & SHADOW_FLAGS_BRUSH_MODEL) == 0); bDrawBrushShadow = !bDrawModelShadow; } else { - int nModelType = modelinfo->GetModelType(pRenderable->GetModel()); + int nModelType = modelinfo->GetModelType( pRenderable->GetModel() ); bDrawModelShadow = nModelType == mod_studio; bDrawBrushShadow = nModelType == mod_brush; } - - if (bDrawModelShadow) + + if ( bDrawModelShadow ) { DrawModelInfo_t info; - matrix3x4_t* pBoneToWorld = modelrender->DrawModelShadowSetup(pRenderable, pRenderable->GetBody(), pRenderable->GetSkin(), &info); - if (pBoneToWorld) + matrix3x4_t *pBoneToWorld = modelrender->DrawModelShadowSetup( pRenderable, pRenderable->GetBody(), pRenderable->GetSkin(), &info ); + if ( pBoneToWorld ) { - modelrender->DrawModelShadow(pRenderable, info, pBoneToWorld); + modelrender->DrawModelShadow( pRenderable, info, pBoneToWorld ); } bDrewTexture = true; } - else if (bDrawBrushShadow) + else if ( bDrawBrushShadow ) { - render->DrawBrushModelShadow(pRenderable); + render->DrawBrushModelShadow( pRenderable ); bDrewTexture = true; } } - if (!pRenderable) + if ( !pRenderable ) return bDrewTexture; - IClientRenderable* pChild; - for (pChild = pRenderable->FirstShadowChild(); pChild; pChild = pChild->NextShadowPeer()) + IClientRenderable *pChild; + for ( pChild = pRenderable->FirstShadowChild(); pChild; pChild = pChild->NextShadowPeer() ) { - if (DrawShadowHierarchy(pChild, shadow, true)) + if ( DrawShadowHierarchy( pChild, shadow, true ) ) { bDrewTexture = true; } @@ -3751,22 +4150,22 @@ bool CClientShadowMgr::DrawShadowHierarchy(IClientRenderable* pRenderable, const //----------------------------------------------------------------------------- // This gets called with every shadow that potentially will need to re-render //----------------------------------------------------------------------------- -bool CClientShadowMgr::BuildSetupListForRenderToTextureShadow(unsigned short clientShadowHandle, float flArea) +bool CClientShadowMgr::BuildSetupListForRenderToTextureShadow( unsigned short clientShadowHandle, float flArea ) { ClientShadow_t& shadow = m_Shadows[clientShadowHandle]; bool bDirtyTexture = (shadow.m_Flags & SHADOW_FLAGS_TEXTURE_DIRTY) != 0; - bool bNeedsRedraw = m_ShadowAllocator.UseTexture(shadow.m_ShadowTexture, bDirtyTexture, flArea); - if (bNeedsRedraw || bDirtyTexture) + bool bNeedsRedraw = m_ShadowAllocator.UseTexture( shadow.m_ShadowTexture, bDirtyTexture, flArea ); + if ( bNeedsRedraw || bDirtyTexture ) { shadow.m_Flags |= SHADOW_FLAGS_TEXTURE_DIRTY; - if (!m_ShadowAllocator.HasValidTexture(shadow.m_ShadowTexture)) + if ( !m_ShadowAllocator.HasValidTexture( shadow.m_ShadowTexture ) ) return false; // shadow to be redrawn; for now, we'll always do it. - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); - if (BuildSetupShadowHierarchy(pRenderable, shadow)) + if ( BuildSetupShadowHierarchy( pRenderable, shadow ) ) return true; } return false; @@ -3775,80 +4174,80 @@ bool CClientShadowMgr::BuildSetupListForRenderToTextureShadow(unsigned short cli //----------------------------------------------------------------------------- // This gets called with every shadow that potentially will need to re-render //----------------------------------------------------------------------------- -bool CClientShadowMgr::DrawRenderToTextureShadow(unsigned short clientShadowHandle, float flArea) +bool CClientShadowMgr::DrawRenderToTextureShadow( unsigned short clientShadowHandle, float flArea ) { ClientShadow_t& shadow = m_Shadows[clientShadowHandle]; // If we were previously using the LOD shadow, set the material - bool bPreviouslyUsingLODShadow = (shadow.m_Flags & SHADOW_FLAGS_USING_LOD_SHADOW) != 0; + bool bPreviouslyUsingLODShadow = ( shadow.m_Flags & SHADOW_FLAGS_USING_LOD_SHADOW ) != 0; shadow.m_Flags &= ~SHADOW_FLAGS_USING_LOD_SHADOW; - if (bPreviouslyUsingLODShadow) + if ( bPreviouslyUsingLODShadow ) { - shadowmgr->SetShadowMaterial(shadow.m_ShadowHandle, m_RenderShadow, m_RenderModelShadow, (void*)(uintp)clientShadowHandle); + shadowmgr->SetShadowMaterial( shadow.m_ShadowHandle, m_RenderShadow, m_RenderModelShadow, (void*)(uintp)clientShadowHandle ); } // Mark texture as being used... bool bDirtyTexture = (shadow.m_Flags & SHADOW_FLAGS_TEXTURE_DIRTY) != 0; bool bDrewTexture = false; - bool bNeedsRedraw = (!m_bThreaded && m_ShadowAllocator.UseTexture(shadow.m_ShadowTexture, bDirtyTexture, flArea)); + bool bNeedsRedraw = ( !m_bThreaded && m_ShadowAllocator.UseTexture( shadow.m_ShadowTexture, bDirtyTexture, flArea ) ); - if (!m_ShadowAllocator.HasValidTexture(shadow.m_ShadowTexture)) + if ( !m_ShadowAllocator.HasValidTexture( shadow.m_ShadowTexture ) ) { - DrawRenderToTextureShadowLOD(clientShadowHandle); + DrawRenderToTextureShadowLOD( clientShadowHandle ); return false; } - if (bNeedsRedraw || bDirtyTexture) + if ( bNeedsRedraw || bDirtyTexture ) { // shadow to be redrawn; for now, we'll always do it. - IClientRenderable* pRenderable = ClientEntityList().GetClientRenderableFromHandle(shadow.m_Entity); - - CMatRenderContextPtr pRenderContext(materials); + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( shadow.m_Entity ); + CMatRenderContextPtr pRenderContext( materials ); + // Sets the viewport state int x, y, w, h; - m_ShadowAllocator.GetTextureRect(shadow.m_ShadowTexture, x, y, w, h); - pRenderContext->Viewport(IsX360() ? 0 : x, IsX360() ? 0 : y, w, h); + m_ShadowAllocator.GetTextureRect( shadow.m_ShadowTexture, x, y, w, h ); + pRenderContext->Viewport( IsX360() ? 0 : x, IsX360() ? 0 : y, w, h ); // Clear the selected viewport only (don't need to clear depth) - pRenderContext->ClearBuffers(true, false); - - pRenderContext->MatrixMode(MATERIAL_VIEW); - pRenderContext->LoadMatrix(shadowmgr->GetInfo(shadow.m_ShadowHandle).m_WorldToShadow); + pRenderContext->ClearBuffers( true, false ); - if (DrawShadowHierarchy(pRenderable, shadow)) + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->LoadMatrix( shadowmgr->GetInfo( shadow.m_ShadowHandle ).m_WorldToShadow ); + + if ( DrawShadowHierarchy( pRenderable, shadow ) ) { bDrewTexture = true; - if (IsX360()) + if ( IsX360() ) { // resolve render target to system memory texture Rect_t srcRect = { 0, 0, w, h }; Rect_t dstRect = { x, y, w, h }; - pRenderContext->CopyRenderTargetToTextureEx(m_ShadowAllocator.GetTexture(), 0, &srcRect, &dstRect); + pRenderContext->CopyRenderTargetToTextureEx( m_ShadowAllocator.GetTexture(), 0, &srcRect, &dstRect ); } } else { // NOTE: Think the flags reset + texcoord set should only happen in DrawShadowHierarchy // but it's 2 days before 360 ship.. not going to change this now. - DevMsg("Didn't draw shadow hierarchy.. bad shadow texcoords probably going to happen..grab Brian!\n"); + DevMsg( "Didn't draw shadow hierarchy.. bad shadow texcoords probably going to happen..grab Brian!\n" ); } // Only clear the dirty flag if the caster isn't animating - if ((shadow.m_Flags & SHADOW_FLAGS_ANIMATING_SOURCE) == 0) + if ( (shadow.m_Flags & SHADOW_FLAGS_ANIMATING_SOURCE) == 0 ) { shadow.m_Flags &= ~SHADOW_FLAGS_TEXTURE_DIRTY; } - SetRenderToTextureShadowTexCoords(shadow.m_ShadowHandle, x, y, w, h); + SetRenderToTextureShadowTexCoords( shadow.m_ShadowHandle, x, y, w, h ); } - else if (bPreviouslyUsingLODShadow) + else if ( bPreviouslyUsingLODShadow ) { // In this case, we were previously using the LOD shadow, but we didn't // have to reconstitute the texture. In this case, we need to reset the texcoord int x, y, w, h; - m_ShadowAllocator.GetTextureRect(shadow.m_ShadowTexture, x, y, w, h); - SetRenderToTextureShadowTexCoords(shadow.m_ShadowHandle, x, y, w, h); + m_ShadowAllocator.GetTextureRect( shadow.m_ShadowTexture, x, y, w, h ); + SetRenderToTextureShadowTexCoords( shadow.m_ShadowHandle, x, y, w, h ); } return bDrewTexture; @@ -3858,14 +4257,14 @@ bool CClientShadowMgr::DrawRenderToTextureShadow(unsigned short clientShadowHand //----------------------------------------------------------------------------- // "Draws" the shadow LOD, which really means just set up the blobby shadow //----------------------------------------------------------------------------- -void CClientShadowMgr::DrawRenderToTextureShadowLOD(unsigned short clientShadowHandle) +void CClientShadowMgr::DrawRenderToTextureShadowLOD( unsigned short clientShadowHandle ) { - ClientShadow_t& shadow = m_Shadows[clientShadowHandle]; - if ((shadow.m_Flags & SHADOW_FLAGS_USING_LOD_SHADOW) == 0) + ClientShadow_t &shadow = m_Shadows[clientShadowHandle]; + if ( (shadow.m_Flags & SHADOW_FLAGS_USING_LOD_SHADOW) == 0 ) { - shadowmgr->SetShadowMaterial(shadow.m_ShadowHandle, m_SimpleShadow, m_SimpleShadow, (void*)CLIENTSHADOW_INVALID_HANDLE); - shadowmgr->SetShadowTexCoord(shadow.m_ShadowHandle, 0, 0, 1, 1); - ClearExtraClipPlanes(clientShadowHandle); // this was ClearExtraClipPlanes( shadow.m_ShadowHandle ), fix is from Joe Demers + shadowmgr->SetShadowMaterial( shadow.m_ShadowHandle, m_SimpleShadow, m_SimpleShadow, (void*)CLIENTSHADOW_INVALID_HANDLE ); + shadowmgr->SetShadowTexCoord( shadow.m_ShadowHandle, 0, 0, 1, 1 ); + ClearExtraClipPlanes( clientShadowHandle ); // this was ClearExtraClipPlanes( shadow.m_ShadowHandle ), fix is from Joe Demers shadow.m_Flags |= SHADOW_FLAGS_USING_LOD_SHADOW; } } @@ -3880,38 +4279,30 @@ void CClientShadowMgr::AdvanceFrame() m_ShadowAllocator.AdvanceFrame(); } -int _cdecl CompareLights(const ClientShadowHandle_t *light_left, const ClientShadowHandle_t *light_right) -{ - const FlashlightState_t& flashlightState1 = shadowmgr->GetFlashlightState(g_pClientShadowMgr->GetShadowHandle(*light_left)); - const FlashlightState_t& flashlightState2 = shadowmgr->GetFlashlightState(g_pClientShadowMgr->GetShadowHandle(*light_right)); - - float distance1 = (flashlightState1.m_vecLightOrigin - MainViewOrigin()).Length(); - float distance2 = (flashlightState2.m_vecLightOrigin - MainViewOrigin()).Length(); - return int(distance1 - distance2); -} //----------------------------------------------------------------------------- // Re-render shadow depth textures that lie in the leaf list //----------------------------------------------------------------------------- -int CClientShadowMgr::BuildActiveShadowDepthList(const CViewSetup& viewSetup, int nMaxDepthShadows, ClientShadowHandle_t* pActiveDepthShadows) +int CClientShadowMgr::BuildActiveShadowDepthList( const CViewSetup &viewSetup, int nMaxDepthShadows, ClientShadowHandle_t *pActiveDepthShadows ) { +#ifdef ASW_PROJECTED_TEXTURES Frustum_t viewFrustum; - GeneratePerspectiveFrustum(viewSetup.origin, viewSetup.angles, viewSetup.zNear, viewSetup.zFar, viewSetup.fov, viewSetup.m_flAspectRatio, viewFrustum); + GeneratePerspectiveFrustum( viewSetup.origin, viewSetup.angles, viewSetup.zNear, viewSetup.zFar, viewSetup.fov, viewSetup.m_flAspectRatio, viewFrustum ); +#endif int nActiveDepthShadowCount = 0; - CUtlVector vActiveShadows; - for (ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i)) + for ( ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) { ClientShadow_t& shadow = m_Shadows[i]; // If this is not a flashlight which should use a shadow depth texture, skip! - if ((shadow.m_Flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE) == 0) + if ( ( shadow.m_Flags & SHADOW_FLAGS_USE_DEPTH_TEXTURE ) == 0 ) continue; - const FlashlightState_t& flashlightState = shadowmgr->GetFlashlightState(shadow.m_ShadowHandle); + const FlashlightState_t& flashlightState = shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ); // Bail if this flashlight doesn't want shadows - if (!flashlightState.m_bEnableShadows) + if ( !flashlightState.m_bEnableShadows ) continue; // Calculate an AABB around the shadow frustum @@ -3923,246 +4314,341 @@ int CClientShadowMgr::BuildActiveShadowDepthList(const CViewSetup& viewSetup, in // FIXME: Could do other sorts of culling here, such as frustum-frustum test, distance etc. // If it's not in the view frustum, move on +#ifdef MAPBASE + if ( !flashlightState.m_bAlwaysDraw && !flashlightState.m_bOrtho && R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) +#elif ASW_PROJECTED_TEXTURES + if ( !flashlightState.m_bOrtho && R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) +#else if ( R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) +#endif { + shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, NULL, 0 ); continue; } - - vActiveShadows.AddToHead(i); + if ( nActiveDepthShadowCount >= nMaxDepthShadows ) + { + static bool s_bOverflowWarning = false; + if ( !s_bOverflowWarning ) + { + Warning( "Too many depth textures rendered in a single view!\n" ); + Assert( 0 ); + s_bOverflowWarning = true; + } + shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, NULL, 0 ); + continue; + } + + pActiveDepthShadows[nActiveDepthShadowCount++] = i; } + return nActiveDepthShadowCount; +} - vActiveShadows.Sort(CompareLights); - FOR_EACH_VEC(vActiveShadows, i) +#ifdef ASW_PROJECTED_TEXTURES +//----------------------------------------------------------------------------- +// Re-render shadow depth textures that lie in the leaf list +//----------------------------------------------------------------------------- +int CClientShadowMgr::BuildActiveFlashlightList( const CViewSetup &viewSetup, int nMaxFlashlights, ClientShadowHandle_t *pActiveFlashlights ) +{ + int nActiveFlashlightCount = 0; + for ( ClientShadowHandle_t i = m_Shadows.Head(); i != m_Shadows.InvalidIndex(); i = m_Shadows.Next(i) ) { - ClientShadow_t& shadow = m_Shadows[vActiveShadows[i]]; - if (nActiveDepthShadowCount >= nMaxDepthShadows) + ClientShadow_t& shadow = m_Shadows[i]; + + if ( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ) + continue; + + // Calculate an AABB around the shadow frustum + Vector vecAbsMins, vecAbsMaxs; + CalculateAABBFromProjectionMatrix( shadow.m_WorldToShadow, &vecAbsMins, &vecAbsMaxs ); + + Frustum_t viewFrustum; + GeneratePerspectiveFrustum( viewSetup.origin, viewSetup.angles, viewSetup.zNear, viewSetup.zFar, viewSetup.fov, viewSetup.m_flAspectRatio, viewFrustum ); + + // FIXME: Could do other sorts of culling here, such as frustum-frustum test, distance etc. + // If it's not in the view frustum, move on + if ( R_CullBox( vecAbsMins, vecAbsMaxs, viewFrustum ) ) { - shadowmgr->SetFlashlightDepthTexture(shadow.m_ShadowHandle, NULL, 0); continue; } - pActiveDepthShadows[nActiveDepthShadowCount++] = vActiveShadows[i]; - } + if ( nActiveFlashlightCount >= nMaxFlashlights ) + { + static bool s_bOverflowWarning = false; + if ( !s_bOverflowWarning ) + { + Warning( "Too many flashlights rendered in a single view!\n" ); + Assert( 0 ); + s_bOverflowWarning = true; + } + //shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, NULL, 0 ); + continue; + } - return nActiveDepthShadowCount; + pActiveFlashlights[nActiveFlashlightCount++] = i; + } + return nActiveFlashlightCount; } - +#endif //----------------------------------------------------------------------------- // Sets the view's active flashlight render state //----------------------------------------------------------------------------- -void CClientShadowMgr::SetViewFlashlightState(int nActiveFlashlightCount, ClientShadowHandle_t* pActiveFlashlights) +void CClientShadowMgr::SetViewFlashlightState( int nActiveFlashlightCount, ClientShadowHandle_t* pActiveFlashlights ) { // NOTE: On the 360, we render the entire scene with the flashlight state // set and don't render flashlights additively in the shadow mgr at a far later time // because the CPU costs are prohibitive - if (!IsX360() && !r_flashlight_version2.GetInt()) + if ( !IsX360() && !r_flashlight_version2.GetInt() ) return; - Assert(nActiveFlashlightCount <= 1); - if (nActiveFlashlightCount > 0) + Assert( nActiveFlashlightCount<= 1 ); + if ( nActiveFlashlightCount > 0 ) { - Assert((m_Shadows[pActiveFlashlights[0]].m_Flags & SHADOW_FLAGS_FLASHLIGHT) != 0); - shadowmgr->SetFlashlightRenderState(pActiveFlashlights[0]); + Assert( ( m_Shadows[ pActiveFlashlights[0] ].m_Flags & SHADOW_FLAGS_FLASHLIGHT ) != 0 ); + shadowmgr->SetFlashlightRenderState( pActiveFlashlights[0] ); } else { - shadowmgr->SetFlashlightRenderState(SHADOW_HANDLE_INVALID); + shadowmgr->SetFlashlightRenderState( SHADOW_HANDLE_INVALID ); } } - -void AddPointToExtentsHelper(const VMatrix& flashlightToWorld, const Vector& vecPos, Vector& vecMin, Vector& vecMax) +#ifdef ASW_PROJECTED_TEXTURES +void AddPointToExtentsHelper( const VMatrix &flashlightToWorld, const Vector &vecPos, Vector &vecMin, Vector &vecMax ) { Vector worldSpacePos; - Vector3DMultiplyPositionProjective(flashlightToWorld, vecPos, worldSpacePos); - VectorMin(vecMin, worldSpacePos, vecMin); - VectorMax(vecMax, worldSpacePos, vecMax); + Vector3DMultiplyPositionProjective( flashlightToWorld, vecPos, worldSpacePos ); + VectorMin( vecMin, worldSpacePos, vecMin ); + VectorMax( vecMax, worldSpacePos, vecMax ); } -void CClientShadowMgr::GetFrustumExtents(ClientShadowHandle_t handle, Vector& vecMin, Vector& vecMax) +void CClientShadowMgr::GetFrustumExtents( ClientShadowHandle_t handle, Vector &vecMin, Vector &vecMax ) { - Assert(m_Shadows.IsValidIndex(handle)); + Assert( m_Shadows.IsValidIndex( handle ) ); - CClientShadowMgr::ClientShadow_t& shadow = m_Shadows[handle]; + CClientShadowMgr::ClientShadow_t &shadow = m_Shadows[ handle ]; VMatrix flashlightToWorld; - MatrixInverseGeneral(shadow.m_WorldToShadow, flashlightToWorld); + MatrixInverseGeneral( shadow.m_WorldToShadow, flashlightToWorld ); - vecMin = Vector(FLT_MAX, FLT_MAX, FLT_MAX); - vecMax = Vector(-FLT_MAX, -FLT_MAX, -FLT_MAX); + vecMin = Vector( FLT_MAX, FLT_MAX, FLT_MAX ); + vecMax = Vector( -FLT_MAX, -FLT_MAX, -FLT_MAX ); - AddPointToExtentsHelper(flashlightToWorld, Vector(0.0f, 0.0f, 0.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(0.0f, 0.0f, 1.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(0.0f, 1.0f, 0.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(1.0f, 0.0f, 0.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(0.0f, 1.0f, 1.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(1.0f, 0.0f, 1.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(1.0f, 1.0f, 0.0f), vecMin, vecMax); - AddPointToExtentsHelper(flashlightToWorld, Vector(1.0f, 1.0f, 1.0f), vecMin, vecMax); + AddPointToExtentsHelper( flashlightToWorld, Vector( 0.0f, 0.0f, 0.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 0.0f, 0.0f, 1.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 0.0f, 1.0f, 0.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 0.0f, 0.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 0.0f, 1.0f, 1.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 0.0f, 1.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 1.0f, 0.0f ), vecMin, vecMax ); + AddPointToExtentsHelper( flashlightToWorld, Vector( 1.0f, 1.0f, 1.0f ), vecMin, vecMax ); } +#endif //----------------------------------------------------------------------------- // Re-render shadow depth textures that lie in the leaf list //----------------------------------------------------------------------------- -void CClientShadowMgr::ComputeShadowDepthTextures(const CViewSetup& viewSetup) +void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) { - VPROF_BUDGET("CClientShadowMgr::ComputeShadowDepthTextures", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); +#ifdef ASW_PROJECTED_TEXTURES + if ( !r_flashlightdepthtexture.GetBool() ) + { + // Build list of active flashlights + ClientShadowHandle_t pActiveFlashlights[16]; + int nActiveFlashlights = BuildActiveFlashlightList( viewSetup, ARRAYSIZE( pActiveFlashlights ), pActiveFlashlights ); + SetViewFlashlightState( nActiveFlashlights, pActiveFlashlights ); + return; + } +#endif - CMatRenderContextPtr pRenderContext(materials); - PIXEVENT(pRenderContext, "Shadow Depth Textures"); + VPROF_BUDGET( "CClientShadowMgr::ComputeShadowDepthTextures", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); + + CMatRenderContextPtr pRenderContext( materials ); + PIXEVENT( pRenderContext, "Shadow Depth Textures" ); // Build list of active render-to-texture shadows ClientShadowHandle_t pActiveDepthShadows[1024]; - int nActiveDepthShadowCount = BuildActiveShadowDepthList(viewSetup, ARRAYSIZE(pActiveDepthShadows), pActiveDepthShadows); - - for (int i = 0; i < m_nMaxDepthTextureShadows; i++) - m_ActiveDepthTextureShadows[i] = SHADOW_HANDLE_INVALID; - - Assert(m_nMaxDepthTextureShadows < ARRAYSIZE(m_ActiveDepthTextureShadows)); + int nActiveDepthShadowCount = BuildActiveShadowDepthList( viewSetup, ARRAYSIZE( pActiveDepthShadows ), pActiveDepthShadows ); // Iterate over all existing textures and allocate shadow textures bool bDebugFrustum = r_flashlightdrawfrustum.GetBool(); - for (int j = 0; j < nActiveDepthShadowCount; ++j) + for ( int j = 0; j < nActiveDepthShadowCount; ++j ) { - ClientShadow_t& shadow = m_Shadows[pActiveDepthShadows[j]]; + ClientShadow_t& shadow = m_Shadows[ pActiveDepthShadows[j] ]; + +#ifdef ASW_PROJECTED_TEXTURES + FlashlightState_t& flashlightState = const_cast( shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ) ); +#endif CTextureReference shadowDepthTexture; - bool bGotShadowDepthTexture = LockShadowDepthTexture(&shadowDepthTexture); - if (!bGotShadowDepthTexture) + bool bGotShadowDepthTexture = LockShadowDepthTexture( &shadowDepthTexture ); + if ( !bGotShadowDepthTexture ) { // If we don't get one, that means we have too many this frame so bind no depth texture static int bitchCount = 0; - if (bitchCount < 10) + if( bitchCount < 10 ) { - Warning("Too many shadow maps this frame!\n"); + Warning( "Too many shadow maps this frame!\n" ); bitchCount++; } Assert(0); - shadowmgr->SetFlashlightDepthTexture(shadow.m_ShadowHandle, NULL, 0); - - if (j <= (INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST)) + shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, NULL, 0 ); +#ifdef MAPBASE + if ( j <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) { - pRenderContext->SetIntRenderingParameter(INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, 0); + pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, 0 ); } - +#endif continue; } - m_ActiveDepthTextureHandle = shadow.m_ShadowHandle; - m_ActiveDepthTextureShadows[j] = shadow.m_ShadowHandle; - CViewSetup shadowView; +#ifndef MAPBASE shadowView.m_flAspectRatio = 1.0f; +#endif shadowView.x = shadowView.y = 0; shadowView.width = shadowDepthTexture->GetActualWidth(); shadowView.height = shadowDepthTexture->GetActualHeight(); +#ifndef ASW_PROJECTED_TEXTURES shadowView.m_bOrtho = false; shadowView.m_bDoBloomAndToneMapping = false; +#ifdef MAPBASE + shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); +#endif // MAPBASE +#endif // Copy flashlight parameters - const FlashlightState_t& flashlightState = shadowmgr->GetFlashlightState(shadow.m_ShadowHandle); +#ifdef ASW_PROJECTED_TEXTURES + if ( !flashlightState.m_bOrtho ) + { + shadowView.m_bOrtho = false; + +#ifdef MAPBASE + shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); +#endif // MAPBASE + } + else + { + shadowView.m_bOrtho = true; + shadowView.m_OrthoLeft = flashlightState.m_fOrthoLeft; + shadowView.m_OrthoTop = flashlightState.m_fOrthoTop; + shadowView.m_OrthoRight = flashlightState.m_fOrthoRight; + shadowView.m_OrthoBottom = flashlightState.m_fOrthoBottom; + +#ifdef MAPBASE + shadowView.m_flAspectRatio = 1.0f; +#endif + } + + shadowView.m_bDoBloomAndToneMapping = false; +#else + const FlashlightState_t& flashlightState = shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ); +#endif shadowView.fov = shadowView.fovViewmodel = flashlightState.m_fHorizontalFOVDegrees; shadowView.origin = flashlightState.m_vecLightOrigin; - QuaternionAngles(flashlightState.m_quatOrientation, shadowView.angles); // Convert from Quaternion to QAngle + QuaternionAngles( flashlightState.m_quatOrientation, shadowView.angles ); // Convert from Quaternion to QAngle shadowView.zNear = shadowView.zNearViewmodel = flashlightState.m_NearZ; shadowView.zFar = shadowView.zFarViewmodel = flashlightState.m_FarZ; // Can turn on all light frustum overlays or per light with flashlightState parameter... - if (bDebugFrustum || flashlightState.m_bDrawShadowFrustum) + if ( bDebugFrustum || flashlightState.m_bDrawShadowFrustum ) { - DebugDrawFrustum(shadowView.origin, shadow.m_WorldToShadow); + DebugDrawFrustum( shadowView.origin, shadow.m_WorldToShadow ); } // Set depth bias factors specific to this flashlight - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->SetShadowDepthBiasFactors(flashlightState.m_flShadowSlopeScaleDepthBias, flashlightState.m_flShadowDepthBias); + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->SetShadowDepthBiasFactors( flashlightState.m_flShadowSlopeScaleDepthBias, flashlightState.m_flShadowDepthBias ); // Render to the shadow depth texture with appropriate view - view->UpdateShadowDepthTexture(m_DummyColorTexture, shadowDepthTexture, shadowView); + view->UpdateShadowDepthTexture( m_DummyColorTexture, shadowDepthTexture, shadowView ); - if (j <= (INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST)) +#ifdef MAPBASE + if ( j <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) { - pRenderContext->SetIntRenderingParameter(INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, int((ITexture*)shadowDepthTexture)); + pRenderContext->SetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + j, int((ITexture*)shadowDepthTexture) ); - FlashlightState_t state = shadowmgr->GetFlashlightState(shadow.m_ShadowHandle); + FlashlightState_t state = shadowmgr->GetFlashlightState( shadow.m_ShadowHandle ); - state.m_nShadowQuality = state.m_nShadowQuality | ((j + 1) << 16); + state.m_nShadowQuality = state.m_nShadowQuality | ( ( j + 1 ) << 16 ); - shadowmgr->UpdateFlashlightState(shadow.m_ShadowHandle, state); + shadowmgr->UpdateFlashlightState( shadow.m_ShadowHandle, state ); } - - m_ActiveDepthTextureHandle = SHADOW_HANDLE_INVALID; +#endif // Associate the shadow depth texture and stencil bit with the flashlight for use during scene rendering - shadowmgr->SetFlashlightDepthTexture(shadow.m_ShadowHandle, shadowDepthTexture, 0); + shadowmgr->SetFlashlightDepthTexture( shadow.m_ShadowHandle, shadowDepthTexture, 0 ); } - SetViewFlashlightState(nActiveDepthShadowCount, pActiveDepthShadows); + SetViewFlashlightState( nActiveDepthShadowCount, pActiveDepthShadows ); } - + //----------------------------------------------------------------------------- // Re-renders all shadow textures for shadow casters that lie in the leaf list //----------------------------------------------------------------------------- -static void SetupBonesOnBaseAnimating(C_BaseAnimating*& pBaseAnimating) +static void SetupBonesOnBaseAnimating( C_BaseAnimating *&pBaseAnimating ) { - pBaseAnimating->SetupBones(NULL, -1, -1, gpGlobals->curtime); + pBaseAnimating->SetupBones( NULL, -1, -1, gpGlobals->curtime ); } -void CClientShadowMgr::ComputeShadowTextures(const CViewSetup& view, int leafCount, LeafIndex_t* pLeafList) +void CClientShadowMgr::ComputeShadowTextures( const CViewSetup &view, int leafCount, LeafIndex_t* pLeafList ) { - VPROF_BUDGET("CClientShadowMgr::ComputeShadowTextures", VPROF_BUDGETGROUP_SHADOW_RENDERING); + VPROF_BUDGET( "CClientShadowMgr::ComputeShadowTextures", VPROF_BUDGETGROUP_SHADOW_RENDERING ); - if (!m_RenderToTextureActive || (r_shadows.GetInt() == 0) || r_shadows_gamecontrol.GetInt() == 0) + if ( !m_RenderToTextureActive || (r_shadows.GetInt() == 0) || r_shadows_gamecontrol.GetInt() == 0 ) return; +#ifdef ASW_PROJECTED_TEXTURES + m_bThreaded = ( r_threaded_client_shadow_manager.GetBool() && g_pThreadPool->NumIdleThreads() ); +#else m_bThreaded = false;//( r_threaded_client_shadow_manager.GetBool() && g_pThreadPool->NumIdleThreads() ); +#endif MDLCACHE_CRITICAL_SECTION(); // First grab all shadow textures we may want to render - int nCount = s_VisibleShadowList.FindShadows(&view, leafCount, pLeafList); - if (nCount == 0) + int nCount = s_VisibleShadowList.FindShadows( &view, leafCount, pLeafList ); + if ( nCount == 0 ) return; // FIXME: Add heuristics based on distance, etc. to futz with // the shadow allocator + to select blobby shadows - CMatRenderContextPtr pRenderContext(materials); + CMatRenderContextPtr pRenderContext( materials ); - PIXEVENT(pRenderContext, "Render-To-Texture Shadows"); + PIXEVENT( pRenderContext, "Render-To-Texture Shadows" ); // Clear to white (color unused), black alpha - pRenderContext->ClearColor4ub(255, 255, 255, 0); + pRenderContext->ClearColor4ub( 255, 255, 255, 0 ); // No height clip mode please. MaterialHeightClipMode_t oldHeightClipMode = pRenderContext->GetHeightClipMode(); - pRenderContext->SetHeightClipMode(MATERIAL_HEIGHTCLIPMODE_DISABLE); + pRenderContext->SetHeightClipMode( MATERIAL_HEIGHTCLIPMODE_DISABLE ); // No projection matrix (orthographic mode) // FIXME: Make it work for projective shadows? - pRenderContext->MatrixMode(MATERIAL_PROJECTION); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PushMatrix(); pRenderContext->LoadIdentity(); - pRenderContext->Scale(1, -1, 1); - pRenderContext->Ortho(0, 0, 1, 1, -9999, 0); + pRenderContext->Scale( 1, -1, 1 ); + pRenderContext->Ortho( 0, 0, 1, 1, -9999, 0 ); - pRenderContext->MatrixMode(MATERIAL_VIEW); + pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->PushMatrix(); - pRenderContext->PushRenderTargetAndViewport(m_ShadowAllocator.GetTexture()); + pRenderContext->PushRenderTargetAndViewport( m_ShadowAllocator.GetTexture() ); - if (!IsX360() && m_bRenderTargetNeedsClear) + if ( !IsX360() && m_bRenderTargetNeedsClear ) { // don't need to clear absent depth buffer - pRenderContext->ClearBuffers(true, false); + pRenderContext->ClearBuffers( true, false ); m_bRenderTargetNeedsClear = false; } @@ -4170,42 +4656,42 @@ void CClientShadowMgr::ComputeShadowTextures(const CViewSetup& view, int leafCou int nModelsRendered = 0; int i; - if (m_bThreaded && g_pThreadPool->NumIdleThreads()) + if ( m_bThreaded && g_pThreadPool->NumIdleThreads() ) { s_NPCShadowBoneSetups.RemoveAll(); s_NonNPCShadowBoneSetups.RemoveAll(); for (i = 0; i < nCount; ++i) { - const VisibleShadowInfo_t& info = s_VisibleShadowList.GetVisibleShadow(i); - if (nModelsRendered < nMaxShadows) + const VisibleShadowInfo_t &info = s_VisibleShadowList.GetVisibleShadow(i); + if ( nModelsRendered < nMaxShadows ) { - if (BuildSetupListForRenderToTextureShadow(info.m_hShadow, info.m_flArea)) + if ( BuildSetupListForRenderToTextureShadow( info.m_hShadow, info.m_flArea ) ) { ++nModelsRendered; } } } - ParallelProcess("NPCShadowBoneSetups", s_NPCShadowBoneSetups.Base(), s_NPCShadowBoneSetups.Count(), &SetupBonesOnBaseAnimating); - ParallelProcess("NonNPCShadowBoneSetups", s_NonNPCShadowBoneSetups.Base(), s_NonNPCShadowBoneSetups.Count(), &SetupBonesOnBaseAnimating); + ParallelProcess( "NPCShadowBoneSetups", s_NPCShadowBoneSetups.Base(), s_NPCShadowBoneSetups.Count(), &SetupBonesOnBaseAnimating ); + ParallelProcess( "NonNPCShadowBoneSetups", s_NonNPCShadowBoneSetups.Base(), s_NonNPCShadowBoneSetups.Count(), &SetupBonesOnBaseAnimating ); nModelsRendered = 0; } for (i = 0; i < nCount; ++i) { - const VisibleShadowInfo_t& info = s_VisibleShadowList.GetVisibleShadow(i); - if (nModelsRendered < nMaxShadows) + const VisibleShadowInfo_t &info = s_VisibleShadowList.GetVisibleShadow(i); + if ( nModelsRendered < nMaxShadows ) { - if (DrawRenderToTextureShadow(info.m_hShadow, info.m_flArea)) + if ( DrawRenderToTextureShadow( info.m_hShadow, info.m_flArea ) ) { ++nModelsRendered; } } else { - DrawRenderToTextureShadowLOD(info.m_hShadow); + DrawRenderToTextureShadowLOD( info.m_hShadow ); } } @@ -4213,28 +4699,28 @@ void CClientShadowMgr::ComputeShadowTextures(const CViewSetup& view, int leafCou pRenderContext->PopRenderTargetAndViewport(); // Restore the matrices - pRenderContext->MatrixMode(MATERIAL_PROJECTION); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PopMatrix(); - pRenderContext->MatrixMode(MATERIAL_VIEW); + pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->PopMatrix(); - pRenderContext->SetHeightClipMode(oldHeightClipMode); + pRenderContext->SetHeightClipMode( oldHeightClipMode ); - pRenderContext->SetHeightClipMode(oldHeightClipMode); + pRenderContext->SetHeightClipMode( oldHeightClipMode ); // Restore the clear color - pRenderContext->ClearColor3ub(0, 0, 0); + pRenderContext->ClearColor3ub( 0, 0, 0 ); } //------------------------------------------------------------------------------------------------------- // Lock down the usage of a shadow depth texture...must be unlocked for use on subsequent views / frames //------------------------------------------------------------------------------------------------------- -bool CClientShadowMgr::LockShadowDepthTexture(CTextureReference* shadowDepthTexture) +bool CClientShadowMgr::LockShadowDepthTexture( CTextureReference *shadowDepthTexture ) { - for (int i = 0; i < m_DepthTextureCache.Count(); i++) // Search for cached shadow depth texture + for ( int i=0; i < m_DepthTextureCache.Count(); i++ ) // Search for cached shadow depth texture { - if (m_DepthTextureCacheLocks[i] == false) // If a free one is found + if ( m_DepthTextureCacheLocks[i] == false ) // If a free one is found { *shadowDepthTexture = m_DepthTextureCache[i]; m_DepthTextureCacheLocks[i] = true; @@ -4250,35 +4736,35 @@ bool CClientShadowMgr::LockShadowDepthTexture(CTextureReference* shadowDepthText //------------------------------------------------------------------ void CClientShadowMgr::UnlockAllShadowDepthTextures() { - for (int i = 0; i < m_DepthTextureCache.Count(); i++) + for (int i=0; i< m_DepthTextureCache.Count(); i++ ) { m_DepthTextureCacheLocks[i] = false; } - SetViewFlashlightState(0, NULL); + SetViewFlashlightState( 0, NULL ); } -void CClientShadowMgr::SetFlashlightTarget(ClientShadowHandle_t shadowHandle, EHANDLE targetEntity) +void CClientShadowMgr::SetFlashlightTarget( ClientShadowHandle_t shadowHandle, EHANDLE targetEntity ) { - Assert(m_Shadows.IsValidIndex(shadowHandle)); + Assert( m_Shadows.IsValidIndex( shadowHandle ) ); - CClientShadowMgr::ClientShadow_t& shadow = m_Shadows[shadowHandle]; - if ((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) == 0) + CClientShadowMgr::ClientShadow_t &shadow = m_Shadows[ shadowHandle ]; + if( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ) return; - // shadow.m_pTargetRenderable = pRenderable; +// shadow.m_pTargetRenderable = pRenderable; shadow.m_hTargetEntity = targetEntity; } -void CClientShadowMgr::SetFlashlightLightWorld(ClientShadowHandle_t shadowHandle, bool bLightWorld) +void CClientShadowMgr::SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ) { - Assert(m_Shadows.IsValidIndex(shadowHandle)); + Assert( m_Shadows.IsValidIndex( shadowHandle ) ); - ClientShadow_t& shadow = m_Shadows[shadowHandle]; - if ((shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT) == 0) + ClientShadow_t &shadow = m_Shadows[ shadowHandle ]; + if( ( shadow.m_Flags & SHADOW_FLAGS_FLASHLIGHT ) == 0 ) return; - if (bLightWorld) + if ( bLightWorld ) { shadow.m_Flags |= SHADOW_FLAGS_LIGHT_WORLD; } @@ -4289,25 +4775,47 @@ void CClientShadowMgr::SetFlashlightLightWorld(ClientShadowHandle_t shadowHandle } -bool CClientShadowMgr::IsFlashlightTarget(ClientShadowHandle_t shadowHandle, IClientRenderable* pRenderable) +bool CClientShadowMgr::IsFlashlightTarget( ClientShadowHandle_t shadowHandle, IClientRenderable *pRenderable ) { - ClientShadow_t& shadow = m_Shadows[shadowHandle]; + ClientShadow_t &shadow = m_Shadows[ shadowHandle ]; - if (shadow.m_hTargetEntity->GetClientRenderable() == pRenderable) + if( shadow.m_hTargetEntity->GetClientRenderable() == pRenderable ) return true; - C_BaseEntity* pChild = shadow.m_hTargetEntity->FirstMoveChild(); - while (pChild) + C_BaseEntity *pChild = shadow.m_hTargetEntity->FirstMoveChild(); + while( pChild ) { - if (pChild->GetClientRenderable() == pRenderable) + if( pChild->GetClientRenderable()==pRenderable ) return true; pChild = pChild->NextMovePeer(); } - + return false; } +#ifdef DYNAMIC_RTT_SHADOWS +void CClientShadowMgr::SetShadowFromWorldLightsEnabled( bool bEnable ) +{ + bool bIsShadowingFromWorldLights = IsShadowingFromWorldLights(); + m_bShadowFromWorldLights = bEnable; + if ( bIsShadowingFromWorldLights != IsShadowingFromWorldLights() ) + { + UpdateAllShadows(); + } +} + +void CClientShadowMgr::SuppressShadowFromWorldLights( bool bSuppress ) +{ + bool bIsShadowingFromWorldLights = IsShadowingFromWorldLights(); + m_bSuppressShadowFromWorldLights = bSuppress; + if ( bIsShadowingFromWorldLights != IsShadowingFromWorldLights() ) + { + UpdateAllShadows(); + } +} +#endif + //----------------------------------------------------------------------------- // A material proxy that resets the base texture to use the rendered shadow //----------------------------------------------------------------------------- @@ -4316,10 +4824,10 @@ class CShadowProxy : public IMaterialProxy public: CShadowProxy(); virtual ~CShadowProxy(); - virtual bool Init(IMaterial* pMaterial, KeyValues* pKeyValues); - virtual void OnBind(void* pProxyData); - virtual void Release(void) { delete this; } - virtual IMaterial* GetMaterial(); + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + virtual void OnBind( void *pProxyData ); + virtual void Release( void ) { delete this; } + virtual IMaterial *GetMaterial(); private: IMaterialVar* m_BaseTextureVar; @@ -4335,30 +4843,30 @@ CShadowProxy::~CShadowProxy() } -bool CShadowProxy::Init(IMaterial* pMaterial, KeyValues* pKeyValues) +bool CShadowProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { bool foundVar; - m_BaseTextureVar = pMaterial->FindVar("$basetexture", &foundVar, false); + m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); return foundVar; } -void CShadowProxy::OnBind(void* pProxyData) +void CShadowProxy::OnBind( void *pProxyData ) { - unsigned short clientShadowHandle = (unsigned short)(int)pProxyData & 0xffff; - ITexture* pTex = s_ClientShadowMgr.GetShadowTexture(clientShadowHandle); - m_BaseTextureVar->SetTextureValue(pTex); - if (ToolsEnabled()) + unsigned short clientShadowHandle = ( unsigned short )(int)pProxyData&0xffff; + ITexture* pTex = s_ClientShadowMgr.GetShadowTexture( clientShadowHandle ); + m_BaseTextureVar->SetTextureValue( pTex ); + if ( ToolsEnabled() ) { - ToolFramework_RecordMaterialParams(GetMaterial()); + ToolFramework_RecordMaterialParams( GetMaterial() ); } } -IMaterial* CShadowProxy::GetMaterial() +IMaterial *CShadowProxy::GetMaterial() { return m_BaseTextureVar->GetOwningMaterial(); } -EXPOSE_INTERFACE(CShadowProxy, IMaterialProxy, "Shadow" IMATERIAL_PROXY_INTERFACE_VERSION); +EXPOSE_INTERFACE( CShadowProxy, IMaterialProxy, "Shadow" IMATERIAL_PROXY_INTERFACE_VERSION ); @@ -4370,10 +4878,10 @@ class CShadowModelProxy : public IMaterialProxy public: CShadowModelProxy(); virtual ~CShadowModelProxy(); - virtual bool Init(IMaterial* pMaterial, KeyValues* pKeyValues); - virtual void OnBind(void* pProxyData); - virtual void Release(void) { delete this; } - virtual IMaterial* GetMaterial(); + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + virtual void OnBind( void *pProxyData ); + virtual void Release( void ) { delete this; } + virtual IMaterial *GetMaterial(); private: IMaterialVar* m_BaseTextureVar; @@ -4401,54 +4909,54 @@ CShadowModelProxy::~CShadowModelProxy() } -bool CShadowModelProxy::Init(IMaterial* pMaterial, KeyValues* pKeyValues) +bool CShadowModelProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { bool foundVar; - m_BaseTextureVar = pMaterial->FindVar("$basetexture", &foundVar, false); + m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); if (!foundVar) return false; - m_BaseTextureOffsetVar = pMaterial->FindVar("$basetextureoffset", &foundVar, false); + m_BaseTextureOffsetVar = pMaterial->FindVar( "$basetextureoffset", &foundVar, false ); if (!foundVar) return false; - m_BaseTextureScaleVar = pMaterial->FindVar("$basetexturescale", &foundVar, false); + m_BaseTextureScaleVar = pMaterial->FindVar( "$basetexturescale", &foundVar, false ); if (!foundVar) return false; - m_BaseTextureMatrixVar = pMaterial->FindVar("$basetexturetransform", &foundVar, false); + m_BaseTextureMatrixVar = pMaterial->FindVar( "$basetexturetransform", &foundVar, false ); if (!foundVar) return false; - m_FalloffOffsetVar = pMaterial->FindVar("$falloffoffset", &foundVar, false); + m_FalloffOffsetVar = pMaterial->FindVar( "$falloffoffset", &foundVar, false ); if (!foundVar) return false; - m_FalloffDistanceVar = pMaterial->FindVar("$falloffdistance", &foundVar, false); + m_FalloffDistanceVar = pMaterial->FindVar( "$falloffdistance", &foundVar, false ); if (!foundVar) return false; - m_FalloffAmountVar = pMaterial->FindVar("$falloffamount", &foundVar, false); + m_FalloffAmountVar = pMaterial->FindVar( "$falloffamount", &foundVar, false ); return foundVar; } -void CShadowModelProxy::OnBind(void* pProxyData) +void CShadowModelProxy::OnBind( void *pProxyData ) { - unsigned short clientShadowHandle = (unsigned short)((int)pProxyData & 0xffff); - ITexture* pTex = s_ClientShadowMgr.GetShadowTexture(clientShadowHandle); - m_BaseTextureVar->SetTextureValue(pTex); + unsigned short clientShadowHandle = ( unsigned short )((int)pProxyData&0xffff); + ITexture* pTex = s_ClientShadowMgr.GetShadowTexture( clientShadowHandle ); + m_BaseTextureVar->SetTextureValue( pTex ); - const ShadowInfo_t& info = s_ClientShadowMgr.GetShadowInfo(clientShadowHandle); - m_BaseTextureMatrixVar->SetMatrixValue(info.m_WorldToShadow); - m_BaseTextureOffsetVar->SetVecValue(info.m_TexOrigin.Base(), 2); - m_BaseTextureScaleVar->SetVecValue(info.m_TexSize.Base(), 2); - m_FalloffOffsetVar->SetFloatValue(info.m_FalloffOffset); - m_FalloffDistanceVar->SetFloatValue(info.m_MaxDist); - m_FalloffAmountVar->SetFloatValue(info.m_FalloffAmount); + const ShadowInfo_t& info = s_ClientShadowMgr.GetShadowInfo( clientShadowHandle ); + m_BaseTextureMatrixVar->SetMatrixValue( info.m_WorldToShadow ); + m_BaseTextureOffsetVar->SetVecValue( info.m_TexOrigin.Base(), 2 ); + m_BaseTextureScaleVar->SetVecValue( info.m_TexSize.Base(), 2 ); + m_FalloffOffsetVar->SetFloatValue( info.m_FalloffOffset ); + m_FalloffDistanceVar->SetFloatValue( info.m_MaxDist ); + m_FalloffAmountVar->SetFloatValue( info.m_FalloffAmount ); - if (ToolsEnabled()) + if ( ToolsEnabled() ) { - ToolFramework_RecordMaterialParams(GetMaterial()); + ToolFramework_RecordMaterialParams( GetMaterial() ); } } -IMaterial* CShadowModelProxy::GetMaterial() +IMaterial *CShadowModelProxy::GetMaterial() { return m_BaseTextureVar->GetOwningMaterial(); } -EXPOSE_INTERFACE(CShadowModelProxy, IMaterialProxy, "ShadowModel" IMATERIAL_PROXY_INTERFACE_VERSION); \ No newline at end of file +EXPOSE_INTERFACE( CShadowModelProxy, IMaterialProxy, "ShadowModel" IMATERIAL_PROXY_INTERFACE_VERSION ); diff --git a/game/client/clientsideeffects.cpp b/game/client/clientsideeffects.cpp index c7912e3b..b9cb5f56 100644 --- a/game/client/clientsideeffects.cpp +++ b/game/client/clientsideeffects.cpp @@ -68,15 +68,6 @@ const char *CClientSideEffect::GetName( void ) return m_pszName; } -//----------------------------------------------------------------------------- -// Purpose: Set the name of effect -// Input : const char -//----------------------------------------------------------------------------- -void CClientSideEffect::SetEffectName( const char *pszName ) -{ - m_pszName = pszName; -} - //----------------------------------------------------------------------------- // Purpose: Is effect still active? // Output : Returns true on success, false on failure. @@ -108,7 +99,6 @@ class CEffectsList : public IEffectsList // Add an effect to the effects list void AddEffect( CClientSideEffect *effect ); // Remove the specified effect - void RemoveEffect( CClientSideEffect *effect ); // Draw/update all effects in the current list void DrawEffects( double frametime ); // Flush out all effects from the list @@ -170,23 +160,6 @@ void CEffectsList::AddEffect( CClientSideEffect *effect ) m_rgEffects[ m_nEffects++ ] = effect; } -//----------------------------------------------------------------------------- -void CEffectsList::RemoveEffect( CClientSideEffect *effect ) -{ - Assert( effect ); - CClientSideEffect **end = &m_rgEffects[m_nEffects]; - for( CClientSideEffect **p = &m_rgEffects[0]; p < end; ++p) - { - if ( *p == effect ) - { - RemoveEffect( p - &m_rgEffects[0] ); // todo remove this crutch - return; - } - } - - Assert( false ); // don't know this effect -} - //----------------------------------------------------------------------------- // Purpose: Remove specified effect by index // Input : effectIndex - diff --git a/game/client/clientsideeffects.h b/game/client/clientsideeffects.h index fd749565..c5aa4fd6 100644 --- a/game/client/clientsideeffects.h +++ b/game/client/clientsideeffects.h @@ -32,10 +32,7 @@ abstract_class CClientSideEffect virtual bool IsActive( void ); // Sets the effect to inactive so it can be destroed virtual void Destroy( void ); - - // Sets the effect name (useful for debugging). - virtual void SetEffectName( const char *pszName ); - + private: // Name of effect ( static data ) const char *m_pszName; @@ -53,8 +50,6 @@ abstract_class IEffectsList // Add an effect to the list of effects virtual void AddEffect( CClientSideEffect *effect ) = 0; - // Remove the specified effect - virtual void RemoveEffect( CClientSideEffect *effect ) = 0; // Simulate/Update/Draw effects on list virtual void DrawEffects( double frametime ) = 0; // Flush out all effects fbrom the list diff --git a/game/client/colorcorrectionmgr.cpp b/game/client/colorcorrectionmgr.cpp index 770354b0..cf1210ac 100644 --- a/game/client/colorcorrectionmgr.cpp +++ b/game/client/colorcorrectionmgr.cpp @@ -8,6 +8,12 @@ #include "cbase.h" #include "tier0/vprof.h" #include "colorcorrectionmgr.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "clientmode_shared.h" //"clientmode.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" +#endif //------------------------------------------------------------------------------ @@ -16,6 +22,13 @@ static CColorCorrectionMgr s_ColorCorrectionMgr; CColorCorrectionMgr *g_pColorCorrectionMgr = &s_ColorCorrectionMgr; +#ifdef MAPBASE // From Alien Swarm SDK +static ConVar mat_colcorrection_editor( "mat_colcorrection_editor", "0" ); + +static CUtlVector g_ColorCorrectionList; +static CUtlVector g_ColorCorrectionVolumeList; +#endif + //------------------------------------------------------------------------------ // Constructor @@ -62,10 +75,89 @@ void CColorCorrectionMgr::RemoveColorCorrection( ClientCCHandle_t h ) } } +#ifdef MAPBASE // From Alien Swarm SDK +ClientCCHandle_t CColorCorrectionMgr::AddColorCorrectionEntity( C_ColorCorrection *pEntity, const char *pName, const char *pFileName ) +{ + ClientCCHandle_t h = AddColorCorrection(pName, pFileName); + if ( h != INVALID_CLIENT_CCHANDLE ) + { + Assert(g_ColorCorrectionList.Find(pEntity) == -1); + g_ColorCorrectionList.AddToTail(pEntity); + } + return h; +} + +void CColorCorrectionMgr::RemoveColorCorrectionEntity( C_ColorCorrection *pEntity, ClientCCHandle_t h) +{ + RemoveColorCorrection(h); + g_ColorCorrectionList.FindAndFastRemove(pEntity); +} + +ClientCCHandle_t CColorCorrectionMgr::AddColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, const char *pName, const char *pFileName ) +{ + ClientCCHandle_t h = AddColorCorrection(pName, pFileName); + if ( h != INVALID_CLIENT_CCHANDLE ) + { + Assert(g_ColorCorrectionVolumeList.Find(pVolume) == -1); + g_ColorCorrectionVolumeList.AddToTail(pVolume); + } + return h; +} + +void CColorCorrectionMgr::RemoveColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, ClientCCHandle_t h) +{ + RemoveColorCorrection(h); + g_ColorCorrectionVolumeList.FindAndFastRemove(pVolume); +} +#endif //------------------------------------------------------------------------------ // Modify color correction weights //------------------------------------------------------------------------------ +#ifdef MAPBASE // From Alien Swarm SDK +void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight, bool bExclusive ) +{ + if ( h != INVALID_CLIENT_CCHANDLE ) + { + SetWeightParams_t params = { h, flWeight, bExclusive }; + m_colorCorrectionWeights.AddToTail( params ); + if( bExclusive && m_bHaveExclusiveWeight && ( flWeight != 0.0f ) ) + { + DevWarning( "Found multiple active color_correction entities with exclusive setting enabled. This is invalid.\n" ); + } + if ( bExclusive ) + { + m_bHaveExclusiveWeight = true; + m_flExclusiveWeight = flWeight; + } + } +} + +void CColorCorrectionMgr::CommitColorCorrectionWeights() +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + + for ( int i = 0; i < m_colorCorrectionWeights.Count(); i++ ) + { + ColorCorrectionHandle_t ccHandle = reinterpret_cast( m_colorCorrectionWeights[i].handle ); + float flWeight = m_colorCorrectionWeights[i].flWeight; + if ( !m_colorCorrectionWeights[i].bExclusive ) + { + flWeight = (1.0f - m_flExclusiveWeight ) * m_colorCorrectionWeights[i].flWeight; + } + pRenderContext->SetLookupWeight( ccHandle, flWeight ); + + // FIXME: NOTE! This doesn't work if the same handle has + // its weight set twice with no intervening calls to ResetColorCorrectionWeights + // which, at the moment, is true + if ( flWeight != 0.0f ) + { + ++m_nActiveWeightCount; + } + } + m_colorCorrectionWeights.RemoveAll(); +} +#else void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight ) { if ( h != INVALID_CLIENT_CCHANDLE ) @@ -83,6 +175,7 @@ void CColorCorrectionMgr::SetColorCorrectionWeight( ClientCCHandle_t h, float fl } } } +#endif void CColorCorrectionMgr::ResetColorCorrectionWeights() { @@ -93,6 +186,11 @@ void CColorCorrectionMgr::ResetColorCorrectionWeights() CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->ResetLookupWeights(); m_nActiveWeightCount = 0; +#ifdef MAPBASE // From Alien Swarm SDK + m_bHaveExclusiveWeight = false; + m_flExclusiveWeight = 0.0f; + m_colorCorrectionWeights.RemoveAll(); +#endif } void CColorCorrectionMgr::SetResetable( ClientCCHandle_t h, bool bResetable ) @@ -113,7 +211,34 @@ void CColorCorrectionMgr::SetResetable( ClientCCHandle_t h, bool bResetable ) //------------------------------------------------------------------------------ // Is color correction active? //------------------------------------------------------------------------------ +#ifdef MAPBASE // From Alien Swarm SDK +bool CColorCorrectionMgr::HasNonZeroColorCorrectionWeights() const +{ + return ( m_nActiveWeightCount != 0 ) || mat_colcorrection_editor.GetBool(); +} + +void CColorCorrectionMgr::UpdateColorCorrection() +{ + ResetColorCorrectionWeights(); + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + IClientMode *pClientMode = GetClientModeNormal(); //GetClientMode(); + + Assert( pClientMode ); + if ( !pPlayer || !pClientMode ) + { + return; + } + + pClientMode->OnColorCorrectionWeightsReset(); + float ccScale = pClientMode->GetColorCorrectionScale(); + + UpdateColorCorrectionEntities( pPlayer, ccScale, g_ColorCorrectionList.Base(), g_ColorCorrectionList.Count() ); + UpdateColorCorrectionVolumes( pPlayer, ccScale, g_ColorCorrectionVolumeList.Base(), g_ColorCorrectionVolumeList.Count() ); + CommitColorCorrectionWeights(); +} +#else bool CColorCorrectionMgr::HasNonZeroColorCorrectionWeights() const { return ( m_nActiveWeightCount != 0 ); } +#endif diff --git a/game/client/colorcorrectionmgr.h b/game/client/colorcorrectionmgr.h index 3d5271db..3eba0f8c 100644 --- a/game/client/colorcorrectionmgr.h +++ b/game/client/colorcorrectionmgr.h @@ -14,6 +14,10 @@ #include "igamesystem.h" +#ifdef MAPBASE // From Alien Swarm SDK +class C_ColorCorrection; +class C_ColorCorrectionVolume; +#endif //------------------------------------------------------------------------------ // Purpose : Singleton manager for color correction on the client @@ -35,8 +39,21 @@ class CColorCorrectionMgr : public CBaseGameSystem ClientCCHandle_t AddColorCorrection( const char *pName, const char *pFileName = NULL ); void RemoveColorCorrection( ClientCCHandle_t ); +#ifdef MAPBASE // From Alien Swarm SDK + ClientCCHandle_t AddColorCorrectionEntity( C_ColorCorrection *pEntity, const char *pName, const char *pFileName = NULL ); + void RemoveColorCorrectionEntity( C_ColorCorrection *pEntity, ClientCCHandle_t ); + + ClientCCHandle_t AddColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, const char *pName, const char *pFileName = NULL ); + void RemoveColorCorrectionVolume( C_ColorCorrectionVolume *pVolume, ClientCCHandle_t ); +#endif + // Modify color correction weights +#ifdef MAPBASE // From Alien Swarm SDK + void SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight, bool bExclusive = false ); + void UpdateColorCorrection(); +#else void SetColorCorrectionWeight( ClientCCHandle_t h, float flWeight ); +#endif void ResetColorCorrectionWeights(); void SetResetable( ClientCCHandle_t h, bool bResetable ); @@ -45,8 +62,27 @@ class CColorCorrectionMgr : public CBaseGameSystem private: int m_nActiveWeightCount; +#ifdef MAPBASE // From Alien Swarm SDK + bool m_bHaveExclusiveWeight; + float m_flExclusiveWeight; + + struct SetWeightParams_t + { + ClientCCHandle_t handle; + float flWeight; + bool bExclusive; + }; + + CUtlVector< SetWeightParams_t > m_colorCorrectionWeights; + + void CommitColorCorrectionWeights(); +#endif }; +#ifdef MAPBASE // From Alien Swarm SDK +void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount ); +void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount ); +#endif //------------------------------------------------------------------------------ // Singleton access diff --git a/game/client/convarproxy.cpp b/game/client/convarproxy.cpp new file mode 100644 index 00000000..6b08bafc --- /dev/null +++ b/game/client/convarproxy.cpp @@ -0,0 +1,113 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Material proxy to stuff a convar into a material var. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +// identifier was truncated to '255' characters in the debug information +//#pragma warning(disable: 4786) + +#include "convar.h" +#include "materialsystem/imaterialproxy.h" +#include "materialsystem/imaterialvar.h" +//#include "imaterialproxydict.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +class CConVarMaterialProxy: public IMaterialProxy +{ +public: + CConVarMaterialProxy() + : m_pResult( NULL ), + m_conVarRef( "", true ) + { + } + + virtual ~CConVarMaterialProxy() + { + } + + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ) + { + const char *pResult = pKeyValues->GetString( "resultVar" ); + if ( !pResult ) + return false; + + bool found; + m_pResult = pMaterial->FindVar( pResult, &found ); + if ( !found ) + { + m_pResult = NULL; + return false; + } + + /* + if ( !Q_stricmp( pResult, "$alpha" ) ) + { + pMaterial->SetMaterialVarFlag( MATERIAL_VAR_ALPHA_MODIFIED_BY_PROXY, true ); + } + */ + + pResult = pKeyValues->GetString( "convar" ); + if( !pResult ) + { + return false; + } + + m_conVarRef.Init( pResult, false ); + if ( !m_conVarRef.IsValid() ) + { + return false; + } + + return true; + } + + virtual void OnBind( void* ) + { + switch( m_pResult->GetType() ) + { + case MATERIAL_VAR_TYPE_VECTOR: + { + float f = m_conVarRef.GetFloat(); + Vector4D vec( f, f, f, f ); + m_pResult->SetVecValue( vec.Base(), m_pResult->VectorSize() ); + } + break; + +#ifdef MAPBASE + case MATERIAL_VAR_TYPE_STRING: + m_pResult->SetStringValue( m_conVarRef.GetString() ); + break; +#endif + + case MATERIAL_VAR_TYPE_INT: + m_pResult->SetIntValue( m_conVarRef.GetInt() ); + break; + + case MATERIAL_VAR_TYPE_FLOAT: + default: + m_pResult->SetFloatValue( m_conVarRef.GetFloat() ); + break; + } + } + + virtual IMaterial *GetMaterial() + { + return m_pResult->GetOwningMaterial(); + } + + virtual void Release() + { + } + +protected: + IMaterialVar *m_pResult; + ConVarRef m_conVarRef; +}; + +EXPOSE_INTERFACE( CConVarMaterialProxy, IMaterialProxy, "ConVar" IMATERIAL_PROXY_INTERFACE_VERSION ); diff --git a/game/client/detailobjectsystem.cpp b/game/client/detailobjectsystem.cpp index 3e211bb0..726e2cd7 100644 --- a/game/client/detailobjectsystem.cpp +++ b/game/client/detailobjectsystem.cpp @@ -1471,6 +1471,7 @@ void CDetailObjectSystem::LevelInitPreEntity() } } +#ifndef MAPBASE if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() ) { // There are detail objects in the level, so precache the material @@ -1489,6 +1490,7 @@ void CDetailObjectSystem::LevelInitPreEntity() } } } +#endif int detailPropLightingLump; if( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) @@ -1512,6 +1514,32 @@ void CDetailObjectSystem::LevelInitPreEntity() void CDetailObjectSystem::LevelInitPostEntity() { +#ifdef MAPBASE + if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() ) + { + const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL; + C_World *pWorld = GetClientWorldEntity(); + if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) ) + pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial(); + + m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER ); + PrecacheMaterial( pDetailSpriteMaterial ); + IMaterial *pMat = m_DetailSpriteMaterial; + + // adjust for non-square textures (cropped) + float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight(); + if ( flRatio > 1.0 ) + { + for( int i = 0; iGetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) ) @@ -1519,6 +1547,7 @@ void CDetailObjectSystem::LevelInitPostEntity() pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial(); } m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER ); +#endif if ( GetDetailController() ) { @@ -1595,12 +1624,14 @@ void CDetailObjectSystem::UnserializeModelDict( CUtlBuffer& buf ) DetailModelDict_t dict; dict.m_pModel = (model_t *)engine->LoadModel( lump.m_Name, true ); +#ifndef MAPBASE // Don't allow vertex-lit models if (modelinfo->IsModelVertexLit(dict.m_pModel)) { Warning("Detail prop model %s is using vertex-lit materials!\nIt must use unlit materials!\n", lump.m_Name ); dict.m_pModel = (model_t *)engine->LoadModel( "models/error.mdl" ); } +#endif m_DetailObjectDict.AddToTail( dict ); } diff --git a/game/client/episodic/c_prop_scalable.cpp b/game/client/episodic/c_prop_scalable.cpp index d3902db3..b3134460 100644 --- a/game/client/episodic/c_prop_scalable.cpp +++ b/game/client/episodic/c_prop_scalable.cpp @@ -5,6 +5,10 @@ //============================================================================= #include "cbase.h" +#ifdef MAPBASE +#include "proxyentity.h" +#include "materialsystem/imaterialvar.h" +#endif class C_PropScalable : public C_BaseAnimating { @@ -194,3 +198,56 @@ void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs ) Assert( theMins.IsValid() && theMaxs.IsValid() ); } + +#ifdef MAPBASE +ConVar r_coreball_update_sphere_center( "r_coreball_update_sphere_center", "1", FCVAR_NONE, "Allows prop_coreball to update its center to the entity's origin" ); + +class CCoreBallUpdateMaterialProxy : public CEntityMaterialProxy +{ +public: + CCoreBallUpdateMaterialProxy() + { + m_pMaterial = NULL; + m_pSphereCenter = NULL; + } + virtual ~CCoreBallUpdateMaterialProxy() + { + } + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ) + { + m_pMaterial = pMaterial; + bool found; + m_pSphereCenter = m_pMaterial->FindVar( "$spherecenter", &found ); + if( !found ) + { + m_pSphereCenter = NULL; + return false; + } + return true; + } + virtual void OnBind( C_BaseEntity *pC_BaseEntity ) + { + if (r_coreball_update_sphere_center.GetBool()) + { + const Vector &origin = pC_BaseEntity->GetAbsOrigin(); + m_pSphereCenter->SetVecValue( origin.x, origin.y, origin.z ); + } + else + { + // Just continuously bind the old hacked value (TODO: Optimize so it's not just assigning the same value constantly?) + m_pSphereCenter->SetVecValue( 2688.0, 12139.0, 5170.0 ); + } + } + + virtual IMaterial *GetMaterial() + { + return m_pMaterial; + } + +protected: + IMaterial *m_pMaterial; + IMaterialVar *m_pSphereCenter; +}; + +EXPOSE_INTERFACE( CCoreBallUpdateMaterialProxy, IMaterialProxy, "CoreBallUpdate" IMATERIAL_PROXY_INTERFACE_VERSION ); +#endif diff --git a/game/client/episodic/episodic_screenspaceeffects.h b/game/client/episodic/episodic_screenspaceeffects.h index f8b5493b..6bc7c952 100644 --- a/game/client/episodic/episodic_screenspaceeffects.h +++ b/game/client/episodic/episodic_screenspaceeffects.h @@ -36,6 +36,10 @@ class CStunEffect : public IScreenSpaceEffect bool m_bUpdateView; }; +#ifndef VANCE +ADD_SCREENSPACE_EFFECT( CStunEffect, episodic_stun ); +#endif + // // EP1 Intro Blur // @@ -71,6 +75,10 @@ class CEP1IntroEffect : public IScreenSpaceEffect bool m_bFadeOut; }; +#ifndef VANCE +ADD_SCREENSPACE_EFFECT( CEP1IntroEffect, episodic_intro ); +#endif + // // EP2 Player Stunned Effect // @@ -110,4 +118,8 @@ class CEP2StunEffect : public IScreenSpaceEffect bool m_bFadeOut; }; +#ifndef VANCE +ADD_SCREENSPACE_EFFECT( CEP2StunEffect, ep2_groggy ); +#endif + #endif // EPISODIC_SCREENSPACEEFFECTS_H diff --git a/game/client/flashlighteffect.cpp b/game/client/flashlighteffect.cpp index 4417aee4..03c9e19c 100644 --- a/game/client/flashlighteffect.cpp +++ b/game/client/flashlighteffect.cpp @@ -1,6 +1,6 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // -// Purpose: +// Purpose: // //===========================================================================// @@ -17,12 +17,9 @@ #ifdef HL2_CLIENT_DLL #include "c_basehlplayer.h" +#include "c_basehlcombatweapon.h" #endif // HL2_CLIENT_DLL -#ifdef VANCE -#include "vance_baseweapon_shared.h" -#endif - #if defined( _X360 ) extern ConVar r_flashlightdepthres; #else @@ -55,21 +52,25 @@ static ConVar r_flashlightnearoffsetscale( "r_flashlightnearoffsetscale", "1.0", static ConVar r_flashlighttracedistcutoff( "r_flashlighttracedistcutoff", "128" ); static ConVar r_flashlightbacktraceoffset( "r_flashlightbacktraceoffset", "0.4", FCVAR_CHEAT ); -static ConVar mat_slopescaledepthbias_shadowmap("mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT); -static ConVar mat_depthbias_shadowmap("mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT); +static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT ); +static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT ); + +static ConVar r_flashlightmuzzleflashfov( "r_flashlightmuzzleflashfov", "120", FCVAR_CHEAT ); + +#ifdef MAPBASE +static ConVar r_flashlighttextureoverride( "r_flashlighttextureoverride", "", FCVAR_CHEAT ); +#endif //----------------------------------------------------------------------------- CFlashlightEffectManager & FlashlightEffectManager() { static CFlashlightEffectManager s_flashlightEffectManager; - -// ASSERT_LOCAL_PLAYER_RESOLVABLE(); return s_flashlightEffectManager; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Input : nEntIndex - The m_nEntIndex of the client entity that is creating us. // vecPos - The position of the light emitter. // vecDir - The direction of the light emission. @@ -97,7 +98,7 @@ CFlashlightEffect::CFlashlightEffect(int nEntIndex, const char *pszTextureName, //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CFlashlightEffect::~CFlashlightEffect() { @@ -105,7 +106,7 @@ CFlashlightEffect::~CFlashlightEffect() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CFlashlightEffect::TurnOn() { @@ -122,7 +123,7 @@ void CFlashlightEffect::SetMuzzleFlashEnabled( bool bEnabled, float flBrightness } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CFlashlightEffect::TurnOff() { @@ -181,7 +182,6 @@ void C_BasePlayer::GetFlashlightOffset( const Vector &vecForward, const Vector & *pVecOffset = r_flashlightoffsety.GetFloat() * vecUp + r_flashlightoffsetx.GetFloat() * vecRight + r_flashlightoffsetz.GetFloat() * vecForward; } -ConVar r_flashlightmuzzleflashfov( "r_flashlightmuzzleflashfov", "120", FCVAR_CHEAT ); //----------------------------------------------------------------------------- @@ -230,7 +230,7 @@ void CFlashlightEffect::UpdateLightTopDown(const Vector &vecPos, const Vector &v state.m_Color[1] = 1.0f; state.m_Color[2] = 1.0f; state.m_Color[3] = r_flashlightambient.GetFloat(); - state.m_NearZ = r_flashlightnear.GetFloat() + m_flCurrentPullBackDist; // Push near plane out so that we don't clip the world when the flashlight pulls back + state.m_NearZ = r_flashlightnear.GetFloat() + m_flCurrentPullBackDist; // Push near plane out so that we don't clip the world when the flashlight pulls back state.m_FarZ = r_flashlightfar.GetFloat(); state.m_bEnableShadows = state.m_bEnableShadows && r_flashlightdepthtexture.GetBool(); state.m_flShadowMapResolution = r_flashlightdepthres.GetInt(); @@ -304,10 +304,10 @@ void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Ve UpdateFlashlightTexture( pTextureName ); -#ifdef VANCE - C_BaseVanceWeapon *pWeapon = (C_BaseVanceWeapon *)C_BasePlayer::GetLocalPlayer()->GetActiveWeapon(); - if (pWeapon) - UpdateMuzzleFlashTexture(pWeapon->GetVanceWpnData().szMuzzleFlashTexture); +#ifdef HL2_CLIENT_DLL + C_BaseHLCombatWeapon *pWeapon = (C_BaseHLCombatWeapon *)C_BasePlayer::GetLocalPlayer()->GetActiveWeapon(); + if ( pWeapon ) + UpdateMuzzleFlashTexture( nullptr ); #endif FlashlightState_t state; @@ -328,9 +328,9 @@ void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Ve g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state ); } } - + g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true ); - + #ifndef NO_TOOLFRAMEWORK if ( clienttools->IsInRecordingMode() ) { @@ -345,7 +345,7 @@ void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Ve #endif } -void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, +void CFlashlightEffect::UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, float flFov, bool castsShadows, ITexture *pFlashlightTexture, const Vector &vecBrightness, bool bTracePlayers ) { @@ -426,16 +426,15 @@ bool CFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, bool bFlicker = false; -#ifdef HL2_EPISODIC C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); - if ( pPlayer ) + if ( hl2_episodic.GetBool() && pPlayer ) { float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower; if ( flBatteryPower <= 10.0f ) { float flScale; if ( flBatteryPower >= 0.0f ) - { + { flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f; } else @@ -472,7 +471,6 @@ bool CFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, bFlicker = true; } } -#endif // HL2_EPISODIC if ( bFlicker == false ) { @@ -508,7 +506,7 @@ bool CFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, state.m_Color[2] = 1.0f; state.m_Color[3] = r_flashlightambient.GetFloat(); - state.m_NearZ = r_flashlightnear.GetFloat() + r_flashlightnearoffsetscale.GetFloat() * m_flCurrentPullBackDist; // Optionally push near plane out so that we don't clip the world when the flashlight pulls back + state.m_NearZ = r_flashlightnear.GetFloat() + r_flashlightnearoffsetscale.GetFloat() * m_flCurrentPullBackDist; // Optionally push near plane out so that we don't clip the world when the flashlight pulls back state.m_FarZ = m_flFarZ; /*if ( m_flFarZ > 0.0f ) { @@ -553,6 +551,15 @@ void CFlashlightEffect::UpdateFlashlightTexture( const char* pTextureName ) pTextureName = pEmptyString; } +#ifdef MAPBASE + if ( r_flashlighttextureoverride.GetString()[0] != '\0' ) + { + m_FlashlightTexture.Init( r_flashlighttextureoverride.GetString(), TEXTURE_GROUP_OTHER, true ); + V_strncpy( m_textureName, pTextureName, sizeof( m_textureName ) ); + return; + } +#endif + if ( !m_FlashlightTexture.IsValid() || V_stricmp( m_textureName, pTextureName ) != 0 ) { @@ -568,27 +575,27 @@ void CFlashlightEffect::UpdateFlashlightTexture( const char* pTextureName ) } } -void CFlashlightEffect::UpdateMuzzleFlashTexture(const char *pTextureName) +void CFlashlightEffect::UpdateMuzzleFlashTexture( const char *pTextureName ) { - static const char* pEmptyString = ""; + static const char *pEmptyString = ""; - if (pTextureName == NULL) + if ( pTextureName == NULL ) { pTextureName = pEmptyString; } - if (!m_MuzzleFlashTexture.IsValid() || - V_stricmp(m_textureName, pTextureName) != 0) + if ( !m_MuzzleFlashTexture.IsValid() || + V_stricmp( m_textureName, pTextureName ) != 0 ) { - if (pTextureName == pEmptyString) + if ( pTextureName == pEmptyString ) { - m_MuzzleFlashTexture.Init("effects/muzzleflash_light", TEXTURE_GROUP_OTHER, true); + m_MuzzleFlashTexture.Init( "effects/muzzleflash_light", TEXTURE_GROUP_OTHER, true ); } else { - m_MuzzleFlashTexture.Init(pTextureName, TEXTURE_GROUP_OTHER, true); + m_MuzzleFlashTexture.Init( pTextureName, TEXTURE_GROUP_OTHER, true ); } - V_strncpy(m_textureName, pTextureName, sizeof(m_textureName)); + V_strncpy( m_textureName, pTextureName, sizeof( m_textureName ) ); } } @@ -624,7 +631,7 @@ bool CFlashlightEffect::ComputeLightPosAndOrientation( const Vector &vecPos, con Vector vOrigin = vecPos + vecOffset; // Not on ladder...trace a hull - if ( !bPlayerOnLadder ) + if ( !bPlayerOnLadder ) { Vector vecPlayerEyePos = pPlayer->GetRenderOrigin() + pPlayer->GetViewOffset(); @@ -749,7 +756,7 @@ bool CFlashlightEffect::ComputeLightPosAndOrientation( const Vector &vecPos, con //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CFlashlightEffect::LightOff() { @@ -774,14 +781,14 @@ void CFlashlightEffect::LightOff() } } -CHeadlightEffect::CHeadlightEffect() +CHeadlightEffect::CHeadlightEffect() { } CHeadlightEffect::~CHeadlightEffect() { - + } void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance ) @@ -799,7 +806,7 @@ void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, VectorNormalize(basisZ); BasisToQuaternion( basisX, basisY, basisZ, state.m_quatOrientation ); - + state.m_vecLightOrigin = vecPos; state.m_fHorizontalFOVDegrees = 45.0f; @@ -817,7 +824,7 @@ void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, state.m_pSpotlightTexture = m_FlashlightTexture; // state.m_pProjectedMaterial = NULL; state.m_nSpotlightTextureFrame = 0; - + if( GetFlashlightHandle() == CLIENTSHADOW_INVALID_HANDLE ) { SetFlashlightHandle( g_pClientShadowMgr->CreateFlashlight( state ) ); @@ -826,7 +833,7 @@ void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, { g_pClientShadowMgr->UpdateFlashlightState( GetFlashlightHandle(), state ); } - + g_pClientShadowMgr->UpdateProjectedTexture( GetFlashlightHandle(), true ); } diff --git a/game/client/flashlighteffect.h b/game/client/flashlighteffect.h index 6f703d84..aadefc93 100644 --- a/game/client/flashlighteffect.h +++ b/game/client/flashlighteffect.h @@ -1,6 +1,6 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -20,7 +20,7 @@ class CFlashlightEffect CFlashlightEffect(int nEntIndex = 0, const char *pszTextureName = NULL, float flFov = 0.0f, float flFarZ = 0.0f, float flLinearAtten = 0.0f ); ~CFlashlightEffect(); - void UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, float flFov, + void UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, float flFov, float flFarZ, float flLinearAtten, bool castsShadows, const char* pTextureName ); void UpdateLight( int nEntIdx, const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, float flFov, bool castsShadows, ITexture *pFlashlightTexture, const Vector &vecBrightness, bool bTracePlayers = true ); @@ -81,7 +81,7 @@ class CFlashlightEffect class CHeadlightEffect : public CFlashlightEffect { public: - + CHeadlightEffect(); ~CHeadlightEffect(); @@ -265,7 +265,7 @@ class CFlashlightEffectManager if ( bFlashlightOn && !m_pFlashlightEffect ) { - m_pFlashlightEffect = new CFlashlightEffect( m_nFlashlightEntIndex ); + m_pFlashlightEffect = new CFlashlightEffect( m_nFlashlightEntIndex ); } else if ( !bFlashlightOn && m_pFlashlightEffect ) { diff --git a/game/client/fx.cpp b/game/client/fx.cpp index b7f12cbd..78a70a77 100644 --- a/game/client/fx.cpp +++ b/game/client/fx.cpp @@ -1256,6 +1256,13 @@ void FX_BuildTeslaHitbox( const CEffectData &data ) { Vector vColor( 1, 1, 1 ); +#ifdef MAPBASE + if ( data.m_bCustomColors ) + { + vColor = data.m_CustomColors.m_vecColor1; + } +#endif + C_BaseEntity *pEntity = ClientEntityList().GetEnt( data.entindex() ); C_BaseAnimating *pAnimating = pEntity ? pEntity->GetBaseAnimating() : NULL; if (!pAnimating) diff --git a/game/client/fx_impact.cpp b/game/client/fx_impact.cpp index 682d5435..236e39b4 100644 --- a/game/client/fx_impact.cpp +++ b/game/client/fx_impact.cpp @@ -25,6 +25,13 @@ extern ConVar r_drawmodeldecals; ImpactSoundRouteFn g_pImpactSoundRouteFn = NULL; +#ifdef MAPBASE +ConVar g_ragdoll_steal_impacts_client( "g_ragdoll_steal_impacts_client", "1", FCVAR_NONE, "Allows clientside death ragdolls to \"steal\" impacts from their source entities. This fixes issues with NPCs dying before decals are applied." ); +ConVar g_ragdoll_steal_impacts_server( "g_ragdoll_steal_impacts_server", "1", FCVAR_NONE, "Allows serverside death ragdolls to \"steal\" impacts from their source entities. This fixes issues with NPCs dying before decals are applied." ); + +ConVar g_ragdoll_client_impact_decals( "g_ragdoll_client_impact_decals", "1", FCVAR_NONE, "Applies decals to clientside ragdolls when they are hit." ); +#endif + //========================================================================================================================== // RAGDOLL ENUMERATOR //========================================================================================================================== @@ -32,7 +39,11 @@ CRagdollEnumerator::CRagdollEnumerator( Ray_t& shot, int iDamageType ) { m_rayShot = shot; m_iDamageType = iDamageType; +#ifdef MAPBASE + m_pHitEnt = NULL; +#else m_bHit = false; +#endif } IterationRetval_t CRagdollEnumerator::EnumElement( IHandleEntity *pHandleEntity ) @@ -57,7 +68,11 @@ IterationRetval_t CRagdollEnumerator::EnumElement( IHandleEntity *pHandleEntity if ( tr.fraction < 1.0 ) { pModel->ImpactTrace( &tr, m_iDamageType, NULL ); +#ifdef MAPBASE + m_pHitEnt = pModel; +#else m_bHit = true; +#endif //FIXME: Yes? No? return ITERATION_STOP; @@ -84,6 +99,22 @@ bool FX_AffectRagdolls( Vector vecOrigin, Vector vecStart, int iDamageType ) return ragdollEnum.Hit(); } +#ifdef MAPBASE +C_BaseAnimating *FX_AffectRagdolls_GetHit( Vector vecOrigin, Vector vecStart, int iDamageType ) +{ + // don't do this when lots of ragdolls are simulating + if ( s_RagdollLRU.CountRagdolls(true) > 1 ) + return NULL; + Ray_t shotRay; + shotRay.Init( vecStart, vecOrigin ); + + CRagdollEnumerator ragdollEnum( shotRay, iDamageType ); + partition->EnumerateElementsAlongRay( PARTITION_CLIENT_RESPONSIVE_EDICTS, shotRay, false, &ragdollEnum ); + + return ragdollEnum.GetHit(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : &data - @@ -104,6 +135,22 @@ bool Impact( Vector &vecOrigin, Vector &vecStart, int iMaterial, int iDamageType Assert ( pEntity ); +#ifdef MAPBASE + // If the entity already has a ragdoll that was created on the current tick, use that ragdoll instead. + // This allows the killing damage's decals to show up on the ragdoll. + if (C_BaseAnimating *pAnimating = pEntity->GetBaseAnimating()) + { + if (pAnimating->m_pClientsideRagdoll && WasRagdollCreatedOnCurrentTick( pAnimating->m_pClientsideRagdoll ) && g_ragdoll_steal_impacts_client.GetBool()) + { + pEntity = pAnimating->m_pClientsideRagdoll; + } + else if (pAnimating->m_pServerRagdoll && WasRagdollCreatedOnCurrentTick( pAnimating->m_pServerRagdoll ) && g_ragdoll_steal_impacts_server.GetBool()) + { + pEntity = pAnimating->m_pServerRagdoll; + } + } +#endif + // Clear out the trace memset( &tr, 0, sizeof(trace_t)); tr.fraction = 1.0f; @@ -115,13 +162,52 @@ bool Impact( Vector &vecOrigin, Vector &vecStart, int iMaterial, int iDamageType VectorMA( vecStart, flLength + 8.0f, shotDir, traceExt ); // Attempt to hit ragdolls - + bool bHitRagdoll = false; - + +#ifdef MAPBASE + if ( !pEntity->IsClientCreated() ) + { + C_BaseAnimating *pRagdoll = FX_AffectRagdolls_GetHit( vecOrigin, vecStart, iDamageType ); + if (pRagdoll) + { + bHitRagdoll = true; + + if (g_ragdoll_client_impact_decals.GetBool() && pRagdoll->IsRagdoll()) + { + pEntity = pRagdoll; + + // HACKHACK: Get the ragdoll's nearest bone for its material + int iNearestMaterial = 0; + float flNearestDistSqr = FLT_MAX; + + IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; + int count = pEntity->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) ); + for ( int i = 0; i < count; i++ ) + { + Vector vecPosition; + QAngle angAngles; + pList[i]->GetPosition( &vecPosition, &angAngles ); + float flDistSqr = (vecStart - vecPosition).LengthSqr(); + if (flDistSqr < flNearestDistSqr) + { + iNearestMaterial = pList[i]->GetMaterialIndex(); + flNearestDistSqr = flDistSqr; + } + } + + // Get the material from the surfaceprop + surfacedata_t *psurfaceData = physprops->GetSurfaceData( iNearestMaterial ); + iMaterial = psurfaceData->game.material; + } + } + } +#else if ( !pEntity->IsClientCreated() ) { bHitRagdoll = FX_AffectRagdolls( vecOrigin, vecStart, iDamageType ); } +#endif if ( (nFlags & IMPACT_NODECAL) == 0 ) { diff --git a/game/client/fx_impact.h b/game/client/fx_impact.h index ad57f7e7..9c6cb875 100644 --- a/game/client/fx_impact.h +++ b/game/client/fx_impact.h @@ -58,12 +58,21 @@ class CRagdollEnumerator : public IPartitionEnumerator // Actual work code virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ); +#ifdef MAPBASE + bool Hit( void ) const { return m_pHitEnt != NULL; } + C_BaseAnimating *GetHit( void ) { return m_pHitEnt; } +#else bool Hit( void ) const { return m_bHit; } +#endif private: Ray_t m_rayShot; int m_iDamageType; +#ifdef MAPBASE + C_BaseAnimating *m_pHitEnt; +#else bool m_bHit; +#endif }; #endif // FX_IMPACT_H diff --git a/game/client/fx_quad.cpp b/game/client/fx_quad.cpp index 12d95b7d..6a254b97 100644 --- a/game/client/fx_quad.cpp +++ b/game/client/fx_quad.cpp @@ -13,21 +13,11 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -static const char g_EffectName[] = "Quad"; - CFXQuad::CFXQuad( const FXQuadData_t &data ) - : CClientSideEffect( g_EffectName ) + +: CClientSideEffect( "Quad" ) { m_FXData = data; - - if ( data.m_pMaterial != NULL ) - { - // If we've got a material, use that as our effectname instead of just "Quad". - // This should hopefully help narrow down messages like "No room for effect Quad". - const char *szMaterialName = data.m_pMaterial->GetName(); - if ( szMaterialName ) - SetEffectName( szMaterialName ); - } } CFXQuad::~CFXQuad( void ) @@ -72,12 +62,6 @@ void CFXQuad::Draw( double frametime ) float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * alphaTimePerc ); alpha = clamp( alpha, 0.0f, 1.0f ); - - // PASSTIME don't bother if alpha is 0 - if ( alpha == 0 ) - { - return; - } CMatRenderContextPtr pRenderContext( materials ); @@ -168,8 +152,6 @@ bool CFXQuad::IsActive( void ) //----------------------------------------------------------------------------- void CFXQuad::Destroy( void ) { - SetEffectName( g_EffectName ); - //Release the material if ( m_FXData.m_pMaterial != NULL ) { diff --git a/game/client/fx_quad.h b/game/client/fx_quad.h index 638547e8..77563e8b 100644 --- a/game/client/fx_quad.h +++ b/game/client/fx_quad.h @@ -82,6 +82,8 @@ class CFXQuad : public CClientSideEffect virtual void Destroy( void ); virtual void Update( double frametime ); +protected: + FXQuadData_t m_FXData; }; diff --git a/game/client/fx_tracer.cpp b/game/client/fx_tracer.cpp index cec013a6..8ce6de18 100644 --- a/game/client/fx_tracer.cpp +++ b/game/client/fx_tracer.cpp @@ -13,9 +13,6 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -ConVar r_drawtracers( "r_drawtracers", "1", FCVAR_CHEAT ); -ConVar r_drawtracers_firstperson( "r_drawtracers_firstperson", "1", FCVAR_ARCHIVE, "Toggle visibility of first person weapon tracers" ); - #define TRACER_SPEED 5000 //----------------------------------------------------------------------------- @@ -26,7 +23,7 @@ Vector GetTracerOrigin( const CEffectData &data ) Vector vecStart = data.m_vStart; QAngle vecAngles; - int iAttachment = data.m_nAttachmentIndex; + int iAttachment = data.m_nAttachmentIndex;; // Attachment? if ( data.m_fFlags & TRACER_FLAG_USEATTACHMENT ) @@ -40,11 +37,13 @@ Vector GetTracerOrigin( const CEffectData &data ) C_BaseEntity *pEnt = data.GetEntity(); -// This check should probably be for all multiplayer games, investigate later -#if defined( HL2MP ) || defined( TF_CLIENT_DLL ) - if ( pEnt && pEnt->IsDormant() ) - return vecStart; -#endif + // This check should probably be for all multiplayer games, investigate later + // 10/09/2008: It should. + if ( gpGlobals->maxClients > 1 ) + { + if ( pEnt && pEnt->IsDormant() ) + return vecStart; + } C_BaseCombatWeapon *pWpn = dynamic_cast( pEnt ); if ( pWpn && pWpn->ShouldDrawUsingViewModel() ) @@ -80,17 +79,6 @@ void TracerCallback( const CEffectData &data ) if ( !player ) return; - if ( !r_drawtracers.GetBool() ) - return; - - if ( !r_drawtracers_firstperson.GetBool() ) - { - C_BasePlayer *pPlayer = dynamic_cast( data.GetEntity() ); - - if ( pPlayer && !pPlayer->ShouldDrawThisPlayer() ) - return; - } - // Grab the data Vector vecStart = GetTracerOrigin( data ); float flVelocity = data.m_flScale; @@ -134,17 +122,6 @@ void ParticleTracerCallback( const CEffectData &data ) if ( !player ) return; - if ( !r_drawtracers.GetBool() ) - return; - - if ( !r_drawtracers_firstperson.GetBool() ) - { - C_BasePlayer *pPlayer = dynamic_cast( data.GetEntity() ); - - if ( pPlayer && !pPlayer->ShouldDrawThisPlayer() ) - return; - } - // Grab the data Vector vecStart = GetTracerOrigin( data ); Vector vecEnd = data.m_vOrigin; diff --git a/game/client/game_controls/MapOverview.cpp b/game/client/game_controls/MapOverview.cpp index 73d259ff..b4262fbb 100644 --- a/game/client/game_controls/MapOverview.cpp +++ b/game/client/game_controls/MapOverview.cpp @@ -181,7 +181,7 @@ void CMapOverview::Init( void ) // register for events as client listener ListenForGameEvent( "game_newmap" ); ListenForGameEvent( "round_start" ); - ListenForGameEvent( "player_connect_client" ); + ListenForGameEvent( "player_connect" ); ListenForGameEvent( "player_info" ); ListenForGameEvent( "player_team" ); ListenForGameEvent( "player_spawn" ); @@ -933,7 +933,7 @@ void CMapOverview::FireGameEvent( IGameEvent *event ) ResetRound(); } - else if ( Q_strcmp(type,"player_connect_client") == 0 ) + else if ( Q_strcmp(type,"player_connect") == 0 ) { int index = event->GetInt("index"); // = entity index - 1 diff --git a/game/client/game_controls/SpectatorGUI.cpp b/game/client/game_controls/SpectatorGUI.cpp index 3ce30008..1c95068a 100644 --- a/game/client/game_controls/SpectatorGUI.cpp +++ b/game/client/game_controls/SpectatorGUI.cpp @@ -67,7 +67,6 @@ static const char *s_SpectatorModes[] = "#Spec_Mode2", // OBS_MODE_FIXED, "#Spec_Mode3", // OBS_MODE_IN_EYE, "#Spec_Mode4", // OBS_MODE_CHASE, - "#Spec_Mode_POI", // OBS_MODE_POI, PASSTIME "#Spec_Mode5", // OBS_MODE_ROAMING, }; @@ -807,8 +806,6 @@ CON_COMMAND_F( spec_mode, "Set spectator mode", FCVAR_CLIENTCMD_CAN_EXECUTE ) if ( mode > LAST_PLAYER_OBSERVERMODE ) mode = OBS_MODE_IN_EYE; - else if ( mode == OBS_MODE_POI ) // PASSTIME skip POI mode since hltv doesn't have the entity data required to make it work - mode = OBS_MODE_ROAMING; } // handle the command clientside diff --git a/game/client/game_controls/basemodel_panel.cpp b/game/client/game_controls/basemodel_panel.cpp index 5f834412..e4115ea4 100644 --- a/game/client/game_controls/basemodel_panel.cpp +++ b/game/client/game_controls/basemodel_panel.cpp @@ -22,7 +22,6 @@ CBaseModelPanel::CBaseModelPanel( vgui::Panel *pParent, const char *pName ): Bas m_bForcePos = false; m_bMousePressed = false; m_bAllowRotation = false; - m_bAllowPitch = false; m_bAllowFullManipulation = false; m_bApplyManipulators = false; m_bForcedCameraPosition = false; @@ -44,7 +43,6 @@ void CBaseModelPanel::ApplySettings( KeyValues *inResourceData ) // Set whether we render to texture m_bRenderToTexture = inResourceData->GetBool( "render_texture", true ); - m_bUseParticle = inResourceData->GetBool( "use_particle", false ); // Grab and set the camera FOV. float flFOV = GetCameraFOV(); @@ -53,7 +51,6 @@ void CBaseModelPanel::ApplySettings( KeyValues *inResourceData ) // Do we allow rotation on these panels. m_bAllowRotation = inResourceData->GetBool( "allow_rot", false ); - m_bAllowPitch = inResourceData->GetBool( "allow_pitch", false ); // Do we allow full manipulation on these panels. m_bAllowFullManipulation = inResourceData->GetBool( "allow_manip", false ); @@ -67,7 +64,7 @@ void CBaseModelPanel::ApplySettings( KeyValues *inResourceData ) } } - SetMouseInputEnabled( m_bAllowFullManipulation || m_bAllowRotation || m_bAllowPitch ); + SetMouseInputEnabled( m_bAllowFullManipulation || m_bAllowRotation ); } //----------------------------------------------------------------------------- @@ -415,16 +412,13 @@ void CBaseModelPanel::OnMousePressed ( vgui::MouseCode code ) return; } - if ( !m_bAllowRotation && !m_bAllowPitch ) + if ( !m_bAllowRotation ) return; RequestFocus(); EnableMouseCapture( true, code ); - // Save where they clicked - input()->GetCursorPosition( m_nClickStartX, m_nClickStartY ); - // Warp the mouse to the center of the screen int width, height; GetSize( width, height ); @@ -452,14 +446,11 @@ void CBaseModelPanel::OnMouseReleased( vgui::MouseCode code ) return; } - if ( !m_bAllowRotation && !m_bAllowPitch ) + if ( !m_bAllowRotation ) return; EnableMouseCapture( false ); m_bMousePressed = false; - - // Restore the cursor to where the clicked - input()->SetCursorPos( m_nClickStartX, m_nClickStartY ); } //----------------------------------------------------------------------------- @@ -476,7 +467,7 @@ void CBaseModelPanel::OnCursorMoved( int x, int y ) return; } - if ( !m_bAllowRotation && !m_bAllowPitch ) + if ( !m_bAllowRotation ) return; if ( m_bMousePressed ) @@ -485,25 +476,11 @@ void CBaseModelPanel::OnCursorMoved( int x, int y ) int xpos, ypos; input()->GetCursorPos( xpos, ypos ); - if ( m_bAllowRotation ) - { - // Only want the x delta. - float flDelta = xpos - m_nManipStartX; - + // Only want the x delta. + float flDelta = xpos - m_nManipStartX; - // Apply the delta and rotate the player. - RotateYaw( flDelta ); - } - - if ( m_bAllowPitch ) - { - // Only want the y delta. - float flDelta = ypos - m_nManipStartY; - - - // Apply the delta and rotate the player. - RotatePitch( flDelta ); - } + // Apply the delta and rotate the player. + RotateYaw( flDelta ); } } @@ -524,23 +501,6 @@ void CBaseModelPanel::RotateYaw( float flDelta ) SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos ); } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CBaseModelPanel::RotatePitch( float flDelta ) -{ - m_angPlayer.x += flDelta; - if ( m_angPlayer.x > m_flMaxPitch ) - { - m_angPlayer.x = m_flMaxPitch; - } - else if ( m_angPlayer.x < -m_flMaxPitch ) - { - m_angPlayer.x = -m_flMaxPitch; - } - - SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos ); -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- Vector CBaseModelPanel::GetPlayerPos() const @@ -683,7 +643,7 @@ void CBaseModelPanel::LookAtBounds( const Vector &vecBoundsMin, const Vector &ve // Clear the camera pivot and set position matrix. ResetCameraPivot(); - if (m_bAllowRotation || m_bAllowPitch ) + if (m_bAllowRotation ) { vecCameraOffset.x = 0.0f; } @@ -691,150 +651,3 @@ void CBaseModelPanel::LookAtBounds( const Vector &vecBoundsMin, const Vector &ve UpdateCameraTransform(); } - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CBaseModelPanel::particle_data_t::~particle_data_t() -{ - if ( m_pParticleSystem ) - { - delete m_pParticleSystem; - m_pParticleSystem = NULL; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Allocate particle data -//----------------------------------------------------------------------------- -void CBaseModelPanel::particle_data_t::UpdateControlPoints( CStudioHdr *pStudioHdr, matrix3x4_t *pWorldMatrix, const CUtlVector< int >& vecAttachments, int iDefaultBone /*= 0*/, const Vector& vecParticleOffset /*= vec3_origin*/ ) -{ - if ( m_pParticleSystem ) - { - // Update control points which is updating the position of the particles - matrix3x4_t matAttachToWorld; - Vector vecPosition, vecForward, vecRight, vecUp; - if ( vecAttachments.Count() ) - { - for ( int i = 0; i < vecAttachments.Count(); ++i ) - { - const mstudioattachment_t& attach = pStudioHdr->pAttachment( vecAttachments[i] ); - MatrixMultiply( pWorldMatrix[ attach.localbone ], attach.local, matAttachToWorld ); - - MatrixVectors( matAttachToWorld, &vecForward, &vecRight, &vecUp ); - MatrixPosition( matAttachToWorld, vecPosition ); - - m_pParticleSystem->SetControlPointOrientation( i, vecForward, vecRight, vecUp ); - m_pParticleSystem->SetControlPoint( i, vecPosition + vecParticleOffset ); - } - } - else - { - matAttachToWorld = pWorldMatrix[iDefaultBone]; - MatrixVectors( matAttachToWorld, &vecForward, &vecRight, &vecUp ); - MatrixPosition( matAttachToWorld, vecPosition ); - - m_pParticleSystem->SetControlPointOrientation( 0, vecForward, vecRight, vecUp ); - m_pParticleSystem->SetControlPoint( 0, vecPosition + vecParticleOffset ); - } - } - - m_bIsUpdateToDate = true; -} - - -//----------------------------------------------------------------------------- -// Purpose: Allocate particle data -//----------------------------------------------------------------------------- -CBaseModelPanel::particle_data_t *CBaseModelPanel::CreateParticleData( const char *pszParticleName ) -{ - Assert( m_bUseParticle ); - if ( !m_bUseParticle ) - return NULL; - - CParticleCollection *pParticle = g_pParticleSystemMgr->CreateParticleCollection( pszParticleName ); - if ( !pParticle ) - return NULL; - - particle_data_t *pData = new particle_data_t; - pData->m_bIsUpdateToDate = false; - pData->m_pParticleSystem = pParticle; - - m_particleList.AddToTail( pData ); - - return pData; -} - - -//----------------------------------------------------------------------------- -// Purpose: remove and delete particle data -//----------------------------------------------------------------------------- -bool CBaseModelPanel::SafeDeleteParticleData( particle_data_t **pData ) -{ - if ( !m_bUseParticle ) - return false; - - if ( *pData ) - { - FOR_EACH_VEC( m_particleList, i ) - { - if ( *pData == m_particleList[i] ) - { - delete *pData; - *pData = NULL; - m_particleList.FastRemove( i ); - return true; - } - } - } - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseModelPanel::PrePaint3D( IMatRenderContext *pRenderContext ) -{ - if ( !m_bUseParticle ) - return; - - // mark all effects need to be updated - FOR_EACH_VEC( m_particleList, i ) - { - m_particleList[i]->m_bIsUpdateToDate = false; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseModelPanel::PostPaint3D( IMatRenderContext *pRenderContext ) -{ - if ( !m_bUseParticle ) - return; - - // This needs calling to reset various counters. - g_pParticleSystemMgr->SetLastSimulationTime( gpGlobals->curtime ); - - // Render Particles - pRenderContext->MatrixMode( MATERIAL_MODEL ); - pRenderContext->PushMatrix(); - pRenderContext->LoadIdentity( ); - - FOR_EACH_VEC( m_particleList, i ) - { - if ( m_particleList[i]->m_bIsUpdateToDate ) - { - m_particleList[i]->m_pParticleSystem->Simulate( gpGlobals->frametime, false ); - m_particleList[i]->m_pParticleSystem->Render( pRenderContext ); - m_particleList[i]->m_bIsUpdateToDate = false; - } - } - - pRenderContext->MatrixMode( MATERIAL_MODEL ); - pRenderContext->PopMatrix(); -} - diff --git a/game/client/game_controls/basemodel_panel.h b/game/client/game_controls/basemodel_panel.h index a71bb7a4..b9fa0d68 100644 --- a/game/client/game_controls/basemodel_panel.h +++ b/game/client/game_controls/basemodel_panel.h @@ -182,8 +182,7 @@ class CBaseModelPanel : public CMDLPanel studiohdr_t* GetStudioHdr( void ) { return m_RootMDL.m_MDL.GetStudioHdr(); } void SetBody( unsigned int nBody ) { m_RootMDL.m_MDL.m_nBody = nBody; } - void RotateYaw( float flDelta ); - void RotatePitch( float flDelta ); + void RotateYaw( float flDelta ); Vector GetPlayerPos() const; QAngle GetPlayerAngles() const; @@ -214,7 +213,6 @@ class CBaseModelPanel : public CMDLPanel bool m_bForcePos; bool m_bMousePressed; bool m_bAllowRotation; - bool m_bAllowPitch; bool m_bAllowFullManipulation; bool m_bApplyManipulators; bool m_bForcedCameraPosition; @@ -222,25 +220,6 @@ class CBaseModelPanel : public CMDLPanel // VGUI script accessible variables. CPanelAnimationVar( bool, m_bStartFramed, "start_framed", "0" ); CPanelAnimationVar( bool, m_bDisableManipulation, "disable_manipulation", "0" ); - CPanelAnimationVar( bool, m_bUseParticle, "use_particle", "0" ); - CPanelAnimationVar( float, m_flMaxPitch, "max_pitch", "90" ); - - struct particle_data_t - { - ~particle_data_t(); - - void UpdateControlPoints( CStudioHdr *pStudioHdr, matrix3x4_t *pWorldMatrix, const CUtlVector< int >& vecAttachments, int iDefaultBone = 0, const Vector& vecParticleOffset = vec3_origin ); - - bool m_bIsUpdateToDate; - CParticleCollection *m_pParticleSystem; - }; - CUtlVector< particle_data_t* > m_particleList; - - particle_data_t *CreateParticleData( const char *pszParticleName ); - bool SafeDeleteParticleData( particle_data_t **pData ); - - virtual void PrePaint3D( IMatRenderContext *pRenderContext ) OVERRIDE; - virtual void PostPaint3D( IMatRenderContext *pRenderContext ) OVERRIDE; }; #endif // BASEMODEL_PANEL_H \ No newline at end of file diff --git a/game/client/game_controls/baseviewport.cpp b/game/client/game_controls/baseviewport.cpp index 31d8dca2..a0986620 100644 --- a/game/client/game_controls/baseviewport.cpp +++ b/game/client/game_controls/baseviewport.cpp @@ -65,17 +65,7 @@ vgui::Panel *g_lastPanel = NULL; // used for mouseover buttons, keeps track of t vgui::Button *g_lastButton = NULL; // used for mouseover buttons, keeps track of the last active button using namespace vgui; -void hud_autoreloadscript_callback( IConVar *var, const char *pOldValue, float flOldValue ); - -ConVar hud_autoreloadscript("hud_autoreloadscript", "0", FCVAR_NONE, "Automatically reloads the animation script each time one is ran", hud_autoreloadscript_callback); - -void hud_autoreloadscript_callback( IConVar *var, const char *pOldValue, float flOldValue ) -{ - if ( g_pClientMode && g_pClientMode->GetViewportAnimationController() ) - { - g_pClientMode->GetViewportAnimationController()->SetAutoReloadScript( hud_autoreloadscript.GetBool() ); - } -} +ConVar hud_autoreloadscript("hud_autoreloadscript", "0", FCVAR_NONE, "Automatically reloads the animation script each time one is ran"); static ConVar cl_leveloverviewmarker( "cl_leveloverviewmarker", "0", FCVAR_CHEAT ); @@ -156,6 +146,32 @@ bool CBaseViewport::LoadHudAnimations( void ) return true; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Reloads HUD animations after loading a map-specific HUD animations file. +//----------------------------------------------------------------------------- +void CBaseViewport::ReloadHudAnimations( void ) +{ + // Force a reload + if ( LoadHudAnimations() == false ) + { + // Fall back to just the main + if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false ) + { + Assert(0); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Loads a map-specific HUD animations file. +//----------------------------------------------------------------------------- +bool CBaseViewport::LoadCustomHudAnimations( const char *pszFile ) +{ + return m_pAnimController->SetScriptFile( GetVPanel(), pszFile, true ); +} +#endif + //================================================================ CBaseViewport::CBaseViewport() : vgui::EditablePanel( NULL, "CBaseViewport") { @@ -239,11 +255,12 @@ void CBaseViewport::CreateDefaultPanels( void ) AddNewPanel( CreatePanelByName( PANEL_SCOREBOARD ), "PANEL_SCOREBOARD" ); AddNewPanel( CreatePanelByName( PANEL_INFO ), "PANEL_INFO" ); AddNewPanel( CreatePanelByName( PANEL_SPECGUI ), "PANEL_SPECGUI" ); -#if !defined( TF_CLIENT_DLL ) AddNewPanel( CreatePanelByName( PANEL_SPECMENU ), "PANEL_SPECMENU" ); AddNewPanel( CreatePanelByName( PANEL_NAV_PROGRESS ), "PANEL_NAV_PROGRESS" ); -#endif // !TF_CLIENT_DLL -#endif // !_XBOX + // AddNewPanel( CreatePanelByName( PANEL_TEAM ), "PANEL_TEAM" ); + // AddNewPanel( CreatePanelByName( PANEL_CLASS ), "PANEL_CLASS" ); + // AddNewPanel( CreatePanelByName( PANEL_BUY ), "PANEL_BUY" ); +#endif } void CBaseViewport::UpdateAllPanels( void ) @@ -583,12 +600,11 @@ void CBaseViewport::OnThink() else m_pActivePanel = NULL; } - - // TF does this in OnTick in TFViewport. This remains to preserve old - // behavior in other games -#if !defined( TF_CLIENT_DLL ) + m_pAnimController->UpdateAnimations( gpGlobals->curtime ); -#endif + + // check the auto-reload cvar + m_pAnimController->SetAutoReloadScript(hud_autoreloadscript.GetBool()); int count = m_Panels.Count(); diff --git a/game/client/game_controls/baseviewport.h b/game/client/game_controls/baseviewport.h index 4e4c64e8..cbc602a0 100644 --- a/game/client/game_controls/baseviewport.h +++ b/game/client/game_controls/baseviewport.h @@ -73,6 +73,10 @@ class CBaseViewport : public vgui::EditablePanel, public IViewPort, public IGame public: // IGameEventListener: virtual void FireGameEvent( IGameEvent * event); +#ifdef MAPBASE + bool LoadCustomHudAnimations( const char *pszFile ); + void ReloadHudAnimations( void ); +#endif protected: diff --git a/game/client/game_controls/teammenu.cpp b/game/client/game_controls/teammenu.cpp index 6b98afd7..c242c936 100644 --- a/game/client/game_controls/teammenu.cpp +++ b/game/client/game_controls/teammenu.cpp @@ -190,7 +190,6 @@ void CTeamMenu::LoadMapPage( const char *mapName ) char mapRES[ MAX_PATH ]; char uilanguage[ 64 ]; - uilanguage[0] = 0; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_%s.html", mapName, uilanguage ); diff --git a/game/client/game_controls/vguitextwindow.cpp b/game/client/game_controls/vguitextwindow.cpp index 3c25eb80..5cdc2532 100644 --- a/game/client/game_controls/vguitextwindow.cpp +++ b/game/client/game_controls/vguitextwindow.cpp @@ -102,7 +102,11 @@ CTextWindow::CTextWindow(IViewPort *pViewPort) : Frame(NULL, PANEL_INFO ) SetTitleBarVisible( false ); m_pTextMessage = new TextEntry( this, "TextMessage" ); +#if defined( ENABLE_CHROMEHTMLWINDOW ) m_pHTMLMessage = new CMOTDHTML( this,"HTMLMessage" ); +#else + m_pHTMLMessage = NULL; +#endif m_pTitleLabel = new Label( this, "MessageTitle", "Message Title" ); m_pOK = new Button(this, "ok", "#PropertyDialog_OK"); @@ -138,9 +142,9 @@ void CTextWindow::Reset( void ) // HPE_BEGIN: // [Forrest] Replace strange hard-coded default message with hard-coded error message. //============================================================================= - V_strcpy_safe( m_szTitle, "Error loading info message." ); - V_strcpy_safe( m_szMessage, "" ); - V_strcpy_safe( m_szMessageFallback, "" ); + Q_strcpy( m_szTitle, "Error loading info message." ); + Q_strcpy( m_szMessage, "" ); + Q_strcpy( m_szMessageFallback, "" ); //============================================================================= // HPE_END //============================================================================= @@ -161,6 +165,7 @@ void CTextWindow::ShowText( const char *text ) void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable ) { +#if defined( ENABLE_CHROMEHTMLWINDOW ) #ifdef _DEBUG Msg( "CTextWindow::ShowURL( %s )\n", URL ); #endif @@ -191,6 +196,8 @@ void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable ) m_pHTMLMessage->SetVisible( true ); m_pHTMLMessage->OpenURL( URL, NULL ); m_bShownURL = true; + +#endif } void CTextWindow::ShowIndex( const char *entry ) @@ -279,8 +286,9 @@ void CTextWindow::Update( void ) m_pTitleLabel->SetText( m_szTitle ); - if ( m_pHTMLMessage ) - m_pHTMLMessage->SetVisible( false ); +#if defined( ENABLE_CHROMEHTMLWINDOW ) + m_pHTMLMessage->SetVisible( false ); +#endif m_pTextMessage->SetVisible( false ); if ( m_nContentType == TYPE_INDEX ) @@ -419,11 +427,13 @@ void CTextWindow::ShowPanel( bool bShow ) SetVisible( false ); SetMouseInputEnabled( false ); - if ( m_bUnloadOnDismissal && m_bShownURL && m_pHTMLMessage ) +#if defined( ENABLE_CHROMEHTMLWINDOW ) + if ( m_bUnloadOnDismissal && m_bShownURL ) { m_pHTMLMessage->OpenURL( "about:blank", NULL ); m_bShownURL = false; } +#endif } } diff --git a/game/client/glow_outline_effect.h b/game/client/glow_outline_effect.h index aac399d7..11132862 100644 --- a/game/client/glow_outline_effect.h +++ b/game/client/glow_outline_effect.h @@ -150,6 +150,10 @@ class CGlowObjectManager static const int ENTRY_IN_USE = -2; }; +#ifdef MAPBASE_VSCRIPT + // For unregistration boundary check +public: +#endif CUtlVector< GlowObjectDefinition_t > m_GlowObjectDefinitions; int m_nFirstFreeSlot; }; diff --git a/game/client/hl2/c_basehlplayer.cpp b/game/client/hl2/c_basehlplayer.cpp index fbc40eb2..15a33ea8 100644 --- a/game/client/hl2/c_basehlplayer.cpp +++ b/game/client/hl2/c_basehlplayer.cpp @@ -31,6 +31,9 @@ ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDL IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player) RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ), RecvPropBool( RECVINFO( m_fIsSprinting ) ), +#ifdef SP_ANIM_STATE + RecvPropFloat( RECVINFO( m_flAnimRenderYaw ) ), +#endif END_RECV_TABLE() BEGIN_PREDICTION_DATA( C_BaseHLPlayer ) @@ -38,6 +41,11 @@ BEGIN_PREDICTION_DATA( C_BaseHLPlayer ) DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), END_PREDICTION_DATA() +// link to the correct class. +#if !defined ( HL2MP ) && !defined ( PORTAL ) +LINK_ENTITY_TO_CLASS( player, C_BaseHLPlayer ); +#endif + //----------------------------------------------------------------------------- // Purpose: Drops player's primary weapon //----------------------------------------------------------------------------- @@ -66,6 +74,11 @@ C_BaseHLPlayer::C_BaseHLPlayer() m_flZoomRate = 0.0f; m_flZoomStartTime = 0.0f; m_flSpeedMod = cl_forwardspeed.GetFloat(); + +#ifdef MAPBASE + ConVarRef scissor("r_flashlightscissor"); + scissor.SetValue("0"); +#endif } //----------------------------------------------------------------------------- @@ -80,6 +93,13 @@ void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType ) SetNextClientThink( CLIENT_THINK_ALWAYS ); } +#ifdef SP_ANIM_STATE + if (m_flAnimRenderYaw != FLT_MAX) + { + m_angAnimRender = QAngle( 0, m_flAnimRenderYaw, 0 ); + } +#endif + BaseClass::OnDataChanged( updateType ); } @@ -647,3 +667,21 @@ void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quatern BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" ); } + +#ifdef SP_ANIM_STATE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const QAngle& C_BaseHLPlayer::GetRenderAngles( void ) +{ + if ( m_flAnimRenderYaw != FLT_MAX ) + { + return m_angAnimRender; + } + else + { + return BaseClass::GetRenderAngles(); + } +} +#endif + diff --git a/game/client/hl2/c_basehlplayer.h b/game/client/hl2/c_basehlplayer.h index c6507e95..368c9bb1 100644 --- a/game/client/hl2/c_basehlplayer.h +++ b/game/client/hl2/c_basehlplayer.h @@ -5,7 +5,6 @@ // $Workfile: $ // $NoKeywords: $ //=============================================================================// - #if !defined( C_BASEHLPLAYER_H ) #define C_BASEHLPLAYER_H #ifdef _WIN32 @@ -16,6 +15,10 @@ #include "c_baseplayer.h" #include "c_hl2_playerlocaldata.h" +#if !defined( HL2MP ) && defined ( MAPBASE ) +#include "mapbase/singleplayer_animstate.h" +#endif + class C_BaseHLPlayer : public C_BasePlayer { public: @@ -34,10 +37,17 @@ class C_BaseHLPlayer : public C_BasePlayer float GetZoom( void ); bool IsZoomed( void ) { return m_HL2Local.m_bZooming; } - bool IsSprinting( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; } + //Tony; minor cosmetic really, fix confusion by simply renaming this one; everything calls IsSprinting(), and this isn't really even used. + bool IsSprintActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; } bool IsFlashlightActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_FLASHLIGHT; } bool IsBreatherActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_BREATHER; } +#ifdef MAPBASE + bool IsCustomDevice0Active( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_CUSTOM0; } + bool IsCustomDevice1Active( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_CUSTOM1; } + bool IsCustomDevice2Active( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_CUSTOM2; } +#endif + virtual int DrawModel( int flags ); virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ); @@ -52,6 +62,10 @@ class C_BaseHLPlayer : public C_BasePlayer bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; } +#ifdef SP_ANIM_STATE + virtual const QAngle& GetRenderAngles( void ); +#endif + public: C_HL2PlayerLocalData m_HL2Local; @@ -72,7 +86,13 @@ class C_BaseHLPlayer : public C_BasePlayer bool m_bPlayUseDenySound; // Signaled by PlayerUse, but can be unset by HL2 ladder code... float m_flSpeedMod; float m_flExitSpeedMod; - + +#ifdef SP_ANIM_STATE + // At the moment, we network the render angles since almost none of the player anim stuff is done on the client in SP. + // If any of this is ever adapted for MP, this method should be replaced with replicating/moving the anim state to the client. + float m_flAnimRenderYaw; + QAngle m_angAnimRender; +#endif friend class CHL2GameMovement; }; diff --git a/game/client/hl2/c_env_starfield.cpp b/game/client/hl2/c_env_starfield.cpp index 632c6f35..123dc0c1 100644 --- a/game/client/hl2/c_env_starfield.cpp +++ b/game/client/hl2/c_env_starfield.cpp @@ -90,6 +90,11 @@ void C_EnvStarfield::ClientThink( void ) if ( !m_bOn || !m_flDensity ) return; +#ifdef MAPBASE + if ( engine->IsPaused() ) + return; +#endif + PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" ); // Find a start & end point for the particle diff --git a/game/client/hl2/c_script_intro.cpp b/game/client/hl2/c_script_intro.cpp index eb97cb4f..835e0a82 100644 --- a/game/client/hl2/c_script_intro.cpp +++ b/game/client/hl2/c_script_intro.cpp @@ -10,6 +10,9 @@ #include "iviewrender.h" #include "view_shared.h" #include "viewrender.h" +#ifdef MAPBASE +#include "c_point_camera.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -53,6 +56,11 @@ class C_ScriptIntro : public C_BaseEntity float m_flBlendStartTime; bool m_bActive; EHANDLE m_hCameraEntity; +#ifdef MAPBASE + bool m_bDrawSky; + bool m_bDrawSky2; + bool m_bUseEyePosition; +#endif // Fades float m_flFadeColor[3]; // Server's desired fade color @@ -71,6 +79,11 @@ IMPLEMENT_CLIENTCLASS_DT( C_ScriptIntro, DT_ScriptIntro, CScriptIntro ) RecvPropFloat( RECVINFO( m_flNextBlendTime ) ), RecvPropFloat( RECVINFO( m_flBlendStartTime ) ), RecvPropBool( RECVINFO( m_bActive ) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bDrawSky ) ), + RecvPropBool( RECVINFO( m_bDrawSky2 ) ), + RecvPropBool( RECVINFO( m_bUseEyePosition ) ), +#endif // Fov & fov blends RecvPropInt( RECVINFO( m_iFOV ) ), @@ -140,6 +153,10 @@ void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType ) m_IntroData.m_vecCameraViewAngles = m_vecCameraViewAngles; m_IntroData.m_Passes.SetCount( 0 ); +#ifdef MAPBASE + m_IntroData.m_bDrawSky = m_bDrawSky; +#endif + // Find/Create our first pass IntroDataBlendPass_t *pass1; if ( m_IntroData.m_Passes.Count() == 0 ) @@ -161,6 +178,20 @@ void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType ) else { m_IntroData.m_bDrawPrimary = true; +#ifdef MAPBASE + m_IntroData.m_bDrawSky2 = m_bDrawSky2; + + // If it's a point_camera and it's ortho, send it to the intro data + // Change this code if the purpose of m_hCameraEntity in intro data ever goes beyond ortho + if ( m_hCameraEntity && Q_strncmp(m_hCameraEntity->GetClassname(), "point_camera", 12) == 0 ) + { + C_PointCamera *pCamera = dynamic_cast(m_hCameraEntity.Get()); + if (pCamera && pCamera->IsOrtho()) + { + m_IntroData.m_hCameraEntity = m_hCameraEntity; + } + } +#endif } // If we're currently blending to a new mode, set the second pass @@ -239,8 +270,20 @@ void C_ScriptIntro::ClientThink( void ) if ( m_hCameraEntity ) { +#ifdef MAPBASE + if ( m_bUseEyePosition ) + { + m_hCameraEntity->GetEyePosition( m_IntroData.m_vecCameraView, m_IntroData.m_vecCameraViewAngles ); + } + else + { + m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin(); + m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles(); + } +#else m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin(); m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles(); +#endif } CalculateFOV(); @@ -325,3 +368,135 @@ void C_ScriptIntro::CalculateAlpha( void ) m_IntroData.m_flCurrentFadeColor[3] = flNewAlpha; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class C_PlayerViewProxy : public C_BaseEntity +{ + DECLARE_CLASS( C_PlayerViewProxy, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + Vector EyePosition( void ); // position of eyes + const QAngle &EyeAngles( void ); // Direction of eyes in world space + void GetEyePosition( Vector &vecOrigin, QAngle &angAngles ); + const QAngle &LocalEyeAngles( void ); // Direction of eyes + Vector EarPosition( void ); // position of ears + +#ifdef MAPBASE_MP + C_BasePlayer *GetPlayer() { return m_bEnabled ? (m_hPlayer.Get() ? m_hPlayer.Get() : C_BasePlayer::GetLocalPlayer()) : NULL; } +#else + C_BasePlayer *GetPlayer() { return m_bEnabled ? C_BasePlayer::GetLocalPlayer() : NULL; } +#endif + +public: +#ifdef MAPBASE_MP + CHandle m_hPlayer; +#endif + + bool m_bEnabled; +}; + +IMPLEMENT_CLIENTCLASS_DT( C_PlayerViewProxy, DT_PlayerViewProxy, CPlayerViewProxy ) +#ifdef MAPBASE_MP + RecvPropEHandle( RECVINFO( m_hPlayer ) ), +#endif + RecvPropBool( RECVINFO( m_bEnabled ) ), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Vector C_PlayerViewProxy::EyePosition( void ) +{ + C_BasePlayer *pPlayer = GetPlayer(); + if (pPlayer) + { + //Vector vecPlayerOffset = m_hPlayer.Get()->EyePosition() - m_hPlayer.Get()->GetAbsOrigin(); + //return GetAbsOrigin() + vecPlayerOffset; + + Vector vecOrigin; + QAngle angAngles; + float fldummy; + pPlayer->CalcView( vecOrigin, angAngles, fldummy, fldummy, fldummy ); + + return GetAbsOrigin() + (vecOrigin - pPlayer->GetAbsOrigin()); + } + else + return BaseClass::EyePosition(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const QAngle &C_PlayerViewProxy::EyeAngles( void ) +{ + C_BasePlayer *pPlayer = GetPlayer(); + if (pPlayer) + { + Vector vecOrigin; + static QAngle angAngles; + float fldummy; + pPlayer->CalcView( vecOrigin, angAngles, fldummy, fldummy, fldummy ); + + angAngles = GetAbsAngles() + (angAngles - pPlayer->GetAbsAngles()); + return angAngles; + + //return m_hPlayer.Get()->EyeAngles(); + } + else + return BaseClass::EyeAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PlayerViewProxy::GetEyePosition( Vector &vecOrigin, QAngle &angAngles ) +{ + C_BasePlayer *pPlayer = GetPlayer(); + if (pPlayer) + { + float fldummy; + pPlayer->CalcView( vecOrigin, angAngles, fldummy, fldummy, fldummy ); + + vecOrigin = GetAbsOrigin() + (vecOrigin - pPlayer->GetAbsOrigin()); + angAngles = GetAbsAngles() + (angAngles - pPlayer->GetAbsAngles()); + } + else + { + BaseClass::GetEyePosition( vecOrigin, angAngles ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const QAngle &C_PlayerViewProxy::LocalEyeAngles( void ) +{ + C_BasePlayer *pPlayer = GetPlayer(); + if (pPlayer) { + static QAngle angAngles; + angAngles = GetAbsAngles() + (pPlayer->LocalEyeAngles() - pPlayer->GetAbsAngles()); + return angAngles; + } + else + return BaseClass::LocalEyeAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Vector C_PlayerViewProxy::EarPosition( void ) +{ + C_BasePlayer *pPlayer = GetPlayer(); + if (pPlayer) + { + Vector vecPlayerOffset = pPlayer->GetAbsOrigin() - pPlayer->EarPosition(); + return GetAbsOrigin() + vecPlayerOffset; + } + else + return BaseClass::EarPosition(); +} +#endif + diff --git a/game/client/hl2/c_waterbullet.cpp b/game/client/hl2/c_waterbullet.cpp index c758069d..b4491ca1 100644 --- a/game/client/hl2/c_waterbullet.cpp +++ b/game/client/hl2/c_waterbullet.cpp @@ -85,7 +85,7 @@ class C_WaterBullet : public C_BaseAnimating sParticle->m_flDieTime = 0.2f; sParticle->m_flRoll = random->RandomInt( 0, 360 ); - sParticle->m_flRollDelta = random->RandomInt( -4, 4 ); + sParticle->m_flRollDelta = random->RandomInt( -4, 4 );; unsigned char color = random->RandomInt( 200, 255 ); diff --git a/game/client/hl2/c_weapon__stubs_hl2.cpp b/game/client/hl2/c_weapon__stubs_hl2.cpp index 2b117dcc..1f21bd25 100644 --- a/game/client/hl2/c_weapon__stubs_hl2.cpp +++ b/game/client/hl2/c_weapon__stubs_hl2.cpp @@ -33,7 +33,9 @@ STUB_WEAPON_CLASS( weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon ); STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun ); STUB_WEAPON_CLASS( weapon_357, Weapon357, C_BaseHLCombatWeapon ); STUB_WEAPON_CLASS( weapon_crossbow, WeaponCrossbow, C_BaseHLCombatWeapon ); +#ifndef MAPBASE STUB_WEAPON_CLASS( weapon_slam, Weapon_SLAM, C_BaseHLCombatWeapon ); +#endif STUB_WEAPON_CLASS( weapon_crowbar, WeaponCrowbar, C_BaseHLBludgeonWeapon ); #ifdef HL2_EPISODIC STUB_WEAPON_CLASS( weapon_hopwire, WeaponHopwire, C_BaseHLCombatWeapon ); diff --git a/game/client/hl2/hud_autoaim.cpp b/game/client/hl2/hud_autoaim.cpp index aa808acf..9520dc3e 100644 --- a/game/client/hl2/hud_autoaim.cpp +++ b/game/client/hl2/hud_autoaim.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -32,7 +32,7 @@ ConVar hud_reticle_maxalpha( "hud_reticle_maxalpha", "255" ); ConVar hud_alpha_speed("hud_reticle_alpha_speed", "700" ); ConVar hud_magnetism("hud_magnetism", "0.3" ); -enum +enum { AUTOAIM_METHOD_RETICLE = 1, AUTOAIM_METHOD_DRIFT, @@ -57,7 +57,7 @@ class CHUDAutoAim : public CHudElement, public vgui::Panel private: void ResetAlpha() { m_alpha = 0; } void ResetScale() { m_scale = 1.0f; } - + void ResetPosition() { m_vecPos.x = ScreenWidth() / 2; @@ -141,11 +141,11 @@ void CHUDAutoAim::VidInit( void ) //----------------------------------------------------------------------------- // Purpose: Save CPU cycles by letting the HUD system early cull -// costly traversal. Called per frame, return true if thinking and +// costly traversal. Called per frame, return true if thinking and // painting need to occur. //----------------------------------------------------------------------------- bool CHUDAutoAim::ShouldDraw( void ) -{ +{ #ifndef HL1_CLIENT_DLL C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pLocalPlayer ) @@ -165,7 +165,7 @@ bool CHUDAutoAim::ShouldDraw( void ) #define AUTOAIM_MAX_ALPHA 120 #define AUTOAIM_MAX_SCALE 1.0f #define AUTOAIM_MIN_SCALE 0.5f -#define AUTOAIM_SCALE_SPEED 10.0f +#define AUTOAIM_SCALE_SPEED 10.0f #define AUTOAIM_ONTARGET_CROSSHAIR_SPEED (ScreenWidth() / 3) // Can cross the whole screen in 3 seconds. #define AUTOAIM_OFFTARGET_CROSSHAIR_SPEED (ScreenWidth() / 4) @@ -210,7 +210,7 @@ void CHUDAutoAim::OnThink() } m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) ); - + switch( hud_autoaim_method.GetInt() ) { @@ -254,7 +254,7 @@ void CHUDAutoAim::OnThink() #if 0 bool doScaling = hud_autoaim_scale_icon.GetBool(); - // These are the X & Y coords of where the crosshair should be. Default to + // These are the X & Y coords of where the crosshair should be. Default to // returning to the center of the screen if there is no target. int goalx = ScreenWidth() / 2; int goaly = ScreenHeight() / 2; @@ -318,7 +318,7 @@ void CHUDAutoAim::OnThink() Vector vecGoal( goalx, goaly, 0 ); Vector vecDir = vecGoal - m_vecPos; float flDistRemaining = VectorNormalize( vecDir ); - m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) ); + m_vecPos += vecDir * MIN(flDistRemaining, (speed * gpGlobals->frametime) ); // Lerp and Clamp scale float scaleDelta = fabs( goalscale - m_scale ); @@ -369,7 +369,7 @@ void CHUDAutoAim::OnThink() QAngle viewangles; engine->GetViewAngles( viewangles ); - + Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition(); VectorNormalize(vecDir); @@ -399,7 +399,7 @@ void CHUDAutoAim::Paint() float uv1 = 0.5f / width, uv2 = 1.0f - uv1; - vgui::Vertex_t vert[4]; + vgui::Vertex_t vert[4]; Vector2D uv11( uv1, uv1 ); Vector2D uv12( uv1, uv2 ); @@ -433,7 +433,7 @@ void CHUDAutoAim::Paint() int xCenter = ScreenWidth() / 2; int yCenter = ScreenHeight() / 2; - vgui::Vertex_t vert[4]; + vgui::Vertex_t vert[4]; Vector2D uv11( 0, 0 ); Vector2D uv12( 0, 1 ); @@ -459,7 +459,7 @@ void CHUDAutoAim::Paint() C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if( pLocalPlayer && pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() ) { - r = 250; + r = 250; g = 138; b = 4; } @@ -469,4 +469,4 @@ void CHUDAutoAim::Paint() vgui::surface()->DrawSetColor( clr ); vgui::surface()->DrawTexturedPolygon( 4, vert ); } -} \ No newline at end of file +} diff --git a/game/client/hl2/hud_credits.cpp b/game/client/hl2/hud_credits.cpp index 6ad1488b..fb4354f5 100644 --- a/game/client/hl2/hud_credits.cpp +++ b/game/client/hl2/hud_credits.cpp @@ -32,6 +32,16 @@ struct creditname_t float flTimeAdd; float flTimeStart; int iSlot; + +#ifdef MAPBASE + // New credits stuff + + Color cColorOverride; + + // Images + int iImageID = -1; + float flImageScale = 1.0f; +#endif }; #define CREDITS_FILE "scripts/credits.txt" @@ -47,6 +57,9 @@ enum #define CREDITS_LOGO 1 #define CREDITS_INTRO 2 #define CREDITS_OUTRO 3 +#ifdef MAPBASE +#define CREDITS_PRECACHE 4 +#endif bool g_bRollingCredits = false; @@ -93,15 +106,27 @@ class CHudCredits : public CHudElement, public vgui::Panel void DrawOutroCreditsName( void ); void DrawIntroCreditsName( void ); void DrawLogo( void ); +#ifdef MAPBASE + void DrawOutroCreditFont( const char *pCreditName, float flYPos, vgui::HFont hTFont, const Color &cColor, int iScreenWidth, int iDivisor = 2 ); + void DrawOutroCreditTexture( int iImageID, float flYPos, float flImageScale, const Color &cColor, int iScreenWidth, int iDivisor = 2 ); +#endif void PrepareLogo( float flTime ); void PrepareOutroCredits( void ); void PrepareIntroCredits( void ); +#ifdef MAPBASE + void PrecacheCredits(); +#endif + float FadeBlend( float fadein, float fadeout, float hold, float localTime ); void PrepareLine( vgui::HFont hFont, char const *pchLine ); +#ifdef MAPBASE + int GetOrAllocateImageID( const char *szFileName ); +#endif + CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" ); CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" ); @@ -109,6 +134,12 @@ class CHudCredits : public CHudElement, public vgui::Panel float m_flScrollTime; float m_flSeparation; +#ifdef MAPBASE + int m_iEndLines; + float m_flEndLinesFadeHoldTime; + bool m_bAllowColumns; + CUtlDict m_ImageDict; +#endif float m_flFadeTime; bool m_bLastOneInPlace; int m_Alpha; @@ -133,6 +164,15 @@ class CHudCredits : public CHudElement, public vgui::Panel char m_szLogo2[256]; Color m_cColor; + +#ifdef MAPBASE + char m_szCreditsFile[MAX_PATH]; + + char m_szLogoFont[64]; + char m_szLogo2Font[64]; + Color m_cLogoColor; + Color m_cLogo2Color; +#endif }; @@ -141,7 +181,11 @@ void CHudCredits::PrepareCredits( const char *pKeyName ) Clear(); KeyValues *pKV= new KeyValues( "CreditsFile" ); +#ifdef MAPBASE + if ( !pKV->LoadFromFile( filesystem, m_szCreditsFile, "MOD" ) ) +#else if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE, "MOD" ) ) +#endif { pKV->deleteThis(); @@ -189,6 +233,20 @@ void CHudCredits::Clear( void ) m_bLastOneInPlace = false; m_Alpha = m_TextColor[3]; m_iLogoState = LOGO_FADEOFF; + +#ifdef MAPBASE + if ( surface() ) + { + for (int i = m_ImageDict.Count()-1; i >= 0; i--) + { + if (m_ImageDict[i] != -1) + { + surface()->DestroyTextureID( m_ImageDict[i] ); + m_ImageDict.RemoveAt( i ); + } + } + } +#endif } //----------------------------------------------------------------------------- @@ -216,7 +274,11 @@ void CHudCredits::ReadNames( KeyValues *pKeyValue ) { creditname_t Credits; V_strcpy_safe( Credits.szCreditName, pKVNames->GetName() ); +#ifdef MAPBASE + V_strcpy_safe( Credits.szFontName, pKVNames->GetString( (const char *)NULL, "Default" ) ); +#else V_strcpy_safe( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) ); +#endif m_CreditsList.AddToTail( Credits ); pKVNames = pKVNames->GetNextKey(); @@ -233,6 +295,11 @@ void CHudCredits::ReadParams( KeyValues *pKeyValue ) m_flScrollTime = pKeyValue->GetFloat( "scrolltime", 57 ); m_flSeparation = pKeyValue->GetFloat( "separation", 5 ); +#ifdef MAPBASE + m_iEndLines = pKeyValue->GetInt( "endlines", 1 ); + m_flEndLinesFadeHoldTime = pKeyValue->GetFloat( "endlines_fadeholdtime", ( IsConsole() ? 2.0f : 10.0f ) ); // "360 certification requires that we not hold a static image too long." + m_bAllowColumns = pKeyValue->GetBool( "allow_columns", false ); +#endif m_flFadeInTime = pKeyValue->GetFloat( "fadeintime", 1 ); m_flFadeHoldTime = pKeyValue->GetFloat( "fadeholdtime", 3 ); @@ -249,6 +316,14 @@ void CHudCredits::ReadParams( KeyValues *pKeyValue ) Q_strncpy( m_szLogo, pKeyValue->GetString( "logo", "HALF-LIFE'" ), sizeof( m_szLogo ) ); Q_strncpy( m_szLogo2, pKeyValue->GetString( "logo2", "" ), sizeof( m_szLogo2 ) ); + +#ifdef MAPBASE + Q_strncpy( m_szLogoFont, pKeyValue->GetString( "logofont", "" ), sizeof( m_szLogoFont ) ); + Q_strncpy( m_szLogo2Font, pKeyValue->GetString( "logo2font", "" ), sizeof( m_szLogo2Font ) ); + + m_cLogoColor = pKeyValue->GetColor( "logocolor" ); + m_cLogo2Color = pKeyValue->GetColor( "logo2color" ); +#endif } int CHudCredits::GetStringPixelWidth( wchar_t *pString, vgui::HFont hFont ) @@ -280,10 +355,46 @@ void CHudCredits::DrawOutroCreditsName( void ) if ( pCredit == NULL ) continue; +#ifdef MAPBASE + vgui::HScheme scheme = GetScheme(); +#else vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true ); +#endif + vgui::HFont m_hTFont = INVALID_FONT; - int iFontTall = surface()->GetFontTall ( m_hTFont ); + int iFontTall = 1; + +#ifdef MAPBASE + if (pCredit->iImageID != -1) + { + // Get the size of the tallest image if there's multiple + int iFontWide; + if (m_bAllowColumns && V_strstr( pCredit->szCreditName, "\t" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szCreditName, "\t", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + int iTempTall; + surface()->DrawGetTextureSize( GetOrAllocateImageID( outStrings[i] ), iFontWide, iTempTall ); + if (iTempTall > iFontTall) + iFontTall = iTempTall; + } + outStrings.PurgeAndDeleteElements(); + } + else + { + surface()->DrawGetTextureSize( GetOrAllocateImageID( pCredit->szCreditName ), iFontWide, iFontTall ); + } + + iFontTall = ((float)iFontTall * pCredit->flImageScale); + } + else +#endif + { + m_hTFont = vgui::scheme()->GetIScheme( scheme )->GetFont( pCredit->szFontName, true ); + iFontTall = surface()->GetFontTall( m_hTFont ); + } if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall ) { @@ -296,9 +407,17 @@ void CHudCredits::DrawOutroCreditsName( void ) Color cColor = m_TextColor; +#ifdef MAPBASE + if (pCredit->cColorOverride.a() > 0) + cColor = pCredit->cColorOverride; + + // Some lines should stick around and fade out + if ( i >= m_CreditsList.Count()-m_iEndLines ) +#else //HACKHACK //Last one stays on screen and fades out if ( i == m_CreditsList.Count()-1 ) +#endif { if ( m_bLastOneInPlace == false ) { @@ -308,8 +427,12 @@ void CHudCredits::DrawOutroCreditsName( void ) { m_bLastOneInPlace = true; +#ifdef MAPBASE + m_flFadeTime = gpGlobals->curtime + m_flEndLinesFadeHoldTime; +#else // 360 certification requires that we not hold a static image too long. m_flFadeTime = gpGlobals->curtime + ( IsConsole() ? 2.0f : 10.0f ); +#endif } } else @@ -339,6 +462,50 @@ void CHudCredits::DrawOutroCreditsName( void ) if ( pCredit->bActive == false ) continue; +#ifdef MAPBASE + // Credits separated by tabs should appear divided + if (m_bAllowColumns && V_strstr( pCredit->szCreditName, "\t" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szCreditName, "\t", outStrings ); + int iDivisor = 1 + outStrings.Count(); + if (pCredit->iImageID != -1) + { + FOR_EACH_VEC( outStrings, i ) + { + int iImageID = GetOrAllocateImageID( outStrings[i] ); + + // Center the image if needed + int iImageWide, iImageTall = 1; + surface()->DrawGetTextureSize( iImageID, iImageWide, iImageTall ); + if (iImageTall < iFontTall) + { + DrawOutroCreditTexture( iImageID, pCredit->flYPos + ((iFontTall * 0.5f) - (iImageTall * 0.5f)), pCredit->flImageScale, cColor, iWidth*(i + 1), iDivisor ); + } + else + { + DrawOutroCreditTexture( iImageID, pCredit->flYPos, pCredit->flImageScale, cColor, iWidth*(i + 1), iDivisor ); + } + } + } + else + { + FOR_EACH_VEC( outStrings, i ) + { + DrawOutroCreditFont( outStrings[i], pCredit->flYPos, m_hTFont, cColor, iWidth*(i + 1), iDivisor ); + } + } + outStrings.PurgeAndDeleteElements(); + } + else if (pCredit->iImageID != -1) + { + DrawOutroCreditTexture( pCredit->iImageID, pCredit->flYPos, pCredit->flImageScale, cColor, iWidth, 2 ); + } + else + { + DrawOutroCreditFont( pCredit->szCreditName, pCredit->flYPos, m_hTFont, cColor, iWidth, 2 ); + } +#else surface()->DrawSetTextFont( m_hTFont ); surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] ); @@ -357,9 +524,56 @@ void CHudCredits::DrawOutroCreditsName( void ) surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos ); surface()->DrawUnicodeString( unicode ); +#endif } } +#ifdef MAPBASE +void CHudCredits::DrawOutroCreditFont( const char *pCreditName, float flYPos, vgui::HFont hTFont, const Color &cColor, int iScreenWidth, int iDivisor ) +{ + surface()->DrawSetTextFont( hTFont ); + surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] ); + + wchar_t unicode[256]; + + if ( pCreditName[0] == '#' ) + { + g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pCreditName), 0 ); + } + else + { + g_pVGuiLocalize->ConvertANSIToUnicode( pCreditName, unicode, sizeof( unicode ) ); + } + + int iStringWidth = GetStringPixelWidth( unicode, hTFont ); + + // ((iScreenWidth*iMultiplier) / iDivisor) + // When needed, just multiply iScreenWidth before sending to the function + surface()->DrawSetTextPos( (iScreenWidth / iDivisor) - (iStringWidth / 2), flYPos ); + surface()->DrawUnicodeString( unicode ); +} + +void CHudCredits::DrawOutroCreditTexture( int iImageID, float flYPos, float flImageScale, const Color &cColor, int iScreenWidth, int iDivisor ) +{ + int iImageWide, iImageTall; + surface()->DrawGetTextureSize( iImageID, iImageWide, iImageTall ); + + // Scale for resolution + flImageScale *= ((float)GetTall() / 900.0f); + + iImageWide = ((float)(iImageWide) * flImageScale); + iImageTall = ((float)(iImageTall) * flImageScale); + + iImageWide /= 2; + //iImageTall /= 2; + iScreenWidth /= iDivisor; + + surface()->DrawSetColor( cColor ); + surface()->DrawSetTexture( iImageID ); + surface()->DrawTexturedRect( iScreenWidth - iImageWide, flYPos, iScreenWidth + iImageWide, flYPos + iImageTall ); +} +#endif + void CHudCredits::DrawLogo( void ) { if( m_iLogoState == LOGO_FADEOFF ) @@ -418,6 +632,14 @@ void CHudCredits::DrawLogo( void ) char szLogoFont[64]; +#ifdef MAPBASE + if (m_szLogoFont[0] != '\0') + { + // Custom logo font + Q_strncpy( szLogoFont, m_szLogoFont, sizeof( szLogoFont ) ); + } + else +#endif if ( IsXbox() ) { Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons_Small" ); @@ -431,13 +653,22 @@ void CHudCredits::DrawLogo( void ) Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons" ); } +#ifdef MAPBASE + vgui::HScheme scheme = GetScheme(); +#else vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); +#endif vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( szLogoFont ); int iFontTall = surface()->GetFontTall ( m_hTFont ); Color cColor = m_TextColor; cColor[3] = m_Alpha; + +#ifdef MAPBASE + if (m_cLogoColor.a() > 0) + cColor = m_cLogoColor; +#endif surface()->DrawSetTextFont( m_hTFont ); surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] ); @@ -452,6 +683,19 @@ void CHudCredits::DrawLogo( void ) if ( Q_strlen( m_szLogo2 ) > 0 ) { +#ifdef MAPBASE + if (m_szLogo2Font[0] != '\0') + { + m_hTFont = vgui::scheme()->GetIScheme( scheme )->GetFont( m_szLogo2Font ); + iFontTall = surface()->GetFontTall( m_hTFont ); + surface()->DrawSetTextFont( m_hTFont ); + } + if (m_cLogo2Color.a() > 0) + { + surface()->DrawSetTextColor( m_cLogo2Color[0], m_cLogo2Color[1], m_cLogo2Color[2], m_cLogo2Color[3] ); + } +#endif + g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo2, unicode, sizeof( unicode ) ); iStringWidth = GetStringPixelWidth( unicode, m_hTFont ); @@ -511,14 +755,26 @@ void CHudCredits::DrawIntroCreditsName( void ) if ( pCredit->bActive == false ) continue; - + +#ifdef MAPBASE + vgui::HScheme scheme = GetScheme(); +#else vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); +#endif vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName ); float localTime = gpGlobals->curtime - pCredit->flTimeStart; surface()->DrawSetTextFont( m_hTFont ); +#ifdef MAPBASE + Color cColor = m_cColor; + if (pCredit->cColorOverride.a() > 0) + cColor = pCredit->cColorOverride; + + surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * cColor[3] ); +#else surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * m_cColor[3] ); +#endif wchar_t unicode[256]; g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) ); @@ -638,6 +894,20 @@ void CHudCredits::PrepareOutroCredits( void ) int iHeight = iTall; +#ifdef MAPBASE + if (m_iEndLines <= 0) + { + // We need a credit to fade out at the end so we know when the credits are done. + // Add a dummy credit to act as the "end line". + creditname_t DummyCredit; + V_strcpy_safe( DummyCredit.szCreditName, ""); + V_strcpy_safe( DummyCredit.szFontName, "Default" ); + + m_CreditsList.AddToTail(DummyCredit); + m_iEndLines = 1; + } +#endif + for ( int i = 0; i < m_CreditsList.Count(); i++ ) { creditname_t *pCredit = &m_CreditsList[i]; @@ -645,17 +915,119 @@ void CHudCredits::PrepareOutroCredits( void ) if ( pCredit == NULL ) continue; +#ifdef MAPBASE + vgui::HScheme scheme = GetScheme(); +#else vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true ); +#endif - pCredit->flYPos = iHeight; - pCredit->bActive = false; +#ifdef MAPBASE + if (pCredit->szFontName[0] == '$') + { + if (V_strncmp( pCredit->szFontName + 1, "Image", 5 ) == 0) + { + if (pCredit->szFontName[6] == ';') + { + CUtlStringList outStrings; + V_SplitString( pCredit->szFontName, ";", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + switch (i) + { + // Get scale + case 1: + pCredit->flImageScale = atof( outStrings[i] ); + break; + + // Get color + case 2: + int tmp[4]; + UTIL_StringToIntArray( tmp, 4, outStrings[i] ); + pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] ); + break; + } + } + outStrings.PurgeAndDeleteElements(); + } - iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation; + // Get the size of the tallest image if there's multiple + int iFontWide, iFontTall = 1; + if (m_bAllowColumns && V_strstr( pCredit->szCreditName, "\t" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szCreditName, "\t", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + pCredit->iImageID = GetOrAllocateImageID( outStrings[i] ); - PrepareLine( m_hTFont, pCredit->szCreditName ); + int iTempTall; + surface()->DrawGetTextureSize( pCredit->iImageID, iFontWide, iTempTall ); + if (iTempTall > iFontTall) + iFontTall = iTempTall; + } + outStrings.PurgeAndDeleteElements(); + } + else + { + pCredit->iImageID = GetOrAllocateImageID( pCredit->szCreditName ); + surface()->DrawGetTextureSize( pCredit->iImageID, iFontWide, iFontTall ); + } + + pCredit->flYPos = iHeight; + pCredit->bActive = false; + + iHeight += ((float)iFontTall * pCredit->flImageScale * ((float)GetTall() / 900.0f)) + m_flSeparation; + + //Msg( "'%s' is image type (image scale is %f)\n", pCredit->szCreditName, pCredit->flImageScale ); + } + else + { + //Msg( "'%s' is not an image type\n", pCredit->szFontName + 1 ); + } + } + else +#endif + { +#ifdef MAPBASE + if (V_strstr( pCredit->szFontName, ";" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szFontName, ";", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + switch (i) + { + // Get color + case 1: + int tmp[4]; + UTIL_StringToIntArray( tmp, 4, outStrings[i] ); + pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] ); + break; + } + } + + Q_strncpy( pCredit->szFontName, outStrings[0], sizeof( pCredit->szFontName ) ); + outStrings.PurgeAndDeleteElements(); + } +#endif + + vgui::HFont m_hTFont = vgui::scheme()->GetIScheme( scheme )->GetFont( pCredit->szFontName, true ); + + pCredit->flYPos = iHeight; + pCredit->bActive = false; + + iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation; + + PrepareLine( m_hTFont, pCredit->szCreditName ); + } } +#ifdef MAPBASE + // Check if the last line has a color override. If it does, use that as the alpha for the fadeout + if (m_CreditsList.Tail().cColorOverride.a() != 0) + m_Alpha = m_CreditsList.Tail().cColorOverride.a(); +#endif + SetActive( true ); g_iCreditsPixelHeight = iHeight; @@ -674,7 +1046,34 @@ void CHudCredits::PrepareIntroCredits( void ) if ( pCredit == NULL ) continue; +#ifdef MAPBASE + if (V_strstr( pCredit->szFontName, ";" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szFontName, ";", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + switch (i) + { + // Get color + case 1: + int tmp[4]; + UTIL_StringToIntArray( tmp, 4, outStrings[i] ); + pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] ); + break; + } + } + + Q_strncpy( pCredit->szFontName, outStrings[0], sizeof( pCredit->szFontName ) ); + outStrings.PurgeAndDeleteElements(); + } +#endif + +#ifdef MAPBASE + vgui::HScheme scheme = GetScheme(); +#else vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); +#endif vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName ); pCredit->flYPos = m_flY + ( iSlot * surface()->GetFontTall ( m_hTFont ) ); @@ -702,10 +1101,75 @@ void CHudCredits::PrepareIntroCredits( void ) SetActive( true ); } +#ifdef MAPBASE +void CHudCredits::PrecacheCredits() +{ + PrepareCredits( "OutroCreditsNames" ); + + if ( m_CreditsList.Count() == 0 ) + return; + + for ( int i = 0; i < m_CreditsList.Count(); i++ ) + { + creditname_t *pCredit = &m_CreditsList[i]; + + if ( pCredit == NULL ) + continue; + + if (pCredit->szFontName[0] == '$') + { + if (V_strncmp( pCredit->szFontName + 1, "Image", 5 ) == 0) + { + if (m_bAllowColumns && V_strstr( pCredit->szCreditName, "\t" )) + { + CUtlStringList outStrings; + V_SplitString( pCredit->szCreditName, "\t", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + GetOrAllocateImageID( outStrings[i] ); + } + outStrings.PurgeAndDeleteElements(); + } + else + { + GetOrAllocateImageID( pCredit->szCreditName ); + } + } + else + { + //Msg( "'%s' is not an image type\n", pCredit->szFontName + 1 ); + } + } + } + + m_CreditsList.RemoveAll(); +} + +int CHudCredits::GetOrAllocateImageID( const char *szFileName ) +{ + int iIndex = m_ImageDict.Find( szFileName ); + if (iIndex == m_ImageDict.InvalidIndex()) + { + iIndex = surface()->CreateNewTextureID(); + m_ImageDict.Insert( szFileName, iIndex ); + surface()->DrawSetTextureFile( iIndex, szFileName, true, false ); + return iIndex; + } + return m_ImageDict[iIndex]; +} +#endif + void CHudCredits::MsgFunc_CreditsMsg( bf_read &msg ) { m_iCreditsType = msg.ReadByte(); +#ifdef MAPBASE + msg.ReadString(m_szCreditsFile, sizeof(m_szCreditsFile)); + + if (m_szCreditsFile[0] == '\0') + Q_strncpy(m_szCreditsFile, CREDITS_FILE, sizeof(m_szCreditsFile)); +#endif + switch ( m_iCreditsType ) { case CREDITS_LOGO: @@ -723,13 +1187,30 @@ void CHudCredits::MsgFunc_CreditsMsg( bf_read &msg ) PrepareOutroCredits(); break; } +#ifdef MAPBASE + case CREDITS_PRECACHE: + { + PrecacheCredits(); + break; + } +#endif } } void CHudCredits::MsgFunc_LogoTimeMsg( bf_read &msg ) { m_iCreditsType = CREDITS_LOGO; +#ifdef MAPBASE + float flLogoTime = msg.ReadFloat(); + msg.ReadString(m_szCreditsFile, sizeof(m_szCreditsFile)); + + if (m_szCreditsFile[0] == '\0') + Q_strncpy(m_szCreditsFile, CREDITS_FILE, sizeof(m_szCreditsFile)); + + PrepareLogo(flLogoTime); +#else PrepareLogo( msg.ReadFloat() ); +#endif } diff --git a/game/client/hl2/hud_damageindicator.cpp b/game/client/hl2/hud_damageindicator.cpp index 9de538a0..48dd9b62 100644 --- a/game/client/hl2/hud_damageindicator.cpp +++ b/game/client/hl2/hud_damageindicator.cpp @@ -178,7 +178,7 @@ void CHudDamageIndicator::DrawDamageIndicator(int side) int x1 = m_flDmgX; int x2 = m_flDmgX + m_flDmgWide; - int y[4] = { (int)m_flDmgY, (int)(m_flDmgY + insetY), (int)(m_flDmgY + m_flDmgTall1 - insetY), (int)(m_flDmgY + m_flDmgTall1) }; + int y[4] = { m_flDmgY, m_flDmgY + insetY, m_flDmgY + m_flDmgTall1 - insetY, m_flDmgY + m_flDmgTall1 }; int alpha[4] = { 0.0f, 1.0f, 1.0f, 0.0f }; // see if we're high damage diff --git a/game/client/hl2/hud_quickinfo.cpp b/game/client/hl2/hud_quickinfo.cpp index 4ec56a2f..37db4c31 100644 --- a/game/client/hl2/hud_quickinfo.cpp +++ b/game/client/hl2/hud_quickinfo.cpp @@ -98,10 +98,6 @@ CHUDQuickInfo::CHUDQuickInfo( const char *pElementName ) : SetParent( pParent ); SetHiddenBits( HIDEHUD_CROSSHAIR ); - -#ifdef VANCE - SetHiddenBits( HIDEHUD_NEEDSUIT ); -#endif } void CHUDQuickInfo::ApplySchemeSettings( IScheme *scheme ) @@ -306,10 +302,8 @@ void CHUDQuickInfo::Paint() m_ammoFade = 255; m_warnAmmo = true; -#ifndef VANCE // Uses clip-based ticking ala CS:GO. CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowAmmo" ); -#endif } } else diff --git a/game/client/hl2/hud_suitpower.cpp b/game/client/hl2/hud_suitpower.cpp index 416c9300..f1af00ac 100644 --- a/game/client/hl2/hud_suitpower.cpp +++ b/game/client/hl2/hud_suitpower.cpp @@ -104,12 +104,27 @@ void CHudSuitPower::OnThink( void ) bool breatherActive = pPlayer->IsBreatherActive(); int activeDevices = (int)flashlightActive + (int)sprintActive + (int)breatherActive; +#ifdef MAPBASE + activeDevices += (int)pPlayer->IsCustomDevice0Active() + (int)pPlayer->IsCustomDevice1Active() + (int)pPlayer->IsCustomDevice2Active(); +#endif + if (activeDevices != m_iActiveSuitDevices) { m_iActiveSuitDevices = activeDevices; switch ( m_iActiveSuitDevices ) { +#ifdef MAPBASE + case 6: + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerSixItemsActive"); + break; + case 5: + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerFiveItemsActive"); + break; + case 4: + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerFourItemsActive"); + break; +#endif default: case 3: g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerThreeItemsActive"); @@ -251,6 +266,59 @@ void CHudSuitPower::Paint() } ypos += text2_gap; } + +#ifdef MAPBASE + if (pPlayer->IsCustomDevice0Active()) + { + tempString = g_pVGuiLocalize->Find("#Mapbase_Hud_DEVICE0"); + + surface()->DrawSetTextPos(text2_xpos, ypos); + + if (tempString) + { + surface()->DrawPrintText(tempString, wcslen(tempString)); + } + else + { + surface()->DrawPrintText(L"CUSTOM 0", wcslen(L"CUSTOM 0")); + } + ypos += text2_gap; + } + + if (pPlayer->IsCustomDevice1Active()) + { + tempString = g_pVGuiLocalize->Find("#Mapbase_Hud_DEVICE1"); + + surface()->DrawSetTextPos(text2_xpos, ypos); + + if (tempString) + { + surface()->DrawPrintText(tempString, wcslen(tempString)); + } + else + { + surface()->DrawPrintText(L"CUSTOM 1", wcslen(L"CUSTOM 1")); + } + ypos += text2_gap; + } + + if (pPlayer->IsCustomDevice2Active()) + { + tempString = g_pVGuiLocalize->Find("#Mapbase_Hud_DEVICE2"); + + surface()->DrawSetTextPos(text2_xpos, ypos); + + if (tempString) + { + surface()->DrawPrintText(tempString, wcslen(tempString)); + } + else + { + surface()->DrawPrintText(L"CUSTOM 2", wcslen(L"CUSTOM 2")); + } + ypos += text2_gap; + } +#endif } } diff --git a/game/client/hl2/hud_weaponselection.cpp b/game/client/hl2/hud_weaponselection.cpp index f5600705..3754c729 100644 --- a/game/client/hl2/hud_weaponselection.cpp +++ b/game/client/hl2/hud_weaponselection.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -60,7 +60,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void SelectWeaponSlot( int iSlot ); virtual C_BaseCombatWeapon *GetSelectedWeapon( void ) - { + { return m_hSelectedWeapon; } @@ -75,7 +75,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void ApplySchemeSettings(vgui::IScheme *pScheme); virtual bool IsWeaponSelectable() - { + { if (IsInSelectionMode()) return true; @@ -110,17 +110,17 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel void ActivateWeaponHighlight( C_BaseCombatWeapon *pWeapon ); float GetWeaponBoxAlpha( bool bSelected ); int GetLastPosInSlot( int iSlot ) const; - + void FastWeaponSwitch( int iWeaponSlot ); void PlusTypeFastWeaponSwitch( int iWeaponSlot ); - virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) - { + virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) + { m_hSelectedWeapon = pWeapon; } - virtual void SetSelectedSlot( int slot ) - { + virtual void SetSelectedSlot( int slot ) + { m_iSelectedSlot = slot; } @@ -271,7 +271,7 @@ bool CHudWeaponSelection::ShouldDraw() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CHudWeaponSelection::LevelInit() { @@ -464,7 +464,7 @@ void CHudWeaponSelection::Paint() // interpolate the selected box size between the small box size and the large box size // interpolation has been removed since there is no weapon pickup animation anymore, so it's all at the largest size - float percentageDone = 1.0f; //min(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); + float percentageDone = 1.0f; //MIN(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); int largeBoxWide = m_flSmallBoxSize + ((m_flLargeBoxWide - m_flSmallBoxSize) * percentageDone); int largeBoxTall = m_flSmallBoxSize + ((m_flLargeBoxTall - m_flSmallBoxSize) * percentageDone); Color selectedColor; @@ -644,16 +644,25 @@ void CHudWeaponSelection::Paint() // This is a bit of a misnomer... we really are asking "Is this the selected slot"? selectedWeapon = true; } +#ifdef MAPBASE + else if (!hud_showemptyweaponslots.GetBool() && !pWeapon) + { + // Revert the offset + xPos -= ( m_flMediumBoxWide + 5 ) * xModifiers[ i ]; + yPos -= ( m_flMediumBoxTall + 5 ) * yModifiers[ i ]; + continue; + } +#endif // Draw the box with the appropriate icon - DrawLargeWeaponBox( pWeapon, - selectedWeapon, - x, - y, - boxWide, - boxTall, - selectedWeapon ? selectedColor : m_BoxColor, - GetWeaponBoxAlpha( selectedWeapon ), + DrawLargeWeaponBox( pWeapon, + selectedWeapon, + x, + y, + boxWide, + boxTall, + selectedWeapon ? selectedColor : m_BoxColor, + GetWeaponBoxAlpha( selectedWeapon ), -1 ); } } @@ -690,14 +699,14 @@ void CHudWeaponSelection::Paint() else { bool bSelected = (pWeapon == pSelectedWeapon); - DrawLargeWeaponBox( pWeapon, - bSelected, - xpos, - ypos, - largeBoxWide, - largeBoxTall, - bSelected ? selectedColor : m_BoxColor, - GetWeaponBoxAlpha( bSelected ), + DrawLargeWeaponBox( pWeapon, + bSelected, + xpos, + ypos, + largeBoxWide, + largeBoxTall, + bSelected ? selectedColor : m_BoxColor, + GetWeaponBoxAlpha( bSelected ), bDrawBucketNumber ? i + 1 : -1 ); } @@ -752,7 +761,7 @@ void CHudWeaponSelection::Paint() void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int xpos, int ypos, int boxWide, int boxTall, Color selectedColor, float alpha, int number ) { Color col = bSelected ? m_SelectedFgColor : GetFgColor(); - + switch ( hud_fastswitch.GetInt() ) { case HUDTYPE_BUCKETS: @@ -794,7 +803,7 @@ void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool // draw an active version over the top pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col ); } - + // draw the inactive version pWeapon->GetSpriteInactive()->DrawSelf( xpos + x_offs, ypos + y_offs, col ); } @@ -937,7 +946,7 @@ void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool { for (wchar_t *pch = text; *pch != 0; pch++) { - if (*pch == '\n') + if (*pch == '\n') { // newline character, drop to the next line if (slen > maxslen) @@ -1033,7 +1042,7 @@ void CHudWeaponSelection::ApplySchemeSettings(vgui::IScheme *pScheme) if ( hud_fastswitch.GetInt() == HUDTYPE_CAROUSEL ) { - // need bounds to be exact width for proper clipping during scroll + // need bounds to be exact width for proper clipping during scroll int width = MAX_CAROUSEL_SLOTS*m_flLargeBoxWide + (MAX_CAROUSEL_SLOTS-1)*m_flBoxGap; SetBounds( (screenWide-width)/2, y, width, screenTall - y); } @@ -1269,7 +1278,7 @@ int CHudWeaponSelection::GetLastPosInSlot( int iSlot ) const for ( int i = 0; i < MAX_WEAPONS; i++ ) { C_BaseCombatWeapon *pWeapon = player->GetWeapon(i); - + if ( pWeapon == NULL ) continue; @@ -1375,6 +1384,23 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot ) // Changing vertical/horizontal direction. Reset the selected box position to zero. m_iSelectedBoxPosition = 0; m_iSelectedSlot = iWeaponSlot; + +#ifdef MAPBASE + if (!hud_showemptyweaponslots.GetBool()) + { + // Skip empty slots + int i = 0; + while ( i < MAX_WEAPON_POSITIONS ) + { + C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( iWeaponSlot, i ); + if ( pWeapon ) + break; + i++; + } + + m_iSelectedBoxPosition = i; + } +#endif } else { @@ -1382,9 +1408,30 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot ) int increment = 1; if ( m_iSelectedSlot != iWeaponSlot ) { - // Decrementing within the slot. If we're at the zero position in this slot, + // Decrementing within the slot. If we're at the zero position in this slot, // jump to the zero position of the opposite slot. This also counts as our increment. increment = -1; +#ifdef MAPBASE + if (!hud_showemptyweaponslots.GetBool()) + { + // Skip empty slots + int iZeroPos = 0; + while ( iZeroPos < MAX_WEAPON_POSITIONS ) + { + C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, iZeroPos ); + if ( pWeapon ) + break; + iZeroPos++; + } + + if ( iZeroPos == m_iSelectedBoxPosition ) + { + newSlot = ( m_iSelectedSlot + 2 ) % 4; + m_iSelectedBoxPosition = increment = 0; + } + } + else +#endif if ( 0 == m_iSelectedBoxPosition ) { newSlot = ( m_iSelectedSlot + 2 ) % 4; @@ -1403,6 +1450,35 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot ) } } +#ifdef MAPBASE + if (!hud_showemptyweaponslots.GetBool()) + { + // Skip empty slots + int i = m_iSelectedBoxPosition + increment; + while ( i >= 0 && i < lastSlotPos ) + { + C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( newSlot, i ); + if ( !pWeapon ) + { + if (increment < 0) + { + increment--; + i--; + } + else + { + increment++; + i++; + } + } + else + { + break; + } + } + } +#endif + // Increment/Decrement the selected box position if ( m_iSelectedBoxPosition + increment <= lastSlotPos ) { @@ -1455,7 +1531,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) // Don't try and read past our possible number of slots if ( iSlot >= MAX_WEAPON_SLOTS ) return; - + // Make sure the player's allowed to switch weapons if ( pPlayer->IsAllowedToSwitchWeapons() == false ) return; @@ -1468,7 +1544,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) FastWeaponSwitch( iSlot ); return; } - + case HUDTYPE_PLUS: { if ( !IsInSelectionMode() ) @@ -1476,7 +1552,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) // open the weapon selection OpenSelection(); } - + PlusTypeFastWeaponSwitch( iSlot ); ActivateWeaponHighlight( GetSelectedWeapon() ); } @@ -1499,7 +1575,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) { pActiveWeapon = GetNextActivePos( iSlot, 0 ); } - + if ( pActiveWeapon != NULL ) { if ( !IsInSelectionMode() ) diff --git a/game/client/hltvcamera.cpp b/game/client/hltvcamera.cpp index 1da4acfd..9754b99f 100644 --- a/game/client/hltvcamera.cpp +++ b/game/client/hltvcamera.cpp @@ -736,7 +736,7 @@ void C_HLTVCamera::FireGameEvent( IGameEvent * event) } // after this only auto-director commands follow - // don't execute them if autodirector is off and PVS is unlocked + // don't execute them is autodirector is off and PVS is unlocked if ( !spec_autodirector.GetBool() && !IsPVSLocked() ) return; diff --git a/game/client/hud.cpp b/game/client/hud.cpp index af50b187..a7d77a32 100644 --- a/game/client/hud.cpp +++ b/game/client/hud.cpp @@ -134,10 +134,13 @@ void LoadHudTextures( CUtlDict< CHudTexture *, int >& list, const char *szFilena pTemp = pTemp->GetNextKey(); } } - } - // Failed for some reason. Delete the Key data and abort. - pKeyValuesData->deleteThis(); + pKeyValuesData->deleteThis(); + } + else + { + Warning( "Unable to read script %s.\n", szFilenameWithoutExtension ); + } } //----------------------------------------------------------------------------- @@ -469,6 +472,8 @@ void CHud::Init( void ) } FreeHudTextureList( textureList ); + + HudIcons().Init(); } //----------------------------------------------------------------------------- @@ -1197,3 +1202,232 @@ CON_COMMAND_F( testhudanim, "Test a hud element animation.\n\tArguments: GetViewportAnimationController()->StartAnimationSequence( args[1] ); } +CHudIcons::CHudIcons() : + m_bHudTexturesLoaded( false ) +{ +} + +CHudIcons::~CHudIcons() +{ + int c = m_Icons.Count(); + for ( int i = c - 1; i >= 0; i-- ) + { + CHudTexture *tex = m_Icons[ i ]; + g_HudTextureMemoryPool.Free( tex ); + } + m_Icons.Purge(); +} + +void CHudIcons::Init() +{ + if ( m_bHudTexturesLoaded ) + return; + + m_bHudTexturesLoaded = true; + CUtlDict< CHudTexture *, int > textureList; + + // check to see if we have sprites for this res; if not, step down + LoadHudTextures( textureList, "scripts/hud_textures", NULL ); + LoadHudTextures( textureList, "scripts/mod_textures", NULL ); + + LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); +#ifdef HL2_CLIENT_DLL + LoadHudTextures( textureList, "scripts/instructor_textures_hl2", NULL ); +#endif + LoadHudTextures( textureList, "scripts/instructor_modtextures", NULL ); + + int c = textureList.Count(); + for ( int index = 0; index < c; index++ ) + { + CHudTexture* tex = textureList[ index ]; + AddSearchableHudIconToList( *tex ); + } + + FreeHudTextureList( textureList ); +} + +void CHudIcons::Shutdown() +{ + m_bHudTexturesLoaded = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHudTexture *CHudIcons::AddUnsearchableHudIconToList( CHudTexture& texture ) +{ + // These names are composed based on the texture file name + char composedName[ 512 ]; + + if ( texture.bRenderUsingFont ) + { + Q_snprintf( composedName, sizeof( composedName ), "%s_c%i", + texture.szTextureFile, texture.cCharacterInFont ); + } + else + { + Q_snprintf( composedName, sizeof( composedName ), "%s_%i_%i_%i_%i", + texture.szTextureFile, texture.rc.left, texture.rc.top, texture.rc.right, texture.rc.bottom ); + } + + CHudTexture *icon = GetIcon( composedName ); + if ( icon ) + { + return icon; + } + + CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc(); + *newTexture = texture; + + SetupNewHudTexture( newTexture ); + + int idx = m_Icons.Insert( composedName, newTexture ); + return m_Icons[ idx ]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHudTexture *CHudIcons::AddSearchableHudIconToList( CHudTexture& texture ) +{ + CHudTexture *icon = GetIcon( texture.szShortName ); + if ( icon ) + { + return icon; + } + + CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc(); + *newTexture = texture; + + SetupNewHudTexture( newTexture ); + + int idx = m_Icons.Insert( texture.szShortName, newTexture ); + return m_Icons[ idx ]; +} + +//----------------------------------------------------------------------------- +// Purpose: returns a pointer to an icon in the list +//----------------------------------------------------------------------------- +CHudTexture *CHudIcons::GetIcon( const char *szIcon ) +{ + int i = m_Icons.Find( szIcon ); + if ( i == m_Icons.InvalidIndex() ) + return NULL; + + return m_Icons[ i ]; +} + +//----------------------------------------------------------------------------- +// Purpose: Gets texture handles for the hud icon +//----------------------------------------------------------------------------- +void CHudIcons::SetupNewHudTexture( CHudTexture *t ) +{ + if ( t->bRenderUsingFont ) + { + vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); + t->hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( t->szTextureFile, true ); + t->rc.top = 0; + t->rc.left = 0; + t->rc.right = vgui::surface()->GetCharacterWidth( t->hFont, t->cCharacterInFont ); + t->rc.bottom = vgui::surface()->GetFontTall( t->hFont ); + } + else + { + // Set up texture id and texture coordinates + t->textureId = vgui::surface()->CreateNewTextureID(); + vgui::surface()->DrawSetTextureFile( t->textureId, t->szTextureFile, false, false ); + + int wide, tall; + vgui::surface()->DrawGetTextureSize( t->textureId, wide, tall ); + + t->texCoords[ 0 ] = (float)(t->rc.left + 0.5f) / (float)wide; + t->texCoords[ 1 ] = (float)(t->rc.top + 0.5f) / (float)tall; + t->texCoords[ 2 ] = (float)(t->rc.right - 0.5f) / (float)wide; + t->texCoords[ 3 ] = (float)(t->rc.bottom - 0.5f) / (float)tall; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudIcons::RefreshHudTextures() +{ + if ( !m_bHudTexturesLoaded ) + { + Assert( 0 ); + return; + } + + CUtlDict< CHudTexture *, int > textureList; + + // check to see if we have sprites for this res; if not, step down + LoadHudTextures( textureList, "scripts/hud_textures", NULL ); + LoadHudTextures( textureList, "scripts/mod_textures", NULL ); + + LoadHudTextures( textureList, "scripts/instructor_textures", NULL ); + + + // fix up all the texture icons first + int c = textureList.Count(); + for ( int index = 0; index < c; index++ ) + { + CHudTexture *tex = textureList[ index ]; + Assert( tex ); + + CHudTexture *icon = GetIcon( tex->szShortName ); + if ( !icon ) + continue; + + // Update file + Q_strncpy( icon->szTextureFile, tex->szTextureFile, sizeof( icon->szTextureFile ) ); + + if ( !icon->bRenderUsingFont ) + { + // Update subrect + icon->rc = tex->rc; + + // Keep existing texture id, but now update texture file and texture coordinates + vgui::surface()->DrawSetTextureFile( icon->textureId, icon->szTextureFile, false, false ); + + // Get new texture dimensions in case it changed + int wide, tall; + vgui::surface()->DrawGetTextureSize( icon->textureId, wide, tall ); + + // Assign coords + icon->texCoords[ 0 ] = (float)(icon->rc.left + 0.5f) / (float)wide; + icon->texCoords[ 1 ] = (float)(icon->rc.top + 0.5f) / (float)tall; + icon->texCoords[ 2 ] = (float)(icon->rc.right - 0.5f) / (float)wide; + icon->texCoords[ 3 ] = (float)(icon->rc.bottom - 0.5f) / (float)tall; + } + } + + FreeHudTextureList( textureList ); + + // fixup all the font icons + vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); + for (int i = m_Icons.First(); m_Icons.IsValidIndex(i); i = m_Icons.Next(i)) + { + CHudTexture *icon = m_Icons[i]; + if ( !icon ) + continue; + + // Update file + if ( icon->bRenderUsingFont ) + { + icon->hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( icon->szTextureFile, true ); + icon->rc.top = 0; + icon->rc.left = 0; + icon->rc.right = vgui::surface()->GetCharacterWidth( icon->hFont, icon->cCharacterInFont ); + icon->rc.bottom = vgui::surface()->GetFontTall( icon->hFont ); + } + } +} + + +static CHudIcons g_HudIcons; + +CHudIcons &HudIcons() +{ + return g_HudIcons; +} + diff --git a/game/client/hud.h b/game/client/hud.h index b623a3eb..52ff0580 100644 --- a/game/client/hud.h +++ b/game/client/hud.h @@ -194,6 +194,37 @@ class CHud extern CHud gHUD; +//----------------------------------------------------------------------------- +// Purpose: CHudIcons +//----------------------------------------------------------------------------- +class CHudIcons +{ +public: + CHudIcons(); + ~CHudIcons(); + + void Init(); + void Shutdown(); + + CHudTexture *GetIcon( const char *szIcon ); + + // loads a new icon into the list, without duplicates + CHudTexture *AddUnsearchableHudIconToList( CHudTexture& texture ); + CHudTexture *AddSearchableHudIconToList( CHudTexture& texture ); + + void RefreshHudTextures(); + +private: + + void SetupNewHudTexture( CHudTexture *t ); + bool m_bHudTexturesLoaded; + // Global list of known icons + CUtlDict< CHudTexture *, int > m_Icons; + +}; + +CHudIcons &HudIcons(); + //----------------------------------------------------------------------------- // Global fonts used in the client DLL //----------------------------------------------------------------------------- diff --git a/game/client/hud_basechat.cpp b/game/client/hud_basechat.cpp index f6b20413..69d67862 100644 --- a/game/client/hud_basechat.cpp +++ b/game/client/hud_basechat.cpp @@ -24,7 +24,6 @@ #include "vgui/IInput.h" #include "vgui/ILocalize.h" #include "multiplay_gamerules.h" -#include "voice_status.h" // memdbgon must be the last include file in a .cpp file!!! @@ -37,7 +36,6 @@ ConVar hud_saytext_time( "hud_saytext_time", "12", 0 ); ConVar cl_showtextmsg( "cl_showtextmsg", "1", 0, "Enable/disable text messages printing on the screen." ); ConVar cl_chatfilters( "cl_chatfilters", "63", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Stores the chat filter settings " ); ConVar cl_chatfilter_version( "cl_chatfilter_version", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE | FCVAR_HIDDEN, "Stores the chat filter version" ); -ConVar cl_mute_all_comms("cl_mute_all_comms", "1", FCVAR_ARCHIVE, "If 1, then all communications from a player will be blocked when that player is muted, including chat messages."); const int kChatFilterVersion = 1; @@ -1752,13 +1750,6 @@ void CBaseHudChat::ChatPrintf( int iPlayerIndex, int iFilter, const char *fmt, . return; } - // If a player is muted for voice, also mute them for text because jerks gonna jerk. - if ( cl_mute_all_comms.GetBool() && iPlayerIndex != 0 ) - { - if ( GetClientVoiceMgr() && GetClientVoiceMgr()->IsPlayerBlocked( iPlayerIndex ) ) - return; - } - if ( *pmsg < 32 ) { hudlcd->AddChatLine( pmsg + 1 ); diff --git a/game/client/hud_basechat.h b/game/client/hud_basechat.h index cf5c3f1f..90de8fbf 100644 --- a/game/client/hud_basechat.h +++ b/game/client/hud_basechat.h @@ -241,7 +241,7 @@ class CBaseHudChat : public CHudElement, public vgui::EditablePanel void MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf); virtual void Printf( int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ); - virtual void ChatPrintf( int iPlayerIndex, int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 4, 5 ); + virtual void ChatPrintf( int iPlayerIndex, int iFilter, PRINTF_FORMAT_STRING const char *fmt, ... ); virtual void StartMessageMode( int iMessageModeType ); virtual void StopMessageMode( void ); diff --git a/game/client/hud_basedeathnotice.cpp b/game/client/hud_basedeathnotice.cpp index 36a9cc3c..d732bd05 100644 --- a/game/client/hud_basedeathnotice.cpp +++ b/game/client/hud_basedeathnotice.cpp @@ -65,7 +65,6 @@ void CHudBaseDeathNotice::Init( void ) ListenForGameEvent( "teamplay_point_captured" ); ListenForGameEvent( "teamplay_capture_blocked" ); ListenForGameEvent( "teamplay_flag_event" ); - ListenForGameEvent( "rd_robot_killed" ); } //----------------------------------------------------------------------------- @@ -115,9 +114,7 @@ void CHudBaseDeathNotice::Paint() DeathNoticeItem &msg = m_DeathNotices[i]; CHudTexture *icon = msg.iconDeath; - CHudTexture *iconPostKillerName = msg.iconPostKillerName; - CHudTexture *iconPreKillerName = msg.iconPreKillerName; - CHudTexture *iconPostVictimName = msg.iconPostVictimName; + CHudTexture *iconPrekiller = msg.iconPreKiller; wchar_t victim[256]=L""; wchar_t killer[256]=L""; @@ -137,11 +134,7 @@ void CHudBaseDeathNotice::Paint() int iconWide = 0, iconTall = 0, iDeathInfoOffset = 0, iVictimTextOffset = 0, iconActualWide = 0; int iPreKillerTextWide = msg.wzPreKillerText[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzPreKillerText ) - xSpacing : 0; - - int iconPrekillerWide = 0, iconPrekillerActualWide = 0, iconPrekillerTall = 0; - int iconPostkillerWide = 0, iconPostkillerActualWide = 0, iconPostkillerTall = 0; - - int iconPostVictimWide = 0, iconPostVictimActualWide = 0, iconPostVictimTall = 0; + int iconPrekillerWide = 0, iconPrekillerActualWide = 0, iconPreKillerTall = 0; // Get the local position for this notice if ( icon ) @@ -159,53 +152,23 @@ void CHudBaseDeathNotice::Paint() iconWide *= flScale; } - if ( iconPreKillerName ) + if ( iconPrekiller ) { - iconPrekillerActualWide = iconPreKillerName->EffectiveWidth( 1.0f ); + iconPrekillerActualWide = iconPrekiller->EffectiveWidth( 1.0f ); iconPrekillerWide = iconPrekillerActualWide; - iconPrekillerTall = iconPreKillerName->EffectiveHeight( 1.0f ); + iconPreKillerTall = iconPrekiller->EffectiveHeight( 1.0f ); - int iconTallDesired = iLineTall - YRES( 2 ); + int iconTallDesired = iLineTall-YRES(2); Assert( 0 != iconTallDesired ); - float flScale = (float)iconTallDesired / (float)iconPrekillerTall; + float flScale = (float) iconTallDesired / (float) iconPreKillerTall; iconPrekillerActualWide *= flScale; - iconPrekillerTall *= flScale; + iconPreKillerTall *= flScale; iconPrekillerWide *= flScale; } - if ( iconPostKillerName ) - { - iconPostkillerActualWide = iconPostKillerName->EffectiveWidth( 1.0f ); - iconPostkillerWide = iconPostkillerActualWide; - iconPostkillerTall = iconPostKillerName->EffectiveHeight( 1.0f ); - - int iconTallDesired = iLineTall-YRES(2); - Assert( 0 != iconTallDesired ); - float flScale = (float) iconTallDesired / (float) iconPostkillerTall; - - iconPostkillerActualWide *= flScale; - iconPostkillerTall *= flScale; - iconPostkillerWide *= flScale; - } - - if ( iconPostVictimName ) - { - iconPostVictimActualWide = iconPostVictimName->EffectiveWidth( 1.0f ); - iconPostVictimWide = iconPostVictimActualWide; - iconPostVictimTall = iconPostVictimName->EffectiveHeight( 1.0f ); - - int iconTallDesired = iLineTall - YRES( 2 ); - Assert( 0 != iconTallDesired ); - float flScale = (float)iconTallDesired / (float)iconPostVictimTall; - - iconPostVictimActualWide *= flScale; - iconPostVictimTall *= flScale; - iconPostVictimWide *= flScale; - } - int iTotalWide = iKillerTextWide + iconWide + iVictimTextWide + iDeathInfoTextWide + iDeathInfoEndTextWide + ( xMargin * 2 ); - iTotalWide += iconPrekillerWide + iconPostkillerWide + iPreKillerTextWide + iconPostVictimWide; + iTotalWide += iconPrekillerWide + iPreKillerTextWide; int y = yStart + ( ( iLineTall + m_flLineSpacing ) * i ); int yText = y + ( ( iLineTall - iTextTall ) / 2 ); @@ -226,14 +189,6 @@ void CHudBaseDeathNotice::Paint() x += xMargin; - // prekiller icon - if ( iconPreKillerName ) - { - int yPreIconTall = y + ( ( iLineTall - iconPrekillerTall ) / 2 ); - iconPreKillerName->DrawSelf( x, yPreIconTall, iconPrekillerActualWide, iconPrekillerTall, m_clrIcon); - x += iconPrekillerWide + xSpacing; - } - if ( killer[0] ) { // Draw killer's name @@ -249,12 +204,12 @@ void CHudBaseDeathNotice::Paint() x += iPreKillerTextWide; } - // postkiller icon - if ( iconPostKillerName ) + // Prekiller icon + if ( iconPrekiller ) { - int yPreIconTall = y + ( ( iLineTall - iconPostkillerTall ) / 2 ); - iconPostKillerName->DrawSelf( x, yPreIconTall, iconPostkillerActualWide, iconPostkillerTall, m_clrIcon ); - x += iconPostkillerWide + xSpacing; + int yPreIconTall = y + ( ( iLineTall - iconPreKillerTall ) / 2 ); + iconPrekiller->DrawSelf( x, yPreIconTall, iconPrekillerActualWide, iconPreKillerTall, m_clrIcon ); + x += iconPrekillerWide + xSpacing; } // Draw glow behind weapon icon to show it was a crit death @@ -287,14 +242,6 @@ void CHudBaseDeathNotice::Paint() DrawText( x + iVictimTextOffset, yText, m_hTextFont, GetTeamColor( msg.Victim.iTeam, msg.bLocalPlayerInvolved ), victim ); x += iVictimTextWide; - // postkiller icon - if ( iconPostVictimName ) - { - int yPreIconTall = y + ( ( iLineTall - iconPostVictimTall ) / 2 ); - iconPostVictimName->DrawSelf( x, yPreIconTall, iconPostVictimActualWide, iconPostVictimTall, m_clrIcon ); - x += iconPostkillerWide + xSpacing; - } - // Draw Additional Text on the end of the victims name if ( msg.wzInfoTextEnd[0] ) { @@ -621,27 +568,16 @@ void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event ) } } - bool bIsHalloween2014 = TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ); - switch ( iEventType ) { case TF_FLAGEVENT_PICKUP: - pszMsgKey = bIsHalloween2014 ? "#Msg_PickedUpFlagHalloween2014" : "#Msg_PickedUpFlag"; + pszMsgKey = "#Msg_PickedUpFlag"; break; case TF_FLAGEVENT_CAPTURE: - pszMsgKey = bIsHalloween2014 ? "#Msg_CapturedFlagHalloween2014" : "#Msg_CapturedFlag"; + pszMsgKey = "#Msg_CapturedFlag"; break; case TF_FLAGEVENT_DEFEND: - if ( bIsMvM ) - { - pszMsgKey = "#Msg_DefendedBomb"; - } - else - { - pszMsgKey = bIsHalloween2014 ? "#Msg_DefendedFlagHalloween2014" : "#Msg_DefendedFlag"; - } - - + pszMsgKey = bIsMvM ? "#Msg_DefendedBomb" : "#Msg_DefendedFlag"; break; // Add this when we can get localization for it diff --git a/game/client/hud_basedeathnotice.h b/game/client/hud_basedeathnotice.h index b4f34eb8..2a9da0c5 100644 --- a/game/client/hud_basedeathnotice.h +++ b/game/client/hud_basedeathnotice.h @@ -42,10 +42,8 @@ struct DeathNoticeItem iKillerID = -1; iVictimID = -1; - iconPreKillerName = NULL; - iconPostKillerName = NULL; + iconPreKiller = NULL; wzPreKillerText[0] = 0; - iconPostVictimName = NULL; } float GetExpiryTime(); @@ -58,13 +56,9 @@ struct DeathNoticeItem CHudTexture *iconDeath; CHudTexture *iconCritDeath; // crit background icon - CHudTexture *iconPreKillerName; - - CHudTexture *iconPostKillerName; + CHudTexture *iconPreKiller; wchar_t wzPreKillerText[32]; - CHudTexture *iconPostVictimName; - bool bSelfInflicted; bool bLocalPlayerInvolved; bool bCrit; diff --git a/game/client/hud_closecaption.cpp b/game/client/hud_closecaption.cpp index c1a1fa29..e2d718c9 100644 --- a/game/client/hud_closecaption.cpp +++ b/game/client/hud_closecaption.cpp @@ -31,12 +31,20 @@ extern ISoundEmitterSystemBase *soundemitterbase; // Marked as FCVAR_USERINFO so that the server can cull CC messages before networking them down to us!!! +#ifdef MAPBASE +ConVar closecaption( "closecaption", "1", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX | FCVAR_USERINFO, "Enable close captioning." ); +#else ConVar closecaption( "closecaption", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX | FCVAR_USERINFO, "Enable close captioning." ); +#endif extern ConVar cc_lang; static ConVar cc_linger_time( "cc_linger_time", "1.0", FCVAR_ARCHIVE, "Close caption linger time." ); static ConVar cc_predisplay_time( "cc_predisplay_time", "0.25", FCVAR_ARCHIVE, "Close caption delay before showing caption." ); static ConVar cc_captiontrace( "cc_captiontrace", "1", 0, "Show missing closecaptions (0 = no, 1 = devconsole, 2 = show in hud)" ); +#ifdef MAPBASE +static ConVar cc_subtitles( "cc_subtitles", "1", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "If set, don't show sound effect captions, just voice overs (i.e., won't help hearing impaired players)." ); +#else static ConVar cc_subtitles( "cc_subtitles", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "If set, don't show sound effect captions, just voice overs (i.e., won't help hearing impaired players)." ); +#endif ConVar english( "english", "1", FCVAR_USERINFO, "If set to 1, running the english language set of assets." ); static ConVar cc_smallfontlength( "cc_smallfontlength", "300", 0, "If text stream is this long, force usage of small font size." ); @@ -844,7 +852,6 @@ CHudCloseCaption::CHudCloseCaption( const char *pElementName ) HOOK_HUD_MESSAGE( CHudCloseCaption, CloseCaption ); char uilanguage[ 64 ]; - uilanguage[0] = 0; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); if ( !Q_stricmp( uilanguage, "english" ) ) @@ -1295,7 +1302,7 @@ void CHudCloseCaption::Reset( void ) Unlock(); } -bool CHudCloseCaption::SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t *args ) const +bool CHudCloseCaption::SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t *args, int size ) const { const wchar_t *in = *ppIn; const wchar_t *oldin = in; @@ -1310,8 +1317,11 @@ bool CHudCloseCaption::SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t cmd[ 0 ]= 0; wchar_t *out = cmd; in++; - while ( *in != L'\0' && *in != L':' && *in != L'>' && !isspace( *in ) ) + while ( *in != L'\0' && *in != L':' && *in != L'>' && !V_isspace( *in ) ) { + if ( (int)( out - cmd ) + (int)sizeof( wchar_t ) >= size ) + break; + *out++ = *in++; } *out = L'\0'; @@ -1326,6 +1336,9 @@ bool CHudCloseCaption::SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t out = args; while ( *in != L'\0' && *in != L'>' ) { + if ( (int)( out - args ) + (int)sizeof( wchar_t ) >= size ) + break; + *out++ = *in++; } *out = L'\0'; @@ -1353,7 +1366,7 @@ bool CHudCloseCaption::GetFloatCommandValue( const wchar_t *stream, const wchar_ wchar_t cmd[ 256 ]; wchar_t args[ 256 ]; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, findcmd ) ) { @@ -1377,7 +1390,7 @@ bool CHudCloseCaption::StreamHasCommand( const wchar_t *stream, const wchar_t *f wchar_t cmd[ 256 ]; wchar_t args[ 256 ]; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, findcmd ) ) { @@ -1416,7 +1429,7 @@ bool CHudCloseCaption::StreamHasCommand( const wchar_t *stream, const wchar_t *s wchar_t cmd[ 256 ]; wchar_t args[ 256 ]; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, search ) ) { @@ -1508,7 +1521,7 @@ void CHudCloseCaption::Process( const wchar_t *stream, float duration, const cha const wchar_t *prevpos = curpos; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, L"delay" ) ) { @@ -1605,6 +1618,9 @@ struct WorkUnitParams clr = Color( 255, 255, 255, 255 ); newline = false; font = 0; +#ifdef MAPBASE + customFont = false; +#endif } ~WorkUnitParams() @@ -1650,6 +1666,9 @@ struct WorkUnitParams Color clr; bool newline; vgui::HFont font; +#ifdef MAPBASE + bool customFont; +#endif }; void CHudCloseCaption::AddWorkUnit( CCloseCaptionItem *item, @@ -1709,7 +1728,7 @@ void CHudCloseCaption::ComputeStreamWork( int available_width, CCloseCaptionItem wchar_t cmd[ 256 ]; wchar_t args[ 256 ]; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, L"cr" ) ) { @@ -1764,27 +1783,58 @@ void CHudCloseCaption::ComputeStreamWork( int available_width, CCloseCaptionItem { AddWorkUnit( item, params ); params.italic = !params.italic; +#ifdef MAPBASE + params.customFont = false; +#endif } else if ( !wcscmp( cmd, L"B" ) ) { AddWorkUnit( item, params ); params.bold = !params.bold; +#ifdef MAPBASE + params.customFont = false; +#endif } +#ifdef MAPBASE + else if ( !wcscmp( cmd, L"font" ) ) + { + AddWorkUnit( item, params ); + vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() ); + + if ( args[0] != 0 ) + { + char font[64]; + g_pVGuiLocalize->ConvertUnicodeToANSI( args, font, sizeof( font ) ); + params.font = pScheme->GetFont( font ); + params.customFont = true; + } + else + { + params.customFont = false; + } + } +#endif continue; } - int font; - if ( IsPC() ) - { - font = params.GetFontNumber(); - } - else + vgui::HFont useF = params.font; +#ifdef MAPBASE + if (params.customFont == false) +#endif { - font = streamlen >= cc_smallfontlength.GetInt() ? CCFONT_SMALL : CCFONT_NORMAL; + int font; + if ( IsPC() ) + { + font = params.GetFontNumber(); + } + else + { + font = streamlen >= cc_smallfontlength.GetInt() ? CCFONT_SMALL : CCFONT_NORMAL; + } + useF = m_hFonts[font]; + params.font = useF; } - vgui::HFont useF = m_hFonts[font]; - params.font = useF; int w, h; @@ -1932,7 +1982,7 @@ bool CHudCloseCaption::GetNoRepeatValue( const wchar_t *caption, float &retval ) wchar_t cmd[ 256 ]; wchar_t args[ 256 ]; - if ( SplitCommand( &curpos, cmd, args ) ) + if ( SplitCommand( &curpos, cmd, args, sizeof( cmd ) ) ) { if ( !wcscmp( cmd, L"norepeat" ) ) { @@ -2357,11 +2407,11 @@ bool CHudCloseCaption::AddAsyncWork( const char *tokenstream, bool bIsStream, fl char tokenname[ 512 ]; tokenname[ 0 ] = 0; const char *p = tokenstream; - p = nexttoken( tokenname, p, ' ' ); + p = nexttoken( tokenname, p, ' ' , sizeof(tokenname) ); // p points to reset of sentence tokens, build up a unicode string from them... while ( p && Q_strlen( tokenname ) > 0 ) { - p = nexttoken( tokenname, p, ' ' ); + p = nexttoken( tokenname, p, ' ' , sizeof(tokenname) ); if ( Q_strlen( tokenname ) == 0 ) break; @@ -2396,7 +2446,7 @@ void CHudCloseCaption::ProcessSentenceCaptionStream( const char *tokenstream ) const char *p = tokenstream; - p = nexttoken( tokenname, p, ' ' ); + p = nexttoken( tokenname, p, ' ' , sizeof(tokenname) ); if ( Q_strlen( tokenname ) > 0 ) { @@ -2623,6 +2673,124 @@ void CHudCloseCaption::InitCaptionDictionary( const char *dbfile ) g_AsyncCaptionResourceManager.SetDbInfo( m_AsyncCaptions ); } +#ifdef MAPBASE +void CHudCloseCaption::AddAdditionalCaptionDictionary( const char *dbfile, CUtlVector &outPathSymbols ) +{ + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Adding additional caption dictionary \"%s\"\n", dbfile ); + + g_AsyncCaptionResourceManager.Clear(); + + char searchPaths[4096]; + filesystem->GetSearchPath( "MOD", true, searchPaths, sizeof( searchPaths ) ); + + for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) ) + { + if ( IsX360() && ( filesystem->GetDVDMode() == DVDMODE_STRICT ) && !V_stristr( path, ".zip" ) ) + { + // only want zip paths + continue; + } + + char fullpath[MAX_PATH]; + Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", path, dbfile ); + Q_FixSlashes( fullpath ); + + if ( IsX360() ) + { + char fullpath360[MAX_PATH]; + UpdateOrCreateCaptionFile( fullpath, fullpath360, sizeof( fullpath360 ) ); + Q_strncpy( fullpath, fullpath360, sizeof( fullpath ) ); + } + + // Seach for this dictionary. If it already exists, remove it. + for (int i = 0; i < m_AsyncCaptions.Count(); ++i) + { + if (FStrEq( m_AsyncCaptions[i].m_DataBaseFile.String(), fullpath )) + { + m_AsyncCaptions.Remove( i ); + break; + } + } + + FileHandle_t fh = filesystem->Open( fullpath, "rb" ); + if ( FILESYSTEM_INVALID_HANDLE != fh ) + { + MEM_ALLOC_CREDIT(); + + CUtlBuffer dirbuffer; + + AsyncCaption_t& entry = m_AsyncCaptions[ m_AsyncCaptions.AddToTail() ]; + + // Read the header + filesystem->Read( &entry.m_Header, sizeof( entry.m_Header ), fh ); + if ( entry.m_Header.magic != COMPILED_CAPTION_FILEID ) + Error( "Invalid file id for %s\n", fullpath ); + if ( entry.m_Header.version != COMPILED_CAPTION_VERSION ) + Error( "Invalid file version for %s\n", fullpath ); + if ( entry.m_Header.directorysize < 0 || entry.m_Header.directorysize > 64 * 1024 ) + Error( "Invalid directory size %d for %s\n", entry.m_Header.directorysize, fullpath ); + //if ( entry.m_Header.blocksize != MAX_BLOCK_SIZE ) + // Error( "Invalid block size %d, expecting %d for %s\n", entry.m_Header.blocksize, MAX_BLOCK_SIZE, fullpath ); + + int directoryBytes = entry.m_Header.directorysize * sizeof( CaptionLookup_t ); + entry.m_CaptionDirectory.EnsureCapacity( entry.m_Header.directorysize ); + dirbuffer.EnsureCapacity( directoryBytes ); + + filesystem->Read( dirbuffer.Base(), directoryBytes, fh ); + filesystem->Close( fh ); + + entry.m_CaptionDirectory.CopyArray( (const CaptionLookup_t *)dirbuffer.PeekGet(), entry.m_Header.directorysize ); + entry.m_CaptionDirectory.RedoSort( true ); + + entry.m_DataBaseFile = fullpath; + outPathSymbols.AddToTail( entry.m_DataBaseFile ); + } + } + + g_AsyncCaptionResourceManager.SetDbInfo( m_AsyncCaptions ); +} + +void CHudCloseCaption::AddCustomCaptionFile( char const *file, CUtlVector &outPathSymbols ) +{ + // + // 'file' should be something like "maps/mapbase_demo01_closecaption_%language%" + // + + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Adding custom caption file \"%s\"\n", file ); + + if (!IsX360()) + { + g_pVGuiLocalize->AddFile( file, "MOD", true ); + } + + char uilanguage[64]; + engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); + + char dbfile[512]; + V_StrSubst( file, "%language%", uilanguage, dbfile, sizeof( dbfile ) ); + V_SetExtension( dbfile, ".dat", sizeof( dbfile ) ); + AddAdditionalCaptionDictionary( dbfile, outPathSymbols ); +} + +void CHudCloseCaption::RemoveCaptionDictionary( const CUtlSymbol &dbFileSymbol ) +{ + // + // 'file' should be something like "maps/mapbase_demo01_closecaption_%language%" + // + + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Removing custom caption file \"%s\"\n", dbFileSymbol.String() ); + + for (int i = 0; i < m_AsyncCaptions.Count(); ++i) + { + if ( m_AsyncCaptions[i].m_DataBaseFile == dbFileSymbol ) + { + m_AsyncCaptions.Remove( i ); + break; + } + } +} +#endif + void CHudCloseCaption::OnFinishAsyncLoad( int nFileIndex, int nBlockNum, AsyncCaptionData_t *pData ) { // Fill in data for all users of pData->m_nBlockNum @@ -2693,6 +2861,11 @@ CON_COMMAND_F_COMPLETION( cc_emit, "Emits a closed caption", 0, EmitCaptionCompl return; } +#ifdef MAPBASE // 1upD + if (!closecaption.GetBool()) + return; +#endif + CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); if ( hudCloseCaption ) { @@ -2753,7 +2926,6 @@ void OnCaptionLanguageChanged( IConVar *pConVar, const char *pOldString, float f } char uilanguage[ 64 ]; - uilanguage[0] = 0; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); diff --git a/game/client/hud_closecaption.h b/game/client/hud_closecaption.h index 180afe9d..8688e60e 100644 --- a/game/client/hud_closecaption.h +++ b/game/client/hud_closecaption.h @@ -111,6 +111,11 @@ class CHudCloseCaption : public CHudElement, public vgui::Panel void PlayRandomCaption(); void InitCaptionDictionary( char const *dbfile ); +#ifdef MAPBASE + void AddAdditionalCaptionDictionary( char const *dbfile, CUtlVector &outPathSymbols ); + void AddCustomCaptionFile( char const *file, CUtlVector &outPathSymbols ); + void RemoveCaptionDictionary( const CUtlSymbol &dbFileSymbol ); +#endif void OnFinishAsyncLoad( int nFileIndex, int nBlockNum, AsyncCaptionData_t *pData ); void Flush(); @@ -133,6 +138,11 @@ class CHudCloseCaption : public CHudElement, public vgui::Panel void FindSound( char const *pchANSI ); +#ifdef MAPBASE + inline bool IsUsingCommentaryDimensions() const { return m_bUsingCommentaryDimensions; } + inline void SetUsingCommentaryDimensions( bool bToggle ) { m_bUsingCommentaryDimensions = bToggle; } +#endif + public: struct CaptionRepeat @@ -169,7 +179,7 @@ class CHudCloseCaption : public CHudElement, public vgui::Panel void DrawStream( wrect_t& rect, wrect_t &rcWindow, CCloseCaptionItem *item, int iFadeLine, float flFadeLineAlpha ); void ComputeStreamWork( int available_width, CCloseCaptionItem *item ); - bool SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t *args ) const; + bool SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t *args, int size ) const; bool StreamHasCommand( const wchar_t *stream, const wchar_t *findcmd ) const; bool GetFloatCommandValue( const wchar_t *stream, const wchar_t *findcmd, float& value ) const; @@ -212,6 +222,10 @@ class CHudCloseCaption : public CHudElement, public vgui::Panel bool m_bVisibleDueToDirect; bool m_bPaintDebugInfo; CUtlSymbol m_CurrentLanguage; + +#ifdef MAPBASE + bool m_bUsingCommentaryDimensions; +#endif }; #endif // HUD_CLOSECAPTION_H diff --git a/game/client/hud_controlpointicons.cpp b/game/client/hud_controlpointicons.cpp index 2c0628e3..cc446c83 100644 --- a/game/client/hud_controlpointicons.cpp +++ b/game/client/hud_controlpointicons.cpp @@ -1402,7 +1402,7 @@ void CControlPointProgressBar::PerformLayout( void ) { BaseClass::PerformLayout(); - if ( m_pAttachedToIcon && m_pTeardrop && m_pTeardropSide && m_pAttachedToIcon->GetVPanel() ) + if ( m_pAttachedToIcon && m_pTeardrop && m_pTeardropSide ) { int iIconX, iIconY; ipanel()->GetAbsPos(m_pAttachedToIcon->GetVPanel(), iIconX, iIconY ); diff --git a/game/client/hud_crosshair.cpp b/game/client/hud_crosshair.cpp index 41085d03..fc7714fe 100644 --- a/game/client/hud_crosshair.cpp +++ b/game/client/hud_crosshair.cpp @@ -31,9 +31,6 @@ ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE ); ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE ); -#ifdef VANCE -ConVar cl_crosshair_forceaimdirection( "cl_crosshair_forceaimdirection", "1" ); -#endif using namespace vgui; @@ -168,18 +165,10 @@ void CHudCrosshair::GetDrawPosition ( float *pX, float *pY, bool *pbBehindCamera Vector vecStart; Vector vecEnd; - if ( UseVR() -#ifdef VANCE - || cl_crosshair_forceaimdirection.GetBool() -#endif - ) + if ( UseVR() ) { // These are the correct values to use, but they lag the high-speed view data... -#ifdef VANCE - vecStart = MainViewOrigin(); -#else vecStart = pPlayer->Weapon_ShootPosition(); -#endif Vector vecAimDirection = pPlayer->GetAutoaimVector( 1.0f ); // ...so in some aim modes, they get zapped by something completely up-to-date. g_ClientVirtualReality.OverrideWeaponHudAimVectors ( &vecStart, &vecAimDirection ); diff --git a/game/client/hud_hintdisplay.cpp b/game/client/hud_hintdisplay.cpp index 487633bd..50ab208a 100644 --- a/game/client/hud_hintdisplay.cpp +++ b/game/client/hud_hintdisplay.cpp @@ -599,10 +599,39 @@ bool CHudHintKeyDisplay::SetHintText( const char *text ) else { const char *key = engine->Key_LookupBinding( *binding == '+' ? binding + 1 : binding ); +#ifdef MAPBASE + if ( !key ) + { + const char *pszNotBound = VarArgs("< %s, not bound >", *binding == '+' ? binding + 1 : binding); + if (strchr(binding, '&')) + { + // "%walk&use%" >> "ALT + E" + char *token = strtok(binding, "&"); + while (token) + { + const char *tokenkey = engine->Key_LookupBinding( *token == '+' ? token + 1 : token ); + + key = VarArgs("%s%s%s", key ? key : "", key ? " + " : "", tokenkey ? tokenkey : pszNotBound); + + token = strtok(NULL, "&"); + } + } + else if (binding[0] == '$') + { + // "%$COOL STRING DUDE%" >> "COOL STRING DUDE" + key = binding + 1; + } + else + { + key = pszNotBound; + } + } +#else if ( !key ) { key = "< not bound >"; } +#endif Q_snprintf( friendlyName, sizeof(friendlyName), "#%s", key ); Q_strupr( friendlyName ); diff --git a/game/client/hud_lcd.cpp b/game/client/hud_lcd.cpp index 0f0609d6..d0425d6b 100644 --- a/game/client/hud_lcd.cpp +++ b/game/client/hud_lcd.cpp @@ -528,15 +528,15 @@ void CLCD::ShowItems_R( CLCDPage *page, unsigned int dwCurTime, CUtlVector< CLCD { CLCDItem *newItem = NULL; - CLCDItem *item = ag->m_Definition[ r ]; - switch ( item->m_Type ) + CLCDItem *itemLocl = ag->m_Definition[ r ]; + switch ( itemLocl->m_Type ) { default: break; case LCDITEM_TEXT: { - CLCDItemText *text = static_cast< CLCDItemText * >( item ); + CLCDItemText *text = static_cast< CLCDItemText * >( itemLocl ); CUtlString s; s = text->m_OriginalText; Replace( s, prefix, s1 ); @@ -551,7 +551,7 @@ void CLCD::ShowItems_R( CLCDPage *page, unsigned int dwCurTime, CUtlVector< CLCD // text->m_OriginalText = s; - CLCDItemText *copy = static_cast< CLCDItemText * >( page->Alloc( item->m_Type ) ); + CLCDItemText *copy = static_cast< CLCDItemText * >( page->Alloc( itemLocl->m_Type ) ); *copy = *text; copy->m_bActive = true; copy->m_OriginalText = s; @@ -564,8 +564,8 @@ void CLCD::ShowItems_R( CLCDPage *page, unsigned int dwCurTime, CUtlVector< CLCD break; case LCDITEM_ICON: { - CLCDItemIcon *icon = static_cast< CLCDItemIcon * >( item ); - CLCDItemIcon *copy = static_cast< CLCDItemIcon * >( page->Alloc( item->m_Type ) ); + CLCDItemIcon *icon = static_cast< CLCDItemIcon * >( itemLocl ); + CLCDItemIcon *copy = static_cast< CLCDItemIcon * >( page->Alloc( itemLocl->m_Type ) ); *copy = *icon; copy->m_bActive = true; copy->Create( m_lcd ); @@ -1186,16 +1186,16 @@ void CLCD::DumpPlayer() C_Team *team = player->GetTeam(); if ( team ) { - CDescribeData helper( team ); - helper.DumpDescription( team->GetPredDescMap() ); + CDescribeData helperLocl( team ); + helperLocl.DumpDescription( team->GetPredDescMap() ); } Msg( "(playerresource)\n\n" ); if ( g_PR ) { - CDescribeData helper( g_PR ); - helper.DumpDescription( g_PR->GetPredDescMap() ); + CDescribeData helperLocl( g_PR ); + helperLocl.DumpDescription( g_PR->GetPredDescMap() ); } Msg( "(localplayerweapon)\n\n" ); @@ -1203,8 +1203,8 @@ void CLCD::DumpPlayer() C_BaseCombatWeapon *active = player->GetActiveWeapon(); if ( active ) { - CDescribeData helper( active ); - helper.DumpDescription( active->GetPredDescMap() ); + CDescribeData helperLocl( active ); + helperLocl.DumpDescription( active->GetPredDescMap() ); } Msg( "Other replacements:\n\n" ); diff --git a/game/client/hud_locator_target.cpp b/game/client/hud_locator_target.cpp new file mode 100644 index 00000000..8479b07e --- /dev/null +++ b/game/client/hud_locator_target.cpp @@ -0,0 +1,2207 @@ +//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============// +// +// Purpose: See header file +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "hud_locator_target.h" +#include "iclientmode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "iinput.h" +#include "view.h" +#include "hud.h" +#include "hudelement.h" +#include "vgui_int.h" + +#include "hud_macros.h" +#include "iclientmode.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +#define ICON_SIZE 0.04f // Icons are ScreenWidth() * ICON_SIZE wide. +#define ICON_GAP 5 // Number of pixels between the icon and the text + +#define OFFSCREEN_ICON_POSITION_RADIUS 100 +#define BUTTON_FONT_HANDLE m_hCaptionFont + +#define ICON_DIST_TOO_FAR (60.0f * 12.0f) + +#define MIN_ICON_ALPHA 0.5 +#define MAX_ICON_ALPHA 1 + +ConVar locator_icon_min_size_non_ss( "locator_icon_min_size_non_ss", "1.0", FCVAR_NONE, "Minimum scale of the icon on the screen" ); +ConVar locator_icon_max_size_non_ss( "locator_icon_max_size_non_ss", "1.5", FCVAR_NONE, "Maximum scale of the icon on the screen" ); + +#define MIN_ICON_SCALE locator_icon_min_size_non_ss.GetFloat() +#define MAX_ICON_SCALE locator_icon_max_size_non_ss.GetFloat() + +#define LOCATOR_OCCLUSION_TEST_RATE 0.25f + +enum +{ + DRAW_ARROW_NO = 0, + DRAW_ARROW_UP, + DRAW_ARROW_DOWN, + DRAW_ARROW_LEFT, + DRAW_ARROW_RIGHT +}; + +ConVar locator_fade_time( "locator_fade_time", "0.3", FCVAR_NONE, "Number of seconds it takes for a lesson to fully fade in/out." ); +ConVar locator_lerp_speed( "locator_lerp_speed", "5.0f", FCVAR_NONE, "Speed that static lessons move along the Y axis." ); +ConVar locator_lerp_rest( "locator_lerp_rest", "2.25f", FCVAR_NONE, "Number of seconds before moving from the center." ); +ConVar locator_lerp_time( "locator_lerp_time", "1.75f", FCVAR_NONE, "Number of seconds to lerp before reaching final destination" ); +ConVar locator_pulse_time( "locator_pulse_time", "1.0f", FCVAR_NONE, "Number of seconds to pulse after changing icon or position" ); +ConVar locator_start_at_crosshair( "locator_start_at_crosshair", "0", FCVAR_NONE, "Start position at the crosshair instead of the top middle of the screen." ); + +ConVar locator_topdown_style( "locator_topdown_style", "0", FCVAR_NONE, "Topdown games set this to handle distance and offscreen location differently." ); + +ConVar locator_background_style( "locator_background_style", "0", FCVAR_NONE, "Setting this to 1 will show rectangle backgrounds behind the items word-bubble pointers." ); +ConVar locator_background_color( "locator_background_color", "255 255 255 5", FCVAR_NONE, "The default color for the background." ); +ConVar locator_background_border_color( "locator_background_border_color", "255 255 255 15", FCVAR_NONE, "The default color for the border." ); +ConVar locator_background_thickness_x( "locator_background_thickness_x", "8", FCVAR_NONE, "How many pixels the background borders the left and right." ); +ConVar locator_background_thickness_y( "locator_background_thickness_y", "0", FCVAR_NONE, "How many pixels the background borders the top and bottom." ); +ConVar locator_background_shift_x( "locator_background_shift_x", "3", FCVAR_NONE, "How many pixels the background is shifted right." ); +ConVar locator_background_shift_y( "locator_background_shift_y", "1", FCVAR_NONE, "How many pixels the background is shifted down." ); +ConVar locator_background_border_thickness( "locator_background_border_thickness", "3", FCVAR_NONE, "How many pixels the background borders the left and right." ); + +ConVar locator_target_offset_x( "locator_target_offset_x", "0", FCVAR_NONE, "How many pixels to offset the locator from the target position." ); +ConVar locator_target_offset_y( "locator_target_offset_y", "0", FCVAR_NONE, "How many pixels to offset the locator from the target position." ); + +ConVar locator_text_drop_shadow( "locator_text_drop_shadow", "1", FCVAR_NONE, "If enabled, a drop shadow is drawn behind caption text. PC only." ); +ConVar locator_text_glow( "locator_text_glow", "0", FCVAR_NONE, "If enabled, a glow is drawn behind caption text" ); +ConVar locator_text_glow_color( "locator_text_glow_color", "255 255 255 255", FCVAR_NONE, "Color of text glow" ); + +ConVar locator_split_maxwide_percent( "locator_split_maxwide_percent", "0.80f", FCVAR_CHEAT ); +ConVar locator_split_len( "locator_split_len", "0.5f", FCVAR_CHEAT ); + +#ifdef MAPBASE +extern ConVar gameinstructor_default_bindingcolor; +#endif + + +//------------------------------------ +CLocatorTarget::CLocatorTarget( void ) +{ + Deactivate( true ); + + PrecacheMaterial("vgui/hud/icon_arrow_left"); + PrecacheMaterial("vgui/hud/icon_arrow_right"); + PrecacheMaterial("vgui/hud/icon_arrow_up"); + PrecacheMaterial("vgui/hud/icon_arrow_down"); + PrecacheMaterial("vgui/hud/icon_arrow_plain"); +} + +//------------------------------------ +void CLocatorTarget::Activate( int serialNumber ) +{ + m_serialNumber = serialNumber; + m_frameLastUpdated = gpGlobals->framecount; + m_isActive = true; + + m_bVisible = true; + m_bOnscreen = true; + m_alpha = 0; + m_fadeStart = gpGlobals->curtime; + + m_offsetX = m_offsetY = 0; + + int iStartX = ScreenWidth() / 2; + int iStartY = ScreenHeight() / 4; + + // We want to start lessons at the players crosshair, cause that's where they're looking! + if ( locator_start_at_crosshair.GetBool() ) + vgui::input()->GetCursorPos( iStartX, iStartY ); + + m_lastXPos = iStartX; + m_lastYPos = iStartY; + + m_drawArrowDirection = DRAW_ARROW_NO; + m_lerpStart = gpGlobals->curtime; + m_pulseStart = gpGlobals->curtime; + m_declutterIndex = 0; + m_lastDeclutterIndex = 0; + + AddIconEffects(LOCATOR_ICON_FX_FADE_IN); + +#ifdef MAPBASE + // Mods are capable of using a custom binding color + CSplitString colorValues( gameinstructor_default_bindingcolor.GetString(), "," ); + + int r,g,b; + r = g = b = 0; + + if (colorValues.Count() == 3) + { + r = atoi( colorValues[0] ); + g = atoi( colorValues[1] ); + b = atoi( colorValues[2] ); + } + + m_bindingColor.SetColor( r, g, b, 255 ); +#endif +} + +//------------------------------------ +void CLocatorTarget::Deactivate( bool bNoFade ) +{ + if ( bNoFade || m_alpha == 0 || + ( m_bOccluded && !( m_iEffectsFlags & LOCATOR_ICON_FX_FORCE_CAPTION ) ) || + ( !m_bOnscreen && ( m_iEffectsFlags & LOCATOR_ICON_FX_NO_OFFSCREEN ) ) ) + { + m_bOriginInScreenspace = false; + + m_serialNumber = -1; + m_isActive = false; + m_frameLastUpdated = 0; + m_pIcon_onscreen = NULL; + m_pIcon_offscreen = NULL; + m_bDrawControllerButton = false; + m_bDrawControllerButtonOffscreen = false; + m_iEffectsFlags = LOCATOR_ICON_FX_NONE; + m_captionWide = 0; + + m_pchDrawBindingName = NULL; + m_pchDrawBindingNameOffscreen = NULL; + m_widthScale_onscreen = 1.0f; + m_bOccluded = false; + m_alpha = 0; + m_bIsDrawing = false; + m_bVisible = false; + + m_szVguiTargetName = ""; + m_szVguiTargetLookup = ""; + m_hVguiTarget = NULL; + m_nVguiTargetEdge = vgui::Label::a_northwest; + + m_szBinding = ""; + m_iBindingTick = 0; + m_flNextBindingTick = 0.0f; + m_flNextOcclusionTest = 0.0f; + m_iBindingChoicesCount = 0; + + m_wszCaption.RemoveAll(); + m_wszCaption.AddToTail( (wchar_t)0 ); + } + else if ( !( m_iEffectsFlags & LOCATOR_ICON_FX_FADE_OUT ) ) + { + // Determine home much time it would have spent fading to reach the current alpha + float flAssumedFadeTime; + flAssumedFadeTime = ( 1.0f - static_cast( m_alpha ) / 255.0f ) * locator_fade_time.GetFloat(); + + // Set the fade + m_fadeStart = gpGlobals->curtime - flAssumedFadeTime; + AddIconEffects( LOCATOR_ICON_FX_FADE_OUT ); + RemoveIconEffects( LOCATOR_ICON_FX_FADE_IN ); + } +} + +//------------------------------------ +void CLocatorTarget::Update() +{ + m_frameLastUpdated = gpGlobals->framecount; + + if ( m_bVisible && ( m_iEffectsFlags & LOCATOR_ICON_FX_FADE_OUT ) ) + { + // Determine home much time it would have spent fading to reach the current alpha + float flAssumedFadeTime; + flAssumedFadeTime = ( 1.0f - static_cast( m_alpha ) / 255.0f ) * locator_fade_time.GetFloat(); + + // Set the fade + m_fadeStart = gpGlobals->curtime - flAssumedFadeTime; + AddIconEffects( LOCATOR_ICON_FX_FADE_OUT ); + RemoveIconEffects( LOCATOR_ICON_FX_FADE_OUT ); + } +} + +int CLocatorTarget::GetIconX( void ) +{ + return m_iconX + ( IsOnScreen() ? locator_target_offset_x.GetInt()+m_offsetX : 0 ); +} + +int CLocatorTarget::GetIconY( void ) +{ + return m_iconY + ( IsOnScreen() ? locator_target_offset_y.GetInt()+m_offsetY : 0 ); +} + +int CLocatorTarget::GetIconCenterX( void ) +{ + return m_centerX + locator_target_offset_x.GetInt() + m_offsetX; +} + +int CLocatorTarget::GetIconCenterY( void ) +{ + return m_centerY + locator_target_offset_y.GetInt() + m_offsetY; +} + +void CLocatorTarget::SetVisible( bool bVisible ) +{ + // They are already the same + if ( m_bVisible == bVisible ) + return; + + m_bVisible = bVisible; + + if ( bVisible ) + { + // Determine home much time it would have spent fading to reach the current alpha + float flAssumedFadeTime; + flAssumedFadeTime = ( static_cast( m_alpha ) / 255.0f ) * locator_fade_time.GetFloat(); + + // Set the fade + m_fadeStart = gpGlobals->curtime - flAssumedFadeTime; + AddIconEffects( LOCATOR_ICON_FX_FADE_IN ); + RemoveIconEffects( LOCATOR_ICON_FX_FADE_OUT ); + } + else + { + // Determine home much time it would have spent fading to reach the current alpha + float flAssumedFadeTime; + flAssumedFadeTime = ( 1.0f - static_cast( m_alpha ) / 255.0f ) * locator_fade_time.GetFloat(); + + // Set the fade + m_fadeStart = gpGlobals->curtime - flAssumedFadeTime; + AddIconEffects( LOCATOR_ICON_FX_FADE_OUT ); + RemoveIconEffects( LOCATOR_ICON_FX_FADE_IN ); + } +} + +bool CLocatorTarget::IsVisible( void ) +{ + return m_bVisible; +} + +void CLocatorTarget::SetCaptionText( const char *pszText, const char *pszParam ) +{ + wchar_t outbuf[ 256 ]; + outbuf[ 0 ] = L'\0'; + + if ( pszParam && pszParam[ 0 ] != '\0' ) + { + wchar_t wszParamBuff[ 128 ]; + wchar_t *pLocalizedParam = NULL; + + if ( pszParam[ 0 ] == '#' ) + { + pLocalizedParam = g_pVGuiLocalize->Find( pszParam ); + } + + if ( !pLocalizedParam ) + { + g_pVGuiLocalize->ConvertANSIToUnicode( pszParam, wszParamBuff, sizeof( wszParamBuff ) ); + pLocalizedParam = wszParamBuff; + } + + wchar_t wszTextBuff[ 128 ]; + wchar_t *pLocalizedText = NULL; + + if ( pszText[ 0 ] == '#' ) + pLocalizedText = g_pVGuiLocalize->Find( pszText ); + + if ( !pLocalizedText ) + { + g_pVGuiLocalize->ConvertANSIToUnicode( pszText, wszTextBuff, sizeof( wszTextBuff ) ); + pLocalizedText = wszTextBuff; + } + + wchar_t buf[ 256 ]; + g_pVGuiLocalize->ConstructString( buf, sizeof(buf), pLocalizedText, 1, pLocalizedParam ); + + UTIL_ReplaceKeyBindings( buf, sizeof( buf ), outbuf, sizeof( outbuf ) ); + } + else + { + wchar_t wszTextBuff[ 128 ]; + wchar_t *pLocalizedText = NULL; + + if ( pszText[ 0 ] == '#' ) + { + pLocalizedText = g_pVGuiLocalize->Find( pszText ); + } + + if ( !pLocalizedText ) + { + g_pVGuiLocalize->ConvertANSIToUnicode( pszText, wszTextBuff, sizeof( wszTextBuff ) ); + pLocalizedText = wszTextBuff; + } + + wchar_t buf[ 256 ]; + Q_wcsncpy( buf, pLocalizedText, sizeof( buf ) ); + + UTIL_ReplaceKeyBindings( buf, sizeof(buf), outbuf, sizeof( outbuf ) ); + } + + int len = wcslen( outbuf ) + 1; + m_wszCaption.RemoveAll(); + m_wszCaption.EnsureCount( len ); + Q_wcsncpy( m_wszCaption.Base(), outbuf, len * sizeof( wchar_t ) ); +} + +void CLocatorTarget::SetCaptionColor( const char *pszCaptionColor ) +{ + int r,g,b; + r = g = b = 0; + + CSplitString colorValues( pszCaptionColor, "," ); + + if( colorValues.Count() == 3 ) + { + r = atoi( colorValues[0] ); + g = atoi( colorValues[1] ); + b = atoi( colorValues[2] ); + + m_captionColor.SetColor( r,g,b, 255 ); + } + else + { + DevWarning( "caption_color format incorrect. RRR,GGG,BBB expected.\n"); + } +} + +bool CLocatorTarget::IsStatic() +{ + return ( ( m_iEffectsFlags & LOCATOR_ICON_FX_STATIC ) || IsPresenting() ); +} + +bool CLocatorTarget::IsPresenting() +{ + return ( gpGlobals->curtime - m_lerpStart < locator_lerp_rest.GetFloat() ); +} + +void CLocatorTarget::StartTimedLerp() +{ + if ( gpGlobals->curtime - m_lerpStart > locator_lerp_rest.GetFloat() ) + { + m_lerpStart = gpGlobals->curtime - locator_lerp_rest.GetFloat(); + } +} + +void CLocatorTarget::StartPresent() +{ + m_lerpStart = gpGlobals->curtime; +} + + +void CLocatorTarget::EndPresent() +{ + if ( gpGlobals->curtime - m_lerpStart < locator_lerp_rest.GetFloat() ) + { + m_lerpStart = gpGlobals->curtime - locator_lerp_rest.GetFloat(); + } +} + +void CLocatorTarget::UpdateVguiTarget( void ) +{ + const char *pchVguiTargetName = m_szVguiTargetName.String(); + + if ( !pchVguiTargetName || pchVguiTargetName[ 0 ] == '\0' ) + { + m_hVguiTarget = NULL; + return; + } + + // Get the appropriate token based on the binding + if ( m_iBindingChoicesCount > 0 ) + { + int nTagetToken = m_iBindChoicesOriginalToken[ m_iBindingTick % m_iBindingChoicesCount ]; + + for ( int nToken = 0; nToken < nTagetToken && pchVguiTargetName; ++nToken ) + { + pchVguiTargetName = strchr( pchVguiTargetName, ';' ); + + if ( pchVguiTargetName ) + { + pchVguiTargetName++; + } + } + + if ( !pchVguiTargetName || pchVguiTargetName[ 0 ] == '\0' ) + { + // There wasn't enough tokens, just use the first + pchVguiTargetName = m_szVguiTargetName.String(); + } + } + + m_hVguiTarget = g_pClientMode->GetViewport(); +} + +void CLocatorTarget::SetVguiTargetName( const char *pchVguiTargetName ) +{ + if ( Q_strcmp( m_szVguiTargetName.String(), pchVguiTargetName ) == 0 ) + return; + + m_szVguiTargetName = pchVguiTargetName; + + UpdateVguiTarget(); +} + +void CLocatorTarget::SetVguiTargetLookup( const char *pchVguiTargetLookup ) +{ + m_szVguiTargetLookup = pchVguiTargetLookup; +} + +void CLocatorTarget::SetVguiTargetEdge( int nVguiEdge ) +{ + m_nVguiTargetEdge = nVguiEdge; +} + +vgui::Panel *CLocatorTarget::GetVguiTarget( void ) +{ + return (vgui::Panel *)m_hVguiTarget.Get(); +} + +//------------------------------------ +void CLocatorTarget::SetOnscreenIconTextureName( const char *pszTexture ) +{ + if ( Q_strcmp( m_szOnscreenTexture.String(), pszTexture ) == 0 ) + return; + + m_szOnscreenTexture = pszTexture; + m_pIcon_onscreen = NULL; // Dirty the onscreen icon so that the Locator will look up the new icon by name. + m_pulseStart = gpGlobals->curtime; +} + +//------------------------------------ +void CLocatorTarget::SetOffscreenIconTextureName( const char *pszTexture ) +{ + if ( Q_strcmp( m_szOffscreenTexture.String(), pszTexture ) == 0 ) + return; + + m_szOffscreenTexture = pszTexture; + m_pIcon_offscreen = NULL; // Ditto + m_pulseStart = gpGlobals->curtime; +} + +//------------------------------------ +void CLocatorTarget::SetBinding( const char *pszBinding ) +{ + int iAllowJoystick = -1; + + /*if ( !IsX360() ) + { + // Only show joystick binds if it's enabled and non-joystick if it's disabled + iAllowJoystick = input->ControllerModeActive(); + }*/ + + bool bIsControllerNow = ( iAllowJoystick != 0 ); + + if ( m_bWasControllerLast == bIsControllerNow ) + { + // We haven't toggled joystick enabled recently, so if it's the same bind, bail + if ( Q_strcmp( m_szBinding.String(), pszBinding ) == 0 ) + return; + } + + m_bWasControllerLast = bIsControllerNow; + + m_szBinding = pszBinding; + m_pIcon_onscreen = NULL; // Dirty the onscreen icon so that the Locator will look up the new icon by name. + m_pIcon_offscreen = NULL; // ditto. + m_flNextBindingTick = gpGlobals->curtime + 0.75f; + + // Get a list of all the keys bound to these actions + m_iBindingChoicesCount = 0; + + // Tokenize the binding name (could be more than one binding) + int nOriginalToken = 0; + const char *pchToken = m_szBinding.String(); + char szToken[ 128 ]; + + pchToken = nexttoken( szToken, pchToken, ';', sizeof( szToken ) ); + + while ( pchToken ) + { + // Get the first parameter + int iTokenBindingCount = 0; + const char *pchBinding = engine->Key_LookupBindingExact( szToken ); + + while ( m_iBindingChoicesCount < MAX_LOCATOR_BINDINGS_SHOWN && pchBinding ) + { + m_pchBindingChoices[ m_iBindingChoicesCount ] = pchBinding; + m_iBindChoicesOriginalToken[ m_iBindingChoicesCount ] = nOriginalToken; + ++m_iBindingChoicesCount; + ++iTokenBindingCount; + + pchBinding = engine->Key_LookupBindingExact( szToken ); + } + + nOriginalToken++; + pchToken = nexttoken( szToken, pchToken, ';', sizeof( szToken ) ); + } + + m_pulseStart = gpGlobals->curtime; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const char *CLocatorTarget::UseBindingImage( char *pchIconTextureName, size_t bufSize ) +{ + if ( m_iBindingChoicesCount <= 0 ) + { + if ( IsX360() ) + { + Q_strncpy( pchIconTextureName, "icon_blank", bufSize ); + } + else + { + Q_strncpy( pchIconTextureName, "icon_key_wide", bufSize ); + return "#GameUI_Icons_NONE"; + } + + return NULL; + } + + // Cycle through the list of binds at a rate of 2 per second + const char *pchBinding = m_pchBindingChoices[ m_iBindingTick % m_iBindingChoicesCount ]; + + // We counted at least one binding... this should not be NULL! + Assert( pchBinding ); + + if ( IsX360() ) + { + // Use a blank background for the button icons + Q_strncpy( pchIconTextureName, "icon_blank", bufSize ); + return pchBinding; + } + + /*if ( input->ControllerModeActive() && + ( Q_strcmp( pchBinding, "A_BUTTON" ) == 0 || + Q_strcmp( pchBinding, "B_BUTTON" ) == 0 || + Q_strcmp( pchBinding, "X_BUTTON" ) == 0 || + Q_strcmp( pchBinding, "Y_BUTTON" ) == 0 || + Q_strcmp( pchBinding, "L_SHOULDER" ) == 0 || + Q_strcmp( pchBinding, "R_SHOULDER" ) == 0 || + Q_strcmp( pchBinding, "L_TRIGGER" ) == 0 || + Q_strcmp( pchBinding, "R_TRIGGER" ) == 0 || + Q_strcmp( pchBinding, "BACK" ) == 0 || + Q_strcmp( pchBinding, "START" ) == 0 || + Q_strcmp( pchBinding, "STICK1" ) == 0 || + Q_strcmp( pchBinding, "STICK2" ) == 0 || + Q_strcmp( pchBinding, "UP" ) == 0 || + Q_strcmp( pchBinding, "DOWN" ) == 0 || + Q_strcmp( pchBinding, "LEFT" ) == 0 || + Q_strcmp( pchBinding, "RIGHT" ) == 0 ) ) + { + // Use a blank background for the button icons + Q_strncpy( pchIconTextureName, "icon_blank", bufSize ); + return pchBinding; + }*/ + + if ( Q_strcmp( pchBinding, "MOUSE1" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_mouseLeft", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "MOUSE2" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_mouseRight", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "MOUSE3" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_mouseThree", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "MWHEELUP" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_mouseWheel_up", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "MWHEELDOWN" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_mouseWheel_down", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "UPARROW" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_key_up", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "LEFTARROW" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_key_left", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "DOWNARROW" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_key_down", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "RIGHTARROW" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_key_right", bufSize ); + return NULL; + } + else if ( Q_strcmp( pchBinding, "SEMICOLON" ) == 0 || + Q_strcmp( pchBinding, "INS" ) == 0 || + Q_strcmp( pchBinding, "DEL" ) == 0 || + Q_strcmp( pchBinding, "HOME" ) == 0 || + Q_strcmp( pchBinding, "END" ) == 0 || + Q_strcmp( pchBinding, "PGUP" ) == 0 || + Q_strcmp( pchBinding, "PGDN" ) == 0 || + Q_strcmp( pchBinding, "PAUSE" ) == 0 || + Q_strcmp( pchBinding, "F10" ) == 0 || + Q_strcmp( pchBinding, "F11" ) == 0 || + Q_strcmp( pchBinding, "F12" ) == 0 ) + { + Q_strncpy( pchIconTextureName, "icon_key_generic", bufSize ); + return pchBinding; + } + else if ( Q_strlen( pchBinding ) <= 2 ) + { + Q_strncpy( pchIconTextureName, "icon_key_generic", bufSize ); + return pchBinding; + } + else if ( Q_strlen( pchBinding ) <= 6 ) + { + Q_strncpy( pchIconTextureName, "icon_key_wide", bufSize ); + return pchBinding; + } + else + { + Q_strncpy( pchIconTextureName, "icon_key_wide", bufSize ); + return pchBinding; + } + + return pchBinding; +} + +//----------------------------------------------------------------------------- +int CLocatorTarget::GetIconWidth( void ) +{ + return m_wide; +} + +//----------------------------------------------------------------------------- +int CLocatorTarget::GetIconHeight( void ) +{ + return m_tall; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CLocatorPanel : public vgui::EditablePanel +{ + DECLARE_CLASS_SIMPLE( CLocatorPanel, vgui::EditablePanel ); +public: + CLocatorPanel( vgui::Panel *parent, const char *name ); + ~CLocatorPanel( void ); + + virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); + virtual void PerformLayout( void ); + virtual void OnTick( void ); + virtual void PaintBackground( void ); + virtual void Paint( void ); + void ValidateTexture( int *pTextureID, const char *pszTextureName ); + bool ValidateTargetTextures( CLocatorTarget *pTarget ); + bool IconsAreIntersecting( CLocatorTarget &first, CLocatorTarget &second, int iTolerance ); + virtual void PaintTarget( CLocatorTarget *pTarget ); + + void DrawPointerBackground( CLocatorTarget *pTarget, int nPointerX, int nPointerY, int nWide, int nTall, bool bPointer ); + void DrawStaticIcon( CLocatorTarget *pTarget ); + void DrawDynamicIcon( CLocatorTarget *pTarget, bool bDrawCaption, bool bDrawSimpleArrow ); + void DrawIndicatorArrow( int x, int y, int iconWide, int iconTall, int textWidth, int direction ); + void DrawTargetCaption( CLocatorTarget *pTarget, int x, int y, bool bDrawMultiline ); + int GetScreenWidthForCaption( const wchar_t *pString, vgui::HFont hFont ); + void DrawBindingName( CLocatorTarget *pTarget, const char *pchBindingName, int x, int y, bool bController ); + void ComputeTargetIconPosition( CLocatorTarget *pTarget, bool bSetPosition ); + void CalculateOcclusion( CLocatorTarget *pTarget ); + + void DrawSimpleArrow( int x, int y, int iconWide, int iconTall ); + void GetIconPositionForOffscreenTarget( const Vector &vecDelta, float flDist, int *pXPos, int *pYPos ); + + CLocatorTarget *GetPointerForHandle( int hTarget ); + int AddTarget(); + void RemoveTarget( int hTarget ); + + void GetTargetPosition( const Vector &vecDelta, float flRadius, float *xpos, float *ypos, float *flRotation ); + + void DeactivateAllTargets(); + void CollectGarbage(); + + // Animation + void AnimateIconSize( int flags, int *wide, int *tall, float fPulseStart ); + void AnimateIconPosition( int flags, int *x, int *y ); + void AnimateIconAlpha( int flags, int *alpha, float fadeStart ); + +private: + + CPanelAnimationVar( vgui::HFont, m_hCaptionFont, "font", "InstructorTitle" ); + CPanelAnimationVar( vgui::HFont, m_hCaptionFont_ss, "font", "InstructorTitle_ss" ); + CPanelAnimationVar( vgui::HFont, m_hCaptionGlowFont, "font", "InstructorTitleGlow" ); + CPanelAnimationVar( vgui::HFont, m_hCaptionGlowFont_ss, "font", "InstructorTitleGlow_ss" ); + + CPanelAnimationVar( vgui::HFont, m_hButtonFont, "font", "InstructorButtons" ); + + CPanelAnimationVar( vgui::HFont, m_hButtonFont_ss, "font", "InstructorButtons_ss" ); + CPanelAnimationVar( vgui::HFont, m_hKeysFont, "font", "InstructorKeyBindings" ); + + + CPanelAnimationVar( int, m_iShouldWrapStaticLocators, "WrapStaticLocators", "0" ); + + static int m_serializer; // Used to issue unique serial numbers to targets, for use as handles + int m_textureID_ArrowRight; + int m_textureID_ArrowLeft; + int m_textureID_ArrowUp; + int m_textureID_ArrowDown; + int m_textureID_SimpleArrow; + + int m_staticIconPosition;// Helps us stack static icons + + CLocatorTarget m_targets[MAX_LOCATOR_TARGETS]; +}; + +//----------------------------------------------------------------------------- +// Local variables +//----------------------------------------------------------------------------- +static CLocatorPanel *s_pLocatorPanel; + +inline CLocatorPanel * GetPlayerLocatorPanel() +{ + //if ( !engine->IsLocalPlayerResolvable() ) + //return NULL; + + Assert( s_pLocatorPanel ); + return s_pLocatorPanel; +} + + +//----------------------------------------------------------------------------- +// Static variable initialization +//----------------------------------------------------------------------------- +int CLocatorPanel::m_serializer = 1000; // Serial numbers start at 1000 + +//----------------------------------------------------------------------------- +// This is the interface function that other systems use to send us targets +//----------------------------------------------------------------------------- +int Locator_AddTarget() +{ + if( s_pLocatorPanel == NULL ) + { + // Locator has not been used yet. Construct it. + CLocatorPanel *pLocator = new CLocatorPanel( g_pClientMode->GetViewport(), "LocatorPanel" ); + vgui::SETUP_PANEL(pLocator); + pLocator->SetBounds( 0, 0, ScreenWidth(), ScreenHeight() ); + pLocator->SetPos( 0, 0 ); + pLocator->SetVisible( true ); + vgui::ivgui()->AddTickSignal( pLocator->GetVPanel() ); + } + + Assert( s_pLocatorPanel != NULL ); + return s_pLocatorPanel ? s_pLocatorPanel->AddTarget() : -1; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void Locator_RemoveTarget( int hTarget ) +{ + if ( CLocatorPanel *pPanel = GetPlayerLocatorPanel() ) + pPanel->RemoveTarget( hTarget ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CLocatorTarget *Locator_GetTargetFromHandle( int hTarget ) +{ + if ( CLocatorPanel *pPanel = GetPlayerLocatorPanel() ) + return pPanel->GetPointerForHandle( hTarget ); + else + return NULL; +} + +void Locator_ComputeTargetIconPositionFromHandle( int hTarget ) +{ + if ( CLocatorPanel *pPanel = GetPlayerLocatorPanel() ) + { + if ( CLocatorTarget *pTarget = pPanel->GetPointerForHandle( hTarget ) ) + { + if( !( pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_STATIC ) ) + { + // It's not presenting in the middle of the screen, so figure out it's position + pPanel->ComputeTargetIconPosition( pTarget, !pTarget->IsPresenting() ); + pPanel->CalculateOcclusion( pTarget ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CLocatorPanel::CLocatorPanel( Panel *parent, const char *name ) : EditablePanel(parent,name) +{ + Assert( s_pLocatorPanel == NULL ); + DeactivateAllTargets(); + + s_pLocatorPanel = this; + m_textureID_ArrowRight = -1; + m_textureID_ArrowLeft = -1; + m_textureID_ArrowUp = -1; + m_textureID_ArrowDown = -1; + m_textureID_SimpleArrow = -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CLocatorPanel::~CLocatorPanel( void ) +{ + Assert( s_pLocatorPanel == this ); + s_pLocatorPanel = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Applies scheme settings +//----------------------------------------------------------------------------- +void CLocatorPanel::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + LoadControlSettings("resource/UI/Locator.res"); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLocatorPanel::PerformLayout( void ) +{ + BaseClass::PerformLayout(); + + vgui::Panel *pPanel = FindChildByName( "LocatorBG" ); + + if ( pPanel ) + pPanel->SetPos( (GetWide() - pPanel->GetWide()) * 0.5, (GetTall() - pPanel->GetTall()) * 0.5 ); +} + +//----------------------------------------------------------------------------- +// Purpose: Given an offscreen target position, compute the 'compass position' +// so that we can draw an icon on the imaginary circle around the crosshair +// that indicates which way the player should turn to bring the target into view. +//----------------------------------------------------------------------------- +void CLocatorPanel::GetTargetPosition( const Vector &vecDelta, float flRadius, float *xpos, float *ypos, float *flRotation ) +{ + // Player Data + Vector playerPosition = MainViewOrigin(); + QAngle playerAngles = MainViewAngles(); + + Vector forward, right, up(0,0,1); + AngleVectors (playerAngles, &forward, NULL, NULL ); + forward.z = 0; + VectorNormalize(forward); + CrossProduct( up, forward, right ); + float front = DotProduct(vecDelta, forward); + float side = DotProduct(vecDelta, right); + *xpos = flRadius * -side; + *ypos = flRadius * -front; + + // Get the rotation (yaw) + *flRotation = atan2(*xpos,*ypos) + M_PI; + *flRotation *= 180 / M_PI; + + float yawRadians = -(*flRotation) * M_PI / 180.0f; + float ca = cos( yawRadians ); + float sa = sin( yawRadians ); + + // Rotate it around the circle, squash Y to make an oval rather than a circle + *xpos = (int)((ScreenWidth() / 2) + (flRadius * sa)); + *ypos = (int)((ScreenHeight() / 2) - (flRadius * 0.6f * ca)); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLocatorPanel::DeactivateAllTargets() +{ + for( int i = 0 ; i < MAX_LOCATOR_TARGETS ; i++ ) + m_targets[ i ].Deactivate( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: Deactivate any target that has not been updated within several frames +//----------------------------------------------------------------------------- +void CLocatorPanel::CollectGarbage() +{ + for( int i = 0 ; i < MAX_LOCATOR_TARGETS ; i++ ) + { + if( m_targets[ i ].m_isActive ) + { + if( gpGlobals->framecount - m_targets[ i ].m_frameLastUpdated > 20 ) + m_targets[ i ].Deactivate(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Provide simple animation by modifying the width and height of the +// icon before it is drawn. +//----------------------------------------------------------------------------- +void CLocatorPanel::AnimateIconSize( int flags, int *wide, int *tall, float fPulseStart ) +{ + float flScale = MIN_ICON_SCALE; + float scaleDelta = MAX_ICON_SCALE - MIN_ICON_SCALE; + + float newWide = *wide; + float newTall = *tall; + + if( flags & LOCATOR_ICON_FX_PULSE_SLOW || gpGlobals->curtime - fPulseStart < locator_pulse_time.GetFloat() ) + { + flScale += scaleDelta * fabs( sin( ( gpGlobals->curtime - fPulseStart ) * M_PI ) ); + } + else if( flags & LOCATOR_ICON_FX_PULSE_FAST ) + { + flScale += scaleDelta * fabs( sin( gpGlobals->curtime * 2 * M_PI ) ); + } + else if( flags & LOCATOR_ICON_FX_PULSE_URGENT ) + { + flScale += scaleDelta * fabs( sin( gpGlobals->curtime * 4 * M_PI ) ); + } + + if ( newWide > newTall ) + { + // Get scale to make width change by only the standard height amount of pixels + int iHeightDelta = (int)(newTall * flScale - newTall); + flScale = ( newWide + iHeightDelta ) / newWide; + } + + newWide = newWide * flScale; + newTall = newTall * flScale; + + *wide = newWide; + *tall = newTall; +} + +//----------------------------------------------------------------------------- +// Purpose: Modify the alpha of the icon before it is drawn. +//----------------------------------------------------------------------------- +void CLocatorPanel::AnimateIconAlpha( int flags, int *alpha, float fadeStart ) +{ + float flScale = MIN_ICON_ALPHA; + float scaleDelta = MAX_ICON_ALPHA - MIN_ICON_ALPHA; + + if( flags & LOCATOR_ICON_FX_ALPHA_SLOW ) + { + flScale += scaleDelta * fabs( sin( gpGlobals->curtime * 3 ) ); + } + else if( flags & LOCATOR_ICON_FX_ALPHA_FAST ) + { + flScale += scaleDelta * fabs( sin( gpGlobals->curtime * 7 ) ); + } + else if( flags & LOCATOR_ICON_FX_ALPHA_URGENT ) + { + flScale += scaleDelta * fabs( sin( gpGlobals->curtime * 10 ) ); + } + else + { + flScale = MAX_ICON_ALPHA; + } + + if ( flags & LOCATOR_ICON_FX_FADE_OUT ) + { + flScale *= MAX( 0.0f, ( locator_fade_time.GetFloat() - ( gpGlobals->curtime - fadeStart ) ) / locator_fade_time.GetFloat() ); + } + else if ( flags & LOCATOR_ICON_FX_FADE_IN ) + { + flScale *= MAX_ICON_ALPHA - MAX( 0.0f, ( locator_fade_time.GetFloat() - ( gpGlobals->curtime - fadeStart ) ) / locator_fade_time.GetFloat() ); + } + + *alpha = static_cast( 255.0f * flScale ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLocatorPanel::AnimateIconPosition( int flags, int *x, int *y ) +{ + int newX = *x; + int newY = *y; + + if( flags & LOCATOR_ICON_FX_SHAKE_NARROW ) + { + newX += RandomInt( -2, 2 ); + newY += RandomInt( -2, 2 ); + } + else if( flags & LOCATOR_ICON_FX_SHAKE_WIDE ) + { + newX += RandomInt( -5, 5 ); + newY += RandomInt( -5, 5 ); + } + + *x = newX; + *y = newY; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLocatorPanel::OnTick( void ) +{ + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLocatorPanel::PaintBackground( void ) +{ + return; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLocatorPanel::Paint( void ) +{ + ValidateTexture( &m_textureID_ArrowLeft, "vgui/hud/icon_arrow_left" ); + ValidateTexture( &m_textureID_ArrowRight, "vgui/hud/icon_arrow_right" ); + ValidateTexture( &m_textureID_ArrowUp, "vgui/hud/icon_arrow_up" ); + ValidateTexture( &m_textureID_ArrowDown, "vgui/hud/icon_arrow_down" ); + ValidateTexture( &m_textureID_SimpleArrow, "vgui/hud/icon_arrow_plain" ); + + // reset the static icon position. This is the y position at which the first + // static icon will be drawn. This value will be incremented by the height of + // each static icon drawn, which forces the next static icon to be drawn below + // the previous one, creating a little fixed, vertical stack below the crosshair. + m_staticIconPosition = ScreenHeight() / 6; + + // Time now to draw the 'dynamic' icons, the icons which help players locate things + // in actual world space. + + //---------- + // Batch 1 + // Go through all of the active locator targets and compute where to draw the icons + // that represent each of them. This builds a poor man's draw list by updating the + // m_iconX, m_iconY members of each locator target. + CUtlVectorFixed< CLocatorTarget *, MAX_LOCATOR_TARGETS > vecValid; + + for( int i = 0 ; i < MAX_LOCATOR_TARGETS ; i++ ) + { + CLocatorTarget *pLocatorTarget = &(m_targets[ i ]); + + // Reset drawing state for this frame... set back to true when it's finally draws + pLocatorTarget->m_bIsDrawing = false; + + if ( ( !pLocatorTarget->m_bVisible && !pLocatorTarget->m_alpha ) || !pLocatorTarget->m_isActive ) + { + // Don't want to be visible and have finished fading + continue; + } + + vecValid.AddToTail( pLocatorTarget ); + + // This prevents an error that if a locator was fading as the map transitioned + pLocatorTarget->m_fadeStart = fpmin( pLocatorTarget->m_fadeStart, gpGlobals->curtime ); + + if( !( pLocatorTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_STATIC ) ) + { + // It's not presenting in the middle of the screen, so figure out it's position + ComputeTargetIconPosition( pLocatorTarget, !pLocatorTarget->IsPresenting() ); + CalculateOcclusion( pLocatorTarget ); + + pLocatorTarget->m_lastDeclutterIndex = pLocatorTarget->m_declutterIndex; + pLocatorTarget->m_declutterIndex = 0; + } + } + + //---------- + // Batch 2 + // Now that we know where each icon _wants_ to be drawn, we grovel through them and + // push apart any icons that are too close to one another. This helps to unclutter + // the display and ensure the maximum number of legible icons and captions. Obviously + // this process changes where some icons will be drawn. Bubble sort, but tiny data set. + int iTolerance = 1.25 * (ScreenWidth() * ICON_SIZE); + int iterations = 0;// Count iterations, don't go infinite in the event of some weird case. + bool bStillUncluttering = true; + static int MAX_UNCLUTTER_ITERATIONS = 10; + while( iterations < MAX_UNCLUTTER_ITERATIONS && bStillUncluttering ) + { + iterations++; + bStillUncluttering = false; + + for( int i = 0 ; i < vecValid.Count() ; ++i ) + { + CLocatorTarget *pLocatorTarget1 = vecValid[ i ]; + + for( int j = i + 1 ; j < vecValid.Count() ; ++j ) + { + CLocatorTarget *pLocatorTarget2 = vecValid[ j ]; + + // Don't attempt to declutter icons if one or both is attempting to fade out + bool bLocatorsFullyActive = !((pLocatorTarget1->GetIconEffectsFlags()|pLocatorTarget2->GetIconEffectsFlags()) & LOCATOR_ICON_FX_FADE_OUT); + + if ( bLocatorsFullyActive && IconsAreIntersecting( *pLocatorTarget1, *pLocatorTarget2, iTolerance ) ) + { + // Unclutter. Lift whichever icon is highest a bit higher + if( pLocatorTarget1->m_iconY < pLocatorTarget2->m_iconY ) + { + pLocatorTarget1->m_iconY = pLocatorTarget2->m_iconY - iTolerance; + pLocatorTarget1->m_centerY = pLocatorTarget2->m_centerY - iTolerance; + pLocatorTarget1->m_declutterIndex -= 1; + } + else + { + pLocatorTarget2->m_iconY = pLocatorTarget1->m_iconY - iTolerance; + pLocatorTarget2->m_centerY = pLocatorTarget1->m_centerY - iTolerance; + pLocatorTarget2->m_declutterIndex -= 1; + } + + bStillUncluttering = true; + } + } + } + } + + if( iterations == MAX_UNCLUTTER_ITERATIONS ) + { + DevWarning( "Game instructor hit MAX_UNCLUTTER_ITERATIONS!\n"); + } + + float flLocatorLerpRest = locator_lerp_rest.GetFloat(); + float flLocatorLerpTime = locator_lerp_time.GetFloat(); + + //---------- + // Batch 3 + // Draw each of the icons. + for( int i = 0 ; i < vecValid.Count() ; i++ ) + { + CLocatorTarget *pLocatorTarget = vecValid[ i ]; + // Back to lerping for these guys + if ( pLocatorTarget->m_lastDeclutterIndex != pLocatorTarget->m_declutterIndex ) + { + // It wants to be popped to another position... do it smoothly + pLocatorTarget->StartTimedLerp(); + } + + // Lerp to the desired position + float flLerpTime = gpGlobals->curtime - pLocatorTarget->m_lerpStart; + + if ( flLerpTime >= flLocatorLerpRest && flLerpTime < flLocatorLerpRest + flLocatorLerpTime ) + { + // Lerp slow to fast + float fInterp = 1.0f - ( ( flLocatorLerpTime - ( flLerpTime - flLocatorLerpRest ) ) / flLocatorLerpTime ); + + // Get our desired position + float iconX = pLocatorTarget->m_iconX; + float iconY = pLocatorTarget->m_iconY; + + // Get the distance we need to go to reach it + float diffX = fabsf( pLocatorTarget->m_iconX - pLocatorTarget->m_lastXPos ); + float diffY = fabsf( pLocatorTarget->m_iconY - pLocatorTarget->m_lastYPos ); + + // Go from our current position toward the desired position as quick as the interp allows + pLocatorTarget->m_iconX = static_cast( Approach( iconX, pLocatorTarget->m_lastXPos, diffX * fInterp ) ); + pLocatorTarget->m_iconY = static_cast( Approach( iconY, pLocatorTarget->m_lastYPos, diffY * fInterp ) ); + + // Get how much our position changed and apply it to the center values + int iOffsetX = pLocatorTarget->m_iconX - iconX; + int iOffsetY = pLocatorTarget->m_iconY - iconY; + + pLocatorTarget->m_centerX += iOffsetX; + pLocatorTarget->m_centerY += iOffsetY; + + if ( iOffsetX < 3 && iOffsetY < 3 ) + { + // Near our target! Stop lerping! + flLerpTime = flLocatorLerpRest + flLocatorLerpTime; + } + } + + PaintTarget( pLocatorTarget ); + } + + CollectGarbage(); +} + +//----------------------------------------------------------------------------- +// Purpose: A helper function to save on typing. Make sure our texture ID's +// stay valid. +//----------------------------------------------------------------------------- +void CLocatorPanel::ValidateTexture( int *pTextureID, const char *pszTextureName ) +{ + if( *pTextureID == -1 ) + { + *pTextureID = vgui::surface()->CreateNewTextureID(); + vgui::surface()->DrawSetTextureFile( *pTextureID, pszTextureName, true, false ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Called every frame before painting the targets. Ensures that the +// target's textures are properly cached. +//----------------------------------------------------------------------------- +bool CLocatorPanel::ValidateTargetTextures( CLocatorTarget *pTarget ) +{ + bool bBindingTick = false; + + if ( gpGlobals->curtime >= pTarget->m_flNextBindingTick ) + { + if ( pTarget->m_iBindingChoicesCount > 1 ) + { + bBindingTick = true; + pTarget->m_iBindingTick++; + } + + pTarget->m_flNextBindingTick = gpGlobals->curtime + 0.75f; + + pTarget->UpdateVguiTarget(); + } + + bool bUsesBinding = ( Q_stricmp( pTarget->GetOnscreenIconTextureName(), "use_binding" ) == 0 ); + + if( !pTarget->m_pIcon_onscreen || !pTarget->m_pIcon_offscreen || ( bUsesBinding && bBindingTick ) ) + { + char szIconTextureName[ 256 ]; + if ( bUsesBinding ) + { + const char *pchDrawBindingName = pTarget->UseBindingImage( szIconTextureName, sizeof( szIconTextureName ) ); + pTarget->m_bDrawControllerButton = ( Q_strcmp( szIconTextureName, "icon_blank" ) == 0 ); + + pTarget->DrawBindingName( pchDrawBindingName ); + } + else + { + pTarget->m_bDrawControllerButton = false; + Q_strcpy( szIconTextureName, pTarget->GetOnscreenIconTextureName() ); + pTarget->DrawBindingName( NULL ); + } + + // This target's texture ID is dirty, meaning the target is about to be drawn + // for the first time, or about to be drawn for the first time since a texture + // was changed. + if ( Q_strlen(szIconTextureName) == 0 ) + { + DevWarning("Locator Target has no onscreen texture name!\n"); + return false; + } + else + { + pTarget->m_pIcon_onscreen = HudIcons().GetIcon( szIconTextureName ); + if ( pTarget->m_pIcon_onscreen ) + { + pTarget->m_widthScale_onscreen = static_cast< float >( pTarget->m_pIcon_onscreen->Width() ) / pTarget->m_pIcon_onscreen->Height(); + } + else + { + pTarget->m_widthScale_onscreen = 1.0f; + } + } + + if ( Q_stricmp( pTarget->GetOffscreenIconTextureName() , "use_binding" ) == 0 ) + { + const char *pchDrawBindingName = pTarget->UseBindingImage( szIconTextureName, sizeof( szIconTextureName ) ); + pTarget->m_bDrawControllerButtonOffscreen = ( Q_strcmp( szIconTextureName, "icon_blank" ) == 0 ); + + pTarget->DrawBindingNameOffscreen( pchDrawBindingName ); + } + else + { + pTarget->m_bDrawControllerButtonOffscreen = false; + Q_strcpy( szIconTextureName, pTarget->GetOffscreenIconTextureName() ); + pTarget->DrawBindingNameOffscreen( NULL ); + } + + if( Q_strlen(szIconTextureName) == 0 ) + { + if( !pTarget->m_pIcon_onscreen ) + { + DevWarning("Locator Target has no offscreen texture name and can't fall back!\n"); + } + else + { + // The onscreen texture is valid, so default behavior is to use that. + pTarget->m_pIcon_offscreen = pTarget->m_pIcon_onscreen; + const char *pchDrawBindingName = pTarget->DrawBindingName(); + pTarget->DrawBindingNameOffscreen( pchDrawBindingName ); + } + } + else + { + pTarget->m_pIcon_offscreen = HudIcons().GetIcon( szIconTextureName ); + } + + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Compute where on the screen to draw the icon for this target. +//----------------------------------------------------------------------------- +void CLocatorPanel::ComputeTargetIconPosition( CLocatorTarget *pTarget, bool bSetPosition ) +{ + int iconX; + int iconY; + + // Measure the delta and the dist from this player to this target. + Vector vecTarget = pTarget->m_vecOrigin; + Vector vecDelta = vecTarget - MainViewOrigin(); + + if ( pTarget->m_bOriginInScreenspace ) + { + // Coordinates are already in screenspace + pTarget->m_distFromPlayer = 0.0f; + + iconX = vecTarget.x * ScreenWidth(); + iconY = vecTarget.y * ScreenHeight(); + pTarget->m_targetX = iconX; + pTarget->m_targetY = iconY; + } + else + { + pTarget->m_distFromPlayer = VectorNormalize( vecDelta ); + + if ( GetVectorInScreenSpace( vecTarget, iconX, iconY ) ) + { + // NOTE: GetVectorInScreenSpace returns false in an edge case where the + // target is very far off screen... just us the old values + pTarget->m_targetX = iconX; + pTarget->m_targetY = iconY; + } + } + + pTarget->m_drawArrowDirection = DRAW_ARROW_NO; + + float fTitleSafeInset = ScreenWidth() * 0.075f; + + if( iconX < fTitleSafeInset || iconX > ScreenWidth() - fTitleSafeInset ) + { + // It's off the screen left or right. + if ( pTarget->m_bOnscreen && !( pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_NO_OFFSCREEN ) ) + { + // Back to lerping + pTarget->StartTimedLerp(); + pTarget->m_pulseStart = gpGlobals->curtime; + } + + if ( bSetPosition ) + { + pTarget->m_bOnscreen = false; + } + + GetIconPositionForOffscreenTarget( vecDelta, pTarget->m_distFromPlayer, &iconX, &iconY ); + + Vector vCenter = pTarget->m_vecOrigin; + if( MainViewRight().Dot( vCenter - MainViewOrigin() ) > 0 ) + pTarget->m_drawArrowDirection = DRAW_ARROW_RIGHT; + else + pTarget->m_drawArrowDirection = DRAW_ARROW_LEFT; + } + else if( iconY < fTitleSafeInset || iconY > ScreenHeight() - fTitleSafeInset ) + { + // It's off the screen up or down. + if ( pTarget->m_bOnscreen && !( pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_NO_OFFSCREEN ) ) + { + // Back to lerping + pTarget->StartTimedLerp(); + pTarget->m_pulseStart = gpGlobals->curtime; + } + + if ( bSetPosition ) + { + pTarget->m_bOnscreen = false; + } + + GetIconPositionForOffscreenTarget( vecDelta, pTarget->m_distFromPlayer, &iconX, &iconY ); + + Vector vCenter = pTarget->m_vecOrigin; + if( MainViewUp().Dot( vCenter - MainViewOrigin() ) > 0 ) + pTarget->m_drawArrowDirection = DRAW_ARROW_UP; + else + pTarget->m_drawArrowDirection = DRAW_ARROW_DOWN; + } + else + { + if ( !pTarget->m_bOnscreen && !( pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_NO_OFFSCREEN ) ) + { + // Back to lerping + pTarget->StartTimedLerp(); + pTarget->m_pulseStart = gpGlobals->curtime; + } + + pTarget->m_bOnscreen = true; + } + + if ( bSetPosition ) + { + int tall = ScreenWidth() * ICON_SIZE; + int wide = tall * pTarget->m_widthScale_onscreen; + + // Animate the icon + AnimateIconSize( pTarget->GetIconEffectsFlags(), &wide, &tall, pTarget->m_pulseStart ); + AnimateIconPosition( pTarget->GetIconEffectsFlags(), &iconX, &iconY ); + AnimateIconAlpha( pTarget->GetIconEffectsFlags(), &pTarget->m_alpha, pTarget->m_fadeStart ); + + if( pTarget->m_distFromPlayer > ICON_DIST_TOO_FAR && !locator_topdown_style.GetBool() ) + { + // Make the icon smaller + wide = wide >> 1; + tall = tall >> 1; + } + + pTarget->m_centerX = iconX; + pTarget->m_centerY = iconY; + + pTarget->m_iconX = pTarget->m_centerX - ( wide >> 1 ); + pTarget->m_iconY = pTarget->m_centerY - ( tall >> 1 ); + pTarget->m_wide = wide; + pTarget->m_tall = tall; + } +} + +void CLocatorPanel::CalculateOcclusion( CLocatorTarget *pTarget ) +{ + if ( gpGlobals->curtime >= pTarget->m_flNextOcclusionTest ) + { + pTarget->m_flNextOcclusionTest = gpGlobals->curtime + LOCATOR_OCCLUSION_TEST_RATE; + + // Assume the target is not occluded. + pTarget->m_bOccluded = false; + + if ( pTarget->m_bOriginInScreenspace ) + return; + + trace_t tr; + UTIL_TraceLine( pTarget->m_vecOrigin, MainViewOrigin(), (CONTENTS_SOLID|CONTENTS_MOVEABLE), NULL, COLLISION_GROUP_NONE, &tr ); + if ( tr.fraction < 1.0f ) + { + pTarget->m_bOccluded = true; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: This is not valid until after you have computed the onscreen +// icon position for each target! +//----------------------------------------------------------------------------- +bool CLocatorPanel::IconsAreIntersecting( CLocatorTarget &first, CLocatorTarget &second, int iTolerance ) +{ + if( first.m_bOnscreen != second.m_bOnscreen ) + { + // We only declutter onscreen icons against other onscreen icons and vice-versa. + return false; + } + + if( first.IsStatic() || second.IsStatic() ) + { + // Static icons don't count. + return false; + } + + if( abs(first.GetIconY() - second.GetIconY()) < iTolerance ) + { + // OK, we need the Y-check first. Now we have to see if these icons and their captions overlap. + int firstWide = iTolerance + first.m_captionWide; + int secondWide = iTolerance + second.m_captionWide; + + if( abs(first.GetIconX() - second.GetIconX()) < (firstWide + secondWide) / 2 ) + { + return true; + } + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Draw this target on the locator. +// +// IF onscreen and visible, draw no icon, draw no arrows +// IF onscreen and occluded, draw icon transparently, draw no arrows +// IF offscreen, draw icon, draw an arrow indicating the direction to the target +//----------------------------------------------------------------------------- +void CLocatorPanel::PaintTarget( CLocatorTarget *pTarget ) +{ + bool bNewTexture = ValidateTargetTextures( pTarget ); + + if ( bNewTexture ) + { + // Refigure the width/height for the new texture + int tall = ScreenWidth() * ICON_SIZE; + int wide = tall * pTarget->m_widthScale_onscreen; + + AnimateIconSize( pTarget->GetIconEffectsFlags(), &wide, &tall, pTarget->m_pulseStart ); + + pTarget->m_wide = wide; + pTarget->m_tall = tall; + } + + // A static icon just draws with other static icons in a stack under the crosshair. + // Once displayed, they do not move. The are often used for notifiers. + if( pTarget->IsStatic() ) + { + DrawStaticIcon( pTarget ); + return; + } + + if ( !pTarget->m_bOnscreen && ( pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_NO_OFFSCREEN ) ) + { + // Doesn't draw when offscreen... reset it's alpha so it has to fade in again + pTarget->m_fadeStart = gpGlobals->curtime; + pTarget->m_alpha = 0; + } + else + { + // Save these coordinates for later lerping + pTarget->m_lastXPos = pTarget->m_iconX; + pTarget->m_lastYPos = pTarget->m_iconY; + + // Draw when it's on screen or allowed to draw offscreen + DrawDynamicIcon( pTarget, pTarget->HasCaptionText(), pTarget->m_bOnscreen ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draws the caption-like background with word-bubble style pointer +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawPointerBackground( CLocatorTarget *pTarget, int nPointerX, int nPointerY, int nWide, int nTall, bool bPointer ) +{ + if ( locator_background_style.GetInt() == 0 || pTarget->m_alpha == 0 ) + return; + + /* + int nPosX = pTarget->GetIconX() + locator_background_shift_x.GetInt() - locator_background_thickness_x.GetInt() / 2; + int nPosY = pTarget->GetIconY() + locator_background_shift_y.GetInt() - locator_background_thickness_y.GetInt() / 2; + int nBackgroundWide = nWide + locator_background_thickness_x.GetInt(); + int nBackgroundTall = nTall + locator_background_thickness_y.GetInt(); + + nPointerX = clamp( nPointerX, -0.5f * ScreenWidth(), ScreenWidth() * 1.5f ); + nPointerY = clamp( nPointerY, -0.5f * ScreenHeight(), ScreenHeight() * 1.5f ); + + float fAlpha = static_cast( pTarget->m_alpha ) / 255.0f; + + Color rgbaBackground = locator_background_color.GetColor(); + rgbaBackground[ 3 ] *= fAlpha; + + Color rgbaBorder = locator_background_border_color.GetColor(); + rgbaBorder[ 3 ] *= fAlpha; + */ + + DevMsg("[TODO] vgui::surface()->DrawWordBubble \n"); + + //vgui::surface()->DrawWordBubble( nPosX, nPosY, nPosX + nBackgroundWide, nPosY + nBackgroundTall, locator_background_border_thickness.GetInt(), rgbaBackground, rgbaBorder, bPointer, nPointerX, nPointerY, ScreenWidth() * ICON_SIZE ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw an icon with the group of static icons. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawStaticIcon( CLocatorTarget *pTarget ) +{ + int centerX = ScreenWidth() / 2; + int centerY = ScreenHeight() / 2; + centerY += m_staticIconPosition; + + int iconTall = ScreenWidth() * ICON_SIZE; + int iconWide = iconTall * pTarget->m_widthScale_onscreen; + + pTarget->m_centerX = centerX; + pTarget->m_centerY = centerY; + + // Animate the icon + AnimateIconSize( pTarget->GetIconEffectsFlags(), &iconWide, &iconTall, pTarget->m_pulseStart ); + AnimateIconPosition( pTarget->GetIconEffectsFlags(), ¢erX, ¢erY ); + AnimateIconAlpha( pTarget->GetIconEffectsFlags(), &pTarget->m_alpha, pTarget->m_fadeStart ); + + // Figure out the caption width + pTarget->m_captionWide = GetScreenWidthForCaption( pTarget->GetCaptionText(), m_hCaptionFont ); + + bool bDrawMultilineCaption = false; + + if ( m_iShouldWrapStaticLocators > 0 ) // conditionalized in locator.res + { + if ( pTarget->m_captionWide > ( ScreenWidth() * locator_split_maxwide_percent.GetFloat() ) ) + { + // we will double-line this + pTarget->m_captionWide = pTarget->m_captionWide * locator_split_len.GetFloat(); + bDrawMultilineCaption = true; + } + } + int totalWide = iconWide + ICON_GAP + pTarget->m_captionWide; + pTarget->m_iconX = centerX - totalWide * 0.5f; + pTarget->m_iconY = centerY - ( iconTall >> 1 ); + + // Lerp by speed on the Y axis + float iconY = pTarget->m_iconY; + + float diffY = fabsf( pTarget->m_iconY - pTarget->m_lastYPos ); + + float flLerpSpeed = gpGlobals->frametime * locator_lerp_speed.GetFloat(); + pTarget->m_iconY = static_cast( Approach( iconY, pTarget->m_lastYPos, MAX( 3.0f, flLerpSpeed * diffY ) ) ); + pTarget->m_centerY += ( pTarget->m_iconY - iconY ); + + pTarget->m_lastXPos = pTarget->m_iconX; + pTarget->m_lastYPos = pTarget->m_iconY; + + pTarget->m_bIsDrawing = true; + + vgui::Panel *pVguiTarget = pTarget->GetVguiTarget(); + + if ( pVguiTarget ) + { + int nPanelX, nPanelY; + nPanelX = 0; + nPanelY = 0; + + vgui::Label::Alignment nVguiTargetEdge = (vgui::Label::Alignment)pTarget->GetVguiTargetEdge(); + + int nWide = pVguiTarget->GetWide(); + int nTall = pVguiTarget->GetTall(); + + /* + const char *pchLookup = pTarget->GetVguiTargetLookup(); + if ( pchLookup[ 0 ] != '\0' ) + { + bool bLookupSuccess = false; + bLookupSuccess = pVguiTarget->LookupElementBounds( pchLookup, nPanelX, nPanelY, nWide, nTall ); + + Assert( bLookupSuccess ); + } + */ + + if ( nVguiTargetEdge == vgui::Label::a_north || + nVguiTargetEdge == vgui::Label::a_center || + nVguiTargetEdge == vgui::Label::a_south ) + { + nPanelX += nWide / 2; + } + else if ( nVguiTargetEdge == vgui::Label::a_northeast || + nVguiTargetEdge == vgui::Label::a_east || + nVguiTargetEdge == vgui::Label::a_southeast ) + { + nPanelX += nWide; + } + + if ( nVguiTargetEdge == vgui::Label::a_west || + nVguiTargetEdge == vgui::Label::a_center || + nVguiTargetEdge == vgui::Label::a_east ) + { + nPanelY += nTall / 2; + } + else if ( nVguiTargetEdge == vgui::Label::a_southwest || + nVguiTargetEdge == vgui::Label::a_south || + nVguiTargetEdge == vgui::Label::a_southeast ) + { + nPanelY += nTall; + } + + pVguiTarget->LocalToScreen( nPanelX, nPanelY ); + + DrawPointerBackground( pTarget, nPanelX, nPanelY, totalWide, iconTall, true ); + } + else + { + DrawPointerBackground( pTarget, pTarget->m_centerX, pTarget->m_centerY, totalWide, iconTall, false ); + } + + if ( pTarget->m_pIcon_onscreen ) + { + if ( !pTarget->m_bDrawControllerButton ) + { + // Don't draw the icon if we're on 360 and have a binding to draw + pTarget->m_pIcon_onscreen->DrawSelf( pTarget->GetIconX(), pTarget->GetIconY(), iconWide, iconTall, Color( 255, 255, 255, pTarget->m_alpha ) ); + } + } + + DrawTargetCaption( pTarget, pTarget->GetIconX() + iconWide + ICON_GAP, pTarget->GetIconCenterY(), bDrawMultilineCaption ); + if ( pTarget->DrawBindingName() ) + { + DrawBindingName( pTarget, pTarget->DrawBindingName(), pTarget->GetIconX() + (iconWide>>1), pTarget->GetIconY() + (iconTall>>1), pTarget->m_bDrawControllerButton ); + } + + // Draw the arrow. + int iArrowSize = ScreenWidth() * ICON_SIZE; // Always square width + DrawIndicatorArrow( pTarget->GetIconX(), pTarget->GetIconY(), iArrowSize, iArrowSize, pTarget->m_captionWide + ICON_GAP, pTarget->m_drawArrowDirection ); + + pTarget->m_bOnscreen = true; + + // Move the static icon position so the next static icon drawn this frame below this one. + m_staticIconPosition += iconTall + (iconTall>>2); + // Move down a little more if this one was multi-line + if ( bDrawMultilineCaption ) + { + m_staticIconPosition += (iconTall>>2); + } + return; +} + +//----------------------------------------------------------------------------- +// Purpose: Position and animate this target's icon on the screen. Based on +// options, draw the indicator arrows (arrows that point to the +// direction the player should turn to see the icon), text caption, +// and the 'simple' arrow which just points down to indicate the +// item the icon represents. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawDynamicIcon( CLocatorTarget *pTarget, bool bDrawCaption, bool bDrawSimpleArrow ) +{ + int alpha = pTarget->m_alpha; + + if( pTarget->m_bOccluded && !( (pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_FORCE_CAPTION) || locator_topdown_style.GetBool() ) ) + { + return; + } + + // Draw the icon! + vgui::surface()->DrawSetColor( 255, 255, 255, alpha ); + + int iWide = pTarget->m_wide; + + if ( !pTarget->m_bOnscreen ) + { + // Width is always square for offscreen icons + iWide /= pTarget->m_widthScale_onscreen; + } + + // Figure out the caption width + pTarget->m_captionWide = GetScreenWidthForCaption( pTarget->GetCaptionText(), m_hCaptionFont ); + + bool bDrawMultilineCaption = false; + + if ( m_iShouldWrapStaticLocators > 0 ) // conditionalized in locator.res + { + if ( pTarget->m_captionWide > ( ScreenWidth() * locator_split_maxwide_percent.GetFloat() ) ) + { + // we will double-line this + pTarget->m_captionWide = pTarget->m_captionWide * locator_split_len.GetFloat(); + bDrawMultilineCaption = true; + } + } + + int totalWide = iWide; + + bool bShouldDrawCaption = ( (pTarget->GetIconEffectsFlags() & LOCATOR_ICON_FX_FORCE_CAPTION) || (!pTarget->m_bOccluded && pTarget->m_distFromPlayer <= ICON_DIST_TOO_FAR) || locator_topdown_style.GetBool() ); + + if( pTarget->m_bOnscreen && bDrawCaption && bShouldDrawCaption ) + { + totalWide += ( ICON_GAP + pTarget->m_captionWide ); + } + + pTarget->m_bIsDrawing = true; + + int nTargetX, nTargetY; + + vgui::Panel *pVguiTarget = pTarget->GetVguiTarget(); + + if ( pVguiTarget ) + { + nTargetX = 0; + nTargetY = 0; + + vgui::Label::Alignment nVguiTargetEdge = (vgui::Label::Alignment)pTarget->GetVguiTargetEdge(); + + int nWide = pVguiTarget->GetWide(); + int nTall = pVguiTarget->GetTall(); + + /* + const char *pchLookup = pTarget->GetVguiTargetLookup(); + + if ( pchLookup[ 0 ] != '\0' ) + { + bool bLookupSuccess = false; + bLookupSuccess = pVguiTarget->LookupElementBounds( pchLookup, nTargetX, nTargetY, nWide, nTall ); + Assert( bLookupSuccess ); + } + */ + + if ( nVguiTargetEdge == vgui::Label::a_north || + nVguiTargetEdge == vgui::Label::a_center || + nVguiTargetEdge == vgui::Label::a_south ) + { + nTargetX += nWide / 2; + } + else if ( nVguiTargetEdge== vgui::Label::a_northeast || + nVguiTargetEdge == vgui::Label::a_east || + nVguiTargetEdge == vgui::Label::a_southeast ) + { + nTargetX += nWide; + } + + if ( nVguiTargetEdge == vgui::Label::a_west || + nVguiTargetEdge == vgui::Label::a_center || + nVguiTargetEdge == vgui::Label::a_east ) + { + nTargetY += nTall / 2; + } + else if ( nVguiTargetEdge == vgui::Label::a_southwest || + nVguiTargetEdge == vgui::Label::a_south || + nVguiTargetEdge == vgui::Label::a_southeast ) + { + nTargetY += nTall; + } + + pVguiTarget->LocalToScreen( nTargetX, nTargetY ); + } + else if ( !pTarget->m_bOnscreen ) + { + nTargetX = pTarget->m_targetX; + nTargetY = pTarget->m_targetY; + } + else + { + nTargetX = pTarget->m_centerX; + nTargetY = pTarget->m_centerY; + } + + if ( pTarget->m_bOnscreen ) + { + DrawPointerBackground( pTarget, nTargetX, nTargetY, totalWide, pTarget->m_tall, true ); + } + else + { + // Offscreen we need to point the pointer toward out offscreen target + DrawPointerBackground( pTarget, nTargetX, nTargetY, totalWide, pTarget->m_tall, true ); + } + + if( pTarget->m_bOnscreen && pTarget->m_pIcon_onscreen ) + { + if ( !pTarget->m_bDrawControllerButton ) + { + pTarget->m_pIcon_onscreen->DrawSelf( pTarget->GetIconX(), pTarget->GetIconY(), iWide, pTarget->m_tall, Color( 255, 255, 255, alpha ) ); + } + } + else if ( pTarget->m_pIcon_offscreen ) + { + if ( !pTarget->m_bDrawControllerButtonOffscreen ) + { + pTarget->m_pIcon_offscreen->DrawSelf( pTarget->GetIconX(), pTarget->GetIconY(), iWide, pTarget->m_tall, Color( 255, 255, 255, alpha ) ); + } + } + + if( !pTarget->m_bOnscreen ) + { + if ( pTarget->DrawBindingNameOffscreen() ) + { + DrawBindingName( pTarget, pTarget->DrawBindingName(), pTarget->GetIconX() + (iWide>>1), pTarget->GetIconY() + (pTarget->m_tall>>1), pTarget->m_bDrawControllerButtonOffscreen ); + } + + if ( locator_background_style.GetInt() == 0 ) + { + // Draw the arrow. + DrawIndicatorArrow( pTarget->GetIconX(), pTarget->GetIconY(), iWide, pTarget->m_tall, 0, pTarget->m_drawArrowDirection ); + } + } + else if( bShouldDrawCaption ) + { + if( bDrawCaption ) + { + //ScreenWidth() * * pTarget->m_widthScale_onscreen + DrawTargetCaption( pTarget, pTarget->GetIconCenterX() + ICON_GAP + pTarget->GetIconWidth() * 0.5, pTarget->GetIconCenterY(), bDrawMultilineCaption ); + } + if ( pTarget->DrawBindingName() ) + { + DrawBindingName( pTarget, pTarget->DrawBindingName(), pTarget->GetIconX() + (iWide>>1), pTarget->GetIconY() + (pTarget->m_tall>>1), pTarget->m_bDrawControllerButton ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Some targets have text captions. Draw the text. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawTargetCaption( CLocatorTarget *pTarget, int x, int y, bool bDrawMultiline ) +{ + // Draw the caption + vgui::surface()->DrawSetTextFont( m_hCaptionFont ); + int fontTall = vgui::surface()->GetFontTall( m_hCaptionFont ); + int iCaptionWidth = GetScreenWidthForCaption( pTarget->GetCaptionText(), m_hCaptionFont ); + + if ( bDrawMultiline ) + { + iCaptionWidth *= locator_split_len.GetFloat(); + } + + // Mapbase fixes glow and shadow not working in multiline + bool bDrawGlow = locator_text_glow.GetBool(); + bool bDrawShadow = !IsConsole() && locator_text_drop_shadow.GetBool(); // Only draw drop shadow on PC because it looks crappy on a TV + + if ( !bDrawMultiline ) + { + if ( bDrawGlow ) + { + vgui::surface()->DrawSetTextFont( m_hCaptionGlowFont ); + Color glowColor = locator_text_glow_color.GetColor(); + vgui::surface()->DrawSetTextColor( glowColor.r(), glowColor.g(), glowColor.b(), ( glowColor.a() / 255.0f ) * pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( x - 1, y - (fontTall >>1) - 1 ); + vgui::surface()->DrawUnicodeString( pTarget->GetCaptionText() ); + vgui::surface()->DrawSetTextFont( m_hCaptionFont ); + } + + if ( bDrawShadow ) + { + // Draw black text (drop shadow) + vgui::surface()->DrawSetTextColor( 0,0,0, pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( x, y - (fontTall >>1) ); + vgui::surface()->DrawUnicodeString( pTarget->GetCaptionText() ); + } + + // Draw text + vgui::surface()->DrawSetTextColor( pTarget->m_captionColor.r(),pTarget->m_captionColor.g(),pTarget->m_captionColor.b(), pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( x - 1, y - (fontTall >>1) - 1 ); + vgui::surface()->DrawUnicodeString( pTarget->GetCaptionText() ); + } + else + { + int charX = x-1; + int charY = y - ( fontTall >> 1 ) - 1; + + int iWidth = 0; + + const wchar_t *pString = pTarget->GetCaptionText(); + int len = Q_wcslen( pString ); + + Color glowColor = locator_text_glow_color.GetColor(); + for ( int iChar = 0; iChar < len; ++ iChar ) + { + int charW = vgui::surface()->GetCharacterWidth( m_hCaptionFont, pString[ iChar ] ); + iWidth += charW; + + if ( iWidth > pTarget->m_captionWide && pString[iChar] == L' ' ) + { + charY += fontTall; + charX = x-1; + iWidth = 0; + } + + if ( bDrawGlow ) + { + vgui::surface()->DrawSetTextFont( m_hCaptionGlowFont ); + vgui::surface()->DrawSetTextColor( glowColor.r(), glowColor.g(), glowColor.b(), ( glowColor.a() / 255.0f ) * pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( charX - 1, charY ); + vgui::surface()->DrawUnicodeChar( pString[iChar] ); + vgui::surface()->DrawSetTextFont( m_hCaptionFont ); + } + + if ( bDrawShadow ) + { + // Draw black text (drop shadow) + vgui::surface()->DrawSetTextColor( 0,0,0, pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( charX, charY + 1 ); + vgui::surface()->DrawUnicodeChar( pString[iChar] ); + } + + // Draw text + vgui::surface()->DrawSetTextColor( pTarget->m_captionColor.r(),pTarget->m_captionColor.g(),pTarget->m_captionColor.b(), pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( charX, charY ); + vgui::surface()->DrawUnicodeChar( pString[iChar] ); + charX += charW; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Figure out how wide (pixels) a string will be if rendered with this font +// +//----------------------------------------------------------------------------- +int CLocatorPanel::GetScreenWidthForCaption( const wchar_t *pString, vgui::HFont hFont ) +{ + int iWidth = 0; + + for ( int iChar = 0; iChar < Q_wcslen( pString ); ++ iChar ) + { + iWidth += vgui::surface()->GetCharacterWidth( hFont, pString[ iChar ] ); + } + + return iWidth; +} + +//----------------------------------------------------------------------------- +// Purpose: Some targets' captions contain information about key bindings that +// should be displayed to the player. Do so. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawBindingName( CLocatorTarget *pTarget, const char *pchBindingName, int x, int y, bool bController ) +{ + if ( !bController && !IsConsole() ) + { + // Draw the caption + vgui::surface()->DrawSetTextFont( m_hKeysFont ); + int fontTall = vgui::surface()->GetFontTall( m_hKeysFont ); + + char szBinding[ 256 ]; + Q_strcpy( szBinding, pchBindingName ? pchBindingName : "" ); + + if ( Q_strcmp( szBinding, "SEMICOLON" ) == 0 ) + { + Q_strcpy( szBinding, ";" ); + } + else if ( Q_strlen( szBinding ) == 1 && szBinding[ 0 ] >= 'a' && szBinding[ 0 ] <= 'z' ) + { + // Make single letters uppercase + szBinding[ 0 ] += ( 'A' - 'a' ); + } + + wchar_t wszCaption[ 64 ]; + g_pVGuiLocalize->ConstructString( wszCaption, sizeof(wchar_t)*64, szBinding, NULL ); + + int iWidth = GetScreenWidthForCaption( wszCaption, m_hKeysFont ); + +#ifdef MAPBASE + // Mods are capable of choosing a custom color + vgui::surface()->DrawSetTextColor( pTarget->m_bindingColor.r(), pTarget->m_bindingColor.g(), pTarget->m_bindingColor.b(), pTarget->m_alpha ); +#else + // Draw black text + vgui::surface()->DrawSetTextColor( 0,0,0, pTarget->m_alpha ); +#endif + vgui::surface()->DrawSetTextPos( x - (iWidth>>1) - 1, y - (fontTall >>1) - 1 ); + vgui::surface()->DrawUnicodeString( wszCaption ); + } + else + { + // Draw the caption + wchar_t wszCaption[ 64 ]; + + vgui::surface()->DrawSetTextFont( BUTTON_FONT_HANDLE ); + int fontTall = vgui::surface()->GetFontTall( BUTTON_FONT_HANDLE ); + + char szBinding[ 256 ]; + + // Turn localized string into icon character + Q_snprintf( szBinding, sizeof( szBinding ), "#GameUI_Icons_%s", pchBindingName ); + g_pVGuiLocalize->ConstructString( wszCaption, sizeof( wszCaption ), g_pVGuiLocalize->Find( szBinding ), 0 ); + g_pVGuiLocalize->ConvertUnicodeToANSI( wszCaption, szBinding, sizeof( szBinding ) ); + + int iWidth = GetScreenWidthForCaption( wszCaption, BUTTON_FONT_HANDLE ); + + int iLargeIconShift = MAX( 0, iWidth - ( ScreenWidth() * ICON_SIZE + ICON_GAP + ICON_GAP ) ); + + // Draw the button + vgui::surface()->DrawSetTextColor( 255,255,255, pTarget->m_alpha ); + vgui::surface()->DrawSetTextPos( x - (iWidth>>1) - iLargeIconShift, y - (fontTall >>1) ); + vgui::surface()->DrawUnicodeString( wszCaption ); + + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw an arrow to indicate that a target is offscreen +// +// iconWide is sent to this function so that the arrow knows how to straddle +// the icon that it is being drawn near. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawIndicatorArrow( int x, int y, int iconWide, int iconTall, int textWidth, int direction ) +{ + int wide = iconWide; + int tall = iconTall; + + //tall = wide = ScreenWidth() * ICON_SIZE; + + switch( direction ) + { + case DRAW_ARROW_LEFT: + vgui::surface()->DrawSetTexture( m_textureID_ArrowLeft ); + x -= wide; + y += iconTall / 2 - tall / 2; + vgui::surface()->DrawTexturedRect( x, y, x + wide, y + tall ); + break; + + case DRAW_ARROW_RIGHT: + vgui::surface()->DrawSetTexture( m_textureID_ArrowRight ); + x += iconWide + textWidth; + y += iconTall / 2 - tall / 2; + vgui::surface()->DrawTexturedRect( x, y, x + wide, y + tall ); + break; + + case DRAW_ARROW_UP: + vgui::surface()->DrawSetTexture( m_textureID_ArrowUp ); + x += iconWide / 2 - wide / 2; + y -= tall; + vgui::surface()->DrawTexturedRect( x, y, x + wide, y + tall ); + break; + + case DRAW_ARROW_DOWN: + vgui::surface()->DrawSetTexture( m_textureID_ArrowDown ); + x += iconWide / 2 - wide / 2; + y += iconTall; + vgui::surface()->DrawTexturedRect( x, y, x + wide, y + tall ); + break; + + default: + // Do not draw. + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draws a very simple arrow that points down. +//----------------------------------------------------------------------------- +void CLocatorPanel::DrawSimpleArrow( int x, int y, int iconWide, int iconTall ) +{ + vgui::surface()->DrawSetTexture( m_textureID_SimpleArrow ); + + y += iconTall; + + vgui::surface()->DrawTexturedRect( x, y, x + iconWide, y + iconTall ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLocatorPanel::GetIconPositionForOffscreenTarget( const Vector &vecDelta, float flDist, int *pXPos, int *pYPos ) +{ + float xpos, ypos; + float flRotation; + float flRadius = YRES(OFFSCREEN_ICON_POSITION_RADIUS); + + if ( locator_topdown_style.GetBool() ) + { + flRadius *= clamp( flDist / 600.0f, 1.75f, 3.0f ); + } + + GetTargetPosition( vecDelta, flRadius, &xpos, &ypos, &flRotation ); + + *pXPos = xpos; + *pYPos = ypos; +} + +//----------------------------------------------------------------------------- +// Purpose: Given a handle, return the pointer to the proper locator target. +//----------------------------------------------------------------------------- +CLocatorTarget *CLocatorPanel::GetPointerForHandle( int hTarget ) +{ + for( int i = 0 ; i < MAX_LOCATOR_TARGETS ; i++ ) + { + if( m_targets[ i ].m_isActive && m_targets[ i ].m_serialNumber == hTarget ) + { + return &m_targets[ i ]; + } + } + + return NULL; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CLocatorPanel::AddTarget() +{ + for( int i = 0 ; i < MAX_LOCATOR_TARGETS ; i++ ) + { + if( !m_targets[ i ].m_isActive ) + { + m_targets[ i ].Activate( m_serializer ); + m_serializer++; + + return m_targets[ i ].m_serialNumber; + } + } + + DevWarning( "Locator Panel has no free targets!\n" ); + return -1; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLocatorPanel::RemoveTarget( int hTarget ) +{ + CLocatorTarget *pTarget = GetPointerForHandle( hTarget ); + + if( pTarget ) + { + pTarget->Deactivate(); + } +} + diff --git a/game/client/hud_locator_target.h b/game/client/hud_locator_target.h new file mode 100644 index 00000000..69939dbb --- /dev/null +++ b/game/client/hud_locator_target.h @@ -0,0 +1,184 @@ +//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: Add entities to this system, and the Locator will maintain an arrow +// on the HUD that points to the entities when they are offscreen. +// +//============================================================================= + +#ifndef L4D_HUD_LOCATOR_H +#define L4D_HUD_LOCATOR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "vgui_controls/PHandle.h" + + +#define MAX_LOCATOR_BINDINGS_SHOWN 8 +#define MAX_LOCATOR_TARGETS 10 +#define LOCATOR_FLAGS_NONE 0x00000000 + +#define LOCATOR_ICON_FX_NONE 0x00000000 +#define LOCATOR_ICON_FX_PULSE_SLOW 0x00000001 +#define LOCATOR_ICON_FX_PULSE_FAST 0x00000002 +#define LOCATOR_ICON_FX_PULSE_URGENT 0x00000004 +#define LOCATOR_ICON_FX_ALPHA_SLOW 0x00000008 +#define LOCATOR_ICON_FX_ALPHA_FAST 0x00000010 +#define LOCATOR_ICON_FX_ALPHA_URGENT 0x00000020 +#define LOCATOR_ICON_FX_SHAKE_NARROW 0x00000040 +#define LOCATOR_ICON_FX_SHAKE_WIDE 0x00000080 +#define LOCATOR_ICON_FX_STATIC 0x00000100 // This icon draws at a fixed location on the HUD. +#define LOCATOR_ICON_FX_NO_OFFSCREEN 0x00000200 +#define LOCATOR_ICON_FX_FORCE_CAPTION 0x00000400 // Always draw the caption, even when the icon is occluded. +#define LOCATOR_ICON_FX_FADE_OUT 0x00000800 // Set when deactivated so it can smoothly vanish +#define LOCATOR_ICON_FX_FADE_IN 0x00001000 // Set when activated so it can smoothly appear + +#include "tier1/utlsymbol.h" + +// See comments in UtlSymbol on why this is useful +DECLARE_PRIVATE_SYMBOLTYPE( CGameInstructorSymbol ); + +//----------------------------------------------------------------------------- +// This class represents a single target to be tracked by the locator +//----------------------------------------------------------------------------- +class CLocatorTarget +{ +public: + bool m_bOriginInScreenspace; + Vector m_vecOrigin; // The location in the world to draw on the locator + + // ONLY the locator panel should fiddle with these fields. + bool m_isActive; + int m_serialNumber; + int m_frameLastUpdated; + bool m_bOnscreen; + bool m_bOccluded; + bool m_bVisible; + bool m_bIsDrawing; + float m_distFromPlayer; + CHudTexture *m_pIcon_onscreen; + CHudTexture *m_pIcon_offscreen; + int m_iBindingTick; + float m_flNextBindingTick; + float m_flNextOcclusionTest; + int m_iBindingChoicesCount; + const char *(m_pchBindingChoices[ MAX_LOCATOR_BINDINGS_SHOWN ]); + int m_iBindChoicesOriginalToken[ MAX_LOCATOR_BINDINGS_SHOWN ]; + + // Fields for drawing + int m_targetX; // screen X position of the actual target + int m_targetY; // screen Y position of the actual target + int m_iconX; // screen X position (top) + int m_iconY; // screen Y position (left) + int m_centerX; // screen X position (center) + int m_centerY; // screen Y position (center) + int m_wide; // draw width of icon (may be different from frame to frame as the icon's size animates, for instance) + int m_tall; // draw height of icon '' '' + float m_widthScale_onscreen; // for icons that are wider than standard + int m_alpha; // + float m_fadeStart; // time stamp when fade out started + float m_lerpStart; // time stamp when lerping started + float m_pulseStart; // time stamp when pulsing started + int m_declutterIndex; // sort order from the declutterer + int m_lastDeclutterIndex; // last sort order from the declutterer + int m_drawArrowDirection; // Whether to draw an arrow indicating this target is off-screen, also tells us which arrow to draw (left, up, etc.) + int m_captionWide; // How wide (pixels) my caption is. + bool m_bDrawControllerButton; + bool m_bDrawControllerButtonOffscreen; + int m_offsetX; // User-specified X offset which is applied in screenspace + int m_offsetY; // User-specified Y offset which is applied in screenspace + + // Fields for interpolating icon position + float m_flTimeLerpDone; // How much time left before this icon arrives where it is supposed to be. + int m_lastXPos; // screen X position last frame + int m_lastYPos; // '' Y + + CLocatorTarget( void ); + void Activate( int serialNumber ); + void Deactivate( bool bNoFade = false ); + void Update(); + + int GetIconX( void ); + int GetIconY( void ); + int GetIconCenterX( void ); + int GetIconCenterY( void ); + int GetIconWidth( void ); + int GetIconHeight( void ); + + void AddIconEffects( int add ) { m_iEffectsFlags |= add; } + void RemoveIconEffects( int remove ) { m_iEffectsFlags &= ~remove; } + int GetIconEffectsFlags() { return m_iEffectsFlags; } + void SetCaptionColor( Color col ) { m_captionColor = col; } + void SetCaptionColor( const char *pszCaptionColor ); + bool IsStatic(); + bool IsPresenting(); + void StartTimedLerp(); + void StartPresent(); + void EndPresent(); + + void UpdateVguiTarget( void ); + vgui::Panel *GetVguiTarget( void ); + void SetVguiTargetName( const char *pchVguiTargetName ); + const char *GetVguiTargetName( void ) { return m_szVguiTargetName.String(); } + void SetVguiTargetLookup( const char *pchVguiTargetLookup ); + const char *GetVguiTargetLookup( void ) { return m_szVguiTargetLookup.String(); } + void SetVguiTargetEdge( int nVguiEdge ); + int GetVguiTargetEdge( void ) const { return m_nVguiTargetEdge; } + + void SetOnscreenIconTextureName( const char *pszTexture ); + void SetOffscreenIconTextureName( const char *pszTexture ); + void SetBinding( const char *pszBinding ); + const char *UseBindingImage( char *pchIconTextureName, size_t bufSize ); + + const char *GetOnscreenIconTextureName() { return m_szOnscreenTexture.String(); } + const char *GetOffscreenIconTextureName() { return m_szOffscreenTexture.String(); } + const char *GetBinding() { return m_szBinding.String(); } + + void SetVisible( bool bVisible ); + bool IsVisible( void ); + + void SetCaptionText( const char *pszText, const char *pszParam ); + const wchar_t *GetCaptionText( void ) { return (const wchar_t *)m_wszCaption.Base(); } + bool HasCaptionText( void ) { return m_wszCaption.Count() > 1; } + + void DrawBindingName( const char *pchDrawName ) { m_pchDrawBindingName = pchDrawName; } + void DrawBindingNameOffscreen( const char *pchDrawName ) { m_pchDrawBindingNameOffscreen = pchDrawName; } + + const char *DrawBindingName( void ) { return m_pchDrawBindingName; } + const char *DrawBindingNameOffscreen( void ) { return m_pchDrawBindingNameOffscreen; } + + bool IsOnScreen() { return m_bOnscreen; } + bool IsOccluded() { return m_bOccluded; } + + +private: + CGameInstructorSymbol m_szVguiTargetName; + CGameInstructorSymbol m_szVguiTargetLookup; + vgui::DHANDLE m_hVguiTarget; + int m_nVguiTargetEdge; + + CGameInstructorSymbol m_szOnscreenTexture; + CGameInstructorSymbol m_szOffscreenTexture; + CGameInstructorSymbol m_szBinding; + + bool m_bWasControllerLast; + const char *m_pchDrawBindingName; + const char *m_pchDrawBindingNameOffscreen; + int m_iEffectsFlags; + CUtlVector< wchar_t > m_wszCaption; + +public: + Color m_captionColor; +#ifdef MAPBASE + Color m_bindingColor; +#endif +}; + +extern int Locator_AddTarget(); +extern void Locator_RemoveTarget( int hTarget ); +CLocatorTarget *Locator_GetTargetFromHandle( int hTarget ); +void Locator_ComputeTargetIconPositionFromHandle( int hTarget ); + + +#endif // L4D_HUD_LOCATOR_H \ No newline at end of file diff --git a/game/client/hud_pdump.cpp b/game/client/hud_pdump.cpp index 612a18d7..56ac16f4 100644 --- a/game/client/hud_pdump.cpp +++ b/game/client/hud_pdump.cpp @@ -21,9 +21,15 @@ static CPDumpPanel *g_pPDumpPanel = NULL; // we pragma'd away in platform.h, so this little compiler specific hack will eliminate those warnings while // retaining our own warning setup...ywb #ifdef WIN32 + +#if _MSC_VER < 1900 #pragma warning( push ) #include #pragma warning( pop ) +#else +#include +#endif + #endif using namespace vgui; diff --git a/game/client/hud_vote.cpp b/game/client/hud_vote.cpp index 319255dd..659669a0 100644 --- a/game/client/hud_vote.cpp +++ b/game/client/hud_vote.cpp @@ -59,7 +59,7 @@ class CTFVoteNotification : public CEconNotification { g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, m_wszPlayerName, sizeof(m_wszPlayerName) ); SetLifetime( 7 ); - SetText( "#GameUI_Vote_Notification_Text" ); + SetText( "#Vote_notification_text" ); AddStringToken( "initiator", m_wszPlayerName ); } virtual bool CanBeTriggered() @@ -68,10 +68,7 @@ class CTFVoteNotification : public CEconNotification } virtual void Trigger() { - CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#GameUI_Vote_Notification_Title", - "#GameUI_Vote_Notification_Text", - "#GameUI_Vote_Notification_View", - "#cancel", &ConfirmShowVoteSetup ); + CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#Vote_notification_title", "#Vote_notification_text", "#Vote_notification_view", "#cancel", &ConfirmShowVoteSetup ); pDialog->SetContext( this ); pDialog->AddStringToken( "initiator", m_wszPlayerName ); // so we aren't deleted @@ -98,7 +95,7 @@ class CTFVoteNotification : public CEconNotification CHudVote *pHudVote = GET_HUDELEMENT( CHudVote ); if ( pHudVote ) { - pHudVote->ShowVoteUI( true ); + pHudVote->ShowVoteUI(); } } pNotification->SetIsInUse( false ); @@ -293,76 +290,6 @@ void CVoteSetupDialog::ApplySettings(KeyValues *inResourceData) m_HeaderFGColor = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) ); } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CVoteSetupDialog::InitializeIssueList( void ) -{ - m_pComboBox->RemoveAll(); - m_pComboBox->SetVisible( false ); - SetDialogVariable( "combo_label", "" ); - - for ( int index = 0; index < m_VoteIssues.Count(); index++ ) - { - if ( !m_VoteIssues[index].szName || !m_VoteIssues[index].szName[0] ) - continue; - - bool bActive = m_VoteIssues[index].bIsActive; - - char szIssueLocalized[k_MAX_VOTE_NAME_LENGTH] = { 0 }; - g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( m_VoteIssues[index].szNameString ), szIssueLocalized, sizeof( szIssueLocalized ) ); - - if ( !bActive ) - { - char szDisabled[k_MAX_VOTE_NAME_LENGTH] = { 0 }; - g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#GameUI_Vote_Disabled" ), szDisabled, sizeof( szDisabled ) ); - V_strcat_safe( szIssueLocalized, szDisabled ); - } - - KeyValues *pKeyValues = new KeyValues( "Issue" ); - pKeyValues->SetString( "Issue", szIssueLocalized ); - pKeyValues->SetString( "IssueRaw", m_VoteIssues[index].szName ); - pKeyValues->SetBool( "Active", m_VoteIssues[index].bIsActive ); - int iId = m_pVoteSetupList->AddItem( 0, pKeyValues ); - pKeyValues->deleteThis(); - - // Setup the list entry style - if ( m_hIssueFont != INVALID_FONT ) - { - m_pVoteSetupList->SetItemFont( iId, m_hIssueFont ); - Color colFG = bActive ? m_IssueFGColor : m_IssueFGColorDisabled; - m_pVoteSetupList->SetItemFgColor( iId, colFG ); - } - } - - // Select the first item by default - if ( m_pVoteSetupList->GetItemCount() > 0 ) - { - m_pVoteSetupList->SetSelectedItem( 0 ); - } - else - { - // No active issues - char szIssueLocalized[k_MAX_VOTE_NAME_LENGTH] = { 0 }; - g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#GameUI_Vote_System_Disabled" ), szIssueLocalized, sizeof( szIssueLocalized ) ); - - KeyValues *pKeyValues = new KeyValues( "Issue" ); - pKeyValues->SetString( "Issue", szIssueLocalized ); - pKeyValues->SetString( "IssueRaw", "Disabled" ); - pKeyValues->SetBool( "Active", false ); - int iId = m_pVoteSetupList->AddItem( 0, pKeyValues ); - pKeyValues->deleteThis(); - - if ( m_hIssueFont != INVALID_FONT ) - { - m_pVoteSetupList->SetItemFont( iId, m_hIssueFont ); - m_pVoteSetupList->SetItemFgColor( iId, m_IssueFGColor ); - } - } - - UpdateCurrentMap(); -} - //----------------------------------------------------------------------------- // Purpose: Keep track of the current map //----------------------------------------------------------------------------- @@ -375,7 +302,7 @@ void CVoteSetupDialog::UpdateCurrentMap( void ) //----------------------------------------------------------------------------- // Purpose: Feeds Issues from the server to this Dialog //----------------------------------------------------------------------------- -void CVoteSetupDialog::AddVoteIssues( CUtlVector< VoteIssue_t > &m_VoteSetupIssues ) +void CVoteSetupDialog::AddVoteIssues( CUtlStringList &m_VoteSetupIssues ) { m_VoteIssues.RemoveAll(); for ( int index = 0; index < m_VoteSetupIssues.Count(); index++ ) @@ -458,7 +385,36 @@ void CVoteSetupDialog::Activate() m_pVoteParameterList->SetSectionFgColor( 1, m_HeaderFGColor ); } - InitializeIssueList(); + // Populate the Issue list + for ( int index = 0; index < m_VoteIssues.Count(); index++ ) + { + const char *pszIssue = m_VoteIssues[index]; + if ( !pszIssue || !pszIssue[0] ) + continue; + + KeyValues *pKeyValues = new KeyValues( "Issue" ); + pKeyValues->SetString( "Issue", pszIssue ); + int iId = m_pVoteSetupList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + + // Setup the list entry style + if ( m_hIssueFont != INVALID_FONT ) + { + m_pVoteSetupList->SetItemFont( iId, m_hIssueFont ); + + bool bDisabled = V_stristr( pszIssue, "(Disabled on Server)" ); // driller: need to localize + Color colFG = bDisabled ? m_IssueFGColorDisabled : m_IssueFGColor; + m_pVoteSetupList->SetItemFgColor( iId, colFG ); + } + } + + // Select the first item by default + if ( m_pVoteSetupList->GetItemCount() > 0 ) + { + m_pVoteSetupList->SetSelectedItem( 0 ); + } + + UpdateCurrentMap(); } //----------------------------------------------------------------------------- @@ -476,15 +432,15 @@ void CVoteSetupDialog::OnClose() void CVoteSetupDialog::OnCommand(const char *command) { // We should have enough data to issue a CallVote command - if ( !V_stricmp( command, "CallVote" ) ) + if ( V_stricmp( command, "CallVote" ) == 0 ) { int iSelectedItem = m_pVoteSetupList->GetSelectedItem(); if ( iSelectedItem >= 0 ) { - char szVoteCommand[k_MAX_VOTE_NAME_LENGTH]; + char szVoteCommand[128]; KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); - const char *szIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); - if ( !V_stricmp( "ChangeLevel", szIssueRaw ) || !V_stricmp( "NextLevel", szIssueRaw ) ) + const char *szIssue = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "changelevel", szIssue ) == 0 || V_stricmp( "nextlevel", szIssue ) == 0 ) { int nSelectedParam = m_pVoteParameterList->GetSelectedItem(); if ( nSelectedParam >= 0 ) @@ -498,13 +454,13 @@ void CVoteSetupDialog::OnCommand(const char *command) { // Which Map? const char *szMapName = pParameterKeyValues->GetString( "Name" ); - Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssueRaw, szMapName ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szMapName ); engine->ClientCmd( szVoteCommand ); } } } } - else if ( !V_stricmp( "Kick", szIssueRaw ) ) + else if ( V_stricmp( "kick", szIssue ) == 0 ) { // Get selected Player int iSelectedParam = m_pVoteParameterList->GetSelectedItem(); @@ -520,7 +476,7 @@ void CVoteSetupDialog::OnCommand(const char *command) if ( engine->GetPlayerInfo( playerIndex, &playerInfo ) ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerIndex ); - Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s \"%d %s\"\n;", szIssueRaw, pPlayer->GetUserID(), pReasonString ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s \"%d %s\"\n;", szIssue, pPlayer->GetUserID(), pReasonString ); engine->ClientCmd( szVoteCommand ); #ifdef TF_CLIENT_DLL CSteamID steamID; @@ -539,7 +495,7 @@ void CVoteSetupDialog::OnCommand(const char *command) } } #ifdef TF_CLIENT_DLL - else if ( !V_stricmp( "ChangeMission", szIssueRaw ) ) + else if ( V_stricmp( "ChangeMission", szIssue ) == 0 ) { int nSelectedParam = m_pVoteParameterList->GetSelectedItem(); if ( nSelectedParam >= 0 ) @@ -553,7 +509,7 @@ void CVoteSetupDialog::OnCommand(const char *command) { // Which Pop File? const char *szPopFile = pParameterKeyValues->GetString( "Name" ); - Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssueRaw, szPopFile ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szPopFile ); engine->ClientCmd( szVoteCommand ); } } @@ -563,7 +519,7 @@ void CVoteSetupDialog::OnCommand(const char *command) else { // Non-parameter vote. i.e. callvote scrambleteams - Q_snprintf( szVoteCommand, sizeof(szVoteCommand), "callvote %s\n;", szIssueRaw ); + Q_snprintf( szVoteCommand, sizeof(szVoteCommand), "callvote %s\n;", szIssue ); engine->ClientCmd( szVoteCommand ); } @@ -595,23 +551,22 @@ void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel ) if ( !pIssueKeyValues ) return; - CHudVote *pHudVote = GET_HUDELEMENT( CHudVote ); - if ( !pHudVote ) - return; - // We're rebuilding, so clear state m_bVoteButtonEnabled = false; m_pVoteParameterList->ClearSelection(); m_pVoteParameterList->RemoveAll(); - const char *pszIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); - bool bActive = pIssueKeyValues->GetBool( "Active" ); - if ( !pHudVote->IsVoteSystemActive() || !bActive ) + const char *szName = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "Voting disabled on this Server", szName ) == 0 ) + { + m_bVoteButtonEnabled = false; + } + else if ( V_stristr( szName, "(Disabled on Server)" ) ) // driller: need to localize { m_bVoteButtonEnabled = false; } // CHANGELEVEL / NEXTLEVEL - else if ( !V_stricmp( "ChangeLevel", pszIssueRaw ) || !V_stricmp( "NextLevel", pszIssueRaw ) ) + else if ( V_stricmp( "changelevel", szName ) == 0 || V_stricmp( "nextlevel", szName ) == 0 ) { // Feed the mapcycle to the parameters list for ( int index = 0; index < m_VoteIssuesMapCycle.Count(); index++ ) @@ -643,7 +598,7 @@ void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel ) } } // KICK - else if ( !V_stricmp( "Kick", pszIssueRaw ) ) + else if ( V_stricmp( "kick", szName ) == 0 ) { // Feed the player list to the parameters list int nMaxClients = engine->GetMaxClients(); @@ -701,7 +656,7 @@ void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel ) } #ifdef TF_CLIENT_DLL // CHANGE POP FILE - else if ( !V_stricmp( "ChangeMission", pszIssueRaw ) ) + else if ( V_stricmp( "ChangeMission", szName ) == 0 ) { // Feed the popfiles to the parameters list for ( int index = 0; index < m_VoteIssuesPopFiles.Count(); index++ ) @@ -787,8 +742,8 @@ void CVoteSetupDialog::RefreshIssueParameters() if ( iSelectedItem >= 0 ) { KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); - const char *pszIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); - if ( !V_stricmp( "Kick", pszIssueRaw ) ) + const char *szName = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "kick", szName ) == 0 ) { if ( m_pVoteParameterList->GetItemCount() > 0 ) { @@ -831,10 +786,10 @@ void CVoteSetupDialog::RefreshIssueParameters() m_pVoteParameterList->InvalidateItem( index ); } + + m_pVoteParameterList->SetImageList( m_pImageList, false ); } } - - m_pVoteParameterList->SetImageList( m_pImageList, false ); } } @@ -844,9 +799,9 @@ void CVoteSetupDialog::RefreshIssueParameters() void CVoteSetupDialog::ResetData() { m_bVoteButtonEnabled = false; - m_pVoteSetupList->RemoveAll(); - m_pVoteParameterList->RemoveAll(); - m_pComboBox->RemoveAll(); + m_pVoteSetupList->DeleteAllItems(); + m_pVoteParameterList->DeleteAllItems(); + m_pComboBox->DeleteAllItems(); } //----------------------------------------------------------------------------- @@ -908,7 +863,7 @@ void CHudVote::Init( void ) ListenForGameEvent( "vote_options" ); ListenForGameEvent( "vote_cast" ); - m_bVotingActive = false; + SetVoteActive( false ); m_flVoteResultCycleTime = -1; m_flHideTime = -1; m_bIsYesNoVote = true; @@ -916,8 +871,6 @@ void CHudVote::Init( void ) m_nVoteChoicesCount = 2; // Yes/No is the default m_bShowVoteActivePanel = false; m_iVoteCallerIdx = -1; - m_bVoteSystemActive = false; - m_nVoteTeamIndex = 0; HOOK_HUD_MESSAGE( CHudVote, CallVoteFailed ); HOOK_HUD_MESSAGE( CHudVote, VoteStart ); @@ -931,7 +884,7 @@ void CHudVote::Init( void ) //----------------------------------------------------------------------------- void CHudVote::LevelInit( void ) { - m_bVotingActive = false; + SetVoteActive( false ); m_flVoteResultCycleTime = -1; m_flHideTime = -1; m_flPostVotedHideTime = -1; @@ -948,7 +901,7 @@ int CHudVote::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBin if ( !down ) return 1; - if ( !m_bVotingActive ) + if ( !m_bVoteActive ) return 1; if ( m_bPlayerVoted ) @@ -1026,19 +979,15 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) m_pCallVoteFailed->SetVisible( true ); m_pVoteSetupDialog->SetVisible( false ); - m_flHideTime = gpGlobals->curtime + 4.f; + m_flHideTime = gpGlobals->curtime + 4.0; - char szTime[k_MAX_VOTE_NAME_LENGTH]; - wchar_t wszTime[k_MAX_VOTE_NAME_LENGTH]; - bool bMinutes = ( nTime > 65 ); - if ( bMinutes ) - { - nTime /= 60; - } + char szTime[256]; + wchar_t wszTime[256]; Q_snprintf( szTime, sizeof ( szTime), "%i", nTime ); g_pVGuiLocalize->ConvertANSIToUnicode( szTime, wszTime, sizeof( wszTime ) ); - wchar_t wszHeaderString[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wszHeaderString[512]; + wchar_t *pwszHeaderString; switch( nReason ) { @@ -1051,12 +1000,10 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) break; case VOTE_FAILED_RATE_EXCEEDED: - { - const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_vote_spam_min" : "#GameUI_vote_failed_vote_spam_mins" ) : "#GameUI_vote_failed_vote_spam"; - g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof( wszHeaderString ), g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); - m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_vote_spam" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); break; - } case VOTE_FAILED_ISSUE_DISABLED: m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_disabled_issue" ); @@ -1074,13 +1021,11 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_name_required" ); break; - case VOTE_FAILED_ON_COOLDOWN: - { - const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_recently_min" : "#GameUI_vote_failed_recently_mins" ) : "#GameUI_vote_failed_recently"; - g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof( wszHeaderString ), g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); - m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); + case VOTE_FAILED_FAILED_RECENTLY: + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_recently" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); break; - } case VOTE_FAILED_TEAM_CANT_CALL: m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_team_cant_call" ); @@ -1107,12 +1052,10 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) break; case VOTE_FAILED_CANNOT_KICK_FOR_TIME: - { - const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_cannot_kick_min" : "#GameUI_vote_failed_cannot_kick_mins" ) : "#GameUI_vote_failed_cannot_kick"; - g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof( wszHeaderString ), g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); - m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_cannot_kick_for_time" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); break; - } case VOTE_FAILED_CANNOT_KICK_DURING_ROUND: m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_round_active" ); @@ -1121,14 +1064,6 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) case VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE: m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_event_already_active" ); break; - - case VOTE_FAILED_VOTE_IN_PROGRESS: - m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_vote_in_progress" ); - break; - - case VOTE_FAILED_KICK_LIMIT_REACHED: - m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_kick_limit" ); - break; } } @@ -1140,14 +1075,14 @@ void CHudVote::MsgFunc_VoteFailed( bf_read &msg ) if ( IsPlayingDemo() ) return; - m_nVoteTeamIndex = msg.ReadByte(); + int iTeam = msg.ReadByte(); vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte(); // Visibility of this error is handled by OnThink() - m_bVotingActive = false; + SetVoteActive( false ); m_bVotePassed = false; - m_flVoteResultCycleTime = gpGlobals->curtime + 2.f; - m_flHideTime = gpGlobals->curtime + 5.f; + m_flVoteResultCycleTime = gpGlobals->curtime + 2; + m_flHideTime = gpGlobals->curtime + 5; switch ( nReason ) { @@ -1164,10 +1099,11 @@ void CHudVote::MsgFunc_VoteFailed( bf_read &msg ) break; } + // driller: this event has no listeners - will eventually hook into stats IGameEvent *event = gameeventmanager->CreateEvent( "vote_failed" ); if ( event ) { - event->SetInt( "team", m_nVoteTeamIndex ); + event->SetInt( "team", iTeam ); gameeventmanager->FireEventClientSide( event ); } @@ -1175,11 +1111,7 @@ void CHudVote::MsgFunc_VoteFailed( bf_read &msg ) if ( !pLocalPlayer ) return; - bool bShowToPlayer = ( !m_nVoteTeamIndex || pLocalPlayer->GetTeamNumber() == m_nVoteTeamIndex ); - if ( bShowToPlayer ) - { - pLocalPlayer->EmitSound("Vote.Failed"); - } + pLocalPlayer->EmitSound("Vote.Failed"); } //----------------------------------------------------------------------------- @@ -1195,8 +1127,9 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) return; // Is this a team-only vote? - m_nVoteTeamIndex = msg.ReadByte(); - if ( m_nVoteTeamIndex >= FIRST_GAME_TEAM && m_nVoteTeamIndex != pLocalPlayer->GetTeamNumber() ) + int iTeam = msg.ReadByte(); + uint8 invalidTeam = (uint8)TEAM_INVALID; + if ( iTeam != invalidTeam && iTeam != pLocalPlayer->GetTeamNumber() ) return; // Entity calling the vote @@ -1224,18 +1157,18 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) } // DisplayString - char szIssue[k_MAX_VOTE_NAME_LENGTH]; + char szIssue[256]; szIssue[0] = 0; msg.ReadString( szIssue, sizeof(szIssue) ); // DetailString - char szParam1[k_MAX_VOTE_NAME_LENGTH]; + char szParam1[256]; szParam1[0] = 0; msg.ReadString( szParam1, sizeof(szParam1) ); m_bIsYesNoVote = msg.ReadByte(); - m_bVotingActive = true; + SetVoteActive( true ); m_pVoteFailed->SetVisible( false ); m_pVotePassed->SetVisible( false ); m_pCallVoteFailed->SetVisible( false ); @@ -1265,23 +1198,25 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) // Display vote caller's name wchar_t wszCallerName[MAX_PLAYER_NAME_LENGTH]; - wchar_t wszHeaderString[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wszHeaderString[512]; + wchar_t *pwszHeaderString; // Player g_pVGuiLocalize->ConvertANSIToUnicode( pszCallerName, wszCallerName, sizeof( wszCallerName ) ); // String - g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof( wszHeaderString ), g_pVGuiLocalize->Find( "#GameUI_vote_header" ), 1, wszCallerName ); + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_header" ), 1, wszCallerName ); + pwszHeaderString = wszHeaderString; // Final - m_pVoteActive->SetDialogVariable( "header", wszHeaderString ); + m_pVoteActive->SetDialogVariable( "header", pwszHeaderString ); // Display the Issue wchar_t *pwcParam; - wchar_t wcParam[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wcParam[128]; wchar_t *pwcIssue; - wchar_t wcIssue[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wcIssue[512]; if ( Q_strlen( szParam1 ) > 0 ) { @@ -1311,7 +1246,7 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) if ( m_bIsYesNoVote ) { // YES / NO UI - wchar_t wzFinal[k_MAX_VOTE_NAME_LENGTH] = L""; + wchar_t wzFinal[512] = L""; wchar_t *pszText = g_pVGuiLocalize->Find( "#GameUI_vote_yes_pc_instruction" ); if ( pszText ) { @@ -1353,7 +1288,7 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) // Construct Option name const char *pszChoiceName = m_VoteSetupChoices[iIndex]; - char szOptionName[k_MAX_VOTE_NAME_LENGTH]; + char szOptionName[256]; Q_snprintf( szOptionName, sizeof( szOptionName ), "F%i. ", iIndex + 1 ); Q_strncat( szOptionName, pszChoiceName, sizeof( szOptionName ), COPY_ALL_CHARACTERS ); @@ -1379,7 +1314,7 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) { event->SetString( "issue", szIssue ); event->SetString( "param1", szParam1 ); - event->SetInt( "team", m_nVoteTeamIndex ); + event->SetInt( "team", iTeam ); event->SetInt( "initiator", m_iVoteCallerIdx ); gameeventmanager->FireEventClientSide( event ); } @@ -1391,10 +1326,10 @@ void CHudVote::MsgFunc_VoteStart( bf_read &msg ) } else { - m_bShowVoteActivePanel = true; + ShowVoteUI(); } #else - m_bShowVoteActivePanel = true; + ShowVoteUI(); #endif // TF_CLIENT_DLL } @@ -1406,24 +1341,24 @@ void CHudVote::MsgFunc_VotePass( bf_read &msg ) if ( IsPlayingDemo() ) return; - m_nVoteTeamIndex = msg.ReadByte(); + int iTeam = msg.ReadByte(); // Passed string - char szResult[k_MAX_VOTE_NAME_LENGTH]; + char szResult[256]; szResult[0] = 0; msg.ReadString( szResult, sizeof(szResult) ); // Detail string - char szParam1[k_MAX_VOTE_NAME_LENGTH]; + char szParam1[256]; szParam1[0] = 0; msg.ReadString( szParam1, sizeof(szParam1) ); // Localize wchar_t *pwcParam; - wchar_t wcParam[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wcParam[128]; wchar_t *pwcIssue; - wchar_t wcIssue[k_MAX_VOTE_NAME_LENGTH]; + wchar_t wcIssue[512]; if ( Q_strlen( szParam1 ) > 0 ) { @@ -1449,10 +1384,10 @@ void CHudVote::MsgFunc_VotePass( bf_read &msg ) m_pVotePassed->SetDialogVariable( "passedresult", pwcIssue ); - m_bVotingActive = false; + SetVoteActive( false ); m_bVotePassed = true; - m_flVoteResultCycleTime = gpGlobals->curtime + 2.f; - m_flHideTime = gpGlobals->curtime + 5.f; + m_flVoteResultCycleTime = gpGlobals->curtime + 2; + m_flHideTime = gpGlobals->curtime + 5; // driller: this event has no listeners - will eventually hook into stats IGameEvent *event = gameeventmanager->CreateEvent( "vote_passed" ); @@ -1460,7 +1395,7 @@ void CHudVote::MsgFunc_VotePass( bf_read &msg ) { event->SetString( "details", szResult ); event->SetString( "param1", szParam1 ); - event->SetInt( "team", m_nVoteTeamIndex ); + event->SetInt( "team", iTeam ); gameeventmanager->FireEventClientSide( event ); } @@ -1493,45 +1428,21 @@ void CHudVote::MsgFunc_VoteSetup( bf_read &msg ) int nIssueCount = msg.ReadByte(); if ( nIssueCount ) { - for ( int i = 0; i < nIssueCount; i++ ) + for ( int index = 0; index < nIssueCount; index++ ) { - char szIssue[k_MAX_VOTE_NAME_LENGTH]; - char szIssueString[k_MAX_VOTE_NAME_LENGTH]; - msg.ReadString( szIssue, sizeof( szIssue ) ); - msg.ReadString( szIssueString, sizeof( szIssueString ) ); - bool bIsActive = (bool)msg.ReadByte(); - - m_bVoteSystemActive |= bIsActive; - - bool bAdd = true; - FOR_EACH_VEC( m_VoteSetupIssues, j ) - { - if ( !V_strcmp( szIssue, m_VoteSetupIssues[j].szName ) ) - { - bAdd = false; - break; - } - } - - if ( bAdd ) + char szIssue[256]; + msg.ReadString( szIssue, sizeof(szIssue) ); + if ( !m_VoteSetupIssues.HasElement( szIssue ) ) { - // When empty, assume that we just pre-pend #Vote_ to szIssue (reduces msg size) - if ( !szIssueString[0] ) - { - V_sprintf_safe( szIssueString, "#Vote_%s", szIssue ); - } - - VoteIssue_t issue; - V_strcpy_safe( issue.szName, szIssue ); - V_strcpy_safe( issue.szNameString, szIssueString ); - issue.bIsActive = bIsActive; - // Send it over to the listpanel - m_VoteSetupIssues.AddToTail( issue ); + m_VoteSetupIssues.CopyAndAddToTail( szIssue ); } } } - + else + { + m_VoteSetupIssues.CopyAndAddToTail( "Voting disabled on this Server" ); + } m_pVoteSetupDialog->AddVoteIssues( m_VoteSetupIssues ); // Load up the list of Vote Issue Parameters @@ -1721,51 +1632,50 @@ void CHudVote::FireGameEvent( IGameEvent *event ) //----------------------------------------------------------------------------- void CHudVote::OnThink() { - C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); - if ( pLocalPlayer ) + // We delay hiding the menu after we cast a vote + if ( m_bPlayerVoted && m_flPostVotedHideTime > 0 && m_flPostVotedHideTime < gpGlobals->curtime ) { - bool bShowToPlayer = ( !m_nVoteTeamIndex || pLocalPlayer->GetTeamNumber() == m_nVoteTeamIndex ); + m_pVoteActive->SetVisible( false ); + m_bShowVoteActivePanel = false; + m_flPostVotedHideTime = -1; + } - // We delay hiding the menu after we cast a vote - if ( m_bPlayerVoted && m_flPostVotedHideTime > 0 && gpGlobals->curtime > m_flPostVotedHideTime ) - { - m_pVoteActive->SetVisible( false ); - m_bShowVoteActivePanel = false; - m_flPostVotedHideTime = -1; - } + if ( m_flVoteResultCycleTime > 0 && m_flVoteResultCycleTime < gpGlobals->curtime ) + { + m_pVoteActive->SetVisible( false ); + m_pVoteFailed->SetVisible( !m_bVotePassed ); + m_pVotePassed->SetVisible( m_bVotePassed ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" ); + + m_flVoteResultCycleTime = -1; + m_bPlayerVoted = false; + m_bVoteActive = false; + m_bShowVoteActivePanel = false; + m_iVoteCallerIdx = -1; + } - if ( m_flVoteResultCycleTime > 0 && gpGlobals->curtime > m_flVoteResultCycleTime ) + if ( m_bVoteActive ) + { + // driller: Need to rewrite this to handle all vote types (Yes/No and General) + if ( m_bIsYesNoVote && m_pVoteActive ) { - m_pVoteActive->SetVisible( false ); - m_pVoteFailed->SetVisible( !m_bVotePassed && bShowToPlayer ); - m_pVotePassed->SetVisible( m_bVotePassed && bShowToPlayer ); - g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" ); - - m_flVoteResultCycleTime = -1; - m_bPlayerVoted = false; - m_bVotingActive = false; - m_bShowVoteActivePanel = false; - m_iVoteCallerIdx = -1; - } + char szYesCount[512] = ""; + Q_snprintf( szYesCount, 512, "%d", m_nVoteOptionCount[0] ); - if ( m_bVotingActive && m_bShowVoteActivePanel ) - { - // driller: Need to rewrite this to handle all vote types (Yes/No and General) - if ( m_bIsYesNoVote && m_pVoteActive ) - { - char szYesCount[k_MAX_VOTE_NAME_LENGTH] = ""; - Q_snprintf( szYesCount, sizeof( szYesCount ), "%d", m_nVoteOptionCount[0] ); + char szNoCount[512] = ""; + Q_snprintf( szNoCount, 512, "%d", m_nVoteOptionCount[1] ); - char szNoCount[k_MAX_VOTE_NAME_LENGTH] = ""; - Q_snprintf( szNoCount, sizeof( szNoCount ), "%d", m_nVoteOptionCount[1] ); + m_pVoteActive->SetControlString( "Option1CountLabel", szYesCount ); + m_pVoteActive->SetControlString( "Option2CountLabel", szNoCount ); + } - m_pVoteActive->SetControlString( "Option1CountLabel", szYesCount ); - m_pVoteActive->SetControlString( "Option2CountLabel", szNoCount ); - } + if ( !m_pVoteActive->IsVisible() && m_bShowVoteActivePanel ) + { + m_pVoteActive->SetVisible( true ); - if ( !m_pVoteActive->IsVisible() && bShowToPlayer ) + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pLocalPlayer ) { - m_pVoteActive->SetVisible( true ); pLocalPlayer->EmitSound("Vote.Created"); } } @@ -1779,7 +1689,7 @@ void CHudVote::OnThink() //----------------------------------------------------------------------------- bool CHudVote::ShouldDraw( void ) { - return ( m_bVotingActive || gpGlobals->curtime < m_flHideTime ); + return ( m_bVoteActive || m_flHideTime > gpGlobals->curtime ); } //----------------------------------------------------------------------------- @@ -1790,6 +1700,22 @@ bool CHudVote::IsPlayingDemo() const return engine->IsPlayingDemo(); } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::SetVoteActive( bool bActive ) +{ + m_bVoteActive = bActive; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::ShowVoteUI( void ) +{ + m_bShowVoteActivePanel = true; +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/client/hud_vote.h b/game/client/hud_vote.h index 38956366..91ba1e9b 100644 --- a/game/client/hud_vote.h +++ b/game/client/hud_vote.h @@ -25,8 +25,6 @@ extern INetworkStringTable *g_pStringTableServerPopFiles; extern INetworkStringTable *g_pStringTableServerMapCycleMvM; #endif -static const int k_MAX_VOTE_NAME_LENGTH = 256; - namespace vgui { class SectionedListPanel; @@ -34,13 +32,6 @@ namespace vgui class ImageList; }; -struct VoteIssue_t -{ - char szName[k_MAX_VOTE_NAME_LENGTH]; - char szNameString[k_MAX_VOTE_NAME_LENGTH]; - bool bIsActive; -}; - class VoteBarPanel : public vgui::Panel, public CGameEventListener { DECLARE_CLASS_SIMPLE( VoteBarPanel, vgui::Panel ); @@ -78,9 +69,8 @@ class CVoteSetupDialog : public vgui::Frame virtual void PostApplySchemeSettings( vgui::IScheme *pScheme ); virtual void ApplySettings(KeyValues *inResourceData); - void InitializeIssueList( void ); void UpdateCurrentMap( void ); - void AddVoteIssues( CUtlVector< VoteIssue_t > &m_VoteSetupIssues ); + void AddVoteIssues( CUtlStringList &m_VoteSetupIssues ); void AddVoteIssueParams_MapCycle( CUtlStringList &m_VoteSetupMapCycle ); #ifdef TF_CLIENT_DLL @@ -104,7 +94,7 @@ class CVoteSetupDialog : public vgui::Frame vgui::Button *m_pCallVoteButton; vgui::ImageList *m_pImageList; - CUtlVector< VoteIssue_t > m_VoteIssues; + CUtlVector m_VoteIssues; CUtlVector m_VoteIssuesMapCycle; #ifdef TF_CLIENT_DLL @@ -147,12 +137,12 @@ class CHudVote : public vgui::EditablePanel, public CHudElement void MsgFunc_VoteSetup( bf_read &msg ); void PropagateOptionParameters( void ); - void ShowVoteUI( bool bShow ) { m_bShowVoteActivePanel = bShow; } + void ShowVoteUI( void ); bool IsVoteUIActive( void ); - bool IsVoteSystemActive( void ) { return m_bVoteSystemActive; } private: bool IsPlayingDemo() const; + void SetVoteActive( bool bActive ); EditablePanel *m_pVoteActive; VoteBarPanel *m_voteBar; @@ -161,7 +151,7 @@ class CHudVote : public vgui::EditablePanel, public CHudElement EditablePanel *m_pCallVoteFailed; CVoteSetupDialog *m_pVoteSetupDialog; - CUtlVector< VoteIssue_t > m_VoteSetupIssues; + CUtlStringList m_VoteSetupIssues; CUtlStringList m_VoteSetupMapCycle; #ifdef TF_CLIENT_DLL @@ -170,8 +160,7 @@ class CHudVote : public vgui::EditablePanel, public CHudElement CUtlStringList m_VoteSetupChoices; - bool m_bVotingActive; - bool m_bVoteSystemActive; + bool m_bVoteActive; float m_flVoteResultCycleTime; // what time will we cycle to the result float m_flHideTime; // what time will we hide bool m_bVotePassed; // what mode are we going to cycle to @@ -183,7 +172,6 @@ class CHudVote : public vgui::EditablePanel, public CHudElement float m_flPostVotedHideTime; bool m_bShowVoteActivePanel; int m_iVoteCallerIdx; - int m_nVoteTeamIndex; // If defined, only players on this team will see/vote on the issue }; #endif // HUD_VOTE_H diff --git a/game/client/hudelement.h b/game/client/hudelement.h index b903de5d..824cb975 100644 --- a/game/client/hudelement.h +++ b/game/client/hudelement.h @@ -58,6 +58,9 @@ class CHudElement : public CGameEventListener // Hidden bits. // HIDEHUD_ flags that note when this element should be hidden in the HUD virtual void SetHiddenBits( int iBits ); +#ifdef MAPBASE_VSCRIPT + int GetHiddenBits() const { return m_iHiddenBits; } +#endif bool IsParentedToClientDLLRootPanel() const; void SetParentedToClientDLLRootPanel( bool parented ); diff --git a/game/client/iclientmode.h b/game/client/iclientmode.h index 2b74f625..38b60047 100644 --- a/game/client/iclientmode.h +++ b/game/client/iclientmode.h @@ -112,6 +112,11 @@ abstract_class IClientMode virtual bool CanRecordDemo( char *errorMsg, int length ) const = 0; +#ifdef MAPBASE // From Alien Swarm SDK + virtual void OnColorCorrectionWeightsReset( void ) = 0; + virtual float GetColorCorrectionScale( void ) const = 0; +#endif + virtual void ComputeVguiResConditions( KeyValues *pkvConditions ) = 0; //============================================================================= diff --git a/game/client/iclientshadowmgr.h b/game/client/iclientshadowmgr.h index f2e2ad37..472bf51a 100644 --- a/game/client/iclientshadowmgr.h +++ b/game/client/iclientshadowmgr.h @@ -97,19 +97,23 @@ abstract_class IClientShadowMgr : public IGameSystemPerFrame // Set flashlight light world flag virtual void SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ) = 0; +#ifdef ASW_PROJECTED_TEXTURES + virtual void GetFrustumExtents( ClientShadowHandle_t handle, Vector &vecMin, Vector &vecMax ) = 0; +#endif + +#ifdef DYNAMIC_RTT_SHADOWS + // Toggle shadow casting from world light sources + virtual void SetShadowFromWorldLightsEnabled( bool bEnable ) = 0; +#endif + virtual void SetShadowsDisabled( bool bDisabled ) = 0; virtual void ComputeShadowDepthTextures( const CViewSetup &pView ) = 0; - virtual void GetFrustumExtents( ClientShadowHandle_t handle, Vector& vecMin, Vector& vecMax ) = 0; - - virtual ShadowHandle_t GetShadowHandle(ClientShadowHandle_t clienthandle) = 0; - virtual ShadowHandle_t GetActiveDepthTextureHandle() = 0; - virtual ShadowType_t GetActualShadowCastType(ClientShadowHandle_t handle) const = 0; +#ifdef VANCE + virtual ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ) = 0; virtual int GetNumShadowDepthtextures() = 0; - virtual CTextureReference GetShadowDepthTex(int num) = 0; - virtual ShadowHandle_t GetShadowDepthHandle(int num) = 0; - +#endif }; diff --git a/game/client/in_camera.cpp b/game/client/in_camera.cpp index ec40ac18..aa010732 100644 --- a/game/client/in_camera.cpp +++ b/game/client/in_camera.cpp @@ -60,7 +60,6 @@ void CAM_ToThirdPerson(void) { if ( cl_thirdperson.GetBool() == false ) { - g_ThirdPersonManager.SetDesiredCameraOffset( Vector( cam_idealdist.GetFloat(), cam_idealdistright.GetFloat(), cam_idealdistup.GetFloat() ) ); g_ThirdPersonManager.SetOverridingThirdPerson( true ); } diff --git a/game/client/in_joystick.cpp b/game/client/in_joystick.cpp index a3b63620..a2f73ee5 100644 --- a/game/client/in_joystick.cpp +++ b/game/client/in_joystick.cpp @@ -25,7 +25,9 @@ #include "tier0/icommandline.h" #include "inputsystem/iinputsystem.h" #include "inputsystem/ButtonCode.h" +#if _MSC_VER < 1900 #include "math.h" +#endif #include "tier1/convar_serverbounded.h" #include "cam_thirdperson.h" @@ -800,7 +802,7 @@ void CInput::JoyStickMove( float frametime, CUserCmd *cmd ) if ( m_flPreviousJoystickForward || m_flPreviousJoystickSide || m_flPreviousJoystickPitch || m_flPreviousJoystickYaw ) { - const Vector& vTempOffset = g_ThirdPersonManager.GetCameraOffsetAngles(); + Vector vTempOffset = g_ThirdPersonManager.GetCameraOffsetAngles(); // update the ideal pitch and yaw cam_idealpitch.SetValue( vTempOffset[ PITCH ] - viewangles[ PITCH ] ); diff --git a/game/client/in_main.cpp b/game/client/in_main.cpp index 0e3df34b..492b54a7 100644 --- a/game/client/in_main.cpp +++ b/game/client/in_main.cpp @@ -144,7 +144,7 @@ static kbutton_t in_grenade1; static kbutton_t in_grenade2; static kbutton_t in_attack3; kbutton_t in_ducktoggle; -kbutton_t in_throwgrenade; +kbutton_t in_throwgrenade; /* =========== @@ -1222,6 +1222,9 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo } // Let the move manager override anything it wants to. +#ifdef VGUI_SCREEN_FIX + cmd->buttons |= IN_VALIDVGUIINPUT; +#endif if ( g_pClientMode->CreateMove( input_sample_frametime, cmd ) ) { // Get current view angles after the client mode tweaks with it diff --git a/game/client/in_mouse.cpp b/game/client/in_mouse.cpp index 332b0ea1..bcf715a1 100644 --- a/game/client/in_mouse.cpp +++ b/game/client/in_mouse.cpp @@ -522,7 +522,7 @@ void CInput::ApplyMouse( QAngle& viewangles, CUserCmd *cmd, float mouse_x, float } else { - viewangles[PITCH] += CAM_CapPitch( m_pitch->GetFloat() * mouse_y ); + viewangles[PITCH] += m_pitch->GetFloat() * mouse_y; } // Check pitch bounds diff --git a/game/client/input.h b/game/client/input.h index 2fa2cec3..e34b82db 100644 --- a/game/client/input.h +++ b/game/client/input.h @@ -99,8 +99,7 @@ class CInput : public IInput virtual bool CAM_IsOrthographic() const; virtual void CAM_OrthographicSize( float& w, float& h ) const; - virtual float CAM_CapYaw( float fVal ) const { return fVal; } - virtual float CAM_CapPitch( float fVal ) const { return fVal; } + virtual float CAM_CapYaw( float fVal ) { return fVal; } #if defined( HL2_CLIENT_DLL ) // IK back channel info @@ -114,7 +113,7 @@ class CInput : public IInput virtual bool EnableJoystickMode(); // Private Implementation -protected: +private: // Implementation specific initialization void Init_Camera( void ); void Init_Keyboard( void ); @@ -135,8 +134,8 @@ class CInput : public IInput void GetAccumulatedMouseDeltasAndResetAccumulators( float *mx, float *my ); void GetMouseDelta( float inmousex, float inmousey, float *pOutMouseX, float *pOutMouseY ); void ScaleMouse( float *x, float *y ); - virtual void ApplyMouse( QAngle& viewangles, CUserCmd *cmd, float mouse_x, float mouse_y ); - virtual void MouseMove ( CUserCmd *cmd ); + void ApplyMouse( QAngle& viewangles, CUserCmd *cmd, float mouse_x, float mouse_y ); + void MouseMove ( CUserCmd *cmd ); // Joystick movement input helpers void ControllerMove ( float frametime, CUserCmd *cmd ); diff --git a/game/client/iviewrender.h b/game/client/iviewrender.h index c66061ae..8d797dea 100644 --- a/game/client/iviewrender.h +++ b/game/client/iviewrender.h @@ -115,6 +115,13 @@ abstract_class IViewRender virtual void SetScreenOverlayMaterial( IMaterial *pMaterial ) = 0; virtual IMaterial *GetScreenOverlayMaterial( ) = 0; +#ifdef MAPBASE + virtual void SetIndexedScreenOverlayMaterial( int i, IMaterial *pMaterial ) = 0; + virtual IMaterial *GetIndexedScreenOverlayMaterial( int i ) = 0; + virtual void ResetIndexedScreenOverlays() = 0; + virtual int GetMaxIndexedScreenOverlays() const = 0; +#endif + virtual void WriteSaveGameScreenshot( const char *pFilename ) = 0; virtual void WriteSaveGameScreenshotOfSize( const char *pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false ) = 0; diff --git a/game/client/mapbase/c_func_clientclip.cpp b/game/client/mapbase/c_func_clientclip.cpp new file mode 100644 index 00000000..f6595949 --- /dev/null +++ b/game/client/mapbase/c_func_clientclip.cpp @@ -0,0 +1,93 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//===========================================================================// + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +class C_FuncClientClip : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_FuncClientClip, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + void OnDataChanged( DataUpdateType_t type ); + void ClientThink(); + bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace ); + + bool m_bDisabled; +}; + +IMPLEMENT_CLIENTCLASS_DT( C_FuncClientClip, DT_FuncClientClip, CFuncClientClip ) + RecvPropBool( RECVINFO( m_bDisabled ) ), +END_RECV_TABLE() + +void C_FuncClientClip::OnDataChanged( DataUpdateType_t type ) +{ + BaseClass::OnDataChanged( type ); + + //if ( type == DATA_UPDATE_CREATED ) + //{ + SetSolid(GetMoveParent() ? SOLID_VPHYSICS : SOLID_BSP); // SOLID_VPHYSICS + //} + + if ( !m_bDisabled ) + { + VPhysicsDestroyObject(); + VPhysicsInitShadow( true, true ); + + // Think constantly updates the shadow + if (GetMoveParent()) + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } + else + { + // Disabling + VPhysicsDestroyObject(); + SetNextClientThink( CLIENT_THINK_NEVER ); + } +} + +void C_FuncClientClip::ClientThink() +{ + // We shouldn't be thinking if we're disabled + Assert(!m_bDisabled); + + if (VPhysicsGetObject()) + { + // Constantly updates the shadow. + // This think function should really only be active when we're parented. + VPhysicsGetObject()->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, TICK_INTERVAL ); + } + else + { + // This should never happen... + VPhysicsInitShadow( true, true ); + } + + BaseClass::ClientThink(); +} + +bool C_FuncClientClip::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace ) +{ + if ( m_bDisabled ) + return false; + + if ( !VPhysicsGetObject() ) + return false; + + physcollision->TraceBox( ray, VPhysicsGetObject()->GetCollide(), GetAbsOrigin(), GetAbsAngles(), &trace ); + + if ( trace.DidHit() ) + { + trace.surface.surfaceProps = VPhysicsGetObject()->GetMaterialIndex(); + return true; + } + + return false; +} diff --git a/game/client/mapbase/c_func_fake_worldportal.cpp b/game/client/mapbase/c_func_fake_worldportal.cpp new file mode 100644 index 00000000..703d5a88 --- /dev/null +++ b/game/client/mapbase/c_func_fake_worldportal.cpp @@ -0,0 +1,171 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Recreates Portal 2 linked_portal_door visual functionality using SDK code only. +// (basically a combination of point_camera and func_reflective_glass) +// +// $NoKeywords: $ +//===========================================================================// +#include "cbase.h" +#include "view_shared.h" +#include "viewrender.h" +#include "c_func_fake_worldportal.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +IMPLEMENT_CLIENTCLASS_DT( C_FuncFakeWorldPortal, DT_FuncFakeWorldPortal, CFuncFakeWorldPortal ) + + RecvPropEHandle( RECVINFO( m_hTargetPlane ) ), + RecvPropVector( RECVINFO( m_PlaneAngles ) ), + RecvPropInt( RECVINFO( m_iSkyMode ) ), + RecvPropFloat( RECVINFO( m_flScale ) ), + RecvPropString( RECVINFO( m_iszRenderTarget ) ), + RecvPropEHandle( RECVINFO( m_hFogController ) ), + +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +C_EntityClassList g_FakeWorldPortalList; +template<> C_FuncFakeWorldPortal *C_EntityClassList::m_pClassList = NULL; + +C_FuncFakeWorldPortal* GetFakeWorldPortalList() +{ + return g_FakeWorldPortalList.m_pClassList; +} + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +C_FuncFakeWorldPortal::C_FuncFakeWorldPortal() +{ + m_iszRenderTarget[0] = '\0'; + + g_FakeWorldPortalList.Insert( this ); +} + +C_FuncFakeWorldPortal::~C_FuncFakeWorldPortal() +{ + g_FakeWorldPortalList.Remove( this ); +} + + +bool C_FuncFakeWorldPortal::ShouldDraw() +{ + return true; +} + + +//----------------------------------------------------------------------------- +// Iterates through fake world portals instead of just picking one +//----------------------------------------------------------------------------- +C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, + Vector &vecAbsPlaneNormal, float &flLocalPlaneDist, const Frustum_t &frustum ) +{ + // Early out if no cameras + C_FuncFakeWorldPortal *pReflectiveGlass = NULL; + if (!pStart) + pReflectiveGlass = GetFakeWorldPortalList(); + else + pReflectiveGlass = pStart->m_pNext; + + cplane_t localPlane, worldPlane; + Vector vecMins, vecMaxs, vecLocalOrigin, vecAbsOrigin, vecDelta; + + for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) + { + if ( pReflectiveGlass->IsDormant() ) + continue; + + if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) ) + continue; + + // Must have valid plane + if ( !pReflectiveGlass->m_hTargetPlane ) + continue; + + pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); + if ( R_CullBox( vecMins, vecMaxs, frustum ) ) + continue; + + const model_t *pModel = pReflectiveGlass->GetModel(); + const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform(); + + int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); + for ( int i = 0; i < nCount; ++i ) + { + modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecLocalOrigin ); + + MatrixTransformPlane( mat, localPlane, worldPlane ); // Transform to world space + + if ( view.origin.Dot( worldPlane.normal ) <= worldPlane.dist ) // Check for view behind plane + continue; + + VectorTransform( vecLocalOrigin, mat, vecAbsOrigin ); + VectorSubtract( vecAbsOrigin, view.origin, vecDelta ); + + if ( vecDelta.Dot( worldPlane.normal ) >= 0 ) // Backface cull + continue; + + flLocalPlaneDist = localPlane.dist; + vecAbsPlaneNormal = worldPlane.normal; + + return pReflectiveGlass; + } + } + + return NULL; +} + +void C_FuncFakeWorldPortal::OnDataChanged( DataUpdateType_t type ) +{ + // Reset render texture + m_pRenderTarget = NULL; + + // Reset fog + m_pFog = NULL; + + return BaseClass::OnDataChanged( type ); +} + +extern ITexture *GetWaterReflectionTexture( void ); + +ITexture *C_FuncFakeWorldPortal::RenderTarget() +{ + if (m_iszRenderTarget[0] != '\0') + { + if (!m_pRenderTarget) + { + // We don't use a CTextureReference for this because we don't want to shut down the texture on removal/change + m_pRenderTarget = materials->FindTexture( m_iszRenderTarget, TEXTURE_GROUP_RENDER_TARGET ); + } + + if (m_pRenderTarget) + return m_pRenderTarget; + } + + return GetWaterReflectionTexture(); +} + +fogparams_t *C_FuncFakeWorldPortal::GetFog() +{ + if (m_pFog) + return m_pFog; + + if (m_hFogController) + { + C_FogController *pFogController = dynamic_cast(m_hFogController.Get()); + if (pFogController) + { + m_pFog = &pFogController->m_fog; + } + else + { + Warning("%s is not an env_fog_controller\n", m_hFogController->GetEntityName()); + } + } + + return NULL; +} diff --git a/game/client/mapbase/c_func_fake_worldportal.h b/game/client/mapbase/c_func_fake_worldportal.h new file mode 100644 index 00000000..bc1d9e61 --- /dev/null +++ b/game/client/mapbase/c_func_fake_worldportal.h @@ -0,0 +1,62 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Recreates Portal 2 linked_portal_door functionality using SDK code only. +// (basically a combination of point_camera and func_reflective_glass) +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef C_FUNC_FAKE_WORLDPORTAL +#define C_FUNC_FAKE_WORLDPORTAL + +#ifdef _WIN32 +#pragma once +#endif + +struct cplane_t; +class CViewSetup; + +class C_FuncFakeWorldPortal : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_FuncFakeWorldPortal, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + C_FuncFakeWorldPortal(); + virtual ~C_FuncFakeWorldPortal(); + + virtual bool ShouldDraw(); + virtual void OnDataChanged( DataUpdateType_t type ); + + SkyboxVisibility_t SkyMode() { return m_iSkyMode; } + + ITexture *RenderTarget(); + + fogparams_t *GetFog(); + +public: + + EHANDLE m_hTargetPlane; + QAngle m_PlaneAngles; + SkyboxVisibility_t m_iSkyMode; + float m_flScale; + + EHANDLE m_hFogController; + fogparams_t *m_pFog; + + char m_iszRenderTarget[64]; + ITexture *m_pRenderTarget; + + C_FuncFakeWorldPortal *m_pNext; +}; + +//----------------------------------------------------------------------------- +// Do we have reflective glass in view? If so, what's the reflection plane? +//----------------------------------------------------------------------------- +C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, + Vector &vecAbsPlaneNormal, float &flLocalPlaneDist, const Frustum_t &frustum ); + + +#endif // C_FUNC_FAKE_WORLDPORTAL + + diff --git a/game/client/mapbase/c_point_glow.cpp b/game/client/mapbase/c_point_glow.cpp new file mode 100644 index 00000000..590e0f3e --- /dev/null +++ b/game/client/mapbase/c_point_glow.cpp @@ -0,0 +1,103 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase off-shoot of tf_glow (created using SDK code only) +// +//===========================================================================// + +#include "cbase.h" +#include "glow_outline_effect.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +class C_PointGlow : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_PointGlow, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + ~C_PointGlow(); + + enum + { + GLOW_VIS_ALWAYS, + GLOW_VIS_NOT_WHEN_VISIBLE, + GLOW_VIS_ONLY_WHEN_VISIBLE, + }; + + void OnDataChanged( DataUpdateType_t type ); + + CGlowObject *GetGlowObject( void ){ return m_pGlowEffect; } + void UpdateGlowEffect( void ); + void DestroyGlowEffect( void ); + + EHANDLE m_hGlowTarget; + color32 m_GlowColor; + + bool m_bGlowDisabled; + CGlowObject *m_pGlowEffect; +}; + +IMPLEMENT_CLIENTCLASS_DT( C_PointGlow, DT_PointGlow, CPointGlow ) + RecvPropEHandle( RECVINFO( m_hGlowTarget ) ), + RecvPropInt( RECVINFO( m_GlowColor ), 0, RecvProxy_IntToColor32 ), + RecvPropBool( RECVINFO( m_bGlowDisabled ) ), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_PointGlow::~C_PointGlow() +{ + DestroyGlowEffect(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointGlow::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + UpdateGlowEffect(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointGlow::UpdateGlowEffect( void ) +{ + // destroy the existing effect + if ( m_pGlowEffect ) + { + DestroyGlowEffect(); + } + + // create a new effect + if ( !m_bGlowDisabled ) + { + Vector4D vecColor( m_GlowColor.r, m_GlowColor.g, m_GlowColor.b, m_GlowColor.a ); + for (int i = 0; i < 4; i++) + { + if (vecColor[i] == 0.0f) + continue; + + vecColor[i] /= 255.0f; + } + + m_pGlowEffect = new CGlowObject( m_hGlowTarget, vecColor.AsVector3D(), vecColor.w, true ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PointGlow::DestroyGlowEffect( void ) +{ + if ( m_pGlowEffect ) + { + delete m_pGlowEffect; + m_pGlowEffect = NULL; + } +} diff --git a/game/client/mapbase/c_vgui_text_display.cpp b/game/client/mapbase/c_vgui_text_display.cpp new file mode 100644 index 00000000..f0d2032d --- /dev/null +++ b/game/client/mapbase/c_vgui_text_display.cpp @@ -0,0 +1,282 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Displays easy, flexible VGui text. Mapbase equivalent of point_worldtext. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "panelmetaclassmgr.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include +#include +#include +#include "ienginevgui.h" +#include "c_vguiscreen.h" +#include "vgui_bitmapbutton.h" +#include "vgui_bitmappanel.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace vgui; + +//----------------------------------------------------------------------------- +// vgui_text_display +//----------------------------------------------------------------------------- +class C_VGuiTextDisplay : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_VGuiTextDisplay, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + + C_VGuiTextDisplay(); + ~C_VGuiTextDisplay(); + + virtual void PostDataUpdate( DataUpdateType_t updateType ); + + bool IsEnabled( void ) const { return m_bEnabled; } + + const char *GetDisplayText( void ) const { return m_szDisplayText; } + const char *GetFontName( void ) const { return m_szFont; } + int GetResolution( void ) const { return m_iResolution; } + vgui::Label::Alignment GetContentAlignment() const { return m_iContentAlignment; } + + bool NeedsTextUpdate() { return m_bTextNeedsUpdate; } + void UpdatedText() { m_bTextNeedsUpdate = false; } + +private: + bool m_bEnabled; + char m_szDisplayText[256]; + vgui::Label::Alignment m_iContentAlignment; + char m_szFont[64]; + int m_iResolution; + + bool m_bTextNeedsUpdate; +}; + +IMPLEMENT_CLIENTCLASS_DT( C_VGuiTextDisplay, DT_VGuiTextDisplay, CVGuiTextDisplay ) + RecvPropBool( RECVINFO( m_bEnabled ) ), + RecvPropString( RECVINFO( m_szDisplayText ) ), + RecvPropInt( RECVINFO( m_iContentAlignment ) ), + RecvPropString( RECVINFO( m_szFont ) ), + RecvPropInt( RECVINFO( m_iResolution ) ), +END_RECV_TABLE() + +C_VGuiTextDisplay::C_VGuiTextDisplay() +{ +} + +C_VGuiTextDisplay::~C_VGuiTextDisplay() +{ +} + +void C_VGuiTextDisplay::PostDataUpdate( DataUpdateType_t updateType ) +{ + BaseClass::PostDataUpdate( updateType ); + + // For now, always update + m_bTextNeedsUpdate = true; +} + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Control screen +//----------------------------------------------------------------------------- +class C_TextDisplayPanel : public CVGuiScreenPanel +{ + DECLARE_CLASS( C_TextDisplayPanel, CVGuiScreenPanel ); + +public: + C_TextDisplayPanel( vgui::Panel *parent, const char *panelName ); + ~C_TextDisplayPanel( void ); + + virtual void ApplySchemeSettings( IScheme *pScheme ); + + void UpdateText(); + + virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ); + virtual void OnTick( void ); + virtual void Paint( void ); + +private: + + CHandle m_hVGUIScreen; + CHandle m_hScreenEntity; + + // VGUI specifics + Label *m_pDisplayTextLabel; +}; + +DECLARE_VGUI_SCREEN_FACTORY( C_TextDisplayPanel, "text_display_panel" ); + +CUtlVector g_TextDisplays; + +//----------------------------------------------------------------------------- +// Constructor: +//----------------------------------------------------------------------------- +C_TextDisplayPanel::C_TextDisplayPanel( vgui::Panel *parent, const char *panelName ) +: BaseClass( parent, "C_TextDisplayPanel"/*, vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/WorldTextPanel.res", "WorldTextPanel" )*/ ) +{ + // Add ourselves to the global list of movie displays + g_TextDisplays.AddToTail( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Clean up the movie +//----------------------------------------------------------------------------- +C_TextDisplayPanel::~C_TextDisplayPanel( void ) +{ + // Remove ourselves from the global list of movie displays + g_TextDisplays.FindAndRemove( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Setup our scheme +//----------------------------------------------------------------------------- +void C_TextDisplayPanel::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + /* + m_pDisplayTextLabel->SetFgColor( Color( 255, 255, 255, 255 ) ); + m_pDisplayTextLabel->SetText( "" ); + m_pDisplayTextLabel->SetVisible( false ); + */ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_TextDisplayPanel::UpdateText() +{ + color32 clr = m_hScreenEntity->GetRenderColor(); + + m_pDisplayTextLabel->SetFgColor( Color( clr.r, clr.g, clr.b, clr.a ) ); + m_pDisplayTextLabel->SetText( m_hScreenEntity->GetDisplayText() ); + + //SetSize( m_hScreenEntity->GetTextSize(), m_hScreenEntity->GetTextSize() ); + //m_pDisplayTextLabel->SetSize( m_hScreenEntity->GetTextSize(), m_hScreenEntity->GetTextSize() ); + + Label::Alignment iAlignment = m_hScreenEntity->GetContentAlignment(); + + switch (iAlignment) + { + // Use a special scaling method when using a south alignment + case Label::Alignment::a_southwest: + case Label::Alignment::a_south: + case Label::Alignment::a_southeast: + int lW, lT; + m_pDisplayTextLabel->GetContentSize( lW, lT ); + SetSize( m_hScreenEntity->GetResolution(), lT ); + m_pDisplayTextLabel->SetSize( m_hScreenEntity->GetResolution(), lT ); + + float sW, sT; + m_hVGUIScreen->GetSize( sW, sT ); + //Msg( "Screen width: %f, new height: %f\n", sW, sW * (lT / m_hScreenEntity->GetResolution()) ); + m_hVGUIScreen->SetHeight( sW * ((float)lT / (float)m_hScreenEntity->GetResolution()) ); + m_hVGUIScreen->SetPixelHeight( lT ); + break; + + default: + SetSize( m_hScreenEntity->GetResolution(), m_hScreenEntity->GetResolution() ); + m_pDisplayTextLabel->SetSize( m_hScreenEntity->GetResolution(), m_hScreenEntity->GetResolution() ); + break; + } + + m_pDisplayTextLabel->SetContentAlignment( iAlignment ); + + bool bWrap = true; + bool bCenterWrap = false; + switch (iAlignment) + { + // Center wrap if centered + case Label::Alignment::a_north: + case Label::Alignment::a_center: + case Label::Alignment::a_south: + bCenterWrap = true; + break; + + // HACKHACK: Don't wrap if using an east alignment + case Label::Alignment::a_northeast: + case Label::Alignment::a_east: + case Label::Alignment::a_southeast: + bWrap = false; + break; + } + + m_pDisplayTextLabel->SetWrap( bWrap ); + m_pDisplayTextLabel->SetCenterWrap( bCenterWrap ); + + //Msg( "Resolution is %i\n", m_hScreenEntity->GetResolution() ); + + const char *pszFontName = m_hScreenEntity->GetFontName(); + if (pszFontName && pszFontName[0] != '\0') + { + HFont font = scheme()->GetIScheme( GetScheme() )->GetFont( pszFontName ); + m_pDisplayTextLabel->SetFont( font ); + } + + m_pDisplayTextLabel->SetVisible( true ); +} + +//----------------------------------------------------------------------------- +// Initialization +//----------------------------------------------------------------------------- +bool C_TextDisplayPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ) +{ + if ( !BaseClass::Init( pKeyValues, pInitData ) ) + return false; + + // Make sure we get ticked... + vgui::ivgui()->AddTickSignal( GetVPanel() ); + + m_pDisplayTextLabel = dynamic_cast(FindChildByName( "TextDisplay" )); + + // Save this for simplicity later on + m_hVGUIScreen = dynamic_cast( GetEntity() ); + if ( m_hVGUIScreen != NULL ) + { + // Also get the associated entity + m_hScreenEntity = dynamic_cast(m_hVGUIScreen->GetOwnerEntity()); + UpdateText(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Update the display string +//----------------------------------------------------------------------------- +void C_TextDisplayPanel::OnTick() +{ + if (m_hScreenEntity->NeedsTextUpdate()) + { + UpdateText(); + m_hScreenEntity->UpdatedText(); + } + + BaseClass::OnTick(); +} + +ConVar r_vguitext_bg( "r_vguitext_bg", "0" ); + +//----------------------------------------------------------------------------- +// Purpose: Update and draw the frame +//----------------------------------------------------------------------------- +void C_TextDisplayPanel::Paint( void ) +{ + // Black out the background (we could omit drawing under the video surface, but this is straight-forward) + if ( r_vguitext_bg.GetBool() ) + { + surface()->DrawSetColor( 0, 0, 0, 255 ); + surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() ); + + //surface()->DrawSetColor( 64, 64, 64, 255 ); + //surface()->DrawFilledRect( 0, 0, m_pDisplayTextLabel->GetWide(), m_pDisplayTextLabel->GetTall() ); + } + + // Parent's turn + BaseClass::Paint(); +} diff --git a/game/client/mapbase/mapbase_autocubemap.cpp b/game/client/mapbase/mapbase_autocubemap.cpp new file mode 100644 index 00000000..03602ef2 --- /dev/null +++ b/game/client/mapbase/mapbase_autocubemap.cpp @@ -0,0 +1,280 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: A utility which automatically generates HDR and LDR cubemaps. +// This has the following purposes: +// +// 1. Allow both HDR and LDR cubemaps to be generated automatically after a map is compiled +// 2. Have a way to batch build cubemaps for several levels at once +// +// Author: Blixibon +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "tier0/icommandline.h" +#include "igamesystem.h" +#include "filesystem.h" +#include "utlbuffer.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern const char *g_MapName; + +ConVar autocubemap_hdr_do_both( "autocubemap_hdr_do_both", "1" ); +ConVar autocubemap_hdr_value( "autocubemap_hdr_value", "2" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CAutoCubemapSystem : public CAutoGameSystem +{ +public: + CAutoCubemapSystem() : CAutoGameSystem( "CAutoCubemapSystem" ) + { + } + + virtual bool Init() + { + const char *pszFile = NULL; + if (CommandLine()->CheckParm( "-autocubemap", &pszFile )) + { + if (!pszFile || pszFile[0] == '\0') + { + // Assume that we just want to autocubemap the first map we load + // (no code here for now) + } + else + { + LoadFile( pszFile ); + } + + // Begin autocubemap with the first level we load + m_bAutoCubemapOnFirstLevel = true; + } + + return true; + } + + virtual void LevelInitPostEntity() + { + if (m_bAutoCubemapActive) + { + if (m_bAutoCubemapBuildingCubemaps) + { + // Check if we need to do the other HDR level + if (autocubemap_hdr_do_both.GetBool() && !m_bAutoCubemapDoingBoth) + { + m_bAutoCubemapBuildingCubemaps = false; + m_bAutoCubemapDoingBoth = true; + + // Change the HDR level and restart the map + //ConVarRef mat_hdr_level( "mat_hdr_level" ); + engine->ClientCmd_Unrestricted( VarArgs( "toggle mat_hdr_level 0 %i; restart", autocubemap_hdr_value.GetInt() ) ); + } + else + { + // Go to the next map + m_bAutoCubemapBuildingCubemaps = false; + m_bAutoCubemapDoingBoth = false; + + m_AutoCubemapMapsIndex++; + if (m_AutoCubemapMapsIndex < m_AutoCubemapMaps.Count()) + { + engine->ClientCmd_Unrestricted( VarArgs( "map %s", m_AutoCubemapMaps[m_AutoCubemapMapsIndex] ) ); + } + else + { + // CUBEMAPPER FINISHED + m_AutoCubemapMaps.PurgeAndDeleteElements(); + m_AutoCubemapMapsIndex = 0; + m_bAutoCubemapActive = false; + + Msg( "CUBEMAPPER FINISHED\n" ); + + if (autocubemap_hdr_do_both.GetBool()) + { + engine->ClientCmd_Unrestricted( VarArgs( "mat_hdr_level %i", m_iAutoCubemapUserHDRLevel ) ); + } + } + } + } + else + { + // Build cubemaps for this map + m_bAutoCubemapBuildingCubemaps = true; + engine->ClientCmd_Unrestricted( "exec buildcubemaps_prep; buildcubemaps" ); + } + } + else if (m_bAutoCubemapOnFirstLevel) + { + // Start autocubemap now + StartAutoCubemap(); + m_bAutoCubemapOnFirstLevel = false; + } + } + + //------------------------------------------------------------------------------------- + + void StartAutoCubemap() + { + if (m_AutoCubemapMaps.Count() <= 0) + { + //Msg("No maps to cubemap with!\n"); + //return; + + // Just do this map + m_AutoCubemapMaps.AddToTail( strdup( g_MapName ) ); + } + + if (autocubemap_hdr_do_both.GetBool()) + { + // Save the user's HDR level + ConVarRef mat_hdr_level( "mat_hdr_level" ); + m_iAutoCubemapUserHDRLevel = mat_hdr_level.GetInt(); + } + + m_bAutoCubemapActive = true; + m_AutoCubemapMapsIndex = 0; + + if (FStrEq( m_AutoCubemapMaps[m_AutoCubemapMapsIndex], g_MapName )) + { + // Build cubemaps right here, right now + m_bAutoCubemapBuildingCubemaps = true; + engine->ClientCmd_Unrestricted( "exec buildcubemaps_prep; buildcubemaps" ); + } + else + { + // Go to that map + engine->ClientCmd_Unrestricted( VarArgs( "map %s", m_AutoCubemapMaps[m_AutoCubemapMapsIndex] ) ); + } + } + + void LoadFile( const char *pszFile ) + { + KeyValues *pKV = new KeyValues( "AutoCubemap" ); + + if ( pKV->LoadFromFile( filesystem, pszFile, NULL ) ) + { + KeyValues *pSubKey = pKV->GetFirstSubKey(); + + while ( pSubKey ) + { + m_AutoCubemapMaps.AddToTail( strdup(pSubKey->GetName()) ); + pSubKey = pSubKey->GetNextKey(); + } + + Msg( "Initted autocubemap\n" ); + } + else + { + Warning( "Unable to load autocubemap file \"%s\"\n", pszFile ); + } + + pKV->deleteThis(); + } + + void Clear() + { + m_bAutoCubemapActive = false; + m_bAutoCubemapBuildingCubemaps = false; + m_bAutoCubemapDoingBoth = false; + + m_AutoCubemapMaps.PurgeAndDeleteElements(); + m_AutoCubemapMapsIndex = 0; + } + + void PrintState() + { + char szCmd[1024] = { 0 }; + + if (m_AutoCubemapMaps.Count() > 0) + { + Q_strncpy( szCmd, "=== CUBEMAPPER MAP LIST ===\n", sizeof( szCmd ) ); + + FOR_EACH_VEC( m_AutoCubemapMaps, i ) + { + Q_snprintf( szCmd, sizeof( szCmd ), "%s%s\n", szCmd, m_AutoCubemapMaps[i] ); + } + + Q_strncat( szCmd, "========================", sizeof( szCmd ), COPY_ALL_CHARACTERS ); + + Q_snprintf( szCmd, sizeof( szCmd ), "%s\nNumber of maps: %i (starting at %i)\n", szCmd, m_AutoCubemapMaps.Count(), m_AutoCubemapMapsIndex ); + } + else + { + Q_strncat( szCmd, "========================\n", sizeof( szCmd ), COPY_ALL_CHARACTERS ); + Q_strncat( szCmd, "There are no maps selected. Use 'autocubemap_init' to load a map list.\nIf 'autocubemap_start' is executed while no maps are selected, only the current map will have cubemaps generated.\n", sizeof( szCmd ), COPY_ALL_CHARACTERS ); + Q_strncat( szCmd, "========================\n", sizeof( szCmd ), COPY_ALL_CHARACTERS ); + } + + Msg( "%s", szCmd ); + } + + //------------------------------------------------------------------------------------- + + bool m_bAutoCubemapActive = false; + bool m_bAutoCubemapBuildingCubemaps = false; + bool m_bAutoCubemapDoingBoth = false; + int m_iAutoCubemapUserHDRLevel; // For setting the user back to the right HDR level when we're finished + + // Start autocubemap with the first level we load (used for launch parameter) + bool m_bAutoCubemapOnFirstLevel = false; + + CUtlVector m_AutoCubemapMaps; + int m_AutoCubemapMapsIndex; +}; + +CAutoCubemapSystem g_AutoCubemapSystem; + +CON_COMMAND( autocubemap_init, "Inits autocubemap" ) +{ + if (gpGlobals->maxClients > 1) + { + Msg( "Can't run autocubemap in multiplayer\n" ); + return; + } + + if (args.ArgC() <= 1) + { + Msg("Format: autocubemap_init \n"); + return; + } + + g_AutoCubemapSystem.LoadFile( args.Arg( 1 ) ); +} + +CON_COMMAND( autocubemap_print, "Prints current autocubemap information" ) +{ + if (gpGlobals->maxClients > 1) + { + Msg("Can't run autocubemap in multiplayer\n"); + return; + } + + g_AutoCubemapSystem.PrintState(); +} + +CON_COMMAND( autocubemap_clear, "Clears autocubemap stuff" ) +{ + if (gpGlobals->maxClients > 1) + { + Msg("Can't run autocubemap in multiplayer\n"); + return; + } + + g_AutoCubemapSystem.Clear(); +} + +CON_COMMAND( autocubemap_start, "Begins the autocubemap (it's recommended to check 'autocubemap_print' before running this command)" ) +{ + if (gpGlobals->maxClients > 1) + { + Msg("Can't run autocubemap in multiplayer\n"); + return; + } + + g_AutoCubemapSystem.StartAutoCubemap(); +} diff --git a/game/client/mapbase/vscript_vgui.cpp b/game/client/mapbase/vscript_vgui.cpp new file mode 100644 index 00000000..8d08e8be --- /dev/null +++ b/game/client/mapbase/vscript_vgui.cpp @@ -0,0 +1,3891 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// Author: samisalreadytaken +// +//=============================================================================// + + +#include "cbase.h" +#include "tier1/utlcommon.h" + +#include "inputsystem/iinputsystem.h" +#include "iinput.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "matsys_controls/matsyscontrols.h" +#include "VGuiMatSurface/IMatSystemSurface.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +#if VGUI_TGA_IMAGE_PANEL +#include "bitmap/tgaloader.h" +#endif + +#if !defined(NO_STEAM) +#include "steam/steam_api.h" +#include "vgui_avatarimage.h" +#endif + +#include "view.h" +#include "hudelement.h" +//#include "iclientmode.h" // g_pClientMode->GetViewport() + +#include "vscript_vgui.h" +#include "vscript_vgui.nut" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//============================================================================= +// +// Exposing a new panel class (e.g. vgui::FileOpenDialog): +// +// 1. Create C++ bindings using 'CLASS_HELPER_INTERFACE( FileOpenDialog, Frame ){};' +// 2. Define script bindings using '#define DEFINE_VGUI_SCRIPTFUNC_FileOpenDialog()' +// 3. Create 'class CScript_FileOpenDialog : FileOpenDialog' with vgui message callbacks and overrides if needed +// 4. Create script helper using 'BEGIN_VGUI_HELPER( FileOpenDialog )', 'END_VGUI_HELPER()'. This determines the script class name. +// 5. Register script bindings with 'BEGIN_SCRIPTDESC_VGUI( FileOpenDialog )', 'END_SCRIPTDESC()' +// 6. Add new condition in CScriptVGUI::CreatePanel() +// +// +// +// CScript_FileOpenDialog_Helper +// ^^ +// IScript_FileOpenDialog << CScript_FileOpenDialog +// ^^ ^^ +// IScript_Frame FileOpenDialog +// ^^ ^^ +// IScript_Panel Frame +// ^^ ^^ +// CScriptVGUIObject Panel +// +//============================================================================= + + +// When enabled, script panels will be parented to custom root panels. +// When disabled, script panels will be parented to engine root panels, and allow Z values for script panels to be interplaced amongst non-script panels. +// Changing this is not backwards compatible, as existing top level script panel depth would then change relative to non-script panels. +#define SCRIPT_ENGINE_ROOT_PANELS 1 + +// NOTE: causes rendering issues +#define ALLOW_SCRIPT_HUD_VIEWPORT_ROOT_PANEL 0 + +#define ALLOW_SCRIPT_GAMEUI_ROOT_PANEL 0 + +// On level transitions Restore is called up to 4 times in a row (due to .hl? client state files), each time +// trying to restore script panels from pre and post transitions, failing every time because script panels are +// destroyed on level shutdown but after client state files are written. +// +// Script variables are also reset between each OnRestore callback, causing duplicate panels if user scripts create panels +// by checking restored script variables. +// +// The workaround hack is to queue OnRestore callbacks with a think function. +// +// This code is left here for testing. +#define SCRIPT_VGUI_SAVERESTORE 0 + +#define SCRIPT_VGUI_SIGNAL_INTERFACE 0 + + + +#ifdef _DEBUG +#define DebugMsg(...) ConColorMsg( Color(196, 196, 156, 255), __VA_ARGS__ ) +#define DebugWarning(...) Warning( __VA_ARGS__ ) +#define DebugDevMsg(...) DevMsg( __VA_ARGS__ ) + +#define DBG_PARAM(...) __VA_ARGS__ +#else +#define DebugMsg(...) (void)(0) +#define DebugWarning(...) (void)(0) +#define DebugDevMsg(...) (void)(0) + +#define DBG_PARAM(...) +#endif + + + +template< typename T > +class CCopyableUtlVectorConservative : public CUtlVectorConservative< T > +{ + typedef CUtlVectorConservative< T > BaseClass; +public: + explicit CCopyableUtlVectorConservative( int growSize = 0, int initSize = 0 ) : BaseClass( growSize, initSize ) {} + explicit CCopyableUtlVectorConservative( T* pMemory, int numElements ) : BaseClass( pMemory, numElements ) {} + CCopyableUtlVectorConservative( CCopyableUtlVectorConservative const& vec ) { this->CopyArray( vec.Base(), vec.Count() ); } +}; + + +using namespace vgui; +class IScriptVGUIObject; +struct FontData_t; + +// Aliases contain only one font definition unless 'yres' was defined +typedef CCopyableUtlVectorConservative< FontData_t > fontalias_t; +typedef CUtlDict< fontalias_t > CFontDict; + + +CFontDict g_ScriptFonts( k_eDictCompareTypeCaseSensitive ); +CUtlVector< int > g_ScriptTextureIDs; +CUtlLinkedList< IScriptVGUIObject*, unsigned short > g_ScriptPanels; + + +// Boundary is not checked in Surface, keep count manually to sanitise user input. +static int g_nFontCount = 0; + +static inline HFont IntToFontHandle( int i ) +{ + if ( i < 0 || i > g_nFontCount ) + return INVALID_FONT; + return static_cast< unsigned int >(i); +} + +// vscript does not support unsigned int, +// but the representation of the handle does not matter, +// and these handles are CUtlVector indices +static inline int HandleToInt( unsigned int i ) +{ + return static_cast< int >(i); +} + + +struct FontData_t +{ + HFont font; + char *name; + int tall; + int weight; + int blur; + int scanlines; + int flags; + //int range_min; + //int range_max; + int yres_min; + int yres_max; + bool proportional; +}; + +static const char *GetFixedFontName( const char *name, bool proportional ) +{ + static char fontName[64]; + V_snprintf( fontName, sizeof(fontName), "%s-%s", name, proportional ? "p" : "no" ); + return fontName; +} + +CON_COMMAND( vgui_spew_fonts_script, "" ) +{ + char fontName[64]; + + FOR_EACH_DICT_FAST( g_ScriptFonts, i ) + { + const FontData_t &data = g_ScriptFonts[i].Head(); + const char *name = surface()->GetFontName( data.font ); + const char *alias = g_ScriptFonts.GetElementName(i); + + // Strip off the appendix "-p" / "-no" + V_StrLeft( alias, V_strlen(alias) - (data.proportional ? 2 : 3), fontName, sizeof(fontName) ); + + Msg( " %2d: HFont:0x%8.8lx, %s, %s, font:%s, tall:%d(%d) {%d}\n", + i, + data.font, + fontName, + alias, + name ? name : "??", + surface()->GetFontTall( data.font ), + surface()->GetFontTallRequested( data.font ), + g_ScriptFonts[i].Count() ); + } +} + +bool LoadFont( const FontData_t &font DBG_PARAM(, const char *fontAlias) ) +{ + if ( font.yres_min ) + { + int nScreenWide, nScreenTall; + surface()->GetScreenSize( nScreenWide, nScreenTall ); + + if ( nScreenTall < font.yres_min ) + return false; + + if ( font.yres_max && nScreenTall > font.yres_max ) + return false; + } + + int tall = font.tall; + int blur = font.blur; + int scanlines = font.scanlines; + + if ( font.proportional && !font.yres_min ) + { + tall = scheme()->GetProportionalScaledValue( tall ); + blur = scheme()->GetProportionalScaledValue( blur ); + scanlines = scheme()->GetProportionalScaledValue( scanlines ); + } + + bool bSuccess = surface()->SetFontGlyphSet( + font.font, + font.name, + tall, + font.weight, + blur, + scanlines, + font.flags ); + + NOTE_UNUSED( bSuccess ); + if ( bSuccess ) + { + if ( font.yres_min ) + DebugMsg( "Load font [%li]%s [%d %d]\n", font.font, fontAlias, font.yres_min, font.yres_max ); + else + DebugMsg( "Load font [%li]%s\n", font.font, fontAlias ); + } + else + { + DebugWarning( "Failed to load font [%li]%s\n", font.font, fontAlias ); + } + + return true; +} + +void ReloadScriptFontGlyphs() +{ + // Invalidate cached values + if ( g_pScriptVM ) + g_pScriptVM->Run( "ISurface.__OnScreenSizeChanged()" ); + + FOR_EACH_DICT_FAST( g_ScriptFonts, i ) + { + const fontalias_t &alias = g_ScriptFonts[i]; + for ( int j = 0; j < alias.Count(); ++j ) + { + if ( LoadFont( alias.Element(j) DBG_PARAM(, g_ScriptFonts.GetElementName(i)) ) ) + break; + } + } +} + + +static inline void InitRootPanel( Panel *p, VGuiPanel_t parent, const char *name ) +{ + int w, h; + surface()->GetScreenSize( w, h ); + p->Init( 0, 0, w, h ); + p->SetName( name ); + p->SetVisible( true ); + p->SetPaintEnabled( false ); + p->SetPaintBackgroundEnabled( false ); + p->SetPaintBorderEnabled( false ); + p->SetPostChildPaintEnabled( false ); + p->SetParent( enginevgui->GetPanel( parent ) ); +} + +class CScriptRootPanel : public Panel +{ +public: + CScriptRootPanel() + { + InitRootPanel( this, PANEL_ROOT, "VScriptRoot" ); + } + + void OnTick() + { + if ( m_nLastFrame == gpGlobals->framecount ) + return; + + ReloadScriptFontGlyphs(); + ivgui()->RemoveTickSignal( GetVPanel() ); + } + + // Used as a callback to font invalidation. + // Ideally script fonts would be loaded along with others in engine. + // In that case CScriptRootPanel would be removed, and + // g_pScriptRootPanel would be CScriptRootDLLPanel inside #if SCRIPT_ENGINE_ROOT_PANELS + void OnScreenSizeChanged( int w, int t ) + { + // Reload fonts in the next vgui frame + ivgui()->AddTickSignal( GetVPanel() ); + m_nLastFrame = gpGlobals->framecount; + + // Invalidate cached values + if ( g_pScriptVM ) + g_pScriptVM->Run( "ISurface.__OnScreenSizeChanged()" ); + + Panel::OnScreenSizeChanged( w, t ); + } + +private: + int m_nLastFrame; +}; + +CScriptRootPanel *g_pScriptRootPanel = NULL; + +#if SCRIPT_ENGINE_ROOT_PANELS +class CScriptRootDLLPanel : public Panel +{ +public: + CScriptRootDLLPanel( VGuiPanel_t parent, const char *name ) + { + InitRootPanel( this, parent, name ); + } +}; + +CScriptRootDLLPanel *g_pScriptClientDLLPanel = NULL; +#if ALLOW_SCRIPT_GAMEUI_ROOT_PANEL +CScriptRootDLLPanel *g_pScriptGameUIDLLPanel = NULL; +#endif +#endif + +void VGUI_DestroyScriptRootPanels() +{ + if ( g_pScriptRootPanel ) + { + delete g_pScriptRootPanel; + g_pScriptRootPanel = NULL; + } +#if SCRIPT_ENGINE_ROOT_PANELS + if ( g_pScriptClientDLLPanel ) + { + delete g_pScriptClientDLLPanel; + g_pScriptClientDLLPanel = NULL; + } +#if ALLOW_SCRIPT_GAMEUI_ROOT_PANEL + if ( g_pScriptGameUIDLLPanel ) + { + delete g_pScriptGameUIDLLPanel; + g_pScriptGameUIDLLPanel = NULL; + } +#endif +#endif +} + +VPANEL VGUI_GetScriptRootPanel( VGuiPanel_t type ) +{ +#if !SCRIPT_ENGINE_ROOT_PANELS + if ( !g_pScriptRootPanel ) + g_pScriptRootPanel = new CScriptRootPanel(); + + return enginevgui->GetPanel( type ); +#else + switch ( type ) + { + case PANEL_ROOT: + { + if ( !g_pScriptRootPanel ) + g_pScriptRootPanel = new CScriptRootPanel(); + + return g_pScriptRootPanel->GetVPanel(); + } + case PANEL_CLIENTDLL: + { + if ( !g_pScriptClientDLLPanel ) + g_pScriptClientDLLPanel = new CScriptRootDLLPanel( PANEL_CLIENTDLL, "VScriptClient" ); + + return g_pScriptClientDLLPanel->GetVPanel(); + } +#if ALLOW_SCRIPT_GAMEUI_ROOT_PANEL + case PANEL_GAMEUIDLL: + { + if ( !g_pScriptGameUIDLLPanel ) + g_pScriptGameUIDLLPanel = new CScriptRootDLLPanel( PANEL_GAMEUIDLL, "VScriptGameUI" ); + + return g_pScriptGameUIDLLPanel->GetVPanel(); + } +#endif + } + return NULL; +#endif +} + + +// +// Escapes "vgui/" prepended to the file name in CSchemeManager::GetImage(). +// +IImage *vgui_GetImage( const char *imageName, bool hardwareFilter ) +{ + char fileName[MAX_PATH]; + V_snprintf( fileName, sizeof( fileName ), "../%s", imageName ); + + return scheme()->GetImage( fileName, hardwareFilter ); +} + + +//-------------------------------------------------------------- +// +//-------------------------------------------------------------- +class CScriptSurface +{ +public: + void PlaySound( const char* sound ); + void SetColor( int r, int g, int b, int a ); + void DrawFilledRect( int x0, int y0, int width, int height ); + void DrawFilledRectFade( int x0, int y0, int width, int height, int a0, int a1, bool bHorz ); + void DrawOutlinedRect( int x0, int y0, int width, int height, int thickness ); + void DrawLine( int x0, int y0, int x1, int y1 ); + void DrawOutlinedCircle( int x, int y, int radius, int segments ); + + void SetTextColor( int r, int g, int b, int a ); + void SetTextPos( int x, int y ); + void SetTextFont( int font ); + void DrawText( const char *text, int drawType/* = FONT_DRAW_DEFAULT*/ ); + void DrawUnicodeChar( int ch, int drawType/* = FONT_DRAW_DEFAULT*/ ); + + int GetFont( const char* name, bool proportional, const char* schema ); + int GetTextWidth( int font, const char* text ); + int GetFontTall( int font ); + int GetCharacterWidth( int font, int ch ); + + void CreateFont( const char *customName, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int yresMin, int yresMax, bool proportional ); + bool AddCustomFontFile( const char *fontFileName ); + + int GetTextureID( char const *filename ); + int ValidateTexture( const char *filename, bool hardwareFilter, bool forceReload, bool procedural ); + void SetTextureFile( int id, const char *filename, bool hardwareFilter ); + int GetTextureWide( int id ); + int GetTextureTall( int id ); + void SetTexture( int id ); + + void DrawTexturedRect( int x0, int y0, int width, int height ); + void DrawTexturedSubRect( int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1 ); + + // ------------------------------------------------------------ + // Utility functions + // ------------------------------------------------------------ + + void DrawTexturedBox( int texture, int x, int y, int wide, int tall, int r, int g, int b, int a ); + void DrawColoredText( int font, int x, int y, int r, int g, int b, int a, const char *text ); + void DrawColoredTextRect( int font, int x, int y, int w, int h, int r, int g, int b, int a, const char *text ); + void DrawTexturedRectRotated( int x, int y, int w, int t, float yaw ); + +} script_surface; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptSurface, "ISurface", SCRIPT_SINGLETON ) + DEFINE_SCRIPTFUNC( PlaySound, "" ) + + DEFINE_SCRIPTFUNC( SetColor, "" ) + DEFINE_SCRIPTFUNC( DrawFilledRect, "" ) + DEFINE_SCRIPTFUNC( DrawFilledRectFade, "" ) + DEFINE_SCRIPTFUNC( DrawOutlinedRect, "" ) + DEFINE_SCRIPTFUNC( DrawLine, "" ) + DEFINE_SCRIPTFUNC( DrawOutlinedCircle, "" ) + + DEFINE_SCRIPTFUNC( SetTextColor, "" ) + DEFINE_SCRIPTFUNC( SetTextPos, "" ) + DEFINE_SCRIPTFUNC( SetTextFont, "" ) + DEFINE_SCRIPTFUNC( DrawText, "" ) + DEFINE_SCRIPTFUNC( DrawUnicodeChar, "" ) + + DEFINE_SCRIPTFUNC( GetFont, "" ) + DEFINE_SCRIPTFUNC( GetTextWidth, "" ) + DEFINE_SCRIPTFUNC( GetFontTall, "" ) + DEFINE_SCRIPTFUNC( GetCharacterWidth, "" ) + + DEFINE_SCRIPTFUNC( CreateFont, SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC( AddCustomFontFile, "" ) + + DEFINE_SCRIPTFUNC( GetTextureID, "" ) + DEFINE_SCRIPTFUNC( ValidateTexture, "" ) + DEFINE_SCRIPTFUNC( SetTextureFile, "" ) + DEFINE_SCRIPTFUNC( GetTextureWide, "" ) + DEFINE_SCRIPTFUNC( GetTextureTall, "" ) + DEFINE_SCRIPTFUNC( SetTexture, "" ) + + DEFINE_SCRIPTFUNC( DrawTexturedRect, "" ) + DEFINE_SCRIPTFUNC( DrawTexturedSubRect, "" ) + + DEFINE_SCRIPTFUNC( DrawTexturedBox, "" ) + DEFINE_SCRIPTFUNC( DrawColoredText, "" ) + DEFINE_SCRIPTFUNC( DrawColoredTextRect, "" ) + DEFINE_SCRIPTFUNC( DrawTexturedRectRotated, "" ) +END_SCRIPTDESC() + + +void CScriptSurface::PlaySound( const char* sound ) +{ + surface()->PlaySound(sound); +} + +void CScriptSurface::SetColor( int r, int g, int b, int a ) +{ + surface()->DrawSetColor( r, g, b, a ); +} + +void CScriptSurface::DrawFilledRect( int x0, int y0, int width, int height ) +{ + surface()->DrawFilledRect( x0, y0, x0 + width, y0 + height ); +} + +void CScriptSurface::DrawFilledRectFade( int x0, int y0, int width, int height, int a0, int a1, bool bHorz ) +{ + surface()->DrawFilledRectFade( x0, y0, x0 + width, y0 + height, a0, a1, bHorz ); +} + +void CScriptSurface::DrawOutlinedRect( int x0, int y0, int width, int height, int thickness ) +{ + int x1 = x0 + width; + int y1 = y0 + height - thickness; + y0 += thickness; + + surface()->DrawFilledRect( x0, y0 - thickness, x1, y0 ); // top + surface()->DrawFilledRect( x1 - thickness, y0, x1, y1 ); // right + surface()->DrawFilledRect( x0, y1, x1, y1 + thickness ); // bottom + surface()->DrawFilledRect( x0, y0, x0 + thickness, y1 ); // left +} + +void CScriptSurface::DrawLine( int x0, int y0, int x1, int y1 ) +{ + surface()->DrawLine( x0, y0, x1, y1 ); +} +#if 0 +void CScriptSurface::DrawPolyLine( HSCRIPT ax, HSCRIPT ay, int count ) +{ + if (count < 1) + return; + + if (count > 4096) + count = 4096; + + int *px = (int*)stackalloc( count * sizeof(int) ); + int *py = (int*)stackalloc( count * sizeof(int) ); + ScriptVariant_t vx, vy; + + int i = count; + while ( i-- ) + { + g_pScriptVM->GetValue( ax, i, &vx ); + g_pScriptVM->GetValue( ay, i, &vy ); + + px[i] = vx.m_int; + py[i] = vy.m_int; + } + + surface()->DrawPolyLine( px, py, count ); +} +#endif +void CScriptSurface::DrawOutlinedCircle( int x, int y, int radius, int segments ) +{ + surface()->DrawOutlinedCircle( x, y, radius, segments ); +} + +void CScriptSurface::SetTextColor( int r, int g, int b, int a ) +{ + surface()->DrawSetTextColor( r, g, b, a ); +} + +void CScriptSurface::SetTextPos( int x, int y ) +{ + surface()->DrawSetTextPos( x, y ); +} + +void CScriptSurface::SetTextFont( int font ) +{ + surface()->DrawSetTextFont( IntToFontHandle(font) ); +} + +void CScriptSurface::DrawText( const char *text, int drawType ) +{ + wchar_t wcs[512]; + g_pVGuiLocalize->ConvertANSIToUnicode( text, wcs, sizeof(wcs) ); + surface()->DrawPrintText( wcs, wcslen(wcs), (FontDrawType_t)drawType ); +} + +void CScriptSurface::DrawUnicodeChar( int ch, int drawType ) +{ + surface()->DrawUnicodeChar( (wchar_t)ch, (FontDrawType_t)drawType ); +} + +int CScriptSurface::GetFont( const char* name, bool proportional, const char* schema ) +{ + HFont font = INVALID_FONT; + + if ( !schema || !schema[0] ) + { + int idx = g_ScriptFonts.Find( GetFixedFontName( name, proportional ) ); + if ( idx != g_ScriptFonts.InvalidIndex() ) + { + font = g_ScriptFonts[idx].Head().font; + } + } + else + { + HScheme sch = scheme()->GetScheme( schema ); + font = scheme()->GetIScheme(sch)->GetFont( name, proportional ); + + // Update known count + if ( font > (unsigned int)g_nFontCount ) + g_nFontCount = font; + } + + return HandleToInt( font ); +} + +int CScriptSurface::GetTextWidth( int font, const char* text ) +{ + int w, t; + wchar_t wcs[512]; + g_pVGuiLocalize->ConvertANSIToUnicode( text, wcs, sizeof(wcs) ); + surface()->GetTextSize( IntToFontHandle(font), wcs, w, t ); + return w; +} + +int CScriptSurface::GetFontTall( int font ) +{ + return surface()->GetFontTall( IntToFontHandle(font) ); +} + +int CScriptSurface::GetCharacterWidth( int font, int ch ) +{ + return surface()->GetCharacterWidth( IntToFontHandle(font), ch ); +} + +void CScriptSurface::CreateFont( const char *customName, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int yresMin, int yresMax, bool proportional ) +{ + if ( flags & ISurface::FONTFLAG_BITMAP ) + { + AssertMsg( 0, "Bitmap fonts are not supported!" ); + return; + } + + if ( proportional && yresMin ) + { + AssertMsg( 0, "Resolution cannot be defined on a proportional font!" ); + return; + } + + if ( (yresMin < 0 || yresMax < 0) || (!!yresMin != !!yresMax) ) + { + AssertMsg( 0, "Invalid resolution!" ); + return; + } + + const char *fontAlias = GetFixedFontName( customName, proportional ); + + int idx = g_ScriptFonts.Find( fontAlias ); + if ( idx != g_ScriptFonts.InvalidIndex() ) + { + fontalias_t &alias = g_ScriptFonts[idx]; + // TODO: One proportional font to fall back to amongst resolution filtered fonts. + +#ifdef _DEBUG + if ( !yresMin && !yresMax ) + { + // There must be only one font registered. + Assert( alias.Count() == 1 ); + + HFont font = alias.Head().font; + int oldTall = surface()->GetFontTallRequested( font ); + int newTall = proportional ? scheme()->GetProportionalScaledValue( tall ) : tall; + const char *oldName = surface()->GetFontName( font ); + + // Font changes will not be applied. + Assert( oldTall == newTall ); + if ( oldName ) // can be null + Assert( !V_stricmp( oldName, windowsFontName ) ); + } +#endif + + // if input resolutions match any of the existing fonts, + // then this must be a duplicate call. + for ( int i = 0; i < alias.Count(); ++i ) + { + FontData_t &data = alias.Element(i); + + if ( yresMin == data.yres_min && yresMax == data.yres_max ) + return; + } + + DebugMsg( "Create font add '%s' [%d %d]\n", fontAlias, yresMin, yresMax ); + + FontData_t &newFont = alias.Element( alias.AddToTail() ); + newFont.font = alias.Head().font; + newFont.name = strdup( windowsFontName ); + newFont.tall = tall; + newFont.weight = weight; + newFont.blur = blur; + newFont.scanlines = scanlines; + newFont.flags = flags; + newFont.yres_min = yresMin; + newFont.yres_max = yresMax; + newFont.proportional = proportional; + + LoadFont( newFont DBG_PARAM(, fontAlias) ); + } + else + { + HFont font = surface()->CreateFont(); + + // Sanity check + Assert( font > (unsigned int)g_nFontCount && font < INT_MAX ); + + // Update known count + if ( font > (unsigned int)g_nFontCount ) + g_nFontCount = font; + + if ( yresMax && yresMin > yresMax ) + { + int t = yresMin; + yresMin = yresMax; + yresMax = t; + } + + if ( yresMin ) + DebugMsg( "Create font new '%s' [%d %d]\n", fontAlias, yresMin, yresMax ); + else + DebugMsg( "Create font new '%s'\n", fontAlias ); + + fontalias_t &alias = g_ScriptFonts.Element( g_ScriptFonts.Insert( fontAlias ) ); + FontData_t &newFont = alias.Element( alias.AddToTail() ); + newFont.font = font; + newFont.name = strdup( windowsFontName ); + newFont.tall = tall; + newFont.weight = weight; + newFont.blur = blur; + newFont.scanlines = scanlines; + newFont.flags = flags; + newFont.yres_min = yresMin; + newFont.yres_max = yresMax; + newFont.proportional = proportional; + + LoadFont( newFont DBG_PARAM(, fontAlias) ); + } +} + +bool CScriptSurface::AddCustomFontFile( const char *fontFileName ) +{ + return surface()->AddCustomFontFile( NULL, fontFileName ); +} + +int CScriptSurface::GetTextureID( char const *filename ) +{ + return surface()->DrawGetTextureId( filename ); +} + +// Create texture if it does not already exist +int CScriptSurface::ValidateTexture( const char *filename, bool hardwareFilter, bool forceReload, bool procedural ) +{ + int id = surface()->DrawGetTextureId( filename ); + if ( id <= 0 ) + { + id = surface()->CreateNewTextureID( procedural ); + g_ScriptTextureIDs.AddToTail( id ); + + surface()->DrawSetTextureFile( id, filename, hardwareFilter, forceReload ); + +#ifdef _DEBUG + char tex[MAX_PATH]; + surface()->DrawGetTextureFile( id, tex, sizeof(tex)-1 ); + if ( !V_stricmp( filename, tex ) ) + { + DebugMsg( "Create texture [%i]%s\n", id, filename ); + } + else + { + DebugWarning( "Create texture [%i]%s(%s)\n", id, tex, filename ); + } +#endif + } + else if ( forceReload && g_ScriptTextureIDs.HasElement( id ) ) + { + surface()->DrawSetTextureFile( id, filename, hardwareFilter, forceReload ); + } + else + { + surface()->DrawSetTexture( id ); + } + + return id; +} + +// Replace existing texture +void CScriptSurface::SetTextureFile( int id, const char *filename, bool hardwareFilter ) +{ + if ( g_ScriptTextureIDs.HasElement(id) ) + { + Assert( surface()->IsTextureIDValid(id) ); + surface()->DrawSetTextureFile( id, filename, hardwareFilter, true ); + +#ifdef _DEBUG + char tex[MAX_PATH]; + surface()->DrawGetTextureFile( id, tex, sizeof(tex)-1 ); + if ( !V_stricmp( filename, tex ) ) + { + DebugMsg( "Set texture [%i]%s\n", id, filename ); + } + else + { + DebugWarning( "Set texture [%i]%s(%s)\n", id, tex, filename ); + } +#endif + } + +#ifdef _DEBUG + if ( !g_ScriptTextureIDs.HasElement(id) && surface()->IsTextureIDValid(id) ) + { + DebugWarning( "Tried to set non-script created texture! [%i]%s\n", id, filename ); + } + + if ( !surface()->IsTextureIDValid(id) ) + { + DebugWarning( "Tried to set invalid texture id! [%i]%s\n", id, filename ); + } +#endif +} +#if 0 +void CScriptSurface::SetTextureMaterial( int id, HSCRIPT hMaterial ) +{ + IMaterial *pMaterial = (IMaterial*)HScriptToClass< IScriptMaterial >( hMaterial ); + if ( !IsValid( pMaterial ) ) + return; + + if ( g_ScriptTextureIDs.HasElement(id) ) + { + Assert( surface()->IsTextureIDValid(id) ); + MatSystemSurface()->DrawSetTextureMaterial( id, pMaterial ); + + DebugMsg( "Set texture [%i]%s\n", id, pMaterial->GetName() ); + } + +#ifdef _DEBUG + if ( !g_ScriptTextureIDs.HasElement(id) && surface()->IsTextureIDValid(id) ) + { + DebugWarning( "Tried to set non-script created texture! [%i]\n", id ); + } + + if ( !surface()->IsTextureIDValid(id) ) + { + DebugWarning( "Tried to set invalid texture id! [%i]\n", id ); + } +#endif +} +#endif +int CScriptSurface::GetTextureWide( int id ) +{ + int w, t; + surface()->DrawGetTextureSize( id, w, t ); + return w; +} + +int CScriptSurface::GetTextureTall( int id ) +{ + int w, t; + surface()->DrawGetTextureSize( id, w, t ); + return t; +} + +void CScriptSurface::SetTexture( int id ) +{ + surface()->DrawSetTexture( id ); +} + +void CScriptSurface::DrawTexturedRect( int x0, int y0, int width, int height ) +{ + surface()->DrawTexturedRect( x0, y0, x0 + width, y0 + height ); +} + +void CScriptSurface::DrawTexturedSubRect( int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1 ) +{ + surface()->DrawTexturedSubRect( x0, y0, x1, y1, texs0, text0, texs1, text1 ); +} + +void CScriptSurface::DrawTexturedRectRotated( int x, int y, int w, int t, float yaw ) +{ + Vertex_t verts[4]; + Vector2D axis[2]; + + float sy, cy; + SinCos( DEG2RAD( -yaw ), &sy, &cy ); + + axis[0].x = cy; + axis[0].y = sy; + axis[1].x = -axis[0].y; + axis[1].y = axis[0].x; + + verts[0].m_TexCoord.Init( 0, 0 ); + Vector2DMA( Vector2D( x + w * 0.5f, y + t * 0.5f ), w * -0.5f, axis[0], verts[0].m_Position ); + Vector2DMA( verts[0].m_Position, t * -0.5f, axis[1], verts[0].m_Position ); + + verts[1].m_TexCoord.Init( 1, 0 ); + Vector2DMA( verts[0].m_Position, w, axis[0], verts[1].m_Position ); + + verts[2].m_TexCoord.Init( 1, 1 ); + Vector2DMA( verts[1].m_Position, t, axis[1], verts[2].m_Position ); + + verts[3].m_TexCoord.Init( 0, 1 ); + Vector2DMA( verts[0].m_Position, t, axis[1], verts[3].m_Position ); + + surface()->DrawTexturedPolygon( 4, verts ); +} + +void CScriptSurface::DrawTexturedBox( int texture, int x, int y, int wide, int tall, int r, int g, int b, int a ) +{ + surface()->DrawSetColor( r, g, b, a ); + surface()->DrawSetTexture( texture ); + surface()->DrawTexturedRect( x, y, x + wide, y + tall ); +} + +void CScriptSurface::DrawColoredText( int font, int x, int y, int r, int g, int b, int a, const char *text ) +{ + wchar_t wcs[512]; + g_pVGuiLocalize->ConvertANSIToUnicode( text, wcs, sizeof(wcs) ); + + surface()->DrawSetTextFont( IntToFontHandle(font) ); + surface()->DrawSetTextColor( r, g, b, a ); + surface()->DrawSetTextPos( x, y ); + surface()->DrawPrintText( wcs, wcslen(wcs) ); +} + +void CScriptSurface::DrawColoredTextRect( int font, int x, int y, int w, int h, int r, int g, int b, int a, const char *text ) +{ + MatSystemSurface()->DrawColoredTextRect( IntToFontHandle(font), x, y, w, h, r, g, b, a, text ); +} + + +//============================================================== +//============================================================== + +#define __base() this->_base + +#define BEGIN_SCRIPTDESC_VGUI( panelClass )\ + BEGIN_SCRIPTDESC_NAMED( CScript_##panelClass##_Helper, IScriptVGUIObject, #panelClass, "" )\ + DEFINE_VGUI_SCRIPTFUNC_##panelClass() + +// +// Script helpers are wrappers that only redirect to VGUI panels (such as CScript_Panel : Panel), +// these macros help to simplify definitions. +// + +// +// BEGIN_VGUI_HELPER() assumes the VGUI panel class has the prefix 'CScript_' +// Use BEGIN_VGUI_HELPER_EX() to manually define VGUI panel class name. +// +#define BEGIN_VGUI_HELPER( panelClass )\ + BEGIN_VGUI_HELPER_EX( panelClass, CScript_##panelClass ) + +#define BEGIN_VGUI_HELPER_DEFAULT_TEXT( panelClass )\ + BEGIN_VGUI_HELPER_DEFAULT_TEXT_EX( panelClass, CScript_##panelClass ) + +#define BEGIN_VGUI_HELPER_EX( panelClass, baseClass )\ + class CScript_##panelClass##_Helper : public IScript_##panelClass< baseClass >\ + {\ + void Create( const char *panelName ) override\ + {\ + Assert( !_base && !_vpanel );\ + _base = new baseClass( NULL, panelName );\ + }\ +\ + public: + +#define BEGIN_VGUI_HELPER_DEFAULT_TEXT_EX( panelClass, baseClass )\ + class CScript_##panelClass##_Helper : public IScript_##panelClass< baseClass >\ + {\ + void Create( const char *panelName ) override\ + {\ + Assert( !_base && !_vpanel );\ + _base = new baseClass( NULL, panelName, (const char*)NULL );\ + }\ +\ + public: +#define END_VGUI_HELPER()\ + }; + + +#define CLASS_HELPER_INTERFACE_ROOT( panelClass )\ + template \ + class IScript_##panelClass : public CScriptVGUIObject + +#define CLASS_HELPER_INTERFACE( panelClass, baseClass )\ + template \ + class IScript_##panelClass : public IScript_##baseClass + + +#ifdef _DEBUG +#define DEBUG_DESTRUCTOR( panelClass, baseClass )\ + panelClass()\ + {\ + DebugDestructor( baseClass )\ + } + +#define DebugDestructor( panelClass )\ + {\ + DebugDevMsg( " ~" #panelClass "() '%s'\n", GetName() );\ + } +#else +#define DEBUG_DESTRUCTOR( panelClass, baseClass ) +#define DebugDestructor( panelClass ) +#endif + +#define DECLARE_SCRIPTVGUI_CLASS( baseClass )\ + DECLARE_SCRIPTVGUI_CLASS_EX( CScript_##baseClass, baseClass )\ + DEBUG_DESTRUCTOR( ~CScript_##baseClass, baseClass ) + +#define DECLARE_SCRIPTVGUI_CLASS_EX( panelClass, baseClass )\ + typedef baseClass BaseClass;\ + typedef panelClass ThisClass;\ +public:\ + void OnDelete()\ + {\ + DebugMsg( #baseClass "::OnDelete() '%s'\n", GetName() );\ + int i;\ + IScriptVGUIObject *obj = FindInScriptPanels( GetVPanel(), i );\ + if ( obj )\ + {\ + obj->Destroy( i );\ + }\ + BaseClass::OnDelete();\ + } + +// +// Definitions for 'empty' vgui objects that do not have any script specific implementation - overrides or callbacks. +// These are required to shutdown script objects on panel death +// (on save restore where panel destructor is called after the VM is restarted while HSCRIPT members are invalid but not nullified, +// and on C++ deletion where IScriptVGUIObject::Destroy() is not automatically called). +// +#define DEFINE_VGUI_CLASS_EMPTY( panelClass )\ + class CScript_##panelClass : public panelClass\ + {\ + DECLARE_SCRIPTVGUI_CLASS( panelClass )\ + void Shutdown() {}\ +\ + public:\ + CScript_##panelClass( Panel *parent, const char *name )\ + : BaseClass( parent, name )\ + {}\ + };\ +\ + BEGIN_VGUI_HELPER( panelClass )\ + END_VGUI_HELPER()\ +\ + BEGIN_SCRIPTDESC_VGUI( panelClass )\ + END_SCRIPTDESC() + +#define DEFINE_VGUI_CLASS_EMPTY_DEFAULT_TEXT( panelClass )\ + class CScript_##panelClass : public panelClass\ + {\ + DECLARE_SCRIPTVGUI_CLASS( panelClass )\ + void Shutdown() {}\ +\ + public:\ + CScript_##panelClass( Panel *parent, const char *name, const char *text )\ + : BaseClass( parent, name, text )\ + {}\ + };\ +\ + BEGIN_VGUI_HELPER_DEFAULT_TEXT( panelClass )\ + END_VGUI_HELPER()\ +\ + BEGIN_SCRIPTDESC_VGUI( panelClass )\ + END_SCRIPTDESC() + +class IScriptVGUIObject +{ +public: + virtual ~IScriptVGUIObject() {} + +#ifdef _DEBUG + virtual const char *GetName() = 0; +#endif + //----------------------------------------------------- + // Free the VGUI panel and script instance. + //----------------------------------------------------- + virtual void Destroy( int ) = 0; + + //----------------------------------------------------- + // Create new panel + //----------------------------------------------------- + virtual void Create( const char *panelName ) = 0; + +public: + VPANEL GetVPanel() { return _vpanel; } + HSCRIPT GetScriptInstance() { return m_hScriptInstance; } + +protected: + VPANEL _vpanel; + HSCRIPT m_hScriptInstance; + + // Called on deletion + static void ResolveChildren_r( VPANEL panel DBG_PARAM(, int level) ); + +public: +#if SCRIPT_VGUI_SAVERESTORE + IScriptVGUIObject() {} + void SetScriptInstance( HSCRIPT h ) { m_hScriptInstance = h; } + char m_pszScriptId[16]; +#endif + +#ifdef _DEBUG + #if SCRIPT_VGUI_SAVERESTORE + const char *GetDebugName() { return m_pszScriptId; } + #else + const char *GetDebugName() { return ""; } + #endif +#endif +}; + +BEGIN_SCRIPTDESC_ROOT( IScriptVGUIObject, SCRIPT_HIDE ) +END_SCRIPTDESC() + + +#if SCRIPT_VGUI_SAVERESTORE +class CScriptVGUIScriptInstanceHelper : public IScriptInstanceHelper +{ + void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ) + { + DebugMsg( "BindOnRead (0x%p) (%s) (count %d)\n", (uint)hInstance, pszId, g_ScriptPanels.Count() ); + + FOR_EACH_LL( g_ScriptPanels, i ) + { + IScriptVGUIObject *pPanel = g_ScriptPanels[i]; + // DebugMsg( " cmp (%s)\n", pPanel->m_pszScriptId ); + if ( !V_stricmp( pPanel->m_pszScriptId, pszId ) ) + { + pPanel->SetScriptInstance( hInstance ); + DebugMsg( " ret (%s)\n", pPanel->m_pszScriptId ); + return pPanel; + } + } + DebugMsg( " ret (null)\n" ); + return NULL; + } +}; + +static CScriptVGUIScriptInstanceHelper g_ScriptVGUIScriptInstanceHelper; + +#define DEFINE_VGUI_SCRIPT_INSTANCE_HELPER() DEFINE_SCRIPT_INSTANCE_HELPER( &g_ScriptVGUIScriptInstanceHelper ) +#else +#define DEFINE_VGUI_SCRIPT_INSTANCE_HELPER() +#endif + + +IScriptVGUIObject *ToScriptVGUIObj( HSCRIPT inst ) +{ + return (IScriptVGUIObject *)g_pScriptVM->GetInstanceValue( inst, ::GetScriptDesc( (IScriptVGUIObject *)0 ) ); +} + +template < typename T > inline T* AllocScriptPanel() +{ + return new T; +} + +inline IScriptVGUIObject *FindInScriptPanels( VPANEL panel, int &I ) +{ + for ( int i = g_ScriptPanels.Head(); i != g_ScriptPanels.InvalidIndex(); i = g_ScriptPanels.Next(i) ) + { + IScriptVGUIObject *obj = g_ScriptPanels[i]; + if ( obj->GetVPanel() == panel ) + { + I = i; + return obj; + } + } + return NULL; +} + +void IScriptVGUIObject::ResolveChildren_r( VPANEL panel DBG_PARAM(, int level = 0) ) +{ +#ifdef _DEBUG + char indent[32]; + + int l = level, c = 0; + if ( l > 15 ) + l = 15; + + while ( l-- ) + { + indent[c++] = ' '; + indent[c++] = ' '; + } + indent[c] = 0; + + if ( level > 15 ) + { + indent[c-1] = '.'; + indent[c-2] = '.'; + } +#endif + + CUtlVector< VPANEL > &children = ipanel()->GetChildren( panel ); + FOR_EACH_VEC_BACK( children, i ) + { + VPANEL child = children[i]; + int j; + IScriptVGUIObject *obj = FindInScriptPanels( child, j ); + if ( obj ) + { + if ( ipanel()->IsAutoDeleteSet(child) ) + { + DebugMsg( " %sResolveChildren: '%s' (autodelete)\n", indent, obj->GetName() ); + + if ( g_pScriptVM ) + g_pScriptVM->RemoveInstance( obj->m_hScriptInstance ); + g_ScriptPanels.Remove( j ); + delete obj; + + ResolveChildren_r( child DBG_PARAM(, level+1) ); + } + else + { + DebugMsg( " %sResolveChildren: '%s'\n", indent, obj->GetName() ); + + // Panel::SetAutoDelete should not be added until + // what to do on their parent death is finalised. + // + // This assert will be hit if a deleted panel has + // C++ created and autodelete disabled children who are + // also registered to script. + Assert(0); + } + } + } +} + +template +class CScriptVGUIObject : public IScriptVGUIObject +{ +public: + T *_base; + + CScriptVGUIObject() : _base(0) + { + _vpanel = 0; + m_hScriptInstance = 0; + } + + void Destroy( int i = -1 ) + { + if ( i != -1 ) + { + Assert( g_ScriptPanels.IsValidIndex(i) ); + Assert( g_ScriptPanels[i] == this ); + + g_ScriptPanels.Remove( i ); + } + else + { + Assert( g_ScriptPanels.Find( this ) != g_ScriptPanels.InvalidIndex() ); + + g_ScriptPanels.FindAndRemove( this ); + } + + if ( GetVPanel() ) + { + DebugMsg( " Destroy panel '%s' %s\n", _base->GetName(), GetDebugName() ); + _base->Shutdown(); + ResolveChildren_r( _vpanel ); + _base->MarkForDeletion(); + } + + if ( m_hScriptInstance ) + { + if ( g_pScriptVM ) + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + } + + delete this; + } + + template + void CreateFromScript( HSCRIPT parent, const char *panelName, int root ) + { + Assert( !_vpanel && !m_hScriptInstance && !g_ScriptPanels.IsValidIndex( g_ScriptPanels.Find( this ) ) ); + + Create( panelName && *panelName ? panelName : NULL ); + _vpanel = _base->GetVPanel(); + m_hScriptInstance = g_pScriptVM->RegisterInstance< CHelper >( static_cast< CHelper* >( this ) ); + +#if SCRIPT_VGUI_SAVERESTORE + g_pScriptVM->GenerateUniqueKey( "", m_pszScriptId, sizeof(m_pszScriptId) ); + g_pScriptVM->SetInstanceUniqeId( m_hScriptInstance, m_pszScriptId ); +#endif + + if ( parent ) + { + IScriptVGUIObject *obj = ToScriptVGUIObj( parent ); + if ( obj ) + { + // Insert this after the parent to make sure children come after their parents, + // and their removal is done inside ResolveChildren_r(), not by individual Destroy() calls from LevelShutdown. + unsigned short parentIdx = g_ScriptPanels.Find( obj ); + + // My parent can't not be in the list. + Assert( parentIdx != g_ScriptPanels.InvalidIndex() && g_ScriptPanels.IsInList( parentIdx ) ); + + g_ScriptPanels.InsertAfter( parentIdx, this ); + + _base->SetParent( obj->GetVPanel() ); + return; + } + + AssertMsg( 0, "invalid parent" ); + } + + g_ScriptPanels.AddToTail( this ); + + // Script specified root panel - a cheap alternative to registering uneditable panel instances. + // Match the values to vscript_vgui.nut. + // + // This parameter is hidden in script, and is defined by the return value of dummy functions. + VPANEL vparent = 0; + switch ( root ) + { + case 0: + vparent = VGUI_GetScriptRootPanel( PANEL_ROOT ); + break; +#if ALLOW_SCRIPT_GAMEUI_ROOT_PANEL + case 1: + vparent = VGUI_GetScriptRootPanel( PANEL_GAMEUIDLL ); + break; +#endif + case 2: + vparent = VGUI_GetScriptRootPanel( PANEL_CLIENTDLL ); + break; +#if ALLOW_SCRIPT_HUD_VIEWPORT_ROOT_PANEL + // Hud viewport + case 10: + Assert( g_pClientMode && g_pClientMode->GetViewport() ); + vparent = g_pClientMode->GetViewport()->GetVPanel(); + break; +#endif + default: UNREACHABLE(); // Invalid parent panel + } + + _base->SetParent( vparent ); + } +}; + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE_ROOT( Panel ) +{ +public: + void Destroy() + { + CScriptVGUIObject::Destroy(); + } + + void MakeReadyForUse() + { + __base()->MakeReadyForUse(); + } + + const char *GetName() + { + return __base()->GetName(); + } + + void AddTickSignal( int i ) + { + ivgui()->AddTickSignal( this->GetVPanel(), i ); + } +#if SCRIPT_VGUI_SIGNAL_INTERFACE + void AddActionSignalTarget( HSCRIPT messageTarget ) + { + IScriptVGUIObject *obj = ToScriptVGUIObj( messageTarget ); + if ( obj ) + { + __base()->AddActionSignalTarget( obj->GetVPanel() ); + } + } +#endif + //----------------------------------------------------- + // Get script created parent + //----------------------------------------------------- + HSCRIPT GetParent() + { + VPANEL parent = ipanel()->GetParent( this->GetVPanel() ); + if ( !parent ) + return NULL; + + int i; + IScriptVGUIObject* obj = FindInScriptPanels( parent, i ); + if ( obj ) + { + // My parent can't be invalid. + Assert( ToScriptVGUIObj( obj->GetScriptInstance() ) ); + + return obj->GetScriptInstance(); + } + +#ifdef _DEBUG + // Is my parent one of the root panels? + bool bRootParent = false; +#if SCRIPT_ENGINE_ROOT_PANELS + if ( ( parent == g_pScriptRootPanel->GetVPanel() ) + #if ALLOW_SCRIPT_GAMEUI_ROOT_PANEL + || ( g_pScriptGameUIDLLPanel && parent == g_pScriptGameUIDLLPanel->GetVPanel() ) + #endif + || ( g_pScriptClientDLLPanel && parent == g_pScriptClientDLLPanel->GetVPanel() ) + ) + { + bRootParent = true; + } + else +#endif + for ( int i = PANEL_ROOT; i <= PANEL_CLIENTDLL_TOOLS; ++i ) + { + if ( parent == enginevgui->GetPanel( (VGuiPanel_t)i ) ) + { + bRootParent = true; + break; + } + } +#if ALLOW_SCRIPT_HUD_VIEWPORT_ROOT_PANEL + if ( g_pClientMode && g_pClientMode->GetViewport() && ( parent == g_pClientMode->GetViewport()->GetVPanel() ) ) + bRootParent = true; +#endif + // My parent wasn't registered. + AssertMsg1( bRootParent, "'%s'", ipanel()->GetName(parent) ); +#endif + + return NULL; + } + + //----------------------------------------------------- + // Set script created parent + //----------------------------------------------------- + void SetParent( HSCRIPT parent ) + { + if ( !parent ) + { + __base()->SetParent( (VPANEL)NULL ); + return; + } + + IScriptVGUIObject *obj = ToScriptVGUIObj( parent ); + if ( obj ) + { + __base()->SetParent( obj->GetVPanel() ); + return; + } + + AssertMsg( 0, "invalid parent" ); + } + + void GetChildren( HSCRIPT arr ) + { + CUtlVector< VPANEL > &children = ipanel()->GetChildren( this->GetVPanel() ); + FOR_EACH_VEC( children, i ) + { + VPANEL child = children[i]; + int j; + IScriptVGUIObject* obj = FindInScriptPanels( child, j ); + if ( obj ) + { + g_pScriptVM->ArrayAppend( arr, obj->GetScriptInstance() ); + } + // Beware of dangling pointers if C++ created children are to be registered + } + } + + int GetXPos() + { + int x, y; + ipanel()->GetPos( this->GetVPanel(), x, y ); + return x; + } + + int GetYPos() + { + int x, y; + ipanel()->GetPos( this->GetVPanel(), x, y ); + return y; + } + + void SetPos( int x, int y ) + { + ipanel()->SetPos( this->GetVPanel(), x, y ); + } + + void SetZPos( int i ) + { + ipanel()->SetZPos( this->GetVPanel(), i ); + } + + int GetZPos() + { + return ipanel()->GetZPos( this->GetVPanel() ); + } + + void SetSize( int w, int t ) + { + ipanel()->SetSize( this->GetVPanel(), w, t ); + } + + void SetWide( int w ) + { + ipanel()->SetSize( this->GetVPanel(), w, GetTall() ); + } + + int GetWide() + { + int w, t; + ipanel()->GetSize( this->GetVPanel(), w, t ); + return w; + } + + void SetTall( int t ) + { + ipanel()->SetSize( this->GetVPanel(), GetWide(), t ); + } + + int GetTall() + { + int w, t; + ipanel()->GetSize( this->GetVPanel(), w, t ); + return t; + } + + int GetAlpha() + { + return __base()->GetAlpha(); + } + + void SetAlpha( int i ) + { + __base()->SetAlpha( i ); + } + + void SetVisible( bool i ) + { + ipanel()->SetVisible( this->GetVPanel(), i ); + } + + bool IsVisible() + { + return ipanel()->IsVisible( this->GetVPanel() ); + } +#if BUILD_GROUPS_ENABLED + void SetProportional( bool i ) + { + __base()->SetProportional(i); + } +#endif +#if 0 + void LocalToScreen( HSCRIPT out ) + { + int px, py; + ipanel()->GetAbsPos( this->GetVPanel(), px, py ); + + ScriptVariant_t x, y; + g_pScriptVM->GetValue( out, (ScriptVariant_t)0, &x ); + g_pScriptVM->GetValue( out, 1, &y ); + + g_pScriptVM->SetValue( out, (ScriptVariant_t)0, x.m_int + px ); + g_pScriptVM->SetValue( out, 1, y.m_int + py ); + } + + void ScreenToLocal( HSCRIPT out ) + { + int px, py; + ipanel()->GetAbsPos( this->GetVPanel(), px, py ); + + ScriptVariant_t x, y; + g_pScriptVM->GetValue( out, (ScriptVariant_t)0, &x ); + g_pScriptVM->GetValue( out, 1, &y ); + + g_pScriptVM->SetValue( out, (ScriptVariant_t)0, x.m_int - px ); + g_pScriptVM->SetValue( out, 1, y.m_int - py ); + } +#endif + bool IsWithin( int x, int y ) + { + return __base()->IsWithin( x, y ); + } + + void SetEnabled( bool i ) + { + __base()->SetEnabled(i); + } + + bool IsEnabled() + { + return __base()->IsEnabled(); + } + + void SetPaintEnabled( bool i ) + { + __base()->SetPaintEnabled(i); + } + + void SetPaintBackgroundEnabled( bool i ) + { + __base()->SetPaintBackgroundEnabled(i); + } + + void SetPaintBorderEnabled( bool i ) + { + __base()->SetPaintBorderEnabled(i); + } + + void SetPostChildPaintEnabled( bool i ) + { + __base()->SetPostChildPaintEnabled(i); + } + + // 0 for normal(opaque), 1 for single texture from Texture1, and 2 for rounded box w/ four corner textures + void SetPaintBackgroundType( int i ) + { + __base()->SetPaintBackgroundType(i); + } + + void SetFgColor( int r, int g, int b, int a ) + { + __base()->SetFgColor( Color( r, g, b, a ) ); + } + + void SetBgColor( int r, int g, int b, int a ) + { + __base()->SetBgColor( Color( r, g, b, a ) ); + } +#if 0 + void SetScheme( const char *tag ) + { + return __base()->SetScheme( tag ); + } +#endif + void SetCursor( int cursor ) + { + AssertMsg( cursor >= 0 && cursor < dc_last, "invalid cursor" ); + + // do nothing + if ( cursor < 0 || cursor >= dc_last ) + return; + + return __base()->SetCursor( (HCursor)cursor ); + } + + bool IsCursorOver() + { + return __base()->IsCursorOver(); + } + + bool HasFocus() + { + return __base()->HasFocus(); + } + + void RequestFocus() + { + __base()->RequestFocus(); + } + + void MakePopup() + { + __base()->MakePopup(); + } + + void MoveToFront() + { + __base()->MoveToFront(); + } + + void SetMouseInputEnabled( bool i ) + { + __base()->SetMouseInputEnabled(i); + } + + void SetKeyBoardInputEnabled( bool i ) + { + __base()->SetKeyBoardInputEnabled(i); + } + + // ----------------------- + // Drawing utility + // ----------------------- + //void SetRoundedCorners( int cornerFlags ) + //{ + // __base()->SetRoundedCorners( cornerFlags & 0xff ); + //} + + void DrawBox( int x, int y, int wide, int tall, int r, int g, int b, int a, bool hollow ) + { + __base()->DrawBox( x, y, wide, tall, Color(r, g, b, a), 1.0f, hollow ); + } + + void DrawBoxFade( int x, int y, int wide, int tall, int r, int g, int b, int a, int alpha0, int alpha1, bool bHorizontal, bool hollow ) + { + __base()->DrawBoxFade( x, y, wide, tall, Color(r, g, b, a), 1.0f, alpha0, alpha1, bHorizontal, hollow ); + } +#if 0 + // ----------------------- + // drag drop + // ----------------------- + void SetDragEnabled( bool i ) + { + __base()->SetDragEnabled(i); + } + + bool IsDragEnabled() + { + return __base()->IsDragEnabled(); + } + + void SetDropEnabled( bool i ) + { + __base()->SetDropEnabled( i, 0.0f ); + } + + bool IsDropEnabled() + { + return __base()->IsDropEnabled(); + } + + void SetShowDragHelper( int i ) + { + __base()->SetShowDragHelper(i); + } + + int GetDragStartTolerance() + { + return __base()->GetDragStartTolerance(); + } + + void SetDragStartTolerance( int i ) + { + __base()->SetDragSTartTolerance(i); + } +#endif +#if 0 + void SetTooltip( const char *text ) + { + __base()->GetTooltip()->SetText( text ); + } + + void SetTooltipDelay( int delay ) + { + __base()->GetTooltip()->SetTooltipDelay( delay ); + } +#endif +}; + +#define DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_VGUI_SCRIPT_INSTANCE_HELPER()\ +\ + DEFINE_SCRIPTFUNC( Destroy, "" )\ + DEFINE_SCRIPTFUNC( MakeReadyForUse, "" )\ + DEFINE_SCRIPTFUNC( GetName, "" )\ + DEFINE_SCRIPTFUNC( AddTickSignal, "" )\ +\ + DEFINE_SCRIPTFUNC( GetParent, "" )\ + DEFINE_SCRIPTFUNC( SetParent, "" )\ + DEFINE_SCRIPTFUNC( GetChildren, "" )\ +\ + DEFINE_SCRIPTFUNC( GetXPos, "" )\ + DEFINE_SCRIPTFUNC( GetYPos, "" )\ + DEFINE_SCRIPTFUNC( SetPos, "" )\ +\ + DEFINE_SCRIPTFUNC( GetZPos, "" )\ + DEFINE_SCRIPTFUNC( SetZPos, "" )\ +\ + DEFINE_SCRIPTFUNC( SetSize, "" )\ + DEFINE_SCRIPTFUNC( GetWide, "" )\ + DEFINE_SCRIPTFUNC( SetWide, "" )\ +\ + DEFINE_SCRIPTFUNC( GetTall, "" )\ + DEFINE_SCRIPTFUNC( SetTall, "" )\ +\ + DEFINE_SCRIPTFUNC( GetAlpha, "" )\ + DEFINE_SCRIPTFUNC( SetAlpha, "" )\ +\ + DEFINE_SCRIPTFUNC( SetVisible, "" )\ + DEFINE_SCRIPTFUNC( IsVisible, "" )\ +\ + DEFINE_SCRIPTFUNC( IsWithin, "" )\ +\ + DEFINE_SCRIPTFUNC( SetEnabled, "" )\ + DEFINE_SCRIPTFUNC( IsEnabled, "" )\ +\ + DEFINE_SCRIPTFUNC( SetPaintEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetPaintBackgroundEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetPaintBorderEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetPostChildPaintEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetPaintBackgroundType, "" )\ +\ + DEFINE_SCRIPTFUNC( SetFgColor, "" )\ + DEFINE_SCRIPTFUNC( SetBgColor, "" )\ +\ + DEFINE_SCRIPTFUNC( SetCursor, "" )\ + DEFINE_SCRIPTFUNC( IsCursorOver, "" )\ + DEFINE_SCRIPTFUNC( HasFocus, "" )\ + DEFINE_SCRIPTFUNC( RequestFocus, "" )\ + DEFINE_SCRIPTFUNC( MakePopup, "" )\ + DEFINE_SCRIPTFUNC( MoveToFront, "" )\ + DEFINE_SCRIPTFUNC( SetMouseInputEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetKeyBoardInputEnabled, "" )\ +\ + DEFINE_SCRIPTFUNC( DrawBox, "" )\ + DEFINE_SCRIPTFUNC( DrawBoxFade, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +// These need more testing. +// TODO: IScript_Panel::FindChildByName() +// TODO: DECLARE_BUILD_FACTORY_SCRIPT() to create overridable script panels from controls file +// TODO: CScript_EditablePanel::ApplySchemeSettings() callback +// (IScheme parameter can be passed as null until schemes are also tested) +#if BUILD_GROUPS_ENABLED +CLASS_HELPER_INTERFACE( EditablePanel, Panel ) +{ +public: + // Call on creation or on ApplySchemeSettings() + void LoadControlSettings( const char *resName ) + { + __base()->LoadControlSettings( resName ); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_EditablePanel()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( LoadControlSettings, "" ) +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( Label, Panel ) +{ +public: + void SetText( const char *text ) + { + wchar_t wcs[512]; + g_pVGuiLocalize->ConvertANSIToUnicode( text, wcs, sizeof(wcs) ); + __base()->SetText( wcs ); + } + + void SetFont( int i ) + { + __base()->SetFont( IntToFontHandle(i) ); + } + + void SetAllCaps( bool i ) + { + __base()->SetAllCaps(i); + } + + void SetWrap( bool i ) + { + __base()->SetWrap(i); + } + + void SetCenterWrap( bool i ) + { + __base()->SetCenterWrap(i); + } + + void SetContentAlignment( int i ) + { + __base()->SetContentAlignment( (Label::Alignment)i ); + } + + void SetTextInset( int x, int y ) + { + __base()->SetTextInset( x, y ); + } + + void SizeToContents() + { + __base()->SizeToContents(); + } + + void SetAssociatedControl( HSCRIPT control ) + { + IScriptVGUIObject *obj = ToScriptVGUIObj( control ); + if ( obj ) + { + __base()->SetAssociatedControl( ipanel()->GetPanel( obj->GetVPanel(), GetControlsModuleName() ) ); + } + } + + void AddColorChange( int r, int g, int b, int a, int iTextStreamIndex ) + { + __base()->GetTextImage()->AddColorChange( Color( r, g, b, a ), iTextStreamIndex ); + } + + void ClearColorChangeStream() + { + __base()->GetTextImage()->ClearColorChangeStream(); + } +#if 0 + void SetTextImageIndex( int index ) + { + __base()->SetTextImageIndex( index ); + } + + void SetImageAtIndex( int index, const char *imageName, bool hardwareFilter, int offset ) + { + return __base()->SetImageAtIndex( index, vgui_GetImage( imageName, hardwareFilter ), offset ); + } + + int AddImage( const char *imageName, bool hardwareFilter, int offset ) + { + return __base()->AddImage( vgui_GetImage( imageName, hardwareFilter ), offset ); + } +#endif +}; + +#define DEFINE_VGUI_SCRIPTFUNC_Label()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetText, "" )\ + DEFINE_SCRIPTFUNC( SetFont, "" )\ + DEFINE_SCRIPTFUNC( SetAllCaps, "" )\ + DEFINE_SCRIPTFUNC( SetWrap, "" )\ + DEFINE_SCRIPTFUNC( SetCenterWrap, "" )\ + DEFINE_SCRIPTFUNC( SetContentAlignment, "" )\ + DEFINE_SCRIPTFUNC( SetTextInset, "" )\ + DEFINE_SCRIPTFUNC( SizeToContents, "" )\ + DEFINE_SCRIPTFUNC( SetAssociatedControl, "" )\ + DEFINE_SCRIPTFUNC( AddColorChange, "" )\ + DEFINE_SCRIPTFUNC( ClearColorChangeStream, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( Button, Label ) +{ +public: +#if SCRIPT_VGUI_SIGNAL_INTERFACE + // Sets the command message to send to the action signal target when the button is pressed + void SetCommand( const char *command ) + { + if ( !V_strnicmp( command, "url ", 4 ) ) + { + __base()->SetCommand( (KeyValues*)NULL ); + + g_pScriptVM->RaiseException("invalid button command"); + return; + } + + __base()->SetCommand( command ); + } +#endif + void SetButtonActivationType( int activationType ) + { + __base()->SetButtonActivationType( (Button::ActivationType_t)activationType ); + } + + bool IsArmed() + { + return __base()->IsArmed(); + } + + void SetArmed( bool state ) + { + __base()->SetArmed(state); + } + + bool IsSelected() + { + return __base()->IsSelected(); + } + + void SetSelected( bool state ) + { + __base()->SetSelected(state); + } + + bool IsDepressed() + { + return __base()->IsDepressed(); + } + + void ForceDepressed( bool state ) + { + __base()->ForceDepressed(state); + } + + void SetMouseClickEnabled( int code, bool state ) + { + __base()->SetMouseClickEnabled( (MouseCode)code, state ); + } + + bool IsMouseClickEnabled( int code ) + { + return __base()->IsMouseClickEnabled( (MouseCode)code ); + } + + void SetDefaultColor( int fr, int fg, int fb, int fa, int br, int bg, int bb, int ba ) + { + __base()->SetDefaultColor( Color(fr, fg, fb, fa), Color(br, bg, bb, ba) ); + } + + void SetArmedColor( int fr, int fg, int fb, int fa, int br, int bg, int bb, int ba ) + { + __base()->SetArmedColor( Color(fr, fg, fb, fa), Color(br, bg, bb, ba) ); + } + + void SetSelectedColor( int fr, int fg, int fb, int fa, int br, int bg, int bb, int ba ) + { + __base()->SetSelectedColor( Color(fr, fg, fb, fa), Color(br, bg, bb, ba) ); + } + + void SetDepressedColor( int fr, int fg, int fb, int fa, int br, int bg, int bb, int ba ) + { + __base()->SetDepressedColor( Color(fr, fg, fb, fa), Color(br, bg, bb, ba) ); + } + + void SetArmedSound( const char *sound ) + { + __base()->SetArmedSound( sound ); + } + + void SetDepressedSound( const char *sound ) + { + __base()->SetDepressedSound( sound ); + } + + void SetReleasedSound( const char *sound ) + { + __base()->SetReleasedSound( sound ); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_Button()\ + DEFINE_VGUI_SCRIPTFUNC_Label()\ + DEFINE_SCRIPTFUNC( SetButtonActivationType, "" )\ + DEFINE_SCRIPTFUNC( IsArmed, "" )\ + DEFINE_SCRIPTFUNC( SetArmed, "" )\ + DEFINE_SCRIPTFUNC( IsSelected, "" )\ + DEFINE_SCRIPTFUNC( SetSelected, "" )\ + DEFINE_SCRIPTFUNC( IsDepressed, "" )\ + DEFINE_SCRIPTFUNC( ForceDepressed, "" )\ + DEFINE_SCRIPTFUNC( SetMouseClickEnabled, "" )\ + DEFINE_SCRIPTFUNC( IsMouseClickEnabled, "" )\ + DEFINE_SCRIPTFUNC( SetDefaultColor, "" )\ + DEFINE_SCRIPTFUNC( SetArmedColor, "" )\ + DEFINE_SCRIPTFUNC( SetSelectedColor, "" )\ + DEFINE_SCRIPTFUNC( SetDepressedColor, "" )\ + DEFINE_SCRIPTFUNC( SetArmedSound, "" )\ + DEFINE_SCRIPTFUNC( SetDepressedSound, "" )\ + DEFINE_SCRIPTFUNC( SetReleasedSound, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( ImagePanel, Panel ) +{ +public: + void SetImage( const char *imageName, bool hardwareFilter ) + { + __base()->EvictImage(); + __base()->SetImage( vgui_GetImage( imageName, hardwareFilter ) ); + } + + void SetDrawColor( int r, int g, int b, int a ) + { + __base()->SetDrawColor( Color( r, g, b, a ) ); + } + + void SetTileImage( bool bTile ) + { + __base()->SetTileImage( bTile ); + } + + void SetShouldScaleImage( bool state ) + { + __base()->SetShouldScaleImage( state ); + } +#if 0 + void SetFrame( int nFrame ) + { + __base()->SetFrame( nFrame ); + } +#endif +}; + +#define DEFINE_VGUI_SCRIPTFUNC_ImagePanel()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetImage, "" )\ + DEFINE_SCRIPTFUNC( SetDrawColor, "" )\ + DEFINE_SCRIPTFUNC( SetTileImage, "" )\ + DEFINE_SCRIPTFUNC( SetShouldScaleImage, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( Frame, Panel ) +{ +public: + void SetMinimumSize( int wide, int tall ) + { + __base()->SetMinimumSize( wide, tall ); + } + + void SetTitle( const char* titel ) + { + __base()->SetTitle( titel, false ); + } + + void Close() + { + __base()->Close(); + } + + void SetDeleteSelfOnClose( bool state ) + { + __base()->SetDeleteSelfOnClose( state ); + } + + void SetMoveable( bool state ) + { + __base()->SetMoveable( state ); + } + + void SetSizeable( bool state ) + { + __base()->SetSizeable( state ); + } + + void SetCloseButtonVisible( bool state ) + { + __base()->SetCloseButtonVisible( state ); + } + + void SetTitleBarVisible( bool state ) + { + __base()->SetTitleBarVisible( state ); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_Frame()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetMinimumSize, "" )\ + DEFINE_SCRIPTFUNC( SetTitle, "" )\ + DEFINE_SCRIPTFUNC( Close, "" )\ + DEFINE_SCRIPTFUNC( SetDeleteSelfOnClose, "" )\ + DEFINE_SCRIPTFUNC( SetMoveable, "" )\ + DEFINE_SCRIPTFUNC( SetSizeable, "" )\ + DEFINE_SCRIPTFUNC( SetCloseButtonVisible, "" )\ + DEFINE_SCRIPTFUNC( SetTitleBarVisible, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( RichText, Panel ) +{ +public: + void SetText( const char* text ) + { + __base()->SetText( text ); + } + + void SetFont( int font ) + { + __base()->SetFont( IntToFontHandle(font) ); + } + + void InsertString( const char* text ) + { + __base()->InsertString( text ); + } + + void SetPanelInteractive( bool bInteractive ) + { + __base()->SetPanelInteractive( bInteractive ); + } + + void SetUnusedScrollbarInvisible( bool bInvis ) + { + __base()->SetUnusedScrollbarInvisible( bInvis ); + } + + void GotoTextStart() + { + __base()->GotoTextStart(); + } + + void GotoTextEnd() + { + __base()->GotoTextEnd(); + } + + void SetMaximumCharCount( int maxChars ) + { + __base()->SetMaximumCharCount( maxChars ); + } + + void InsertColorChange( int r, int g, int b, int a ) + { + __base()->InsertColorChange( Color( r, g, b, a ) ); + } + + int GetNumLines() + { + return __base()->GetNumLines(); + } + + void SetDrawTextOnly() + { + __base()->SetDrawTextOnly(); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_RichText()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetText, "" )\ + DEFINE_SCRIPTFUNC( SetFont, "" )\ + DEFINE_SCRIPTFUNC( InsertString, "" )\ + DEFINE_SCRIPTFUNC( SetPanelInteractive, "" )\ + DEFINE_SCRIPTFUNC( SetUnusedScrollbarInvisible, "" )\ + DEFINE_SCRIPTFUNC( GotoTextStart, "" )\ + DEFINE_SCRIPTFUNC( GotoTextEnd, "" )\ + DEFINE_SCRIPTFUNC( SetMaximumCharCount, "" )\ + DEFINE_SCRIPTFUNC( InsertColorChange, "" )\ + DEFINE_SCRIPTFUNC( GetNumLines, "" )\ + DEFINE_SCRIPTFUNC( SetDrawTextOnly, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +CLASS_HELPER_INTERFACE( TextEntry, Panel ) +{ +public: + void SetText( const char* text ) + { + wchar_t wcs[512]; + g_pVGuiLocalize->ConvertANSIToUnicode( text, wcs, sizeof(wcs) ); + __base()->SetText( wcs ); + } + + const char *GetText() + { + static char sz[512]; + __base()->GetText( sz, sizeof(sz) ); + return sz; + } + + void SetFont( int font ) + { + __base()->SetFont( IntToFontHandle(font) ); + } + + void SetEditable( bool state ) + { + __base()->SetEditable( state ); + } + + void GotoTextStart() + { + __base()->GotoTextStart(); + } + + void GotoTextEnd() + { + __base()->GotoTextEnd(); + } + + void InsertString( const char* text ) + { + __base()->InsertString( text ); + } + + void SelectNone() + { + __base()->SelectNone(); + } + + void SetMultiline( bool state ) + { + __base()->SetMultiline( state ); + } + + void SetVerticalScrollbar( bool state ) + { + __base()->SetVerticalScrollbar( state ); + } +#if 0 + void SetHorizontalScrolling( bool status ) + { + __base()->SetHorizontalScrolling( status ); + } +#endif + void SetCatchEnterKey( bool state ) + { + __base()->SetCatchEnterKey( state ); + } + + void SetMaximumCharCount( int maxChars ) + { + __base()->SetMaximumCharCount( maxChars ); + } +#if 0 + void SetWrap( bool wrap ) + { + __base()->SetWrap( wrap ); + } +#endif + void SetAllowNumericInputOnly( bool state ) + { + __base()->SetAllowNumericInputOnly( state ); + } +#if 0 + void SetDisabledBgColor( int r, int g, int b, int a ) + { + __base()->SetDisabledBgColor( Color( r, g, b, a ) ); + } + + void SetSelectionTextColor( int r, int g, int b, int a ) + { + __base()->SetSelectionTextColor( Color( r, g, b, a ) ); + } + + void SetSelectionBgColor( int r, int g, int b, int a ) + { + __base()->SetSelectionBgColor( Color( r, g, b, a ) ); + } + + void SetSelectionUnfocusedBgColor( int r, int g, int b, int a ) + { + __base()->SetSelectionUnfocusedBgColor( Color( r, g, b, a ) ); + } +#endif +}; + +#define DEFINE_VGUI_SCRIPTFUNC_TextEntry()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetText, "" )\ + DEFINE_SCRIPTFUNC( GetText, "" )\ + DEFINE_SCRIPTFUNC( SetFont, "" )\ + DEFINE_SCRIPTFUNC( SetEditable, "" )\ + DEFINE_SCRIPTFUNC( GotoTextStart, "" )\ + DEFINE_SCRIPTFUNC( GotoTextEnd, "" )\ + DEFINE_SCRIPTFUNC( InsertString, "" )\ + DEFINE_SCRIPTFUNC( SelectNone, "" )\ + DEFINE_SCRIPTFUNC( SetMultiline, "" )\ + DEFINE_SCRIPTFUNC( SetVerticalScrollbar, "" )\ + DEFINE_SCRIPTFUNC( SetCatchEnterKey, "" )\ + DEFINE_SCRIPTFUNC( SetMaximumCharCount, "" )\ + DEFINE_SCRIPTFUNC( SetAllowNumericInputOnly, "" )\ + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if !defined(NO_STEAM) +CLASS_HELPER_INTERFACE( AvatarImage, Panel ) +{ +public: + void SetPlayer( const char *steam2id, int eAvatarSize ) + { + uint32 __SteamInstanceID; + uint32 __SteamLocalUserID_Low32Bits; + uint32 __SteamLocalUserID_High32Bits; + + int c = sscanf( steam2id, "STEAM_%u:%u:%u", + &__SteamInstanceID, &__SteamLocalUserID_High32Bits, &__SteamLocalUserID_Low32Bits ); + + if ( c < 3 ) + return; + + CSteamID id( __SteamLocalUserID_Low32Bits * 2 + __SteamLocalUserID_High32Bits, + k_EUniversePublic, + k_EAccountTypeIndividual ); + + __base()->SetPlayer( id, (EAvatarSize)eAvatarSize ); + } + + void SetPlayerByIndex( int entindex, int eAvatarSize ) + { + if ( !entindex ) + { + __base()->ClearAvatar(); + return; + } + + __base()->SetPlayer( entindex, (EAvatarSize)eAvatarSize ); + } + + void SetDefaultAvatar( const char *imageName ) + { + __base()->SetDefaultAvatar( vgui_GetImage( imageName, false ) ); + } + + void SetShouldScaleImage( bool state ) + { + __base()->SetShouldScaleImage( state ); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_AvatarImage()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetPlayer, "" )\ + DEFINE_SCRIPTFUNC( SetPlayerByIndex, "" )\ + DEFINE_SCRIPTFUNC( SetDefaultAvatar, "" )\ + DEFINE_SCRIPTFUNC( SetShouldScaleImage, "" ) +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if VGUI_TGA_IMAGE_PANEL +CLASS_HELPER_INTERFACE( TGAImagePanel, Panel ) +{ +public: + void SetTGAImage( const char *p ) + { + __base()->SetTGAImage( p ); + } + + void SetDrawColor( int r, int g, int b, int a ) + { + __base()->SetDrawColor( r, g, b, a ); + } + + void SetShouldScaleImage( bool i ) + { + __base()->SetShouldScaleImage( i ); + } +}; + +#define DEFINE_VGUI_SCRIPTFUNC_TGAImagePanel()\ + DEFINE_VGUI_SCRIPTFUNC_Panel()\ + DEFINE_SCRIPTFUNC( SetTGAImage, "" )\ + DEFINE_SCRIPTFUNC( SetDrawColor, "" )\ + DEFINE_SCRIPTFUNC( SetShouldScaleImage, "" ) +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +//============================================================== +//============================================================== + + +static inline void SetHScript( HSCRIPT &var, HSCRIPT val ) +{ + if ( var && g_pScriptVM ) + g_pScriptVM->ReleaseScript( var ); + var = val; +} + +#define CheckCallback(s)\ + if ( FStrEq( cb, #s ) )\ + {\ + SetHScript( m_hfn##s, fn );\ + return;\ + } + +//-------------------------------------------------------- +// C++ objects for vgui overrides and messages. +//-------------------------------------------------------- + + +class CScript_Panel : public Panel +{ + DECLARE_SCRIPTVGUI_CLASS( Panel ); + +private: + HSCRIPT m_hfnPaint; + HSCRIPT m_hfnPaintBackground; + HSCRIPT m_hfnPostChildPaint; + + HSCRIPT m_hfnPerformLayout; + HSCRIPT m_hfnOnTick; + HSCRIPT m_hfnOnScreenSizeChanged; + + HSCRIPT m_hfnOnCursorEntered; + HSCRIPT m_hfnOnCursorExited; + HSCRIPT m_hfnOnCursorMoved; + + HSCRIPT m_hfnOnMousePressed; + HSCRIPT m_hfnOnMouseDoublePressed; + HSCRIPT m_hfnOnMouseReleased; + HSCRIPT m_hfnOnMouseWheeled; + + HSCRIPT m_hfnOnKeyCodePressed; + HSCRIPT m_hfnOnKeyCodeReleased; + HSCRIPT m_hfnOnKeyCodeTyped; +#if SCRIPT_VGUI_SIGNAL_INTERFACE + HSCRIPT m_hfnOnCommand; +#endif + +public: + CScript_Panel( Panel *parent, const char *name ) : + BaseClass( parent, name ), + + m_hfnPaint(NULL), + m_hfnPaintBackground(NULL), + m_hfnPostChildPaint(NULL), + + m_hfnPerformLayout(NULL), + m_hfnOnTick(NULL), + m_hfnOnScreenSizeChanged(NULL), + + m_hfnOnCursorEntered(NULL), + m_hfnOnCursorExited(NULL), + m_hfnOnCursorMoved(NULL), + + m_hfnOnMousePressed(NULL), + m_hfnOnMouseDoublePressed(NULL), + m_hfnOnMouseReleased(NULL), + m_hfnOnMouseWheeled(NULL), + + m_hfnOnKeyCodePressed(NULL), + m_hfnOnKeyCodeReleased(NULL), + m_hfnOnKeyCodeTyped(NULL) +#if SCRIPT_VGUI_SIGNAL_INTERFACE + , + m_hfnOnCommand(NULL) +#endif + {} + + void Shutdown() + { + ivgui()->RemoveTickSignal( GetVPanel() ); + + SetHScript( m_hfnPaint, NULL ); + SetHScript( m_hfnPaintBackground, NULL ); + SetHScript( m_hfnPostChildPaint, NULL ); + + SetHScript( m_hfnPerformLayout, NULL ); + SetHScript( m_hfnOnTick, NULL ); + SetHScript( m_hfnOnScreenSizeChanged, NULL ); + + SetHScript( m_hfnOnCursorEntered, NULL ); + SetHScript( m_hfnOnCursorExited, NULL ); + SetHScript( m_hfnOnCursorMoved, NULL ); + + SetHScript( m_hfnOnMousePressed, NULL ); + SetHScript( m_hfnOnMouseDoublePressed, NULL ); + SetHScript( m_hfnOnMouseReleased, NULL ); + SetHScript( m_hfnOnMouseWheeled, NULL ); + + SetHScript( m_hfnOnKeyCodePressed, NULL ); + SetHScript( m_hfnOnKeyCodeReleased, NULL ); + SetHScript( m_hfnOnKeyCodeTyped, NULL ); +#if SCRIPT_VGUI_SIGNAL_INTERFACE + SetHScript( m_hfnOnCommand, NULL ); +#endif + } + +public: + void Paint() + { + g_pScriptVM->ExecuteFunction( m_hfnPaint, NULL, 0, NULL, NULL, true ); + } + + void PaintBackground() + { + if ( m_hfnPaintBackground ) + { + g_pScriptVM->ExecuteFunction( m_hfnPaintBackground, NULL, 0, NULL, NULL, true ); + } + else + { + BaseClass::PaintBackground(); + } + } + + void PostChildPaint() + { + g_pScriptVM->ExecuteFunction( m_hfnPostChildPaint, NULL, 0, NULL, NULL, true ); + } + + void PerformLayout() + { + BaseClass::PerformLayout(); + + if ( m_hfnPerformLayout ) + { + g_pScriptVM->ExecuteFunction( m_hfnPerformLayout, NULL, 0, NULL, NULL, true ); + } + } + + void OnTick() + { + g_pScriptVM->ExecuteFunction( m_hfnOnTick, NULL, 0, NULL, NULL, true ); + } + + void OnScreenSizeChanged( int oldwide, int oldtall ) + { + BaseClass::OnScreenSizeChanged( oldwide, oldtall ); + + if ( m_hfnOnScreenSizeChanged ) + { + ScriptVariant_t args[2] = { oldwide, oldtall }; + g_pScriptVM->ExecuteFunction( m_hfnOnScreenSizeChanged, args, 2, NULL, NULL, true ); + } + } +#if SCRIPT_VGUI_SIGNAL_INTERFACE + void OnCommand( const char *command ) + { + if ( m_hfnOnCommand ) + { + ScriptVariant_t ret, arg = command; + g_pScriptVM->ExecuteFunction( m_hfnOnCommand, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnCommand( command ); + } +#endif + void OnCursorEntered() + { + if ( m_hfnOnCursorEntered ) + { + g_pScriptVM->ExecuteFunction( m_hfnOnCursorEntered, NULL, 0, NULL, NULL, true ); + } + } + + void OnCursorExited() + { + if ( m_hfnOnCursorExited ) + { + g_pScriptVM->ExecuteFunction( m_hfnOnCursorExited, NULL, 0, NULL, NULL, true ); + } + } + + void OnCursorMoved( int x, int y ) + { + if ( m_hfnOnCursorMoved ) + { + ScriptVariant_t args[2] = { x, y }; + g_pScriptVM->ExecuteFunction( m_hfnOnCursorMoved, args, 2, NULL, NULL, true ); + } + else + { + Assert( !ParentNeedsCursorMoveEvents() ); + } + } + + void OnMousePressed( MouseCode code ) + { + if ( m_hfnOnMousePressed ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMousePressed, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseDoublePressed( MouseCode code ) + { + if ( m_hfnOnMouseDoublePressed ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseDoublePressed, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseReleased( MouseCode code ) + { + if ( m_hfnOnMouseReleased ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseReleased, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseWheeled( int delta ) + { + if ( m_hfnOnMouseWheeled ) + { + ScriptVariant_t arg = (int)delta; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseWheeled, &arg, 1, NULL, NULL, true ); + } + } + + void OnKeyCodePressed( KeyCode code ) + { + if ( m_hfnOnKeyCodePressed ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodePressed, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnKeyCodePressed( code ); + } + + void OnKeyCodeReleased( KeyCode code ) + { + if ( m_hfnOnKeyCodeReleased ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodeReleased, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnKeyCodeReleased( code ); + } + + void OnKeyCodeTyped( KeyCode code ) + { + if ( m_hfnOnKeyCodeTyped ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodeTyped, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnKeyCodeTyped( code ); + } + +public: + void SetCallback( const char* cb, HSCRIPT fn ) + { + CheckCallback( Paint ); + CheckCallback( PaintBackground ); + CheckCallback( PostChildPaint ); + + CheckCallback( PerformLayout ); + CheckCallback( OnTick ); + CheckCallback( OnScreenSizeChanged ); + + CheckCallback( OnCursorEntered ); + CheckCallback( OnCursorExited ); + CheckCallback( OnCursorMoved ); + + CheckCallback( OnMousePressed ); + CheckCallback( OnMouseDoublePressed ); + CheckCallback( OnMouseReleased ); + CheckCallback( OnMouseWheeled ); + + CheckCallback( OnKeyCodePressed ); + CheckCallback( OnKeyCodeReleased ); + CheckCallback( OnKeyCodeTyped ); +#if SCRIPT_VGUI_SIGNAL_INTERFACE + CheckCallback( OnCommand ); +#endif + + g_pScriptVM->RaiseException("invalid callback"); + } +}; + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +class CScript_Frame : public Frame +{ + DECLARE_SCRIPTVGUI_CLASS( Frame ); + +private: + HSCRIPT m_hfnPaint; + HSCRIPT m_hfnPaintBackground; + + HSCRIPT m_hfnPerformLayout; + HSCRIPT m_hfnOnTick; + HSCRIPT m_hfnOnScreenSizeChanged; + + HSCRIPT m_hfnOnCursorEntered; + HSCRIPT m_hfnOnCursorExited; + HSCRIPT m_hfnOnCursorMoved; + + HSCRIPT m_hfnOnMousePressed; + HSCRIPT m_hfnOnMouseDoublePressed; + HSCRIPT m_hfnOnMouseReleased; + HSCRIPT m_hfnOnMouseWheeled; + + HSCRIPT m_hfnOnKeyCodePressed; + HSCRIPT m_hfnOnKeyCodeReleased; + HSCRIPT m_hfnOnKeyCodeTyped; +#if SCRIPT_VGUI_SIGNAL_INTERFACE + HSCRIPT m_hfnOnCommand; +#endif + +public: + CScript_Frame( Panel *parent, const char *name ) : + + // Start without popup + BaseClass( parent, name, false, false ), + + m_hfnPaint(NULL), + m_hfnPaintBackground(NULL), + + m_hfnPerformLayout(NULL), + m_hfnOnTick(NULL), + m_hfnOnScreenSizeChanged(NULL), + + m_hfnOnCursorEntered(NULL), + m_hfnOnCursorExited(NULL), + m_hfnOnCursorMoved(NULL), + + m_hfnOnMousePressed(NULL), + m_hfnOnMouseDoublePressed(NULL), + m_hfnOnMouseReleased(NULL), + m_hfnOnMouseWheeled(NULL), + + m_hfnOnKeyCodePressed(NULL), + m_hfnOnKeyCodeReleased(NULL), + m_hfnOnKeyCodeTyped(NULL) +#if SCRIPT_VGUI_SIGNAL_INTERFACE + , + m_hfnOnCommand(NULL) +#endif + { + SetFadeEffectDisableOverride( true ); + } + + void Shutdown() + { + ivgui()->RemoveTickSignal( GetVPanel() ); + + SetHScript( m_hfnPaint, NULL ); + SetHScript( m_hfnPaintBackground, NULL ); + + SetHScript( m_hfnPerformLayout, NULL ); + SetHScript( m_hfnOnTick, NULL ); + SetHScript( m_hfnOnScreenSizeChanged, NULL ); + + SetHScript( m_hfnOnMousePressed, NULL ); + SetHScript( m_hfnOnMouseDoublePressed, NULL ); + SetHScript( m_hfnOnMouseReleased, NULL ); + SetHScript( m_hfnOnMouseWheeled, NULL ); + + SetHScript( m_hfnOnKeyCodePressed, NULL ); + SetHScript( m_hfnOnKeyCodeReleased, NULL ); + SetHScript( m_hfnOnKeyCodeTyped, NULL ); +#if SCRIPT_VGUI_SIGNAL_INTERFACE + SetHScript( m_hfnOnCommand, NULL ); +#endif + } + +public: + void Paint() + { + g_pScriptVM->ExecuteFunction( m_hfnPaint, NULL, 0, NULL, NULL, true ); + } + + void PaintBackground() + { + if ( m_hfnPaintBackground ) + { + g_pScriptVM->ExecuteFunction( m_hfnPaintBackground, NULL, 0, NULL, NULL, true ); + } + else + { + BaseClass::PaintBackground(); + } + } + + void PerformLayout() + { + BaseClass::PerformLayout(); + + if ( m_hfnPerformLayout ) + { + g_pScriptVM->ExecuteFunction( m_hfnPerformLayout, NULL, 0, NULL, NULL, true ); + } + } + + void OnTick() + { + g_pScriptVM->ExecuteFunction( m_hfnOnTick, NULL, 0, NULL, NULL, true ); + } + + void OnScreenSizeChanged( int oldwide, int oldtall ) + { + BaseClass::OnScreenSizeChanged( oldwide, oldtall ); + + if ( m_hfnOnScreenSizeChanged ) + { + ScriptVariant_t args[2] = { oldwide, oldtall }; + g_pScriptVM->ExecuteFunction( m_hfnOnScreenSizeChanged, args, 2, NULL, NULL, true ); + } + } +#if SCRIPT_VGUI_SIGNAL_INTERFACE + void OnCommand( const char *command ) + { + if ( m_hfnOnCommand ) + { + ScriptVariant_t ret, arg = command; + g_pScriptVM->ExecuteFunction( m_hfnOnCommand, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnCommand( command ); + } +#endif + void OnCursorEntered() + { + if ( m_hfnOnCursorEntered ) + { + g_pScriptVM->ExecuteFunction( m_hfnOnCursorEntered, NULL, 0, NULL, NULL, true ); + } + } + + void OnCursorExited() + { + if ( m_hfnOnCursorExited ) + { + g_pScriptVM->ExecuteFunction( m_hfnOnCursorExited, NULL, 0, NULL, NULL, true ); + } + } + + void OnCursorMoved( int x, int y ) + { + if ( m_hfnOnCursorMoved ) + { + ScriptVariant_t args[2] = { x, y }; + g_pScriptVM->ExecuteFunction( m_hfnOnCursorMoved, args, 2, NULL, NULL, true ); + } + else + { + Assert( !ParentNeedsCursorMoveEvents() ); + } + } + + void OnMousePressed( MouseCode code ) + { + BaseClass::OnMousePressed( code ); + + if ( m_hfnOnMousePressed ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMousePressed, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseDoublePressed( MouseCode code ) + { + if ( m_hfnOnMouseDoublePressed ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseDoublePressed, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseReleased( MouseCode code ) + { + if ( m_hfnOnMouseReleased ) + { + ScriptVariant_t arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseReleased, &arg, 1, NULL, NULL, true ); + } + } + + void OnMouseWheeled( int delta ) + { + if ( m_hfnOnMouseWheeled ) + { + ScriptVariant_t arg = (int)delta; + g_pScriptVM->ExecuteFunction( m_hfnOnMouseWheeled, &arg, 1, NULL, NULL, true ); + } + } + + void OnKeyCodePressed( KeyCode code ) + { + if ( m_hfnOnKeyCodePressed ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodePressed, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnKeyCodePressed( code ); + } + + void OnKeyCodeReleased( KeyCode code ) + { + if ( m_hfnOnKeyCodeReleased ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodeReleased, &arg, 1, &ret, NULL, true ); + + // Return true to swallow + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + } + + BaseClass::OnKeyCodeReleased( code ); + } + + void OnKeyCodeTyped( KeyCode code ) + { + if ( m_hfnOnKeyCodeTyped ) + { + ScriptVariant_t ret, arg = (int)code; + g_pScriptVM->ExecuteFunction( m_hfnOnKeyCodeTyped, &arg, 1, &ret, NULL, true ); + + // Return true to swallow the CanChainKeysToParent() override check and fallback, + // which by default swallows the input. + if ( ret.m_type == FIELD_BOOLEAN && ret.m_bool ) + return; + + if ( CanChainKeysToParent() ) + { + BaseClass::OnKeyCodeTyped( code ); + } + } + else + { + BaseClass::OnKeyCodeTyped( code ); + } + } + +public: + void SetCallback( const char* cb, HSCRIPT fn ) + { + CheckCallback( Paint ); + CheckCallback( PaintBackground ); + + CheckCallback( PerformLayout ); + CheckCallback( OnTick ); + CheckCallback( OnScreenSizeChanged ); + + CheckCallback( OnCursorEntered ); + CheckCallback( OnCursorExited ); + CheckCallback( OnCursorMoved ); + + CheckCallback( OnMousePressed ); + CheckCallback( OnMouseDoublePressed ); + CheckCallback( OnMouseReleased ); + CheckCallback( OnMouseWheeled ); + + CheckCallback( OnKeyCodePressed ); + CheckCallback( OnKeyCodeReleased ); + CheckCallback( OnKeyCodeTyped ); +#if SCRIPT_VGUI_SIGNAL_INTERFACE + CheckCallback( OnCommand ); +#endif + + g_pScriptVM->RaiseException("invalid callback"); + } +}; + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +class CScript_Button : public Button +{ + DECLARE_SCRIPTVGUI_CLASS( Button ); + +private: + HSCRIPT m_hfnPaint; + HSCRIPT m_hfnPaintBackground; + HSCRIPT m_hfnDoClick; + +public: + CScript_Button( Panel *parent, const char *name, const char *text ) : + BaseClass( parent, name, text ), + + m_hfnPaint(NULL), + m_hfnPaintBackground(NULL), + + m_hfnDoClick(NULL) + {} + + void Shutdown() + { + SetHScript( m_hfnPaint, NULL ); + SetHScript( m_hfnPaintBackground, NULL ); + + SetHScript( m_hfnDoClick, NULL ); + } + +public: + void Paint() + { + if ( m_hfnPaint ) + { + g_pScriptVM->ExecuteFunction( m_hfnPaint, NULL, 0, NULL, NULL, true ); + } + else + { + BaseClass::Paint(); + } + } + + void PaintBackground() + { + if ( m_hfnPaintBackground ) + { + g_pScriptVM->ExecuteFunction( m_hfnPaintBackground, NULL, 0, NULL, NULL, true ); + } + else + { + BaseClass::PaintBackground(); + } + } + + void DoClick() + { + BaseClass::DoClick(); + + if ( m_hfnDoClick ) + { + g_pScriptVM->ExecuteFunction( m_hfnDoClick, NULL, 0, NULL, NULL, true ); + } + } + +public: + void SetCallback( const char* cb, HSCRIPT fn ) + { + CheckCallback( Paint ); + CheckCallback( PaintBackground ); + CheckCallback( DoClick ); + + g_pScriptVM->RaiseException("invalid callback"); + } +}; + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +class CScript_TextEntry : public TextEntry +{ + DECLARE_SCRIPTVGUI_CLASS( TextEntry ); + +private: + HSCRIPT m_hfnTextChanged; + +public: + CScript_TextEntry( Panel *parent, const char *name ) : + BaseClass( parent, name ), + + m_hfnTextChanged(NULL) + {} + + void Shutdown() + { + SetHScript( m_hfnTextChanged, NULL ); + } + +public: + //--------------------------------------------- + // On "TextMessage" message. + // Used for responding to user input as it is typed. + //--------------------------------------------- + void FireActionSignal() + { + BaseClass::FireActionSignal(); + + if ( m_hfnTextChanged ) + { + g_pScriptVM->ExecuteFunction( m_hfnTextChanged, NULL, 0, NULL, NULL, true ); + } + } + +public: + void SetCallback( const char* cb, HSCRIPT fn ) + { + CheckCallback( TextChanged ); + + g_pScriptVM->RaiseException("invalid callback"); + } +}; + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if !defined(NO_STEAM) +class CScript_AvatarImage : public CAvatarImagePanel +{ + DECLARE_SCRIPTVGUI_CLASS_EX( CScript_AvatarImage, CAvatarImagePanel ); + +public: + CScript_AvatarImage( Panel *parent, const char *name ) : + BaseClass( parent, name ) + { + SetShouldDrawFriendIcon( false ); + } + + DEBUG_DESTRUCTOR( ~CScript_AvatarImage, CAvatarImagePanel ) + + void Shutdown() {} +}; +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if VGUI_TGA_IMAGE_PANEL +class CTGAImagePanel : public Panel +{ + DECLARE_SCRIPTVGUI_CLASS_EX( CTGAImagePanel, Panel ); + +private: + int m_iTextureID; + int m_nWidth; + int m_nHeight; + Color m_ImageColor; + bool m_bScaleImage; + +public: + CTGAImagePanel( Panel *parent, const char *name ) : + BaseClass( parent, name ), + m_iTextureID(-1), + m_bScaleImage(0), + m_ImageColor( 255, 255, 255, 255 ) + { + SetPaintBackgroundEnabled( false ); + } + + ~CTGAImagePanel() + { + DebugDestructor( CTGAImagePanel ); + + if ( m_iTextureID != -1 ) + { + surface()->DestroyTextureID( m_iTextureID ); + } + } + + void Shutdown() {} + +public: + void Paint() + { + if ( m_iTextureID != -1 ) + { + surface()->DrawSetColor( m_ImageColor ); + surface()->DrawSetTexture( m_iTextureID ); + + if ( m_bScaleImage ) + { + int w, t; + GetSize( w, t ); + surface()->DrawTexturedRect( 0, 0, w, t ); + } + else + { + surface()->DrawTexturedRect( 0, 0, m_nWidth, m_nHeight ); + } + } + else + { + int w, t; + GetSize( w, t ); + surface()->DrawSetColor( 200, 50, 150, 255 ); + surface()->DrawFilledRect( 0, 0, w, t ); + } + } + +public: + void SetTGAImage( const char *fileName ) + { + if ( V_stricmp( V_GetFileExtension( fileName ), "tga" ) != 0 ) + return; + + CUtlMemory< unsigned char > tga; + + if ( TGALoader::LoadRGBA8888( fileName, tga, m_nWidth, m_nHeight ) ) + { + if ( m_iTextureID == -1 ) + { + m_iTextureID = surface()->CreateNewTextureID( true ); + } + + surface()->DrawSetTextureRGBA( m_iTextureID, tga.Base(), m_nWidth, m_nHeight, false, false ); + } + else + { + Warning( "Failed to load TGA image: '%s'\n", fileName ); + } + } + + void SetDrawColor( int r, int g, int b, int a ) + { + m_ImageColor.SetColor( r, g, b, a ); + } + + void SetShouldScaleImage( bool state ) + { + m_bScaleImage = state; + } +}; +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +//============================================================== +//============================================================== + +//-------------------------------------------------------- +// Script objects +//-------------------------------------------------------- + +DEFINE_VGUI_CLASS_EMPTY_DEFAULT_TEXT( Label ) +DEFINE_VGUI_CLASS_EMPTY( ImagePanel ) +DEFINE_VGUI_CLASS_EMPTY( RichText ) + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +BEGIN_VGUI_HELPER( Panel ) + void SetCallback( const char *a, HSCRIPT b ) { __base()->SetCallback( a, b ); } +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( Panel ) + DEFINE_SCRIPTFUNC( SetCallback, "" ) +END_SCRIPTDESC() + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +BEGIN_VGUI_HELPER( Frame ) + void SetCallback( const char *a, HSCRIPT b ) { __base()->SetCallback( a, b ); } +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( Frame ) + DEFINE_SCRIPTFUNC( SetCallback, "" ) +END_SCRIPTDESC() + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +BEGIN_VGUI_HELPER_DEFAULT_TEXT( Button ) + void SetCallback( const char *a, HSCRIPT b ) { __base()->SetCallback( a, b ); } +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( Button ) + DEFINE_SCRIPTFUNC( SetCallback, "" ) +END_SCRIPTDESC() + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +BEGIN_VGUI_HELPER( TextEntry ) + void SetCallback( const char *a, HSCRIPT b ) { __base()->SetCallback( a, b ); } +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( TextEntry ) + DEFINE_SCRIPTFUNC( SetCallback, "" ) +END_SCRIPTDESC() + +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if !defined(NO_STEAM) +BEGIN_VGUI_HELPER( AvatarImage ) +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( AvatarImage ) +END_SCRIPTDESC() +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- +#if VGUI_TGA_IMAGE_PANEL +BEGIN_VGUI_HELPER_EX( TGAImagePanel, CTGAImagePanel ) +END_VGUI_HELPER() + +BEGIN_SCRIPTDESC_VGUI( TGAImagePanel ) +END_SCRIPTDESC() +#endif +//-------------------------------------------------------------- +//-------------------------------------------------------------- + +//-------------------------------------------------------------- +//-------------------------------------------------------------- + + +//============================================================== +//============================================================== + + +struct hudelementcache_t +{ + CUtlConstString name; + int bits; +}; +CUtlVector< hudelementcache_t > m_HudElementCache; + +// Check if hud elements were changed in this level to shortcut on level shutdown +bool m_bHudVisiblityChangedThisLevel = false; + + + +class CScriptVGUI : public CAutoGameSystem +{ +public: + void LevelShutdownPostEntity(); + void Shutdown(); + +public: + HSCRIPT CreatePanel( const char* panelClass, HSCRIPT parent, const char* panelName, int root ); + //void LoadSchemeFromFile( const char *filename, const char *tag ); + +} script_vgui; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptVGUI, "IVGui", SCRIPT_SINGLETON ) + DEFINE_SCRIPTFUNC( CreatePanel, SCRIPT_HIDE ) +END_SCRIPTDESC() + + +HSCRIPT CScriptVGUI::CreatePanel( const char* panelClass, HSCRIPT parent, const char* panelName, int root ) +{ + if ( (unsigned)g_ScriptPanels.Count() >= (unsigned)g_ScriptPanels.InvalidIndex()-1 ) + { + Warning( "CScriptVGUI::CreatePanel() exhausted vgui panel storage!\n" ); + return NULL; + } + +#define Check( _name )\ + if ( FStrEq( panelClass, #_name ) )\ + {\ + CScript_##_name##_Helper *helper = AllocScriptPanel< CScript_##_name##_Helper >();\ + helper->CreateFromScript< CScript_##_name##_Helper >( (HSCRIPT)parent, panelName, root );\ + DebugDevMsg( "%3d | Create vgui %s '%s' %s\n", g_ScriptPanels.Count(), panelClass, panelName, helper->GetDebugName() );\ + return helper->GetScriptInstance();\ + } + + Check( Panel ); + Check( Label ); + Check( Button ); + Check( ImagePanel ); + Check( Frame ); + Check( RichText ); + Check( TextEntry ); +#if !defined(NO_STEAM) + Check( AvatarImage ); +#endif +#if VGUI_TGA_IMAGE_PANEL + Check( TGAImagePanel ); +#endif + + g_pScriptVM->RaiseException("invalid vgui class"); + return NULL; + +#undef Check +} + +void CScriptVGUI::LevelShutdownPostEntity() +{ + DebugMsg( "LevelShutdownPostEntity()\n" ); + + while ( g_ScriptPanels.Count() ) + { + Assert( g_ScriptPanels.Head() != g_ScriptPanels.InvalidIndex() ); + + int head = g_ScriptPanels.Head(); + g_ScriptPanels[ head ]->Destroy( head ); + } + g_ScriptPanels.Purge(); + + FOR_EACH_VEC( g_ScriptTextureIDs, i ) + { +#ifdef _DEBUG + char tex[MAX_PATH]; + surface()->DrawGetTextureFile( g_ScriptTextureIDs[i], tex, sizeof(tex)-1 ); + DebugMsg( "Destroy texture [%i]%s\n", g_ScriptTextureIDs[i], tex ); +#endif + surface()->DestroyTextureID( g_ScriptTextureIDs[i] ); + } + g_ScriptTextureIDs.Purge(); + + // + // Reset hud element visibility + // + if ( m_bHudVisiblityChangedThisLevel ) + { + m_bHudVisiblityChangedThisLevel = false; + + FOR_EACH_VEC( m_HudElementCache, i ) + { + const hudelementcache_t &cache = m_HudElementCache[i]; + Assert( !cache.name.IsEmpty() ); + CHudElement *elem = gHUD.FindElement( cache.name ); + Assert( elem ); + if ( elem ) + { + elem->SetHiddenBits( cache.bits ); + } + } + } +} + +void CScriptVGUI::Shutdown() +{ + VGUI_DestroyScriptRootPanels(); + + FOR_EACH_DICT_FAST( g_ScriptFonts, i ) + { + fontalias_t &alias = g_ScriptFonts[i]; + for ( int j = 0; j < alias.Count(); ++j ) + { + char *pName = alias.Element(j).name; + if ( pName ) + { + free( pName ); + alias.Element(j).name = NULL; + } + } + + alias.Purge(); + } + + g_ScriptFonts.Purge(); + + m_HudElementCache.Purge(); +} + + +void SetHudElementVisible( const char *name, bool state ) +{ + CHudElement *elem = gHUD.FindElement( name ); + if ( !elem ) + return; + + int iOldBits = -2; + + FOR_EACH_VEC( m_HudElementCache, i ) + { + const hudelementcache_t &cache = m_HudElementCache[i]; + if ( !V_stricmp( cache.name, name ) ) + { + iOldBits = cache.bits; + break; + } + } + + if ( iOldBits == -2 ) + { + if ( state ) // no change + return; + + // First time setting the visibility of this element, save the original bits + hudelementcache_t &cache = m_HudElementCache.Element( m_HudElementCache.AddToTail() ); + cache.name.Set( name ); + cache.bits = elem->GetHiddenBits(); + } + + elem->SetHiddenBits( state ? iOldBits : -1 ); + + m_bHudVisiblityChangedThisLevel = true; +} + +#ifdef _DEBUG +CON_COMMAND( dump_hud_elements, "" ) +{ + int size = gHUD.m_HudList.Size(); + + CUtlVector< const char* > list( 0, size ); + + for ( int i = 0; i < size; i++ ) + { + list.AddToTail( gHUD.m_HudList[i]->GetName() ); + } + + struct _cmp + { + static int __cdecl fn( const char * const *a, const char * const *b ) { return strcmp( *a, *b ); } + }; + + list.Sort( _cmp::fn ); + + for ( int i = 0; i < size; i++ ) + { + Msg( "%s\n", list[i] ); + } +} +#endif + + +class CScriptIInput +{ +public: + void MakeWeaponSelection( HSCRIPT weapon ) + { + ::input->MakeWeaponSelection( HScriptToClass< C_BaseCombatWeapon >( weapon ) ); + } +#if 0 + int GetButtonBits() + { + return ::input->GetButtonBits(0); + } + + void ClearInputButton( int i ) + { + return ::input->ClearInputButton(i); + } +#endif + void SetCursorPos( int x, int y ) + { + vgui::input()->SetCursorPos( x, y ); + } + + int GetAnalogValue( int code ) + { + Assert( code >= 0 && code < ANALOG_CODE_LAST ); + + if ( code < 0 || code >= ANALOG_CODE_LAST ) + return 0; + + return inputsystem->GetAnalogValue( (AnalogCode_t)code ); + } + + int GetAnalogDelta( int code ) + { + Assert( code >= 0 && code < ANALOG_CODE_LAST ); + + if ( code < 0 || code >= ANALOG_CODE_LAST ) + return 0; + + return inputsystem->GetAnalogDelta( (AnalogCode_t)code ); + } + + bool IsButtonDown( int code ) + { + Assert( code >= BUTTON_CODE_NONE && code < BUTTON_CODE_LAST ); + + if ( code < BUTTON_CODE_NONE || code >= BUTTON_CODE_LAST ) + return 0; + + return inputsystem->IsButtonDown( (ButtonCode_t)code ); + } + + // key -> button + int StringToButtonCode( const char *key ) + { + return inputsystem->StringToButtonCode( key ); + } + + // button -> key + const char *ButtonCodeToString( int code ) + { + Assert( code >= BUTTON_CODE_NONE && code < BUTTON_CODE_LAST ); + + if ( code < BUTTON_CODE_NONE || code >= BUTTON_CODE_LAST ) + return 0; + + return inputsystem->ButtonCodeToString( (ButtonCode_t)code ); + } + + // bind -> key + const char *LookupBinding( const char *bind ) + { + return engine->Key_LookupBinding( bind ); + } + + // button -> bind + const char *BindingForKey( int code ) + { + return engine->Key_BindingForKey( (ButtonCode_t)code ); + } +#if 0 + const char *GetIMELanguageShortCode() + { + static char ret[5]; + wchar_t get[5]; + get[0] = L'\0'; + vgui::input()->GetIMELanguageShortCode( get, wcslen(get) ); + g_pVGuiLocalize->ConvertUnicodeToANSI( get, ret, sizeof(ret) ); + return ret; + } +#endif +} script_input; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptIInput, "IInput", SCRIPT_SINGLETON ) + DEFINE_SCRIPTFUNC( MakeWeaponSelection, "" ) + + DEFINE_SCRIPTFUNC( SetCursorPos, "" ) + + DEFINE_SCRIPTFUNC( GetAnalogValue, "" ) + DEFINE_SCRIPTFUNC( GetAnalogDelta, "" ) + DEFINE_SCRIPTFUNC( IsButtonDown, "" ) + + DEFINE_SCRIPTFUNC( StringToButtonCode, "" ) + DEFINE_SCRIPTFUNC( ButtonCodeToString, "" ) + DEFINE_SCRIPTFUNC( LookupBinding, "" ) + DEFINE_SCRIPTFUNC( BindingForKey, "" ) +END_SCRIPTDESC() + + +void SetClipboardText( const char *text ) +{ + system()->SetClipboardText( text, V_strlen(text) ); +} + +//============================================================== +//============================================================== + +#if 0 +//----------------------------------------------------------------------------- +// Get world position in screen space [0,1]. Return true if on screen. +//----------------------------------------------------------------------------- +inline bool WorldToScreen( const Vector &pos, int &ix, int &iy ) +{ + int scrw, scrh; + surface()->GetScreenSize( scrw, scrh ); + + const VMatrix &worldToScreen = engine->WorldToScreenMatrix(); + bool bOnScreen; + + // VMatrix * Vector (position projective) + vec_t w = worldToScreen[3][0] * pos[0] + worldToScreen[3][1] * pos[1] + worldToScreen[3][2] * pos[2] + worldToScreen[3][3]; + vec_t fx = worldToScreen[0][0] * pos[0] + worldToScreen[0][1] * pos[1] + worldToScreen[0][2] * pos[2] + worldToScreen[0][3]; + vec_t fy = worldToScreen[1][0] * pos[0] + worldToScreen[1][1] * pos[1] + worldToScreen[1][2] * pos[2] + worldToScreen[1][3]; + + if ( w < 0.001f ) + { + fx *= 1e5f; + fy *= 1e5f; + bOnScreen = false; + } + else + { + w = 1.0f / w; + fx *= w; + fy *= w; + bOnScreen = true; + } + + ix = (int)( scrw * 0.5f * ( 1.0f + fx ) + 0.5f ); + iy = (int)( scrh * 0.5f * ( 1.0f - fy ) + 0.5f ); + + return bOnScreen; +} +#endif +//----------------------------------------------------------------------------- +// Get screen pixel position [0,1] in world space. +//----------------------------------------------------------------------------- +inline void ScreenToWorld( int x, int y, Vector &out ) +{ + int scrw, scrh; + surface()->GetScreenSize( scrw, scrh ); + float scrx = (float)x / (float)scrw; + float scry = (float)y / (float)scrh; + + vec_t tmp[2]; + tmp[0] = 2.0f * scrx - 1.0f; + tmp[1] = 1.0f - 2.0f * scry; + //tmp[2] = 1.0f; + //tmp[3] = 1.0f; + + VMatrix screenToWorld; + MatrixInverseGeneral( engine->WorldToScreenMatrix(), screenToWorld ); + + // VMatrix * Vector (position projective) + vec_t iw = 1.0f / ( screenToWorld[3][0] * tmp[0] + screenToWorld[3][1] * tmp[1] + screenToWorld[3][2] + screenToWorld[3][3] ); + out[0] = iw * ( screenToWorld[0][0] * tmp[0] + screenToWorld[0][1] * tmp[1] + screenToWorld[0][2] + screenToWorld[0][3] ); + out[1] = iw * ( screenToWorld[1][0] * tmp[0] + screenToWorld[1][1] * tmp[1] + screenToWorld[1][2] + screenToWorld[1][3] ); + out[2] = iw * ( screenToWorld[2][0] * tmp[0] + screenToWorld[2][1] * tmp[1] + screenToWorld[2][2] + screenToWorld[2][3] ); +} + +#if 0 +static bool ScriptWorldToScreen( const Vector &pos, HSCRIPT out ) +{ + int ix, iy; + bool r = WorldToScreen( pos, ix, iy ); + + g_pScriptVM->SetValue( out, (ScriptVariant_t)0, ix ); + g_pScriptVM->SetValue( out, 1, iy ); + return r; +} +#endif +static const Vector& ScriptScreenToWorld( int x, int y ) +{ + static Vector out; + ScreenToWorld( x, y, out ); + return out; +} + +static const Vector& ScreenToRay( int x, int y ) +{ + static Vector out; + ScreenToWorld( x, y, out ); + VectorSubtract( out, CurrentViewOrigin(), out ); + VectorNormalize( out ); + return out; +} + +//----------------------------------------------------------------------------- +// Get world position normalised in screen space. Return true if on screen. +//----------------------------------------------------------------------------- +int ScreenTransform( const Vector& point, Vector& screen ); +static bool ScriptScreenTransform( const Vector &pos, HSCRIPT out ) +{ + Vector v; + bool r = ScreenTransform( pos, v ); + float x = 0.5f * ( 1.0f + v[0] ); + float y = 0.5f * ( 1.0f - v[1] ); + + g_pScriptVM->SetValue( out, (ScriptVariant_t)0, x ); + g_pScriptVM->SetValue( out, 1, y ); + return !r; +} + +int ScriptScreenWidth() +{ + int w, h; + surface()->GetScreenSize( w, h ); + return w; +} + +int ScriptScreenHeight() +{ + int w, h; + surface()->GetScreenSize( w, h ); + return h; +} + +// +// Saving the static (ScreenWidth/640) ratio in a script closure +// messes up on save/restore at differing resolutions - +// the closure and the user script funcs retain the ratio at the time of the save. +// It is not possible to update restored script closure outer variables without writing language specific functions. +// +// NOTE: Returns int! int usage is more common than float operations. +// +static int ScriptXRES( float x ) +{ + return x * ( (float)ScriptScreenWidth() / 640.0f ); +} + +static int ScriptYRES( float y ) +{ + return y * ( (float)ScriptScreenHeight() / 480.0f ); +} + +vgui::HFont GetScriptFont( const char *name, bool proportional ) +{ + return script_surface.GetFont( name, proportional, NULL ); +} + + +void RegisterScriptVGUI() +{ + ScriptRegisterFunction( g_pScriptVM, SetHudElementVisible, "" ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptXRES, "XRES", "" ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptYRES, "YRES", "" ); + + ScriptRegisterFunction( g_pScriptVM, SetClipboardText, "" ); + //ScriptRegisterFunctionNamed( g_pScriptVM, ScriptWorldToScreen, "WorldToScreen", "Get world position in screen space [0,1]. Return true if on screen." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenToWorld, "ScreenToWorld", "Get screen pixel position [0,1] in world space." ); + ScriptRegisterFunction( g_pScriptVM, ScreenToRay, "Get a ray from screen pixel position to world space." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenTransform, "ScreenTransform", "Get world position normalised in screen space. Return true if on screen." ); + + g_pScriptVM->Run( g_Script_vgui_init ); + + g_pScriptVM->RegisterInstance( &script_surface, "surface" ); + g_pScriptVM->RegisterInstance( &script_input, "input" ); + g_pScriptVM->RegisterInstance( &script_vgui, "vgui" ); +} diff --git a/game/client/mapbase/vscript_vgui.h b/game/client/mapbase/vscript_vgui.h new file mode 100644 index 00000000..d5214073 --- /dev/null +++ b/game/client/mapbase/vscript_vgui.h @@ -0,0 +1,16 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VSCRIPT_VGUI_H +#define VSCRIPT_VGUI_H +#ifdef _WIN32 +#pragma once +#endif + +void RegisterScriptVGUI(); + +#endif diff --git a/game/client/mapbase/vscript_vgui.nut b/game/client/mapbase/vscript_vgui.nut new file mode 100644 index 00000000..a4452705 --- /dev/null +++ b/game/client/mapbase/vscript_vgui.nut @@ -0,0 +1,394 @@ +static const char* g_Script_vgui_init = R"script( +local DoCreateFont = ISurface.CreateFont; +ISurface.CreateFont <- function( name, props ) +{ + if ( !("name" in props) || typeof props.name != "string" ) + throw "invalid parameter 'name'"; + + if ( !("tall" in props) || typeof props.tall != "integer" || !props.tall ) + throw "invalid parameter 'tall'"; + + if ( !("weight" in props) || typeof props.weight != "integer" ) + throw "invalid parameter 'weight'"; + + local yres_min = 0, yres_max = 0; + + if ( "yres" in props && typeof props.yres == "string" ) + { + local ss = ::split( props.yres, " " ); + try + { + yres_min = ss[0].tointeger(); + yres_max = ss[1].tointeger(); + } + catch(x) + { + throw "invalid parameter 'yres'"; + } + } + + if ( ( (!("proportional" in props) || typeof props.proportional != "bool") ) && !yres_min ) + { + throw "parameter 'proportional' or 'yres' not found"; + } + else if ( "proportional" in props && props.proportional && yres_min ) + { + throw "resolution definition on a proportional font" + } + + local blur = 0, scanlines = 0, proportional = false, flags = 0; + + if ( "blur" in props && typeof props.blur == "integer" ) + blur = props.blur; + + if ( "scanlines" in props && typeof props.scanlines == "integer" ) + scanlines = props.scanlines; + + if ( "proportional" in props && typeof props.proportional == "bool" ) + proportional = props.proportional; + + if ( "italic" in props && props.italic == true ) + flags = flags | 0x001; + + if ( "underline" in props && props.underline == true ) + flags = flags | 0x002; + + if ( "strikeout" in props && props.strikeout == true ) + flags = flags | 0x004; + + if ( "symbol" in props && props.symbol == true ) + flags = flags | 0x008; + + if ( "antialias" in props && props.antialias == true ) + flags = flags | 0x010; + + if ( "gaussianblur" in props && props.gaussianblur == true ) + flags = flags | 0x020; + + if ( "rotary" in props && props.rotary == true ) + flags = flags | 0x040; + + if ( "dropshadow" in props && props.dropshadow == true ) + flags = flags | 0x080; + + if ( "additive" in props && props.additive == true ) + flags = flags | 0x100; + + if ( "outline" in props && props.outline == true ) + flags = flags | 0x200; + + if ( "custom" in props && props.custom == true ) + flags = flags | 0x400; + + if ( "bitmap" in props && props.bitmap == true ) + flags = flags | 0x800; + + return DoCreateFont( name, props.name, props.tall, props.weight, blur, scanlines, flags, yres_min, yres_max, proportional ); +} + +local _Schemes = {} +local _FontTall = {} +local DoGetFont = ISurface.DoGetFont <- ISurface.GetFont; +local DoGetFontTall = ISurface.GetFontTall; + +ISurface.GetFont <- function( name, proportional, sch = "" ) +{ + if ( sch in _Schemes ) + { + local fonts = _Schemes[sch][proportional.tointeger()]; + if ( name in fonts ) + return fonts[name]; + } + else + { + if ( typeof sch != "string" ) + throw "invalid parameter 'scheme'"; + _Schemes[sch] <- [{}, {}]; + } + + local id = DoGetFont( name, proportional, sch ); + if ( id > 0 ) + _Schemes[sch][proportional.tointeger()][name] <- id; + + return id; +} + +ISurface.GetFontTall <- function( id ) +{ + if ( id in _FontTall ) + return _FontTall[id]; + return _FontTall[id] <- DoGetFontTall( id ); +} + +local _Textures = {} +local DoGetTextureID = ISurface.GetTextureID; +local DoValidateTexture = ISurface.ValidateTexture; +local DoSetTextureFile = ISurface.SetTextureFile; + +ISurface.ValidateTexture <- function( filename, hardwareFilter, forceReload = false, procedural = false ) +{ + return DoValidateTexture( filename, hardwareFilter, forceReload, procedural ); +} + +ISurface.SetTextureFile <- function( id, filename, hardwareFilter ) +{ + if ( filename in _Textures ) + delete _Textures[filename]; + + return DoSetTextureFile( id, filename, hardwareFilter ); +} + +ISurface.GetTextureID <- function( name ) +{ + if ( name in _Textures ) + return _Textures[name]; + + local id = DoGetTextureID( name ); + if ( id > 0 ) + _Textures[name] <- id; + + return id; +} + +// Forward compatibility +IVGui.GetRootPanel <- function() { return 1000 } +//IVGui.GetGameUIRootPanel <- function() { return 1001 } +IVGui.GetClientDLLRootPanel <- function() { return 1002 } +//IVGui.GetHudViewportPanel <- function() { return 1010 } + +local CreatePanel = IVGui.CreatePanel; +IVGui.CreatePanel <- function( type, parent, name ) +{ + if ( !parent ) + throw "invalid parent"; + + local root = 0; + + if ( typeof parent == "integer" ) + { + switch ( parent ) + { + case 1000: + root = 0; + break; + + case 1002: + root = 2; + break; + + default: + throw "invalid parent"; + } + parent = null; + } + return CreatePanel( type, parent, name, root ); +} + +ISurface.__OnScreenSizeChanged <- function() +{ + _FontTall.clear(); +} + +// MAX_JOYSTICKS = 1 // ( 1 << MAX_SPLITSCREEN_CLIENT_BITS ) +// MAX_JOYSTICK_AXES = 6 // X,Y,Z,R,U,V +// JOYSTICK_MAX_BUTTON_COUNT = 32 +// JOYSTICK_POV_BUTTON_COUNT = 4 +// JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2 + +enum ButtonCode +{ + KEY_FIRST = 0 + KEY_0 = 1 + KEY_1 = 2 + KEY_2 = 3 + KEY_3 = 4 + KEY_4 = 5 + KEY_5 = 6 + KEY_6 = 7 + KEY_7 = 8 + KEY_8 = 9 + KEY_9 = 10 + KEY_A = 11 + KEY_B = 12 + KEY_C = 13 + KEY_D = 14 + KEY_E = 15 + KEY_F = 16 + KEY_G = 17 + KEY_H = 18 + KEY_I = 19 + KEY_J = 20 + KEY_K = 21 + KEY_L = 22 + KEY_M = 23 + KEY_N = 24 + KEY_O = 25 + KEY_P = 26 + KEY_Q = 27 + KEY_R = 28 + KEY_S = 29 + KEY_T = 30 + KEY_U = 31 + KEY_V = 32 + KEY_W = 33 + KEY_X = 34 + KEY_Y = 35 + KEY_Z = 36 + KEY_PAD_0 = 37 + KEY_PAD_1 = 38 + KEY_PAD_2 = 39 + KEY_PAD_3 = 40 + KEY_PAD_4 = 41 + KEY_PAD_5 = 42 + KEY_PAD_6 = 43 + KEY_PAD_7 = 44 + KEY_PAD_8 = 45 + KEY_PAD_9 = 46 + KEY_PAD_DIVIDE = 47 + KEY_PAD_MULTIPLY = 48 + KEY_PAD_MINUS = 49 + KEY_PAD_PLUS = 50 + KEY_PAD_ENTER = 51 + KEY_PAD_DECIMAL = 52 + KEY_LBRACKET = 53 + KEY_RBRACKET = 54 + KEY_SEMICOLON = 55 + KEY_APOSTROPHE = 56 + KEY_BACKQUOTE = 57 + KEY_COMMA = 58 + KEY_PERIOD = 59 + KEY_SLASH = 60 + KEY_BACKSLASH = 61 + KEY_MINUS = 62 + KEY_EQUAL = 63 + KEY_ENTER = 64 + KEY_SPACE = 65 + KEY_BACKSPACE = 66 + KEY_TAB = 67 + KEY_CAPSLOCK = 68 + KEY_NUMLOCK = 69 + KEY_ESCAPE = 70 + KEY_SCROLLLOCK = 71 + KEY_INSERT = 72 + KEY_DELETE = 73 + KEY_HOME = 74 + KEY_END = 75 + KEY_PAGEUP = 76 + KEY_PAGEDOWN = 77 + KEY_BREAK = 78 + KEY_LSHIFT = 79 + KEY_RSHIFT = 80 + KEY_LALT = 81 + KEY_RALT = 82 + KEY_LCONTROL = 83 + KEY_RCONTROL = 84 + KEY_LWIN = 85 + KEY_RWIN = 86 + KEY_APP = 87 + KEY_UP = 88 + KEY_LEFT = 89 + KEY_DOWN = 90 + KEY_RIGHT = 91 + KEY_F1 = 92 + KEY_F2 = 93 + KEY_F3 = 94 + KEY_F4 = 95 + KEY_F5 = 96 + KEY_F6 = 97 + KEY_F7 = 98 + KEY_F8 = 99 + KEY_F9 = 100 + KEY_F10 = 101 + KEY_F11 = 102 + KEY_F12 = 103 + KEY_CAPSLOCKTOGGLE = 104 + KEY_NUMLOCKTOGGLE = 105 + KEY_SCROLLLOCKTOGGLE = 106 + KEY_LAST = 106 + + MOUSE_FIRST = 107 + MOUSE_LEFT = 107 + MOUSE_RIGHT = 108 + MOUSE_MIDDLE = 109 + MOUSE_4 = 110 + MOUSE_5 = 111 + MOUSE_WHEEL_UP = 112 + MOUSE_WHEEL_DOWN = 113 + MOUSE_LAST = 113 + + JOYSTICK_FIRST = 114 + JOYSTICK_FIRST_BUTTON = 114 + JOYSTICK_LAST_BUTTON = 145 + JOYSTICK_FIRST_POV_BUTTON = 146 + JOYSTICK_LAST_POV_BUTTON = 149 + JOYSTICK_FIRST_AXIS_BUTTON = 150 + JOYSTICK_LAST_AXIS_BUTTON = 161 + JOYSTICK_LAST = 161 +} + +enum AnalogCode +{ + MOUSE_X = 0 + MOUSE_Y = 1 + MOUSE_XY = 2 + MOUSE_WHEEL = 3 + + JOYSTICK_FIRST_AXIS = 4 + JOYSTICK_LAST_AXIS = 9 +} + +enum CursorCode +{ + dc_none = 1 + dc_arrow = 2 + dc_ibeam = 3 + dc_hourglass = 4 + dc_waitarrow = 5 + dc_crosshair = 6 + dc_up = 7 + dc_sizenwse = 8 + dc_sizenesw = 9 + dc_sizewe = 10 + dc_sizens = 11 + dc_sizeall = 12 + dc_no = 13 + dc_hand = 14 + dc_blank = 15 +} + +enum Alignment +{ + northwest = 0 + north = 1 + northeast = 2 + west = 3 + center = 4 + east = 5 + southwest = 6 + south = 7 + southeast = 8 +} + +if ( __Documentation.RegisterHelp != dummy ) +{ + local RegEnum = function( e ) + { + local K = getconsttable()[e]; + __Documentation.RegisterEnumHelp( e, K.len(), "" ); + e += "."; + foreach ( s, v in K ) + { + __Documentation.RegisterConstHelp( e+s, v, "" ); + } + } + RegEnum( "ButtonCode" ); + RegEnum( "AnalogCode" ); + RegEnum( "CursorCode" ); + RegEnum( "Alignment" ); + + __Documentation.RegisterHelp( "ISurface::CreateFont", "void ISurface::CreateFont(string, handle)", "" ); + __Documentation.RegisterHelp( "IVGui::CreatePanel", "handle IVGui::CreatePanel(string, handle, string)", "" ); + __Documentation.RegisterHelp( "IVGui::GetRootPanel", "handle IVGui::GetRootPanel()", "" ); + __Documentation.RegisterHelp( "IVGui::GetClientDLLRootPanel", "handle IVGui::GetClientDLLRootPanel()", "" ); +} +)script"; diff --git a/game/client/message.cpp b/game/client/message.cpp index fe341e71..dc41bb00 100644 --- a/game/client/message.cpp +++ b/game/client/message.cpp @@ -862,6 +862,85 @@ void CHudMessage::MsgFunc_HudMsg(bf_read &msg) // see tmessage.cpp why 512 msg.ReadString( (char*)pNetMessage->pMessage, 512 ); +#ifdef MAPBASE + // + // Mapbase adds a new data entry for custom fonts on entities like game_text. + // Some existing instances of this user message may not have this, so we have to make sure we have any bits left first. + // + if (msg.GetNumBitsLeft() > 0) + { + // Try to have VGui font names for each channel + static char szVGuiFontNames[MAX_NETMESSAGE][512]; + msg.ReadString( szVGuiFontNames[channel], 512 ); + if (szVGuiFontNames[channel][0] != '\0') + { + pNetMessage->pVGuiSchemeFontName = szVGuiFontNames[channel]; + } + } + + // + // Mapbase adds a new data entry for breaking game_text into newline when it goes past the user's screen. + // Some existing instances of this user message may not have this, so we have to make sure we have any bits left first. + // + if (msg.GetNumBitsLeft() > 0) + { + int len = msg.ReadByte(); + + // This is supposed to work around a bug where certain aspect ratios cut off lengthy texts. + //int lineMax = 64 * ((float)ScreenWidth() / 1440.0f); + int lineMax = 100 / engine->GetScreenAspectRatio(); + + int lineMinBreak = lineMax * 0.9; + + CGMsg( 2, CON_GROUP_CHOREO, "Line max is %i from an aspect ratio of %.3f (strlen %i)\n", lineMax, engine->GetScreenAspectRatio(), len ); + + char *curMessage = (char*)pNetMessage->pMessage; + char newMessage[512]; + + int cur = 0; // Current time on this line + int i = 0; // curMessage + int i2 = 0; // newMessage + for (i = 0; i < len; i++) + { + cur++; + newMessage[i2] = curMessage[i]; + + // Check if we're past the point in which we should break the line + if (cur >= lineMinBreak) + { + // Line break at the next space + if (curMessage[i] == ' ') + { + newMessage[i2] = '\n'; + cur = 0; + } + else if (curMessage[i] == '\n') + { + // Already a newline here + cur = 0; + } + else if (cur >= lineMax) + { + // We're at the max and there's no space. Force a newline with a hyphen + newMessage[i2] = '-'; + i2++; + newMessage[i2] = '\n'; + i2++; + newMessage[i2] = curMessage[i]; + cur = 0; + } + } + + i2++; + } + + // Null terminate + newMessage[i2] = '\0'; + + Q_strncpy( (char*)pNetMessage->pMessage, newMessage, 512 ); + } +#endif + MessageAdd( pNetMessage->pName ); } diff --git a/game/client/particle_collision.cpp b/game/client/particle_collision.cpp index 5da0ac14..69cf5f51 100644 --- a/game/client/particle_collision.cpp +++ b/game/client/particle_collision.cpp @@ -294,7 +294,9 @@ void CParticleCollision::Setup( const Vector &origin, const Vector *dir, float a // timeDelta - time step //----------------------------------------------------------------------------- bool CParticleCollision::MoveParticle( Vector &origin, Vector &velocity, float *rollDelta, float timeDelta, trace_t *pTrace ) -{ +{ + pTrace->allsolid = false; // TE120 + //Don't bother with non-moving particles if ( velocity == vec3_origin ) return false; diff --git a/game/client/particlemgr.cpp b/game/client/particlemgr.cpp index 0eb09a43..d62c6e73 100644 --- a/game/client/particlemgr.cpp +++ b/game/client/particlemgr.cpp @@ -97,8 +97,8 @@ CParticleSubTextureGroup::~CParticleSubTextureGroup() CParticleSubTexture::CParticleSubTexture() { - m_tCoordMins[0] = m_tCoordMins[1] = 0; - m_tCoordMaxs[0] = m_tCoordMaxs[1] = 1; + m_tCoordMins[0] = m_tCoordMins[0] = 0; + m_tCoordMaxs[0] = m_tCoordMaxs[0] = 1; m_pGroup = &m_DefaultGroup; m_pMaterial = NULL; @@ -1540,15 +1540,12 @@ static ConVar r_threaded_particles( "r_threaded_particles", "1" ); static float s_flThreadedPSystemTimeStep; -static void ProcessPSystem( ParticleSimListEntry_t& pSimListEntry ) +static void ProcessPSystem( CNewParticleEffect *&pNewEffect ) { // Enable FP exceptions here when FP_EXCEPTIONS_ENABLED is defined, // to help track down bad math. FPExceptionEnabler enableExceptions; - CNewParticleEffect* pNewEffect = pSimListEntry.m_pNewParticleEffect; - bool updateBboxOnly = pSimListEntry.m_bBoundingBoxOnly; - // If this is a new effect, then update its bbox so it goes in the // right leaves (if it has particles). int bFirstUpdate = pNewEffect->GetNeedsBBoxUpdate(); @@ -1567,12 +1564,12 @@ static void ProcessPSystem( ParticleSimListEntry_t& pSimListEntry ) if ( pNewEffect->GetFirstFrameFlag() ) { - pNewEffect->Simulate( 0.0f, updateBboxOnly ); + pNewEffect->Simulate( 0.0f ); pNewEffect->SetFirstFrameFlag( false ); } else if ( pNewEffect->ShouldSimulate() ) { - pNewEffect->Simulate( s_flThreadedPSystemTimeStep, updateBboxOnly ); + pNewEffect->Simulate( s_flThreadedPSystemTimeStep ); } if ( pNewEffect->IsFinished() ) @@ -1687,7 +1684,7 @@ bool CParticleMgr::RetireParticleCollections( CParticleSystemDefinition* pDef, // Next, see if there are new particle systems that need early retirement static ConVar cl_particle_retire_cost( "cl_particle_retire_cost", "0", FCVAR_CHEAT ); -bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_t *ppEffects ) +bool CParticleMgr::EarlyRetireParticleSystems( int nCount, CNewParticleEffect **ppEffects ) { // NOTE: Doing a cheap and hacky estimate of worst-case fillrate const CViewSetup *pViewSetup = view->GetPlayerViewSetup(); @@ -1702,14 +1699,14 @@ bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_ CParticleSystemDefinition **ppDefs = (CParticleSystemDefinition**)stackalloc( nCount * sizeof(CParticleSystemDefinition*) ); for ( int i = 0; i < nCount; ++i ) { - CParticleSystemDefinition *pDef = ppEffects[i].m_pNewParticleEffect->m_pDef; + CParticleSystemDefinition *pDef = ppEffects[i]->m_pDef; // Skip stuff that doesn't have a cull radius set if ( pDef->GetCullRadius() == 0.0f ) continue; // Only perform the cull check on creation - if ( !ppEffects[i].m_pNewParticleEffect->GetFirstFrameFlag() ) + if ( !ppEffects[i]->GetFirstFrameFlag() ) continue; if ( pDef->HasRetirementBeenChecked( gpGlobals->framecount ) ) @@ -1717,7 +1714,7 @@ bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_ pDef->MarkRetirementCheck( gpGlobals->framecount ); - ppDefs[nDefCount++] = ppEffects[i].m_pNewParticleEffect->m_pDef; + ppDefs[nDefCount++] = ppEffects[i]->m_pDef; } if ( nDefCount == 0 ) @@ -1725,7 +1722,7 @@ bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_ for ( int i = 0; i < nCount; ++i ) { - ppEffects[i].m_pNewParticleEffect->MarkShouldPerformCullCheck( true ); + ppEffects[i]->MarkShouldPerformCullCheck( true ); } Vector vecCameraForward; @@ -1752,45 +1749,28 @@ bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_ for ( int i = 0; i < nCount; ++i ) { - ppEffects[i].m_pNewParticleEffect->MarkShouldPerformCullCheck( false ); + ppEffects[i]->MarkShouldPerformCullCheck( false ); } return bRetiredCollections; } static ConVar particle_sim_alt_cores( "particle_sim_alt_cores", "2" ); -void CParticleMgr::BuildParticleSimList( CUtlVector< ParticleSimListEntry_t > &list ) +void CParticleMgr::BuildParticleSimList( CUtlVector< CNewParticleEffect* > &list ) { float flNow = g_pParticleSystemMgr->GetLastSimulationTime(); for( CNewParticleEffect *pNewEffect=m_NewEffects.m_pHead; pNewEffect; pNewEffect=pNewEffect->m_pNext ) { - bool bSkip = false; - bool bNeedsBboxUpdate = false; - if ( flNow >= pNewEffect->m_flNextSleepTime && pNewEffect->m_nActiveParticles > 0 ) - bSkip = true; + continue; if ( pNewEffect->GetRemoveFlag() ) - bSkip = true; - - if ( !bSkip && g_bMeasureParticlePerformance ) + continue; + if ( g_bMeasureParticlePerformance ) { g_nNumParticlesSimulated += pNewEffect->m_nActiveParticles; } - - // Particles that are attached to moving things will need to update their bboxes even if they - // otherwise would like to skip the updates. Check that here. - if (bSkip) - { - bNeedsBboxUpdate = pNewEffect->HasMoved(); - bSkip = !bNeedsBboxUpdate; - } - - if (!bSkip) - { - ParticleSimListEntry_t entry = { pNewEffect, bNeedsBboxUpdate }; - list.AddToTail( entry ); - } + list.AddToTail( pNewEffect ); } } @@ -1832,27 +1812,23 @@ void CParticleMgr::UpdateNewEffects( float flTimeDelta ) int nParticleStatsTriggerCount = cl_particle_stats_trigger_count.GetInt(); BeginSimulateParticles(); + CUtlVector particlesToSimulate; + BuildParticleSimList( particlesToSimulate ); s_flThreadedPSystemTimeStep = flTimeDelta; + int nCount = particlesToSimulate.Count(); + // first, run non-reentrant part to get CP updates from entities - // This is done on all particles, because it updates control point locations which we need to determine whether or not we should - // do full simulation later. - for (CNewParticleEffect *pNewEffect = m_NewEffects.m_pHead; pNewEffect; - pNewEffect = pNewEffect->m_pNext) + for( int i=0; iUpdate( s_flThreadedPSystemTimeStep ); + particlesToSimulate[i]->Update( s_flThreadedPSystemTimeStep ); if ( nParticleStatsTriggerCount > 0 ) { - nParticleActiveParticlesCount += CountParticleSystemActiveParticles( pNewEffect ); + nParticleActiveParticlesCount += CountParticleSystemActiveParticles( particlesToSimulate[i] ); } } - CUtlVector particlesToSimulate; - BuildParticleSimList(particlesToSimulate); - int nCount = particlesToSimulate.Count(); - - // See if there are new particle systems that need early retirement // This has to happen after the first update if ( EarlyRetireParticleSystems( nCount, particlesToSimulate.Base() ) ) @@ -1885,7 +1861,7 @@ void CParticleMgr::UpdateNewEffects( float flTimeDelta ) { nAltCore = 2; } - CParallelProcessor > processor( "CParticleMgr::UpdateNewEffects" ); + CParallelProcessor > processor( "CParticleMgr::UpdateNewEffects" ); processor.m_ItemProcessor.Init( ProcessPSystem, NULL, NULL ); processor.Run( particlesToSimulate.Base(), nCount, INT_MAX, m_pThreadPool[nAltCore-1] ); } @@ -1896,7 +1872,7 @@ void CParticleMgr::UpdateNewEffects( float flTimeDelta ) for( int i=0; iDetectChanges(); + particlesToSimulate[i]->DetectChanges(); } EndSimulateParticles(); diff --git a/game/client/particlemgr.h b/game/client/particlemgr.h index d4537f35..ee86e515 100644 --- a/game/client/particlemgr.h +++ b/game/client/particlemgr.h @@ -119,7 +119,7 @@ entities. Each one is useful under different conditions. #include "tier0/fasttimer.h" #include "utllinkedlist.h" #include "utldict.h" -#ifdef WIN32 +#if defined(WIN32) && _MSC_VER < 1900 #include #else #include @@ -236,13 +236,6 @@ class CParticleSubTexture IMaterial *m_pMaterial; }; -// Particle simulation list, used to determine what particles to simulate and how. -struct ParticleSimListEntry_t -{ - CNewParticleEffect* m_pNewParticleEffect; - bool m_bBoundingBoxOnly; -}; - //----------------------------------------------------------------------------- // interface IParticleEffect: @@ -722,9 +715,8 @@ class CParticleMgr const CViewSetup& view, const VMatrix &worldToPixels, float flFocalDist ); bool RetireParticleCollections( CParticleSystemDefinition* pDef, int nCount, RetireInfo_t *pInfo, float flScreenArea, float flMaxTotalArea ); - - void BuildParticleSimList( CUtlVector< ParticleSimListEntry_t > &list ); - bool EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_t *ppEffects ); + void BuildParticleSimList( CUtlVector< CNewParticleEffect* > &list ); + bool EarlyRetireParticleSystems( int nCount, CNewParticleEffect **ppEffects ); static int RetireSort( const void *p1, const void *p2 ); private: diff --git a/game/client/particles_new.cpp b/game/client/particles_new.cpp index 647d304f..d3dc6599 100644 --- a/game/client/particles_new.cpp +++ b/game/client/particles_new.cpp @@ -65,8 +65,6 @@ void CNewParticleEffect::Construct() m_MaxBounds = Vector( -1.0e6, -1.0e6, -1.0e6 ); m_pDebugName = NULL; - m_bViewModelEffect = m_pDef ? m_pDef->IsViewModelEffect() : false; - if ( IsValid() && clienttools->IsInRecordingMode() ) { int nId = AllocateToolParticleEffectId(); diff --git a/game/client/particles_new.h b/game/client/particles_new.h index 06d98c9c..eb80f93a 100644 --- a/game/client/particles_new.h +++ b/game/client/particles_new.h @@ -91,9 +91,6 @@ class CNewParticleEffect : public IParticleEffect, public CParticleCollection, p void SetControlPointUpVector( int nWhichPoint, const Vector &v ); void SetControlPointRightVector( int nWhichPoint, const Vector &v ); - void SetIsViewModelEffect ( bool bIsViewModelEffect ) { m_bViewModelEffect = bIsViewModelEffect; } - bool GetIsViewModelEffect () { return m_bViewModelEffect; } - FORCEINLINE EHANDLE const &GetControlPointEntity( int nWhichPoint ) { return m_hControlPointOwners[ nWhichPoint ]; @@ -156,8 +153,6 @@ class CNewParticleEffect : public IParticleEffect, public CParticleCollection, p Vector m_LastMin; Vector m_LastMax; - bool m_bViewModelEffect; - private: // Update the reference count. void AddRef(); @@ -314,7 +309,7 @@ inline void CNewParticleEffect::MarkShouldPerformCullCheck( bool bEnable ) inline CSmartPtr CNewParticleEffect::Create( CBaseEntity *pOwner, const char *pParticleSystemName, const char *pDebugName ) { CNewParticleEffect *pRet = new CNewParticleEffect( pOwner, pParticleSystemName ); - pRet->m_pDebugName = pDebugName ? pDebugName : pParticleSystemName; + pRet->m_pDebugName = pDebugName; pRet->SetDynamicallyAllocated( true ); return pRet; } @@ -322,7 +317,7 @@ inline CSmartPtr CNewParticleEffect::Create( CBaseEntity *pO inline CSmartPtr CNewParticleEffect::Create( CBaseEntity *pOwner, CParticleSystemDefinition *pDef, const char *pDebugName ) { CNewParticleEffect *pRet = new CNewParticleEffect( pOwner, pDef ); - pRet->m_pDebugName = pDebugName ? pDebugName : pDef->GetName(); + pRet->m_pDebugName = pDebugName; pRet->SetDynamicallyAllocated( true ); return pRet; } diff --git a/game/client/particles_simple.cpp b/game/client/particles_simple.cpp index b2971dbb..20500b32 100644 --- a/game/client/particles_simple.cpp +++ b/game/client/particles_simple.cpp @@ -308,8 +308,12 @@ void CSimpleEmitter::UpdateVelocity( SimpleParticle *pParticle, float timeDelta { if (pParticle->m_iFlags & SIMPLE_PARTICLE_FLAG_WINDBLOWN) { +#ifdef MAPBASE + Vector vecWind = GetWindspeedAtLocation( pParticle->m_Pos ); +#else Vector vecWind; GetWindspeedAtTime( gpGlobals->curtime, vecWind ); +#endif for ( int i = 0 ; i < 2 ; i++ ) { diff --git a/game/client/physics_main_client.cpp b/game/client/physics_main_client.cpp index b1af5b23..ebc392e2 100644 --- a/game/client/physics_main_client.cpp +++ b/game/client/physics_main_client.cpp @@ -6,7 +6,7 @@ //=============================================================================// #include "cbase.h" #include "c_baseentity.h" -#ifdef WIN32 +#if defined(WIN32) && _MSC_VER < 1900 #include #endif #include "tier0/vprof.h" diff --git a/game/client/physpropclientside.cpp b/game/client/physpropclientside.cpp index 3dd2d7b5..3db90618 100644 --- a/game/client/physpropclientside.cpp +++ b/game/client/physpropclientside.cpp @@ -704,9 +704,157 @@ void C_PhysPropClientside::ParseAllEntities(const char *pMapData) } } +#ifdef MAPBASE +CBaseAnimating *BreakModelCreate_Ragdoll( CBaseEntity *pOwnerEnt, breakmodel_t *pModel, const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity ) +{ + C_BaseAnimating *pOwner = dynamic_cast( pOwnerEnt ); + if ( !pOwner ) + return NULL; + + C_ClientRagdoll *pRagdoll = new C_ClientRagdoll( false ); + if ( pRagdoll == NULL ) + return NULL; + + const char *pModelName = pModel->modelName; + if ( pRagdoll->InitializeAsClientEntity( pModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false ) + { + pRagdoll->Release(); + return NULL; + } + + pRagdoll->SetAbsOrigin( position ); + pRagdoll->SetAbsAngles( angles ); + + matrix3x4_t boneDelta0[MAXSTUDIOBONES]; + matrix3x4_t boneDelta1[MAXSTUDIOBONES]; + matrix3x4_t currentBones[MAXSTUDIOBONES]; + const float boneDt = 0.1f; + + pRagdoll->SetParent( pOwner ); + pRagdoll->ForceSetupBonesAtTime( boneDelta0, gpGlobals->curtime - boneDt ); + pRagdoll->ForceSetupBonesAtTime( boneDelta1, gpGlobals->curtime ); + pRagdoll->ForceSetupBonesAtTime( currentBones, gpGlobals->curtime ); + pRagdoll->SetParent( NULL ); + + // We need to take these from the entity + //pRagdoll->SetAbsOrigin( position ); + //pRagdoll->SetAbsAngles( angles ); + + pRagdoll->IgniteRagdoll( pOwner ); + pRagdoll->TransferDissolveFrom( pOwner ); + pRagdoll->InitModelEffects(); + + if ( pOwner->IsEffectActive( EF_NOSHADOW ) ) + { + pRagdoll->AddEffects( EF_NOSHADOW ); + } + + pRagdoll->m_nRenderFX = kRenderFxRagdoll; + pRagdoll->SetRenderMode( pOwner->GetRenderMode() ); + pRagdoll->SetRenderColor( pOwner->GetRenderColor().r, pOwner->GetRenderColor().g, pOwner->GetRenderColor().b, pOwner->GetRenderColor().a ); + //pRagdoll->SetGlobalFadeScale( pOwner->GetGlobalFadeScale() ); + + pRagdoll->SetSkin( pOwner->GetSkin() ); + //pRagdoll->m_vecForce = pOwner->m_vecForce; + //pRagdoll->m_nForceBone = 0; //pOwner->m_nForceBone; + pRagdoll->SetNextClientThink( CLIENT_THINK_ALWAYS ); + + pRagdoll->SetModelName( AllocPooledString( pModelName ) ); + pRagdoll->ResetSequence( 0 ); + pRagdoll->SetModelScale( pOwner->GetModelScale() ); + pRagdoll->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); + //pRagdoll->m_builtRagdoll = true; + + CStudioHdr *hdr = pRagdoll->GetModelPtr(); + if ( !hdr ) + { + pRagdoll->Release(); + Warning( "Couldn't create ragdoll gib for %s (no model pointer)\n", pModel->modelName ); + return NULL; + } + + pRagdoll->m_pRagdoll = CreateRagdoll( + pRagdoll, + hdr, + vec3_origin, + 0, + boneDelta0, + boneDelta1, + currentBones, + boneDt ); + + if ( !pRagdoll->m_pRagdoll ) + { + pRagdoll->Release(); + Warning( "Couldn't create ragdoll gib for %s\n", pModel->modelName ); + return NULL; + } + + IPhysicsObject *pPhysicsObject = pRagdoll->VPhysicsGetObject(); + if ( pPhysicsObject ) + { + // randomize velocity by 5% + float rndf = RandomFloat( -0.025, 0.025 ); + Vector rndVel = velocity + rndf*velocity; + + pPhysicsObject->AddVelocity( &rndVel, &angVelocity ); + } + pRagdoll->ApplyLocalAngularVelocityImpulse( angVelocity ); + + if ( pRagdoll->m_pRagdoll ) + { + pRagdoll->m_bImportant = false; + pRagdoll->m_flForcedRetireTime = pModel->fadeTime > 0.0f ? gpGlobals->curtime + pModel->fadeTime : 0.0f; + s_RagdollLRU.MoveToTopOfLRU( pRagdoll, pRagdoll->m_bImportant, pRagdoll->m_flForcedRetireTime ); + pRagdoll->m_bFadeOut = true; + } + + // Cause the entity to recompute its shadow type and make a + // version which only updates when physics state changes + // NOTE: We have to do this after m_pRagdoll is assigned above + // because that's what ShadowCastType uses to figure out which type of shadow to use. + pRagdoll->DestroyShadow(); + pRagdoll->CreateShadow(); + + pRagdoll->SetAbsOrigin( position ); + pRagdoll->SetAbsAngles( angles ); + + pRagdoll->SetPlaybackRate( 0 ); + pRagdoll->SetCycle( 0 ); + + // put into ACT_DIERAGDOLL if it exists, otherwise use sequence 0 + int nSequence = pRagdoll->SelectWeightedSequence( ACT_DIERAGDOLL ); + if ( nSequence < 0 ) + { + pRagdoll->ResetSequence( 0 ); + } + else + { + pRagdoll->ResetSequence( nSequence ); + } + + pRagdoll->UpdatePartitionListEntry(); + pRagdoll->MarkRenderHandleDirty(); + + NoteRagdollCreationTick( pRagdoll ); + + //pRagdoll->InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); + + return pRagdoll; +} +#endif + CBaseEntity *BreakModelCreateSingle( CBaseEntity *pOwner, breakmodel_t *pModel, const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, int nSkin, const breakablepropparams_t ¶ms ) { +#ifdef MAPBASE + if ( pModel->isRagdoll ) + { + CBaseEntity *pEntity = BreakModelCreate_Ragdoll( pOwner, pModel, position, angles, velocity, angVelocity ); + return pEntity; + } +#endif + C_PhysPropClientside *pEntity = C_PhysPropClientside::CreateNew(); if ( !pEntity ) @@ -778,10 +926,12 @@ CBaseEntity *BreakModelCreateSingle( CBaseEntity *pOwner, breakmodel_t *pModel, pEntity->SetFadeMinMax( pModel->fadeMinDist, pModel->fadeMaxDist ); } +#ifndef MAPBASE if ( pModel->isRagdoll ) { DevMsg( "BreakModelCreateSingle: clientside doesn't support ragdoll breakmodels.\n" ); } +#endif IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); diff --git a/game/client/prediction.cpp b/game/client/prediction.cpp index 2a67007b..d7dfbff7 100644 --- a/game/client/prediction.cpp +++ b/game/client/prediction.cpp @@ -30,6 +30,13 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +// This turned out to be causing major issues with VPhysics collision. +// It's deactivated until a fix is found. +// See player_command.cpp as well. +//#define PLAYER_COMMAND_FIX 1 +#endif + IPredictionSystem *IPredictionSystem::g_pPredictionSystems = NULL; #if !defined( NO_ENTITY_PREDICTION ) @@ -45,12 +52,6 @@ static ConVar cl_predictionentitydump( "cl_pdump", "-1", FCVAR_CHEAT, "Dump info static ConVar cl_predictionentitydumpbyclass( "cl_pclass", "", FCVAR_CHEAT, "Dump entity by prediction classname." ); static ConVar cl_pred_optimize( "cl_pred_optimize", "2", 0, "Optimize for not copying data if didn't receive a network update (1), and also for not repredicting if there were no errors (2)." ); -#ifdef STAGING_ONLY -// Do not ship this - testing a fix -static ConVar cl_pred_optimize_prefer_server_data( "cl_pred_optimize_prefer_server_data", "0", 0, "In the case where we have both server data and predicted data up to the same tick, choose server data over predicted data." ); -// -#endif // STAGING_ONLY - #endif extern IGameMovement *g_pGameMovement; @@ -909,9 +910,15 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper pVehicle->ProcessMovement( player, g_pMoveData ); } +#ifdef PLAYER_COMMAND_FIX + RunPostThink( player ); + + FinishMove( player, ucmd, g_pMoveData ); +#else FinishMove( player, ucmd, g_pMoveData ); RunPostThink( player ); +#endif g_pGameMovement->FinishTrackPredictionErrors( player ); @@ -1407,11 +1414,6 @@ int CPrediction::ComputeFirstCommandToExecute( bool received_new_world_update, i } else { -#ifdef STAGING_ONLY - int nPredictedLimit = cl_pred_optimize_prefer_server_data.GetBool() ? m_nCommandsPredicted - 1 : m_nCommandsPredicted; -#else - int nPredictedLimit = m_nCommandsPredicted; -#endif // STAGING_ONLY // Otherwise, there is a second optimization, wherein if we did receive an update, but no // values differed (or were outside their epsilon) and the server actually acknowledged running // one or more commands, then we can revert the entity to the predicted state from last frame, @@ -1420,7 +1422,7 @@ int CPrediction::ComputeFirstCommandToExecute( bool received_new_world_update, i if ( cl_pred_optimize.GetInt() >= 2 && !m_bPreviousAckHadErrors && m_nCommandsPredicted > 0 && - m_nServerCommandsAcknowledged <= nPredictedLimit ) + m_nServerCommandsAcknowledged <= m_nCommandsPredicted ) { // Copy all of the previously predicted data back into entity so we can skip repredicting it // This is the final slot that we previously predicted diff --git a/game/client/proxyplayer.cpp b/game/client/proxyplayer.cpp index d6521cc9..5fa7f1bc 100644 --- a/game/client/proxyplayer.cpp +++ b/game/client/proxyplayer.cpp @@ -12,6 +12,9 @@ #include "materialsystem/imaterialsystem.h" #include "functionproxy.h" #include "toolframework_client.h" +#ifdef MAPBASE +#include "view.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -521,4 +524,100 @@ void CPlayerLogoOnModelProxy::OnBind( void *pC_BaseEntity ) } EXPOSE_INTERFACE( CPlayerLogoOnModelProxy, IMaterialProxy, "PlayerLogoOnModel" IMATERIAL_PROXY_INTERFACE_VERSION ); -*/ \ No newline at end of file +*/ + + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Returns the proximity of the current view to the entity +//----------------------------------------------------------------------------- +class CViewProximityProxy : public CResultProxy +{ +public: + bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + void OnBind( void *pC_BaseEntity ); + +private: + float m_Factor; +}; + +bool CViewProximityProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) +{ + if (!CResultProxy::Init( pMaterial, pKeyValues )) + return false; + + m_Factor = pKeyValues->GetFloat( "scale", 0.002 ); + return true; +} + +void CViewProximityProxy::OnBind( void *pC_BaseEntity ) +{ + if (!pC_BaseEntity) + return; + + // Find the distance between the player and this entity.... + C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity ); + + Vector delta; + VectorSubtract( pEntity->WorldSpaceCenter(), CurrentViewOrigin(), delta ); + + Assert( m_pResult ); + SetFloatResult( delta.Length() * m_Factor ); + + if ( ToolsEnabled() ) + { + ToolFramework_RecordMaterialParams( GetMaterial() ); + } +} + +EXPOSE_INTERFACE( CViewProximityProxy, IMaterialProxy, "ViewProximity" IMATERIAL_PROXY_INTERFACE_VERSION ); + +//----------------------------------------------------------------------------- +// Returns the current view direction +//----------------------------------------------------------------------------- +class CViewDirectionProxy : public CResultProxy +{ +public: + bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + void OnBind( void *pC_BaseEntity ); + +private: + float m_Factor; +}; + +bool CViewDirectionProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) +{ + if (!CResultProxy::Init( pMaterial, pKeyValues )) + return false; + + m_Factor = pKeyValues->GetFloat( "scale", 2 ); + return true; +} + +void CViewDirectionProxy::OnBind( void *pC_BaseEntity ) +{ + if (!pC_BaseEntity) + return; + + // Find the view angle between the player and this entity.... + C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity ); + + Vector delta; + Vector forward; + + VectorSubtract( pEntity->WorldSpaceCenter(), CurrentViewOrigin(), delta ); + VectorNormalize( delta ); + + forward = CurrentViewForward(); + + Assert( m_pResult ); + SetFloatResult( DotProduct( forward, delta ) * m_Factor ); + + if ( ToolsEnabled() ) + { + ToolFramework_RecordMaterialParams( GetMaterial() ); + } +} + +EXPOSE_INTERFACE( CViewDirectionProxy, IMaterialProxy, "ViewDirection" IMATERIAL_PROXY_INTERFACE_VERSION ); +#endif diff --git a/game/client/ragdoll.cpp b/game/client/ragdoll.cpp index 3457b054..1e044a1d 100644 --- a/game/client/ragdoll.cpp +++ b/game/client/ragdoll.cpp @@ -69,6 +69,16 @@ BEGIN_SIMPLE_DATADESC( CRagdoll ) DEFINE_RAGDOLL_ELEMENT( 21 ), DEFINE_RAGDOLL_ELEMENT( 22 ), DEFINE_RAGDOLL_ELEMENT( 23 ), +#ifdef MAPBASE + DEFINE_RAGDOLL_ELEMENT( 24 ), + DEFINE_RAGDOLL_ELEMENT( 25 ), + DEFINE_RAGDOLL_ELEMENT( 26 ), + DEFINE_RAGDOLL_ELEMENT( 27 ), + DEFINE_RAGDOLL_ELEMENT( 28 ), + DEFINE_RAGDOLL_ELEMENT( 29 ), + DEFINE_RAGDOLL_ELEMENT( 30 ), + DEFINE_RAGDOLL_ELEMENT( 31 ), +#endif END_DATADESC() @@ -477,6 +487,9 @@ int C_ServerRagdoll::InternalDrawModel( int flags ) return ret; } +#ifdef MAPBASE +static ConVar g_ragdoll_server_snatch_instance( "g_ragdoll_server_snatch_instance", "1", FCVAR_NONE, "Allows serverside ragdolls to snatch their source entities' model instances in the same way clientside ragdolls do, thereby retaining decals." ); +#endif CStudioHdr *C_ServerRagdoll::OnNewModel( void ) { @@ -499,6 +512,26 @@ CStudioHdr *C_ServerRagdoll::OnNewModel( void ) m_iv_ragAngles.SetMaxCount( m_elementCount ); } +#ifdef MAPBASE + if ( GetOwnerEntity() ) + { + if (GetOwnerEntity()->GetModelName() == GetModelName()) + { + // TODO: Is there a better place for this? + if (GetOwnerEntity()->GetBaseAnimating()) + GetOwnerEntity()->GetBaseAnimating()->m_pServerRagdoll = this; + + if (g_ragdoll_server_snatch_instance.GetBool()) + { + GetOwnerEntity()->SnatchModelInstance( this ); + } + } + } + + // Add server ragdolls to the creation tick list + NoteRagdollCreationTick( this ); +#endif + return hdr; } diff --git a/game/client/rendertexture.cpp b/game/client/rendertexture.cpp index 08e8bfcf..78780e93 100644 --- a/game/client/rendertexture.cpp +++ b/game/client/rendertexture.cpp @@ -96,38 +96,6 @@ ITexture *GetFullFrameDepthTexture( void ) return s_pFullFrameDepthTexture; } -//============================================================================= -// Full Frame Depth Texture -//============================================================================= -static CTextureReference s_pFullFrameHDRTexture; -ITexture* GetFullFrameHDRTexture(void) -{ - if (!s_pFullFrameHDRTexture) - { - s_pFullFrameHDRTexture.Init(materials->FindTexture("_rt_VanceHDR", TEXTURE_GROUP_RENDER_TARGET)); - Assert(!IsErrorTexture(s_pFullFrameHDRTexture)); - AddReleaseFunc(); - } - - return s_pFullFrameHDRTexture; -} - -//============================================================================= -// Scope Texture -//============================================================================= -static CTextureReference s_pScopeTexture; -ITexture* GetScopeTexture(void) -{ - if (!s_pScopeTexture) - { - s_pScopeTexture.Init(materials->FindTexture("_rt_Scope", TEXTURE_GROUP_RENDER_TARGET)); - Assert(!IsErrorTexture(s_pScopeTexture)); - AddReleaseFunc(); - } - - return s_pScopeTexture; -} - //============================================================================= // Full Frame Buffer Textures //============================================================================= @@ -139,11 +107,11 @@ ITexture *GetFullFrameFrameBufferTexture( int textureIndex ) char name[256]; if( textureIndex != 0 ) { - V_sprintf_safe( name, "_rt_FullFrameFB%d", textureIndex ); + sprintf( name, "_rt_FullFrameFB%d", textureIndex ); } else { - V_strcpy_safe( name, "_rt_FullFrameFB" ); + Q_strcpy( name, "_rt_FullFrameFB" ); } s_pFullFrameFrameBufferTexture[textureIndex].Init( materials->FindTexture( name, TEXTURE_GROUP_RENDER_TARGET ) ); Assert( !IsErrorTexture( s_pFullFrameFrameBufferTexture[textureIndex] ) ); @@ -284,8 +252,6 @@ void ReleaseRenderTargets( void ) s_pQuarterSizedFB0.Shutdown(); s_pQuarterSizedFB1.Shutdown(); s_pFullFrameDepthTexture.Shutdown(); - s_pFullFrameHDRTexture.Shutdown(); - s_pScopeTexture.Shutdown(); for (int i=0; iGetInt( "killer_class" ); - V_strcpy_safe( m_szKillerName, pIn->GetString( "killer_name" ) ); + V_strcpy( m_szKillerName, pIn->GetString( "killer_name" ) ); // Make sure vector is clear Assert( GetKillCount() == 0 ); diff --git a/game/client/replay/vgui/replayperformanceeditor.cpp b/game/client/replay/vgui/replayperformanceeditor.cpp index be274ccb..99178f6e 100644 --- a/game/client/replay/vgui/replayperformanceeditor.cpp +++ b/game/client/replay/vgui/replayperformanceeditor.cpp @@ -576,7 +576,7 @@ class CCameraOptionsPanel : public EditablePanel BaseClass::PerformLayout(); int nWidth = XRES( 140 ); - int nMargins[2] = { (int)XRES( 5 ), (int)YRES( 5 ) }; + int nMargins[2] = { XRES( 5 ), YRES( 5 ) }; int nVBuf = YRES( 0 ); int nLastY = -1; int nY = nMargins[1]; @@ -1969,7 +1969,7 @@ void CReplayPerformanceEditorPanel::PerformLayout() dynamic_cast< CExLabel * >( m_pPlayerCellsPanel->FindChildByName( "RedLabel" ) ), dynamic_cast< CExLabel * >( m_pPlayerCellsPanel->FindChildByName( "BlueLabel" ) ) }; - int nMargins[2] = { (int)XRES( 5 ), (int)YRES( 2 ) }; + int nMargins[2] = { XRES( 5 ), YRES( 2 ) }; for ( int i = 0; i < 2; ++i ) { pRedBlueLabels[i]->SizeToContents(); diff --git a/game/client/sdk/sdk_hud_weaponselection.cpp b/game/client/sdk/sdk_hud_weaponselection.cpp index 77577471..63f04a87 100644 --- a/game/client/sdk/sdk_hud_weaponselection.cpp +++ b/game/client/sdk/sdk_hud_weaponselection.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -42,7 +42,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void SelectWeaponSlot( int iSlot ); virtual C_BaseCombatWeapon *GetSelectedWeapon( void ) - { + { return m_hSelectedWeapon; } @@ -57,7 +57,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void ApplySchemeSettings(vgui::IScheme *pScheme); virtual bool IsWeaponSelectable() - { + { if (IsInSelectionMode()) return true; @@ -70,8 +70,8 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel void FastWeaponSwitch( int iWeaponSlot ); - virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) - { + virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) + { m_hSelectedWeapon = pWeapon; } @@ -189,7 +189,7 @@ bool CHudWeaponSelection::ShouldDraw() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CHudWeaponSelection::LevelInit() { @@ -217,7 +217,7 @@ void CHudWeaponSelection::Paint() // interpolate the selected box size between the small box size and the large box size // interpolation has been removed since there is no weapon pickup animation anymore, so it's all at the largest size - float percentageDone = 1.0f; //min(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); + float percentageDone = 1.0f; //MIN(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); int largeBoxWide = m_flSmallBoxSize + ((m_flLargeBoxWide - m_flSmallBoxSize) * percentageDone); int largeBoxTall = m_flSmallBoxSize + ((m_flLargeBoxTall - m_flSmallBoxSize) * percentageDone); Color selectedColor; @@ -309,7 +309,7 @@ void CHudWeaponSelection::Paint() { for (wchar_t *pch = text; *pch != 0; pch++) { - if (*pch == '\n') + if (*pch == '\n') { // newline character, drop to the next line if (slen > maxslen) diff --git a/game/client/sixense/in_sixense.cpp b/game/client/sixense/in_sixense.cpp index c8f79ec7..e0f4ba39 100644 --- a/game/client/sixense/in_sixense.cpp +++ b/game/client/sixense/in_sixense.cpp @@ -2151,7 +2151,7 @@ void SixenseInput::SetPlayerHandPositions( CUserCmd *pCmd, float flFrametime ) // This 'slides' the hold origin if you pull the object back into the player float min_z_dist = sixense_hold_slide_z_min_dist.GetFloat(); - float xy_radius = sixense_hold_slide_xy_radius.GetFloat(); + float xy_radius = sixense_hold_slide_xy_radius.GetFloat();; if ( !m_bScalingLockedOneToOne && (Vector3( ss_right_pos[0], ss_right_pos[1], 0.0f ).length() < xy_radius) && (ss_right_pos[2] > min_z_dist) ) { diff --git a/game/client/spritemodel.cpp b/game/client/spritemodel.cpp index 09284865..018e918f 100644 --- a/game/client/spritemodel.cpp +++ b/game/client/spritemodel.cpp @@ -201,7 +201,7 @@ static void AdjustSubRect(CEngineSprite *pSprite, int frame, float *pfLeft, floa *pw = rc.right - rc.left; *ph = rc.bottom - rc.top; - f = 1.0 / (float)pSprite->GetWidth(); + f = 1.0 / (float)pSprite->GetWidth();; *pfLeft = ((float)rc.left + 0.5) * f; *pfRight = ((float)rc.right - 0.5) * f; @@ -415,14 +415,12 @@ IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame ) m_VideoMaterial->SetFrame( nFrame ); } + IMaterial *pMaterial = m_material[nRenderMode]; - if ( pMaterial ) + IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); + if ( pFrameVar ) { - IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); - if ( pFrameVar ) - { - pFrameVar->SetIntValue( nFrame ); - } + pFrameVar->SetIntValue( nFrame ); } return pMaterial; diff --git a/game/client/text_message.cpp b/game/client/text_message.cpp index 2251556b..33bef81f 100644 --- a/game/client/text_message.cpp +++ b/game/client/text_message.cpp @@ -121,7 +121,7 @@ char *CHudTextMessage::BufferedLocaliseTextString( const char *msg ) char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) { if ( !msg ) - return ""; + return (char*)""; // '#' character indicates this is a reference to a string in titles.txt, and not the string itself if ( msg[0] == '#' ) diff --git a/game/client/vance/IDeferredExt_client.cpp b/game/client/vance/IDeferredExt_client.cpp index e4cddba5..8bcce148 100644 --- a/game/client/vance/IDeferredExt_client.cpp +++ b/game/client/vance/IDeferredExt_client.cpp @@ -1,39 +1,39 @@ #include "cbase.h" #include "IDeferredExt.h" - +#include "shader_override.h" #include "tier0/memdbgon.h" -CSysModule *__g_pDeferredShaderModule = NULL; -static IDeferredExtension *__g_defExt = NULL; +CSysModule *g_pDeferredShaderModule = nullptr; +static IDeferredExtension *g_pDeferredExtension = nullptr; IDeferredExtension *GetDeferredExt() { - return __g_defExt; + return g_pDeferredExtension; } +CUtlString GetModulePath( const char *pszModuleName, const char *pszPathId ); + bool ConnectDeferredExt() { - char modulePath[MAX_PATH * 4]; - Q_snprintf(modulePath, sizeof(modulePath), "%s/bin/game_shader_dx9.dll", engine->GetGameDirectory()); - if (!Sys_LoadInterface(modulePath, DEFERRED_EXTENSION_VERSION, &__g_pDeferredShaderModule, reinterpret_cast(&__g_defExt))) - Warning("Unable to pull IDeferredExtension interface from game_shader_dx9.dll.\nPulling from stdshader_dx9.dll\n"); - else - return __g_defExt != NULL; + OverrideShaders(); + + CUtlString modulePath = GetModulePath( "game_shader", "GAMEBIN" ); - Q_snprintf(modulePath, sizeof(modulePath), "bin/stdshader_dx9.dll"); - if (!Sys_LoadInterface(modulePath, DEFERRED_EXTENSION_VERSION, &__g_pDeferredShaderModule, reinterpret_cast(&__g_defExt))) - Warning("Unable to pull IDeferredExtension interface from stdshader_dx9.dll.\n"); + if (!Sys_LoadInterface(modulePath, DEFERRED_EXTENSION_VERSION, &g_pDeferredShaderModule, reinterpret_cast(&g_pDeferredExtension))) + Warning("Unable to pull IDeferredExtension interface from game_shader_dx9.dll.\n"); + else + return g_pDeferredExtension != NULL; - return __g_defExt != NULL; + return g_pDeferredExtension != NULL; } void ShutdownDeferredExt() { - if (!__g_defExt) + if (!g_pDeferredExtension) return; //__g_defExt->CommitLightData_Common(NULL); - __g_defExt = NULL; + g_pDeferredExtension = NULL; - Sys_UnloadModule(__g_pDeferredShaderModule); + Sys_UnloadModule(g_pDeferredShaderModule); } \ No newline at end of file diff --git a/game/client/vance/c_env_global_light.cpp b/game/client/vance/c_env_global_light.cpp index 64646820..e9533aa4 100644 --- a/game/client/vance/c_env_global_light.cpp +++ b/game/client/vance/c_env_global_light.cpp @@ -6,24 +6,26 @@ //=============================================================================// #include "cbase.h" -#include "c_baseplayer.h" + #include "c_env_global_light.h" -#include "viewrender.h" -#include "renderparm.h" -#include "materialsystem/imesh.h" -#include "materialsystem/itexture.h" + +#include "c_baseplayer.h" #include "materialsystem/imaterial.h" -#include "materialsystem/imaterialvar.h" #include "materialsystem/imaterialsystem.h" +#include "materialsystem/imaterialvar.h" +#include "materialsystem/imesh.h" +#include "materialsystem/itexture.h" +#include "renderparm.h" +#include "viewrender.h" #include "vprof.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -C_GlobalLight* g_pCSMLight; +C_GlobalLight *g_pCSMLight; -static ConVar csm_enabled("r_csm", "1", 0, "0 = off, 1 = on/force"); -static ConVar r_csm_time("r_csm_time", "-1", 0, "-1 = use entity angles, everything else = force"); +static ConVar csm_enabled( "r_csm", "1", 0, "0 = off, 1 = on/force" ); +static ConVar r_csm_time( "r_csm_time", "-1", 0, "-1 = use entity angles, everything else = force" ); // Controls sun position according to time, month, and observer's latitude. // Sun position computation based on Earth's orbital elements: https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html @@ -46,21 +48,18 @@ class CSunController December }; - CSunController() - : m_latitude(50.0f) - , m_month(June) - , m_eclipticObliquity(DEG2RAD(23.4f)) - , m_delta(0.0f) + CSunController() : + m_latitude( 50.0f ), m_month( June ), m_eclipticObliquity( DEG2RAD( 23.4f ) ), m_delta( 0.0f ) { - m_northDir = { 1.0f, 0.0f, 0.0f }; + m_northDir = { 1.0f, 0.0f, 0.0f }; m_sunDir = { 0.0f, 0.0f, 1.0f }; - m_upDir = { 0.0f, 0.0f, 1.0f }; + m_upDir = { 0.0f, 0.0f, 1.0f }; } - void Update(float _time) + void Update( float _time ) { CalculateSunOrbit(); - UpdateSunPosition(_time - 12.0f); + UpdateSunPosition( _time - 12.0f ); } Vector m_northDir; @@ -74,31 +73,28 @@ class CSunController { float day = 30.0f * m_month + 15.0f; float lambda = 280.46f + 0.9856474f * day; - lambda = DEG2RAD(lambda); - m_delta = asin(sin(m_eclipticObliquity) * sin(lambda)); + lambda = DEG2RAD( lambda ); + m_delta = asin( sin( m_eclipticObliquity ) * sin( lambda ) ); } - void UpdateSunPosition(float _hour) + void UpdateSunPosition( float _hour ) { - const float latitude = DEG2RAD(m_latitude); + const float latitude = DEG2RAD( m_latitude ); const float hh = _hour * M_PI_F / 12.0f; const float azimuth = atan2f( - sin(hh) - , cos(hh) * sin(latitude) - tan(m_delta) * cos(latitude) - ); + sin( hh ), cos( hh ) * sin( latitude ) - tan( m_delta ) * cos( latitude ) ); const float altitude = asin( - sin(latitude) * sin(m_delta) + cos(latitude) * cos(m_delta) * cos(hh) - ); + sin( latitude ) * sin( m_delta ) + cos( latitude ) * cos( m_delta ) * cos( hh ) ); - const Quaternion rot0(m_upDir.x, m_upDir.y, m_upDir.z, -azimuth); + const Quaternion rot0( m_upDir.x, m_upDir.y, m_upDir.z, -azimuth ); Vector dir; - VectorRotate(m_northDir, rot0, dir); - const Vector uxd = CrossProduct(m_upDir, dir); + VectorRotate( m_northDir, rot0, dir ); + const Vector uxd = CrossProduct( m_upDir, dir ); - const Quaternion rot1(uxd.x, uxd.y, uxd.z, altitude); - VectorRotate(dir, rot1, m_sunDir); + const Quaternion rot1( uxd.x, uxd.y, uxd.z, altitude ); + VectorRotate( dir, rot1, m_sunDir ); } float m_eclipticObliquity; @@ -107,44 +103,37 @@ class CSunController CSunController g_sunControl; - -IMPLEMENT_CLIENTCLASS_DT(C_GlobalLight, DT_GlobalLight, CGlobalLight) -RecvPropVector(RECVINFO(m_shadowDirection)), -RecvPropBool(RECVINFO(m_bEnabled)), -RecvPropString(RECVINFO(m_TextureName)), -RecvPropVector(RECVINFO(m_LinearFloatLightColor)), -RecvPropVector(RECVINFO(m_LinearFloatAmbientColor)), -RecvPropFloat(RECVINFO(m_flColorTransitionTime)), -RecvPropFloat(RECVINFO(m_flSunDistance)), -RecvPropFloat(RECVINFO(m_flFOV)), -RecvPropFloat(RECVINFO(m_flNearZ)), -RecvPropFloat(RECVINFO(m_flNorthOffset)), -RecvPropBool(RECVINFO(m_bEnableShadows)), -RecvPropBool(RECVINFO(m_bEnableVolumetrics)), -RecvPropBool(RECVINFO(m_bEnableDynamicSky)), -RecvPropFloat(RECVINFO(m_flDayNightTimescale)), -RecvPropFloat(RECVINFO(m_fTime)), +IMPLEMENT_CLIENTCLASS_DT( C_GlobalLight, DT_GlobalLight, CGlobalLight ) + RecvPropVector( RECVINFO( m_shadowDirection ) ), + RecvPropBool( RECVINFO( m_bEnabled ) ), + RecvPropString( RECVINFO( m_TextureName ) ), + RecvPropVector( RECVINFO( m_LinearFloatLightColor ) ), + RecvPropVector( RECVINFO( m_LinearFloatAmbientColor ) ), + RecvPropFloat( RECVINFO( m_flColorTransitionTime ) ), + RecvPropFloat( RECVINFO( m_flSunDistance ) ), + RecvPropFloat( RECVINFO( m_flFOV ) ), + RecvPropFloat( RECVINFO( m_flNearZ ) ), + RecvPropFloat( RECVINFO( m_flNorthOffset ) ), + RecvPropBool( RECVINFO( m_bEnableShadows ) ), + RecvPropBool( RECVINFO( m_bEnableVolumetrics ) ), + RecvPropBool( RECVINFO( m_bEnableDynamicSky ) ), + RecvPropFloat( RECVINFO( m_flDayNightTimescale ) ), + RecvPropFloat( RECVINFO( m_fTime ) ), END_RECV_TABLE() -C_GlobalLight::C_GlobalLight() - : m_angSunAngles(vec3_angle) - , m_vecLight(vec3_origin) - , m_vecAmbient(vec3_origin) - , m_bCascadedShadowMappingEnabled(false) - , m_bEnableDynamicSky(false) - , m_flDayNightTimescale(1.0f) +C_GlobalLight::C_GlobalLight() : + m_angSunAngles( vec3_angle ), m_vecLight( vec3_origin ), m_vecAmbient( vec3_origin ), m_bCascadedShadowMappingEnabled( false ), m_bEnableDynamicSky( false ), m_flDayNightTimescale( 1.0f ) { } C_GlobalLight::~C_GlobalLight() { - if (g_pCSMLight == this) + if ( g_pCSMLight == this ) { g_pCSMLight = NULL; } } - bool C_GlobalLight::IsCascadedShadowMappingEnabled() const { const int iCSMCvarEnabled = csm_enabled.GetInt(); @@ -173,9 +162,9 @@ float C_GlobalLight::DayNightTimescale() const float C_GlobalLight::CurrentTime() const { - if (r_csm_time.GetFloat() < 0.0f) + if ( r_csm_time.GetFloat() < 0.0f ) { - if (m_fTime < 0.0f) + if ( m_fTime < 0.0f ) return gpGlobals->curtime * DayNightTimescale(); else return m_fTime; @@ -186,18 +175,18 @@ float C_GlobalLight::CurrentTime() const } } -void C_GlobalLight::OnDataChanged(DataUpdateType_t updateType) +void C_GlobalLight::OnDataChanged( DataUpdateType_t updateType ) { - if (updateType == DATA_UPDATE_CREATED) + if ( updateType == DATA_UPDATE_CREATED ) { - m_SpotlightTexture.Init(m_TextureName, TEXTURE_GROUP_OTHER, true); + m_SpotlightTexture.Init( m_TextureName, TEXTURE_GROUP_OTHER, true ); } - if (g_pCSMLight == NULL) + if ( g_pCSMLight == NULL ) { g_pCSMLight = this; } - BaseClass::OnDataChanged(updateType); + BaseClass::OnDataChanged( updateType ); } void C_GlobalLight::Spawn() @@ -206,7 +195,7 @@ void C_GlobalLight::Spawn() m_bOldEnableShadows = m_bEnableShadows; - SetNextClientThink(CLIENT_THINK_ALWAYS); + SetNextClientThink( CLIENT_THINK_ALWAYS ); } //------------------------------------------------------------------------------ @@ -219,7 +208,7 @@ bool C_GlobalLight::ShouldDraw() void C_GlobalLight::ClientThink() { - if (!m_bEnabled) + if ( !m_bEnabled ) { m_bCascadedShadowMappingEnabled = m_bEnabled; return; @@ -227,23 +216,23 @@ void C_GlobalLight::ClientThink() m_bCascadedShadowMappingEnabled = m_bEnabled; Vector vDirection = m_shadowDirection; - if (IsDynamicSkyEnabled()) + if ( IsDynamicSkyEnabled() ) { - if (UsesTimeForAngles()) + if ( UsesTimeForAngles() ) { - g_sunControl.Update(CurrentTime()); + g_sunControl.Update( CurrentTime() ); vDirection = g_sunControl.m_sunDir; } } - VectorNormalize(vDirection); + VectorNormalize( vDirection ); QAngle angAngles; - VectorAngles(vDirection, angAngles); + VectorAngles( vDirection, angAngles ); m_angSunAngles = angAngles; - m_vecLight = Vector(m_LinearFloatLightColor[0], m_LinearFloatLightColor[1], m_LinearFloatLightColor[2]); - m_vecAmbient = Vector(m_LinearFloatAmbientColor[0], m_LinearFloatAmbientColor[1], m_LinearFloatAmbientColor[2]); + m_vecLight = Vector( m_LinearFloatLightColor[0], m_LinearFloatLightColor[1], m_LinearFloatLightColor[2] ); + m_vecAmbient = Vector( m_LinearFloatAmbientColor[0], m_LinearFloatAmbientColor[1], m_LinearFloatAmbientColor[2] ); BaseClass::ClientThink(); } \ No newline at end of file diff --git a/game/client/vance/c_env_skydome.cpp b/game/client/vance/c_env_skydome.cpp index 5058efb6..39af194a 100644 --- a/game/client/vance/c_env_skydome.cpp +++ b/game/client/vance/c_env_skydome.cpp @@ -8,7 +8,7 @@ #include "rendertexture.h" #include "viewrender.h" #include "fmtstr.h" -#include "mathlib\mathlib.h" +#include "mathlib/mathlib.h" #include ConVarRef cl_sky_sunpos ("cl_sky_sunpos"); ConVarRef cl_sky_windspeed ("cl_sky_windspeed"); diff --git a/game/client/vance/c_light_manager.h b/game/client/vance/c_light_manager.h index 2b2e7af5..9ccac2ff 100644 --- a/game/client/vance/c_light_manager.h +++ b/game/client/vance/c_light_manager.h @@ -1,9 +1,11 @@ #ifndef C_LIGHT_MANAGER_H #define C_LIGHT_MANAGER_H +#include "cbase.h" #include "igamesystem.h" -#include "UtlVector.h" -#include "../../public/mathlib/vector4d.h" +#include "tier1/utlvector.h" +#include "mathlib/vector4d.h" +#include "view_shared.h" #define DEFLIGHT_SPOT_ZNEAR 8.0f #define DEFLIGHT_SPOT_RESOLUTION 1024 diff --git a/game/client/vance/c_weapon_stubs_vance.cpp b/game/client/vance/c_weapon_stubs_vance.cpp index 59b37cef..dc316056 100644 --- a/game/client/vance/c_weapon_stubs_vance.cpp +++ b/game/client/vance/c_weapon_stubs_vance.cpp @@ -7,11 +7,12 @@ #include "cbase.h" #include "c_weapon__stubs.h" #include "c_basehlcombatweapon.h" -#include "weapons/vance_baseweapon_shared.h" +#include "vance_baseweapon_shared.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#if 0 STUB_WEAPON_CLASS(cycler_weapon, WeaponCycler, C_BaseCombatWeapon); STUB_WEAPON_CLASS(weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon); @@ -33,8 +34,44 @@ STUB_WEAPON_CLASS(weapon_357, Weapon357, C_BaseVanceWeapon); STUB_WEAPON_CLASS(weapon_crossbow, WeaponCrossbow, C_BaseVanceWeapon); STUB_WEAPON_CLASS(weapon_hopwire, WeaponHopwire, C_BaseVanceWeapon); STUB_WEAPON_CLASS(weapon_ar2, WeaponAR2, C_VanceMachineGun); -STUB_WEAPON_CLASS(weapon_smg1, WeaponSMG1, C_VanceSelectFireMachineGun); +STUB_WEAPON_CLASS(weapon_smg1, WeaponSMG1, C_VanceMachineGun); STUB_WEAPON_CLASS(weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon); STUB_WEAPON_CLASS(weapon_socketwrench, WeaponSocketWrench, C_BaseVanceWeapon); STUB_WEAPON_CLASS(weapon_resistancegun, WeaponResistanceGun, C_BaseVanceWeapon); -STUB_WEAPON_CLASS(weapon_sniper, WeaponSniper, C_BaseVanceWeapon); \ No newline at end of file +STUB_WEAPON_CLASS(weapon_sniper, WeaponSniper, C_BaseVanceWeapon); +#else +STUB_WEAPON_CLASS( cycler_weapon, WeaponCycler, C_BaseCombatWeapon ); + +STUB_WEAPON_CLASS( weapon_binoculars, WeaponBinoculars, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_flaregun, Flaregun, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_annabelle, WeaponAnnabelle, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_gauss, WeaponGaussGun, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_cubemap, WeaponCubemap, C_BaseCombatWeapon ); +STUB_WEAPON_CLASS( weapon_alyxgun, WeaponAlyxGun, C_HLSelectFireMachineGun ); +STUB_WEAPON_CLASS( weapon_citizenpackage, WeaponCitizenPackage, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_citizensuitcase, WeaponCitizenSuitcase, C_WeaponCitizenPackage ); + +#ifndef HL2MP +STUB_WEAPON_CLASS( weapon_ar2, WeaponAR2, C_HLMachineGun ); +STUB_WEAPON_CLASS( weapon_frag, WeaponFrag, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_rpg, WeaponRPG, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_pistol, WeaponPistol, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun ); +STUB_WEAPON_CLASS( weapon_357, Weapon357, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_crossbow, WeaponCrossbow, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_slam, Weapon_SLAM, C_BaseHLCombatWeapon ); +STUB_WEAPON_CLASS( weapon_crowbar, WeaponCrowbar, C_BaseHLBludgeonWeapon ); +#ifdef HL2_EPISODIC +STUB_WEAPON_CLASS( weapon_hopwire, WeaponHopwire, C_BaseHLCombatWeapon ); +//STUB_WEAPON_CLASS( weapon_proto1, WeaponProto1, C_BaseHLCombatWeapon ); +#endif +#ifdef HL2_LOSTCOAST +STUB_WEAPON_CLASS( weapon_oldmanharpoon, WeaponOldManHarpoon, C_WeaponCitizenPackage ); +#endif +#endif + + + +#endif diff --git a/game/client/vance/deferred_material_passthru.h b/game/client/vance/deferred_material_passthru.h index 136f625e..3d3b6f35 100644 --- a/game/client/vance/deferred_material_passthru.h +++ b/game/client/vance/deferred_material_passthru.h @@ -1,6 +1,6 @@ -//====== Copyright Sandern Corporation, All rights reserved. ===========// +//====== Copyright � Sandern Corporation, All rights reserved. ===========// // -// Purpose: Implementation of IMaterialSystem interface which "passes tru" all +// Purpose: Implementation of IMaterialSystem interface which "passes tru" all // function calls to the real interface. Can be used to override // IMaterialSystem function calls (combined with engine->Mat_Stub). // @@ -9,7 +9,7 @@ #ifndef WARS_MATERIALSYSTEM_PASSTHRU_H #define WARS_MATERIALSYSTEM_PASSTHRU_H #ifdef _WIN32 -#pragma once + #pragma once #endif #include "materialsystem/imaterialsystem.h" @@ -23,354 +23,655 @@ class CPassThruMaterialSystem : public IMaterialSystem m_pBaseMaterialsPassThru = NULL; } - void InitPassThru(IMaterialSystem* pBaseMaterialsPassThru) + void InitPassThru( IMaterialSystem *pBaseMaterialsPassThru ) { m_pBaseMaterialsPassThru = pBaseMaterialsPassThru; } public: - virtual bool Connect(CreateInterfaceFn factory) { return m_pBaseMaterialsPassThru->Connect(factory); } - virtual void Disconnect() { return m_pBaseMaterialsPassThru->Disconnect(); } - virtual void* QueryInterface(const char* pInterfaceName) { return m_pBaseMaterialsPassThru->QueryInterface(pInterfaceName); } - virtual InitReturnVal_t Init() { return m_pBaseMaterialsPassThru->Init(); } - virtual void Shutdown() { m_pBaseMaterialsPassThru->Shutdown(); } - - virtual CreateInterfaceFn Init(char const* pShaderAPIDLL, - IMaterialProxyFactory* pMaterialProxyFactory, - CreateInterfaceFn fileSystemFactory, - CreateInterfaceFn cvarFactory = NULL) + virtual bool Connect( CreateInterfaceFn factory ) { - return m_pBaseMaterialsPassThru->Init(pShaderAPIDLL, pMaterialProxyFactory, fileSystemFactory, cvarFactory); + return m_pBaseMaterialsPassThru->Connect( factory ); + } + virtual void Disconnect() + { + return m_pBaseMaterialsPassThru->Disconnect(); + } + virtual void *QueryInterface( const char *pInterfaceName ) + { + return m_pBaseMaterialsPassThru->QueryInterface( pInterfaceName ); + } + virtual InitReturnVal_t Init() + { + return m_pBaseMaterialsPassThru->Init(); + } + virtual void Shutdown() + { + m_pBaseMaterialsPassThru->Shutdown(); } - virtual void SetShaderAPI(char const* pShaderAPIDLL) { m_pBaseMaterialsPassThru->SetShaderAPI(pShaderAPIDLL); } - - virtual void SetAdapter(int nAdapter, int nFlags) { m_pBaseMaterialsPassThru->SetAdapter(nAdapter, nFlags); } - - virtual void ModInit() { m_pBaseMaterialsPassThru->ModInit(); } - virtual void ModShutdown() { m_pBaseMaterialsPassThru->ModShutdown(); } - - virtual void SetThreadMode(MaterialThreadMode_t mode, int nServiceThread = -1) { m_pBaseMaterialsPassThru->SetThreadMode(mode, nServiceThread); } - virtual MaterialThreadMode_t GetThreadMode() { return m_pBaseMaterialsPassThru->GetThreadMode(); } - virtual void ExecuteQueued() { m_pBaseMaterialsPassThru->ExecuteQueued(); } - - virtual IMaterialSystemHardwareConfig* GetHardwareConfig(const char* pVersion, int* returnCode) { return m_pBaseMaterialsPassThru->GetHardwareConfig(pVersion, returnCode); } + virtual CreateInterfaceFn Init( char const *pShaderAPIDLL, IMaterialProxyFactory *pMaterialProxyFactory, CreateInterfaceFn fileSystemFactory, CreateInterfaceFn cvarFactory = NULL ) + { + return m_pBaseMaterialsPassThru->Init( pShaderAPIDLL, pMaterialProxyFactory, fileSystemFactory, cvarFactory ); + } - virtual bool UpdateConfig(bool bForceUpdate) { return m_pBaseMaterialsPassThru->UpdateConfig(bForceUpdate); } + virtual void SetShaderAPI( char const *pShaderAPIDLL ) + { + m_pBaseMaterialsPassThru->SetShaderAPI( pShaderAPIDLL ); + } - virtual bool OverrideConfig(const MaterialSystem_Config_t& config, bool bForceUpdate) { return m_pBaseMaterialsPassThru->OverrideConfig(config, bForceUpdate); } + virtual void SetAdapter( int nAdapter, int nFlags ) + { + m_pBaseMaterialsPassThru->SetAdapter( nAdapter, nFlags ); + } - virtual const MaterialSystem_Config_t& GetCurrentConfigForVideoCard() const { return m_pBaseMaterialsPassThru->GetCurrentConfigForVideoCard(); } + virtual void ModInit() + { + m_pBaseMaterialsPassThru->ModInit(); + } + virtual void ModShutdown() + { + m_pBaseMaterialsPassThru->ModShutdown(); + } - virtual bool GetRecommendedConfigurationInfo(int nDXLevel, KeyValues* pKeyValues) { return m_pBaseMaterialsPassThru->GetRecommendedConfigurationInfo(nDXLevel, pKeyValues); } + virtual void SetThreadMode( MaterialThreadMode_t mode, int nServiceThread = -1 ) + { + m_pBaseMaterialsPassThru->SetThreadMode( mode, nServiceThread ); + } + virtual MaterialThreadMode_t GetThreadMode() + { + return m_pBaseMaterialsPassThru->GetThreadMode(); + } + virtual void ExecuteQueued() + { + m_pBaseMaterialsPassThru->ExecuteQueued(); + } - virtual int GetDisplayAdapterCount() const { return m_pBaseMaterialsPassThru->GetDisplayAdapterCount(); } + virtual IMaterialSystemHardwareConfig *GetHardwareConfig( const char *pVersion, int *returnCode ) + { + return m_pBaseMaterialsPassThru->GetHardwareConfig( pVersion, returnCode ); + } - virtual int GetCurrentAdapter() const { return m_pBaseMaterialsPassThru->GetCurrentAdapter(); } + virtual bool UpdateConfig( bool bForceUpdate ) + { + return m_pBaseMaterialsPassThru->UpdateConfig( bForceUpdate ); + } - virtual void GetDisplayAdapterInfo(int adapter, MaterialAdapterInfo_t& info) const { m_pBaseMaterialsPassThru->GetDisplayAdapterInfo(adapter, info); } + virtual bool OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate ) + { + return m_pBaseMaterialsPassThru->OverrideConfig( config, bForceUpdate ); + } - virtual int GetModeCount(int adapter) const { return m_pBaseMaterialsPassThru->GetModeCount(adapter); } + virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const + { + return m_pBaseMaterialsPassThru->GetCurrentConfigForVideoCard(); + } - virtual void GetModeInfo(int adapter, int mode, MaterialVideoMode_t& info) const { m_pBaseMaterialsPassThru->GetModeInfo(adapter, mode, info); } + virtual bool GetRecommendedConfigurationInfo( int nDXLevel, KeyValues *pKeyValues ) + { + return m_pBaseMaterialsPassThru->GetRecommendedConfigurationInfo( nDXLevel, pKeyValues ); + } - virtual void AddModeChangeCallBack(ModeChangeCallbackFunc_t func) { m_pBaseMaterialsPassThru->AddModeChangeCallBack(func); } + virtual int GetDisplayAdapterCount() const + { + return m_pBaseMaterialsPassThru->GetDisplayAdapterCount(); + } - virtual void GetDisplayMode(MaterialVideoMode_t& mode) const { m_pBaseMaterialsPassThru->GetDisplayMode(mode); } + virtual int GetCurrentAdapter() const + { + return m_pBaseMaterialsPassThru->GetCurrentAdapter(); + } - virtual bool SetMode(void* hwnd, const MaterialSystem_Config_t& config) { return m_pBaseMaterialsPassThru->SetMode(hwnd, config); } + virtual void GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t &info ) const + { + m_pBaseMaterialsPassThru->GetDisplayAdapterInfo( adapter, info ); + } - virtual bool SupportsMSAAMode(int nMSAAMode) { return m_pBaseMaterialsPassThru->SupportsMSAAMode(nMSAAMode); } + virtual int GetModeCount( int adapter ) const + { + return m_pBaseMaterialsPassThru->GetModeCount( adapter ); + } - virtual const MaterialSystemHardwareIdentifier_t& GetVideoCardIdentifier(void) const { return m_pBaseMaterialsPassThru->GetVideoCardIdentifier(); } + virtual void GetModeInfo( int adapter, int mode, MaterialVideoMode_t &info ) const + { + m_pBaseMaterialsPassThru->GetModeInfo( adapter, mode, info ); + } - virtual void SpewDriverInfo() const { m_pBaseMaterialsPassThru->SpewDriverInfo(); } + virtual void AddModeChangeCallBack( ModeChangeCallbackFunc_t func ) + { + m_pBaseMaterialsPassThru->AddModeChangeCallBack( func ); + } - virtual void GetBackBufferDimensions(int& width, int& height) const { m_pBaseMaterialsPassThru->GetBackBufferDimensions(width, height); } - virtual ImageFormat GetBackBufferFormat() const { return m_pBaseMaterialsPassThru->GetBackBufferFormat(); } + virtual void GetDisplayMode( MaterialVideoMode_t &mode ) const + { + m_pBaseMaterialsPassThru->GetDisplayMode( mode ); + } - virtual bool SupportsHDRMode(HDRType_t nHDRModede) { return m_pBaseMaterialsPassThru->SupportsHDRMode(nHDRModede); } + virtual bool SetMode( void *hwnd, const MaterialSystem_Config_t &config ) + { + return m_pBaseMaterialsPassThru->SetMode( hwnd, config ); + } - virtual bool AddView(void* hwnd) { return m_pBaseMaterialsPassThru->AddView(hwnd); } - virtual void RemoveView(void* hwnd) { m_pBaseMaterialsPassThru->RemoveView(hwnd); } + virtual bool SupportsMSAAMode( int nMSAAMode ) + { + return m_pBaseMaterialsPassThru->SupportsMSAAMode( nMSAAMode ); + } - virtual void SetView(void* hwnd) { m_pBaseMaterialsPassThru->SetView(hwnd); } + virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const + { + return m_pBaseMaterialsPassThru->GetVideoCardIdentifier(); + } - virtual void BeginFrame(float frameTime) { m_pBaseMaterialsPassThru->BeginFrame(frameTime); } - virtual void EndFrame() { m_pBaseMaterialsPassThru->EndFrame(); } - virtual void Flush(bool flushHardware = false) { m_pBaseMaterialsPassThru->Flush(flushHardware); } + virtual void SpewDriverInfo() const + { + m_pBaseMaterialsPassThru->SpewDriverInfo(); + } - virtual void SwapBuffers() { m_pBaseMaterialsPassThru->SwapBuffers(); } + virtual void GetBackBufferDimensions( int &width, int &height ) const + { + m_pBaseMaterialsPassThru->GetBackBufferDimensions( width, height ); + } + virtual ImageFormat GetBackBufferFormat() const + { + return m_pBaseMaterialsPassThru->GetBackBufferFormat(); + } - virtual void EvictManagedResources() { m_pBaseMaterialsPassThru->EvictManagedResources(); } + virtual bool SupportsHDRMode( HDRType_t nHDRModede ) + { + return m_pBaseMaterialsPassThru->SupportsHDRMode( nHDRModede ); + } - virtual void ReleaseResources(void) { m_pBaseMaterialsPassThru->ReleaseResources(); } - virtual void ReacquireResources(void) { m_pBaseMaterialsPassThru->ReacquireResources(); } + virtual bool AddView( void *hwnd ) + { + return m_pBaseMaterialsPassThru->AddView( hwnd ); + } + virtual void RemoveView( void *hwnd ) + { + m_pBaseMaterialsPassThru->RemoveView( hwnd ); + } - virtual void AddReleaseFunc(MaterialBufferReleaseFunc_t func) { m_pBaseMaterialsPassThru->AddReleaseFunc(func); } - virtual void RemoveReleaseFunc(MaterialBufferReleaseFunc_t func) { m_pBaseMaterialsPassThru->RemoveReleaseFunc(func); } + virtual void SetView( void *hwnd ) + { + m_pBaseMaterialsPassThru->SetView( hwnd ); + } - virtual void AddRestoreFunc(MaterialBufferRestoreFunc_t func) { m_pBaseMaterialsPassThru->AddRestoreFunc(func); } - virtual void RemoveRestoreFunc(MaterialBufferRestoreFunc_t func) { m_pBaseMaterialsPassThru->RemoveRestoreFunc(func); } + virtual void BeginFrame( float frameTime ) + { + m_pBaseMaterialsPassThru->BeginFrame( frameTime ); + } + virtual void EndFrame() + { + m_pBaseMaterialsPassThru->EndFrame(); + } + virtual void Flush( bool flushHardware = false ) + { + m_pBaseMaterialsPassThru->Flush( flushHardware ); + } - virtual void ResetTempHWMemory(bool bExitingLevel = false) { m_pBaseMaterialsPassThru->ResetTempHWMemory(bExitingLevel); } + virtual void SwapBuffers() + { + m_pBaseMaterialsPassThru->SwapBuffers(); + } - virtual void HandleDeviceLost() { m_pBaseMaterialsPassThru->HandleDeviceLost(); } + virtual void EvictManagedResources() + { + m_pBaseMaterialsPassThru->EvictManagedResources(); + } - virtual int ShaderCount() const { return m_pBaseMaterialsPassThru->ShaderCount(); } - virtual int GetShaders(int nFirstShader, int nMaxCount, IShader** ppShaderList) const { return m_pBaseMaterialsPassThru->GetShaders(nFirstShader, nMaxCount, ppShaderList); } + virtual void ReleaseResources( void ) + { + m_pBaseMaterialsPassThru->ReleaseResources(); + } + virtual void ReacquireResources( void ) + { + m_pBaseMaterialsPassThru->ReacquireResources(); + } - virtual int ShaderFlagCount() const { return m_pBaseMaterialsPassThru->ShaderFlagCount(); } - virtual const char* ShaderFlagName(int nIndex) const { return m_pBaseMaterialsPassThru->ShaderFlagName(nIndex); } + virtual void AddReleaseFunc( MaterialBufferReleaseFunc_t func ) + { + m_pBaseMaterialsPassThru->AddReleaseFunc( func ); + } + virtual void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func ) + { + m_pBaseMaterialsPassThru->RemoveReleaseFunc( func ); + } - virtual void GetShaderFallback(const char* pShaderName, char* pFallbackShader, int nFallbackLength) { m_pBaseMaterialsPassThru->GetShaderFallback(pShaderName, pFallbackShader, nFallbackLength); } + virtual void AddRestoreFunc( MaterialBufferRestoreFunc_t func ) + { + m_pBaseMaterialsPassThru->AddRestoreFunc( func ); + } + virtual void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func ) + { + m_pBaseMaterialsPassThru->RemoveRestoreFunc( func ); + } - virtual IMaterialProxyFactory* GetMaterialProxyFactory() { return m_pBaseMaterialsPassThru->GetMaterialProxyFactory(); } + virtual void ResetTempHWMemory( bool bExitingLevel = false ) + { + m_pBaseMaterialsPassThru->ResetTempHWMemory( bExitingLevel ); + } - virtual void SetMaterialProxyFactory(IMaterialProxyFactory* pFactory) { m_pBaseMaterialsPassThru->SetMaterialProxyFactory(pFactory); } + virtual void HandleDeviceLost() + { + m_pBaseMaterialsPassThru->HandleDeviceLost(); + } - virtual void EnableEditorMaterials() { m_pBaseMaterialsPassThru->EnableEditorMaterials(); } + virtual int ShaderCount() const + { + return m_pBaseMaterialsPassThru->ShaderCount(); + } + virtual int GetShaders( int nFirstShader, int nMaxCount, IShader **ppShaderList ) const + { + return m_pBaseMaterialsPassThru->GetShaders( nFirstShader, nMaxCount, ppShaderList ); + } - virtual void SetInStubMode(bool bInStubMode) { m_pBaseMaterialsPassThru->SetInStubMode(bInStubMode); } + virtual int ShaderFlagCount() const + { + return m_pBaseMaterialsPassThru->ShaderFlagCount(); + } + virtual const char *ShaderFlagName( int nIndex ) const + { + return m_pBaseMaterialsPassThru->ShaderFlagName( nIndex ); + } - virtual void DebugPrintUsedMaterials(const char* pSearchSubString, bool bVerbose) { m_pBaseMaterialsPassThru->DebugPrintUsedMaterials(pSearchSubString, bVerbose); } - virtual void DebugPrintUsedTextures(void) { m_pBaseMaterialsPassThru->DebugPrintUsedTextures(); } + virtual void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength ) + { + m_pBaseMaterialsPassThru->GetShaderFallback( pShaderName, pFallbackShader, nFallbackLength ); + } - virtual void ToggleSuppressMaterial(char const* pMaterialName) { m_pBaseMaterialsPassThru->ToggleSuppressMaterial(pMaterialName); } - virtual void ToggleDebugMaterial(char const* pMaterialName) { m_pBaseMaterialsPassThru->ToggleDebugMaterial(pMaterialName); } + virtual IMaterialProxyFactory *GetMaterialProxyFactory() + { + return m_pBaseMaterialsPassThru->GetMaterialProxyFactory(); + } - virtual bool UsingFastClipping(void) { return m_pBaseMaterialsPassThru->UsingFastClipping(); } + virtual void SetMaterialProxyFactory( IMaterialProxyFactory *pFactory ) + { + m_pBaseMaterialsPassThru->SetMaterialProxyFactory( pFactory ); + } - virtual int StencilBufferBits(void) { return m_pBaseMaterialsPassThru->StencilBufferBits(); } + virtual void EnableEditorMaterials() + { + m_pBaseMaterialsPassThru->EnableEditorMaterials(); + } - virtual void UncacheAllMaterials() { m_pBaseMaterialsPassThru->UncacheAllMaterials(); } + virtual void SetInStubMode( bool bInStubMode ) + { + m_pBaseMaterialsPassThru->SetInStubMode( bInStubMode ); + } - virtual void UncacheUnusedMaterials(bool bRecomputeStateSnapshots = false) { m_pBaseMaterialsPassThru->UncacheUnusedMaterials(bRecomputeStateSnapshots); } + virtual void DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose ) + { + m_pBaseMaterialsPassThru->DebugPrintUsedMaterials( pSearchSubString, bVerbose ); + } + virtual void DebugPrintUsedTextures( void ) + { + m_pBaseMaterialsPassThru->DebugPrintUsedTextures(); + } + virtual void ToggleSuppressMaterial( char const *pMaterialName ) + { + m_pBaseMaterialsPassThru->ToggleSuppressMaterial( pMaterialName ); + } + virtual void ToggleDebugMaterial( char const *pMaterialName ) + { + m_pBaseMaterialsPassThru->ToggleDebugMaterial( pMaterialName ); + } - virtual void CacheUsedMaterials() { m_pBaseMaterialsPassThru->CacheUsedMaterials(); } + virtual bool UsingFastClipping( void ) + { + return m_pBaseMaterialsPassThru->UsingFastClipping(); + } - virtual void ReloadTextures() { m_pBaseMaterialsPassThru->ReloadTextures(); } + virtual int StencilBufferBits( void ) + { + return m_pBaseMaterialsPassThru->StencilBufferBits(); + } - virtual void ReloadMaterials(const char* pSubString = NULL) { m_pBaseMaterialsPassThru->ReloadMaterials(pSubString); } + virtual void UncacheAllMaterials() + { + m_pBaseMaterialsPassThru->UncacheAllMaterials(); + } - virtual IMaterial* CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues) { return m_pBaseMaterialsPassThru->CreateMaterial(pMaterialName, pVMTKeyValues); } + virtual void UncacheUnusedMaterials( bool bRecomputeStateSnapshots = false ) + { + m_pBaseMaterialsPassThru->UncacheUnusedMaterials( bRecomputeStateSnapshots ); + } - virtual IMaterial* FindMaterial(char const* pMaterialName, const char* pTextureGroupName, bool complain = true, const char* pComplainPrefix = NULL) + virtual void CacheUsedMaterials() { - return m_pBaseMaterialsPassThru->FindMaterial(pMaterialName, pTextureGroupName, complain, pComplainPrefix); + m_pBaseMaterialsPassThru->CacheUsedMaterials(); } - virtual MaterialHandle_t FirstMaterial() const { return m_pBaseMaterialsPassThru->FirstMaterial(); } + virtual void ReloadTextures() + { + m_pBaseMaterialsPassThru->ReloadTextures(); + } - virtual MaterialHandle_t NextMaterial(MaterialHandle_t h) const { return m_pBaseMaterialsPassThru->NextMaterial(h); } + virtual void ReloadMaterials( const char *pSubString = NULL ) + { + m_pBaseMaterialsPassThru->ReloadMaterials( pSubString ); + } - virtual MaterialHandle_t InvalidMaterial() const { return m_pBaseMaterialsPassThru->InvalidMaterial(); } + virtual IMaterial *CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) + { + return m_pBaseMaterialsPassThru->CreateMaterial( pMaterialName, pVMTKeyValues ); + } - virtual IMaterial* GetMaterial(MaterialHandle_t h) const { return m_pBaseMaterialsPassThru->GetMaterial(h); } + virtual IMaterial *FindMaterial( char const *pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) + { + return m_pBaseMaterialsPassThru->FindMaterial( pMaterialName, pTextureGroupName, complain, pComplainPrefix ); + } - virtual int GetNumMaterials() const { return m_pBaseMaterialsPassThru->GetNumMaterials(); } + virtual MaterialHandle_t FirstMaterial() const + { + return m_pBaseMaterialsPassThru->FirstMaterial(); + } - virtual ITexture* FindTexture(char const* pTextureName, const char* pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0) { return m_pBaseMaterialsPassThru->FindTexture(pTextureName, pTextureGroupName, complain, nAdditionalCreationFlags); } + virtual MaterialHandle_t NextMaterial( MaterialHandle_t h ) const + { + return m_pBaseMaterialsPassThru->NextMaterial( h ); + } - virtual bool IsTextureLoaded(char const* pTextureName) const { return m_pBaseMaterialsPassThru->IsTextureLoaded(pTextureName); } + virtual MaterialHandle_t InvalidMaterial() const + { + return m_pBaseMaterialsPassThru->InvalidMaterial(); + } - virtual ITexture* CreateProceduralTexture(const char* pTextureName, - const char* pTextureGroupName, - int w, - int h, - ImageFormat fmt, - int nFlags) + virtual IMaterial *GetMaterial( MaterialHandle_t h ) const { - return m_pBaseMaterialsPassThru->CreateProceduralTexture(pTextureName, pTextureGroupName, w, h, fmt, nFlags); + return m_pBaseMaterialsPassThru->GetMaterial( h ); } - virtual void BeginRenderTargetAllocation() { return m_pBaseMaterialsPassThru->BeginRenderTargetAllocation(); } - virtual void EndRenderTargetAllocation() { return m_pBaseMaterialsPassThru->EndRenderTargetAllocation(); } + virtual int GetNumMaterials() const + { + return m_pBaseMaterialsPassThru->GetNumMaterials(); + } - virtual ITexture* CreateRenderTargetTexture(int w, - int h, - RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED) + virtual ITexture *FindTexture( char const *pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0 ) { - return m_pBaseMaterialsPassThru->CreateRenderTargetTexture(w, h, sizeMode, format, depth); + return m_pBaseMaterialsPassThru->FindTexture( pTextureName, pTextureGroupName, complain, nAdditionalCreationFlags ); } - virtual ITexture* CreateNamedRenderTargetTextureEx(const char* pRTName, // Pass in NULL here for an unnamed render target. - int w, - int h, - RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, - unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, - unsigned int renderTargetFlags = 0) + virtual bool IsTextureLoaded( char const *pTextureName ) const { - return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTextureEx(pRTName, w, h, sizeMode, format, depth, textureFlags, renderTargetFlags); + return m_pBaseMaterialsPassThru->IsTextureLoaded( pTextureName ); } - virtual ITexture* CreateNamedRenderTargetTexture(const char* pRTName, - int w, - int h, - RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, - bool bClampTexCoords = true, - bool bAutoMipMap = false) + virtual ITexture *CreateProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ) { - return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTexture(pRTName, w, h, sizeMode, format, depth, bClampTexCoords, bAutoMipMap); + return m_pBaseMaterialsPassThru->CreateProceduralTexture( pTextureName, pTextureGroupName, w, h, fmt, nFlags ); } - virtual ITexture* CreateNamedRenderTargetTextureEx2(const char* pRTName, // Pass in NULL here for an unnamed render target. - int w, - int h, - RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, - unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, - unsigned int renderTargetFlags = 0) + virtual void BeginRenderTargetAllocation() { - return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTextureEx2(pRTName, w, h, sizeMode, format, depth, textureFlags, renderTargetFlags); + return m_pBaseMaterialsPassThru->BeginRenderTargetAllocation(); + } + virtual void EndRenderTargetAllocation() + { + return m_pBaseMaterialsPassThru->EndRenderTargetAllocation(); } - virtual void BeginLightmapAllocation() { m_pBaseMaterialsPassThru->BeginLightmapAllocation(); } - virtual void EndLightmapAllocation() { m_pBaseMaterialsPassThru->EndLightmapAllocation(); } + virtual ITexture *CreateRenderTargetTexture( int w, int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED ) + { + return m_pBaseMaterialsPassThru->CreateRenderTargetTexture( w, h, sizeMode, format, depth ); + } - virtual int AllocateLightmap(int width, int height, - int offsetIntoLightmapPage[2], - IMaterial* pMaterial) + virtual ITexture *CreateNamedRenderTargetTextureEx( const char *pRTName, // Pass in NULL here for an unnamed render target. + int w, int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ) { - return m_pBaseMaterialsPassThru->AllocateLightmap(width, height, offsetIntoLightmapPage, pMaterial); + return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTextureEx( pRTName, w, h, sizeMode, format, depth, textureFlags, renderTargetFlags ); } - virtual int AllocateWhiteLightmap(IMaterial* pMaterial) { return m_pBaseMaterialsPassThru->AllocateWhiteLightmap(pMaterial); } - virtual void UpdateLightmap(int lightmapPageID, int lightmapSize[2], - int offsetIntoLightmapPage[2], - float* pFloatImage, float* pFloatImageBump1, - float* pFloatImageBump2, float* pFloatImageBump3) + virtual ITexture *CreateNamedRenderTargetTexture( const char *pRTName, int w, int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, bool bClampTexCoords = true, bool bAutoMipMap = false ) { - m_pBaseMaterialsPassThru->UpdateLightmap(lightmapPageID, lightmapSize, offsetIntoLightmapPage, pFloatImage, pFloatImageBump1, pFloatImageBump2, pFloatImageBump3); + return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTexture( pRTName, w, h, sizeMode, format, depth, bClampTexCoords, bAutoMipMap ); } - virtual int GetNumSortIDs() { return m_pBaseMaterialsPassThru->GetNumSortIDs(); } - virtual void GetSortInfo(MaterialSystem_SortInfo_t* sortInfoArray) { m_pBaseMaterialsPassThru->GetSortInfo(sortInfoArray); } + virtual ITexture *CreateNamedRenderTargetTextureEx2( const char *pRTName, // Pass in NULL here for an unnamed render target. + int w, int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ) + { + return m_pBaseMaterialsPassThru->CreateNamedRenderTargetTextureEx2( pRTName, w, h, sizeMode, format, depth, textureFlags, renderTargetFlags ); + } - virtual void GetLightmapPageSize(int lightmap, int* width, int* height) const { m_pBaseMaterialsPassThru->GetLightmapPageSize(lightmap, width, height); } + virtual void BeginLightmapAllocation() + { + m_pBaseMaterialsPassThru->BeginLightmapAllocation(); + } + virtual void EndLightmapAllocation() + { + m_pBaseMaterialsPassThru->EndLightmapAllocation(); + } - virtual void ResetMaterialLightmapPageInfo() { m_pBaseMaterialsPassThru->ResetMaterialLightmapPageInfo(); } + virtual int AllocateLightmap( int width, int height, int offsetIntoLightmapPage[2], IMaterial *pMaterial ) + { + return m_pBaseMaterialsPassThru->AllocateLightmap( width, height, offsetIntoLightmapPage, pMaterial ); + } + virtual int AllocateWhiteLightmap( IMaterial *pMaterial ) + { + return m_pBaseMaterialsPassThru->AllocateWhiteLightmap( pMaterial ); + } - virtual void ClearBuffers(bool bClearColor, bool bClearDepth, bool bClearStencil = false) { m_pBaseMaterialsPassThru->ClearBuffers(bClearColor, bClearDepth, bClearStencil); } + virtual void UpdateLightmap( int lightmapPageID, int lightmapSize[2], int offsetIntoLightmapPage[2], float *pFloatImage, float *pFloatImageBump1, float *pFloatImageBump2, float *pFloatImageBump3 ) + { + m_pBaseMaterialsPassThru->UpdateLightmap( lightmapPageID, lightmapSize, offsetIntoLightmapPage, pFloatImage, pFloatImageBump1, pFloatImageBump2, pFloatImageBump3 ); + } - virtual IMatRenderContext* GetRenderContext() { return m_pBaseMaterialsPassThru->GetRenderContext(); } + virtual int GetNumSortIDs() + { + return m_pBaseMaterialsPassThru->GetNumSortIDs(); + } + virtual void GetSortInfo( MaterialSystem_SortInfo_t *sortInfoArray ) + { + m_pBaseMaterialsPassThru->GetSortInfo( sortInfoArray ); + } - virtual void BeginUpdateLightmaps(void) { m_pBaseMaterialsPassThru->BeginUpdateLightmaps(); } - virtual void EndUpdateLightmaps(void) { m_pBaseMaterialsPassThru->EndUpdateLightmaps(); } + virtual void GetLightmapPageSize( int lightmap, int *width, int *height ) const + { + m_pBaseMaterialsPassThru->GetLightmapPageSize( lightmap, width, height ); + } - virtual MaterialLock_t Lock() { return m_pBaseMaterialsPassThru->Lock(); } - virtual void Unlock(MaterialLock_t l) { return m_pBaseMaterialsPassThru->Unlock(l); } + virtual void ResetMaterialLightmapPageInfo() + { + m_pBaseMaterialsPassThru->ResetMaterialLightmapPageInfo(); + } - virtual IMatRenderContext* CreateRenderContext(MaterialContextType_t type) { return m_pBaseMaterialsPassThru->CreateRenderContext(type); } + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) + { + m_pBaseMaterialsPassThru->ClearBuffers( bClearColor, bClearDepth, bClearStencil ); + } - virtual IMatRenderContext* SetRenderContext(IMatRenderContext* c) { return m_pBaseMaterialsPassThru->SetRenderContext(c); } + virtual IMatRenderContext *GetRenderContext() + { + return m_pBaseMaterialsPassThru->GetRenderContext(); + } - virtual bool SupportsCSAAMode(int nNumSamples, int nQualityLevel) { return m_pBaseMaterialsPassThru->SupportsCSAAMode(nNumSamples, nQualityLevel); } + virtual void BeginUpdateLightmaps( void ) + { + m_pBaseMaterialsPassThru->BeginUpdateLightmaps(); + } + virtual void EndUpdateLightmaps( void ) + { + m_pBaseMaterialsPassThru->EndUpdateLightmaps(); + } - virtual void RemoveModeChangeCallBack(ModeChangeCallbackFunc_t func) { m_pBaseMaterialsPassThru->RemoveModeChangeCallBack(func); } + virtual MaterialLock_t Lock() + { + return m_pBaseMaterialsPassThru->Lock(); + } + virtual void Unlock( MaterialLock_t l ) + { + return m_pBaseMaterialsPassThru->Unlock( l ); + } - virtual IMaterial* FindProceduralMaterial(const char* pMaterialName, const char* pTextureGroupName, KeyValues* pVMTKeyValues) + virtual IMatRenderContext *CreateRenderContext( MaterialContextType_t type ) { - return m_pBaseMaterialsPassThru->FindProceduralMaterial(pMaterialName, pTextureGroupName, pVMTKeyValues); + return m_pBaseMaterialsPassThru->CreateRenderContext( type ); } - virtual void AddTextureAlias(const char* pAlias, const char* pRealName) { m_pBaseMaterialsPassThru->AddTextureAlias(pAlias, pRealName); } - virtual void RemoveTextureAlias(const char* pAlias) { m_pBaseMaterialsPassThru->RemoveTextureAlias(pAlias); } + virtual IMatRenderContext *SetRenderContext( IMatRenderContext *c ) + { + return m_pBaseMaterialsPassThru->SetRenderContext( c ); + } - virtual int AllocateDynamicLightmap(int lightmapSize[2], int* pOutOffsetIntoPage, int frameID) + virtual bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) { - return m_pBaseMaterialsPassThru->AllocateDynamicLightmap(lightmapSize, pOutOffsetIntoPage, frameID); + return m_pBaseMaterialsPassThru->SupportsCSAAMode( nNumSamples, nQualityLevel ); } - virtual void SetExcludedTextures(const char* pScriptName) { m_pBaseMaterialsPassThru->SetExcludedTextures(pScriptName); } - virtual void UpdateExcludedTextures(void) { m_pBaseMaterialsPassThru->UpdateExcludedTextures(); } + virtual void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func ) + { + m_pBaseMaterialsPassThru->RemoveModeChangeCallBack( func ); + } - virtual bool IsInFrame() const { return m_pBaseMaterialsPassThru->IsInFrame(); } + virtual IMaterial *FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) + { + return m_pBaseMaterialsPassThru->FindProceduralMaterial( pMaterialName, pTextureGroupName, pVMTKeyValues ); + } - virtual void CompactMemory() { m_pBaseMaterialsPassThru->CompactMemory(); } + virtual void AddTextureAlias( const char *pAlias, const char *pRealName ) + { + m_pBaseMaterialsPassThru->AddTextureAlias( pAlias, pRealName ); + } + virtual void RemoveTextureAlias( const char *pAlias ) + { + m_pBaseMaterialsPassThru->RemoveTextureAlias( pAlias ); + } - virtual void ReloadFilesInList(IFileList* pFilesToReload) { m_pBaseMaterialsPassThru->ReloadFilesInList(pFilesToReload); } + virtual int AllocateDynamicLightmap( int lightmapSize[2], int *pOutOffsetIntoPage, int frameID ) + { + return m_pBaseMaterialsPassThru->AllocateDynamicLightmap( lightmapSize, pOutOffsetIntoPage, frameID ); + } - virtual bool AllowThreading(bool bAllow, int nServiceThread) { return m_pBaseMaterialsPassThru->AllowThreading(bAllow, nServiceThread); } + virtual void SetExcludedTextures( const char *pScriptName ) + { + m_pBaseMaterialsPassThru->SetExcludedTextures( pScriptName ); + } + virtual void UpdateExcludedTextures( void ) + { + m_pBaseMaterialsPassThru->UpdateExcludedTextures(); + } - virtual bool IsRenderThreadSafe() { return m_pBaseMaterialsPassThru->IsRenderThreadSafe(); } + virtual bool IsInFrame() const + { + return m_pBaseMaterialsPassThru->IsInFrame(); + } - virtual void GetDXLevelDefaults(uint& max_dxlevel, uint& recomended) { m_pBaseMaterialsPassThru->GetDXLevelDefaults(max_dxlevel, recomended); } + virtual void CompactMemory() + { + m_pBaseMaterialsPassThru->CompactMemory(); + } - virtual bool IsMaterialLoaded(const char* name) { return m_pBaseMaterialsPassThru->IsMaterialLoaded(name); } + virtual void ReloadFilesInList( IFileList *pFilesToReload ) + { + m_pBaseMaterialsPassThru->ReloadFilesInList( pFilesToReload ); + } - virtual void SetAsyncTextureLoadCache(void* data) { m_pBaseMaterialsPassThru->SetAsyncTextureLoadCache(data); } + virtual bool AllowThreading( bool bAllow, int nServiceThread ) + { + return m_pBaseMaterialsPassThru->AllowThreading( bAllow, nServiceThread ); + } - virtual bool SupportsShadowDepthTextures() { return m_pBaseMaterialsPassThru->SupportsShadowDepthTextures(); } + virtual bool IsRenderThreadSafe() + { + return m_pBaseMaterialsPassThru->IsRenderThreadSafe(); + } - virtual ImageFormat GetShadowDepthTextureFormat() { return m_pBaseMaterialsPassThru->GetShadowDepthTextureFormat(); } + virtual void GetDXLevelDefaults( uint &max_dxlevel, uint &recomended ) + { + m_pBaseMaterialsPassThru->GetDXLevelDefaults( max_dxlevel, recomended ); + } - virtual bool SupportsFetch4() { return m_pBaseMaterialsPassThru->SupportsFetch4(); } + virtual bool IsMaterialLoaded( const char *name ) + { + return m_pBaseMaterialsPassThru->IsMaterialLoaded( name ); + } - virtual ImageFormat GetNullTextureFormat() { return m_pBaseMaterialsPassThru->GetNullTextureFormat(); } + virtual void SetAsyncTextureLoadCache( void *data ) + { + m_pBaseMaterialsPassThru->SetAsyncTextureLoadCache( data ); + } - virtual IMaterial* FindMaterialEx(char const* pMaterialName, const char* pTextureGroupName, int nContext, bool complain = true, const char* pComplainPrefix = NULL) + virtual bool SupportsShadowDepthTextures() { - return m_pBaseMaterialsPassThru->FindMaterialEx(pMaterialName, pTextureGroupName, nContext, complain, pComplainPrefix); + return m_pBaseMaterialsPassThru->SupportsShadowDepthTextures(); } - virtual void SetRenderTargetFrameBufferSizeOverrides(int nWidth, int nHeight) { m_pBaseMaterialsPassThru->SetRenderTargetFrameBufferSizeOverrides(nWidth, nHeight); } + virtual ImageFormat GetShadowDepthTextureFormat() + { + return m_pBaseMaterialsPassThru->GetShadowDepthTextureFormat(); + } - virtual void GetRenderTargetFrameBufferDimensions(int& nWidth, int& nHeight) { m_pBaseMaterialsPassThru->GetRenderTargetFrameBufferDimensions(nWidth, nHeight); } + virtual bool SupportsFetch4() + { + return m_pBaseMaterialsPassThru->SupportsFetch4(); + } - virtual char* GetDisplayDeviceName() const { return m_pBaseMaterialsPassThru->GetDisplayDeviceName(); } + virtual ImageFormat GetNullTextureFormat() + { + return m_pBaseMaterialsPassThru->GetNullTextureFormat(); + } - virtual ITexture* CreateTextureFromBits(int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits) + virtual IMaterial *FindMaterialEx( char const *pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL ) { - return m_pBaseMaterialsPassThru->CreateTextureFromBits(w, h, mips, fmt, srcBufferSize, srcBits); + return m_pBaseMaterialsPassThru->FindMaterialEx( pMaterialName, pTextureGroupName, nContext, complain, pComplainPrefix ); } - virtual void OverrideRenderTargetAllocation(bool rtAlloc) { m_pBaseMaterialsPassThru->OverrideRenderTargetAllocation(rtAlloc); } +#ifdef DX_TO_GL_ABSTRACTION + virtual void DoStartupShaderPreloading( void ) + { + return m_pBaseMaterialsPassThru->DoStartupShaderPreloading(); + } +#endif - virtual ITextureCompositor* NewTextureCompositor(int w, int h, const char* pCompositeName, int nTeamNum, uint64 randomSeed, KeyValues* stageDesc, uint32 texCompositeCreateFlags = 0) + virtual void SetRenderTargetFrameBufferSizeOverrides( int nWidth, int nHeight ) { - return m_pBaseMaterialsPassThru->NewTextureCompositor(w, h, pCompositeName, nTeamNum, randomSeed, stageDesc, texCompositeCreateFlags); + m_pBaseMaterialsPassThru->SetRenderTargetFrameBufferSizeOverrides( nWidth, nHeight ); } - virtual void AsyncFindTexture(const char* pFilename, const char* pTextureGroupName, IAsyncTextureOperationReceiver* pRecipient, void* pExtraArgs, bool bComplain = true, int nAdditionalCreationFlags = 0) + virtual void GetRenderTargetFrameBufferDimensions( int &nWidth, int &nHeight ) { - m_pBaseMaterialsPassThru->AsyncFindTexture(pFilename, pTextureGroupName, pRecipient, pExtraArgs, bComplain, nAdditionalCreationFlags); + m_pBaseMaterialsPassThru->GetRenderTargetFrameBufferDimensions( nWidth, nHeight ); } - virtual ITexture* CreateNamedTextureFromBitsEx(const char* pName, const char* pTextureGroupName, int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits, int nFlags) + virtual char *GetDisplayDeviceName() const + { + return m_pBaseMaterialsPassThru->GetDisplayDeviceName(); + } + + virtual RenderBackend_t GetRenderBackend() const { - return m_pBaseMaterialsPassThru->CreateNamedTextureFromBitsEx(pName, pTextureGroupName, w, h, mips, fmt, srcBufferSize, srcBits, nFlags); + return m_pBaseMaterialsPassThru->GetRenderBackend(); } protected: - IMaterialSystem* m_pBaseMaterialsPassThru; - }; + IMaterialSystem *m_pBaseMaterialsPassThru; +}; class CDeferredMaterialSystem : public CPassThruMaterialSystem { typedef CPassThruMaterialSystem BaseClass; - public: - IMaterial* FindMaterialEx(char const* pMaterialName, const char* pTextureGroupName, int nContext, bool complain = true, const char* pComplainPrefix = NULL) OVERRIDE + +public: + IMaterial *FindMaterialEx( char const *pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL ) OVERRIDE { - return ReplaceMaterialInternal(BaseClass::FindMaterialEx(pMaterialName, pTextureGroupName, nContext, complain, pComplainPrefix)); + return ReplaceMaterialInternal( BaseClass::FindMaterialEx( pMaterialName, pTextureGroupName, nContext, complain, pComplainPrefix ) ); } - IMaterial* FindMaterial(char const* pMaterialName, const char* pTextureGroupName, bool complain = true, const char* pComplainPrefix = NULL) OVERRIDE + IMaterial *FindMaterial( char const *pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) OVERRIDE { - return ReplaceMaterialInternal(BaseClass::FindMaterial(pMaterialName, pTextureGroupName, complain, pComplainPrefix)); + return ReplaceMaterialInternal( BaseClass::FindMaterial( pMaterialName, pTextureGroupName, complain, pComplainPrefix ) ); } - IMaterial* FindProceduralMaterial(const char* pMaterialName, const char* pTextureGroupName, KeyValues* pVMTKeyValues) OVERRIDE; - IMaterial* CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues) OVERRIDE; -private: - IMaterial* ReplaceMaterialInternal(IMaterial* pMat) const; - }; + IMaterial *FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) OVERRIDE; + IMaterial *CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) OVERRIDE; +private: + IMaterial *ReplaceMaterialInternal( IMaterial *pMat ) const; +}; #endif // WARS_MATERIALSYSTEM_PASSTHRU_H \ No newline at end of file diff --git a/game/client/vance/deferred_material_replace.cpp b/game/client/vance/deferred_material_replace.cpp index 6290a537..97118244 100644 --- a/game/client/vance/deferred_material_replace.cpp +++ b/game/client/vance/deferred_material_replace.cpp @@ -1,4 +1,4 @@ -//====== Copyright Sandern Corporation, All rights reserved. ===========// +//====== Copyright � Sandern Corporation, All rights reserved. ===========// // // Purpose: // @@ -24,7 +24,9 @@ CON_COMMAND(print_num_replaced_mats, "") ConColorMsg(COLOR_GREEN, "%d replaced materials\n", matCount); } -bool replMatPossible = true; +//bool replMatPossible = true; +// Echoes; Disabled. +bool replMatPossible = false; //----------------------------------------------------------------------------- // List of materials that should be replaced @@ -37,8 +39,6 @@ static const char * const pszShaderReplaceDict[][2] = { }; static const int iNumShaderReplaceDict = ARRAYSIZE(pszShaderReplaceDict); -#include "icommandline.h" - // Copied from cdeferred_manager_client.cpp static void ShaderReplaceReplMat(const char *szNewShadername, IMaterial *pMat) { @@ -191,18 +191,11 @@ const char *Console_GetLastLine(size_t errorSize) char *pszRet = NULL; strcpy(pszRet, pszLine); - delete pszLine; + delete[] pszLine; return pszRet; } -#ifdef _DEBUG -#define DebuggerBreakOnError(pszError) if (V_stricmp(Console_GetLastLine(strlen(pszError)), pszError) == 0) \ - DebuggerBreak(); -#else -#define DebuggerBreakOnError(pszError) -#endif - IMaterial* CDeferredMaterialSystem::FindProceduralMaterial(const char* pMaterialName, const char* pTextureGroupName, KeyValues* pVMTKeyValues) { @@ -217,11 +210,7 @@ IMaterial* CDeferredMaterialSystem::FindProceduralMaterial(const char* pMaterial } } - IMaterial *pMaterial = BaseClass::FindProceduralMaterial(pMaterialName, pTextureGroupName, pVMTKeyValues); - // DebuggerBreakOnError("ShaderAPIDX8::CreateD3DTexture: D3DERR_INVALIDCALL\n"); - if (!pMaterial) - DebuggerBreak(); - return pMaterial; + return BaseClass::FindProceduralMaterial(pMaterialName, pTextureGroupName, pVMTKeyValues); } IMaterial* CDeferredMaterialSystem::CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues) @@ -237,11 +226,7 @@ IMaterial* CDeferredMaterialSystem::CreateMaterial(const char* pMaterialName, Ke } } - IMaterial *pMaterial = BaseClass::CreateMaterial(pMaterialName, pVMTKeyValues); - // DebuggerBreakOnError("ShaderAPIDX8::CreateD3DTexture: D3DERR_INVALIDCALL\n"); - if (!pMaterial) - DebuggerBreak(); - return pMaterial; + return BaseClass::CreateMaterial(pMaterialName, pVMTKeyValues); } IMaterial* CDeferredMaterialSystem::ReplaceMaterialInternal(IMaterial* pMat) const @@ -297,7 +282,6 @@ static ReplacementSystem s_ReplacementSystem; void ReplacementSystem::Enable() { - if (m_pOldMaterialSystem || !replMatPossible) return; diff --git a/game/client/vance/deferred_screenspace_effects.cpp b/game/client/vance/deferred_screenspace_effects.cpp deleted file mode 100644 index 3d0b4f4f..00000000 --- a/game/client/vance/deferred_screenspace_effects.cpp +++ /dev/null @@ -1,569 +0,0 @@ -#include "cbase.h" -#include "screenspaceeffects.h" -#include "rendertexture.h" -#include "model_types.h" -#include "materialsystem/imaterialsystemhardwareconfig.h" -#include "materialsystem/imaterialsystem.h" -#include "materialsystem/imaterialvar.h" -#include "cdll_client_int.h" -#include "materialsystem/itexture.h" -#include "keyvalues.h" -#include "ClientEffectPrecacheSystem.h" -#include "viewrender.h" -#include "view_scene.h" -#include "c_basehlplayer.h" -#include "tier0/vprof.h" -#include "view.h" -#include "hl2_gamerules.h" - -#include "deferred_screenspace_effects.h" -#include "deferred_rt.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Specifically for Deferred lighting pass -//----------------------------------------------------------------------------- -static void DrawLightingPass(IMaterial* pMaterial, int x, int y, int w, int h, bool shouldScale = false) -{ - ITexture* pTexture = GetFullFrameFrameBufferTexture(0); - UpdateScreenEffectTexture(0, x, y, w, h, false); - - CMatRenderContextPtr pRenderContext(materials); - - pRenderContext->DrawScreenSpaceRectangle(pMaterial, x, y, w * (shouldScale ? (pTexture->GetActualWidth() / w) : 1), h * (shouldScale ? (pTexture->GetActualHeight() / h) : 1), - x, y, x + w - 1, y + h - 1, - w, h); -} - -static void SetRenderTargetAndViewPort(ITexture* rt) -{ - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->SetRenderTarget(rt); - pRenderContext->Viewport(0, 0, rt->GetActualWidth(), rt->GetActualHeight()); -} - -void CFXAA::Init(void) -{ - PrecacheMaterial("shaders/fxaa_luma"); - PrecacheMaterial("shaders/fxaa"); - - m_Luma.Init(materials->FindMaterial("shaders/fxaa_luma", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_FXAA.Init(materials->FindMaterial("shaders/fxaa", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CFXAA::Shutdown(void) -{ - m_Luma.Shutdown(); - m_FXAA.Shutdown(); -} - -ConVar r_post_fxaa("r_post_fxaa", "1", FCVAR_ARCHIVE); -ConVar r_post_fxaa_quality("r_post_fxaa_quality", "4", FCVAR_ARCHIVE, "0 = Very Low, 1 = Low, 2 = Medium, 3 = High, 4 = Very High", true, 0, true, 4); -void CFXAA::Render(int x, int y, int w, int h) -{ - VPROF("CFXAA::Render"); - - if (!r_post_fxaa.GetBool() || (IsEnabled() == false)) - return; - - IMaterialVar *var; - var = m_FXAA->FindVar("$QUALITY", NULL); - var->SetIntValue(r_post_fxaa_quality.GetInt()); - - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->OverrideDepthEnable(true, false); - DrawScreenEffectMaterial(m_Luma, x, y, w, h); - DrawScreenEffectMaterial(m_FXAA, x, y, w, h); - pRenderContext->OverrideDepthEnable(false, true); -} - -void CTonemap::Init(void) -{ - PrecacheMaterial("shaders/tonemap"); - - m_Tonemap.Init(materials->FindMaterial("shaders/tonemap", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CTonemap::Shutdown(void) -{ - m_Tonemap.Shutdown(); -} - -ConVar r_post_tonemap("r_post_tonemap", "1", FCVAR_ARCHIVE); -void CTonemap::Render(int x, int y, int w, int h) -{ - VPROF("CFXAA::Render"); - - if (!r_post_tonemap.GetBool() || (IsEnabled() == false)) - return; - - DrawScreenEffectMaterial(m_Tonemap, x, y, w, h); -} - -void CSSAO::Init(void) -{ - PrecacheMaterial("shaders/ssgi"); - PrecacheMaterial("shaders/ssao_bilateralx"); - PrecacheMaterial("shaders/ssao_bilateraly"); - PrecacheMaterial("shaders/ssgi_combine"); - - m_Normal.Init("_rt_Normals", TEXTURE_GROUP_RENDER_TARGET); - m_SSAO.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSAOFB"); - m_SSAOX.InitRenderTarget(ScreenWidth(), ScreenHeight(), RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSAOFBX"); - m_SSAOY.InitRenderTarget(ScreenWidth(), ScreenHeight(), RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSAOFBY"); - - m_SSAO_Mat.Init(materials->FindMaterial("shaders/ssgi", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_SSAO_BilateralX.Init(materials->FindMaterial("shaders/ssao_bilateralx", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_SSAO_BilateralY.Init(materials->FindMaterial("shaders/ssao_bilateraly", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_SSAO_Combine.Init(materials->FindMaterial("shaders/ssgi_combine", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CSSAO::Shutdown(void) -{ - m_SSAO.Shutdown(); -} - -ConVar r_post_ssao("r_post_ssao", "0", FCVAR_ARCHIVE); -void CSSAO::Render(int x, int y, int w, int h) -{ - VPROF("CFXAA::Render"); - - if (!r_post_ssao.GetBool() || (IsEnabled() == false)) - return; - IMaterialVar* var; - CMatRenderContextPtr pRenderContext(materials); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSAO); - DrawScreenEffectQuad(m_SSAO_Mat, m_SSAO->GetActualWidth(), m_SSAO->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSAOX); - DrawScreenEffectQuad(m_SSAO_BilateralX, m_SSAOX->GetActualWidth(), m_SSAOX->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSAOY); - DrawScreenEffectQuad(m_SSAO_BilateralY, m_SSAOY->GetActualWidth(), m_SSAOY->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - var = m_SSAO_Combine->FindVar("$AMOUNT", NULL); - var->SetFloatValue(1.0f); - DrawScreenEffectMaterial(m_SSAO_Combine, x, y, w, h); - - pRenderContext.SafeRelease(); -} - -void CUnsharpEffect::Init(void) -{ - m_UnsharpBlurFB.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_UnsharpBlur"); - - PrecacheMaterial("shaders/unsharp_blur"); - PrecacheMaterial("shaders/unsharp"); - - m_UnsharpBlur.Init(materials->FindMaterial("shaders/unsharp_blur", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_Unsharp.Init(materials->FindMaterial("shaders/unsharp", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CUnsharpEffect::Shutdown(void) -{ - m_UnsharpBlurFB.Shutdown(); - m_UnsharpBlur.Shutdown(); - m_Unsharp.Shutdown(); -} - -ConVar r_post_unsharp("r_post_unsharp", "1", FCVAR_ARCHIVE); -ConVar r_post_unsharp_debug("r_post_unsharp_debug", "0", FCVAR_CHEAT); -ConVar r_post_unsharp_strength("r_post_unsharp_strength", "0.3", FCVAR_CHEAT); -ConVar r_post_unsharp_blursize("r_post_unsharp_blursize", "5.0", FCVAR_CHEAT); -void CUnsharpEffect::Render(int x, int y, int w, int h) -{ - VPROF("CUnsharpEffect::Render"); - - if (!r_post_unsharp.GetBool() || (IsEnabled() == false)) - return; - - // Grab the render context - CMatRenderContextPtr pRenderContext(materials); - - // Set to the proper rendering mode. - pRenderContext->MatrixMode(MATERIAL_VIEW); - pRenderContext->PushMatrix(); - pRenderContext->LoadIdentity(); - pRenderContext->MatrixMode(MATERIAL_PROJECTION); - pRenderContext->PushMatrix(); - pRenderContext->LoadIdentity(); - - IMaterialVar *var; - var = m_UnsharpBlur->FindVar("$blursize", NULL); - var->SetFloatValue(r_post_unsharp_blursize.GetFloat()); - - if (r_post_unsharp_debug.GetBool()) - { - DrawScreenEffectMaterial(m_UnsharpBlur, x, y, w, h); - return; - } - - Rect_t actualRect; - UpdateScreenEffectTexture(0, x, y, w, h, false, &actualRect); - pRenderContext->PushRenderTargetAndViewport(m_UnsharpBlurFB); - DrawScreenEffectQuad(m_UnsharpBlur, m_UnsharpBlurFB->GetActualWidth(), m_UnsharpBlurFB->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - //Restore our state - pRenderContext->MatrixMode(MATERIAL_VIEW); - pRenderContext->PopMatrix(); - pRenderContext->MatrixMode(MATERIAL_PROJECTION); - pRenderContext->PopMatrix(); - - var = m_Unsharp->FindVar("$fbblurtexture", NULL); - var->SetTextureValue(m_UnsharpBlurFB); - var = m_Unsharp->FindVar("$unsharpstrength", NULL); - var->SetFloatValue(r_post_unsharp_strength.GetFloat()); - var = m_Unsharp->FindVar("$blursize", NULL); - var->SetFloatValue(r_post_unsharp_blursize.GetFloat()); - - DrawScreenEffectMaterial(m_Unsharp, x, y, w, h); -} - -ConVar r_post_watereffects_underwater_chromaticoffset("r_post_watereffects_underwater_chromaticoffset", "1.0", FCVAR_CHEAT); -ConVar r_post_watereffects_underwater_amount("r_post_watereffects_underwater_amount", "0.1", FCVAR_CHEAT); -ConVar r_post_watereffects_underwater_viscosity("r_post_watereffects_underwater_viscosity", "1.0", FCVAR_CHEAT); -ConVar r_post_watereffects_lerp_viscosity("r_post_watereffects_lerp_viscosity", "0.01", FCVAR_CHEAT); -ConVar r_post_watereffects_lerp_amount("r_post_watereffects_lerp_amount", "0.005", FCVAR_CHEAT); -ConVar r_post_watereffects_underwater_gaussianamount("r_post_watereffects_underwater_gaussianamount", "1.5", FCVAR_CHEAT); -void CWaterEffects::Init(void) -{ - fViscosity = 0.01; - fAmount = 0; - m_bUnderwater = false; - - PrecacheMaterial("shaders/chromaticDisp"); - PrecacheMaterial("shaders/screenwater"); - PrecacheMaterial("shaders/screen_blurx"); - PrecacheMaterial("shaders/screen_blury"); - - m_ChromaticDisp.Init(materials->FindMaterial("shaders/chromaticDisp", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_WaterFX.Init(materials->FindMaterial("shaders/screenwater", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_BlurX.Init(materials->FindMaterial("shaders/screen_blurx", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_BlurY.Init(materials->FindMaterial("shaders/screen_blury", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CWaterEffects::Shutdown(void) -{ - m_ChromaticDisp.Shutdown(); - m_WaterFX.Shutdown(); - m_BlurX.Shutdown(); - m_BlurY.Shutdown(); -} - -void CWaterEffects::SetParameters(KeyValues *params) -{ - if (IsUnderwater()) - return; - - float in, temp; - - if (params->FindKey("amount")) - { - in = params->GetFloat("amount"); - temp = GetAmount(); - temp += in; - if (temp > 0.1f) - temp = 0.1f; - - SetAmount(temp); - } - - if (params->FindKey("viscosity")) - { - in = params->GetFloat("viscosity"); - temp = GetViscosity(); - temp += in; - if (temp > 1.0f) - temp = 1.0f; - - SetViscosity(temp); - } -} - -ConVar r_post_watereffects("r_post_watereffects", "1", FCVAR_ARCHIVE); -ConVar r_post_watereffects_debug("r_post_watereffects_debug", "0", FCVAR_CHEAT); -void CWaterEffects::Render(int x, int y, int w, int h) -{ - VPROF("CWaterEffects::Render"); - - if (!r_post_watereffects.GetBool() || (IsEnabled() == false)) - return; - - C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); - if (!pPlayer) - return; - - IMaterialVar *var; - - if (pPlayer->GetWaterLevel() >= 3) - { - m_bUnderwater = true; - fViscosity = r_post_watereffects_underwater_viscosity.GetFloat(); - fAmount = r_post_watereffects_underwater_amount.GetFloat(); - - //Gaussian Blur the screen - var = m_BlurX->FindVar("$BLURSIZE", NULL); - var->SetFloatValue(r_post_watereffects_underwater_gaussianamount.GetFloat()); - var = m_BlurX->FindVar("$RESDIVISOR", NULL); - var->SetIntValue(1); - DrawScreenEffectMaterial(m_BlurX, x, y, w, h); - var = m_BlurY->FindVar("$BLURSIZE", NULL); - var->SetFloatValue(r_post_watereffects_underwater_gaussianamount.GetFloat()); - var = m_BlurY->FindVar("$RESDIVISOR", NULL); - var->SetIntValue(1); - DrawScreenEffectMaterial(m_BlurY, x, y, w, h); - - //Render Chromatic Dispersion - var = m_ChromaticDisp->FindVar("$FOCUSOFFSET", NULL); - var->SetFloatValue(r_post_watereffects_underwater_chromaticoffset.GetFloat()); - var = m_ChromaticDisp->FindVar("$radial", NULL); - var->SetIntValue(0); - DrawScreenEffectMaterial(m_ChromaticDisp, x, y, w, h); - } - else - { - m_bUnderwater = false; - - if (fViscosity != 0.01) - fViscosity = FLerp(fViscosity, 0.01, r_post_watereffects_lerp_viscosity.GetFloat()); - - if (fAmount != 0) - fAmount = FLerp(fAmount, 0, r_post_watereffects_lerp_amount.GetFloat()); - - if (fAmount < 0.01) - { - if (r_post_watereffects_debug.GetBool()) - { - DevMsg("Water Effects Stopped.\n"); - } - return; - } - } - - var = m_WaterFX->FindVar("$AMOUNT", NULL); - var->SetFloatValue(fAmount); - var = m_WaterFX->FindVar("$VISCOSITY", NULL); - var->SetFloatValue(fViscosity); - DrawScreenEffectMaterial(m_WaterFX, x, y, w, h); - - if (r_post_watereffects_debug.GetBool()) - { - DevMsg("Water Amount: %.2f\n", fAmount); - DevMsg("Water Viscosity: %.2f\n", fViscosity); - } -} - -extern void Generate8BitBloomTexture(IMatRenderContext *pRenderContext, float flBloomScale, int x, int y, int w, int h); -extern float GetBloomAmount(); - -void CBloom::Init(void) -{ - PrecacheMaterial("shaders/bloom_sample"); - PrecacheMaterial("shaders/bloom_gaussianx"); - PrecacheMaterial("shaders/bloom_gaussiany"); - PrecacheMaterial("shaders/bloom_combine"); - PrecacheMaterial("shaders/bloom_downsample"); - - m_BloomDS.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomDS"); - m_BloomDS1.InitRenderTarget(ScreenWidth() / 4, ScreenHeight() / 4, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomDS1"); - m_BloomDS2.InitRenderTarget(ScreenWidth() / 8, ScreenHeight() / 8, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomDS2"); - m_BloomDS3.InitRenderTarget(ScreenWidth() / 16, ScreenHeight() / 16, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomDS3"); - - m_BloomFB0.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomFB0"); - m_BloomFB1.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA16161616F, MATERIAL_RT_DEPTH_NONE, false, "_rt_BloomFB1"); - - m_BloomSample.Init(materials->FindMaterial("shaders/bloom_sample", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_GaussianX.Init(materials->FindMaterial("shaders/bloom_gaussianx", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_GaussianY.Init(materials->FindMaterial("shaders/bloom_gaussiany", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_BloomDownsample.Init(materials->FindMaterial("shaders/bloom_downsample", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_BloomCombine.Init(materials->FindMaterial("shaders/bloom_combine", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CBloom::Shutdown(void) -{ - m_BloomFB0.Shutdown(); - m_BloomFB1.Shutdown(); - m_BloomDS.Shutdown(); - m_BloomDS1.Shutdown(); - m_BloomDS2.Shutdown(); - m_BloomDS3.Shutdown(); - - m_BloomSample.Shutdown(); - m_GaussianX.Shutdown(); - m_GaussianY.Shutdown(); - m_BloomDownsample.Shutdown(); - m_BloomCombine.Shutdown(); -} - -ConVar r_post_bloom("r_post_bloom", "1", FCVAR_ARCHIVE); -ConVar r_post_bloom_amount("r_post_bloom_amount", "1", FCVAR_ARCHIVE); -ConVar r_post_bloom_gaussianamount("r_post_bloom_gaussianamount", "1", FCVAR_ARCHIVE); -ConVar r_post_bloom_exposure("r_post_bloom_exposure", "1", FCVAR_ARCHIVE); -void CBloom::Render(int x, int y, int w, int h) -{ - VPROF("CBloom::Render"); - - if (!r_post_bloom.GetBool() || (IsEnabled() == false)) - return; - - IMaterialVar *var; - CMatRenderContextPtr pRenderContext(materials); - - Generate8BitBloomTexture(pRenderContext, GetBloomAmount(), x, y, w, h); - - //Gaussian Blur the screen - var = m_GaussianX->FindVar("$BLURSIZE", NULL); - var->SetFloatValue(r_post_bloom_gaussianamount.GetFloat()); - var = m_GaussianY->FindVar("$BLURSIZE", NULL); - var->SetFloatValue(r_post_bloom_gaussianamount.GetFloat()); - - var = m_BloomSample->FindVar("$C1_X", NULL); - var->SetFloatValue(r_post_bloom_exposure.GetFloat()); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomDS); - DrawScreenEffectQuad(m_BloomSample, m_BloomDS->GetActualWidth(), m_BloomDS->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomFB0); - DrawScreenEffectQuad(m_GaussianX, m_BloomFB0->GetActualWidth(), m_BloomFB0->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomFB1); - DrawScreenEffectQuad(m_GaussianY, m_BloomFB1->GetActualWidth(), m_BloomFB1->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - var = m_BloomDownsample->FindVar("$C1_X", NULL); - var->SetFloatValue(1.0f); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomDS1); - DrawScreenEffectQuad(m_BloomDownsample, m_BloomDS1->GetActualWidth(), m_BloomDS1->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomDS2); - DrawScreenEffectQuad(m_BloomDownsample, m_BloomDS2->GetActualWidth(), m_BloomDS2->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - pRenderContext->PushRenderTargetAndViewport(); - SetRenderTargetAndViewPort(m_BloomDS3); - DrawScreenEffectQuad(m_BloomDownsample, m_BloomDS3->GetActualWidth(), m_BloomDS3->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - var = m_BloomCombine->FindVar("$AMOUNT", NULL); - var->SetFloatValue(GetBloomAmount() * r_post_bloom_amount.GetFloat()); - DrawScreenEffectMaterial(m_BloomCombine, x, y, w, h); -} - -void CVolumetrics::Init(void) -{ - PrecacheMaterial("shaders/volumetrics_combine"); - PrecacheMaterial("shaders/volumetrics_downsample"); - - //m_VolumetricsFB0.InitRenderTarget(ScreenWidth() / 16, ScreenHeight() / 16, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_VolumetricsFB0"); - m_VolumetricsFB0.Init( materials->FindTexture("_rt_VolumetricsBuffer", TEXTURE_GROUP_RENDER_TARGET) ); - m_VolumetricsCombine.Init(materials->FindMaterial("shaders/volumetrics_combine", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_VolumetricsSample.Init(materials->FindMaterial("shaders/volumetrics_downsample", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CVolumetrics::Shutdown(void) -{ - m_VolumetricsFB0.Shutdown(); - m_VolumetricsCombine.Shutdown(); -} - -extern ConVar r_volumetrics; -void CVolumetrics::Render(int x, int y, int w, int h) -{ - VPROF("CVolumetrics::Render"); - - if (!r_volumetrics.GetBool() || (IsEnabled() == false)) - return; - - CMatRenderContextPtr pRenderContext(materials); - - IMaterialVar* var = m_VolumetricsCombine->FindVar("$C1_X", NULL); - var->SetFloatValue(1.0f); - - DrawScreenEffectMaterial(m_VolumetricsCombine, x, y, w, h); -} - -void CSSR::Init(void) -{ - PrecacheMaterial("shaders/SSR"); - PrecacheMaterial("shaders/ssr_add"); - - m_SSR.InitRenderTarget(ScreenWidth() / 2, ScreenHeight() / 2, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSR"); - m_SSRX.InitRenderTarget(ScreenWidth(), ScreenHeight(), RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSRX"); - m_SSRY.InitRenderTarget(ScreenWidth(), ScreenHeight(), RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_NONE, false, "_rt_SSRY"); - - m_SSR_Mat.Init(materials->FindMaterial("shaders/SSR", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_SSR_Add.Init(materials->FindMaterial("shaders/ssr_add", TEXTURE_GROUP_PIXEL_SHADERS, true)); - - m_SSR_BilateralX.Init(materials->FindMaterial("shaders/ssr_bilateralx", TEXTURE_GROUP_PIXEL_SHADERS, true)); - m_SSR_BilateralY.Init(materials->FindMaterial("shaders/ssr_bilateraly", TEXTURE_GROUP_PIXEL_SHADERS, true)); -} - -void CSSR::Shutdown(void) -{ - m_SSR.Shutdown(); - m_SSR_Mat.Shutdown(); - m_SSR_Add.Shutdown(); -} - -ConVar r_post_ssr("r_post_ssr", "0", FCVAR_ARCHIVE); -ConVar r_post_ssr_raystep("r_post_ssr_raystep", "1", FCVAR_ARCHIVE); -ConVar r_post_ssr_maxdepth("r_post_ssr_maxdepth", "1", FCVAR_ARCHIVE); -ConVar r_post_ssr_stepmul("r_post_ssr_stepmul", "1.0", FCVAR_ARCHIVE); -void CSSR::Render(int x, int y, int w, int h) -{ - VPROF("CSSR::Render"); - - if (!r_post_ssr.GetBool() || (IsEnabled() == false)) - return; - - CMatRenderContextPtr pRenderContext(materials); - - IMaterialVar* var; - var = m_SSR_Mat->FindVar("$C1_X", NULL); - var->SetFloatValue(r_post_ssr_raystep.GetFloat()); - var = m_SSR_Mat->FindVar("$C1_Y", NULL); - var->SetFloatValue(r_post_ssr_maxdepth.GetFloat()); - var = m_SSR_Mat->FindVar("$C1_Z", NULL); - var->SetFloatValue(r_post_ssr_stepmul.GetFloat()); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSR); - DrawScreenEffectQuad(m_SSR_Mat, m_SSR->GetActualWidth(), m_SSR->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSRX); - DrawScreenEffectQuad(m_SSR_BilateralX, m_SSRX->GetActualWidth(), m_SSRX->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - UpdateScreenEffectTexture(0, x, y, w, h, false); - pRenderContext->PushRenderTargetAndViewport(m_SSRY); - DrawScreenEffectQuad(m_SSR_BilateralY, m_SSRY->GetActualWidth(), m_SSRY->GetActualHeight()); - pRenderContext->PopRenderTargetAndViewport(); - - var = m_SSR_Add->FindVar("$C1_X", NULL); - var->SetFloatValue(1.0f); - - DrawScreenEffectMaterial(m_SSR_Add, x, y, w, h); - - pRenderContext.SafeRelease(); -} \ No newline at end of file diff --git a/game/client/vance/deferred_screenspace_effects.h b/game/client/vance/deferred_screenspace_effects.h deleted file mode 100644 index 21388468..00000000 --- a/game/client/vance/deferred_screenspace_effects.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef VANCE_SCREENSPACEEFFECTS_H -#define VANCE_SCREENSPACEEFFECTS_H -#ifdef _WIN32 -#pragma once -#endif - -#include "ScreenSpaceEffects.h" - -class CFXAA : public IScreenSpaceEffect -{ -public: - CFXAA(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues *params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CMaterialReference m_Luma; - CMaterialReference m_FXAA; -}; - -class CTonemap : public IScreenSpaceEffect -{ -public: - CTonemap(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues* params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CMaterialReference m_Tonemap; -}; - -class CSSAO : public IScreenSpaceEffect -{ -public: - CSSAO(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues* params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CTextureReference m_Normal; - CTextureReference m_SSAO; - CTextureReference m_SSAOX; - CTextureReference m_SSAOY; - - CMaterialReference m_SSAO_Mat; - CMaterialReference m_SSAO_BilateralX; - CMaterialReference m_SSAO_BilateralY; - CMaterialReference m_SSAO_Combine; -}; - -class CUnsharpEffect : public IScreenSpaceEffect -{ -public: - CUnsharpEffect(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues *params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CTextureReference m_UnsharpBlurFB; - CMaterialReference m_UnsharpBlur; - CMaterialReference m_Unsharp; -}; - -class CWaterEffects : public IScreenSpaceEffect -{ -public: - CWaterEffects(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues *params); - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - - virtual float GetViscosity() { return fViscosity; } - virtual float GetAmount() { return fAmount; } - virtual void SetViscosity(float fNewViscosity) { fViscosity = fNewViscosity; } - virtual void SetAmount(float fNewAmount) { fAmount = fNewAmount; } - virtual bool IsUnderwater() { return m_bUnderwater; } - -private: - bool m_bEnabled; - bool m_bUnderwater; - - float fViscosity; - float fAmount; - - CMaterialReference m_ChromaticDisp; - CMaterialReference m_WaterFX; - CMaterialReference m_BlurX; - CMaterialReference m_BlurY; -}; - -class CBloom : public IScreenSpaceEffect -{ -public: - CBloom(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues *params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CTextureReference m_BloomDS; - CTextureReference m_BloomDS1; - CTextureReference m_BloomDS2; - CTextureReference m_BloomDS3; - - CTextureReference m_BloomFB0; - CTextureReference m_BloomFB1; - - CMaterialReference m_BloomSample; - CMaterialReference m_GaussianX; - CMaterialReference m_GaussianY; - CMaterialReference m_BloomDownsample; - CMaterialReference m_BloomCombine; -}; - -class CVolumetrics : public IScreenSpaceEffect -{ -public: - CVolumetrics(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues* params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CTextureReference m_VolumetricsFB0; - - CMaterialReference m_VolumetricsSample; - CMaterialReference m_VolumetricsCombine; -}; - - -class CSSR : public IScreenSpaceEffect -{ -public: - CSSR(void) { }; - - virtual void Init(void); - virtual void Shutdown(void); - virtual void SetParameters(KeyValues* params) {}; - virtual void Enable(bool bEnable) { m_bEnabled = bEnable; } - virtual bool IsEnabled() { return m_bEnabled; } - - virtual void Render(int x, int y, int w, int h); - -private: - bool m_bEnabled; - - CTextureReference m_SSR; - CTextureReference m_SSRX; - CTextureReference m_SSRY; - - CMaterialReference m_SSR_BilateralX; - CMaterialReference m_SSR_BilateralY; - - CMaterialReference m_SSR_Mat; - CMaterialReference m_SSR_Add; -}; - -#endif \ No newline at end of file diff --git a/game/client/vance/deferred_screenspace_effects_order.cpp b/game/client/vance/deferred_screenspace_effects_order.cpp deleted file mode 100644 index ad785407..00000000 --- a/game/client/vance/deferred_screenspace_effects_order.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//========= Copyright 2010, Gear Development, All rights reserved. ============// -// -// Purpose: I imagine a few of you are going to wonder dearly what this is is why we're doing this. -// Well, sit down. I'm going to tell you a story: -// When Valve created the screeneffects system, they did with 1 effect running at any given time, max; -// More if render order wasn't important or you wanted to stick to a single screeneffects file. -// In City17, we need a whopping 6 screeneffects on at all times, not including any of the stock screeneffects. -// This presented us with a problem, because there weren't any ways to scientifically control the render order of the effects. -// This is our "fix". If you want to add a new effect, include it's headers here, and then define it here within this render order stack. -// -// Note: Bottom renders first. -// -//===============================================================================// -#include "cbase.h" -#include "ScreenSpaceEffects.h" -#include "deferred_screenspace_effects.h" -#include "episodic\episodic_screenspaceeffects.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// FXAA -ADD_SCREENSPACE_EFFECT(CFXAA, vance_fxaa); - -// Unsharp -ADD_SCREENSPACE_EFFECT(CUnsharpEffect, vance_unsharp); - -// Episodic -ADD_SCREENSPACE_EFFECT(CStunEffect, episodic_stun); -ADD_SCREENSPACE_EFFECT(CEP2StunEffect, ep2_groggy); - -// Underwater effects -ADD_SCREENSPACE_EFFECT(CWaterEffects, vance_waterfx); - -// Episodic -ADD_SCREENSPACE_EFFECT(CEP1IntroEffect, episodic_intro); - -// Tonemap -ADD_SCREENSPACE_EFFECT(CTonemap, vance_tonemap); - -// Gaussian Bloom -ADD_SCREENSPACE_EFFECT(CBloom, vance_bloom); - -// Volumetric lighting combine -ADD_SCREENSPACE_EFFECT(CVolumetrics, vance_volumetrics); - -// SSR -ADD_SCREENSPACE_EFFECT(CSSR, vance_ssr); - -// SSAO -ADD_SCREENSPACE_EFFECT(CSSAO, vance_ssao); diff --git a/game/client/vance/hook/CHardwareConfig.h b/game/client/vance/hook/CHardwareConfig.h new file mode 100644 index 00000000..b3d5dbc5 --- /dev/null +++ b/game/client/vance/hook/CHardwareConfig.h @@ -0,0 +1,218 @@ +#pragma once +#include "materialsystem/imaterialsystem.h" + +#define MAT_DXLEVEL_OVERRIDE 100 +#define MAT_DXLEVEL_OVERRIDE_S "100" + +enum CompressedTextureState_t +{ + COMPRESSED_TEXTURES_ON, + COMPRESSED_TEXTURES_OFF, + COMPRESSED_TEXTURES_NOT_INITIALIZED +}; + +struct HardwareCaps_t : public MaterialAdapterInfo_t +{ + CompressedTextureState_t m_SupportsCompressedTextures; + VertexCompressionType_t m_SupportsCompressedVertices; + int m_NumSamplers; + int m_NumTextureStages; + int m_nMaxAnisotropy; + int m_MaxTextureWidth; + int m_MaxTextureHeight; + int m_MaxTextureDepth; + int m_MaxTextureAspectRatio; + int m_MaxPrimitiveCount; + int m_NumPixelShaderConstants; + int m_NumBooleanPixelShaderConstants; + int m_NumIntegerPixelShaderConstants; + int m_NumVertexShaderConstants; + int m_NumBooleanVertexShaderConstants; + int m_NumIntegerVertexShaderConstants; + int m_TextureMemorySize; + int m_MaxNumLights; + int m_MaxBlendMatrices; + int m_MaxBlendMatrixIndices; + int m_MaxVertexShaderBlendMatrices; + int m_MaxUserClipPlanes; + HDRType_t m_HDRType; + char m_pShaderDLL[32]; + ImageFormat m_ShadowDepthTextureFormat; + ImageFormat m_NullTextureFormat; + int m_nVertexTextureCount; + int m_nMaxVertexTextureDimension; + unsigned long m_AlphaToCoverageState; + unsigned long m_AlphaToCoverageEnableValue; + unsigned long m_AlphaToCoverageDisableValue; + int m_nMaxViewports; + float m_flMinGammaControlPoint; + float m_flMaxGammaControlPoint; + int m_nGammaControlPointCount; + int m_MaxVertexShader30InstructionSlots; + int m_MaxPixelShader30InstructionSlots; + int m_MaxSimultaneousRenderTargets; + bool m_bDeviceOk : 1; + bool m_HasSetDeviceGammaRamp : 1; + bool m_SupportsVertexShaders : 1; + bool m_SupportsVertexShaders_2_0 : 1; + bool m_SupportsPixelShaders : 1; + bool m_SupportsPixelShaders_1_4 : 1; + bool m_SupportsPixelShaders_2_0 : 1; + bool m_SupportsPixelShaders_2_b : 1; + bool m_SupportsShaderModel_3_0 : 1; + bool m_bSupportsAnisotropicFiltering : 1; + bool m_bSupportsMagAnisotropicFiltering : 1; + bool m_bSupportsVertexTextures : 1; + bool m_ZBiasAndSlopeScaledDepthBiasSupported : 1; + bool m_SupportsMipmapping : 1; + bool m_SupportsOverbright : 1; + bool m_SupportsCubeMaps : 1; + bool m_SupportsHardwareLighting : 1; + bool m_SupportsMipmappedCubemaps : 1; + bool m_SupportsNonPow2Textures : 1; + bool m_PreferDynamicTextures : 1; + bool m_HasProjectedBumpEnv : 1; + bool m_SupportsSRGB : 1; + bool m_bSupportsSpheremapping : 1; + bool m_UseFastClipping : 1; + bool m_bNeedsATICentroidHack : 1; + bool m_bDisableShaderOptimizations : 1; + bool m_bColorOnSecondStream : 1; + bool m_bSupportsStreamOffset : 1; + bool m_bFogColorSpecifiedInLinearSpace : 1; + bool m_bFogColorAlwaysLinearSpace : 1; + bool m_bSupportsAlphaToCoverage : 1; + bool m_bSupportsShadowDepthTextures : 1; + bool m_bSupportsFetch4 : 1; + bool m_bSoftwareVertexProcessing : 1; + bool m_bScissorSupported : 1; + bool m_bSupportsFloat32RenderTargets : 1; + bool m_bSupportsBorderColor : 1; + bool m_bDX10Card : 1; + bool m_bDX10Blending : 1; + bool m_bSupportsStaticControlFlow : 1; + bool m_FakeSRGBWrite : 1; + bool m_CanDoSRGBReadFromRTs : 1; + bool m_bSupportsGLMixedSizeTargets : 1; + bool m_bCanStretchRectFromTextures : 1; + HDRType_t m_MaxHDRType; +}; + +class IHardwareConfigInternal : public IMaterialSystemHardwareConfig +{ +public: + virtual const char *GetHWSpecificShaderDLLName() const = 0; +}; + +class CHardwareConfig : public IHardwareConfigInternal +{ +public: + + static void OverrideHardwareCaps( CHardwareConfig *pHardwareConfig ) + { + pHardwareConfig->m_ActualCaps.m_NumPixelShaderConstants = 224; + pHardwareConfig->m_Caps.m_NumPixelShaderConstants = 224; + pHardwareConfig->m_UnOverriddenCaps.m_NumPixelShaderConstants = 224; + + pHardwareConfig->m_ActualCaps.m_nDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + pHardwareConfig->m_Caps.m_nDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + pHardwareConfig->m_UnOverriddenCaps.m_nDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + + pHardwareConfig->m_ActualCaps.m_nMaxDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + pHardwareConfig->m_Caps.m_nMaxDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + pHardwareConfig->m_UnOverriddenCaps.m_nMaxDXSupportLevel = MAT_DXLEVEL_OVERRIDE; + + pHardwareConfig->m_ActualCaps.m_SupportsShaderModel_3_0 = true; + pHardwareConfig->m_Caps.m_SupportsShaderModel_3_0 = true; + pHardwareConfig->m_UnOverriddenCaps.m_SupportsShaderModel_3_0 = true; + } + + virtual bool HasDestAlphaBuffer() const; + virtual bool HasStencilBuffer() const; + virtual int GetFrameBufferColorDepth() const; + virtual int GetSamplerCount() const; + virtual bool HasSetDeviceGammaRamp() const; + virtual bool SupportsCompressedTextures() const; + virtual VertexCompressionType_t SupportsCompressedVertices() const; + virtual bool SupportsBorderColor() const; + virtual bool SupportsFetch4() const; + virtual bool CanStretchRectFromTextures() const; + virtual bool SupportsVertexAndPixelShaders() const; + virtual bool SupportsPixelShaders_1_4() const; + virtual bool SupportsPixelShaders_2_0() const; + virtual bool SupportsStaticControlFlow() const; + virtual bool SupportsVertexShaders_2_0() const; + virtual int MaximumAnisotropicLevel() const; + virtual int MaxTextureWidth() const; + virtual int MaxTextureHeight() const; + virtual int TextureMemorySize() const; + virtual bool SupportsOverbright() const; + virtual bool SupportsCubeMaps() const; + virtual bool SupportsMipmappedCubemaps() const; + virtual bool SupportsNonPow2Textures() const; + virtual int GetTextureStageCount() const; + virtual int NumVertexShaderConstants() const; + virtual int NumBooleanVertexShaderConstants() const; + virtual int NumIntegerVertexShaderConstants() const; + virtual int NumPixelShaderConstants() const; + virtual int NumBooleanPixelShaderConstants() const; + virtual int NumIntegerPixelShaderConstants() const; + virtual int MaxNumLights() const; + virtual bool SupportsHardwareLighting() const; + virtual int MaxBlendMatrices() const; + virtual int MaxBlendMatrixIndices() const; + virtual int MaxTextureAspectRatio() const; + virtual int MaxVertexShaderBlendMatrices() const; + virtual int MaxUserClipPlanes() const; + virtual bool UseFastClipping() const; + virtual int GetDXSupportLevel() const; + virtual const char *GetShaderDLLName() const; + virtual bool ReadPixelsFromFrontBuffer() const; + virtual bool PreferDynamicTextures() const; + virtual bool SupportsHDR() const; + virtual bool HasProjectedBumpEnv() const; + virtual bool SupportsSpheremapping() const; + virtual bool NeedsAAClamp() const; + virtual bool NeedsATICentroidHack() const; + virtual bool SupportsColorOnSecondStream() const; + virtual bool SupportsStaticPlusDynamicLighting() const; + virtual bool PreferReducedFillrate() const; + virtual int GetMaxDXSupportLevel() const; + virtual bool SpecifiesFogColorInLinearSpace() const; + virtual bool SupportsSRGB() const; + virtual bool FakeSRGBWrite() const; + virtual bool CanDoSRGBReadFromRTs() const; + virtual bool SupportsGLMixedSizeTargets() const; + virtual bool IsAAEnabled() const; + virtual int GetVertexTextureCount() const; + virtual int GetMaxVertexTextureDimension() const; + virtual int MaxTextureDepth() const; + virtual HDRType_t GetHDRType() const; + virtual HDRType_t GetHardwareHDRType() const; + virtual bool SupportsPixelShaders_2_b() const; + virtual bool SupportsShaderModel_3_0() const; + virtual bool SupportsStreamOffset() const; + virtual int StencilBufferBits() const; + virtual int MaxViewports() const; + virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ); + virtual int GetShadowFilterMode() const; + virtual int NeedsShaderSRGBConversion() const; + virtual bool UsesSRGBCorrectBlending() const; + virtual bool HasFastVertexTextures() const; + virtual int MaxHWMorphBatchCount() const; + + virtual bool ActuallySupportsPixelShaders_2_b() const; + + virtual bool SupportsHDRMode( HDRType_t nHDRMode ) const; + + virtual bool GetHDREnabled( void ) const; + virtual void SetHDREnabled( bool bEnable ); + +protected: + + HardwareCaps_t m_ActualCaps; + HardwareCaps_t m_Caps; + HardwareCaps_t m_UnOverriddenCaps; + bool m_bHDREnabled; +}; + diff --git a/game/client/vance/hook/IShaderSystemInternal.h b/game/client/vance/hook/IShaderSystemInternal.h new file mode 100644 index 00000000..e48afcf5 --- /dev/null +++ b/game/client/vance/hook/IShaderSystemInternal.h @@ -0,0 +1,35 @@ +#pragma once +#include "materialsystem/ishaderapi.h" +#include "../../materialsystem/ishadersystem.h" + +struct ShaderRenderState_t; + +class IShaderSystemInternal : public IShaderInit, public IShaderSystem +{ +public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + virtual void ModInit() = 0; + virtual void ModShutdown() = 0; + virtual bool LoadShaderDLL( const char *pFullPath ) = 0; + virtual void UnloadShaderDLL( const char *pFullPath ) = 0; + virtual IShader *FindShader( char const* pShaderName ) = 0; + virtual const char *ShaderStateString( int i ) const = 0; + virtual int ShaderStateCount( ) const = 0; + virtual void CreateDebugMaterials() = 0; + virtual void CleanUpDebugMaterials() = 0; + virtual void InitShaderParameters( IShader *pShader, IMaterialVar **params, const char *pMaterialName ) = 0; + virtual void InitShaderInstance( IShader *pShader, IMaterialVar **params, const char *pMaterialName, const char *pTextureGroupName ) = 0; + virtual bool InitRenderState( IShader *pShader, int numParams, IMaterialVar **params, ShaderRenderState_t* pRenderState, char const* pMaterialName ) = 0; + virtual void CleanupRenderState( ShaderRenderState_t* pRenderState ) = 0; + + virtual void DrawElements( IShader *pShader, IMaterialVar **params, ShaderRenderState_t* pShaderState, VertexCompressionType_t vertexCompression, + uint32 nMaterialVarTimeStamp ) = 0; + + virtual int ShaderCount() const = 0; + virtual int GetShaders( int nFirstShader, int nCount, IShader **ppShaderList ) const = 0; +}; + +#define SHADERSYSTEM_INTERFACE_VERSION "ShaderSystem002" + + diff --git a/game/client/vance/hud_weaponselection.cpp b/game/client/vance/hud_weaponselection.cpp index be315ba3..74de0913 100644 --- a/game/client/vance/hud_weaponselection.cpp +++ b/game/client/vance/hud_weaponselection.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -60,7 +60,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void SelectWeaponSlot( int iSlot ); virtual C_BaseCombatWeapon *GetSelectedWeapon( void ) - { + { return m_hSelectedWeapon; } @@ -75,7 +75,7 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel virtual void ApplySchemeSettings(vgui::IScheme *pScheme); virtual bool IsWeaponSelectable() - { + { if (IsInSelectionMode()) return true; @@ -110,17 +110,17 @@ class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel void ActivateWeaponHighlight( C_BaseCombatWeapon *pWeapon ); float GetWeaponBoxAlpha( bool bSelected ); int GetLastPosInSlot( int iSlot ) const; - + void FastWeaponSwitch( int iWeaponSlot ); void PlusTypeFastWeaponSwitch( int iWeaponSlot ); - virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) - { + virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon ) + { m_hSelectedWeapon = pWeapon; } - virtual void SetSelectedSlot( int slot ) - { + virtual void SetSelectedSlot( int slot ) + { m_iSelectedSlot = slot; } @@ -271,7 +271,7 @@ bool CHudWeaponSelection::ShouldDraw() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CHudWeaponSelection::LevelInit() { @@ -473,7 +473,7 @@ void CHudWeaponSelection::Paint() // interpolate the selected box size between the small box size and the large box size // interpolation has been removed since there is no weapon pickup animation anymore, so it's all at the largest size - float percentageDone = 1.0f; //min(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); + float percentageDone = 1.0f; //MIN(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime); int largeBoxWide = m_flSmallBoxSize + ( ( m_flLargeBoxWide - m_flSmallBoxSize) * percentageDone ); int largeBoxTall = m_flSmallBoxSize + ( ( m_flLargeBoxTall - m_flSmallBoxSize) * percentageDone ); Color selectedColor; @@ -655,14 +655,14 @@ void CHudWeaponSelection::Paint() } // Draw the box with the appropriate icon - DrawLargeWeaponBox( pWeapon, - selectedWeapon, - x, - y, - boxWide, - boxTall, - selectedWeapon ? selectedColor : m_BoxColor, - GetWeaponBoxAlpha( selectedWeapon ), + DrawLargeWeaponBox( pWeapon, + selectedWeapon, + x, + y, + boxWide, + boxTall, + selectedWeapon ? selectedColor : m_BoxColor, + GetWeaponBoxAlpha( selectedWeapon ), -1 ); } } @@ -700,14 +700,14 @@ void CHudWeaponSelection::Paint() else { bool bSelected = ( pWeapon == pSelectedWeapon ); - DrawLargeWeaponBox( pWeapon, - bSelected, - xpos, - ypos, - largeBoxWide, - largeBoxTall, - bSelected ? selectedColor : m_BoxColor, - GetWeaponBoxAlpha( bSelected ), + DrawLargeWeaponBox( pWeapon, + bSelected, + xpos, + ypos, + largeBoxWide, + largeBoxTall, + bSelected ? selectedColor : m_BoxColor, + GetWeaponBoxAlpha( bSelected ), bDrawBucketNumber ? i + 1 : -1 ); } @@ -762,7 +762,7 @@ void CHudWeaponSelection::Paint() void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int xpos, int ypos, int boxWide, int boxTall, Color selectedColor, float alpha, int number ) { Color col = bSelected ? m_SelectedFgColor : GetFgColor(); - + switch ( hud_fastswitch.GetInt() ) { case HUDTYPE_BUCKETS: @@ -804,7 +804,7 @@ void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool // draw an active version over the top pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col ); } - + // draw the inactive version pWeapon->GetSpriteInactive()->DrawSelf( xpos + x_offs, ypos + y_offs, col ); } @@ -950,7 +950,7 @@ void CHudWeaponSelection::ApplySchemeSettings(vgui::IScheme *pScheme) if ( hud_fastswitch.GetInt() == HUDTYPE_CAROUSEL ) { - // need bounds to be exact width for proper clipping during scroll + // need bounds to be exact width for proper clipping during scroll int width = MAX_CAROUSEL_SLOTS * m_flLargeBoxWide + ( MAX_CAROUSEL_SLOTS - 1 ) * m_flBoxGap; SetBounds( ( screenWide - width ) / 2, y, width, screenTall - y ); } @@ -1217,7 +1217,7 @@ int CHudWeaponSelection::GetLastPosInSlot( int iSlot ) const for ( int i = 0; i < MAX_WEAPONS; i++ ) { C_BaseCombatWeapon *pWeapon = player->GetWeapon(i); - + if ( pWeapon == NULL ) continue; @@ -1330,7 +1330,7 @@ void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot ) int increment = 1; if ( m_iSelectedSlot != iWeaponSlot ) { - // Decrementing within the slot. If we're at the zero position in this slot, + // Decrementing within the slot. If we're at the zero position in this slot, // jump to the zero position of the opposite slot. This also counts as our increment. increment = -1; if ( 0 == m_iSelectedBoxPosition ) @@ -1403,7 +1403,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) // Don't try and read past our possible number of slots if ( iSlot >= MAX_WEAPON_SLOTS ) return; - + // Make sure the player's allowed to switch weapons if ( pPlayer->IsAllowedToSwitchWeapons() == false ) return; @@ -1423,7 +1423,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) FastWeaponSwitch( iSlot ); return; } - + case HUDTYPE_PLUS: { if ( !IsInSelectionMode() ) @@ -1436,7 +1436,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) // Play the "move weapon selection" sound pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" ); } - + PlusTypeFastWeaponSwitch( iSlot ); ActivateWeaponHighlight( GetSelectedWeapon() ); } @@ -1459,7 +1459,7 @@ void CHudWeaponSelection::SelectWeaponSlot( int iSlot ) { pActiveWeapon = GetNextActivePos( iSlot, 0 ); } - + if ( pActiveWeapon != NULL ) { if ( !IsInSelectionMode() ) diff --git a/game/client/vance/shader_override.cpp b/game/client/vance/shader_override.cpp new file mode 100644 index 00000000..107e3582 --- /dev/null +++ b/game/client/vance/shader_override.cpp @@ -0,0 +1,168 @@ +#include "cbase.h" +#include "cdll_client_int.h" +#include "filesystem.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/materialsystem_config.h" +#include "shaderapi/IShaderDevice.h" +#include "hook/IShaderSystemInternal.h" +#include "hook/CHardwareConfig.h" + + +CUtlString GetModulePath( const char *pszModuleName, const char *pszPathId ) +{ + CUtlString modulePath; + modulePath.SetLength( MAX_PATH ); + filesystem->GetSearchPath( pszPathId, false, modulePath.Get(), MAX_PATH ); + + V_AppendSlash( modulePath.Get(), MAX_PATH ); + V_strcat( modulePath.Get(), pszModuleName, MAX_PATH ); + V_strcat( modulePath.Get(), DLL_EXT_STRING, MAX_PATH ); + + return modulePath; +} + +IShaderDevice *ShaderDevice() +{ + static IShaderDevice *pShaderDevice = nullptr; + if ( !pShaderDevice ) + { + CSysModule *pModule = nullptr; + Sys_LoadInterface( "shaderapidx9" DLL_EXT_STRING, SHADER_DEVICE_INTERFACE_VERSION, + &pModule, reinterpret_cast( &pShaderDevice ) ); + } + return pShaderDevice; +} + +IShaderSystem *ShaderSystem() +{ + static IShaderSystem *pShaderSystem = nullptr; + if ( !pShaderSystem ) + { + CSysModule *pModule = nullptr; + Sys_LoadInterface( "materialsystem" DLL_EXT_STRING, SHADERSYSTEM_INTERFACE_VERSION, + &pModule, reinterpret_cast( &pShaderSystem ) ); + } + return pShaderSystem; +} + +// Get the private shader system interface. +// Needed to override shaders. +IShaderSystemInternal *ShaderSystemInternal() +{ + return static_cast( ShaderSystem() ); +} + +// Special class to override any ConVar. It's named +// CCvar as ConVar is already friends with a class +// of such a name. +class CCvar : public ConVar +{ +public: + + void Override( const char *pName, const char *pDefaultValue, int flags = 0, + const char *pHelpString = NULL, bool bMin = false, float fMin = 0.0, + bool bMax = false, float fMax = false, FnChangeCallback_t callback = NULL ) + { + // Name should be static data + SetDefault( pDefaultValue ); + + // Deallocate what was previously allocated for + // the cvar we're overriding. + if ( m_pszString ) + { + delete[] m_pszString; + } + + m_StringLength = V_strlen( m_pszDefaultValue ) + 1; + m_pszString = new char[m_StringLength]; + memcpy( m_pszString, m_pszDefaultValue, m_StringLength ); + + m_bHasMin = bMin; + m_fMinVal = fMin; + m_bHasMax = bMax; + m_fMaxVal = fMax; + + m_fnChangeCallback = callback; + + m_fValue = ( float )atof( m_pszString ); + m_nValue = atoi( m_pszString ); // dont convert from float to int and lose bits + } + +}; + +void OverrideDxLevel( MaterialSystem_Config_t &videoConfig ) +{ + ConVar *mat_dxlevel = cvar->FindVar( "mat_dxlevel" ); + if ( mat_dxlevel ) + { + CCvar &override = reinterpret_cast( *mat_dxlevel ); + override.Override( "mat_dxlevel", MAT_DXLEVEL_OVERRIDE_S, + FCVAR_UNREGISTERED, "", true, ABSOLUTE_MINIMUM_DXLEVEL, + true, MAT_DXLEVEL_OVERRIDE ); + + override.SetValue( MAT_DXLEVEL_OVERRIDE ); + } + + videoConfig.dxSupportLevel = MAT_DXLEVEL_OVERRIDE; + + CommandLine()->AppendParm( "-dxlevel", MAT_DXLEVEL_OVERRIDE_S ); +} + +// - Sets the maximum number of pixel shader constants to 224 +// - Force mat_dxlevel to 100 +void OverrideHardwareCaps() +{ + if ( g_pMaterialSystemHardwareConfig ) + { + CHardwareConfig *pHardwareConfig = static_cast( g_pMaterialSystemHardwareConfig ); + CHardwareConfig::OverrideHardwareCaps( pHardwareConfig ); + } + + MaterialSystem_Config_t videoConfig = materials->GetCurrentConfigForVideoCard(); + + // Regardless of whether -vulkan is used or not, + // the engine still employs some stupid abstract + // limitations on POSIX, like forcing mat_dxlevel + // to be between 90 and 92. + if ( IsPosix() ) + { + OverrideDxLevel( videoConfig ); + } + + videoConfig.m_nReserved++; + materials->OverrideConfig( videoConfig, true ); +} + +// Unloads Valve's shader DLL. +void UnloadShaderDLL() +{ + if ( ShaderSystemInternal() ) + { + CUtlString modulePath = GetModulePath( "stdshader_dx9", "EXECUTABLE_PATH" ); + ShaderSystemInternal()->UnloadShaderDLL( modulePath ); + } +} + +// Loads a shader DLL from gamebin. The loaded +// DLL will override any existing shaders. +void OverrideShaderDLL() +{ + if ( ShaderSystemInternal() ) + { + CUtlString modulePath = GetModulePath( "game_shader", "GAMEBIN" ); + ShaderSystemInternal()->LoadShaderDLL( modulePath ); + } +} + +// Handles all the shader overriding stuff. Ideally +// called before or within modemanager->Init(). +void OverrideShaders() +{ + //Msg( "[Shaders] Overwrote stock shaders.\n" ); + + //UnloadShaderDLL(); + + OverrideHardwareCaps(); + + OverrideShaderDLL(); +} \ No newline at end of file diff --git a/game/client/vance/shader_override.h b/game/client/vance/shader_override.h new file mode 100644 index 00000000..db72f7bb --- /dev/null +++ b/game/client/vance/shader_override.h @@ -0,0 +1,7 @@ +#pragma once +#include "shaderapi/IShaderDevice.h" + +void OverrideShaders(); +void OverrideHardwareCaps(); + +IShaderDevice *ShaderDevice(); diff --git a/game/client/vance/vis.cpp b/game/client/vance/vis.cpp new file mode 100644 index 00000000..8a004335 --- /dev/null +++ b/game/client/vance/vis.cpp @@ -0,0 +1,861 @@ +#include "cbase.h" +#include "filesystem.h" +#include "lumpfiles.h" +#include "tier1/memstack.h" + +#include "tier0/memdbgon.h" + +#pragma region CORE +static CMemoryStack g_MemStack; +template static T* Hunk_Alloc( size_t s, bool clear = true ) +{ + return static_cast( g_MemStack.Alloc( s, clear ) ); +} + +static void CM_LoadMap( const char *name ); +static void CM_FreeMap(); +static class TEST : public CAutoGameSystem +{ +public: + TEST() : CAutoGameSystem( "visMemoryManager" ) {} + + bool Init() OVERRIDE + { + const int nMaxBytes = 48 * 1024 * 1024; + const int nMinCommitBytes = 0x8000; + const int nInitialCommit = 0x280000; + g_MemStack.Init( nMaxBytes, nMinCommitBytes, nInitialCommit ); + return true; + } + + void Shutdown() OVERRIDE + { + g_MemStack.FreeAll(); + } + + void LevelInitPostEntity() OVERRIDE + { + CM_LoadMap( VarArgs( "maps/%s.bsp", MapName() ) ); + } + + void LevelShutdownPreEntity() OVERRIDE + { + CM_FreeMap(); + } + +} memManager; + +void GetMapNameOnDisk( char *pDiskName, const char *pFullMapName, unsigned int nDiskNameSize ) +{ + if ( pFullMapName != pDiskName ) + { + V_strncpy( pDiskName, pFullMapName, nDiskNameSize ); + } +} + +void GenerateLumpFileName( const char *bspfilename, char *lumpfilename, int iBufferSize, int iIndex ) +{ + char lumppre[MAX_PATH]; + V_StripExtension( bspfilename, lumppre, MAX_PATH ); + Q_snprintf( lumpfilename, iBufferSize, "%s_l_%d.lmp", lumppre, iIndex ); +} + +template +class CRangeValidatedArray +{ +public: + void Attach( int nCount, T* pData ) + { + m_pArray = pData; + +#ifdef _DEBUG + m_nCount = nCount; +#endif + } + + void Detach() + { + m_pArray = NULL; + +#ifdef _DEBUG + m_nCount = 0; +#endif + } + + T &operator[]( int i ) + { + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pArray[i]; + } + + const T &operator[]( int i ) const + { + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pArray[i]; + } + + T *Base() + { + return m_pArray; + } + +private: + T *m_pArray; + +#ifdef _DEBUG + int m_nCount; +#endif +}; + +struct cnode_t +{ + cplane_t *plane; + int children[2]; // negative numbers are leafs +}; +struct cleaf_t +{ + int contents; + short cluster; + short area : 9; + short flags : 7; + unsigned short firstleafbrush; + unsigned short numleafbrushes; + unsigned short dispListStart; + unsigned short dispCount; +}; + +class CCollisionBSPData +{ +public: + // This is sort of a hack, but it was a little too painful to do this any other way + // The goal of this dude is to allow us to override the tree with some + // other tree (or a subtree) + cnode_t* map_rootnode; + + int numplanes; + CRangeValidatedArray map_planes; + int numnodes; + CRangeValidatedArray map_nodes; + int numleafs; // allow leaf funcs to be called without a map + CRangeValidatedArray map_leafs; + int emptyleaf, solidleaf; + + // this points to the whole block of memory for vis data, but it is used to + // reference the header at the top of the block. + int numvisibility; + dvis_t *map_vis; + + int numclusters; +}; + +class CMapLoadHelper +{ +public: + CMapLoadHelper( int lumpToLoad ) + { + if ( lumpToLoad < 0 || lumpToLoad >= HEADER_LUMPS ) + { + Warning( "Can't load lump %i, range is 0 to %i!!!", lumpToLoad, HEADER_LUMPS - 1 ); + } + + m_nLumpID = lumpToLoad; + m_pData = NULL; + m_pRawData = NULL; + + // Load raw lump from disk + lump_t *lump = &s_MapHeader.lumps[ lumpToLoad ]; + Assert( lump ); + + m_nLumpSize = lump->filelen; + m_nLumpOffset = lump->fileofs; + m_nLumpVersion = lump->version; + + const FileHandle_t fileToUse = s_MapFileHandle; + + if ( !m_nLumpSize ) + { + // this lump has no data + return; + } + + if ( s_MapFileHandle == FILESYSTEM_INVALID_HANDLE ) + { + Warning( "Can't load map from invalid handle!!!" ); + } + + unsigned nOffsetAlign, nSizeAlign, nBufferAlign; + filesystem->GetOptimalIOConstraints( fileToUse, &nOffsetAlign, &nSizeAlign, &nBufferAlign ); + + const bool bTryOptimal = ( m_nLumpOffset % 4 == 0 ); // Don't return badly aligned data + unsigned int alignedOffset = m_nLumpOffset; + unsigned int alignedBytesToRead = ( ( m_nLumpSize ) ? m_nLumpSize : 1 ); + + if ( bTryOptimal ) + { + alignedOffset = AlignValue( ( alignedOffset - nOffsetAlign ) + 1, nOffsetAlign ); + alignedBytesToRead = AlignValue( ( m_nLumpOffset - alignedOffset ) + alignedBytesToRead, nSizeAlign ); + } + + m_pRawData = static_cast( filesystem->AllocOptimalReadBuffer( fileToUse, alignedBytesToRead, alignedOffset ) ); + if ( !m_pRawData && m_nLumpSize ) + { + Warning( "Can't load lump %i, allocation of %i bytes failed!!!", lumpToLoad, m_nLumpSize + 1 ); + } + + if ( m_nLumpSize ) + { + filesystem->Seek( fileToUse, alignedOffset, FILESYSTEM_SEEK_HEAD ); + filesystem->ReadEx( m_pRawData, alignedBytesToRead, alignedBytesToRead, fileToUse ); + m_pData = m_pRawData + ( m_nLumpOffset - alignedOffset ); + } + } + + ~CMapLoadHelper() + { + if ( m_pRawData ) + { + filesystem->FreeOptimalReadBuffer( m_pRawData ); + } + } + + byte *LumpBase() const + { + return m_pData; + } + + int LumpSize() const + { + return m_nLumpSize; + } + + int LumpOffset() const + { + return m_nLumpOffset; + } + + int LumpVersion() const + { + return m_nLumpVersion; + } + + // Global setup/shutdown + static void Init( const char *loadname ) + { + if ( ++s_nMapLoadRecursion > 1 ) + { + return; + } + + s_MapFileHandle = FILESYSTEM_INVALID_HANDLE; + V_memset( &s_MapHeader, 0, sizeof( s_MapHeader ) ); + + V_strcpy_safe( s_szLoadName, loadname ); + s_MapFileHandle = filesystem->OpenEx( loadname, "rb" ); + if ( s_MapFileHandle == FILESYSTEM_INVALID_HANDLE ) + { + Warning( "CMapLoadHelper::Init, unable to open %s\n", loadname ); + return; + } + + filesystem->Read( &s_MapHeader, sizeof( dheader_t ), s_MapFileHandle ); + if ( s_MapHeader.ident != IDBSPHEADER ) + { + filesystem->Close( s_MapFileHandle ); + s_MapFileHandle = FILESYSTEM_INVALID_HANDLE; + Warning( "CMapLoadHelper::Init, map %s has wrong identifier\n", loadname ); + return; + } + + if ( s_MapHeader.version < MINBSPVERSION || s_MapHeader.version > BSPVERSION ) + { + filesystem->Close( s_MapFileHandle ); + s_MapFileHandle = FILESYSTEM_INVALID_HANDLE; + Warning( "CMapLoadHelper::Init, map %s has wrong version (%i when expecting %i)\n", loadname, + s_MapHeader.version, BSPVERSION ); + } + } + + static void Shutdown() + { + if ( --s_nMapLoadRecursion > 0 ) + { + return; + } + + if ( s_MapFileHandle != FILESYSTEM_INVALID_HANDLE ) + { + filesystem->Close( s_MapFileHandle ); + s_MapFileHandle = FILESYSTEM_INVALID_HANDLE; + } + + s_szLoadName[ 0 ] = 0; + V_memset( &s_MapHeader, 0, sizeof( s_MapHeader ) ); + } + + // Returns the size of a particular lump without loading it + static int LumpSize( int lumpId ) + { + lump_t *pLump = &s_MapHeader.lumps[ lumpId ]; + Assert( pLump ); + + return pLump->filelen; + } + + static int LumpOffset( int lumpId ) + { + lump_t *pLump = &s_MapHeader.lumps[ lumpId ]; + Assert( pLump ); + + return pLump->fileofs; + } + + // Loads one element in a lump. + void LoadLumpElement( int nElemIndex, int nElemSize, void *pData ) const + { + if ( !nElemSize || !m_nLumpSize ) + { + return; + } + + // supply from memory + if ( nElemIndex * nElemSize + nElemSize <= m_nLumpSize ) + { + V_memcpy( pData, m_pData + nElemIndex * nElemSize, nElemSize ); + } + else + { + // out of range + Assert( 0 ); + } + } + + void LoadLumpData( int offset, int size, void *pData ) const + { + if ( !size || !m_nLumpSize ) + { + return; + } + + if ( offset + size <= m_nLumpSize ) + { + V_memcpy( pData, m_pData + offset, size ); + } + else + { + // out of range + Assert( 0 ); + } + } + +private: + int m_nLumpSize; + int m_nLumpOffset; + int m_nLumpVersion; + byte *m_pRawData; + byte *m_pData; + + // Handling for lump files + int m_nLumpID; + + static dheader_t s_MapHeader; + static FileHandle_t s_MapFileHandle; + static char s_szLoadName[64]; + static int s_nMapLoadRecursion; +}; +dheader_t CMapLoadHelper::s_MapHeader; +FileHandle_t CMapLoadHelper::s_MapFileHandle = FILESYSTEM_INVALID_HANDLE; +char CMapLoadHelper::s_szLoadName[64]; +int CMapLoadHelper::s_nMapLoadRecursion = 0; + +static void CollisionBSPData_LoadLeafs( CCollisionBSPData* ); +static void CollisionBSPData_LoadVisibility( CCollisionBSPData* ); +static void CollisionBSPData_LoadNodes( CCollisionBSPData* ); +static void CollisionBSPData_LoadPlanes( CCollisionBSPData* ); +static bool CollisionBSPData_Load( CCollisionBSPData *pBSPData ) +{ + COM_TimestampedLog( " CollisionBSPData_LoadPlanes" ); + CollisionBSPData_LoadPlanes( pBSPData ); + + COM_TimestampedLog( " CollisionBSPData_LoadNodes" ); + CollisionBSPData_LoadNodes( pBSPData ); + + COM_TimestampedLog( " CollisionBSPData_LoadLeafs" ); + CollisionBSPData_LoadLeafs( pBSPData ); + + COM_TimestampedLog( " CollisionBSPData_LoadVisibility" ); + CollisionBSPData_LoadVisibility( pBSPData ); + + return true; +} + +static void CollisionBSPData_LoadLeafs_Version_0( CCollisionBSPData *pBSPData, CMapLoadHelper &lh ) +{ + dleaf_version_0_t *in = reinterpret_cast( lh.LumpBase() ); + if ( lh.LumpSize() % sizeof( dleaf_version_0_t ) ) + Warning( "CollisionBSPData_LoadLeafs: funny lump size"); + + const int count = lh.LumpSize() / sizeof( dleaf_version_0_t ); + + if (count < 1) + Warning( "Map with no leafs"); + + // need to save space for box planes + if (count > MAX_MAP_PLANES) + Warning( "Map has too many planes"); + + // Need an extra one for the emptyleaf below + const int nSize = (count + 1) * sizeof(cleaf_t); + pBSPData->map_leafs.Attach( count + 1, Hunk_Alloc( nSize ) ); + + pBSPData->numleafs = count; + pBSPData->numclusters = 0; + + for ( int i = 0 ; imap_leafs[i]; + out->contents = in->contents; + out->cluster = in->cluster; + out->area = in->area; + out->flags = in->flags; + out->firstleafbrush = in->firstleafbrush; + out->numleafbrushes = in->numleafbrushes; + + out->dispCount = 0; + + if (out->cluster >= pBSPData->numclusters) + { + pBSPData->numclusters = out->cluster + 1; + } + } + + if (pBSPData->map_leafs[0].contents != CONTENTS_SOLID) + Warning( "Map leaf 0 is not CONTENTS_SOLID"); + + pBSPData->solidleaf = 0; + pBSPData->emptyleaf = pBSPData->numleafs; + V_memset( &pBSPData->map_leafs[pBSPData->emptyleaf], 0, sizeof(pBSPData->map_leafs[pBSPData->emptyleaf]) ); + pBSPData->numleafs++; +} + +static void CollisionBSPData_LoadLeafs_Version_1( CCollisionBSPData *pBSPData, CMapLoadHelper &lh ) +{ + dleaf_t *in = reinterpret_cast( lh.LumpBase() ); + if ( lh.LumpSize() % sizeof( dleaf_t ) ) + Warning( "CollisionBSPData_LoadLeafs: funny lump size"); + + const int count = lh.LumpSize() / sizeof( dleaf_t ); + + if (count < 1) + Warning( "Map with no leafs"); + + // need to save space for box planes + if (count > MAX_MAP_PLANES) + Warning( "Map has too many planes"); + + // Need an extra one for the emptyleaf below + const int nSize = (count + 1) * sizeof(cleaf_t); + pBSPData->map_leafs.Attach( count + 1, Hunk_Alloc( nSize ) ); + + pBSPData->numleafs = count; + pBSPData->numclusters = 0; + + for ( int i = 0 ; imap_leafs[i]; + out->contents = in->contents; + out->cluster = in->cluster; + out->area = in->area; + out->flags = in->flags; + out->firstleafbrush = in->firstleafbrush; + out->numleafbrushes = in->numleafbrushes; + + out->dispCount = 0; + + if (out->cluster >= pBSPData->numclusters) + { + pBSPData->numclusters = out->cluster + 1; + } + } + + if (pBSPData->map_leafs[0].contents != CONTENTS_SOLID) + Warning( "Map leaf 0 is not CONTENTS_SOLID"); + + pBSPData->solidleaf = 0; + pBSPData->emptyleaf = pBSPData->numleafs; + V_memset( &pBSPData->map_leafs[pBSPData->emptyleaf], 0, sizeof(pBSPData->map_leafs[pBSPData->emptyleaf]) ); + pBSPData->numleafs++; +} + +static void CollisionBSPData_LoadLeafs( CCollisionBSPData *pBSPData ) +{ + CMapLoadHelper lh( LUMP_LEAFS ); + switch( lh.LumpVersion() ) + { + case 0: + CollisionBSPData_LoadLeafs_Version_0( pBSPData, lh ); + break; + case 1: + CollisionBSPData_LoadLeafs_Version_1( pBSPData, lh ); + break; + default: + Assert( 0 ); + Warning( "Unknown LUMP_LEAFS version\n" ); + break; + } +} + +static void CollisionBSPData_LoadVisibility( CCollisionBSPData *pBSPData ) +{ + CMapLoadHelper lh( LUMP_VISIBILITY ); + + pBSPData->numvisibility = lh.LumpSize(); + if ( lh.LumpSize() > MAX_MAP_VISIBILITY ) + Warning( "Map has too large visibility lump" ); + + int visDataSize = lh.LumpSize(); + if ( visDataSize == 0 ) + { + pBSPData->map_vis = NULL; + } + else + { + pBSPData->map_vis = Hunk_Alloc( visDataSize, false ); + V_memcpy( pBSPData->map_vis, lh.LumpBase(), visDataSize ); + } +} + +static void CollisionBSPData_LoadNodes( CCollisionBSPData *pBSPData ) +{ + CMapLoadHelper lh( LUMP_NODES ); + + dnode_t *in = reinterpret_cast( lh.LumpBase() ); + if ( lh.LumpSize() % sizeof( dnode_t ) ) + Warning( "CollisionBSPData_LoadNodes: funny lump size" ); + const int count = lh.LumpSize() / sizeof( dnode_t ); + + if ( count < 1 ) + Warning( "Map has no nodes" ); + + if ( count > MAX_MAP_NODES ) + Warning( "Map has too many nodes" ); + + // 6 extra for box hull + const int nSize = ( count + 6 ) * sizeof( cnode_t ); + pBSPData->map_nodes.Attach( count + 6, Hunk_Alloc( nSize ) ); + + pBSPData->numnodes = count; + pBSPData->map_rootnode = pBSPData->map_nodes.Base(); + + for ( int i = 0; imap_nodes[i]; + out->plane = &pBSPData->map_planes[in->planenum]; + for ( int j = 0; j<2; j++ ) + { + out->children[j] = in->children[j]; + } + } +} + +static void CollisionBSPData_LoadPlanes( CCollisionBSPData *pBSPData ) +{ + CMapLoadHelper lh( LUMP_PLANES ); + + dplane_t *in = reinterpret_cast( lh.LumpBase() ); + if ( lh.LumpSize() % sizeof( dplane_t ) ) + Warning( "CollisionBSPData_LoadPlanes: funny lump size" ); + + const int count = lh.LumpSize() / sizeof( dplane_t ); + + if ( count < 1 ) + Warning( "Map with no planes" ); + + // need to save space for box planes + if ( count > MAX_MAP_PLANES ) + Warning( "Map has too many planes" ); + + const int nSize = count * sizeof( cplane_t ); + pBSPData->map_planes.Attach( count, Hunk_Alloc( nSize ) ); + pBSPData->numplanes = count; + + for ( int i = 0; imap_planes[i]; + int bits = 0; + for ( int j = 0; j<3; j++ ) + { + out->normal[j] = in->normal[j]; + if ( out->normal[j] < 0 ) + { + bits |= 1 << j; + } + } + + out->dist = in->dist; + out->type = in->type; + out->signbits = bits; + } +} + +static bool CollisionBSPData_Init( CCollisionBSPData *pBSPData ) +{ + pBSPData->numleafs = 1; + pBSPData->map_vis = NULL; + pBSPData->numclusters = 1; + + return true; +} + +static void CollisionBSPData_PreLoad( CCollisionBSPData *pBSPData ) +{ + // initialize the collision bsp data + CollisionBSPData_Init( pBSPData ); +} + +static CCollisionBSPData* GetCollisionBSPData() +{ + static CCollisionBSPData data; + return &data; +} + +static void CM_FreeMap() +{ + // get the current collision bsp -- there is only one! + CCollisionBSPData *pBSPData = GetCollisionBSPData(); + + if ( pBSPData->map_planes.Base() ) + { + pBSPData->map_planes.Detach(); + } + + if ( pBSPData->map_leafs.Base() ) + { + pBSPData->map_leafs.Detach(); + } + + if ( pBSPData->map_nodes.Base() ) + { + pBSPData->map_nodes.Detach(); + } + + if ( pBSPData->map_vis ) + { + pBSPData->map_vis = NULL; + } + + pBSPData->numplanes = 0; + pBSPData->emptyleaf = 0; + pBSPData->solidleaf = 0; + pBSPData->numnodes = 0; + pBSPData->numleafs = 0; + pBSPData->numclusters = 0; + pBSPData->numvisibility = 0; + pBSPData->map_rootnode = NULL; +} + +static void CM_LoadMap( const char *name ) +{ + // get the current bsp -- there is currently only one! + CCollisionBSPData *pBSPData = GetCollisionBSPData(); + + Assert( physcollision ); + + // only pre-load if the map doesn't already exist + CollisionBSPData_PreLoad( pBSPData ); + + if ( !name || !name[0] ) + return; // cinematic servers won't have anything at all + + // read in the collision model data + CMapLoadHelper::Init( name ); + CollisionBSPData_Load( pBSPData ); + CMapLoadHelper::Shutdown( ); +} + +static int CM_NumClusters() +{ + return GetCollisionBSPData()->numclusters; +} + +static void CM_NullVis( CCollisionBSPData *pBSPData, byte *out ) +{ + int numClusterBytes = (pBSPData->numclusters+7)>>3; + byte *out_p = out; + + while (numClusterBytes) + { + *out_p++ = 0xff; + numClusterBytes--; + } +} + +static void CM_DecompressVis( CCollisionBSPData *pBSPData, int cluster, int visType, byte *out ) +{ + if ( !pBSPData ) + { + Assert( false ); // Shouldn't ever happen. + } + + if ( cluster > pBSPData->numclusters || cluster < 0 ) + { + // This can happen if this is called while the level is loading. See Map_VisCurrentCluster. + CM_NullVis( pBSPData, out ); + return; + } + + // no vis info, so make all visible + if ( !pBSPData->numvisibility || !pBSPData->map_vis ) + { + CM_NullVis( pBSPData, out ); + return; + } + + byte *in = reinterpret_cast( pBSPData->map_vis ) + pBSPData->map_vis->bitofs[cluster][visType]; + const int numClusterBytes = (pBSPData->numclusters+7)>>3; + byte *out_p = out; + + // no vis info, so make all visible + if ( !in ) + { + CM_NullVis( pBSPData, out ); + return; + } + + do + { + if (*in) + { + *out_p++ = *in++; + continue; + } + + int c = in[1]; + in += 2; + if ((out_p - out) + c > numClusterBytes) + { + c = numClusterBytes - (out_p - out); + DevWarning( "Vis decompression overrun\n" ); + } + while (c) + { + *out_p++ = 0; + c--; + } + } while (out_p - out < numClusterBytes); +} + +static void CM_Vis( byte *dest, int destlen, int cluster, int visType ) +{ + // get the current collision bsp -- there is only one! + CCollisionBSPData *pBSPData = GetCollisionBSPData(); + + if ( !dest || visType > 2 || visType < 0 ) + { + Warning( "CM_Vis: error"); + return; + } + + if ( cluster == -1 ) + { + const int len = (pBSPData->numclusters+7)>>3; + if ( len > destlen ) + { + Warning( "CM_Vis: buffer not big enough (%i but need %i)\n", + destlen, len ); + } + V_memset( dest, 0, (pBSPData->numclusters+7)>>3 ); + } + else + { + CM_DecompressVis( pBSPData, cluster, visType, dest ); + } +} + +static int CM_LeafCluster( int leafnum ) +{ + const CCollisionBSPData *pBSPData = GetCollisionBSPData(); + + Assert( leafnum >= 0 ); + Assert( leafnum < pBSPData->numleafs ); + + return pBSPData->map_leafs[leafnum].cluster; +} + +static int CM_PointLeafnum_r( CCollisionBSPData *pBSPData, const Vector& p, int num) +{ + float d; + while (num >= 0) + { + cnode_t *node = pBSPData->map_rootnode + num; + cplane_t *plane = node->plane; + + if (plane->type < 3) + d = p[plane->type] - plane->dist; + else + d = DotProduct (plane->normal, p) - plane->dist; + if (d < 0) + num = node->children[1]; + else + num = node->children[0]; + } + + return -1 - num; +} + +static int CM_PointLeafnum (const Vector& p) +{ + // get the current collision bsp -- there is only one! + CCollisionBSPData *pBSPData = GetCollisionBSPData(); + + if ( !pBSPData->numnodes ) + return 0; + + return CM_PointLeafnum_r(pBSPData, p, 0); +} +#pragma endregion + +int GetClusterForOrigin( const Vector& org ) +{ + return CM_LeafCluster( CM_PointLeafnum( org ) ); +} + +int GetPVSForCluster( int clusterIndex, int outputpvslength, unsigned char *outputpvs ) +{ + const int length = (CM_NumClusters()+7)>>3; + + if ( outputpvs ) + { + if ( outputpvslength < length ) + { + Warning( "GetPVSForOrigin called with inusfficient sized pvs array, need %i bytes!", length ); + return length; + } + + CM_Vis( outputpvs, outputpvslength, clusterIndex, DVIS_PVS ); + } + + return length; +} + +bool CheckOriginInPVS( const Vector& org, const unsigned char *checkpvs, int checkpvssize ) +{ + const int clusterIndex = GetClusterForOrigin( org ); + + if ( clusterIndex < 0 ) + return false; + + const int offset = clusterIndex>>3; + if ( offset > checkpvssize ) + { + Warning( "CheckOriginInPVS: cluster would read past end of pvs data (%i:%i)\n", + offset, checkpvssize ); + return false; + } + + if ( !(checkpvs[offset] & (1<<(clusterIndex&7)) ) ) + { + return false; + } + + return true; +} diff --git a/game/client/vance/vis.h b/game/client/vance/vis.h new file mode 100644 index 00000000..2768f679 --- /dev/null +++ b/game/client/vance/vis.h @@ -0,0 +1,8 @@ +#pragma once + +class Vector; + +int GetClusterForOrigin( const Vector& org ); +int GetPVSForCluster( int clusterIndex, int outputpvslength, unsigned char *outputpvs ); +bool CheckOriginInPVS( const Vector& org, const unsigned char *checkpvs, int checkpvssize ); + diff --git a/game/client/vance/worldlight.cpp b/game/client/vance/worldlight.cpp new file mode 100644 index 00000000..f24d89ab --- /dev/null +++ b/game/client/vance/worldlight.cpp @@ -0,0 +1,246 @@ +//========= Copyright (C) 2021, CSProMod Team, All rights reserved. =========// +// Written: November 2011 +// Author: Saul Rennison + +#include "cbase.h" +#include "bspfile.h" +#include "eiface.h" +#include "filesystem.h" +#include "worldlight.h" +#include "vis.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static float Engine_WorldLightDistanceFalloff( const dworldlight_t *wl, const Vector &delta ) +{ + float falloff; + + switch ( wl->type ) + { + case emit_surface: + // Cull out stuff that's too far + if ( wl->radius != 0 ) + { + if ( DotProduct( delta, delta ) > ( wl->radius * wl->radius ) ) + return 0.0f; + } + + return InvRSquared( delta ); + + case emit_skylight: + return 1.0f; + + case emit_quakelight: + // X - r; + falloff = wl->linear_attn - FastSqrt( DotProduct( delta, delta ) ); + if ( falloff < 0 ) + return 0.0f; + + return falloff; + + case emit_skyambient: + return 1.0f; + + case emit_point: + case emit_spotlight: // Directional & positional + { + float dist2, dist; + + dist2 = DotProduct( delta, delta ); + dist = FastSqrt( dist2 ); + + // Cull out stuff that's too far + if ( wl->radius != 0 && dist > wl->radius ) + return 0.0f; + + return 1.0f / ( wl->constant_attn + wl->linear_attn * dist + wl->quadratic_attn * dist2 ); + } + } + + return 1.0f; +} + +CWorldLights::CWorldLights() : CAutoGameSystem( "World lights" ) +{ + m_nWorldLights = 0; + m_pWorldLights = nullptr; +} + +void CWorldLights::Clear() +{ + m_nWorldLights = 0; + + if ( m_pWorldLights ) + { + delete[] m_pWorldLights; + m_pWorldLights = nullptr; + } +} + +bool CWorldLights::Init() +{ + return true; +} + +void CWorldLights::LevelInitPreEntity() +{ + // Get the map path + const char *pszMapName = modelinfo->GetModelName( modelinfo->GetModel( 1 ) ); + + // Open map + FileHandle_t hFile = g_pFullFileSystem->Open( pszMapName, "rb" ); + if ( !hFile ) + { + Warning( "CWorldLights: Unable to open map\n" ); + return; + } + + // Read the BSP header. We don't need to do any version checks, etc. as we + // can safely assume that the engine did this for us + dheader_t hdr; + g_pFullFileSystem->Read( &hdr, sizeof( hdr ), hFile ); + + // Grab the light lump and seek to it + lump_t &lightLump = hdr.lumps[LUMP_WORLDLIGHTS]; + + // If the worldlights lump is empty, that means theres no normal, LDR lights to extract + // This can happen when, for example, the map is compiled in HDR mode only + // So move on to the HDR worldlights lump + if ( lightLump.filelen == 0 ) + { + lightLump = hdr.lumps[LUMP_WORLDLIGHTS_HDR]; + } + + // If we can't divide the lump data into a whole number of worldlights, + // then the BSP format changed and we're unaware + if ( lightLump.filelen % sizeof( dworldlight_t ) ) + { + Warning( "CWorldLights: Unknown world light lump\n" ); + + // Close file + g_pFullFileSystem->Close( hFile ); + return; + } + + g_pFullFileSystem->Seek( hFile, lightLump.fileofs, FILESYSTEM_SEEK_HEAD ); + + // Allocate memory for the worldlights + m_nWorldLights = lightLump.filelen / sizeof( dworldlight_t ); + m_pWorldLights = new dworldlight_t[m_nWorldLights]; + + // Read worldlights then close + g_pFullFileSystem->Read( m_pWorldLights, lightLump.filelen, hFile ); + g_pFullFileSystem->Close( hFile ); + + DevMsg( "CWorldLights: Load successful (%d lights at 0x%p)\n", m_nWorldLights, m_pWorldLights ); +} + +bool CWorldLights::GetBrightestLightSource( const Vector &vecPosition, Vector &vecLightPos, Vector &vecLightBrightness ) +{ + if ( !m_nWorldLights || !m_pWorldLights ) + return false; + + // Default light position and brightness to zero + vecLightBrightness.Init(); + vecLightPos.Init(); + + // Find the size of the PVS for our current position + int nCluster = GetClusterForOrigin( vecPosition ); + int nPVSSize = GetPVSForCluster( nCluster, 0, nullptr ); + + // Get the PVS at our position + byte *pvs = new byte[nPVSSize]; + GetPVSForCluster( nCluster, nPVSSize, pvs ); + + // Iterate through all the worldlights + for ( int i = 0; i < m_nWorldLights; ++i ) + { + dworldlight_t *light = &m_pWorldLights[i]; + + // Skip skyambient + if ( light->type == emit_skyambient ) + { + continue; + } + + // Handle sun + if ( light->type == emit_skylight ) + { + // Calculate sun position + Vector vecAbsStart = vecPosition + Vector( 0, 0, 30 ); + Vector vecAbsEnd = vecAbsStart - ( light->normal * MAX_TRACE_LENGTH ); + + trace_t tr; + UTIL_TraceLine( vecPosition, vecAbsEnd, MASK_OPAQUE, nullptr, COLLISION_GROUP_NONE, &tr ); + + // If we didn't hit anything then we have a problem + if ( !tr.DidHit() ) + { + continue; + } + + // If we did hit something, and it wasn't the skybox, then skip + // this worldlight + if ( !( tr.surface.flags & SURF_SKY ) && !( tr.surface.flags & SURF_SKY2D ) ) + { + continue; + } + + // Act like we didn't find any valid worldlights, so the shadow + // manager uses the default shadow direction instead (should be the + // sun direction) + + delete[] pvs; + + return false; + } + + // Calculate square distance to this worldlight + Vector vecDelta = light->origin - vecPosition; + float flDistSqr = vecDelta.LengthSqr(); + float flRadiusSqr = light->radius * light->radius; + + // Skip lights that are out of our radius + if ( flRadiusSqr > 0 && flDistSqr >= flRadiusSqr ) + { + continue; + } + + // Is it out of our PVS? + if ( !CheckOriginInPVS( light->origin, pvs, nPVSSize ) ) + { + continue; + } + + // Calculate intensity at our position + float flRatio = Engine_WorldLightDistanceFalloff( light, vecDelta ); + Vector vecIntensity = light->intensity * flRatio; + + // Is this light more intense than the one we already found? + if ( vecIntensity.LengthSqr() <= vecLightBrightness.LengthSqr() ) + { + continue; + } + + // Can we see the light? + trace_t tr; + Vector vecAbsStart = vecPosition + Vector( 0, 0, 30 ); + UTIL_TraceLine( vecAbsStart, light->origin, MASK_OPAQUE, nullptr, COLLISION_GROUP_NONE, &tr ); + + if ( tr.DidHit() ) + { + continue; + } + + vecLightPos = light->origin; + vecLightBrightness = vecIntensity; + } + + delete[] pvs; + + return !vecLightBrightness.IsZero(); +} + +static CWorldLights s_WorldLights; +CWorldLights *g_pWorldLights = &s_WorldLights; diff --git a/game/client/vance/worldlight.h b/game/client/vance/worldlight.h new file mode 100644 index 00000000..0640127e --- /dev/null +++ b/game/client/vance/worldlight.h @@ -0,0 +1,31 @@ +//========= Copyright (C) 2021, CSProMod Team, All rights reserved. =========// +// Written: November 2011 +// Author: Saul Rennison +#pragma once + +#include "igamesystem.h" + +class Vector; +struct dworldlight_t; + +class CWorldLights : public CAutoGameSystem +{ +public: + CWorldLights(); + ~CWorldLights() { Clear(); } + + bool GetBrightestLightSource( const Vector &vecPosition, Vector &vecLightPos, Vector &vecLightBrightness ); + + bool Init() override; + void LevelInitPreEntity() override; + void LevelShutdownPostEntity() override { Clear(); } + +private: + void Clear(); + + int m_nWorldLights; + dworldlight_t *m_pWorldLights; +}; + +// Singleton accessor +extern CWorldLights *g_pWorldLights; diff --git a/game/client/vgui_debugoverlaypanel.cpp b/game/client/vgui_debugoverlaypanel.cpp index 696ea292..2460ffa0 100644 --- a/game/client/vgui_debugoverlaypanel.cpp +++ b/game/client/vgui_debugoverlaypanel.cpp @@ -76,7 +76,7 @@ void CDebugOverlay::ApplySchemeSettings(vgui::IScheme *pScheme) // Use a large font // m_hFont = pScheme->GetFont( "Default" ); - m_hFont = pScheme->GetFont( "DebugOverlay", true ); + m_hFont = pScheme->GetFont( "DebugOverlay" ); assert( m_hFont ); int w, h; @@ -129,7 +129,7 @@ void CDebugOverlay::Paint() { float xPos = screenPos[0]; float yPos = screenPos[1]+ (pCurrText->lineOffset*13); // Line spacing; - g_pMatSystemSurface->DrawColoredText( m_hFont, xPos, yPos, r, g, b, a, pCurrText->text ); + g_pMatSystemSurface->DrawColoredText( m_hFont, xPos, yPos, r, g, b, a, "%s", pCurrText->text ); } } else @@ -138,7 +138,7 @@ void CDebugOverlay::Paint() { float xPos = screenPos[0]; float yPos = screenPos[1]+ (pCurrText->lineOffset*13); // Line spacing; - g_pMatSystemSurface->DrawColoredText( m_hFont, xPos, yPos, r, g, b, a, pCurrText->text ); + g_pMatSystemSurface->DrawColoredText( m_hFont, xPos, yPos, r, g, b, a, "%s", pCurrText->text ); } } } @@ -166,8 +166,7 @@ class CDebugOverlayPanel : public IDebugOverlayPanel if ( debugOverlayPanel ) { debugOverlayPanel->SetParent( (vgui::Panel *)NULL ); - debugOverlayPanel->MarkForDeletion(); - debugOverlayPanel = NULL; + delete debugOverlayPanel; } } }; diff --git a/game/client/vgui_fpspanel.cpp b/game/client/vgui_fpspanel.cpp index 7458b702..aec28add 100644 --- a/game/client/vgui_fpspanel.cpp +++ b/game/client/vgui_fpspanel.cpp @@ -18,7 +18,6 @@ #include "filesystem.h" #include "../common/xbox/xboxstubs.h" #include "steam/steam_api.h" -#include "tier0/cpumonitoring.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -209,28 +208,6 @@ void GetFPSColor( int nFps, unsigned char ucColor[3] ) } } -//----------------------------------------------------------------------------- -// Purpose: Set the color appropriately based on the CPU's frequency percentage -//----------------------------------------------------------------------------- -void GetCPUColor( float cpuPercentage, unsigned char ucColor[3] ) -{ - // These colors are for poor CPU performance - ucColor[0] = 255; ucColor[1] = 0; ucColor[2] = 0; - - if ( cpuPercentage >= kCPUMonitoringWarning1 ) - { - // Excellent CPU performance - ucColor[0] = 10; - ucColor[1] = 200; - } - else if ( cpuPercentage >= kCPUMonitoringWarning2 ) - { - // Medium CPU performance - ucColor[0] = 220; - ucColor[1] = 220; - } -} - //----------------------------------------------------------------------------- // Purpose: // Input : @@ -295,17 +272,6 @@ void CFPSPanel::Paint() GetFPSColor( nFps, ucColor ); g_pMatSystemSurface->DrawColoredText( m_hFont, x, 2, ucColor[0], ucColor[1], ucColor[2], 255, "%3i fps on %s", nFps, engine->GetLevelName() ); } - - const CPUFrequencyResults frequency = GetCPUFrequencyResults(); - double currentTime = Plat_FloatTime(); - const double displayTime = 5.0f; // Display frequency results for this long. - if ( frequency.m_GHz > 0 && frequency.m_timeStamp + displayTime > currentTime ) - { - int lineHeight = vgui::surface()->GetFontTall( m_hFont ); - // Optionally print out the CPU frequency monitoring data. - GetCPUColor( frequency.m_percentage, ucColor ); - g_pMatSystemSurface->DrawColoredText( m_hFont, x, lineHeight + 2, ucColor[0], ucColor[1], ucColor[2], 255, "CPU frequency percent: %3.1f%% Min percent: %3.1f%%", frequency.m_percentage, frequency.m_lowestPercentage ); - } } } m_lastRealTime = gpGlobals->realtime; @@ -395,7 +361,7 @@ class CFPS : public IFPSPanel if ( fpsPanel ) { fpsPanel->SetParent( (vgui::Panel *)NULL ); - fpsPanel->MarkForDeletion(); + delete fpsPanel; fpsPanel = NULL; } } @@ -814,7 +780,7 @@ class CBlockingFileIO : public IShowBlockingPanel if ( ioPanel ) { ioPanel->SetParent( (vgui::Panel *)NULL ); - ioPanel->MarkForDeletion(); + delete ioPanel; ioPanel = NULL; } } diff --git a/game/client/vgui_loadingdiscpanel.cpp b/game/client/vgui_loadingdiscpanel.cpp index 2dc7dd8f..94b2a9fb 100644 --- a/game/client/vgui_loadingdiscpanel.cpp +++ b/game/client/vgui_loadingdiscpanel.cpp @@ -128,14 +128,14 @@ class CLoadingDisc : public ILoadingDisc if ( loadingDiscPanel ) { loadingDiscPanel->SetParent( (vgui::Panel *)NULL ); - loadingDiscPanel->MarkForDeletion(); + delete loadingDiscPanel; loadingDiscPanel = NULL; } if ( m_pPauseDiscPanel ) { m_pPauseDiscPanel->SetParent( (vgui::Panel *)NULL ); - m_pPauseDiscPanel->MarkForDeletion(); + delete m_pPauseDiscPanel; m_pPauseDiscPanel = NULL; } diff --git a/game/client/vgui_messagechars.cpp b/game/client/vgui_messagechars.cpp index 6bde7566..1d1410f1 100644 --- a/game/client/vgui_messagechars.cpp +++ b/game/client/vgui_messagechars.cpp @@ -378,7 +378,7 @@ class CMessageChars : public IMessageChars if ( messageCharsPanel ) { messageCharsPanel->SetParent( (vgui::Panel *)NULL ); - messageCharsPanel->MarkForDeletion(); + delete messageCharsPanel; messageCharsPanel = NULL; } } diff --git a/game/client/vgui_movie_display.cpp b/game/client/vgui_movie_display.cpp new file mode 100644 index 00000000..7bc5bb62 --- /dev/null +++ b/game/client/vgui_movie_display.cpp @@ -0,0 +1,442 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "cbase.h" +#include "c_vguiscreen.h" +#include "vgui_controls/Label.h" +#include "vgui_bitmappanel.h" +#include +#include "c_slideshow_display.h" +#include "ienginevgui.h" +#include "fmtstr.h" +#include "vgui_controls/ImagePanel.h" +#include +#include "video/ivideoservices.h" +#include "engine/IEngineSound.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include "c_movie_display.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +using namespace vgui; + +struct VideoPlaybackInfo_t +{ + VideoPlaybackInfo_t( void ) : + m_pMaterial ( NULL ), + m_nSourceHeight(0), m_nSourceWidth(0), + m_flU(0.0f),m_flV(0.0f) {} + + IMaterial *m_pMaterial; + int m_nSourceHeight, m_nSourceWidth; // Source movie's dimensions + float m_flU, m_flV; // U,V ranges for video on its sheet +}; + +//----------------------------------------------------------------------------- +// Control screen +//----------------------------------------------------------------------------- +class CMovieDisplayScreen : public CVGuiScreenPanel +{ + DECLARE_CLASS( CMovieDisplayScreen, CVGuiScreenPanel ); + +public: + CMovieDisplayScreen( vgui::Panel *parent, const char *panelName ); + ~CMovieDisplayScreen( void ); + + virtual void ApplySchemeSettings( IScheme *pScheme ); + + virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ); + virtual void OnTick( void ); + virtual void Paint( void ); + +private: + bool IsActive( void ); + + void SetupMovie( void ); + void UpdateMovie( void ); + bool BeginPlayback( const char *pFilename ); + void CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight ); + + inline void GetPanelPos( int &xpos, int &ypos ) + { + xpos = ( (float) ( GetWide() - m_nPlaybackWidth ) / 2 ); + ypos = ( (float) ( GetTall() - m_nPlaybackHeight ) / 2 ); + } + +private: + + // BINK playback info + IVideoMaterial *m_VideoMaterial; + VideoPlaybackInfo_t m_playbackInfo; + CHandle m_hVGUIScreen; + CHandle m_hScreenEntity; + + int m_nTextureId; + int m_nPlaybackHeight; // Playback dimensions (proper ration adjustments) + int m_nPlaybackWidth; + bool m_bBlackBackground; + bool m_bSlaved; + bool m_bInitialized; + bool m_bLastActiveState; // HACK: I'd rather get a real callback... + + // VGUI specifics + Label *m_pDisplayTextLabel; + + Color m_cDefault; + Color m_cInvisible; + + bool bIsAlreadyVisible; +}; + +DECLARE_VGUI_SCREEN_FACTORY( CMovieDisplayScreen, "movie_display_screen" ); + +CUtlVector g_MovieDisplays; + +//----------------------------------------------------------------------------- +// Constructor: +//----------------------------------------------------------------------------- +CMovieDisplayScreen::CMovieDisplayScreen( vgui::Panel *parent, const char *panelName ) +: BaseClass( parent, "CMovieDisplayScreen", vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/MovieDisplayScreen.res", "MovieDisplayScreen" ) ) +{ + m_pDisplayTextLabel = new vgui::Label( this, "NumberDisplay", "testing!"); + + m_VideoMaterial = NULL; + m_nTextureId = -1; + m_bBlackBackground = true; + m_bSlaved = false; + m_bInitialized = false; + // Add ourselves to the global list of movie displays + g_MovieDisplays.AddToTail( this ); + //m_VideoMaterial->SetMuted(true); + m_bLastActiveState = IsActive(); +} + +//----------------------------------------------------------------------------- +// Purpose: Clean up the movie +//----------------------------------------------------------------------------- +CMovieDisplayScreen::~CMovieDisplayScreen( void ) +{ + if ( g_pVideo != NULL && m_VideoMaterial != NULL ) + { + g_pVideo->DestroyVideoMaterial( m_VideoMaterial ); + m_VideoMaterial = NULL; + } + + // Clean up our texture reference + g_pMatSystemSurface->DestroyTextureID( m_nTextureId ); + + // Remove ourselves from the global list of movie displays + g_MovieDisplays.FindAndRemove( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Setup our scheme +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::ApplySchemeSettings( IScheme *pScheme ) +{ + assert( pScheme ); + + m_cDefault = Color( 255, 255, 255, 255 ); + m_cInvisible = Color( 0, 0, 0, 0 ); + + m_pDisplayTextLabel->SetFgColor( m_cDefault ); + m_pDisplayTextLabel->SetText( "" ); + m_pDisplayTextLabel->SetVisible( false ); +} + +//----------------------------------------------------------------------------- +// Initialization +//----------------------------------------------------------------------------- +bool CMovieDisplayScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ) +{ + // Make sure we get ticked... + vgui::ivgui()->AddTickSignal( GetVPanel() ); + + if ( !BaseClass::Init( pKeyValues, pInitData ) ) + return false; + + // Save this for simplicity later on + m_hVGUIScreen = dynamic_cast( GetEntity() ); + if ( m_hVGUIScreen != NULL ) + { + // Also get the associated entity + m_hScreenEntity = dynamic_cast(m_hVGUIScreen->GetOwnerEntity()); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Helper function to check our active state +//----------------------------------------------------------------------------- +bool CMovieDisplayScreen::IsActive( void ) +{ + bool bScreenActive = false; + if ( m_hVGUIScreen != NULL ) + { + bScreenActive = m_hVGUIScreen->IsActive(); + } + + return bScreenActive; +} + +//----------------------------------------------------------------------------- +// Purpose: Either become the master of a group of screens, or become a slave to another +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::SetupMovie( void ) +{ + // Only bother if we haven't been setup yet + if ( m_bInitialized ) + return; + + const char *szGroupName = m_hScreenEntity->GetGroupName(); + + CMovieDisplayScreen *pMasterScreen = NULL; + for ( int i = 0; i < g_MovieDisplays.Count(); i++ ) + { + // Must be valid and not us + if ( g_MovieDisplays[i] == NULL || g_MovieDisplays[i] == this ) + continue; + + // Must have an associated movie entity + if ( g_MovieDisplays[i]->m_hScreenEntity == NULL ) + continue; + + // Must have a group name to care + if ( szGroupName[0] == NULL ) + continue; + + // Group names must match! + // FIXME: Use an ID instead? + const char *szTestGroupName = g_MovieDisplays[i]->m_hScreenEntity->GetGroupName(); + if ( Q_strnicmp( szTestGroupName, szGroupName, 128 ) ) + continue; + + // See if we've found a master display + if ( g_MovieDisplays[i]->m_bInitialized && g_MovieDisplays[i]->m_bSlaved == false ) + { + m_bSlaved = true; + + // Share the info from the master + m_playbackInfo = g_MovieDisplays[i]->m_playbackInfo; + + // We need to calculate our own playback dimensions as we may be a different size than our parent + CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight ); + + // Bind our texture + m_nTextureId = surface()->CreateNewTextureID( true ); + g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial ); + + // Hold this as the master screen + pMasterScreen = g_MovieDisplays[i]; + break; + } + } + + // We need to try again, we have no screen entity! + if ( m_hScreenEntity == NULL ) + return; + + // No master found, become one + if ( pMasterScreen == NULL ) + { + const char *szFilename = m_hScreenEntity->GetMovieFilename(); + BeginPlayback( szFilename ); + m_bSlaved = false; + } + + // Done + m_bInitialized = true; +} + +//----------------------------------------------------------------------------- +// Purpose: Deal with the details of the video playback +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::UpdateMovie( void ) +{ + // Only the master in a group updates the bink file + if ( m_bSlaved ) + return; + + if ( m_VideoMaterial == NULL ) + return; + + // Get the current activity state of the screen + bool bScreenActive = IsActive(); + + // Pause if the game has paused + if ( engine->IsPaused() || engine->Con_IsVisible() ) + { + bScreenActive = false; + } + + // See if we've changed our activity state + if ( bScreenActive != m_bLastActiveState ) + { + m_VideoMaterial->SetPaused( !bScreenActive ); + } + + // Updated + m_bLastActiveState = bScreenActive; + + // Update the frame if we're currently enabled + if ( bScreenActive ) + { + // Update our frame + if ( m_VideoMaterial->Update() == false ) + { + // Issue a close command + // OnVideoOver(); + // StopPlayback(); + } + + if (!m_hScreenEntity->IsMuted()) + { + m_VideoMaterial->SetMuted(false); + } + } +} + +//----------------------------------------------------------------------------- +// Update the display string +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::OnTick() +{ + BaseClass::OnTick(); + + // Create our playback or slave to another screen already playing + SetupMovie(); + + // Now update the movie + UpdateMovie(); +} + +//----------------------------------------------------------------------------- +// Purpose: Adjust the playback dimensions to properly account for our screen dimensions +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight ) +{ + float flFrameRatio = ( (float) GetWide() / (float) GetTall() ); + float flVideoRatio = ( (float) nSrcWidth / (float) nSrcHeight ); + + if ( flVideoRatio > flFrameRatio ) + { + m_nPlaybackWidth = GetWide(); + m_nPlaybackHeight = ( GetWide() / flVideoRatio ); + } + else if ( flVideoRatio < flFrameRatio ) + { + m_nPlaybackWidth = ( GetTall() * flVideoRatio ); + m_nPlaybackHeight = GetTall(); + } + else + { + m_nPlaybackWidth = GetWide(); + m_nPlaybackHeight = GetTall(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Begins playback of a movie +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CMovieDisplayScreen::BeginPlayback( const char *pFilename ) +{ + // need working video services + if ( g_pVideo == NULL ) + return false; + + // Create a new video material + if ( m_VideoMaterial != NULL ) + { + g_pVideo->DestroyVideoMaterial( m_VideoMaterial ); + m_VideoMaterial = NULL; + } + + // Create a globally unique name for this material + char szMaterialName[256]; + + // Append our group name if we have one + const char *szGroupName = m_hScreenEntity->GetGroupName(); + if ( szGroupName[0] != NULL ) + { + Q_snprintf( szMaterialName, sizeof(szMaterialName), "%s_%s", pFilename, szGroupName ); + } + else + { + Q_snprintf( szMaterialName, sizeof(szMaterialName), "%s_%s", pFilename, m_hScreenEntity->GetEntityName() ); + } + + m_VideoMaterial = g_pVideo->CreateVideoMaterial( szMaterialName, pFilename, "GAME", + VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS, + VideoSystem::DETERMINE_FROM_FILE_EXTENSION/*, m_bAllowAlternateMedia*/ ); + + if ( m_VideoMaterial == NULL ) + return false; + + + + m_VideoMaterial->SetMuted(true); // FIXME: Allow? + + + if ( m_hScreenEntity->IsLooping() ) + { + m_VideoMaterial->SetLooping( true ); + } + + if ( m_VideoMaterial->HasAudio()) + { + // We want to be the sole audio source + enginesound->NotifyBeginMoviePlayback(); + } + + // Get our basic info from the movie + m_VideoMaterial->GetVideoImageSize( &m_playbackInfo.m_nSourceWidth, &m_playbackInfo.m_nSourceHeight ); + m_VideoMaterial->GetVideoTexCoordRange( &m_playbackInfo.m_flU, &m_playbackInfo.m_flV ); + m_playbackInfo.m_pMaterial = m_VideoMaterial->GetMaterial(); + + // Get our playback dimensions + CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight ); + + // Bind our texture + m_nTextureId = surface()->CreateNewTextureID( true ); + g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial ); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Update and draw the frame +//----------------------------------------------------------------------------- +void CMovieDisplayScreen::Paint( void ) +{ + // Masters must keep the video updated + if ( m_bSlaved == false && m_VideoMaterial == NULL ) + { + BaseClass::Paint(); + return; + } + + // Sit in the "center" + int xpos, ypos; + GetPanelPos( xpos, ypos ); + + // Black out the background (we could omit drawing under the video surface, but this is straight-forward) + if ( m_bBlackBackground ) + { + surface()->DrawSetColor( 0, 0, 0, 255 ); + surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() ); + } + + // Draw it + surface()->DrawSetTexture( m_nTextureId ); + surface()->DrawSetColor( 255, 255, 255, 255 ); + surface()->DrawTexturedSubRect( xpos, ypos, xpos+m_nPlaybackWidth, ypos+m_nPlaybackHeight, 0.0f, 0.0f, m_playbackInfo.m_flU, m_playbackInfo.m_flV ); + + // Parent's turn + BaseClass::Paint(); +} diff --git a/game/client/vgui_netgraphpanel.cpp b/game/client/vgui_netgraphpanel.cpp index adf3e4b9..d3837c03 100644 --- a/game/client/vgui_netgraphpanel.cpp +++ b/game/client/vgui_netgraphpanel.cpp @@ -20,7 +20,6 @@ #include #include #include "tier0/vprof.h" -#include "tier0/cpumonitoring.h" #include "cdll_bounded_cvars.h" #include "materialsystem/imaterialsystem.h" @@ -492,10 +491,6 @@ void CNetGraphPanel::DrawTimes( vrect_t vrect, cmdinfo_t *cmdinfo, int x, int w, { i = ( m_OutgoingSequence - a ) & ( TIMINGS - 1 ); h = MIN( ( cmdinfo[i].cmd_lerp / 3.0 ) * LERP_HEIGHT, LERP_HEIGHT ); - if ( h < 0 ) - { - h = LERP_HEIGHT; - } rcFill.x = x + w -a - 1; rcFill.width = 1; @@ -518,9 +513,7 @@ void CNetGraphPanel::DrawTimes( vrect_t vrect, cmdinfo_t *cmdinfo, int x, int w, for ( j = start; j < h; j++ ) { - int index = j + extrap_point; - Assert( (size_t)index < Q_ARRAYSIZE( colors ) ); - DrawLine(&rcFill, colors[ index ], 255 ); + DrawLine(&rcFill, colors[j + extrap_point], 255 ); rcFill.y--; } } @@ -538,9 +531,7 @@ void CNetGraphPanel::DrawTimes( vrect_t vrect, cmdinfo_t *cmdinfo, int x, int w, for ( j = 0; j < h; j++ ) { - int index = j + oldh; - Assert( (size_t)index < Q_ARRAYSIZE( colors ) ); - DrawLine(&rcFill, colors[ index ], 255 ); + DrawLine(&rcFill, colors[j + oldh], 255 ); rcFill.y--; } } @@ -770,7 +761,7 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban Q_snprintf( sz, sizeof( sz ), "lerp: %5.1f ms", GetClientInterpAmount() * 1000.0f ); - int interpcolor[ 3 ] = { (int)GRAPH_RED, (int)GRAPH_GREEN, (int)GRAPH_BLUE }; + int interpcolor[ 3 ] = { GRAPH_RED, GRAPH_GREEN, GRAPH_BLUE }; float flInterp = GetClientInterpAmount(); if ( flInterp > 0.001f ) { @@ -826,7 +817,7 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban { Q_snprintf( sz, sizeof( sz ), "sv : %5.1f var: %4.2f msec", m_flServerFramerate, m_flServerFramerateStdDeviation * 1000.0f ); - int servercolor[ 3 ] = { (int)GRAPH_RED, (int)GRAPH_GREEN, (int)GRAPH_BLUE }; + int servercolor[ 3 ] = { GRAPH_RED, GRAPH_GREEN, GRAPH_BLUE }; if ( m_flServerFramerate < 10.0f ) { @@ -885,35 +876,6 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban g_pMatSystemSurface->DrawColoredText( m_hFontSmall, x, y, 0, 0, 128, 255, "voice" ); y -= textTall; } - else - { - const CPUFrequencyResults frequency = GetCPUFrequencyResults(); - double currentTime = Plat_FloatTime(); - const double displayTime = 5.0f; // Display frequency results for this long. - if ( frequency.m_GHz > 0 && frequency.m_timeStamp + displayTime > currentTime ) - { - // Optionally print out the CPU frequency monitoring data. - uint8 cpuColor[4] = { (uint8)GRAPH_RED, (uint8)GRAPH_GREEN, (uint8)GRAPH_BLUE, 255 }; - - if ( frequency.m_percentage < kCPUMonitoringWarning2 ) - { - cpuColor[0] = 255; - cpuColor[1] = 31; - cpuColor[2] = 31; - } - else if ( frequency.m_percentage < kCPUMonitoringWarning1 ) - { - cpuColor[0] = 255; - cpuColor[1] = 125; - cpuColor[2] = 31; - } - // Experimental fading out as data becomes stale. Probably too distracting. - //float age = currentTime - frequency.m_timeStamp; - //cpuColor.a *= ( displayTime - age ) / displayTime; - g_pMatSystemSurface->DrawColoredText( font, x, y, cpuColor[0], cpuColor[1], cpuColor[2], cpuColor[3], - "CPU freq: %3.1f%% Min: %3.1f%%", frequency.m_percentage, frequency.m_lowestPercentage ); - } - } } //----------------------------------------------------------------------------- @@ -1541,7 +1503,7 @@ class CNetGraphPanelInterface : public INetGraphPanel if ( netGraphPanel ) { netGraphPanel->SetParent( (Panel *)NULL ); - netGraphPanel->MarkForDeletion(); + delete netGraphPanel; netGraphPanel = NULL; } } diff --git a/game/client/vgui_schemevisualizer.cpp b/game/client/vgui_schemevisualizer.cpp index afde874d..12070f29 100644 --- a/game/client/vgui_schemevisualizer.cpp +++ b/game/client/vgui_schemevisualizer.cpp @@ -177,14 +177,12 @@ void CSchemeVisualizer::AddBordersToList() void CSchemeVisualizer::AddFontsToList() { #ifdef POSIX - const char strOAccent[] = { (char)0xc3, (char)0x93, 0x00 }; // UTF-8 for U+00D3 (LATIN CAPITAL LETTER O WITH ACUTE) - const char strSkull[] = { (char)0xe2, (char)0x98, (char)0xa0, 0x00 }; + const char strOAccent[] = { 0xc3, 0x93, 0x00 }; // UTF-8 for U+00D3 (LATIN CAPITAL LETTER O WITH ACUTE) #else const uint8 strOAccent[] = { 0xd3, 0x00 }; - const char strSkull[] = ""; #endif // Stick an intl character in here to test accents (O') - CFmtStr fmtText( "ABCDEFGHIJKLMN%sPQRSTUVWXYZ%sabcdefhijklmnopqrstuvwxyz0123456789!@#$%%^&*()-_=+", strOAccent, strSkull ); + CFmtStr fmtText( "ABCDEFGHIJKLMN%sPQRSTUVWXYZabcdefhijklmnopqrstuvwxyz0123456789!@#$%%^&*()-_=+", strOAccent ); const int nFontCount = m_pViewScheme->GetFontCount(); @@ -290,4 +288,4 @@ void CSchemeVisualizer::OnTick() // Update the list now UpdateList( nType ); -} +} \ No newline at end of file diff --git a/game/client/vgui_video.cpp b/game/client/vgui_video.cpp index 57323f40..17e28aa2 100644 --- a/game/client/vgui_video.cpp +++ b/game/client/vgui_video.cpp @@ -16,15 +16,59 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +using namespace vgui; + +static CUtlVector< VideoPanel * > g_vecVideoPanels; + +// Thiis is a hack due to the fact that the user can type quit with the video panel up, but it's parented to the GameUI dll root panel, which is already gone so +// we would crash in the destructor +void VGui_ClearVideoPanels() +{ + for ( int i = g_vecVideoPanels.Count() - 1; i >= 0; --i ) + { + if ( g_vecVideoPanels[ i ] ) + { + delete g_vecVideoPanels[ i ]; + } + } + g_vecVideoPanels.RemoveAll(); +} + +struct VideoPanelParms_t +{ + VideoPanelParms_t( bool _interrupt = true, bool _loop = false, bool _mute = false ) + { + bAllowInterrupt = _interrupt; + bLoop = _loop; + bMute = _mute; + } + + bool bAllowInterrupt; + bool bLoop; + bool bMute; + + //float flFadeIn; + //float flFadeOut; +}; VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHeight, unsigned int nWidth, bool allowAlternateMedia ) : BaseClass( NULL, "VideoPanel" ), m_VideoMaterial( NULL ), m_nPlaybackWidth( 0 ), m_nPlaybackHeight( 0 ), - m_bAllowAlternateMedia( allowAlternateMedia ) + m_nShutdownCount( 0 ), + m_bLooping( false ), + m_bStopAllSounds( true ), + m_bAllowInterruption( true ), + m_bAllowAlternateMedia( allowAlternateMedia ), + m_bStarted( false ) { +#ifdef MAPBASE + vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_ROOT ); +#else vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_GAMEUIDLL ); +#endif + SetParent( pParent ); SetVisible( false ); @@ -48,6 +92,11 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe SetScheme(vgui::scheme()->LoadSchemeFromFile( "resource/VideoPanelScheme.res", "VideoPanelScheme")); LoadControlSettings("resource/UI/VideoPanel.res"); + + // Let us update + vgui::ivgui()->AddTickSignal( GetVPanel() ); + + g_vecVideoPanels.AddToTail( this ); } //----------------------------------------------------------------------------- @@ -55,6 +104,8 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe //----------------------------------------------------------------------------- VideoPanel::~VideoPanel( void ) { + g_vecVideoPanels.FindAndRemove( this ); + SetParent( (vgui::Panel *) NULL ); // Shut down this video, destroy the video material @@ -65,13 +116,39 @@ VideoPanel::~VideoPanel( void ) } } +//----------------------------------------------------------------------------- +// Purpose: Keeps a tab on when the movie is ending and allows a frame to pass to prevent threading issues +//----------------------------------------------------------------------------- +void VideoPanel::OnTick( void ) +{ + if ( m_nShutdownCount > 0 ) + { + m_nShutdownCount++; + + if ( m_nShutdownCount > 10 ) + { + OnClose(); + m_nShutdownCount = 0; + } + } + + BaseClass::OnTick(); +} + +void VideoPanel::OnVideoOver() +{ + StopPlayback(); +} + //----------------------------------------------------------------------------- // Purpose: Begins playback of a movie // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool VideoPanel::BeginPlayback( const char *pFilename ) { - // Who the heck hacked this in? + if ( !pFilename || pFilename[ 0 ] == '\0' ) + return false; + #ifdef _X360 XVIDEO_MODE videoMode; XGetVideoMode( &videoMode ); @@ -101,9 +178,25 @@ bool VideoPanel::BeginPlayback( const char *pFilename ) if ( m_VideoMaterial == NULL ) return false; + if ( m_bLooping ) + { + m_VideoMaterial->SetLooping( true ); + } + +#ifdef MAPBASE + if ( m_bMuted ) + { + m_VideoMaterial->SetMuted( true ); + } +#endif + + m_bStarted = true; + // We want to be the sole audio source - // FIXME: This may not always be true! - enginesound->NotifyBeginMoviePlayback(); + if ( m_bStopAllSounds ) + { + enginesound->NotifyBeginMoviePlayback(); + } int nWidth, nHeight; m_VideoMaterial->GetVideoImageSize( &nWidth, &nHeight ); @@ -163,9 +256,10 @@ void VideoPanel::DoModal( void ) //----------------------------------------------------------------------------- void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code ) { - if ( code == KEY_ESCAPE ) + bool bInterruptKeyPressed = ( code == KEY_ESCAPE ); + if ( m_bAllowInterruption && bInterruptKeyPressed ) { - OnClose(); + StopPlayback(); } else { @@ -176,34 +270,54 @@ void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code ) //----------------------------------------------------------------------------- // Purpose: Handle keys that should cause us to close //----------------------------------------------------------------------------- -void VideoPanel::OnKeyCodePressed( vgui::KeyCode code ) +void VideoPanel::OnKeyCodePressed( vgui::KeyCode keycode ) { + vgui::KeyCode code = GetBaseButtonCode( keycode ); + + // All these keys will interrupt playback + bool bInterruptKeyPressed = ( code == KEY_ESCAPE || + code == KEY_BACKQUOTE || + code == KEY_SPACE || + code == KEY_ENTER || + code == KEY_XBUTTON_A || + code == KEY_XBUTTON_B || + code == KEY_XBUTTON_X || + code == KEY_XBUTTON_Y || + code == KEY_XBUTTON_START || + code == KEY_XBUTTON_BACK ); + // These keys cause the panel to shutdown - if ( code == KEY_ESCAPE || - code == KEY_BACKQUOTE || - code == KEY_SPACE || - code == KEY_ENTER || - code == KEY_XBUTTON_A || - code == KEY_XBUTTON_B || - code == KEY_XBUTTON_X || - code == KEY_XBUTTON_Y || - code == KEY_XBUTTON_START || - code == KEY_XBUTTON_BACK ) + if ( m_bAllowInterruption && bInterruptKeyPressed ) { - OnClose(); + StopPlayback(); } else { - BaseClass::OnKeyCodePressed( code ); + BaseClass::OnKeyCodePressed( keycode ); } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void VideoPanel::StopPlayback( void ) +{ + SetVisible( false ); + + // Start the deferred shutdown process + m_nShutdownCount = 1; +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void VideoPanel::OnClose( void ) { - enginesound->NotifyEndMoviePlayback(); + if ( m_bStopAllSounds ) + { + enginesound->NotifyEndMoviePlayback(); + } + BaseClass::OnClose(); if ( vgui::input()->GetAppModalSurface() == GetVPanel() ) @@ -219,7 +333,6 @@ void VideoPanel::OnClose( void ) engine->ClientCmd( m_szExitCommand ); } - SetVisible( false ); MarkForDeletion(); } @@ -242,26 +355,52 @@ void VideoPanel::Paint( void ) if ( m_VideoMaterial == NULL ) return; + float alpha = ((float)GetFgColor()[3]/255.0f); +#ifdef MAPBASE + if (m_flFadeIn != 0.0f || m_flFadeOut != 0.0f) + { + // GetCurrentVideoTime() and GetVideoDuration() are borked + float flFrameCount = m_VideoMaterial->GetFrameCount(); + float flEnd = flFrameCount / m_VideoMaterial->GetVideoFrameRate().GetFPS(); + float flTime = ((float)(m_VideoMaterial->GetCurrentFrame()) / flFrameCount) * flEnd; + float flFadeOutDelta = (flEnd - m_flFadeOut); + + if (flTime <= m_flFadeIn) + { + alpha = (flTime / m_flFadeIn); + } + else if (flTime >= flFadeOutDelta) + { + alpha = (1.0f - ((flTime - flFadeOutDelta) / m_flFadeOut)); + } + } +#endif + if ( m_VideoMaterial->Update() == false ) { // Issue a close command OnVideoOver(); - OnClose(); + //OnClose(); } // Sit in the "center" int xpos, ypos; GetPanelPos( xpos, ypos ); + LocalToScreen( xpos, ypos ); // Black out the background (we could omit drawing under the video surface, but this is straight-forward) if ( m_bBlackBackground ) { - vgui::surface()->DrawSetColor( 0, 0, 0, 255 ); + vgui::surface()->DrawSetColor( 0, 0, 0, alpha * 255.0f ); vgui::surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() ); } // Draw the polys to draw this out CMatRenderContextPtr pRenderContext( materials ); + +#ifdef MAPBASE + pRenderContext->ClearColor4ub( 255, 255, 255, alpha * 255.0f ); +#endif pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->PushMatrix(); @@ -301,8 +440,6 @@ void VideoPanel::Paint( void ) flTopY = FLerp( 1, -1, 0, vh ,flTopY ); flBottomY = FLerp( 1, -1, 0, vh, flBottomY ); - float alpha = ((float)GetFgColor()[3]/255.0f); - for ( int corner=0; corner<4; corner++ ) { bool bLeft = (corner==0) || (corner==3); @@ -335,21 +472,41 @@ void VideoPanel::Paint( void ) bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos, unsigned int nWidth, unsigned int nHeight, const char *pVideoFilename, - const char *pExitCommand /*= NULL*/) + const char *pExitCommand /*= NULL*/, + const VideoPanelParms_t &parms ) { // Create the base video panel - VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth, false ); + VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth ); if ( pVideoPanel == NULL ) return false; + // Toggle if we want the panel to allow interruption + pVideoPanel->SetAllowInterrupt( parms.bAllowInterrupt ); + // Set the command we'll call (if any) when the video is interrupted or completes pVideoPanel->SetExitCommand( pExitCommand ); +#ifdef MAPBASE + // Toggle if we want the panel to loop (inspired by Portal 2) + pVideoPanel->SetLooping( parms.bLoop ); + + // Toggle if we want the panel to be muted + pVideoPanel->SetMuted( parms.bMute ); + + // TODO: Unique "Stop All Sounds" parameter + if (parms.bMute) + { + pVideoPanel->SetStopAllSounds( false ); + } + + // Fade parameters (unfinished) + //pVideoPanel->SetFade( parms.flFadeIn, parms.flFadeOut ); +#endif + // Start it going if ( pVideoPanel->BeginPlayback( pVideoFilename ) == false ) { - pVideoPanel->MarkForDeletion(); - pVideoPanel = NULL; + delete pVideoPanel; return false; } @@ -360,8 +517,29 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos, } //----------------------------------------------------------------------------- -// Purpose: Used to launch a video playback (Debug) - -// user must include file extension +// Purpose: Create a video panel with the supplied commands +//----------------------------------------------------------------------------- +void CreateVideoPanel( const char *lpszFilename, const char *lpszExitCommand, int nWidth, int nHeight, VideoPanelParms_t &parms ) +{ + char strFullpath[MAX_PATH]; + Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory + char strFilename[MAX_PATH]; + Q_StripExtension( lpszFilename, strFilename, MAX_PATH ); + Q_strncat( strFullpath, lpszFilename, MAX_PATH ); + + // Use the full screen size if they haven't specified an override + unsigned int nScreenWidth = ( nWidth != 0 ) ? nWidth : ScreenWidth(); + unsigned int nScreenHeight = ( nHeight != 0 ) ? nHeight : ScreenHeight(); + + // Create the panel and go! + if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, lpszExitCommand, parms ) == false ) + { + Warning( "Unable to play video: %s\n", strFullpath ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Used to launch a video playback //----------------------------------------------------------------------------- CON_COMMAND( playvideo, "Plays a video: [width height]" ) @@ -371,30 +549,32 @@ CON_COMMAND( playvideo, "Plays a video: [width height]" ) unsigned int nScreenWidth = Q_atoi( args[2] ); unsigned int nScreenHeight = Q_atoi( args[3] ); + + // New struct; functionally identical + VideoPanelParms_t parms; - char strFullpath[MAX_PATH]; - Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory - char strFilename[MAX_PATH]; - Q_StripExtension( args[1], strFilename, MAX_PATH ); - Q_strncat( strFullpath, args[1], MAX_PATH ); - - if ( nScreenWidth == 0 ) - { - nScreenWidth = ScreenWidth(); - } - - if ( nScreenHeight == 0 ) - { - nScreenHeight = ScreenHeight(); - } + CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms ); +} - // Create the panel and go! - if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath ) == false ) - { - Warning( "Unable to play video: %s\n", strFullpath ); - } +//----------------------------------------------------------------------------- +// Purpose: Used to launch a video playback +//----------------------------------------------------------------------------- + +CON_COMMAND( playvideo_nointerrupt, "Plays a video without ability to skip: [width height]" ) +{ + if ( args.ArgC() < 2 ) + return; + + unsigned int nScreenWidth = Q_atoi( args[2] ); + unsigned int nScreenHeight = Q_atoi( args[3] ); + + // New struct; functionally identical + VideoPanelParms_t parms( false ); + + CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms ); } + //----------------------------------------------------------------------------- // Purpose: Used to launch a video playback and fire a command on completion //----------------------------------------------------------------------------- @@ -404,21 +584,78 @@ CON_COMMAND( playvideo_exitcommand, "Plays a video and fires and exit command wh if ( args.ArgC() < 2 ) return; - unsigned int nScreenWidth = ScreenWidth(); - unsigned int nScreenHeight = ScreenHeight(); + // Pull out the exit command we want to use + char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] ); - char strFullpath[MAX_PATH]; - Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory - char strFilename[MAX_PATH]; - Q_StripExtension( args[1], strFilename, MAX_PATH ); - Q_strncat( strFullpath, args[1], MAX_PATH ); + // New struct; functionally identical + VideoPanelParms_t parms; + CreateVideoPanel( args[1], pExitCommand, 0, 0, parms ); +} + +//----------------------------------------------------------------------------- +// Purpose: Used to launch a video playback and fire a command on completion +//----------------------------------------------------------------------------- + +CON_COMMAND( playvideo_exitcommand_nointerrupt, "Plays a video (without interruption) and fires and exit command when it is stopped or finishes: " ) +{ + if ( args.ArgC() < 2 ) + return; + + // Pull out the exit command we want to use char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] ); - // Create the panel and go! - if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, pExitCommand ) == false ) + // New struct; functionally identical + VideoPanelParms_t parms( false ); + + CreateVideoPanel( args[1], pExitCommand, 0, 0, parms ); +} + +//----------------------------------------------------------------------------- +// Purpose: Cause all playback to stop +//----------------------------------------------------------------------------- + +CON_COMMAND( stopvideos, "Stops all videos playing to the screen" ) +{ + FOR_EACH_VEC( g_vecVideoPanels, itr ) { - Warning( "Unable to play video: %s\n", strFullpath ); - engine->ClientCmd( pExitCommand ); + g_vecVideoPanels[itr]->StopPlayback(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Used to launch a video playback and fire a command on completion +//----------------------------------------------------------------------------- + +CON_COMMAND( playvideo_complex, "Plays a video with various parameters to simplify logic_playmovie: " ) +{ + if ( args.ArgC() < 2 ) + return; + + // Pull out the exit command we want to use + char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] ); + + // Parameters + VideoPanelParms_t parms; + + if (args.ArgC() >= 3) + parms.bAllowInterrupt = atoi( args[3] ) != 0; + if (args.ArgC() >= 4) + parms.bLoop = atoi( args[4] ) != 0; + if (args.ArgC() >= 5) + parms.bMute = atoi( args[5] ) != 0; + + //if (args.ArgC() >= 5) + // parms.flFadeIn = atof( args[5] ); + //if (args.ArgC() >= 6) + // parms.flFadeOut = atof( args[6] ); + + // Stop a softlock + if (parms.bAllowInterrupt == false && parms.bLoop) + { + Warning( "WARNING: Tried to play video set to be uninterruptible and looping. This would cause a softlock because the video loops forever and there's no way to stop it.\n" ); + return; } -} \ No newline at end of file + + CreateVideoPanel( args[1], pExitCommand, 0, 0, parms ); +} diff --git a/game/client/vgui_video.h b/game/client/vgui_video.h index 61a980b1..b413d832 100644 --- a/game/client/vgui_video.h +++ b/game/client/vgui_video.h @@ -45,14 +45,22 @@ class VideoPanel : public vgui::EditablePanel } bool BeginPlayback( const char *pFilename ); + void StopPlayback( void ); void SetBlackBackground( bool bBlack ){ m_bBlackBackground = bBlack; } + void SetAllowInterrupt( bool bAllowInterrupt ) { m_bAllowInterruption = bAllowInterrupt; } + void SetStopAllSounds( bool bStopAllSounds ) { m_bStopAllSounds = bStopAllSounds; } +#ifdef MAPBASE + void SetLooping( bool bLooping ) { m_bLooping = bLooping; } + void SetMuted( bool bMuted ) { m_bMuted = bMuted; } + void SetFade( float flStartFade, float flEndFade ) { m_flFadeIn = flStartFade; m_flFadeOut = flEndFade; } +#endif protected: - virtual void OnTick( void ) { BaseClass::OnTick(); } + virtual void OnTick( void ); virtual void OnCommand( const char *pcCommand ) { BaseClass::OnCommand( pcCommand ); } - virtual void OnVideoOver(){} + virtual void OnVideoOver(); protected: IVideoMaterial *m_VideoMaterial; @@ -65,8 +73,19 @@ class VideoPanel : public vgui::EditablePanel float m_flU; // U,V ranges for video on its sheet float m_flV; + bool m_bLooping; +#ifdef MAPBASE + float m_flFadeIn; + float m_flFadeOut; + bool m_bMuted; +#endif + bool m_bStopAllSounds; + bool m_bAllowInterruption; bool m_bBlackBackground; bool m_bAllowAlternateMedia; + int m_nShutdownCount; + + bool m_bStarted; }; diff --git a/game/client/view.cpp b/game/client/view.cpp index 39980140..8cd5293d 100644 --- a/game/client/view.cpp +++ b/game/client/view.cpp @@ -36,7 +36,6 @@ #include "materialsystem/itexture.h" #include "materialsystem/imaterialsystem.h" #include "materialsystem/materialsystem_config.h" -#include "materialsystem/imaterialvar.h" #include "VGuiMatSurface/IMatSystemSurface.h" #include "toolframework_client.h" #include "tier0/icommandline.h" @@ -60,7 +59,7 @@ #include "c_prop_portal.h" //portal surface rendering functions #endif - + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -108,14 +107,13 @@ extern ConVar cl_forwardspeed; static ConVar v_centermove( "v_centermove", "0.15"); static ConVar v_centerspeed( "v_centerspeed","500" ); -#ifdef TF_CLIENT_DLL +#if defined(TF_CLIENT_DLL) || defined(MAPBASE) // 54 degrees approximates a 35mm camera - we determined that this makes the viewmodels // and motions look the most natural. -ConVar v_viewmodel_fov( "viewmodel_fov", "54", FCVAR_ARCHIVE, "Sets the field-of-view for the viewmodel.", true, 0.1, true, 179.9 ); -#elif VANCE -ConVar v_viewmodel_fov( "viewmodel_fov", "70", FCVAR_CHEAT ); +ConVar v_viewmodel_fov( "viewmodel_fov", "54", FCVAR_ARCHIVE ); +ConVar v_viewmodel_fov_script_override( "viewmodel_fov_script_override", "0", FCVAR_NONE, "If nonzero, overrides the viewmodel FOV of weapon scripts which override the viewmodel FOV." ); #else -ConVar v_viewmodel_fov( "viewmodel_fov", "54", FCVAR_CHEAT, "Sets the field-of-view for the viewmodel.", true, 0.1, true, 179.9 ); +ConVar v_viewmodel_fov( "viewmodel_fov", "54", FCVAR_CHEAT ); #endif ConVar mat_viewportscale( "mat_viewportscale", "1.0", FCVAR_ARCHIVE, "Scale down the main viewport (to reduce GPU impact on CPU profiling)", true, (1.0f / 640.0f), true, 1.0f ); ConVar mat_viewportupscale( "mat_viewportupscale", "1", FCVAR_ARCHIVE, "Scale the viewport back up" ); @@ -129,6 +127,9 @@ ConVar gl_clear( "gl_clear", "0"); ConVar gl_clear_randomcolor( "gl_clear_randomcolor", "0", FCVAR_CHEAT, "Clear the back buffer to random colors every frame. Helps spot open seams in geometry." ); static ConVar r_farz( "r_farz", "-1", FCVAR_CHEAT, "Override the far clipping plane. -1 means to use the value in env_fog_controller." ); +#ifdef MAPBASE +static ConVar r_nearz( "r_nearz", "-1", FCVAR_CHEAT, "Override the near clipping plane. -1 means to use the default value (usually 7)." ); +#endif static ConVar cl_demoviewoverride( "cl_demoviewoverride", "0", 0, "Override view during demo playback" ); @@ -306,8 +307,7 @@ void CViewRender::Init( void ) m_TranslucentSingleColor.Init( "debug/debugtranslucentsinglecolor", TEXTURE_GROUP_OTHER ); m_ModulateSingleColor.Init( "engine/modulatesinglecolor", TEXTURE_GROUP_OTHER ); - m_SkydomeMaterial.Init("shaders/skydome", TEXTURE_GROUP_MODEL); - + extern CMaterialReference g_material_WriteZ; g_material_WriteZ.Init( "engine/writez", TEXTURE_GROUP_OTHER ); @@ -324,81 +324,6 @@ void CViewRender::Init( void ) m_flLastFOV = default_fov.GetFloat(); #endif - ITexture *depthOld = materials->FindTexture("_rt_FullFrameDepth", TEXTURE_GROUP_RENDER_TARGET); - static int flags = TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_RENDERTARGET; - if (depthOld) - flags = depthOld->GetFlags(); - - int iW, iH; - materials->GetBackBufferDimensions(iW, iH); - materials->BeginRenderTargetAllocation(); - materials->CreateNamedRenderTargetTextureEx( - "_rt_DepthBuffer", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGBA32323232F, - MATERIAL_RT_DEPTH_SEPARATE, - flags, - 0); - materials->CreateNamedRenderTargetTextureEx( - "_rt_VolumetricsBuffer", - iW / 4, iH / 4, RT_SIZE_NO_CHANGE, - IMAGE_FORMAT_RGBA16161616F, - MATERIAL_RT_DEPTH_SHARED, - flags, - 0); - - materials->CreateNamedRenderTargetTextureEx( - "_rt_VanceHDR", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGBA16161616F, - MATERIAL_RT_DEPTH_SHARED, - TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, - CREATERENDERTARGETFLAGS_HDR); - - materials->CreateNamedRenderTargetTextureEx( - "_rt_Scope", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGBA16161616F, - MATERIAL_RT_DEPTH_SHARED, - TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, - CREATERENDERTARGETFLAGS_HDR); - - m_NormalBuffer = materials->CreateNamedRenderTargetTextureEx( - "_rt_Normals", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGBA16161616F, - MATERIAL_RT_DEPTH_SHARED, - flags, - 0); - m_MRAOBuffer = materials->CreateNamedRenderTargetTextureEx( - "_rt_MRAO", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGBA16161616F, - MATERIAL_RT_DEPTH_SHARED, - flags, - 0); - - m_AlbedoBuffer = materials->CreateNamedRenderTargetTextureEx( - "_rt_Albedo", - iW, iH, RT_SIZE_FULL_FRAME_BUFFER, - IMAGE_FORMAT_RGB888, - MATERIAL_RT_DEPTH_SHARED, - flags, - 0); - - // Init all IScreenSpaceEffects - g_pScreenSpaceEffects->InitScreenSpaceEffects(); - - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_unsharp"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_fxaa"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_waterfx"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_bloom"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_tonemap"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_ssao"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_ssr"); - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_volumetrics"); - - materials->EndRenderTargetAllocation(); } //----------------------------------------------------------------------------- @@ -420,6 +345,9 @@ void CViewRender::LevelInit( void ) // Clear our overlay materials m_ScreenOverlayMaterial.Init( NULL ); + + // Init all IScreenSpaceEffects + g_pScreenSpaceEffects->InitScreenSpaceEffects( ); } //----------------------------------------------------------------------------- @@ -427,6 +355,7 @@ void CViewRender::LevelInit( void ) //----------------------------------------------------------------------------- void CViewRender::LevelShutdown( void ) { + g_pScreenSpaceEffects->ShutdownScreenSpaceEffects( ); } //----------------------------------------------------------------------------- @@ -434,17 +363,6 @@ void CViewRender::LevelShutdown( void ) //----------------------------------------------------------------------------- void CViewRender::Shutdown( void ) { - g_pScreenSpaceEffects->ShutdownScreenSpaceEffects(); - - g_pScreenSpaceEffects->EnableScreenSpaceEffect("vance_unsharp"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_fxaa"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_waterfx"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_bloom"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_tonemap"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_ssao"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_ssr"); - g_pScreenSpaceEffects->DisableScreenSpaceEffect("vance_volumetrics"); - m_TranslucentSingleColor.Shutdown( ); m_ModulateSingleColor.Shutdown( ); m_ScreenOverlayMaterial.Shutdown(); @@ -688,6 +606,11 @@ static QAngle s_DbgSetupAngles; //----------------------------------------------------------------------------- float CViewRender::GetZNear() { +#ifdef MAPBASE + if (r_nearz.GetFloat() > 0) + return r_nearz.GetFloat(); +#endif + return VIEW_NEARZ; } @@ -753,6 +676,10 @@ void CViewRender::SetUpViews() Vector ViewModelOrigin; QAngle ViewModelAngles; +#ifdef MAPBASE + view.fovViewmodel = g_pClientMode->GetViewModelFOV(); +#endif + if ( engine->IsHLTV() ) { HLTVCamera()->CalcView( view.origin, view.angles, view.fov ); @@ -788,6 +715,18 @@ void CViewRender::SetUpViews() bCalcViewModelView = true; ViewModelOrigin = view.origin; ViewModelAngles = view.angles; + +#ifdef MAPBASE + // Allow weapons to override viewmodel FOV + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + if (pWeapon && pWeapon->GetViewmodelFOVOverride() != 0.0f) + { + if (v_viewmodel_fov_script_override.GetFloat() > 0.0f) + view.fovViewmodel = v_viewmodel_fov_script_override.GetFloat(); + else + view.fovViewmodel = pWeapon->GetViewmodelFOVOverride(); + } +#endif } else { @@ -822,7 +761,11 @@ void CViewRender::SetUpViews() float flFOVOffset = fDefaultFov - view.fov; //Adjust the viewmodel's FOV to move with any FOV offsets on the viewer's end +#ifdef MAPBASE + view.fovViewmodel = max(0.001f, view.fovViewmodel - flFOVOffset); +#else view.fovViewmodel = g_pClientMode->GetViewModelFOV() - flFOVOffset; +#endif if ( UseVR() ) { diff --git a/game/client/view_scene.h b/game/client/view_scene.h index 9fce569b..3cb440da 100644 --- a/game/client/view_scene.h +++ b/game/client/view_scene.h @@ -133,16 +133,16 @@ inline void DrawScreenEffectMaterial( IMaterial *pMaterial, int x, int y, int w, pTexture->GetActualWidth(), pTexture->GetActualHeight() ); } -inline void DrawScreenEffectQuad(IMaterial *pMaterial, int w, int h) +inline void DrawScreenEffectQuad( IMaterial *pMaterial, int w, int h ) { if (pMaterial != NULL) { - CMatRenderContextPtr pRenderContext(materials); + CMatRenderContextPtr pRenderContext( materials ); pRenderContext->DrawScreenSpaceRectangle( pMaterial, 0, 0, w, h, 0, 0, w - 1, h - 1, - w, h); + w, h ); } } diff --git a/game/client/viewdebug.cpp b/game/client/viewdebug.cpp index 619993fa..94988d9f 100644 --- a/game/client/viewdebug.cpp +++ b/game/client/viewdebug.cpp @@ -29,6 +29,9 @@ static ConVar mat_wateroverlaysize( "mat_wateroverlaysize", "256" ); static ConVar mat_showframebuffertexture( "mat_showframebuffertexture", "0", FCVAR_CHEAT ); static ConVar mat_framebuffercopyoverlaysize( "mat_framebuffercopyoverlaysize", "256" ); static ConVar mat_showcamerarendertarget( "mat_showcamerarendertarget", "0", FCVAR_CHEAT ); +#ifdef MAPBASE +static ConVar mat_showcamerarendertarget_all( "mat_showcamerarendertarget_all", "0", FCVAR_CHEAT ); +#endif static ConVar mat_camerarendertargetoverlaysize( "mat_camerarendertargetoverlaysize", "256", FCVAR_CHEAT ); static ConVar mat_hsv( "mat_hsv", "0", FCVAR_CHEAT ); static ConVar mat_yuv( "mat_yuv", "0", FCVAR_CHEAT ); @@ -178,6 +181,11 @@ void OverlayCameraRenderTarget( const char *pszMaterialName, float flX, float fl pMaterial = materials->FindMaterial( pszMaterialName, TEXTURE_GROUP_OTHER, true ); if( !IsErrorMaterial( pMaterial ) ) { +#ifdef MAPBASE + // HACKHACK + pMaterial->IncrementReferenceCount(); +#endif + CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( pMaterial ); IMesh* pMesh = pRenderContext->GetDynamicMesh( true ); @@ -203,6 +211,11 @@ void OverlayCameraRenderTarget( const char *pszMaterialName, float flX, float fl meshBuilder.End(); pMesh->Draw(); + +#ifdef MAPBASE + // HACKHACK + pMaterial->DecrementReferenceCount(); +#endif } } @@ -214,7 +227,11 @@ static void OverlayFrameBufferTexture( int nFrameBufferIndex ) IMaterial *pMaterial; char buf[MAX_PATH]; Q_snprintf( buf, MAX_PATH, "debug/debugfbtexture%d", nFrameBufferIndex ); +#ifdef MAPBASE + pMaterial = materials->FindMaterial( buf, NULL, true ); +#else pMaterial = materials->FindMaterial( buf, TEXTURE_GROUP_OTHER, true ); +#endif if( !IsErrorMaterial( pMaterial ) ) { CMatRenderContextPtr pRenderContext( materials ); @@ -586,12 +603,52 @@ void CDebugViewRender::Draw2DDebuggingInfo( const CViewSetup &view ) if ( mat_showcamerarendertarget.GetBool() ) { +#ifdef MAPBASE + float w = mat_camerarendertargetoverlaysize.GetFloat(); + float h = mat_camerarendertargetoverlaysize.GetFloat(); +#else float w = mat_wateroverlaysize.GetFloat(); float h = mat_wateroverlaysize.GetFloat(); +#endif #ifdef PORTAL g_pPortalRender->OverlayPortalRenderTargets( w, h ); #else + +#ifdef MAPBASE + int iCameraNum = mat_showcamerarendertarget.GetInt(); + + if (iCameraNum == 1) // Display the default camera + { + OverlayCameraRenderTarget( "debug/debugcamerarendertarget", 0, 0, w, h ); + } + else if (mat_showcamerarendertarget_all.GetBool()) // Display all cameras + { + OverlayCameraRenderTarget( "debug/debugcamerarendertarget", 0, 0, w, h ); + + // Already showed one camera + iCameraNum--; + + // Show Mapbase's cameras + char szTextureName[48]; + for (int i = 0; i < iCameraNum; i++) + { + V_snprintf( szTextureName, sizeof( szTextureName ), "debug/debugcamerarendertarget_camera%i", i ); + + // Show them vertically if the cvar is set to 2 + if (mat_showcamerarendertarget_all.GetInt() == 2) + OverlayCameraRenderTarget( szTextureName, 0, h * (i + 1), w, h ); + else + OverlayCameraRenderTarget( szTextureName, w * (i + 1), 0, w, h ); + } + } + else // Display one of the new cameras + { + OverlayCameraRenderTarget( VarArgs( "debug/debugcamerarendertarget_camera%i", iCameraNum-2 ), 0, 0, w, h ); + } +#else OverlayCameraRenderTarget( "debug/debugcamerarendertarget", 0, 0, w, h ); +#endif + #endif } @@ -655,6 +712,57 @@ CON_COMMAND_F( r_screenoverlay, "Draw specified material as an overlay", FCVAR_C } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// The same as above, but using the new indexed overlays +//----------------------------------------------------------------------------- +CON_COMMAND_F( r_screenoverlay_indexed, "Draw specified material as an overlay in the specified index", FCVAR_CHEAT|FCVAR_SERVER_CAN_EXECUTE ) +{ + if( args.ArgC() == 3 ) + { + int index = atoi( args[1] ); + if (index < 0 || index >= MAX_SCREEN_OVERLAYS) + { + Warning( "r_screenoverlay_indexed: '%i' is out of range (should be 0-9)\n", index ); + return; + } + + if ( !Q_stricmp( "off", args[2] ) ) + { + view->SetIndexedScreenOverlayMaterial( index, NULL ); + } + else + { + IMaterial *pMaterial = materials->FindMaterial( args[2], TEXTURE_GROUP_OTHER, false ); + if ( !IsErrorMaterial( pMaterial ) ) + { + view->SetIndexedScreenOverlayMaterial( index, pMaterial ); + } + else + { + view->SetIndexedScreenOverlayMaterial( index, NULL ); + } + } + } + else if ( args.ArgC() == 2 ) + { + int index = atoi( args[1] ); + if (index < 0 || index >= MAX_SCREEN_OVERLAYS) + { + Warning( "r_screenoverlay_indexed: '%i' is out of range (should be 0-9)\n", index ); + return; + } + + IMaterial *pMaterial = view->GetIndexedScreenOverlayMaterial( index ); + Warning( "r_screenoverlay_indexed %i: %s\n", index, pMaterial ? pMaterial->GetName() : "off" ); + } + else + { + Warning( "Format: r_screenoverlay_indexed []\n" ); + } +} +#endif + // Used to verify frame syncing. void CDebugViewRender::GenerateOverdrawForTesting() { diff --git a/game/client/viewpostprocess.cpp b/game/client/viewpostprocess.cpp index ec72069a..3a0c858c 100644 --- a/game/client/viewpostprocess.cpp +++ b/game/client/viewpostprocess.cpp @@ -13,8 +13,13 @@ #include "materialsystem/materialsystem_config.h" #include "tier1/callqueue.h" #include "colorcorrectionmgr.h" +#include "postprocess_shared.h" #include "view_scene.h" #include "c_world.h" + +//Tony; new +#include "c_baseplayer.h" + #include "bitmap/tgawriter.h" #include "filesystem.h" #include "tier0/vprof.h" @@ -34,6 +39,15 @@ float g_flCustomAutoExposureMax = 0; float g_flCustomBloomScale = 0.0f; float g_flCustomBloomScaleMinimum = 0.0f; +// mapmaker controlled depth of field +bool g_bDOFEnabled = false; +float g_flDOFNearBlurDepth = 20.0f; +float g_flDOFNearFocusDepth = 100.0f; +float g_flDOFFarFocusDepth = 250.0f; +float g_flDOFFarBlurDepth = 1000.0f; +float g_flDOFNearBlurRadius = 0.0f; +float g_flDOFFarBlurRadius = 10.0f; + bool g_bFlashlightIsOn = false; // hdr parameters @@ -44,7 +58,7 @@ ConVar mat_bloomamount_rate( "mat_bloomamount_rate", "0.05f", FCVAR_CHEAT ); static ConVar debug_postproc( "mat_debug_postprocessing_effects", "0", FCVAR_NONE, "0 = off, 1 = show post-processing passes in quadrants of the screen, 2 = only apply post-processing to the centre of the screen" ); static ConVar split_postproc( "mat_debug_process_halfscreen", "0", FCVAR_CHEAT ); static ConVar mat_postprocessing_combine( "mat_postprocessing_combine", "1", FCVAR_NONE, "Combine bloom, software anti-aliasing and color correction into one post-processing pass" ); -static ConVar mat_dynamic_tonemapping( "mat_dynamic_tonemapping", "0", FCVAR_CHEAT ); +static ConVar mat_dynamic_tonemapping( "mat_dynamic_tonemapping", "1", FCVAR_CHEAT ); static ConVar mat_show_ab_hdr( "mat_show_ab_hdr", "0" ); static ConVar mat_tonemapping_occlusion_use_stencil( "mat_tonemapping_occlusion_use_stencil", "0" ); ConVar mat_debug_autoexposure("mat_debug_autoexposure","0", FCVAR_CHEAT); @@ -129,7 +143,7 @@ struct ClipBox int m_maxx, m_maxy; }; -static void DrawClippedScreenSpaceRectangle( +static void DrawClippedScreenSpaceRectangle( IMaterial *pMaterial, int destx, int desty, int width, int height, @@ -188,7 +202,7 @@ void ApplyPostProcessingPasses(PostProcessingPass *pass_list, // table of effect CMatRenderContextPtr pRenderContext( materials ); ITexture *pSaveRenderTarget = pRenderContext->GetRenderTarget(); int pcount=0; - if ( debug_postproc.GetInt() == 1 ) + if ( debug_postproc.GetInt() == 1 ) { pRenderContext->SetRenderTarget(NULL); int dest_width,dest_height; @@ -289,13 +303,13 @@ void ApplyPostProcessingPasses(PostProcessingPass *pass_list, // table of effect pRenderContext->SetRenderTarget(NULL); int row=pcount/4; int col=pcount %4; - int dest_width,dest_height; - pRenderContext->GetRenderTargetDimensions( dest_width, dest_height ); - pRenderContext->Viewport( 0, 0, dest_width, dest_height ); + int destwidth,destheight; + pRenderContext->GetRenderTargetDimensions( destwidth, destheight ); + pRenderContext->Viewport( 0, 0, destwidth, destheight ); DrawClippedScreenSpaceRectangle(src_mat,10+col*220,10+row*220, 200,200, 0,0,1,1,1,1,cb); - } + } } if (dest_coords_out) { @@ -332,7 +346,7 @@ PostProcessingPass HDRSimulate_NonHDR[] = PPP_END }; -static void SetRenderTargetAndViewPort(ITexture *rt) +void SetRenderTargetAndViewPort(ITexture *rt) { tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); @@ -351,7 +365,7 @@ static void SetRenderTargetAndViewPort(ITexture *rt) // destination than we actually intend to, so as to replicate the border pixels so that garbage // pixels do not get sucked into the sampling. To deal with this, we always add FILTER_KERNEL_SLOP // to our widths/heights if there is room for them in the destination. -static void DrawScreenSpaceRectangleWithSlop( +static void DrawScreenSpaceRectangleWithSlop( ITexture *dest_rt, IMaterial *pMaterial, int destx, int desty, @@ -364,8 +378,8 @@ static void DrawScreenSpaceRectangleWithSlop( ) { // add slop - int slopwidth = width + FILTER_KERNEL_SLOP; //min(dest_rt->GetActualWidth()-destx,width+FILTER_KERNEL_SLOP); - int slopheight = height + FILTER_KERNEL_SLOP; //min(dest_rt->GetActualHeight()-desty,height+FILTER_KERNEL_SLOP); + int slopwidth = width + FILTER_KERNEL_SLOP; //MIN(dest_rt->GetActualWidth()-destx,width+FILTER_KERNEL_SLOP); + int slopheight = height + FILTER_KERNEL_SLOP; //MIN(dest_rt->GetActualHeight()-desty,height+FILTER_KERNEL_SLOP); // adjust coordinates for slop src_texture_x1 = FLerp( src_texture_x0, src_texture_x1, destx, destx + width - 1, destx + slopwidth - 1 ); @@ -765,7 +779,19 @@ static float GetCurrentBloomScale( void ) { // Use the appropriate bloom scale settings. Mapmakers's overrides the convar settings. float flCurrentBloomScale = 1.0f; - if ( g_bUseCustomBloomScale ) + + //Tony; get the local player first.. + C_BasePlayer *pLocalPlayer = NULL; + + if ( ( gpGlobals->maxClients > 1 ) ) + pLocalPlayer = (C_BasePlayer*)C_BasePlayer::GetLocalPlayer(); + + //Tony; in multiplayer, get the local player etc. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin > 0.0f) ) + { + flCurrentBloomScale = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin; + } + else if ( g_bUseCustomBloomScale ) { flCurrentBloomScale = g_flCustomBloomScale; } @@ -778,8 +804,19 @@ static float GetCurrentBloomScale( void ) static void GetExposureRange( float *flAutoExposureMin, float *flAutoExposureMax ) { + //Tony; get the local player first.. + C_BasePlayer *pLocalPlayer = NULL; + + if ( ( gpGlobals->maxClients > 1 ) ) + pLocalPlayer = (C_BasePlayer*)C_BasePlayer::GetLocalPlayer(); + + //Tony; in multiplayer, get the local player etc. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin > 0.0f) ) + { + *flAutoExposureMin = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin; + } // Get min - if ( ( g_bUseCustomAutoExposureMin ) && ( g_flCustomAutoExposureMin > 0.0f ) ) + else if ( ( g_bUseCustomAutoExposureMin ) && ( g_flCustomAutoExposureMin > 0.0f ) ) { *flAutoExposureMin = g_flCustomAutoExposureMin; } @@ -788,8 +825,13 @@ static void GetExposureRange( float *flAutoExposureMin, float *flAutoExposureMax *flAutoExposureMin = mat_autoexposure_min.GetFloat(); } + //Tony; in multiplayer, get the value from the local player, if it's set. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMax > 0.0f) ) + { + *flAutoExposureMax = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMax; + } // Get max - if ( ( g_bUseCustomAutoExposureMax ) && ( g_flCustomAutoExposureMax > 0.0f ) ) + else if ( ( g_bUseCustomAutoExposureMax ) && ( g_flCustomAutoExposureMax > 0.0f ) ) { *flAutoExposureMax = g_flCustomAutoExposureMax; } @@ -947,10 +989,10 @@ void CLuminanceHistogramSystem::DisplayHistogram( void ) { engine->Con_NPrintf( 17, "(All values in linear space)" ); - engine->Con_NPrintf( 21, "AvgLum @ %4.2f%% mat_tonemap_min_avglum = %4.2f%% Using %d pixels of %d pixels on screen (%3d%%)", + engine->Con_NPrintf( 21, "AvgLum @ %4.2f%% mat_tonemap_min_avglum = %4.2f%% Using %d pixels of %d pixels on screen (%3d%%)", MAX( 0.0f, FindLocationOfPercentBrightPixels( 50.0f ) ) * 100.0f, mat_tonemap_min_avglum.GetFloat(), nTotalValidPixels, ( dest_width * dest_height ), int( float( nTotalValidPixels ) * 100.0f / float( dest_width * dest_height ) ) ); - engine->Con_NPrintf( 23, "BloomScale = %4.2f mat_hdr_manual_tonemap_rate = %4.2f mat_accelerate_adjust_exposure_down = %4.2f", + engine->Con_NPrintf( 23, "BloomScale = %4.2f mat_hdr_manual_tonemap_rate = %4.2f mat_accelerate_adjust_exposure_down = %4.2f", GetCurrentBloomScale(), mat_hdr_manual_tonemap_rate.GetFloat(), mat_accelerate_adjust_exposure_down.GetFloat() ); } @@ -1113,6 +1155,32 @@ void CLuminanceHistogramSystem::DisplayHistogram( void ) pRenderContext->PopRenderTargetAndViewport(); } +// Local contrast setting +PostProcessParameters_t s_LocalPostProcessParameters; + +// view fade param settings +static Vector4D s_viewFadeColor; +static bool s_bViewFadeModulate; + +static bool s_bOverridePostProcessParams = false; + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters ) +{ + if (!s_bOverridePostProcessParams) + s_LocalPostProcessParameters = *pPostProcessParameters; +} + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters, bool bOverride ) +{ + s_bOverridePostProcessParams = bOverride; + s_LocalPostProcessParameters = *pPostProcessParameters; +} + +void SetViewFadeParams( byte r, byte g, byte b, byte a, bool bModulate ) +{ + s_viewFadeColor.Init( float( r ) / 255.0f, float( g ) / 255.0f, float( b ) / 255.0f, float( a ) / 255.0f ); + s_bViewFadeModulate = bModulate; +} static CLuminanceHistogramSystem g_HDR_HistogramSystem; @@ -1208,15 +1276,32 @@ class CEnginePostMaterialProxy : public CEntityMaterialProxy IMaterialVar *m_pMaterialParam_AAValues; IMaterialVar *m_pMaterialParam_AAValues2; IMaterialVar *m_pMaterialParam_BloomEnable; + IMaterialVar *m_pMaterialParam_BloomAmount; IMaterialVar *m_pMaterialParam_BloomUVTransform; IMaterialVar *m_pMaterialParam_ColCorrectEnable; IMaterialVar *m_pMaterialParam_ColCorrectNumLookups; IMaterialVar *m_pMaterialParam_ColCorrectDefaultWeight; IMaterialVar *m_pMaterialParam_ColCorrectLookupWeights; + IMaterialVar *m_pMaterialParam_LocalContrastStrength; + IMaterialVar *m_pMaterialParam_LocalContrastEdgeStrength; + IMaterialVar *m_pMaterialParam_VignetteStart; + IMaterialVar *m_pMaterialParam_VignetteEnd; + IMaterialVar *m_pMaterialParam_VignetteBlurEnable; + IMaterialVar *m_pMaterialParam_VignetteBlurStrength; + IMaterialVar *m_pMaterialParam_FadeToBlackStrength; + IMaterialVar *m_pMaterialParam_DepthBlurFocalDistance; + IMaterialVar *m_pMaterialParam_DepthBlurStrength; + IMaterialVar *m_pMaterialParam_ScreenBlurStrength; + IMaterialVar *m_pMaterialParam_FilmGrainStrength; + IMaterialVar *m_pMaterialParam_VomitEnable; + IMaterialVar *m_pMaterialParam_VomitColor1; + IMaterialVar *m_pMaterialParam_VomitColor2; + IMaterialVar *m_pMaterialParam_FadeColor; + IMaterialVar *m_pMaterialParam_FadeType; public: static IMaterial * SetupEnginePostMaterial( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, const Vector2D & destTexSize, - bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength ); + bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength, float flBloomAmount ); static void SetupEnginePostMaterialAA( bool bPerformSoftwareAA, float flAAStrength ); static void SetupEnginePostMaterialTextureTransform( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, Vector2D destTexSize ); @@ -1225,12 +1310,14 @@ class CEnginePostMaterialProxy : public CEntityMaterialProxy static float s_vBloomAAValues2[4]; static float s_vBloomUVTransform[4]; static int s_PostBloomEnable; + static float s_PostBloomAmount; }; float CEnginePostMaterialProxy::s_vBloomAAValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float CEnginePostMaterialProxy::s_vBloomAAValues2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float CEnginePostMaterialProxy::s_vBloomUVTransform[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; int CEnginePostMaterialProxy::s_PostBloomEnable = 1; +float CEnginePostMaterialProxy::s_PostBloomAmount = 1.0f; CEnginePostMaterialProxy::CEnginePostMaterialProxy() { @@ -1238,10 +1325,22 @@ CEnginePostMaterialProxy::CEnginePostMaterialProxy() m_pMaterialParam_AAValues2 = NULL; m_pMaterialParam_BloomUVTransform = NULL; m_pMaterialParam_BloomEnable = NULL; + m_pMaterialParam_BloomAmount = NULL; m_pMaterialParam_ColCorrectEnable = NULL; m_pMaterialParam_ColCorrectNumLookups = NULL; m_pMaterialParam_ColCorrectDefaultWeight = NULL; m_pMaterialParam_ColCorrectLookupWeights = NULL; + m_pMaterialParam_LocalContrastStrength = NULL; + m_pMaterialParam_LocalContrastEdgeStrength = NULL; + m_pMaterialParam_VignetteStart = NULL; + m_pMaterialParam_VignetteEnd = NULL; + m_pMaterialParam_VignetteBlurEnable = NULL; + m_pMaterialParam_VignetteBlurStrength = NULL; + m_pMaterialParam_FadeToBlackStrength = NULL; + m_pMaterialParam_DepthBlurFocalDistance = NULL; + m_pMaterialParam_DepthBlurStrength = NULL; + m_pMaterialParam_ScreenBlurStrength = NULL; + m_pMaterialParam_FilmGrainStrength = NULL; } CEnginePostMaterialProxy::~CEnginePostMaterialProxy() @@ -1257,10 +1356,27 @@ bool CEnginePostMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues m_pMaterialParam_AAValues2 = pMaterial->FindVar( "$AAInternal3", &bFoundVar, false ); m_pMaterialParam_BloomUVTransform = pMaterial->FindVar( "$AAInternal2", &bFoundVar, false ); m_pMaterialParam_BloomEnable = pMaterial->FindVar( "$bloomEnable", &bFoundVar, false ); + m_pMaterialParam_BloomAmount = pMaterial->FindVar( "$bloomAmount", &bFoundVar, false ); m_pMaterialParam_ColCorrectEnable = pMaterial->FindVar( "$colCorrectEnable", &bFoundVar, false ); m_pMaterialParam_ColCorrectNumLookups = pMaterial->FindVar( "$colCorrect_NumLookups", &bFoundVar, false ); m_pMaterialParam_ColCorrectDefaultWeight = pMaterial->FindVar( "$colCorrect_DefaultWeight", &bFoundVar, false ); m_pMaterialParam_ColCorrectLookupWeights = pMaterial->FindVar( "$colCorrect_LookupWeights", &bFoundVar, false ); + m_pMaterialParam_LocalContrastStrength = pMaterial->FindVar( "$localContrastScale", &bFoundVar, false ); + m_pMaterialParam_LocalContrastEdgeStrength = pMaterial->FindVar( "$localContrastEdgeScale", &bFoundVar, false ); + m_pMaterialParam_VignetteStart = pMaterial->FindVar( "$localContrastVignetteStart", &bFoundVar, false ); + m_pMaterialParam_VignetteEnd = pMaterial->FindVar( "$localContrastVignetteEnd", &bFoundVar, false ); + m_pMaterialParam_VignetteBlurEnable = pMaterial->FindVar( "$blurredVignetteEnable", &bFoundVar, false ); + m_pMaterialParam_VignetteBlurStrength = pMaterial->FindVar( "$blurredVignetteScale", &bFoundVar, false ); + m_pMaterialParam_FadeToBlackStrength = pMaterial->FindVar( "$fadeToBlackScale", &bFoundVar, false ); + m_pMaterialParam_DepthBlurFocalDistance = pMaterial->FindVar( "$depthBlurFocalDistance", &bFoundVar, false ); + m_pMaterialParam_DepthBlurStrength = pMaterial->FindVar( "$depthBlurStrength", &bFoundVar, false ); + m_pMaterialParam_ScreenBlurStrength = pMaterial->FindVar( "$screenBlurStrength", &bFoundVar, false ); + m_pMaterialParam_FilmGrainStrength = pMaterial->FindVar( "$noiseScale", &bFoundVar, false ); + m_pMaterialParam_VomitEnable = pMaterial->FindVar( "$vomitEnable", &bFoundVar, false ); + m_pMaterialParam_VomitColor1 = pMaterial->FindVar( "$vomitColor1", &bFoundVar, false ); + m_pMaterialParam_VomitColor2 = pMaterial->FindVar( "$vomitColor2", &bFoundVar, false ); + m_pMaterialParam_FadeColor = pMaterial->FindVar( "$fadeColor", &bFoundVar, false ); + m_pMaterialParam_FadeType = pMaterial->FindVar( "$fade", &bFoundVar, false ); return true; } @@ -1278,6 +1394,56 @@ void CEnginePostMaterialProxy::OnBind( C_BaseEntity *pEnt ) if ( m_pMaterialParam_BloomEnable ) m_pMaterialParam_BloomEnable->SetIntValue( s_PostBloomEnable ); + + if ( m_pMaterialParam_BloomAmount ) + m_pMaterialParam_BloomAmount->SetFloatValue( s_PostBloomAmount ); + + if ( m_pMaterialParam_LocalContrastStrength ) + m_pMaterialParam_LocalContrastStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_LOCAL_CONTRAST_STRENGTH ] ); + + if ( m_pMaterialParam_LocalContrastEdgeStrength ) + m_pMaterialParam_LocalContrastEdgeStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_LOCAL_CONTRAST_EDGE_STRENGTH ] ); + + if ( m_pMaterialParam_VignetteStart ) + m_pMaterialParam_VignetteStart->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_START ] ); + + if ( m_pMaterialParam_VignetteEnd ) + m_pMaterialParam_VignetteEnd->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_END ] ); + + if ( m_pMaterialParam_VignetteBlurEnable ) + m_pMaterialParam_VignetteBlurEnable->SetIntValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ] > 0.0f ? 1 : 0 ); + + if ( m_pMaterialParam_VignetteBlurStrength ) + m_pMaterialParam_VignetteBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_FadeToBlackStrength ) + m_pMaterialParam_FadeToBlackStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_FADE_TO_BLACK_STRENGTH ] ); + + if ( m_pMaterialParam_DepthBlurFocalDistance ) + m_pMaterialParam_DepthBlurFocalDistance->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_DEPTH_BLUR_FOCAL_DISTANCE ] ); + + if ( m_pMaterialParam_DepthBlurStrength ) + m_pMaterialParam_DepthBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_DEPTH_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_ScreenBlurStrength ) + m_pMaterialParam_ScreenBlurStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_SCREEN_BLUR_STRENGTH ] ); + + if ( m_pMaterialParam_FilmGrainStrength ) + m_pMaterialParam_FilmGrainStrength->SetFloatValue( s_LocalPostProcessParameters.m_flParameters[ PPPN_FILM_GRAIN_STRENGTH ] ); + + + + if ( m_pMaterialParam_FadeType ) + { + int nFadeType = ( s_bViewFadeModulate ) ? 2 : 1; + nFadeType = ( s_viewFadeColor[3] > 0.0f ) ? nFadeType : 0; + m_pMaterialParam_FadeType->SetIntValue( nFadeType ); + } + + if ( m_pMaterialParam_FadeColor ) + { + m_pMaterialParam_FadeColor->SetVecValue( s_viewFadeColor.Base(), 4 ); + } } IMaterial *CEnginePostMaterialProxy::GetMaterial() @@ -1350,26 +1516,29 @@ void CEnginePostMaterialProxy::SetupEnginePostMaterialTextureTransform( const Ve } IMaterial * CEnginePostMaterialProxy::SetupEnginePostMaterial( const Vector4D & fullViewportBloomUVs, const Vector4D & fullViewportFBUVs, const Vector2D & destTexSize, - bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength ) + bool bPerformSoftwareAA, bool bPerformBloom, bool bPerformColCorrect, float flAAStrength, float flBloomAmount ) { // Shouldn't get here if none of the effects are enabled Assert( bPerformSoftwareAA || bPerformBloom || bPerformColCorrect ); - s_PostBloomEnable = bPerformBloom ? 1 : 0; + s_PostBloomEnable = bPerformBloom ? 1 : 0; + s_PostBloomAmount = flBloomAmount; SetupEnginePostMaterialAA( bPerformSoftwareAA, flAAStrength ); - if ( bPerformSoftwareAA || bPerformColCorrect ) + //if ( bPerformSoftwareAA || bPerformColCorrect ) { SetupEnginePostMaterialTextureTransform( fullViewportBloomUVs, fullViewportFBUVs, destTexSize ); return materials->FindMaterial( "dev/engine_post", TEXTURE_GROUP_OTHER, true); } + /* else { // Just use the old bloomadd material (which uses additive blending, unlike engine_post) // NOTE: this path is what gets used for DX8 (which cannot enable AA or col-correction) return materials->FindMaterial( "dev/bloomadd", TEXTURE_GROUP_OTHER, true); } + */ } EXPOSE_INTERFACE( CEnginePostMaterialProxy, IMaterialProxy, "engine_post" IMATERIAL_PROXY_INTERFACE_VERSION ); @@ -1377,7 +1546,7 @@ EXPOSE_INTERFACE( CEnginePostMaterialProxy, IMaterialProxy, "engine_post" IMATER static void DrawBloomDebugBoxes( IMatRenderContext *pRenderContext ) { - // draw inset rects which should have a centered bloom + // draw inset rects which should have a centered bloom pRenderContext->SetRenderTarget(NULL); int dest_width, dest_height; pRenderContext->GetRenderTargetDimensions( dest_width, dest_height ); @@ -1406,15 +1575,15 @@ static void DrawBloomDebugBoxes( IMatRenderContext *pRenderContext ) // upper right pRenderContext->Viewport( dest_width - inset - size, inset, size, size ); pRenderContext->ClearBuffers( true, true ); - + // lower right pRenderContext->Viewport( dest_width - inset - size, dest_height - inset - size, size, size ); pRenderContext->ClearBuffers( true, true ); - + // lower left pRenderContext->Viewport( inset, dest_height - inset - size, size, size ); pRenderContext->ClearBuffers( true, true ); - + // restore pRenderContext->Viewport( 0, 0, dest_width, dest_height ); } @@ -1428,7 +1597,7 @@ float GetBloomAmount( void ) HDRType_t hdrType = g_pMaterialSystemHardwareConfig->GetHDRType(); bool bBloomEnabled = (mat_hdr_level.GetInt() >= 1); - + if ( !engine->MapHasHDRLighting() ) bBloomEnabled = false; if ( mat_force_bloom.GetInt() ) @@ -1443,7 +1612,7 @@ float GetBloomAmount( void ) } if( !g_pMaterialSystemHardwareConfig->CanDoSRGBReadFromRTs() && g_pMaterialSystemHardwareConfig->FakeSRGBWrite() ) { - bBloomEnabled = false; + bBloomEnabled = false; } float flBloomAmount=0.0; @@ -1520,13 +1689,35 @@ void DumpTGAofRenderTarget( const int width, const int height, const char *pFile static bool s_bScreenEffectTextureIsUpdated = false; +// WARNING: This function sets rendertarget and viewport. Save and restore is left to the caller. +static void DownsampleFBQuarterSize( IMatRenderContext *pRenderContext, int nSrcWidth, int nSrcHeight, ITexture* pDest, + bool bFloatHDR = false ) +{ + Assert( pRenderContext ); + Assert( pDest ); + + IMaterial *downsample_mat = materials->FindMaterial( bFloatHDR ? "dev/downsample" : "dev/downsample_non_hdr", TEXTURE_GROUP_OTHER, true ); + + // *Everything* in here relies on the small RTs being exactly 1/4 the full FB res + Assert( pDest->GetActualWidth() == nSrcWidth / 4 ); + Assert( pDest->GetActualHeight() == nSrcHeight / 4 ); + + // downsample fb to rt0 + SetRenderTargetAndViewPort( pDest ); + // note the -2's below. Thats because we are downsampling on each axis and the shader + // accesses pixels on both sides of the source coord + pRenderContext->DrawScreenSpaceRectangle( downsample_mat, 0, 0, nSrcWidth/4, nSrcHeight/4, + 0, 0, nSrcWidth-2, nSrcHeight-2, + nSrcWidth, nSrcHeight ); +} + void Generate8BitBloomTexture( IMatRenderContext *pRenderContext, float flBloomScale, - int x, int y, int w, int h ) + int x, int y, int w, int h ) { tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); pRenderContext->PushRenderTargetAndViewport(); - ITexture *pSrc = materials->FindTexture( "_rt_VanceHDR", TEXTURE_GROUP_RENDER_TARGET ); + ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); int nSrcWidth = pSrc->GetActualWidth(); int nSrcHeight = pSrc->GetActualHeight(); //,dest_height; @@ -1582,7 +1773,7 @@ void Generate8BitBloomTexture( IMatRenderContext *pRenderContext, float flBloomS // Gaussian blur y rt1 to rt0 SetRenderTargetAndViewPort( dest_rt0 ); IMaterialVar *pBloomAmountVar = yblur_mat->FindVar( "$bloomamount", NULL ); - pBloomAmountVar->SetFloatValue( flBloomScale ); + pBloomAmountVar->SetFloatValue( 1.0f ); // the bloom amount is now applied in engine_post or bloomadd materials pRenderContext->DrawScreenSpaceRectangle( yblur_mat, 0, 0, nSrcWidth / 4, nSrcHeight / 4, 0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1, nSrcWidth / 4, nSrcHeight / 4 ); @@ -1622,7 +1813,7 @@ static void DoPreBloomTonemapping( IMatRenderContext *pRenderContext, int nX, in { SetToneMapScale( pRenderContext, flTargetScalarClamped, flAutoExposureMin, flAutoExposureMax ); } - + if ( mat_debug_autoexposure.GetInt() || mat_show_histogram.GetInt() ) { bool bDrawTextThisFrame = true; @@ -1659,10 +1850,6 @@ static void DoPreBloomTonemapping( IMatRenderContext *pRenderContext, int nX, in } } } - else - { - SetToneMapScale(pRenderContext, 1.0f, flAutoExposureMin, flAutoExposureMax); - } } static void DoPostBloomTonemapping( IMatRenderContext *pRenderContext, int nX, int nY, int nWidth, int nHeight, float flAutoExposureMin, float flAutoExposureMax ) @@ -1832,23 +2019,23 @@ static void CreatePyroSide( int nSide, Vector2D &vMaxSize ) static float PryoVignetteSTHorizontal[ 6 ][ 2 ] = { - { 0.0f, 0.0f }, - { 0.0f, 1.0f }, - { 1.0f, 1.0f }, + { 0.0f, 0.0f }, + { 0.0f, 1.0f }, + { 1.0f, 1.0f }, - { 1.0f, 1.0f }, - { 0.0f, 0.0f }, + { 1.0f, 1.0f }, + { 0.0f, 0.0f }, { 1.0f, 0.0f } }; static float PryoVignetteSTVertical[ 6 ][ 2 ] = { - { 0.0f, 0.0f }, - { 1.0f, 0.0f }, - { 1.0f, 1.0f }, + { 0.0f, 0.0f }, + { 1.0f, 0.0f }, + { 1.0f, 1.0f }, - { 1.0f, 1.0f }, - { 0.0f, 0.0f }, + { 1.0f, 1.0f }, + { 0.0f, 0.0f }, { 0.0f, 1.0f } }; @@ -1991,7 +2178,7 @@ static void DrawPyroVignette( int nDestX, int nDestY, int nWidth, int nHeight, / } -static void DrawPyroPost( IMaterial *pMaterial, +static void DrawPyroPost( IMaterial *pMaterial, int nDestX, int nDestY, int nWidth, int nHeight, // Rect to draw into in screen space float flSrcTextureX0, float flSrcTextureY0, // which texel you want to appear at destx/y float flSrcTextureX1, float flSrcTextureY1, // which texel you want to appear at destx+width-1, desty+height-1 @@ -2096,7 +2283,7 @@ static void DrawPyroPost( IMaterial *pMaterial, meshBuilder.Position3f( flLeftX + (float) 0 * flWidth, flTopY - (float) (0+1) * flHeight, 0.0f ); meshBuilder.TexCoord2f( 0, flLeftU + (float) 0 * flUWidth, flTopV + (float)(0+1) * flVHeight); meshBuilder.AdvanceVertex(); - + // Bottom Bar // Top left @@ -2269,7 +2456,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b } switch( hdrType ) - { + { case HDR_TYPE_NONE: case HDR_TYPE_INTEGER: { @@ -2329,8 +2516,8 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // bloom, software-AA and colour-correction (applied in 1 pass, after generation of the bloom texture) bool bPerformSoftwareAA = IsX360() && ( engine->GetDXSupportLevel() >= 90 ) && ( flAAStrength != 0.0f ); - bool bPerformBloom = /*!bPostVGui && ( flBloomScale > 0.0f ) && ( engine->GetDXSupportLevel() >= 90 )*/ false; // we use custom bloom now - bool bPerformColCorrect = !bPostVGui && + bool bPerformBloom = true; //!bPostVGui && ( flBloomScale > 0.0f ) && ( engine->GetDXSupportLevel() >= 90 ); + bool bPerformColCorrect = !bPostVGui && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90) && ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_FLOAT ) && g_pColorCorrectionMgr->HasNonZeroColorCorrectionWeights() && @@ -2389,12 +2576,12 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b partialViewportPostDestRect.height -= 0.50f*fullViewportPostDestRect.height; // This math interprets texel coords as being at corner pixel centers (*not* at corner vertices): - Vector2D uvScale( 1.0f - ( (w / 2) / (float)(w - 1) ), + Vector2D uvScaleCorner( 1.0f - ( (w / 2) / (float)(w - 1) ), 1.0f - ( (h / 2) / (float)(h - 1) ) ); - CenterScaleQuadUVs( partialViewportPostSrcCorners, uvScale ); + CenterScaleQuadUVs( partialViewportPostSrcCorners, uvScaleCorner ); } - // Temporary hack... Color correction was crashing on the first frame + // Temporary hack... Color correction was crashing on the first frame // when run outside the debugger for some mods (DoD). This forces it to skip // a frame, ensuring we don't get the weird texture crash we otherwise would. // FIXME: This will be removed when the true cause is found [added: Main CL 144694] @@ -2407,7 +2594,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b { // Perform post-processing in one combined pass - IMaterial *post_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, bPerformBloom, bPerformColCorrect, flAAStrength ); + IMaterial *post_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, bPerformBloom, bPerformColCorrect, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2416,10 +2603,10 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b pRenderContext->DrawScreenSpaceRectangle(post_mat, // TomF - offset already done by the viewport. - 0,0, //partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + 0,0, //partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, dest_rt1->GetActualWidth(),dest_rt1->GetActualHeight(), GetClientWorldEntity()->GetClientRenderable(), mat_postprocess_x.GetInt(), mat_postprocess_y.GetInt() ); @@ -2435,7 +2622,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // Perform post-processing in three separate passes if ( bPerformSoftwareAA ) { - IMaterial *aa_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, false, false, flAAStrength ); + IMaterial *aa_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, bPerformSoftwareAA, false, false, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2444,10 +2631,10 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b pRenderContext->DrawScreenSpaceRectangle(aa_mat, // TODO: check if offsets should be 0,0 here, as with the combined-pass case - partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, dest_rt1->GetActualWidth(),dest_rt1->GetActualHeight(), GetClientWorldEntity()->GetClientRenderable()); @@ -2460,7 +2647,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b if ( bPerformBloom ) { - IMaterial *bloom_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, bPerformBloom, false, flAAStrength ); + IMaterial *bloom_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, bPerformBloom, false, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2469,10 +2656,10 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b pRenderContext->DrawScreenSpaceRectangle(bloom_mat, // TODO: check if offsets should be 0,0 here, as with the combined-pass case - partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, dest_rt1->GetActualWidth(),dest_rt1->GetActualHeight(), GetClientWorldEntity()->GetClientRenderable()); @@ -2491,7 +2678,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect ); } - IMaterial *colcorrect_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, false, bPerformColCorrect, flAAStrength ); + IMaterial *colcorrect_mat = CEnginePostMaterialProxy::SetupEnginePostMaterial( fullViewportPostSrcCorners, fullViewportPostDestCorners, destTexSize, false, false, bPerformColCorrect, flAAStrength, flBloomScale ); if (bSplitScreenHDR) { @@ -2500,10 +2687,10 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b pRenderContext->DrawScreenSpaceRectangle(colcorrect_mat, // TODO: check if offsets should be 0,0 here, as with the combined-pass case - partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, dest_rt1->GetActualWidth(),dest_rt1->GetActualHeight(), GetClientWorldEntity()->GetClientRenderable()); @@ -2527,19 +2714,19 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b DrawPyroVignette( // TODO: check if offsets should be 0,0 here, as with the combined-pass case - partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, GetClientWorldEntity()->GetClientRenderable() ); IMaterial *pPyroVisionPostMaterial = materials->FindMaterial( "dev/pyro_post", TEXTURE_GROUP_OTHER, true); DrawPyroPost( pPyroVisionPostMaterial, // TODO: check if offsets should be 0,0 here, as with the combined-pass case - partialViewportPostDestRect.x, partialViewportPostDestRect.y, - partialViewportPostDestRect.width, partialViewportPostDestRect.height, - partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, - partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, + partialViewportPostDestRect.x, partialViewportPostDestRect.y, + partialViewportPostDestRect.width, partialViewportPostDestRect.height, + partialViewportPostSrcCorners.x, partialViewportPostSrcCorners.y, + partialViewportPostSrcCorners.z, partialViewportPostSrcCorners.w, dest_rt1->GetActualWidth(),dest_rt1->GetActualHeight(), GetClientWorldEntity()->GetClientRenderable() ); } @@ -2576,20 +2763,14 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b mat_hdr_tonemapscale.SetValue( scalevalue ); } } - else - { - float scalevalue = 1.0f; - pRenderContext->SetGoalToneMappingScale(scalevalue); - mat_hdr_tonemapscale.SetValue(scalevalue); - } - - /*IMaterial *pBloomMaterial; + + IMaterial *pBloomMaterial; pBloomMaterial = materials->FindMaterial( "dev/floattoscreen_combine", "" ); IMaterialVar *pBloomAmountVar = pBloomMaterial->FindVar( "$bloomamount", NULL ); pBloomAmountVar->SetFloatValue( flBloomScale ); - + PostProcessingPass* selectedHDR; - + if ( flBloomScale > 0.0 ) { selectedHDR = HDRFinal_Float; @@ -2598,25 +2779,25 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b { selectedHDR = HDRFinal_Float_NoBloom; } - + if (mat_show_ab_hdr.GetInt()) { ClipBox splitScreenClip; - + splitScreenClip.m_minx = splitScreenClip.m_miny = 0; // Left half splitScreenClip.m_maxx = dest_width / 2; splitScreenClip.m_maxy = dest_height - 1; - + ApplyPostProcessingPasses(HDRSimulate_NonHDR, &splitScreenClip); - + // Right half splitScreenClip.m_minx = splitScreenClip.m_maxx; splitScreenClip.m_maxx = dest_width - 1; - + ApplyPostProcessingPasses(selectedHDR, &splitScreenClip); - + } else { @@ -2634,7 +2815,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b SetToneMapScale( pRenderContext, scalevalue, flAutoExposureMin, flAutoExposureMax ); } pRenderContext->SetRenderTarget( NULL ); - break;*/ + break; } } @@ -2645,6 +2826,7 @@ void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, b // Motion Blur Material Proxy ========================================================================================= static float g_vMotionBlurValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static float g_vMotionBlurViewportValues[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; class CMotionBlurMaterialProxy : public CEntityMaterialProxy { public: @@ -2656,6 +2838,7 @@ class CMotionBlurMaterialProxy : public CEntityMaterialProxy private: IMaterialVar *m_pMaterialParam; + IMaterialVar *m_pMaterialParamViewport; }; CMotionBlurMaterialProxy::CMotionBlurMaterialProxy() @@ -2676,6 +2859,10 @@ bool CMotionBlurMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues if ( bFoundVar == false) return false; + m_pMaterialParamViewport = pMaterial->FindVar( "$MotionBlurViewportInternal", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + return true; } @@ -2685,6 +2872,11 @@ void CMotionBlurMaterialProxy::OnBind( C_BaseEntity *pEnt ) { m_pMaterialParam->SetVecValue( g_vMotionBlurValues, 4 ); } + + if ( m_pMaterialParamViewport != NULL ) + { + m_pMaterialParamViewport->SetVecValue( g_vMotionBlurViewportValues, 4 ); + } } IMaterial *CMotionBlurMaterialProxy::GetMaterial() @@ -2701,24 +2893,49 @@ EXPOSE_INTERFACE( CMotionBlurMaterialProxy, IMaterialProxy, "MotionBlur" IMATERI // Image-space Motion Blur ============================================================================================ //===================================================================================================================== ConVar mat_motion_blur_enabled( "mat_motion_blur_enabled", "1", FCVAR_ARCHIVE ); + ConVar mat_motion_blur_forward_enabled( "mat_motion_blur_forward_enabled", "0" ); ConVar mat_motion_blur_falling_min( "mat_motion_blur_falling_min", "10.0" ); + ConVar mat_motion_blur_falling_max( "mat_motion_blur_falling_max", "20.0" ); ConVar mat_motion_blur_falling_intensity( "mat_motion_blur_falling_intensity", "1.0" ); //ConVar mat_motion_blur_roll_intensity( "mat_motion_blur_roll_intensity", "1.0" ); ConVar mat_motion_blur_rotation_intensity( "mat_motion_blur_rotation_intensity", "1.0" ); ConVar mat_motion_blur_strength( "mat_motion_blur_strength", "1.0" ); -void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ) +struct MotionBlurHistory_t { -#ifdef CSS_PERF_TEST - return; -#endif - if ( ( !mat_motion_blur_enabled.GetInt() ) || ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 ) ) + MotionBlurHistory_t() + { + m_flLastTimeUpdate = 0.0f; + m_flPreviousPitch = 0.0f; + m_flPreviousYaw = 0.0f; + m_vPreviousPositon.Init( 0.0f, 0.0f, 0.0f ); + m_mPreviousFrameBasisVectors; + m_flNoRotationalMotionBlurUntil = 0.0f; + SetIdentityMatrix( m_mPreviousFrameBasisVectors ); + } + + float m_flLastTimeUpdate; + float m_flPreviousPitch; + float m_flPreviousYaw; + Vector m_vPreviousPositon; + matrix3x4_t m_mPreviousFrameBasisVectors; + float m_flNoRotationalMotionBlurUntil; +}; + +void DoImageSpaceMotionBlur( const CViewSetup &viewSetup ) +{ + if ( !mat_motion_blur_enabled.GetInt() ) { return; } + int x = viewSetup.x; + int y = viewSetup.y; + int w = viewSetup.width; + int h = viewSetup.height; + //======================================================================================================// // Get these convars here to make it easier to remove them later and to default each client differently // //======================================================================================================// @@ -2737,22 +2954,19 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //=====================// // Previous frame data // //=====================// - static float s_flLastTimeUpdate = 0.0f; - static float s_flPreviousPitch = 0.0f; - static float s_flPreviousYaw = 0.0f; - static float s_vPreviousPositon[3] = { 0.0f, 0.0f, 0.0f }; - static matrix3x4_t s_mPreviousFrameBasisVectors; - static float s_flNoRotationalMotionBlurUntil = 0.0f; + static MotionBlurHistory_t history; + //float vPreviousSideVec[3] = { s_mPreviousFrameBasisVectors[0][1], s_mPreviousFrameBasisVectors[1][1], s_mPreviousFrameBasisVectors[2][1] }; //float vPreviousForwardVec[3] = { s_mPreviousFrameBasisVectors[0][0], s_mPreviousFrameBasisVectors[1][0], s_mPreviousFrameBasisVectors[2][0] }; //float vPreviousUpVec[3] = { s_mPreviousFrameBasisVectors[0][2], s_mPreviousFrameBasisVectors[1][2], s_mPreviousFrameBasisVectors[2][2] }; - float flTimeElapsed = gpGlobals->realtime - s_flLastTimeUpdate; + float flTimeElapsed = gpGlobals->realtime - history.m_flLastTimeUpdate; + //===================================// // Get current pitch & wrap to +-180 // //===================================// - float flCurrentPitch = view.angles[PITCH]; + float flCurrentPitch = viewSetup.angles[PITCH]; while ( flCurrentPitch > 180.0f ) flCurrentPitch -= 360.0f; while ( flCurrentPitch < -180.0f ) @@ -2761,35 +2975,39 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //=================================// // Get current yaw & wrap to +-180 // //=================================// - float flCurrentYaw = view.angles[YAW]; + float flCurrentYaw = viewSetup.angles[YAW]; while ( flCurrentYaw > 180.0f ) flCurrentYaw -= 360.0f; while ( flCurrentYaw < -180.0f ) flCurrentYaw += 360.0f; - //engine->Con_NPrintf( 0, "Blur Pitch: %6.2f Yaw: %6.2f", flCurrentPitch, flCurrentYaw ); - //engine->Con_NPrintf( 1, "Blur FOV: %6.2f Aspect: %6.2f Ortho: %s", view.fov, view.m_flAspectRatio, view.m_bOrtho ? "Yes" : "No" ); + + + /*engine->Con_NPrintf( 0, "Blur Pitch: %6.2f Yaw: %6.2f", flCurrentPitch, flCurrentYaw ); + engine->Con_NPrintf( 1, "Blur FOV: %6.2f Aspect: %6.2f Ortho: %s", view.fov, view.m_flAspectRatio, view.m_bOrtho ? "Yes" : "No" ); + engine->Con_NPrintf( 2, "View Angles: %6.2f %6.2f %6.2f", XYZ(view.angles) );*/ //===========================// // Get current basis vectors // //===========================// matrix3x4_t mCurrentBasisVectors; - AngleMatrix( view.angles, mCurrentBasisVectors ); + AngleMatrix( viewSetup.angles, mCurrentBasisVectors ); + - float vCurrentSideVec[3] = { mCurrentBasisVectors[0][1], mCurrentBasisVectors[1][1], mCurrentBasisVectors[2][1] }; - float vCurrentForwardVec[3] = { mCurrentBasisVectors[0][0], mCurrentBasisVectors[1][0], mCurrentBasisVectors[2][0] }; - //float vCurrentUpVec[3] = { mCurrentBasisVectors[0][2], mCurrentBasisVectors[1][2], mCurrentBasisVectors[2][2] }; + Vector vCurrentSideVec( mCurrentBasisVectors[0][1], mCurrentBasisVectors[1][1], mCurrentBasisVectors[2][1] ); + Vector vCurrentForwardVec( mCurrentBasisVectors[0][0], mCurrentBasisVectors[1][0], mCurrentBasisVectors[2][0] ); + //Vector vCurrentUpVec( mCurrentBasisVectors[0][2], mCurrentBasisVectors[1][2], mCurrentBasisVectors[2][2] ); //======================// // Get current position // //======================// - float vCurrentPosition[3] = { view.origin.x, view.origin.y, view.origin.z }; + Vector vCurrentPosition = viewSetup.origin; //===============================================================// // Evaluate change in position to determine if we need to update // //===============================================================// - float vPositionChange[3] = { 0.0f, 0.0f, 0.0f }; - VectorSubtract( s_vPreviousPositon, vCurrentPosition, vPositionChange ); + Vector vPositionChange( 0.0f, 0.0f, 0.0f ); + VectorSubtract( history.m_vPreviousPositon, vCurrentPosition, vPositionChange ); if ( ( VectorLength( vPositionChange ) > 30.0f ) && ( flTimeElapsed >= 0.5f ) ) { //=======================================================// @@ -2803,7 +3021,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h g_vMotionBlurValues[2] = 0.0f; g_vMotionBlurValues[3] = 0.0f; } - else if ( flTimeElapsed > ( 1.0f / 15.0f ) ) + else if ( ( flTimeElapsed > ( 1.0f / 15.0f ) ) ) { //==========================================// // If slower than 15 fps, don't motion blur // @@ -2813,7 +3031,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h g_vMotionBlurValues[2] = 0.0f; g_vMotionBlurValues[3] = 0.0f; } - else if ( VectorLength( vPositionChange ) > 50.0f ) + else if ( ( VectorLength( vPositionChange ) > 50.0f ) ) { //================================================================================// // We moved a far distance in a frame, use the same motion blur as last frame // @@ -2821,7 +3039,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //================================================================================// //engine->Con_NPrintf( 8, " Position changed %f units @ %.2f time ", VectorLength( vPositionChange ), gpGlobals->realtime ); - s_flNoRotationalMotionBlurUntil = gpGlobals->realtime + 1.0f; // Wait a second until the portal craziness calms down + history.m_flNoRotationalMotionBlurUntil = gpGlobals->realtime + 1.0f; // Wait a second until the portal craziness calms down } else { @@ -2829,8 +3047,8 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Normal update path // //====================// // Compute horizontal and vertical fov - float flHorizontalFov = view.fov; - float flVerticalFov = ( view.m_flAspectRatio <= 0.0f ) ? ( view.fov ) : ( view.fov / view.m_flAspectRatio ); + float flHorizontalFov = viewSetup.fov; + float flVerticalFov = ( viewSetup.m_flAspectRatio <= 0.0f ) ? ( viewSetup.fov ) : ( viewSetup.fov / viewSetup.m_flAspectRatio ); //engine->Con_NPrintf( 2, "Horizontal Fov: %6.2f Vertical Fov: %6.2f", flHorizontalFov, flVerticalFov ); //=====================// @@ -2846,10 +3064,10 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Yaw (Compensate for circle strafe) // //====================================// float flSideDotMotion = DotProduct( vCurrentSideVec, vPositionChange ); - float flYawDiffOriginal = s_flPreviousYaw - flCurrentYaw; - if ( ( ( s_flPreviousYaw - flCurrentYaw > 180.0f ) || ( s_flPreviousYaw - flCurrentYaw < -180.0f ) ) && - ( ( s_flPreviousYaw + flCurrentYaw > -180.0f ) && ( s_flPreviousYaw + flCurrentYaw < 180.0f ) ) ) - flYawDiffOriginal = s_flPreviousYaw + flCurrentYaw; + float flYawDiffOriginal = history.m_flPreviousYaw - flCurrentYaw; + if ( ( ( history.m_flPreviousYaw - flCurrentYaw > 180.0f ) || ( history.m_flPreviousYaw - flCurrentYaw < -180.0f ) ) && + ( ( history.m_flPreviousYaw + flCurrentYaw > -180.0f ) && ( history.m_flPreviousYaw + flCurrentYaw < 180.0f ) ) ) + flYawDiffOriginal = history.m_flPreviousYaw + flCurrentYaw; float flYawDiffAdjusted = flYawDiffOriginal + ( flSideDotMotion / 3.0f ); // Yes, 3.0 is a magic number, sue me @@ -2869,7 +3087,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h // Pitch (Compensate for forward motion) // //=======================================// float flPitchCompensateMask = 1.0f - ( ( 1.0f - fabs( vCurrentForwardVec[2] ) ) * ( 1.0f - fabs( vCurrentForwardVec[2] ) ) ); - float flPitchDiffOriginal = s_flPreviousPitch - flCurrentPitch; + float flPitchDiffOriginal = history.m_flPreviousPitch - flCurrentPitch; float flPitchDiffAdjusted = flPitchDiffOriginal; if ( flCurrentPitch > 0.0f ) @@ -2919,24 +3137,21 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //===============================================================// // Dampen motion blur from 100%-0% as fps drops from 50fps-30fps // //===============================================================// - if ( !IsX360() ) // I'm not doing this on the 360 yet since I can't test it - { - float flSlowFps = 30.0f; - float flFastFps = 50.0f; - float flCurrentFps = ( flTimeElapsed > 0.0f ) ? ( 1.0f / flTimeElapsed ) : 0.0f; - float flDampenFactor = clamp( ( ( flCurrentFps - flSlowFps ) / ( flFastFps - flSlowFps ) ), 0.0f, 1.0f ); + float flSlowFps = 30.0f; + float flFastFps = 50.0f; + float flCurrentFps = ( flTimeElapsed > 0.0f ) ? ( 1.0f / flTimeElapsed ) : 0.0f; + float flDampenFactor = clamp( ( ( flCurrentFps - flSlowFps ) / ( flFastFps - flSlowFps ) ), 0.0f, 1.0f ); - //engine->Con_NPrintf( 4, "gpGlobals->realtime %.2f gpGlobals->curtime %.2f", gpGlobals->realtime, gpGlobals->curtime ); - //engine->Con_NPrintf( 5, "flCurrentFps %.2f", flCurrentFps ); - //engine->Con_NPrintf( 7, "flTimeElapsed %.2f", flTimeElapsed ); + //engine->Con_NPrintf( 4, "gpGlobals->realtime %.2f gpGlobals->curtime %.2f", gpGlobals->realtime, gpGlobals->curtime ); + //engine->Con_NPrintf( 5, "flCurrentFps %.2f", flCurrentFps ); + //engine->Con_NPrintf( 7, "flTimeElapsed %.2f", flTimeElapsed ); - g_vMotionBlurValues[0] *= flDampenFactor; - g_vMotionBlurValues[1] *= flDampenFactor; - g_vMotionBlurValues[2] *= flDampenFactor; - g_vMotionBlurValues[3] *= flDampenFactor; + g_vMotionBlurValues[0] *= flDampenFactor; + g_vMotionBlurValues[1] *= flDampenFactor; + g_vMotionBlurValues[2] *= flDampenFactor; + g_vMotionBlurValues[3] *= flDampenFactor; - //engine->Con_NPrintf( 6, "Dampen: %.2f", flDampenFactor ); - } + //engine->Con_NPrintf( 6, "Dampen: %.2f", flDampenFactor ); //engine->Con_NPrintf( 6, "Final values: { %6.2f%%, %6.2f%%, %6.2f%%, %6.2f%% }", g_vMotionBlurValues[0]*100.0f, g_vMotionBlurValues[1]*100.0f, g_vMotionBlurValues[2]*100.0f, g_vMotionBlurValues[3]*100.0f ); } @@ -2944,7 +3159,7 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h //============================================// // Zero out blur if still in that time window // //============================================// - if ( gpGlobals->realtime < s_flNoRotationalMotionBlurUntil ) + if ( gpGlobals->realtime < history.m_flNoRotationalMotionBlurUntil ) { //engine->Con_NPrintf( 9, " No Rotation @ %f ", gpGlobals->realtime ); @@ -2955,17 +3170,60 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h } else { - s_flNoRotationalMotionBlurUntil = 0.0f; + history.m_flNoRotationalMotionBlurUntil = 0.0f; } //====================================// // Store current frame for next frame // //====================================// - VectorCopy( vCurrentPosition, s_vPreviousPositon ); - s_mPreviousFrameBasisVectors = mCurrentBasisVectors; - s_flPreviousPitch = flCurrentPitch; - s_flPreviousYaw = flCurrentYaw; - s_flLastTimeUpdate = gpGlobals->realtime; + VectorCopy( vCurrentPosition, history.m_vPreviousPositon ); + history.m_mPreviousFrameBasisVectors = mCurrentBasisVectors; + history.m_flPreviousPitch = flCurrentPitch; + history.m_flPreviousYaw = flCurrentYaw; + history.m_flLastTimeUpdate = gpGlobals->realtime; + } + + //engine->Con_NPrintf( 6, "Final values: { %6.2f%%, %6.2f%%, %6.2f%%, %6.2f%% }", g_vMotionBlurValues[0]*100.0f, g_vMotionBlurValues[1]*100.0f, g_vMotionBlurValues[2]*100.0f, g_vMotionBlurValues[3]*100.0f ); + + //==========================================// + // Set global g_vMotionBlurViewportValues[] // + //==========================================// + if ( true ) + { + ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); + float flSrcWidth = ( float )pSrc->GetActualWidth(); + float flSrcHeight = ( float )pSrc->GetActualHeight(); + + // NOTE #1: float4 stored as ( minx, miny, maxy, maxx )...z&w have been swapped to save pixel shader instructions + // NOTE #2: This code should definitely work for 2 players (horizontal or vertical), or 4 players (4 corners), but + // it might have to be modified if we ever want to support other split screen configurations + + int nOffset; // Offset by one pixel to land in the correct half + + // Left + nOffset = ( x > 0 ) ? 1 : 0; + g_vMotionBlurViewportValues[0] = ( float )( x + nOffset ) / ( flSrcWidth - 1 ); + + // Right + nOffset = ( x < ( flSrcWidth - 1 ) ) ? -1 : 0; + g_vMotionBlurViewportValues[3] = ( float )( x + w + nOffset ) / ( flSrcWidth - 1 ); + + // Top + nOffset = ( y > 0 ) ? 1 : 0; // Offset by one pixel to land in the correct half + g_vMotionBlurViewportValues[1] = ( float )( y + nOffset ) / ( flSrcHeight - 1 ); + + // Bottom + nOffset = ( y < ( flSrcHeight - 1 ) ) ? -1 : 0; + g_vMotionBlurViewportValues[2] = ( float )( y + h + nOffset ) / ( flSrcHeight - 1 ); + + // Only allow clamping to happen in the middle of the screen, so nudge the clamp values out if they're on the border of the screen + for ( int i = 0; i < 4; i++ ) + { + if ( g_vMotionBlurViewportValues[i] <= 0.0f ) + g_vMotionBlurViewportValues[i] = -1.0f; + else if ( g_vMotionBlurViewportValues[i] >= 1.0f ) + g_vMotionBlurViewportValues[i] = 2.0f; + } } //=============================================================================================// @@ -2978,13 +3236,10 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); int nSrcWidth = pSrc->GetActualWidth(); int nSrcHeight = pSrc->GetActualHeight(); - int dest_width, dest_height, nDummy; - pRenderContext->GetViewport( nDummy, nDummy, dest_width, dest_height ); + int nViewportWidth, nViewportHeight, nDummy; + pRenderContext->GetViewport( nDummy, nDummy, nViewportWidth, nViewportHeight ); - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_FLOAT ) - { - UpdateScreenEffectTexture( 0, x, y, w, h, true ); // Do we need to check if we already did this? - } + UpdateScreenEffectTexture( 0, x, y, w, h, false ); // Get material pointer IMaterial *pMatMotionBlur = materials->FindMaterial( "dev/motion_blur", TEXTURE_GROUP_OTHER, true ); @@ -2996,14 +3251,200 @@ void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h { pRenderContext->DrawScreenSpaceRectangle( pMatMotionBlur, - 0, 0, dest_width, dest_height, - 0, 0, nSrcWidth-1, nSrcHeight-1, + 0, 0, nViewportWidth, nViewportHeight, + x, y, x + w-1, y + h-1, nSrcWidth, nSrcHeight, GetClientWorldEntity()->GetClientRenderable() ); - - if ( g_bDumpRenderTargets ) - { - DumpTGAofRenderTarget( dest_width, dest_height, "MotionBlur" ); - } } } } + +//===================================================================================================================== +// Depth of field ===================================================================================================== +//===================================================================================================================== +ConVar mat_dof_enabled( "mat_dof_enabled", "1" ); +ConVar mat_dof_override( "mat_dof_override", "0" ); +ConVar mat_dof_near_blur_depth( "mat_dof_near_blur_depth", "20.0" ); +ConVar mat_dof_near_focus_depth( "mat_dof_near_focus_depth", "100.0" ); +ConVar mat_dof_far_focus_depth( "mat_dof_far_focus_depth", "250.0" ); +ConVar mat_dof_far_blur_depth( "mat_dof_far_blur_depth", "1000.0" ); +ConVar mat_dof_near_blur_radius( "mat_dof_near_blur_radius", "0.0" ); +ConVar mat_dof_far_blur_radius( "mat_dof_far_blur_radius", "10.0" ); +ConVar mat_dof_quality( "mat_dof_quality", "3" ); + +static float GetNearBlurDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_near_blur_depth.GetFloat() : g_flDOFNearBlurDepth; +} + +static float GetNearFocusDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_near_focus_depth.GetFloat() : g_flDOFNearFocusDepth; +} + +static float GetFarFocusDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_far_focus_depth.GetFloat() : g_flDOFFarFocusDepth; +} + +static float GetFarBlurDepth() +{ + return mat_dof_override.GetBool() ? mat_dof_far_blur_depth.GetFloat() : g_flDOFFarBlurDepth; +} + +static float GetNearBlurRadius() +{ + return mat_dof_override.GetBool() ? mat_dof_near_blur_radius.GetFloat() : g_flDOFNearBlurRadius; +} + +static float GetFarBlurRadius() +{ + return mat_dof_override.GetBool() ? mat_dof_far_blur_radius.GetFloat() : g_flDOFFarBlurRadius; +} + +bool IsDepthOfFieldEnabled() +{ + const CViewSetup *pViewSetup = view->GetViewSetup(); + if ( !pViewSetup ) + return false; + + if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 92 ) + return false; + + if ( !mat_dof_enabled.GetBool() ) + return false; + + if ( mat_dof_override.GetBool() == true ) + { + return mat_dof_enabled.GetBool(); + } + else + { + return g_bDOFEnabled; + } +} + +static inline bool SetMaterialVarFloat( IMaterial* pMat, const char* pVarName, float flValue ) +{ + Assert( pMat != NULL ); + Assert( pVarName != NULL ); + if ( pMat == NULL || pVarName == NULL ) + { + return false; + } + + bool bFound = false; + IMaterialVar* pVar = pMat->FindVar( pVarName, &bFound ); + if ( bFound ) + { + pVar->SetFloatValue( flValue ); + } + + return bFound; +} + +static inline bool SetMaterialVarInt( IMaterial* pMat, const char* pVarName, int nValue ) +{ + Assert( pMat != NULL ); + Assert( pVarName != NULL ); + if ( pMat == NULL || pVarName == NULL ) + { + return false; + } + + bool bFound = false; + IMaterialVar* pVar = pMat->FindVar( pVarName, &bFound ); + if ( bFound ) + { + pVar->SetIntValue( nValue ); + } + + return bFound; +} + +void DoDepthOfField( const CViewSetup &viewSetup ) +{ + if ( !IsDepthOfFieldEnabled() ) + { + return; + } + + // Copy from backbuffer to _rt_FullFrameFB + UpdateScreenEffectTexture( 0, viewSetup.x, viewSetup.y, viewSetup.width, viewSetup.height, false ); // Do we need to check if we already did this? + + CMatRenderContextPtr pRenderContext( materials ); + + ITexture *pSrc = materials->FindTexture( "_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET ); + int nSrcWidth = pSrc->GetActualWidth(); + int nSrcHeight = pSrc->GetActualHeight(); + + int nViewportWidth = 0; + int nViewportHeight = 0; + int nDummy = 0; + pRenderContext->GetViewport( nDummy, nDummy, nViewportWidth, nViewportHeight ); + + if ( mat_dof_quality.GetInt() < 2 ) + { + ///////////////////////////////////// + // Downsample backbuffer to 1/4 size + ///////////////////////////////////// + + // Update downsampled framebuffer. TODO: Don't do this again for the bloom if we already did it here... + pRenderContext->PushRenderTargetAndViewport(); + ITexture *dest_rt0 = materials->FindTexture( "_rt_SmallFB0", TEXTURE_GROUP_RENDER_TARGET ); + + // *Everything* in here relies on the small RTs being exactly 1/4 the full FB res + Assert( dest_rt0->GetActualWidth() == pSrc->GetActualWidth() / 4 ); + Assert( dest_rt0->GetActualHeight() == pSrc->GetActualHeight() / 4 ); + + // Downsample fb to rt0 + DownsampleFBQuarterSize( pRenderContext, nSrcWidth, nSrcHeight, dest_rt0, true ); + + ////////////////////////////////////// + // Additional blur using 3x3 gaussian + ////////////////////////////////////// + + IMaterial *pMat = materials->FindMaterial( "dev/blurgaussian_3x3", TEXTURE_GROUP_OTHER, true ); + + if ( pMat == NULL ) + return; + + SetMaterialVarFloat( pMat, "$c0_x", 0.5f / (float)dest_rt0->GetActualWidth() ); + SetMaterialVarFloat( pMat, "$c0_y", 0.5f / (float)dest_rt0->GetActualHeight() ); + SetMaterialVarFloat( pMat, "$c1_x", -0.5f / (float)dest_rt0->GetActualWidth() ); + SetMaterialVarFloat( pMat, "$c1_y", 0.5f / (float)dest_rt0->GetActualHeight() ); + + ITexture *dest_rt1 = materials->FindTexture( "_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET ); + SetRenderTargetAndViewPort( dest_rt1 ); + + pRenderContext->DrawScreenSpaceRectangle( + pMat, 0, 0, nSrcWidth/4, nSrcHeight/4, + 0, 0, dest_rt0->GetActualWidth()-1, dest_rt0->GetActualHeight()-1, + dest_rt0->GetActualWidth(), dest_rt0->GetActualHeight() ); + + pRenderContext->PopRenderTargetAndViewport(); + } + + // Render depth-of-field quad + IMaterial *pMatDOF = materials->FindMaterial( "dev/depth_of_field", TEXTURE_GROUP_OTHER, true ); + + if ( pMatDOF == NULL ) + return; + + SetMaterialVarFloat( pMatDOF, "$nearPlane", viewSetup.zNear ); + SetMaterialVarFloat( pMatDOF, "$farPlane", viewSetup.zFar ); + + // pull from convars/globals + SetMaterialVarFloat( pMatDOF, "$nearBlurDepth", GetNearBlurDepth() ); + SetMaterialVarFloat( pMatDOF, "$nearFocusDepth", GetNearFocusDepth() ); + SetMaterialVarFloat( pMatDOF, "$farFocusDepth", GetFarFocusDepth() ); + SetMaterialVarFloat( pMatDOF, "$farBlurDepth", GetFarBlurDepth() ); + SetMaterialVarFloat( pMatDOF, "$nearBlurRadius", GetNearBlurRadius() ); + SetMaterialVarFloat( pMatDOF, "$farBlurRadius", GetFarBlurRadius() ); + SetMaterialVarInt( pMatDOF, "$quality", mat_dof_quality.GetInt() ); + + pRenderContext->DrawScreenSpaceRectangle( + pMatDOF, + 0, 0, nViewportWidth, nViewportHeight, + 0, 0, nSrcWidth-1, nSrcHeight-1, + nSrcWidth, nSrcHeight, GetClientWorldEntity()->GetClientRenderable() ); +} diff --git a/game/client/viewpostprocess.h b/game/client/viewpostprocess.h index eb2ad9cc..f40a6937 100644 --- a/game/client/viewpostprocess.h +++ b/game/client/viewpostprocess.h @@ -11,8 +11,20 @@ #pragma once #endif +struct PostProcessParameters_t; + void DoEnginePostProcessing( int x, int y, int w, int h, bool bFlashlightIsOn, bool bPostVGui = false ); -void DoImageSpaceMotionBlur( const CViewSetup &view, int x, int y, int w, int h ); +void DoImageSpaceMotionBlur( const CViewSetup &viewSetup ); void DumpTGAofRenderTarget( const int width, const int height, const char *pFilename ); +void SetRenderTargetAndViewPort( ITexture *rt ); + +bool IsDepthOfFieldEnabled(); +void DoDepthOfField( const CViewSetup &view ); + +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters ); +void SetPostProcessParams( const PostProcessParameters_t* pPostProcessParameters, bool override ); + +void SetViewFadeParams( byte r, byte g, byte b, byte a, bool bModulate ); + #endif // VIEWPOSTPROCESS_H diff --git a/game/client/viewrender.cpp b/game/client/viewrender.cpp index a2626f71..6bcff8da 100644 --- a/game/client/viewrender.cpp +++ b/game/client/viewrender.cpp @@ -74,15 +74,14 @@ #include "c_point_camera.h" #endif // USE_MONITORS +#ifdef MAPBASE +#include "mapbase/c_func_fake_worldportal.h" +#include "colorcorrectionmgr.h" +#endif + // Projective textures #include "C_Env_Projected_Texture.h" -#include "IDeferredExt.h" -#include "c_env_global_light.h" -#include "c_deferred_common.h" -#include "c_light_manager.h" -#include "callqueue.h" - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -125,6 +124,10 @@ static ConVar r_drawtranslucentrenderables( "r_drawtranslucentrenderables", "1", static ConVar r_drawopaquerenderables( "r_drawopaquerenderables", "1", FCVAR_CHEAT ); static ConVar r_threaded_renderables( "r_threaded_renderables", "0" ); +#ifdef MAPBASE +static ConVar r_skybox_use_complex_views( "r_skybox_use_complex_views", "0", FCVAR_CHEAT, "Enable complex views in skyboxes, like reflective glass" ); +#endif + // FIXME: This is not static because we needed to turn it off for TF2 playtests ConVar r_DrawDetailProps( "r_DrawDetailProps", "1", FCVAR_NONE, "0=Off, 1=Normal, 2=Wireframe" ); @@ -170,10 +173,6 @@ static ConVar r_screenfademaxsize( "r_screenfademaxsize", "0" ); static ConVar cl_drawmonitors( "cl_drawmonitors", "1" ); static ConVar r_eyewaterepsilon( "r_eyewaterepsilon", "10.0f", FCVAR_CHEAT ); -static ConVar r_csm_angle("r_csm_angle", "0"); - -ConVar r_volumetrics("r_volumetrics", "1"); - #ifdef TF_CLIENT_DLL static ConVar pyro_dof( "pyro_dof", "1", FCVAR_ARCHIVE ); #endif @@ -182,6 +181,10 @@ extern ConVar cl_leveloverview; extern ConVar localplayer_visionflags; +#ifdef MAPBASE +static ConVar r_nearz_skybox( "r_nearz_skybox", "2.0", FCVAR_CHEAT ); +#endif + //----------------------------------------------------------------------------- // Globals //----------------------------------------------------------------------------- @@ -194,7 +197,6 @@ IntroData_t *g_pIntroData = NULL; static bool g_bRenderingView = false; // For debugging... static int g_CurrentViewID = VIEW_NONE; bool g_bRenderingScreenshot = false; -static bool s_bDrawViewmodelShadow = false; #define FREEZECAM_SNAPSHOT_FADE_SPEED 340 @@ -412,43 +414,6 @@ class CSkyboxView : public CRendering3dView sky3dparams_t *m_pSky3dParams; }; -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -class CDepthView : public CRendering3dView -{ - DECLARE_CLASS(CDepthView, CRendering3dView); -public: - CDepthView(CViewRender* pMainView) : - CRendering3dView(pMainView) - { - } - - bool Setup(const CViewSetup& view, ITexture* pDepthTexture = NULL, ITexture* pRenderTarget = NULL); - void Draw(); - -protected: - ITexture* m_pColorTexture; - ITexture* m_pDepthTexture; - void DrawInternal(view_id_t iSkyBoxViewID); -}; -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -class CVolumetricsView : public CRendering3dView -{ - DECLARE_CLASS(CVolumetricsView, CRendering3dView); -public: - CVolumetricsView(CViewRender* pMainView) : - CRendering3dView(pMainView) - { - } - - bool Setup(const CViewSetup& view, ITexture* pDepthTexture = NULL, ITexture* pRenderTarget = NULL); - void Draw(); - -protected: - void DrawInternal(view_id_t iSkyBoxViewID); -}; - //----------------------------------------------------------------------------- // 3d skybox view when drawing portals //----------------------------------------------------------------------------- @@ -474,24 +439,6 @@ class CPortalSkyboxView : public CSkyboxView }; #endif -//----------------------------------------------------------------------------- -// Cascaded Shadow map depth texture -//----------------------------------------------------------------------------- -class CCSMDepthView : public CRendering3dView -{ - DECLARE_CLASS(CCSMDepthView, CRendering3dView); -public: - CCSMDepthView(CViewRender* pMainView, int &cascade) : CRendering3dView(pMainView), nCascade(cascade) {} - - void Setup(const CViewSetup& shadowViewIn, ITexture* pRenderTarget, ITexture* pDepthTexture); - void Draw(); - -private: - ITexture* m_pRenderTarget; - ITexture* m_pDepthTexture; - - int nCascade; -}; //----------------------------------------------------------------------------- // Shadow depth texture @@ -546,6 +493,11 @@ class CBaseWorldView : public CRendering3dView void SSAO_DepthPass(); void DrawDepthOfField(); + +#ifdef MAPBASE + virtual ITexture *GetRefractionTexture() { return GetWaterRefractionTexture(); } + virtual ITexture *GetReflectionTexture() { return GetWaterReflectionTexture(); } +#endif }; @@ -732,6 +684,11 @@ class CReflectiveGlassView : public CSimpleWorldView void Draw(); cplane_t m_ReflectionPlane; + +#ifdef MAPBASE + ITexture *GetReflectionTexture() { return m_pRenderTarget; } + ITexture *m_pRenderTarget; +#endif }; class CRefractiveGlassView : public CSimpleWorldView @@ -749,6 +706,11 @@ class CRefractiveGlassView : public CSimpleWorldView void Draw(); cplane_t m_ReflectionPlane; + +#ifdef MAPBASE + ITexture *GetRefractionTexture() { return m_pRenderTarget; } + ITexture *m_pRenderTarget; +#endif }; @@ -858,6 +820,8 @@ CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffects ) CLIENTEFFECT_MATERIAL( "dev/copyfullframefb_vanilla" ) CLIENTEFFECT_MATERIAL( "dev/copyfullframefb" ) CLIENTEFFECT_MATERIAL( "dev/engine_post" ) + CLIENTEFFECT_MATERIAL( "dev/depth_of_field" ) + CLIENTEFFECT_MATERIAL( "dev/blurgaussian_3x3" ) CLIENTEFFECT_MATERIAL( "dev/motion_blur" ) CLIENTEFFECT_MATERIAL( "dev/upscale" ) @@ -877,37 +841,37 @@ CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 ) //----------------------------------------------------------------------------- const Vector &CurrentViewOrigin() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_vecCurrentRenderOrigin; } const QAngle &CurrentViewAngles() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_vecCurrentRenderAngles; } const Vector &CurrentViewForward() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_vecCurrentVForward; } const Vector &CurrentViewRight() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_vecCurrentVRight; } const Vector &CurrentViewUp() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_vecCurrentVUp; } const VMatrix &CurrentWorldToViewMatrix() { -// Assert( s_bCanAccessCurrentView ); + Assert( s_bCanAccessCurrentView ); return g_matCurrentCamInverse; } @@ -1129,11 +1093,8 @@ void CViewRender::DrawViewModels( const CViewSetup &view, bool drawViewmodel ) pRTDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Depth ); } - if (!s_bDrawViewmodelShadow) - { - render->Push3DView(viewModelSetup, 0, pRTColor, GetFrustum(), pRTDepth); - PushGBufferRT(); - } + render->Push3DView( viewModelSetup, 0, pRTColor, GetFrustum(), pRTDepth ); + #ifdef PORTAL //the depth range hack doesn't work well enough for the portal mod (and messing with the depth hack values makes some models draw incorrectly) //step up to a full depth clear if we're extremely close to a portal (in a portal environment) extern bool LocalPlayerIsCloseToPortal( void ); //defined in C_Portal_Player.cpp, abstracting to a single bool function to remove explicit dependence on c_portal_player.h/cpp, you can define the function as a "return true" in other build configurations at the cost of some perf @@ -1141,7 +1102,7 @@ void CViewRender::DrawViewModels( const CViewSetup &view, bool drawViewmodel ) if( !bUseDepthHack ) pRenderContext->ClearBuffers( false, true, false ); #else - const bool bUseDepthHack = /*true*/ !s_bDrawViewmodelShadow; + const bool bUseDepthHack = true; #endif // FIXME: Add code to read the current depth range @@ -1191,112 +1152,21 @@ void CViewRender::DrawViewModels( const CViewSetup &view, bool drawViewmodel ) UpdateRefractIfNeededByList( translucentViewModelList ); } - DrawRenderablesInList( opaqueViewModelList, (s_bDrawViewmodelShadow ? STUDIO_SHADOWDEPTHTEXTURE : 0)); - DrawRenderablesInList( translucentViewModelList, STUDIO_TRANSPARENCY | (s_bDrawViewmodelShadow ? STUDIO_SHADOWDEPTHTEXTURE : 0)); + DrawRenderablesInList( opaqueViewModelList ); + DrawRenderablesInList( translucentViewModelList, STUDIO_TRANSPARENCY ); } // Reset the depth range to the original values if( bUseDepthHack ) pRenderContext->DepthRange( depthmin, depthmax ); - if(!s_bDrawViewmodelShadow) - render->PopView( GetFrustum() ); + render->PopView( GetFrustum() ); // Restore the matrices pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PopMatrix(); } -void CViewRender::DrawSky(const CViewSetup& view) -{ - float flRadius = 32.0f; - int nTheta = 8; - int nPhi = 8; - - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->OverrideDepthEnable(true, false); - - int nTriangles = 2 * nTheta * (nPhi - 1); // Two extra degenerate triangles per row (except the last one) - int nIndices = 2 * (nTheta + 1) * (nPhi - 1); - - pRenderContext->Bind(m_SkydomeMaterial); - - CMeshBuilder meshBuilder; - IMesh* pMesh = pRenderContext->GetDynamicMesh(); - - meshBuilder.Begin(pMesh, MATERIAL_TRIANGLE_STRIP, nTriangles, nIndices); - - // - // Build the index buffer. - // - int i, j; - for (i = 0; i < nPhi; ++i) - { - for (j = 0; j < nTheta; ++j) - { - float u = j / (float)(nTheta - 1); - float v = i / (float)(nPhi - 1); - float theta = 2.0f * M_PI * u; - float phi = M_PI * v; - - Vector vecPos; - vecPos.x = flRadius * sin(phi) * cos(theta); - vecPos.y = flRadius * sin(phi) * sin(theta); - vecPos.z = flRadius * cos(phi); - - Vector vecNormal = vecPos; - VectorNormalize(vecNormal); - - meshBuilder.Position3f(vecPos.x, vecPos.y, vecPos.z); - meshBuilder.AdvanceVertex(); - } - } - - // - // Emit the triangle strips. - // - int idx = 0; - for (i = nPhi - 2; i >= 0; --i) - { - for (j = nTheta - 1; j >= 0; --j) - { - idx = nTheta * i + j; - - meshBuilder.Index(idx + nTheta); - meshBuilder.AdvanceIndex(); - - meshBuilder.Index(idx); - meshBuilder.AdvanceIndex(); - } - - // - // Emit a degenerate triangle to skip to the next row without - // a connecting triangle. - // - if (i < nPhi - 2) - { - meshBuilder.Index(idx); - meshBuilder.AdvanceIndex(); - - meshBuilder.Index(idx + nTheta + 1); - meshBuilder.AdvanceIndex(); - } - } - - pRenderContext->MatrixMode(MATERIAL_MODEL); - pRenderContext->PushMatrix(); - pRenderContext->LoadIdentity(); - pRenderContext->Translate(view.origin.x, view.origin.y, view.origin.z); - - meshBuilder.End(); - pMesh->Draw(); - - pRenderContext->MatrixMode(MATERIAL_MODEL); - pRenderContext->PopMatrix(); - - pRenderContext->OverrideDepthEnable(false, true); -} - //----------------------------------------------------------------------------- // Purpose: @@ -1345,6 +1215,73 @@ IMaterial *CViewRender::GetScreenOverlayMaterial( ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets the screen space effect material (can't be done during rendering) +//----------------------------------------------------------------------------- +void CViewRender::SetIndexedScreenOverlayMaterial( int i, IMaterial *pMaterial ) +{ + if (i < 0 || i >= MAX_SCREEN_OVERLAYS) + return; + + m_IndexedScreenOverlayMaterials[i].Init( pMaterial ); + + if (pMaterial == NULL) + { + // Check if we should set to false + int i; + for (i = 0; i < MAX_SCREEN_OVERLAYS; i++) + { + if (m_IndexedScreenOverlayMaterials[i] != NULL) + break; + } + + if (i == MAX_SCREEN_OVERLAYS) + m_bUsingIndexedScreenOverlays = false; + } + else + { + m_bUsingIndexedScreenOverlays = true; + } +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +IMaterial *CViewRender::GetIndexedScreenOverlayMaterial( int i ) +{ + if (i < 0 || i >= MAX_SCREEN_OVERLAYS) + return NULL; + + return m_IndexedScreenOverlayMaterials[i]; +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CViewRender::ResetIndexedScreenOverlays() +{ + for (int i = 0; i < MAX_SCREEN_OVERLAYS; i++) + { + m_IndexedScreenOverlayMaterials[i].Init( NULL ); + } + + m_bUsingIndexedScreenOverlays = false; +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +int CViewRender::GetMaxIndexedScreenOverlays( ) const +{ + return MAX_SCREEN_OVERLAYS; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Performs screen space effects, if any //----------------------------------------------------------------------------- @@ -1381,6 +1318,44 @@ void CViewRender::PerformScreenOverlay( int x, int y, int w, int h ) render->ViewDrawFade( color, m_ScreenOverlayMaterial ); } } + +#ifdef MAPBASE + if (m_bUsingIndexedScreenOverlays) + { + for (int i = 0; i < MAX_SCREEN_OVERLAYS; i++) + { + if (!m_IndexedScreenOverlayMaterials[i]) + continue; + + tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); + + if ( m_IndexedScreenOverlayMaterials[i]->NeedsFullFrameBufferTexture() ) + { + // FIXME: check with multi/sub-rect renders. Should this be 0,0,w,h instead? + DrawScreenEffectMaterial( m_IndexedScreenOverlayMaterials[i], x, y, w, h ); + } + else if ( m_IndexedScreenOverlayMaterials[i]->NeedsPowerOfTwoFrameBufferTexture() ) + { + // First copy the FB off to the offscreen texture + UpdateRefractTexture( x, y, w, h, true ); + + // Now draw the entire screen using the material... + CMatRenderContextPtr pRenderContext( materials ); + ITexture *pTexture = GetPowerOfTwoFrameBufferTexture( ); + int sw = pTexture->GetActualWidth(); + int sh = pTexture->GetActualHeight(); + // Note - don't offset by x,y - already done by the viewport. + pRenderContext->DrawScreenSpaceRectangle( m_IndexedScreenOverlayMaterials[i], 0, 0, w, h, + 0, 0, sw-1, sh-1, sw, sh ); + } + else + { + byte color[4] = { 255, 255, 255, 255 }; + render->ViewDrawFade( color, m_IndexedScreenOverlayMaterials[i] ); + } + } + } +#endif } void CViewRender::DrawUnderwaterOverlay( void ) @@ -1468,181 +1443,6 @@ bool CViewRender::UpdateShadowDepthTexture( ITexture *pRenderTarget, ITexture *p return true; } -static ConVar r_csm_size("r_csm_size", "64"); -static ConVar r_csm_bias("r_csm_bias", "0.0002"); -static ConVar r_csm_slopescalebias("r_csm_slopescale_depthbias", "3"); -static ConVar r_csm_performance("r_csm_performance", "0"); -void CViewRender::UpdateLighting(const CViewSetup& view) -{ - QAngle angCascadedAngles; - Vector vecLight, vecAmbient; - g_pCSMLight->GetShadowMappingConstants(angCascadedAngles, vecLight, vecAmbient); - - - if (r_csm_angle.GetBool()) - { - int iParsed[3]; - UTIL_StringToIntArray(iParsed, 3, r_csm_angle.GetString()); - angCascadedAngles.Init(iParsed[0], iParsed[1], iParsed[2]); - } - CMatRenderContextPtr pRenderContext(materials); - - Vector vecFwd, vecRight, vecUp; - AngleVectors(angCascadedAngles, &vecFwd, &vecRight, &vecUp); - - - Vector vecMainViewFwd; - AngleVectors(view.angles, &vecMainViewFwd); - - Vector vecCascadeOrigin(view.origin); - vecCascadeOrigin -= vecFwd * 4096.0f; - - float flOrthoSize = 2048.0f; - - struct ShadowConfig_t - { - float flOrthoSize; - float flForwardOffset; - float flViewDepthBiasHack; - } shadowConfigs[] = { - { r_csm_size.GetFloat(), 0.0f, 0.0f }, - { r_csm_size.GetFloat() * 4, 256.0f, 0.0f }, - { r_csm_size.GetFloat() * 8, 512.0f, 0.0f }, - { r_csm_size.GetFloat() * 32, 1024.0f, 0.0f } - }; - - static VMatrix s_CSMSwapMatrix[4]; - static int s_iCSMSwapIndex = 0; - - static CTextureReference s_CascadedShadowDepthTexture; - static CTextureReference s_CascadedShadowColorTexture; - if (!s_CascadedShadowDepthTexture.IsValid()) - { - s_CascadedShadowDepthTexture.Init(materials->FindTexture("_rt_CascadedShadowDepth", TEXTURE_GROUP_OTHER)); - } - - if (!s_CascadedShadowColorTexture.IsValid()) - { - s_CascadedShadowColorTexture.Init(materials->FindTexture("_rt_CascadedShadowColor", TEXTURE_GROUP_OTHER)); - } - - CViewSetup cascadedShadowView; - cascadedShadowView.angles = angCascadedAngles; - cascadedShadowView.m_bOrtho = true; - - cascadedShadowView.width = s_CascadedShadowDepthTexture->GetMappingWidth() / 4; - cascadedShadowView.height = s_CascadedShadowDepthTexture->GetMappingHeight(); - - for (int i = 0; i < (s_bDrawViewmodelShadow ? 1 : 4); i++) - { - const ShadowConfig_t& shadowConfig = shadowConfigs[i]; - - cascadedShadowView.m_OrthoTop = -shadowConfig.flOrthoSize; - cascadedShadowView.m_OrthoRight = shadowConfig.flOrthoSize; - cascadedShadowView.m_OrthoBottom = shadowConfig.flOrthoSize; - cascadedShadowView.m_OrthoLeft = -shadowConfig.flOrthoSize; - - cascadedShadowView.x = i * (cascadedShadowView.width); - cascadedShadowView.y = 0; - - cascadedShadowView.m_flAspectRatio = 1.0f; - cascadedShadowView.m_bDoBloomAndToneMapping = false; - cascadedShadowView.zFar = cascadedShadowView.zFarViewmodel = s_bDrawViewmodelShadow ? 4128.0f : 6144.0f; - cascadedShadowView.zNear = cascadedShadowView.zNearViewmodel = 128.0f; - cascadedShadowView.fov = cascadedShadowView.fovViewmodel = 90.0f; - - Vector vecOrigin = vecCascadeOrigin + vecMainViewFwd * 0.0f; - const float flViewFrustumWidthScale = flOrthoSize * 2.0f / cascadedShadowView.width; - const float flViewFrustumHeightScale = flOrthoSize * 2.0f / cascadedShadowView.height; - const float flFractionX = fmod(DotProduct(vecOrigin, vecRight), flViewFrustumWidthScale); - const float flFractionY = fmod(DotProduct(vecOrigin, vecUp), flViewFrustumHeightScale); - vecOrigin -= flFractionX * vecRight; - vecOrigin -= flFractionY * vecUp; - - cascadedShadowView.origin = vecOrigin; - - if (i == 0) - { - VMatrix worldToView, viewToProjection, worldToProjection, worldToTexture; - render->GetMatricesForView(cascadedShadowView, &worldToView, &viewToProjection, &worldToProjection, &worldToTexture); - VMatrix tmp; - MatrixBuildScale(tmp, 0.5f, -0.5f, 1.0f); - tmp[0][3] = 0.5f; - tmp[1][3] = 0.5f; - - VMatrix& currentSwapMatrix = s_CSMSwapMatrix[s_iCSMSwapIndex]; - MatrixMultiply(tmp, worldToProjection, currentSwapMatrix); - - pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0, (int)¤tSwapMatrix); - } - - if ((r_csm_performance.GetInt() == 1 && (i == 0 || i == 1)) || - (r_csm_performance.GetInt() >= 2 && (i == 0 || i == 1 || i == 2)) ) - { - continue; - } - - ITexture* pDepthTexture = s_CascadedShadowDepthTexture; - pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE, int(pDepthTexture)); - - - pRenderContext->SetShadowDepthBiasFactors(r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat()); - cascadedShadowView.origin -= vecFwd * -shadowConfig.flViewDepthBiasHack; - CRefPtr pShadowDepthView = new CCSMDepthView(this, i); - pShadowDepthView->Setup(cascadedShadowView, s_CascadedShadowColorTexture, s_CascadedShadowDepthTexture); - AddViewToScene(pShadowDepthView); - } - - s_iCSMSwapIndex = (s_iCSMSwapIndex + 1) % 4; - - lightData_Global_t lightDataState; - lightDataState.vecLight = vecFwd; - lightDataState.light = vecLight.Base(); - lightDataState.ambient = vecAmbient.Base(); - lightDataState.sizes = Vector4D( - shadowConfigs[0].flOrthoSize, - shadowConfigs[1].flOrthoSize / shadowConfigs[0].flOrthoSize, - shadowConfigs[2].flOrthoSize / shadowConfigs[0].flOrthoSize, - shadowConfigs[3].flOrthoSize / shadowConfigs[0].flOrthoSize); - QUEUE_FIRE(CommitLightData_Global, lightDataState); -} - - -void CViewRender::ProcessGlobals(const CViewSetup& view) -{ - VMatrix matPerspective, matView, matViewInv, matProjInv; - - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->GetMatrix(MATERIAL_VIEW, &matView); - pRenderContext->GetMatrix(MATERIAL_PROJECTION, &matPerspective); - - MatrixInverseGeneral(matView, matViewInv); - MatrixInverseGeneral(matPerspective, matProjInv); - - Vector vFwd; - AngleVectors(view.angles, &vFwd); - QUEUE_FIRE(CommitCommonData, view.origin, vFwd, view.zNear, view.zFar, - (g_pCSMLight != 0) ? g_pCSMLight->CurrentTime() : 0.0f, // HACKHACK: csmlight probably shouldnt store current time of the whole map - matView, matPerspective, matViewInv, matProjInv); - - GetLightingManager()->SetRenderConstants(matPerspective, view); -} - -void CViewRender::PushGBufferRT(bool firstPush) -{ - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->SetRenderTargetEx(1, m_NormalBuffer); - pRenderContext->SetRenderTargetEx(2, m_MRAOBuffer); - pRenderContext->SetRenderTargetEx(3, m_AlbedoBuffer); - - if (firstPush) - { - pRenderContext->ClearColor4ub(0, 0, 0, 255); - pRenderContext->ClearBuffers(true, true); - } - pRenderContext.SafeRelease(); -} - //----------------------------------------------------------------------------- // Purpose: Renders world and all entities, etc. //----------------------------------------------------------------------------- @@ -1656,6 +1456,17 @@ void CViewRender::ViewDrawScene( bool bDrew3dSkybox, SkyboxVisibility_t nSkyboxV // (e.g. once for a monitor scene and once for the main scene) g_viewscene_refractUpdateFrame = gpGlobals->framecount - 1; + g_pClientShadowMgr->PreRender(); + + // Shadowed flashlights supported on ps_2_b and up... + if ( r_flashlightdepthtexture.GetBool() && (viewID == VIEW_MAIN) ) + { + g_pClientShadowMgr->ComputeShadowDepthTextures( view ); +#ifdef ASW_PROJECTED_TEXTURES + CMatRenderContextPtr pRenderContext( materials ); +#endif + } + m_BaseDrawFlags = baseDrawFlags; SetupCurrentView( view.origin, view.angles, viewID ); @@ -1762,8 +1573,8 @@ static void GetFogColorTransition( fogparams_t *pFogParams, float *pColorPrimary { float flPercent = 1.0f - (( pFogParams->lerptime - gpGlobals->curtime ) / pFogParams->duration ); - float flPrimaryColorLerp[3] = { (float)pFogParams->colorPrimaryLerpTo.GetR(), (float)pFogParams->colorPrimaryLerpTo.GetG(), (float)pFogParams->colorPrimaryLerpTo.GetB() }; - float flSecondaryColorLerp[3] = { (float)pFogParams->colorSecondaryLerpTo.GetR(), (float)pFogParams->colorSecondaryLerpTo.GetG(), (float)pFogParams->colorSecondaryLerpTo.GetB() }; + float flPrimaryColorLerp[3] = { pFogParams->colorPrimaryLerpTo.GetR(), pFogParams->colorPrimaryLerpTo.GetG(), pFogParams->colorPrimaryLerpTo.GetB() }; + float flSecondaryColorLerp[3] = { pFogParams->colorSecondaryLerpTo.GetR(), pFogParams->colorSecondaryLerpTo.GetG(), pFogParams->colorSecondaryLerpTo.GetB() }; CheckAndTransitionColor( flPercent, pColorPrimary, flPrimaryColorLerp ); CheckAndTransitionColor( flPercent, pColorSecondary, flSecondaryColorLerp ); @@ -1786,8 +1597,8 @@ static void GetFogColor( fogparams_t *pFogParams, float *pColor ) } else { - float flPrimaryColor[3] = { (float)pFogParams->colorPrimary.GetR(), (float)pFogParams->colorPrimary.GetG(), (float)pFogParams->colorPrimary.GetB() }; - float flSecondaryColor[3] = { (float)pFogParams->colorSecondary.GetR(), (float)pFogParams->colorSecondary.GetG(), (float)pFogParams->colorSecondary.GetB() }; + float flPrimaryColor[3] = { pFogParams->colorPrimary.GetR(), pFogParams->colorPrimary.GetG(), pFogParams->colorPrimary.GetB() }; + float flSecondaryColor[3] = { pFogParams->colorSecondary.GetR(), pFogParams->colorSecondary.GetG(), pFogParams->colorSecondary.GetB() }; GetFogColorTransition( pFogParams, flPrimaryColor, flSecondaryColor ); @@ -2149,8 +1960,24 @@ void CViewRender::SetupMain3DView( const CViewSetup &view, int &nClearFlags ) nClearFlags |= nDepthStencilFlags; // Add them back in if we're clearing color } - render->Push3DView(view, nClearFlags, GetFullFrameHDRTexture(), GetFrustum()); - PushGBufferRT(true); + // If we are using HDR, we render to the HDR full frame buffer texture + // instead of whatever was previously the render target + if( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT ) + { + render->Push3DView( view, nClearFlags, GetFullFrameFrameBufferTexture( 0 ), GetFrustum() ); + } + else + { + ITexture *pRTColor = NULL; + ITexture *pRTDepth = NULL; + if( view.m_eStereoEye != STEREO_EYE_MONO ) + { + pRTColor = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Color ); + pRTDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Depth ); + } + + render->Push3DView( view, nClearFlags, pRTColor, GetFrustum(), pRTDepth ); + } // If we didn't clear the depth here, we'll need to clear it later nClearFlags ^= nDepthStencilFlags; // Toggle these bits @@ -2273,6 +2100,26 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT { CViewSetup viewMiddle = GetView( STEREO_EYE_MONO ); DrawMonitors( viewMiddle ); + +#ifdef MAPBASE + // Any fake world portals? + Frustum_t frustum; + GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); + + Vector vecAbsPlaneNormal; + float flLocalPlaneDist; + C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, vecAbsPlaneNormal, flLocalPlaneDist, frustum ); + while ( pPortalEnt != NULL ) + { + ITexture *pCameraTarget = pPortalEnt->RenderTarget(); + int width = pCameraTarget->GetActualWidth(); + int height = pCameraTarget->GetActualHeight(); + + DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, vecAbsPlaneNormal, flLocalPlaneDist ); + + pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, vecAbsPlaneNormal, flLocalPlaneDist, frustum ); + } +#endif } #endif @@ -2280,40 +2127,30 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT // Must be first render->SceneBegin(); - - { - pRenderContext.GetFrom(materials); - pRenderContext->TurnOnToneMapping(); - pRenderContext->SetToneMappingScaleLinear(Vector(1, 1, 1)); - pRenderContext.SafeRelease(); - } - - g_pClientShadowMgr->PreRender(); - - // Shadowed flashlights supported on ps_2_b and up... - if (r_flashlightdepthtexture.GetBool()) - { - g_pClientShadowMgr->ComputeShadowDepthTextures(view); - } - if (g_pCSMLight && g_pCSMLight->IsCascadedShadowMappingEnabled()) - { - UpdateLighting(view); - } - else - { - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE, 0); - pRenderContext.SafeRelease(); // don't want to hold for long periods in case in a locking active share thread mode - } +#ifdef MAPBASE // From Alien Swarm SDK + g_pColorCorrectionMgr->UpdateColorCorrection(); +#endif - bool bDrew3dSkybox = false; - SkyboxVisibility_t nSkyboxVisible = SKYBOX_NOT_VISIBLE; + pRenderContext.GetFrom( materials ); + pRenderContext->TurnOnToneMapping(); + pRenderContext.SafeRelease(); // clear happens here probably SetupMain3DView( view, nClearFlags ); + + bool bDrew3dSkybox = false; + SkyboxVisibility_t nSkyboxVisible = SKYBOX_NOT_VISIBLE; - ProcessGlobals(view); +#ifndef MAPBASE // Moved to respective ViewDrawScenes() for script_intro skybox fix + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( view, &nClearFlags, &nSkyboxVisible ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); +#endif // Force it to clear the framebuffer if they're in solid space. if ( ( nClearFlags & VIEW_CLEAR_COLOR ) == 0 ) @@ -2324,43 +2161,39 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT } } - // if the 3d skybox world is drawn, then don't draw the normal skybox - CSkyboxView* pSkyView = new CSkyboxView(this); - if ((bDrew3dSkybox = pSkyView->Setup(view, &nClearFlags, &nSkyboxVisible)) != false) - { - AddViewToScene(pSkyView); - } - SafeRelease(pSkyView); +#ifdef MAPBASE + // For script_intro viewmodel fix + bool bDrawnViewmodel = false; +#endif // Render world and all entities, particles, etc. if( !g_pIntroData ) { +#ifdef MAPBASE + // Moved here for the script_intro skybox fix. + // We can't put it in ViewDrawScene() directly because other functions use it as well. + + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( view, &nClearFlags, &nSkyboxVisible ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); +#endif + ViewDrawScene( bDrew3dSkybox, nSkyboxVisible, view, nClearFlags, VIEW_MAIN, whatToDraw & RENDERVIEW_DRAWVIEWMODEL ); } else { +#ifdef MAPBASE + ViewDrawScene_Intro( view, nClearFlags, *g_pIntroData, bDrew3dSkybox, nSkyboxVisible, whatToDraw & RENDERVIEW_DRAWVIEWMODEL ); + bDrawnViewmodel = true; +#else ViewDrawScene_Intro( view, nClearFlags, *g_pIntroData ); +#endif } - - // HACKHACK: depth pre-pass messes up with view frustum stack in the engine - // so i have to do it AFTER we render everything - CDepthView *pDepthView = new CDepthView( this ); - pDepthView->Setup( view ); - { - AddViewToScene( pDepthView ); - } - SafeRelease( pDepthView ); - - if (r_volumetrics.GetBool()) - { - CVolumetricsView* pVolumetricsView = new CVolumetricsView(this); - pVolumetricsView->Setup(view); - { - AddViewToScene(pVolumetricsView); - } - SafeRelease(pVolumetricsView); - } // We can still use the 'current view' stuff set up in ViewDrawScene s_bCanAccessCurrentView = true; @@ -2378,14 +2211,24 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT RenderPlayerSprites(); // Image-space motion blur - if ( !building_cubemaps.GetBool() && view.m_bDoBloomAndToneMapping ) // We probably should use a different view. variable here + if ( !building_cubemaps.GetBool() /*&& view.m_bDoBloomAndToneMapping*/ ) // We probably should use a different view. variable here { + if ( IsDepthOfFieldEnabled() ) + { + pRenderContext.GetFrom( materials ); + { + PIXEVENT( pRenderContext, "DoDepthOfField()" ); + DoDepthOfField( view ); + } + pRenderContext.SafeRelease(); + } + if ( ( mat_motion_blur_enabled.GetInt() ) && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90 ) ) { pRenderContext.GetFrom( materials ); { PIXEVENT( pRenderContext, "DoImageSpaceMotionBlur" ); - DoImageSpaceMotionBlur( view, view.x, view.y, view.width, view.height ); + DoImageSpaceMotionBlur( view ); } pRenderContext.SafeRelease(); } @@ -2393,30 +2236,12 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT GetClientModeNormal()->DoPostScreenSpaceEffects( &view ); - s_bDrawViewmodelShadow = true; - if (g_pCSMLight && g_pCSMLight->IsCascadedShadowMappingEnabled()) - { - UpdateLighting(view); - } - else - { - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE, 0); - pRenderContext.SafeRelease(); // don't want to hold for long periods in case in a locking active share thread mode - } - s_bDrawViewmodelShadow = false; - - - CMatRenderContextPtr pRenderContext(materials); - Rect_t srcRect = { 0, 0, GetScopeTexture()->GetActualWidth(), GetScopeTexture()->GetActualHeight() }; - pRenderContext->CopyRenderTargetToTextureEx(GetScopeTexture(), 0, &srcRect); - pRenderContext.SafeRelease(); // don't want to hold for long periods in case in a locking active share thread mode - // Now actually draw the viewmodel +#ifdef MAPBASE + if (!bDrawnViewmodel) +#endif DrawViewModels( view, whatToDraw & RENDERVIEW_DRAWVIEWMODEL ); - GetLightingManager()->RenderLights(view); - DrawUnderwaterOverlay(); PixelVisibility_EndScene(); @@ -2466,6 +2291,13 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT PerformScreenSpaceEffects( 0, 0, view.width, view.height ); + if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + pRenderContext.GetFrom( materials ); + pRenderContext->SetToneMappingScaleLinear(Vector(1,1,1)); + pRenderContext.SafeRelease(); + } + CleanupMain3DView( view ); if ( m_rbTakeFreezeFrame[ view.m_eStereoEye ] ) @@ -2715,10 +2547,6 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT //----------------------------------------------------------------------------- void CViewRender::Render2DEffectsPreHUD( const CViewSetup &view ) { - //DrawScreenEffectMaterial(m_HDRSample, view.x, view.y, view.width, view.height); - CMatRenderContextPtr pRenderContext(materials); - Rect_t srcRect = {0, 0, GetFullFrameHDRTexture()->GetActualWidth(), GetFullFrameHDRTexture()->GetActualHeight()}; - pRenderContext->CopyTextureToRenderTargetEx(0, GetFullFrameHDRTexture(), &srcRect); } //----------------------------------------------------------------------------- @@ -2930,6 +2758,34 @@ void CViewRender::DrawWorldAndEntities( bool bDrawSkybox, const CViewSetup &view { tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "bCheapWater" ); cplane_t glassReflectionPlane; +#ifdef MAPBASE + // New expansions allow for custom render targets and multiple mirror renders + Frustum_t frustum; + GeneratePerspectiveFrustum( viewIn.origin, viewIn.angles, viewIn.zNear, viewIn.zFar, viewIn.fov, viewIn.m_flAspectRatio, frustum ); + + ITexture *pTextureTargets[2]; + C_BaseEntity *pReflectiveGlass = NextReflectiveGlass( NULL, viewIn, glassReflectionPlane, frustum, pTextureTargets ); + while ( pReflectiveGlass != NULL ) + { + if (pTextureTargets[0]) + { + CRefPtr pGlassReflectionView = new CReflectiveGlassView( this ); + pGlassReflectionView->m_pRenderTarget = pTextureTargets[0]; + pGlassReflectionView->Setup( viewIn, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, bDrawSkybox, fogVolumeInfo, info, glassReflectionPlane ); + AddViewToScene( pGlassReflectionView ); + } + + if (pTextureTargets[1]) + { + CRefPtr pGlassRefractionView = new CRefractiveGlassView( this ); + pGlassRefractionView->Setup( viewIn, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, bDrawSkybox, fogVolumeInfo, info, glassReflectionPlane ); + pGlassRefractionView->m_pRenderTarget = pTextureTargets[1]; + AddViewToScene( pGlassRefractionView ); + } + + pReflectiveGlass = NextReflectiveGlass( pReflectiveGlass, viewIn, glassReflectionPlane, frustum, pTextureTargets ); + } +#else if ( IsReflectiveGlassInView( viewIn, glassReflectionPlane ) ) { CRefPtr pGlassReflectionView = new CReflectiveGlassView( this ); @@ -2940,6 +2796,7 @@ void CViewRender::DrawWorldAndEntities( bool bDrawSkybox, const CViewSetup &view pGlassRefractionView->Setup( viewIn, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, bDrawSkybox, fogVolumeInfo, info, glassReflectionPlane ); AddViewToScene( pGlassRefractionView ); } +#endif CRefPtr pNoWaterView = new CSimpleWorldView( this ); pNoWaterView->Setup( viewIn, nClearFlags, bDrawSkybox, fogVolumeInfo, info, pCustomVisibility ); @@ -3230,7 +3087,12 @@ void CViewRender::GetWaterLODParams( float &flCheapWaterStartDistance, float &fl // Input : &view - // &introData - //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, const IntroData_t &introData, + bool bDrew3dSkybox, SkyboxVisibility_t nSkyboxVisible, bool bDrawViewModel, ViewCustomVisibility_t *pCustomVisibility ) +#else void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, const IntroData_t &introData ) +#endif { VPROF( "CViewRender::ViewDrawScene" ); @@ -3260,11 +3122,43 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, CViewSetup playerView( view ); playerView.origin = introData.m_vecCameraView; playerView.angles = introData.m_vecCameraViewAngles; +#ifdef MAPBASE + // Ortho handling (change this code if we ever use m_hCameraEntity for other things) + if (introData.m_hCameraEntity /*&& introData.m_hCameraEntity->IsOrtho()*/) + { + playerView.m_bOrtho = true; + introData.m_hCameraEntity->GetOrthoDimensions( playerView.m_OrthoTop, playerView.m_OrthoBottom, + playerView.m_OrthoLeft, playerView.m_OrthoRight ); + } +#endif if ( introData.m_playerViewFOV ) { playerView.fov = ScaleFOVByWidthRatio( introData.m_playerViewFOV, engine->GetScreenAspectRatio() / ( 4.0f / 3.0f ) ); } +#ifdef MAPBASE + bool drawSkybox; + int nViewFlags; + if (introData.m_bDrawSky2) + { + drawSkybox = r_skybox.GetBool(); + nViewFlags = VIEW_CLEAR_DEPTH; + + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( playerView, &nClearFlags, &nSkyboxVisible ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); + } + else + { + drawSkybox = false; + nViewFlags = (VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH); + } +#endif + g_pClientShadowMgr->PreRender(); // Shadowed flashlights supported on ps_2_b and up... @@ -3279,11 +3173,38 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, IGameSystem::PreRenderAllSystems(); // Start view, clear frame/z buffer if necessary +#ifdef MAPBASE + SetupVis( playerView, visFlags, pCustomVisibility ); +#else SetupVis( playerView, visFlags ); +#endif + +#ifdef MAPBASE + if (introData.m_bDrawSky2) + { + if ( !bDrew3dSkybox && + ( nSkyboxVisible == SKYBOX_NOT_VISIBLE ) /*&& ( visFlags & IVRenderView::VIEW_SETUP_VIS_EX_RETURN_FLAGS_USES_RADIAL_VIS )*/ ) + { + // This covers the case where we don't see a 3dskybox, yet radial vis is clipping + // the far plane. Need to clear to fog color in this case. + nClearFlags |= VIEW_CLEAR_COLOR; + //SetClearColorToFogColor( ); + } + + if ( bDrew3dSkybox || ( nSkyboxVisible == SKYBOX_NOT_VISIBLE ) ) + { + drawSkybox = false; + } + } +#endif +#ifdef MAPBASE + render->Push3DView( playerView, nViewFlags, NULL, GetFrustum() ); + DrawWorldAndEntities( drawSkybox, playerView, nViewFlags ); +#else render->Push3DView( playerView, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH, NULL, GetFrustum() ); - PushGBufferRT(); DrawWorldAndEntities( true /* drawSkybox */, playerView, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH ); +#endif render->PopView( GetFrustum() ); // Free shadow depth textures for use in future view @@ -3299,12 +3220,28 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, Rect_t actualRect; UpdateScreenEffectTexture( 0, view.x, view.y, view.width, view.height, false, &actualRect ); +#ifdef MAPBASE + if (introData.m_bDrawSky) + { + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( view, &nClearFlags, &nSkyboxVisible ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); + } +#endif + g_pClientShadowMgr->PreRender(); // Shadowed flashlights supported on ps_2_b and up... if ( r_flashlightdepthtexture.GetBool() ) { g_pClientShadowMgr->ComputeShadowDepthTextures( view ); +#ifdef ASW_PROJECTED_TEXTURES + CMatRenderContextPtr pRenderContext( materials ); +#endif } // ----------------------------------------------------------------------- @@ -3321,7 +3258,41 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, // Clear alpha to 255 so that masking with the vortigaunts (0) works properly. pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); +#ifdef MAPBASE + bool drawSkybox; + int nViewFlags; + if (introData.m_bDrawSky) + { + drawSkybox = r_skybox.GetBool(); + nViewFlags = VIEW_CLEAR_DEPTH; + + if ( !bDrew3dSkybox && + ( nSkyboxVisible == SKYBOX_NOT_VISIBLE ) /*&& ( visFlags & IVRenderView::VIEW_SETUP_VIS_EX_RETURN_FLAGS_USES_RADIAL_VIS )*/ ) + { + // This covers the case where we don't see a 3dskybox, yet radial vis is clipping + // the far plane. Need to clear to fog color in this case. + nViewFlags |= VIEW_CLEAR_COLOR; + //SetClearColorToFogColor( ); + } + + if ( bDrew3dSkybox || ( nSkyboxVisible == SKYBOX_NOT_VISIBLE ) ) + { + drawSkybox = false; + } + } + else + { + drawSkybox = false; + nViewFlags = (VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH); + } + + DrawWorldAndEntities( drawSkybox, view, nViewFlags ); + + // Solution for viewmodels not drawing in script_intro + DrawViewModels( view, bDrawViewModel ); +#else DrawWorldAndEntities( true /* drawSkybox */, view, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH ); +#endif UpdateScreenEffectTexture( 1, view.x, view.y, view.width, view.height ); @@ -3400,6 +3371,11 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, // Let the particle manager simulate things that haven't been simulated. ParticleMgr()->PostRender(); +#ifdef MAPBASE + // Invoke post-render methods + IGameSystem::PostRenderAllSystems(); +#endif + FinishCurrentView(); // Free shadow depth textures for use in future view @@ -3469,16 +3445,230 @@ bool CViewRender::DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_Poin monitorView.origin = pCameraEnt->GetAbsOrigin(); monitorView.angles = pCameraEnt->GetAbsAngles(); monitorView.fov = pCameraEnt->GetFOV(); +#ifdef MAPBASE + if (pCameraEnt->IsOrtho()) + { + monitorView.m_bOrtho = true; + pCameraEnt->GetOrthoDimensions( monitorView.m_OrthoTop, monitorView.m_OrthoBottom, + monitorView.m_OrthoLeft, monitorView.m_OrthoRight ); + } + else + { + monitorView.m_bOrtho = false; + } +#else monitorView.m_bOrtho = false; +#endif monitorView.m_flAspectRatio = pCameraEnt->UseScreenAspectRatio() ? 0.0f : 1.0f; monitorView.m_bViewToProjectionOverride = false; +#ifdef MAPBASE + // + // Monitor sky handling + // + SkyboxVisibility_t nSkyMode = pCameraEnt->SkyMode(); + if ( nSkyMode == SKYBOX_3DSKYBOX_VISIBLE ) + { + int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR); + bool bDrew3dSkybox = false; + + Frustum frustum; + render->Push3DView( monitorView, nClearFlags, pRenderTarget, (VPlane *)frustum ); + + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( monitorView, &nClearFlags, &nSkyMode ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); + + ViewDrawScene( bDrew3dSkybox, nSkyMode, monitorView, nClearFlags, VIEW_MONITOR ); + render->PopView( frustum ); + } + else if (nSkyMode == SKYBOX_NOT_VISIBLE) + { + // @MULTICORE (toml 8/11/2006): this should be a renderer.... + Frustum frustum; + render->Push3DView( monitorView, VIEW_CLEAR_DEPTH, pRenderTarget, (VPlane *)frustum ); + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->PushRenderTargetAndViewport( pRenderTarget ); + pRenderContext->SetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA, 1 ); + if ( pRenderTarget ) + { + pRenderContext->OverrideAlphaWriteEnable( true, true ); + } + + ViewDrawScene( false, nSkyMode, monitorView, 0, VIEW_MONITOR ); + + pRenderContext->PopRenderTargetAndViewport(); + render->PopView( frustum ); + } + else + { + // @MULTICORE (toml 8/11/2006): this should be a renderer.... + Frustum frustum; + render->Push3DView( monitorView, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, pRenderTarget, (VPlane *)frustum ); + ViewDrawScene( false, nSkyMode, monitorView, 0, VIEW_MONITOR ); + render->PopView( frustum ); + } +#else // @MULTICORE (toml 8/11/2006): this should be a renderer.... Frustum frustum; render->Push3DView( monitorView, VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR, pRenderTarget, (VPlane *)frustum ); - PushGBufferRT(); ViewDrawScene( false, SKYBOX_2DSKYBOX_VISIBLE, monitorView, 0, VIEW_MONITOR ); render->PopView( frustum ); +#endif + + // Reset the world fog parameters. + if ( fogEnabled ) + { + if ( pFogParams ) + { + *pFogParams = oldFogParams; + } + monitorView.zFar = flOldZFar; + } +#endif // USE_MONITORS + return true; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets up scene and renders WIP fake world portal view. +// Based on code from monitors, mirrors, and logic_measure_movement. +// +// Input : cameraNum - +// &cameraView +// *localPlayer - +// x - +// y - +// width - +// height - +// highend - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, + int x, int y, int width, int height, + const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, float flLocalPlaneDist ) +{ +#ifdef USE_MONITORS + VPROF_INCREMENT_COUNTER( "cameras rendered", 1 ); + // Setup fog state for the camera. + fogparams_t oldFogParams; + float flOldZFar = 0.0f; + + // If fog should be disabled instead of using the player's controller, a blank fog controller can just be used + bool fogEnabled = true; //pCameraEnt->IsFogEnabled(); + + CViewSetup monitorView = cameraView; + + fogparams_t *pFogParams = NULL; + + if ( fogEnabled ) + { + if ( !localPlayer ) + return false; + + pFogParams = localPlayer->GetFogParams(); + + // Save old fog data. + oldFogParams = *pFogParams; + + if ( pCameraEnt->GetFog() ) + { + *pFogParams = *pCameraEnt->GetFog(); + } + } + + monitorView.x = x; + monitorView.y = y; + monitorView.width = width; + monitorView.height = height; + monitorView.m_bOrtho = mainView.m_bOrtho; + monitorView.fov = mainView.fov; + monitorView.m_flAspectRatio = mainView.m_flAspectRatio; + monitorView.m_bViewToProjectionOverride = false; + + matrix3x4_t worldToView; + AngleIMatrix( mainView.angles, mainView.origin, worldToView ); + + matrix3x4_t targetToWorld; + { + // NOTE: m_PlaneAngles is angle offset + QAngle targetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles; + AngleMatrix( targetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), targetToWorld ); + } + + matrix3x4_t portalToWorld; + { + Vector left, up; + VectorVectors( vecAbsPlaneNormal, left, up ); + VectorNegate( left ); + portalToWorld.Init( vecAbsPlaneNormal, left, up, pCameraEnt->GetAbsOrigin() ); + } + + matrix3x4_t portalToView; + ConcatTransforms( worldToView, portalToWorld, portalToView ); + + if ( pCameraEnt->m_flScale > 0.0f ) + { + portalToView[0][3] /= pCameraEnt->m_flScale; + portalToView[1][3] /= pCameraEnt->m_flScale; + portalToView[2][3] /= pCameraEnt->m_flScale; + } + + matrix3x4_t viewToPortal; + MatrixInvert( portalToView, viewToPortal ); + + matrix3x4_t newViewToWorld; + ConcatTransforms( targetToWorld, viewToPortal, newViewToWorld ); + + MatrixAngles( newViewToWorld, monitorView.angles, monitorView.origin ); + + + // @MULTICORE (toml 8/11/2006): this should be a renderer.... + int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL); + bool bDrew3dSkybox = false; + + Frustum frustum; + render->Push3DView( monitorView, nClearFlags, pRenderTarget, (VPlane *)frustum ); + + // + // Sky handling + // + SkyboxVisibility_t nSkyMode = pCameraEnt->SkyMode(); + if ( nSkyMode == SKYBOX_3DSKYBOX_VISIBLE ) + { + // if the 3d skybox world is drawn, then don't draw the normal skybox + CSkyboxView *pSkyView = new CSkyboxView( this ); + if ( ( bDrew3dSkybox = pSkyView->Setup( monitorView, &nClearFlags, &nSkyMode ) ) != false ) + { + AddViewToScene( pSkyView ); + } + SafeRelease( pSkyView ); + } + + Vector4D plane; + + // target direction + MatrixGetColumn( targetToWorld, 0, plane.AsVector3D() ); + VectorNormalize( plane.AsVector3D() ); + VectorNegate( plane.AsVector3D() ); + + plane.w = + MatrixColumnDotProduct( targetToWorld, 3, plane.AsVector3D() ) // target clip plane distance + - flLocalPlaneDist // portal plane distance on the brush. This distance needs to be accounted for while placing the exit target + - 0.1; + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->PushCustomClipPlane( plane.Base() ); + + ViewDrawScene( bDrew3dSkybox, nSkyMode, monitorView, nClearFlags, VIEW_MONITOR ); + + pRenderContext->PopCustomClipPlane(); + render->PopView( frustum ); // Reset the world fog parameters. if ( fogEnabled ) @@ -3492,6 +3682,7 @@ bool CViewRender::DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_Poin #endif // USE_MONITORS return true; } +#endif void CViewRender::DrawMonitors( const CViewSetup &cameraView ) { @@ -3526,6 +3717,17 @@ void CViewRender::DrawMonitors( const CViewSetup &cameraView ) if ( !pCameraEnt->IsActive() || pCameraEnt->IsDormant() ) continue; +#ifdef MAPBASE + // Check if the camera has its own render target + // (Multiple render target support) + if ( pCameraTarget != pCameraEnt->RenderTarget() ) + { + pCameraTarget = pCameraEnt->RenderTarget(); + width = pCameraTarget->GetActualWidth(); + height = pCameraTarget->GetActualHeight(); + } +#endif + if ( !DrawOneMonitor( pCameraTarget, cameraNum, pCameraEnt, cameraView, player, 0, 0, width, height ) ) continue; @@ -3900,13 +4102,6 @@ void CRendering3dView::DrawWorld( float waterZAdjust ) return; } - if ((m_DrawFlags & DF_DRAWSKYBOX) && (g_pCSMLight && g_pCSMLight->IsDynamicSkyEnabled())) - { - m_DrawFlags &= ~DF_DRAWSKYBOX; // dont render engine sky, we have our own sky now - - m_pMainView->DrawSky(*this); - } - unsigned long engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags ); render->DrawWorldLists( m_pWorldRenderList, engineFlags, waterZAdjust ); @@ -4286,55 +4481,15 @@ static void DrawOpaqueRenderables_DrawStaticProps( CClientRenderablesList::CEntr } if ( numScheduled ) - staticpropmgr->DrawStaticProps( pStatics, numScheduled, DepthMode, vcollide_wireframe.GetBool() ); -} - -static void DrawOpaqueRenderables_Range( CClientRenderablesList::CEntry *pEntitiesBegin, CClientRenderablesList::CEntry *pEntitiesEnd, ERenderDepthMode DepthMode ) -{ - for( CClientRenderablesList::CEntry *itEntity = pEntitiesBegin; itEntity < pEntitiesEnd; ++ itEntity ) - { - if ( itEntity->m_pRenderable ) - DrawOpaqueRenderable( itEntity->m_pRenderable, ( itEntity->m_TwoPass != 0 ), DepthMode ); - } -} - -static void DrawOpaqueRenderable_Parallel_Normal(CClientRenderablesList::CEntry& Entity) -{ - if (Entity.m_pRenderable) - { - DrawOpaqueRenderable(Entity.m_pRenderable, (Entity.m_TwoPass != 0), DEPTH_MODE_NORMAL); - } -} - -static void DrawOpaqueRenderable_Parallel_Shadow(CClientRenderablesList::CEntry& Entity) -{ - if (Entity.m_pRenderable) - { - DrawOpaqueRenderable(Entity.m_pRenderable, (Entity.m_TwoPass != 0), DEPTH_MODE_SHADOW); - } -} - -static void DrawOpaqueRenderable_Parallel_SSA0(CClientRenderablesList::CEntry& Entity) -{ - if (Entity.m_pRenderable) - { - DrawOpaqueRenderable(Entity.m_pRenderable, (Entity.m_TwoPass != 0), DEPTH_MODE_SSA0); - } + staticpropmgr->DrawStaticProps( pStatics, numScheduled, DepthMode, vcollide_wireframe.GetBool() ); } -static void DrawOpaqueRenderables_Parallel(CClientRenderablesList::CEntry* pEntitiesBegin, int nCount, ERenderDepthMode DepthMode, const char* pszDescription) +static void DrawOpaqueRenderables_Range( CClientRenderablesList::CEntry *pEntitiesBegin, CClientRenderablesList::CEntry *pEntitiesEnd, ERenderDepthMode DepthMode ) { - switch (DepthMode) + for( CClientRenderablesList::CEntry *itEntity = pEntitiesBegin; itEntity < pEntitiesEnd; ++ itEntity ) { - case DEPTH_MODE_NORMAL: - ParallelProcess(pszDescription, pEntitiesBegin, nCount, &DrawOpaqueRenderable_Parallel_Normal); - break; - case DEPTH_MODE_SHADOW: - ParallelProcess(pszDescription, pEntitiesBegin, nCount, &DrawOpaqueRenderable_Parallel_Shadow); - break; - case DEPTH_MODE_SSA0: - ParallelProcess(pszDescription, pEntitiesBegin, nCount, &DrawOpaqueRenderable_Parallel_SSA0); - break; + if ( itEntity->m_pRenderable ) + DrawOpaqueRenderable( itEntity->m_pRenderable, ( itEntity->m_TwoPass != 0 ), DepthMode ); } } @@ -4460,7 +4615,7 @@ void CRendering3dView::DrawOpaqueRenderables( ERenderDepthMode DepthMode ) } } - if (r_threaded_renderables.GetBool() ) + if ( 0 && r_threaded_renderables.GetBool() ) { ParallelProcess( "BoneSetupNpcsLast", arrBoneSetupNpcsLast.Base() + numOpaqueEnts - numNpcs, numNpcs, &SetupBonesOnBaseAnimating ); ParallelProcess( "BoneSetupNpcsLast NonNPCs", arrBoneSetupNpcsLast.Base(), numNonNpcsAnimating, &SetupBonesOnBaseAnimating ); @@ -4544,10 +4699,7 @@ void CRendering3dView::DrawOpaqueRenderables( ERenderDepthMode DepthMode ) // // Draw NPCs now // - if (r_threaded_renderables.GetBool()) - DrawOpaqueRenderables_Parallel(arrRenderEntsNpcsFirst.Base(), numNpcs, DepthMode, "Draw NPCs"); - else - DrawOpaqueRenderables_Range( arrRenderEntsNpcsFirst.Base(), arrRenderEntsNpcsFirst.Base() + numNpcs, DepthMode ); + DrawOpaqueRenderables_Range( arrRenderEntsNpcsFirst.Base(), arrRenderEntsNpcsFirst.Base() + numNpcs, DepthMode ); // // Ropes and particles @@ -5171,7 +5323,20 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR // if you can get really close to the skybox geometry it's possible that you'll be able to clip into it // with this near plane. If so, move it in a bit. It's at 2.0 to give us more precision. That means you // need to keep the eye position at least 2 * scale away from the geometry in the skybox +#ifdef MAPBASE + zNear = r_nearz_skybox.GetFloat(); + + // Use the fog's farz if specified + if (m_pSky3dParams->fog.farz > 0) + { + zFar = ( m_pSky3dParams->scale > 0.0f ? + m_pSky3dParams->fog.farz / m_pSky3dParams->scale : + m_pSky3dParams->fog.farz ); + } + else +#else zNear = 2.0; +#endif zFar = MAX_TRACE_LENGTH; // scale origin by sky scale @@ -5181,15 +5346,57 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR VectorScale( origin, scale, origin ); } Enable3dSkyboxFog(); +#ifdef MAPBASE + // Skybox angle support. + // + // If any of the angles aren't 0, do the rotation code. + if (m_pSky3dParams->skycamera) + { + // Re-use the x coordinate to determine if we shuld do this with angles + if (m_pSky3dParams->angles.GetX() != 0) + { + const matrix3x4_t &matSky = m_pSky3dParams->skycamera->EntityToWorldTransform(); + matrix3x4_t matView; + AngleMatrix( angles, origin, matView ); + ConcatTransforms( matSky, matView, matView ); + MatrixAngles( matView, angles, origin ); + } + else + { + VectorAdd( origin, m_pSky3dParams->skycamera->GetAbsOrigin(), origin ); + } + } + else + { + if (m_pSky3dParams->angles.GetX() != 0 || + m_pSky3dParams->angles.GetY() != 0 || + m_pSky3dParams->angles.GetZ() != 0) + { + matrix3x4_t matSky, matView; + AngleMatrix( m_pSky3dParams->angles, m_pSky3dParams->origin, matSky ); + AngleMatrix( angles, origin, matView ); + ConcatTransforms( matSky, matView, matView ); + MatrixAngles( matView, angles, origin ); + } + else + { + VectorAdd( origin, m_pSky3dParams->origin, origin ); + } + } +#else VectorAdd( origin, m_pSky3dParams->origin, origin ); +#endif // BUGBUG: Fix this!!! We shouldn't need to call setup vis for the sky if we're connecting // the areas. We'd have to mark all the clusters in the skybox area in the PVS of any // cluster with sky. Then we could just connect the areas to do our vis. //m_bOverrideVisOrigin could hose us here, so call direct +#ifdef MAPBASE + render->ViewSetupVis( false, 1, m_pSky3dParams->skycamera ? &m_pSky3dParams->skycamera->GetAbsOrigin() : &m_pSky3dParams->origin.Get() ); +#else render->ViewSetupVis( false, 1, &m_pSky3dParams->origin.Get() ); +#endif render->Push3DView( (*this), m_ClearFlags, pRenderTarget, GetFrustum(), pDepthTarget ); - m_pMainView->PushGBufferRT(); // Store off view origin and angles SetupCurrentView( origin, angles, iSkyBoxViewID ); @@ -5222,6 +5429,51 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR DrawTranslucentRenderables( true, false ); DrawNoZBufferTranslucentRenderables(); +#ifdef MAPBASE + // Allows reflective glass to be drawn in the skybox. + // New expansions also allow for custom render targets and multiple mirror renders + if (r_skybox_use_complex_views.GetBool()) + { + VisibleFogVolumeInfo_t fogVolumeInfo; + render->GetVisibleFogVolume( origin, &fogVolumeInfo ); + + WaterRenderInfo_t info; + info.m_bCheapWater = true; + info.m_bRefract = false; + info.m_bReflect = false; + info.m_bReflectEntities = false; + info.m_bDrawWaterSurface = false; + info.m_bOpaqueWater = true; + + cplane_t glassReflectionPlane; + Frustum_t frustum; + GeneratePerspectiveFrustum( origin, angles, zNear, zFar, fov, m_flAspectRatio, frustum ); + + ITexture *pTextureTargets[2]; + C_BaseEntity *pReflectiveGlass = NextReflectiveGlass( NULL, (*this), glassReflectionPlane, frustum, pTextureTargets ); + while ( pReflectiveGlass != NULL ) + { + if (pTextureTargets[0]) + { + CRefPtr pGlassReflectionView = new CReflectiveGlassView( m_pMainView ); + pGlassReflectionView->m_pRenderTarget = pTextureTargets[0]; + pGlassReflectionView->Setup( (*this), VIEW_CLEAR_DEPTH, true, fogVolumeInfo, info, glassReflectionPlane ); + m_pMainView->AddViewToScene( pGlassReflectionView ); + } + + if (pTextureTargets[1]) + { + CRefPtr pGlassRefractionView = new CRefractiveGlassView( m_pMainView ); + pGlassRefractionView->m_pRenderTarget = pTextureTargets[1]; + pGlassRefractionView->Setup( (*this), VIEW_CLEAR_DEPTH, true, fogVolumeInfo, info, glassReflectionPlane ); + m_pMainView->AddViewToScene( pGlassRefractionView ); + } + + pReflectiveGlass = NextReflectiveGlass( pReflectiveGlass, (*this), glassReflectionPlane, frustum, pTextureTargets ); + } + } +#endif + m_pMainView->DisableFog(); CGlowOverlay::UpdateSkyOverlays( zFar, m_bCacheFullSceneState ); @@ -5269,6 +5521,20 @@ bool CSkyboxView::Setup( const CViewSetup &view, int *pClearFlags, SkyboxVisibil *pClearFlags |= VIEW_CLEAR_DEPTH; // Need to clear depth after rednering the skybox m_DrawFlags = DF_RENDER_UNDERWATER | DF_RENDER_ABOVEWATER | DF_RENDER_WATER; +#ifdef MAPBASE + if (m_pSky3dParams->skycolor.GetA() != 0 && *pSkyboxVisible != SKYBOX_NOT_VISIBLE) + { + m_ClearFlags |= (VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH); + m_DrawFlags |= DF_CLIP_SKYBOX; + + color32 color = m_pSky3dParams->skycolor.Get(); + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->ClearColor4ub( color.r, color.g, color.b, color.a ); + pRenderContext.SafeRelease(); + } + else +#endif if( r_skybox.GetBool() ) { m_DrawFlags |= DF_DRAWSKYBOX; @@ -5398,8 +5664,15 @@ void CShadowDepthView::Draw() pRenderContext.SafeRelease(); - render->Push3DView( (*this), VIEW_CLEAR_DEPTH, m_pRenderTarget, GetFrustum(), m_pDepthTexture ); - + if( IsPC() ) + { + render->Push3DView( (*this), VIEW_CLEAR_DEPTH, m_pRenderTarget, GetFrustum(), m_pDepthTexture ); + } + else if( IsX360() ) + { + //for the 360, the dummy render target has a separate depth buffer which we Resolve() from afterward + render->Push3DView( (*this), VIEW_CLEAR_DEPTH, m_pRenderTarget, GetFrustum() ); + } SetupCurrentView( origin, angles, VIEW_SHADOW_DEPTH_TEXTURE ); @@ -5439,99 +5712,20 @@ void CShadowDepthView::Draw() pRenderContext.GetFrom( materials ); - render->PopView( GetFrustum() ); - -#if defined( _X360 ) - pRenderContext->PopVertexShaderGPRAllocation(); -#endif -} - - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CCSMDepthView::Setup(const CViewSetup& shadowViewIn, ITexture* pRenderTarget, ITexture* pDepthTexture) -{ - BaseClass::Setup(shadowViewIn); - m_pRenderTarget = pRenderTarget; - m_pDepthTexture = pDepthTexture; -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CCSMDepthView::Draw() -{ - VPROF_BUDGET("CShadowDepthView::Draw", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - - // Start view - //unsigned int visFlags; - render->ViewSetupVis(false, 1, &origin); // @MULTICORE (toml 8/9/2006): Portal problem, not sending custom vis down - - CMatRenderContextPtr pRenderContext(materials); - - pRenderContext->ClearColor3ub(0xFF, 0xFF, 0xFF); - -#if defined( _X360 ) - pRenderContext->PushVertexShaderGPRAllocation(112); //almost all work is done in vertex shaders for depth rendering, max out their threads -#endif - - pRenderContext.SafeRelease(); - - - render->Push3DView((*this), VIEW_CLEAR_DEPTH, m_pRenderTarget, GetFrustum(), m_pDepthTexture); - - - SetupCurrentView(origin, angles, VIEW_SHADOW_DEPTH_TEXTURE); - - MDLCACHE_CRITICAL_SECTION(); - - { - VPROF_BUDGET("BuildWorldRenderLists", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - BuildWorldRenderLists(true, -1, true, true); // @MULTICORE (toml 8/9/2006): Portal problem, not sending custom vis down - } - - if(nCascade < 3) - { - VPROF_BUDGET("BuildRenderableRenderLists", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - BuildRenderableRenderLists(CurrentViewID()); - } - - engine->Sound_ExtraUpdate(); // Make sure sound doesn't stutter - - m_DrawFlags = m_pMainView->GetBaseDrawFlags() | DF_RENDER_UNDERWATER | DF_RENDER_ABOVEWATER | DF_SHADOW_DEPTH_MAP; // Don't draw water surface... - - { - VPROF_BUDGET("DrawWorld", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - DrawWorld(0.0f); - } - - // Draw opaque and translucent renderables with appropriate override materials - // OVERRIDE_DEPTH_WRITE is OK with a NULL material pointer - modelrender->ForcedMaterialOverride(NULL, OVERRIDE_DEPTH_WRITE); - - if (nCascade < 3) + if( IsX360() ) { - VPROF_BUDGET("DrawOpaqueRenderables", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING); - DrawOpaqueRenderables(DEPTH_MODE_SHADOW); + //Resolve() the depth texture here. Before the pop so the copy will recognize that the resolutions are the same + pRenderContext->CopyRenderTargetToTextureEx( m_pDepthTexture, -1, NULL, NULL ); } - if (s_bDrawViewmodelShadow) - m_pMainView->DrawViewModels((*this), true); - - modelrender->ForcedMaterialOverride(0); - - m_DrawFlags = 0; - - pRenderContext.GetFrom(materials); - - render->PopView(GetFrustum()); + render->PopView( GetFrustum() ); #if defined( _X360 ) pRenderContext->PopVertexShaderGPRAllocation(); #endif } + //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -5614,7 +5808,7 @@ bool CBaseWorldView::AdjustView( float waterHeight ) { if( m_DrawFlags & DF_RENDER_REFRACTION ) { - ITexture *pTexture = GetWaterRefractionTexture(); + ITexture *pTexture = GetRefractionTexture(); // Use the aspect ratio of the main view! So, don't recompute it here x = y = 0; @@ -5626,7 +5820,7 @@ bool CBaseWorldView::AdjustView( float waterHeight ) if( m_DrawFlags & DF_RENDER_REFLECTION ) { - ITexture *pTexture = GetWaterReflectionTexture(); + ITexture *pTexture = GetReflectionTexture(); // If the main view is overriding the projection matrix (for Stereo or // some other nefarious purpose) make sure to include any Y offset in @@ -5688,14 +5882,14 @@ void CBaseWorldView::PushView( float waterHeight ) pRenderContext->SetHeightClipMode( clipMode ); // Have to re-set up the view since we reset the size - render->Push3DView( *this, m_ClearFlags, GetWaterRefractionTexture(), GetFrustum() ); + render->Push3DView( *this, m_ClearFlags, GetRefractionTexture(), GetFrustum() ); return; } if( m_DrawFlags & DF_RENDER_REFLECTION ) { - ITexture *pTexture = GetWaterReflectionTexture(); + ITexture *pTexture = GetReflectionTexture(); pRenderContext->SetFogZ( waterHeight ); @@ -5710,7 +5904,7 @@ void CBaseWorldView::PushView( float waterHeight ) render->Push3DView( *this, m_ClearFlags, pTexture, GetFrustum() ); - //SetLightmapScaleForWater(); + SetLightmapScaleForWater(); return; } @@ -5749,18 +5943,18 @@ void CBaseWorldView::PopView() // these renders paths used their surfaces, so blit their results if ( m_DrawFlags & DF_RENDER_REFRACTION ) { - pRenderContext->CopyRenderTargetToTextureEx( GetWaterRefractionTexture(), NULL, NULL ); + pRenderContext->CopyRenderTargetToTextureEx( GetRefractionTexture(), NULL, NULL ); } if ( m_DrawFlags & DF_RENDER_REFLECTION ) { - pRenderContext->CopyRenderTargetToTextureEx( GetWaterReflectionTexture(), NULL, NULL ); + pRenderContext->CopyRenderTargetToTextureEx( GetReflectionTexture(), NULL, NULL ); } } render->PopView( GetFrustum() ); if (SavedLinearLightMapScale.x>=0) { - //pRenderContext->SetToneMappingScaleLinear(SavedLinearLightMapScale); + pRenderContext->SetToneMappingScaleLinear(SavedLinearLightMapScale); SavedLinearLightMapScale.x=-1; } } @@ -6154,158 +6348,6 @@ void CSimpleWorldView::Draw() #endif } -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -bool CDepthView::Setup(const CViewSetup& view, ITexture* pDepthTexture, ITexture* pRenderTarget) -{ - BaseClass::Setup(view); - - // At this point, we've cleared everything we need to clear - // The next path will need to clear depth, though. - m_ClearFlags = VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL | VIEW_CLEAR_FULL_TARGET; - - m_DrawFlags = DF_RENDER_UNDERWATER | DF_RENDER_ABOVEWATER | DF_RENDER_WATER; - - zNear = view.zNear; - zFar = view.zFar; - - m_pDepthTexture = pDepthTexture; - m_pColorTexture = pRenderTarget; - - return true; -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CDepthView::Draw() -{ - VPROF_BUDGET("CViewRender::Draw3dSkyboxworld", "3D Skybox"); - - DrawInternal(CurrentViewID()); -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CDepthView::DrawInternal(view_id_t iSkyBoxViewID) -{ - ITexture* DepthBufferTexture = materials->FindTexture("_rt_DepthBuffer", TEXTURE_GROUP_RENDER_TARGET); - - if (m_pDepthTexture == NULL && m_pColorTexture == NULL) - { - render->Push3DView((*this), m_ClearFlags, DepthBufferTexture, GetFrustum(), NULL); - } - else - { - render->Push3DView((*this), m_ClearFlags, m_pDepthTexture, GetFrustum(), m_pColorTexture); - } - render->BeginUpdateLightmaps(); - BuildWorldRenderLists(true, true, -1); - BuildRenderableRenderLists(iSkyBoxViewID); - render->EndUpdateLightmaps(); - - m_DrawFlags |= DF_SSAO_DEPTH_PASS; - - DrawWorld(0.0f); - - // Draw opaque and translucent renderables with appropriate override materials - // OVERRIDE_SSAO_DEPTH_WRITE is OK with a NULL material pointer - modelrender->ForcedMaterialOverride(nullptr, OVERRIDE_SSAO_DEPTH_WRITE); - - // Iterate over all leaves and render objects in those leaves - DrawOpaqueRenderables(DEPTH_MODE_SSA0); - - m_pMainView->DrawViewModels((*this), true); - - modelrender->ForcedMaterialOverride(nullptr); - - render->PopView(GetFrustum()); - -#if defined( _X360 ) - pRenderContext.GetFrom(materials); - pRenderContext->PopVertexShaderGPRAllocation(); -#endif -} - - - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -bool CVolumetricsView::Setup(const CViewSetup& view, ITexture* pDepthTexture, ITexture* pRenderTarget) -{ - BaseClass::Setup(view); - - m_ClearFlags = VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL; - - m_DrawFlags = DF_RENDER_UNDERWATER | DF_RENDER_ABOVEWATER | DF_RENDER_WATER; - - return true; -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CVolumetricsView::Draw() -{ - VPROF_BUDGET("CViewRender::Draw3dSkyboxworld", "3D Skybox"); - - DrawInternal(VIEW_VOLUMETRICS); -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void CVolumetricsView::DrawInternal(view_id_t iSkyBoxViewID) -{ - ITexture* ColorBufferTexture = materials->FindTexture("_rt_VolumetricsBuffer", TEXTURE_GROUP_RENDER_TARGET); - - render->Push3DView((*this), m_ClearFlags, ColorBufferTexture, GetFrustum(), NULL); - - view_id_t iSavedID = CurrentViewID(); - // Store off view origin and angles - SetupCurrentView(origin, angles, iSkyBoxViewID); - - CMatRenderContextPtr pRenderContext(materials); - pRenderContext->Viewport(0, 0, ColorBufferTexture->GetActualWidth(), ColorBufferTexture->GetActualHeight()); - pRenderContext.SafeRelease(); - - render->BeginUpdateLightmaps(); - BuildWorldRenderLists(true, true, -1); - BuildRenderableRenderLists(iSkyBoxViewID); - render->EndUpdateLightmaps(); - - m_DrawFlags |= DF_SSAO_DEPTH_PASS; - DrawWorld(0.0f); - - // Draw opaque and translucent renderables with appropriate override materials - // OVERRIDE_SSAO_DEPTH_WRITE is OK with a NULL material pointer - modelrender->ForcedMaterialOverride(nullptr, OVERRIDE_DEPTH_WRITE); - - // Iterate over all leaves and render objects in those leaves - DrawOpaqueRenderables(DEPTH_MODE_NORMAL); - - m_pMainView->DrawViewModels((*this), true); - - modelrender->ForcedMaterialOverride(nullptr); - - pRenderContext.GetFrom(materials); - pRenderContext->ClearBuffers(true, false); - pRenderContext.SafeRelease(); - - GetLightingManager()->RenderVolumetrics((*this)); - - render->PopView(GetFrustum()); - - SetupCurrentView(origin, angles, iSavedID); - -#if defined( _X360 ) - pRenderContext.GetFrom(materials); - pRenderContext->PopVertexShaderGPRAllocation(); -#endif -} //----------------------------------------------------------------------------- // @@ -6782,7 +6824,11 @@ void CReflectiveGlassView::Setup( const CViewSetup &view, int nClearFlags, bool bool CReflectiveGlassView::AdjustView( float flWaterHeight ) { +#ifdef MAPBASE + ITexture *pTexture = GetReflectionTexture(); +#else ITexture *pTexture = GetWaterReflectionTexture(); +#endif // Use the aspect ratio of the main view! So, don't recompute it here x = y = 0; @@ -6808,8 +6854,11 @@ bool CReflectiveGlassView::AdjustView( float flWaterHeight ) void CReflectiveGlassView::PushView( float waterHeight ) { +#ifdef MAPBASE + render->Push3DView( *this, m_ClearFlags, GetReflectionTexture(), GetFrustum() ); +#else render->Push3DView( *this, m_ClearFlags, GetWaterReflectionTexture(), GetFrustum() ); - m_pMainView->PushGBufferRT(); +#endif Vector4D plane; VectorCopy( m_ReflectionPlane.normal, plane.AsVector3D() ); @@ -6837,6 +6886,12 @@ void CReflectiveGlassView::Draw() CMatRenderContextPtr pRenderContext( materials ); PIXEVENT( pRenderContext, "CReflectiveGlassView::Draw" ); +#ifdef MAPBASE + // Store off view origin and angles and set the new view + int nSaveViewID = CurrentViewID(); + SetupCurrentView( origin, angles, VIEW_REFLECTION ); +#endif + // Disable occlusion visualization in reflection bool bVisOcclusion = r_visocclusion.GetInt(); r_visocclusion.SetValue( 0 ); @@ -6845,6 +6900,11 @@ void CReflectiveGlassView::Draw() r_visocclusion.SetValue( bVisOcclusion ); +#ifdef MAPBASE + // finish off the view. restore the previous view. + SetupCurrentView( origin, angles, (view_id_t)nSaveViewID ); +#endif + pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); pRenderContext->Flush(); } @@ -6864,7 +6924,11 @@ void CRefractiveGlassView::Setup( const CViewSetup &view, int nClearFlags, bool bool CRefractiveGlassView::AdjustView( float flWaterHeight ) { +#ifdef MAPBASE + ITexture *pTexture = GetRefractionTexture(); +#else ITexture *pTexture = GetWaterRefractionTexture(); +#endif // Use the aspect ratio of the main view! So, don't recompute it here x = y = 0; @@ -6876,8 +6940,11 @@ bool CRefractiveGlassView::AdjustView( float flWaterHeight ) void CRefractiveGlassView::PushView( float waterHeight ) { +#ifdef MAPBASE + render->Push3DView( *this, m_ClearFlags, GetRefractionTexture(), GetFrustum() ); +#else render->Push3DView( *this, m_ClearFlags, GetWaterRefractionTexture(), GetFrustum() ); - m_pMainView->PushGBufferRT(); +#endif Vector4D plane; VectorMultiply( m_ReflectionPlane.normal, -1, plane.AsVector3D() ); @@ -6907,8 +6974,19 @@ void CRefractiveGlassView::Draw() CMatRenderContextPtr pRenderContext( materials ); PIXEVENT( pRenderContext, "CRefractiveGlassView::Draw" ); +#ifdef MAPBASE + // Store off view origin and angles and set the new view + int nSaveViewID = CurrentViewID(); + SetupCurrentView( origin, angles, VIEW_REFRACTION ); +#endif + BaseClass::Draw(); +#ifdef MAPBASE + // finish off the view. restore the previous view. + SetupCurrentView( origin, angles, (view_id_t)nSaveViewID ); +#endif + pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); pRenderContext->Flush(); } diff --git a/game/client/viewrender.h b/game/client/viewrender.h index b1552ec5..3ba6cd9f 100644 --- a/game/client/viewrender.h +++ b/game/client/viewrender.h @@ -37,6 +37,10 @@ class CReplayScreenshotTaker; class CStunEffect; #endif // HL2_EPISODIC +#ifdef MAPBASE + class C_FuncFakeWorldPortal; +#endif + //----------------------------------------------------------------------------- // Data specific to intro mode to control rendering. //----------------------------------------------------------------------------- @@ -51,11 +55,22 @@ struct IntroData_t bool m_bDrawPrimary; Vector m_vecCameraView; QAngle m_vecCameraViewAngles; +#ifdef MAPBASE + // Used for ortho views + CHandle m_hCameraEntity; +#endif float m_playerViewFOV; CUtlVector m_Passes; // Fade overriding for the intro float m_flCurrentFadeColor[4]; + +#ifdef MAPBASE + // Draws the skybox. + bool m_bDrawSky; + // Draws the skybox in the secondary camera as well. + bool m_bDrawSky2; +#endif }; // Robin, make this point at something to get intro mode. @@ -78,7 +93,6 @@ enum view_id_t VIEW_INTRO_CAMERA = 6, VIEW_SHADOW_DEPTH_TEXTURE = 7, VIEW_SSAO = 8, - VIEW_VOLUMETRICS = 9, VIEW_ID_COUNT }; view_id_t CurrentViewID(); @@ -324,9 +338,6 @@ class CViewRender : public IViewRender, // Sets up the view parameters of map overview mode (cl_leveloverview) void SetUpOverView(); - void UpdateLighting(const CViewSetup& view); - void ProcessGlobals(const CViewSetup& view); - // generates a low-res screenshot for save games virtual void WriteSaveGameScreenshotOfSize( const char *pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false ); void WriteSaveGameScreenshot( const char *filename ); @@ -403,7 +414,7 @@ class CViewRender : public IViewRender, virtual C_BaseEntity *GetCurrentlyDrawingEntity(); virtual void SetCurrentlyDrawingEntity( C_BaseEntity *pEnt ); - virtual bool UpdateShadowDepthTexture(ITexture *pRenderTarget, ITexture *pDepthTexture, const CViewSetup &shadowView); + virtual bool UpdateShadowDepthTexture( ITexture *pRenderTarget, ITexture *pDepthTexture, const CViewSetup &shadowView ); int GetBaseDrawFlags() { return m_BaseDrawFlags; } virtual bool ShouldForceNoVis() { return m_bForceNoVis; } @@ -427,12 +438,6 @@ class CViewRender : public IViewRender, { m_UnderWaterOverlayMaterial.Init( pMaterial ); } - // Drawing primitives - bool ShouldDrawViewModel( bool drawViewmodel ); - void DrawViewModels( const CViewSetup &view, bool drawViewmodel ); - void DrawSky(const CViewSetup& view); - - void PushGBufferRT(bool firstPush = false); private: int m_BuildWorldListsNumber; @@ -446,6 +451,16 @@ class CViewRender : public IViewRender, bool DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_PointCamera *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, int x, int y, int width, int height ); +#ifdef MAPBASE + bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, + int x, int y, int width, int height, + const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, float flLocalPlaneDist ); +#endif + + // Drawing primitives + bool ShouldDrawViewModel( bool drawViewmodel ); + void DrawViewModels( const CViewSetup &view, bool drawViewmodel ); + void PerformScreenSpaceEffects( int x, int y, int w, int h ); // Overlays @@ -453,12 +468,23 @@ class CViewRender : public IViewRender, IMaterial *GetScreenOverlayMaterial( ); void PerformScreenOverlay( int x, int y, int w, int h ); +#ifdef MAPBASE + void SetIndexedScreenOverlayMaterial( int i, IMaterial *pMaterial ); + IMaterial *GetIndexedScreenOverlayMaterial( int i ); + void ResetIndexedScreenOverlays(); + int GetMaxIndexedScreenOverlays() const; +#endif + void DrawUnderwaterOverlay( void ); // Water-related methods void DrawWorldAndEntities( bool drawSkybox, const CViewSetup &view, int nClearFlags, ViewCustomVisibility_t *pCustomVisibility = NULL ); +#ifdef MAPBASE + virtual void ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, const IntroData_t &introData, bool bDrew3dSkybox = false, SkyboxVisibility_t nSkyboxVisible = SKYBOX_NOT_VISIBLE, bool bDrawViewModel = false, ViewCustomVisibility_t *pCustomVisibility = NULL ); +#else virtual void ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, const IntroData_t &introData ); +#endif #ifdef PORTAL // Intended for use in the middle of another ViewDrawScene call, this allows stencils to be drawn after opaques but before translucents are drawn in the main view. @@ -492,13 +518,11 @@ class CViewRender : public IViewRender, CMaterialReference m_TranslucentSingleColor; CMaterialReference m_ModulateSingleColor; CMaterialReference m_ScreenOverlayMaterial; - CMaterialReference m_UnderWaterOverlayMaterial; - CMaterialReference m_SkydomeMaterial; - - ITexture* m_DepthBuffer; - ITexture* m_NormalBuffer; - ITexture* m_MRAOBuffer; - ITexture* m_AlbedoBuffer; +#ifdef MAPBASE + CMaterialReference m_IndexedScreenOverlayMaterials[MAX_SCREEN_OVERLAYS]; + bool m_bUsingIndexedScreenOverlays; +#endif + CMaterialReference m_UnderWaterOverlayMaterial; Vector m_vecLastFacing; float m_flCheapWaterStartDistance; diff --git a/game/client/vscript_client.cpp b/game/client/vscript_client.cpp new file mode 100644 index 00000000..6c8c5371 --- /dev/null +++ b/game/client/vscript_client.cpp @@ -0,0 +1,787 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "vscript_client.h" +#include "icommandline.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "filesystem.h" +#include "characterset.h" +#include "isaverestore.h" +#include "gamerules.h" +#include "vscript_client.nut" +#ifdef MAPBASE_VSCRIPT +#include "view.h" +#include "c_world.h" +#include "proxyentity.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialvar.h" +#include "mapbase/matchers.h" +#include "mapbase/vscript_singletons.h" +#include "mapbase/vscript_vgui.h" +#endif + +extern IScriptManager *scriptmanager; +extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); + +// #define VMPROFILE 1 + +#ifdef VMPROFILE + +#define VMPROF_START float debugStartTime = Plat_FloatTime(); +#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 ); + +#else // !VMPROFILE + +#define VMPROF_START +#define VMPROF_SHOW + +#endif // VMPROFILE + +#ifdef MAPBASE_VSCRIPT +static ScriptHook_t g_Hook_OnEntityCreated; +static ScriptHook_t g_Hook_OnEntityDeleted; + +//----------------------------------------------------------------------------- +// Purpose: A clientside variant of CScriptEntityIterator. +//----------------------------------------------------------------------------- +class CScriptClientEntityIterator : public IClientEntityListener +{ +public: + HSCRIPT GetLocalPlayer() + { + return ToHScript( C_BasePlayer::GetLocalPlayer() ); + } + + HSCRIPT First() { return Next(NULL); } + + HSCRIPT Next( HSCRIPT hStartEntity ) + { + return ToHScript( ClientEntityList().NextBaseEntity( ToEnt( hStartEntity ) ) ); + } + + HSCRIPT CreateByClassname( const char *className ) + { + return ToHScript( CreateEntityByName( className ) ); + } + + HSCRIPT FindByClassname( HSCRIPT hStartEntity, const char *szName ) + { + const CEntInfo *pInfo = hStartEntity ? ClientEntityList().GetEntInfoPtr( ToEnt( hStartEntity )->GetRefEHandle() )->m_pNext : ClientEntityList().FirstEntInfo(); + for ( ;pInfo; pInfo = pInfo->m_pNext ) + { + C_BaseEntity *ent = (C_BaseEntity *)pInfo->m_pEntity; + if ( !ent ) + continue; + + if ( Matcher_Match( szName, ent->GetClassname() ) ) + return ToHScript( ent ); + } + + return NULL; + } + + HSCRIPT FindByName( HSCRIPT hStartEntity, const char *szName ) + { + const CEntInfo *pInfo = hStartEntity ? ClientEntityList().GetEntInfoPtr( ToEnt( hStartEntity )->GetRefEHandle() )->m_pNext : ClientEntityList().FirstEntInfo(); + for ( ;pInfo; pInfo = pInfo->m_pNext ) + { + C_BaseEntity *ent = (C_BaseEntity *)pInfo->m_pEntity; + if ( !ent ) + continue; + + if ( Matcher_Match( szName, ent->GetEntityName() ) ) + return ToHScript( ent ); + } + + return NULL; + } + + void EnableEntityListening() + { + // Start getting entity updates! + ClientEntityList().AddListenerEntity( this ); + } + + void DisableEntityListening() + { + // Stop getting entity updates! + ClientEntityList().RemoveListenerEntity( this ); + } + + void OnEntityCreated( CBaseEntity *pEntity ) + { + if ( g_pScriptVM && GetScriptHookManager().IsEventHooked( "OnEntityCreated" ) ) + { + // entity + ScriptVariant_t args[] = { ScriptVariant_t( pEntity->GetScriptInstance() ) }; + g_Hook_OnEntityCreated.Call( NULL, NULL, args ); + } + }; + + void OnEntityDeleted( CBaseEntity *pEntity ) + { + if ( g_pScriptVM && GetScriptHookManager().IsEventHooked( "OnEntityDeleted" ) ) + { + // entity + ScriptVariant_t args[] = { ScriptVariant_t( pEntity->GetScriptInstance() ) }; + g_Hook_OnEntityDeleted.Call( NULL, NULL, args ); + } + }; + +private: +} g_ScriptEntityIterator; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptClientEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" ) + DEFINE_SCRIPTFUNC( GetLocalPlayer, "Get local player" ) + DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" ) + DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" ) + DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" ) + DEFINE_SCRIPTFUNC( FindByClassname, "Find entities by class name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByName, "Find entities by name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + + DEFINE_SCRIPTFUNC( EnableEntityListening, "Enables the 'OnEntity' hooks. This function must be called before using them." ) + DEFINE_SCRIPTFUNC( DisableEntityListening, "Disables the 'OnEntity' hooks." ) + + BEGIN_SCRIPTHOOK( g_Hook_OnEntityCreated, "OnEntityCreated", FIELD_VOID, "Called when an entity is created. Requires EnableEntityListening() to be fired beforehand." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_OnEntityDeleted, "OnEntityDeleted", FIELD_VOID, "Called when an entity is deleted. Requires EnableEntityListening() to be fired beforehand." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- +// Purpose: A base class for VScript-utilizing clientside classes which can persist +// across levels, requiring their scripts to be shut down manually. +//----------------------------------------------------------------------------- +abstract_class IClientScriptPersistable +{ +public: + virtual void TermScript() = 0; +}; + +CUtlVector g_ScriptPersistableList; + +#define SCRIPT_MAT_PROXY_MAX_VARS 8 + +//----------------------------------------------------------------------------- +// Purpose: A material proxy which runs a VScript and allows it to read/write +// to material variables. +//----------------------------------------------------------------------------- +class CScriptMaterialProxy : public IMaterialProxy, public IClientScriptPersistable +{ +public: + CScriptMaterialProxy(); + virtual ~CScriptMaterialProxy(); + + virtual void Release( void ); + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + virtual void OnBind( void *pRenderable ); + virtual IMaterial *GetMaterial() { return NULL; } + + // Proxies can persist across levels and aren't bound to a loaded map. + // The VM, however, is bound to the loaded map, so the proxy's script variables persisting + // causes problems when they're used in a new level with a new VM. + // As a result, we call InitScript() and TermScript() during OnBind and when the level is unloaded respectively. + bool InitScript(); + void TermScript(); + + bool ValidateIndex(int i) + { + if (i > SCRIPT_MAT_PROXY_MAX_VARS || i < 0) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "VScriptProxy: %i out of range", i ); + return false; + } + + return true; + } + + const char *GetVarString( int i ); + int GetVarInt( int i ); + float GetVarFloat( int i ); + const Vector& GetVarVector( int i ); + + void SetVarString( int i, const char *value ); + void SetVarInt( int i, int value ); + void SetVarFloat( int i, float value ); + void SetVarVector( int i, const Vector &value ); + + const char *GetVarName( int i ); + +private: + IMaterialVar *m_MaterialVars[SCRIPT_MAT_PROXY_MAX_VARS]; + + // Save the keyvalue string for InitScript() + char m_szFilePath[MAX_PATH]; + + CScriptScope m_ScriptScope; + HSCRIPT m_hScriptInstance; + HSCRIPT m_hFuncOnBind; +}; + +class CMaterialProxyScriptInstanceHelper : public IScriptInstanceHelper +{ + bool ToString( void *p, char *pBuf, int bufSize ); + void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ); +}; + +CMaterialProxyScriptInstanceHelper g_MaterialProxyScriptInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMaterialProxy, "CScriptMaterialProxy", "Material proxy for VScript" ) + DEFINE_SCRIPT_INSTANCE_HELPER( &g_MaterialProxyScriptInstanceHelper ) + DEFINE_SCRIPTFUNC( GetVarString, "Gets a material var's string value" ) + DEFINE_SCRIPTFUNC( GetVarInt, "Gets a material var's int value" ) + DEFINE_SCRIPTFUNC( GetVarFloat, "Gets a material var's float value" ) + DEFINE_SCRIPTFUNC( GetVarVector, "Gets a material var's vector value" ) + DEFINE_SCRIPTFUNC( SetVarString, "Sets a material var's string value" ) + DEFINE_SCRIPTFUNC( SetVarInt, "Sets a material var's int value" ) + DEFINE_SCRIPTFUNC( SetVarFloat, "Sets a material var's float value" ) + DEFINE_SCRIPTFUNC( SetVarVector, "Sets a material var's vector value" ) + + DEFINE_SCRIPTFUNC( GetVarName, "Gets a material var's name" ) +END_SCRIPTDESC(); + +CScriptMaterialProxy::CScriptMaterialProxy() +{ + m_hScriptInstance = NULL; + m_hFuncOnBind = NULL; + + V_memset( m_MaterialVars, 0, sizeof(m_MaterialVars) ); +} + +CScriptMaterialProxy::~CScriptMaterialProxy() +{ +} + + +//----------------------------------------------------------------------------- +// Cleanup +//----------------------------------------------------------------------------- +void CScriptMaterialProxy::Release( void ) +{ + if ( m_hScriptInstance && g_pScriptVM ) + { + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + m_hScriptInstance = NULL; + } + + delete this; +} + +bool CScriptMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) +{ + for (KeyValues *pKey = pKeyValues->GetFirstSubKey(); pKey != NULL; pKey = pKey->GetNextKey()) + { + // Get each variable we're looking for + if (Q_strnicmp( pKey->GetName(), "var", 3 ) == 0) + { + int index = atoi(pKey->GetName() + 3); + if (index > SCRIPT_MAT_PROXY_MAX_VARS) + { + Warning("VScript material proxy only supports 8 vars (not %i)\n", index); + continue; + } + + bool foundVar; + m_MaterialVars[index] = pMaterial->FindVar( pKey->GetString(), &foundVar ); + + // Don't init if we didn't find the var + if (!foundVar) + return false; + } + else if (FStrEq( pKey->GetName(), "scriptfile" )) + { + Q_strncpy( m_szFilePath, pKey->GetString(), sizeof( m_szFilePath ) ); + } + } + + return true; +} + +bool CScriptMaterialProxy::InitScript() +{ + if (!m_ScriptScope.IsInitialized()) + { + if (scriptmanager == NULL) + { + ExecuteOnce(DevMsg("Cannot execute script because scripting is disabled (-scripting)\n")); + return false; + } + + if (g_pScriptVM == NULL) + { + ExecuteOnce(DevMsg(" Cannot execute script because there is no available VM\n")); + return false; + } + + char* iszScriptId = (char*)stackalloc( 1024 ); + g_pScriptVM->GenerateUniqueKey("VScriptProxy", iszScriptId, 1024); + + m_hScriptInstance = g_pScriptVM->RegisterInstance( GetScriptDescForClass( CScriptMaterialProxy ), this ); + g_pScriptVM->SetInstanceUniqeId( m_hScriptInstance, iszScriptId ); + + bool bResult = m_ScriptScope.Init( iszScriptId ); + + if (!bResult) + { + CGMsg( 1, CON_GROUP_VSCRIPT, "VScriptProxy couldn't create ScriptScope!\n" ); + return false; + } + + g_pScriptVM->SetValue( m_ScriptScope, "self", m_hScriptInstance ); + } + + // Don't init if we can't run the script + if (!VScriptRunScript( m_szFilePath, m_ScriptScope, true )) + return false; + + m_hFuncOnBind = m_ScriptScope.LookupFunction( "OnBind" ); + + if (!m_hFuncOnBind) + { + // Don't init if we can't find our func + Warning("VScript material proxy can't find OnBind function\n"); + return false; + } + + g_ScriptPersistableList.AddToTail( this ); + return true; +} + +void CScriptMaterialProxy::TermScript() +{ + if ( m_hScriptInstance ) + { + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + m_hScriptInstance = NULL; + } + + m_hFuncOnBind = NULL; + + m_ScriptScope.Term(); +} + +void CScriptMaterialProxy::OnBind( void *pRenderable ) +{ + if (m_hFuncOnBind != NULL) + { + C_BaseEntity *pEnt = NULL; + if (pRenderable) + { + IClientRenderable *pRend = (IClientRenderable*)pRenderable; + pEnt = pRend->GetIClientUnknown()->GetBaseEntity(); + if ( pEnt ) + { + g_pScriptVM->SetValue( m_ScriptScope, "entity", pEnt->GetScriptInstance() ); + } + } + + if (!pEnt) + { + g_pScriptVM->SetValue( m_ScriptScope, "entity", SCRIPT_VARIANT_NULL ); + } + + m_ScriptScope.Call( m_hFuncOnBind, NULL ); + } + else + { + // The VM might not exist if we do it from Init(), so we have to do it here. + // TODO: We have no handling for if this fails, how do you cancel a proxy? + if (InitScript()) + OnBind( pRenderable ); + } +} + +const char *CScriptMaterialProxy::GetVarString( int i ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return NULL; + + return m_MaterialVars[i]->GetStringValue(); +} + +int CScriptMaterialProxy::GetVarInt( int i ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return 0; + + return m_MaterialVars[i]->GetIntValue(); +} + +float CScriptMaterialProxy::GetVarFloat( int i ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return 0.0f; + + return m_MaterialVars[i]->GetFloatValue(); +} + +const Vector& CScriptMaterialProxy::GetVarVector( int i ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return vec3_origin; + + if (m_MaterialVars[i]->GetType() != MATERIAL_VAR_TYPE_VECTOR) + return vec3_origin; + + // This is really bad. Too bad! + return *(reinterpret_cast(m_MaterialVars[i]->GetVecValue())); +} + +void CScriptMaterialProxy::SetVarString( int i, const char *value ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return; + + return m_MaterialVars[i]->SetStringValue( value ); +} + +void CScriptMaterialProxy::SetVarInt( int i, int value ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return; + + return m_MaterialVars[i]->SetIntValue( value ); +} + +void CScriptMaterialProxy::SetVarFloat( int i, float value ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return; + + return m_MaterialVars[i]->SetFloatValue( value ); +} + +void CScriptMaterialProxy::SetVarVector( int i, const Vector &value ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return; + + return m_MaterialVars[i]->SetVecValue( value.Base(), 3 ); +} + +const char *CScriptMaterialProxy::GetVarName( int i ) +{ + if (!ValidateIndex( i ) || !m_MaterialVars[i]) + return NULL; + + return m_MaterialVars[i]->GetName(); +} + +EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION ); + +bool CMaterialProxyScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) +{ + CScriptMaterialProxy *pProxy = (CScriptMaterialProxy *)p; + V_snprintf( pBuf, bufSize, "(proxy: %s)", pProxy->GetMaterial() != NULL ? pProxy->GetMaterial()->GetName() : "" ); + return true; +} + +void *CMaterialProxyScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ) +{ + // TODO: Material proxy save/restore? + return NULL; +} +#endif // MAPBASE_VSCRIPT + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +static float Time() +{ + return gpGlobals->curtime; +} + +static const char *GetMapName() +{ + return engine->GetLevelName(); +} + +static const char *DoUniqueString( const char *pszBase ) +{ + static char szBuf[512]; + g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) ); + return szBuf; +} + +bool DoIncludeScript( const char *pszScript, HSCRIPT hScope ) +{ + if ( !VScriptRunScript( pszScript, hScope, true ) ) + { + g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) ); + return false; + } + return true; +} + +#ifdef MAPBASE_VSCRIPT +int ScriptScreenWidth(); +int ScriptScreenHeight(); + +static float FrameTime() +{ + return gpGlobals->frametime; +} + +static bool Con_IsVisible() +{ + return engine->Con_IsVisible(); +} + +static bool IsWindowedMode() +{ + return engine->IsWindowedMode(); +} + +// Creates a client-side prop +HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char *pszModelName, int iAnim ) +{ + C_BaseAnimating *pBaseEntity = (C_BaseAnimating *)CreateEntityByName( pszEntityName ); + if (!pBaseEntity) + return NULL; + + pBaseEntity->SetAbsOrigin( vOrigin ); + pBaseEntity->SetModelName( pszModelName ); + if (!pBaseEntity->InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY )) + { + Warning("Can't initialize %s as client entity\n", pszEntityName); + return NULL; + } + + pBaseEntity->SetPlaybackRate( 1.0f ); + + int iSequence = pBaseEntity->SelectWeightedSequence( (Activity)iAnim ); + + if ( iSequence != -1 ) + { + pBaseEntity->SetSequence( iSequence ); + } + + return ToHScript( pBaseEntity ); +} +#endif + +bool VScriptClientInit() +{ + VMPROF_START + + if( scriptmanager != NULL ) + { + ScriptLanguage_t scriptLanguage = SL_DEFAULT; + + char const *pszScriptLanguage; +#ifdef MAPBASE_VSCRIPT + if (GetClientWorldEntity()->GetScriptLanguage() != SL_NONE) + { + // Allow world entity to override script language + scriptLanguage = GetClientWorldEntity()->GetScriptLanguage(); + + // Less than SL_NONE means the script language should literally be none + if (scriptLanguage < SL_NONE) + scriptLanguage = SL_NONE; + } + else +#endif + if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) ) + { + if( !Q_stricmp(pszScriptLanguage, "gamemonkey") ) + { + scriptLanguage = SL_GAMEMONKEY; + } + else if( !Q_stricmp(pszScriptLanguage, "squirrel") ) + { + scriptLanguage = SL_SQUIRREL; + } + else if( !Q_stricmp(pszScriptLanguage, "python") ) + { + scriptLanguage = SL_PYTHON; + } +#ifdef MAPBASE_VSCRIPT + else if( !Q_stricmp(pszScriptLanguage, "lua") ) + { + scriptLanguage = SL_LUA; + } +#endif + else + { + CGWarning( 1, CON_GROUP_VSCRIPT, "-scriptlang does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage ); + scriptLanguage = SL_NONE; + } + + } + if( scriptLanguage != SL_NONE ) + { + if ( g_pScriptVM == NULL ) + g_pScriptVM = scriptmanager->CreateVM( scriptLanguage ); + + if( g_pScriptVM ) + { +#ifdef MAPBASE_VSCRIPT + CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#else + Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#endif + +#ifdef MAPBASE_VSCRIPT + GetScriptHookManager().OnInit(); +#endif + + ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map."); + ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" ); + ScriptRegisterFunction( g_pScriptVM, DoUniqueString, SCRIPT_ALIAS( "UniqueString", "Generate a string guaranteed to be unique across the life of the script VM, with an optional root string." ) ); + ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" ); +#ifdef MAPBASE_VSCRIPT + ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the client in the last frame" ); + ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenWidth, "ScreenWidth", "Width of the screen in pixels" ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenHeight, "ScreenHeight", "Height of the screen in pixels" ); + ScriptRegisterFunction( g_pScriptVM, IsWindowedMode, "" ); + + ScriptRegisterFunction( g_pScriptVM, MainViewOrigin, "" ); + ScriptRegisterFunction( g_pScriptVM, MainViewAngles, "" ); + ScriptRegisterFunction( g_pScriptVM, PrevMainViewOrigin, "" ); + ScriptRegisterFunction( g_pScriptVM, PrevMainViewAngles, "" ); + ScriptRegisterFunction( g_pScriptVM, MainViewForward, "" ); + ScriptRegisterFunction( g_pScriptVM, MainViewRight, "" ); + ScriptRegisterFunction( g_pScriptVM, MainViewUp, "" ); + + ScriptRegisterFunction( g_pScriptVM, CurrentViewOrigin, "" ); + ScriptRegisterFunction( g_pScriptVM, CurrentViewAngles, "" ); + ScriptRegisterFunction( g_pScriptVM, CurrentViewForward, "" ); + ScriptRegisterFunction( g_pScriptVM, CurrentViewRight, "" ); + ScriptRegisterFunction( g_pScriptVM, CurrentViewUp, "" ); + + ScriptRegisterFunction( g_pScriptVM, CreateProp, "Create an animating prop" ); +#endif + + + if ( GameRules() ) + { + GameRules()->RegisterScriptFunctions(); + } + +#ifdef MAPBASE_VSCRIPT + g_pScriptVM->RegisterAllClasses(); + g_pScriptVM->RegisterAllEnums(); + + g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" ); + + IGameSystem::RegisterVScriptAllSystems(); + + RegisterSharedScriptConstants(); + RegisterSharedScriptFunctions(); + RegisterScriptVGUI(); +#else + //g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" ); +#endif + + if (scriptLanguage == SL_SQUIRREL) + { + g_pScriptVM->Run( g_Script_vscript_client ); + } + + VScriptRunScript( "vscript_client", true ); + VScriptRunScript( "mapspawn", false ); + +#ifdef MAPBASE_VSCRIPT + RunAddonScripts(); +#endif + + VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" ); + + return true; + } + else + { + CGWarning( 1, CON_GROUP_VSCRIPT, "VM Did not start!\n" ); + } + } +#ifdef MAPBASE_VSCRIPT + else + { + CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Not starting because language is set to 'none'\n" ); + } +#endif + } + else + { + CGWarning( 0, CON_GROUP_VSCRIPT, "\nVSCRIPT: Scripting is disabled.\n" ); + } + g_pScriptVM = NULL; + return false; +} + +void VScriptClientTerm() +{ + if( g_pScriptVM != NULL ) + { +#ifdef MAPBASE_VSCRIPT + // Things like proxies can persist across levels, so we have to shut down their scripts manually + for (int i = g_ScriptPersistableList.Count()-1; i >= 0; i--) + { + if (g_ScriptPersistableList[i]) + { + g_ScriptPersistableList[i]->TermScript(); + g_ScriptPersistableList.FastRemove( i ); + } + } +#endif + + if( g_pScriptVM ) + { + scriptmanager->DestroyVM( g_pScriptVM ); + g_pScriptVM = NULL; + } + } +} + + +class CVScriptGameSystem : public CAutoGameSystemPerFrame +{ +public: + // Inherited from IAutoServerSystem + virtual void LevelInitPreEntity( void ) + { + m_bAllowEntityCreationInScripts = true; + VScriptClientInit(); + } + + virtual void LevelInitPostEntity( void ) + { + m_bAllowEntityCreationInScripts = false; + } + + virtual void LevelShutdownPostEntity( void ) + { +#ifdef MAPBASE_VSCRIPT + g_ScriptNetMsg->LevelShutdownPreVM(); + + GetScriptHookManager().OnShutdown(); +#endif + VScriptClientTerm(); + } + + virtual void FrameUpdatePostEntityThink() + { + if ( g_pScriptVM ) + g_pScriptVM->Frame( gpGlobals->frametime ); + } + + bool m_bAllowEntityCreationInScripts; +}; + +CVScriptGameSystem g_VScriptGameSystem; + +bool IsEntityCreationAllowedInScripts( void ) +{ + return g_VScriptGameSystem.m_bAllowEntityCreationInScripts; +} + + diff --git a/game/client/vscript_client.h b/game/client/vscript_client.h new file mode 100644 index 00000000..9b69563e --- /dev/null +++ b/game/client/vscript_client.h @@ -0,0 +1,26 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_CLIENT_H +#define VSCRIPT_CLIENT_H + +#include "vscript/ivscript.h" +#include "vscript_shared.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +extern IScriptVM * g_pScriptVM; + +// Only allow scripts to create entities during map initialization +bool IsEntityCreationAllowedInScripts( void ); + +#ifdef MAPBASE_VSCRIPT +extern IScriptManager * scriptmanager; +#endif + +#endif // VSCRIPT_CLIENT_H diff --git a/game/client/vscript_client.nut b/game/client/vscript_client.nut new file mode 100644 index 00000000..7b4f2810 --- /dev/null +++ b/game/client/vscript_client.nut @@ -0,0 +1,36 @@ +static char g_Script_vscript_client[] = R"vscript( +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +local DoUniqueString = DoUniqueString +local DoDispatchParticleEffect = DoDispatchParticleEffect + +function UniqueString( string = "" ) +{ + return DoUniqueString( "" + string ); +} + +function IncludeScript( name, scope = null ) +{ + if ( !scope ) + { + scope = this; + } + return ::DoIncludeScript( name, scope ); +} + +function DispatchParticleEffect( particleName, origin, angles, entity = null ) +{ + return DoDispatchParticleEffect( particleName, origin, angles, entity ); +} + +function ImpulseScale( flTargetMass, flDesiredSpeed ) +{ + return flTargetMass * flDesiredSpeed; +} +__Documentation.RegisterHelp( "ImpulseScale", "float ImpulseScale(float, float)", "Returns an impulse scale required to push an object." ); + +)vscript"; \ No newline at end of file diff --git a/game/client/weapon_selection.cpp b/game/client/weapon_selection.cpp index dc2adf4e..5568c532 100644 --- a/game/client/weapon_selection.cpp +++ b/game/client/weapon_selection.cpp @@ -101,7 +101,6 @@ void CBaseHudWeaponSelection::Reset(void) // Start hidden m_bSelectionVisible = false; m_flSelectionTime = gpGlobals->curtime; - gHUD.UnlockRenderGroup( gHUD.LookupRenderGroupIndexByName( "weapon_selection" ) ); } //----------------------------------------------------------------------------- @@ -208,7 +207,6 @@ bool CBaseHudWeaponSelection::IsInSelectionMode() void CBaseHudWeaponSelection::OpenSelection( void ) { m_bSelectionVisible = true; - gHUD.LockRenderGroup( gHUD.LookupRenderGroupIndexByName( "weapon_selection" ) ); } //----------------------------------------------------------------------------- @@ -217,7 +215,6 @@ void CBaseHudWeaponSelection::OpenSelection( void ) void CBaseHudWeaponSelection::HideSelection( void ) { m_bSelectionVisible = false; - gHUD.UnlockRenderGroup( gHUD.LookupRenderGroupIndexByName( "weapon_selection" ) ); } //----------------------------------------------------------------------------- @@ -252,9 +249,14 @@ int CBaseHudWeaponSelection::KeyInput( int down, ButtonCode_t keynum, const char return 0; } - if ( down >= 1 && keynum >= KEY_1 && keynum <= KEY_9 ) + //Tony; check 0 as well, otherwise you have to have 0 bound to slot10 no matter what. + if ( down >= 1 && keynum >= KEY_0 && keynum <= KEY_9 ) { - if ( HandleHudMenuInput( keynum - KEY_0 ) ) + //Tony; 0 is actually '10' (slot10) + if (keynum == KEY_0) + keynum = KEY_A; //Dealing with button codes, so just use KEY_A, which is equal to 11 anyway. + + if ( HandleHudMenuInput( keynum - 1 ) ) return 0; } diff --git a/game/gamepadui/gamepadui_achievements.cpp b/game/gamepadui/gamepadui_achievements.cpp index fa26ce6c..4ec0da5f 100644 --- a/game/gamepadui/gamepadui_achievements.cpp +++ b/game/gamepadui/gamepadui_achievements.cpp @@ -130,7 +130,7 @@ class GamepadUIAchievement : public GamepadUIButton m_nCount = m_nGoal; } else - m_flProgress = min( float( nCount ) / float( nGoal ), 1.0f ); + m_flProgress = MIN( float( nCount ) / float( nGoal ), 1.0f ); } private: diff --git a/game/gamepadui/gamepadui_base.vpc b/game/gamepadui/gamepadui_base.vpc index fe8066ed..9c2cf9e7 100644 --- a/game/gamepadui/gamepadui_base.vpc +++ b/game/gamepadui/gamepadui_base.vpc @@ -36,6 +36,7 @@ $Configuration $Compiler { $AdditionalIncludeDirectories "$BASE;.\;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\gamepadui;..\..\public" + $AdditionalIncludeDirectories "$BASE;$SRCDIR\thirdparty\SDL\include\SDL" [$LINUX] $PreprocessorDefinitions "$BASE;GAMEPADUI_DLL;VERSION_SAFE_STEAM_API_INTERFACES;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead" } diff --git a/game/gamepadui/gamepadui_vance.vpc b/game/gamepadui/gamepadui_vance.vpc index bf4140b2..d5cb64f2 100644 --- a/game/gamepadui/gamepadui_vance.vpc +++ b/game/gamepadui/gamepadui_vance.vpc @@ -5,7 +5,7 @@ //----------------------------------------------------------------------------- $Macro SRCDIR "..\.." -$Macro GAMENAME "VANCE" +$Macro GAMENAME "vance" $Macro OUTBINNAME "gamepadui" $Include "$SRCDIR\game\gamepadui\gamepadui_base.vpc" @@ -18,6 +18,6 @@ $Configuration } } -$Project "GamepadUI (VANCE)" +$Project "GamepadUI (Vance)" { } \ No newline at end of file diff --git a/game/server/AI_Criteria.cpp b/game/server/AI_Criteria.cpp index 128e9d32..d0b25e8a 100644 --- a/game/server/AI_Criteria.cpp +++ b/game/server/AI_Criteria.cpp @@ -27,8 +27,13 @@ AI_CriteriaSet::AI_CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ) //----------------------------------------------------------------------------- AI_CriteriaSet::AI_CriteriaSet( const AI_CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ) { - // Use fast Copy CUtlRBTree CopyFrom. WARNING: It only handles POD. - m_Lookup.CopyFrom( src.m_Lookup ); + m_Lookup.Purge(); + for ( short i = src.m_Lookup.FirstInorder(); + i != src.m_Lookup.InvalidIndex(); + i = src.m_Lookup.NextInorder( i ) ) + { + m_Lookup.Insert( src.m_Lookup[ i ] ); + } } //----------------------------------------------------------------------------- @@ -157,6 +162,7 @@ void AI_CriteriaSet::Describe() { for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) { + CritEntry_t *entry = &m_Lookup[ i ]; if ( entry->weight != 1.0f ) @@ -170,6 +176,22 @@ void AI_CriteriaSet::Describe() } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Merges another AI_CriteriaSet without clearing +// Input : src - +//----------------------------------------------------------------------------- +void AI_CriteriaSet::MergeSet( const AI_CriteriaSet& src ) +{ + for ( short i = src.m_Lookup.FirstInorder(); + i != src.m_Lookup.InvalidIndex(); + i = src.m_Lookup.NextInorder( i ) ) + { + m_Lookup.Insert( src.m_Lookup[ i ] ); + } +} +#endif + BEGIN_SIMPLE_DATADESC( AI_ResponseParams ) DEFINE_FIELD( flags, FIELD_SHORT ), DEFINE_FIELD( odds, FIELD_SHORT ), @@ -193,18 +215,31 @@ AI_Response::AI_Response() { m_Type = RESPONSE_NONE; m_szResponseName[0] = 0; - m_szMatchingRule[0] = 0; - m_pCriteria = NULL; + m_szMatchingRule[0]=0; + m_szContext = NULL; +#ifdef MAPBASE + m_iContextFlags = 0; +#else m_bApplyContextToWorld = false; +#endif } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- AI_Response::AI_Response( const AI_Response &from ) { + Assert( (void*)(&m_Type) == (void*)this ); + m_pCriteria = NULL; + memcpy( this, &from, sizeof(*this) ); m_pCriteria = NULL; - *this = from; + m_szContext = NULL; + SetContext( from.m_szContext ); +#ifdef MAPBASE + m_iContextFlags = from.m_iContextFlags; +#else + m_bApplyContextToWorld = from.m_bApplyContextToWorld; +#endif } //----------------------------------------------------------------------------- @@ -213,34 +248,24 @@ AI_Response::AI_Response( const AI_Response &from ) AI_Response::~AI_Response() { delete m_pCriteria; - m_pCriteria = NULL; + delete[] m_szContext; } //----------------------------------------------------------------------------- AI_Response &AI_Response::operator=( const AI_Response &from ) { Assert( (void*)(&m_Type) == (void*)this ); - - if (this == &from) - return *this; - - m_Type = from.m_Type; - - V_strcpy_safe( m_szResponseName, from.m_szResponseName ); - V_strcpy_safe( m_szMatchingRule, from.m_szMatchingRule ); - delete m_pCriteria; m_pCriteria = NULL; - - // Copy criteria. - if (from.m_pCriteria) - m_pCriteria = new AI_CriteriaSet(*from.m_pCriteria); - - m_Params = from.m_Params; - - m_szContext = from.m_szContext; + memcpy( this, &from, sizeof(*this) ); + m_pCriteria = NULL; + m_szContext = NULL; + SetContext( from.m_szContext ); +#ifdef MAPBASE + m_iContextFlags = from.m_iContextFlags; +#else m_bApplyContextToWorld = from.m_bApplyContextToWorld; - +#endif return *this; } @@ -249,24 +274,40 @@ AI_Response &AI_Response::operator=( const AI_Response &from ) // Input : *response - // *criteria - //----------------------------------------------------------------------------- -void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, - const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, - bool bApplyContextToWorld ) +void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, bool bApplyContextToWorld ) { m_Type = type; - - V_strcpy_safe( m_szResponseName, responseName ); - V_strcpy_safe( m_szMatchingRule, ruleName ? ruleName : "NULL" ); - + Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); // Copy underlying criteria - Assert( !m_pCriteria ); m_pCriteria = new AI_CriteriaSet( criteria ); - + Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); m_Params = responseparams; - - m_szContext = applyContext; + SetContext( applyContext ); +#ifdef MAPBASE + bApplyContextToWorld ? m_iContextFlags = APPLYCONTEXT_WORLD : m_iContextFlags = 0; +#else m_bApplyContextToWorld = bApplyContextToWorld; +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : *response - +// *criteria - +//----------------------------------------------------------------------------- +void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, int iContextFlags ) +{ + m_Type = type; + Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); + // Copy underlying criteria + m_pCriteria = new AI_CriteriaSet( criteria ); + Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); + m_Params = responseparams; + SetContext( applyContext ); + m_iContextFlags = iContextFlags; } +#endif //----------------------------------------------------------------------------- // Purpose: @@ -279,29 +320,47 @@ void AI_Response::Describe() m_pCriteria->Describe(); } if ( m_szMatchingRule[ 0 ] ) + { DevMsg( "Matched rule '%s', ", m_szMatchingRule ); - if ( m_szContext.Length() ) - DevMsg( "Contexts to set '%s' on %s, ", m_szContext.Get(), m_bApplyContextToWorld ? "world" : "speaker" ); + } + if ( m_szContext ) + { +#ifdef MAPBASE + DevMsg( "Contexts to set '%s' on ", m_szContext ); + if (m_iContextFlags & APPLYCONTEXT_WORLD) + DevMsg("world, "); + else if (m_iContextFlags & APPLYCONTEXT_SQUAD) + DevMsg("squad, "); + else if (m_iContextFlags & APPLYCONTEXT_ENEMY) + DevMsg("enemy, "); + else + DevMsg("speaker, "); +#else + DevMsg( "Contexts to set '%s' on %s, ", m_szContext, m_bApplyContextToWorld ? "world" : "speaker" ); +#endif + } - DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); + DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); } //----------------------------------------------------------------------------- // Purpose: +// Output : char const //----------------------------------------------------------------------------- -const char * AI_Response::GetNamePtr() const +void AI_Response::GetName( char *buf, size_t buflen ) const { - return m_szResponseName; + Q_strncpy( buf, m_szResponseName, buflen ); } + //----------------------------------------------------------------------------- // Purpose: +// Output : char const //----------------------------------------------------------------------------- -const char * AI_Response::GetResponsePtr() const +void AI_Response::GetResponse( char *buf, size_t buflen ) const { - return m_szResponseName; + GetName( buf, buflen ); } - //----------------------------------------------------------------------------- // Purpose: // Input : type - @@ -317,15 +376,25 @@ const char *AI_Response::DescribeResponse( ResponseType_t type ) switch( type ) { - case RESPONSE_NONE: return "RESPONSE_NONE"; - case RESPONSE_SPEAK: return "RESPONSE_SPEAK"; - case RESPONSE_SENTENCE: return "RESPONSE_SENTENCE"; - case RESPONSE_SCENE: return "RESPONSE_SCENE"; - case RESPONSE_RESPONSE: return "RESPONSE_RESPONSE"; - case RESPONSE_PRINT: return "RESPONSE_PRINT"; + default: + { + Assert( 0 ); + } + // Fall through + case RESPONSE_NONE: + return "RESPONSE_NONE"; + case RESPONSE_SPEAK: + return "RESPONSE_SPEAK"; + case RESPONSE_SENTENCE: + return "RESPONSE_SENTENCE"; + case RESPONSE_SCENE: + return "RESPONSE_SCENE"; + case RESPONSE_RESPONSE: + return "RESPONSE_RESPONSE"; + case RESPONSE_PRINT: + return "RESPONSE_PRINT"; } - Assert( 0 ); return "RESPONSE_NONE"; } @@ -441,7 +510,16 @@ float AI_Response::GetPreDelay() const //----------------------------------------------------------------------------- void AI_Response::SetContext( const char *context ) { - m_szContext = context; + delete[] m_szContext; + m_szContext = NULL; + + if ( context ) + { + int len = Q_strlen( context ); + m_szContext = new char[ len + 1 ]; + Q_memcpy( m_szContext, context, len ); + m_szContext[ len ] = 0; + } } //----------------------------------------------------------------------------- diff --git a/game/server/AI_Criteria.h b/game/server/AI_Criteria.h index f10c2d05..53277858 100644 --- a/game/server/AI_Criteria.h +++ b/game/server/AI_Criteria.h @@ -4,6 +4,9 @@ // //=============================================================================// +#ifdef NEW_RESPONSE_SYSTEM +#include "ai_criteria_new.h" +#else #ifndef AI_CRITERIA_H #define AI_CRITERIA_H #ifdef _WIN32 @@ -37,6 +40,10 @@ class AI_CriteriaSet const char *GetValue( int index ) const; float GetWeight( int index ) const; +#ifdef MAPBASE + void MergeSet( const AI_CriteriaSet& src ); +#endif + private: struct CritEntry_t @@ -84,10 +91,8 @@ class AI_CriteriaSet Q_strncpy( value, str, sizeof( value ) ); } } - - // We use CUtlRBTree CopyFrom() in ctor, so CritEntry_t must be POD. If you add - // CUtlString or something then you must change AI_CriteriaSet copy ctor. - CUtlSymbol criterianame; + + CUtlSymbol criterianame; char value[ 64 ]; float weight; }; @@ -170,6 +175,24 @@ enum ResponseType_t NUM_RESPONSES, }; +#ifdef MAPBASE +// I wanted to add more options to apply contexts to, +// so I replaced the existing system with a flag-based integer instead of a bunch of booleans. +// +// New ones should be implemented in: +// CResponseSystem::ParseRule() - AI_ResponseSystem.cpp +// AI_Response::Describe() - AI_Criteria.cpp +// CAI_Expresser::SpeakDispatchResponse() - ai_speech.cpp +enum +{ + APPLYCONTEXT_SELF = (1 << 0), // Included for contexts that apply to both self and something else + APPLYCONTEXT_WORLD = (1 << 1), // Apply to world + + APPLYCONTEXT_SQUAD = (1 << 2), // Apply to squad + APPLYCONTEXT_ENEMY = (1 << 3), // Apply to enemy +}; +#endif + class AI_Response { public: @@ -180,10 +203,10 @@ class AI_Response ~AI_Response(); AI_Response &operator=( const AI_Response &from ); - void Release(); + void Release(); - const char * GetNamePtr() const; - const char * GetResponsePtr() const; + void GetName( char *buf, size_t buflen ) const; + void GetResponse( char *buf, size_t buflen ) const; const AI_ResponseParams *GetParams() const { return &m_Params; } ResponseType_t GetType() const { return (ResponseType_t)m_Type; } soundlevel_t GetSoundLevel() const; @@ -197,9 +220,14 @@ class AI_Response float GetPreDelay() const; void SetContext( const char *context ); - const char * GetContext( void ) const { return m_szContext.Length() ? m_szContext.Get() : NULL; } + const char * GetContext( void ) const { return m_szContext; } +#ifdef MAPBASE + int GetContextFlags() { return m_iContextFlags; } + bool IsApplyContextToWorld( void ) { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } +#else bool IsApplyContextToWorld( void ) { return m_bApplyContextToWorld; } +#endif void Describe(); @@ -213,6 +241,16 @@ class AI_Response const char *applyContext, bool bApplyContextToWorld ); +#ifdef MAPBASE + void Init( ResponseType_t type, + const char *responseName, + const AI_CriteriaSet& criteria, + const AI_ResponseParams& responseparams, + const char *matchingRule, + const char *applyContext, + int iContextFlags ); +#endif + static const char *DescribeResponse( ResponseType_t type ); enum @@ -232,8 +270,13 @@ class AI_Response AI_ResponseParams m_Params; - CUtlString m_szContext; + char * m_szContext; +#ifdef MAPBASE + int m_iContextFlags; +#else bool m_bApplyContextToWorld; +#endif }; #endif // AI_CRITERIA_H +#endif diff --git a/game/server/AI_ResponseSystem.cpp b/game/server/AI_ResponseSystem.cpp index 510a1d4e..a46ddb36 100644 --- a/game/server/AI_ResponseSystem.cpp +++ b/game/server/AI_ResponseSystem.cpp @@ -22,6 +22,9 @@ #include "stringpool.h" #include "fmtstr.h" #include "multiplay_gamerules.h" +#ifdef MAPBASE +#include "mapbase/matchers.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -30,6 +33,10 @@ ConVar rr_debugresponses( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose ma ConVar rr_debugrule( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); ConVar rr_dumpresponses( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +#ifdef MAPBASE +ConVar rr_enhanced_saverestore( "rr_enhanced_saverestore", "0", FCVAR_NONE, "Enables enhanced save/restore capabilities for the Response System." ); +#endif + static CUtlSymbolTable g_RS; inline static char *CopyString( const char *in ) @@ -57,6 +64,9 @@ class Matcher minequals = false; usemax = false; maxequals = false; +#ifdef MAPBASE + isbit = false; +#endif maxval = 0.0f; minval = 0.0f; @@ -99,6 +109,14 @@ class Matcher return; } +#ifdef MAPBASE + if (isbit) + { + DevMsg( " matcher: &%s%s\n", notequal ? "~" : "", GetToken() ); + return; + } +#endif + if ( notequal ) { DevMsg( " matcher: !=%s\n", GetToken() ); @@ -118,6 +136,9 @@ class Matcher bool minequals : 1; //5 bool usemax : 1; //6 bool maxequals : 1; //7 +#ifdef MAPBASE + bool isbit : 1; //8 +#endif void SetToken( char const *s ) { @@ -461,7 +482,11 @@ struct Rule m_bMatchOnce = false; m_bEnabled = true; m_szContext = NULL; +#ifdef MAPBASE + m_iContextFlags = 0; +#else m_bApplyContextToWorld = false; +#endif } Rule& operator =( const Rule& src ) @@ -487,7 +512,11 @@ struct Rule SetContext( src.m_szContext ); m_bMatchOnce = src.m_bMatchOnce; m_bEnabled = src.m_bEnabled; +#ifdef MAPBASE + m_iContextFlags = src.m_iContextFlags; +#else m_bApplyContextToWorld = src.m_bApplyContextToWorld; +#endif return *this; } @@ -511,7 +540,11 @@ struct Rule SetContext( src.m_szContext ); m_bMatchOnce = src.m_bMatchOnce; m_bEnabled = src.m_bEnabled; +#ifdef MAPBASE + m_iContextFlags = src.m_iContextFlags; +#else m_bApplyContextToWorld = src.m_bApplyContextToWorld; +#endif } ~Rule() @@ -530,14 +563,22 @@ struct Rule bool IsEnabled() const { return m_bEnabled; } void Disable() { m_bEnabled = false; } bool IsMatchOnce() const { return m_bMatchOnce; } +#ifdef MAPBASE + bool IsApplyContextToWorld() const { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } +#else bool IsApplyContextToWorld() const { return m_bApplyContextToWorld; } +#endif // Indices into underlying criteria and response dictionaries CUtlVector< unsigned short > m_Criteria; CUtlVector< unsigned short> m_Responses; char *m_szContext; +#ifdef MAPBASE + int m_iContextFlags; +#else bool m_bApplyContextToWorld : 1; +#endif bool m_bMatchOnce : 1; bool m_bEnabled : 1; @@ -668,7 +709,11 @@ abstract_class CResponseSystem : public IResponseSystem void ParseOneResponse( const char *responseGroupName, ResponseGroup& group ); +#ifdef MAPBASE + void ParseInclude( CStringPool &includedFiles, const char *scriptfile = NULL ); +#else void ParseInclude( CStringPool &includedFiles ); +#endif void ParseResponse( void ); void ParseCriterion( void ); void ParseRule( void ); @@ -865,6 +910,7 @@ void CResponseSystem::ResolveToken( Matcher& matcher, char *token, size_t bufsiz } +#ifndef MAPBASE // Moved to matchers.h static bool AppearsToBeANumber( char const *token ) { if ( atof( token ) != 0.0f ) @@ -881,6 +927,7 @@ static bool AppearsToBeANumber( char const *token ) return true; } +#endif void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) { @@ -905,6 +952,9 @@ void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) bool lt = false; bool eq = false; bool nt = false; +#ifdef MAPBASE + bool bit = false; +#endif bool done = false; while ( !done ) @@ -937,6 +987,17 @@ void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) // Convert raw token to real token in case token is an enumerated type specifier ResolveToken( matcher, token, sizeof( token ), rawtoken ); +#ifdef MAPBASE + // Bits are an entirely different and independent story + if (bit) + { + matcher.isbit = true; + matcher.notequal = nt; + + matcher.isnumeric = true; + } + else +#endif // Fill in first data set if ( gt ) { @@ -978,6 +1039,13 @@ void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) case '!': nt = true; break; +#ifdef MAPBASE + case '~': + nt = true; + case '&': + bit = true; + break; +#endif default: rawtoken[ n++ ] = *in; break; @@ -1002,6 +1070,19 @@ bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, boo bool found = false; v = LookupEnumeration( setValue, found ); } + +#ifdef MAPBASE + // Bits are always a different story + if (m.isbit) + { + int v1 = v; + int v2 = atoi(m.GetToken()); + if (m.notequal) + return (v1 & v2) == 0; + else + return (v1 & v2) != 0; + } +#endif int minmaxcount = 0; @@ -1052,7 +1133,11 @@ bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, boo } else { +#ifdef MAPBASE + if ( Matcher_NamesMatch(m.GetToken(), setValue) ) +#else if ( !Q_stricmp( setValue, m.GetToken() ) ) +#endif return false; } @@ -1069,7 +1154,12 @@ bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, boo return v == (float)atof( m.GetToken() ); } +#ifdef MAPBASE + // Wildcards. + return Matcher_NamesMatch(m.GetToken(), setValue) ? true : false; +#else return !Q_stricmp( setValue, m.GetToken() ) ? true : false; +#endif } bool CResponseSystem::Compare( const char *setValue, Criteria *c, bool verbose /*= false*/ ) @@ -1745,11 +1835,19 @@ bool CResponseSystem::FindBestResponse( const AI_CriteriaSet& set, AI_Response& char ruleName[ 128 ]; char responseName[ 128 ]; const char *context; +#ifdef MAPBASE + int contextflags; +#else bool bcontexttoworld; +#endif ruleName[ 0 ] = 0; responseName[ 0 ] = 0; context = NULL; +#ifdef MAPBASE + contextflags = 0; +#else bcontexttoworld = false; +#endif if ( bestRule != -1 ) { Rule *r = &m_Rules[ bestRule ]; @@ -1770,12 +1868,20 @@ bool CResponseSystem::FindBestResponse( const AI_CriteriaSet& set, AI_Response& r->Disable(); } context = r->GetContext(); +#ifdef MAPBASE + contextflags = r->m_iContextFlags; +#else bcontexttoworld = r->IsApplyContextToWorld(); +#endif valid = true; } +#ifdef MAPBASE + response.Init( responseType, responseName, set, rp, ruleName, context, contextflags ); +#else response.Init( responseType, responseName, set, rp, ruleName, context, bcontexttoworld ); +#endif if ( showResult ) { @@ -1894,11 +2000,43 @@ void CResponseSystem::Precache() } } +#ifdef MAPBASE +void CResponseSystem::ParseInclude( CStringPool &includedFiles, const char *scriptfile ) +#else void CResponseSystem::ParseInclude( CStringPool &includedFiles ) +#endif { char includefile[ 256 ]; ParseToken(); +#ifdef MAPBASE + if (scriptfile) + { + // Gets first path + // (for example, an #include from a file in resource/script/resp will return resource) + size_t len = strlen(scriptfile)-1; + for (size_t i = 0; i < len; i++) + { + if (scriptfile[i] == CORRECT_PATH_SEPARATOR || scriptfile[i] == INCORRECT_PATH_SEPARATOR) + { + len = i; + } + } + Q_strncpy(includefile, scriptfile, len+1); + + if (len+1 != strlen(scriptfile)) + { + Q_strncat( includefile, "/", sizeof( includefile ) ); + Q_strncat( includefile, token, sizeof( includefile ) ); + } + else + includefile[0] = '\0'; + } + + if (!includefile[0]) + Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); +#else Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); +#endif // check if the file is already included if ( includedFiles.Find( includefile ) != NULL ) @@ -1939,8 +2077,19 @@ void CResponseSystem::LoadFromBuffer( const char *scriptfile, const char *buffer if ( !Q_stricmp( token, "#include" ) ) { +#ifdef MAPBASE + ParseInclude( includedFiles, scriptfile ); +#else ParseInclude( includedFiles ); +#endif } +#ifdef MAPBASE + else if ( !Q_stricmp( token, "#base" ) ) + { + // Actual #base in the future? + ParseInclude( includedFiles, scriptfile ); + } +#endif else if ( !Q_stricmp( token, "response" ) ) { ParseResponse(); @@ -2324,6 +2473,16 @@ void CResponseSystem::ParseResponse( void ) ParseOneResponse( responseGroupName, newGroup ); } +#ifdef MAPBASE + short existing = m_Responses.Find( responseGroupName ); + if ( existing != m_Responses.InvalidIndex() ) + { + //ResponseWarning( "Additional definition for response '%s', overwriting\n", responseGroupName ); + m_Responses[existing] = newGroup; + m_Responses.SetElementName(existing, responseGroupName); + return; + } +#endif m_Responses.Insert( responseGroupName, newGroup ); } @@ -2405,11 +2564,22 @@ int CResponseSystem::ParseOneCriterion( const char *criterionName ) ComputeMatcher( &newCriterion, newCriterion.matcher ); } +#ifdef MAPBASE + short existing = m_Criteria.Find( criterionName ); + if ( existing != m_Criteria.InvalidIndex() ) + { + //ResponseWarning( "Additional definition for criteria '%s', overwriting\n", criterionName ); + m_Criteria[existing] = newCriterion; + m_Criteria.SetElementName(existing, criterionName); + return existing; + } +#else if ( m_Criteria.Find( criterionName ) != m_Criteria.InvalidIndex() ) { ResponseWarning( "Multiple definitions for criteria '%s'\n", criterionName ); return m_Criteria.InvalidIndex(); } +#endif int idx = m_Criteria.Insert( criterionName, newCriterion ); return idx; @@ -2475,12 +2645,22 @@ void CResponseSystem::ParseEnumeration( void ) { m_Enumerations.Insert( sz, newEnum ); } +#ifdef MAPBASE + else + { + short existing = m_Enumerations.Find( sz ); + //ResponseWarning( "Additional definition for enumeration '%s', overwriting\n", sz ); + m_Enumerations[existing] = newEnum; + m_Enumerations.SetElementName(existing, sz); + } +#else /* else { ResponseWarning( "Ignoring duplication enumeration '%s'\n", sz ); } */ +#endif } } @@ -2531,10 +2711,28 @@ void CResponseSystem::ParseRule( void ) if ( !Q_stricmp( token, "applyContextToWorld" ) ) { +#ifdef MAPBASE + newRule.m_iContextFlags |= APPLYCONTEXT_WORLD; +#else newRule.m_bApplyContextToWorld = true; +#endif + continue; + } + +#ifdef MAPBASE + if ( !Q_stricmp( token, "applyContextToSquad" ) ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_SQUAD; continue; } + if ( !Q_stricmp( token, "applyContextToEnemy" ) ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_ENEMY; + continue; + } +#endif + if ( !Q_stricmp( token, "applyContext" ) ) { ParseToken(); @@ -2606,6 +2804,16 @@ void CResponseSystem::ParseRule( void ) if ( validRule ) { +#ifdef MAPBASE + short existing = m_Rules.Find( ruleName ); + if ( existing != m_Rules.InvalidIndex() ) + { + //ResponseWarning( "Additional definition for rule '%s', overwriting\n", ruleName ); + m_Rules[existing] = newRule; + m_Rules.SetElementName(existing, ruleName); + return; + } +#endif m_Rules.Insert( ruleName, newRule ); } else @@ -2791,7 +2999,11 @@ void CResponseSystem::CopyRuleFrom( Rule *pSrcRule, int iRule, CResponseSystem * dstRule.SetContext( pSrcRule->GetContext() ); dstRule.m_bMatchOnce = pSrcRule->m_bMatchOnce; dstRule.m_bEnabled = pSrcRule->m_bEnabled; +#ifdef MAPBASE + dstRule.m_iContextFlags = pSrcRule->m_iContextFlags; +#else dstRule.m_bApplyContextToWorld = pSrcRule->m_bApplyContextToWorld; +#endif // Copy off criteria. CopyCriteriaFrom( pSrcRule, &dstRule, pCustomSystem ); @@ -2806,6 +3018,10 @@ void CResponseSystem::CopyRuleFrom( Rule *pSrcRule, int iRule, CResponseSystem * pCustomSystem->m_Rules.Insert( m_Rules.GetElementName( iRule ), dstRule ); } +#ifdef MAPBASE +ConVar mapbase_rs_clear("mapbase_rs_clear", "1"); +#endif + //----------------------------------------------------------------------------- // Purpose: A special purpose response system associated with a custom entity //----------------------------------------------------------------------------- @@ -2853,6 +3069,32 @@ class CInstancedResponseSystem : public CResponseSystem Clear(); delete this; } + +#ifdef MAPBASE + // From an old version of Mapbase's map-specific response system stuff. + /* + #define CopyRSDict(dict) for (unsigned int i = 0; i < dict.Count(); i++) \ + { \ + rs->dict.Insert(dict.GetElementName(i), dict[i]); \ + } \ + + bool MergeWithMain(bool bRemoveThis = true) + { + extern IResponseSystem *g_pResponseSystem; + CResponseSystem *rs = static_cast(g_pResponseSystem); + + CopyRSDict(m_Responses); + CopyRSDict(m_Criteria); + CopyRSDict(m_Rules); + CopyRSDict(m_Enumerations); + + if (mapbase_rs_clear.GetBool()) + Release(); + + return true; + } + */ +#endif private: char *m_pszScriptFile; @@ -2939,6 +3181,9 @@ class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem Precache(); } +#ifdef MAPBASE + if (!rr_enhanced_saverestore.GetBool() || gpGlobals->eLoadType != MapLoad_Transition) +#endif ResetResponseGroups(); } @@ -3051,6 +3296,254 @@ CON_COMMAND( rr_reloadresponsesystems, "Reload all response system scripts." ) #endif } +#ifdef MAPBASE +// Designed for extern magic, this gives the <, >, etc. of response system criteria to the outside world. +// Mostly just used for Matcher_Match in matchers.h. +bool ResponseSystemCompare(const char *criterion, const char *value) +{ + Criteria criteria; + criteria.value = CopyString( criterion ); + defaultresponsesytem.ComputeMatcher(&criteria, criteria.matcher); + return defaultresponsesytem.CompareUsingMatcher(value, criteria.matcher, true); + + return false; +} + +// Another version that returns the criterion without the operators. +// I ended up not using this, but feel free to uncomment it. +// Just keep in mind it was scrapped before I could test it... +/* +const char *ResponseSystemCompare(const char *criterion, const char *value, bool bReturnToken) +{ + CResponseSystem *responsesys = dynamic_cast(g_pResponseSystem); + if (responsesys) + { + Criteria criteria; + criteria.value = CopyString( criterion ); + responsesys->ComputeMatcher(&criteria, criteria.matcher); + return responsesys->CompareUsingMatcher(value, criteria.matcher, true) ? criteria.matcher.GetToken() : NULL; + } + return NULL; +} +*/ + +//----------------------------------------------------------------------------- +// CResponseFilePrecacher +// +// Purpose: Precaches a single talker file. That's it. +// +// It copies from a bunch of the original Response System class and therefore it's really messy. +// Despite the horrors a normal programmer might find in here, I think it performs better than anything else I could've come up with. +//----------------------------------------------------------------------------- +class CResponseFilePrecacher +{ +public: + + // Stuff copied from the Response System. + // Direct copy-pastes are very compact, to say the least. + inline bool ParseToken( void ) + { + if ( m_bUnget ) + { m_bUnget = false; return true; } + if ( m_ScriptStack.Count() <= 0 ) + { return false; } + + m_ScriptStack[ 0 ].currenttoken = engine->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); + m_ScriptStack[ 0 ].tokencount++; + return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + } + + CUtlVector< CResponseSystem::ScriptEntry > m_ScriptStack; + bool m_bUnget; + char token[ 1204 ]; + + + void PrecacheResponse( const char *response, byte type ) + { + switch ( type ) + { + default: + break; + case RESPONSE_SCENE: + { + DevMsg("Precaching scene %s...\n", response); + + // fixup $gender references + char file[_MAX_PATH]; + Q_strncpy( file, response, sizeof(file) ); + char *gender = strstr( file, "$gender" ); + if ( gender ) + { + // replace with male & female + const char *postGender = gender + strlen("$gender"); + *gender = 0; + char genderFile[_MAX_PATH]; + + Q_snprintf( genderFile, sizeof(genderFile), "%smale%s", file, postGender); + PrecacheInstancedScene( genderFile ); + + Q_snprintf( genderFile, sizeof(genderFile), "%sfemale%s", file, postGender); + PrecacheInstancedScene( genderFile ); + } + else + { + PrecacheInstancedScene( file ); + } + } + break; + case RESPONSE_SPEAK: + { + DevMsg("Precaching sound %s...\n", response); + CBaseEntity::PrecacheScriptSound( response ); + } + break; + } + } + + bool IsRootCommand() + { + if (!Q_stricmp( token, "#include" ) || !Q_stricmp( token, "response" ) + || !Q_stricmp( token, "enumeration" ) || !Q_stricmp( token, "criteria" ) + || !Q_stricmp( token, "criterion" ) || !Q_stricmp( token, "rule" )) + return true; + return false; + } + + void ParseResponse( void ) + { + // Must go to response group name + ParseToken(); + + while ( 1 ) + { + ParseToken(); + + if ( !Q_stricmp( token, "{" ) ) + { + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + byte type = ComputeResponseType( token ); + if (type == RESPONSE_NONE) + continue; + + ParseToken(); + char *value = CopyString( token ); + + PrecacheResponse(value, type); + } + break; + } + + byte type = ComputeResponseType( token ); + if (type == RESPONSE_NONE) + break; + + ParseToken(); + char *value = CopyString( token ); + + PrecacheResponse(value, type); + + break; + } + } + + bool LoadFromBuffer(const char *scriptfile, unsigned char *buffer, CStringPool &includedFiles) + { + includedFiles.Allocate( scriptfile ); + + CResponseSystem::ScriptEntry e; + e.name = filesystem->FindOrAddFileName( scriptfile ); + e.buffer = buffer; + e.currenttoken = (char *)e.buffer; + e.tokencount = 0; + m_ScriptStack.AddToHead( e ); + + while ( 1 ) + { + ParseToken(); + if ( !token[0] ) + { + break; + } + + if ( !Q_stricmp( token, "response" ) ) + { + ParseResponse(); + } + else if ( !Q_stricmp( token, "#include" ) || !Q_stricmp( token, "#base" ) ) + { + // Compacted version of ParseInclude(), including new changes. + // Look at that if you want to read. + char includefile[ 256 ]; + ParseToken(); + if (scriptfile) { size_t len = strlen(scriptfile)-1; + for (size_t i = 0; i < len; i++) + { if (scriptfile[i] == CORRECT_PATH_SEPARATOR || scriptfile[i] == INCORRECT_PATH_SEPARATOR) + { len = i; } + } Q_strncpy(includefile, scriptfile, len+1); + if (len+1 != strlen(scriptfile)) + { Q_snprintf(includefile, sizeof(includefile), "%s/%s", includefile, token); } + else includefile[0] = '\0'; + } if (!includefile[0]) Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); + + if ( includedFiles.Find( includefile ) == NULL ) + { + MEM_ALLOC_CREDIT(); + + // Try and load it + CUtlBuffer buf; + if ( filesystem->ReadFile( includefile, "GAME", buf ) ) + { + LoadFromBuffer( includefile, (unsigned char *)buf.PeekGet(), includedFiles ); + } + } + } + } + + if ( m_ScriptStack.Count() > 0 ) + m_ScriptStack.Remove( 0 ); + + return true; + } +}; + +// Loads a file directly to the main response system +bool LoadResponseSystemFile(const char *scriptfile) +{ + CUtlBuffer buf; + if ( !filesystem->ReadFile( scriptfile, "GAME", buf ) ) + { + return false; + } + + // This is a really messy and specialized system that precaches the responses and only the responses of a talker file. + CStringPool includedFiles; + CResponseFilePrecacher *rs = new CResponseFilePrecacher(); + if (!rs || !rs->LoadFromBuffer(scriptfile, (unsigned char *)buf.PeekGet(), includedFiles)) + { + Warning( "Failed to load response system data from %s", scriptfile ); + delete rs; + return false; + } + delete rs; + + CStringPool includedFiles2; + defaultresponsesytem.LoadFromBuffer(scriptfile, (const char *)buf.PeekGet(), includedFiles2); + + return true; +} + +// Called from Mapbase manifests to flush +void ReloadResponseSystem() +{ + defaultresponsesytem.ReloadAllResponseSystems(); +} +#endif + static short RESPONSESYSTEM_SAVE_RESTORE_VERSION = 1; // note: this won't save/restore settings from instanced response systems. Could add that with a CDefSaveRestoreOps implementation if needed @@ -3103,6 +3596,34 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc pSave->EndBlock(); } + +#ifdef MAPBASE + // Enhanced Response System save/restore + int count2 = 0; + if (rr_enhanced_saverestore.GetBool()) + { + // Rule state save/load + count2 = rs.m_Rules.Count(); + pSave->WriteInt( &count2 ); + for ( int i = 0; i < count2; ++i ) + { + pSave->StartBlock( "Rule" ); + + pSave->WriteString( rs.m_Rules.GetElementName( i ) ); + const Rule *rule = &rs.m_Rules[ i ]; + + bool bEnabled = rule->m_bEnabled; + pSave->WriteBool( &bEnabled ); + + pSave->EndBlock(); + } + } + else + { + // Indicate this isn't using enhanced save/restore + pSave->WriteInt( &count2 ); + } +#endif } void Restore( IRestore *pRestore, bool createPlayers ) @@ -3166,6 +3687,34 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc pRestore->EndBlock(); } + +#ifdef MAPBASE + // Enhanced Response System save/restore + count = pRestore->ReadInt(); + for ( int i = 0; i < count; ++i ) + { + char szRuleBlockName[SIZE_BLOCK_NAME_BUF]; + pRestore->StartBlock( szRuleBlockName ); + if ( !Q_stricmp( szRuleBlockName, "Rule" ) ) + { + char groupname[ 256 ]; + pRestore->ReadString( groupname, sizeof( groupname ), 0 ); + + // Try and find it + int idx = rs.m_Rules.Find( groupname ); + if ( idx != rs.m_Rules.InvalidIndex() ) + { + Rule *rule = &rs.m_Rules[ idx ]; + + bool bEnabled; + pRestore->ReadBool( &bEnabled ); + rule->m_bEnabled = bEnabled; + } + } + + pRestore->EndBlock(); + } +#endif } private: diff --git a/game/server/AI_ResponseSystem.h b/game/server/AI_ResponseSystem.h index a7b3a797..0b0b6334 100644 --- a/game/server/AI_ResponseSystem.h +++ b/game/server/AI_ResponseSystem.h @@ -4,6 +4,9 @@ // //=============================================================================// +#ifdef NEW_RESPONSE_SYSTEM +#include "ai_responsesystem_new.h" +#else #ifndef AI_RESPONSESYSTEM_H #define AI_RESPONSESYSTEM_H @@ -18,7 +21,6 @@ abstract_class IResponseFilter { public: - virtual ~IResponseFilter(){} virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ) = 0; }; @@ -40,3 +42,4 @@ class ISaveRestoreBlockHandler *GetDefaultResponseSystemSaveRestoreBlockHandler( class ISaveRestoreOps *GetResponseSystemSaveRestoreOps(); #endif // AI_RESPONSESYSTEM_H +#endif diff --git a/game/server/BaseAnimatingOverlay.cpp b/game/server/BaseAnimatingOverlay.cpp index 84be6fba..06bf690e 100644 --- a/game/server/BaseAnimatingOverlay.cpp +++ b/game/server/BaseAnimatingOverlay.cpp @@ -57,6 +57,45 @@ BEGIN_DATADESC( CBaseAnimatingOverlay ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CBaseAnimatingOverlay, CBaseAnimating, "Animating models which support dynamic animation layers/overlays." ) + + DEFINE_SCRIPTFUNC( GetNumAnimOverlays, "Gets the current number of animation layers." ) + DEFINE_SCRIPTFUNC( RemoveAllGestures, "Removes all animation layers." ) + + DEFINE_SCRIPTFUNC( IsValidLayer, "Returns true if the specified layer index is valid." ) + DEFINE_SCRIPTFUNC( HasActiveLayer, "Returns true if there is currently an active layer." ) + DEFINE_SCRIPTFUNC( RemoveLayer, "Removes the specified layer index with the specified kill rate and delay." ) + DEFINE_SCRIPTFUNC( FastRemoveLayer, "Removes the specified layer index immediately." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddGesture, "AddGesture", "Adds a new animation layer using the specified activity name." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddGestureID, "AddGestureID", "Adds a new animation layer using the specified activity index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddGestureSequence, "AddGestureSequence", "Adds a new animation layer using the specified activity name." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddGestureSequenceID, "AddGestureSequenceID", "Adds a new animation layer using the specified sequence index." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptFindGestureLayer, "FindGestureLayer", "Finds and returns the first active animation layer which uses the specified activity name." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFindGestureLayerByID, "FindGestureLayerByID", "Finds and returns the first active animation layer which uses the specified activity index." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLayerActivity, "GetLayerActivity", "Gets the activity name of the specified layer index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLayerActivityID, "GetLayerActivityID", "Gets the activity index of the specified layer index." ) + DEFINE_SCRIPTFUNC( GetLayerSequence, "Gets the sequence index of the specified layer index." ) + DEFINE_SCRIPTFUNC( SetLayerDuration, "Sets the duration of the specified layer index." ) + DEFINE_SCRIPTFUNC( GetLayerDuration, "Gets the duration of the specified layer index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetLayerCycle, "SetLayerCycle", "Sets the cycle of the specified layer index." ) + DEFINE_SCRIPTFUNC( GetLayerCycle, "Gets the cycle of the specified layer index." ) + DEFINE_SCRIPTFUNC( SetLayerPlaybackRate, "Sets the playback rate of the specified layer index." ) + DEFINE_SCRIPTFUNC( SetLayerWeight, "Sets the weight of the specified layer index." ) + DEFINE_SCRIPTFUNC( GetLayerWeight, "Gets the weight of the specified layer index." ) + DEFINE_SCRIPTFUNC( SetLayerBlendIn, "Sets the fade-in of the specified layer index, with the fade being a 0-1 fraction of the cycle." ) + DEFINE_SCRIPTFUNC( SetLayerBlendOut, "Sets the fade-out of the specified layer index, with the fade being a 0-1 fraction of the cycle." ) + DEFINE_SCRIPTFUNC( SetLayerAutokill, "Sets whether or not the specified layer index should remove itself when it's finished playing." ) + DEFINE_SCRIPTFUNC( SetLayerLooping, "Sets whether or not the specified layer index should loop." ) + DEFINE_SCRIPTFUNC( SetLayerNoRestore, "Sets whether or not the specified layer index should restore after a save is loaded." ) + DEFINE_SCRIPTFUNC( SetLayerNoEvents, "Sets whether or not the specified layer index should fire animation events." ) + +END_SCRIPTDESC(); +#endif + #define ORDER_BITS 4 #define WEIGHT_BITS 8 @@ -354,7 +393,11 @@ void CBaseAnimatingOverlay::DispatchAnimEvents ( CBaseAnimating *eventHandler ) for ( int i = 0; i < m_AnimOverlay.Count(); i++ ) { +#ifdef MAPBASE // From Alien Swarm SDK + if (m_AnimOverlay[ i ].IsActive() && !m_AnimOverlay[ i ].NoEvents()) +#else if (m_AnimOverlay[ i ].IsActive()) +#endif { m_AnimOverlay[ i ].DispatchAnimEvents( eventHandler, this ); } @@ -427,6 +470,11 @@ void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAni event.eventtime = pOwner->m_flAnimTime + (flCycle - m_flCycle) / flCycleRate + pOwner->GetAnimTimeInterval(); } +#ifdef MAPBASE_VSCRIPT + if (eventHandler->m_ScriptScope.IsInitialized() && eventHandler->ScriptHookHandleAnimEvent( &event ) == false) + continue; +#endif + // Msg( "dispatch %d (%d : %.2f)\n", index - 1, event.event, event.eventtime ); eventHandler->HandleAnimEvent( &event ); } @@ -925,25 +973,6 @@ void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle, float flPr m_AnimOverlay[iLayer].MarkActive( ); } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle, float flPrevCycle, float flLastEventCheck ) -{ - if (!IsValidLayer( iLayer )) - return; - - if (!m_AnimOverlay[iLayer].m_bLooping) - { - flCycle = clamp( flCycle, 0.0f, 1.0f ); - flPrevCycle = clamp( flPrevCycle, 0.0f, 1.0f ); - } - m_AnimOverlay[iLayer].m_flCycle = flCycle; - m_AnimOverlay[iLayer].m_flPrevCycle = flPrevCycle; - m_AnimOverlay[iLayer].m_flLastEventCheck = flLastEventCheck; - m_AnimOverlay[iLayer].MarkActive( ); -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1066,6 +1095,38 @@ void CBaseAnimatingOverlay::SetLayerNoRestore( int iLayer, bool bNoRestore ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// From Alien Swarm SDK +//----------------------------------------------------------------------------- +void CBaseAnimatingOverlay::SetLayerNoEvents( int iLayer, bool bNoEvents ) +{ + if (!IsValidLayer( iLayer )) + return; + + if (bNoEvents) + { + m_AnimOverlay[iLayer].m_fFlags |= ANIM_LAYER_NOEVENTS; + } + else + { + m_AnimOverlay[iLayer].m_fFlags &= ~ANIM_LAYER_NOEVENTS; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseAnimatingOverlay::IsLayerFinished( int iLayer ) +{ + if (!IsValidLayer( iLayer )) + return true; + + return m_AnimOverlay[iLayer].m_bSequenceFinished; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1163,4 +1224,36 @@ bool CBaseAnimatingOverlay::HasActiveLayer( void ) return false; } +#ifdef MAPBASE_VSCRIPT +int CBaseAnimatingOverlay::ScriptAddGesture( const char *pszActivity, bool autokill ) +{ + return AddGesture( (Activity)CAI_BaseNPC::GetActivityID( pszActivity ), autokill ); +} + +int CBaseAnimatingOverlay::ScriptAddGestureID( int iActivity, bool autokill ) +{ + return AddGesture( (Activity)iActivity, autokill ); +} + +int CBaseAnimatingOverlay::ScriptFindGestureLayer( const char *pszActivity ) +{ + return FindGestureLayer( (Activity)CAI_BaseNPC::GetActivityID( pszActivity ) ); +} + +int CBaseAnimatingOverlay::ScriptFindGestureLayerByID( int iActivity ) +{ + return FindGestureLayer( (Activity)iActivity ); +} + +const char *CBaseAnimatingOverlay::ScriptGetLayerActivity( int iLayer ) +{ + return CAI_BaseNPC::GetActivityName( GetLayerActivity( iLayer ) ); +} + +int CBaseAnimatingOverlay::ScriptGetLayerActivityID( int iLayer ) +{ + return GetLayerActivity( iLayer ); +} +#endif + //----------------------------------------------------------------------------- diff --git a/game/server/BaseAnimatingOverlay.h b/game/server/BaseAnimatingOverlay.h index 5184eac3..38ee7ed1 100644 --- a/game/server/BaseAnimatingOverlay.h +++ b/game/server/BaseAnimatingOverlay.h @@ -43,6 +43,9 @@ class CAnimationLayer #define ANIM_LAYER_DONTRESTORE 0x0008 #define ANIM_LAYER_CHECKACCESS 0x0010 #define ANIM_LAYER_DYING 0x0020 +#ifdef MAPBASE // From Alien Swarm SDK +#define ANIM_LAYER_NOEVENTS 0x0040 +#endif int m_fFlags; @@ -80,6 +83,9 @@ class CAnimationLayer void Dying( void ) { m_fFlags |= ANIM_LAYER_DYING; } bool IsDying( void ) { return ((m_fFlags & ANIM_LAYER_DYING) != 0); } void Dead( void ) { m_fFlags &= ~ANIM_LAYER_DYING; } +#ifdef MAPBASE // From Alien Swarm SDK + bool NoEvents( void ) { return ((m_fFlags & ANIM_LAYER_NOEVENTS) != 0); } +#endif bool IsAbandoned( void ); void MarkActive( void ); @@ -165,7 +171,6 @@ class CBaseAnimatingOverlay : public CBaseAnimating void SetLayerCycle( int iLayer, float flCycle ); void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle ); - void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle, float flLastEventCheck ); float GetLayerCycle( int iLayer ); void SetLayerPlaybackRate( int iLayer, float flPlaybackRate ); @@ -176,6 +181,11 @@ class CBaseAnimatingOverlay : public CBaseAnimating void SetLayerAutokill( int iLayer, bool bAutokill ); void SetLayerLooping( int iLayer, bool bLooping ); void SetLayerNoRestore( int iLayer, bool bNoRestore ); +#ifdef MAPBASE + void SetLayerNoEvents( int iLayer, bool bNoEvents ); // From Alien Swarm SDK + + bool IsLayerFinished( int iLayer ); +#endif Activity GetLayerActivity( int iLayer ); int GetLayerSequence( int iLayer ); @@ -196,9 +206,26 @@ class CBaseAnimatingOverlay : public CBaseAnimating private: int AllocateLayer( int iPriority = 0 ); // lower priorities are processed first +#ifdef MAPBASE_VSCRIPT + int ScriptAddGesture( const char *pszActivity, bool autokill ); + int ScriptAddGestureID( int iActivity, bool autokill ); + int ScriptAddGestureSequence( const char *pszSequence, bool autokill ) { return AddGestureSequence( LookupSequence( pszSequence ), autokill ); } + int ScriptAddGestureSequenceID( int iSequence, bool autokill ) { return AddGestureSequence( iSequence, autokill ); } + + int ScriptFindGestureLayer( const char *pszActivity ); + int ScriptFindGestureLayerByID( int iActivity ); + const char *ScriptGetLayerActivity( int iLayer ); + int ScriptGetLayerActivityID( int iLayer ); + + void ScriptSetLayerCycle( int iLayer, float flCycle ) { SetLayerCycle( iLayer, flCycle ); } +#endif + DECLARE_SERVERCLASS(); DECLARE_DATADESC(); DECLARE_PREDICTABLE(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif }; EXTERN_SEND_TABLE(DT_BaseAnimatingOverlay); diff --git a/game/server/BasePropDoor.h b/game/server/BasePropDoor.h index 2b0366e8..7e8400d2 100644 --- a/game/server/BasePropDoor.h +++ b/game/server/BasePropDoor.h @@ -21,10 +21,6 @@ #include "props.h" #include "locksounds.h" #include "entityoutput.h" -#ifdef VANCE -#include "doors.h" -#include "vance_shareddefs.h" -#endif extern ConVar g_debug_doors; @@ -50,25 +46,6 @@ abstract_class CBasePropDoor : public CDynamicProp void Activate(); int ObjectCaps(); -#ifdef VANCE - int OnTakeDamage(const CTakeDamageInfo & info) - { - if (info.GetDamageType() == DMG_KICK && m_bCanBeKickedOpen && !IsDoorOpen()) - { - // Play door unlock sounds. - // PlayLockSounds(this, &m_ls, false, false); - m_bKickedOpen = true; - Unlock(); - DoorOpen(info.GetAttacker()); - return 0; - } - - return BaseClass::OnTakeDamage(info); - } - - bool m_bKickedOpen; -#endif - void HandleAnimEvent( animevent_t *pEvent ); // Base class services. @@ -98,6 +75,12 @@ abstract_class CBasePropDoor : public CDynamicProp virtual float GetOpenInterval(void) = 0; // } +#ifdef MAPBASE + virtual bool PassesDoorFilter(CBaseEntity *pEntity) { return true; } + + virtual bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + protected: enum DoorState_t @@ -122,6 +105,12 @@ abstract_class CBasePropDoor : public CDynamicProp inline CBaseEntity *GetActivator(); +#ifdef MAPBASE + inline float GetNPCOpenDistance() { return m_flNPCOpenDistance; } + inline Activity GetNPCOpenFrontActivity() { return m_eNPCOpenFrontActivity; } + inline Activity GetNPCOpenBackActivity() { return m_eNPCOpenBackActivity; } +#endif + private: // Implement these in your leaf class. @@ -186,6 +175,10 @@ abstract_class CBasePropDoor : public CDynamicProp void InputOpenAwayFrom(inputdata_t &inputdata); void InputToggle(inputdata_t &inputdata); void InputUnlock(inputdata_t &inputdata); +#ifdef MAPBASE + void InputAllowPlayerUse(inputdata_t &inputdata); + void InputDisallowPlayerUse(inputdata_t &inputdata); +#endif void SetDoorBlocker( CBaseEntity *pBlocker ); @@ -207,14 +200,16 @@ abstract_class CBasePropDoor : public CDynamicProp bool m_bForceClosed; // True if this door must close no matter what. -#ifdef VANCE - bool m_bCanBeKickedOpen; -#endif - string_t m_SoundMoving; string_t m_SoundOpen; string_t m_SoundClose; +#ifdef MAPBASE + float m_flNPCOpenDistance; + Activity m_eNPCOpenFrontActivity; + Activity m_eNPCOpenBackActivity; +#endif + // dvs: FIXME: can we remove m_flSpeed from CBaseEntity? //float m_flSpeed; // Rotation speed when opening or closing in degrees per second. diff --git a/game/server/CRagdollMagnet.cpp b/game/server/CRagdollMagnet.cpp index 454f7804..fc17cc9a 100644 --- a/game/server/CRagdollMagnet.cpp +++ b/game/server/CRagdollMagnet.cpp @@ -20,10 +20,17 @@ BEGIN_DATADESC( CRagdollMagnet ) DEFINE_KEYFIELD( m_force, FIELD_FLOAT, "force" ), DEFINE_KEYFIELD( m_axis, FIELD_VECTOR, "axis" ), DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_BoneTarget, FIELD_STRING, "BoneTarget" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnUsed, "OnUsed" ), +#endif + END_DATADESC() //----------------------------------------------------------------------------- @@ -111,20 +118,54 @@ CRagdollMagnet *CRagdollMagnet::FindBestMagnet( CBaseEntity *pNPC ) // // NOTE: This function assumes pNPC is within this magnet's radius. //----------------------------------------------------------------------------- +#ifdef MAPBASE +Vector CRagdollMagnet::GetForceVector( CBaseEntity *pNPC, int *pBone ) +#else Vector CRagdollMagnet::GetForceVector( CBaseEntity *pNPC ) +#endif { Vector vecForceToApply; +#ifdef MAPBASE + Vector vecNPCPos = pNPC->WorldSpaceCenter(); + + if (pBone) + { + CBaseAnimating *pAnimating = pNPC->GetBaseAnimating(); + Assert( pAnimating != NULL ); + + const char *szBoneTarget = BoneTarget(); + Assert( szBoneTarget != NULL ); + + int iBone = pAnimating->LookupBone( szBoneTarget ); + + if (iBone != -1) + { + matrix3x4_t bonetoworld; + pAnimating->GetBoneTransform( iBone, bonetoworld ); + MatrixPosition( bonetoworld, vecNPCPos ); + *pBone = iBone; + } + } +#endif + if( IsBarMagnet() ) { CPlane axis; Vector vecForceDir; Vector vecClosest; +#ifdef MAPBASE + CalcClosestPointOnLineSegment( vecNPCPos, GetAbsOrigin(), m_axis, vecClosest, NULL ); + + vecForceDir = (vecClosest - vecNPCPos ); + VectorNormalize( vecForceDir ); +#else CalcClosestPointOnLineSegment( pNPC->WorldSpaceCenter(), GetAbsOrigin(), m_axis, vecClosest, NULL ); vecForceDir = (vecClosest - pNPC->WorldSpaceCenter() ); VectorNormalize( vecForceDir ); +#endif vecForceToApply = vecForceDir * m_force; } @@ -132,7 +173,11 @@ Vector CRagdollMagnet::GetForceVector( CBaseEntity *pNPC ) { Vector vecForce; +#ifdef MAPBASE + vecForce = GetAbsOrigin() - vecNPCPos; +#else vecForce = GetAbsOrigin() - pNPC->WorldSpaceCenter(); +#endif VectorNormalize( vecForce ); vecForceToApply = vecForce * m_force; diff --git a/game/server/CRagdollMagnet.h b/game/server/CRagdollMagnet.h index b2211724..52d3f57d 100644 --- a/game/server/CRagdollMagnet.h +++ b/game/server/CRagdollMagnet.h @@ -18,7 +18,11 @@ class CRagdollMagnet : public CPointEntity DECLARE_CLASS( CRagdollMagnet, CPointEntity ); DECLARE_DATADESC(); +#ifdef MAPBASE + Vector GetForceVector( CBaseEntity *pNPC, int *pBone = NULL ); +#else Vector GetForceVector( CBaseEntity *pNPC ); +#endif float GetRadius( void ) { return m_radius; } Vector GetAxisVector( void ) { return m_axis - GetAbsOrigin(); } float DistToPoint( const Vector &vecPoint ); @@ -35,11 +39,20 @@ class CRagdollMagnet : public CPointEntity void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + const char *BoneTarget() { return STRING(m_BoneTarget); } + + COutputVector m_OnUsed; +#endif + private: bool m_bDisabled; float m_radius; float m_force; Vector m_axis; +#ifdef MAPBASE + string_t m_BoneTarget; +#endif }; #endif //CRAGDOLLMAGNET_H \ No newline at end of file diff --git a/game/server/CommentarySystem.cpp b/game/server/CommentarySystem.cpp index 677b4d84..7ff8b33e 100644 --- a/game/server/CommentarySystem.cpp +++ b/game/server/CommentarySystem.cpp @@ -22,6 +22,11 @@ #include "gamestats.h" #include "ai_basenpc.h" #include "Sprite.h" +#ifdef MAPBASE +#include "mapbase/SystemConvarMod.h" +#include +#include +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -42,6 +47,7 @@ enum teleport_stages_t TELEPORT_FADEIN, }; +#ifndef MAPBASE // This has been moved to mapbase/SystemConvarMod.h // Convar restoration save/restore #define MAX_MODIFIED_CONVAR_STRING 128 struct modifiedconvars_t @@ -52,6 +58,7 @@ struct modifiedconvars_t char pszCurrentValue[MAX_MODIFIED_CONVAR_STRING]; char pszOrgValue[MAX_MODIFIED_CONVAR_STRING]; }; +#endif bool g_bInCommentaryMode = false; bool IsInCommentaryMode( void ) @@ -67,8 +74,23 @@ class CPointCommentaryNode : public CBaseAnimating DECLARE_CLASS( CPointCommentaryNode, CBaseAnimating ); public: DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif DECLARE_SERVERCLASS(); + CPointCommentaryNode() + { +#ifdef MAPBASE + m_flViewTargetSpeedScale = 1.0f; + m_flViewPositionSpeedScale = 1.0f; + m_flReturnSpeedScale = 0.0f; + m_flPanelScale = 1.0f; + m_flPanelX = -1.0f; + m_flPanelY = -1.0f; +#endif + } + void Spawn( void ); void Precache( void ); void Activate( void ); @@ -97,11 +119,39 @@ class CPointCommentaryNode : public CBaseAnimating void TeleportTo( CBasePlayer *pPlayer ); bool CanTeleportTo( void ); +#ifdef MAPBASE + bool IsActive() { return m_bActive; } + bool IsDisabled() { return m_bDisabled; } + + int GetCommentaryType() { return m_iCommentaryType; } + void SetCommentaryType( int iType ) { m_iCommentaryType = iType; } + + const char *GetCommentaryFile() { return STRING( m_iszCommentaryFile.Get() ); } + void SetCommentaryFile( const char *pszNewFile ) { m_iszCommentaryFile.Set( AllocPooledString( pszNewFile ) ); } + const char *GetSpeakers() { return STRING( m_iszSpeakers.Get() ); } + void SetSpeakers( const char *pszSpeakers ) { m_iszSpeakers.Set( AllocPooledString( pszSpeakers ) ); } + const char *GetPrintName() { return STRING( m_iszPrintName.Get() ); } + void SetPrintName( const char *pszPrintName ) { m_iszPrintName.Set( AllocPooledString( pszPrintName ) ); } + const char *GetFootnote() { return STRING( m_iszFootnote.Get() ); } + void SetFootnote( const char *pszFootnote ) { m_iszFootnote.Set( AllocPooledString( pszFootnote ) ); } +#endif + // Inputs void InputStartCommentary( inputdata_t &inputdata ); void InputStartUnstoppableCommentary( inputdata_t &inputdata ); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetViewTarget( inputdata_t &inputdata ); + void InputSetViewPosition( inputdata_t &inputdata ); + void InputSetViewTargetSpeed( inputdata_t &inputdata ); + void InputSetViewPositionSpeed( inputdata_t &inputdata ); + void InputSetReturnSpeed( inputdata_t &inputdata ); +#endif + +#ifdef MAPBASE_VSCRIPT + static ScriptHook_t g_Hook_PreStartCommentary; +#endif private: string_t m_iszPreCommands; @@ -114,6 +164,14 @@ class CPointCommentaryNode : public CBaseAnimating string_t m_iszViewPosition; CNetworkVar( EHANDLE, m_hViewPosition ); EHANDLE m_hViewPositionMover; // Entity used to blend the view to the viewposition entity +#ifdef MAPBASE + float m_flViewTargetSpeedScale; + float m_flViewPositionSpeedScale; + float m_flReturnSpeedScale; + CNetworkVar( string_t, m_iszPrintName ); + CNetworkVar( string_t, m_iszFootnote ); + float m_flViewPositionChangedTime; // View position now blends relative to this value. Mainly needed for when SetViewPosition is used +#endif bool m_bPreventMovement; bool m_bUnderCrosshair; bool m_bUnstoppable; @@ -133,6 +191,13 @@ class CPointCommentaryNode : public CBaseAnimating CNetworkVar( string_t, m_iszSpeakers ); CNetworkVar( int, m_iNodeNumber ); CNetworkVar( int, m_iNodeNumberMax ); + +#ifdef MAPBASE + CNetworkVar( int, m_iCommentaryType ); + CNetworkVar( float, m_flPanelScale ); + CNetworkVar( float, m_flPanelX ); + CNetworkVar( float, m_flPanelY ); +#endif }; BEGIN_DATADESC( CPointCommentaryNode ) @@ -161,6 +226,18 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_FIELD( m_bPreventChangesWhileMoving, FIELD_BOOLEAN ), DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "start_disabled" ), DEFINE_KEYFIELD( m_vecTeleportOrigin, FIELD_VECTOR, "teleport_origin" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flViewTargetSpeedScale, FIELD_FLOAT, "viewtarget_speed" ), + DEFINE_KEYFIELD( m_flViewPositionSpeedScale, FIELD_FLOAT, "viewposition_speed" ), + DEFINE_KEYFIELD( m_flReturnSpeedScale, FIELD_FLOAT, "return_speed" ), + DEFINE_KEYFIELD( m_iszPrintName, FIELD_STRING, "printname" ), + DEFINE_KEYFIELD( m_iszFootnote, FIELD_STRING, "footnote" ), + DEFINE_FIELD( m_flViewPositionChangedTime, FIELD_TIME ), + DEFINE_KEYFIELD( m_iCommentaryType, FIELD_INTEGER, "type" ), + DEFINE_KEYFIELD( m_flPanelScale, FIELD_FLOAT, "panelscale" ), + DEFINE_KEYFIELD( m_flPanelX, FIELD_FLOAT, "x" ), + DEFINE_KEYFIELD( m_flPanelY, FIELD_FLOAT, "y" ), +#endif // Outputs DEFINE_OUTPUT( m_pOnCommentaryStarted, "OnCommentaryStarted" ), @@ -171,6 +248,13 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_INPUTFUNC( FIELD_VOID, "StartUnstoppableCommentary", InputStartUnstoppableCommentary ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetViewTarget", InputSetViewTarget ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetViewPosition", InputSetViewPosition ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetViewTargetSpeed", InputSetViewTargetSpeed ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetViewPositionSpeed", InputSetViewPositionSpeed ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetReturnSpeed", InputSetReturnSpeed ), +#endif // Functions DEFINE_THINKFUNC( SpinThink ), @@ -178,6 +262,37 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_THINKFUNC( UpdateViewPostThink ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT + +ScriptHook_t CPointCommentaryNode::g_Hook_PreStartCommentary; + +BEGIN_ENT_SCRIPTDESC( CPointCommentaryNode, CBaseAnimating, "Commentary nodes which play commentary in commentary mode." ) + DEFINE_SCRIPTFUNC( IsDisabled, "" ) + DEFINE_SCRIPTFUNC( SetDisabled, "" ) + + DEFINE_SCRIPTFUNC( IsActive, "" ) + DEFINE_SCRIPTFUNC( GetCommentaryFile, "" ) + DEFINE_SCRIPTFUNC( SetCommentaryFile, "" ) + DEFINE_SCRIPTFUNC( GetSpeakers, "" ) + DEFINE_SCRIPTFUNC( SetSpeakers, "" ) + DEFINE_SCRIPTFUNC( GetPrintName, "" ) + DEFINE_SCRIPTFUNC( SetPrintName, "" ) + DEFINE_SCRIPTFUNC( GetFootnote, "" ) + DEFINE_SCRIPTFUNC( SetFootnote, "" ) + DEFINE_SCRIPTFUNC( GetCommentaryType, "" ) + DEFINE_SCRIPTFUNC( SetCommentaryType, "" ) + + DEFINE_SCRIPTFUNC( HasViewTarget, "" ) + DEFINE_SCRIPTFUNC( PreventsMovement, "" ) + DEFINE_SCRIPTFUNC( CannotBeStopped, "" ) + + DEFINE_SCRIPTFUNC( AbortPlaying, "Stops playing the node and snaps out of its camera control immediately. The game uses this function to shut down commentary while in the middle of playing a node, as it can't smoothly blend out (since the commentary entities need to be removed)." ) + + DEFINE_SIMPLE_SCRIPTHOOK( CPointCommentaryNode::g_Hook_PreStartCommentary, "PreStartCommentary", FIELD_BOOLEAN, "Called just before commentary begins. Use this to modify variables or commentary behavior before it begins. Returning false will prevent the commentary from starting." ) +END_SCRIPTDESC(); + +#endif // MAPBASE_VSCRIPT + IMPLEMENT_SERVERCLASS_ST( CPointCommentaryNode, DT_PointCommentaryNode ) SendPropBool( SENDINFO(m_bActive) ), SendPropStringT( SENDINFO(m_iszCommentaryFile) ), @@ -187,6 +302,14 @@ IMPLEMENT_SERVERCLASS_ST( CPointCommentaryNode, DT_PointCommentaryNode ) SendPropInt( SENDINFO(m_iNodeNumber), 8, SPROP_UNSIGNED ), SendPropInt( SENDINFO(m_iNodeNumberMax), 8, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO(m_hViewPosition) ), +#ifdef MAPBASE + SendPropStringT( SENDINFO( m_iszPrintName ) ), + SendPropStringT( SENDINFO( m_iszFootnote ) ), + SendPropInt( SENDINFO( m_iCommentaryType ), 2, SPROP_UNSIGNED ), + SendPropFloat( SENDINFO( m_flPanelScale ) ), + SendPropFloat( SENDINFO( m_flPanelX ) ), + SendPropFloat( SENDINFO( m_flPanelY ) ), +#endif END_SEND_TABLE() LINK_ENTITY_TO_CLASS( point_commentary_node, CPointCommentaryNode ); @@ -663,7 +786,16 @@ class CCommentarySystem : public CAutoGameSystemPerFrame Msg( "Commentary: Could not find commentary data file '%s'. \n", szFullName ); } +#ifdef MAPBASE // VDC Memory Leak Fixes + pkvFile->deleteThis(); +#endif + engine->LockNetworkStringTables( oldLock ); + +#ifdef MAPBASE + // Special commentary localization file (useful for things like text nodes or print names) + g_pVGuiLocalize->AddFile( "resource/commentary_%language%.txt", "MOD" ); +#endif } void ShutDownCommentary( void ) @@ -821,11 +953,13 @@ BEGIN_DATADESC_NO_BASE( CCommentarySystem ) DEFINE_FIELD( m_iCommentaryNodeCount, FIELD_INTEGER ), END_DATADESC() +#ifndef MAPBASE // This has been moved to mapbase/SystemConvarMod.h BEGIN_SIMPLE_DATADESC( modifiedconvars_t ) DEFINE_ARRAY( pszConvar, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), DEFINE_ARRAY( pszCurrentValue, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), DEFINE_ARRAY( pszOrgValue, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), END_DATADESC() +#endif //----------------------------------------------------------------------------- @@ -839,7 +973,7 @@ void CC_CommentaryChanged( IConVar *pConVar, const char *pOldString, float flOld g_CommentarySystem.SetCommentaryMode( var.GetBool() ); } } -ConVar commentary( "commentary", "0", FCVAR_NONE, "Desired commentary mode state.", CC_CommentaryChanged ); +ConVar commentary("commentary", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "Desired commentary mode state.", CC_CommentaryChanged ); //----------------------------------------------------------------------------- // Purpose: We need to revert back any convar changes that are made by the @@ -881,10 +1015,32 @@ bool IsListeningToCommentary( void ) void CPointCommentaryNode::Spawn( void ) { // No model specified? - char *szModel = (char *)STRING( GetModelName() ); + const char *szModel = STRING( GetModelName() ); if (!szModel || !*szModel) { +#ifdef MAPBASE + switch (m_iCommentaryType) + { + case COMMENTARY_TYPE_TEXT: + szModel = "models/extras/info_text.mdl"; + break; + + case COMMENTARY_TYPE_IMAGE: + szModel = "models/extras/info_image.mdl"; + break; + + case COMMENTARY_TYPE_SCENE: + szModel = "models/extras/info_scene.mdl"; + break; + + default: + case COMMENTARY_TYPE_AUDIO: + szModel = "models/extras/info_speech.mdl"; + break; + } +#else szModel = "models/extras/info_speech.mdl"; +#endif SetModelName( AllocPooledString(szModel) ); } @@ -895,6 +1051,12 @@ void CPointCommentaryNode::Spawn( void ) AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST ); AddEffects( EF_NOSHADOW ); +#ifdef MAPBASE + // Default to view position speed scale (which in turn defaults to 1.0) + if (m_flReturnSpeedScale == 0.0f) + m_flReturnSpeedScale = m_flViewPositionSpeedScale; +#endif + // Setup for animation ResetSequence( LookupSequence("idle") ); SetThink( &CPointCommentaryNode::SpinThink ); @@ -1108,6 +1270,19 @@ void CPointCommentaryNode::StartCommentary( void ) if ( !pPlayer ) return; +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_PreStartCommentary.CanRunInScope( m_ScriptScope )) + { + ScriptVariant_t functionReturn; + if ( g_Hook_PreStartCommentary.Call( m_ScriptScope, &functionReturn, NULL ) && functionReturn.m_type == FIELD_BOOLEAN ) + { + // Don't play the commentary if it returned false + if (functionReturn.m_bool == false) + return; + } + } +#endif + m_bActive = true; m_flAnimTime = gpGlobals->curtime; @@ -1129,6 +1304,21 @@ void CPointCommentaryNode::StartCommentary( void ) // Start the commentary m_flStartTime = gpGlobals->curtime; +#ifdef MAPBASE + if (m_hViewPosition.Get()) + { + m_flViewPositionChangedTime = gpGlobals->curtime; + } + else + { + m_flViewPositionChangedTime = -1.0f; + } + + // This is now used in certain places to denote the "last blend to" origin + m_vecFinishOrigin = pPlayer->EyePosition(); + m_vecFinishAngles = pPlayer->EyeAngles(); +#endif + // If we have a view target, start blending towards it if ( m_hViewTarget || m_hViewPosition.Get() ) { @@ -1203,6 +1393,10 @@ void CPointCommentaryNode::UpdateViewThink( void ) float dx = AngleDiff( angGoal.x, angCurrent.x ); float dy = AngleDiff( angGoal.y, angCurrent.y ); float mod = 1.0 - ExponentialDecay( 0.5, 0.3, gpGlobals->frametime ); +#ifdef MAPBASE + if (m_flViewTargetSpeedScale != 1.0f) + mod *= m_flViewTargetSpeedScale; +#endif float dxmod = dx * mod; float dymod = dy * mod; @@ -1243,16 +1437,85 @@ void CPointCommentaryNode::UpdateViewThink( void ) } // Blend to the target position over time. - float flCurTime = (gpGlobals->curtime - m_flStartTime); +#ifdef MAPBASE + float flCurTime = (gpGlobals->curtime - m_flViewPositionChangedTime); + if (m_flViewPositionSpeedScale != 1.0f) + flCurTime *= m_flViewPositionSpeedScale; +#else + float flCurTime = (gpGlobals->curtime - m_flStartTime); +#endif float flBlendPerc = clamp( flCurTime * 0.5f, 0.f, 1.f ); // Figure out the current view position Vector vecCurEye; +#ifdef MAPBASE + VectorLerp( m_vecFinishOrigin, m_hViewPosition.Get()->GetAbsOrigin(), flBlendPerc, vecCurEye ); +#else VectorLerp( pPlayer->EyePosition(), m_hViewPosition.Get()->GetAbsOrigin(), flBlendPerc, vecCurEye ); +#endif m_hViewPositionMover->SetAbsOrigin( vecCurEye ); SetNextThink( gpGlobals->curtime, s_pCommentaryUpdateViewThink ); } +#ifdef MAPBASE + else if ( m_flViewPositionChangedTime != -1.0f && m_hViewPositionMover ) + { + // Blend back to the player's position over time. + float flCurTime = (gpGlobals->curtime - m_flViewPositionChangedTime); + if (m_flViewPositionSpeedScale != 1.0f) + flCurTime *= m_flViewPositionSpeedScale; + + //float flTimeToBlend = MIN( 2.0, m_flViewPositionChangedTime - m_flStartTime ); + //float flBlendPerc = 1.0f - clamp( flCurTime / flTimeToBlend, 0.f, 1.f ); + float flBlendPerc = 1.0f - clamp( flCurTime * 0.5f, 0.f, 1.f ); + + //Msg("OUT: CurTime %.2f, BlendTime: %.2f, Blend: %.3f\n", flCurTime, flTimeToBlend, flBlendPerc ); + + // Only do this while we're still moving + if ( flBlendPerc > 0 ) + { + // Figure out the current view position + Vector vecPlayerPos = pPlayer->EyePosition(); + Vector vecToPosition = (m_vecFinishOrigin - vecPlayerPos); + Vector vecCurEye = pPlayer->EyePosition() + (vecToPosition * flBlendPerc); + m_hViewPositionMover->SetAbsOrigin( vecCurEye ); + + if ( m_hViewTarget ) + { + Quaternion quatFinish; + Quaternion quatOriginal; + Quaternion quatCurrent; + AngleQuaternion( m_vecOriginalAngles, quatOriginal ); + AngleQuaternion( m_vecFinishAngles, quatFinish ); + QuaternionSlerp( quatFinish, quatOriginal, 1.0 - flBlendPerc, quatCurrent ); + QAngle angCurrent; + QuaternionAngles( quatCurrent, angCurrent ); + m_hViewPositionMover->SetAbsAngles( angCurrent ); + } + + SetNextThink( gpGlobals->curtime, s_pCommentaryUpdateViewThink ); + return; + } + else + { + pPlayer->SnapEyeAngles( m_hViewPositionMover->GetAbsAngles() ); + + // Try to clean up the view position stuff without ending the commentary + if ( !m_hViewTargetAngles && pPlayer->GetActiveWeapon() ) + { + pPlayer->GetActiveWeapon()->Deploy(); + } + + if (pPlayer->GetViewEntity() == m_hViewPositionMover) + { + pPlayer->SetViewEntity( NULL ); + } + UTIL_Remove( m_hViewPositionMover ); + + m_flViewPositionChangedTime = -1.0f; + } + } +#endif } //----------------------------------------------------------------------------- @@ -1268,6 +1531,10 @@ void CPointCommentaryNode::UpdateViewPostThink( void ) { // Blend back to the player's position over time. float flCurTime = (gpGlobals->curtime - m_flFinishedTime); +#ifdef MAPBASE + if (m_flReturnSpeedScale != 1.0f) + flCurTime *= m_flReturnSpeedScale; +#endif float flTimeToBlend = MIN( 2.0, m_flFinishedTime - m_flStartTime ); float flBlendPerc = 1.0f - clamp( flCurTime / flTimeToBlend, 0.f, 1.f ); @@ -1429,6 +1696,79 @@ void CPointCommentaryNode::InputDisable( inputdata_t &inputdata ) SetDisabled( true ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCommentaryNode::InputSetViewTarget( inputdata_t &inputdata ) +{ + m_hViewTarget = inputdata.value.Entity(); + + // Do not let Activate() reassign this + m_iszViewTarget = NULL_STRING; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCommentaryNode::InputSetViewPosition( inputdata_t &inputdata ) +{ + if (m_hViewPosition.Get() && m_hViewPositionMover) + { + // In case the view position is being cleared, assign the "finish" vectors + m_vecFinishOrigin = m_hViewPositionMover->GetAbsOrigin(); + m_vecFinishAngles = m_hViewPositionMover->GetAbsAngles(); + } + else + { + CBasePlayer *pPlayer = GetCommentaryPlayer(); + if (pPlayer) + { + // And in case it's a new view position coming from the player, assign the "finish" vectors to the player + m_vecFinishOrigin = pPlayer->EyePosition(); + m_vecFinishAngles = m_vecOriginalAngles = pPlayer->EyeAngles(); + } + } + + m_hViewPosition = inputdata.value.Entity(); + + // Do not let Activate() reassign this + m_iszViewPosition = NULL_STRING; + + m_flViewPositionChangedTime = gpGlobals->curtime; + + // If we have a view target, start blending towards it + if ( m_hViewPosition.Get() ) + { + SetContextThink( &CPointCommentaryNode::UpdateViewThink, gpGlobals->curtime, s_pCommentaryUpdateViewThink ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCommentaryNode::InputSetViewTargetSpeed( inputdata_t &inputdata ) +{ + m_flViewTargetSpeedScale = inputdata.value.Float(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCommentaryNode::InputSetViewPositionSpeed( inputdata_t &inputdata ) +{ + m_flViewPositionSpeedScale = inputdata.value.Float(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCommentaryNode::InputSetReturnSpeed( inputdata_t &inputdata ) +{ + m_flReturnSpeedScale = inputdata.value.Float(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1490,7 +1830,11 @@ void CPointCommentaryNode::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways bool CPointCommentaryNode::PreventsMovement( void ) { // If we're moving the player's view at all, prevent movement +#ifdef MAPBASE + if ( m_hViewPosition.Get() || m_flViewPositionChangedTime != -1.0f ) +#else if ( m_hViewPosition.Get() ) +#endif return true; return m_bPreventMovement; diff --git a/game/server/EntityFlame.cpp b/game/server/EntityFlame.cpp index d3a1be10..80217efb 100644 --- a/game/server/EntityFlame.cpp +++ b/game/server/EntityFlame.cpp @@ -242,7 +242,12 @@ void CEntityFlame::FlameThink( void ) } CAI_BaseNPC *pNPC = m_hEntAttached->MyNPCPointer(); +#ifdef MAPBASE + // Don't extingish if the NPC is still dying + if ( pNPC && !pNPC->IsAlive() && pNPC->m_lifeState != LIFE_DYING ) +#else if ( pNPC && !pNPC->IsAlive() ) +#endif { UTIL_Remove( this ); // Notify the NPC that it's no longer burning! diff --git a/game/server/EnvBeam.cpp b/game/server/EnvBeam.cpp index b4308811..c74df00d 100644 --- a/game/server/EnvBeam.cpp +++ b/game/server/EnvBeam.cpp @@ -48,6 +48,11 @@ class CEnvBeam : public CBeam void InputTurnOff( inputdata_t &inputdata ); void InputToggle( inputdata_t &inputdata ); void InputStrikeOnce( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputAmplitude( inputdata_t &inputdata ); + void InputSetStartEntity( inputdata_t &inputdata ) { m_iszStartEntity = inputdata.value.StringID(); BeamUpdateVars(); } + void InputSetEndEntity( inputdata_t &inputdata ) { m_iszEndEntity = inputdata.value.StringID(); BeamUpdateVars(); } +#endif void TurnOn( void ); void TurnOff( void ); @@ -123,6 +128,11 @@ BEGIN_DATADESC( CEnvBeam ) DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), DEFINE_INPUTFUNC( FIELD_VOID, "StrikeOnce", InputStrikeOnce ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "Amplitude", InputAmplitude ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetStartEntity", InputSetStartEntity ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetEndEntity", InputSetEndEntity ), +#endif DEFINE_OUTPUT( m_OnTouchedByEntity, "OnTouchedByEntity" ), @@ -287,6 +297,17 @@ void CEnvBeam::InputStrikeOnce( inputdata_t &inputdata ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for amplitude +//----------------------------------------------------------------------------- +void CEnvBeam::InputAmplitude( inputdata_t &inputdata ) +{ + m_noiseAmplitude = inputdata.value.Float(); +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Turns the lightning on. If it is set for interval refiring, it will // begin doing so. If it is set to be continually on, it will do so. @@ -383,11 +404,53 @@ void CEnvBeam::Strike( void ) m_speed = clamp( (int) m_speed, 0, (int) MAX_BEAM_SCROLLSPEED ); +#ifdef MAPBASE + bool pointStart = IsStaticPointEntity( pStart ); + bool pointEnd = IsStaticPointEntity( pEnd ); +#else int pointStart = IsStaticPointEntity( pStart ); int pointEnd = IsStaticPointEntity( pEnd ); +#endif if ( pointStart || pointEnd ) { +#ifdef MAPBASE + if ( m_spawnflags & SF_BEAM_RING ) + { + te->BeamRing( filter, 0.0, + pStart->entindex(), + pEnd->entindex(), + m_spriteTexture, + 0, // No halo + m_frameStart, + (int)m_flFrameRate, + m_life, + m_boltWidth, + 0, // No spread + m_noiseAmplitude, + m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a, + m_speed ); + } + else + { + te->BeamEntPoint( filter, 0.0, + pStart->entindex(), + &pStart->GetAbsOrigin(), + pEnd->entindex(), + &pEnd->GetAbsOrigin(), + m_spriteTexture, + 0, // No halo + m_frameStart, + (int)m_flFrameRate, + m_life, + m_boltWidth, + m_boltWidth, // End width + 0, // No fade + m_noiseAmplitude, + m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a, + m_speed ); + } +#else if ( m_spawnflags & SF_BEAM_RING ) { // don't work @@ -410,6 +473,7 @@ void CEnvBeam::Strike( void ) m_noiseAmplitude, m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a, m_speed ); +#endif } else { diff --git a/game/server/EnvFade.cpp b/game/server/EnvFade.cpp index fa0185d5..8b6c58f2 100644 --- a/game/server/EnvFade.cpp +++ b/game/server/EnvFade.cpp @@ -58,6 +58,9 @@ END_DATADESC() #define SF_FADE_MODULATE 0x0002 // Modulate, don't blend #define SF_FADE_ONLYONE 0x0004 #define SF_FADE_STAYOUT 0x0008 +#ifdef MAPBASE +#define SF_FADE_DONT_PURGE 0x0016 +#endif //----------------------------------------------------------------------------- // Purpose: @@ -93,6 +96,13 @@ void CEnvFade::InputFade( inputdata_t &inputdata ) fadeFlags |= FFADE_STAYOUT; } +#ifdef MAPBASE + if ( !HasSpawnFlags(SF_FADE_DONT_PURGE) ) + { + fadeFlags |= FFADE_PURGE; + } +#endif + if ( m_spawnflags & SF_FADE_ONLYONE ) { if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() ) @@ -102,7 +112,11 @@ void CEnvFade::InputFade( inputdata_t &inputdata ) } else { +#ifdef MAPBASE + UTIL_ScreenFadeAll( m_clrRender, Duration(), HoldTime(), fadeFlags ); +#else UTIL_ScreenFadeAll( m_clrRender, Duration(), HoldTime(), fadeFlags|FFADE_PURGE ); +#endif } m_OnBeginFade.FireOutput( inputdata.pActivator, this ); diff --git a/game/server/EnvHudHint.cpp b/game/server/EnvHudHint.cpp index 858fc7b9..2cb38eab 100644 --- a/game/server/EnvHudHint.cpp +++ b/game/server/EnvHudHint.cpp @@ -32,6 +32,9 @@ class CEnvHudHint : public CPointEntity void InputShowHudHint( inputdata_t &inputdata ); void InputHideHudHint( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetHudHint( inputdata_t &inputdata ); +#endif string_t m_iszMessage; DECLARE_DATADESC(); }; @@ -43,6 +46,9 @@ BEGIN_DATADESC( CEnvHudHint ) DEFINE_KEYFIELD( m_iszMessage, FIELD_STRING, "message" ), DEFINE_INPUTFUNC( FIELD_VOID, "ShowHudHint", InputShowHudHint ), DEFINE_INPUTFUNC( FIELD_VOID, "HideHudHint", InputHideHudHint ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetHudHint", InputSetHudHint ), +#endif END_DATADESC() @@ -140,3 +146,12 @@ void CEnvHudHint::InputHideHudHint( inputdata_t &inputdata ) MessageEnd(); } } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvHudHint::InputSetHudHint( inputdata_t &inputdata ) +{ + m_iszMessage = inputdata.value.StringID(); +} +#endif diff --git a/game/server/EnvLaser.cpp b/game/server/EnvLaser.cpp index 0e603db6..3db94e7c 100644 --- a/game/server/EnvLaser.cpp +++ b/game/server/EnvLaser.cpp @@ -31,6 +31,10 @@ BEGIN_DATADESC( CEnvLaser ) DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnTouchedByEntity, "OnTouchedByEntity" ), +#endif + END_DATADESC() @@ -221,6 +225,12 @@ void CEnvLaser::FireAtPoint( trace_t &tr ) // Apply damage and do sparks every 1/10th of a second. if ( gpGlobals->curtime >= m_flFireTime + 0.1 ) { +#ifdef MAPBASE + if ( tr.fraction != 1.0 && tr.m_pEnt && !tr.m_pEnt->IsWorld() ) + { + m_OnTouchedByEntity.FireOutput( tr.m_pEnt, this ); + } +#endif BeamDamage( &tr ); DoSparks( GetAbsStartPos(), tr.endpos ); } diff --git a/game/server/EnvLaser.h b/game/server/EnvLaser.h index 79165042..fc740442 100644 --- a/game/server/EnvLaser.h +++ b/game/server/EnvLaser.h @@ -37,6 +37,9 @@ class CEnvLaser : public CBeam void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); void InputToggle( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetTarget( inputdata_t &inputdata ) { m_iszLaserTarget = inputdata.value.StringID(); } +#endif DECLARE_DATADESC(); @@ -45,6 +48,10 @@ class CEnvLaser : public CBeam string_t m_iszSpriteName; Vector m_firePosition; +#ifdef MAPBASE + COutputEvent m_OnTouchedByEntity; +#endif + float m_flStartFrame; }; diff --git a/game/server/EnvMessage.cpp b/game/server/EnvMessage.cpp index a22dfc11..7725b67d 100644 --- a/game/server/EnvMessage.cpp +++ b/game/server/EnvMessage.cpp @@ -154,6 +154,9 @@ class CCredits : public CPointEntity DECLARE_DATADESC(); void Spawn( void ); +#ifdef MAPBASE + void PrecacheCreditsThink(); +#endif void InputRollCredits( inputdata_t &inputdata ); void InputRollOutroCredits( inputdata_t &inputdata ); void InputShowLogo( inputdata_t &inputdata ); @@ -168,6 +171,11 @@ class CCredits : public CPointEntity bool m_bRolledOutroCredits; float m_flLogoLength; + +#ifdef MAPBASE + // Custom credits.txt, defaults to that + string_t m_iszCreditsFile; +#endif }; LINK_ENTITY_TO_CLASS( env_credits, CCredits ); @@ -179,6 +187,12 @@ BEGIN_DATADESC( CCredits ) DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLogoLength", InputSetLogoLength ), DEFINE_OUTPUT( m_OnCreditsDone, "OnCreditsDone"), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszCreditsFile, FIELD_STRING, "CreditsFile" ), + + DEFINE_THINKFUNC( PrecacheCreditsThink ), +#endif + DEFINE_FIELD( m_bRolledOutroCredits, FIELD_BOOLEAN ), DEFINE_FIELD( m_flLogoLength, FIELD_FLOAT ) END_DATADESC() @@ -187,7 +201,34 @@ void CCredits::Spawn( void ) { SetSolid( SOLID_NONE ); SetMoveType( MOVETYPE_NONE ); + +#ifdef MAPBASE + // Ensures the player has time to spawn + SetContextThink( &CCredits::PrecacheCreditsThink, gpGlobals->curtime + 0.5f, "PrecacheCreditsContext" ); +#endif +} + +#ifdef MAPBASE +void CCredits::PrecacheCreditsThink() +{ + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if (!pPlayer) + { + Warning( "%s: No player\n", GetDebugName() ); + return; + } + + CSingleUserRecipientFilter user( pPlayer ); + user.MakeReliable(); + + UserMessageBegin( user, "CreditsMsg" ); + WRITE_BYTE( 4 ); + WRITE_STRING( STRING(m_iszCreditsFile) ); + MessageEnd(); + + SetContextThink( NULL, TICK_NEVER_THINK, "PrecacheCreditsContext" ); } +#endif static void CreditsDone_f( void ) { @@ -203,6 +244,10 @@ static ConCommand creditsdone("creditsdone", CreditsDone_f ); extern ConVar sv_unlockedchapters; +#ifdef MAPBASE +extern int Mapbase_GetChapterCount(); +#endif + void CCredits::OnRestore() { BaseClass::OnRestore(); @@ -217,6 +262,10 @@ void CCredits::OnRestore() void CCredits::RollOutroCredits() { +#ifdef MAPBASE + // Don't set this if we're using Mapbase chapters or if sv_unlockedchapters is already greater than 15 + if (Mapbase_GetChapterCount() <= 0 && sv_unlockedchapters.GetInt() < 15) +#endif sv_unlockedchapters.SetValue( "15" ); CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); @@ -226,6 +275,9 @@ void CCredits::RollOutroCredits() UserMessageBegin( user, "CreditsMsg" ); WRITE_BYTE( 3 ); +#ifdef MAPBASE + WRITE_STRING( STRING(m_iszCreditsFile) ); +#endif MessageEnd(); } @@ -250,12 +302,18 @@ void CCredits::InputShowLogo( inputdata_t &inputdata ) { UserMessageBegin( user, "LogoTimeMsg" ); WRITE_FLOAT( m_flLogoLength ); +#ifdef MAPBASE + WRITE_STRING( STRING(m_iszCreditsFile) ); +#endif MessageEnd(); } else { UserMessageBegin( user, "CreditsMsg" ); WRITE_BYTE( 1 ); +#ifdef MAPBASE + WRITE_STRING( STRING(m_iszCreditsFile) ); +#endif MessageEnd(); } } @@ -274,5 +332,8 @@ void CCredits::InputRollCredits( inputdata_t &inputdata ) UserMessageBegin( user, "CreditsMsg" ); WRITE_BYTE( 2 ); +#ifdef MAPBASE + WRITE_STRING( STRING(m_iszCreditsFile) ); +#endif MessageEnd(); } diff --git a/game/server/GameStats_BasicStatsFunctions.cpp b/game/server/GameStats_BasicStatsFunctions.cpp index 47e3de77..5656b6b7 100644 --- a/game/server/GameStats_BasicStatsFunctions.cpp +++ b/game/server/GameStats_BasicStatsFunctions.cpp @@ -155,7 +155,7 @@ bool BasicGameStats_t::ParseFromBuffer( CUtlBuffer& buf, int iBufferStatsVersion for ( int i = 0; i < c; ++i ) { char mapname[ 256 ]; - buf.GetString( mapname ); + buf.GetString( mapname, sizeof( mapname ) ); BasicGameStatsRecord_t *rec = FindOrAddRecordForMap( mapname ); bool valid= rec->ParseFromBuffer( buf, iBufferStatsVersion ); diff --git a/game/server/MaterialModifyControl.cpp b/game/server/MaterialModifyControl.cpp index 130a10bb..05d8714f 100644 --- a/game/server/MaterialModifyControl.cpp +++ b/game/server/MaterialModifyControl.cpp @@ -271,7 +271,7 @@ void CMaterialModifyControl::InputStartFloatLerp( inputdata_t &inputdata ) { bool bWrap = atoi(pszParam) != 0; // We don't implement wrap currently. - NOTE_UNUSED( bWrap ); + bWrap = bWrap; // Got all the parameters. Save 'em and return; m_flFloatLerpStartValue = flStartValue; diff --git a/game/server/RagdollBoogie.cpp b/game/server/RagdollBoogie.cpp index 6344b74a..0d54418d 100644 --- a/game/server/RagdollBoogie.cpp +++ b/game/server/RagdollBoogie.cpp @@ -15,6 +15,10 @@ #include "effect_dispatch_data.h" #include "te_effect_dispatch.h" #include "IEffects.h" +#ifdef MAPBASE +#include "saverestore_utlvector.h" +#include "interval.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -37,6 +41,10 @@ BEGIN_DATADESC( CRagdollBoogie ) // Think this should be handled by StartTouch/etc. // DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_FIELD( m_vecColor, FIELD_VECTOR ), +#endif + DEFINE_FUNCTION( BoogieThink ), DEFINE_FUNCTION( ZapThink ), @@ -50,7 +58,11 @@ LINK_ENTITY_TO_CLASS( env_ragdoll_boogie, CRagdollBoogie ); // Input : pTarget - //----------------------------------------------------------------------------- CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude, +#ifdef MAPBASE + float flStartTime, float flLengthTime, int nSpawnFlags, const Vector *vecColor ) +#else float flStartTime, float flLengthTime, int nSpawnFlags ) +#endif { CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( pTarget ); if ( !pRagdoll ) @@ -64,6 +76,10 @@ CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude, pBoogie->AttachToEntity( pTarget ); pBoogie->SetBoogieTime( flStartTime, flLengthTime ); pBoogie->SetMagnitude( flMagnitude ); +#ifdef MAPBASE + if (vecColor != NULL) + pBoogie->SetColor( *vecColor ); +#endif pBoogie->Spawn(); return pBoogie; } @@ -115,6 +131,13 @@ void CRagdollBoogie::ZapThink() data.m_nEntIndex = GetMoveParent()->entindex(); data.m_flMagnitude = 4; data.m_flScale = HasSpawnFlags(SF_RAGDOLL_BOOGIE_ELECTRICAL_NARROW_BEAM) ? 1.0f : 2.0f; +#ifdef MAPBASE + if (!m_vecColor.IsZero()) + { + data.m_bCustomColors = true; + data.m_CustomColors.m_vecColor1 = m_vecColor; + } +#endif DispatchEffect( "TeslaHitboxes", data ); } @@ -266,3 +289,190 @@ void CRagdollBoogie::BoogieThink( void ) SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Allows mappers to control ragdoll dancing +//----------------------------------------------------------------------------- +class CPointRagdollBoogie : public CBaseEntity +{ + DECLARE_DATADESC(); + DECLARE_CLASS( CPointRagdollBoogie, CBaseEntity ); + +public: + bool ApplyBoogie(CBaseEntity *pTarget, CBaseEntity *pActivator); + + void InputActivate( inputdata_t &inputdata ); + void InputDeactivate( inputdata_t &inputdata ); + void InputBoogieTarget( inputdata_t &inputdata ); + void InputSetZapColor( inputdata_t &inputdata ); + + bool KeyValue( const char *szKeyName, const char *szValue ); + +private: + float m_flStartTime; + interval_t m_BoogieLength; + float m_flMagnitude; + + Vector m_vecZapColor; + + // This allows us to change or remove active boogies later. + CUtlVector> m_Boogies; +}; + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- +BEGIN_DATADESC( CPointRagdollBoogie ) + + DEFINE_KEYFIELD( m_flStartTime, FIELD_FLOAT, "StartTime" ), + DEFINE_KEYFIELD( m_BoogieLength, FIELD_INTERVAL, "BoogieLength" ), + DEFINE_KEYFIELD( m_flMagnitude, FIELD_FLOAT, "Magnitude" ), + + DEFINE_KEYFIELD( m_vecZapColor, FIELD_VECTOR, "ZapColor" ), + + // Think this should be handled by StartTouch/etc. +// DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ), + + DEFINE_UTLVECTOR( m_Boogies, FIELD_EHANDLE ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), + DEFINE_INPUTFUNC( FIELD_STRING, "BoogieTarget", InputBoogieTarget ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetZapColor", InputSetZapColor ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( point_ragdollboogie, CPointRagdollBoogie ); + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +bool CPointRagdollBoogie::ApplyBoogie( CBaseEntity *pTarget, CBaseEntity *pActivator ) +{ + if (dynamic_cast(pTarget)) + { + m_Boogies.AddToTail(CRagdollBoogie::Create(pTarget, m_flMagnitude, gpGlobals->curtime + m_flStartTime, RandomInterval(m_BoogieLength), GetSpawnFlags(), &m_vecZapColor)); + } + else if (pTarget->MyCombatCharacterPointer()) + { + // Basically CBaseCombatCharacter::BecomeRagdollBoogie(), but adjusted to our needs + CTakeDamageInfo info(this, pActivator, 1.0f, DMG_GENERIC); + + CBaseEntity *pRagdoll = CreateServerRagdoll(pTarget->MyCombatCharacterPointer(), 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true); + + pRagdoll->SetCollisionBounds(CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs()); + + m_Boogies.AddToTail(CRagdollBoogie::Create(pRagdoll, m_flMagnitude, gpGlobals->curtime + m_flStartTime, RandomInterval(m_BoogieLength), GetSpawnFlags(), &m_vecZapColor)); + + CTakeDamageInfo ragdollInfo(this, pActivator, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL); + ragdollInfo.SetDamagePosition(WorldSpaceCenter()); + ragdollInfo.SetDamageForce(Vector(0, 0, 1)); + ragdollInfo.SetForceFriendlyFire(true); + pTarget->TakeDamage(ragdollInfo); + } + else + { + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPointRagdollBoogie::InputActivate( inputdata_t &inputdata ) +{ + CBaseEntity *pEnt = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + while (pEnt) + { + ApplyBoogie(pEnt, inputdata.pActivator); + + pEnt = gEntList.FindEntityByName(pEnt, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPointRagdollBoogie::InputDeactivate( inputdata_t &inputdata ) +{ + if (m_Boogies.Count() == 0) + return; + + for (int i = 0; i < m_Boogies.Count(); i++) + { + UTIL_Remove(m_Boogies[i]); + } + + m_Boogies.Purge(); + + //m_Boogies.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPointRagdollBoogie::InputBoogieTarget( inputdata_t &inputdata ) +{ + CBaseEntity *pEnt = gEntList.FindEntityByName(NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller); + while (pEnt) + { + if (!ApplyBoogie(pEnt, inputdata.pActivator)) + { + Warning("%s was unable to apply ragdoll boogie to %s, classname %s.\n", GetDebugName(), pEnt->GetDebugName(), pEnt->GetClassname()); + } + + pEnt = gEntList.FindEntityByName(pEnt, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPointRagdollBoogie::InputSetZapColor( inputdata_t &inputdata ) +{ + inputdata.value.Vector3D( m_vecZapColor ); + if (!m_vecZapColor.IsZero()) + { + // Turn into ratios of 255 + m_vecZapColor /= 255.0f; + } + + // Apply to existing boogies + for (int i = 0; i < m_Boogies.Count(); i++) + { + if (m_Boogies[i]) + { + m_Boogies[i]->SetColor( m_vecZapColor ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CPointRagdollBoogie::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "ZapColor" ) ) + { + UTIL_StringToVector(m_vecZapColor.Base(), szValue); + if (!m_vecZapColor.IsZero()) + { + // Turn into ratios of 255 + m_vecZapColor /= 255.0f; + } + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif diff --git a/game/server/RagdollBoogie.h b/game/server/RagdollBoogie.h index cb52c955..8ca99e81 100644 --- a/game/server/RagdollBoogie.h +++ b/game/server/RagdollBoogie.h @@ -28,10 +28,18 @@ class CRagdollBoogie : public CBaseEntity DECLARE_CLASS( CRagdollBoogie, CBaseEntity ); public: +#ifdef MAPBASE + static CRagdollBoogie *Create( CBaseEntity *pTarget, float flMagnitude, float flStartTime, float flLengthTime = 0.0f, int nSpawnFlags = 0, const Vector *vecColor = NULL ); +#else static CRagdollBoogie *Create( CBaseEntity *pTarget, float flMagnitude, float flStartTime, float flLengthTime = 0.0f, int nSpawnFlags = 0 ); +#endif static void IncrementSuppressionCount( CBaseEntity *pTarget ); static void DecrementSuppressionCount( CBaseEntity *pTarget ); +#ifdef MAPBASE + void SetColor( const Vector &vecColor ) { m_vecColor = vecColor; } +#endif + void Spawn(); private: @@ -45,6 +53,10 @@ class CRagdollBoogie : public CBaseEntity float m_flBoogieLength; float m_flMagnitude; int m_nSuppressionCount; + +#ifdef MAPBASE + Vector m_vecColor = Vector(1, 1, 1); +#endif }; #endif // RAGDOLLBOOGIE_H diff --git a/game/server/ServerNetworkProperty.cpp b/game/server/ServerNetworkProperty.cpp index 50641b2d..5bd93c18 100644 --- a/game/server/ServerNetworkProperty.cpp +++ b/game/server/ServerNetworkProperty.cpp @@ -108,9 +108,6 @@ IHandleEntity *CServerNetworkProperty::GetEntityHandle( ) void CServerNetworkProperty::Release() { delete m_pOuter; - // Don't zero m_pOuter or reference any member variables after - // the delete call because the object may be deleted. - //m_pOuter = NULL; } diff --git a/game/server/SkyCamera.cpp b/game/server/SkyCamera.cpp index 294c9c25..be9716d4 100644 --- a/game/server/SkyCamera.cpp +++ b/game/server/SkyCamera.cpp @@ -15,13 +15,24 @@ // automatically hooks in the system's callbacks CEntityClassList g_SkyList; template <> CSkyCamera *CEntityClassList::m_pClassList = NULL; +#ifdef MAPBASE +CHandle g_hActiveSkybox = NULL; +#endif //----------------------------------------------------------------------------- // Retrives the current skycamera //----------------------------------------------------------------------------- CSkyCamera* GetCurrentSkyCamera() { +#ifdef MAPBASE + if ( g_hActiveSkybox.Get() == NULL ) + { + g_hActiveSkybox = GetSkyCameraList(); + } + return g_hActiveSkybox.Get(); +#else return g_SkyList.m_pClassList; +#endif } CSkyCamera* GetSkyCameraList() @@ -38,6 +49,12 @@ BEGIN_DATADESC( CSkyCamera ) DEFINE_KEYFIELD( m_skyboxData.scale, FIELD_INTEGER, "scale" ), DEFINE_FIELD( m_skyboxData.origin, FIELD_VECTOR ), DEFINE_FIELD( m_skyboxData.area, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_FIELD( m_skyboxData.angles, FIELD_VECTOR ), + DEFINE_FIELD( m_skyboxData.skycamera, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_skyboxData.skycolor, FIELD_COLOR32, "skycolor" ), + DEFINE_KEYFIELD( m_bUseAnglesForSky, FIELD_BOOLEAN, "use_angles_for_sky" ), +#endif // Quiet down classcheck // DEFINE_FIELD( m_skyboxData, sky3dparams_t ), @@ -55,6 +72,36 @@ BEGIN_DATADESC( CSkyCamera ) DEFINE_KEYFIELD( m_skyboxData.fog.start, FIELD_FLOAT, "fogstart" ), DEFINE_KEYFIELD( m_skyboxData.fog.end, FIELD_FLOAT, "fogend" ), DEFINE_KEYFIELD( m_skyboxData.fog.maxdensity, FIELD_FLOAT, "fogmaxdensity" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_skyboxData.fog.farz, FIELD_FLOAT, "farz" ), +#endif + +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "ForceUpdate", InputForceUpdate ), + DEFINE_INPUTFUNC( FIELD_VOID, "StartUpdating", InputStartUpdating ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopUpdating", InputStopUpdating ), + + DEFINE_INPUTFUNC( FIELD_VOID, "ActivateSkybox", InputActivateSkybox ), + DEFINE_INPUTFUNC( FIELD_VOID, "DeactivateSkybox", InputDeactivateSkybox ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFogStartDist", InputSetFogStartDist ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFogEndDist", InputSetFogEndDist ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFogMaxDensity", InputSetFogMaxDensity ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOnFog", InputTurnOnFog ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOffFog", InputTurnOffFog ), + DEFINE_INPUTFUNC( FIELD_COLOR32, "SetFogColor", InputSetFogColor ), + DEFINE_INPUTFUNC( FIELD_COLOR32, "SetFogColorSecondary", InputSetFogColorSecondary ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "CopyFogController", InputCopyFogController ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "CopyFogControllerWithScale", InputCopyFogControllerWithScale ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetFarZ", InputSetFarZ ), + + DEFINE_INPUTFUNC( FIELD_COLOR32, "SetSkyColor", InputSetSkyColor ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetScale", InputSetScale ), + + DEFINE_THINKFUNC( UpdateThink ), +#endif END_DATADESC() @@ -93,6 +140,9 @@ CSkyCamera::CSkyCamera() { g_SkyList.Insert( this ); m_skyboxData.fog.maxdensity = 1.0f; +#ifdef MAPBASE + m_skyboxData.skycolor.Init(0, 0, 0, 0); +#endif } CSkyCamera::~CSkyCamera() @@ -102,7 +152,24 @@ CSkyCamera::~CSkyCamera() void CSkyCamera::Spawn( void ) { +#ifdef MAPBASE + if (HasSpawnFlags(SF_SKY_MASTER)) + g_hActiveSkybox = this; + + if (HasSpawnFlags(SF_SKY_START_UPDATING)) + { + SetCameraEntityMode(); + + SetThink( &CSkyCamera::UpdateThink ); + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } + else + { + SetCameraPositionMode(); + } +#else m_skyboxData.origin = GetLocalOrigin(); +#endif m_skyboxData.area = engine->GetArea( m_skyboxData.origin ); Precache(); @@ -145,3 +212,251 @@ void CSkyCamera::Activate( ) } #endif } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CSkyCamera::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ) +{ + if (!BaseClass::AcceptInput( szInputName, pActivator, pCaller, Value, outputID )) + return false; + + if (g_hActiveSkybox == this) + { + // Most inputs require an update + DoUpdate( true ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSkyCamera::SetCameraEntityMode() +{ + m_skyboxData.skycamera = this; + + // Ensure the viewrender knows whether this should be using angles + if (m_bUseAnglesForSky) + m_skyboxData.angles.SetX( 1 ); + else + m_skyboxData.angles.SetX( 0 ); +} + +void CSkyCamera::SetCameraPositionMode() +{ + // Must be absolute now that the sky_camera can be parented + m_skyboxData.skycamera = NULL; + m_skyboxData.origin = GetAbsOrigin(); + if (m_bUseAnglesForSky) + m_skyboxData.angles = GetAbsAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: Update sky position mid-game +//----------------------------------------------------------------------------- +bool CSkyCamera::DoUpdate( bool bUpdateData ) +{ + // Now that sky camera updating uses an entity handle directly transmitted to the client, + // this thinking is only used to update area and other parameters + + // Getting into another area is unlikely, but if it's not expensive, I guess it's okay. + int area = engine->GetArea( GetAbsOrigin() ); + if (m_skyboxData.area != area) + { + m_skyboxData.area = area; + bUpdateData = true; + } + + if ( m_bUseAngles ) + { + Vector fogForward; + AngleVectors( GetAbsAngles(), &fogForward ); + fogForward *= -1.0f; + + if ( m_skyboxData.fog.dirPrimary.Get() != fogForward ) + { + m_skyboxData.fog.dirPrimary = fogForward; + bUpdateData = true; + } + } + + if (bUpdateData) + { + // Updates client data, this completely ignores m_pOldSkyCamera + CBasePlayer *pPlayer = NULL; + for (int i = 1; i <= gpGlobals->maxClients; i++) + { + pPlayer = UTIL_PlayerByIndex(i); + if (pPlayer) + pPlayer->m_Local.m_skybox3d.CopyFrom(m_skyboxData); + } + } + + // Needed for entity interpolation + SetSimulationTime( gpGlobals->curtime ); + + return bUpdateData; +} + +void CSkyCamera::UpdateThink() +{ + if (DoUpdate()) + { + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } + else + { + SetNextThink( gpGlobals->curtime + 0.2f ); + } +} + +void CSkyCamera::InputForceUpdate( inputdata_t &inputdata ) +{ + if (m_skyboxData.skycamera == NULL) + { + m_skyboxData.origin = GetAbsOrigin(); + if (m_bUseAnglesForSky) + m_skyboxData.angles = GetAbsAngles(); + } + + DoUpdate( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSkyCamera::InputStartUpdating( inputdata_t &inputdata ) +{ + if (GetCurrentSkyCamera() == this) + { + SetCameraEntityMode(); + DoUpdate( true ); + + SetThink( &CSkyCamera::UpdateThink ); + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } + + // If we become the current sky camera later, remember that we want to update + AddSpawnFlags( SF_SKY_START_UPDATING ); + + // Must update transmit state so we show up on the client + DispatchUpdateTransmitState(); +} + +void CSkyCamera::InputStopUpdating( inputdata_t &inputdata ) +{ + SetThink( NULL ); + SetNextThink( TICK_NEVER_THINK ); + RemoveSpawnFlags( SF_SKY_START_UPDATING ); + DispatchUpdateTransmitState(); + + SetCameraPositionMode(); + DoUpdate( true ); +} + +//----------------------------------------------------------------------------- +// Activate! +//----------------------------------------------------------------------------- +void CSkyCamera::InputActivateSkybox( inputdata_t &inputdata ) +{ + CSkyCamera *pActiveSky = GetCurrentSkyCamera(); + if (pActiveSky && pActiveSky->GetNextThink() != TICK_NEVER_THINK && pActiveSky != this) + { + // Deactivate that skybox + pActiveSky->SetThink( NULL ); + pActiveSky->SetNextThink( TICK_NEVER_THINK ); + } + + g_hActiveSkybox = this; + + if (HasSpawnFlags( SF_SKY_START_UPDATING )) + InputStartUpdating( inputdata ); +} + +//----------------------------------------------------------------------------- +// Deactivate! +//----------------------------------------------------------------------------- +void CSkyCamera::InputDeactivateSkybox( inputdata_t &inputdata ) +{ + if (GetCurrentSkyCamera() == this) + { + g_hActiveSkybox = NULL; + + // ClientData doesn't catch this immediately + CBasePlayer *pPlayer = NULL; + for (int i = 1; i <= gpGlobals->maxClients; i++) + { + pPlayer = UTIL_PlayerByIndex( i ); + if (pPlayer) + pPlayer->m_Local.m_skybox3d.area = 255; + } + } + + SetThink( NULL ); + SetNextThink( TICK_NEVER_THINK ); +} + +//------------------------------------------------------------------------------ +// Purpose: Input handlers for setting fog stuff. +//------------------------------------------------------------------------------ +void CSkyCamera::InputSetFogStartDist( inputdata_t &inputdata ) { m_skyboxData.fog.start = inputdata.value.Float(); } +void CSkyCamera::InputSetFogEndDist( inputdata_t &inputdata ) { m_skyboxData.fog.end = inputdata.value.Float(); } +void CSkyCamera::InputSetFogMaxDensity( inputdata_t &inputdata ) { m_skyboxData.fog.maxdensity = inputdata.value.Float(); } +void CSkyCamera::InputTurnOnFog( inputdata_t &inputdata ) { m_skyboxData.fog.enable = true; } +void CSkyCamera::InputTurnOffFog( inputdata_t &inputdata ) { m_skyboxData.fog.enable = false; } +void CSkyCamera::InputSetFogColor( inputdata_t &inputdata ) { m_skyboxData.fog.colorPrimary = inputdata.value.Color32(); } +void CSkyCamera::InputSetFogColorSecondary( inputdata_t &inputdata ) { m_skyboxData.fog.colorSecondary = inputdata.value.Color32(); } + +void CSkyCamera::InputSetFarZ( inputdata_t &inputdata ) { m_skyboxData.fog.farz = inputdata.value.Int(); } + +void CSkyCamera::InputCopyFogController( inputdata_t &inputdata ) +{ + CFogController *pFogController = dynamic_cast(inputdata.value.Entity().Get()); + if (!pFogController) + return; + + m_skyboxData.fog.dirPrimary = pFogController->m_fog.dirPrimary; + m_skyboxData.fog.colorPrimary = pFogController->m_fog.colorPrimary; + m_skyboxData.fog.colorSecondary = pFogController->m_fog.colorSecondary; + //m_skyboxData.fog.colorPrimaryLerpTo = pFogController->m_fog.colorPrimaryLerpTo; + //m_skyboxData.fog.colorSecondaryLerpTo = pFogController->m_fog.colorSecondaryLerpTo; + m_skyboxData.fog.start = pFogController->m_fog.start; + m_skyboxData.fog.end = pFogController->m_fog.end; + m_skyboxData.fog.farz = pFogController->m_fog.farz; + m_skyboxData.fog.maxdensity = pFogController->m_fog.maxdensity; + + //m_skyboxData.fog.startLerpTo = pFogController->m_fog.startLerpTo; + //m_skyboxData.fog.endLerpTo = pFogController->m_fog.endLerpTo; + //m_skyboxData.fog.lerptime = pFogController->m_fog.lerptime; + //m_skyboxData.fog.duration = pFogController->m_fog.duration; + //m_skyboxData.fog.enable = pFogController->m_fog.enable; + m_skyboxData.fog.blend = pFogController->m_fog.blend; +} + +void CSkyCamera::InputCopyFogControllerWithScale( inputdata_t &inputdata ) +{ + CFogController *pFogController = dynamic_cast(inputdata.value.Entity().Get()); + if (!pFogController) + return; + + m_skyboxData.fog.dirPrimary = pFogController->m_fog.dirPrimary; + m_skyboxData.fog.colorPrimary = pFogController->m_fog.colorPrimary; + m_skyboxData.fog.colorSecondary = pFogController->m_fog.colorSecondary; + //m_skyboxData.fog.colorPrimaryLerpTo = pFogController->m_fog.colorPrimaryLerpTo; + //m_skyboxData.fog.colorSecondaryLerpTo = pFogController->m_fog.colorSecondaryLerpTo; + m_skyboxData.fog.start = pFogController->m_fog.start * m_skyboxData.scale; + m_skyboxData.fog.end = pFogController->m_fog.end * m_skyboxData.scale; + m_skyboxData.fog.farz = pFogController->m_fog.farz != -1 ? (pFogController->m_fog.farz * m_skyboxData.scale) : pFogController->m_fog.farz; + m_skyboxData.fog.maxdensity = pFogController->m_fog.maxdensity; + + //m_skyboxData.fog.startLerpTo = pFogController->m_fog.startLerpTo; + //m_skyboxData.fog.endLerpTo = pFogController->m_fog.endLerpTo; + //m_skyboxData.fog.lerptime = pFogController->m_fog.lerptime; + //m_skyboxData.fog.duration = pFogController->m_fog.duration; + //m_skyboxData.fog.enable = pFogController->m_fog.enable; + m_skyboxData.fog.blend = pFogController->m_fog.blend; +} +#endif diff --git a/game/server/SkyCamera.h b/game/server/SkyCamera.h index 8032d8fd..a1936568 100644 --- a/game/server/SkyCamera.h +++ b/game/server/SkyCamera.h @@ -14,13 +14,30 @@ class CSkyCamera; +#ifdef MAPBASE +#define SF_SKY_MASTER (1 << 0) +#define SF_SKY_START_UPDATING (1 << 1) + +//============================================================================= +// +// Sky Camera Class +// Now derived directly from CBaseEntity for parenting and angles! (please don't break anything) +// +//============================================================================= +class CSkyCamera : public CBaseEntity +#else //============================================================================= // // Sky Camera Class // class CSkyCamera : public CLogicalEntity +#endif { +#ifdef MAPBASE + DECLARE_CLASS( CSkyCamera, CBaseEntity ); +#else DECLARE_CLASS( CSkyCamera, CLogicalEntity ); +#endif public: @@ -30,9 +47,48 @@ class CSkyCamera : public CLogicalEntity virtual void Spawn( void ); virtual void Activate(); +#ifdef MAPBASE + bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ); + + int UpdateTransmitState() { return HasSpawnFlags( SF_SKY_START_UPDATING ) ? SetTransmitState( FL_EDICT_ALWAYS ) : BaseClass::UpdateTransmitState(); } + + void SetCameraEntityMode(); + void SetCameraPositionMode(); + + bool DoUpdate( bool bUpdateData = false ); + void UpdateThink(); + + void InputForceUpdate( inputdata_t &inputdata ); + void InputStartUpdating( inputdata_t &inputdata ); + void InputStopUpdating( inputdata_t &inputdata ); + + void InputActivateSkybox( inputdata_t &inputdata ); + void InputDeactivateSkybox( inputdata_t &inputdata ); + + void InputSetFogStartDist( inputdata_t &data ); + void InputSetFogEndDist( inputdata_t &data ); + void InputTurnOnFog( inputdata_t &data ); + void InputTurnOffFog( inputdata_t &data ); + void InputSetFogColor( inputdata_t &data ); + void InputSetFogColorSecondary( inputdata_t &data ); + void InputSetFogMaxDensity( inputdata_t &inputdata ); + void InputCopyFogController( inputdata_t &inputdata ); + void InputCopyFogControllerWithScale( inputdata_t &inputdata ); + + void InputSetFarZ( inputdata_t &data ); + + void InputSetSkyColor( inputdata_t &inputdata ) { m_skyboxData.skycolor = inputdata.value.Color32(); } + + void InputSetScale( inputdata_t &inputdata ) { m_skyboxData.scale = inputdata.value.Int(); } +#endif + public: sky3dparams_t m_skyboxData; bool m_bUseAngles; +#ifdef MAPBASE + // Uses angles for actual skybox + bool m_bUseAnglesForSky; +#endif CSkyCamera *m_pNext; }; diff --git a/game/server/TemplateEntities.cpp b/game/server/TemplateEntities.cpp index a5092904..b2a54fd1 100644 --- a/game/server/TemplateEntities.cpp +++ b/game/server/TemplateEntities.cpp @@ -159,6 +159,70 @@ string_t Templates_FindByTargetName(const char *pszName) return NULL_STRING; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: A new version of name fixup which targets all instances of a name +// in a keyvalue, including output parameters. +//----------------------------------------------------------------------------- +void Templates_NewNameFixup( CUtlVector< grouptemplate_t > &GroupTemplates, int i, int iCount, CEntityMapData *mapData, CUtlDict< int, int > &KeyInstanceCount, char *keyName, char *value ) +{ + do + { + // Ignore targetnames + if ( !stricmp( keyName, "targetname" ) ) + continue; + + // Add to the count for this + int idx = KeyInstanceCount.Find( keyName ); + if ( idx == KeyInstanceCount.InvalidIndex() ) + { + idx = KeyInstanceCount.Insert( keyName, 0 ); + } + KeyInstanceCount[idx]++; + + // Loop through our group templates + for ( int iTName = 0; iTName < iCount; iTName++ ) + { + char *pName = GroupTemplates[iTName].pszName; + if (strstr( value, pName ) == NULL) + continue; + + if ( template_debug.GetInt() ) + { + Msg("Template Connection Found: Key %s (\"%s\") in entity named \"%s\"(%d) matches entity %d's targetname\n", keyName, value, GroupTemplates[i].pszName, i, iTName ); + } + + char newvalue[MAPKEY_MAXLENGTH]; + char fixedup[MAPKEY_MAXLENGTH]; + Q_strncpy( fixedup, pName, MAPKEY_MAXLENGTH ); + Q_strncat( fixedup, ENTITYIO_FIXUP_STRING, sizeof( fixedup ), COPY_ALL_CHARACTERS ); + + // Get the current key instance. (-1 because it's this one we're changing) + int nKeyInstance = KeyInstanceCount[idx] - 1; + + // Add our IO value to the targetname + V_StrSubst( value, pName, fixedup, newvalue, MAPKEY_MAXLENGTH ); + + if ( template_debug.GetInt() ) + { + Msg(" Fixed up value: Key %s with \"%s\" in entity named \"%s\"(%d) has become \"%s\"\n", keyName, value, GroupTemplates[i].pszName, i, newvalue ); + } + + mapData->SetValue( keyName, newvalue, nKeyInstance ); + Q_strncpy( value, newvalue, MAPKEY_MAXLENGTH ); + + // Remember we changed this targetname + GroupTemplates[iTName].bChangeTargetname = true; + + // Set both entity's flags telling them their template needs fixup when it's spawned + g_Templates[ GroupTemplates[i].iIndex ]->bNeedsEntityIOFixup = true; + g_Templates[ GroupTemplates[iTName].iIndex ]->bNeedsEntityIOFixup = true; + } + } + while ( mapData->GetNextKey(keyName, value) ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: A CPointTemplate has asked us to reconnect all the entity I/O links // inside it's templates. Go through the keys and add look for values @@ -208,6 +272,14 @@ void Templates_ReconnectIOForGroup( CPointTemplate *pGroup ) if ( !mapData->GetFirstKey(keyName, value) ) continue; +#ifdef MAPBASE + if ( pGroup->NameFixupExpanded() ) + { + Templates_NewNameFixup( GroupTemplates, i, iCount, mapData, KeyInstanceCount, keyName, value ); + continue; + } +#endif + do { // Ignore targetnames @@ -326,7 +398,9 @@ void Templates_StartUniqueInstance( void ) //----------------------------------------------------------------------------- char *Templates_GetEntityIOFixedMapData( int iIndex ) { +#ifndef MAPBASE // This code also runs when the point_template's script scope is active Assert( Templates_IndexRequiresEntityIOFixup( iIndex ) ); +#endif // First time through? if ( !g_Templates[iIndex]->pszFixedMapData ) diff --git a/game/server/ai_activity.cpp b/game/server/ai_activity.cpp index 8f821962..eaedab9e 100644 --- a/game/server/ai_activity.cpp +++ b/game/server/ai_activity.cpp @@ -22,7 +22,7 @@ int CAI_BaseNPC::m_iNumActivities = 0; // Purpose: Add an activity to the activity string registry and increment // the acitivty counter //----------------------------------------------------------------------------- -void CAI_BaseNPC::AddActivityToSR(const char *actName, int actID) +void CAI_BaseNPC::AddActivityToSR(const char *actName, int actID) { Assert( m_pActivitySR ); if ( !m_pActivitySR ) @@ -48,13 +48,13 @@ void CAI_BaseNPC::AddActivityToSR(const char *actName, int actID) //----------------------------------------------------------------------------- // Purpose: Given and activity ID, return the activity name //----------------------------------------------------------------------------- -const char *CAI_BaseNPC::GetActivityName(int actID) +const char *CAI_BaseNPC::GetActivityName(int actID) { if ( actID == -1 ) return "ACT_INVALID"; // m_pActivitySR only contains public activities, ActivityList_NameForIndex() has them all - const char *name = ActivityList_NameForIndex(actID); + const char *name = ActivityList_NameForIndex(actID); if( !name ) { @@ -67,7 +67,7 @@ const char *CAI_BaseNPC::GetActivityName(int actID) //----------------------------------------------------------------------------- // Purpose: Given and activity name, return the activity ID //----------------------------------------------------------------------------- -int CAI_BaseNPC::GetActivityID(const char* actName) +int CAI_BaseNPC::GetActivityID(const char* actName) { Assert( m_pActivitySR ); if ( !m_pActivitySR ) @@ -81,7 +81,7 @@ int CAI_BaseNPC::GetActivityID(const char* actName) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CAI_BaseNPC::InitDefaultActivitySR(void) +void CAI_BaseNPC::InitDefaultActivitySR(void) { ADD_ACTIVITY_TO_SR( ACT_INVALID ); ADD_ACTIVITY_TO_SR( ACT_RESET ); @@ -173,7 +173,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_WALK_STIMULATED ); ADD_ACTIVITY_TO_SR( ACT_WALK_AGITATED ); ADD_ACTIVITY_TO_SR( ACT_WALK_STEALTH ); - + ADD_ACTIVITY_TO_SR( ACT_RUN_RELAXED ); ADD_ACTIVITY_TO_SR( ACT_RUN_STIMULATED ); ADD_ACTIVITY_TO_SR( ACT_RUN_AGITATED ); @@ -206,7 +206,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_WALK_SCARED ); ADD_ACTIVITY_TO_SR( ACT_RUN_SCARED ); ADD_ACTIVITY_TO_SR( ACT_VICTORY_DANCE ); - + ADD_ACTIVITY_TO_SR( ACT_DIE_HEADSHOT ); ADD_ACTIVITY_TO_SR( ACT_DIE_CHESTSHOT ); ADD_ACTIVITY_TO_SR( ACT_DIE_GUTSHOT ); @@ -487,15 +487,15 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) // RPG activities ADD_ACTIVITY_TO_SR( ACT_IDLE_RPG_RELAXED ); - ADD_ACTIVITY_TO_SR( ACT_IDLE_RPG ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_RPG ); ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_RPG ); - ADD_ACTIVITY_TO_SR( ACT_COVER_LOW_RPG ); + ADD_ACTIVITY_TO_SR( ACT_COVER_LOW_RPG ); ADD_ACTIVITY_TO_SR( ACT_WALK_RPG ); - ADD_ACTIVITY_TO_SR( ACT_RUN_RPG ); - ADD_ACTIVITY_TO_SR( ACT_WALK_CROUCH_RPG ); - ADD_ACTIVITY_TO_SR( ACT_RUN_CROUCH_RPG ); - ADD_ACTIVITY_TO_SR( ACT_WALK_RPG_RELAXED ); - ADD_ACTIVITY_TO_SR( ACT_RUN_RPG_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_RPG ); + ADD_ACTIVITY_TO_SR( ACT_WALK_CROUCH_RPG ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROUCH_RPG ); + ADD_ACTIVITY_TO_SR( ACT_WALK_RPG_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_RPG_RELAXED ); ADD_ACTIVITY_TO_SR( ACT_WALK_RIFLE ); ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_RIFLE ); @@ -721,7 +721,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_DEEPIDLE3 ); ADD_ACTIVITY_TO_SR( ACT_DEEPIDLE4 ); - ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_DEPLOYED ); + ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_DEPLOYED ); ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_IDLE ); ADD_ACTIVITY_TO_SR( ACT_VM_DRAW_DEPLOYED ); @@ -790,7 +790,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_8 ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_7 ); - ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_6 ); + ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_6 ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_5 ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_4 ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_DEPLOYED_3 ); @@ -810,7 +810,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_DOD_PRIMARYATTACK_DEPLOYED ); ADD_ACTIVITY_TO_SR( ACT_DOD_PRIMARYATTACK_PRONE_DEPLOYED ); ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_DEPLOYED ); - ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_DEPLOYED ); + ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_DEPLOYED ); ADD_ACTIVITY_TO_SR( ACT_DOD_PRIMARYATTACK_PRONE ); ADD_ACTIVITY_TO_SR( ACT_DOD_SECONDARYATTACK_PRONE ); ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_CROUCH ); @@ -1223,7 +1223,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_RIFLE ); ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_RIFLEGRENADE ); ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_C96 ); - + // Prone bazooka ADD_ACTIVITY_TO_SR( ACT_DOD_RELOAD_PRONE_BAZOOKA ); ADD_ACTIVITY_TO_SR( ACT_DOD_ZOOMLOAD_PRONE_BAZOOKA ); @@ -1291,7 +1291,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) //=========================== // HL2MP Specific Activities //=========================== - + ADD_ACTIVITY_TO_SR ( ACT_HL2MP_IDLE ); ADD_ACTIVITY_TO_SR ( ACT_HL2MP_RUN ); ADD_ACTIVITY_TO_SR ( ACT_HL2MP_IDLE_CROUCH ); @@ -1479,8 +1479,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_STAND_PRIMARY_2 ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_STAND_PRIMARY_LOOP_2 ); - ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_STAND_PRIMARY_END_2 ); - ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY_2 ); + ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_STAND_PRIMARY_END_2 ); + ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY_2 ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY_LOOP_2 ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY_END_2 ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_SWIM_PRIMARY_2 ); @@ -1686,11 +1686,6 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_ATTACK_SWIM_GRENADE_ITEM2 ); ADD_ACTIVITY_TO_SR( ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2 ); - // Passtime - ADD_ACTIVITY_TO_SR( ACT_MP_STAND_PASSTIME ); - ADD_ACTIVITY_TO_SR( ACT_MP_RUN_PASSTIME ); - ADD_ACTIVITY_TO_SR( ACT_MP_CROUCHWALK_PASSTIME ); - // Flinches ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_FLINCH ); ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_FLINCH_PRIMARY ); @@ -1831,7 +1826,6 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_ITEM1 ); ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_ITEM2 ); ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE ); - ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME ); ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_VC_HANDMOUTH ); ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_VC_FINGERPOINT ); @@ -1893,11 +1887,6 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_STUN_MIDDLE ); ADD_ACTIVITY_TO_SR( ACT_MP_STUN_END ); - ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_BEGIN ); - ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_MIDDLE ); - ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_END ); - ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_CANCEL ); - ADD_ACTIVITY_TO_SR( ACT_VM_UNUSABLE ); ADD_ACTIVITY_TO_SR( ACT_VM_UNUSABLE_TO_USABLE ); ADD_ACTIVITY_TO_SR( ACT_VM_USABLE_TO_UNUSABLE ); @@ -1908,20 +1897,20 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_FINISH ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_FINISH ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_LOWERED_TO_IDLE ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_RELOAD_2 ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START_2 ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START_2 ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_FINISH_2 ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_RELOAD_3 ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START_3 ); + ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_START_3 ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_RELOAD_FINISH_3 ); ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_PRIMARYATTACK_3 ); @@ -1931,11 +1920,11 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_RELOAD ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_RELOAD_START ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_RELOAD_FINISH ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_RELOAD2 ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_RELOAD2 ); + ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_LOWERED_TO_IDLE ); @@ -1951,8 +1940,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_LOWERED_TO_IDLE ); @@ -1966,8 +1955,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_PDA_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_PDA_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_PDA_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_PDA_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_PDA_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_PDA_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_PDA_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_PDA_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_PDA_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_PDA_VM_LOWERED_TO_IDLE ); @@ -1986,19 +1975,19 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_LOWERED_TO_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_RELOAD_START ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_RELOAD_FINISH ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_HITCENTER ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_SWINGHARD ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_UP ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_DOWN ); - ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_ITEM1_STUN ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_RELOAD_START ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_RELOAD_FINISH ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_HITCENTER ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_VM_SWINGHARD ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_UP ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_DOWN ); + ADD_ACTIVITY_TO_SR( ACT_ITEM1_BACKSTAB_VM_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_ITEM1_STUN ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_DRAW ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_HOLSTER ); @@ -2006,8 +1995,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_LOWERED_TO_IDLE ); @@ -2017,10 +2006,10 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_CHARGE_IDLE_3 ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_HITCENTER ); ADD_ACTIVITY_TO_SR( ACT_ITEM2_VM_SWINGHARD ); - ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_UP ); - ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_DOWN ); - ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_ITEM2_STUN ); + ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_UP ); + ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_DOWN ); + ADD_ACTIVITY_TO_SR( ACT_ITEM2_BACKSTAB_VM_IDLE ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_ITEM2_STUN ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_DRAW ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_HOLSTER ); @@ -2028,8 +2017,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_ITEM3_VM_LOWERED_TO_IDLE ); @@ -2046,10 +2035,10 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_SECONDARY2ATTACK ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_RELOAD ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_RELOAD_START ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_RELOAD_FINISH ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_RELOAD2 ); + ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_RELOAD2 ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_SECONDARY2_VM_IDLE_LOWERED ); @@ -2124,13 +2113,13 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_PULLBACK ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_PRIMARYATTACK ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_SECONDARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_RELOAD ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_DRYFIRE ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_RELOAD ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_DRYFIRE ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_IDLE_TO_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_IDLE_LOWERED ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_LOWERED_TO_IDLE ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_STUN ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_HITCENTER ); + ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_HITCENTER ); ADD_ACTIVITY_TO_SR( ACT_MELEE_ALLCLASS_VM_SWINGHARD ); ADD_ACTIVITY_TO_SR( ACT_MP_STAND_BOMB ); @@ -2145,8 +2134,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_VM_PULLBACK_QRL ); ADD_ACTIVITY_TO_SR( ACT_VM_PRIMARYATTACK_QRL ); ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_QRL ); - ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_START_QRL ); - ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_FINISH_QRL ); + ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_START_QRL ); + ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_FINISH_QRL ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_STAND_PRIMARY3 ); ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY3 ); @@ -2160,7 +2149,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_SWIM_PRIMARY3 ); ADD_ACTIVITY_TO_SR( ACT_MP_THROW ); - ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_DRAW ); + ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_DRAW ); ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_IDLE ); ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_FIRE ); @@ -2169,90 +2158,718 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_ARM ); ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_FIRE ); - ADD_ACTIVITY_TO_SR( ACT_BREADSAPPER_VM_DRAW ); - ADD_ACTIVITY_TO_SR( ACT_BREADSAPPER_VM_IDLE ); - - ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_HITLEFT ); - ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_HITRIGHT ); - ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_SWINGHARD ); - ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_BREADGLOVES_VM_DRAW ); - - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_HITRIGHT ); - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_GLOVES_HITUP ); - - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_DRAW ); - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_BREADMONSTER_VM_PRIMARYATTACK ); - - ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_DEPLOY ); - ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_DEPLOY_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_RETRACT ); - ADD_ACTIVITY_TO_SR( ACT_PARACHUTE_RETRACT_IDLE ); - - ADD_ACTIVITY_TO_SR( ACT_BOT_SPAWN ); - ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC ); - ADD_ACTIVITY_TO_SR( ACT_BOT_PRIMARY_MOVEMENT ); - ADD_ACTIVITY_TO_SR( ACT_BOT_GESTURE_FLINCH ); - ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_START ); - ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_END ); - - ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_DRAW ); - ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_PRIMARYATTACK ); - ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_RELOAD ); - - ADD_ACTIVITY_TO_SR( ACT_KART_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_KART_ACTION_SHOOT ); - ADD_ACTIVITY_TO_SR( ACT_KART_ACTION_DASH ); - ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_START ); - ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_FLOAT ); - ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_LAND ); - ADD_ACTIVITY_TO_SR( ACT_KART_IMPACT ); - ADD_ACTIVITY_TO_SR( ACT_KART_IMPACT_BIG ); - ADD_ACTIVITY_TO_SR( ACT_KART_GESTURE_POSITIVE ); - ADD_ACTIVITY_TO_SR( ACT_KART_GESTURE_NEGATIVE ); - - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_DRAW ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_FIRE_START ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_FIRE_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_START ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_END ); - - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_START ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_END ); - - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_START ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_END ); - - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_START ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_IDLE ); - ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_END ); +#if AR2_ACTIVITY_FIX == 1 + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_AR2 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR2_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_WALK_AR2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR2_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_AR2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR2_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_WALK_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR2 ); + + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR2_LOW ); + + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_AR2 ); + + ADD_ACTIVITY_TO_SR( ACT_COVER_AR2_LOW ); +#endif + +#if SHARED_COMBINE_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_COMBINE_THROW_GRENADE ); + ADD_ACTIVITY_TO_SR( ACT_COMBINE_AR2_ALTFIRE ); + + ADD_ACTIVITY_TO_SR( ACT_GESTURE_COMBINE_THROW_GRENADE ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_COMBINE_AR2_ALTFIRE ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SPECIAL_ATTACK1 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SPECIAL_ATTACK2 ); + + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_ADVANCE ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_FORWARD ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_GROUP ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_HALT ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_LEFT ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_RIGHT ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_SIGNAL_TAKECOVER ); +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_IDLE_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_WALK_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_RUN_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_REVOLVER_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_REVOLVER_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_REVOLVER_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_REVOLVER_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_REVOLVER ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_WALK_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_CROSSBOW_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_CROSSBOW_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_CROSSBOW_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_CROSSBOW_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_CROSSBOW ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_CROSSBOW_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_CROSSBOW_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_CROSSBOW_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROSSBOW_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_CROSSBOW_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROSSBOW_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_CROSSBOW_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_CROSSBOW_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_CROSSBOW_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_PISTOL_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_PISTOL_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_PISTOL_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_PISTOL_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_PISTOL_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_PISTOL_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_PISTOL_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_PISTOL_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_PISTOL_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_WALK_CROUCH_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_WALK_CROUCH_AIM_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROUCH_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_RUN_CROUCH_AIM_PISTOL ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SHOTGUN ); + + ADD_ACTIVITY_TO_SR( ACT_COVER_SHOTGUN_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SHOTGUN_LOW ); + + ADD_ACTIVITY_TO_SR( ACT_WALK_SHOTGUN_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SHOTGUN_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SHOTGUN_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SHOTGUN_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SHOTGUN_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SHOTGUN_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SHOTGUN_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_RPG_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_RPG_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_RPG ); + + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_ANNABELLE ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_ANNABELLE_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_ANNABELLE ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_ANNABELLE ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_ANNABELLE_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_ANNABELLE ); + + ADD_ACTIVITY_TO_SR( ACT_WALK_MELEE ); + ADD_ACTIVITY_TO_SR( ACT_RUN_MELEE ); + + ADD_ACTIVITY_TO_SR( ACT_RUN_PACKAGE ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SUITCASE ); + + ADD_ACTIVITY_TO_SR( ACT_ARM_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_ARM_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_ARM_RPG ); + ADD_ACTIVITY_TO_SR( ACT_ARM_MELEE ); + ADD_ACTIVITY_TO_SR( ACT_DISARM_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_DISARM_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_DISARM_RPG ); + ADD_ACTIVITY_TO_SR( ACT_DISARM_MELEE ); +#endif + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR1 ); + //ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_AR1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_AR1_LOW ); + //ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_AR1 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR1_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_AR1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR1_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_AR3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_AR3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_AR3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_AR3 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_AR3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AR3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AR3_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_AR3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_AR3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_AR3_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SMG2 ); + //ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG2_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SMG2_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_SMG2_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SMG2_LOW ); + //ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_SMG2 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG2_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG2_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SMG2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SMG2_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SMG2_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SMG3 ); + //ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SMG3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_SMG3_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SMG3_LOW ); + //ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_SMG3 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_SMG3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG3_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SMG3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SMG3_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SMG3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SMG3_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SMG3_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_HMG1 ); + //ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_HMG1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_HMG1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_HMG1_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_HMG1_LOW ); + //ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_HMG1 ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_HMG1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_HMG1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_HMG1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_HMG1_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_HMG1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_HMG1_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_HMG1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_HMG1_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_HMG1_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SNIPER_RIFLE ); + //ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SNIPER_RIFLE_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_SNIPER_RIFLE_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_SNIPER_RIFLE_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SNIPER_RIFLE_LOW ); + //ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_SNIPER_RIFLE ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_SNIPER_RIFLE_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_SNIPER_RIFLE_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SNIPER_RIFLE_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SNIPER_RIFLE_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_SNIPER_RIFLE_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_SNIPER_RIFLE_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_ANGRY_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RELOAD_DUAL_PISTOLS_LOW ); + ADD_ACTIVITY_TO_SR( ACT_COVER_DUAL_PISTOLS_LOW ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_DUAL_PISTOLS_LOW ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_GESTURE_RELOAD_DUAL_PISTOLS ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_IDLE_DUAL_PISTOLS_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS_RELAXED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_DUAL_PISTOLS_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_DUAL_PISTOLS_STIMULATED ); + + ADD_ACTIVITY_TO_SR( ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED ); + ADD_ACTIVITY_TO_SR( ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED ); +#endif + +#if EXPANDED_NAVIGATION_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_CLIMB_ALL ); + ADD_ACTIVITY_TO_SR( ACT_CLIMB_IDLE ); + + ADD_ACTIVITY_TO_SR( ACT_CLIMB_MOUNT_TOP ); + ADD_ACTIVITY_TO_SR( ACT_CLIMB_MOUNT_BOTTOM ); + ADD_ACTIVITY_TO_SR( ACT_CLIMB_DISMOUNT_BOTTOM ); +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK2_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_MED ); + + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR2_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SHOTGUN_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_PISTOL_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_RPG_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_REVOLVER_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_CROSSBOW_MED ); + + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_AR2_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SMG1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SHOTGUN_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_PISTOL_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_RPG_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_REVOLVER_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_CROSSBOW_MED ); + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_AR1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_AR3_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_AR3_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SMG2_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG2_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SMG3_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SMG3_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_HMG1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_HMG1_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_SNIPER_RIFLE_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_AIM_DUAL_PISTOLS_MED ); + ADD_ACTIVITY_TO_SR( ACT_RANGE_ATTACK_DUAL_PISTOLS_MED ); +#endif + + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_R ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_L ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_R ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_L ); + + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_R_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_L_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_R_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_L_RIFLE ); + + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_R_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_L_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_R_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_COVER_WALL_LOW_L_PISTOL ); +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_PHYSGUN ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_GRENADE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_RPG ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_MELEE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SLAM ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_PISTOL ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SHOTGUN ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_PHYSGUN ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_GRENADE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_RPG ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_CROSSBOW ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_REVOLVER ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_REVOLVER ); + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_AR1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_AR1 ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_AR3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_AR3 ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SMG2 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SMG2 ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SMG3 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SMG3 ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_HMG1 ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_HMG1 ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SNIPER_RIFLE ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_DUAL_PISTOLS ); +#endif + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_USE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_USE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_USE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_USE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_USE ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_USE ); + + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_USE_HEAVY ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_USE_HEAVY ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_USE_HEAVY ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_CROUCH_USE_HEAVY ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_CROUCH_USE_HEAVY ); + ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_USE_HEAVY ); +#endif #ifdef VANCE - ADD_ACTIVITY_TO_SR(ACT_VM_WALK); - ADD_ACTIVITY_TO_SR(ACT_VM_SPRINT); - ADD_ACTIVITY_TO_SR(ACT_VM_FIRSTDRAW); - ADD_ACTIVITY_TO_SR(ACT_VM_LAND); - ADD_ACTIVITY_TO_SR(ACT_VM_KICK); - ADD_ACTIVITY_TO_SR(ACT_VM_EXTEND); - ADD_ACTIVITY_TO_SR(ACT_VM_IDLE_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_DRAW_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_RELOAD_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_SPRINT_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_FIRE_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_WALK_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_HOLSTER_EXTENDED); - ADD_ACTIVITY_TO_SR(ACT_VM_RETRACT); - - ADD_ACTIVITY_TO_SR(ACT_VM_SWING_LEFT); - ADD_ACTIVITY_TO_SR(ACT_VM_SWING_RIGHT); - ADD_ACTIVITY_TO_SR(ACT_VM_IDLE_TO_THROW); - ADD_ACTIVITY_TO_SR(ACT_VM_THROW_IDLE); + ADD_ACTIVITY_TO_SR( ACT_VM_WALK ); + ADD_ACTIVITY_TO_SR( ACT_VM_SPRINT); + ADD_ACTIVITY_TO_SR( ACT_VM_FIRSTDRAW); + ADD_ACTIVITY_TO_SR( ACT_VM_LAND); + ADD_ACTIVITY_TO_SR( ACT_VM_KICK); + ADD_ACTIVITY_TO_SR( ACT_VM_EXTEND); + ADD_ACTIVITY_TO_SR( ACT_VM_IDLE_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_DRAW_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_RELOAD_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_SPRINT_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_FIRE_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_WALK_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_HOLSTER_EXTENDED ); + ADD_ACTIVITY_TO_SR( ACT_VM_RETRACT ); + ADD_ACTIVITY_TO_SR( ACT_VM_SWING_LEFT ); + ADD_ACTIVITY_TO_SR( ACT_VM_SWING_RIGHT ); + ADD_ACTIVITY_TO_SR( ACT_VM_IDLE_TO_THROW ); + ADD_ACTIVITY_TO_SR( ACT_VM_THROW_IDLE ); #endif } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: This is a multi-purpose table which links NPC activities to their gesture variants. +//----------------------------------------------------------------------------- +CAI_BaseNPC::actlink_t CAI_BaseNPC::gm_ActivityGestureLinks[] = +{ + { ACT_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK1 }, + { ACT_RANGE_ATTACK2, ACT_GESTURE_RANGE_ATTACK2 }, + { ACT_MELEE_ATTACK1, ACT_GESTURE_MELEE_ATTACK1 }, + { ACT_MELEE_ATTACK2, ACT_GESTURE_MELEE_ATTACK2 }, + { ACT_RELOAD, ACT_GESTURE_RELOAD }, + + { ACT_RANGE_ATTACK1_LOW, ACT_GESTURE_RANGE_ATTACK1 }, // NOTE: ACT_GESTURE_RANGE_ATTACK1_LOW exists, but isn't used + { ACT_RANGE_ATTACK2_LOW, ACT_GESTURE_RANGE_ATTACK2 }, // NOTE: ACT_GESTURE_RANGE_ATTACK2_LOW exists, but isn't used + { ACT_RELOAD_LOW, ACT_GESTURE_RELOAD }, + + { ACT_MELEE_ATTACK_SWING, ACT_GESTURE_MELEE_ATTACK_SWING }, + + // ----------------------------------------------------------- + + { ACT_RANGE_ATTACK_AR2, ACT_GESTURE_RANGE_ATTACK_AR2 }, + { ACT_RANGE_ATTACK_AR2_LOW, ACT_GESTURE_RANGE_ATTACK_AR2 }, + { ACT_RANGE_ATTACK_SMG1, ACT_GESTURE_RANGE_ATTACK_SMG1 }, + { ACT_RANGE_ATTACK_SMG1_LOW, ACT_GESTURE_RANGE_ATTACK_SMG1 }, + { ACT_RANGE_ATTACK_SHOTGUN, ACT_GESTURE_RANGE_ATTACK_SHOTGUN }, + { ACT_RANGE_ATTACK_SHOTGUN_LOW, ACT_GESTURE_RANGE_ATTACK_SHOTGUN }, + { ACT_RANGE_ATTACK_PISTOL, ACT_GESTURE_RANGE_ATTACK_PISTOL }, + { ACT_RANGE_ATTACK_PISTOL_LOW, ACT_GESTURE_RANGE_ATTACK_PISTOL }, + + // ----------------------------------------------------------- + + { ACT_SMALL_FLINCH, ACT_GESTURE_SMALL_FLINCH }, + { ACT_BIG_FLINCH, ACT_GESTURE_BIG_FLINCH }, + { ACT_FLINCH_HEAD, ACT_GESTURE_FLINCH_HEAD }, + { ACT_FLINCH_CHEST, ACT_GESTURE_FLINCH_CHEST }, + { ACT_FLINCH_STOMACH, ACT_GESTURE_FLINCH_STOMACH }, + { ACT_FLINCH_LEFTARM, ACT_GESTURE_FLINCH_LEFTARM }, + { ACT_FLINCH_RIGHTARM, ACT_GESTURE_FLINCH_RIGHTARM }, + { ACT_FLINCH_LEFTLEG, ACT_GESTURE_FLINCH_LEFTLEG }, + { ACT_FLINCH_RIGHTLEG, ACT_GESTURE_FLINCH_RIGHTLEG }, + + // ----------------------------------------------------------- + +#if AR2_ACTIVITY_FIX == 1 + { ACT_RELOAD_AR2, ACT_GESTURE_RELOAD_AR2 }, + { ACT_RELOAD_AR2_LOW, ACT_GESTURE_RELOAD_AR2 }, +#endif + { ACT_RELOAD_SMG1, ACT_GESTURE_RELOAD_SMG1 }, + { ACT_RELOAD_SMG1_LOW, ACT_GESTURE_RELOAD_SMG1 }, + { ACT_RELOAD_SHOTGUN, ACT_GESTURE_RELOAD_SHOTGUN }, + { ACT_RELOAD_SHOTGUN_LOW, ACT_GESTURE_RELOAD_SHOTGUN }, + { ACT_RELOAD_PISTOL, ACT_GESTURE_RELOAD_PISTOL }, + { ACT_RELOAD_PISTOL_LOW, ACT_GESTURE_RELOAD_PISTOL }, + +#if SHARED_COMBINE_ACTIVITIES + { ACT_SPECIAL_ATTACK1, ACT_GESTURE_SPECIAL_ATTACK1 }, + { ACT_SPECIAL_ATTACK2, ACT_GESTURE_SPECIAL_ATTACK2 }, + { ACT_COMBINE_THROW_GRENADE, ACT_GESTURE_COMBINE_THROW_GRENADE }, + { ACT_COMBINE_AR2_ALTFIRE, ACT_GESTURE_COMBINE_AR2_ALTFIRE }, + + { ACT_SIGNAL_ADVANCE, ACT_GESTURE_SIGNAL_ADVANCE }, + { ACT_SIGNAL_FORWARD, ACT_GESTURE_SIGNAL_FORWARD }, + { ACT_SIGNAL_GROUP, ACT_GESTURE_SIGNAL_GROUP }, + { ACT_SIGNAL_HALT, ACT_GESTURE_SIGNAL_HALT }, + { ACT_SIGNAL_LEFT, ACT_GESTURE_SIGNAL_LEFT }, + { ACT_SIGNAL_RIGHT, ACT_GESTURE_SIGNAL_RIGHT }, + { ACT_SIGNAL_TAKECOVER, ACT_GESTURE_SIGNAL_TAKECOVER }, +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RANGE_ATTACK_REVOLVER, ACT_GESTURE_RANGE_ATTACK_REVOLVER }, + { ACT_RANGE_ATTACK_REVOLVER_LOW, ACT_GESTURE_RANGE_ATTACK_REVOLVER }, + { ACT_RANGE_ATTACK_CROSSBOW, ACT_GESTURE_RANGE_ATTACK_CROSSBOW }, + { ACT_RANGE_ATTACK_CROSSBOW_LOW, ACT_GESTURE_RANGE_ATTACK_CROSSBOW }, + { ACT_RANGE_ATTACK_RPG, ACT_GESTURE_RANGE_ATTACK_RPG }, + { ACT_RANGE_ATTACK_RPG_LOW, ACT_GESTURE_RANGE_ATTACK_RPG }, + { ACT_RANGE_ATTACK_ANNABELLE, ACT_GESTURE_RANGE_ATTACK_ANNABELLE }, + { ACT_RANGE_ATTACK_ANNABELLE_LOW, ACT_GESTURE_RANGE_ATTACK_ANNABELLE }, + + { ACT_RELOAD_REVOLVER, ACT_GESTURE_RELOAD_REVOLVER }, + { ACT_RELOAD_REVOLVER_LOW, ACT_GESTURE_RELOAD_REVOLVER }, + { ACT_RELOAD_CROSSBOW, ACT_GESTURE_RELOAD_CROSSBOW }, + { ACT_RELOAD_CROSSBOW_LOW, ACT_GESTURE_RELOAD_CROSSBOW }, + { ACT_RELOAD_ANNABELLE, ACT_GESTURE_RELOAD_ANNABELLE }, + { ACT_RELOAD_ANNABELLE_LOW, ACT_GESTURE_RELOAD_ANNABELLE }, +#endif + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + { ACT_RANGE_ATTACK_AR1, ACT_GESTURE_RANGE_ATTACK_AR1 }, + { ACT_RANGE_ATTACK_AR1_LOW, ACT_GESTURE_RANGE_ATTACK_AR1 }, + { ACT_RANGE_ATTACK_AR3, ACT_GESTURE_RANGE_ATTACK_AR3 }, + { ACT_RANGE_ATTACK_AR3_LOW, ACT_GESTURE_RANGE_ATTACK_AR3 }, + { ACT_RANGE_ATTACK_AR2_GRENADE, ACT_GESTURE_RANGE_ATTACK_AR2_GRENADE }, + { ACT_RANGE_ATTACK_HMG1, ACT_GESTURE_RANGE_ATTACK_HMG1 }, + { ACT_RANGE_ATTACK_HMG1_LOW, ACT_GESTURE_RANGE_ATTACK_HMG1 }, + { ACT_RANGE_ATTACK_ML, ACT_GESTURE_RANGE_ATTACK_ML }, + { ACT_RANGE_ATTACK_SMG2, ACT_GESTURE_RANGE_ATTACK_SMG2 }, + { ACT_RANGE_ATTACK_SMG2_LOW, ACT_GESTURE_RANGE_ATTACK_SMG2 }, + { ACT_RANGE_ATTACK_SMG3, ACT_GESTURE_RANGE_ATTACK_SMG3 }, + { ACT_RANGE_ATTACK_SMG3_LOW, ACT_GESTURE_RANGE_ATTACK_SMG3 }, + { ACT_RANGE_ATTACK_SLAM, ACT_GESTURE_RANGE_ATTACK_SLAM }, + { ACT_RANGE_ATTACK_TRIPWIRE, ACT_GESTURE_RANGE_ATTACK_TRIPWIRE }, + { ACT_RANGE_ATTACK_THROW, ACT_GESTURE_RANGE_ATTACK_THROW }, + { ACT_RANGE_ATTACK_SNIPER_RIFLE, ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE }, + { ACT_RANGE_ATTACK_SNIPER_RIFLE_LOW, ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE }, + + { ACT_RELOAD_AR1, ACT_GESTURE_RELOAD_AR1 }, + { ACT_RELOAD_AR1_LOW, ACT_GESTURE_RELOAD_AR1 }, + { ACT_RELOAD_AR3, ACT_GESTURE_RELOAD_AR3 }, + { ACT_RELOAD_AR3_LOW, ACT_GESTURE_RELOAD_AR3 }, + { ACT_RELOAD_SMG2, ACT_GESTURE_RELOAD_SMG2 }, + { ACT_RELOAD_SMG2_LOW, ACT_GESTURE_RELOAD_SMG2 }, + { ACT_RELOAD_SMG3, ACT_GESTURE_RELOAD_SMG3 }, + { ACT_RELOAD_SMG3_LOW, ACT_GESTURE_RELOAD_SMG3 }, + { ACT_RELOAD_HMG1, ACT_GESTURE_RELOAD_HMG1 }, + { ACT_RELOAD_HMG1_LOW, ACT_GESTURE_RELOAD_HMG1 }, + { ACT_RELOAD_SNIPER_RIFLE, ACT_GESTURE_RELOAD_SNIPER_RIFLE }, + { ACT_RELOAD_SNIPER_RIFLE_LOW, ACT_GESTURE_RELOAD_SNIPER_RIFLE }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_ATTACK1_MED, ACT_GESTURE_RANGE_ATTACK1 }, + { ACT_RANGE_ATTACK2_MED, ACT_GESTURE_RANGE_ATTACK2 }, + + { ACT_RANGE_ATTACK_AR2_MED, ACT_GESTURE_RANGE_ATTACK_AR2 }, + { ACT_RANGE_ATTACK_SMG1_MED, ACT_GESTURE_RANGE_ATTACK_SMG1 }, + { ACT_RANGE_ATTACK_SHOTGUN_MED, ACT_GESTURE_RANGE_ATTACK_SHOTGUN }, + { ACT_RANGE_ATTACK_PISTOL_MED, ACT_GESTURE_RANGE_ATTACK_PISTOL }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RANGE_ATTACK_RPG_MED, ACT_GESTURE_RANGE_ATTACK_RPG }, + { ACT_RANGE_ATTACK_REVOLVER_MED, ACT_GESTURE_RANGE_ATTACK_REVOLVER }, + { ACT_RANGE_ATTACK_CROSSBOW_MED, ACT_GESTURE_RANGE_ATTACK_CROSSBOW }, +#endif +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + { ACT_RANGE_ATTACK_AR1_MED, ACT_GESTURE_RANGE_ATTACK_AR1 }, + { ACT_RANGE_ATTACK_AR3_MED, ACT_GESTURE_RANGE_ATTACK_AR3 }, + { ACT_RANGE_ATTACK_SMG2_MED, ACT_GESTURE_RANGE_ATTACK_SMG2 }, + { ACT_RANGE_ATTACK_SMG3_MED, ACT_GESTURE_RANGE_ATTACK_SMG3 }, + { ACT_RANGE_ATTACK_HMG1_MED, ACT_GESTURE_RANGE_ATTACK_HMG1 }, + { ACT_RANGE_ATTACK_SNIPER_RIFLE_MED, ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE }, +#endif +#endif +}; + +Activity CAI_BaseNPC::GetGestureVersionOfActivity( Activity inActivity ) +{ + actlink_t *pTable = gm_ActivityGestureLinks; + int actCount = ARRAYSIZE( gm_ActivityGestureLinks ); + + for ( int i = 0; i < actCount; i++, pTable++ ) + { + if ( inActivity == pTable->sequence ) + { + return pTable->gesture; + } + } + + return ACT_INVALID; +} + +Activity CAI_BaseNPC::GetSequenceVersionOfGesture( Activity inActivity ) +{ + actlink_t *pTable = gm_ActivityGestureLinks; + int actCount = ARRAYSIZE( gm_ActivityGestureLinks ); + + for (int i = 0; i < actCount; i++, pTable++) + { + if (inActivity == pTable->gesture) + { + return pTable->sequence; + } + } + + return ACT_INVALID; +} +#endif diff --git a/game/server/ai_baseactor.cpp b/game/server/ai_baseactor.cpp index e9814967..df0a5aaa 100644 --- a/game/server/ai_baseactor.cpp +++ b/game/server/ai_baseactor.cpp @@ -98,6 +98,15 @@ BEGIN_DATADESC( CAI_BaseActor ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CAI_BaseActor, CAI_BaseNPC, "The base class for NPCs which act in complex choreo scenes." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddLookTarget, "AddLookTarget", "Add a potential look target for this actor with the specified importance, duration, and ramp." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddLookTargetPos, "AddLookTargetPos", "Add a potential look target position for this actor with the specified importance, duration, and ramp." ) + +END_SCRIPTDESC(); +#endif + BEGIN_SIMPLE_DATADESC( CAI_InterestTarget_t ) DEFINE_FIELD( m_eType, FIELD_INTEGER ), @@ -230,7 +239,11 @@ void CAI_BaseActor::SetModel( const char *szModelName ) // Purpose: //----------------------------------------------------------------------------- +#ifdef MAPBASE +bool CAI_BaseActor::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget, CSceneEntity *pSceneEnt ) +#else bool CAI_BaseActor::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ) +#endif { Assert( info ); Assert( info->m_pScene ); @@ -314,6 +327,109 @@ bool CAI_BaseActor::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, { info->m_nType = SCENE_AI_DISABLEAI; } +#ifdef MAPBASE + else if (stricmp(event->GetParameters(), "AI_ADDCONTEXT") == 0) + { + // Adds a response context to the caller in place of the target field. + // This is supposed to be used with the talker system. + if (event->GetParameters2()) + { + info->m_nType = SCENE_AI_ADDCONTEXT; + AddContext(event->GetParameters2()); + return true; + } + } + else if (stricmp(event->GetParameters(), "AI_INPUT") == 0) + { + // Fires an input on an entity in place of the target field. + // This is supposed to be used with the talker system. + if (event->GetParameters2()) + { + info->m_nType = SCENE_AI_INPUT; + + const char *raw = event->GetParameters2(); + char sTarget[128]; + char sInput[128]; + char sParameter[128]; + char *colon1 = Q_strstr( raw, ":" ); + if (!colon1) + { + Warning("%s (%s) AI_INPUT missing colon separator!\n", GetClassname(), GetDebugName()); + return false; + } + + int len = colon1 - raw; + Q_strncpy( sTarget, raw, MIN( len + 1, sizeof(sTarget) ) ); + sTarget[MIN(len, sizeof(sTarget) - 1)] = 0; + + bool bParameter = true; + char *colon2 = Q_strstr(colon1 + 1, ":"); + if (!colon2) + { + DevMsg("Assuming no parameter\n"); + colon2 = colon1 + 1; + bParameter = false; + } + + if (bParameter) + { + len = MIN(colon2 - (colon1 + 1), sizeof(sInput) - 1); + Q_strncpy(sInput, colon1 + 1, MIN(len + 1, sizeof(sInput))); + sInput[MIN(len, sizeof(sInput) - 1)] = 0; + + Q_strncpy(sParameter, colon2 + 1, sizeof(sInput)); + } + else + { + len = colon2 - raw; + Q_strncpy(sInput, colon2, sizeof(sInput)); + } + + CBaseEntity *pEnt = gEntList.FindEntityByName(NULL, sTarget, this); + if (!pEnt) + { + DevMsg("%s not found with normal search, slamming to scene ent\n", sTarget); + pEnt = UTIL_FindNamedSceneEntity(sTarget, this, pSceneEnt); + if (!pEnt) + { + DevWarning("%s slammed to self!\n", sTarget); + pEnt = this; + } + } + + if (pEnt && sInput) + { + variant_t variant; + if (bParameter && sParameter) + { + const char *strParam = sParameter; + if (strParam[0] == '!') + { + CBaseEntity *pParamEnt = UTIL_FindNamedSceneEntity(strParam, this, pSceneEnt); + if (pParamEnt && pParamEnt->GetEntityName() != NULL_STRING && !gEntList.FindEntityProcedural(strParam)) + { + // We make sure it's a scene entity that can't be found with entlist procedural so we can translate !target# without messing with !activators, etc. + //const char *newname = pParamEnt->GetEntityName().ToCStr(); + strParam = pParamEnt->GetEntityName().ToCStr(); + } + } + + if (strParam) + { + variant.SetString(MAKE_STRING(strParam)); + } + } + + pEnt->AcceptInput(sInput, this, this, variant, 0); + return true; + } + else + { + Warning("%s (%s) AI_INPUT cannot find entity %s!\n", GetClassname(), GetDebugName(), sTarget); + } + } + } +#endif else { return BaseClass::StartSceneEvent( info, scene, event, actor, pTarget ); @@ -508,6 +624,11 @@ bool CAI_BaseActor::ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scen Vector vecAimTargetLoc = info->m_hTarget->EyePosition(); Vector vecAimDir = vecAimTargetLoc - EyePosition(); +#ifdef MAPBASE + // Mind the ramp + vecAimDir *= event->GetIntensity(scene->GetTime()); +#endif + VectorNormalize( vecAimDir ); SetAim( vecAimDir); } @@ -548,6 +669,16 @@ bool CAI_BaseActor::ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scen EnterSceneSequence( scene, event ); } return true; +#ifdef MAPBASE + case SCENE_AI_ADDCONTEXT: + { + } + return true; + case SCENE_AI_INPUT: + { + } + return true; +#endif default: return false; } @@ -704,7 +835,11 @@ void CAI_BaseActor::UpdateLatchedValues( ) // set head latch m_fLatchedPositions |= HUMANOID_LATCHED_HEAD; +#ifdef MAPBASE // From Alien Swarm SDK + if ( CanSkipAnimation() || !GetAttachment( "eyes", m_latchedEyeOrigin, &m_latchedHeadDirection )) +#else if (!HasCondition( COND_IN_PVS ) || !GetAttachment( "eyes", m_latchedEyeOrigin, &m_latchedHeadDirection )) +#endif { m_latchedEyeOrigin = BaseClass::EyePosition( ); AngleVectors( GetLocalAngles(), &m_latchedHeadDirection ); @@ -1007,6 +1142,24 @@ void CAI_BaseActor::UpdateHeadControl( const Vector &vHeadTarget, float flHeadIn ConcatTransforms( worldToForward, targetXform, headXform ); MatrixAngles( headXform, vTargetAngles ); +#ifdef MAPBASE + // This is here to cover an edge case where pose parameters set to NaN invalidate the model. + if (!vTargetAngles.IsValid()) + { + Warning( "================================================================================\n" + "!!!!! %s tried to set a NaN head angle (can happen when look targets have >1 importance) !!!!!\n" + "================================================================================\n", GetDebugName() ); + m_goalHeadCorrection.Init(); + Set( m_FlexweightHeadRightLeft, 0.0f ); + Set( m_FlexweightHeadUpDown, 0.0f ); + Set( m_FlexweightHeadTilt, 0.0f ); + Set( m_ParameterHeadYaw, 0.0f ); + Set( m_ParameterHeadPitch, 0.0f ); + Set( m_ParameterHeadRoll, 0.0f ); + return; + } +#endif + // partially debounce head goal float s0 = 1.0 - flHeadInfluence + GetHeadDebounce() * flHeadInfluence; float s1 = (1.0 - s0); @@ -1495,7 +1648,11 @@ void CAI_BaseActor::MaintainLookTargets( float flInterval ) } // don't bother with any of the rest if the player can't see you +#ifdef MAPBASE // From Alien Swarm SDK + if ( CanSkipAnimation() ) +#else if (!HasCondition( COND_IN_PVS )) +#endif { return; } @@ -1802,7 +1959,7 @@ void CAI_BaseActor::OnStateChange( NPC_STATE OldState, NPC_STATE NewState ) { PlayExpressionForState( NewState ); -#ifdef HL2_EPISODIC +#if defined(HL2_EPISODIC) || defined(MAPBASE) // If we've just switched states, ensure we stop any scenes that asked to be stopped if ( OldState == NPC_STATE_IDLE ) { @@ -1902,7 +2059,11 @@ bool CAI_BaseActor::UseSemaphore( void ) CAI_Expresser *CAI_BaseActor::CreateExpresser() { +#ifdef NEW_RESPONSE_SYSTEM + m_pExpresser = new CAI_ExpresserWithFollowup(this); +#else m_pExpresser = new CAI_Expresser(this); +#endif return m_pExpresser; } diff --git a/game/server/ai_baseactor.h b/game/server/ai_baseactor.h index 49caea53..f0d9f8ae 100644 --- a/game/server/ai_baseactor.h +++ b/game/server/ai_baseactor.h @@ -101,7 +101,11 @@ class CAI_BaseActor : public CAI_ExpresserHost virtual void SetModel( const char *szModelName ); +#ifdef MAPBASE + virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget, CSceneEntity *pSceneEnt = NULL ); +#else virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); +#endif virtual bool ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled ); virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event ); @@ -166,6 +170,15 @@ class CAI_BaseActor : public CAI_ExpresserHost void ClearExpression(); const char * GetExpression(); +#ifdef MAPBASE_VSCRIPT + //--------------------------------- + + void ScriptAddLookTarget( HSCRIPT pTarget, float flImportance, float flDuration, float flRamp = 0.0 ) { AddLookTarget(ToEnt(pTarget), flImportance, flDuration, flRamp); } + void ScriptAddLookTargetPos( const Vector &vecPosition, float flImportance, float flDuration, float flRamp = 0.0 ) { AddLookTarget(vecPosition, flImportance, flDuration, flRamp); } + + //--------------------------------- +#endif + enum { SCENE_AI_BLINK = 1, @@ -177,10 +190,19 @@ class CAI_BaseActor : public CAI_ExpresserHost SCENE_AI_RANDOMHEADFLEX, SCENE_AI_IGNORECOLLISION, SCENE_AI_DISABLEAI +#ifdef MAPBASE + , + SCENE_AI_ADDCONTEXT, + SCENE_AI_INPUT, + SCENE_AI_GAMETEXT, // This is handled in CBaseFlex +#endif }; DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif private: enum { diff --git a/game/server/ai_basenpc.cpp b/game/server/ai_basenpc.cpp index b4442260..299aa5c4 100644 --- a/game/server/ai_basenpc.cpp +++ b/game/server/ai_basenpc.cpp @@ -95,6 +95,16 @@ #include "prop_portal_shared.h" #endif +#ifdef MAPBASE +#include "mapbase/matchers.h" +#include "items.h" +#include "point_camera.h" +#endif + +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" +#endif + #include "env_debughistory.h" #include "collisionutils.h" @@ -156,6 +166,14 @@ ConVar ai_test_moveprobe_ignoresmall( "ai_test_moveprobe_ignoresmall", "0" ); extern ConVar ai_vehicle_avoidance; #endif // HL2_EPISODIC +#ifdef MAPBASE +extern ISoundEmitterSystemBase *soundemitterbase; + +ConVar ai_dynint_always_enabled( "ai_dynint_always_enabled", "0", FCVAR_NONE, "Makes the \"Don't Care\" setting equivalent to \"Yes\"." ); + +ConVar ai_debug_fake_sequence_gestures_always_play( "ai_debug_fake_sequence_gestures_always_play", "0", FCVAR_NONE, "Always plays fake sequence gestures." ); +#endif + #ifndef _RETAIL #define ShouldUseEfficiency() ( ai_use_think_optimizations.GetBool() && ai_use_efficiency.GetBool() ) #define ShouldUseFrameThinkLimits() ( ai_use_think_optimizations.GetBool() && ai_use_frame_think_limits.GetBool() ) @@ -291,6 +309,17 @@ int CAI_BaseNPC::gm_nSpawnedThisFrame; CSimpleSimTimer CAI_BaseNPC::m_AnyUpdateEnemyPosTimer; +#ifdef MAPBASE_VSCRIPT +// TODO: Better placement? +ScriptHook_t CAI_BaseNPC::g_Hook_QueryHearSound; +ScriptHook_t CAI_BaseNPC::g_Hook_QuerySeeEntity; +ScriptHook_t CAI_BaseNPC::g_Hook_TranslateActivity; +ScriptHook_t CAI_BaseNPC::g_Hook_TranslateSchedule; +ScriptHook_t CAI_BaseNPC::g_Hook_GetActualShootPosition; +ScriptHook_t CAI_BaseNPC::g_Hook_OverrideMove; +ScriptHook_t CAI_BaseNPC::g_Hook_ShouldPlayFakeSequenceGesture; +#endif + // // Deferred Navigation calls go here // @@ -544,7 +573,7 @@ void CAI_BaseNPC::CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput ) RemoveActorFromScriptedScenes( this, false /*all scenes*/ ); } else - DevMsg( "Unexpected double-death-cleanup\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Unexpected double-death-cleanup\n" ); } void CAI_BaseNPC::SelectDeathPose( const CTakeDamageInfo &info ) @@ -644,7 +673,7 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo #ifdef HL2_EPISODIC CBasePlayer *pPlayer = AI_GetSinglePlayer(); - if ( pPlayer->IRelationType( this ) != D_LI ) + if ( pPlayer && pPlayer->IRelationType( this ) != D_LI ) { CNPC_Alyx *alyx = CNPC_Alyx::GetAlyx(); @@ -660,11 +689,209 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo ConVar ai_block_damage( "ai_block_damage","0" ); +#ifdef MAPBASE +bool CAI_BaseNPC::FriendlyFireEnabled() +{ + if (m_FriendlyFireOverride != TRS_NONE) + return m_FriendlyFireOverride == TRS_TRUE; + + if (HL2GameRules()->GlobalFriendlyFire() != TRS_NONE) + return HL2GameRules()->GlobalFriendlyFire() == TRS_TRUE; + + return !(CapabilitiesGet() & bits_CAP_FRIENDLY_DMG_IMMUNE); +} + +//----------------------------------------------------------------------------- +void CAI_BaseNPC::InputSetFriendlyFire( inputdata_t &inputdata ) +{ + m_FriendlyFireOverride = TO_THREESTATE(inputdata.value.Int()); +} +#endif + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CAI_BaseNPC::VScriptGetEnemy() +{ + return ToHScript( GetEnemy() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_BaseNPC::VScriptSetEnemy( HSCRIPT pEnemy ) +{ + SetEnemy( ToEnt( pEnemy ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +Vector CAI_BaseNPC::VScriptGetEnemyLKP() +{ + return GetEnemyLKP(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CAI_BaseNPC::VScriptFindEnemyMemory( HSCRIPT pEnemy ) +{ + HSCRIPT hScript = NULL; + AI_EnemyInfo_t *info = GetEnemies()->Find( ToEnt(pEnemy) ); + if (info) + { + hScript = g_pScriptVM->RegisterInstance( reinterpret_cast(info) ); + } + + return hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CAI_BaseNPC::VScriptGetState() +{ + return (int)GetState(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CAI_BaseNPC::VScriptGetHintNode() +{ + return ToHScript( GetHintNode() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char *CAI_BaseNPC::VScriptGetSchedule() +{ + const char *pName = NULL; + if (GetCurSchedule()) + pName = GetCurSchedule()->GetName(); + + if (!pName) + pName = "Unknown"; + + return pName; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CAI_BaseNPC::VScriptGetScheduleID() +{ + if (!GetCurSchedule()) + return -1; + + int iSched = GetCurSchedule()->GetId(); + + // Local IDs are needed to correspond with user-friendly enums + if ( AI_IdIsGlobal( iSched ) ) + { + iSched = GetClassScheduleIdSpace()->ScheduleGlobalToLocal(iSched); + } + + return iSched; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_BaseNPC::VScriptSetSchedule( const char *szSchedule ) +{ + SetSchedule( GetScheduleID( szSchedule ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char *CAI_BaseNPC::VScriptGetTask() +{ + const Task_t *pTask = GetTask(); + const char *pName = NULL; + if (pTask) + pName = TaskName( pTask->iTask ); + else + pName = "None"; + + return pName; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CAI_BaseNPC::VScriptGetTaskID() +{ + const Task_t *pTask = GetTask(); + int iID = -1; + if (pTask) + iID = GetTaskID( TaskName( pTask->iTask ) ); + + return iID; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CAI_BaseNPC::VScriptGetExpresser() +{ + HSCRIPT hScript = NULL; + CAI_Expresser *pExpresser = GetExpresser(); + if (pExpresser) + { + hScript = g_pScriptVM->RegisterInstance( pExpresser ); + } + + return hScript; +} + +HSCRIPT CAI_BaseNPC::VScriptGetCine() +{ + return ToHScript(m_hCine.Get()); +} + +HSCRIPT CAI_BaseNPC::VScriptGetSquad() +{ + HSCRIPT hScript = NULL; + CAI_Squad *pSquad = GetSquad(); + if (pSquad) + { + hScript = g_pScriptVM->RegisterInstance( pSquad ); + } + + return hScript; +} +#endif + bool CAI_BaseNPC::PassesDamageFilter( const CTakeDamageInfo &info ) { if ( ai_block_damage.GetBool() ) return false; // FIXME: hook a friendly damage filter to the npc instead? +#ifdef MAPBASE + if ( !FriendlyFireEnabled() && info.GetAttacker() && info.GetAttacker() != this && !info.IsForceFriendlyFire() ) + { + // check attackers relationship with me + CBaseCombatCharacter *npcEnemy = info.GetAttacker()->MyCombatCharacterPointer(); + + if ( npcEnemy && npcEnemy->IRelationType( this ) == D_LI ) + { + m_fNoDamageDecal = true; + + if ( npcEnemy->IsPlayer() ) + { + m_OnDamagedByPlayer.FireOutput( info.GetAttacker(), this ); + // This also counts as being harmed by player's squad. + m_OnDamagedByPlayerSquad.FireOutput( info.GetAttacker(), this ); + } + + return false; + } + + if ( IServerVehicle *pVehicle = info.GetAttacker()->GetServerVehicle() ) + { + m_fNoDamageDecal = true; + if (pVehicle->GetPassenger() && pVehicle->GetPassenger()->IRelationType(this) == D_LI) + { + // Players could bail from their cars to kill NPCs with this! + // Is there a "last passenger" variable we could use? + return false; + } + } + } +#else if ( (CapabilitiesGet() & bits_CAP_FRIENDLY_DMG_IMMUNE) && info.GetAttacker() && info.GetAttacker() != this ) { // check attackers relationship with me @@ -692,6 +919,7 @@ bool CAI_BaseNPC::PassesDamageFilter( const CTakeDamageInfo &info ) return false; } } +#endif if ( !BaseClass::PassesDamageFilter( info ) ) { @@ -714,7 +942,11 @@ int CAI_BaseNPC::OnTakeDamage_Alive( const CTakeDamageInfo &info ) return 0; if ( GetSleepState() == AISS_WAITING_FOR_THREAT ) +#ifdef MAPBASE + Wake( info.GetAttacker() ); +#else Wake(); +#endif // NOTE: This must happen after the base class is called; we need to reduce // health before the pain sound, since some NPCs use the final health @@ -766,24 +998,27 @@ int CAI_BaseNPC::OnTakeDamage_Alive( const CTakeDamageInfo &info ) // only fire once per frame m_OnDamaged.FireOutput( info.GetAttacker(), this); - if( info.GetAttacker()->IsPlayer() ) + if ( info.GetAttacker() ) { - m_OnDamagedByPlayer.FireOutput( info.GetAttacker(), this ); + if( info.GetAttacker()->IsPlayer() ) + { + m_OnDamagedByPlayer.FireOutput( info.GetAttacker(), this ); - // This also counts as being harmed by player's squad. - m_OnDamagedByPlayerSquad.FireOutput( info.GetAttacker(), this ); - } - else - { - // See if the person that injured me is an NPC. - CAI_BaseNPC *pAttacker = dynamic_cast( info.GetAttacker() ); - CBasePlayer *pPlayer = AI_GetSinglePlayer(); - - if( pAttacker && pAttacker->IsAlive() && pPlayer ) + // This also counts as being harmed by player's squad. + m_OnDamagedByPlayerSquad.FireOutput( info.GetAttacker(), this ); + } + else { - if( pAttacker->GetSquad() != NULL && pAttacker->IsInPlayerSquad() ) + // See if the person that injured me is an NPC. + CAI_BaseNPC *pAttacker = info.GetAttacker()->MyNPCPointer(); + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + + if( pAttacker && pAttacker->IsAlive() && pPlayer ) { - m_OnDamagedByPlayerSquad.FireOutput( info.GetAttacker(), this ); + if( pAttacker->GetSquad() != NULL && pAttacker->IsInPlayerSquad() ) + { + m_OnDamagedByPlayerSquad.FireOutput( info.GetAttacker(), this ); + } } } } @@ -995,7 +1230,8 @@ void CAI_BaseNPC::NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ) { if ( (originNpc.AsVector2D() - origin.AsVector2D()).LengthSqr() < NEAR_XY_SQ ) { - if ( pNpc->GetSquad() == GetSquad() || IRelationType( pNpc ) == D_LI ) + //Tony; add a check to make sure this doesn't get called if the npc isn't in a squad + if ( ( pNpc->GetSquad() == GetSquad() && !( pNpc->GetSquad() == NULL || GetSquad() == NULL ) ) || IRelationType( pNpc ) == D_LI ) pNpc->OnFriendDamaged( this, pAttacker ); } } @@ -1013,7 +1249,11 @@ void CAI_BaseNPC::OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity float distSqToThreat = ( GetAbsOrigin() - pAttacker->GetAbsOrigin() ).LengthSqr(); if ( GetSleepState() != AISS_AWAKE && distSqToThreat < Square( 20 * 12 ) ) +#ifdef MAPBASE + Wake( pAttacker ); +#else Wake(); +#endif if ( distSqToThreat < Square( 50 * 12 ) ) ForceGatherConditions(); @@ -1182,7 +1422,12 @@ void CAI_BaseNPC::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir break; } +#ifdef MAPBASE + bool bBloodAllowed = DamageFilterAllowsBlood( info ); + if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) && bBloodAllowed ) +#else if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) ) +#endif { if( !IsPlayer() || ( IsPlayer() && g_pGameRules->IsMultiplayer() ) ) { @@ -1197,6 +1442,12 @@ void CAI_BaseNPC::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir m_fNoDamageDecal = true; } } +#ifdef MAPBASE + else if (!bBloodAllowed) + { + m_fNoDamageDecal = true; + } +#endif // Airboat gun will impart major force if it's about to kill him.... if ( info.GetDamageType() & DMG_AIRBOAT ) @@ -1286,7 +1537,12 @@ bool CAI_BaseNPC::PlayerInSpread( const Vector &sourcePos, const Vector &targetP { CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); +#ifdef MAPBASE + // "> D_FR" means it isn't D_HT, D_FR, or D_ER (error disposition) + if ( pPlayer && ( !ignoreHatedPlayers || IRelationType( pPlayer ) > D_FR ) && !(pPlayer->GetFlags() & FL_NOTARGET) ) +#else if ( pPlayer && ( !ignoreHatedPlayers || IRelationType( pPlayer ) != D_HT ) ) +#endif { if ( PointInSpread( pPlayer, sourcePos, targetPos, pPlayer->WorldSpaceCenter(), flSpread, maxDistOffCenter ) ) return true; @@ -1738,6 +1994,118 @@ void CAI_BaseNPC::ClearIgnoreConditions( int *pConditions, int nConditions ) } } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Adds a condition to this NPC, integral or not +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputSetCondition( inputdata_t &inputdata ) +{ + const char *pszCondition = inputdata.value.String(); + if (!pszCondition || !pszCondition[0]) + return; + + int iCondition = atoi(pszCondition); + if (iCondition == 0) + { + // Convert from string + iCondition = GetConditionID(pszCondition); + } + + SetCondition(iCondition); +} + +//------------------------------------------------------------------------------ +// Purpose: Removes a condition from this NPC, integral or not +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputClearCondition( inputdata_t &inputdata ) +{ + const char *pszCondition = inputdata.value.String(); + if (!pszCondition || !pszCondition[0]) + return; + + int iCondition = atoi(pszCondition); + if (iCondition == 0) + { + // Convert from string + iCondition = GetConditionID(pszCondition); + } + + ClearCondition(iCondition); +} + +//------------------------------------------------------------------------------ +// Purpose: Sets our think to CallNPCThink() in case SetThinkNull was fired before +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputSetThinkNPC( inputdata_t &inputdata ) +{ + SetThink ( &CAI_BaseNPC::CallNPCThink ); + SetNextThink(gpGlobals->curtime + inputdata.value.Float()); +} + +//------------------------------------------------------------------------------ +// Purpose: Sets our look distance +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputSetDistLook( inputdata_t &inputdata ) +{ + if ( inputdata.value.Float() != 0.0f ) + { + SetDistLook( inputdata.value.Float() ); + } + else + { + SetDistLook( 2048.0 ); + + if ( HasSpawnFlags( SF_NPC_LONG_RANGE ) ) + { + SetDistLook( 6000.0 ); + } + } +} + +//------------------------------------------------------------------------------ +// Purpose: Sets our distance too far +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputSetDistTooFar( inputdata_t &inputdata ) +{ + if ( inputdata.value.Float() != 0.0f ) + { + m_flDistTooFar = inputdata.value.Float(); + } + else + { + m_flDistTooFar = 1024.0; + + if ( HasSpawnFlags( SF_NPC_LONG_RANGE ) ) + { + m_flDistTooFar = 1e9f; + } + } +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputSetTarget( inputdata_t &inputdata ) +{ + m_target = inputdata.value.StringID(); + + if ( m_target != NULL_STRING )// this npc has a target + { + // Find the npc's initial target entity, stash it + SetGoalEnt( gEntList.FindEntityByName( NULL, m_target ) ); + + if ( !GetGoalEnt() ) + { + Warning( "ReadyNPC()--%s couldn't find target %s\n", GetClassname(), STRING(m_target)); + } + else + { + StartTargetHandling( GetGoalEnt() ); + } + } +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- bool CAI_BaseNPC::HasInterruptCondition( int iCondition ) @@ -1935,6 +2303,15 @@ bool CAI_BaseNPC::QueryHearSound( CSound *pSound ) return false; } +#ifdef MAPBASE + if ( pSound->SoundContext() & SOUND_CONTEXT_OWNER_ALLIES ) + { + CBaseCombatCharacter *pOwner = ToBaseCombatCharacter(pSound->m_hOwner); + if (!pOwner || pOwner->IRelationType(this) != D_LI) + return false; + } +#endif + if ( pSound->IsSoundType( SOUND_PLAYER ) && GetState() == NPC_STATE_IDLE && !FVisible( pSound->GetSoundReactOrigin() ) ) { // NPC's that are IDLE should disregard player movement sounds if they can't see them. @@ -1955,6 +2332,22 @@ bool CAI_BaseNPC::QueryHearSound( CSound *pSound ) if( ShouldIgnoreSound( pSound ) ) return false; +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_QueryHearSound.CanRunInScope(m_ScriptScope)) + { + HSCRIPT hSound = g_pScriptVM->RegisterInstance( pSound ); + + ScriptVariant_t functionReturn = true; + ScriptVariant_t args[] = { hSound }; + g_Hook_QueryHearSound.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( hSound ); + + if (functionReturn.m_bool == false) + return false; + } +#endif + return true; } @@ -1962,12 +2355,31 @@ bool CAI_BaseNPC::QueryHearSound( CSound *pSound ) bool CAI_BaseNPC::QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC ) { + bool bValid = true; + if ( bOnlyHateOrFearIfNPC && pEntity->IsNPC() ) { Disposition_t disposition = IRelationType( pEntity ); - return ( disposition == D_HT || disposition == D_FR ); + bValid = ( disposition == D_HT || disposition == D_FR ); } - return true; + +#ifdef MAPBASE_VSCRIPT + if (bValid) + { + if (m_ScriptScope.IsInitialized() && g_Hook_QuerySeeEntity.CanRunInScope(m_ScriptScope)) + { + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript(pEntity) }; + if (g_Hook_QuerySeeEntity.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_bool == false) + bValid = false; + } + } + } +#endif + + return bValid; } //----------------------------------------------------------------------------- @@ -2129,7 +2541,7 @@ void CAI_BaseNPC::OnListened() case SOUND_PLAYER_VEHICLE: condition = COND_HEAR_PLAYER; break; default: - DevMsg( "**ERROR: NPC %s hearing sound of unknown type %d!\n", GetClassname(), pCurrentSound->SoundType() ); + CGMsg( 1, CON_GROUP_NPC_AI, "**ERROR: NPC %s hearing sound of unknown type %d!\n", GetClassname(), pCurrentSound->SoundType() ); break; } } @@ -2317,7 +2729,7 @@ CSound* CAI_BaseNPC::GetBestSound( int validTypes ) return m_pLockedBestSound; CSound *pResult = GetSenses()->GetClosestSound( false, validTypes ); if ( pResult == NULL) - DevMsg( "Warning: NULL Return from GetBestSound\n" ); // condition previously set now no longer true. Have seen this when play too many sounds... + CGMsg( 1, CON_GROUP_NPC_AI, "Warning: NULL Return from GetBestSound\n" ); // condition previously set now no longer true. Have seen this when play too many sounds... return pResult; } @@ -2329,7 +2741,7 @@ CSound* CAI_BaseNPC::GetBestScent( void ) { CSound *pResult = GetSenses()->GetClosestSound( true ); if ( pResult == NULL) - DevMsg("Warning: NULL Return from GetBestScent\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Warning: NULL Return from GetBestScent\n" ); return pResult; } @@ -3354,6 +3766,9 @@ void CAI_BaseNPC::UpdateSleepState( bool bInPVS ) { if ( GetSleepState() > AISS_AWAKE ) { +#ifdef MAPBASE +#define Wake() Wake(pLocalPlayer) +#endif CBasePlayer *pLocalPlayer = AI_GetSinglePlayer(); if ( !pLocalPlayer ) { @@ -3414,6 +3829,9 @@ void CAI_BaseNPC::UpdateSleepState( bool bInPVS ) } } } +#ifdef MAPBASE +#undef Wake +#endif } else { @@ -3884,6 +4302,12 @@ bool CAI_BaseNPC::CheckPVSCondition() { bool bInPVS = ( UTIL_FindClientInPVS( edict() ) != NULL ) || (UTIL_ClientPVSIsExpanded() && UTIL_FindClientInVisibilityPVS( edict() )); +#ifdef MAPBASE + // We can be in a player's PVS if there is an active point_camera nearby (fixes issues with choreo) + if (!bInPVS && UTIL_FindRTCameraInEntityPVS( edict() )) + bInPVS = true; +#endif + if ( bInPVS ) SetCondition( COND_IN_PVS ); else @@ -4176,6 +4600,24 @@ int CAI_BaseNPC::CapabilitiesGet( void ) const return capability; } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Adds capabilities to this NPC +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputAddCapabilities( inputdata_t &inputdata ) +{ + CapabilitiesAdd(inputdata.value.Int()); +} + +//------------------------------------------------------------------------------ +// Purpose: Removes capabilities from this NPC +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputRemoveCapabilities( inputdata_t &inputdata ) +{ + CapabilitiesRemove(inputdata.value.Int()); +} +#endif + // Set capability mask int CAI_BaseNPC::CapabilitiesAdd( int capability ) { @@ -4379,7 +4821,11 @@ void CAI_BaseNPC::SetState( NPC_STATE State ) if ( GetEnemy() != NULL ) { SetEnemy( NULL ); // not allowed to have an enemy anymore. +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_NPC_AI, "Stripped enemy pointer from NPC going back to idle\n" ); +#else DevMsg( 2, "Stripped\n" ); +#endif } break; } @@ -4398,6 +4844,20 @@ void CAI_BaseNPC::SetState( NPC_STATE State ) // Notify the character that its state has changed. if( fNotifyChange ) { +#ifdef MAPBASE + // Doing OnStateChange here instead of in OnStateChange() to prevent override shenanigans. + + // Assume our enemy is the activator. + // States that don't have an enemy have a NULL activator, which is fine. + CBaseEntity *pActivator = GetEnemy(); + + // If we entered a script, use the scripted_sequence as the activator + if (m_NPCState == NPC_STATE_SCRIPT) + pActivator = m_hCine; + + m_OnStateChange.Set(m_NPCState, pActivator, this); +#endif + OnStateChange( OldState, m_NPCState ); } } @@ -4414,10 +4874,39 @@ void CAI_BaseNPC::Wake( bool bFireOutput ) if ( GetSleepState() != AISS_AWAKE ) { m_nWakeTick = gpGlobals->tickcount; +#ifndef MAPBASE SetSleepState( AISS_AWAKE ); +#endif RemoveEffects( EF_NODRAW ); if ( bFireOutput ) +#ifdef MAPBASE + { + // Activator is based on sleep state + CBaseEntity *pActivator = this; + + switch (GetSleepState()) + { + case AISS_WAITING_FOR_THREAT: + pActivator = GetEnemy(); + break; + + case AISS_WAITING_FOR_PVS: + case AISS_AUTO_PVS: + case AISS_AUTO_PVS_AFTER_PVS: + pActivator = UTIL_GetLocalPlayer(); + break; + + case AISS_WAITING_FOR_INPUT: + // I can't really do this here, but InputWake() uses the new function with pActivator, so it's fine + break; + } + + m_OnWake.FireOutput( pActivator, this ); + } + SetSleepState( AISS_AWAKE ); +#else m_OnWake.FireOutput( this, this ); +#endif if ( m_bWakeSquad && GetSquad() ) { @@ -4435,6 +4924,37 @@ void CAI_BaseNPC::Wake( bool bFireOutput ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_BaseNPC::Wake( CBaseEntity *pActivator ) +{ + if ( GetSleepState() != AISS_AWAKE ) + { + m_nWakeTick = gpGlobals->tickcount; + RemoveEffects( EF_NODRAW ); + + m_OnWake.FireOutput( pActivator, this ); + + SetSleepState( AISS_AWAKE ); + + if ( m_bWakeSquad && GetSquad() ) + { + AISquadIter_t iter; + for ( CAI_BaseNPC *pSquadMember = GetSquad()->GetFirstMember( &iter ); pSquadMember; pSquadMember = GetSquad()->GetNextMember( &iter ) ) + { + if ( pSquadMember->IsAlive() && pSquadMember != this ) + { + pSquadMember->m_bWakeSquad = false; + pSquadMember->Wake(pActivator); + } + } + + } + } +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_BaseNPC::Sleep() @@ -4698,7 +5218,7 @@ void CAI_BaseNPC::GatherConditions( void ) // @Note (toml 05-05-04): There seems to be a case where an NPC can not respond // to COND_NEW_ENEMY. Only evidence right now is save // games after the fact, so for now, just patching it up - DevMsg( 2, "Had to force COND_NEW_ENEMY\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "Had to force COND_NEW_ENEMY\n" ); SetCondition(COND_NEW_ENEMY); } } @@ -4750,8 +5270,30 @@ void CAI_BaseNPC::PrescheduleThink( void ) CheckForScriptedNPCInteractions(); #endif +#ifdef MAPBASE + // Please excuse the readability here. + if (CapabilitiesGet() & bits_CAP_USE_WEAPONS) + { + if ( CanUnholsterWeapon() ) + { + // If we should have our gun out, fetch it + if ( ShouldUnholsterWeapon() && m_iDesiredWeaponState == DESIREDWEAPONSTATE_IGNORE ) + { + SetDesiredWeaponState( DESIREDWEAPONSTATE_UNHOLSTERED ); + } + } + else if (m_iDesiredWeaponState == DESIREDWEAPONSTATE_UNHOLSTERED) + { + // If we cannot have our gun out, refuse to fetch it + SetDesiredWeaponState( DESIREDWEAPONSTATE_IGNORE ); + } + + // If our desired weapon state is not the current, fix it + if( (m_iDesiredWeaponState == DESIREDWEAPONSTATE_HOLSTERED || m_iDesiredWeaponState == DESIREDWEAPONSTATE_UNHOLSTERED || m_iDesiredWeaponState == DESIREDWEAPONSTATE_HOLSTERED_DESTROYED ) ) +#else // If we use weapons, and our desired weapon state is not the current, fix it if( (CapabilitiesGet() & bits_CAP_USE_WEAPONS) && (m_iDesiredWeaponState == DESIREDWEAPONSTATE_HOLSTERED || m_iDesiredWeaponState == DESIREDWEAPONSTATE_UNHOLSTERED || m_iDesiredWeaponState == DESIREDWEAPONSTATE_HOLSTERED_DESTROYED ) ) +#endif { if ( IsAlive() && !IsInAScript() ) { @@ -4774,6 +5316,9 @@ void CAI_BaseNPC::PrescheduleThink( void ) m_iDesiredWeaponState = DESIREDWEAPONSTATE_IGNORE; } } +#ifdef MAPBASE + } +#endif } //----------------------------------------------------------------------------- @@ -5130,6 +5675,62 @@ NPC_STATE CAI_BaseNPC::SelectIdealState( void ) return m_IdealNPCState; } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Creates a new weapon and makes us equip it. +//------------------------------------------------------------------------------ +CBaseCombatWeapon *CAI_BaseNPC::GiveWeapon( string_t iszWeaponName, bool bDiscardCurrent ) +{ + CBaseCombatWeapon *pWeapon = Weapon_Create( STRING(iszWeaponName) ); + if ( !pWeapon ) + { + Warning( "Couldn't create weapon %s to give NPC %s.\n", STRING(iszWeaponName), GetDebugName() ); + return NULL; + } + + // If I have a weapon already, drop it + if ( bDiscardCurrent && GetActiveWeapon() ) + { + Weapon_Drop( GetActiveWeapon() ); + } + + // If I have a name, make my weapon match it with "_weapon" appended + if ( GetEntityName() != NULL_STRING ) + { + pWeapon->SetName( AllocPooledString(UTIL_VarArgs("%s_weapon", STRING(GetEntityName()) )) ); + } + + Weapon_Equip( pWeapon ); + + // Handle this case + OnGivenWeapon( pWeapon ); + + return pWeapon; +} + +//------------------------------------------------------------------------------ +// Purpose: Creates a new weapon and puts it in our inventory. +//------------------------------------------------------------------------------ +CBaseCombatWeapon *CAI_BaseNPC::GiveWeaponHolstered( string_t iszWeaponName ) +{ + CBaseCombatWeapon *pWeapon = Weapon_Create( STRING(iszWeaponName) ); + if ( !pWeapon ) + { + Warning( "Couldn't create weapon %s to give NPC %s.\n", STRING(iszWeaponName), GetDebugName() ); + return NULL; + } + + // If I have a name, make my weapon match it with "_weapon" appended + if ( GetEntityName() != NULL_STRING ) + { + pWeapon->SetName( AllocPooledString(UTIL_VarArgs("%s_weapon", STRING(GetEntityName()) )) ); + } + + Weapon_EquipHolstered( pWeapon ); + + return pWeapon; +} +#else //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void CAI_BaseNPC::GiveWeapon( string_t iszWeaponName ) @@ -5158,6 +5759,7 @@ void CAI_BaseNPC::GiveWeapon( string_t iszWeaponName ) // Handle this case OnGivenWeapon( pWeapon ); } +#endif //----------------------------------------------------------------------------- // Rather specific function that tells us if an NPC is in the process of @@ -5599,6 +6201,11 @@ void CAI_BaseNPC::GatherEnemyConditions( CBaseEntity *pEnemy ) EHANDLE hEnemy; hEnemy.Set( GetEnemy() ); +#ifdef MAPBASE + if (hEnemy->IsPlayer()) + m_OnFoundPlayer.Set(hEnemy, hEnemy, this); + m_OnFoundEnemy.Set(hEnemy, hEnemy, this); +#else if (GetEnemy()->IsPlayer()) { m_OnFoundPlayer.Set(hEnemy, this, this); @@ -5608,6 +6215,7 @@ void CAI_BaseNPC::GatherEnemyConditions( CBaseEntity *pEnemy ) { m_OnFoundEnemy.Set(hEnemy, this, this); } +#endif } Remember( bits_MEMORY_HAD_LOS ); } @@ -5904,6 +6512,136 @@ CAI_BaseNPC *CAI_BaseNPC::CreateCustomTarget( const Vector &vecOrigin, float dur #endif// HL2_DLL } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: This is used by TranslateActivity() before anything else. +// Input : eNewActivity - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CAI_BaseNPC::TranslateCrouchActivity( Activity eNewActivity ) +{ + if (CapabilitiesGet() & bits_CAP_DUCK && CanTranslateCrouchActivity()) + { + // ======================================================================== + // The main issue with cover hint nodes is that crouch activities are not translated at the right time + // in the activity translation process. Weapons aren't given a chance to translate from them + // and therefore the crouch activities on many NPCs are inaccessible. + // + // Regular, non-hint-node crouching seen on Combine soldiers and Episodic Alyx + // seemingly don't work when put here, so don't bother. + // ======================================================================== + Activity nCoverActivity = eNewActivity; + if (eNewActivity == ACT_RELOAD) + { + nCoverActivity = GetReloadActivity(GetHintNode()); + } + // INCOVER is synonymous with crouching at crouch cover nodes. + // Any time we need to crouch at cover is when INCOVER is valid. + else if (HasMemory(bits_MEMORY_INCOVER)) + { + if (eNewActivity == ACT_IDLE || eNewActivity == ACT_COVER) + { + // They stick to cover sometimes, but that might just be when they can't path to the enemy. + if (GetState() == NPC_STATE_COMBAT /*&& !IsCurSchedule(SCHED_COMBAT_STAND, false)*/) + nCoverActivity = GetCoverActivity(GetHintNode()); + } + else if (eNewActivity == ACT_RANGE_ATTACK1) + { + // Soldiers are the only ones I've seen attack while INCOVER, + // so I don't think we have to give it its own function. + CAI_Hint *pHint = GetHintNode(); + if (pHint) + { + if (pHint->HintType() == HINT_TACTICAL_COVER_LOW) + { + nCoverActivity = ACT_RANGE_ATTACK1_LOW; + } + else if (pHint->HintType() == HINT_TACTICAL_COVER_MED) + { +#if EXPANDED_HL2_COVER_ACTIVITIES + nCoverActivity = ACT_RANGE_ATTACK1_MED; +#else + nCoverActivity = ACT_RANGE_ATTACK1_LOW; +#endif + } + } + } + } + + if (nCoverActivity != ACT_IDLE) + eNewActivity = nCoverActivity; + + /* + // --------------------------------------------------------------- + // Some NPCs don't have a cover activity defined so just use idle + // --------------------------------------------------------------- + if (nCoverActivity != eNewActivity) + { + if (SelectWeightedSequence(nCoverActivity) != ACTIVITY_NOT_AVAILABLE) + { + eNewActivity = nCoverActivity; + } + else if (eNewActivity == ACT_COVER) + { + // Untranslated ACT_COVER should revert to ACT_IDLE + eNewActivity = ACT_IDLE; + } + } + */ + } + + return eNewActivity; +} + +//----------------------------------------------------------------------------- +// Purpose: Backup activity (NPC version of Weapon_BackupActivity) +// This only gets called if the NPC absolutely does not have an animation. +// This means if we don't return another activity, the NPC will most likely T-pose. +// Input : eNewActivity - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CAI_BaseNPC::NPC_BackupActivity( Activity eNewActivity ) +{ + //if (eNewActivity == ACT_DROP_WEAPON) + // return TranslateActivity(ACT_IDLE); + + // --------------------------------------------- + + // Accounts for certain act busy activities that aren't on all NPCs. + if (eNewActivity == ACT_BUSY_QUEUE || eNewActivity == ACT_BUSY_STAND) + return TranslateActivity(ACT_IDLE); + + // --------------------------------------------- + + if (eNewActivity == ACT_WALK_ANGRY) + return TranslateActivity(ACT_WALK); + + // --------------------------------------------- + + // If one climbing animation isn't available, use the other + if (eNewActivity == ACT_CLIMB_DOWN) + return ACT_CLIMB_UP; + else if (eNewActivity == ACT_CLIMB_UP) + return ACT_CLIMB_DOWN; + + // --------------------------------------------- + + switch (eNewActivity) + { + case ACT_COVER_MED: eNewActivity = ACT_COVER_LOW; break; +#if EXPANDED_HL2_COVER_ACTIVITIES + case ACT_RANGE_AIM_MED: eNewActivity = ACT_RANGE_AIM_LOW; break; + case ACT_RANGE_ATTACK1_MED: eNewActivity = ACT_RANGE_ATTACK1_LOW; break; +#endif + } + + //if (eNewActivity == ACT_COVER) + // return TranslateActivity(ACT_IDLE); + + return eNewActivity; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : eNewActivity - @@ -5911,6 +6649,51 @@ CAI_BaseNPC *CAI_BaseNPC::CreateCustomTarget( const Vector &vecOrigin, float dur //----------------------------------------------------------------------------- Activity CAI_BaseNPC::NPC_TranslateActivity( Activity eNewActivity ) { +#if EXPANDED_NAVIGATION_ACTIVITIES + if ( GetNavType() == NAV_CLIMB && eNewActivity == ACT_IDLE ) + { + // Schedules which break into idle activities should try to maintain the climbing animation. + return ACT_CLIMB_IDLE; + } +#endif + +#ifdef MAPBASE + Assert( eNewActivity != ACT_INVALID ); + + if (IsCrouching()) + { + switch (eNewActivity) + { + case ACT_RANGE_ATTACK1: eNewActivity = ACT_RANGE_ATTACK1_LOW; break; + case ACT_RELOAD: eNewActivity = ACT_RELOAD_LOW; break; + case ACT_IDLE: eNewActivity = ACT_RANGE_AIM_LOW; break; // ACT_CROUCHIDLE is more-or-less deprecated and not friendly to weapon translation + } + } + +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_TranslateActivity.CanRunInScope(m_ScriptScope)) + { + // activity, activity_id + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { GetActivityName(eNewActivity), (int)eNewActivity }; + if (g_Hook_TranslateActivity.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_INTEGER) + { + Activity activity = (Activity)functionReturn.m_int; + if (activity != ACT_INVALID) + eNewActivity = (Activity)functionReturn.m_int; + } + else + { + Activity activity = (Activity)GetActivityID( functionReturn.m_pszString ); + if (activity != ACT_INVALID) + eNewActivity = activity; + } + } + } +#endif +#else Assert( eNewActivity != ACT_INVALID ); if (eNewActivity == ACT_RANGE_ATTACK1) @@ -5967,6 +6750,7 @@ Activity CAI_BaseNPC::NPC_TranslateActivity( Activity eNewActivity ) return nCoverActivity; } } +#endif return eNewActivity; } @@ -5986,6 +6770,13 @@ Activity CAI_BaseNPC::TranslateActivity( Activity idealActivity, Activity *pIdea Activity last; Activity current; +#ifdef MAPBASE + // Crouch activities are translated before everything else. + idealActivity = TranslateCrouchActivity( idealActivity ); + //if ( idealWeaponActivity != idealActivity /*&& HaveSequenceForActivity(idealWeaponActivity)*/ ) + // idealActivity = idealWeaponActivity; +#endif + idealWeaponActivity = Weapon_TranslateActivity( idealActivity, &bIdealWeaponRequired ); if ( pIdealWeaponActivity ) *pIdealWeaponActivity = idealWeaponActivity; @@ -6013,6 +6804,12 @@ Activity CAI_BaseNPC::TranslateActivity( Activity idealActivity, Activity *pIdea if ( HaveSequenceForActivity( weaponTranslation ) ) return weaponTranslation; +#ifdef MAPBASE + // This is used so NPCs can use any weapon, restored AR2 activities on one NPC don't T-pose another, etc. + Activity backupActivity = Weapon_BackupActivity(baseTranslation, bWeaponRequired); + if (baseTranslation != backupActivity && HaveSequenceForActivity(backupActivity)) + return backupActivity; +#endif if ( bWeaponRequired ) { @@ -6033,11 +6830,31 @@ Activity CAI_BaseNPC::TranslateActivity( Activity idealActivity, Activity *pIdea return baseTranslation; if ( idealWeaponActivity != baseTranslation && HaveSequenceForActivity( idealWeaponActivity ) ) +#ifdef MAPBASE + return idealWeaponActivity; +#else return idealActivity; +#endif if ( idealActivity != idealWeaponActivity && HaveSequenceForActivity( idealActivity ) ) return idealActivity; +#ifdef MAPBASE + // We absolutely do not have an activity for this. + // Do the same as above, but with any backup activity we may have available. + backupActivity = NPC_BackupActivity(baseTranslation); + if (backupActivity != baseTranslation && HaveSequenceForActivity(backupActivity)) + return backupActivity; + + backupActivity = NPC_BackupActivity(idealWeaponActivity); + if (backupActivity != idealWeaponActivity && HaveSequenceForActivity(backupActivity)) + return backupActivity; + + backupActivity = NPC_BackupActivity(idealActivity); + if (backupActivity != idealActivity && HaveSequenceForActivity(backupActivity)) + return backupActivity; +#endif + Assert( !HaveSequenceForActivity( idealActivity ) ); if ( idealActivity == ACT_RUN ) { @@ -6066,7 +6883,12 @@ void CAI_BaseNPC::ResolveActivityToSequence(Activity NewActivity, int &iSequence translatedActivity = TranslateActivity( NewActivity, &weaponActivity ); +#ifdef MAPBASE + // Cover cases where TranslateActivity() returns a sequence by using ACT_SCRIPT_CUSTOM_MOVE + if ( NewActivity == ACT_SCRIPT_CUSTOM_MOVE || translatedActivity == ACT_SCRIPT_CUSTOM_MOVE ) +#else if ( NewActivity == ACT_SCRIPT_CUSTOM_MOVE ) +#endif { iSequence = GetScriptCustomMoveSequence(); } @@ -6252,6 +7074,23 @@ void CAI_BaseNPC::SetIdealActivity( Activity NewActivity ) // Perform translation in case we need to change sequences within a single activity, // such as between a standing idle and a crouching idle. ResolveActivityToSequence(m_IdealActivity, m_nIdealSequence, m_IdealTranslatedActivity, m_IdealWeaponActivity); + +#ifdef MAPBASE + // Check if we need a gesture to imitate this sequence + if ( ShouldPlayFakeSequenceGesture( m_IdealActivity, m_IdealTranslatedActivity ) ) + { + Activity nGesture = SelectFakeSequenceGesture( m_IdealActivity, m_IdealTranslatedActivity ); + if (nGesture != -1) + { + PlayFakeSequenceGesture( nGesture, m_IdealActivity, m_IdealTranslatedActivity ); + } + } + else if (GetFakeSequenceGesture() != -1) + { + // Reset the current gesture sequence if there is one + ResetFakeSequenceGesture(); + } +#endif } @@ -6300,6 +7139,14 @@ void CAI_BaseNPC::AdvanceToIdealActivity(void) //DevMsg("%s: Unable to get from sequence %s to %s!\n", GetClassname(), GetSequenceName(GetSequence()), GetSequenceName(m_nIdealSequence)); SetActivity(m_IdealActivity); } + +#ifdef MAPBASE + // If there was a gesture imitating a sequence, get rid of it + if ( GetFakeSequenceGesture() != -1 ) + { + ResetFakeSequenceGesture(); + } +#endif } @@ -6357,6 +7204,12 @@ void CAI_BaseNPC::MaintainActivity(void) } // Else a transition sequence is in progress, do nothing. } +#ifdef MAPBASE + else if (GetFakeSequenceGesture() != -1) + { + // Don't advance even if the sequence gesture is finished, as advancing would just play the original activity afterwards + } +#endif // Else get a specific sequence for the activity and try to transition to that. else { @@ -6375,26 +7228,118 @@ void CAI_BaseNPC::MaintainActivity(void) } -//----------------------------------------------------------------------------- -// Purpose: Returns true if our ideal activity has finished playing. -//----------------------------------------------------------------------------- -bool CAI_BaseNPC::IsActivityFinished( void ) +#ifdef MAPBASE +bool CAI_BaseNPC::ShouldPlayFakeSequenceGesture( Activity nActivity, Activity nTranslatedActivity ) { - return (IsSequenceFinished() && (GetSequence() == m_nIdealSequence)); -} + // Don't do anything if we're resetting our activity + if (GetActivity() == ACT_RESET) + return false; -//----------------------------------------------------------------------------- -// Purpose: Checks to see if the activity is one of the standard phase-matched movement activities -// Input : activity -//----------------------------------------------------------------------------- -bool CAI_BaseNPC::IsActivityMovementPhased( Activity activity ) -{ - switch( activity ) + // No need to do this while we're moving or for sequences which will make us move + if (IsMoving()) + return false; + + if (ai_debug_fake_sequence_gestures_always_play.GetBool()) + return true; + +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_ShouldPlayFakeSequenceGesture.CanRunInScope(m_ScriptScope)) { - case ACT_WALK: - case ACT_WALK_AIM: - case ACT_WALK_CROUCH: - case ACT_WALK_CROUCH_AIM: + // activity, translatedActivity + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { GetActivityName( nActivity ), GetActivityName( nTranslatedActivity ) }; + if (g_Hook_ShouldPlayFakeSequenceGesture.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_BOOLEAN) + return functionReturn.m_bool; + } + } +#endif + + if (GetHintNode() && GetHintNode()->HintActivityName() != NULL_STRING) + { + switch (GetHintNode()->HintType()) + { + // Cover nodes with custom activities should allow NPCs to do things like reload while in cover. + case HINT_TACTICAL_COVER_LOW: + case HINT_TACTICAL_COVER_MED: + case HINT_TACTICAL_COVER_CUSTOM: + if (HasMemory( bits_MEMORY_INCOVER )) + { + // Don't attack while using a custom animation in cover + if (nActivity != ACT_RANGE_ATTACK1 && nActivity != ACT_RANGE_ATTACK1_LOW) + return true; + } + break; + } + } + + return false; +} + +Activity CAI_BaseNPC::SelectFakeSequenceGesture( Activity nActivity, Activity nTranslatedActivity ) +{ + return GetGestureVersionOfActivity( nTranslatedActivity ); +} + +inline void CAI_BaseNPC::PlayFakeSequenceGesture( Activity nActivity, Activity nSequence, Activity nTranslatedSequence ) +{ + RestartGesture( nActivity, true, true ); + m_FakeSequenceGestureLayer = FindGestureLayer( nActivity ); + + switch ( nSequence ) + { + case ACT_RANGE_ATTACK1: + //case ACT_RANGE_ATTACK2: + { + OnRangeAttack1(); + + // FIXME: this seems a bit wacked + Weapon_SetActivity( Weapon_TranslateActivity( nSequence ), 0 ); + } break; + } +} + +inline int CAI_BaseNPC::GetFakeSequenceGesture() +{ + return m_FakeSequenceGestureLayer; +} + +void CAI_BaseNPC::ResetFakeSequenceGesture() +{ + SetLayerCycle( m_FakeSequenceGestureLayer, 1.0f ); + m_FakeSequenceGestureLayer = -1; +} +#endif + + +//----------------------------------------------------------------------------- +// Purpose: Returns true if our ideal activity has finished playing. +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::IsActivityFinished( void ) +{ +#ifdef MAPBASE + if (GetFakeSequenceGesture() != -1) + { + return IsLayerFinished( GetFakeSequenceGesture() ); + } +#endif + + return (IsSequenceFinished() && (GetSequence() == m_nIdealSequence)); +} + +//----------------------------------------------------------------------------- +// Purpose: Checks to see if the activity is one of the standard phase-matched movement activities +// Input : activity +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::IsActivityMovementPhased( Activity activity ) +{ + switch( activity ) + { + case ACT_WALK: + case ACT_WALK_AIM: + case ACT_WALK_CROUCH: + case ACT_WALK_CROUCH_AIM: case ACT_RUN: case ACT_RUN_AIM: case ACT_RUN_CROUCH: @@ -6415,6 +7360,15 @@ void CAI_BaseNPC::OnChangeActivity( Activity eNewActivity ) eNewActivity == ACT_WALK ) { Stand(); + +#ifdef MAPBASE + // Unlock custom cover nodes + if (GetHintNode() && GetHintNode()->HintType() == HINT_TACTICAL_COVER_CUSTOM && HasMemory(bits_MEMORY_INCOVER)) + { + GetHintNode()->Unlock( GetHintDelay( GetHintNode()->HintType() ) ); + SetHintNode( NULL ); + } +#endif } } @@ -6691,7 +7645,11 @@ void CAI_BaseNPC::SetHullSizeNormal( bool force ) if ( m_fIsUsingSmallHull || force ) { // Find out what the height difference will be between the versions and adjust our bbox accordingly to keep us level +#ifdef MAPBASE // From Alien Swarm SDK + const float flScale = MIN( 1.0f, GetModelScale() ); // NOTE: Cannot scale NPC bounding box up, as pathfinding will fail (hull needs to match the traces used for the node network) +#else const float flScale = GetModelScale(); +#endif Vector vecMins = ( GetHullMins() * flScale ); Vector vecMaxs = ( GetHullMaxs() * flScale ); @@ -6983,7 +7941,11 @@ void CAI_BaseNPC::OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseComb //----------------------------------------------------------------------------- bool CAI_BaseNPC::CanHolsterWeapon( void ) { +#ifdef MAPBASE + int seq = SelectWeightedSequence( TranslateActivity(ACT_DISARM) ); +#else int seq = SelectWeightedSequence( ACT_DISARM ); +#endif return (seq >= 0); } @@ -6995,12 +7957,22 @@ int CAI_BaseNPC::HolsterWeapon( void ) if ( IsWeaponHolstered() ) return -1; +#ifdef MAPBASE + Activity activity = TranslateActivity( ACT_DISARM ); + int iHolsterGesture = FindGestureLayer( activity ); + if ( iHolsterGesture != -1 ) + return iHolsterGesture; + + int iLayer = AddGesture( activity, true ); + //iLayer = AddGesture( ACT_GESTURE_DISARM, true ); +#else int iHolsterGesture = FindGestureLayer( ACT_DISARM ); if ( iHolsterGesture != -1 ) return iHolsterGesture; int iLayer = AddGesture( ACT_DISARM, true ); //iLayer = AddGesture( ACT_GESTURE_DISARM, true ); +#endif if (iLayer != -1) { @@ -7022,6 +7994,13 @@ int CAI_BaseNPC::HolsterWeapon( void ) ClearCondition(COND_NO_PRIMARY_AMMO); ClearCondition(COND_NO_SECONDARY_AMMO); } +#ifdef MAPBASE + else + { + // We don't have the animation, so just make our weapon holster instantaneously. + DoHolster(); + } +#endif return iLayer; } @@ -7034,18 +8013,40 @@ int CAI_BaseNPC::UnholsterWeapon( void ) if ( !IsWeaponHolstered() ) return -1; +#ifdef MAPBASE + Activity activity = TranslateActivity( ACT_ARM ); + int iHolsterGesture = FindGestureLayer( activity ); +#else int iHolsterGesture = FindGestureLayer( ACT_ARM ); +#endif if ( iHolsterGesture != -1 ) return iHolsterGesture; +#ifdef MAPBASE + int i = m_iLastHolsteredWeapon >= 0 && GetWeapon(m_iLastHolsteredWeapon) ? m_iLastHolsteredWeapon : -1; + if (i == -1) + { + // Set i to the first weapon you can find + for (i = 0; i < WeaponCount(); i++) + { + if (GetWeapon(i)) + break; + } + } +#else // Deploy the first weapon you can find for (int i = 0; i < WeaponCount(); i++) +#endif { if ( GetWeapon( i )) { SetActiveWeapon( GetWeapon(i) ); +#ifdef MAPBASE + int iLayer = AddGesture( TranslateActivity( ACT_ARM ), true ); +#else int iLayer = AddGesture( ACT_ARM, true ); +#endif //iLayer = AddGesture( ACT_GESTURE_ARM, true ); if (iLayer != -1) @@ -7056,6 +8057,13 @@ int CAI_BaseNPC::UnholsterWeapon( void ) m_iDesiredWeaponState = DESIREDWEAPONSTATE_CHANGING; } +#ifdef MAPBASE + else + { + // We don't have the animation, so just make our weapon unholster instantaneously. + DoUnholster(); + } +#endif // Refill the clip if ( GetActiveWeapon()->UsesClipsForAmmo1() ) @@ -7096,6 +8104,26 @@ void CAI_BaseNPC::InputHolsterAndDestroyWeapon( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CAI_BaseNPC::InputUnholsterWeapon( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Support for unholstering a specific weapon + if (inputdata.value.String()) + { + if (IsWeaponHolstered()) + { + for (int i=0;im_iClassname == inputdata.value.StringID() ) + { + //Weapon_Switch(m_hMyWeapons[i]); + //DoHolster(); + m_iLastHolsteredWeapon = i; + } + } + } + } +#endif + m_iDesiredWeaponState = DESIREDWEAPONSTATE_UNHOLSTERED; } @@ -7121,6 +8149,246 @@ bool CAI_BaseNPC::IsWeaponStateChanging( void ) return ( m_iDesiredWeaponState == DESIREDWEAPONSTATE_CHANGING || m_iDesiredWeaponState == DESIREDWEAPONSTATE_CHANGING_DESTROY ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Allows NPC to holster from more than just the animation event +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::DoHolster( void ) +{ + // Cache off the weapon. + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + + if (pWeapon) + { + // Mark this as our last weapon + for (int i = 0; i < MAX_WEAPONS; i++) + { + if (m_hMyWeapons[i].Get() == pWeapon) + { + // Set to this weapon if we don't have a "target" weapon to unholster + if (m_iLastHolsteredWeapon == -1) + m_iLastHolsteredWeapon = i; + + break; + } + } + + GetActiveWeapon()->Holster(); + SetActiveWeapon( NULL ); + + //Force the NPC to recalculate it's arrival activity since it'll most likely be wrong now that we don't have a weapon out. + GetNavigator()->SetArrivalSequence( ACT_INVALID ); + + if ( m_iDesiredWeaponState == DESIREDWEAPONSTATE_CHANGING_DESTROY ) + { + // Get rid of it! + UTIL_Remove( pWeapon ); + } + + if ( m_iDesiredWeaponState != DESIREDWEAPONSTATE_IGNORE ) + { + m_iDesiredWeaponState = DESIREDWEAPONSTATE_IGNORE; + m_Activity = ACT_RESET; + } + + return true; + } + else + { + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Allows NPC to unholster from more than just the animation event +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::DoUnholster( void ) +{ + if (GetActiveWeapon()) + { + GetActiveWeapon()->Deploy(); + + //Force the NPC to recalculate it's arrival activity since it'll most likely be wrong now. + GetNavigator()->SetArrivalSequence( ACT_INVALID ); + + if ( m_iDesiredWeaponState != DESIREDWEAPONSTATE_IGNORE ) + { + m_iDesiredWeaponState = DESIREDWEAPONSTATE_IGNORE; + m_Activity = ACT_RESET; + } + + // Clear last holstered weapon + m_iLastHolsteredWeapon = -1; + + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the NPC should be unholstering their weapon +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::ShouldUnholsterWeapon( void ) +{ + return GetState() == NPC_STATE_COMBAT; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the NPC can unholster their weapon +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::CanUnholsterWeapon( void ) +{ + // Don't unholster during special navigation + if ( GetNavType() == NAV_JUMP || GetNavType() == NAV_CLIMB ) + return false; + + return IsWeaponHolstered(); +} + +//------------------------------------------------------------------------------ +// Purpose: Give the NPC in question the weapon specified +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputGiveWeaponHolstered( inputdata_t &inputdata ) +{ + string_t iszWeaponName = inputdata.value.StringID(); + if ( iszWeaponName != NULL_STRING ) + { + GiveWeaponHolstered( iszWeaponName ); + } +} + +//------------------------------------------------------------------------------ +// Purpose: Makes the NPC change to the specified weapon via successive holster/unholster animations, creates it if it doesn't exist +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputChangeWeapon( inputdata_t &inputdata ) +{ + CBaseCombatWeapon *pSwitchTo = NULL; // The weapon itself + int iSwitchTo; // Index in m_hMyWeapons + for (int i=0;im_iClassname == inputdata.value.StringID() ) + { + pSwitchTo = m_hMyWeapons[i]; + iSwitchTo = i; + break; + } + } + + if (!pSwitchTo) + { + // We must not have it + pSwitchTo = GiveWeaponHolstered(inputdata.value.StringID()); + for (int i = 0; im_iClassname); + g_EventQueue.AddEvent(this, "UnholsterWeapon", variant, GetLayerDuration(iHolsterLayer) /*+ 0.65*/, this, this); + } +} + +//------------------------------------------------------------------------------ +// Purpose: Makes the NPC pick up the specified weapon if it can +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputPickupWeapon( inputdata_t &inputdata ) +{ + string_t iszWeaponName = inputdata.value.StringID(); + if (iszWeaponName == NULL_STRING) + return; + + // Doing a custom search implementation to prevent us from trying to pick up other people's weapons + // Also works generically so you could do things like "PickupWeapon > weapon_smg1" to pick up the nearest SMG + float flCurDist = MAX_TRACE_LENGTH; + CBaseCombatWeapon *pWeapon = NULL; + + CBaseEntity *pSearch = NULL; + while ((pSearch = gEntList.FindEntityGeneric(pSearch, STRING(iszWeaponName), this, inputdata.pActivator, inputdata.pCaller)) != NULL) + { + if (!pSearch->edict()) + continue; + + // Don't pick up non-weapons or weapons we can't use + CBaseCombatWeapon *pSearchWeapon = pSearch->MyCombatWeaponPointer(); + if (!pSearchWeapon || pSearchWeapon->GetOwner() || pSearchWeapon->IsLocked(this)) + continue; + + // If the weapon is marked to deny NPC pickup, only reject it if we're not searching for this weapon specifically. + // It might only have that spawnflag to prevent other NPCs from picking it up automatically. + // If we're searching for any weapon in general though (classnames or wildcards), don't use it. + if (pSearchWeapon->HasSpawnFlags( SF_WEAPON_NO_NPC_PICKUP ) && iszWeaponName != pSearchWeapon->GetEntityName()) + continue; + + float flDist = (pSearch->GetAbsOrigin() - GetAbsOrigin()).LengthSqr(); + if (flDist < flCurDist) + { + pWeapon = pSearchWeapon; + flCurDist = flDist; + } + } + + if (!pWeapon) + { + Msg("%s couldn't find %s to pick up\n", GetDebugName(), STRING(iszWeaponName)); + return; + } + + m_flNextWeaponSearchTime = gpGlobals->curtime + 10.0; + // Now lock the weapon for several seconds while we go to pick it up. + pWeapon->Lock( 10.0, this ); + SetTarget( pWeapon ); + SetSchedule(SCHED_NEW_WEAPON); +} + +//------------------------------------------------------------------------------ +// Purpose: Makes the NPC pick up the specified item if it can +//------------------------------------------------------------------------------ +void CAI_BaseNPC::InputPickupItem( inputdata_t &inputdata ) +{ + string_t iszItemName = inputdata.value.StringID(); + if (iszItemName == NULL_STRING) + return; + + // Searching generically allows for things like "PickupItem > item_health*" to pick up the nearest healthkit + CBaseEntity *pEntity = gEntList.FindEntityGenericNearest(STRING(iszItemName), GetLocalOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); + if (!pEntity) + return; + + SetTarget( pEntity ); + + // Can apply to anything, not just healthkits + SetSchedule(SCHED_GET_HEALTHKIT); +} +#endif + //----------------------------------------------------------------------------- // Set up the shot regulator based on the equipped weapon //----------------------------------------------------------------------------- @@ -7152,6 +8420,7 @@ void CAI_BaseNPC::InitRelationshipTable(void) } +#ifndef MAPBASE // Moved to CBaseCombatCharacter //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -7236,6 +8505,28 @@ void CAI_BaseNPC::AddRelationship( const char *pszRelationship, CBaseEntity *pAc } else { +#ifdef MAPBASE + if (!Q_strnicmp(entityString, "CLASS_", 5)) + { + // Go through all of the classes and find which one this is + Class_T resultClass = CLASS_NONE; + for (int i = 0; i < NUM_AI_CLASSES; i++) + { + if (FStrEq(g_pGameRules->AIClassText(i), entityString)) + { + resultClass = (Class_T)i; + } + } + + if (resultClass != CLASS_NONE) + { + AddClassRelationship( resultClass, disposition, priority ); + bFoundEntity = true; + } + } + + if (!bFoundEntity) +#endif DevWarning( "Couldn't set relationship to unknown entity or class (%s)!\n", entityString ); } } @@ -7244,6 +8535,7 @@ void CAI_BaseNPC::AddRelationship( const char *pszRelationship, CBaseEntity *pAc entityString = strtok(NULL," "); } } +#endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -7448,7 +8740,7 @@ bool CAI_BaseNPC::InitSquad( void ) { if ( !m_SquadName ) { - DevMsg(2, "Found %s that isn't in a squad\n",GetClassname()); + CGMsg( 2, CON_GROUP_NPC_AI, "Found %s that isn't in a squad\n", GetClassname() ); } else { @@ -7710,9 +9002,7 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) if (!pEnemy || !pEnemy->IsAlive()) { if ( pEnemy ) - { DbgEnemyMsg( this, " %s rejected: dead\n", pEnemy->GetDebugName() ); - } continue; } @@ -7787,9 +9077,7 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) { DbgEnemyMsg( this, " %s accepted (1)\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) - { DbgEnemyMsg( this, " (%s displaced)\n", pBestEnemy->GetDebugName() ); - } iBestPriority = IRelationPriority ( pEnemy ); iBestDistSq = (pEnemy->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); @@ -7803,9 +9091,7 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) { DbgEnemyMsg( this, " %s accepted\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) - { DbgEnemyMsg( this, " (%s displaced due to priority, %d > %d )\n", pBestEnemy->GetDebugName(), IRelationPriority( pEnemy ), iBestPriority ); - } // this entity is disliked MORE than the entity that we // currently think is the best visible enemy. No need to do // a distance check, just get mad at this one for now. @@ -7939,9 +9225,7 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) DbgEnemyMsg( this, " %s accepted\n", pEnemy->GetDebugName() ); if ( pBestEnemy ) - { DbgEnemyMsg( this, " (%s displaced due to distance/visibility)\n", pBestEnemy->GetDebugName() ); - } fBestSeen = fCurSeen; fBestVisible = fCurVisible; iBestDistSq = iDistSq; @@ -7950,9 +9234,7 @@ CBaseEntity *CAI_BaseNPC::BestEnemy( void ) bBestUnreachable = bUnreachable; } else - { DbgEnemyMsg( this, " %s rejected: lower priority\n", pEnemy->GetDebugName() ); - } } DbgEnemyMsg( this, "} == %s\n", pBestEnemy->GetDebugName() ); @@ -7976,6 +9258,24 @@ Activity CAI_BaseNPC::GetReloadActivity( CAI_Hint* pHint ) case HINT_TACTICAL_COVER_LOW: case HINT_TACTICAL_COVER_MED: { +#ifdef MAPBASE + if (HasMemory(bits_MEMORY_INCOVER)) + { + // Don't do that trace thing. INCOVER means we're already crouching. + nReloadActivity = ACT_RELOAD_LOW; + } + else + { + Vector vEyePos = GetAbsOrigin() + GetCrouchEyeOffset(); + // Check if this location will block the threat's line of sight to me + trace_t tr; + AI_TraceLOS(vEyePos, GetEnemy()->EyePosition(), this, &tr); + if (tr.fraction != 1.0) + { + nReloadActivity = ACT_RELOAD_LOW; + } + } +#else if (SelectWeightedSequence( ACT_RELOAD_LOW ) != ACTIVITY_NOT_AVAILABLE) { Vector vEyePos = GetAbsOrigin() + EyeOffset(ACT_RELOAD_LOW); @@ -7987,6 +9287,7 @@ Activity CAI_BaseNPC::GetReloadActivity( CAI_Hint* pHint ) nReloadActivity = ACT_RELOAD_LOW; } } +#endif break; } } @@ -8012,19 +9313,53 @@ Activity CAI_BaseNPC::GetCoverActivity( CAI_Hint *pHint ) { case HINT_TACTICAL_COVER_MED: { +#ifdef MAPBASE + // NPCs which lack ACT_COVER_MED should fall through to HINT_TACTICAL_COVER_LOW + if (SelectWeightedSequence( ACT_COVER_MED ) != ACTIVITY_NOT_AVAILABLE) + { + nCoverActivity = ACT_COVER_MED; + } +#else nCoverActivity = ACT_COVER_MED; break; +#endif } case HINT_TACTICAL_COVER_LOW: { +#ifdef MAPBASE + // Make sure nCoverActivity wasn't already assigned above, then fall through to HINT_TACTICAL_COVER_CUSTOM + if (nCoverActivity == ACT_INVALID) + nCoverActivity = ACT_COVER_LOW; +#else nCoverActivity = ACT_COVER_LOW; break; +#endif + } + +#ifdef MAPBASE + case HINT_TACTICAL_COVER_CUSTOM: + { + if (pHint->HintActivityName() != NULL_STRING) + { + nCoverActivity = (Activity)CAI_BaseNPC::GetActivityID( STRING(pHint->HintActivityName()) ); + if (nCoverActivity == ACT_INVALID) + { + m_iszSceneCustomMoveSeq = pHint->HintActivityName(); + nCoverActivity = ACT_SCRIPT_CUSTOM_MOVE; + } + } + break; } +#endif } } if ( nCoverActivity == ACT_INVALID ) +#ifdef MAPBASE + nCoverActivity = ACT_IDLE; +#else nCoverActivity = ACT_COVER; +#endif return nCoverActivity; } @@ -8043,7 +9378,6 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget ) { vecProjection.x = -vecTarget.y; vecProjection.y = vecTarget.x; - vecProjection.z = 0; return UTIL_VecToYaw( vecProjection - GetLocalOrigin() ); } @@ -8051,10 +9385,16 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget ) { vecProjection.x = vecTarget.y; vecProjection.y = vecTarget.x; - vecProjection.z = 0; return UTIL_VecToYaw( vecProjection - GetLocalOrigin() ); } +#ifdef MAPBASE + // Allow hint nodes to override the yaw without needing to control AI + else if (GetHintNode() && GetHintNode()->OverridesNPCYaw( this )) + { + return GetHintNode()->Yaw(); + } +#endif else { return UTIL_VecToYaw ( vecTarget - GetLocalOrigin() ); @@ -8078,7 +9418,7 @@ void CAI_BaseNPC::SetDefaultEyeOffset ( void ) { if ( Classify() != CLASS_NONE ) { - DevMsg( "WARNING: %s(%s) has no eye offset in .qc!\n", GetClassname(), STRING(GetModelName()) ); + CGMsg( 1, CON_GROUP_NPC_AI, "WARNING: %s(%s) has no eye offset in .qc!\n", GetClassname(), STRING( GetModelName() ) ); } VectorAdd( WorldAlignMins(), WorldAlignMaxs(), m_vDefaultEyeOffset ); m_vDefaultEyeOffset *= 0.75; @@ -8394,8 +9734,12 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) { if ( GetActiveWeapon() ) { +#ifdef MAPBASE + GetActiveWeapon()->Reload_NPC( true ); +#else GetActiveWeapon()->WeaponSound( RELOAD_NPC ); GetActiveWeapon()->m_iClip1 = GetActiveWeapon()->GetMaxClip1(); +#endif ClearCondition(COND_LOW_PRIMARY_AMMO); ClearCondition(COND_NO_PRIMARY_AMMO); ClearCondition(COND_NO_SECONDARY_AMMO); @@ -8415,8 +9759,12 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) case EVENT_WEAPON_RELOAD_FILL_CLIP: { if ( GetActiveWeapon() ) - { + { +#ifdef MAPBASE + GetActiveWeapon()->Reload_NPC( false ); +#else GetActiveWeapon()->m_iClip1 = GetActiveWeapon()->GetMaxClip1(); +#endif ClearCondition(COND_LOW_PRIMARY_AMMO); ClearCondition(COND_NO_PRIMARY_AMMO); ClearCondition(COND_NO_SECONDARY_AMMO); @@ -8431,7 +9779,11 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) case NPC_EVENT_OPEN_DOOR: { +#ifdef MAPBASE + CBasePropDoor *pDoor = m_hOpeningDoor; +#else CBasePropDoor *pDoor = (CBasePropDoor *)(CBaseEntity *)GetNavigator()->GetPath()->GetCurWaypoint()->GetEHandleData(); +#endif if (pDoor != NULL) { OpenPropDoorNow( pDoor ); @@ -8445,6 +9797,11 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) { if (pEvent->event == AE_NPC_HOLSTER) { +#ifdef MAPBASE + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if (DoHolster()) + m_OnHolsterWeapon.Set(pWeapon, pWeapon, this); +#else // Cache off the weapon. CBaseCombatWeapon *pWeapon = GetActiveWeapon(); @@ -8467,11 +9824,16 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) m_iDesiredWeaponState = DESIREDWEAPONSTATE_IGNORE; m_Activity = ACT_RESET; } +#endif return; } else if (pEvent->event == AE_NPC_DRAW) { +#ifdef MAPBASE + if (DoUnholster()) + m_OnUnholsterWeapon.Set(GetActiveWeapon(), GetActiveWeapon(), this); +#else if (GetActiveWeapon()) { GetActiveWeapon()->Deploy(); @@ -8485,6 +9847,7 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) m_Activity = ACT_RESET; } } +#endif return; } else if ( pEvent->event == AE_NPC_BODYDROP_HEAVY ) @@ -9565,6 +10928,20 @@ void CAI_BaseNPC::CollectShotStats( const Vector &vecShootOrigin, const Vector & //----------------------------------------------------------------------------- Vector CAI_BaseNPC::GetActualShootPosition( const Vector &shootOrigin ) { +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope(m_ScriptScope)) + { + // shootOrigin, target + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { shootOrigin, ToHScript( GetEnemy() ) }; + if (g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f) + return *functionReturn.m_pVector; + } + } +#endif + // Project the target's location into the future. Vector vecEnemyLKP = GetEnemyLKP(); Vector vecEnemyOffset = GetEnemy()->BodyTarget( shootOrigin ) - GetEnemy()->GetAbsOrigin(); @@ -9899,6 +11276,7 @@ int CAI_BaseNPC::PlayScriptedSentence( const char *pszSentence, float delay, flo return PlaySentence( pszSentence, delay, volume, soundlevel, pListener ); } +#ifndef MAPBASE // Moved to CBaseCombatCharacter //----------------------------------------------------------------------------- // Purpose: // Input : @@ -9973,6 +11351,7 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter * return NULL; } +#endif void CAI_BaseNPC::CorpseFallThink( void ) @@ -10272,7 +11651,7 @@ bool CAI_BaseNPC::ChooseEnemy( void ) } else if ( !fHaveCondNewEnemy && !fHaveCondLostEnemy && GetCurSchedule() ) { - DevMsg( 2, "WARNING: AI enemy went NULL but schedule (%s) is not interested\n", GetCurSchedule()->GetName() ); + CGMsg( 2, CON_GROUP_NPC_AI, "WARNING: AI enemy went NULL but schedule (%s) is not interested\n", GetCurSchedule()->GetName() ); } m_bSkippedChooseEnemy = false; @@ -10352,11 +11731,56 @@ bool CAI_BaseNPC::ChooseEnemy( void ) //========================================================= void CAI_BaseNPC::PickupWeapon( CBaseCombatWeapon *pWeapon ) { +#ifdef MAPBASE + if ( pWeapon->VPhysicsGetObject() && pWeapon->VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + pPlayer->ForceDropOfCarriedPhysObjects( pWeapon ); + } +#endif + pWeapon->OnPickedUp( this ); Weapon_Equip( pWeapon ); m_iszPendingWeapon = NULL_STRING; } +#ifdef MAPBASE +extern ConVar sk_healthvial; + +//------------------------------------------------------------------------------ +// Purpose: Moved from CNPC_Citizen to CAI_BaseNPC for new pickup input +//------------------------------------------------------------------------------ +void CAI_BaseNPC::PickupItem( CBaseEntity *pItem ) +{ + // Must cache number of elements in case any fire only once (therefore being removed after being fired) + int iNumElements = m_OnItemPickup.NumberOfElements(); + if (iNumElements > 0) + m_OnItemPickup.Set( pItem, pItem, this ); + + Assert( pItem != NULL ); + if( FClassnameIs( pItem, "item_health*" ) ) // item_healthkit, item_healthvial, item_healthkit_custom, etc. + { + if ( TakeHealth( static_cast(pItem)->GetItemAmount(), DMG_GENERIC ) ) + { + RemoveAllDecals(); + UTIL_Remove( pItem ); + } + } + else if ( FClassnameIs(pItem, "item_ammo_ar2_altfire") || FClassnameIs(pItem, "item_ammo_smg1_grenade") || + FClassnameIs(pItem, "weapon_frag") ) + { + AddGrenades( 1 ); + UTIL_Remove( pItem ); + } + + // Only warn if we didn't have any elements of OnItemPickup + else if (iNumElements <= 0) + { + DevMsg("%s doesn't know how to pick up %s!\n", GetClassname(), pItem->GetClassname() ); + } +} +#endif + //========================================================= // DropItem - dead npc drops named item //========================================================= @@ -10396,6 +11820,10 @@ CBaseEntity *CAI_BaseNPC::DropItem ( const char *pszItemName, Vector vecPos, QAn pItem->ApplyLocalAngularVelocityImpulse( AngularImpulse( 0, random->RandomFloat( 0, 100 ), 0 ) ); } +#ifdef MAPBASE + m_OnItemDrop.Set( pItem, pItem, this ); +#endif + return pItem; } else @@ -10631,6 +12059,9 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_FIELD( m_iInteractionPlaying, FIELD_INTEGER ), DEFINE_UTLVECTOR(m_ScriptedInteractions,FIELD_EMBEDDED), DEFINE_FIELD( m_flInteractionYaw, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_INPUT( m_iDynamicInteractionsAllowed, FIELD_INTEGER, "SetDynamicInteractions" ), +#endif DEFINE_EMBEDDED( m_CheckOnGroundTimer ), DEFINE_FIELD( m_vDefaultEyeOffset, FIELD_VECTOR ), DEFINE_FIELD( m_flNextEyeLookTime, FIELD_TIME ), @@ -10641,7 +12072,11 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_FIELD( m_flHeadYaw, FIELD_FLOAT ), DEFINE_FIELD( m_flHeadPitch, FIELD_FLOAT ), DEFINE_FIELD( m_flOriginalYaw, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bInAScript, FIELD_BOOLEAN, "SpawnWithStartScripting" ), +#else DEFINE_FIELD( m_bInAScript, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_scriptState, FIELD_INTEGER ), DEFINE_FIELD( m_hCine, FIELD_EHANDLE ), DEFINE_CUSTOM_FIELD( m_ScriptArrivalActivity, ActivityDataOps() ), @@ -10662,6 +12097,9 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_KEYFIELD( m_bIgnoreUnseenEnemies, FIELD_BOOLEAN , "ignoreunseenenemies"), DEFINE_EMBEDDED( m_ShotRegulator ), DEFINE_FIELD( m_iDesiredWeaponState, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_FIELD( m_iLastHolsteredWeapon, FIELD_INTEGER ), +#endif // m_pSquad Saved specially in ai_saverestore.cpp DEFINE_KEYFIELD(m_SquadName, FIELD_STRING, "squadname" ), DEFINE_FIELD( m_iMySquadSlot, FIELD_INTEGER ), @@ -10704,6 +12142,13 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_FIELD( m_bImportanRagdoll, FIELD_BOOLEAN ), DEFINE_FIELD( m_bPlayerAvoidState, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_FriendlyFireOverride, FIELD_INTEGER, "FriendlyFireOverride" ), + + DEFINE_KEYFIELD( m_flSpeedModifier, FIELD_FLOAT, "BaseSpeedModifier" ), + DEFINE_FIELD( m_FakeSequenceGestureLayer, FIELD_INTEGER ), +#endif + // Satisfy classcheck // DEFINE_FIELD( m_ScheduleHistory, CUtlVector < AIScheduleChoice_t > ), @@ -10745,11 +12190,21 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_OUTPUT( m_OnForcedInteractionStarted, "OnForcedInteractionStarted" ), DEFINE_OUTPUT( m_OnForcedInteractionAborted, "OnForcedInteractionAborted" ), DEFINE_OUTPUT( m_OnForcedInteractionFinished, "OnForcedInteractionFinished" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnItemPickup, "OnItemPickup" ), + DEFINE_OUTPUT( m_OnItemDrop, "OnItemDrop" ), +#endif // Inputs +#ifndef MAPBASE DEFINE_INPUTFUNC( FIELD_STRING, "SetRelationship", InputSetRelationship ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetEnemyFilter", InputSetEnemyFilter ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthFraction", InputSetHealthFraction ), +#else DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "BeginRappel", InputBeginRappel ), DEFINE_INPUTFUNC( FIELD_STRING, "SetSquad", InputSetSquad ), DEFINE_INPUTFUNC( FIELD_VOID, "Wake", InputWake ), @@ -10766,12 +12221,42 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_INPUTFUNC( FIELD_VOID, "DisableSpeedModifier", InputDisableSpeedModifier ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSpeedModRadius", InputSetSpeedModifierRadius ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSpeedModSpeed", InputSetSpeedModifierSpeed ), +#ifndef MAPBASE // Moved to CBaseCombatCharacter DEFINE_INPUTFUNC( FIELD_VOID, "HolsterWeapon", InputHolsterWeapon ), DEFINE_INPUTFUNC( FIELD_VOID, "HolsterAndDestroyWeapon", InputHolsterAndDestroyWeapon ), DEFINE_INPUTFUNC( FIELD_VOID, "UnholsterWeapon", InputUnholsterWeapon ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "ForceInteractionWithNPC", InputForceInteractionWithNPC ), DEFINE_INPUTFUNC( FIELD_STRING, "UpdateEnemyMemory", InputUpdateEnemyMemory ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetFriendlyFire", InputSetFriendlyFire ), + + DEFINE_INPUTFUNC( FIELD_STRING, "GiveWeaponHolstered", InputGiveWeaponHolstered ), + DEFINE_INPUTFUNC( FIELD_STRING, "ChangeWeapon", InputChangeWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "PickupWeapon", InputPickupWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "PickupItem", InputPickupItem ), + DEFINE_OUTPUT( m_OnHolsterWeapon, "OnHolsterWeapon" ), + DEFINE_OUTPUT( m_OnUnholsterWeapon, "OnUnholsterWeapon" ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddCapabilities", InputAddCapabilities ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveCapabilities", InputRemoveCapabilities ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetCondition", InputSetCondition ), + DEFINE_INPUTFUNC( FIELD_STRING, "ClearCondition", InputClearCondition ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetHintGroup", InputSetHintGroup ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetThinkNPC", InputSetThinkNPC ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDistLook", InputSetDistLook ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDistTooFar", InputSetDistTooFar ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeedModifier", InputSetSpeedModifier ), + + DEFINE_OUTPUT( m_OnStateChange, "OnStateChange" ), +#endif + // Function pointers DEFINE_USEFUNC( NPCUse ), DEFINE_THINKFUNC( CallNPCThink ), @@ -10780,6 +12265,118 @@ BEGIN_DATADESC( CAI_BaseNPC ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CAI_BaseNPC, CBaseCombatCharacter, "The base class all NPCs derive from." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetEnemy, "GetEnemy", "Get the NPC's current enemy." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetEnemy, "SetEnemy", "Set the NPC's current enemy." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetEnemyLKP, "GetEnemyLKP", "Get the last known position of the NPC's current enemy." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptFindEnemyMemory, "FindEnemyMemory", "Get information about the NPC's current enemy." ) + + DEFINE_SCRIPTFUNC( GetLastAttackTime, "Get the last time the NPC has used an attack (e.g. fired a bullet from a gun)." ) + DEFINE_SCRIPTFUNC( GetLastDamageTime, "Get the last time the NPC has been damaged." ) + DEFINE_SCRIPTFUNC( GetLastPlayerDamageTime, "Get the last time the NPC has been damaged by a player." ) + DEFINE_SCRIPTFUNC( GetLastEnemyTime, "Get the last time the NPC has seen an enemy." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetState, "GetNPCState", "Get the NPC's current state." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptWake, "Wake", "Awakens the NPC if it is currently asleep." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSleep, "Sleep", "Puts the NPC into a sleeping state." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSleepState, "GetSleepState", "Get the NPC's sleep state. (see AISS_ set of constants)" ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetSleepState, "SetSleepState", "Set the NPC's sleep state. (see AISS_ set of constants)" ) + DEFINE_SCRIPTFUNC( AddSleepFlags, "Add to the NPC's sleep flags. (see AI_SLEEP_ set of constants)" ) + DEFINE_SCRIPTFUNC( RemoveSleepFlags, "Remove from NPC's sleep flags. (see AI_SLEEP_ set of constants)" ) + DEFINE_SCRIPTFUNC( HasSleepFlags, "Return true if the NPC has the specified sleep flags. (see AI_SLEEP_ set of constants)" ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintGroup, "GetHintGroup", "Get the name of the NPC's hint group." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintNode, "GetHintNode", "Get the NPC's current AI hint." ) + + DEFINE_SCRIPTFUNC( CapabilitiesGet, "Get the capabilities the NPC currently possesses." ) + DEFINE_SCRIPTFUNC( CapabilitiesAdd, "Add capabilities to the NPC." ) + DEFINE_SCRIPTFUNC( CapabilitiesRemove, "Remove capabilities from the NPC." ) + DEFINE_SCRIPTFUNC( CapabilitiesClear, "Clear capabilities for the NPC." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetActivity, "GetActivity", "Get the NPC's current activity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetActivityID, "GetActivityID", "Get the NPC's current activity ID." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetActivity, "SetActivity", "Set the NPC's current activity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetActivityID, "SetActivityID", "Set the NPC's current activity ID." ) + DEFINE_SCRIPTFUNC( ResetActivity, "Reset the NPC's current activity." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptTranslateActivity, "TranslateActivity", "Translates the specified activity string and returns the translated activity ID." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptTranslateActivityID, "TranslateActivityID", "Translates the specified activity ID and returns the translated activity ID." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetGestureVersionOfActivity, "GetGestureVersionOfActivity", "Get the gesture activity counterpart of the specified sequence activity, if one exists." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetGestureVersionOfActivityID, "GetGestureVersionOfActivityID", "Get the gesture activity ID counterpart of the specified sequence activity ID, if one exists." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSequenceVersionOfGesture, "GetSequenceVersionOfGesture", "Get the sequence activity counterpart of the specified gesture activity, if one exists." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSequenceVersionOfGestureID, "GetSequenceVersionOfGestureID", "Get the sequence activity ID counterpart of the specified gesture activity ID, if one exists." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSchedule, "GetSchedule", "Get the NPC's current schedule." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetScheduleID, "GetScheduleID", "Get the NPC's current schedule ID." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetSchedule, "SetSchedule", "Set the NPC's current schedule." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetScheduleID, "SetScheduleID", "Set the NPC's current schedule ID." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetTask, "GetTask", "Get the NPC's current task." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptGetTaskID, "GetTaskID", "Get the NPC's current task ID." ) + DEFINE_SCRIPTFUNC( ClearSchedule, "Clear the NPC's current schedule for the specified reason." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptHasCondition, "HasCondition", "Get whether the NPC has a condition." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptHasConditionID, "HasConditionID", "Get whether the NPC has a condition ID." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptSetCondition, "SetCondition", "Set a condition on the NPC." ) + DEFINE_SCRIPTFUNC_NAMED( SetCondition, "SetConditionID", "Set a condition on the NPC by ID." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptClearCondition, "ClearCondition", "Clear a condition on the NPC." ) + DEFINE_SCRIPTFUNC_NAMED( ClearCondition, "ClearConditionID", "Clear a condition on the NPC by ID." ) + + DEFINE_SCRIPTFUNC( IsMoving, "Check if the NPC is moving." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetExpresser, "GetExpresser", "Get a handle for this NPC's expresser." ) + + DEFINE_SCRIPTFUNC( IsCommandable, "Check if the NPC is commandable." ) + DEFINE_SCRIPTFUNC( IsInPlayerSquad, "Check if the NPC is in the player's squad." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetCine, "GetCine", "Get the NPC's currently running scripted sequence if it has one." ) + DEFINE_SCRIPTFUNC( GetScriptState, "Get the NPC's current scripted sequence state." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetSquad, "GetSquad", "Get the NPC's squad if it has one." ) + DEFINE_SCRIPTFUNC( IsInSquad, "Returns true if the NPC is in a squad." ) + DEFINE_SCRIPTFUNC( NumWeaponsInSquad, "Get the number of weapons in a squad." ) + + DEFINE_SCRIPTFUNC( IsCrouching, "Returns true if the NPC is crouching." ) + DEFINE_SCRIPTFUNC( Crouch, "Tells the NPC to crouch." ) + DEFINE_SCRIPTFUNC( Stand, "Tells the NPC to stand if it is crouching." ) + + // + // Hooks + // + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_QueryHearSound, "QueryHearSound", FIELD_BOOLEAN, "Called when the NPC is deciding whether to hear a CSound or not." ) + DEFINE_SCRIPTHOOK_PARAM( "sound", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_QuerySeeEntity, "QuerySeeEntity", FIELD_BOOLEAN, "Called when the NPC is deciding whether to see an entity or not." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_TranslateActivity, "NPC_TranslateActivity", FIELD_VARIANT, "Called when the NPC is translating their current activity. The activity is provided in both string and ID form. Should return either an activity string or an activity ID. Return -1 to not translate." ) + DEFINE_SCRIPTHOOK_PARAM( "activity", FIELD_CSTRING ) + DEFINE_SCRIPTHOOK_PARAM( "activity_id", FIELD_INTEGER ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_TranslateSchedule, "NPC_TranslateSchedule", FIELD_VARIANT, "Called when the NPC is translating their current schedule. The schedule is provided in both string and ID form. Should return either a schedule string or a schedule ID. Return -1 to not translate." ) + DEFINE_SCRIPTHOOK_PARAM( "schedule", FIELD_CSTRING ) + DEFINE_SCRIPTHOOK_PARAM( "schedule_id", FIELD_INTEGER ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_GetActualShootPosition, "GetActualShootPosition", FIELD_VECTOR, "Called when the NPC is getting their actual shoot position, using the default shoot position as the parameter. (NOTE: NPCs which override this themselves might not always use this hook!)" ) + DEFINE_SCRIPTHOOK_PARAM( "shootOrigin", FIELD_VECTOR ) + DEFINE_SCRIPTHOOK_PARAM( "target", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_OverrideMove, "OverrideMove", FIELD_VOID, "Called when the NPC runs movement code, allowing the NPC's movement to be overridden by some other method. (NOTE: NPCs which override this themselves might not always use this hook!)" ) + DEFINE_SCRIPTHOOK_PARAM( "interval", FIELD_FLOAT ) + END_SCRIPTHOOK() + BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_ShouldPlayFakeSequenceGesture, "ShouldPlayFakeSequenceGesture", FIELD_BOOLEAN, "Called when an activity is set on a NPC. Returning true will make the NPC convert the activity into a gesture (if a gesture is available) and continue their current activity instead." ) + DEFINE_SCRIPTHOOK_PARAM( "activity", FIELD_CSTRING ) + DEFINE_SCRIPTHOOK_PARAM( "translatedActivity", FIELD_CSTRING ) + END_SCRIPTHOOK() + +END_SCRIPTDESC(); +#endif + BEGIN_SIMPLE_DATADESC( AIScheduleState_t ) DEFINE_FIELD( iCurTask, FIELD_INTEGER ), DEFINE_FIELD( fTaskStatus, FIELD_INTEGER ), @@ -10834,6 +12431,9 @@ BEGIN_SIMPLE_DATADESC( ScriptedNPCInteraction_t ) DEFINE_FIELD( vecRelativeOrigin, FIELD_VECTOR ), DEFINE_FIELD( angRelativeAngles, FIELD_VECTOR ), DEFINE_FIELD( vecRelativeVelocity, FIELD_VECTOR ), +#ifdef MAPBASE + DEFINE_FIELD( vecRelativeEndPos, FIELD_VECTOR ), +#endif DEFINE_FIELD( flDelay, FIELD_FLOAT ), DEFINE_FIELD( flDistSqr, FIELD_FLOAT ), DEFINE_FIELD( iszMyWeapon, FIELD_STRING ), @@ -10842,6 +12442,9 @@ BEGIN_SIMPLE_DATADESC( ScriptedNPCInteraction_t ) DEFINE_FIELD( matDesiredLocalToWorld, FIELD_VMATRIX ), DEFINE_FIELD( bValidOnCurrentEnemy, FIELD_BOOLEAN ), DEFINE_FIELD( flNextAttemptTime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_FIELD( MiscCriteria, FIELD_STRING ),//DEFINE_UTLVECTOR( MiscCriteria, FIELD_EMBEDDED ), +#endif END_DATADESC() //------------------------------------- @@ -11069,7 +12672,7 @@ void CAI_BaseNPC::DiscardScheduleState() // for now, just go back to idle and let the AI figure out what to do. SetState( NPC_STATE_IDLE ); SetIdealState( NPC_STATE_IDLE ); - DevMsg(1, "Scripted Sequence stripped on level transition for %s\n", GetDebugName() ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted Sequence stripped on level transition for %s\n", GetDebugName() ); } } @@ -11254,6 +12857,36 @@ bool CAI_BaseNPC::KeyValue( const char *szKeyName, const char *szValue ) return bResult; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + // Why was GetKeyValue("squadname") pointless again? + /* + if (FStrEq(szKeyName, "squadname")) + { + // "squadname" does change initially and in InputSetSquad(), but not in SetSquad() itself. + // Probably not in any other function that changes the squad either. This is needed so we get + // an accurate reading of the squad name. + GetSquad() ? + Q_strncpy(szValue, GetSquad()->GetName(), iMaxLen) : + Q_strncpy(szValue, "", iMaxLen); + } + else*/ if (FStrEq(szKeyName, "additionalequipment")) + { + if (GetActiveWeapon()) + Q_strncpy(szValue, GetActiveWeapon()->GetClassname(), iMaxLen); + else + return false; + } + else + return BaseClass::GetKeyValue(szKeyName, szValue, iMaxLen); + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Debug function to make this NPC freeze in place (or unfreeze). //----------------------------------------------------------------------------- @@ -11386,6 +13019,13 @@ CAI_BaseNPC::CAI_BaseNPC(void) m_bInChoreo = true; // assume so until call to UpdateEfficiency() SetCollisionGroup( COLLISION_GROUP_NPC ); + +#ifdef MAPBASE + m_iDynamicInteractionsAllowed = TRS_NONE; + m_flSpeedModifier = 1.0f; + + m_FakeSequenceGestureLayer = -1; +#endif } //----------------------------------------------------------------------------- @@ -11418,7 +13058,7 @@ void CAI_BaseNPC::UpdateOnRemove(void) if ( !m_bDidDeathCleanup ) { if ( m_NPCState == NPC_STATE_DEAD ) - DevMsg( "May not have cleaned up on NPC death\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "May not have cleaned up on NPC death\n" ); CleanupOnDeath( NULL, false ); } @@ -11533,6 +13173,7 @@ CAI_Pathfinder *CAI_BaseNPC::CreatePathfinder() return new CAI_Pathfinder( this ); } +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -11540,6 +13181,7 @@ void CAI_BaseNPC::InputSetRelationship( inputdata_t &inputdata ) { AddRelationship( inputdata.value.String(), inputdata.pActivator ); } +#endif //----------------------------------------------------------------------------- @@ -11552,6 +13194,39 @@ void CAI_BaseNPC::InputSetEnemyFilter( inputdata_t &inputdata ) m_hEnemyFilter = dynamic_cast(pFilter); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_BaseNPC::InputSetHealthFraction( inputdata_t &inputdata ) +{ + // npc_helicopter uses SetHealth() instead of the regular NPC practice of TakeHealth() and TakeDamage(). + // It also also uses 50, 75, etc. and scales it by 0.01 for some reason. + // We're using the same model as InputSetHealth() and just letting npc_helicopter override it. No big deal. + // We're also adding support for its "whole number * 0.01" thing too. + float flFactor = inputdata.value.Float(); + if ( flFactor > 1.0f ) + { + flFactor *= 0.01f; + } + + // Excuse the complication... + float flNewHealth = (GetMaxHealth() * flFactor); + int iNewHealth = (int)flNewHealth; + if (flNewHealth < (GetMaxHealth() / 2)) + iNewHealth = (int)ceil(flNewHealth); + + int iDelta = abs(GetHealth() - iNewHealth); + if ( iNewHealth > GetHealth() ) + { + TakeHealth( iDelta, DMG_GENERIC ); + } + else if ( iNewHealth < GetHealth() ) + { + TakeDamage( CTakeDamageInfo( this, this, iDelta, DMG_GENERIC ) ); + } +} +#else //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -11568,6 +13243,7 @@ void CAI_BaseNPC::InputSetHealth( inputdata_t &inputdata ) TakeDamage( CTakeDamageInfo( this, this, iDelta, DMG_GENERIC ) ); } } +#endif //----------------------------------------------------------------------------- // Purpose: @@ -11610,7 +13286,11 @@ void CAI_BaseNPC::InputSetSquad( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CAI_BaseNPC::InputWake( inputdata_t &inputdata ) { +#ifdef MAPBASE + Wake( inputdata.pActivator ); +#else Wake(); +#endif // Check if we have a path to follow. This is normally done in StartNPC, // but putting the NPC to sleep will cancel it, so we have to do it again. @@ -11637,10 +13317,16 @@ void CAI_BaseNPC::InputForgetEntity( inputdata_t &inputdata ) { const char *pszEntityToForget = inputdata.value.String(); +#ifndef MAPBASE // I would assume this was here for a reason, but wildcards have nothing to do with ClearMemory(), so I really have no idea. if ( g_pDeveloper->GetInt() && pszEntityToForget[strlen( pszEntityToForget ) - 1] == '*' ) DevMsg( "InputForgetEntity does not support wildcards\n" ); +#endif +#ifdef MAPBASE + CBaseEntity *pEntity = gEntList.FindEntityGeneric( NULL, pszEntityToForget, this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, pszEntityToForget ); +#endif if ( pEntity ) { if ( GetEnemy() == pEntity ) @@ -11672,7 +13358,11 @@ void CAI_BaseNPC::InputIgnoreDangerSounds( inputdata_t &inputdata ) void CAI_BaseNPC::InputUpdateEnemyMemory( inputdata_t &inputdata ) { const char *pszEnemy = inputdata.value.String(); +#ifdef MAPBASE + CBaseEntity *pEnemy = gEntList.FindEntityByName( NULL, pszEnemy, this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pEnemy = gEntList.FindEntityByName( NULL, pszEnemy ); +#endif if( pEnemy ) { @@ -11812,7 +13502,11 @@ bool CAI_BaseNPC::CineCleanup() if ( m_hForcedInteractionPartner ) { // We've finished a forced interaction. Let the mapmaker know. +#ifdef MAPBASE + m_OnForcedInteractionFinished.FireOutput( m_hInteractionPartner, this ); +#else m_OnForcedInteractionFinished.FireOutput( this, this ); +#endif } // Clear interaction partner, because we're not running a scripted sequence anymore @@ -11987,6 +13681,10 @@ void CAI_BaseNPC::Teleport( const Vector *newPosition, const QAngle *newAngles, CleanupScriptsOnTeleport( false ); BaseClass::Teleport( newPosition, newAngles, newVelocity ); + +#ifdef MAPBASE // From Alien Swarm SDK + CheckPVSCondition(); +#endif } //----------------------------------------------------------------------------- @@ -12110,6 +13808,20 @@ bool CAI_BaseNPC::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInt bool CAI_BaseNPC::OverrideMove( float flInterval ) { +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_OverrideMove.CanRunInScope(m_ScriptScope)) + { + // interval + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { flInterval }; + if (g_Hook_OverrideMove.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_BOOLEAN) + return functionReturn.m_bool; + } + } +#endif + return false; } @@ -12141,7 +13853,19 @@ bool CAI_BaseNPC::OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, { if ( pMoveGoal->directTrace.pObstruction ) { +#ifdef MAPBASE + CBaseEntity *pObstruction = pMoveGoal->directTrace.pObstruction; + CBasePropDoor *pPropDoor = dynamic_cast( pObstruction ); + + // It could be another entity (e.g. a func_brush) parented to a blank door + if (!pPropDoor && pObstruction->GetParent()) + { + pObstruction = pObstruction->GetParent(); + pPropDoor = dynamic_cast( pObstruction ); + } +#else CBasePropDoor *pPropDoor = dynamic_cast( pMoveGoal->directTrace.pObstruction ); +#endif if ( pPropDoor && OnUpcomingPropDoor( pMoveGoal, pPropDoor, distClear, pResult ) ) { return true; @@ -12233,7 +13957,11 @@ bool CAI_BaseNPC::OnUpcomingPropDoor( AILocalMoveGoal_t *pMoveGoal, m_hOpeningDoor = NULL; } +#ifdef MAPBASE + if ((CapabilitiesGet() & bits_CAP_DOORS_GROUP) && !pDoor->IsDoorLocked() && (pDoor->IsDoorClosed() || pDoor->IsDoorClosing()) && pDoor->PassesDoorFilter(this)) +#else if ((CapabilitiesGet() & bits_CAP_DOORS_GROUP) && !pDoor->IsDoorLocked() && (pDoor->IsDoorClosed() || pDoor->IsDoorClosing())) +#endif { AI_Waypoint_t *pOpenDoorRoute = NULL; @@ -12265,6 +13993,10 @@ bool CAI_BaseNPC::OnUpcomingPropDoor( AILocalMoveGoal_t *pMoveGoal, GetNavigator()->GetPath()->PrependWaypoints( pOpenDoorRoute ); +#ifdef MAPBASE + GetNavigator()->SetArrivalDirection( opendata.vecFaceDir ); +#endif + m_hOpeningDoor = pDoor; pMoveGoal->maxDist = distClear; *pResult = AIMR_CHANGE_TYPE; @@ -12285,6 +14017,21 @@ bool CAI_BaseNPC::OnUpcomingPropDoor( AILocalMoveGoal_t *pMoveGoal, //----------------------------------------------------------------------------- void CAI_BaseNPC::OpenPropDoorBegin( CBasePropDoor *pDoor ) { +#ifdef MAPBASE + opendata_t opendata; + pDoor->GetNPCOpenData(this, opendata); + + if (HaveSequenceForActivity( opendata.eActivity )) + { + int iLayer = AddGesture( opendata.eActivity ); + float flDuration = GetLayerDuration( iLayer ); + + // Face the door and wait for the activity to finish before trying to move through the doorway. + m_flMoveWaitFinished = gpGlobals->curtime + flDuration + pDoor->GetOpenInterval(); + AddFacingTarget( opendata.vecFaceDir, 1.0, flDuration ); + } + else +#else // dvs: not quite working, disabled for now. //opendata_t opendata; //pDoor->GetNPCOpenData(this, opendata); @@ -12294,6 +14041,7 @@ void CAI_BaseNPC::OpenPropDoorBegin( CBasePropDoor *pDoor ) // SetIdealActivity(opendata.eActivity); //} //else +#endif { // We don't have an appropriate sequence, just open the door magically. OpenPropDoorNow( pDoor ); @@ -12313,6 +14061,15 @@ void CAI_BaseNPC::OpenPropDoorNow( CBasePropDoor *pDoor ) // Wait for the door to finish opening before trying to move through the doorway. m_flMoveWaitFinished = gpGlobals->curtime + pDoor->GetOpenInterval(); + +#ifdef MAPBASE + // Remove the door from our waypoint + if (GetNavigator()->GetPath() && GetNavigator()->GetCurWaypointFlags() & bits_WP_TO_DOOR) + { + GetNavigator()->GetPath()->GetCurWaypoint()->ModifyFlags( bits_WP_TO_DOOR, false ); + GetNavigator()->GetPath()->GetCurWaypoint()->m_hData = NULL; + } +#endif } @@ -12483,7 +14240,7 @@ static void AIMsgGuts( CAI_BaseNPC *pAI, unsigned flags, const char *pszMsg ) else pszFmt2 = "%s (%s: %d/%s) [%d]"; - DevMsg( pszFmt2, + CGMsg( 1, CON_GROUP_NPC_AI, pszFmt2, pszMsg, pAI->GetClassname(), pAI->entindex(), @@ -12680,7 +14437,11 @@ void CAI_BaseNPC::TestPlayerPushing( CBaseEntity *pEntity ) // Heuristic for determining if the player is pushing me away CBasePlayer *pPlayer = ToBasePlayer( pEntity ); +#ifdef MAPBASE + if ( pPlayer && !( pPlayer->GetFlags() & FL_NOTARGET ) && IRelationType( pPlayer ) > D_FR ) +#else if ( pPlayer && !( pPlayer->GetFlags() & FL_NOTARGET ) ) +#endif { if ( (pPlayer->m_nButtons & (IN_FORWARD|IN_BACK|IN_MOVELEFT|IN_MOVERIGHT)) || pPlayer->GetAbsVelocity().AsVector2D().LengthSqr() > 50*50 ) @@ -12922,6 +14683,34 @@ void CAI_BaseNPC::InputSetSpeedModifierSpeed( inputdata_t &inputdata ) m_iSpeedModSpeed = inputdata.value.Int(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Get movement speed, multipled by modifier +//----------------------------------------------------------------------------- +float CAI_BaseNPC::GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence ) +{ + float t = SequenceDuration( pStudioHdr, iSequence ); + + if (t > 0) + { + return (GetSequenceMoveDist( pStudioHdr, iSequence ) * m_flSpeedModifier / t); + } + else + { + return 0; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Hammer input to change the speed of the NPC (based on 1upD's npc_shadow_walker code) +// Not to be confused with the inputs above +//----------------------------------------------------------------------------- +void CAI_BaseNPC::InputSetSpeedModifier( inputdata_t &inputdata ) +{ + this->m_flSpeedModifier = inputdata.value.Float(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -12937,161 +14726,356 @@ bool CAI_BaseNPC::IsAllowedToDodge( void ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CAI_BaseNPC::ParseScriptedNPCInteractions( void ) +void CAI_BaseNPC::ParseScriptedNPCInteractions(void) { // Already parsed them? - if ( m_ScriptedInteractions.Count() ) + if (m_ScriptedInteractions.Count()) return; // Parse the model's key values and find any dynamic interactions - KeyValues *modelKeyValues = new KeyValues(""); - CUtlBuffer buf( 1024, 0, CUtlBuffer::TEXT_BUFFER ); + KeyValues* modelKeyValues = new KeyValues(""); + CUtlBuffer buf(1024, 0, CUtlBuffer::TEXT_BUFFER); - if (! modelinfo->GetModelKeyValue( GetModel(), buf )) + if (!modelinfo->GetModelKeyValue(GetModel(), buf)) return; - - if ( modelKeyValues->LoadFromBuffer( modelinfo->GetModelName( GetModel() ), buf ) ) + + if (modelKeyValues->LoadFromBuffer(modelinfo->GetModelName(GetModel()), buf)) { - // Do we have a dynamic interactions section? - KeyValues *pkvInteractions = modelKeyValues->FindKey("dynamic_interactions"); - if ( pkvInteractions ) +#ifdef MAPBASE + CUtlVector iszUsedNames; + for (KeyValues* pkvModelBlock = modelKeyValues; pkvModelBlock != nullptr; pkvModelBlock = pkvModelBlock->GetNextKey()) + { + // Do we have a dynamic interactions section? + KeyValues* pkvInteractions = pkvModelBlock->FindKey("dynamic_interactions"); + if (pkvInteractions) + { + KeyValues* pkvNode = pkvInteractions->GetFirstSubKey(); + while (pkvNode) + { + ScriptedNPCInteraction_t sInteraction; + sInteraction.iszInteractionName = AllocPooledString(pkvNode->GetName()); + + if (iszUsedNames.Find(sInteraction.iszInteractionName) != iszUsedNames.InvalidIndex()) + { + DevMsg(2, "Scripted interaction %s already defined on %s\n", pkvNode->GetName(), GetClassname()); + pkvNode = pkvNode->GetNextKey(); + continue; + } + + // The method for parsing dynamic interactions has been reworked. + // Unknown values are now stored as response contexts to test against response criteria. + + bool bValidInteraction = true; + + // Default values + UTIL_StringToVector(sInteraction.vecRelativeOrigin.Base(), "0 0 0"); + sInteraction.flDelay = 10.0; + sInteraction.flDistSqr = (DSS_MAX_DIST * DSS_MAX_DIST); + + // Misc. response criteria + char* szCriteria = ""; + + KeyValues* pCurNode = pkvNode->GetFirstSubKey(); + const char* szName = NULL; + const char* szValue = NULL; + while (pCurNode) + { + szName = pCurNode->GetName(); + szValue = pCurNode->GetString(); + + if (!szName || !szValue) + { + DevWarning("ERROR: Invalid dynamic interaction string\n"); + pCurNode = pCurNode->GetNextKey(); + } + + if (!Q_strncmp(szName, "classname", 9)) + { + bool pass = false; + if (Q_strstr(szValue, "!=")) + { + szValue += 2; + pass = true; + } + + if (!FStrEq(GetClassname(), szValue)) + pass = !pass; + } + else if (!Q_strncmp(szName, "mapbase", 7)) + { + sInteraction.iFlags |= SCNPC_FLAG_MAPBASE_ADDITION; + } + else if (!Q_strncmp(szName, "trigger", 7)) + { + if (!Q_strncmp(szValue, "auto_in_combat", 14)) + sInteraction.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT; + } + else if (!Q_strncmp(szValue, "loop_break_trigger", 18)) + { + char szTrigger[256]; + Q_strncpy(szTrigger, szValue, sizeof(szTrigger)); + char* pszParam = strtok(szTrigger, " "); + while (pszParam) + { + if (!Q_strncmp(pszParam, "on_damage", 9)) + { + sInteraction.iLoopBreakTriggerMethod |= SNPCINT_LOOPBREAK_ON_DAMAGE; + } + else if (!Q_strncmp(pszParam, "on_flashlight_illum", 19)) + { + sInteraction.iLoopBreakTriggerMethod |= SNPCINT_LOOPBREAK_ON_FLASHLIGHT_ILLUM; + } + + pszParam = strtok(NULL, " "); + } + } + else if (!Q_strncmp(szName, "origin_relative", 15)) + UTIL_StringToVector(sInteraction.vecRelativeOrigin.Base(), szValue); + else if (!Q_strncmp(szName, "angles_relative", 15)) + { + sInteraction.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES; + UTIL_StringToVector(sInteraction.angRelativeAngles.Base(), szValue); + } + else if (!Q_strncmp(szName, "velocity_relative", 17)) + { + sInteraction.iFlags |= SCNPC_FLAG_TEST_OTHER_VELOCITY; + UTIL_StringToVector(sInteraction.vecRelativeVelocity.Base(), szValue); + } + else if (!Q_strncmp(szName, "end_position", 12)) + { + sInteraction.iFlags |= SCNPC_FLAG_TEST_END_POSITION; + UTIL_StringToVector(sInteraction.vecRelativeEndPos.Base(), szValue); + } + + else if (!Q_strncmp(szName, "entry_sequence", 14)) + sInteraction.sPhases[SNPCINT_ENTRY].iszSequence = AllocPooledString(szValue); + else if (!Q_strncmp(szName, "entry_activity", 14)) + sInteraction.sPhases[SNPCINT_ENTRY].iActivity = GetActivityID(szValue); + + else if (!Q_strncmp(szName, "sequence", 8)) + sInteraction.sPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString(szValue); + else if (!Q_strncmp(szName, "activity", 8)) + sInteraction.sPhases[SNPCINT_SEQUENCE].iActivity = GetActivityID(szValue); + + else if (!Q_strncmp(szName, "exit_sequence", 13)) + sInteraction.sPhases[SNPCINT_EXIT].iszSequence = AllocPooledString(szValue); + else if (!Q_strncmp(szName, "exit_activity", 13)) + sInteraction.sPhases[SNPCINT_EXIT].iActivity = GetActivityID(szValue); + + else if (!Q_strncmp(szName, "delay", 5)) + sInteraction.flDelay = atof(szValue); + else if (!Q_strncmp(szName, "origin_max_delta", 16)) + sInteraction.flDistSqr = atof(szValue); + + else if (!Q_strncmp(szName, "loop_in_action", 14) && !FStrEq(szValue, "0")) + sInteraction.iFlags |= SCNPC_FLAG_LOOP_IN_ACTION; + + else if (!Q_strncmp(szName, "dont_teleport_at_end", 20)) + { + if (!Q_stricmp(szValue, "me") || !Q_stricmp(szValue, "both")) + sInteraction.iFlags |= SCNPC_FLAG_DONT_TELEPORT_AT_END_ME; + else if (!Q_stricmp(szValue, "them") || !Q_stricmp(szValue, "both")) + sInteraction.iFlags |= SCNPC_FLAG_DONT_TELEPORT_AT_END_THEM; + } + + else if (!Q_strncmp(szName, "needs_weapon", 12)) + { + if (!Q_strncmp(szValue, "ME", 2)) + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; + else if (!Q_strncmp(szValue, "THEM", 4)) + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; + else if (!Q_strncmp(szValue, "BOTH", 4)) + { + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; + } + } + + else if (!Q_strncmp(szName, "weapon_mine", 11)) + { + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; + sInteraction.iszMyWeapon = AllocPooledString(szValue); + } + else if (!Q_strncmp(szName, "weapon_theirs", 13)) + { + sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; + sInteraction.iszTheirWeapon = AllocPooledString(szValue); + } + + // Add anything else to our miscellaneous criteria + else + { + szCriteria = UTIL_VarArgs("%s,%s:%s", szCriteria, szName, szValue); + } + + pCurNode = pCurNode->GetNextKey(); + } + + if (!bValidInteraction) + { + DevMsg("Scripted interaction %s rejected by %s\n", pkvNode->GetName(), GetClassname()); + pkvNode = pkvNode->GetNextKey(); + continue; + } + + if (szCriteria[0] == ',') + { + szCriteria += 1; + sInteraction.MiscCriteria = AllocPooledString(szCriteria); + } + + + // Add it to the list + AddScriptedNPCInteraction(&sInteraction); + iszUsedNames.AddToTail(sInteraction.iszInteractionName); + + // Move to next interaction + pkvNode = pkvNode->GetNextKey(); + } + } + } +#else +// Do we have a dynamic interactions section? + KeyValues* pkvInteractions = modelKeyValues->FindKey("dynamic_interactions"); + if (pkvInteractions) { - KeyValues *pkvNode = pkvInteractions->GetFirstSubKey(); - while ( pkvNode ) + KeyValues* pkvNode = pkvInteractions->GetFirstSubKey(); + while (pkvNode) { ScriptedNPCInteraction_t sInteraction; - sInteraction.iszInteractionName = AllocPooledString( pkvNode->GetName() ); + sInteraction.iszInteractionName = AllocPooledString(pkvNode->GetName()); + // Trigger method - const char *pszTrigger = pkvNode->GetString( "trigger", NULL ); - if ( pszTrigger ) + const char* pszTrigger = pkvNode->GetString("trigger", NULL); + if (pszTrigger) { - if ( !Q_strncmp( pszTrigger, "auto_in_combat", 14) ) + if (!Q_strncmp(pszTrigger, "auto_in_combat", 14)) { sInteraction.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT; } } // Loop Break trigger method - pszTrigger = pkvNode->GetString( "loop_break_trigger", NULL ); - if ( pszTrigger ) + pszTrigger = pkvNode->GetString("loop_break_trigger", NULL); + if (pszTrigger) { char szTrigger[256]; - Q_strncpy( szTrigger, pszTrigger, sizeof(szTrigger) ); - char *pszParam = strtok( szTrigger, " " ); + Q_strncpy(szTrigger, pszTrigger, sizeof(szTrigger)); + char* pszParam = strtok(szTrigger, " "); while (pszParam) { - if ( !Q_strncmp( pszParam, "on_damage", 9) ) + if (!Q_strncmp(pszParam, "on_damage", 9)) { sInteraction.iLoopBreakTriggerMethod |= SNPCINT_LOOPBREAK_ON_DAMAGE; } - if ( !Q_strncmp( pszParam, "on_flashlight_illum", 19) ) + if (!Q_strncmp(pszParam, "on_flashlight_illum", 19)) { sInteraction.iLoopBreakTriggerMethod |= SNPCINT_LOOPBREAK_ON_FLASHLIGHT_ILLUM; } - pszParam = strtok(NULL," "); + pszParam = strtok(NULL, " "); } } // Origin - const char *pszOrigin = pkvNode->GetString( "origin_relative", "0 0 0" ); - UTIL_StringToVector( sInteraction.vecRelativeOrigin.Base(), pszOrigin ); + const char* pszOrigin = pkvNode->GetString("origin_relative", "0 0 0"); + UTIL_StringToVector(sInteraction.vecRelativeOrigin.Base(), pszOrigin); // Angles - const char *pszAngles = pkvNode->GetString( "angles_relative", NULL ); - if ( pszAngles ) + const char* pszAngles = pkvNode->GetString("angles_relative", NULL); + if (pszAngles) { sInteraction.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES; - UTIL_StringToVector( sInteraction.angRelativeAngles.Base(), pszAngles ); + UTIL_StringToVector(sInteraction.angRelativeAngles.Base(), pszAngles); } // Velocity - const char *pszVelocity = pkvNode->GetString( "velocity_relative", NULL ); - if ( pszVelocity ) + const char* pszVelocity = pkvNode->GetString("velocity_relative", NULL); + if (pszVelocity) { sInteraction.iFlags |= SCNPC_FLAG_TEST_OTHER_VELOCITY; - UTIL_StringToVector( sInteraction.vecRelativeVelocity.Base(), pszVelocity ); + UTIL_StringToVector(sInteraction.vecRelativeVelocity.Base(), pszVelocity); } // Entry Sequence - const char *pszSequence = pkvNode->GetString( "entry_sequence", NULL ); - if ( pszSequence ) + const char* pszSequence = pkvNode->GetString("entry_sequence", NULL); + if (pszSequence) { - sInteraction.sPhases[SNPCINT_ENTRY].iszSequence = AllocPooledString( pszSequence ); + sInteraction.sPhases[SNPCINT_ENTRY].iszSequence = AllocPooledString(pszSequence); } // Entry Activity - const char *pszActivity = pkvNode->GetString( "entry_activity", NULL ); - if ( pszActivity ) + const char* pszActivity = pkvNode->GetString("entry_activity", NULL); + if (pszActivity) { - sInteraction.sPhases[SNPCINT_ENTRY].iActivity = GetActivityID( pszActivity ); + sInteraction.sPhases[SNPCINT_ENTRY].iActivity = GetActivityID(pszActivity); } // Sequence - pszSequence = pkvNode->GetString( "sequence", NULL ); - if ( pszSequence ) + pszSequence = pkvNode->GetString("sequence", NULL); + if (pszSequence) { - sInteraction.sPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString( pszSequence ); + sInteraction.sPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString(pszSequence); } // Activity - pszActivity = pkvNode->GetString( "activity", NULL ); - if ( pszActivity ) + pszActivity = pkvNode->GetString("activity", NULL); + if (pszActivity) { - sInteraction.sPhases[SNPCINT_SEQUENCE].iActivity = GetActivityID( pszActivity ); + sInteraction.sPhases[SNPCINT_SEQUENCE].iActivity = GetActivityID(pszActivity); } // Exit Sequence - pszSequence = pkvNode->GetString( "exit_sequence", NULL ); - if ( pszSequence ) + pszSequence = pkvNode->GetString("exit_sequence", NULL); + if (pszSequence) { - sInteraction.sPhases[SNPCINT_EXIT].iszSequence = AllocPooledString( pszSequence ); + sInteraction.sPhases[SNPCINT_EXIT].iszSequence = AllocPooledString(pszSequence); } // Exit Activity - pszActivity = pkvNode->GetString( "exit_activity", NULL ); - if ( pszActivity ) + pszActivity = pkvNode->GetString("exit_activity", NULL); + if (pszActivity) { - sInteraction.sPhases[SNPCINT_EXIT].iActivity = GetActivityID( pszActivity ); + sInteraction.sPhases[SNPCINT_EXIT].iActivity = GetActivityID(pszActivity); } // Delay - sInteraction.flDelay = pkvNode->GetFloat( "delay", 10.0 ); + sInteraction.flDelay = pkvNode->GetFloat("delay", 10.0); // Delta - sInteraction.flDistSqr = pkvNode->GetFloat( "origin_max_delta", (DSS_MAX_DIST * DSS_MAX_DIST) ); + sInteraction.flDistSqr = pkvNode->GetFloat("origin_max_delta", (DSS_MAX_DIST * DSS_MAX_DIST)); // Loop? - if ( pkvNode->GetFloat( "loop_in_action", 0 ) ) + if (pkvNode->GetFloat("loop_in_action", 0)) { sInteraction.iFlags |= SCNPC_FLAG_LOOP_IN_ACTION; } // Fixup position? - const char *pszDontFixup = pkvNode->GetString( "dont_teleport_at_end", NULL ); - if ( pszDontFixup ) + const char* pszDontFixup = pkvNode->GetString("dont_teleport_at_end", NULL); + if (pszDontFixup) { - if ( !Q_stricmp( pszDontFixup, "me" ) || !Q_stricmp( pszDontFixup, "both" ) ) + if (!Q_stricmp(pszDontFixup, "me") || !Q_stricmp(pszDontFixup, "both")) { sInteraction.iFlags |= SCNPC_FLAG_DONT_TELEPORT_AT_END_ME; } - else if ( !Q_stricmp( pszDontFixup, "them" ) || !Q_stricmp( pszDontFixup, "both" ) ) + else if (!Q_stricmp(pszDontFixup, "them") || !Q_stricmp(pszDontFixup, "both")) { sInteraction.iFlags |= SCNPC_FLAG_DONT_TELEPORT_AT_END_THEM; } } // Needs a weapon? - const char *pszNeedsWeapon = pkvNode->GetString( "needs_weapon", NULL ); - if ( pszNeedsWeapon ) + const char* pszNeedsWeapon = pkvNode->GetString("needs_weapon", NULL); + if (pszNeedsWeapon) { - if ( !Q_strncmp( pszNeedsWeapon, "ME", 2 ) ) + if (!Q_strncmp(pszNeedsWeapon, "ME", 2)) { sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; } - else if ( !Q_strncmp( pszNeedsWeapon, "THEM", 4 ) ) + else if (!Q_strncmp(pszNeedsWeapon, "THEM", 4)) { sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; } - else if ( !Q_strncmp( pszNeedsWeapon, "BOTH", 4 ) ) + else if (!Q_strncmp(pszNeedsWeapon, "BOTH", 4)) { sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; @@ -13099,26 +15083,28 @@ void CAI_BaseNPC::ParseScriptedNPCInteractions( void ) } // Specific weapon types - const char *pszWeaponName = pkvNode->GetString( "weapon_mine", NULL ); - if ( pszWeaponName ) + const char* pszWeaponName = pkvNode->GetString("weapon_mine", NULL); + if (pszWeaponName) { sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_ME; - sInteraction.iszMyWeapon = AllocPooledString( pszWeaponName ); + sInteraction.iszMyWeapon = AllocPooledString(pszWeaponName); } - pszWeaponName = pkvNode->GetString( "weapon_theirs", NULL ); - if ( pszWeaponName ) + pszWeaponName = pkvNode->GetString("weapon_theirs", NULL); + if (pszWeaponName) { sInteraction.iFlags |= SCNPC_FLAG_NEEDS_WEAPON_THEM; - sInteraction.iszTheirWeapon = AllocPooledString( pszWeaponName ); + sInteraction.iszTheirWeapon = AllocPooledString(pszWeaponName); } // Add it to the list - AddScriptedNPCInteraction( &sInteraction ); + AddScriptedNPCInteraction(&sInteraction); // Move to next interaction pkvNode = pkvNode->GetNextKey(); } } +#endif // MAPBASE + } modelKeyValues->deleteThis(); @@ -13348,6 +15334,11 @@ void CAI_BaseNPC::StartScriptedNPCInteraction( CAI_BaseNPC *pOtherNPC, ScriptedN //----------------------------------------------------------------------------- bool CAI_BaseNPC::CanRunAScriptedNPCInteraction( bool bForced ) { +#ifdef MAPBASE + if ( m_iDynamicInteractionsAllowed == TRS_FALSE && !bForced ) + return false; +#endif + if ( m_NPCState != NPC_STATE_IDLE && m_NPCState != NPC_STATE_ALERT && m_NPCState != NPC_STATE_COMBAT ) return false; @@ -13431,6 +15422,11 @@ void CAI_BaseNPC::CheckForScriptedNPCInteractions( void ) if ( pInteraction->flNextAttemptTime > gpGlobals->curtime ) continue; +#ifdef MAPBASE + if ( !InteractionIsAllowed(pNPC, pInteraction) ) + continue; +#endif + Vector vecOrigin; QAngle angAngles; if ( InteractionCouldStart( pNPC, pInteraction, vecOrigin, angAngles ) ) @@ -13473,7 +15469,12 @@ void CAI_BaseNPC::CalculateValidEnemyInteractions( void ) // If we have a damage filter that prevents us hurting the enemy, // don't interact with him, since most interactions kill the enemy. // Create a fake damage info to test it with. +#ifdef MAPBASE + // DMG_PREVENT_PHYSICS_FORCE can be used to identify dynamic interaction tests + CTakeDamageInfo tempinfo( this, this, vec3_origin, vec3_origin, 1.0, DMG_BULLET | DMG_PREVENT_PHYSICS_FORCE ); +#else CTakeDamageInfo tempinfo( this, this, vec3_origin, vec3_origin, 1.0, DMG_BULLET ); +#endif if ( !pNPC->PassesDamageFilter( tempinfo ) ) continue; @@ -13484,23 +15485,82 @@ void CAI_BaseNPC::CalculateValidEnemyInteractions( void ) continue; // Check the specific weapon type +#ifdef MAPBASE + if ( pInteraction->iszMyWeapon != NULL_STRING ) + { + const char *myweapon = STRING(pInteraction->iszMyWeapon); + bool pass = false; + if (Q_strstr(myweapon, "!=")) + { + myweapon += 2; + pass = true; + } + + if (Q_strstr(myweapon, "WEPCLASS")) + pass = (GetActiveWeapon()->WeaponClassFromString(myweapon) == GetActiveWeapon()->WeaponClassify()) ? !pass : pass; + else + pass = (GetActiveWeapon()->m_iClassname == pInteraction->iszMyWeapon) ? !pass : pass; + + if (!pass) + continue; + } +#else if ( pInteraction->iszMyWeapon != NULL_STRING && GetActiveWeapon()->m_iClassname != pInteraction->iszMyWeapon ) continue; +#endif } if ( pInteraction->iFlags & SCNPC_FLAG_NEEDS_WEAPON_THEM ) { if ( !pNPC->GetActiveWeapon() ) continue; +#ifdef MAPBASE + if ( pInteraction->iszTheirWeapon != NULL_STRING ) + { + const char *theirweapon = STRING(pInteraction->iszTheirWeapon); + bool pass = false; + if (Q_strstr(theirweapon, "!=")) + { + theirweapon += 2; + pass = true; + } + + if (Q_strstr(theirweapon, "WEPCLASS")) + pass = (pNPC->GetActiveWeapon()->WeaponClassFromString(theirweapon) == pNPC->GetActiveWeapon()->WeaponClassify()) ? !pass : pass; + else + pass = (pNPC->GetActiveWeapon()->m_iClassname == pInteraction->iszTheirWeapon) ? !pass : pass; + + if (!pass) + continue; + } +#else // Check the specific weapon type if ( pInteraction->iszTheirWeapon != NULL_STRING && pNPC->GetActiveWeapon()->m_iClassname != pInteraction->iszTheirWeapon ) continue; +#endif } // Script needs the other NPC, so make sure they're not dead if ( !pNPC->IsAlive() ) continue; +#ifdef MAPBASE + // If they have an interaction with the same name, it means we're not supposed to engage with them + bool bSame = false; + for ( int i2 = 0; i2 < pNPC->m_ScriptedInteractions.Count(); i2++ ) + { + // These strings are pooled, so this works + if (m_ScriptedInteractions[i].iszInteractionName == pNPC->m_ScriptedInteractions[i2].iszInteractionName) + { + bSame = true; + break; + } + } + + if (bSame) + continue; +#endif + // Use sequence? or activity? if ( pInteraction->sPhases[SNPCINT_SEQUENCE].iActivity != ACT_INVALID ) { @@ -13517,6 +15577,54 @@ void CAI_BaseNPC::CalculateValidEnemyInteractions( void ) continue; } +#ifdef MAPBASE + if (pInteraction->MiscCriteria != NULL_STRING) + { + // Test against response system criteria + AI_CriteriaSet set; + ModifyOrAppendCriteria( set ); + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + ReAppendContextCriteria( set ); + + DevMsg("Testing %s misc criteria\n", STRING(pInteraction->MiscCriteria)); + + int index; + const char *criteriavalue; + char key[128]; + char value[128]; + const char *p = STRING(pInteraction->MiscCriteria); + while ( p ) + { +#ifdef NEW_RESPONSE_SYSTEM + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), NULL, STRING(pInteraction->MiscCriteria) ); +#else + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), NULL ); +#endif + + index = set.FindCriterionIndex(key); + if (index != -1) + { + criteriavalue = set.GetValue(index); + if (!Matcher_Match(value, criteriavalue)) + { + continue; + } + } + else + { + // Test with empty string in case our criteria is != or something + criteriavalue = ""; + if (!Matcher_Match(value, criteriavalue)) + { + continue; + } + } + } + } +#endif + pInteraction->bValidOnCurrentEnemy = true; bFound = true; @@ -13584,7 +15692,11 @@ void CAI_BaseNPC::CheckForcedNPCInteractions( void ) if ( m_hForcedInteractionPartner ) { // We've aborted a forced interaction. Let the mapmaker know. +#ifdef MAPBASE + m_OnForcedInteractionAborted.FireOutput( pNPC, this ); +#else m_OnForcedInteractionAborted.FireOutput( this, this ); +#endif } CleanupForcedInteraction(); @@ -13594,7 +15706,11 @@ void CAI_BaseNPC::CheckForcedNPCInteractions( void ) } StartScriptedNPCInteraction( pNPC, pInteraction, vecOrigin, angAngles ); +#ifdef MAPBASE + m_OnForcedInteractionStarted.FireOutput( pNPC, this ); +#else m_OnForcedInteractionStarted.FireOutput( this, this ); +#endif } @@ -13660,6 +15776,25 @@ bool CanNPCsTradePlaces( CAI_BaseNPC *pNPC1, CAI_BaseNPC *pNPC2, bool bDebug ) return true; } +#ifdef MAPBASE +bool CAI_BaseNPC::InteractionIsAllowed( CAI_BaseNPC *pOtherNPC, ScriptedNPCInteraction_t *pInteraction ) +{ + // Now that female citizens have hunter interactions, Alyx is vulnerable to being murdered by hunters *dynamically*! + // Citizens also have antlion interaction kill animations, so antlions could potentially murder her as well. + // + // Forced interactions should still work, but this prevents regular interactions from targeting vital allies. + // Hopefully there aren't any maps that already have hunters murder Barneys. + if (pOtherNPC->Classify() == CLASS_PLAYER_ALLY_VITAL) + return false; + + // This convar allows all NPCs to perform Mapbase interactions for both testing and player fun. + if (ai_dynint_always_enabled.GetBool() && m_iDynamicInteractionsAllowed != TRS_FALSE) + return true; + + // m_iDynamicInteractionsAllowed == TRS_FALSE case is already handled in CanRunAScriptedNPCInteraction(). + return !(pInteraction->iFlags & SCNPC_FLAG_MAPBASE_ADDITION && m_iDynamicInteractionsAllowed == TRS_NONE); +} +#endif //----------------------------------------------------------------------------- // Purpose: @@ -13801,6 +15936,34 @@ bool CAI_BaseNPC::InteractionCouldStart( CAI_BaseNPC *pOtherNPC, ScriptedNPCInte return false; } +#ifdef MAPBASE + // Make sure we could fit at the sequence end position too. + if (pInteraction->iFlags & SCNPC_FLAG_TEST_END_POSITION) + { + VMatrix matTestToWorld; + matTestToWorld.SetupMatrixOrgAngles(pInteraction->vecRelativeEndPos, angMyCurrent); + MatrixMultiply( matMeToWorld, matTestToWorld, matLocalToWorld ); + Vector vecPos = (matLocalToWorld.GetTranslation()); + + // Start from the NPC's position. + AI_TraceHull( pOtherNPC->GetAbsOrigin(), vecPos, GetHullMins(), GetHullMaxs(), MASK_SOLID, &traceFilter, &tr ); + if ( tr.fraction != 1.0 ) + { + if ( bDebug ) + { + NDebugOverlay::Box( vecPos, GetHullMins(), GetHullMaxs(), 255,0,0, 100, 1.0 ); + } + return false; + } + else if ( bDebug ) + { + //NDebugOverlay::Box( vecPos, GetHullMins(), GetHullMaxs(), 0,255,0, 100, 1.0 ); + + NDebugOverlay::Axis( vecPos, angAngles, 20, true, 10.0 ); + } + } +#endif + // If the NPCs are swapping places during this interaction, make sure they can fit at each // others' origins before allowing the interaction. if ( !CanNPCsTradePlaces( this, pOtherNPC, bDebug ) ) @@ -13997,6 +16160,9 @@ void CAI_BaseNPC::ModifyOrAppendCriteria( AI_CriteriaSet& set ) set.AppendCriteria( "timesinceseenplayer", "-1" ); } +#ifdef MAPBASE + ModifyOrAppendEnemyCriteria(set, GetEnemy()); +#else // Append distance to my enemy if ( GetEnemy() ) { @@ -14006,7 +16172,95 @@ void CAI_BaseNPC::ModifyOrAppendCriteria( AI_CriteriaSet& set ) { set.AppendCriteria( "distancetoenemy", "-1" ); } +#endif + +#ifdef MAPBASE + // Append our gender + // I know scenes can use $gender01, but some rules now use more than scenes. + const char *modelname = STRING(GetModelName()); + if (modelname) + { + set.AppendCriteria( "gender", UTIL_VarArgs("%i", soundemitterbase->GetActorGender(modelname)) ); + } + + if (IsInSquad()) + { + set.AppendCriteria( "insquad", "1" ); + set.AppendCriteria( "squadmates", UTIL_VarArgs( "%i", GetSquad()->NumMembers() ) ); + set.AppendCriteria( "isleader", GetSquad()->IsLeader(this) ? "0" : "1" ); + } + else + { + set.AppendCriteria( "insquad", "0" ); + } +#endif +} + +#ifdef MAPBASE +// Went for a different structure that directly takes AI_CriteriaSet for modifiers +/* +#define GetModifiersFromCriteria( function, output, maxlen ) AI_CriteriaSet set; \ + function; \ + for (int i = 0; i < set.GetCount(); i++) { Q_snprintf(output, maxlen, "%s,%s:%s", output, set.GetName(i), set.GetValue(i)); } \ + memmove(output, output + 1, strlen(output + 1) + 1); \ + */ + +//----------------------------------------------------------------------------- +// Purpose: Appends enemy criteria so some classes could re-define it for, say, killing something +//----------------------------------------------------------------------------- +void CAI_BaseNPC::ModifyOrAppendEnemyCriteria( AI_CriteriaSet& set, CBaseEntity *pEnemy ) +{ + if ( pEnemy ) + { + set.AppendCriteria( "enemy", pEnemy->GetClassname() ); + set.AppendCriteria( "enemyclass", g_pGameRules->AIClassText( pEnemy->Classify() ) ); // UTIL_VarArgs("%i", pEnemy->Classify()) + set.AppendCriteria( "distancetoenemy", UTIL_VarArgs( "%f", EnemyDistance(pEnemy) ) ); + set.AppendCriteria( "timesincecombat", "-1" ); + } + else + { + if ( GetLastEnemyTime() == 0.0 ) + set.AppendCriteria( "timesincecombat", "999999.0" ); + else + set.AppendCriteria( "timesincecombat", UTIL_VarArgs( "%f", gpGlobals->curtime - GetLastEnemyTime() ) ); + + set.AppendCriteria( "distancetoenemy", "-1" ); + } +} + +/* +//----------------------------------------------------------------------------- +// Purpose: Gets enemy criteria in context form +//----------------------------------------------------------------------------- +void CAI_BaseNPC::GetEnemyCriteriaModifiers( CBaseEntity *pEnemy, char *szCriteria, int iMaxLen ) +{ + GetModifiersFromCriteria(ModifyOrAppendEnemyCriteria(set, pEnemy), szCriteria, iMaxLen); +} +*/ + +//----------------------------------------------------------------------------- +// Purpose: Appends damage criteria for pain sounds, death sounds, etc. +//----------------------------------------------------------------------------- +void CAI_BaseNPC::ModifyOrAppendDamageCriteria( AI_CriteriaSet& set, const CTakeDamageInfo &info ) +{ + if ( info.GetAttacker() && info.GetAttacker() != this ) + set.AppendCriteria("attacker", info.GetAttacker()->GetClassname()); + else + set.AppendCriteria("attacker", ""); + + set.AppendCriteria("damagetype", UTIL_VarArgs("%i", info.GetDamageType())); +} + +/* +//----------------------------------------------------------------------------- +// Purpose: Gets damage criteria in context form +//----------------------------------------------------------------------------- +void CAI_BaseNPC::GetDamageCriteriaModifiers( const CTakeDamageInfo &info, char *szCriteria, int iMaxLen ) +{ + GetModifiersFromCriteria(ModifyOrAppendDamageCriteria(set, info), szCriteria, iMaxLen); } +*/ +#endif //----------------------------------------------------------------------------- // If I were crouching at my current location, could I shoot this target? @@ -14036,6 +16290,26 @@ bool CAI_BaseNPC::CouldShootIfCrouching( CBaseEntity *pTarget ) return bResult; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Check if this position will block our line of sight if aiming low. +//----------------------------------------------------------------------------- +bool CAI_BaseNPC::CouldShootIfCrouchingAt( const Vector &vecPosition, const Vector &vecForward, const Vector &vecRight, float flDist ) +{ + Vector vGunPos = vecPosition; + vGunPos += (GetCrouchGunOffset() + vecRight * 8); + + trace_t tr; + AI_TraceLOS( vGunPos, vGunPos + (vecForward * flDist), this, &tr ); + if (tr.fraction != 1.0) + { + return false; + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -14050,6 +16324,18 @@ bool CAI_BaseNPC::IsCrouchedActivity( Activity activity ) case ACT_COVER_PISTOL_LOW: case ACT_COVER_SMG1_LOW: case ACT_RELOAD_SMG1_LOW: +#ifdef MAPBASE +#if AR2_ACTIVITY_FIX == 1 + case ACT_COVER_AR2_LOW: + case ACT_RELOAD_AR2_LOW: +#endif + case ACT_RELOAD_PISTOL_LOW: + case ACT_RELOAD_SHOTGUN_LOW: +#if EXPANDED_HL2_WEAPON_ACTIVITIES + case ACT_RELOAD_REVOLVER_LOW: + case ACT_RELOAD_CROSSBOW_LOW: +#endif +#endif return true; } diff --git a/game/server/ai_basenpc.h b/game/server/ai_basenpc.h index 7c65c0cc..878a6f81 100644 --- a/game/server/ai_basenpc.h +++ b/game/server/ai_basenpc.h @@ -64,7 +64,9 @@ class CBaseGrenade; class CBaseDoor; class CBasePropDoor; struct AI_Waypoint_t; +#ifndef NEW_RESPONSE_SYSTEM class AI_Response; +#endif class CBaseFilter; typedef CBitVec CAI_ScheduleBits; @@ -95,6 +97,36 @@ extern bool AIStrongOpt( void ); // Max's of the box used to search for a weapon to pick up. 45x45x~8 ft. #define WEAPON_SEARCH_DELTA Vector( 540, 540, 100 ) +#ifdef MAPBASE +// Defines Mapbase's extended NPC response system usage. +#define EXPANDED_RESPONSE_SYSTEM_USAGE +#endif + +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + +// This macro implements the response system on any NPC, particularly non-actors that can't use CAI_ExpresserHost. +// NOTE: Because of the lack of CAI_ExpresserHost, some Response System settings like odds, delays, etc. cannot be used. +// It's recommended to just use CAI_ExpresserHost if possible. +#define DeclareResponseSystem IResponseSystem *GetResponseSystem() { extern IResponseSystem *g_pResponseSystem; return g_pResponseSystem; } + +// Default CAI_ExpresserHost implementation for NPCs using CAI_ExpresserHost. +#define DeclareDefaultExpresser() virtual CAI_Expresser *CreateExpresser( void ) { m_pExpresser = new CAI_Expresser(this); if (!m_pExpresser) return NULL; m_pExpresser->Connect(this); return m_pExpresser; } \\ + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } \\ + virtual void PostConstructor(const char *szClassname) { BaseClass::PostConstructor(szClassname); CreateExpresser(); } \\ + private: \\ + CAI_Expresser *m_pExpresser; \\ + public: + +// Variant of DeclareDefaultExpresser() that doesn't implement its own PostConstructor. +// CreateExpresser() should still be called from there. +#define DeclareDefaultExpresser_ExistingPC() virtual CAI_Expresser *CreateExpresser( void ) { m_pExpresser = new CAI_Expresser(this); if (!m_pExpresser) return NULL; m_pExpresser->Connect(this); return m_pExpresser; } \\ + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } \\ + private: \\ + CAI_Expresser *m_pExpresser; \\ + public: + +#endif + enum Interruptability_t { GENERAL_INTERRUPTABILITY, @@ -316,6 +348,10 @@ struct UnreachableEnt_t #define SCNPC_FLAG_NEEDS_WEAPON_THEM ( 1 << 5 ) #define SCNPC_FLAG_DONT_TELEPORT_AT_END_ME ( 1 << 6 ) #define SCNPC_FLAG_DONT_TELEPORT_AT_END_THEM ( 1 << 7 ) +#ifdef MAPBASE +#define SCNPC_FLAG_MAPBASE_ADDITION ( 1 << 8 ) +#define SCNPC_FLAG_TEST_END_POSITION ( 1 << 9 ) +#endif // ----------------------------------------- // Scripted NPC interaction trigger methods @@ -387,6 +423,10 @@ struct ScriptedNPCInteraction_t flNextAttemptTime = 0; iszMyWeapon = NULL_STRING; iszTheirWeapon = NULL_STRING; +#ifdef MAPBASE + vecRelativeEndPos = vec3_origin; + MiscCriteria = NULL_STRING; +#endif for ( int i = 0; i < SNPCINT_NUM_PHASES; i++) { @@ -403,6 +443,9 @@ struct ScriptedNPCInteraction_t Vector vecRelativeOrigin; // (forward, right, up) QAngle angRelativeAngles; Vector vecRelativeVelocity; // Desired relative velocity of the other NPC +#ifdef MAPBASE + Vector vecRelativeEndPos; // Relative position that the NPC must fit in +#endif float flDelay; // Delay before interaction can be used again float flDistSqr; // Max distance sqr from the relative origin the NPC is allowed to be to trigger string_t iszMyWeapon; // Classname of the weapon I'm holding, if any @@ -415,6 +458,13 @@ struct ScriptedNPCInteraction_t float flNextAttemptTime; +#ifdef MAPBASE + // Unrecognized keyvalues are tested against response criteria later. + // This was originally a CUtlVector that carries response contexts, but I couldn't get it working due to some CUtlVector-struct shenanigans. + // It works when we use a single string_t that's split and read each time the code runs, but feel free to improve on this. + string_t MiscCriteria; // CUtlVector +#endif + DECLARE_SIMPLE_DATADESC(); }; @@ -499,6 +549,9 @@ class CAI_BaseNPC : public CBaseCombatCharacter, DECLARE_DATADESC(); DECLARE_SERVERCLASS(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif virtual int Save( ISave &save ); virtual int Restore( IRestore &restore ); @@ -510,6 +563,9 @@ class CAI_BaseNPC : public CBaseCombatCharacter, virtual unsigned int PhysicsSolidMaskForEntity( void ) const; virtual bool KeyValue( const char *szKeyName, const char *szValue ); +#ifdef MAPBASE + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); +#endif //--------------------------------- @@ -565,6 +621,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, // Thinking, including core thinking, movement, animation virtual void NPCThink( void ); +#ifdef MAPBASE + void InputSetThinkNPC( inputdata_t &inputdata ); +#endif + // Core thinking (schedules & tasks) virtual void RunAI( void );// core ai function! @@ -607,6 +667,7 @@ class CAI_BaseNPC : public CBaseCombatCharacter, virtual bool ShouldAlwaysThink(); void ForceGatherConditions() { m_bForceConditionsGather = true; SetEfficiency( AIE_NORMAL ); } // Force an NPC out of PVS to call GatherConditions on next think + bool IsForceGatherConditionsSet() { return m_bForceConditionsGather; } virtual float LineOfSightDist( const Vector &vecDir = vec3_invalid, float zEye = FLT_MAX ); @@ -853,6 +914,11 @@ class CAI_BaseNPC : public CBaseCombatCharacter, bool DidChooseEnemy() const { return !m_bSkippedChooseEnemy; } +#ifdef MAPBASE + void InputSetCondition( inputdata_t &inputdata ); + void InputClearCondition( inputdata_t &inputdata ); +#endif + private: CAI_ScheduleBits m_Conditions; CAI_ScheduleBits m_CustomInterruptConditions; //Bit string assembled by the schedule running, then @@ -895,8 +961,12 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void RemoveSleepFlags( int flags ) { m_SleepFlags &= ~flags; } bool HasSleepFlags( int flags ) { return (m_SleepFlags & flags) == flags; } - void UpdateSleepState( bool bInPVS ); + virtual void UpdateSleepState( bool bInPVS ); virtual void Wake( bool bFireOutput = true ); +#ifdef MAPBASE + // A version of Wake() that takes an activator + virtual void Wake( CBaseEntity *pActivator ); +#endif void Sleep(); bool WokeThisTick() const; @@ -926,10 +996,19 @@ class CAI_BaseNPC : public CBaseCombatCharacter, Activity TranslateActivity( Activity idealActivity, Activity *pIdealWeaponActivity = NULL ); Activity NPC_TranslateActivity( Activity eNewActivity ); +#ifdef MAPBASE + Activity TranslateCrouchActivity( Activity baseAct ); + virtual bool CanTranslateCrouchActivity( void ) { return true; } + virtual Activity NPC_BackupActivity( Activity eNewActivity ); +#endif Activity GetActivity( void ) { return m_Activity; } virtual void SetActivity( Activity NewActivity ); Activity GetIdealActivity( void ) { return m_IdealActivity; } void SetIdealActivity( Activity NewActivity ); +#ifdef MAPBASE + Activity GetTranslatedActivity( void ) { return m_translatedActivity; } + Activity GetIdealTranslatedActivity( void ) { return m_IdealTranslatedActivity; } +#endif void ResetIdealActivity( Activity newIdealActivity ); void SetSequenceByName( const char *szSequence ); void SetSequenceById( int iSequence ); @@ -946,6 +1025,25 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void SetActivityAndSequence(Activity NewActivity, int iSequence, Activity translatedActivity, Activity weaponActivity); +#ifdef MAPBASE + //----------------------------------------------------- + + // Returns the gesture variant of an activity (i.e. "ACT_GESTURE_RANGE_ATTACK1") + static Activity GetGestureVersionOfActivity( Activity inActivity ); + + // Returns the sequence variant of a gesture activity + static Activity GetSequenceVersionOfGesture( Activity inActivity ); + + //----------------------------------------------------- + + virtual bool ShouldPlayFakeSequenceGesture( Activity nActivity, Activity nTranslatedActivity ); + virtual Activity SelectFakeSequenceGesture( Activity nActivity, Activity nTranslatedActivity ); + void PlayFakeSequenceGesture( Activity nActivity, Activity nSequence, Activity nTranslatedSequence ); + + int GetFakeSequenceGesture(); + void ResetFakeSequenceGesture(); +#endif + private: void AdvanceToIdealActivity(void); @@ -959,6 +1057,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, Activity m_IdealTranslatedActivity; // Desired actual translated animation state Activity m_IdealWeaponActivity; // Desired weapon animation state +#ifdef MAPBASE + int m_FakeSequenceGestureLayer; // The gesture layer impersonating a sequence (-1 if invalid) +#endif + CNetworkVar(int, m_iDeathPose ); CNetworkVar(int, m_iDeathFrame ); @@ -973,6 +1075,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, const CAI_Senses * GetSenses() const { return m_pSenses; } void SetDistLook( float flDistLook ); +#ifdef MAPBASE + void InputSetDistLook( inputdata_t &inputdata ); + void InputSetDistTooFar( inputdata_t &inputdata ); +#endif virtual bool QueryHearSound( CSound *pSound ); virtual bool QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC = false ); @@ -1042,6 +1148,9 @@ class CAI_BaseNPC : public CBaseCombatCharacter, CBaseEntity *GetEnemyOccluder(void); virtual void StartTargetHandling( CBaseEntity *pTargetEnt ); +#ifdef MAPBASE + void InputSetTarget( inputdata_t &inputdata ); +#endif //--------------------------------- @@ -1122,6 +1231,73 @@ class CAI_BaseNPC : public CBaseCombatCharacter, public: CAI_MoveMonitor m_CommandMoveMonitor; +#ifdef MAPBASE + ThreeState_t m_FriendlyFireOverride = TRS_NONE; + virtual bool FriendlyFireEnabled(); + void InputSetFriendlyFire( inputdata_t &inputdata ); + + // Grenade-related functions from Combine soldiers ported to ai_basenpc so they could be shared. + // + // This is necessary because other NPCs can use them now and many instances where they were used relied on dynamic_casts. + virtual Vector GetAltFireTarget() { return GetEnemy() ? GetEnemy()->BodyTarget(Weapon_ShootPosition()) : vec3_origin; } + virtual void DelayGrenadeCheck(float delay) { ; } + virtual void AddGrenades( int inc, CBaseEntity *pLastGrenade = NULL ) { ; } +#endif + +#ifdef MAPBASE_VSCRIPT +private: + + // VScript stuff uses "VScript" instead of just "Script" to avoid + // confusion with NPC_STATE_SCRIPT or StartScripting + HSCRIPT VScriptGetEnemy(); + void VScriptSetEnemy( HSCRIPT pEnemy ); + Vector VScriptGetEnemyLKP(); + + HSCRIPT VScriptFindEnemyMemory( HSCRIPT pEnemy ); + + int VScriptGetState(); + + void VScriptWake( HSCRIPT hActivator ) { Wake( ToEnt(hActivator) ); } + void VScriptSleep() { Sleep(); } + + int VScriptGetSleepState() { return (int)GetSleepState(); } + void VScriptSetSleepState( int sleepState ) { SetSleepState( (AI_SleepState_t)sleepState ); } + + const char* VScriptGetHintGroup() { return STRING( GetHintGroup() ); } + HSCRIPT VScriptGetHintNode(); + + const char* ScriptGetActivity() { return GetActivityName( GetActivity() ); } + int ScriptGetActivityID() { return GetActivity(); } + void ScriptSetActivity( const char *szActivity ) { SetActivity( (Activity)GetActivityID( szActivity ) ); } + void ScriptSetActivityID( int iActivity ) { SetActivity((Activity)iActivity); } + int ScriptTranslateActivity( const char *szActivity ) { return TranslateActivity( (Activity)GetActivityID( szActivity ) ); } + int ScriptTranslateActivityID( int iActivity ) { return TranslateActivity( (Activity)iActivity ); } + + const char* VScriptGetGestureVersionOfActivity( const char *pszActivity ) { return GetActivityName( GetGestureVersionOfActivity( (Activity)GetActivityID( pszActivity ) ) ); } + int VScriptGetGestureVersionOfActivityID( int iActivity ) { return GetGestureVersionOfActivity( (Activity)iActivity ); } + const char* VScriptGetSequenceVersionOfGesture( const char *pszActivity ) { return GetActivityName( GetSequenceVersionOfGesture( (Activity)GetActivityID( pszActivity ) ) ); } + int VScriptGetSequenceVersionOfGestureID( int iActivity ) { return GetSequenceVersionOfGesture( (Activity)iActivity ); } + + const char* VScriptGetSchedule(); + int VScriptGetScheduleID(); + void VScriptSetSchedule( const char *szSchedule ); + void VScriptSetScheduleID( int iSched ) { SetSchedule( iSched ); } + const char* VScriptGetTask(); + int VScriptGetTaskID(); + + bool VScriptHasCondition( const char *szCondition ) { return HasCondition( GetConditionID( szCondition ) ); } + bool VScriptHasConditionID( int iCondition ) { return HasCondition( iCondition ); } + void VScriptSetCondition( const char *szCondition ) { SetCondition( GetConditionID( szCondition ) ); } + void VScriptClearCondition( const char *szCondition ) { ClearCondition( GetConditionID( szCondition ) ); } + + HSCRIPT VScriptGetExpresser(); + + HSCRIPT VScriptGetCine(); + int GetScriptState() { return m_scriptState; } + + HSCRIPT VScriptGetSquad(); +#endif + //----------------------------------------------------- // Dynamic scripted NPC interactions //----------------------------------------------------- @@ -1137,6 +1313,11 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void CheckForScriptedNPCInteractions( void ); void CalculateValidEnemyInteractions( void ); void CheckForcedNPCInteractions( void ); +#ifdef MAPBASE + // This is checked during automatic dynamic interactions, but not during forced interactions. + // This is so we can control interaction permissions while still letting forced interactions play when needed. + virtual bool InteractionIsAllowed( CAI_BaseNPC *pOtherNPC, ScriptedNPCInteraction_t *pInteraction ); +#endif bool InteractionCouldStart( CAI_BaseNPC *pOtherNPC, ScriptedNPCInteraction_t *pInteraction, Vector &vecOrigin, QAngle &angAngles ); virtual bool CanRunAScriptedNPCInteraction( bool bForced = false ); bool IsRunningDynamicInteraction( void ) { return (m_iInteractionState != NPCINT_NOT_RUNNING && (m_hCine != NULL)); } @@ -1162,10 +1343,20 @@ class CAI_BaseNPC : public CBaseCombatCharacter, bool m_bCannotDieDuringInteraction; int m_iInteractionState; int m_iInteractionPlaying; +#ifdef MAPBASE +public: +#endif CUtlVector m_ScriptedInteractions; float m_flInteractionYaw; +#ifdef MAPBASE + // Allows mappers to control dynamic interactions. + // DI added by Mapbase requires this to be on TRS_TRUE (1). Others, like Alyx's interactions, only require TRS_NONE (2). + // TRS_FALSE (0) disables all dynamic interactions, including existing ones. + ThreeState_t m_iDynamicInteractionsAllowed; +#endif + public: //----------------------------------------------------- @@ -1209,6 +1400,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, virtual void PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot ); virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); +#ifdef MAPBASE + virtual void ModifyOrAppendEnemyCriteria( AI_CriteriaSet& set, CBaseEntity *pEnemy ); + virtual void ModifyOrAppendDamageCriteria( AI_CriteriaSet& set, const CTakeDamageInfo &info ); +#endif protected: float SoundWaitTime() const { return m_flSoundWaitTime; } @@ -1226,6 +1421,11 @@ class CAI_BaseNPC : public CBaseCombatCharacter, int CapabilitiesRemove( int capabilities ); void CapabilitiesClear( void ); +#ifdef MAPBASE + void InputAddCapabilities( inputdata_t &inputdata ); + void InputRemoveCapabilities( inputdata_t &inputdata ); +#endif + private: int m_afCapability; // tells us what a npc can/can't do. @@ -1562,8 +1762,25 @@ class CAI_BaseNPC : public CBaseCombatCharacter, bool IsWeaponStateChanging( void ); void SetDesiredWeaponState( DesiredWeaponState_t iState ) { m_iDesiredWeaponState = iState; } +#ifdef MAPBASE + virtual bool DoHolster(void); + virtual bool DoUnholster(void); + + virtual bool ShouldUnholsterWeapon(); + virtual bool CanUnholsterWeapon(); + + void InputGiveWeaponHolstered( inputdata_t &inputdata ); + void InputChangeWeapon( inputdata_t &inputdata ); + void InputPickupWeapon( inputdata_t &inputdata ); + void InputPickupItem( inputdata_t &inputdata ); +#endif + // NOTE: The Shot Regulator is used to manage the RangeAttack1 weapon. inline CAI_ShotRegulator* GetShotRegulator() { return &m_ShotRegulator; } +#ifdef MAPBASE + // A special function for ai_weaponmodifier. + inline void SetShotRegulator(CAI_ShotRegulator NewRegulator) { m_ShotRegulator = NewRegulator; } +#endif virtual void OnRangeAttack1(); protected: @@ -1582,6 +1799,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, float m_flLastAttackTime; // Last time that I attacked my current enemy float m_flLastEnemyTime; float m_flNextWeaponSearchTime; // next time to search for a better weapon +#ifdef MAPBASE +public: + int m_iLastHolsteredWeapon; +#endif string_t m_iszPendingWeapon; // THe NPC should create and equip this weapon. bool m_bIgnoreUnseenEnemies; @@ -1624,6 +1845,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void SetHintGroup( string_t name, bool bHintGroupNavLimiting = false ); bool IsLimitingHintGroups( void ) { return m_bHintGroupNavLimiting; } +#ifdef MAPBASE + void InputSetHintGroup( inputdata_t &inputdata ) { SetHintGroup(inputdata.value.StringID()); } +#endif + //--------------------------------- CAI_TacticalServices *GetTacticalServices() { return m_pTacticalServices; } @@ -1663,7 +1888,9 @@ class CAI_BaseNPC : public CBaseCombatCharacter, //----------------------------------------------------- void InitRelationshipTable( void ); +#ifndef MAPBASE void AddRelationship( const char *pszRelationship, CBaseEntity *pActivator ); +#endif virtual void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ); virtual void AddClassRelationship( Class_T nClass, Disposition_t nDisposition, int nPriority ); @@ -1695,7 +1922,9 @@ class CAI_BaseNPC : public CBaseCombatCharacter, //--------------------------------- +#ifndef MAPBASE // Moved to CBaseCombatCharacter virtual CBaseEntity *FindNamedEntity( const char *pszName, IEntityFindFilter *pFilter = NULL ); +#endif //--------------------------------- // States @@ -1706,7 +1935,12 @@ class CAI_BaseNPC : public CBaseCombatCharacter, virtual bool ShouldLookForBetterWeapon(); bool Weapon_IsBetterAvailable ( void ) ; virtual Vector Weapon_ShootPosition( void ); +#ifdef MAPBASE + virtual CBaseCombatWeapon* GiveWeapon( string_t iszWeaponName, bool bDiscardCurrent = true ); + virtual CBaseCombatWeapon* GiveWeaponHolstered( string_t iszWeaponName ); +#else virtual void GiveWeapon( string_t iszWeaponName ); +#endif virtual void OnGivenWeapon( CBaseCombatWeapon *pNewWeapon ) { } bool IsMovingToPickupWeapon(); virtual bool WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos, bool bSetConditions); @@ -1761,6 +1995,7 @@ class CAI_BaseNPC : public CBaseCombatCharacter, virtual Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture ); + virtual bool ShouldGib( const CTakeDamageInfo &info ) { return false; } // Always ragdoll, unless specified by the leaf class virtual bool Event_Gibbed( const CTakeDamageInfo &info ); virtual void Event_Killed( const CTakeDamageInfo &info ); @@ -1803,16 +2038,27 @@ class CAI_BaseNPC : public CBaseCombatCharacter, //--------------------------------- virtual void PickupWeapon( CBaseCombatWeapon *pWeapon ); +#ifdef MAPBASE + virtual void PickupItem( CBaseEntity *pItem ); +#else virtual void PickupItem( CBaseEntity *pItem ) { }; +#endif CBaseEntity* DropItem( const char *pszItemName, Vector vecPos, QAngle vecAng );// drop an item. //--------------------------------- // Inputs //--------------------------------- +#ifndef MAPBASE // Moved to CBaseCombatCharacter void InputSetRelationship( inputdata_t &inputdata ); +#endif void InputSetEnemyFilter( inputdata_t &inputdata ); +#ifdef MAPBASE + // This is virtual so npc_helicopter can override it + virtual void InputSetHealthFraction( inputdata_t &inputdata ); +#else void InputSetHealth( inputdata_t &inputdata ); +#endif void InputBeginRappel( inputdata_t &inputdata ); void InputSetSquad( inputdata_t &inputdata ); void InputWake( inputdata_t &inputdata ); @@ -1903,6 +2149,16 @@ class CAI_BaseNPC : public CBaseCombatCharacter, COutputEvent m_OnForcedInteractionAborted; COutputEvent m_OnForcedInteractionFinished; +#ifdef MAPBASE + COutputEHANDLE m_OnHolsterWeapon; + COutputEHANDLE m_OnUnholsterWeapon; + + COutputEHANDLE m_OnItemPickup; + COutputEHANDLE m_OnItemDrop; + + COutputInt m_OnStateChange; +#endif + public: // use this to shrink the bbox temporarily void SetHullSizeNormal( bool force = false ); @@ -1986,6 +2242,10 @@ class CAI_BaseNPC : public CBaseCombatCharacter, inline void ForceCrouch( void ); inline void ClearForceCrouch( void ); +#ifdef MAPBASE + bool CouldShootIfCrouchingAt( const Vector &vecPosition, const Vector &vecForward, const Vector &vecRight, float flDist = 48.0f ); +#endif + protected: virtual bool Crouch( void ); virtual bool Stand( void ); @@ -2045,6 +2305,16 @@ class CAI_BaseNPC : public CBaseCombatCharacter, static CAI_GlobalScheduleNamespace gm_SchedulingSymbols; static CAI_ClassScheduleIdSpace gm_ClassScheduleIdSpace; +#ifdef MAPBASE + typedef struct + { + Activity sequence; + Activity gesture; + } actlink_t; + + static actlink_t gm_ActivityGestureLinks[]; +#endif + public: //---------------------------------------------------- // Debugging tools @@ -2089,6 +2359,16 @@ class CAI_BaseNPC : public CBaseCombatCharacter, CUtlVector m_ScheduleHistory; #endif//AI_MONITOR_FOR_OSCILLATION +#ifdef MAPBASE_VSCRIPT + static ScriptHook_t g_Hook_QueryHearSound; + static ScriptHook_t g_Hook_QuerySeeEntity; + static ScriptHook_t g_Hook_TranslateActivity; + static ScriptHook_t g_Hook_TranslateSchedule; + static ScriptHook_t g_Hook_GetActualShootPosition; + static ScriptHook_t g_Hook_OverrideMove; + static ScriptHook_t g_Hook_ShouldPlayFakeSequenceGesture; +#endif + private: // Break into pieces! @@ -2116,6 +2396,15 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void InputSetSpeedModifierRadius( inputdata_t &inputdata ); void InputSetSpeedModifierSpeed( inputdata_t &inputdata ); +#ifdef MAPBASE + // Hammer input to change the speed of the NPC (based on 1upD's npc_shadow_walker code) + // Not to be confused with the inputs above + virtual float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence ); + inline float GetSequenceGroundSpeed( int iSequence ) { return GetSequenceGroundSpeed( GetModelPtr(), iSequence ); } + void InputSetSpeedModifier( inputdata_t &inputdata ); + float m_flSpeedModifier; +#endif + virtual bool ShouldProbeCollideAgainstEntity( CBaseEntity *pEntity ); bool m_bPlayerAvoidState; @@ -2675,7 +2964,11 @@ class ScheduleLoadHelperImpl derivedClass::AccessClassScheduleIdSpaceDirect().Init( #derivedClass, BaseClass::GetSchedulingSymbols(), &BaseClass::AccessClassScheduleIdSpaceDirect() ); \ derivedClass::gm_SquadSlotIdSpace.Init( &CAI_BaseNPC::gm_SquadSlotNamespace, &BaseClass::gm_SquadSlotIdSpace); +#ifdef MAPBASE +#define ADD_CUSTOM_INTERACTION( interaction ) { CBaseCombatCharacter::AddInteractionWithString( interaction, #interaction ); } +#else #define ADD_CUSTOM_INTERACTION( interaction ) { interaction = CBaseCombatCharacter::GetInteractionID(); } +#endif #define ADD_CUSTOM_SQUADSLOT_NAMED(derivedClass,squadSlotName,squadSlotEN)\ if ( !derivedClass::gm_SquadSlotIdSpace.AddSymbol( squadSlotName, squadSlotEN, "squadslot", derivedClass::gm_pszErrorClassName ) ) return; @@ -3058,10 +3351,19 @@ abstract_class INPCInteractive // NOTE: YOU MUST DEFINE THE OUTPUTS IN YOUR CLASS'S DATADESC! // THE DO SO, INSERT THE FOLLOWING MACRO INTO YOUR CLASS'S DATADESC. // +#ifdef MAPBASE +#define DEFINE_BASENPCINTERACTABLE_DATADESC() \ + DEFINE_OUTPUT( m_OnAlyxStartedInteraction, "OnAlyxStartedInteraction" ), \ + DEFINE_OUTPUT( m_OnAlyxFinishedInteraction, "OnAlyxFinishedInteraction" ), \ + DEFINE_OUTPUT( m_OnHacked, "OnHacked" ), \ + DEFINE_INPUTFUNC( FIELD_VOID, "InteractivePowerDown", InputPowerdown ), \ + DEFINE_INPUTFUNC( FIELD_VOID, "Hack", InputDoInteraction ) +#else #define DEFINE_BASENPCINTERACTABLE_DATADESC() \ DEFINE_OUTPUT( m_OnAlyxStartedInteraction, "OnAlyxStartedInteraction" ), \ DEFINE_OUTPUT( m_OnAlyxFinishedInteraction, "OnAlyxFinishedInteraction" ), \ DEFINE_INPUTFUNC( FIELD_VOID, "InteractivePowerDown", InputPowerdown ) +#endif template class CNPCBaseInteractive : public NPC_CLASS, public INPCInteractive @@ -3077,6 +3379,13 @@ class CNPCBaseInteractive : public NPC_CLASS, public INPCInteractive } +#ifdef MAPBASE + virtual void InputDoInteraction( inputdata_t &inputdata ) + { + NotifyInteraction(inputdata.pActivator ? inputdata.pActivator->MyNPCPointer() : NULL); + } +#endif + // Alyx specific interactions virtual void AlyxStartedInteraction( void ) { @@ -3092,6 +3401,9 @@ class CNPCBaseInteractive : public NPC_CLASS, public INPCInteractive // Alyx specific interactions COutputEvent m_OnAlyxStartedInteraction; COutputEvent m_OnAlyxFinishedInteraction; +#ifdef MAPBASE + COutputEvent m_OnHacked; +#endif }; // diff --git a/game/server/ai_basenpc_schedule.cpp b/game/server/ai_basenpc_schedule.cpp index 35fa1af8..61fefb3f 100644 --- a/game/server/ai_basenpc_schedule.cpp +++ b/game/server/ai_basenpc_schedule.cpp @@ -470,7 +470,7 @@ CAI_Schedule *CAI_BaseNPC::GetNewSchedule( void ) // You may not be in combat state with no enemy!!! (sjb) 11/4/03 if( m_NPCState == NPC_STATE_COMBAT && !GetEnemy() ) { - DevMsg("**ERROR: Combat State with no enemy! slamming to ALERT\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "**ERROR: Combat State with no enemy! slamming to ALERT\n" ); SetState( NPC_STATE_ALERT ); } @@ -693,7 +693,7 @@ void CAI_BaseNPC::MaintainSchedule ( void ) if ( !GetCurSchedule() || GetCurSchedule()->NumTasks() == 0 ) { - DevMsg("ERROR: Missing or invalid schedule!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: Missing or invalid schedule!\n" ); SetActivity ( ACT_IDLE ); return; } @@ -980,8 +980,12 @@ bool CAI_BaseNPC::FindCoverFromEnemy( bool bNodesOnly, float flMinDistance, floa // FIXME: add to goal if (GetHintNode()) { +#ifdef MAPBASE + GetHintNode()->NPCHandleStartNav( this, true ); +#else GetNavigator()->SetArrivalActivity( GetCoverActivity( GetHintNode() ) ); GetNavigator()->SetArrivalDirection( GetHintNode()->GetDirection() ); +#endif } return true; @@ -1004,7 +1008,7 @@ bool CAI_BaseNPC::FindCoverFromBestSound( Vector *pCoverPos ) } else { - DevMsg( 2, "Attempting to find cover from best sound, but best sound not founc.\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "Attempting to find cover from best sound, but best sound not founc.\n" ); } return false; @@ -1360,6 +1364,14 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) break; case TASK_STOP_MOVING: +#ifdef MAPBASE + if ( GetNavType() == NAV_CLIMB ) + { + // Don't clear the goal so that the climb can finish + DbgNavMsg( this, "Start TASK_STOP_MOVING with climb workaround\n" ); + } + else +#endif if ( ( GetNavigator()->IsGoalSet() && GetNavigator()->IsGoalActive() ) || GetNavType() == NAV_JUMP ) { DbgNavMsg( this, "Start TASK_STOP_MOVING\n" ); @@ -1585,6 +1597,39 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) SetWait( pTask->flTaskData ); break; +#ifdef MAPBASE + case TASK_FACE_INTERACTION_ANGLES: + { + if ( !m_hForcedInteractionPartner ) + { + TaskFail( FAIL_NO_TARGET ); + return; + } + + // Get our running interaction from our partner, + // as this should only run with the NPC "receiving" the interaction + ScriptedNPCInteraction_t *pInteraction = m_hForcedInteractionPartner->GetRunningDynamicInteraction(); + + // Get our target's origin + Vector vecTarget = m_hForcedInteractionPartner->GetAbsOrigin(); + + // Face the angles the interaction actually wants us at, opposite to the partner + float angInteractionAngle = pInteraction->angRelativeAngles.y; + angInteractionAngle += 180.0f; + + GetMotor()->SetIdealYaw( CalcIdealYaw( vecTarget ) + angInteractionAngle ); + + if (FacingIdeal()) + TaskComplete(); + else + { + GetMotor()->SetIdealYaw( CalcReasonableFacing( true ) ); + SetTurnActivity(); + } + } + break; +#endif + case TASK_FACE_ENEMY: { Vector vecEnemyLKP = GetEnemyLKP(); @@ -1750,16 +1795,8 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) break; case TASK_RELOAD: -#ifdef VANCE - { - Activity reloadAct = TranslateActivity( ACT_GESTURE_RELOAD ); - AddGesture( reloadAct ); - TaskComplete(); - break; - } -#else ResetIdealActivity( ACT_RELOAD ); -#endif + break; case TASK_SPECIAL_ATTACK1: ResetIdealActivity( ACT_SPECIAL_ATTACK1 ); @@ -2715,7 +2752,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) case TASK_SOUND_ANGRY: { // sounds are complete as soon as we get here, cause we've already played them. - DevMsg( 2, "SOUND\n" ); + CGMsg( 2, CON_GROUP_NPC_AI, "SOUND\n" ); TaskComplete(); break; } @@ -2757,7 +2794,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) { if ( !m_hCine ) { - DevMsg( "Scripted sequence destroyed while in use\n" ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -2768,13 +2805,20 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) { if ( !m_hCine ) { - DevMsg( "Scripted sequence destroyed while in use\n" ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } string_t iszArrivalText; +#ifdef MAPBASE + if ( m_hCine->m_iszPreIdle != NULL_STRING ) + { + iszArrivalText = m_hCine->m_iszPreIdle; + } + else +#endif if ( m_hCine->m_iszEntry != NULL_STRING ) { iszArrivalText = m_hCine->m_iszEntry; @@ -2865,6 +2909,9 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) // if ( m_hCine->m_iszPreIdle != NULL_STRING ) { +#ifdef MAPBASE + m_hCine->OnPreIdleSequence( this ); +#endif m_hCine->StartSequence( ( CAI_BaseNPC * )this, m_hCine->m_iszPreIdle, false ); if ( FStrEq( STRING( m_hCine->m_iszPreIdle ), STRING( m_hCine->m_iszPlay ) ) ) { @@ -2977,7 +3024,16 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) case TASK_ITEM_PICKUP: { - SetIdealActivity( ACT_PICKUP_GROUND ); +#ifdef MAPBASE + if (GetTarget() && fabs( GetTarget()->WorldSpaceCenter().z - GetAbsOrigin().z ) >= 12.0f) + { + SetIdealActivity( ACT_PICKUP_RACK ); + } + else +#endif + { + SetIdealActivity( ACT_PICKUP_GROUND ); + } } break; @@ -3105,7 +3161,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask ) default: { - DevMsg( "No StartTask entry for %s\n", TaskName( task ) ); + CGMsg( 1, CON_GROUP_NPC_AI, "No StartTask entry for %s\n", TaskName( task ) ); } break; } @@ -3252,7 +3308,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) // Put a debugging check in here if (GetHintNode()->User() != this) { - DevMsg("Hint node (%s) being used by non-owner!\n",GetHintNode()->GetDebugName()); + CGMsg( 1, CON_GROUP_NPC_AI, "Hint node (%s) being used by non-owner!\n", GetHintNode()->GetDebugName() ); } if ( IsActivityFinished() ) @@ -3301,8 +3357,40 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) // a navigation while in the middle of a climb if (GetNavType() == NAV_CLIMB) { +#ifdef MAPBASE + if (GetActivity() != ACT_CLIMB_DISMOUNT) + { + // Try to just pause the climb, but dismount if we're in SCHED_FAIL + if (IsCurSchedule( SCHED_FAIL, false )) + { + GetMotor()->MoveClimbStop(); + } + else + { + GetMotor()->MoveClimbPause(); + } + + TaskComplete(); + } + else if (IsActivityFinished()) + { + // Dismount complete. + GetMotor()->MoveClimbStop(); + + // Fix up our position if we have to + Vector vecTeleportOrigin; + if (GetMotor()->MoveClimbShouldTeleportToSequenceEnd( vecTeleportOrigin )) + { + SetLocalOrigin( vecTeleportOrigin ); + } + + TaskComplete(); + } + break; +#else // wait until you reach the end break; +#endif } DbgNavMsg( this, "TASK_STOP_MOVING Complete\n" ); @@ -3347,6 +3435,17 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) // If the yaw is locked, this function will not act correctly Assert( GetMotor()->IsYawLocked() == false ); +#ifdef MAPBASE + if ( GetHintNode() && GetHintNode()->OverridesNPCYaw( this ) ) + { + // If the yaw is supposed to use that of a hint node, chain to TASK_FACE_HINTNODE + GetMotor()->SetIdealYaw( GetHintNode()->Yaw() ); + GetMotor()->SetIdealYaw( CalcReasonableFacing( true ) ); // CalcReasonableFacing() is based on previously set ideal yaw + ChainRunTask( TASK_FACE_HINTNODE, pTask->flTaskData ); + break; + } +#endif + Vector vecEnemyLKP = GetEnemyLKP(); if (!FInAimCone( vecEnemyLKP )) { @@ -3388,6 +3487,36 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) } break; +#ifdef MAPBASE + case TASK_FACE_INTERACTION_ANGLES: + { + if ( !m_hForcedInteractionPartner ) + { + TaskFail( FAIL_NO_TARGET ); + return; + } + + // Get our running interaction from our partner, + // as this should only run with the NPC "receiving" the interaction + ScriptedNPCInteraction_t *pInteraction = m_hForcedInteractionPartner->GetRunningDynamicInteraction(); + + // Get our target's origin + Vector vecTarget = m_hForcedInteractionPartner->GetAbsOrigin(); + + // Face the angles the interaction actually wants us at, opposite to the partner + float angInteractionAngle = pInteraction->angRelativeAngles.y; + angInteractionAngle += 180.0f; + + GetMotor()->SetIdealYawAndUpdate( CalcIdealYaw( vecTarget ) + angInteractionAngle, AI_KEEP_YAW_SPEED ); + + if (IsWaitFinished()) + { + TaskComplete(); + } + } + break; +#endif + case TASK_FIND_COVER_FROM_BEST_SOUND: { switch( GetTaskInterrupt() ) @@ -3676,9 +3805,22 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) { if( GetNavigator()->SetGoal(vecGoal) ) { +#ifdef MAPBASE + // Pushaway destinations could be an entire floor above. + // That would get frustrating. Only go to hints within a path distance of 300 units, + // only slightly above our initial search conditions. + if (GetNavigator()->BuildAndGetPathDistToGoal() < 300.0f) + { + pHint->NPCHandleStartNav(this, false); + pHint->DisableForSeconds( 0.1f ); // Force others to find their own. + TaskComplete(); + break; + } +#else pHint->DisableForSeconds( 0.1f ); // Force others to find their own. TaskComplete(); break; +#endif } } } @@ -3889,15 +4031,25 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) if ( m_hCine && m_hCine->IsTimeToStart() ) { TaskComplete(); +#ifdef MAPBASE + m_hCine->OnBeginSequence(this); +#else m_hCine->OnBeginSequence(); +#endif // If we have an entry, we have to play it first if ( m_hCine->m_iszEntry != NULL_STRING ) { +#ifdef MAPBASE + m_hCine->OnEntrySequence( this ); +#endif m_hCine->StartSequence( (CAI_BaseNPC *)this, m_hCine->m_iszEntry, true ); } else { +#ifdef MAPBASE + m_hCine->OnActionSequence( this ); +#endif m_hCine->StartSequence( (CAI_BaseNPC *)this, m_hCine->m_iszPlay, true ); } @@ -3912,7 +4064,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) } else if (!m_hCine) { - DevMsg( "Cine died!\n"); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Cine died!\n" ); TaskComplete(); } else if ( IsRunningDynamicInteraction() ) @@ -3968,7 +4120,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) { if ( !m_hCine ) { - DevMsg( "Scripted sequence destroyed while in use\n" ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -3987,7 +4139,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) { if ( !m_hCine ) { - DevMsg( "Scripted sequence destroyed while in use\n" ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "Scripted sequence destroyed while in use\n" ); TaskFail( FAIL_SCHEDULE_NOT_FOUND ); break; } @@ -4144,7 +4296,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask ) default: { - DevMsg( "No RunTask entry for %s\n", TaskName( pTask->iTask ) ); + CGMsg( 1, CON_GROUP_NPC_AI, "No RunTask entry for %s\n", TaskName( pTask->iTask ) ); TaskComplete(); } break; @@ -4180,6 +4332,15 @@ void CAI_BaseNPC::SetTurnActivity ( void ) float flYD; flYD = GetMotor()->DeltaIdealYaw(); +#ifdef MAPBASE + // Allow AddTurnGesture() to decide this + if (GetMotor()->AddTurnGesture( flYD )) + { + SetIdealActivity( ACT_IDLE ); + Remember( bits_MEMORY_TURNING ); + return; + } +#else // FIXME: unknown case, update yaw should catch these /* if (GetMotor()->AddTurnGesture( flYD )) @@ -4189,6 +4350,7 @@ void CAI_BaseNPC::SetTurnActivity ( void ) return; } */ +#endif if( flYD <= -80 && flYD >= -100 && SelectWeightedSequence( ACT_90_RIGHT ) != ACTIVITY_NOT_AVAILABLE ) { @@ -4316,7 +4478,7 @@ int CAI_BaseNPC::GetScriptCustomMoveSequence( void ) iSequence = LookupSequence( STRING( m_hCine->m_iszCustomMove ) ); if ( iSequence == ACTIVITY_NOT_AVAILABLE ) { - DevMsg( "SCRIPT_CUSTOM_MOVE: %s has no sequence:%s\n", GetClassname(), STRING(m_hCine->m_iszCustomMove) ); + CGMsg( 1, CON_GROUP_NPC_SCRIPTS, "SCRIPT_CUSTOM_MOVE: %s has no sequence:%s\n", GetClassname(), STRING(m_hCine->m_iszCustomMove) ); } } else if ( m_iszSceneCustomMoveSeq != NULL_STRING ) diff --git a/game/server/ai_behavior.cpp b/game/server/ai_behavior.cpp index 7071bd50..4730e122 100644 --- a/game/server/ai_behavior.cpp +++ b/game/server/ai_behavior.cpp @@ -411,6 +411,35 @@ void CAI_BehaviorBase::HandleAnimEvent( animevent_t *pEvent ) m_pBackBridge->BackBridge_HandleAnimEvent( pEvent ); } +#ifdef MAPBASE +//------------------------------------- + +bool CAI_BehaviorBase::CanUnholsterWeapon( void ) +{ + Assert( m_pBackBridge != NULL ); + + return m_pBackBridge->BackBridge_CanUnholsterWeapon(); +} + +//------------------------------------- + +bool CAI_BehaviorBase::ShouldPickADeathPose( void ) +{ + Assert( m_pBackBridge != NULL ); + + return m_pBackBridge->BackBridge_ShouldPickADeathPose(); +} + +//------------------------------------- + +bool CAI_BehaviorBase::CanTranslateCrouchActivity( void ) +{ + Assert( m_pBackBridge != NULL ); + + return m_pBackBridge->BackBridge_CanTranslateCrouchActivity(); +} +#endif + //------------------------------------- bool CAI_BehaviorBase::NotifyChangeBehaviorStatus( bool fCanFinishSchedule ) diff --git a/game/server/ai_behavior.h b/game/server/ai_behavior.h index f88a0c45..f4df0640 100644 --- a/game/server/ai_behavior.h +++ b/game/server/ai_behavior.h @@ -130,6 +130,11 @@ abstract_class CAI_BehaviorBase : public CAI_Component void BridgeModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ); void BridgeTeleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity ); void BridgeHandleAnimEvent( animevent_t *pEvent ); +#ifdef MAPBASE + bool BridgeCanUnholsterWeapon( void ); + bool BridgeShouldPickADeathPose( void ); + bool BridgeCanTranslateCrouchActivity( void ); +#endif virtual void GatherConditions(); virtual void GatherConditionsNotActive() { return; } // Override this and your behavior will call this in place of GatherConditions() when your behavior is NOT the active one. @@ -215,6 +220,11 @@ abstract_class CAI_BehaviorBase : public CAI_Component virtual void ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ); virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity ); virtual void HandleAnimEvent( animevent_t *pEvent ); +#ifdef MAPBASE + virtual bool CanUnholsterWeapon( void ); + virtual bool ShouldPickADeathPose( void ); + virtual bool CanTranslateCrouchActivity( void ); +#endif virtual bool ShouldAlwaysThink(); @@ -361,6 +371,14 @@ abstract_class IBehaviorBackBridge virtual void BackBridge_HandleAnimEvent( animevent_t *pEvent ) = 0; +#ifdef MAPBASE + // For func_tank behavior + virtual bool BackBridge_CanUnholsterWeapon( void ) = 0; + + virtual bool BackBridge_ShouldPickADeathPose( void ) = 0; + virtual bool BackBridge_CanTranslateCrouchActivity( void ) = 0; +#endif + //------------------------------------- }; @@ -457,6 +475,11 @@ class CAI_BehaviorHost : public BASE_NPC, Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture ); bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ); void HandleAnimEvent( animevent_t *pEvent ); +#ifdef MAPBASE + bool CanUnholsterWeapon( void ); + bool ShouldPickADeathPose( void ); + bool CanTranslateCrouchActivity( void ); +#endif bool ShouldAlwaysThink(); @@ -517,6 +540,14 @@ class CAI_BehaviorHost : public BASE_NPC, void BackBridge_HandleAnimEvent( animevent_t *pEvent ); +#ifdef MAPBASE + // For func_tank behavior + bool BackBridge_CanUnholsterWeapon( void ); + + bool BackBridge_ShouldPickADeathPose( void ); + bool BackBridge_CanTranslateCrouchActivity( void ); +#endif + CAI_BehaviorBase **AccessBehaviors(); int NumBehaviors(); @@ -887,6 +918,29 @@ inline void CAI_BehaviorBase::BridgeHandleAnimEvent( animevent_t *pEvent ) HandleAnimEvent( pEvent ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- + +inline bool CAI_BehaviorBase::BridgeCanUnholsterWeapon( void ) +{ + return CanUnholsterWeapon(); +} + +//----------------------------------------------------------------------------- + +inline bool CAI_BehaviorBase::BridgeShouldPickADeathPose( void ) +{ + return ShouldPickADeathPose(); +} + +//----------------------------------------------------------------------------- + +inline bool CAI_BehaviorBase::BridgeCanTranslateCrouchActivity( void ) +{ + return CanTranslateCrouchActivity(); +} +#endif + //----------------------------------------------------------------------------- template @@ -1462,6 +1516,32 @@ inline void CAI_BehaviorHost::BackBridge_HandleAnimEvent( animevent_t BaseClass::HandleAnimEvent( pEvent ); } +#ifdef MAPBASE +//------------------------------------- + +template +inline bool CAI_BehaviorHost::BackBridge_CanUnholsterWeapon( void ) +{ + return BaseClass::CanUnholsterWeapon(); +} + +//------------------------------------- + +template +inline bool CAI_BehaviorHost::BackBridge_ShouldPickADeathPose( void ) +{ + return BaseClass::ShouldPickADeathPose(); +} + +//------------------------------------- + +template +inline bool CAI_BehaviorHost::BackBridge_CanTranslateCrouchActivity( void ) +{ + return BaseClass::CanTranslateCrouchActivity(); +} +#endif + //------------------------------------- template @@ -1865,6 +1945,41 @@ inline void CAI_BehaviorHost::HandleAnimEvent( animevent_t *pEvent ) return BaseClass::HandleAnimEvent( pEvent ); } +#ifdef MAPBASE +//------------------------------------- + +template +inline bool CAI_BehaviorHost::CanUnholsterWeapon( void ) +{ + if ( m_pCurBehavior ) + return m_pCurBehavior->BridgeCanUnholsterWeapon(); + + return BaseClass::CanUnholsterWeapon(); +} + +//------------------------------------- + +template +inline bool CAI_BehaviorHost::ShouldPickADeathPose( void ) +{ + if (m_pCurBehavior) + return m_pCurBehavior->BridgeShouldPickADeathPose(); + + return BaseClass::ShouldPickADeathPose(); +} + +//------------------------------------- + +template +inline bool CAI_BehaviorHost::CanTranslateCrouchActivity( void ) +{ + if (m_pCurBehavior) + return m_pCurBehavior->BridgeCanTranslateCrouchActivity(); + + return BaseClass::CanTranslateCrouchActivity(); +} +#endif + //------------------------------------- template diff --git a/game/server/ai_behavior_assault.cpp b/game/server/ai_behavior_assault.cpp index e02627cc..bacb4d6a 100644 --- a/game/server/ai_behavior_assault.cpp +++ b/game/server/ai_behavior_assault.cpp @@ -251,7 +251,12 @@ CAssaultPoint *CAI_AssaultBehavior::FindAssaultPoint( string_t iszAssaultPointNa CUtlVectorpAssaultPoints; CUtlVectorpClearAssaultPoints; +#ifdef MAPBASE + // Prevents non-assault points (e.g. rally points) from crashing the game + CAssaultPoint *pAssaultEnt = dynamic_cast(gEntList.FindEntityByName( NULL, iszAssaultPointName )); +#else CAssaultPoint *pAssaultEnt = (CAssaultPoint *)gEntList.FindEntityByName( NULL, iszAssaultPointName ); +#endif while( pAssaultEnt != NULL ) { diff --git a/game/server/ai_behavior_fear.cpp b/game/server/ai_behavior_fear.cpp index ea908ba6..d153b7e3 100644 --- a/game/server/ai_behavior_fear.cpp +++ b/game/server/ai_behavior_fear.cpp @@ -20,6 +20,9 @@ BEGIN_DATADESC( CAI_FearBehavior ) DEFINE_FIELD( m_hMovingToHint, FIELD_EHANDLE ), DEFINE_EMBEDDED( m_SafePlaceMoveMonitor ), DEFINE_FIELD( m_flDeferUntil, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_FIELD( m_hFearGoal, FIELD_EHANDLE ), +#endif END_DATADESC(); #define BEHAVIOR_FEAR_SAFETY_TIME 5 @@ -61,6 +64,11 @@ void CAI_FearBehavior::StartTask( const Task_t *pTask ) m_hSafePlaceHint = m_hMovingToHint; m_hSafePlaceHint->Lock( GetOuter() ); m_SafePlaceMoveMonitor.SetMark( GetOuter(), FEAR_SAFE_PLACE_TOLERANCE ); +#ifdef MAPBASE + m_hSafePlaceHint->NPCStartedUsing( GetOuter() ); + if (m_hFearGoal) + m_hFearGoal->m_OnArriveAtFearNode.FireOutput(m_hSafePlaceHint, GetOuter()); +#endif TaskComplete(); break; @@ -149,7 +157,11 @@ void CAI_FearBehavior::RunTask( const Task_t *pTask ) } else { +#ifdef MAPBASE + m_hMovingToHint->NPCHandleStartNav( GetOuter(), true ); +#else GetNavigator()->SetArrivalDirection( m_hMovingToHint->GetAbsAngles() ); +#endif } } break; @@ -231,6 +243,10 @@ void CAI_FearBehavior::ReleaseAllHints() // If I have a safe place, unlock it for others. m_hSafePlaceHint->Unlock(); +#ifdef MAPBASE + m_hSafePlaceHint->NPCStoppedUsing(GetOuter()); +#endif + // Don't make it available right away. I probably left for a good reason. // We also don't want to oscillate m_hSafePlaceHint->DisableForSeconds( 4.0f ); @@ -274,6 +290,22 @@ bool CAI_FearBehavior::CanSelectSchedule() if( GetOuter()->IRelationType(pEnemy) != D_FR ) return false; +#ifdef MAPBASE + // Don't run fear behavior if we've been ordered somewhere + if (GetOuter()->GetCommandGoal() != vec3_invalid) + return false; + + // Don't run fear behavior if we're running any non-follow behaviors + if (GetOuter()->GetRunningBehavior() && GetOuter()->GetRunningBehavior() != this && !FStrEq(GetOuter()->GetRunningBehavior()->GetName(), "Follow")) + return false; + + if (m_hFearGoal && m_iszFearTarget != NULL_STRING) + { + if (pEnemy->NameMatches(m_iszFearTarget) || pEnemy->ClassMatches(m_iszFearTarget)) + return true; + } +#endif + if( !pEnemy->ClassMatches("npc_hunter") ) return false; @@ -457,6 +489,9 @@ CAI_Hint *CAI_FearBehavior::FindFearWithdrawalDest() hintCriteria.AddHintType( HINT_PLAYER_ALLY_FEAR_DEST ); hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE_TO_PLAYER | bits_HINT_NOT_CLOSE_TO_ENEMY /*| bits_HINT_NODE_IN_VIEWCONE | bits_HINT_NPC_IN_NODE_FOV*/ ); +#ifdef MAPBASE + hintCriteria.SetFlag(bits_HINT_NODE_USE_GROUP); +#endif hintCriteria.AddIncludePosition( AI_GetSinglePlayer()->GetAbsOrigin(), ( ai_fear_player_dist.GetFloat() ) ); pHint = CAI_HintManager::FindHint( pOuter, hintCriteria ); @@ -478,6 +513,108 @@ CAI_Hint *CAI_FearBehavior::FindFearWithdrawalDest() return pHint; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +Activity CAI_FearBehavior::NPC_TranslateActivity( Activity activity ) +{ + if ( activity == ACT_IDLE && m_hSafePlaceHint && m_hSafePlaceHint->HintActivityName() != NULL_STRING ) + { + return GetOuter()->GetHintActivity(m_hSafePlaceHint->HintType(), (Activity)CAI_BaseNPC::GetActivityID( STRING(m_hSafePlaceHint->HintActivityName()) ) ); + } + return BaseClass::NPC_TranslateActivity( activity ); +} + +//----------------------------------------------------------------------------- +// Updates the fear goal's target. +//----------------------------------------------------------------------------- +void CAI_FearBehavior::OnRestore() +{ + BaseClass::OnRestore(); + + if (m_hFearGoal.Get() != NULL) + { + m_iszFearTarget = m_hFearGoal->m_target; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_FearBehavior::SetParameters( CAI_FearGoal *pGoal, string_t target ) +{ + m_hFearGoal = pGoal; + m_iszFearTarget = target; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//============================================================================= +//============================================================================= +// >AI_GOAL_FEAR +//============================================================================= +//============================================================================= +LINK_ENTITY_TO_CLASS( ai_goal_fear, CAI_FearGoal ); + +BEGIN_DATADESC( CAI_FearGoal ) + //DEFINE_KEYFIELD( m_iSomething, FIELD_INTEGER, "something" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + + // Outputs + //DEFINE_OUTPUT( m_OnSeeFearEntity, "OnSeeFearEntity" ), + DEFINE_OUTPUT( m_OnArriveAtFearNode, "OnArrivedAtNode" ), +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_FearGoal::EnableGoal( CAI_BaseNPC *pAI ) +{ + CAI_FearBehavior *pBehavior; + + if ( !pAI->GetBehavior( &pBehavior ) ) + { + return; + } + + pBehavior->SetParameters(this, m_target); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_FearGoal::DisableGoal( CAI_BaseNPC *pAI ) +{ + CAI_FearBehavior *pBehavior; + + if ( !pAI->GetBehavior( &pBehavior ) ) + { + return; + } + + pBehavior->SetParameters(NULL, NULL_STRING); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CAI_FearGoal::InputActivate( inputdata_t &inputdata ) +{ + BaseClass::InputActivate( inputdata ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CAI_FearGoal::InputDeactivate( inputdata_t &inputdata ) +{ + BaseClass::InputDeactivate( inputdata ); +} +#endif + AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_FearBehavior ) DECLARE_TASK( TASK_FEAR_GET_PATH_TO_SAFETY_HINT ) @@ -531,6 +668,25 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_FearBehavior ) //=============================================== //=============================================== +#ifdef MAPBASE + DEFINE_SCHEDULE + ( + SCHED_FEAR_STAY_IN_SAFE_PLACE, + + " Tasks" + " TASK_FEAR_WAIT_FOR_SAFETY 0" + "" + " Interrupts" + "" + " COND_NEW_ENEMY" + " COND_HEAR_DANGER" + " COND_FEAR_ENEMY_CLOSE" + " COND_FEAR_ENEMY_TOO_CLOSE" + " COND_CAN_RANGE_ATTACK1" + " COND_FEAR_SEPARATED_FROM_PLAYER" + " COND_ENEMY_DEAD" // Allows the fearful to follow the player when enemy dies + ); +#else DEFINE_SCHEDULE ( SCHED_FEAR_STAY_IN_SAFE_PLACE, @@ -547,6 +703,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_FearBehavior ) " COND_CAN_RANGE_ATTACK1" " COND_FEAR_SEPARATED_FROM_PLAYER" ); +#endif AI_END_CUSTOM_SCHEDULE_PROVIDER() diff --git a/game/server/ai_behavior_fear.h b/game/server/ai_behavior_fear.h index b13848cb..e92ae689 100644 --- a/game/server/ai_behavior_fear.h +++ b/game/server/ai_behavior_fear.h @@ -20,6 +20,37 @@ #include "ai_behavior.h" +#ifdef MAPBASE +#include "ai_goalentity.h" + +//========================================================= +//========================================================= +class CAI_FearGoal : public CAI_GoalEntity +{ + DECLARE_CLASS( CAI_FearGoal, CAI_GoalEntity ); +public: + CAI_FearGoal() + { + } + + void EnableGoal( CAI_BaseNPC *pAI ); + void DisableGoal( CAI_BaseNPC *pAI ); + + // Inputs + virtual void InputActivate( inputdata_t &inputdata ); + virtual void InputDeactivate( inputdata_t &inputdata ); + + // Note that the outer is the caller in these outputs + //COutputEvent m_OnSeeFearEntity; + COutputEvent m_OnArriveAtFearNode; + + DECLARE_DATADESC(); + +protected: + // Put something here +}; +#endif + class CAI_FearBehavior : public CAI_SimpleBehavior { DECLARE_CLASS( CAI_FearBehavior, CAI_SimpleBehavior ); @@ -56,6 +87,17 @@ class CAI_FearBehavior : public CAI_SimpleBehavior void BuildScheduleTestBits(); int TranslateSchedule( int scheduleType ); +#ifdef MAPBASE + virtual Activity NPC_TranslateActivity( Activity activity ); + + virtual void OnRestore(); + virtual void SetParameters( CAI_FearGoal *pGoal, string_t target ); + CHandle m_hFearGoal; + + // Points to goal's fear target + string_t m_iszFearTarget; +#endif + enum { diff --git a/game/server/ai_behavior_follow.cpp b/game/server/ai_behavior_follow.cpp index 4c77972c..a2ab0cae 100644 --- a/game/server/ai_behavior_follow.cpp +++ b/game/server/ai_behavior_follow.cpp @@ -20,6 +20,9 @@ #ifdef HL2_EPISODIC #include "info_darknessmode_lightsource.h" +#ifdef MAPBASE + #include "globalstate.h" +#endif #endif // memdbgon must be the last include file in a .cpp file!!! @@ -403,8 +406,13 @@ bool CAI_FollowBehavior::SetFollowGoal( CAI_FollowGoal *pGoal, bool fFinishCurSc } SetFollowTarget( pGoal->GetGoalEntity() ); +#ifdef MAPBASE + Assert( pGoal->m_iFormation < AIF_NUM_FORMATIONS ); + SetParameters( AI_FollowParams_t( (AI_Formations_t)pGoal->m_iFormation, pGoal->m_bNormalMemoryDiscard ) ); +#else Assert( pGoal->m_iFormation == AIF_SIMPLE || pGoal->m_iFormation == AIF_WIDE || pGoal->m_iFormation == AIF_MEDIUM || pGoal->m_iFormation == AIF_SIDEKICK || pGoal->m_iFormation == AIF_VORTIGAUNT ); SetParameters( AI_FollowParams_t( (AI_Formations_t)pGoal->m_iFormation ) ); +#endif m_hFollowGoalEnt = pGoal; m_flTimeUpdatedFollowPosition = 0; return true; @@ -764,7 +772,12 @@ void CAI_FollowBehavior::GatherConditions( void ) #ifdef HL2_EPISODIC // Let followers know if the player is lit in the darkness +#ifdef MAPBASE + // If the darkness mode counter is 1, follow behavior is not affected by darkness. + if ( GetFollowTarget()->IsPlayer() && HL2GameRules()->IsAlyxInDarknessMode() && GlobalEntity_GetCounter("ep_alyx_darknessmode") != 1 ) +#else if ( GetFollowTarget()->IsPlayer() && HL2GameRules()->IsAlyxInDarknessMode() ) +#endif { if ( LookerCouldSeeTargetInDarkness( GetOuter(), GetFollowTarget() ) ) { @@ -907,6 +920,11 @@ void CAI_FollowBehavior::ClearFollowPoint() { if ( GetHintNode() && GetHintNode()->HintType() == HINT_FOLLOW_WAIT_POINT ) { +#ifdef MAPBASE + // If we were in range, we were probably already using it + if (GetFollowTarget() && (GetHintNode()->GetAbsOrigin() - GetFollowTarget()->GetAbsOrigin()).LengthSqr() < Square(MAX(m_FollowNavGoal.followPointTolerance, GetGoalRange()))) + GetHintNode()->NPCStoppedUsing(GetOuter()); +#endif GetHintNode()->Unlock(); SetHintNode( NULL ); } @@ -931,7 +949,14 @@ CAI_Hint *CAI_FollowBehavior::FindFollowPoint() CHintCriteria hintCriteria; hintCriteria.SetHintType( HINT_FOLLOW_WAIT_POINT ); +#ifdef MAPBASE + // NOTE: Does this make them stop following? + hintCriteria.SetGroup( GetOuter()->GetHintGroup() ); + hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE | bits_HINT_NODE_NEAREST | bits_HINT_NODE_USE_GROUP ); + //hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE | bits_HINT_NODE_NEAREST ); +#else hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE | bits_HINT_NODE_NEAREST ); +#endif // Add the search position hintCriteria.AddIncludePosition( GetGoalPosition(), MAX( m_FollowNavGoal.followPointTolerance, GetGoalRange() ) ); @@ -1033,6 +1058,9 @@ int CAI_FollowBehavior::SelectScheduleFollowPoints() { if ( bNewHint || distSqToPoint > WAIT_HINT_MIN_DIST ) return SCHED_FOLLOWER_GO_TO_WAIT_POINT; +#ifdef MAPBASE + GetHintNode()->NPCStartedUsing(GetOuter()); +#endif if ( !ShouldIgnoreFollowPointFacing() ) return SCHED_FOLLOWER_STAND_AT_WAIT_POINT; } @@ -2111,6 +2139,9 @@ bool CAI_FollowBehavior::ShouldAlwaysThink() BEGIN_DATADESC( CAI_FollowGoal ) DEFINE_KEYFIELD( m_iFormation, FIELD_INTEGER, "Formation" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bNormalMemoryDiscard, FIELD_BOOLEAN, "NormalMemoryDiscard" ), +#endif #ifdef HL2_EPISODIC DEFINE_INPUTFUNC( FIELD_VOID, "OutsideTransition", InputOutsideTransition ), diff --git a/game/server/ai_behavior_follow.h b/game/server/ai_behavior_follow.h index a0e43837..097588c6 100644 --- a/game/server/ai_behavior_follow.h +++ b/game/server/ai_behavior_follow.h @@ -36,6 +36,9 @@ enum AI_Formations_t AIF_SIDEKICK, AIF_HUNTER, AIF_VORTIGAUNT, +#ifdef MAPBASE + AIF_NUM_FORMATIONS, +#endif }; enum AI_FollowFormationFlags_t @@ -68,6 +71,10 @@ class CAI_FollowGoal : public CAI_GoalEntity int m_iFormation; +#ifdef MAPBASE + bool m_bNormalMemoryDiscard = false; +#endif + DECLARE_DATADESC(); }; diff --git a/game/server/ai_behavior_lead.cpp b/game/server/ai_behavior_lead.cpp index 9cee1951..e27aaa20 100644 --- a/game/server/ai_behavior_lead.cpp +++ b/game/server/ai_behavior_lead.cpp @@ -269,7 +269,7 @@ bool CAI_LeadBehavior::GetClosestPointOnRoute( const Vector &targetPos, Vector * float flNearestDist = 999999999; float flPathDist, flPathDist2D; - Vector vecNearestPoint(0, 0, 0); + Vector vecNearestPoint; Vector vecPrevPos = GetOuter()->GetAbsOrigin(); for ( ; (waypoint != NULL) ; waypoint = waypoint->GetNext() ) { @@ -543,8 +543,12 @@ int CAI_LeadBehavior::SelectSchedule() if ( !m_flWeaponSafetyTimeOut || (m_flWeaponSafetyTimeOut > gpGlobals->curtime) ) return SCHED_LEAD_PLAYERNEEDSWEAPON; +#ifdef MAPBASE + pFollower->GiveNamedItem( STRING(m_weaponname) ); +#else string_t iszItem = AllocPooledString( "weapon_bugbait" ); pFollower->GiveNamedItem( STRING(iszItem) ); +#endif } } @@ -996,7 +1000,7 @@ void CAI_LeadBehavior::RunTask( const Task_t *pTask ) //------------------------------------- -bool CAI_LeadBehavior::Speak( AIConcept_t concept ) +bool CAI_LeadBehavior::Speak( AIConcept_t conceptId ) { CAI_Expresser *pExpresser = GetOuter()->GetExpresser(); if ( !pExpresser ) @@ -1007,7 +1011,7 @@ bool CAI_LeadBehavior::Speak( AIConcept_t concept ) return false; // If we haven't said the start speech, don't nag - bool bNag = ( FStrEq(concept,TLK_LEAD_COMINGBACK) || FStrEq(concept, TLK_LEAD_CATCHUP) || FStrEq(concept, TLK_LEAD_RETRIEVE) ); + bool bNag = ( FStrEq(conceptId,TLK_LEAD_COMINGBACK) || FStrEq(conceptId, TLK_LEAD_CATCHUP) || FStrEq(conceptId, TLK_LEAD_RETRIEVE) ); if ( !m_hasspokenstart && bNag ) return false; @@ -1018,7 +1022,7 @@ bool CAI_LeadBehavior::Speak( AIConcept_t concept ) // We ignore nag timers for this, because the response rules will control refire rates. CAI_PlayerAlly *pAlly = dynamic_cast(GetOuter()); if ( pAlly ) - return pAlly->SpeakIfAllowed( concept, GetConceptModifiers( concept ) ); + return pAlly->SpeakIfAllowed( conceptId, GetConceptModifiers( conceptId ) ); } // Don't spam Nags @@ -1031,7 +1035,7 @@ bool CAI_LeadBehavior::Speak( AIConcept_t concept ) } } - if ( pExpresser->Speak( concept, GetConceptModifiers( concept ) ) ) + if ( pExpresser->Speak( conceptId, GetConceptModifiers( conceptId ) ) ) { m_flSpeakNextNagTime = gpGlobals->curtime + LEAD_NAG_TIME; return true; @@ -1649,6 +1653,9 @@ class CAI_LeadGoal_Weapon : public CAI_LeadGoal private: string_t m_iszWeaponName; +#ifdef MAPBASE + float m_flTimeoutTime = 60; +#endif string_t m_iszMissingWeaponConceptModifier; DECLARE_DATADESC(); @@ -1664,6 +1671,9 @@ LINK_ENTITY_TO_CLASS( ai_goal_lead_weapon, CAI_LeadGoal_Weapon ); BEGIN_DATADESC( CAI_LeadGoal_Weapon ) DEFINE_KEYFIELD( m_iszWeaponName, FIELD_STRING, "WeaponName"), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flTimeoutTime, FIELD_FLOAT, "TimeoutTime" ), +#endif DEFINE_KEYFIELD( m_iszMissingWeaponConceptModifier, FIELD_STRING, "MissingWeaponConceptModifier"), END_DATADESC() @@ -1688,6 +1698,10 @@ void CAI_LeadGoal_Weapon::InputActivate( inputdata_t &inputdata ) CAI_LeadBehavior *pBehavior = GetLeadBehavior(); if ( pBehavior ) { +#ifdef MAPBASE + pBehavior->SetWaitForWeapon( m_iszWeaponName, m_flTimeoutTime ); +#else pBehavior->SetWaitForWeapon( m_iszWeaponName ); +#endif } } diff --git a/game/server/ai_behavior_lead.h b/game/server/ai_behavior_lead.h index d59a87d3..74ea3279 100644 --- a/game/server/ai_behavior_lead.h +++ b/game/server/ai_behavior_lead.h @@ -9,12 +9,19 @@ #include "simtimer.h" #include "ai_behavior.h" +#ifdef NEW_RESPONSE_SYSTEM +#include "ai_speechconcept.h" +#endif #if defined( _WIN32 ) #pragma once #endif +#ifdef NEW_RESPONSE_SYSTEM +typedef CAI_Concept AIConcept_t; +#else typedef const char *AIConcept_t; +#endif // Speak concepts #define TLK_LEAD_START "TLK_LEAD_START" @@ -125,7 +132,11 @@ class CAI_LeadBehavior : public CAI_SimpleBehavior bool Connect( CAI_LeadBehaviorHandler *); bool Disconnect( CAI_LeadBehaviorHandler *); +#ifdef MAPBASE + void SetWaitForWeapon( string_t iszWeaponName, float flTimeout = 60 ) { m_weaponname = iszWeaponName; m_flWeaponSafetyTimeOut = gpGlobals->curtime + flTimeout; } +#else void SetWaitForWeapon( string_t iszWeaponName ) { m_weaponname = iszWeaponName; m_flWeaponSafetyTimeOut = gpGlobals->curtime + 60; } +#endif enum { @@ -184,7 +195,7 @@ class CAI_LeadBehavior : public CAI_SimpleBehavior bool GetClosestPointOnRoute( const Vector &targetPos, Vector *pVecClosestPoint ); bool PlayerIsAheadOfMe( bool bForce = false ); - bool Speak( AIConcept_t concept ); + bool Speak( AIConcept_t conceptId ); bool IsSpeaking(); // -------------------------------- diff --git a/game/server/ai_behavior_passenger.cpp b/game/server/ai_behavior_passenger.cpp index d5d4439d..9ea3d4c2 100644 --- a/game/server/ai_behavior_passenger.cpp +++ b/game/server/ai_behavior_passenger.cpp @@ -1554,12 +1554,12 @@ void CAI_PassengerBehavior::SetTransitionSequence( int nSequence ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CAI_PassengerBehavior::SpeakIfAllowed( AIConcept_t concept, const char *modifiers /*= NULL*/, bool bRespondingToPlayer /*= false*/, char *pszOutResponseChosen /*= NULL*/, size_t bufsize /*= 0*/ ) +bool CAI_PassengerBehavior::SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers /*= NULL*/, bool bRespondingToPlayer /*= false*/, char *pszOutResponseChosen /*= NULL*/, size_t bufsize /*= 0*/ ) { // FIXME: Store this cast off? CAI_PlayerAlly *pAlly = dynamic_cast(GetOuter()); if ( pAlly != NULL ) - return pAlly->SpeakIfAllowed( concept, modifiers, bRespondingToPlayer, pszOutResponseChosen, bufsize ); + return pAlly->SpeakIfAllowed( conceptId, modifiers, bRespondingToPlayer, pszOutResponseChosen, bufsize ); return false; } diff --git a/game/server/ai_behavior_passenger.h b/game/server/ai_behavior_passenger.h index 61e0d730..c47c2882 100644 --- a/game/server/ai_behavior_passenger.h +++ b/game/server/ai_behavior_passenger.h @@ -149,7 +149,7 @@ class CAI_PassengerBehavior : public CAI_SimpleBehavior virtual int SelectTransitionSchedule( void ); - bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); + bool SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); bool CanExitVehicle( void ); void SetTransitionSequence( int nSequence ); diff --git a/game/server/ai_behavior_rappel.cpp b/game/server/ai_behavior_rappel.cpp index 7dfe4e14..a9a75e91 100644 --- a/game/server/ai_behavior_rappel.cpp +++ b/game/server/ai_behavior_rappel.cpp @@ -125,6 +125,9 @@ bool CAI_RappelBehavior::KeyValue( const char *szKeyName, const char *szValue ) void CAI_RappelBehavior::Precache() { +#ifdef MAPBASE + CBaseEntity::PrecacheModel( "cable/cable_rappel.vmt" ); +#endif CBaseEntity::PrecacheModel( "cable/cable.vmt" ); } @@ -300,7 +303,14 @@ void CAI_RappelBehavior::GatherConditions() if( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { // Shoot at the enemy so long as I'm six feet or more above them. +#ifdef MAPBASE + // There seems to be an underlying issue here. COND_CAN_RANGE_ATTACK1 should not be valid without an enemy, + // but crashes have been reported from GetEnemy() returning null in this code. + Assert( GetEnemy() ); + if( GetEnemy() && (GetAbsOrigin().z - GetEnemy()->GetAbsOrigin().z >= 36.0f) && GetOuter()->GetShotRegulator()->ShouldShoot() ) +#else if( (GetAbsOrigin().z - GetEnemy()->GetAbsOrigin().z >= 36.0f) && GetOuter()->GetShotRegulator()->ShouldShoot() ) +#endif { Activity activity = GetOuter()->TranslateActivity( ACT_GESTURE_RANGE_ATTACK1 ); Assert( activity != ACT_INVALID ); @@ -386,7 +396,11 @@ void CAI_RappelBehavior::CreateZipline() if( attachment > 0 ) { CBeam *pBeam; +#ifdef MAPBASE + pBeam = CBeam::BeamCreate( "cable/cable_rappel.vmt", 1 ); +#else pBeam = CBeam::BeamCreate( "cable/cable.vmt", 1 ); +#endif pBeam->SetColor( 150, 150, 150 ); pBeam->SetWidth( 0.3 ); pBeam->SetEndWidth( 0.3 ); diff --git a/game/server/ai_behavior_standoff.cpp b/game/server/ai_behavior_standoff.cpp index 4f5f7469..00e1565b 100644 --- a/game/server/ai_behavior_standoff.cpp +++ b/game/server/ai_behavior_standoff.cpp @@ -240,6 +240,23 @@ void CAI_StandoffBehavior::SetActive( bool fActive ) { if ( fActive != m_fActive ) { +#ifdef MAPBASE + // These sentences are only spoken if the standoff behavior is active, so they have to be arranged separately + if ( fActive ) + { + m_fActive = fActive; + NotifyChangeBehaviorStatus(); + + GetOuter()->SpeakSentence( STANDOFF_SENTENCE_BEGIN_STANDOFF ); + } + else + { + GetOuter()->SpeakSentence( STANDOFF_SENTENCE_END_STANDOFF ); + + m_fActive = fActive; + NotifyChangeBehaviorStatus(); + } +#else if ( fActive ) { GetOuter()->SpeakSentence( STANDOFF_SENTENCE_BEGIN_STANDOFF ); @@ -251,6 +268,7 @@ void CAI_StandoffBehavior::SetActive( bool fActive ) m_fActive = fActive; NotifyChangeBehaviorStatus(); +#endif } } @@ -278,7 +296,12 @@ bool CAI_StandoffBehavior::CanSelectSchedule() if ( !m_fActive ) return false; +#ifdef MAPBASE + // Allow NPCs with innate range attacks to use standoffs + return ( GetNpcState() == NPC_STATE_COMBAT && (GetOuter()->GetActiveWeapon() != NULL || GetOuter()->CapabilitiesGet() & bits_CAP_INNATE_RANGE_ATTACK1) ); +#else return ( GetNpcState() == NPC_STATE_COMBAT && GetOuter()->GetActiveWeapon() != NULL ); +#endif } //------------------------------------- @@ -516,6 +539,11 @@ int CAI_StandoffBehavior::SelectScheduleCheckCover( void ) if ( GetOuter()->GetShotRegulator()->IsInRestInterval() ) { StandoffMsg( "Regulated to not shoot\n" ); +#ifdef MAPBASE + if ( GetHintType() == HINT_TACTICAL_COVER_MED || GetCoverActivity() == ACT_COVER_MED ) + SetPosture( AIP_CROUCHING_MED ); + else +#endif if ( GetHintType() == HINT_TACTICAL_COVER_LOW ) SetPosture( AIP_CROUCHING ); else @@ -535,7 +563,11 @@ int CAI_StandoffBehavior::SelectScheduleEstablishAim( void ) { if ( HasCondition( COND_ENEMY_OCCLUDED ) ) { +#if EXPANDED_HL2_COVER_ACTIVITIES + if ( GetPosture() == AIP_CROUCHING || GetPosture() == AIP_CROUCHING_MED ) +#else if ( GetPosture() == AIP_CROUCHING ) +#endif { // force a stand up, just in case GetOuter()->SpeakSentence( STANDOFF_SENTENCE_STAND_CHECK_TARGET ); @@ -573,7 +605,11 @@ int CAI_StandoffBehavior::SelectScheduleAttack( void ) !HasCondition( COND_CAN_MELEE_ATTACK1 ) && HasCondition( COND_TOO_FAR_TO_ATTACK ) ) { +#ifdef MAPBASE + if ( (GetOuter()->GetActiveWeapon() && ( GetOuter()->GetActiveWeapon()->CapabilitiesGet() & bits_CAP_WEAPON_RANGE_ATTACK1 )) || GetOuter()->CapabilitiesGet() & bits_CAP_INNATE_RANGE_ATTACK1 ) +#else if ( GetOuter()->GetActiveWeapon() && ( GetOuter()->GetActiveWeapon()->CapabilitiesGet() & bits_CAP_WEAPON_RANGE_ATTACK1 ) ) +#endif { if ( !HasCondition( COND_ENEMY_OCCLUDED ) || random->RandomInt(0,99) < 50 ) // Don't advance, just fire anyway @@ -646,6 +682,15 @@ Activity CAI_MappedActivityBehavior_Temporary::GetMappedActivity( AI_Posture_t p { if ( posture != AIP_STANDING ) { +#if EXPANDED_HL2_COVER_ACTIVITIES + // See UpdateTranslateActivityMap() for more information on what this is for + if ( posture == AIP_CROUCHING_MED ) + { + if (activity != ACT_RANGE_ATTACK1) + posture = AIP_CROUCHING; + } +#endif + unsigned short iActivityTranslation = m_ActivityMap.Find( MAKE_ACTMAP_KEY( posture, activity ) ); if ( iActivityTranslation != m_ActivityMap.InvalidIndex() ) { @@ -663,10 +708,28 @@ Activity CAI_StandoffBehavior::NPC_TranslateActivity( Activity activity ) Activity coverActivity = GetCoverActivity(); if ( coverActivity != ACT_INVALID ) { +#ifdef MAPBASE + if ( GetPosture() == AIP_STANDING ) + { + if ( coverActivity == ACT_COVER_LOW ) + SetPosture( AIP_CROUCHING ); + else if ( coverActivity == ACT_COVER_MED ) + { + SetPosture( AIP_CROUCHING_MED ); + coverActivity = ACT_COVER_LOW; + } + } + else if (coverActivity == ACT_COVER_MED) + coverActivity = ACT_COVER_LOW; + if ( activity == ACT_IDLE ) activity = coverActivity; +#else + if (activity == ACT_IDLE) + activity = coverActivity; if ( GetPosture() == AIP_STANDING && coverActivity == ACT_COVER_LOW ) SetPosture( AIP_CROUCHING ); +#endif } Activity result = GetMappedActivity( GetPosture(), activity ); @@ -1067,10 +1130,31 @@ void CAI_StandoffBehavior::UnlockHintNode() Activity CAI_StandoffBehavior::GetCoverActivity() { +#if EXPANDED_HL2_COVER_ACTIVITIES + // GetCoverActivity() already checks everything we checked here. + Activity coverActivity = GetOuter()->GetCoverActivity( GetHintNode() ); + + if (coverActivity == ACT_COVER_LOW) + { + // Check if this node will block our line of sight if aiming low. + Vector vHintPos, vHintForward, vHintRight; + GetHintNode()->GetPosition( GetHullType(), &vHintPos ); + vHintForward = GetHintNode()->GetDirection(); + + GetHintNode()->GetVectors( NULL, &vHintRight, NULL ); + if (GetOuter()->CouldShootIfCrouchingAt( vHintPos, vHintForward, vHintRight )) + { + coverActivity = ACT_COVER_MED; + } + } + + return coverActivity == ACT_IDLE ? ACT_INVALID : coverActivity; +#else CAI_Hint *pHintNode = GetHintNode(); if ( pHintNode && pHintNode->HintType() == HINT_TACTICAL_COVER_LOW ) return GetOuter()->GetCoverActivity( pHintNode ); return ACT_INVALID; +#endif } @@ -1082,6 +1166,14 @@ struct AI_ActivityMapping_t Activity activity; const char * pszWeapon; Activity translation; +#ifdef MAPBASE + Activity backup; + + AI_ActivityMapping_t( AI_Posture_t _p, Activity _a, const char *_w, Activity _t, Activity _b = ACT_INVALID ) + { + posture = _p; activity = _a; pszWeapon = _w; translation = _t; backup = _b; + } +#endif }; void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap() @@ -1095,15 +1187,60 @@ void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap() { AIP_CROUCHING, ACT_WALK_AIM, NULL, ACT_WALK_CROUCH_AIM, }, { AIP_CROUCHING, ACT_RUN_AIM, NULL, ACT_RUN_CROUCH_AIM, }, { AIP_CROUCHING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, }, +#ifdef MAPBASE + { AIP_CROUCHING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_LOW, }, + { AIP_CROUCHING, ACT_COVER_MED, NULL, ACT_COVER_LOW, }, +#else { AIP_CROUCHING, ACT_RANGE_ATTACK_SMG1, NULL, ACT_RANGE_ATTACK_SMG1_LOW, }, { AIP_CROUCHING, ACT_RANGE_ATTACK_AR2, NULL, ACT_RANGE_ATTACK_AR2_LOW, }, +#endif +#if EXPANDED_HL2_COVER_ACTIVITIES + // + // ============ Really long explanation that should be in a wiki/documentation article somewhere ~ Blixibon, 10/27/2021 ============ + // + // Standoff behavior assumes low attack animations allow NPCs to see over barricades, with ACT_COVER_LOW being their "safely in cover" animation. + // This is why AIP_CROUCHING translates ACT_RANGE_ATTACK1 to its low animation, but translates ACT_IDLE_ANGRY to ACT_COVER_LOW instead of ACT_RANGE_AIM_LOW, + // as this would ideally allow NPCs to pop in and out of cover to shoot. + // This is also why AIP_PEEKING translates ACT_COVER_LOW to ACT_RANGE_AIM_LOW, as it's supposed to force the NPC to peek over their cover. + // + // However, this assumption mainly just applies to metrocops. Citizens' low attacking animations crouch low to the ground (which isn't effective for + // shooting over most barricades) and, while they do have a distinct ACT_COVER_LOW animation with transitions, they are close enough together that popping + // in and out of cover is redundant in most cases. Meanwhile, Combine soldiers have identical ACT_COVER_LOW and ACT_RANGE_AIM_LOW animations, which means + // they do not pop in and out of cover and AIP_PEEKING does nothing. This may be the reason why Combine soldiers occasionally get stuck in cover after a fight. + // + // ------------------------------------------------------------- + // + // As part of Mapbase v7.0's NPC activity overhaul, a new "medium cover" activity set has been added. Metrocops' previous "low cover" animation set (which, as + // mentioned before, is different from that of other NPCs) has been retroactively changed to use "medium cover". This was done for a few reasons unrelated to + // standoff behavior, but the important point is that these activities indicate a new cover height. This means we can use them to give standoff behavior more leeway + // for judging which animations to use in various levels of cover. + // + // Standoff behavior can use "medium cover" animations in cover which is too high for the "low" animations, and when the medium cover animations are not available, + // it simply falls back to the "standing" animations, thus resolving the issue with other NPCs not peeking in and out of cover without requiring new medium cover + // animations. + // + // In Mapbase, this is done by changing AIP_PEEKING to use the medium cover animations and adding a new alternate crouching posture posture called "AIP_CROUCHING_MED", + // which only uses the medium cover attack activity and otherwise automatically falls back to AIP_CROUCHING. AIP_CROUCHING_MED is automatically set if the NPC cannot + // get LOS from a regular crouching position. + // + { AIP_CROUCHING_MED, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_MED, }, + + //---- + { AIP_PEEKING, ACT_IDLE, NULL, ACT_RANGE_AIM_MED, }, + { AIP_PEEKING, ACT_IDLE_ANGRY, NULL, ACT_RANGE_AIM_MED, }, + { AIP_PEEKING, ACT_COVER_LOW, NULL, ACT_RANGE_AIM_MED, ACT_IDLE_ANGRY }, + { AIP_PEEKING, ACT_COVER_MED, NULL, ACT_RANGE_AIM_MED, ACT_IDLE_ANGRY }, + { AIP_PEEKING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_MED, }, + { AIP_PEEKING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, }, +#else //---- { AIP_PEEKING, ACT_IDLE, NULL, ACT_RANGE_AIM_LOW, }, { AIP_PEEKING, ACT_IDLE_ANGRY, NULL, ACT_RANGE_AIM_LOW, }, { AIP_PEEKING, ACT_COVER_LOW, NULL, ACT_RANGE_AIM_LOW, }, { AIP_PEEKING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_LOW, }, { AIP_PEEKING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, }, +#endif }; m_ActivityMap.RemoveAll(); @@ -1114,11 +1251,24 @@ void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap() { if ( !mappings[i].pszWeapon || stricmp( mappings[i].pszWeapon, pszWeaponClass ) == 0 ) { +#ifdef MAPBASE + // Check NPC backup activity + if ( HaveSequenceForActivity( mappings[i].translation ) || HaveSequenceForActivity( GetOuter()->Weapon_TranslateActivity( mappings[i].translation ) ) || HaveSequenceForActivity( GetOuter()->Weapon_BackupActivity( mappings[i].translation ) ) ) +#else if ( HaveSequenceForActivity( mappings[i].translation ) || HaveSequenceForActivity( GetOuter()->Weapon_TranslateActivity( mappings[i].translation ) ) ) +#endif { Assert( m_ActivityMap.Find( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ) ) == m_ActivityMap.InvalidIndex() ); m_ActivityMap.Insert( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ), mappings[i].translation ); } +#ifdef MAPBASE + // Check activity map backup activity + else if ( mappings[i].backup != ACT_INVALID && HaveSequenceForActivity( mappings[i].backup ) ) + { + Assert( m_ActivityMap.Find( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ) ) == m_ActivityMap.InvalidIndex() ); + m_ActivityMap.Insert( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ), mappings[i].backup ); + } +#endif } } } diff --git a/game/server/ai_behavior_standoff.h b/game/server/ai_behavior_standoff.h index c08059e8..9141e874 100644 --- a/game/server/ai_behavior_standoff.h +++ b/game/server/ai_behavior_standoff.h @@ -51,6 +51,9 @@ enum AI_Posture_t AIP_INDIFFERENT, AIP_STANDING, AIP_CROUCHING, +#if EXPANDED_HL2_COVER_ACTIVITIES + AIP_CROUCHING_MED, // See UpdateTranslateActivityMap() for more information on what this is for +#endif AIP_PEEKING, }; @@ -149,6 +152,14 @@ class CAI_StandoffBehavior : public CAI_MappedActivityBehavior_Temporary // Standoff overrides base AI crouch handling bool IsCrouching( void ) { return false; } + +#ifdef MAPBASE + // Standoff overrides base cover activity translation + bool CanTranslateCrouchActivity( void ) { return false; } + + // Don't do death poses while crouching + bool ShouldPickADeathPose( void ) { return (GetPosture() != AIP_CROUCHING && GetPosture() != AIP_PEEKING) && BaseClass::ShouldPickADeathPose(); } +#endif private: diff --git a/game/server/ai_blended_movement.cpp b/game/server/ai_blended_movement.cpp index 7c4ba8af..0a11c915 100644 --- a/game/server/ai_blended_movement.cpp +++ b/game/server/ai_blended_movement.cpp @@ -1640,10 +1640,17 @@ void CAI_BlendedMotor::MaintainTurnActivity( void ) ConVar scene_flatturn( "scene_flatturn", "1" ); +#ifdef MAPBASE +ConVar ai_turning_enabled( "ai_turning_enabled", "1", FCVAR_NONE, "Enables NPC turning, which was previously disabled by Valve at some point after 2004 due to a now-unknown major issue." ); +#endif + bool CAI_BlendedMotor::AddTurnGesture( float flYD ) { // some funky bug with human turn gestures, disable for now +#ifdef MAPBASE + if (!ai_turning_enabled.GetBool()) +#endif return false; // try using a turn gesture @@ -1864,7 +1871,7 @@ float ChangeDistance( float flInterval, float flGoalDistance, float flGoalVeloci // I need to speed up flNewVelocity = flCurVelocity + flGoalAccel * flInterval; if (flNewVelocity > flGoalVelocity) - flNewVelocity = flGoalVelocity; + flGoalVelocity = flGoalVelocity; } else if (flNewVelocity < flIdealVelocity) { diff --git a/game/server/ai_concommands.cpp b/game/server/ai_concommands.cpp index 8c647f55..e004dca1 100644 --- a/game/server/ai_concommands.cpp +++ b/game/server/ai_concommands.cpp @@ -390,6 +390,152 @@ void CC_NPC_Focus( const CCommand &args ) static ConCommand npc_focus("npc_focus", CC_NPC_Focus, "Displays red line to NPC's enemy (if has one) and blue line to NPC's target entity (if has one)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at", FCVAR_CHEAT); ConVar npc_create_equipment("npc_create_equipment", ""); + +#ifdef MAPBASE +extern int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 ); +extern bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ); + +//------------------------------------------------------------------------------ +// Purpose: Create an NPC of the given type +//------------------------------------------------------------------------------ +class CNPCCreateAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback +{ +public: + virtual bool CreateAimed() { return false; } + + virtual void CommandCallback( const CCommand &args ) + { + MDLCACHE_CRITICAL_SECTION(); + + bool allowPrecache = CBaseEntity::IsPrecacheAllowed(); + CBaseEntity::SetAllowPrecache( true ); + + // Try to create entity + CAI_BaseNPC *baseNPC = dynamic_cast< CAI_BaseNPC * >( CreateEntityByName(args[1]) ); + if (baseNPC) + { + baseNPC->KeyValue( "additionalequipment", npc_create_equipment.GetString() ); + + if ( args.ArgC() == 3 ) + { + baseNPC->SetName( AllocPooledString( args[2] ) ); + } + else if ( args.ArgC() > 3 ) + { + baseNPC->SetName( AllocPooledString( args[2] ) ); + + // Pass in any additional parameters. + for ( int i = 3; i + 1 < args.ArgC(); i += 2 ) + { + const char *pKeyName = args[i]; + const char *pValue = args[i+1]; + baseNPC->KeyValue( pKeyName, pValue ); + } + } + + DispatchSpawn(baseNPC); + + // Now attempt to drop into the world + CBasePlayer* pPlayer = UTIL_GetCommandClient(); + trace_t tr; + Vector forward; + QAngle angles; + pPlayer->EyeVectors( &forward ); + + bool bCreateAimed = CreateAimed(); + if (bCreateAimed) + { + VectorAngles( forward, angles ); + angles.x = 0; + angles.z = 0; + } + + // Pass through the player's vehicle + CTraceFilterSkipTwoEntities filter( pPlayer, pPlayer->GetVehicleEntity(), COLLISION_GROUP_NONE ); + AI_TraceLine(pPlayer->EyePosition(), + pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID, + &filter, &tr ); + + if ( tr.fraction != 1.0) + { + if (baseNPC->CapabilitiesGet() & bits_CAP_MOVE_FLY) + { + Vector pos = tr.endpos - forward * 36; + baseNPC->Teleport( &pos, bCreateAimed ? &angles : NULL, NULL ); + } + else + { + // Raise the end position a little up off the floor, place the npc and drop him down + tr.endpos.z += 12; + baseNPC->Teleport( &tr.endpos, bCreateAimed ? &angles : NULL, NULL ); + UTIL_DropToFloor( baseNPC, MASK_NPCSOLID ); + } + + // Now check that this is a valid location for the new npc to be + Vector vUpBit = baseNPC->GetAbsOrigin(); + vUpBit.z += 1; + + AI_TraceHull( baseNPC->GetAbsOrigin(), vUpBit, baseNPC->GetHullMins(), baseNPC->GetHullMaxs(), + MASK_NPCSOLID, baseNPC, COLLISION_GROUP_NONE, &tr ); + if ( tr.startsolid || (tr.fraction < 1.0) ) + { + baseNPC->SUB_Remove(); + DevMsg("Can't create %s. Bad Position!\n",args[1]); + NDebugOverlay::Box(baseNPC->GetAbsOrigin(), baseNPC->GetHullMins(), baseNPC->GetHullMaxs(), 255, 0, 0, 0, 0); + } + } + else if (bCreateAimed) + { + baseNPC->Teleport( NULL, &angles, NULL ); + } + + baseNPC->Activate(); + } + CBaseEntity::SetAllowPrecache( allowPrecache ); + } + + virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) + { + if ( !g_pGameRules ) + { + return 0; + } + + const char *cmdname = CreateAimed() ? "npc_create_aimed" : "npc_create"; + + char *substring = (char *)partial; + if ( Q_strstr( partial, cmdname ) ) + { + substring = (char *)partial + strlen( cmdname ) + 1; + } + + int checklen = Q_strlen( substring ); + + if (checklen <= 0) + { + // Only show classnames prefixed with "npc" unless the user starts typing other characters + substring = "npc"; + checklen = 3; + } + + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return EntityFactory_AutoComplete( cmdname, commands, symbols, substring, checklen ); + } +}; + +static CNPCCreateAutoCompletionFunctor g_NPCCreateAutoComplete; +static ConCommand npc_create("npc_create", &g_NPCCreateAutoComplete, "Creates an NPC of the given type where the player is looking (if the given NPC can actually stand at that location).\n\tArguments: {npc_class_name}", FCVAR_CHEAT, &g_NPCCreateAutoComplete); + +class CNPCCreateAimedAutoCompletionFunctor : public CNPCCreateAutoCompletionFunctor +{ +public: + virtual bool CreateAimed() { return true; } +}; + +static CNPCCreateAimedAutoCompletionFunctor g_NPCCreateAimedAutoComplete; + +static ConCommand npc_create_aimed("npc_create_aimed", &g_NPCCreateAimedAutoComplete, "Creates an NPC aimed away from the player of the given type where the player is looking (if the given NPC can actually stand at that location).\n\tArguments: {npc_class_name}", FCVAR_CHEAT, &g_NPCCreateAimedAutoComplete); +#else //------------------------------------------------------------------------------ // Purpose: Create an NPC of the given type //------------------------------------------------------------------------------ @@ -411,6 +557,20 @@ void CC_NPC_Create( const CCommand &args ) { baseNPC->SetName( AllocPooledString( args[2] ) ); } +#ifdef MAPBASE + else if ( args.ArgC() > 3 ) + { + baseNPC->SetName( AllocPooledString( args[2] ) ); + + // Pass in any additional parameters. + for ( int i = 3; i + 1 < args.ArgC(); i += 2 ) + { + const char *pKeyName = args[i]; + const char *pValue = args[i+1]; + baseNPC->KeyValue( pKeyName, pValue ); + } + } +#endif DispatchSpawn(baseNPC); // Now attempt to drop into the world @@ -526,6 +686,7 @@ void CC_NPC_Create_Aimed( const CCommand &args ) CBaseEntity::SetAllowPrecache( allowPrecache ); } static ConCommand npc_create_aimed("npc_create_aimed", CC_NPC_Create_Aimed, "Creates an NPC aimed away from the player of the given type where the player is looking (if the given NPC can actually stand at that location). Note that this only works for npc classes that are already in the world. You can not create an entity that doesn't have an instance in the level.\n\tArguments: {npc_class_name}", FCVAR_CHEAT); +#endif //------------------------------------------------------------------------------ // Purpose: Destroy unselected NPCs @@ -697,6 +858,134 @@ void CC_NPC_Reset( void ) } static ConCommand npc_reset("npc_reset", CC_NPC_Reset, "Reloads schedules for all NPC's from their script files\n\tArguments: -none-", FCVAR_CHEAT); +#ifdef MAPBASE +extern bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ); + +//------------------------------------------------------------------------------ +// Purpose : Auto-completes with entities in the entity list, but only uses NPC-derived entities. +// Input : cmdname - The name of the command. +// &commands - Where the complete autocompletes should be sent to. +// substring - The current search query. (only pool entities that start with this) +// checklen - The number of characters to check. +// Output : A pointer to a cUtlRBTRee containing all of the entities. +//------------------------------------------------------------------------------ +static int AutoCompleteNPCs(const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0) +{ + CBaseEntity *pos = NULL; + while ((pos = gEntList.NextEnt(pos)) != NULL) + { + if (!pos->IsNPC()) + continue; + + const char *name = pos->GetClassname(); + if (pos->GetEntityName() == NULL_STRING || Q_strnicmp(STRING(pos->GetEntityName()), substring, checklen)) + { + if (Q_strnicmp(pos->GetClassname(), substring, checklen)) + continue; + } + else + name = STRING(pos->GetEntityName()); + + CUtlString sym = name; + int idx = symbols.Find(sym); + if (idx == symbols.InvalidIndex()) + { + symbols.Insert(sym); + } + + // Too many + if (symbols.Count() >= COMMAND_COMPLETION_MAXITEMS) + break; + } + + // Now fill in the results + for (int i = symbols.FirstInorder(); i != symbols.InvalidIndex(); i = symbols.NextInorder(i)) + { + const char *name = symbols[i].String(); + + char buf[512]; + Q_strncpy(buf, name, sizeof(buf)); + Q_strlower(buf); + + CUtlString command; + command = CFmtStr("%s %s", cmdname, buf); + commands.AddToTail(command); + } + + return symbols.Count(); +} + +//------------------------------------------------------------------------------ +// There's a big set of NPC debug commands that do similar operations and +// can fall under this base class for auto-completion, etc. +//------------------------------------------------------------------------------ +class CNPCDebugAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback +{ +public: + virtual const char *CommandName() { return NULL; } + virtual void CommandCallback( const CCommand &args ) + { + SetDebugBits( UTIL_GetCommandClient(), args[1], OVERLAY_NPC_NEAREST_BIT ); + } + + virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) + { + if ( !g_pGameRules ) + { + return 0; + } + + const char *cmdname = CommandName(); + + char *substring = (char *)partial; + if ( Q_strstr( partial, cmdname ) ) + { + substring = (char *)partial + strlen( cmdname ) + 1; + } + + int checklen = Q_strlen( substring ); + + if (checklen == 0 || atoi(substring) != 0) + { + // Must be the picker or an entity index + return 0; + } + + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return AutoCompleteNPCs(cmdname, commands, symbols, substring, checklen); + } +}; + +#define NPCDebugCommand(name, functor, bit, help) class CNPC##functor##AutoCompletionFunctor : public CNPCDebugAutoCompletionFunctor \ +{ \ +public: \ + virtual const char *CommandName() { return #name; } \ + virtual void CommandCallback( const CCommand &args ) \ + { \ + SetDebugBits( UTIL_GetCommandClient(), args[1], bit ); \ + } \ +}; \ +static CNPC##functor##AutoCompletionFunctor g_NPC##functor##AutoCompletionFunctor; \ +static ConCommand name(#name, &g_NPC##functor##AutoCompletionFunctor, help, FCVAR_CHEAT, &g_NPC##functor##AutoCompletionFunctor); + +NPCDebugCommand( npc_nearest, Nearest, OVERLAY_NPC_NEAREST_BIT, "Draw's a while box around the NPC(s) nearest node\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at " ); +NPCDebugCommand( npc_route, Route, OVERLAY_NPC_ROUTE_BIT, "Displays the current route of the given NPC as a line on the screen. Waypoints along the route are drawn as small cyan rectangles. Line is color coded in the following manner:\n\tBlue - path to a node\n\tCyan - detour around an object (triangulation)\n\tRed - jump\n\tMaroon - path to final target position\n\tArguments: {npc_name} / {npc_class_name} / no argument picks what player is looking at " ); +NPCDebugCommand( npc_select, Select, OVERLAY_NPC_SELECTED_BIT, "Select or deselects the given NPC(s) for later manipulation. Selected NPC's are shown surrounded by a red translucent box\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at " ); +NPCDebugCommand( npc_combat, Combat, OVERLAY_NPC_SQUAD_BIT, "Displays text debugging information about the squad and enemy of the selected NPC (See Overlay Text)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at" ); +NPCDebugCommand( npc_tasks, Tasks, OVERLAY_NPC_TASK_BIT, "Displays detailed text debugging information about the all the tasks of the selected NPC current schedule (See Overlay Text)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at " ); +NPCDebugCommand( npc_task_text, TaskText, OVERLAY_TASK_TEXT_BIT, "Outputs text debugging information to the console about the all the tasks + break conditions of the selected NPC current schedule\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at " ); +NPCDebugCommand( npc_conditions, Conditions, OVERLAY_NPC_CONDITIONS_BIT, "Displays all the current AI conditions that an NPC has in the overlay text.\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at" ); +NPCDebugCommand( npc_viewcone, Viewcone, OVERLAY_NPC_VIEWCONE_BIT, "Displays the viewcone of the NPC (where they are currently looking and what the extents of there vision is)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" ); +NPCDebugCommand( npc_relationships, Relationships, OVERLAY_NPC_RELATION_BIT, "Displays the relationships between this NPC and all others.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" ); +NPCDebugCommand( npc_steering, Steering, OVERLAY_NPC_STEERING_REGULATIONS, "Displays the steering obstructions of the NPC( used to perform local avoidance )\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" ); + +// For backwards compatibility +void CC_NPC_Squads( const CCommand &args ) +{ + SetDebugBits( UTIL_GetCommandClient(),args[1],OVERLAY_NPC_SQUAD_BIT); +} +static ConCommand npc_squads("npc_squads", CC_NPC_Squads, "Obsolete. Replaced by npc_combat", FCVAR_CHEAT); +#else //------------------------------------------------------------------------------ // Purpose: Show the selected NPC's nearest node //------------------------------------------------------------------------------ @@ -791,6 +1080,7 @@ void CC_NPC_ViewSteeringRegulations( const CCommand &args ) SetDebugBits( UTIL_GetCommandClient(), args[1], OVERLAY_NPC_STEERING_REGULATIONS); } static ConCommand npc_steering("npc_steering", CC_NPC_ViewSteeringRegulations, "Displays the steering obstructions of the NPC (used to perform local avoidance)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT); +#endif void CC_NPC_ViewSteeringRegulationsAll( void ) { diff --git a/game/server/ai_debug.h b/game/server/ai_debug.h index 3f5c47fb..8a438d70 100644 --- a/game/server/ai_debug.h +++ b/game/server/ai_debug.h @@ -51,8 +51,8 @@ enum AIMsgFlags AIMF_IGNORE_SELECTED = 0x01 }; -void DevMsg( CAI_BaseNPC *pAI, unsigned flags, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION( 3, 4 ); -void DevMsg( CAI_BaseNPC *pAI, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION( 2, 3 ); +void DevMsg( CAI_BaseNPC *pAI, unsigned flags, PRINTF_FORMAT_STRING const char *pszFormat, ... ); +void DevMsg( CAI_BaseNPC *pAI, PRINTF_FORMAT_STRING const char *pszFormat, ... ); //----------------------------------------------------------------------------- diff --git a/game/server/ai_default.cpp b/game/server/ai_default.cpp index 5d2319c9..8f660ec3 100644 --- a/game/server/ai_default.cpp +++ b/game/server/ai_default.cpp @@ -155,10 +155,6 @@ void CAI_BaseNPC::InitDefaultScheduleSR(void) ADD_DEF_SCHEDULE( "SCHED_INTERACTION_WAIT_FOR_PARTNER", SCHED_INTERACTION_WAIT_FOR_PARTNER ); ADD_DEF_SCHEDULE( "SCHED_SLEEP", SCHED_SLEEP ); - -#ifdef VANCE - ADD_DEF_SCHEDULE( "SCHED_FIRE_AND_RELOAD", SCHED_FIRE_AND_RELOAD ); -#endif } bool CAI_BaseNPC::LoadDefaultSchedules(void) @@ -251,10 +247,6 @@ bool CAI_BaseNPC::LoadDefaultSchedules(void) AI_LOAD_DEF_SCHEDULE( CAI_BaseNPC, SCHED_INTERACTION_WAIT_FOR_PARTNER); AI_LOAD_DEF_SCHEDULE( CAI_BaseNPC, SCHED_SLEEP ); -#ifdef VANCE - AI_LOAD_DEF_SCHEDULE( CAI_BaseNPC, SCHED_FIRE_AND_RELOAD ); -#endif - return true; } @@ -382,6 +374,10 @@ int CAI_BaseNPC::TranslateSchedule( int scheduleType ) return scheduleType; } +#ifdef MAPBASE +extern ScriptHook_t g_Hook_TranslateSchedule; +#endif + //========================================================= // GetScheduleOfType - returns a pointer to one of the // NPC's available schedules of the indicated type. @@ -394,6 +390,35 @@ CAI_Schedule *CAI_BaseNPC::GetScheduleOfType( int scheduleType ) scheduleType = TranslateSchedule( scheduleType ); AI_PROFILE_SCOPE_END(); +#ifdef MAPBASE_VSCRIPT + if ( m_ScriptScope.IsInitialized() && g_Hook_TranslateSchedule.CanRunInScope(m_ScriptScope) ) + { + int newSchedule = scheduleType; + if ( AI_IdIsLocal( newSchedule ) ) + { + newSchedule = GetClassScheduleIdSpace()->ScheduleLocalToGlobal(newSchedule); + } + + // schedule, schedule_id (local ID) + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { GetSchedulingSymbols()->ScheduleIdToSymbol( newSchedule ), scheduleType }; + if (g_Hook_TranslateSchedule.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_INTEGER) + { + newSchedule = functionReturn.m_int; + } + else + { + newSchedule = GetScheduleID( functionReturn.m_pszString ); + } + + if (newSchedule != scheduleType && newSchedule > -1) + scheduleType = newSchedule; + } + } +#endif + // Get a pointer to that schedule CAI_Schedule *schedule = GetSchedule(scheduleType); @@ -1125,47 +1150,9 @@ AI_DEFINE_SCHEDULE " Interrupts" ); -#ifdef VANCE -AI_DEFINE_SCHEDULE -( - SCHED_FIRE_AND_RELOAD, - - " Tasks" - " TASK_STOP_MOVING 0" - " TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_RELOAD" - " TASK_FIND_COVER_FROM_ENEMY 0" - " TASK_RUN_PATH 0" - " TASK_WAIT_FOR_MOVEMENT 0" - " TASK_REMEMBER MEMORY:INCOVER" - " TASK_FACE_ENEMY 0" - "" - " Interrupts" - " COND_HEAR_DANGER" -); -#endif - //========================================================= // SCHED_HIDE_AND_RELOAD //========================================================= -#ifdef VANCE_NEW_AI -AI_DEFINE_SCHEDULE -( - SCHED_HIDE_AND_RELOAD, - - " Tasks" - " TASK_STOP_MOVING 0" - " TASK_RELOAD 0" - " TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_RELOAD" - " TASK_FIND_COVER_FROM_ENEMY 0" - " TASK_RUN_PATH 0" - " TASK_WAIT_FOR_MOVEMENT 0" - " TASK_REMEMBER MEMORY:INCOVER" - " TASK_FACE_ENEMY 0" - "" - " Interrupts" - " COND_HEAR_DANGER" -); -#else AI_DEFINE_SCHEDULE ( SCHED_HIDE_AND_RELOAD, @@ -1183,24 +1170,10 @@ AI_DEFINE_SCHEDULE " Interrupts" " COND_HEAR_DANGER" ); -#endif //========================================================= // > Reload //========================================================= -#ifdef VANCE_NEW_AI -AI_DEFINE_SCHEDULE -( - SCHED_RELOAD, - - " Tasks" - " TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_HIDE_AND_RELOAD" - " TASK_RELOAD 0" - "" - " Interrupts" - " COND_HEAR_DANGER" -); -#else AI_DEFINE_SCHEDULE ( SCHED_RELOAD, @@ -1212,7 +1185,6 @@ AI_DEFINE_SCHEDULE " Interrupts" " COND_HEAR_DANGER" ); -#endif //========================================================= // > Melee_Attack1 @@ -1835,6 +1807,24 @@ AI_DEFINE_SCHEDULE // Run to cover, but don't turn to face enemy and upon // fail run around randomly //========================================================= +#ifdef MAPBASE +AI_DEFINE_SCHEDULE +( + SCHED_RUN_FROM_ENEMY, + + " Tasks" + " TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_RUN_FROM_ENEMY_FALLBACK" + " TASK_STOP_MOVING 0" + " TASK_FIND_COVER_FROM_ENEMY 0" + " TASK_RUN_PATH 0" + " TASK_WAIT_FOR_MOVEMENT 0" + " TASK_REMEMBER MEMORY:INCOVER" // Now that crouch nodes are fixed, this is necessary in case cover leads to a crouch node + "" + " Interrupts" + " COND_NEW_ENEMY" + " COND_ENEMY_DEAD" +); +#else AI_DEFINE_SCHEDULE ( SCHED_RUN_FROM_ENEMY, @@ -1850,6 +1840,7 @@ AI_DEFINE_SCHEDULE " COND_NEW_ENEMY" " COND_ENEMY_DEAD" ); +#endif AI_DEFINE_SCHEDULE ( @@ -2412,6 +2403,19 @@ AI_DEFINE_SCHEDULE //========================================================= // > SCHED_INTERACTION_WAIT_FOR_PARTNER //========================================================= +#ifdef MAPBASE +AI_DEFINE_SCHEDULE +( + SCHED_INTERACTION_WAIT_FOR_PARTNER, + + " Tasks" + " TASK_FACE_INTERACTION_ANGLES 0" // New task to fix forced interaction anomalies + " TASK_WAIT 1" + "" + " Interrupts" + " COND_NO_CUSTOM_INTERRUPTS" +); +#else AI_DEFINE_SCHEDULE ( SCHED_INTERACTION_WAIT_FOR_PARTNER, @@ -2423,6 +2427,7 @@ AI_DEFINE_SCHEDULE " Interrupts" " COND_NO_CUSTOM_INTERRUPTS" ); +#endif //========================================================= // > SCHED_SLEEP diff --git a/game/server/ai_default.h b/game/server/ai_default.h index d75ccb21..662dd45f 100644 --- a/game/server/ai_default.h +++ b/game/server/ai_default.h @@ -111,8 +111,6 @@ enum SCHED_SLEEP, - SCHED_FIRE_AND_RELOAD, - // ====================================== // IMPORTANT: This must be the last enum // ====================================== diff --git a/game/server/ai_dynamiclink.cpp b/game/server/ai_dynamiclink.cpp index 5f5fba9c..a08402e8 100644 --- a/game/server/ai_dynamiclink.cpp +++ b/game/server/ai_dynamiclink.cpp @@ -15,6 +15,14 @@ #include "ai_link.h" #include "ai_network.h" #include "ai_networkmanager.h" +#ifdef MAPBASE +#include "ai_hint.h" +#include "ai_basenpc.h" +#include "filters.h" +#include "point_template.h" +#include "TemplateEntities.h" +#include "mapentities.h" +#endif #include "saverestore_utlvector.h" #include "editor_sendcommand.h" #include "bitstring.h" @@ -169,6 +177,156 @@ void CAI_DynamicLinkController::InputSetInvert( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//============================================================================= +// >> CAI_CustomLinkController +// Uses the specified link class +//============================================================================= +class CAI_CustomLinkController : public CAI_DynamicLinkController +{ + DECLARE_CLASS( CAI_CustomLinkController, CAI_DynamicLinkController ); +public: + CAI_CustomLinkController(); + + void GenerateLinksFromVolume(); + int GetReferenceLinkIndex(); + + string_t m_iszReferenceLinkTemplate; + int m_iReferenceLink; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(info_template_link_controller, CAI_CustomLinkController); + +BEGIN_DATADESC( CAI_CustomLinkController ) + + DEFINE_KEYFIELD( m_iszReferenceLinkTemplate, FIELD_STRING, "ReferenceTemplate" ), + //DEFINE_FIELD( m_iReferenceLink, FIELD_INTEGER ), // I don't know if this should be saved. It's only a cached variable, so not saving it shouldn't hurt anything. + +END_DATADESC() + +CAI_CustomLinkController::CAI_CustomLinkController() +{ + m_iReferenceLink = -1; +} + +int CAI_CustomLinkController::GetReferenceLinkIndex() +{ + if (m_iReferenceLink != -1) + return m_iReferenceLink; + + CBaseEntity *pEnt = gEntList.FindEntityByName(NULL, STRING(m_iszReferenceLinkTemplate), this); + if (CPointTemplate *pTemplate = dynamic_cast(pEnt)) + { + Assert(pTemplate->GetTemplateEntity(0)); + + m_iReferenceLink = pTemplate->GetTemplateIndexForTemplate(0); + return m_iReferenceLink; + } + + return -1; +} + +void CAI_CustomLinkController::GenerateLinksFromVolume() +{ + Assert( m_ControlledLinks.Count() == 0 ); + + int nNodes = g_pBigAINet->NumNodes(); + CAI_Node **ppNodes = g_pBigAINet->AccessNodes(); + + float MinDistCareSq = 0; + if (m_bUseAirLinkRadius) + { + MinDistCareSq = Square(MAX_AIR_NODE_LINK_DIST + 0.1); + } + else + { + MinDistCareSq = Square(MAX_NODE_LINK_DIST + 0.1); + } + + const Vector &origin = WorldSpaceCenter(); + Vector vAbsMins, vAbsMaxs; + CollisionProp()->WorldSpaceAABB( &vAbsMins, &vAbsMaxs ); + vAbsMins -= Vector( 1, 1, 1 ); + vAbsMaxs += Vector( 1, 1, 1 ); + + int iReference = GetReferenceLinkIndex(); + if (iReference == -1) + { + Warning("WARNING! %s reference link is invalid!\n", GetDebugName()); + return; + } + + // Get the map data before the loop + char *pMapData = (char*)STRING( Templates_FindByIndex( iReference ) ); + + // Make sure the entity is a dynamic link before doing anything + CBaseEntity *pEntity = NULL; + MapEntity_ParseEntity( pEntity, pMapData, NULL ); + if ( !dynamic_cast(pEntity) ) + { + Warning("WARNING! %s reference link is not a node link!\n", GetDebugName()); + UTIL_RemoveImmediate(pEntity); + return; + } + + UTIL_RemoveImmediate(pEntity); + + for ( int i = 0; i < nNodes; i++ ) + { + CAI_Node *pNode = ppNodes[i]; + const Vector &nodeOrigin = pNode->GetOrigin(); + if ( origin.DistToSqr(nodeOrigin) < MinDistCareSq ) + { + int nLinks = pNode->NumLinks(); + for ( int j = 0; j < nLinks; j++ ) + { + CAI_Link *pLink = pNode->GetLinkByIndex( j ); + int iLinkDest = pLink->DestNodeID( i ); + if ( iLinkDest > i ) + { + const Vector &originOther = ppNodes[iLinkDest]->GetOrigin(); + if ( origin.DistToSqr(originOther) < MinDistCareSq ) + { + if ( IsBoxIntersectingRay( vAbsMins, vAbsMaxs, nodeOrigin, originOther - nodeOrigin ) ) + { + Assert( IsBoxIntersectingRay( vAbsMins, vAbsMaxs, originOther, nodeOrigin - originOther ) ); + + CBaseEntity *pEntity = NULL; + + // Create the entity from the mapdata + MapEntity_ParseEntity( pEntity, pMapData, NULL ); + if ( pEntity == NULL ) + { + Msg("%s failed to initialize templated link with mapdata: %s\n", GetDebugName(), pMapData ); + return; + } + + // We already made sure it was an info_node_link template earlier. + CAI_DynamicLink *pLink = static_cast(pEntity); + + pLink->m_nSrcID = i; + pLink->m_nDestID = iLinkDest; + pLink->m_nSrcEditID = g_pAINetworkManager->GetEditOps()->GetWCIdFromNodeId( pLink->m_nSrcID ); + pLink->m_nDestEditID = g_pAINetworkManager->GetEditOps()->GetWCIdFromNodeId( pLink->m_nDestID ); + pLink->m_nLinkState = m_nLinkState; + pLink->m_strAllowUse = m_strAllowUse; + pLink->m_bInvertAllow = m_bInvertAllow; + pLink->m_bFixedUpIds = true; + pLink->m_bNotSaved = true; + + pLink->Spawn(); + m_ControlledLinks.AddToTail( pLink ); + } + } + } + } + } + } +} +#endif + //----------------------------------------------------------------------------- LINK_ENTITY_TO_CLASS(info_node_link, CAI_DynamicLink); @@ -579,6 +737,242 @@ CAI_DynamicLink::~CAI_DynamicLink(void) { } } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose : Determines if usage is allowed by a NPC, whether the link is disabled or not. +// This was created for info_node_link derivatives. +// Input : +// Output : +//------------------------------------------------------------------------------ +bool CAI_DynamicLink::UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) +{ + if (!(FindLink()->m_LinkInfo & bits_LINK_OFF)) + return true; + + if ( m_strAllowUse == NULL_STRING ) + return false; + + const char *pszAllowUse = STRING( m_strAllowUse ); + if ( m_bInvertAllow ) + { + // Exlude only the specified entity name or classname + if ( !pNPC->NameMatches(pszAllowUse) && !pNPC->ClassMatches( pszAllowUse ) ) + return true; + } + else + { + // Exclude everything but the allowed entity name or classname + if ( pNPC->NameMatches( pszAllowUse) || pNPC->ClassMatches( pszAllowUse ) ) + return true; + } + + return false; +} + +//============================================================================= +// >> CAI_DynanicLinkOneWay +//============================================================================= +class CAI_DynamicLinkOneWay : public CAI_DynamicLink +{ + DECLARE_CLASS( CAI_DynamicLinkOneWay, CAI_DynamicLink ); +public: + virtual bool UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd); + //virtual void SetLinkState( void ); + + bool m_bNormalWhenEnabled; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(info_node_link_oneway, CAI_DynamicLinkOneWay); + +BEGIN_DATADESC( CAI_DynamicLinkOneWay ) + + DEFINE_KEYFIELD( m_bNormalWhenEnabled, FIELD_BOOLEAN, "Usage" ), + +END_DATADESC() + +//------------------------------------------------------------------------------ +// Purpose : Determines if usage is allowed by a NPC. +// This was created for info_node_link derivatives. +// Input : +// Output : +//------------------------------------------------------------------------------ +bool CAI_DynamicLinkOneWay::UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) +{ + if (m_bNormalWhenEnabled) + return (m_nLinkState == LINK_OFF && bFromEnd) ? BaseClass::UseAllowed(pNPC, bFromEnd) : true; + + if (bFromEnd || m_nLinkState == LINK_OFF) + return BaseClass::UseAllowed(pNPC, bFromEnd); + + return true; +} + +#if 0 +//------------------------------------------------------------------------------ +// Purpose : Updates network link state if dynamic link state has changed +// Input : +// Output : +//------------------------------------------------------------------------------ +void CAI_DynamicLinkOneWay::SetLinkState(void) +{ + if (m_bNormalWhenEnabled) + return BaseClass::SetLinkState(); + + if ( !gm_bInitialized ) + { + // Safe to quietly return. Consistency will be enforced when InitDynamicLinks() is called + return; + } + + if (m_nSrcID == NO_NODE || m_nDestID == NO_NODE) + { + Vector pos = GetAbsOrigin(); + DevWarning("ERROR: Dynamic link at %f %f %f pointing to invalid node ID!!\n", pos.x, pos.y, pos.z); + return; + } + + CAI_Node * pSrcNode = g_pBigAINet->GetNode(m_nSrcID, false); + if ( pSrcNode ) + { + CAI_Link* pLink = FindLink(); + if ( pLink ) + { + // One-way always registers as off so it always calls UseAllowed() + pLink->m_pDynamicLink = this; + pLink->m_LinkInfo |= bits_LINK_OFF; + } + else + { + DevMsg("Dynamic Link Error: (%s) unable to form between nodes %d and %d\n", GetDebugName(), m_nSrcID, m_nDestID ); + } + } +} +#endif + +//============================================================================= +// >> CAI_DynamicLinkFilter +//============================================================================= +class CAI_DynamicLinkFilter : public CAI_DynamicLink +{ + DECLARE_CLASS( CAI_DynamicLinkFilter, CAI_DynamicLink ); +public: + virtual bool UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd); + //virtual void SetLinkState( void ); + + bool m_bNormalWhenEnabled; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(info_node_link_filtered, CAI_DynamicLinkFilter); + +BEGIN_DATADESC( CAI_DynamicLinkFilter ) + + DEFINE_KEYFIELD( m_bNormalWhenEnabled, FIELD_BOOLEAN, "Usage" ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetLinkFilter", InputSetDamageFilter ), + +END_DATADESC() + +//------------------------------------------------------------------------------ +// Purpose : Determines if usage is allowed by a NPC. +// This was created for info_node_link derivatives. +// Input : +// Output : +//------------------------------------------------------------------------------ +bool CAI_DynamicLinkFilter::UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) +{ + if ( !m_hDamageFilter ) + { + m_hDamageFilter = gEntList.FindEntityByName( NULL, m_iszDamageFilterName ); + if (!m_hDamageFilter) + { + Warning("%s (%s) couldn't find filter \"%s\"!\n", GetClassname(), GetDebugName(), STRING(m_iszDamageFilterName)); + return BaseClass::UseAllowed(pNPC, bFromEnd); + } + } + + CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); + + if (m_bNormalWhenEnabled) + return (m_nLinkState == LINK_OFF) ? (pFilter->PassesFilter(this, pNPC) || BaseClass::UseAllowed(pNPC, bFromEnd)) : true; + + if (m_nLinkState == LINK_OFF) + return BaseClass::UseAllowed(pNPC, bFromEnd); + + return pFilter->PassesFilter(this, pNPC); +} + +//============================================================================= +// >> CAI_DynamicLinkLogic +//============================================================================= +class CAI_DynamicLinkLogic : public CAI_DynamicLink +{ + DECLARE_CLASS( CAI_DynamicLinkLogic, CAI_DynamicLink ); +public: + virtual bool UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd); + virtual bool FinalUseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd); + + COutputEvent m_OnUsageAccepted; + COutputEvent m_OnUsageAcceptedWhileDisabled; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(info_node_link_logic, CAI_DynamicLinkLogic); + +BEGIN_DATADESC( CAI_DynamicLinkLogic ) + + DEFINE_OUTPUT( m_OnUsageAccepted, "OnUsageAccepted" ), + DEFINE_OUTPUT( m_OnUsageAcceptedWhileDisabled, "OnUsageAcceptedWhileDisabled" ), + +END_DATADESC() + +//------------------------------------------------------------------------------ +// Purpose : Determines if usage is allowed by a NPC. +// This was created for info_node_link derivatives. +// Input : +// Output : +//------------------------------------------------------------------------------ +bool CAI_DynamicLinkLogic::UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) +{ + // + // If the link is off, we want to fire "OnUsageAcceptedWhileDisabled", but we have to make sure + // the rest of the pathfinding calculations work. Yes, they might do all of this just to find a disabled link, + // but we have to fire the output somehow. + // + // Links already enabled go through regular usage rules. + // + if (m_nLinkState == LINK_OFF) + return true; + else + return BaseClass::UseAllowed( pNPC, bFromEnd ); +} + +//------------------------------------------------------------------------------ +// Purpose : After nothing else is left, finally determines if usage is allowed by a NPC. +// This was created for info_node_link derivatives. +// Input : +// Output : +//------------------------------------------------------------------------------ +bool CAI_DynamicLinkLogic::FinalUseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) +{ + if (m_nLinkState == LINK_ON) + { + m_OnUsageAccepted.FireOutput(pNPC, this); + return true; + } + else + { + m_OnUsageAcceptedWhileDisabled.FireOutput(pNPC, this); + + // We skipped the usage rules before. Do them now. + return BaseClass::UseAllowed(pNPC, bFromEnd); + } +} +#endif + LINK_ENTITY_TO_CLASS(info_radial_link_controller, CAI_RadialLinkController); BEGIN_DATADESC( CAI_RadialLinkController ) diff --git a/game/server/ai_dynamiclink.h b/game/server/ai_dynamiclink.h index cefec66c..971df96a 100644 --- a/game/server/ai_dynamiclink.h +++ b/game/server/ai_dynamiclink.h @@ -65,6 +65,13 @@ class CAI_DynamicLink : public CServerOnlyEntity int ObjectCaps(); +#ifdef MAPBASE + virtual bool UseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd); + + // Called after we know the NPC meets all of the node's criteria + virtual bool FinalUseAllowed(CAI_BaseNPC *pNPC, bool bFromEnd) { return true; } +#endif + // ---------------- // Inputs // ---------------- @@ -83,6 +90,9 @@ class CAI_DynamicLinkController : public CServerOnlyEntity { DECLARE_CLASS( CAI_DynamicLinkController, CServerOnlyEntity ); public: +#ifdef MAPBASE + virtual +#endif void GenerateLinksFromVolume(); // ---------------- diff --git a/game/server/ai_expresserfollowup.cpp b/game/server/ai_expresserfollowup.cpp new file mode 100644 index 00000000..8e810450 --- /dev/null +++ b/game/server/ai_expresserfollowup.cpp @@ -0,0 +1,509 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "ai_speech.h" + +#include "game.h" +#include "eventqueue.h" +#include "ai_basenpc.h" +#include "basemultiplayerplayer.h" +#include "ai_baseactor.h" +#include "sceneentity.h" +//#include "flex_expresser.h" +/* +#include "engine/ienginesound.h" +#include "keyvalues.h" +#include "ai_criteria.h" +#include "isaverestore.h" +#include "sceneentity.h" +*/ + + + +// memdbgon must be the last include file in a .cpp file!!! +#include + +static const char *GetResponseName( CBaseEntity *pEnt ) +{ + Assert( pEnt ); + if ( pEnt == NULL ) + return ""; + return STRING( pEnt->GetEntityName() ); +} + +// This is a tiny helper function for below -- what I'd use a lambda for, usually +static void DispatchComeback( CAI_ExpresserWithFollowup *pExpress, CBaseEntity *pSpeaker, CBaseEntity *pRespondent, AI_ResponseFollowup &followup ) +{ + AssertMsg(pSpeaker != NULL, "Response expressor somehow got called with a NULL Outer.\n"); + if ( !pRespondent ) + { + return; + } + + float delay = followup.followup_delay; + if (pSpeaker == pRespondent && delay < 0) + { + Warning("Response rule with a 'self' target specified negative delay, which isn't legal because that would make someone talk over himself."); + delay = 0; + } + + // Msg( "%s: Dispatch comeback about %s to %s\n", pSpeaker->GetBotString(), g_pConceptManager->GetTopicName( handle ), pRespondent->GetBotString() ); + + // build an input event that we will use to force the bot to talk through the IO system + variant_t value; + // Don't send along null contexts + if (followup.followup_contexts && followup.followup_contexts[0] != '\0') + { + value.SetString( MAKE_STRING( followup.followup_contexts ) ); + g_EventQueue.AddEvent( pRespondent, "AddContext", value, delay - 0.01, pSpeaker, pSpeaker ); + } + + /* + value.SetString(MAKE_STRING(followup.followup_concept)); + g_EventQueue.AddEvent( pRespondent, "SpeakResponseConcept", value, delay , pSpeaker, pSpeaker ); + */ + + AI_CriteriaSet criteria; + + // add in the FROM context so dispatchee knows was from me + const char * RESTRICT pszSpeakerName = GetResponseName( pSpeaker ); + criteria.AppendCriteria( "From", pszSpeakerName ); +#ifdef MAPBASE + // See DispatchFollowupThroughQueue() + criteria.AppendCriteria( "From_idx", CNumStr( pSpeaker->entindex() ) ); + criteria.AppendCriteria( "From_class", pSpeaker->GetClassname() ); +#endif + // if a SUBJECT criteria is missing, put it back in. + if ( criteria.FindCriterionIndex( "Subject" ) == -1 ) + { + criteria.AppendCriteria( "Subject", pszSpeakerName ); + } + + // add in any provided contexts from the parameters onto the ones stored in the followup + criteria.Merge( followup.followup_contexts ); + + // This is kludgy and needs to be fixed in class hierarchy, but for now, try to guess at the most likely + // kinds of targets and dispatch to them. + if (CBaseMultiplayerPlayer *pPlayer = dynamic_cast(pRespondent)) + { + pPlayer->Speak( followup.followup_concept, &criteria ); + } + + else if (CAI_BaseActor *pActor = dynamic_cast(pRespondent)) + { + pActor->Speak( followup.followup_concept, &criteria ); + } +} + +#if 0 +//----------------------------------------------------------------------------- +// Purpose: Placeholder for rules based response system +// Input : concept - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_ExpresserWithFollowup::Speak( AIConcept_t &conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AI_Response *result = SpeakFindResponse( conceptId, modifiers ); + if ( !result ) + { + return false; + } + + CNPC_CompanionBot *pBot = dynamic_cast(GetOuter()); + if ( pBot ) + { + pBot->SetConversationTopic( g_pConceptManager->GetTopic( handle ) ); + pBot->SetLastSpeaker( g_pConceptManager->GetSpeaker( handle ) ); + // Msg( "%s: Conversing about %s\n", pBot->GetBotString(), g_pConceptManager->GetTopicName( handle ) ); + } + + SpeechMsg( GetOuter(), "%s (%x) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), g_pConceptManager->GetConcept( handle ), gpGlobals->curtime ); + + bool spoke = SpeakDispatchResponse( handle, result, filter ); + if ( pszOutResponseChosen ) + { + result->GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} +#endif + + +// Work out the character from the "subject" context. +// Right now, this is a simple find by entity name search. +// But you can define arbitrary subject names, like L4D does +// for "biker", "manager", etc. +static CBaseEntity *AscertainSpeechSubjectFromContext( AI_Response *response, AI_CriteriaSet &criteria, const char *pContextName ) +{ + const char *subject = criteria.GetValue( criteria.FindCriterionIndex( pContextName ) ); + if (subject) + { + CBaseEntity *pEnt = gEntList.FindEntityByName( NULL, subject ); + +#ifdef MAPBASE + // Allow entity indices to be used (see DispatchFollowupThroughQueue() for one particular use case) + if (!pEnt && atoi(subject)) + { + pEnt = CBaseEntity::Instance( atoi( subject ) ); + } +#endif + + return pEnt; + + } + else + { + return NULL; + } +} + +// TODO: Currently uses awful stricmp. Use symbols! Once I know which ones we want, that is. +static CResponseQueue::CFollowupTargetSpec_t ResolveFollowupTargetToEntity( AIConcept_t &conceptId, AI_CriteriaSet &criteria, const char * RESTRICT szTarget, AI_Response * RESTRICT response = NULL ) +{ + + + + if ( Q_stricmp(szTarget, "self") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_SPECIFIC, conceptId.GetSpeaker() ); + } + else if ( Q_stricmp(szTarget, "subject") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( AscertainSpeechSubjectFromContext( response, criteria, "Subject" ) ); + } + else if ( Q_stricmp(szTarget, "from") == 0 ) + { +#ifdef MAPBASE + // See DispatchFollowupThroughQueue() + return CResponseQueue::CFollowupTargetSpec_t( AscertainSpeechSubjectFromContext( response, criteria, "From_idx" ) ); +#else + return CResponseQueue::CFollowupTargetSpec_t( AscertainSpeechSubjectFromContext( response, criteria, "From" ) ); +#endif + } + else if ( Q_stricmp(szTarget, "any") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_ANY, conceptId.GetSpeaker() ); + } + else if ( Q_stricmp(szTarget, "all") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_ALL ); + } + + // last resort, try a named lookup +#ifdef MAPBASE + else if ( CBaseEntity *pSpecific = gEntList.FindEntityByName(NULL, szTarget, conceptId.GetSpeaker()) ) // it could be anything +#else + else if ( CBaseEntity *pSpecific = gEntList.FindEntityByName(NULL, szTarget) ) // it could be anything +#endif + { + return CResponseQueue::CFollowupTargetSpec_t( pSpecific ); + } + + Warning("Couldn't resolve response target %s\n", szTarget ); + return CResponseQueue::CFollowupTargetSpec_t(); // couldn't resolve. +} + + +// TODO: Currently uses awful stricmp. Use symbols! Once I know which ones we want, that is. +static CResponseQueue::CFollowupTargetSpec_t ResolveFollowupTargetToEntity( AIConcept_t &conceptId, AI_CriteriaSet &criteria, AI_Response * RESTRICT response, AI_ResponseFollowup * RESTRICT followup ) +{ + const char * RESTRICT szTarget = followup->followup_target; + const CResponseQueue::CFollowupTargetSpec_t INVALID; // default: invalid result + if ( szTarget == NULL ) + return INVALID; + else + return ResolveFollowupTargetToEntity( conceptId, criteria, szTarget, response ); +} + + +ConVar chet_debug_idle( "chet_debug_idle", "0", FCVAR_ARCHIVE, "If set one, many debug prints to help track down the TLK_IDLE issue. Set two for super verbose info" ); +// extern ConVar chet_debug_idle; +bool CAI_ExpresserWithFollowup::Speak( AIConcept_t conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + VPROF("CAI_Expresser::Speak"); + if ( IsSpeechGloballySuppressed() ) + { + return false; + } + + conceptId.SetSpeaker(GetOuter()); + AI_CriteriaSet criteria; + GatherCriteria(&criteria, conceptId, modifiers); + GetOuter()->ModifyOrAppendDerivedCriteria(criteria); + AI_Response result; + if ( !FindResponse( result, conceptId, &criteria ) ) + { + if (chet_debug_idle.GetBool()) + { + + const char *name = GetOuter()->GetDebugName(); + + Msg( "TLK_IDLE: %s did not FindResponse\n", name ); + } + return false; + } + else + { + if (chet_debug_idle.GetBool()) + { + + + const char *name = GetOuter()->GetDebugName(); + + Msg( "TLK_IDLE: %s SUCCESSFUL FindResponse\n", name ); + } + } + + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)conceptId, gpGlobals->curtime ); + // Msg( "%s:%s to %s:%s\n", GetOuter()->GetDebugName(), conceptId.GetStringConcept(), criteria.GetValue(criteria.FindCriterionIndex("Subject")), pTarget ? pTarget->GetDebugName() : "none" ); + + bool spoke = SpeakDispatchResponse( conceptId, &result, &criteria, filter ); + if ( pszOutResponseChosen ) + { + result.GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} + +extern ISoundEmitterSystemBase* soundemitterbase; + +static float GetSpeechDurationForResponse( const AI_Response * RESTRICT response, const char *szActorModel) +{ + switch (response->GetType()) + { + case ResponseRules::RESPONSE_SCENE: + { + char szScene[MAX_PATH]; + soundemitterbase->GenderExpandString(szActorModel, response->GetResponsePtr(), szScene, MAX_PATH); + return GetSceneSpeechDuration(szScene); + } + break; + default: + break; + } + + return 0.f; +} + +//----------------------------------------------------------------------------- +// Purpose: Dispatches the result +// Input : *response - +//----------------------------------------------------------------------------- +bool CAI_ExpresserWithFollowup::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter ) +{ + // This gives the chance for the other bot to respond. + if ( !conceptId.GetSpeaker().IsValid() ) + { + conceptId.SetSpeaker(GetOuter()); + } + + bool bInterrupted = IsSpeaking(); + bool bSuc = CAI_Expresser::SpeakDispatchResponse( conceptId, response, criteria, filter ); + if (!bSuc) + { + return false; + } + + if ( bInterrupted ) + { + g_ResponseQueueManager.GetQueue()->RemoveSpeechQueuedFor( GetOuter() ); + } + + // Record my followup details so that I may defer its use til end of the speech + AI_ResponseFollowup * RESTRICT followup = response->GetParams()->m_pFollowup; + if ( followup ) + { + if ( followup->followup_entityiotarget && followup->followup_entityioinput ) + { +#ifdef MAPBASE + CBaseEntity * RESTRICT pTarget = ResolveFollowupTargetToEntity( conceptId, *criteria, followup->followup_entityiotarget, response ).m_hHandle; +#else + CBaseEntity * RESTRICT pTarget = gEntList.FindEntityByName( NULL, followup->followup_entityiotarget ); +#endif + if ( pTarget ) + { + g_EventQueue.AddEvent( pTarget, followup->followup_entityioinput, variant_t(), followup->followup_entityiodelay, GetOuter(), GetOuter() ); + } + } + if ( followup->IsValid() ) + { + // 11th hour change: rather than trigger followups from the end of a VCD, + // instead fire it from the end of the last speech event in the VCD, because + // there's a multisecond facial relax delay built into the scene. + // The speech length is stored in the cache, so we can post the followup now. + if ( response->GetType() == ResponseRules::RESPONSE_SCENE && + followup->followup_delay >= 0 ) + { + float fTimeToLastSpeech = GetSpeechDurationForResponse( response, STRING(GetOuter()->GetModelName()) ); + // failsafe + if ( fTimeToLastSpeech > 0 ) + { + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( conceptId, *criteria, response, followup ), + fTimeToLastSpeech + followup->followup_delay, GetOuter() ); + } + else // error + { + // old way, copied from "else" below + m_pPostponedFollowup = followup; + if ( criteria ) + m_followupTarget = ResolveFollowupTargetToEntity( conceptId, *criteria, response, m_pPostponedFollowup ); + else + { + AI_CriteriaSet tmpCriteria; + m_followupTarget = ResolveFollowupTargetToEntity( conceptId, tmpCriteria, response, m_pPostponedFollowup ); + } + } + } + else if ( followup->followup_delay < 0 ) + { + // a negative delay has a special meaning. Usually the comeback dispatches after + // the currently said line is finished; the delay is added to that, to provide a + // pause between when character A finishes speaking and B begins. + // A negative delay (-n) actually means "dispatch the comeback n seconds + // after I start talking". + // In this case we do not need to postpone the followup; we just throw it directly + // into the queue. + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( conceptId, *criteria, response, followup ), + -followup->followup_delay, GetOuter() ); + } +#ifndef MAPBASE // RESPONSE_PRINT now notes speaking time + else if ( response->GetType() == ResponseRules::RESPONSE_PRINT ) + { // zero-duration responses dispatch immediately via the queue (must be the queue bec. + // the m_pPostponedFollowup will never trigger) + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( conceptId, *criteria, response, followup ), + followup->followup_delay, GetOuter() ); + } +#endif + else + { + // this is kind of a quick patch to immediately deal with the issue of null criteria + // (arose while branching to main) without replumbing a bunch of stuff -- to be fixed + // 5.13.08 egr + m_pPostponedFollowup = followup; + if ( criteria ) + m_followupTarget = ResolveFollowupTargetToEntity( conceptId, *criteria, response, m_pPostponedFollowup ); + else + { + AI_CriteriaSet tmpCriteria; + m_followupTarget = ResolveFollowupTargetToEntity( conceptId, tmpCriteria, response, m_pPostponedFollowup ); + } + } + } + } + + + return bSuc; +} + +// This is a gimmick used when a negative delay is specified in a followup, which is a shorthand +// for "this many seconds after the beginning of the line" rather than "this may seconds after the end +// of the line", eg to create a THEN rule when two characters talk over each other. +// It's static to avoid accidental use of the postponed followup/target members. +void CAI_ExpresserWithFollowup::DispatchFollowupThroughQueue( const AIConcept_t &conceptId, + const char * RESTRICT criteriaStr, + const CResponseQueue::CFollowupTargetSpec_t &target, + float delay, + CBaseEntity * RESTRICT pOuter + ) +{ + AI_CriteriaSet criteria; + // Don't add my own criteria! GatherCriteria( &criteria, followup.followup_concept, followup.followup_contexts ); + + criteria.AppendCriteria( "From", STRING( pOuter->GetEntityName() ) ); +#ifdef MAPBASE + // The index of the "From" entity. + // In HL2 mods, many followup users would be generic NPCs (e.g. citizens) who might not have any particular significance. + // Those generic NPCs are quite likely to have no name or have a name in common with other entities. As a result, Mapbase + // changes internal operations of the "From" context to search for an entity index. This won't be 100% reliable if the source + // talker dies and another entity is created immediately afterwards, but it's a lot more reliable than a simple entity name search. + criteria.AppendCriteria( "From_idx", CNumStr( pOuter->entindex() ) ); + + // Generic NPCs should also be attributable by classname + criteria.AppendCriteria( "From_class", pOuter->GetClassname() ); +#endif + + criteria.Merge( criteriaStr ); + g_ResponseQueueManager.GetQueue()->Add( conceptId, &criteria, gpGlobals->curtime + delay, target, pOuter ); +} + +//----------------------------------------------------------------------------- +// Purpose: Handles the new concept objects +//----------------------------------------------------------------------------- +void CAI_ExpresserWithFollowup::SpeakDispatchFollowup( AI_ResponseFollowup &followup ) +{ + if ( !m_followupTarget.IsValid() ) + return; + + // If a specific entity target is given, use the old pathway for now + if ( m_followupTarget.m_iTargetType == kDRT_SPECIFIC && followup.followup_delay == 0 ) + { + CBaseEntity *pTarget = m_followupTarget.m_hHandle.Get(); + if (!pTarget) + { + return; + } + DispatchComeback( this, GetOuter(), pTarget, followup ); + } + else + { + DispatchFollowupThroughQueue( followup.followup_concept, followup.followup_contexts, m_followupTarget, followup.followup_delay, GetOuter() ); + } + // clear out the followup member just in case. + m_pPostponedFollowup = NULL; + m_followupTarget.m_iTargetType = kDRT_MAX; +} + +void CAI_ExpresserWithFollowup::OnSpeechFinished() +{ + if (m_pPostponedFollowup && m_pPostponedFollowup->IsValid()) + { +#ifdef MAPBASE + // HACKHACK: Non-scene speech (e.g. noscene speak/sentence) fire OnSpeechFinished() immediately, + // so add the actual speech time to the followup delay + if (GetTimeSpeechCompleteWithoutDelay() > gpGlobals->curtime) + m_pPostponedFollowup->followup_delay += GetTimeSpeechCompleteWithoutDelay() - gpGlobals->curtime; +#endif + return SpeakDispatchFollowup(*m_pPostponedFollowup); + } +} + + + + +void CC_RR_ForceConcept_f( const CCommand &args ) +{ + if ( args.ArgC() < 3 ) + { + Msg("USAGE: rr_forceconcept \"criteria1:value1,criteria2:value2,...\"\n"); + return; + } + + AI_CriteriaSet criteria; + if ( args.ArgC() >= 3 ) + { + const char *criteriastring = args[3]; + criteria.Merge( criteriastring ); + } + + AIConcept_t conceptId( args[2] ); + QueueSpeak( conceptId, ResolveFollowupTargetToEntity( conceptId, criteria, args[1] ), criteria ); +} + + +static ConCommand rr_forceconcept( "rr_forceconcept", CC_RR_ForceConcept_f, + "fire a response concept directly at a given character.\n" + "USAGE: rr_forceconcept \"criteria1:value1,criteria2:value2,...\"\n" + "criteria values are optional.\n" + + , FCVAR_CHEAT ); diff --git a/game/server/ai_goalentity.cpp b/game/server/ai_goalentity.cpp index 31981097..916d9210 100644 --- a/game/server/ai_goalentity.cpp +++ b/game/server/ai_goalentity.cpp @@ -38,6 +38,15 @@ BEGIN_DATADESC( CAI_GoalEntity ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CAI_GoalEntity, CBaseEntity, "The base class for goal entities used to control NPC behavior." ) + + DEFINE_SCRIPTFUNC( IsActive, "Check if the goal entity is active." ) + DEFINE_SCRIPTFUNC( NumActors, "Get the number of actors using this goal entity." ) + +END_SCRIPTDESC(); +#endif + //------------------------------------- diff --git a/game/server/ai_goalentity.h b/game/server/ai_goalentity.h index 2a6805f4..56252d25 100644 --- a/game/server/ai_goalentity.h +++ b/game/server/ai_goalentity.h @@ -27,6 +27,9 @@ class CAI_GoalEntity : public CBaseEntity, public IEntityListener { DECLARE_CLASS( CAI_GoalEntity, CBaseEntity ); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif public: CAI_GoalEntity() : m_iszActor(NULL_STRING), diff --git a/game/server/ai_hint.cpp b/game/server/ai_hint.cpp index c0014220..2e8e90af 100644 --- a/game/server/ai_hint.cpp +++ b/game/server/ai_hint.cpp @@ -35,6 +35,10 @@ CHintCriteria::CHintCriteria( void ) m_strGroup = NULL_STRING; m_iFlags = 0; m_HintTypes.Purge(); +#ifdef MAPBASE // From Alien Swarm SDK + m_pfnFilter = NULL; + m_pFilterContext = NULL; +#endif } //----------------------------------------------------------------------------- @@ -890,6 +894,9 @@ BEGIN_DATADESC( CAI_Hint ) // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "EnableHint", InputEnableHint ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableHint", InputDisableHint ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetHintGroup", InputSetHintGroup ), +#endif // Outputs DEFINE_OUTPUT( m_OnNPCStartedUsing, "OnNPCStartedUsing" ), @@ -897,6 +904,23 @@ BEGIN_DATADESC( CAI_Hint ) END_DATADESC( ); +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CAI_Hint, CBaseEntity, "An entity which gives contextual pointers for NPCs." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintType, "GetHintType", "Get the hint's type ID." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetUser, "GetUser", "Get the hint's current user." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintGroup, "GetHintGroup", "Get the name of the hint's group." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintActivity, "GetHintActivity", "Get the name of the hint activity." ) + + DEFINE_SCRIPTFUNC( IsDisabled, "Check if the hint is disabled." ) + DEFINE_SCRIPTFUNC( IsLocked, "Check if the hint is locked." ) + DEFINE_SCRIPTFUNC( GetNodeId, "Get the hint's node ID." ) + DEFINE_SCRIPTFUNC( Yaw, "Get the hint's yaw." ) + DEFINE_SCRIPTFUNC( GetDirection, "Get the hint's direction." ) + +END_SCRIPTDESC(); +#endif + //------------------------------------------------------------------------------ // Purpose : //------------------------------------------------------------------------------ @@ -913,6 +937,18 @@ void CAI_Hint::InputDisableHint( inputdata_t &inputdata ) m_NodeData.iDisabled = true; } +#ifdef MAPBASE +void CAI_Hint::SetGroup( string_t iszNewGroup ) +{ + m_NodeData.strGroup = iszNewGroup; +} + +void CAI_Hint::InputSetHintGroup( inputdata_t &inputdata ) +{ + SetGroup(inputdata.value.StringID()); +} +#endif + //------------------------------------------------------------------------------ // Purpose : @@ -1075,6 +1111,85 @@ bool CAI_Hint::IsInNodeFOV( CBaseEntity *pOther ) return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// An easy way of engaging certain hint parameters on certain hint types that didn't use it before. +//----------------------------------------------------------------------------- +void CAI_Hint::NPCHandleStartNav( CAI_BaseNPC *pNPC, bool bDefaultFacing ) +{ + Assert( pNPC != NULL ); + + HintIgnoreFacing_t facing = GetIgnoreFacing(); + if (facing == HIF_DEFAULT) + facing = bDefaultFacing ? HIF_NO : HIF_YES; + + if (facing == HIF_NO) + pNPC->GetNavigator()->SetArrivalDirection( GetDirection() ); + + if (HintActivityName() != NULL_STRING) + { + Activity hintActivity = (Activity)CAI_BaseNPC::GetActivityID( STRING(HintActivityName()) ); + if ( hintActivity != ACT_INVALID ) + { + pNPC->GetNavigator()->SetArrivalActivity( pNPC->GetHintActivity(HintType(), hintActivity) ); + } + else + { + int iSequence = pNPC->LookupSequence(STRING(HintActivityName())); + if ( iSequence != ACT_INVALID ) + { + pNPC->GetNavigator()->SetArrivalSequence( iSequence ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if this hint should override a NPC's yaw even during regular AI. +//----------------------------------------------------------------------------- +bool CAI_Hint::OverridesNPCYaw( CAI_BaseNPC *pNPC ) +{ + switch (HintType()) + { + case HINT_TACTICAL_COVER_CUSTOM: + case HINT_TACTICAL_COVER_MED: + case HINT_TACTICAL_COVER_LOW: + { + if (pNPC->HasMemory( bits_MEMORY_INCOVER )) + { + // By default, don't override yaw on cover nodes unless they use custom activities. + HintIgnoreFacing_t facing = GetIgnoreFacing(); + if (facing == HIF_DEFAULT) + return ( HintActivityName() != NULL_STRING ); + + return facing == HIF_NO; + } + + break; + } + + case HINT_PLAYER_ALLY_MOVE_AWAY_DEST: + { + Vector vHintPos; + GetPosition( pNPC, &vHintPos ); + if (VectorsAreEqual( vHintPos, pNPC->GetAbsOrigin(), 0.1f )) + { + // By default, don't override yaw on move away destinations unless they use custom activities. + HintIgnoreFacing_t facing = GetIgnoreFacing(); + if (facing == HIF_DEFAULT) + return ( HintActivityName() != NULL_STRING ); + + return facing == HIF_NO; + } + + break; + } + } + + return false; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Locks the node for use by an AI for hints // Output : Returns true if the node was available for locking, false on failure. @@ -1192,6 +1307,30 @@ bool CAI_Hint::HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hint return false; } +#ifdef MAPBASE + // Test against generic filter + // (From Alien Swarm SDK) + if ( !hintCriteria.PassesFilter( this ) ) + { + REPORTFAILURE( "Failed filter test" ); + return false; + } + + // (From Alien Swarm SDK) + int nRadius = GetRadius(); + if ( nRadius != 0 ) + { + // Calculate our distance + float distance = (GetAbsOrigin() - position).LengthSqr(); + + if ( distance > nRadius * nRadius ) + { + REPORTFAILURE( "NPC is not within the node's radius." ); + return false; + } + } +#endif + if ( hintCriteria.HasFlag(bits_HINT_NPC_IN_NODE_FOV) ) { if ( pNPC == NULL ) @@ -1311,10 +1450,18 @@ bool CAI_Hint::HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hint { trace_t tr; // Can my bounding box fit there? +#ifdef MAPBASE // From Alien Swarm SDK + Vector vStep( 0, 0, pNPC->StepHeight() ); + AI_TraceHull ( GetAbsOrigin() + vStep, GetAbsOrigin(), pNPC->WorldAlignMins(), pNPC->WorldAlignMaxs() - vStep, + MASK_SOLID, pNPC, COLLISION_GROUP_NONE, &tr ); + + if ( tr.fraction < 0.95 ) +#else AI_TraceHull ( GetAbsOrigin(), GetAbsOrigin(), pNPC->WorldAlignMins(), pNPC->WorldAlignMaxs(), MASK_SOLID, pNPC, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction != 1.0 ) +#endif { REPORTFAILURE( "Node isn't clear." ); return false; @@ -1330,6 +1477,15 @@ bool CAI_Hint::HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hint // Calculate our distance float distance = (GetAbsOrigin() - position).Length(); +#ifdef MAPBASE + // Divide by hint weight + float flWeight = GetHintWeight(); + if ( flWeight != 1.0f ) + { + distance *= GetHintWeightInverse(); + } +#endif + // Must be closer than the current best if ( distance > *flNearestDistance ) { @@ -1426,6 +1582,15 @@ int CAI_Hint::DrawDebugTextOverlays(void) EntityText(text_offset,tempstr,0); text_offset++; +#ifdef MAPBASE + if (m_NodeData.strGroup != NULL_STRING) + { + Q_snprintf(tempstr,sizeof(tempstr),"hintgroup %s", STRING(m_NodeData.strGroup) ) ; + EntityText(text_offset,tempstr,0); + text_offset++; + } +#endif + if ( m_NodeData.iDisabled ) { Q_snprintf(tempstr,sizeof(tempstr),"DISABLED" ); @@ -1501,6 +1666,14 @@ void CAI_Hint::OnRestore() m_NodeData.nNodeID = g_pAINetworkManager->GetEditOps()->GetNodeIdFromWCId( m_NodeData.nWCNodeID ); FixupTargetNode(); +#ifdef MAPBASE + if (m_NodeData.flWeight != 0.0f && m_NodeData.flWeight != 1.0f) + { + // Re-invert the weight + m_NodeData.flWeightInverse = 1.0f / m_NodeData.flWeight; + } +#endif + CAI_Node *pNode = GetNode(); if ( !pNode ) @@ -1676,6 +1849,11 @@ void CC_ai_drop_hint( const CCommand &args ) nodeData.fIgnoreFacing = HIF_DEFAULT; nodeData.minState = NPC_STATE_IDLE; nodeData.maxState = NPC_STATE_COMBAT; +#ifdef MAPBASE + nodeData.nRadius = 0; // From Alien Swarm SDK + nodeData.flWeight = 1.0f; + nodeData.flWeightInverse = 1.0f; +#endif CAI_Hint *pHint = CAI_HintManager::CreateHint( &nodeData, NULL ); if ( pHint ) { diff --git a/game/server/ai_hint.h b/game/server/ai_hint.h index 89daef3d..570f85ef 100644 --- a/game/server/ai_hint.h +++ b/game/server/ai_hint.h @@ -112,6 +112,13 @@ enum Hint_e // CS port hints HINT_CSTRIKE_HOSTAGE_ESCAPE = 1100, + +#ifdef MAPBASE + // Mapbase hints + // (these start at a high number to avoid potential conflicts with mod hints) + + HINT_TACTICAL_COVER_CUSTOM = 10000, // Cover node with a custom hint activity (NPCs can take cover and reload here while playing said activity) +#endif }; const char *GetHintTypeDescription( Hint_e iHintType ); const char *GetHintTypeDescription( CAI_Hint *pHint ); @@ -120,6 +127,10 @@ const char *GetHintTypeDescription( CAI_Hint *pHint ); // CHintCriteria //----------------------------------------------------------------------------- +#ifdef MAPBASE // From Alien Swarm SDK +typedef bool (*HintSearchFilterFunc_t)( void *pContext, CAI_Hint *pCandidate ); +#endif + class CHintCriteria { public: @@ -134,6 +145,11 @@ class CHintCriteria void SetGroup( string_t group ); string_t GetGroup( void ) const { return m_strGroup; } +#ifdef MAPBASE // From Alien Swarm SDK + void SetFilterFunc( HintSearchFilterFunc_t pfnFilter, void *pContext = NULL ) { m_pfnFilter = pfnFilter; m_pFilterContext = pContext; } + bool PassesFilter( CAI_Hint *pCandidate ) const { return (m_pfnFilter) ? (*m_pfnFilter)(m_pFilterContext, pCandidate) : true; } +#endif + int GetFirstHintType( void ) const { return m_iFirstHintType; } int GetLastHintType( void ) const { return m_iLastHintType; } bool MatchesHintType( int hintType ) const; @@ -176,6 +192,11 @@ class CHintCriteria zoneList_t m_zoneInclude; zoneList_t m_zoneExclude; + +#ifdef MAPBASE + HintSearchFilterFunc_t m_pfnFilter; + void * m_pFilterContext; +#endif }; class CAI_Node; @@ -281,11 +302,19 @@ class CAI_Hint : public CServerOnlyEntity float Yaw( void ); CAI_Node *GetNode( void ); string_t GetGroup( void ) const { return m_NodeData.strGroup; } +#ifdef MAPBASE + void SetGroup( string_t iszNewGroup ); +#endif CBaseEntity *User( void ) const { return m_hHintOwner; }; Hint_e HintType( void ) const { return (Hint_e)m_NodeData.nHintType; }; void SetHintType( int hintType, bool force = false ); string_t HintActivityName( void ) const { return m_NodeData.iszActivityName; } int GetTargetNode( void ) const { return m_nTargetNodeID; } +#ifdef MAPBASE + // HACKHACK: This is for when target nodes need to be accessed before being sorted into engine IDs + int GetTargetWCNodeID( void ) const { return m_NodeData.nTargetWCNodeID; } + int GetWCNodeID( void ) const { return m_NodeData.nWCNodeID; } +#endif bool IsDisabled( void ) const { return (m_NodeData.iDisabled != 0); } void SetDisabled( bool bDisabled ) { m_NodeData.iDisabled = bDisabled; } void DisableForSeconds( float flSeconds ); @@ -302,10 +331,33 @@ class CAI_Hint : public CServerOnlyEntity int GetNodeId() { return m_NodeData.nNodeID; } int GetWCId() { return m_NodeData.nWCNodeID; } +#ifdef MAPBASE + int GetRadius() const { return m_NodeData.nRadius; } // From Alien Swarm SDK + + float GetHintWeight() const { return m_NodeData.flWeight; } + float GetHintWeightInverse() const { return m_NodeData.flWeightInverse; } // Used to multiply distances +#endif + bool HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, const Vector &position, float *flNearestDistance, bool bIgnoreLock = false, bool bIgnoreHintType = false ); bool IsInNodeFOV( CBaseEntity *pOther ); +#ifdef MAPBASE + void NPCHandleStartNav( CAI_BaseNPC *pNPC, bool bDefaultFacing ); + + // Returns true if this hint should override a NPC's yaw even during regular AI. + bool OverridesNPCYaw( CAI_BaseNPC *pNPC ); +#endif + +#ifdef MAPBASE_VSCRIPT + int ScriptGetHintType() { return (int)HintType(); } + HSCRIPT ScriptGetUser() { return ToHScript( User() ); } + const char* ScriptGetHintGroup() { return STRING( GetGroup() ); } + const char* ScriptGetHintActivity() { return STRING( HintActivityName() ); } +#endif + +#ifndef MAPBASE private: +#endif void Spawn( void ); virtual void Activate(); virtual void UpdateOnRemove( void ); @@ -317,6 +369,9 @@ class CAI_Hint : public CServerOnlyEntity // Input handlers void InputEnableHint( inputdata_t &inputdata ); void InputDisableHint( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetHintGroup( inputdata_t &inputdata ); +#endif private: @@ -333,6 +388,9 @@ class CAI_Hint : public CServerOnlyEntity friend class CAI_HintManager; DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif }; #define SF_ALLOW_JUMP_UP 65536 diff --git a/game/server/ai_initutils.cpp b/game/server/ai_initutils.cpp index 8c476719..cd792798 100644 --- a/game/server/ai_initutils.cpp +++ b/game/server/ai_initutils.cpp @@ -173,6 +173,10 @@ BEGIN_SIMPLE_DATADESC( HintNodeData ) DEFINE_KEYFIELD( fIgnoreFacing, FIELD_INTEGER, "IgnoreFacing" ), DEFINE_KEYFIELD( minState, FIELD_INTEGER, "MinimumState" ), DEFINE_KEYFIELD( maxState, FIELD_INTEGER, "MaximumState" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( nRadius, FIELD_INTEGER, "radius" ), // From Alien Swarm SDK + DEFINE_KEYFIELD( flWeight, FIELD_FLOAT, "hintweight" ), +#endif END_DATADESC() @@ -205,6 +209,17 @@ int CNodeEnt::Spawn( const char *pMapData ) m_NodeData.minState = NPC_STATE_IDLE; if ( m_NodeData.maxState == NPC_STATE_NONE ) m_NodeData.maxState = NPC_STATE_COMBAT; +#ifdef MAPBASE + if (m_NodeData.flWeight == 0.0f) + { + m_NodeData.flWeight = 1.0f; + } + else if (m_NodeData.flWeight != 1.0f) + { + // Invert the weight so that it could be used as a direct multiplier for distances, etc. + m_NodeData.flWeightInverse = 1.0f / m_NodeData.flWeight; + } +#endif // --------------------------------------------------------------------------------- // If just a hint node (not used for navigation) just create a hint and bail // --------------------------------------------------------------------------------- @@ -227,7 +242,11 @@ int CNodeEnt::Spawn( const char *pMapData ) // --------------------------------------------------------------------------------- CAI_Hint *pHint = NULL; - if ( ClassMatches( "info_node_hint" ) || ClassMatches( "info_node_air_hint" ) ) + if ( ClassMatches( "info_node_hint" ) || ClassMatches( "info_node_air_hint" ) +#ifdef MAPBASE + || ClassMatches( "info_node_climb" ) // Climb nodes contain hint data in the FGD +#endif + ) { if ( m_NodeData.nHintType || m_NodeData.strGroup != NULL_STRING || m_NodeData.strEntityName != NULL_STRING ) { diff --git a/game/server/ai_initutils.h b/game/server/ai_initutils.h index 22aaf5f3..70bd019c 100644 --- a/game/server/ai_initutils.h +++ b/game/server/ai_initutils.h @@ -42,6 +42,11 @@ struct HintNodeData HintIgnoreFacing_t fIgnoreFacing; NPC_STATE minState; NPC_STATE maxState; +#ifdef MAPBASE + int nRadius; // From Alien Swarm SDK + float flWeight; + float flWeightInverse; // Not saved +#endif int nWCNodeID; // Node ID assigned by worldcraft (not same as engine!) diff --git a/game/server/ai_motor.cpp b/game/server/ai_motor.cpp index 49f3d5f4..43eb86a3 100644 --- a/game/server/ai_motor.cpp +++ b/game/server/ai_motor.cpp @@ -14,6 +14,9 @@ #include "ai_basenpc.h" #include "ai_localnavigator.h" #include "ai_moveprobe.h" +#ifdef MAPBASE +#include "ai_hint.h" +#endif #include "saverestore_utlvector.h" // memdbgon must be the last include file in a .cpp file!!! @@ -235,18 +238,47 @@ void CAI_Motor::MoveClimbStart( const Vector &climbDest, const Vector &climbDir // > code are not reciprocal for all state, and furthermore, stomp // > other state? + bool bGoingUp = (climbDir.z > 0.01); +#if EXPANDED_NAVIGATION_ACTIVITIES + if ( bGoingUp && GetOuter()->HaveSequenceForActivity( ACT_CLIMB_MOUNT_BOTTOM ) ) + { + SetActivity( ACT_CLIMB_MOUNT_BOTTOM ); + + // Steal m_vecDismount for this + GetOuter()->GetSequenceLinearMotion( GetSequence(), &m_vecDismount ); + GetOuter()->SetCycle( GetOuter()->GetMovementFrame( m_vecDismount.z - climbDist ) ); + } + else if ( !bGoingUp && GetOuter()->HaveSequenceForActivity( ACT_CLIMB_MOUNT_TOP ) ) + { + SetActivity( ACT_CLIMB_MOUNT_TOP ); + + // Steal m_vecDismount for this + GetOuter()->GetSequenceLinearMotion( GetSequence(), &m_vecDismount ); + GetOuter()->SetCycle( GetOuter()->GetMovementFrame( m_vecDismount.z - climbDist ) ); + } + else +#endif if ( fabsf( climbDir.z ) < .1 ) { SetActivity( GetNavigator()->GetMovementActivity() ); } else { - SetActivity( (climbDir.z > -0.01 ) ? ACT_CLIMB_UP : ACT_CLIMB_DOWN ); + SetActivity( bGoingUp ? ACT_CLIMB_UP : ACT_CLIMB_DOWN ); } m_nDismountSequence = SelectWeightedSequence( ACT_CLIMB_DISMOUNT ); if (m_nDismountSequence != ACT_INVALID) { +#if EXPANDED_NAVIGATION_ACTIVITIES + if ( !bGoingUp ) + { + int nBottomDismount = SelectWeightedSequence( ACT_CLIMB_DISMOUNT_BOTTOM ); + if (nBottomDismount != ACTIVITY_NOT_AVAILABLE) + m_nDismountSequence = nBottomDismount; + } +#endif + GetOuter()->GetSequenceLinearMotion( m_nDismountSequence, &m_vecDismount ); } else @@ -262,6 +294,76 @@ void CAI_Motor::MoveClimbStart( const Vector &climbDest, const Vector &climbDir AIMoveResult_t CAI_Motor::MoveClimbExecute( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw, int climbNodesLeft ) { +#if EXPANDED_NAVIGATION_ACTIVITIES + if ( (GetActivity() == ACT_CLIMB_MOUNT_TOP || GetActivity() == ACT_CLIMB_MOUNT_BOTTOM) ) + { + if (!GetOuter()->IsActivityFinished()) + { + // Wait for the mounting to finish + SetGroundEntity( NULL ); + } + else + { + // Fix up our position if we have to + Vector vecTeleportOrigin; + if (MoveClimbShouldTeleportToSequenceEnd( vecTeleportOrigin )) + { + SetLocalOrigin( vecTeleportOrigin ); + } + + // Reset activity and start from the beginning + GetOuter()->ResetActivity(); + return MoveClimbExecute( climbDest, climbDir, climbDist, yaw, climbNodesLeft ); + } + } + else if ( fabsf( climbDir.z ) > .1 && (GetActivity() != ACT_CLIMB_DISMOUNT && GetActivity() != ACT_CLIMB_DISMOUNT_BOTTOM) ) + { + bool bGoingUp = (climbDir.z > -0.01); + if ( GetOuter()->HaveSequenceForActivity( ACT_CLIMB_ALL ) ) + { + SetActivity( ACT_CLIMB_ALL ); + + // TODO: Use UTIL_VecToPitch() instead if move_yaw becomes a true climb yaw and not just an up-down scalar + SetPoseParameter( GetOuter()->LookupPoseMoveYaw(), climbDir.z < 0 ? 180.0 : -180.0 ); + } + else + { + Activity desiredActivity = bGoingUp ? ACT_CLIMB_UP : ACT_CLIMB_DOWN; + if ( GetActivity() != desiredActivity ) + { + SetActivity( desiredActivity ); + } + } + + if (m_nDismountSequence != ACT_INVALID) + { + if (climbNodesLeft <= 2 && climbDist < fabs( m_vecDismount.z )) + { + if (bGoingUp) + { + // fixme: No other way to force m_nIdealSequence? + GetOuter()->SetActivity( ACT_CLIMB_DISMOUNT ); + GetOuter()->SetCycle( GetOuter()->GetMovementFrame( m_vecDismount.z - climbDist ) ); + } + else + { + if (GetSequence() != m_nDismountSequence && GetOuter()->GetSequenceActivity( m_nDismountSequence ) == ACT_CLIMB_DISMOUNT_BOTTOM) + { + SetActivity( ACT_CLIMB_DISMOUNT_BOTTOM ); + } + } + } + } + } + else if ( climbDir.Length() == 0 && GetOuter()->GetInstantaneousVelocity() <= 0.01 ) + { + // The NPC is somehow stuck climbing with no direction or movement. + // This can be caused by NPCs getting stuck in each other and/or being moved away from the ladder. + // In these cases, the NPC has to be made unstuck, or else they may remain in an immobile climbing state forever. + Warning( "%s had to abort climbing due to no direction or movement\n", GetOuter()->GetDebugName() ); + return AIMR_ILLEGAL; + } +#else if ( fabsf( climbDir.z ) > .1 ) { if ( GetActivity() != ACT_CLIMB_DISMOUNT ) @@ -292,13 +394,34 @@ AIMoveResult_t CAI_Motor::MoveClimbExecute( const Vector &climbDest, const Vecto } } } +#endif float climbSpeed = GetOuter()->GetInstantaneousVelocity(); if (m_nDismountSequence != ACT_INVALID) { // catch situations where the climb mount/dismount finished before reaching goal +#if EXPANDED_NAVIGATION_ACTIVITIES + if ((GetActivity() == ACT_CLIMB_DISMOUNT || GetActivity() == ACT_CLIMB_DISMOUNT_BOTTOM)) + { + SetGroundEntity( NULL ); + + if (GetOuter()->IsActivityFinished()) + { + // Fix up our position if we have to + Vector vecTeleportOrigin; + if (MoveClimbShouldTeleportToSequenceEnd( vecTeleportOrigin )) + { + // Just force it to complete + climbDist = 0.0f; + } + + climbSpeed = 200.0f; + } + } +#else climbSpeed = MAX( climbSpeed, 30.0 ); +#endif } else { @@ -314,7 +437,7 @@ AIMoveResult_t CAI_Motor::MoveClimbExecute( const Vector &climbDest, const Vecto climbDist = 0; const float climbTime = climbDist / climbSpeed; - + SetMoveInterval( GetMoveInterval() - climbTime ); SetLocalOrigin( climbDest ); @@ -330,6 +453,20 @@ AIMoveResult_t CAI_Motor::MoveClimbExecute( const Vector &climbDest, const Vecto // -------------------------------------------- SetIdealYawAndUpdate( yaw ); +#ifdef MAPBASE + // Lock the yaw if we're in position + if ( UTIL_AngleMod( yaw ) == UTIL_AngleMod( GetLocalAngles().y ) ) + { + SetYawLocked( true ); + } + else if ( IsYawLocked() ) + { + // We're in a different position now. Unlock the yaw and update it + SetYawLocked( false ); + UpdateYaw( -1 ); + } +#endif + return AIMR_OK; } @@ -340,11 +477,62 @@ void CAI_Motor::MoveClimbStop() else SetActivity( ACT_IDLE ); +#ifdef MAPBASE + // Unlock desired weapon state so NPCs can unholster their weapons again. + GetOuter()->SetDesiredWeaponState( DESIREDWEAPONSTATE_IGNORE ); + + // Unlock yaw + SetYawLocked( false ); +#endif + GetOuter()->RemoveFlag( FL_FLY ); SetSmoothedVelocity( vec3_origin ); SetGravity( 1.0 ); } +#ifdef MAPBASE +void CAI_Motor::MoveClimbPause() +{ + if (GetActivity() != ACT_CLIMB_DISMOUNT +#if EXPANDED_NAVIGATION_ACTIVITIES + && GetActivity() != ACT_CLIMB_MOUNT_TOP && GetActivity() != ACT_CLIMB_MOUNT_BOTTOM +#endif + ) + { + if ( GetActivity() == ACT_CLIMB_ALL ) + { + SetPoseParameter( GetOuter()->LookupPoseMoveYaw(), 0.0f ); + } + + SetSmoothedVelocity( vec3_origin ); + } + else + { + // If already dismounting, do nothing + } +} + +//----------------------------------------------------------------------------- +// Purpose: This is part of a hack needed in cases where ladder mount/dismount animations collide with the world and don't move properly. +// It's based off of the same code as scripted_sequence's teleportation fixup, although this function only resolves the bone origin and +// returns whether or not teleportation is necessary, as the teleportation is achieved in different ways for different uses of this code. +//----------------------------------------------------------------------------- +bool CAI_Motor::MoveClimbShouldTeleportToSequenceEnd( Vector &teleportOrigin ) +{ + QAngle new_angle; + GetOuter()->GetBonePosition( 0, teleportOrigin, new_angle ); + + // Ensure that there is actually a distance needed to teleport there + if ((GetLocalOrigin() - teleportOrigin).Length2DSqr() > Square( 8.0 )) + { + teleportOrigin.z = GetLocalOrigin().z; + return true; + } + + return false; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Motion for jumping // Input : @@ -651,9 +839,21 @@ void CAI_Motor::MoveFacing( const AILocalMoveGoal_t &move ) { // FIXME: move this up to navigator so that path goals can ignore these overrides. Vector dir; - float flInfluence = GetFacingDirection( dir ); - dir = move.facing * (1 - flInfluence) + dir * flInfluence; - VectorNormalize( dir ); + +#ifdef MAPBASE + if (IsDeceleratingToGoal() && (GetOuter()->GetHintNode() /*|| GetOuter()->m_hOpeningDoor*/)) + { + // Don't let the facing queue interfere with arrival direction in important cases + dir = move.facing; + VectorNormalize( dir ); + } + else +#endif + { + float flInfluence = GetFacingDirection( dir ); + dir = move.facing * (1 - flInfluence) + dir * flInfluence; + VectorNormalize( dir ); + } // ideal facing direction float idealYaw = UTIL_AngleMod( UTIL_VecToYaw( dir ) ); diff --git a/game/server/ai_motor.h b/game/server/ai_motor.h index d7f14293..29c05f84 100644 --- a/game/server/ai_motor.h +++ b/game/server/ai_motor.h @@ -62,6 +62,10 @@ class CAI_Motor : public CAI_Component, virtual void MoveClimbStart( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw ); virtual AIMoveResult_t MoveClimbExecute( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw, int climbNodesLeft ); virtual void MoveClimbStop(); +#ifdef MAPBASE + virtual void MoveClimbPause(); + virtual bool MoveClimbShouldTeleportToSequenceEnd( Vector &teleportOrigin ); +#endif //--------------------------------- @@ -83,6 +87,9 @@ class CAI_Motor : public CAI_Component, const Vector & GetCurVel() const { return m_vecVelocity; } virtual float OverrideMaxYawSpeed( Activity activity ) { return -1; } +#ifdef MAPBASE + virtual +#endif bool IsDeceleratingToGoal() const { return false; } //--------------------------------- diff --git a/game/server/ai_moveprobe.cpp b/game/server/ai_moveprobe.cpp index b2a86d83..bdf8796b 100644 --- a/game/server/ai_moveprobe.cpp +++ b/game/server/ai_moveprobe.cpp @@ -94,10 +94,16 @@ bool CAI_MoveProbe::ShouldBrushBeIgnored( CBaseEntity *pEntity ) CFuncBrush *pFuncBrush = assert_cast(pEntity); // this is true if my class or entity name matches the exclusion name on the func brush +#ifdef MAPBASE + // The only way it could conflict is if a map has a NPC using a classname as its targetname, like a single npc_fastzombie entity referred to as "npc_zombie". + // I doubt anyone's doing that unless they don't know what they're doing, and even then this still shouldn't be barred from plain-HL2 mappers. + bool nameMatches = GetOuter()->ClassMatches(pFuncBrush->m_iszExcludedClass) || GetOuter()->NameMatches(pFuncBrush->m_iszExcludedClass); +#else #if HL2_EPISODIC bool nameMatches = ( pFuncBrush->m_iszExcludedClass == GetOuter()->m_iClassname ) || GetOuter()->NameMatches(pFuncBrush->m_iszExcludedClass); #else // do not match against entity name in base HL2 (just in case there is some case somewhere that might be broken by this) bool nameMatches = ( pFuncBrush->m_iszExcludedClass == GetOuter()->m_iClassname ); +#endif #endif // return true (ignore brush) if the name matches, or, if exclusion is inverted, if the name does not match diff --git a/game/server/ai_movesolver.cpp b/game/server/ai_movesolver.cpp index 2f06a5b8..101056a7 100644 --- a/game/server/ai_movesolver.cpp +++ b/game/server/ai_movesolver.cpp @@ -114,7 +114,7 @@ bool CAI_MoveSolver::Solve( const AI_MoveSuggestion_t *pSuggestions, int nSugges AI_MoveSuggestion_t *pHighSuggestion; }; - Solution_t solutions[NUM_SOLUTIONS] = { { 0, 0, NULL } }; + Solution_t solutions[NUM_SOLUTIONS] = { 0 }; //--------------------------------- diff --git a/game/server/ai_navigator.cpp b/game/server/ai_navigator.cpp index d136c923..dacab2aa 100644 --- a/game/server/ai_navigator.cpp +++ b/game/server/ai_navigator.cpp @@ -999,12 +999,23 @@ int CAI_Navigator::GetArrivalSequence( int curSequence ) activity = ACT_IDLE; } - sequence = GetOuter()->SelectWeightedSequence( GetOuter()->TranslateActivity( activity ), curSequence ); + Activity translatedActivity = GetOuter()->TranslateActivity( activity ); + sequence = GetOuter()->SelectWeightedSequence( translatedActivity, curSequence ); if ( sequence == ACT_INVALID ) { - DevMsg( GetOuter(), "No appropriate sequence for arrival activity %s (%d)\n", GetOuter()->GetActivityName( GetPath()->GetArrivalActivity() ), GetPath()->GetArrivalActivity() ); - sequence = GetOuter()->SelectWeightedSequence( GetOuter()->TranslateActivity( ACT_IDLE ), curSequence ); +#ifdef MAPBASE + if ( translatedActivity == ACT_SCRIPT_CUSTOM_MOVE ) + { + // ACT_SCRIPT_CUSTOM_MOVE allows activity translation to resolve into specific sequences + sequence = GetOuter()->GetScriptCustomMoveSequence(); + } + else +#endif + { + DevMsg( GetOuter(), "No appropriate sequence for arrival activity %s (%d)\n", GetOuter()->GetActivityName( GetPath()->GetArrivalActivity() ), GetPath()->GetArrivalActivity() ); + sequence = GetOuter()->SelectWeightedSequence( GetOuter()->TranslateActivity( ACT_IDLE ), curSequence ); + } } Assert( sequence != ACT_INVALID ); GetPath()->SetArrivalSequence( sequence ); @@ -1642,6 +1653,15 @@ void CAI_Navigator::MoveCalcBaseGoal( AILocalMoveGoal_t *pMoveGoal ) AI_Waypoint_t *pCurWaypoint = GetPath()->GetCurWaypoint(); if ( pCurWaypoint->GetNext() && pCurWaypoint->GetNext()->NavType() != pCurWaypoint->NavType() ) pMoveGoal->flags |= AILMG_TARGET_IS_TRANSITION; + +#ifdef MAPBASE + // TODO: Better place for this code? + if (pMoveGoal->flags & AILMG_TARGET_IS_TRANSITION && pCurWaypoint->GetNext()->NavType() == NAV_CLIMB) + { + // NPCs need to holster their weapons before climbing. + GetOuter()->SetDesiredWeaponState( DESIREDWEAPONSTATE_HOLSTERED ); + } +#endif } const Task_t *pCurTask = GetOuter()->GetTask(); @@ -2164,11 +2184,26 @@ bool CAI_Navigator::OnMoveBlocked( AIMoveResult_t *pResult ) if (pDoor != NULL) { GetOuter()->OpenPropDoorBegin( pDoor ); +#ifdef MAPBASE + // Tell the navigation to stop running until we're done. + OnNewGoal(); +#endif *pResult = AIMR_OK; return true; } } +#ifdef MAPBASE + if ( GetOuter()->m_hOpeningDoor ) + { + // In the process of opening a door + // Because navigation is now supposed to terminate when a NPC begins opening a door, this code should not be reached. + DbgNavMsg( GetOuter(), "CAI_Navigator::OnMoveBlocked had to check for m_hOpeningDoor\n" ); + *pResult = AIMR_OK; + return true; + } +#endif + // Allow the NPC to override this behavior if ( GetOuter()->OnMoveBlocked( pResult )) @@ -2591,8 +2626,12 @@ bool CAI_Navigator::Move( float flInterval ) if ( GetNavType() == NAV_CLIMB ) { +#ifdef MAPBASE + GetMotor()->MoveClimbPause(); +#else GetMotor()->MoveClimbStop(); SetNavType( NAV_GROUND ); +#endif } GetMotor()->MoveStop(); AssertMsg( TaskIsRunning() || TaskIsComplete(), ("Schedule stalled!!\n") ); @@ -2695,6 +2734,11 @@ void CAI_Navigator::AdvancePath() if (pDoor != NULL) { GetOuter()->OpenPropDoorBegin(pDoor); + +#ifdef MAPBASE + // Tell the navigation to stop running until we're done. + OnNewGoal(); +#endif } else { @@ -3880,7 +3924,12 @@ bool CAI_Navigator::GetStoppingPath( CAI_WaypointList * pClippedWaypoints ) AI_Waypoint_t *pCurWaypoint = GetPath()->GetCurWaypoint(); if ( pCurWaypoint ) { +#if EXPANDED_NAVIGATION_ACTIVITIES + // Since regular climb nav can interrupt itself now, only do this when dismounting + bool bMustCompleteCurrent = ( (pCurWaypoint->NavType() == NAV_CLIMB && (GetActivity() == ACT_CLIMB_DISMOUNT || GetActivity() == ACT_CLIMB_MOUNT_TOP)) || pCurWaypoint->NavType() == NAV_JUMP ); +#else bool bMustCompleteCurrent = ( pCurWaypoint->NavType() == NAV_CLIMB || pCurWaypoint->NavType() == NAV_JUMP ); +#endif float distRemaining = GetMotor()->MinStoppingDist( 0 ); if ( bMustCompleteCurrent ) diff --git a/game/server/ai_navigator.h b/game/server/ai_navigator.h index c84932be..a2100943 100644 --- a/game/server/ai_navigator.h +++ b/game/server/ai_navigator.h @@ -43,7 +43,7 @@ extern ConVar ai_debug_nav; do \ { \ if (DbgNav()) \ - DevMsg( pAI, "[Nav] %s", static_cast(pszMsg) ); \ + DevMsg( pAI, CFmtStr( "[Nav] %s", static_cast(pszMsg) ) ); \ } while (0) #define DbgNavMsg1( pAI, pszMsg, a ) DbgNavMsg( pAI, CFmtStr(static_cast(pszMsg), (a) ) ) #define DbgNavMsg2( pAI, pszMsg, a, b ) DbgNavMsg( pAI, CFmtStr(static_cast(pszMsg), (a), (b) ) ) diff --git a/game/server/ai_network.cpp b/game/server/ai_network.cpp index 78b7a53f..1323b7ce 100644 --- a/game/server/ai_network.cpp +++ b/game/server/ai_network.cpp @@ -16,6 +16,9 @@ #include "ai_navigator.h" #include "world.h" #include "ai_moveprobe.h" +#ifdef MAPBASE_VSCRIPT +#include "ai_hint.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -31,6 +34,53 @@ extern float MOVE_HEIGHT_EPSILON; // later point we will probabaly have multiple AINetworkds per level CAI_Network* g_pBigAINet; +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CAI_Network, SCRIPT_SINGLETON "The global list of AI nodes." ) + DEFINE_SCRIPTFUNC( NumNodes, "Number of nodes in the level" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodePosition, "GetNodePosition", "Get position of node using a generic human hull" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodePositionWithHull, "GetNodePositionWithHull", "Get position of node using the specified hull" ) + DEFINE_SCRIPTFUNC( GetNodeYaw, "Get yaw of node" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptNearestNodeToPoint, "NearestNodeToPoint", "Get ID of nearest node" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptNearestNodeToPointWithNPC, "NearestNodeToPointForNPC", "Get ID of nearest node using the specified NPC's properties" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodeType, "GetNodeType", "Get a node's type" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodeHint, "GetNodeHint", "Get a node's hint" ) +END_SCRIPTDESC(); + +HSCRIPT CAI_Network::ScriptGetNodeHint( int nodeID ) +{ + CAI_Node *pNode = GetNode( nodeID ); + if (!pNode) + return NULL; + + return ToHScript( pNode->GetHint() ); +} + +int CAI_Network::ScriptGetNodeType( int nodeID ) +{ + CAI_Node *pNode = GetNode( nodeID ); + if (!pNode) + return NULL; + + return (int)pNode->GetType(); +} + +int CAI_Network::ScriptNearestNodeToPointWithNPC( HSCRIPT hNPC, const Vector &vecPosition, bool bCheckVisibility ) +{ + CBaseEntity *pEnt = ToEnt( hNPC ); + if (!pEnt || !pEnt->MyNPCPointer()) + { + Warning("vscript: NearestNodeToPointWithNPC - Invalid NPC\n"); + return NO_NODE; + } + + return NearestNodeToPoint( pEnt->MyNPCPointer(), vecPosition, bCheckVisibility ); +} +#endif + //----------------------------------------------------------------------------- abstract_class INodeListFilter @@ -94,6 +144,31 @@ class CNodeFilter : public INodeListFilter int m_capabilities; // cache this }; +#ifdef MAPBASE +//------------------------------------- +// Purpose: A version of CNodeFilter which allows hints to influence the result. +//------------------------------------- +class CNodeHintFilter : public CNodeFilter +{ +public: + CNodeHintFilter( CAI_BaseNPC *pNPC, const Vector &pos ) : CNodeFilter( pNPC, pos ) {} + CNodeHintFilter( const Vector &pos ) : CNodeFilter( pos ) {} + + virtual float NodeDistanceSqr( CAI_Node &node ) + { + // Heavier hints are considered closer + if ( node.GetHint() && node.GetHint()->GetHintWeight() != 1.0f && (node.GetHint()->GetGroup() == NULL_STRING || node.GetHint()->GetGroup() == m_pNPC->GetHintGroup()) ) + { + return CNodeFilter::NodeDistanceSqr( node ) * node.GetHint()->GetHintWeightInverse(); + } + else + { + return CNodeFilter::NodeDistanceSqr( node ); + } + } +}; +#endif + //----------------------------------------------------------------------------- // CAI_Network //----------------------------------------------------------------------------- @@ -301,7 +376,12 @@ int CAI_Network::NearestNodeToPoint( CAI_BaseNPC *pNPC, const Vector &vecOrigin, // First get nodes distances and eliminate those that are beyond // the maximum allowed distance for local movements // --------------------------------------------------------------- +#ifdef MAPBASE + // Allow hint weight to influence supposed distance + CNodeHintFilter filter( pNPC, vecOrigin ); +#else CNodeFilter filter( pNPC, vecOrigin ); +#endif #ifdef AI_PERF_MON m_nPerfStatNN++; @@ -555,8 +635,13 @@ CAI_Node *CAI_Network::AddNode( const Vector &origin, float yaw ) CAI_Link *CAI_Network::CreateLink( int srcID, int destID, CAI_DynamicLink *pDynamicLink ) { +#ifdef MAPBASE // From Alien Swarm SDK + CAI_Node *pSrcNode = GetNode( srcID ); + CAI_Node *pDestNode = GetNode( destID ); +#else CAI_Node *pSrcNode = g_pBigAINet->GetNode( srcID ); CAI_Node *pDestNode = g_pBigAINet->GetNode( destID ); +#endif Assert( pSrcNode && pDestNode && pSrcNode != pDestNode ); diff --git a/game/server/ai_network.h b/game/server/ai_network.h index 8cebd16a..a86d89b8 100644 --- a/game/server/ai_network.h +++ b/game/server/ai_network.h @@ -127,6 +127,17 @@ class CAI_Network : public IPartitionEnumerator } CAI_Node** AccessNodes() const { return m_pAInode; } + +#ifdef MAPBASE_VSCRIPT + Vector ScriptGetNodePosition( int nodeID ) { return GetNodePosition( HULL_HUMAN, nodeID ); } + Vector ScriptGetNodePositionWithHull( int nodeID, int hull ) { return GetNodePosition( (Hull_t)hull, nodeID ); } + + int ScriptNearestNodeToPoint( const Vector &vecPosition, bool bCheckVisibility = true ) { return NearestNodeToPoint( NULL, vecPosition, bCheckVisibility ); } + int ScriptNearestNodeToPointWithNPC( HSCRIPT hNPC, const Vector &vecPosition, bool bCheckVisibility = true ); + + HSCRIPT ScriptGetNodeHint( int nodeID ); + int ScriptGetNodeType( int nodeID ); +#endif private: friend class CAI_NetworkManager; diff --git a/game/server/ai_networkmanager.cpp b/game/server/ai_networkmanager.cpp index 21a6f9de..10fb51ff 100644 --- a/game/server/ai_networkmanager.cpp +++ b/game/server/ai_networkmanager.cpp @@ -25,6 +25,9 @@ #include "ndebugoverlay.h" #include "ai_hint.h" #include "tier0/icommandline.h" +#ifdef MAPBASE +#include "gameinterface.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -69,6 +72,14 @@ CON_COMMAND( ai_debug_node_connect, "Debug the attempted connection between two // line to properly override the node graph building. ConVar g_ai_norebuildgraph( "ai_norebuildgraph", "0" ); +#ifdef MAPBASE +ConVar g_ai_norebuildgraphmessage( "ai_norebuildgraphmessage", "0", FCVAR_ARCHIVE, "Stops the \"Node graph out of date\" message from appearing when rebuilding node graph" ); + +ConVar g_ai_norebuildgraph_if_in_chapters( "ai_norebuildgraph_if_in_chapters", "0", FCVAR_NONE, "Ignores rebuilding nodegraph if it's in chapters.txt. This allows for bypassing problems with Steam rebuilding nodegraphs in a mod's main maps without affecting custom maps." ); + +extern CUtlVector *Mapbase_GetChapterMaps(); +extern CUtlVector *Mapbase_GetChapterList(); +#endif //----------------------------------------------------------------------------- @@ -945,6 +956,13 @@ void CAI_NetworkManager::InitializeAINetworks() } } +#ifdef MAPBASE_VSCRIPT + if (g_pScriptVM) + { + g_pScriptVM->RegisterInstance( g_pBigAINet, "AINetwork" ); + } +#endif + // Reset node counter used during load CNodeEnt::m_nNodeCount = 0; @@ -976,6 +994,24 @@ bool CAI_NetworkManager::IsAIFileCurrent ( const char *szMapName ) // dvd build process validates and guarantees correctness, timestamps are allowed to be wrong return true; } + +#ifdef MAPBASE + if (g_ai_norebuildgraph_if_in_chapters.GetBool()) + { + // Look in the mod's chapter list. If this map is part of one of the chapters, consider it to have a good node graph + CUtlVector *ModChapterComments = Mapbase_GetChapterMaps(); + if (ModChapterComments->Count() > 0) + { + for ( int i = 0; i < ModChapterComments->Count(); i++ ) + { + if ( !Q_strnicmp( STRING(gpGlobals->mapname), ModChapterComments->Element(i).pBSPName, strlen(ModChapterComments->Element(i).pBSPName) ) ) + { + return true; + } + } + } + } +#endif { const char *pGameDir = CommandLine()->ParmValue( "-game", "hl2" ); @@ -1110,9 +1146,18 @@ void CAI_NetworkManager::DelayedInit( void ) #endif DevMsg( "Node Graph out of Date. Rebuilding... (%d, %d, %d)\n", (int)m_bDontSaveGraph, (int)!CAI_NetworkManager::NetworksLoaded(), (int) engine->IsInEditMode() ); +#ifdef MAPBASE + if (!g_ai_norebuildgraphmessage.GetBool()) + UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" ); + + // Do it much sooner after map load + g_pAINetworkManager->SetNextThink( gpGlobals->curtime + 0.5 ); + m_bNeedGraphRebuild = true; +#else UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" ); m_bNeedGraphRebuild = true; g_pAINetworkManager->SetNextThink( gpGlobals->curtime + 1 ); +#endif return; } @@ -3040,6 +3085,16 @@ int CAI_NetworkBuilder::ComputeConnection( CAI_Node *pSrcNode, CAI_Node *pDestNo } else { +#ifdef MAPBASE + // This is kind of a hack since target node IDs are designed to be used *after* the nodegraph is generated. + // However, for the purposes of forcing a climb connection outside of regular lineup bounds, it seems to be a reasonable solution. + if (pSrcNode->GetHint() && pDestNode->GetHint() && + (pSrcNode->GetHint()->GetTargetWCNodeID() == pDestNode->GetHint()->GetWCId() || pDestNode->GetHint()->GetTargetWCNodeID() == pSrcNode->GetHint()->GetWCId())) + { + DebugConnectMsg( srcId, destId, " Ignoring climbing lineup due to manual target ID linkage\n" ); + } + else +#endif if ( !IsInLineForClimb(srcPos, UTIL_YawToVector( pSrcNode->m_flYaw ), destPos, UTIL_YawToVector( pDestNode->m_flYaw ) ) ) { Assert( !IsInLineForClimb(destPos, UTIL_YawToVector( pDestNode->m_flYaw ), srcPos, UTIL_YawToVector( pSrcNode->m_flYaw ) ) ); diff --git a/game/server/ai_pathfinder.cpp b/game/server/ai_pathfinder.cpp index 5099925e..61c641a5 100644 --- a/game/server/ai_pathfinder.cpp +++ b/game/server/ai_pathfinder.cpp @@ -597,6 +597,17 @@ bool CAI_Pathfinder::IsLinkUsable(CAI_Link *pLink, int startID) // -------------------------------------------------------------------------- // Skip if link turned off // -------------------------------------------------------------------------- +#ifdef MAPBASE + if (pLink->m_pDynamicLink) + { + if (!pLink->m_pDynamicLink->UseAllowed(GetOuter(), startID == pLink->m_pDynamicLink->m_nDestID)) + return false; + } + else if (pLink->m_LinkInfo & bits_LINK_OFF) + { + return false; + } +#else if (pLink->m_LinkInfo & bits_LINK_OFF) { CAI_DynamicLink *pDynamicLink = pLink->m_pDynamicLink; @@ -618,6 +629,7 @@ bool CAI_Pathfinder::IsLinkUsable(CAI_Link *pLink, int startID) return false; } } +#endif // -------------------------------------------------------------------------- // Get the destination nodeID @@ -691,6 +703,12 @@ bool CAI_Pathfinder::IsLinkUsable(CAI_Link *pLink, int startID) return false; } } +#ifdef MAPBASE + if (pLink->m_pDynamicLink) + { + return pLink->m_pDynamicLink->FinalUseAllowed(GetOuter(), startID == pLink->m_pDynamicLink->m_nDestID); + } +#endif return true; } diff --git a/game/server/ai_playerally.cpp b/game/server/ai_playerally.cpp index 1ce4da31..eaf8d6ce 100644 --- a/game/server/ai_playerally.cpp +++ b/game/server/ai_playerally.cpp @@ -12,6 +12,9 @@ #include "eventqueue.h" #include "ai_behavior_lead.h" #include "gameinterface.h" +#ifdef MAPBASE +#include "mapbase/matchers.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -54,7 +57,7 @@ ConceptInfo_t g_ConceptInfos[] = { TLK_USE, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_STARTFOLLOW, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_STOPFOLLOW, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, - { TLK_JOINPLAYER, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, + { TLK_JOINPLAYER, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_STOP, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_NOSHOOT, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_PLHURT1, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, @@ -98,7 +101,7 @@ ConceptInfo_t g_ConceptInfos[] = { TLK_SPOTTED_HEADCRAB_LEAVING_ZOMBIE,SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_DANGER_ZOMBINE_GRENADE, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_BALLSOCKETED, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, - + // Darkness mode { TLK_DARKNESS_LOSTPLAYER, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, { TLK_DARKNESS_FOUNDPLAYER, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, @@ -124,26 +127,37 @@ ConceptInfo_t g_ConceptInfos[] = { TLK_LEAD_IDLE, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, // Passenger behaviour - { TLK_PASSENGER_NEW_RADAR_CONTACT, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, + { TLK_PASSENGER_NEW_RADAR_CONTACT, SPEECH_IMPORTANT, -1, -1, -1, -1, -1, -1, AICF_DEFAULT, }, }; //----------------------------------------------------------------------------- -bool ConceptStringLessFunc( const string_t &lhs, const string_t &rhs ) -{ - return CaselessStringLessThan( STRING(lhs), STRING(rhs) ); +bool ConceptStringLessFunc( const string_t &lhs, const string_t &rhs ) +{ + return CaselessStringLessThan( STRING(lhs), STRING(rhs) ); +} + +#ifdef NEW_RESPONSE_SYSTEM +bool ConceptInfoStringLessFunc( const AIConcept_t& lhs, const AIConcept_t& rhs ) +{ + return CaselessStringLessThan( lhs.GetStringConcept(), rhs.GetStringConcept() ); } +#endif //----------------------------------------------------------------------------- class CConceptInfoMap : public CUtlMap { public: CConceptInfoMap() : +#ifdef NEW_RESPONSE_SYSTEM + CUtlMap( ConceptInfoStringLessFunc ) +#else CUtlMap( CaselessStringLessThan ) +#endif { for ( int i = 0; i < ARRAYSIZE(g_ConceptInfos); i++ ) { - Insert( g_ConceptInfos[i].concept, &g_ConceptInfos[i] ); + Insert( g_ConceptInfos[i].conceptId, &g_ConceptInfos[i] ); } } }; @@ -166,7 +180,7 @@ void CAI_AllySpeechManager::Spawn() { Assert( g_ConceptInfoMap.Count() != 0 ); for ( int i = 0; i < ARRAYSIZE(g_ConceptInfos); i++ ) - m_ConceptTimers.Insert( AllocPooledString( g_ConceptInfos[i].concept ), CSimpleSimTimer() ); + m_ConceptTimers.Insert( AllocPooledString( g_ConceptInfos[i].conceptId ), CSimpleSimTimer() ); } void CAI_AllySpeechManager::AddCustomConcept( const ConceptInfo_t &conceptInfo ) @@ -174,14 +188,14 @@ void CAI_AllySpeechManager::AddCustomConcept( const ConceptInfo_t &conceptInfo ) Assert( g_ConceptInfoMap.Count() != 0 ); Assert( m_ConceptTimers.Count() != 0 ); - if ( g_ConceptInfoMap.Find( conceptInfo.concept ) == g_ConceptInfoMap.InvalidIndex() ) + if ( g_ConceptInfoMap.Find( conceptInfo.conceptId ) == g_ConceptInfoMap.InvalidIndex() ) { - g_ConceptInfoMap.Insert( conceptInfo.concept, new ConceptInfo_t( conceptInfo ) ); + g_ConceptInfoMap.Insert( conceptInfo.conceptId, new ConceptInfo_t( conceptInfo ) ); } - if ( m_ConceptTimers.Find( AllocPooledString(conceptInfo.concept) ) == m_ConceptTimers.InvalidIndex() ) + if ( m_ConceptTimers.Find( AllocPooledString(conceptInfo.conceptId) ) == m_ConceptTimers.InvalidIndex() ) { - m_ConceptTimers.Insert( AllocPooledString( conceptInfo.concept ), CSimpleSimTimer() ); + m_ConceptTimers.Insert( AllocPooledString( conceptInfo.conceptId ), CSimpleSimTimer() ); } } @@ -190,22 +204,22 @@ ConceptCategoryInfo_t *CAI_AllySpeechManager::GetConceptCategoryInfo( ConceptCat return &g_ConceptCategoryInfos[category]; } -ConceptInfo_t *CAI_AllySpeechManager::GetConceptInfo( AIConcept_t concept ) +ConceptInfo_t *CAI_AllySpeechManager::GetConceptInfo( AIConcept_t conceptId ) { - int iResult = g_ConceptInfoMap.Find( concept ); + int iResult = g_ConceptInfoMap.Find( conceptId ); return ( iResult != g_ConceptInfoMap.InvalidIndex() ) ? g_ConceptInfoMap[iResult] : NULL; } -void CAI_AllySpeechManager::OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t concept, AI_Response *response ) +void CAI_AllySpeechManager::OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t conceptId, AI_Response *response ) { - ConceptInfo_t * pConceptInfo = GetConceptInfo( concept ); + ConceptInfo_t * pConceptInfo = GetConceptInfo( conceptId ); ConceptCategory_t category = ( pConceptInfo ) ? pConceptInfo->category : SPEECH_IDLE; ConceptCategoryInfo_t * pCategoryInfo = GetConceptCategoryInfo( category ); if ( pConceptInfo ) { - if ( pConceptInfo->flags & AICF_PROPAGATE_SPOKEN ) + if ( pConceptInfo->flags & AICF_PROPAGATE_SPOKEN ) { CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); CAI_PlayerAlly *pTalker; @@ -213,12 +227,12 @@ void CAI_AllySpeechManager::OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConce { pTalker = dynamic_cast(ppAIs[i]); - if ( pTalker && pTalker != pPlayerAlly && - (pTalker->GetAbsOrigin() - pPlayerAlly->GetAbsOrigin()).LengthSqr() < Square(TALKRANGE_MIN * 2) && + if ( pTalker && pTalker != pPlayerAlly && + (pTalker->GetAbsOrigin() - pPlayerAlly->GetAbsOrigin()).LengthSqr() < Square(TALKRANGE_MIN * 2) && pPlayerAlly->FVisible( pTalker ) ) { // Tell this guy he's already said the concept to the player, too. - pTalker->GetExpresser()->SetSpokeConcept( concept, NULL, false ); + pTalker->GetExpresser()->SetSpokeConcept( conceptId, NULL, false ); } } } @@ -249,29 +263,29 @@ void CAI_AllySpeechManager::OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConce if ( pConceptInfo && pConceptInfo->minConceptDelay != -1 ) { Assert( pConceptInfo->maxConceptDelay != -1 ); - char iConceptTimer = m_ConceptTimers.Find( MAKE_STRING(concept) ); + char iConceptTimer = m_ConceptTimers.Find( MAKE_STRING(conceptId) ); if ( iConceptTimer != m_ConceptTimers.InvalidIndex() ) m_ConceptTimers[iConceptTimer].Set( pConceptInfo->minConceptDelay, pConceptInfo->minConceptDelay ); } } } -void CAI_AllySpeechManager::SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay ) -{ +void CAI_AllySpeechManager::SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay ) +{ if ( category != SPEECH_PRIORITY ) - m_ConceptCategoryTimers[category].Set( minDelay, maxDelay ); + m_ConceptCategoryTimers[category].Set( minDelay, maxDelay ); } -bool CAI_AllySpeechManager::CategoryDelayExpired( ConceptCategory_t category ) -{ +bool CAI_AllySpeechManager::CategoryDelayExpired( ConceptCategory_t category ) +{ if ( category == SPEECH_PRIORITY ) return true; - return m_ConceptCategoryTimers[category].Expired(); + return m_ConceptCategoryTimers[category].Expired(); } -bool CAI_AllySpeechManager::ConceptDelayExpired( AIConcept_t concept ) +bool CAI_AllySpeechManager::ConceptDelayExpired( AIConcept_t conceptId ) { - char iConceptTimer = m_ConceptTimers.Find( MAKE_STRING(concept) ); + char iConceptTimer = m_ConceptTimers.Find( MAKE_STRING(conceptId) ); if ( iConceptTimer != m_ConceptTimers.InvalidIndex() ) return m_ConceptTimers[iConceptTimer].Expired(); return true; @@ -338,6 +352,9 @@ BEGIN_DATADESC( CAI_PlayerAlly ) DEFINE_INPUTFUNC( FIELD_STRING, "SpeakResponseConcept", InputSpeakResponseConcept ), DEFINE_INPUTFUNC( FIELD_VOID, "MakeGameEndAlly", InputMakeGameEndAlly ), DEFINE_INPUTFUNC( FIELD_VOID, "MakeRegularAlly", InputMakeRegularAlly ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "AskQuestion", InputAskQuestion ), +#endif DEFINE_INPUTFUNC( FIELD_INTEGER, "AnswerQuestion", InputAnswerQuestion ), DEFINE_INPUTFUNC( FIELD_INTEGER, "AnswerQuestionHello", InputAnswerQuestionHello ), DEFINE_INPUTFUNC( FIELD_VOID, "EnableSpeakWhileScripting", InputEnableSpeakWhileScripting ), @@ -368,7 +385,7 @@ void CAI_PlayerAlly::DisplayDeathMessage( void ) CBaseEntity *pPlayer = AI_GetSinglePlayer(); - if ( pPlayer ) + if ( pPlayer ) { UTIL_ShowMessage( GetDeathMessageText(), ToBasePlayer( pPlayer ) ); ToBasePlayer(pPlayer)->NotifySinglePlayerGameEnding(); @@ -393,14 +410,14 @@ void CAI_PlayerAlly::DisplayDeathMessage( void ) //----------------------------------------------------------------------------- void CAI_PlayerAlly::TalkInit( void ) { -} +} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_PlayerAlly::GatherConditions( void ) { BaseClass::GatherConditions(); - + if ( !HasCondition( COND_SEE_PLAYER ) ) { SetCondition( COND_TALKER_CLIENTUNSEEN ); @@ -419,10 +436,10 @@ void CAI_PlayerAlly::GatherConditions( void ) { SetCondition( COND_TALKER_PLAYER_DEAD ); } - + if ( HasCondition( COND_SEE_PLAYER ) ) { - + bool bPlayerIsLooking = false; if ( ( pLocalPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2DSqr() < Square(TALKER_STARE_DIST) ) { @@ -432,7 +449,7 @@ void CAI_PlayerAlly::GatherConditions( void ) bPlayerIsLooking = true; } } - + if ( bPlayerIsLooking ) { SetCondition( COND_TALKER_PLAYER_STARING ); @@ -463,14 +480,14 @@ void CAI_PlayerAlly::GatherEnemyConditions( CBaseEntity *pEnemy ) if( pPlayer ) { - + // If I can see the player, and the player would see this enemy if he turned around... if( !pPlayer->FInViewCone(pEnemy) && FVisible( pPlayer ) && pPlayer->FVisible(pEnemy) ) { Vector2D vecPlayerView = pPlayer->EyeDirection2D().AsVector2D(); Vector2D vecToEnemy = ( pEnemy->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).AsVector2D(); Vector2DNormalize( vecToEnemy ); - + if( DotProduct2D(vecPlayerView, vecToEnemy) <= -0.75 ) { SpeakIfAllowed( TLK_WATCHOUT, "dangerloc:behind" ); @@ -500,7 +517,7 @@ void CAI_PlayerAlly::OnStateChange( NPC_STATE OldState, NPC_STATE NewState ) { DeferAllIdleSpeech(); } - + if ( GetState() == NPC_STATE_IDLE || GetState() == NPC_STATE_ALERT ) { m_flNextIdleSpeechTime = gpGlobals->curtime + RandomFloat(5,10); @@ -542,17 +559,20 @@ void CAI_PlayerAlly::PrescheduleThink( void ) } #ifdef HL2_EPISODIC - if ( (GetState() == NPC_STATE_IDLE || GetState() == NPC_STATE_ALERT) + if ( (GetState() == NPC_STATE_IDLE || GetState() == NPC_STATE_ALERT) && !HasCondition(COND_RECEIVED_ORDERS) && !IsInAScript() ) { if ( m_flNextIdleSpeechTime && m_flNextIdleSpeechTime < gpGlobals->curtime ) { AISpeechSelection_t selection; - if ( SelectNonCombatSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); +#ifdef NEW_RESPONSE_SYSTEM + SpeakDispatchResponse( selection.conceptId.c_str(), &selection.Response ); +#else + SpeakDispatchResponse( selection.conceptId.c_str(), selection.pResponse ); +#endif m_flNextIdleSpeechTime = gpGlobals->curtime + RandomFloat( 20,30 ); } else @@ -590,28 +610,39 @@ int CAI_PlayerAlly::SelectSchedule( void ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool CAI_PlayerAlly::SelectSpeechResponse( AIConcept_t concept, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ) +bool CAI_PlayerAlly::SelectSpeechResponse( AIConcept_t conceptId, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ) { - if ( IsAllowedToSpeak( concept ) ) + if ( IsAllowedToSpeak( conceptId ) ) { - bool result = SpeakFindResponse( pSelection->Response, concept, pszModifiers ); +#ifdef NEW_RESPONSE_SYSTEM + bool result = SpeakFindResponse( pSelection->Response, conceptId, pszModifiers ); if ( result ) { - pSelection->concept = concept; + pSelection->conceptId = conceptId; pSelection->hSpeechTarget = pTarget; return true; } +#else + AI_Response *pResponse = SpeakFindResponse( conceptId, pszModifiers ); + if ( pResponse ) + { + pSelection->Set( conceptId, pResponse, pTarget ); + return true; + } +#endif } - return false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CAI_PlayerAlly::SetPendingSpeech( AIConcept_t concept, AI_Response &Response ) +void CAI_PlayerAlly::SetPendingSpeech( AIConcept_t conceptId, AI_Response *pResponse ) { - m_PendingResponse = Response; - m_PendingConcept = concept; + m_PendingResponse = *pResponse; +#ifndef NEW_RESPONSE_SYSTEM + pResponse->Release(); +#endif + m_PendingConcept = conceptId; m_TimePendingSet = gpGlobals->curtime; } @@ -636,7 +667,7 @@ bool CAI_PlayerAlly::SelectIdleSpeech( AISpeechSelection_t *pSelection ) { if ( SelectSpeechResponse( TLK_HELLO, NULL, pTarget, pSelection ) ) return true; - + if ( GetTimePlayerStaring() > 6 && !IsMoving() ) { if ( SelectSpeechResponse( TLK_STARE, NULL, pTarget, pSelection ) ) @@ -651,7 +682,7 @@ bool CAI_PlayerAlly::SelectIdleSpeech( AISpeechSelection_t *pSelection ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_PlayerAlly::SelectAlertSpeech( AISpeechSelection_t *pSelection ) { @@ -692,7 +723,11 @@ bool CAI_PlayerAlly::SelectInterjection() if ( SelectIdleSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); +#ifdef NEW_RESPONSE_SYSTEM + SpeakDispatchResponse( selection.conceptId.c_str(), &selection.Response ); +#else + SpeakDispatchResponse( selection.conceptId.c_str(), selection.pResponse ); +#endif return true; } } @@ -711,12 +746,12 @@ bool CAI_PlayerAlly::SelectPlayerUseSpeech() DeferAllIdleSpeech(); else return Speak( ( !GetExpresser()->SpokeConcept( TLK_HELLO ) ) ? TLK_HELLO : TLK_IDLE ); - } + } return false; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_PlayerAlly::SelectQuestionAndAnswerSpeech( AISpeechSelection_t *pSelection ) { @@ -727,24 +762,29 @@ bool CAI_PlayerAlly::SelectQuestionAndAnswerSpeech( AISpeechSelection_t *pSelect return false; // if there is a friend nearby to speak to, play sentence, set friend's response time, return +#ifdef MAPBASE + CAI_PlayerAlly *pFriend = dynamic_cast(FindSpeechTarget( AIST_NPCS | AIST_NOT_GAGGED )); + if ( pFriend && !pFriend->IsMoving() ) +#else CAI_PlayerAlly *pFriend = dynamic_cast(FindSpeechTarget( AIST_NPCS )); if ( pFriend && !pFriend->IsMoving() && !pFriend->HasSpawnFlags(SF_NPC_GAG) ) +#endif return SelectQuestionFriend( pFriend, pSelection ); return false; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -void CAI_PlayerAlly::PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ) +void CAI_PlayerAlly::PostSpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ) { #ifdef HL2_EPISODIC CAI_AllySpeechManager *pSpeechManager = GetAllySpeechManager(); - ConceptInfo_t *pConceptInfo = pSpeechManager->GetConceptInfo( concept ); + ConceptInfo_t *pConceptInfo = pSpeechManager->GetConceptInfo( conceptId ); if ( pConceptInfo && (pConceptInfo->flags & AICF_QUESTION) && GetSpeechTarget() ) { - bool bSaidHelloToNPC = !Q_strcmp(concept, "TLK_HELLO_NPC"); + bool bSaidHelloToNPC = !Q_strcmp(conceptId, "TLK_HELLO_NPC"); float duration = GetExpresser()->GetSemaphoreAvailableTime(this) - gpGlobals->curtime; @@ -752,11 +792,11 @@ void CAI_PlayerAlly::PostSpeakDispatchResponse( AIConcept_t concept, AI_Response { if ( bSaidHelloToNPC ) { - Warning("Q&A: '%s' said Hello to '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), concept ); + Warning("Q&A: '%s' said Hello to '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), (const char*)conceptId ); } else { - Warning("Q&A: '%s' questioned '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), concept ); + Warning("Q&A: '%s' questioned '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), (const char*)conceptId ); } NDebugOverlay::HorzArrow( GetAbsOrigin(), GetSpeechTarget()->GetAbsOrigin(), 8, 0, 255, 0, 64, true, duration ); } @@ -818,7 +858,17 @@ bool CAI_PlayerAlly::SelectQuestionFriend( CBaseEntity *pFriend, AISpeechSelecti // If we haven't said hello, say hello first. // Only ever say hello to NPCs other than my type. +#ifdef MAPBASE + // Why only say hello to NPCs other than my type? + // Are citizens a hivemind? Do they not greet each other? + // They don't have any responses for it anyway, so SelectSpeechResponse() will fail + // and TLK_HELLO_NPC will be marked as spoken. + // + // Responses could be added so modders/mappers can take advantage of this. + if ( !GetExpresser()->SpokeConcept( TLK_HELLO_NPC ) ) +#else if ( !GetExpresser()->SpokeConcept( TLK_HELLO_NPC ) && !FClassnameIs( this, pFriend->GetClassname()) ) +#endif { if ( SelectSpeechResponse( TLK_HELLO_NPC, NULL, pFriend, pSelection ) ) return true; @@ -846,8 +896,89 @@ bool CAI_PlayerAlly::SelectAnswerFriend( CBaseEntity *pFriend, AISpeechSelection return SelectSpeechResponse( TLK_ANSWER, NULL, pFriend, pSelection ); } +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: +// Purpose: Asks a question now. +//----------------------------------------------------------------------------- +bool CAI_PlayerAlly::AskQuestionNow( CBaseEntity *pSpeechTarget, int iQARandomNumber, const char *conceptId ) +{ + m_hPotentialSpeechTarget = pSpeechTarget; + m_iQARandomNumber = iQARandomNumber; + + if (!m_hPotentialSpeechTarget) + m_hPotentialSpeechTarget = /*dynamic_cast*/(FindSpeechTarget( AIST_NPCS | AIST_NOT_GAGGED )); + + if (m_iQARandomNumber == -1) + m_iQARandomNumber = RandomInt(0, 100); + + AISpeechSelection_t selection; +#ifdef NEW_RESPONSE_SYSTEM + if (SelectSpeechResponse( conceptId, NULL, m_hPotentialSpeechTarget.Get(), &selection )) + { + SetSpeechTarget( selection.hSpeechTarget ); + ClearPendingSpeech(); + + // Speak immediately + return SpeakDispatchResponse( selection.conceptId.c_str(), &selection.Response ); + } + + return false; +#else + SelectSpeechResponse( conceptId, NULL, m_hPotentialSpeechTarget.Get(), &selection ); + + SetSpeechTarget( selection.hSpeechTarget ); + ClearPendingSpeech(); + + if (!selection.pResponse) + return false; + + // Speak immediately + return SpeakDispatchResponse( selection.conceptId.c_str(), selection.pResponse ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_PlayerAlly::InputAskQuestion( inputdata_t &inputdata ) +{ + CBaseEntity *pSpeechTarget = NULL; + int iQARandomNumber = 0; + const char *conceptId = TLK_QUESTION; + + // I didn't feel like using strtok today. + CUtlStringList vecStrings; + V_SplitString(inputdata.value.String(), " ", vecStrings); + FOR_EACH_VEC( vecStrings, i ) + { + // 0 : QA Number (-1 for N/A) + // 1 : Speech Target + // 2 : Concept + switch (i) + { + case 0: iQARandomNumber = atoi(vecStrings[i]); break; + case 1: pSpeechTarget = gEntList.FindEntityByName(NULL, vecStrings[i], this, inputdata.pActivator, inputdata.pCaller); break; + case 2: conceptId = vecStrings[i]; break; + } + } + + if (pSpeechTarget == NULL) + { + CAI_PlayerAlly *pFriend = dynamic_cast(FindSpeechTarget( AIST_NPCS | AIST_NOT_GAGGED )); + if ( pFriend ) + pSpeechTarget = pFriend; + } + else if (pSpeechTarget == this) + { + pSpeechTarget = NULL; + } + + AskQuestionNow(pSpeechTarget, iQARandomNumber, conceptId); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: //----------------------------------------------------------------------------- void CAI_PlayerAlly::InputAnswerQuestion( inputdata_t &inputdata ) { @@ -855,7 +986,7 @@ void CAI_PlayerAlly::InputAnswerQuestion( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_PlayerAlly::InputAnswerQuestionHello( inputdata_t &inputdata ) { @@ -863,7 +994,7 @@ void CAI_PlayerAlly::InputAnswerQuestionHello( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_PlayerAlly::AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomNum, bool bAnsweringHello ) { @@ -892,7 +1023,12 @@ void CAI_PlayerAlly::AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomN } SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); +#ifdef NEW_RESPONSE_SYSTEM + SpeakDispatchResponse( selection.conceptId.c_str(), &selection.Response ); +#else + Assert( selection.pResponse ); + SpeakDispatchResponse( selection.conceptId.c_str(), selection.pResponse ); +#endif // Prevent idle speech for a while DeferAllIdleSpeech( random->RandomFloat( TALKER_DEFER_IDLE_SPEAK_MIN, TALKER_DEFER_IDLE_SPEAK_MAX ), GetSpeechTarget()->MyNPCPointer() ); @@ -920,7 +1056,7 @@ int CAI_PlayerAlly::SelectNonCombatSpeech( AISpeechSelection_t *pSelection ) if ( !bResult ) { - if ( GetState() == NPC_STATE_ALERT ) + if ( GetState() == NPC_STATE_ALERT ) { bResult = SelectAlertSpeech( pSelection ); } @@ -940,28 +1076,32 @@ int CAI_PlayerAlly::SelectNonCombatSpeechSchedule() if ( !HasPendingSpeech() ) { AISpeechSelection_t selection; - if ( SelectNonCombatSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SetPendingSpeech( selection.concept.c_str(), selection.Response ); +#ifdef NEW_RESPONSE_SYSTEM + SetPendingSpeech( selection.conceptId.c_str(), &selection.Response ); +#else + Assert( selection.pResponse ); + SetPendingSpeech( selection.conceptId.c_str(), selection.pResponse ); +#endif } } - + if ( HasPendingSpeech() ) { if ( m_TimePendingSet == gpGlobals->curtime || IsAllowedToSpeak( m_PendingConcept.c_str() ) ) return SCHED_TALKER_SPEAK_PENDING_IDLE; } - + return SCHED_NONE; -} +} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int CAI_PlayerAlly::TranslateSchedule( int schedule ) { - if ( ( GetState() == NPC_STATE_IDLE || GetState() == NPC_STATE_ALERT ) && + if ( ( GetState() == NPC_STATE_IDLE || GetState() == NPC_STATE_ALERT ) && ConditionInterruptsSchedule( schedule, COND_IDLE_INTERRUPT ) && !HasCondition(COND_RECEIVED_ORDERS) ) { @@ -1019,14 +1159,18 @@ void CAI_PlayerAlly::StartTask( const Task_t *pTask ) case TASK_TALKER_SPEAK_PENDING: if ( !m_PendingConcept.empty() ) { - SpeakDispatchResponse( m_PendingConcept.c_str(), m_PendingResponse ); +#ifdef NEW_RESPONSE_SYSTEM + SpeakDispatchResponse( m_PendingConcept.c_str(), &m_PendingResponse ); +#else + AI_Response *pResponse = new AI_Response; + *pResponse = m_PendingResponse; + SpeakDispatchResponse( m_PendingConcept.c_str(), pResponse ); +#endif m_PendingConcept.erase(); TaskComplete(); } else - { TaskFail( FAIL_NO_SOUND ); - } break; default: @@ -1073,21 +1217,43 @@ void CAI_PlayerAlly::Touch( CBaseEntity *pOther ) // Stay put during speech if ( GetExpresser()->IsSpeaking() ) return; - + TestPlayerPushing( pOther ); } } +#ifdef MAPBASE +ConVar mapbase_ally_flinching("mapbase_ally_flinching", "1", FCVAR_ARCHIVE, "Enables/disables the new flinching animations."); +//----------------------------------------------------------------------------- +// Purpose: This is to adjust for the new citizen flinching animations, +// as they would exist on all NPCs that use citizen animations. +// +// Vortigaunts and Alyx in the Episodes are the only ones who can flinch normally, +// and that's been rectified with their own functions. (they currently skip CAI_PlayerAlly's implementation) +//----------------------------------------------------------------------------- +bool CAI_PlayerAlly::CanFlinch( void ) +{ + if (mapbase_ally_flinching.GetBool() != true) + return false; + + return BaseClass::CanFlinch(); +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_PlayerAlly::OnKilledNPC( CBaseCombatCharacter *pKilled ) { if ( pKilled ) { - if ( !pKilled->IsNPC() || + if ( !pKilled->IsNPC() || ( pKilled->MyNPCPointer()->GetLastPlayerDamageTime() == 0 || gpGlobals->curtime - pKilled->MyNPCPointer()->GetLastPlayerDamageTime() > 5 ) ) { +#ifdef MAPBASE + m_hPotentialSpeechTarget = pKilled; + SetSpeechTarget(pKilled); +#endif SpeakIfAllowed( TLK_ENEMY_DEAD ); } } @@ -1175,8 +1341,14 @@ void CAI_PlayerAlly::Event_Killed( const CTakeDamageInfo &info ) CBasePlayer *player = AI_GetSinglePlayer(); if ( player ) { +#ifdef MAPBASE + variant_t variant; + variant.SetEntity(this); + player->AcceptInput( "OnSquadMemberKilled", info.GetAttacker(), this, variant, 0 ); +#else variant_t emptyVariant; player->AcceptInput( "OnSquadMemberKilled", this, this, emptyVariant, 0 ); +#endif } } @@ -1186,6 +1358,10 @@ void CAI_PlayerAlly::Event_Killed( const CTakeDamageInfo &info ) CAI_PlayerAlly *pMourner = dynamic_cast(FindSpeechTarget( AIST_NPCS )); if ( pMourner ) { +#ifdef MAPBASE + pMourner->m_hPotentialSpeechTarget = this; + pMourner->SetSpeechTarget(this); +#endif pMourner->SpeakIfAllowed( TLK_ALLY_KILLED ); } @@ -1198,7 +1374,7 @@ void CAI_PlayerAlly::Event_Killed( const CTakeDamageInfo &info ) DisplayDeathMessage(); } -// Player allies should use simple shadows to save CPU. This means they can't +// Player allies should use simple shadows to save CPU. This means they can't // be killed by crush damage. bool CAI_PlayerAlly::CreateVPhysics() { @@ -1264,7 +1440,7 @@ bool CAI_PlayerAlly::IsValidSpeechTarget( int flags, CBaseEntity *pEntity ) if ( IRelationType( pEntity ) != D_LI ) return false; } - } + } if ( !pEntity->IsAlive() ) // don't dead people @@ -1287,8 +1463,13 @@ bool CAI_PlayerAlly::IsValidSpeechTarget( int flags, CBaseEntity *pEntity ) // Don't bother people who don't want to be bothered if ( !pNPC->CanBeUsedAsAFriend() ) return false; + +#ifdef MAPBASE + if (flags & AIST_NOT_GAGGED && pNPC->HasSpawnFlags(SF_NPC_GAG)) + return false; +#endif } - + if ( flags & AIST_FACING_TARGET ) { if ( pEntity->IsPlayer() ) @@ -1309,7 +1490,7 @@ CBaseEntity *CAI_PlayerAlly::FindSpeechTarget( int flags ) CBaseEntity * pNearest = NULL; float distSq; int i; - + if ( flags & AIST_PLAYERS ) { for ( i = 1; i <= gpGlobals->maxClients; i++ ) @@ -1318,10 +1499,10 @@ CBaseEntity *CAI_PlayerAlly::FindSpeechTarget( int flags ) if ( pPlayer ) { distSq = ( vAbsOrigin - pPlayer->GetAbsOrigin() ).LengthSqr(); - + if ( distSq > Square(TALKRANGE_MIN) ) continue; - + if ( !(flags & AIST_ANY_QUALIFIED) && distSq > closestDistSq ) continue; @@ -1336,7 +1517,7 @@ CBaseEntity *CAI_PlayerAlly::FindSpeechTarget( int flags ) } } } - + if ( flags & AIST_NPCS ) { for ( i = 0; i < g_AI_Manager.NumAIs(); i++ ) @@ -1344,10 +1525,10 @@ CBaseEntity *CAI_PlayerAlly::FindSpeechTarget( int flags ) CAI_BaseNPC *pNPC = (g_AI_Manager.AccessAIs())[i]; distSq = ( vAbsOrigin - pNPC->GetAbsOrigin() ).LengthSqr(); - + if ( distSq > Square(TALKRANGE_MIN) ) continue; - + if ( !(flags & AIST_ANY_QUALIFIED) && distSq > closestDistSq ) continue; @@ -1367,11 +1548,11 @@ CBaseEntity *CAI_PlayerAlly::FindSpeechTarget( int flags ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool CAI_PlayerAlly::CanPlaySentence( bool fDisregardState ) -{ +bool CAI_PlayerAlly::CanPlaySentence( bool fDisregardState ) +{ if ( fDisregardState ) return BaseClass::CanPlaySentence( fDisregardState ); - return IsOkToSpeak(); + return IsOkToSpeak(); } //----------------------------------------------------------------------------- @@ -1381,7 +1562,7 @@ int CAI_PlayerAlly::PlayScriptedSentence( const char *pszSentence, float delay, ClearCondition( COND_PLAYER_PUSHING ); // Forget about moving! I've got something to say! int sentenceIndex = BaseClass::PlayScriptedSentence( pszSentence, delay, volume, soundlevel, bConcurrent, pListener ); SetSpeechTarget( pListener ); - + return sentenceIndex; } @@ -1404,7 +1585,7 @@ void CAI_PlayerAlly::DeferAllIdleSpeech( float flDelay, CAI_BaseNPC *pIgnore ) bool CAI_PlayerAlly::IsOkToSpeak( ConceptCategory_t category, bool fRespondingToPlayer ) { CAI_AllySpeechManager *pSpeechManager = GetAllySpeechManager(); - + // if not alive, certainly don't speak if ( !IsAlive() ) return false; @@ -1523,10 +1704,10 @@ bool CAI_PlayerAlly::IsOkToSpeakInResponseToPlayer( void ) //----------------------------------------------------------------------------- // Purpose: Return true if I should speak based on the chance & the speech filter's modifier //----------------------------------------------------------------------------- -bool CAI_PlayerAlly::ShouldSpeakRandom( AIConcept_t concept, int iChance ) +bool CAI_PlayerAlly::ShouldSpeakRandom( AIConcept_t conceptId, int iChance ) { CAI_AllySpeechManager * pSpeechManager = GetAllySpeechManager(); - ConceptInfo_t * pInfo = pSpeechManager->GetConceptInfo( concept ); + ConceptInfo_t * pInfo = pSpeechManager->GetConceptInfo( conceptId ); ConceptCategory_t category = ( pInfo ) ? pInfo->category : SPEECH_IDLE; if ( GetSpeechFilter() ) @@ -1536,26 +1717,26 @@ bool CAI_PlayerAlly::ShouldSpeakRandom( AIConcept_t concept, int iChance ) float flModifier = GetSpeechFilter()->GetIdleModifier(); if ( flModifier < 0.001 ) return false; - + iChance = floor( (float)iChance / flModifier ); } } - + if ( iChance < 1 ) return false; if ( iChance == 1 ) return true; - + return (random->RandomInt(1,iChance) == 1); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool CAI_PlayerAlly::IsAllowedToSpeak( AIConcept_t concept, bool bRespondingToPlayer ) -{ +bool CAI_PlayerAlly::IsAllowedToSpeak( AIConcept_t conceptId, bool bRespondingToPlayer ) +{ CAI_AllySpeechManager * pSpeechManager = GetAllySpeechManager(); - ConceptInfo_t * pInfo = pSpeechManager->GetConceptInfo( concept ); + ConceptInfo_t * pInfo = pSpeechManager->GetConceptInfo( conceptId ); ConceptCategory_t category = ( pInfo ) ? pInfo->category : SPEECH_IDLE; if ( !IsOkToSpeak( category, bRespondingToPlayer ) ) @@ -1563,46 +1744,70 @@ bool CAI_PlayerAlly::IsAllowedToSpeak( AIConcept_t concept, bool bRespondingToPl if ( GetSpeechFilter() && GetSpeechFilter()->NeverSayHello() ) { - if ( CompareConcepts( concept, TLK_HELLO ) ) + if ( CompareConcepts( conceptId, TLK_HELLO ) ) return false; - if ( CompareConcepts( concept, TLK_HELLO_NPC ) ) + if ( CompareConcepts( conceptId, TLK_HELLO_NPC ) ) return false; } - - if ( !pSpeechManager->ConceptDelayExpired( concept ) ) + + if ( !pSpeechManager->ConceptDelayExpired( conceptId ) ) return false; - if ( ( pInfo && pInfo->flags & AICF_SPEAK_ONCE ) && GetExpresser()->SpokeConcept( concept ) ) + if ( ( pInfo && pInfo->flags & AICF_SPEAK_ONCE ) && GetExpresser()->SpokeConcept( conceptId ) ) return false; - if ( !GetExpresser()->CanSpeakConcept( concept ) ) + if ( !GetExpresser()->CanSpeakConcept( conceptId ) ) return false; - + return true; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool CAI_PlayerAlly::SpeakIfAllowed( AIConcept_t concept, const char *modifiers, bool bRespondingToPlayer, char *pszOutResponseChosen, size_t bufsize ) -{ - if ( IsAllowedToSpeak( concept, bRespondingToPlayer ) ) +bool CAI_PlayerAlly::SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers, bool bRespondingToPlayer, char *pszOutResponseChosen, size_t bufsize ) +{ + if ( IsAllowedToSpeak( conceptId, bRespondingToPlayer ) ) { - return Speak( concept, modifiers, pszOutResponseChosen, bufsize ); + return Speak( conceptId, modifiers, pszOutResponseChosen, bufsize ); } return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CAI_PlayerAlly::SpeakIfAllowed( AIConcept_t conceptId, AI_CriteriaSet& modifiers, bool bRespondingToPlayer, char *pszOutResponseChosen, size_t bufsize ) +{ + if ( IsAllowedToSpeak( conceptId, bRespondingToPlayer ) ) + { + return Speak( conceptId, modifiers, pszOutResponseChosen, bufsize ); + } + return false; +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_PlayerAlly::ModifyOrAppendCriteria( AI_CriteriaSet& set ) { BaseClass::ModifyOrAppendCriteria( set ); +#ifdef MAPBASE + // For the below speechtarget criteria + if (GetSpeechTarget() && !m_hPotentialSpeechTarget) + m_hPotentialSpeechTarget = GetSpeechTarget(); +#endif + if ( m_hPotentialSpeechTarget ) { set.AppendCriteria( "speechtarget", m_hPotentialSpeechTarget->GetClassname() ); set.AppendCriteria( "speechtargetname", STRING(m_hPotentialSpeechTarget->GetEntityName()) ); set.AppendCriteria( "randomnum", UTIL_VarArgs("%d", m_iQARandomNumber) ); + +#ifdef MAPBASE + // Speech target contexts. + m_hPotentialSpeechTarget->AppendContextToCriteria(set, "speechtarget_"); +#endif } // Do we have a speech filter? If so, append it's criteria too @@ -1614,16 +1819,18 @@ void CAI_PlayerAlly::ModifyOrAppendCriteria( AI_CriteriaSet& set ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CAI_PlayerAlly::OnSpokeConcept( AIConcept_t concept, AI_Response *response ) +void CAI_PlayerAlly::OnSpokeConcept( AIConcept_t conceptId, AI_Response *response ) { CAI_AllySpeechManager *pSpeechManager = GetAllySpeechManager(); - pSpeechManager->OnSpokeConcept( this, concept, response ); + pSpeechManager->OnSpokeConcept( this, conceptId, response ); +#ifndef MAPBASE // This has been moved directly to CAI_Expresser if( response != NULL && (response->GetParams()->flags & AI_ResponseParams::RG_WEAPONDELAY) ) { // Stop shooting, as instructed, so that my speech can be heard. GetShotRegulator()->FireNoEarlierThan( gpGlobals->curtime + response->GetWeaponDelay() ); } +#endif } //----------------------------------------------------------------------------- @@ -1661,7 +1868,7 @@ void CAI_PlayerAlly::InputDisableSpeakWhileScripting( inputdata_t &inputdata ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_PlayerAlly::SpeakMapmakerInterruptConcept( string_t iszConcept ) { @@ -1677,7 +1884,7 @@ bool CAI_PlayerAlly::SpeakMapmakerInterruptConcept( string_t iszConcept ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_PlayerAlly::CanRespondToEvent( const char *ResponseConcept ) { @@ -1685,15 +1892,16 @@ bool CAI_PlayerAlly::CanRespondToEvent( const char *ResponseConcept ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_PlayerAlly::RespondedTo( const char *ResponseConcept, bool bForce, bool bCancelScene ) { if ( bForce ) { // We're being forced to respond to the event, probably because it's the - // player dying or something equally important. - AI_Response response; + // player dying or something equally important. +#ifdef NEW_RESPONSE_SYSTEM + AI_Response response; bool result = SpeakFindResponse( response, ResponseConcept, NULL ); if ( result ) { @@ -1701,8 +1909,20 @@ bool CAI_PlayerAlly::RespondedTo( const char *ResponseConcept, bool bForce, bool if ( bCancelScene ) RemoveActorFromScriptedScenes( this, false ); - return SpeakDispatchResponse( ResponseConcept, response ); + return SpeakDispatchResponse( ResponseConcept, &response ); } +#else + AI_Response *result = SpeakFindResponse( ResponseConcept, NULL ); + if ( result ) + { + // We've got something to say. Stop any scenes we're in, and speak the response. + if ( bCancelScene ) + RemoveActorFromScriptedScenes( this, false ); + + bool spoke = SpeakDispatchResponse( ResponseConcept, result ); + return spoke; + } +#endif return false; } @@ -1730,7 +1950,7 @@ AI_BEGIN_CUSTOM_NPC(talk_monster_base,CAI_PlayerAlly) //========================================================= // > SCHED_TALKER_SPEAK_PENDING_IDLE //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_TALKER_SPEAK_PENDING_IDLE, @@ -1754,7 +1974,7 @@ AI_BEGIN_CUSTOM_NPC(talk_monster_base,CAI_PlayerAlly) //========================================================= // > SCHED_TALKER_SPEAK_PENDING_ALERT //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_TALKER_SPEAK_PENDING_ALERT, @@ -1777,7 +1997,7 @@ AI_BEGIN_CUSTOM_NPC(talk_monster_base,CAI_PlayerAlly) //========================================================= // > SCHED_TALKER_SPEAK_PENDING_COMBAT //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_TALKER_SPEAK_PENDING_COMBAT, diff --git a/game/server/ai_playerally.h b/game/server/ai_playerally.h index bd1e5ab4..da719576 100644 --- a/game/server/ai_playerally.h +++ b/game/server/ai_playerally.h @@ -182,7 +182,7 @@ enum AIConceptFlags_t struct ConceptInfo_t { - AIConcept_t concept; + AIConcept_t conceptId; ConceptCategory_t category; float minGlobalCategoryDelay; float maxGlobalCategoryDelay; @@ -206,12 +206,12 @@ class CAI_AllySpeechManager : public CLogicalEntity void AddCustomConcept( const ConceptInfo_t &conceptInfo ); ConceptCategoryInfo_t *GetConceptCategoryInfo( ConceptCategory_t category ); - ConceptInfo_t *GetConceptInfo( AIConcept_t concept ); - void OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t concept, AI_Response *response ); + ConceptInfo_t *GetConceptInfo( AIConcept_t conceptId ); + void OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t conceptId, AI_Response *response ); void SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay = 0.0 ); bool CategoryDelayExpired( ConceptCategory_t category ); - bool ConceptDelayExpired( AIConcept_t concept ); + bool ConceptDelayExpired( AIConcept_t conceptId ); private: @@ -244,13 +244,35 @@ enum AISpeechTargetSearchFlags_t AIST_IGNORE_RELATIONSHIP = (1<<2), AIST_ANY_QUALIFIED = (1<<3), AIST_FACING_TARGET = (1<<4), +#ifdef MAPBASE + // I needed this for something + AIST_NOT_GAGGED = (1<<5), +#endif }; struct AISpeechSelection_t { - std::string concept; +#ifdef NEW_RESPONSE_SYSTEM + std::string conceptId; AI_Response Response; EHANDLE hSpeechTarget; +#else + AISpeechSelection_t() + : pResponse(NULL) + { + } + + void Set( AIConcept_t newConcept, AI_Response *pNewResponse, CBaseEntity *pTarget = NULL ) + { + pResponse = pNewResponse; + conceptId = newConcept; + hSpeechTarget = pTarget; + } + + std::string conceptId; + AI_Response * pResponse; + EHANDLE hSpeechTarget; +#endif }; //------------------------------------- @@ -284,6 +306,10 @@ class CAI_PlayerAlly : public CAI_BaseActor void ClearTransientConditions(); void Touch( CBaseEntity *pOther ); +#ifdef MAPBASE + virtual bool CanFlinch( void ); +#endif + //--------------------------------- // Combat //--------------------------------- @@ -313,6 +339,12 @@ class CAI_PlayerAlly : public CAI_BaseActor CBaseEntity *GetSpeechTarget() { return m_hTalkTarget.Get(); } void SetSpeechTarget( CBaseEntity *pSpeechTarget ) { m_hTalkTarget = pSpeechTarget; } + +#ifdef MAPBASE + // Needed for additional speech target responses + CBaseEntity *GetPotentialSpeechTarget() { return m_hPotentialSpeechTarget.Get(); } + void SetPotentialSpeechTarget( CBaseEntity *pSpeechTarget ) { m_hPotentialSpeechTarget = pSpeechTarget; } +#endif void SetSpeechFilter( CAI_SpeechFilter *pFilter ) { m_hSpeechFilter = pFilter; } CAI_SpeechFilter *GetSpeechFilter( void ) { return m_hSpeechFilter; } @@ -328,14 +360,14 @@ class CAI_PlayerAlly : public CAI_BaseActor //--------------------------------- virtual bool SelectQuestionAndAnswerSpeech( AISpeechSelection_t *pSelection ); - virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ); + virtual void PostSpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ); bool SelectQuestionFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection ); bool SelectAnswerFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection, bool bRespondingToHello ); //--------------------------------- - bool SelectSpeechResponse( AIConcept_t concept, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ); - void SetPendingSpeech( AIConcept_t concept, AI_Response &Response ); + bool SelectSpeechResponse( AIConcept_t conceptId, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ); + void SetPendingSpeech( AIConcept_t conceptId, AI_Response *pResponse ); void ClearPendingSpeech(); bool HasPendingSpeech() { return !m_PendingConcept.empty(); } @@ -358,9 +390,12 @@ class CAI_PlayerAlly : public CAI_BaseActor bool IsOkToCombatSpeak( void ); bool IsOkToSpeakInResponseToPlayer( void ); - bool ShouldSpeakRandom( AIConcept_t concept, int iChance ); - bool IsAllowedToSpeak( AIConcept_t concept, bool bRespondingToPlayer = false ); - virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); + bool ShouldSpeakRandom( AIConcept_t conceptId, int iChance ); + bool IsAllowedToSpeak( AIConcept_t conceptId, bool bRespondingToPlayer = false ); + virtual bool SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); +#ifdef MAPBASE + virtual bool SpeakIfAllowed( AIConcept_t conceptId, AI_CriteriaSet& modifiers, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); +#endif void ModifyOrAppendCriteria( AI_CriteriaSet& set ); //--------------------------------- @@ -374,7 +409,7 @@ class CAI_PlayerAlly : public CAI_BaseActor //--------------------------------- - void OnSpokeConcept( AIConcept_t concept, AI_Response *response ); + void OnSpokeConcept( AIConcept_t conceptId, AI_Response *response ); void OnStartSpeaking(); // Inputs @@ -386,6 +421,10 @@ class CAI_PlayerAlly : public CAI_BaseActor virtual const char *GetDeathMessageText( void ) { return "GAMEOVER_ALLY"; } void InputMakeGameEndAlly( inputdata_t &inputdata ); void InputMakeRegularAlly( inputdata_t &inputdata ); +#ifdef MAPBASE + bool AskQuestionNow( CBaseEntity *pSpeechTarget = NULL, int iQARandomNumber = -1, const char *conceptId = TLK_QUESTION ); + void InputAskQuestion( inputdata_t &inputdata ); +#endif void InputAnswerQuestion( inputdata_t &inputdata ); void InputAnswerQuestionHello( inputdata_t &inputdata ); void InputEnableSpeakWhileScripting( inputdata_t &inputdata ); diff --git a/game/server/ai_relationship.cpp b/game/server/ai_relationship.cpp index eec28d99..a700552a 100644 --- a/game/server/ai_relationship.cpp +++ b/game/server/ai_relationship.cpp @@ -7,6 +7,9 @@ #include "cbase.h" #include "ndebugoverlay.h" #include "ai_basenpc.h" +#ifdef MAPBASE +#include "mapbase/matchers.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -34,6 +37,9 @@ class CAI_Relationship : public CBaseEntity, public IEntityListener void Activate(); void SetActive( bool bActive ); +#ifdef MAPBASE + virtual +#endif void ChangeRelationships( int disposition, int iReverting, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); void ApplyRelationship( CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); @@ -45,11 +51,20 @@ class CAI_Relationship : public CBaseEntity, public IEntityListener bool IsASubject( CBaseEntity *pEntity ); bool IsATarget( CBaseEntity *pEntity ); +#ifdef MAPBASE + // Assume no insane person already has "CLASS_" at the beginning of an entity's (class)name. + inline bool IsSubjectClassify() { return Q_strncmp(STRING(m_target), "CLASS_", 6) == 0; } + inline bool IsTargetClassify() { return Q_strncmp(STRING(m_target), "CLASS_", 6) == 0; } +#endif void OnEntitySpawned( CBaseEntity *pEntity ); void OnEntityDeleted( CBaseEntity *pEntity ); +#ifdef MAPBASE +protected: +#else private: +#endif void ApplyRelationshipThink( void ); CBaseEntity *FindEntityForProceduralName( string_t iszName, CBaseEntity *pActivator, CBaseEntity *pCaller ); @@ -259,6 +274,12 @@ bool CAI_Relationship::IsASubject( CBaseEntity *pEntity ) if( pEntity->ClassMatches( m_iszSubject ) ) return true; +#ifdef MAPBASE + // Hopefully doesn't impact performance. + if (Matcher_NamesMatch(STRING(m_iszSubject), g_pGameRules->AIClassText((pEntity->Classify())))) + return true; +#endif + return false; } @@ -272,6 +293,12 @@ bool CAI_Relationship::IsATarget( CBaseEntity *pEntity ) if( pEntity->ClassMatches( m_target ) ) return true; +#ifdef MAPBASE + // Hopefully doesn't impact performance. + if (Matcher_NamesMatch(STRING(m_target), g_pGameRules->AIClassText((pEntity->Classify())))) + return true; +#endif + return false; } @@ -494,3 +521,133 @@ void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBa } } +#ifdef MAPBASE +//========================================================= +//========================================================= +class CAI_ClassRelationship : public CAI_Relationship +{ + DECLARE_CLASS( CAI_ClassRelationship, CAI_Relationship ); + +public: + + // Must override CAI_Relationship + void Spawn() { m_bIsActive = false; } + + bool KeyValue( const char *szKeyName, const char *szValue ); + + void ChangeRelationships( int disposition, int iReverting, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + + inline bool SubjectUsingClassify() { return m_iSubjectClass != NUM_AI_CLASSES; } + inline bool TargetUsingClassify() { return m_iTargetClass != NUM_AI_CLASSES; } + +protected: + + Class_T m_iSubjectClass; + Class_T m_iTargetClass; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( ai_relationship_classify, CAI_ClassRelationship ); + +BEGIN_DATADESC( CAI_ClassRelationship ) + + DEFINE_FIELD( m_iSubjectClass, FIELD_INTEGER ), + DEFINE_FIELD( m_iTargetClass, FIELD_INTEGER ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Caches entity key values until spawn is called. +// Input : szKeyName - +// szValue - +// Output : +//----------------------------------------------------------------------------- +bool CAI_ClassRelationship::KeyValue( const char *szKeyName, const char *szValue ) +{ + // Override regular subject and target from ai_relationship + if (FStrEq(szKeyName, "subject")) + { + m_iSubjectClass = (Class_T)atoi(szValue); + + // Direct string maybe + if (m_iSubjectClass == CLASS_NONE) + { + for (int i = 0; i < NUM_AI_CLASSES; i++) + { + if (FStrEq(szValue, g_pGameRules->AIClassText(i))) + { + m_iSubjectClass = (Class_T)i; + } + } + } + } + else if (FStrEq(szKeyName, "target")) + { + m_iTargetClass = (Class_T)atoi(szValue); + + // Direct string maybe + if (m_iTargetClass == CLASS_NONE) + { + for (int i = 0; i < NUM_AI_CLASSES; i++) + { + if (FStrEq(szValue, g_pGameRules->AIClassText(i))) + { + m_iTargetClass = (Class_T)i; + } + } + } + } + else + return BaseClass::KeyValue(szKeyName, szValue); + + return true; +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CAI_ClassRelationship::ChangeRelationships( int disposition, int iReverting, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + if( iReverting != NOT_REVERTING && m_iPreviousDisposition == -1 ) + { + // Trying to revert without having ever set the relationships! + DevMsg( 2, "ai_relationship cannot revert changes before they are applied!\n"); + return; + } + + if ( m_iPreviousDisposition == -1 && iReverting == NOT_REVERTING ) + { + // Set previous disposition. + m_iPreviousDisposition = CBaseCombatCharacter::GetDefaultRelationshipDisposition( m_iSubjectClass, m_iTargetClass ); + m_iPreviousRank = CBaseCombatCharacter::GetDefaultRelationshipPriority( m_iSubjectClass, m_iTargetClass ); + } + + // We can't actually reset to "default" without resetting all class relationships period, so we just use the previous disposition. + // There probably wouldn't be much overlap with this entity anyway. + if ( iReverting == REVERTING_TO_PREV || iReverting == REVERTING_TO_DEFAULT ) + { + CBaseCombatCharacter::SetDefaultRelationship(m_iSubjectClass, m_iTargetClass, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank ); + + if( m_bReciprocal ) + { + CBaseCombatCharacter::SetDefaultRelationship(m_iTargetClass, m_iSubjectClass, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank ); + } + } + else if( CBaseCombatCharacter::GetDefaultRelationshipDisposition( m_iSubjectClass, m_iTargetClass ) != disposition || + CBaseCombatCharacter::GetDefaultRelationshipPriority( m_iSubjectClass, m_iTargetClass ) != m_iRank ) + { + // Apply the relationship to the subject + CBaseCombatCharacter::SetDefaultRelationship(m_iSubjectClass, m_iTargetClass, (Disposition_t)disposition, m_iRank ); + + // Notification flags can't be used here. Sorry. + + // This relationship is applied to target and subject alike + if ( m_bReciprocal ) + { + // Apply the relationship to the target + CBaseCombatCharacter::SetDefaultRelationship(m_iTargetClass, m_iSubjectClass, (Disposition_t)disposition, m_iRank ); + } + } +} +#endif + diff --git a/game/server/ai_scriptconditions.cpp b/game/server/ai_scriptconditions.cpp index 9f10c0c3..205bcfb9 100644 --- a/game/server/ai_scriptconditions.cpp +++ b/game/server/ai_scriptconditions.cpp @@ -52,6 +52,9 @@ BEGIN_DATADESC( CAI_ScriptConditions ) DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SatisfyConditions", InputSatisfyConditions ), +#endif //--------------------------------- @@ -195,12 +198,20 @@ bool CAI_ScriptConditions::EvalState( const EvalArgs_t &args ) -1, // NPC_STATE_PLAYDEAD -1, // NPC_STATE_PRONE -1, // NPC_STATE_DEAD +#ifdef MAPBASE + 3, // A "Don't care" for the maximum value +#endif }; int valState = stateVals[pNpc->m_NPCState]; if ( valState < 0 ) { +#ifdef MAPBASE + if (m_fMinState == 0) + return true; +#endif + if ( pNpc->m_NPCState == NPC_STATE_SCRIPT && m_fScriptStatus >= TRS_TRUE ) return true; @@ -676,6 +687,25 @@ void CAI_ScriptConditions::InputDisable( inputdata_t &inputdata ) Disable(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- + +void CAI_ScriptConditions::InputSatisfyConditions( inputdata_t &inputdata ) +{ + // This satisfies things. + CBaseEntity *pActivator = HasSpawnFlags(SF_ACTOR_AS_ACTIVATOR) ? inputdata.value.Entity() : this; + m_OnConditionsSatisfied.FireOutput(pActivator, this); + + + //All done! + if ( m_ElementList.Count() == 1 ) + { + Disable(); + m_ElementList.Purge(); + } +} +#endif + //----------------------------------------------------------------------------- bool CAI_ScriptConditions::IsInFOV( CBaseEntity *pViewer, CBaseEntity *pViewed, float fov, bool bTrueCone ) @@ -829,6 +859,11 @@ void CAI_ScriptConditions::OnEntitySpawned( CBaseEntity *pEntity ) if ( pEntity->MyNPCPointer() == NULL ) return; +#ifdef MAPBASE + if ( m_Actor == NULL_STRING ) + return; +#endif + if ( pEntity->NameMatches( m_Actor ) ) { if ( ActorInList( pEntity ) == false ) diff --git a/game/server/ai_scriptconditions.h b/game/server/ai_scriptconditions.h index 8162c100..f63096ce 100644 --- a/game/server/ai_scriptconditions.h +++ b/game/server/ai_scriptconditions.h @@ -159,6 +159,9 @@ class CAI_ScriptConditions : public CBaseEntity, public IEntityListener // Input handlers void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSatisfyConditions( inputdata_t &inputdata ); +#endif // Output handlers COutputEvent m_OnConditionsSatisfied; diff --git a/game/server/ai_speech.cpp b/game/server/ai_speech.cpp index da85fdd9..a5f880a0 100644 --- a/game/server/ai_speech.cpp +++ b/game/server/ai_speech.cpp @@ -16,6 +16,9 @@ #include "AI_Criteria.h" #include "isaverestore.h" #include "sceneentity.h" +#ifdef MAPBASE +#include "ai_squad.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include @@ -38,7 +41,10 @@ CAI_TimedSemaphore g_AIFoesTalkSemaphore; ConceptHistory_t::~ConceptHistory_t() { - delete response; + if ( response ) + { + delete response; + } response = NULL; } @@ -54,16 +60,14 @@ ConceptHistory_t::ConceptHistory_t( const ConceptHistory_t& src ) ConceptHistory_t& ConceptHistory_t::operator =( const ConceptHistory_t& src ) { - if ( this != &src ) - { - timeSpoken = src.timeSpoken; + if ( this == &src ) + return *this; - delete response; - response = NULL; - if ( src.response ) - { - response = new AI_Response( *src.response ); - } + timeSpoken = src.timeSpoken; + response = NULL; + if ( src.response ) + { + response = new AI_Response( *src.response ); } return *this; @@ -88,14 +92,14 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps pSave->StartBlock(); { + // Write element name pSave->WriteString( ch->GetElementName( i ) ); // Write data pSave->WriteAll( pHistory ); - // Write response blob - bool hasresponse = !!pHistory->response; + bool hasresponse = pHistory->response != NULL ? true : false; pSave->WriteBool( &hasresponse ); if ( hasresponse ) { @@ -117,7 +121,6 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps { char conceptname[ 512 ]; conceptname[ 0 ] = 0; - ConceptHistory_t history; pRestore->StartBlock(); @@ -127,6 +130,7 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps pRestore->ReadAll( &history ); bool hasresponse = false; + pRestore->ReadBool( &hasresponse ); if ( hasresponse ) { @@ -150,7 +154,7 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps } } } - + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) { } @@ -180,6 +184,25 @@ BEGIN_SIMPLE_DATADESC( CAI_Expresser ) DEFINE_FIELD( m_flLastTimeAcceptedSpeak, FIELD_TIME ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CAI_Expresser, "Expresser class for complex speech." ) + + DEFINE_SCRIPTFUNC( IsSpeaking, "Check if the actor is speaking." ) + DEFINE_SCRIPTFUNC( CanSpeak, "Check if the actor can speak." ) + DEFINE_SCRIPTFUNC( BlockSpeechUntil, "Block speech for a certain amount of time. This is stored in curtime." ) + DEFINE_SCRIPTFUNC( ForceNotSpeaking, "If the actor is speaking, force the system to recognize them as not speaking." ) + + DEFINE_SCRIPTFUNC( GetVoicePitch, "Get the actor's voice pitch. Used in sentences." ) + DEFINE_SCRIPTFUNC( SetVoicePitch, "Set the actor's voice pitch. Used in sentences." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawScene, "SpeakRawScene", "Speak a raw, instanced VCD scene as though it were played through the Response System. Return whether the scene successfully plays." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakAutoGeneratedScene, "SpeakAutoGeneratedScene", "Speak an automatically generated, instanced VCD scene for this sound as though it were played through the Response System. Return whether the scene successfully plays." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawSentence, "SpeakRawSentence", "Speak a raw sentence as though it were played through the Response System. Return the sentence's index; -1 if not successfully played." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeak, "Speak", "Speak a response concept with the specified modifiers." ) + +END_SCRIPTDESC(); +#endif + //------------------------------------- bool CAI_Expresser::SemaphoreIsAvailable( CBaseEntity *pTalker ) @@ -250,14 +273,14 @@ void CAI_Expresser::TestAllResponses() if ( pResponseSystem ) { CUtlVector responses; - pResponseSystem->GetAllResponses( &responses ); for ( int i = 0; i < responses.Count(); i++ ) { - const char *szResponse = responses[i]->GetResponsePtr(); + char response[ 256 ]; + responses[i]->GetResponse( response, sizeof( response ) ); - Msg( "Response: %s\n", szResponse ); - SpeakDispatchResponse( "", *responses[i] ); + Msg( "Response: %s\n", response ); + SpeakDispatchResponse( "", responses[i] ); } } } @@ -272,21 +295,32 @@ static const int LEN_SPECIFIC_SCENE_MODIFIER = strlen( AI_SPECIFIC_SCENE_MODIFIE // NULL - // Output : AI_Response //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t conceptId, const char *modifiers /*= NULL*/ ) { +#ifdef MAPBASE + AI_CriteriaSet set; + + if (modifiers) + { + MergeModifiers(set, modifiers); + } + + // Now return the code in the new function. + return SpeakFindResponse(conceptId, set); +#else IResponseSystem *rs = GetOuter()->GetResponseSystem(); if ( !rs ) { Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); - return false; + return NULL; } AI_CriteriaSet set; // Always include the concept name - set.AppendCriteria( "concept", concept, CONCEPT_WEIGHT ); + set.AppendCriteria( "concept", conceptId, CONCEPT_WEIGHT ); // Always include any optional modifiers - if ( modifiers ) + if ( modifiers != NULL ) { char copy_modifiers[ 255 ]; const char *pCopy; @@ -318,55 +352,256 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con pPlayer->ModifyOrAppendPlayerCriteria( set ); } +#ifdef MAPBASE + GetOuter()->ReAppendContextCriteria( set ); +#endif + // Now that we have a criteria set, ask for a suitable response - bool found = rs->FindBestResponse( set, outResponse, this ); + AI_Response *result = new AI_Response; + Assert( result && "new AI_Response: Returned a NULL AI_Response!" ); + bool found = rs->FindBestResponse( set, *result, this ); if ( rr_debugresponses.GetInt() == 3 ) { if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) { - const char *pszName = GetOuter()->IsPlayer() ? - ((CBasePlayer*)GetOuter())->GetPlayerName() : GetOuter()->GetDebugName(); + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } if ( found ) { - const char *szReponse = outResponse.GetResponsePtr(); - Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, concept, szReponse ); + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, conceptId, response ); } else { - Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, concept ); + Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, conceptId ); } } } if ( !found ) - return false; + { + //Assert( !"rs->FindBestResponse: Returned a NULL AI_Response!" ); + delete result; + return NULL; + } - const char *szReponse = outResponse.GetResponsePtr(); - if ( !szReponse[0] ) - return false; + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); - if ( ( outResponse.GetOdds() < 100 ) && ( random->RandomInt( 1, 100 ) <= outResponse.GetOdds() ) ) - return false; + if ( !response[0] ) + { + delete result; + return NULL; + } - return true; + if ( result->GetOdds() < 100 && random->RandomInt( 1, 100 ) <= result->GetOdds() ) + { + delete result; + return NULL; + } + + return result; +#endif } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Merges modifiers with set. +//----------------------------------------------------------------------------- +void CAI_Expresser::MergeModifiers( AI_CriteriaSet& set, const char *modifiers ) +{ + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL ); + + if( *key && *value ) + { + set.AppendCriteria( key, value, CONCEPT_WEIGHT ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Searches for a possible response, takes an AI_CriteriaSet instead. +// Input : concept - +// NULL - +// Output : AI_Response +//----------------------------------------------------------------------------- +AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t conceptId, const AI_CriteriaSet &modifiers ) +{ + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return NULL; + } + + AI_CriteriaSet set; + // Always include the concept name + set.AppendCriteria( "concept", conceptId, CONCEPT_WEIGHT ); + + // Tier 1: Criteria + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( set ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + } + + // Tier 2: Modifiers + set.MergeSet(modifiers); + + // Tier 3: Contexts + GetOuter()->ReAppendContextCriteria( set ); + + // Now that we have a criteria set, ask for a suitable response + AI_Response *result = new AI_Response; + Assert( result && "new AI_Response: Returned a NULL AI_Response!" ); + bool found = rs->FindBestResponse( set, *result, this ); + + if ( rr_debugresponses.GetInt() == 3 ) + { + if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) + { + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } + + if ( found ) + { + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, conceptId, response ); + } + else + { + Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, conceptId ); + } + } + } + + if ( !found ) + { + //Assert( !"rs->FindBestResponse: Returned a NULL AI_Response!" ); + delete result; + return NULL; + } + + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + if ( !response[0] ) + { + delete result; + return NULL; + } + + if ( result->GetOdds() < 100 && random->RandomInt( 1, 100 ) <= result->GetOdds() ) + { + delete result; + return NULL; + } + + return result; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Dispatches the result // Input : *response - //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response, IRecipientFilter *filter /* = NULL */ ) +#ifdef MAPBASE +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *result, IRecipientFilter *filter, const AI_CriteriaSet *modifiers ) +#else +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *result, IRecipientFilter *filter /* = NULL */ ) +#endif { + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + +#ifdef MAPBASE + if (response[0] == '$') + { + const char *context = response + 1; + const char *replace = GetOuter()->GetContextValue(context); + + // If we can't find the context, check modifiers + if (!replace && modifiers) + { + for (int i = 0; i < modifiers->GetCount(); i++) + { + if (FStrEq(context, modifiers->GetName(i))) + { + replace = modifiers->GetValue(i); + break; + } + } + } + + if (replace) + { + CGMsg( 1, CON_GROUP_CHOREO, "Replacing %s with %s...\n", response, replace ); + Q_strncpy(response, replace, sizeof(response)); + + // Precache it now because it may not have been precached before + switch ( result->GetType() ) + { + case RESPONSE_SPEAK: + { + GetOuter()->PrecacheScriptSound( response ); + } + break; + + case RESPONSE_SCENE: + { + // TODO: Gender handling? + PrecacheInstancedScene( response ); + } + break; + } + } + } +#endif + + float delay = result->GetDelay(); + bool spoke = false; - float delay = response.GetDelay(); - const char *szResponse = response.GetResponsePtr(); - soundlevel_t soundlevel = response.GetSoundLevel(); - if ( IsSpeaking() && concept[0] != 0 ) + soundlevel_t soundlevel = result->GetSoundLevel(); + + if ( IsSpeaking() && conceptId[0] != 0 ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), conceptId ); // Tracker 15911: Can break the game if we stop an imported map placed lcs here, so only // cancel actor out of instanced scripted scenes. ywb @@ -375,53 +610,68 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res if ( IsRunningScriptedScene( GetOuter() ) ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), conceptId ); + delete result; return false; } } - switch ( response.GetType() ) + switch ( result->GetType() ) { default: case RESPONSE_NONE: break; case RESPONSE_SPEAK: - if ( !response.ShouldntUseScene() ) - { - // This generates a fake CChoreoScene wrapping the sound.txt name - spoke = SpeakAutoGeneratedScene( szResponse, delay ); - } - else { - float speakTime = GetResponseDuration( response ); - GetOuter()->EmitSound( szResponse ); + if ( !result->ShouldntUseScene() ) + { + // This generates a fake CChoreoScene wrapping the sound.txt name +#ifdef MAPBASE + spoke = SpeakAutoGeneratedScene( response, delay, result, filter ); +#else + spoke = SpeakAutoGeneratedScene( response, delay ); +#endif + } + else + { + float speakTime = GetResponseDuration( result ); + GetOuter()->EmitSound( response ); - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), szResponse ); - NoteSpeaking( speakTime, delay ); - spoke = true; + CGMsg( 1, CON_GROUP_CHOREO, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); + NoteSpeaking( speakTime, delay ); + spoke = true; + } } break; case RESPONSE_SENTENCE: - spoke = ( -1 != SpeakRawSentence( szResponse, delay, VOL_NORM, soundlevel ) ) ? true : false; + { + spoke = ( -1 != SpeakRawSentence( response, delay, VOL_NORM, soundlevel ) ) ? true : false; + } break; case RESPONSE_SCENE: - spoke = SpeakRawScene( szResponse, delay, &response, filter ); + { + spoke = SpeakRawScene( response, delay, result, filter ); + } break; case RESPONSE_RESPONSE: - // This should have been recursively resolved already - Assert( 0 ); + { + // This should have been recursively resolved already + Assert( 0 ); + } break; case RESPONSE_PRINT: - if ( g_pDeveloper->GetInt() > 0 ) { - Vector vPrintPos; - GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, szResponse, true, 1.5 ); - spoke = true; + if ( g_pDeveloper->GetInt() > 0 ) + { + Vector vPrintPos; + GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); + NDebugOverlay::Text( vPrintPos, response, true, 1.5 ); + spoke = true; + } } break; } @@ -429,27 +679,82 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res if ( spoke ) { m_flLastTimeAcceptedSpeak = gpGlobals->curtime; - if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response.GetType() != RESPONSE_PRINT ) + if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response && result->GetType() != RESPONSE_PRINT ) { Vector vPrintPos; GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", concept, szResponse ), true, 1.5 ); + NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", conceptId, response ), true, 1.5 ); } - if ( response.IsApplyContextToWorld() ) +#ifdef MAPBASE + if (result->GetContext()) + { + const char *pszContext = result->GetContext(); + + // Check for operators + char *pOperator = Q_strstr(pszContext, ":")+1; + if (pOperator && (pOperator[0] == '+' || pOperator[0] == '-' || + pOperator[0] == '*' || pOperator[0] == '/')) + { + pszContext = ParseApplyContext(pszContext); + } + + int iContextFlags = result->GetContextFlags(); + if ( iContextFlags & APPLYCONTEXT_SQUAD ) + { + CAI_BaseNPC *pNPC = GetOuter()->MyNPCPointer(); + if (pNPC && pNPC->GetSquad()) + { + AISquadIter_t iter; + CAI_BaseNPC *pSquadmate = pNPC->GetSquad()->GetFirstMember( &iter ); + while ( pSquadmate ) + { + pSquadmate->AddContext( pszContext ); + + pSquadmate = pNPC->GetSquad()->GetNextMember( &iter ); + } + } + } + if ( iContextFlags & APPLYCONTEXT_ENEMY ) + { + CBaseEntity *pEnemy = GetOuter()->GetEnemy(); + if ( pEnemy ) + { + pEnemy->AddContext( pszContext ); + } + } + if ( iContextFlags & APPLYCONTEXT_WORLD ) + { + CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( 0 ) ); + if ( pEntity ) + { + pEntity->AddContext( pszContext ); + } + } + if ( iContextFlags == 0 || iContextFlags & APPLYCONTEXT_SELF ) + { + GetOuter()->AddContext( pszContext ); + } + } +#else + if ( result->IsApplyContextToWorld() ) { CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( 0 ) ); if ( pEntity ) { - pEntity->AddContext( response.GetContext() ); + pEntity->AddContext( result->GetContext() ); } } else { - GetOuter()->AddContext( response.GetContext() ); + GetOuter()->AddContext( result->GetContext() ); } - - SetSpokeConcept( concept, &response ); +#endif + SetSpokeConcept( conceptId, result ); + } + else + { + delete result; } return spoke; @@ -460,33 +765,44 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res // Input : *response - // Output : float //----------------------------------------------------------------------------- -float CAI_Expresser::GetResponseDuration( AI_Response& response ) +float CAI_Expresser::GetResponseDuration( AI_Response *result ) { - const char *szResponse = response.GetResponsePtr(); + Assert( result ); + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); - switch ( response.GetType() ) + switch ( result->GetType() ) { default: case RESPONSE_NONE: break; - case RESPONSE_SPEAK: - return GetOuter()->GetSoundDuration( szResponse, STRING( GetOuter()->GetModelName() ) ); - + { + return GetOuter()->GetSoundDuration( response, STRING( GetOuter()->GetModelName() ) ); + } + break; case RESPONSE_SENTENCE: - Assert( 0 ); - return 999.0f; - + { + Assert( 0 ); + return 999.0f; + } + break; case RESPONSE_SCENE: - return GetSceneDuration( szResponse ); - + { + return GetSceneDuration( response ); + } + break; case RESPONSE_RESPONSE: - // This should have been recursively resolved already - Assert( 0 ); + { + // This should have been recursively resolved already + Assert( 0 ); + } break; - case RESPONSE_PRINT: - return 1.0; + { + return 1.0; + } + break; } return 0.0f; @@ -497,24 +813,50 @@ float CAI_Expresser::GetResponseDuration( AI_Response& response ) // Input : concept - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- -bool CAI_Expresser::Speak( AIConcept_t concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +bool CAI_Expresser::Speak( AIConcept_t conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AI_Response *result = SpeakFindResponse( conceptId, modifiers ); + if ( !result ) + { + return false; + } + + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), conceptId, gpGlobals->curtime ); + + bool spoke = SpeakDispatchResponse( conceptId, result, filter ); + if ( pszOutResponseChosen ) + { + result->GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Uses an AI_CriteriaSet directly instead of using context-format modifier text. +// Input : concept - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_Expresser::Speak( AIConcept_t conceptId, const AI_CriteriaSet& modifiers, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) { - AI_Response response; - bool result = SpeakFindResponse( response, concept, modifiers ); + AI_Response *result = SpeakFindResponse( conceptId, modifiers ); if ( !result ) + { return false; + } - SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), concept, gpGlobals->curtime ); + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), conceptId, gpGlobals->curtime ); - bool spoke = SpeakDispatchResponse( concept, response, filter ); + bool spoke = SpeakDispatchResponse( conceptId, result, filter, &modifiers ); if ( pszOutResponseChosen ) { - const char *szResponse = response.GetResponsePtr(); - Q_strncpy( pszOutResponseChosen, szResponse, bufsize ); + result->GetResponse( pszOutResponseChosen, bufsize ); } return spoke; } +#endif //----------------------------------------------------------------------------- // Purpose: @@ -544,9 +886,17 @@ bool CAI_Expresser::SpeakRawScene( const char *pszScene, float delay, AI_Respons } // This will create a fake .vcd/CChoreoScene to wrap the sound to be played +#ifdef MAPBASE +bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response, IRecipientFilter *filter ) +#else bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay ) +#endif { +#ifdef MAPBASE + float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname, delay, response, filter ); +#else float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname ); +#endif if ( speakTime > 0 ) { SpeechMsg( GetOuter(), "SpeakAutoGeneratedScene( %s, %f) %f\n", soundname, delay, speakTime ); @@ -691,10 +1041,10 @@ bool CAI_Expresser::CanSpeakAfterMyself() } //------------------------------------- -bool CAI_Expresser::CanSpeakConcept( AIConcept_t concept ) +bool CAI_Expresser::CanSpeakConcept( AIConcept_t conceptId ) { // Not in history? - int iter = m_ConceptHistories.Find( concept ); + int iter = m_ConceptHistories.Find( conceptId ); if ( iter == m_ConceptHistories.InvalidIndex() ) { return true; @@ -723,16 +1073,16 @@ bool CAI_Expresser::CanSpeakConcept( AIConcept_t concept ) //------------------------------------- -bool CAI_Expresser::SpokeConcept( AIConcept_t concept ) +bool CAI_Expresser::SpokeConcept( AIConcept_t conceptId ) { - return GetTimeSpokeConcept( concept ) != -1.f; + return GetTimeSpokeConcept( conceptId ) != -1.f; } //------------------------------------- -float CAI_Expresser::GetTimeSpokeConcept( AIConcept_t concept ) +float CAI_Expresser::GetTimeSpokeConcept( AIConcept_t conceptId ) { - int iter = m_ConceptHistories.Find( concept ); + int iter = m_ConceptHistories.Find( conceptId ); if ( iter == m_ConceptHistories.InvalidIndex() ) return -1; @@ -742,37 +1092,92 @@ float CAI_Expresser::GetTimeSpokeConcept( AIConcept_t concept ) //------------------------------------- -void CAI_Expresser::SetSpokeConcept( AIConcept_t concept, AI_Response *response, bool bCallback ) +void CAI_Expresser::SetSpokeConcept( AIConcept_t conceptId, AI_Response *response, bool bCallback ) { - int idx = m_ConceptHistories.Find( concept ); + int idx = m_ConceptHistories.Find( conceptId ); if ( idx == m_ConceptHistories.InvalidIndex() ) { ConceptHistory_t h; h.timeSpoken = gpGlobals->curtime; - idx = m_ConceptHistories.Insert( concept, h ); + idx = m_ConceptHistories.Insert( conceptId, h ); } ConceptHistory_t *slot = &m_ConceptHistories[ idx ]; slot->timeSpoken = gpGlobals->curtime; - // Update response info if ( response ) { - delete slot->response; - slot->response = new AI_Response( *response ); + AI_Response *r = slot->response; + if ( r ) + { + delete r; + } + + // FIXME: Are we leaking AI_Responses? + slot->response = response; } +#ifdef MAPBASE + // This "weapondelay" was just in player allies before. + // Putting it here eliminates the need to implement OnSpokeConcept on all NPCs for weapondelay. if ( bCallback ) - GetSink()->OnSpokeConcept( concept, response ); + { + if( response != NULL && (response->GetParams()->flags & AI_ResponseParams::RG_WEAPONDELAY) ) + { + if ( GetOuter()->IsNPC() ) + { + // Stop shooting, as instructed, so that my speech can be heard. + GetOuter()->MyNPCPointer()->GetShotRegulator()->FireNoEarlierThan( gpGlobals->curtime + response->GetWeaponDelay() ); + } + else + { + char szResponse[64]; + response->GetName(szResponse, sizeof(szResponse)); + Warning("%s response %s wants to use weapondelay, but %s is not a NPC!\n", GetOuter()->GetDebugName(), szResponse, GetOuter()->GetDebugName()); + } + } + + GetSink()->OnSpokeConcept( conceptId, response ); + } +#else + if ( bCallback ) + GetSink()->OnSpokeConcept( conceptId, response ); +#endif +} + +//------------------------------------- + +void CAI_Expresser::ClearSpokeConcept( AIConcept_t conceptId ) +{ + m_ConceptHistories.Remove( conceptId ); } +#ifdef MAPBASE //------------------------------------- -void CAI_Expresser::ClearSpokeConcept( AIConcept_t concept ) +AIConcept_t CAI_Expresser::GetLastSpokeConcept( AIConcept_t excludeConcept /* = NULL */ ) { - m_ConceptHistories.Remove( concept ); + int iLastSpokenIndex = m_ConceptHistories.InvalidIndex(); + float flLast = 0.0f; + for ( int i = m_ConceptHistories.First(); i != m_ConceptHistories.InvalidIndex(); i = m_ConceptHistories.Next(i ) ) + { + ConceptHistory_t *h = &m_ConceptHistories[ i ]; + + // If an 'exclude concept' was provided, skip over this entry in the history if it matches the exclude concept + if ( excludeConcept != NULL && FStrEq( m_ConceptHistories.GetElementName( i ), excludeConcept ) ) + continue; + + if ( h->timeSpoken >= flLast ) + { + iLastSpokenIndex = i; + flLast = h->timeSpoken; + } + } + + return iLastSpokenIndex != m_ConceptHistories.InvalidIndex() ? m_ConceptHistories.GetElementName( iLastSpokenIndex ) : NULL; } +#endif //------------------------------------- @@ -827,15 +1232,75 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) if ( pFlex->MyNPCPointer() ) { - DevMsg( pFlex->MyNPCPointer(), "%s", string ); + DevMsg( pFlex->MyNPCPointer(), string ); } else { - DevMsg( "%s", string ); + CGMsg( 1, CON_GROUP_CHOREO, "%s", string ); } - UTIL_LogPrintf( "%s", string ); + UTIL_LogPrintf( string ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +char *CAI_Expresser::ParseApplyContext( const char *szContext ) +{ + char szKey[128]; + char szValue[128]; + float flDuration = 0.0; + + SplitContext(szContext, szKey, sizeof(szKey), szValue, sizeof(szValue), &flDuration); + + // This is the value without the operator + const char *pszValue = szValue + 1; + + // This is the operator itself + char cOperator = szValue[0]; + + // This is the value to operate with (e.g. the "7" in "+7") + float flNewValue = atof( pszValue ); + + if (flNewValue == 0.0f) + { + // If it's really 0, then this is a waste of time + Warning("\"%s\" was detected by applyContext operators as an operable number, but it's not.\n", szValue); + return szContext; + } + + // This is the existing value; will be operated upon and become the final assignment + float flValue = 0.0f; + const char *szExistingValue = GetOuter()->GetContextValue(szKey); + if (szExistingValue) + flValue = atof(szExistingValue); + + // Do the operation based on what the character was + switch (cOperator) + { + case '+': flValue += flNewValue; break; + case '-': flValue -= flNewValue; break; + case '*': flValue *= flNewValue; break; + case '/': flValue /= flNewValue; break; + } + + Q_snprintf(szValue, sizeof(szValue), "%f", flValue); + + // Remove all trailing 0's from the float to maintain whole integers + int i; + for (i = strlen(szValue)-1; szValue[i] == '0'; i--) + { + szValue[i] = '\0'; + } + + // If there were only zeroes past the period, this is a whole number. Remove the period + if (szValue[i] == '.') + szValue[i] = '\0'; + + return UTIL_VarArgs("%s:%s:%f", szKey, szValue, flDuration); +} +#endif + //----------------------------------------------------------------------------- @@ -854,6 +1319,7 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C set.AppendCriteria( "npcstate", UTIL_VarArgs( "[NPCState::%s]", pStateNames[pSpeaker->m_NPCState] ) ); } +#ifndef MAPBASE if ( pSpeaker->GetEnemy() ) { set.AppendCriteria( "enemy", pSpeaker->GetEnemy()->GetClassname() ); @@ -866,6 +1332,7 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C else set.AppendCriteria( "timesincecombat", UTIL_VarArgs( "%f", gpGlobals->curtime - pSpeaker->GetLastEnemyTime() ) ); } +#endif set.AppendCriteria( "speed", UTIL_VarArgs( "%.3f", pSpeaker->GetSmoothedVelocity().Length() ) ); @@ -984,4 +1451,4 @@ void CMultiplayer_Expresser::AllowMultipleScenes() void CMultiplayer_Expresser::DisallowMultipleScenes() { m_bAllowMultipleScenes = false; -} \ No newline at end of file +} diff --git a/game/server/ai_speech.h b/game/server/ai_speech.h index fa173c1e..4ff15442 100644 --- a/game/server/ai_speech.h +++ b/game/server/ai_speech.h @@ -5,6 +5,9 @@ // $NoKeywords: $ //=============================================================================// +#ifdef NEW_RESPONSE_SYSTEM +#include "ai_speech_new.h" +#else #ifndef AI_SPEECH_H #define AI_SPEECH_H @@ -117,7 +120,7 @@ class AI_Response; class CAI_ExpresserSink { public: - virtual void OnSpokeConcept( AIConcept_t concept, AI_Response *response ) {}; + virtual void OnSpokeConcept( AIConcept_t conceptId, AI_Response *response ) {}; virtual void OnStartSpeaking() {} virtual bool UseSemaphore() { return true; } }; @@ -135,7 +138,7 @@ struct ConceptHistory_t ConceptHistory_t& operator = ( const ConceptHistory_t& src ); ~ConceptHistory_t(); - + float timeSpoken; AI_Response *response; }; @@ -156,12 +159,21 @@ class CAI_Expresser : public IResponseFilter // -------------------------------- - bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + bool Speak( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); +#ifdef MAPBASE + bool Speak( AIConcept_t conceptId, const AI_CriteriaSet& modifiers, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + AI_Response *SpeakFindResponse( AIConcept_t conceptId, const AI_CriteriaSet& modifiers ); + void MergeModifiers( AI_CriteriaSet& set, const char *modifiers ); +#endif // These two methods allow looking up a response and dispatching it to be two different steps - bool SpeakFindResponse( AI_Response &response, AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response &response, IRecipientFilter *filter = NULL ); - float GetResponseDuration( AI_Response &response ); + AI_Response *SpeakFindResponse( AIConcept_t conceptId, const char *modifiers = NULL ); +#ifdef MAPBASE + bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, IRecipientFilter *filter = NULL, const AI_CriteriaSet *modifiers = NULL ); +#else + bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, IRecipientFilter *filter = NULL ); +#endif + float GetResponseDuration( AI_Response *response ); virtual int SpeakRawSentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); @@ -175,14 +187,22 @@ class CAI_Expresser : public IResponseFilter bool CanSpeakAfterMyself(); float GetTimeSpeechComplete() const { return m_flStopTalkTime; } void BlockSpeechUntil( float time ); + +#ifdef MAPBASE + float GetRealTimeSpeechComplete() const { return m_flStopTalkTimeWithoutDelay; } +#endif // -------------------------------- - bool CanSpeakConcept( AIConcept_t concept ); - bool SpokeConcept( AIConcept_t concept ); - float GetTimeSpokeConcept( AIConcept_t concept ); // returns -1 if never - void SetSpokeConcept( AIConcept_t concept, AI_Response *response, bool bCallback = true ); - void ClearSpokeConcept( AIConcept_t concept ); + bool CanSpeakConcept( AIConcept_t conceptId ); + bool SpokeConcept( AIConcept_t conceptId ); + float GetTimeSpokeConcept( AIConcept_t conceptId ); // returns -1 if never + void SetSpokeConcept( AIConcept_t conceptId, AI_Response *response, bool bCallback = true ); + void ClearSpokeConcept( AIConcept_t conceptId ); + +#ifdef MAPBASE + AIConcept_t GetLastSpokeConcept( AIConcept_t excludeConcept = NULL ); +#endif // -------------------------------- @@ -194,17 +214,33 @@ class CAI_Expresser : public IResponseFilter // Force the NPC to release the semaphore & clear next speech time void ForceNotSpeaking( void ); +#ifdef MAPBASE_VSCRIPT + bool ScriptSpeakRawScene( char const *soundname, float delay ) { return SpeakRawScene( soundname, delay, NULL ); } + bool ScriptSpeakAutoGeneratedScene( char const *soundname, float delay ) { return SpeakAutoGeneratedScene( soundname, delay ); } + int ScriptSpeakRawSentence( char const *pszSentence, float delay ) { return SpeakRawSentence( pszSentence, delay ); } + bool ScriptSpeak( char const *conceptId, const char *modifiers ) { return Speak( conceptId, modifiers[0] != '\0' ? modifiers : NULL ); } +#endif + protected: CAI_TimedSemaphore *GetMySpeechSemaphore( CBaseEntity *pNpc ); bool SpeakRawScene( const char *pszScene, float delay, AI_Response *response, IRecipientFilter *filter = NULL ); // This will create a fake .vcd/CChoreoScene to wrap the sound to be played +#ifdef MAPBASE + bool SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); +#else bool SpeakAutoGeneratedScene( char const *soundname, float delay ); +#endif void DumpHistories(); void SpeechMsg( CBaseEntity *pFlex, PRINTF_FORMAT_STRING const char *pszFormat, ... ); +#ifdef MAPBASE + // Handles context operators + char *ParseApplyContext( const char *szContext ); +#endif + // -------------------------------- CAI_ExpresserSink *GetSink() { return m_pSink; } @@ -280,13 +316,19 @@ class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink public: virtual void NoteSpeaking( float duration, float delay ); - virtual bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool Speak( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); +#ifdef MAPBASE + virtual bool Speak( AIConcept_t conceptId, const AI_CriteriaSet& modifiers, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); +#endif // These two methods allow looking up a response and dispatching it to be two different steps - bool SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ); - virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) { return; } - float GetResponseDuration( AI_Response& response ); + AI_Response * SpeakFindResponse( AIConcept_t conceptId, const char *modifiers = NULL ); +#ifdef MAPBASE + AI_Response * SpeakFindResponse( AIConcept_t conceptId, const AI_CriteriaSet& modifiers ); +#endif + bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ); + virtual void PostSpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ) { return; } + float GetResponseDuration( AI_Response *response ); float GetTimeSpeechComplete() const { return this->GetExpresser()->GetTimeSpeechComplete(); } @@ -294,9 +336,9 @@ class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink bool CanSpeak() { return this->GetExpresser()->CanSpeak(); } bool CanSpeakAfterMyself() { return this->GetExpresser()->CanSpeakAfterMyself(); } - void SetSpokeConcept( AIConcept_t concept, AI_Response *response, bool bCallback = true ) { this->GetExpresser()->SetSpokeConcept( concept, response, bCallback ); } - float GetTimeSpokeConcept( AIConcept_t concept ) { return this->GetExpresser()->GetTimeSpokeConcept( concept ); } - bool SpokeConcept( AIConcept_t concept ) { return this->GetExpresser()->SpokeConcept( concept ); } + void SetSpokeConcept( AIConcept_t conceptId, AI_Response *response, bool bCallback = true ) { this->GetExpresser()->SetSpokeConcept( conceptId, response, bCallback ); } + float GetTimeSpokeConcept( AIConcept_t conceptId ) { return this->GetExpresser()->GetTimeSpokeConcept( conceptId ); } + bool SpokeConcept( AIConcept_t conceptId ) { return this->GetExpresser()->SpokeConcept( conceptId ); } protected: int PlaySentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); @@ -318,11 +360,23 @@ inline void CAI_ExpresserHost::NoteSpeaking( float duration, float del //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::Speak( AIConcept_t concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +inline bool CAI_ExpresserHost::Speak( AIConcept_t conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AssertOnce( this->GetExpresser()->GetOuter() == this ); + return this->GetExpresser()->Speak( conceptId, modifiers, pszOutResponseChosen, bufsize, filter ); +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Version of Speak() that takes a direct AI_CriteriaSet for modifiers. +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::Speak( AIConcept_t conceptId, const AI_CriteriaSet& modifiers, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) { AssertOnce( this->GetExpresser()->GetOuter() == this ); - return this->GetExpresser()->Speak( concept, modifiers, pszOutResponseChosen, bufsize, filter ); + return this->GetExpresser()->Speak( conceptId, modifiers, pszOutResponseChosen, bufsize, filter ); } +#endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -360,19 +414,29 @@ inline IResponseSystem *CAI_ExpresserHost::GetResponseSystem() //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t conceptId, const char *modifiers /*= NULL*/ ) { - return this->GetExpresser()->SpeakFindResponse( response, concept, modifiers ); + return this->GetExpresser()->SpeakFindResponse( conceptId, modifiers ); } +#ifdef MAPBASE //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t conceptId, const AI_CriteriaSet& modifiers ) { - if ( this->GetExpresser()->SpeakDispatchResponse( concept, response ) ) + return this->GetExpresser()->SpeakFindResponse( conceptId, modifiers ); +} +#endif + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ) +{ + if ( this->GetExpresser()->SpeakDispatchResponse( conceptId, response ) ) { - PostSpeakDispatchResponse( concept, response ); + PostSpeakDispatchResponse( conceptId, response ); return true; } @@ -382,7 +446,7 @@ inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t conc //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline float CAI_ExpresserHost::GetResponseDuration( AI_Response& response ) +inline float CAI_ExpresserHost::GetResponseDuration( AI_Response *response ) { return this->GetExpresser()->GetResponseDuration( response ); } @@ -399,3 +463,4 @@ inline void CAI_ExpresserHost::DispatchResponse( const char *conceptNa //----------------------------------------------------------------------------- #endif // AI_SPEECH_H +#endif diff --git a/game/server/ai_speech_new.cpp b/game/server/ai_speech_new.cpp new file mode 100644 index 00000000..cb7e1838 --- /dev/null +++ b/game/server/ai_speech_new.cpp @@ -0,0 +1,1777 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "ai_speech.h" + +#include "game.h" +#include "engine/IEngineSound.h" +#include "KeyValues.h" +#include "ai_basenpc.h" +#include "AI_Criteria.h" +#include "isaverestore.h" +#include "sceneentity.h" +#include "ai_speechqueue.h" +#ifdef MAPBASE +#include "ai_squad.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include + +#define DEBUG_AISPEECH 1 +#ifdef DEBUG_AISPEECH +ConVar ai_debug_speech( "ai_debug_speech", "0" ); +#define DebuggingSpeech() ai_debug_speech.GetBool() +#else +inline void SpeechMsg( ... ) {} +#define DebuggingSpeech() (false) +#endif + +extern ConVar rr_debugresponses; + +#ifdef MAPBASE +ConVar ai_speech_print_mode( "ai_speech_print_mode", "1", FCVAR_NONE, "Set this value to 1 to print responses as game_text instead of debug point_message-like text." ); +#endif + +//----------------------------------------------------------------------------- + +CAI_TimedSemaphore g_AIFriendliesTalkSemaphore; +CAI_TimedSemaphore g_AIFoesTalkSemaphore; + +ConceptHistory_t::~ConceptHistory_t() +{ +} + +ConceptHistory_t::ConceptHistory_t( const ConceptHistory_t& src ) +{ + timeSpoken = src.timeSpoken; + m_response = src.m_response ; +} + +ConceptHistory_t& ConceptHistory_t::operator =( const ConceptHistory_t& src ) +{ + if ( this == &src ) + return *this; + + timeSpoken = src.timeSpoken; + m_response = src.m_response ; + + return *this; +} + +BEGIN_SIMPLE_DATADESC( ConceptHistory_t ) + DEFINE_FIELD( timeSpoken, FIELD_TIME ), // Relative to server time + // DEFINE_EMBEDDED( response, FIELD_??? ), // This is manually saved/restored by the ConceptHistory saverestore ops below +END_DATADESC() + +class CConceptHistoriesDataOps : public CDefSaveRestoreOps +{ +public: + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) + { + CUtlDict< ConceptHistory_t, int > *ch = ((CUtlDict< ConceptHistory_t, int > *)fieldInfo.pField); + int count = ch->Count(); + pSave->WriteInt( &count ); + for ( int i = 0 ; i < count; i++ ) + { + ConceptHistory_t *pHistory = &(*ch)[ i ]; + + pSave->StartBlock(); + { + + // Write element name + pSave->WriteString( ch->GetElementName( i ) ); + + // Write data + pSave->WriteAll( pHistory ); + // Write response blob + bool hasresponse = !pHistory->m_response.IsEmpty() ; + pSave->WriteBool( &hasresponse ); + if ( hasresponse ) + { + pSave->WriteAll( &pHistory->m_response ); + } + // TODO: Could blat out pHistory->criteria pointer here, if it's needed + } + pSave->EndBlock(); + } + } + + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) + { + CUtlDict< ConceptHistory_t, int > *ch = ((CUtlDict< ConceptHistory_t, int > *)fieldInfo.pField); + + int count = pRestore->ReadInt(); + Assert( count >= 0 ); + for ( int i = 0 ; i < count; i++ ) + { + char conceptname[ 512 ]; + conceptname[ 0 ] = 0; + ConceptHistory_t history; + + pRestore->StartBlock(); + { + pRestore->ReadString( conceptname, sizeof( conceptname ), 0 ); + + pRestore->ReadAll( &history ); + + bool hasresponse = false; + + pRestore->ReadBool( &hasresponse ); + if ( hasresponse ) + { + history.m_response; + pRestore->ReadAll( &history.m_response ); + } + else + { + history.m_response.Invalidate(); + } + } + + pRestore->EndBlock(); + + // TODO: Could restore pHistory->criteria pointer here, if it's needed + + // Add to utldict + if ( conceptname[0] != 0 ) + { + ch->Insert( conceptname, history ); + } + else + { + Assert( !"Error restoring ConceptHistory_t, discarding!" ); + } + } + } + + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + } + + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + CUtlDict< ConceptHistory_t, int > *ch = ((CUtlDict< ConceptHistory_t, int > *)fieldInfo.pField); + return ch->Count() == 0 ? true : false; + } +}; + +CConceptHistoriesDataOps g_ConceptHistoriesSaveDataOps; + +///////////////////////////////////////////////// +// context operators +RR::CApplyContextOperator RR::sm_OpCopy(0); // " +RR::CIncrementOperator RR::sm_OpIncrement(2); // "++" +RR::CDecrementOperator RR::sm_OpDecrement(2); // "--" +#ifdef MAPBASE +RR::CMultiplyOperator RR::sm_OpMultiply(2); // "**" +RR::CDivideOperator RR::sm_OpDivide(2); // "/=" +#endif +RR::CToggleOperator RR::sm_OpToggle(1); // "!" + +#ifdef MAPBASE +// LEGACY - See below +RR::CIncrementOperator RR::sm_OpLegacyIncrement(1); // "+" +RR::CDecrementOperator RR::sm_OpLegacyDecrement(1); // "-" +RR::CMultiplyOperator RR::sm_OpLegacyMultiply(1); // "*" +RR::CDivideOperator RR::sm_OpLegacyDivide(1); // "/" +#endif + +RR::CApplyContextOperator *RR::CApplyContextOperator::FindOperator( const char *pContextString ) +{ + if ( !pContextString || pContextString[0] == 0 ) + { + return &sm_OpCopy; + } + +#ifdef MAPBASE + // This is one of those freak coincidences where Mapbase implemented its own context operators with no knowledge of context operators from later versions of the engine. + // Mapbase's context operators only required *one* operator character (e.g. '+' as opposed to '++') and supported multiplication and division. + // Although Valve's system now replaces Mapbase's system, multiplication and division have been added and maintaining the old syntax is needed for legacy support. + // That being said, it's believed that almost nobody knew that Mapbase supported context operators in the first place, so there might not be much legacy to support anyway. + switch (pContextString[0]) + { + case '+': + { + if (pContextString[1] != '+') + { + Warning( "\"%s\" needs another '+' to qualify as a proper operator. This code is regarding it as an operator anyway for legacy support, which might be going away soon!!!\n", pContextString ); + return &sm_OpLegacyIncrement; + } + else if (pContextString[2] == '\0') + break; + return &sm_OpIncrement; + } + case '-': + { + if (pContextString[1] != '-') + { + Warning( "\"%s\" needs another '-' to qualify as a proper operator. This code is regarding it as an operator anyway for legacy support, which might be going away soon!!!\n", pContextString ); + return &sm_OpLegacyDecrement; + } + else if (pContextString[2] == '\0') + break; + return &sm_OpIncrement; + } + case '*': + { + if (pContextString[1] != '*') + { + Warning( "\"%s\" needs another '*' to qualify as a proper operator. This code is regarding it as an operator anyway for legacy support, which might be going away soon!!!\n", pContextString ); + return &sm_OpLegacyMultiply; + } + else if (pContextString[2] == '\0') + break; + return &sm_OpMultiply; + } + case '/': + { + if (pContextString[1] != '=') + { + Warning( "\"%s\" needs a '=' after the '/' to qualify as a proper operator. This code is regarding it as an operator anyway for legacy support, which might be going away soon!!!\n", pContextString ); + return &sm_OpLegacyDivide; + } + else if (pContextString[2] == '\0') + break; + return &sm_OpDivide; + } break; + case '!': + { + return &sm_OpToggle; + } + } + + return &sm_OpCopy; +#else + if ( pContextString[0] == '+' && pContextString [1] == '+' && pContextString[2] != '\0' ) + { + return &sm_OpIncrement; + } + else if ( pContextString[0] == '-' && pContextString [1] == '-' && pContextString[2] != '\0' ) + { + return &sm_OpDecrement; + } +#ifdef MAPBASE + else if ( pContextString[0] == '*' && pContextString [1] == '*' && pContextString[2] != '\0' ) + { + return &sm_OpMultiply; + } + else if ( pContextString[0] == '/' && pContextString [1] == '=' && pContextString[2] != '\0' ) + { + return &sm_OpDivide; + } +#endif + else if ( pContextString[0] == '!' ) + { + return &sm_OpToggle; + } + else + { + return &sm_OpCopy; + } +#endif +} + +// default is just copy +bool RR::CApplyContextOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator && pNewValue && pNewValBufSize > 0 ); + Assert( m_nSkipChars == 0 ); + if ( pOperator ) + { + V_strncpy( pNewValue, pOperator, pNewValBufSize ); + } + else + { + *pNewValue = 0; + } + return true; +} + +bool RR::CIncrementOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '+' && pOperator[1] == '+' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld+nInc ); + return true; +} + +bool RR::CDecrementOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '-' && pOperator[1] == '-' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld-nInc ); + return true; +} + +#ifdef MAPBASE +bool RR::CMultiplyOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '*' && pOperator[1] == '*' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld*nInc ); + return true; +} + +bool RR::CDivideOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '/' && pOperator[1] == '=' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + if (nInc == 0) + V_strncpy( pNewValue, "0", pNewValBufSize ); + else + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld/nInc ); + return true; +} +#endif + +bool RR::CToggleOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '!' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld ? 0 : 1 ); + return true; +} + + +//----------------------------------------------------------------------------- +// +// CLASS: CAI_Expresser +// + +BEGIN_SIMPLE_DATADESC( CAI_Expresser ) + // m_pSink (reconnected on load) +// DEFINE_FIELD( m_pOuter, CHandle < CBaseFlex > ), + DEFINE_CUSTOM_FIELD( m_ConceptHistories, &g_ConceptHistoriesSaveDataOps ), + DEFINE_FIELD( m_flStopTalkTime, FIELD_TIME ), + DEFINE_FIELD( m_flStopTalkTimeWithoutDelay, FIELD_TIME ), + DEFINE_FIELD( m_flBlockedTalkTime, FIELD_TIME ), + DEFINE_FIELD( m_voicePitch, FIELD_INTEGER ), + DEFINE_FIELD( m_flLastTimeAcceptedSpeak, FIELD_TIME ), +END_DATADESC() + +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CAI_Expresser, "Expresser class for complex speech." ) + + DEFINE_SCRIPTFUNC( IsSpeaking, "Check if the actor is speaking." ) + DEFINE_SCRIPTFUNC( CanSpeak, "Check if the actor can speak." ) + DEFINE_SCRIPTFUNC( BlockSpeechUntil, "Block speech for a certain amount of time. This is stored in curtime." ) + DEFINE_SCRIPTFUNC( ForceNotSpeaking, "If the actor is speaking, force the system to recognize them as not speaking." ) + + DEFINE_SCRIPTFUNC( GetVoicePitch, "Get the actor's voice pitch. Used in sentences." ) + DEFINE_SCRIPTFUNC( SetVoicePitch, "Set the actor's voice pitch. Used in sentences." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawScene, "SpeakRawScene", "Speak a raw, instanced VCD scene as though it were played through the Response System. Return whether the scene successfully plays." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakAutoGeneratedScene, "SpeakAutoGeneratedScene", "Speak an automatically generated, instanced VCD scene for this sound as though it were played through the Response System. Return whether the scene successfully plays." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawSentence, "SpeakRawSentence", "Speak a raw sentence as though it were played through the Response System. Return the sentence's index; -1 if not successfully played." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSpeak, "Speak", "Speak a response concept with the specified modifiers." ) + +END_SCRIPTDESC(); +#endif + +//------------------------------------- + +bool CAI_Expresser::SemaphoreIsAvailable( CBaseEntity *pTalker ) +{ + if ( !GetSink()->UseSemaphore() ) + return true; + + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( pTalker->MyNPCPointer() ); + return (pSemaphore ? pSemaphore->IsAvailable( pTalker ) : true); +} + +//------------------------------------- + +float CAI_Expresser::GetSemaphoreAvailableTime( CBaseEntity *pTalker ) +{ + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( pTalker->MyNPCPointer() ); + return (pSemaphore ? pSemaphore->GetReleaseTime() : 0); +} + +//------------------------------------- + +int CAI_Expresser::GetVoicePitch() const +{ + return m_voicePitch + random->RandomInt(0,3); +} + +#ifdef DEBUG +static int g_nExpressers; +#endif + +/* +inline bool ShouldBeInExpresserQueue( CBaseFlex *pOuter ) +{ + return true; // return IsTerrorPlayer( pOuter, TEAM_SURVIVOR ); +} +*/ + +CAI_Expresser::CAI_Expresser( CBaseFlex *pOuter ) + : m_pOuter( pOuter ), + m_pSink( NULL ), + m_flStopTalkTime( 0 ), + m_flBlockedTalkTime( 0 ), + m_flStopTalkTimeWithoutDelay( 0 ), + m_voicePitch( 100 ), + m_flLastTimeAcceptedSpeak( 0 ) +{ +#ifdef DEBUG + g_nExpressers++; +#endif + if (m_pOuter) + { + // register me with the global expresser queue. + + // L4D: something a little ass backwards is happening here. We only want + // survivors to be in the queue. However, the team number isn't + // specified yet. So, we actually need to do this in the player's ChangeTeam. + g_ResponseQueueManager.GetQueue()->AddExpresserHost(m_pOuter); + + } +} + +CAI_Expresser::~CAI_Expresser() +{ + m_ConceptHistories.Purge(); + + CBaseFlex *RESTRICT outer = GetOuter(); + if ( outer ) + { + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( outer ); + if ( pSemaphore ) + { + if ( pSemaphore->GetOwner() == outer ) + pSemaphore->Release(); + +#ifdef DEBUG + g_nExpressers--; + if ( g_nExpressers == 0 && pSemaphore->GetOwner() ) + CGMsg( 2, CON_GROUP_SPEECH_AI, "Speech semaphore being held by non-talker entity\n" ); +#endif + } + + g_ResponseQueueManager.GetQueue()->RemoveExpresserHost(outer); + } +} + +//----------------------------------------------------------------------------- +void CAI_Expresser::TestAllResponses() +{ + IResponseSystem *pResponseSystem = GetOuter()->GetResponseSystem(); + if ( pResponseSystem ) + { + CUtlVector responses; + pResponseSystem->GetAllResponses( &responses ); + for ( int i = 0; i < responses.Count(); i++ ) + { + char response[ 256 ]; + responses[i].GetResponse( response, sizeof( response ) ); + + Msg( "Response: %s\n", response ); + AIConcept_t conceptId; + SpeakDispatchResponse( conceptId, &responses[i], NULL ); + } + } +} + +//----------------------------------------------------------------------------- +void CAI_Expresser::SetOuter( CBaseFlex *pOuter ) +{ + // if we're changing outers (which is a strange thing to do) + // unregister the old one from the queue. + if ( m_pOuter && ( m_pOuter != pOuter ) ) + { + AssertMsg2( false, "Expresser is switching its Outer from %s to %s. Why?", m_pOuter->GetDebugName(), pOuter->GetDebugName() ); + // unregister me with the global expresser queue + g_ResponseQueueManager.GetQueue()->RemoveExpresserHost(m_pOuter); + } + + m_pOuter = pOuter; +} + +//----------------------------------------------------------------------------- + +static const int LEN_SPECIFIC_SCENE_MODIFIER = strlen( AI_SPECIFIC_SCENE_MODIFIER ); + + +// This function appends "Global world" criteria that are always added to +// any character doing any match. This represents global concepts like weather, who's +// alive, etc. +static void ModifyOrAppendGlobalCriteria( AI_CriteriaSet * RESTRICT outputSet ) +{ + return; +} + + +void CAI_Expresser::GatherCriteria( AI_CriteriaSet * RESTRICT outputSet, const AIConcept_t &conceptId, const char * RESTRICT modifiers ) +{ + // Always include the concept name + outputSet->AppendCriteria( "concept", conceptId, CONCEPT_WEIGHT ); + +#if 1 + outputSet->Merge( modifiers ); +#else + // Always include any optional modifiers + if ( modifiers != NULL ) + { + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + outputSet->AppendCriteria( key, value, CONCEPT_WEIGHT ); + } + } + } +#endif + + // include any global criteria + ModifyOrAppendGlobalCriteria( outputSet ); + + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( *outputSet ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( *outputSet ); + } + +#ifdef MAPBASE + GetOuter()->ReAppendContextCriteria( *outputSet ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Searches for a possible response +// Input : concept - +// NULL - +// Output : AI_Response +//----------------------------------------------------------------------------- +// AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t conceptId, const char *modifiers /*= NULL*/ ) +bool CAI_Expresser::FindResponse( AI_Response &outResponse, const AIConcept_t &conceptId, AI_CriteriaSet *criteria ) +{ + VPROF("CAI_Expresser::FindResponse"); + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return NULL; + } + + // if I'm dead, I can't possibly match dialog. +#ifndef MAPBASE // Except for...you know...death sounds. + if ( !GetOuter()->IsAlive() ) + { + return false; + } +#endif + +#if 0 // this is the old technique, where we always gathered criteria in this function + AI_CriteriaSet set; + // Always include the concept name + set.AppendCriteria( "concept", conceptId, CONCEPT_WEIGHT ); + + // Always include any optional modifiers + if ( modifiers != NULL ) + { + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + set.AppendCriteria( key, value, CONCEPT_WEIGHT ); + } + } + } + + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( set ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + } +#else + AI_CriteriaSet localCriteriaSet; // put it on the stack so we don't deal with new/delete + if (criteria == NULL) + { + GatherCriteria( &localCriteriaSet, conceptId, NULL ); + criteria = &localCriteriaSet; + } +#endif + + /// intercept any deferred criteria that are being sent to world + AI_CriteriaSet worldWritebackCriteria; + AI_CriteriaSet::InterceptWorldSetContexts( criteria, &worldWritebackCriteria ); + + // Now that we have a criteria set, ask for a suitable response + bool found = rs->FindBestResponse( *criteria, outResponse, this ); + + if ( rr_debugresponses.GetInt() == 4 ) + { + if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) + { + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } + + if ( found ) + { + char response[ 256 ]; + outResponse.GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, (const char*)conceptId, response ); + } + else + { + Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, (const char*)conceptId ); + } + } + } + + if ( !found ) + { + return false; + } + else if ( worldWritebackCriteria.GetCount() > 0 ) + { + Assert( CBaseEntity::Instance( INDEXENT( 0 ) )->IsWorld( ) ); + worldWritebackCriteria.WriteToEntity( CBaseEntity::Instance( INDEXENT( 0 ) ) ); + } + + if ( outResponse.IsEmpty() ) + { + // AssertMsg2( false, "RR: %s got empty but valid response for %s", GetOuter()->GetDebugName(), conceptId.GetStringConcept() ); + return false; + } + else + { + return true; + } +} + +#if 0 +//----------------------------------------------------------------------------- +// Purpose: Searches for a possible response; writes it into a response passed as +// parameter rather than new'ing one up. +// Input : concept - +// NULL - +// Output : bool : true on success, false on fail +//----------------------------------------------------------------------------- +AI_Response *CAI_Expresser::SpeakFindResponse( AI_Response *result, const AIConcept_t &conceptId, AI_CriteriaSet *criteria ) +{ + Assert(response); + + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return NULL; + } + +#if 0 + AI_CriteriaSet set; + // Always include the concept name + set.AppendCriteria( "concept", conceptId, CONCEPT_WEIGHT ); + + // Always include any optional modifiers + if ( modifiers != NULL ) + { + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + set.AppendCriteria( key, value, CONCEPT_WEIGHT ); + } + } + } + + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( set ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + } +#else + AI_CriteriaSet &set = *criteria; +#endif + + // Now that we have a criteria set, ask for a suitable response + bool found = rs->FindBestResponse( set, *result, this ); + + if ( rr_debugresponses.GetInt() == 4 ) + { + if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) + { + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } + + if ( found ) + { + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, conceptId, response ); + } + else + { + Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, conceptId ); + } + } + } + + if ( !found ) + { + //Assert( !"rs->FindBestResponse: Returned a NULL AI_Response!" ); + return false; + } + + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + if ( !response[0] ) + { + return false; + } + + return true; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Dispatches the result +// Input : *response - +//----------------------------------------------------------------------------- +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *result, AI_CriteriaSet *criteria, IRecipientFilter *filter /* = NULL */ ) +{ + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + float delay = result->GetDelay(); + + bool spoke = false; + + soundlevel_t soundlevel = result->GetSoundLevel(); + + if ( IsSpeaking() && conceptId[0] != 0 && result->GetType() != ResponseRules::RESPONSE_PRINT ) + { + const char *entityName = STRING( GetOuter()->GetEntityName() ); + if ( GetOuter()->IsPlayer() ) + { + entityName = ToBasePlayer( GetOuter() )->GetPlayerName(); + } + CGMsg( 2, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)conceptId ); + + // Tracker 15911: Can break the game if we stop an imported map placed lcs here, so only + // cancel actor out of instanced scripted scenes. ywb + RemoveActorFromScriptedScenes( GetOuter(), true /*instanced scenes only*/ ); + GetOuter()->SentenceStop(); + + if ( IsRunningScriptedScene( GetOuter() ) ) + { + CGMsg( 1, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)conceptId ); + return false; + } + } + + switch ( result->GetType() ) + { + default: + case ResponseRules::RESPONSE_NONE: + break; + + case ResponseRules::RESPONSE_SPEAK: + { + if ( !result->ShouldntUseScene() ) + { + // This generates a fake CChoreoScene wrapping the sound.txt name +#ifdef MAPBASE + spoke = SpeakAutoGeneratedScene( response, delay, result, filter ); +#else + spoke = SpeakAutoGeneratedScene( response, delay ); +#endif + } + else + { + float speakTime = GetResponseDuration( result ); + GetOuter()->EmitSound( response ); + + CGMsg( 2, CON_GROUP_SPEECH_AI, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); + NoteSpeaking( speakTime, delay ); + spoke = true; +#ifdef MAPBASE + // Not really any other way of doing this + OnSpeechFinished(); +#endif + } + } + break; + + case ResponseRules::RESPONSE_SENTENCE: + { + spoke = ( -1 != SpeakRawSentence( response, delay, VOL_NORM, soundlevel ) ) ? true : false; +#ifdef MAPBASE + // Not really any other way of doing this + OnSpeechFinished(); +#endif + } + break; + + case ResponseRules::RESPONSE_SCENE: + { + spoke = SpeakRawScene( response, delay, result, filter ); + } + break; + + case ResponseRules::RESPONSE_RESPONSE: + { + // This should have been recursively resolved already + Assert( 0 ); + } + break; + case ResponseRules::RESPONSE_PRINT: + { +#ifdef MAPBASE + // Note speaking for print responses + int responseLen = Q_strlen( response ); + float responseDuration = ((float)responseLen) * 0.1f; + NoteSpeaking( responseDuration, delay ); + + // game_text print responses + hudtextparms_t textParams; + textParams.holdTime = 4.0f + responseDuration; // Give extra padding for the text itself + textParams.fadeinTime = 0.5f; + textParams.fadeoutTime = 0.5f; + + textParams.channel = 3; + textParams.x = -1; + textParams.y = 0.6; + textParams.effect = 0; + + textParams.r1 = 255; + textParams.g1 = 255; + textParams.b1 = 255; + + if (ai_speech_print_mode.GetBool() && GetOuter()->GetGameTextSpeechParams( textParams )) + { + CRecipientFilter filter; + filter.AddAllPlayers(); + filter.MakeReliable(); + + UserMessageBegin( filter, "HudMsg" ); + WRITE_BYTE ( textParams.channel & 0xFF ); + WRITE_FLOAT( textParams.x ); + WRITE_FLOAT( textParams.y ); + WRITE_BYTE ( textParams.r1 ); + WRITE_BYTE ( textParams.g1 ); + WRITE_BYTE ( textParams.b1 ); + WRITE_BYTE ( textParams.a1 ); + WRITE_BYTE ( textParams.r2 ); + WRITE_BYTE ( textParams.g2 ); + WRITE_BYTE ( textParams.b2 ); + WRITE_BYTE ( textParams.a2 ); + WRITE_BYTE ( textParams.effect ); + WRITE_FLOAT( textParams.fadeinTime ); + WRITE_FLOAT( textParams.fadeoutTime ); + WRITE_FLOAT( textParams.holdTime ); + WRITE_FLOAT( textParams.fxTime ); + WRITE_STRING( response ); + WRITE_STRING( "" ); // No custom font + WRITE_BYTE ( responseLen ); + MessageEnd(); + + spoke = true; + + OnSpeechFinished(); + } + else +#endif + if ( g_pDeveloper->GetInt() > 0 ) + { + Vector vPrintPos; + GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); + NDebugOverlay::Text( vPrintPos, response, true, 1.5 ); + } + spoke = true; +#ifdef MAPBASE + OnSpeechFinished(); +#endif + } + break; + case ResponseRules::RESPONSE_ENTITYIO: + { + spoke = FireEntIOFromResponse( response, GetOuter() ); +#ifdef MAPBASE + OnSpeechFinished(); +#endif + } + break; +#ifdef MAPBASE_VSCRIPT + case ResponseRules::RESPONSE_VSCRIPT: + { + spoke = RunScriptResponse( GetOuter(), response, criteria, false ); + OnSpeechFinished(); + } + break; + case ResponseRules::RESPONSE_VSCRIPT_FILE: + { + spoke = RunScriptResponse( GetOuter(), response, criteria, true ); + OnSpeechFinished(); + } + break; +#endif + } + + if ( spoke ) + { + m_flLastTimeAcceptedSpeak = gpGlobals->curtime; + if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response && result->GetType() != ResponseRules::RESPONSE_PRINT ) + { + Vector vPrintPos; + GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); + NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", (const char*)conceptId, response ), true, 1.5 ); + } + +#ifdef MAPBASE + if (result->GetContext()) + { + const char *pszContext = result->GetContext(); + + int iContextFlags = result->GetContextFlags(); + if ( iContextFlags & ResponseRules::APPLYCONTEXT_SQUAD ) + { + CAI_BaseNPC *pNPC = GetOuter()->MyNPCPointer(); + if (pNPC && pNPC->GetSquad()) + { + AISquadIter_t iter; + CAI_BaseNPC *pSquadmate = pNPC->GetSquad()->GetFirstMember( &iter ); + while ( pSquadmate ) + { + pSquadmate->AddContext( pszContext ); + + pSquadmate = pNPC->GetSquad()->GetNextMember( &iter ); + } + } + } + if ( iContextFlags & ResponseRules::APPLYCONTEXT_ENEMY ) + { + CBaseEntity *pEnemy = GetOuter()->GetEnemy(); + if ( pEnemy ) + { + pEnemy->AddContext( pszContext ); + } + } + if ( iContextFlags & ResponseRules::APPLYCONTEXT_WORLD ) + { + CBaseEntity *pEntity = CBaseEntity::Instance( INDEXENT( 0 ) ); + if ( pEntity ) + { + pEntity->AddContext( pszContext ); + } + } + if ( iContextFlags == 0 || iContextFlags & ResponseRules::APPLYCONTEXT_SELF ) + { + GetOuter()->AddContext( pszContext ); + } + } +#else + if ( result->IsApplyContextToWorld() ) + { + CBaseEntity *pEntity = CBaseEntity::Instance( INDEXENT( 0 ) ); + if ( pEntity ) + { + pEntity->AddContext( result->GetContext() ); + } + } + else + { + GetOuter()->AddContext( result->GetContext() ); + } +#endif + SetSpokeConcept( conceptId, result ); + } + else + { + } + + return spoke; +} + +bool CAI_Expresser::FireEntIOFromResponse( char *response, CBaseEntity *pInitiator ) +{ + // find the space-separator in the response name, then split into entityname, input, and parameter + // may barf in linux; there, should make some StringTokenizer() class that wraps the strtok_s behavior, etc. + char *pszEntname; + char *pszInput; + char *pszParam; + char *strtokContext; + + pszEntname = V_strtok_s( response, " ", &strtokContext ); + if ( !pszEntname ) + { + Warning( "Response was entityio but had bad value %s\n", response ); + return false; + } + + pszInput = V_strtok_s( NULL, " ", &strtokContext ); + if ( !pszInput ) + { + Warning( "Response was entityio but had bad value %s\n", response ); + return false; + } + + pszParam = V_strtok_s( NULL, " ", &strtokContext ); + + // poke entity io + CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, pszEntname, pInitiator ); + if ( !pTarget ) + { + CGMsg( 0, CON_GROUP_SPEECH_AI, "Response rule targeted %s with entityio, but that doesn't exist.\n", pszEntname ); + // but this is actually a legit use case, so return true (below). + } + else + { + // pump the action into the target + variant_t variant; + if ( pszParam ) + { + variant.SetString( MAKE_STRING(pszParam) ); + } + pTarget->AcceptInput( pszInput, pInitiator, pInitiator, variant, 0 ); + + } + return true; +} + +#ifdef MAPBASE_VSCRIPT +bool CAI_Expresser::RunScriptResponse( CBaseEntity *pTarget, const char *response, AI_CriteriaSet *criteria, bool file ) +{ + if (!pTarget->ValidateScriptScope()) + return false; + + ScriptVariant_t varCriteriaTable; + g_pScriptVM->CreateTable( varCriteriaTable ); + + if (criteria) + { + // Sort all of the criteria into a table. + // Letting VScript have access to this is important because not all criteria is appended in ModifyOrAppendCriteria() and + // not all contexts are actually appended as contexts. This is specifically important for followup responses. + int count = criteria->GetCount(); + for ( int i = 0 ; i < count ; ++i ) + { + // TODO: Weight? + g_pScriptVM->SetValue( varCriteriaTable, criteria->GetName(i), criteria->GetValue(i) ); + } + + g_pScriptVM->SetValue( "criteria", varCriteriaTable ); + } + + bool bSuccess = false; + if (file) + { + bSuccess = pTarget->RunScriptFile( response ); + } + else + { + bSuccess = pTarget->RunScript( response, "ResponseScript" ); + } + + g_pScriptVM->ClearValue( "criteria" ); + g_pScriptVM->ReleaseScript( varCriteriaTable ); + + return bSuccess; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *response - +// Output : float +//----------------------------------------------------------------------------- +float CAI_Expresser::GetResponseDuration( AI_Response *result ) +{ + Assert( result ); + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + switch ( result->GetType() ) + { + case ResponseRules::RESPONSE_SPEAK: + { + return GetOuter()->GetSoundDuration( response, STRING( GetOuter()->GetModelName() ) ); + } + break; + case ResponseRules::RESPONSE_SENTENCE: + { + Assert( 0 ); + return 999.0f; + } + break; + case ResponseRules::RESPONSE_SCENE: + { + return GetSceneDuration( response ); + } + break; + case ResponseRules::RESPONSE_RESPONSE: + { + // This should have been recursively resolved already + Assert( 0 ); + } + break; + case ResponseRules::RESPONSE_PRINT: + { + return 1.0; + } + break; + default: + case ResponseRules::RESPONSE_NONE: + case ResponseRules::RESPONSE_ENTITYIO: + return 0.0f; + } + + return 0.0f; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Expresser::SetUsingProspectiveResponses( bool bToggle ) +{ + VPROF("CAI_Expresser::SetUsingProspectiveResponses"); + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return; + } + + rs->SetProspective( bToggle ); +} + +void CAI_Expresser::MarkResponseAsUsed( AI_Response *response ) +{ + VPROF("CAI_Expresser::MarkResponseAsUsed"); + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return; + } + + rs->MarkResponseAsUsed( response->GetInternalIndices()[0], response->GetInternalIndices()[1] ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Placeholder for rules based response system +// Input : concept - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_Expresser::Speak( AIConcept_t conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + conceptId.SetSpeaker(GetOuter()); + AI_CriteriaSet criteria; + GatherCriteria(&criteria, conceptId, modifiers); + + return Speak( conceptId, &criteria, pszOutResponseChosen, bufsize, filter ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CAI_Expresser::Speak( const AIConcept_t &conceptId, AI_CriteriaSet * RESTRICT criteria, char *pszOutResponseChosen , size_t bufsize , IRecipientFilter *filter ) +{ + VPROF("CAI_Expresser::Speak"); + if ( IsSpeechGloballySuppressed() ) + { + return false; + } + + GetOuter()->ModifyOrAppendDerivedCriteria(*criteria); + AI_Response result; + if ( !FindResponse( result, conceptId, criteria ) ) + { + return false; + } + + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)conceptId, gpGlobals->curtime ); + // Msg( "%s:%s to %s:%s\n", GetOuter()->GetDebugName(), conceptId.GetStringConcept(), criteria.GetValue(criteria.FindCriterionIndex("Subject")), pTarget ? pTarget->GetDebugName() : "none" ); + + bool spoke = SpeakDispatchResponse( conceptId, &result, criteria, filter ); + if ( pszOutResponseChosen ) + { + result.GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CAI_Expresser::SpeakRawScene( const char *pszScene, float delay, AI_Response *response, IRecipientFilter *filter /* = NULL */ ) +{ + float sceneLength = GetOuter()->PlayScene( pszScene, delay, response, filter ); + if ( sceneLength > 0 ) + { + SpeechMsg( GetOuter(), "SpeakRawScene( %s, %f) %f\n", pszScene, delay, sceneLength ); + +#if defined( HL2_EPISODIC ) + char szInstanceFilename[256]; + GetOuter()->GenderExpandString( pszScene, szInstanceFilename, sizeof( szInstanceFilename ) ); + // Only mark ourselves as speaking if the scene has speech + if ( GetSceneSpeechCount(szInstanceFilename) > 0 ) + { + NoteSpeaking( sceneLength, delay ); + } +#else + NoteSpeaking( sceneLength, delay ); +#endif + + return true; + } + return false; +} + +// This will create a fake .vcd/CChoreoScene to wrap the sound to be played +#ifdef MAPBASE +bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response, IRecipientFilter *filter ) +#else +bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay ) +#endif +{ +#ifdef MAPBASE + float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname, delay, response, filter ); +#else + float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname ); +#endif + if ( speakTime > 0 ) + { + SpeechMsg( GetOuter(), "SpeakAutoGeneratedScene( %s, %f) %f\n", soundname, delay, speakTime ); + NoteSpeaking( speakTime, delay ); + return true; + } + return false; +} + +//------------------------------------- + +int CAI_Expresser::SpeakRawSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, CBaseEntity *pListener ) +{ + int sentenceIndex = -1; + + if ( !pszSentence ) + return sentenceIndex; + + if ( pszSentence[0] == AI_SP_SPECIFIC_SENTENCE ) + { + sentenceIndex = SENTENCEG_Lookup( pszSentence ); + + if( sentenceIndex == -1 ) + { + // sentence not found + return -1; + } + + CPASAttenuationFilter filter( GetOuter(), soundlevel ); + CBaseEntity::EmitSentenceByIndex( filter, GetOuter()->entindex(), CHAN_VOICE, sentenceIndex, volume, soundlevel, 0, GetVoicePitch()); + } + else + { + sentenceIndex = SENTENCEG_PlayRndSz( GetOuter()->NetworkProp()->edict(), pszSentence, volume, soundlevel, 0, GetVoicePitch() ); + } + + SpeechMsg( GetOuter(), "SpeakRawSentence( %s, %f) %f\n", pszSentence, delay, engine->SentenceLength( sentenceIndex ) ); + NoteSpeaking( engine->SentenceLength( sentenceIndex ), delay ); + + return sentenceIndex; +} + +//------------------------------------- + +void CAI_Expresser::BlockSpeechUntil( float time ) +{ + SpeechMsg( GetOuter(), "BlockSpeechUntil(%f) %f\n", time, time - gpGlobals->curtime ); + m_flBlockedTalkTime = time; +} + + +//------------------------------------- + +void CAI_Expresser::NoteSpeaking( float duration, float delay ) +{ + duration += delay; + + GetSink()->OnStartSpeaking(); + + if ( duration <= 0 ) + { + // no duration :( + m_flStopTalkTime = gpGlobals->curtime + 3; + duration = 0; + } + else + { + m_flStopTalkTime = gpGlobals->curtime + duration; + } + + m_flStopTalkTimeWithoutDelay = m_flStopTalkTime - delay; + + SpeechMsg( GetOuter(), "NoteSpeaking( %f, %f ) (stop at %f)\n", duration, delay, m_flStopTalkTime ); + + if ( GetSink()->UseSemaphore() ) + { + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( GetOuter() ); + if ( pSemaphore ) + { + pSemaphore->Acquire( duration, GetOuter() ); + } + } +} + +//------------------------------------- + +void CAI_Expresser::ForceNotSpeaking( void ) +{ + if ( IsSpeaking() ) + { + m_flStopTalkTime = gpGlobals->curtime; + m_flStopTalkTimeWithoutDelay = gpGlobals->curtime; + + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( GetOuter() ); + if ( pSemaphore ) + { + if ( pSemaphore->GetOwner() == GetOuter() ) + { + pSemaphore->Release(); + } + } + } +} + +//------------------------------------- + +bool CAI_Expresser::IsSpeaking( void ) +{ + if ( m_flStopTalkTime > gpGlobals->curtime ) + SpeechMsg( GetOuter(), "IsSpeaking() %f\n", m_flStopTalkTime - gpGlobals->curtime ); + + if ( m_flLastTimeAcceptedSpeak == gpGlobals->curtime ) // only one speak accepted per think + return true; + + return ( m_flStopTalkTime > gpGlobals->curtime ); +} + +//------------------------------------- + +bool CAI_Expresser::CanSpeak() +{ + if ( m_flLastTimeAcceptedSpeak == gpGlobals->curtime ) // only one speak accepted per think + return false; + + float timeOk = MAX( m_flStopTalkTime, m_flBlockedTalkTime ); + return ( timeOk <= gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if it's ok for this entity to speak after himself. +// The base CanSpeak() includes the default speech delay, and won't +// return true until that delay time has passed after finishing the +// speech. This returns true as soon as the speech finishes. +//----------------------------------------------------------------------------- +bool CAI_Expresser::CanSpeakAfterMyself() +{ + if ( m_flLastTimeAcceptedSpeak == gpGlobals->curtime ) // only one speak accepted per think + return false; + + float timeOk = MAX( m_flStopTalkTimeWithoutDelay, m_flBlockedTalkTime ); + return ( timeOk <= gpGlobals->curtime ); +} + +//------------------------------------- +bool CAI_Expresser::CanSpeakConcept( const AIConcept_t &conceptId ) +{ + // Not in history? + int iter = m_ConceptHistories.Find( conceptId ); + if ( iter == m_ConceptHistories.InvalidIndex() ) + { + return true; + } + + ConceptHistory_t *history = &m_ConceptHistories[iter]; + Assert( history ); + + const AI_Response &response = history->m_response; + if ( response.IsEmpty() ) + return true; + + if ( response.GetSpeakOnce() ) + return false; + + float respeakDelay = response.GetRespeakDelay(); + + if ( respeakDelay != 0.0f ) + { + if ( history->timeSpoken != -1 && ( gpGlobals->curtime < history->timeSpoken + respeakDelay ) ) + return false; + } + + return true; +} + +//------------------------------------- + +bool CAI_Expresser::SpokeConcept( const AIConcept_t &conceptId ) +{ + return GetTimeSpokeConcept( conceptId ) != -1.f; +} + +//------------------------------------- + +float CAI_Expresser::GetTimeSpokeConcept( const AIConcept_t &conceptId ) +{ + int iter = m_ConceptHistories.Find( conceptId ); + if ( iter == m_ConceptHistories.InvalidIndex() ) + return -1; + + ConceptHistory_t *h = &m_ConceptHistories[iter]; + return h->timeSpoken; +} + +//------------------------------------- + +void CAI_Expresser::SetSpokeConcept( const AIConcept_t &conceptId, AI_Response *response, bool bCallback ) +{ + int idx = m_ConceptHistories.Find( conceptId ); + if ( idx == m_ConceptHistories.InvalidIndex() ) + { + ConceptHistory_t h; + h.timeSpoken = gpGlobals->curtime; + idx = m_ConceptHistories.Insert( conceptId, h ); + } + + ConceptHistory_t *slot = &m_ConceptHistories[ idx ]; + + slot->timeSpoken = gpGlobals->curtime; + // Update response info + if ( response ) + { + slot->m_response = *response; + } + + if ( bCallback ) + GetSink()->OnSpokeConcept( conceptId, response ); +} + +//------------------------------------- + +void CAI_Expresser::ClearSpokeConcept( const AIConcept_t &conceptId ) +{ + m_ConceptHistories.Remove( conceptId ); +} + +#ifdef MAPBASE +//------------------------------------- + +AIConcept_t CAI_Expresser::GetLastSpokeConcept( AIConcept_t excludeConcept /* = NULL */ ) +{ + int iLastSpokenIndex = m_ConceptHistories.InvalidIndex(); + float flLast = 0.0f; + for ( int i = m_ConceptHistories.First(); i != m_ConceptHistories.InvalidIndex(); i = m_ConceptHistories.Next(i ) ) + { + ConceptHistory_t *h = &m_ConceptHistories[ i ]; + + // If an 'exclude concept' was provided, skip over this entry in the history if it matches the exclude concept + if ( excludeConcept != NULL && FStrEq( m_ConceptHistories.GetElementName( i ), excludeConcept ) ) + continue; + + if ( h->timeSpoken >= flLast ) + { + iLastSpokenIndex = i; + flLast = h->timeSpoken; + } + } + + return iLastSpokenIndex != m_ConceptHistories.InvalidIndex() ? m_ConceptHistories.GetElementName( iLastSpokenIndex ) : NULL; +} +#endif + +//------------------------------------- + +void CAI_Expresser::DumpHistories() +{ + int c = 1; + for ( int i = m_ConceptHistories.First(); i != m_ConceptHistories.InvalidIndex(); i = m_ConceptHistories.Next(i ) ) + { + ConceptHistory_t *h = &m_ConceptHistories[ i ]; + + CGMsg( 1, CON_GROUP_SPEECH_AI, "%i: %s at %f\n", c++, m_ConceptHistories.GetElementName( i ), h->timeSpoken ); + } +} + +//------------------------------------- + +bool CAI_Expresser::IsValidResponse( ResponseType_t type, const char *pszValue ) +{ + if ( type == ResponseRules::RESPONSE_SCENE ) + { + char szInstanceFilename[256]; + GetOuter()->GenderExpandString( pszValue, szInstanceFilename, sizeof( szInstanceFilename ) ); + return ( GetSceneDuration( szInstanceFilename ) > 0 ); + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_TimedSemaphore *CAI_Expresser::GetMySpeechSemaphore( CBaseEntity *pNpc ) +{ + if ( !pNpc->MyNPCPointer() ) + return NULL; + + return (pNpc->MyNPCPointer()->IsPlayerAlly() ? &g_AIFriendliesTalkSemaphore : &g_AIFoesTalkSemaphore ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) +{ + if ( !DebuggingSpeech() ) + return; + + va_list arg_ptr; + + va_start(arg_ptr, pszFormat); + CFmtStr formatted; + formatted.sprintf_argv(pszFormat, arg_ptr); + va_end(arg_ptr); + + if ( pFlex->MyNPCPointer() ) + { + + DevMsg( pFlex->MyNPCPointer(), "%s", formatted.Get() ); + } + else + { + CGMsg( 1, CON_GROUP_SPEECH_AI, "%s", formatted.Get() ); + } + UTIL_LogPrintf( "%s", formatted.Get() ); +} + +//----------------------------------------------------------------------------- +// Purpose: returns true when l4d is in credits screen or some other +// speech-forbidden state +//----------------------------------------------------------------------------- +bool CAI_Expresser::IsSpeechGloballySuppressed() +{ + return false; +} + +//----------------------------------------------------------------------------- + +void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_CriteriaSet& set ) +{ + // Append current activity name + const char *pActivityName = pSpeaker->GetActivityName( pSpeaker->GetActivity() ); + if ( pActivityName ) + { + set.AppendCriteria( "activity", pActivityName ); + } + + static const char *pStateNames[] = { "None", "Idle", "Alert", "Combat", "Scripted", "PlayDead", "Dead" }; + if ( (int)pSpeaker->m_NPCState < ARRAYSIZE(pStateNames) ) + { + set.AppendCriteria( "npcstate", UTIL_VarArgs( "[NPCState::%s]", pStateNames[pSpeaker->m_NPCState] ) ); + } + + if ( pSpeaker->GetEnemy() ) + { + set.AppendCriteria( "enemy", pSpeaker->GetEnemy()->GetClassname() ); + set.AppendCriteria( "timesincecombat", "-1" ); + } + else + { + if ( pSpeaker->GetLastEnemyTime() == 0.0 ) + set.AppendCriteria( "timesincecombat", "999999.0" ); + else + set.AppendCriteria( "timesincecombat", UTIL_VarArgs( "%f", gpGlobals->curtime - pSpeaker->GetLastEnemyTime() ) ); + } + + set.AppendCriteria( "speed", UTIL_VarArgs( "%.3f", pSpeaker->GetSmoothedVelocity().Length() ) ); + + CBaseCombatWeapon *weapon = pSpeaker->GetActiveWeapon(); + if ( weapon ) + { + set.AppendCriteria( "weapon", weapon->GetClassname() ); + } + else + { + set.AppendCriteria( "weapon", "none" ); + } + + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + if ( pPlayer ) + { + Vector distance = pPlayer->GetAbsOrigin() - pSpeaker->GetAbsOrigin(); + + set.AppendCriteria( "distancetoplayer", UTIL_VarArgs( "%f", distance.Length() ) ); + + } + else + { + set.AppendCriteria( "distancetoplayer", UTIL_VarArgs( "%i", MAX_COORD_RANGE ) ); + } + + if ( pSpeaker->HasCondition( COND_SEE_PLAYER ) ) + { + set.AppendCriteria( "seeplayer", "1" ); + } + else + { + set.AppendCriteria( "seeplayer", "0" ); + } + + if ( pPlayer && pPlayer->FInViewCone( pSpeaker ) && pPlayer->FVisible( pSpeaker ) ) + { + set.AppendCriteria( "seenbyplayer", "1" ); + } + else + { + set.AppendCriteria( "seenbyplayer", "0" ); + } +} + +//----------------------------------------------------------------------------- + +extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer ); + +CON_COMMAND( npc_speakall, "Force the npc to try and speak all their responses" ) +{ + CBaseEntity *pEntity; + + if ( args[1] && *args[1] ) + { + pEntity = gEntList.FindEntityByName( NULL, args[1], NULL ); + if ( !pEntity ) + { + pEntity = gEntList.FindEntityByClassname( NULL, args[1] ); + } + } + else + { + pEntity = UTIL_GetCommandClient() ? FindPickerEntity( UTIL_GetCommandClient() ) : NULL; + } + + if ( pEntity ) + { + CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); + if (pNPC) + { + if ( pNPC->GetExpresser() ) + { + bool save = engine->LockNetworkStringTables( false ); + pNPC->GetExpresser()->TestAllResponses(); + engine->LockNetworkStringTables( save ); + } + } + } +} +//----------------------------------------------------------------------------- + +CMultiplayer_Expresser::CMultiplayer_Expresser( CBaseFlex *pOuter ) : CAI_ExpresserWithFollowup( pOuter ) +{ + m_bAllowMultipleScenes = false; +} + +bool CMultiplayer_Expresser::IsSpeaking( void ) +{ + if ( m_bAllowMultipleScenes ) + { + return false; + } + + return CAI_Expresser::IsSpeaking(); +} + + +void CMultiplayer_Expresser::AllowMultipleScenes() +{ + m_bAllowMultipleScenes = true; +} + +void CMultiplayer_Expresser::DisallowMultipleScenes() +{ + m_bAllowMultipleScenes = false; +} diff --git a/game/server/ai_speech_new.h b/game/server/ai_speech_new.h new file mode 100644 index 00000000..d5641029 --- /dev/null +++ b/game/server/ai_speech_new.h @@ -0,0 +1,713 @@ +//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SPEECH_H +#define AI_SPEECH_H + +#include "utlmap.h" + +#include "soundflags.h" +#include "AI_Criteria.h" +#include "AI_ResponseSystem.h" +#include "utldict.h" +#include "ai_speechconcept.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +class KeyValues; + +using ResponseRules::ResponseType_t; +using ResponseRules::AI_ResponseFollowup; + + +//----------------------------------------------------------------------------- +// Purpose: Used to share a global resource or prevent a system stepping on +// own toes. +//----------------------------------------------------------------------------- + +class CAI_TimedSemaphore +{ +public: + CAI_TimedSemaphore() + : m_ReleaseTime( 0 ) + { + m_hCurrentTalker = NULL; + } + + void Acquire( float time, CBaseEntity *pTalker ) { m_ReleaseTime = gpGlobals->curtime + time; m_hCurrentTalker = pTalker; } + void Release() { m_ReleaseTime = 0; m_hCurrentTalker = NULL; } + + // Current owner of the semaphore is always allowed to talk + bool IsAvailable( CBaseEntity *pTalker ) const { return ((gpGlobals->curtime > m_ReleaseTime) || (m_hCurrentTalker == pTalker)); } + float GetReleaseTime() const { return m_ReleaseTime; } + + CBaseEntity *GetOwner() { return m_hCurrentTalker; } + +private: + float m_ReleaseTime; + EHANDLE m_hCurrentTalker; +}; + +//----------------------------------------------------------------------------- + +extern CAI_TimedSemaphore g_AIFriendliesTalkSemaphore; +extern CAI_TimedSemaphore g_AIFoesTalkSemaphore; + +#define GetSpeechSemaphore( pNpc ) (((pNpc)->IsPlayerAlly()) ? &g_AIFriendliesTalkSemaphore : &g_AIFoesTalkSemaphore ) +//----------------------------------------------------------------------------- +// Basic speech system types +//----------------------------------------------------------------------------- + +//------------------------------------- +// Constants + + +const float AIS_NO_DELAY = 0; +const soundlevel_t AIS_DEF_SNDLVL = SNDLVL_TALKING; +#define AI_NULL_CONCEPT NULL + +#define AI_NULL_SENTENCE NULL + +// Sentence prefix constants +#define AI_SP_SPECIFIC_SENTENCE '!' +#define AI_SP_WAVFILE '^' +#define AI_SP_SCENE_GROUP '=' +#define AI_SP_SPECIFIC_SCENE '?' + +#define AI_SPECIFIC_SENTENCE(str_constant) "!" str_constant +#define AI_WAVFILE(str_constant) "^" str_constant +// @Note (toml 09-12-02): as scene groups are not currently implemented, the string is a semi-colon delimited list +#define AI_SCENE_GROUP(str_constant) "=" str_constant +#define AI_SPECIFIC_SCENE(str_constant) "?" str_constant + +// Designer overriding modifiers +#define AI_SPECIFIC_SCENE_MODIFIER "scene:" + +//------------------------------------- + +//------------------------------------- +// An id that represents the core meaning of a spoken phrase, +// eventually to be mapped to a sentence group or scene + +#if AI_CONCEPTS_ARE_STRINGS +typedef const char *AIConcept_t; +inline bool CompareConcepts( AIConcept_t c1, AIConcept_t c2 ) +{ + return ( (void *)c1 == (void *)c2 || ( c1 && c2 && Q_stricmp( c1, c2 ) == 0 ) ); +} +#else +typedef CAI_Concept AIConcept_t; +inline bool CompareConcepts( AIConcept_t c1, AIConcept_t c2 ) +{ + return c1.m_iConcept == c2.m_iConcept; +} +#endif + + +//----------------------------------------------------------------------------- +// CAI_Expresser +// +// Purpose: Provides the functionality of going from abstract concept ("hello") +// to specific sentence/scene/wave +// + +//------------------------------------- +// Sink supports behavior control and receives notifications of internal events + +class CAI_ExpresserSink +{ +public: + virtual void OnSpokeConcept( AIConcept_t conceptId, AI_Response *response ) {}; + virtual void OnStartSpeaking() {} + virtual bool UseSemaphore() { return true; } +}; + +struct ConceptHistory_t +{ + DECLARE_SIMPLE_DATADESC(); + + ConceptHistory_t(float timeSpoken = -1 ) + : timeSpoken( timeSpoken ), m_response( ) + { + } + + ConceptHistory_t( const ConceptHistory_t& src ); + ConceptHistory_t& operator = ( const ConceptHistory_t& src ); + + ~ConceptHistory_t(); + + float timeSpoken; + AI_Response m_response; +}; +//------------------------------------- + +class CAI_Expresser : public ResponseRules::IResponseFilter +{ +public: + CAI_Expresser( CBaseFlex *pOuter = NULL ); + ~CAI_Expresser(); + + // -------------------------------- + + bool Connect( CAI_ExpresserSink *pSink ) { m_pSink = pSink; return true; } + bool Disconnect( CAI_ExpresserSink *pSink ) { m_pSink = NULL; return true;} + + void TestAllResponses(); + + // -------------------------------- + + bool Speak( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + bool Speak( const AIConcept_t &conceptId, AI_CriteriaSet *criteria, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + + // Given modifiers (which are colon-delimited strings), fill out a criteria set including this + // character's contexts and the ones in the modifier. This lets us hang on to them after a call + // to SpeakFindResponse. + void GatherCriteria( AI_CriteriaSet *outputCritera, const AIConcept_t &conceptId, const char *modifiers ); + // These two methods allow looking up a response and dispatching it to be two different steps + // AI_Response *SpeakFindResponse( AIConcept_t conceptId, const char *modifiers = NULL ); + // AI_Response *SpeakFindResponse( AIConcept_t &conceptId, AI_CriteriaSet *criteria ); + // Find the appropriate response for the given concept. Return false if none found. + // Fills out the response object that you provide. + bool FindResponse( AI_Response &outResponse, const AIConcept_t &conceptId, AI_CriteriaSet *modifiers = NULL ); + virtual bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); + float GetResponseDuration( AI_Response *response ); + +#ifdef MAPBASE + void SetUsingProspectiveResponses( bool bToggle ); + void MarkResponseAsUsed( AI_Response *response ); +#endif + + virtual int SpeakRawSentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); + + bool SemaphoreIsAvailable( CBaseEntity *pTalker ); + float GetSemaphoreAvailableTime( CBaseEntity *pTalker ); + + virtual void OnSpeechFinished() {}; + + // This function can be overriden by games to suppress speech altogether during glue screens, etc + static bool IsSpeechGloballySuppressed(); + + // -------------------------------- + + virtual bool IsSpeaking(); + bool CanSpeak(); + bool CanSpeakAfterMyself(); + float GetTimeSpeechComplete() const { return m_flStopTalkTime; } +#ifdef MAPBASE + float GetTimeSpeechCompleteWithoutDelay() const { return m_flStopTalkTimeWithoutDelay; } +#endif + void BlockSpeechUntil( float time ); + + // -------------------------------- + + bool CanSpeakConcept( const AIConcept_t &conceptId ); + bool SpokeConcept( const AIConcept_t &conceptId ); + float GetTimeSpokeConcept( const AIConcept_t &conceptId ); // returns -1 if never + void SetSpokeConcept( const AIConcept_t &conceptId, AI_Response *response, bool bCallback = true ); + void ClearSpokeConcept( const AIConcept_t &conceptId ); + +#ifdef MAPBASE + AIConcept_t GetLastSpokeConcept( AIConcept_t excludeConcept = NULL ); +#endif + + // -------------------------------- + + void SetVoicePitch( int voicePitch ) { m_voicePitch = voicePitch; } + int GetVoicePitch() const; + + void NoteSpeaking( float duration, float delay = 0 ); + + // Force the NPC to release the semaphore & clear next speech time + void ForceNotSpeaking( void ); + +#ifdef MAPBASE_VSCRIPT + bool ScriptSpeakRawScene( char const *soundname, float delay ) { return SpeakRawScene( soundname, delay, NULL ); } + bool ScriptSpeakAutoGeneratedScene( char const *soundname, float delay ) { return SpeakAutoGeneratedScene( soundname, delay ); } + int ScriptSpeakRawSentence( char const *pszSentence, float delay ) { return SpeakRawSentence( pszSentence, delay ); } + bool ScriptSpeak( char const *conceptId, const char *modifiers ) { return Speak( conceptId, modifiers[0] != '\0' ? modifiers : NULL ); } +#endif + + // helper used in dealing with RESPONSE_ENTITYIO + // response is the output of AI_Response::GetName + // note: the response string will get stomped on (by strtok) + // returns false on failure (eg, couldn't match parse contents) + static bool FireEntIOFromResponse( char *response, CBaseEntity *pInitiator ); + +#ifdef MAPBASE_VSCRIPT + // Used for RESPONSE_VSCRIPT(_FILE) + static bool RunScriptResponse( CBaseEntity *pTarget, const char *response, AI_CriteriaSet *criteria, bool file ); +#endif + +protected: + CAI_TimedSemaphore *GetMySpeechSemaphore( CBaseEntity *pNpc ); + + bool SpeakRawScene( const char *pszScene, float delay, AI_Response *response, IRecipientFilter *filter = NULL ); + // This will create a fake .vcd/CChoreoScene to wrap the sound to be played +#ifdef MAPBASE + bool SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); +#else + bool SpeakAutoGeneratedScene( char const *soundname, float delay ); +#endif + + void DumpHistories(); + + void SpeechMsg( CBaseEntity *pFlex, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION(3, 4); + + // -------------------------------- + + CAI_ExpresserSink *GetSink() { return m_pSink; } + +private: + // -------------------------------- + + virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ); + + // -------------------------------- + + CAI_ExpresserSink *m_pSink; + + // -------------------------------- + // + // Speech concept data structures + // + + CUtlDict< ConceptHistory_t, int > m_ConceptHistories; + + // -------------------------------- + // + // Speaking states + // + + float m_flStopTalkTime; // when in the future that I'll be done saying this sentence. + float m_flStopTalkTimeWithoutDelay; // same as the above, but minus the delay before other people can speak + float m_flBlockedTalkTime; + int m_voicePitch; // pitch of voice for this head + float m_flLastTimeAcceptedSpeak; // because speech may not be blocked until NoteSpeaking called by scene ent, this handles in-think blocking + + DECLARE_SIMPLE_DATADESC(); + + // -------------------------------- + // +public: + void SetOuter( CBaseFlex *pOuter ); + + CBaseFlex * GetOuter() { return m_pOuter; } + const CBaseFlex * GetOuter() const { return m_pOuter; } + +private: + CHandle m_pOuter; +}; + +//----------------------------------------------------------------------------- +// +// An NPC base class to assist a branch of the inheritance graph +// in utilizing CAI_Expresser +// + +template +class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink +{ + DECLARE_CLASS_NOFRIEND( CAI_ExpresserHost, BASE_NPC ); + +public: + virtual void NoteSpeaking( float duration, float delay ); + + virtual bool Speak( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool Speak( AIConcept_t conceptId, AI_CriteriaSet *pCriteria, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); +#ifdef MAPBASE + virtual bool Speak( AIConcept_t conceptId, AI_CriteriaSet& modifiers, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ) { return Speak( conceptId, &modifiers, pszOutResponseChosen, bufsize, filter ); } +#endif + + + void GatherCriteria( AI_CriteriaSet *outputCritera, const AIConcept_t &conceptId, const char *modifiers ); + // These two methods allow looking up a response and dispatching it to be two different steps +#ifdef MAPBASE + //AI_Response *SpeakFindResponse( AIConcept_t conceptId, const AI_CriteriaSet& modifiers ); + inline bool SpeakDispatchResponse( const AIConcept_t &conceptId, AI_Response &response, AI_CriteriaSet *criteria = NULL ) { return SpeakDispatchResponse( conceptId, &response, criteria ); } +#endif + bool SpeakFindResponse( AI_Response& outResponse, const AIConcept_t &conceptId, const char *modifiers = NULL ); + // AI_Response * SpeakFindResponse( AIConcept_t conceptId, const char *modifiers = NULL ); + // AI_Response *SpeakFindResponse( AIConcept_t conceptId, AI_CriteriaSet *criteria ); + // AI_Response *SpeakFindResponse( AIConcept_t conceptId ); + // Find the appropriate response for the given concept. Return false if none found. + // Fills out the response object that you provide. + bool FindResponse( AI_Response &outResponse, const AIConcept_t &conceptId, AI_CriteriaSet *criteria = NULL ); + + bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, AI_CriteriaSet *criteria = NULL ); + virtual void PostSpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response ) { return; } + float GetResponseDuration( AI_Response *response ); + + float GetTimeSpeechComplete() const { return this->GetExpresser()->GetTimeSpeechComplete(); } + + bool IsSpeaking() { return this->GetExpresser()->IsSpeaking(); } + bool CanSpeak() { return this->GetExpresser()->CanSpeak(); } + bool CanSpeakAfterMyself() { return this->GetExpresser()->CanSpeakAfterMyself(); } + + void SetSpokeConcept( AIConcept_t conceptId, AI_Response *response, bool bCallback = true ) { this->GetExpresser()->SetSpokeConcept( conceptId, response, bCallback ); } + float GetTimeSpokeConcept( AIConcept_t conceptId ) { return this->GetExpresser()->GetTimeSpokeConcept( conceptId ); } + bool SpokeConcept( AIConcept_t conceptId ) { return this->GetExpresser()->SpokeConcept( conceptId ); } + +protected: + int PlaySentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); + virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); + + virtual IResponseSystem *GetResponseSystem(); + // Override of base entity response input handler + virtual void DispatchResponse( const char *conceptName ); +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline void CAI_ExpresserHost::NoteSpeaking( float duration, float delay ) +{ + this->GetExpresser()->NoteSpeaking( duration, delay ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::Speak( AIConcept_t conceptId, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AssertOnce( this->GetExpresser()->GetOuter() == this ); + return this->GetExpresser()->Speak( conceptId, modifiers, pszOutResponseChosen, bufsize, filter ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::Speak( AIConcept_t conceptId, AI_CriteriaSet *pCriteria, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AssertOnce( this->GetExpresser()->GetOuter() == this ); + CAI_Expresser * const RESTRICT pExpresser = this->GetExpresser(); + conceptId.SetSpeaker(this); + // add in any local criteria to the one passed on the command line. + pExpresser->GatherCriteria( pCriteria, conceptId, NULL ); + // call the "I have aleady gathered criteria" version of Expresser::Speak + return pExpresser->Speak( conceptId, pCriteria, pszOutResponseChosen, bufsize, filter ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline int CAI_ExpresserHost::PlaySentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, CBaseEntity *pListener ) +{ + return this->GetExpresser()->SpeakRawSentence( pszSentence, delay, volume, soundlevel, pListener ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +extern void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_CriteriaSet& criteriaSet ); + +template +inline void CAI_ExpresserHost::ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ) +{ + BaseClass::ModifyOrAppendCriteria( criteriaSet ); + + + if ( this->MyNPCPointer() ) + { + CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( this->MyNPCPointer(), criteriaSet ); + } + +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline IResponseSystem *CAI_ExpresserHost::GetResponseSystem() +{ + extern IResponseSystem *g_pResponseSystem; + // Expressive NPC's use the general response system + return g_pResponseSystem; +} + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline void CAI_ExpresserHost::GatherCriteria( AI_CriteriaSet *outputCriteria, const AIConcept_t &conceptId, const char *modifiers ) +{ + return this->GetExpresser()->GatherCriteria( outputCriteria, conceptId, modifiers ); +} + + +#if 1 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::SpeakFindResponse(AI_Response& outResponse, const AIConcept_t &conceptId, const char *modifiers /*= NULL*/ ) +{ + AI_CriteriaSet criteria; + GatherCriteria(&criteria, conceptId, modifiers); + return FindResponse( outResponse, conceptId, &criteria ); +} +#else +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &conceptId, const char *modifiers /*= NULL*/ ) +{ + return this->GetExpresser()->SpeakFindResponse( conceptId, modifiers ); +} +#endif + +#if 0 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &conceptId, AI_CriteriaSet *criteria /*= NULL*/ ) +{ + return this->GetExpresser()->SpeakFindResponse( conceptId, criteria ); +} + + +//----------------------------------------------------------------------------- +// In this case we clearly don't care to hang on to the criteria, so make a convenience +// class that generates a one off. +//----------------------------------------------------------------------------- +template +inline AI_Response * CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &conceptId ) +{ + AI_CriteriaSet criteria; + GatherCriteria( &criteria, conceptId, NULL ); + return this->GetExpresser()->SpeakFindResponse( conceptId, &criteria ); +} +#endif + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::FindResponse( AI_Response &outResponse, const AIConcept_t &conceptId, AI_CriteriaSet *criteria ) +{ + return this->GetExpresser()->FindResponse( outResponse, conceptId, criteria ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, AI_CriteriaSet *criteria ) +{ + if ( this->GetExpresser()->SpeakDispatchResponse( conceptId, response, criteria ) ) + { + PostSpeakDispatchResponse( conceptId, response ); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline float CAI_ExpresserHost::GetResponseDuration( AI_Response *response ) +{ + return this->GetExpresser()->GetResponseDuration( response ); +} + +//----------------------------------------------------------------------------- +// Override of base entity response input handler +//----------------------------------------------------------------------------- +template +inline void CAI_ExpresserHost::DispatchResponse( const char *conceptName ) +{ + Speak( AIConcept_t( conceptName ) ); +} + +//----------------------------------------------------------------------------- + +/// A shim under CAI_ExpresserHost you can use when deriving a new expresser +/// host type under CAI_BaseNPC. This does the extra step of declaring an m_pExpresser +/// member and initializing it from CreateComponents(). If your BASE_NPC class isn't +/// actually an NPC, then CreateComponents() never gets called and you won't have +/// an expresser created. +/// Note: you still need to add m_pExpresser to the Datadesc for your derived type. +/// This is because I couldn't figure out how to make a templatized datadesc declaration +/// that works generically on the template type. +template +class CAI_ExpresserHostWithData : public CAI_ExpresserHost +{ + DECLARE_CLASS_NOFRIEND( CAI_ExpresserHostWithData, CAI_ExpresserHost ); + +public: + CAI_ExpresserHostWithData( ) : m_pExpresser(NULL) {}; + + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } + const CAI_Expresser *GetExpresser() const { return m_pExpresser; } + + virtual bool CreateComponents() + { + return BaseClass::CreateComponents() && ( CreateExpresser() != NULL ); + } + +protected: + EXPRESSER_TYPE *CreateExpresser( void ) + { + AssertMsg1( m_pExpresser == NULL, "Tried to double-initialize expresser in %s\n", this->GetDebugName() ); + m_pExpresser = new EXPRESSER_TYPE(this); + if ( !m_pExpresser) + { + AssertMsg1( false, "Creating an expresser failed in %s\n", this->GetDebugName() ); + return NULL; + } + + m_pExpresser->Connect(this); + return m_pExpresser; + } + + virtual ~CAI_ExpresserHostWithData( void ) + { + delete m_pExpresser; + m_pExpresser = NULL; + } + + EXPRESSER_TYPE *m_pExpresser; +}; + +/// response rules +namespace RR +{ + /// some applycontext clauses have operators preceding them, + /// like ++1 which means "take the current value and increment it + /// by one". These classes detect these cases and do the appropriate + /// thing. + class CApplyContextOperator + { + public: + inline CApplyContextOperator( int nSkipChars ) : m_nSkipChars(nSkipChars) {}; + + /// perform whatever this operator does upon the given context value. + /// Default op is simply to copy old to new. + /// pOldValue should be the currently set value of the context. May be NULL meaning no prior value. + /// pOperator the value that applycontext says to set + /// pNewValue a pointer to a buffer where the real new value will be writ. + /// returns true on success; false on failure (eg, tried to increment a + /// non-numeric value). + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + + /// This is the function that should be called from outside, + /// fed the input string, it'll select the right operator + /// to apply. + static CApplyContextOperator *FindOperator( const char *pContextString ); + + protected: + int m_nSkipChars; // how many chars to "skip" in the value string to get past the op specifier to the actual value + // eg, "++3" has a m_nSkipChars of 2, because the op string "++" is two characters. + }; + + class CIncrementOperator : public CApplyContextOperator + { + public: + inline CIncrementOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + class CDecrementOperator : public CApplyContextOperator + { + public: + inline CDecrementOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + +#ifdef MAPBASE + class CMultiplyOperator : public CApplyContextOperator + { + public: + inline CMultiplyOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + class CDivideOperator : public CApplyContextOperator + { + public: + inline CDivideOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; +#endif + + class CToggleOperator : public CApplyContextOperator + { + public: + inline CToggleOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + // the singleton operators + extern CApplyContextOperator sm_OpCopy; + extern CIncrementOperator sm_OpIncrement; + extern CDecrementOperator sm_OpDecrement; +#ifdef MAPBASE + extern CMultiplyOperator sm_OpMultiply; + extern CDivideOperator sm_OpDivide; +#endif + extern CToggleOperator sm_OpToggle; + +#ifdef MAPBASE + // LEGACY - See CApplyContextOperator::FindOperator() + extern CIncrementOperator sm_OpLegacyIncrement; + extern CDecrementOperator sm_OpLegacyDecrement; + extern CMultiplyOperator sm_OpLegacyMultiply; + extern CDivideOperator sm_OpLegacyDivide; +#endif +}; + + +//----------------------------------------------------------------------------- +#include "ai_speechqueue.h" + +//----------------------------------------------------------------------------- +// A kind of AI Expresser that can dispatch a follow-up speech event when it +// finishes speaking. +//----------------------------------------------------------------------------- +class CAI_ExpresserWithFollowup : public CAI_Expresser +{ +public: + CAI_ExpresserWithFollowup( CBaseFlex *pOuter = NULL ) : CAI_Expresser(pOuter), + m_pPostponedFollowup(NULL) + {}; + virtual bool Speak( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool SpeakDispatchResponse( AIConcept_t conceptId, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); + virtual void SpeakDispatchFollowup( AI_ResponseFollowup &followup ); + + virtual void OnSpeechFinished(); + + typedef CAI_Expresser BaseClass; +protected: + static void DispatchFollowupThroughQueue( const AIConcept_t &conceptId, + const char *criteriaStr, + const CResponseQueue::CFollowupTargetSpec_t &target, + float delay, + CBaseEntity * RESTRICT pOuter ); + + AI_ResponseFollowup *m_pPostponedFollowup; // TODO: save/restore + CResponseQueue::CFollowupTargetSpec_t m_followupTarget; +}; + +class CMultiplayer_Expresser : public CAI_ExpresserWithFollowup +{ +public: + CMultiplayer_Expresser( CBaseFlex *pOuter = NULL ); + //~CMultiplayer_Expresser(); + + virtual bool IsSpeaking(); + + void AllowMultipleScenes(); + void DisallowMultipleScenes(); + +private: + bool m_bAllowMultipleScenes; + +}; + + +#endif // AI_SPEECH_H diff --git a/game/server/ai_speechqueue.cpp b/game/server/ai_speechqueue.cpp new file mode 100644 index 00000000..a95d8510 --- /dev/null +++ b/game/server/ai_speechqueue.cpp @@ -0,0 +1,495 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "basemultiplayerplayer.h" +#include "ai_baseactor.h" +#include "ai_speech.h" +//#include "flex_expresser.h" +// memdbgon must be the last include file in a .cpp file!!! +#include + +extern ConVar ai_debug_speech; +#define DebuggingSpeech() ai_debug_speech.GetBool() +extern ConVar rr_debugresponses; + +ConVar rr_followup_maxdist( "rr_followup_maxdist", "1800", FCVAR_CHEAT, "'then ANY' or 'then ALL' response followups will be dispatched only to characters within this distance." ); + +/////////////////////////////////////////////////////////////////////////////// +// RESPONSE QUEUE DATA STRUCTURE +/////////////////////////////////////////////////////////////////////////////// + +CResponseQueue::CResponseQueue( int queueSize ) : m_Queue(queueSize), m_ExpresserTargets(8,8) +{}; + +/// Add a deferred response. +void CResponseQueue::Add( const AIConcept_t &rrConcept, ///< concept to dispatch + const AI_CriteriaSet * RESTRICT contexts, + float time, ///< when to dispatch it. You can specify a time of zero to mean "immediately." + const CFollowupTargetSpec_t &targetspec, + CBaseEntity *pIssuer + ) +{ + // Add a response. + AssertMsg( m_Queue.Count() < AI_RESPONSE_QUEUE_SIZE, "AI Response queue overfilled." ); + QueueType_t::IndexLocalType_t idx = m_Queue.AddToTail(); + m_Queue[idx].Init( rrConcept, contexts, time, targetspec, pIssuer ); +} + + +/// Remove a deferred response matching the concept and issuer. +void CResponseQueue::Remove( const AIConcept_t &rrConcept, ///< concept to dispatch + CBaseEntity * const RESTRICT pIssuer ///< the entity issuing the response, if one exists. + ) RESTRICT +{ + // walk through the queue until we find a response matching the concept and issuer, then strike it. + QueueType_t::IndexLocalType_t idx = m_Queue.Head(); + while (idx != m_Queue.InvalidIndex()) + { + CDeferredResponse &response = m_Queue[idx]; + QueueType_t::IndexLocalType_t previdx = idx; // advance the index immediately because we may be deleting the "current" element + idx = m_Queue.Next(idx); // is now the next index + if ( CompareConcepts( response.m_concept, rrConcept ) && // if concepts match and + ( !pIssuer || ( response.m_hIssuer.Get() == pIssuer ) ) // issuer is null, or matches the one in the response + ) + { + m_Queue.Remove(previdx); + } + } +} + + +void CResponseQueue::RemoveSpeechQueuedFor( const CBaseEntity *pSpeaker ) +{ + // walk through the queue until we find a response matching the speaker, then strike it. + // because responses are dispatched from inside a loop that is already walking through the + // queue, it's not safe to actually remove the elements. Instead, quash it by replacing it + // with a null event. + + for ( QueueType_t::IndexLocalType_t idx = m_Queue.Head() ; + idx != m_Queue.InvalidIndex() ; + idx = m_Queue.Next(idx) ) // is now the next index + { + CDeferredResponse &response = m_Queue[idx]; + if ( response.m_Target.m_hHandle.Get() == pSpeaker ) + { + response.Quash(); + } + } +} + +// TODO: use a more compact representation. +void CResponseQueue::DeferContextsFromCriteriaSet( DeferredContexts_t &contextsOut, const AI_CriteriaSet * RESTRICT criteriaIn ) +{ + contextsOut.Reset(); + if (criteriaIn) + { + contextsOut.Merge(criteriaIn); + } +} + +void CResponseQueue::PerFrameDispatch() +{ +failsafe: + // Walk through the list, find any messages whose time has come, and dispatch them. Then remove them. + QueueType_t::IndexLocalType_t idx = m_Queue.Head(); + while (idx != m_Queue.InvalidIndex()) + { + // do we need to dispatch this concept? + CDeferredResponse &response = m_Queue[idx]; + QueueType_t::IndexLocalType_t previdx = idx; // advance the index immediately because we may be deleting the "current" element + idx = m_Queue.Next(idx); // is now the next index + + if ( response.IsQuashed() ) + { + // we can delete this entry now + m_Queue.Remove(previdx); + } + else if ( response.m_fDispatchTime <= gpGlobals->curtime ) + { + // dispatch. we've had bugs where dispatches removed things from inside the queue; + // so, as a failsafe, if the queue length changes as a result, start over. + int oldLength = m_Queue.Count(); + DispatchOneResponse(response); + if ( m_Queue.Count() < oldLength ) + { + AssertMsg( false, "Response queue length changed in non-reentrant way! FAILSAFE TRIGGERED" ); + goto failsafe; // ick + } + + // we can delete this entry now + m_Queue.Remove(previdx); + } + } +} + + +/// Add an expressor owner to this queue. +void CResponseQueue::AddExpresserHost(CBaseEntity *host) +{ + EHANDLE ehost(host); + // see if it's in there already + if (m_ExpresserTargets.HasElement(ehost)) + { + AssertMsg1(false, "Tried to add %s to response queue when it was already in there.", host->GetDebugName()); + } + else + { + // zip through the queue front to back, first see if there's any invalid handles to replace + int count = m_ExpresserTargets.Count(); + for (int i = 0 ; i < count ; ++i ) + { + if ( !m_ExpresserTargets[i].Get() ) + { + m_ExpresserTargets[i] = ehost; + return; + } + } + + // if we're down here we didn't find one to replace, so append the host to the end. + m_ExpresserTargets.AddToTail(ehost); + } +} + +/// Remove an expresser host from this queue. +void CResponseQueue::RemoveExpresserHost(CBaseEntity *host) +{ + int idx = m_ExpresserTargets.Find(host); + if (idx == -1) + { + // AssertMsg1(false, "Tried to remove %s from response queue, but it's not in there to begin with!", host->GetDebugName() ); + } + else + { + m_ExpresserTargets.FastRemove(idx); + } +} + +/// Get the expresser for a base entity. +/// TODO: Kind of an ugly hack until I get the class hierarchy straightened out. +static CAI_Expresser *InferExpresserFromBaseEntity(CBaseEntity * RESTRICT pEnt) +{ +#ifdef MAPBASE + if ( CBasePlayer *pPlayer = ToBasePlayer(pEnt) ) +#else + if ( CBaseMultiplayerPlayer *pPlayer = dynamic_cast(pEnt) ) +#endif + { + return pPlayer->GetExpresser(); + } + else if ( CAI_BaseActor *pActor = dynamic_cast(pEnt) ) + { + return pActor->GetExpresser(); + } + /* + else if ( CFlexExpresser *pFlex = dynamic_cast(pEnt) ) + { + return pFlex->GetExpresser(); + } + */ + else + { + return NULL; + } +} + + +void CResponseQueue::CDeferredResponse::Quash() +{ + m_Target = CFollowupTargetSpec_t(); + m_fDispatchTime = 0; +} + +bool CResponseQueue::DispatchOneResponse(CDeferredResponse &response) +{ + // find the target. + CBaseEntity * RESTRICT pTarget = NULL; + AI_CriteriaSet &deferredCriteria = response.m_contexts; + CAI_Expresser * RESTRICT pEx = NULL; + CBaseEntity * RESTRICT pIssuer = response.m_hIssuer.Get(); // MAY BE NULL + float followupMaxDistSq; + { + /* + CFlexExpresser * RESTRICT pOrator = CFlexExpresser::AsFlexExpresser( pIssuer ); + if ( pOrator ) + { + // max dist is overridden. "0" means infinite distance (for orators only), + // anything else is a finite distance. + if ( pOrator->m_flThenAnyMaxDist > 0 ) + { + followupMaxDistSq = pOrator->m_flThenAnyMaxDist * pOrator->m_flThenAnyMaxDist; + } + else + { + followupMaxDistSq = FLT_MAX; + } + + } + else + */ + { + followupMaxDistSq = rr_followup_maxdist.GetFloat(); // square of max audibility distance + followupMaxDistSq *= followupMaxDistSq; + } + } + + switch (response.m_Target.m_iTargetType) + { + case kDRT_SPECIFIC: + { + pTarget = response.m_Target.m_hHandle.Get(); + } + break; + case kDRT_ANY: + { + return DispatchOneResponse_ThenANY( response, &deferredCriteria, pIssuer, followupMaxDistSq ); + } + break; + case kDRT_ALL: + { + bool bSaidAnything = false; + Vector issuerLocation; + if ( pIssuer ) + { + issuerLocation = pIssuer->GetAbsOrigin(); + } + + // find all characters + int numExprs = GetNumExpresserTargets(); + for ( int i = 0 ; i < numExprs; ++i ) + { + pTarget = GetExpresserHost(i); + float distIssuerToTargetSq = 0.0f; + if ( pIssuer ) + { + distIssuerToTargetSq = (pTarget->GetAbsOrigin() - issuerLocation).LengthSqr(); + if ( distIssuerToTargetSq > followupMaxDistSq ) + continue; // too far + } + + pEx = InferExpresserFromBaseEntity(pTarget); + if ( !pEx || pTarget == pIssuer ) + continue; + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge(&deferredCriteria); + if ( pIssuer ) + { + characterCriteria.AppendCriteria( "dist_from_issuer", UTIL_VarArgs( "%f", sqrt(distIssuerToTargetSq) ) ); + } + AI_Response prospectiveResponse; + if ( pEx->FindResponse( prospectiveResponse, response.m_concept, &characterCriteria ) ) + { + // dispatch it + bSaidAnything = pEx->SpeakDispatchResponse(response.m_concept, &prospectiveResponse, &deferredCriteria) || bSaidAnything ; + } + } + + return bSaidAnything; + + } + break; + default: + // WTF? + AssertMsg1( false, "Unknown deferred response type %d\n", response.m_Target.m_iTargetType ); + return false; + } + + if (!pTarget) + return false; // we're done right here. + + // Get the expresser for the target. + pEx = InferExpresserFromBaseEntity(pTarget); + if (!pEx) + return false; + + + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge(&deferredCriteria); + pEx->Speak( response.m_concept, &characterCriteria ); + + return true; +} + +// +ConVar rr_thenany_score_slop( "rr_thenany_score_slop", "0.0", FCVAR_CHEAT, "When computing respondents for a 'THEN ANY' rule, all rule-matching scores within this much of the best score will be considered." ); +#define EXARRAYMAX 32 // maximum number of prospective expressers in the array (hardcoded for simplicity) +bool CResponseQueue::DispatchOneResponse_ThenANY( CDeferredResponse &response, AI_CriteriaSet * RESTRICT pDeferredCriteria, CBaseEntity * const RESTRICT pIssuer, float followupMaxDistSq ) +{ + CBaseEntity * RESTRICT pTarget = NULL; + CAI_Expresser * RESTRICT pEx = NULL; + float bestScore = 0; + float slop = rr_thenany_score_slop.GetFloat(); + Vector issuerLocation; + if ( pIssuer ) + { + issuerLocation = pIssuer->GetAbsOrigin(); + } + + // this is an array of prospective respondents. + CAI_Expresser * RESTRICT pBestEx[EXARRAYMAX]; + AI_Response responseToSay[EXARRAYMAX]; + int numExFound = 0; // and this is the high water mark for the array. + + // Here's the algorithm: we're going to walk through all the characters, finding the + // highest scoring ones for this rule. Let the highest score be called k. + // Because there may be (n) many characters all scoring k, we store an array of + // all characters with score k, then choose randomly from that array at return. + // We also define an allowable error for k in the global cvar + // rr_thenany_score_slop , which may be zero. + + // find all characters (except the issuer) + int numExprs = GetNumExpresserTargets(); + AssertMsg1( numExprs <= EXARRAYMAX, "Response queue has %d possible expresser targets, please increase EXARRAYMAX ", numExprs ); + for ( int i = 0 ; i < numExprs; ++i ) + { + pTarget = GetExpresserHost(i); + if ( pTarget == pIssuer ) + continue; // don't dispatch to myself + + if ( !pTarget->IsAlive() ) + continue; // dead men tell no tales + + float distIssuerToTargetSq = 0.0f; + if ( pIssuer ) + { + distIssuerToTargetSq = (pTarget->GetAbsOrigin() - issuerLocation).LengthSqr(); + if ( distIssuerToTargetSq > followupMaxDistSq ) + continue; // too far + } + + pEx = InferExpresserFromBaseEntity(pTarget); + if ( !pEx ) + continue; + + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge( pDeferredCriteria ); + pTarget->ModifyOrAppendDerivedCriteria( characterCriteria ); + if ( pIssuer ) + { + characterCriteria.AppendCriteria( "dist_from_issuer", UTIL_VarArgs( "%f", sqrt(distIssuerToTargetSq) ) ); + } + AI_Response prospectiveResponse; + +#ifdef MAPBASE + pEx->SetUsingProspectiveResponses( true ); +#endif + + if ( pEx->FindResponse( prospectiveResponse, response.m_concept, &characterCriteria ) ) + { + float score = prospectiveResponse.GetMatchScore(); + if ( score > 0 && !prospectiveResponse.IsEmpty() ) // ignore scores that are zero, regardless of slop + { + // if this score is better than all we've seen (outside the slop), then replace the array with + // an entry just to this expresser + if ( score > bestScore + slop ) + { + responseToSay[0] = prospectiveResponse; + pBestEx[0] = pEx; + bestScore = score; + numExFound = 1; + } + else if ( score >= bestScore - slop ) // if this score is at least as good as the best we've seen, but not better than all + { + if ( numExFound >= EXARRAYMAX ) + { +#ifdef MAPBASE + pEx->SetUsingProspectiveResponses( false ); +#endif + continue; // SAFETY: don't overflow the array + } + + responseToSay[numExFound] = prospectiveResponse; + pBestEx[numExFound] = pEx; + bestScore = fpmax( score, bestScore ); + numExFound += 1; + } + } + } + +#ifdef MAPBASE + pEx->SetUsingProspectiveResponses( false ); +#endif + } + + // if I have a response, dispatch it. + if ( numExFound > 0 ) + { + // get a random number between 0 and the responses found + int iSelect = numExFound > 1 ? RandomInt( 0, numExFound - 1 ) : 0; + + if ( pBestEx[iSelect] != NULL ) + { +#ifdef MAPBASE + pBestEx[iSelect]->MarkResponseAsUsed( responseToSay + iSelect ); +#endif + return pBestEx[iSelect]->SpeakDispatchResponse( response.m_concept, responseToSay + iSelect, pDeferredCriteria ); + } + else + { + AssertMsg( false, "Response queue somehow found a response, but no expresser for it.\n" ); + return false; + } + } + else + { // I did not find a response. + return false; + } + + return false; // just in case +} + +void CResponseQueue::Evacuate() +{ + m_Queue.RemoveAll(); +} + +#undef EXARRAYMAX + + +/////////////////////////////////////////////////////////////////////////////// +// RESPONSE QUEUE MANAGER +/////////////////////////////////////////////////////////////////////////////// + + +void CResponseQueueManager::LevelInitPreEntity( void ) +{ + if (m_pQueue == NULL) + { + m_pQueue = new CResponseQueue(AI_RESPONSE_QUEUE_SIZE); + } +} + +CResponseQueueManager::~CResponseQueueManager() +{ + if (m_pQueue != NULL) + { + delete m_pQueue; + m_pQueue = NULL; + } +} + +void CResponseQueueManager::Shutdown() +{ + if (m_pQueue != NULL) + { + delete m_pQueue; + m_pQueue = NULL; + } +} + +void CResponseQueueManager::FrameUpdatePostEntityThink() +{ + Assert(m_pQueue); + m_pQueue->PerFrameDispatch(); +} + +CResponseQueueManager g_ResponseQueueManager( "CResponseQueueManager" ); + diff --git a/game/server/ai_speechqueue.h b/game/server/ai_speechqueue.h new file mode 100644 index 00000000..af173f09 --- /dev/null +++ b/game/server/ai_speechqueue.h @@ -0,0 +1,239 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: An event queue of AI concepts that dispatches them to appropriate characters. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SPEECHQUEUE_H +#define AI_SPEECHQUEUE_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "ai_speech.h" + +#define AI_RESPONSE_QUEUE_SIZE 64 + +enum DeferredResponseTarget_t // possible targets for a deferred response +{ + kDRT_ANY, // best matching respondent within range -- except for the one in the m_hTarget handle + kDRT_ALL, // send to everyone in range -- except for the one in the m_hTarget handle + kDRT_SPECIFIC, // a specific entity is targeted + + kDRT_MAX, // high water mark +}; + +// Allows you to postpone AI speech concepts to a later time, or to direct them to +// a specific character, or all of them. +class CResponseQueue +{ + //////////////////// Local types //////////////////// +public: + + // We pack up contexts to send along with the concept. + // For now I'll just copy criteria sets, but it will be better to do something + // more efficient in the future. + typedef AI_CriteriaSet DeferredContexts_t; + + struct CFollowupTargetSpec_t ///< to whom a followup is directed. Can be a specific entity or something more exotic. + { + DeferredResponseTarget_t m_iTargetType; ///< ANY, ALL, or SPECIFIC. If specific, pass through a handle to: + EHANDLE m_hHandle; ///< a specific target for the message, or a specific character to OMIT. + inline bool IsValid( void ) const; + + // constructors/destructors + explicit CFollowupTargetSpec_t(const DeferredResponseTarget_t &targetType, const EHANDLE &handle) + : m_iTargetType(targetType), m_hHandle(handle) + {}; + explicit CFollowupTargetSpec_t(const EHANDLE &handle) + : m_iTargetType(kDRT_SPECIFIC), m_hHandle(handle) + {}; + CFollowupTargetSpec_t(DeferredResponseTarget_t target) // eg, ANY, ALL, etc. + : m_iTargetType(target) + { + AssertMsg(m_iTargetType != kDRT_SPECIFIC, "Response rule followup tried to specify an entity target, but didn't provide the target.\n" ); + } + CFollowupTargetSpec_t(void) // default: invalid + : m_iTargetType(kDRT_MAX) + {}; + }; + + /// A single deferred response. + struct CDeferredResponse + { + AIConcept_t m_concept; + DeferredContexts_t m_contexts; ///< contexts to send along with the concept + float m_fDispatchTime; + EHANDLE m_hIssuer; ///< an entity, if issued by an entity + /* + DeferredResponseTarget_t m_iTargetType; + EHANDLE m_hTarget; // May be invalid. + */ + CFollowupTargetSpec_t m_Target; + + inline void Init( const AIConcept_t &rrConcept, const AI_CriteriaSet * RESTRICT contexts, float dtime, const CFollowupTargetSpec_t &target, CBaseEntity *pIssuer ); + inline bool IsQuashed() { return !m_Target.IsValid(); } + void Quash(); ///< make this response invalid. + }; + /// write + static void DeferContextsFromCriteriaSet( DeferredContexts_t &contextsOut, const AI_CriteriaSet *criteriaIn ); + + //////////////////// Methods //////////////////// +public: + CResponseQueue( int queueSize ); + + /// Add a deferred response. + void Add( const AIConcept_t &rrConcept, ///< concept to dispatch + const AI_CriteriaSet * RESTRICT contexts, ///< the contexts that come with it (may be NULL) + float time, ///< when to dispatch it. You can specify a time of zero to mean "immediately." + const CFollowupTargetSpec_t &targetspec, /// All information necessary to target this response + CBaseEntity *pIssuer = NULL ///< the entity who should not respond if this is a ANY or ALL rule. (eg, don't let people talk to themselves.) + ); + + /// Remove all deferred responses matching the concept and issuer. + void Remove( const AIConcept_t &rrConcept, ///< concept to dispatch + CBaseEntity * const pIssuer = NULL ///< the entity issuing the response, if one exists. + ); + + /// Remove all deferred responses queued to be spoken by given character + void RemoveSpeechQueuedFor( const CBaseEntity *pSpeaker ); + + /// Empty out all pending events + void Evacuate(); + + /// Go through and dispatch any deferred responses. + void PerFrameDispatch(); + + /// Add an expressor owner to this queue. + void AddExpresserHost(CBaseEntity *host); + + /// Remove an expresser host from this queue. + void RemoveExpresserHost(CBaseEntity *host); + + /// Iterate over potential expressers for this queue + inline int GetNumExpresserTargets() const; + inline CBaseEntity *GetExpresserHost(int which) const; + +protected: + /// Actually send off one response to a consumer + /// Return true if dispatch succeeded + bool DispatchOneResponse( CDeferredResponse &response ); + +private: + /// Helper function for one case in DispatchOneResponse + /// (for better organization) + bool DispatchOneResponse_ThenANY( CDeferredResponse &response, AI_CriteriaSet * RESTRICT pDeferredCriteria, CBaseEntity * const RESTRICT pIssuer, float followupMaxDistSq ); + + //////////////////// Data //////////////////// +protected: + typedef CUtlFixedLinkedList< CDeferredResponse > QueueType_t; + QueueType_t m_Queue; // the queue of deferred responses, will eventually be sorted + /// Note about the queue type: if you move to replace it with a sorted priority queue, + /// make sure it is a type such that an iterator is not invalidated by inserts and deletes. + /// CResponseQueue::PerFrameDispatch() iterates over the queue calling DispatchOneResponse + /// on each in turn, and those responses may very easily add new events to the queue. + /// A crash will result if the iterator used in CResponseQueue::PerFrameDispatch()'s loop + /// becomes invalid. + + CUtlVector m_ExpresserTargets; // a list of legitimate expresser targets +}; + +inline void CResponseQueue::CDeferredResponse::Init(const AIConcept_t &rrConcept, const AI_CriteriaSet * RESTRICT contexts, float dtime, const CFollowupTargetSpec_t &target, CBaseEntity *pIssuer ) +{ + m_concept = rrConcept; + m_fDispatchTime = dtime; + /* + m_iTargetType = targetType; + m_hTarget = handle ; + */ + m_Target = target; + m_hIssuer = pIssuer; + DeferContextsFromCriteriaSet(m_contexts, contexts); +} + +int CResponseQueue::GetNumExpresserTargets() const +{ + return m_ExpresserTargets.Count(); +} + +CBaseEntity *CResponseQueue::GetExpresserHost(int which) const +{ + return m_ExpresserTargets[which]; +} + + +// The wrapper game system that contains a response queue, and ticks it each frame. + +class CResponseQueueManager : public CAutoGameSystemPerFrame +{ +public: + CResponseQueueManager(char const *name) : CAutoGameSystemPerFrame( name ) + { + m_pQueue = NULL; + } + virtual ~CResponseQueueManager(void); + virtual void Shutdown(); + virtual void FrameUpdatePostEntityThink( void ); + virtual void LevelInitPreEntity( void ); + + inline CResponseQueue *GetQueue(void) { Assert(m_pQueue); return m_pQueue; } + +protected: + CResponseQueue *m_pQueue; +}; + + +// Valid if the target type enum is within bounds. Furthermore if it +// specifies a specific entity, that handle must be valid. +bool CResponseQueue::CFollowupTargetSpec_t::IsValid( void ) const +{ + if (m_iTargetType >= kDRT_MAX) + return false; + if (m_iTargetType < 0) + return false; + if (m_iTargetType == kDRT_SPECIFIC && !m_hHandle.IsValid()) + return false; + + return true; +} + +extern CResponseQueueManager g_ResponseQueueManager; + + +// Handy global helper funcs + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &rrConcept, ///< concept name to say + const CResponseQueue::CFollowupTargetSpec_t& targetspec, ///< kDRT_ANY, kDRT_ALL, etc + CBaseEntity *pIssuer = NULL ///< if specifying ANY or ALL, use this to specify the one you *don't* want to speak + ) +{ + return g_ResponseQueueManager.GetQueue()->Add( rrConcept, NULL, 0.0f, targetspec, pIssuer ); +} + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &rrConcept, ///< concept name to say + const CResponseQueue::CFollowupTargetSpec_t& targetspec, ///< kDRT_ANY, kDRT_ALL, etc + const AI_CriteriaSet &criteria, ///< criteria to pass in + CBaseEntity *pIssuer = NULL ///< if specifying ANY or ALL, use this to specify the one you *don't* want to speak + ) +{ + return g_ResponseQueueManager.GetQueue()->Add( rrConcept, &criteria, 0.0f, targetspec, pIssuer ); +} + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &rrConcept, ///< concept name to say + const EHANDLE &target, ///< which entity shall speak + float delay, ///< how far in the future to speak + const AI_CriteriaSet &criteria, ///< criteria to pass in + CBaseEntity *pIssuer = NULL ) +{ + return g_ResponseQueueManager.GetQueue()->Add( rrConcept, &criteria, gpGlobals->curtime + delay, + CResponseQueue::CFollowupTargetSpec_t(target), pIssuer ); +} + + + +#endif // AI_SPEECHQUEUE_H diff --git a/game/server/ai_squad.cpp b/game/server/ai_squad.cpp index 17e0c18f..15e7fb68 100644 --- a/game/server/ai_squad.cpp +++ b/game/server/ai_squad.cpp @@ -114,6 +114,48 @@ void CAI_SquadManager::DeleteAllSquads(void) CAI_SquadManager::m_pSquads = NULL; } +#ifdef MAPBASE_VSCRIPT +//------------------------------------- +// Purpose: +//------------------------------------- +HSCRIPT CAI_SquadManager::ScriptGetFirstSquad() +{ + return m_pSquads ? g_pScriptVM->RegisterInstance( m_pSquads ) : NULL; +} + +HSCRIPT CAI_SquadManager::ScriptGetNextSquad( HSCRIPT hStart ) +{ + CAI_Squad *pSquad = HScriptToClass( hStart ); + return (pSquad && pSquad->m_pNextSquad) ? g_pScriptVM->RegisterInstance( pSquad->m_pNextSquad ) : NULL; +} + +//------------------------------------- +// Purpose: +//------------------------------------- +HSCRIPT CAI_SquadManager::ScriptFindSquad( const char *squadName ) +{ + CAI_Squad *pSquad = FindSquad( MAKE_STRING(squadName) ); + return pSquad ? g_pScriptVM->RegisterInstance( pSquad ) : NULL; +} + +HSCRIPT CAI_SquadManager::ScriptFindCreateSquad( const char *squadName ) +{ + CAI_Squad *pSquad = FindCreateSquad( MAKE_STRING( squadName ) ); + return pSquad ? g_pScriptVM->RegisterInstance( pSquad ) : NULL; +} + +BEGIN_SCRIPTDESC_ROOT( CAI_SquadManager, SCRIPT_SINGLETON "Manager for NPC squads." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFirstSquad, "GetFirstSquad", "Get the first squad in the squad list." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNextSquad, "GetNextSquad", "Get the next squad in the squad list starting from the specified squad." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFindSquad, "FindSquad", "Find the specified squad in the squad list. Returns null if none found." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFindCreateSquad, "FindCreateSquad", "Find the specified squad in the squad list or create it if it doesn't exist." ) + + DEFINE_SCRIPTFUNC( NumSquads, "Get the number of squads in the list." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- // CAI_Squad // @@ -151,6 +193,38 @@ BEGIN_SIMPLE_DATADESC( CAI_Squad ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CAI_Squad, "NPC squads used for schedule coordination, sharing information about enemies, etc." ) + + DEFINE_SCRIPTFUNC( GetName, "Get the squad's name." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFirstMember, "GetFirstMember", "Get the squad's first member. The parameter is for whether to ignore silent members (see CAI_Squad::IsSilentMember() for more info)." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetMember, "GetMember", "Get one of the squad's members by their index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAnyMember, "GetAnyMember", "Randomly get any one of the squad's members." ) + DEFINE_SCRIPTFUNC( NumMembers, "Get the squad's number of members. The parameter is for whether to ignore silent members (see CAI_Squad::IsSilentMember() for more info)." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSquadIndex, "GetSquadIndex", "Get the index of the specified NPC in the squad." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptUpdateEnemyMemory, "UpdateEnemyMemory", "Updates the squad's memory of an enemy. The first parameter is the updater, the second parameter is the enemy, and the third parameter is the position." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSquadMemberInRange, "SquadMemberInRange", "Get the first squad member found around the specified position in the specified range." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptNearestSquadMember, "NearestSquadMember", "Get the squad member nearest to the specified member." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetVisibleSquadMembers, "GetVisibleSquadMembers", "Get the number of squad members visible to the specified member." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSquadMemberNearestTo, "GetSquadMemberNearestTo", "Get the squad member nearest to a point." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsMember, "IsMember", "Returns true if the specified NPC is a member of the squad." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsLeader, "IsLeader", "Returns true if the specified NPC is the squad's leader." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeader, "GetLeader", "Get the squad's leader." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddToSquad, "AddToSquad", "Adds a NPC to the squad." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptRemoveFromSquad, "RemoveFromSquad", "Removes a NPC from the squad." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptIsSilentMember, "IsSilentMember", "Returns true if the specified NPC is a \"silent squad member\", which means it's only in squads for enemy information purposes and does not actually participate in any tactics. For example, this is used for npc_enemyfinder and vital allies (e.g. Alyx) in the player's squad. Please note that this does not check if the NPC is in the squad first." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetSquadData, "SetSquadData", "Set the squad data in the specified slot." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSquadData, "GetSquadData", "Get the squad data in the specified slot." ) + +END_SCRIPTDESC(); +#endif + //------------------------------------- CAI_Squad::CAI_Squad(string_t newName) @@ -220,7 +294,7 @@ void CAI_Squad::RemoveFromSquad( CAI_BaseNPC *pNPC, bool bDeath ) int myIndex = m_SquadMembers.Find(pNPC); if (myIndex == -1) { - DevMsg("ERROR: Attempting to remove non-existing squad membmer!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: Attempting to remove non-existing squad member!\n" ); return; } m_SquadMembers.Remove(myIndex); @@ -263,7 +337,7 @@ void CAI_Squad::AddToSquad(CAI_BaseNPC *pNPC) if (m_SquadMembers.Count() == MAX_SQUAD_MEMBERS) { - DevMsg("Error!! Squad %s is too big!!! Replacing last member\n", STRING( this->m_Name )); + CGMsg( 1, CON_GROUP_NPC_AI, "Error!! Squad %s is too big!!! Replacing last member\n", STRING( this->m_Name ) ); m_SquadMembers.Remove(m_SquadMembers.Count()-1); } m_SquadMembers.AddToTail(pNPC); @@ -485,7 +559,7 @@ void CAI_Squad::SquadNewEnemy( CBaseEntity *pEnemy ) { if ( !pEnemy ) { - DevMsg( "ERROR: SquadNewEnemy() - pEnemy is NULL!\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR: SquadNewEnemy() - pEnemy is NULL!\n" ); return; } @@ -604,7 +678,7 @@ bool CAI_Squad::OccupyStrategySlotRange( CBaseEntity *pEnemy, int slotIDStart, i // As a debug measure check to see if slot was filled if (!IsSlotOccupied(pEnemy, *pSlot)) { - DevMsg( "ERROR! Vacating an empty slot!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR! Vacating an empty slot!\n" ); } // Free the slot @@ -643,7 +717,7 @@ void CAI_Squad::VacateStrategySlot( CBaseEntity *pEnemy, int slot) // As a debug measure check to see if slot was filled if (!IsSlotOccupied(pEnemy, slot)) { - DevMsg( "ERROR! Vacating an empty slot!\n"); + CGMsg( 1, CON_GROUP_NPC_AI, "ERROR! Vacating an empty slot!\n" ); } // Free the slot @@ -783,5 +857,44 @@ bool CAI_Squad::IsSquadInflictor( CBaseEntity *pInflictor ) return (m_hSquadInflictor.Get() == pInflictor); } +#ifdef MAPBASE_VSCRIPT +//------------------------------------------------------------------------------ + +// Functions tailored specifically for VScript. + +HSCRIPT CAI_Squad::ScriptGetFirstMember( bool bIgnoreSilentMembers ) { return ToHScript( GetFirstMember( NULL, bIgnoreSilentMembers ) ); } +HSCRIPT CAI_Squad::ScriptGetMember( int iIndex ) { return iIndex < m_SquadMembers.Count() ? ToHScript( m_SquadMembers[iIndex] ) : NULL; } +HSCRIPT CAI_Squad::ScriptGetAnyMember() { return ToHScript( GetAnyMember() ); } +//int CAI_Squad::ScriptNumMembers( bool bIgnoreSilentMembers ) { return NumMembers( bIgnoreSilentMembers ); } +int CAI_Squad::ScriptGetSquadIndex( HSCRIPT hNPC ) { return GetSquadIndex( HScriptToClass( hNPC ) ); } + +void CAI_Squad::ScriptUpdateEnemyMemory( HSCRIPT hUpdater, HSCRIPT hEnemy, const Vector &position ) { UpdateEnemyMemory( HScriptToClass( hUpdater ), ToEnt( hEnemy ), position ); } + +HSCRIPT CAI_Squad::ScriptSquadMemberInRange( const Vector &vecLocation, float flDist ) { return ToHScript( SquadMemberInRange( vecLocation, flDist ) ); } +HSCRIPT CAI_Squad::ScriptNearestSquadMember( HSCRIPT hMember ) { return ToHScript( NearestSquadMember( HScriptToClass( hMember ) ) ); } +int CAI_Squad::ScriptGetVisibleSquadMembers( HSCRIPT hMember ) { return GetVisibleSquadMembers( HScriptToClass( hMember ) ); } +HSCRIPT CAI_Squad::ScriptGetSquadMemberNearestTo( const Vector &vecLocation ) { return ToHScript( GetSquadMemberNearestTo( vecLocation ) ); } +bool CAI_Squad::ScriptIsMember( HSCRIPT hMember ) { return SquadIsMember( HScriptToClass( hMember ) ); } +bool CAI_Squad::ScriptIsLeader( HSCRIPT hLeader ) { return IsLeader( HScriptToClass( hLeader ) ); } +HSCRIPT CAI_Squad::ScriptGetLeader( void ) { return ToHScript( GetLeader() ); } + +void CAI_Squad::ScriptAddToSquad( HSCRIPT hNPC ) { AddToSquad( HScriptToClass( hNPC ) ); } +void CAI_Squad::ScriptRemoveFromSquad( HSCRIPT hNPC ) { RemoveFromSquad( HScriptToClass( hNPC ), false ); } + +bool CAI_Squad::ScriptIsSilentMember( HSCRIPT hNPC ) { return IsSilentMember( HScriptToClass( hNPC ) ); } + +void CAI_Squad::ScriptSetSquadData( int iSlot, const char *data ) +{ + SetSquadData( iSlot, data ); +} + +const char *CAI_Squad::ScriptGetSquadData( int iSlot ) +{ + const char *data; + GetSquadData( iSlot, &data ); + return data; +} +#endif + //============================================================================= diff --git a/game/server/ai_squad.h b/game/server/ai_squad.h index 846e9a11..9604d1f0 100644 --- a/game/server/ai_squad.h +++ b/game/server/ai_squad.h @@ -52,6 +52,14 @@ class CAI_SquadManager void DeleteSquad( CAI_Squad *pSquad ); void DeleteAllSquads(void); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetFirstSquad(); + HSCRIPT ScriptGetNextSquad( HSCRIPT hStart ); + + HSCRIPT ScriptFindSquad( const char *squadName ); + HSCRIPT ScriptFindCreateSquad( const char *squadName ); +#endif + private: CAI_Squad * m_pSquads; // A linked list of all squads @@ -152,6 +160,36 @@ class CAI_Squad void VacateSlot( CBaseEntity *pEnemy, int i ); bool IsSlotOccupied( CBaseEntity *pEnemy, int i ) const; +#ifdef MAPBASE_VSCRIPT + // Functions tailored specifically for VScript. + ALLOW_SCRIPT_ACCESS(); +private: + + HSCRIPT ScriptGetFirstMember( bool bIgnoreSilentMembers ); + HSCRIPT ScriptGetMember( int iIndex ); + HSCRIPT ScriptGetAnyMember(); + //int ScriptNumMembers( bool bIgnoreSilentMembers ); + int ScriptGetSquadIndex( HSCRIPT hNPC ); + + void ScriptUpdateEnemyMemory( HSCRIPT hUpdater, HSCRIPT hEnemy, const Vector &position ); + + HSCRIPT ScriptSquadMemberInRange( const Vector &vecLocation, float flDist ); + HSCRIPT ScriptNearestSquadMember( HSCRIPT hMember ); + int ScriptGetVisibleSquadMembers( HSCRIPT hMember ); + HSCRIPT ScriptGetSquadMemberNearestTo( const Vector &vecLocation ); + bool ScriptIsMember( HSCRIPT hMember ); + bool ScriptIsLeader( HSCRIPT hLeader ); + HSCRIPT ScriptGetLeader( void ); + + void ScriptAddToSquad( HSCRIPT hNPC ); + void ScriptRemoveFromSquad( HSCRIPT hNPC ); + + bool ScriptIsSilentMember( HSCRIPT hNPC ); + + void ScriptSetSquadData( int iSlot, const char *data ); + const char *ScriptGetSquadData( int iSlot ); +#endif + private: friend class CAI_SaveRestoreBlockHandler; friend class CAI_SquadManager; diff --git a/game/server/ai_squadslot.h b/game/server/ai_squadslot.h index c0dfcaed..53e43a3e 100644 --- a/game/server/ai_squadslot.h +++ b/game/server/ai_squadslot.h @@ -29,7 +29,6 @@ enum SQUAD_SLOT_t { SQUAD_SLOT_ATTACK1 = 0, // reserve 2 attack slots for most squads SQUAD_SLOT_ATTACK2, - SQUAD_SLOT_ATTACK3, SQUAD_SLOT_INVESTIGATE_SOUND, diff --git a/game/server/ai_tacticalservices.cpp b/game/server/ai_tacticalservices.cpp index 87399c4f..8bcdcc08 100644 --- a/game/server/ai_tacticalservices.cpp +++ b/game/server/ai_tacticalservices.cpp @@ -411,7 +411,12 @@ int CAI_TacticalServices::FindCoverNode(const Vector &vNearPos, const Vector &vT // -------------------------------------------------------- pNode->Lock( 1.0 ); +#ifdef MAPBASE + if ( pNode->GetHint() && ( pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_MED || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_LOW + || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_CUSTOM ) ) +#else if ( pNode->GetHint() && ( pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_MED || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_LOW ) ) +#endif { if ( GetOuter()->GetHintNode() ) { diff --git a/game/server/ai_task.cpp b/game/server/ai_task.cpp index a2cf6be6..6e471351 100644 --- a/game/server/ai_task.cpp +++ b/game/server/ai_task.cpp @@ -222,6 +222,9 @@ void CAI_BaseNPC::InitDefaultTaskSR(void) ADD_DEF_TASK( TASK_ADD_HEALTH ); ADD_DEF_TASK( TASK_GET_PATH_TO_INTERACTION_PARTNER ); ADD_DEF_TASK( TASK_PRE_SCRIPT ); +#ifdef MAPBASE + ADD_DEF_TASK( TASK_FACE_INTERACTION_ANGLES ); +#endif } diff --git a/game/server/ai_task.h b/game/server/ai_task.h index 43170a39..dc167752 100644 --- a/game/server/ai_task.h +++ b/game/server/ai_task.h @@ -494,6 +494,11 @@ enum sharedtasks_e // First task of all schedules for playing back scripted sequences TASK_PRE_SCRIPT, +#ifdef MAPBASE + // Faces the actual interaction angles instead of just facing the enemy + TASK_FACE_INTERACTION_ANGLES, +#endif + // ====================================== // IMPORTANT: This must be the last enum // ====================================== diff --git a/game/server/baseanimating.cpp b/game/server/baseanimating.cpp index 6d34aeac..5462e984 100644 --- a/game/server/baseanimating.cpp +++ b/game/server/baseanimating.cpp @@ -27,6 +27,14 @@ #include "datacache/idatacache.h" #include "smoke_trail.h" #include "props.h" +#ifdef MAPBASE +#include "ai_speech.h" +#include "gib.h" +#include "CRagdollMagnet.h" +#endif +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -202,14 +210,21 @@ BEGIN_DATADESC( CBaseAnimating ) DEFINE_INPUTFUNC( FIELD_INTEGER, "IgniteNumHitboxFires", InputIgniteNumHitboxFires ), DEFINE_INPUTFUNC( FIELD_FLOAT, "IgniteHitboxFireScale", InputIgniteHitboxFireScale ), DEFINE_INPUTFUNC( FIELD_VOID, "BecomeRagdoll", InputBecomeRagdoll ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "CreateSeparateRagdoll", InputCreateSeparateRagdoll ), + DEFINE_INPUTFUNC( FIELD_VOID, "CreateSeparateRagdollClient", InputCreateSeparateRagdollClient ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetPoseParameter", InputSetPoseParameter ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetLightingOriginHack", InputSetLightingOriginRelative ), DEFINE_INPUTFUNC( FIELD_STRING, "SetLightingOrigin", InputSetLightingOrigin ), DEFINE_OUTPUT( m_OnIgnite, "OnIgnite" ), - #ifdef VANCE DEFINE_KEYFIELD( m_bHackable, FIELD_BOOLEAN, "Hackable" ), DEFINE_OUTPUT( m_OnHacked, "OnHacked" ), #endif +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnServerRagdoll, "OnServerRagdoll" ), +#endif DEFINE_INPUT( m_fadeMinDist, FIELD_FLOAT, "fademindist" ), DEFINE_INPUT( m_fadeMaxDist, FIELD_FLOAT, "fademaxdist" ), @@ -217,6 +232,12 @@ BEGIN_DATADESC( CBaseAnimating ) DEFINE_KEYFIELD( m_flModelScale, FIELD_FLOAT, "modelscale" ), DEFINE_INPUTFUNC( FIELD_VECTOR, "SetModelScale", InputSetModelScale ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetModel", InputSetModel ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetCycle", InputSetCycle ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPlaybackRate", InputSetPlaybackRate ), +#endif DEFINE_FIELD( m_fBoneCacheFlags, FIELD_SHORT ), @@ -268,6 +289,75 @@ IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating) END_SEND_TABLE() +#ifdef MAPBASE_VSCRIPT +ScriptHook_t CBaseAnimating::g_Hook_OnServerRagdoll; +ScriptHook_t CBaseAnimating::g_Hook_HandleAnimEvent; +#endif + +BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" ) + + DEFINE_SCRIPTFUNC( LookupAttachment, "Get the named attachement id" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentOrigin, "GetAttachmentOrigin", "Get the attachement id's origin vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentAngles, "GetAttachmentAngles", "Get the attachement id's angles as a p,y,r vector" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentMatrix, "GetAttachmentMatrix", "Get the attachement id's matrix transform" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPoseParameter, "GetPoseParameter", "Get the specified pose parameter's value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" ) + DEFINE_SCRIPTFUNC( LookupBone, "Get the named bone id" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoneTransform, "GetBoneTransform", "Get the transform for the specified bone" ) + DEFINE_SCRIPTFUNC( GetPhysicsBone, "Get physics bone from bone index" ) + DEFINE_SCRIPTFUNC( GetNumBones, "Get the number of bones" ) + DEFINE_SCRIPTFUNC( GetSequence, "Gets the current sequence" ) + DEFINE_SCRIPTFUNC( SetSequence, "Sets the current sequence" ) + DEFINE_SCRIPTFUNC( SequenceLoops, "Does the current sequence loop?" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSequenceDuration, "SequenceDuration", "Get the specified sequence duration" ) + DEFINE_SCRIPTFUNC( LookupSequence, "Gets the index of the specified sequence name" ) + DEFINE_SCRIPTFUNC( LookupActivity, "Gets the ID of the specified activity name" ) + DEFINE_SCRIPTFUNC_NAMED( HasMovement, "SequenceHasMovement", "Checks if the specified sequence has movement" ) + DEFINE_SCRIPTFUNC( GetSequenceMoveYaw, "Gets the move yaw of the specified sequence" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceMoveDist, "GetSequenceMoveDist", "Gets the move distance of the specified sequence" ) + DEFINE_SCRIPTFUNC( GetSequenceName, "Gets the name of the specified sequence index" ) + DEFINE_SCRIPTFUNC( GetSequenceActivityName, "Gets the activity name of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceActivity, "GetSequenceActivity", "Gets the activity ID of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSelectWeightedSequence, "SelectWeightedSequence", "Selects a sequence for the specified activity ID" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSelectHeaviestSequence, "SelectHeaviestSequence", "Selects the sequence with the heaviest weight for the specified activity ID" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceKeyValues, "GetSequenceKeyValues", "Get a KeyValue class instance on the specified sequence. WARNING: This uses the same KeyValue pointer as GetModelKeyValues!" ) + DEFINE_SCRIPTFUNC( ResetSequenceInfo, "" ) + DEFINE_SCRIPTFUNC( StudioFrameAdvance, "" ) + DEFINE_SCRIPTFUNC( GetPlaybackRate, "" ) + DEFINE_SCRIPTFUNC( SetPlaybackRate, "" ) + DEFINE_SCRIPTFUNC( GetCycle, "" ) + DEFINE_SCRIPTFUNC( SetCycle, "" ) + DEFINE_SCRIPTFUNC( GetSkin, "Gets the model's skin" ) + DEFINE_SCRIPTFUNC( SetSkin, "Sets the model's skin" ) +#endif + DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" ) + DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup") +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( GetBodygroup, "Gets a bodygroup" ) + DEFINE_SCRIPTFUNC( GetBodygroupName, "Gets a bodygroup name" ) + DEFINE_SCRIPTFUNC( FindBodygroupByName, "Finds a bodygroup by name" ) + DEFINE_SCRIPTFUNC( GetBodygroupCount, "Gets the number of models in a bodygroup" ) + DEFINE_SCRIPTFUNC( GetNumBodyGroups, "Gets the number of bodygroups" ) + + DEFINE_SCRIPTFUNC( Dissolve, "Use 'sprites/blueglow1.vmt' for the default material, Time() for the default start time, false for npcOnly if you don't want it to check if the entity is a NPC first, 0 for the default dissolve type, Vector(0,0,0) for the default dissolver origin, and 0 for the default magnitude." ) + DEFINE_SCRIPTFUNC( Ignite, "'NPCOnly' only lets this fall through if the entity is a NPC and 'CalledByLevelDesigner' determines whether to treat this like the Ignite input or just an internal ignition call." ) + DEFINE_SCRIPTFUNC( Scorch, "Makes the entity darker from scorching" ) + + DEFINE_SCRIPTFUNC( BecomeRagdollOnClient, "" ) + DEFINE_SCRIPTFUNC( IsRagdoll, "" ) + DEFINE_SCRIPTFUNC( CanBecomeRagdoll, "" ) + + BEGIN_SCRIPTHOOK( CBaseAnimating::g_Hook_OnServerRagdoll, "OnServerRagdoll", FIELD_VOID, "Called when this entity creates/turns into a server-side ragdoll." ) + DEFINE_SCRIPTHOOK_PARAM( "ragdoll", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "submodel", FIELD_BOOLEAN ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseAnimating::g_Hook_HandleAnimEvent, "HandleAnimEvent", FIELD_BOOLEAN, "Called when handling animation events. Return false to cancel base handling." ) + DEFINE_SCRIPTHOOK_PARAM( "event", FIELD_HSCRIPT ) + END_SCRIPTHOOK() +#endif +END_SCRIPTDESC(); CBaseAnimating::CBaseAnimating() { @@ -425,6 +515,11 @@ void CBaseAnimating::StudioFrameAdvanceInternal( CStudioHdr *pStudioHdr, float f float flNewCycle = GetCycle() + flCycleDelta; if (flNewCycle < 0.0 || flNewCycle >= 1.0) { + if (flNewCycle >= 1.0f) + { + ReachedEndOfSequence(); + } + if (m_bSequenceLoops) { flNewCycle -= (int)(flNewCycle); @@ -475,6 +570,7 @@ void CBaseAnimating::StudioFrameAdvanceManual( float flInterval ) if ( !pStudioHdr ) return; + UpdateModelScale(); m_flAnimTime = gpGlobals->curtime; m_flPrevAnimTime = m_flAnimTime - flInterval; float flCycleRate = GetSequenceCycleRate( pStudioHdr, GetSequence() ) * m_flPlaybackRate; @@ -494,6 +590,8 @@ void CBaseAnimating::StudioFrameAdvance() return; } + UpdateModelScale(); + if ( !m_flPrevAnimTime ) { m_flPrevAnimTime = m_flAnimTime; @@ -530,7 +628,11 @@ void CBaseAnimating::StudioFrameAdvance() //----------------------------------------------------------------------------- // Set the relative lighting origin //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CBaseAnimating::SetLightingOriginRelative( string_t strLightingOriginRelative, inputdata_t *inputdata ) +#else void CBaseAnimating::SetLightingOriginRelative( string_t strLightingOriginRelative ) +#endif { if ( strLightingOriginRelative == NULL_STRING ) { @@ -538,7 +640,11 @@ void CBaseAnimating::SetLightingOriginRelative( string_t strLightingOriginRelati } else { +#ifdef MAPBASE + CBaseEntity *pLightingOrigin = gEntList.FindEntityByName( NULL, strLightingOriginRelative, this, inputdata ? inputdata->pActivator : NULL, inputdata ? inputdata->pCaller : NULL ); +#else CBaseEntity *pLightingOrigin = gEntList.FindEntityByName( NULL, strLightingOriginRelative ); +#endif if ( !pLightingOrigin ) { DevWarning( "%s: Could not find info_lighting_relative '%s'!\n", GetClassname(), STRING( strLightingOriginRelative ) ); @@ -568,7 +674,11 @@ void CBaseAnimating::SetLightingOriginRelative( string_t strLightingOriginRelati //----------------------------------------------------------------------------- // Set the lighting origin //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CBaseAnimating::SetLightingOrigin( string_t strLightingOrigin, inputdata_t *inputdata ) +#else void CBaseAnimating::SetLightingOrigin( string_t strLightingOrigin ) +#endif { if ( strLightingOrigin == NULL_STRING ) { @@ -576,7 +686,11 @@ void CBaseAnimating::SetLightingOrigin( string_t strLightingOrigin ) } else { +#ifdef MAPBASE + CBaseEntity *pLightingOrigin = gEntList.FindEntityByName( NULL, strLightingOrigin, this, inputdata ? inputdata->pActivator : NULL, inputdata ? inputdata->pCaller : NULL ); +#else CBaseEntity *pLightingOrigin = gEntList.FindEntityByName( NULL, strLightingOrigin ); +#endif if ( !pLightingOrigin ) { DevWarning( "%s: Could not find lighting origin entity named '%s'!\n", GetClassname(), STRING( strLightingOrigin ) ); @@ -599,9 +713,15 @@ void CBaseAnimating::SetLightingOrigin( string_t strLightingOrigin ) //----------------------------------------------------------------------------- void CBaseAnimating::InputSetLightingOriginRelative( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Pass our input data now. + // (and stop doing that MAKE_STRING nonsense) + SetLightingOriginRelative( inputdata.value.StringID(), &inputdata ); +#else // Find our specified target string_t strLightingOriginRelative = MAKE_STRING( inputdata.value.String() ); SetLightingOriginRelative( strLightingOriginRelative ); +#endif } //----------------------------------------------------------------------------- @@ -610,9 +730,15 @@ void CBaseAnimating::InputSetLightingOriginRelative( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CBaseAnimating::InputSetLightingOrigin( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Pass our input data now. + // (and stop doing that MAKE_STRING nonsense) + SetLightingOrigin( inputdata.value.StringID(), &inputdata ); +#else // Find our specified target string_t strLightingOrigin = MAKE_STRING( inputdata.value.String() ); SetLightingOrigin( strLightingOrigin ); +#endif } //----------------------------------------------------------------------------- @@ -626,6 +752,37 @@ void CBaseAnimating::InputSetModelScale( inputdata_t &inputdata ) SetModelScale( vecScale.x, vecScale.y ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets our current model +//----------------------------------------------------------------------------- +void CBaseAnimating::InputSetModel( inputdata_t &inputdata ) +{ + const char *szModel = inputdata.value.String(); + if (PrecacheModel(szModel, false) != -1) + { + SetModelName(AllocPooledString(szModel)); + SetModel(szModel); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our current cycle +//----------------------------------------------------------------------------- +void CBaseAnimating::InputSetCycle( inputdata_t &inputdata ) +{ + SetCycle( inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our current cycle +//----------------------------------------------------------------------------- +void CBaseAnimating::InputSetPlaybackRate( inputdata_t &inputdata ) +{ + SetPlaybackRate( inputdata.value.Float() ); +} +#endif + //========================================================= // SelectWeightedSequence @@ -633,7 +790,7 @@ void CBaseAnimating::InputSetModelScale( inputdata_t &inputdata ) int CBaseAnimating::SelectWeightedSequence ( Activity activity ) { Assert( activity != ACT_INVALID ); - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::SelectWeightedSequence( GetModelPtr(), activity, GetSequence() ); } @@ -641,23 +798,16 @@ int CBaseAnimating::SelectWeightedSequence ( Activity activity ) int CBaseAnimating::SelectWeightedSequence ( Activity activity, int curSequence ) { Assert( activity != ACT_INVALID ); - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::SelectWeightedSequence( GetModelPtr(), activity, curSequence ); } -int CBaseAnimating::SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount ) -{ - Assert( activity != ACT_INVALID ); - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); - return GetModelPtr()->SelectWeightedSequenceFromModifiers( activity, pActivityModifiers, iModifierCount ); -} - //========================================================= // ResetActivityIndexes //========================================================= void CBaseAnimating::ResetActivityIndexes ( void ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); ::ResetActivityIndexes( GetModelPtr() ); } @@ -666,7 +816,7 @@ void CBaseAnimating::ResetActivityIndexes ( void ) //========================================================= void CBaseAnimating::ResetEventIndexes ( void ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); ::ResetEventIndexes( GetModelPtr() ); } @@ -678,7 +828,7 @@ void CBaseAnimating::ResetEventIndexes ( void ) //========================================================= int CBaseAnimating::SelectHeaviestSequence ( Activity activity ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::SelectHeaviestSequence( GetModelPtr(), activity ); } @@ -690,7 +840,7 @@ int CBaseAnimating::SelectHeaviestSequence ( Activity activity ) //----------------------------------------------------------------------------- int CBaseAnimating::LookupActivity( const char *label ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::LookupActivity( GetModelPtr(), label ); } @@ -698,7 +848,7 @@ int CBaseAnimating::LookupActivity( const char *label ) //========================================================= int CBaseAnimating::LookupSequence( const char *label ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::LookupSequence( GetModelPtr(), label ); } @@ -738,7 +888,7 @@ float CBaseAnimating::GetSequenceMoveYaw( int iSequence ) { Vector vecReturn; - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); ::GetSequenceLinearMotion( GetModelPtr(), iSequence, GetPoseParameterArray(), &vecReturn ); if (vecReturn.Length() > 0) @@ -774,7 +924,7 @@ float CBaseAnimating::GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence //----------------------------------------------------------------------------- void CBaseAnimating::GetSequenceLinearMotion( int iSequence, Vector *pVec ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); ::GetSequenceLinearMotion( GetModelPtr(), iSequence, GetPoseParameterArray(), pVec ); } @@ -921,7 +1071,7 @@ void CBaseAnimating::ResetSequenceInfo ( ) //========================================================= bool CBaseAnimating::IsValidSequence( int iSequence ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); CStudioHdr* pstudiohdr = GetModelPtr( ); if (iSequence < 0 || iSequence >= pstudiohdr->GetNumSeq()) { @@ -1112,6 +1262,11 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler ) event.eventtime = m_flAnimTime + (flCycle - GetCycle()) / flCycleRate + GetAnimTimeInterval(); } +#ifdef MAPBASE_VSCRIPT + if (eventHandler->ScriptHookHandleAnimEvent( &event ) == false) + continue; +#endif + /* if (m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) { @@ -1142,6 +1297,29 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler ) } } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseAnimating::ScriptHookHandleAnimEvent( animevent_t *pEvent ) +{ + if (m_ScriptScope.IsInitialized() && g_Hook_HandleAnimEvent.CanRunInScope(m_ScriptScope)) + { + HSCRIPT hEvent = g_pScriptVM->RegisterInstance( reinterpret_cast(pEvent) ); + + // event + ScriptVariant_t args[] = { hEvent }; + ScriptVariant_t returnValue = true; + g_Hook_HandleAnimEvent.Call( m_ScriptScope, &returnValue, args ); + + g_pScriptVM->RemoveInstance( hEvent ); + return returnValue.m_bool; + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1154,6 +1332,21 @@ void CBaseAnimating::HandleAnimEvent( animevent_t *pEvent ) EmitSound( pEvent->options ); return; } +#ifdef MAPBASE + else if ( pEvent->event == AE_NPC_RESPONSE ) + { + if (!MyNPCPointer()->GetExpresser()->IsSpeaking()) + { + DispatchResponse( pEvent->options ); + } + return; + } + else if ( pEvent->event == AE_NPC_RESPONSE_FORCED ) + { + DispatchResponse( pEvent->options ); + return; + } +#endif else if ( pEvent->event == AE_RAGDOLL ) { // Convert to ragdoll immediately @@ -1761,7 +1954,7 @@ ConVar ai_setupbones_debug( "ai_setupbones_debug", "0", 0, "Shows that bones tha -inline bool CBaseAnimating::CanSkipAnimation( void ) +bool CBaseAnimating::CanSkipAnimation( void ) { if ( !sv_pvsskipanimation.GetBool() ) return false; @@ -1788,7 +1981,7 @@ void CBaseAnimating::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ) MDLCACHE_CRITICAL_SECTION(); - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); CStudioHdr *pStudioHdr = GetModelPtr( ); @@ -2033,6 +2226,95 @@ bool CBaseAnimating::GetAttachment( int iAttachment, Vector &absOrigin, Vector * return bRet; } +//----------------------------------------------------------------------------- +// Purpose: Returns the world location and world angles of an attachment to vscript caller +// Input : attachment name +// Output : location and angles +//----------------------------------------------------------------------------- +const Vector& CBaseAnimating::ScriptGetAttachmentOrigin( int iAttachment ) +{ + + static Vector absOrigin; + static QAngle qa; + + CBaseAnimating::GetAttachment( iAttachment, absOrigin, qa ); + + return absOrigin; +} + +const Vector& CBaseAnimating::ScriptGetAttachmentAngles( int iAttachment ) +{ + + static Vector absOrigin; + static Vector absAngles; + static QAngle qa; + + CBaseAnimating::GetAttachment( iAttachment, absOrigin, qa ); + absAngles.x = qa.x; + absAngles.y = qa.y; + absAngles.z = qa.z; + return absAngles; +} + +#ifdef MAPBASE_VSCRIPT +HSCRIPT CBaseAnimating::ScriptGetAttachmentMatrix( int iAttachment ) +{ + static matrix3x4_t matrix; + + CBaseAnimating::GetAttachment( iAttachment, matrix ); + return g_pScriptVM->RegisterInstance( &matrix ); +} + +float CBaseAnimating::ScriptGetPoseParameter( const char* szName ) +{ + CStudioHdr* pHdr = GetModelPtr(); + if (pHdr == NULL) + return 0.0f; + + int iPoseParam = LookupPoseParameter( pHdr, szName ); + return GetPoseParameter( iPoseParam ); +} + +void CBaseAnimating::ScriptSetPoseParameter( const char* szName, float fValue ) +{ + CStudioHdr* pHdr = GetModelPtr(); + if (pHdr == NULL) + return; + + int iPoseParam = LookupPoseParameter( pHdr, szName ); + SetPoseParameter( pHdr, iPoseParam, fValue ); +} + +void CBaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ) +{ + if (hTransform == NULL) + return; + + GetBoneTransform( iBone, *HScriptToClass( hTransform ) ); +} + +//----------------------------------------------------------------------------- +// VScript access to sequence's key values +// for iteration and value access, use: +// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString, +// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey +// NOTE: This is recycled from ScriptGetModelKeyValues() and uses its pointer!!! +//----------------------------------------------------------------------------- +HSCRIPT CBaseAnimating::ScriptGetSequenceKeyValues( int iSequence ) +{ + KeyValues *pSeqKeyValues = GetSequenceKeyValues( iSequence ); + HSCRIPT hScript = NULL; + if ( pSeqKeyValues ) + { + // UNDONE: how does destructor get called on this + m_pScriptModelKeyValues = hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pSeqKeyValues, true ); + + // UNDONE: who calls ReleaseInstance on this??? Does name need to be unique??? + } + + return hScript; +} +#endif //----------------------------------------------------------------------------- // Returns the attachment in local space @@ -2096,7 +2378,7 @@ void CBaseAnimating::GetEyeballs( Vector &origin, QAngle &angles ) //========================================================= int CBaseAnimating::FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); if (piDir == NULL) { @@ -2145,7 +2427,7 @@ void CBaseAnimating::SetBodygroup( int iGroup, int iValue ) { // SetBodygroup is not supported on pending dynamic models. Wait for it to load! // XXX TODO we could buffer up the group and value if we really needed to. -henryg - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); int newBody = m_nBody; ::SetBodygroup( GetModelPtr( ), newBody, iGroup, iValue ); m_nBody = newBody; @@ -2652,9 +2934,9 @@ void CBaseAnimating::InvalidateBoneCache( void ) bool CBaseAnimating::TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr ) { // Return a special case for scaled physics objects - if ( GetModelScale() != 1.0f ) + IPhysicsObject *pPhysObject = VPhysicsGetObject(); + if ( GetModelScale() != 1.0f && pPhysObject ) { - IPhysicsObject *pPhysObject = VPhysicsGetObject(); Vector vecPosition; QAngle vecAngles; pPhysObject->GetPosition( &vecPosition, &vecAngles ); @@ -2744,7 +3026,7 @@ void CBaseAnimating::InitBoneControllers ( void ) // FIXME: rename //========================================================= float CBaseAnimating::SetBoneController ( int iController, float flValue ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); CStudioHdr *pmodel = (CStudioHdr*)GetModelPtr(); @@ -2761,7 +3043,7 @@ float CBaseAnimating::SetBoneController ( int iController, float flValue ) //========================================================= float CBaseAnimating::GetBoneController ( int iController ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); CStudioHdr *pmodel = (CStudioHdr*)GetModelPtr(); @@ -2952,7 +3234,7 @@ void CBaseAnimating::SetHitboxSet( int setnum ) //----------------------------------------------------------------------------- void CBaseAnimating::SetHitboxSetByName( const char *setname ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); m_nHitboxSet = FindHitboxSetByName( GetModelPtr(), setname ); } @@ -2971,7 +3253,7 @@ int CBaseAnimating::GetHitboxSet( void ) //----------------------------------------------------------------------------- const char *CBaseAnimating::GetHitboxSetName( void ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::GetHitboxSetName( GetModelPtr(), m_nHitboxSet ); } @@ -2981,7 +3263,7 @@ const char *CBaseAnimating::GetHitboxSetName( void ) //----------------------------------------------------------------------------- int CBaseAnimating::GetHitboxSetCount( void ) { - AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" ); + Assert( GetModelPtr() ); return ::GetHitboxSetCount( GetModelPtr() ); } @@ -3220,6 +3502,18 @@ void CBaseAnimating::CopyAnimationDataFrom( CBaseAnimating *pSource ) this->m_flAnimTime = pSource->m_flAnimTime; this->m_nBody = pSource->m_nBody; this->m_nSkin = pSource->m_nSkin; +#ifdef MAPBASE + this->m_clrRender = pSource->m_clrRender; + this->m_nRenderMode = pSource->m_nRenderMode; + this->m_nRenderFX = pSource->m_nRenderFX; + this->m_iViewHideFlags = pSource->m_iViewHideFlags; + this->m_fadeMinDist = pSource->m_fadeMinDist; + this->m_fadeMaxDist = pSource->m_fadeMaxDist; + this->m_flFadeScale = pSource->m_flFadeScale; + + if (this->GetModelScale() != pSource->GetModelScale()) + this->SetModelScale( pSource->GetModelScale() ); +#endif this->LockStudioHdr(); } @@ -3312,7 +3606,6 @@ void CBaseAnimating::SetModelScale( float scale, float change_duration /*= 0.0f* mvs->m_flModelScaleGoal = scale; mvs->m_flModelScaleStartTime = gpGlobals->curtime; mvs->m_flModelScaleFinishTime = mvs->m_flModelScaleStartTime + change_duration; - SetContextThink( &CBaseAnimating::UpdateModelScale, gpGlobals->curtime, "UpdateModelScaleThink" ); } else { @@ -3351,11 +3644,6 @@ void CBaseAnimating::UpdateModelScale() } RefreshCollisionBounds(); - - if ( frac < 1.f ) - { - SetContextThink( &CBaseAnimating::UpdateModelScale, gpGlobals->curtime, "UpdateModelScaleThink" ); - } } void CBaseAnimating::RefreshCollisionBounds( void ) @@ -3554,6 +3842,72 @@ void CBaseAnimating::InputBecomeRagdoll( inputdata_t &inputdata ) BecomeRagdollOnClient( vec3_origin ); } +#ifdef MAPBASE +void CBaseAnimating::InputCreateSeparateRagdoll( inputdata_t &inputdata ) +{ + CTakeDamageInfo info( this, inputdata.pActivator, 0.0f, DMG_GENERIC ); + + // See if there's a ragdoll magnet that should influence our force. + CRagdollMagnet *pMagnet = CRagdollMagnet::FindBestMagnet( this ); + if( pMagnet ) + { + info.SetDamageForce(pMagnet->GetForceVector( this )); + pMagnet->m_OnUsed.Set(info.GetDamageForce(), this, pMagnet); + } + + CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true ); +} + +void CBaseAnimating::InputCreateSeparateRagdollClient( inputdata_t &inputdata ) +{ + // I remember there being a reason why this must be initialized to all 0's... + Vector forceVector = Vector(0.0f, 0.0f, 0.0f); + + // See if there's a ragdoll magnet that should influence our force. + CRagdollMagnet *pMagnet = CRagdollMagnet::FindBestMagnet( this ); + if( pMagnet ) + { + forceVector += pMagnet->GetForceVector( this ); + pMagnet->m_OnUsed.Set(forceVector, this, pMagnet); + } + + CBaseEntity *pRagdoll = CreateRagGib( STRING( GetModelName() ), GetAbsOrigin(), GetAbsAngles(), forceVector, 25.0f ); + + if (pRagdoll->GetBaseAnimating()) + { + pRagdoll->GetBaseAnimating()->CopyAnimationDataFrom( this ); + } +} + +void CBaseAnimating::InputSetPoseParameter( inputdata_t &inputdata ) +{ + char token[64]; + Q_strncpy( token, inputdata.value.String(), sizeof(token) ); + char *sChar = strchr( token, ' ' ); + if ( sChar ) + { + *sChar = '\0'; + + // Name + const int index = LookupPoseParameter( token ); + if (index == -1) + { + Warning("SetPoseParameter: Could not find pose parameter \"%s\" on %s\n", token, GetDebugName()); + return; + } + + // Value + const float value = atof( sChar+1 ); + + SetPoseParameter( index, value ); + } + else + { + Warning("SetPoseParameter: \"%s\" is invalid; format is \" \"\n", inputdata.value.String()); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -3617,4 +3971,5 @@ void CBaseAnimating::Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) m_bHacked = true; m_OnHacked.FireOutput( pActivator, pCaller ); } -#endif \ No newline at end of file +#endif + diff --git a/game/server/baseanimating.h b/game/server/baseanimating.h index 4478b2a7..bd48b82a 100644 --- a/game/server/baseanimating.h +++ b/game/server/baseanimating.h @@ -44,6 +44,7 @@ class CBaseAnimating : public CBaseEntity DECLARE_DATADESC(); DECLARE_SERVERCLASS(); + DECLARE_ENT_SCRIPTDESC(); virtual void SetModel( const char *szModelName ); virtual void Activate(); @@ -83,6 +84,7 @@ class CBaseAnimating : public CBaseEntity virtual void StudioFrameAdvance(); // advance animation frame to some time in the future void StudioFrameAdvanceManual( float flInterval ); bool IsValidSequence( int iSequence ); + virtual void ReachedEndOfSequence() { return; } inline float GetPlaybackRate(); inline void SetPlaybackRate( float rate ); @@ -99,6 +101,9 @@ class CBaseAnimating : public CBaseEntity inline float SequenceDuration( void ) { return SequenceDuration( m_nSequence ); } float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence ); inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); } +#ifdef MAPBASE_VSCRIPT + inline float ScriptSequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); } +#endif float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence ); inline float GetSequenceCycleRate( int iSequence ) { return GetSequenceCycleRate(GetModelPtr(),iSequence); } float GetLastVisibleCycle( CStudioHdr *pStudioHdr, int iSequence ); @@ -108,7 +113,6 @@ class CBaseAnimating : public CBaseEntity void ResetEventIndexes ( void ); int SelectWeightedSequence ( Activity activity ); int SelectWeightedSequence ( Activity activity, int curSequence ); - int SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount ); int SelectHeaviestSequence ( Activity activity ); int LookupActivity( const char *label ); int LookupSequence ( const char *label ); @@ -141,6 +145,9 @@ class CBaseAnimating : public CBaseEntity bool HasAnimEvent( int nSequence, int nEvent ); virtual void DispatchAnimEvents ( CBaseAnimating *eventHandler ); // Handle events that have happend since last time called up until X seconds into the future virtual void HandleAnimEvent( animevent_t *pEvent ); +#ifdef MAPBASE_VSCRIPT + bool ScriptHookHandleAnimEvent( animevent_t *pEvent ); +#endif int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName ); inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); } @@ -187,6 +194,29 @@ class CBaseAnimating : public CBaseEntity bool GetAttachment( int iAttachment, Vector &absOrigin, QAngle &absAngles ); int GetAttachmentBone( int iAttachment ); virtual bool GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld ); + const Vector& ScriptGetAttachmentOrigin(int iAttachment); + const Vector& ScriptGetAttachmentAngles(int iAttachment); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetAttachmentMatrix(int iAttachment); + float ScriptGetPoseParameter(const char* szName); + void ScriptSetPoseParameter(const char* szName, float fValue); + + void ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ); + + int ScriptGetSequenceActivity( int iSequence ) { return GetSequenceActivity( iSequence ); } + float ScriptGetSequenceMoveDist( int iSequence ) { return GetSequenceMoveDist( GetModelPtr(), iSequence ); } + int ScriptSelectHeaviestSequence( int activity ) { return SelectHeaviestSequence( (Activity)activity ); } + int ScriptSelectWeightedSequence( int activity, int curSequence ) { return SelectWeightedSequence( (Activity)activity, curSequence ); } + + HSCRIPT ScriptGetSequenceKeyValues( int iSequence ); + + // For VScript + int GetSkin() { return m_nSkin; } + void SetSkin( int iSkin ) { m_nSkin = iSkin; } + + static ScriptHook_t g_Hook_OnServerRagdoll; + static ScriptHook_t g_Hook_HandleAnimEvent; +#endif // These return the attachment in the space of the entity bool GetAttachmentLocal( const char *szName, Vector &origin, QAngle &angles ); @@ -298,6 +328,11 @@ class CBaseAnimating : public CBaseEntity void InputIgniteNumHitboxFires( inputdata_t &inputdata ); void InputIgniteHitboxFireScale( inputdata_t &inputdata ); void InputBecomeRagdoll( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputCreateSeparateRagdoll( inputdata_t &inputdata ); + void InputCreateSeparateRagdollClient( inputdata_t &inputdata ); + void InputSetPoseParameter( inputdata_t &inputdata ); +#endif // Dissolve, returns true if the ragdoll has been created bool Dissolve( const char *pMaterialName, float flStartTime, bool bNPCOnly = true, int nDissolveType = 0, Vector vDissolverOrigin = vec3_origin, int iMagnitude = 0 ); @@ -309,11 +344,19 @@ class CBaseAnimating : public CBaseEntity float m_flLastEventCheck; // cycle index of when events were last checked virtual void SetLightingOriginRelative( CBaseEntity *pLightingOriginRelative ); +#ifdef MAPBASE + void SetLightingOriginRelative( string_t strLightingOriginRelative, inputdata_t *inputdata = NULL ); +#else void SetLightingOriginRelative( string_t strLightingOriginRelative ); +#endif CBaseEntity *GetLightingOriginRelative(); virtual void SetLightingOrigin( CBaseEntity *pLightingOrigin ); +#ifdef MAPBASE + void SetLightingOrigin( string_t strLightingOrigin, inputdata_t *inputdata = NULL ); +#else void SetLightingOrigin( string_t strLightingOrigin ); +#endif CBaseEntity *GetLightingOrigin(); const float* GetPoseParameterArray() { return m_flPoseParameter.Base(); } @@ -333,10 +376,10 @@ class CBaseAnimating : public CBaseEntity bool PrefetchSequence( int iSequence ); #ifdef VANCE - virtual bool IsHackable() { return m_bHackable; } - - bool IsHacked() { return m_bHacked; } + virtual bool IsHackable() const { return m_bHackable; } virtual void Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ); + + inline bool IsHacked() const { return m_bHacked; } #endif private: @@ -347,6 +390,14 @@ class CBaseAnimating : public CBaseEntity void InputSetLightingOriginRelative( inputdata_t &inputdata ); void InputSetLightingOrigin( inputdata_t &inputdata ); void InputSetModelScale( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetModel( inputdata_t &inputdata ); + + void InputSetCycle( inputdata_t &inputdata ); + void InputSetPlaybackRate( inputdata_t &inputdata ); + +public: // From Alien Swarm SDK +#endif bool CanSkipAnimation( void ); @@ -431,6 +482,9 @@ class CBaseAnimating : public CBaseEntity #ifdef VANCE COutputEvent m_OnHacked; #endif +#ifdef MAPBASE + COutputEHANDLE m_OnServerRagdoll; +#endif private: CStudioHdr *m_pStudioHdr; @@ -452,14 +506,10 @@ inline CStudioHdr *CBaseAnimating::GetModelPtr( void ) return NULL; #ifdef _DEBUG - if ( !HushAsserts() ) - { - // GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance. - static IDataCacheSection *pModelCache = datacache->FindSection( "ModelData" ); - AssertOnce( pModelCache->IsFrameLocking() ); - } + // 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() ) { LockStudioHdr(); diff --git a/game/server/basebludgeonweapon.cpp b/game/server/basebludgeonweapon.cpp index ff8df099..57683a19 100644 --- a/game/server/basebludgeonweapon.cpp +++ b/game/server/basebludgeonweapon.cpp @@ -93,6 +93,14 @@ void CBaseHLBludgeonWeapon::ItemPostFrame( void ) if ( pOwner == NULL ) return; +#ifdef MAPBASE + if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING )) + { + WeaponIdle(); + return; + } +#endif + if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) { PrimaryAttack(); @@ -363,12 +371,27 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary ) // We want to test the first swing again Vector testEnd = swingStart + forward * GetRange(); + +#ifdef MAPBASE + // Sound has been moved here since we're using the other melee sounds now + WeaponSound( SINGLE ); +#endif // See if we happened to hit water ImpactWater( swingStart, testEnd ); } else { +#ifdef MAPBASE + // Other melee sounds + if (traceHit.m_pEnt && traceHit.m_pEnt->IsWorld()) + WeaponSound(MELEE_HIT_WORLD); + else if (traceHit.m_pEnt && !traceHit.m_pEnt->PassesDamageFilter(triggerInfo)) + WeaponSound(MELEE_MISS); + else + WeaponSound(MELEE_HIT); +#endif + Hit( traceHit, nHitActivity, bIsSecondary ? true : false ); } @@ -379,6 +402,12 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary ) m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); +#ifndef MAPBASE //Play swing sound WeaponSound( SINGLE ); +#endif + +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif } diff --git a/game/server/basecombatcharacter.cpp b/game/server/basecombatcharacter.cpp index 03f1c649..938b3287 100644 --- a/game/server/basecombatcharacter.cpp +++ b/game/server/basecombatcharacter.cpp @@ -68,12 +68,17 @@ ConVar ai_force_serverside_ragdoll( "ai_force_serverside_ragdoll", "0" ); ConVar nb_last_area_update_tolerance( "nb_last_area_update_tolerance", "4.0", FCVAR_CHEAT, "Distance a character needs to travel in order to invalidate cached area" ); // 4.0 tested as sweet spot (for wanderers, at least). More resulted in little benefit, less quickly diminished benefit [7/31/2008 tom] +#ifdef MAPBASE +// ShouldUseVisibilityCache() is used as an actual function now +ConVar ai_use_visibility_cache( "ai_use_visibility_cache", "1" ); +#else #ifndef _RETAIL ConVar ai_use_visibility_cache( "ai_use_visibility_cache", "1" ); #define ShouldUseVisibilityCache() ai_use_visibility_cache.GetBool() #else #define ShouldUseVisibilityCache() true #endif +#endif BEGIN_DATADESC( CBaseCombatCharacter ) @@ -97,22 +102,117 @@ BEGIN_DATADESC( CBaseCombatCharacter ) DEFINE_FIELD( m_flDamageAccumulator, FIELD_FLOAT ), DEFINE_INPUT( m_impactEnergyScale, FIELD_FLOAT, "physdamagescale" ), DEFINE_FIELD( m_CurrentWeaponProficiency, FIELD_INTEGER), +#ifdef MAPBASE + DEFINE_INPUT( m_ProficiencyOverride, FIELD_INTEGER, "SetProficiencyOverride"), +#endif DEFINE_UTLVECTOR( m_Relationship, FIELD_EMBEDDED), DEFINE_AUTO_ARRAY( m_iAmmo, FIELD_INTEGER ), DEFINE_AUTO_ARRAY( m_hMyWeapons, FIELD_EHANDLE ), DEFINE_FIELD( m_hActiveWeapon, FIELD_EHANDLE ), + #ifdef VANCE DEFINE_FIELD( m_hDeployingWeapon, FIELD_EHANDLE ), #endif + +#ifdef MAPBASE + DEFINE_INPUT( m_bForceServerRagdoll, FIELD_BOOLEAN, "SetForceServerRagdoll" ), +#else DEFINE_FIELD( m_bForceServerRagdoll, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_bPreventWeaponPickup, FIELD_BOOLEAN ), +#ifndef MAPBASE // See CBaseEntity::InputKilledNPC() DEFINE_INPUTFUNC( FIELD_VOID, "KilledNPC", InputKilledNPC ), +#endif + +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetBloodColor", InputSetBloodColor ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetRelationship", InputSetRelationship ), + + DEFINE_INPUTFUNC( FIELD_VOID, "HolsterWeapon", InputHolsterWeapon ), + DEFINE_INPUTFUNC( FIELD_VOID, "HolsterAndDestroyWeapon", InputHolsterAndDestroyWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "UnholsterWeapon", InputUnholsterWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "SwitchToWeapon", InputSwitchToWeapon ), + + DEFINE_INPUTFUNC( FIELD_STRING, "GiveWeapon", InputGiveWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "DropWeapon", InputDropWeapon ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "PickupWeaponInstant", InputPickupWeaponInstant ), + DEFINE_OUTPUT( m_OnWeaponEquip, "OnWeaponEquip" ), + DEFINE_OUTPUT( m_OnWeaponDrop, "OnWeaponDrop" ), + + DEFINE_OUTPUT( m_OnKilledEnemy, "OnKilledEnemy" ), + DEFINE_OUTPUT( m_OnKilledPlayer, "OnKilledPlayer" ), + DEFINE_OUTPUT( m_OnHealthChanged, "OnHealthChanged" ), +#endif END_DATADESC() +#ifdef MAPBASE_VSCRIPT +ScriptHook_t CBaseCombatCharacter::g_Hook_RelationshipType; +ScriptHook_t CBaseCombatCharacter::g_Hook_RelationshipPriority; + +BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by players and NPCs." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetActiveWeapon, "GetActiveWeapon", "Get the character's active weapon entity." ) + DEFINE_SCRIPTFUNC( WeaponCount, "Get the number of weapons a character possesses." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeapon, "GetWeapon", "Get a specific weapon in the character's inventory." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeaponByType, "FindWeapon", "Find a specific weapon in the character's inventory by its classname." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAllWeapons, "GetAllWeapons", "Get the character's weapon inventory." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetCurrentWeaponProficiency, "GetCurrentWeaponProficiency", "Get the character's current proficiency (accuracy) with their current weapon." ) + + DEFINE_SCRIPTFUNC_NAMED( Weapon_ShootPosition, "ShootPosition", "Get the character's shoot position." ) + DEFINE_SCRIPTFUNC_NAMED( Weapon_DropAll, "DropAllWeapons", "Make the character drop all of its weapons." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEquipWeapon, "EquipWeapon", "Make the character equip the specified weapon entity. If they don't already own the weapon, they will acquire it instantly." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptDropWeapon, "DropWeapon", "Make the character drop the specified weapon entity if they own it." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGiveAmmo, "GiveAmmo", "Gives the specified amount of the specified ammo type. The third parameter is whether or not to suppress the ammo pickup sound. Returns the amount of ammo actually given, which is 0 if the player's ammo for this type is already full." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptRemoveAmmo, "RemoveAmmo", "Removes the specified amount of the specified ammo type." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAmmoCount, "GetAmmoCount", "Get the ammo count of the specified ammo type." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAmmoCount, "SetAmmoCount", "Set the ammo count of the specified ammo type." ) + + DEFINE_SCRIPTFUNC( DoMuzzleFlash, "Does a muzzle flash." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttackSpread, "GetAttackSpread", "Get the attack spread." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSpreadBias, "GetSpreadBias", "Get the spread bias." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptRelationType, "GetRelationship", "Get a character's relationship to a specific entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptRelationPriority, "GetRelationPriority", "Get a character's relationship priority for a specific entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetRelationship, "SetRelationship", "Set a character's relationship with a specific entity." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetVehicleEntity, "GetVehicleEntity", "Get the entity for a character's current vehicle if they're in one." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptInViewCone, "InViewCone", "Check if the specified position is in the character's viewcone." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEntInViewCone, "EntInViewCone", "Check if the specified entity is in the character's viewcone." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptInAimCone, "InAimCone", "Check if the specified position is in the character's aim cone." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEntInViewCone, "EntInAimCone", "Check if the specified entity is in the character's aim cone." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptBodyAngles, "BodyAngles", "Get the body's angles." ) + DEFINE_SCRIPTFUNC( BodyDirection2D, "Get the body's 2D direction." ) + DEFINE_SCRIPTFUNC( BodyDirection3D, "Get the body's 3D direction." ) + DEFINE_SCRIPTFUNC( HeadDirection2D, "Get the head's 2D direction." ) + DEFINE_SCRIPTFUNC( HeadDirection3D, "Get the head's 3D direction." ) + DEFINE_SCRIPTFUNC( EyeDirection2D, "Get the eyes' 2D direction." ) + DEFINE_SCRIPTFUNC( EyeDirection3D, "Get the eyes' 3D direction." ) + + // + // Hooks + // + BEGIN_SCRIPTHOOK( CBaseCombatCharacter::g_Hook_RelationshipType, "RelationshipType", FIELD_INTEGER, "Called when a character's relationship to another entity is requested. Returning a disposition will make the game use that disposition instead of the default relationship. (note: 'default' in this case includes overrides from ai_relationship/SetRelationship)" ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "def", FIELD_INTEGER ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseCombatCharacter::g_Hook_RelationshipPriority, "RelationshipPriority", FIELD_INTEGER, "Called when a character's relationship priority for another entity is requested. Returning a number will make the game use that priority instead of the default priority. (note: 'default' in this case includes overrides from ai_relationship/SetRelationship)" ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "def", FIELD_INTEGER ) + END_SCRIPTHOOK() + +END_SCRIPTDESC(); +#endif + BEGIN_SIMPLE_DATADESC( Relationship_t ) DEFINE_FIELD( entity, FIELD_EHANDLE ), @@ -201,6 +301,7 @@ IMPLEMENT_SERVERCLASS_ST(CBaseCombatCharacter, DT_BaseCombatCharacter) SendPropEHandle( SENDINFO( m_hActiveWeapon ) ), SendPropArray3( SENDINFO_ARRAY3(m_hMyWeapons), SendPropEHandle( SENDINFO_ARRAY(m_hMyWeapons) ) ), + #ifdef VANCE SendPropEHandle( SENDINFO( m_hDeployingWeapon ) ), #endif @@ -231,6 +332,21 @@ int CBaseCombatCharacter::GetInteractionID(void) return (m_lastInteraction); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: New method of adding interactions which allows their name to be available (currently used for VScript) +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::AddInteractionWithString( int &interaction, const char *szName ) +{ + interaction = GetInteractionID(); + + if (g_pScriptVM) + { + ScriptRegisterConstantNamed( g_pScriptVM, interaction, szName, "An interaction which could be used with HandleInteraction or DispatchInteraction. NOTE: These are usually only initialized by certain types of NPCs when an instance of one spawns in the level for the first time!!! (the fact you're seeing this one means there was an NPC in the level which initialized it)" ); + } +} +#endif + // ============================================================================ bool CBaseCombatCharacter::HasHumanGibs( void ) { @@ -337,11 +453,16 @@ bool CBaseCombatCharacter::FVisible( CBaseEntity *pEntity, int traceMask, CBaseE { VPROF( "CBaseCombatCharacter::FVisible" ); +#ifdef MAPBASE + if ( traceMask != MASK_BLOCKLOS || !ShouldUseVisibilityCache( pEntity ) || pEntity == this || !ai_use_visibility_cache.GetBool() + ) +#else if ( traceMask != MASK_BLOCKLOS || !ShouldUseVisibilityCache() || pEntity == this #if defined(HL2_DLL) || Classify() == CLASS_BULLSEYE || pEntity->Classify() == CLASS_BULLSEYE #endif ) +#endif { return BaseClass::FVisible( pEntity, traceMask, ppBlocker ); } @@ -447,6 +568,17 @@ void CBaseCombatCharacter::ResetVisibilityCache( CBaseCombatCharacter *pBCC ) } } +#ifdef MAPBASE +bool CBaseCombatCharacter::ShouldUseVisibilityCache( CBaseEntity *pEntity ) +{ +#ifdef HL2_DLL + return Classify() != CLASS_BULLSEYE && pEntity->Classify() != CLASS_BULLSEYE; +#else + return true; +#endif +} +#endif + #ifdef PORTAL bool CBaseCombatCharacter::FVisibleThroughPortal( const CProp_Portal *pPortal, CBaseEntity *pEntity, int traceMask, CBaseEntity **ppBlocker ) { @@ -1168,7 +1300,11 @@ bool CTraceFilterMelee::ShouldHitEntity( IHandleEntity *pHandleEntity, int conte if ( pBCC && pVictimBCC ) { // Can only damage other NPCs that we hate +#ifdef MAPBASE + if ( m_bDamageAnyNPC || pBCC->IRelationType( pEntity ) <= D_FR ) +#else if ( m_bDamageAnyNPC || pBCC->IRelationType( pEntity ) == D_HT ) +#endif { if ( info.GetDamage() ) { @@ -1491,6 +1627,30 @@ bool CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vect return true; } +#ifdef MAPBASE +CBaseEntity *CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags, const Vector *vecColor ) +{ + Assert( CanBecomeRagdoll() ); + + CTakeDamageInfo info( pKiller, pKiller, 1.0f, DMG_GENERIC ); + + info.SetDamageForce( forceVector ); + + CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true ); + + pRagdoll->SetCollisionBounds( CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs() ); + + CBaseEntity *pBoogie = CRagdollBoogie::Create( pRagdoll, 200, gpGlobals->curtime, duration, flags, vecColor ); + + CTakeDamageInfo ragdollInfo( pKiller, pKiller, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL ); + ragdollInfo.SetDamagePosition( WorldSpaceCenter() ); + ragdollInfo.SetDamageForce( Vector( 0, 0, 1 ) ); + TakeDamage( ragdollInfo ); + + return pBoogie; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1599,7 +1759,23 @@ void CBaseCombatCharacter::Event_Killed( const CTakeDamageInfo &info ) CRagdollMagnet *pMagnet = CRagdollMagnet::FindBestMagnet( this ); if( pMagnet ) { +#ifdef MAPBASE + if (pMagnet->BoneTarget() && pMagnet->BoneTarget()[0] != '\0') + { + int iBone = -1; + forceVector += pMagnet->GetForceVector( this, &iBone ); + if (iBone != -1) + m_nForceBone = GetPhysicsBone(iBone); + } + else + { + forceVector += pMagnet->GetForceVector( this ); + } + + pMagnet->m_OnUsed.Set(forceVector, this, pMagnet); +#else forceVector += pMagnet->GetForceVector( this ); +#endif } CBaseCombatWeapon *pDroppedWeapon = m_hActiveWeapon.Get(); @@ -1618,7 +1794,14 @@ void CBaseCombatCharacter::Event_Killed( const CTakeDamageInfo &info ) // if flagged to drop a health kit if (HasSpawnFlags(SF_NPC_DROP_HEALTHKIT)) { - CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles() ); + CBaseEntity *pItem = CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles() ); + if (pItem) + { +#ifdef MAPBASE + if (MyNPCPointer()) + MyNPCPointer()->m_OnItemDrop.Set( pItem, pItem, this ); +#endif + } } // clear the deceased's sound channels.(may have been firing or reloading when killed) EmitSound( "BaseCombatCharacter.StopWeaponSounds" ); @@ -1652,7 +1835,11 @@ void CBaseCombatCharacter::Event_Killed( const CTakeDamageInfo &info ) } } #ifdef HL2_DLL +#ifdef MAPBASE + else if ( PlayerHasMegaPhysCannon() && GlobalEntity_GetCounter("super_phys_gun") != 1 ) +#else else if ( PlayerHasMegaPhysCannon() ) +#endif { if ( pDroppedWeapon ) { @@ -1912,7 +2099,11 @@ void CBaseCombatCharacter::Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector return; // If I'm an NPC, fill the weapon with ammo before I drop it. +#ifdef MAPBASE + if ( GetFlags() & FL_NPC && !pWeapon->HasSpawnFlags(SF_WEAPON_PRESERVE_AMMO) ) +#else if ( GetFlags() & FL_NPC ) +#endif { if ( pWeapon->UsesClipsForAmmo1() ) { @@ -2048,6 +2239,10 @@ void CBaseCombatCharacter::Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector pWeapon->Drop( vecThrow ); Weapon_Detach( pWeapon ); +#ifdef MAPBASE + m_OnWeaponDrop.FireOutput(pWeapon, this); +#endif + if ( HasSpawnFlags( SF_NPC_NO_WEAPON_DROP ) ) { // Don't drop weapons when the super physgun is happening. @@ -2070,6 +2265,227 @@ void CBaseCombatCharacter::SetLightingOriginRelative( CBaseEntity *pLightingOrig } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Gives character new weapon and equips it +// Input : New weapon +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::Weapon_Equip( CBaseCombatWeapon *pWeapon ) +{ + Weapon_HandleEquip(pWeapon); + + // Players don't automatically holster their current weapon + if ( IsPlayer() == false ) + { + if ( m_hActiveWeapon ) + { + m_hActiveWeapon->Holster(); + // FIXME: isn't this handeled by the weapon? + m_hActiveWeapon->AddEffects( EF_NODRAW ); + } + SetActiveWeapon( pWeapon ); + m_hActiveWeapon->RemoveEffects( EF_NODRAW ); + + } + + WeaponProficiency_t proficiency; + proficiency = CalcWeaponProficiency( pWeapon ); + + if( weapon_showproficiency.GetBool() != 0 ) + { + Msg("%s equipped with %s, proficiency is %s\n", GetClassname(), pWeapon->GetClassname(), GetWeaponProficiencyName( proficiency ) ); + } + + SetCurrentWeaponProficiency( proficiency ); +} + +//----------------------------------------------------------------------------- +// Purpose: Puts a new weapon in the inventory +// Input : New weapon +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::Weapon_EquipHolstered( CBaseCombatWeapon *pWeapon ) +{ + Weapon_HandleEquip(pWeapon); + pWeapon->AddEffects( EF_NODRAW ); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds new weapon to the character +// Input : New weapon +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::Weapon_HandleEquip( CBaseCombatWeapon *pWeapon ) +{ + // Add the weapon to my weapon inventory + if (IsPlayer()) + { + // This code drops existing weapons that are in the same bucket and bucket position. + // This doesn't really harm anything since that situation would've broken the HUD anyway. + // + // It goes through every single index in case there's a NULL pointer in between weapons. + int iFirstNullIndex = -1; + for (int i=0;iGetSlot() == m_hMyWeapons[i]->GetSlot() && + pWeapon->GetPosition() == m_hMyWeapons[i]->GetPosition()) + { + // Replace our existing weapon in this slot + Weapon_Drop(m_hMyWeapons[i]); + { + // We found a slot, we don't care about the first null index anymore + iFirstNullIndex = -1; + + m_hMyWeapons.Set( i, pWeapon ); + break; + } + } + } + } + + if (iFirstNullIndex != -1) + m_hMyWeapons.Set( iFirstNullIndex, pWeapon ); + } + else + { + for (int i=0;iChangeTeam( GetTeamNumber() ); + + bool bPreserveAmmo = pWeapon->HasSpawnFlags(SF_WEAPON_PRESERVE_AMMO); + if (!bPreserveAmmo) + { + // ---------------------- + // Give Primary Ammo + // ---------------------- + // If gun doesn't use clips, just give ammo + if (pWeapon->GetMaxClip1() == -1) + { +#ifdef HL2_DLL + if( FStrEq(STRING(gpGlobals->mapname), "d3_c17_09") && FClassnameIs(pWeapon, "weapon_rpg") && pWeapon->NameMatches("player_spawn_items") ) + { + // !!!HACK - Don't give any ammo with the spawn equipment RPG in d3_c17_09. This is a chapter + // start and the map is way to easy if you start with 3 RPG rounds. It's fine if a player conserves + // them and uses them here, but it's not OK to start with enough ammo to bypass the snipers completely. + GiveAmmo( 0, pWeapon->m_iPrimaryAmmoType); + } + else +#endif // HL2_DLL + GiveAmmo(pWeapon->GetDefaultClip1(), pWeapon->m_iPrimaryAmmoType); + } + // If default ammo given is greater than clip + // size, fill clips and give extra ammo + else if ( pWeapon->GetDefaultClip1() > pWeapon->GetMaxClip1() ) + { + pWeapon->m_iClip1 = pWeapon->GetMaxClip1(); + GiveAmmo( (pWeapon->GetDefaultClip1() - pWeapon->GetMaxClip1()), pWeapon->m_iPrimaryAmmoType); + } + + // ---------------------- + // Give Secondary Ammo + // ---------------------- + // If gun doesn't use clips, just give ammo + if (pWeapon->GetMaxClip2() == -1) + { + GiveAmmo(pWeapon->GetDefaultClip2(), pWeapon->m_iSecondaryAmmoType); + } + // If default ammo given is greater than clip + // size, fill clips and give extra ammo + else if ( pWeapon->GetDefaultClip2() > pWeapon->GetMaxClip2() ) + { + pWeapon->m_iClip2 = pWeapon->GetMaxClip2(); + GiveAmmo( (pWeapon->GetDefaultClip2() - pWeapon->GetMaxClip2()), pWeapon->m_iSecondaryAmmoType); + } + } + else //if (IsPlayer()) + { + if (pWeapon->UsesClipsForAmmo1()) + { + if (pWeapon->m_iClip1 > pWeapon->GetMaxClip1()) + { + // Handle excess ammo + GiveAmmo( pWeapon->m_iClip1 - pWeapon->GetMaxClip1(), pWeapon->m_iPrimaryAmmoType ); + pWeapon->m_iClip1 = pWeapon->GetMaxClip1(); + } + } + else if (pWeapon->m_iClip1 > 0) + { + // Just because the weapon can't use clips doesn't mean + // the mapper can't override their clip value for ammo. + GiveAmmo(pWeapon->m_iClip1, pWeapon->m_iPrimaryAmmoType); + pWeapon->m_iClip1 = WEAPON_NOCLIP; + } + + if (pWeapon->UsesClipsForAmmo2()) + { + if (pWeapon->m_iClip2 > pWeapon->GetMaxClip2()) + { + // Handle excess ammo + GiveAmmo(pWeapon->m_iClip2 - pWeapon->GetMaxClip2(), pWeapon->m_iSecondaryAmmoType); + pWeapon->m_iClip2 = pWeapon->GetMaxClip2(); + } + } + else if (pWeapon->m_iClip2 > 0) + { + // Just because the weapon can't use clips doesn't mean + // the mapper can't override their clip value for ammo. + GiveAmmo(pWeapon->m_iClip2, pWeapon->m_iSecondaryAmmoType); + pWeapon->m_iClip2 = WEAPON_NOCLIP; + } + } + + pWeapon->Equip( this ); + + // Gotta do this *after* Equip because it may whack maxRange + if ( IsPlayer() == false ) + { + // If SF_NPC_LONG_RANGE spawn flags is set let weapon work from any distance + if ( HasSpawnFlags(SF_NPC_LONG_RANGE) ) + { + pWeapon->m_fMaxRange1 = 999999999; + pWeapon->m_fMaxRange2 = 999999999; + } + } + else if (bPreserveAmmo) + { + // The clip doesn't update on the client unless we do this. + // This is the only way I've figured out how to update without doing something worse. + // TODO: Remove this hack, we've finally fixed it + /* + variant_t clip1; + clip1.SetInt(pWeapon->m_iClip1); + variant_t clip2; + clip2.SetInt(pWeapon->m_iClip2); + + pWeapon->m_iClip1 = pWeapon->m_iClip1 - 1; + pWeapon->m_iClip2 = pWeapon->m_iClip2 - 1; + + g_EventQueue.AddEvent(pWeapon, "SetAmmo1", clip1, 0.0001f, this, this, 0); + g_EventQueue.AddEvent(pWeapon, "SetAmmo2", clip2, 0.0001f, this, this, 0); + */ + } + + // Pass the lighting origin over to the weapon if we have one + pWeapon->SetLightingOriginRelative( GetLightingOriginRelative() ); + + //if (m_aliveTimer.IsLessThen(0.01f)) + m_OnWeaponEquip.FireOutput(pWeapon, this); +} +#else //----------------------------------------------------------------------------- // Purpose: Add new weapon to the character // Input : New weapon @@ -2171,6 +2587,7 @@ void CBaseCombatCharacter::Weapon_Equip( CBaseCombatWeapon *pWeapon ) // Pass the lighting origin over to the weapon if we have one pWeapon->SetLightingOriginRelative( GetLightingOriginRelative() ); } +#endif //----------------------------------------------------------------------------- // Purpose: Leaves weapon, giving only ammo to the character @@ -2286,8 +2703,8 @@ CBaseCombatWeapon *CBaseCombatCharacter::Weapon_GetWpnForAmmo( int iAmmoIndex ) //----------------------------------------------------------------------------- bool CBaseCombatCharacter::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) { - int actCount = 0; - acttable_t *pTable = pWeapon->ActivityList( actCount ); + acttable_t *pTable = pWeapon->ActivityList(); + int actCount = pWeapon->ActivityListCount(); if( actCount < 1 ) { @@ -2304,6 +2721,12 @@ bool CBaseCombatCharacter::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) if ( SelectWeightedSequence(translatedActivity) == ACTIVITY_NOT_AVAILABLE ) { +#ifdef MAPBASE + // Do we have a backup? + translatedActivity = Weapon_BackupActivity((Activity)(pTable->baseAct), true, pWeapon); + if (SelectWeightedSequence(translatedActivity) != ACTIVITY_NOT_AVAILABLE) + return true; +#endif return false; } } @@ -2312,6 +2735,76 @@ bool CBaseCombatCharacter::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) return true; } +#ifdef MAPBASE + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +static Activity Weapon_BackupActivityFromList( CBaseCombatCharacter *pBCC, acttable_t *pTable, int actCount, Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pWeapon ) +{ + int i = 0; + for ( ; i < actCount; i++, pTable++ ) + { + if ( activity == pTable->baseAct ) + { + // Don't pick backup activities we don't actually have an animation for. + if (!pBCC->GetModelPtr()->HaveSequenceForActivity(pTable->weaponAct)) + break; + + return (Activity)pTable->weaponAct; + } + } + + // We didn't succeed in finding an activity. See if we can recurse + acttable_t *pBackupTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pTable - i, actCount ); + if (pBackupTable) + { + return Weapon_BackupActivityFromList( pBCC, pBackupTable, actCount, activity, weaponTranslationWasRequired, pWeapon ); + } + + return activity; +} + +//----------------------------------------------------------------------------- +// Purpose: Uses an activity from a different weapon when the activity we were originally looking for does not exist on this character. +// This gives NPCs and players the ability to use weapons they are otherwise unable to use. +//----------------------------------------------------------------------------- +Activity CBaseCombatCharacter::Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pSpecificWeapon ) +{ + CBaseCombatWeapon *pWeapon = pSpecificWeapon ? pSpecificWeapon : GetActiveWeapon(); + if (!pWeapon) + return activity; + + // Make sure the weapon allows this activity to have a backup. + if (!pWeapon->SupportsBackupActivity(activity)) + return activity; + + // UNDONE: Sometimes, a NPC is supposed to use the default activity. Return that if the weapon translation was "not required" and we have an original activity. + /* + if (!weaponTranslationWasRequired && GetModelPtr()->HaveSequenceForActivity(activity) && !IsPlayer()) + { + return activity; + } + */ + + acttable_t *pTable = pWeapon->GetBackupActivityList(); + int actCount = pWeapon->GetBackupActivityListCount(); + if (!pTable) + { + // Look for a default list + actCount = pWeapon->ActivityListCount(); + pTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pWeapon->ActivityList(), actCount ); + } + + if (pTable && GetModelPtr()) + { + return Weapon_BackupActivityFromList( this, pTable, actCount, activity, weaponTranslationWasRequired, pWeapon ); + } + + return activity; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : @@ -2358,6 +2851,11 @@ int CBaseCombatCharacter::TakeHealth (float flHealth, int bitsDamageType) { if (!m_takedamage) return 0; + +#ifdef MAPBASE + float flRatio = clamp( (float)m_iHealth / (float)m_iMaxHealth, 0.f, 1.f ); + m_OnHealthChanged.Set(flRatio, NULL, this); +#endif return BaseClass::TakeHealth(flHealth, bitsDamageType); } @@ -2424,8 +2922,21 @@ int CBaseCombatCharacter::OnTakeDamage( const CTakeDamageInfo &info ) { case LIFE_ALIVE: retVal = OnTakeDamage_Alive( info ); +#ifdef MAPBASE + if (retVal) + { + float flRatio = clamp( (float)m_iHealth / (float)m_iMaxHealth, 0.f, 1.f ); + m_OnHealthChanged.Set(flRatio, NULL, this); + } +#endif if ( m_iHealth <= 0 ) { +#ifdef MAPBASE_VSCRIPT + // False = Cheat death + if (ScriptDeathHook( const_cast(&info) ) == false) + return retVal; +#endif + IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) { @@ -2451,11 +2962,28 @@ int CBaseCombatCharacter::OnTakeDamage( const CTakeDamageInfo &info ) break; case LIFE_DYING: +#ifdef MAPBASE + retVal = OnTakeDamage_Dying( info ); + if (retVal) + { + float flRatio = clamp( (float)m_iHealth / (float)m_iMaxHealth, 0.f, 1.f ); + m_OnHealthChanged.Set(flRatio, NULL, this); + } + return retVal; +#else return OnTakeDamage_Dying( info ); +#endif default: case LIFE_DEAD: retVal = OnTakeDamage_Dead( info ); +#ifdef MAPBASE + if (retVal) + { + float flRatio = clamp( (float)m_iHealth / (float)m_iMaxHealth, 0.f, 1.f ); + m_OnHealthChanged.Set(flRatio, NULL, this); + } +#endif if ( m_iHealth <= 0 && g_pGameRules->Damage_ShouldGibCorpse( info.GetDamageType() ) && ShouldGib( info ) ) { Event_Gibbed( info ); @@ -2615,15 +3143,38 @@ void CBaseCombatCharacter::AddClassRelationship ( Class_T class_type, Dispositio m_Relationship[index].priority = ( priority != DEF_RELATIONSHIP_PRIORITY ) ? priority : 0; } +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: Add or Change a entity relationship for this entity -// Input : -// Output : +// Purpose: Removes a class relationship from our list +// Input : *class_type - Class with whom the relationship should be ended +// Output : True is relation was removed, false if it was not found //----------------------------------------------------------------------------- -void CBaseCombatCharacter::AddEntityRelationship ( CBaseEntity* pEntity, Disposition_t disposition, int priority ) +bool CBaseCombatCharacter::RemoveClassRelationship( Class_T class_type ) { - // First check to see if a relationship has already been declared for this entity - // If so, update it with the new relationship + // Find the relationship in our list, if it exists + for ( int i = m_Relationship.Count()-1; i >= 0; i-- ) + { + if ( m_Relationship[i].classType == class_type ) + { + // Done, remove it + m_Relationship.Remove( i ); + return true; + } + } + + return false; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Add or Change a entity relationship for this entity +// Input : +// Output : +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::AddEntityRelationship ( CBaseEntity* pEntity, Disposition_t disposition, int priority ) +{ + // First check to see if a relationship has already been declared for this entity + // If so, update it with the new relationship for (int i=m_Relationship.Count()-1;i >= 0;i--) { if (m_Relationship[i].entity == pEntity) @@ -2696,6 +3247,44 @@ void CBaseCombatCharacter::SetDefaultRelationship(Class_T nClass, Class_T nClass } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Fetch the default (ignore ai_relationship changes) relationship +// Input : +// Output : +//----------------------------------------------------------------------------- +Disposition_t CBaseCombatCharacter::GetDefaultRelationshipDisposition( Class_T nClassSource, Class_T nClassTarget ) +{ + Assert( m_DefaultRelationship != NULL ); + + return m_DefaultRelationship[nClassSource][nClassTarget].disposition; +} + +//----------------------------------------------------------------------------- +// Purpose: Fetch the default (ignore ai_relationship changes) priority +// Input : +// Output : +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::GetDefaultRelationshipPriority( Class_T nClassSource, Class_T nClassTarget ) +{ + Assert( m_DefaultRelationship != NULL ); + + return m_DefaultRelationship[nClassSource][nClassTarget].priority; +} + +//----------------------------------------------------------------------------- +// Purpose: Fetch the default (ignore ai_relationship changes) priority +// Input : +// Output : +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::GetDefaultRelationshipPriority( Class_T nClassTarget ) +{ + Assert( m_DefaultRelationship != NULL ); + + return m_DefaultRelationship[Classify()][nClassTarget].priority; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Fetch the default (ignore ai_relationship changes) relationship // Input : @@ -2751,7 +3340,24 @@ Relationship_t *CBaseCombatCharacter::FindEntityRelationship( CBaseEntity *pTarg Disposition_t CBaseCombatCharacter::IRelationType ( CBaseEntity *pTarget ) { if ( pTarget ) + { +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_RelationshipType.CanRunInScope( m_ScriptScope )) + { + // entity, default + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ScriptVariant_t( pTarget->GetScriptInstance() ), FindEntityRelationship( pTarget )->disposition }; + if (g_Hook_RelationshipType.Call( m_ScriptScope, &functionReturn, args ) && (functionReturn.m_type == FIELD_INTEGER && functionReturn.m_int != D_ER)) + { + // Use the disposition returned by the script + return (Disposition_t)functionReturn.m_int; + } + } +#endif + return FindEntityRelationship( pTarget )->disposition; + } + return D_NU; } @@ -2763,10 +3369,152 @@ Disposition_t CBaseCombatCharacter::IRelationType ( CBaseEntity *pTarget ) int CBaseCombatCharacter::IRelationPriority( CBaseEntity *pTarget ) { if ( pTarget ) + { +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_RelationshipPriority.CanRunInScope( m_ScriptScope )) + { + // entity, default + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ScriptVariant_t( pTarget->GetScriptInstance() ), FindEntityRelationship( pTarget )->priority }; + if (g_Hook_RelationshipPriority.Call( m_ScriptScope, &functionReturn, args ) && functionReturn.m_type == FIELD_INTEGER) + { + // Use the priority returned by the script + return functionReturn.m_int; + } + } +#endif + return FindEntityRelationship( pTarget )->priority; + } + return 0; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Ported from CAI_BaseNPC so players can use it +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::AddRelationship( const char *pszRelationship, CBaseEntity *pActivator ) +{ + // Parse the keyvalue data + char parseString[1000]; + Q_strncpy(parseString, pszRelationship, sizeof(parseString)); + + // Look for an entity string + char *entityString = strtok(parseString," "); + while (entityString) + { + // Get the disposition + char *dispositionString = strtok(NULL," "); + Disposition_t disposition = D_NU; + if ( dispositionString ) + { + if (!stricmp(dispositionString,"D_HT")) + { + disposition = D_HT; + } + else if (!stricmp(dispositionString,"D_FR")) + { + disposition = D_FR; + } + else if (!stricmp(dispositionString,"D_LI")) + { + disposition = D_LI; + } + else if (!stricmp(dispositionString,"D_NU")) + { + disposition = D_NU; + } + else + { + disposition = D_NU; + Warning( "***ERROR***\nBad relationship type (%s) to unknown entity (%s)!\n", dispositionString,entityString ); + Assert( 0 ); + return; + } + } + else + { + Warning("Can't parse relationship info (%s) - Expecting 'name [D_HT, D_FR, D_LI, D_NU] [1-99]'\n", pszRelationship ); + Assert(0); + return; + } + + // Get the priority + char *priorityString = strtok(NULL," "); + int priority = ( priorityString ) ? atoi(priorityString) : DEF_RELATIONSHIP_PRIORITY; + + bool bFoundEntity = false; + + // Try to get pointer to an entity of this name + CBaseEntity *entity = gEntList.FindEntityByName( NULL, entityString ); + while( entity ) + { + // make sure you catch all entities of this name. + bFoundEntity = true; + AddEntityRelationship(entity, disposition, priority ); + entity = gEntList.FindEntityByName( entity, entityString ); + } + + if( !bFoundEntity ) + { + // Need special condition for player as we can only have one + if (!stricmp("player", entityString) || !stricmp("!player", entityString)) + { + AddClassRelationship( CLASS_PLAYER, disposition, priority ); + } + // Otherwise try to create one too see if a valid classname and get class type + else + { + // HACKHACK: + CBaseEntity *pEntity = CanCreateEntityClass( entityString ) ? CreateEntityByName( entityString ) : NULL; + if (pEntity) + { + AddClassRelationship( pEntity->Classify(), disposition, priority ); + UTIL_RemoveImmediate(pEntity); + } + else + { +#ifdef MAPBASE // I know the extra #ifdef is pointless, but it's there so you know this is new + if (!Q_strnicmp(entityString, "CLASS_", 5)) + { + // Go through all of the classes and find which one this is + Class_T resultClass = CLASS_NONE; + for (int i = 0; i < NUM_AI_CLASSES; i++) + { + if (FStrEq(g_pGameRules->AIClassText(i), entityString)) + { + resultClass = (Class_T)i; + } + } + + if (resultClass != CLASS_NONE) + { + AddClassRelationship( resultClass, disposition, priority ); + bFoundEntity = true; + } + } + + if (!bFoundEntity) +#endif + DevWarning( "Couldn't set relationship to unknown entity or class (%s)!\n", entityString ); + } + } + } + // Check for another entity in the list + entityString = strtok(NULL," "); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputSetRelationship( inputdata_t &inputdata ) +{ + AddRelationship( inputdata.value.String(), inputdata.pActivator ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Get shoot position of BCC at current position/orientation // Input : @@ -2799,6 +3547,11 @@ CBaseEntity *CBaseCombatCharacter::FindHealthItem( const Vector &vecPosition, co if( pItem ) { +#ifdef MAPBASE + if (pItem->HasSpawnFlags(SF_ITEM_NO_NPC_PICKUP)) + continue; +#endif + // Healthkits and healthvials if( pItem->ClassMatches( "item_health*" ) && FVisible( pItem ) ) { @@ -2843,6 +3596,18 @@ CBaseEntity *CBaseCombatCharacter::Weapon_FindUsable( const Vector &range ) { bool bConservative = false; +#ifdef MAPBASE + if (HasContext("weapon_conservative:1")) + bConservative = true; +#ifdef HL2_DLL + else if (hl2_episodic.GetBool() && !GetActiveWeapon()) + { + // Unarmed citizens are conservative in their weapon finding...in Episode One + if (Classify() != CLASS_PLAYER_ALLY_VITAL && Q_strncmp(STRING(gpGlobals->mapname), "ep1_", 4)) + bConservative = true; + } +#endif +#else #ifdef HL2_DLL if( hl2_episodic.GetBool() && !GetActiveWeapon() ) { @@ -2852,6 +3617,7 @@ CBaseEntity *CBaseCombatCharacter::Weapon_FindUsable( const Vector &range ) bConservative = true; } } +#endif #endif CBaseCombatWeapon *weaponList[64]; @@ -2875,26 +3641,56 @@ CBaseEntity *CBaseCombatCharacter::Weapon_FindUsable( const Vector &range ) if ( pWeapon->CanBePickedUpByNPCs() == false ) continue; +#ifdef MAPBASE + if ( pWeapon->HasSpawnFlags(SF_WEAPON_NO_NPC_PICKUP) ) + continue; +#endif + if ( velocity.LengthSqr() > 1 || !Weapon_CanUse(pWeapon) ) continue; if ( pWeapon->IsLocked(this) ) continue; +#ifdef MAPBASE + // Skip weapons we already own + if ( Weapon_OwnsThisType(pWeapon->GetClassname()) ) + continue; +#endif + if ( GetActiveWeapon() ) { // Already armed. Would picking up this weapon improve my situation? +#ifndef MAPBASE if( GetActiveWeapon()->m_iClassname == pWeapon->m_iClassname ) { // No, I'm already using this type of weapon. continue; } +#endif +#ifdef MAPBASE + if ( pWeapon->IsMeleeWeapon() && !GetActiveWeapon()->IsMeleeWeapon() ) + { + // This weapon is a melee weapon and the weapon I have now is not. + // Picking up this weapon might not improve my situation. + continue; + } + + if ( pWeapon->GetWeight() != 0 && GetActiveWeapon()->GetWeight() > pWeapon->GetWeight() ) + { + // Discard if our target weapon supports weight but our current weapon has more of it. + // + // (RIP going from AR2 to shotgun) + continue; + } +#else if( FClassnameIs( pWeapon, "weapon_pistol" ) ) { // No, it's a pistol. continue; } +#endif } float fCurDist = (pWeapon->GetLocalOrigin() - GetLocalOrigin()).Length(); @@ -2907,6 +3703,23 @@ CBaseEntity *CBaseCombatCharacter::Weapon_FindUsable( const Vector &range ) if ( pBestWeapon ) { +#ifdef MAPBASE + // NPCs now use weight to determine which weapon is best. + // All HL2 weapons are weighted and are usually good enough. + // + // This probably won't cause problems... + if (pWeapon->GetWeight() > 1) + { +#if 0 + float flRatio = MIN( (2.5f / (pWeapon->GetWeight() - (GetActiveWeapon() ? GetActiveWeapon()->GetWeight() : 0))), 1.0 ); + if (flRatio < 0) + flRatio *= -1; flRatio += 1.0f; + fCurDist *= flRatio; +#else + fCurDist *= MIN( (2.5f / pWeapon->GetWeight()), 1.0 ); +#endif + } +#else // UNDONE: Better heuristic needed here // Need to pick by power of weapons // Don't want to pick a weapon right next to a NPC! @@ -2916,6 +3729,7 @@ CBaseEntity *CBaseCombatCharacter::Weapon_FindUsable( const Vector &range ) { fCurDist *= 0.5; } +#endif // choose the last range attack weapon you find or the first available other weapon if ( ! (pWeapon->CapabilitiesGet() & bits_CAP_RANGE_ATTACK_GROUP) ) @@ -2993,19 +3807,7 @@ int CBaseCombatCharacter::GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSo // Ammo pickup sound if ( !bSuppressSound ) { -#ifdef VANCE - CBasePlayer *pPlayer = dynamic_cast( this ); - if ( pPlayer && !pPlayer->IsSuitEquipped() ) - { - EmitSound( "HL2Player.AmmoPickup_Suitless" ); - } - else - { - EmitSound( "BaseCombatCharacter.AmmoPickup" ); - } -#else EmitSound( "BaseCombatCharacter.AmmoPickup" ); -#endif } m_iAmmo.Set( iAmmoIndex, m_iAmmo[iAmmoIndex] + iAdd ); @@ -3342,6 +4144,306 @@ void CBaseCombatCharacter::InputKilledNPC( inputdata_t &inputdata ) OnKilledNPC( inputdata.pActivator ? inputdata.pActivator->MyCombatCharacterPointer() : NULL ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Handle enemy kills. (this technically measures players too) +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::OnKilledNPC( CBaseCombatCharacter *pKilled ) +{ + m_OnKilledEnemy.Set(pKilled, pKilled, this); + + // Fire an additional output if this was a player + if (pKilled && pKilled->IsPlayer()) + m_OnKilledPlayer.Set(pKilled, pKilled, this); +} + +//------------------------------------------------------------------------------ +// Purpose: Give the NPC in question the weapon specified +//------------------------------------------------------------------------------ +void CBaseCombatCharacter::InputGiveWeapon( inputdata_t &inputdata ) +{ + // Give the NPC the specified weapon + string_t iszWeaponName = inputdata.value.StringID(); + if ( iszWeaponName != NULL_STRING ) + { + if (IsNPC()) + { + if( Classify() == CLASS_PLAYER_ALLY_VITAL ) + { + MyNPCPointer()->m_iszPendingWeapon = iszWeaponName; + } + else + { + MyNPCPointer()->GiveWeapon( iszWeaponName ); + } + } + else + { + CBaseCombatWeapon *pWeapon = Weapon_Create(STRING(iszWeaponName)); + if (pWeapon) + { + Weapon_Equip(pWeapon); + } + else + { + Warning( "Couldn't create weapon %s to give %s.\n", STRING(iszWeaponName), GetDebugName() ); + return; + } + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputDropWeapon( inputdata_t &inputdata ) +{ + CBaseCombatWeapon *pWeapon = FStrEq(inputdata.value.String(), "") ? GetActiveWeapon() : Weapon_OwnsThisType(inputdata.value.String()); + if (pWeapon) + { + Weapon_Drop(pWeapon); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputPickupWeaponInstant( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity() && inputdata.value.Entity()->IsBaseCombatWeapon()) + { + CBaseCombatWeapon *pWeapon = inputdata.value.Entity()->MyCombatWeaponPointer(); + if (pWeapon->GetOwner()) + { + Msg("Ignoring PickupWeaponInstant on %s because %s already has an owner\n", GetDebugName(), pWeapon->GetDebugName()); + return; + } + + if (CBaseCombatWeapon *pExistingWeapon = Weapon_OwnsThisType(pWeapon->GetClassname())) + { + // Drop our existing weapon then! + Weapon_Drop(pExistingWeapon); + } + + if (IsNPC()) + { + Weapon_Equip(pWeapon); + MyNPCPointer()->OnGivenWeapon(pWeapon); + } + else + { + Weapon_Equip(pWeapon); + } + + pWeapon->OnPickedUp( this ); + } + else + { + Warning("%s received PickupWeaponInstant with invalid entity %s\n", GetDebugName(), inputdata.value.Entity() ? inputdata.value.Entity()->GetDebugName() : "<>"); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputHolsterWeapon( inputdata_t &inputdata ) +{ + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if (pWeapon) + { + pWeapon->Holster(); + //SetActiveWeapon( NULL ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputHolsterAndDestroyWeapon( inputdata_t &inputdata ) +{ + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if (pWeapon) + { + pWeapon->Holster(); + SetActiveWeapon( NULL ); + + if (pWeapon->GetActivity() == ACT_VM_HOLSTER) + { + // Remove when holster is finished + pWeapon->ThinkSet( &CBaseEntity::SUB_Remove, gpGlobals->curtime + pWeapon->GetViewModelSequenceDuration() ); + } + else + { + // Remove now + UTIL_Remove( pWeapon ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputUnholsterWeapon( inputdata_t &inputdata ) +{ + // NPCs can handle strings, but players fall back to SwitchToWeapon + if (inputdata.value.StringID() != NULL_STRING) + InputSwitchToWeapon( inputdata ); + + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if (pWeapon && pWeapon->IsEffectActive(EF_NODRAW)) + { + pWeapon->Deploy(); + } +} + +//------------------------------------------------------------------------------ +// Purpose: Makes the NPC instantly switch to the specified weapon, creates it if it doesn't exist +//------------------------------------------------------------------------------ +void CBaseCombatCharacter::InputSwitchToWeapon( inputdata_t &inputdata ) +{ + for (int i = 0; im_iClassname == inputdata.value.StringID()) + { + Weapon_Switch( m_hMyWeapons[i] ); + return; + } + } + + // We must not have it + if (IsNPC()) + MyNPCPointer()->GiveWeapon( inputdata.value.StringID(), false ); + else + { + CBaseCombatWeapon *pWeapon = Weapon_Create( inputdata.value.String() ); + if (pWeapon) + { + Weapon_Equip( pWeapon ); + } + else + { + Warning( "Couldn't create weapon %s to give %s.\n", inputdata.value.String(), GetDebugName() ); + } + } +} + +#define FINDNAMEDENTITY_MAX_ENTITIES 32 +//----------------------------------------------------------------------------- +// Purpose: FindNamedEntity has been moved from CAI_BaseNPC to CBaseCombatCharacter so players can use it. +// Coincidentally, everything that it did on NPCs could be done on BaseCombatCharacters with no consequences. +// Input : +// Output : +//----------------------------------------------------------------------------- +CBaseEntity *CBaseCombatCharacter::FindNamedEntity( const char *szName, IEntityFindFilter *pFilter ) +{ + const char *name = szName; + if (name[0] == '!') + name++; + + if ( !stricmp( name, "player" )) + { + return AI_GetSinglePlayer(); + } + else if ( !stricmp( name, "enemy" ) ) + { + return GetEnemy(); + } + else if ( !stricmp( name, "self" ) || !stricmp( name, "target1" ) ) + { + return this; + } + else if ( !stricmp( name, "nearestfriend" ) || !strnicmp( name, "friend", 6 ) ) + { + // Just look for the nearest friendly NPC within 500 units + // (most of this was stolen from CAI_PlayerAlly::FindSpeechTarget()) + const Vector & vAbsOrigin = GetAbsOrigin(); + float closestDistSq = Square(500.0); + CBaseEntity * pNearest = NULL; + float distSq; + int i; + for ( i = 0; i < g_AI_Manager.NumAIs(); i++ ) + { + CAI_BaseNPC *pNPC = (g_AI_Manager.AccessAIs())[i]; + + if ( pNPC == this ) + continue; + + distSq = ( vAbsOrigin - pNPC->GetAbsOrigin() ).LengthSqr(); + + if ( distSq > closestDistSq ) + continue; + + if ( IRelationType( pNPC ) == D_LI ) + { + closestDistSq = distSq; + pNearest = pNPC; + } + } + + if (stricmp(name, "friend_npc") != 0) + { + // Okay, find the nearest friendly client. + for ( i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer ) + { + // Don't get players with notarget + if (pPlayer->GetFlags() & FL_NOTARGET) + continue; + + distSq = ( vAbsOrigin - pPlayer->GetAbsOrigin() ).LengthSqr(); + + if ( distSq > closestDistSq ) + continue; + + if ( IRelationType( pPlayer ) == D_LI ) + { + closestDistSq = distSq; + pNearest = pPlayer; + } + } + } + } + + return pNearest; + } + else if (!stricmp( name, "weapon" )) + { + return GetActiveWeapon(); + } + + // HACKHACK: FindEntityProcedural can go through this now, so running this code could cause an infinite loop. + // As a result, FindEntityProcedural currently identifies itself with this entity filter. + else if (!pFilter || !dynamic_cast(pFilter)) + { + // search for up to 32 entities with the same name and choose one randomly + CBaseEntity *entityList[ FINDNAMEDENTITY_MAX_ENTITIES ]; + CBaseEntity *entity; + int iCount; + + entity = NULL; + for( iCount = 0; iCount < FINDNAMEDENTITY_MAX_ENTITIES; iCount++ ) + { + entity = gEntList.FindEntityByName( entity, szName, this, NULL, NULL, pFilter ); + if ( !entity ) + { + break; + } + entityList[ iCount ] = entity; + } + + if ( iCount > 0 ) + { + int index = RandomInt( 0, iCount - 1 ); + entity = entityList[ index ]; + return entity; + } + } + + return NULL; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Overload our muzzle flash and send it to any actively held weapon //----------------------------------------------------------------------------- @@ -3360,6 +4462,204 @@ void CBaseCombatCharacter::DoMuzzleFlash() } } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseCombatCharacter::ScriptGetActiveWeapon() +{ + return ToHScript( GetActiveWeapon() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseCombatCharacter::ScriptGetWeapon( int i ) +{ + Assert( i >= 0 && i < MAX_WEAPONS ); + + if ( i < 0 || i >= MAX_WEAPONS ) + return NULL; + + return ToHScript( GetWeapon( i ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseCombatCharacter::ScriptGetWeaponByType( const char *pszWeapon, int iSubType ) +{ + return ToHScript( Weapon_OwnsThisType( pszWeapon, iSubType ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptGetAllWeapons( HSCRIPT hTable ) +{ + for (int i=0;iSetValue( hTable, m_hMyWeapons[i]->GetClassname(), ToHScript( m_hMyWeapons[i] ) ); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptDropWeapon( HSCRIPT hWeapon ) +{ + CBaseCombatWeapon *pWeapon = HScriptToClass( hWeapon ); + if (!pWeapon) + return; + + if (pWeapon->GetOwner() == this) + { + // Drop the weapon + Weapon_Drop( pWeapon ); + } + else + { + CGMsg( 1, CON_GROUP_VSCRIPT, "ScriptDropWeapon: %s is not owned by %s", pWeapon->GetDebugName(), GetDebugName() ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptEquipWeapon( HSCRIPT hWeapon ) +{ + CBaseCombatWeapon *pWeapon = HScriptToClass( hWeapon ); + if (!pWeapon) + return; + + if (pWeapon->GetOwner() == this) + { + // Switch to this weapon + Weapon_Switch( pWeapon ); + } + else + { + if (CBaseCombatWeapon *pExistingWeapon = Weapon_OwnsThisType( pWeapon->GetClassname() )) + { + // Drop our existing weapon then! + Weapon_Drop( pExistingWeapon ); + } + + if (IsNPC()) + { + Weapon_Equip( pWeapon ); + MyNPCPointer()->OnGivenWeapon( pWeapon ); + } + else + { + Weapon_Equip( pWeapon ); + } + + pWeapon->OnPickedUp( this ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::ScriptGiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound ) +{ + return GiveAmmo( iCount, iAmmoIndex, bSuppressSound ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptRemoveAmmo( int iCount, int iAmmoIndex ) +{ + if (iAmmoIndex == -1) + { + Warning( "%i is not a valid ammo type\n", iAmmoIndex ); + return; + } + + RemoveAmmo( iCount, iAmmoIndex ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::ScriptGetAmmoCount( int iType ) const +{ + Assert( iType == -1 || iType < MAX_AMMO_SLOTS ); + + if ( iType < 0 || iType >= MAX_AMMO_SLOTS ) + return 0; + + return GetAmmoCount( iType ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptSetAmmoCount( int iType, int iCount ) +{ + Assert( iType == -1 || iType < MAX_AMMO_SLOTS ); + + if ( iType < 0 || iType >= MAX_AMMO_SLOTS ) + return; + + return SetAmmoCount( iCount, iType ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const Vector& CBaseCombatCharacter::ScriptGetAttackSpread( HSCRIPT hWeapon, HSCRIPT hTarget ) +{ + CBaseEntity *pWeapon = ToEnt( hWeapon ); + if (!pWeapon || !pWeapon->IsBaseCombatWeapon()) + { + Warning( "GetAttackSpread: %s is not a valid weapon\n", pWeapon ? pWeapon->GetDebugName() : "Null entity" ); + return vec3_origin; + } + + // TODO: Make this a simple non-reference Vector? + static Vector vec; + vec = GetAttackSpread( pWeapon->MyCombatWeaponPointer(), ToEnt( hTarget ) ); + return vec; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +float CBaseCombatCharacter::ScriptGetSpreadBias( HSCRIPT hWeapon, HSCRIPT hTarget ) +{ + CBaseEntity *pWeapon = ToEnt( hWeapon ); + if (!pWeapon || !pWeapon->IsBaseCombatWeapon()) + { + Warning( "GetSpreadBias: %s is not a valid weapon\n", pWeapon ? pWeapon->GetDebugName() : "Null entity" ); + return 1.0f; + } + + return GetSpreadBias( pWeapon->MyCombatWeaponPointer(), ToEnt( hTarget ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::ScriptRelationType( HSCRIPT pTarget ) +{ + return (int)IRelationType( ToEnt( pTarget ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CBaseCombatCharacter::ScriptRelationPriority( HSCRIPT pTarget ) +{ + return IRelationPriority( ToEnt( pTarget ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::ScriptSetRelationship( HSCRIPT pTarget, int disposition, int priority ) +{ + AddEntityRelationship( ToEnt( pTarget ), (Disposition_t)disposition, priority ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseCombatCharacter::ScriptGetVehicleEntity() +{ + return ToHScript( GetVehicleEntity() ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: return true if given target cant be seen because of fog //----------------------------------------------------------------------------- diff --git a/game/server/basecombatcharacter.h b/game/server/basecombatcharacter.h index 0d005b6b..f3f071e6 100644 --- a/game/server/basecombatcharacter.h +++ b/game/server/basecombatcharacter.h @@ -119,6 +119,9 @@ class CBaseCombatCharacter : public CBaseFlex DECLARE_SERVERCLASS(); DECLARE_DATADESC(); DECLARE_PREDICTABLE(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif public: @@ -136,6 +139,10 @@ class CBaseCombatCharacter : public CBaseFlex virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ) { return BaseClass::FVisible( vecTarget, traceMask, ppBlocker ); } static void ResetVisibilityCache( CBaseCombatCharacter *pBCC = NULL ); +#ifdef MAPBASE + virtual bool ShouldUseVisibilityCache( CBaseEntity *pEntity ); +#endif + #ifdef PORTAL virtual bool FVisibleThroughPortal( const CProp_Portal *pPortal, CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); #endif @@ -154,8 +161,10 @@ class CBaseCombatCharacter : public CBaseFlex virtual bool ShouldShootMissTarget( CBaseCombatCharacter *pAttacker ); virtual CBaseEntity *FindMissTarget( void ); +#ifndef MAPBASE // This function now exists in CBaseEntity // Do not call HandleInteraction directly, use DispatchInteraction bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; } +#endif virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); virtual QAngle BodyAngles(); @@ -225,7 +234,14 @@ class CBaseCombatCharacter : public CBaseFlex virtual void Weapon_HandleAnimEvent( animevent_t *pEvent ); CBaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon ); // True is allowed to use this class of weapon +#ifdef MAPBASE + virtual Activity Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired = false, CBaseCombatWeapon *pSpecificWeapon = NULL ); + virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); // Adds weapon to player + virtual void Weapon_EquipHolstered( CBaseCombatWeapon *pWeapon ); // Pretty much only useful for NPCs + virtual void Weapon_HandleEquip( CBaseCombatWeapon *pWeapon ); +#else virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); // Adds weapon to player +#endif virtual bool Weapon_EquipAmmoOnly( CBaseCombatWeapon *pWeapon ); // Adds weapon ammo to player, leaves weapon bool Weapon_Detach( CBaseCombatWeapon *pWeapon ); // Clear any pointers to the weapon. virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL ); @@ -288,7 +304,29 @@ class CBaseCombatCharacter : public CBaseFlex // Killed a character void InputKilledNPC( inputdata_t &inputdata ); +#ifdef MAPBASE + + void InputGiveWeapon( inputdata_t &inputdata ); + void InputDropWeapon( inputdata_t &inputdata ); + void InputPickupWeaponInstant( inputdata_t &inputdata ); + COutputEvent m_OnWeaponEquip; + COutputEvent m_OnWeaponDrop; + + virtual void InputHolsterWeapon( inputdata_t &inputdata ); + virtual void InputHolsterAndDestroyWeapon( inputdata_t &inputdata ); + virtual void InputUnholsterWeapon( inputdata_t &inputdata ); + void InputSwitchToWeapon( inputdata_t &inputdata ); + + COutputEHANDLE m_OnKilledEnemy; + COutputEHANDLE m_OnKilledPlayer; + virtual void OnKilledNPC( CBaseCombatCharacter *pKilled ); + + virtual CBaseEntity *FindNamedEntity( const char *pszName, IEntityFindFilter *pFilter = NULL ); + + COutputFloat m_OnHealthChanged; +#else virtual void OnKilledNPC( CBaseCombatCharacter *pKilled ) {}; +#endif // Exactly one of these happens immediately after killed (gibbed may happen later when the corpse gibs) // Character gibbed or faded out (violence controls) (only fired once) @@ -304,6 +342,12 @@ class CBaseCombatCharacter : public CBaseFlex virtual bool BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags ); +#ifdef MAPBASE + // A version of BecomeRagdollBoogie() that allows the color to change and returns the entity itself instead. + // In order to avoid breaking anything, it doesn't change the original function. + virtual CBaseEntity *BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags, const Vector *vecColor ); +#endif + CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range ); @@ -327,6 +371,11 @@ class CBaseCombatCharacter : public CBaseFlex virtual Disposition_t IRelationType( CBaseEntity *pTarget ); virtual int IRelationPriority( CBaseEntity *pTarget ); +#ifdef MAPBASE + void AddRelationship( const char *pszRelationship, CBaseEntity *pActivator ); + void InputSetRelationship( inputdata_t &inputdata ); +#endif + virtual void SetLightingOriginRelative( CBaseEntity *pLightingOrigin ); protected: @@ -342,6 +391,9 @@ class CBaseCombatCharacter : public CBaseFlex // Blood color (see BLOOD_COLOR_* macros in baseentity.h) void SetBloodColor( int nBloodColor ); +#ifdef MAPBASE + void InputSetBloodColor( inputdata_t &inputdata ); +#endif // Weapons.. CBaseCombatWeapon* GetActiveWeapon() const; @@ -352,23 +404,78 @@ class CBaseCombatCharacter : public CBaseFlex CBaseCombatWeapon* GetWeapon( int i ) const; bool RemoveWeapon( CBaseCombatWeapon *pWeapon ); virtual void RemoveAllWeapons(); - WeaponProficiency_t GetCurrentWeaponProficiency() { return m_CurrentWeaponProficiency; } + WeaponProficiency_t GetCurrentWeaponProficiency() + { +#ifdef MAPBASE + // Mapbase adds proficiency override + return (m_ProficiencyOverride > WEAPON_PROFICIENCY_INVALID) ? m_ProficiencyOverride : m_CurrentWeaponProficiency; +#else + return m_CurrentWeaponProficiency; +#endif + } void SetCurrentWeaponProficiency( WeaponProficiency_t iProficiency ) { m_CurrentWeaponProficiency = iProficiency; } virtual WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ); +#ifdef MAPBASE + inline bool OverridingWeaponProficiency() { return (m_ProficiencyOverride > WEAPON_PROFICIENCY_INVALID); } +#endif virtual Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL ); virtual float GetSpreadBias( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget ); virtual void DoMuzzleFlash(); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetActiveWeapon(); + HSCRIPT ScriptGetWeapon( int i ); + HSCRIPT ScriptGetWeaponByType( const char *pszWeapon, int iSubType = 0 ); + void ScriptGetAllWeapons( HSCRIPT hTable ); + int ScriptGetCurrentWeaponProficiency() { return GetCurrentWeaponProficiency(); } + + void ScriptDropWeapon( HSCRIPT hWeapon ); + void ScriptEquipWeapon( HSCRIPT hWeapon ); + + int ScriptGiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false ); + void ScriptRemoveAmmo( int iCount, int iAmmoIndex ); + int ScriptGetAmmoCount( int iType ) const; + void ScriptSetAmmoCount( int iType, int iCount ); + + const Vector& ScriptGetAttackSpread( HSCRIPT hWeapon, HSCRIPT hTarget ); + float ScriptGetSpreadBias( HSCRIPT hWeapon, HSCRIPT hTarget ); + + int ScriptRelationType( HSCRIPT pTarget ); + int ScriptRelationPriority( HSCRIPT pTarget ); + void ScriptSetRelationship( HSCRIPT pTarget, int disposition, int priority ); + + HSCRIPT ScriptGetVehicleEntity(); + + bool ScriptInViewCone( const Vector &vecSpot ) { return FInViewCone( vecSpot ); } + bool ScriptEntInViewCone( HSCRIPT pEntity ) { return FInViewCone( ToEnt( pEntity ) ); } + + bool ScriptInAimCone( const Vector &vecSpot ) { return FInAimCone( vecSpot ); } + bool ScriptEntInAimCone( HSCRIPT pEntity ) { return FInAimCone( ToEnt( pEntity ) ); } + + const Vector& ScriptBodyAngles( void ) { static Vector vec; QAngle qa = BodyAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; } + + static ScriptHook_t g_Hook_RelationshipType; + static ScriptHook_t g_Hook_RelationshipPriority; +#endif + // Interactions static void InitInteractionSystem(); // Relationships static void AllocateDefaultRelationships( ); static void SetDefaultRelationship( Class_T nClass, Class_T nClassTarget, Disposition_t nDisposition, int nPriority ); +#ifdef MAPBASE + static Disposition_t GetDefaultRelationshipDisposition( Class_T nClassSource, Class_T nClassTarget ); + static int GetDefaultRelationshipPriority( Class_T nClassSource, Class_T nClassTarget ); + int GetDefaultRelationshipPriority( Class_T nClassTarget ); +#endif Disposition_t GetDefaultRelationshipDisposition( Class_T nClassTarget ); virtual void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ); virtual bool RemoveEntityRelationship( CBaseEntity *pEntity ); virtual void AddClassRelationship( Class_T nClass, Disposition_t nDisposition, int nPriority ); +#ifdef MAPBASE + virtual bool RemoveClassRelationship( Class_T nClass ); +#endif virtual void ChangeTeam( int iTeamNum ); @@ -453,7 +560,9 @@ class CBaseCombatCharacter : public CBaseFlex public: // returns the last body region that took damage int LastHitGroup() const { return m_LastHitGroup; } +#ifndef MAPBASE // For filter_damage_transfer protected: +#endif void SetLastHitGroup( int nHitGroup ) { m_LastHitGroup = nHitGroup; } public: @@ -467,10 +576,6 @@ class CBaseCombatCharacter : public CBaseFlex private: Hull_t m_eHull; -#ifdef VANCE - friend class CShowWeapon; // This allows CShowWeapon to access whatever it needs to update for the character -#endif - void UpdateGlowEffect( void ); void DestroyGlowEffect( void ); @@ -488,6 +593,11 @@ class CBaseCombatCharacter : public CBaseFlex public: static int GetInteractionID(); // Returns the next interaction # +#ifdef MAPBASE + // Mapbase's new method for adding interactions which allows them to be handled with their names, currently for VScript + static void AddInteractionWithString( int &interaction, const char *szName ); +#endif + protected: // Visibility-related stuff bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const; @@ -510,6 +620,11 @@ class CBaseCombatCharacter : public CBaseFlex // cached off as the CurrentWeaponProficiency. WeaponProficiency_t m_CurrentWeaponProficiency; +#ifdef MAPBASE + // Weapon proficiency can be overridden with this. + WeaponProficiency_t m_ProficiencyOverride = WEAPON_PROFICIENCY_INVALID; +#endif + // --------------- // Relationships // --------------- @@ -523,6 +638,7 @@ class CBaseCombatCharacter : public CBaseFlex CNetworkArray( CBaseCombatWeaponHandle, m_hMyWeapons, MAX_WEAPONS ); CNetworkHandle( CBaseCombatWeapon, m_hActiveWeapon ); + #ifdef VANCE CNetworkHandle( CBaseCombatWeapon, m_hDeployingWeapon ); friend class CBasePlayer; diff --git a/game/server/basecombatweapon.cpp b/game/server/basecombatweapon.cpp index c05cb33d..2863b747 100644 --- a/game/server/basecombatweapon.cpp +++ b/game/server/basecombatweapon.cpp @@ -342,7 +342,11 @@ bool CBaseCombatWeapon::WeaponLOSCondition( const Vector &ownerPos, const Vector if ( pBCC ) { +#ifdef MAPBASE + if ( npcOwner->IRelationType( pBCC ) <= D_FR ) +#else if ( npcOwner->IRelationType( pBCC ) == D_HT ) +#endif return true; if ( bSetConditions ) @@ -369,7 +373,12 @@ bool CBaseCombatWeapon::WeaponLOSCondition( const Vector &ownerPos, const Vector //----------------------------------------------------------------------------- int CBaseCombatWeapon::WeaponRangeAttack1Condition( float flDot, float flDist ) { +#ifdef MAPBASE + // HACKHACK: HasPrimaryAmmo() checks the NPC's reserve ammo counts, which should not be evaluated here if we use clips + if ( UsesPrimaryAmmo() && (UsesClipsForAmmo1() ? !m_iClip1 : !HasPrimaryAmmo()) ) +#else if ( UsesPrimaryAmmo() && !HasPrimaryAmmo() ) +#endif { return COND_NO_PRIMARY_AMMO; } @@ -478,7 +487,11 @@ void CBaseCombatWeapon::Kill( void ) //----------------------------------------------------------------------------- void CBaseCombatWeapon::FallInit( void ) { +#ifdef MAPBASE + SetModel( (GetDroppedModel() && GetDroppedModel()[0]) ? GetDroppedModel() : GetWorldModel() ); +#else SetModel( GetWorldModel() ); +#endif VPhysicsDestroyObject(); if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) ) @@ -716,6 +729,11 @@ void CBaseCombatWeapon::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ { m_OnPlayerUse.FireOutput( pActivator, pCaller ); +#ifdef MAPBASE + // Mark that we're being +USE'd, not bumped + AddSpawnFlags(SF_WEAPON_USED); +#endif + // // Bump the weapon to try equipping it before picking it up physically. This is // important in a few spots in the game where the player could potentially +use pickup @@ -729,6 +747,10 @@ void CBaseCombatWeapon::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ { pPlayer->PickupObject( this ); } + +#ifdef MAPBASE + RemoveSpawnFlags(SF_WEAPON_USED); +#endif } } diff --git a/game/server/baseentity.cpp b/game/server/baseentity.cpp index 9bd525a4..45b2b8cc 100644 --- a/game/server/baseentity.cpp +++ b/game/server/baseentity.cpp @@ -62,6 +62,13 @@ #include "env_debughistory.h" #include "tier1/utlstring.h" #include "utlhashtable.h" +#ifdef MAPBASE +#include "mapbase/matchers.h" +#include "mapbase/datadesc_mod.h" +#endif +#ifdef NEW_RESPONSE_SYSTEM +#include "ai_speech.h" +#endif #if defined( TF_DLL ) #include "tf_gamerules.h" @@ -86,7 +93,6 @@ bool CBaseEntity::sm_bDisableTouchFuncs = false; // Disables PhysicsTouch and Ph bool CBaseEntity::sm_bAccurateTriggerBboxChecks = true; // set to false for legacy behavior in ep1 int CBaseEntity::m_nPredictionRandomSeed = -1; -int CBaseEntity::m_nPredictionRandomSeedServer = -1; CBasePlayer *CBaseEntity::m_pPredictionPlayer = NULL; // Used to make sure nobody calls UpdateTransmitState directly. @@ -98,6 +104,13 @@ bool CBaseEntity::s_bAbsQueriesValid = true; ConVar sv_netvisdist( "sv_netvisdist", "10000", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Test networking visibility distance" ); +ConVar sv_script_think_interval("sv_script_think_interval", "0.1"); + +#ifdef MAPBASE_VSCRIPT +ConVar ent_text_allow_script( "ent_text_allow_script", "1" ); +#endif + + // This table encodes edict data. void SendProxy_AnimTime( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID ) { @@ -112,7 +125,7 @@ void SendProxy_AnimTime( const SendProp *pProp, const void *pStruct, const void Assert( !pAnimating->IsUsingClientSideAnimation() ); } #endif - + int ticknumber = TIME_TO_TICKS( pEntity->m_flAnimTime ); // Tickbase is current tick rounded down to closes 100 ticks int tickbase = gpGlobals->GetNetworkBase( gpGlobals->tickcount, pEntity->entindex() ); @@ -152,12 +165,12 @@ void* SendProxy_ClientSideAnimation( const SendProp *pProp, const void *pStruct, return (void*)pVarData; else return NULL; // Don't send animtime unless the client needs it. -} +} REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_ClientSideAnimation ); BEGIN_SEND_TABLE_NOBASE( CBaseEntity, DT_AnimTimeMustBeFirst ) - // NOTE: Animtime must be sent before origin and angles ( from pev ) because it has a + // NOTE: Animtime must be sent before origin and angles ( from pev ) because it has a // proxy on the client that stores off the old values before writing in the new values and // if it is sent after the new values, then it will only have the new origin and studio model, etc. // interpolation will be busted @@ -179,7 +192,7 @@ static void* SendProxy_SendPredictableId( const SendProp *pProp, const void *pSt int id_player_index = pEntity->m_PredictableID->GetPlayer(); pRecipients->SetOnly( id_player_index ); - + return ( void * )pVarData; } REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendPredictableId ); @@ -262,7 +275,7 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity ) SendPropDataTable( "AnimTimeMustBeFirst", 0, &REFERENCE_SEND_TABLE(DT_AnimTimeMustBeFirst), SendProxy_ClientSideAnimation ), SendPropInt (SENDINFO(m_flSimulationTime), SIMULATION_TIME_WINDOW_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN|SPROP_ENCODED_AGAINST_TICKCOUNT, SendProxy_SimulationTime), -#if PREDICTION_ERROR_CHECK_LEVEL > 1 +#if PREDICTION_ERROR_CHECK_LEVEL > 1 SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ), #else SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_COORD|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ), @@ -275,6 +288,11 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity ) SendPropInt (SENDINFO(m_nRenderMode), 8, SPROP_UNSIGNED ), SendPropInt (SENDINFO(m_fEffects), EF_MAX_BITS, SPROP_UNSIGNED), SendPropInt (SENDINFO(m_clrRender), 32, SPROP_UNSIGNED), +#ifdef MAPBASE + // Keep consistent with VIEW_ID_COUNT in viewrender.h + SendPropInt (SENDINFO(m_iViewHideFlags), 9, SPROP_UNSIGNED ), + SendPropBool (SENDINFO(m_bDisableFlashlight) ), +#endif SendPropInt (SENDINFO(m_iTeamNum), TEAMNUM_NUM_BITS, 0), SendPropInt (SENDINFO(m_CollisionGroup), 5, SPROP_UNSIGNED), SendPropFloat (SENDINFO(m_flElasticity), 0, SPROP_COORD), @@ -284,9 +302,11 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity ) SendPropEHandle (SENDINFO_NAME(m_hMoveParent, moveparent)), SendPropInt (SENDINFO(m_iParentAttachment), NUM_PARENTATTACHMENT_BITS, SPROP_UNSIGNED), + SendPropStringT( SENDINFO( m_iName ) ), + SendPropInt (SENDINFO_NAME( m_MoveType, movetype ), MOVETYPE_MAX_BITS, SPROP_UNSIGNED ), SendPropInt (SENDINFO_NAME( m_MoveCollide, movecollide ), MOVECOLLIDE_MAX_BITS, SPROP_UNSIGNED ), -#if PREDICTION_ERROR_CHECK_LEVEL > 1 +#if PREDICTION_ERROR_CHECK_LEVEL > 1 SendPropVector (SENDINFO(m_angRotation), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0, HIGH_DEFAULT, SendProxy_Angles ), #else SendPropQAngles (SENDINFO(m_angRotation), 13, SPROP_CHANGES_OFTEN, SendProxy_Angles ), @@ -345,8 +365,6 @@ void CBaseEntityModelLoadProxy::Handler::OnModelLoadComplete( const model_t *pMo CBaseEntity::CBaseEntity( bool bServerOnly ) { - m_pAttributes = NULL; - COMPILE_TIME_ASSERT( MOVETYPE_LAST < (1 << MOVETYPE_MAX_BITS) ); COMPILE_TIME_ASSERT( MOVECOLLIDE_COUNT < (1 << MOVECOLLIDE_MAX_BITS) ); @@ -440,6 +458,17 @@ extern bool g_bDisableEhandleAccess; //----------------------------------------------------------------------------- CBaseEntity::~CBaseEntity( ) { +#ifdef MAPBASE_VSCRIPT + // HACKHACK: This is needed to fix a crash when an entity removes itself with Destroy() during its own think function. + // (see https://github.com/mapbase-source/source-sdk-2013/issues/138) + FOR_EACH_VEC( m_ScriptThinkFuncs, i ) + { + HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink; + if ( h ) g_pScriptVM->ReleaseScript( h ); + } + m_ScriptThinkFuncs.PurgeAndDeleteElements(); +#endif // MAPBASE_VSCRIPT + // FIXME: This can't be called from UpdateOnRemove! There's at least one // case where friction sounds are added between the call to UpdateOnRemove + ~CBaseEntity PhysCleanupFrictionSounds( this ); @@ -493,14 +522,14 @@ void CBaseEntity::PostConstructor( const char *szClassname ) NetworkProp()->AttachEdict( g_pForceAttachEdict ); g_pForceAttachEdict = NULL; } - + // Some ents like the player override the AttachEdict function and do it at a different time. // While precaching, they don't ever have an edict, so we don't need to add them to // the entity list in that case. if ( edict() ) { gEntList.AddNetworkableEntity( this, entindex() ); - + // Cache our IServerNetworkable pointer for the engine for fast access. if ( edict() ) edict()->m_pNetworkable = NetworkProp(); @@ -543,7 +572,7 @@ static void AddDataMapFieldNamesToList( KeyValueNameList_t &list, datamap_t *pDa list.AddToTail( pField->externalName ); } } - + pDataMap = pDataMap->baseMap; } } @@ -632,11 +661,11 @@ void CBaseEntity::SetModelIndex( int index ) { sg_DynamicLoadHandlers.Remove( this ); } - + modelinfo->ReleaseDynamicModel( m_nModelIndex ); modelinfo->AddRefDynamicModel( index ); m_nModelIndex = index; - + m_bDynamicModelSetBounds = false; if ( IsDynamicModelIndex( index ) ) @@ -671,15 +700,15 @@ void CBaseEntity::SetModelIndexOverride( int index, int nValue ) if ( nValue != m_nModelIndexOverrides[index] ) { m_nModelIndexOverrides.Set( index, nValue ); - } + } } #endif } - + // position to shoot at -Vector CBaseEntity::BodyTarget( const Vector &posSrc, bool bNoisy) -{ - return WorldSpaceCenter( ); +Vector CBaseEntity::BodyTarget( const Vector &posSrc, bool bNoisy) +{ + return WorldSpaceCenter( ); } // return the position of my head. someone's trying to attack it. @@ -694,7 +723,7 @@ struct TimedOverlay_t char *msg; int msgEndTime; int msgStartTime; - TimedOverlay_t *pNextTimedOverlay; + TimedOverlay_t *pNextTimedOverlay; }; //----------------------------------------------------------------------------- @@ -760,7 +789,7 @@ void CBaseEntity::DrawAbsBoxOverlay() } void CBaseEntity::DrawRBoxOverlay() -{ +{ } @@ -817,7 +846,7 @@ void CBaseEntity::DrawTimedOverlays(void) Q_snprintf( tempstr, sizeof( tempstr ), "[%s]", GetDebugName() ); EntityText(0,tempstr, 0); } - + // Now draw overlays TimedOverlay_t* pTO = m_pTimedOverlay; TimedOverlay_t* pNextTO = NULL; @@ -846,7 +875,7 @@ void CBaseEntity::DrawTimedOverlays(void) else { int nAlpha = 0; - + // If messages aren't paused fade out if (!CBaseEntity::Debug_IsPaused()) { @@ -879,25 +908,25 @@ void CBaseEntity::DrawTimedOverlays(void) // Input : // Output : Current text offset from the top //----------------------------------------------------------------------------- -void CBaseEntity::DrawDebugGeometryOverlays(void) +void CBaseEntity::DrawDebugGeometryOverlays(void) { DrawTimedOverlays(); DrawDebugTextOverlays(); - if (m_debugOverlays & OVERLAY_NAME_BIT) - { + if (m_debugOverlays & OVERLAY_NAME_BIT) + { EntityText(0,GetDebugName(), 0); } - if (m_debugOverlays & OVERLAY_BBOX_BIT) - { + if (m_debugOverlays & OVERLAY_BBOX_BIT) + { DrawBBoxOverlay(); } if (m_debugOverlays & OVERLAY_ABSBOX_BIT ) { DrawAbsBoxOverlay(); } - if (m_debugOverlays & OVERLAY_PIVOT_BIT) - { + if (m_debugOverlays & OVERLAY_PIVOT_BIT) + { SendDebugPivotOverlay(); } if( m_debugOverlays & OVERLAY_RBOX_BIT ) @@ -955,7 +984,7 @@ void CBaseEntity::DrawDebugGeometryOverlays(void) if( ((int)gpGlobals->curtime) % 2 == 1 ) { - r = 255; + r = 255; g = 255; b = 255; @@ -997,10 +1026,10 @@ void CBaseEntity::DrawDebugGeometryOverlays(void) // Purpose: Draw any text overlays (override in subclass to add additional text) // Output : Current text offset from the top //----------------------------------------------------------------------------- -int CBaseEntity::DrawDebugTextOverlays(void) +int CBaseEntity::DrawDebugTextOverlays(void) { int offset = 1; - if (m_debugOverlays & OVERLAY_TEXT_BIT) + if (m_debugOverlays & OVERLAY_TEXT_BIT) { char tempstr[512]; Q_snprintf( tempstr, sizeof(tempstr), "(%d) Name: %s (%s)", entindex(), GetDebugName(), GetClassname() ); @@ -1032,10 +1061,46 @@ int CBaseEntity::DrawDebugTextOverlays(void) EntityText( offset,tempstr,0 ); offset++; } + +#ifdef MAPBASE + if (m_ResponseContexts.Count() > 0) + { + const char *contexts = UTIL_VarArgs("%s:%s", STRING(m_ResponseContexts[0].m_iszName), STRING(m_ResponseContexts[0].m_iszValue)); + for (int i = 1; i < GetContextCount(); i++) + { + contexts = UTIL_VarArgs("%s,%s:%s", contexts, STRING(m_ResponseContexts[i].m_iszName), STRING(m_ResponseContexts[i].m_iszValue)); + } + Q_snprintf(tempstr, sizeof(tempstr), "Response Contexts:%s", contexts); + EntityText(offset, tempstr, 0); + offset++; + } +#endif + +#ifdef MAPBASE_VSCRIPT + // 'OnEntText' hook inspired by later source games + if (m_ScriptScope.IsInitialized() && g_Hook_OnEntText.CanRunInScope( m_ScriptScope )) + { + if (ent_text_allow_script.GetBool()) + { + ScriptVariant_t functionReturn; + if ( g_Hook_OnEntText.Call( m_ScriptScope, &functionReturn, NULL ) && functionReturn.m_type == FIELD_CSTRING ) + { + CUtlStringList outStrings; + V_SplitString( functionReturn.m_pszString, "\n", outStrings ); + + FOR_EACH_VEC( outStrings, i ) + { + EntityText( offset, outStrings[i], 0, 224, 240, 255 ); + offset++; + } + } + } + } +#endif } if (m_debugOverlays & OVERLAY_VIEWOFFSET) - { + { NDebugOverlay::Cross3D( EyePosition(), 16, 255, 0, 0, true, 0.05f ); } @@ -1046,7 +1111,11 @@ int CBaseEntity::DrawDebugTextOverlays(void) void CBaseEntity::SetParent( string_t newParent, CBaseEntity *pActivator, int iAttachment ) { // find and notify the new parent +#ifdef MAPBASE + CBaseEntity *pParent = gEntList.FindEntityByName( NULL, newParent, this, pActivator ); +#else CBaseEntity *pParent = gEntList.FindEntityByName( NULL, newParent, NULL, pActivator ); +#endif // debug check if ( newParent != NULL_STRING && pParent == NULL ) @@ -1056,7 +1125,11 @@ void CBaseEntity::SetParent( string_t newParent, CBaseEntity *pActivator, int iA else { // make sure there isn't any ambiguity +#ifdef MAPBASE + if ( gEntList.FindEntityByName( pParent, newParent, this, pActivator ) ) +#else if ( gEntList.FindEntityByName( pParent, newParent, NULL, pActivator ) ) +#endif { Msg( "Entity %s(%s) has ambigious parent %s\n", STRING(m_iClassname), GetDebugName(), STRING(newParent) ); } @@ -1094,7 +1167,7 @@ void CBaseEntity::TransformStepData_ParentToParent( CBaseEntity *pOldParent, CBa // Convert our positions UTIL_ParentToWorldSpace( pOldParent, step->m_Previous2.vecOrigin, step->m_Previous2.qRotation ); UTIL_WorldToParentSpace( pNewParent, step->m_Previous2.vecOrigin, step->m_Previous2.qRotation ); - + UTIL_ParentToWorldSpace( pOldParent, step->m_Previous.vecOrigin, step->m_Previous.qRotation ); UTIL_WorldToParentSpace( pNewParent, step->m_Previous.vecOrigin, step->m_Previous.qRotation ); } @@ -1146,7 +1219,7 @@ void CBaseEntity::SetParent( CBaseEntity *pParentEntity, int iAttachment ) Assert(0); m_pParent = NULL; } - + if ( m_pParent == NULL ) { m_iParent = NULL_STRING; @@ -1186,7 +1259,7 @@ void CBaseEntity::SetParent( CBaseEntity *pParentEntity, int iAttachment ) matrix.InitFromEntity( const_cast(pParentEntity), m_iParentAttachment ); // parent->world childMatrix.InitFromEntityLocal( this ); // child->world Vector localOrigin = matrix.WorldToLocal( GetLocalOrigin() ); - + // I have the axes of local space in world space. (childMatrix) // I want to compute those world space axes in the parent's local space // and set that transform (as angles) on the child's object so the net @@ -1226,7 +1299,7 @@ void CBaseEntity::SetParent( CBaseEntity *pParentEntity, int iAttachment ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseEntity::ValidateEntityConnections() { @@ -1279,13 +1352,51 @@ void CBaseEntity::ValidateEntityConnections() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseEntity::FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay ) { if ( pszOutput == NULL ) return; + CBaseEntityOutput *pOutput = FindNamedOutput( pszOutput ); + if ( pOutput ) + { + pOutput->FireOutput( variant, pActivator, pCaller, flDelay ); + return; + } +} + +#ifdef MAPBASE_VSCRIPT +void CBaseEntity::ScriptFireOutput( const char *pszOutput, HSCRIPT hActivator, HSCRIPT hCaller, const char *szValue, float flDelay ) +{ + variant_t value; + value.SetString( MAKE_STRING(szValue) ); + + FireNamedOutput( pszOutput, value, ToEnt(hActivator), ToEnt(hCaller), flDelay ); +} + +float CBaseEntity::GetMaxOutputDelay( const char *pszOutput ) +{ + CBaseEntityOutput *pOutput = FindNamedOutput( pszOutput ); + if ( pOutput ) + { + return pOutput->GetMaxDelay(); + } + return 0; +} + +//void CBaseEntity::CancelEventsByInput( const char *szInput ) +//{ +// g_EventQueue.CancelEventsByInput( this, szInput ); +//} +#endif // MAPBASE_VSCRIPT + +CBaseEntityOutput *CBaseEntity::FindNamedOutput( const char *pszOutput ) +{ + if ( pszOutput == NULL ) + return NULL; + datamap_t *dmap = GetDataDescMap(); while ( dmap ) { @@ -1298,14 +1409,13 @@ void CBaseEntity::FireNamedOutput( const char *pszOutput, variant_t variant, CBa CBaseEntityOutput *pOutput = ( CBaseEntityOutput * )( ( int )this + ( int )dataDesc->fieldOffset[0] ); if ( !Q_stricmp( dataDesc->externalName, pszOutput ) ) { - pOutput->FireOutput( variant, pActivator, pCaller, flDelay ); - return; + return pOutput; } } } - dmap = dmap->baseMap; } + return NULL; } void CBaseEntity::Activate( void ) @@ -1326,7 +1436,7 @@ void CBaseEntity::Activate( void ) if (m_iInitialTeamNum) { ChangeTeam( m_iInitialTeamNum ); - } + } // Get a handle to my damage filter entity if there is one. if ( m_iszDamageFilterName != NULL_STRING ) @@ -1335,7 +1445,7 @@ void CBaseEntity::Activate( void ) } // Add any non-null context strings to our context vector - if ( m_iszResponseContext != NULL_STRING ) + if ( m_iszResponseContext != NULL_STRING ) { AddContext( m_iszResponseContext.ToCStr() ); } @@ -1348,7 +1458,7 @@ void CBaseEntity::Activate( void ) //////////////////////////// old CBaseEntity stuff /////////////////////////////////// -// give health. +// give health. // Returns the amount of health actually taken. int CBaseEntity::TakeHealth( float flHealth, int bitsDamageType ) { @@ -1392,7 +1502,7 @@ int CBaseEntity::OnTakeDamage( const CTakeDamageInfo &info ) // this global is still used for glass and other non-NPC killables, along with decals. g_vecAttackDir = vecTemp; VectorNormalize(g_vecAttackDir); - + // save damage based on the target's armor level // figure momentum add (don't let hurt brushes or other triggers move player) @@ -1406,7 +1516,7 @@ int CBaseEntity::OnTakeDamage( const CTakeDamageInfo &info ) } else { - if ( info.GetInflictor() && (GetMoveType() == MOVETYPE_WALK || GetMoveType() == MOVETYPE_STEP) && + if ( info.GetInflictor() && (GetMoveType() == MOVETYPE_WALK || GetMoveType() == MOVETYPE_STEP) && !info.GetAttacker()->IsSolidFlagSet(FSOLID_TRIGGER) ) { Vector vecDir, vecInflictorCentroid; @@ -1416,8 +1526,8 @@ int CBaseEntity::OnTakeDamage( const CTakeDamageInfo &info ) VectorNormalize( vecDir ); float flForce = info.GetDamage() * ((32 * 32 * 72.0) / (WorldAlignSize().x * WorldAlignSize().y * WorldAlignSize().z)) * 5; - - if (flForce > 1000.0) + + if (flForce > 1000.0) flForce = 1000.0; ApplyAbsVelocityImpulse( vecDir * flForce ); } @@ -1441,19 +1551,19 @@ int CBaseEntity::OnTakeDamage( const CTakeDamageInfo &info ) //----------------------------------------------------------------------------- // Purpose: Scale damage done and call OnTakeDamage //----------------------------------------------------------------------------- -int CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo ) +void CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo ) { if ( !g_pGameRules ) - return 0; + return; bool bHasPhysicsForceDamage = !g_pGameRules->Damage_NoPhysicsForce( inputInfo.GetDamageType() ); if ( bHasPhysicsForceDamage && inputInfo.GetDamageType() != DMG_GENERIC ) { // If you hit this assert, you've called TakeDamage with a damage type that requires a physics damage - // force & position without specifying one or both of them. Decide whether your damage that's causing - // this is something you believe should impart physics force on the receiver. If it is, you need to + // force & position without specifying one or both of them. Decide whether your damage that's causing + // this is something you believe should impart physics force on the receiver. If it is, you need to // setup the damage force & position inside the CTakeDamageInfo (Utility functions for this are in - // takedamageinfo.cpp. If you think the damage shouldn't cause force (unlikely!) then you can set the + // takedamageinfo.cpp. If you think the damage shouldn't cause force (unlikely!) then you can set the // damage type to DMG_GENERIC, or | DMG_CRUSH if you need to preserve the damage type for purposes of HUD display. if ( inputInfo.GetDamageForce() == vec3_origin || inputInfo.GetDamagePosition() == vec3_origin ) @@ -1473,17 +1583,27 @@ int CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo ) } } +#ifndef MAPBASE // Moved below the gamerules AllowDamage() check // Make sure our damage filter allows the damage. if ( !PassesDamageFilter( inputInfo )) { - return 0; + return; } +#endif if( !g_pGameRules->AllowDamage(this, inputInfo) ) { - return 0; + return; } +#ifdef MAPBASE + // Make sure our damage filter allows the damage. + if ( !PassesFinalDamageFilter( inputInfo )) + { + return; + } +#endif + if ( PhysIsInCallback() ) { PhysCallbackDamage( this, inputInfo ); @@ -1491,7 +1611,7 @@ int CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo ) else { CTakeDamageInfo info = inputInfo; - + // Scale the damage by the attacker's modifier. if ( info.GetAttacker() ) { @@ -1503,9 +1623,13 @@ int CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo ) //Msg("%s took %.2f Damage, at %.2f\n", GetClassname(), info.GetDamage(), gpGlobals->curtime ); - return OnTakeDamage( info ); +#ifdef MAPBASE + // Modify damage if we have a filter that does that + DamageFilterDamageMod(info); +#endif + + OnTakeDamage( info ); } - return 0; } //----------------------------------------------------------------------------- @@ -1558,10 +1682,10 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info ) Vector offset = info.GetDamagePosition(); // If you hit this assert, you've called TakeDamage with a damage type that requires a physics damage - // force & position without specifying one or both of them. Decide whether your damage that's causing - // this is something you believe should impart physics force on the receiver. If it is, you need to + // force & position without specifying one or both of them. Decide whether your damage that's causing + // this is something you believe should impart physics force on the receiver. If it is, you need to // setup the damage force & position inside the CTakeDamageInfo (Utility functions for this are in - // takedamageinfo.cpp. If you think the damage shouldn't cause force (unlikely!) then you can set the + // takedamageinfo.cpp. If you think the damage shouldn't cause force (unlikely!) then you can set the // damage type to DMG_GENERIC, or | DMG_CRUSH if you need to preserve the damage type for purposes of HUD display. #if !defined( TF_DLL ) Assert( force != vec3_origin && offset != vec3_origin ); @@ -1577,7 +1701,27 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info ) if ( gameFlags & FVPHYSICS_PLAYER_HELD ) { // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + CBasePlayer *pPlayer = NULL; + + if ( AI_IsSinglePlayer() ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && (tempPlayer->GetHeldObject() == this ) ) + { + pPlayer = tempPlayer; + break; + } + } + } + if ( pPlayer ) { float mass = pPlayer->GetHeldObjectMass( VPhysicsGetObject() ); @@ -1611,6 +1755,12 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info ) // Character killed (only fired once) void CBaseEntity::Event_Killed( const CTakeDamageInfo &info ) { +#ifdef MAPBASE_VSCRIPT + // False = Cheat death + if (ScriptDeathHook( const_cast(&info) ) == false) + return; +#endif + if( info.GetAttacker() ) { info.GetAttacker()->Event_KilledOther(this, info); @@ -1639,12 +1789,28 @@ void CBaseEntity::SendOnKilledGameEvent( const CTakeDamageInfo &info ) if ( info.GetInflictor()) { event->SetInt( "entindex_inflictor", info.GetInflictor()->entindex() ); - } + } event->SetInt( "damagebits", info.GetDamageType() ); gameeventmanager->FireEvent( event ); } } +void CBaseEntity::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) +{ +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_OnKilledOther.CanRunInScope( m_ScriptScope )) + { + HSCRIPT hInfo = g_pScriptVM->RegisterInstance( const_cast(&info) ); + + // victim, info + ScriptVariant_t args[] = { ScriptVariant_t( pVictim->GetScriptInstance() ), ScriptVariant_t( hInfo ) }; + g_Hook_OnKilledOther.Call( m_ScriptScope, NULL, args ); + + g_pScriptVM->RemoveInstance( hInfo ); + } +#endif +} + bool CBaseEntity::HasTarget( string_t targetname ) { @@ -1781,10 +1947,20 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_FIELD( m_flSimulationTime, FIELD_TIME ), DEFINE_FIELD( m_nLastThinkTick, FIELD_TICK ), + DEFINE_FIELD(m_iszScriptId, FIELD_STRING), + // m_ScriptScope; + // m_hScriptInstance; + + DEFINE_KEYFIELD(m_iszVScripts, FIELD_STRING, "vscripts"), + DEFINE_KEYFIELD(m_iszScriptThinkFunction, FIELD_STRING, "thinkfunction"), DEFINE_KEYFIELD( m_nNextThinkTick, FIELD_TICK, "nextthink" ), DEFINE_KEYFIELD( m_fEffects, FIELD_INTEGER, "effects" ), DEFINE_KEYFIELD( m_clrRender, FIELD_COLOR32, "rendercolor" ), DEFINE_GLOBAL_KEYFIELD( m_nModelIndex, FIELD_SHORT, "modelindex" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iViewHideFlags, FIELD_INTEGER, "viewhideflags" ), + DEFINE_KEYFIELD( m_bDisableFlashlight, FIELD_BOOLEAN, "disableflashlight" ), +#endif #if !defined( NO_ENTITY_PREDICTION ) // DEFINE_FIELD( m_PredictableID, CPredictableId ), #endif @@ -1810,7 +1986,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_KEYFIELD( m_iszDamageFilterName, FIELD_STRING, "damagefilter" ), DEFINE_FIELD( m_hDamageFilter, FIELD_EHANDLE ), - + DEFINE_FIELD( m_debugOverlays, FIELD_INTEGER ), DEFINE_GLOBAL_FIELD( m_pParent, FIELD_EHANDLE ), @@ -1818,7 +1994,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_GLOBAL_FIELD( m_hMoveParent, FIELD_EHANDLE ), DEFINE_GLOBAL_FIELD( m_hMoveChild, FIELD_EHANDLE ), DEFINE_GLOBAL_FIELD( m_hMovePeer, FIELD_EHANDLE ), - + DEFINE_FIELD( m_iEFlags, FIELD_INTEGER ), DEFINE_FIELD( m_iName, FIELD_STRING ), @@ -1827,7 +2003,11 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_FIELD( m_MoveType, FIELD_CHARACTER ), DEFINE_FIELD( m_MoveCollide, FIELD_CHARACTER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_hOwnerEntity, FIELD_EHANDLE, "OwnerEntity" ), +#else DEFINE_FIELD( m_hOwnerEntity, FIELD_EHANDLE ), +#endif DEFINE_FIELD( m_CollisionGroup, FIELD_INTEGER ), DEFINE_PHYSPTR( m_pPhysicsObject), DEFINE_FIELD( m_flElasticity, FIELD_FLOAT ), @@ -1842,7 +2022,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_FIELD( m_hGroundEntity, FIELD_EHANDLE ), DEFINE_FIELD( m_flGroundChangeTime, FIELD_TIME ), DEFINE_GLOBAL_KEYFIELD( m_ModelName, FIELD_MODELNAME, "model" ), - + DEFINE_KEYFIELD( m_vecBaseVelocity, FIELD_VECTOR, "basevelocity" ), DEFINE_FIELD( m_vecAbsVelocity, FIELD_VECTOR ), DEFINE_KEYFIELD( m_vecAngVelocity, FIELD_VECTOR, "avelocity" ), @@ -1878,7 +2058,12 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_KEYFIELD( m_vecViewOffset, FIELD_VECTOR, "view_ofs" ), +#ifdef MAPBASE + // You know, m_fFlags access + DEFINE_KEYFIELD( m_fFlags, FIELD_INTEGER, "m_fFlags" ), +#else DEFINE_FIELD( m_fFlags, FIELD_INTEGER ), +#endif #if !defined( NO_ENTITY_PREDICTION ) // DEFINE_FIELD( m_bIsPlayerSimulated, FIELD_INTEGER ), // DEFINE_FIELD( m_hPlayerSimulationOwner, FIELD_EHANDLE ), @@ -1927,17 +2112,108 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_INPUTFUNC( FIELD_VOID, "EnableShadow", InputEnableShadow ), DEFINE_INPUTFUNC( FIELD_STRING, "AddOutput", InputAddOutput ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "ChangeVariable", InputChangeVariable ), +#endif + +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INPUT, "PassUser1", InputPassUser1 ), + DEFINE_INPUTFUNC( FIELD_INPUT, "PassUser2", InputPassUser2 ), + DEFINE_INPUTFUNC( FIELD_INPUT, "PassUser3", InputPassUser3 ), + DEFINE_INPUTFUNC( FIELD_INPUT, "PassUser4", InputPassUser4 ), + DEFINE_INPUTFUNC( FIELD_VOID, "FireUser1", InputFireUser1 ), + DEFINE_INPUTFUNC( FIELD_VOID, "FireUser2", InputFireUser2 ), + DEFINE_INPUTFUNC( FIELD_VOID, "FireUser3", InputFireUser3 ), + DEFINE_INPUTFUNC( FIELD_VOID, "FireUser4", InputFireUser4 ), + + DEFINE_INPUTFUNC( FIELD_VOID, "FireRandomUser", InputFireRandomUser ), + DEFINE_INPUTFUNC( FIELD_INPUT, "PassRandomUser", InputPassRandomUser ), +#else DEFINE_INPUTFUNC( FIELD_STRING, "FireUser1", InputFireUser1 ), DEFINE_INPUTFUNC( FIELD_STRING, "FireUser2", InputFireUser2 ), DEFINE_INPUTFUNC( FIELD_STRING, "FireUser3", InputFireUser3 ), DEFINE_INPUTFUNC( FIELD_STRING, "FireUser4", InputFireUser4 ), +#endif + + DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptFile", InputRunScriptFile), + DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptCode", InputRunScript), + DEFINE_INPUTFUNC(FIELD_STRING, "CallScriptFunction", InputCallScriptFunction), +#ifdef MAPBASE_VSCRIPT + DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptCodeQuotable", InputRunScriptQuotable), + DEFINE_INPUTFUNC(FIELD_VOID, "ClearScriptScope", InputClearScriptScope), +#endif + +#ifdef MAPBASE + DEFINE_OUTPUT( m_OutUser1, "OutUser1" ), + DEFINE_OUTPUT( m_OutUser2, "OutUser2" ), + DEFINE_OUTPUT( m_OutUser3, "OutUser3" ), + DEFINE_OUTPUT( m_OutUser4, "OutUser4" ), +#endif DEFINE_OUTPUT( m_OnUser1, "OnUser1" ), DEFINE_OUTPUT( m_OnUser2, "OnUser2" ), DEFINE_OUTPUT( m_OnUser3, "OnUser3" ), DEFINE_OUTPUT( m_OnUser4, "OnUser4" ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetEntityName", InputSetEntityName ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget", InputSetTarget ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetOwnerEntity", InputSetOwnerEntity ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddHealth", InputAddHealth ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveHealth", InputRemoveHealth ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxHealth", InputSetMaxHealth ), + + DEFINE_INPUTFUNC( FIELD_STRING, "FireOutput", InputFireOutput ), + DEFINE_INPUTFUNC( FIELD_STRING, "RemoveOutput", InputRemoveOutput ), + //DEFINE_INPUTFUNC( FIELD_STRING, "CancelOutput", InputCancelOutput ), // Find a way to implement this + DEFINE_INPUTFUNC( FIELD_STRING, "ReplaceOutput", InputReplaceOutput ), + DEFINE_INPUTFUNC( FIELD_STRING, "AcceptInput", InputAcceptInput ), + DEFINE_INPUTFUNC( FIELD_VOID, "CancelPending", InputCancelPending ), + + DEFINE_INPUTFUNC( FIELD_VOID, "FreeChildren", InputFreeChildren ), + + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalOrigin", InputSetLocalOrigin ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalAngles", InputSetLocalAngles ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetAbsOrigin", InputSetAbsOrigin ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetAbsAngles", InputSetAbsAngles ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalVelocity", InputSetLocalVelocity ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalAngularVelocity", InputSetLocalAngularVelocity ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddSpawnFlags", InputAddSpawnFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveSpawnFlags", InputRemoveSpawnFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetRenderMode", InputSetRenderMode ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetRenderFX", InputSetRenderFX ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetViewHideFlags", InputSetViewHideFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddEffects", InputAddEffects ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveEffects", InputRemoveEffects ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableDraw", InputDrawEntity ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableDraw", InputUndrawEntity ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableReceivingFlashlight", InputEnableReceivingFlashlight ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableReceivingFlashlight", InputDisableReceivingFlashlight ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddEFlags", InputAddEFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveEFlags", InputRemoveEFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddSolidFlags", InputAddSolidFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveSolidFlags", InputRemoveSolidFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMoveType", InputSetMoveType ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCollisionGroup", InputSetCollisionGroup ), + + DEFINE_INPUTFUNC( FIELD_EHANDLE, "Touch", InputTouch ), + + DEFINE_INPUTFUNC( FIELD_INPUT, "KilledNPC", InputKilledNPC ), + + DEFINE_INPUTFUNC( FIELD_VOID, "KillIfNotVisible", InputKillIfNotVisible ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "KillWhenNotVisible", InputKillWhenNotVisible ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetThinkNull", InputSetThinkNull ), + + DEFINE_OUTPUT( m_OnKilled, "OnKilled" ), +#endif + // Function Pointers DEFINE_FUNCTION( SUB_Remove ), DEFINE_FUNCTION( SUB_DoNothing ), @@ -1947,6 +2223,14 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_FUNCTION( SUB_Vanish ), DEFINE_FUNCTION( SUB_CallUseToggle ), DEFINE_THINKFUNC( ShadowCastDistThink ), + DEFINE_THINKFUNC( ScriptThink ), +#ifdef MAPBASE_VSCRIPT + DEFINE_THINKFUNC( ScriptContextThink ), +#endif + +#ifdef MAPBASE + DEFINE_FUNCTION( SUB_RemoveWhenNotVisible ), +#endif DEFINE_FIELD( m_hEffectEntity, FIELD_EHANDLE ), @@ -1959,6 +2243,306 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) END_DATADESC() + +#ifdef MAPBASE_VSCRIPT +ScriptHook_t CBaseEntity::g_Hook_UpdateOnRemove; +ScriptHook_t CBaseEntity::g_Hook_OnEntText; + +ScriptHook_t CBaseEntity::g_Hook_VPhysicsCollision; +ScriptHook_t CBaseEntity::g_Hook_FireBullets; +ScriptHook_t CBaseEntity::g_Hook_OnDeath; +ScriptHook_t CBaseEntity::g_Hook_OnKilledOther; +ScriptHook_t CBaseEntity::g_Hook_HandleInteraction; +ScriptHook_t CBaseEntity::g_Hook_ModifyEmitSoundParams; +ScriptHook_t CBaseEntity::g_Hook_ModifySentenceParams; +#endif + +BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" ) + DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper ) + DEFINE_SCRIPTFUNC_NAMED( ConnectOutputToScript, "ConnectOutput", "Adds an I/O connection that will call the named function when the specified output fires" ) + DEFINE_SCRIPTFUNC_NAMED( DisconnectOutputFromScript, "DisconnectOutput", "Removes a connected script function from an I/O event." ) + + DEFINE_SCRIPTFUNC( GetHealth, "" ) + DEFINE_SCRIPTFUNC( SetHealth, "" ) + DEFINE_SCRIPTFUNC( GetMaxHealth, "" ) + DEFINE_SCRIPTFUNC( SetMaxHealth, "" ) + + DEFINE_SCRIPTFUNC( SetModel, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." ) + DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname.") + + + DEFINE_SCRIPTFUNC( GetClassname, "" ) + DEFINE_SCRIPTFUNC_NAMED( GetEntityNameAsCStr, "GetName", "" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( GetDebugName, "If name exists returns name, otherwise returns classname" ) + DEFINE_SCRIPTFUNC_NAMED( SetNameAsCStr, "SetName", "" ) +#endif + DEFINE_SCRIPTFUNC( GetPreTemplateName, "Get the entity name stripped of template unique decoration" ) + + DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" ) + DEFINE_SCRIPTFUNC( SetAbsOrigin, "SetAbsOrigin" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( SetAbsAngles, "SetAbsAngles" ) + + DEFINE_SCRIPTFUNC( GetLocalOrigin, "GetLocalOrigin" ) + DEFINE_SCRIPTFUNC( SetLocalOrigin, "SetLocalOrigin" ) + DEFINE_SCRIPTFUNC( GetLocalAngles, "GetLocalAngles" ) + DEFINE_SCRIPTFUNC( SetLocalAngles, "SetLocalAngles" ) +#endif + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetOrigin, "SetOrigin", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetForward, "SetForwardVector", "Set the orientation of the entity to have this forward vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRight, "GetRightVector", "Get the right vector of the entity" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeft, "GetLeftVector", SCRIPT_HIDE ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetUp, "GetUpVector", "Get the up vector of the entity" ) + +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptSetOriginAngles, "SetOriginAngles", "Set both the origin and the angles" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetOriginAnglesVelocity, "SetOriginAnglesVelocity", "Set the origin, the angles, and the velocity" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysicsObject, "GetPhysicsObject", "Get the entity's physics object if it has one" ) + + DEFINE_SCRIPTFUNC( ApplyAbsVelocityImpulse, "" ) + DEFINE_SCRIPTFUNC( ApplyLocalAngularVelocityImpulse, "" ) + + DEFINE_SCRIPTFUNC( BodyTarget, "" ) + DEFINE_SCRIPTFUNC( HeadTarget, "" ) +#endif + + DEFINE_SCRIPTFUNC_NAMED( GetAbsVelocity, "GetVelocity", "" ) + DEFINE_SCRIPTFUNC_NAMED( SetAbsVelocity, "SetVelocity", "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetLocalAngularVelocity, "SetAngularVelocity", "Set the local angular velocity - takes float pitch,yaw,roll velocities" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetLocalAngularVelocity, "GetAngularVelocity", "Get the local angular velocity - returns a vector of pitch,yaw,roll" ) + + DEFINE_SCRIPTFUNC_NAMED( WorldSpaceCenter, "GetCenter", "Get vector to center of object - absolute coords") + DEFINE_SCRIPTFUNC_NAMED( ScriptEyePosition, "EyePosition", "Get vector to eye position - absolute coords") +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptEyeAngles, "EyeAngles", "Get eye pitch, yaw, roll as a vector" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAngles, "SetAngles", "Set entity pitch, yaw, roll") + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector") + + DEFINE_SCRIPTFUNC( SetSize, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object") + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object") + + DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetOwner, "SetOwner", "" ) + DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeam", "" ) + DEFINE_SCRIPTFUNC_NAMED( ChangeTeam, "SetTeam", "" ) + +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptSetParent, "SetParent", "" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveParent, "GetMoveParent", "If in hierarchy, retrieves the entity's parent" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRootMoveParent, "GetRootMoveParent", "If in hierarchy, walks up the hierarchy to find the root parent" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFirstMoveChild, "FirstMoveChild", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptNextMovePeer, "NextMovePeer", "" ) + + DEFINE_SCRIPTFUNC_NAMED( KeyValueFromString, "__KeyValueFromString", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( KeyValueFromFloat, "__KeyValueFromFloat", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( KeyValueFromInt, "__KeyValueFromInt", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( KeyValueFromVector, "__KeyValueFromVector", SCRIPT_HIDE ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelKeyValues, "GetModelKeyValues", "Get a KeyValue class instance on this entity's model") + +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( Activate, "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisible, "IsVisible", "Check if the specified position can be visible to this entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsEntVisible, "IsEntVisible", "Check if the specified entity can be visible to this entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisibleWithMask, "IsVisibleWithMask", "Check if the specified position can be visible to this entity with a specific trace mask." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptTakeDamage, "TakeDamage", "Apply damage to this entity with a given info handle" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFireBullets, "FireBullets", "Fire bullets from entity with a given info handle" ) + + DEFINE_SCRIPTFUNC( TakeHealth, "Give this entity health" ) + DEFINE_SCRIPTFUNC( IsAlive, "Return true if this entity is alive" ) + + DEFINE_SCRIPTFUNC( GetWaterLevel, "Get current level of water submergence" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetContext, "GetContext", "Get a response context value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddContext, "AddContext", "Add a response context value" ) + DEFINE_SCRIPTFUNC( GetContextExpireTime, "Get a response context's expiration time" ) + DEFINE_SCRIPTFUNC( GetContextCount, "Get the number of response contexts" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetContextIndex, "GetContextIndex", "Get a response context at a specific index in the form of a table" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptFollowEntity, "FollowEntity", "Begin following the specified entity. This makes this entity non-solid, parents it to the target entity, and teleports it to the specified entity's origin. The second parameter is whether or not to use bonemerging while following." ) + DEFINE_SCRIPTFUNC( StopFollowingEntity, "Stops following an entity if we're following one." ) + DEFINE_SCRIPTFUNC( IsFollowingEntity, "Returns true if this entity is following another entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFollowedEntity, "GetFollowedEntity", "Get the entity we're following." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptClassify, "Classify", "Get Class_T class ID (corresponds to the CLASS_ set of constants)" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAcceptInput, "AcceptInput", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFireOutput, "FireOutput", "Fire an entity output" ) + DEFINE_SCRIPTFUNC( GetMaxOutputDelay, "Get the longest delay for all events attached to an output" ) + //DEFINE_SCRIPTFUNC( CancelEventsByInput, "Cancel all I/O events for this entity, match input" ) // Commented out due to unpredictability and unknown risks + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddOutput, "AddOutput", "Add an output" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValue, "GetKeyValue", "Get a keyvalue" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorVector, "GetRenderColorVector", "Get the render color as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorR, "GetRenderColorR", "Get the render color's R value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorG, "GetRenderColorG", "Get the render color's G value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorB, "GetRenderColorB", "Get the render color's B value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAlpha, "GetRenderAlpha", "Get the render color's alpha value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorVector, "SetRenderColorVector", "Set the render color as a vector" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColor, "SetRenderColor", "Set the render color" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorR, "SetRenderColorR", "Set the render color's R value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorG, "SetRenderColorG", "Set the render color's G value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorB, "SetRenderColorB", "Set the render color's B value" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAlpha, "SetRenderAlpha", "Set the render color's alpha value" ) + + // LEGACY + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorVector, "GetColorVector", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorR, "GetColorR", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorG, "GetColorG", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorB, "GetColorB", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAlpha, "GetAlpha", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorVector, "SetColorVector", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorR, "SetColorR", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorG, "SetColorG", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorB, "SetColorB", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAlpha, "SetAlpha", SCRIPT_HIDE ) + // END LEGACY + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRenderMode, "GetRenderMode", "Get render mode" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetRenderMode, "SetRenderMode", "Set render mode" ) + + DEFINE_SCRIPTFUNC( GetSpawnFlags, "Get spawnflags" ) + DEFINE_SCRIPTFUNC( AddSpawnFlags, "Add spawnflag(s)" ) + DEFINE_SCRIPTFUNC( RemoveSpawnFlags, "Remove spawnflag(s)" ) + DEFINE_SCRIPTFUNC( ClearSpawnFlags, "Clear spawnflag(s)" ) + DEFINE_SCRIPTFUNC( HasSpawnFlags, "Check if the entity has specific spawnflag(s) ticked" ) + + DEFINE_SCRIPTFUNC( GetEffects, "Get effects" ) + DEFINE_SCRIPTFUNC( AddEffects, "Add effect(s)" ) + DEFINE_SCRIPTFUNC( RemoveEffects, "Remove effect(s)" ) + DEFINE_SCRIPTFUNC( ClearEffects, "Clear effect(s)" ) + DEFINE_SCRIPTFUNC( SetEffects, "Set effect(s)" ) + DEFINE_SCRIPTFUNC( IsEffectActive, "Check if an effect is active" ) + + DEFINE_SCRIPTFUNC( GetFlags, "Get flags" ) + DEFINE_SCRIPTFUNC( AddFlag, "Add flag" ) + DEFINE_SCRIPTFUNC( RemoveFlag, "Remove flag" ) + + DEFINE_SCRIPTFUNC( GetEFlags, "Get Eflags" ) + DEFINE_SCRIPTFUNC( AddEFlags, "Add Eflags" ) + DEFINE_SCRIPTFUNC( RemoveEFlags, "Remove Eflags" ) + + DEFINE_SCRIPTFUNC( GetTransmitState, "" ) + DEFINE_SCRIPTFUNC( SetTransmitState, "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveType, "GetMoveType", "Get the move type" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetMoveType, "SetMoveType", "Set the move type" ) + + DEFINE_SCRIPTFUNC( GetCollisionGroup, "Get the collision group" ) + DEFINE_SCRIPTFUNC( SetCollisionGroup, "Set the collision group" ) + + DEFINE_SCRIPTFUNC( GetGravity, "" ) + DEFINE_SCRIPTFUNC( SetGravity, "" ) + DEFINE_SCRIPTFUNC( GetFriction, "" ) + DEFINE_SCRIPTFUNC( SetFriction, "" ) + DEFINE_SCRIPTFUNC( GetMass, "" ) + DEFINE_SCRIPTFUNC( SetMass, "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSolid, "GetSolid", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetSolid, "SetSolid", "" ) + + DEFINE_SCRIPTFUNC( GetSolidFlags, "Get solid flags" ) + DEFINE_SCRIPTFUNC( AddSolidFlags, "Add solid flags" ) + DEFINE_SCRIPTFUNC( RemoveSolidFlags, "Remove solid flags" ) + + DEFINE_SCRIPTFUNC( IsPlayer, "Returns true if this entity is a player." ) + DEFINE_SCRIPTFUNC( IsNPC, "Returns true if this entity is a NPC." ) + DEFINE_SCRIPTFUNC( IsCombatCharacter, "Returns true if this entity is a combat character (player or NPC)." ) + DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." ) + DEFINE_SCRIPTFUNC( IsWorld, "Returns true if this entity is the world." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptDispatchInteraction, "DispatchInteraction", "Dispatches an interaction on this entity. See the g_interaction set of constants for more information." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTakeDamage, "GetTakeDamage", "Gets this entity's m_takedamage value. (DAMAGE_YES, DAMAGE_NO, etc.)" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetTakeDamage, "SetTakeDamage", "Sets this entity's m_takedamage value. (DAMAGE_YES, DAMAGE_NO, etc.)" ) + + // DEFINE_SCRIPTFUNC( IsMarkedForDeletion, "Returns true if the entity is valid and marked for deletion." ) +#endif + + DEFINE_SCRIPTFUNC( ValidateScriptScope, "Ensure that an entity's script scope has been created" ) + DEFINE_SCRIPTFUNC( GetScriptScope, "Retrieve the script-side data associated with an entity" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( GetOrCreatePrivateScriptScope, "Create and retrieve the script-side data associated with an entity" ) +#endif + DEFINE_SCRIPTFUNC( GetScriptId, "Retrieve the unique identifier used to refer to the entity within the scripting system" ) + DEFINE_SCRIPTFUNC_NAMED( GetScriptOwnerEntity, "GetOwner", "Gets this entity's owner" ) + DEFINE_SCRIPTFUNC_NAMED( SetScriptOwnerEntity, "SetOwner", "Sets this entity's owner" ) + DEFINE_SCRIPTFUNC( entindex, "" ) + +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptSetThinkFunction, "SetThinkFunction", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptStopThinkFunction, "StopThinkFunction", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetThink, "SetThink", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptStopThink, "StopThink", "" ) + + // + // Hooks + // + DEFINE_SIMPLE_SCRIPTHOOK( CBaseEntity::g_Hook_UpdateOnRemove, "UpdateOnRemove", FIELD_VOID, "Called when the entity is being removed." ) + DEFINE_SIMPLE_SCRIPTHOOK( CBaseEntity::g_Hook_OnEntText, "OnEntText", FIELD_CSTRING, "Called every frame when ent_text is enabled on the entity. Return a string to be added to the ent_text printout." ) + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_VPhysicsCollision, "VPhysicsCollision", FIELD_VOID, "Called for every single VPhysics-related collision experienced by this entity." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "speed", FIELD_FLOAT ) + DEFINE_SCRIPTHOOK_PARAM( "point", FIELD_VECTOR ) + DEFINE_SCRIPTHOOK_PARAM( "normal", FIELD_VECTOR ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_FireBullets, "FireBullets", FIELD_VOID, "Called for every single VPhysics-related collision experienced by this entity." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "speed", FIELD_FLOAT ) + DEFINE_SCRIPTHOOK_PARAM( "point", FIELD_VECTOR ) + DEFINE_SCRIPTHOOK_PARAM( "normal", FIELD_VECTOR ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_OnDeath, "OnDeath", FIELD_BOOLEAN, "Called when the entity dies (Event_Killed). Returning false makes the entity cancel death, although this could have unforeseen consequences. For hooking any damage instead of just death, see filter_script and PassesFinalDamageFilter." ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_OnKilledOther, "OnKilledOther", FIELD_VOID, "Called when the entity kills another entity." ) + DEFINE_SCRIPTHOOK_PARAM( "victim", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_HandleInteraction, "HandleInteraction", FIELD_BOOLEAN, "Called for internal game interactions. See the g_interaction set of constants for more information. Returning true or false will return that value without falling to any internal handling. Returning nothing will allow the interaction to fall to any internal handling." ) + DEFINE_SCRIPTHOOK_PARAM( "interaction", FIELD_INTEGER ) + //DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT ) + DEFINE_SCRIPTHOOK_PARAM( "sourceEnt", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_ModifyEmitSoundParams, "ModifyEmitSoundParams", FIELD_VOID, "Called every time a sound is emitted on this entity, allowing for its parameters to be modified." ) + DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_ModifySentenceParams, "ModifySentenceParams", FIELD_VOID, "Called every time a sentence is emitted on this entity, allowing for its parameters to be modified." ) + DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT ) + END_SCRIPTHOOK() +#endif +END_SCRIPTDESC(); + + // For code error checking extern bool g_bReceivedChainedUpdateOnRemove; @@ -1973,9 +2557,9 @@ extern bool g_bReceivedChainedUpdateOnRemove; // destructed (especially since the entity list order is more or less random!). // NOTE: You should never call delete directly on an entity (there's an assert now), see note // at CBaseEntity::~CBaseEntity for more information. -// +// // NOTE: You should chain to BaseClass::UpdateOnRemove after doing your own cleanup code, e.g.: -// +// // void CDerived::UpdateOnRemove( void ) // { // ... cleanup code @@ -2052,18 +2636,31 @@ void CBaseEntity::UpdateOnRemove( void ) { sg_DynamicLoadHandlers.Remove( this ); } - + if ( IsDynamicModelIndex( m_nModelIndex ) ) { modelinfo->ReleaseDynamicModel( m_nModelIndex ); // no-op if not dynamic m_nModelIndex = -1; } + + if ( m_hScriptInstance ) + { +#ifdef MAPBASE_VSCRIPT + if ( m_ScriptScope.IsInitialized() && g_Hook_UpdateOnRemove.CanRunInScope( m_ScriptScope ) ) + { + g_Hook_UpdateOnRemove.Call( m_ScriptScope, NULL, NULL ); + } +#endif // MAPBASE_VSCRIPT + + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + m_hScriptInstance = NULL; + } } //----------------------------------------------------------------------------- // capabilities //----------------------------------------------------------------------------- -int CBaseEntity::ObjectCaps( void ) +int CBaseEntity::ObjectCaps( void ) { #if 1 model_t *pModel = GetModel(); @@ -2086,7 +2683,7 @@ int CBaseEntity::ObjectCaps( void ) return caps; } - else if ( !bIsBrush ) + else if ( !bIsBrush ) { return FCAP_ACROSS_TRANSITION; } @@ -2100,7 +2697,7 @@ int CBaseEntity::ObjectCaps( void ) { parentCaps = GetParent()->ObjectCaps(); parentCaps &= ( FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE | FCAP_DIRECTIONAL_USE ); - } + } model_t *pModel = GetModel(); if ( pModel && modelinfo->GetModelType( pModel ) == mod_brush ) @@ -2118,8 +2715,8 @@ void CBaseEntity::StartTouch( CBaseEntity *pOther ) } void CBaseEntity::Touch( CBaseEntity *pOther ) -{ - if ( m_pfnTouch ) +{ + if ( m_pfnTouch ) (this->*m_pfnTouch)( pOther ); // notify parent of touch @@ -2142,7 +2739,7 @@ void CBaseEntity::EndTouch( CBaseEntity *pOther ) // Input : pOther - The entity that is blocking us. //----------------------------------------------------------------------------- void CBaseEntity::Blocked( CBaseEntity *pOther ) -{ +{ if ( m_pfnBlocked ) { (this->*m_pfnBlocked)( pOther ); @@ -2160,14 +2757,14 @@ void CBaseEntity::Blocked( CBaseEntity *pOther ) //----------------------------------------------------------------------------- // Purpose: Dispatches use events to this entity's use handler, set via SetUse. -// Input : pActivator - -// pCaller - -// useType - -// value - +// Input : pActivator - +// pCaller - +// useType - +// value - //----------------------------------------------------------------------------- -void CBaseEntity::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +void CBaseEntity::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( m_pfnUse != NULL ) + if ( m_pfnUse != NULL ) { (this->*m_pfnUse)( pActivator, pCaller, useType, value ); } @@ -2438,7 +3035,7 @@ void CBaseEntity::VPhysicsUpdatePusher( IPhysicsObject *pPhysics ) QAngle angles; // physics updated the shadow, so check to see if I got blocked - // NOTE: SOLID_BSP cannont compute consistent collisions wrt vphysics, so + // NOTE: SOLID_BSP cannont compute consistent collisions wrt vphysics, so // don't allow vphysics to block. Assume game physics has handled it. if ( GetSolid() != SOLID_BSP && pPhysics->GetShadowPosition( &origin, &angles ) ) { @@ -2606,14 +3203,14 @@ void CBaseEntity::PhysicsTouchTriggers( const Vector *pPrevAbsOrigin ) { Assert(CollisionProp()); bool isTriggerCheckSolids = IsSolidFlagSet( FSOLID_TRIGGER ); - bool isSolidCheckTriggers = IsSolid() && !isTriggerCheckSolids; // NOTE: Moving triggers (items, ammo etc) are not + bool isSolidCheckTriggers = IsSolid() && !isTriggerCheckSolids; // NOTE: Moving triggers (items, ammo etc) are not // checked against other triggers to reduce the number of touchlinks created if ( !(isSolidCheckTriggers || isTriggerCheckSolids) ) return; - if ( GetSolid() == SOLID_BSP ) + if ( GetSolid() == SOLID_BSP ) { - if ( !GetModel() && Q_strlen( STRING( GetModelName() ) ) == 0 ) + if ( !GetModel() && Q_strlen( STRING( GetModelName() ) ) == 0 ) { Warning( "Inserted %s with no model\n", GetClassname() ); return; @@ -2646,6 +3243,21 @@ void CBaseEntity::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) int otherIndex = !index; CBaseEntity *pHitEntity = pEvent->pEntities[otherIndex]; +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_VPhysicsCollision.CanRunInScope(m_ScriptScope)) + { + Vector vecContactPoint; + pEvent->pInternalData->GetContactPoint( vecContactPoint ); + + Vector vecSurfaceNormal; + pEvent->pInternalData->GetSurfaceNormal( vecSurfaceNormal ); + + // entity, speed, point, normal + ScriptVariant_t args[] = { ScriptVariant_t( pHitEntity->GetScriptInstance() ), pEvent->collisionSpeed, vecContactPoint, vecSurfaceNormal }; + g_Hook_VPhysicsCollision.Call( m_ScriptScope, NULL, args ); + } +#endif + // Don't make sounds / effects if neither entity is MOVETYPE_VPHYSICS. The game // physics should have done so. if ( GetMoveType() != MOVETYPE_VPHYSICS && pHitEntity->GetMoveType() != MOVETYPE_VPHYSICS ) @@ -2760,7 +3372,7 @@ bool CBaseEntity::Intersects( CBaseEntity *pOther ) CCollisionProperty *pMyProp = CollisionProp(); CCollisionProperty *pOtherProp = pOther->CollisionProp(); - return IsOBBIntersectingOBB( + return IsOBBIntersectingOBB( pMyProp->GetCollisionOrigin(), pMyProp->GetCollisionAngles(), pMyProp->OBBMins(), pMyProp->OBBMaxs(), pOtherProp->GetCollisionOrigin(), pOtherProp->GetCollisionAngles(), pOtherProp->OBBMins(), pOtherProp->OBBMaxs() ); } @@ -2781,7 +3393,7 @@ bool CBaseEntity::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity **p #if HL1_DLL // FIXME: only block LOS through opaque water // don't look through water - if ((m_nWaterLevel != 3 && pEntity->m_nWaterLevel == 3) + if ((m_nWaterLevel != 3 && pEntity->m_nWaterLevel == 3) || (m_nWaterLevel == 3 && pEntity->m_nWaterLevel == 0)) return false; #endif @@ -2812,7 +3424,7 @@ bool CBaseEntity::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity **p CTraceFilterLOS traceFilter( this, COLLISION_GROUP_NONE, pEntity ); UTIL_TraceLine( vecLookerOrigin, vecTargetOrigin, traceMask, &traceFilter, &tr ); } - + if (tr.fraction != 1.0 || tr.startsolid ) { // If we hit the entity we're looking for, it's visible @@ -2845,7 +3457,7 @@ bool CBaseEntity::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity **p bool CBaseEntity::FVisible( const Vector &vecTarget, int traceMask, CBaseEntity **ppBlocker ) { #if HL1_DLL - + // don't look through water // FIXME: only block LOS through opaque water bool inWater = ( UTIL_PointContents( vecTarget ) & (CONTENTS_SLIME|CONTENTS_WATER) ) ? true : false; @@ -2854,7 +3466,7 @@ bool CBaseEntity::FVisible( const Vector &vecTarget, int traceMask, CBaseEntity if ( ( m_nWaterLevel == 3 && !inWater ) || ( m_nWaterLevel != 3 && inWater ) ) return false; -#endif +#endif trace_t tr; Vector vecLookerOrigin = EyePosition();// look through the caller's 'eyes' @@ -2922,7 +3534,7 @@ ConVar ai_debug_los("ai_debug_los", "0", FCVAR_CHEAT, "NPC Line-Of-Sight debug m Class_T CBaseEntity::Classify ( void ) -{ +{ return CLASS_NONE; } @@ -2967,14 +3579,80 @@ bool CBaseEntity::PassesDamageFilter( const CTakeDamageInfo &info ) if (m_hDamageFilter) { CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); +#ifdef MAPBASE + return pFilter->PassesDamageFilter(this, info); +#else return pFilter->PassesDamageFilter(info); +#endif + } + + return true; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: A damage filter pass for when this is most certainly the part where we might actually take damage. +// Made for the "damage" family of filters, including filter_damage_transfer. +//----------------------------------------------------------------------------- +bool CBaseEntity::PassesFinalDamageFilter( const CTakeDamageInfo &info ) +{ + if (!PassesDamageFilter(info)) + return false; + + if (m_hDamageFilter) + { + CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); + if (!pFilter->PassesFinalDamageFilter(this, info)) + { + return false; + } + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: A hack for damage transfers. +//----------------------------------------------------------------------------- +bool CBaseEntity::DamageFilterAllowsBlood( const CTakeDamageInfo &info ) +{ + if (m_hDamageFilter) + { + CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); + if (!pFilter->BloodAllowed(this, info)) + { + return false; + } } return true; } +//----------------------------------------------------------------------------- +// Purpose: Modifies damage taken. Returns true if damage was successfully modded. +//----------------------------------------------------------------------------- +bool CBaseEntity::DamageFilterDamageMod( CTakeDamageInfo &info ) +{ + if (m_hDamageFilter) + { + CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); + if (pFilter->DamageMod(this, info)) + { + return true; + } + } + + return false; +} +#endif + FORCEINLINE bool NamesMatch( const char *pszQuery, string_t nameToMatch ) { +#ifdef MAPBASE + // NamesMatch has been turned into Matcher_NamesMatch in matchers.h + // for a wider range of accessibility and flexibility. + return Matcher_NamesMatch(pszQuery, STRING(nameToMatch)); +#else if ( nameToMatch == NULL_STRING ) return (!pszQuery || *pszQuery == 0 || *pszQuery == '*'); @@ -3009,6 +3687,7 @@ FORCEINLINE bool NamesMatch( const char *pszQuery, string_t nameToMatch ) return true; return false; +#endif } bool CBaseEntity::NameMatchesComplex( const char *pszNameOrWildcard ) @@ -3035,7 +3714,7 @@ void CBaseEntity::MakeDormant( void ) return; SETBITS( m_iEFlags, EFL_DORMANT ); - + // Don't touch AddSolidFlags( FSOLID_NOT_SOLID ); // Don't move @@ -3053,11 +3732,11 @@ int CBaseEntity::IsDormant( void ) bool CBaseEntity::IsInWorld( void ) const -{ +{ if ( !edict() ) return true; - // position + // position if (GetAbsOrigin().x >= MAX_COORD_INTEGER) return false; if (GetAbsOrigin().y >= MAX_COORD_INTEGER) return false; if (GetAbsOrigin().z >= MAX_COORD_INTEGER) return false; @@ -3198,7 +3877,7 @@ int CBaseEntity::Restore( IRestore &restore ) // so update with the worldspace leveltransition transform parentSpaceOffset += pGameInfo->GetLandmark(); } - + // NOTE: Do *not* use GetAbsOrigin() here because it will // try to recompute m_rgflCoordinateFrame! MatrixSetColumn( m_vecAbsOrigin, 3, m_rgflCoordinateFrame ); @@ -3248,6 +3927,7 @@ void CBaseEntity::OnSave( IEntitySaveUtils *pUtils ) //----------------------------------------------------------------------------- void CBaseEntity::OnRestore() { +#ifndef MAPBASE // It's your fault if you're trying to load old, broken saves from a possibly closed 2013 beta in Mapbase. #if defined( PORTAL ) || defined( HL2_EPISODIC ) || defined ( HL2_DLL ) || defined( HL2_LOSTCOAST ) // We had a short period during the 2013 beta where the FL_* flags had a bogus value near the top, so detect // these bad saves and just give up. Only saves from the short beta period should have been effected. @@ -3256,9 +3936,10 @@ void CBaseEntity::OnRestore() char szMsg[256]; V_snprintf( szMsg, sizeof(szMsg), "\nInvalid save, unable to load. Please run \"map %s\" to restart this level manually\n\n", gpGlobals->mapname.ToCStr() ); Msg( "%s", szMsg ); - + engine->ServerCommand("wait;wait;disconnect;showconsole\n"); } +#endif #endif SimThink_EntityChanged( this ); @@ -3364,7 +4045,7 @@ void CBaseEntity::operator delete( void *pMem ) #ifdef _DEBUG void CBaseEntity::FunctionCheck( void *pFunction, const char *name ) -{ +{ #ifdef USES_SAVERESTORE // Note, if you crash here and your class is using multiple inheritance, it is // probably the case that CBaseEntity (or a descendant) is not the first @@ -3417,7 +4098,7 @@ void CBaseEntity::SetMoveType( MoveType_t val, MoveCollide_t moveCollide ) if ( VPhysicsGetObject() && val != MOVETYPE_NONE ) { // What am I supposed to do with the physics object if - // you're changing away from MOVETYPE_VPHYSICS without making the object + // you're changing away from MOVETYPE_VPHYSICS without making the object // shadow? This isn't likely to work, assert. // You probably meant to call VPhysicsInitShadow() instead of VPhysicsInitNormal()! Assert( VPhysicsGetObject()->GetShadowController() ); @@ -3474,7 +4155,7 @@ void CBaseEntity::SetMoveType( MoveType_t val, MoveCollide_t moveCollide ) CheckHasGamePhysicsSimulation(); } -void CBaseEntity::Spawn( void ) +void CBaseEntity::Spawn( void ) { } @@ -3502,11 +4183,11 @@ int CBaseEntity::SetTransmitState( int nFlag) return 0; // clear current flags = check ShouldTransmit() - ed->ClearTransmitState(); - + ed->ClearTransmitState(); + int oldFlags = ed->m_fStateFlags; ed->m_fStateFlags |= nFlag; - + // Tell the engine (used for a network backdoor optimization). if ( (oldFlags & FL_EDICT_DONTSEND) != (ed->m_fStateFlags & FL_EDICT_DONTSEND) ) engine->NotifyEdictFlagsChange( entindex() ); @@ -3519,10 +4200,10 @@ int CBaseEntity::UpdateTransmitState() // If you get this assert, you should be calling DispatchUpdateTransmitState // instead of UpdateTransmitState. Assert( g_nInsideDispatchUpdateTransmitState > 0 ); - + // If an object is the moveparent of something else, don't skip it just because it's marked EF_NODRAW or else // the client won't have a proper origin for the child since the hierarchy won't be correctly transmitted down - if ( IsEffectActive( EF_NODRAW ) && + if ( IsEffectActive( EF_NODRAW ) && !m_hMoveChild.Get() ) { return SetTransmitState( FL_EDICT_DONTSEND ); @@ -3556,20 +4237,20 @@ int CBaseEntity::DispatchUpdateTransmitState() edict_t *ed = edict(); if ( m_nTransmitStateOwnedCounter != 0 ) return ed ? ed->m_fStateFlags : 0; - + g_nInsideDispatchUpdateTransmitState++; int ret = UpdateTransmitState(); g_nInsideDispatchUpdateTransmitState--; - + return ret; } //----------------------------------------------------------------------------- // Purpose: Note, an entity can override the send table ( e.g., to send less data or to send minimal data for // objects ( prob. players ) that are not in the pvs. -// Input : **ppSendTable - -// *recipient - -// *pvs - +// Input : **ppSendTable - +// *recipient - +// *pvs - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- int CBaseEntity::ShouldTransmit( const CCheckTransmitInfo *pInfo ) @@ -3597,18 +4278,18 @@ int CBaseEntity::ShouldTransmit( const CCheckTransmitInfo *pInfo ) CBaseEntity *pRecipientEntity = CBaseEntity::Instance( pInfo->m_pClientEnt ); Assert( pRecipientEntity->IsPlayer() ); - + CBasePlayer *pRecipientPlayer = static_cast( pRecipientEntity ); // FIXME: Refactor once notion of "team" is moved into HL2 code // Team rules may tell us that we should - if ( pRecipientPlayer->GetTeam() ) + if ( pRecipientPlayer->GetTeam() ) { if ( pRecipientPlayer->GetTeam()->ShouldTransmitToPlayer( pRecipientPlayer, this )) return FL_EDICT_ALWAYS; } - + /*#ifdef INVASION_DLL // Check test network vis distance stuff. Eventually network LOD will do this. @@ -3642,15 +4323,15 @@ void CBaseEntity::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ) if ( pInfo->m_pTransmitAlways ) { // in HLTV/Replay mode always transmit entitys with move-parents - // HLTV/Replay can't resolve the mode-parents relationships + // HLTV/Replay can't resolve the mode-parents relationships if ( bAlways || pNetworkParent ) { // tell HLTV/Replay that this entity is always transmitted pInfo->m_pTransmitAlways->Set( index ); } - else + else { - // HLTV/Replay will PVS cull this entity, so update the + // HLTV/Replay will PVS cull this entity, so update the // node/cluster infos if necessary m_Network.RecomputePVSInformation(); } @@ -3718,9 +4399,9 @@ const char *CBaseEntity::GetDebugName(void) if ( this == NULL ) return "<>"; - if ( m_iName != NULL_STRING ) + if ( m_iName.Get() != NULL_STRING ) { - return STRING(m_iName); + return STRING(m_iName.Get()); } else { @@ -3881,7 +4562,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, NDebugOverlay::Box( pCaller->GetAbsOrigin(), Vector(-4, -4, -4), Vector(4, 4, 4), 255, 0, 0, 0, 3 ); } - NDebugOverlay::Text( GetAbsOrigin(), szInputName, false, 3 ); + NDebugOverlay::Text( GetAbsOrigin(), szInputName, false, 3 ); NDebugOverlay::Box( GetAbsOrigin(), Vector(-4, -4, -4), Vector(4, 4, 4), 0, 255, 0, 0, 3 ); } @@ -3897,17 +4578,12 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, { // found a match - char szBuffer[256]; // mapper debug message - if (pCaller != NULL) - { - Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, STRING(pCaller->m_iName), GetDebugName(), szInputName, Value.String() ); - } - else - { - Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) input : %s.%s(%s)\n", gpGlobals->curtime, GetDebugName(), szInputName, Value.String() ); - } - DevMsg( 2, "%s", szBuffer ); +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iName.Get()) : "", GetDebugName(), szInputName, Value.String() ); +#else + DevMsg( 2, "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iName.Get()) : "", GetDebugName(), szInputName, Value.String() ); +#endif ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer ); if (m_debugOverlays & OVERLAY_MESSAGE_BIT) @@ -3920,15 +4596,51 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, { if ( !(Value.FieldType() == FIELD_VOID && dmap->dataDesc[i].fieldType == FIELD_STRING) ) // allow empty strings { +#ifdef MAPBASE + // Activator, etc. support for EHANDLE convert + if ( !Value.Convert( (fieldtype_t)dmap->dataDesc[i].fieldType, this, pActivator, pCaller ) ) + { + bool bBadConversion = true; + + // Attempt to convert to string and back. + // Almost all field types support being converted to a string, and many support being parsed from a string too. + fieldtype_t originalfield = Value.FieldType(); + if (Value.Convert(FIELD_STRING)) + { + bBadConversion = !(Value.Convert((fieldtype_t)dmap->dataDesc[i].fieldType, this, pActivator, pCaller)); + if (!bBadConversion) + { + // Actual support should be added for each field, but if it works, it works. + // Warning against it only matters if you're a programmer and want to add support for each field. + // Only send a warning in dev mode. + DevWarning("!! Had to convert to string and back\n" + "!! Source Field Type: %i, Target Field Type: %i\n", + originalfield, dmap->dataDesc[i].fieldType); + } + } + + if (bBadConversion) + { + Warning( "!! ERROR: bad input/output link:\n!! Unable to convert value \"%s\" from %s (%s) to field type %i\n!! Target Entity: %s (%s), Input: %s\n", + Value.GetDebug(), + ( pCaller != NULL ) ? STRING(pCaller->m_iClassname) : "", + ( pCaller != NULL ) ? STRING(pCaller->m_iName.Get()) : "", + dmap->dataDesc[i].fieldType, + STRING(m_iClassname), GetDebugName(), szInputName ); + return false; + } + } +#else if ( !Value.Convert( (fieldtype_t)dmap->dataDesc[i].fieldType ) ) { // bad conversion - Warning( "!! ERROR: bad input/output link:\n!! %s(%s,%s) doesn't match type from %s(%s)\n", - STRING(m_iClassname), GetDebugName(), szInputName, + Warning( "!! ERROR: bad input/output link:\n!! %s(%s,%s) doesn't match type from %s(%s)\n", + STRING(m_iClassname), GetDebugName(), szInputName, ( pCaller != NULL ) ? STRING(pCaller->m_iClassname) : "", - ( pCaller != NULL ) ? STRING(pCaller->m_iName) : "" ); + ( pCaller != NULL ) ? STRING(pCaller->m_iName.Get()) : "" ); return false; } +#endif } } @@ -3936,7 +4648,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, inputfunc_t pfnInput = dmap->dataDesc[i].inputFunc; if ( pfnInput ) - { + { // Package the data into a struct for passing to the input handler. inputdata_t data; data.pActivator = pActivator; @@ -3944,13 +4656,35 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, data.value = Value; data.nOutputID = outputID; - (this->*pfnInput)( data ); + + // Now, see if there's a function named Input in this entity's script file. + // If so, execute it and let it decide whether to allow the default behavior to also execute. + bool bCallInputFunc = true; // Always assume default behavior (do call the input function) + + if ( m_ScriptScope.IsInitialized() ) + { + ScriptVariant_t functionReturn; + if ( ScriptInputHook( szInputName, pActivator, pCaller, Value, functionReturn ) ) + { + bCallInputFunc = functionReturn.m_bool; + } + } + + if( bCallInputFunc ) + { + (this->*pfnInput)( data ); + } + + if ( m_ScriptScope.IsInitialized() ) + { + ScriptInputHookClearParams(); + } } else if ( dmap->dataDesc[i].flags & FTYPEDESC_KEY ) { // set the value directly Value.SetOther( ((char*)this) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ]); - + // TODO: if this becomes evil and causes too many full entity updates, then we should make // a macro like this: // @@ -3967,10 +4701,102 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, } } - DevMsg( 2, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName()/*,", from (%s,%s)" STRING(pCaller->m_iClassname), STRING(pCaller->m_iName)*/ ); +#ifdef MAPBASE_VSCRIPT + // Allow VScript to handle unhandled inputs. + if (m_ScriptScope.IsInitialized()) + { + ScriptVariant_t functionReturn; + + if ( ScriptInputHook( szInputName, pActivator, pCaller, Value, functionReturn ) ) + { + if (functionReturn.m_bool) + return true; + } + + ScriptInputHookClearParams(); + } +#endif + +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName() ); +#else + DevMsg( 2, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName()/*,", from (%s,%s)" STRING(pCaller->m_iClassname), STRING(pCaller->m_iName.Get())*/ ); +#endif return false; } +#ifdef MAPBASE_VSCRIPT +bool CBaseEntity::ScriptAcceptInput( const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller ) +{ + variant_t value; + value.SetString( MAKE_STRING( szValue ) ); + + return AcceptInput( szInputName, ToEnt( hActivator ), ToEnt( hCaller ), value, 0 ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseEntity::ScriptInputHook( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, ScriptVariant_t &functionReturn ) +{ + char szScriptFunctionName[255]; + Q_strcpy( szScriptFunctionName, "Input" ); + Q_strcat( szScriptFunctionName, szInputName, 255 ); + + g_pScriptVM->SetValue( "activator", ( pActivator ) ? ScriptVariant_t( pActivator->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); + g_pScriptVM->SetValue( "caller", ( pCaller ) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); +#ifdef MAPBASE_VSCRIPT + Value.SetScriptVariant( functionReturn ); + g_pScriptVM->SetValue( "parameter", functionReturn ); +#endif + + bool bHandled = false; + if( CallScriptFunction( szScriptFunctionName, &functionReturn ) ) + { + bHandled = true; + } + + return bHandled; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptInputHookClearParams() +{ + g_pScriptVM->ClearValue( "activator" ); + g_pScriptVM->ClearValue( "caller" ); +#ifdef MAPBASE_VSCRIPT + g_pScriptVM->ClearValue( "parameter" ); +#endif +} + +#ifdef MAPBASE_VSCRIPT +bool CBaseEntity::ScriptDeathHook( CTakeDamageInfo *info ) +{ + if (m_ScriptScope.IsInitialized() && g_Hook_OnDeath.CanRunInScope( m_ScriptScope )) + { + HSCRIPT hInfo = g_pScriptVM->RegisterInstance( info ); + + // info + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ScriptVariant_t( hInfo ) }; + if ( g_Hook_OnDeath.Call( m_ScriptScope, &functionReturn, args ) && (functionReturn.m_type == FIELD_BOOLEAN && functionReturn.m_bool == false) ) + { + // Make this entity cheat death + g_pScriptVM->RemoveInstance( hInfo ); + return false; + } + + g_pScriptVM->RemoveInstance( hInfo ); + } + + return true; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Input handler for the entity alpha. // Input : nAlpha - Alpha value (0 - 255). @@ -4010,6 +4836,17 @@ void CBaseEntity::InputColor( inputdata_t &inputdata ) void CBaseEntity::InputUse( inputdata_t &inputdata ) { Use( inputdata.pActivator, inputdata.pCaller, (USE_TYPE)inputdata.nOutputID, 0 ); + +#ifdef MAPBASE + IGameEvent *event = gameeventmanager->CreateEvent( "player_use" ); + if ( event ) + { + event->SetInt( "userid", inputdata.pActivator && inputdata.pActivator->IsPlayer() ? + ((CBasePlayer*)inputdata.pActivator)->GetUserID() : 0 ); + event->SetInt( "entity", entindex() ); + gameeventmanager->FireEvent( event ); + } +#endif // MAPBASE } @@ -4058,7 +4895,7 @@ void CBaseEntity::InputDisableDamageForces( inputdata_t &inputdata ) AddEFlags( EFL_NO_DAMAGE_FORCES ); } - + //----------------------------------------------------------------------------- // Purpose: Sets the damage filter on the object //----------------------------------------------------------------------------- @@ -4100,7 +4937,7 @@ void CBaseEntity::InputDispatchEffect( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: Returns the origin at which to play an inputted dispatcheffect +// Purpose: Returns the origin at which to play an inputted dispatcheffect //----------------------------------------------------------------------------- void CBaseEntity::GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles ) { @@ -4121,7 +4958,23 @@ void CBaseEntity::InputKill( inputdata_t &inputdata ) SetOwnerEntity( NULL ); } +#ifdef MAPBASE + m_OnKilled.FireOutput( inputdata.pActivator, this ); +#endif + +#ifdef MAPBASE + // Kick players + if ( IsPlayer() ) + { + engine->ServerCommand( UTIL_VarArgs( "kickid %d CBaseEntity::InputKill()\n", engine->GetPlayerUserId(edict()) ) ); + } + else + { + UTIL_Remove( this ); + } +#else UTIL_Remove( this ); +#endif } void CBaseEntity::InputKillHierarchy( inputdata_t &inputdata ) @@ -4141,6 +4994,13 @@ void CBaseEntity::InputKillHierarchy( inputdata_t &inputdata ) SetOwnerEntity( NULL ); } +#ifdef MAPBASE + m_OnKilled.FireOutput( inputdata.pActivator, this ); + + // Kicking players in InputKillHierarchy does not exist in future Valve games + // if ( IsPlayer() ) +#endif + UTIL_Remove( this ); } @@ -4159,7 +5019,7 @@ void CBaseEntity::InputSetParent( inputdata_t &inputdata ) } //------------------------------------------------------------------------------ -// Purpose: +// Purpose: //------------------------------------------------------------------------------ void CBaseEntity::SetParentAttachment( const char *szInputName, const char *szAttachment, bool bMaintainOffset ) { @@ -4251,10 +5111,10 @@ void CBaseEntity::GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity) } bool CBaseEntity::IsMoving() -{ +{ Vector velocity; GetVelocity( &velocity, NULL ); - return velocity != vec3_origin; + return velocity != vec3_origin; } //----------------------------------------------------------------------------- @@ -4270,25 +5130,25 @@ void CBaseEntity::GetVectors(Vector* pForward, Vector* pRight, Vector* pUp) cons if (pForward != NULL) { - MatrixGetColumn( entityToWorld, 0, *pForward ); + MatrixGetColumn( entityToWorld, 0, *pForward ); } if (pRight != NULL) { - MatrixGetColumn( entityToWorld, 1, *pRight ); + MatrixGetColumn( entityToWorld, 1, *pRight ); *pRight *= -1.0f; } if (pUp != NULL) { - MatrixGetColumn( entityToWorld, 2, *pUp ); + MatrixGetColumn( entityToWorld, 2, *pUp ); } } //----------------------------------------------------------------------------- // Purpose: Sets the model, validates that it's of the appropriate type -// Input : *szModelName - +// Input : *szModelName - //----------------------------------------------------------------------------- void CBaseEntity::SetModel( const char *szModelName ) { @@ -4366,7 +5226,7 @@ bool CBaseEntity::IsInTeam( CTeam *pTeam ) const } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CBaseEntity::GetTeamNumber( void ) const { @@ -4374,7 +5234,7 @@ int CBaseEntity::GetTeamNumber( void ) const } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseEntity::IsInAnyTeam( void ) const { @@ -4399,6 +5259,37 @@ void CBaseEntity::NotifySystemEvent( CBaseEntity *pNotify, notify_system_event_t } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseEntity::DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) +{ + if (interactionType <= 0) + return false; + + if (m_ScriptScope.IsInitialized() && g_Hook_HandleInteraction.CanRunInScope( m_ScriptScope )) + { + //HSCRIPT hData = g_pScriptVM->RegisterInstance( data ); + + // interaction, data, sourceEnt + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { interactionType/*, ScriptVariant_t( hData )*/, ScriptVariant_t( ToHScript( sourceEnt ) ) }; + if ( g_Hook_HandleInteraction.Call( m_ScriptScope, &functionReturn, args ) && (functionReturn.m_type == FIELD_BOOLEAN) ) + { + // Return the interaction here + //g_pScriptVM->RemoveInstance( hData ); + return functionReturn.m_bool; + } + + //g_pScriptVM->RemoveInstance( hData ); + } + + return HandleInteraction( interactionType, data, sourceEnt ); +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Holds an entity's previous abs origin and angles at the time of // teleportation. Used for child & constrained entity fixup to prevent @@ -4491,7 +5382,7 @@ static void TeleportEntity( CBaseEntity *pSourceEntity, TeleportListEntry_t &ent static void BuildTeleportList_r( CBaseEntity *pTeleport, CUtlVector &teleportList ) { TeleportListEntry_t entry; - + entry.pEntity = pTeleport; entry.prevAbsOrigin = pTeleport->GetAbsOrigin(); entry.prevAbsAngles = pTeleport->GetAbsAngles(); @@ -4565,7 +5456,7 @@ CStudioHdr *ModelSoundsCache_LoadModel( const char *filename ) model_t *mdl = (model_t *)modelinfo->GetModel( idx ); if ( mdl ) { - CStudioHdr *studioHdr = new CStudioHdr( modelinfo->GetStudiomodel( mdl ), mdlcache ); + CStudioHdr *studioHdr = new CStudioHdr( modelinfo->GetStudiomodel( mdl ), mdlcache ); if ( studioHdr->IsValid() ) { return studioHdr; @@ -4586,7 +5477,7 @@ void ModelSoundsCache_PrecacheScriptSound( const char *soundname ) CBaseEntity::PrecacheScriptSound( soundname ); } -static CUtlCachedFileData< CModelSoundsCache > g_ModelSoundsCache( "modelsounds.cache", MODELSOUNDSCACHE_VERSION, 0, UTL_CACHED_FILE_USE_FILESIZE, false ); +static CUtlCachedFileData< CModelSoundsCache > g_ModelSoundsCache( "modelsounds.cache", MODELSOUNDSCACHE_VERSION, 0, UTL_CACHED_FILE_USE_FILESIZE, false ); void ClearModelSoundsCache() { @@ -4599,7 +5490,7 @@ void ClearModelSoundsCache() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool ModelSoundsCacheInit() @@ -4613,7 +5504,7 @@ bool ModelSoundsCacheInit() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void ModelSoundsCacheShutdown() { @@ -4790,7 +5681,7 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) { KeyValues *pParticleEffects = pModelKeyValues->FindKey("Particles"); if ( pParticleEffects ) - { + { // Start grabbing the sounds and slotting them in for ( KeyValues *pSingleEffect = pParticleEffects->GetFirstSubKey(); pSingleEffect; pSingleEffect = pSingleEffect->GetNextKey() ) { @@ -4804,7 +5695,7 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) // model anim event owned components { // Check animevents for particle events - CStudioHdr studioHdr( modelinfo->GetStudiomodel( pModel ), mdlcache ); + CStudioHdr studioHdr( modelinfo->GetStudiomodel( pModel ), mdlcache ); if ( studioHdr.IsValid() ) { // force animation event resolution!!! @@ -4825,8 +5716,8 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) { char token[256]; const char *pOptions = pEvent->pszOptions(); - nexttoken( token, pOptions, ' ' ); - if ( token[0] ) + nexttoken( token, pOptions, ' ', sizeof( token ) ); + if ( token ) { PrecacheParticleSystem( token ); } @@ -4881,7 +5772,7 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) } else { - Warning( "-- Error --: empty soundname, .qc error on AE_CL_PLAYSOUND in model %s, sequence %s, animevent # %i\n", + Warning( "-- Error --: empty soundname, .qc error on AE_CL_PLAYSOUND in model %s, sequence %s, animevent # %i\n", studioHdr.GetRenderHdr()->pszName(), seq.pszLabel(), j+1 ); } } @@ -4902,7 +5793,7 @@ void CBaseEntity::PrecacheModelComponents( int nModelIndex ) } - + //----------------------------------------------------------------------------- // Purpose: Add model to level precache list // Input : *name - model name @@ -4912,9 +5803,7 @@ int CBaseEntity::PrecacheModel( const char *name, bool bPreload ) { if ( !name || !*name ) { -#ifdef STAGING_ONLY Msg( "Attempting to precache model, but model name is NULL\n"); -#endif return -1; } @@ -4923,7 +5812,8 @@ int CBaseEntity::PrecacheModel( const char *name, bool bPreload ) { if ( !engine->IsModelPrecached( name ) ) { - DevMsg( "Late precache of %s -- not necessarily a bug now that we allow ~everything to be dynamically loaded.\n", name ); + Assert( !"CBaseEntity::PrecacheModel: too late" ); + Warning( "Late precache of %s\n", name ); } } #if defined( WATCHACCESS ) @@ -4947,7 +5837,7 @@ int CBaseEntity::PrecacheModel( const char *name, bool bPreload ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseEntity::Remove( ) { @@ -4967,7 +5857,7 @@ extern CBaseEntity *GetNextCommandEntity( CBasePlayer *pPlayer, const char *name void ConsoleFireTargets( CBasePlayer *pPlayer, const char *name) { // If no name was given use the picker - if (FStrEq(name,"")) + if (FStrEq(name,"")) { CBaseEntity *pEntity = FindPickerEntity( pPlayer ); if ( pEntity && !pEntity->IsMarkedForDeletion()) @@ -4981,8 +5871,66 @@ void ConsoleFireTargets( CBasePlayer *pPlayer, const char *name) FireTargets( name, pPlayer, pPlayer, USE_TOGGLE, 0 ); } +#ifdef MAPBASE +inline bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ) +{ + return Q_stricmp( lhs.String(), rhs.String() ) < 0; +} + +//------------------------------------------------------------------------------ +// Purpose : More concommands needed access to entities, so this has been moved to its own function. +// Input : cmdname - The name of the command. +// &commands - Where the complete autocompletes should be sent to. +// substring - The current search query. (only pool entities that start with this) +// checklen - The number of characters to check. +// Output : A pointer to a cUtlRBTRee containing all of the entities. +//------------------------------------------------------------------------------ +static int AutoCompleteEntities(const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0) +{ + CBaseEntity *pos = NULL; + while ((pos = gEntList.NextEnt(pos)) != NULL) + { + const char *name = pos->GetClassname(); + if (pos->GetEntityName() == NULL_STRING || Q_strnicmp(STRING(pos->GetEntityName()), substring, checklen)) + { + if (Q_strnicmp(pos->GetClassname(), substring, checklen)) + continue; + } + else + name = STRING(pos->GetEntityName()); + + CUtlString sym = name; + int idx = symbols.Find(sym); + if (idx == symbols.InvalidIndex()) + { + symbols.Insert(sym); + } + + // Too many + if (symbols.Count() >= COMMAND_COMPLETION_MAXITEMS) + break; + } + + // Now fill in the results + for (int i = symbols.FirstInorder(); i != symbols.InvalidIndex(); i = symbols.NextInorder(i)) + { + const char *name = symbols[i].String(); + + char buf[512]; + Q_strncpy(buf, name, sizeof(buf)); + Q_strlower(buf); + + CUtlString command; + command = CFmtStr("%s %s", cmdname, buf); + commands.AddToTail(command); + } + + return symbols.Count(); +} +#endif + //------------------------------------------------------------------------------ -// Purpose : +// Purpose : // Input : // Output : //------------------------------------------------------------------------------ @@ -4992,12 +5940,77 @@ void CC_Ent_Name( const CCommand& args ) } static ConCommand ent_name("ent_name", CC_Ent_Name, 0, FCVAR_CHEAT); + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void DumpScriptScope(CBasePlayer* pPlayer, const char* name) +{ + CBaseEntity* pEntity = NULL; + while ((pEntity = GetNextCommandEntity(pPlayer, name, pEntity)) != NULL) + { + if (pEntity->m_ScriptScope.IsInitialized()) + { + Msg("----Script Dump for entity %s\n", pEntity->GetDebugName()); + HSCRIPT hDumpScopeFunc = g_pScriptVM->LookupFunction("__DumpScope"); + g_pScriptVM->Call(hDumpScopeFunc, NULL, true, NULL, 1, (HSCRIPT)pEntity->m_ScriptScope); + Msg("----End Script Dump\n"); + } + else + { + DevWarning("ent_script_dump: Entity %s has no script scope!\n", pEntity->GetDebugName()); + } + } +} + +//------------------------------------------------------------------------------ +void CC_Ent_Script_Dump( const CCommand& args ) +{ + DumpScriptScope(UTIL_GetCommandClient(),args[1]); +} +static ConCommand ent_script_dump("ent_script_dump", CC_Ent_Script_Dump, "Dumps the names and values of this entity's script scope to the console\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); + + //------------------------------------------------------------------------------ +#ifdef MAPBASE +class CEntTextAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback +{ +public: + virtual void CommandCallback( const CCommand &command ) + { + SetDebugBits(UTIL_GetCommandClient(), command.Arg(1), OVERLAY_TEXT_BIT); + } + + virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) + { + if ( !g_pGameRules ) + { + return 0; + } + + const char *cmdname = "ent_text"; + + char *substring = (char *)partial; + if ( Q_strstr( partial, cmdname ) ) + { + substring = (char *)partial + strlen( cmdname ) + 1; + } + + int checklen = Q_strlen( substring ); + + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return AutoCompleteEntities(cmdname, commands, symbols, substring, checklen); + } +}; + +static CEntTextAutoCompletionFunctor g_EntTextAutoComplete; +static ConCommand ent_text("ent_text", &g_EntTextAutoComplete, "Displays text debugging information about the given entity(ies) on top of the entity (See Overlay Text)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT, &g_EntTextAutoComplete); +#else void CC_Ent_Text( const CCommand& args ) { SetDebugBits(UTIL_GetCommandClient(),args[1],OVERLAY_TEXT_BIT); } static ConCommand ent_text("ent_text", CC_Ent_Text, "Displays text debugging information about the given entity(ies) on top of the entity (See Overlay Text)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); +#endif //------------------------------------------------------------------------------ void CC_Ent_BBox( const CCommand& args ) @@ -5042,11 +6055,11 @@ void CC_Ent_Remove( const CCommand& args ) CBaseEntity *pEntity = NULL; // If no name was given set bits based on the picked - if ( FStrEq( args[1],"") ) + if ( FStrEq( args[1],"") ) { pEntity = FindPickerEntity( UTIL_GetCommandClient() ); } - else + else { int index = atoi( args[1] ); if ( index ) @@ -5059,7 +6072,7 @@ void CC_Ent_Remove( const CCommand& args ) CBaseEntity *ent = NULL; while ( (ent = gEntList.NextEnt(ent)) != NULL ) { - if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || + if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || (ent->m_iClassname != NULL_STRING && FStrEq(args[1], STRING(ent->m_iClassname))) || (ent->GetClassname()!=NULL && FStrEq(args[1], ent->GetClassname()))) { @@ -5087,14 +6100,14 @@ void CC_Ent_RemoveAll( const CCommand& args ) { Msg( "Removes all entities of the specified type\n\tArguments: {entity_name} / {class_name}\n" ); } - else + else { // Otherwise remove based on name or classname int iCount = 0; CBaseEntity *ent = NULL; while ( (ent = gEntList.NextEnt(ent)) != NULL ) { - if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || + if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || (ent->m_iClassname != NULL_STRING && FStrEq(args[1], STRING(ent->m_iClassname))) || (ent->GetClassname()!=NULL && FStrEq(args[1], ent->GetClassname()))) { @@ -5131,17 +6144,17 @@ void CC_Ent_SetName( const CCommand& args ) else { // If no name was given set bits based on the picked - if ( FStrEq( args[2],"") ) + if ( FStrEq( args[2],"") ) { pEntity = FindPickerEntity( UTIL_GetCommandClient() ); } - else + else { // Otherwise set bits based on name or classname CBaseEntity *ent = NULL; while ( (ent = gEntList.NextEnt(ent)) != NULL ) { - if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || + if ( (ent->GetEntityName() != NULL_STRING && FStrEq(args[1], STRING(ent->GetEntityName()))) || (ent->m_iClassname != NULL_STRING && FStrEq(args[1], STRING(ent->m_iClassname))) || (ent->GetClassname()!=NULL && FStrEq(args[1], ent->GetClassname()))) { @@ -5231,7 +6244,7 @@ void CC_Find_Ent_Index( const CCommand& args ) } static ConCommand find_ent_index("find_ent_index", CC_Find_Ent_Index, "Display data for entity matching specified index.\nFormat: find_ent_index \n", FCVAR_CHEAT); -// Purpose : +// Purpose : //------------------------------------------------------------------------------ void CC_Ent_Dump( const CCommand& args ) { @@ -5311,7 +6324,7 @@ static ConCommand ent_dump("ent_dump", CC_Ent_Dump, "Usage:\n ent_dump = 5 ) { +#ifdef MAPBASE + delay = atof( command.Arg( 4 ) ); +#else delay = atoi( command.Arg( 4 ) ); +#endif } g_EventQueue.AddEvent( target, action, value, delay, pPlayer, pPlayer ); @@ -5412,6 +6440,10 @@ class CEntFireAutoCompletionFunctor : public ICommandCallback, public ICommandCo checklen = Q_strlen( substring ); } +#ifdef MAPBASE + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return AutoCompleteEntities(cmdname, commands, symbols, substring, checklen); +#else CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); CBaseEntity *pos = NULL; @@ -5451,6 +6483,7 @@ class CEntFireAutoCompletionFunctor : public ICommandCallback, public ICommandCo } return symbols.Count(); +#endif } private: int EntFire_AutoCompleteInput( const char *partial, CUtlVector< CUtlString > &commands ) @@ -5479,7 +6512,12 @@ class CEntFireAutoCompletionFunctor : public ICommandCallback, public ICommandCo Q_strncat( targetEntity, substring, sizeof( targetEntity ), nEntityNameLength ); // Find the target entity by name +#ifdef MAPBASE + CBasePlayer *pPlayer = UTIL_GetCommandClient(); + CBaseEntity *target = gEntList.FindEntityGeneric( NULL, targetEntity, pPlayer, pPlayer, pPlayer ); +#else CBaseEntity *target = gEntList.FindEntityByName( NULL, targetEntity ); +#endif if ( target == NULL ) return 0; @@ -5506,10 +6544,14 @@ class CEntFireAutoCompletionFunctor : public ICommandCallback, public ICommandCo if ( !( field->flags & FTYPEDESC_INPUT ) ) continue; +#ifndef MAPBASE // What did input variables ever do to you? + // Only want input functions if ( field->flags & FTYPEDESC_SAVE ) continue; +#endif + // See if we've got a partial string for the input name already if ( inputPartial != NULL ) { @@ -5566,7 +6608,7 @@ void CC_Ent_CancelPendingEntFires( const CCommand& args ) static ConCommand ent_cancelpendingentfires("ent_cancelpendingentfires", CC_Ent_CancelPendingEntFires, "Cancels all ent_fire created outputs that are currently waiting for their delay to expire." ); //------------------------------------------------------------------------------ -// Purpose : +// Purpose : // Input : // Output : //------------------------------------------------------------------------------ @@ -5577,7 +6619,7 @@ void CC_Ent_Info( const CCommand& args ) { return; } - + if ( args.ArgC() < 2 ) { ClientPrint( pPlayer, HUD_PRINTCONSOLE, "Usage:\n ent_info \n" ); @@ -5624,43 +6666,190 @@ void CC_Ent_Info( const CCommand& args ) } static ConCommand ent_info("ent_info", CC_Ent_Info, "Usage:\n ent_info \n", FCVAR_CHEAT); - +#ifdef MAPBASE //------------------------------------------------------------------------------ -// Purpose : +// Purpose : // Input : // Output : //------------------------------------------------------------------------------ -void CC_Ent_Messages( const CCommand& args ) +void CC_Ent_Info_Datatable( const CCommand& args ) { - SetDebugBits(UTIL_GetCommandClient(),args[1],OVERLAY_MESSAGE_BIT); -} -static ConCommand ent_messages("ent_messages", CC_Ent_Messages ,"Toggles input/output message display for the selected entity(ies). The name of the entity will be displayed as well as any messages that it sends or receives.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT); - + CBasePlayer *pPlayer = ToBasePlayer( UTIL_GetCommandClient() ); + if (!pPlayer) + { + return; + } -//------------------------------------------------------------------------------ -// Purpose : -// Input : -// Output : -//------------------------------------------------------------------------------ -void CC_Ent_Pause( void ) -{ - if (CBaseEntity::Debug_IsPaused()) + if ( args.ArgC() < 2 ) { - Msg( "Resuming entity I/O events\n" ); - CBaseEntity::Debug_Pause(false); + ClientPrint( pPlayer, HUD_PRINTCONSOLE, "Usage:\n ent_info_datatable \n" ); } else { - Msg( "Pausing entity I/O events\n" ); - CBaseEntity::Debug_Pause(true); - } -} -static ConCommand ent_pause("ent_pause", CC_Ent_Pause, "Toggles pausing of input/output message processing for entities. When turned on processing of all message will stop. Any messages displayed with 'ent_messages' will stop fading and be displayed indefinitely. To step through the messages one by one use 'ent_step'.", FCVAR_CHEAT); + // Each element corresponds to a specific field type. + // Hey, if you've got a better idea, be my guest. + static const char *g_FieldStrings[FIELD_TYPECOUNT] = + { + "VOID", + "FLOAT", + "STRING", + "VECTOR", + "QUATERNION", + "INTEGER", + "BOOLEAN", + "SHORT", + "CHARACTER", + "COLOR32", + "EMBEDDED", + "CUSTOM", + + "CLASSPTR", + "EHANDLE", + "EDICT", + + "POSITION_VECTOR", + "TIME", + "TICK", + "MODELNAME", + "SOUNDNAME", + + "INPUT", + "FUNCTION", + "VMATRIX", + "VMATRIX_WORLDSPACE", + "MATRIX3X4_WORLDSPACE", + "INTERVAL", + "MODELINDEX", + "MATERIALINDEX", + + "VECTOR2D", + }; + // iterate through all the ents printing out their details + CBaseEntity *ent = CreateEntityByName( args[1] ); -//------------------------------------------------------------------------------ -// Purpose : Enables the entity picker, revelaing debug information about the -// entity under the crosshair. + if ( ent ) + { +#define ENT_INFO_BY_HIERARCHY 1 +#ifdef ENT_INFO_BY_HIERARCHY + CUtlVector dmap_namelist; + + CUtlVector< CUtlVector > dmap_fieldlist; + CUtlVector< CUtlVector > dmap_fieldtypelist; + + datamap_t *dmap; + int dmapnum = 0; + for ( dmap = ent->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + dmap_fieldlist.AddToTail(); + dmap_fieldtypelist.AddToTail(); + + // search through all the actions in the data description, printing out details + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + dmap_fieldlist[dmapnum].AddToTail(dmap->dataDesc[i].fieldName); + dmap_fieldtypelist[dmapnum].AddToTail(dmap->dataDesc[i].fieldType); + } + + dmapnum++; + dmap_namelist.AddToTail(dmap->dataClassName); + } + + char offset[64] = { 0 }; // Needed so garbage isn't spewed at the beginning + for ( int i = 0; i < dmapnum; i++ ) + { + Q_strncat(offset, " ", sizeof(offset)); + + // Header for each class + ClientPrint( pPlayer, HUD_PRINTCONSOLE, UTIL_VarArgs("%s=========| %s |=========\n", offset, dmap_namelist[i]) ); + + Q_strncat(offset, " ", sizeof(offset)); + + int iFieldCount = dmap_fieldlist[i].Count(); + for ( int index = 0; index < iFieldCount; index++ ) + { + int iType = dmap_fieldtypelist[i][index]; + ClientPrint( pPlayer, HUD_PRINTCONSOLE, UTIL_VarArgs("%s%s (%i): %s\n", offset, g_FieldStrings[iType], iType, dmap_fieldlist[i][index]) ); + } + + // Clean up after ourselves + dmap_fieldlist[i].RemoveAll(); + dmap_fieldtypelist[i].RemoveAll(); + } +#else // This sorts by field type instead + CUtlVector fieldlist[FIELD_TYPECOUNT]; + + datamap_t *dmap; + for ( dmap = ent->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the actions in the data description, printing out details + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + fieldlist[dmap->dataDesc[i].fieldType].AddToTail(dmap->dataDesc[i].fieldName); + } + } + + for ( int i = 0; i < FIELD_TYPECOUNT; i++ ) + { + const char *typestring = g_FieldStrings[i]; + for ( int index = 0; index < fieldlist[i].Count(); index++ ) + { + ClientPrint( pPlayer, HUD_PRINTCONSOLE, UTIL_VarArgs(" %s (%i): %s\n", typestring, i, fieldlist[i][index]) ); + } + + // Clean up after ourselves + fieldlist[i].RemoveAll(); + } +#endif + + delete ent; + } + else + { + ClientPrint( pPlayer, HUD_PRINTCONSOLE, UTIL_VarArgs("no such entity %s\n", args[1]) ); + } + } +} +static ConCommand ent_info_datatable("ent_info_datatable", CC_Ent_Info_Datatable, "Usage:\n ent_info_datatable \n", FCVAR_CHEAT); +#endif + + +//------------------------------------------------------------------------------ +// Purpose : +// Input : +// Output : +//------------------------------------------------------------------------------ +void CC_Ent_Messages( const CCommand& args ) +{ + SetDebugBits(UTIL_GetCommandClient(),args[1],OVERLAY_MESSAGE_BIT); +} +static ConCommand ent_messages("ent_messages", CC_Ent_Messages ,"Toggles input/output message display for the selected entity(ies). The name of the entity will be displayed as well as any messages that it sends or receives.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT); + + +//------------------------------------------------------------------------------ +// Purpose : +// Input : +// Output : +//------------------------------------------------------------------------------ +void CC_Ent_Pause( void ) +{ + if (CBaseEntity::Debug_IsPaused()) + { + Msg( "Resuming entity I/O events\n" ); + CBaseEntity::Debug_Pause(false); + } + else + { + Msg( "Pausing entity I/O events\n" ); + CBaseEntity::Debug_Pause(true); + } +} +static ConCommand ent_pause("ent_pause", CC_Ent_Pause, "Toggles pausing of input/output message processing for entities. When turned on processing of all message will stop. Any messages displayed with 'ent_messages' will stop fading and be displayed indefinitely. To step through the messages one by one use 'ent_step'.", FCVAR_CHEAT); + + +//------------------------------------------------------------------------------ +// Purpose : Enables the entity picker, revelaing debug information about the +// entity under the crosshair. // Input : an optional command line argument "full" enables all debug info. // Output : //------------------------------------------------------------------------------ @@ -5674,7 +6863,7 @@ void CC_Ent_Picker( void ) static ConCommand picker("picker", CC_Ent_Picker, "Toggles 'picker' mode. When picker is on, the bounding box, pivot and debugging text is displayed for whatever entity the player is looking at.\n\tArguments: full - enables all debug information", FCVAR_CHEAT); //------------------------------------------------------------------------------ -// Purpose : +// Purpose : // Input : // Output : //------------------------------------------------------------------------------ @@ -5685,7 +6874,7 @@ void CC_Ent_Pivot( const CCommand& args ) static ConCommand ent_pivot("ent_pivot", CC_Ent_Pivot, "Displays the pivot for the given entity(ies).\n\t(y=up=green, z=forward=blue, x=left=red). \n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); //------------------------------------------------------------------------------ -// Purpose : +// Purpose : // Input : // Output : //------------------------------------------------------------------------------ @@ -5757,7 +6946,7 @@ void CBaseEntity::CalcAbsolutePosition( void ) MatrixCopy( tmpMatrix, m_rgflCoordinateFrame ); // pull our absolute position out of the matrix - MatrixGetColumn( m_rgflCoordinateFrame, 3, m_vecAbsOrigin ); + MatrixGetColumn( m_rgflCoordinateFrame, 3, m_vecAbsOrigin ); // if we have any angles, we have to extract our absolute angles from our matrix if (( m_angRotation == vec3_angle ) && ( m_iParentAttachment == 0 )) @@ -5875,7 +7064,7 @@ matrix3x4_t& CBaseEntity::GetParentToWorldTransform( matrix3x4_t &tempMatrix ) return tempMatrix; } } - + // If we fall through to here, then just use the move parent's abs origin and angles. return pMoveParent->EntityToWorldTransform(); } @@ -5887,7 +7076,7 @@ matrix3x4_t& CBaseEntity::GetParentToWorldTransform( matrix3x4_t &tempMatrix ) void CBaseEntity::SetAbsOrigin( const Vector& absOrigin ) { AssertMsg( absOrigin.IsValid(), "Invalid origin set" ); - + // This is necessary to get the other fields of m_rgflCoordinateFrame ok CalcAbsolutePosition(); @@ -5899,8 +7088,8 @@ void CBaseEntity::SetAbsOrigin( const Vector& absOrigin ) RemoveEFlags( EFL_DIRTY_ABSTRANSFORM ); m_vecAbsOrigin = absOrigin; - - MatrixSetColumn( absOrigin, 3, m_rgflCoordinateFrame ); + + MatrixSetColumn( absOrigin, 3, m_rgflCoordinateFrame ); Vector vecNewOrigin; CBaseEntity *pMoveParent = GetMoveParent(); @@ -5942,7 +7131,7 @@ void CBaseEntity::SetAbsAngles( const QAngle& absAngles ) m_angAbsRotation = absAngles; AngleMatrix( absAngles, m_rgflCoordinateFrame ); - MatrixSetColumn( m_vecAbsOrigin, 3, m_rgflCoordinateFrame ); + MatrixSetColumn( m_vecAbsOrigin, 3, m_rgflCoordinateFrame ); QAngle angNewRotation; CBaseEntity *pMoveParent = GetMoveParent(); @@ -6067,7 +7256,7 @@ void CBaseEntity::SetLocalOrigin( const Vector& origin ) Assert( origin.y >= -largeVal && origin.y <= largeVal ); Assert( origin.z >= -largeVal && origin.z <= largeVal ); #endif - + InvalidatePhysicsRecursive( POSITION_CHANGED ); m_vecOrigin = origin; SetSimulationTime( gpGlobals->curtime ); @@ -6091,7 +7280,7 @@ void CBaseEntity::SetLocalAngles( const QAngle& angles ) { Warning( "Bad SetLocalAngles(%f,%f,%f) on %s\n", angles.x, angles.y, angles.z, GetDebugName() ); } - AssertMsg( false, "Bad SetLocalAngles(%f,%f,%f) on %s\n", angles.x, angles.y, angles.z, GetDebugName() ); + Assert( false ); return; } @@ -6194,10 +7383,10 @@ bool CBaseEntity::IsFloating() //----------------------------------------------------------------------------- // Purpose: Created predictable and sets up Id. Note that persist is ignored on the server. -// Input : *classname - -// *module - -// line - -// persist - +// Input : *classname - +// *module - +// line - +// persist - // Output : CBaseEntity //----------------------------------------------------------------------------- CBaseEntity *CBaseEntity::CreatePredictedEntityByName( const char *classname, const char *module, int line, bool persist /* = false */ ) @@ -6289,8 +7478,8 @@ void CBaseEntity::RemoveAllDecals( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : set - +// Purpose: +// Input : set - //----------------------------------------------------------------------------- void CBaseEntity::ModifyOrAppendCriteria( AI_CriteriaSet& set ) { @@ -6317,15 +7506,17 @@ void CBaseEntity::ModifyOrAppendCriteria( AI_CriteriaSet& set ) // Go through all the global states and append them - for ( int i = 0; i < GlobalEntity_GetNumGlobals(); i++ ) + for ( int i = 0; i < GlobalEntity_GetNumGlobals(); i++ ) { const char *szGlobalName = GlobalEntity_GetName(i); int iGlobalState = (int)GlobalEntity_GetStateByIndex(i); set.AppendCriteria( szGlobalName, UTIL_VarArgs( "%i", iGlobalState ) ); } +#ifndef MAPBASE // We do this later now so contexts can override criteria. I originally didn't want to remove it here in case there would be problems, but I think I have all of the bases covered. // Append anything from I/O or keyvalues pairs AppendContextToCriteria( set ); +#endif if( hl2_episodic.GetBool() ) { @@ -6333,17 +7524,27 @@ void CBaseEntity::ModifyOrAppendCriteria( AI_CriteriaSet& set ) } // Append anything from world I/O/keyvalues with "world" as prefix +#ifdef MAPBASE + CWorld *world = GetWorldEntity(); +#else CWorld *world = dynamic_cast< CWorld * >( CBaseEntity::Instance( engine->PEntityOfEntIndex( 0 ) ) ); +#endif if ( world ) { world->AppendContextToCriteria( set, "world" ); } + +#ifdef MAPBASE + // Append base stuff + set.AppendCriteria("spawnflags", UTIL_VarArgs("%i", GetSpawnFlags())); + set.AppendCriteria("flags", UTIL_VarArgs("%i", GetFlags())); +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : set - -// "" - +// Purpose: +// Input : set - +// "" - //----------------------------------------------------------------------------- void CBaseEntity::AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix /*= ""*/ ) { @@ -6364,9 +7565,32 @@ void CBaseEntity::AppendContextToCriteria( AI_CriteriaSet& set, const char *pref } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : set - +// "" - +//----------------------------------------------------------------------------- +void CBaseEntity::ReAppendContextCriteria( AI_CriteriaSet& set ) +{ + // Append contexts again. This allows it to override standard criteria, including that of derived classes. + CWorld *world = GetWorldEntity(); + if ( world ) + { + // I didn't know this until recently, but world contexts are actually prefixed by "world". + // I'm changing this here to reduce confusion and allow greater potential. + // (e.g. disabling combine soldier episodic on/off in Episodic binaries with world context "episodic:0", even though that's not happening anymore) + // The old prefixed ones still exist. They're just not appended again. + world->AppendContextToCriteria( set ); + } + + AppendContextToCriteria( set ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Removes expired concepts from list -// Output : +// Output : //----------------------------------------------------------------------------- void CBaseEntity::RemoveExpiredConcepts( void ) { @@ -6395,8 +7619,8 @@ int CBaseEntity::GetContextCount() const } //----------------------------------------------------------------------------- -// Purpose: -// Input : index - +// Purpose: +// Input : index - // Output : const char //----------------------------------------------------------------------------- const char *CBaseEntity::GetContextName( int index ) const @@ -6411,8 +7635,8 @@ const char *CBaseEntity::GetContextName( int index ) const } //----------------------------------------------------------------------------- -// Purpose: -// Input : index - +// Purpose: +// Input : index - // Output : const char //----------------------------------------------------------------------------- const char *CBaseEntity::GetContextValue( int index ) const @@ -6424,11 +7648,12 @@ const char *CBaseEntity::GetContextValue( int index ) const } return m_ResponseContexts[ index ].m_iszValue.ToCStr(); + } //----------------------------------------------------------------------------- // Purpose: Check if context has expired -// Input : index - +// Input : index - // Output : bool //----------------------------------------------------------------------------- bool CBaseEntity::ContextExpired( int index ) const @@ -6449,7 +7674,7 @@ bool CBaseEntity::ContextExpired( int index ) const //----------------------------------------------------------------------------- // Purpose: Search for index of named context string -// Input : *name - +// Input : *name - // Output : int //----------------------------------------------------------------------------- int CBaseEntity::FindContextByName( const char *name ) const @@ -6464,57 +7689,111 @@ int CBaseEntity::FindContextByName( const char *name ) const return -1; } +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: -// Input : inputdata - +// Purpose: Searches entity for named context string and/or value. +// Intended to be called by entities rather than the conventional response system. +// Input : *name - Context name. +// *value - Context value. (optional) +// Output : bool //----------------------------------------------------------------------------- -void CBaseEntity::InputAddContext( inputdata_t& inputdata ) +bool CBaseEntity::HasContext( const char *name, const char *value ) const { - const char *contextName = inputdata.value.String(); - AddContext( contextName ); -} + int c = m_ResponseContexts.Count(); + for ( int i = 0; i < c; i++ ) + { + if ( Matcher_NamesMatch( name, STRING(m_ResponseContexts[i].m_iszName) ) ) + { + if (value == NULL) + return true; + else + return Matcher_Match( value, STRING(m_ResponseContexts[i].m_iszValue) ); + } + } + return false; +} //----------------------------------------------------------------------------- -// Purpose: User inputs. These fire the corresponding user outputs, and are -// a means of forwarding messages through !activator to a target known -// known by !activator but not by the targetting entity. -// -// For example, say you have three identical trains, following the same -// path. Each train has a sprite in hierarchy with it that needs to -// toggle on/off as it passes each path_track. You would hook each train's -// OnUser1 output to it's sprite's Toggle input, then connect each path_track's -// OnPass output to !activator's FireUser1 input. +// Purpose: Searches entity for named context string and/or value. +// Intended to be called by entities rather than the conventional response system. +// Input : *name - Context name. +// *value - Context value. (optional) +// Output : bool //----------------------------------------------------------------------------- -void CBaseEntity::InputFireUser1( inputdata_t& inputdata ) +bool CBaseEntity::HasContext( string_t name, string_t value ) const { - m_OnUser1.FireOutput( inputdata.pActivator, this ); -} + int c = m_ResponseContexts.Count(); + for ( int i = 0; i < c; i++ ) + { + if ( name == m_ResponseContexts[i].m_iszName ) + { + if (value == NULL_STRING) + return true; + else + return value == m_ResponseContexts[i].m_iszValue; + } + } + return false; +} -void CBaseEntity::InputFireUser2( inputdata_t& inputdata ) +//----------------------------------------------------------------------------- +// Purpose: Searches entity for named context string and/or value. +// Intended to be called by entities rather than the conventional response system. +// Input : *nameandvalue - Context name and value. +// Output : bool +//----------------------------------------------------------------------------- +bool CBaseEntity::HasContext( const char *nameandvalue ) const { - m_OnUser2.FireOutput( inputdata.pActivator, this ); -} + char key[ 128 ]; + char value[ 128 ]; + + const char *p = nameandvalue; + while ( p ) + { +#ifdef NEW_RESPONSE_SYSTEM + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), NULL, nameandvalue ); +#else + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), NULL ); +#endif + return HasContext( key, value ); + } -void CBaseEntity::InputFireUser3( inputdata_t& inputdata ) -{ - m_OnUser3.FireOutput( inputdata.pActivator, this ); + return false; } - -void CBaseEntity::InputFireUser4( inputdata_t& inputdata ) +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : const char +//----------------------------------------------------------------------------- +const char *CBaseEntity::GetContextValue( const char *contextName ) const { - m_OnUser4.FireOutput( inputdata.pActivator, this ); + int idx = FindContextByName( contextName ); + if ( idx == -1 ) + return ""; + + return m_ResponseContexts[ idx ].m_iszValue.ToCStr(); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +float CBaseEntity::GetContextExpireTime( const char *name ) +{ + int idx = FindContextByName( name ); + if ( idx == -1 ) + return 0.0f; + + return m_ResponseContexts[ idx ].m_fExpirationTime; +} //----------------------------------------------------------------------------- -// Purpose: -// Input : *contextName - +// Purpose: Internal method or removing contexts and can remove multiple contexts in one call +// Input : *contextName - //----------------------------------------------------------------------------- -void CBaseEntity::AddContext( const char *contextName ) +void CBaseEntity::RemoveContext( const char *contextName ) { char key[ 128 ]; char value[ 128 ]; @@ -6524,7 +7803,11 @@ void CBaseEntity::AddContext( const char *contextName ) while ( p ) { duration = 0.0f; +#ifdef NEW_RESPONSE_SYSTEM + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), &duration, contextName ); +#else p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), &duration ); +#endif if ( duration ) { duration += gpGlobals->curtime; @@ -6533,323 +7816,1636 @@ void CBaseEntity::AddContext( const char *contextName ) int iIndex = FindContextByName( key ); if ( iIndex != -1 ) { - // Set the existing context to the new value - m_ResponseContexts[iIndex].m_iszValue = AllocPooledString( value ); - m_ResponseContexts[iIndex].m_fExpirationTime = duration; - continue; + m_ResponseContexts.Remove( iIndex ); } - - ResponseContext_t newContext; - newContext.m_iszName = AllocPooledString( key ); - newContext.m_iszValue = AllocPooledString( value ); - newContext.m_fExpirationTime = duration; - - m_ResponseContexts.AddToTail( newContext ); } } +#endif //----------------------------------------------------------------------------- -// Purpose: -// Input : inputdata - +// Purpose: +// Input : inputdata - //----------------------------------------------------------------------------- -void CBaseEntity::InputRemoveContext( inputdata_t& inputdata ) +void CBaseEntity::InputAddContext( inputdata_t& inputdata ) { const char *contextName = inputdata.value.String(); - int idx = FindContextByName( contextName ); - if ( idx == -1 ) - return; - - m_ResponseContexts.Remove( idx ); + AddContext( contextName ); } + //----------------------------------------------------------------------------- -// Purpose: -// Input : inputdata - +// Purpose: User inputs. These fire the corresponding user outputs, and are +// a means of forwarding messages through !activator to a target known +// known by !activator but not by the targetting entity. +// +// For example, say you have three identical trains, following the same +// path. Each train has a sprite in hierarchy with it that needs to +// toggle on/off as it passes each path_track. You would hook each train's +// OnUser1 output to it's sprite's Toggle input, then connect each path_track's +// OnPass output to !activator's FireUser1 input. //----------------------------------------------------------------------------- -void CBaseEntity::InputClearContext( inputdata_t& inputdata ) +void CBaseEntity::InputFireUser1( inputdata_t& inputdata ) { - m_ResponseContexts.RemoveAll(); + m_OnUser1.FireOutput( inputdata.pActivator, this ); } -//----------------------------------------------------------------------------- -// Purpose: -// Output : IResponseSystem -//----------------------------------------------------------------------------- -IResponseSystem *CBaseEntity::GetResponseSystem() + +void CBaseEntity::InputFireUser2( inputdata_t& inputdata ) { - return NULL; + m_OnUser2.FireOutput( inputdata.pActivator, this ); } -//----------------------------------------------------------------------------- -// Purpose: -// Input : inputdata - -//----------------------------------------------------------------------------- -void CBaseEntity::InputDispatchResponse( inputdata_t& inputdata ) + +void CBaseEntity::InputFireUser3( inputdata_t& inputdata ) { - DispatchResponse( inputdata.value.String() ); + m_OnUser3.FireOutput( inputdata.pActivator, this ); } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CBaseEntity::InputDisableShadow( inputdata_t &inputdata ) + +void CBaseEntity::InputFireUser4( inputdata_t& inputdata ) { - AddEffects( EF_NOSHADOW ); + m_OnUser4.FireOutput( inputdata.pActivator, this ); } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CBaseEntity::InputEnableShadow( inputdata_t &inputdata ) + +#ifdef MAPBASE +void CBaseEntity::InputPassUser1( inputdata_t& inputdata ) { - RemoveEffects( EF_NOSHADOW ); + m_OutUser1.Set( inputdata.value, inputdata.pActivator, this ); } -//----------------------------------------------------------------------------- -// Purpose: An input to add a new connection from this entity -// Input : &inputdata - -//----------------------------------------------------------------------------- -void CBaseEntity::InputAddOutput( inputdata_t &inputdata ) +void CBaseEntity::InputPassUser2( inputdata_t& inputdata ) { - char sOutputName[MAX_PATH]; - Q_strncpy( sOutputName, inputdata.value.String(), sizeof(sOutputName) ); - char *sChar = strchr( sOutputName, ' ' ); - if ( sChar ) - { - *sChar = '\0'; - // Now replace all the :'s in the string with ,'s. - // Has to be done this way because Hammer doesn't allow ,'s inside parameters. - char *sColon = strchr( sChar+1, ':' ); - while ( sColon ) - { - *sColon = ','; - sColon = strchr( sChar+1, ':' ); - } - KeyValue( sOutputName, sChar+1 ); + m_OutUser2.Set( inputdata.value, inputdata.pActivator, this ); +} + +void CBaseEntity::InputPassUser3( inputdata_t& inputdata ) +{ + m_OutUser3.Set( inputdata.value, inputdata.pActivator, this ); +} + +void CBaseEntity::InputPassUser4( inputdata_t& inputdata ) +{ + m_OutUser4.Set( inputdata.value, inputdata.pActivator, this ); +} + + +void CBaseEntity::InputFireRandomUser( inputdata_t& inputdata ) +{ + switch (RandomInt(1, 4)) + { + case 1: m_OnUser1.FireOutput( inputdata.pActivator, this ); break; + case 2: m_OnUser2.FireOutput( inputdata.pActivator, this ); break; + case 3: m_OnUser3.FireOutput( inputdata.pActivator, this ); break; + case 4: m_OnUser4.FireOutput( inputdata.pActivator, this ); break; } - else +} + +void CBaseEntity::InputPassRandomUser( inputdata_t& inputdata ) +{ + switch (RandomInt(1, 4)) { - Warning("AddOutput input fired with bad string. Format: ,,,,\n"); + case 1: m_OutUser1.Set( inputdata.value, inputdata.pActivator, this ); break; + case 2: m_OutUser2.Set( inputdata.value, inputdata.pActivator, this ); break; + case 3: m_OutUser3.Set( inputdata.value, inputdata.pActivator, this ); break; + case 4: m_OutUser4.Set( inputdata.value, inputdata.pActivator, this ); break; } } +#endif +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: -// Input : *conceptName - +// Purpose: Sets the entity's targetname. //----------------------------------------------------------------------------- -void CBaseEntity::DispatchResponse( const char *conceptName ) +void CBaseEntity::InputSetEntityName( inputdata_t& inputdata ) { - IResponseSystem *rs = GetResponseSystem(); - if ( !rs ) - return; - - AI_CriteriaSet set; - // Always include the concept name - set.AppendCriteria( "concept", conceptName, CONCEPT_WEIGHT ); - // Let NPC fill in most match criteria - ModifyOrAppendCriteria( set ); + SetName( inputdata.value.StringID() ); +} - // Append local player criteria to set,too - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if( pPlayer ) - pPlayer->ModifyOrAppendPlayerCriteria( set ); +//----------------------------------------------------------------------------- +// Purpose: Sets the generic target field. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetTarget( inputdata_t& inputdata ) +{ + m_target = inputdata.value.StringID(); + Activate(); +} - // Now that we have a criteria set, ask for a suitable response - AI_Response result; - bool found = rs->FindBestResponse( set, result ); - if ( !found ) - return; +//----------------------------------------------------------------------------- +// Purpose: Sets our owner entity. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetOwnerEntity( inputdata_t& inputdata ) +{ + SetOwnerEntity(inputdata.value.Entity()); +} - // Handle the response here... - const char *szResponse = result.GetResponsePtr(); - switch ( result.GetType() ) - { - case RESPONSE_SPEAK: - EmitSound( szResponse ); - break; +//----------------------------------------------------------------------------- +// Purpose: Input handler for adding to the entity's health. +// Input : Integer health points to add. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddHealth( inputdata_t &inputdata ) +{ + TakeHealth( abs(inputdata.value.Int()), DMG_GENERIC ); +} - case RESPONSE_SENTENCE: - { - int sentenceIndex = SENTENCEG_Lookup( szResponse ); - if( sentenceIndex == -1 ) - { - // sentence not found - break; - } +//----------------------------------------------------------------------------- +// Purpose: Input handler for removing health from the entity. +// Input : Integer health points to remove. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveHealth( inputdata_t &inputdata ) +{ + TakeDamage( CTakeDamageInfo( this, this, abs(inputdata.value.Int()), DMG_GENERIC ) ); +} - // FIXME: Get pitch from npc? - CPASAttenuationFilter filter( this ); - CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); - } - break; +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetHealth( inputdata_t &inputdata ) +{ + int iNewHealth = inputdata.value.Int(); + int iDelta = abs(GetHealth() - iNewHealth); + if ( iNewHealth > GetHealth() ) + { + TakeHealth( iDelta, DMG_GENERIC ); + } + else if ( iNewHealth < GetHealth() ) + { + TakeDamage( CTakeDamageInfo( this, this, iDelta, DMG_GENERIC ) ); + } +} - case RESPONSE_SCENE: - // Try to fire scene w/o an actor - InstancedScriptedScene( NULL, szResponse ); - break; +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetMaxHealth( inputdata_t &inputdata ) +{ + int iNewMaxHealth = inputdata.value.Int(); + SetMaxHealth(iNewMaxHealth); - case RESPONSE_PRINT: - break; - default: - // Don't know how to handle .vcds!!! - break; + if (GetHealth() > iNewMaxHealth) + { + SetHealth(iNewMaxHealth); } } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: Forces the named output to fire. +// In addition to the output itself, parameter may include !activator, !caller, and what to pass. //----------------------------------------------------------------------------- -void CBaseEntity::DumpResponseCriteria( void ) +void CBaseEntity::InputFireOutput( inputdata_t& inputdata ) { - Msg("----------------------------------------------\n"); - Msg("RESPONSE CRITERIA FOR: %s (%s)\n", GetClassname(), GetDebugName() ); + char sParameter[MAX_PATH]; + Q_strncpy( sParameter, inputdata.value.String(), sizeof(sParameter) ); + if ( sParameter ) + { + int iter = 0; + char *data[5] = {sParameter}; + char *sToken = strtok( sParameter, ":" ); + while ( sToken && iter < 5 ) + { + data[iter] = sToken; + iter++; + sToken = strtok( NULL, ":" ); + } - AI_CriteriaSet set; - // Let NPC fill in most match criteria - ModifyOrAppendCriteria( set ); + //DevMsg("data[0]: %s\ndata[1]: %s\ndata[2]: %s\ndata[3]: %s\ndata[4]: %s\n", data[0], data[1], data[2], data[3], data[4]); - // Append local player criteria to set,too - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + // Format: :::: + // + // data[0] = Output Name + // data[1] = Activator + // data[2] = Caller + // data[3] = Parameter + // data[4] = Delay + // + CBaseEntity *pActivator = inputdata.pActivator; + if (data[1]) + pActivator = gEntList.FindEntityByName(NULL, data[1], this, inputdata.pActivator, inputdata.pCaller); + + CBaseEntity *pCaller = this; + if (data[2]) + pCaller = gEntList.FindEntityByName(NULL, data[2], this, inputdata.pActivator, inputdata.pCaller); + + variant_t parameter; + if (data[3]) + { + parameter.SetString(MAKE_STRING(data[3])); + } + + float flDelay = 0.0f; + if (data[4]) + flDelay = atof(data[4]); + + FireNamedOutput(data[0], parameter, pActivator, pCaller, flDelay); + //Msg("Output Name: %s, Activator: %s, Caller: %s, Data: %s, Delay: %f\n", data[0], pActivator->GetDebugName(), pCaller->GetDebugName(), parameter.String(), flDelay); + } + else { - pPlayer->ModifyOrAppendPlayerCriteria( set ); + Warning("FireOutput input fired with bad parameter. Format: ::::\n"); } - - // Now dump it all to console - set.Describe(); } -//------------------------------------------------------------------------------ -void CC_Ent_Show_Response_Criteria( const CCommand& args ) +//----------------------------------------------------------------------------- +// Purpose: Removes all outputs of the specified name. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveOutput( inputdata_t& inputdata ) { - CBaseEntity *pEntity = NULL; - while ( (pEntity = GetNextCommandEntity( UTIL_GetCommandClient(), args[1], pEntity )) != NULL ) + const char *szOutput = inputdata.value.String(); + datamap_t *dmap = GetDataDescMap(); + while ( dmap ) { - pEntity->DumpResponseCriteria(); + int fields = dmap->dataNumFields; + for ( int i = 0; i < fields; i++ ) + { + typedescription_t *dataDesc = &dmap->dataDesc[i]; + if ( ( dataDesc->fieldType == FIELD_CUSTOM ) && ( dataDesc->flags & FTYPEDESC_OUTPUT ) ) + { + // If our names match, remove + if (Matcher_NamesMatch(szOutput, dataDesc->externalName)) + { + CBaseEntityOutput *pOutput = (CBaseEntityOutput *)((int)this + (int)dataDesc->fieldOffset[0]); + pOutput->DeleteAllElements(); + } + } + } + + dmap = dmap->baseMap; } } -static ConCommand ent_show_response_criteria("ent_show_response_criteria", CC_Ent_Show_Response_Criteria, "Print, to the console, an entity's current criteria set used to select responses.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); +// Find a way to implement this +/* //------------------------------------------------------------------------------ -// Purpose: Show an entity's autoaim radius +// Purpose: Cancels all I/O events of a specific output. //------------------------------------------------------------------------------ -void CC_Ent_Autoaim( const CCommand& args ) +void CBaseEntity::InputCancelOutput( inputdata_t &inputdata ) { - SetDebugBits( UTIL_GetCommandClient(),args[1], OVERLAY_AUTOAIM_BIT ); -} -static ConCommand ent_autoaim("ent_autoaim", CC_Ent_Autoaim, "Displays the entity's autoaim radius.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT ); - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CAI_BaseNPC *CBaseEntity::MyNPCPointer( void ) -{ - if ( IsNPC() ) - return assert_cast(this); - return NULL; } - -ConVar step_spline( "step_spline", "0" ); +*/ //----------------------------------------------------------------------------- -// Purpose: Run one tick's worth of faked simulation -// Input : *step - +// Purpose: Replaces all outputs of the specified name. //----------------------------------------------------------------------------- -void CBaseEntity::ComputeStepSimulationNetwork( StepSimulationData *step ) +void CBaseEntity::InputReplaceOutput( inputdata_t& inputdata ) { - if ( !step ) - { - Assert( !"ComputeStepSimulationNetworkOriginAndAngles with NULL step\n" ); + char sParameter[128]; + Q_strncpy( sParameter, inputdata.value.String(), sizeof(sParameter) ); + if (!sParameter) return; + + int iter = 0; + char *data[2]; + char *sToken = strtok( sParameter, ": " ); + while ( sToken && iter < 2 ) + { + data[iter] = sToken; + iter++; + sToken = strtok( NULL, ": " ); } - // Don't run again if we've already calculated this tick - if ( step->m_nLastProcessTickCount == gpGlobals->tickcount ) + const char *szOutput = data[0]; + const char *szNewOutput = data[1]; + if (!szOutput || !szNewOutput) { + Warning("ReplaceOutput input fired with bad parameter. Format: :\n"); return; } - step->m_nLastProcessTickCount = gpGlobals->tickcount; - - // Origin - // It's inactive - if ( step->m_bOriginActive ) + int iOutputsReplaced = 0; + datamap_t *dmap = GetDataDescMap(); + while ( dmap ) { - // First see if any external code moved the entity - if ( GetStepOrigin() != step->m_Next.vecOrigin ) - { - step->m_bOriginActive = false; - } - else + int fields = dmap->dataNumFields; + for ( int i = 0; i < fields; i++ ) { - // Compute interpolated info based on tick interval - float frac = 1.0f; - int tickdelta = step->m_Next.nTickCount - step->m_Previous.nTickCount; - if ( tickdelta > 0 ) - { - frac = (float)( gpGlobals->tickcount - step->m_Previous.nTickCount ) / (float) tickdelta; - frac = clamp( frac, 0.0f, 1.0f ); - } - - if (step->m_Previous2.nTickCount == 0 || step->m_Previous2.nTickCount >= step->m_Previous.nTickCount) - { - Vector delta = step->m_Next.vecOrigin - step->m_Previous.vecOrigin; - VectorMA( step->m_Previous.vecOrigin, frac, delta, step->m_vecNetworkOrigin ); - } - else if (!step_spline.GetBool()) + typedescription_t *dataDesc = &dmap->dataDesc[i]; + if ( ( dataDesc->fieldType == FIELD_CUSTOM ) && ( dataDesc->flags & FTYPEDESC_OUTPUT ) ) { - StepSimulationStep *pOlder = &step->m_Previous; - StepSimulationStep *pNewer = &step->m_Next; - - if (step->m_Discontinuity.nTickCount > step->m_Previous.nTickCount) + // If our names match, replace + if (Matcher_NamesMatch(szOutput, dataDesc->externalName)) { - if (gpGlobals->tickcount > step->m_Discontinuity.nTickCount) - { - pOlder = &step->m_Discontinuity; - } - else - { - pNewer = &step->m_Discontinuity; - } - - tickdelta = pNewer->nTickCount - pOlder->nTickCount; - if ( tickdelta > 0 ) + CBaseEntityOutput *pOutput = (CBaseEntityOutput *)((int)this + (int)dataDesc->fieldOffset[0]); + const char *szTarget; + const char *szInputName; + const char *szParam; + float flDelay; + int iNumTimes; + char szData[256]; + for ( CEventAction *ev = pOutput->GetActionList(); ev != NULL; ev = ev->m_pNext ) { - frac = (float)( gpGlobals->tickcount - pOlder->nTickCount ) / (float) tickdelta; - frac = clamp( frac, 0.0f, 1.0f ); + // This is the only way I think we could do this. Accomplishes the job more or less anyway + szTarget = STRING(ev->m_iTarget); + szInputName = STRING(ev->m_iTargetInput); + szParam = ev->m_iParameter == NULL_STRING ? "" : STRING(ev->m_iParameter); + flDelay = ev->m_flDelay; + iNumTimes = ev->m_nTimesToFire; + Q_snprintf(szData, sizeof(szData), "%s,%s,%s,%f,%i", szTarget, szInputName, szParam, flDelay, iNumTimes); + + KeyValue(szNewOutput, szData); + + DevMsg("ReplaceOutput: %s %s\n", szNewOutput, szData); + + iOutputsReplaced++; } + pOutput->DeleteAllElements(); } - - Vector delta = pNewer->vecOrigin - pOlder->vecOrigin; - VectorMA( pOlder->vecOrigin, frac, delta, step->m_vecNetworkOrigin ); - } - else - { - Hermite_Spline( step->m_Previous2.vecOrigin, step->m_Previous.vecOrigin, step->m_Next.vecOrigin, frac, step->m_vecNetworkOrigin ); } } + + dmap = dmap->baseMap; } - // Angles - if ( step->m_bAnglesActive ) + if (iOutputsReplaced == 0) { - // See if external code changed the orientation of the entity - if ( GetStepAngles() != step->m_angNextRotation ) + Warning("ReplaceOutput unable to find %s on %s\n", szOutput, GetDebugName()); + } + else + { + DevMsg("Replaced %i instances of %s with %s on %s\n", iOutputsReplaced, szOutput, szNewOutput, GetDebugName()); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Forces the named input to fire...what? +// Inputception...or is it just "Inception"? Whatever. +// True inception would be using this input to fire AcceptInput. +// (it would probably crash, I haven't tested it) +// +// In addition to the input itself, parameter may include !activator, !caller, and what to pass. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAcceptInput( inputdata_t& inputdata ) +{ + char sParameter[MAX_PATH]; + Q_strncpy( sParameter, inputdata.value.String(), sizeof(sParameter) ); + if ( sParameter ) + { + int iter = 0; + char *data[5] = {sParameter}; + char *sToken = strtok( sParameter, ":" ); + while ( sToken && iter < 5 ) { - step->m_bAnglesActive = false; + data[iter] = sToken; + iter++; + sToken = strtok( NULL, ":" ); } - else + + //DevMsg("data[0]: %s\ndata[1]: %s\ndata[2]: %s\ndata[3]: %s\ndata[4]: %s\n", data[0], data[1], data[2], data[3], data[4]); + + // Format: :::: + // + // data[0] = Input Name + // data[1] = Parameter + // data[2] = Activator + // data[3] = Caller + // data[4] = Output ID + // + variant_t parameter; + if (data[1]) { - // Compute interpolated info based on tick interval - float frac = 1.0f; - int tickdelta = step->m_Next.nTickCount - step->m_Previous.nTickCount; - if ( tickdelta > 0 ) - { - frac = (float)( gpGlobals->tickcount - step->m_Previous.nTickCount ) / (float) tickdelta; - frac = clamp( frac, 0.0f, 1.0f ); - } - - if (step->m_Previous2.nTickCount == 0 || step->m_Previous2.nTickCount >= step->m_Previous.nTickCount) - { + parameter.SetString(MAKE_STRING(data[1])); + } + + CBaseEntity *pActivator = inputdata.pActivator; + if (data[2]) + pActivator = gEntList.FindEntityByName(NULL, data[2], this, inputdata.pActivator, inputdata.pCaller); + + CBaseEntity *pCaller = this; + if (data[3]) + pCaller = gEntList.FindEntityByName(NULL, data[3], this, inputdata.pActivator, inputdata.pCaller); + + int iOutputID = -1; + if (data[4]) + iOutputID = atoi(data[4]); + + AcceptInput(data[0], pActivator, pCaller, parameter, iOutputID); + Msg("Input Name: %s, Activator: %s, Caller: %s, Data: %s, Output ID: %i\n", data[0], pActivator ? pActivator->GetDebugName() : "None", pCaller ? pCaller->GetDebugName() : "None", parameter.String(), iOutputID); + } + else + { + Warning("AcceptInput input fired with bad parameter. Format: ::::\n"); + } +} + +//------------------------------------------------------------------------------ +// Purpose: Cancels any I/O events in the queue that were fired by this entity. +//------------------------------------------------------------------------------ +void CBaseEntity::InputCancelPending( inputdata_t &inputdata ) +{ + g_EventQueue.CancelEvents( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Frees all of our children, entities parented to this entity. +//----------------------------------------------------------------------------- +void CBaseEntity::InputFreeChildren( inputdata_t& inputdata ) +{ + UnlinkAllChildren( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our origin. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetLocalOrigin( inputdata_t& inputdata ) +{ + Vector vec; + inputdata.value.Vector3D(vec); + SetLocalOrigin(vec); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our angles. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetLocalAngles( inputdata_t& inputdata ) +{ + QAngle ang; + inputdata.value.Angle3D(ang); + SetLocalAngles(ang); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our origin. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetAbsOrigin( inputdata_t& inputdata ) +{ + Vector vec; + inputdata.value.Vector3D(vec); + SetAbsOrigin(vec); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our angles. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetAbsAngles( inputdata_t& inputdata ) +{ + QAngle ang; + inputdata.value.Angle3D(ang); + SetAbsAngles(ang); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our velocity. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetLocalVelocity( inputdata_t& inputdata ) +{ + Vector vec; + inputdata.value.Vector3D(vec); + SetLocalVelocity(vec); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our angular velocity. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetLocalAngularVelocity( inputdata_t& inputdata ) +{ + Vector vec; + inputdata.value.Vector3D(vec); + SetLocalAngularVelocity(QAngle(vec.x, vec.y, vec.z)); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds spawn flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddSpawnFlags( inputdata_t& inputdata ) +{ + AddSpawnFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes spawn flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveSpawnFlags( inputdata_t& inputdata ) +{ + RemoveSpawnFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our render mode. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetRenderMode( inputdata_t& inputdata ) +{ + SetRenderMode((RenderMode_t)inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our render FX. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetRenderFX( inputdata_t& inputdata ) +{ + m_nRenderFX = inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our view hide flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetViewHideFlags( inputdata_t& inputdata ) +{ + m_iViewHideFlags = inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds effects. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddEffects( inputdata_t& inputdata ) +{ + AddEffects(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes effects. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveEffects( inputdata_t& inputdata ) +{ + RemoveEffects(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Shortcut for removing nodraw. +//----------------------------------------------------------------------------- +void CBaseEntity::InputDrawEntity( inputdata_t& inputdata ) +{ + RemoveEffects(EF_NODRAW); +} + +//----------------------------------------------------------------------------- +// Purpose: Shortcut to adding nodraw. +//----------------------------------------------------------------------------- +void CBaseEntity::InputUndrawEntity( inputdata_t& inputdata ) +{ + AddEffects(EF_NODRAW); +} + +//----------------------------------------------------------------------------- +// Purpose: Inspired by the Portal 2 input of the same name. +//----------------------------------------------------------------------------- +void CBaseEntity::InputEnableReceivingFlashlight( inputdata_t& inputdata ) +{ + m_bDisableFlashlight = false; +} + +//----------------------------------------------------------------------------- +// Purpose: Inspired by the Portal 2 input of the same name. +//----------------------------------------------------------------------------- +void CBaseEntity::InputDisableReceivingFlashlight( inputdata_t& inputdata ) +{ + m_bDisableFlashlight = true; +} + +//----------------------------------------------------------------------------- +// Purpose: Adds eflags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddEFlags( inputdata_t& inputdata ) +{ + AddEFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes eflags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveEFlags( inputdata_t& inputdata ) +{ + RemoveEFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds solid flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddSolidFlags( inputdata_t& inputdata ) +{ + AddSolidFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes solid flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveSolidFlags( inputdata_t& inputdata ) +{ + RemoveSolidFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the movetype. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetMoveType( inputdata_t& inputdata ) +{ + SetMoveType((MoveType_t)inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the collision group. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetCollisionGroup( inputdata_t& inputdata ) +{ + SetCollisionGroup(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Touch touch :) +//----------------------------------------------------------------------------- +void CBaseEntity::InputTouch( inputdata_t& inputdata ) +{ + if (inputdata.value.Entity()) + Touch( inputdata.value.Entity() ); + else + Warning( "%s InputTouch: Can't touch null entity", GetDebugName() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Passes KilledNPC to our possibly more capable parents. +//----------------------------------------------------------------------------- +void CBaseEntity::InputKilledNPC( inputdata_t &inputdata ) +{ + // Don't get stuck in an endless loop + if (inputdata.value.Int() > 16) + return; + else + inputdata.value.SetInt(inputdata.value.Int() + 1); + + if (GetOwnerEntity()) + { + GetOwnerEntity()->AcceptInput("KilledNPC", inputdata.pActivator, inputdata.pCaller, inputdata.value, inputdata.nOutputID); + } + else if (HasPhysicsAttacker(4.0f)) + { + HasPhysicsAttacker(4.0f)->AcceptInput("KilledNPC", inputdata.pActivator, inputdata.pCaller, inputdata.value, inputdata.nOutputID); + } + else if (GetMoveParent()) + { + GetMoveParent()->AcceptInput("KilledNPC", inputdata.pActivator, inputdata.pCaller, inputdata.value, inputdata.nOutputID); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Remove if not visible by any players +//----------------------------------------------------------------------------- +void CBaseEntity::InputKillIfNotVisible( inputdata_t& inputdata ) +{ +#ifdef MAPBASE_MP + // Go through each client and check if we're in their viewcone. + // If we're in someone's viewcone, return immediately. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer && pPlayer->FInViewCone( this ) ) + return; + } +#else + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( !pPlayer || !pPlayer->FInViewCone( this ) ) +#endif + { + m_OnKilled.FireOutput(inputdata.pActivator, this); + UTIL_Remove(this); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Remove when not visible by any players +//----------------------------------------------------------------------------- +void CBaseEntity::InputKillWhenNotVisible( inputdata_t& inputdata ) +{ + SetContextThink( &CBaseEntity::SUB_RemoveWhenNotVisible, gpGlobals->curtime + inputdata.value.Float(), "SUB_RemoveWhenNotVisible" ); + //SetRenderColorA( 255 ); + //m_nRenderMode = kRenderNormal; +} + +//----------------------------------------------------------------------------- +// Purpose: Stop thinking +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetThinkNull( inputdata_t& inputdata ) +{ + const char *szContext = inputdata.value.String(); + if (szContext && szContext[0] != '\0') + { + SetContextThink( NULL, TICK_NEVER_THINK, szContext ); + } + else + { + SetThink( NULL ); + SetNextThink( TICK_NEVER_THINK ); + } +} +#endif + + +//--------------------------------------------------------- +// Use the string as the filename of a script file +// that should be loaded from disk, compiled, and run. +//--------------------------------------------------------- +void CBaseEntity::InputRunScriptFile(inputdata_t& inputdata) +{ + RunScriptFile(inputdata.value.String()); +} + +//--------------------------------------------------------- +// Send the string to the VM as source code and execute it +//--------------------------------------------------------- +void CBaseEntity::InputRunScript(inputdata_t& inputdata) +{ + RunScript(inputdata.value.String(), "InputRunScript"); +} + +//--------------------------------------------------------- +// Make an explicit function call. +//--------------------------------------------------------- +void CBaseEntity::InputCallScriptFunction(inputdata_t& inputdata) +{ + CallScriptFunction(inputdata.value.String(), NULL); +} + +#ifdef MAPBASE_VSCRIPT +//--------------------------------------------------------- +// Send the string to the VM as source code and execute it +//--------------------------------------------------------- +void CBaseEntity::InputRunScriptQuotable(inputdata_t& inputdata) +{ + char szQuotableCode[1024]; + if (V_StrSubst( inputdata.value.String(), "''", "\"", szQuotableCode, sizeof( szQuotableCode ), false )) + { + RunScript( szQuotableCode, "InputRunScriptQuotable" ); + } + else + { + RunScript( inputdata.value.String(), "InputRunScriptQuotable" ); + } +} + +//--------------------------------------------------------- +// Clear this entity's script scope +//--------------------------------------------------------- +void CBaseEntity::InputClearScriptScope(inputdata_t& inputdata) +{ + m_ScriptScope.Term(); +} +#endif + +// #define VMPROFILE // define to profile vscript calls + +#ifdef VMPROFILE +float g_debugCumulativeTime = 0.0; +float g_debugCounter = 0; + +#define START_VMPROFILE float debugStartTime = Plat_FloatTime(); +#define UPDATE_VMPROFILE \ + g_debugCumulativeTime += Plat_FloatTime() - debugStartTime; \ + g_debugCounter++; \ + if ( g_debugCounter >= 500 ) \ + { \ + DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", "500 vscript function calls", "", g_debugCumulativeTime*1000.0 ); \ + g_debugCounter = 0; \ + g_debugCumulativeTime = 0.0; \ + } \ + +#else + +#define START_VMPROFILE +#define UPDATE_VMPROFILE + +#endif // VMPROFILE + +//----------------------------------------------------------------------------- +// Returns true if the function was located and called. false otherwise. +// NOTE: Assumes the function takes no parameters at the moment. +//----------------------------------------------------------------------------- +bool CBaseEntity::CallScriptFunction(const char* pFunctionName, ScriptVariant_t* pFunctionReturn) +{ + START_VMPROFILE + + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + + HSCRIPT hFunc = m_ScriptScope.LookupFunction(pFunctionName); + + if (hFunc) + { + m_ScriptScope.Call(hFunc, pFunctionReturn); + m_ScriptScope.ReleaseFunction(hFunc); + + UPDATE_VMPROFILE + + return true; + } + + return false; +} + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Gets a function handle +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::LookupScriptFunction(const char* pFunctionName) +{ + START_VMPROFILE + + if (!m_ScriptScope.IsInitialized()) + { + return NULL; + } + + return m_ScriptScope.LookupFunction(pFunctionName); +} + +//----------------------------------------------------------------------------- +// Calls and releases a function handle (ASSUMES SCRIPT SCOPE AND FUNCTION ARE VALID!) +//----------------------------------------------------------------------------- +bool CBaseEntity::CallScriptFunctionHandle(HSCRIPT hFunc, ScriptVariant_t* pFunctionReturn) +{ + m_ScriptScope.Call(hFunc, pFunctionReturn); + m_ScriptScope.ReleaseFunction(hFunc); + + UPDATE_VMPROFILE + + return true; +} +#endif + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ConnectOutputToScript(const char* pszOutput, const char* pszScriptFunc) +{ + CBaseEntityOutput* pOutput = FindNamedOutput(pszOutput); + if (!pOutput) + { + DevMsg(2, "Script failed to find output \"%s\"\n", pszOutput); + return; + } + + string_t iszSelf = AllocPooledString("!self"); // @TODO: cache this [4/25/2008 tom] + CEventAction* pAction = pOutput->GetActionList(); + while (pAction) + { + if (pAction->m_iTarget == iszSelf && + pAction->m_flDelay == 0 && + pAction->m_nTimesToFire == EVENT_FIRE_ALWAYS && + V_strcmp(STRING(pAction->m_iTargetInput), "CallScriptFunction") == 0 && + V_strcmp(STRING(pAction->m_iParameter), pszScriptFunc) == 0) + { + return; + } + pAction = pAction->m_pNext; + } + + pAction = new CEventAction(NULL); + pAction->m_iTarget = iszSelf; + pAction->m_iTargetInput = AllocPooledString("CallScriptFunction"); + pAction->m_iParameter = AllocPooledString(pszScriptFunc); + pOutput->AddEventAction(pAction); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::DisconnectOutputFromScript(const char* pszOutput, const char* pszScriptFunc) +{ + CBaseEntityOutput* pOutput = FindNamedOutput(pszOutput); + if (!pOutput) + { + DevMsg(2, "Script failed to find output \"%s\"\n", pszOutput); + return; + } + + string_t iszSelf = AllocPooledString("!self"); // @TODO: cache this [4/25/2008 tom] + CEventAction* pAction = pOutput->GetActionList(); + while (pAction) + { + if (pAction->m_iTarget == iszSelf && + pAction->m_flDelay == 0 && + pAction->m_nTimesToFire == EVENT_FIRE_ALWAYS && + V_strcmp(STRING(pAction->m_iTargetInput), "CallScriptFunction") == 0 && + V_strcmp(STRING(pAction->m_iParameter), pszScriptFunc) == 0) + { + pOutput->RemoveEventAction(pAction); + delete pAction; + return; + } + pAction = pAction->m_pNext; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptThink(void) +{ + ScriptVariant_t varThinkRetVal; + if (CallScriptFunction(m_iszScriptThinkFunction.ToCStr(), &varThinkRetVal)) + { + float flThinkFrequency = 0.0f; + if (!varThinkRetVal.AssignTo(&flThinkFrequency)) + { + // use default think interval if script think function doesn't provide one + flThinkFrequency = sv_script_think_interval.GetFloat(); + } + + SetNextThink( gpGlobals->curtime + flThinkFrequency, "ScriptThink" ); + } + else + { + DevWarning("%s FAILED to call script think function %s!\n", GetDebugName(), STRING(m_iszScriptThinkFunction)); + } +} + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptSetThinkFunction( const char *szFunc, float flTime ) +{ + // Empty string stops thinking + if (!szFunc || szFunc[0] == '\0') + { + ScriptStopThinkFunction(); + } + else + { + m_iszScriptThinkFunction = AllocPooledString(szFunc); + flTime = MAX( 0, flTime ); + SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime + flTime, "ScriptThink" ); + } +} + +void CBaseEntity::ScriptStopThinkFunction() +{ + m_iszScriptThinkFunction = NULL_STRING; + SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThink" ); +} +#endif // MAPBASE_VSCRIPT + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char* CBaseEntity::GetScriptId() +{ +#ifdef MAPBASE_VSCRIPT + return STRING(m_iszScriptId); +#else + return STRING(m_iszScriptThinkFunction); +#endif +} + +//----------------------------------------------------------------------------- +// Recreate the old behaviour of GetScriptId under a new function +//----------------------------------------------------------------------------- +// const char* CBaseEntity::GetScriptThinkFunction() +// { +// return STRING(m_iszScriptThinkFunction); +// } + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::GetScriptScope() +{ + return m_ScriptScope; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptGetMoveParent(void) +{ + return ToHScript(GetMoveParent()); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptGetRootMoveParent() +{ + return ToHScript(GetRootMoveParent()); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptFirstMoveChild(void) +{ + return ToHScript(FirstMoveChild()); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptNextMovePeer(void) +{ + return ToHScript(NextMovePeer()); +} + +//----------------------------------------------------------------------------- +// Purpose: Load, compile, and run a script file from disk. +// Input : *pScriptFile - The filename of the script file. +// bUseRootScope - If true, runs this script in the root scope, not +// in this entity's private scope. +//----------------------------------------------------------------------------- +bool CBaseEntity::RunScriptFile(const char* pScriptFile, bool bUseRootScope) +{ + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + if (bUseRootScope) + { + return VScriptRunScript(pScriptFile); + } + else + { + return VScriptRunScript(pScriptFile, m_ScriptScope, true); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Compile and execute a discrete string of script source code +// Input : *pScriptText - A string containing script code to compile and run +//----------------------------------------------------------------------------- +bool CBaseEntity::RunScript(const char* pScriptText, const char* pDebugFilename) +{ + if (!ValidateScriptScope()) + { + DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n"); + return false; + } + + if (m_ScriptScope.Run(pScriptText, pDebugFilename) == SCRIPT_ERROR) + { + DevWarning(" Entity %s encountered an error in RunScript()\n", GetDebugName()); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *contextName - +//----------------------------------------------------------------------------- +void CBaseEntity::AddContext( const char *contextName ) +{ + char key[ 128 ]; + char value[ 128 ]; + float duration = 0.0f; + + const char *p = contextName; + while ( p ) + { + duration = 0.0f; +#ifdef NEW_RESPONSE_SYSTEM + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), &duration, contextName ); +#else + p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), &duration ); +#endif + if ( duration ) + { + duration += gpGlobals->curtime; + } + + AddContext( key, value, duration ); + } +} + +void CBaseEntity::AddContext( const char *name, const char *value, float duration ) +{ + int iIndex = FindContextByName( name ); + if ( iIndex != -1 ) + { + // Set the existing context to the new value + +#ifdef NEW_RESPONSE_SYSTEM + char buf[64]; + if ( RR::CApplyContextOperator::FindOperator( value )->Apply( + m_ResponseContexts[iIndex].m_iszValue.ToCStr(), value, buf, sizeof(buf) ) ) + { + m_ResponseContexts[iIndex].m_iszValue = AllocPooledString( buf ); + } + else + { + Warning( "RR: could not apply operator %s to prior value %s\n", + value, m_ResponseContexts[iIndex].m_iszValue.ToCStr() ); + m_ResponseContexts[iIndex].m_iszValue = AllocPooledString( value ); + } +#else + m_ResponseContexts[iIndex].m_iszValue = AllocPooledString( value ); +#endif + m_ResponseContexts[iIndex].m_fExpirationTime = duration; + } + else + { + ResponseContext_t newContext; + newContext.m_iszName = AllocPooledString( name ); + +#ifdef NEW_RESPONSE_SYSTEM + char buf[64]; + if ( RR::CApplyContextOperator::FindOperator( value )->Apply( + NULL, value, buf, sizeof(buf) ) ) + { + newContext.m_iszValue = AllocPooledString( buf ); + } + else + { + newContext.m_iszValue = AllocPooledString( value ); + } +#else + newContext.m_iszValue = AllocPooledString( value ); +#endif + + newContext.m_fExpirationTime = duration; + + m_ResponseContexts.AddToTail( newContext ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveContext( inputdata_t& inputdata ) +{ + const char *contextName = inputdata.value.String(); + int idx = FindContextByName( contextName ); + if ( idx == -1 ) + return; + + m_ResponseContexts.Remove( idx ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::InputClearContext( inputdata_t& inputdata ) +{ + m_ResponseContexts.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : IResponseSystem +//----------------------------------------------------------------------------- +IResponseSystem *CBaseEntity::GetResponseSystem() +{ + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::InputDispatchResponse( inputdata_t& inputdata ) +{ + DispatchResponse( inputdata.value.String() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::InputDisableShadow( inputdata_t &inputdata ) +{ + AddEffects( EF_NOSHADOW ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::InputEnableShadow( inputdata_t &inputdata ) +{ + RemoveEffects( EF_NOSHADOW ); +} + +//----------------------------------------------------------------------------- +// Purpose: An input to add a new connection from this entity +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddOutput( inputdata_t &inputdata ) +{ + char sOutputName[MAX_PATH]; + Q_strncpy( sOutputName, inputdata.value.String(), sizeof(sOutputName) ); + char *sChar = strchr( sOutputName, ' ' ); + if ( sChar ) + { + *sChar = '\0'; + // Now replace all the :'s in the string with ,'s. + // Has to be done this way because Hammer doesn't allow ,'s inside parameters. + char *sColon = strchr( sChar+1, ':' ); + while ( sColon ) + { + *sColon = ','; + sColon = strchr( sChar+1, ':' ); + } + KeyValue( sOutputName, sChar+1 ); + } + else + { + Warning("AddOutput input fired with bad string. Format: ,,,,\n"); + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::InputChangeVariable( inputdata_t &inputdata ) +{ + const char *szKeyName = NULL; + const char *szValue = NULL; + + char sOutputName[MAX_PATH]; + Q_strncpy( sOutputName, inputdata.value.String(), sizeof(sOutputName) ); + char *sChar = strchr( sOutputName, ' ' ); + if ( sChar ) + { + *sChar = '\0'; + // Now replace all the :'s in the string with ,'s. + // Has to be done this way because Hammer doesn't allow ,'s inside parameters. + char *sColon = strchr( sChar+1, ':' ); + while ( sColon ) + { + *sColon = ','; + sColon = strchr( sChar+1, ':' ); + } + + szKeyName = sOutputName; + szValue = sChar + 1; + } + else + { + Warning("ChangeVariable input fired with bad string. Format: ,,,,\n"); + return; + } + + if (szKeyName == NULL) + return; + + for ( datamap_t *dmap = GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) ) + { + if ( Matcher_NamesMatch(szKeyName, dmap->dataDesc[i].fieldName) ) + { + // Copied from ::ParseKeyvalue...or technically logic_datadesc_accessor... + typedescription_t *pField = &dmap->dataDesc[i]; + char *data = Datadesc_SetFieldString( szValue, this, pField, NULL ); + + if (!data) + { + Warning( "%s cannot set field of type %i.\n", GetDebugName(), dmap->dataDesc[i].fieldType ); + } + } + } + } + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *conceptName - +//----------------------------------------------------------------------------- +void CBaseEntity::DispatchResponse( const char *conceptName ) +{ +#ifdef NEW_RESPONSE_SYSTEM + #undef IResponseSystem + using namespace ResponseRules; +#endif + + IResponseSystem *rs = GetResponseSystem(); + if ( !rs ) + return; + + AI_CriteriaSet set; + // Always include the concept name + set.AppendCriteria( "concept", conceptName, CONCEPT_WEIGHT ); + // Let NPC fill in most match criteria + ModifyOrAppendCriteria( set ); + + // Append local player criteria to set,too + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + +#ifdef MAPBASE + ReAppendContextCriteria( set ); +#endif + + // Now that we have a criteria set, ask for a suitable response + AI_Response result; + bool found = rs->FindBestResponse( set, result ); + if ( !found ) + { + return; + } + + // Handle the response here... + char response[ 256 ]; + result.GetResponse( response, sizeof( response ) ); +#ifdef NEW_RESPONSE_SYSTEM + switch (result.GetType()) + { + case ResponseRules::RESPONSE_SPEAK: + { + EmitSound(response); + } + break; + case ResponseRules::RESPONSE_SENTENCE: + { + int sentenceIndex = SENTENCEG_Lookup(response); + if (sentenceIndex == -1) + { + // sentence not found + break; + } + + // FIXME: Get pitch from npc? + CPASAttenuationFilter filter(this); + CBaseEntity::EmitSentenceByIndex(filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM); + } + break; + case ResponseRules::RESPONSE_SCENE: + { + // Try to fire scene w/o an actor + InstancedScriptedScene(NULL, response); + } + break; + case ResponseRules::RESPONSE_PRINT: + { + + } + break; + case ResponseRules::RESPONSE_ENTITYIO: + { + CAI_Expresser::FireEntIOFromResponse(response, this); + break; + } +#ifdef MAPBASE_VSCRIPT + case ResponseRules::RESPONSE_VSCRIPT: + { + CAI_Expresser::RunScriptResponse( this, response, &set, false ); + break; + } + case ResponseRules::RESPONSE_VSCRIPT_FILE: + { + CAI_Expresser::RunScriptResponse( this, response, &set, true ); + break; + } +#endif + default: + // Don't know how to handle .vcds!!! + break; + } +#else +#ifdef MAPBASE + if (response[0] == '$') + { + const char *context = response + 1; + const char *replace = GetContextValue(context); + + if (replace) + { + DevMsg("Replacing %s with %s...\n", response, replace); + Q_strncpy(response, replace, sizeof(response)); + + // Precache it now because it may not have been precached before + switch ( result.GetType() ) + { + case RESPONSE_SPEAK: + { + PrecacheScriptSound( response ); + } + break; + + case RESPONSE_SCENE: + { + // TODO: Gender handling? + PrecacheInstancedScene( response ); + } + break; + } + } + } +#endif + switch ( result.GetType() ) + { + case RESPONSE_SPEAK: + { + EmitSound( response ); + } + break; + case RESPONSE_SENTENCE: + { +#ifdef MAPBASE + if (response[0] != '!') + { + SENTENCEG_PlayRndSz( edict(), response, 1, result.GetSoundLevel(), 0, PITCH_NORM ); + break; + } +#endif + int sentenceIndex = SENTENCEG_Lookup( response ); + if( sentenceIndex == -1 ) + { + // sentence not found + break; + } + + // FIXME: Get pitch from npc? + CPASAttenuationFilter filter( this ); + CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); + } + break; + case RESPONSE_SCENE: + { +#ifdef MAPBASE + // Most flexing actors that use scenes override DispatchResponse via CAI_Expresser in ai_speech. + // So, in order for non-actors to use scenes by themselves, they actually don't really use them at all. + // Most scenes that would be used as responses only have one sound, so we take the first sound in a scene and emit it manually. + // + // Of course, env_speaker uses scenes without using itself as an actor, but that overrides DispatchResponse in Mapbase + // with the original code intact. Hopefully no other entity uses this like that... + + //if (!ClassMatches("env_speaker")) + { + // Expand gender string + GenderExpandString( response, response, sizeof( response ) ); + + // Trust that it's been precached + const char *pszSound = GetFirstSoundInScene(response); + EmitSound(pszSound); + } + //else + // InstancedScriptedScene(NULL, response); +#else + // Try to fire scene w/o an actor + InstancedScriptedScene( NULL, response ); +#endif + } + break; + case RESPONSE_PRINT: + { + + } + break; + default: + // Don't know how to handle .vcds!!! + break; + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseEntity::DumpResponseCriteria( void ) +{ + Msg("----------------------------------------------\n"); + Msg("RESPONSE CRITERIA FOR: %s (%s)\n", GetClassname(), GetDebugName() ); + + AI_CriteriaSet set; + // Let NPC fill in most match criteria + ModifyOrAppendCriteria( set ); + + // Append local player criteria to set,too + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer ) + { + pPlayer->ModifyOrAppendPlayerCriteria( set ); + } + +#ifdef MAPBASE + ReAppendContextCriteria( set ); +#endif + + // Now dump it all to console + set.Describe(); +} + +//------------------------------------------------------------------------------ +void CC_Ent_Show_Response_Criteria( const CCommand& args ) +{ + CBaseEntity *pEntity = NULL; + while ( (pEntity = GetNextCommandEntity( UTIL_GetCommandClient(), args[1], pEntity )) != NULL ) + { + pEntity->DumpResponseCriteria(); + } +} +static ConCommand ent_show_response_criteria("ent_show_response_criteria", CC_Ent_Show_Response_Criteria, "Print, to the console, an entity's current criteria set used to select responses.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); + +//------------------------------------------------------------------------------ +// Purpose: Show an entity's autoaim radius +//------------------------------------------------------------------------------ +void CC_Ent_Autoaim( const CCommand& args ) +{ + SetDebugBits( UTIL_GetCommandClient(),args[1], OVERLAY_AUTOAIM_BIT ); +} +static ConCommand ent_autoaim("ent_autoaim", CC_Ent_Autoaim, "Displays the entity's autoaim radius.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_BaseNPC *CBaseEntity::MyNPCPointer( void ) +{ + if ( IsNPC() ) + return assert_cast(this); + + return NULL; +} + +ConVar step_spline( "step_spline", "0" ); + +//----------------------------------------------------------------------------- +// Purpose: Run one tick's worth of faked simulation +// Input : *step - +//----------------------------------------------------------------------------- +void CBaseEntity::ComputeStepSimulationNetwork( StepSimulationData *step ) +{ + if ( !step ) + { + Assert( !"ComputeStepSimulationNetworkOriginAndAngles with NULL step\n" ); + return; + } + + // Don't run again if we've already calculated this tick + if ( step->m_nLastProcessTickCount == gpGlobals->tickcount ) + { + return; + } + + step->m_nLastProcessTickCount = gpGlobals->tickcount; + + // Origin + // It's inactive + if ( step->m_bOriginActive ) + { + // First see if any external code moved the entity + if ( GetStepOrigin() != step->m_Next.vecOrigin ) + { + step->m_bOriginActive = false; + } + else + { + // Compute interpolated info based on tick interval + float frac = 1.0f; + int tickdelta = step->m_Next.nTickCount - step->m_Previous.nTickCount; + if ( tickdelta > 0 ) + { + frac = (float)( gpGlobals->tickcount - step->m_Previous.nTickCount ) / (float) tickdelta; + frac = clamp( frac, 0.0f, 1.0f ); + } + + if (step->m_Previous2.nTickCount == 0 || step->m_Previous2.nTickCount >= step->m_Previous.nTickCount) + { + Vector delta = step->m_Next.vecOrigin - step->m_Previous.vecOrigin; + VectorMA( step->m_Previous.vecOrigin, frac, delta, step->m_vecNetworkOrigin ); + } + else if (!step_spline.GetBool()) + { + StepSimulationStep *pOlder = &step->m_Previous; + StepSimulationStep *pNewer = &step->m_Next; + + if (step->m_Discontinuity.nTickCount > step->m_Previous.nTickCount) + { + if (gpGlobals->tickcount > step->m_Discontinuity.nTickCount) + { + pOlder = &step->m_Discontinuity; + } + else + { + pNewer = &step->m_Discontinuity; + } + + tickdelta = pNewer->nTickCount - pOlder->nTickCount; + if ( tickdelta > 0 ) + { + frac = (float)( gpGlobals->tickcount - pOlder->nTickCount ) / (float) tickdelta; + frac = clamp( frac, 0.0f, 1.0f ); + } + } + + Vector delta = pNewer->vecOrigin - pOlder->vecOrigin; + VectorMA( pOlder->vecOrigin, frac, delta, step->m_vecNetworkOrigin ); + } + else + { + Hermite_Spline( step->m_Previous2.vecOrigin, step->m_Previous.vecOrigin, step->m_Next.vecOrigin, frac, step->m_vecNetworkOrigin ); + } + } + } + + // Angles + if ( step->m_bAnglesActive ) + { + // See if external code changed the orientation of the entity + if ( GetStepAngles() != step->m_angNextRotation ) + { + step->m_bAnglesActive = false; + } + else + { + // Compute interpolated info based on tick interval + float frac = 1.0f; + int tickdelta = step->m_Next.nTickCount - step->m_Previous.nTickCount; + if ( tickdelta > 0 ) + { + frac = (float)( gpGlobals->tickcount - step->m_Previous.nTickCount ) / (float) tickdelta; + frac = clamp( frac, 0.0f, 1.0f ); + } + + if (step->m_Previous2.nTickCount == 0 || step->m_Previous2.nTickCount >= step->m_Previous.nTickCount) + { // Pure blend between start/end orientations Quaternion outangles; QuaternionBlend( step->m_Previous.qRotation, step->m_Next.qRotation, frac, outangles ); @@ -6857,448 +9453,992 @@ void CBaseEntity::ComputeStepSimulationNetwork( StepSimulationData *step ) } else if (!step_spline.GetBool()) { - StepSimulationStep *pOlder = &step->m_Previous; - StepSimulationStep *pNewer = &step->m_Next; - - if (step->m_Discontinuity.nTickCount > step->m_Previous.nTickCount) - { - if (gpGlobals->tickcount > step->m_Discontinuity.nTickCount) - { - pOlder = &step->m_Discontinuity; - } - else - { - pNewer = &step->m_Discontinuity; - } - - tickdelta = pNewer->nTickCount - pOlder->nTickCount; - if ( tickdelta > 0 ) - { - frac = (float)( gpGlobals->tickcount - pOlder->nTickCount ) / (float) tickdelta; - frac = clamp( frac, 0.0f, 1.0f ); - } - } - - // Pure blend between start/end orientations - Quaternion outangles; - QuaternionBlend( pOlder->qRotation, pNewer->qRotation, frac, outangles ); - QuaternionAngles( outangles, step->m_angNetworkAngles ); + StepSimulationStep *pOlder = &step->m_Previous; + StepSimulationStep *pNewer = &step->m_Next; + + if (step->m_Discontinuity.nTickCount > step->m_Previous.nTickCount) + { + if (gpGlobals->tickcount > step->m_Discontinuity.nTickCount) + { + pOlder = &step->m_Discontinuity; + } + else + { + pNewer = &step->m_Discontinuity; + } + + tickdelta = pNewer->nTickCount - pOlder->nTickCount; + if ( tickdelta > 0 ) + { + frac = (float)( gpGlobals->tickcount - pOlder->nTickCount ) / (float) tickdelta; + frac = clamp( frac, 0.0f, 1.0f ); + } + } + + // Pure blend between start/end orientations + Quaternion outangles; + QuaternionBlend( pOlder->qRotation, pNewer->qRotation, frac, outangles ); + QuaternionAngles( outangles, step->m_angNetworkAngles ); + } + else + { + // FIXME: enable spline interpolation when turning is debounced. + Quaternion outangles; + Hermite_Spline( step->m_Previous2.qRotation, step->m_Previous.qRotation, step->m_Next.qRotation, frac, outangles ); + QuaternionAngles( outangles, step->m_angNetworkAngles ); + } + } + } + +} + + +//----------------------------------------------------------------------------- +bool CBaseEntity::UseStepSimulationNetworkOrigin( const Vector **out_v ) +{ + Assert( out_v ); + + + if ( g_bTestMoveTypeStepSimulation && + GetMoveType() == MOVETYPE_STEP && + HasDataObjectType( STEPSIMULATION ) ) + { + StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); + ComputeStepSimulationNetwork( step ); + *out_v = &step->m_vecNetworkOrigin; + + return step->m_bOriginActive; + } + + return false; +} + +//----------------------------------------------------------------------------- +bool CBaseEntity::UseStepSimulationNetworkAngles( const QAngle **out_a ) +{ + Assert( out_a ); + + if ( g_bTestMoveTypeStepSimulation && + GetMoveType() == MOVETYPE_STEP && + HasDataObjectType( STEPSIMULATION ) ) + { + StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); + ComputeStepSimulationNetwork( step ); + *out_a = &step->m_angNetworkAngles; + return step->m_bAnglesActive; + } + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool CBaseEntity::AddStepDiscontinuity( float flTime, const Vector &vecOrigin, const QAngle &vecAngles ) +{ + if ((GetMoveType() != MOVETYPE_STEP ) || !HasDataObjectType( STEPSIMULATION ) ) + { + return false; + } + + StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); + + if (!step) + { + Assert( 0 ); + return false; + } + + step->m_Discontinuity.nTickCount = TIME_TO_TICKS( flTime ); + step->m_Discontinuity.vecOrigin = vecOrigin; + AngleQuaternion( vecAngles, step->m_Discontinuity.qRotation ); + + return true; +} + + +Vector CBaseEntity::GetStepOrigin( void ) const +{ + return GetLocalOrigin(); +} + +QAngle CBaseEntity::GetStepAngles( void ) const +{ + return GetLocalAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from +// the recipient list. +// Input : filter - +//----------------------------------------------------------------------------- +void CBaseEntity::RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter ) +{ + int c = filter.GetRecipientCount(); + for ( int i = c - 1; i >= 0; --i ) + { + int playerIndex = filter.GetRecipientIndex( i ); + + CBasePlayer *player = static_cast< CBasePlayer * >( CBaseEntity::Instance( playerIndex ) ); + if ( !player ) + continue; +#if !defined( _XBOX ) + const char *cvarvalue = engine->GetClientConVarValue( playerIndex, "closecaption" ); + Assert( cvarvalue ); + if ( !cvarvalue[ 0 ] ) + continue; + + int value = atoi( cvarvalue ); +#else + static ConVar *s_pCloseCaption = NULL; + if ( !s_pCloseCaption ) + { + s_pCloseCaption = cvar->FindVar( "closecaption" ); + if ( !s_pCloseCaption ) + { + Error( "XBOX couldn't find closecaption convar!!!" ); } - else + } + + int value = s_pCloseCaption->GetInt(); +#endif + // No close captions? + if ( value == 0 ) + { + filter.RemoveRecipient( player ); + } + } +} + +#ifndef MAPBASE // Moved to SoundEmitterSystem.cpp +//----------------------------------------------------------------------------- +// Purpose: Wrapper to emit a sentence and also a close caption token for the sentence as appropriate. +// Input : filter - +// iEntIndex - +// iChannel - +// iSentenceIndex - +// flVolume - +// iSoundlevel - +// iFlags - +// iPitch - +// bUpdatePositions - +// soundtime - +//----------------------------------------------------------------------------- +void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, + float flVolume, soundlevel_t iSoundlevel, int iFlags /*= 0*/, int iPitch /*=PITCH_NORM*/, + const Vector *pOrigin /*=NULL*/, const Vector *pDirection /*=NULL*/, + bool bUpdatePositions /*=true*/, float soundtime /*=0.0f*/ ) +{ + CUtlVector< Vector > dummy; + enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex, + flVolume, iSoundlevel, iFlags, iPitch, 0, pOrigin, pDirection, &dummy, bUpdatePositions, soundtime ); +} +#endif + + +void CBaseEntity::SetRefEHandle( const CBaseHandle &handle ) +{ + m_RefEHandle = handle; + if ( edict() ) + { + COMPILE_TIME_ASSERT( NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS <= 8*sizeof( edict()->m_NetworkSerialNumber ) ); + edict()->m_NetworkSerialNumber = (m_RefEHandle.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1); + } +} + + +bool CPointEntity::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + { + Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +bool CServerOnlyPointEntity::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + { + Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +bool CLogicalEntity::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + { + Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets the entity invisible, and makes it remove itself on the next frame +//----------------------------------------------------------------------------- +void CBaseEntity::RemoveDeferred( void ) +{ + // Set our next think to remove us + SetThink( &CBaseEntity::SUB_Remove ); + SetNextThink( gpGlobals->curtime + 0.1f ); + + // Hide us completely + AddEffects( EF_NODRAW ); + AddSolidFlags( FSOLID_NOT_SOLID ); + SetMoveType( MOVETYPE_NONE ); +} + +#define MIN_CORPSE_FADE_TIME 10.0 +#define MIN_CORPSE_FADE_DIST 256.0 +#define MAX_CORPSE_FADE_DIST 1500.0 + +// +// fade out - slowly fades a entity out, then removes it. +// +// DON'T USE ME FOR GIBS AND STUFF IN MULTIPLAYER! +// SET A FUTURE THINK AND A RENDERMODE!! +void CBaseEntity::SUB_StartFadeOut( float delay, bool notSolid ) +{ + SetThink( &CBaseEntity::SUB_FadeOut ); + SetNextThink( gpGlobals->curtime + delay ); + SetRenderColorA( 255 ); + m_nRenderMode = kRenderNormal; + + if ( notSolid ) + { + AddSolidFlags( FSOLID_NOT_SOLID ); + SetLocalAngularVelocity( vec3_angle ); + } +} + +void CBaseEntity::SUB_StartFadeOutInstant() +{ + SUB_StartFadeOut( 0, true ); +} + +//----------------------------------------------------------------------------- +// Purpose: Vanish when players aren't looking +//----------------------------------------------------------------------------- +void CBaseEntity::SUB_Vanish( void ) +{ + //Always think again next frame + SetNextThink( gpGlobals->curtime + 0.1f ); + + CBasePlayer *pPlayer; + + //Get all players + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + //Get the next client + if ( ( pPlayer = UTIL_PlayerByIndex( i ) ) != NULL ) + { + Vector corpseDir = (GetAbsOrigin() - pPlayer->WorldSpaceCenter() ); + + float flDistSqr = corpseDir.LengthSqr(); + //If the player is close enough, don't fade out + if ( flDistSqr < (MIN_CORPSE_FADE_DIST*MIN_CORPSE_FADE_DIST) ) + return; + + // If the player's far enough away, we don't care about looking at it + if ( flDistSqr < (MAX_CORPSE_FADE_DIST*MAX_CORPSE_FADE_DIST) ) { - // FIXME: enable spline interpolation when turning is debounced. - Quaternion outangles; - Hermite_Spline( step->m_Previous2.qRotation, step->m_Previous.qRotation, step->m_Next.qRotation, frac, outangles ); - QuaternionAngles( outangles, step->m_angNetworkAngles ); + VectorNormalize( corpseDir ); + + Vector plForward; + pPlayer->EyeVectors( &plForward ); + + float dot = plForward.Dot( corpseDir ); + + if ( dot > 0.0f ) + return; } } } + //If we're here, then we can vanish safely + m_iHealth = 0; + SetThink( &CBaseEntity::SUB_Remove ); +} + +void CBaseEntity::SUB_PerformFadeOut( void ) +{ + float dt = gpGlobals->frametime; + if ( dt > 0.1f ) + { + dt = 0.1f; + } + m_nRenderMode = kRenderTransTexture; + int speed = MAX(1,256*dt); // fade out over 1 second + SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) ); +} + +bool CBaseEntity::SUB_AllowedToFade( void ) +{ + if( VPhysicsGetObject() ) + { + if( VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD || GetEFlags() & EFL_IS_BEING_LIFTED_BY_BARNACLE ) + return false; + } + + // on Xbox, allow these to fade out +#ifndef _XBOX + CBasePlayer *pPlayer = ( AI_IsSinglePlayer() ) ? UTIL_GetLocalPlayer() : NULL; + + if ( pPlayer && pPlayer->FInViewCone( this ) ) + return false; +#endif + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Fade out slowly +//----------------------------------------------------------------------------- +void CBaseEntity::SUB_FadeOut( void ) +{ + if ( SUB_AllowedToFade() == false ) + { + SetNextThink( gpGlobals->curtime + 1 ); + SetRenderColorA( 255 ); + return; + } + + SUB_PerformFadeOut(); + + if ( m_clrRender->a == 0 ) + { +#ifdef MAPBASE + // This was meant for KillWhenNotVisible before it used its own function, + // but there's not really any harm for keeping this here. + m_OnKilled.FireOutput(this, this); +#endif + UTIL_Remove(this); + } + else + { + SetNextThink( gpGlobals->curtime ); + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: For KillWhenNotVisible, based off of SUB_FadeOut +//----------------------------------------------------------------------------- +void CBaseEntity::SUB_RemoveWhenNotVisible( void ) +{ + if ( SUB_AllowedToFade() == false ) + { + SetNextThink( gpGlobals->curtime + 1, "SUB_RemoveWhenNotVisible" ); + SetRenderColorA( 255 ); + return; + } + + SetRenderColorA( m_clrRender->a - 1 ); + + if ( m_clrRender->a == 0 ) + { + m_OnKilled.FireOutput(this, this); + UTIL_Remove(this); + } + else + { + SetNextThink( gpGlobals->curtime, "SUB_RemoveWhenNotVisible" ); + } } +#endif -//----------------------------------------------------------------------------- -bool CBaseEntity::UseStepSimulationNetworkOrigin( const Vector **out_v ) +inline bool AnyPlayersInHierarchy_R( CBaseEntity *pEnt ) { - Assert( out_v ); - + if ( pEnt->IsPlayer() ) + return true; - if ( g_bTestMoveTypeStepSimulation && - GetMoveType() == MOVETYPE_STEP && - HasDataObjectType( STEPSIMULATION ) ) + for ( CBaseEntity *pCur = pEnt->FirstMoveChild(); pCur; pCur=pCur->NextMovePeer() ) { - StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); - ComputeStepSimulationNetwork( step ); - *out_v = &step->m_vecNetworkOrigin; - - return step->m_bOriginActive; + if ( AnyPlayersInHierarchy_R( pCur ) ) + return true; } return false; } -//----------------------------------------------------------------------------- -bool CBaseEntity::UseStepSimulationNetworkAngles( const QAngle **out_a ) + +void CBaseEntity::RecalcHasPlayerChildBit() { - Assert( out_a ); + if ( AnyPlayersInHierarchy_R( this ) ) + AddEFlags( EFL_HAS_PLAYER_CHILD ); + else + RemoveEFlags( EFL_HAS_PLAYER_CHILD ); +} - if ( g_bTestMoveTypeStepSimulation && - GetMoveType() == MOVETYPE_STEP && - HasDataObjectType( STEPSIMULATION ) ) - { - StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); - ComputeStepSimulationNetwork( step ); - *out_a = &step->m_angNetworkAngles; - return step->m_bAnglesActive; - } - return false; + +bool CBaseEntity::DoesHavePlayerChild() +{ + return IsEFlagSet( EFL_HAS_PLAYER_CHILD ); } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBaseEntity::AddStepDiscontinuity( float flTime, const Vector &vecOrigin, const QAngle &vecAngles ) +//------------------------------------------------------------------------------ +void CBaseEntity::IncrementInterpolationFrame() { - if ((GetMoveType() != MOVETYPE_STEP ) || !HasDataObjectType( STEPSIMULATION ) ) - { - return false; - } + m_ubInterpolationFrame = (m_ubInterpolationFrame + 1) % NOINTERP_PARITY_MAX; +} - StepSimulationData *step = ( StepSimulationData * )GetDataObject( STEPSIMULATION ); +//------------------------------------------------------------------------------ - if (!step) +void CBaseEntity::OnModelLoadComplete( const model_t* model ) +{ + Assert( m_bDynamicModelPending && IsDynamicModelIndex( m_nModelIndex ) ); + Assert( model == modelinfo->GetModel( m_nModelIndex ) ); + + m_bDynamicModelPending = false; + + if ( m_bDynamicModelSetBounds ) { - Assert( 0 ); - return false; + m_bDynamicModelSetBounds = false; + SetCollisionBoundsFromModel(); } - step->m_Discontinuity.nTickCount = TIME_TO_TICKS( flTime ); - step->m_Discontinuity.vecOrigin = vecOrigin; - AngleQuaternion( vecAngles, step->m_Discontinuity.qRotation ); - - return true; + OnNewModel(); } +//------------------------------------------------------------------------------ -Vector CBaseEntity::GetStepOrigin( void ) const -{ - return GetLocalOrigin(); +void CBaseEntity::SetCollisionBoundsFromModel() +{ + if ( IsDynamicModelLoading() ) + { + m_bDynamicModelSetBounds = true; + return; + } + + if ( const model_t *pModel = GetModel() ) + { + Vector mns, mxs; + modelinfo->GetModelBounds( pModel, mns, mxs ); + UTIL_SetSize( this, mns, mxs ); + } } -QAngle CBaseEntity::GetStepAngles( void ) const + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::GetScriptInstance() { - return GetLocalAngles(); + if (!m_hScriptInstance) + { + if (m_iszScriptId == NULL_STRING) + { + char* szName = (char*)stackalloc(1024); + g_pScriptVM->GenerateUniqueKey((m_iName.Get() != NULL_STRING) ? STRING(GetEntityName()) : GetClassname(), szName, 1024); + m_iszScriptId = AllocPooledString(szName); + } + + m_hScriptInstance = g_pScriptVM->RegisterInstance(GetScriptDesc(), this); + g_pScriptVM->SetInstanceUniqeId(m_hScriptInstance, STRING(m_iszScriptId)); + } + return m_hScriptInstance; } //----------------------------------------------------------------------------- -// Purpose: For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from -// the recipient list. -// Input : filter - +// Using my edict, cook up a unique VScript scope that's private to me, and +// persistent. //----------------------------------------------------------------------------- -void CBaseEntity::RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter ) +bool CBaseEntity::ValidateScriptScope() { - int c = filter.GetRecipientCount(); - for ( int i = c - 1; i >= 0; --i ) + if (!m_ScriptScope.IsInitialized()) { - int playerIndex = filter.GetRecipientIndex( i ); - - CBasePlayer *player = static_cast< CBasePlayer * >( CBaseEntity::Instance( playerIndex ) ); - if ( !player ) - continue; -#if !defined( _XBOX ) - const char *cvarvalue = engine->GetClientConVarValue( playerIndex, "closecaption" ); - Assert( cvarvalue ); - if ( !cvarvalue[ 0 ] ) - continue; + if (scriptmanager == NULL) + { + ExecuteOnce(DevMsg("Cannot execute script because scripting is disabled (-scripting)\n")); + return false; + } - int value = atoi( cvarvalue ); -#else - static ConVar *s_pCloseCaption = NULL; - if ( !s_pCloseCaption ) + if (g_pScriptVM == NULL) { - s_pCloseCaption = cvar->FindVar( "closecaption" ); - if ( !s_pCloseCaption ) - { - Error( "XBOX couldn't find closecaption convar!!!" ); - } + ExecuteOnce(DevMsg(" Cannot execute script because there is no available VM\n")); + return false; } - int value = s_pCloseCaption->GetInt(); -#endif - // No close captions? - if ( value == 0 ) + // Force instance creation + GetScriptInstance(); + + EHANDLE hThis; + hThis.Set(this); + + bool bResult = m_ScriptScope.Init(STRING(m_iszScriptId)); + + if (!bResult) { - filter.RemoveRecipient( player ); + DevMsg("%s couldn't create ScriptScope!\n", GetDebugName()); + return false; } + g_pScriptVM->SetValue(m_ScriptScope, "self", GetScriptInstance()); } + return true; } //----------------------------------------------------------------------------- -// Purpose: Wrapper to emit a sentence and also a close caption token for the sentence as appropriate. -// Input : filter - -// iEntIndex - -// iChannel - -// iSentenceIndex - -// flVolume - -// iSoundlevel - -// iFlags - -// iPitch - -// bUpdatePositions - -// soundtime - -//----------------------------------------------------------------------------- -void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, - float flVolume, soundlevel_t iSoundlevel, int iFlags /*= 0*/, int iPitch /*=PITCH_NORM*/, - const Vector *pOrigin /*=NULL*/, const Vector *pDirection /*=NULL*/, - bool bUpdatePositions /*=true*/, float soundtime /*=0.0f*/ ) +// Purpose: Run all of the vscript files that are set in this entity's VSCRIPTS +// field in Hammer. The list is space-delimited. +//----------------------------------------------------------------------------- +void CBaseEntity::RunVScripts() { - CUtlVector< Vector > dummy; - enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex, - flVolume, iSoundlevel, iFlags, iPitch, 0, pOrigin, pDirection, &dummy, bUpdatePositions, soundtime ); -} - + if (m_iszVScripts == NULL_STRING) + { + return; + } -void CBaseEntity::SetRefEHandle( const CBaseHandle &handle ) -{ - m_RefEHandle = handle; - if ( edict() ) +#ifdef MAPBASE_VSCRIPT + if (g_pScriptVM == NULL) { - COMPILE_TIME_ASSERT( NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS <= 8*sizeof( edict()->m_NetworkSerialNumber ) ); - edict()->m_NetworkSerialNumber = m_RefEHandle.GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); + return; } -} +#endif + ValidateScriptScope(); -bool CPointEntity::KeyValue( const char *szKeyName, const char *szValue ) -{ - if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + // All functions we want to have call chained instead of overwritten + // by other scripts in this entities list. + static const char* sCallChainFunctions[] = { - Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); - return true; - } + "OnPostSpawn", + "Precache" + }; - return BaseClass::KeyValue( szKeyName, szValue ); -} + ScriptLanguage_t language = g_pScriptVM->GetLanguage(); -bool CServerOnlyPointEntity::KeyValue( const char *szKeyName, const char *szValue ) -{ - if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + // Make a call chainer for each in this entities scope + for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j) { - Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); - return true; + + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter + HSCRIPT hCreateChainScript = g_pScriptVM->CompileScript(CFmtStr("%sCallChain <- CSimpleCallChainer(\"%s\", self.GetScriptScope(), true)", sCallChainFunctions[j], sCallChainFunctions[j])); + g_pScriptVM->Run(hCreateChainScript, (HSCRIPT)m_ScriptScope); + } } - return BaseClass::KeyValue( szKeyName, szValue ); -} + char szScriptsList[255]; + Q_strcpy(szScriptsList, STRING(m_iszVScripts)); + CUtlStringList szScripts; -bool CLogicalEntity::KeyValue( const char *szKeyName, const char *szValue ) -{ - if ( FStrEq( szKeyName, "mins" ) || FStrEq( szKeyName, "maxs" ) ) + V_SplitString(szScriptsList, " ", szScripts); + + for (int i = 0; i < szScripts.Count(); i++) { - Warning("Warning! Can't specify mins/maxs for point entities! (%s)\n", GetClassname() ); - return true; +#ifdef MAPBASE + CGMsg( 0, CON_GROUP_VSCRIPT, "%s executing script: %s\n", GetDebugName(), szScripts[i] ); +#else + Log( "%s executing script: %s\n", GetDebugName(), szScripts[i]); +#endif + + RunScriptFile(szScripts[i], IsWorld()); + + for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j) + { + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter. + HSCRIPT hRunPostScriptExecute = g_pScriptVM->CompileScript(CFmtStr("%sCallChain.PostScriptExecute()", sCallChainFunctions[j])); + g_pScriptVM->Run(hRunPostScriptExecute, (HSCRIPT)m_ScriptScope); + } + } } - return BaseClass::KeyValue( szKeyName, szValue ); + if (m_iszScriptThinkFunction != NULL_STRING) + { + SetContextThink(&CBaseEntity::ScriptThink, gpGlobals->curtime + sv_script_think_interval.GetFloat(), "ScriptThink"); + } } -//----------------------------------------------------------------------------- -// Purpose: Sets the entity invisible, and makes it remove itself on the next frame -//----------------------------------------------------------------------------- -void CBaseEntity::RemoveDeferred( void ) +//-------------------------------------------------------------------------------------------------- +// This is called during entity spawning and after restore to allow scripts to precache any +// resources they need. +//-------------------------------------------------------------------------------------------------- +void CBaseEntity::RunPrecacheScripts(void) { - // Set our next think to remove us - SetThink( &CBaseEntity::SUB_Remove ); - SetNextThink( gpGlobals->curtime + 0.1f ); + if (m_iszVScripts == NULL_STRING) + { + return; + } - // Hide us completely - AddEffects( EF_NODRAW ); - AddSolidFlags( FSOLID_NOT_SOLID ); - SetMoveType( MOVETYPE_NONE ); -} +#ifdef MAPBASE_VSCRIPT + if (g_pScriptVM == NULL) + { + return; + } +#endif -#define MIN_CORPSE_FADE_TIME 10.0 -#define MIN_CORPSE_FADE_DIST 256.0 -#define MAX_CORPSE_FADE_DIST 1500.0 + HSCRIPT hScriptPrecache = m_ScriptScope.LookupFunction("DispatchPrecache"); + if (hScriptPrecache) + { + g_pScriptVM->Call(hScriptPrecache, m_ScriptScope); + m_ScriptScope.ReleaseFunction(hScriptPrecache); + } +} -// -// fade out - slowly fades a entity out, then removes it. -// -// DON'T USE ME FOR GIBS AND STUFF IN MULTIPLAYER! -// SET A FUTURE THINK AND A RENDERMODE!! -void CBaseEntity::SUB_StartFadeOut( float delay, bool notSolid ) +void CBaseEntity::RunOnPostSpawnScripts(void) { - SetThink( &CBaseEntity::SUB_FadeOut ); - SetNextThink( gpGlobals->curtime + delay ); - SetRenderColorA( 255 ); - m_nRenderMode = kRenderNormal; + if (m_iszVScripts == NULL_STRING) + { + return; + } - if ( notSolid ) +#ifdef MAPBASE_VSCRIPT + if (g_pScriptVM == NULL) { - AddSolidFlags( FSOLID_NOT_SOLID ); - SetLocalAngularVelocity( vec3_angle ); + return; + } +#endif + + HSCRIPT hFuncConnect = g_pScriptVM->LookupFunction("ConnectOutputs"); + if (hFuncConnect) + { + g_pScriptVM->Call(hFuncConnect, NULL, true, NULL, (HSCRIPT)m_ScriptScope); + g_pScriptVM->ReleaseFunction(hFuncConnect); + } + + HSCRIPT hFuncDisp = m_ScriptScope.LookupFunction("DispatchOnPostSpawn"); + if (hFuncDisp) + { + variant_t variant; + variant.SetString(MAKE_STRING("DispatchOnPostSpawn")); + g_EventQueue.AddEvent(this, "CallScriptFunction", variant, 0, this, this); + m_ScriptScope.ReleaseFunction(hFuncDisp); + } } -void CBaseEntity::SUB_StartFadeOutInstant() +#ifndef MAPBASE_VSCRIPT // This is shared now +HSCRIPT CBaseEntity::GetScriptOwnerEntity() +{ + return ToHScript(GetOwnerEntity()); +} + +void CBaseEntity::SetScriptOwnerEntity(HSCRIPT pOwner) { - SUB_StartFadeOut( 0, true ); + SetOwnerEntity(ToEnt(pOwner)); } +#endif //----------------------------------------------------------------------------- -// Purpose: Vanish when players aren't looking +// VScript access to model's key values +// for iteration and value access, use: +// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString, +// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey //----------------------------------------------------------------------------- -void CBaseEntity::SUB_Vanish( void ) +HSCRIPT CBaseEntity::ScriptGetModelKeyValues( void ) { - //Always think again next frame - SetNextThink( gpGlobals->curtime + 0.1f ); - - CBasePlayer *pPlayer; + KeyValues *pModelKeyValues = new KeyValues(""); + HSCRIPT hScript = NULL; + const char *pszModelName = modelinfo->GetModelName( GetModel() ); + const char *pBuffer = modelinfo->GetModelKeyValueText( GetModel() ) ; - //Get all players - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + if ( pModelKeyValues->LoadFromBuffer( pszModelName, pBuffer ) ) { - //Get the next client - if ( ( pPlayer = UTIL_PlayerByIndex( i ) ) != NULL ) - { - Vector corpseDir = (GetAbsOrigin() - pPlayer->WorldSpaceCenter() ); - - float flDistSqr = corpseDir.LengthSqr(); - //If the player is close enough, don't fade out - if ( flDistSqr < (MIN_CORPSE_FADE_DIST*MIN_CORPSE_FADE_DIST) ) - return; - - // If the player's far enough away, we don't care about looking at it - if ( flDistSqr < (MAX_CORPSE_FADE_DIST*MAX_CORPSE_FADE_DIST) ) - { - VectorNormalize( corpseDir ); + // UNDONE: how does destructor get called on this +#ifdef MAPBASE_VSCRIPT + m_pScriptModelKeyValues = hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pModelKeyValues, true ); // Allow VScript to delete this when the instance is removed. +#else + m_pScriptModelKeyValues = new CScriptKeyValues( pModelKeyValues ); +#endif - Vector plForward; - pPlayer->EyeVectors( &plForward ); + // UNDONE: who calls ReleaseInstance on this??? Does name need to be unique??? - float dot = plForward.Dot( corpseDir ); +#ifndef MAPBASE_VSCRIPT + hScript = g_pScriptVM->RegisterInstance( m_pScriptModelKeyValues ); +#endif - if ( dot > 0.0f ) - return; + /* + KeyValues *pParticleEffects = pModelKeyValues->FindKey("Particles"); + if ( pParticleEffects ) + { + // Start grabbing the sounds and slotting them in + for ( KeyValues *pSingleEffect = pParticleEffects->GetFirstSubKey(); pSingleEffect; pSingleEffect = pSingleEffect->GetNextKey() ) + { + const char *pParticleEffectName = pSingleEffect->GetString( "name", "" ); + PrecacheParticleSystem( pParticleEffectName ); } } + */ } - //If we're here, then we can vanish safely - m_iHealth = 0; - SetThink( &CBaseEntity::SUB_Remove ); + return hScript; } -void CBaseEntity::SUB_PerformFadeOut( void ) +void CBaseEntity::ScriptSetLocalAngularVelocity(float pitchVel, float yawVel, float rollVel) { - float dt = gpGlobals->frametime; - if ( dt > 0.1f ) - { - dt = 0.1f; - } - m_nRenderMode = kRenderTransTexture; - int speed = MAX(1,256*dt); // fade out over 1 second - SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) ); + QAngle qa; + qa.Init(pitchVel, yawVel, rollVel); + SetLocalAngularVelocity(qa); } -bool CBaseEntity::SUB_AllowedToFade( void ) +const Vector& CBaseEntity::ScriptGetLocalAngularVelocity(void) { - if( VPhysicsGetObject() ) - { - if( VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD || GetEFlags() & EFL_IS_BEING_LIFTED_BY_BARNACLE ) - return false; - } - - // on Xbox, allow these to fade out -#ifndef _XBOX - CBasePlayer *pPlayer = ( AI_IsSinglePlayer() ) ? UTIL_GetLocalPlayer() : NULL; + QAngle qa = GetLocalAngularVelocity(); + static Vector v; + v.x = qa.x; + v.y = qa.y; + v.z = qa.z; + return v; +} - if ( pPlayer && pPlayer->FInViewCone( this ) ) - return false; -#endif +//----------------------------------------------------------------------------- +// Vscript: Gets the min collision bounds, centered on object +//----------------------------------------------------------------------------- +const Vector& CBaseEntity::ScriptGetBoundingMins(void) +{ + return m_Collision.OBBMins(); +} - return true; +//----------------------------------------------------------------------------- +// Vscript: Gets the max collision bounds, centered on object +//----------------------------------------------------------------------------- +const Vector& CBaseEntity::ScriptGetBoundingMaxs(void) +{ + return m_Collision.OBBMaxs(); } +#ifdef MAPBASE_VSCRIPT //----------------------------------------------------------------------------- -// Purpose: Fade out slowly //----------------------------------------------------------------------------- -void CBaseEntity::SUB_FadeOut( void ) +int CBaseEntity::ScriptTakeDamage( HSCRIPT pInfo ) { - if ( SUB_AllowedToFade() == false ) + CTakeDamageInfo *info = HScriptToClass< CTakeDamageInfo >( pInfo ); + if ( info ) { - SetNextThink( gpGlobals->curtime + 1 ); - SetRenderColorA( 255 ); - return; + return OnTakeDamage( *info ); } - - SUB_PerformFadeOut(); - if ( m_clrRender->a == 0 ) - { - UTIL_Remove(this); - } - else - { - SetNextThink( gpGlobals->curtime ); - } + return 0; } - -inline bool AnyPlayersInHierarchy_R( CBaseEntity *pEnt ) +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptFireBullets( HSCRIPT pInfo ) { - if ( pEnt->IsPlayer() ) - return true; - - for ( CBaseEntity *pCur = pEnt->FirstMoveChild(); pCur; pCur=pCur->NextMovePeer() ) + FireBulletsInfo_t *info = HScriptToClass< FireBulletsInfo_t >( pInfo ); + if ( info ) { - if ( AnyPlayersInHierarchy_R( pCur ) ) - return true; + FireBullets( *info ); } - - return false; } - -void CBaseEntity::RecalcHasPlayerChildBit() +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptAddContext( const char *name, const char *value, float duration ) { - if ( AnyPlayersInHierarchy_R( this ) ) - AddEFlags( EFL_HAS_PLAYER_CHILD ); - else - RemoveEFlags( EFL_HAS_PLAYER_CHILD ); + AddContext( name, value, duration ); } - -bool CBaseEntity::DoesHavePlayerChild() +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char *CBaseEntity::ScriptGetContext( const char *name ) { - return IsEFlagSet( EFL_HAS_PLAYER_CHILD ); + return GetContextValue( name ); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptGetContextIndex( int index ) +{ + if (index >= m_ResponseContexts.Count()) + return NULL; + + ScriptVariant_t varTable; + g_pScriptVM->CreateTable( varTable ); -//------------------------------------------------------------------------------ -void CBaseEntity::IncrementInterpolationFrame() + g_pScriptVM->SetValue( varTable, "name", STRING( m_ResponseContexts[index].m_iszName ) ); + g_pScriptVM->SetValue( varTable, "value", STRING( m_ResponseContexts[index].m_iszValue ) ); + g_pScriptVM->SetValue( varTable, "expiration_time", m_ResponseContexts[index].m_fExpirationTime ); + + return varTable.m_hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CBaseEntity::ScriptClassify( void ) { - m_ubInterpolationFrame = (m_ubInterpolationFrame + 1) % NOINTERP_PARITY_MAX; + return (int)Classify(); } -//------------------------------------------------------------------------------ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CBaseEntity::ScriptAddOutput( const char *pszOutputName, const char *pszTarget, const char *pszAction, const char *pszParameter, float flDelay, int iMaxTimes ) +{ + const char *pszValue = UTIL_VarArgs("%s,%s,%s,%f,%i", pszTarget, pszAction, pszParameter, flDelay, iMaxTimes); + return KeyValue( pszOutputName, pszValue ); +} -void CBaseEntity::OnModelLoadComplete( const model_t* model ) +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char *CBaseEntity::ScriptGetKeyValue( const char *pszKeyName ) { - Assert( m_bDynamicModelPending && IsDynamicModelIndex( m_nModelIndex ) ); - Assert( model == modelinfo->GetModel( m_nModelIndex ) ); - - m_bDynamicModelPending = false; - - if ( m_bDynamicModelSetBounds ) - { - m_bDynamicModelSetBounds = false; - SetCollisionBoundsFromModel(); - } + static char szValue[128]; + GetKeyValue( pszKeyName, szValue, sizeof(szValue) ); + return szValue; +} - OnNewModel(); +//----------------------------------------------------------------------------- +// Vscript: Dispatch an interaction to the entity +//----------------------------------------------------------------------------- +bool CBaseEntity::ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt ) +{ + return DispatchInteraction( interactionType, data, ToEnt( sourceEnt ) ? ToEnt( sourceEnt )->MyCombatCharacterPointer() : NULL ); } +#endif -//------------------------------------------------------------------------------ -void CBaseEntity::SetCollisionBoundsFromModel() +#ifdef MAPBASE +extern int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 ); + +//------------------------------------------------------------------------------ +// Purpose: Create an entity of the given type +//------------------------------------------------------------------------------ +class CEntCreateAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback { - if ( IsDynamicModelLoading() ) +public: + virtual bool CreateAimed() { return false; } + + virtual void CommandCallback( const CCommand &args ) { - m_bDynamicModelSetBounds = true; - return; + MDLCACHE_CRITICAL_SECTION(); + + CBasePlayer *pPlayer = UTIL_GetCommandClient(); + if (!pPlayer) + { + return; + } + + // Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire + if ( !Q_stricmp( args[1], "point_servercommand" ) ) + { + if ( engine->IsDedicatedServer() ) + { + // We allow people with disabled autokick to do it, because they already have rcon. + if ( pPlayer->IsAutoKickDisabled() == false ) + return; + } + else if ( gpGlobals->maxClients > 1 ) + { + // On listen servers with more than 1 player, only allow the host to create point_servercommand. + CBasePlayer *pHostPlayer = UTIL_GetListenServerHost(); + if ( pPlayer != pHostPlayer ) + return; + } + } + + bool allowPrecache = CBaseEntity::IsPrecacheAllowed(); + CBaseEntity::SetAllowPrecache( true ); + + // Try to create entity + CBaseEntity *entity = dynamic_cast< CBaseEntity * >( CreateEntityByName(args[1]) ); + if (entity) + { + // Pass in any additional parameters. + for ( int i = 2; i + 1 < args.ArgC(); i += 2 ) + { + const char *pKeyName = args[i]; + const char *pValue = args[i+1]; + entity->KeyValue( pKeyName, pValue ); + } + + DispatchSpawn(entity); + + // Now attempt to drop into the world + trace_t tr; + Vector forward; + pPlayer->EyeVectors( &forward ); + + // Pass through the player's vehicle + CTraceFilterSkipTwoEntities filter( pPlayer, pPlayer->GetVehicleEntity(), COLLISION_GROUP_NONE ); + UTIL_TraceLine(pPlayer->EyePosition(), + pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_SOLID, + &filter, &tr ); + + if ( tr.fraction != 1.0 ) + { + // Raise the end position a little up off the floor, place the npc and drop him down + tr.endpos.z += 12; + + if (CreateAimed()) + { + QAngle angles; + VectorAngles( forward, angles ); + angles.x = 0; + angles.z = 0; + entity->Teleport( &tr.endpos, &angles, NULL ); + } + else + { + entity->Teleport( &tr.endpos, NULL, NULL ); + } + + UTIL_DropToFloor( entity, MASK_SOLID ); + } + + entity->Activate(); + } + CBaseEntity::SetAllowPrecache( allowPrecache ); } - if ( const model_t *pModel = GetModel() ) + virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) { - Vector mns, mxs; - modelinfo->GetModelBounds( pModel, mns, mxs ); - UTIL_SetSize( this, mns, mxs ); + if ( !g_pGameRules ) + { + return 0; + } + + const char *cmdname = CreateAimed() ? "ent_create_aimed" : "ent_create"; + + char *substring = (char *)partial; + if ( Q_strstr( partial, cmdname ) ) + { + substring = (char *)partial + strlen( cmdname ) + 1; + } + + int checklen = Q_strlen( substring ); + + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return EntityFactory_AutoComplete( cmdname, commands, symbols, substring, checklen ); } -} +}; + +static CEntCreateAutoCompletionFunctor g_EntCreateAutoComplete; +static ConCommand ent_create("ent_create", &g_EntCreateAutoComplete, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create ... ", FCVAR_GAMEDLL | FCVAR_CHEAT, &g_EntCreateAutoComplete); +class CEntCreateAimedAutoCompletionFunctor : public CEntCreateAutoCompletionFunctor +{ +public: + virtual bool CreateAimed() { return true; } +}; + +static CEntCreateAimedAutoCompletionFunctor g_EntCreateAimedAutoComplete; +static ConCommand ent_create_aimed("ent_create_aimed", &g_EntCreateAimedAutoComplete, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create_aimed ... ", FCVAR_CHEAT, &g_EntCreateAimedAutoComplete); +#else //------------------------------------------------------------------------------ // Purpose: Create an NPC of the given type //------------------------------------------------------------------------------ @@ -7354,7 +10494,7 @@ void CC_Ent_Create( const CCommand& args ) Vector forward; pPlayer->EyeVectors( &forward ); UTIL_TraceLine(pPlayer->EyePosition(), - pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_SOLID, + pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction != 1.0 ) { @@ -7369,6 +10509,7 @@ void CC_Ent_Create( const CCommand& args ) CBaseEntity::SetAllowPrecache( allowPrecache ); } static ConCommand ent_create("ent_create", CC_Ent_Create, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create ... ", FCVAR_GAMEDLL | FCVAR_CHEAT); +#endif //------------------------------------------------------------------------------ // Purpose: Teleport a specified entity to where the player is looking @@ -7408,7 +10549,7 @@ bool CC_GetCommandEnt( const CCommand& args, CBaseEntity **ent, Vector *vecTarge Vector forward; pPlayer->EyeVectors( &forward ); UTIL_TraceLine(pPlayer->EyePosition(), - pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID, + pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction != 1.0 ) @@ -7425,6 +10566,51 @@ bool CC_GetCommandEnt( const CCommand& args, CBaseEntity **ent, Vector *vecTarge return true; } +#ifdef MAPBASE +class CEntTeleportAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback +{ +public: + virtual void CommandCallback( const CCommand &command ) + { + if ( command.ArgC() < 2 ) + { + Msg( "Format: ent_teleport \n" ); + return; + } + + CBaseEntity *pEnt; + Vector vecTargetPoint; + if ( CC_GetCommandEnt( command, &pEnt, &vecTargetPoint, NULL ) ) + { + pEnt->Teleport( &vecTargetPoint, NULL, NULL ); + } + } + + virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) + { + if ( !g_pGameRules ) + { + return 0; + } + + const char *cmdname = "ent_teleport"; + + char *substring = (char *)partial; + if ( Q_strstr( partial, cmdname ) ) + { + substring = (char *)partial + strlen( cmdname ) + 1; + } + + int checklen = Q_strlen( substring ); + + CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc ); + return AutoCompleteEntities(cmdname, commands, symbols, substring, checklen); + } +}; + +static CEntTeleportAutoCompletionFunctor g_EntTeleportAutoComplete; +static ConCommand ent_teleport("ent_teleport", &g_EntTeleportAutoComplete, "Teleport the specified entity to where the player is looking.\n\tFormat: ent_teleport ", FCVAR_CHEAT, &g_EntTeleportAutoComplete); +#else //------------------------------------------------------------------------------ // Purpose: Teleport a specified entity to where the player is looking //------------------------------------------------------------------------------ @@ -7445,6 +10631,7 @@ void CC_Ent_Teleport( const CCommand& args ) } static ConCommand ent_teleport("ent_teleport", CC_Ent_Teleport, "Teleport the specified entity to where the player is looking.\n\tFormat: ent_teleport ", FCVAR_CHEAT); +#endif //------------------------------------------------------------------------------ // Purpose: Orient a specified entity to match the player's angles diff --git a/game/server/baseentity.h b/game/server/baseentity.h index b2caa6b5..f4ea5983 100644 --- a/game/server/baseentity.h +++ b/game/server/baseentity.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -20,14 +20,23 @@ #include "ServerNetworkProperty.h" #include "shareddefs.h" #include "engine/ivmodelinfo.h" +#ifdef NEW_RESPONSE_SYSTEM +#include "AI_Criteria.h" +#include "AI_ResponseSystem.h" +#endif + +#include "vscript/ivscript.h" +#include "vscript_server.h" class CDamageModifier; class CDmgAccumulator; struct CSoundParameters; +#ifndef NEW_RESPONSE_SYSTEM class AI_CriteriaSet; class IResponseSystem; +#endif class IEntitySaveUtils; class CRecipientFilter; class CStudioHdr; @@ -36,6 +45,11 @@ class CStudioHdr; // FIXME: Could do this in the script file by making it required and bumping up weighting there instead... #define CONCEPT_WEIGHT 5.0f +#ifdef NEW_RESPONSE_SYSTEM +// Relax the namespace standard a bit so that less code has to be changed +#define IResponseSystem ResponseRules::IResponseSystem +#endif + typedef CHandle EHANDLE; #define MANUALMODE_GETSET_PROP(type, accessorName, varName) \ @@ -82,8 +96,9 @@ typedef struct KeyValueData_s KeyValueData; class CUserCmd; class CSkyCamera; class CEntityMapData; +class CWorld; class INextBot; -class IHasAttributes; + typedef CUtlVector< CBaseEntity* > EntityList_t; @@ -92,26 +107,28 @@ typedef CUtlVector< CBaseEntity* > EntityList_t; // For CLASSIFY enum Class_T { - CLASS_NONE=0, - CLASS_PLAYER, + CLASS_NONE=0, + CLASS_PLAYER, CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY_VITAL, CLASS_ANTLION, CLASS_BARNACLE, CLASS_BULLSEYE, - CLASS_BULLSQUID, - CLASS_CITIZEN_PASSIVE, + //CLASS_BULLSQUID, + CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_REBEL, CLASS_COMBINE, CLASS_COMBINE_GUNSHIP, CLASS_CONSCRIPT, CLASS_HEADCRAB, +#ifdef VANCE CLASS_HOUNDEYE, +#endif CLASS_MANHACK, - CLASS_METROPOLICE, - CLASS_MILITARY, - CLASS_SCANNER, - CLASS_STALKER, + CLASS_METROPOLICE, + CLASS_MILITARY, + CLASS_SCANNER, + CLASS_STALKER, CLASS_VORTIGAUNT, CLASS_ZOMBIE, CLASS_PROTOSNIPER, @@ -150,14 +167,14 @@ enum Class_T enum Class_T { CLASS_NONE = 0, - CLASS_PLAYER, + CLASS_PLAYER, CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY_VITAL, CLASS_ANTLION, CLASS_BARNACLE, CLASS_BULLSEYE, - //CLASS_BULLSQUID, - CLASS_CITIZEN_PASSIVE, + //CLASS_BULLSQUID, + CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_REBEL, CLASS_COMBINE, CLASS_COMBINE_GUNSHIP, @@ -165,10 +182,10 @@ enum Class_T CLASS_HEADCRAB, //CLASS_HOUNDEYE, CLASS_MANHACK, - CLASS_METROPOLICE, - CLASS_MILITARY, - CLASS_SCANNER, - CLASS_STALKER, + CLASS_METROPOLICE, + CLASS_MILITARY, + CLASS_SCANNER, + CLASS_STALKER, CLASS_VORTIGAUNT, CLASS_ZOMBIE, CLASS_PROTOSNIPER, @@ -298,7 +315,7 @@ enum DebugOverlayBits_t struct TimedOverlay_t; -/* ========= CBaseEntity ======== +/* ========= CBaseEntity ======== All objects in the game are derived from this. @@ -306,16 +323,18 @@ a list of all CBaseEntitys is kept in gEntList ================================ */ // creates an entity by string name, but does not spawn it -// If iForceEdictIndex is not -1, then it will use the edict by that index. If the index is +// If iForceEdictIndex is not -1, then it will use the edict by that index. If the index is // invalid or there is already an edict using that index, it will error out. CBaseEntity *CreateEntityByName( const char *className, int iForceEdictIndex = -1 ); CBaseNetworkable *CreateNetworkableByName( const char *className ); +CBaseEntity* ToEnt(HSCRIPT hScript); + // creates an entity and calls all the necessary spawn functions extern void SpawnEntityByName( const char *className, CEntityMapData *mapData = NULL ); // calls the spawn functions for an entity -extern int DispatchSpawn( CBaseEntity *pEntity ); +extern int DispatchSpawn( CBaseEntity *pEntity, bool bRunVScripts = true); inline CBaseEntity *GetContainingEntity( edict_t *pent ); @@ -332,6 +351,16 @@ struct thinkfunc_t DECLARE_SIMPLE_DATADESC(); }; +#ifdef MAPBASE_VSCRIPT +struct scriptthinkfunc_t +{ + float m_flNextThink; + HSCRIPT m_hfnThink; + unsigned m_iContextHash; + bool m_bNoParam; +}; +#endif + struct EmitSound_t; struct rotatingpushmove_t; @@ -344,7 +373,7 @@ struct rotatingpushmove_t; class CBaseEntity : public IServerEntity { public: - DECLARE_CLASS_NOBASE( CBaseEntity ); + DECLARE_CLASS_NOBASE( CBaseEntity ); //---------------------------------------- // Class vars and functions @@ -379,7 +408,9 @@ class CBaseEntity : public IServerEntity DECLARE_SERVERCLASS(); // data description DECLARE_DATADESC(); - + // script description + DECLARE_ENT_SCRIPTDESC(); + // memory handling void *operator new( size_t stAllocateBlock ); void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine ); @@ -468,7 +499,7 @@ class CBaseEntity : public IServerEntity // This function gets your parent's transform. If you're parented to an attachment, // this calculates the attachment's transform and gives you that. // - // You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of + // You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of // pointing you right at a variable in your parent. matrix3x4_t& GetParentToWorldTransform( matrix3x4_t &tempMatrix ); @@ -493,6 +524,8 @@ class CBaseEntity : public IServerEntity virtual void SetOwnerEntity( CBaseEntity* pOwner ); void SetEffectEntity( CBaseEntity *pEffectEnt ); CBaseEntity *GetEffectEntity() const; + HSCRIPT GetScriptOwnerEntity(); + virtual void SetScriptOwnerEntity(HSCRIPT pOwner); // Only CBaseEntity implements these. CheckTransmit calls the virtual ShouldTransmit to see if the // entity wants to be sent. If so, it calls SetTransmit, which will mark any dependents for transmission too. @@ -502,10 +535,10 @@ class CBaseEntity : public IServerEntity int SetTransmitState( int nFlag); int GetTransmitState( void ); int DispatchUpdateTransmitState(); - + // Do NOT call this directly. Use DispatchUpdateTransmitState. virtual int UpdateTransmitState(); - + // Entities (like ropes) use this to own the transmit state of another entity // by forcing it to not call UpdateTransmitState. void IncrementTransmitStateOwnedCounter(); @@ -544,6 +577,11 @@ class CBaseEntity : public IServerEntity bool IsFollowingEntity(); CBaseEntity *GetFollowedEntity(); +#ifdef MAPBASE_VSCRIPT + void ScriptFollowEntity( HSCRIPT hBaseEntity, bool bBoneMerge ); + HSCRIPT ScriptGetFollowedEntity(); +#endif + // initialization virtual void Spawn( void ); virtual void Precache( void ) {} @@ -563,9 +601,20 @@ class CBaseEntity : public IServerEntity virtual bool KeyValue( const char *szKeyName, float flValue ); virtual bool KeyValue( const char *szKeyName, const Vector &vecValue ); virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + bool KeyValueFromString( const char *szKeyName, const char *szValue ) { return KeyValue( szKeyName, szValue ); } + bool KeyValueFromFloat( const char *szKeyName, float flValue ) { return KeyValue( szKeyName, flValue ); } + bool KeyValueFromInt( const char *szKeyName, int nValue ) { return KeyValue( szKeyName, nValue ); } + bool KeyValueFromVector( const char *szKeyName, const Vector &vecValue ) { return KeyValue( szKeyName, vecValue ); } void ValidateEntityConnections(); void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f ); + CBaseEntityOutput *FindNamedOutput( const char *pszOutput ); +#ifdef MAPBASE_VSCRIPT + void ScriptFireOutput( const char *pszOutput, HSCRIPT hActivator, HSCRIPT hCaller, const char *szValue, float flDelay ); + float GetMaxOutputDelay( const char *pszOutput ); + //void CancelEventsByInput( const char *szInput ); +#endif + // Activate - called for each entity after each load game and level load virtual void Activate( void ); @@ -577,10 +626,13 @@ class CBaseEntity : public IServerEntity CBaseEntity *NextMovePeer( void ); void SetName( string_t newTarget ); +#ifdef MAPBASE_VSCRIPT + void SetNameAsCStr( const char *newTarget ); +#endif void SetParent( string_t newParent, CBaseEntity *pActivator, int iAttachment = -1 ); - + // Set the movement parent. Your local origin and angles will become relative to this parent. - // If iAttachment is a valid attachment on the parent, then your local origin and angles + // If iAttachment is a valid attachment on the parent, then your local origin and angles // are relative to the attachment on this entity. If iAttachment == -1, it'll preserve the // current m_iParentAttachment. virtual void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 ); @@ -588,6 +640,8 @@ class CBaseEntity : public IServerEntity int GetParentAttachment(); string_t GetEntityName(); + const char* GetEntityNameAsCStr(); // This method is temporary for VSCRIPT functionality until we figure out what to do with string_t (sjb) + const char* GetPreTemplateName(); // Not threadsafe. Get the name stripped of template unique decoration bool NameMatches( const char *pszNameOrWildcard ); bool ClassMatches( const char *pszClassOrWildcard ); @@ -636,6 +690,15 @@ class CBaseEntity : public IServerEntity // handles an input (usually caused by outputs) // returns true if the the value in the pass in should be set, false if the input is to be ignored virtual bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ); +#ifdef MAPBASE_VSCRIPT + bool ScriptAcceptInput(const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller); +#endif + + bool ScriptInputHook( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, ScriptVariant_t &functionReturn ); + void ScriptInputHookClearParams(); +#ifdef MAPBASE_VSCRIPT + bool ScriptDeathHook( CTakeDamageInfo *info ); +#endif // // Input handlers. @@ -663,12 +726,93 @@ class CBaseEntity : public IServerEntity void InputDisableShadow( inputdata_t &inputdata ); void InputEnableShadow( inputdata_t &inputdata ); void InputAddOutput( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputChangeVariable( inputdata_t &inputdata ); +#endif void InputFireUser1( inputdata_t &inputdata ); void InputFireUser2( inputdata_t &inputdata ); void InputFireUser3( inputdata_t &inputdata ); void InputFireUser4( inputdata_t &inputdata ); - // Returns the origin at which to play an inputted dispatcheffect +#ifdef MAPBASE + void InputPassUser1( inputdata_t &inputdata ); + void InputPassUser2( inputdata_t &inputdata ); + void InputPassUser3( inputdata_t &inputdata ); + void InputPassUser4( inputdata_t &inputdata ); + + void InputFireRandomUser( inputdata_t &inputdata ); + void InputPassRandomUser( inputdata_t &inputdata ); + + void InputSetEntityName( inputdata_t &inputdata ); + + virtual void InputSetTarget( inputdata_t &inputdata ); + virtual void InputSetOwnerEntity( inputdata_t &inputdata ); + + virtual void InputAddHealth( inputdata_t &inputdata ); + virtual void InputRemoveHealth( inputdata_t &inputdata ); + virtual void InputSetHealth( inputdata_t &inputdata ); + + virtual void InputSetMaxHealth( inputdata_t &inputdata ); + + void InputFireOutput( inputdata_t &inputdata ); + void InputRemoveOutput( inputdata_t &inputdata ); + //virtual void InputCancelOutput( inputdata_t &inputdata ); // Find a way to implement this + void InputReplaceOutput( inputdata_t &inputdata ); + void InputAcceptInput( inputdata_t &inputdata ); + virtual void InputCancelPending( inputdata_t &inputdata ); + + void InputFreeChildren( inputdata_t &inputdata ); + + void InputSetLocalOrigin( inputdata_t &inputdata ); + void InputSetLocalAngles( inputdata_t &inputdata ); + void InputSetAbsOrigin( inputdata_t &inputdata ); + void InputSetAbsAngles( inputdata_t &inputdata ); + void InputSetLocalVelocity( inputdata_t &inputdata ); + void InputSetLocalAngularVelocity( inputdata_t &inputdata ); + + void InputAddSpawnFlags( inputdata_t &inputdata ); + void InputRemoveSpawnFlags( inputdata_t &inputdata ); + void InputSetRenderMode( inputdata_t &inputdata ); + void InputSetRenderFX( inputdata_t &inputdata ); + void InputSetViewHideFlags( inputdata_t &inputdata ); + void InputAddEffects( inputdata_t &inputdata ); + void InputRemoveEffects( inputdata_t &inputdata ); + void InputDrawEntity( inputdata_t &inputdata ); + void InputUndrawEntity( inputdata_t &inputdata ); + void InputEnableReceivingFlashlight( inputdata_t &inputdata ); + void InputDisableReceivingFlashlight( inputdata_t &inputdata ); + void InputAddEFlags( inputdata_t &inputdata ); + void InputRemoveEFlags( inputdata_t &inputdata ); + void InputAddSolidFlags( inputdata_t &inputdata ); + void InputRemoveSolidFlags( inputdata_t &inputdata ); + void InputSetMoveType( inputdata_t &inputdata ); + void InputSetCollisionGroup( inputdata_t &inputdata ); + + void InputTouch( inputdata_t &inputdata ); + + virtual void InputKilledNPC( inputdata_t &inputdata ); + + void InputKillIfNotVisible( inputdata_t &inputdata ); + void InputKillWhenNotVisible( inputdata_t &inputdata ); + + void InputSetThinkNull( inputdata_t &inputdata ); + + COutputEvent m_OnKilled; +#endif + + void InputRunScript(inputdata_t& inputdata); + void InputRunScriptFile(inputdata_t& inputdata); + void InputCallScriptFunction(inputdata_t& inputdata); +#ifdef MAPBASE_VSCRIPT + void InputRunScriptQuotable(inputdata_t& inputdata); + void InputClearScriptScope(inputdata_t& inputdata); +#endif + + bool RunScriptFile(const char* pScriptFile, bool bUseRootScope = false); + bool RunScript(const char* pScriptText, const char* pDebugFilename = "CBaseEntity::RunScript"); + + + // Returns the origin at which to play an inputted dispatcheffect virtual void GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles ); // tries to read a field from the entities data description - result is placed in variant_t @@ -681,7 +825,7 @@ class CBaseEntity : public IServerEntity // Debug Overlays void EntityText( int text_offset, const char *text, float flDuration, int r = 255, int g = 255, int b = 255, int a = 255 ); const char *GetDebugName(void); // do not make this virtual -- designed to handle NULL this - virtual void DrawDebugGeometryOverlays(void); + virtual void DrawDebugGeometryOverlays(void); virtual int DrawDebugTextOverlays(void); void DrawTimedOverlays( void ); void DrawBBoxOverlay( float flDuration = 0.0f ); @@ -736,7 +880,7 @@ class CBaseEntity : public IServerEntity // returns the edict index the entity requires when used in save/restore (eg players, world) // -1 means it doesn't require any special index - virtual int RequiredEdictIndex( void ) { return -1; } + virtual int RequiredEdictIndex( void ) { return -1; } // interface function pts void (CBaseEntity::*m_pfnMoveDone)(void); @@ -790,11 +934,24 @@ class CBaseEntity : public IServerEntity // was pev->rendermode CNetworkVar( unsigned char, m_nRenderMode ); CNetworkVar( short, m_nModelIndex ); - + #ifdef TF_DLL CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary #endif +#ifdef MAPBASE + // Prevents this entity from drawing under certain view IDs. Each flag is (1 << the view ID to hide from). + // For example, hiding an entity from VIEW_MONITOR prevents it from showing up on RT camera monitors + // and hiding an entity from VIEW_MAIN just prevents it from showing up through the player's own "eyes". + // Doing this via flags allows for the entity to be hidden from multiple view IDs at the same time. + // + // This was partly inspired by Underhell's keyvalue that allows entities to only render in mirrors and cameras. + CNetworkVar( int, m_iViewHideFlags ); + + // Disables receiving projected textures. Based on a keyvalue from later Source games. + CNetworkVar( bool, m_bDisableFlashlight ); +#endif + // was pev->rendercolor CNetworkColor32( m_clrRender ); const color32 GetRenderColor() const; @@ -822,7 +979,7 @@ class CBaseEntity : public IServerEntity #endif // used so we know when things are no longer touching - int touchStamp; + int touchStamp; protected: @@ -841,13 +998,30 @@ class CBaseEntity : public IServerEntity #endif void RemoveExpiredConcepts( void ); +#ifdef MAPBASE + // Some new code needs to access these functions from outside of the class. +public: +#endif int GetContextCount() const; // Call RemoveExpiredConcepts to clean out expired concepts const char *GetContextName( int index ) const; // note: context may be expired const char *GetContextValue( int index ) const; // note: context may be expired bool ContextExpired( int index ) const; int FindContextByName( const char *name ) const; +#ifndef MAPBASE public: +#endif + +#ifdef MAPBASE + bool HasContext( const char *name, const char *value ) const; + bool HasContext( string_t name, string_t value ) const; // NOTE: string_t version only compares pointers! + bool HasContext( const char *nameandvalue ) const; + const char *GetContextValue( const char *contextName ) const; + float GetContextExpireTime( const char *name ); + void RemoveContext( const char *nameandvalue ); +#endif + void AddContext( const char *nameandvalue ); + void AddContext( const char *name, const char *value, float duration = 0.0f ); protected: CUtlVector< ResponseContext_t > m_ResponseContexts; @@ -891,6 +1065,12 @@ class CBaseEntity : public IServerEntity // Call this to do a TraceAttack on an entity, performs filtering. Don't call TraceAttack() directly except when chaining up to base class void DispatchTraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL ); virtual bool PassesDamageFilter( const CTakeDamageInfo &info ); +#ifdef MAPBASE + // Special filter functions made for the "damage" family of filters, including filter_damage_transfer. + bool PassesFinalDamageFilter( const CTakeDamageInfo &info ); + bool DamageFilterAllowsBlood( const CTakeDamageInfo &info ); + bool DamageFilterDamageMod( CTakeDamageInfo &info ); +#endif protected: @@ -904,7 +1084,7 @@ class CBaseEntity : public IServerEntity virtual int OnTakeDamage( const CTakeDamageInfo &info ); // This is what you should call to apply damage to an entity. - int TakeDamage( const CTakeDamageInfo &info ); + void TakeDamage( const CTakeDamageInfo &info ); virtual void AdjustDamageDirection( const CTakeDamageInfo &info, Vector &dir, CBaseEntity *pEnt ) {} virtual int TakeHealth( float flHealth, int bitsDamageType ); @@ -912,11 +1092,11 @@ class CBaseEntity : public IServerEntity virtual bool IsAlive( void ); // Entity killed (only fired once) virtual void Event_Killed( const CTakeDamageInfo &info ); - + void SendOnKilledGameEvent( const CTakeDamageInfo &info ); // Notifier that I've killed some other entity. (called from Victim's Event_Killed). - virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) { return; } + virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ); // UNDONE: Make this data? virtual int BloodColor( void ); @@ -924,12 +1104,12 @@ class CBaseEntity : public IServerEntity void TraceBleed( float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType ); virtual bool IsTriggered( CBaseEntity *pActivator ) {return true;} virtual bool IsNPC( void ) const { return false; } - CAI_BaseNPC *MyNPCPointer( void ); + CAI_BaseNPC *MyNPCPointer( void ); virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; } virtual INextBot *MyNextBotPointer( void ) { return NULL; } virtual float GetDelay( void ) { return 0; } virtual bool IsMoving( void ); - bool IsWorld() { return entindex() == 0; } + bool IsWorld() const { extern CWorld *g_WorldEntity; return (void *)this == (void *)g_WorldEntity; } // Ported from the Alien Swarm SDK to fix false IsWorld() positives on server-only entities virtual char const *DamageDecal( int bitsDamageType, int gameMaterial ); virtual void DecalTrace( trace_t *pTrace, char const *decalName ); virtual void ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName = NULL ); @@ -987,7 +1167,7 @@ class CBaseEntity : public IServerEntity void VelocityPunch( const Vector &vecForce ); CBaseEntity *GetNextTarget( void ); - + // fundamental callbacks void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther ); void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); @@ -995,7 +1175,7 @@ class CBaseEntity : public IServerEntity virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); virtual void StartTouch( CBaseEntity *pOther ); - virtual void Touch( CBaseEntity *pOther ); + virtual void Touch( CBaseEntity *pOther ); virtual void EndTouch( CBaseEntity *pOther ); virtual void StartBlocked( CBaseEntity *pOther ) {} virtual void Blocked( CBaseEntity *pOther ); @@ -1049,6 +1229,10 @@ class CBaseEntity : public IServerEntity void SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); } void SUB_PerformFadeOut( void ); virtual bool SUB_AllowedToFade( void ); +#ifdef MAPBASE + // For KillWhenNotVisible + void SUB_RemoveWhenNotVisible( void ); +#endif // change position, velocity, orientation instantly // passing NULL means no change @@ -1062,13 +1246,13 @@ class CBaseEntity : public IServerEntity virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ); virtual int GetTracerAttachment( void ); virtual void FireBullets( const FireBulletsInfo_t &info ); - virtual void FireBulletProjectiles(const ProjectileBulletsInfo_t& info); + virtual void FireBulletProjectiles( const ProjectileBulletsInfo_t &info ); virtual void DoImpactEffect( trace_t &tr, int nDamageType ); // give shooter a chance to do a custom impact. // OLD VERSION! Use the struct version - void FireBullets( int cShots, const Vector &vecSrc, const Vector &vecDirShooting, - const Vector &vecSpread, float flDistance, int iAmmoType, int iTracerFreq = 4, - int firingEntID = -1, int attachmentID = -1, int iDamage = 0, + void FireBullets( int cShots, const Vector &vecSrc, const Vector &vecDirShooting, + const Vector &vecSpread, float flDistance, int iAmmoType, int iTracerFreq = 4, + int firingEntID = -1, int attachmentID = -1, int iDamage = 0, CBaseEntity *pAttacker = NULL, bool bFirstShotAccurate = false, bool bPrimaryAttack = true ); virtual void ModifyFireBulletsDamage( CTakeDamageInfo* dmgInfo ) {} @@ -1088,60 +1272,61 @@ class CBaseEntity : public IServerEntity int GetHealth() const { return m_iHealth; } void SetHealth( int amt ) { m_iHealth = amt; } - float HealthFraction() const; - // Ugly code to lookup all functions to make sure they are in the table when set. #ifdef _DEBUG + void FunctionCheck( void *pFunction, const char *name ); + ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, const char *name ) + { #ifdef GNUC -#define ENTITYFUNCPTR_SIZE 8 + COMPILE_TIME_ASSERT( sizeof(func) == 8 ); #else -#define ENTITYFUNCPTR_SIZE 4 + COMPILE_TIME_ASSERT( sizeof(func) == 4 ); #endif - - void FunctionCheck( void *pFunction, const char *name ); - ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) - { - COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); - m_pfnTouch = func; - FunctionCheck( *(reinterpret_cast(&m_pfnTouch)), name ); + m_pfnTouch = func; + FunctionCheck( *(reinterpret_cast(&m_pfnTouch)), name ); return func; } - USEPTR UseSet( USEPTR func, char *name ) - { - COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); - m_pfnUse = func; - FunctionCheck( *(reinterpret_cast(&m_pfnUse)), name ); + USEPTR UseSet( USEPTR func, const char *name ) + { +#ifdef GNUC + COMPILE_TIME_ASSERT( sizeof(func) == 8 ); +#else + COMPILE_TIME_ASSERT( sizeof(func) == 4 ); +#endif + m_pfnUse = func; + FunctionCheck( *(reinterpret_cast(&m_pfnUse)), name ); return func; } - ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name ) - { - COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE ); - m_pfnBlocked = func; - FunctionCheck( *(reinterpret_cast(&m_pfnBlocked)), name ); + ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, const char *name ) + { +#ifdef GNUC + COMPILE_TIME_ASSERT( sizeof(func) == 8 ); +#else + COMPILE_TIME_ASSERT( sizeof(func) == 4 ); +#endif + m_pfnBlocked = func; + FunctionCheck( *(reinterpret_cast(&m_pfnBlocked)), name ); return func; } -#endif // _DEBUG - +#endif virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); +#ifdef NEW_RESPONSE_SYSTEM + // this computes criteria that depend on the other criteria having been set. + // needs to be done in a second pass because we may have multiple overrids for + // a context before it all settles out. + virtual void ModifyOrAppendDerivedCriteria( AI_CriteriaSet& set ) {}; +#endif void AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" ); +#ifdef MAPBASE + void ReAppendContextCriteria( AI_CriteriaSet& set ); +#endif void DumpResponseCriteria( void ); - // Return the IHasAttributes interface for this base entity. Removes the need for: - // dynamic_cast< IHasAttributes * >( pEntity ); - // Which is remarkably slow. - // GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses - // this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast. - inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; } - -protected: - // NOTE: m_pAttributes needs to be set in the leaf class constructor. - IHasAttributes *m_pAttributes; - private: friend class CAI_Senses; - CBaseEntity *m_pLink;// used for temporary link-list operations. + CBaseEntity *m_pLink;// used for temporary link-list operations. public: // variables promoted from edict_t @@ -1161,7 +1346,7 @@ class CBaseEntity : public IServerEntity TimedOverlay_t* m_pTimedOverlay; // For debug only // virtual functions used by a few classes - + // creates an entity of a specified class, by name static CBaseEntity *Create( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL ); static CBaseEntity *CreateNoSpawn( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL ); @@ -1176,6 +1361,20 @@ class CBaseEntity : public IServerEntity virtual float GetDamage() { return 0; } virtual void SetDamage(float flDamage) {} +#ifdef MAPBASE + // Some entities want to use interactions regardless of whether they're a CBaseCombatCharacter. + // Valve ran into this issue with frag grenades when they started deriving from CBaseAnimating instead of CBaseCombatCharacter, + // preventing them from using the barnacle interactions for rigged grenade timing so it's guaranteed to blow up in the barnacle's face. + // We're used to unaltered behavior now, so we're not restoring that as default, but making this a "base entity" thing is supposed to help in situtions like those. + // + // Also, keep in mind pretty much all existing DispatchInteraction() calls are only performed on CBaseCombatCharacters. + // You'll need to change their code manually if you want other, non-character entities to use the interaction. + bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); + + // Do not call HandleInteraction directly, use DispatchInteraction + virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return false; } +#endif + virtual Vector EyePosition( void ); // position of eyes virtual const QAngle &EyeAngles( void ); // Direction of eyes in world space virtual const QAngle &LocalEyeAngles( void ); // Direction of eyes @@ -1226,6 +1425,10 @@ class CBaseEntity : public IServerEntity void SetGravity( float gravity ); float GetFriction( void ) const; void SetFriction( float flFriction ); +#ifdef MAPBASE_VSCRIPT + void SetMass(float mass); + float GetMass(); +#endif virtual bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); @@ -1257,13 +1460,13 @@ class CBaseEntity : public IServerEntity virtual bool PhysicsSplash( const Vector ¢erPoint, const Vector &normal, float rawSpeed, float scaledSpeed ) { return false; } virtual void Splash() {} - void ClearSolidFlags( void ); + void ClearSolidFlags( void ); void RemoveSolidFlags( int flags ); void AddSolidFlags( int flags ); bool IsSolidFlagSet( int flagMask ) const; void SetSolidFlags( int flags ); bool IsSolid() const; - + void SetModelName( string_t name ); model_t *GetModel( void ); @@ -1283,8 +1486,8 @@ class CBaseEntity : public IServerEntity virtual const Vector& WorldSpaceCenter( ) const; const Vector& WorldAlignSize( ) const; - // Returns a radius of a sphere - // *centered at the world space center* bounding the collision representation + // Returns a radius of a sphere + // *centered at the world space center* bounding the collision representation // of the entity. NOTE: The world space center *may* move when the entity rotates. float BoundingRadius() const; bool IsPointSized() const; @@ -1312,9 +1515,9 @@ class CBaseEntity : public IServerEntity void IncrementLocalTime( float flTimeDelta ); float GetMoveDoneTime( ) const; void SetMoveDoneTime( float flTime ); - + // Used by the PAS filters to ask the entity where in world space the sounds it emits come from. - // This is used right now because if you have something sitting on an incline, using our axis-aligned + // This is used right now because if you have something sitting on an incline, using our axis-aligned // bounding boxes can return a position in solid space, so you won't hear sounds emitted by the object. // For now, we're hacking around it by moving the sound emission origin up on certain objects like vehicles. // @@ -1338,6 +1541,12 @@ class CBaseEntity : public IServerEntity void GenderExpandString( char const *in, char *out, int maxlen ); virtual void ModifyEmitSoundParams( EmitSound_t ¶ms ); +#ifdef MAPBASE + // Same as above, but for sentences + // (which don't actually have EmitSound_t params) + virtual void ModifySentenceParams( int &iSentenceIndex, int &iChannel, float &flVolume, soundlevel_t &iSoundlevel, int &iFlags, int &iPitch, + const Vector **pOrigin, const Vector **pDirection, bool &bUpdatePositions, float &soundtime, int &iSpecialDSP, int &iSpeakerIndex ); +#endif static float GetSoundDuration( const char *soundname, char const *actormodel ); @@ -1361,13 +1570,17 @@ class CBaseEntity : public IServerEntity static HSOUNDSCRIPTHANDLE PrecacheScriptSound( const char *soundname ); static void PrefetchScriptSound( const char *soundname ); - // For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from + // For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from // the recipient list. static void RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter ); static void EmitCloseCaption( IRecipientFilter& filter, int entindex, char const *token, CUtlVector< Vector >& soundorigins, float duration, bool warnifmissing = false ); - static void EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, + static void EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM, - const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f ); + const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f +#ifdef MAPBASE + , int iSpecialDSP = 0, int iSpeakerIndex = 0 // Needed for env_microphone +#endif + ); static bool IsPrecacheAllowed(); static void SetAllowPrecache( bool allow ); @@ -1418,14 +1631,14 @@ class CBaseEntity : public IServerEntity inline IPhysicsObject *VPhysicsGetObject( void ) const { return m_pPhysicsObject; } virtual void VPhysicsUpdate( IPhysicsObject *pPhysics ); void VPhysicsUpdatePusher( IPhysicsObject *pPhysics ); - + // react physically to damage (called from CBaseEntity::OnTakeDamage() by default) virtual int VPhysicsTakeDamage( const CTakeDamageInfo &info ); virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent ); virtual void VPhysicsShadowUpdate( IPhysicsObject *pPhysics ) {} virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); virtual void VPhysicsFriction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit ); - + // update the shadow so it will coincide with the current AI position at some time // in the future (or 0 for now) virtual void UpdatePhysicsShadowToCurrentPosition( float deltaTime ); @@ -1457,6 +1670,11 @@ class CBaseEntity : public IServerEntity // Callbacks for the physgun/cannon picking up an entity virtual CBasePlayer *HasPhysicsAttacker( float dt ) { return NULL; } +#ifdef MAPBASE + // This function needed to be extended to phys_magnet and I didn't like the dynamic_casts. + virtual bool CanBePickedUpByPhyscannon() { return false; } +#endif + // UNDONE: Make this data? virtual unsigned int PhysicsSolidMaskForEntity( void ) const; @@ -1547,7 +1765,7 @@ class CBaseEntity : public IServerEntity // origin and angles to use in step calculations virtual Vector GetStepOrigin( void ) const; virtual QAngle GetStepAngles( void ) const; - + // These set entity flags (EFL_*) to help optimize queries void CheckHasThinkFunction( bool isThinkingHint = false ); void CheckHasGamePhysicsSimulation(); @@ -1601,7 +1819,7 @@ class CBaseEntity : public IServerEntity // was pev->flags CNetworkVarForDerived( int, m_fFlags ); - string_t m_iName; // name used to identify this entity + CNetworkVar( string_t, m_iName ); // name used to identify this entity // Damage modifiers friend class CDamageModifier; @@ -1617,9 +1835,9 @@ class CBaseEntity : public IServerEntity // FIXME: clarify m_pParent vs. m_pMoveParent CNetworkHandle( CBaseEntity, m_hMoveParent ); // cached child list - EHANDLE m_hMoveChild; + EHANDLE m_hMoveChild; // generated from m_pMoveParent - EHANDLE m_hMovePeer; + EHANDLE m_hMovePeer; friend class CCollisionProperty; friend class CServerNetworkProperty; @@ -1636,7 +1854,7 @@ class CBaseEntity : public IServerEntity // Team handling int m_iInitialTeamNum; // Team number of this entity's team read from file - CNetworkVar( int, m_iTeamNum ); // Team number of this entity's team. + CNetworkVar( int, m_iTeamNum ); // Team number of this entity's team. // Sets water type + level for physics objects unsigned char m_nWaterTouch; @@ -1647,7 +1865,7 @@ class CBaseEntity : public IServerEntity CNetworkHandleForDerived( CBaseEntity, m_hGroundEntity ); float m_flGroundChangeTime; // Time that the ground entity changed - + string_t m_ModelName; // Velocity of the thing we're standing on (world space) @@ -1686,15 +1904,21 @@ class CBaseEntity : public IServerEntity Vector m_vecAbsOrigin; CNetworkVectorForDerived( m_vecVelocity ); - + //Adrian CNetworkVar( unsigned char, m_iTextureFrameIndex ); - + CNetworkVar( bool, m_bSimulatedEveryTick ); CNetworkVar( bool, m_bAnimatedEveryTick ); CNetworkVar( bool, m_bAlternateSorting ); // User outputs. Fired when the "FireInputX" input is triggered. +#ifdef MAPBASE + COutputVariant m_OutUser1; + COutputVariant m_OutUser2; + COutputVariant m_OutUser3; + COutputVariant m_OutUser4; +#endif COutputEvent m_OnUser1; COutputEvent m_OnUser2; COutputEvent m_OnUser3; @@ -1721,7 +1945,7 @@ class CBaseEntity : public IServerEntity void EnableDynamicModels() { m_bDynamicModelAllowed = true; } public: - bool IsDynamicModelLoading() const { return m_bDynamicModelPending; } + bool IsDynamicModelLoading() const { return m_bDynamicModelPending; } void SetCollisionBoundsFromModel(); #if !defined( NO_ENTITY_PREDICTION ) @@ -1738,7 +1962,7 @@ class CBaseEntity : public IServerEntity // Methods shared by client and server public: void SetSize( const Vector &vecMin, const Vector &vecMax ); // UTIL_SetSize( this, mins, maxs ); - static int PrecacheModel( const char *name, bool bPreload = true ); + static int PrecacheModel( const char *name, bool bPreload = true ); static bool PrecacheSound( const char *name ); static void PrefetchSound( const char *name ); void Remove( ); // UTIL_Remove( this ); @@ -1749,7 +1973,6 @@ class CBaseEntity : public IServerEntity // randon number generators to spit out the same random numbers on both sides for a particular // usercmd input. static int m_nPredictionRandomSeed; - static int m_nPredictionRandomSeedServer; static CBasePlayer *m_pPredictionPlayer; // FIXME: Make hierarchy a member of CBaseEntity @@ -1760,10 +1983,10 @@ class CBaseEntity : public IServerEntity friend void UnlinkAllChildren( CBaseEntity *pParent ); friend void UnlinkFromParent( CBaseEntity *pRemove ); friend void TransferChildren( CBaseEntity *pOldParent, CBaseEntity *pNewParent ); - + public: // Accessors for above - static int GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime = false ); + static int GetPredictionRandomSeed( void ); static void SetPredictionRandomSeed( const CUserCmd *cmd ); static CBasePlayer *GetPredictionPlayer( void ); static void SetPredictionPlayer( CBasePlayer *player ); @@ -1784,25 +2007,178 @@ class CBaseEntity : public IServerEntity { return "server"; } - + // Used to access m_vecAbsOrigin during restore when it's unsafe to call GetAbsOrigin. friend class CPlayerRestoreHelper; - + static bool s_bAbsQueriesValid; // Call this when hierarchy is not completely set up (such as during Restore) to throw asserts - // when people call GetAbsAnything. + // when people call GetAbsAnything. static inline void SetAbsQueriesValid( bool bValid ) { s_bAbsQueriesValid = bValid; } - + static inline bool IsAbsQueriesValid() { return s_bAbsQueriesValid; } - virtual bool ShouldBlockNav() const { return true; } + + // VSCRIPT + HSCRIPT GetScriptInstance(); + bool ValidateScriptScope(); + virtual void RunVScripts(); + bool CallScriptFunction(const char* pFunctionName, ScriptVariant_t* pFunctionReturn); + void ConnectOutputToScript(const char* pszOutput, const char* pszScriptFunc); + void DisconnectOutputFromScript(const char* pszOutput, const char* pszScriptFunc); + void ScriptThink(); +#ifdef MAPBASE_VSCRIPT + void ScriptSetThinkFunction(const char *szFunc, float time); + void ScriptStopThinkFunction(); + void ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float time ); + void ScriptSetThink( HSCRIPT hFunc, float time ); + void ScriptStopThink(); + void ScriptContextThink(); +private: + CUtlVector< scriptthinkfunc_t* > m_ScriptThinkFuncs; +public: +#endif + const char* GetScriptId(); + HSCRIPT GetScriptScope(); +#ifdef MAPBASE_VSCRIPT + HSCRIPT GetOrCreatePrivateScriptScope(); +#endif + void RunPrecacheScripts(void); + void RunOnPostSpawnScripts(void); + +#ifdef MAPBASE_VSCRIPT + HSCRIPT LookupScriptFunction(const char* pFunctionName); + bool CallScriptFunctionHandle(HSCRIPT hFunc, ScriptVariant_t* pFunctionReturn); +#endif + + HSCRIPT ScriptGetMoveParent(void); + HSCRIPT ScriptGetRootMoveParent(); + HSCRIPT ScriptFirstMoveChild(void); + HSCRIPT ScriptNextMovePeer(void); + + const Vector& ScriptEyePosition(void) { static Vector vec; vec = EyePosition(); return vec; } +#ifdef MAPBASE_VSCRIPT + const QAngle& ScriptEyeAngles(void) { static QAngle ang; ang = EyeAngles(); return ang; } + void ScriptSetAngles(const QAngle angles) { Teleport(NULL, &angles, NULL); } + const QAngle& ScriptGetAngles(void) { return GetAbsAngles(); } +#else + void ScriptSetAngles(float fPitch, float fYaw, float fRoll) { QAngle angles(fPitch, fYaw, fRoll); Teleport(NULL, &angles, NULL); } + const Vector& ScriptGetAngles(void) { static Vector vec; QAngle qa = GetAbsAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; } +#endif + +#ifndef MAPBASE_VSCRIPT + void ScriptSetSize(const Vector& mins, const Vector& maxs) { UTIL_SetSize(this, mins, maxs); } + void ScriptUtilRemove(void) { UTIL_Remove(this); } +#endif + void ScriptSetOwner(HSCRIPT hEntity) { SetOwnerEntity(ToEnt(hEntity)); } + void ScriptSetOrigin(const Vector& v) { Teleport(&v, NULL, NULL); } + void ScriptSetForward(const Vector& v) { QAngle angles; VectorAngles(v, angles); Teleport(NULL, &angles, NULL); } + const Vector& ScriptGetForward(void) { static Vector vecForward; GetVectors(&vecForward, NULL, NULL); return vecForward; } +#ifdef MAPBASE_VSCRIPT + const Vector& ScriptGetRight(void) { static Vector vecRight; GetVectors(NULL, &vecRight, NULL); return vecRight; } +#endif + const Vector& ScriptGetLeft(void) { static Vector vecRight; GetVectors(NULL, &vecRight, NULL); return vecRight; } + + const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; } + +#ifdef MAPBASE_VSCRIPT + void ScriptSetOriginAngles(const Vector &vecOrigin, const QAngle &angAngles) { Teleport(&vecOrigin, &angAngles, NULL); } + void ScriptSetOriginAnglesVelocity(const Vector &vecOrigin, const QAngle &angAngles, const Vector &vecVelocity) { Teleport(&vecOrigin, &angAngles, &vecVelocity); } + + HSCRIPT ScriptEntityToWorldTransform( void ); + + HSCRIPT ScriptGetPhysicsObject( void ); + + void ScriptSetParent(HSCRIPT hParent, const char *szAttachment); +#endif + + const char* ScriptGetModelName(void) const; + HSCRIPT ScriptGetModelKeyValues(void); + + void ScriptStopSound(const char* soundname); + void ScriptEmitSound(const char* soundname); + float ScriptSoundDuration(const char* soundname, const char* actormodel); + + void VScriptPrecacheScriptSound(const char* soundname); + + const Vector& ScriptGetLocalAngularVelocity( void ); + void ScriptSetLocalAngularVelocity( float pitchVel, float yawVel, float rollVel ); + + const Vector& ScriptGetBoundingMins(void); + const Vector& ScriptGetBoundingMaxs(void); + +#ifdef MAPBASE_VSCRIPT + bool ScriptIsVisible( const Vector &vecSpot ) { return FVisible( vecSpot ); } + bool ScriptIsEntVisible( HSCRIPT pEntity ) { return FVisible( ToEnt( pEntity ) ); } + bool ScriptIsVisibleWithMask( const Vector &vecSpot, int traceMask ) { return FVisible( vecSpot, traceMask ); } + + int ScriptTakeDamage( HSCRIPT pInfo ); + void ScriptFireBullets( HSCRIPT pInfo ); + + void ScriptAddContext( const char *name, const char *value, float duration = 0.0f ); + const char *ScriptGetContext( const char *name ); + HSCRIPT ScriptGetContextIndex( int index ); + + int ScriptClassify(void); + + bool ScriptAddOutput( const char *pszOutputName, const char *pszTarget, const char *pszAction, const char *pszParameter, float flDelay, int iMaxTimes ); + const char *ScriptGetKeyValue( const char *pszKeyName ); + + const Vector& ScriptGetColorVector(); + int ScriptGetColorR() { return m_clrRender.GetR(); } + int ScriptGetColorG() { return m_clrRender.GetG(); } + int ScriptGetColorB() { return m_clrRender.GetB(); } + int ScriptGetAlpha() { return m_clrRender.GetA(); } + void ScriptSetColorVector( const Vector& vecColor ); + void ScriptSetColor( int r, int g, int b ); + void ScriptSetColorR( int iVal ) { SetRenderColorR( iVal ); } + void ScriptSetColorG( int iVal ) { SetRenderColorG( iVal ); } + void ScriptSetColorB( int iVal ) { SetRenderColorB( iVal ); } + void ScriptSetAlpha( int iVal ) { SetRenderColorA( iVal ); } + + int ScriptGetRenderMode() { return GetRenderMode(); } + void ScriptSetRenderMode( int nRenderMode ) { SetRenderMode( (RenderMode_t)nRenderMode ); } + + int ScriptGetMoveType() { return GetMoveType(); } + void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); } + + int ScriptGetSolid() { return GetSolid(); } + void ScriptSetSolid( int i ) { SetSolid( (SolidType_t)i ); } + + bool ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt ); + + int ScriptGetTakeDamage() { return m_takedamage; } + void ScriptSetTakeDamage( int val ) { m_takedamage = val; } + + static ScriptHook_t g_Hook_UpdateOnRemove; + static ScriptHook_t g_Hook_OnEntText; + + static ScriptHook_t g_Hook_VPhysicsCollision; + static ScriptHook_t g_Hook_FireBullets; + static ScriptHook_t g_Hook_OnDeath; + static ScriptHook_t g_Hook_OnKilledOther; + static ScriptHook_t g_Hook_HandleInteraction; + static ScriptHook_t g_Hook_ModifyEmitSoundParams; + static ScriptHook_t g_Hook_ModifySentenceParams; +#endif + + string_t m_iszVScripts; + string_t m_iszScriptThinkFunction; + CScriptScope m_ScriptScope; + HSCRIPT m_hScriptInstance; + string_t m_iszScriptId; +#ifdef MAPBASE_VSCRIPT + HSCRIPT m_pScriptModelKeyValues; +#else + CScriptKeyValues* m_pScriptModelKeyValues; +#endif }; // Send tables exposed in this module. @@ -1812,7 +2188,7 @@ EXTERN_SEND_TABLE(DT_BaseEntity); // Ugly technique to override base member functions -// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a +// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a // member function of a base class. static_cast is a sleezy way around that problem. #ifdef _DEBUG @@ -1899,12 +2275,12 @@ inline bool CBaseEntity::Debug_ShouldStep(void) //----------------------------------------------------------------------------- inline CBaseEntity *CBaseEntity::GetMoveParent( void ) { - return m_hMoveParent.Get(); + return m_hMoveParent.Get(); } inline CBaseEntity *CBaseEntity::FirstMoveChild( void ) { - return m_hMoveChild.Get(); + return m_hMoveChild.Get(); } inline CBaseEntity *CBaseEntity::NextMovePeer( void ) @@ -1926,9 +2302,24 @@ inline int CBaseEntity::GetParentAttachment() //----------------------------------------------------------------------------- // Inline methods //----------------------------------------------------------------------------- -inline string_t CBaseEntity::GetEntityName() -{ - return m_iName; +inline string_t CBaseEntity::GetEntityName() +{ + return m_iName; +} + +inline const char *CBaseEntity::GetEntityNameAsCStr() +{ + return STRING(m_iName.Get()); +} + +inline const char *CBaseEntity::GetPreTemplateName() +{ + const char *pszDelimiter = V_strrchr( STRING(m_iName.Get()), '&' ); + if ( !pszDelimiter ) + return STRING( m_iName.Get() ); + static char szStrippedName[128]; + V_strncpy( szStrippedName, STRING( m_iName.Get() ), MIN( ARRAYSIZE(szStrippedName), pszDelimiter - STRING( m_iName.Get() ) + 1 ) ); + return szStrippedName; } inline void CBaseEntity::SetName( string_t newName ) @@ -1936,6 +2327,12 @@ inline void CBaseEntity::SetName( string_t newName ) m_iName = newName; } +#ifdef MAPBASE_VSCRIPT +inline void CBaseEntity::SetNameAsCStr( const char *newName ) +{ + m_iName = AllocPooledString(newName); +} +#endif inline bool CBaseEntity::NameMatches( const char *pszNameOrWildcard ) { @@ -1972,35 +2369,35 @@ inline bool CBaseEntity::ClassMatches( string_t nameStr ) } inline int CBaseEntity::GetSpawnFlags( void ) const -{ - return m_spawnflags; +{ + return m_spawnflags; } -inline void CBaseEntity::AddSpawnFlags( int nFlags ) -{ - m_spawnflags |= nFlags; +inline void CBaseEntity::AddSpawnFlags( int nFlags ) +{ + m_spawnflags |= nFlags; } -inline void CBaseEntity::RemoveSpawnFlags( int nFlags ) -{ - m_spawnflags &= ~nFlags; +inline void CBaseEntity::RemoveSpawnFlags( int nFlags ) +{ + m_spawnflags &= ~nFlags; } -inline void CBaseEntity::ClearSpawnFlags( void ) -{ - m_spawnflags = 0; +inline void CBaseEntity::ClearSpawnFlags( void ) +{ + m_spawnflags = 0; } inline bool CBaseEntity::HasSpawnFlags( int nFlags ) const -{ - return (m_spawnflags & nFlags) != 0; +{ + return (m_spawnflags & nFlags) != 0; } //----------------------------------------------------------------------------- // checks to see if the entity is marked for deletion //----------------------------------------------------------------------------- -inline bool CBaseEntity::IsMarkedForDeletion( void ) -{ - return (m_iEFlags & EFL_KILLME); +inline bool CBaseEntity::IsMarkedForDeletion( void ) +{ + return (m_iEFlags & EFL_KILLME); } //----------------------------------------------------------------------------- @@ -2034,7 +2431,7 @@ inline void CBaseEntity::AddEFlags( int nEFlagMask ) inline void CBaseEntity::RemoveEFlags( int nEFlagMask ) { m_iEFlags &= ~nEFlagMask; - + if ( nEFlagMask & ( EFL_FORCE_CHECK_TRANSMIT | EFL_IN_SKYBOX ) ) DispatchUpdateTransmitState(); } @@ -2113,31 +2510,61 @@ inline const QAngle& CBaseEntity::GetAbsAngles( void ) const return m_angAbsRotation; } +#ifdef MAPBASE_VSCRIPT +inline float CBaseEntity::GetMass() +{ + IPhysicsObject *vPhys = VPhysicsGetObject(); + if (vPhys) + { + return vPhys->GetMass(); + } + else + { + Warning("Tried to call GetMass() on %s but it has no physics.\n", GetDebugName()); + return 0; + } +} + +inline void CBaseEntity::SetMass(float mass) +{ + mass = clamp(mass, VPHYSICS_MIN_MASS, VPHYSICS_MAX_MASS); + + IPhysicsObject *vPhys = VPhysicsGetObject(); + if (vPhys) + { + vPhys->SetMass(mass); + } + else + { + Warning("Tried to call SetMass() on %s but it has no physics.\n", GetDebugName()); + } +} +#endif //----------------------------------------------------------------------------- // Returns the entity-to-world transform //----------------------------------------------------------------------------- -inline matrix3x4_t &CBaseEntity::EntityToWorldTransform() -{ +inline matrix3x4_t &CBaseEntity::EntityToWorldTransform() +{ Assert( CBaseEntity::IsAbsQueriesValid() ); if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM)) { CalcAbsolutePosition(); } - return m_rgflCoordinateFrame; + return m_rgflCoordinateFrame; } inline const matrix3x4_t &CBaseEntity::EntityToWorldTransform() const -{ +{ Assert( CBaseEntity::IsAbsQueriesValid() ); if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM)) { const_cast(this)->CalcAbsolutePosition(); } - return m_rgflCoordinateFrame; + return m_rgflCoordinateFrame; } @@ -2214,64 +2641,64 @@ inline const QAngle &CBaseEntity::GetAbsAngularVelocity( ) const } */ -inline const Vector& CBaseEntity::GetBaseVelocity() const -{ - return m_vecBaseVelocity.Get(); +inline const Vector& CBaseEntity::GetBaseVelocity() const +{ + return m_vecBaseVelocity.Get(); } -inline void CBaseEntity::SetBaseVelocity( const Vector& v ) -{ - m_vecBaseVelocity = v; +inline void CBaseEntity::SetBaseVelocity( const Vector& v ) +{ + m_vecBaseVelocity = v; } inline float CBaseEntity::GetGravity( void ) const -{ - return m_flGravity; +{ + return m_flGravity; } inline void CBaseEntity::SetGravity( float gravity ) -{ - m_flGravity = gravity; +{ + m_flGravity = gravity; } inline float CBaseEntity::GetFriction( void ) const -{ - return m_flFriction; +{ + return m_flFriction; } inline void CBaseEntity::SetFriction( float flFriction ) -{ - m_flFriction = flFriction; +{ + m_flFriction = flFriction; } inline void CBaseEntity::SetElasticity( float flElasticity ) -{ - m_flElasticity = flElasticity; +{ + m_flElasticity = flElasticity; } -inline float CBaseEntity::GetElasticity( void ) const -{ - return m_flElasticity; +inline float CBaseEntity::GetElasticity( void ) const +{ + return m_flElasticity; } inline void CBaseEntity::SetShadowCastDistance( float flDistance ) -{ - m_flShadowCastDistance = flDistance; +{ + m_flShadowCastDistance = flDistance; } -inline float CBaseEntity::GetShadowCastDistance( void ) const -{ - return m_flShadowCastDistance; +inline float CBaseEntity::GetShadowCastDistance( void ) const +{ + return m_flShadowCastDistance; } inline float CBaseEntity::GetLocalTime( void ) const -{ - return m_flLocalTime; +{ + return m_flLocalTime; } inline void CBaseEntity::IncrementLocalTime( float flTimeDelta ) -{ - m_flLocalTime += flTimeDelta; +{ + m_flLocalTime += flTimeDelta; } inline float CBaseEntity::GetMoveDoneTime( ) const @@ -2284,8 +2711,8 @@ inline CBaseEntity *CBaseEntity::Instance( const edict_t *pent ) return GetContainingEntity( const_cast(pent) ); } -inline CBaseEntity *CBaseEntity::Instance( edict_t *pent ) -{ +inline CBaseEntity *CBaseEntity::Instance( edict_t *pent ) +{ if ( !pent ) { pent = INDEXENT(0); @@ -2344,8 +2771,8 @@ inline void CBaseEntity::SetRenderColorA( byte a ) } inline void CBaseEntity::SetMoveCollide( MoveCollide_t val ) -{ - m_MoveCollide = val; +{ + m_MoveCollide = val; } inline bool CBaseEntity::IsTransparent() const @@ -2431,7 +2858,7 @@ inline SolidType_t CBaseEntity::GetSolid() const return CollisionProp()->GetSolid(); } - + //----------------------------------------------------------------------------- // Methods related to IServerUnknown //----------------------------------------------------------------------------- @@ -2449,7 +2876,7 @@ inline CBaseEntity *CBaseEntity::GetBaseEntity() { return this; } - + //----------------------------------------------------------------------------- // Model related methods @@ -2557,7 +2984,7 @@ inline void CBaseEntity::NetworkStateChanged( void *pVar ) // Make sure it's a semi-reasonable pointer. Assert( (char*)pVar > (char*)this ); Assert( (char*)pVar - (char*)this < 32768 ); - + // Good, they passed an offset so we can track this variable's change // and avoid sending the whole entity. NetworkProp()->NetworkStateChanged( (char*)pVar - (char*)this ); @@ -2584,11 +3011,12 @@ inline void CBaseEntity::DecrementTransmitStateOwnedCounter() m_nTransmitStateOwnedCounter--; } + //----------------------------------------------------------------------------- // Bullet firing (legacy)... //----------------------------------------------------------------------------- -inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc, - const Vector &vecDirShooting, const Vector &vecSpread, float flDistance, +inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc, + const Vector &vecDirShooting, const Vector &vecSpread, float flDistance, int iAmmoType, int iTracerFreq, int firingEntID, int attachmentID, int iDamage, CBaseEntity *pAttacker, bool bFirstShotAccurate, bool bPrimaryAttack ) { @@ -2608,8 +3036,16 @@ inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc, FireBullets( info ); } +//----------------------------------------------------------------------------- +// VScript +//----------------------------------------------------------------------------- +inline const char* CBaseEntity::ScriptGetModelName(void) const +{ + return STRING(m_ModelName); +} + // Ugly technique to override base member functions -// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a +// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a // member function of a base class. static_cast is a sleezy way around that problem. #define SetThink( a ) ThinkSet( static_cast (a), 0, NULL ) @@ -2629,8 +3065,8 @@ inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc, inline bool FClassnameIs(CBaseEntity *pEntity, const char *szClassname) -{ - return pEntity->ClassMatches(szClassname); +{ + return pEntity->ClassMatches(szClassname); } class CPointEntity : public CBaseEntity @@ -2650,7 +3086,7 @@ class CServerOnlyEntity : public CBaseEntity DECLARE_CLASS( CServerOnlyEntity, CBaseEntity ); public: CServerOnlyEntity() : CBaseEntity( true ) {} - + virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } }; diff --git a/game/server/baseflex.cpp b/game/server/baseflex.cpp index b760ed54..49f3c189 100644 --- a/game/server/baseflex.cpp +++ b/game/server/baseflex.cpp @@ -95,6 +95,18 @@ BEGIN_DATADESC( CBaseFlex ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CBaseFlex, CBaseAnimatingOverlay, "Animated characters who have vertex flex capability." ) +#else +BEGIN_ENT_SCRIPTDESC( CBaseFlex, CBaseAnimating, "Animated characters who have vertex flex capability." ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptGetOldestScene, "GetCurrentScene", "Returns the instance of the oldest active scene entity (if any)." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSceneByIndex, "GetSceneByIndex", "Returns the instance of the scene entity at the specified index." ) + +#ifdef MAPBASE + DEFINE_SCRIPTFUNC( SetViewtarget, "Sets the entity's eye target." ) +#endif +END_SCRIPTDESC(); LINK_ENTITY_TO_CLASS( funCBaseFlex, CBaseFlex ); // meaningless independant class!! @@ -113,7 +125,7 @@ CBaseFlex::CBaseFlex( void ) : CBaseFlex::~CBaseFlex( void ) { m_LocalToGlobal.RemoveAll(); - AssertMsg( m_SceneEvents.Count() == 0, "m_ScenesEvent.Count != 0: %d", m_SceneEvents.Count() ); + Assert( m_SceneEvents.Count() == 0 ); } void CBaseFlex::SetModel( const char *szModelName ) @@ -394,7 +406,11 @@ bool CBaseFlex::ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canc // expression - // duration - //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CBaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget, CSceneEntity *pSceneEnt ) +#else void CBaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget ) +#endif { if ( !scene || !event ) { @@ -417,9 +433,14 @@ void CBaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEn info.m_pEvent = event; info.m_pScene = scene; info.m_hTarget = pTarget; - info.m_bStarted = false; + info.m_bStarted = false; + info.m_hSceneEntity = pSceneEnt; +#ifdef MAPBASE + if (StartSceneEvent( &info, scene, event, actor, pTarget, pSceneEnt )) +#else if (StartSceneEvent( &info, scene, event, actor, pTarget )) +#endif { m_SceneEvents.AddToTail( info ); } @@ -508,7 +529,7 @@ bool CBaseFlex::HandleStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoSce float seq_duration = SequenceDuration( info->m_nSequence ); float flCycle = dt / seq_duration; flCycle = flCycle - (int)flCycle; // loop - SetLayerCycle( info->m_iLayer, flCycle, flCycle, 0.f ); + SetLayerCycle( info->m_iLayer, flCycle, flCycle ); SetLayerPlaybackRate( info->m_iLayer, 0.0 ); } @@ -735,7 +756,11 @@ bool CBaseFlex::StartMoveToSceneEvent( CSceneEventInfo *info, CChoreoScene *scen //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- +#ifdef MAPBASE +bool CBaseFlex::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget, CSceneEntity *pSceneEnt ) +#else bool CBaseFlex::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ) +#endif { switch ( event->GetType() ) { @@ -765,6 +790,67 @@ bool CBaseFlex::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CCh case CChoreoEvent::EXPRESSION: // These are handled client-side return true; + +#ifdef MAPBASE + case CChoreoEvent::GENERIC: + { + // This is handled in CBaseFlex so that any flex entity--including players--could use this text. + if (stricmp(event->GetParameters(), "AI_GAMETEXT") == 0) + { + // game_text-based lines, for placeholders + if ( event->GetParameters2() ) + { + info->m_nType = 12; // SCENE_AI_GAMETEXT + + hudtextparms_t textParams; + textParams.holdTime = event->GetDuration(); + textParams.fadeinTime = 0.5f; + textParams.fadeoutTime = 0.5f; + + textParams.channel = 3; + textParams.x = -1; + textParams.y = 0.6; + textParams.effect = 0; + + textParams.r1 = 255; + textParams.g1 = 255; + textParams.b1 = 255; + + if ( GetGameTextSpeechParams( textParams ) ) + { + CRecipientFilter filter; + filter.AddAllPlayers(); + filter.MakeReliable(); + + UserMessageBegin( filter, "HudMsg" ); + WRITE_BYTE ( textParams.channel & 0xFF ); + WRITE_FLOAT( textParams.x ); + WRITE_FLOAT( textParams.y ); + WRITE_BYTE ( textParams.r1 ); + WRITE_BYTE ( textParams.g1 ); + WRITE_BYTE ( textParams.b1 ); + WRITE_BYTE ( textParams.a1 ); + WRITE_BYTE ( textParams.r2 ); + WRITE_BYTE ( textParams.g2 ); + WRITE_BYTE ( textParams.b2 ); + WRITE_BYTE ( textParams.a2 ); + WRITE_BYTE ( textParams.effect ); + WRITE_FLOAT( textParams.fadeinTime ); + WRITE_FLOAT( textParams.fadeoutTime ); + WRITE_FLOAT( textParams.holdTime ); + WRITE_FLOAT( textParams.fxTime ); + WRITE_STRING( event->GetParameters2() ); + WRITE_STRING( "" ); // No custom font + WRITE_BYTE ( Q_strlen( event->GetParameters2() ) ); + MessageEnd(); + } + return true; + } + } + + return false; + } +#endif } return false; @@ -2004,12 +2090,105 @@ float CBaseFlex::PlayScene( const char *pszScene, float flDelay, AI_Response *re // Input : *soundname - // Output : float //----------------------------------------------------------------------------- +#ifdef MAPBASE +float CBaseFlex::PlayAutoGeneratedSoundScene( const char *soundname, float flDelay, AI_Response *response, IRecipientFilter *filter ) +{ + return InstancedAutoGeneratedSoundScene( this, soundname, NULL, flDelay, false, response, false, filter ); +} +#else float CBaseFlex::PlayAutoGeneratedSoundScene( const char *soundname ) { return InstancedAutoGeneratedSoundScene( this, soundname ); } +#endif + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Parameters for scene event AI_GameText +//----------------------------------------------------------------------------- +bool CBaseFlex::GetGameTextSpeechParams( hudtextparms_t ¶ms ) +{ + ScriptVariant_t varTable; + if (g_pScriptVM->GetValue(m_ScriptScope, "m_GameTextSpeechParams", &varTable) && varTable.m_type == FIELD_HSCRIPT) + { + int nIterator = -1; + ScriptVariant_t varKey, varValue; + while ((nIterator = g_pScriptVM->GetKeyValue( varTable.m_hScript, nIterator, &varKey, &varValue )) != -1) + { + if (FStrEq( varKey.m_pszString, "color" )) + { + params.r1 = varValue.m_pVector->x; + params.g1 = varValue.m_pVector->y; + params.b1 = varValue.m_pVector->z; + } + else if (FStrEq( varKey.m_pszString, "color2" )) + { + params.r2 = varValue.m_pVector->x; + params.g2 = varValue.m_pVector->y; + params.b2 = varValue.m_pVector->z; + } + else if (FStrEq( varKey.m_pszString, "channel" )) + { + params.channel = varValue.m_int; + } + else if (FStrEq( varKey.m_pszString, "x" )) + { + params.x = varValue.m_float; + } + else if (FStrEq( varKey.m_pszString, "y" )) + { + params.y = varValue.m_float; + } + else if (FStrEq( varKey.m_pszString, "effect" )) + { + params.effect = varValue.m_int; + } + else if (FStrEq( varKey.m_pszString, "fxtime" )) + { + params.fxTime = varValue.m_float; + } + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } + } + + return true; +} +#endif +//-------------------------------------------------------------------------------------------------- +// Returns the script instance of the scene entity associated with our oldest ("top level") scene event +//-------------------------------------------------------------------------------------------------- +HSCRIPT CBaseFlex::ScriptGetOldestScene( void ) +{ + if ( m_SceneEvents.Count() > 0 ) + { + CSceneEventInfo curScene = m_SceneEvents.Head(); + return ToHScript( (CBaseEntity*)(curScene.m_hSceneEntity.Get()) ); + } + else + { + return NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +// Returns the script instance of the scene at the specified index, or null if index >= count +//-------------------------------------------------------------------------------------------------- +HSCRIPT CBaseFlex::ScriptGetSceneByIndex( int index ) +{ + if ( m_SceneEvents.IsValidIndex( index ) ) + { + CSceneEventInfo curScene = m_SceneEvents.Element( index ); + return ToHScript( (CBaseEntity*)(curScene.m_hSceneEntity.Get()) ); + } + else + { + return NULL; + } +} // FIXME: move to CBaseActor @@ -2157,8 +2336,13 @@ void CBaseFlex::DoBodyLean( void ) { m_vecPrevVelocity = vecDelta; float decay = ExponentialDecay( 0.5, 0.1, dt ); +#ifdef MAPBASE // From Alien Swarm SDK + m_vecShift = m_vecShift * decay; + m_vecLean = m_vecLean * decay; +#else m_vecShift = m_vecLean * decay; m_vecLean = m_vecShift * decay; +#endif } m_vecPrevOrigin = vecOrigin; @@ -2555,7 +2739,7 @@ void CFlexCycler::Think( void ) { m_flexnum = LookupFlex( szTemp ); - if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1) + if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); diff --git a/game/server/baseflex.h b/game/server/baseflex.h index 1f0009ec..ec809534 100644 --- a/game/server/baseflex.h +++ b/game/server/baseflex.h @@ -19,7 +19,9 @@ struct flexsettinghdr_t; struct flexsetting_t; +#ifndef NEW_RESPONSE_SYSTEM class AI_Response; +#endif //----------------------------------------------------------------------------- // Purpose: A .vfe referenced by a scene during .vcd playback @@ -46,6 +48,8 @@ class CBaseFlex : public CBaseAnimatingOverlay DECLARE_SERVERCLASS(); DECLARE_DATADESC(); DECLARE_PREDICTABLE(); + // script description + DECLARE_ENT_SCRIPTDESC(); // Construction CBaseFlex( void ); @@ -72,7 +76,11 @@ class CBaseFlex : public CBaseAnimatingOverlay void RemoveChoreoScene( CChoreoScene *scene, bool canceled = false ); // Start the specifics of an scene event +#ifdef MAPBASE + virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget, CSceneEntity *pSceneEnt = NULL ); +#else virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); +#endif // Manipulation of events for the object // Should be called by think function to process all scene events @@ -91,7 +99,11 @@ class CBaseFlex : public CBaseAnimatingOverlay virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled ); // Add the event to the queue for this actor +#ifdef MAPBASE + void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget = NULL, CSceneEntity *pSceneEnt = NULL ); +#else void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget = NULL ); +#endif // Remove the event from the queue for this actor void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill ); @@ -116,10 +128,22 @@ class CBaseFlex : public CBaseAnimatingOverlay void SentenceStop( void ) { EmitSound( "AI_BaseNPC.SentenceStop" ); } virtual float PlayScene( const char *pszScene, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); +#ifdef MAPBASE + virtual float PlayAutoGeneratedSoundScene( const char *soundname, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); +#else virtual float PlayAutoGeneratedSoundScene( const char *soundname ); +#endif + + // Returns the script instance of the scene entity associated with our oldest ("top level") scene event + virtual HSCRIPT ScriptGetOldestScene( void ); + virtual HSCRIPT ScriptGetSceneByIndex( int index ); virtual int GetSpecialDSP( void ) { return 0; } +#ifdef MAPBASE + virtual bool GetGameTextSpeechParams( hudtextparms_t ¶ms ); +#endif + protected: // For handling .vfe files // Search list, or add if not in list diff --git a/game/server/basemultiplayerplayer.cpp b/game/server/basemultiplayerplayer.cpp index fee7515d..6fb2c7a9 100644 --- a/game/server/basemultiplayerplayer.cpp +++ b/game/server/basemultiplayerplayer.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //============================================================================= @@ -28,10 +28,11 @@ CBaseMultiplayerPlayer::CBaseMultiplayerPlayer() CBaseMultiplayerPlayer::~CBaseMultiplayerPlayer() { m_pAchievementKV->deleteThis(); + delete m_pExpresser; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CAI_Expresser *CBaseMultiplayerPlayer::CreateExpresser( void ) { @@ -44,7 +45,7 @@ CAI_Expresser *CBaseMultiplayerPlayer::CreateExpresser( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseMultiplayerPlayer::PostConstructor( const char *szClassname ) { @@ -53,7 +54,7 @@ void CBaseMultiplayerPlayer::PostConstructor( const char *szClassname ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseMultiplayerPlayer::ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ) { @@ -63,19 +64,19 @@ void CBaseMultiplayerPlayer::ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -bool CBaseMultiplayerPlayer::SpeakIfAllowed( AIConcept_t concept, const char *modifiers, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter ) -{ +bool CBaseMultiplayerPlayer::SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter ) +{ if ( !IsAlive() ) return false; - //if ( IsAllowedToSpeak( concept, bRespondingToPlayer ) ) - return Speak( concept, modifiers, pszOutResponseChosen, bufsize, filter ); + //if ( IsAllowedToSpeak( conceptId, bRespondingToPlayer ) ) + return Speak( conceptId, modifiers, pszOutResponseChosen, bufsize, filter ); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- IResponseSystem *CBaseMultiplayerPlayer::GetResponseSystem() { @@ -89,13 +90,21 @@ IResponseSystem *CBaseMultiplayerPlayer::GetResponseSystem() //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::SpeakConcept( AI_Response &response, int iConcept ) { - // Save the current concept. m_iCurrentConcept = iConcept; - return SpeakFindResponse( response, g_pszMPConcepts[iConcept] ); +#ifdef NEW_RESPONSE_SYSTEM + CAI_Concept conceptId(g_pszMPConcepts[iConcept]); + conceptId.SetSpeaker(this); + return FindResponse( response, conceptId ); +#else + AI_Response *pResponse = SpeakFindResponse( g_pszMPConcepts[iConcept] ); + if (pResponse) + response = *pResponse; + return pResponse != NULL; +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::SpeakConceptIfAllowed( int iConcept, const char *modifiers, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter ) { @@ -105,7 +114,7 @@ bool CBaseMultiplayerPlayer::SpeakConceptIfAllowed( int iConcept, const char *mo } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::CanHearAndReadChatFrom( CBasePlayer *pPlayer ) { @@ -129,7 +138,7 @@ bool CBaseMultiplayerPlayer::CanHearAndReadChatFrom( CBasePlayer *pPlayer ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const CCommand &args ) { @@ -137,7 +146,7 @@ bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const CCommand &args ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const char *pszCommand ) { @@ -162,7 +171,7 @@ bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const char *pszCommand } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseMultiplayerPlayer::ClientCommand( const CCommand &args ) { @@ -305,7 +314,7 @@ void CBaseMultiplayerPlayer::EscortScoringThink( void ) if ( m_flCapPointScoreRate > 0 ) { - float flTimeForOnePoint = 1.0f / m_flCapPointScoreRate; + float flTimeForOnePoint = 1.0f / m_flCapPointScoreRate; int iPoints = 0; @@ -327,7 +336,7 @@ void CBaseMultiplayerPlayer::EscortScoringThink( void ) } } - SetContextThink( &CBaseMultiplayerPlayer::EscortScoringThink, gpGlobals->curtime + ESCORT_SCORE_INTERVAL, ESCORT_SCORE_CONTEXT ); + SetContextThink( &CBaseMultiplayerPlayer::EscortScoringThink, gpGlobals->curtime + ESCORT_SCORE_INTERVAL, ESCORT_SCORE_CONTEXT ); } //----------------------------------------------------------------------------- diff --git a/game/server/basemultiplayerplayer.h b/game/server/basemultiplayerplayer.h index a1ea58f8..bbf1e685 100644 --- a/game/server/basemultiplayerplayer.h +++ b/game/server/basemultiplayerplayer.h @@ -26,9 +26,9 @@ class CBaseMultiplayerPlayer : public CAI_ExpresserHost virtual void PostConstructor( const char *szClassname ); virtual void ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ); - virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); virtual IResponseSystem *GetResponseSystem(); - bool SpeakConcept( AI_Response& response, int iConcept ); + bool SpeakConcept( AI_Response &response, int iConcept ); virtual bool SpeakConceptIfAllowed( int iConcept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer ); diff --git a/game/server/bmodels.cpp b/game/server/bmodels.cpp index 71be7d39..e8291f8f 100644 --- a/game/server/bmodels.cpp +++ b/game/server/bmodels.cpp @@ -16,9 +16,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#define SF_BRUSH_ACCDCC 16// brush should accelerate and decelerate when toggled -#define SF_BRUSH_HURT 32// rotating brush that inflicts pain based on rotation speed -#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. +//Tony; moved the spawnflags to util.h to prevent more mistakes in the future. // =================== FUNC_WALL ============================================== class CFuncWall : public CBaseEntity @@ -452,6 +450,11 @@ class CFuncRotating : public CBaseEntity bool m_bSolidBsp; // Brush is SOLID_BSP +#ifdef MAPBASE + int m_iMinPitch = 30; // FANPITCHMIN + int m_iMaxPitch = 100; // FANPITCHMAX +#endif + public: Vector m_vecClientOrigin; QAngle m_vecClientAngles; @@ -474,6 +477,10 @@ BEGIN_DATADESC( CFuncRotating ) DEFINE_FIELD( m_angStart, FIELD_VECTOR ), DEFINE_FIELD( m_bStopAtStartPos, FIELD_BOOLEAN ), DEFINE_KEYFIELD( m_bSolidBsp, FIELD_BOOLEAN, "solidbsp" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iMinPitch, FIELD_INTEGER, "minpitch" ), + DEFINE_KEYFIELD( m_iMaxPitch, FIELD_INTEGER, "maxpitch" ), +#endif // Function Pointers DEFINE_FUNCTION( SpinUpMove ), @@ -825,8 +832,14 @@ void CFuncRotating::HurtTouch ( CBaseEntity *pOther ) } +#ifdef MAPBASE +// In Mapbase, use the keyvalues instead +#define FANPITCHMIN m_iMinPitch +#define FANPITCHMAX m_iMaxPitch +#else #define FANPITCHMIN 30 #define FANPITCHMAX 100 +#endif //----------------------------------------------------------------------------- @@ -1092,6 +1105,18 @@ void CFuncRotating::RotateMove( void ) { SetMoveDoneTime( 10 ); +#ifdef MAPBASE + QAngle angNormalizedAngles = GetLocalAngles(); + if (m_vecMoveAng.x) + angNormalizedAngles.x = AngleNormalize( angNormalizedAngles.x ); + if (m_vecMoveAng.y) + angNormalizedAngles.y = AngleNormalize( angNormalizedAngles.y ); + if (m_vecMoveAng.z) + angNormalizedAngles.z = AngleNormalize( angNormalizedAngles.z ); + + SetLocalAngles(angNormalizedAngles); +#endif + if ( m_bStopAtStartPos ) { SetMoveDoneTime( GetNextMoveInterval() ); @@ -1380,6 +1405,9 @@ class CFuncVPhysicsClip : public CBaseEntity void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetFilter( inputdata_t &inputdata ); +#endif private: @@ -1394,10 +1422,17 @@ BEGIN_DATADESC( CFuncVPhysicsClip ) // Keyfields DEFINE_KEYFIELD( m_iFilterName, FIELD_STRING, "filtername" ), DEFINE_FIELD( m_hFilter, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), +#else DEFINE_FIELD( m_bDisabled, FIELD_BOOLEAN ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetFilter", InputSetFilter ), +#endif END_DATADESC() @@ -1440,6 +1475,12 @@ bool CFuncVPhysicsClip::EntityPassesFilter( CBaseEntity *pOther ) if ( pFilter ) return pFilter->PassesFilter( this, pOther ); +#ifdef MAPBASE + // I couldn't figure out what else made this crash. The entity shouldn't be NULL. + if ( !pOther->VPhysicsGetObject() ) + return false; +#endif + if ( pOther->GetMoveType() == MOVETYPE_VPHYSICS && pOther->VPhysicsGetObject()->IsMoveable() ) return true; @@ -1463,3 +1504,19 @@ void CFuncVPhysicsClip::InputDisable( inputdata_t &inputdata ) VPhysicsGetObject()->EnableCollisions(false); m_bDisabled = true; } + +#ifdef MAPBASE +void CFuncVPhysicsClip::InputSetFilter( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity()) + { + m_iFilterName = inputdata.value.Entity()->GetEntityName(); + m_hFilter = dynamic_cast(inputdata.value.Entity().Get()); + } + else + { + m_iFilterName = NULL_STRING; + m_hFilter = NULL; + } +} +#endif diff --git a/game/server/buttons.cpp b/game/server/buttons.cpp index af46d0c4..47472d43 100644 --- a/game/server/buttons.cpp +++ b/game/server/buttons.cpp @@ -898,6 +898,13 @@ void CRotButton::Spawn( void ) SetUse(&CRotButton::ButtonUse); +#ifdef MAPBASE + if (HasSpawnFlags(SF_BUTTON_LOCKED)) + { + m_bLocked = true; + } +#endif + // // If touching activates the button, set its touch function. // diff --git a/game/server/cbase.cpp b/game/server/cbase.cpp index d6627b4b..abee7a5d 100644 --- a/game/server/cbase.cpp +++ b/game/server/cbase.cpp @@ -84,6 +84,10 @@ some of these can overlap. all the data descriptions usable are: #include "tier1/strtools.h" #include "datacache/imdlcache.h" #include "env_debughistory.h" +#ifdef MAPBASE +#include "mapbase/variant_tools.h" +#include "mapbase/matchers.h" +#endif #include "tier0/vprof.h" @@ -132,7 +136,7 @@ CEventAction::CEventAction( const char *ActionData ) // // Parse the target name. // - const char *psz = nexttoken(szToken, ActionData, ','); + const char *psz = nexttoken(szToken, ActionData, ',', sizeof(szToken)); if (szToken[0] != '\0') { m_iTarget = AllocPooledString(szToken); @@ -141,7 +145,7 @@ CEventAction::CEventAction( const char *ActionData ) // // Parse the input name. // - psz = nexttoken(szToken, psz, ','); + psz = nexttoken(szToken, psz, ',', sizeof(szToken)); if (szToken[0] != '\0') { m_iTargetInput = AllocPooledString(szToken); @@ -154,7 +158,7 @@ CEventAction::CEventAction( const char *ActionData ) // // Parse the parameter override. // - psz = nexttoken(szToken, psz, ','); + psz = nexttoken(szToken, psz, ',', sizeof(szToken)); if (szToken[0] != '\0') { m_iParameter = AllocPooledString(szToken); @@ -163,7 +167,7 @@ CEventAction::CEventAction( const char *ActionData ) // // Parse the delay. // - psz = nexttoken(szToken, psz, ','); + psz = nexttoken(szToken, psz, ',', sizeof(szToken)); if (szToken[0] != '\0') { m_flDelay = atof(szToken); @@ -172,7 +176,7 @@ CEventAction::CEventAction( const char *ActionData ) // // Parse the number of times to fire. // - nexttoken(szToken, psz, ','); + nexttoken(szToken, psz, ',', sizeof(szToken)); if (szToken[0] != '\0') { m_nTimesToFire = atoi(szToken); @@ -272,7 +276,12 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa // variant_t ValueOverride; ValueOverride.SetString( ev->m_iParameter ); +#ifdef MAPBASE + // I found this while making point_advanced_finder. FireOutput()'s own delay parameter doesn't work with...uh...parameters. + g_EventQueue.AddEvent( STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), ValueOverride, ev->m_flDelay + fDelay, pActivator, pCaller, ev->m_iIDStamp ); +#else g_EventQueue.AddEvent( STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), ValueOverride, ev->m_flDelay, pActivator, pCaller, ev->m_iIDStamp ); +#endif } if ( ev->m_flDelay ) @@ -293,7 +302,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa ev->m_flDelay, STRING(ev->m_iParameter) ); +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "%s", szBuffer ); +#else DevMsg( 2, "%s", szBuffer ); +#endif ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer ); } else @@ -312,7 +325,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa STRING(ev->m_iTargetInput), STRING(ev->m_iParameter) ); +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "%s", szBuffer ); +#else DevMsg( 2, "%s", szBuffer ); +#endif ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer ); } @@ -333,7 +350,12 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa { char szBuffer[256]; Q_snprintf( szBuffer, sizeof(szBuffer), "Removing from action list: (%s,%s) -> (%s,%s)\n", pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput)); + +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "%s", szBuffer ); +#else DevMsg( 2, "%s", szBuffer ); +#endif ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer ); bRemove = true; } @@ -387,6 +409,28 @@ void CBaseEntityOutput::AddEventAction( CEventAction *pEventAction ) m_ActionList = pEventAction; } +void CBaseEntityOutput::RemoveEventAction( CEventAction *pEventAction ) +{ + CEventAction *pAction = GetActionList(); + CEventAction *pPrevAction = NULL; + while ( pAction ) + { + if ( pAction == pEventAction ) + { + if ( !pPrevAction ) + { + m_ActionList = NULL; + } + else + { + pPrevAction->m_pNext = pAction->m_pNext; + } + return; + } + pAction = pAction->m_pNext; + } +} + // save data description for the event queue BEGIN_SIMPLE_DATADESC( CBaseEntityOutput ) @@ -467,7 +511,7 @@ void CBaseEntityOutput::DeleteAllElements( void ) m_ActionList = NULL; while (pNext) { - CEventAction *strikeThis = pNext; + register CEventAction *strikeThis = pNext; pNext = pNext->m_pNext; delete strikeThis; } @@ -805,7 +849,12 @@ void CEventQueue::Dump( void ) //----------------------------------------------------------------------------- // Purpose: adds the action into the correct spot in the priority queue, targeting entity via string name //----------------------------------------------------------------------------- -void CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID ) +#ifdef MAPBASE_VSCRIPT +int +#else +void +#endif +CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID ) { // build the new event EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t; @@ -823,12 +872,22 @@ void CEventQueue::AddEvent( const char *target, const char *targetInput, variant newEvent->m_iOutputID = outputID; AddEvent( newEvent ); + +#ifdef MAPBASE_VSCRIPT + Assert( sizeof(EventQueuePrioritizedEvent_t*) == sizeof(int) ); + return reinterpret_cast(newEvent); // POINTER_TO_INT +#endif } //----------------------------------------------------------------------------- // Purpose: adds the action into the correct spot in the priority queue, targeting entity via pointer //----------------------------------------------------------------------------- -void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID ) +#ifdef MAPBASE_VSCRIPT +int +#else +void +#endif +CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID ) { // build the new event EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t; @@ -846,6 +905,11 @@ void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, varian newEvent->m_iOutputID = outputID; AddEvent( newEvent ); + +#ifdef MAPBASE_VSCRIPT + Assert( sizeof(EventQueuePrioritizedEvent_t*) == sizeof(int) ); + return reinterpret_cast(newEvent); // POINTER_TO_INT +#endif } void CEventQueue::AddEvent( CBaseEntity *target, const char *action, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID ) @@ -922,17 +986,32 @@ void CEventQueue::ServiceEvents( void ) { // In the context the event, the searching entity is also the caller CBaseEntity *pSearchingEntity = pe->m_pCaller; - CBaseEntity *target = NULL; - while ( 1 ) +#ifdef MAPBASE + // This is a hack to access the entity from a FIELD_EHANDLE input + if ( FStrEq( STRING( pe->m_iTarget ), "!output" ) ) { - target = gEntList.FindEntityByName( target, pe->m_iTarget, pSearchingEntity, pe->m_pActivator, pe->m_pCaller ); - if ( !target ) - break; + pe->m_VariantValue.Convert( FIELD_EHANDLE ); + CBaseEntity *target = pe->m_VariantValue.Entity(); // pump the action into the target - target->AcceptInput( STRING(pe->m_iTargetInput), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID ); + target->AcceptInput( STRING( pe->m_iTargetInput ), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID ); targetFound = true; } + else +#endif + { + CBaseEntity *target = NULL; + while ( 1 ) + { + target = gEntList.FindEntityByName( target, pe->m_iTarget, pSearchingEntity, pe->m_pActivator, pe->m_pCaller ); + if ( !target ) + break; + + // pump the action into the target + target->AcceptInput( STRING(pe->m_iTargetInput), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID ); + targetFound = true; + } + } } // direct pointer @@ -974,7 +1053,11 @@ void CEventQueue::ServiceEvents( void ) char szBuffer[256]; Q_snprintf( szBuffer, sizeof(szBuffer), "unhandled input: (%s) -> (%s), from (%s,%s); target entity not found\n", STRING(pe->m_iTargetInput), STRING(pe->m_iTarget), pClass, pName ); +#ifdef MAPBASE + CGMsg( 2, CON_GROUP_IO_SYSTEM, "%s", szBuffer ); +#else DevMsg( 2, "%s", szBuffer ); +#endif ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer ); } @@ -1122,6 +1205,77 @@ void ServiceEventQueue( void ) } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Remove pending events on entity by input. +// +// Also removes events that were targeted with their debug name (classname when unnamed). +// E.g. CancelEventsByInput( pRelay, "Trigger" ) removes all pending logic_relay "Trigger" events. +//----------------------------------------------------------------------------- +void CEventQueue::CancelEventsByInput( CBaseEntity *pTarget, const char *szInput ) +{ + if ( !pTarget ) + return; + + string_t iszDebugName = MAKE_STRING( pTarget->GetDebugName() ); + EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext; + + while ( pCur ) + { + bool bRemove = false; + + if ( pTarget == pCur->m_pEntTarget || pCur->m_iTarget == iszDebugName ) + { + if ( !V_strncmp( STRING(pCur->m_iTargetInput), szInput, strlen(szInput) ) ) + { + bRemove = true; + } + } + + EventQueuePrioritizedEvent_t *pPrev = pCur; + pCur = pCur->m_pNext; + + if ( bRemove ) + { + RemoveEvent(pPrev); + delete pPrev; + } + } +} + +bool CEventQueue::RemoveEvent( int event ) +{ + EventQueuePrioritizedEvent_t *pe = reinterpret_cast(event); // INT_TO_POINTER + + for ( EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext; pCur; pCur = pCur->m_pNext ) + { + if ( pCur == pe ) + { + RemoveEvent(pCur); + delete pCur; + return true; + } + } + + return false; +} + +float CEventQueue::GetTimeLeft( int event ) +{ + EventQueuePrioritizedEvent_t *pe = reinterpret_cast(event); // INT_TO_POINTER + + for ( EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext; pCur; pCur = pCur->m_pNext ) + { + if ( pCur == pe ) + { + return (pCur->m_flFireTime - gpGlobals->curtime); + } + } + + return 0.f; +} +#endif // MAPBASE_VSCRIPT + // save data description for the event queue BEGIN_SIMPLE_DATADESC( CEventQueue ) @@ -1252,6 +1406,23 @@ void variant_t::Set( fieldtype_t ftype, void *data ) break; } +#ifdef MAPBASE + // There's this output class called COutputVariant which could output any data type, like a FIELD_INPUT input function. + // Well...nobody added support for it. It was there, but it wasn't functional. + // Mapbase adds support for it so you could variant your outputs as you please. + case FIELD_INPUT: + { + variant_t *variant = (variant_t*)data; + + // Pretty much just copying over its stored value. + fieldType = variant->FieldType(); + variant->SetOther(data); + + Set(fieldType, data); + break; + } +#endif + case FIELD_EHANDLE: eVal = *((EHANDLE *)data); break; case FIELD_CLASSPTR: eVal = *((CBaseEntity **)data); break; case FIELD_VOID: @@ -1292,6 +1463,10 @@ void variant_t::SetOther( void *data ) } } +#ifdef MAPBASE +// This way we don't have to use string comparisons when reading failed conversions +static const char *g_szNoConversion = "No conversion to string"; +#endif //----------------------------------------------------------------------------- // Purpose: Converts the variant to a new type. This function defines which I/O @@ -1324,6 +1499,24 @@ bool variant_t::Convert( fieldtype_t newType ) return true; } +#ifdef MAPBASE + if (newType == FIELD_STRING) + { + // I got a conversion error when I tried to convert int to string. I'm actually quite baffled. + // Was that case really not handled before? Did I do something that overrode something that already did this? + const char *szString = ToString(); + + // g_szNoConversion is returned in ToString() when we can't convert to a string, + // so this is safe and it lets us get away with a pointer comparison. + if (szString != g_szNoConversion) + { + SetString(AllocPooledString(szString)); + return true; + } + return false; + } +#endif + switch ( fieldType ) { case FIELD_INTEGER: @@ -1441,8 +1634,14 @@ bool variant_t::Convert( fieldtype_t newType ) CBaseEntity *ent = NULL; if ( iszVal != NULL_STRING ) { +#ifdef MAPBASE + // We search by both entity name and class name now. + // We also have an entirely new version of Convert specifically for !activators on FIELD_EHANDLE. + ent = gEntList.FindEntityGeneric( NULL, STRING(iszVal) ); +#else // FIXME: do we need to pass an activator in here? ent = gEntList.FindEntityByName( NULL, iszVal ); +#endif } SetEntity( ent ); return true; @@ -1452,6 +1651,7 @@ bool variant_t::Convert( fieldtype_t newType ) break; } +#ifndef MAPBASE // ToString() above handles this case FIELD_EHANDLE: { switch ( newType ) @@ -1469,12 +1669,64 @@ bool variant_t::Convert( fieldtype_t newType ) } break; } +#endif + +#ifdef MAPBASE + case FIELD_VOID: + { + // Many fields already turn into some equivalent of "NULL" when given a null string_t. + // This takes advantage of that and allows FIELD_VOID to be converted to more than just empty strings. + SetString(NULL_STRING); + return Convert(newType); + } +#endif } // invalid conversion return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Only for when something like !activator needs to become a FIELD_EHANDLE, or when that's a possibility. +//----------------------------------------------------------------------------- +bool variant_t::Convert( fieldtype_t newType, CBaseEntity *pSelf, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + // Support for turning !activator, !caller, and !self into a FIELD_EHANDLE. + // Extremely necessary. + if (newType == FIELD_EHANDLE) + { + if (newType == fieldType) + return true; + + CBaseEntity *ent = NULL; + if (iszVal != NULL_STRING) + { + ent = gEntList.FindEntityGeneric(NULL, STRING(iszVal), pSelf, pActivator, pCaller); + } + SetEntity(ent); + return true; + } + +#if 0 // This was scrapped almost immediately. See the Trello card for details. + // Serves as a way of converting the name of the !activator, !caller, or !self into a string + // without passing the text "!activator" and stuff. + else if (fieldType == FIELD_STRING && STRING(iszVal)[0] == '&') + { + const char *val = STRING(iszVal) + 1; + + #define GetRealName(string, ent) if (FStrEq(val, string)) { if (ent) {SetString(ent->GetEntityName());} return true; } + + GetRealName("!activator", pActivator) + else GetRealName("!caller", pCaller) + else GetRealName("!self", pSelf) + } +#endif + + return Convert(newType); +} +#endif + //----------------------------------------------------------------------------- // Purpose: All types must be able to display as strings for debugging purposes. @@ -1542,13 +1794,22 @@ const char *variant_t::ToString( void ) const case FIELD_EHANDLE: { +#ifdef MAPBASE + // This is a really bad idea. + const char *pszName = (Entity()) ? Entity()->GetDebugName() : "<>"; +#else const char *pszName = (Entity()) ? STRING(Entity()->GetEntityName()) : "<>"; +#endif Q_strncpy( szBuf, pszName, 512 ); return (szBuf); } } +#ifdef MAPBASE + return g_szNoConversion; +#else return("No conversion to string"); +#endif } #define classNameTypedef variant_t // to satisfy DEFINE... macros @@ -1756,6 +2017,21 @@ class CVariantSaveDataOps : public CDefSaveRestoreOps // Don't no how to. This is okay, since objects of this type // are always born clean before restore, and not reused } + +#ifdef MAPBASE + // Parses a keyvalue string into a variant_t. + // We could just turn it into a string since variant_t can convert it later, but this keyvalue is probably a variant_t for a reason, + // meaning it might use strings and numbers completely differently without converting them. + // As a result, we try to read it to figure out what type it is. + virtual bool Parse( const SaveRestoreFieldInfo_t &fieldInfo, char const* szValue ) + { + variant_t *var = (variant_t*)fieldInfo.pField; + + *var = Variant_Parse(szValue); + + return true; + } +#endif }; CVariantSaveDataOps g_VariantSaveDataOps; diff --git a/game/server/cbase.h b/game/server/cbase.h index 2173cd6d..2b00af39 100644 --- a/game/server/cbase.h +++ b/game/server/cbase.h @@ -80,6 +80,9 @@ #include "baseentity_shared.h" #include "basetoggle.h" #include "igameevents.h" +#ifdef MAPBASE +#include "tier1/mapbase_con_groups.h" +#endif // saverestore.h declarations class ISave; @@ -101,6 +104,13 @@ extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseE #define MAX_OLD_ENEMIES 4 // how many old enemies to remember +#ifdef MAPBASE +// Use the model keyvalue if it is defined +#define DefaultOrCustomModel(defaultModel) GetModelName() != NULL_STRING ? STRING(GetModelName()) : defaultModel +#else +#define DefaultOrCustomModel() defaultModel +#endif + // used by suit voice to indicate damage sustained and repaired type to player enum @@ -114,10 +124,6 @@ enum itbd_SlowBurn, itbd_SlowFreeze, -#ifdef VANCE - itbd_Bleed, -#endif - // Must be last! CDMG_TIMEBASED }; diff --git a/game/server/client.cpp b/game/server/client.cpp index eced1df1..087d023f 100644 --- a/game/server/client.cpp +++ b/game/server/client.cpp @@ -45,6 +45,10 @@ #include "weapon_physcannon.h" #endif +#ifdef MAPBASE +#include "fmtstr.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -57,60 +61,6 @@ extern bool IsInCommentaryMode( void ); ConVar *sv_cheats = NULL; -enum eAllowPointServerCommand { - eAllowNever, - eAllowOfficial, - eAllowAlways -}; - -#ifdef TF_DLL -// The default value here should match the default of the convar -eAllowPointServerCommand sAllowPointServerCommand = eAllowOfficial; -#else -eAllowPointServerCommand sAllowPointServerCommand = eAllowAlways; -#endif // TF_DLL - -void sv_allow_point_servercommand_changed( IConVar *pConVar, const char *pOldString, float flOldValue ) -{ - ConVarRef var( pConVar ); - if ( !var.IsValid() ) - { - return; - } - - const char *pNewValue = var.GetString(); - if ( V_strcasecmp ( pNewValue, "always" ) == 0 ) - { - sAllowPointServerCommand = eAllowAlways; - } -#ifdef TF_DLL - else if ( V_strcasecmp ( pNewValue, "official" ) == 0 ) - { - sAllowPointServerCommand = eAllowOfficial; - } -#endif // TF_DLL - else - { - sAllowPointServerCommand = eAllowNever; - } -} - -ConVar sv_allow_point_servercommand ( "sv_allow_point_servercommand", -#ifdef TF_DLL - // The default value here should match the default of the convar - "official", -#else - // Other games may use this in their official maps, and only TF exposes IsValveMap() currently - "always", -#endif // TF_DLL - FCVAR_NONE, - "Allow use of point_servercommand entities in map. Potentially dangerous for untrusted maps.\n" - " disallow : Always disallow\n" -#ifdef TF_DLL - " official : Allowed for valve maps only\n" -#endif // TF_DLL - " always : Allow for all maps", sv_allow_point_servercommand_changed ); - void ClientKill( edict_t *pEdict, const Vector &vecForce, bool bExplode = false ) { CBasePlayer *pPlayer = static_cast( GetContainingEntity( pEdict ) ); @@ -388,6 +338,16 @@ void ClientPrecache( void ) CBaseEntity::PrecacheScriptSound( "Bounce.Shell" ); CBaseEntity::PrecacheScriptSound( "Bounce.Concrete" ); +#ifdef MAPBASE + // Game Instructor sounds + CBaseEntity::PrecacheScriptSound( "Instructor.LessonStart" ); + CBaseEntity::PrecacheScriptSound( "Instructor.ImportantLessonStart" ); + + // TODO: Does sv_pure cover this? This is from the ASW SDK to prevent people from making simple scripted wall hacks + //engine->ForceExactFile( "scripts/instructor_lessons.txt" ); + //engine->ForceExactFile( "scripts/mod_lessons.txt" ); +#endif + ClientGamePrecache(); } @@ -623,22 +583,7 @@ void CPointServerCommand::InputCommand( inputdata_t& inputdata ) if ( !inputdata.value.String()[0] ) return; - bool bAllowed = ( sAllowPointServerCommand == eAllowAlways ); -#ifdef TF_DLL - if ( sAllowPointServerCommand == eAllowOfficial ) - { - bAllowed = TFGameRules() && TFGameRules()->IsValveMap(); - } -#endif // TF_DLL - - if ( bAllowed ) - { - engine->ServerCommand( UTIL_VarArgs( "%s\n", inputdata.value.String() ) ); - } - else - { - Warning( "point_servercommand usage blocked by sv_allow_point_servercommand setting\n" ); - } + engine->ServerCommand( UTIL_VarArgs( "%s\n", inputdata.value.String() ) ); } BEGIN_DATADESC( CPointServerCommand ) @@ -669,7 +614,7 @@ void CC_DrawLine( const CCommand &args ) static ConCommand drawline("drawline", CC_DrawLine, "Draws line between two 3D Points.\n\tGreen if no collision\n\tRed is collides with something\n\tArguments: x1 y1 z1 x2 y2 z2", FCVAR_CHEAT); //------------------------------------------------------------------------------ -// Purpose : Draw a cross at a points. +// Purpose : Draw a cross at a points. // Input : // Output : //------------------------------------------------------------------------------ @@ -1418,7 +1363,6 @@ void CC_HurtMe_f(const CCommand &args) static ConCommand hurtme("hurtme", CC_HurtMe_f, "Hurts the player.\n\tArguments: ", FCVAR_CHEAT); -#ifdef DBGFLAG_ASSERT static bool IsInGroundList( CBaseEntity *ent, CBaseEntity *ground ) { if ( !ground || !ent ) @@ -1438,8 +1382,8 @@ static bool IsInGroundList( CBaseEntity *ent, CBaseEntity *ground ) } return false; + } -#endif static int DescribeGroundList( CBaseEntity *ent ) { @@ -1591,6 +1535,32 @@ void ClientCommand( CBasePlayer *pPlayer, const CCommand &args ) { if ( !g_pGameRules->ClientCommand( pPlayer, args ) ) { +#ifdef MAPBASE_VSCRIPT + // Console command hook for VScript + if ( pPlayer->m_ScriptScope.IsInitialized() ) + { + ScriptVariant_t functionReturn; + g_pScriptVM->SetValue( "command", ScriptVariant_t( pCmd ) ); + + ScriptVariant_t varTable; + g_pScriptVM->CreateTable( varTable ); + HSCRIPT hTable = varTable.m_hScript; + for ( int i = 0; i < args.ArgC(); i++ ) + { + g_pScriptVM->SetValue( hTable, CNumStr( i ), ScriptVariant_t( args[i] ) ); + } + g_pScriptVM->SetValue( "args", varTable ); + + pPlayer->CallScriptFunction( "ClientCommand", &functionReturn ); + + g_pScriptVM->ClearValue( "command" ); + g_pScriptVM->ClearValue( "args" ); + g_pScriptVM->ReleaseValue( varTable ); + + if (functionReturn.m_bool) + return; + } +#endif if ( Q_strlen( pCmd ) > 128 ) { ClientPrint( pPlayer, HUD_PRINTCONSOLE, "Console command too long.\n" ); diff --git a/game/server/colorcorrection.cpp b/game/server/colorcorrection.cpp index 16d01222..69e6db85 100644 --- a/game/server/colorcorrection.cpp +++ b/game/server/colorcorrection.cpp @@ -5,9 +5,8 @@ // $NoKeywords: $ //===========================================================================// -#include - #include "cbase.h" +#include "colorcorrection.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -16,64 +15,6 @@ static const char *s_pFadeInContextThink = "ColorCorrectionFadeInThink"; static const char *s_pFadeOutContextThink = "ColorCorrectionFadeOutThink"; - -//------------------------------------------------------------------------------ -// FIXME: This really should inherit from something more lightweight -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Purpose : Shadow control entity -//------------------------------------------------------------------------------ -class CColorCorrection : public CBaseEntity -{ - DECLARE_CLASS( CColorCorrection, CBaseEntity ); -public: - DECLARE_SERVERCLASS(); - DECLARE_DATADESC(); - - CColorCorrection(); - - void Spawn( void ); - int UpdateTransmitState(); - void Activate( void ); - - virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - // Inputs - void InputEnable( inputdata_t &inputdata ); - void InputDisable( inputdata_t &inputdata ); - void InputSetFadeInDuration ( inputdata_t &inputdata ); - void InputSetFadeOutDuration ( inputdata_t &inputdata ); - -private: - void FadeIn ( void ); - void FadeOut ( void ); - - void FadeInThink( void ); // Fades lookup weight from Cur->MaxWeight - void FadeOutThink( void ); // Fades lookup weight from CurWeight->0.0 - - - - float m_flFadeInDuration; // Duration for a full 0->MaxWeight transition - float m_flFadeOutDuration; // Duration for a full Max->0 transition - float m_flStartFadeInWeight; - float m_flStartFadeOutWeight; - float m_flTimeStartFadeIn; - float m_flTimeStartFadeOut; - - float m_flMaxWeight; - - bool m_bStartDisabled; - CNetworkVar( bool, m_bEnabled ); - - CNetworkVar( float, m_MinFalloff ); - CNetworkVar( float, m_MaxFalloff ); - CNetworkVar( float, m_flCurWeight ); - CNetworkString( m_netlookupFilename, MAX_PATH ); - - string_t m_lookupFilename; -}; LINK_ENTITY_TO_CLASS(color_correction, CColorCorrection); @@ -97,12 +38,19 @@ BEGIN_DATADESC( CColorCorrection ) DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "enabled" ), DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ), +#ifdef MAPBASE // From Alien Swarm SDK + DEFINE_KEYFIELD( m_bExclusive, FIELD_BOOLEAN, "exclusive" ), +#endif // DEFINE_ARRAY( m_netlookupFilename, FIELD_CHARACTER, MAX_PATH ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeInDuration", InputSetFadeInDuration ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeOutDuration", InputSetFadeOutDuration ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMinFalloff", InputSetMinFalloff ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxFalloff", InputSetMaxFalloff ), +#endif END_DATADESC() @@ -112,8 +60,18 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CColorCorrection, DT_ColorCorrection) SendPropFloat( SENDINFO(m_MinFalloff) ), SendPropFloat( SENDINFO(m_MaxFalloff) ), SendPropFloat( SENDINFO(m_flCurWeight) ), +#ifdef MAPBASE // From Alien Swarm SDK + SendPropFloat( SENDINFO(m_flMaxWeight) ), + SendPropFloat( SENDINFO(m_flFadeInDuration) ), + SendPropFloat( SENDINFO(m_flFadeOutDuration) ), +#endif SendPropString( SENDINFO(m_netlookupFilename) ), SendPropBool( SENDINFO(m_bEnabled) ), +#ifdef MAPBASE // From Alien Swarm SDK + SendPropBool( SENDINFO(m_bMaster) ), + SendPropBool( SENDINFO(m_bClientSide) ), + SendPropBool( SENDINFO(m_bExclusive) ), +#endif END_SEND_TABLE() @@ -132,6 +90,11 @@ CColorCorrection::CColorCorrection() : BaseClass() m_flTimeStartFadeOut = 0.0f; m_netlookupFilename.GetForModify()[0] = 0; m_lookupFilename = NULL_STRING; +#ifdef MAPBASE // From Alien Swarm SDK + m_bMaster = false; + m_bClientSide = false; + m_bExclusive = false; +#endif } @@ -175,6 +138,11 @@ void CColorCorrection::Activate( void ) { BaseClass::Activate(); +#ifdef MAPBASE // From Alien Swarm SDK (moved to Activate() for save/restore support) + m_bMaster = IsMaster(); + m_bClientSide = IsClientSide(); +#endif + Q_strncpy( m_netlookupFilename.GetForModify(), STRING( m_lookupFilename ), MAX_PATH ); } @@ -183,6 +151,11 @@ void CColorCorrection::Activate( void ) //----------------------------------------------------------------------------- void CColorCorrection::FadeIn ( void ) { +#ifdef MAPBASE // From Alien Swarm SDK + if ( m_bClientSide || ( m_bEnabled && m_flCurWeight >= m_flMaxWeight ) ) + return; +#endif + m_bEnabled = true; m_flTimeStartFadeIn = gpGlobals->curtime; m_flStartFadeInWeight = m_flCurWeight; @@ -194,6 +167,11 @@ void CColorCorrection::FadeIn ( void ) //----------------------------------------------------------------------------- void CColorCorrection::FadeOut ( void ) { +#ifdef MAPBASE // From Alien Swarm SDK + if ( m_bClientSide || ( !m_bEnabled && m_flCurWeight <= 0.0f ) ) + return; +#endif + m_bEnabled = false; m_flTimeStartFadeOut = gpGlobals->curtime; m_flStartFadeOutWeight = m_flCurWeight; @@ -230,7 +208,11 @@ void CColorCorrection::FadeInThink( void ) flFadeRatio = clamp ( flFadeRatio, 0.0f, 1.0f ); m_flStartFadeInWeight = clamp ( m_flStartFadeInWeight, 0.0f, 1.0f ); +#ifdef MAPBASE + m_flCurWeight = Lerp( flFadeRatio, m_flStartFadeInWeight, m_flMaxWeight.Get() ); +#else m_flCurWeight = Lerp( flFadeRatio, m_flStartFadeInWeight, m_flMaxWeight ); +#endif SetNextThink( gpGlobals->curtime + COLOR_CORRECTION_ENT_THINK_RATE, s_pFadeInContextThink ); } @@ -312,3 +294,94 @@ void CColorCorrection::InputSetFadeOutDuration( inputdata_t& inputdata ) { m_flFadeOutDuration = inputdata.value.Float(); } + +#ifdef MAPBASE +void CColorCorrection::InputSetMinFalloff( inputdata_t& inputdata ) +{ + m_MinFalloff = inputdata.value.Float(); +} + +void CColorCorrection::InputSetMaxFalloff( inputdata_t& inputdata ) +{ + m_MaxFalloff = inputdata.value.Float(); +} +#endif + +#ifdef MAPBASE // From Alien Swarm SDK +CColorCorrectionSystem s_ColorCorrectionSystem( "ColorCorrectionSystem" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CColorCorrectionSystem *ColorCorrectionSystem( void ) +{ + return &s_ColorCorrectionSystem; +} + + +//----------------------------------------------------------------------------- +// Purpose: Clear out the fog controller. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::LevelInitPreEntity( void ) +{ + m_hMasterController = NULL; + ListenForGameEvent( "round_start" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Find the master controller. If no controller is +// set as Master, use the first controller found. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::InitMasterController( void ) +{ + CColorCorrection *pColorCorrection = NULL; + do + { + pColorCorrection = static_cast( gEntList.FindEntityByClassname( pColorCorrection, "color_correction" ) ); + if ( pColorCorrection ) + { + if ( m_hMasterController.Get() == NULL ) + { + m_hMasterController = pColorCorrection; + } + else + { + if ( pColorCorrection->IsMaster() ) + { + m_hMasterController = pColorCorrection; + } + } + } + } while ( pColorCorrection ); +} + +//----------------------------------------------------------------------------- +// Purpose: On a multiplayer map restart, re-find the master controller. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::FireGameEvent( IGameEvent *pEvent ) +{ + InitMasterController(); +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master fog controller. If no controller is +// set as Master, use the first fog controller found. +//----------------------------------------------------------------------------- +void CColorCorrectionSystem::LevelInitPostEntity( void ) +{ + InitMasterController(); + + // HACK: Singleplayer games don't get a call to CBasePlayer::Spawn on level transitions. + // CBasePlayer::Activate is called before this is called so that's too soon to set up the fog controller. + // We don't have a hook similar to Activate that happens after LevelInitPostEntity + // is called, or we could just do this in the player itself. + if ( gpGlobals->maxClients == 1 ) + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer && ( pPlayer->m_hColorCorrectionCtrl.Get() == NULL ) ) + { + pPlayer->InitColorCorrectionController(); + } + } +} +#endif diff --git a/game/server/colorcorrection.h b/game/server/colorcorrection.h new file mode 100644 index 00000000..2e96eb7c --- /dev/null +++ b/game/server/colorcorrection.h @@ -0,0 +1,147 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: Color correction entity. +// +//=============================================================================// + +#ifndef COLOR_CORRECTION_H +#define COLOR_CORRECTION_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "cbase.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "GameEventListener.h" + +// Spawn Flags +#define SF_COLORCORRECTION_MASTER 0x0001 +#define SF_COLORCORRECTION_CLIENTSIDE 0x0002 +#endif + +//------------------------------------------------------------------------------ +// FIXME: This really should inherit from something more lightweight +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Purpose : Shadow control entity +//------------------------------------------------------------------------------ +class CColorCorrection : public CBaseEntity +{ + DECLARE_CLASS( CColorCorrection, CBaseEntity ); +public: + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + + CColorCorrection(); + + void Spawn( void ); + int UpdateTransmitState(); + void Activate( void ); + + virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + +#ifdef MAPBASE // From Alien Swarm SDK + bool IsMaster( void ) const { return HasSpawnFlags( SF_COLORCORRECTION_MASTER ); } + + bool IsClientSide( void ) const { return HasSpawnFlags( SF_COLORCORRECTION_CLIENTSIDE ); } + + bool IsExclusive( void ) const { return m_bExclusive; } +#endif + + // Inputs + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputSetFadeInDuration ( inputdata_t &inputdata ); + void InputSetFadeOutDuration ( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetMinFalloff( inputdata_t &inputdata ); + void InputSetMaxFalloff( inputdata_t &inputdata ); +#endif + +private: + void FadeIn ( void ); + void FadeOut ( void ); + + void FadeInThink( void ); // Fades lookup weight from Cur->MaxWeight + void FadeOutThink( void ); // Fades lookup weight from CurWeight->0.0 + + + +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_flFadeInDuration ); // Duration for a full 0->MaxWeight transition + CNetworkVar( float, m_flFadeOutDuration ); // Duration for a full Max->0 transition +#else + float m_flFadeInDuration; // Duration for a full 0->MaxWeight transition + float m_flFadeOutDuration; // Duration for a full Max->0 transition +#endif + float m_flStartFadeInWeight; + float m_flStartFadeOutWeight; + float m_flTimeStartFadeIn; + float m_flTimeStartFadeOut; + +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_flMaxWeight ); +#else + float m_flMaxWeight; +#endif + + bool m_bStartDisabled; + CNetworkVar( bool, m_bEnabled ); +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( bool, m_bMaster ); + CNetworkVar( bool, m_bClientSide ); + CNetworkVar( bool, m_bExclusive ); +#endif + + CNetworkVar( float, m_MinFalloff ); + CNetworkVar( float, m_MaxFalloff ); + CNetworkVar( float, m_flCurWeight ); + CNetworkString( m_netlookupFilename, MAX_PATH ); + + string_t m_lookupFilename; +}; + +#ifdef MAPBASE // From Alien Swarm SDK +//============================================================================= +// +// ColorCorrection Controller System. Just a place to store a master controller +// +class CColorCorrectionSystem : public CAutoGameSystem, public CGameEventListener +{ +public: + + // Creation/Init. + CColorCorrectionSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = NULL; + } + + ~CColorCorrectionSystem() + { + m_hMasterController = NULL; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + virtual void FireGameEvent( IGameEvent *pEvent ); + CColorCorrection *GetMasterColorCorrection( void ) { return m_hMasterController; } + +private: + + void InitMasterController( void ); + CHandle< CColorCorrection > m_hMasterController; +}; + +CColorCorrectionSystem *ColorCorrectionSystem( void ); +#endif + +#endif // COLOR_CORRECTION_H diff --git a/game/server/colorcorrectionvolume.cpp b/game/server/colorcorrectionvolume.cpp index a56cd533..abc55d75 100644 --- a/game/server/colorcorrectionvolume.cpp +++ b/game/server/colorcorrectionvolume.cpp @@ -48,7 +48,11 @@ class CColorCorrectionVolume : public CBaseTrigger private: +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( bool, m_bEnabled ); +#else bool m_bEnabled; +#endif bool m_bStartDisabled; CNetworkVar( float, m_Weight ); @@ -61,7 +65,11 @@ class CColorCorrectionVolume : public CBaseTrigger float m_LastExitWeight; float m_LastExitTime; +#ifdef MAPBASE // From Alien Swarm SDK + CNetworkVar( float, m_FadeDuration ); +#else float m_FadeDuration; +#endif }; LINK_ENTITY_TO_CLASS(color_correction_volume, CColorCorrectionVolume); @@ -90,6 +98,11 @@ END_DATADESC() IMPLEMENT_SERVERCLASS_ST_NOBASE(CColorCorrectionVolume, DT_ColorCorrectionVolume) +#ifdef MAPBASE // From Alien Swarm SDK + SendPropBool( SENDINFO(m_bEnabled) ), + SendPropFloat( SENDINFO(m_MaxWeight) ), + SendPropFloat( SENDINFO(m_FadeDuration) ), +#endif SendPropFloat( SENDINFO(m_Weight) ), SendPropString( SENDINFO(m_lookupFilename) ), END_SEND_TABLE() diff --git a/game/server/doors.h b/game/server/doors.h index 9b485fe2..7658482c 100644 --- a/game/server/doors.h +++ b/game/server/doors.h @@ -150,8 +150,6 @@ class CBaseDoor : public CBaseToggle bool ShouldLoopMoveSound( void ) { return m_bLoopMoveSound; } bool m_bLoopMoveSound; // Move sound loops until stopped - virtual bool ShouldBlockNav() const OVERRIDE { return false; } - private: void ChainUse( void ); ///< Chains +use on through to m_ChainTarget void ChainTouch( CBaseEntity *pOther ); ///< Chains touch on through to m_ChainTarget diff --git a/game/server/effects.cpp b/game/server/effects.cpp index f9d457c6..cbe05190 100644 --- a/game/server/effects.cpp +++ b/game/server/effects.cpp @@ -29,11 +29,19 @@ #include "Sprite.h" #include "precipitation_shared.h" #include "shot_manipulator.h" +#ifdef MAPBASE +#include "point_template.h" +#include "TemplateEntities.h" +#include "mapentities_shared.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" #define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them. +#ifdef MAPBASE +#define SF_FUNNEL_DONT_REMOVE 2 +#endif #define SF_GIBSHOOTER_REPEATABLE (1<<0) // allows a gibshooter to be refired #define SF_SHOOTER_FLAMING (1<<1) // gib is on fire @@ -536,7 +544,11 @@ CBaseEntity *CGibShooter::SpawnGib( const Vector &vecShootDir, float flSpeed ) { // UNDONE: Assume a mass of 200 for now Vector force = vecShootDir * flSpeed * 200; +#ifdef MAPBASE + return CreateRagGib( STRING( GetModelName() ), GetAbsOrigin(), GetAbsAngles(), force, m_flGibLife, HasSpawnFlags(SF_SHOOTER_FLAMING) ); +#else return CreateRagGib( STRING( GetModelName() ), GetAbsOrigin(), GetAbsAngles(), force, m_flGibLife ); +#endif } case GIB_SIMULATE_PHYSICS: @@ -1246,6 +1258,10 @@ class CEnvFunnel : public CBaseEntity void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); int m_iSprite; // Don't save, precache +#ifdef MAPBASE + // This unfortunately doesn't work with the way the effect is set up + //string_t m_iszSprite; +#endif }; LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel ); @@ -1255,6 +1271,10 @@ LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel ); //--------------------------------------------------------- BEGIN_DATADESC( CEnvFunnel ) +#ifdef MAPBASE + //DEFINE_KEYFIELD( m_iszSprite, FIELD_STRING, "Sprite" ), + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputUse ), +#endif // DEFINE_FIELD( m_iSprite, FIELD_INTEGER ), END_DATADESC() @@ -1263,7 +1283,15 @@ END_DATADESC() void CEnvFunnel::Precache ( void ) { +#ifdef MAPBASE + //if (m_iszSprite == NULL_STRING) + // m_iszSprite = AllocPooledString("sprites/flare6.vmt"); + + //m_iSprite = PrecacheModel(STRING(m_iszSprite)); m_iSprite = PrecacheModel ( "sprites/flare6.vmt" ); +#else + m_iSprite = PrecacheModel ( "sprites/flare6.vmt" ); +#endif } void CEnvFunnel::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) @@ -1272,6 +1300,10 @@ void CEnvFunnel::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us te->LargeFunnel( filter, 0.0, &GetAbsOrigin(), m_iSprite, HasSpawnFlags( SF_FUNNEL_REVERSE ) ? 1 : 0 ); +#ifdef MAPBASE + if (HasSpawnFlags(SF_FUNNEL_DONT_REMOVE)) + return; +#endif SetThink( &CEnvFunnel::SUB_Remove ); SetNextThink( gpGlobals->curtime ); } @@ -1480,6 +1512,7 @@ class CPrecipitation : public CBaseEntity DECLARE_SERVERCLASS(); CPrecipitation(); + int UpdateTransmitState(); void Spawn( void ); CNetworkVar( PrecipitationType_t, m_nPrecipType ); @@ -1493,7 +1526,10 @@ END_DATADESC() // Just send the normal entity crap IMPLEMENT_SERVERCLASS_ST( CPrecipitation, DT_Precipitation) - SendPropInt( SENDINFO( m_nPrecipType ), Q_log2( NUM_PRECIPITATION_TYPES ) + 1, SPROP_UNSIGNED ) + SendPropInt( SENDINFO( m_nPrecipType ), Q_log2( NUM_PRECIPITATION_TYPES ) + 1, SPROP_UNSIGNED ), +#ifdef MAPBASE + SendPropInt( SENDINFO( m_spawnflags ), 2, SPROP_UNSIGNED ), +#endif END_SEND_TABLE() @@ -1502,17 +1538,35 @@ CPrecipitation::CPrecipitation() m_nPrecipType = PRECIPITATION_TYPE_RAIN; // default to rain. } +int CPrecipitation::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + void CPrecipitation::Spawn( void ) { + //SetTransmitState( FL_EDICT_ALWAYS ); + SetTransmitState( FL_EDICT_PVSCHECK ); + PrecacheMaterial( "effects/fleck_ash1" ); PrecacheMaterial( "effects/fleck_ash2" ); PrecacheMaterial( "effects/fleck_ash3" ); PrecacheMaterial( "effects/ember_swirling001" ); Precache(); - SetSolid( SOLID_NONE ); // Remove model & collisions SetMoveType( MOVETYPE_NONE ); SetModel( STRING( GetModelName() ) ); // Set size + if ( IsParticleRainType( m_nPrecipType ) ) + { + SetSolid( SOLID_VPHYSICS ); + AddSolidFlags( FSOLID_NOT_SOLID ); + AddSolidFlags( FSOLID_FORCE_WORLD_ALIGNED ); + VPhysicsInitStatic(); + } + else + { + SetSolid( SOLID_NONE ); // Remove model & collisions + } // Default to rain. if ( m_nPrecipType < 0 || m_nPrecipType > NUM_PRECIPITATION_TYPES ) @@ -1559,6 +1613,11 @@ BEGIN_DATADESC( CEnvWind ) DEFINE_KEYFIELD( m_EnvWindShared.m_iGustDirChange, FIELD_INTEGER, "gustdirchange" ), DEFINE_KEYFIELD( m_EnvWindShared.m_flGustDuration, FIELD_FLOAT, "gustduration" ), // DEFINE_KEYFIELD( m_EnvWindShared.m_iszGustSound, FIELD_STRING, "gustsound" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_EnvWindShared.m_windRadius, FIELD_FLOAT, "windradius" ), + DEFINE_KEYFIELD( m_EnvWindShared.m_windRadiusInner, FIELD_FLOAT, "windradiusinner" ), + DEFINE_KEYFIELD( m_EnvWindShared.m_flTreeSwayScale, FIELD_FLOAT, "treeswayscale" ), +#endif // Just here to quiet down classcheck // DEFINE_FIELD( m_EnvWindShared, CEnvWindShared ), @@ -1566,6 +1625,20 @@ BEGIN_DATADESC( CEnvWind ) DEFINE_FIELD( m_EnvWindShared.m_iWindDir, FIELD_INTEGER ), DEFINE_FIELD( m_EnvWindShared.m_flWindSpeed, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_INPUT( m_EnvWindShared.m_iMinWind, FIELD_INTEGER, "SetMinWind" ), + DEFINE_INPUT( m_EnvWindShared.m_iMaxWind, FIELD_INTEGER, "SetMaxWind" ), + DEFINE_INPUT( m_EnvWindShared.m_iMinGust, FIELD_INTEGER, "SetMinGust" ), + DEFINE_INPUT( m_EnvWindShared.m_iMaxGust, FIELD_INTEGER, "SetMaxGust" ), + DEFINE_INPUT( m_EnvWindShared.m_flMinGustDelay, FIELD_FLOAT, "SetMinGustDelay" ), + DEFINE_INPUT( m_EnvWindShared.m_flMaxGustDelay, FIELD_FLOAT, "SetMaxGustDelay" ), + DEFINE_INPUT( m_EnvWindShared.m_iGustDirChange, FIELD_INTEGER, "SetGustDirChange" ), + DEFINE_INPUT( m_EnvWindShared.m_flGustDuration, FIELD_FLOAT, "SetGustDuration" ), + DEFINE_INPUT( m_EnvWindShared.m_windRadius, FIELD_FLOAT, "SetWindRadius" ), + DEFINE_INPUT( m_EnvWindShared.m_windRadiusInner, FIELD_FLOAT, "SetWindRadiusInner" ), + DEFINE_INPUT( m_EnvWindShared.m_flTreeSwayScale, FIELD_FLOAT, "SetTreeSwayScale" ), +#endif + DEFINE_OUTPUT( m_EnvWindShared.m_OnGustStart, "OnGustStart" ), DEFINE_OUTPUT( m_EnvWindShared.m_OnGustEnd, "OnGustEnd" ), @@ -1594,6 +1667,12 @@ BEGIN_SEND_TABLE_NOBASE(CEnvWindShared, DT_EnvWindShared) SendPropFloat (SENDINFO(m_flGustDuration), 0, SPROP_NOSCALE), // Sound related // SendPropInt (SENDINFO(m_iszGustSound), 10, SPROP_UNSIGNED ), +#ifdef MAPBASE + SendPropFloat (SENDINFO(m_windRadius), 0, SPROP_NOSCALE), + SendPropFloat (SENDINFO(m_windRadiusInner), 0, SPROP_NOSCALE), + SendPropVector (SENDINFO(m_location), -1, SPROP_COORD), + SendPropFloat (SENDINFO(m_flTreeSwayScale), 0, SPROP_NOSCALE), +#endif END_SEND_TABLE() // This table encodes the CBaseEntity data. @@ -1615,7 +1694,13 @@ void CEnvWind::Spawn( void ) SetSolid( SOLID_NONE ); AddEffects( EF_NODRAW ); +#ifdef MAPBASE + m_EnvWindShared.m_iInitialWindDir = (int)(anglemod( m_EnvWindShared.m_iInitialWindDir )); + m_EnvWindShared.Init( entindex(), 0, gpGlobals->curtime, GetLocalAngles().y, 0 ); + m_EnvWindShared.m_location = GetAbsOrigin(); +#else m_EnvWindShared.Init( entindex(), 0, gpGlobals->frametime, GetLocalAngles().y, 0 ); +#endif SetThink( &CEnvWind::WindThink ); SetNextThink( gpGlobals->curtime ); @@ -2037,6 +2122,10 @@ class CEnvGunfire : public CPointEntity void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputFireBurst( inputdata_t &inputdata ); +#endif + int m_iMinBurstSize; int m_iMaxBurstSize; @@ -2062,6 +2151,10 @@ class CEnvGunfire : public CPointEntity EHANDLE m_hTarget; +#ifdef MAPBASE + COutputEvent m_OnFire; +#endif + DECLARE_DATADESC(); }; @@ -2090,6 +2183,11 @@ BEGIN_DATADESC( CEnvGunfire ) DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "FireBurst", InputFireBurst ), + + DEFINE_OUTPUT( m_OnFire, "OnFire" ), +#endif END_DATADESC() LINK_ENTITY_TO_CLASS( env_gunfire, CEnvGunfire ); @@ -2234,10 +2332,26 @@ void CEnvGunfire::ShootThink() m_iShotsRemaining--; +#ifdef MAPBASE + m_OnFire.FireOutput(m_hTarget, this); +#endif + if( m_iShotsRemaining == 0 ) { +#ifdef MAPBASE + if (m_bDisabled) + { + StopShooting(); + } + else + { + StartShooting(); + SetNextThink( gpGlobals->curtime + random->RandomFloat( m_flMinBurstDelay, m_flMaxBurstDelay ) ); + } +#else StartShooting(); SetNextThink( gpGlobals->curtime + random->RandomFloat( m_flMinBurstDelay, m_flMaxBurstDelay ) ); +#endif } } @@ -2257,6 +2371,18 @@ void CEnvGunfire::InputDisable( inputdata_t &inputdata ) SetThink( NULL ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvGunfire::InputFireBurst( inputdata_t &inputdata ) +{ + m_iShotsRemaining = inputdata.value.Int(); + + SetThink( &CEnvGunfire::ShootThink ); + SetNextThink( gpGlobals->curtime ); +} +#endif + //----------------------------------------------------------------------------- // Quadratic spline beam effect //----------------------------------------------------------------------------- @@ -2377,3 +2503,123 @@ void CEnvViewPunch::InputViewPunch( inputdata_t &inputdata ) { DoViewPunch(); } + +#ifdef MAPBASE +class CBreakableGibShooter : public CBaseEntity +{ + DECLARE_CLASS( CBreakableGibShooter, CBaseEntity ); + DECLARE_DATADESC(); +public: + + int GetRandomTemplateModelIndex( CPointTemplate *pTemplate ); + + void Precache( void ); + + void Shoot( void ); + + // ---------------- + // Inputs + // ---------------- + void InputShoot( inputdata_t &inputdata ); + +public: + + int m_iModelType; + enum + { + MODELTYPE_BREAKABLECHUNKS, + MODELTYPE_MODEL, + MODELTYPE_TEMPLATE, + }; + + int m_iCount; + float m_flDelay; + Vector m_vecGibSize; + float m_flGibSpeed; + int m_iRandomization; + float m_flLifetime; + int m_iGibFlags; +}; + +BEGIN_DATADESC( CBreakableGibShooter ) + + DEFINE_KEYFIELD( m_iModelType, FIELD_INTEGER, "modeltype" ), + DEFINE_INPUT( m_iCount, FIELD_INTEGER, "SetCount" ), + DEFINE_INPUT( m_flDelay, FIELD_FLOAT, "SetDelay" ), + DEFINE_INPUT( m_vecGibSize, FIELD_VECTOR, "SetGibSize" ), + DEFINE_INPUT( m_flGibSpeed, FIELD_FLOAT, "SetGibSpeed" ), + DEFINE_INPUT( m_iRandomization, FIELD_INTEGER, "SetRandomization" ), + DEFINE_INPUT( m_flLifetime, FIELD_FLOAT, "SetLifetime" ), + DEFINE_INPUT( m_iGibFlags, FIELD_INTEGER, "SetGibFlags" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Shoot", InputShoot ), + +END_DATADESC() + + +LINK_ENTITY_TO_CLASS( env_break_shooter, CBreakableGibShooter ); + + +int CBreakableGibShooter::GetRandomTemplateModelIndex( CPointTemplate *pTemplate ) +{ + int iIndex = RandomInt( 0, pTemplate->GetNumTemplates() ); + const char *szTemplate = STRING(Templates_FindByIndex(pTemplate->GetTemplateIndexForTemplate(iIndex))); + + // This might seem a little messy, but I think it's cheaper than creating the entity. + char szModel[MAPKEY_MAXLENGTH]; + bool modelExtracted = MapEntity_ExtractValue(szTemplate, "model", szModel); + + return modelinfo->GetModelIndex( modelExtracted ? szModel : NULL ); +} + +void CBreakableGibShooter::Precache( void ) +{ + if (m_iModelType == MODELTYPE_MODEL) + PrecacheModel( STRING(GetModelName()) ); +} + +void CBreakableGibShooter::Shoot( void ) +{ + int iModelIndex = 0; + if (m_iModelType == MODELTYPE_MODEL) + iModelIndex = modelinfo->GetModelIndex( STRING(GetModelName()) ); + + CPointTemplate *pTemplate = NULL; + if (m_iModelType == MODELTYPE_TEMPLATE) + { + pTemplate = dynamic_cast(gEntList.FindEntityByName(NULL, STRING(GetModelName()), this)); + if (!pTemplate) + { + Warning("%s cannot find point_template %s!\n", GetDebugName(), STRING(GetModelName())); + return; + } + } + + CPVSFilter filter( GetAbsOrigin() ); + for ( int i = 0; i < m_iCount; i++ ) + { + if (m_iModelType == MODELTYPE_BREAKABLECHUNKS) + iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( GetModelName() ) ) ); + else if (m_iModelType == MODELTYPE_TEMPLATE) + iModelIndex = GetRandomTemplateModelIndex( pTemplate ); + + // All objects except the first one in this run are marked as slaves... + int slaveFlag = 0; + if ( i != 0 ) + { + slaveFlag = BREAK_SLAVE; + } + + Vector vecShootDir; + AngleVectors( GetAbsAngles(), &vecShootDir ); + VectorNormalize( vecShootDir ); + + te->BreakModel( filter, m_flDelay, GetAbsOrigin(), GetAbsAngles(), m_vecGibSize, vecShootDir * m_flGibSpeed, iModelIndex, m_iRandomization, 1, m_flLifetime, m_iGibFlags | slaveFlag ); + } +} + +void CBreakableGibShooter::InputShoot( inputdata_t &inputdata ) +{ + Shoot(); +} +#endif diff --git a/game/server/enginecallback.h b/game/server/enginecallback.h index cce07866..45993be9 100644 --- a/game/server/enginecallback.h +++ b/game/server/enginecallback.h @@ -26,6 +26,7 @@ class IDataCache; class IMDLCache; class IServerEngineTools; class IXboxSystem; +class IScriptManager; class CSteamAPIContext; class CSteamGameServerAPIContext; @@ -43,6 +44,7 @@ extern IDataCache *datacache; extern IMDLCache *mdlcache; extern IServerEngineTools *serverenginetools; extern IXboxSystem *xboxsystem; // 360 only +extern IScriptManager *scriptmanager; extern CSteamAPIContext *steamapicontext; // available on game clients extern CSteamGameServerAPIContext *steamgameserverapicontext; //available on game servers diff --git a/game/server/entity_tools_server.cpp b/game/server/entity_tools_server.cpp index b08d0754..8b76e888 100644 --- a/game/server/entity_tools_server.cpp +++ b/game/server/entity_tools_server.cpp @@ -14,6 +14,13 @@ #include "sceneentity.h" #include "particles/particles.h" +#if _MSC_VER >= 1900 +#include "icommandline.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + //----------------------------------------------------------------------------- // Interface from engine to tools for manipulating entities @@ -53,27 +60,7 @@ class CServerTools : public IServerTools virtual void ApplyMultiDamage( void ); virtual void AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity ); virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore ); - virtual ITempEntsSystem *GetTempEntsSystem( void ); - virtual CBaseTempEntity *GetTempEntList( void ); - virtual CGlobalEntityList *GetEntityList( void ); - virtual bool IsEntityPtr( void *pTest ); - virtual CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ); - virtual CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ); - virtual CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ); - virtual CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ); - virtual CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ); - virtual CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - virtual CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - virtual CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ); - virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ); - virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ); - virtual CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - virtual CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - virtual CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - virtual CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ); - virtual CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ); - virtual CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); }; @@ -84,11 +71,10 @@ static CServerTools g_ServerTools; // VSERVERTOOLS_INTERFACE_VERSION_1 is compatible with the latest since we're only adding things to the end, so expose that as well. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools001, VSERVERTOOLS_INTERFACE_VERSION_1, g_ServerTools ); -EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools002, VSERVERTOOLS_INTERFACE_VERSION_2, g_ServerTools ); EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION, g_ServerTools ); // When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way -COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 3 ); +COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 2 ); IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity ) @@ -368,101 +354,6 @@ ITempEntsSystem *CServerTools::GetTempEntsSystem( void ) return (ITempEntsSystem *)te; } -CBaseTempEntity *CServerTools::GetTempEntList( void ) -{ - return CBaseTempEntity::GetList(); -} - -CGlobalEntityList *CServerTools::GetEntityList( void ) -{ - return &gEntList; -} - -bool CServerTools::IsEntityPtr( void *pTest ) -{ - return gEntList.IsEntityPtr( pTest ); -} - -CBaseEntity *CServerTools::FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) -{ - return gEntList.FindEntityByClassname( pStartEntity, szName ); -} - -CBaseEntity *CServerTools::FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller, IEntityFindFilter *pFilter ) -{ - return gEntList.FindEntityByName( pStartEntity, szName, pSearchingEntity, pActivator, pCaller, pFilter ); -} - -CBaseEntity *CServerTools::FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) -{ - return gEntList.FindEntityInSphere( pStartEntity, vecCenter, flRadius ); -} - -CBaseEntity *CServerTools::FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ) -{ - return gEntList.FindEntityByTarget( pStartEntity, szName ); -} - -CBaseEntity *CServerTools::FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ) -{ - return gEntList.FindEntityByModel( pStartEntity, szModelName ); -} - -CBaseEntity *CServerTools::FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityByNameNearest( szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); -} - -CBaseEntity *CServerTools::FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityByNameWithin( pStartEntity, szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); -} - -CBaseEntity *CServerTools::FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ) -{ - return gEntList.FindEntityByClassnameNearest( szName, vecSrc, flRadius ); -} - -CBaseEntity *CServerTools::FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ) -{ - return gEntList.FindEntityByClassnameWithin( pStartEntity, szName, vecSrc, flRadius ); -} - -CBaseEntity *CServerTools::FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ) -{ - return gEntList.FindEntityByClassnameWithin( pStartEntity, szName, vecMins, vecMaxs ); -} - -CBaseEntity *CServerTools::FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityGeneric( pStartEntity, szName, pSearchingEntity, pActivator, pCaller ); -} - -CBaseEntity *CServerTools::FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityGenericWithin( pStartEntity, szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); -} - -CBaseEntity *CServerTools::FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityGenericNearest( szName, vecSrc, flRadius, pSearchingEntity, pActivator, pCaller ); -} - -CBaseEntity *CServerTools::FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ) -{ - return gEntList.FindEntityNearestFacing( origin, facing, threshold ); -} - -CBaseEntity *CServerTools::FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ) -{ - return gEntList.FindEntityClassNearestFacing( origin, facing, threshold, classname ); -} - -CBaseEntity *CServerTools::FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - return gEntList.FindEntityProcedural( szName, pSearchingEntity, pActivator, pCaller ); -} - // Interface from engine to tools for manipulating entities class CServerChoreoTools : public IServerChoreoTools diff --git a/game/server/entitylist.cpp b/game/server/entitylist.cpp index d1afa218..55d5614b 100644 --- a/game/server/entitylist.cpp +++ b/game/server/entitylist.cpp @@ -20,6 +20,10 @@ #ifdef HL2_DLL #include "npc_playercompanion.h" +#ifdef MAPBASE +#include "hl2_player.h" +#include "mapbase_matchers_base.h" +#endif #endif // HL2_DLL // memdbgon must be the last include file in a .cpp file!!! @@ -75,6 +79,15 @@ class CAimTargetManager : public IEntityListener // IEntityListener virtual void OnEntityCreated( CBaseEntity *pEntity ) {} + virtual void OnEntitySpawned( CBaseEntity *pEntity ) + { + // From Alien Swarm SDK + if ( ShouldAddEntity( pEntity ) ) + { + RemoveEntity( pEntity ); + AddEntity( pEntity ); + } + } virtual void OnEntityDeleted( CBaseEntity *pEntity ) { if ( !(pEntity->GetFlags() & FL_AIMTARGET) ) @@ -102,6 +115,10 @@ class CAimTargetManager : public IEntityListener memcpy( pList, m_targetList.Base(), sizeof(CBaseEntity *) * count ); return count; } + CBaseEntity *ListElement( int iIndex ) // From Alien Swarm SDK + { + return m_targetList[iIndex]; + } private: CUtlVector m_targetList; @@ -117,6 +134,10 @@ int AimTarget_ListCopy( CBaseEntity *pList[], int listMax ) { return g_AimManager.ListCopy( pList, listMax ); } +CBaseEntity *AimTarget_ListElement( int iIndex ) +{ + return g_AimManager.ListElement( iIndex ); +} void AimTarget_ForceRepopulateList() { g_AimManager.ForceRepopulateList(); @@ -290,6 +311,10 @@ CBaseEntityClassList::~CBaseEntityClassList() { } +#ifdef MAPBASE_VSCRIPT +static CUtlVector g_CustomProcedurals; +#endif + CGlobalEntityList::CGlobalEntityList() { m_iHighestEnt = m_iNumEnts = m_iNumEdicts = 0; @@ -377,6 +402,10 @@ void CGlobalEntityList::Clear( void ) // free the memory g_DeleteList.Purge(); +#ifdef MAPBASE_VSCRIPT + g_CustomProcedurals.Purge(); +#endif + CBaseEntity::m_nDebugPlayer = -1; CBaseEntity::m_bInDebugSelect = false; m_iHighestEnt = 0; @@ -479,7 +508,11 @@ bool CGlobalEntityList::IsEntityPtr( void *pTest ) // Input : pStartEntity - Last entity found, NULL to start a new iteration. // szName - Classname to search for. //----------------------------------------------------------------------------- +#ifdef MAPBASE +CBaseEntity *CGlobalEntityList::FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName, IEntityFindFilter *pFilter ) +#else CBaseEntity *CGlobalEntityList::FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) +#endif { const CEntInfo *pInfo = pStartEntity ? GetEntInfoPtr( pStartEntity->GetRefEHandle() )->m_pNext : FirstEntInfo(); @@ -492,8 +525,55 @@ CBaseEntity *CGlobalEntityList::FindEntityByClassname( CBaseEntity *pStartEntity continue; } +#ifdef MAPBASE + if ( pEntity->ClassMatches(szName) ) + { + if ( pFilter && !pFilter->ShouldFindEntity(pEntity) ) + continue; + + return pEntity; + } +#else if ( pEntity->ClassMatches(szName) ) return pEntity; +#endif + } + + return NULL; +} + +// From Alien Swarm SDK +CBaseEntity *CGlobalEntityList::FindEntityByClassnameFast( CBaseEntity *pStartEntity, string_t iszClassname ) +{ + /* + if ( pStartEntity ) + { + return pStartEntity->m_pNextByClass; + } + + EntsByStringList_t key = { iszClassname }; + UtlHashHandle_t hEntry = g_EntsByClassname.Find( key ); + if ( hEntry != g_EntsByClassname.InvalidHandle() ) + { + return g_EntsByClassname[hEntry].pHead; + } + */ + + const CEntInfo *pInfo = pStartEntity ? GetEntInfoPtr( pStartEntity->GetRefEHandle() )->m_pNext : FirstEntInfo(); + + for ( ;pInfo; pInfo = pInfo->m_pNext ) + { + CBaseEntity *pEntity = (CBaseEntity *)pInfo->m_pEntity; + if ( !pEntity ) + { + DevWarning( "NULL entity in global entity list!\n" ); + continue; + } + + if ( pEntity->m_iClassname == iszClassname) + { + return pEntity; + } } return NULL; @@ -551,12 +631,60 @@ CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseE } else if ( FStrEq( pName, "picker" ) ) { +#ifdef MAPBASE_MP + // TODO: Player could be activator instead + CBasePlayer *pPlayer = ToBasePlayer(pSearchingEntity); + return FindPickerEntity( pPlayer ? pPlayer : UTIL_PlayerByIndex(1) ); +#else return FindPickerEntity( UTIL_PlayerByIndex(1) ); +#endif } else if ( FStrEq( pName, "self" ) ) { return pSearchingEntity; } +#ifdef MAPBASE + else if ( FStrEq( pName, "parent" ) ) + { + return pSearchingEntity ? pSearchingEntity->GetParent() : NULL; + } + else if ( FStrEq( pName, "owner" ) ) + { + return pSearchingEntity ? pSearchingEntity->GetOwnerEntity() : NULL; + } + else if ( FStrEq( pName, "plrsquadrep" ) ) + { +#ifdef HL2_DLL + CHL2_Player *pPlayer = static_cast(UTIL_PlayerByIndex(1)); + if (pPlayer) + { + return pPlayer->GetSquadCommandRepresentative(); + } +#endif + } + else if (strchr(pName, ':')) + { + char name[128]; + Q_strncpy(name, pName, strchr(pName, ':')-pName+1); + + CBaseEntity *pEntity = FindEntityProcedural(UTIL_VarArgs("!%s", name), pSearchingEntity, pActivator, pCaller); + if (pEntity && pEntity->IsNPC()) + { + const char *target = (Q_strstr(pName, ":") + 1); + if (target[0] != '!') + target = UTIL_VarArgs("!%s", target); + + return pEntity->MyNPCPointer()->FindNamedEntity(target); + } + } + else if (pSearchingEntity && pSearchingEntity->IsCombatCharacter()) + { + // Perhaps the entity itself has the answer? + // This opens up new possibilities. The weird filter is there so it doesn't go through this twice. + CNullEntityFilter pFilter; + return pSearchingEntity->MyCombatCharacterPointer()->FindNamedEntity(szName, &pFilter); + } +#endif else { Warning( "Invalid entity search name %s\n", szName ); @@ -568,6 +696,93 @@ CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseE } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: Finds an entity given a custom procedural name. +// Input : szName - The procedural name to search for, should start with '!'. +// pSearchingEntity - +// pActivator - The activator entity if this was called from an input +// or Use handler. +//----------------------------------------------------------------------------- +CBaseEntity *CGlobalEntityList::FindEntityCustomProcedural( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + const char *pName = szName; + + // + // Check for the name escape character. + // + if ( szName[0] == '!' ) + pName = szName + 1; + + // + // Look through the custom procedural list. + // + for (int i = 0; i < g_CustomProcedurals.Count(); i++) + { + if (Matcher_NamesMatch( g_CustomProcedurals[i].szName, pName )) + { + if (pStartEntity && g_CustomProcedurals[i].bCanReturnMultiple == false) + return NULL; + + // name, startEntity, searchingEntity, activator, caller + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { + ScriptVariant_t( pName ), + ScriptVariant_t( ToHScript( pStartEntity ) ), + ScriptVariant_t( ToHScript( pSearchingEntity ) ), + ScriptVariant_t( ToHScript( pActivator ) ), + ScriptVariant_t( ToHScript( pCaller ) ), + }; + + g_pScriptVM->ExecuteFunction( g_CustomProcedurals[i].hFunc, args, 5, &functionReturn, NULL, true ); + + return ToEnt( functionReturn.m_hScript ); + } + } + + return NULL; +} + +void CGlobalEntityList::AddCustomProcedural( const char *pszName, HSCRIPT hFunc, bool bCanReturnMultiple ) +{ + // + // Check for any existing custom procedurals to replace. + // + for (int i = 0; i < g_CustomProcedurals.Count(); i++) + { + if (FStrEq( pszName, g_CustomProcedurals[i].szName )) + { + g_CustomProcedurals.FastRemove( i ); + break; + } + } + + // + // Add a new custom procedural. + // + int i = g_CustomProcedurals.AddToTail(); + g_CustomProcedurals[i].szName = pszName; + g_CustomProcedurals[i].hFunc = hFunc; + g_CustomProcedurals[i].bCanReturnMultiple = bCanReturnMultiple; +} + +void CGlobalEntityList::RemoveCustomProcedural( const char *pszName ) +{ + // + // Remove the specified custom procedural. + // + for (int i = 0; i < g_CustomProcedurals.Count(); i++) + { + if (FStrEq( pszName, g_CustomProcedurals[i].szName )) + { + g_CustomProcedurals.FastRemove( i ); + break; + } + } +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Iterates the entities with a given name. // Input : pStartEntity - Last entity found, NULL to start a new iteration. @@ -582,6 +797,16 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con if ( szName[0] == '!' ) { +#ifdef MAPBASE + if (g_CustomProcedurals.Count() > 0) + { + // Search for a custom procedural + CBaseEntity *ent = FindEntityCustomProcedural( pStartEntity, szName, pSearchingEntity, pActivator, pCaller ); + if (ent != NULL) + return ent; + } +#endif + // // Avoid an infinite loop, only find one match per procedural search! // @@ -602,7 +827,7 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con continue; } - if ( !ent->m_iName ) + if ( !ent->m_iName.Get() ) continue; if ( ent->NameMatches( szName ) ) @@ -617,6 +842,35 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con return NULL; } +// From Alien Swarm SDK +CBaseEntity *CGlobalEntityList::FindEntityByNameFast( CBaseEntity *pStartEntity, string_t iszName ) +{ + if ( iszName == NULL_STRING || STRING(iszName)[0] == 0 ) + return NULL; + + const CEntInfo *pInfo = pStartEntity ? GetEntInfoPtr( pStartEntity->GetRefEHandle() )->m_pNext : FirstEntInfo(); + + for ( ;pInfo; pInfo = pInfo->m_pNext ) + { + CBaseEntity *ent = (CBaseEntity *)pInfo->m_pEntity; + if ( !ent ) + { + DevWarning( "NULL entity in global entity list!\n" ); + continue; + } + + if ( !ent->m_iName.Get() ) + continue; + + if ( ent->m_iName.Get() == iszName ) + { + return ent; + } + } + + return NULL; +} + //----------------------------------------------------------------------------- // Purpose: // Input : pStartEntity - @@ -834,6 +1088,80 @@ CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearest( const char *szName } +// From Alien Swarm SDK +CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearestFast( string_t iszName, const Vector &vecSrc, float flRadius ) +{ + CBaseEntity *pEntity = NULL; + + // + // Check for matching class names within the search radius. + // + float flMaxDist2 = flRadius * flRadius; + if (flMaxDist2 == 0) + { + flMaxDist2 = MAX_TRACE_LENGTH * MAX_TRACE_LENGTH; + } + + CBaseEntity *pSearch = NULL; + while ((pSearch = gEntList.FindEntityByClassnameFast( pSearch, iszName )) != NULL) + { + if ( !pSearch->edict() ) + continue; + + float flDist2 = (pSearch->GetAbsOrigin() - vecSrc).LengthSqr(); + + if (flMaxDist2 > flDist2) + { + pEntity = pSearch; + flMaxDist2 = flDist2; + } + } + + return pEntity; +} + + +//----------------------------------------------------------------------------- +// Purpose: Finds the nearest entity by class name withing given search radius. +// From Alien Swarm SDK +// Input : szName - Entity name to search for. Treated as a target name first, +// then as an entity class name, ie "info_target". +// vecSrc - Center of search radius. +// flRadius - Search radius for classname search, 0 to search everywhere. +// Output : Returns a pointer to the found entity, NULL if none. +//----------------------------------------------------------------------------- +CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearest2D( const char *szName, const Vector &vecSrc, float flRadius ) +{ + CBaseEntity *pEntity = NULL; + + // + // Check for matching class names within the search radius. + // + float flMaxDist2 = flRadius * flRadius; + if (flMaxDist2 == 0) + { + flMaxDist2 = MAX_TRACE_LENGTH * MAX_TRACE_LENGTH; + } + + CBaseEntity *pSearch = NULL; + while ((pSearch = gEntList.FindEntityByClassname( pSearch, szName )) != NULL) + { + if ( !pSearch->edict() ) + continue; + + float flDist2 = (pSearch->GetAbsOrigin().AsVector2D() - vecSrc.AsVector2D()).LengthSqr(); + + if (flMaxDist2 > flDist2) + { + pEntity = pSearch; + flMaxDist2 = flDist2; + } + } + + return pEntity; +} + + //----------------------------------------------------------------------------- // Purpose: Finds the first entity within radius distance by class name. @@ -917,6 +1245,20 @@ CBaseEntity *CGlobalEntityList::FindEntityByClassnameWithin( CBaseEntity *pStart // or Use handler, NULL otherwise. // Output : Returns a pointer to the found entity, NULL if none. //----------------------------------------------------------------------------- +#ifdef MAPBASE +CBaseEntity *CGlobalEntityList::FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller, IEntityFindFilter *pFilter ) +{ + CBaseEntity *pEntity = NULL; + + pEntity = gEntList.FindEntityByName( pStartEntity, szName, pSearchingEntity, pActivator, pCaller, pFilter ); + if (!pEntity) + { + pEntity = gEntList.FindEntityByClassname( pStartEntity, szName, pFilter ); + } + + return pEntity; +} +#else CBaseEntity *CGlobalEntityList::FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) { CBaseEntity *pEntity = NULL; @@ -929,6 +1271,7 @@ CBaseEntity *CGlobalEntityList::FindEntityGeneric( CBaseEntity *pStartEntity, co return pEntity; } +#endif //----------------------------------------------------------------------------- @@ -1105,7 +1448,7 @@ void CGlobalEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) void CGlobalEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) { -#ifdef DBGFLAG_ASSERT +#ifdef DEBUG if ( !g_fInCleanupDelete ) { int i; diff --git a/game/server/entitylist.h b/game/server/entitylist.h index 540e2d50..e2339ada 100644 --- a/game/server/entitylist.h +++ b/game/server/entitylist.h @@ -66,6 +66,36 @@ abstract_class IEntityFindFilter virtual CBaseEntity *GetFilterResult( void ) = 0; }; +#ifdef MAPBASE +// Returns false every time. Created for some sick hack involving FindEntityProcedural looking at FindNamedEntity. +class CNullEntityFilter : public IEntityFindFilter +{ +public: + virtual bool ShouldFindEntity( CBaseEntity *pEntity ) { return false; } + virtual CBaseEntity *GetFilterResult( void ) { return NULL; } +}; + +//----------------------------------------------------------------------------- +// Custom procedural names via VScript. This allows users to reference new '!' targets +// or override existing ones. It is capable of returning multiple entities when needed. +// +// This is useful if you want I/O and beyond to reference an entity/a number of entities +// which may possess differing or ambiguous targetnames, or if you want to reference an +// entity specific to the context of the operation (e.g. getting the searching entity's +// current weapon). +// +// For example, you could add a new procedural called "!first_child" which uses VScript to +// return the searching entity's first child entity. You could also add a procedural called +// "!children" which returns all of the searching entity's child entities. +//----------------------------------------------------------------------------- +struct CustomProcedural_t +{ + HSCRIPT hFunc; + const char *szName; + bool bCanReturnMultiple; +}; +#endif + //----------------------------------------------------------------------------- // Purpose: a global list of all the entities in the game. All iteration through // entities is done through this object. @@ -133,7 +163,11 @@ class CGlobalEntityList : public CBaseEntityList // search functions bool IsEntityPtr( void *pTest ); +#ifdef MAPBASE + CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName, IEntityFindFilter *pFilter = NULL ); +#else CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ); +#endif CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ); CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, string_t iszName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ) { @@ -146,18 +180,36 @@ class CGlobalEntityList : public CBaseEntityList CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ); + CBaseEntity *FindEntityByClassnameNearest2D( const char *szName, const Vector &vecSrc, float flRadius ); // From Alien Swarm SDK CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecSrc, float flRadius ); CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecMins, const Vector &vecMaxs ); +#ifdef MAPBASE + CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ); +#else CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); +#endif CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold); CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname); + CBaseEntity *FindEntityByNetname( CBaseEntity *pStartEntity, const char *szModelName ); CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); - +#ifdef MAPBASE_VSCRIPT + CBaseEntity *FindEntityCustomProcedural( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + + void AddCustomProcedural( const char *pszName, HSCRIPT hFunc, bool bCanReturnMultiple ); + void RemoveCustomProcedural( const char *pszName ); +#endif + + // Fast versions that require a (real) string_t, and won't do wildcarding + // From Alien Swarm SDK + CBaseEntity *FindEntityByClassnameFast( CBaseEntity *pStartEntity, string_t iszClassname ); + CBaseEntity *FindEntityByClassnameNearestFast( string_t iszClassname, const Vector &vecSrc, float flRadius ); + CBaseEntity *FindEntityByNameFast( CBaseEntity *pStartEntity, string_t iszName ); + CGlobalEntityList(); // CBaseEntityList overrides. @@ -354,6 +406,7 @@ extern INotify *g_pNotify; void EntityTouch_Add( CBaseEntity *pEntity ); int AimTarget_ListCount(); int AimTarget_ListCopy( CBaseEntity *pList[], int listMax ); +CBaseEntity *AimTarget_ListElement( int iIndex ); void AimTarget_ForceRepopulateList(); void SimThink_EntityChanged( CBaseEntity *pEntity ); diff --git a/game/server/entityoutput.h b/game/server/entityoutput.h index 6aeb7380..424ae761 100644 --- a/game/server/entityoutput.h +++ b/game/server/entityoutput.h @@ -63,6 +63,7 @@ class CBaseEntityOutput void ParseEventAction( const char *EventData ); void AddEventAction( CEventAction *pEventAction ); + void RemoveEventAction( CEventAction *pEventAction ); int Save( ISave &save ); int Restore( IRestore &restore, int elementCount ); @@ -78,6 +79,12 @@ class CBaseEntityOutput /// Delete every single action in the action list. void DeleteAllElements( void ) ; +#ifdef MAPBASE + // Needed for ReplaceOutput, hopefully not bad + CEventAction *GetActionList() { return m_ActionList; } + void SetActionList(CEventAction *newlist) { m_ActionList = newlist; } +#endif + protected: variant_t m_Value; CEventAction *m_ActionList; @@ -146,6 +153,29 @@ class CEntityOutputTemplate : public CBaseEntityOutp { m_Value.Vector3D(vec); } + +#ifdef MAPBASE + // Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification + void Init( const QAngle &value ) + { + // reinterpret_cast(value) + m_Value.SetAngle3D( value ); + } + + // Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification + void Set( const QAngle &value, CBaseEntity *pActivator, CBaseEntity *pCaller ) + { + // reinterpret_cast(value) + m_Value.SetAngle3D( value ); + FireOutput( m_Value, pActivator, pCaller ); + } + + // Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification + void Get( QAngle &ang ) + { + m_Value.Angle3D(ang); + } +#endif }; diff --git a/game/server/env_dof_controller.cpp b/game/server/env_dof_controller.cpp new file mode 100644 index 00000000..d061fc73 --- /dev/null +++ b/game/server/env_dof_controller.cpp @@ -0,0 +1,186 @@ +//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: Depth of field controller entity +// +//============================================================================= + +#include "cbase.h" +#include "baseentity.h" +#include "entityoutput.h" +#include "env_dof_controller.h" +#include "ai_utils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +LINK_ENTITY_TO_CLASS( env_dof_controller, CEnvDOFController ); + +BEGIN_DATADESC( CEnvDOFController ) + + DEFINE_KEYFIELD( m_bDOFEnabled, FIELD_BOOLEAN, "enabled" ), + DEFINE_KEYFIELD( m_flNearBlurDepth, FIELD_FLOAT, "near_blur" ), + DEFINE_KEYFIELD( m_flNearFocusDepth, FIELD_FLOAT, "near_focus" ), + DEFINE_KEYFIELD( m_flFarFocusDepth, FIELD_FLOAT, "far_focus" ), + DEFINE_KEYFIELD( m_flFarBlurDepth, FIELD_FLOAT, "far_blur" ), + DEFINE_KEYFIELD( m_flNearBlurRadius, FIELD_FLOAT, "near_radius" ), + DEFINE_KEYFIELD( m_flFarBlurRadius, FIELD_FLOAT, "far_radius" ), + DEFINE_KEYFIELD( m_strFocusTargetName, FIELD_STRING, "focus_target" ), + DEFINE_KEYFIELD( m_flFocusTargetRange, FIELD_FLOAT, "focus_range" ), + + DEFINE_FIELD( m_hFocusTarget, FIELD_EHANDLE ), + + DEFINE_THINKFUNC( UpdateParamBlend ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearBlurDepth", InputSetNearBlurDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearFocusDepth", InputSetNearFocusDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarFocusDepth", InputSetFarFocusDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarBlurDepth", InputSetFarBlurDepth ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearBlurRadius", InputSetNearBlurRadius ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarBlurRadius", InputSetFarBlurRadius ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFocusTarget", InputSetFocusTarget ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFocusTargetRange", InputSetFocusTargetRange ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CEnvDOFController, DT_EnvDOFController ) + SendPropInt( SENDINFO(m_bDOFEnabled), 1, SPROP_UNSIGNED ), + SendPropFloat( SENDINFO(m_flNearBlurDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flNearFocusDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarFocusDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarBlurDepth), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flNearBlurRadius), 0, SPROP_NOSCALE), + SendPropFloat( SENDINFO(m_flFarBlurRadius), 0, SPROP_NOSCALE), +END_SEND_TABLE() + +void CEnvDOFController::Spawn() +{ + SetSolid( SOLID_NONE ); + SetMoveType( MOVETYPE_NONE ); + +#ifdef MAPBASE + // Find our target entity and hold on to it + m_hFocusTarget = gEntList.FindEntityByName( NULL, m_strFocusTargetName, this ); + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#endif +} + +void CEnvDOFController::Activate() +{ + BaseClass::Activate(); + +#ifndef MAPBASE // Mapbase moves this to Spawn() to avoid issues with save/restore and entities set via the SetFocusTarget input + // Find our target entity and hold on to it + m_hFocusTarget = gEntList.FindEntityByName( NULL, m_strFocusTargetName ); + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#endif +} + +int CEnvDOFController::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +void CEnvDOFController::InputSetNearBlurDepth( inputdata_t &inputdata ) +{ + m_flNearBlurDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetNearFocusDepth( inputdata_t &inputdata ) +{ + m_flNearFocusDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetFarFocusDepth( inputdata_t &inputdata ) +{ + m_flFarFocusDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetFarBlurDepth( inputdata_t &inputdata ) +{ + m_flFarBlurDepth = inputdata.value.Float(); +} + +void CEnvDOFController::InputSetNearBlurRadius( inputdata_t &inputdata ) +{ + m_flNearBlurRadius = inputdata.value.Float(); + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +void CEnvDOFController::InputSetFarBlurRadius( inputdata_t &inputdata ) +{ + m_flFarBlurRadius = inputdata.value.Float(); + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +void CEnvDOFController::SetControllerState( DOFControlSettings_t setting ) +{ + m_flNearBlurDepth = setting.flNearBlurDepth; + m_flNearBlurRadius = setting.flNearBlurRadius; + m_flNearFocusDepth = setting.flNearFocusDistance; + + m_flFarBlurDepth = setting.flFarBlurDepth; + m_flFarBlurRadius = setting.flFarBlurRadius; + m_flFarFocusDepth = setting.flFarFocusDistance; + + m_bDOFEnabled = ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ); +} + +#define BLUR_DEPTH 500.0f + +//----------------------------------------------------------------------------- +// Purpose: Blend the parameters to the specified value +//----------------------------------------------------------------------------- +void CEnvDOFController::UpdateParamBlend() +{ + // Update our focal target if we have one + if ( m_hFocusTarget ) + { + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + float flDistToFocus = ( m_hFocusTarget->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).Length(); + m_flFarFocusDepth.GetForModify() = flDistToFocus + m_flFocusTargetRange; + m_flFarBlurDepth.GetForModify() = m_flFarFocusDepth + BLUR_DEPTH; + + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Set the "focus" target entity +//----------------------------------------------------------------------------- +void CEnvDOFController::InputSetFocusTarget( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + m_hFocusTarget = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); +#else + m_hFocusTarget = gEntList.FindEntityByName( NULL, inputdata.value.String() ); +#endif + + // Update if we have a focal target + if ( m_hFocusTarget ) + { + SetThink( &CEnvDOFController::UpdateParamBlend ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Set the range behind the focus entity that we'll blur (in units) +//----------------------------------------------------------------------------- +void CEnvDOFController::InputSetFocusTargetRange( inputdata_t &inputdata ) +{ + m_flFocusTargetRange = inputdata.value.Float(); +} diff --git a/game/server/env_dof_controller.h b/game/server/env_dof_controller.h new file mode 100644 index 00000000..e323ef52 --- /dev/null +++ b/game/server/env_dof_controller.h @@ -0,0 +1,56 @@ +#pragma once + +struct DOFControlSettings_t +{ + // Near plane + float flNearBlurDepth; + float flNearBlurRadius; + float flNearFocusDistance; + // Far plane + float flFarBlurDepth; + float flFarBlurRadius; + float flFarFocusDistance; +}; + +//----------------------------------------------------------------------------- +// Purpose: Entity that controls depth of field postprocessing +//----------------------------------------------------------------------------- +class CEnvDOFController : public CPointEntity +{ + DECLARE_CLASS( CEnvDOFController, CPointEntity ); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + virtual void Spawn(); + virtual void Activate(); + virtual int UpdateTransmitState(); + void SetControllerState( DOFControlSettings_t setting ); + + void UpdateParamBlend(); + + // Inputs + void InputSetNearBlurDepth( inputdata_t &inputdata ); + void InputSetNearFocusDepth( inputdata_t &inputdata ); + void InputSetFarFocusDepth( inputdata_t &inputdata ); + void InputSetFarBlurDepth( inputdata_t &inputdata ); + void InputSetNearBlurRadius( inputdata_t &inputdata ); + void InputSetFarBlurRadius( inputdata_t &inputdata ); + + void InputSetFocusTarget( inputdata_t &inputdata ); + void InputSetFocusTargetRange( inputdata_t &inputdata ); + +private: + float m_flFocusTargetRange; + + string_t m_strFocusTargetName; // Name of the entity to focus on + EHANDLE m_hFocusTarget; + + CNetworkVar( bool, m_bDOFEnabled ); + CNetworkVar( float, m_flNearBlurDepth ); + CNetworkVar( float, m_flNearFocusDepth ); + CNetworkVar( float, m_flFarFocusDepth ); + CNetworkVar( float, m_flFarBlurDepth ); + CNetworkVar( float, m_flNearBlurRadius ); + CNetworkVar( float, m_flFarBlurRadius ); +}; diff --git a/game/server/env_entity_maker.cpp b/game/server/env_entity_maker.cpp index d8ad528e..19d8ddf6 100644 --- a/game/server/env_entity_maker.cpp +++ b/game/server/env_entity_maker.cpp @@ -30,6 +30,7 @@ class CEnvEntityMaker : public CPointEntity DECLARE_CLASS( CEnvEntityMaker, CPointEntity ); public: DECLARE_DATADESC(); + DECLARE_ENT_SCRIPTDESC(); virtual void Spawn( void ); virtual void Activate( void ); @@ -38,7 +39,15 @@ class CEnvEntityMaker : public CPointEntity void CheckSpawnThink( void ); void InputForceSpawn( inputdata_t &inputdata ); void InputForceSpawnAtEntityOrigin( inputdata_t &inputdata ); - +#ifdef MAPBASE + void InputForceSpawnAtEntityCenter( inputdata_t &inputdata ); + void InputForceSpawnAtPosition( inputdata_t &inputdata ); +#endif + + void SpawnEntityFromScript(); + void SpawnEntityAtEntityOriginFromScript(HSCRIPT hEntity); + void SpawnEntityAtNamedEntityOriginFromScript(const char* pszName); + void SpawnEntityAtLocationFromScript(const Vector& vecAlternateOrigin, const Vector& vecAlternateAngles); private: CPointTemplate *FindTemplate(); @@ -62,6 +71,9 @@ class CEnvEntityMaker : public CPointEntity COutputEvent m_pOutputOnSpawned; COutputEvent m_pOutputOnFailedSpawn; +#ifdef MAPBASE + COutputEHANDLE m_pOutputOutEntity; +#endif }; BEGIN_DATADESC( CEnvEntityMaker ) @@ -79,15 +91,29 @@ BEGIN_DATADESC( CEnvEntityMaker ) // Outputs DEFINE_OUTPUT( m_pOutputOnSpawned, "OnEntitySpawned" ), DEFINE_OUTPUT( m_pOutputOnFailedSpawn, "OnEntityFailedSpawn" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_pOutputOutEntity, "OutSpawnedEntity" ), +#endif // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "ForceSpawn", InputForceSpawn ), DEFINE_INPUTFUNC( FIELD_STRING, "ForceSpawnAtEntityOrigin", InputForceSpawnAtEntityOrigin ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "ForceSpawnAtEntityCenter", InputForceSpawnAtEntityCenter ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "ForceSpawnAtPosition", InputForceSpawnAtPosition ), +#endif // Functions DEFINE_THINKFUNC( CheckSpawnThink ), END_DATADESC() +BEGIN_ENT_SCRIPTDESC( CEnvEntityMaker, CBaseEntity, "env_entity_maker" ) + DEFINE_SCRIPTFUNC_NAMED( SpawnEntityFromScript, "SpawnEntity", "Create an entity at the location of the maker" ) + DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtEntityOriginFromScript, "SpawnEntityAtEntityOrigin", "Create an entity at the location of a specified entity instance" ) + DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtNamedEntityOriginFromScript, "SpawnEntityAtNamedEntityOrigin", "Create an entity at the location of a named entity" ) + DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtLocationFromScript, "SpawnEntityAtLocation", "Create an entity at a specified location and orientaton, orientation is Euler angle in degrees (pitch, yaw, roll)" ) +END_SCRIPTDESC() + LINK_ENTITY_TO_CLASS( env_entity_maker, CEnvEntityMaker ); @@ -201,6 +227,11 @@ void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternat for ( int i = 0; i < hNewEntities.Count(); i++ ) { CBaseEntity *pEntity = hNewEntities[i]; + +#ifdef MAPBASE + m_pOutputOutEntity.Set(pEntity, pEntity, this); +#endif + if ( pEntity->GetMoveType() == MOVETYPE_NONE ) continue; @@ -238,8 +269,59 @@ void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternat } } } +#ifdef MAPBASE + else + { + for ( int i = 0; i < hNewEntities.Count(); i++ ) + { + m_pOutputOutEntity.Set(hNewEntities[i], hNewEntities[i], this); + } + } +#endif + + pTemplate->CreationComplete( hNewEntities ); +} + +//----------------------------------------------------------------------------- +// Purpose: Spawn an instance of the entity +//----------------------------------------------------------------------------- +void CEnvEntityMaker::SpawnEntityFromScript() +{ + SpawnEntity(); +} + +//----------------------------------------------------------------------------- +// Purpose: Spawn an instance of the entity +//----------------------------------------------------------------------------- +void CEnvEntityMaker::SpawnEntityAtEntityOriginFromScript( HSCRIPT hEntity ) +{ + CBaseEntity *pTargetEntity = ToEnt( hEntity ); + if ( pTargetEntity ) + { + SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Spawn an instance of the entity +//----------------------------------------------------------------------------- +void CEnvEntityMaker::SpawnEntityAtNamedEntityOriginFromScript( const char *pszName ) +{ + CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, pszName, this, NULL, NULL ); + + if( pTargetEntity ) + { + SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() ); + } } +//----------------------------------------------------------------------------- +// Purpose: Spawn an instance of the entity +//----------------------------------------------------------------------------- +void CEnvEntityMaker::SpawnEntityAtLocationFromScript( const Vector &vecAlternateOrigin, const Vector &vecAlternateAngles ) +{ + SpawnEntity( vecAlternateOrigin, *((QAngle *)&vecAlternateAngles) ); +} //----------------------------------------------------------------------------- // Purpose: Returns whether or not the template entities can fit if spawned. @@ -364,3 +446,30 @@ void CEnvEntityMaker::InputForceSpawnAtEntityOrigin( inputdata_t &inputdata ) SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() ); } } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvEntityMaker::InputForceSpawnAtEntityCenter( inputdata_t &inputdata ) +{ + CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); + + if( pTargetEntity ) + { + SpawnEntity( pTargetEntity->WorldSpaceCenter(), pTargetEntity->GetAbsAngles() ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvEntityMaker::InputForceSpawnAtPosition(inputdata_t &inputdata) +{ + Vector vecPos; + inputdata.value.Vector3D(vecPos); + if (vecPos != vec3_origin && vecPos.IsValid()) + { + SpawnEntity(vecPos, GetLocalAngles()); + } +} +#endif // MAPBASE + diff --git a/game/server/env_global_light.cpp b/game/server/env_global_light.cpp index 11e2f5f4..6c1549b2 100644 --- a/game/server/env_global_light.cpp +++ b/game/server/env_global_light.cpp @@ -1,6 +1,6 @@ -//========= Copyright � 1996-2010, Valve Corporation, All rights reserved. ============// +//========= Copyright 1996-2010, Valve Corporation, All rights reserved. ============// // -// Purpose: global dynamic light. +// Purpose: global dynamic light. Ported from Insolence's port of Alien Swarm's env_global_light. // // $NoKeywords: $ //=============================================================================// @@ -21,135 +21,170 @@ class CGlobalLight : public CBaseEntity { public: - DECLARE_CLASS(CGlobalLight, CBaseEntity); + DECLARE_CLASS( CGlobalLight, CBaseEntity ); CGlobalLight(); - void Spawn(void); - bool KeyValue(const char* szKeyName, const char* szValue); - virtual bool GetKeyValue(const char* szKeyName, char* szValue, int iMaxLen); + void Spawn( void ); + bool KeyValue( const char *szKeyName, const char *szValue ); + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); int UpdateTransmitState(); // Inputs - void InputSetAngles(inputdata_t& inputdata); - void InputEnable(inputdata_t& inputdata); - void InputDisable(inputdata_t& inputdata); - void InputSetTexture(inputdata_t& inputdata); - void InputSetEnableShadows(inputdata_t& inputdata); - void InputSetLightColor(inputdata_t& inputdata); - - void InputSetEnableDynamicSky(inputdata_t& inputdata); - void InputSetTimescale(inputdata_t& inputdata); - void InputSetTime(inputdata_t& inputdata); + void InputSetAngles( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputSetTexture( inputdata_t &inputdata ); + void InputSetEnableShadows( inputdata_t &inputdata ); + void InputSetLightColor( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetBrightness( inputdata_t &inputdata ); + void InputSetColorTransitionTime( inputdata_t &inputdata ); + void InputSetXOffset( inputdata_t &inputdata ) { m_flEastOffset = inputdata.value.Float(); } + void InputSetYOffset( inputdata_t &inputdata ) { m_flForwardOffset = inputdata.value.Float(); } + void InputSetOrthoSize( inputdata_t &inputdata ) { m_flOrthoSize = inputdata.value.Float(); } + void InputSetDistance( inputdata_t &inputdata ) { m_flSunDistance = inputdata.value.Float(); } + void InputSetFOV( inputdata_t &inputdata ) { m_flFOV = inputdata.value.Float(); } + void InputSetNearZDistance( inputdata_t &inputdata ) { m_flNearZ = inputdata.value.Float(); } + void InputSetNorthOffset( inputdata_t &inputdata ) { m_flNorthOffset = inputdata.value.Float(); } +#endif - virtual int ObjectCaps(void) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } DECLARE_SERVERCLASS(); DECLARE_DATADESC(); private: - CNetworkVector(m_shadowDirection); - - CNetworkVar(bool, m_bEnabled); - bool m_bStartDisabled; - - CNetworkString(m_TextureName, MAX_PATH); - CNetworkVector(m_LinearFloatLightColor); - CNetworkVector(m_LinearFloatAmbientColor); - CNetworkVar(float, m_flColorTransitionTime); - CNetworkVar(float, m_flSunDistance); - CNetworkVar(float, m_flFOV); - CNetworkVar(float, m_flNearZ); - CNetworkVar(float, m_flNorthOffset); - CNetworkVar(bool, m_bEnableShadows); - CNetworkVar(bool, m_bEnableVolumetrics); - - CNetworkVar(bool, m_bEnableDynamicSky); - CNetworkVar(bool, m_bEnableTimeAngles); - CNetworkVar(float, m_flDayNightTimescale); - CNetworkVar(float, m_fTime); + CNetworkVector( m_shadowDirection ); + + CNetworkVar( bool, m_bEnabled ); + + CNetworkString( m_TextureName, MAX_PATH ); +#ifdef MAPBASE + CNetworkVar( int, m_nSpotlightTextureFrame ); +#endif + CNetworkColor32( m_LightColor ); +#ifdef MAPBASE + CNetworkVar( float, m_flBrightnessScale ); +#endif + CNetworkVar( float, m_flColorTransitionTime ); + CNetworkVar( float, m_flSunDistance ); + CNetworkVar( float, m_flFOV ); + CNetworkVar( float, m_flNearZ ); + CNetworkVar( float, m_flNorthOffset ); +#ifdef MAPBASE + CNetworkVar( float, m_flEastOffset ); // xoffset + CNetworkVar( float, m_flForwardOffset ); // yoffset + CNetworkVar( float, m_flOrthoSize ); +#endif + CNetworkVar( bool, m_bEnableShadows ); }; LINK_ENTITY_TO_CLASS(env_global_light, CGlobalLight); -LINK_ENTITY_TO_CLASS(env_environment, CGlobalLight); - -BEGIN_DATADESC(CGlobalLight) - -DEFINE_KEYFIELD(m_bEnabled, FIELD_BOOLEAN, "enabled"), -DEFINE_KEYFIELD(m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled"), -DEFINE_AUTO_ARRAY_KEYFIELD(m_TextureName, FIELD_CHARACTER, "texturename"), -DEFINE_KEYFIELD(m_flSunDistance, FIELD_FLOAT, "distance"), -DEFINE_KEYFIELD(m_flFOV, FIELD_FLOAT, "fov"), -DEFINE_KEYFIELD(m_flNearZ, FIELD_FLOAT, "nearz"), -DEFINE_KEYFIELD(m_flNorthOffset, FIELD_FLOAT, "northoffset"), -DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), -DEFINE_KEYFIELD(m_bEnableVolumetrics, FIELD_BOOLEAN, "enablevolumetrics"), -DEFINE_KEYFIELD(m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime"), - -DEFINE_KEYFIELD(m_bEnableDynamicSky, FIELD_BOOLEAN, "enabledynamicsky"), -DEFINE_KEYFIELD(m_bEnableTimeAngles, FIELD_BOOLEAN, "usetimeforangles"), - -DEFINE_KEYFIELD(m_flDayNightTimescale, FIELD_FLOAT, "timescale"), -DEFINE_KEYFIELD(m_fTime, FIELD_FLOAT, "time"), - -// Inputs -DEFINE_INPUT(m_flSunDistance, FIELD_FLOAT, "SetDistance"), -DEFINE_INPUT(m_flFOV, FIELD_FLOAT, "SetFOV"), -DEFINE_INPUT(m_flNearZ, FIELD_FLOAT, "SetNearZDistance"), -DEFINE_INPUT(m_flNorthOffset, FIELD_FLOAT, "SetNorthOffset"), - -DEFINE_INPUTFUNC(FIELD_COLOR32, "LightColor", InputSetLightColor), -DEFINE_INPUTFUNC(FIELD_STRING, "SetAngles", InputSetAngles), -DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), -DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), -DEFINE_INPUTFUNC(FIELD_STRING, "SetTexture", InputSetTexture), -DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows), -DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableDynamicSky", InputSetEnableDynamicSky), -DEFINE_INPUTFUNC(FIELD_FLOAT, "EnableSetTimescale", InputSetTimescale), -DEFINE_INPUTFUNC(FIELD_FLOAT, "SetTime", InputSetTime), - -DEFINE_FIELD(m_LinearFloatLightColor, FIELD_VECTOR), -DEFINE_FIELD(m_LinearFloatAmbientColor, FIELD_VECTOR), + +BEGIN_DATADESC( CGlobalLight ) + + DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "enabled" ), + DEFINE_AUTO_ARRAY_KEYFIELD( m_TextureName, FIELD_CHARACTER, "texturename" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ), +#endif + DEFINE_KEYFIELD( m_flSunDistance, FIELD_FLOAT, "distance" ), + DEFINE_KEYFIELD( m_flFOV, FIELD_FLOAT, "fov" ), + DEFINE_KEYFIELD( m_flNearZ, FIELD_FLOAT, "nearz" ), + DEFINE_KEYFIELD( m_flNorthOffset, FIELD_FLOAT, "northoffset" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flEastOffset, FIELD_FLOAT, "eastoffset" ), + DEFINE_KEYFIELD( m_flForwardOffset, FIELD_FLOAT, "forwardoffset" ), + DEFINE_KEYFIELD( m_flOrthoSize, FIELD_FLOAT, "orthosize" ), +#endif + DEFINE_KEYFIELD( m_bEnableShadows, FIELD_BOOLEAN, "enableshadows" ), + DEFINE_FIELD( m_LightColor, FIELD_COLOR32 ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flBrightnessScale, FIELD_FLOAT, "brightnessscale" ), +#endif + DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ), + + DEFINE_FIELD( m_shadowDirection, FIELD_VECTOR ), + + // Inputs +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetXOffset", InputSetXOffset ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetYOffset", InputSetYOffset ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetOrthoSize", InputSetOrthoSize ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDistance", InputSetDistance ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFOV", InputSetFOV ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZDistance", InputSetNearZDistance ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNorthOffset", InputSetNorthOffset ), +#else + DEFINE_INPUT( m_flSunDistance, FIELD_FLOAT, "SetDistance" ), + DEFINE_INPUT( m_flFOV, FIELD_FLOAT, "SetFOV" ), + DEFINE_INPUT( m_flNearZ, FIELD_FLOAT, "SetNearZDistance" ), + DEFINE_INPUT( m_flNorthOffset, FIELD_FLOAT, "SetNorthOffset" ), +#endif + + DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetAngles", InputSetAngles ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTexture", InputSetTexture ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBrightness", InputSetBrightness ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetColorTransitionTime", InputSetColorTransitionTime ), +#endif END_DATADESC() IMPLEMENT_SERVERCLASS_ST_NOBASE(CGlobalLight, DT_GlobalLight) -SendPropVector(SENDINFO(m_shadowDirection), -1, SPROP_NOSCALE), -SendPropBool(SENDINFO(m_bEnabled)), -SendPropString(SENDINFO(m_TextureName)), -SendPropVector(SENDINFO(m_LinearFloatLightColor)), -SendPropVector(SENDINFO(m_LinearFloatAmbientColor)), -SendPropFloat(SENDINFO(m_flColorTransitionTime)), -SendPropFloat(SENDINFO(m_flSunDistance), 0, SPROP_NOSCALE), -SendPropFloat(SENDINFO(m_flFOV), 0, SPROP_NOSCALE), -SendPropFloat(SENDINFO(m_flNearZ), 0, SPROP_NOSCALE), -SendPropFloat(SENDINFO(m_flNorthOffset), 0, SPROP_NOSCALE), -SendPropBool(SENDINFO(m_bEnableShadows)), - -SendPropBool(SENDINFO(m_bEnableDynamicSky)), -SendPropFloat(SENDINFO(m_flDayNightTimescale)), -SendPropFloat(SENDINFO(m_fTime)), + SendPropVector(SENDINFO(m_shadowDirection), -1, SPROP_NOSCALE ), + SendPropBool(SENDINFO(m_bEnabled) ), + SendPropString(SENDINFO(m_TextureName)), +#ifdef MAPBASE + SendPropInt(SENDINFO(m_nSpotlightTextureFrame)), +#endif + /*SendPropInt(SENDINFO (m_LightColor ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),*/ + SendPropInt(SENDINFO (m_LightColor ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt ), +#ifdef MAPBASE + SendPropFloat( SENDINFO( m_flBrightnessScale ) ), +#endif + SendPropFloat( SENDINFO( m_flColorTransitionTime ) ), + SendPropFloat(SENDINFO(m_flSunDistance), 0, SPROP_NOSCALE ), + SendPropFloat(SENDINFO(m_flFOV), 0, SPROP_NOSCALE ), + SendPropFloat(SENDINFO(m_flNearZ), 0, SPROP_NOSCALE ), + SendPropFloat(SENDINFO(m_flNorthOffset), 0, SPROP_NOSCALE ), +#ifdef MAPBASE + SendPropFloat(SENDINFO(m_flEastOffset), 0, SPROP_NOSCALE ), + SendPropFloat(SENDINFO(m_flForwardOffset), 0, SPROP_NOSCALE ), + SendPropFloat(SENDINFO(m_flOrthoSize), 0, SPROP_NOSCALE ), +#endif + SendPropBool( SENDINFO( m_bEnableShadows ) ), END_SEND_TABLE() CGlobalLight::CGlobalLight() { #if defined( _X360 ) - Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight_border"); + Q_strcpy( m_TextureName.GetForModify(), "effects/flashlight_border" ); +#else + Q_strcpy( m_TextureName.GetForModify(), "effects/flashlight001" ); +#endif +#ifdef MAPBASE + m_LightColor.Init( 255, 255, 255, 255 ); #else - Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight001"); + m_LightColor.Init( 255, 255, 255, 1 ); #endif m_flColorTransitionTime = 0.5f; m_flSunDistance = 10000.0f; - m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); m_flFOV = 5.0f; m_bEnableShadows = false; - - m_bEnableDynamicSky = false; - m_bEnableTimeAngles = false; - m_flDayNightTimescale = 1.0f; - m_fTime = 0.0f; +#ifdef MAPBASE + m_nSpotlightTextureFrame = 0; + m_flBrightnessScale = 1.0f; + m_flOrthoSize = 1000.0f; +#endif + m_bEnabled = true; } @@ -159,145 +194,143 @@ CGlobalLight::CGlobalLight() int CGlobalLight::UpdateTransmitState() { // ALWAYS transmit to all clients. - return SetTransmitState(FL_EDICT_ALWAYS); + return SetTransmitState( FL_EDICT_ALWAYS ); } -extern void UTIL_ColorStringToLinearFloatColor(Vector& color, const char* pString); -bool CGlobalLight::KeyValue(const char* szKeyName, const char* szValue) +bool CGlobalLight::KeyValue( const char *szKeyName, const char *szValue ) { - if (FStrEq(szKeyName, "color")) - { - Vector tmp; - UTIL_ColorStringToLinearFloatColor(tmp, szValue); - m_LinearFloatLightColor = tmp; - } - else if (FStrEq(szKeyName, "ambient")) +#ifdef MAPBASE + if ( FStrEq( szKeyName, "lightcolor" ) || FStrEq( szKeyName, "color" ) ) +#else + if ( FStrEq( szKeyName, "color" ) ) +#endif { - Vector tmp; - UTIL_ColorStringToLinearFloatColor(tmp, szValue); - m_LinearFloatAmbientColor = tmp; + float tmp[4]; + UTIL_StringToFloatArray( tmp, 4, szValue ); + + m_LightColor.SetR( tmp[0] ); + m_LightColor.SetG( tmp[1] ); + m_LightColor.SetB( tmp[2] ); + m_LightColor.SetA( tmp[3] ); } - else if (FStrEq(szKeyName, "angles")) + else if ( FStrEq( szKeyName, "angles" ) ) { QAngle angles; - UTIL_StringToVector(angles.Base(), szValue); + UTIL_StringToVector( angles.Base(), szValue ); if (angles == vec3_angle) { - angles.Init(80, 30, 0); + angles.Init( 80, 30, 0 ); } Vector vForward; - AngleVectors(angles, &vForward); + AngleVectors( angles, &vForward ); m_shadowDirection = vForward; return true; } - else if (FStrEq(szKeyName, "texturename")) + else if ( FStrEq( szKeyName, "texturename" ) ) { #if defined( _X360 ) - if (Q_strcmp(szValue, "effects/flashlight001") == 0) + if ( Q_strcmp( szValue, "effects/flashlight001" ) == 0 ) { // Use this as the default for Xbox - Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight_border"); + Q_strcpy( m_TextureName.GetForModify(), "effects/flashlight_border" ); } else { - Q_strcpy(m_TextureName.GetForModify(), szValue); + Q_strcpy( m_TextureName.GetForModify(), szValue ); } #else - Q_strcpy(m_TextureName.GetForModify(), szValue); + Q_strcpy( m_TextureName.GetForModify(), szValue ); #endif } + else if ( FStrEq( szKeyName, "StartDisabled" ) ) + { + m_bEnabled.Set( atoi( szValue ) <= 0 ); + } - return BaseClass::KeyValue(szKeyName, szValue); + return BaseClass::KeyValue( szKeyName, szValue ); } -bool CGlobalLight::GetKeyValue(const char* szKeyName, char* szValue, int iMaxLen) +bool CGlobalLight::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) { - if (FStrEq(szKeyName, "color")) + if ( FStrEq( szKeyName, "color" ) ) { - //Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() ); + Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() ); return true; } - else if (FStrEq(szKeyName, "texturename")) + else if ( FStrEq( szKeyName, "texturename" ) ) { - Q_snprintf(szValue, iMaxLen, "%s", m_TextureName.Get()); + Q_snprintf( szValue, iMaxLen, "%s", m_TextureName.Get() ); return true; } - return BaseClass::GetKeyValue(szKeyName, szValue, iMaxLen); + else if ( FStrEq( szKeyName, "StartDisabled" ) ) + { + Q_snprintf( szValue, iMaxLen, "%d", !m_bEnabled.Get() ); + return true; + } + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); } //------------------------------------------------------------------------------ // Purpose : //------------------------------------------------------------------------------ -void CGlobalLight::Spawn(void) +void CGlobalLight::Spawn( void ) { Precache(); - SetSolid(SOLID_NONE); - - if (m_bStartDisabled) - { - m_bEnabled = false; - } - else - { - m_bEnabled = true; - } + SetSolid( SOLID_NONE ); } //------------------------------------------------------------------------------ // Input values //------------------------------------------------------------------------------ -void CGlobalLight::InputSetAngles(inputdata_t& inputdata) +void CGlobalLight::InputSetAngles( inputdata_t &inputdata ) { - const char* pAngles = inputdata.value.String(); + const char *pAngles = inputdata.value.String(); QAngle angles; - UTIL_StringToVector(angles.Base(), pAngles); + UTIL_StringToVector( angles.Base(), pAngles ); Vector vTemp; - AngleVectors(angles, &vTemp); + AngleVectors( angles, &vTemp ); m_shadowDirection = vTemp; } //------------------------------------------------------------------------------ // Purpose : Input handlers //------------------------------------------------------------------------------ -void CGlobalLight::InputEnable(inputdata_t& inputdata) +void CGlobalLight::InputEnable( inputdata_t &inputdata ) { m_bEnabled = true; } -void CGlobalLight::InputDisable(inputdata_t& inputdata) +void CGlobalLight::InputDisable( inputdata_t &inputdata ) { m_bEnabled = false; } -void CGlobalLight::InputSetTexture(inputdata_t& inputdata) +void CGlobalLight::InputSetTexture( inputdata_t &inputdata ) { - Q_strcpy(m_TextureName.GetForModify(), inputdata.value.String()); + Q_strcpy( m_TextureName.GetForModify(), inputdata.value.String() ); } -void CGlobalLight::InputSetEnableShadows(inputdata_t& inputdata) +void CGlobalLight::InputSetEnableShadows( inputdata_t &inputdata ) { m_bEnableShadows = inputdata.value.Bool(); } -void CGlobalLight::InputSetLightColor(inputdata_t& inputdata) +void CGlobalLight::InputSetLightColor( inputdata_t &inputdata ) { - //m_LightColor = inputdata.value.Color32(); -} + m_LightColor = inputdata.value.Color32(); +} -void CGlobalLight::InputSetEnableDynamicSky(inputdata_t& inputdata) +#ifdef MAPBASE +void CGlobalLight::InputSetBrightness( inputdata_t &inputdata ) { - m_bEnableDynamicSky = inputdata.value.Bool(); + m_flBrightnessScale = inputdata.value.Float(); } -void CGlobalLight::InputSetTimescale(inputdata_t& inputdata) +void CGlobalLight::InputSetColorTransitionTime( inputdata_t &inputdata ) { - m_flDayNightTimescale = inputdata.value.Float(); -} - -void CGlobalLight::InputSetTime(inputdata_t& inputdata) -{ - m_fTime = inputdata.value.Float(); + m_flColorTransitionTime = inputdata.value.Float(); } +#endif diff --git a/game/server/env_instructor_hint.cpp b/game/server/env_instructor_hint.cpp new file mode 100644 index 00000000..3ee20fb2 --- /dev/null +++ b/game/server/env_instructor_hint.cpp @@ -0,0 +1,319 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: An entity for creating instructor hints entirely with map logic +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "baseentity.h" +#include "world.h" +#ifdef MAPBASE +#include "eventqueue.h" +#endif + +#ifdef INFESTED_DLL + #include "asw_marine.h" + #include "asw_player.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CEnvInstructorHint : public CPointEntity +{ +public: + DECLARE_CLASS( CEnvInstructorHint, CPointEntity ); + DECLARE_DATADESC(); + +#ifdef MAPBASE + CEnvInstructorHint( void ); +#endif + virtual ~CEnvInstructorHint( void ) {} + +#ifdef MAPBASE + virtual void OnRestore( void ); +#endif + +private: + void InputShowHint( inputdata_t &inputdata ); + void InputEndHint( inputdata_t &inputdata ); + +#ifdef MAPBASE + void InputSetCaption( inputdata_t &inputdata ) { m_iszCaption = inputdata.value.StringID(); } +#endif + + string_t m_iszReplace_Key; + string_t m_iszHintTargetEntity; + int m_iTimeout; + string_t m_iszIcon_Onscreen; + string_t m_iszIcon_Offscreen; + string_t m_iszCaption; + string_t m_iszActivatorCaption; + color32 m_Color; + float m_fIconOffset; + float m_fRange; + uint8 m_iPulseOption; + uint8 m_iAlphaOption; + uint8 m_iShakeOption; + bool m_bStatic; + bool m_bNoOffscreen; + bool m_bForceCaption; + string_t m_iszBinding; + bool m_bAllowNoDrawTarget; + bool m_bLocalPlayerOnly; +#ifdef MAPBASE + string_t m_iszStartSound; + int m_iHintTargetPos; + float m_flActiveUntil; + CHandle m_hActivator; + EHANDLE m_hTarget; + bool m_bFilterByActivator; +#endif +}; + +LINK_ENTITY_TO_CLASS( env_instructor_hint, CEnvInstructorHint ); + +BEGIN_DATADESC( CEnvInstructorHint ) + + DEFINE_KEYFIELD( m_iszReplace_Key, FIELD_STRING, "hint_replace_key" ), + DEFINE_KEYFIELD( m_iszHintTargetEntity, FIELD_STRING, "hint_target" ), + DEFINE_KEYFIELD( m_iTimeout, FIELD_INTEGER, "hint_timeout" ), + DEFINE_KEYFIELD( m_iszIcon_Onscreen, FIELD_STRING, "hint_icon_onscreen" ), + DEFINE_KEYFIELD( m_iszIcon_Offscreen, FIELD_STRING, "hint_icon_offscreen" ), + DEFINE_KEYFIELD( m_iszCaption, FIELD_STRING, "hint_caption" ), + DEFINE_KEYFIELD( m_iszActivatorCaption, FIELD_STRING, "hint_activator_caption" ), + DEFINE_KEYFIELD( m_Color, FIELD_COLOR32, "hint_color" ), + DEFINE_KEYFIELD( m_fIconOffset, FIELD_FLOAT, "hint_icon_offset" ), + DEFINE_KEYFIELD( m_fRange, FIELD_FLOAT, "hint_range" ), + DEFINE_KEYFIELD( m_iPulseOption, FIELD_CHARACTER, "hint_pulseoption" ), + DEFINE_KEYFIELD( m_iAlphaOption, FIELD_CHARACTER, "hint_alphaoption" ), + DEFINE_KEYFIELD( m_iShakeOption, FIELD_CHARACTER, "hint_shakeoption" ), + DEFINE_KEYFIELD( m_bStatic, FIELD_BOOLEAN, "hint_static" ), + DEFINE_KEYFIELD( m_bNoOffscreen, FIELD_BOOLEAN, "hint_nooffscreen" ), + DEFINE_KEYFIELD( m_bForceCaption, FIELD_BOOLEAN, "hint_forcecaption" ), + DEFINE_KEYFIELD( m_iszBinding, FIELD_STRING, "hint_binding" ), + DEFINE_KEYFIELD( m_bAllowNoDrawTarget, FIELD_BOOLEAN, "hint_allow_nodraw_target" ), + DEFINE_KEYFIELD( m_bLocalPlayerOnly, FIELD_BOOLEAN, "hint_local_player_only" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszStartSound, FIELD_STRING, "hint_start_sound" ), + DEFINE_KEYFIELD( m_iHintTargetPos, FIELD_INTEGER, "hint_target_pos" ), + + DEFINE_FIELD( m_flActiveUntil, FIELD_TIME ), + DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), + DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), + DEFINE_FIELD( m_bFilterByActivator, FIELD_BOOLEAN ), +#endif + + DEFINE_INPUTFUNC( FIELD_STRING, "ShowHint", InputShowHint ), + DEFINE_INPUTFUNC( FIELD_VOID, "EndHint", InputEndHint ), + +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetCaption", InputSetCaption ), +#endif + +END_DATADESC() + + +#define LOCATOR_ICON_FX_PULSE_SLOW 0x00000001 +#define LOCATOR_ICON_FX_ALPHA_SLOW 0x00000008 +#define LOCATOR_ICON_FX_SHAKE_NARROW 0x00000040 +#define LOCATOR_ICON_FX_STATIC 0x00000100 // This icon draws at a fixed location on the HUD. + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CEnvInstructorHint::CEnvInstructorHint( void ) +{ + m_hActivator = NULL; + m_hTarget = NULL; + m_bFilterByActivator = false; + m_flActiveUntil = -1.0f; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvInstructorHint::OnRestore( void ) +{ + BaseClass::OnRestore(); + + int iTimeLeft = 0; + if ( m_flActiveUntil < 0.0f ) + { + return; + } + if ( m_iTimeout != 0 ) + { + iTimeLeft = static_cast( m_flActiveUntil - gpGlobals->curtime ); + if ( iTimeLeft <= 0 ) + { + return; + } + } + + int iOriginalTimeout = m_iTimeout; + m_iTimeout = iTimeLeft; + g_EventQueue.AddEvent( this, "ShowHint", 0.01f, NULL, this ); + m_iTimeout = iOriginalTimeout; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Input handler for showing the message and/or playing the sound. +//----------------------------------------------------------------------------- +void CEnvInstructorHint::InputShowHint( inputdata_t &inputdata ) +{ + IGameEvent * event = gameeventmanager->CreateEvent( "instructor_server_hint_create", false ); + if ( event ) + { + CBaseEntity *pTargetEntity = NULL; + +#ifdef MAPBASE + pTargetEntity = m_hTarget; + + if ( pTargetEntity == NULL ) +#endif + pTargetEntity = gEntList.FindEntityByName( NULL, m_iszHintTargetEntity ); + + if( pTargetEntity == NULL && !m_bStatic ) + pTargetEntity = inputdata.pActivator; + + if( pTargetEntity == NULL ) + pTargetEntity = GetWorldEntity(); + + char szColorString[128]; + Q_snprintf( szColorString, sizeof( szColorString ), "%.3d,%.3d,%.3d", m_Color.r, m_Color.g, m_Color.b ); + + int iFlags = 0; + + iFlags |= (m_iPulseOption == 0) ? 0 : (LOCATOR_ICON_FX_PULSE_SLOW << (m_iPulseOption - 1)); + iFlags |= (m_iAlphaOption == 0) ? 0 : (LOCATOR_ICON_FX_ALPHA_SLOW << (m_iAlphaOption - 1)); + iFlags |= (m_iShakeOption == 0) ? 0 : (LOCATOR_ICON_FX_SHAKE_NARROW << (m_iShakeOption - 1)); + iFlags |= m_bStatic ? LOCATOR_ICON_FX_STATIC : 0; + + CBasePlayer *pActivator = NULL; + bool bFilterByActivator = m_bLocalPlayerOnly; + +#ifdef INFESTED_DLL + CASW_Marine *pMarine = dynamic_cast( inputdata.pActivator ); + if ( pMarine ) + { + pActivator = pMarine->GetCommander(); + } +#else +#ifdef MAPBASE + if ( m_hActivator ) + { + pActivator = m_hActivator; + bFilterByActivator = m_bFilterByActivator; + } + else +#endif + + if ( inputdata.value.StringID() != NULL_STRING ) + { + CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, inputdata.value.String() ); + pActivator = dynamic_cast( pTarget ); + if ( pActivator ) + { + bFilterByActivator = true; + } + } + else + { + if ( GameRules()->IsMultiplayer() == false ) + { + pActivator = UTIL_GetLocalPlayer(); + } + else + { + Warning( "Failed to play server side instructor hint: no player specified for hint\n" ); + Assert( 0 ); + } + } +#endif + + const char *pActivatorCaption = m_iszActivatorCaption.ToCStr(); + if ( !pActivatorCaption || pActivatorCaption[ 0 ] == '\0' ) + { + pActivatorCaption = m_iszCaption.ToCStr(); + } + + event->SetString( "hint_name", GetEntityName().ToCStr() ); + event->SetString( "hint_replace_key", m_iszReplace_Key.ToCStr() ); + event->SetInt( "hint_target", pTargetEntity->entindex() ); + event->SetInt( "hint_activator_userid", ( pActivator ? pActivator->GetUserID() : 0 ) ); + event->SetInt( "hint_timeout", m_iTimeout ); + event->SetString( "hint_icon_onscreen", m_iszIcon_Onscreen.ToCStr() ); + event->SetString( "hint_icon_offscreen", m_iszIcon_Offscreen.ToCStr() ); + event->SetString( "hint_caption", m_iszCaption.ToCStr() ); + event->SetString( "hint_activator_caption", pActivatorCaption ); + event->SetString( "hint_color", szColorString ); + event->SetFloat( "hint_icon_offset", m_fIconOffset ); + event->SetFloat( "hint_range", m_fRange ); + event->SetInt( "hint_flags", iFlags ); + event->SetString( "hint_binding", m_iszBinding.ToCStr() ); + event->SetBool( "hint_allow_nodraw_target", m_bAllowNoDrawTarget ); + event->SetBool( "hint_nooffscreen", m_bNoOffscreen ); + event->SetBool( "hint_forcecaption", m_bForceCaption ); + event->SetBool( "hint_local_player_only", bFilterByActivator ); +#ifdef MAPBASE + event->SetString( "hint_start_sound", m_iszStartSound.ToCStr() ); + event->SetInt( "hint_target_pos", m_iHintTargetPos ); +#endif + + gameeventmanager->FireEvent( event ); + +#ifdef MAPBASE + m_flActiveUntil = gpGlobals->curtime + m_iTimeout; + m_hTarget = pTargetEntity; + m_hActivator = pActivator; + m_bFilterByActivator = bFilterByActivator; +#endif + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CEnvInstructorHint::InputEndHint( inputdata_t &inputdata ) +{ + IGameEvent * event = gameeventmanager->CreateEvent( "instructor_server_hint_stop", false ); + if ( event ) + { + event->SetString( "hint_name", GetEntityName().ToCStr() ); + + gameeventmanager->FireEvent( event ); + +#ifdef MAPBASE + m_flActiveUntil = -1.0f; + m_hActivator = NULL; + m_hTarget = NULL; + m_bFilterByActivator = false; +#endif + } +} + +//----------------------------------------------------------------------------- +// Purpose: A generic target entity that gets replicated to the client for instructor hint targetting +//----------------------------------------------------------------------------- +class CInfoInstructorHintTarget : public CPointEntity +{ +public: + DECLARE_CLASS( CInfoInstructorHintTarget, CPointEntity ); + + virtual int UpdateTransmitState( void ) // set transmit filter to transmit always + { + return SetTransmitState( FL_EDICT_ALWAYS ); + } + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( info_target_instructor_hint, CInfoInstructorHintTarget ); + +BEGIN_DATADESC( CInfoInstructorHintTarget ) + +END_DATADESC() diff --git a/game/server/env_music.cpp b/game/server/env_music.cpp deleted file mode 100644 index 05595c7a..00000000 --- a/game/server/env_music.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "cbase.h" -/* -class CEnvMusicChannel; - -class CEnvMusicMaster : public CBaseEntity -{ - DECLARE_CLASS(CEnvMusicMaster, CBaseEntity); - DECLARE_SERVERCLASS(); - DECLARE_DATADESC(); -public: - void Spawn(); - void Think(); - - int GetBPM(); - -private: - int m_iBPM; - - bool m_bStartEnabled; - - char* m_szMainLoopFile; - char* m_szAlternateLoopFile; - - float m_flVolume; // must be range 1-9 - - CEnvMusicChannel *m_pChannels; -}; - -LINK_ENTITY_TO_CLASS(env_music_master, CEnvMusicMaster); - -BEGIN_DATADESC(CEnvMusicMaster) -DEFINE_KEYFIELD(m_szMainLoopFile, FIELD_STRING, "Master Loop"), -DEFINE_KEYFIELD(m_szAlternateLoopFile, FIELD_STRING, "Alternate Loop"), -DEFINE_KEYFIELD(m_flVolume, FIELD_FLOAT, "Volume"), -END_DATADESC() - -IMPLEMENT_SERVERCLASS_ST(CEnvMusicMaster, DT_EnvMusicMaster) -SendPropBool() -END_SEND_TABLE() - -void CEnvMusicMaster::Spawn() -{ - BaseClass::Spawn(); - - if (m_bStartEnabled) - { - SetNextThink(gpGlobals->curtime); - } -} - -void CEnvMusicMaster::Think() -{ - BaseClass::Think(); - - SetNextThink(gpGlobals->curtime + 0.15); -} - -int CEnvMusicMaster::GetBPM() -{ - static bool bpmSet = false; - if (!bpmSet) - { - m_iBPM = /* GET BPM FROM MAIN LOOP ; - } - - return m_iBPM; -} - -enum -{ - SF_QUANTIZE = (1 << 32), - SF_LOOP = (1 << 33), -}; - -class CEnvMusicChannel : public CBaseEntity -{ - DECLARE_CLASS(CEnvMusicChannel, CBaseEntity); - DECLARE_DATADESC(); -public: - void Spawn(); - void Think(); - -private: - - // Keyfields - char *m_szLoopCue; - float m_flVolume; - int m_iPlayOnBeat; - float m_flInterval; - - // Flags - CNetworkVar(bool, m_bQuantize); - CNetworkVar(bool, m_bLoop); -}; - -LINK_ENTITY_TO_CLASS(env_music_channel, CEnvMusicChannel); - -BEGIN_DATADESC(CEnvMusicChannel) -DEFINE_KEYFIELD(m_szLoopCue, FIELD_STRING, "Alternate Loop"), -DEFINE_KEYFIELD(m_flVolume, FIELD_FLOAT, "Volume"), -DEFINE_KEYFIELD(m_iPlayOnBeat, FIELD_INTEGER, "Play on beat") -DEFINE_KEYFIELD(m_flInterval, FIELD_FLOAT, "Interval"), -END_DATADESC() - -IMPLEMENT_SERVERCLASS_ST(CEnvMusicChannel, DT_EnvMusicChannel) -SendPropBool(SENDINFO(m_bLoop)), -SendPropBool(SENDINFO(m_bQuantize)), -END_SEND_TABLE() - -void CEnvMusicChannel::Spawn() -{ - BaseClass::Spawn(); - - if (GetSpawnFlags() & SF_QUANTIZE) - { - m_bQuantize = true; - } - - if (GetSpawnFlags() & SF_LOOP) - { - m_bLoop = true; - } -} - -void CEnvMusicChannel::Think() -{ - BaseClass::Think(); - - SetNextThink(gpGlobals->curtime + 0.15); -}*/ \ No newline at end of file diff --git a/game/server/env_projectedtexture.cpp b/game/server/env_projectedtexture.cpp index f6330ddf..15fb1367 100644 --- a/game/server/env_projectedtexture.cpp +++ b/game/server/env_projectedtexture.cpp @@ -1,20 +1,539 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: Entity to control screen overlays on a player // -// $NoKeywords: $ -//=============================================================================// +//============================================================================= #include "cbase.h" #include "shareddefs.h" - +#ifdef ASW_PROJECTED_TEXTURES #include "env_projectedtexture.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef ASW_PROJECTED_TEXTURES + LINK_ENTITY_TO_CLASS( env_projectedtexture, CEnvProjectedTexture ); +BEGIN_DATADESC( CEnvProjectedTexture ) + DEFINE_FIELD( m_hTargetEntity, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDontFollowTarget, FIELD_BOOLEAN, "dontfollowtarget" ), + DEFINE_FIELD( m_bAlwaysUpdate, FIELD_BOOLEAN ), +#endif + DEFINE_FIELD( m_bState, FIELD_BOOLEAN ), + DEFINE_KEYFIELD( m_flLightFOV, FIELD_FLOAT, "lightfov" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flLightHorFOV, FIELD_FLOAT, "lighthorfov" ), +#endif + DEFINE_KEYFIELD( m_bEnableShadows, FIELD_BOOLEAN, "enableshadows" ), + DEFINE_KEYFIELD( m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget" ), + DEFINE_KEYFIELD( m_bLightWorld, FIELD_BOOLEAN, "lightworld" ), + DEFINE_KEYFIELD( m_bCameraSpace, FIELD_BOOLEAN, "cameraspace" ), + DEFINE_KEYFIELD( m_flAmbient, FIELD_FLOAT, "ambient" ), + DEFINE_AUTO_ARRAY( m_SpotlightTextureName, FIELD_CHARACTER ), + DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ), + DEFINE_KEYFIELD( m_flNearZ, FIELD_FLOAT, "nearz" ), + DEFINE_KEYFIELD( m_flFarZ, FIELD_FLOAT, "farz" ), + DEFINE_KEYFIELD( m_nShadowQuality, FIELD_INTEGER, "shadowquality" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bAlwaysDraw, FIELD_BOOLEAN, "alwaysdraw" ), + DEFINE_KEYFIELD( m_bProjectedTextureVersion, FIELD_BOOLEAN, "ProjectedTextureVersion" ), +#endif + DEFINE_KEYFIELD( m_flBrightnessScale, FIELD_FLOAT, "brightnessscale" ), + DEFINE_FIELD( m_LightColor, FIELD_COLOR32 ), + DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ), +#ifdef MAPBASE + DEFINE_FIELD( m_flConstantAtten, FIELD_FLOAT ), + DEFINE_FIELD( m_flLinearAtten, FIELD_FLOAT ), + DEFINE_FIELD( m_flQuadraticAtten, FIELD_FLOAT ), + DEFINE_KEYFIELD( m_flShadowAtten, FIELD_FLOAT, "shadowatten" ), + DEFINE_KEYFIELD( m_flShadowFilter, FIELD_FLOAT, "shadowfilter" ), +#endif + + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOn", InputAlwaysUpdateOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOff", InputAlwaysUpdateOff ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "FOV", InputSetFOV ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "VerFOV", InputSetVerFOV ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "HorFOV", InputSetHorFOV ), +#endif + DEFINE_INPUTFUNC( FIELD_EHANDLE, "Target", InputSetTarget ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "CameraSpace", InputSetCameraSpace ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightOnlyTarget", InputSetLightOnlyTarget ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightWorld", InputSetLightWorld ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows ), + DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "Ambient", InputSetAmbient ), + DEFINE_INPUTFUNC( FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSpotlightFrame", InputSetSpotlightFrame ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBrightness", InputSetBrightness ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetColorTransitionTime", InputSetColorTransitionTime ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetQuadratic", InputSetQuadratic ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLinear", InputSetLinear ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetConstant", InputSetConstant ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetShadowAtten", InputSetShadowAtten ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFilter", InputSetFilter ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZ", InputSetNearZ ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarZ", InputSetFarZ ), + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOn", InputAlwaysDrawOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOff", InputAlwaysDrawOff ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopFollowingTarget", InputStopFollowingTarget ), + DEFINE_INPUTFUNC( FIELD_VOID, "StartFollowingTarget", InputStartFollowingTarget ), +#endif + DEFINE_THINKFUNC( InitialThink ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture ) + SendPropEHandle( SENDINFO( m_hTargetEntity ) ), +#ifdef MAPBASE + SendPropBool( SENDINFO( m_bDontFollowTarget ) ), +#endif + SendPropBool( SENDINFO( m_bState ) ), + SendPropBool( SENDINFO( m_bAlwaysUpdate ) ), + SendPropFloat( SENDINFO( m_flLightFOV ) ), +#ifdef MAPBASE + SendPropFloat( SENDINFO( m_flLightHorFOV ) ), +#endif + SendPropBool( SENDINFO( m_bEnableShadows ) ), + SendPropBool( SENDINFO( m_bLightOnlyTarget ) ), + SendPropBool( SENDINFO( m_bLightWorld ) ), + SendPropBool( SENDINFO( m_bCameraSpace ) ), + SendPropFloat( SENDINFO( m_flBrightnessScale ) ), + SendPropInt( SENDINFO ( m_LightColor ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt ), + SendPropFloat( SENDINFO( m_flColorTransitionTime ) ), + SendPropFloat( SENDINFO( m_flAmbient ) ), + SendPropString( SENDINFO( m_SpotlightTextureName ) ), + SendPropInt( SENDINFO( m_nSpotlightTextureFrame ) ), + SendPropFloat( SENDINFO( m_flNearZ ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f ), + SendPropFloat( SENDINFO( m_flFarZ ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f ), + SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now +#ifdef MAPBASE + SendPropFloat( SENDINFO( m_flConstantAtten ) ), + SendPropFloat( SENDINFO( m_flLinearAtten ) ), + SendPropFloat( SENDINFO( m_flQuadraticAtten ) ), + SendPropFloat( SENDINFO( m_flShadowAtten ) ), + SendPropFloat( SENDINFO( m_flShadowFilter ) ), + SendPropBool( SENDINFO( m_bAlwaysDraw ) ), + + // Not needed on the client right now, change when it actually is needed + //SendPropBool( SENDINFO( m_bProjectedTextureVersion ) ), +#endif +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CEnvProjectedTexture::CEnvProjectedTexture( void ) +{ + m_bState = true; + m_bAlwaysUpdate = false; + m_flLightFOV = 45.0f; + m_bEnableShadows = false; + m_bLightOnlyTarget = false; + m_bLightWorld = true; + m_bCameraSpace = false; + +#ifndef MAPBASE + Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" ); +#endif + Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight001" ); + + m_nSpotlightTextureFrame = 0; + m_flBrightnessScale = 1.0f; + m_LightColor.Init( 255, 255, 255, 255 ); +#ifdef MAPBASE + m_flColorTransitionTime = 0.0f; +#else + m_flColorTransitionTime = 0.5f; +#endif + m_flAmbient = 0.0f; + m_flNearZ = 4.0f; + m_flFarZ = 750.0f; + m_nShadowQuality = 0; +#ifdef MAPBASE + m_flQuadraticAtten = 0.0f; + m_flLinearAtten = 100.0f; + m_flConstantAtten = 0.0f; + m_flShadowAtten = 0.0f; + m_flShadowFilter = 0.5f; +#endif +} + +void UTIL_ColorStringToLinearFloatColor( Vector &color, const char *pString ) +{ + float tmp[4]; + UTIL_StringToFloatArray( tmp, 4, pString ); + if( tmp[3] <= 0.0f ) + { + tmp[3] = 255.0f; + } + tmp[3] *= ( 1.0f / 255.0f ); + color.x = tmp[0] * ( 1.0f / 255.0f ) * tmp[3]; + color.y = tmp[1] * ( 1.0f / 255.0f ) * tmp[3]; + color.z = tmp[2] * ( 1.0f / 255.0f ) * tmp[3]; +} + +bool CEnvProjectedTexture::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "lightcolor" ) ) + { +#ifdef MAPBASE + // + // Most existing projected textures don't have intensity implemented. + // This can give them 0% intensity, which makes them invisible. + // If intensity is not detected, assume 255. + // + // Also, get rid of the floats, for god's sake. Have you ever seen a color32 with decimals? + // + int tmp[4]; + tmp[3] = 255; + UTIL_StringToIntArray_PreserveArray( tmp, 4, szValue ); + + m_LightColor.SetR( tmp[0] ); + m_LightColor.SetG( tmp[1] ); + m_LightColor.SetB( tmp[2] ); + m_LightColor.SetA( tmp[3] ); +#else + float tmp[4]; + UTIL_StringToFloatArray( tmp, 4, szValue ); + + m_LightColor.SetR( tmp[0] ); + m_LightColor.SetG( tmp[1] ); + m_LightColor.SetB( tmp[2] ); + m_LightColor.SetA( tmp[3] ); +#endif + } + else if ( FStrEq( szKeyName, "texturename" ) ) + { +#if defined( _X360 ) + if ( Q_strcmp( szValue, "effects/flashlight001" ) == 0 ) + { + // Use this as the default for Xbox + Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" ); + } + else + { + Q_strcpy( m_SpotlightTextureName.GetForModify(), szValue ); + } +#else + Q_strcpy( m_SpotlightTextureName.GetForModify(), szValue ); +#endif + } +#ifdef MAPBASE + else if ( FStrEq( szKeyName, "constant_attn" ) ) + { + m_flConstantAtten = CorrectConstantAtten( atof( szValue ) ); + } + else if ( FStrEq( szKeyName, "linear_attn" ) ) + { + m_flLinearAtten = CorrectLinearAtten( atof( szValue ) ); + } + else if ( FStrEq( szKeyName, "quadratic_attn" ) ) + { + m_flQuadraticAtten = CorrectQuadraticAtten( atof( szValue ) ); + } +#endif + else + { + return BaseClass::KeyValue( szKeyName, szValue ); + } + + return true; +} + +bool CEnvProjectedTexture::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + if ( FStrEq( szKeyName, "lightcolor" ) ) + { + Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() ); + return true; + } + else if ( FStrEq( szKeyName, "texturename" ) ) + { + Q_snprintf( szValue, iMaxLen, "%s", m_SpotlightTextureName.Get() ); + return true; + } +#ifdef MAPBASE + else if ( FStrEq( szKeyName, "constant_attn" ) ) + { + // Undo correction + Q_snprintf( szValue, iMaxLen, "%f", m_flConstantAtten *= 2.0f ); + return true; + } + else if ( FStrEq( szKeyName, "linear_attn" ) ) + { + // Undo correction + Q_snprintf( szValue, iMaxLen, "%f", m_flLinearAtten *= 0.01f ); + return true; + } + else if ( FStrEq( szKeyName, "quadratic_attn" ) ) + { + // Undo correction + Q_snprintf( szValue, iMaxLen, "%f", m_flQuadraticAtten *= 0.0001f ); + return true; + } +#endif + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); +} + +void CEnvProjectedTexture::InputTurnOn( inputdata_t &inputdata ) +{ + m_bState = true; +} + +void CEnvProjectedTexture::InputTurnOff( inputdata_t &inputdata ) +{ + m_bState = false; +} + +void CEnvProjectedTexture::InputAlwaysUpdateOn( inputdata_t &inputdata ) +{ + m_bAlwaysUpdate = true; +} + +void CEnvProjectedTexture::InputAlwaysUpdateOff( inputdata_t &inputdata ) +{ + m_bAlwaysUpdate = false; +} + +void CEnvProjectedTexture::InputSetFOV( inputdata_t &inputdata ) +{ + m_flLightFOV = inputdata.value.Float(); +#ifdef MAPBASE + m_flLightHorFOV = inputdata.value.Float(); +#endif +} + +#ifdef MAPBASE +void CEnvProjectedTexture::InputSetVerFOV( inputdata_t &inputdata ) +{ + m_flLightFOV = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetHorFOV( inputdata_t &inputdata ) +{ + m_flLightHorFOV = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetFilter( inputdata_t &inputdata ) +{ + m_flShadowFilter = inputdata.value.Float(); +} +#endif + +void CEnvProjectedTexture::InputSetTarget( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + // env_projectedtexture's "Target" uses FIELD_EHANDLE while Mapbase's base entity "SetTarget" uses FIELD_STRING + if (inputdata.value.FieldType() != FIELD_EHANDLE) + inputdata.value.Convert(FIELD_EHANDLE, this, inputdata.pActivator, inputdata.pCaller); +#endif + m_hTargetEntity = inputdata.value.Entity(); +} + +void CEnvProjectedTexture::InputSetCameraSpace( inputdata_t &inputdata ) +{ + m_bCameraSpace = inputdata.value.Bool(); +} + +void CEnvProjectedTexture::InputSetLightOnlyTarget( inputdata_t &inputdata ) +{ + m_bLightOnlyTarget = inputdata.value.Bool(); +} + +void CEnvProjectedTexture::InputSetLightWorld( inputdata_t &inputdata ) +{ + m_bLightWorld = inputdata.value.Bool(); +} + +void CEnvProjectedTexture::InputSetEnableShadows( inputdata_t &inputdata ) +{ + m_bEnableShadows = inputdata.value.Bool(); +} + +void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) +{ + m_LightColor = inputdata.value.Color32(); +} + +void CEnvProjectedTexture::InputSetAmbient( inputdata_t &inputdata ) +{ + m_flAmbient = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetSpotlightTexture( inputdata_t &inputdata ) +{ + Q_strcpy( m_SpotlightTextureName.GetForModify(), inputdata.value.String() ); +} + +#ifdef MAPBASE +void CEnvProjectedTexture::InputSetSpotlightFrame( inputdata_t &inputdata ) +{ + m_nSpotlightTextureFrame = inputdata.value.Int(); +} + +void CEnvProjectedTexture::InputSetBrightness( inputdata_t &inputdata ) +{ + m_flBrightnessScale = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetColorTransitionTime( inputdata_t &inputdata ) +{ + m_flColorTransitionTime = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetNearZ( inputdata_t &inputdata ) +{ + m_flNearZ = inputdata.value.Float(); +} + +void CEnvProjectedTexture::InputSetFarZ( inputdata_t &inputdata ) +{ + m_flFarZ = inputdata.value.Float(); +} +#endif + +#ifdef MAPBASE +void CEnvProjectedTexture::Spawn( void ) +{ + // Set m_flLightHorFOV to m_flLightFOV if it's still 0, indicating either legacy support or desire to do this + if (m_flLightHorFOV == 0.0f) + { + m_flLightHorFOV = m_flLightFOV; + } + + m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 ); + m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 ); + + BaseClass::Spawn(); +} +#endif + +void CEnvProjectedTexture::Activate( void ) +{ +#ifndef MAPBASE // Putting this in Activate() breaks projected textures which start off or don't start always updating in savegames. Moved to Spawn() instead + m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 ); + m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 ); +#endif + + SetThink( &CEnvProjectedTexture::InitialThink ); + SetNextThink( gpGlobals->curtime + 0.1f ); + +#ifdef MAPBASE + if (m_bProjectedTextureVersion == 0 && GetMoveParent()) + { + // Pre-Mapbase projected textures should use the VDC parenting fix. + m_bAlwaysUpdate = true; + } +#endif + + BaseClass::Activate(); +} + +#ifdef MAPBASE +void CEnvProjectedTexture::SetParent( CBaseEntity* pNewParent, int iAttachment ) +{ + BaseClass::SetParent( pNewParent, iAttachment ); + + if (m_bProjectedTextureVersion == 0) + { + // Pre-Mapbase projected textures should use the VDC parenting fix. + // Since the ASW changes structure projected textures differently, + // we have to set it here on the server when our parent changes. + // Don't run this code if we already have the spawnflag though. + if ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) == 0 ) + { + m_bAlwaysUpdate = GetMoveParent() != NULL; + } + } +} +#endif + +void CEnvProjectedTexture::InitialThink( void ) +{ + m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target ); +} + +int CEnvProjectedTexture::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +#else + +#define ENV_PROJECTEDTEXTURE_STARTON (1<<0) +#ifdef MAPBASE +#define ENV_PROJECTEDTEXTURE_ALWAYSUPDATE (1<<1) +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CEnvProjectedTexture : public CPointEntity +{ + DECLARE_CLASS( CEnvProjectedTexture, CPointEntity ); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CEnvProjectedTexture(); + bool KeyValue( const char *szKeyName, const char *szValue ); + + // Always transmit to clients + virtual int UpdateTransmitState(); + virtual void Activate( void ); + + void InputTurnOn( inputdata_t &inputdata ); + void InputTurnOff( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputAlwaysUpdateOn( inputdata_t &inputdata ); + void InputAlwaysUpdateOff( inputdata_t &inputdata ); +#endif + void InputSetFOV( inputdata_t &inputdata ); + void InputSetTarget( inputdata_t &inputdata ); + void InputSetCameraSpace( inputdata_t &inputdata ); + void InputSetLightOnlyTarget( inputdata_t &inputdata ); + void InputSetLightWorld( inputdata_t &inputdata ); + void InputSetEnableShadows( inputdata_t &inputdata ); +#ifndef MAPBASE +// void InputSetLightColor( inputdata_t &inputdata ); +#else + void InputSetLightColor( inputdata_t &inputdata ); +#endif + void InputSetSpotlightTexture( inputdata_t &inputdata ); + void InputSetAmbient( inputdata_t &inputdata ); + + void InitialThink( void ); + + CNetworkHandle( CBaseEntity, m_hTargetEntity ); + +private: + + CNetworkVar( bool, m_bState ); +#ifdef MAPBASE + CNetworkVar( bool, m_bAlwaysUpdate ); +#endif + CNetworkVar( float, m_flLightFOV ); + CNetworkVar( bool, m_bEnableShadows ); + CNetworkVar( bool, m_bLightOnlyTarget ); + CNetworkVar( bool, m_bLightWorld ); + CNetworkVar( bool, m_bCameraSpace ); + CNetworkVector( m_LinearFloatLightColor ); + CNetworkVar( float, m_flAmbient ); + CNetworkString( m_SpotlightTextureName, MAX_PATH ); + CNetworkVar( int, m_nSpotlightTextureFrame ); + CNetworkVar( float, m_flNearZ ); + CNetworkVar( float, m_flFarZ ); + CNetworkVar( int, m_nShadowQuality ); +}; + +LINK_ENTITY_TO_CLASS( env_projectedtexture, CEnvProjectedTexture ); BEGIN_DATADESC( CEnvProjectedTexture ) DEFINE_FIELD( m_hTargetEntity, FIELD_EHANDLE ), @@ -25,65 +544,52 @@ BEGIN_DATADESC( CEnvProjectedTexture ) DEFINE_KEYFIELD( m_bLightWorld, FIELD_BOOLEAN, "lightworld" ), DEFINE_KEYFIELD( m_bCameraSpace, FIELD_BOOLEAN, "cameraspace" ), DEFINE_KEYFIELD( m_flAmbient, FIELD_FLOAT, "ambient" ), +#ifndef MAPBASE DEFINE_AUTO_ARRAY_KEYFIELD( m_SpotlightTextureName, FIELD_CHARACTER, "texturename" ), +#else + DEFINE_AUTO_ARRAY( m_SpotlightTextureName, FIELD_CHARACTER ), +#endif DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ), DEFINE_KEYFIELD( m_flNearZ, FIELD_FLOAT, "nearz" ), DEFINE_KEYFIELD( m_flFarZ, FIELD_FLOAT, "farz" ), DEFINE_KEYFIELD( m_nShadowQuality, FIELD_INTEGER, "shadowquality" ), - DEFINE_FIELD( m_LinearFloatLightColor, FIELD_VECTOR ), - DEFINE_KEYFIELD( m_nLinear, FIELD_INTEGER, "linear" ), - DEFINE_KEYFIELD( m_nQuadratic, FIELD_INTEGER, "quadratic" ), - DEFINE_KEYFIELD( m_nConstant, FIELD_INTEGER, "constant" ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), - DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOn", InputAlwaysUpdateOn ), - DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOff", InputAlwaysUpdateOff ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOn", InputAlwaysUpdateOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOff", InputAlwaysUpdateOff ), +#endif DEFINE_INPUTFUNC( FIELD_FLOAT, "FOV", InputSetFOV ), DEFINE_INPUTFUNC( FIELD_EHANDLE, "Target", InputSetTarget ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "CameraSpace", InputSetCameraSpace ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightOnlyTarget", InputSetLightOnlyTarget ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightWorld", InputSetLightWorld ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows ), +#ifndef MAPBASE // this is broken . . need to be able to set color and intensity like light_dynamic // DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ), +#else + DEFINE_INPUTFUNC( FIELD_STRING, "LightColor", InputSetLightColor ), +#endif DEFINE_INPUTFUNC( FIELD_FLOAT, "Ambient", InputSetAmbient ), DEFINE_INPUTFUNC( FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture ), DEFINE_THINKFUNC( InitialThink ), - - DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableVolumetrics", InputSetEnableVolumetrics), - - DEFINE_KEYFIELD(m_bEnableVolumetrics, FIELD_BOOLEAN, "enablevolumetrics"), - DEFINE_KEYFIELD(m_bEnableVolumetricsLOD, FIELD_BOOLEAN, "volumetricslod"), - DEFINE_KEYFIELD(m_flVolumetricsFadeDistance, FIELD_FLOAT, "volumetricsfadedistance"), - DEFINE_KEYFIELD(m_iVolumetricsQuality, FIELD_INTEGER, "volumetricsquality"), - DEFINE_KEYFIELD(m_flVolumetricsQualityBias, FIELD_FLOAT, "volumetricsqualitybias"), - DEFINE_KEYFIELD(m_flVolumetricsMultiplier, FIELD_FLOAT, "volumetricsmultiplier"), END_DATADESC() IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture ) SendPropEHandle( SENDINFO( m_hTargetEntity ) ), SendPropBool( SENDINFO( m_bState ) ), +#ifdef MAPBASE SendPropBool( SENDINFO( m_bAlwaysUpdate ) ), +#endif SendPropFloat( SENDINFO( m_flLightFOV ) ), SendPropBool( SENDINFO( m_bEnableShadows ) ), SendPropBool( SENDINFO( m_bLightOnlyTarget ) ), SendPropBool( SENDINFO( m_bLightWorld ) ), SendPropBool( SENDINFO( m_bCameraSpace ) ), - - SendPropBool( SENDINFO(m_bEnableVolumetrics)), - SendPropBool( SENDINFO(m_bEnableVolumetricsLOD)), - SendPropFloat(SENDINFO(m_flVolumetricsFadeDistance)), - SendPropInt( SENDINFO(m_iVolumetricsQuality)), - SendPropFloat(SENDINFO(m_flVolumetricsQualityBias)), - SendPropFloat(SENDINFO(m_flVolumetricsMultiplier)), - SendPropVector( SENDINFO( m_LinearFloatLightColor ) ), - SendPropInt( SENDINFO( m_nLinear ) ), - SendPropInt( SENDINFO( m_nQuadratic ) ), - SendPropInt( SENDINFO( m_nConstant ) ), - SendPropFloat( SENDINFO( m_flAmbient ) ), SendPropString( SENDINFO( m_SpotlightTextureName ) ), SendPropInt( SENDINFO( m_nSpotlightTextureFrame ) ), @@ -104,7 +610,12 @@ CEnvProjectedTexture::CEnvProjectedTexture( void ) m_bLightWorld = true; m_bCameraSpace = false; - Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight001" ); +// if ( g_pHardwareConfig->SupportsBorderColor() ) +#if defined( _X360 ) + Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" ); +#else + Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight001" ); +#endif m_nSpotlightTextureFrame = 0; m_LinearFloatLightColor.Init( 1.0f, 1.0f, 1.0f ); @@ -136,6 +647,12 @@ bool CEnvProjectedTexture::KeyValue( const char *szKeyName, const char *szValue UTIL_ColorStringToLinearFloatColor( tmp, szValue ); m_LinearFloatLightColor = tmp; } +#ifdef MAPBASE + else if ( FStrEq(szKeyName, "texturename") ) + { + Q_strcpy(m_SpotlightTextureName.GetForModify(), szValue); + } +#endif else { return BaseClass::KeyValue( szKeyName, szValue ); @@ -154,15 +671,17 @@ void CEnvProjectedTexture::InputTurnOff( inputdata_t &inputdata ) m_bState = false; } -void CEnvProjectedTexture::InputAlwaysUpdateOn( inputdata_t& inputdata ) +#ifdef MAPBASE +void CEnvProjectedTexture::InputAlwaysUpdateOn( inputdata_t &inputdata ) { m_bAlwaysUpdate = true; } -void CEnvProjectedTexture::InputAlwaysUpdateOff( inputdata_t& inputdata ) +void CEnvProjectedTexture::InputAlwaysUpdateOff( inputdata_t &inputdata ) { m_bAlwaysUpdate = false; } +#endif void CEnvProjectedTexture::InputSetFOV( inputdata_t &inputdata ) { @@ -194,10 +713,19 @@ void CEnvProjectedTexture::InputSetEnableShadows( inputdata_t &inputdata ) m_bEnableShadows = inputdata.value.Bool(); } +#ifndef MAPBASE //void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) //{ // m_cLightColor = inputdata.value.Color32(); //} +#else +void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) +{ + Vector tmp; + UTIL_ColorStringToLinearFloatColor( tmp, inputdata.value.String() ); + m_LinearFloatLightColor = tmp; +} +#endif void CEnvProjectedTexture::InputSetAmbient( inputdata_t &inputdata ) { @@ -209,15 +737,15 @@ void CEnvProjectedTexture::InputSetSpotlightTexture( inputdata_t &inputdata ) Q_strcpy( m_SpotlightTextureName.GetForModify(), inputdata.value.String() ); } -void CEnvProjectedTexture::InputSetEnableVolumetrics(inputdata_t& inputdata) -{ - m_bEnableVolumetrics = inputdata.value.Bool(); -} - void CEnvProjectedTexture::Activate( void ) { - m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 ); + if ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) + { + m_bState = true; + } +#ifdef MAPBASE m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 ); +#endif SetThink( &CEnvProjectedTexture::InitialThink ); SetNextThink( gpGlobals->curtime + 0.1f ); @@ -227,19 +755,19 @@ void CEnvProjectedTexture::Activate( void ) void CEnvProjectedTexture::InitialThink( void ) { - //m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target ); - - if ( m_hTargetEntity == NULL && m_target != NULL_STRING ) - m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target ); - if ( m_hTargetEntity == NULL ) +#ifndef MAPBASE + m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target ); +#else + if (m_hTargetEntity == NULL && m_target != NULL_STRING) + m_hTargetEntity = gEntList.FindEntityByName(NULL, m_target); + if (m_hTargetEntity == NULL) return; - - Vector vecToTarget = ( m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin() ); + Vector vecToTarget = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()); QAngle vecAngles; - VectorAngles( vecToTarget, vecAngles ); - SetAbsAngles( vecAngles ); - - SetNextThink( gpGlobals->curtime + 0.1 ); + VectorAngles(vecToTarget, vecAngles); + SetAbsAngles(vecAngles); + SetNextThink(gpGlobals->curtime + 0.1); +#endif } int CEnvProjectedTexture::UpdateTransmitState() @@ -247,6 +775,9 @@ int CEnvProjectedTexture::UpdateTransmitState() return SetTransmitState( FL_EDICT_ALWAYS ); } +#endif + + // Console command for creating env_projectedtexture entities void CC_CreateFlashlight( const CCommand &args ) { @@ -263,13 +794,6 @@ void CC_CreateFlashlight( const CCommand &args ) pFlashlight->SetName( AllocPooledString( args[1] ) ); } - pFlashlight->m_bAlwaysUpdate = true; - pFlashlight->m_bEnableShadows = true; - pFlashlight->m_nQuadratic = 150; - pFlashlight->m_flLightFOV = 90; - pFlashlight->m_flNearZ = 4; - pFlashlight->m_flFarZ = 1500; - pFlashlight->Teleport( &origin, &angles, NULL ); } diff --git a/game/server/env_projectedtexture.h b/game/server/env_projectedtexture.h index 7ba39f66..6cb248ba 100644 --- a/game/server/env_projectedtexture.h +++ b/game/server/env_projectedtexture.h @@ -1,9 +1,3 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// #ifndef ENV_PROJECTEDTEXTURE_H #define ENV_PROJECTEDTEXTURE_H @@ -14,6 +8,7 @@ #define ENV_PROJECTEDTEXTURE_STARTON (1<<0) #define ENV_PROJECTEDTEXTURE_ALWAYSUPDATE (1<<1) +#ifdef ASW_PROJECTED_TEXTURES //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -26,61 +21,102 @@ class CEnvProjectedTexture : public CPointEntity CEnvProjectedTexture(); bool KeyValue( const char *szKeyName, const char *szValue ); - //virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); // Always transmit to clients virtual int UpdateTransmitState(); +#ifdef MAPBASE + virtual void Spawn( void ); +#endif virtual void Activate( void ); +#ifdef MAPBASE + void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 ); +#endif void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); void InputAlwaysUpdateOn( inputdata_t &inputdata ); void InputAlwaysUpdateOff( inputdata_t &inputdata ); void InputSetFOV( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetVerFOV( inputdata_t &inputdata ); + void InputSetHorFOV( inputdata_t &inputdata ); +#endif void InputSetTarget( inputdata_t &inputdata ); void InputSetCameraSpace( inputdata_t &inputdata ); void InputSetLightOnlyTarget( inputdata_t &inputdata ); void InputSetLightWorld( inputdata_t &inputdata ); void InputSetEnableShadows( inputdata_t &inputdata ); - //void InputSetLightColor( inputdata_t &inputdata ); + void InputSetLightColor( inputdata_t &inputdata ); void InputSetSpotlightTexture( inputdata_t &inputdata ); void InputSetAmbient( inputdata_t &inputdata ); - void InputSetEnableVolumetrics(inputdata_t& inputdata); +#ifdef MAPBASE + void InputSetSpotlightFrame( inputdata_t &inputdata ); + void InputSetBrightness( inputdata_t &inputdata ); + void InputSetColorTransitionTime( inputdata_t &inputdata ); + void InputSetConstant( inputdata_t &inputdata ) { m_flConstantAtten = CorrectConstantAtten(inputdata.value.Float()); } + void InputSetLinear( inputdata_t &inputdata ) { m_flLinearAtten = CorrectLinearAtten(inputdata.value.Float()); } + void InputSetQuadratic( inputdata_t &inputdata ) { m_flQuadraticAtten = CorrectQuadraticAtten(inputdata.value.Float()); } + void InputSetShadowAtten( inputdata_t &inputdata ) { m_flShadowAtten = inputdata.value.Float(); } + void InputSetNearZ( inputdata_t &inputdata ); + void InputSetFarZ( inputdata_t &inputdata ); + void InputAlwaysDrawOn( inputdata_t &inputdata ) { m_bAlwaysDraw = true; } + void InputAlwaysDrawOff( inputdata_t &inputdata ) { m_bAlwaysDraw = false; } + void InputStopFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = true; } + void InputStartFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = false; } + void InputSetFilter( inputdata_t &inputdata ); + + // Corrects keyvalue/input attenuation for internal FlashlightEffect_t attenuation. + float CorrectConstantAtten( float fl ) { return fl * 0.5f; } + float CorrectLinearAtten( float fl ) { return fl * 100.0f; } + float CorrectQuadraticAtten( float fl ) { return fl * 10000.0f; } +#endif void InitialThink( void ); CNetworkHandle( CBaseEntity, m_hTargetEntity ); +#ifdef MAPBASE + CNetworkVar( bool, m_bDontFollowTarget ); +#endif + +private: -// commented out for create flashlight for 600 years -//private: - - CNetworkVar( bool, m_bState ); - CNetworkVar( bool, m_bAlwaysUpdate ); - CNetworkVar( float, m_flLightFOV ); - CNetworkVar( bool, m_bEnableShadows ); - CNetworkVar( bool, m_bLightOnlyTarget ); - CNetworkVar( bool, m_bLightWorld ); - CNetworkVar( bool, m_bCameraSpace ); - - //CNetworkColor32( m_LightColor ); - CNetworkVector( m_LinearFloatLightColor ); - CNetworkVar( int, m_nLinear ); - CNetworkVar( int, m_nQuadratic ); - CNetworkVar( int, m_nConstant ); - - CNetworkVar( float, m_flAmbient ); - CNetworkString( m_SpotlightTextureName, MAX_PATH ); - CNetworkVar( int, m_nSpotlightTextureFrame ); - CNetworkVar( float, m_flNearZ ); - CNetworkVar( float, m_flFarZ ); - CNetworkVar( int, m_nShadowQuality ); - - CNetworkVar(bool, m_bEnableVolumetrics); - CNetworkVar(bool, m_bEnableVolumetricsLOD); - CNetworkVar(float, m_flVolumetricsFadeDistance); - CNetworkVar(int, m_iVolumetricsQuality); - CNetworkVar(float, m_flVolumetricsQualityBias); - CNetworkVar(float, m_flVolumetricsMultiplier); + CNetworkVar( bool, m_bState ); + CNetworkVar( bool, m_bAlwaysUpdate ); + CNetworkVar( float, m_flLightFOV ); +#ifdef MAPBASE + CNetworkVar( float, m_flLightHorFOV ); +#endif + CNetworkVar( bool, m_bEnableShadows ); + CNetworkVar( bool, m_bLightOnlyTarget ); + CNetworkVar( bool, m_bLightWorld ); + CNetworkVar( bool, m_bCameraSpace ); + CNetworkVar( float, m_flBrightnessScale ); + CNetworkColor32( m_LightColor ); + CNetworkVar( float, m_flColorTransitionTime ); + CNetworkVar( float, m_flAmbient ); + CNetworkString( m_SpotlightTextureName, MAX_PATH ); + CNetworkVar( int, m_nSpotlightTextureFrame ); + CNetworkVar( float, m_flNearZ ); + CNetworkVar( float, m_flFarZ ); + CNetworkVar( int, m_nShadowQuality ); +#ifdef MAPBASE + CNetworkVar( float, m_flConstantAtten ); + CNetworkVar( float, m_flLinearAtten ); + CNetworkVar( float, m_flQuadraticAtten ); + CNetworkVar( float, m_flShadowAtten ); + + CNetworkVar( float, m_flShadowFilter ); + + CNetworkVar( bool, m_bAlwaysDraw ); + + // 1 = New projected texture + // 0 = Non-Mapbase projected texture, e.g. one that uses the VDC parenting fix instead of the spawnflag + // Not needed on the client right now, change to CNetworkVar when it actually is needed + bool m_bProjectedTextureVersion; +#endif }; +#endif + #endif // ENV_PROJECTEDTEXTURE_H \ No newline at end of file diff --git a/game/server/env_screenoverlay.cpp b/game/server/env_screenoverlay.cpp index 07bbf08d..259a6fdc 100644 --- a/game/server/env_screenoverlay.cpp +++ b/game/server/env_screenoverlay.cpp @@ -39,6 +39,9 @@ class CEnvScreenOverlay : public CPointEntity CNetworkVar( float, m_flStartTime ); CNetworkVar( int, m_iDesiredOverlay ); CNetworkVar( bool, m_bIsActive ); +#ifdef MAPBASE + CNetworkVar( int, m_iOverlayIndex ); +#endif }; LINK_ENTITY_TO_CLASS( env_screenoverlay, CEnvScreenOverlay ); @@ -74,6 +77,9 @@ BEGIN_DATADESC( CEnvScreenOverlay ) DEFINE_FIELD( m_iDesiredOverlay, FIELD_INTEGER ), DEFINE_FIELD( m_flStartTime, FIELD_TIME ), DEFINE_FIELD( m_bIsActive, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iOverlayIndex, FIELD_INTEGER, "OverlayIndex" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "StartOverlays", InputStartOverlay ), DEFINE_INPUTFUNC( FIELD_VOID, "StopOverlays", InputStopOverlay ), @@ -93,6 +99,9 @@ IMPLEMENT_SERVERCLASS_ST( CEnvScreenOverlay, DT_EnvScreenOverlay ) SendPropFloat( SENDINFO( m_flStartTime ), 32, SPROP_NOSCALE ), SendPropInt( SENDINFO( m_iDesiredOverlay ), 5 ), SendPropBool( SENDINFO( m_bIsActive ) ), +#ifdef MAPBASE + SendPropInt( SENDINFO( m_iOverlayIndex ), 5 ), +#endif END_SEND_TABLE() //----------------------------------------------------------------------------- @@ -103,6 +112,9 @@ CEnvScreenOverlay::CEnvScreenOverlay( void ) m_flStartTime = 0; m_iDesiredOverlay = 0; m_bIsActive = false; +#ifdef MAPBASE + m_iOverlayIndex = -1; +#endif } //----------------------------------------------------------------------------- diff --git a/game/server/env_skydome.cpp b/game/server/env_skydome.cpp deleted file mode 100644 index ae012a85..00000000 --- a/game/server/env_skydome.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include "cbase.h" - -//------------------------------------------------------------------------------ -// Purpose : Sunlight shadow control entity -//------------------------------------------------------------------------------ -class CSkyDome : public CBaseAnimating -{ -public: - DECLARE_CLASS(CSkyDome, CBaseAnimating); - - CSkyDome() {} - - void Spawn(void); - - virtual bool KeyValue(const char *szKeyName, const char *szValue); - - virtual int UpdateTransmitState() - { - return SetTransmitState(FL_EDICT_ALWAYS); - } - - // Inputs - void InputSetSunPos(inputdata_t& inputdata); - void InputSetWindSpeed(inputdata_t& inputdata); - void InputSetThickness(inputdata_t& inputdata); - void InputSetCoverage(inputdata_t& inputdata); - - DECLARE_SERVERCLASS() - DECLARE_DATADESC(); -private: - - CNetworkVector(m_vDesiredSunPos); - CNetworkVector(m_vDesiredWindSpeed); - CNetworkVar(float, m_flDesiredThickness); - CNetworkVar(float, m_flDesiredCoverage); -}; - -//----------------------------------------------------------------------------- -// Save/load -//----------------------------------------------------------------------------- -BEGIN_DATADESC(CSkyDome) - -DEFINE_FIELD(m_vDesiredSunPos, FIELD_VECTOR), -DEFINE_FIELD(m_vDesiredWindSpeed, FIELD_VECTOR), -DEFINE_FIELD(m_flDesiredThickness, FIELD_FLOAT), -DEFINE_FIELD(m_flDesiredCoverage, FIELD_FLOAT), - -DEFINE_INPUTFUNC(FIELD_VECTOR, "SetSunPos", InputSetSunPos), -DEFINE_INPUTFUNC(FIELD_VECTOR, "SetWindSpeed", InputSetWindSpeed), -DEFINE_INPUTFUNC(FIELD_FLOAT, "InputSetThickness", InputSetThickness), -DEFINE_INPUTFUNC(FIELD_FLOAT, "InputSetCoverage", InputSetCoverage), -END_DATADESC(); - -IMPLEMENT_SERVERCLASS_ST(CSkyDome, DT_SkyDome) -SendPropVector(SENDINFO(m_vDesiredSunPos)), -SendPropVector(SENDINFO(m_vDesiredWindSpeed)), -SendPropFloat(SENDINFO(m_flDesiredThickness)), -SendPropFloat(SENDINFO(m_flDesiredCoverage)), -END_SEND_TABLE() - -void CSkyDome::Spawn() -{ - PrecacheModel("models/effects/skydome.mdl"); - SetModel("models/effects/skydome.mdl"); - - SetMoveType(MOVETYPE_NONE); - SetCollisionGroup(COLLISION_GROUP_NONE); - SetSolid(SOLID_NONE); -} - -bool CSkyDome::KeyValue(const char *szKeyName, const char *szValue) -{ - if (FStrEq(szKeyName, "thickness")) - { - m_flDesiredThickness = atof(szValue); - if(cvar->FindVar("cl_sky_thickness")) - cvar->FindVar("cl_sky_thickness")->SetValue(szValue); - return true; - } - - if (FStrEq(szKeyName, "coverage")) - { - m_flDesiredCoverage = atof(szValue); - if (cvar->FindVar("cl_sky_coverage")) - cvar->FindVar("cl_sky_coverage")->SetValue(szValue); - return true; - } - - if (FStrEq(szKeyName, "sunpos")) - { - Vector Pos; - UTIL_StringToVector(Pos.Base(), szValue); - m_vDesiredSunPos = Pos; - - if (cvar->FindVar("cl_sky_SunPos")) - cvar->FindVar("cl_sky_SunPos")->SetValue(szValue); - return true; - } - if (FStrEq(szKeyName, "windspeed")) - { - Vector Pos; - UTIL_StringToVector(Pos.Base(), szValue); - m_vDesiredWindSpeed = Pos; - - if (cvar->FindVar("cl_sky_windspeed")) - cvar->FindVar("cl_sky_windspeed")->SetValue(szValue); - return true; - } - - return true; -} - -//------------------------------------------------------------------------------ -// Input values -//------------------------------------------------------------------------------ -void CSkyDome::InputSetSunPos(inputdata_t& inputdata) -{ - const char* pPos = inputdata.value.String(); - - Vector Pos; - UTIL_StringToVector(Pos.Base(), pPos); - m_vDesiredSunPos = Pos; -} - -//------------------------------------------------------------------------------ -// Input values -//------------------------------------------------------------------------------ -void CSkyDome::InputSetWindSpeed(inputdata_t& inputdata) -{ - const char* pPos = inputdata.value.String(); - - Vector Pos; - UTIL_StringToVector(Pos.Base(), pPos); - m_vDesiredWindSpeed = Pos; -} - -//------------------------------------------------------------------------------ -// Input values -//------------------------------------------------------------------------------ -void CSkyDome::InputSetThickness(inputdata_t& inputdata) -{ - m_flDesiredThickness = inputdata.value.Float(); -} - -//------------------------------------------------------------------------------ -// Input values -//------------------------------------------------------------------------------ -void CSkyDome::InputSetCoverage(inputdata_t& inputdata) -{ - m_flDesiredCoverage = inputdata.value.Float(); -} -LINK_ENTITY_TO_CLASS(env_skydome, CSkyDome); \ No newline at end of file diff --git a/game/server/env_tonemap_controller.cpp b/game/server/env_tonemap_controller.cpp index 613d4548..95cf6135 100644 --- a/game/server/env_tonemap_controller.cpp +++ b/game/server/env_tonemap_controller.cpp @@ -5,58 +5,18 @@ //============================================================================= #include "cbase.h" +#include "env_tonemap_controller.h" #include "baseentity.h" #include "entityoutput.h" #include "convar.h" + +#include "player.h" //Tony; need player.h so we can trigger inputs on the player, from our inputs! + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" ConVar mat_hdr_tonemapscale( "mat_hdr_tonemapscale", "1.0", FCVAR_CHEAT, "The HDR tonemap scale. 1 = Use autoexposure, 0 = eyes fully closed, 16 = eyes wide open." ); -// 0 - eyes fully closed / fully black -// 1 - nominal -// 16 - eyes wide open / fully white - -//----------------------------------------------------------------------------- -// Purpose: Entity that controls player's tonemap -//----------------------------------------------------------------------------- -class CEnvTonemapController : public CPointEntity -{ - DECLARE_CLASS( CEnvTonemapController, CPointEntity ); -public: - DECLARE_DATADESC(); - DECLARE_SERVERCLASS(); - - void Spawn( void ); - int UpdateTransmitState( void ); - void UpdateTonemapScaleBlend( void ); - - // Inputs - void InputSetTonemapScale( inputdata_t &inputdata ); - void InputBlendTonemapScale( inputdata_t &inputdata ); - void InputSetTonemapRate( inputdata_t &inputdata ); - void InputSetAutoExposureMin( inputdata_t &inputdata ); - void InputSetAutoExposureMax( inputdata_t &inputdata ); - void InputUseDefaultAutoExposure( inputdata_t &inputdata ); - void InputSetBloomScale( inputdata_t &inputdata ); - void InputUseDefaultBloomScale( inputdata_t &inputdata ); - void InputSetBloomScaleRange( inputdata_t &inputdata ); - -private: - float m_flBlendTonemapStart; // HDR Tonemap at the start of the blend - float m_flBlendTonemapEnd; // Target HDR Tonemap at the end of the blend - float m_flBlendEndTime; // Time at which the blend ends - float m_flBlendStartTime; // Time at which the blend started - - CNetworkVar( bool, m_bUseCustomAutoExposureMin ); - CNetworkVar( bool, m_bUseCustomAutoExposureMax ); - CNetworkVar( bool, m_bUseCustomBloomScale ); - CNetworkVar( float, m_flCustomAutoExposureMin ); - CNetworkVar( float, m_flCustomAutoExposureMax ); - CNetworkVar( float, m_flCustomBloomScale); - CNetworkVar( float, m_flCustomBloomScaleMinimum); -}; - LINK_ENTITY_TO_CLASS( env_tonemap_controller, CEnvTonemapController ); BEGIN_DATADESC( CEnvTonemapController ) @@ -83,7 +43,11 @@ BEGIN_DATADESC( CEnvTonemapController ) DEFINE_INPUTFUNC( FIELD_VOID, "UseDefaultAutoExposure", InputUseDefaultAutoExposure ), DEFINE_INPUTFUNC( FIELD_VOID, "UseDefaultBloomScale", InputUseDefaultBloomScale ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBloomScale", InputSetBloomScale ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetBloomScaleRange", InputSetBloomScaleRange ), +#else DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBloomScaleRange", InputSetBloomScaleRange ), +#endif END_DATADESC() IMPLEMENT_SERVERCLASS_ST( CEnvTonemapController, DT_EnvTonemapController ) @@ -113,6 +77,67 @@ int CEnvTonemapController::UpdateTransmitState() return SetTransmitState( FL_EDICT_ALWAYS ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CEnvTonemapController::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "TonemapScale" ) ) + { + float flTonemapScale = atof( szValue ); + if (flTonemapScale != -1.0f) + { + mat_hdr_tonemapscale.SetValue( flTonemapScale ); + } + } + else if (FStrEq( szKeyName, "TonemapRate" )) + { + float flTonemapRate = atof( szValue ); + if (flTonemapRate != -1.0f) + { + ConVarRef mat_hdr_manual_tonemap_rate( "mat_hdr_manual_tonemap_rate" ); + if ( mat_hdr_manual_tonemap_rate.IsValid() ) + { + mat_hdr_manual_tonemap_rate.SetValue( flTonemapRate ); + } + } + } + else if (FStrEq( szKeyName, "AutoExposureMin" )) + { + float flAutoExposureMin = atof( szValue ); + if (flAutoExposureMin != -1.0f) + { + m_flCustomAutoExposureMin = flAutoExposureMin; + m_bUseCustomAutoExposureMin = true; + } + } + else if (FStrEq( szKeyName, "AutoExposureMax" )) + { + float flAutoExposureMax = atof( szValue ); + if (flAutoExposureMax != -1.0f) + { + m_flCustomAutoExposureMax = flAutoExposureMax; + m_bUseCustomAutoExposureMax = true; + } + } + else if (FStrEq( szKeyName, "BloomScale" )) + { + float flBloomScale = atof( szValue ); + if (flBloomScale != -1.0f) + { + m_flCustomBloomScale = flBloomScale; + m_flCustomBloomScaleMinimum = flBloomScale; + m_bUseCustomBloomScale = true; + } + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Set the tonemap scale to the specified value //----------------------------------------------------------------------------- @@ -162,7 +187,7 @@ void CEnvTonemapController::InputBlendTonemapScale( inputdata_t &inputdata ) void CEnvTonemapController::InputSetBloomScaleRange( inputdata_t &inputdata ) { float bloom_max=1, bloom_min=1; - int nargs=sscanf("%f %f",inputdata.value.String(), bloom_max, bloom_min ); + int nargs=sscanf( inputdata.value.String(), "%f %f", &bloom_max, &bloom_min ); if (nargs != 2) { Warning("%s (%s) received SetBloomScaleRange input without 2 arguments. Syntax: \n", GetClassname(), GetDebugName() ); @@ -170,6 +195,9 @@ void CEnvTonemapController::InputSetBloomScaleRange( inputdata_t &inputdata ) } m_flCustomBloomScale=bloom_max; m_flCustomBloomScaleMinimum=bloom_min; +#ifdef MAPBASE + m_bUseCustomBloomScale = true; +#endif } //----------------------------------------------------------------------------- @@ -247,3 +275,109 @@ void CEnvTonemapController::InputUseDefaultBloomScale( inputdata_t &inputdata ) { m_bUseCustomBloomScale = false; } + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +LINK_ENTITY_TO_CLASS( trigger_tonemap, CTonemapTrigger ); + +BEGIN_DATADESC( CTonemapTrigger ) + DEFINE_KEYFIELD( m_tonemapControllerName, FIELD_STRING, "TonemapName" ), +END_DATADESC() + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::Spawn( void ) +{ + AddSpawnFlags( SF_TRIGGER_ALLOW_CLIENTS ); + + BaseClass::Spawn(); + InitTrigger(); + + m_hTonemapController = gEntList.FindEntityByName( NULL, m_tonemapControllerName ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::StartTouch( CBaseEntity *other ) +{ + if ( !PassesTriggerFilters( other ) ) + return; + + BaseClass::StartTouch( other ); + + CBasePlayer *player = ToBasePlayer( other ); + if ( !player ) + return; + + player->OnTonemapTriggerStartTouch( this ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CTonemapTrigger::EndTouch( CBaseEntity *other ) +{ + if ( !PassesTriggerFilters( other ) ) + return; + + BaseClass::EndTouch( other ); + + CBasePlayer *player = ToBasePlayer( other ); + if ( !player ) + return; + + player->OnTonemapTriggerEndTouch( this ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Clear out the tonemap controller. +//----------------------------------------------------------------------------- +void CTonemapSystem::LevelInitPreEntity( void ) +{ + m_hMasterController = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master fog controller. If no controller is +// set as Master, use the first fog controller found. +//----------------------------------------------------------------------------- +void CTonemapSystem::LevelInitPostEntity( void ) +{ + // Overall master controller + CEnvTonemapController *pTonemapController = NULL; + do + { + pTonemapController = static_cast( gEntList.FindEntityByClassname( pTonemapController, "env_tonemap_controller" ) ); + if ( pTonemapController ) + { + if ( m_hMasterController == NULL ) + { + m_hMasterController = pTonemapController; + } + else + { + if ( pTonemapController->IsMaster() ) + { + m_hMasterController = pTonemapController; + } + } + } + } while ( pTonemapController ); + + +} + + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem s_TonemapSystem( "TonemapSystem" ); + + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem *TheTonemapSystem( void ) +{ + return &s_TonemapSystem; +} + + +//-------------------------------------------------------------------------------------------------------- +#endif diff --git a/game/server/env_tonemap_controller.h b/game/server/env_tonemap_controller.h new file mode 100644 index 00000000..94e3e0f4 --- /dev/null +++ b/game/server/env_tonemap_controller.h @@ -0,0 +1,140 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Note that this header exists in the Alien Swarm SDK, but not in stock Source SDK 2013. +// Although technically a new Mapbase file, it only serves to move otherwise identical code, +// so most code and repo conventions will pretend it was always there. +// +// -------------------------------------------------------------------- +// +// Purpose: +// +//=============================================================================// + +#ifndef ENV_TONEMAP_CONTROLLER_H +#define ENV_TONEMAP_CONTROLLER_H + +#include "triggers.h" + +// 0 - eyes fully closed / fully black +// 1 - nominal +// 16 - eyes wide open / fully white + +#ifdef MAPBASE // From Alien Swarm SDK +// Spawn Flags +#define SF_TONEMAP_MASTER 0x0001 +#endif + +//----------------------------------------------------------------------------- +// Purpose: Entity that controls player's tonemap +//----------------------------------------------------------------------------- +class CEnvTonemapController : public CPointEntity +{ + DECLARE_CLASS( CEnvTonemapController, CPointEntity ); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + void Spawn( void ); + int UpdateTransmitState( void ); + void UpdateTonemapScaleBlend( void ); + +#ifdef MAPBASE + bool IsMaster( void ) const { return HasSpawnFlags( SF_TONEMAP_MASTER ); } // From Alien Swarm SDK + + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + + // Inputs + void InputSetTonemapScale( inputdata_t &inputdata ); + void InputBlendTonemapScale( inputdata_t &inputdata ); + void InputSetTonemapRate( inputdata_t &inputdata ); + void InputSetAutoExposureMin( inputdata_t &inputdata ); + void InputSetAutoExposureMax( inputdata_t &inputdata ); + void InputUseDefaultAutoExposure( inputdata_t &inputdata ); + void InputSetBloomScale( inputdata_t &inputdata ); + void InputUseDefaultBloomScale( inputdata_t &inputdata ); + void InputSetBloomScaleRange( inputdata_t &inputdata ); + +private: + float m_flBlendTonemapStart; // HDR Tonemap at the start of the blend + float m_flBlendTonemapEnd; // Target HDR Tonemap at the end of the blend + float m_flBlendEndTime; // Time at which the blend ends + float m_flBlendStartTime; // Time at which the blend started + +#ifdef MAPBASE // From Alien Swarm SDK +public: +#endif + CNetworkVar( bool, m_bUseCustomAutoExposureMin ); + CNetworkVar( bool, m_bUseCustomAutoExposureMax ); + CNetworkVar( bool, m_bUseCustomBloomScale ); + CNetworkVar( float, m_flCustomAutoExposureMin ); + CNetworkVar( float, m_flCustomAutoExposureMax ); + CNetworkVar( float, m_flCustomBloomScale); + CNetworkVar( float, m_flCustomBloomScaleMinimum); +}; + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +class CTonemapTrigger : public CBaseTrigger +{ +public: + DECLARE_CLASS( CTonemapTrigger, CBaseTrigger ); + DECLARE_DATADESC(); + + virtual void Spawn( void ); + virtual void StartTouch( CBaseEntity *other ); + virtual void EndTouch( CBaseEntity *other ); + + CBaseEntity *GetTonemapController( void ) const; + +private: + string_t m_tonemapControllerName; + EHANDLE m_hTonemapController; +}; + + +//-------------------------------------------------------------------------------------------------------- +inline CBaseEntity *CTonemapTrigger::GetTonemapController( void ) const +{ + return m_hTonemapController.Get(); +} + + +//-------------------------------------------------------------------------------------------------------- +// Tonemap Controller System. +class CTonemapSystem : public CAutoGameSystem +{ +public: + + // Creation/Init. + CTonemapSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = NULL; + } + + ~CTonemapSystem() + { + m_hMasterController = NULL; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + CBaseEntity *GetMasterTonemapController( void ) const; + +private: + + EHANDLE m_hMasterController; +}; + + +//-------------------------------------------------------------------------------------------------------- +inline CBaseEntity *CTonemapSystem::GetMasterTonemapController( void ) const +{ + return m_hMasterController.Get(); +} + +//-------------------------------------------------------------------------------------------------------- +CTonemapSystem *TheTonemapSystem( void ); +#endif + +#endif //ENV_TONEMAP_CONTROLLER_H \ No newline at end of file diff --git a/game/server/env_zoom.cpp b/game/server/env_zoom.cpp index 2a9f8478..ec679152 100644 --- a/game/server/env_zoom.cpp +++ b/game/server/env_zoom.cpp @@ -23,6 +23,10 @@ class CEnvZoom : public CPointEntity void InputZoom( inputdata_t &inputdata ); void InputUnZoom( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputUnZoomWithRate( inputdata_t &inputdata ); + void InputSetZoomRate( inputdata_t &inputdata ); +#endif int GetFOV( void ) { return m_nFOV; } float GetSpeed( void ) { return m_flSpeed; } @@ -43,6 +47,10 @@ BEGIN_DATADESC( CEnvZoom ) DEFINE_INPUTFUNC( FIELD_VOID, "Zoom", InputZoom ), DEFINE_INPUTFUNC( FIELD_VOID, "UnZoom", InputUnZoom ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "UnZoomWithRate", InputUnZoomWithRate ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetZoomRate", InputSetZoomRate ), +#endif END_DATADESC() @@ -114,3 +122,29 @@ void CEnvZoom::InputUnZoom( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvZoom::InputUnZoomWithRate( inputdata_t &inputdata ) +{ + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + + if ( pPlayer ) + { + // Stuff the values + pPlayer->SetFOV( this, 0, m_flSpeed, m_nFOV ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvZoom::InputSetZoomRate( inputdata_t &inputdata ) +{ + m_flSpeed = inputdata.value.Float(); +} +#endif + diff --git a/game/server/envmicrophone.cpp b/game/server/envmicrophone.cpp index 9e85b0d9..23b1758c 100644 --- a/game/server/envmicrophone.cpp +++ b/game/server/envmicrophone.cpp @@ -19,6 +19,9 @@ #include "soundflags.h" #include "engine/IEngineSound.h" #include "filters.h" +#ifdef MAPBASE +#include "fmtstr.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -27,6 +30,10 @@ const float MICROPHONE_SETTLE_EPSILON = 0.005; +#ifdef MAPBASE +static ConVar sv_microphones_always_pickup_sentences( "sv_microphones_always_pickup_sentences", "0", FCVAR_NONE, "Allows env_microphones to always detect and play back sentences, regardless of their keyvalues." ); +#endif + // List of env_microphones who want to be told whenever a sound is started static CUtlVector< CHandle > s_Microphones; @@ -44,6 +51,13 @@ BEGIN_DATADESC( CEnvMicrophone ) DEFINE_KEYFIELD(m_iszListenFilter, FIELD_STRING, "ListenFilter"), DEFINE_FIELD(m_hListenFilter, FIELD_EHANDLE), DEFINE_FIELD(m_hSpeaker, FIELD_EHANDLE), +#ifdef MAPBASE + DEFINE_KEYFIELD(m_iszLandmarkName, FIELD_STRING, "landmark"), + DEFINE_FIELD(m_hLandmark, FIELD_EHANDLE), + DEFINE_KEYFIELD(m_flPitchScale, FIELD_FLOAT, "PitchScale"), + DEFINE_KEYFIELD(m_flVolumeScale, FIELD_FLOAT, "VolumeScale"), + DEFINE_KEYFIELD(m_nChannel, FIELD_INTEGER, "channel"), +#endif // DEFINE_FIELD(m_bAvoidFeedback, FIELD_BOOLEAN), // DONT SAVE DEFINE_KEYFIELD(m_iSpeakerDSPPreset, FIELD_INTEGER, "speaker_dsp_preset" ), DEFINE_KEYFIELD(m_flMaxRange, FIELD_FLOAT, "MaxRange"), @@ -52,6 +66,12 @@ BEGIN_DATADESC( CEnvMicrophone ) DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), DEFINE_INPUTFUNC(FIELD_STRING, "SetSpeakerName", InputSetSpeakerName), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_INTEGER, "SetDSPPreset", InputSetDSPPreset), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPitchScale", InputSetPitchScale ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVolumeScale", InputSetVolumeScale ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetChannel", InputSetChannel ), +#endif DEFINE_OUTPUT(m_SoundLevel, "SoundLevel"), DEFINE_OUTPUT(m_OnRoutedSound, "OnRoutedSound" ), @@ -190,6 +210,13 @@ void CEnvMicrophone::ActivateSpeaker( void ) s_Microphones.AddToTail( this ); } } + +#ifdef MAPBASE + if (m_iszLandmarkName != NULL_STRING) + { + m_hLandmark = gEntList.FindEntityByName(NULL, m_iszLandmarkName, this, NULL, NULL); + } +#endif } //----------------------------------------------------------------------------- @@ -216,7 +243,11 @@ void CEnvMicrophone::InputDisable( inputdata_t &inputdata ) m_bDisabled = true; if ( m_hSpeaker ) { +#ifdef MAPBASE + CBaseEntity::StopSound( m_hSpeaker->entindex(), m_nChannel, m_szLastSound ); +#else CBaseEntity::StopSound( m_hSpeaker->entindex(), CHAN_STATIC, m_szLastSound ); +#endif m_szLastSound[0] = 0; // Remove ourselves from the list of active mics @@ -234,6 +265,45 @@ void CEnvMicrophone::InputSetSpeakerName( inputdata_t &inputdata ) SetSpeakerName( inputdata.value.StringID() ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvMicrophone::InputSetDSPPreset( inputdata_t &inputdata ) +{ + m_iSpeakerDSPPreset = inputdata.value.Int(); + ActivateSpeaker(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvMicrophone::InputSetPitchScale( inputdata_t &inputdata ) +{ + m_flPitchScale = inputdata.value.Float(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvMicrophone::InputSetVolumeScale( inputdata_t &inputdata ) +{ + m_flVolumeScale = inputdata.value.Float(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvMicrophone::InputSetChannel( inputdata_t &inputdata ) +{ + m_nChannel = inputdata.value.Int(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Checks whether this microphone can hear a given sound, and at what // relative volume level. @@ -473,6 +543,21 @@ MicrophoneResult_t CEnvMicrophone::SoundPlayed( int entindex, const char *soundn } } +#ifdef MAPBASE + // Something similar to trigger_teleport landmarks for sounds transmitting to speaker + Vector vecOrigin = m_hSpeaker->GetAbsOrigin(); + if (m_hLandmark) + { + Vector vecSoundPos; + if (pOrigin) + vecSoundPos = *pOrigin; + else if (CBaseEntity *pEntity = CBaseEntity::Instance(engine->PEntityOfEntIndex(entindex))) + vecSoundPos = pEntity->GetAbsOrigin(); + + vecOrigin += (vecSoundPos - m_hLandmark->GetAbsOrigin()); + } +#endif + m_bAvoidFeedback = true; // Add the speaker flag. Detected at playback and applies the speaker filter. @@ -480,17 +565,41 @@ MicrophoneResult_t CEnvMicrophone::SoundPlayed( int entindex, const char *soundn CPASAttenuationFilter filter( m_hSpeaker ); EmitSound_t ep; - ep.m_nChannel = CHAN_STATIC; - ep.m_pSoundName = soundname; - ep.m_flVolume = flVolume; - ep.m_SoundLevel = soundlevel; - ep.m_nFlags = iFlags; - ep.m_nPitch = iPitch; - ep.m_pOrigin = &m_hSpeaker->GetAbsOrigin(); - ep.m_flSoundTime = soundtime; - ep.m_nSpeakerEntity = entindex; - - CBaseEntity::EmitSound( filter, m_hSpeaker->entindex(), ep ); + +#ifdef MAPBASE + if (m_bHearingSentence) + { + CBaseEntity::EmitSentenceByIndex( filter, m_hSpeaker->entindex(), m_nChannel, atoi(soundname), flVolume, soundlevel, 0, iPitch, &vecOrigin, NULL, true, soundtime, + m_iSpeakerDSPPreset, entindex ); + } + else +#endif + { +#ifdef MAPBASE + ep.m_nChannel = m_nChannel; + if (m_flVolumeScale != 1.0f) + ep.m_flVolume = (flVolume * m_flVolumeScale); + else + ep.m_flVolume = flVolume; + if (m_flPitchScale != 1.0f) + ep.m_nPitch = (int)((float)iPitch * m_flPitchScale); + else + ep.m_nPitch = iPitch; + ep.m_pOrigin = &vecOrigin; +#else + ep.m_nChannel = CHAN_STATIC; + ep.m_flVolume = flVolume; + ep.m_nPitch = iPitch; + ep.m_pOrigin = &m_hSpeaker->GetAbsOrigin(); +#endif + ep.m_pSoundName = soundname; + ep.m_SoundLevel = soundlevel; + ep.m_nFlags = iFlags; + ep.m_flSoundTime = soundtime; + ep.m_nSpeakerEntity = entindex; + + CBaseEntity::EmitSound( filter, m_hSpeaker->entindex(), ep ); + } Q_strncpy( m_szLastSound, soundname, sizeof(m_szLastSound) ); m_OnRoutedSound.FireOutput( this, this, 0 ); @@ -558,3 +667,56 @@ bool CEnvMicrophone::OnSoundPlayed( int entindex, const char *soundname, soundle return bSwallowed; } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Called by the sound system whenever a sentence is played so that +// active microphones can have a chance to pick up the sound. +// Output : Returns whether or not the sentence was swallowed by the microphone. +// Swallowed sentences should not be played by the sound system. +//----------------------------------------------------------------------------- +bool CEnvMicrophone::OnSentencePlayed( int entindex, int sentenceIndex, soundlevel_t soundlevel, float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins ) +{ + bool bSwallowed = false; + + // Loop through all registered microphones and tell them the sound was just played + int iCount = s_Microphones.Count(); + if ( iCount > 0 ) + { + CNumStr szSentenceStr( sentenceIndex ); + + // Iterate backwards because we might be deleting microphones. + for ( int i = iCount - 1; i >= 0; i-- ) + { + if ( s_Microphones[i] && (s_Microphones[i]->ShouldHearSentences() || sv_microphones_always_pickup_sentences.GetBool()) ) + { + // HACKHACK: Don't want to duplicate all of the code, so just use the same function with a new member variable + s_Microphones[i]->ToggleHearingSentence( true ); + MicrophoneResult_t eResult = s_Microphones[i]->SoundPlayed( + entindex, + szSentenceStr, + soundlevel, + flVolume, + iFlags, + iPitch, + pOrigin, + soundtime, + soundorigins ); + s_Microphones[i]->ToggleHearingSentence( false ); + + if ( eResult == MicrophoneResult_Swallow ) + { + // Microphone told us to swallow it + bSwallowed = true; + } + else if ( eResult == MicrophoneResult_Remove ) + { + s_Microphones.FastRemove( i ); + } + } + } + } + + return bSwallowed; +} +#endif diff --git a/game/server/envmicrophone.h b/game/server/envmicrophone.h index 1cad0761..e330099c 100644 --- a/game/server/envmicrophone.h +++ b/game/server/envmicrophone.h @@ -20,6 +20,9 @@ const int SF_MICROPHONE_SOUND_BULLET_IMPACT = 0x08; const int SF_MICROPHONE_SWALLOW_ROUTED_SOUNDS = 0x10; const int SF_MICROPHONE_SOUND_EXPLOSION = 0x20; const int SF_MICROPHONE_IGNORE_NONATTENUATED = 0x40; +#ifdef MAPBASE +const int SF_MICROPHONE_SOUND_SENTENCE = 0x80; +#endif // Return codes from SoundPlayed @@ -50,10 +53,20 @@ class CEnvMicrophone : public CPointEntity void SetSensitivity( float flSensitivity ); void SetSpeakerName( string_t iszSpeakerName ); +#ifdef MAPBASE + bool ShouldHearSentences() const { return HasSpawnFlags( SF_MICROPHONE_SOUND_SENTENCE ); } + inline void ToggleHearingSentence( bool bToggle ) { m_bHearingSentence = bToggle; } +#endif void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); void InputSetSpeakerName( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetDSPPreset( inputdata_t &inputdata ); + void InputSetPitchScale( inputdata_t &inputdata ); + void InputSetVolumeScale( inputdata_t &inputdata ); + void InputSetChannel( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); @@ -61,6 +74,12 @@ class CEnvMicrophone : public CPointEntity static bool OnSoundPlayed( int entindex, const char *soundname, soundlevel_t soundlevel, float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins ); +#ifdef MAPBASE + // Same as above, except for sentences. + static bool OnSentencePlayed( int entindex, int sentenceIndex, soundlevel_t soundlevel, + float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins ); +#endif + private: // Per-microphone notification that a sound has played. @@ -79,6 +98,15 @@ class CEnvMicrophone : public CPointEntity int m_iSpeakerDSPPreset; // Speaker DSP preset to use when this microphone is enabled string_t m_iszListenFilter; CHandle m_hListenFilter; +#ifdef MAPBASE + string_t m_iszLandmarkName; + EHANDLE m_hLandmark; + float m_flPitchScale = 1.0f; + float m_flVolumeScale = 1.0f; + int m_nChannel = CHAN_STATIC; + + bool m_bHearingSentence; // HACKHACK: Allows SoundPlayed() to know when to play a sentence instead +#endif COutputFloat m_SoundLevel; // Fired when the sampled volume level changes. COutputEvent m_OnRoutedSound; // Fired when a sound has been played through our speaker diff --git a/game/server/episodic/ai_behavior_alyx_injured.cpp b/game/server/episodic/ai_behavior_alyx_injured.cpp index a762587d..1d056387 100644 --- a/game/server/episodic/ai_behavior_alyx_injured.cpp +++ b/game/server/episodic/ai_behavior_alyx_injured.cpp @@ -479,16 +479,16 @@ void CAI_BehaviorAlyxInjured::GatherConditions( void ) //----------------------------------------------------------------------------- // Purpose: Speak a concept if we're able to //----------------------------------------------------------------------------- -void CAI_BehaviorAlyxInjured::SpeakIfAllowed( AIConcept_t concept ) +void CAI_BehaviorAlyxInjured::SpeakIfAllowed( AIConcept_t conceptId ) { CAI_Expresser *pExpresser = GetOuter()->GetExpresser(); if ( pExpresser == NULL ) return; // Must be able to speak the concept - if ( pExpresser->CanSpeakConcept( concept ) ) + if ( pExpresser->CanSpeakConcept( conceptId ) ) { - pExpresser->Speak( concept ); + pExpresser->Speak( conceptId ); } } diff --git a/game/server/episodic/ai_behavior_alyx_injured.h b/game/server/episodic/ai_behavior_alyx_injured.h index 2eb1ff19..b50e9f07 100644 --- a/game/server/episodic/ai_behavior_alyx_injured.h +++ b/game/server/episodic/ai_behavior_alyx_injured.h @@ -75,7 +75,7 @@ class CAI_BehaviorAlyxInjured : public CAI_FollowBehavior private: - void SpeakIfAllowed( AIConcept_t concept ); + void SpeakIfAllowed( AIConcept_t conceptId ); bool ShouldRunToCover( void ); bool ShouldRunToFollowGoal( void ); bool FindThreatDirection2D( const Vector &vecSource, Vector *vecOut ); diff --git a/game/server/episodic/ai_behavior_passenger_companion.cpp b/game/server/episodic/ai_behavior_passenger_companion.cpp index f96c2a55..a9568c69 100644 --- a/game/server/episodic/ai_behavior_passenger_companion.cpp +++ b/game/server/episodic/ai_behavior_passenger_companion.cpp @@ -530,7 +530,11 @@ void CAI_PassengerBehaviorCompanion::GatherConditions( void ) AIEnemiesIter_t iter; for( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) ) { +#ifdef MAPBASE + if( GetOuter()->IRelationType( pEMemory->hEnemy ) <= D_FR ) +#else if( GetOuter()->IRelationType( pEMemory->hEnemy ) == D_HT ) +#endif { if( pEMemory->timeLastSeen == gpGlobals->curtime ) { diff --git a/game/server/episodic/ep2_gamestats.h b/game/server/episodic/ep2_gamestats.h index cef1f839..cc36301c 100644 --- a/game/server/episodic/ep2_gamestats.h +++ b/game/server/episodic/ep2_gamestats.h @@ -215,7 +215,7 @@ struct Ep2LevelStats_t { Ep2LevelStats_t::EntityDeathsLump_t data; char npcName[ 512 ]; - LoadBuffer.GetString( npcName ); + LoadBuffer.GetString( npcName, sizeof( npcName ) ); LoadBuffer.Get( &data, sizeof( data ) ); pItem->m_dictEntityDeaths.Insert( npcName, data ); } @@ -229,7 +229,7 @@ struct Ep2LevelStats_t { Ep2LevelStats_t::WeaponLump_t data; char weaponName[ 512 ]; - LoadBuffer.GetString( weaponName ); + LoadBuffer.GetString( weaponName, sizeof( weaponName ) ); LoadBuffer.Get( &data, sizeof( data ) ); pItem->m_dictWeapons.Insert( weaponName, data ); } @@ -240,7 +240,7 @@ struct Ep2LevelStats_t Assert( pItem ); Ep2LevelStats_t::SaveGameInfo_t *info = &pItem->m_SaveGameInfo; char sz[ 512 ]; - LoadBuffer.GetString( sz ); + LoadBuffer.GetString( sz, sizeof( sz ) ); info->m_sCurrentSaveFile = sz; info->m_nCurrentSaveFileTime = LoadBuffer.GetInt(); int c = LoadBuffer.GetInt(); @@ -277,7 +277,7 @@ struct Ep2LevelStats_t { Ep2LevelStats_t::GenericStatsLump_t data; char pchStatName[ 512 ]; - LoadBuffer.GetString( pchStatName ); + LoadBuffer.GetString( pchStatName, sizeof( pchStatName ) ); LoadBuffer.Get( &data, sizeof( data ) ); pItem->m_dictGeneric.Insert( pchStatName, data ); } diff --git a/game/server/episodic/npc_hunter.cpp b/game/server/episodic/npc_hunter.cpp index 4bab75cc..d551374f 100644 --- a/game/server/episodic/npc_hunter.cpp +++ b/game/server/episodic/npc_hunter.cpp @@ -63,6 +63,9 @@ #include "weapon_striderbuster.h" #include "monstermaker.h" #include "weapon_rpg.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -201,11 +204,19 @@ int g_interactionHunterFoundEnemy = 0; //----------------------------------------------------------------------------- // Local stuff. //----------------------------------------------------------------------------- +#ifdef MAPBASE +#define s_iszStriderClassname gm_isz_class_Strider +#define s_iszPhysPropClassname gm_isz_class_PropPhysics +static string_t s_iszStriderBusterClassname; +static string_t s_iszMagnadeClassname; +static string_t s_iszHuntersToRunOver; +#else static string_t s_iszStriderClassname; static string_t s_iszStriderBusterClassname; static string_t s_iszMagnadeClassname; static string_t s_iszPhysPropClassname; static string_t s_iszHuntersToRunOver; +#endif //----------------------------------------------------------------------------- @@ -1378,6 +1389,10 @@ class CNPC_Hunter : public CAI_BaseActor string_t m_iszFollowTarget; // Name of the strider we should follow. CSimpleStopwatch m_BeginFollowDelay; +#ifdef MAPBASE + bool m_bNoIdlePatrol; +#endif + int m_nKillingDamageType; HunterEyeStates_t m_eEyeState; @@ -1480,6 +1495,10 @@ BEGIN_DATADESC( CNPC_Hunter ) DEFINE_KEYFIELD( m_iszFollowTarget, FIELD_STRING, "FollowTarget" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bNoIdlePatrol, FIELD_BOOLEAN, "NoIdlePatrol" ), +#endif + DEFINE_FIELD( m_aimYaw, FIELD_FLOAT ), DEFINE_FIELD( m_aimPitch, FIELD_FLOAT ), @@ -1617,8 +1636,16 @@ CNPC_Hunter::~CNPC_Hunter() //----------------------------------------------------------------------------- void CNPC_Hunter::Precache() { +#ifdef MAPBASE + if (GetModelName() == NULL_STRING) + SetModelName( AllocPooledString( "models/hunter.mdl" ) ); + + PrecacheModel( STRING( GetModelName() ) ); + PropBreakablePrecacheAll( GetModelName() ); +#else PrecacheModel( "models/hunter.mdl" ); PropBreakablePrecacheAll( MAKE_STRING("models/hunter.mdl") ); +#endif PrecacheScriptSound( "NPC_Hunter.Idle" ); PrecacheScriptSound( "NPC_Hunter.Scan" ); @@ -1679,7 +1706,11 @@ void CNPC_Hunter::Spawn() { Precache(); +#ifdef MAPBASE + SetModel( STRING( GetModelName() ) ); +#else SetModel( "models/hunter.mdl" ); +#endif BaseClass::Spawn(); //m_debugOverlays |= OVERLAY_NPC_ROUTE_BIT | OVERLAY_BBOX_BIT | OVERLAY_PIVOT_BIT; @@ -1915,11 +1946,17 @@ void CNPC_Hunter::Activate() { BaseClass::Activate(); +#ifdef MAPBASE + s_iszStriderBusterClassname = AllocPooledString( "weapon_striderbuster" ); + s_iszMagnadeClassname = AllocPooledString( "npc_grenade_magna" ); + s_iszHuntersToRunOver = AllocPooledString( "hunters_to_run_over" ); +#else s_iszStriderBusterClassname = AllocPooledString( "weapon_striderbuster" ); s_iszStriderClassname = AllocPooledString( "npc_strider" ); s_iszMagnadeClassname = AllocPooledString( "npc_grenade_magna" ); s_iszPhysPropClassname = AllocPooledString( "prop_physics" ); s_iszHuntersToRunOver = AllocPooledString( "hunters_to_run_over" ); +#endif // If no one has initialized the hunters to run over counter, just zero it out. if ( !GlobalEntity_IsInTable( s_iszHuntersToRunOver ) ) @@ -3048,6 +3085,9 @@ int CNPC_Hunter::SelectSchedule() { case NPC_STATE_IDLE: { +#ifdef MAPBASE + if (!m_bNoIdlePatrol) +#endif return SCHED_HUNTER_PATROL; } @@ -3429,7 +3469,13 @@ void CNPC_Hunter::StartTask( const Task_t *pTask ) { SetLastAttackTime( gpGlobals->curtime ); +#ifdef MAPBASE + // The "VS_PLAYER" animation looks better than the regular animation when used against non-humans + if ( GetEnemy() && (GetEnemy()->IsPlayer() || + (GetEnemy()->IsCombatCharacter() && GetEnemy()->MyCombatCharacterPointer()->GetHullType() != HULL_HUMAN)) ) +#else if ( GetEnemy() && GetEnemy()->IsPlayer() ) +#endif { ResetIdealActivity( ( Activity )ACT_HUNTER_MELEE_ATTACK1_VS_PLAYER ); } @@ -4031,7 +4077,11 @@ bool CNPC_Hunter::HandleChargeImpact( Vector vecImpact, CBaseEntity *pEntity ) } // Hit anything we don't like +#ifdef MAPBASE + if ( IRelationType( pEntity ) <= D_FR && ( GetNextAttack() < gpGlobals->curtime ) ) +#else if ( IRelationType( pEntity ) == D_HT && ( GetNextAttack() < gpGlobals->curtime ) ) +#endif { EmitSound( "NPC_Hunter.ChargeHitEnemy" ); @@ -4313,7 +4363,11 @@ void CNPC_Hunter::HandleAnimEvent( animevent_t *pEvent ) //----------------------------------------------------------------------------- void CNPC_Hunter::AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ) { +#ifdef MAPBASE + if ( nDisposition == D_HT && pEntity->ClassMatches(gm_isz_class_Bullseye) ) +#else if ( nDisposition == D_HT && pEntity->ClassMatches("npc_bullseye") ) +#endif UpdateEnemyMemory( pEntity, pEntity->GetAbsOrigin() ); BaseClass::AddEntityRelationship( pEntity, nDisposition, nPriority ); } @@ -4948,7 +5002,11 @@ int CNPC_Hunter::RangeAttack2Conditions( float flDot, float flDist ) { return COND_TOO_FAR_TO_ATTACK; } +#ifdef MAPBASE + else if ( !bIsBuster && ( !GetEnemy() || !GetEnemy()->ClassMatches( gm_isz_class_Bullseye ) ) && flDist < hunter_flechette_min_range.GetFloat() ) +#else else if ( !bIsBuster && ( !GetEnemy() || !GetEnemy()->ClassMatches( "npc_bullseye" ) ) && flDist < hunter_flechette_min_range.GetFloat() ) +#endif { return COND_TOO_CLOSE_TO_ATTACK; } @@ -5553,6 +5611,40 @@ int CNPC_Hunter::OnTakeDamage( const CTakeDamageInfo &info ) } } } +#ifdef MAPBASE + else if (info.GetDamageType() == DMG_CLUB && + info.GetInflictor() && info.GetInflictor()->IsNPC()) + { + // If the *inflictor* is a NPC doing club damage, it's most likely an antlion guard or even another hunter charging us. + // Add DMG_CRUSH so we ragdoll immediately if we die. + myInfo.AddDamageType( DMG_CRUSH ); + } + + + // "So, do you know what the alternative fire method does on the AR2? It kills hunters. How did--" + // "No, only Freeman's does it!" + // "What do you mean 'Only Freeman's does it'?" + // "Only energy balls fired by the player can dissolve hunters. Energy balls fired by NPCs only do a metered amount of damage." + // "...Huh. Well, in that case, we'll just use rocket launchers." + // + // That instructor was straight-up lying to those rebels, but now he's telling the truth. + // Hunters die to NPC balls instantly and act like it was a player ball. + // Implementation is sketchy, but it was the best I could do. + if (myInfo.GetDamageType() & DMG_DISSOLVE && + info.GetAttacker() && info.GetAttacker()->IsNPC() && + info.GetInflictor() && info.GetInflictor()->ClassMatches("prop_combine_ball")) + { + // We divide by the ally damage scale to counter its usage in OnTakeDamage_Alive. + myInfo.SetDamage( (float)GetMaxHealth() / sk_hunter_citizen_damage_scale.GetFloat() ); + + myInfo.AddDamageType( DMG_CRUSH ); + //myInfo.SetDamagePosition( info.GetInflictor()->GetAbsOrigin() ); + //myInfo.SetDamageForce( info.GetInflictor()->GetAbsVelocity() ); + + // Make the NPC's ball explode + info.GetInflictor()->AcceptInput( "Explode", this, this, variant_t(), 0 ); + } +#endif return BaseClass::OnTakeDamage( myInfo ); } diff --git a/game/server/episodic/npc_hunter.h b/game/server/episodic/npc_hunter.h index 95ab29c0..fe98495e 100644 --- a/game/server/episodic/npc_hunter.h +++ b/game/server/episodic/npc_hunter.h @@ -11,20 +11,12 @@ #pragma once #endif #include "props.h" -class CBaseEntity; - -/// true if given entity pointer is a hunter. -bool Hunter_IsHunter(CBaseEntity *pEnt); - -// call throughs for member functions -void Hunter_StriderBusterAttached( CBaseEntity *pHunter, CBaseEntity *pAttached ); -void Hunter_StriderBusterDetached( CBaseEntity *pHunter, CBaseEntity *pAttached ); -void Hunter_StriderBusterLaunched( CBaseEntity *pBuster ); +class CBaseEntity; class CHunterFlechette : public CPhysicsProp, public IParentPropInteraction { - DECLARE_CLASS(CHunterFlechette, CPhysicsProp); + DECLARE_CLASS( CHunterFlechette, CPhysicsProp ); public: @@ -32,7 +24,7 @@ class CHunterFlechette : public CPhysicsProp, public IParentPropInteraction ~CHunterFlechette(); Class_T Classify() { return CLASS_NONE; } - + bool WasThrownBack() { return m_bThrownBack; @@ -43,24 +35,24 @@ class CHunterFlechette : public CPhysicsProp, public IParentPropInteraction void Spawn(); void Activate(); void Precache(); - void Shoot(Vector& vecVelocity, bool bBright); - void SetSeekTarget(CBaseEntity* pTargetEntity); + void Shoot( Vector &vecVelocity, bool bBright ); + void SetSeekTarget( CBaseEntity *pTargetEntity ); void Explode(); bool CreateVPhysics(); unsigned int PhysicsSolidMaskForEntity() const; - static CHunterFlechette* FlechetteCreate(const Vector& vecOrigin, const QAngle& angAngles, CBaseEntity* pentOwner = NULL); + static CHunterFlechette *FlechetteCreate( const Vector &vecOrigin, const QAngle &angAngles, CBaseEntity *pentOwner = NULL ); // IParentPropInteraction - void OnParentCollisionInteraction(parentCollisionInteraction_t eType, int index, gamevcollisionevent_t* pEvent); - void OnParentPhysGunDrop(CBasePlayer* pPhysGunUser, PhysGunDrop_t Reason); + void OnParentCollisionInteraction( parentCollisionInteraction_t eType, int index, gamevcollisionevent_t *pEvent ); + void OnParentPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ); protected: void SetupGlobalModelData(); - void StickTo(CBaseEntity* pOther, trace_t& tr); + void StickTo( CBaseEntity *pOther, trace_t &tr ); void BubbleThink(); void DangerSoundThink(); @@ -68,9 +60,9 @@ class CHunterFlechette : public CPhysicsProp, public IParentPropInteraction void DopplerThink(); void SeekThink(); - bool CreateSprites(bool bBright); + bool CreateSprites( bool bBright ); - void FlechetteTouch(CBaseEntity* pOther); + void FlechetteTouch( CBaseEntity *pOther ); Vector m_vecShootPosition; EHANDLE m_hSeekTarget; @@ -80,4 +72,13 @@ class CHunterFlechette : public CPhysicsProp, public IParentPropInteraction //DECLARE_SERVERCLASS(); }; +/// true if given entity pointer is a hunter. +bool Hunter_IsHunter(CBaseEntity *pEnt); + +// call throughs for member functions + +void Hunter_StriderBusterAttached( CBaseEntity *pHunter, CBaseEntity *pAttached ); +void Hunter_StriderBusterDetached( CBaseEntity *pHunter, CBaseEntity *pAttached ); +void Hunter_StriderBusterLaunched( CBaseEntity *pBuster ); + #endif diff --git a/game/server/episodic/npc_magnusson.cpp b/game/server/episodic/npc_magnusson.cpp index 31008353..30e1f697 100644 --- a/game/server/episodic/npc_magnusson.cpp +++ b/game/server/episodic/npc_magnusson.cpp @@ -37,6 +37,11 @@ class CNPC_Magnusson : public CAI_BaseActor Class_T Classify ( void ); void HandleAnimEvent( animevent_t *pEvent ); int GetSoundInterests ( void ); + +#ifdef MAPBASE + // Use Magnusson's default subtitle color (209,178,178) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 209; params.g1 = 178; params.b1 = 178; return BaseClass::GetGameTextSpeechParams( params ); } +#endif }; LINK_ENTITY_TO_CLASS( npc_magnusson, CNPC_Magnusson ); diff --git a/game/server/episodic/vehicle_jeep_episodic.cpp b/game/server/episodic/vehicle_jeep_episodic.cpp index 368f1b9f..69bb4c3f 100644 --- a/game/server/episodic/vehicle_jeep_episodic.cpp +++ b/game/server/episodic/vehicle_jeep_episodic.cpp @@ -328,6 +328,9 @@ BEGIN_DATADESC( CPropJeepEpisodic ) DEFINE_ARRAY( m_hHazardLights, FIELD_EHANDLE, NUM_HAZARD_LIGHTS ), DEFINE_FIELD( m_flCargoStartTime, FIELD_TIME ), DEFINE_FIELD( m_bBlink, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bNoHazardLights, FIELD_BOOLEAN, "NoHazardLights" ), +#endif DEFINE_FIELD( m_bRadarEnabled, FIELD_BOOLEAN ), DEFINE_FIELD( m_bRadarDetectsEnemies, FIELD_BOOLEAN ), DEFINE_FIELD( m_hRadarScreen, FIELD_EHANDLE ), @@ -357,13 +360,20 @@ BEGIN_DATADESC( CPropJeepEpisodic ) DEFINE_INPUTFUNC( FIELD_VOID, "EnableRadarDetectEnemies", InputEnableRadarDetectEnemies ), DEFINE_INPUTFUNC( FIELD_VOID, "AddBusterToCargo", InputAddBusterToCargo ), DEFINE_INPUTFUNC( FIELD_VOID, "OutsideTransition", InputOutsideTransition ), +#ifndef MAPBASE DEFINE_INPUTFUNC( FIELD_VOID, "DisablePhysGun", InputDisablePhysGun ), DEFINE_INPUTFUNC( FIELD_VOID, "EnablePhysGun", InputEnablePhysGun ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "CreateLinkController", InputCreateLinkController ), DEFINE_INPUTFUNC( FIELD_VOID, "DestroyLinkController", InputDestroyLinkController ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetCargoHopperVisibility", InputSetCargoVisibility ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "EnableHazardLights", InputEnableHazardLights ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableHazardLights", InputDisableHazardLights ), +#endif + END_DATADESC(); IMPLEMENT_SERVERCLASS_ST(CPropJeepEpisodic, DT_CPropJeepEpisodic) @@ -1354,6 +1364,11 @@ void CPropJeepEpisodic::DriveVehicle( float flFrameTime, CUserCmd *ucmd, int iBu //----------------------------------------------------------------------------- void CPropJeepEpisodic::CreateHazardLights( void ) { +#ifdef MAPBASE + if (m_bNoHazardLights) + return; +#endif + static const char *s_szAttach[NUM_HAZARD_LIGHTS] = { "rearlight_r", @@ -1412,6 +1427,26 @@ void CPropJeepEpisodic::DestroyHazardLights( void ) SetContextThink( NULL, gpGlobals->curtime, "HazardBlink" ); } +#ifdef MAPBASE +void CPropJeepEpisodic::InputEnableHazardLights( inputdata_t &data ) +{ + if (m_bNoHazardLights) + { + m_bNoHazardLights = false; + CreateHazardLights(); + } +} + +void CPropJeepEpisodic::InputDisableHazardLights( inputdata_t &data ) +{ + if (!m_bNoHazardLights) + { + m_bNoHazardLights = true; + DestroyHazardLights(); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : nRole - @@ -1664,6 +1699,7 @@ void CPropJeepEpisodic::InputOutsideTransition( inputdata_t &inputdata ) Warning("No valid vehicle teleport points!\n"); } +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: Stop players punting the car around. //----------------------------------------------------------------------------- @@ -1678,6 +1714,7 @@ void CPropJeepEpisodic::InputEnablePhysGun( inputdata_t &data ) { RemoveEFlags( EFL_NO_PHYSCANNON_INTERACTION ); } +#endif //----------------------------------------------------------------------------- // Create and parent two radial node link controllers. diff --git a/game/server/episodic/vehicle_jeep_episodic.h b/game/server/episodic/vehicle_jeep_episodic.h index 70cb5894..869cf33a 100644 --- a/game/server/episodic/vehicle_jeep_episodic.h +++ b/game/server/episodic/vehicle_jeep_episodic.h @@ -104,9 +104,15 @@ class CPropJeepEpisodic : public CPropJeep void InputEnableRadarDetectEnemies( inputdata_t &data ); void InputAddBusterToCargo( inputdata_t &data ); void InputSetCargoVisibility( inputdata_t &data ); +#ifdef MAPBASE + void InputEnableHazardLights( inputdata_t &data ); + void InputDisableHazardLights( inputdata_t &data ); +#endif void InputOutsideTransition( inputdata_t &data ); +#ifndef MAPBASE void InputDisablePhysGun( inputdata_t &data ); void InputEnablePhysGun( inputdata_t &data ); +#endif void InputCreateLinkController( inputdata_t &data ); void InputDestroyLinkController( inputdata_t &data ); void CreateAvoidanceZone( void ); @@ -116,6 +122,10 @@ class CPropJeepEpisodic : public CPropJeep bool m_bAddingCargo; bool m_bBlink; +#ifdef MAPBASE + bool m_bNoHazardLights; +#endif + float m_flCargoStartTime; // Time when the cargo was first added to the vehicle (used for animating into hold) float m_flNextAvoidBroadcastTime; // Next time we'll warn entity to move out of us diff --git a/game/server/eventqueue.h b/game/server/eventqueue.h index 1c7f030e..d5cc2d5f 100644 --- a/game/server/eventqueue.h +++ b/game/server/eventqueue.h @@ -40,9 +40,14 @@ class CEventQueue { public: // pushes an event into the queue, targeting a string name (m_iName), or directly by a pointer - void AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); +#ifdef MAPBASE_VSCRIPT + int AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); + int AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); +#else + void AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); + void AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); +#endif void AddEvent( CBaseEntity *target, const char *action, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); - void AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 ); void CancelEvents( CBaseEntity *pCaller ); void CancelEventOn( CBaseEntity *pTarget, const char *sInputName ); @@ -66,6 +71,12 @@ class CEventQueue void Dump( void ); +#ifdef MAPBASE_VSCRIPT + void CancelEventsByInput( CBaseEntity *pTarget, const char *szInput ); + bool RemoveEvent( int event ); + float GetTimeLeft( int event ); +#endif // MAPBASE_VSCRIPT + private: void AddEvent( EventQueuePrioritizedEvent_t *event ); diff --git a/game/server/explode.cpp b/game/server/explode.cpp index 42d8df35..d9031dd4 100644 --- a/game/server/explode.cpp +++ b/game/server/explode.cpp @@ -17,6 +17,10 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +ConVar explosion_sparks("explosion_sparks", "0", FCVAR_NONE); +#endif + //----------------------------------------------------------------------------- // Purpose: Spark shower, created by the explosion entity. //----------------------------------------------------------------------------- @@ -111,6 +115,9 @@ class CEnvExplosion : public CPointEntity // Input handlers void InputExplode( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetIgnoredEntity( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); @@ -150,6 +157,9 @@ BEGIN_DATADESC( CEnvExplosion ) // Inputs DEFINE_INPUTFUNC(FIELD_VOID, "Explode", InputExplode), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_EHANDLE, "SetIgnoredEntity", InputSetIgnoredEntity), +#endif END_DATADESC() @@ -352,7 +362,11 @@ void CEnvExplosion::InputExplode( inputdata_t &inputdata ) SetNextThink( gpGlobals->curtime + 0.3 ); // Only do these effects if we're not submerged +#ifdef MAPBASE + if ( explosion_sparks.GetBool() && !(UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER) ) +#else if ( UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER ) +#endif { // draw sparks if ( !( m_spawnflags & SF_ENVEXPLOSION_NOSPARKS ) ) @@ -369,6 +383,16 @@ void CEnvExplosion::InputExplode( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for setting the ignored entity. +//----------------------------------------------------------------------------- +void CEnvExplosion::InputSetIgnoredEntity( inputdata_t &inputdata ) +{ + m_hEntityIgnore = inputdata.value.Entity(); +} +#endif + void CEnvExplosion::Smoke( void ) { @@ -388,7 +412,7 @@ void ExplosionCreate( const Vector ¢er, const QAngle &angles, CEnvExplosion *pExplosion = (CEnvExplosion*)CBaseEntity::Create( "env_explosion", center, angles, pOwner ); Q_snprintf( buf,sizeof(buf), "%3d", magnitude ); - char *szKeyName = "iMagnitude"; + const char *szKeyName = "iMagnitude"; char *szValue = buf; pExplosion->KeyValue( szKeyName, szValue ); diff --git a/game/server/filters.cpp b/game/server/filters.cpp index 6179254d..c15f8eee 100644 --- a/game/server/filters.cpp +++ b/game/server/filters.cpp @@ -9,6 +9,12 @@ #include "entitylist.h" #include "ai_squad.h" #include "ai_basenpc.h" +#ifdef MAPBASE +#include "mapbase/matchers.h" +#include "AI_Criteria.h" +#include "ai_hint.h" +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -21,9 +27,16 @@ LINK_ENTITY_TO_CLASS(filter_base, CBaseFilter); BEGIN_DATADESC( CBaseFilter ) DEFINE_KEYFIELD(m_bNegated, FIELD_BOOLEAN, "Negated"), +#ifdef MAPBASE + DEFINE_KEYFIELD(m_bPassCallerWhenTested, FIELD_BOOLEAN, "PassCallerWhenTested"), +#endif // Inputs DEFINE_INPUTFUNC( FIELD_INPUT, "TestActivator", InputTestActivator ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "TestEntity", InputTestEntity ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetField", InputSetField ), +#endif // Outputs DEFINE_OUTPUT( m_OnPass, "OnPass"), @@ -31,6 +44,18 @@ BEGIN_DATADESC( CBaseFilter ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CBaseFilter, CBaseEntity, "All entities which could be used as filters." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptPassesFilter, "PassesFilter", "Check if the given caller and entity pass the filter. The caller is the one who requests the filter result; For example, the entity being damaged when using this as a damage filter." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptPassesDamageFilter, "PassesDamageFilter", "Check if the given caller and damage info pass the damage filter, with the second parameter being a CTakeDamageInfo instance. The caller is the one who requests the filter result; For example, the entity being damaged when using this as a damage filter." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptPassesFinalDamageFilter, "PassesFinalDamageFilter", "Used by filter_damage_redirect to distinguish between standalone filter calls and actually damaging an entity. Returns true if there's no unique behavior. Parameters are identical to PassesDamageFilter." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptBloodAllowed, "BloodAllowed", "Check if the given caller and damage info allow for the production of blood." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptDamageMod, "DamageMod", "Mods the damage info with the given caller." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- bool CBaseFilter::PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) @@ -46,17 +71,37 @@ bool CBaseFilter::PassesFilter( CBaseEntity *pCaller, CBaseEntity *pEntity ) } +#ifdef MAPBASE +bool CBaseFilter::PassesDamageFilter(CBaseEntity *pCaller, const CTakeDamageInfo &info) +{ + bool baseResult = PassesDamageFilterImpl(pCaller, info); + return (m_bNegated) ? !baseResult : baseResult; +} +#endif + bool CBaseFilter::PassesDamageFilter(const CTakeDamageInfo &info) { +#ifdef MAPBASE + Warning("WARNING: Deprecated usage of PassesDamageFilter!\n"); + bool baseResult = PassesDamageFilterImpl(NULL, info); +#else bool baseResult = PassesDamageFilterImpl(info); +#endif return (m_bNegated) ? !baseResult : baseResult; } +#ifdef MAPBASE +bool CBaseFilter::PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) +{ + return PassesFilterImpl( pCaller, info.GetAttacker() ); +} +#else bool CBaseFilter::PassesDamageFilterImpl( const CTakeDamageInfo &info ) { return PassesFilterImpl( NULL, info.GetAttacker() ); } +#endif //----------------------------------------------------------------------------- // Purpose: Input handler for testing the activator. If the activator passes the @@ -66,14 +111,63 @@ void CBaseFilter::InputTestActivator( inputdata_t &inputdata ) { if ( PassesFilter( inputdata.pCaller, inputdata.pActivator ) ) { +#ifdef MAPBASE + m_OnPass.FireOutput( inputdata.pActivator, m_bPassCallerWhenTested ? inputdata.pCaller : this ); +#else m_OnPass.FireOutput( inputdata.pActivator, this ); +#endif } else { +#ifdef MAPBASE + m_OnFail.FireOutput( inputdata.pActivator, m_bPassCallerWhenTested ? inputdata.pCaller : this ); +#else m_OnFail.FireOutput( inputdata.pActivator, this ); +#endif + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for testing the activator. If the activator passes the +// filter test, the OnPass output is fired. If not, the OnFail output is fired. +//----------------------------------------------------------------------------- +void CBaseFilter::InputTestEntity( inputdata_t &inputdata ) +{ + if ( !inputdata.value.Entity() ) + { + // HACKHACK: Not firing OnFail in this case is intentional for the time being (activator shouldn't be null) + return; + } + + if ( PassesFilter( inputdata.pCaller, inputdata.value.Entity() ) ) + { + m_OnPass.FireOutput( inputdata.value.Entity(), m_bPassCallerWhenTested ? inputdata.pCaller : this ); + } + else + { + m_OnFail.FireOutput( inputdata.value.Entity(), m_bPassCallerWhenTested ? inputdata.pCaller : this ); } } +//----------------------------------------------------------------------------- +// Purpose: Tries to set the filter's target since most filters use "filtername" anyway +//----------------------------------------------------------------------------- +void CBaseFilter::InputSetField( inputdata_t& inputdata ) +{ + KeyValue("filtername", inputdata.value.String()); + Activate(); +} +#endif + +#ifdef MAPBASE_VSCRIPT +bool CBaseFilter::ScriptPassesFilter( HSCRIPT pCaller, HSCRIPT pEntity ) { return PassesFilter( ToEnt(pCaller), ToEnt(pEntity) ); } +bool CBaseFilter::ScriptPassesDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? PassesDamageFilter( ToEnt( pCaller ), *const_cast(HScriptToClass( pInfo )) ) : NULL; } +bool CBaseFilter::ScriptPassesFinalDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? PassesFinalDamageFilter( ToEnt( pCaller ), *const_cast(HScriptToClass( pInfo )) ) : NULL; } +bool CBaseFilter::ScriptBloodAllowed( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? BloodAllowed( ToEnt( pCaller ), *const_cast(HScriptToClass( pInfo )) ) : NULL; } +bool CBaseFilter::ScriptDamageMod( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? DamageMod( ToEnt( pCaller ), *HScriptToClass( pInfo ) ) : NULL; } +#endif + // ################################################################### // > FilterMultiple @@ -97,8 +191,18 @@ class CFilterMultiple : public CBaseFilter EHANDLE m_hFilter[MAX_FILTERS]; bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ); +#ifdef MAPBASE + bool PassesDamageFilterImpl(CBaseEntity *pCaller, const CTakeDamageInfo &info); +#else bool PassesDamageFilterImpl(const CTakeDamageInfo &info); +#endif void Activate(void); + +#ifdef MAPBASE + bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ); + bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ); + bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ); +#endif }; LINK_ENTITY_TO_CLASS(filter_multi, CFilterMultiple); @@ -145,6 +249,13 @@ void CFilterMultiple::Activate( void ) Warning("filter_multi: Tried to add entity (%s) which is not a filter entity!\n", STRING( m_iFilterName[i] ) ); continue; } +#ifdef MAPBASE + else if ( pFilter == this ) + { + Warning("filter_multi: Tried to add itself!\n"); + continue; + } +#endif // Take this entity and increment out array pointer m_hFilter[nNextFilter] = pFilter; @@ -198,7 +309,11 @@ bool CFilterMultiple::PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEnti // Purpose: Returns true if the entity passes our filter, false if not. // Input : pEntity - Entity to test. //----------------------------------------------------------------------------- +#ifdef MAPBASE +bool CFilterMultiple::PassesDamageFilterImpl(CBaseEntity *pCaller, const CTakeDamageInfo &info) +#else bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info) +#endif { // Test against each filter if (m_nFilterType == FILTER_AND) @@ -208,7 +323,11 @@ bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info) if (m_hFilter[i] != NULL) { CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get()); +#ifdef MAPBASE + if (!pFilter->PassesDamageFilter(pCaller, info)) +#else if (!pFilter->PassesDamageFilter(info)) +#endif { return false; } @@ -223,7 +342,129 @@ bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info) if (m_hFilter[i] != NULL) { CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get()); +#ifdef MAPBASE + if (pFilter->PassesDamageFilter(pCaller, info)) +#else if (pFilter->PassesDamageFilter(info)) +#endif + { + return true; + } + } + } + return false; + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Returns true if blood should be allowed, false if not. +// Input : pEntity - Entity to test. +//----------------------------------------------------------------------------- +bool CFilterMultiple::BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) +{ + // Test against each filter + if (m_nFilterType == FILTER_AND) + { + for (int i=0;iBloodAllowed(pCaller, info)) + { + return false; + } + } + } + return true; + } + else // m_nFilterType == FILTER_OR + { + for (int i=0;iBloodAllowed(pCaller, info)) + { + return true; + } + } + } + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the entity passes our filter, false if not. +// Input : pEntity - Entity to test. +//----------------------------------------------------------------------------- +bool CFilterMultiple::PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) +{ + // Test against each filter + if (m_nFilterType == FILTER_AND) + { + for (int i=0;iPassesFinalDamageFilter(pCaller, info)) + { + return false; + } + } + } + return true; + } + else // m_nFilterType == FILTER_OR + { + for (int i=0;iPassesFinalDamageFilter(pCaller, info)) + { + return true; + } + } + } + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if damage should be modded, false if not. +// Input : pEntity - Entity to test. +//----------------------------------------------------------------------------- +bool CFilterMultiple::DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ) +{ + // Test against each filter + if (m_nFilterType == FILTER_AND) + { + for (int i=0;iDamageMod(pCaller, info)) + { + return false; + } + } + } + return true; + } + else // m_nFilterType == FILTER_OR + { + for (int i=0;iDamageMod(pCaller, info)) { return true; } @@ -232,6 +473,7 @@ bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info) return false; } } +#endif // ################################################################### @@ -257,6 +499,14 @@ class CFilterName : public CBaseFilter return pEntity->NameMatches( STRING(m_iFilterName) ); } } + +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterName = inputdata.value.StringID(); + } +#endif }; LINK_ENTITY_TO_CLASS( filter_activator_name, CFilterName ); @@ -285,6 +535,14 @@ class CFilterClass : public CBaseFilter { return pEntity->ClassMatches( STRING(m_iFilterClass) ); } + +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterClass = inputdata.value.StringID(); + } +#endif }; LINK_ENTITY_TO_CLASS( filter_activator_class, CFilterClass ); @@ -312,6 +570,14 @@ class FilterTeam : public CBaseFilter { return ( pEntity->GetTeamNumber() == m_iFilterTeam ); } + +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_INTEGER); + m_iFilterTeam = inputdata.value.Int(); + } +#endif }; LINK_ENTITY_TO_CLASS( filter_activator_team, FilterTeam ); @@ -342,6 +608,14 @@ class CFilterMassGreater : public CBaseFilter return ( pEntity->VPhysicsGetObject()->GetMass() > m_fFilterMass ); } + +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_FLOAT); + m_fFilterMass = inputdata.value.Float(); + } +#endif }; LINK_ENTITY_TO_CLASS( filter_activator_mass_greater, CFilterMassGreater ); @@ -370,12 +644,58 @@ class FilterDamageType : public CBaseFilter return true; } +#ifdef MAPBASE + bool PassesDamageFilterImpl(CBaseEntity *pCaller, const CTakeDamageInfo &info) +#else bool PassesDamageFilterImpl(const CTakeDamageInfo &info) +#endif { +#ifdef MAPBASE + switch (m_iFilterType) + { + case 1: return (info.GetDamageType() & m_iDamageType) != 0; + case 2: + { + int iRecvDT = info.GetDamageType(); + int iOurDT = m_iDamageType; + while (iRecvDT) + { + if (iRecvDT & iOurDT) + return true; + + iRecvDT >>= 1; iOurDT >>= 1; + } + return false; + } break; + } +#endif return info.GetDamageType() == m_iDamageType; } +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_INTEGER); + m_iDamageType = inputdata.value.Int(); + } + + bool KeyValue( const char *szKeyName, const char *szValue ) + { + if (FStrEq( szKeyName, "damageor" ) || FStrEq( szKeyName, "damagepresets" )) + { + m_iDamageType |= atoi( szValue ); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; + } +#endif + int m_iDamageType; +#ifdef MAPBASE + int m_iFilterType; +#endif }; LINK_ENTITY_TO_CLASS( filter_damage_type, FilterDamageType ); @@ -384,6 +704,9 @@ BEGIN_DATADESC( FilterDamageType ) // Keyfields DEFINE_KEYFIELD( m_iDamageType, FIELD_INTEGER, "damagetype" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iFilterType, FIELD_INTEGER, "FilterType" ), +#endif END_DATADESC() @@ -403,7 +726,19 @@ class CFilterEnemy : public CBaseFilter public: virtual bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ); - virtual bool PassesDamageFilterImpl( const CTakeDamageInfo &info ); +#ifdef MAPBASE + virtual bool PassesDamageFilterImpl(CBaseEntity *pCaller, const CTakeDamageInfo &info); +#else + virtual bool PassesDamageFilterImpl(const CTakeDamageInfo &info); +#endif + +#ifdef MAPBASE + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iszEnemyName = inputdata.value.StringID(); + } +#endif private: @@ -415,7 +750,9 @@ class CFilterEnemy : public CBaseFilter float m_flRadius; // Radius (enemies are acquired at this range) float m_flOuterRadius; // Outer radius (enemies are LOST at this range) int m_nMaxSquadmatesPerEnemy; // Maximum number of squadmates who may share the same enemy +#ifndef MAPBASE string_t m_iszPlayerName; // "!player" +#endif }; //----------------------------------------------------------------------------- @@ -452,7 +789,11 @@ bool CFilterEnemy::PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- +#ifdef MAPBASE +bool CFilterEnemy::PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) +#else bool CFilterEnemy::PassesDamageFilterImpl( const CTakeDamageInfo &info ) +#endif { // NOTE: This function has no meaning to this implementation of the filter class! Assert( 0 ); @@ -470,6 +811,9 @@ bool CFilterEnemy::PassesNameFilter( CBaseEntity *pEnemy ) if ( m_iszEnemyName == NULL_STRING ) return true; +#ifdef MAPBASE + if ( m_iszEnemyName == gm_isz_name_player ) +#else // Cache off the special case player name if ( m_iszPlayerName == NULL_STRING ) { @@ -477,6 +821,7 @@ bool CFilterEnemy::PassesNameFilter( CBaseEntity *pEnemy ) } if ( m_iszEnemyName == m_iszPlayerName ) +#endif { if ( pEnemy->IsPlayer() ) { @@ -488,7 +833,11 @@ bool CFilterEnemy::PassesNameFilter( CBaseEntity *pEnemy ) } // May be either a targetname or classname +#ifdef MAPBASE + bool bNameOrClassnameMatches = ( pEnemy->NameMatches(STRING(m_iszEnemyName)) || pEnemy->ClassMatches(STRING(m_iszEnemyName)) ); +#else bool bNameOrClassnameMatches = ( m_iszEnemyName == pEnemy->GetEntityName() || m_iszEnemyName == pEnemy->m_iClassname ); +#endif // We only leave this code block in a state meaning we've "succeeded" in any context if ( m_bNegated ) @@ -626,6 +975,1353 @@ BEGIN_DATADESC( CFilterEnemy ) DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "filter_radius" ), DEFINE_KEYFIELD( m_flOuterRadius, FIELD_FLOAT, "filter_outer_radius" ), DEFINE_KEYFIELD( m_nMaxSquadmatesPerEnemy, FIELD_INTEGER, "filter_max_per_enemy" ), +#ifndef MAPBASE DEFINE_FIELD( m_iszPlayerName, FIELD_STRING ), +#endif + +END_DATADESC() + +#ifdef MAPBASE +// ################################################################### +// > CFilterModel +// ################################################################### +class CFilterModel : public CBaseFilter +{ + DECLARE_CLASS( CFilterModel, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iFilterModel; + string_t m_strFilterSkin; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (FStrEq(STRING(m_strFilterSkin), "-1") /*m_strFilterSkin == NULL_STRING|| FStrEq(STRING(m_strFilterSkin), "")*/) + return Matcher_NamesMatch(STRING(m_iFilterModel), STRING(pEntity->GetModelName())); + else if (pEntity->GetBaseAnimating()) + { + //DevMsg("Skin isn't null\n"); + return Matcher_NamesMatch(STRING(m_iFilterModel), STRING(pEntity->GetModelName())) && Matcher_Match(STRING(m_strFilterSkin), pEntity->GetBaseAnimating()->m_nSkin); + } + return false; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterModel = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_model, CFilterModel ); + +BEGIN_DATADESC( CFilterModel ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterModel, FIELD_STRING, "filtermodel" ), + DEFINE_KEYFIELD( m_iFilterModel, FIELD_STRING, "filtername" ), + DEFINE_KEYFIELD( m_strFilterSkin, FIELD_STRING, "skin" ), + +END_DATADESC() + +// ################################################################### +// > CFilterContext +// ################################################################### +class CFilterContext : public CBaseFilter +{ + DECLARE_CLASS( CFilterContext, CBaseFilter ); + DECLARE_DATADESC(); + +public: + bool m_bAny; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + bool passes = false; + ResponseContext_t curcontext; + const char *contextvalue; + for (int i = 0; i < GetContextCount(); i++) + { + curcontext = m_ResponseContexts[i]; + if (!pEntity->HasContext(STRING(curcontext.m_iszName), NULL)) + { + if (m_bAny) + continue; + else + return false; + } + + contextvalue = pEntity->GetContextValue(STRING(curcontext.m_iszName)); + if (Matcher_NamesMatch(STRING(m_ResponseContexts[i].m_iszValue), contextvalue)) + { + passes = true; + if (m_bAny) + break; + } + else if (!m_bAny) + { + return false; + } + } + + return passes; + } + + void InputSetField( inputdata_t& inputdata ) + { + m_ResponseContexts.RemoveAll(); + AddContext(inputdata.value.String()); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_context, CFilterContext ); + +BEGIN_DATADESC( CFilterContext ) + + // Keyfields + DEFINE_KEYFIELD( m_bAny, FIELD_BOOLEAN, "any" ), END_DATADESC() + +// ################################################################### +// > CFilterSquad +// ################################################################### +class CFilterSquad : public CBaseFilter +{ + DECLARE_CLASS( CFilterSquad, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iFilterName; + bool m_bAllowSilentSquadMembers; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); + if (pEntity && pNPC) + { + if (pNPC->GetSquad() && Matcher_NamesMatch(STRING(m_iFilterName), pNPC->GetSquad()->GetName())) + { + if (CAI_Squad::IsSilentMember(pNPC)) + { + return m_bAllowSilentSquadMembers; + } + else + { + return true; + } + } + } + + return false; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterName = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_squad, CFilterSquad ); + +BEGIN_DATADESC( CFilterSquad ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterName, FIELD_STRING, "filtername" ), + DEFINE_KEYFIELD( m_bAllowSilentSquadMembers, FIELD_BOOLEAN, "allowsilentmembers" ), + +END_DATADESC() + +// ################################################################### +// > CFilterHintGroup +// ################################################################### +class CFilterHintGroup : public CBaseFilter +{ + DECLARE_CLASS( CFilterHintGroup, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iFilterName; + ThreeState_t m_fHintLimiting; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (!pEntity) + return false; + + if (CAI_BaseNPC *pNPC = pEntity->MyNPCPointer()) + { + if (pNPC->GetHintGroup() == NULL_STRING || Matcher_NamesMatch(STRING(m_iFilterName), STRING(pNPC->GetHintGroup()))) + { + switch (m_fHintLimiting) + { + case TRS_FALSE: return !pNPC->IsLimitingHintGroups(); break; + case TRS_TRUE: return pNPC->IsLimitingHintGroups(); break; + } + + return true; + } + } + else if (CAI_Hint *pHint = dynamic_cast(pEntity)) + { + // Just in case someone somehow puts a hint node through a filter. + // Maybe they'd use a point_advanced_finder or something, I dunno. + return Matcher_NamesMatch(STRING(m_iFilterName), STRING(pHint->GetGroup())); + } + + return false; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterName = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_hintgroup, CFilterHintGroup ); + +BEGIN_DATADESC( CFilterHintGroup ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterName, FIELD_STRING, "filtername" ), + DEFINE_KEYFIELD( m_fHintLimiting, FIELD_INTEGER, "hintlimiting" ), + +END_DATADESC() + +extern bool ReadUnregisteredKeyfields(CBaseEntity *pTarget, const char *szKeyName, variant_t *variant); + +// ################################################################### +// > CFilterKeyfield +// ################################################################### +class CFilterKeyfield : public CBaseFilter +{ + DECLARE_CLASS( CFilterKeyfield, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iFilterKey; + string_t m_iFilterValue; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + variant_t var; + bool found = (pEntity->ReadKeyField(STRING(m_iFilterKey), &var) || ReadUnregisteredKeyfields(pEntity, STRING(m_iFilterKey), &var)); + return m_iFilterValue != NULL_STRING ? Matcher_Match(STRING(m_iFilterValue), var.String()) : found; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterKey = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_keyfield, CFilterKeyfield ); + +BEGIN_DATADESC( CFilterKeyfield ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterKey, FIELD_STRING, "keyname" ), + DEFINE_KEYFIELD( m_iFilterValue, FIELD_STRING, "value" ), + +END_DATADESC() + +// ################################################################### +// > CFilterRelationship +// ################################################################### +class CFilterRelationship : public CBaseFilter +{ + DECLARE_CLASS( CFilterKeyfield, CBaseFilter ); + DECLARE_DATADESC(); + +public: + Disposition_t m_iDisposition; + string_t m_iszPriority; // string_t to support matchers + bool m_bInvertTarget; + bool m_bReciprocal; + EHANDLE m_hTarget; + + bool RelationshipPasses(CBaseCombatCharacter *pBCC, CBaseEntity *pTarget) + { + if (!pBCC || !pTarget) + return m_iDisposition == D_NU; + + Disposition_t disposition = pBCC->IRelationType(pTarget); + int priority = pBCC->IRelationPriority(pTarget); + + bool passes = (disposition == m_iDisposition); + if (!passes) + return false; + + if (m_iszPriority != NULL_STRING) + { + passes = Matcher_Match(STRING(m_iszPriority), priority); + } + + return passes; + } + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + CBaseEntity *pSubject = NULL; + if (m_target != NULL_STRING) + { + if (!m_hTarget) + { + m_hTarget = gEntList.FindEntityGeneric(NULL, STRING(m_target), pCaller, pEntity, pCaller); + } + pSubject = m_hTarget; + } + + if (!pSubject) + pSubject = pCaller; + + // No subject or entity, cannot continue + if (!pSubject || !pEntity) + return m_iDisposition == D_NU; + + CBaseCombatCharacter *pBCC1 = !m_bInvertTarget ? pSubject->MyCombatCharacterPointer() : pEntity->MyCombatCharacterPointer(); + CBaseEntity *pTarget = m_bInvertTarget ? pSubject : pEntity; + if (!pBCC1) + { + //Warning("Error: %s subject %s is not a character that uses relationships!\n", GetDebugName(), !m_bInvertTarget ? pSubject->GetDebugName() : pEntity->GetDebugName()); + return m_iDisposition == D_NU; + } + + bool passes = RelationshipPasses(pBCC1, pTarget); + if (m_bReciprocal) + passes = RelationshipPasses(pTarget->MyCombatCharacterPointer(), pBCC1); + + return passes; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_target = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_relationship, CFilterRelationship ); + +BEGIN_DATADESC( CFilterRelationship ) + + // Keyfields + DEFINE_KEYFIELD( m_iDisposition, FIELD_INTEGER, "disposition" ), + DEFINE_KEYFIELD( m_iszPriority, FIELD_STRING, "rank" ), + DEFINE_KEYFIELD( m_bInvertTarget, FIELD_BOOLEAN, "inverttarget" ), + DEFINE_KEYFIELD( m_bReciprocal, FIELD_BOOLEAN, "Reciprocal" ), + DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), + +END_DATADESC() + +// ################################################################### +// > CFilterClassify +// ################################################################### +class CFilterClassify : public CBaseFilter +{ + DECLARE_CLASS( CFilterClassify, CBaseFilter ); + DECLARE_DATADESC(); + +public: + Class_T m_iFilterClassify; + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + return pEntity->Classify() == m_iFilterClassify; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_INTEGER); + m_iFilterClassify = (Class_T)inputdata.value.Int(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_classify, CFilterClassify ); + +BEGIN_DATADESC( CFilterClassify ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterClassify, FIELD_INTEGER, "filterclassify" ), + +END_DATADESC() + +// ################################################################### +// > CFilterCriteria +// ################################################################### +class CFilterCriteria : public CBaseFilter +{ + DECLARE_CLASS( CFilterCriteria, CBaseFilter ); + DECLARE_DATADESC(); + +public: + bool m_bAny; + bool m_bFull; // All criteria functions are gathered + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (!pEntity) + return false; + + AI_CriteriaSet set; + pEntity->ModifyOrAppendCriteria( set ); + if (m_bFull) + { + // Meeets the full wrath of the response criteria + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + + pEntity->ReAppendContextCriteria( set ); + } + + bool passes = false; + const char *contextname; + const char *contextvalue; + const char *matchingvalue; + for (int i = 0; i < set.GetCount(); i++) + { + contextname = set.GetName(i); + contextvalue = set.GetValue(i); + + matchingvalue = GetContextValue(contextname); + if (matchingvalue == NULL) + { + if (m_bAny) + continue; + else + return false; + } + else + { + if (Matcher_NamesMatch(matchingvalue, contextvalue)) + { + passes = true; + if (m_bAny) + break; + } + else if (!m_bAny) + { + return false; + } + } + } + + return passes; + } + + void InputSetField( inputdata_t& inputdata ) + { + m_ResponseContexts.RemoveAll(); + AddContext(inputdata.value.String()); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_criteria, CFilterCriteria ); + +BEGIN_DATADESC( CFilterCriteria ) + + // Keyfields + DEFINE_KEYFIELD( m_bAny, FIELD_BOOLEAN, "any" ), + DEFINE_KEYFIELD( m_bFull, FIELD_BOOLEAN, "full" ), + +END_DATADESC() + +extern bool TestEntityTriggerIntersection_Accurate( CBaseEntity *pTrigger, CBaseEntity *pEntity ); + +// ################################################################### +// > CFilterInVolume +// Passes when the entity is within the specified volume. +// ################################################################### +class CFilterInVolume : public CBaseFilter +{ + DECLARE_CLASS( CFilterInVolume, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iszVolumeTester; + + void Spawn() + { + BaseClass::Spawn(); + + // Assume no string = use activator + if (m_iszVolumeTester == NULL_STRING) + m_iszVolumeTester = AllocPooledString("!activator"); + } + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + CBaseEntity *pVolume = gEntList.FindEntityByNameNearest(STRING(m_target), pEntity->GetLocalOrigin(), 0, this, pEntity, pCaller); + if (!pVolume) + { + Msg("%s cannot find volume %s\n", GetDebugName(), STRING(m_target)); + return false; + } + + CBaseEntity *pTarget = gEntList.FindEntityByName(NULL, STRING(m_iszVolumeTester), this, pEntity, pCaller); + if (pTarget) + return TestEntityTriggerIntersection_Accurate(pVolume, pTarget); + else + { + Msg("%s cannot find target entity %s, returning false\n", GetDebugName(), STRING(m_iszVolumeTester)); + return false; + } + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iszVolumeTester = inputdata.value.StringID(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_involume, CFilterInVolume ); + +BEGIN_DATADESC( CFilterInVolume ) + + // Keyfields + DEFINE_KEYFIELD( m_iszVolumeTester, FIELD_STRING, "tester" ), + +END_DATADESC() + +// ################################################################### +// > CFilterSurfaceProp +// ################################################################### +class CFilterSurfaceData : public CBaseFilter +{ + DECLARE_CLASS( CFilterSurfaceData, CBaseFilter ); + DECLARE_DATADESC(); + +public: + string_t m_iFilterSurface; + int m_iSurfaceIndex; + + enum + { + SURFACETYPE_SURFACEPROP, + SURFACETYPE_GAMEMATERIAL, + }; + + // Gets the surfaceprop's game material and filters by that. + int m_iSurfaceType; + + void ParseSurfaceIndex() + { + m_iSurfaceIndex = physprops->GetSurfaceIndex(STRING(m_iFilterSurface)); + + switch (m_iSurfaceType) + { + case SURFACETYPE_GAMEMATERIAL: + { + const surfacedata_t *pSurfaceData = physprops->GetSurfaceData(m_iSurfaceIndex); + if (pSurfaceData) + m_iSurfaceIndex = pSurfaceData->game.material; + else + Warning("Can't get surface data for %s\n", STRING(m_iFilterSurface)); + } break; + } + } + + void Activate() + { + BaseClass::Activate(); + ParseSurfaceIndex(); + } + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (pEntity->VPhysicsGetObject()) + { + int iMatIndex = pEntity->VPhysicsGetObject()->GetMaterialIndex(); + switch (m_iSurfaceType) + { + case SURFACETYPE_GAMEMATERIAL: + { + const surfacedata_t *pSurfaceData = physprops->GetSurfaceData(iMatIndex); + if (pSurfaceData) + return m_iSurfaceIndex == pSurfaceData->game.material; + } + default: + return iMatIndex == m_iSurfaceIndex; + } + } + + return false; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + m_iFilterSurface = inputdata.value.StringID(); + ParseSurfaceIndex(); + } +}; + +LINK_ENTITY_TO_CLASS( filter_activator_surfacedata, CFilterSurfaceData ); + +BEGIN_DATADESC( CFilterSurfaceData ) + + // Keyfields + DEFINE_KEYFIELD( m_iFilterSurface, FIELD_STRING, "filterstring" ), + DEFINE_KEYFIELD( m_iSurfaceType, FIELD_INTEGER, "SurfaceType" ), + +END_DATADESC() + +// =================================================================== +// Redirect filters +// +// Redirects certain data to a specific filter. +// =================================================================== +class CBaseFilterRedirect : public CBaseFilter +{ + DECLARE_CLASS( CBaseFilterRedirect, CBaseFilter ); + +public: + inline CBaseEntity *GetTargetFilter() + { + // Yes, this hijacks damage filter functionality. + // It's not like it was using it before anyway. + return m_hDamageFilter.Get(); + } + + bool RedirectToFilter( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (GetTargetFilter() && pEntity) + { + CBaseFilter *pFilter = static_cast(GetTargetFilter()); + return pFilter->PassesFilter(pCaller, pEntity); + } + + return pEntity != NULL; + } + + bool RedirectToDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (GetTargetFilter()) + { + CBaseFilter *pFilter = static_cast(GetTargetFilter()); + return pFilter->PassesDamageFilter(pCaller, info); + } + + return true; + } + + virtual bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + return RedirectToDamageFilter( pCaller, info ); + } + + virtual bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + return RedirectToFilter( pCaller, pEntity ); + } + + virtual bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (GetTargetFilter()) + { + CBaseFilter *pFilter = static_cast(GetTargetFilter()); + return pFilter->BloodAllowed(pCaller, info); + } + + return true; + } + + virtual bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ) + { + if (GetTargetFilter()) + { + CBaseFilter *pFilter = static_cast(GetTargetFilter()); + return pFilter->DamageMod( pCaller, info ); + } + + return true; + } + + void InputSetField( inputdata_t& inputdata ) + { + inputdata.value.Convert(FIELD_STRING); + InputSetDamageFilter(inputdata); + } + + enum + { + REDIRECT_MUST_PASS_TO_DAMAGE_CALLER, // Must pass to damage caller, if damage is allowed + REDIRECT_MUST_PASS_TO_ACT, // Must pass to do action + REDIRECT_MUST_PASS_ACTIVATORS, // Each activator must pass this filter + }; +}; + +// ################################################################### +// > CFilterRedirectInflictor +// Uses the specified filter to filter by damage inflictor. +// ################################################################### +class CFilterRedirectInflictor : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterRedirectInflictor, CBaseFilterRedirect ); + +public: + bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + return RedirectToFilter(pCaller, info.GetInflictor()); + } +}; + +LINK_ENTITY_TO_CLASS( filter_redirect_inflictor, CFilterRedirectInflictor ); + +// ################################################################### +// > CFilterRedirectWeapon +// Uses the specified filter to filter by either the entity's active weapon or the weapon causing damage, +// depending on the context. +// ################################################################### +class CFilterRedirectWeapon : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterRedirectWeapon, CBaseFilterRedirect ); + +public: + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + CBaseCombatCharacter *pBCC = pEntity->MyCombatCharacterPointer(); + if (pBCC && pBCC->GetActiveWeapon()) + { + return RedirectToFilter( pCaller, pBCC->GetActiveWeapon() ); + } + + return false; + } + + bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + // Pass any weapon found in the damage info + if (info.GetWeapon()) + { + return RedirectToFilter( pCaller, info.GetWeapon() ); + } + + // Check the attacker's active weapon instead + if (info.GetAttacker()) + { + return PassesFilterImpl( pCaller, info.GetAttacker() ); + } + + // No weapon to check + return false; + } +}; + +LINK_ENTITY_TO_CLASS( filter_redirect_weapon, CFilterRedirectWeapon ); + +// ################################################################### +// > CFilterRedirectOwner +// Uses the specified filter to filter by owner entity. +// ################################################################### +class CFilterRedirectOwner : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterRedirectOwner, CBaseFilterRedirect ); + +public: + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (pEntity->GetOwnerEntity()) + { + return RedirectToFilter(pCaller, pEntity->GetOwnerEntity()); + } + + return false; + } +}; + +LINK_ENTITY_TO_CLASS( filter_redirect_owner, CFilterRedirectOwner ); + +// ################################################################### +// > CFilterDamageTransfer +// Transfers damage to another entity. +// ################################################################### +class CFilterDamageTransfer : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterDamageTransfer, CBaseFilterRedirect ); + DECLARE_DATADESC(); + +public: + void Spawn() + { + BaseClass::Spawn(); + + // Assume no string = use activator + if (m_target == NULL_STRING) + m_target = AllocPooledString("!activator"); + + // A number less than or equal to 0 is always synonymous with no limit + if (m_iMaxEntities <= 0) + m_iMaxEntities = MAX_EDICTS; + } + + // Some secondary filter modes shouldn't be used in non-final filter passes + // Always return true on non-standard secondary filter modes + /* + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + return true; + } + */ + + // A hack because of the way final damage filtering now works. + bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (!m_bCallerDamageAllowed) + return false; + else + return m_iSecondaryFilterMode == REDIRECT_MUST_PASS_TO_DAMAGE_CALLER && GetTargetFilter() ? RedirectToDamageFilter(pCaller, info) : true; + } + + // PassesFinalDamageFilter() was created for the express purpose of having filter_damage_transfer function without + // passing damage on filter checks that don't actually lead to us taking damage in the first place. + // PassesFinalDamageFilter() is only called in certain base entity functions where we DEFINITELY will take damage otherwise. + bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (m_iSecondaryFilterMode == REDIRECT_MUST_PASS_TO_ACT) + { + // Transfer only if the secondary filter passes + if (!RedirectToDamageFilter(pCaller, info)) + { + // Otherwise just return the other flag + return m_bCallerDamageAllowed; + } + } + + CBaseEntity *pTarget = gEntList.FindEntityGeneric(NULL, STRING(m_target), this, info.GetAttacker(), pCaller); + int iNumDamaged = 0; + while (pTarget) + { + // Avoid recursive loops! + if (pTarget->m_hDamageFilter != this) + { + CTakeDamageInfo info2 = info; + + // Adjust damage position stuff + if (m_bAdjustDamagePosition) + { + info2.SetDamagePosition(pTarget->GetAbsOrigin() + (pCaller->GetAbsOrigin() - info.GetDamagePosition())); + + if (pCaller->IsCombatCharacter() && pTarget->IsCombatCharacter()) + pTarget->MyCombatCharacterPointer()->SetLastHitGroup(pCaller->MyCombatCharacterPointer()->LastHitGroup()); + } + + if (m_iSecondaryFilterMode != REDIRECT_MUST_PASS_ACTIVATORS || RedirectToFilter(pCaller, pTarget)) + { + pTarget->TakeDamage(info2); + iNumDamaged++; + } + } + + if (iNumDamaged < m_iMaxEntities) + pTarget = gEntList.FindEntityGeneric(pTarget, STRING(m_target), this, info.GetAttacker(), pCaller); + else + break; + } + + // We've transferred the damage, now determine whether the caller should take damage. + // Boolean surpasses all. + if (!m_bCallerDamageAllowed) + return false; + else + return m_iSecondaryFilterMode == REDIRECT_MUST_PASS_TO_DAMAGE_CALLER && GetTargetFilter() ? RedirectToDamageFilter(pCaller, info) : true; + } + + /* + void InputSetTarget( inputdata_t& inputdata ) + { + m_target = inputdata.value.StringID(); + m_hTarget = NULL; + } + */ + + inline CBaseEntity *GetTarget(CBaseEntity *pCaller, CBaseEntity *pActivator) + { + return gEntList.FindEntityGeneric(NULL, STRING(m_target), this, pActivator, pCaller); + } + + //EHANDLE m_hTarget; + + bool m_bAdjustDamagePosition; + + // See CBaseRedirectFilter enum for more info + int m_iSecondaryFilterMode; + + // If enabled, the caller can be damaged after the transfer. If disabled, the caller cannot. + bool m_bCallerDamageAllowed; + + int m_iMaxEntities = MAX_EDICTS; +}; + +LINK_ENTITY_TO_CLASS( filter_damage_transfer, CFilterDamageTransfer ); + +BEGIN_DATADESC( CFilterDamageTransfer ) + + //DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_bAdjustDamagePosition, FIELD_BOOLEAN, "AdjustDamagePosition" ), + DEFINE_KEYFIELD( m_iMaxEntities, FIELD_INTEGER, "MaxEntities" ), + DEFINE_KEYFIELD( m_iSecondaryFilterMode, FIELD_INTEGER, "SecondaryFilterMode" ), + DEFINE_KEYFIELD( m_bCallerDamageAllowed, FIELD_BOOLEAN, "CallerDamageAllowed" ), + +END_DATADESC() + +// ################################################################### +// > CFilterBloodControl +// Takes advantage of hacks created for filter_damage_transfer to control blood. +// ################################################################### +class CFilterBloodControl : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterBloodControl, CBaseFilterRedirect ); + DECLARE_DATADESC(); +public: + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (GetTargetFilter() && m_bSecondaryFilterIsDamageFilter) + return RedirectToFilter(pCaller, pEntity); + + return true; + } + + bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (m_bBloodDisabled) + return false; + + return GetTargetFilter() ? RedirectToDamageFilter(pCaller, info) : true; + } + + void InputDisableBlood( inputdata_t &inputdata ) { m_bBloodDisabled = true; } + void InputEnableBlood( inputdata_t &inputdata ) { m_bBloodDisabled = false; } + + bool m_bBloodDisabled; + + // Uses the secondary filter as a damage filter instead of just a blood filter + bool m_bSecondaryFilterIsDamageFilter; +}; + +LINK_ENTITY_TO_CLASS( filter_blood_control, CFilterBloodControl ); + +BEGIN_DATADESC( CFilterBloodControl ) + + DEFINE_KEYFIELD( m_bBloodDisabled, FIELD_BOOLEAN, "BloodDisabled" ), + DEFINE_KEYFIELD( m_bSecondaryFilterIsDamageFilter, FIELD_BOOLEAN, "SecondaryFilterMode" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "DisableBlood", InputDisableBlood ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableBlood", InputEnableBlood ), + +END_DATADESC() + +// ################################################################### +// > CFilterDamageMod +// Modifies damage. +// ################################################################### +class CFilterDamageMod : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterDamageMod, CBaseFilterRedirect ); + DECLARE_DATADESC(); +public: + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (GetTargetFilter() && m_iSecondaryFilterMode == REDIRECT_MUST_PASS_TO_DAMAGE_CALLER) + return RedirectToFilter(pCaller, pEntity); + + return true; + } + + bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (GetTargetFilter() && m_iSecondaryFilterMode == REDIRECT_MUST_PASS_TO_DAMAGE_CALLER) + return RedirectToDamageFilter( pCaller, info ); + + return true; + } + + bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ) + { + if (GetTargetFilter()) + { + bool bPass = true; + + switch (m_iSecondaryFilterMode) + { + case REDIRECT_MUST_PASS_TO_DAMAGE_CALLER: + case REDIRECT_MUST_PASS_TO_ACT: bPass = (RedirectToDamageFilter( pCaller, info )); break; + + case REDIRECT_MUST_PASS_ACTIVATORS: bPass = (info.GetAttacker() && RedirectToFilter(pCaller, info.GetAttacker())); break; + } + + if (!bPass) + return false; + } + + if (m_flDamageMultiplier != 1.0f) + info.ScaleDamage(m_flDamageMultiplier); + if (m_flDamageAddend != 0.0f) + info.AddDamage(m_flDamageAddend); + + if (m_iDamageBitsAdded != 0) + info.AddDamageType(m_iDamageBitsAdded); + if (m_iDamageBitsRemoved != 0) + info.AddDamageType(~m_iDamageBitsRemoved); + + if (m_iszNewAttacker != NULL_STRING) + { + if (!m_hNewAttacker) + m_hNewAttacker = gEntList.FindEntityByName(NULL, m_iszNewAttacker, this, info.GetAttacker(), pCaller); + info.SetAttacker(m_hNewAttacker); + } + if (m_iszNewInflictor != NULL_STRING) + { + if (!m_hNewInflictor) + m_hNewInflictor = gEntList.FindEntityByName(NULL, m_iszNewInflictor, this, info.GetAttacker(), pCaller); + info.SetInflictor(m_hNewInflictor); + } + if (m_iszNewWeapon != NULL_STRING) + { + if (!m_hNewWeapon) + m_hNewWeapon = gEntList.FindEntityByName(NULL, m_iszNewWeapon, this, info.GetAttacker(), pCaller); + info.SetWeapon(m_hNewWeapon); + } + + return true; + } + + void InputSetNewAttacker( inputdata_t &inputdata ) { m_iszNewAttacker = inputdata.value.StringID(); m_hNewAttacker = NULL; } + void InputSetNewInflictor( inputdata_t &inputdata ) { m_iszNewInflictor = inputdata.value.StringID(); m_hNewInflictor = NULL; } + void InputSetNewWeapon( inputdata_t &inputdata ) { m_iszNewWeapon = inputdata.value.StringID(); m_hNewWeapon = NULL; } + + float m_flDamageMultiplier = 1.0f; + float m_flDamageAddend; + int m_iDamageBitsAdded; + int m_iDamageBitsRemoved; + + string_t m_iszNewAttacker; EHANDLE m_hNewAttacker; + string_t m_iszNewInflictor; EHANDLE m_hNewInflictor; + string_t m_iszNewWeapon; EHANDLE m_hNewWeapon; + + // See CBaseRedirectFilter enum for more info + int m_iSecondaryFilterMode; +}; + +LINK_ENTITY_TO_CLASS( filter_damage_mod, CFilterDamageMod ); + +BEGIN_DATADESC( CFilterDamageMod ) + + DEFINE_KEYFIELD( m_iszNewAttacker, FIELD_STRING, "NewAttacker" ), + DEFINE_KEYFIELD( m_iszNewInflictor, FIELD_STRING, "NewInflictor" ), + DEFINE_KEYFIELD( m_iszNewWeapon, FIELD_STRING, "NewWeapon" ), + DEFINE_FIELD( m_hNewAttacker, FIELD_EHANDLE ), + DEFINE_FIELD( m_hNewInflictor, FIELD_EHANDLE ), + DEFINE_FIELD( m_hNewWeapon, FIELD_EHANDLE ), + + DEFINE_INPUT( m_flDamageMultiplier, FIELD_FLOAT, "SetDamageMultiplier" ), + DEFINE_INPUT( m_flDamageAddend, FIELD_FLOAT, "SetDamageAddend" ), + DEFINE_INPUT( m_iDamageBitsAdded, FIELD_INTEGER, "SetDamageBitsAdded" ), + DEFINE_INPUT( m_iDamageBitsRemoved, FIELD_INTEGER, "SetDamageBitsRemoved" ), + + DEFINE_KEYFIELD( m_iSecondaryFilterMode, FIELD_INTEGER, "SecondaryFilterMode" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetNewAttacker", InputSetNewAttacker ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetNewInflictor", InputSetNewInflictor ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetNewWeapon", InputSetNewWeapon ), + +END_DATADESC() + +// ################################################################### +// > CFilterDamageLogic +// Fires outputs from damage information. +// ################################################################### +class CFilterDamageLogic : public CBaseFilterRedirect +{ + DECLARE_CLASS( CFilterDamageLogic, CBaseFilterRedirect ); + DECLARE_DATADESC(); +public: + bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + bool bPassesFilter = !GetTargetFilter() || RedirectToDamageFilter( pCaller, info ); + if (!bPassesFilter) + { + if (m_iSecondaryFilterMode == 2) + return true; + else if (m_iSecondaryFilterMode != 1) + return false; + } + + CBaseEntity *pActivator = info.GetAttacker(); + + m_OutInflictor.Set( info.GetInflictor(), pActivator, pCaller ); + m_OutAttacker.Set( info.GetAttacker(), pActivator, pCaller ); + m_OutWeapon.Set( info.GetWeapon(), pActivator, pCaller ); + + m_OutDamage.Set( info.GetDamage(), pActivator, pCaller ); + m_OutMaxDamage.Set( info.GetMaxDamage(), pActivator, pCaller ); + m_OutBaseDamage.Set( info.GetBaseDamage(), pActivator, pCaller ); + + m_OutDamageType.Set( info.GetDamageType(), pActivator, pCaller ); + m_OutDamageCustom.Set( info.GetDamageCustom(), pActivator, pCaller ); + m_OutDamageStats.Set( info.GetDamageStats(), pActivator, pCaller ); + m_OutAmmoType.Set( info.GetAmmoType(), pActivator, pCaller ); + + m_OutDamageForce.Set( info.GetDamageForce(), pActivator, pCaller ); + m_OutDamagePosition.Set( info.GetDamagePosition(), pActivator, pCaller ); + + m_OutForceFriendlyFire.Set( info.IsForceFriendlyFire() ? 1 : 0, pActivator, pCaller ); + + return bPassesFilter; + } + + bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if (GetTargetFilter() && m_iSecondaryFilterMode != 2) + return RedirectToDamageFilter( pCaller, info ); + + return true; + } + + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if (GetTargetFilter() && m_iSecondaryFilterMode != 2) + return RedirectToFilter( pCaller, pEntity ); + + return true; + } + + // 0 = Use as a regular damage filter. If it doesn't pass, damage won't be outputted. + // 1 = Fire outputs even if the secondary filter doesn't pass. + // 2 = Only use the secondary filter for whether to output damage, other damage is actually dealt. + int m_iSecondaryFilterMode; + + // Outputs + COutputEHANDLE m_OutInflictor; + COutputEHANDLE m_OutAttacker; + COutputEHANDLE m_OutWeapon; + + COutputFloat m_OutDamage; + COutputFloat m_OutMaxDamage; + COutputFloat m_OutBaseDamage; + + COutputInt m_OutDamageType; + COutputInt m_OutDamageCustom; + COutputInt m_OutDamageStats; + COutputInt m_OutAmmoType; + + COutputVector m_OutDamageForce; + COutputPositionVector m_OutDamagePosition; + + COutputInt m_OutForceFriendlyFire; +}; + +LINK_ENTITY_TO_CLASS( filter_damage_logic, CFilterDamageLogic ); + +BEGIN_DATADESC( CFilterDamageLogic ) + + DEFINE_KEYFIELD( m_iSecondaryFilterMode, FIELD_INTEGER, "SecondaryFilterMode" ), + + // Outputs + DEFINE_OUTPUT( m_OutInflictor, "OutInflictor" ), + DEFINE_OUTPUT( m_OutAttacker, "OutAttacker" ), + DEFINE_OUTPUT( m_OutWeapon, "OutWeapon" ), + + DEFINE_OUTPUT( m_OutDamage, "OutDamage" ), + DEFINE_OUTPUT( m_OutMaxDamage, "OutMaxDamage" ), + DEFINE_OUTPUT( m_OutBaseDamage, "OutBaseDamage" ), + + DEFINE_OUTPUT( m_OutDamageType, "OutDamageType" ), + DEFINE_OUTPUT( m_OutDamageCustom, "OutDamageCustom" ), + DEFINE_OUTPUT( m_OutDamageStats, "OutDamageStats" ), + DEFINE_OUTPUT( m_OutAmmoType, "OutAmmoType" ), + + DEFINE_OUTPUT( m_OutDamageForce, "OutDamageForce" ), + DEFINE_OUTPUT( m_OutDamagePosition, "OutDamagePosition" ), + + DEFINE_OUTPUT( m_OutForceFriendlyFire, "OutForceFriendlyFire" ), + +END_DATADESC() +#endif + +#ifdef MAPBASE_VSCRIPT +ScriptHook_t g_Hook_PassesFilter; +ScriptHook_t g_Hook_PassesDamageFilter; +ScriptHook_t g_Hook_PassesFinalDamageFilter; +ScriptHook_t g_Hook_BloodAllowed; +ScriptHook_t g_Hook_DamageMod; + +// ################################################################### +// > CFilterScript +// ################################################################### +class CFilterScript : public CBaseFilter +{ + DECLARE_CLASS( CFilterScript, CBaseFilter ); + DECLARE_DATADESC(); + DECLARE_ENT_SCRIPTDESC(); + +public: + bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ) + { + if ( !m_ScriptScope.IsInitialized() ) + { + Warning( "%s: No script scope, cannot filter\n", GetDebugName() ); + return false; + } + + if ( g_Hook_PassesFilter.CanRunInScope( m_ScriptScope ) ) + { + // caller, activator + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pCaller ), ToHScript( pEntity ) }; + g_Hook_PassesFilter.Call( m_ScriptScope, &functionReturn, args ); + + return functionReturn.m_bool; + } + + Warning( "%s: No PassesFilter function\n", GetDebugName() ); + return false; + } + + bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if ( !m_ScriptScope.IsInitialized() ) + { + Warning( "%s: No script scope, cannot filter\n", GetDebugName() ); + return false; + } + + if ( g_Hook_PassesDamageFilter.CanRunInScope( m_ScriptScope ) ) + { + HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast(&info) ); + + // caller, info + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pCaller ), pInfo }; + g_Hook_PassesDamageFilter.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( pInfo ); + + return functionReturn.m_bool; + } + + // Fall back to main filter function + return PassesFilterImpl( pCaller, info.GetAttacker() ); + } + + bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if ( !m_ScriptScope.IsInitialized() ) + { + Warning( "%s: No script scope, cannot filter\n", GetDebugName() ); + return false; + } + + if ( g_Hook_PassesFinalDamageFilter.CanRunInScope( m_ScriptScope ) ) + { + HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast(&info) ); + + // caller, info + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pCaller ), pInfo }; + g_Hook_PassesFinalDamageFilter.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( pInfo ); + + return functionReturn.m_bool; + } + + return BaseClass::PassesFinalDamageFilter( pCaller, info ); + } + + bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) + { + if ( !m_ScriptScope.IsInitialized() ) + { + Warning( "%s: No script scope, cannot filter\n", GetDebugName() ); + return false; + } + + if ( g_Hook_BloodAllowed.CanRunInScope( m_ScriptScope ) ) + { + HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast(&info) ); + + // caller, info + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pCaller ), pInfo }; + g_Hook_BloodAllowed.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( pInfo ); + + return functionReturn.m_bool; + } + + return BaseClass::BloodAllowed( pCaller, info ); + } + + bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ) + { + if ( !m_ScriptScope.IsInitialized() ) + { + Warning( "%s: No script scope, cannot filter\n", GetDebugName() ); + return false; + } + + if ( g_Hook_DamageMod.CanRunInScope( m_ScriptScope ) ) + { + HSCRIPT pInfo = g_pScriptVM->RegisterInstance( &info ); + + // caller, info + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pCaller ), pInfo }; + g_Hook_DamageMod.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( pInfo ); + + return functionReturn.m_bool; + } + + return BaseClass::DamageMod( pCaller, info ); + } +}; + +LINK_ENTITY_TO_CLASS( filter_script, CFilterScript ); + +BEGIN_DATADESC( CFilterScript ) +END_DATADESC() + +BEGIN_ENT_SCRIPTDESC( CFilterScript, CBaseFilter, "The filter_script entity which allows VScript functions to hook onto filter methods." ) + + // + // Hooks + // + + // The CFilterScript class is visible in the help string, so "A hook used by filter_script" is redundant, but these names are also + // used for functions in CBaseFilter. In order to reduce confusion, the description emphasizes that these are hooks. + BEGIN_SCRIPTHOOK( g_Hook_PassesFilter, "PassesFilter", FIELD_BOOLEAN, "A hook used by filter_script to determine what entities should pass it. Return true if the entity should pass or false if it should not. This hook is required for regular filtering." ) + DEFINE_SCRIPTHOOK_PARAM( "caller", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "activator", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_PassesDamageFilter, "PassesDamageFilter", FIELD_BOOLEAN, "A hook used by filter_script to determine what damage should pass it when it's being used as a damage filter. Return true if the info should pass or false if it should not. If this hook is not defined in a filter_script, damage filter requests will instead check PassesFilter with the attacker as the activator." ) + DEFINE_SCRIPTHOOK_PARAM( "caller", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_PassesFinalDamageFilter, "PassesFinalDamageFilter", FIELD_BOOLEAN, "A completely optional hook used by filter_script which only runs when the entity will take damage. This is different from PassesDamageFilter, which is sometimes used in cases where damage is not actually about to be taken. This also runs after a regular PassesDamageFilter check. Return true if the info should pass or false if it should not. If this hook is not defined, it will always return true." ) + DEFINE_SCRIPTHOOK_PARAM( "caller", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_BloodAllowed, "BloodAllowed", FIELD_BOOLEAN, "A completely optional hook used by filter_script to determine if a caller is allowed to emit blood after taking damage. Return true if blood should be allowed or false if it should not. If this hook is not defined, it will always return true." ) + DEFINE_SCRIPTHOOK_PARAM( "caller", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_DamageMod, "DamageMod", FIELD_BOOLEAN, "A completely optional hook used by filter_script to modify damage being taken by an entity. You are free to use CTakeDamageInfo functions on the damage info handle and it will change how the caller is damaged. Returning true or false currently has no effect on vanilla code, but you should generally return true if the damage info has been modified by your code and false if it was not. If this hook is not defined, it will always return false." ) + DEFINE_SCRIPTHOOK_PARAM( "caller", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + +END_SCRIPTDESC() +#endif diff --git a/game/server/filters.h b/game/server/filters.h index 483de243..faaa20fd 100644 --- a/game/server/filters.h +++ b/game/server/filters.h @@ -38,15 +38,47 @@ class CBaseFilter : public CLogicalEntity public: DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif bool PassesFilter( CBaseEntity *pCaller, CBaseEntity *pEntity ); +#ifdef MAPBASE + bool PassesDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ); + + // This was made for filter_damage_transfer. Should return true on all other filters. + virtual bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info ) { return true; } + + virtual bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info ) { return true; } + + virtual bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info ) { return false; } + + // Deprecated. Pass the caller in front. + bool PassesDamageFilter( const CTakeDamageInfo &info ); +#else bool PassesDamageFilter( const CTakeDamageInfo &info ); +#endif + +#ifdef MAPBASE_VSCRIPT + bool ScriptPassesFilter( HSCRIPT pCaller, HSCRIPT pEntity ); + bool ScriptPassesDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ); + bool ScriptPassesFinalDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ); + bool ScriptBloodAllowed( HSCRIPT pCaller, HSCRIPT pInfo ); + bool ScriptDamageMod( HSCRIPT pCaller, HSCRIPT pInfo ); +#endif bool m_bNegated; // Inputs void InputTestActivator( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputTestEntity( inputdata_t &inputdata ); + virtual void InputSetField( inputdata_t &inputdata ); + + bool m_bPassCallerWhenTested; +#endif + // Outputs COutputEvent m_OnPass; // Fired when filter is passed COutputEvent m_OnFail; // Fired when filter is failed @@ -54,7 +86,49 @@ class CBaseFilter : public CLogicalEntity protected: virtual bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity ); +#ifdef MAPBASE + virtual bool PassesDamageFilterImpl(CBaseEntity *pCaller, const CTakeDamageInfo &info); +#else virtual bool PassesDamageFilterImpl(const CTakeDamageInfo &info); +#endif +}; + +#ifdef MAPBASE +//========================================================= +// Trace filter that uses a filter entity. +// If the regular trace filter stuff tells this trace to hit an entity, it will go through a filter entity. +// If the entity passes the filter, the trace will go through. +// This can be negated with m_bHitIfPassed, meaning entities that pass will be hit. +// Use m_bFilterExclusive to make the filter the sole factor in hitting an entity. +//========================================================= +class CTraceFilterEntityFilter : public CTraceFilterSimple +{ +public: + CTraceFilterEntityFilter( const IHandleEntity *passentity, int collisionGroup ) : CTraceFilterSimple( passentity, collisionGroup ) {} + CTraceFilterEntityFilter( int collisionGroup ) : CTraceFilterSimple( NULL, collisionGroup ) {} + + bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) + { + bool base = CTraceFilterSimple::ShouldHitEntity( pHandleEntity, contentsMask ); + CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); + + if (m_bFilterExclusive && m_pFilter) + return m_pFilter->PassesFilter(m_pCaller, pEntity) ? m_bHitIfPassed : !m_bHitIfPassed; + else if (m_pFilter && (base ? !m_bHitIfPassed : m_bHitIfPassed)) + { + return m_bHitIfPassed ? m_pFilter->PassesFilter(m_pCaller, pEntity) : !m_pFilter->PassesFilter(m_pCaller, pEntity); + } + + return base; + } + + CBaseFilter *m_pFilter; + CBaseEntity *m_pCaller; + + bool m_bHitIfPassed; + bool m_bFilterExclusive; + }; +#endif #endif // FILTERS_H diff --git a/game/server/fire.cpp b/game/server/fire.cpp index ee5fd24c..a4fb9720 100644 --- a/game/server/fire.cpp +++ b/game/server/fire.cpp @@ -17,11 +17,16 @@ #include "ispatialpartition.h" #include "collisionutils.h" #include "tier0/vprof.h" +#ifdef MAPBASE +#include "weapon_flaregun.h" +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifndef MAPBASE /******************************************************************** NOTE: if you are looking at this file becase you would like flares to be considered as fires (and thereby trigger gas traps), be aware @@ -40,7 +45,13 @@ For some partial work towards this end, see changelist 192474. ********************************************************************/ - +#else +// ================================================================ // +// env_firesensors now have the ability to sense flares, toggled via spawnflag. +// This is different from integrating it with the greater fire system and easily preserves original behavior. +// You could try treating flares as real fires yourself if you think it's an issue. +// ================================================================ // +#endif @@ -243,7 +254,11 @@ IterationRetval_t CFireSphere::EnumElement( IHandleEntity *pHandleEntity ) { // UNDONE: Measure which of these is faster // CFire *pFire = dynamic_cast(pEntity); +#ifdef MAPBASE + if ( !EntIsClass( pEntity, gm_isz_class_EnvFire ) ) +#else if ( !FClassnameIs( pEntity, "env_fire" ) ) +#endif return ITERATION_CONTINUE; CFire *pFire = static_cast(pEntity); @@ -995,7 +1010,11 @@ void CFire::Update( float simTime ) { continue; } +#ifdef MAPBASE + else if ( EntIsClass( pOther, gm_isz_class_EnvFire ) ) +#else else if ( FClassnameIs( pOther, "env_fire" ) ) +#endif { if ( fireCount < ARRAYSIZE(pFires) ) { @@ -1307,6 +1326,9 @@ void CEnvFireSource::InputDisable( inputdata_t &inputdata ) // CEnvFireSensor detects changes in heat //================================================== #define SF_FIRESENSOR_START_ON 1 +#ifdef MAPBASE +#define SF_FIRESENSOR_ACCEPT_FLARES 2 +#endif class CEnvFireSensor : public CBaseEntity { @@ -1318,6 +1340,9 @@ class CEnvFireSensor : public CBaseEntity void TurnOff(); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + int DrawDebugTextOverlays(void); +#endif DECLARE_DATADESC(); @@ -1328,6 +1353,10 @@ class CEnvFireSensor : public CBaseEntity float m_targetLevel; float m_targetTime; float m_levelTime; +#ifdef MAPBASE + // Only stored for access in debug overlays, don't save + float m_curheat; +#endif COutputEvent m_OnHeatLevelStart; COutputEvent m_OnHeatLevelEnd; @@ -1385,6 +1414,28 @@ void CEnvFireSensor::Think() heat += pFires[i]->GetHeatLevel(); } +#ifdef MAPBASE + if (HasSpawnFlags(SF_FIRESENSOR_ACCEPT_FLARES)) + { + // Also look for nearby flares + CBaseEntity *pEntity = gEntList.FindEntityByClassnameWithin( NULL, "env_flare", GetAbsOrigin(), m_radius ); + while (pEntity) + { + CFlare *pFlare = static_cast(pEntity); + if (pFlare) + { + heat += (pFlare->m_flTimeBurnOut > -1.0 ? (pFlare->m_flTimeBurnOut - gpGlobals->curtime) : 32); + } + + pEntity = gEntList.FindEntityByClassnameWithin( pEntity, "env_flare", GetAbsOrigin(), m_radius ); + } + } +#endif + +#ifdef MAPBASE + m_curheat = heat; +#endif + if ( heat >= m_targetLevel ) { m_levelTime += time; @@ -1442,6 +1493,28 @@ void CEnvFireSensor::InputDisable( inputdata_t &inputdata ) TurnOff(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CEnvFireSensor::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + // print flame size + Q_snprintf(tempstr, sizeof(tempstr), " Current Heat: %f", m_curheat); + EntityText(text_offset,tempstr,0); + text_offset++; + } + return text_offset; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Draw any debug text overlays // Output : Current text offset from the top diff --git a/game/server/fish.cpp b/game/server/fish.cpp index e6620068..553c7659 100644 --- a/game/server/fish.cpp +++ b/game/server/fish.cpp @@ -540,6 +540,19 @@ BEGIN_DATADESC( CFishPool ) DEFINE_FIELD( m_isDormant, FIELD_BOOLEAN ), DEFINE_UTLVECTOR( m_fishes, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_INPUT( m_nSkin, FIELD_INTEGER, "skin" ), + + DEFINE_KEYFIELD( m_flLoudPanicRange, FIELD_FLOAT, "LoudPanicRange" ), + DEFINE_KEYFIELD( m_flQuietPanicRange, FIELD_FLOAT, "QuietPanicRange" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "SpawnFish", InputSpawnFish ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "PanicLoudFromPoint", InputPanicLoudFromPoint ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "PanicQuietFromPoint", InputPanicQuietFromPoint ), + + DEFINE_OUTPUT( m_OnSpawnFish, "OnSpawnFish" ), +#endif + DEFINE_THINKFUNC( Update ), END_DATADESC() @@ -553,6 +566,14 @@ CFishPool::CFishPool( void ) m_swimDepth = 0.0f; m_isDormant = false; +#ifdef MAPBASE + m_nSkin = 0; + + // Original defaults + m_flLoudPanicRange = 500.0f; + m_flQuietPanicRange = 75.0f; +#endif + m_visTimer.Start( 0.5f ); ListenForGameEvent( "player_shoot" ); @@ -588,6 +609,10 @@ void CFishPool::Spawn() CHandle hFish; hFish.Set( fish ); m_fishes.AddToTail( hFish ); +#ifdef MAPBASE + fish->m_nSkin = m_nSkin; + m_OnSpawnFish.Set( hFish, fish, this ); +#endif } } } @@ -638,10 +663,14 @@ void CFishPool::FireGameEvent( IGameEvent *event ) CBasePlayer *player = UTIL_PlayerByUserId( event->GetInt( "userid" ) ); // the fish panic +#ifdef MAPBASE + float range = (Q_strcmp( "player_footstep", event->GetName() )) ? m_flLoudPanicRange : m_flQuietPanicRange; +#else const float loudRange = 500.0f; const float quietRange = 75.0f; float range = (Q_strcmp( "player_footstep", event->GetName() )) ? loudRange : quietRange; +#endif for( int i=0; iResetVisible(); } @@ -731,3 +769,63 @@ void CFishPool::Update( void ) } } +#ifdef MAPBASE +//------------------------------------------------------------------------------------------------------------- +/** + * Inputs + */ +void CFishPool::InputSpawnFish( inputdata_t &inputdata ) +{ + QAngle heading( 0.0f, RandomFloat( 0, 360.0f ), 0.0f ); + + CFish *fish = (CFish *)Create( "fish", GetAbsOrigin(), heading, this ); + fish->Initialize( this, m_fishes.Count() ); + + if (fish) + { + CHandle hFish; + hFish.Set( fish ); + m_fishes.AddToTail( hFish ); +#ifdef MAPBASE + m_OnSpawnFish.Set( hFish, fish, this ); +#endif + } +} + +void CFishPool::InputPanicLoudFromPoint( inputdata_t &inputdata ) +{ + // Make the fish panic from this point + Vector vecPoint; + inputdata.value.Vector3D( vecPoint ); + for( int i=0; iGetAbsOrigin()).IsLengthGreaterThan( m_flLoudPanicRange )) + { + // event too far away to care + continue; + } + + m_fishes[i]->Panic(); + } +} + +void CFishPool::InputPanicQuietFromPoint( inputdata_t &inputdata ) +{ + // Make the fish panic from this point + Vector vecPoint; + inputdata.value.Vector3D( vecPoint ); + for( int i=0; iGetAbsOrigin()).IsLengthGreaterThan( m_flQuietPanicRange )) + { + // event too far away to care + continue; + } + + m_fishes[i]->Panic(); + } +} +#endif + diff --git a/game/server/fish.h b/game/server/fish.h index 6eb7e64d..257bdbcd 100644 --- a/game/server/fish.h +++ b/game/server/fish.h @@ -109,6 +109,12 @@ class CFishPool : public CBaseEntity, public CGameEventListener float GetWaterLevel( void ) const; ///< return Z coordinate of water in world coords float GetMaxRange( void ) const; ///< return how far a fish is allowed to wander +#ifdef MAPBASE + void InputSpawnFish( inputdata_t &inputdata ); + void InputPanicLoudFromPoint( inputdata_t &inputdata ); + void InputPanicQuietFromPoint( inputdata_t &inputdata ); +#endif + private: int m_fishCount; ///< number of fish in the pool float m_maxRange; ///< how far a fish is allowed to wander @@ -120,6 +126,15 @@ class CFishPool : public CBaseEntity, public CGameEventListener CUtlVector< CHandle > m_fishes; ///< vector of all fish in this pool +#ifdef MAPBASE + int m_nSkin; // Sets the skin of spawned fish + + float m_flLoudPanicRange; + float m_flQuietPanicRange; + + COutputEHANDLE m_OnSpawnFish; +#endif + CountdownTimer m_visTimer; ///< for throttling line of sight checks between all fish }; diff --git a/game/server/fogcontroller.cpp b/game/server/fogcontroller.cpp index 7057982a..3ed75060 100644 --- a/game/server/fogcontroller.cpp +++ b/game/server/fogcontroller.cpp @@ -387,5 +387,17 @@ void CFogSystem::LevelInitPostEntity( void ) pPlayer->InitFogController(); } } + else + { + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + + if ( pPlayer && ( pPlayer->m_Local.m_PlayerFog.m_hCtrl.Get() == NULL ) ) + { + pPlayer->InitFogController(); + } + } + } } diff --git a/game/server/fogvolume.cpp b/game/server/fogvolume.cpp new file mode 100644 index 00000000..f2f9a718 --- /dev/null +++ b/game/server/fogvolume.cpp @@ -0,0 +1,153 @@ +//-------------------------------------------------------------------------------------------------------- +// Copyright (c) 2007 Turtle Rock Studios, Inc. - All Rights Reserved + +#include "cbase.h" +#include "fogvolume.h" +#include "collisionutils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +CUtlVector< CFogVolume * > TheFogVolumes; + +ConVar fog_volume_debug( "fog_volume_debug", "0", 0, "If enabled, prints diagnostic information about the current fog volume" ); + +//-------------------------------------------------------------------------------------------------------- +LINK_ENTITY_TO_CLASS(fog_volume, CFogVolume); + +BEGIN_DATADESC( CFogVolume ) + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_KEYFIELD( m_fogName, FIELD_STRING, "FogName" ), + DEFINE_KEYFIELD( m_postProcessName, FIELD_STRING, "PostProcessName" ), + DEFINE_KEYFIELD( m_colorCorrectionName, FIELD_STRING, "ColorCorrectionName" ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + DEFINE_FIELD( m_hFogController, FIELD_EHANDLE ), + DEFINE_FIELD( m_hPostProcessController, FIELD_EHANDLE ), + DEFINE_FIELD( m_hColorCorrectionController, FIELD_EHANDLE ), + +END_DATADESC() + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume *CFogVolume::FindFogVolumeForPosition( const Vector &position ) +{ + CFogVolume *fogVolume = NULL; + for ( int i=0; iCollisionProp()->WorldToCollisionSpace( position, &vecRelativeCenter ); + if ( IsBoxIntersectingSphere( fogVolume->CollisionProp()->OBBMins(), fogVolume->CollisionProp()->OBBMaxs(), vecRelativeCenter, 1.0f ) ) + { + break; + } + fogVolume = NULL; + } + + // This doesn't work well if there are multiple players or multiple fog volume queries per frame; might want to relocate this if that's the case + if ( fog_volume_debug.GetBool() ) + { + if ( fogVolume ) + { + char fogVolumeName[256]; + fogVolume->GetKeyValue( "targetname", fogVolumeName, 256 ); + engine->Con_NPrintf( 0, "Fog Volume ""%s"" found at position (%f %f %f)", fogVolumeName, position.x, position.y, position.z ); + engine->Con_NPrintf( 1, "Fog: %s, post process: %s, color correct: %s", fogVolume->m_fogName, fogVolume->m_postProcessName, fogVolume->m_colorCorrectionName ); + } + else + { + engine->Con_NPrintf( 0, "No Fog Volume found at given position (%f %f %f)", position.x, position.y, position.z ); + } + } + + return fogVolume; +} + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume::CFogVolume() : + BaseClass(), + m_bDisabled( false ), + m_bInFogVolumesList( false ) +{ +} + + +//-------------------------------------------------------------------------------------------------------- +CFogVolume::~CFogVolume() +{ + RemoveFromGlobalList(); +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::Spawn( void ) +{ + BaseClass::Spawn(); + + SetSolid( SOLID_BSP ); + SetSolidFlags( FSOLID_NOT_SOLID ); + SetModel( STRING( GetModelName() ) ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::AddToGlobalList() +{ + if ( !m_bInFogVolumesList ) + { + TheFogVolumes.AddToTail( this ); + m_bInFogVolumesList = true; + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CFogVolume::RemoveFromGlobalList() +{ + if ( m_bInFogVolumesList ) + { + TheFogVolumes.FindAndRemove( this ); + m_bInFogVolumesList = false; + } +} + + +//---------------------------------------------------------------------------- +void CFogVolume::InputEnable( inputdata_t &data ) +{ + m_bDisabled = false; + AddToGlobalList(); +} + + +//---------------------------------------------------------------------------- +void CFogVolume::InputDisable( inputdata_t &data ) +{ + m_bDisabled = true; + RemoveFromGlobalList(); +} + + +//---------------------------------------------------------------------------- +// Called when the level loads or is restored +//---------------------------------------------------------------------------- +void CFogVolume::Activate() +{ + BaseClass::Activate(); + + m_hFogController = dynamic_cast< CFogController* >( gEntList.FindEntityByName( NULL, m_fogName ) ); + m_hPostProcessController = dynamic_cast< CPostProcessController* >( gEntList.FindEntityByName( NULL, m_postProcessName ) ); + m_hColorCorrectionController = dynamic_cast< CColorCorrection* >( gEntList.FindEntityByName( NULL, m_colorCorrectionName ) ); + + if ( !m_bDisabled ) + { + AddToGlobalList(); + } +} diff --git a/game/server/fogvolume.h b/game/server/fogvolume.h new file mode 100644 index 00000000..6bd5880a --- /dev/null +++ b/game/server/fogvolume.h @@ -0,0 +1,74 @@ +//-------------------------------------------------------------------------------------------------------- +// Copyright (c) 2007 Turtle Rock Studios, Inc. - All Rights Reserved + +#ifndef FOG_VOLUME_H +#define FOG_VOLUME_H + +#ifdef _WIN32 +#pragma once +#endif + + +class CFogController; +class CPostProcessController; +class CColorCorrection; + + +//-------------------------------------------------------------------------------------------------------- +// Fog volume entity +class CFogVolume : public CServerOnlyEntity +{ + DECLARE_CLASS( CFogVolume, CServerOnlyEntity ); + DECLARE_DATADESC(); + +public: + CFogVolume(); + virtual ~CFogVolume(); + virtual void Spawn( void ); + virtual void Activate(); + + static CFogVolume *FindFogVolumeForPosition( const Vector &position ); + + const char *GetFogControllerName() const + { + return STRING( m_fogName ); + } + + CFogController* GetFogController( ) const + { + return m_hFogController.Get(); + } + + CPostProcessController* GetPostProcessController( ) const + { + return m_hPostProcessController.Get(); + } + + CColorCorrection* GetColorCorrectionController( ) const + { + return m_hColorCorrectionController.Get(); + } + + void InputEnable( inputdata_t &data ); + void InputDisable( inputdata_t &data ); + +private: + string_t m_fogName; + string_t m_postProcessName; + string_t m_colorCorrectionName; + + CHandle< CFogController > m_hFogController; + CHandle< CPostProcessController > m_hPostProcessController; + CHandle< CColorCorrection > m_hColorCorrectionController; + + bool m_bDisabled; + bool m_bInFogVolumesList; + + void AddToGlobalList(); + void RemoveFromGlobalList(); +}; + +extern CUtlVector< CFogVolume * > TheFogVolumes; + + +#endif // FOG_VOLUME_H \ No newline at end of file diff --git a/game/server/fourwheelvehiclephysics.cpp b/game/server/fourwheelvehiclephysics.cpp index 3a70d02d..ba4a827a 100644 --- a/game/server/fourwheelvehiclephysics.cpp +++ b/game/server/fourwheelvehiclephysics.cpp @@ -148,6 +148,39 @@ BEGIN_DATADESC_NO_BASE( CFourWheelVehiclePhysics ) DEFINE_FIELD( m_bLastSkid, FIELD_BOOLEAN ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CFourWheelVehiclePhysics, "Handler for four-wheel vehicle physics." ) + + DEFINE_SCRIPTFUNC( SetThrottle, "Sets the throttle." ) + DEFINE_SCRIPTFUNC( SetMaxThrottle, "Sets the max throttle." ) + DEFINE_SCRIPTFUNC( SetMaxReverseThrottle, "Sets the max reverse throttle." ) + DEFINE_SCRIPTFUNC( SetSteering, "Sets the steering." ) + DEFINE_SCRIPTFUNC( SetSteeringDegrees, "Sets the degrees of steering." ) + DEFINE_SCRIPTFUNC( SetAction, "Sets the action." ) + DEFINE_SCRIPTFUNC( SetHandbrake, "Sets the handbrake." ) + DEFINE_SCRIPTFUNC( SetBoost, "Sets the boost." ) + DEFINE_SCRIPTFUNC( SetHasBrakePedal, "Sets whether a handbrake pedal exists." ) + + DEFINE_SCRIPTFUNC( SetDisableEngine, "Sets whether the engine is disabled." ) + DEFINE_SCRIPTFUNC( IsEngineDisabled, "Checks whether the engine is disabled." ) + + DEFINE_SCRIPTFUNC( EnableMotion, "Enables vehicle motion." ) + DEFINE_SCRIPTFUNC( DisableMotion, "Disables vehicle motion." ) + + DEFINE_SCRIPTFUNC( GetSpeed, "Gets the speed." ) + DEFINE_SCRIPTFUNC( GetMaxSpeed, "Gets the max speed." ) + DEFINE_SCRIPTFUNC( GetRPM, "Gets the RPM." ) + DEFINE_SCRIPTFUNC( GetThrottle, "Gets the throttle." ) + DEFINE_SCRIPTFUNC( HasBoost, "Checks if the vehicle has the ability to boost." ) + DEFINE_SCRIPTFUNC( BoostTimeLeft, "Gets how much time is left in any current boost." ) + DEFINE_SCRIPTFUNC( IsBoosting, "Checks if the vehicle is boosting." ) + DEFINE_SCRIPTFUNC( GetHLSpeed, "Gets HL speed." ) + DEFINE_SCRIPTFUNC( GetSteering, "Gets the steeering." ) + DEFINE_SCRIPTFUNC( GetSteeringDegrees, "Gets the degrees of steeering." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- // Constructor diff --git a/game/server/func_areaportal.cpp b/game/server/func_areaportal.cpp index ca391317..d2e50a35 100644 --- a/game/server/func_areaportal.cpp +++ b/game/server/func_areaportal.cpp @@ -42,6 +42,11 @@ class CAreaPortal : public CFuncAreaPortalBase virtual bool UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ); +#ifdef MAPBASE + // For func_areaportal_oneway. + int GetPortalState() { return m_state; } +#endif + DECLARE_DATADESC(); private: @@ -189,3 +194,197 @@ int CAreaPortal::UpdateTransmitState() return SetTransmitState( FL_EDICT_DONTSEND ); } +#ifdef MAPBASE +// An areaportal that automatically closes and opens depending on the direction of the client. +// http://developer.valvesoftware.com/wiki/CAreaPortalOneWay +class CAreaPortalOneWay : public CAreaPortal // CAPOW! +{ + DECLARE_CLASS( CAreaPortalOneWay, CAreaPortal ); + DECLARE_DATADESC(); + +public: + Vector m_vecOpenVector; + bool m_bAvoidPop; + bool m_bOneWayActive; + + void Spawn(); + void Activate(); + int Restore(IRestore &restore); + bool UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ); + + void InputDisableOneWay( inputdata_t &inputdata ); + void InputEnableOneWay( inputdata_t &inputdata ); + void InputToggleOneWay( inputdata_t &inputdata ); + void InputInvertOneWay( inputdata_t &inputdata ); + +protected: + void RemoteUpdate( bool IsOpen ); + + bool m_bRemotelyUpdated; + bool m_bRemoteCalcWasOpen; + CHandle m_hNextPortal; // This get saved to disc... + CAreaPortalOneWay* m_pNextPortal; // ...while this gets used at runtime, avoiding loads of casts + +private: + void UpdateNextPortal( bool IsOpen ); + + // These two are irrelevant once the entity has established itself + string_t m_strGroupName; + Vector m_vecOrigin_; // The portal won't compile properly if vecOrigin itself has a value, but it's okay to move something in at runtime +}; + +LINK_ENTITY_TO_CLASS( func_areaportal_oneway, CAreaPortalOneWay ); + +BEGIN_DATADESC( CAreaPortalOneWay ) + DEFINE_KEYFIELD( m_vecOpenVector, FIELD_VECTOR, "onewayfacing" ), + DEFINE_KEYFIELD( m_bAvoidPop, FIELD_BOOLEAN, "avoidpop" ), + DEFINE_KEYFIELD_NOT_SAVED( m_vecOrigin_, FIELD_VECTOR, "origin_" ), + DEFINE_KEYFIELD_NOT_SAVED( m_strGroupName, FIELD_STRING, "group" ), + DEFINE_FIELD( m_bOneWayActive, FIELD_BOOLEAN ), + DEFINE_FIELD( m_hNextPortal, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableOneWay", InputDisableOneWay ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableOneWay", InputEnableOneWay ), + DEFINE_INPUTFUNC( FIELD_VOID, "ToggleOneWay", InputToggleOneWay ), + DEFINE_INPUTFUNC( FIELD_VOID, "InvertOneWay", InputInvertOneWay ), +END_DATADESC() + +void CAreaPortalOneWay::Spawn() +{ + // Convert our angle from Hammer to a proper vector + QAngle angOpenDir = QAngle( m_vecOpenVector.x, m_vecOpenVector.y, m_vecOpenVector.z ); + AngleVectors( angOpenDir, &m_vecOpenVector ); + + SetLocalOrigin(m_vecOrigin_); + m_bOneWayActive = true; + m_bRemotelyUpdated = false; + + BaseClass::Spawn(); +} + +void CAreaPortalOneWay::Activate() +{ + // Optimisation: share open/closed value for CAPOWs with the same GroupName. + if (m_strGroupName != NULL_STRING) + { + for( unsigned short i = GetPortalListElement(); i != g_AreaPortals.InvalidIndex(); i = g_AreaPortals.Next(i) ) + { + CAreaPortalOneWay* pCur = dynamic_cast(g_AreaPortals[i]); + + if ( pCur && pCur != this && strcmp( STRING(m_strGroupName),STRING(pCur->m_strGroupName) ) == 0 ) + { + m_pNextPortal = pCur; + m_hNextPortal = pCur; + break; + } + } + } + + BaseClass::Activate(); +} + +int CAreaPortalOneWay::Restore(IRestore &restore) +{ + if ( m_hNextPortal.IsValid() ) + m_pNextPortal = m_hNextPortal.Get(); + + return BaseClass::Restore(restore); +} + +// Disable the CAPOW (becomes a normal AP) +void CAreaPortalOneWay::InputDisableOneWay( inputdata_t &inputdata ) +{ + m_bOneWayActive = false; +} + +// Re-enable the CAPOW +void CAreaPortalOneWay::InputEnableOneWay( inputdata_t &inputdata ) +{ + m_bOneWayActive = true; +} + +// Toggle CAPOW +void CAreaPortalOneWay::InputToggleOneWay( inputdata_t &inputdata ) +{ + m_bOneWayActive = !m_bOneWayActive; +} + +// Flip the one way direction +void CAreaPortalOneWay::InputInvertOneWay( inputdata_t &inputdata ) +{ + m_vecOpenVector.Negate(); +} + +// Recieve a shared state from another CAPOW, then pass it on to the next +void CAreaPortalOneWay::RemoteUpdate( bool IsOpen ) +{ + m_bRemotelyUpdated = true; + m_bRemoteCalcWasOpen = IsOpen; + UpdateNextPortal(IsOpen); +} + +// Inline func since this code is required three times +inline void CAreaPortalOneWay::UpdateNextPortal( bool IsOpen ) +{ + if (m_pNextPortal) + m_pNextPortal->RemoteUpdate(IsOpen); +} + +#define VIEWER_PADDING 80 // Value copied from func_areaportalbase.cpp + +bool CAreaPortalOneWay::UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ) +{ + if (!m_bOneWayActive) + return BaseClass::UpdateVisibility( vOrigin, fovDistanceAdjustFactor, bIsOpenOnClient ); + + if( m_portalNumber == -1 || GetPortalState() == AREAPORTAL_CLOSED ) + { + bIsOpenOnClient = false; + return false; + } + + // Has another CAPOW on our plane already done a calculation? + // Note that the CAPOW chain is traversed with new values in RemoteUpdate(), NOT here + if (m_bRemotelyUpdated) + { + m_bRemotelyUpdated = false; + return m_bRemoteCalcWasOpen ? BaseClass::UpdateVisibility( vOrigin, fovDistanceAdjustFactor, bIsOpenOnClient ) : false; + } + + // *********************** + // If we've got this far then we're the first CAPOW in the chain this frame + // and need to calculate a value and pass it along said chain ourselves + // *********************** + + float dist = VIEWER_PADDING; // Assume open for backfacing tests... + VPlane plane; + if( engine->GetAreaPortalPlane(vOrigin,m_portalNumber,&plane) ) + dist = plane.DistTo(vOrigin); // ...but if we find a plane, use a genuine figure instead. + // This is done because GetAreaPortalPlane only works for + // portals facing the current area. + + // We can use LocalOrigin here because APs never have parents. + float dot = DotProduct(m_vecOpenVector,vOrigin - GetLocalOrigin()); + + if( dot > 0 ) + { + // We are on the open side of the portal. Pass the result on! + UpdateNextPortal(true); + + // The following backfacing check is the inverse of CFuncAreaPortalBase's: + // it /closes/ the portal if the camera is /behind/ the plane. IsOpenOnClient + // is left alone as per func_areaportalbase.h + return dist < -VIEWER_PADDING ? false : true; + } + else // Closed side + { + // To avoid latency pop when crossing the portal's plane, it is only + // closed on the client if said client is outside the "padding zone". + if ( !m_bAvoidPop || (m_bAvoidPop && dist > VIEWER_PADDING) ) + bIsOpenOnClient = false; + + // We are definitely closed on the server, however. + UpdateNextPortal(false); + return false; + } +} +#endif diff --git a/game/server/func_areaportalbase.h b/game/server/func_areaportalbase.h index ff6c167e..124ece47 100644 --- a/game/server/func_areaportalbase.h +++ b/game/server/func_areaportalbase.h @@ -95,6 +95,10 @@ class CFuncAreaPortalBase : public CBaseEntity // see into area 2. virtual bool UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ); +#ifdef MAPBASE + // For func_areaportal_oneway. + unsigned short GetPortalListElement() { return m_AreaPortalsElement; } +#endif public: diff --git a/game/server/func_break.cpp b/game/server/func_break.cpp index e7043ea9..fd4839ae 100644 --- a/game/server/func_break.cpp +++ b/game/server/func_break.cpp @@ -220,6 +220,14 @@ bool CBreakable::KeyValue( const char *szKeyName, const char *szValue ) int object = atoi( szValue ); if ( object > 0 && object < ARRAYSIZE(pSpawnObjects) ) m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); +#ifdef MAPBASE + // "0" is the default value of a "choices" field in Hammer, representing nothing selected + // atoi() returning 0 may also indicate a failed conversion, so check szValue directly + else if ( FStrEq( szValue, "0" ) ) + m_iszSpawnObject = NULL_STRING; + else + m_iszSpawnObject = AllocPooledString(szValue); +#endif } else if (FStrEq(szKeyName, "propdata") ) { @@ -431,9 +439,10 @@ void CBreakable::Precache( void ) case matCinderBlock: pGibName = "ConcreteChunks"; break; + #endif -#if HL2_EPISODIC +#if HL2_EPISODIC || MAPBASE case matNone: pGibName = ""; break; @@ -817,6 +826,8 @@ void CBreakable::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) //----------------------------------------------------------------------------- int CBreakable::OnTakeDamage( const CTakeDamageInfo &info ) { + Vector vecTemp; + CTakeDamageInfo subInfo = info; // If attacker can't do at least the min required damage to us, don't take any damage from them @@ -830,6 +841,8 @@ int CBreakable::OnTakeDamage( const CTakeDamageInfo &info ) return 1; } + vecTemp = subInfo.GetInflictor()->GetAbsOrigin() - WorldSpaceCenter(); + if (!IsBreakable()) return 0; diff --git a/game/server/func_breakablesurf.cpp b/game/server/func_breakablesurf.cpp index 902722b5..ddd8542f 100644 --- a/game/server/func_breakablesurf.cpp +++ b/game/server/func_breakablesurf.cpp @@ -35,6 +35,9 @@ // Spawn flags #define SF_BREAKABLESURF_CRACK_DECALS 0x00000001 #define SF_BREAKABLESURF_DAMAGE_FROM_HELD_OBJECTS 0x00000002 +#ifdef MAPBASE +#define SF_BREAKABLESURF_PLAY_BREAK_SOUND 0x00000004 +#endif //############################################################################# // > CWindowPane @@ -109,6 +112,8 @@ void CWindowPane::PaneTouch( CBaseEntity *pOther ) //------------------------------------------------------------------------------ void CWindowPane::Die( void ) { + Vector flForce = -1 * GetAbsVelocity(); + CPASFilter filter( GetAbsOrigin() ); te->ShatterSurface( filter, 0.0, &GetAbsOrigin(), &GetAbsAngles(), @@ -609,7 +614,15 @@ void CBreakableSurface::Die( CBaseEntity *pBreaker, const Vector &vAttackDir ) return; // Play a break sound +#ifdef MAPBASE + if ( HasSpawnFlags(SF_BREAKABLESURF_PLAY_BREAK_SOUND) ) + { + Vector centerPos = (m_vLLVertex + m_vURVertex) / 2; + PhysBreakSound( this, VPhysicsGetObject(), centerPos ); + } +#else PhysBreakSound( this, VPhysicsGetObject(), GetAbsOrigin() ); +#endif m_bIsBroken = true; m_iHealth = 0.0f; diff --git a/game/server/func_dust.cpp b/game/server/func_dust.cpp index a06265ea..3e3fcb21 100644 --- a/game/server/func_dust.cpp +++ b/game/server/func_dust.cpp @@ -162,7 +162,7 @@ void CFunc_Dust::Spawn() //Since keyvalues can arrive in any order, and UTIL_StringToColor32 stomps alpha, //install the alpha value here. - color32 clr = { m_Color.m_Value.r, m_Color.m_Value.g, m_Color.m_Value.b, (byte)m_iAlpha }; + color32 clr = { m_Color.m_Value.r, m_Color.m_Value.g, m_Color.m_Value.b, m_iAlpha }; m_Color.Set( clr ); BaseClass::Spawn(); diff --git a/game/server/func_lod.cpp b/game/server/func_lod.cpp index f88c4c0d..7a71e270 100644 --- a/game/server/func_lod.cpp +++ b/game/server/func_lod.cpp @@ -28,6 +28,9 @@ class CFunc_LOD : public CBaseEntity // (waits until it's out of the view frustrum or until there's a lot of motion) // (m_fDisappearDist+): the bmodel is forced to be invisible CNetworkVar( float, m_fDisappearDist ); +#ifdef MAPBASE + CNetworkVar( float, m_fDisappearMaxDist ); +#endif // CBaseEntity overrides. public: @@ -41,6 +44,9 @@ class CFunc_LOD : public CBaseEntity IMPLEMENT_SERVERCLASS_ST(CFunc_LOD, DT_Func_LOD) SendPropFloat(SENDINFO(m_fDisappearDist), 0, SPROP_NOSCALE), +#ifdef MAPBASE + SendPropFloat(SENDINFO(m_fDisappearMaxDist), 0, SPROP_NOSCALE), +#endif END_SEND_TABLE() @@ -53,6 +59,9 @@ LINK_ENTITY_TO_CLASS(func_lod, CFunc_LOD); BEGIN_DATADESC( CFunc_LOD ) DEFINE_FIELD( m_fDisappearDist, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_FIELD( m_fDisappearMaxDist, FIELD_FLOAT ), +#endif END_DATADESC() @@ -98,6 +107,16 @@ bool CFunc_LOD::KeyValue( const char *szKeyName, const char *szValue ) { m_fDisappearDist = (float)atof(szValue); } +#ifdef MAPBASE + else if (FStrEq(szKeyName, "DisappearMaxDist")) + { + m_fDisappearMaxDist = (float)atof(szValue); + } + else if (FStrEq(szKeyName, "DisappearMinDist")) // Forwards compatibility + { + m_fDisappearDist = (float)atof(szValue); + } +#endif else if (FStrEq(szKeyName, "Solid")) { if (atoi(szValue) != 0) diff --git a/game/server/func_movelinear.cpp b/game/server/func_movelinear.cpp index 397fefd1..0fd92a82 100644 --- a/game/server/func_movelinear.cpp +++ b/game/server/func_movelinear.cpp @@ -39,6 +39,9 @@ BEGIN_DATADESC( CFuncMoveLinear ) DEFINE_KEYFIELD( m_flBlockDamage, FIELD_FLOAT, "BlockDamage"), DEFINE_KEYFIELD( m_flStartPosition, FIELD_FLOAT, "StartPosition"), DEFINE_KEYFIELD( m_flMoveDistance, FIELD_FLOAT, "MoveDistance"), +#ifdef MAPBASE + DEFINE_FIELD( m_vecReference, FIELD_VECTOR ), +#endif // DEFINE_PHYSPTR( m_pFluidController ), // Inputs @@ -84,9 +87,16 @@ void CFuncMoveLinear::Spawn( void ) m_flMoveDistance = DotProductAbs( m_vecMoveDir, vecOBB ) - m_flLip; } +#ifdef MAPBASE + m_vecPosition1 = GetLocalOrigin() - (m_vecMoveDir * m_flMoveDistance * m_flStartPosition); + m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * m_flMoveDistance); + m_vecFinalDest = GetLocalOrigin(); + m_vecReference = GetLocalOrigin(); +#else m_vecPosition1 = GetAbsOrigin() - (m_vecMoveDir * m_flMoveDistance * m_flStartPosition); m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * m_flMoveDistance); m_vecFinalDest = GetAbsOrigin(); +#endif SetTouch( NULL ); @@ -116,6 +126,30 @@ bool CFuncMoveLinear::ShouldSavePhysics( void ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets the movement parent of this entity. This entity will be moved +// to a local coordinate calculated from its current absolute offset +// from the parent entity and will then follow the parent entity. +// Input : pParentEntity - This entity's new parent in the movement hierarchy. +//----------------------------------------------------------------------------- +void CFuncMoveLinear::SetParent( CBaseEntity *pParentEntity, int iAttachment ) +{ + Vector oldLocal = GetLocalOrigin(); + + BaseClass::SetParent( pParentEntity, iAttachment ); + + // SOLID_NONE indicates we haven't spawned yet + if (GetSolid() != SOLID_NONE) + { + m_vecReference = ((m_vecReference - oldLocal) + GetLocalOrigin()); + m_vecPosition1 = m_vecReference - (m_vecMoveDir * m_flMoveDistance * m_flStartPosition); + m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * m_flMoveDistance); + m_vecFinalDest = m_vecReference - m_vecFinalDest; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -256,6 +290,16 @@ void CFuncMoveLinear::MoveDone( void ) SetNextThink( gpGlobals->curtime + 0.1f ); BaseClass::MoveDone(); +#ifdef MAPBASE + if ( GetLocalOrigin() == m_vecPosition2 ) + { + m_OnFullyOpen.FireOutput( this, this ); + } + else if ( GetLocalOrigin() == m_vecPosition1 ) + { + m_OnFullyClosed.FireOutput( this, this ); + } +#else if ( GetAbsOrigin() == m_vecPosition2 ) { m_OnFullyOpen.FireOutput( this, this ); @@ -264,6 +308,7 @@ void CFuncMoveLinear::MoveDone( void ) { m_OnFullyClosed.FireOutput( this, this ); } +#endif } @@ -277,8 +322,9 @@ void CFuncMoveLinear::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY if ( value > 1.0 ) value = 1.0; + Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1)); - + Vector delta = move - GetLocalOrigin(); float speed = delta.Length() * 10; @@ -380,6 +426,36 @@ int CFuncMoveLinear::DrawDebugTextOverlays(void) if (m_debugOverlays & OVERLAY_TEXT_BIT) { +#ifdef MAPBASE + if (GetMoveParent()) + { + Vector vecReference, vecPosition1, vecPosition2; + QAngle angReference; + + vecReference = m_vecFinalDest + GetMoveParent()->GetAbsOrigin(); + angReference = GetAbsAngles(); + vecPosition1 = vecReference + m_vecPosition1; + vecPosition2 = vecReference + m_vecPosition2; + + NDebugOverlay::Axis( vecReference, angReference, 12.0f, true, 0.15f ); + NDebugOverlay::Axis( vecPosition1, angReference, 5.0f, true, 0.15f ); + NDebugOverlay::Axis( vecPosition2, angReference, 2.5f, true, 0.15f ); + + char tempstr[512]; + float flTravelDist = (vecPosition1 - vecPosition2).Length(); + float flCurDist = (vecPosition1 - GetAbsOrigin()).Length(); + Q_snprintf(tempstr,sizeof(tempstr),"Current Pos: %3.3f",flCurDist/flTravelDist); + EntityText(text_offset,tempstr,0); + text_offset++; + + float flTargetDist = (vecPosition1 - m_vecFinalDest).Length(); + Q_snprintf(tempstr,sizeof(tempstr),"Target Pos: %3.3f",flTargetDist/flTravelDist); + EntityText(text_offset,tempstr,0); + text_offset++; + } + else + { +#else char tempstr[512]; float flTravelDist = (m_vecPosition1 - m_vecPosition2).Length(); float flCurDist = (m_vecPosition1 - GetLocalOrigin()).Length(); @@ -391,6 +467,10 @@ int CFuncMoveLinear::DrawDebugTextOverlays(void) Q_snprintf(tempstr,sizeof(tempstr),"Target Pos: %3.3f",flTargetDist/flTravelDist); EntityText(text_offset,tempstr,0); text_offset++; +#endif +#ifdef MAPBASE + } +#endif } return text_offset; } diff --git a/game/server/func_movelinear.h b/game/server/func_movelinear.h index 8f09adc2..ac58f963 100644 --- a/game/server/func_movelinear.h +++ b/game/server/func_movelinear.h @@ -27,6 +27,10 @@ class CFuncMoveLinear : public CBaseToggle bool CreateVPhysics( void ); bool ShouldSavePhysics( void ); +#ifdef MAPBASE + void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 ); +#endif + void MoveTo(Vector vPosition, float flSpeed); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void MoveDone( void ); @@ -53,6 +57,11 @@ class CFuncMoveLinear : public CBaseToggle float m_flBlockDamage; // Damage inflicted when blocked. float m_flStartPosition; // Position of brush when spawned float m_flMoveDistance; // Total distance the brush can move +#ifdef MAPBASE + // For the parenting fix. + // Prevents position inconsistencies when changing parent. + Vector m_vecReference; +#endif IPhysicsFluidController *m_pFluidController; diff --git a/game/server/func_reflective_glass.cpp b/game/server/func_reflective_glass.cpp index d68840ef..187556b5 100644 --- a/game/server/func_reflective_glass.cpp +++ b/game/server/func_reflective_glass.cpp @@ -15,13 +15,44 @@ class CFuncReflectiveGlass : public CFuncBrush DECLARE_DATADESC(); DECLARE_CLASS( CFuncReflectiveGlass, CFuncBrush ); DECLARE_SERVERCLASS(); + + CFuncReflectiveGlass() + { +#ifdef MAPBASE + m_iszReflectRenderTarget = AllocPooledString( "_rt_WaterReflection" ); + m_iszRefractRenderTarget = AllocPooledString( "_rt_WaterRefraction" ); +#endif + } + +#ifdef MAPBASE + void InputSetReflectRenderTarget( inputdata_t &inputdata ) { m_iszReflectRenderTarget = inputdata.value.StringID(); } + void InputSetRefractRenderTarget( inputdata_t &inputdata ) { m_iszRefractRenderTarget = inputdata.value.StringID(); } + + CNetworkVar( string_t, m_iszReflectRenderTarget ); + CNetworkVar( string_t, m_iszRefractRenderTarget ); +#endif }; // automatically hooks in the system's callbacks BEGIN_DATADESC( CFuncReflectiveGlass ) + +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszReflectRenderTarget, FIELD_STRING, "ReflectRenderTarget" ), + DEFINE_KEYFIELD( m_iszRefractRenderTarget, FIELD_STRING, "RefractRenderTarget" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetReflectRenderTarget", InputSetReflectRenderTarget ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetRefractRenderTarget", InputSetRefractRenderTarget ), +#endif + END_DATADESC() LINK_ENTITY_TO_CLASS( func_reflective_glass, CFuncReflectiveGlass ); IMPLEMENT_SERVERCLASS_ST( CFuncReflectiveGlass, DT_FuncReflectiveGlass ) + +#ifdef MAPBASE + SendPropStringT( SENDINFO( m_iszReflectRenderTarget ) ), + SendPropStringT( SENDINFO( m_iszRefractRenderTarget ) ), +#endif + END_SEND_TABLE() diff --git a/game/server/game_ui.cpp b/game/server/game_ui.cpp index 0e57ada9..dd2e2032 100644 --- a/game/server/game_ui.cpp +++ b/game/server/game_ui.cpp @@ -38,6 +38,9 @@ class CGameUI : public CBaseEntity // Input handlers void InputDeactivate( inputdata_t &inputdata ); void InputActivate( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputGetButtons( inputdata_t &inputdata ); +#endif void Think( void ); void Deactivate( CBaseEntity *pActivator ); @@ -54,6 +57,14 @@ class CGameUI : public CBaseEntity COutputEvent m_pressedBack; COutputEvent m_pressedAttack; COutputEvent m_pressedAttack2; +#ifdef MAPBASE + COutputEvent m_pressedUse; + COutputEvent m_pressedJump; + COutputEvent m_pressedCrouch; + COutputEvent m_pressedAttack3; + COutputEvent m_pressedSprint; + COutputEvent m_pressedReload; +#endif COutputEvent m_unpressedMoveLeft; COutputEvent m_unpressedMoveRight; @@ -61,12 +72,24 @@ class CGameUI : public CBaseEntity COutputEvent m_unpressedBack; COutputEvent m_unpressedAttack; COutputEvent m_unpressedAttack2; +#ifdef MAPBASE + COutputEvent m_unpressedUse; + COutputEvent m_unpressedJump; + COutputEvent m_unpressedCrouch; + COutputEvent m_unpressedAttack3; + COutputEvent m_unpressedSprint; + COutputEvent m_unpressedReload; +#endif COutputFloat m_xaxis; COutputFloat m_yaxis; COutputFloat m_attackaxis; COutputFloat m_attack2axis; +#ifdef MAPBASE + COutputInt m_OutButtons; +#endif + bool m_bForceUpdate; int m_nLastButtonState; @@ -84,6 +107,9 @@ BEGIN_DATADESC( CGameUI ) DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), DEFINE_INPUTFUNC( FIELD_STRING, "Activate", InputActivate ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "GetButtons", InputGetButtons ), +#endif DEFINE_OUTPUT( m_playerOn, "PlayerOn" ), DEFINE_OUTPUT( m_playerOff, "PlayerOff" ), @@ -94,6 +120,14 @@ BEGIN_DATADESC( CGameUI ) DEFINE_OUTPUT( m_pressedBack, "PressedBack" ), DEFINE_OUTPUT( m_pressedAttack, "PressedAttack" ), DEFINE_OUTPUT( m_pressedAttack2, "PressedAttack2" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_pressedUse, "PressedUse" ), + DEFINE_OUTPUT( m_pressedJump, "PressedJump" ), + DEFINE_OUTPUT( m_pressedCrouch, "PressedCrouch" ), + DEFINE_OUTPUT( m_pressedAttack3, "PressedAttack3" ), + DEFINE_OUTPUT( m_pressedSprint, "PressedSprint" ), + DEFINE_OUTPUT( m_pressedReload, "PressedReload" ), +#endif DEFINE_OUTPUT( m_unpressedMoveLeft, "UnpressedMoveLeft" ), DEFINE_OUTPUT( m_unpressedMoveRight, "UnpressedMoveRight" ), @@ -101,6 +135,16 @@ BEGIN_DATADESC( CGameUI ) DEFINE_OUTPUT( m_unpressedBack, "UnpressedBack" ), DEFINE_OUTPUT( m_unpressedAttack, "UnpressedAttack" ), DEFINE_OUTPUT( m_unpressedAttack2, "UnpressedAttack2" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_unpressedUse, "UnpressedUse" ), + DEFINE_OUTPUT( m_unpressedJump, "UnpressedJump" ), + DEFINE_OUTPUT( m_unpressedCrouch, "UnpressedCrouch" ), + DEFINE_OUTPUT( m_unpressedAttack3, "UnpressedAttack3" ), + DEFINE_OUTPUT( m_unpressedSprint, "UnpressedSprint" ), + DEFINE_OUTPUT( m_unpressedReload, "UnpressedReload" ), + + DEFINE_OUTPUT( m_OutButtons, "OutButtons" ), +#endif DEFINE_OUTPUT( m_xaxis, "XAxis" ), DEFINE_OUTPUT( m_yaxis, "YAxis" ), @@ -170,7 +214,11 @@ void CGameUI::Deactivate( CBaseEntity *pActivator ) } else { +#ifdef MAPBASE + Warning("%s Deactivate(): I have no player when called by %s!\n", GetEntityName().ToCStr(), pActivator ? pActivator->GetEntityName().ToCStr() : "(null)"); +#else Warning("%s Deactivate(): I have no player when called by %s!\n", GetEntityName().ToCStr(), pActivator->GetEntityName().ToCStr()); +#endif } // Stop thinking @@ -297,6 +345,13 @@ void CGameUI::Think( void ) if ((( pPlayer->m_afButtonPressed & IN_USE ) && ( m_spawnflags & SF_GAMEUI_USE_DEACTIVATES )) || (( pPlayer->m_afButtonPressed & IN_JUMP ) && ( m_spawnflags & SF_GAMEUI_JUMP_DEACTIVATES ))) { +#ifdef MAPBASE + if (pPlayer->m_afButtonPressed & IN_USE) + m_pressedUse.FireOutput( pPlayer, this, 0 ); + if (pPlayer->m_afButtonPressed & IN_JUMP) + m_pressedJump.FireOutput( pPlayer, this, 0 ); +#endif + Deactivate( pPlayer ); return; } @@ -380,6 +435,80 @@ void CGameUI::Think( void ) } } +#ifdef MAPBASE + if ( nButtonsChanged & IN_USE ) + { + if ( m_nLastButtonState & IN_USE ) + { + m_unpressedUse.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedUse.FireOutput( pPlayer, this, 0 ); + } + } + + if ( nButtonsChanged & IN_JUMP ) + { + if ( m_nLastButtonState & IN_JUMP ) + { + m_unpressedJump.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedJump.FireOutput( pPlayer, this, 0 ); + } + } + + if ( nButtonsChanged & IN_DUCK ) + { + if ( m_nLastButtonState & IN_DUCK ) + { + m_unpressedCrouch.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedCrouch.FireOutput( pPlayer, this, 0 ); + } + } + + if ( nButtonsChanged & IN_ATTACK3 ) + { + if ( m_nLastButtonState & IN_ATTACK3 ) + { + m_unpressedAttack3.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedAttack3.FireOutput( pPlayer, this, 0 ); + } + } + + if ( nButtonsChanged & IN_SPEED ) + { + if ( m_nLastButtonState & IN_SPEED ) + { + m_unpressedSprint.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedSprint.FireOutput( pPlayer, this, 0 ); + } + } + + if ( nButtonsChanged & IN_RELOAD ) + { + if ( m_nLastButtonState & IN_RELOAD ) + { + m_unpressedReload.FireOutput( pPlayer, this, 0 ); + } + else + { + m_pressedReload.FireOutput( pPlayer, this, 0 ); + } + } +#endif + // Setup for the next frame m_nLastButtonState = pPlayer->m_nButtons; @@ -437,3 +566,13 @@ void CGameUI::Think( void ) m_bForceUpdate = false; } + +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Gets and outputs the player's current buttons +//------------------------------------------------------------------------------ +void CGameUI::InputGetButtons( inputdata_t &inputdata ) +{ + m_OutButtons.Set(m_player ? m_player->m_nButtons : m_nLastButtonState, m_player, this); +} +#endif diff --git a/game/server/gameinterface.cpp b/game/server/gameinterface.cpp index f6bbebb4..8f3df0a7 100644 --- a/game/server/gameinterface.cpp +++ b/game/server/gameinterface.cpp @@ -89,6 +89,12 @@ #include "tier3/tier3.h" #include "serverbenchmark_base.h" #include "querycache.h" +#ifdef MAPBASE +#include "world.h" +#endif + +#include "vscript/ivscript.h" +#include "vscript_server.h" #ifdef TF_DLL @@ -99,7 +105,6 @@ #include "tf_gamerules.h" #include "tf_lobby.h" #include "player_vs_environment/tf_population_manager.h" -#include "workshop/maps_workshop.h" extern ConVar tf_mm_trusted; extern ConVar tf_mm_servermode; @@ -183,6 +188,7 @@ IServerEngineTools *serverenginetools = NULL; ISceneFileCache *scenefilecache = NULL; IXboxSystem *xboxsystem = NULL; // Xbox 360 only IMatchmaking *matchmaking = NULL; // Xbox 360 only +IScriptManager *scriptmanager = NULL; #if defined( REPLAY_ENABLED ) IReplaySystem *g_pReplay = NULL; IServerReplayContext *g_pReplayServerContext = NULL; @@ -560,11 +566,11 @@ void DrawAllDebugOverlays( void ) CServerGameDLL g_ServerGameDLL; // INTERFACEVERSION_SERVERGAMEDLL_VERSION_8 is compatible with the latest since we're only adding things to the end, so expose that as well. -//EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL008, INTERFACEVERSION_SERVERGAMEDLL_VERSION_8, g_ServerGameDLL ); +EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL008, INTERFACEVERSION_SERVERGAMEDLL_VERSION_8, g_ServerGameDLL ); EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL, g_ServerGameDLL); // When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way -COMPILE_TIME_ASSERT( INTERFACEVERSION_SERVERGAMEDLL_INT == 10 ); +COMPILE_TIME_ASSERT( INTERFACEVERSION_SERVERGAMEDLL_INT == 9 ); bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn fileSystemFactory, @@ -625,6 +631,16 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory, if ( IsX360() && (matchmaking = (IMatchmaking *)appSystemFactory( VENGINE_MATCHMAKING_VERSION, NULL )) == NULL ) return false; + if (!CommandLine()->CheckParm("-noscripting")) + { + scriptmanager = (IScriptManager*)appSystemFactory(VSCRIPT_INTERFACE_VERSION, NULL); + + if (scriptmanager == nullptr) + { + scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL); + } + } + // If not running dedicated, grab the engine vgui interface if ( !engine->IsDedicatedServer() ) { @@ -682,6 +698,7 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory, g_pGameSaveRestoreBlockSet->AddBlockHandler( GetCommentarySaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->AddBlockHandler( GetEventQueueSaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->AddBlockHandler( GetAchievementSaveRestoreBlockHandler() ); + g_pGameSaveRestoreBlockSet->AddBlockHandler( GetVScriptSaveRestoreBlockHandler() ); // The string system must init first + shutdown last IGameSystem::Add( GameStringSystem() ); @@ -702,6 +719,9 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory, IGameSystem::Add( SoundEmitterSystem() ); // load Mod specific game events ( MUST be before InitAllSystems() so it can pickup the mod specific events) +#ifdef MAPBASE + gameeventmanager->LoadEventsFromFile("resource/MapbaseEvents.res"); +#endif gameeventmanager->LoadEventsFromFile("resource/ModEvents.res"); #ifdef CSTRIKE_DLL // BOTPORT: TODO: move these ifdefs out @@ -757,6 +777,7 @@ void CServerGameDLL::DLLShutdown( void ) // Due to dependencies, these are not autogamesystems ModelSoundsCacheShutdown(); + g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetVScriptSaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetAchievementSaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetCommentarySaveRestoreBlockHandler() ); g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetEventQueueSaveRestoreBlockHandler() ); @@ -1082,7 +1103,7 @@ bool g_bCheckForChainedActivate; { \ if ( bCheck ) \ { \ - AssertMsg( g_bReceivedChainedActivate, "Entity (%i/%s/%s) failed to call base class Activate()\n", pClass->entindex(), pClass->GetClassname(), STRING( pClass->GetEntityName() ) ); \ + AssertMsg( g_bReceivedChainedActivate == true, "Entity (%i/%s/%s) failed to call base class Activate()\n", pClass->entindex(), pClass->GetClassname(), STRING( pClass->GetEntityName() ) ); \ } \ g_bCheckForChainedActivate = false; \ } @@ -1099,7 +1120,7 @@ void CServerGameDLL::ServerActivate( edict_t *pEdictList, int edictCount, int cl if ( gEntList.ResetDeleteList() != 0 ) { - Msg( "%s", "ERROR: Entity delete queue not empty on level start!\n" ); + Msg( "ERROR: Entity delete queue not empty on level start!\n" ); } for ( CBaseEntity *pClass = gEntList.FirstEnt(); pClass != NULL; pClass = gEntList.NextEnt(pClass) ) @@ -1149,7 +1170,6 @@ void CServerGameDLL::ServerActivate( edict_t *pEdictList, int edictCount, int cl void CServerGameDLL::GameServerSteamAPIActivated( void ) { #ifndef NO_STEAM - steamgameserverapicontext->Clear(); steamgameserverapicontext->Init(); if ( steamgameserverapicontext->SteamGameServer() && engine->IsDedicatedServer() ) { @@ -1160,7 +1180,6 @@ void CServerGameDLL::GameServerSteamAPIActivated( void ) #ifdef TF_DLL GCClientSystem()->GameServerActivate(); InventoryManager()->GameServerSteamAPIActivated(); - TFMapsWorkshop()->GameServerSteamAPIActivated(); #endif } @@ -1722,9 +1741,41 @@ static TITLECOMMENT gTitleComments[] = #endif }; +#ifdef MAPBASE +extern CUtlVector *Mapbase_GetChapterMaps(); +extern CUtlVector *Mapbase_GetChapterList(); +#endif + #ifdef _XBOX void CServerGameDLL::GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) { +#ifdef MAPBASE + // Check the world entity for a chapter title + if ( CWorld *pWorld = GetWorldEntity() ) + { + const char *pWorldChapter = pWorld->GetChapterTitle(); + if ( pWorldChapter && pWorldChapter[0] != '\0' ) + { + Q_strncpy( chapterTitle, pWorldChapter, sizeof( chapterTitle ) ); + return; + } + } + + // Look in the mod's chapter list + CUtlVector *ModChapterComments = Mapbase_GetChapterMaps(); + if (ModChapterComments->Count() > 0) + { + for ( int i = 0; i < ModChapterComments->Count(); i++ ) + { + if ( !Q_strnicmp( mapname, ModChapterComments->Element(i).pBSPName, strlen(ModChapterComments->Element(i).pBSPName) ) ) + { + Q_strncpy( pTitleBuff, ModChapterComments->Element(i).pTitleName, titleBuffSize ); + return; + } + } + } +#endif + // Try to find a matching title comment for this mapname for ( int i = 0; i < ARRAYSIZE(gTitleComments); i++ ) { @@ -1734,6 +1785,7 @@ void CServerGameDLL::GetTitleName( const char *pMapName, char* pTitleBuff, int t return; } } + Q_strncpy( pTitleBuff, pMapName, titleBuffSize ); } #endif @@ -1771,6 +1823,44 @@ void CServerGameDLL::GetSaveComment( char *text, int maxlength, float flMinutes, break; } } + +#ifdef MAPBASE + // Look in the mod's chapter list + CUtlVector *ModChapterComments = Mapbase_GetChapterMaps(); + if (ModChapterComments->Count() > 0) + { + for ( int i = 0; i < ModChapterComments->Count(); i++ ) + { + if ( !Q_strnicmp( mapname, ModChapterComments->Element(i).pBSPName, strlen(ModChapterComments->Element(i).pBSPName) ) ) + { + // found one + int j; + + // Got a message, post-process it to be save name friendly + Q_strncpy( comment, ModChapterComments->Element(i).pTitleName, sizeof( comment ) ); + pName = comment; + j = 0; + // Strip out CRs + while ( j < 64 && comment[j] ) + { + if ( comment[j] == '\n' || comment[j] == '\r' ) + comment[j] = 0; + else + j++; + } + break; + } + } + } + + // Check the world entity for a chapter title + if ( CWorld *pWorld = GetWorldEntity() ) + { + const char *pWorldChapter = pWorld->GetChapterTitle(); + if ( pWorldChapter && pWorldChapter[0] != '\0' ) + pName = pWorldChapter; + } +#endif // If we didn't get one, use the designer's map name, or the BSP name itself if ( !pName ) @@ -1928,61 +2018,6 @@ const char *CServerGameDLL::GetServerBrowserGameData() return rchResult; } -//----------------------------------------------------------------------------- -void CServerGameDLL::Status( void (*print) (const char *fmt, ...) ) -{ - if ( g_pGameRules ) - { - g_pGameRules->Status( print ); - } -} - -//----------------------------------------------------------------------------- -void CServerGameDLL::PrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize ) -{ -#ifdef TF_DLL - TFMapsWorkshop()->PrepareLevelResources( pszMapName, nMapNameSize, pszMapFile, nMapFileSize ); -#endif // TF_DLL -} - -//----------------------------------------------------------------------------- -IServerGameDLL::ePrepareLevelResourcesResult -CServerGameDLL::AsyncPrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize, - float *flProgress /* = NULL */ ) -{ -#ifdef TF_DLL - return TFMapsWorkshop()->AsyncPrepareLevelResources( pszMapName, nMapNameSize, pszMapFile, nMapFileSize, flProgress ); -#endif // TF_DLL - - if ( flProgress ) - { - *flProgress = 1.f; - } - return IServerGameDLL::ePrepareLevelResources_Prepared; -} - -//----------------------------------------------------------------------------- -IServerGameDLL::eCanProvideLevelResult CServerGameDLL::CanProvideLevel( /* in/out */ char *pMapName, int nMapNameMax ) -{ -#ifdef TF_DLL - return TFMapsWorkshop()->OnCanProvideLevel( pMapName, nMapNameMax ); -#endif // TF_DLL - return IServerGameDLL::eCanProvideLevel_CannotProvide; -} - -//----------------------------------------------------------------------------- -bool CServerGameDLL::IsManualMapChangeOkay( const char **pszReason ) -{ - if ( GameRules() ) - { - return GameRules()->IsManualMapChangeOkay( pszReason ); - } - - return true; -} - //----------------------------------------------------------------------------- // Purpose: Called during a transition, to build a map adjacency list //----------------------------------------------------------------------------- @@ -2121,6 +2156,68 @@ void UpdateChapterRestrictions( const char *mapname ) } } +#ifdef MAPBASE + // Look in the mod's chapter list + CUtlVector *ModChapterComments = Mapbase_GetChapterMaps(); + if (ModChapterComments->Count() > 0) + { + for ( int i = 0; i < ModChapterComments->Count(); i++ ) + { + if ( !Q_strnicmp( mapname, ModChapterComments->Element(i).pBSPName, strlen(ModChapterComments->Element(i).pBSPName) ) ) + { + // found + Q_strncpy( chapterTitle, ModChapterComments->Element(i).pTitleName, sizeof( chapterTitle ) ); + int j = 0; + while ( j < 64 && chapterTitle[j] ) + { + if ( chapterTitle[j] == '\n' || chapterTitle[j] == '\r' ) + chapterTitle[j] = 0; + else + j++; + } + + // Mods can order their own custom chapter names, + // allowing for more flexible string name usage, multiple names in one chapter, etc. + CUtlVector *ModChapterList = Mapbase_GetChapterList(); + for ( int i = 0; i < ModChapterList->Count(); i++ ) + { + if ( !Q_strnicmp( chapterTitle, ModChapterList->Element(i).pChapterName, strlen(chapterTitle) ) ) + { + // ok we have the string, see if it's newer + int nNewChapter = ModChapterList->Element(i).iChapter; + int nUnlockedChapter = sv_unlockedchapters.GetInt(); + + if ( nUnlockedChapter < nNewChapter ) + { + // ok we're at a higher chapter, unlock + sv_unlockedchapters.SetValue( nNewChapter ); + + // HACK: Call up through a better function than this? 7/23/07 - jdw + if ( IsX360() ) + { + engine->ServerCommand( "host_writeconfig\n" ); + } + } + + g_nCurrentChapterIndex = nNewChapter; + return; + } + } + + break; + } + } + } + + // Check the world entity for a chapter title. + if ( CWorld *pWorld = GetWorldEntity() ) + { + const char *pWorldChapter = pWorld->GetChapterTitle(); + if ( pWorldChapter && pWorldChapter[0] != '\0' ) + Q_strncpy( chapterTitle, pWorldChapter, sizeof( chapterTitle ) ); + } +#endif + if ( !chapterTitle[0] ) return; @@ -2695,7 +2792,7 @@ void CServerGameClients::ClientActive( edict_t *pEdict, bool bLoadGame ) #if defined( TF_DLL ) Assert( pPlayer ); - if ( pPlayer && !pPlayer->IsFakeClient() && !pPlayer->IsHLTV() && !pPlayer->IsReplay() ) + if ( pPlayer && !pPlayer->IsFakeClient() ) { CSteamID steamID; if ( pPlayer->GetSteamID( &steamID ) ) @@ -2704,10 +2801,7 @@ void CServerGameClients::ClientActive( edict_t *pEdict, bool bLoadGame ) } else { - if ( !pPlayer->IsReplay() && !pPlayer->IsHLTV() ) - { - Log("WARNING: ClientActive, but we don't know his SteamID?\n"); - } + Log("WARNING: ClientActive, but we don't know his SteamID?\n"); } } #endif @@ -2781,10 +2875,7 @@ void CServerGameClients::ClientDisconnect( edict_t *pEdict ) } else { - if ( !player->IsReplay() && !player->IsHLTV() ) - { - Log("WARNING: ClientDisconnected, but we don't know his SteamID?\n"); - } + Log("WARNING: ClientDisconnected, but we don't know his SteamID?\n"); } } #endif @@ -3105,7 +3196,11 @@ float CServerGameClients::ProcessUsercmds( edict_t *player, bf_read *buf, int nu for ( i = totalcmds - 1; i >= 0; i-- ) { to = &cmds[ i ]; +#if defined( MAPBASE_VSCRIPT ) + ReadUsercmd( buf, to, from, pPlayer ); // Tell whose UserCmd it is +#else ReadUsercmd( buf, to, from ); +#endif from = to; } @@ -3394,7 +3489,7 @@ void MessageWriteEHandle( CBaseEntity *pEntity ) { EHANDLE hEnt = pEntity; - int iSerialNum = hEnt.GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); + int iSerialNum = hEnt.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; iEncodedEHandle = hEnt.GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS); } else diff --git a/game/server/gameinterface.h b/game/server/gameinterface.h index 3092d4f3..67805ff6 100644 --- a/game/server/gameinterface.h +++ b/game/server/gameinterface.h @@ -28,35 +28,35 @@ extern INetworkStringTable *g_pStringTableServerPopFiles; class CServerGameClients : public IServerGameClients { public: - virtual bool ClientConnect( edict_t *pEntity, char const* pszName, char const* pszAddress, char *reject, int maxrejectlen ) OVERRIDE; - virtual void ClientActive( edict_t *pEntity, bool bLoadGame ) OVERRIDE; - virtual void ClientDisconnect( edict_t *pEntity ) OVERRIDE; - virtual void ClientPutInServer( edict_t *pEntity, const char *playername ) OVERRIDE; - virtual void ClientCommand( edict_t *pEntity, const CCommand &args ) OVERRIDE; - virtual void ClientSettingsChanged( edict_t *pEntity ) OVERRIDE; - virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ) OVERRIDE; + virtual bool ClientConnect( edict_t *pEntity, char const* pszName, char const* pszAddress, char *reject, int maxrejectlen ); + virtual void ClientActive( edict_t *pEntity, bool bLoadGame ); + virtual void ClientDisconnect( edict_t *pEntity ); + virtual void ClientPutInServer( edict_t *pEntity, const char *playername ); + virtual void ClientCommand( edict_t *pEntity, const CCommand &args ); + virtual void ClientSettingsChanged( edict_t *pEntity ); + virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ); virtual float ProcessUsercmds( edict_t *player, bf_read *buf, int numcmds, int totalcmds, - int dropped_packets, bool ignore, bool paused ) OVERRIDE; + int dropped_packets, bool ignore, bool paused ); // Player is running a command - virtual void PostClientMessagesSent_DEPRECIATED( void ) OVERRIDE; - virtual void SetCommandClient( int index ) OVERRIDE; - virtual CPlayerState *GetPlayerState( edict_t *player ) OVERRIDE; - virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ) OVERRIDE; + virtual void PostClientMessagesSent_DEPRECIATED( void ); + virtual void SetCommandClient( int index ); + virtual CPlayerState *GetPlayerState( edict_t *player ); + virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ); - virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const OVERRIDE; + virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const; // returns number of delay ticks if player is in Replay mode (0 = no delay) - virtual int GetReplayDelay( edict_t *player, int& entity ) OVERRIDE; + virtual int GetReplayDelay( edict_t *player, int& entity ); // Anything this game .dll wants to add to the bug reporter text (e.g., the entity/model under the picker crosshair) // can be added here - virtual void GetBugReportInfo( char *buf, int buflen ) OVERRIDE; - virtual void NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ) OVERRIDE; + virtual void GetBugReportInfo( char *buf, int buflen ); + virtual void NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ); // The client has submitted a keyvalues command - virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ) OVERRIDE; + virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ); // Notify that the player is spawned - virtual void ClientSpawned( edict_t *pPlayer ) OVERRIDE; + virtual void ClientSpawned( edict_t *pPlayer ); }; @@ -64,73 +64,73 @@ class CServerGameDLL : public IServerGameDLL { public: virtual bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, - CreateInterfaceFn fileSystemFactory, CGlobalVars *pGlobals) OVERRIDE; - virtual void DLLShutdown( void ) OVERRIDE; + CreateInterfaceFn fileSystemFactory, CGlobalVars *pGlobals); + virtual void DLLShutdown( void ); // Get the simulation interval (must be compiled with identical values into both client and game .dll for MOD!!!) - virtual bool ReplayInit( CreateInterfaceFn fnReplayFactory ) OVERRIDE; - virtual float GetTickInterval( void ) const OVERRIDE; - virtual bool GameInit( void ) OVERRIDE; - virtual void GameShutdown( void ) OVERRIDE; - virtual bool LevelInit( const char *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background ) OVERRIDE; - virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) OVERRIDE; - virtual void LevelShutdown( void ) OVERRIDE; - virtual void GameFrame( bool simulating ) OVERRIDE; // could be called multiple times before sending data to clients - virtual void PreClientUpdate( bool simulating ) OVERRIDE; // called after all GameFrame() calls, before sending data to clients - - virtual ServerClass* GetAllServerClasses( void ) OVERRIDE; - virtual const char *GetGameDescription( void ) OVERRIDE; - virtual void CreateNetworkStringTables( void ) OVERRIDE; + virtual bool ReplayInit( CreateInterfaceFn fnReplayFactory ); + virtual float GetTickInterval( void ) const; + virtual bool GameInit( void ); + virtual void GameShutdown( void ); + virtual bool LevelInit( const char *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background ); + virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); + virtual void LevelShutdown( void ); + virtual void GameFrame( bool simulating ); // could be called multiple times before sending data to clients + virtual void PreClientUpdate( bool simulating ); // called after all GameFrame() calls, before sending data to clients + + virtual ServerClass* GetAllServerClasses( void ); + virtual const char *GetGameDescription( void ); + virtual void CreateNetworkStringTables( void ); // Save/restore system hooks - virtual CSaveRestoreData *SaveInit( int size ) OVERRIDE; - virtual void SaveWriteFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ) OVERRIDE; - virtual void SaveReadFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ) OVERRIDE; - virtual void SaveGlobalState( CSaveRestoreData * ) OVERRIDE; - virtual void RestoreGlobalState( CSaveRestoreData * ) OVERRIDE; - virtual int CreateEntityTransitionList( CSaveRestoreData *, int ) OVERRIDE; - virtual void BuildAdjacentMapList( void ) OVERRIDE; - - virtual void PreSave( CSaveRestoreData * ) OVERRIDE; - virtual void Save( CSaveRestoreData * ) OVERRIDE; - virtual void GetSaveComment( char *comment, int maxlength, float flMinutes, float flSeconds, bool bNoTime = false ) OVERRIDE; + virtual CSaveRestoreData *SaveInit( int size ); + virtual void SaveWriteFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ); + virtual void SaveReadFields( CSaveRestoreData *, char const* , void *, datamap_t *, typedescription_t *, int ); + virtual void SaveGlobalState( CSaveRestoreData * ); + virtual void RestoreGlobalState( CSaveRestoreData * ); + virtual int CreateEntityTransitionList( CSaveRestoreData *, int ); + virtual void BuildAdjacentMapList( void ); + + virtual void PreSave( CSaveRestoreData * ); + virtual void Save( CSaveRestoreData * ); + virtual void GetSaveComment( char *comment, int maxlength, float flMinutes, float flSeconds, bool bNoTime = false ); #ifdef _XBOX - virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) OVERRIDE; + virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ); #endif - virtual void WriteSaveHeaders( CSaveRestoreData * ) OVERRIDE; + virtual void WriteSaveHeaders( CSaveRestoreData * ); - virtual void ReadRestoreHeaders( CSaveRestoreData * ) OVERRIDE; - virtual void Restore( CSaveRestoreData *, bool ) OVERRIDE; - virtual bool IsRestoring() OVERRIDE; + virtual void ReadRestoreHeaders( CSaveRestoreData * ); + virtual void Restore( CSaveRestoreData *, bool ); + virtual bool IsRestoring(); // Retrieve info needed for parsing the specified user message - virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ) OVERRIDE; + virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ); - virtual CStandardSendProxies* GetStandardSendProxies() OVERRIDE; + virtual CStandardSendProxies* GetStandardSendProxies(); - virtual void PostInit() OVERRIDE; - virtual void Think( bool finalTick ) OVERRIDE; + virtual void PostInit(); + virtual void Think( bool finalTick ); - virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) OVERRIDE; + virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ); - virtual void PreSaveGameLoaded( char const *pSaveName, bool bInGame ) OVERRIDE; + virtual void PreSaveGameLoaded( char const *pSaveName, bool bInGame ); // Returns true if the game DLL wants the server not to be made public. // Used by commentary system to hide multiplayer commentary servers from the master. - virtual bool ShouldHideServer( void ) OVERRIDE; + virtual bool ShouldHideServer( void ); - virtual void InvalidateMdlCache() OVERRIDE; + virtual void InvalidateMdlCache(); - virtual void SetServerHibernation( bool bHibernating ) OVERRIDE; + virtual void SetServerHibernation( bool bHibernating ); float m_fAutoSaveDangerousTime; float m_fAutoSaveDangerousMinHealthToCommit; bool m_bIsHibernating; // Called after the steam API has been activated post-level startup - virtual void GameServerSteamAPIActivated( void ) OVERRIDE; + virtual void GameServerSteamAPIActivated( void ); // Called after the steam API has been shutdown post-level startup - virtual void GameServerSteamAPIShutdown( void ) OVERRIDE; + virtual void GameServerSteamAPIShutdown( void ); // interface to the new GC based lobby system virtual IServerGCLobby *GetServerGCLobby() OVERRIDE; @@ -138,21 +138,6 @@ class CServerGameDLL : public IServerGameDLL virtual const char *GetServerBrowserMapOverride() OVERRIDE; virtual const char *GetServerBrowserGameData() OVERRIDE; - // Called to add output to the status command - virtual void Status( void (*print) (const char *fmt, ...) ) OVERRIDE; - - virtual void PrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize ) OVERRIDE; - - virtual ePrepareLevelResourcesResult AsyncPrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize, - float *flProgress = NULL ) OVERRIDE; - - virtual eCanProvideLevelResult CanProvideLevel( /* in/out */ char *pMapName, int nMapNameMax ) OVERRIDE; - - // Called to see if the game server is okay with a manual changelevel or map command - virtual bool IsManualMapChangeOkay( const char **pszReason ) OVERRIDE; - private: // This can just be a wrapper on MapEntity_ParseAllEntities, but CS does some tricks in here @@ -224,5 +209,22 @@ class CServerGameTags : public IServerGameTags }; EXPOSE_SINGLE_INTERFACE( CServerGameTags, IServerGameTags, INTERFACEVERSION_SERVERGAMETAGS ); +#ifdef MAPBASE +// +// Dynamic mod-based mod title comments +// +typedef struct +{ + char pBSPName[64]; + char pTitleName[64]; +} MODTITLECOMMENT; + +typedef struct +{ + int iChapter; + char pChapterName[64]; +} MODCHAPTER; +#endif + #endif // GAMEINTERFACE_H diff --git a/game/server/genericactor.cpp b/game/server/genericactor.cpp index dd518a4e..e68411fd 100644 --- a/game/server/genericactor.cpp +++ b/game/server/genericactor.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -17,6 +17,9 @@ #include "tier1/strtools.h" #include "vstdlib/random.h" #include "engine/IEngineSound.h" +#ifdef MAPBASE +#include "ai_speech.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -44,10 +47,13 @@ class CGenericActor : public CAI_BaseActor void HandleAnimEvent( animevent_t *pEvent ); int GetSoundInterests ( void ); - + void TempGunEffect( void ); string_t m_strHullName; +#ifdef MAPBASE + Class_T m_iClassify = CLASS_NONE; +#endif DECLARE_DATADESC(); }; @@ -56,17 +62,24 @@ LINK_ENTITY_TO_CLASS( generic_actor, CGenericActor ); BEGIN_DATADESC( CGenericActor ) DEFINE_KEYFIELD(m_strHullName, FIELD_STRING, "hull_name" ), +#ifdef MAPBASE + DEFINE_INPUT(m_iClassify, FIELD_INTEGER, "SetClassify" ), +#endif END_DATADESC() //========================================================= -// Classify - indicates this NPC's place in the +// Classify - indicates this NPC's place in the // relationship table. //========================================================= Class_T CGenericActor::Classify ( void ) { +#ifdef MAPBASE + return m_iClassify; +#else return CLASS_NONE; +#endif } //========================================================= @@ -111,7 +124,7 @@ void CGenericActor::Spawn() UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); */ - if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || + if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || FStrEq( STRING( GetModelName() ), "models/holo.mdl" ) || FStrEq( STRING( GetModelName() ), "models/blackout.mdl" ) ) { @@ -137,11 +150,16 @@ void CGenericActor::Spawn() m_iHealth = 8; m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) m_NPCState = NPC_STATE_NONE; - + +#ifdef MAPBASE + CapabilitiesAdd( bits_CAP_SQUAD ); + CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_DOORS_GROUP ); +#else CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS ); - +#endif + // remove head turn if no eyes or forward attachment - if (LookupAttachment( "eyes" ) > 0 && LookupAttachment( "forward" ) > 0) + if (LookupAttachment( "eyes" ) > 0 && LookupAttachment( "forward" ) > 0) { CapabilitiesAdd( bits_CAP_TURN_HEAD | bits_CAP_ANIMATEDFACE ); } @@ -165,7 +183,7 @@ void CGenericActor::Spawn() void CGenericActor::Precache() { PrecacheModel( STRING( GetModelName() ) ); -} +} //========================================================= // AI Schedules Specific to this NPC @@ -173,6 +191,164 @@ void CGenericActor::Precache() +#ifdef MAPBASE +//========================================================= +#define TLK_ACTOR_PAIN "TLK_WOUND" +#define TLK_ACTOR_DEATH "TLK_DEATH" +#define TLK_ACTOR_ALERT "TLK_STARTCOMBAT" +#define TLK_ACTOR_IDLE "TLK_IDLE" +#define TLK_ACTOR_FEAR "TLK_FEAR" +#define TLK_ACTOR_LOSTENEMY "TLK_LOSTENEMY" +#define TLK_ACTOR_FOUNDENEMY "TLK_REFINDENEMY" +//========================================================= +// Enhanced generic actor with built-in response system usage, weapon capabilities, and more. +//========================================================= +class CGenericActorCustom : public CGenericActor +{ +private: + DECLARE_CLASS( CGenericActorCustom, CGenericActor ); +public: + //DECLARE_DATADESC(); + + CGenericActorCustom() { } + void Spawn( void ); + void Precache( void ); + + bool KeyValue( const char *szKeyName, const char *szValue ); + + void SpeakIfAllowed( const char *conceptId, AI_CriteriaSet *modifiers = NULL ); + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); + + void PainSound( const CTakeDamageInfo &info ); + void DeathSound( const CTakeDamageInfo &info ); + void AlertSound( void ); + void IdleSound( void ); + void FearSound( void ); + void LostEnemySound( void ); + void FoundEnemySound( void ); +}; + +LINK_ENTITY_TO_CLASS( generic_actor_custom, CGenericActorCustom ); + +//BEGIN_DATADESC( CGenericActorCustom ) +//END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::Spawn() +{ + BaseClass::Spawn(); + + CapabilitiesAdd( bits_CAP_USE_WEAPONS ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::Precache() +{ + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CGenericActorCustom::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (FStrEq(szKeyName, "UseShotRegulator")) + { + if (atoi(szValue) > 0) + CapabilitiesAdd( bits_CAP_USE_SHOT_REGULATOR ); + else + CapabilitiesRemove( bits_CAP_USE_SHOT_REGULATOR ); + + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Speak concept +//----------------------------------------------------------------------------- +void CGenericActorCustom::SpeakIfAllowed( const char *conceptId, AI_CriteriaSet *modifiers ) +{ + AI_CriteriaSet empty; + Speak( conceptId, modifiers ? *modifiers : empty ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::PainSound( const CTakeDamageInfo &info ) +{ + AI_CriteriaSet modifiers; + ModifyOrAppendDamageCriteria( modifiers, info ); + SpeakIfAllowed( TLK_ACTOR_PAIN, &modifiers ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::DeathSound( const CTakeDamageInfo &info ) +{ + AI_CriteriaSet modifiers; + ModifyOrAppendDamageCriteria( modifiers, info ); + SpeakIfAllowed( TLK_ACTOR_DEATH, &modifiers ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::AlertSound( void ) +{ + SpeakIfAllowed( TLK_ACTOR_ALERT ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::IdleSound( void ) +{ + SpeakIfAllowed( TLK_ACTOR_IDLE ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::FearSound( void ) +{ + SpeakIfAllowed( TLK_ACTOR_FEAR ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::LostEnemySound( void ) +{ + SpeakIfAllowed( TLK_ACTOR_LOSTENEMY ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGenericActorCustom::FoundEnemySound( void ) +{ + SpeakIfAllowed( TLK_ACTOR_FOUNDENEMY ); +} +#endif @@ -306,7 +482,7 @@ void CFlextalkActor::ProcessSceneEvents( void ) BaseClass::ProcessSceneEvents( ); return; } - + // only do this if they have more than eyelid movement if (GetNumFlexControllers() > 2) { @@ -340,7 +516,7 @@ void CFlextalkActor::ProcessSceneEvents( void ) { if (*pszExpression == '+') *pszExpression = ' '; - + pszExpression++; } @@ -372,7 +548,7 @@ void CFlextalkActor::ProcessSceneEvents( void ) { m_flexnum = LookupFlex( szTemp ); - if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1) + if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); @@ -383,7 +559,7 @@ void CFlextalkActor::ProcessSceneEvents( void ) } pszExpression++; } - } + } else if (m_flextime < gpGlobals->curtime) { m_flextime = gpGlobals->curtime + random->RandomFloat( 0.3, 0.5 ) * (30.0 / GetNumFlexControllers()); diff --git a/game/server/genericmonster.cpp b/game/server/genericmonster.cpp index ed1be819..71fd197f 100644 --- a/game/server/genericmonster.cpp +++ b/game/server/genericmonster.cpp @@ -17,6 +17,12 @@ #include "physics_bone_follower.h" #include "ai_baseactor.h" #include "ai_senses.h" +#ifdef MAPBASE +/* +#include "ai_basenpc_flyer.h" +#include "player_pickup.h" +*/ +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -470,3 +476,97 @@ void CNPC_Furniture::DrawDebugGeometryOverlays( void ) BaseClass::DrawDebugGeometryOverlays(); } + +#ifdef MAPBASE +/* +//========================================================= +// Generic flying monster +//========================================================= + +class CGenericFlyingMonster : public CAI_BaseFlyingBot +{ +public: + DECLARE_CLASS( CGenericFlyingMonster, CAI_BaseFlyingBot ); + + CGenericFlyingMonster(); + + void Spawn( void ); + void Precache( void ); + int GetSoundInterests ( void ); +}; + +LINK_ENTITY_TO_CLASS( monster_flying_generic, CGenericFlyingMonster ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CGenericFlyingMonster::CGenericFlyingMonster() +{ +} + +//========================================================= +// GetSoundInterests - generic NPC can't hear. +//========================================================= +int CGenericFlyingMonster::GetSoundInterests ( void ) +{ + return NULL; +} + +//========================================================= +// Spawn +//========================================================= +void CGenericFlyingMonster::Spawn() +{ + Precache(); + + SetModel( STRING( GetModelName() ) ); + + if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || FStrEq( STRING( GetModelName() ), "models/holo.mdl" ) ) + UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); + else + UTIL_SetSize(this, NAI_Hull::Mins(HULL_HUMAN), NAI_Hull::Maxs(HULL_HUMAN)); + + SetSolid( SOLID_BBOX ); + AddSolidFlags( FSOLID_NOT_STANDABLE ); + SetMoveType( MOVETYPE_FLY ); + m_bloodColor = BLOOD_COLOR_RED; + m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) + m_NPCState = NPC_STATE_NONE; + + CapabilitiesAdd( bits_CAP_MOVE_FLY ); + + SetNavType( NAV_FLY ); + + AddFlag( FL_FLY ); + + NPCInit(); + if ( !HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) + { + trace_t tr; + UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin(), MASK_SOLID, &tr ); + if ( tr.startsolid ) + { + Msg("Placed npc_generic in solid!!! (%s)\n", STRING(GetModelName()) ); + m_spawnflags |= SF_GENERICNPC_NOTSOLID; + } + } + + if ( HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) + { + AddSolidFlags( FSOLID_NOT_SOLID ); + m_takedamage = DAMAGE_NO; + VPhysicsDestroyObject(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: precaches all resources this NPC needs +//----------------------------------------------------------------------------- +void CGenericFlyingMonster::Precache() +{ + BaseClass::Precache(); + + PrecacheModel( STRING( GetModelName() ) ); +} +*/ +#endif diff --git a/game/server/globalstate.cpp b/game/server/globalstate.cpp index d8da390c..720e8906 100644 --- a/game/server/globalstate.cpp +++ b/game/server/globalstate.cpp @@ -131,7 +131,9 @@ class CGlobalState : public CAutoGameSystem entity.name = m_nameList.AddString( pGlobalname ); entity.levelName = m_nameList.AddString( pMapName ); entity.state = state; +#ifdef MAPBASE entity.counter = 0; +#endif int index = GetIndex( m_nameList.String( entity.name ) ); if ( index >= 0 ) @@ -144,6 +146,28 @@ class CGlobalState : public CAutoGameSystem return m_list.Count(); } +#ifdef MAPBASE_VSCRIPT + virtual void RegisterVScript() + { + g_pScriptVM->RegisterInstance( this, "Globals" ); + } + + int ScriptAddEntity( const char *pGlobalname, const char *pMapName, int state ) + { + return AddEntity( pGlobalname, pMapName, (GLOBALESTATE)state ); + } + + void ScriptSetState( int globalIndex, int state ) + { + SetState( globalIndex, (GLOBALESTATE)state ); + } + + int ScriptGetState( int globalIndex ) + { + return (int)GetState( globalIndex ); + } +#endif + void Reset( void ); int Save( ISave &save ); int Restore( IRestore &restore ); @@ -324,3 +348,15 @@ CON_COMMAND(server_game_time, "Gives the game time in seconds (server's curtime) ShowServerGameTime(); } + +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CGlobalState, SCRIPT_SINGLETON "Global state system." ) + DEFINE_SCRIPTFUNC( GetIndex, "Gets the index of the specified global name. Returns -1 if it does not exist." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddEntity, "AddGlobal", "Adds a new global with a specific map name and state. Returns its index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetState, "GetState", "Gets the state of the specified global." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetState, "SetState", "Sets the state of the specified global." ) + DEFINE_SCRIPTFUNC( GetCounter, "Gets the counter of the specified global." ) + DEFINE_SCRIPTFUNC( SetCounter, "Sets the counter of the specified global." ) + DEFINE_SCRIPTFUNC( AddToCounter, "Adds to the counter of the specified global." ) +END_SCRIPTDESC(); +#endif diff --git a/game/server/hl2/ai_behavior_actbusy.cpp b/game/server/hl2/ai_behavior_actbusy.cpp index 9f1ac3ef..31762003 100644 --- a/game/server/hl2/ai_behavior_actbusy.cpp +++ b/game/server/hl2/ai_behavior_actbusy.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -18,6 +18,9 @@ #include "SoundEmitterSystem/isoundemittersystembase.h" #include "entityblocker.h" #include "npcevent.h" +#ifdef MAPBASE +#include "interval.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -58,6 +61,9 @@ BEGIN_DATADESC( CAI_ActBusyBehavior ) DEFINE_FIELD( m_bInQueue, FIELD_BOOLEAN ), DEFINE_FIELD( m_iCurrentBusyAnim, FIELD_INTEGER ), DEFINE_FIELD( m_hActBusyGoal, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_FIELD( m_hNextActBusyGoal, FIELD_EHANDLE ), +#endif DEFINE_FIELD( m_bNeedToSetBounds, FIELD_BOOLEAN ), DEFINE_FIELD( m_hSeeEntity, FIELD_EHANDLE ), DEFINE_FIELD( m_fTimeLastSawSeeEntity, FIELD_TIME ), @@ -65,6 +71,9 @@ BEGIN_DATADESC( CAI_ActBusyBehavior ) DEFINE_FIELD( m_bExitedBusyToDueSeeEnemy, FIELD_BOOLEAN ), DEFINE_FIELD( m_iNumConsecutivePathFailures, FIELD_INTEGER ), DEFINE_FIELD( m_bAutoFireWeapon, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_FIELD( m_flNextAutoFireTime, FIELD_TIME ), +#endif DEFINE_FIELD( m_flDeferUntil, FIELD_TIME ), DEFINE_FIELD( m_iNumEnemiesInSafeZone, FIELD_INTEGER ), END_DATADESC(); @@ -91,7 +100,11 @@ class CActBusyAnimData : public CAutoGameSystem virtual void LevelShutdownPostEntity( void ); // Read in the data from the anim data file +#ifdef MAPBASE + void ParseAnimDataFile( const char *file = "scripts/actbusy.txt" ); +#else void ParseAnimDataFile( void ); +#endif // Parse a keyvalues section into an act busy anim bool ParseActBusyFromKV( busyanim_t *pAnim, KeyValues *pSection ); @@ -107,6 +120,13 @@ class CActBusyAnimData : public CAutoGameSystem CActBusyAnimData g_ActBusyAnimDataSystem; +#ifdef MAPBASE +void ParseCustomActbusyFile( const char *file ) +{ + g_ActBusyAnimDataSystem.ParseAnimDataFile(file); +} +#endif + //----------------------------------------------------------------------------- // Inherited from IAutoServerSystem //----------------------------------------------------------------------------- @@ -116,7 +136,7 @@ void CActBusyAnimData::LevelInitPostEntity( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CActBusyAnimData::LevelShutdownPostEntity( void ) { @@ -126,10 +146,18 @@ void CActBusyAnimData::LevelShutdownPostEntity( void ) //----------------------------------------------------------------------------- // Clear out the stats + their history //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CActBusyAnimData::ParseAnimDataFile( const char *file ) +#else void CActBusyAnimData::ParseAnimDataFile( void ) +#endif { KeyValues *pKVAnimData = new KeyValues( "ActBusyAnimDatafile" ); +#ifdef MAPBASE + if ( pKVAnimData->LoadFromFile( filesystem, file ) ) +#else if ( pKVAnimData->LoadFromFile( filesystem, "scripts/actbusy.txt" ) ) +#endif { // Now try and parse out each act busy anim KeyValues *pKVAnim = pKVAnimData->GetFirstSubKey(); @@ -147,7 +175,7 @@ void CActBusyAnimData::ParseAnimDataFile( void ) } } pKVAnimData->deleteThis(); -} +} //----------------------------------------------------------------------------- // Purpose: Parse a keyvalues section into the prop @@ -170,7 +198,7 @@ bool CActBusyAnimData::ParseActBusyFromKV( busyanim_t *pAnim, KeyValues *pSectio pAnim->iszSounds[BA_BUSY] = AllocPooledString( pSection->GetString( "busy_sound", NULL ) ); pAnim->iszSounds[BA_ENTRY] = AllocPooledString( pSection->GetString( "entry_sound", NULL ) ); pAnim->iszSounds[BA_EXIT] = AllocPooledString( pSection->GetString( "exit_sound", NULL ) ); - + // Times pAnim->flMinTime = pSection->GetFloat( "min_time", 10.0 ); pAnim->flMaxTime = pSection->GetFloat( "max_time", 20.0 ); @@ -207,6 +235,10 @@ bool CActBusyAnimData::ParseActBusyFromKV( busyanim_t *pAnim, KeyValues *pSectio pAnim->iBusyInterruptType = BA_INT_NONE; } +#ifdef MAPBASE + pAnim->bTranslateActivity = pSection->GetBool("translateactivity", false); +#endif + return true; } @@ -244,7 +276,7 @@ int CActBusyAnimData::FindBusyAnim( Activity iActivity, const char *pSequence ) //============================================================================================================= //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CAI_ActBusyBehavior::CAI_ActBusyBehavior() { @@ -256,7 +288,7 @@ CAI_ActBusyBehavior::CAI_ActBusyBehavior() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::Enable( CAI_ActBusyGoal *pGoal, float flRange, bool bVisibleOnly ) { @@ -271,7 +303,11 @@ void CAI_ActBusyBehavior::Enable( CAI_ActBusyGoal *pGoal, float flRange, bool bV m_bMovingToBusy = false; m_bNeedsToPlayExitAnim = false; m_bLeaving = false; +#ifdef MAPBASE + m_flNextBusySearchTime = gpGlobals->curtime + (m_hActBusyGoal.Get() ? m_hActBusyGoal->NextBusySearchInterval().start : ai_actbusy_search_time.GetFloat()); +#else m_flNextBusySearchTime = gpGlobals->curtime + ai_actbusy_search_time.GetFloat(); +#endif m_flEndBusyAt = 0; m_bVisibleOnly = bVisibleOnly; m_bInQueue = dynamic_cast(m_hActBusyGoal.Get()) != NULL; @@ -321,7 +357,7 @@ void CAI_ActBusyBehavior::OnRestore() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::SetBusySearchRange( float flRange ) { @@ -329,7 +365,7 @@ void CAI_ActBusyBehavior::SetBusySearchRange( float flRange ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::Disable( void ) { @@ -348,12 +384,22 @@ void CAI_ActBusyBehavior::Disable( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::ForceActBusy( CAI_ActBusyGoal *pGoal, CAI_Hint *pHintNode, float flMaxTime, bool bVisibleOnly, bool bTeleportToBusy, bool bUseNearestBusy, CBaseEntity *pSeeEntity, Activity activity ) { Assert( !m_bLeaving ); +#ifdef MAPBASE + if ( m_bNeedsToPlayExitAnim && !bTeleportToBusy ) + { + if ( HasAnimForActBusy( m_iCurrentBusyAnim, BA_EXIT ) ) + { + m_hNextActBusyGoal = pGoal; + //m_bNextActBusyVisOnly = bVisibleOnly; + } + } +#else if ( m_bNeedsToPlayExitAnim ) { // If we hit this, the mapmaker's told this NPC to actbusy somewhere while it's still in an actbusy. @@ -364,6 +410,7 @@ void CAI_ActBusyBehavior::ForceActBusy( CAI_ActBusyGoal *pGoal, CAI_Hint *pHintN return; } } +#endif if ( ai_debug_actbusy.GetInt() == 4 ) { @@ -379,7 +426,18 @@ void CAI_ActBusyBehavior::ForceActBusy( CAI_ActBusyGoal *pGoal, CAI_Hint *pHintN Msg("\n"); } +#ifdef MAPBASE + if (!m_hNextActBusyGoal) + { + Enable( pGoal, m_flBusySearchRange, bVisibleOnly ); + } + else + { + Enable( NULL, m_flBusySearchRange, bVisibleOnly ); + } +#else Enable( pGoal, m_flBusySearchRange, bVisibleOnly ); +#endif m_bForceActBusy = true; m_flForcedMaxTime = flMaxTime; m_bTeleportToBusy = bTeleportToBusy; @@ -516,13 +574,13 @@ CAI_Hint *CAI_ActBusyBehavior::FindCombatActBusyHintNode() // -The player can see // -Is within the accepted max dist from player int iBits = bits_HINT_NODE_USE_GROUP; - + if ( m_bVisibleOnly ) iBits |= bits_HINT_NODE_VISIBLE; - + if ( ai_debug_actbusy.GetInt() == 3 && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) iBits |= bits_HINT_NODE_REPORT_FAILURES; - + if ( m_bUseNearestBusy ) iBits |= bits_HINT_NODE_NEAREST; else @@ -575,7 +633,7 @@ CAI_Hint *CAI_ActBusyBehavior::FindCombatActBusyTeleportHintNode() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::FValidateHintType( CAI_Hint *pHint ) { @@ -611,7 +669,7 @@ bool CAI_ActBusyBehavior::FValidateHintType( CAI_Hint *pHint ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::CanSelectSchedule( void ) { @@ -627,7 +685,7 @@ bool CAI_ActBusyBehavior::CanSelectSchedule( void ) if ( CountEnemiesInSafeZone() > 0 ) { - // I have enemies left in the safe zone. Actbusy isn't appropriate. + // I have enemies left in the safe zone. Actbusy isn't appropriate. // I should be off fighting them. return false; } @@ -655,13 +713,13 @@ bool CAI_ActBusyBehavior::IsCurScheduleOverridable( void ) if ( GetOuter()->IsInAVehicle() ) return false; - // Only if we're about to idle (or SCHED_NONE to catch newly spawned guys) + // Only if we're about to idle (or SCHED_NONE to catch newly spawned guys) return ( IsCurSchedule( SCHED_IDLE_STAND ) || IsCurSchedule( SCHED_NONE ) ); } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pSound - +// Purpose: +// Input : *pSound - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::ShouldIgnoreSound( CSound *pSound ) @@ -699,11 +757,16 @@ bool CAI_ActBusyBehavior::ShouldIgnoreSound( CSound *pSound ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker ) { +#ifdef MAPBASE + // Now that this has been extended beyond Alyx, it doesn't just need to be the player anymore + if( IsCombatActBusy() && IsInSafeZone( pAttacker ) ) +#else if( IsCombatActBusy() && pSquadmate->IsPlayer() && IsInSafeZone( pAttacker ) ) +#endif { SetCondition( COND_ACTBUSY_AWARE_OF_ENEMY_IN_SAFE_ZONE ); // Break the actbusy, if we're running it. m_flDeferUntil = gpGlobals->curtime + 4.0f; // Stop actbusying and go deal with that enemy!! @@ -716,10 +779,10 @@ void CAI_ActBusyBehavior::OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBa // Purpose: Count the number of enemies of mine that are inside my safe zone // volume. // -// NOTE: We keep this count to prevent the NPC re-entering combat +// NOTE: We keep this count to prevent the NPC re-entering combat // actbusy whilst too many enemies are present in the safe zone. // This count does not automatically alert the NPC that there are -// enemies in the safe zone. +// enemies in the safe zone. // You must set COND_ACTBUSY_AWARE_OF_ENEMY_IN_SAFE_ZONE to let // the NPC know. //----------------------------------------------------------------------------- @@ -731,7 +794,7 @@ int CAI_ActBusyBehavior::CountEnemiesInSafeZone() } // Grovel the AI list and count the enemies in the zone. By enemies, I mean - // anyone that I would fight if I saw. + // anyone that I would fight if I saw. CAI_BaseNPC ** ppAIs = g_AI_Manager.AccessAIs(); int nAIs = g_AI_Manager.NumAIs(); int count = 0; @@ -751,7 +814,7 @@ int CAI_ActBusyBehavior::CountEnemiesInSafeZone() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_ActBusyBehavior::OnTakeDamage_Alive( const CTakeDamageInfo &info ) { @@ -765,7 +828,7 @@ int CAI_ActBusyBehavior::OnTakeDamage_Alive( const CTakeDamageInfo &info ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::GatherConditions( void ) { @@ -773,7 +836,7 @@ void CAI_ActBusyBehavior::GatherConditions( void ) // set this condition if it is relevant. if( !IsCurSchedule(SCHED_ACTBUSY_BUSY, false) ) { - // Only clear this condition when we aren't busying. We want it to be sticky + // Only clear this condition when we aren't busying. We want it to be sticky // during that time so that schedule selection works properly (sjb) ClearCondition( COND_ACTBUSY_ENEMY_TOO_CLOSE ); } @@ -804,7 +867,12 @@ void CAI_ActBusyBehavior::GatherConditions( void ) SetCondition( COND_ACTBUSY_LOST_SEE_ENTITY ); m_hActBusyGoal->NPCLostSeeEntity( GetOuter() ); +#ifdef MAPBASE + // Now that this has been extended beyond Alyx, this could just apply to player allies in general + if( IsCombatActBusy() && (m_hSeeEntity->IsPlayer() && GetOuter()->IsPlayerAlly()) ) +#else if( IsCombatActBusy() && (GetOuter()->Classify() == CLASS_PLAYER_ALLY_VITAL && m_hSeeEntity->IsPlayer()) ) +#endif { // Defer any actbusying for several seconds. This serves as a heuristic for waiting // for the player to settle after moving out of the room. This helps Alyx pick a more @@ -892,13 +960,21 @@ void CAI_ActBusyBehavior::GatherConditions( void ) } } +#ifdef MAPBASE + if( m_bAutoFireWeapon && m_flNextAutoFireTime <= gpGlobals->curtime && random->RandomInt(0, 4) <= 3 ) +#else if( m_bAutoFireWeapon && random->RandomInt(0, 5) <= 3 ) +#endif { CBaseCombatWeapon *pWeapon = GetOuter()->GetActiveWeapon(); if( pWeapon ) { pWeapon->Operator_ForceNPCFire( GetOuter(), false ); +#ifdef MAPBASE + pWeapon->DoMuzzleFlash(); + m_flNextAutoFireTime = gpGlobals->curtime + pWeapon->GetFireRate(); +#endif } } @@ -918,7 +994,7 @@ void CAI_ActBusyBehavior::GatherConditions( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::EndScheduleSelection( void ) { @@ -928,8 +1004,8 @@ void CAI_ActBusyBehavior::EndScheduleSelection( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : nActivity - +// Purpose: +// Input : nActivity - //----------------------------------------------------------------------------- Activity CAI_ActBusyBehavior::NPC_TranslateActivity( Activity nActivity ) { @@ -988,7 +1064,7 @@ void CAI_ActBusyBehavior::CheckAndCleanupOnExit( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::BuildScheduleTestBits( void ) { @@ -1085,7 +1161,7 @@ void CAI_ActBusyBehavior::BuildScheduleTestBits( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_ActBusyBehavior::SelectScheduleForLeaving( void ) { @@ -1144,7 +1220,7 @@ int CAI_ActBusyBehavior::SelectScheduleForLeaving( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) { @@ -1158,7 +1234,11 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) } else { +#ifdef MAPBASE + m_flNextBusySearchTime = gpGlobals->curtime + (m_hActBusyGoal ? RandomInterval(m_hActBusyGoal->NextBusySearchInterval()) : RandomFloat(ai_actbusy_search_time.GetFloat(), ai_actbusy_search_time.GetFloat()*2)); +#else m_flNextBusySearchTime = gpGlobals->curtime + RandomFloat(ai_actbusy_search_time.GetFloat(), ai_actbusy_search_time.GetFloat()*2); +#endif } // We may already have a node @@ -1168,7 +1248,7 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) { if( IsCombatActBusy() ) { - if ( m_hActBusyGoal->IsCombatActBusyTeleportAllowed() && m_iNumConsecutivePathFailures >= 2 && !AI_GetSinglePlayer()->FInViewCone(GetOuter()) ) + if ( m_hActBusyGoal->IsCombatActBusyTeleportAllowed() && m_iNumConsecutivePathFailures >= 2 && !AI_GetSinglePlayer()->FInViewCone(GetOuter()) ) { // Looks like I've tried several times to find a path to a valid hint node and // haven't been able to. This means I'm on a patch of node graph that simply @@ -1206,12 +1286,12 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) char sActOrSeqName[512]; Q_strncpy( sActOrSeqName, pSequenceOrActivity, (cSpace-pSequenceOrActivity)+1 ); - iNodeActivity = (Activity)CAI_BaseNPC::GetActivityID( sActOrSeqName ); + iNodeActivity = (Activity)CAI_BaseNPC::GetActivityID( sActOrSeqName ); iBusyAnim = g_ActBusyAnimDataSystem.FindBusyAnim( iNodeActivity, sActOrSeqName ); } else { - iNodeActivity = (Activity)CAI_BaseNPC::GetActivityID( pSequenceOrActivity ); + iNodeActivity = (Activity)CAI_BaseNPC::GetActivityID( pSequenceOrActivity ); iBusyAnim = g_ActBusyAnimDataSystem.FindBusyAnim( iNodeActivity, pSequenceOrActivity ); } @@ -1268,7 +1348,7 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) m_hSeeEntity.Set( gEntList.FindEntityByName(NULL, m_hActBusyGoal->m_iszSeeEntityName) ); } - // At this point we know we're starting. + // At this point we know we're starting. ClearCondition( COND_ACTBUSY_AWARE_OF_ENEMY_IN_SAFE_ZONE ); // If we're supposed to teleport, do that instead @@ -1303,7 +1383,7 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_ActBusyBehavior::SelectScheduleWhileBusy( void ) { @@ -1328,7 +1408,7 @@ int CAI_ActBusyBehavior::SelectScheduleWhileBusy( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_ActBusyBehavior::SelectSchedule() { @@ -1349,6 +1429,23 @@ int CAI_ActBusyBehavior::SelectSchedule() if ( m_bLeaving ) return SelectScheduleForLeaving(); +#ifdef MAPBASE + if (m_hNextActBusyGoal) + { + if (m_bBusy) + { + m_flEndBusyAt = gpGlobals->curtime; + } + else + { + // Next busy + // (the parameters should've been safely stored when we transferred) + Enable(m_hNextActBusyGoal, m_flBusySearchRange, m_bVisibleOnly); + m_hNextActBusyGoal = NULL; + } + } +#endif + // NPCs should not be busy if the actbusy behaviour has been disabled, or if they've received player squad commands bool bShouldNotBeBusy = (!m_bEnabled || HasCondition( COND_PLAYER_ADDED_TO_SQUAD ) || HasCondition( COND_RECEIVED_ORDERS ) ); if ( bShouldNotBeBusy ) @@ -1372,18 +1469,18 @@ int CAI_ActBusyBehavior::SelectSchedule() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::ActBusyNodeStillActive( void ) { if ( !GetHintNode() ) return false; - + return ( GetHintNode()->IsDisabled() == false ); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::IsInterruptable( void ) @@ -1395,7 +1492,7 @@ bool CAI_ActBusyBehavior::IsInterruptable( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::CanFlinch( void ) @@ -1407,7 +1504,7 @@ bool CAI_ActBusyBehavior::CanFlinch( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::CanRunAScriptedNPCInteraction( bool bForced ) { @@ -1419,7 +1516,7 @@ bool CAI_ActBusyBehavior::CanRunAScriptedNPCInteraction( bool bForced ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::OnScheduleChange() { @@ -1440,12 +1537,12 @@ void CAI_ActBusyBehavior::OnScheduleChange() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::QueryHearSound( CSound *pSound ) { // Ignore friendly created combat sounds while in an actbusy. - // Fixes friendly NPCs going in & out of actbusies when the + // Fixes friendly NPCs going in & out of actbusies when the // player fires shots at their feet. if ( pSound->IsSoundType( SOUND_COMBAT ) || pSound->IsSoundType( SOUND_BULLET_IMPACT ) ) { @@ -1476,7 +1573,7 @@ void CAI_ActBusyBehavior::OnSeeEntity( CBaseEntity *pEntity ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_ActBusyBehavior::ShouldPlayerAvoid( void ) @@ -1615,7 +1712,20 @@ bool CAI_ActBusyBehavior::HasAnimForActBusy( int iActBusy, busyanimparts_t AnimP // Try and play the activity second if ( pBusyAnim->iActivities[AnimPart] != ACT_INVALID ) +#ifdef MAPBASE + { + if (pBusyAnim->bTranslateActivity == true) + { + return GetOuter()->HaveSequenceForActivity( GetOuter()->TranslateActivity(pBusyAnim->iActivities[AnimPart]) ); + } + else + { + return GetOuter()->HaveSequenceForActivity( pBusyAnim->iActivities[AnimPart] ); + } + } +#else return GetOuter()->HaveSequenceForActivity( pBusyAnim->iActivities[AnimPart] ); +#endif return false; } @@ -1645,12 +1755,16 @@ void CAI_ActBusyBehavior::PlaySoundForActBusy( busyanimparts_t AnimPart ) CAI_Expresser *pExpresser = GetOuter()->GetExpresser(); if ( pExpresser ) { - const char *concept = STRING(pBusyAnim->iszSounds[AnimPart]); +#ifdef NEW_RESPONSE_SYSTEM + CAI_Concept conceptId = STRING(pBusyAnim->iszSounds[AnimPart]); +#else + const char *conceptId = STRING(pBusyAnim->iszSounds[AnimPart]); +#endif // Must be able to speak the concept - if ( !pExpresser->IsSpeaking() && pExpresser->CanSpeakConcept( concept ) ) + if ( !pExpresser->IsSpeaking() && pExpresser->CanSpeakConcept( conceptId ) ) { - pExpresser->Speak( concept ); + pExpresser->Speak( conceptId ); } } } @@ -1677,7 +1791,11 @@ bool CAI_ActBusyBehavior::PlayAnimForActBusy( busyanimparts_t AnimPart ) // Try and play the activity second if ( pBusyAnim->iActivities[AnimPart] != ACT_INVALID ) { +#ifdef MAPBASE + GetOuter()->SetIdealActivity( pBusyAnim->bTranslateActivity ? GetOuter()->TranslateActivity(pBusyAnim->iActivities[AnimPart]) : pBusyAnim->iActivities[AnimPart] ); +#else GetOuter()->SetIdealActivity( pBusyAnim->iActivities[AnimPart] ); +#endif return true; } @@ -1685,7 +1803,7 @@ bool CAI_ActBusyBehavior::PlayAnimForActBusy( busyanimparts_t AnimPart ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::StartTask( const Task_t *pTask ) { @@ -1723,7 +1841,7 @@ void CAI_ActBusyBehavior::StartTask( const Task_t *pTask ) // We only do this check if we're still moving to the busy. This will only // be true if there was no entry animation for this busy. We do it this way // because the entry code contains this same check, and so we assume we're - // valid even if we're off now, because some entry animations move the + // valid even if we're off now, because some entry animations move the // character off the node. if ( m_bMovingToBusy ) { @@ -1854,13 +1972,13 @@ void CAI_ActBusyBehavior::StartTask( const Task_t *pTask ) // before they exit their actbusy. This task is designed to delay until that time if necessary. if( !m_bUseRenderBoundsForCollision ) { - // Don't bother if we didn't alter our BBox. + // Don't bother if we didn't alter our BBox. TaskComplete(); break; } // Set up a timer to check immediately. - GetOuter()->SetWait( 0 ); + GetOuter()->SetWait( 0 ); } break; @@ -1994,10 +2112,10 @@ void CAI_ActBusyBehavior::StartTask( const Task_t *pTask ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -void CAI_ActBusyBehavior::RunTask( const Task_t *pTask ) -{ +void CAI_ActBusyBehavior::RunTask( const Task_t *pTask ) +{ switch ( pTask->iTask ) { case TASK_WAIT_FOR_MOVEMENT: @@ -2131,7 +2249,7 @@ void CAI_ActBusyBehavior::RunTask( const Task_t *pTask ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyBehavior::NotifyBusyEnding( void ) { @@ -2196,7 +2314,11 @@ void CAI_ActBusyBehavior::NotifyBusyEnding( void ) } else { +#ifdef MAPBASE + m_flNextBusySearchTime = gpGlobals->curtime + (m_hActBusyGoal ? RandomInterval(m_hActBusyGoal->NextBusySearchInterval()) : RandomFloat(ai_actbusy_search_time.GetFloat(), ai_actbusy_search_time.GetFloat()*2)); +#else m_flNextBusySearchTime = gpGlobals->curtime + (RandomFloat(ai_actbusy_search_time.GetFloat(), ai_actbusy_search_time.GetFloat()*2)); +#endif } } @@ -2222,7 +2344,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ActBusyBehavior ) //--------------------------------- DEFINE_SCHEDULE - ( + ( SCHED_ACTBUSY_START_BUSYING, " Tasks" @@ -2240,7 +2362,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ActBusyBehavior ) ) DEFINE_SCHEDULE - ( + ( SCHED_ACTBUSY_BUSY, " Tasks" @@ -2251,7 +2373,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ActBusyBehavior ) ) DEFINE_SCHEDULE - ( + ( SCHED_ACTBUSY_STOP_BUSYING, " Tasks" @@ -2264,7 +2386,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ActBusyBehavior ) ) DEFINE_SCHEDULE - ( + ( SCHED_ACTBUSY_LEAVE, " Tasks" @@ -2278,7 +2400,7 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ActBusyBehavior ) ) DEFINE_SCHEDULE - ( + ( SCHED_ACTBUSY_TELEPORT_TO_BUSY, " Tasks" @@ -2306,6 +2428,12 @@ BEGIN_DATADESC( CAI_ActBusyGoal ) DEFINE_KEYFIELD( m_bVisibleOnly, FIELD_BOOLEAN, "visibleonly" ), DEFINE_KEYFIELD( m_iType, FIELD_INTEGER, "type" ), DEFINE_KEYFIELD( m_bAllowCombatActBusyTeleport, FIELD_BOOLEAN, "allowteleport" ), +#ifdef MAPBASE + // interval_t's can be saved. No instance of its use exists in vanilla Source 2013, + // so it's either an unused field type or something used in the engine. It appears to be functional either way. + // I added built-in keyvalue support as an experiment, and this keyvalue is part of said experiment. + DEFINE_KEYFIELD( m_NextBusySearch, FIELD_INTERVAL, "NextBusy" ), +#endif DEFINE_KEYFIELD( m_iszSeeEntityName, FIELD_STRING, "SeeEntity" ), DEFINE_KEYFIELD( m_flSeeEntityTimeout, FIELD_FLOAT, "SeeEntityTimeout" ), DEFINE_KEYFIELD( m_iszSafeZoneVolume, FIELD_STRING, "SafeZone" ), @@ -2316,17 +2444,35 @@ BEGIN_DATADESC( CAI_ActBusyGoal ) DEFINE_INPUTFUNC( FIELD_STRING, "ForceNPCToActBusy", InputForceNPCToActBusy ), DEFINE_INPUTFUNC( FIELD_EHANDLE, "ForceThisNPCToActBusy", InputForceThisNPCToActBusy ), DEFINE_INPUTFUNC( FIELD_EHANDLE, "ForceThisNPCToLeave", InputForceThisNPCToLeave ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "ForceThisNPCToStopBusy", InputForceThisNPCToStopBusy ), +#endif // Outputs DEFINE_OUTPUT( m_OnNPCStartedBusy, "OnNPCStartedBusy" ), DEFINE_OUTPUT( m_OnNPCFinishedBusy, "OnNPCFinishedBusy" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnNPCStartedLeavingBusy, "OnNPCStartedLeavingBusy" ), + DEFINE_OUTPUT( m_OnNPCMovingToBusy, "OnNPCMovingToBusy" ), + DEFINE_OUTPUT( m_OnNPCAbortedMoveTo, "OnNPCAbortedMoveTo" ), +#endif DEFINE_OUTPUT( m_OnNPCLeft, "OnNPCLeft" ), DEFINE_OUTPUT( m_OnNPCLostSeeEntity, "OnNPCLostSeeEntity" ), DEFINE_OUTPUT( m_OnNPCSeeEnemy, "OnNPCSeeEnemy" ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CAI_ActBusyGoal, CAI_GoalEntity, "A goal entity which makes NPCs act busy." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptForceBusy, "ForceBusy", "Force a NPC to act busy." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptForceBusyComplex, "ForceBusyComplex", "Force a NPC to act busy with additional parameters." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptStopBusy, "StopBusy", "Force a NPC to stop busying." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CAI_ActBusyBehavior *CAI_ActBusyGoal::GetBusyBehaviorForNPC( CBaseEntity *pEntity, const char *sInputName ) { @@ -2349,7 +2495,7 @@ CAI_ActBusyBehavior *CAI_ActBusyGoal::GetBusyBehaviorForNPC( CBaseEntity *pEntit } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CAI_ActBusyBehavior *CAI_ActBusyGoal::GetBusyBehaviorForNPC( const char *pszActorName, CBaseEntity *pActivator, CBaseEntity *pCaller, const char *sInputName ) { @@ -2364,8 +2510,8 @@ CAI_ActBusyBehavior *CAI_ActBusyGoal::GetBusyBehaviorForNPC( const char *pszActo } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::EnableGoal( CAI_BaseNPC *pAI ) { @@ -2389,8 +2535,8 @@ void CAI_ActBusyGoal::EnableGoal( CAI_BaseNPC *pAI ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::InputActivate( inputdata_t &inputdata ) { @@ -2403,8 +2549,8 @@ void CAI_ActBusyGoal::InputActivate( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::InputDeactivate( inputdata_t &inputdata ) { @@ -2437,7 +2583,7 @@ void CAI_ActBusyGoal::InputDeactivate( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyGoal::InputSetBusySearchRange( inputdata_t &inputdata ) { @@ -2460,7 +2606,7 @@ void CAI_ActBusyGoal::InputSetBusySearchRange( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyGoal::InputForceNPCToActBusy( inputdata_t &inputdata ) { @@ -2485,7 +2631,7 @@ void CAI_ActBusyGoal::InputForceNPCToActBusy( inputdata_t &inputdata ) // Do we have a specified node too? pszParam = strtok(NULL," "); if ( pszParam ) - { + { // Find the specified hintnode CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, pszParam, NULL, inputdata.pActivator, inputdata.pCaller ); if ( pEntity ) @@ -2539,7 +2685,7 @@ void CAI_ActBusyGoal::InputForceNPCToActBusy( inputdata_t &inputdata ) activity = ACT_SCRIPT_CUSTOM_MOVE; } } - else + else { // Do we have a specified time? flMaxTime = atof( pszParam ); @@ -2586,17 +2732,42 @@ void CAI_ActBusyGoal::InputForceThisNPCToLeave( inputdata_t &inputdata ) pBehavior->ForceActBusyLeave(); } +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: Forces a specific NPC to stop acting busy +//----------------------------------------------------------------------------- +void CAI_ActBusyGoal::InputForceThisNPCToStopBusy( inputdata_t &inputdata ) +{ + CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( inputdata.value.Entity(), "InputForceThisNPCToStopBusy" ); + if ( !pBehavior ) + return; + + if (!IsActive() && pBehavior->GetActBusyGoal() == this) + { + pBehavior->Disable(); + } + else + { + // Just stop busying + pBehavior->StopBusying(); + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCMovingToBusy( CAI_BaseNPC *pNPC ) { +#ifdef MAPBASE + m_OnNPCMovingToBusy.Set( pNPC, pNPC, this ); +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCStartedBusy( CAI_BaseNPC *pNPC ) { @@ -2604,23 +2775,29 @@ void CAI_ActBusyGoal::NPCStartedBusy( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCStartedLeavingBusy( CAI_BaseNPC *pNPC ) { +#ifdef MAPBASE + m_OnNPCStartedLeavingBusy.Set( pNPC, pNPC, this ); +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCAbortedMoveTo( CAI_BaseNPC *pNPC ) { +#ifdef MAPBASE + m_OnNPCAbortedMoveTo.Set( pNPC, pNPC, this ); +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCFinishedBusy( CAI_BaseNPC *pNPC ) { @@ -2628,8 +2805,8 @@ void CAI_ActBusyGoal::NPCFinishedBusy( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyGoal::NPCLeft( CAI_BaseNPC *pNPC ) { @@ -2650,11 +2827,69 @@ void CAI_ActBusyGoal::NPCSeeEnemy( CAI_BaseNPC *pNPC ) m_OnNPCSeeEnemy.Set( pNPC, pNPC, this ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +interval_t &CAI_ActBusyGoal::NextBusySearchInterval() +{ + if (m_NextBusySearch.start == 0) + { + // Return an interval_t version of the convar + static interval_t defaultInterval; + defaultInterval.start = ai_actbusy_search_time.GetFloat(); + defaultInterval.range = ai_actbusy_search_time.GetFloat(); // Range is end - start, so we don't have to multiply it here + return defaultInterval; + } + + return m_NextBusySearch; +} +#endif + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_ActBusyGoal::ScriptForceBusy( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly ) +{ + CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "ForceBusy (vscript)" ); + if ( !pBehavior ) + return; + + // Tell the NPC to immediately act busy + pBehavior->SetBusySearchRange( m_flBusySearchRange ); + pBehavior->ForceActBusy( this, dynamic_cast(ToEnt( hHint )), NO_MAX_TIME, false, bTeleportOnly ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_ActBusyGoal::ScriptForceBusyComplex( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly, bool bVisibleOnly, bool bUseNearestBusy, float flMaxTime, int activity, HSCRIPT pSeeEntity ) +{ + CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "ForceBusyComplex (vscript)" ); + if ( !pBehavior ) + return; + + // Tell the NPC to immediately act busy + pBehavior->SetBusySearchRange( m_flBusySearchRange ); + pBehavior->ForceActBusy( this, dynamic_cast(ToEnt( hHint )), flMaxTime, bVisibleOnly, bTeleportOnly, bUseNearestBusy, ToEnt( pSeeEntity ), (Activity)activity ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CAI_ActBusyGoal::ScriptStopBusy( HSCRIPT hNPC ) +{ + CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "StopBusy (vscript)" ); + if ( !pBehavior ) + return; + + // Just stop busying + pBehavior->StopBusying(); +} +#endif + //========================================================================================================== // ACT BUSY QUEUE //========================================================================================================== //----------------------------------------------------------------------------- -// Purpose: A level tool to control the actbusy behavior to create NPC queues +// Purpose: A level tool to control the actbusy behavior to create NPC queues //----------------------------------------------------------------------------- LINK_ENTITY_TO_CLASS( ai_goal_actbusy_queue, CAI_ActBusyQueueGoal ); @@ -2708,7 +2943,7 @@ END_DATADESC() #define QUEUE_MOVEUP_THINK_CONTEXT "ActBusyQueueMoveUpThinkContext" //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::Spawn( void ) { @@ -2718,7 +2953,7 @@ void CAI_ActBusyQueueGoal::Spawn( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::DrawDebugGeometryOverlays( void ) { @@ -2741,7 +2976,7 @@ void CAI_ActBusyQueueGoal::DrawDebugGeometryOverlays( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::InputActivate( inputdata_t &inputdata ) { @@ -2800,8 +3035,8 @@ void CAI_ActBusyQueueGoal::InputActivate( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : iCount - +// Purpose: +// Input : iCount - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::RecalculateQueueCount( void ) { @@ -2853,8 +3088,8 @@ void CAI_ActBusyQueueGoal::RecalculateQueueCount( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::InputPlayerStartedBlocking( inputdata_t &inputdata ) { @@ -2874,7 +3109,7 @@ void CAI_ActBusyQueueGoal::InputPlayerStartedBlocking( inputdata_t &inputdata ) CAI_ActBusyBehavior *pBehavior = GetQueueBehaviorForNPC( pNPC ); if ( pBehavior->IsMovingToBusy() ) { - // We may be ahead of the player in the queue, which means we can safely + // We may be ahead of the player in the queue, which means we can safely // be left alone to reach the node. Make sure we're not closer to it than the player is float flPlayerDistToNode = (inputdata.pActivator->GetAbsOrigin() - m_hNodes[i]->GetAbsOrigin()).LengthSqr(); if ( (pNPC->GetAbsOrigin() - m_hNodes[i]->GetAbsOrigin()).LengthSqr() < flPlayerDistToNode ) @@ -2930,8 +3165,8 @@ void CAI_ActBusyQueueGoal::PushNPCBackInQueue( CAI_BaseNPC *pNPC, int iStartingN } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::InputPlayerStoppedBlocking( inputdata_t &inputdata ) { @@ -2945,8 +3180,8 @@ void CAI_ActBusyQueueGoal::InputPlayerStoppedBlocking( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::InputMoveQueueUp( inputdata_t &inputdata ) { @@ -2983,8 +3218,8 @@ void CAI_ActBusyQueueGoal::InputMoveQueueUp( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::NPCMovingToBusy( CAI_BaseNPC *pNPC ) { @@ -2993,8 +3228,8 @@ void CAI_ActBusyQueueGoal::NPCMovingToBusy( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::NPCStartedBusy( CAI_BaseNPC *pNPC ) { @@ -3016,7 +3251,7 @@ void CAI_ActBusyQueueGoal::MoveQueueUp( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::MoveQueueUpThink( void ) { @@ -3047,8 +3282,8 @@ void CAI_ActBusyQueueGoal::MoveQueueUpThink( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::NPCAbortedMoveTo( CAI_BaseNPC *pNPC ) { @@ -3058,8 +3293,8 @@ void CAI_ActBusyQueueGoal::NPCAbortedMoveTo( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::NPCFinishedBusy( CAI_BaseNPC *pNPC ) { @@ -3077,8 +3312,8 @@ void CAI_ActBusyQueueGoal::NPCFinishedBusy( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pNPC - +// Purpose: +// Input : *pNPC - //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::NPCStartedLeavingBusy( CAI_BaseNPC *pNPC ) { @@ -3092,7 +3327,7 @@ void CAI_ActBusyQueueGoal::NPCStartedLeavingBusy( CAI_BaseNPC *pNPC ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_ActBusyQueueGoal::RemoveNPCFromQueue( CAI_BaseNPC *pNPC ) { @@ -3116,16 +3351,16 @@ void CAI_ActBusyQueueGoal::QueueThink( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -inline bool CAI_ActBusyQueueGoal::NodeIsOccupied( int i ) -{ - return ( m_hNodes[i] && !m_hNodes[i]->IsDisabled() && m_hNodes[i]->IsLocked() ); +inline bool CAI_ActBusyQueueGoal::NodeIsOccupied( int i ) +{ + return ( m_hNodes[i] && !m_hNodes[i]->IsDisabled() && m_hNodes[i]->IsLocked() ); } //----------------------------------------------------------------------------- -// Purpose: -// Input : iNode - +// Purpose: +// Input : iNode - // Output : CAI_BaseNPC //----------------------------------------------------------------------------- CAI_BaseNPC *CAI_ActBusyQueueGoal::GetNPCOnNode( int iNode ) @@ -3137,8 +3372,8 @@ CAI_BaseNPC *CAI_ActBusyQueueGoal::GetNPCOnNode( int iNode ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : iNode - +// Purpose: +// Input : iNode - // Output : CAI_ActBusyBehavior //----------------------------------------------------------------------------- CAI_ActBusyBehavior *CAI_ActBusyQueueGoal::GetQueueBehaviorForNPC( CAI_BaseNPC *pNPC ) diff --git a/game/server/hl2/ai_behavior_actbusy.h b/game/server/hl2/ai_behavior_actbusy.h index 750b600f..264fdb3d 100644 --- a/game/server/hl2/ai_behavior_actbusy.h +++ b/game/server/hl2/ai_behavior_actbusy.h @@ -50,6 +50,9 @@ struct busyanim_t float flMaxTime; // Max time spent in this busy animation. 0 means continue until interrupted. busyinterrupt_t iBusyInterruptType; bool bUseAutomovement; +#ifdef MAPBASE + bool bTranslateActivity; +#endif }; struct busysafezone_t @@ -150,6 +153,10 @@ class CAI_ActBusyBehavior : public CAI_SimpleBehavior bool IsInSafeZone( CBaseEntity *pEntity ); int CountEnemiesInSafeZone(); +#ifdef MAPBASE + CAI_ActBusyGoal *GetActBusyGoal() const { return m_hActBusyGoal; } +#endif + private: virtual int SelectSchedule( void ); int SelectScheduleForLeaving( void ); @@ -181,6 +188,10 @@ class CAI_ActBusyBehavior : public CAI_SimpleBehavior bool m_bInQueue; int m_iCurrentBusyAnim; CHandle m_hActBusyGoal; +#ifdef MAPBASE + // So exit animations can play + CHandle m_hNextActBusyGoal; +#endif bool m_bNeedToSetBounds; EHANDLE m_hSeeEntity; float m_fTimeLastSawSeeEntity; @@ -189,6 +200,9 @@ class CAI_ActBusyBehavior : public CAI_SimpleBehavior int m_iNumConsecutivePathFailures; // Count how many times we failed to find a path to a node, so we can consider teleporting. bool m_bAutoFireWeapon; +#ifdef MAPBASE + float m_flNextAutoFireTime; +#endif float m_flDeferUntil; int m_iNumEnemiesInSafeZone; @@ -225,6 +239,16 @@ class CAI_ActBusyGoal : public CAI_GoalEntity int GetType() { return m_iType; } bool IsCombatActBusyTeleportAllowed() { return m_bAllowCombatActBusyTeleport; } +#ifdef MAPBASE + interval_t &NextBusySearchInterval(); +#endif + +#ifdef MAPBASE_VSCRIPT + void ScriptForceBusy( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly ); + void ScriptForceBusyComplex( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly, bool bVisibleOnly, bool bUseNearestBusy, float flMaxTime, int activity, HSCRIPT pSeeEntity ); + void ScriptStopBusy( HSCRIPT hNPC ); +#endif + protected: CAI_ActBusyBehavior *GetBusyBehaviorForNPC( const char *pszActorName, CBaseEntity *pActivator, CBaseEntity *pCaller, const char *sInputName ); CAI_ActBusyBehavior *GetBusyBehaviorForNPC( CBaseEntity *pEntity, const char *sInputName ); @@ -238,14 +262,23 @@ class CAI_ActBusyGoal : public CAI_GoalEntity void InputForceNPCToActBusy( inputdata_t &inputdata ); void InputForceThisNPCToActBusy( inputdata_t &inputdata ); void InputForceThisNPCToLeave( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputForceThisNPCToStopBusy( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif protected: float m_flBusySearchRange; bool m_bVisibleOnly; int m_iType; bool m_bAllowCombatActBusyTeleport; +#ifdef MAPBASE + interval_t m_NextBusySearch; +#endif public: // Let the actbusy behavior query these so we don't have to duplicate the data. @@ -257,6 +290,11 @@ class CAI_ActBusyGoal : public CAI_GoalEntity protected: COutputEHANDLE m_OnNPCStartedBusy; COutputEHANDLE m_OnNPCFinishedBusy; +#ifdef MAPBASE + COutputEHANDLE m_OnNPCStartedLeavingBusy; + COutputEHANDLE m_OnNPCMovingToBusy; + COutputEHANDLE m_OnNPCAbortedMoveTo; +#endif COutputEHANDLE m_OnNPCLeft; COutputEHANDLE m_OnNPCLostSeeEntity; COutputEHANDLE m_OnNPCSeeEnemy; diff --git a/game/server/hl2/ai_behavior_functank.cpp b/game/server/hl2/ai_behavior_functank.cpp index 0c1ae3bf..89f79228 100644 --- a/game/server/hl2/ai_behavior_functank.cpp +++ b/game/server/hl2/ai_behavior_functank.cpp @@ -50,6 +50,12 @@ bool CAI_FuncTankBehavior::CanSelectSchedule() if ( !m_hFuncTank ) return false; +#ifdef MAPBASE + // We're glued to our func_tank, don't get off of it + if ( m_hFuncTank->m_bControllerGlued ) + return true; +#endif + // Are you alive, in a script? if ( !GetOuter()->IsInterruptable() ) return false; @@ -92,6 +98,42 @@ void CAI_FuncTankBehavior::PrescheduleThink() } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_FuncTankBehavior::IsInterruptable( void ) +{ + if ( m_hFuncTank && m_hFuncTank->m_bControllerGlued ) + return false; + + return BaseClass::IsInterruptable(); +} + +ConVar ai_tank_allow_expanded_npcs( "ai_tank_allow_expanded_npcs", "1", FCVAR_NONE, "Allows Father Grigori, Barney, and vortigaunts to automatically man func_tanks." ); + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_FuncTankBehavior::CanManTank( CFuncTank *pTank, bool bForced ) +{ + if (!bForced) + { + // In order to prevent potential problems in existing maps, Father Grigori, Barney, and vortigaunts can be set to not automatically man func_tanks by default. + if (ai_tank_allow_expanded_npcs.GetBool() == false) + { + const char *pszClass = GetOuter()->GetClassname(); + if ( FStrEq( pszClass, "npc_monk" ) || FStrEq( pszClass, "npc_barney" ) || FStrEq( pszClass, "npc_vortigaunt" ) ) + return false; + } + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -114,6 +156,15 @@ int CAI_FuncTankBehavior::SelectSchedule() // If we are not mounted to a func_tank look for one. if ( !IsMounted() ) { +#ifdef MAPBASE + // Forced mounts use a special schedule. + // If our outer is parented, automatically grab the tank if we're in its control volume. + if (HasCondition(COND_FUNCTANK_FORCED) || (GetOuter()->GetParent() && m_hFuncTank->m_hControlVolume)) + { + return SCHED_FORCE_MOUNT_FUNCTANK; + } +#endif + return SCHED_MOVE_TO_FUNCTANK; } @@ -180,6 +231,10 @@ void CAI_FuncTankBehavior::Dismount( void ) // Set this condition to force breakout of any func_tank behavior schedules SetCondition( COND_FUNCTANK_DISMOUNT ); + +#ifdef MAPBASE + ClearCondition( COND_FUNCTANK_FORCED ); +#endif } //----------------------------------------------------------------------------- @@ -204,7 +259,11 @@ int CAI_FuncTankBehavior::OnTakeDamage_Alive( const CTakeDamageInfo &info ) if ( m_hFuncTank && bValidDismountAttacker == true ) { +#ifdef MAPBASE + if ( !m_hFuncTank->IsEntityInViewCone( pAttacker ) && !m_hFuncTank->m_bControllerGlued ) +#else if ( !m_hFuncTank->IsEntityInViewCone( pAttacker ) ) +#endif { SetCondition( COND_FUNCTANK_DISMOUNT ); } @@ -571,7 +630,12 @@ void CAI_FuncTankBehavior::GatherConditions() } } +#ifdef MAPBASE + // So they don't unholster every time there's a tank in the map looking for NPCs + if (!m_hFuncTank && m_bMounted) +#else if ( !m_hFuncTank ) +#endif { m_bMounted = false; GetOuter()->SetDesiredWeaponState( DESIREDWEAPONSTATE_UNHOLSTERED ); @@ -704,6 +768,9 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_FuncTankBehavior ) DECLARE_TASK( TASK_FUNCTANK_ANNOUNCE_SCAN ) DECLARE_CONDITION( COND_FUNCTANK_DISMOUNT ) +#ifdef MAPBASE + DECLARE_CONDITION( COND_FUNCTANK_FORCED ) +#endif //========================================================= //========================================================= @@ -773,4 +840,20 @@ AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_FuncTankBehavior ) " Interrupts" ) +#ifdef MAPBASE + //========================================================= + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_FORCE_MOUNT_FUNCTANK, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_FACE_FUNCTANK 0" + " TASK_HOLSTER_WEAPON 0" + " " + " Interrupts" + ) +#endif + AI_END_CUSTOM_SCHEDULE_PROVIDER() diff --git a/game/server/hl2/ai_behavior_functank.h b/game/server/hl2/ai_behavior_functank.h index a8d61466..75d5b8df 100644 --- a/game/server/hl2/ai_behavior_functank.h +++ b/game/server/hl2/ai_behavior_functank.h @@ -49,6 +49,11 @@ class CAI_FuncTankBehavior : public CAI_SimpleBehavior void BeginScheduleSelection(); void EndScheduleSelection(); void PrescheduleThink(); +#ifdef MAPBASE + bool IsInterruptable( void ); + + bool CanManTank( CFuncTank *pTank, bool bForced ); +#endif Activity NPC_TranslateActivity( Activity activity ); @@ -61,6 +66,9 @@ class CAI_FuncTankBehavior : public CAI_SimpleBehavior SCHED_FIRE_FUNCTANK, SCHED_SCAN_WITH_FUNCTANK, SCHED_FAIL_MOVE_TO_FUNCTANK, +#ifdef MAPBASE + SCHED_FORCE_MOUNT_FUNCTANK, +#endif }; // Tasks @@ -82,6 +90,9 @@ class CAI_FuncTankBehavior : public CAI_SimpleBehavior enum { COND_FUNCTANK_DISMOUNT = BaseClass::NEXT_CONDITION, +#ifdef MAPBASE + COND_FUNCTANK_FORCED, +#endif NEXT_CONDITION, }; @@ -104,6 +115,12 @@ class CAI_FuncTankBehavior : public CAI_SimpleBehavior bool IsMounted( void ) { return m_bMounted; } +#ifdef MAPBASE + void SetMounted( bool bMounted ) { m_bMounted = bMounted; } + + bool CanUnholsterWeapon( void ) { return !IsMounted(); } +#endif + private: // Schedule diff --git a/game/server/hl2/ai_behavior_police.cpp b/game/server/hl2/ai_behavior_police.cpp index eb1b45b3..e641372a 100644 --- a/game/server/hl2/ai_behavior_police.cpp +++ b/game/server/hl2/ai_behavior_police.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -11,6 +11,9 @@ #include "ai_memory.h" #include "collisionutils.h" #include "npc_metropolice.h" +#ifdef MAPBASE +#include "npc_combine.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -36,7 +39,7 @@ CAI_PolicingBehavior::CAI_PolicingBehavior( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_PolicingBehavior::TargetIsHostile( void ) @@ -48,8 +51,8 @@ bool CAI_PolicingBehavior::TargetIsHostile( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pGoal - +// Purpose: +// Input : *pGoal - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::Enable( CAI_PoliceGoal *pGoal ) { @@ -64,7 +67,7 @@ void CAI_PolicingBehavior::Enable( CAI_PoliceGoal *pGoal ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_PolicingBehavior::Disable( void ) { @@ -73,7 +76,7 @@ void CAI_PolicingBehavior::Disable( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_PolicingBehavior::CanSelectSchedule( void ) @@ -86,8 +89,8 @@ bool CAI_PolicingBehavior::CanSelectSchedule( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : false - +// Purpose: +// Input : false - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::HostSetBatonState( bool state ) { @@ -102,8 +105,8 @@ void CAI_PolicingBehavior::HostSetBatonState( bool state ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : false - +// Purpose: +// Input : false - //----------------------------------------------------------------------------- bool CAI_PolicingBehavior::HostBatonIsOn( void ) { @@ -116,7 +119,7 @@ bool CAI_PolicingBehavior::HostBatonIsOn( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_PolicingBehavior::HostSpeakSentence( const char *pSentence, SentencePriority_t nSoundPriority, SentenceCriteria_t nCriteria ) { @@ -125,14 +128,64 @@ void CAI_PolicingBehavior::HostSpeakSentence( const char *pSentence, SentencePri if ( pCop != NULL ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + pCop->SpeakIfAllowed( pSentence, nSoundPriority, nCriteria ); +#else CAI_Sentence< CNPC_MetroPolice > *pSentences = pCop->GetSentences(); pSentences->Speak( pSentence, nSoundPriority, nCriteria ); +#endif } +#ifdef MAPBASE + else if ( CNPC_Combine *pCombine = dynamic_cast(GetOuter()) ) + { + pCombine->SpeakIfAllowed( pSentence, nSoundPriority, nCriteria ); + } + else if ( GetOuter()->GetExpresser() ) + { +#ifdef NEW_RESPONSE_SYSTEM + CAI_Concept rrConcept = pSentence; + GetOuter()->GetExpresser()->Speak( rrConcept ); +#else + GetOuter()->GetExpresser()->Speak( pSentence ); +#endif + } +#endif } +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM +//----------------------------------------------------------------------------- +// Purpose: //----------------------------------------------------------------------------- -// Purpose: +void CAI_PolicingBehavior::HostSpeakSentence( const char *pSentence, const char *modifiers, SentencePriority_t nSoundPriority, SentenceCriteria_t nCriteria ) +{ + // If we're a cop, turn the baton on + CNPC_MetroPolice *pCop = dynamic_cast(GetOuter()); + + if ( pCop != NULL ) + { + pCop->SpeakIfAllowed( pSentence, modifiers, nSoundPriority, nCriteria ); + } +#ifdef MAPBASE + else if ( CNPC_Combine *pCombine = dynamic_cast(GetOuter()) ) + { + pCombine->SpeakIfAllowed( pSentence, modifiers, nSoundPriority, nCriteria ); + } + else if ( GetOuter()->GetExpresser() ) + { +#ifdef NEW_RESPONSE_SYSTEM + CAI_Concept rrConcept( pSentence ); + GetOuter()->GetExpresser()->Speak( rrConcept, modifiers ); +#else + GetOuter()->GetExpresser()->Speak( pSentence, modifiers ); +#endif + } +#endif +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: //----------------------------------------------------------------------------- void CAI_PolicingBehavior::BuildScheduleTestBits( void ) { @@ -148,7 +201,7 @@ void CAI_PolicingBehavior::BuildScheduleTestBits( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CAI_PolicingBehavior::GatherConditions( void ) { @@ -175,6 +228,10 @@ void CAI_PolicingBehavior::GatherConditions( void ) // See if we need to knock out our target immediately if ( ShouldKnockOutTarget( pTarget ) ) { +#ifdef MAPBASE + // If this isn't actually an enemy of ours and we're already warning, don't set this condition + if (GetOuter()->IRelationType( m_hPoliceGoal->GetTarget() ) <= D_FR || !IsCurSchedule(SCHED_POLICE_WARN_TARGET, false)) +#endif SetCondition( COND_POLICE_TARGET_TOO_CLOSE_SUPPRESS ); } @@ -189,6 +246,10 @@ void CAI_PolicingBehavior::GatherConditions( void ) if ( flDistSqr < (m_hPoliceGoal->GetRadius()*m_hPoliceGoal->GetRadius()) ) { +#ifdef MAPBASE + // If this isn't actually an enemy of ours and we're already warning, don't set this condition + if (GetOuter()->IRelationType( m_hPoliceGoal->GetTarget() ) <= D_FR || !IsCurSchedule(SCHED_POLICE_WARN_TARGET, false)) +#endif SetCondition( COND_POLICE_TARGET_TOO_CLOSE_SUPPRESS ); } } @@ -207,30 +268,34 @@ void CAI_PolicingBehavior::GatherConditions( void ) void CAI_PolicingBehavior::AnnouncePolicing( void ) { // We're policing - static const char *pWarnings[3] = + static const char *pWarnings[3] = { "METROPOLICE_MOVE_ALONG_A", "METROPOLICE_MOVE_ALONG_B", "METROPOLICE_MOVE_ALONG_C", }; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + HostSpeakSentence(TLK_COP_MOVE_ALONG, UTIL_VarArgs("numwarnings:%i", m_nNumWarnings), SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL); +#else if ( m_nNumWarnings <= 3 ) { HostSpeakSentence( pWarnings[ m_nNumWarnings - 1 ], SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); } - else + else { - // We loop at m_nNumWarnings == 4 for players who aren't moving + // We loop at m_nNumWarnings == 4 for players who aren't moving // but still pissing us off, and we're not allowed to do anything about it. (i.e. can't leave post) // First two sentences sound pretty good, so randomly pick one of them. int iSentence = RandomInt( 0, 1 ); HostSpeakSentence( pWarnings[ iSentence ], SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); } +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : scheduleType - +// Purpose: +// Input : scheduleType - // Output : int //----------------------------------------------------------------------------- int CAI_PolicingBehavior::TranslateSchedule( int scheduleType ) @@ -239,14 +304,20 @@ int CAI_PolicingBehavior::TranslateSchedule( int scheduleType ) { if ( m_hPoliceGoal->ShouldRemainAtPost() && !MaintainGoalPosition() ) return BaseClass::TranslateSchedule( SCHED_COMBAT_FACE ); + +#ifdef MAPBASE + // If this isn't actually an enemy of ours, keep warning + if ( GetOuter()->IRelationType(m_hPoliceGoal->GetTarget()) > D_FR ) + return BaseClass::TranslateSchedule( SCHED_POLICE_WARN_TARGET ); +#endif } return BaseClass::TranslateSchedule( scheduleType ); } //----------------------------------------------------------------------------- -// Purpose: -// Input : newActivity - +// Purpose: +// Input : newActivity - // Output : Activity //----------------------------------------------------------------------------- Activity CAI_PolicingBehavior::NPC_TranslateActivity( Activity newActivity ) @@ -271,7 +342,7 @@ Activity CAI_PolicingBehavior::NPC_TranslateActivity( Activity newActivity ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : CBaseEntity //----------------------------------------------------------------------------- CBaseEntity *CAI_PolicingBehavior::GetGoalTarget( void ) @@ -287,8 +358,8 @@ CBaseEntity *CAI_PolicingBehavior::GetGoalTarget( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : time - +// Purpose: +// Input : time - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::SetTargetHostileDuration( float time ) { @@ -296,8 +367,8 @@ void CAI_PolicingBehavior::SetTargetHostileDuration( float time ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pTask - +// Purpose: +// Input : *pTask - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) { @@ -325,7 +396,7 @@ void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) // See how far away the default one is float testDist = UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), harassPos ); - + // If our other goal is closer, choose it if ( testDist > UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), vPos ) ) { @@ -335,7 +406,11 @@ void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) if ( GetNavigator()->SetGoal( harassPos, pTask->flTaskData ) ) { +#ifdef MAPBASE + GetNavigator()->SetMovementActivity( GetOuter()->TranslateActivity(ACT_WALK_ANGRY) ); +#else GetNavigator()->SetMovementActivity( (Activity) ACT_WALK_ANGRY ); +#endif GetNavigator()->SetArrivalDirection( m_hPoliceGoal->GetTarget() ); TaskComplete(); } @@ -345,7 +420,7 @@ void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) } } break; - + case TASK_POLICE_GET_PATH_TO_POLICE_GOAL: { if ( GetNavigator()->SetGoal( m_hPoliceGoal->GetAbsOrigin(), pTask->flTaskData ) ) @@ -379,7 +454,7 @@ void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) if ( m_hPoliceGoal ) { GetMotor()->SetIdealYaw( m_hPoliceGoal->GetAbsAngles().y ); - GetOuter()->SetTurnActivity(); + GetOuter()->SetTurnActivity(); } } break; @@ -391,16 +466,16 @@ void CAI_PolicingBehavior::StartTask( const Task_t *pTask ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- -void CAI_PolicingBehavior::RunTask( const Task_t *pTask ) -{ +void CAI_PolicingBehavior::RunTask( const Task_t *pTask ) +{ switch ( pTask->iTask ) { case TASK_POLICE_FACE_ALONG_GOAL: { GetMotor()->UpdateYaw(); - + if ( GetOuter()->FacingIdeal() ) { TaskComplete(); @@ -414,7 +489,7 @@ void CAI_PolicingBehavior::RunTask( const Task_t *pTask ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_PolicingBehavior::MaintainGoalPosition( void ) @@ -434,7 +509,7 @@ bool CAI_PolicingBehavior::MaintainGoalPosition( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CAI_PolicingBehavior::ShouldKnockOutTarget( CBaseEntity *pTarget ) @@ -451,8 +526,8 @@ bool CAI_PolicingBehavior::ShouldKnockOutTarget( CBaseEntity *pTarget ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pTarget - +// Purpose: +// Input : *pTarget - //----------------------------------------------------------------------------- void CAI_PolicingBehavior::KnockOutTarget( CBaseEntity *pTarget ) { @@ -467,7 +542,7 @@ void CAI_PolicingBehavior::KnockOutTarget( CBaseEntity *pTarget ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : int //----------------------------------------------------------------------------- int CAI_PolicingBehavior::SelectSuppressSchedule( void ) @@ -480,14 +555,14 @@ int CAI_PolicingBehavior::SelectSuppressSchedule( void ) { // Mark this as a valid target m_bTargetIsHostile = true; - + // Attack the target GetOuter()->SetEnemy( pTarget ); GetOuter()->SetState( NPC_STATE_COMBAT ); GetOuter()->UpdateEnemyMemory( pTarget, pTarget->GetAbsOrigin() ); HostSetBatonState( true ); - + // Remember that we're angry with the target m_nNumWarnings = POLICE_MAX_WARNINGS; @@ -519,7 +594,7 @@ int CAI_PolicingBehavior::SelectSuppressSchedule( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : int //----------------------------------------------------------------------------- int CAI_PolicingBehavior::SelectHarassSchedule( void ) @@ -531,7 +606,7 @@ int CAI_PolicingBehavior::SelectHarassSchedule( void ) // If we just started to police, make sure we're on our mark if ( MaintainGoalPosition() ) return SCHED_POLICE_RETURN_FROM_HARASS; - + // Look at the target if they're too close GetOuter()->AddLookTarget( pTarget, 0.5f, 5.0f ); @@ -540,7 +615,7 @@ int CAI_PolicingBehavior::SelectHarassSchedule( void ) { // Gesture the player away GetOuter()->SetTarget( pTarget ); - + // Send outputs for each level of warning if ( m_nNumWarnings == 0 ) { @@ -568,7 +643,7 @@ int CAI_PolicingBehavior::SelectHarassSchedule( void ) GetOuter()->SetState( NPC_STATE_COMBAT ); GetOuter()->UpdateEnemyMemory( pTarget, pTarget->GetAbsOrigin() ); HostSetBatonState( true ); - + m_hPoliceGoal->FireWarningLevelOutput( 4 ); return SCHED_COMBAT_FACE; @@ -577,14 +652,14 @@ int CAI_PolicingBehavior::SelectHarassSchedule( void ) if ( m_hPoliceGoal->ShouldRemainAtPost() == false ) return SCHED_CHASE_ENEMY; } - + // On our last warning, approach the target if ( m_nNumWarnings == (POLICE_MAX_WARNINGS-1) ) { m_hPoliceGoal->FireWarningLevelOutput( 3 ); GetOuter()->SetTarget( pTarget ); - + HostSetBatonState( true ); if ( m_hPoliceGoal->ShouldRemainAtPost() == false ) @@ -599,7 +674,7 @@ int CAI_PolicingBehavior::SelectHarassSchedule( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : int //----------------------------------------------------------------------------- int CAI_PolicingBehavior::SelectSchedule( void ) @@ -610,7 +685,7 @@ int CAI_PolicingBehavior::SelectSchedule( void ) if ( pTarget == NULL ) { DevMsg( "ai_goal_police with NULL target entity!\n" ); - + // Turn us off Disable(); return SCHED_NONE; @@ -627,7 +702,7 @@ int CAI_PolicingBehavior::SelectSchedule( void ) { return SelectSuppressSchedule(); } - + int newSchedule = SCHED_NONE; // See if we're harassing @@ -653,7 +728,7 @@ int CAI_PolicingBehavior::SelectSchedule( void ) HostSetBatonState( false ); m_bTargetIsHostile = false; - } + } // If we just started to police, make sure we're on our mark if ( MaintainGoalPosition() ) @@ -671,7 +746,7 @@ int CAI_PolicingBehavior::SelectSchedule( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CAI_PolicingBehavior::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode ) { @@ -683,7 +758,7 @@ int CAI_PolicingBehavior::SelectFailSchedule( int failedSchedule, int failedTask return SCHED_POLICE_WARN_TARGET; } - + return BaseClass::SelectFailSchedule( failedSchedule, failedTask, taskFailCode ); } diff --git a/game/server/hl2/ai_behavior_police.h b/game/server/hl2/ai_behavior_police.h index 84f132be..ed1f58da 100644 --- a/game/server/hl2/ai_behavior_police.h +++ b/game/server/hl2/ai_behavior_police.h @@ -68,6 +68,9 @@ class CAI_PolicingBehavior : public CAI_SimpleBehavior private: void HostSpeakSentence( const char *pSentence, SentencePriority_t nSoundPriority, SentenceCriteria_t nCriteria ); +#ifdef MAPBASE + void HostSpeakSentence( const char *pSentence, const char *modifiers, SentencePriority_t nSoundPriority, SentenceCriteria_t nCriteria ); +#endif int TranslateSchedule( int scheduleType ); diff --git a/game/server/hl2/basehlcombatweapon.cpp b/game/server/hl2/basehlcombatweapon.cpp index 1735d0b0..894c290b 100644 --- a/game/server/hl2/basehlcombatweapon.cpp +++ b/game/server/hl2/basehlcombatweapon.cpp @@ -336,9 +336,7 @@ void CHLSelectFireMachineGun::PrimaryAttack( void ) case FIREMODE_FULLAUTO: BaseClass::PrimaryAttack(); // Msg("%.3f\n", m_flNextPrimaryAttack.Get() ); - #ifndef VANCE - SetWeaponIdleTime(gpGlobals->curtime + 3.0f); - #endif + SetWeaponIdleTime( gpGlobals->curtime + 3.0f ); break; case FIREMODE_3RNDBURST: @@ -396,6 +394,10 @@ void CHLSelectFireMachineGun::SecondaryAttack( void ) { m_iSecondaryAttacks++; gamestats->Event_WeaponFired( pOwner, false, GetClassname() ); + +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK2 ); +#endif } } diff --git a/game/server/hl2/cbasehelicopter.cpp b/game/server/hl2/cbasehelicopter.cpp index 1243fe18..2b46bce6 100644 --- a/game/server/hl2/cbasehelicopter.cpp +++ b/game/server/hl2/cbasehelicopter.cpp @@ -101,6 +101,10 @@ BEGIN_DATADESC( CBaseHelicopter ) DEFINE_FIELD( m_bSuppressSound, FIELD_BOOLEAN ), DEFINE_FIELD( m_flStartupTime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bAllowAnyDamage, FIELD_BOOLEAN, "AllowAnyDamage" ), +#endif + DEFINE_FIELD( m_cullBoxMins, FIELD_VECTOR ), DEFINE_FIELD( m_cullBoxMaxs, FIELD_VECTOR ), @@ -193,8 +197,15 @@ void CBaseHelicopter::Spawn( void ) AddFlag( FL_NPC ); +#ifdef MAPBASE + if (m_flMaxSpeed == 0) + m_flMaxSpeed = BASECHOPPER_MAX_SPEED; + if (m_flMaxSpeedFiring == 0) + m_flMaxSpeedFiring = BASECHOPPER_MAX_FIRING_SPEED; +#else m_flMaxSpeed = BASECHOPPER_MAX_SPEED; m_flMaxSpeedFiring = BASECHOPPER_MAX_FIRING_SPEED; +#endif m_takedamage = DAMAGE_AIM; // Don't start up if the level designer has asked the @@ -1110,6 +1121,11 @@ void CBaseHelicopter::InputDisableRotorSound( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CBaseHelicopter::InputKill( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Finally, an InputKill override that makes sense. + m_OnKilled.FireOutput( inputdata.pActivator, this ); +#endif + StopRotorWash(); m_bSuppressSound = true; @@ -1269,7 +1285,11 @@ void CBaseHelicopter::TraceAttack( const CTakeDamageInfo &info, const Vector &ve // Take no damage from trace attacks unless it's blast damage. RadiusDamage() sometimes calls // TraceAttack() as a means for delivering blast damage. Usually when the explosive penetrates // the target. (RPG missiles do this sometimes). +#ifdef MAPBASE + if ( info.GetDamageType() & (DMG_BLAST|DMG_AIRBOAT) || m_bAllowAnyDamage ) +#else if( info.GetDamageType() & (DMG_BLAST|DMG_AIRBOAT) ) +#endif { BaseClass::TraceAttack( info, vecDir, ptr, pAccumulator ); } @@ -1520,9 +1540,23 @@ bool CBaseHelicopter::ChooseEnemy( void ) // New enemy! Clear the timers and set conditions. SetEnemy( pNewEnemy ); m_flLastSeen = m_flPrevSeen = gpGlobals->curtime; +#ifdef MAPBASE + Remember( ( pNewEnemy->IsPlayer() ) ? bits_MEMORY_HAD_PLAYER : bits_MEMORY_HAD_ENEMY ); +#endif } else { +#ifdef MAPBASE + if (!pNewEnemy) + { + if ( HasMemory( bits_MEMORY_HAD_PLAYER ) ) + { + m_OnLostPlayer.FireOutput( GetEnemy(), this ); + } + m_OnLostEnemy.FireOutput( GetEnemy(), this ); + } +#endif + SetEnemy( NULL ); SetState( NPC_STATE_ALERT ); } @@ -1542,6 +1576,45 @@ bool CBaseHelicopter::ChooseEnemy( void ) //----------------------------------------------------------------------------- void CBaseHelicopter::GatherEnemyConditions( CBaseEntity *pEnemy ) { +#ifdef MAPBASE + // --------------------------- + // Ported from CAI_BaseNPC. Need it to fire outputs without setting all kinds of conditions + // --------------------------- + if ( HasCondition( COND_NEW_ENEMY ) || GetSenses()->GetTimeLastUpdate( GetEnemy() ) == gpGlobals->curtime ) + { + bool bSensesDidSee = GetSenses()->DidSeeEntity( pEnemy ); + + if ( !bSensesDidSee && ( ( EnemyDistance( pEnemy ) >= GetSenses()->GetDistLook() ) || !FVisible( pEnemy, MASK_BLOCKLOS ) ) ) + { + // No LOS to enemy + if (HasMemory( bits_MEMORY_HAD_LOS )) + { + // Send output event + if (GetEnemy()->IsPlayer()) + { + m_OnLostPlayerLOS.FireOutput( GetEnemy(), this ); + } + m_OnLostEnemyLOS.FireOutput( GetEnemy(), this ); + } + Forget( bits_MEMORY_HAD_LOS ); + } + else + { + if (!HasMemory( bits_MEMORY_HAD_LOS )) + { + // Send output event + EHANDLE hEnemy; + hEnemy.Set( GetEnemy() ); + + if (GetEnemy()->IsPlayer()) + m_OnFoundPlayer.Set(hEnemy, hEnemy, this); + m_OnFoundEnemy.Set(hEnemy, hEnemy, this); + } + Remember( bits_MEMORY_HAD_LOS ); + } + } +#endif + // ------------------- // If enemy is dead // ------------------- @@ -1595,3 +1668,103 @@ void ExpandBBox(Vector &vecMins, Vector &vecMaxs) vecMins.Init(-maxval, -maxval, -maxval); vecMaxs.Init(maxval, maxval, maxval); } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// A custom helicopter +//----------------------------------------------------------------------------- +class CNPC_CustomHelicopter : public CBaseHelicopter +{ +public: + DECLARE_CLASS( CNPC_CustomHelicopter, CBaseHelicopter ); + DECLARE_DATADESC(); + + CNPC_CustomHelicopter(); + ~CNPC_CustomHelicopter(); + + virtual void Precache( void ); + virtual void Spawn( void ); + + void InitializeRotorSound( void ); + + float GetAcceleration( void ) { return m_flAcceleration; } + + float m_flAcceleration; + + string_t m_iszRotorSound; + string_t m_iszRotorBlast; +}; + +LINK_ENTITY_TO_CLASS( npc_helicopter_custom, CNPC_CustomHelicopter ); + +BEGIN_DATADESC( CNPC_CustomHelicopter ) + + DEFINE_KEYFIELD( m_flMaxSpeed, FIELD_FLOAT, "MaxSpeed" ), + DEFINE_KEYFIELD( m_flMaxSpeedFiring, FIELD_FLOAT, "MaxSpeedfiring" ), + + DEFINE_KEYFIELD( m_flAcceleration, FIELD_FLOAT, "Acceleration" ), + + DEFINE_KEYFIELD( m_iszRotorSound, FIELD_STRING, "RotorSound" ), + DEFINE_KEYFIELD( m_iszRotorBlast, FIELD_STRING, "RotorBlast" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CNPC_CustomHelicopter::CNPC_CustomHelicopter() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CNPC_CustomHelicopter::~CNPC_CustomHelicopter() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_CustomHelicopter::Precache( void ) +{ + PrecacheModel( STRING(GetModelName()) ); + + PrecacheScriptSound( STRING(m_iszRotorSound) ); + PrecacheScriptSound( STRING(m_iszRotorBlast) ); + + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_CustomHelicopter::Spawn( void ) +{ + SetModel( STRING(GetModelName()) ); + + BaseClass::Spawn(); +} + +//------------------------------------------------------------------------------ +// Purpose: Create our rotor sound +//------------------------------------------------------------------------------ +void CNPC_CustomHelicopter::InitializeRotorSound( void ) +{ + if ( !m_pRotorSound ) + { + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + CPASAttenuationFilter filter( this ); + + m_pRotorSound = controller.SoundCreate( filter, entindex(), STRING(m_iszRotorSound) ); + m_pRotorBlast = controller.SoundCreate( filter, entindex(), STRING(m_iszRotorBlast) ); + } + else + { + Assert(m_pRotorSound); + Assert(m_pRotorBlast); + } + + BaseClass::InitializeRotorSound(); +} +#endif diff --git a/game/server/hl2/cbasehelicopter.h b/game/server/hl2/cbasehelicopter.h index 4ca3b091..714f62f4 100644 --- a/game/server/hl2/cbasehelicopter.h +++ b/game/server/hl2/cbasehelicopter.h @@ -215,6 +215,10 @@ class CBaseHelicopter : public CAI_TrackPather EHANDLE m_hRotorWash; // Attached rotorwash entity +#ifdef MAPBASE + bool m_bAllowAnyDamage; +#endif + // Inputs void InputActivate( inputdata_t &inputdata ); @@ -263,6 +267,10 @@ class CAvoidSphere : public CBaseEntity typedef CHandle AvoidSphereHandle_t; float m_flRadius; +#ifdef MAPBASE + string_t m_iszAvoidFilter; + EHANDLE m_hAvoidFilter; +#endif static CUtlVector< AvoidSphereHandle_t > s_AvoidSpheres; }; diff --git a/game/server/hl2/combine_mine.cpp b/game/server/hl2/combine_mine.cpp index 4eb7283f..aa9bdf29 100644 --- a/game/server/hl2/combine_mine.cpp +++ b/game/server/hl2/combine_mine.cpp @@ -58,6 +58,10 @@ char *pszMineStateNames[] = // Approximate radius of the bomb's model #define BOUNCEBOMB_RADIUS 24 +#ifdef MAPBASE +ConVar combine_mine_trace_dist( "combine_mine_trace_dist", "1024" ); +#endif + BEGIN_DATADESC( CBounceBomb ) DEFINE_THINKFUNC( ExplodeThink ), DEFINE_ENTITYFUNC( ExplodeTouch ), @@ -87,9 +91,20 @@ BEGIN_DATADESC( CBounceBomb ) DEFINE_FIELD( m_bFoeNearest, FIELD_BOOLEAN ), DEFINE_FIELD( m_flIgnoreWorldTime, FIELD_TIME ), DEFINE_KEYFIELD( m_bDisarmed, FIELD_BOOLEAN, "StartDisarmed" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iInitialState, FIELD_INTEGER, "InitialState" ), + DEFINE_KEYFIELD( m_bCheapWarnSound, FIELD_BOOLEAN, "CheapWarnSound" ), + DEFINE_KEYFIELD( m_iLOSMask, FIELD_INTEGER, "LOSMask" ), + DEFINE_INPUT( m_bUnavoidable, FIELD_BOOLEAN, "SetUnavoidable" ), + DEFINE_KEYFIELD( m_vecPlantOrientation, FIELD_VECTOR, "PlantOrientation" ), +#endif DEFINE_KEYFIELD( m_iModification, FIELD_INTEGER, "Modification" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bPlacedByPlayer, FIELD_BOOLEAN, "Friendly" ), +#else DEFINE_FIELD( m_bPlacedByPlayer, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_bHeldByPhysgun, FIELD_BOOLEAN ), DEFINE_FIELD( m_iFlipAttempts, FIELD_INTEGER ), @@ -97,6 +112,16 @@ BEGIN_DATADESC( CBounceBomb ) DEFINE_FIELD( m_flTimeGrabbed, FIELD_TIME ), DEFINE_FIELD( m_iMineState, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bFilterExclusive, FIELD_BOOLEAN, "FilterExclusive" ), + DEFINE_KEYFIELD( m_iszEnemyFilter, FIELD_STRING, "enemyfilter" ), + DEFINE_FIELD( m_hEnemyFilter, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetEnemyFilter", InputSetEnemyFilter ), + DEFINE_KEYFIELD( m_iszFriendFilter, FIELD_STRING, "friendfilter" ), + DEFINE_FIELD( m_hFriendFilter, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFriendFilter", InputSetFriendFilter ), +#endif + // Physics Influence DEFINE_FIELD( m_hPhysicsAttacker, FIELD_EHANDLE ), DEFINE_FIELD( m_flLastPhysicsInfluenceTime, FIELD_TIME ), @@ -106,6 +131,16 @@ BEGIN_DATADESC( CBounceBomb ) DEFINE_OUTPUT( m_OnPulledUp, "OnPulledUp" ), DEFINE_INPUTFUNC( FIELD_VOID, "Disarm", InputDisarm ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "Bounce", InputBounce ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "BounceAtTarget", InputBounceAtTarget ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetPlantOrientation", InputSetPlantOrientation ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetPlantOrientationRaw", InputSetPlantOrientationRaw ), + + DEFINE_OUTPUT( m_OnTriggered, "OnTriggered" ), + DEFINE_OUTPUT( m_OnExplode, "OnExplode" ), +#endif + END_DATADESC() string_t CBounceBomb::gm_iszFloorTurretClassname; @@ -130,6 +165,13 @@ void CBounceBomb::Precache() gm_iszFloorTurretClassname = AllocPooledString( "npc_turret_floor" ); gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); + +#ifdef MAPBASE + if (m_iszEnemyFilter != NULL_STRING) + m_hEnemyFilter = dynamic_cast(gEntList.FindEntityByName(NULL, STRING(m_iszEnemyFilter), this)); + if (m_iszFriendFilter != NULL_STRING) + m_hFriendFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszFriendFilter), this )); +#endif } //--------------------------------------------------------- @@ -178,10 +220,23 @@ void CBounceBomb::Spawn() { SetMineState( MINE_STATE_DORMANT ); } +#ifdef MAPBASE + else + { + // NOTE: MINE_STATE_DEPLOY and MINE_STATE_DORMANT are swapped in this case! + if (m_iInitialState == 0) + SetMineState( MINE_STATE_DEPLOY ); + else if (m_iInitialState == 1) + SetMineState( MINE_STATE_DORMANT ); + else + SetMineState( m_iInitialState ); + } +#else else { SetMineState( MINE_STATE_DEPLOY ); } +#endif // default to a different skin for cavern turrets (unless explicitly overridden) if ( m_iModification == MINE_MODIFICATION_CAVERN ) @@ -218,6 +273,14 @@ void CBounceBomb::Spawn() // pretend like the player set me down. m_bPlacedByPlayer = true; } + +#ifdef MAPBASE + if (m_vecPlantOrientation != vec3_invalid) + { + // Turn angles into direction + AngleVectors( QAngle( m_vecPlantOrientation.x, m_vecPlantOrientation.y, m_vecPlantOrientation.z ), &m_vecPlantOrientation ); + } +#endif } //--------------------------------------------------------- @@ -261,8 +324,12 @@ void CBounceBomb::SetMineState( int iState ) { case MINE_STATE_DORMANT: { +#ifdef MAPBASE + SilenceWarnSound( 0.1 ); +#else CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.1 ); +#endif UpdateLight( false, 0, 0, 0, 0 ); SetThink( NULL ); } @@ -270,8 +337,12 @@ void CBounceBomb::SetMineState( int iState ) case MINE_STATE_CAPTIVE: { +#ifdef MAPBASE + SilenceWarnSound( 0.2 ); +#else CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.2 ); +#endif // Unhook unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); @@ -314,8 +385,12 @@ void CBounceBomb::SetMineState( int iState ) // Scare NPC's CSoundEnt::InsertSound( SOUND_DANGER, GetAbsOrigin(), 300, 1.0f, this ); +#ifdef MAPBASE + SilenceWarnSound( 0.2 ); +#else CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.2 ); +#endif SetTouch( &CBounceBomb::ExplodeTouch ); unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); @@ -352,7 +427,11 @@ void CBounceBomb::SetMineState( int iState ) else { SetThink( &CBounceBomb::BounceThink ); +#ifdef MAPBASE + SetNextThink( gpGlobals->curtime + m_flExplosionDelay ); +#else SetNextThink( gpGlobals->curtime + 0.5 ); +#endif } } break; @@ -630,7 +709,20 @@ void CBounceBomb::SettleThink() { // If i'm not resting on the world, jump randomly. trace_t tr; - UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1024 ), MASK_SHOT|CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &tr ); +#ifdef MAPBASE + Vector vecTraceDir; + if (m_vecPlantOrientation != vec3_invalid) + { + vecTraceDir = m_vecPlantOrientation * combine_mine_trace_dist.GetFloat(); + } + else + { + vecTraceDir = Vector( 0, 0, combine_mine_trace_dist.GetFloat() ); + } +#else + Vector vecTraceDir = Vector( 0, 0, 1024 ); +#endif + UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - vecTraceDir, MASK_SHOT|CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &tr ); bool bHop = false; if( tr.m_pEnt ) @@ -664,6 +756,20 @@ void CBounceBomb::SettleThink() // Check for upside-down Vector vecUp; GetVectors( NULL, NULL, &vecUp ); +#ifdef MAPBASE + if (m_vecPlantOrientation != vec3_invalid) + { + float flDiff = abs(m_vecPlantOrientation.z - vecUp.z); + if ( flDiff >= 0.2f ) + { + // Landed upside down. Right self + Vector vecForce( 0, 0, 2500 ); + Flip( vecForce, AngularImpulse( 60, 0, 0 ) ); + return; + } + } + else +#endif if( vecUp.z <= 0.8 ) { // Landed upside down. Right self @@ -773,7 +879,11 @@ void CBounceBomb::Wake( bool bAwake ) CReliableBroadcastRecipientFilter filter; +#ifdef MAPBASE + if( !m_pWarnSound && !m_bCheapWarnSound ) +#else if( !m_pWarnSound ) +#endif { m_pWarnSound = controller.SoundCreate( filter, entindex(), "NPC_CombineMine.ActiveLoop" ); controller.Play( m_pWarnSound, 1.0, PITCH_NORM ); @@ -785,7 +895,11 @@ void CBounceBomb::Wake( bool bAwake ) if( m_bFoeNearest ) { EmitSound( "NPC_CombineMine.TurnOn" ); +#ifdef MAPBASE + UpdateWarnSound( 1.0, 0.1 ); +#else controller.SoundChangeVolume( m_pWarnSound, 1.0, 0.1 ); +#endif } unsigned char r, g, b; @@ -811,7 +925,11 @@ void CBounceBomb::Wake( bool bAwake ) } SetNearestNPC( NULL ); +#ifdef MAPBASE + SilenceWarnSound( 0.1 ); +#else controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.1 ); +#endif UpdateLight( false, 0, 0, 0, 0 ); } @@ -845,6 +963,27 @@ float CBounceBomb::FindNearestNPC() if( pNPC->EyePosition().z < GetAbsOrigin().z ) continue; +#ifdef MAPBASE + bool bPassesFilter = false; + if (m_hEnemyFilter || m_hFriendFilter) + { + // If we have an enemy or friend filter, always accept those who pass it + // If we're only supposed to be using filters, only find entities that pass one of them + + if (m_hEnemyFilter && m_hEnemyFilter->PassesFilter( this, pNPC )) + bPassesFilter = true; + + else if (m_hFriendFilter && m_hFriendFilter->PassesFilter( this, pNPC )) + bPassesFilter = true; + + if (m_bFilterExclusive && !bPassesFilter) + continue; + } + + if (!bPassesFilter) + { +#endif + // Disregard things that want to be disregarded if( pNPC->Classify() == CLASS_NONE ) continue; @@ -857,13 +996,21 @@ float CBounceBomb::FindNearestNPC() if( pNPC->m_iClassname == gm_iszFloorTurretClassname || pNPC->m_iClassname == gm_iszGroundTurretClassname ) continue; +#ifdef MAPBASE + } +#endif + float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr(); if( flDist < flNearest ) { // Now do a visibility test. +#ifdef MAPBASE + if( FVisible( pNPC, m_iLOSMask ) ) +#else if( FVisible( pNPC, MASK_SOLID_BRUSHONLY ) ) +#endif { flNearest = flDist; SetNearestNPC( pNPC ); @@ -872,19 +1019,55 @@ float CBounceBomb::FindNearestNPC() } } +#ifdef MAPBASE_MP + for (i = 1; i <= gpGlobals->maxClients; i++) + { + CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) ) + { + float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); + + if( flDist < flNearest && FVisible( pPlayer, m_iLOSMask ) ) + { + flNearest = flDist; + SetNearestNPC( pPlayer ); + } + } + } +#else // finally, check the player. CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) ) { +#ifdef MAPBASE + bool bPassesFilter = true; + if ((m_hEnemyFilter || m_hFriendFilter) && m_bFilterExclusive) + { + // If we have an enemy or friend filter, and that's all we're supposed to be using, + // don't accept the player if they don't pass our filters + + if (m_hEnemyFilter && !m_hEnemyFilter->PassesFilter( this, pPlayer )) + bPassesFilter = false; + + else if (m_hFriendFilter && !m_hFriendFilter->PassesFilter( this, pPlayer )) + bPassesFilter = false; + } +#endif + float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); +#ifdef MAPBASE + if( flDist < flNearest && FVisible( pPlayer, m_iLOSMask ) && bPassesFilter ) +#else if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) ) +#endif { flNearest = flDist; SetNearestNPC( pPlayer ); } } +#endif if( m_hNearestNPC.Get() ) { @@ -894,8 +1077,9 @@ float CBounceBomb::FindNearestNPC() if( m_bFoeNearest ) { // Changing state to where a friend is nearest. - +#ifndef MAPBASE if( IsFriend( m_hNearestNPC ) ) +#endif { // Friend UpdateLight( true, 0, 255, 0, 190 ); @@ -921,6 +1105,14 @@ float CBounceBomb::FindNearestNPC() //--------------------------------------------------------- bool CBounceBomb::IsFriend( CBaseEntity *pEntity ) { +#ifdef MAPBASE + if (m_hFriendFilter && m_hFriendFilter->PassesFilter(this, pEntity)) + return true; + + if (m_hEnemyFilter && m_hEnemyFilter->PassesFilter(this, pEntity)) + return false; +#endif + int classify = pEntity->Classify(); bool bIsCombine = false; @@ -930,10 +1122,16 @@ bool CBounceBomb::IsFriend( CBaseEntity *pEntity ) return false; } - if( classify == CLASS_METROPOLICE || + if( classify == CLASS_METROPOLICE || classify == CLASS_COMBINE || classify == CLASS_MILITARY || classify == CLASS_COMBINE_HUNTER || +#ifdef MAPBASE + classify == CLASS_MANHACK || + classify == CLASS_STALKER || + classify == CLASS_PROTOSNIPER || + classify == CLASS_COMBINE_GUNSHIP || +#endif classify == CLASS_SCANNER ) { bIsCombine = true; @@ -976,7 +1174,12 @@ void CBounceBomb::SearchThink() if( m_pConstraint && gpGlobals->curtime - m_flTimeGrabbed >= 1.0f ) { +#ifdef MAPBASE + // We don't already store our holder for some reason + m_OnPulledUp.FireOutput( UTIL_GetLocalPlayer(), this ); +#else m_OnPulledUp.FireOutput( this, this ); +#endif SetMineState( MINE_STATE_CAPTIVE ); return; } @@ -1002,6 +1205,9 @@ void CBounceBomb::SearchThink() if( flNearestNPCDist <= BOUNCEBOMB_DETONATE_RADIUS && !IsFriend( m_hNearestNPC ) ) { +#ifdef MAPBASE + m_OnTriggered.FireOutput( m_hNearestNPC, this ); +#endif if( m_bBounce ) { SetMineState( MINE_STATE_TRIGGERED ); @@ -1087,6 +1293,11 @@ void CBounceBomb::ExplodeThink() { ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), (pThrower) ? pThrower : this, BOUNCEBOMB_EXPLODE_DAMAGE, BOUNCEBOMB_EXPLODE_RADIUS, true); } + +#ifdef MAPBASE + m_OnExplode.FireOutput( m_hNearestNPC, this ); +#endif + UTIL_Remove( this ); } @@ -1145,6 +1356,82 @@ void CBounceBomb::CloseHooks() #endif } +#ifdef MAPBASE +extern int g_interactionBarnacleVictimBite; +extern int g_interactionBarnacleVictimFinalBite; +extern int ACT_BARNACLE_BITE_SMALL_THINGS; +//----------------------------------------------------------------------------- +// Purpose: Uses the new CBaseEntity interaction implementation and +// replaces the dynamic_casting from npc_barnacle +// Input : The type of interaction, extra info pointer, and who started it +// Output : true - if sub-class has a response for the interaction +// false - if sub-class has no response +//----------------------------------------------------------------------------- +bool CBounceBomb::HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) +{ + // This was originally done in npc_barnacle itself, but + // we've transitioned to interactions so we could extend special behavior to others + // without just adding more casting. + if ( interactionType == g_interactionBarnacleVictimBite ) + { + Assert( sourceEnt && sourceEnt->IsNPC() ); + sourceEnt->MyNPCPointer()->SetActivity( (Activity)ACT_BARNACLE_BITE_SMALL_THINGS ); + return true; + } + else if ( interactionType == g_interactionBarnacleVictimFinalBite ) + { + ExplodeThink(); + return true; + } + + return BaseClass::HandleInteraction(interactionType, data, sourceEnt); +} + +//----------------------------------------------------------------------------- +void CBounceBomb::UpdateWarnSound( float flVolume, float flDelta ) +{ + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + if (m_bCheapWarnSound && !m_pWarnSound) + { + CReliableBroadcastRecipientFilter filter; + //m_pWarnSound = controller.SoundCreate( filter, entindex(), "NPC_CombineMine.ActiveLoop" ); + //controller.Play( m_pWarnSound, flVolume, PITCH_NORM ); + + EmitSound_t params; + params.m_pSoundName = "NPC_CombineMine.ActiveLoop"; + params.m_flVolume = flVolume; + params.m_nPitch = PITCH_NORM; + + EmitSound( filter, entindex(), params ); + } + else + { + controller.SoundChangeVolume( m_pWarnSound, flVolume, flDelta ); + } +} + +void CBounceBomb::SilenceWarnSound( float flDelta ) +{ + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + if (m_bCheapWarnSound) + { + //if ( m_pWarnSound ) + //{ + // controller.SoundDestroy( m_pWarnSound ); + //} + + StopSound( "NPC_CombineMine.ActiveLoop" ); + } + else + { + if ( m_pWarnSound ) + { + controller.SoundChangeVolume( m_pWarnSound, 0.0, flDelta ); + } + } +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::InputDisarm( inputdata_t &inputdata ) @@ -1165,6 +1452,56 @@ void CBounceBomb::InputDisarm( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBounceBomb::InputSetEnemyFilter( inputdata_t &inputdata ) +{ + m_iszEnemyFilter = inputdata.value.StringID(); + m_hEnemyFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszEnemyFilter), this )); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBounceBomb::InputSetFriendFilter( inputdata_t &inputdata ) +{ + m_iszFriendFilter = inputdata.value.StringID(); + m_hFriendFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszFriendFilter), this )); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CBounceBomb::InputBounce( inputdata_t &inputdata ) +{ + m_hNearestNPC = NULL; + SetMineState(MINE_STATE_TRIGGERED); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CBounceBomb::InputBounceAtTarget( inputdata_t &inputdata ) +{ + m_hNearestNPC = inputdata.value.Entity(); + SetMineState(MINE_STATE_TRIGGERED); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CBounceBomb::InputSetPlantOrientation( inputdata_t &inputdata ) +{ + Vector vecInput; + inputdata.value.Vector3D( vecInput ); + AngleVectors( QAngle(vecInput.x, vecInput.y, vecInput.z), &m_vecPlantOrientation ); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CBounceBomb::InputSetPlantOrientationRaw( inputdata_t &inputdata ) +{ + inputdata.value.Vector3D( m_vecPlantOrientation ); +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ) @@ -1207,6 +1544,18 @@ CBasePlayer *CBounceBomb::HasPhysicsAttacker( float dt ) return NULL; } +//--------------------------------------------------------- +//--------------------------------------------------------- +bool CBounceBomb::ShouldBeAvoidedByCompanions() +{ +#ifdef MAPBASE + if (m_bUnavoidable) + return false; +#endif + + return !IsPlayerPlaced() && IsAwake(); +} + //--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ) diff --git a/game/server/hl2/combine_mine.h b/game/server/hl2/combine_mine.h index 48dbb468..097968db 100644 --- a/game/server/hl2/combine_mine.h +++ b/game/server/hl2/combine_mine.h @@ -24,13 +24,20 @@ class CSoundPatch; #define BOUNCEBOMB_EXPLODE_RADIUS 125.0 #define BOUNCEBOMB_EXPLODE_DAMAGE 150.0 #include "player_pickup.h" +#ifdef MAPBASE +#include "filters.h" +#endif class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics { DECLARE_CLASS( CBounceBomb, CBaseAnimating ); public: +#ifdef MAPBASE + CBounceBomb() { m_pWarnSound = NULL; m_bPlacedByPlayer = false; m_flExplosionDelay = 0.5f; m_iLOSMask = MASK_SOLID_BRUSHONLY; m_vecPlantOrientation = vec3_invalid; } +#else CBounceBomb() { m_pWarnSound = NULL; m_bPlacedByPlayer = false; } +#endif void Precache(); void Spawn(); void OnRestore(); @@ -65,6 +72,9 @@ class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics bool IsPlayerPlaced() { return m_bPlacedByPlayer; } + // Determines whether companions should treat the mine as a navigation obstacle and avoid it + bool ShouldBeAvoidedByCompanions(); + bool CreateVPhysics() { VPhysicsInitNormal( SOLID_VPHYSICS, 0, false ); @@ -76,6 +86,14 @@ class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics void OpenHooks( bool bSilent = false ); void CloseHooks(); +#ifdef MAPBASE + // Uses the new CBaseEntity interaction implementation and replaces the dynamic_casting from npc_barnacle + bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); + + void UpdateWarnSound( float flVolume, float flDelta ); + void SilenceWarnSound( float flDelta ); +#endif + DECLARE_DATADESC(); static string_t gm_iszFloorTurretClassname; @@ -104,6 +122,19 @@ class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics float m_flIgnoreWorldTime; bool m_bDisarmed; +#ifdef MAPBASE + int m_iInitialState; + bool m_bCheapWarnSound; + + // Allows control over the mask used in LOS + int m_iLOSMask; + + bool m_bUnavoidable; + + // What direction the mine should be facing when planting itself (i.e. facing up, facing left, etc.) + // vec3_invalid = use default (0 0 1 or -90 0 0) + Vector m_vecPlantOrientation; +#endif bool m_bPlacedByPlayer; @@ -119,8 +150,29 @@ class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics IPhysicsConstraint *m_pConstraint; int m_iMineState; +#ifdef MAPBASE + // Makes the filters the exclusive factor in determining friend/foe + bool m_bFilterExclusive; + + string_t m_iszEnemyFilter; + CHandle m_hEnemyFilter; + void InputSetEnemyFilter( inputdata_t &inputdata ); + + string_t m_iszFriendFilter; + CHandle m_hFriendFilter; + void InputSetFriendFilter( inputdata_t &inputdata ); +#endif + COutputEvent m_OnPulledUp; void InputDisarm( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputBounce( inputdata_t &inputdata ); + void InputBounceAtTarget( inputdata_t &inputdata ); + void InputSetPlantOrientation( inputdata_t &inputdata ); + void InputSetPlantOrientationRaw( inputdata_t &inputdata ); + COutputEvent m_OnTriggered; + COutputEvent m_OnExplode; +#endif }; diff --git a/game/server/hl2/env_headcrabcanister.cpp b/game/server/hl2/env_headcrabcanister.cpp index ed1883d1..e94fe3f1 100644 --- a/game/server/hl2/env_headcrabcanister.cpp +++ b/game/server/hl2/env_headcrabcanister.cpp @@ -95,6 +95,9 @@ class CEnvHeadcrabCanister : public CBaseAnimating void InputOpenCanister( inputdata_t &inputdata ); void InputSpawnHeadcrabs( inputdata_t &inputdata ); void InputStopSmoke( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputStopHissing( inputdata_t &inputdata ); +#endif // Think(s) void HeadcrabCanisterSkyboxThink( void ); @@ -152,6 +155,9 @@ class CEnvHeadcrabCanister : public CBaseAnimating COutputEHANDLE m_OnLaunched; COutputEvent m_OnImpacted; COutputEvent m_OnOpened; +#ifdef MAPBASE + COutputEHANDLE m_OnCrab; +#endif // Only for skybox only cannisters. float m_flMinRefireTime; @@ -201,11 +207,17 @@ BEGIN_DATADESC( CEnvHeadcrabCanister ) DEFINE_INPUTFUNC( FIELD_VOID, "OpenCanister", InputOpenCanister ), DEFINE_INPUTFUNC( FIELD_VOID, "SpawnHeadcrabs", InputSpawnHeadcrabs ), DEFINE_INPUTFUNC( FIELD_VOID, "StopSmoke", InputStopSmoke ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "StopHissing", InputStopHissing ), +#endif // Outputs DEFINE_OUTPUT( m_OnLaunched, "OnLaunched" ), DEFINE_OUTPUT( m_OnImpacted, "OnImpacted" ), DEFINE_OUTPUT( m_OnOpened, "OnOpened" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnCrab, "OnCrab" ), +#endif END_DATADESC() @@ -545,6 +557,17 @@ void CEnvHeadcrabCanister::InputStopSmoke( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CEnvHeadcrabCanister::InputStopHissing( inputdata_t &inputdata ) +{ + StopSound( "HeadcrabCanister.AfterLanding" ); +} +#endif + //============================================================================= // // Enumerator for swept bbox collision. @@ -725,6 +748,10 @@ void CEnvHeadcrabCanister::HeadcrabCanisterSpawnHeadcrabThink() pHeadCrab->SetLocalOrigin( vec3_origin ); pHeadCrab->SetLocalAngles( vec3_angle ); pHeadCrab->CrawlFromCanister(); + +#ifdef MAPBASE + m_OnCrab.Set(pHeadCrab, pHeadCrab, this); +#endif } if ( m_nHeadcrabCount != 0 ) diff --git a/game/server/hl2/env_speaker.cpp b/game/server/hl2/env_speaker.cpp index dd141eca..94ff6ffa 100644 --- a/game/server/hl2/env_speaker.cpp +++ b/game/server/hl2/env_speaker.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -21,6 +21,9 @@ #include "ndebugoverlay.h" #include "soundscape.h" #include "AI_ResponseSystem.h" +#ifdef MAPBASE +#include "sceneentity.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -35,6 +38,10 @@ LINK_ENTITY_TO_CLASS( env_speaker, CSpeaker ); BEGIN_DATADESC( CSpeaker ) +#ifdef MAPBASE + DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), +#endif + DEFINE_KEYFIELD( m_delayMin, FIELD_FLOAT, "delaymin" ), DEFINE_KEYFIELD( m_delayMax, FIELD_FLOAT, "delaymax" ), DEFINE_KEYFIELD( m_iszRuleScriptFile, FIELD_STRING, "rulescript" ), @@ -50,6 +57,10 @@ BEGIN_DATADESC( CSpeaker ) DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnSpeak, "OnSpeak" ), +#endif + END_DATADESC() @@ -65,15 +76,15 @@ void CSpeaker::Spawn( void ) return; } -// const char *concept = (const char *)STRING( m_iszConcept ); -// if ( Q_strlen( concept ) < 1 ) +// const char *rrConcept = (const char *)STRING( m_iszConcept ); +// if ( Q_strlen( rrConcept ) < 1 ) // { // Warning( "'speaker' entity using rule set %s with empty concept string\n", soundfile ); // } SetSolid( SOLID_NONE ); SetMoveType( MOVETYPE_NONE ); - + SetThink(&CSpeaker::SpeakerThink); SetNextThink( TICK_NEVER_THINK ); @@ -100,7 +111,7 @@ void CSpeaker::Precache( void ) //----------------------------------------------------------------------------- // Purpose: Need a custom save restore so we can restore the instanced response system by name // after we've loaded the filename from disk... -// Input : &save - +// Input : &save - //----------------------------------------------------------------------------- int CSpeaker::Save( ISave &save ) { @@ -123,8 +134,8 @@ int CSpeaker::Save( ISave &save ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &restore - +// Purpose: +// Input : &restore - //----------------------------------------------------------------------------- int CSpeaker::Restore( IRestore &restore ) { @@ -171,16 +182,173 @@ void CSpeaker::SpeakerThink( void ) SetNextThink( releaseTime ); return; } - + DispatchResponse( m_iszConcept.ToCStr() ); SetNextThink( gpGlobals->curtime + random->RandomFloat(m_delayMin, m_delayMax) ); // time delay until it's ok to speak: used so that two NPCs don't talk at once - g_AIFriendliesTalkSemaphore.Acquire( 5, this ); - g_AIFoesTalkSemaphore.Acquire( 5, this ); + g_AIFriendliesTalkSemaphore.Acquire( 5, this ); + g_AIFoesTalkSemaphore.Acquire( 5, this ); +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CBaseEntity *CSpeaker::GetTarget() +{ + if (!m_hTarget && m_target != NULL_STRING) + m_hTarget = gEntList.FindEntityByName(NULL, STRING(m_target), this, NULL, this); + return m_hTarget; } +//----------------------------------------------------------------------------- +// Purpose: Copied from CBaseEntity so we could use a !target for everything +// Input : *conceptName - +//----------------------------------------------------------------------------- +void CSpeaker::DispatchResponse( const char *conceptName ) +{ + IResponseSystem *rs = GetResponseSystem(); + if ( !rs ) + return; + + CBaseEntity *pTarget = GetTarget(); + if (!pTarget) + pTarget = this; + + // See CBaseEntity and stuff... + AI_CriteriaSet set; + set.AppendCriteria( "concept", conceptName, CONCEPT_WEIGHT ); + ModifyOrAppendCriteria( set ); + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + ReAppendContextCriteria( set ); + AI_Response result; + bool found = rs->FindBestResponse( set, result ); + if ( !found ) + { + return; + } + + // Handle the response here... + char response[ 256 ]; + result.GetResponse( response, sizeof( response ) ); + if (response[0] == '$') + { + response[0] = '\0'; + DevMsg("Replacing %s with %s...\n", response, GetContextValue(response)); + Q_strncpy(response, GetContextValue(response), sizeof(response)); + PrecacheScriptSound( response ); + } + +#ifdef NEW_RESPONSE_SYSTEM + switch (result.GetType()) + { + case ResponseRules::RESPONSE_SPEAK: + { + pTarget->EmitSound( response ); + } + break; + case ResponseRules::RESPONSE_SENTENCE: + { + int sentenceIndex = SENTENCEG_Lookup( response ); + if (sentenceIndex == -1) + { + // sentence not found + break; + } + + // FIXME: Get pitch from npc? + CPASAttenuationFilter filter( pTarget ); + CBaseEntity::EmitSentenceByIndex( filter, pTarget->entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); + } + break; + case ResponseRules::RESPONSE_SCENE: + { + CBaseFlex *pFlex = NULL; + if (pTarget != this) + { + // Attempt to get flex on the target + pFlex = dynamic_cast(pTarget); + } + InstancedScriptedScene(pFlex, response); + } + break; + case ResponseRules::RESPONSE_PRINT: + { + + } + break; + case ResponseRules::RESPONSE_ENTITYIO: + { + CAI_Expresser::FireEntIOFromResponse( response, pTarget ); + break; + } +#ifdef MAPBASE_VSCRIPT + case ResponseRules::RESPONSE_VSCRIPT: + { + CAI_Expresser::RunScriptResponse( pTarget, response, &set, false ); + break; + } + case ResponseRules::RESPONSE_VSCRIPT_FILE: + { + CAI_Expresser::RunScriptResponse( pTarget, response, &set, true ); + break; + } +#endif + default: + break; + } +#else + switch ( result.GetType() ) + { + case RESPONSE_SPEAK: + { + pTarget->EmitSound( response ); + } + break; + case RESPONSE_SENTENCE: + { + int sentenceIndex = SENTENCEG_Lookup( response ); + if( sentenceIndex == -1 ) + { + // sentence not found + break; + } + + // FIXME: Get pitch from npc? + CPASAttenuationFilter filter( pTarget ); + CBaseEntity::EmitSentenceByIndex( filter, pTarget->entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); + } + break; + case RESPONSE_SCENE: + { + CBaseFlex *pFlex = NULL; + if (pTarget != this) + { + // Attempt to get flex on the target + pFlex = dynamic_cast(pTarget); + } + InstancedScriptedScene(pFlex, response); + } + break; + case RESPONSE_PRINT: + { + + } + break; + default: + break; + } +#endif + + // AllocPooledString? + m_OnSpeak.Set(MAKE_STRING(response), pTarget, this); +} +#endif + void CSpeaker::InputTurnOn( inputdata_t &inputdata ) { @@ -209,9 +377,9 @@ void CSpeaker::InputToggle( inputdata_t &inputdata ) // turn off announcements SetNextThink( TICK_NEVER_THINK ); } - else + else { // turn on announcements SetNextThink( gpGlobals->curtime + 0.1f ); - } + } } diff --git a/game/server/hl2/env_speaker.h b/game/server/hl2/env_speaker.h index 20fbeb6b..a28a2a47 100644 --- a/game/server/hl2/env_speaker.h +++ b/game/server/hl2/env_speaker.h @@ -36,6 +36,13 @@ class CSpeaker : public CPointEntity void SpeakerThink( void ); +#ifdef MAPBASE + EHANDLE m_hTarget; + virtual void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); m_hTarget = NULL; } + CBaseEntity *GetTarget(); + virtual void DispatchResponse( const char *conceptName ); +#endif + void InputToggle( inputdata_t &inputdata ); float m_delayMin; @@ -49,6 +56,10 @@ class CSpeaker : public CPointEntity void InputTurnOff( inputdata_t &inputdata ); void InputTurnOn( inputdata_t &inputdata ); + +#ifdef MAPBASE + COutputString m_OnSpeak; +#endif }; #endif // ENV_SPEAKER_H diff --git a/game/server/hl2/func_recharge.cpp b/game/server/hl2/func_recharge.cpp index 37c42637..c3bf74c1 100644 --- a/game/server/hl2/func_recharge.cpp +++ b/game/server/hl2/func_recharge.cpp @@ -35,6 +35,9 @@ class CRecharge : public CBaseToggle DECLARE_CLASS( CRecharge, CBaseToggle ); void Spawn( ); +#ifdef MAPBASE + void Precache( void ); +#endif bool CreateVPhysics(); int DrawDebugTextOverlays(void); void Off(void); @@ -45,6 +48,10 @@ class CRecharge : public CBaseToggle private: void InputRecharge( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetCharge( inputdata_t &inputdata ); + void InputSetChargeNoMax( inputdata_t &inputdata ); +#endif float MaxJuice() const; void UpdateJuice( int newJuice ); @@ -56,6 +63,10 @@ class CRecharge : public CBaseToggle int m_iJuice; int m_iOn; // 0 = off, 1 = startup, 2 = going float m_flSoundTime; +#ifdef MAPBASE + int m_iMaxJuice; + int m_iIncrementValue; +#endif int m_nState; @@ -70,9 +81,16 @@ BEGIN_DATADESC( CRecharge ) DEFINE_FIELD( m_flNextCharge, FIELD_TIME ), DEFINE_FIELD( m_iReactivate, FIELD_INTEGER), - DEFINE_FIELD( m_iJuice, FIELD_INTEGER), +#ifdef MAPBASE + DEFINE_KEYFIELD(m_iJuice, FIELD_INTEGER, "Charge"), +#else + DEFINE_FIELD(m_iJuice, FIELD_INTEGER), +#endif DEFINE_FIELD( m_iOn, FIELD_INTEGER), DEFINE_FIELD( m_flSoundTime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_INPUT( m_iIncrementValue, FIELD_INTEGER, "SetIncrementValue" ), +#endif DEFINE_FIELD( m_nState, FIELD_INTEGER ), // Function Pointers @@ -86,6 +104,10 @@ BEGIN_DATADESC( CRecharge ) DEFINE_OUTPUT(m_OnPlayerUse, "OnPlayerUse" ), DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCharge", InputSetCharge ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetChargeNoMax", InputSetChargeNoMax ), +#endif END_DATADESC() @@ -123,13 +145,30 @@ void CRecharge::Spawn() SetModel( STRING( GetModelName() ) ); +#ifdef MAPBASE + // In case the juice was overridden + if (m_iJuice == 0) + UpdateJuice( MaxJuice() ); + else if (m_iJuice == -1) + m_iJuice = 0; +#else UpdateJuice( MaxJuice() ); +#endif m_nState = 0; CreateVPhysics(); } +#ifdef MAPBASE +void CRecharge::Precache( void ) +{ + PrecacheScriptSound( "SuitRecharge.Deny" ); + PrecacheScriptSound( "SuitRecharge.Start" ); + PrecacheScriptSound( "SuitRecharge.ChargingLoop" ); +} +#endif + bool CRecharge::CreateVPhysics() { VPhysicsInitStatic(); @@ -156,6 +195,14 @@ int CRecharge::DrawDebugTextOverlays(void) //----------------------------------------------------------------------------- float CRecharge::MaxJuice() const { +#ifdef MAPBASE + if ( m_iMaxJuice != 0 ) + { + // It must've been overridden by the mapper + return m_iMaxJuice; + } +#endif + if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) { return sk_suitcharger_citadel.GetFloat(); @@ -199,6 +246,18 @@ void CRecharge::InputRecharge( inputdata_t &inputdata ) Recharge(); } +#ifdef MAPBASE +void CRecharge::InputSetCharge( inputdata_t &inputdata ) +{ + m_iMaxJuice = m_iJuice = inputdata.value.Int(); +} + +void CRecharge::InputSetChargeNoMax( inputdata_t &inputdata ) +{ + UpdateJuice(inputdata.value.Int()); +} +#endif + void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // if it's not a player, ignore @@ -287,6 +346,11 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use } } +#ifdef MAPBASE + if (m_iIncrementValue != 0) + nIncrementArmor = m_iIncrementValue; +#endif + if (pl->ArmorValue() < nMaxArmor) { UpdateJuice( m_iJuice - nIncrementArmor ); @@ -350,6 +414,9 @@ class CNewRecharge : public CBaseAnimating private: void InputRecharge( inputdata_t &inputdata ); void InputSetCharge( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetChargeNoMax( inputdata_t &inputdata ); +#endif float MaxJuice() const; void UpdateJuice( int newJuice ); void Precache( void ); @@ -365,6 +432,9 @@ class CNewRecharge : public CBaseAnimating int m_nState; int m_iCaps; int m_iMaxJuice; +#ifdef MAPBASE + int m_iIncrementValue; +#endif COutputFloat m_OutRemainingCharge; COutputEvent m_OnHalfEmpty; @@ -380,12 +450,21 @@ BEGIN_DATADESC( CNewRecharge ) DEFINE_FIELD( m_flNextCharge, FIELD_TIME ), DEFINE_FIELD( m_iReactivate, FIELD_INTEGER), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iJuice, FIELD_INTEGER, "Charge" ), +#else DEFINE_FIELD( m_iJuice, FIELD_INTEGER), +#endif DEFINE_FIELD( m_iOn, FIELD_INTEGER), DEFINE_FIELD( m_flSoundTime, FIELD_TIME ), DEFINE_FIELD( m_nState, FIELD_INTEGER ), DEFINE_FIELD( m_iCaps, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iMaxJuice, FIELD_INTEGER, "MaxCharge" ), + DEFINE_INPUT( m_iIncrementValue, FIELD_INTEGER, "SetIncrementValue" ), +#else DEFINE_FIELD( m_iMaxJuice, FIELD_INTEGER ), +#endif // Function Pointers DEFINE_FUNCTION( Off ), @@ -400,6 +479,9 @@ BEGIN_DATADESC( CNewRecharge ) DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCharge", InputSetCharge ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetChargeNoMax", InputSetChargeNoMax ), +#endif END_DATADESC() @@ -412,6 +494,10 @@ LINK_ENTITY_TO_CLASS( item_suitcharger, CNewRecharge); #define CITADEL_CHARGES_PER_SECOND 10 / CHARGE_RATE #define CALLS_PER_SECOND 7.0f * CHARGES_PER_SECOND +#ifdef MAPBASE +#define CUSTOM_CHARGES_PER_SECOND(inc) inc / CHARGE_RATE +#endif + bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue ) { @@ -436,7 +522,14 @@ bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue ) void CNewRecharge::Precache( void ) { +#ifdef MAPBASE + if ( GetModelName() == NULL_STRING ) + SetModelName( AllocPooledString(HEALTH_CHARGER_MODEL_NAME) ); + + PrecacheModel( STRING(GetModelName()) ); +#else PrecacheModel( HEALTH_CHARGER_MODEL_NAME ); +#endif PrecacheScriptSound( "SuitRecharge.Deny" ); PrecacheScriptSound( "SuitRecharge.Start" ); @@ -446,6 +539,14 @@ void CNewRecharge::Precache( void ) void CNewRecharge::SetInitialCharge( void ) { +#ifdef MAPBASE + if ( m_iMaxJuice != 0 ) + { + // It must've been overridden by the mapper + return; + } +#endif + if ( HasSpawnFlags( SF_KLEINER_RECHARGER ) ) { // The charger in Kleiner's lab. @@ -470,14 +571,31 @@ void CNewRecharge::Spawn() SetSolid( SOLID_VPHYSICS ); CreateVPhysics(); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else SetModel( HEALTH_CHARGER_MODEL_NAME ); +#endif AddEffects( EF_NOSHADOW ); ResetSequence( LookupSequence( "idle" ) ); SetInitialCharge(); +#ifdef MAPBASE + // In case the juice was overridden + if (m_iJuice == 0) + UpdateJuice( MaxJuice() ); + else if (m_iJuice == -1) + { + UpdateJuice( 0 ); + ResetSequence( LookupSequence( "empty" ) ); + } + else + UpdateJuice( m_iJuice ); +#else UpdateJuice( MaxJuice() ); +#endif m_nState = 0; m_iCaps = FCAP_CONTINUOUS_USE; @@ -579,13 +697,25 @@ void CNewRecharge::InputRecharge( inputdata_t &inputdata ) void CNewRecharge::InputSetCharge( inputdata_t &inputdata ) { - ResetSequence( LookupSequence( "idle" ) ); - int iJuice = inputdata.value.Int(); m_flJuice = m_iMaxJuice = m_iJuice = iJuice; + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); + StudioFrameAdvance(); +} + +#ifdef MAPBASE +void CNewRecharge::InputSetChargeNoMax( inputdata_t &inputdata ) +{ + m_flJuice = inputdata.value.Float(); + + UpdateJuice(m_flJuice); + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); StudioFrameAdvance(); } +#endif void CNewRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { @@ -606,6 +736,11 @@ void CNewRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) flCharges = CITADEL_CHARGES_PER_SECOND; +#ifdef MAPBASE + if ( m_iIncrementValue != 0 ) + flCharges = CUSTOM_CHARGES_PER_SECOND(m_iIncrementValue); +#endif + m_flJuice -= flCharges / flCalls; StudioFrameAdvance(); } @@ -667,6 +802,11 @@ void CNewRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE } } +#ifdef MAPBASE + if (m_iIncrementValue != 0) + nIncrementArmor = m_iIncrementValue; +#endif + // If we're over our limit, debounce our keys if ( pPlayer->ArmorValue() >= nMaxArmor) { diff --git a/game/server/hl2/func_tank.cpp b/game/server/hl2/func_tank.cpp index db5a2e32..c4462575 100644 --- a/game/server/hl2/func_tank.cpp +++ b/game/server/hl2/func_tank.cpp @@ -39,6 +39,10 @@ #include "particle_parse.h" // NVNT turret recoil #include "haptics/haptic_utils.h" +#ifdef MAPBASE +#include "shot_manipulator.h" +#include "filters.h" +#endif #ifdef HL2_DLL #include "hl2_player.h" @@ -49,6 +53,10 @@ extern Vector PointOnLineNearestPoint(const Vector& vStartPos, const Vector& vEndPos, const Vector& vPoint); +#ifdef MAPBASE +extern ConVar ai_debug_shoot_positions; +#endif + ConVar mortar_visualize("mortar_visualize", "0" ); BEGIN_DATADESC( CFuncTank ) @@ -70,13 +78,19 @@ BEGIN_DATADESC( CFuncTank ) DEFINE_KEYFIELD( m_spriteScale, FIELD_FLOAT, "spritescale" ), DEFINE_KEYFIELD( m_iszSpriteSmoke, FIELD_STRING, "spritesmoke" ), DEFINE_KEYFIELD( m_iszSpriteFlash, FIELD_STRING, "spriteflash" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszShootSound, FIELD_SOUNDNAME, "shootsound" ), +#endif +#ifndef AMMOTYPE_MOVED DEFINE_KEYFIELD( m_bulletType, FIELD_INTEGER, "bullet" ), +#endif DEFINE_FIELD( m_nBulletCount, FIELD_INTEGER ), DEFINE_KEYFIELD( m_spread, FIELD_INTEGER, "firespread" ), DEFINE_KEYFIELD( m_iBulletDamage, FIELD_INTEGER, "bullet_damage" ), DEFINE_KEYFIELD( m_iBulletDamageVsPlayer, FIELD_INTEGER, "bullet_damage_vs_player" ), DEFINE_KEYFIELD( m_iszMaster, FIELD_STRING, "master" ), +#ifndef AMMOTYPE_MOVED #ifdef HL2_EPISODIC DEFINE_KEYFIELD( m_iszAmmoType, FIELD_STRING, "ammotype" ), DEFINE_FIELD( m_iAmmoType, FIELD_INTEGER ), @@ -85,6 +99,7 @@ BEGIN_DATADESC( CFuncTank ) DEFINE_FIELD( m_iMediumAmmoType, FIELD_INTEGER ), DEFINE_FIELD( m_iLargeAmmoType, FIELD_INTEGER ), #endif // HL2_EPISODIC +#endif // AMMOTYPE_MOVED DEFINE_KEYFIELD( m_soundStartRotate, FIELD_SOUNDNAME, "rotatestartsound" ), DEFINE_KEYFIELD( m_soundStopRotate, FIELD_SOUNDNAME, "rotatestopsound" ), @@ -115,7 +130,11 @@ BEGIN_DATADESC( CFuncTank ) DEFINE_FIELD( m_hControlVolume, FIELD_EHANDLE ), DEFINE_KEYFIELD( m_iszControlVolume, FIELD_STRING, "control_volume" ), DEFINE_FIELD( m_flNextControllerSearch, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bShouldFindNPCs, FIELD_BOOLEAN, "ShouldFindNPCs" ), +#else DEFINE_FIELD( m_bShouldFindNPCs, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_bNPCInRoute, FIELD_BOOLEAN ), DEFINE_KEYFIELD( m_iszNPCManPoint, FIELD_STRING, "npc_man_point" ), DEFINE_FIELD( m_bReadyToFire, FIELD_BOOLEAN ), @@ -140,6 +159,16 @@ BEGIN_DATADESC( CFuncTank ) DEFINE_KEYFIELD( m_iEffectHandling, FIELD_INTEGER, "effecthandling" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDontHitController, FIELD_BOOLEAN, "DontHitController" ), + DEFINE_KEYFIELD( m_bControllerGlued, FIELD_BOOLEAN, "ControllerGlued" ), + + DEFINE_KEYFIELD( m_iszTraceFilter, FIELD_STRING, "TraceFilter" ), + DEFINE_FIELD( m_hTraceFilter, FIELD_EHANDLE ), + + DEFINE_KEYFIELD( m_flPlayerBBoxDist, FIELD_FLOAT, "PlayerBBoxDist" ), +#endif + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), @@ -151,6 +180,10 @@ BEGIN_DATADESC( CFuncTank ) DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetTargetEntity", InputSetTargetEntity ), DEFINE_INPUTFUNC( FIELD_VOID, "ClearTargetEntity", InputClearTargetEntity ), DEFINE_INPUTFUNC( FIELD_STRING, "FindNPCToManTank", InputFindNPCToManTank ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "TeleportNPCToManTank", InputTeleportNPCToManTank ), + DEFINE_INPUTFUNC( FIELD_STRING, "ForceNPCToManTank", InputForceNPCToManTank ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "StopFindingNPCs", InputStopFindingNPCs ), DEFINE_INPUTFUNC( FIELD_VOID, "StartFindingNPCs", InputStartFindingNPCs ), DEFINE_INPUTFUNC( FIELD_VOID, "ForceNPCOff", InputForceNPCOff ), @@ -178,6 +211,10 @@ CFuncTank::CFuncTank() m_bNPCInRoute = false; m_flNextControllerSearch = 0; m_bShouldFindNPCs = true; + +#ifdef MAPBASE + m_flPlayerBBoxDist = 24; +#endif } //----------------------------------------------------------------------------- @@ -353,7 +390,11 @@ void CFuncTank::InputFindNPCToManTank( inputdata_t &inputdata ) return; // NPC assigned to man the func_tank? +#ifdef MAPBASE + CBaseEntity *pEntity = gEntList.FindEntityByNameNearest( inputdata.value.String(), GetAbsOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.StringID() ); +#endif if ( pEntity ) { CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); @@ -361,7 +402,11 @@ void CFuncTank::InputFindNPCToManTank( inputdata_t &inputdata ) { // Verify the npc has the func_tank controller behavior. CAI_FuncTankBehavior *pBehavior; +#ifdef MAPBASE + if ( pNPC->GetBehavior( &pBehavior ) && pBehavior->CanManTank( this, true ) ) +#else if ( pNPC->GetBehavior( &pBehavior ) ) +#endif { m_hController = pNPC; pBehavior->SetFuncTank( this ); @@ -375,6 +420,124 @@ void CFuncTank::InputFindNPCToManTank( inputdata_t &inputdata ) NPC_FindController(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for telling the func_tank to teleport an NPC to man it. +//----------------------------------------------------------------------------- +void CFuncTank::InputTeleportNPCToManTank( inputdata_t &inputdata ) +{ + // Verify the func_tank is controllable and available. + if ( !IsNPCControllable() && !IsNPCSetController() ) + return; + + // If we have a controller already - don't look for one. + if ( HasController() ) + return; + + // NPC assigned to man the func_tank? + CBaseEntity *pEntity = gEntList.FindEntityByNameNearest( inputdata.value.String(), GetAbsOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller ); + if ( pEntity ) + { + CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); + if ( pNPC ) + { + // Verify the npc has the func_tank controller behavior. + CAI_FuncTankBehavior *pBehavior; + if ( pNPC->GetBehavior( &pBehavior ) && pBehavior->CanManTank( this, true ) ) + { + Vector vecVec; + QAngle angAng; + Vector vecVel = vec3_origin; + if ( m_iszNPCManPoint != NULL_STRING ) + { + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, m_iszNPCManPoint, this ); + if ( pEntity ) + { + vecVec = pEntity->GetAbsOrigin(); + } + } + + angAng = pNPC->GetAbsAngles(); + angAng.y = UTIL_VecToYaw ( GetAbsOrigin() - vecVec ); // Yaw from man point to turret + + pNPC->Teleport(&vecVec, &angAng, &vecVel); + + m_hController = pNPC; + pBehavior->SetFuncTank( this ); + NPC_SetInRoute( true ); + +#if 1 + pNPC->GetMotor()->SetIdealYawToTarget( GetAbsOrigin() ); + pNPC->SetTurnActivity(); + + pNPC->DoHolster(); + + pNPC->SpeakSentence( FUNCTANK_SENTENCE_JUST_MOUNTED ); + + // We are at the correct position and facing for the func_tank, mount it. + StartControl( pNPC ); + pNPC->ClearEnemyMemory(); + pBehavior->SetMounted(true); + + pNPC->SetIdealActivity( ACT_IDLE_MANNEDGUN ); +#endif + + return; + } + } + } + else + { + Warning("%s unable to find NPC \"%s\" to teleport to tank\n", GetDebugName(), inputdata.value.String()); + } + + // NPC_FindController() doesn't return a NPC and teleporting a random NPC seems kind of dangerous anyway. +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for telling the func_tank to find a NPC and instantly make them man it, no matter what they're doing or where they are. +//----------------------------------------------------------------------------- +void CFuncTank::InputForceNPCToManTank( inputdata_t &inputdata ) +{ + // Verify the func_tank is controllable and available. + if ( !IsNPCControllable() && !IsNPCSetController() ) + return; + + // If we have a controller already - don't look for one. + if ( HasController() ) + return; + + // NPC assigned to man the func_tank? + CBaseEntity *pEntity = gEntList.FindEntityByNameNearest( inputdata.value.String(), GetAbsOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller ); + if ( pEntity ) + { + CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); + if ( pNPC ) + { + // Verify the npc has the func_tank controller behavior. + CAI_FuncTankBehavior *pBehavior; + if ( pNPC->GetBehavior( &pBehavior ) && pBehavior->CanManTank( this, true ) ) + { + // Set the forced condition + pBehavior->SetCondition( CAI_FuncTankBehavior::COND_FUNCTANK_FORCED ); + + m_hController = pNPC; + pBehavior->SetFuncTank( this ); + NPC_SetInRoute( true ); + + return; + } + } + } + else + { + Warning("%s unable to find NPC \"%s\" to force to tank\n", GetDebugName(), inputdata.value.String()); + } + + // NPC_FindController() doesn't return a NPC and teleporting a random NPC seems kind of dangerous anyway. +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : &inputdata - @@ -468,7 +631,11 @@ void CFuncTank::NPC_FindController( void ) continue; CAI_FuncTankBehavior *pBehavior; +#ifdef MAPBASE + if ( pNPC->GetBehavior( &pBehavior ) && pBehavior->CanManTank( this, false ) ) +#else if ( pNPC->GetBehavior( &pBehavior ) ) +#endif { // Don't mount the func_tank if your "enemy" is within X feet or it or the npc. CBaseEntity *pEnemy = pNPC->GetEnemy(); @@ -735,13 +902,16 @@ void CFuncTank::Spawn( void ) { Precache(); +#ifndef AMMOTYPE_MOVED #ifdef HL2_EPISODIC - m_iAmmoType = GetAmmoDef()->Index( STRING( m_iszAmmoType ) ); + m_iAmmoType = GetAmmoDef()->Index(STRING(m_iszAmmoType)); #else - m_iSmallAmmoType = GetAmmoDef()->Index("Pistol"); - m_iMediumAmmoType = GetAmmoDef()->Index("SMG1"); - m_iLargeAmmoType = GetAmmoDef()->Index("AR2"); -#endif // HL2_EPISODIC + m_iSmallAmmoType = GetAmmoDef()->Index("Pistol"); + m_iMediumAmmoType = GetAmmoDef()->Index("SMG1"); + m_iLargeAmmoType = GetAmmoDef()->Index("AR2"); +#endif // HL2_EPISODIC +#endif // AMMOTYPE_MOVED + SetMoveType( MOVETYPE_PUSH ); // so it doesn't get pushed by anything SetSolid( SOLID_VPHYSICS ); @@ -878,6 +1048,15 @@ void CFuncTank::Activate( void ) m_nBarrelAttachment = pAnim->LookupAttachment( STRING(m_iszBarrelAttachment) ); } } + +#ifdef MAPBASE + if ( m_iszTraceFilter != NULL_STRING ) + { + m_hTraceFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszTraceFilter) )); + if (!m_hTraceFilter) + Warning("WARNING: %s trace filter %s is not a filter!\n", GetDebugName(), STRING(m_iszTraceFilter)); + } +#endif } bool CFuncTank::CreateVPhysics() @@ -893,6 +1072,10 @@ void CFuncTank::Precache( void ) PrecacheModel( STRING(m_iszSpriteSmoke) ); if ( m_iszSpriteFlash != NULL_STRING ) PrecacheModel( STRING(m_iszSpriteFlash) ); +#ifdef MAPBASE + if ( m_iszShootSound != NULL_STRING ) + PrecacheScriptSound( STRING(m_iszShootSound) ); +#endif if ( m_soundStartRotate != NULL_STRING ) PrecacheScriptSound( STRING(m_soundStartRotate) ); @@ -1046,6 +1229,16 @@ bool CFuncTank::StartControl( CBaseCombatCharacter *pController ) SetNextThink( gpGlobals->curtime + 0.1f ); // Let the map maker know a controller has been found +#ifdef MAPBASE + if ( m_hController->IsPlayer() ) + { + m_OnGotPlayerController.FireOutput( m_hController, this ); + } + else + { + m_OnGotController.FireOutput( m_hController, this ); + } +#else if ( m_hController->IsPlayer() ) { m_OnGotPlayerController.FireOutput( this, this ); @@ -1054,6 +1247,7 @@ bool CFuncTank::StartControl( CBaseCombatCharacter *pController ) { m_OnGotController.FireOutput( this, this ); } +#endif OnStartControlled(); return true; @@ -1071,8 +1265,13 @@ void CFuncTank::StopControl() OnStopControlled(); +#ifdef MAPBASE + // Arm player/npc weapon if they're not in a vehicle. + if ( !m_hController->IsInAVehicle() && m_hController->GetActiveWeapon() ) +#else // Arm player/npc weapon. if ( m_hController->GetActiveWeapon() ) +#endif { m_hController->GetActiveWeapon()->Deploy(); } @@ -1087,6 +1286,16 @@ void CFuncTank::StopControl() SetNextThink( TICK_NEVER_THINK ); // Let the map maker know a controller has been lost. +#ifdef MAPBASE + if ( m_hController->IsPlayer() ) + { + m_OnLostPlayerController.FireOutput( m_hController, this ); + } + else + { + m_OnLostController.FireOutput( m_hController, this ); + } +#else if ( m_hController->IsPlayer() ) { m_OnLostPlayerController.FireOutput( this, this ); @@ -1095,6 +1304,7 @@ void CFuncTank::StopControl() { m_OnLostController.FireOutput( this, this ); } +#endif // Reset the func_tank as unmanned (player/npc). if ( m_hController->IsPlayer() ) @@ -1161,7 +1371,12 @@ void CFuncTank::ControllerPostFrame( void ) Vector start = WorldBarrelPosition(); Vector dir = forward; +#ifdef MAPBASE + CTraceFilterSimple traceFilter = GetTraceFilter(); + UTIL_TraceHull( start, start + forward * 8192, -Vector(8,8,8), Vector(8,8,8), MASK_SHOT, &traceFilter, &tr ); +#else UTIL_TraceHull( start, start + forward * 8192, -Vector(8,8,8), Vector(8,8,8), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); +#endif if( tr.m_pEnt && tr.m_pEnt->m_takedamage != DAMAGE_NO && (tr.m_pEnt->GetFlags() & FL_AIMTARGET) ) { @@ -1189,6 +1404,9 @@ void CFuncTank::ControllerPostFrame( void ) if( --m_iAmmoCount == 0 ) { // Kick the player off the gun, and make myself not usable. +#ifdef MAPBASE + m_OnAmmoDepleted.FireOutput(pPlayer, this); +#endif m_spawnflags &= ~SF_TANK_CANCONTROL; StopControl(); return; @@ -1335,6 +1553,11 @@ void CFuncTank::NPC_Fire( void ) { SetNextAttack( gpGlobals->curtime + m_fireTime ); } + +#ifdef MAPBASE + // This is now needed in some cases + m_fireLast = gpGlobals->curtime; +#endif } @@ -1660,6 +1883,15 @@ QAngle CFuncTank::AimBarrelAt( const Vector &parentTarget ) { return GetLocalAngles(); } +#ifdef MAPBASE + else if ( m_barrelPos.LengthSqr() == 0.0f ) + { + // Do a simpler calculation that doesn't take barrel into account + float targetToCenterYaw = atan2( target.y, target.x ); + float targetToCenterPitch = atan2( target.z, sqrt( quadTargetXY ) ); + return QAngle( -RAD2DEG( targetToCenterPitch ), RAD2DEG( targetToCenterYaw ), 0 ); + } +#endif else { // We're trying to aim the offset barrel at an arbitrary point. @@ -1706,8 +1938,14 @@ void CFuncTank::CalcPlayerCrosshairTarget( Vector *pVecTarget ) vecDir = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT ); } +#ifdef MAPBASE + CTraceFilterSimple traceFilter = GetTraceFilter(); + UTIL_TraceLine( vecStart + vecDir * m_flPlayerBBoxDist, vecStart + vecDir * 8192, MASK_BLOCKLOS_AND_NPCS, &traceFilter, &tr ); + //DebugDrawLine(tr.startpos, tr.endpos, 222, 222, 0, false, 0.1); +#else // Make sure to start the trace outside of the player's bbox! UTIL_TraceLine( vecStart + vecDir * 24, vecStart + vecDir * 8192, MASK_BLOCKLOS_AND_NPCS, this, COLLISION_GROUP_NONE, &tr ); +#endif *pVecTarget = tr.endpos; } @@ -1822,11 +2060,15 @@ bool CFuncTank::RotateTankToAngles( const QAngle &angles, float *pDistX, float * //----------------------------------------------------------------------------- // We lost our target! //----------------------------------------------------------------------------- -void CFuncTank::LostTarget( void ) +void CFuncTank::LostTarget( CBaseEntity *pTarget ) { if (m_fireLast != 0) { +#ifdef MAPBASE + m_OnLoseTarget.Set(pTarget, pTarget, this); +#else m_OnLoseTarget.FireOutput(this, this); +#endif m_fireLast = 0; } } @@ -1929,7 +2171,11 @@ void CFuncTank::AimFuncTankAtTarget( void ) m_hTarget = FindTarget( m_targetEntityName, NULL ); } +#ifdef MAPBASE + LostTarget(pEntity); +#else LostTarget(); +#endif return; } @@ -1953,8 +2199,13 @@ void CFuncTank::AimFuncTankAtTarget( void ) { if ( m_hTarget ) { +#ifdef MAPBASE + LostTarget(m_hTarget); + m_hTarget = NULL; +#else m_hTarget = NULL; LostTarget(); +#endif } return; } @@ -2053,18 +2304,30 @@ void CFuncTank::AimFuncTankAtTarget( void ) { if (m_fireLast == 0) { +#ifdef MAPBASE + m_OnAquireTarget.Set(pTarget, pTarget, this); +#else m_OnAquireTarget.FireOutput(this, this); +#endif } FiringSequence( barrelEnd, forward, this ); } else { +#ifdef MAPBASE + LostTarget(pTarget); +#else LostTarget(); +#endif } } else { +#ifdef MAPBASE + LostTarget(pTarget); +#else LostTarget(); +#endif } } @@ -2203,6 +2466,55 @@ const char *CFuncTank::GetTracerType( void ) //----------------------------------------------------------------------------- void CFuncTank::Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread ) { +#ifdef MAPBASE + bool bSpriteSmoke = m_iszSpriteSmoke != NULL_STRING; + bool bSpriteFlash = m_iszSpriteFlash != NULL_STRING; + + if (bSpriteSmoke || bSpriteFlash) + { + if (bSpriteSmoke) + { + CSprite *pSmoke = CSprite::SpriteCreate( STRING(m_iszSpriteSmoke), barrelEnd, TRUE ); + pSmoke->AnimateAndDie( random->RandomFloat( 15.0, 20.0 ) ); + pSmoke->SetTransparency( kRenderTransAlpha, m_clrRender->r, m_clrRender->g, m_clrRender->b, 255, kRenderFxNone ); + + Vector vecVelocity( 0, 0, random->RandomFloat(40, 80) ); + pSmoke->SetAbsVelocity( vecVelocity ); + pSmoke->SetScale( m_spriteScale ); + } + + if (bSpriteFlash) + { + CSprite *pFlash = CSprite::SpriteCreate( STRING(m_iszSpriteFlash), barrelEnd, TRUE ); + pFlash->AnimateAndDie( 5 ); + pFlash->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); + pFlash->SetScale( m_spriteScale ); + } + } + else if ( m_iEffectHandling == EH_AR2 ) + { + DoMuzzleFlash(); + } + else if ( m_iEffectHandling == EH_COMBINE_CANNON ) + { + DoMuzzleFlash(); + } + + if (m_iszShootSound != NULL_STRING) + { + EmitSound(STRING(m_iszShootSound)); + } + else if ( m_iEffectHandling == EH_AR2 ) + { + // Play the AR2 sound + EmitSound( "Weapon_functank.Single" ); + } + else if ( m_iEffectHandling == EH_COMBINE_CANNON ) + { + // Play the cannon sound + EmitSound( "NPC_Combine_Cannon.FireBullet" ); + } +#else // If we have a specific effect handler, apply it's effects if ( m_iEffectHandling == EH_AR2 ) { @@ -2238,6 +2550,7 @@ void CFuncTank::Fire( int bulletCount, const Vector &barrelEnd, const Vector &fo pSprite->SetScale( m_spriteScale ); } } +#endif if( pAttacker && pAttacker->IsPlayer() ) { @@ -2252,7 +2565,11 @@ void CFuncTank::Fire( int bulletCount, const Vector &barrelEnd, const Vector &fo } +#ifdef MAPBASE + m_OnFire.FireOutput(pAttacker, this); +#else m_OnFire.FireOutput(this, this); +#endif m_bReadyToFire = false; } @@ -2384,6 +2701,84 @@ bool CFuncTank::IsEntityInViewCone( CBaseEntity *pEntity ) return true; } +#ifdef MAPBASE +//========================================================= +// I decided to make a custom trace filter for func_tank trace filters. +// If the base class thinks the trace should hit the entity, it goes through +// a filter and if it passes the filter, the trace passes the entity instead. +// +// This is different from CTraceFilterEntityFilter because it's simplified and can use its own exclusion list. +// (it also came before it) +//========================================================= +class CTankTraceFilter : public CTraceFilterSimpleList +{ +public: + CTankTraceFilter( int collisionGroup ) : CTraceFilterSimpleList( collisionGroup ) {} + + bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) + { + bool base = CTraceFilterSimpleList::ShouldHitEntity( pHandleEntity, contentsMask ); + + // Our base is telling us to hit. If it passes the filter, don't. + if ( base && m_pFilter ) + { + CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); + return !m_pFilter->PassesFilter(m_pCaller, pEntity); + + // TODO: Should we use this code from CBulletsTraceFilter? + /* + CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); + CBaseEntity *pPassEntity = EntityFromEntityHandle( m_PassEntities[0] ); + if ( pEntity && pPassEntity && pEntity->GetOwnerEntity() == pPassEntity && + pPassEntity->IsSolidFlagSet(FSOLID_NOT_SOLID) && pPassEntity->IsSolidFlagSet( FSOLID_CUSTOMBOXTEST ) && + pPassEntity->IsSolidFlagSet( FSOLID_CUSTOMRAYTEST ) ) + { + // It's a bone follower of the entity to ignore (toml 8/3/2007) + return false; + } + */ + } + + return base; + } + + CBaseFilter *m_pFilter; + CBaseEntity *m_pCaller; + +}; + +//----------------------------------------------------------------------------- +// Purpose: Gets our general trace filter we use for LOS, trace locations, etc. +// This was created so we could easily change the trace filter func_tank generally uses, +// but it can be overridden by derived classes, so there's that. +//----------------------------------------------------------------------------- +CTraceFilterSimple CFuncTank::GetTraceFilter() +{ + //CTraceFilterSkipTwoEntities traceFilter( this, GetParent(), COLLISION_GROUP_NONE ); + + CTankTraceFilter traceFilter( COLLISION_GROUP_NONE ); + traceFilter.SetPassEntity(this); + + if (GetParent()) + { + CBaseEntity *pParent = GetParent(); + traceFilter.AddEntityToIgnore(pParent); + + // Add the parent's parent too. (for func_tanks mounted on moving things, like vehicles) + if (pParent->GetParent()) + traceFilter.AddEntityToIgnore(pParent->GetParent()); + } + + if (m_bDontHitController) + traceFilter.AddEntityToIgnore(GetController()); + + traceFilter.m_pFilter = m_hTraceFilter.Get(); + traceFilter.m_pCaller = this; + + return traceFilter; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Return true if this func tank can see the enemy //----------------------------------------------------------------------------- @@ -2398,7 +2793,11 @@ bool CFuncTank::HasLOSTo( CBaseEntity *pEntity ) trace_t tr; // Ignore the func_tank and any prop it's parented to +#ifdef MAPBASE + CTraceFilterSimple traceFilter = GetTraceFilter(); +#else CTraceFilterSkipTwoEntities traceFilter( this, GetParent(), COLLISION_GROUP_NONE ); +#endif // UNDONE: Should this hit BLOCKLOS brushes? AI_TraceLine( vecBarrelEnd, vecTarget, MASK_BLOCKLOS_AND_NPCS, &traceFilter, &tr ); @@ -2428,10 +2827,76 @@ class CFuncTankGun : public CFuncTank public: DECLARE_CLASS( CFuncTankGun, CFuncTank ); +#ifdef AMMOTYPE_MOVED + DECLARE_DATADESC(); + + string_t m_iszAmmoType; // The name of the ammodef that we use when we fire. Bullet damage still comes from keyvalues. + int m_iAmmoType; // The cached index of the ammodef that we use when we fire. +#endif // !AMMOTYPE_MOVED + +#ifdef AMMOTYPE_MOVED + void Spawn( void ); + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif // AMMOTYPE_MOVED + + void Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread ); }; + +#ifdef AMMOTYPE_MOVED +BEGIN_DATADESC(CFuncTankGun) + + DEFINE_KEYFIELD( m_iszAmmoType, FIELD_STRING, "ammotype" ), + DEFINE_FIELD( m_iAmmoType, FIELD_INTEGER ), + +END_DATADESC() +#endif // AMMOTYPE_MOVED + LINK_ENTITY_TO_CLASS( func_tank, CFuncTankGun ); +#ifdef AMMOTYPE_MOVED +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CFuncTankGun::Spawn( void ) +{ + if (m_iszAmmoType != NULL_STRING) + m_iAmmoType = GetAmmoDef()->Index(STRING(m_iszAmmoType)); + + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: Caches entity key values until spawn is called. +// Input : szKeyName - +// szValue - +// Output : +//----------------------------------------------------------------------------- +bool CFuncTankGun::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (FStrEq(szKeyName, "bullet")) + { + switch (atoi(szValue)) + { + case TANK_BULLET_SMALL: + m_iAmmoType = GetAmmoDef()->Index("Pistol"); + break; + case TANK_BULLET_MEDIUM: + m_iAmmoType = GetAmmoDef()->Index("SMG1"); + break; + case TANK_BULLET_LARGE: + m_iAmmoType = GetAmmoDef()->Index("AR2"); + break; + default: + m_iAmmoType = -1; + } + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} +#endif // AMMOTYPE_MOVED + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -2459,7 +2924,27 @@ void CFuncTankGun::Fire( int bulletCount, const Vector &barrelEnd, const Vector info.m_pAttacker = pAttacker; info.m_pAdditionalIgnoreEnt = GetParent(); -#ifdef HL2_EPISODIC +#ifdef MAPBASE + CUtlVector ignorelist; + + if (pAttacker) + { + if (m_bDontHitController) + { + ignorelist.AddToTail(pAttacker); + } + + // Ignore any vehicle our controller is in + if (pAttacker->MyCombatCharacterPointer() && pAttacker->MyCombatCharacterPointer()->IsInAVehicle()) + { + ignorelist.AddToTail(pAttacker->MyCombatCharacterPointer()->GetVehicleEntity()); + } + } + + info.m_pIgnoreEntList = &ignorelist; +#endif + +#if defined(HL2_EPISODIC) || defined(AMMOTYPE_MOVED) if ( m_iAmmoType != -1 ) { for ( i = 0; i < bulletCount; i++ ) @@ -2515,7 +3000,11 @@ class CFuncTankPulseLaser : public CFuncTankGun color32 m_flPulseColor; float m_flPulseLife; float m_flPulseLag; +#ifdef MAPBASE + #define m_sPulseFireSound m_iszShootSound +#else string_t m_sPulseFireSound; +#endif }; LINK_ENTITY_TO_CLASS( func_tankpulselaser, CFuncTankPulseLaser ); @@ -2695,6 +3184,82 @@ void CFuncTankLaser::Fire( int bulletCount, const Vector &barrelEnd, const Vecto } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Missile for func_tankrocket so kills are credited properly and don't kill friendlies +//----------------------------------------------------------------------------- +class CFuncTankMissile : public CMissile +{ + DECLARE_CLASS( CFuncTankMissile, CMissile ); + DECLARE_DATADESC(); + +public: + virtual void Spawn( void ); + + EHANDLE m_hTurret; + +private: + void FTnkMissileTouch( CBaseEntity *pOther ); +}; + +BEGIN_DATADESC( CFuncTankMissile ) + + DEFINE_FIELD( m_hTurret, FIELD_EHANDLE ), + + // Function Pointers + DEFINE_FUNCTION( FTnkMissileTouch ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( func_tankrocket_missile, CFuncTankMissile ); + +void CFuncTankMissile::Spawn( void ) +{ + Precache(); + + SetSolid( SOLID_BBOX ); + SetModel("models/weapons/w_missile_launch.mdl"); + UTIL_SetSize( this, -Vector(4,4,4), Vector(4,4,4) ); + + SetTouch( &CFuncTankMissile::FTnkMissileTouch ); + + SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); + SetThink( &CMissile::IgniteThink ); + + SetNextThink( gpGlobals->curtime + 0.3f ); + + m_takedamage = DAMAGE_YES; + m_iHealth = m_iMaxHealth = 100; + m_bloodColor = DONT_BLEED; + + AddFlag( FL_OBJECT ); +} + +//----------------------------------------------------------------------------- +// The actual explosion +//----------------------------------------------------------------------------- +void CFuncTankMissile::FTnkMissileTouch( CBaseEntity *pOther ) +{ + Assert( pOther ); + + // Don't touch triggers (but DO hit weapons) + if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER|FSOLID_VOLUME_CONTENTS) && pOther->GetCollisionGroup() != COLLISION_GROUP_WEAPON ) + { + // Some NPCs are triggers that can take damage (like antlion grubs). We should hit them. + if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) ) + return; + } + + // Do not touch the turret we fired from + if (pOther == m_hTurret.Get()) + { + return; + } + + Explode(); +} +#endif + class CFuncTankRocket : public CFuncTank { public: @@ -2720,13 +3285,23 @@ LINK_ENTITY_TO_CLASS( func_tankrocket, CFuncTankRocket ); void CFuncTankRocket::Precache( void ) { +#ifdef MAPBASE + UTIL_PrecacheOther( "func_tankrocket_missile" ); +#else UTIL_PrecacheOther( "rpg_missile" ); +#endif CFuncTank::Precache(); } void CFuncTankRocket::Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread ) { +#ifdef MAPBASE + CFuncTankMissile *pRocket = (CFuncTankMissile*)CBaseEntity::Create( "func_tankrocket_missile", barrelEnd, GetAbsAngles(), GetController() ); + pRocket->AddEffects( EF_NOSHADOW ); + pRocket->m_hTurret.Set(this); +#else CMissile *pRocket = (CMissile *) CBaseEntity::Create( "rpg_missile", barrelEnd, GetAbsAngles(), this ); +#endif pRocket->DumbFire(); pRocket->SetNextThink( gpGlobals->curtime + 0.1f ); @@ -2743,6 +3318,9 @@ void CFuncTankRocket::Fire( int bulletCount, const Vector &barrelEnd, const Vect CFuncTank::Fire( bulletCount, barrelEnd, forward, this, bIgnoreSpread ); } +#ifdef MAPBASE +static const char *s_pAirboatGunThinkContext = "AirboatGunThinkContext"; +#endif //----------------------------------------------------------------------------- // Airboat gun @@ -2753,15 +3331,32 @@ class CFuncTankAirboatGun : public CFuncTank DECLARE_CLASS( CFuncTankAirboatGun, CFuncTank ); DECLARE_DATADESC(); +#ifdef MAPBASE + CFuncTankAirboatGun() + { + // -1 = original behavior + m_spread = -1; + } +#endif + void Precache( void ); virtual void Spawn(); virtual void Activate(); virtual void Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread ); virtual void ControllerPostFrame(); +#ifdef MAPBASE + virtual void FuncTankAirboatGunThink(); + virtual void TankActivate(void); + virtual void TankDeactivate(void); + virtual void OnStartControlled(); +#endif virtual void OnStopControlled(); virtual const char *GetTracerType( void ); virtual Vector WorldBarrelPosition( void ); virtual void DoImpactEffect( trace_t &tr, int nDamageType ); +#ifdef MAPBASE + virtual void StopLoopingSounds() { DestroySounds(); BaseClass::StopLoopingSounds(); } +#endif private: void CreateSounds(); @@ -2778,6 +3373,12 @@ class CFuncTankAirboatGun : public CFuncTank CHandle m_hAirboatGunModel; int m_nGunBarrelAttachment; float m_flLastImpactEffectTime; + +#ifdef MAPBASE + float m_flHeavyShotInterval = 0.2f; + int m_iHeavyShotSpread; + bool m_bUseDamageKV; +#endif }; @@ -2793,6 +3394,15 @@ BEGIN_DATADESC( CFuncTankAirboatGun ) // DEFINE_FIELD( m_hAirboatGunModel, FIELD_EHANDLE ), // DEFINE_FIELD( m_nGunBarrelAttachment, FIELD_INTEGER ), DEFINE_FIELD( m_flLastImpactEffectTime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flHeavyShotInterval, FIELD_FLOAT, "heavy_shot_interval" ), + DEFINE_KEYFIELD( m_iHeavyShotSpread, FIELD_INTEGER, "heavy_shot_spread" ), + DEFINE_KEYFIELD( m_bUseDamageKV, FIELD_BOOLEAN, "use_damage_kv" ), +#endif + +#ifdef MAPBASE + DEFINE_THINKFUNC( FuncTankAirboatGunThink ), +#endif END_DATADESC() @@ -2805,7 +3415,16 @@ LINK_ENTITY_TO_CLASS( func_tankairboatgun, CFuncTankAirboatGun ); void CFuncTankAirboatGun::Precache( void ) { BaseClass::Precache(); +#ifdef MAPBASE + // Odd placement, but it works + if (m_iszShootSound == NULL_STRING) + { + m_iszShootSound = AllocPooledString("Airboat.FireGunLoop"); + PrecacheScriptSound(STRING(m_iszShootSound)); + } +#else PrecacheScriptSound( "Airboat.FireGunLoop" ); +#endif PrecacheScriptSound( "Airboat.FireGunRevDown"); CreateSounds(); } @@ -2820,6 +3439,10 @@ void CFuncTankAirboatGun::Spawn( void ) m_flNextHeavyShotTime = 0.0f; m_bIsFiring = false; m_flLastImpactEffectTime = -1; + +#ifdef MAPBASE + SetContextThink( &CFuncTankAirboatGun::FuncTankAirboatGunThink, gpGlobals->curtime, s_pAirboatGunThinkContext ); +#endif } @@ -2838,6 +3461,13 @@ void CFuncTankAirboatGun::Activate() m_nGunBarrelAttachment = m_hAirboatGunModel->LookupAttachment( "muzzle" ); } } +#ifdef MAPBASE + else if (GetParent() && GetParent()->GetBaseAnimating()) + { + m_hAirboatGunModel = GetParent()->GetBaseAnimating(); + m_nGunBarrelAttachment = GetGunBarrelAttachment(); + } +#endif } @@ -2851,7 +3481,11 @@ void CFuncTankAirboatGun::CreateSounds() CPASAttenuationFilter filter( this ); if (!m_pGunFiringSound) { +#ifdef MAPBASE + m_pGunFiringSound = controller.SoundCreate( filter, entindex(), STRING(m_iszShootSound) ); +#else m_pGunFiringSound = controller.SoundCreate( filter, entindex(), "Airboat.FireGunLoop" ); +#endif controller.Play( m_pGunFiringSound, 0, 100 ); } } @@ -2914,11 +3548,73 @@ void CFuncTankAirboatGun::ControllerPostFrame( void ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Maintains airboat gun sounds on NPCs +//----------------------------------------------------------------------------- +void CFuncTankAirboatGun::FuncTankAirboatGunThink( void ) +{ + if (!GetController()) + { + if (m_fireLast != 0) + { + StartFiring(); + } + else + { + StopFiring(); + } + } + else if (GetController()->IsNPC()) + { + // Attempt to estimate when we wouldn't be firing + if ((gpGlobals->curtime - m_fireLast - (1.0 / m_fireRate)) < 0.1f) + { + StartFiring(); + } + else + { + StopFiring(); + } + } + + SetNextThink( gpGlobals->curtime + 0.05f, s_pAirboatGunThinkContext ); +} + + +void CFuncTankAirboatGun::TankActivate(void) +{ + SetNextThink( gpGlobals->curtime + 0.05f, s_pAirboatGunThinkContext ); + BaseClass::TankActivate(); +} + +void CFuncTankAirboatGun::TankDeactivate(void) +{ + DevMsg("Tank deactivate\n"); + SetNextThink( TICK_NEVER_THINK, s_pAirboatGunThinkContext ); + StopFiring(); + BaseClass::TankDeactivate(); +} + +void CFuncTankAirboatGun::OnStartControlled() +{ + if (GetController() && GetController()->IsNPC()) + SetNextThink( gpGlobals->curtime + 0.05f, s_pAirboatGunThinkContext ); + + BaseClass::OnStartControlled(); +} +#endif + + //----------------------------------------------------------------------------- // Stop controlled //----------------------------------------------------------------------------- void CFuncTankAirboatGun::OnStopControlled() { +#ifdef MAPBASE + DevMsg("Tank stop control\n"); + SetNextThink( TICK_NEVER_THINK, s_pAirboatGunThinkContext ); +#endif StopFiring(); BaseClass::OnStopControlled(); } @@ -2999,16 +3695,35 @@ void CFuncTankAirboatGun::Fire( int bulletCount, const Vector &barrelEnd, const info.m_flDistance = 4096; info.m_iAmmoType = ammoType; +#ifdef MAPBASE + info.m_pAttacker = pAttacker; + info.m_pAdditionalIgnoreEnt = GetParent(); + + if (m_bUseDamageKV) + { + info.m_flDamage = m_iBulletDamage; + info.m_iPlayerDamage = m_iBulletDamageVsPlayer; + } +#endif + if ( gpGlobals->curtime >= m_flNextHeavyShotTime ) { info.m_iShots = 1; +#ifdef MAPBASE + info.m_vecSpread = gTankSpread[m_iHeavyShotSpread]; +#else info.m_vecSpread = VECTOR_CONE_PRECALCULATED; +#endif info.m_flDamageForceScale = 1000.0f; } else { info.m_iShots = 2; +#ifdef MAPBASE + info.m_vecSpread = m_spread != -1 ? gTankSpread[m_spread] : VECTOR_CONE_5DEGREES; +#else info.m_vecSpread = VECTOR_CONE_5DEGREES; +#endif } FireBullets( info ); @@ -3016,10 +3731,39 @@ void CFuncTankAirboatGun::Fire( int bulletCount, const Vector &barrelEnd, const DoMuzzleFlash(); // NOTE: This must occur after FireBullets +#ifdef MAPBASE + if ( gpGlobals->curtime >= m_flNextHeavyShotTime && m_flHeavyShotInterval != -1 ) +#else if ( gpGlobals->curtime >= m_flNextHeavyShotTime ) +#endif { +#ifdef MAPBASE + m_flNextHeavyShotTime = gpGlobals->curtime + m_flHeavyShotInterval; +#else m_flNextHeavyShotTime = gpGlobals->curtime + AIRBOAT_GUN_HEAVY_SHOT_INTERVAL; +#endif + } + +#ifdef MAPBASE + // Things from CFuncTank::Fire(). + // We can't use everything because it overrides a few things. + if( pAttacker && pAttacker->IsPlayer() ) + { + if ( IsX360() ) + { + // Now, if you're playing Mapbase on the Xbox 360, the airboat gun turret will make your controller rumble! + // Isn't that lovely? Hmm? + UTIL_PlayerByIndex(1)->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART | RUMBLE_FLAG_RANDOM_AMPLITUDE ); + } + else + { + CSoundEnt::InsertSound( SOUND_MOVE_AWAY, barrelEnd + forward * 32.0f, 32.0f, 0.2f, pAttacker, SOUNDENT_CHANNEL_WEAPON ); + } } + + m_OnFire.FireOutput(pAttacker, this); + m_bReadyToFire = false; +#endif } @@ -3216,7 +3960,11 @@ class CMortarShell : public CBaseEntity public: DECLARE_CLASS( CMortarShell, CBaseEntity ); +#ifdef MAPBASE + static CMortarShell *Create( const Vector &vecStart, const trace_t &tr, const Vector &vecShotDir, float flImpactDelay, float flWarnDelay, string_t warnSound ); +#else static CMortarShell *Create( const Vector &vecStart, const Vector &vecTarget, const Vector &vecShotDir, float flImpactDelay, float flWarnDelay, string_t warnSound ); +#endif void Spawn( void ); void Precache( void ); @@ -3226,6 +3974,15 @@ class CMortarShell : public CBaseEntity void FadeThink( void ); int UpdateTransmitState( void ); +#ifdef MAPBASE + void SetRadius(float fl) { m_flRadius = fl; } + void SetMagnitude(int i) { m_Magnitude = i; } + +public: + + bool m_bDontHitController; +#endif + private: void FixUpImpactPoint( const Vector &initialPos, const Vector &initialNormal, Vector *endPos, Vector *endNormal ); @@ -3240,6 +3997,9 @@ class CMortarShell : public CBaseEntity Vector m_vecFiredFrom; Vector m_vecFlyDir; float m_flSpawnedTime; +#ifdef MAPBASE + int m_Magnitude; +#endif CHandle m_pBeamEffect[4]; @@ -3268,6 +4028,10 @@ BEGIN_DATADESC( CMortarShell ) DEFINE_AUTO_ARRAY( m_pBeamEffect, FIELD_EHANDLE), DEFINE_FIELD( m_flRadius, FIELD_FLOAT ), DEFINE_FIELD( m_vecSurfaceNormal, FIELD_VECTOR ), +#ifdef MAPBASE + DEFINE_FIELD( m_bDontHitController, FIELD_BOOLEAN ), + DEFINE_FIELD( m_Magnitude, FIELD_INTEGER ), +#endif DEFINE_FUNCTION( FlyThink ), DEFINE_FUNCTION( FadeThink ), @@ -3327,13 +4091,19 @@ void CMortarShell::FixUpImpactPoint( const Vector &initialPos, const Vector &ini #define MORTAR_BLAST_DAMAGE 50 #define MORTAR_BLAST_HEIGHT 7500 +#ifdef MAPBASE +CMortarShell *CMortarShell::Create( const Vector &vecStart, const trace_t &tr, const Vector &vecShotDir, float flImpactDelay, float flWarnDelay, string_t warnSound ) +#else CMortarShell *CMortarShell::Create( const Vector &vecStart, const Vector &vecTarget, const Vector &vecShotDir, float flImpactDelay, float flWarnDelay, string_t warnSound ) +#endif { CMortarShell *pShell = (CMortarShell *)CreateEntityByName("mortarshell" ); +#ifndef MAPBASE // Place the mortar shell at the target location so that it can make the sound and explode. trace_t tr; UTIL_TraceLine( vecTarget, vecTarget + ( vecShotDir * 128.0f ), MASK_SOLID_BRUSHONLY, pShell, COLLISION_GROUP_NONE, &tr ); +#endif Vector targetPos, targetNormal; pShell->FixUpImpactPoint( tr.endpos, tr.plane.normal, &targetPos, &targetNormal ); @@ -3619,7 +4389,11 @@ void CMortarShell::Impact( void ) // Fire the bullets Vector vecSrc, vecShootDir; +#ifdef MAPBASE + float flRadius = m_flRadius; +#else float flRadius = MORTAR_BLAST_RADIUS; +#endif trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 128 ), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); @@ -3680,7 +4454,11 @@ void CMortarShell::Impact( void ) FBEAM_FADEOUT ); +#ifdef MAPBASE + RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), m_Magnitude / 2, (DMG_BLAST|DMG_DISSOLVE) ), GetAbsOrigin(), flRadius, CLASS_NONE, m_bDontHitController ? GetOwnerEntity() : NULL ); +#else RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), MORTAR_BLAST_DAMAGE, (DMG_BLAST|DMG_DISSOLVE) ), GetAbsOrigin(), MORTAR_BLAST_RADIUS, CLASS_NONE, NULL ); +#endif EmitSound( "Weapon_Mortar.Impact" ); @@ -3772,7 +4550,11 @@ class CFuncTankMortar : public CFuncTank int m_Magnitude; float m_fireDelay; +#ifdef MAPBASE + #define m_fireStartSound m_iszShootSound +#else string_t m_fireStartSound; +#endif //string_t m_fireEndSound; string_t m_incomingSound; @@ -3781,6 +4563,11 @@ class CFuncTankMortar : public CFuncTank bool m_fLastShotMissed; +#ifdef MAPBASE + float m_flRadius; + int m_iMortarTraceMask = MASK_SOLID_BRUSHONLY; +#endif + // store future firing event CBaseEntity *m_pAttacker; }; @@ -3799,6 +4586,11 @@ BEGIN_DATADESC( CFuncTankMortar ) DEFINE_FIELD( m_fLastShotMissed, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "radius" ), + DEFINE_KEYFIELD( m_iMortarTraceMask, FIELD_INTEGER, "trace_mask" ), +#endif + DEFINE_FIELD( m_pAttacker, FIELD_CLASSPTR ), // Inputs @@ -3933,13 +4725,21 @@ void CFuncTankMortar::Fire( int bulletCount, const Vector &barrelEnd, const Vect vecSpot.z = GetAbsOrigin().z; // Trace up to find the fake 'apex' of the shell. The skybox or 1024 units, whichever comes first. +#ifdef MAPBASE + UTIL_TraceLine( vecSpot, vecSpot + Vector(0, 0, 1024), m_iMortarTraceMask, NULL, COLLISION_GROUP_NONE, &tr ); +#else UTIL_TraceLine( vecSpot, vecSpot + Vector(0, 0, 1024), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); +#endif vecSpot = tr.endpos; //NDebugOverlay::Line( tr.startpos, tr.endpos, 0,255,0, false, 5 ); // Now trace from apex to target +#ifdef MAPBASE + UTIL_TraceLine( vecSpot, vecProjectedPosition, m_iMortarTraceMask, NULL, COLLISION_GROUP_NONE, &tr ); +#else UTIL_TraceLine( vecSpot, vecProjectedPosition, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); +#endif if( mortar_visualize.GetBool() ) { @@ -3962,7 +4762,16 @@ void CFuncTankMortar::Fire( int bulletCount, const Vector &barrelEnd, const Vect Vector vecFinalDir = tr.endpos - tr.startpos; VectorNormalize( vecFinalDir ); +#ifdef MAPBASE + CMortarShell *pShell = CMortarShell::Create( barrelEnd, tr, vecFinalDir, m_fireDelay, m_flWarningTime, m_incomingSound ); + pShell->SetOwnerEntity(GetController()); + pShell->m_bDontHitController = m_bDontHitController; + if (m_flRadius != 0) + pShell->SetRadius(m_flRadius); + pShell->SetMagnitude(m_Magnitude); +#else CMortarShell::Create( barrelEnd, tr.endpos, vecFinalDir, m_fireDelay, m_flWarningTime, m_incomingSound ); +#endif BaseClass::Fire( bulletCount, barrelEnd, vecForward, this, bIgnoreSpread ); } @@ -4063,6 +4872,9 @@ class CFuncTankCombineCannon : public CFuncTankGun Vector m_vecTrueForward; bool m_bShouldHarrass; bool m_bLastTargetWasNPC; // Tells whether the last entity we fired a shot at was an NPC (otherwise it was the player) +#ifdef MAPBASE + bool m_bControllableVersion = false; // Allows new behavior that makes player/NPC control easier. Doesn't use spawnflag for legacy purposes, as if anyone used this as a regular tank before. +#endif }; BEGIN_DATADESC( CFuncTankCombineCannon ) @@ -4074,6 +4886,9 @@ BEGIN_DATADESC( CFuncTankCombineCannon ) DEFINE_FIELD( m_vecTrueForward, FIELD_VECTOR ), DEFINE_FIELD( m_bShouldHarrass, FIELD_BOOLEAN ), DEFINE_FIELD( m_bLastTargetWasNPC, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bControllableVersion, FIELD_BOOLEAN, "ControllableVersion" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "EnableHarrass", InputEnableHarrass ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableHarrass", InputDisableHarrass ), @@ -4100,7 +4915,12 @@ void CFuncTankCombineCannon::Spawn() { BaseClass::Spawn(); m_flTimeBeamOn = gpGlobals->curtime; +#ifdef MAPBASE + if (!m_bControllableVersion) + CreateBeam(); +#else CreateBeam(); +#endif m_bShouldHarrass = true; @@ -4154,8 +4974,14 @@ void CFuncTankCombineCannon::DestroyBeam() //--------------------------------------------------------- void CFuncTankCombineCannon::AdjustRateOfFire() { +#ifdef MAPBASE + // Only maintain 1.5 rounds per second if we're using legacy behavior. + if (!m_bControllableVersion) + m_fireRate = 1.5; +#else // Maintain 1.5 rounds per second rate of fire. m_fireRate = 1.5; +#endif /* if( m_hTarget.Get() != NULL && m_hTarget->IsPlayer() ) { @@ -4208,6 +5034,12 @@ void CFuncTankCombineCannon::FuncTankPostThink() { AdjustRateOfFire(); +#ifdef MAPBASE + // Controllables don't sweep + if (m_bControllableVersion) + return; +#endif + if( m_hTarget.Get() == NULL ) { if( gpGlobals->curtime > m_flTimeNextSweep ) @@ -4263,7 +5095,11 @@ void CFuncTankCombineCannon::FuncTankPostThink() // Ignore the func_tank and any prop it's parented to, and check line of sight to the point // Trace to the point. If an opaque trace doesn't reach the point, that means the beam hit // something closer, (including a blockLOS), so try again. +#ifdef MAPBASE + CTraceFilterSimple traceFilter = GetTraceFilter(); +#else CTraceFilterSkipTwoEntities traceFilter( this, GetParent(), COLLISION_GROUP_NONE ); +#endif AI_TraceLine( vecBarrelEnd, vecTest, MASK_BLOCKLOS_AND_NPCS, &traceFilter, &trLOS ); AI_TraceLine( vecBarrelEnd, vecTest, MASK_SHOT, &traceFilter, &trShoot ); @@ -4320,13 +5156,23 @@ void CFuncTankCombineCannon::FuncTankPostThink() //--------------------------------------------------------- void CFuncTankCombineCannon::Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread ) { +#ifdef MAPBASE + // If we're in aim-at-pos mode and not in the new controllable version, don't fire in this mode + if ( HasSpawnFlags(SF_TANK_AIM_AT_POS) && !m_bControllableVersion ) + return; +#else // Specifically do NOT fire in aim at pos mode. This is just for show. if( HasSpawnFlags(SF_TANK_AIM_AT_POS) ) return; +#endif Vector vecAdjustedForward = forward; +#ifdef MAPBASE + if ( !IsPlayerManned() && m_hTarget != NULL ) +#else if( m_hTarget != NULL ) +#endif { Vector vecToTarget = m_hTarget->BodyTarget( barrelEnd, false ) - barrelEnd; VectorNormalize( vecToTarget ); @@ -4429,3 +5275,93 @@ void CFuncTankCombineCannon::InputDisableHarrass( inputdata_t &inputdata ) LINK_ENTITY_TO_CLASS( func_tank_combine_cannon, CFuncTankCombineCannon ); + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Func tank that fires a bunch of outputs instead +//----------------------------------------------------------------------------- +class CFuncTankLogic : public CFuncTank +{ +public: + DECLARE_CLASS(CFuncTankLogic, CFuncTank); + DECLARE_DATADESC(); + + CFuncTankLogic(); + + void Fire(int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread); + +protected: + + bool m_bShootsThroughWater; + + COutputVector m_OnFire_BarrelPos; + COutputVector m_OnFire_BarrelAng; + COutputVector m_OnFire_ShootPos; + COutputEHANDLE m_OnFire_FirstEnt; +}; + +LINK_ENTITY_TO_CLASS(func_tanklogic, CFuncTankLogic); + +BEGIN_DATADESC(CFuncTankLogic) + + //DEFINE_KEYFIELD( m_bDontHitController, FIELD_BOOLEAN, "DontHitController" ), + + DEFINE_OUTPUT( m_OnFire_BarrelPos, "OnFire_BarrelPos" ), + DEFINE_OUTPUT( m_OnFire_BarrelAng, "OnFire_BarrelAng" ), + DEFINE_OUTPUT( m_OnFire_ShootPos, "OnFire_ShootPos" ), + DEFINE_OUTPUT( m_OnFire_FirstEnt, "OnFire_FirstEnt" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CFuncTankLogic::CFuncTankLogic() +{ + // This is overriden by KV later + m_bDontHitController = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CFuncTankLogic::Fire(int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread) +{ + // A bunch of stuff from FireBullets() to replicate firing a regular func_tank. + // It mostly just has the trace stuff. + Vector vecDir; + Vector vecEnd; + + trace_t tr; + CTraceFilterSimple traceFilter = GetTraceFilter(); + + CShotManipulator Manipulator( forward ); + vecDir = Manipulator.ApplySpread( bIgnoreSpread ? gTankSpread[0] : gTankSpread[m_spread] ); + + vecEnd = barrelEnd + vecDir * MAX_TRACE_LENGTH; + + int mask = MASK_SHOT; + + if (!m_bShootsThroughWater) + mask |= CONTENTS_WATER; + + AI_TraceLine(barrelEnd, vecEnd, mask, &traceFilter, &tr); + + if ( tr.startsolid ) + { + tr.endpos = tr.startpos; + tr.fraction = 0.0f; + } + + if ( ai_debug_shoot_positions.GetBool() ) + NDebugOverlay::Line(barrelEnd, tr.endpos, 255, 255, 255, false, .1 ); + + BaseClass::Fire(bulletCount, barrelEnd, forward, pAttacker, bIgnoreSpread); + + m_OnFire_BarrelPos.Set(barrelEnd, pAttacker, this); + m_OnFire_BarrelAng.Set(forward, pAttacker, this); + m_OnFire_ShootPos.Set(tr.endpos, pAttacker, this); + m_OnFire_FirstEnt.Set(tr.m_pEnt, tr.m_pEnt, this); +} +#endif // MAPBASE + diff --git a/game/server/hl2/func_tank.h b/game/server/hl2/func_tank.h index 46b444d5..0ecacce5 100644 --- a/game/server/hl2/func_tank.h +++ b/game/server/hl2/func_tank.h @@ -55,6 +55,20 @@ enum TANKBULLET #define MORTAR_BLAST_RADIUS 350 +#ifdef MAPBASE +// This moves variables related to ammo types from CFuncTank to CFuncTankGun, as CFuncTankGun and its derivatives are the only classes that use it. +// It also completely replaces the legacy "bullet" keyvalue with the AmmoType keyvalue, making bullet translate to the ammo type variable directly. +// This fixes the issue where some func_tanks don't fire any bullets. +// +// This code was created in September-October 2018 and moving existing variables like this seems risky and somewhat pointless, but the nature of func_tanks +// make this unlikely to cause any problems and helps my OCD. +// +// Disable this preprocessor if it causes problems. +#define AMMOTYPE_MOVED 1 + +class CTraceFilterSimple; +#endif + // Custom damage // env_laser (duration is 0.5 rate of fire) @@ -134,6 +148,13 @@ class CFuncTank : public CBaseEntity virtual void DoMuzzleFlash( void ); virtual const char *GetTracerType( void ); +#ifdef MAPBASE + virtual CTraceFilterSimple GetTraceFilter(); + + // Needed because func_tankairboatgun needs the barrel + int GetGunBarrelAttachment() { return m_nBarrelAttachment; } +#endif + protected: virtual float GetShotSpeed() { return 0; } @@ -179,6 +200,10 @@ class CFuncTank : public CBaseEntity private: void InputFindNPCToManTank( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputTeleportNPCToManTank( inputdata_t &inputdata ); + void InputForceNPCToManTank( inputdata_t &inputdata ); +#endif void InputStopFindingNPCs( inputdata_t &inputdata ); void InputStartFindingNPCs( inputdata_t &inputdata ); void InputForceNPCOff( inputdata_t &inputdata ); @@ -217,7 +242,11 @@ class CFuncTank : public CBaseEntity bool RotateTankToAngles( const QAngle &angles, float *pDistX = NULL, float *pDistY = NULL ); // We lost our target! +#ifdef MAPBASE + void LostTarget( CBaseEntity *pTarget ); +#else void LostTarget( void ); +#endif // Purpose: void ComputeLeadingPosition( const Vector &vecShootPosition, CBaseEntity *pTarget, Vector *pLeadPosition ); @@ -237,6 +266,7 @@ class CFuncTank : public CBaseEntity int m_iBulletDamage; // 0 means use Bullet type's default damage int m_iBulletDamageVsPlayer; // Damage vs player. 0 means use m_iBulletDamage +#ifndef AMMOTYPE_MOVED #ifdef HL2_EPISODIC string_t m_iszAmmoType; // The name of the ammodef that we use when we fire. Bullet damage still comes from keyvalues. int m_iAmmoType; // The cached index of the ammodef that we use when we fire. @@ -244,7 +274,9 @@ class CFuncTank : public CBaseEntity int m_iSmallAmmoType; int m_iMediumAmmoType; int m_iLargeAmmoType; -#endif // HL2_EPISODIC +#endif // HL2_EPISODIC +#endif // !AMMOTYPE_MOVED + int m_spread; // firing spread @@ -255,6 +287,15 @@ class CFuncTank : public CBaseEntity int m_nBulletCount; +#ifdef MAPBASE + bool m_bDontHitController; + string_t m_iszTraceFilter; + CHandle m_hTraceFilter; + + // Created to nullify aiming problems when the func_tank is on a vehicle or the player is too close to the barrel + float m_flPlayerBBoxDist; +#endif + private: // This is either the player manning the func_tank, or an NPC. The NPC is either manning the tank, or running @@ -293,6 +334,19 @@ class CFuncTank : public CBaseEntity string_t m_iszSpriteSmoke; string_t m_iszSpriteFlash; +#ifdef MAPBASE +public: + // This is kind of tricky to implement. + // Some derived classes already have their own shoot sound variables, making this one redundant, etc. + // To rectify this, m_iszShootSound replaces all of them and takes their keyfield names. + // It's like the TF spy of func_tank. + string_t m_iszShootSound; + + // NPC controllers cannot leave. >:) + bool m_bControllerGlued; +private: +#endif + string_t m_iszMaster; // Master entity (game_team_master or multisource) string_t m_soundStartRotate; @@ -327,9 +381,16 @@ class CFuncTank : public CBaseEntity float m_flNextLeadFactor; float m_flNextLeadFactorTime; +#ifdef MAPBASE +public: + COutputEvent m_OnFire; + COutputEHANDLE m_OnLoseTarget; + COutputEHANDLE m_OnAquireTarget; +#else COutputEvent m_OnFire; COutputEvent m_OnLoseTarget; COutputEvent m_OnAquireTarget; +#endif COutputEvent m_OnAmmoDepleted; COutputEvent m_OnGotController; COutputEvent m_OnLostController; diff --git a/game/server/hl2/grenade_ar2.cpp b/game/server/hl2/grenade_ar2.cpp index 70841c66..455efb18 100644 --- a/game/server/hl2/grenade_ar2.cpp +++ b/game/server/hl2/grenade_ar2.cpp @@ -34,6 +34,9 @@ extern ConVar sk_npc_dmg_smg1_grenade; extern ConVar sk_max_smg1_grenade; ConVar sk_smg1_grenade_radius ( "sk_smg1_grenade_radius","0"); +#ifdef MAPBASE +ConVar smg1_grenade_credit_transfer("smg1_grenade_credit_transfer", "1"); +#endif ConVar g_CV_SmokeTrail("smoke_trail", "1", 0); // temporary dust explosion switch @@ -161,6 +164,14 @@ void CGrenadeAR2::GrenadeAR2Think( void ) void CGrenadeAR2::Event_Killed( const CTakeDamageInfo &info ) { +#ifdef MAPBASE + if (smg1_grenade_credit_transfer.GetBool() && info.GetAttacker()->MyCombatCharacterPointer()) + { + CBaseCombatCharacter *pBCC = info.GetAttacker()->MyCombatCharacterPointer(); + SetThrower(pBCC); + SetOwnerEntity(pBCC); + } +#endif Detonate( ); } diff --git a/game/server/hl2/grenade_bugbait.cpp b/game/server/hl2/grenade_bugbait.cpp index 12e3dda1..7d5d7a47 100644 --- a/game/server/hl2/grenade_bugbait.cpp +++ b/game/server/hl2/grenade_bugbait.cpp @@ -200,6 +200,11 @@ void CGrenadeBugBait::BugBaitTouch( CBaseEntity *pOther ) // Tell all spawners to now fight to this position g_AntlionMakerManager.BroadcastFightGoal( GetAbsOrigin() ); +#ifdef MAPBASE + m_OnDetonate.FireOutput(GetThrower(), this); + m_OnDetonate_OutPosition.Set(GetAbsOrigin(), GetThrower(), this); +#endif + //Go away UTIL_Remove( this ); } diff --git a/game/server/hl2/grenade_frag.cpp b/game/server/hl2/grenade_frag.cpp index 1788d191..b0ad60fb 100644 --- a/game/server/hl2/grenade_frag.cpp +++ b/game/server/hl2/grenade_frag.cpp @@ -11,6 +11,9 @@ #include "Sprite.h" #include "SpriteTrail.h" #include "soundent.h" +#ifdef MAPBASE +#include "mapbase/ai_grenade.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -126,8 +129,31 @@ void CGrenadeFrag::Spawn( void ) SetCollisionGroup( COLLISION_GROUP_WEAPON ); CreateVPhysics(); +#ifdef MAPBASE + if (GetThrower() && GetThrower()->IsNPC()) + { + // One of OnThrowGrenade's useful applications is replacing it with another entity using point_entity_replace. + // However, the grenade is always able to let out a blip before being replaced, which can be confusing/undesirable. + // This code checks to see if OnThrowGrenade is being used for anything, in which case the first blip will be very slightly delayed. + // This doesn't interfere with when the grenade actually detonates and shouldn't be noticable if the grenade is kept by OnThrowGrenade anyway. + CAI_GrenadeUserSink *pGrenadeUser = dynamic_cast(GetThrower()); + if (pGrenadeUser && pGrenadeUser->UsingOnThrowGrenade()) + { + // We delay the blip by 0.05, so replacement must occur within that period in order to skip the blip. + m_flNextBlipTime = gpGlobals->curtime + 0.05f; + } + } + + // Do the blip if m_flNextBlipTime wasn't changed + if (m_flNextBlipTime <= gpGlobals->curtime) + { + BlipSound(); + m_flNextBlipTime = gpGlobals->curtime + FRAG_GRENADE_BLIP_FREQUENCY; + } +#else BlipSound(); m_flNextBlipTime = gpGlobals->curtime + FRAG_GRENADE_BLIP_FREQUENCY; +#endif AddSolidFlags( FSOLID_NOT_STANDABLE ); diff --git a/game/server/hl2/grenade_spit.cpp b/game/server/hl2/grenade_spit.cpp index 4b713e6d..5f3e8ef9 100644 --- a/game/server/hl2/grenade_spit.cpp +++ b/game/server/hl2/grenade_spit.cpp @@ -131,7 +131,19 @@ void CGrenadeSpit::GrenadeSpitTouch( CBaseEntity *pOther ) if ( pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER) ) { // Some NPCs are triggers that can take damage (like antlion grubs). We should hit them. +#ifdef MAPBASE + // But some physics objects that are also triggers (like weapons) shouldn't go through this check. + // + // Note: rpg_missile has the same code, except it properly accounts for weapons in a different way. + // This was discovered after I implemented this and both work fine, but if this ever causes problems, + // use rpg_missile's implementation: + // + // if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER|FSOLID_VOLUME_CONTENTS) && pOther->GetCollisionGroup() != COLLISION_GROUP_WEAPON ) + // + if ( pOther->GetMoveType() == MOVETYPE_NONE && (( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY )) ) +#else if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) ) +#endif return; } diff --git a/game/server/hl2/hl2_client.cpp b/game/server/hl2/hl2_client.cpp index 6125de82..12dc248f 100644 --- a/game/server/hl2/hl2_client.cpp +++ b/game/server/hl2/hl2_client.cpp @@ -137,6 +137,21 @@ void respawn( CBaseEntity *pEdict, bool fCopyCorpse ) // respawn player pEdict->Spawn(); } +#ifdef MAPBASE + else if (g_pGameRules->AllowSPRespawn()) + { + // In SP respawns, only create corpse if drawing externally + CBasePlayer *pPlayer = (CBasePlayer*)pEdict; + if ( fCopyCorpse && pPlayer->GetDrawPlayerModelExternally() ) + { + // make a copy of the dead body for appearances sake + pPlayer->CreateCorpse(); + } + + // respawn player + pPlayer->Spawn(); + } +#endif else { // restart the entire server engine->ServerCommand("reload\n"); diff --git a/game/server/hl2/hl2_player.cpp b/game/server/hl2/hl2_player.cpp index e7583f5a..1cd610bb 100644 --- a/game/server/hl2/hl2_player.cpp +++ b/game/server/hl2/hl2_player.cpp @@ -55,12 +55,21 @@ #include "portal_player.h" #endif // PORTAL +#ifdef MAPBASE +#include "triggers.h" +#include "mapbase/variant_tools.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" extern ConVar weapon_showproficiency; extern ConVar autoaim_max_dist; +#ifdef MAPBASE +extern ConVar player_squad_autosummon_enabled; +#endif + // Do not touch with without seeing me, please! (sjb) // For consistency's sake, enemy gunfire is traced against a scaled down // version of the player's hull, not the hitboxes for the player's model @@ -107,6 +116,15 @@ ConVar autoaim_unlock_target( "autoaim_unlock_target", "0.8666" ); ConVar sv_stickysprint("sv_stickysprint", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX); +#ifdef MAPBASE +ConVar player_autoswitch_enabled( "player_autoswitch_enabled", "1", FCVAR_NONE, "This convar was added by Mapbase to toggle whether players automatically switch to their ''best'' weapon upon picking up ammo for it after it was dry." ); + +#ifdef SP_ANIM_STATE +ConVar hl2_use_sp_animstate( "hl2_use_sp_animstate", "1", FCVAR_NONE, "Allows SP HL2 players to use HL2:DM animations for custom player models. (changes may not apply until model is reloaded)" ); +#endif + +#endif + #define FLASH_DRAIN_TIME 1.1111 // 100 units / 90 secs #define FLASH_CHARGE_TIME 50.0f // 100 units / 2 secs @@ -157,12 +175,26 @@ static impactdamagetable_t gCappedPlayerImpactDamageTable = // Flashlight utility bool g_bCacheLegacyFlashlightStatus = true; +#ifdef MAPBASE +extern ThreeState_t Flashlight_GetLegacyVersionKey(); +#endif bool g_bUseLegacyFlashlight; bool Flashlight_UseLegacyVersion( void ) { // If this is the first run through, cache off what the answer should be (cannot change during a session) if ( g_bCacheLegacyFlashlightStatus ) { +#ifdef MAPBASE + // Check if there's a gameinfo setting. + ThreeState_t iGameKey = Flashlight_GetLegacyVersionKey(); + if (iGameKey != TRS_NONE) + { + g_bUseLegacyFlashlight = (iGameKey == TRS_TRUE); + g_bCacheLegacyFlashlightStatus = false; + return g_bUseLegacyFlashlight; + } +#endif + char modDir[MAX_PATH]; if ( UTIL_GetModDir( modDir, sizeof(modDir) ) == false ) return false; @@ -200,6 +232,17 @@ class CLogicPlayerProxy : public CLogicalEntity COutputInt m_RequestedPlayerHealth; +#ifdef MAPBASE + COutputInt m_OnGetAmmo; + COutputEvent m_PlayerDamaged; + COutputEvent m_OnSquadMemberKilled; + COutputInt m_RequestedPlayerArmor; + COutputFloat m_RequestedPlayerAuxPower; + COutputFloat m_RequestedPlayerFlashBattery; + + COutputEvent m_OnPlayerSpawn; +#endif + void InputRequestPlayerHealth( inputdata_t &inputdata ); void InputSetFlashlightSlowDrain( inputdata_t &inputdata ); void InputSetFlashlightNormalDrain( inputdata_t &inputdata ); @@ -212,14 +255,169 @@ class CLogicPlayerProxy : public CLogicalEntity #ifdef PORTAL void InputSuppressCrosshair( inputdata_t &inputdata ); #endif // PORTAL2 +#ifdef MAPBASE + void InputRequestPlayerArmor( inputdata_t &inputdata ); + void InputRequestPlayerAuxPower( inputdata_t &inputdata ); + void InputRequestPlayerFlashBattery( inputdata_t &inputdata ); + + void InputGetAmmoOnWeapon( inputdata_t &inputdata ); + + void InputSetHandModel( inputdata_t &inputdata ); + void InputSetHandModelSkin( inputdata_t &inputdata ); + void InputSetHandModelBodyGroup( inputdata_t &inputdata ); + + void InputSetPlayerModel( inputdata_t &inputdata ); + void InputSetPlayerDrawExternally( inputdata_t &inputdata ); +#endif void Activate ( void ); +#ifdef MAPBASE + bool KeyValue( const char *szKeyName, const char *szValue ); + + bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ); + + void NotifyPlayerHasProxy(); + + // This is here because the player might not be available when we spawn. + // Hope there wouldn't be enough time for this to need to be saved... + CUtlDict m_QueuedKV; + + int m_MaxArmor = 100; + int m_SuitZoomFOV = 25; +#endif + bool PassesDamageFilter( const CTakeDamageInfo &info ); EHANDLE m_hPlayer; }; +#ifdef MAPBASE +static CUtlVector g_pCommandRedirects; + +//----------------------------------------------------------------------------- +// Redirects player squad commands +//----------------------------------------------------------------------------- +class CCommandRedirect : public CBaseTrigger +{ + DECLARE_CLASS( CCommandRedirect, CBaseTrigger ); +public: + CCommandRedirect() + { + g_pCommandRedirects.AddToTail(this); + //int i = g_pCommandRedirects.AddToTail(); + //g_pCommandRedirects[i].Set( this ); + } + + ~CCommandRedirect() + { + g_pCommandRedirects.FindAndRemove(this); + /* + for (int i = 0; i < g_pCommandRedirects.Count(); i++) + { + if (g_pCommandRedirects[i].Get() == this) + { + g_pCommandRedirects.Remove( i ); + break; + } + } + */ + } + + void Spawn() + { + BaseClass::Spawn(); + InitTrigger(); + } + + // Will the command point change? + // True = Command point changes + // False = Comand point doesn't change + bool TestRedirect(Vector *vecNewCommandPoint, CHL2_Player *pPlayer) + { + // Output the goal before doing anything else. + m_OnCommandGoal.Set(*vecNewCommandPoint, pPlayer, this); + + if (m_target == NULL_STRING) + { + // Not targeting anything. Don't redirect and just leave it at the output + return false; + } + else if (FStrEq(STRING(m_target), "-1")) + { + // Completely cancel the squad command. + *vecNewCommandPoint = vec3_origin; + return true; + } + else + { + // Player is caller. + // Player squad representative is activator. + CBaseEntity *pEntOfInterest = gEntList.FindEntityGeneric(NULL, STRING(m_target), this, pPlayer->GetSquadCommandRepresentative(), pPlayer); + if (pEntOfInterest) + { + // Use the entity's absolute origin as the new command point. + *vecNewCommandPoint = pEntOfInterest->GetAbsOrigin(); + return true; + } + else + { + Warning("%s couldn't find target entity \"%s\"\n", GetDebugName(), STRING(m_target)); + } + } + + return false; + } + + void HandleAllies(CAI_Squad *pSquad, CHL2_Player *pPlayer) + { + if (m_bRepOnly) + { + CBaseEntity *pSquadRep = pPlayer->GetSquadCommandRepresentative(); + if (pSquadRep) + m_OutAlly.Set(pSquadRep, pSquadRep, this); + } + else + { + AISquadIter_t iter; + for ( CBaseEntity *pAllyNpc = pSquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = pSquad->GetNextMember(&iter) ) + { + m_OutAlly.Set(pAllyNpc, pAllyNpc, this); + } + } + } + + bool PassesTriggerFilters(CBaseEntity *pOther) + { + return pOther->IsPlayer() || (pOther->MyNPCPointer() && pOther->MyNPCPointer()->IsInPlayerSquad()); + } + + bool IsDisabled() { return m_bDisabled; } + + DECLARE_DATADESC(); + +private: + bool m_bRepOnly; + + COutputVector m_OnCommandGoal; + COutputEHANDLE m_OutAlly; +}; + +LINK_ENTITY_TO_CLASS( func_commandredirect, CCommandRedirect ); +BEGIN_DATADESC( CCommandRedirect ) + + DEFINE_KEYFIELD( m_bRepOnly, FIELD_BOOLEAN, "reponly" ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_OUTPUT( m_OnCommandGoal, "OnCommandGoal" ), + DEFINE_OUTPUT( m_OutAlly, "OutAlly" ), + +END_DATADESC() +#endif + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -366,10 +564,34 @@ BEGIN_DATADESC( CHL2_Player ) DEFINE_INPUTFUNC( FIELD_FLOAT, "IgnoreFallDamage", InputIgnoreFallDamage ), DEFINE_INPUTFUNC( FIELD_FLOAT, "IgnoreFallDamageWithoutReset", InputIgnoreFallDamageWithoutReset ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "OnSquadMemberKilled", OnSquadMemberKilled ), +#else DEFINE_INPUTFUNC( FIELD_VOID, "OnSquadMemberKilled", OnSquadMemberKilled ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "DisableFlashlight", InputDisableFlashlight ), DEFINE_INPUTFUNC( FIELD_VOID, "EnableFlashlight", InputEnableFlashlight ), DEFINE_INPUTFUNC( FIELD_VOID, "ForceDropPhysObjects", InputForceDropPhysObjects ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "SquadForceSummon", InputSquadForceSummon ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SquadForceGoTo", InputSquadForceGoTo ), // FIELD_INPUT so it supports vectors, ehandles, and strings + + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddArmor", InputAddArmor ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveArmor", InputRemoveArmor ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetArmor", InputSetArmor ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "AddAuxPower", InputAddAuxPower ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "RemoveAuxPower", InputRemoveAuxPower ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetAuxPower", InputSetAuxPower ), + + DEFINE_INPUTFUNC( FIELD_VOID, "TurnFlashlightOn", InputTurnFlashlightOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnFlashlightOff", InputTurnFlashlightOff ), + + DEFINE_INPUTFUNC( FIELD_VOID, "EnableGeigerCounter", InputEnableGeigerCounter ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableGeigerCounter", InputDisableGeigerCounter ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowSquadHUD", InputShowSquadHUD ), + DEFINE_INPUTFUNC( FIELD_VOID, "HideSquadHUD", InputHideSquadHUD ), +#endif DEFINE_SOUNDPATCH( m_sndLeeches ), DEFINE_SOUNDPATCH( m_sndWaterSplashes ), @@ -387,6 +609,27 @@ BEGIN_DATADESC( CHL2_Player ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CHL2_Player, CBasePlayer, "The HL2 player entity." ) + + DEFINE_SCRIPTFUNC_NAMED( SuitPower_Drain, "RemoveAuxPower", "Removes from the player's available aux power." ) + DEFINE_SCRIPTFUNC_NAMED( SuitPower_Charge, "AddAuxPower", "Adds to the player's available aux power." ) + DEFINE_SCRIPTFUNC_NAMED( SuitPower_SetCharge, "SetAuxPower", "Sets the player's available aux power." ) + DEFINE_SCRIPTFUNC_NAMED( SuitPower_GetCurrentPercentage, "GetAuxPower", "Gets the player's available aux power." ) + DEFINE_SCRIPTFUNC( GetFlashlightBattery, "Gets the energy available in the player's flashlight. If the legacy (aux power-based) flashlight is enabled, this returns the aux power." ) + + DEFINE_SCRIPTFUNC( InitCustomSuitDevice, "Initializes a custom suit device. (just sets drain rate for now)" ) + DEFINE_SCRIPTFUNC( AddCustomSuitDevice, "Adds a custom suit device ID. (1-3)" ) + DEFINE_SCRIPTFUNC( RemoveCustomSuitDevice, "Removes a custom suit device ID. (1-3)" ) + DEFINE_SCRIPTFUNC( IsCustomSuitDeviceActive, "Checks if a custom suit device is active." ) + +#ifdef SP_ANIM_STATE + DEFINE_SCRIPTFUNC( AddAnimStateLayer, "Adds a custom sequence index as a misc. layer for the singleplayer anim state, wtih parameters for blending in/out, setting the playback rate, holding the animation at the end, and only playing when the player is still." ) +#endif + +END_SCRIPTDESC(); +#endif + CHL2_Player::CHL2_Player() { m_nNumMissPositions = 0; @@ -415,10 +658,23 @@ CHL2_Player::CHL2_Player() #endif CSuitPowerDevice SuitDeviceBreather( bits_SUIT_DEVICE_BREATHER, 6.7f ); // 100 units in 15 seconds (plus three padded seconds) +#ifdef MAPBASE +// Default: 100 units in 8 seconds +CSuitPowerDevice SuitDeviceCustom[] = +{ + { bits_SUIT_DEVICE_CUSTOM0, 12.5f }, + { bits_SUIT_DEVICE_CUSTOM1, 12.5f }, + { bits_SUIT_DEVICE_CUSTOM2, 12.5f }, +}; +#endif + IMPLEMENT_SERVERCLASS_ST(CHL2_Player, DT_HL2_Player) SendPropDataTable(SENDINFO_DT(m_HL2Local), &REFERENCE_SEND_TABLE(DT_HL2Local), SendProxy_SendLocalDataTable), SendPropBool( SENDINFO(m_fIsSprinting) ), +#ifdef SP_ANIM_STATE + SendPropFloat( SENDINFO(m_flAnimRenderYaw), 0, SPROP_NOSCALE ), +#endif END_SEND_TABLE() @@ -902,6 +1158,16 @@ void CHL2_Player::PostThink( void ) { HandleAdmireGlovesAnimation(); } + +#ifdef SP_ANIM_STATE + if (m_pPlayerAnimState) + { + QAngle angEyeAngles = EyeAngles(); + m_pPlayerAnimState->Update( angEyeAngles.y, angEyeAngles.x ); + + m_flAnimRenderYaw.Set( m_pPlayerAnimState->GetRenderAngles().y ); + } +#endif } void CHL2_Player::StartAdmireGlovesAnimation( void ) @@ -997,6 +1263,10 @@ Class_T CHL2_Player::Classify ( void ) if(IsInAVehicle()) { IServerVehicle *pVehicle = GetVehicle(); +#ifdef MAPBASE + if (!pVehicle) + return CLASS_PLAYER; +#endif return pVehicle->ClassifyPassenger( this, CLASS_PLAYER ); } else @@ -1103,6 +1373,119 @@ void CHL2_Player::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper) BaseClass::PlayerRunCommand( ucmd, moveHelper ); } +#ifdef MAPBASE +void CHL2_Player::SpawnedAtPoint( CBaseEntity *pSpawnPoint ) +{ + FirePlayerProxyOutput( "OnPlayerSpawn", variant_t(), this, pSpawnPoint ); +} + +//----------------------------------------------------------------------------- + +ConVar player_use_anim_enabled( "player_use_anim_enabled", "1" ); +ConVar player_use_anim_heavy_mass( "player_use_anim_heavy_mass", "20.0" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CHL2_Player::Weapon_TranslateActivity( Activity baseAct, bool *pRequired ) +{ + Activity weaponTranslation = BaseClass::Weapon_TranslateActivity( baseAct, pRequired ); + +#if EXPANDED_HL2DM_ACTIVITIES + // +USE activities + // HACKHACK: Make sure m_hUseEntity is a pickup controller first + if ( m_hUseEntity && m_hUseEntity->ClassMatches("player_pickup") && player_use_anim_enabled.GetBool()) + { + CBaseEntity* pHeldEnt = GetPlayerHeldEntity( this ); + float flMass = pHeldEnt ? + (pHeldEnt->VPhysicsGetObject() ? PlayerPickupGetHeldObjectMass( m_hUseEntity, pHeldEnt->VPhysicsGetObject() ) : player_use_anim_heavy_mass.GetFloat()) : + (m_hUseEntity->VPhysicsGetObject() ? m_hUseEntity->GetMass() : player_use_anim_heavy_mass.GetFloat()); + if ( flMass >= player_use_anim_heavy_mass.GetFloat() ) + { + // Heavy versions + switch (baseAct) + { + case ACT_HL2MP_IDLE: weaponTranslation = ACT_HL2MP_IDLE_USE_HEAVY; break; + case ACT_HL2MP_RUN: weaponTranslation = ACT_HL2MP_RUN_USE_HEAVY; break; + case ACT_HL2MP_WALK: weaponTranslation = ACT_HL2MP_WALK_USE_HEAVY; break; + case ACT_HL2MP_IDLE_CROUCH: weaponTranslation = ACT_HL2MP_IDLE_CROUCH_USE_HEAVY; break; + case ACT_HL2MP_WALK_CROUCH: weaponTranslation = ACT_HL2MP_WALK_CROUCH_USE_HEAVY; break; + case ACT_HL2MP_JUMP: weaponTranslation = ACT_HL2MP_JUMP_USE_HEAVY; break; + } + } + else + { + switch (baseAct) + { + case ACT_HL2MP_IDLE: weaponTranslation = ACT_HL2MP_IDLE_USE; break; + case ACT_HL2MP_RUN: weaponTranslation = ACT_HL2MP_RUN_USE; break; + case ACT_HL2MP_WALK: weaponTranslation = ACT_HL2MP_WALK_USE; break; + case ACT_HL2MP_IDLE_CROUCH: weaponTranslation = ACT_HL2MP_IDLE_CROUCH_USE; break; + case ACT_HL2MP_WALK_CROUCH: weaponTranslation = ACT_HL2MP_WALK_CROUCH_USE; break; + case ACT_HL2MP_JUMP: weaponTranslation = ACT_HL2MP_JUMP_USE; break; + } + } + } +#endif + + return weaponTranslation; +} + +#ifdef SP_ANIM_STATE +// Set the activity based on an event or current state +void CHL2_Player::SetAnimation( PLAYER_ANIM playerAnim ) +{ + if (!m_pPlayerAnimState) + { + BaseClass::SetAnimation( playerAnim ); + return; + } + + m_pPlayerAnimState->SetPlayerAnimation( playerAnim ); +} + +void CHL2_Player::AddAnimStateLayer( int iSequence, float flBlendIn, float flBlendOut, float flPlaybackRate, bool bHoldAtEnd, bool bOnlyWhenStill ) +{ + if (!m_pPlayerAnimState) + return; + + m_pPlayerAnimState->AddMiscSequence( iSequence, flBlendIn, flBlendOut, flPlaybackRate, bHoldAtEnd, bOnlyWhenStill ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: model-change notification. Fires on dynamic load completion as well +//----------------------------------------------------------------------------- +CStudioHdr *CHL2_Player::OnNewModel() +{ + CStudioHdr *hdr = BaseClass::OnNewModel(); + +#ifdef SP_ANIM_STATE + // Clears the animation state if we already have one. + if ( m_pPlayerAnimState != NULL ) + { + m_pPlayerAnimState->Release(); + m_pPlayerAnimState = NULL; + } + + if ( hdr && hdr->HaveSequenceForActivity(ACT_HL2MP_IDLE) && hl2_use_sp_animstate.GetBool() ) + { + // Here we create and init the player animation state. + m_pPlayerAnimState = CreatePlayerAnimationState(this); + } + else + { + m_flAnimRenderYaw = FLT_MAX; + } +#endif + + return hdr; +} + +extern char g_szDefaultPlayerModel[MAX_PATH]; +extern bool g_bDefaultPlayerDrawExternally; +#endif + //----------------------------------------------------------------------------- // Purpose: Sets HL2 specific defaults. //----------------------------------------------------------------------------- @@ -1111,12 +1494,30 @@ void CHL2_Player::Spawn(void) #ifndef HL2MP #ifndef PORTAL +#ifdef MAPBASE + if ( GetModelName() == NULL_STRING ) + SetModel( g_szDefaultPlayerModel ); +#else SetModel( "models/player.mdl" ); #endif +#endif #endif BaseClass::Spawn(); +#ifdef MAPBASE + // Ported from CHL2MP_Player. Fixes issues with respawning players in SP + if ( !IsObserver() ) + { + pl.deadflag = false; + RemoveSolidFlags( FSOLID_NOT_SOLID ); + + RemoveEffects( EF_NODRAW ); + } + + SetDrawPlayerModelExternally( g_bDefaultPlayerDrawExternally ); +#endif + // // Our player movement speed is set once here. This will override the cl_xxxx // cvars unless they are set to be lower than this. @@ -1312,7 +1713,11 @@ void CHL2_Player::ToggleZoom(void) //----------------------------------------------------------------------------- void CHL2_Player::StartZooming( void ) { +#ifdef MAPBASE + int iFOV = GetPlayerProxy() ? GetPlayerProxy()->m_SuitZoomFOV : 25; +#else int iFOV = 25; +#endif if ( SetFOV( this, iFOV, 0.4f ) ) { m_HL2Local.m_bZooming = true; @@ -1381,6 +1786,14 @@ void CHL2_Player::InitVCollision( const Vector &vecAbsOrigin, const Vector &vecA CHL2_Player::~CHL2_Player( void ) { +#ifdef SP_ANIM_STATE + // Clears the animation state. + if ( m_pPlayerAnimState != NULL ) + { + m_pPlayerAnimState->Release(); + m_pPlayerAnimState = NULL; + } +#endif } //----------------------------------------------------------------------------- @@ -1397,10 +1810,49 @@ bool CHL2_Player::CommanderFindGoal( commandgoal_t *pGoal ) //--------------------------------- // MASK_SHOT on purpose! So that you don't hit the invisible hulls of the NPCs. +#ifdef MAPBASE + // Get either our +USE entity or the gravity gun entity + CBaseEntity *pHeldEntity = GetPlayerHeldEntity(this); + if ( !pHeldEntity ) + PhysCannonGetHeldEntity( GetActiveWeapon() ); + + CTraceFilterSkipTwoEntities filter( this, pHeldEntity, COLLISION_GROUP_INTERACTIVE_DEBRIS ); +#else CTraceFilterSkipTwoEntities filter( this, PhysCannonGetHeldEntity( GetActiveWeapon() ), COLLISION_GROUP_INTERACTIVE_DEBRIS ); +#endif UTIL_TraceLine( EyePosition(), EyePosition() + forward * MAX_COORD_RANGE, MASK_SHOT, &filter, &tr ); +#ifdef MAPBASE + // func_commandredirect handling + if (g_pCommandRedirects.Count() > 0) + { + for (int i = 0; i < g_pCommandRedirects.Count(); i++) + { + CCommandRedirect *pCommandRedirect = static_cast(g_pCommandRedirects[i]); + if (!pCommandRedirect || pCommandRedirect->IsDisabled() || !pCommandRedirect->PointIsWithin(tr.endpos)) + continue; + + // First, give it our allies so it could fire outputs + pCommandRedirect->HandleAllies(m_pPlayerAISquad, this); + + Vector vec = tr.endpos; + if (pCommandRedirect->TestRedirect(&vec, this)) + { + // If it returned a 0 vector, cancel the command + if (vec.IsZero()) + { + return false; + } + + // Just set our goal to this and skip the code below which checks the target position's validity + pGoal->m_vecGoalLocation = vec; + return true; + } + } + } + //else +#endif if( !tr.DidHitWorld() ) { CUtlVector Allies; @@ -1521,7 +1973,11 @@ void CHL2_Player::CommanderUpdate() { CAI_BaseNPC *pCommandRepresentative = GetSquadCommandRepresentative(); bool bFollowMode = false; +#ifdef MAPBASE + if ( pCommandRepresentative && !HasSpawnFlags(SF_PLAYER_HIDE_SQUAD_HUD) ) +#else if ( pCommandRepresentative ) +#endif { bFollowMode = ( pCommandRepresentative->GetCommandGoal() == vec3_invalid ); @@ -1567,8 +2023,22 @@ void CHL2_Player::CommanderUpdate() { m_CommanderUpdateTimer.Set(2.5); +#ifdef MAPBASE + if ( pCommandRepresentative->ShouldAutoSummon() ) + { + if (!HL2GameRules()->AutosummonDisabled() && player_squad_autosummon_enabled.GetBool()) + CommanderExecute( CC_FOLLOW ); + else + { + // Show a hud hint if autosummoning has been disabled + UTIL_HudHintText( this, "#Valve_Hint_Command_recall" ); + //m_CommanderUpdateTimer.Set(10.0); + } + } +#else if ( pCommandRepresentative->ShouldAutoSummon() ) CommanderExecute( CC_FOLLOW ); +#endif } } @@ -1696,34 +2166,123 @@ void CHL2_Player::CommanderMode() } } +#ifdef MAPBASE //----------------------------------------------------------------------------- // Purpose: -// Input : iImpulse - +//----------------------------------------------------------------------------- +void CHL2_Player::InputSquadForceSummon( inputdata_t &inputdata ) +{ + CommanderExecute( CC_FOLLOW ); +} + //----------------------------------------------------------------------------- -void CHL2_Player::CheatImpulseCommands( int iImpulse ) +// Purpose: Forces the player's squad to go to a specific location or entity. +//----------------------------------------------------------------------------- +void CHL2_Player::InputSquadForceGoTo( inputdata_t &inputdata ) { - switch( iImpulse ) + CAI_BaseNPC *pPlayerSquadLeader = GetSquadCommandRepresentative(); + + if ( !pPlayerSquadLeader ) + return; + + int i; + CUtlVector Allies; + commandgoal_t goal; + + variant_t var = Variant_ParseInput(inputdata); + + if (var.FieldType() == FIELD_VECTOR) { - case 50: + goal.m_pGoalEntity = NULL; + var.Vector3D(goal.m_vecGoalLocation); + } + else { - CommanderMode(); - break; + goal.m_pGoalEntity = var.FieldType() == FIELD_EHANDLE ? var.Entity().Get() : gEntList.FindEntityByNameNearest(var.String(), pPlayerSquadLeader->GetAbsOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); + goal.m_vecGoalLocation = vec3_invalid; } - case 51: + AISquadIter_t iter; + for ( CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) ) { - // Cheat to create a dynamic resupply item - Vector vecForward; - AngleVectors( EyeAngles(), &vecForward ); - CBaseEntity *pItem = (CBaseEntity *)CreateEntityByName( "item_dynamic_resupply" ); - if ( pItem ) - { - Vector vecOrigin = GetAbsOrigin() + vecForward * 256 + Vector(0,0,64); - QAngle vecAngles( 0, GetAbsAngles().y - 90, 0 ); - pItem->SetAbsOrigin( vecOrigin ); - pItem->SetAbsAngles( vecAngles ); - pItem->KeyValue( "targetname", "resupply" ); - pItem->Spawn(); + if ( pAllyNpc->IsCommandable() ) + Allies.AddToTail( pAllyNpc ); + } + + CAI_BaseNPC * pTargetNpc = (goal.m_pGoalEntity) ? goal.m_pGoalEntity->MyNPCPointer() : NULL; + + bool bHandled = false; + if( pTargetNpc ) + { + bHandled = !CommanderExecuteOne( pTargetNpc, goal, Allies.Base(), Allies.Count() ); + } + + for ( i = 0; !bHandled && i < Allies.Count(); i++ ) + { + if ( Allies[i] != pTargetNpc && Allies[i]->IsPlayerAlly() ) + { + bHandled = !CommanderExecuteOne( Allies[i], goal, Allies.Base(), Allies.Count() ); + } + } + + //CommanderExecute( CC_SEND ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2_Player::InputEnableGeigerCounter( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_PLAYER_NO_GEIGER); +} + +void CHL2_Player::InputDisableGeigerCounter( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_PLAYER_NO_GEIGER); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2_Player::InputShowSquadHUD( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_PLAYER_HIDE_SQUAD_HUD); +} + +void CHL2_Player::InputHideSquadHUD( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_PLAYER_HIDE_SQUAD_HUD); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +// Input : iImpulse - +//----------------------------------------------------------------------------- +void CHL2_Player::CheatImpulseCommands( int iImpulse ) +{ + switch( iImpulse ) + { + case 50: + { + CommanderMode(); + break; + } + + case 51: + { + // Cheat to create a dynamic resupply item + Vector vecForward; + AngleVectors( EyeAngles(), &vecForward ); + CBaseEntity *pItem = (CBaseEntity *)CreateEntityByName( "item_dynamic_resupply" ); + if ( pItem ) + { + Vector vecOrigin = GetAbsOrigin() + vecForward * 256 + Vector(0,0,64); + QAngle vecAngles( 0, GetAbsAngles().y - 90, 0 ); + pItem->SetAbsOrigin( vecOrigin ); + pItem->SetAbsAngles( vecAngles ); + pItem->KeyValue( "targetname", "resupply" ); + pItem->Spawn(); pItem->Activate(); } break; @@ -2239,6 +2798,72 @@ void CHL2_Player::InputIgnoreFallDamageWithoutReset( inputdata_t &inputdata ) m_bIgnoreFallDamageResetAfterImpact = false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputAddArmor( inputdata_t &inputdata ) +{ + int iArmor = MIN((GetPlayerProxy() ? GetPlayerProxy()->m_MaxArmor : 100) - ArmorValue(), inputdata.value.Int()); + + IncrementArmorValue( iArmor ); +} + +//----------------------------------------------------------------------------- +// This can also add to the player's armor by passing a negative input +// which can bypass the maximum armor set in the player proxy. +//----------------------------------------------------------------------------- +void CHL2_Player::InputRemoveArmor( inputdata_t &inputdata ) +{ + int iArmor = MIN(ArmorValue(), inputdata.value.Int()); + + IncrementArmorValue( -iArmor ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputSetArmor( inputdata_t &inputdata ) +{ + int iArmor = MIN(GetPlayerProxy() ? GetPlayerProxy()->m_MaxArmor : 100, inputdata.value.Int()); + + SetArmorValue( iArmor ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputAddAuxPower( inputdata_t &inputdata ) +{ + SuitPower_Charge( inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputRemoveAuxPower( inputdata_t &inputdata ) +{ + SuitPower_Drain( inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputSetAuxPower( inputdata_t &inputdata ) +{ + SuitPower_SetCharge( inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputTurnFlashlightOn( inputdata_t &inputdata ) +{ + FlashlightTurnOn(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHL2_Player::InputTurnFlashlightOff( inputdata_t &inputdata ) +{ + FlashlightTurnOff(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Notification of a player's npc ally in the players squad being killed //----------------------------------------------------------------------------- @@ -2249,6 +2874,10 @@ void CHL2_Player::OnSquadMemberKilled( inputdata_t &data ) user.MakeReliable(); UserMessageBegin( user, "SquadMemberDied" ); MessageEnd(); + +#ifdef MAPBASE + FirePlayerProxyOutput("OnSquadMemberKilled", data.value, data.pActivator, data.value.Entity()); +#endif } //----------------------------------------------------------------------------- @@ -2350,6 +2979,10 @@ int CHL2_Player::OnTakeDamage( const CTakeDamageInfo &info ) gamestats->Event_PlayerDamage( this, info ); +#ifdef MAPBASE + FirePlayerProxyOutput("PlayerDamaged", variant_t(), info.GetAttacker(), this); +#endif + return BaseClass::OnTakeDamage( playerDamage ); } @@ -2463,7 +3096,19 @@ void CHL2_Player::Event_Killed( const CTakeDamageInfo &info ) { BaseClass::Event_Killed( info ); +#ifdef MAPBASE + FirePlayerProxyOutput( "PlayerDied", variant_t(), info.GetAttacker(), this ); + + if (IsSuitEquipped()) + { + // Make sure all devices are deactivated (for respawn) + m_HL2Local.m_bitsActiveDevices = 0x00000000; + m_flSuitPowerLoad = 0; + m_flTimeAllSuitDevicesOff = gpGlobals->curtime; + } +#else FirePlayerProxyOutput( "PlayerDied", variant_t(), this, this ); +#endif NotifyScriptsOfDeath(); } @@ -2577,6 +3222,15 @@ bool CHL2_Player::ShouldKeepLockedAutoaimTarget( EHANDLE hLockedTarget ) return true; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CHL2_Player::CanAutoSwitchToNextBestWeapon( CBaseCombatWeapon *pWeapon ) +{ + return player_autoswitch_enabled.GetBool(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : iCount - @@ -2618,6 +3272,9 @@ int CHL2_Player::GiveAmmo( int nCount, int nAmmoIndex, bool bSuppressSound) if ( pWeapon && pWeapon->GetPrimaryAmmoType() == nAmmoIndex ) { +#ifdef MAPBASE + if (CanAutoSwitchToNextBestWeapon(pWeapon)) +#endif SwitchToNextBestWeapon(GetActiveWeapon()); } } @@ -2630,12 +3287,45 @@ int CHL2_Player::GiveAmmo( int nCount, int nAmmoIndex, bool bSuppressSound) bool CHL2_Player::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) { #ifndef HL2MP +#ifdef MAPBASE + if ( pWeapon->ClassMatches( "weapon_stunstick" ) ) + { + switch (HL2GameRules()->GetStunstickPickupBehavior()) + { + // Default, including 0 + default: + { + if ( ApplyBattery( 0.5 ) ) + UTIL_Remove( pWeapon ); + return false; + } break; + + // Allow pickup, if already picked up just apply battery + case 1: + { + if ( Weapon_OwnsThisType("weapon_stunstick") ) + { + if ( ApplyBattery( 0.5 ) ) + UTIL_Remove( pWeapon ); + return false; + } + } break; + + // Don't pickup, don't even apply battery + case 2: return false; + + // Just pickup, never apply battery + case 3: break; + } + } +#else if ( pWeapon->ClassMatches( "weapon_stunstick" ) ) { if ( ApplyBattery( 0.5 ) ) UTIL_Remove( pWeapon ); return false; } +#endif #endif return BaseClass::Weapon_CanUse( pWeapon ); @@ -3154,6 +3844,11 @@ float CHL2_Player::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return mass; } +CBaseEntity *CHL2_Player::GetHeldObject( void ) +{ + return PhysCannonGetHeldEntity( GetActiveWeapon() ); +} + //----------------------------------------------------------------------------- // Purpose: Force the player to drop any physics objects he's carrying //----------------------------------------------------------------------------- @@ -3298,7 +3993,10 @@ Vector CHL2_Player::EyeDirection2D( void ) Vector CHL2_Player::EyeDirection3D( void ) { Vector vecForward; - +#ifdef MAPBASE + EyeVectors( &vecForward ); + return vecForward; +#else // Return the vehicle angles if we request them if ( GetVehicle() != NULL ) { @@ -3309,6 +4007,7 @@ Vector CHL2_Player::EyeDirection3D( void ) AngleVectors( EyeAngles(), &vecForward ); return vecForward; +#endif } @@ -3666,6 +4365,64 @@ void CHL2_Player::DisplayLadderHudHint() #endif//CLIENT_DLL } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CHL2_Player::InitCustomSuitDevice( int iDeviceID, float flDrainRate ) +{ + if (iDeviceID < 0 || iDeviceID > 2) + { + Warning("InitCustomSuitDevice : \"%i\" is not a valid custom device slot\n", iDeviceID); + return; + } + + SuitDeviceCustom[iDeviceID].SetDeviceDrainRate( flDrainRate ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CHL2_Player::AddCustomSuitDevice( int iDeviceID ) +{ + if (iDeviceID < 0 || iDeviceID > 2) + { + Warning("AddCustomSuitDevice : \"%i\" is not a valid custom device slot\n", iDeviceID); + return; + } + + SuitPower_AddDevice( SuitDeviceCustom[iDeviceID] ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CHL2_Player::RemoveCustomSuitDevice( int iDeviceID ) +{ + if (iDeviceID < 0 || iDeviceID > 2) + { + Warning("AddCustomSuitDevice : \"%i\" is not a valid custom device slot\n", iDeviceID); + return; + } + + SuitPower_RemoveDevice( SuitDeviceCustom[iDeviceID] ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CHL2_Player::IsCustomSuitDeviceActive( int iDeviceID ) +{ + if (iDeviceID < 0 || iDeviceID > 2) + { + Warning("IsCustomSuitDeviceActive : \"%i\" is not a valid custom device slot\n", iDeviceID); + return false; + } + + return SuitPower_IsDeviceActive( SuitDeviceCustom[iDeviceID] ); +} +#endif + //----------------------------------------------------------------------------- // Shuts down sounds //----------------------------------------------------------------------------- @@ -3697,6 +4454,22 @@ void CHL2_Player::ModifyOrAppendPlayerCriteria( AI_CriteriaSet& set ) } } +#ifdef MAPBASE +const char *CHL2_Player::GetOverrideStepSound( const char *pszBaseStepSoundName ) +{ + int idx = FindContextByName("footsteps"); + if (idx != -1) + { + const char *szSound = GetContextValue(idx); + if (szSound[0] != '\0') + { + return szSound; + } + } + return pszBaseStepSoundName; +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -3751,6 +4524,9 @@ CLogicPlayerProxy *CHL2_Player::GetPlayerProxy( void ) pProxy->m_hPlayer = this; m_hPlayerProxy = pProxy; +#ifdef MAPBASE + pProxy->NotifyPlayerHasProxy(); +#endif } return pProxy; @@ -3774,6 +4550,15 @@ BEGIN_DATADESC( CLogicPlayerProxy ) DEFINE_OUTPUT( m_PlayerHasNoAmmo, "PlayerHasNoAmmo" ), DEFINE_OUTPUT( m_PlayerDied, "PlayerDied" ), DEFINE_OUTPUT( m_PlayerMissedAR2AltFire, "PlayerMissedAR2AltFire" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_PlayerDamaged, "PlayerDamaged" ), + DEFINE_OUTPUT( m_OnSquadMemberKilled, "OnSquadMemberKilled" ), + DEFINE_OUTPUT( m_OnGetAmmo, "OnGetAmmo" ), + DEFINE_OUTPUT( m_RequestedPlayerArmor, "PlayerArmor" ), + DEFINE_OUTPUT( m_RequestedPlayerAuxPower, "PlayerAuxPower" ), + DEFINE_OUTPUT( m_RequestedPlayerFlashBattery, "PlayerFlashBattery" ), + DEFINE_OUTPUT( m_OnPlayerSpawn, "OnPlayerSpawn" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "RequestPlayerHealth", InputRequestPlayerHealth ), DEFINE_INPUTFUNC( FIELD_VOID, "SetFlashlightSlowDrain", InputSetFlashlightSlowDrain ), DEFINE_INPUTFUNC( FIELD_VOID, "SetFlashlightNormalDrain", InputSetFlashlightNormalDrain ), @@ -3786,6 +4571,19 @@ BEGIN_DATADESC( CLogicPlayerProxy ) #ifdef PORTAL DEFINE_INPUTFUNC( FIELD_VOID, "SuppressCrosshair", InputSuppressCrosshair ), #endif // PORTAL +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "RequestPlayerArmor", InputRequestPlayerArmor ), + DEFINE_INPUTFUNC( FIELD_VOID, "RequestPlayerAuxPower", InputRequestPlayerAuxPower ), + DEFINE_INPUTFUNC( FIELD_VOID, "RequestPlayerFlashBattery", InputRequestPlayerFlashBattery ), + DEFINE_INPUTFUNC( FIELD_STRING, "GetAmmoOnWeapon", InputGetAmmoOnWeapon ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetHandModel", InputSetHandModel ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHandModelSkin", InputSetHandModelSkin ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHandModelBodyGroup", InputSetHandModelBodyGroup ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetPlayerModel", InputSetPlayerModel ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetPlayerDrawExternally", InputSetPlayerDrawExternally ), + DEFINE_INPUT( m_MaxArmor, FIELD_INTEGER, "SetMaxInputArmor" ), + DEFINE_INPUT( m_SuitZoomFOV, FIELD_INTEGER, "SetSuitZoomFOV" ), +#endif DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ), END_DATADESC() @@ -3799,12 +4597,153 @@ void CLogicPlayerProxy::Activate( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CLogicPlayerProxy::KeyValue( const char *szKeyName, const char *szValue ) +{ + bool bPlayerKV = false; + + if (Q_strnicmp(szKeyName, "HandsVM", 7) == 0) + { + if (m_hPlayer) + { + szKeyName += 7; + CBasePlayer *pPlayer = static_cast( m_hPlayer.Get() ); + CBaseViewModel *vm = pPlayer->GetViewModel(1); + if (vm) + { + if (*szKeyName == NULL && PrecacheModel(szValue)) // HandsVM + vm->SetModel(szValue); + else if (FStrEq(szKeyName, "Skin")) // HandsVMSkin + vm->m_nSkin = atoi(szValue); + else if (FStrEq(szKeyName, "Body")) // HandsVMBody + vm->m_nBody = atoi(szValue); + } + return true; + } + } + else if (FStrEq(szKeyName, "ResponseContext")) + { + bPlayerKV = true; + if (m_hPlayer) + return m_hPlayer->KeyValue(szKeyName, szValue); + } + else if (FStrEq(szKeyName, "HideSquadHUD")) + { + if (m_hPlayer) + { + if (szValue[0] != '0') + m_hPlayer->AddSpawnFlags(SF_PLAYER_HIDE_SQUAD_HUD); + else + m_hPlayer->RemoveSpawnFlags(SF_PLAYER_HIDE_SQUAD_HUD); + return true; + } + } + else if (FStrEq(szKeyName, "PlayerModel")) + { + if (m_hPlayer) + { + if (PrecacheModel( szValue )) + { + m_hPlayer->SetModel( szValue ); + } + return true; + } + } + else + { + if (BaseClass::KeyValue( szKeyName, szValue )) + return true; + + if (m_hPlayer) + { + DevMsg("logic_playerproxy: Passing unhandled keyvalue \"%s, %s\" to player\n", szKeyName, szValue); + return m_hPlayer->KeyValue(szKeyName, szValue); + } + } + + // If we reach this point, player is not available to test unidentified/special KV + // Queue it up + DevMsg("logic_playerproxy: Queueing %s, %s\n", szKeyName, szValue); + m_QueuedKV.Insert(bPlayerKV ? UTIL_VarArgs("&&%s", szKeyName) : szKeyName, AllocPooledString(szValue)); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: calls the appropriate message mapped function in the entity according +// to the fired action. +// Input : char *szInputName - input destination +// *pActivator - entity which initiated this sequence of actions +// *pCaller - entity from which this event is sent +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CLogicPlayerProxy::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID ) +{ + bool base = BaseClass::AcceptInput( szInputName, pActivator, pCaller, Value, outputID ); + + if (!base) + { + if (m_hPlayer) + { + DevMsg("logic_playerproxy: Passing unhandled input \"%s\" to player\n", szInputName); + return m_hPlayer->AcceptInput( szInputName, pActivator, pCaller, Value, outputID ); + } + else + { + DevMsg("logic_playerproxy: Player not found!\n"); + + // Need to allocate the string here in case szInputName is freed before the input fires + g_EventQueue.AddEvent("!player", STRING( AllocPooledString(szInputName) ), Value, 0.01f, pActivator, pCaller); + } + } + + return base; +} + +//----------------------------------------------------------------------------- +// Purpose: Notifies logic_playerproxy when player is valid +//----------------------------------------------------------------------------- +void CLogicPlayerProxy::NotifyPlayerHasProxy() +{ + Assert( m_hPlayer != NULL ); + + // Handle any queued keyvalues + int iQueueCount = m_QueuedKV.Count(); + for (int i = 0; i < iQueueCount; i++) + { + const char *name = m_QueuedKV.GetElementName(i); + const char *value = STRING(m_QueuedKV[i]); + DevMsg("logic_playerproxy: Handing over %s, %s from dict\n", name, value); + + if (name[0] == '&' && name[1] == '&') + { + // We're supposed to send this to the player + m_hPlayer->KeyValue(name + 2, value); + } + + KeyValue(name, value); + } + + m_QueuedKV.RemoveAll(); +} +#endif + bool CLogicPlayerProxy::PassesDamageFilter( const CTakeDamageInfo &info ) { if (m_hDamageFilter) { CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get()); +#ifdef MAPBASE + return pFilter->PassesDamageFilter(m_hPlayer.Get(), info); +#else return pFilter->PassesDamageFilter(info); +#endif } return true; @@ -3827,6 +4766,43 @@ void CLogicPlayerProxy::InputRequestPlayerHealth( inputdata_t &inputdata ) m_RequestedPlayerHealth.Set( m_hPlayer->GetHealth(), inputdata.pActivator, inputdata.pCaller ); } +#ifdef MAPBASE +void CLogicPlayerProxy::InputRequestPlayerArmor( inputdata_t &inputdata ) +{ + if ( m_hPlayer == NULL ) + return; + + m_RequestedPlayerArmor.Set( static_cast(m_hPlayer.Get())->ArmorValue(), inputdata.pActivator, inputdata.pCaller ); +} + +void CLogicPlayerProxy::InputRequestPlayerAuxPower( inputdata_t &inputdata ) +{ + if ( m_hPlayer == NULL ) + return; + + m_RequestedPlayerAuxPower.Set( static_cast(m_hPlayer.Get())->SuitPower_GetCurrentPercentage(), inputdata.pActivator, inputdata.pCaller ); +} + +void CLogicPlayerProxy::InputRequestPlayerFlashBattery( inputdata_t &inputdata ) +{ + if ( m_hPlayer == NULL ) + return; + + m_RequestedPlayerFlashBattery.Set( static_cast(m_hPlayer.Get())->GetFlashlightBattery(), inputdata.pActivator, inputdata.pCaller ); +} + +// If it's the EP2 flashlight, it returns the flashlight battery. If it's the legacy flashlight, it returns the aux power. +// Note that this is on CHL2_Player, not CLogicPlayerProxy. +float CHL2_Player::GetFlashlightBattery() +{ +#ifdef HL2_EPISODIC + return Flashlight_UseLegacyVersion() ? SuitPower_GetCurrentPercentage() : m_HL2Local.m_flFlashBattery; +#else + return SuitPower_GetCurrentPercentage(); +#endif +} +#endif + void CLogicPlayerProxy::InputSetFlashlightSlowDrain( inputdata_t &inputdata ) { if( m_hPlayer == NULL ) @@ -3873,6 +4849,99 @@ void CLogicPlayerProxy::InputRequestAmmoState( inputdata_t &inputdata ) m_PlayerHasNoAmmo.FireOutput( this, this, 0 ); } +#ifdef MAPBASE +void CLogicPlayerProxy::InputGetAmmoOnWeapon( inputdata_t &inputdata ) +{ + if( m_hPlayer == NULL ) + return; + + CHL2_Player *pPlayer = dynamic_cast(m_hPlayer.Get()); + + const char *szClass = inputdata.value.String(); + + // Support secondary cases + bool bAmmo2 = szClass[0] == '@'; + if (bAmmo2) + szClass++; + + bool bClipOnly = szClass[0] == '#'; + if (bClipOnly) + szClass++; + + if (szClass[0] != NULL) + { + // Find weapon that matches class + for ( int i = 0 ; i < pPlayer->WeaponCount(); ++i ) + { + CBaseCombatWeapon* pCheck = pPlayer->GetWeapon( i ); + + if ( pCheck && FClassnameIs(pCheck, szClass) ) + { + int ammo = 0; + if (!bAmmo2) + { + // Ammo 1 + if (!bClipOnly) + ammo = pPlayer->GetAmmoCount(pCheck->GetPrimaryAmmoType()); + + if (pCheck->UsesClipsForAmmo1()) + ammo += pCheck->m_iClip1; + else + ammo += pCheck->GetPrimaryAmmoCount(); + } + else + { + // Ammo 2 + if (!bClipOnly) + ammo = pPlayer->GetAmmoCount(pCheck->GetSecondaryAmmoType()); + + if (pCheck->UsesClipsForAmmo2()) + ammo += pCheck->m_iClip2; + else + ammo += pCheck->GetSecondaryAmmoCount(); + } + + m_OnGetAmmo.Set( ammo, this, 0 ); + return; + } + } + } + else + { + // Get current weapon ammo + if (CBaseCombatWeapon *pCheck = pPlayer->GetActiveWeapon()) + { + int ammo = 0; + if (!bAmmo2) + { + // Ammo 1 + if (!bClipOnly) + ammo = pPlayer->GetAmmoCount(pCheck->GetPrimaryAmmoType()); + + if (pCheck->UsesClipsForAmmo1()) + ammo += pCheck->m_iClip1; + else + ammo += pCheck->GetPrimaryAmmoCount(); + } + else + { + // Ammo 2 + if (!bClipOnly) + ammo = pPlayer->GetAmmoCount(pCheck->GetSecondaryAmmoType()); + + if (pCheck->UsesClipsForAmmo2()) + ammo += pCheck->m_iClip2; + else + ammo += pCheck->GetSecondaryAmmoCount(); + } + + m_OnGetAmmo.Set( ammo, this, 0 ); + return; + } + } +} +#endif + void CLogicPlayerProxy::InputLowerWeapon( inputdata_t &inputdata ) { if( m_hPlayer == NULL ) @@ -3928,3 +4997,73 @@ void CLogicPlayerProxy::InputSuppressCrosshair( inputdata_t &inputdata ) pPlayer->SuppressCrosshair( true ); } #endif // PORTAL + +#ifdef MAPBASE +void CLogicPlayerProxy::InputSetHandModel( inputdata_t &inputdata ) +{ + if (!m_hPlayer) + return; + + string_t iszModel = inputdata.value.StringID(); + + if (iszModel != NULL_STRING) + PrecacheModel(STRING(iszModel)); + + CBasePlayer *pPlayer = static_cast( m_hPlayer.Get() ); + CBaseViewModel *vm = pPlayer->GetViewModel(1); + if (vm) + vm->SetModel(STRING(iszModel)); +} + +void CLogicPlayerProxy::InputSetHandModelSkin( inputdata_t &inputdata ) +{ + if (!m_hPlayer) + return; + + CBasePlayer *pPlayer = static_cast( m_hPlayer.Get() ); + CBaseViewModel *vm = pPlayer->GetViewModel(1); + if (vm) + vm->m_nSkin = inputdata.value.Int(); +} + +void CLogicPlayerProxy::InputSetHandModelBodyGroup( inputdata_t &inputdata ) +{ + if (!m_hPlayer) + return; + + CBasePlayer *pPlayer = static_cast( m_hPlayer.Get() ); + CBaseViewModel *vm = pPlayer->GetViewModel(1); + if (vm) + vm->m_nBody = inputdata.value.Int(); +} + +void CLogicPlayerProxy::InputSetPlayerModel( inputdata_t &inputdata ) +{ + if (!m_hPlayer) + return; + + string_t iszModel = inputdata.value.StringID(); + + if (iszModel != NULL_STRING) + PrecacheModel( STRING( iszModel ) ); + else + { + // We're resetting the model. The original model should've been cached to our own model name. + iszModel = GetModelName(); + } + + // Cache the original model as our own model name. + SetModelName( m_hPlayer->GetModelName() ); + + m_hPlayer->SetModel( STRING(iszModel) ); +} + +void CLogicPlayerProxy::InputSetPlayerDrawExternally( inputdata_t &inputdata ) +{ + if (!m_hPlayer) + return; + + CBasePlayer *pPlayer = static_cast(m_hPlayer.Get()); + pPlayer->SetDrawPlayerModelExternally( inputdata.value.Bool() ); +} +#endif diff --git a/game/server/hl2/hl2_player.h b/game/server/hl2/hl2_player.h index 43d5d1dc..5609a7d6 100644 --- a/game/server/hl2/hl2_player.h +++ b/game/server/hl2/hl2_player.h @@ -15,6 +15,13 @@ #include "simtimer.h" #include "soundenvelope.h" +// In HL2MP we need to inherit from BaseMultiplayerPlayer! +#if defined ( HL2MP ) +#include "basemultiplayerplayer.h" +#elif defined ( MAPBASE ) +#include "mapbase/singleplayer_animstate.h" +#endif + class CAI_Squad; class CPropCombineBall; @@ -70,15 +77,29 @@ class CSuitPowerDevice else return m_flDrainRate; } +#ifdef MAPBASE + void SetDeviceDrainRate( float flDrainRate ) { m_flDrainRate = flDrainRate; } +#endif }; //============================================================================= // >> HL2_PLAYER //============================================================================= +#if defined ( HL2MP ) +class CHL2_Player : public CBaseMultiplayerPlayer +#else class CHL2_Player : public CBasePlayer +#endif { public: +#if defined ( HL2MP ) + DECLARE_CLASS( CHL2_Player, CBaseMultiplayerPlayer ); +#else DECLARE_CLASS( CHL2_Player, CBasePlayer ); +#endif +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif CHL2_Player(); ~CHL2_Player( void ); @@ -107,6 +128,23 @@ class CHL2_Player : public CBasePlayer virtual void Splash( void ); virtual void ModifyOrAppendPlayerCriteria( AI_CriteriaSet& set ); +#ifdef MAPBASE + // For the logic_playerproxy output + void SpawnedAtPoint( CBaseEntity *pSpawnPoint ); + + Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL ); + +#ifdef SP_ANIM_STATE + void SetAnimation( PLAYER_ANIM playerAnim ); + + void AddAnimStateLayer( int iSequence, float flBlendIn = 0.0f, float flBlendOut = 0.0f, float flPlaybackRate = 1.0f, bool bHoldAtEnd = false, bool bOnlyWhenStill = false ); +#endif + + virtual CStudioHdr* OnNewModel(); + + virtual const char *GetOverrideStepSound( const char *pszBaseStepSoundName ); +#endif + void DrawDebugGeometryOverlays(void); virtual Vector EyeDirection2D( void ); @@ -139,6 +177,11 @@ class CHL2_Player : public CBasePlayer void SetFlashlightEnabled( bool bState ); +#ifdef MAPBASE + // Needed for logic_playerproxy + float GetFlashlightBattery(); +#endif + // Apply a battery bool ApplyBattery( float powerMultiplier = 1.0 ); @@ -159,6 +202,17 @@ class CHL2_Player : public CBasePlayer int GetNumSquadCommandables(); int GetNumSquadCommandableMedics(); +#ifdef MAPBASE + void InputSquadForceSummon( inputdata_t &inputdata ); + void InputSquadForceGoTo( inputdata_t &inputdata ); + + void InputEnableGeigerCounter( inputdata_t &inputdata ); + void InputDisableGeigerCounter( inputdata_t &inputdata ); + + void InputShowSquadHUD( inputdata_t &inputdata ); + void InputHideSquadHUD( inputdata_t &inputdata ); +#endif + // Locator void UpdateLocatorPosition( const Vector &vecPosition ); @@ -195,6 +249,19 @@ class CHL2_Player : public CBasePlayer void InputEnableFlashlight( inputdata_t &inputdata ); void InputDisableFlashlight( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputAddArmor( inputdata_t &inputdata ); + void InputRemoveArmor( inputdata_t &inputdata ); + void InputSetArmor( inputdata_t &inputdata ); + + void InputAddAuxPower( inputdata_t &inputdata ); + void InputRemoveAuxPower( inputdata_t &inputdata ); + void InputSetAuxPower( inputdata_t &inputdata ); + + void InputTurnFlashlightOn( inputdata_t &inputdata ); + void InputTurnFlashlightOff( inputdata_t &inputdata ); +#endif + const impactdamagetable_t &GetPhysicsImpactDamageTable(); virtual int OnTakeDamage( const CTakeDamageInfo &info ); virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info ); @@ -210,6 +277,10 @@ class CHL2_Player : public CBasePlayer void SetLocatorTargetEntity( CBaseEntity *pEntity ) { m_hLocatorTargetEntity.Set( pEntity ); } +#ifdef MAPBASE + virtual bool CanAutoSwitchToNextBestWeapon( CBaseCombatWeapon *pWeapon ); +#endif + virtual int GiveAmmo( int nCount, int nAmmoIndex, bool bSuppressSound); virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon ); @@ -241,6 +312,7 @@ class CHL2_Player : public CBasePlayer virtual bool IsHoldingEntity( CBaseEntity *pEnt ); virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis ); virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *GetHeldObject( void ); virtual bool IsFollowingPhysics( void ) { return (m_afPhysicsFlags & PFLAG_ONBARNACLE) > 0; } void InputForceDropPhysObjects( inputdata_t &data ); @@ -281,6 +353,13 @@ class CHL2_Player : public CBasePlayer // HUD HINTS void DisplayLadderHudHint(); +#ifdef MAPBASE + void InitCustomSuitDevice( int iDeviceID, float flDrainRate ); + void AddCustomSuitDevice( int iDeviceID ); + void RemoveCustomSuitDevice( int iDeviceID ); + bool IsCustomSuitDeviceActive( int iDeviceID ); +#endif + CSoundPatch *m_sndLeeches; CSoundPatch *m_sndWaterSplashes; @@ -365,6 +444,14 @@ class CHL2_Player : public CBasePlayer #ifdef VANCE friend class CVancePlayer; #endif + +#ifdef SP_ANIM_STATE + CSinglePlayerAnimState* m_pPlayerAnimState; + + // At the moment, we network the render angles since almost none of the player anim stuff is done on the client in SP. + // If any of this is ever adapted for MP, this method should be replaced with replicating/moving the anim state to the client. + CNetworkVar( float, m_flAnimRenderYaw ); +#endif }; diff --git a/game/server/hl2/hl2_triggers.cpp b/game/server/hl2/hl2_triggers.cpp index 55f718fe..9aeee1a9 100644 --- a/game/server/hl2/hl2_triggers.cpp +++ b/game/server/hl2/hl2_triggers.cpp @@ -589,6 +589,10 @@ class CTriggerWateryDeath : public CBaseTrigger public: DECLARE_DATADESC(); +#ifdef MAPBASE + CTriggerWateryDeath(); +#endif + void Spawn( void ); void Precache( void ); void Touch( CBaseEntity *pOther ); @@ -614,6 +618,13 @@ class CTriggerWateryDeath : public CBaseTrigger CUtlVector< float > m_flEntityKillTimes; float m_flNextPullSound; float m_flPainValue; + +#ifdef MAPBASE + float m_flBiteInterval; + float m_flPainStep; + float m_flMaxPain; + COutputInt m_OnDamage; +#endif }; BEGIN_DATADESC( CTriggerWateryDeath ) @@ -621,6 +632,12 @@ BEGIN_DATADESC( CTriggerWateryDeath ) DEFINE_UTLVECTOR( m_hLeeches, FIELD_EHANDLE ), DEFINE_FIELD( m_flNextPullSound, FIELD_TIME ), DEFINE_FIELD( m_flPainValue, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flBiteInterval, FIELD_FLOAT, "BiteInterval" ), + DEFINE_KEYFIELD( m_flPainStep, FIELD_FLOAT, "PainStep" ), + DEFINE_KEYFIELD( m_flMaxPain, FIELD_FLOAT, "MaxPain" ), + DEFINE_OUTPUT( m_OnDamage, "OnDamage" ), +#endif END_DATADESC() @@ -631,6 +648,15 @@ LINK_ENTITY_TO_CLASS( trigger_waterydeath, CTriggerWateryDeath ); #define WD_PAINVALUE_STEP 2.0 #define WD_MAX_DAMAGE 15.0f +#ifdef MAPBASE +CTriggerWateryDeath::CTriggerWateryDeath() +{ + m_flBiteInterval = WD_KILLTIME_NEXT_BITE; + m_flPainStep = WD_PAINVALUE_STEP; + m_flMaxPain = WD_MAX_DAMAGE; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Called when spawning, after keyvalues have been handled. //----------------------------------------------------------------------------- @@ -707,6 +733,23 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther ) { //EmitSound( filter, entindex(), "WateryDeath.Bite", &pOther->GetAbsOrigin() ); // Kill it +#ifdef MAPBASE + if ( pOther->IsPlayer() ) + { + m_flPainValue = MIN( m_flPainValue + m_flPainStep, m_flMaxPain ); + } + else + { + m_flPainValue = m_flMaxPain; + } + + // Do nothing if there is no damage + if (m_flPainValue <= 0.0f) + { + m_flEntityKillTimes[iIndex] = gpGlobals->curtime + m_flBiteInterval; + return; + } +#else if ( pOther->IsPlayer() ) { m_flPainValue = MIN( m_flPainValue + WD_PAINVALUE_STEP, WD_MAX_DAMAGE ); @@ -715,6 +758,7 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther ) { m_flPainValue = WD_MAX_DAMAGE; } +#endif // Use DMG_GENERIC & make the target inflict the damage on himself. // This ensures that if the target is the player, the damage isn't modified by skill @@ -723,7 +767,13 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther ) GuessDamageForce( &info, (pOther->GetAbsOrigin() - GetAbsOrigin()), pOther->GetAbsOrigin() ); pOther->TakeDamage( info ); +#ifdef MAPBASE + m_OnDamage.Set(m_flPainValue, pOther, this); + + m_flEntityKillTimes[iIndex] = gpGlobals->curtime + m_flBiteInterval; +#else m_flEntityKillTimes[iIndex] = gpGlobals->curtime + WD_KILLTIME_NEXT_BITE; +#endif } } diff --git a/game/server/hl2/item_ammo.cpp b/game/server/hl2/item_ammo.cpp index 2a981554..fa54ad1f 100644 --- a/game/server/hl2/item_ammo.cpp +++ b/game/server/hl2/item_ammo.cpp @@ -15,6 +15,64 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +// ======================================================================== +// >> CItemAmmo +// +// All ammo items now derive from this for multiplier purposes. +// ======================================================================== +class CItemAmmo : public CItem +{ +public: + DECLARE_CLASS( CItemAmmo, CItem ); + DECLARE_DATADESC(); + + int ITEM_GiveAmmo( CBasePlayer *pPlayer, float flCount, const char *pszAmmoName, bool bSuppressSound = false ) + { + int iAmmoType = GetAmmoDef()->Index(pszAmmoName); + if (iAmmoType == -1) + { + Msg("ERROR: Attempting to give unknown ammo type (%s)\n",pszAmmoName); + return 0; + } + + flCount *= g_pGameRules->GetAmmoQuantityScale(iAmmoType); + + // Don't give out less than 1 of anything. + flCount = MAX( 1.0f, flCount ); + + // Mapper-specific ammo multiplier. + // If it results in 0, the ammo will simply be ignored. + // If the ammo multiplier is negative, assume it's actually a direct number to override with. + if (m_flAmmoMultiplier != 1.0f) + { + if (m_flAmmoMultiplier >= 0) + flCount *= m_flAmmoMultiplier; + else + flCount = -m_flAmmoMultiplier; + } + + return pPlayer->GiveAmmo( flCount, iAmmoType, bSuppressSound ); + } + + void InputSetAmmoMultiplier( inputdata_t &inputdata ) { m_flAmmoMultiplier = inputdata.value.Float(); } + + float m_flAmmoMultiplier = 1.0f; +}; + +BEGIN_DATADESC( CItemAmmo ) + + DEFINE_KEYFIELD( m_flAmmoMultiplier, FIELD_FLOAT, "AmmoMultiplier" ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetAmmoMultiplier", InputSetAmmoMultiplier ), + +END_DATADESC() + +// Almost all instances of CItem below are for declaring the base class, which is now CItemAmmo. +// This is here so we don't have to #ifdef all of them. +#define CItem CItemAmmo + +#else //--------------------------------------------------------- // Applies ammo quantity scale. //--------------------------------------------------------- @@ -34,6 +92,7 @@ int ITEM_GiveAmmo( CBasePlayer *pPlayer, float flCount, const char *pszAmmoName, return pPlayer->GiveAmmo( flCount, iAmmoType, bSuppressSound ); } +#endif // ======================================================================== // >> BoxSRounds @@ -606,7 +665,10 @@ enum AMMOCRATE_CROSSBOW, AMMOCRATE_AR2_ALTFIRE, AMMOCRATE_SMG_ALTFIRE, - AMMOCRATE_FLAREROUND, +#ifdef MAPBASE + AMMOCRATE_SLAM, + AMMOCRATE_EMPTY, +#endif NUM_AMMO_CRATE_TYPES, }; @@ -649,6 +711,10 @@ class CItem_AmmoCrate : public CBaseAnimating COutputEvent m_OnUsed; CHandle< CBasePlayer > m_hActivator; +#ifdef MAPBASE + COutputEvent m_OnAmmoTaken; +#endif + DECLARE_DATADESC(); }; @@ -669,6 +735,10 @@ BEGIN_DATADESC( CItem_AmmoCrate ) DEFINE_OUTPUT( m_OnUsed, "OnUsed" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnAmmoTaken, "OnAmmoTaken" ), +#endif + DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ), DEFINE_THINKFUNC( CrateThink ), @@ -688,13 +758,22 @@ const char *CItem_AmmoCrate::m_lpzModelNames[NUM_AMMO_CRATE_TYPES] = "models/items/ammocrate_rockets.mdl", // RPG rounds "models/items/ammocrate_buckshot.mdl", // Buckshot "models/items/ammocrate_grenade.mdl", // Grenades +#ifdef MAPBASE + "models/items/ammocrate_357.mdl", // 357 + "models/items/ammocrate_xbow.mdl", // Crossbow + "models/items/ammocrate_ar2alt.mdl", // Combine Ball +#else "models/items/ammocrate_smg1.mdl", // 357 "models/items/ammocrate_smg1.mdl", // Crossbow - + //FIXME: This model is incorrect! "models/items/ammocrate_ar2.mdl", // Combine Ball +#endif "models/items/ammocrate_smg2.mdl", // smg grenade - "models/items/ammocrate_pistol.mdl", // Flareround +#ifdef MAPBASE + "models/items/ammocrate_slam.mdl", // slam + "models/items/ammocrate_empty.mdl", // empty +#endif }; // Ammo type names @@ -710,7 +789,10 @@ const char *CItem_AmmoCrate::m_lpzAmmoNames[NUM_AMMO_CRATE_TYPES] = "XBowBolt", "AR2AltFire", "SMG1_Grenade", - "FlareRound", +#ifdef MAPBASE + "slam", + NULL, +#endif }; // Ammo amount given per +use @@ -726,7 +808,10 @@ int CItem_AmmoCrate::m_nAmmoAmounts[NUM_AMMO_CRATE_TYPES] = 50, // Crossbow 3, // AR2 alt-fire 5, - 3 +#ifdef MAPBASE + 5, // SLAM + NULL, // Empty +#endif }; const char *CItem_AmmoCrate::m_pGiveWeapon[NUM_AMMO_CRATE_TYPES] = @@ -741,7 +826,10 @@ const char *CItem_AmmoCrate::m_pGiveWeapon[NUM_AMMO_CRATE_TYPES] = NULL, // Crossbow NULL, // AR2 alt-fire NULL, // SMG alt-fire - NULL +#ifdef MAPBASE + "weapon_slam", // SLAM + NULL, // Empty +#endif }; #define AMMO_CRATE_CLOSE_DELAY 1.5f @@ -797,6 +885,10 @@ void CItem_AmmoCrate::Precache( void ) //----------------------------------------------------------------------------- void CItem_AmmoCrate::SetupCrate( void ) { +#ifdef MAPBASE + // Custom models might be desired on, say, empty crates with custom textures + if (GetModelName() == NULL_STRING) +#endif SetModelName( AllocPooledString( m_lpzModelNames[m_nAmmoType] ) ); m_nAmmoIndex = GetAmmoDef()->Index( m_lpzAmmoNames[m_nAmmoType] ); @@ -920,13 +1012,24 @@ void CItem_AmmoCrate::HandleAnimEvent( animevent_t *pEvent ) } else { +#ifdef MAPBASE + m_OnAmmoTaken.FireOutput(m_hActivator, this); +#endif SetBodygroup( 1, false ); } } } +#ifdef MAPBASE + // Empty ammo crates should still fire OnAmmoTaken + if ( m_hActivator->GiveAmmo( m_nAmmoAmounts[m_nAmmoType], m_nAmmoIndex ) != 0 || m_nAmmoType == AMMOCRATE_EMPTY ) +#else if ( m_hActivator->GiveAmmo( m_nAmmoAmounts[m_nAmmoType], m_nAmmoIndex ) != 0 ) +#endif { +#ifdef MAPBASE + m_OnAmmoTaken.FireOutput(m_hActivator, this); +#endif SetBodygroup( 1, false ); } m_hActivator = NULL; @@ -984,6 +1087,13 @@ void CItem_AmmoCrate::CrateThink( void ) //----------------------------------------------------------------------------- void CItem_AmmoCrate::InputKill( inputdata_t &data ) { +#ifdef MAPBASE + // Why is this its own function? + // item_dynamic_resupply and item_item_crate are in the same boat. + // I don't understand. + m_OnKilled.FireOutput( data.pActivator, this ); +#endif + UTIL_Remove( this ); } diff --git a/game/server/hl2/item_battery.cpp b/game/server/hl2/item_battery.cpp index 7e299fc5..d5c8b416 100644 --- a/game/server/hl2/item_battery.cpp +++ b/game/server/hl2/item_battery.cpp @@ -23,12 +23,12 @@ class CItemBattery : public CItem void Spawn( void ) { Precache( ); - SetModel( "models/items/battery.mdl" ); + SetModel( DefaultOrCustomModel( "models/items/battery.mdl" ) ); BaseClass::Spawn( ); } void Precache( void ) { - PrecacheModel ("models/items/battery.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/items/battery.mdl" ) ); PrecacheScriptSound( "ItemBattery.Touch" ); @@ -36,10 +36,30 @@ class CItemBattery : public CItem bool MyTouch( CBasePlayer *pPlayer ) { CHL2_Player *pHL2Player = dynamic_cast( pPlayer ); +#ifdef MAPBASE + return ( pHL2Player && pHL2Player->ApplyBattery( m_flPowerMultiplier ) ); +#else return ( pHL2Player && pHL2Player->ApplyBattery() ); +#endif } + +#ifdef MAPBASE + void InputSetPowerMultiplier( inputdata_t &inputdata ) { m_flPowerMultiplier = inputdata.value.Float(); } + float m_flPowerMultiplier = 1.0f; + + DECLARE_DATADESC(); +#endif }; LINK_ENTITY_TO_CLASS(item_battery, CItemBattery); PRECACHE_REGISTER(item_battery); +#ifdef MAPBASE +BEGIN_DATADESC( CItemBattery ) + + DEFINE_KEYFIELD( m_flPowerMultiplier, FIELD_FLOAT, "PowerMultiplier" ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPowerMultiplier", InputSetPowerMultiplier ), + +END_DATADESC() +#endif + diff --git a/game/server/hl2/item_dynamic_resupply.cpp b/game/server/hl2/item_dynamic_resupply.cpp index 6bdcff62..bc0a6c96 100644 --- a/game/server/hl2/item_dynamic_resupply.cpp +++ b/game/server/hl2/item_dynamic_resupply.cpp @@ -116,6 +116,10 @@ class CItem_DynamicResupply : public CPointEntity float m_flDesiredAmmo[ NUM_AMMO_ITEMS ]; bool m_bIsMaster; + +#ifdef MAPBASE + COutputEHANDLE m_OnItem; +#endif }; LINK_ENTITY_TO_CLASS(item_dynamic_resupply, CItem_DynamicResupply); @@ -153,6 +157,10 @@ BEGIN_DATADESC( CItem_DynamicResupply ) DEFINE_FIELD( m_version, FIELD_INTEGER ), DEFINE_FIELD( m_bIsMaster, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnItem, "OnItem" ), +#endif + // Silence, Classcheck! // DEFINE_ARRAY( m_flDesiredHealth, FIELD_FLOAT, NUM_HEALTH_ITEMS ), // DEFINE_ARRAY( m_flDesiredAmmo, FIELD_FLOAT, NUM_AMMO_ITEMS ), @@ -282,6 +290,11 @@ void CItem_DynamicResupply::CheckPVSThink( void ) //----------------------------------------------------------------------------- void CItem_DynamicResupply::InputKill( inputdata_t &data ) { +#ifdef MAPBASE + // What's the point of this being its own function? + m_OnKilled.FireOutput( data.pActivator, this ); +#endif + UTIL_Remove( this ); } @@ -345,7 +358,12 @@ void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBase // If we're supposed to fallback to just a health vial, do that and finish. if ( pMaster->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL) ) { +#ifdef MAPBASE + CBaseEntity *pItem = CBaseEntity::Create("item_healthvial", GetAbsOrigin(), GetAbsAngles(), this); + m_OnItem.Set(pItem, pItem, this); +#else CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles(), this ); +#endif if ( iDebug ) { @@ -364,7 +382,12 @@ void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBase { if ( flChoice <= flRatio[i] ) { +#ifdef MAPBASE + CBaseEntity *pItem = CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this ); + m_OnItem.Set(pItem, pItem, this); +#else CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this ); +#endif if ( iDebug ) { @@ -546,6 +569,10 @@ bool CItem_DynamicResupply::SpawnItemFromRatio( int nCount, DynamicResupplyItems pEnt->SetAbsVelocity( GetAbsVelocity() ); pEnt->SetLocalAngularVelocity( GetLocalAngularVelocity() ); +#ifdef MAPBASE + m_OnItem.Set(pEnt, pEnt, this); +#endif + // Move the entity up so that it doesn't go below the spawn origin Vector vecWorldMins, vecWorldMaxs; pEnt->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs ); @@ -654,4 +681,9 @@ void DynamicResupply_InitFromAlternateMaster( CBaseEntity *pTargetEnt, string_t memcpy( pTargetResupply->m_flDesiredHealth, pMasterResupply->m_flDesiredHealth, sizeof( pMasterResupply->m_flDesiredHealth ) ); memcpy( pTargetResupply->m_flDesiredAmmo, pMasterResupply->m_flDesiredAmmo, sizeof( pMasterResupply->m_flDesiredAmmo ) ); +#ifdef MAPBASE + if (pMasterResupply->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL)) + pTargetResupply->AddSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL); +#endif + } \ No newline at end of file diff --git a/game/server/hl2/item_healthkit.cpp b/game/server/hl2/item_healthkit.cpp index fd3feec3..54f961c7 100644 --- a/game/server/hl2/item_healthkit.cpp +++ b/game/server/hl2/item_healthkit.cpp @@ -30,11 +30,29 @@ class CHealthKit : public CItem void Spawn( void ); void Precache( void ); bool MyTouch( CBasePlayer *pPlayer ); + +#ifdef MAPBASE + float GetItemAmount() { return sk_healthkit.GetFloat() * m_flHealthMultiplier; } + + void InputSetHealthMultiplier( inputdata_t &inputdata ) { m_flHealthMultiplier = inputdata.value.Float(); } + float m_flHealthMultiplier = 1.0f; + + DECLARE_DATADESC(); +#endif }; LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit ); PRECACHE_REGISTER(item_healthkit); +#ifdef MAPBASE +BEGIN_DATADESC( CHealthKit ) + + DEFINE_KEYFIELD( m_flHealthMultiplier, FIELD_FLOAT, "HealthMultiplier" ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthMultiplier", InputSetHealthMultiplier ), + +END_DATADESC() +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -55,10 +73,6 @@ void CHealthKit::Precache( void ) { PrecacheModel("models/items/healthkit.mdl"); -#ifdef VANCE - PrecacheScriptSound( "HealthKit.Touch_Suitless" ); -#endif - PrecacheScriptSound( "HealthKit.Touch" ); } @@ -70,7 +84,11 @@ void CHealthKit::Precache( void ) //----------------------------------------------------------------------------- bool CHealthKit::MyTouch( CBasePlayer *pPlayer ) { +#ifdef MAPBASE + if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) ) +#else if ( pPlayer->TakeHealth( sk_healthkit.GetFloat(), DMG_GENERIC ) ) +#endif { CSingleUserRecipientFilter user( pPlayer ); user.MakeReliable(); @@ -79,18 +97,10 @@ bool CHealthKit::MyTouch( CBasePlayer *pPlayer ) WRITE_STRING( GetClassname() ); MessageEnd(); - const char *szSoundToPlay = "HealthKit.Touch"; -#ifdef VANCE - if ( !pPlayer->IsSuitEquipped() ) - { - szSoundToPlay = "HealthKit.Touch_Suitless"; - } -#endif - - CPASAttenuationFilter filter( pPlayer, szSoundToPlay ); - EmitSound( filter, pPlayer->entindex(), szSoundToPlay ); + CPASAttenuationFilter filter( pPlayer, "HealthKit.Touch" ); + EmitSound( filter, pPlayer->entindex(), "HealthKit.Touch" ); - if ( g_pGameRules->ItemShouldRespawn( this ) ) + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) { Respawn(); } @@ -126,16 +136,16 @@ class CHealthVial : public CItem { PrecacheModel("models/healthvial.mdl"); -#ifdef VANCE - PrecacheScriptSound( "HealthVial.Touch_Suitless" ); -#endif - PrecacheScriptSound( "HealthVial.Touch" ); } bool MyTouch( CBasePlayer *pPlayer ) { +#ifdef MAPBASE + if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) ) +#else if ( pPlayer->TakeHealth( sk_healthvial.GetFloat(), DMG_GENERIC ) ) +#endif { CSingleUserRecipientFilter user( pPlayer ); user.MakeReliable(); @@ -144,18 +154,10 @@ class CHealthVial : public CItem WRITE_STRING( GetClassname() ); MessageEnd(); - const char *szSoundToPlay = "HealthKit.Touch"; -#ifdef VANCE - if ( !pPlayer->IsSuitEquipped() ) - { - szSoundToPlay = "HealthVial.Touch_Suitless"; - } -#endif - - CPASAttenuationFilter filter( pPlayer, szSoundToPlay ); - EmitSound( filter, pPlayer->entindex(), szSoundToPlay ); + CPASAttenuationFilter filter( pPlayer, "HealthVial.Touch" ); + EmitSound( filter, pPlayer->entindex(), "HealthVial.Touch" ); - if ( g_pGameRules->ItemShouldRespawn( this ) ) + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) { Respawn(); } @@ -169,11 +171,132 @@ class CHealthVial : public CItem return false; } + +#ifdef MAPBASE + float GetItemAmount() { return sk_healthvial.GetFloat() * m_flHealthMultiplier; } + + void InputSetHealthMultiplier( inputdata_t &inputdata ) { m_flHealthMultiplier = inputdata.value.Float(); } + float m_flHealthMultiplier = 1.0f; + + DECLARE_DATADESC(); +#endif }; LINK_ENTITY_TO_CLASS( item_healthvial, CHealthVial ); PRECACHE_REGISTER( item_healthvial ); +#ifdef MAPBASE +BEGIN_DATADESC( CHealthVial ) + + DEFINE_KEYFIELD( m_flHealthMultiplier, FIELD_FLOAT, "HealthMultiplier" ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthMultiplier", InputSetHealthMultiplier ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Small health kit. Heals the player when picked up. +//----------------------------------------------------------------------------- +class CHealthKitCustom : public CItem +{ +public: + DECLARE_CLASS( CHealthKitCustom, CItem ); + CHealthKitCustom(); + + void Spawn( void ); + void Precache( void ); + bool MyTouch( CBasePlayer *pPlayer ); + + float GetItemAmount() { return m_flHealthAmount; } + + void InputSetHealthAmount( inputdata_t &inputdata ) { m_flHealthAmount = inputdata.value.Float(); } + + float m_flHealthAmount; + string_t m_iszTouchSound; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( item_healthkit_custom, CHealthKitCustom ); +//PRECACHE_REGISTER(item_healthkit_custom); + +#ifdef MAPBASE +BEGIN_DATADESC( CHealthKitCustom ) + + DEFINE_KEYFIELD( m_flHealthAmount, FIELD_FLOAT, "HealthAmount" ), + DEFINE_KEYFIELD( m_iszTouchSound, FIELD_STRING, "TouchSound" ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthAmount", InputSetHealthAmount ), + +END_DATADESC() +#endif + + +CHealthKitCustom::CHealthKitCustom() +{ + SetModelName( AllocPooledString( "models/items/healthkit.mdl" ) ); + m_flHealthAmount = sk_healthkit.GetFloat(); + m_iszTouchSound = AllocPooledString( "HealthKit.Touch" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHealthKitCustom::Spawn( void ) +{ + Precache(); + SetModel( STRING( GetModelName() ) ); + + BaseClass::Spawn(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHealthKitCustom::Precache( void ) +{ + PrecacheModel( STRING( GetModelName() ) ); + + PrecacheScriptSound( STRING( m_iszTouchSound ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +// Output : +//----------------------------------------------------------------------------- +bool CHealthKitCustom::MyTouch( CBasePlayer *pPlayer ) +{ + if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) ) + { + CSingleUserRecipientFilter user( pPlayer ); + user.MakeReliable(); + + UserMessageBegin( user, "ItemPickup" ); + WRITE_STRING( GetClassname() ); + MessageEnd(); + + CPASAttenuationFilter filter( pPlayer, STRING( m_iszTouchSound ) ); + EmitSound( filter, pPlayer->entindex(), STRING( m_iszTouchSound ) ); + + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) + { + Respawn(); + } + else + { + UTIL_Remove(this); + } + + return true; + } + + return false; +} +#endif + //----------------------------------------------------------------------------- // Wall mounted health kit. Heals the player when used. //----------------------------------------------------------------------------- @@ -456,6 +579,17 @@ class CNewWallHealth : public CBaseAnimating void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | m_iCaps; } +#ifdef MAPBASE + void InputRecharge( inputdata_t &inputdata ); + void InputSetCharge( inputdata_t &inputdata ); + void InputSetChargeNoMax( inputdata_t &inputdata ); + void UpdateJuice( int newJuice ); + float MaxJuice() const; + void SetInitialCharge( void ); + int m_iMaxJuice; + int m_iIncrementValue; +#endif + float m_flNextCharge; int m_iReactivate ; // DeathMatch Delay until reactvated int m_iJuice; @@ -466,6 +600,11 @@ class CNewWallHealth : public CBaseAnimating int m_iCaps; COutputFloat m_OutRemainingHealth; +#ifdef MAPBASE + COutputEvent m_OnHalfEmpty; + COutputEvent m_OnEmpty; + COutputEvent m_OnFull; +#endif COutputEvent m_OnPlayerUse; void StudioFrameAdvance ( void ); @@ -482,12 +621,20 @@ BEGIN_DATADESC( CNewWallHealth ) DEFINE_FIELD( m_flNextCharge, FIELD_TIME), DEFINE_FIELD( m_iReactivate, FIELD_INTEGER), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iJuice, FIELD_INTEGER, "Charge" ), +#else DEFINE_FIELD( m_iJuice, FIELD_INTEGER), +#endif DEFINE_FIELD( m_iOn, FIELD_INTEGER), DEFINE_FIELD( m_flSoundTime, FIELD_TIME), DEFINE_FIELD( m_nState, FIELD_INTEGER ), DEFINE_FIELD( m_iCaps, FIELD_INTEGER ), DEFINE_FIELD( m_flJuice, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iMaxJuice, FIELD_INTEGER, "MaxCharge" ), + DEFINE_INPUT( m_iIncrementValue, FIELD_INTEGER, "SetIncrementValue" ), +#endif // Function Pointers DEFINE_FUNCTION( Off ), @@ -495,6 +642,15 @@ BEGIN_DATADESC( CNewWallHealth ) DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ), DEFINE_OUTPUT( m_OutRemainingHealth, "OutRemainingHealth"), +#ifdef MAPBASE + DEFINE_OUTPUT(m_OnHalfEmpty, "OnHalfEmpty" ), + DEFINE_OUTPUT(m_OnEmpty, "OnEmpty" ), + DEFINE_OUTPUT(m_OnFull, "OnFull" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCharge", InputSetCharge ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetChargeNoMax", InputSetChargeNoMax ), +#endif END_DATADESC() @@ -503,6 +659,10 @@ END_DATADESC() #define CHARGES_PER_SECOND 1.0f / CHARGE_RATE #define CALLS_PER_SECOND 7.0f * CHARGES_PER_SECOND +#ifdef MAPBASE +#define CUSTOM_CHARGES_PER_SECOND(inc) inc / CHARGE_RATE +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -527,6 +687,30 @@ bool CNewWallHealth::KeyValue( const char *szKeyName, const char *szValue ) return(BaseClass::KeyValue( szKeyName, szValue )); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNewWallHealth::SetInitialCharge( void ) +{ + if ( m_iMaxJuice != 0 ) + { + // It must've been overridden by the mapper + return; + } + + m_iMaxJuice = sk_healthcharger.GetFloat(); +} + +//----------------------------------------------------------------------------- +// Max juice for recharger +//----------------------------------------------------------------------------- +float CNewWallHealth::MaxJuice() const +{ + return m_iMaxJuice; +} +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -539,12 +723,34 @@ void CNewWallHealth::Spawn(void) SetSolid( SOLID_VPHYSICS ); CreateVPhysics(); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else SetModel( HEALTH_CHARGER_MODEL_NAME ); +#endif AddEffects( EF_NOSHADOW ); ResetSequence( LookupSequence( "idle" ) ); +#ifdef MAPBASE + if (m_iIncrementValue == 0) + m_iIncrementValue = 1; + + SetInitialCharge(); + + // In case the juice was overridden + if (m_iJuice == 0) + UpdateJuice( MaxJuice() ); + else if (m_iJuice == -1) + { + UpdateJuice( 0 ); + ResetSequence( LookupSequence( "empty" ) ); + } + else + UpdateJuice( m_iJuice ); +#else m_iJuice = sk_healthcharger.GetFloat(); +#endif m_nState = 0; @@ -554,7 +760,11 @@ void CNewWallHealth::Spawn(void) CreateVPhysics(); m_flJuice = m_iJuice; +#ifdef MAPBASE + SetCycle( 1.0f - ( m_flJuice / MaxJuice() ) ); +#else SetCycle( 1.0f - ( m_flJuice / sk_healthcharger.GetFloat() ) ); +#endif } int CNewWallHealth::DrawDebugTextOverlays(void) @@ -584,7 +794,14 @@ bool CNewWallHealth::CreateVPhysics(void) //----------------------------------------------------------------------------- void CNewWallHealth::Precache(void) { +#ifdef MAPBASE + if ( GetModelName() == NULL_STRING ) + SetModelName( AllocPooledString(HEALTH_CHARGER_MODEL_NAME) ); + + PrecacheModel( STRING(GetModelName()) ); +#else PrecacheModel( HEALTH_CHARGER_MODEL_NAME ); +#endif PrecacheScriptSound( "WallHealth.Deny" ); PrecacheScriptSound( "WallHealth.Start" ); @@ -596,7 +813,11 @@ void CNewWallHealth::StudioFrameAdvance( void ) { m_flPlaybackRate = 0; +#ifdef MAPBASE + float flMaxJuice = MaxJuice() + 0.1f; +#else float flMaxJuice = sk_healthcharger.GetFloat(); +#endif SetCycle( 1.0f - (float)( m_flJuice / flMaxJuice ) ); // Msg( "Cycle: %f - Juice: %d - m_flJuice :%f - Interval: %f\n", (float)GetCycle(), (int)m_iJuice, (float)m_flJuice, GetAnimTimeInterval() ); @@ -612,6 +833,62 @@ void CNewWallHealth::StudioFrameAdvance( void ) m_flAnimTime = gpGlobals->curtime; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : newJuice - +//----------------------------------------------------------------------------- +void CNewWallHealth::UpdateJuice( int newJuice ) +{ + bool reduced = newJuice < m_iJuice; + if ( reduced ) + { + // Fire 1/2 way output and/or empyt output + int oneHalfJuice = (int)(MaxJuice() * 0.5f); + if ( newJuice <= oneHalfJuice && m_iJuice > oneHalfJuice ) + { + m_OnHalfEmpty.FireOutput( this, this ); + } + + if ( newJuice <= 0 ) + { + m_OnEmpty.FireOutput( this, this ); + } + } + else if ( newJuice != m_iJuice && + newJuice == (int)MaxJuice() ) + { + m_OnFull.FireOutput( this, this ); + } + m_iJuice = newJuice; +} + +void CNewWallHealth::InputRecharge( inputdata_t &inputdata ) +{ + Recharge(); +} + +void CNewWallHealth::InputSetCharge( inputdata_t &inputdata ) +{ + int iJuice = inputdata.value.Int(); + + m_flJuice = m_iMaxJuice = m_iJuice = iJuice; + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); + StudioFrameAdvance(); +} + +void CNewWallHealth::InputSetChargeNoMax( inputdata_t &inputdata ) +{ + m_flJuice = inputdata.value.Float(); + + UpdateJuice(m_flJuice); + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); + StudioFrameAdvance(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : *pActivator - @@ -638,6 +915,11 @@ void CNewWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP float flCharges = CHARGES_PER_SECOND; float flCalls = CALLS_PER_SECOND; +#ifdef MAPBASE + if ( m_iIncrementValue != 0 ) + flCharges = CUSTOM_CHARGES_PER_SECOND(m_iIncrementValue); +#endif + m_flJuice -= flCharges / flCalls; StudioFrameAdvance(); } @@ -703,13 +985,24 @@ void CNewWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP } // charge the player +#ifdef MAPBASE + if ( pActivator->TakeHealth( m_iIncrementValue, DMG_GENERIC ) ) + { + UpdateJuice(m_iJuice - m_iIncrementValue); + } +#else if ( pActivator->TakeHealth( 1, DMG_GENERIC ) ) { m_iJuice--; } +#endif // Send the output. +#ifdef MAPBASE + float flRemaining = m_iJuice / MaxJuice(); +#else float flRemaining = m_iJuice / sk_healthcharger.GetFloat(); +#endif m_OutRemainingHealth.Set(flRemaining, pActivator, this); // govern the rate of charge @@ -723,7 +1016,12 @@ void CNewWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP void CNewWallHealth::Recharge(void) { EmitSound( "WallHealth.Recharge" ); +#ifdef MAPBASE + UpdateJuice(MaxJuice()); + m_flJuice = m_iJuice; +#else m_flJuice = m_iJuice = sk_healthcharger.GetFloat(); +#endif m_nState = 0; ResetSequence( LookupSequence( "idle" ) ); diff --git a/game/server/hl2/item_itemcrate.cpp b/game/server/hl2/item_itemcrate.cpp index 20ee2ff7..c1d47364 100644 --- a/game/server/hl2/item_itemcrate.cpp +++ b/game/server/hl2/item_itemcrate.cpp @@ -8,6 +8,9 @@ #include "props.h" #include "items.h" #include "item_dynamic_resupply.h" +#ifdef MAPBASE +#include "point_template.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -16,6 +19,9 @@ const char *pszItemCrateModelName[] = { "models/items/item_item_crate.mdl", "models/items/item_beacon_crate.mdl", +#ifdef MAPBASE + "models/items/item_item_crate.mdl", // Custom model placeholder/fallback, this should never be selected +#endif }; //----------------------------------------------------------------------------- @@ -39,14 +45,32 @@ class CItem_ItemCrate : public CPhysicsProp virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); +#ifdef MAPBASE + void InputSetContents( inputdata_t &data ); + void InputSetItemCount( inputdata_t &data ); + void InputMergeContentsWithPlayer( inputdata_t &data ); + + // Item crates always override prop data for custom models + bool OverridePropdata( void ) { return true; } +#endif + protected: virtual void OnBreak( const Vector &vecVelocity, const AngularImpulse &angVel, CBaseEntity *pBreaker ); +#ifdef MAPBASE + bool ShouldRandomizeAngles( CBaseEntity *pEnt ); + #define ITEM_ITEMCRATE_TEMPLATE_TARGET m_strAlternateMaster + CPointTemplate *FindTemplate(); +#endif + private: // Crate types. Add more! enum CrateType_t { CRATE_SPECIFIC_ITEM = 0, +#ifdef MAPBASE + CRATE_POINT_TEMPLATE, +#endif CRATE_TYPE_COUNT, }; @@ -54,6 +78,9 @@ class CItem_ItemCrate : public CPhysicsProp { CRATE_APPEARANCE_DEFAULT = 0, CRATE_APPEARANCE_RADAR_BEACON, +#ifdef MAPBASE + CRATE_APPEARANCE_CUSTOM, +#endif }; private: @@ -64,6 +91,9 @@ class CItem_ItemCrate : public CPhysicsProp CrateAppearance_t m_CrateAppearance; COutputEvent m_OnCacheInteraction; +#ifdef MAPBASE + COutputEHANDLE m_OnItem; +#endif }; @@ -82,6 +112,13 @@ BEGIN_DATADESC( CItem_ItemCrate ) DEFINE_KEYFIELD( m_CrateAppearance, FIELD_INTEGER, "CrateAppearance" ), DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ), DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnItem, "OnItem" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetContents", InputSetContents ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetItemCount", InputSetItemCount ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "MergeContentsWithPlayer", InputMergeContentsWithPlayer ), +#endif END_DATADESC() @@ -92,8 +129,17 @@ END_DATADESC() void CItem_ItemCrate::Precache( void ) { // Set this here to quiet base prop warnings +#ifdef MAPBASE + // Set our model name here instead of in Spawn() so we could use custom crates. + if (m_CrateAppearance != CRATE_APPEARANCE_CUSTOM) + SetModelName(AllocPooledString(pszItemCrateModelName[m_CrateAppearance])); + + PrecacheModel( STRING(GetModelName()) ); + SetModel( STRING(GetModelName()) ); +#else PrecacheModel( pszItemCrateModelName[m_CrateAppearance] ); SetModel( pszItemCrateModelName[m_CrateAppearance] ); +#endif BaseClass::Precache(); if ( m_CrateType == CRATE_SPECIFIC_ITEM ) @@ -118,7 +164,9 @@ void CItem_ItemCrate::Spawn( void ) } DisableAutoFade(); +#ifndef MAPBASE SetModelName( AllocPooledString( pszItemCrateModelName[m_CrateAppearance] ) ); +#endif if ( NULL_STRING == m_strItemClass ) { @@ -128,7 +176,11 @@ void CItem_ItemCrate::Spawn( void ) } Precache( ); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else SetModel( pszItemCrateModelName[m_CrateAppearance] ); +#endif AddEFlags( EFL_NO_ROTORWASH_PUSH ); BaseClass::Spawn( ); } @@ -140,9 +192,76 @@ void CItem_ItemCrate::Spawn( void ) //----------------------------------------------------------------------------- void CItem_ItemCrate::InputKill( inputdata_t &data ) { +#ifdef MAPBASE + // Why is this its own function anyway? + // It just overwrites the death notice stuff. + m_OnKilled.FireOutput(data.pActivator, this); +#endif + UTIL_Remove( this ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputSetContents( inputdata_t &data ) +{ + switch( m_CrateType ) + { + case CRATE_POINT_TEMPLATE: + ITEM_ITEMCRATE_TEMPLATE_TARGET = data.value.StringID(); + break; + + case CRATE_SPECIFIC_ITEM: + default: + m_strItemClass = data.value.StringID(); + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputSetItemCount( inputdata_t &data ) +{ + m_nItemCount = data.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputMergeContentsWithPlayer( inputdata_t &data ) +{ + CBasePlayer *pPlayer = ToBasePlayer(data.value.Entity()); + if (!pPlayer) + pPlayer = UTIL_GetLocalPlayer(); + + if (pPlayer) + { + switch( m_CrateType ) + { + case CRATE_POINT_TEMPLATE: + { + Warning( "%s: item_itemcrate MergeContentsWithPlayer is not supported on template crates yet!!!\n", GetDebugName() ); + } break; + + case CRATE_SPECIFIC_ITEM: + default: + { + for (int i = 0; i < m_nItemCount; i++) + { + pPlayer->GiveNamedItem( STRING( m_strItemClass ) ); + } + } break; + } + } +} +#endif + //----------------------------------------------------------------------------- // Item crates blow up immediately @@ -178,6 +297,34 @@ void CItem_ItemCrate::VPhysicsCollision( int index, gamevcollisionevent_t *pEven } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Finds the template for CRATE_POINT_TEMPLATE. +//----------------------------------------------------------------------------- +inline CPointTemplate *CItem_ItemCrate::FindTemplate() +{ + return dynamic_cast(gEntList.FindEntityByName( NULL, STRING(ITEM_ITEMCRATE_TEMPLATE_TARGET) )); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CItem_ItemCrate::ShouldRandomizeAngles( CBaseEntity *pEnt ) +{ + // Angles probably not supposed to be randomized. + if (m_CrateType == CRATE_POINT_TEMPLATE) + return false; + + // If we have only one NPC, it's probably supposed to spawn correctly. + // (if we have a bunch, it's probably a gag) + if (m_nItemCount == 1 && pEnt->IsNPC()) + return false; + + return true; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -189,7 +336,31 @@ void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse & m_OnCacheInteraction.FireOutput(pBreaker,this); +#ifdef MAPBASE + int iCount = m_nItemCount; + CUtlVector hNewEntities; + CPointTemplate *pTemplate = FindTemplate(); + + if (m_CrateType == CRATE_POINT_TEMPLATE) + { + if (pTemplate && pTemplate->CreateInstance(GetLocalOrigin(), GetLocalAngles(), &hNewEntities)) + { + iCount = hNewEntities.Count() * m_nItemCount; + } + else + { + // This only runs if our template can't be found or its template instancing didn't work. + Warning("item_item_crate %s with CRATE_POINT_TEMPLATE couldn't find point_template %s! Falling back to CRATE_SPECIFIC_ITEM...\n", GetDebugName(), STRING(ITEM_ITEMCRATE_TEMPLATE_TARGET)); + m_CrateType = CRATE_SPECIFIC_ITEM; + } + } +#endif + +#ifdef MAPBASE + for ( int i = 0; i < iCount; i++ ) +#else for ( int i = 0; i < m_nItemCount; ++i ) +#endif { CBaseEntity *pSpawn = NULL; switch( m_CrateType ) @@ -198,6 +369,25 @@ void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse & pSpawn = CreateEntityByName( STRING(m_strItemClass) ); break; +#ifdef MAPBASE + case CRATE_POINT_TEMPLATE: + { + if (i >= hNewEntities.Count()) + { + if (!pTemplate || !pTemplate->CreateInstance(GetLocalOrigin(), GetLocalAngles(), &hNewEntities)) + { + pSpawn = NULL; + i = iCount; + break; + } + + i = 0; + iCount -= hNewEntities.Count(); + } + pSpawn = hNewEntities[i]; + } break; +#endif + default: break; } @@ -205,6 +395,55 @@ void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse & if ( !pSpawn ) return; +#ifdef MAPBASE + Vector vecOrigin; + CollisionProp()->RandomPointInBounds(Vector(0.25, 0.25, 0.25), Vector(0.75, 0.75, 0.75), &vecOrigin); + pSpawn->SetAbsOrigin(vecOrigin); + + if (ShouldRandomizeAngles(pSpawn)) + { + // Give a little randomness... + QAngle vecAngles; + vecAngles.x = random->RandomFloat(-20.0f, 20.0f); + vecAngles.y = random->RandomFloat(0.0f, 360.0f); + vecAngles.z = random->RandomFloat(-20.0f, 20.0f); + pSpawn->SetAbsAngles(vecAngles); + + Vector vecActualVelocity; + vecActualVelocity.Random(-10.0f, 10.0f); + // vecActualVelocity += vecVelocity; + pSpawn->SetAbsVelocity(vecActualVelocity); + + QAngle angVel; + AngularImpulseToQAngle(angImpulse, angVel); + pSpawn->SetLocalAngularVelocity(angVel); + } + else + { + // Only modify the Y value. + QAngle vecAngles; + vecAngles.x = 0; + vecAngles.y = GetLocalAngles().y; + vecAngles.z = 0; + pSpawn->SetAbsAngles(vecAngles); + } + + // We handle dynamic resupplies differently + bool bDynResup = FClassnameIs( pSpawn, "item_dynamic_resupply" ); + if (!bDynResup) + m_OnItem.Set(pSpawn, pSpawn, this); + else if (m_OnItem.NumberOfElements() > 0) + { + // This is here so it could fire OnItem for each item + CEventAction *ourlist = m_OnItem.GetActionList(); + char outputdata[256]; + for (CEventAction *ev = ourlist; ev != NULL; ev = ev->m_pNext) + { + Q_snprintf(outputdata, sizeof(outputdata), "%s,%s,%s,%f,%i", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), STRING(ev->m_iParameter), ev->m_flDelay, ev->m_nTimesToFire); + pSpawn->KeyValue("OnItem", outputdata); + } + } +#else // Give a little randomness... Vector vecOrigin; CollisionProp()->RandomPointInBounds( Vector(0.25, 0.25, 0.25), Vector( 0.75, 0.75, 0.75 ), &vecOrigin ); @@ -224,6 +463,7 @@ void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse & QAngle angVel; AngularImpulseToQAngle( angImpulse, angVel ); pSpawn->SetLocalAngularVelocity( angVel ); +#endif // If we're creating an item, it can't be picked up until it comes to rest // But only if it wasn't broken by a vehicle @@ -236,7 +476,11 @@ void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse & pSpawn->Spawn(); // Avoid missing items drops by a dynamic resupply because they don't think immediately +#ifdef MAPBASE + if (bDynResup) +#else if ( FClassnameIs( pSpawn, "item_dynamic_resupply" ) ) +#endif { if ( m_strAlternateMaster != NULL_STRING ) { diff --git a/game/server/hl2/item_suit.cpp b/game/server/hl2/item_suit.cpp index 5441234f..67d327b9 100644 --- a/game/server/hl2/item_suit.cpp +++ b/game/server/hl2/item_suit.cpp @@ -49,7 +49,11 @@ class CItemSuit : public CItem else UTIL_EmitSoundSuit(pPlayer->edict(), "!HEV_AAx"); // long version of suit logon +#ifdef MAPBASE + pPlayer->EquipSuit(!HasSpawnFlags(SF_SUIT_SHORTLOGON)); +#else pPlayer->EquipSuit(); +#endif return true; } diff --git a/game/server/hl2/npc_BaseZombie.cpp b/game/server/hl2/npc_BaseZombie.cpp index e7e5c6fc..fee51dd7 100644 --- a/game/server/hl2/npc_BaseZombie.cpp +++ b/game/server/hl2/npc_BaseZombie.cpp @@ -205,7 +205,11 @@ BEGIN_DATADESC( CNPC_BaseZombie ) DEFINE_SOUNDPATCH( m_pMoanSound ), DEFINE_FIELD( m_fIsTorso, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_fIsHeadless, FIELD_BOOLEAN, "Headless" ), +#else DEFINE_FIELD( m_fIsHeadless, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_flNextFlinch, FIELD_TIME ), DEFINE_FIELD( m_bHeadShot, FIELD_BOOLEAN ), DEFINE_FIELD( m_flBurnDamage, FIELD_FLOAT ), @@ -220,6 +224,11 @@ BEGIN_DATADESC( CNPC_BaseZombie ) DEFINE_FIELD( m_hObstructor, FIELD_EHANDLE ), DEFINE_FIELD( m_bIsSlumped, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnSwattedProp, "OnSwattedProp" ), + DEFINE_OUTPUT( m_OnCrab, "OnCrab" ), +#endif + END_DATADESC() @@ -311,6 +320,12 @@ bool CNPC_BaseZombie::FindNearestPhysicsObject( int iMaxMass ) pEntity->VPhysicsGetObject()->IsAsleep() && pEntity->VPhysicsGetObject()->IsMoveable() ) { +#ifdef MAPBASE + // Don't swat props that don't want to be swatted + if (pEntity->HasSpawnFlags(SF_PHYSPROP_NO_ZOMBIE_SWAT) && dynamic_cast(pEntity)) + return ITERATION_CONTINUE; +#endif + return CFlaggedEntitiesEnum::EnumElement( pHandleEntity ); } return ITERATION_CONTINUE; @@ -716,6 +731,11 @@ bool CNPC_BaseZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDa if ( info.GetDamageType() & DMG_REMOVENORAGDOLL ) return false; +#ifdef MAPBASE + if ( HasSpawnFlags(SF_ZOMBIE_NO_TORSO) ) + return false; +#endif + if ( m_fIsTorso ) { // Already split. @@ -761,7 +781,11 @@ bool CNPC_BaseZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDa //----------------------------------------------------------------------------- HeadcrabRelease_t CNPC_BaseZombie::ShouldReleaseHeadcrab( const CTakeDamageInfo &info, float flDamageThreshold ) { +#ifdef MAPBASE + if ( m_iHealth <= 0 && !m_fIsHeadless ) +#else if ( m_iHealth <= 0 ) +#endif { if ( info.GetDamageType() & DMG_REMOVENORAGDOLL ) return RELEASE_NO; @@ -853,7 +877,11 @@ int CNPC_BaseZombie::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) bool bSquashed = IsSquashed(info); bool bKilledByVehicle = ( ( info.GetDamageType() & DMG_VEHICLE ) != 0 ); +#ifdef MAPBASE + if ( !m_fIsTorso && (bChopped || bSquashed) && !bKilledByVehicle && !(info.GetDamageType() & DMG_REMOVENORAGDOLL) && !HasSpawnFlags(SF_ZOMBIE_NO_TORSO) ) +#else if( !m_fIsTorso && (bChopped || bSquashed) && !bKilledByVehicle && !(info.GetDamageType() & DMG_REMOVENORAGDOLL) ) +#endif { if( bChopped ) { @@ -1062,6 +1090,10 @@ bool CNPC_BaseZombie::ShouldIgniteZombieGib( void ) #endif } +#ifdef MAPBASE +extern CBaseAnimating *CreateServerRagdollSubmodel( CBaseAnimating *pOwner, const char *pModelName, const Vector &position, const QAngle &angles, int collisionGroup ); +#endif + //----------------------------------------------------------------------------- // Purpose: Handle the special case of a zombie killed by a physics chopper. //----------------------------------------------------------------------------- @@ -1082,6 +1114,14 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info ) } } +#ifdef MAPBASE + // Hack for fast zombies using base torso rules. + if (m_iHealth > 0) + { + SetHealth( 0 ); + } +#endif + float flFadeTime = 0.0; if( HasSpawnFlags( SF_NPC_FADE_CORPSE ) ) @@ -1103,9 +1143,32 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info ) vecLegsForce.z *= -10; } +#ifdef MAPBASE + CBaseEntity *pLegGib = NULL; + if ( m_bForceServerRagdoll ) + { + pLegGib = CreateServerRagdollSubmodel( this, GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS ); + pLegGib->VPhysicsGetObject()->AddVelocity(&vecLegsForce, NULL); + if (ShouldIgniteZombieGib()) + static_cast(pLegGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false ); + + if ( flFadeTime > 0.0 ) + { + pLegGib->SUB_StartFadeOut( flFadeTime, false ); + } + } + else + pLegGib = CreateRagGib( GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() ); +#else CBaseEntity *pLegGib = CreateRagGib( GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() ); +#endif if ( pLegGib ) { +#ifdef MAPBASE + // Inherit some misc. properties + pLegGib->m_iViewHideFlags = m_iViewHideFlags; +#endif + CopyRenderColorTo( pLegGib ); } @@ -1122,15 +1185,42 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info ) QAngle TorsoAngles; TorsoAngles = GetAbsAngles(); TorsoAngles.x -= 90.0f; +#ifdef MAPBASE + CBaseEntity *pTorsoGib = NULL; + if ( m_bForceServerRagdoll ) + { + pTorsoGib = CreateServerRagdollSubmodel( this, GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, COLLISION_GROUP_INTERACTIVE_DEBRIS ); + pTorsoGib->VPhysicsGetObject()->AddVelocity(&forceVector, NULL); + if (ShouldIgniteZombieGib()) + static_cast(pLegGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false ); + + if ( flFadeTime > 0.0 ) + { + pTorsoGib->SUB_StartFadeOut( flFadeTime, false ); + } + } + else + pTorsoGib = CreateRagGib( GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, forceVector, flFadeTime, ShouldIgniteZombieGib() ); +#else CBaseEntity *pTorsoGib = CreateRagGib( GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, forceVector, flFadeTime, ShouldIgniteZombieGib() ); +#endif if ( pTorsoGib ) { CBaseAnimating *pAnimating = dynamic_cast(pTorsoGib); if( pAnimating ) { pAnimating->SetBodygroup( ZOMBIE_BODYGROUP_HEADCRAB, !m_fIsHeadless ); +#ifdef MAPBASE + // Inherit some animating properties + pAnimating->m_nSkin = m_nSkin; +#endif } +#ifdef MAPBASE + // Inherit some misc. properties + pTorsoGib->m_iViewHideFlags = m_iViewHideFlags; +#endif + pTorsoGib->SetOwnerEntity( this ); CopyRenderColorTo( pTorsoGib ); @@ -1559,6 +1649,10 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) pPhysObj->AddVelocity( &v, &angVelocity ); +#ifdef MAPBASE + m_OnSwattedProp.Set(pPhysicsEntity, pPhysicsEntity, this); +#endif + // If we don't put the object scan time well into the future, the zombie // will re-select the object he just hit as it is flying away from him. // It will likely always be the nearest object because the zombie moved @@ -1616,7 +1710,7 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) const char *pString = pEvent->options; char token[128]; - pString = nexttoken( token, pString, ' ' ); + pString = nexttoken( token, pString, ' ', sizeof(token) ); int boneIndex = GetInteractionPartner()->LookupBone( token ); @@ -1626,7 +1720,7 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) return; } - pString = nexttoken( token, pString, ' ' ); + pString = nexttoken( token, pString, ' ', sizeof( token ) ); if ( !token ) { @@ -2255,7 +2349,26 @@ void CNPC_BaseZombie::BecomeTorso( const Vector &vecTorsoForce, const Vector &ve if ( m_fIsTorso == true ) { // -40 on Z to make up for the +40 on Z that we did above. This stops legs spawning above the head. +#ifdef MAPBASE + CBaseEntity *pGib = NULL; + if ( m_bForceServerRagdoll ) + { + pGib = CreateServerRagdollSubmodel( this, GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS ); + if (pGib && pGib->VPhysicsGetObject()) + { + pGib->VPhysicsGetObject()->AddVelocity( &vecLegsForce, NULL ); + + if (flFadeTime > 0.0) + { + pGib->SUB_StartFadeOut( flFadeTime, false ); + } + } + } + else + pGib = CreateRagGib( GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), vecLegsForce, flFadeTime ); +#else CBaseEntity *pGib = CreateRagGib( GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), vecLegsForce, flFadeTime ); +#endif // don't collide with this thing ever if ( pGib ) @@ -2391,7 +2504,25 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve if( fRagdollCrab ) { //Vector vecForce = Vector( 0, 0, random->RandomFloat( 700, 1100 ) ); +#ifdef MAPBASE + CBaseEntity *pGib = NULL; + if ( m_bForceServerRagdoll ) + { + pGib = CreateServerRagdollSubmodel( this, GetHeadcrabModel(), vecOrigin, GetLocalAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS ); + if (pGib && pGib->VPhysicsGetObject()) + { + pGib->VPhysicsGetObject()->AddVelocity(&vecVelocity, NULL); + if (ShouldIgniteZombieGib()) + static_cast(pGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false ); + + pGib->SUB_StartFadeOut( 15, false ); + } + } + else + pGib = CreateRagGib( GetHeadcrabModel(), vecOrigin, GetLocalAngles(), vecVelocity, 15, ShouldIgniteZombieGib() ); +#else CBaseEntity *pGib = CreateRagGib( GetHeadcrabModel(), vecOrigin, GetLocalAngles(), vecVelocity, 15, ShouldIgniteZombieGib() ); +#endif if ( pGib ) { @@ -2410,6 +2541,11 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve return; } +#ifdef MAPBASE + // Inherit some misc. properties + pGib->m_iViewHideFlags = m_iViewHideFlags; +#endif + pGib->SetOwnerEntity( this ); CopyRenderColorTo( pGib ); @@ -2449,6 +2585,12 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve // add on the parent flags pCrab->AddSpawnFlags( m_spawnflags & ZOMBIE_CRAB_INHERITED_SPAWNFLAGS ); + +#ifdef MAPBASE + // Inherit some misc. properties + pCrab->m_bForceServerRagdoll = m_bForceServerRagdoll; + pCrab->m_iViewHideFlags = m_iViewHideFlags; +#endif // make me the crab's owner to avoid collision issues pCrab->SetOwnerEntity( this ); @@ -2502,6 +2644,10 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve CopyRenderColorTo( pCrab ); pCrab->Activate(); + +#ifdef MAPBASE + m_OnCrab.Set( pCrab, pCrab, this ); +#endif } if( fRemoveHead ) diff --git a/game/server/hl2/npc_BaseZombie.h b/game/server/hl2/npc_BaseZombie.h index d4800f3c..743186de 100644 --- a/game/server/hl2/npc_BaseZombie.h +++ b/game/server/hl2/npc_BaseZombie.h @@ -42,6 +42,10 @@ extern int AE_ZOMBIE_POUND; #define ZOMBIE_BLOOD_RIGHT_HAND 1 #define ZOMBIE_BLOOD_BOTH_HANDS 2 #define ZOMBIE_BLOOD_BITE 3 + +#ifdef MAPBASE +#define SF_ZOMBIE_NO_TORSO ( 1 << 15 ) +#endif enum HeadcrabRelease_t @@ -259,6 +263,10 @@ abstract_class CNPC_BaseZombie : public CAI_BaseZombieBase float m_flBurnDamageResetTime; // Time at which we reset the burn damage. EHANDLE m_hPhysicsEnt; +#ifdef MAPBASE + COutputEHANDLE m_OnSwattedProp; + COutputEHANDLE m_OnCrab; +#endif float m_flNextMoanSound; float m_flNextSwat; diff --git a/game/server/hl2/npc_PoisonZombie.cpp b/game/server/hl2/npc_PoisonZombie.cpp index eafebe2d..1611e15b 100644 --- a/game/server/hl2/npc_PoisonZombie.cpp +++ b/game/server/hl2/npc_PoisonZombie.cpp @@ -285,7 +285,11 @@ void CNPC_PoisonZombie::Spawn( void ) { Precache(); +#ifndef MAPBASE // Controlled by KV m_fIsTorso = m_fIsHeadless = false; +#else + m_fIsTorso = false; +#endif #ifdef HL2_EPISODIC SetBloodColor( BLOOD_COLOR_ZOMBIE ); @@ -632,10 +636,16 @@ void CNPC_PoisonZombie::BreatheOffShort( void ) { if ( m_bNearEnemy ) { +#ifdef MAPBASE + if (m_pFastBreathSound) +#endif ENVELOPE_CONTROLLER.SoundPlayEnvelope( m_pFastBreathSound, SOUNDCTRL_CHANGE_VOLUME, envPoisonZombieBreatheVolumeOffShort, ARRAYSIZE(envPoisonZombieBreatheVolumeOffShort) ); } else { +#ifdef MAPBASE + if (m_pSlowBreathSound) +#endif ENVELOPE_CONTROLLER.SoundPlayEnvelope( m_pSlowBreathSound, SOUNDCTRL_CHANGE_VOLUME, envPoisonZombieBreatheVolumeOffShort, ARRAYSIZE(envPoisonZombieBreatheVolumeOffShort) ); } } diff --git a/game/server/hl2/npc_alyx.cpp b/game/server/hl2/npc_alyx.cpp index f9dc1286..72b3f328 100644 --- a/game/server/hl2/npc_alyx.cpp +++ b/game/server/hl2/npc_alyx.cpp @@ -33,6 +33,10 @@ END_DATADESC() int AE_ALYX_EMPTOOL_ATTACHMENT; int AE_ALYX_EMPTOOL_SEQUENCE; +#ifdef MAPBASE +ConVar sk_alyx_health( "sk_alyx_health", "80" ); +#endif + //========================================================= // Classify - indicates this NPC's place in the // relationship table. @@ -127,7 +131,11 @@ void CNPC_Alyx::Spawn() AddEFlags( EFL_NO_DISSOLVE | EFL_NO_MEGAPHYSCANNON_RAGDOLL | EFL_NO_PHYSCANNON_INTERACTION ); +#ifdef MAPBASE + m_iHealth = sk_alyx_health.GetInt(); +#else m_iHealth = 80; +#endif NPCInit(); } diff --git a/game/server/hl2/npc_alyx.h b/game/server/hl2/npc_alyx.h index 96c1c917..266dca6d 100644 --- a/game/server/hl2/npc_alyx.h +++ b/game/server/hl2/npc_alyx.h @@ -31,6 +31,16 @@ class CNPC_Alyx : public CNPC_PlayerCompanion bool IsReadinessCapable() { return false; } void DeathSound( const CTakeDamageInfo &info ); +#ifdef MAPBASE + // Alyx was never meant to automatically unholster her weapon in non-episodic Half-Life 2. + // Now that all allies can holster/unholster, this is a precaution in case it breaks anything. + // Try OnFoundEnemy > UnholsterWeapon if you want Alyx to automatically unholster in non-episodic HL2 maps. + bool CanUnholsterWeapon() { return false; } + + // Use Alyx's default subtitle color (255,212,255) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 255; params.g1 = 212; params.b1 = 255; return BaseClass::GetGameTextSpeechParams( params ); } +#endif + EHANDLE m_hEmpTool; DECLARE_DATADESC(); diff --git a/game/server/hl2/npc_alyx_episodic.cpp b/game/server/hl2/npc_alyx_episodic.cpp index e98c89f5..c729e0bf 100644 --- a/game/server/hl2/npc_alyx_episodic.cpp +++ b/game/server/hl2/npc_alyx_episodic.cpp @@ -36,6 +36,9 @@ #include "ai_interactions.h" #include "weapon_flaregun.h" #include "env_debughistory.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#endif extern Vector PointOnLineNearestPoint(const Vector& vStartPos, const Vector& vEndPos, const Vector& vPoint); @@ -72,6 +75,10 @@ bool IsInCommentaryMode( void ); #define ALYX_MIN_ENEMY_HEALTH_TO_CROUCH 15 #define ALYX_CROUCH_DELAY 5 // Time after crouching before Alyx will crouch again +#ifdef MAPBASE +ConVar sk_alyx_health( "sk_alyx_health", "80" ); +#endif + //----------------------------------------------------------------------------- // Interactions //----------------------------------------------------------------------------- @@ -136,14 +143,23 @@ END_DATADESC() static int AE_ALYX_EMPTOOL_ATTACHMENT; static int AE_ALYX_EMPTOOL_SEQUENCE; static int AE_ALYX_EMPTOOL_USE; +#ifndef MAPBASE static int COMBINE_AE_BEGIN_ALTFIRE; static int COMBINE_AE_ALTFIRE; +#endif ConVar npc_alyx_readiness( "npc_alyx_readiness", "1" ); ConVar npc_alyx_force_stop_moving( "npc_alyx_force_stop_moving", "1" ); ConVar npc_alyx_readiness_transitions( "npc_alyx_readiness_transitions", "1" ); ConVar npc_alyx_crouch( "npc_alyx_crouch", "1" ); +#ifdef MAPBASE +ConVar npc_alyx_interact_manhacks( "npc_alyx_interact_manhacks", "1" ); +ConVar npc_alyx_interact_turrets( "npc_alyx_interact_turrets", "0" ); + +ConVar npc_alyx_allow_fly( "npc_alyx_allow_fly", "0", FCVAR_NONE, "Allows Alyx to use FL_FLY outside of scripted sequences, actbusy, or navigation." ); +#endif + // global pointer to Alyx for fast lookups CEntityClassList g_AlyxList; template <> CNPC_Alyx *CEntityClassList::m_pClassList = NULL; @@ -264,6 +280,7 @@ void CNPC_Alyx::HandleAnimEvent( animevent_t *pEvent ) } return; } +#ifndef MAPBASE else if ( pEvent->event == COMBINE_AE_BEGIN_ALTFIRE ) { EmitSound( "Weapon_CombineGuard.Special1" ); @@ -280,6 +297,7 @@ void CNPC_Alyx::HandleAnimEvent( animevent_t *pEvent ) return; } +#endif switch( pEvent->event ) { @@ -303,7 +321,9 @@ CNPC_Alyx *CNPC_Alyx::GetAlyx( void ) //========================================================= bool CNPC_Alyx::CreateBehaviors() { +#ifndef MAPBASE // Moved to CNPC_PlayerCompanion AddBehavior( &m_FuncTankBehavior ); +#endif bool result = BaseClass::CreateBehaviors(); return result; @@ -334,7 +354,11 @@ void CNPC_Alyx::Spawn() AddEFlags( EFL_NO_DISSOLVE | EFL_NO_MEGAPHYSCANNON_RAGDOLL | EFL_NO_PHYSCANNON_INTERACTION ); +#ifdef MAPBASE + m_iHealth = sk_alyx_health.GetInt(); +#else m_iHealth = 80; +#endif m_bloodColor = DONT_BLEED; NPCInit(); @@ -379,9 +403,15 @@ void CNPC_Alyx::Precache() UTIL_PrecacheOther( "env_alyxemp" ); CLASSNAME_ALYXGUN = AllocPooledString( "weapon_alyxgun" ); +#ifdef MAPBASE + CLASSNAME_SMG1 = gm_iszSMG1Classname; + CLASSNAME_SHOTGUN = gm_iszShotgunClassname; + CLASSNAME_AR2 = gm_iszAR2Classname; +#else CLASSNAME_SMG1 = AllocPooledString( "weapon_smg1" ); CLASSNAME_SHOTGUN = AllocPooledString( "weapon_shotgun" ); CLASSNAME_AR2 = AllocPooledString( "weapon_ar2" ); +#endif } //----------------------------------------------------------------------------- @@ -391,7 +421,15 @@ void CNPC_Alyx::Activate( void ) { // Alyx always kicks her health back up to full after loading a savegame. // Avoids problems with players saving the game in places where she dies immediately afterwards. +#ifdef MAPBASE + // Alyx's health can be >80 thanks to the new convar, and we don't want a 1000-health Alyx to reload + // from 1 health to 1000 health, so this should only kick in if her health is less than her default + // (we also probably don't want this to happen if she's not an ally) + if (IsPlayerAlly() && m_iHealth < 80) + m_iHealth = 80; +#else m_iHealth = 80; +#endif BaseClass::Activate(); @@ -426,6 +464,19 @@ void CNPC_Alyx::Activate( void ) { g_HackOutland10DamageHack = true; } + +#ifdef MAPBASE + // Please, this is not the worst hack you've caught me doing. + for ( int i = 0; i < m_ScriptedInteractions.Count(); i++ ) + { + ScriptedNPCInteraction_t *pInteraction = &m_ScriptedInteractions[i]; + + if (pInteraction->iszMyWeapon == CLASSNAME_ALYXGUN) + pInteraction->iszMyWeapon = AllocPooledString("WEPCLASS_HANDGUN"); + else if (pInteraction->iszMyWeapon == CLASSNAME_SHOTGUN) + pInteraction->iszMyWeapon = AllocPooledString("!=WEPCLASS_HANDGUN"); + } +#endif } //----------------------------------------------------------------------------- @@ -612,11 +663,13 @@ void CNPC_Alyx::PrescheduleThink( void ) } } +#ifndef MAPBASE // See CAI_BaseNPC // If Alyx is in combat, and she doesn't have her gun out, fetch it if ( GetState() == NPC_STATE_COMBAT && IsWeaponHolstered() && !m_FuncTankBehavior.IsRunning() ) { SetDesiredWeaponState( DESIREDWEAPONSTATE_UNHOLSTERED ); } +#endif // If we're in stealth mode, and we can still see the stealth node, keep using it if ( GetReadinessLevel() == AIRL_STEALTH ) @@ -759,11 +812,12 @@ void CNPC_Alyx::GatherConditions() } } - +#ifndef MAPBASE // Moved to CNPC_PlayerCompanion if ( m_NPCState == NPC_STATE_COMBAT ) { DoCustomCombatAI(); } +#endif if( HasInteractTarget() ) { @@ -835,7 +889,11 @@ void CNPC_Alyx::GatherConditions() // ROBIN: This was here to solve a problem in a playtest. We've since found what we think was the cause. // It's a useful piece of debug to have lying there, so I've left it in. - if ( (GetFlags() & FL_FLY) && m_NPCState != NPC_STATE_SCRIPT && !m_ActBusyBehavior.IsActive() && !m_PassengerBehavior.IsEnabled() ) + if ( (GetFlags() & FL_FLY) && m_NPCState != NPC_STATE_SCRIPT && !m_ActBusyBehavior.IsActive() && !m_PassengerBehavior.IsEnabled() +#ifdef MAPBASE + && GetNavType() != NAV_CLIMB && !npc_alyx_allow_fly.GetBool() +#endif + ) { Warning( "Removed FL_FLY from Alyx, who wasn't running a script or actbusy. Time %.2f, map %s.\n", gpGlobals->curtime, STRING(gpGlobals->mapname) ); RemoveFlag( FL_FLY ); @@ -928,7 +986,12 @@ bool CNPC_Alyx::IsValidEnemy( CBaseEntity *pEnemy ) return false; } +#ifdef MAPBASE + // Come to the defense of anyone we like, not just ourselves or the player. + if( pEnemy->GetEnemy() != this && IRelationType(pEnemy->GetEnemy()) == D_LI ) +#else if( pEnemy->GetEnemy() != this && !pEnemy->GetEnemy()->IsPlayer() ) +#endif { return false; } @@ -991,7 +1054,12 @@ void CNPC_Alyx::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo & return; } +#ifdef MAPBASE + // Don't do the custom target thing against dissolve or blast damage (Alyx can do that with companion grenades/balls) + if( !HasShotgun() && !(info.GetDamageType() & (DMG_DISSOLVE | DMG_BLAST)) ) +#else if( !HasShotgun() ) +#endif { CAI_BaseNPC *pTarget = CreateCustomTarget( pVictim->GetAbsOrigin(), 2.0f ); @@ -1009,6 +1077,13 @@ void CNPC_Alyx::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo & pMemory->timeFirstSeen = gpGlobals->curtime - 10.0f; } } + +#ifdef MAPBASE + // This call has a side effect of causing Alyx to speak a regular companion TLK_ENEMY_DEAD, which may conflict with the TLK_ALYX_ENEMY_DEAD + // further up, but this is fine because concepts are protected against interrupting each other and Alyx may even be overridden + // to use TLK_ENEMY_DEAD instead, which is used by other NPCs and appends more modifiers. + BaseClass::Event_KilledOther( pVictim, info ); +#endif } //----------------------------------------------------------------------------- @@ -1426,9 +1501,9 @@ void CNPC_Alyx::DoCustomSpeechAI( void ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CNPC_Alyx::SpeakIfAllowed( AIConcept_t concept, const char *modifiers /*= NULL*/, bool bRespondingToPlayer /*= false*/, char *pszOutResponseChosen /*= NULL*/, size_t bufsize /* = 0 */ ) +bool CNPC_Alyx::SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers /*= NULL*/, bool bRespondingToPlayer /*= false*/, char *pszOutResponseChosen /*= NULL*/, size_t bufsize /* = 0 */ ) { - if ( BaseClass::SpeakIfAllowed( concept, modifiers, bRespondingToPlayer, pszOutResponseChosen, bufsize ) ) + if ( BaseClass::SpeakIfAllowed( conceptId, modifiers, bRespondingToPlayer, pszOutResponseChosen, bufsize ) ) { // If we're breathing in the darkness, drop the volume quickly if ( m_sndDarknessBreathing && CSoundEnvelopeController::GetController().SoundGetVolume( m_sndDarknessBreathing ) > 0.0 ) @@ -1620,9 +1695,88 @@ Activity CNPC_Alyx::NPC_TranslateActivity( Activity activity ) case ACT_DROP_WEAPON: if ( HasShotgun() ) return (Activity)ACT_DROP_WEAPON_SHOTGUN; } +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Alyx has her own pistol readiness animations which use the default activities + switch (activity) + { + case ACT_IDLE_PISTOL_RELAXED: + return ACT_IDLE_RELAXED; + case ACT_IDLE_PISTOL_STIMULATED: + return ACT_IDLE_STIMULATED; + case ACT_WALK_PISTOL_RELAXED: + return ACT_WALK; + case ACT_WALK_PISTOL_STIMULATED: + return ACT_WALK_PISTOL; + case ACT_RUN_PISTOL_RELAXED: + return ACT_RUN; + case ACT_RUN_PISTOL_STIMULATED: + return ACT_RUN_PISTOL; + } +#endif + return activity; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CNPC_Alyx::Weapon_TranslateActivity( Activity activity, bool *pRequired ) +{ + activity = BaseClass::Weapon_TranslateActivity( activity, pRequired ); + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Alyx has her own pistol readiness animations which use the default activities + switch (activity) + { + case ACT_IDLE_PISTOL_RELAXED: + return ACT_IDLE_RELAXED; + case ACT_IDLE_PISTOL_STIMULATED: + return ACT_IDLE_STIMULATED; + case ACT_WALK_PISTOL_RELAXED: + return ACT_WALK; + case ACT_WALK_PISTOL_STIMULATED: + return ACT_WALK_PISTOL; + case ACT_RUN_PISTOL_RELAXED: + return ACT_RUN; + case ACT_RUN_PISTOL_STIMULATED: + return ACT_RUN_PISTOL; + } +#endif + + return activity; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CNPC_Alyx::Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pSpecificWeapon ) +{ + activity = BaseClass::Weapon_BackupActivity( activity, weaponTranslationWasRequired, pSpecificWeapon ); + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Alyx has her own pistol readiness animations which use the default activities + switch (activity) + { + case ACT_IDLE_PISTOL_RELAXED: + return ACT_IDLE_RELAXED; + case ACT_IDLE_PISTOL_STIMULATED: + return ACT_IDLE_STIMULATED; + case ACT_WALK_PISTOL_RELAXED: + return ACT_WALK; + case ACT_WALK_PISTOL_STIMULATED: + return ACT_WALK_PISTOL; + case ACT_RUN_PISTOL_RELAXED: + return ACT_RUN; + case ACT_RUN_PISTOL_STIMULATED: + return ACT_RUN_PISTOL; + } +#endif + + return activity; +} +#endif + bool CNPC_Alyx::ShouldDeferToFollowBehavior() { return BaseClass::ShouldDeferToFollowBehavior(); @@ -1849,6 +2003,29 @@ int CNPC_Alyx::TranslateSchedule( int scheduleType ) //Warning("CROUCH: Standing, no enemy.\n" ); Stand(); } + +#ifdef MAPBASE + // This stuff was ported from npc_playercompanion to help Alyx use grenades. + if (HasGrenades() && !IsCrouching()) + { + if (CanAltFireEnemy( true ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK )) + { + return SCHED_PC_AR2_ALTFIRE; + } + + if ( !OccupyStrategySlotRange( SQUAD_SLOT_ATTACK1, SQUAD_SLOT_ATTACK2 ) ) + { + // Try throwing a grenade if Alyx is in a squad that already has attacking well in hand. + if ( CanGrenadeEnemy() ) + { + if ( OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_RANGE_ATTACK2; + } + } + } + } +#endif } return SCHED_ALYX_RANGE_ATTACK1; @@ -2941,7 +3118,12 @@ bool CNPC_Alyx::Crouch( void ) return false; // Alyx will ignore crouch requests while she has the shotgun +#ifdef MAPBASE + // Alyx will ignore crouch requests from anything that isn't a "pistol", e.g. her Alyx gun. + if ( GetActiveWeapon() && GetActiveWeapon()->WeaponClassify() != WEPCLASS_HANDGUN ) +#else if ( HasShotgun() ) +#endif return false; bool bWasStanding = !IsCrouching(); @@ -2974,9 +3156,13 @@ void CNPC_Alyx::DesireCrouch( void ) //----------------------------------------------------------------------------- void CNPC_Alyx::ModifyOrAppendCriteria( AI_CriteriaSet &set ) { +#ifdef MAPBASE + float fLengthOfLastCombat; +#else AIEnemiesIter_t iter; float fLengthOfLastCombat; int iNumEnemies; +#endif if ( GetState() == NPC_STATE_COMBAT ) { @@ -2989,6 +3175,7 @@ void CNPC_Alyx::ModifyOrAppendCriteria( AI_CriteriaSet &set ) set.AppendCriteria( "combat_length", UTIL_VarArgs( "%.3f", fLengthOfLastCombat ) ); +#ifndef MAPBASE // Moved to CNPC_PlayerCompanion iNumEnemies = 0; for ( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) ) { @@ -2998,6 +3185,7 @@ void CNPC_Alyx::ModifyOrAppendCriteria( AI_CriteriaSet &set ) } } set.AppendCriteria( "num_enemies", UTIL_VarArgs( "%d", iNumEnemies ) ); +#endif set.AppendCriteria( "darkness_mode", UTIL_VarArgs( "%d", HasCondition( COND_ALYX_IN_DARK ) ) ); set.AppendCriteria( "water_level", UTIL_VarArgs( "%d", GetWaterLevel() ) ); @@ -3149,7 +3337,12 @@ bool CNPC_Alyx::PlayerInSpread( const Vector &sourcePos, const Vector &targetPos { CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); +#ifdef MAPBASE + // "> D_FR" means it isn't D_HT, D_FR, or D_ER (error disposition) + if ( pPlayer && ( !ignoreHatedPlayers || IRelationType( pPlayer ) > D_FR ) && !(pPlayer->GetFlags() & FL_NOTARGET) ) +#else if ( pPlayer && ( !ignoreHatedPlayers || IRelationType( pPlayer ) != D_HT ) ) +#endif { //If the player is being lifted by a barnacle then go ahead and ignore the player and shoot. #ifdef HL2_EPISODIC @@ -3324,8 +3517,10 @@ AI_BEGIN_CUSTOM_NPC( npc_alyx, CNPC_Alyx ) DECLARE_ANIMEVENT( AE_ALYX_EMPTOOL_ATTACHMENT ) DECLARE_ANIMEVENT( AE_ALYX_EMPTOOL_SEQUENCE ) DECLARE_ANIMEVENT( AE_ALYX_EMPTOOL_USE ) +#ifndef MAPBASE DECLARE_ANIMEVENT( COMBINE_AE_BEGIN_ALTFIRE ) DECLARE_ANIMEVENT( COMBINE_AE_ALTFIRE ) +#endif DECLARE_CONDITION( COND_ALYX_HAS_INTERACT_TARGET ) DECLARE_CONDITION( COND_ALYX_NO_INTERACT_TARGET ) diff --git a/game/server/hl2/npc_alyx_episodic.h b/game/server/hl2/npc_alyx_episodic.h index 5657dae7..8654bb42 100644 --- a/game/server/hl2/npc_alyx_episodic.h +++ b/game/server/hl2/npc_alyx_episodic.h @@ -54,6 +54,14 @@ class CNPC_Alyx : public CNPC_PlayerCompanion bool OnBeginMoveAndShoot(); void SpeakAttacking( void ); +#ifdef MAPBASE + // This skips CAI_PlayerAlly's CanFlinch() function since Episodic Alyx can flinch to begin with. + virtual bool CanFlinch( void ) { return CAI_BaseActor::CanFlinch(); } + + // Use Alyx's default subtitle color (255,212,255) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 255; params.g1 = 212; params.b1 = 255; return BaseClass::GetGameTextSpeechParams( params ); } +#endif + virtual float GetJumpGravity() const { return 1.8f; } // Crouching @@ -83,6 +91,10 @@ class CNPC_Alyx : public CNPC_PlayerCompanion bool CanSeeEntityInDarkness( CBaseEntity *pEntity ); bool IsCoverPosition( const Vector &vecThreat, const Vector &vecPosition ); Activity NPC_TranslateActivity ( Activity activity ); +#ifdef MAPBASE + Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL ); + Activity Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired = false, CBaseCombatWeapon *pSpecificWeapon = NULL ); +#endif bool ShouldDeferToFollowBehavior(); void BuildScheduleTestBits(); bool ShouldBehaviorSelectSchedule( CAI_BehaviorBase *pBehavior ); @@ -103,7 +115,7 @@ class CNPC_Alyx : public CNPC_PlayerCompanion bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt); - virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); + virtual bool SpeakIfAllowed( AIConcept_t conceptId, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); void HolsterPistol(); void DrawPistol(); @@ -223,7 +235,9 @@ class CNPC_Alyx : public CNPC_PlayerCompanion bool m_bShouldHaveEMP; +#ifndef MAPBASE // Moved to CNPC_PlayerCompanion CAI_FuncTankBehavior m_FuncTankBehavior; +#endif COutputEvent m_OnFinishInteractWithObject; COutputEvent m_OnPlayerUse; diff --git a/game/server/hl2/npc_antlion.cpp b/game/server/hl2/npc_antlion.cpp index 8cb7f789..2d59c9a0 100644 --- a/game/server/hl2/npc_antlion.cpp +++ b/game/server/hl2/npc_antlion.cpp @@ -65,6 +65,9 @@ ConVar sk_antlion_worker_burst_radius( "sk_antlion_worker_burst_radius", "160", ConVar g_test_new_antlion_jump( "g_test_new_antlion_jump", "1", FCVAR_ARCHIVE ); ConVar antlion_easycrush( "antlion_easycrush", "1" ); +#ifdef MAPBASE +ConVar antlion_no_ignite_die( "antlion_no_ignite_die", "0" ); +#endif ConVar g_antlion_cascade_push( "g_antlion_cascade_push", "1", FCVAR_ARCHIVE ); ConVar g_debug_antlion_worker( "g_debug_antlion_worker", "0" ); @@ -247,6 +250,9 @@ BEGIN_DATADESC( CNPC_Antlion ) DEFINE_INPUTFUNC( FIELD_VOID, "IgnoreBugbait", InputIgnoreBugbait ), DEFINE_INPUTFUNC( FIELD_VOID, "HearBugbait", InputHearBugbait ), DEFINE_INPUTFUNC( FIELD_STRING, "JumpAtTarget", InputJumpAtTarget ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetFollowTarget", InputSetFollowTarget ), +#endif DEFINE_OUTPUT( m_OnReachFightGoal, "OnReachedFightGoal" ), DEFINE_OUTPUT( m_OnUnBurrowed, "OnUnBurrowed" ), @@ -274,17 +280,17 @@ void CNPC_Antlion::Spawn( void ) #ifdef HL2_EPISODIC if ( IsWorker() ) { - SetModel( ANTLION_WORKER_MODEL ); + SetModel( DefaultOrCustomModel(ANTLION_WORKER_MODEL) ); AddSpawnFlags( SF_NPC_LONG_RANGE ); SetBloodColor( BLOOD_COLOR_ANTLION_WORKER ); } else { - SetModel( ANTLION_MODEL ); + SetModel( DefaultOrCustomModel(ANTLION_MODEL) ); SetBloodColor( BLOOD_COLOR_ANTLION ); } #else - SetModel( ANTLION_MODEL ); + SetModel( DefaultOrCustomModel(ANTLION_MODEL) ); SetBloodColor( BLOOD_COLOR_YELLOW ); #endif // HL2_EPISODIC @@ -361,6 +367,43 @@ void CNPC_Antlion::Spawn( void ) BaseClass::Spawn(); m_nSkin = random->RandomInt( 0, ANTLION_SKIN_COUNT-1 ); + +#if defined(MAPBASE) && defined(HL2_EPISODIC) + // Implement dynamic interactions here since we can't recompile the model + if (GetModelPtr()) + { + ScriptedNPCInteraction_t sInteraction01; + sInteraction01.iszInteractionName = AllocPooledString( "antlion_v_soldier_01" ); + sInteraction01.sPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString( "antlion_soldier_DI_01" ); + + sInteraction01.vecRelativeOrigin = Vector(224, 0, 0); + sInteraction01.angRelativeAngles = QAngle(0, 180, 0); + //sInteraction01.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES; + sInteraction01.iFlags |= SCNPC_FLAG_TEST_END_POSITION; + sInteraction01.vecRelativeEndPos = Vector(312, -10, 0); + sInteraction01.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT; + sInteraction01.flDelay = 15.0f; + sInteraction01.iFlags |= SCNPC_FLAG_MAPBASE_ADDITION; + sInteraction01.flDistSqr = (8 * 8); + + + ScriptedNPCInteraction_t sInteraction02; + sInteraction02.iszInteractionName = AllocPooledString( "antlion_v_soldier_02" ); + sInteraction02.sPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString( "antlion_soldier_DI_02" ); + + sInteraction02.vecRelativeOrigin = Vector(64, 0, 0); + sInteraction02.angRelativeAngles = QAngle(0, 180, 0); + //sInteraction01.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES; + sInteraction02.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT; + sInteraction02.flDelay = 7.5f; + sInteraction02.iFlags |= SCNPC_FLAG_MAPBASE_ADDITION; + sInteraction02.flDistSqr = (8 * 8); + + + AddScriptedNPCInteraction(&sInteraction01); + AddScriptedNPCInteraction(&sInteraction02); + } +#endif } //----------------------------------------------------------------------------- @@ -657,7 +700,11 @@ void CNPC_Antlion::MeleeAttack( float distance, float damage, QAngle &viewPunch, vecForceDir = ( pHurt->WorldSpaceCenter() - WorldSpaceCenter() ); //FIXME: Until the interaction is setup, kill combine soldiers in one hit -- jdw +#ifdef MAPBASE + if ( pHurt->Classify() == CLASS_COMBINE && FClassnameIs( pHurt, "npc_combine_s" ) && GlobalEntity_GetState("antlion_noinstakill") != GLOBAL_ON ) +#else if ( FClassnameIs( pHurt, "npc_combine_s" ) ) +#endif { CTakeDamageInfo dmgInfo( this, this, pHurt->m_iHealth+25, DMG_SLASH ); CalculateMeleeDamageForce( &dmgInfo, vecForceDir, pHurt->GetAbsOrigin() ); @@ -2465,6 +2512,38 @@ int CNPC_Antlion::SelectSchedule( void ) return SCHED_ANTLION_WORKER_RANGE_ATTACK1; } } + +#ifdef MAPBASE + // "Nemesis" is assigned to enemies we hate with 10+ priority. + // Since bugbait targets are given 99 priority, this means the AI here usually only applies + // when the antlion worker is following bugbait. + // + // This is just so antlion workers are more potent when commanded by bugbait, + // which wasn't explored in the official games, but may be used in HL2 mods. + if ( m_hFollowTarget && IsAllied() /*HasCondition( COND_SEE_NEMESIS )*/ ) + { + // Establish LOF if we can't see the enemy + if ( HasCondition( COND_ENEMY_OCCLUDED ) ) + return SCHED_ESTABLISH_LINE_OF_FIRE; + + // See if we need to destroy breakable cover + if ( HasCondition( COND_WEAPON_SIGHT_OCCLUDED ) ) + return SCHED_SHOOT_ENEMY_COVER; + + // Just face as usual if we're not too close to attack, + // otherwise fall back to base class and charge like any other antlion + if ( !HasCondition( COND_TOO_CLOSE_TO_ATTACK ) ) + { + // Run around randomly if our target is looking in our direction + if ( HasCondition( COND_BEHIND_ENEMY ) == false ) + return SCHED_ANTLION_WORKER_RUN_RANDOM; + + return SCHED_COMBAT_FACE; + } + } + else + { +#endif // Back up, we're too near an enemy or can't see them if ( HasCondition( COND_TOO_CLOSE_TO_ATTACK ) || HasCondition( COND_ENEMY_OCCLUDED ) ) @@ -2480,6 +2559,9 @@ int CNPC_Antlion::SelectSchedule( void ) // Face our target and continue to fire return SCHED_COMBAT_FACE; +#ifdef MAPBASE + } +#endif } else { @@ -2544,6 +2626,15 @@ int CNPC_Antlion::SelectSchedule( void ) void CNPC_Antlion::Ignite ( float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner ) { #ifdef HL2_EPISODIC + +#ifdef MAPBASE + if (antlion_no_ignite_die.GetBool()) + { + BaseClass::Ignite(flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner); + return; + } +#endif + float flDamage = m_iHealth + 1; CTakeDamageInfo dmgInfo( this, this, flDamage, DMG_GENERIC ); @@ -2887,7 +2978,11 @@ int CNPC_Antlion::MeleeAttack1Conditions( float flDot, float flDist ) AI_TraceHull( WorldSpaceCenter(), GetEnemy()->WorldSpaceCenter(), -Vector(8,8,8), Vector(8,8,8), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &tr ); // If the hit entity isn't our target and we don't hate it, don't hit it +#ifdef MAPBASE + if ( tr.m_pEnt != GetEnemy() && tr.fraction < 1.0f && IRelationType( tr.m_pEnt ) > D_FR ) +#else if ( tr.m_pEnt != GetEnemy() && tr.fraction < 1.0f && IRelationType( tr.m_pEnt ) != D_HT ) +#endif return 0; #else @@ -4224,6 +4319,25 @@ void CNPC_Antlion::SetFollowTarget( CBaseEntity *pTarget ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_Antlion::InputSetFollowTarget( inputdata_t &inputdata ) +{ + if ( IsAlive() == false ) + return; + + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), NULL, inputdata.pActivator, inputdata.pCaller ); + + if ( pEntity != NULL ) + { + SetFollowTarget( pEntity ); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. @@ -4438,7 +4552,15 @@ bool CNPC_Antlion::IsHeavyDamage( const CTakeDamageInfo &info ) bool CNPC_Antlion::CanRunAScriptedNPCInteraction( bool bForced /*= false*/ ) { // Workers shouldn't do DSS's because they explode +#ifdef MAPBASE + // Now that antlions have their DI restored, one might want workers to use them as well. + // Forced interactions are allowed now, but I went a step further and enabling dynamic interactions + // will disregard this check. This will allow vortigaunts to use dangerous melee interactions with workers, + // but if you're concerned about that just turn the antlion's interactions off. + if ( IsWorker() && !bForced && m_iDynamicInteractionsAllowed != TRS_TRUE ) +#else if ( IsWorker() ) +#endif return false; return BaseClass::CanRunAScriptedNPCInteraction( bForced ); diff --git a/game/server/hl2/npc_antlion.h b/game/server/hl2/npc_antlion.h index 1de36066..dd26ec2a 100644 --- a/game/server/hl2/npc_antlion.h +++ b/game/server/hl2/npc_antlion.h @@ -143,6 +143,9 @@ class CNPC_Antlion : public CAI_BaseAntlionBase void InputJumpAtTarget( inputdata_t &inputdata ); void SetFollowTarget( CBaseEntity *pTarget ); +#ifdef MAPBASE + void InputSetFollowTarget( inputdata_t &inputdata ); +#endif int TranslateSchedule( int scheduleType ); virtual Activity NPC_TranslateActivity( Activity baseAct ); diff --git a/game/server/hl2/npc_antliongrub.cpp b/game/server/hl2/npc_antliongrub.cpp index 16ee2ed5..07444e9a 100644 --- a/game/server/hl2/npc_antliongrub.cpp +++ b/game/server/hl2/npc_antliongrub.cpp @@ -15,6 +15,9 @@ #include "items.h" #include "item_dynamic_resupply.h" #include "npc_vortigaunt_episodic.h" +#ifdef MAPBASE +#include "filters.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -659,6 +662,16 @@ void CAntlionGrub::GrubTouch( CBaseEntity *pOther ) IPhysicsObject *pPhysOther = pOther->VPhysicsGetObject(); // bool bThrown = ( pTarget->VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_WAS_THROWN ) != 0; if ( pOther->IsPlayer() || FClassnameIs(pOther,"npc_vortigaunt") || ( pPhysOther && (pPhysOther->GetGameFlags() & FVPHYSICS_WAS_THROWN )) ) { +#ifdef MAPBASE + if (m_hDamageFilter) + { + // Don't squash if they don't pass our damage filter + CBaseFilter *pFilter = static_cast(m_hDamageFilter.Get()); + if (pFilter && !pFilter->PassesFilter(this, pOther)) + return; + } +#endif + m_OnAgitated.FireOutput( pOther, pOther ); Squash( pOther, true, true ); } @@ -844,6 +857,13 @@ void CGrubNugget::Spawn( void ) { Precache(); +#ifdef MAPBASE + if ( GetModelName() != NULL_STRING ) + { + SetModel( STRING(GetModelName()) ); + } + else +#endif if ( m_nDenomination == NUGGET_LARGE ) { SetModel( "models/grub_nugget_large.mdl" ); @@ -875,6 +895,10 @@ void CGrubNugget::Precache( void ) PrecacheModel("models/grub_nugget_small.mdl"); PrecacheModel("models/grub_nugget_medium.mdl"); PrecacheModel("models/grub_nugget_large.mdl"); +#ifdef MAPBASE + if (GetModelName() != NULL_STRING) + PrecacheModel( STRING(GetModelName()) ); +#endif PrecacheScriptSound( "GrubNugget.Touch" ); PrecacheScriptSound( "NPC_Antlion_Grub.Explode" ); diff --git a/game/server/hl2/npc_antlionguard.cpp b/game/server/hl2/npc_antlionguard.cpp index 9ed2eff4..57592617 100644 --- a/game/server/hl2/npc_antlionguard.cpp +++ b/game/server/hl2/npc_antlionguard.cpp @@ -190,6 +190,17 @@ Activity ACT_ANTLIONGUARD_CHARGE_STOP; Activity ACT_ANTLIONGUARD_CHARGE_HIT; Activity ACT_ANTLIONGUARD_CHARGE_ANTICIPATION; +#ifdef MAPBASE +// Unused activities +Activity ACT_ANTLIONGUARD_COVER_ENTER; +Activity ACT_ANTLIONGUARD_COVER_LOOP; +Activity ACT_ANTLIONGUARD_COVER_EXIT; +Activity ACT_ANTLIONGUARD_COVER_ADVANCE; +Activity ACT_ANTLIONGUARD_COVER_FLINCH; +Activity ACT_ANTLIONGUARD_SNEAK; +Activity ACT_ANTLIONGUARD_RUN_FULL; +#endif + // Anim events int AE_ANTLIONGUARD_CHARGE_HIT; int AE_ANTLIONGUARD_SHOVE_PHYSOBJECT; @@ -667,7 +678,7 @@ void CNPC_AntlionGuard::UpdateOnRemove( void ) //----------------------------------------------------------------------------- void CNPC_AntlionGuard::Precache( void ) { - PrecacheModel( ANTLIONGUARD_MODEL ); + PrecacheModel( DefaultOrCustomModel( ANTLIONGUARD_MODEL ) ); PrecacheScriptSound( "NPC_AntlionGuard.Shove" ); PrecacheScriptSound( "NPC_AntlionGuard.HitHard" ); @@ -768,7 +779,7 @@ void CNPC_AntlionGuard::Spawn( void ) { Precache(); - SetModel( ANTLIONGUARD_MODEL ); + SetModel( DefaultOrCustomModel( ANTLIONGUARD_MODEL ) ); // Switch our skin (for now), if we're the cavern guard if ( m_bCavernBreed ) @@ -1573,7 +1584,11 @@ class CTraceFilterCharge : public CTraceFilterEntitiesOnly if ( pVictimBCC ) { // Can only damage other NPCs that we hate +#ifdef MAPBASE + if ( m_pAttacker->IRelationType( pEntity ) <= D_FR ) +#else if ( m_pAttacker->IRelationType( pEntity ) == D_HT ) +#endif { pEntity->TakeDamage( info ); return true; @@ -2612,8 +2627,15 @@ class CTraceFilterSkipPhysics : public CTraceFilter if ( !pEntity->IsNPC() && pEntity->GetMoveType() == MOVETYPE_VPHYSICS ) { IPhysicsObject *pPhysics = pEntity->VPhysicsGetObject(); +#ifdef MAPBASE + // A MOVETYPE_VPHYSICS object without a VPhysics object is an odd edge case, but it's evidently possible + // since my game crashed after an antlion guard tried to see me through an EP2 jalopy. + // Perhaps that's a sign of an underlying issue? + if ( pPhysics && pPhysics->IsMoveable() && pPhysics->GetMass() < m_minMass ) +#else Assert(pPhysics); if ( pPhysics->IsMoveable() && pPhysics->GetMass() < m_minMass ) +#endif return false; } @@ -2729,7 +2751,11 @@ bool CNPC_AntlionGuard::HandleChargeImpact( Vector vecImpact, CBaseEntity *pEnti } // Hit anything we don't like +#ifdef MAPBASE + if ( IRelationType( pEntity ) <= D_FR && ( GetNextAttack() < gpGlobals->curtime ) ) +#else if ( IRelationType( pEntity ) == D_HT && ( GetNextAttack() < gpGlobals->curtime ) ) +#endif { EmitSound( "NPC_AntlionGuard.Shove" ); @@ -3227,6 +3253,9 @@ void CNPC_AntlionGuard::SummonAntlions( void ) // Make the antlion fire my input when he dies pAntlion->KeyValue( "OnDeath", UTIL_VarArgs("%s,SummonedAntlionDied,,0,-1", STRING(GetEntityName())) ); +#ifdef MAPBASE + pAntlion->KeyValue( "OnKilled", UTIL_VarArgs("%s,SummonedAntlionDied,,0,-1", STRING(GetEntityName())) ); +#endif // Start the antlion burrowed, and tell him to come up pAntlion->m_bStartBurrowed = true; @@ -3366,6 +3395,11 @@ void CNPC_AntlionGuard::InputClearChargeTarget( inputdata_t &inputdata ) //----------------------------------------------------------------------------- Activity CNPC_AntlionGuard::NPC_TranslateActivity( Activity baseAct ) { +#ifdef MAPBASE + // Needed for VScript NPC_TranslateActiviy hook + baseAct = BaseClass::NPC_TranslateActivity( baseAct ); +#endif + //See which run to use if ( ( baseAct == ACT_RUN ) && IsCurSchedule( SCHED_ANTLIONGUARD_CHARGE ) ) return (Activity) ACT_ANTLIONGUARD_CHARGE_RUN; @@ -4676,6 +4710,15 @@ AI_BEGIN_CUSTOM_NPC( npc_antlionguard, CNPC_AntlionGuard ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_FL ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_RR ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_RL ) +#ifdef MAPBASE + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_ENTER ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_LOOP ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_EXIT ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_ADVANCE ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_FLINCH ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_SNEAK ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_RUN_FULL ) +#endif //Adrian: events go here DECLARE_ANIMEVENT( AE_ANTLIONGUARD_CHARGE_HIT ) diff --git a/game/server/hl2/npc_attackchopper.cpp b/game/server/hl2/npc_attackchopper.cpp index 0687c915..ac6efb1c 100644 --- a/game/server/hl2/npc_attackchopper.cpp +++ b/game/server/hl2/npc_attackchopper.cpp @@ -42,6 +42,10 @@ #include "physics_bone_follower.h" #endif // HL2_EPISODIC +#ifdef MAPBASE +#include "filters.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -115,6 +119,9 @@ static const char *s_pChunkModelName[CHOPPER_MAX_CHUNKS] = #define SF_HELICOPTER_IGNORE_AVOID_FORCES 0x00080000 #define SF_HELICOPTER_AGGRESSIVE 0x00100000 #define SF_HELICOPTER_LONG_SHADOW 0x00200000 +#ifdef MAPBASE +#define SF_HELICOPTER_AIM_WITH_GUN_OFF 0x00400000 +#endif #define CHOPPER_SLOW_BOMB_SPEED 250 @@ -347,6 +354,10 @@ class CHelicopterChunk : public CBaseAnimating void CollisionCallback( CHelicopterChunk *pCaller ); +#ifdef MAPBASE + void InputFallApart( inputdata_t &inputdata ); +#endif + void FallThink( void ); bool m_bLanded; @@ -760,8 +771,13 @@ class CNPC_AttackHelicopter : public CBaseHelicopter CSoundPatch *m_pGunFiringSound; // Outputs +#ifndef MAPBASE COutputInt m_OnHealthChanged; +#endif COutputEvent m_OnShotDown; +#ifdef MAPBASE + COutputEHANDLE m_OutBomb; +#endif // Crashing EHANDLE m_hCrashPoint; @@ -842,6 +858,10 @@ BEGIN_DATADESC( CNPC_AttackHelicopter ) DEFINE_KEYFIELD( m_flMaxSpeed, FIELD_FLOAT, "PatrolSpeed" ), DEFINE_KEYFIELD( m_bNonCombat, FIELD_BOOLEAN, "NonCombat" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flFieldOfView, FIELD_FLOAT, "FieldOfView" ), +#endif + DEFINE_FIELD( m_hCrashPoint, FIELD_EHANDLE ), DEFINE_INPUTFUNC( FIELD_VOID, "ResetIdleTime", InputResetIdleTime ), @@ -866,7 +886,9 @@ BEGIN_DATADESC( CNPC_AttackHelicopter ) DEFINE_INPUTFUNC( FIELD_VOID, "StartContinuousShooting", InputStartContinuousShooting ), DEFINE_INPUTFUNC( FIELD_VOID, "StartFastShooting", InputStartFastShooting ), DEFINE_INPUTFUNC( FIELD_VOID, "GunOff", InputGunOff ), +#ifndef MAPBASE // This has been added to all NPCs. npc_helicopter overrides it with its original function, but the datadesc entry isn't needed anymore. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthFraction", InputSetHealthFraction ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "StartBombExplodeOnContact", InputStartBombExplodeOnContact ), DEFINE_INPUTFUNC( FIELD_VOID, "StopBombExplodeOnContact", InputStopBombExplodeOnContact ), @@ -878,8 +900,13 @@ BEGIN_DATADESC( CNPC_AttackHelicopter ) DEFINE_THINKFUNC( BlinkLightsThink ), DEFINE_THINKFUNC( SpotlightThink ), +#ifndef MAPBASE DEFINE_OUTPUT( m_OnHealthChanged, "OnHealthChanged" ), +#endif DEFINE_OUTPUT( m_OnShotDown, "OnShotDown" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OutBomb, "OutBomb" ), +#endif END_DATADESC() @@ -893,6 +920,9 @@ CNPC_AttackHelicopter::CNPC_AttackHelicopter() : m_bBombsExplodeOnContact( false ) { m_flMaxSpeed = 0; +#ifdef MAPBASE + m_flFieldOfView = -1.0; // 360 degrees +#endif } CNPC_AttackHelicopter::~CNPC_AttackHelicopter(void) @@ -937,6 +967,13 @@ void CNPC_AttackHelicopter::Precache( void ) { BaseClass::Precache(); +#ifdef MAPBASE + if ( GetModelName() != NULL_STRING ) + { + PrecacheModel( STRING(GetModelName()) ); + } + else +#endif if ( !HasSpawnFlags(SF_HELICOPTER_ELECTRICAL_DRONE) ) { PrecacheModel( CHOPPER_MODEL_NAME ); @@ -1038,6 +1075,13 @@ void CNPC_AttackHelicopter::Spawn( void ) m_bBombingSuppressed = false; m_bIgnorePathVisibilityTests = false; +#ifdef MAPBASE + if ( GetModelName() != NULL_STRING ) + { + SetModel( STRING(GetModelName()) ); + } + else +#endif if ( !HasSpawnFlags(SF_HELICOPTER_ELECTRICAL_DRONE) ) { SetModel( CHOPPER_MODEL_NAME ); @@ -1070,6 +1114,11 @@ void CNPC_AttackHelicopter::Spawn( void ) SetPauseState( PAUSE_NO_PAUSE ); +#ifdef MAPBASE + if (m_iHealth != 0) + m_iMaxHealth = m_iHealth; + else +#endif m_iMaxHealth = m_iHealth = sk_helicopter_health.GetInt(); m_flMaxSpeed = flLoadedSpeed; @@ -1081,7 +1130,9 @@ void CNPC_AttackHelicopter::Spawn( void ) m_nGrenadeCount = CHOPPER_BOMB_DROP_COUNT; +#ifndef MAPBASE // Moved to constructor because this is a keyvalue now m_flFieldOfView = -1.0; // 360 degrees +#endif m_flIdleTimeDelay = 0.0f; m_iAmmoType = GetAmmoDef()->Index("HelicopterGun"); @@ -2790,6 +2841,10 @@ CGrenadeHelicopter *CNPC_AttackHelicopter::SpawnBombEntity( const Vector &vecPos } #endif // HL2_EPISODIC +#ifdef MAPBASE + m_OutBomb.Set(pGrenade, pGrenade, this); +#endif + return pGrenade; } @@ -3475,9 +3530,16 @@ void CNPC_AttackHelicopter::TraceAttack( const CTakeDamageInfo &info, const Vect // Take no damage from trace attacks unless it's blast damage. RadiusDamage() sometimes calls // TraceAttack() as a means for delivering blast damage. Usually when the explosive penetrates // the target. (RPG missiles do this sometimes). +#ifdef MAPBASE + if ( ( info.GetDamageType() & DMG_AIRBOAT ) || + ( info.GetInflictor()->Classify() == CLASS_MISSILE ) || + ( info.GetAttacker()->Classify() == CLASS_MISSILE ) || + m_bAllowAnyDamage ) +#else if ( ( info.GetDamageType() & DMG_AIRBOAT ) || ( info.GetInflictor()->Classify() == CLASS_MISSILE ) || ( info.GetAttacker()->Classify() == CLASS_MISSILE ) ) +#endif { BaseClass::BaseClass::TraceAttack( info, vecDir, ptr, pAccumulator ); } @@ -3490,7 +3552,11 @@ void CNPC_AttackHelicopter::TraceAttack( const CTakeDamageInfo &info, const Vect int CNPC_AttackHelicopter::OnTakeDamage( const CTakeDamageInfo &info ) { // We don't take blast damage from anything but the airboat or missiles (or myself!) +#ifdef MAPBASE + if( info.GetInflictor() != this && !m_bAllowAnyDamage ) +#else if( info.GetInflictor() != this ) +#endif { if ( ( ( info.GetDamageType() & DMG_AIRBOAT ) == 0 ) && ( info.GetInflictor()->Classify() != CLASS_MISSILE ) && @@ -3605,12 +3671,14 @@ int CNPC_AttackHelicopter::OnTakeDamage_Alive( const CTakeDamageInfo &info ) ExplodeAndThrowChunk( info.GetDamagePosition() ); } +#ifndef MAPBASE // We need to make sure the base OnHealthChanged works with helicopters int nPrevPercent = (int)(100.0f * nPrevHealth / GetMaxHealth()); int nCurrPercent = (int)(100.0f * GetHealth() / GetMaxHealth()); if (( (nPrevPercent + 9) / 10 ) != ( (nCurrPercent + 9) / 10 )) { m_OnHealthChanged.Set( nCurrPercent, this, this ); } +#endif } return nRetVal; @@ -4795,6 +4863,26 @@ void CNPC_AttackHelicopter::Hunt( void ) { BullrushBombs(); } +#ifdef MAPBASE + // Some may want the hunter-chopper to aim at different positions searching for its target + // without actually firing at anything. Gun aiming is only handled in FireGun(), which is + // disabled when the gun is disabled. point_posecontroller doesn't seem to work well for this either, + // so a new spawnflag is handled here to allow the chopper to aim at its enemy even when the gun is off. + else if ( HasSpawnFlags( SF_HELICOPTER_AIM_WITH_GUN_OFF ) && GetEnemy() ) + { + // Get gun attachment points + Vector vBasePos; + GetAttachment( m_nGunBaseAttachment, vBasePos ); + + Vector vecFireAtPosition; + ComputeFireAtPosition( &vecFireAtPosition ); + + Vector vTargetDir = vecFireAtPosition - vBasePos; + VectorNormalize( vTargetDir ); + + PoseGunTowardTargetDirection( vTargetDir ); + } +#endif } #ifdef HL2_EPISODIC @@ -5596,6 +5684,9 @@ LINK_ENTITY_TO_CLASS( npc_heli_avoidsphere, CAvoidSphere ); BEGIN_DATADESC( CAvoidSphere ) DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "radius" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszAvoidFilter, FIELD_STRING, "AvoidFilter" ), +#endif END_DATADESC() @@ -5636,6 +5727,18 @@ void CAvoidSphere::Activate( ) { BaseClass::Activate(); s_AvoidSpheres.AddToTail( this ); + +#ifdef MAPBASE + m_hAvoidFilter = gEntList.FindEntityByName( NULL, m_iszAvoidFilter, this ); + if (m_hAvoidFilter) + { + if (dynamic_cast(m_hAvoidFilter.Get()) == NULL) + { + Warning( "%s: \"%s\" is not a valid filter", GetDebugName(), m_hAvoidFilter->GetDebugName() ); + m_hAvoidFilter = NULL; + } + } +#endif } void CAvoidSphere::UpdateOnRemove( ) @@ -5662,6 +5765,12 @@ void CAvoidSphere::ComputeAvoidanceForces( CBaseEntity *pEntity, float flEntityR CAvoidSphere *pSphere = s_AvoidSpheres[i].Get(); const Vector &vecAvoidCenter = pSphere->WorldSpaceCenter(); +#ifdef MAPBASE + // Continue if not passing the avoid sphere filter + if ( pSphere->m_hAvoidFilter && !(static_cast( pSphere->m_hAvoidFilter.Get())->PassesFilter(pSphere, pEntity )) ) + continue; +#endif + // NOTE: This test can be thought of sweeping a sphere through space // and seeing if it intersects the avoidance sphere float flTotalRadius = flEntityRadius + pSphere->m_flRadius; @@ -5939,6 +6048,10 @@ BEGIN_DATADESC( CHelicopterChunk ) DEFINE_PHYSPTR( m_pTailConstraint ), DEFINE_PHYSPTR( m_pCockpitConstraint ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "FallApart", InputFallApart ), +#endif + END_DATADESC() //----------------------------------------------------------------------------- @@ -6040,6 +6153,17 @@ void CHelicopterChunk::CollisionCallback( CHelicopterChunk *pCaller ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pCaller - +//----------------------------------------------------------------------------- +void CHelicopterChunk::InputFallApart( inputdata_t &inputdata ) +{ + CollisionCallback(this); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : &vecPos - diff --git a/game/server/hl2/npc_barnacle.cpp b/game/server/hl2/npc_barnacle.cpp index 1c195b90..4a7e53fc 100644 --- a/game/server/hl2/npc_barnacle.cpp +++ b/game/server/hl2/npc_barnacle.cpp @@ -40,6 +40,10 @@ ConVar sk_barnacle_health( "sk_barnacle_health","0"); static ConVar npc_barnacle_swallow( "npc_barnacle_swallow", "0", 0, "Use prototype swallow code." ); +#ifdef MAPBASE +ConVar npc_barnacle_ignite( "npc_barnacle_ignite", "0", FCVAR_NONE, "Allows barnacles to be ignited by flares and beyond." ); +#endif + const char *CNPC_Barnacle::m_szGibNames[NUM_BARNACLE_GIBS] = { "models/gibs/hgibs.mdl", @@ -69,6 +73,9 @@ int g_interactionBarnacleVictimDangle = 0; int g_interactionBarnacleVictimReleased = 0; int g_interactionBarnacleVictimGrab = 0; int g_interactionBarnacleVictimBite = 0; +#ifdef MAPBASE +int g_interactionBarnacleVictimFinalBite = 0; +#endif LINK_ENTITY_TO_CLASS( npc_barnacle, CNPC_Barnacle ); @@ -177,7 +184,7 @@ BEGIN_DATADESC( CNPC_Barnacle ) DEFINE_INPUTFUNC( FIELD_VOID, "DropTongue", InputDropTongue ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetDropTongueSpeed", InputSetDropTongueSpeed ), -#ifdef HL2_EPISODIC +#if HL2_EPISODIC || MAPBASE DEFINE_INPUTFUNC( FIELD_VOID, "LetGo", InputLetGo ), DEFINE_OUTPUT( m_OnGrab, "OnGrab" ), DEFINE_OUTPUT( m_OnRelease, "OnRelease" ), @@ -187,7 +194,9 @@ BEGIN_DATADESC( CNPC_Barnacle ) DEFINE_THINKFUNC( BarnacleThink ), DEFINE_THINKFUNC( WaitTillDead ), +#ifndef MAPBASE DEFINE_FIELD( m_bSwallowingBomb, FIELD_BOOLEAN ), +#endif END_DATADESC() @@ -257,7 +266,7 @@ void CNPC_Barnacle::Spawn() { Precache( ); - SetModel( "models/barnacle.mdl" ); + SetModel( DefaultOrCustomModel( "models/barnacle.mdl" ) ); UTIL_SetSize( this, Vector(-16, -16, -40), Vector(16, 16, 0) ); SetSolid( SOLID_BBOX ); @@ -275,7 +284,9 @@ void CNPC_Barnacle::Spawn() m_cGibs = 0; m_bLiftingPrey = false; m_bSwallowingPrey = false; +#ifndef MAPBASE m_bSwallowingBomb = false; +#endif m_flDigestFinish = 0; m_takedamage = DAMAGE_YES; m_pConstraint = NULL; @@ -406,6 +417,16 @@ void CNPC_Barnacle::PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CNPC_Barnacle::AllowedToIgnite( void ) +{ + return npc_barnacle_ignite.GetBool(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Initialize tongue position when first spawned // Input : @@ -509,7 +530,11 @@ void CNPC_Barnacle::BarnacleThink ( void ) } else if ( GetEnemy() ) { +#ifdef MAPBASE + if ( m_bLiftingPrey ) +#else if ( m_bLiftingPrey || m_bSwallowingBomb == true ) +#endif { LiftPrey(); } @@ -664,6 +689,12 @@ bool CNPC_Barnacle::CanPickup( CBaseCombatCharacter *pBCC ) if( FClassnameIs( pBCC, "npc_turret_floor" ) ) return false; +#ifdef MAPBASE + // Don't pickup rollermines + if( FClassnameIs( pBCC, "npc_rollermine" ) ) + return false; +#endif + // Don't pick up a dead player or NPC if( !pBCC->IsAlive() ) return false; @@ -893,7 +924,7 @@ void CNPC_Barnacle::PullEnemyTorwardsMouth( bool bAdjustEnemyOrigin ) { // get us there in a second Vector desiredVelocity; - float distToMove = min(distFromCenter, 24.0f * dt); + float distToMove = MIN(distFromCenter, 24.0f * dt); desiredVelocity.x = vToCenter.x * distToMove; desiredVelocity.y = vToCenter.y * distToMove; desiredVelocity.z = 0; @@ -1145,6 +1176,24 @@ void CNPC_Barnacle::LiftPhysicsObject( float flBiteZOffset ) // If we got a physics prop, wait until the thing has settled down m_bLiftingPrey = false; +#ifdef MAPBASE + Vector tipPos = m_vecTip.Get(); + Activity curAct = GetActivity(); + + // Other, non-character entities use this now + if (pVictim->DispatchInteraction( g_interactionBarnacleVictimBite, &tipPos, this )) + { + // Make sure the interaction isn't making us use an irregular activity + // (e.g. biting) + if (GetActivity() == curAct) + SetActivity( (Activity)ACT_BARNACLE_TASTE_SPIT ); + } + else + { + // Start the spit animation. + SetActivity( (Activity)ACT_BARNACLE_TASTE_SPIT ); + } +#else if ( hl2_episodic.GetBool() ) { CBounceBomb *pBounce = dynamic_cast( pVictim ); @@ -1181,6 +1230,7 @@ void CNPC_Barnacle::LiftPhysicsObject( float flBiteZOffset ) pBCC->DispatchInteraction( g_interactionBarnacleVictimBite, &tipPos, this ); } +#endif #endif } else @@ -1355,7 +1405,7 @@ void CNPC_Barnacle::InputDropTongue( inputdata_t &inputdata ) void CNPC_Barnacle::AttachTongueToTarget( CBaseEntity *pTouchEnt, Vector vecGrabPos ) { -#if HL2_EPISODIC +#if HL2_EPISODIC || MAPBASE m_OnGrab.Set( pTouchEnt, this, this ); #endif @@ -1577,6 +1627,18 @@ void CNPC_Barnacle::BitePrey( void ) CBaseCombatCharacter *pVictim = GetEnemyCombatCharacterPointer(); +#ifdef MAPBASE + if ( pVictim == NULL ) + { + if ( GetEnemy() ) + { + Vector tipPos = m_vecTip.Get(); + GetEnemy()->DispatchInteraction( g_interactionBarnacleVictimFinalBite, &tipPos, this ); + } + + return; + } +#else #ifdef HL2_EPISODIC if ( pVictim == NULL ) { @@ -1614,6 +1676,7 @@ void CNPC_Barnacle::BitePrey( void ) { return; } +#endif EmitSound( "NPC_Barnacle.FinalBite" ); @@ -1701,6 +1764,12 @@ void CNPC_Barnacle::BitePrey( void ) #endif +#ifdef MAPBASE + Vector tipPos = m_vecTip.Get(); + if (pVictim->DispatchInteraction( g_interactionBarnacleVictimFinalBite, &tipPos, this )) + return; +#endif + // Players are never swallowed, nor is anything we don't have a ragdoll for if ( !m_hRagdoll || pVictim->IsPlayer() ) { @@ -1873,7 +1942,7 @@ void CNPC_Barnacle::RemoveRagdoll( bool bDestroyRagdoll ) void CNPC_Barnacle::LostPrey( bool bRemoveRagdoll ) { -#if HL2_EPISODIC +#if HL2_EPISODIC || MAPBASE m_OnRelease.Set( GetEnemy(), this, this ); #endif @@ -1885,13 +1954,20 @@ void CNPC_Barnacle::LostPrey( bool bRemoveRagdoll ) PhysEnableEntityCollisions( this, pEnemy ); #endif +#ifdef MAPBASE + // These can be CBaseEntity-based now + pEnemy->DispatchInteraction( g_interactionBarnacleVictimReleased, NULL, this ); +#endif + //No one survives being snatched by a barnacle anymore, so leave // this flag set so that their entity gets removed. //GetEnemy()->RemoveEFlags( EFL_IS_BEING_LIFTED_BY_BARNACLE ); CBaseCombatCharacter *pVictim = GetEnemyCombatCharacterPointer(); if ( pVictim ) { +#ifndef MAPBASE pVictim->DispatchInteraction( g_interactionBarnacleVictimReleased, NULL, this ); +#endif pVictim->RemoveEFlags( EFL_IS_BEING_LIFTED_BY_BARNACLE ); if ( m_hRagdoll ) @@ -2213,6 +2289,11 @@ bool CNPC_Barnacle::IsPoisonous( CBaseEntity *pVictim ) if ( FClassnameIs(pVictim,"npc_headcrab_black") ) return true; +#ifdef MAPBASE + if (FClassnameIs( pVictim, "npc_poisonzombie" )) + return true; +#endif + if ( FClassnameIs(pVictim,"npc_antlion") && static_cast(pVictim)->IsWorker() ) @@ -2220,10 +2301,12 @@ bool CNPC_Barnacle::IsPoisonous( CBaseEntity *pVictim ) return false; } +#endif +#if HL2_EPISODIC || MAPBASE //========================================================= // script input to immediately abandon whatever I am lifting //========================================================= @@ -2240,8 +2323,10 @@ void CNPC_Barnacle::InputLetGo( inputdata_t &inputdata ) LostPrey( false ); } } +#endif +#if HL2_EPISODIC // Barnacle has custom impact damage tables, so it can take grave damage from sawblades. static impactentry_t barnacleLinearTable[] = { @@ -2296,7 +2381,7 @@ const impactdamagetable_t &CNPC_Barnacle::GetPhysicsImpactDamageTable( void ) //========================================================= void CNPC_Barnacle::Precache() { - PrecacheModel("models/barnacle.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/barnacle.mdl" ) ); // Precache all gibs for ( int i=0; i < ARRAYSIZE(m_szGibNames); i++ ) @@ -2712,6 +2797,9 @@ AI_BEGIN_CUSTOM_NPC( npc_barnacle, CNPC_Barnacle ) DECLARE_INTERACTION( g_interactionBarnacleVictimReleased ) DECLARE_INTERACTION( g_interactionBarnacleVictimGrab ) DECLARE_INTERACTION( g_interactionBarnacleVictimBite ) +#ifdef MAPBASE + DECLARE_INTERACTION( g_interactionBarnacleVictimFinalBite ) +#endif // Conditions diff --git a/game/server/hl2/npc_barnacle.h b/game/server/hl2/npc_barnacle.h index bcb191cf..373be24b 100644 --- a/game/server/hl2/npc_barnacle.h +++ b/game/server/hl2/npc_barnacle.h @@ -84,6 +84,10 @@ class CNPC_Barnacle : public CAI_BaseNPC int OnTakeDamage_Alive( const CTakeDamageInfo &info ); void PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot ); +#ifdef MAPBASE + bool AllowedToIgnite( void ); +#endif + // The tongue's vphysics updated void OnTongueTipUpdated(); @@ -145,6 +149,19 @@ class CNPC_Barnacle : public CAI_BaseNPC +#ifdef MAPBASE + +#if HL2_EPISODIC + /// Decides whether something should poison the barnacle upon eating + static bool IsPoisonous( CBaseEntity *pVictim ); + const impactdamagetable_t &GetPhysicsImpactDamageTable( void ); +#endif + + // Regular HL2 DLL has these now + void InputLetGo( inputdata_t &inputdata ); + COutputEHANDLE m_OnGrab, m_OnRelease; + +#else #if HL2_EPISODIC /// Decides whether something should poison the barnacle upon eating static bool IsPoisonous( CBaseEntity *pVictim ); @@ -153,6 +170,7 @@ class CNPC_Barnacle : public CAI_BaseNPC COutputEHANDLE m_OnGrab, m_OnRelease; const impactdamagetable_t &GetPhysicsImpactDamageTable( void ); +#endif #endif CNetworkVar( float, m_flAltitude ); @@ -195,7 +213,9 @@ class CNPC_Barnacle : public CAI_BaseNPC Vector m_vLastEnemyPos; float m_flLastPull; CSimpleSimTimer m_StuckTimer; +#ifndef MAPBASE // Handled by interactions now bool m_bSwallowingBomb; +#endif #ifdef HL2_EPISODIC bool m_bSwallowingPoison; #endif diff --git a/game/server/hl2/npc_barney.cpp b/game/server/hl2/npc_barney.cpp index 337d0eb6..cfb80afc 100644 --- a/game/server/hl2/npc_barney.cpp +++ b/game/server/hl2/npc_barney.cpp @@ -51,8 +51,10 @@ class CNPC_Barney : public CNPC_PlayerCompanion virtual void Precache() { +#ifndef MAPBASE // This is now done in CNPC_PlayerCompanion::Precache() // Prevents a warning SelectModel( ); +#endif BaseClass::Precache(); PrecacheScriptSound( "NPC_Barney.FootstepLeft" ); @@ -81,6 +83,11 @@ class CNPC_Barney : public CNPC_PlayerCompanion void GatherConditions(); void UseFunc( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); +#ifdef MAPBASE + // Use Barney's default subtitle color (215,255,255) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 215; params.g1 = 255; params.b1 = 255; return BaseClass::GetGameTextSpeechParams( params ); } +#endif + CAI_FuncTankBehavior m_FuncTankBehavior; COutputEvent m_OnPlayerUse; @@ -111,6 +118,9 @@ END_DATADESC() //----------------------------------------------------------------------------- void CNPC_Barney::SelectModel() { +#ifdef MAPBASE + if (GetModelName() == NULL_STRING) +#endif SetModelName( AllocPooledString( BARNEY_MODEL ) ); } @@ -121,7 +131,11 @@ void CNPC_Barney::Spawn( void ) { Precache(); +#ifdef MAPBASE + m_iHealth = sk_barney_health.GetInt(); +#else m_iHealth = 80; +#endif m_iszIdleExpression = MAKE_STRING("scenes/Expressions/BarneyIdle.vcd"); m_iszAlertExpression = MAKE_STRING("scenes/Expressions/BarneyAlert.vcd"); diff --git a/game/server/hl2/npc_basescanner.cpp b/game/server/hl2/npc_basescanner.cpp index b05441db..fdae50da 100644 --- a/game/server/hl2/npc_basescanner.cpp +++ b/game/server/hl2/npc_basescanner.cpp @@ -41,6 +41,10 @@ BEGIN_DATADESC( CNPC_BaseScanner ) DEFINE_FIELD( m_flAttackFarDist, FIELD_FLOAT ), DEFINE_FIELD( m_flAttackRange, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flCustomMaxSpeed, FIELD_FLOAT, "CustomFlightSpeed" ), +#endif + DEFINE_FIELD( m_nPoseTail, FIELD_INTEGER ), DEFINE_FIELD( m_nPoseDynamo, FIELD_INTEGER ), DEFINE_FIELD( m_nPoseFlare, FIELD_INTEGER ), @@ -52,7 +56,11 @@ BEGIN_DATADESC( CNPC_BaseScanner ) DEFINE_FIELD( m_pSmokeTrail, FIELD_CLASSPTR ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDistanceOverride", InputSetDistanceOverride ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFlightSpeed", InputSetFlightSpeed ), +#else DEFINE_INPUTFUNC( FIELD_INTEGER, "SetFlightSpeed", InputSetFlightSpeed ), +#endif DEFINE_THINKFUNC( DiveBombSoundThink ), END_DATADESC() @@ -861,12 +869,16 @@ void CNPC_BaseScanner::SpeakSentence( int sentenceType ) //----------------------------------------------------------------------------- void CNPC_BaseScanner::InputSetFlightSpeed(inputdata_t &inputdata) { +#ifdef MAPBASE + m_flCustomMaxSpeed = inputdata.value.Float(); +#else //FIXME: Currently unsupported /* m_flFlightSpeed = inputdata.value.Int(); m_bFlightSpeedOverridden = (m_flFlightSpeed > 0); */ +#endif } //----------------------------------------------------------------------------- @@ -1266,6 +1278,14 @@ void CNPC_BaseScanner::MoveToTarget( float flInterval, const Vector &vecMoveTarg myZAccel = flDist / flInterval; } +#ifdef MAPBASE + if (m_flSpeedModifier != 1.0f) + { + myAccel *= m_flSpeedModifier; + //myZAccel *= m_flSpeedModifier; + } +#endif + MoveInDirection( flInterval, targetDir, myAccel, myZAccel, myDecay ); // calc relative banking targets @@ -1655,6 +1675,11 @@ void CNPC_BaseScanner::PainSound( const CTakeDamageInfo &info ) //----------------------------------------------------------------------------- float CNPC_BaseScanner::GetMaxSpeed() { +#ifdef MAPBASE + if (m_flCustomMaxSpeed > 0.0f) + return m_flCustomMaxSpeed; +#endif + return SCANNER_MAX_SPEED; } diff --git a/game/server/hl2/npc_basescanner.h b/game/server/hl2/npc_basescanner.h index ab69c81c..1a286b81 100644 --- a/game/server/hl2/npc_basescanner.h +++ b/game/server/hl2/npc_basescanner.h @@ -200,6 +200,11 @@ class CNPC_BaseScanner : public CAI_BasePhysicsFlyingBot, public CDefaultPlayerP float m_flAttackFarDist; float m_flAttackRange; +#ifdef MAPBASE + // Custom max speed for mappers to control + float m_flCustomMaxSpeed; +#endif + private: CSoundPatch *m_pEngineSound; diff --git a/game/server/hl2/npc_breen.cpp b/game/server/hl2/npc_breen.cpp index e12bab0c..e1409c80 100644 --- a/game/server/hl2/npc_breen.cpp +++ b/game/server/hl2/npc_breen.cpp @@ -34,6 +34,11 @@ class CNPC_Breen : public CAI_BaseActor void HandleAnimEvent( animevent_t *pEvent ); int GetSoundInterests ( void ); bool UseSemaphore( void ); + +#ifdef MAPBASE + // Use Breen's default subtitle color (188,188,188) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 188; params.g1 = 188; params.b1 = 188; return BaseClass::GetGameTextSpeechParams( params ); } +#endif }; LINK_ENTITY_TO_CLASS( npc_breen, CNPC_Breen ); diff --git a/game/server/hl2/npc_bullsquid.cpp b/game/server/hl2/npc_bullsquid.cpp index 2c0706da..954ea868 100644 --- a/game/server/hl2/npc_bullsquid.cpp +++ b/game/server/hl2/npc_bullsquid.cpp @@ -7,11 +7,11 @@ #include "cbase.h" #include "game.h" -#include "AI_Default.h" -#include "AI_Schedule.h" -#include "AI_Hull.h" -#include "AI_Navigator.h" -#include "AI_Motor.h" +#include "ai_default.h" +#include "ai_schedule.h" +#include "ai_hull.h" +#include "ai_navigator.h" +#include "ai_motor.h" #include "ai_squad.h" #include "npc_bullsquid.h" #include "npcevent.h" @@ -30,8 +30,8 @@ #include "engine/IEngineSound.h" #include "movevars_shared.h" -#include "AI_Hint.h" -#include "AI_Senses.h" +#include "ai_hint.h" +#include "ai_senses.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/game/server/hl2/npc_citizen17.cpp b/game/server/hl2/npc_citizen17.cpp index adb9eb8c..ad7dd9da 100644 --- a/game/server/hl2/npc_citizen17.cpp +++ b/game/server/hl2/npc_citizen17.cpp @@ -25,6 +25,12 @@ #include "eventqueue.h" +#ifdef MAPBASE +#include "hl2_gamerules.h" +#include "mapbase/GlobalStrings.h" +#include "collisionutils.h" +#endif + #include "ai_squad.h" #include "ai_pathfinder.h" #include "ai_route.h" @@ -69,6 +75,10 @@ ConVar npc_citizen_squad_marker( "npc_citizen_squad_marker", "0" ); ConVar npc_citizen_explosive_resist( "npc_citizen_explosive_resist", "0" ); ConVar npc_citizen_auto_player_squad( "npc_citizen_auto_player_squad", "1" ); ConVar npc_citizen_auto_player_squad_allow_use( "npc_citizen_auto_player_squad_allow_use", "0" ); +#ifdef MAPBASE +ConVar npc_citizen_squad_secondary_toggle_use_button("npc_citizen_squad_toggle_use_button", "262144"); // IN_WALK by default +ConVar npc_citizen_squad_secondary_toggle_use_always( "npc_citizen_squad_secondary_toggle_use_always", "0", FCVAR_NONE, "Allows all citizens not strictly stuck to the player's squad to be toggled via Alt + E." ); +#endif ConVar npc_citizen_dont_precache_all( "npc_citizen_dont_precache_all", "0" ); @@ -84,15 +94,29 @@ ConVar sk_citizen_heal_toss_player_delay("sk_citizen_heal_toss_player_delay", "2 #define MEDIC_THROW_SPEED npc_citizen_medic_throw_speed.GetFloat() +#ifdef MAPBASE +// We use a boolean now, so NameMatches("griggs") is handled in CNPC_Citizen::Spawn(). +#define USE_EXPERIMENTAL_MEDIC_CODE() (npc_citizen_heal_chuck_medkit.GetBool() && m_bTossesMedkits) +#else #define USE_EXPERIMENTAL_MEDIC_CODE() (npc_citizen_heal_chuck_medkit.GetBool() && NameMatches("griggs")) #endif +#endif +#ifdef MAPBASE +ConVar player_squad_autosummon_enabled( "player_squad_autosummon_enabled", "1" ); +#endif ConVar player_squad_autosummon_time( "player_squad_autosummon_time", "5" ); ConVar player_squad_autosummon_move_tolerance( "player_squad_autosummon_move_tolerance", "20" ); ConVar player_squad_autosummon_player_tolerance( "player_squad_autosummon_player_tolerance", "10" ); ConVar player_squad_autosummon_time_after_combat( "player_squad_autosummon_time_after_combat", "8" ); ConVar player_squad_autosummon_debug( "player_squad_autosummon_debug", "0" ); +#ifdef MAPBASE +ConVar npc_citizen_resupplier_adjust_ammo("npc_citizen_resupplier_adjust_ammo", "1", FCVAR_NONE, "If what ammo we give to the player would go over their max, should we adjust what we give accordingly (1) or cancel it altogether? (0)" ); + +ConVar npc_citizen_nocollide_player( "npc_citizen_nocollide_player", "0" ); +#endif + #define ShouldAutosquad() (npc_citizen_auto_player_squad.GetBool()) enum SquadSlot_T @@ -143,23 +167,23 @@ struct citizen_expression_list_t // Scared citizen_expression_list_t ScaredExpressions[STATES_WITH_EXPRESSIONS] = { - { { "scenes/Expressions/citizen_scared_idle_01.vcd" } }, - { { "scenes/Expressions/citizen_scared_alert_01.vcd" } }, - { { "scenes/Expressions/citizen_scared_combat_01.vcd" } }, + { "scenes/Expressions/citizen_scared_idle_01.vcd" }, + { "scenes/Expressions/citizen_scared_alert_01.vcd" }, + { "scenes/Expressions/citizen_scared_combat_01.vcd" }, }; // Normal citizen_expression_list_t NormalExpressions[STATES_WITH_EXPRESSIONS] = { - { { "scenes/Expressions/citizen_normal_idle_01.vcd" } }, - { { "scenes/Expressions/citizen_normal_alert_01.vcd" } }, - { { "scenes/Expressions/citizen_normal_combat_01.vcd" } }, + { "scenes/Expressions/citizen_normal_idle_01.vcd" }, + { "scenes/Expressions/citizen_normal_alert_01.vcd" }, + { "scenes/Expressions/citizen_normal_combat_01.vcd" }, }; // Angry citizen_expression_list_t AngryExpressions[STATES_WITH_EXPRESSIONS] = { - { { "scenes/Expressions/citizen_angry_idle_01.vcd" } }, - { { "scenes/Expressions/citizen_angry_alert_01.vcd" } }, - { { "scenes/Expressions/citizen_angry_combat_01.vcd" } }, + { "scenes/Expressions/citizen_angry_idle_01.vcd" }, + { "scenes/Expressions/citizen_angry_alert_01.vcd" }, + { "scenes/Expressions/citizen_angry_combat_01.vcd" }, }; //----------------------------------------------------------------------------- @@ -247,6 +271,10 @@ class CMattsPipe : public CWeaponCrowbar void SetPickupTouch( void ) { /* do nothing */ } }; +#ifdef MAPBASE +LINK_ENTITY_TO_CLASS(weapon_mattpipe, CMattsPipe); +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -335,6 +363,10 @@ BEGIN_DATADESC( CNPC_Citizen ) DEFINE_KEYFIELD( m_bNotifyNavFailBlocked, FIELD_BOOLEAN, "notifynavfailblocked" ), DEFINE_KEYFIELD( m_bNeverLeavePlayerSquad, FIELD_BOOLEAN, "neverleaveplayersquad" ), DEFINE_KEYFIELD( m_iszDenyCommandConcept, FIELD_STRING, "denycommandconcept" ), +#ifdef MAPBASE + DEFINE_INPUT( m_bTossesMedkits, FIELD_BOOLEAN, "SetTossMedkits" ), + DEFINE_KEYFIELD( m_bAlternateAiming, FIELD_BOOLEAN, "AlternateAiming" ), +#endif DEFINE_OUTPUT( m_OnJoinedPlayerSquad, "OnJoinedPlayerSquad" ), DEFINE_OUTPUT( m_OnLeftPlayerSquad, "OnLeftPlayerSquad" ), @@ -342,11 +374,20 @@ BEGIN_DATADESC( CNPC_Citizen ) DEFINE_OUTPUT( m_OnStationOrder, "OnStationOrder" ), DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ), DEFINE_OUTPUT( m_OnNavFailBlocked, "OnNavFailBlocked" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnHealedNPC, "OnHealedNPC" ), + DEFINE_OUTPUT( m_OnHealedPlayer, "OnHealedPlayer" ), + DEFINE_OUTPUT( m_OnThrowMedkit, "OnTossMedkit" ), + DEFINE_OUTPUT( m_OnGiveAmmo, "OnGiveAmmo" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "RemoveFromPlayerSquad", InputRemoveFromPlayerSquad ), DEFINE_INPUTFUNC( FIELD_VOID, "StartPatrolling", InputStartPatrolling ), DEFINE_INPUTFUNC( FIELD_VOID, "StopPatrolling", InputStopPatrolling ), DEFINE_INPUTFUNC( FIELD_VOID, "SetCommandable", InputSetCommandable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "SetUnCommandable", InputSetUnCommandable ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "SetMedicOn", InputSetMedicOn ), DEFINE_INPUTFUNC( FIELD_VOID, "SetMedicOff", InputSetMedicOff ), DEFINE_INPUTFUNC( FIELD_VOID, "SetAmmoResupplierOn", InputSetAmmoResupplierOn ), @@ -357,11 +398,36 @@ BEGIN_DATADESC( CNPC_Citizen ) DEFINE_INPUTFUNC( FIELD_VOID, "ThrowHealthKit", InputForceHealthKitToss ), #endif +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetPoliceGoal", InputSetPoliceGoal ), +#endif + DEFINE_USEFUNC( CommanderUse ), DEFINE_USEFUNC( SimpleUse ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +ScriptHook_t CNPC_Citizen::g_Hook_SelectModel; + +BEGIN_ENT_SCRIPTDESC( CNPC_Citizen, CAI_BaseActor, "npc_citizen from Half-Life 2" ) + + DEFINE_SCRIPTFUNC( IsMedic, "Returns true if this citizen is a medic." ) + DEFINE_SCRIPTFUNC( IsAmmoResupplier, "Returns true if this citizen is an ammo resupplier." ) + DEFINE_SCRIPTFUNC( CanHeal, "Returns true if this citizen is a medic or ammo resupplier currently able to heal/give ammo." ) + + DEFINE_SCRIPTFUNC( GetCitizenType, "Gets the citizen's type. 1 = Downtrodden, 2 = Refugee, 3 = Rebel, 4 = Unique" ) + DEFINE_SCRIPTFUNC( SetCitizenType, "Sets the citizen's type. 1 = Downtrodden, 2 = Refugee, 3 = Rebel, 4 = Unique" ) + + BEGIN_SCRIPTHOOK( CNPC_Citizen::g_Hook_SelectModel, "SelectModel", FIELD_CSTRING, "Called when a citizen is selecting a random model. 'model_path' is the directory of the selected model and 'model_head' is the name. The 'gender' parameter uses the 'GENDER_' constants and is based only on the citizen's random head spawnflags. If a full model path string is returned, it will be used as the model instead." ) + DEFINE_SCRIPTHOOK_PARAM( "model_path", FIELD_CSTRING ) + DEFINE_SCRIPTHOOK_PARAM( "model_head", FIELD_CSTRING ) + DEFINE_SCRIPTHOOK_PARAM( "gender", FIELD_INTEGER ) + END_SCRIPTHOOK() + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -373,7 +439,12 @@ CSimpleSimTimer CNPC_Citizen::gm_PlayerSquadEvaluateTimer; bool CNPC_Citizen::CreateBehaviors() { BaseClass::CreateBehaviors(); +#ifdef MAPBASE + AddBehavior( &m_RappelBehavior ); + AddBehavior( &m_PolicingBehavior ); +#else // Moved to CNPC_PlayerCompanion AddBehavior( &m_FuncTankBehavior ); +#endif return true; } @@ -382,7 +453,12 @@ bool CNPC_Citizen::CreateBehaviors() //----------------------------------------------------------------------------- void CNPC_Citizen::Precache() { +#ifdef MAPBASE + // CNPC_PlayerCompanion::Precache() is responsible for calling this now + BaseClass::Precache(); +#else SelectModel(); +#endif SelectExpressionType(); if ( !npc_citizen_dont_precache_all.GetBool() ) @@ -393,8 +469,6 @@ void CNPC_Citizen::Precache() if ( NameMatches( "matt" ) ) PrecacheModel( "models/props_canal/mattpipe.mdl" ); - PrecacheModel( INSIGNIA_MODEL ); - PrecacheScriptSound( "NPC_Citizen.FootstepLeft" ); PrecacheScriptSound( "NPC_Citizen.FootstepRight" ); PrecacheScriptSound( "NPC_Citizen.Die" ); @@ -419,7 +493,9 @@ void CNPC_Citizen::Precache() } } +#ifndef MAPBASE // See above BaseClass::Precache(); +#endif } //----------------------------------------------------------------------------- @@ -481,6 +557,26 @@ void CNPC_Citizen::Spawn() m_bShouldPatrol = false; m_iHealth = sk_citizen_health.GetFloat(); +#ifdef MAPBASE + // Now only gets citizen_trains. + if ( GetMoveParent() && FClassnameIs( GetMoveParent(), "func_tracktrain" ) ) + { + if ( NameMatches("citizen_train_2") ) + { + CapabilitiesRemove( bits_CAP_MOVE_GROUND ); + SetMoveType( MOVETYPE_NONE ); + SetSequenceByName( "d1_t01_TrainRide_Sit_Idle" ); + SetIdealActivity( ACT_DO_NOT_DISTURB ); + } + else if ( NameMatches("citizen_train_1") ) + { + CapabilitiesRemove( bits_CAP_MOVE_GROUND ); + SetMoveType( MOVETYPE_NONE ); + SetSequenceByName( "d1_t01_TrainRide_Stand" ); + SetIdealActivity( ACT_DO_NOT_DISTURB ); + } + } +#else // Are we on a train? Used in trainstation to have NPCs on trains. if ( GetMoveParent() && FClassnameIs( GetMoveParent(), "func_tracktrain" ) ) { @@ -497,6 +593,7 @@ void CNPC_Citizen::Spawn() SetIdealActivity( ACT_DO_NOT_DISTURB ); } } +#endif m_flStopManhackFlinch = -1; @@ -528,6 +625,13 @@ void CNPC_Citizen::Spawn() // Use render bounds instead of human hull for guys sitting in chairs, etc. m_ActBusyBehavior.SetUseRenderBounds( HasSpawnFlags( SF_CITIZEN_USE_RENDER_BOUNDS ) ); + +#ifdef MAPBASE + if (NameMatches("griggs")) + { + m_bTossesMedkits = true; + } +#endif } //----------------------------------------------------------------------------- @@ -589,6 +693,14 @@ void CNPC_Citizen::SelectModel() if ( m_Type == CT_DEFAULT ) { +#ifdef MAPBASE + if (HL2GameRules()->GetDefaultCitizenType() != CT_DEFAULT) + { + m_Type = static_cast(HL2GameRules()->GetDefaultCitizenType()); + } + else + { +#endif struct CitizenTypeMapping { const char *pszMapTag; @@ -621,6 +733,9 @@ void CNPC_Citizen::SelectModel() if ( m_Type == CT_DEFAULT ) m_Type = CT_DOWNTRODDEN; +#ifdef MAPBASE + } +#endif } if( HasSpawnFlags( SF_CITIZEN_RANDOM_HEAD | SF_CITIZEN_RANDOM_HEAD_MALE | SF_CITIZEN_RANDOM_HEAD_FEMALE ) || GetModelName() == NULL_STRING ) @@ -681,6 +796,54 @@ void CNPC_Citizen::SelectModel() pszModelName = g_ppszRandomHeads[m_iHead]; SetModelName(NULL_STRING); } + +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_SelectModel.CanRunInScope( m_ScriptScope )) + { + gender_t scriptGender; + switch (gender) + { + case 'm': + scriptGender = GENDER_MALE; + break; + case 'f': + scriptGender = GENDER_FEMALE; + break; + default: + scriptGender = GENDER_NONE; + break; + } + + const char *pszModelPath = CFmtStr( "models/Humans/%s/", (const char *)(CFmtStr( g_ppszModelLocs[m_Type], (IsMedic()) ? "m" : "" )) ); + + // model_path, model_head, gender + ScriptVariant_t args[] = { pszModelPath, pszModelName, (int)scriptGender }; + ScriptVariant_t returnValue = NULL; + g_Hook_SelectModel.Call( m_ScriptScope, &returnValue, args ); + + if (returnValue.m_type == FIELD_CSTRING && returnValue.m_pszString[0] != '\0') + { + // Refresh the head if it's different + const char *pszNewHead = strrchr( returnValue.m_pszString, '/' ); + if ( pszNewHead && Q_stricmp(pszNewHead+1, pszModelName) != 0 ) + { + pszNewHead++; + for ( int i = 0; i < ARRAYSIZE(g_ppszRandomHeads); i++ ) + { + if ( Q_stricmp( g_ppszRandomHeads[i], pszModelName ) == 0 ) + { + m_iHead = i; + break; + } + } + } + + // Just set the model right here + SetModelName( AllocPooledString( returnValue.m_pszString ) ); + return; + } + } +#endif } Assert( pszModelName || GetModelName() != NULL_STRING ); @@ -751,7 +914,11 @@ void CNPC_Citizen::SelectExpressionType() void CNPC_Citizen::FixupMattWeapon() { CBaseCombatWeapon *pWeapon = GetActiveWeapon(); +#ifdef MAPBASE + if ( pWeapon && EntIsClass( pWeapon, gm_isz_class_Crowbar ) && NameMatches( "matt" ) ) +#else if ( pWeapon && pWeapon->ClassMatches( "weapon_crowbar" ) && NameMatches( "matt" ) ) +#endif { Weapon_Drop( pWeapon ); UTIL_Remove( pWeapon ); @@ -1165,6 +1332,19 @@ int CNPC_Citizen::SelectFailSchedule( int failedSchedule, int failedTask, AI_Tas //----------------------------------------------------------------------------- int CNPC_Citizen::SelectSchedule() { +#ifdef MAPBASE + if ( IsWaitingToRappel() && BehaviorSelectSchedule() ) + { + return BaseClass::SelectSchedule(); + } + + if ( GetMoveType() == MOVETYPE_NONE && !Q_strncmp(STRING(GetEntityName()), "citizen_train_", 14) ) + { + // Only "sit on train" if we're a citizen_train_ + Assert( GetMoveParent() && FClassnameIs( GetMoveParent(), "func_tracktrain" ) ); + return SCHED_CITIZEN_SIT_ON_TRAIN; + } +#else // If we can't move, we're on a train, and should be sitting. if ( GetMoveType() == MOVETYPE_NONE ) { @@ -1173,13 +1353,23 @@ int CNPC_Citizen::SelectSchedule() Assert( GetMoveParent() && FClassnameIs( GetMoveParent(), "func_tracktrain" ) ); return SCHED_CITIZEN_SIT_ON_TRAIN; } +#endif +#ifdef MAPBASE + if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) ) + { + CWeaponRPG *pRPG = static_cast(GetActiveWeapon()); +#else CWeaponRPG *pRPG = dynamic_cast(GetActiveWeapon()); +#endif if ( pRPG && pRPG->IsGuiding() ) { DevMsg( "Citizen in select schedule but RPG is guiding?\n"); pRPG->StopGuiding(); } +#ifdef MAPBASE + } +#endif return BaseClass::SelectSchedule(); } @@ -1351,7 +1541,11 @@ int CNPC_Citizen::SelectScheduleRetrieveItem() // Been kicked out of the player squad since the time I located the health. ClearCondition( COND_HEALTH_ITEM_AVAILABLE ); } +#ifdef MAPBASE + else if ( m_FollowBehavior.GetFollowTarget() ) +#else else +#endif { CBaseEntity *pBase = FindHealthItem(m_FollowBehavior.GetFollowTarget()->GetAbsOrigin(), Vector( 120, 120, 120 ) ); CItem *pItem = dynamic_cast(pBase); @@ -1479,9 +1673,15 @@ int CNPC_Citizen::TranslateSchedule( int scheduleType ) case SCHED_RANGE_ATTACK1: // If we have an RPG, we use a custom schedule for it +#ifdef MAPBASE + if ( !IsMortar( GetEnemy() ) && GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) ) + { + if ( GetEnemy() && EntIsClass(GetEnemy(), gm_isz_class_Strider) ) +#else if ( !IsMortar( GetEnemy() ) && GetActiveWeapon() && FClassnameIs( GetActiveWeapon(), "weapon_rpg" ) ) { if ( GetEnemy() && GetEnemy()->ClassMatches( "npc_strider" ) ) +#endif { if (OccupyStrategySlotRange( SQUAD_SLOT_CITIZEN_RPG1, SQUAD_SLOT_CITIZEN_RPG2 ) ) { @@ -1494,14 +1694,21 @@ int CNPC_Citizen::TranslateSchedule( int scheduleType ) } else { +#ifndef MAPBASE // This has been disabled for now. CBasePlayer *pPlayer = AI_GetSinglePlayer(); +#ifdef MAPBASE + // Don't avoid player if notarget is on + if ( pPlayer && GetEnemy() && !(pPlayer->GetFlags() & FL_NOTARGET) && ( ( GetEnemy()->GetAbsOrigin() - +#else if ( pPlayer && GetEnemy() && ( ( GetEnemy()->GetAbsOrigin() - +#endif pPlayer->GetAbsOrigin() ).LengthSqr() < RPG_SAFE_DISTANCE * RPG_SAFE_DISTANCE ) ) { // Don't fire our RPG at an enemy too close to the player return SCHED_STANDOFF; } else +#endif { return SCHED_CITIZEN_RANGE_ATTACK1_RPG; } @@ -1591,10 +1798,16 @@ void CNPC_Citizen::StartTask( const Task_t *pTask ) break; } +#ifdef MAPBASE + SetSpeechTarget( GetTarget() ); +#endif Speak( TLK_HEAL ); } else if ( IsAmmoResupplier() ) { +#ifdef MAPBASE + SetSpeechTarget( GetTarget() ); +#endif Speak( TLK_GIVEAMMO ); } SetIdealActivity( (Activity)ACT_CIT_HEAL ); @@ -1767,13 +1980,20 @@ void CNPC_Citizen::RunTask( const Task_t *pTask ) } Vector vecEnemyPos = GetEnemy()->BodyTarget(GetAbsOrigin(), false); +#ifndef MAPBASE // This has been disabled for now. CBasePlayer *pPlayer = AI_GetSinglePlayer(); +#ifdef MAPBASE + // Don't avoid player if notarget is on + if ( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) && ( ( vecEnemyPos - pPlayer->GetAbsOrigin() ).LengthSqr() < RPG_SAFE_DISTANCE * RPG_SAFE_DISTANCE ) ) +#else if ( pPlayer && ( ( vecEnemyPos - pPlayer->GetAbsOrigin() ).LengthSqr() < RPG_SAFE_DISTANCE * RPG_SAFE_DISTANCE ) ) +#endif { m_bRPGAvoidPlayer = true; Speak( TLK_WATCHOUT ); } else +#endif { // Pull the laserdot towards the target Vector vecToTarget = (vecEnemyPos - vecLaserPos); @@ -1838,9 +2058,18 @@ Activity CNPC_Citizen::NPC_TranslateActivity( Activity activity ) { if ( activity == ACT_MELEE_ATTACK1 ) { +#ifdef MAPBASE + // It could be the new weapon punt activity. + if (GetActiveWeapon() && GetActiveWeapon()->IsMeleeWeapon()) + { + return ACT_MELEE_ATTACK_SWING; + } +#else return ACT_MELEE_ATTACK_SWING; +#endif } +#ifndef MAPBASE // Covered by the new backup activity system // !!!HACK - Citizens don't have the required animations for shotguns, // so trick them into using the rifle counterparts for now (sjb) if ( activity == ACT_RUN_AIM_SHOTGUN ) @@ -1851,6 +2080,29 @@ Activity CNPC_Citizen::NPC_TranslateActivity( Activity activity ) return ACT_IDLE_ANGRY_SMG1; if ( activity == ACT_RANGE_ATTACK_SHOTGUN_LOW ) return ACT_RANGE_ATTACK_SMG1_LOW; +#endif + +#ifdef MAPBASE + if (m_bAlternateAiming) + { + if (activity == ACT_RUN_AIM_RIFLE) + return ACT_RUN_AIM_RIFLE_STIMULATED; + if (activity == ACT_WALK_AIM_RIFLE) + return ACT_WALK_AIM_RIFLE_STIMULATED; + + if (activity == ACT_RUN_AIM_AR2) + return ACT_RUN_AIM_AR2_STIMULATED; + if (activity == ACT_WALK_AIM_AR2) + return ACT_WALK_AIM_AR2_STIMULATED; + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + if (activity == ACT_RUN_AIM_PISTOL) + return ACT_RUN_AIM_PISTOL_STIMULATED; + if (activity == ACT_WALK_AIM_PISTOL) + return ACT_WALK_AIM_PISTOL_STIMULATED; +#endif + } +#endif return BaseClass::NPC_TranslateActivity( activity ); } @@ -1878,7 +2130,12 @@ void CNPC_Citizen::HandleAnimEvent( animevent_t *pEvent ) { // Heal my target (if within range) #if HL2_EPISODIC +#ifdef MAPBASE + // Don't throw medkits at NPCs, that's not how it works + if ( USE_EXPERIMENTAL_MEDIC_CODE() && IsMedic() && GetTarget() && !GetTarget()->IsNPC() ) +#else if ( USE_EXPERIMENTAL_MEDIC_CODE() && IsMedic() ) +#endif { CBaseCombatCharacter *pTarget = dynamic_cast( GetTarget() ); Assert(pTarget); @@ -1918,6 +2175,7 @@ void CNPC_Citizen::HandleAnimEvent( animevent_t *pEvent ) } } +#ifndef MAPBASE // Moved to CAI_BaseNPC //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void CNPC_Citizen::PickupItem( CBaseEntity *pItem ) @@ -1944,6 +2202,7 @@ void CNPC_Citizen::PickupItem( CBaseEntity *pItem ) DevMsg("Citizen doesn't know how to pick up %s!\n", pItem->GetClassname() ); } } +#endif //----------------------------------------------------------------------------- // Purpose: @@ -2092,7 +2351,12 @@ bool CNPC_Citizen::IsManhackMeleeCombatant() { CBaseCombatWeapon *pWeapon = GetActiveWeapon(); CBaseEntity *pEnemy = GetEnemy(); +#ifdef MAPBASE + // Any melee weapon passes + return ( pEnemy && pWeapon && pEnemy->Classify() == CLASS_MANHACK && pWeapon->IsMeleeWeapon() ); +#else return ( pEnemy && pWeapon && pEnemy->Classify() == CLASS_MANHACK && pWeapon->ClassMatches( "weapon_crowbar" ) ); +#endif } //----------------------------------------------------------------------------- @@ -2103,6 +2367,14 @@ Vector CNPC_Citizen::GetActualShootPosition( const Vector &shootOrigin ) { Vector vecTarget = BaseClass::GetActualShootPosition( shootOrigin ); +#ifdef MAPBASE + // The gunship RPG code does not appear to be funcitonal, so only set the laser position. + if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_RPG) && GetEnemy() ) + { + CWeaponRPG *pRPG = static_cast(GetActiveWeapon()); + pRPG->SetNPCLaserPosition( vecTarget ); + } +#else CWeaponRPG *pRPG = dynamic_cast(GetActiveWeapon()); // If we're firing an RPG at a gunship, aim off to it's side, because we'll auger towards it. if ( pRPG && GetEnemy() ) @@ -2142,8 +2414,8 @@ Vector CNPC_Citizen::GetActualShootPosition( const Vector &shootOrigin ) { pRPG->SetNPCLaserPosition( vecTarget ); } - } +#endif return vecTarget; } @@ -2194,19 +2466,31 @@ bool CNPC_Citizen::ShouldLookForBetterWeapon() { bool bDefer = false; +#ifdef MAPBASE + if ( EntIsClass(pWeapon, gm_isz_class_AR2) ) +#else if( FClassnameIs( pWeapon, "weapon_ar2" ) ) +#endif { // Content to keep this weapon forever m_flNextWeaponSearchTime = OTHER_DEFER_SEARCH_TIME; bDefer = true; } +#ifdef MAPBASE + else if( EntIsClass(pWeapon, gm_isz_class_RPG) ) +#else else if( FClassnameIs( pWeapon, "weapon_rpg" ) ) +#endif { // Content to keep this weapon forever m_flNextWeaponSearchTime = OTHER_DEFER_SEARCH_TIME; bDefer = true; } +#ifdef MAPBASE + else if ( EntIsClass(pWeapon, gm_isz_class_Shotgun) ) +#else else if( FClassnameIs( pWeapon, "weapon_shotgun" ) ) +#endif { // Shotgunners do not defer their weapon search indefinitely. // If more than one citizen in the squad has a shotgun, we force @@ -2294,6 +2578,20 @@ int CNPC_Citizen::OnTakeDamage_Alive( const CTakeDamageInfo &info ) return BaseClass::OnTakeDamage_Alive( newInfo ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_Citizen::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); + + // No need to tell me. + set.AppendCriteria("medic", IsMedic() ? "1" : "0"); + + set.AppendCriteria("citizentype", UTIL_VarArgs("%i", m_Type)); +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool CNPC_Citizen::IsCommandable() @@ -2337,6 +2635,11 @@ bool CNPC_Citizen::CanJoinPlayerSquad() if ( IRelationType( UTIL_GetLocalPlayer() ) != D_LI ) return false; +#ifdef MAPBASE + if ( IsWaitingToRappel() ) + return false; +#endif + return true; } @@ -2501,9 +2804,9 @@ bool CNPC_Citizen::IsValidCommandTarget( CBaseEntity *pTarget ) } //----------------------------------------------------------------------------- -bool CNPC_Citizen::SpeakCommandResponse( AIConcept_t concept, const char *modifiers ) +bool CNPC_Citizen::SpeakCommandResponse( AIConcept_t conceptId, const char *modifiers ) { - return SpeakIfAllowed( concept, + return SpeakIfAllowed( conceptId, CFmtStr( "numselected:%d," "useradio:%d%s", ( GetSquad() ) ? GetSquad()->NumMembers() : 1, @@ -2511,6 +2814,64 @@ bool CNPC_Citizen::SpeakCommandResponse( AIConcept_t concept, const char *modifi ( modifiers ) ? CFmtStr(",%s", modifiers).operator const char *() : "" ) ); } +#ifdef MAPBASE +extern ConVar ai_debug_avoidancebounds; + +//----------------------------------------------------------------------------- +// Purpose: Implements player nocollide. +//----------------------------------------------------------------------------- +void CNPC_Citizen::SetPlayerAvoidState( void ) +{ + bool bShouldPlayerAvoid = false; + Vector vNothing; + + GetSequenceLinearMotion( GetSequence(), &vNothing ); + bool bIsMoving = ( IsMoving() || ( vNothing != vec3_origin ) ); + + m_bPlayerAvoidState = ShouldPlayerAvoid(); + bool bSquadNoCollide = (IsInPlayerSquad() && npc_citizen_nocollide_player.GetBool()); + + // If we are coming out of a script, check if we are stuck inside the player. + if ( m_bPerformAvoidance || ( m_bPlayerAvoidState && bIsMoving ) || bSquadNoCollide ) + { + trace_t trace; + Vector vMins, vMaxs; + + GetPlayerAvoidBounds( &vMins, &vMaxs ); + + CBasePlayer *pLocalPlayer = AI_GetSinglePlayer(); + + if ( pLocalPlayer ) + { + bShouldPlayerAvoid = (!bSquadNoCollide || !pLocalPlayer->IsMoving()) && IsBoxIntersectingBox( GetAbsOrigin() + vMins, GetAbsOrigin() + vMaxs, + pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMins(), pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMaxs() ); + } + + if ( ai_debug_avoidancebounds.GetBool() ) + { + int iRed = ( bShouldPlayerAvoid == true ) ? 255 : 0; + + NDebugOverlay::Box( GetAbsOrigin(), vMins, vMaxs, iRed, 0, 255, 64, 0.1 ); + } + } + + m_bPerformAvoidance = bShouldPlayerAvoid; + + if ( GetCollisionGroup() == COLLISION_GROUP_NPC || GetCollisionGroup() == COLLISION_GROUP_NPC_ACTOR ) + { + if ( m_bPerformAvoidance == true || + (bSquadNoCollide && !m_bPlayerAvoidState)) + { + SetCollisionGroup( COLLISION_GROUP_NPC_ACTOR ); + } + else + { + SetCollisionGroup( COLLISION_GROUP_NPC ); + } + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: return TRUE if the commander mode should try to give this order // to more people. return FALSE otherwise. For instance, we don't @@ -2553,7 +2914,11 @@ void CNPC_Citizen::MoveOrder( const Vector &vecDest, CAI_BaseNPC **Allies, int n if ( !AI_IsSinglePlayer() ) return; +#ifdef MAPBASE + if ( m_iszDenyCommandConcept != NULL_STRING ) +#else if( hl2_episodic.GetBool() && m_iszDenyCommandConcept != NULL_STRING ) +#endif { SpeakCommandResponse( STRING(m_iszDenyCommandConcept) ); return; @@ -2635,6 +3000,28 @@ void CNPC_Citizen::OnMoveOrder() BaseClass::OnMoveOrder(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline bool CNPC_Citizen::ShouldAllowSquadToggleUse( CBasePlayer *pPlayer ) +{ + if (HasSpawnFlags( SF_CITIZEN_NOT_COMMANDABLE )) + return false; + + //if (!HL2GameRules() || !HL2GameRules()->AllowSquadToggleUse()) + if (!HasSpawnFlags( SF_CITIZEN_PLAYER_TOGGLE_SQUAD )) + { + if (!npc_citizen_squad_secondary_toggle_use_always.GetBool() || m_bNeverLeavePlayerSquad) + return false; + + // npc_citizen_squad_secondary_toggle_use_always was invoked + AddSpawnFlags( SF_CITIZEN_PLAYER_TOGGLE_SQUAD ); + } + + return (pPlayer->m_nButtons & npc_citizen_squad_secondary_toggle_use_button.GetInt()) != 0; +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Citizen::CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) @@ -2654,6 +3041,31 @@ void CNPC_Citizen::CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, // Don't say hi after you've been addressed by the player SetSpokeConcept( TLK_HELLO, NULL ); +#ifdef MAPBASE + if ( ShouldAllowSquadToggleUse(UTIL_GetLocalPlayer()) || npc_citizen_auto_player_squad_allow_use.GetBool() ) + { + // Version of TogglePlayerSquadState() that has "used" as a modifier + static const char *szSquadUseModifier = "used:1"; + if ( !IsInPlayerSquad() ) + { + AddToPlayerSquad(); + + if ( HaveCommandGoal() ) + { + SpeakCommandResponse( TLK_COMMANDED, szSquadUseModifier ); + } + else if ( m_FollowBehavior.GetFollowTarget() == UTIL_GetLocalPlayer() ) + { + SpeakCommandResponse( TLK_STARTFOLLOW, szSquadUseModifier ); + } + } + else + { + SpeakCommandResponse( TLK_STOPFOLLOW, szSquadUseModifier ); + RemoveFromPlayerSquad(); + } + } +#else if ( npc_citizen_auto_player_squad_allow_use.GetBool() ) { if ( !ShouldAutosquad() ) @@ -2661,8 +3073,37 @@ void CNPC_Citizen::CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, else if ( !IsInPlayerSquad() && npc_citizen_auto_player_squad_allow_use.GetBool() ) AddToPlayerSquad(); } +#endif else if ( GetCurSchedule() && ConditionInterruptsCurSchedule( COND_IDLE_INTERRUPT ) ) { +#ifdef MAPBASE + // Just do regular idle question behavior so question groups, etc. work on +USE. + if ( IsAllowedToSpeak( TLK_QUESTION, true ) ) + { + // 1 = Old "SpeakIdleResponse" behavior + // 2, 3 = AskQuestion() for QA groups, etc. + // 4 = Just speak + int iRandom = random->RandomInt(1, 4); + if ( iRandom == 1 ) + { + CBaseEntity *pRespondant = FindSpeechTarget( AIST_NPCS ); + if ( pRespondant ) + { + g_EventQueue.AddEvent( pRespondant, "SpeakIdleResponse", ( GetTimeSpeechComplete() - gpGlobals->curtime ) + .2, this, this ); + } + } + if ( iRandom < 4 ) + { + // Ask someone else + AskQuestionNow(); + } + else + { + // Just speak + Speak( TLK_QUESTION ); + } + } +#else if ( SpeakIfAllowed( TLK_QUESTION, NULL, true ) ) { if ( random->RandomInt( 1, 4 ) < 4 ) @@ -2674,6 +3115,7 @@ void CNPC_Citizen::CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, } } } +#endif } } } @@ -2883,6 +3325,11 @@ void CNPC_Citizen::UpdatePlayerSquad() if ( !pCitizen->CanJoinPlayerSquad() ) continue; +#ifdef MAPBASE + if ( pCitizen->HasSpawnFlags(SF_CITIZEN_PLAYER_TOGGLE_SQUAD) ) + continue; +#endif + bool bShouldAdd = false; if ( pCitizen->HasCondition( COND_SEE_PLAYER ) ) @@ -2940,7 +3387,11 @@ void CNPC_Citizen::UpdatePlayerSquad() if ( ppAIs[j]->GetClassname() != GetClassname() ) continue; +#ifdef MAPBASE + if ( ppAIs[j]->HasSpawnFlags( SF_CITIZEN_NOT_COMMANDABLE | SF_CITIZEN_PLAYER_TOGGLE_SQUAD ) ) +#else if ( ppAIs[j]->HasSpawnFlags( SF_CITIZEN_NOT_COMMANDABLE ) ) +#endif continue; CNPC_Citizen *pCitizen = assert_cast(ppAIs[j]); @@ -3415,7 +3866,11 @@ bool CNPC_Citizen::ShouldHealTarget( CBaseEntity *pTarget, bool bActiveUse ) { Disposition_t disposition; +#ifdef MAPBASE + if ( pTarget && ( ( disposition = IRelationType( pTarget ) ) != D_LI && disposition != D_NU ) ) +#else if ( !pTarget && ( ( disposition = IRelationType( pTarget ) ) != D_LI && disposition != D_NU ) ) +#endif return false; // Don't heal if I'm in the middle of talking @@ -3497,6 +3952,14 @@ bool CNPC_Citizen::ShouldHealTarget( CBaseEntity *pTarget, bool bActiveUse ) if ( ((CBasePlayer*)pTarget)->Weapon_GetWpnForAmmo( iAmmoType ) ) return true; } +#ifdef MAPBASE + else if ( (iMax - iCount) < m_iAmmoAmount && (iMax - iCount) != 0 ) + { + // If we're allowed to adjust our ammo, the amount of ammo we give may be reduced, but that's better than not giving any at all! + if (npc_citizen_resupplier_adjust_ammo.GetBool() == true && ((CBasePlayer*)pTarget)->Weapon_GetWpnForAmmo( iAmmoType )) + return true; + } +#endif } } } @@ -3515,14 +3978,25 @@ bool CNPC_Citizen::ShouldHealTossTarget( CBaseEntity *pTarget, bool bActiveUse ) if ( !IsMedic() ) return false; +#ifdef MAPBASE + if ( pTarget && ( ( disposition = IRelationType( pTarget ) ) != D_LI && disposition != D_NU ) ) +#else if ( !pTarget && ( ( disposition = IRelationType( pTarget ) ) != D_LI && disposition != D_NU ) ) +#endif return false; // Don't heal if I'm in the middle of talking if ( IsSpeaking() ) return false; +#ifdef MAPBASE + // NPCs cannot be healed by throwing medkits at them. + // I don't think NPCs even pass through this function anyway, it's just the actual heal event that's the problem. + if (!pTarget->IsPlayer()) + return false; +#else bool bTargetIsPlayer = pTarget->IsPlayer(); +#endif // Don't heal or give ammo to targets in vehicles CBaseCombatCharacter *pCCTarget = pTarget->MyCombatCharacterPointer(); @@ -3550,18 +4024,26 @@ bool CNPC_Citizen::ShouldHealTossTarget( CBaseEntity *pTarget, bool bActiveUse ) } // Are we ready to heal again? +#ifdef MAPBASE + bool bReadyToHeal = m_flPlayerHealTime <= gpGlobals->curtime; +#else bool bReadyToHeal = ( ( bTargetIsPlayer && m_flPlayerHealTime <= gpGlobals->curtime ) || ( !bTargetIsPlayer && m_flAllyHealTime <= gpGlobals->curtime ) ); +#endif // Only heal if we're ready if ( bReadyToHeal ) { int requiredHealth; +#ifdef MAPBASE + requiredHealth = pTarget->GetMaxHealth() - sk_citizen_heal_player.GetFloat(); +#else if ( bTargetIsPlayer ) requiredHealth = pTarget->GetMaxHealth() - sk_citizen_heal_player.GetFloat(); else requiredHealth = pTarget->GetMaxHealth() * sk_citizen_heal_player_min_pct.GetFloat(); +#endif if ( ( pTarget->m_iHealth <= requiredHealth ) && IRelationType( pTarget ) == D_LI ) return true; @@ -3583,6 +4065,11 @@ void CNPC_Citizen::Heal() CBaseEntity *pTarget = GetTarget(); +#ifdef MAPBASE + if ( !pTarget ) + return; +#endif + Vector target = pTarget->GetAbsOrigin() - GetAbsOrigin(); if ( target.Length() > HEAL_TARGET_RANGE * 2 ) return; @@ -3625,6 +4112,10 @@ void CNPC_Citizen::Heal() EmitSound( filter, pTarget->entindex(), "HealthKit.Touch" ); } +#ifdef MAPBASE + pTarget->IsPlayer() ? m_OnHealedPlayer.FireOutput(pTarget, this) : m_OnHealedNPC.FireOutput(pTarget, this); +#endif + pTarget->TakeHealth( healAmt, DMG_GENERIC ); pTarget->RemoveAllDecals(); } @@ -3643,6 +4134,10 @@ void CNPC_Citizen::Heal() else { ((CBasePlayer*)pTarget)->GiveAmmo( m_iAmmoAmount, iAmmoType, false ); + +#ifdef MAPBASE + m_OnGiveAmmo.FireOutput(pTarget, this); +#endif } m_flPlayerGiveAmmoTime = gpGlobals->curtime + sk_citizen_giveammo_player_delay.GetFloat(); @@ -3715,6 +4210,10 @@ void CNPC_Citizen::TossHealthKit(CBaseCombatCharacter *pThrowAt, const Vector &o pPhysicsObject->SetVelocity( &tossVelocity, &angDummy ); } } + +#ifdef MAPBASE + m_OnThrowMedkit.Set(pHealthKit, pHealthKit, this); +#endif } else { @@ -3790,6 +4289,16 @@ void CNPC_Citizen::InputSetCommandable( inputdata_t &inputdata ) gm_PlayerSquadEvaluateTimer.Force(); } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void CNPC_Citizen::InputSetUnCommandable( inputdata_t &inputdata ) +{ + AddSpawnFlags( SF_CITIZEN_NOT_COMMANDABLE ); + RemoveFromPlayerSquad(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : &inputdata - @@ -3833,6 +4342,39 @@ void CNPC_Citizen::InputSpeakIdleResponse( inputdata_t &inputdata ) SpeakIfAllowed( TLK_ANSWER, NULL, true ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_Citizen::InputSetPoliceGoal( inputdata_t &inputdata ) +{ + if (/*!inputdata.value.String() ||*/ inputdata.value.String()[0] == 0) + { + m_PolicingBehavior.Disable(); + return; + } + + CBaseEntity *pGoal = gEntList.FindEntityByName( NULL, inputdata.value.String() ); + + if ( pGoal == NULL ) + { + DevMsg( "SetPoliceGoal: %s (%s) unable to find ai_goal_police: %s\n", GetClassname(), GetDebugName(), inputdata.value.String() ); + return; + } + + CAI_PoliceGoal *pPoliceGoal = dynamic_cast(pGoal); + + if ( pPoliceGoal == NULL ) + { + DevMsg( "SetPoliceGoal: %s (%s)'s target %s is not an ai_goal_police entity!\n", GetClassname(), GetDebugName(), inputdata.value.String() ); + return; + } + + m_PolicingBehavior.Enable( pPoliceGoal ); +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Citizen::DeathSound( const CTakeDamageInfo &info ) @@ -3840,7 +4382,13 @@ void CNPC_Citizen::DeathSound( const CTakeDamageInfo &info ) // Sentences don't play on dead NPCs SentenceStop(); +#ifdef MAPBASE + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + Speak( TLK_DEATH, set ); +#else EmitSound( "NPC_Citizen.Die" ); +#endif } //------------------------------------------------------------------------------ @@ -4197,6 +4745,8 @@ void CNPC_Citizen::AddInsignia() void CNPC_Citizen::RemoveInsignia() { + // This is crap right now. + CBaseEntity *FirstEnt(); CBaseEntity *pEntity = gEntList.FirstEnt(); while( pEntity ) @@ -4242,6 +4792,12 @@ void CSquadInsignia::Spawn() SetSolid( SOLID_NONE ); } +void CSquadInsignia::Precache() +{ + BaseClass::Precache(); + PrecacheModel( INSIGNIA_MODEL ); +} + //----------------------------------------------------------------------------- // Purpose: Draw any debug text overlays // Input : diff --git a/game/server/hl2/npc_citizen17.h b/game/server/hl2/npc_citizen17.h index 49efbc7a..760e9c19 100644 --- a/game/server/hl2/npc_citizen17.h +++ b/game/server/hl2/npc_citizen17.h @@ -11,6 +11,10 @@ #include "npc_playercompanion.h" #include "ai_behavior_functank.h" +#ifdef MAPBASE +#include "ai_behavior_rappel.h" +#include "ai_behavior_police.h" +#endif struct SquadCandidate_t; @@ -33,6 +37,9 @@ struct SquadCandidate_t; #define SF_CITIZEN_RANDOM_HEAD_MALE ( 1 << 22 ) //4194304 #define SF_CITIZEN_RANDOM_HEAD_FEMALE ( 1 << 23 )//8388608 #define SF_CITIZEN_USE_RENDER_BOUNDS ( 1 << 24 )//16777216 +#ifdef MAPBASE +#define SF_CITIZEN_PLAYER_TOGGLE_SQUAD ( 1 << 25 ) //33554432 Prevents the citizen from joining the squad automatically, but still being commandable if the player toggles it +#endif //------------------------------------- // Animation events @@ -130,7 +137,9 @@ class CNPC_Citizen : public CNPC_PlayerCompanion void HandleAnimEvent( animevent_t *pEvent ); void TaskFail( AI_TaskFailureCode_t code ); +#ifndef MAPBASE // Moved to CAI_BaseNPC void PickupItem( CBaseEntity *pItem ); +#endif void SimpleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); @@ -161,6 +170,11 @@ class CNPC_Citizen : public CNPC_PlayerCompanion // Damage handling //--------------------------------- int OnTakeDamage_Alive( const CTakeDamageInfo &info ); + +#ifdef MAPBASE + //--------------------------------- + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); +#endif //--------------------------------- // Commander mode @@ -179,6 +193,9 @@ class CNPC_Citizen : public CNPC_PlayerCompanion void MoveOrder( const Vector &vecDest, CAI_BaseNPC **Allies, int numAllies ); void OnMoveOrder(); void CommanderUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); +#ifdef MAPBASE + bool ShouldAllowSquadToggleUse( CBasePlayer *pPlayer ); +#endif bool ShouldSpeakRadio( CBaseEntity *pListener ); void OnMoveToCommandGoalFailed(); void AddToPlayerSquad(); @@ -194,7 +211,11 @@ class CNPC_Citizen : public CNPC_PlayerCompanion void SetSquad( CAI_Squad *pSquad ); void AddInsignia(); void RemoveInsignia(); - bool SpeakCommandResponse( AIConcept_t concept, const char *modifiers = NULL ); + bool SpeakCommandResponse( AIConcept_t conceptId, const char *modifiers = NULL ); + +#ifdef MAPBASE + virtual void SetPlayerAvoidState( void ); +#endif //--------------------------------- // Scanner interaction @@ -235,11 +256,17 @@ class CNPC_Citizen : public CNPC_PlayerCompanion void InputStartPatrolling( inputdata_t &inputdata ); void InputStopPatrolling( inputdata_t &inputdata ); void InputSetCommandable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetUnCommandable( inputdata_t &inputdata ); +#endif void InputSetMedicOn( inputdata_t &inputdata ); void InputSetMedicOff( inputdata_t &inputdata ); void InputSetAmmoResupplierOn( inputdata_t &inputdata ); void InputSetAmmoResupplierOff( inputdata_t &inputdata ); void InputSpeakIdleResponse( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetPoliceGoal( inputdata_t &inputdata ); +#endif //--------------------------------- // Sounds & speech @@ -250,6 +277,11 @@ class CNPC_Citizen : public CNPC_PlayerCompanion virtual void OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior ); +#ifdef MAPBASE + int GetCitizenType() { return (int)m_Type; } + void SetCitizenType( int iType ) { m_Type = (CitizenType_t)iType; } +#endif + private: //----------------------------------------------------- // Conditions, Schedules, Tasks @@ -303,6 +335,10 @@ class CNPC_Citizen : public CNPC_PlayerCompanion bool m_bWasInPlayerSquad; float m_flTimeLastCloseToPlayer; string_t m_iszDenyCommandConcept; +#ifdef MAPBASE + bool m_bTossesMedkits; + bool m_bAlternateAiming; +#endif CSimpleSimTimer m_AutoSummonTimer; Vector m_vAutoSummonAnchor; @@ -326,9 +362,24 @@ class CNPC_Citizen : public CNPC_PlayerCompanion COutputEvent m_OnStationOrder; COutputEvent m_OnPlayerUse; COutputEvent m_OnNavFailBlocked; +#ifdef MAPBASE + COutputEvent m_OnHealedNPC; + COutputEvent m_OnHealedPlayer; + COutputEHANDLE m_OnThrowMedkit; + COutputEvent m_OnGiveAmmo; +#endif //----------------------------------------------------- +#ifdef MAPBASE + CAI_RappelBehavior m_RappelBehavior; + CAI_PolicingBehavior m_PolicingBehavior; + + // Rappel + virtual bool IsWaitingToRappel( void ) { return m_RappelBehavior.IsWaitingToRappel(); } + void BeginRappel() { m_RappelBehavior.BeginRappel(); } +#else // Moved to CNPC_PlayerCompanion CAI_FuncTankBehavior m_FuncTankBehavior; +#endif CHandle m_hSavedFollowGoalEnt; @@ -337,6 +388,10 @@ class CNPC_Citizen : public CNPC_PlayerCompanion //----------------------------------------------------- +#ifdef MAPBASE_VSCRIPT + static ScriptHook_t g_Hook_SelectModel; + DECLARE_ENT_SCRIPTDESC(); +#endif DECLARE_DATADESC(); #ifdef _XBOX protected: @@ -415,6 +470,7 @@ class CSquadInsignia : public CBaseAnimating { DECLARE_CLASS( CSquadInsignia, CBaseAnimating ); void Spawn(); + void Precache(); }; //------------------------------------- diff --git a/game/server/hl2/npc_combine.cpp b/game/server/hl2/npc_combine.cpp index 09cae88a..bdab56af 100644 --- a/game/server/hl2/npc_combine.cpp +++ b/game/server/hl2/npc_combine.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -29,23 +29,41 @@ #include "weapon_physcannon.h" #include "SoundEmitterSystem/isoundemittersystembase.h" #include "npc_headcrab.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#include "globalstate.h" +#include "sceneentity.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" int g_fCombineQuestion; // true if an idle grunt asked a question. Cleared when someone answers. YUCK old global from grunt code +#ifdef MAPBASE +ConVar npc_combine_idle_walk_easy( "npc_combine_idle_walk_easy", "1", FCVAR_NONE, "Mapbase: Allows Combine soldiers to use ACT_WALK_EASY as a walking animation when idle." ); +ConVar npc_combine_unarmed_anims( "npc_combine_unarmed_anims", "1", FCVAR_NONE, "Mapbase: Allows Combine soldiers to use unarmed idle/walk animations when they have no weapon." ); +ConVar npc_combine_protected_run( "npc_combine_protected_run", "0", FCVAR_NONE, "Mapbase: Allows Combine soldiers to use \"protected run\" animations." ); +ConVar npc_combine_altfire_not_allies_only( "npc_combine_altfire_not_allies_only", "1", FCVAR_NONE, "Mapbase: Elites are normally only allowed to fire their alt-fire attack at the player and the player's allies; This allows elites to alt-fire at other enemies too." ); + +ConVar npc_combine_new_cover_behavior( "npc_combine_new_cover_behavior", "1", FCVAR_NONE, "Mapbase: Toggles small patches for parts of npc_combine AI related to soldiers failing to take cover. These patches are minimal and only change cases where npc_combine would otherwise look at an enemy without shooting or run up to the player to melee attack when they don't have to. Consult the Mapbase wiki for more information." ); +#endif + #define COMBINE_SKIN_DEFAULT 0 #define COMBINE_SKIN_SHOTGUNNER 1 +#ifndef MAPBASE #define COMBINE_GRENADE_THROW_SPEED 650 #define COMBINE_GRENADE_TIMER 3.5 #define COMBINE_GRENADE_FLUSH_TIME 3.0 // Don't try to flush an enemy who has been out of sight for longer than this. #define COMBINE_GRENADE_FLUSH_DIST 256.0 // Don't try to flush an enemy who has moved farther than this distance from the last place I saw him. +#endif #define COMBINE_LIMP_HEALTH 20 +#ifndef MAPBASE #define COMBINE_MIN_GRENADE_CLEAR_DIST 250 +#endif #define COMBINE_EYE_STANDING_POSITION Vector( 0, 0, 66 ) #define COMBINE_GUN_STANDING_POSITION Vector( 0, 0, 57 ) @@ -60,7 +78,11 @@ int g_fCombineQuestion; // true if an idle grunt asked a question. Cleared wh //----------------------------------------------------------------------------- // This is the index to the name of the shotgun's classname in the string pool // so that we can get away with an integer compare rather than a string compare. +#ifdef MAPBASE +#define s_iszShotgunClassname gm_isz_class_Shotgun +#else string_t s_iszShotgunClassname; +#endif //----------------------------------------------------------------------------- // Interactions @@ -73,13 +95,17 @@ int g_interactionCombineBash = 0; // melee bash attack #define COMBINE_AE_RELOAD ( 2 ) #define COMBINE_AE_KICK ( 3 ) #define COMBINE_AE_AIM ( 4 ) +#ifndef MAPBASE #define COMBINE_AE_GREN_TOSS ( 7 ) +#endif #define COMBINE_AE_GREN_LAUNCH ( 8 ) #define COMBINE_AE_GREN_DROP ( 9 ) #define COMBINE_AE_CAUGHT_ENEMY ( 10) // grunt established sight with an enemy (player only) that had previously eluded the squad. +#ifndef MAPBASE int COMBINE_AE_BEGIN_ALTFIRE; int COMBINE_AE_ALTFIRE; +#endif //========================================================= // Combine activities @@ -91,18 +117,27 @@ int COMBINE_AE_ALTFIRE; //Activity ACT_COMBINE_WALKING_AR2; //Activity ACT_COMBINE_STANDING_SHOTGUN; //Activity ACT_COMBINE_CROUCHING_SHOTGUN; +#if !SHARED_COMBINE_ACTIVITIES Activity ACT_COMBINE_THROW_GRENADE; +#endif Activity ACT_COMBINE_LAUNCH_GRENADE; Activity ACT_COMBINE_BUGBAIT; +#if !SHARED_COMBINE_ACTIVITIES Activity ACT_COMBINE_AR2_ALTFIRE; +#endif Activity ACT_WALK_EASY; Activity ACT_WALK_MARCH; +#ifdef MAPBASE +Activity ACT_TURRET_CARRY_IDLE; +Activity ACT_TURRET_CARRY_WALK; +Activity ACT_TURRET_CARRY_RUN; +#endif // ----------------------------------------------- // > Squad slots // ----------------------------------------------- enum SquadSlot_T -{ +{ SQUAD_SLOT_GRENADE1 = LAST_SHARED_SQUADSLOT, SQUAD_SLOT_GRENADE2, SQUAD_SLOT_ATTACK_OCCLUDER, @@ -114,6 +149,9 @@ enum TacticalVariant_T TACTICAL_VARIANT_DEFAULT = 0, TACTICAL_VARIANT_PRESSURE_ENEMY, // Always try to close in on the player. TACTICAL_VARIANT_PRESSURE_ENEMY_UNTIL_CLOSE, // Act like VARIANT_PRESSURE_ENEMY, but go to VARIANT_DEFAULT once within 30 feet +#ifdef MAPBASE + TACTICAL_VARIANT_GRENADE_HAPPY, // Throw grenades as if you're fighting a turret +#endif }; enum PathfindingVariant_T @@ -135,20 +173,33 @@ BEGIN_DATADESC( CNPC_Combine ) DEFINE_FIELD( m_nKickDamage, FIELD_INTEGER ), DEFINE_FIELD( m_vecTossVelocity, FIELD_VECTOR ), +#ifndef MAPBASE DEFINE_FIELD( m_hForcedGrenadeTarget, FIELD_EHANDLE ), +#endif DEFINE_FIELD( m_bShouldPatrol, FIELD_BOOLEAN ), DEFINE_FIELD( m_bFirstEncounter, FIELD_BOOLEAN ), DEFINE_FIELD( m_flNextPainSoundTime, FIELD_TIME ), DEFINE_FIELD( m_flNextAlertSoundTime, FIELD_TIME ), +#ifndef MAPBASE DEFINE_FIELD( m_flNextGrenadeCheck, FIELD_TIME ), +#endif DEFINE_FIELD( m_flNextLostSoundTime, FIELD_TIME ), DEFINE_FIELD( m_flAlertPatrolTime, FIELD_TIME ), +#ifndef MAPBASE DEFINE_FIELD( m_flNextAltFireTime, FIELD_TIME ), +#endif DEFINE_FIELD( m_nShots, FIELD_INTEGER ), DEFINE_FIELD( m_flShotDelay, FIELD_FLOAT ), DEFINE_FIELD( m_flStopMoveShootTime, FIELD_TIME ), +#ifndef MAPBASE // See ai_grenade.h DEFINE_KEYFIELD( m_iNumGrenades, FIELD_INTEGER, "NumGrenades" ), +#else +DEFINE_INPUT( m_bUnderthrow, FIELD_BOOLEAN, "UnderthrowGrenades" ), +DEFINE_INPUT( m_bAlternateCapable, FIELD_BOOLEAN, "SetAlternateCapable" ), +#endif +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM DEFINE_EMBEDDED( m_Sentences ), +#endif // m_AssaultBehavior (auto saved by AI) // m_StandoffBehavior (auto saved by AI) @@ -167,11 +218,27 @@ DEFINE_INPUTFUNC( FIELD_STRING, "Assault", InputAssault ), DEFINE_INPUTFUNC( FIELD_VOID, "HitByBugbait", InputHitByBugbait ), +#ifndef MAPBASE DEFINE_INPUTFUNC( FIELD_STRING, "ThrowGrenadeAtTarget", InputThrowGrenadeAtTarget ), +#else +DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetElite", InputSetElite ), +DEFINE_INPUTFUNC( FIELD_VOID, "DropGrenade", InputDropGrenade ), + +DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTacticalVariant", InputSetTacticalVariant ), + +DEFINE_INPUTFUNC( FIELD_STRING, "SetPoliceGoal", InputSetPoliceGoal ), + +DEFINE_AIGRENADE_DATADESC() +#endif + +#ifndef MAPBASE DEFINE_FIELD( m_iLastAnimEventHandled, FIELD_INTEGER ), +#endif DEFINE_FIELD( m_fIsElite, FIELD_BOOLEAN ), +#ifndef MAPBASE DEFINE_FIELD( m_vecAltFireTarget, FIELD_VECTOR ), +#endif DEFINE_KEYFIELD( m_iTacticalVariant, FIELD_INTEGER, "tacticalvariant" ), DEFINE_KEYFIELD( m_iPathfindingVariant, FIELD_INTEGER, "pathfindingvariant" ), @@ -196,7 +263,9 @@ bool CNPC_Combine::CreateComponents() if ( !BaseClass::CreateComponents() ) return false; +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM m_Sentences.Init( this, "NPC_Combine.SentenceParameters" ); +#endif return true; } @@ -218,7 +287,7 @@ void CNPC_Combine::InputLookOn( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_Combine::InputStartPatrolling( inputdata_t &inputdata ) { @@ -226,7 +295,7 @@ void CNPC_Combine::InputStartPatrolling( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_Combine::InputStopPatrolling( inputdata_t &inputdata ) { @@ -234,7 +303,7 @@ void CNPC_Combine::InputStopPatrolling( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_Combine::InputAssault( inputdata_t &inputdata ) { @@ -249,10 +318,11 @@ void CNPC_Combine::InputHitByBugbait( inputdata_t &inputdata ) SetCondition( COND_COMBINE_HIT_BY_BUGBAIT ); } +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: Force the combine soldier to throw a grenade at the target // If I'm a combine elite, fire my combine ball at the target instead. -// Input : &inputdata - +// Input : &inputdata - //----------------------------------------------------------------------------- void CNPC_Combine::InputThrowGrenadeAtTarget( inputdata_t &inputdata ) { @@ -260,7 +330,11 @@ void CNPC_Combine::InputThrowGrenadeAtTarget( inputdata_t &inputdata ) if ( m_NPCState == NPC_STATE_SCRIPT && m_hCine ) return; +#ifdef MAPBASE + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), NULL, inputdata.pActivator, inputdata.pCaller ); +#endif if ( !pEntity ) { DevMsg("%s (%s) received ThrowGrenadeAtTarget input, but couldn't find target entity '%s'\n", GetClassname(), GetDebugName(), inputdata.value.String() ); @@ -272,6 +346,66 @@ void CNPC_Combine::InputThrowGrenadeAtTarget( inputdata_t &inputdata ) ClearSchedule( "Told to throw grenade via input" ); } +#endif + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Instant transformation of arsenal from grenades to energy balls, or vice versa +//----------------------------------------------------------------------------- +void CNPC_Combine::InputSetElite( inputdata_t &inputdata ) +{ + m_fIsElite = inputdata.value.Bool(); +} + +//----------------------------------------------------------------------------- +// We were told to drop a grenade +//----------------------------------------------------------------------------- +void CNPC_Combine::InputDropGrenade( inputdata_t &inputdata ) +{ + SetCondition( COND_COMBINE_DROP_GRENADE ); + + ClearSchedule( "Told to drop grenade via input" ); +} + +//----------------------------------------------------------------------------- +// Changes our tactical variant easily +//----------------------------------------------------------------------------- +void CNPC_Combine::InputSetTacticalVariant( inputdata_t &inputdata ) +{ + m_iTacticalVariant = inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_Combine::InputSetPoliceGoal( inputdata_t &inputdata ) +{ + if (/*!inputdata.value.String() ||*/ inputdata.value.String()[0] == 0) + { + m_PolicingBehavior.Disable(); + return; + } + + CBaseEntity *pGoal = gEntList.FindEntityByName( NULL, inputdata.value.String() ); + + if ( pGoal == NULL ) + { + DevMsg( "SetPoliceGoal: %s (%s) unable to find ai_goal_police: %s\n", GetClassname(), GetDebugName(), inputdata.value.String() ); + return; + } + + CAI_PoliceGoal *pPoliceGoal = dynamic_cast(pGoal); + + if ( pPoliceGoal == NULL ) + { + DevMsg( "SetPoliceGoal: %s (%s)'s target %s is not an ai_goal_police entity!\n", GetClassname(), GetDebugName(), inputdata.value.String() ); + return; + } + + m_PolicingBehavior.Enable( pPoliceGoal ); +} +#endif //----------------------------------------------------------------------------- // Purpose: @@ -283,7 +417,9 @@ void CNPC_Combine::Precache() PrecacheScriptSound( "NPC_Combine.GrenadeLaunch" ); PrecacheScriptSound( "NPC_Combine.WeaponBash" ); +#ifndef MAPBASE // Now that we use WeaponSound(SPECIAL1), this isn't necessary PrecacheScriptSound( "Weapon_CombineGuard.Special1" ); +#endif BaseClass::Precache(); } @@ -292,12 +428,14 @@ void CNPC_Combine::Precache() //----------------------------------------------------------------------------- void CNPC_Combine::Activate() { +#ifndef MAPBASE s_iszShotgunClassname = FindPooledString( "weapon_shotgun" ); +#endif BaseClass::Activate(); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -350,10 +488,18 @@ void CNPC_Combine::Spawn( void ) m_flNextAltFireTime = gpGlobals->curtime; NPCInit(); + +#ifdef MAPBASE + // This was moved from CalcWeaponProficiency() so soldiers don't change skin unnaturally and uncontrollably + if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_Shotgun) && m_nSkin != COMBINE_SKIN_SHOTGUNNER ) + { + m_nSkin = COMBINE_SKIN_SHOTGUNNER; + } +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_Combine::CreateBehaviors() @@ -364,6 +510,9 @@ bool CNPC_Combine::CreateBehaviors() AddBehavior( &m_StandoffBehavior ); AddBehavior( &m_FollowBehavior ); AddBehavior( &m_FuncTankBehavior ); +#ifdef MAPBASE + AddBehavior( &m_PolicingBehavior ); +#endif return BaseClass::CreateBehaviors(); } @@ -372,15 +521,17 @@ bool CNPC_Combine::CreateBehaviors() //----------------------------------------------------------------------------- void CNPC_Combine::PostNPCInit() { +#ifndef MAPBASE if( IsElite() ) { // Give a warning if a Combine Soldier is equipped with anything other than - // an AR2. + // an AR2. if( !GetActiveWeapon() || !FClassnameIs( GetActiveWeapon(), "weapon_ar2" ) ) { DevWarning("**Combine Elite Soldier MUST be equipped with AR2\n"); } } +#endif BaseClass::PostNPCInit(); } @@ -395,10 +546,15 @@ void CNPC_Combine::GatherConditions() if( GetState() == NPC_STATE_COMBAT ) { +#ifdef MAPBASE + // Don't override the standoff + if( IsCurSchedule( SCHED_COMBINE_WAIT_IN_COVER, false ) && !m_StandoffBehavior.IsActive() ) +#else if( IsCurSchedule( SCHED_COMBINE_WAIT_IN_COVER, false ) ) +#endif { // Soldiers that are standing around doing nothing poll for attack slots so - // that they can respond quickly when one comes available. If they can + // that they can respond quickly when one comes available. If they can // occupy a vacant attack slot, they do so. This holds the slot until their // schedule breaks and schedule selection runs again, essentially reserving this // slot. If they do not select an attack schedule, then they'll release the slot. @@ -421,14 +577,16 @@ void CNPC_Combine::GatherConditions() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_Combine::PrescheduleThink() { BaseClass::PrescheduleThink(); // Speak any queued sentences +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM m_Sentences.UpdateSentenceQueue(); +#endif if ( IsOnFire() ) { @@ -467,7 +625,7 @@ void CNPC_Combine::PrescheduleThink() } } - +#ifndef MAPBASE //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Combine::DelayAltFireAttack( float flDelay ) @@ -494,7 +652,11 @@ void CNPC_Combine::DelaySquadAltFireAttack( float flDelay ) { CNPC_Combine *pCombine = dynamic_cast(pSquadmate); +#ifdef MAPBASE + if( pCombine && pCombine->IsAltFireCapable() ) +#else if( pCombine && pCombine->IsElite() ) +#endif { pCombine->DelayAltFireAttack( flDelay ); } @@ -502,6 +664,7 @@ void CNPC_Combine::DelaySquadAltFireAttack( float flDelay ) pSquadmate = m_pSquad->GetNextMember( &iter ); } } +#endif //----------------------------------------------------------------------------- // Purpose: degrees to turn in 0.1 seconds @@ -534,15 +697,15 @@ float CNPC_Combine::MaxYawSpeed( void ) } //----------------------------------------------------------------------------- -// +// //----------------------------------------------------------------------------- bool CNPC_Combine::ShouldMoveAndShoot() { - // Set this timer so that gpGlobals->curtime can't catch up to it. - // Essentially, we're saying that we're not going to interfere with - // what the AI wants to do with move and shoot. + // Set this timer so that gpGlobals->curtime can't catch up to it. + // Essentially, we're saying that we're not going to interfere with + // what the AI wants to do with move and shoot. // - // If any code below changes this timer, the code is saying + // If any code below changes this timer, the code is saying // "It's OK to move and shoot until gpGlobals->curtime == m_flStopMoveShootTime" m_flStopMoveShootTime = FLT_MAX; @@ -577,7 +740,7 @@ bool CNPC_Combine::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flIn } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -586,6 +749,25 @@ Class_T CNPC_Combine::Classify ( void ) return CLASS_COMBINE; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Function for gauging whether we're capable of alt-firing. +//----------------------------------------------------------------------------- +bool CNPC_Combine::IsAltFireCapable( void ) +{ + // The base class tells us if we're carrying an alt-fire-able weapon. + return (IsElite() || m_bAlternateCapable) && BaseClass::IsAltFireCapable(); +} + +//----------------------------------------------------------------------------- +// Purpose: Function for gauging whether we're capable of throwing grenades. +//----------------------------------------------------------------------------- +bool CNPC_Combine::IsGrenadeCapable( void ) +{ + return !IsElite() || m_bAlternateCapable; +} +#endif + //----------------------------------------------------------------------------- // Continuous movement tasks @@ -628,7 +810,7 @@ void CNPC_Combine::StartTaskChaseEnemyContinuously( const Task_t *pTask ) if ( !GetNavigator()->SetGoal( GOALTYPE_ENEMY, AIN_NO_PATH_TASK_FAIL ) ) { - // no way to get there =( + // no way to get there =( DevWarning( 2, "GetPathToEnemy failed!!\n" ); RememberUnreachable( pEnemy ); TaskFail(FAIL_NO_ROUTE); @@ -719,7 +901,6 @@ void CNPC_Combine::RunTaskChaseEnemyContinuously( const Task_t *pTask ) m_vSavePosition = pEnemy->WorldSpaceCenter(); } - //========================================================= // start task //========================================================= @@ -813,7 +994,11 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) { m_flLastAttackTime = gpGlobals->curtime; +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_ANNOUNCE, SENTENCE_PRIORITY_HIGH ); +#else m_Sentences.Speak( "COMBINE_ANNOUNCE", SENTENCE_PRIORITY_HIGH ); +#endif // Wait two seconds SetWait( 2.0 ); @@ -837,14 +1022,18 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) } else { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_THROWGRENADE, SENTENCE_PRIORITY_MEDIUM ); +#else m_Sentences.Speak( "COMBINE_THROW_GRENADE", SENTENCE_PRIORITY_MEDIUM ); +#endif SetActivity(ACT_IDLE); // Wait two seconds SetWait( 2.0 ); } break; - } + } case TASK_WALK_PATH: case TASK_RUN_PATH: @@ -857,6 +1046,9 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) break; case TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS: +#ifdef MAPBASE + StartTask_GetPathToForced(pTask); +#else { if ( !m_hForcedGrenadeTarget ) { @@ -895,6 +1087,7 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) m_vInterruptSavePosition = posLos; } } +#endif break; case TASK_COMBINE_IGNORE_ATTACKS: @@ -912,6 +1105,9 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) case TASK_COMBINE_DEFER_SQUAD_GRENADES: { +#ifdef MAPBASE + StartTask_DeferSquad(pTask); +#else if ( m_pSquad ) { // iterate my squad and stop everyone from throwing grenades for a little while. @@ -920,18 +1116,23 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) CAI_BaseNPC *pSquadmate = m_pSquad ? m_pSquad->GetFirstMember( &iter ) : NULL; while ( pSquadmate ) { +#ifdef MAPBASE + pSquadmate->DelayGrenadeCheck(5); +#else CNPC_Combine *pCombine = dynamic_cast(pSquadmate); if( pCombine ) { pCombine->m_flNextGrenadeCheck = gpGlobals->curtime + 5; } +#endif pSquadmate = m_pSquad->GetNextMember( &iter ); } } TaskComplete(); +#endif break; } @@ -960,7 +1161,7 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) { CBaseEntity *pEntity = GetEnemy(); - // FIXME: this should be generalized by the schedules that are selected, or in the definition of + // FIXME: this should be generalized by the schedules that are selected, or in the definition of // what "cover" means (i.e., trace attack vulnerability vs. physical attack vulnerability if ( pEntity ) { @@ -973,12 +1174,16 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) m_pSquad->SquadRemember(bits_MEMORY_PLAYER_HURT); } +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_PLAYERHIT, SENTENCE_PRIORITY_INVALID ); +#else m_Sentences.Speak( "COMBINE_PLAYERHIT", SENTENCE_PRIORITY_INVALID ); +#endif JustMadeSound( SENTENCE_PRIORITY_HIGH ); } if ( pEntity->MyNPCPointer() ) { - if ( !(pEntity->MyNPCPointer()->CapabilitiesGet( ) & bits_CAP_WEAPON_RANGE_ATTACK1) && + if ( !(pEntity->MyNPCPointer()->CapabilitiesGet( ) & bits_CAP_WEAPON_RANGE_ATTACK1) && !(pEntity->MyNPCPointer()->CapabilitiesGet( ) & bits_CAP_INNATE_RANGE_ATTACK1) ) { TaskComplete(); @@ -992,6 +1197,15 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) break; case TASK_RANGE_ATTACK1: { +#ifdef MAPBASE + // The game can crash if a soldier's weapon is removed while they're shooting + if (!GetActiveWeapon()) + { + TaskFail( "No weapon" ); + break; + } +#endif + m_nShots = GetActiveWeapon()->GetRandomBurst(); m_flShotDelay = GetActiveWeapon()->GetFireRate(); @@ -1017,7 +1231,7 @@ void CNPC_Combine::StartTask( const Task_t *pTask ) } break; - default: + default: BaseClass:: StartTask( pTask ); break; } @@ -1079,6 +1293,19 @@ void CNPC_Combine::RunTask( const Task_t *pTask ) } break; +#ifdef MAPBASE + case TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: + RunTask_FaceAltFireTarget(pTask); + break; + + case TASK_COMBINE_FACE_TOSS_DIR: + RunTask_FaceTossDir(pTask); + break; + + case TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS: + RunTask_GetPathToForced(pTask); + break; +#else case TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED ); @@ -1124,6 +1351,7 @@ void CNPC_Combine::RunTask( const Task_t *pTask ) } } break; +#endif case TASK_RANGE_ATTACK1: { @@ -1177,11 +1405,11 @@ void CNPC_Combine::RunTask( const Task_t *pTask ) // Input : // Output : //------------------------------------------------------------------------------ -Vector CNPC_Combine::BodyTarget( const Vector &posSrc, bool bNoisy ) +Vector CNPC_Combine::BodyTarget( const Vector &posSrc, bool bNoisy ) { Vector result = BaseClass::BodyTarget( posSrc, bNoisy ); - // @TODO (toml 02-02-04): this seems wrong. Isn't this already be accounted for + // @TODO (toml 02-02-04): this seems wrong. Isn't this already be accounted for // with the eye position used in the base BodyTarget() if ( GetFlags() & FL_DUCKING ) result -= Vector(0,0,24); @@ -1196,7 +1424,7 @@ bool CNPC_Combine::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** { if( m_spawnflags & SF_COMBINE_NO_LOOK ) { - // When no look is set, if enemy has eluded the squad, + // When no look is set, if enemy has eluded the squad, // he's always invisble to me if (GetEnemies()->HasEludedMe(pEntity)) { @@ -1239,7 +1467,11 @@ void CNPC_Combine::Event_Killed( const CTakeDamageInfo &info ) } // In the Citadel we need to dissolve this +#ifdef MAPBASE + if ( PlayerHasMegaPhysCannon() && GlobalEntity_GetCounter("super_phys_gun") != 1 ) +#else if ( PlayerHasMegaPhysCannon() ) +#endif { CBaseCombatWeapon *pWeapon = static_cast(pItem); @@ -1288,8 +1520,52 @@ void CNPC_Combine::BuildScheduleTestBits( void ) { SetCustomInterruptCondition( COND_COMBINE_ON_FIRE ); } + +#ifdef MAPBASE + if (npc_combine_new_cover_behavior.GetBool()) + { + if ( IsCurSchedule( SCHED_COMBINE_COMBAT_FAIL ) ) + { + SetCustomInterruptCondition( COND_NEW_ENEMY ); + SetCustomInterruptCondition( COND_LIGHT_DAMAGE ); + SetCustomInterruptCondition( COND_HEAVY_DAMAGE ); + } + else if ( IsCurSchedule( SCHED_COMBINE_MOVE_TO_MELEE ) ) + { + SetCustomInterruptCondition( COND_HEAR_DANGER ); + SetCustomInterruptCondition( COND_HEAR_MOVE_AWAY ); + } + } +#endif +} + + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : eNewActivity - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CNPC_Combine::Weapon_TranslateActivity( Activity eNewActivity, bool *pRequired ) +{ + return BaseClass::Weapon_TranslateActivity(eNewActivity, pRequired); } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CNPC_Combine::NPC_BackupActivity( Activity eNewActivity ) +{ + // Some models might not contain ACT_COMBINE_BUGBAIT, which the soldier model uses instead of ACT_IDLE_ON_FIRE. + // Contrariwise, soldiers may be called to use ACT_IDLE_ON_FIRE in other parts of the AI and need to translate to ACT_COMBINE_BUGBAIT. + if (eNewActivity == ACT_COMBINE_BUGBAIT) + return ACT_IDLE_ON_FIRE; + else if (eNewActivity == ACT_IDLE_ON_FIRE) + return ACT_COMBINE_BUGBAIT; + + return BaseClass::NPC_BackupActivity( eNewActivity ); +} +#endif //----------------------------------------------------------------------------- // Purpose: Translate base class activities into combot activites @@ -1302,15 +1578,27 @@ Activity CNPC_Combine::NPC_TranslateActivity( Activity eNewActivity ) if (eNewActivity == ACT_RANGE_ATTACK2) { - // grunt is going to a secondary long range attack. This may be a thrown +#ifndef MAPBASE + // grunt is going to a secondary long range attack. This may be a thrown // grenade or fired grenade, we must determine which and pick proper sequence if (Weapon_OwnsThisType( "weapon_grenadelauncher" ) ) { return ( Activity )ACT_COMBINE_LAUNCH_GRENADE; } else +#else + if (m_bUnderthrow) { + return ACT_SPECIAL_ATTACK1; + } + else +#endif + { +#if SHARED_COMBINE_ACTIVITIES + return ACT_COMBINE_THROW_GRENADE; +#else return ( Activity )ACT_COMBINE_THROW_GRENADE; +#endif } } else if (eNewActivity == ACT_IDLE) @@ -1338,6 +1626,35 @@ Activity CNPC_Combine::NPC_TranslateActivity( Activity eNewActivity ) break; } } +#ifdef MAPBASE + else if (!GetActiveWeapon() && !npc_combine_unarmed_anims.GetBool()) + { + if (eNewActivity == ACT_IDLE || eNewActivity == ACT_IDLE_ANGRY) + eNewActivity = ACT_IDLE_SMG1; + else if (eNewActivity == ACT_WALK) + eNewActivity = ACT_WALK_RIFLE; + else if (eNewActivity == ACT_RUN) + eNewActivity = ACT_RUN_RIFLE; + } + else if (m_NPCState == NPC_STATE_IDLE && eNewActivity == ACT_WALK) + { + if (npc_combine_idle_walk_easy.GetBool()) + { + // ACT_WALK_EASY has been replaced with ACT_WALK_RELAXED for weapon translation purposes + eNewActivity = ACT_WALK_RELAXED; + } + else if (GetActiveWeapon()) + { + eNewActivity = ACT_WALK_RIFLE; + } + } + + if ( eNewActivity == ACT_RUN && ( IsCurSchedule( SCHED_TAKE_COVER_FROM_BEST_SOUND ) || IsCurSchedule( SCHED_FLEE_FROM_BEST_SOUND ) ) ) + { + if ( random->RandomInt( 0, 1 ) && npc_combine_protected_run.GetBool() && HaveSequenceForActivity( ACT_RUN_PROTECTED ) ) + eNewActivity = ACT_RUN_PROTECTED; + } +#endif return BaseClass::NPC_TranslateActivity( eNewActivity ); } @@ -1369,7 +1686,7 @@ bool CNPC_Combine::QueryHearSound( CSound *pSound ) //----------------------------------------------------------------------------- -// Purpose: Announce an assault if the enemy can see me and we are pretty +// Purpose: Announce an assault if the enemy can see me and we are pretty // close to him/her // Input : // Output : @@ -1399,13 +1716,20 @@ void CNPC_Combine::AnnounceAssault(void) // Make sure player can see me if ( FVisible( pBCC ) ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_ASSAULT ); +#else m_Sentences.Speak( "COMBINE_ASSAULT" ); +#endif } } void CNPC_Combine::AnnounceEnemyType( CBaseEntity *pEnemy ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_ENEMY, SENTENCE_PRIORITY_HIGH ); +#else const char *pSentenceName = "COMBINE_MONST"; switch ( pEnemy->Classify() ) { @@ -1439,6 +1763,7 @@ void CNPC_Combine::AnnounceEnemyType( CBaseEntity *pEnemy ) } m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_HIGH ); +#endif } void CNPC_Combine::AnnounceEnemyKill( CBaseEntity *pEnemy ) @@ -1446,6 +1771,11 @@ void CNPC_Combine::AnnounceEnemyKill( CBaseEntity *pEnemy ) if (!pEnemy ) return; +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendEnemyCriteria(set, pEnemy); + SpeakIfAllowed( TLK_CMB_KILLENEMY, set, SENTENCE_PRIORITY_HIGH ); +#else const char *pSentenceName = "COMBINE_KILL_MONST"; switch ( pEnemy->Classify() ) { @@ -1475,6 +1805,7 @@ void CNPC_Combine::AnnounceEnemyKill( CBaseEntity *pEnemy ) } m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_HIGH ); +#endif } //----------------------------------------------------------------------------- @@ -1613,9 +1944,9 @@ int CNPC_Combine::SelectCombatSchedule() // If I'm scared of this enemy run away if ( IRelationType( GetEnemy() ) == D_FR ) { - if (HasCondition( COND_SEE_ENEMY ) || - HasCondition( COND_SEE_FEAR ) || - HasCondition( COND_LIGHT_DAMAGE ) || + if (HasCondition( COND_SEE_ENEMY ) || + HasCondition( COND_SEE_FEAR ) || + HasCondition( COND_LIGHT_DAMAGE ) || HasCondition( COND_HEAVY_DAMAGE )) { FearSound(); @@ -1672,7 +2003,7 @@ int CNPC_Combine::SelectCombatSchedule() return SCHED_COMBINE_PRESS_ATTACK; } - AnnounceAssault(); + AnnounceAssault(); return SCHED_COMBINE_ASSAULT; } @@ -1705,6 +2036,9 @@ int CNPC_Combine::SelectSchedule( void ) { Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); +#ifdef MAPBASE + // This was switched to IsAltFireCapable() before, but m_bAlternateCapable makes it necessary to use IsElite() again. +#endif if ( IsElite() ) { if ( FVisible( m_hForcedGrenadeTarget ) ) @@ -1716,7 +2050,7 @@ int CNPC_Combine::SelectSchedule( void ) } else { - // If we can, throw a grenade at the target. + // If we can, throw a grenade at the target. // Ignore grenade count / distance / etc if ( CheckCanThrowGrenade( vecTarget ) ) { @@ -1733,6 +2067,12 @@ int CNPC_Combine::SelectSchedule( void ) } } +#ifdef MAPBASE + // Drop a grenade? + if ( HasCondition( COND_COMBINE_DROP_GRENADE ) ) + return SCHED_COMBINE_DROP_GRENADE; +#endif + if ( m_NPCState != NPC_STATE_SCRIPT) { // If we're hit by bugbait, thrash around @@ -1776,7 +2116,11 @@ int CNPC_Combine::SelectSchedule( void ) { // I hear something dangerous, probably need to take cover. // dangerous sound nearby!, call it out +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM const char *pSentenceName = "COMBINE_DANGER"; +#else + bool bGrenade = false; +#endif CBaseEntity *pSoundOwner = pSound->m_hOwner; if ( pSoundOwner ) @@ -1787,12 +2131,20 @@ int CNPC_Combine::SelectSchedule( void ) if ( IRelationType( pGrenade->GetThrower() ) != D_LI ) { // special case call out for enemy grenades +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM pSentenceName = "COMBINE_GREN"; +#else + bGrenade = true; +#endif } } } +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_DANGER, UTIL_VarArgs( "grenade:%d", bGrenade ) ); +#else m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL ); +#endif // If the sound is approaching danger, I have no enemy, and I don't see it, turn to face. if( !GetEnemy() && pSound->IsSoundType(SOUND_CONTEXT_DANGER_APPROACH) && pSound->m_hOwner && !FInViewCone(pSound->GetSoundReactOrigin()) ) @@ -1853,7 +2205,7 @@ int CNPC_Combine::SelectSchedule( void ) } } - // Don't patrol if I'm in the middle of an assault, because I'll never return to the assault. + // Don't patrol if I'm in the middle of an assault, because I'll never return to the assault. if ( !m_AssaultBehavior.HasAssaultCue() ) { if( m_bShouldPatrol || HasCondition( COND_COMBINE_SHOULD_PATROL ) ) @@ -1881,10 +2233,15 @@ int CNPC_Combine::SelectFailSchedule( int failedSchedule, int failedTask, AI_Tas { if( failedSchedule == SCHED_COMBINE_TAKE_COVER1 ) { +#ifdef MAPBASE + if( IsInSquad() && IsStrategySlotRangeOccupied(SQUAD_SLOT_ATTACK1, SQUAD_SLOT_ATTACK2) && HasCondition(COND_SEE_ENEMY) + && ( !npc_combine_new_cover_behavior.GetBool() || (taskFailCode == FAIL_NO_COVER) ) ) +#else if( IsInSquad() && IsStrategySlotRangeOccupied(SQUAD_SLOT_ATTACK1, SQUAD_SLOT_ATTACK2) && HasCondition(COND_SEE_ENEMY) ) +#endif { // This eases the effects of an unfortunate bug that usually plagues shotgunners. Since their rate of fire is low, - // they spend relatively long periods of time without an attack squad slot. If you corner a shotgunner, usually + // they spend relatively long periods of time without an attack squad slot. If you corner a shotgunner, usually // the other memebers of the squad will hog all of the attack slots and pick schedules to move to establish line of // fire. During this time, the shotgunner is prevented from attacking. If he also cannot find cover (the fallback case) // he will stand around like an idiot, right in front of you. Instead of this, we have him run up to you for a melee attack. @@ -1912,9 +2269,11 @@ bool CNPC_Combine::ShouldChargePlayer() int CNPC_Combine::SelectScheduleAttack() { +#ifndef MAPBASE // Moved to SelectSchedule() // Drop a grenade? if ( HasCondition( COND_COMBINE_DROP_GRENADE ) ) return SCHED_COMBINE_DROP_GRENADE; +#endif // Kick attack? if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) ) @@ -1924,7 +2283,11 @@ int CNPC_Combine::SelectScheduleAttack() // If I'm fighting a combine turret (it's been hacked to attack me), I can't really // hurt it with bullets, so become grenade happy. +#ifdef MAPBASE + if ( GetEnemy() && ( (IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY)) || GetEnemy()->ClassMatches(gm_isz_class_FloorTurret) ) ) +#else if ( GetEnemy() && GetEnemy()->Classify() == CLASS_COMBINE && FClassnameIs(GetEnemy(), "npc_turret_floor") ) +#endif { // Don't do this until I've been fighting the turret for a few seconds float flTimeAtFirstHand = GetEnemies()->TimeAtFirstHand(GetEnemy()); @@ -1940,11 +2303,16 @@ int CNPC_Combine::SelectScheduleAttack() // If we're not in the viewcone of the turret, run up and hit it. Do this a bit later to // give other squadmembers a chance to throw a grenade before I run in. +#ifdef MAPBASE + // Don't do turret charging of we're just grenade happy. + if ( !IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY) && !GetEnemy()->MyNPCPointer()->FInViewCone( this ) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) +#else if ( !GetEnemy()->MyNPCPointer()->FInViewCone( this ) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) +#endif return SCHED_COMBINE_CHARGE_TURRET; } - // When fighting against the player who's wielding a mega-physcannon, + // When fighting against the player who's wielding a mega-physcannon, // always close the distance if possible // But don't do it if you're in a nav-limited hint group if ( ShouldChargePlayer() ) @@ -1979,7 +2347,7 @@ int CNPC_Combine::SelectScheduleAttack() if ( m_pSquad ) { // if the enemy has eluded the squad and a squad member has just located the enemy - // and the enemy does not see the squad member, issue a call to the squad to waste a + // and the enemy does not see the squad member, issue a call to the squad to waste a // little time and give the player a chance to turn. if ( MySquadLeader()->m_fEnemyEluded && !HasConditions ( bits_COND_ENEMY_FACING_ME ) ) { @@ -2011,7 +2379,7 @@ int CNPC_Combine::SelectScheduleAttack() if ( GetEnemy() && !HasCondition(COND_SEE_ENEMY) ) { // We don't see our enemy. If it hasn't been long since I last saw him, - // and he's pretty close to the last place I saw him, throw a grenade in + // and he's pretty close to the last place I saw him, throw a grenade in // to flush him out. A wee bit of cheating here... float flTime; @@ -2045,7 +2413,7 @@ int CNPC_Combine::SelectScheduleAttack() // Input : // Output : //----------------------------------------------------------------------------- -int CNPC_Combine::TranslateSchedule( int scheduleType ) +int CNPC_Combine::TranslateSchedule( int scheduleType ) { switch( scheduleType ) { @@ -2054,11 +2422,15 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) if ( m_pSquad ) { // Have to explicitly check innate range attack condition as may have weapon with range attack 2 - if ( g_pGameRules->IsSkillLevel( SKILL_HARD ) && + if ( g_pGameRules->IsSkillLevel( SKILL_HARD ) && HasCondition(COND_CAN_RANGE_ATTACK2) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_THROWGRENADE ); +#else m_Sentences.Speak( "COMBINE_THROW_GRENADE" ); +#endif return SCHED_COMBINE_TOSS_GRENADE_COVER1; } else @@ -2097,8 +2469,15 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) return TranslateSchedule( SCHED_RANGE_ATTACK1 ); } +#ifdef MAPBASE + if ( npc_combine_new_cover_behavior.GetBool() && HasCondition( COND_CAN_RANGE_ATTACK2 ) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) + { + return TranslateSchedule( SCHED_RANGE_ATTACK2 ); + } +#endif + // Run somewhere randomly - return TranslateSchedule( SCHED_FAIL ); + return TranslateSchedule( SCHED_FAIL ); break; } break; @@ -2119,8 +2498,8 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) } else if ( !m_AssaultBehavior.HasAssaultCue() ) { - // Don't patrol if I'm in the middle of an assault, because - // I'll never return to the assault. + // Don't patrol if I'm in the middle of an assault, because + // I'll never return to the assault. if ( GetEnemy() ) { RememberUnreachable( GetEnemy() ); @@ -2134,7 +2513,7 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) { CBaseEntity *pEntity = GetEnemy(); - // FIXME: this should be generalized by the schedules that are selected, or in the definition of + // FIXME: this should be generalized by the schedules that are selected, or in the definition of // what "cover" means (i.e., trace attack vulnerability vs. physical attack vulnerability if (pEntity && pEntity->MyNPCPointer()) { @@ -2202,7 +2581,7 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) if( CanAltFireEnemy(true) && OccupyStrategySlot(SQUAD_SLOT_SPECIAL_ATTACK) ) { - // Since I'm holding this squadslot, no one else can try right now. If I die before the shot + // Since I'm holding this squadslot, no one else can try right now. If I die before the shot // goes off, I won't have affected anyone else's ability to use this attack at their nearest // convenience. return SCHED_COMBINE_AR2_ALTFIRE; @@ -2237,6 +2616,12 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) Stand(); } +#ifdef MAPBASE + // SCHED_COMBINE_WAIT_IN_COVER uses INCOVER, but only gets out of it when the soldier moves. + // That seems to mess up shooting, so this Forget() attempts to fix that. + Forget( bits_MEMORY_INCOVER ); +#endif + return SCHED_COMBINE_RANGE_ATTACK1; } case SCHED_RANGE_ATTACK2: @@ -2302,7 +2687,7 @@ int CNPC_Combine::TranslateSchedule( int scheduleType ) //========================================================= //========================================================= -void CNPC_Combine::OnStartSchedule( int scheduleType ) +void CNPC_Combine::OnStartSchedule( int scheduleType ) { } @@ -2320,12 +2705,24 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == COMBINE_AE_BEGIN_ALTFIRE ) { +#ifdef MAPBASE + if (GetActiveWeapon()) + GetActiveWeapon()->WeaponSound(SPECIAL1); +#else EmitSound( "Weapon_CombineGuard.Special1" ); +#endif +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_THROWGRENADE, "altfire:1", SENTENCE_PRIORITY_MEDIUM ); +#endif handledEvent = true; } else if ( pEvent->event == COMBINE_AE_ALTFIRE ) { - if( IsElite() ) +#ifdef MAPBASE + if ( IsAltFireCapable() && GetActiveWeapon() ) +#else + if ( IsElite() ) +#endif { animevent_t fakeEvent; @@ -2343,7 +2740,15 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) // that makes sure the elite has grenades in order to fire a combine ball, we // preserve the legacy behavior while making it possible for a designer to prevent // elites from shooting combine balls by setting grenades to '0' in hammer. (sjb) EP2_OUTLAND_10 +#ifdef MAPBASE + // + // Here's a tip: In Mapbase, "OnThrowGrenade" is fired during alt-fire as well, fired by the weapon so it could pass its alt-fire projectile. + // So if you want elites to decrement on each grenade again, you could fire "!self > AddGrenades -1" every time an elite fires OnThrowGrenade. + // + // AddGrenades(-1); +#else // m_iNumGrenades--; +#endif } handledEvent = true; @@ -2357,7 +2762,7 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { - case COMBINE_AE_AIM: + case COMBINE_AE_AIM: { handledEvent = true; break; @@ -2367,9 +2772,13 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) // We never actually run out of ammo, just need to refill the clip if (GetActiveWeapon()) { +#ifdef MAPBASE + GetActiveWeapon()->Reload_NPC(); +#else GetActiveWeapon()->WeaponSound( RELOAD_NPC ); - GetActiveWeapon()->m_iClip1 = GetActiveWeapon()->GetMaxClip1(); - GetActiveWeapon()->m_iClip2 = GetActiveWeapon()->GetMaxClip2(); + GetActiveWeapon()->m_iClip1 = GetActiveWeapon()->GetMaxClip1(); +#endif + GetActiveWeapon()->m_iClip2 = GetActiveWeapon()->GetMaxClip2(); } ClearCondition(COND_LOW_PRIMARY_AMMO); ClearCondition(COND_NO_PRIMARY_AMMO); @@ -2395,13 +2804,24 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) GetVectors( &forward, NULL, &up ); vecThrow = forward * 750 + up * 175; +#ifdef MAPBASE + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, true ); + m_OnThrowGrenade.Set(pGrenade, pGrenade, this); +#else Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, true ); +#endif } else { // Use the Velocity that AI gave us. +#ifdef MAPBASE + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, true ); + m_OnThrowGrenade.Set(pGrenade, pGrenade, this); + AddGrenades(-1, pGrenade); +#else Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, true ); m_iNumGrenades--; +#endif } // wait six seconds before even looking again to see if a grenade can be thrown. @@ -2429,10 +2849,34 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) case COMBINE_AE_GREN_DROP: { Vector vecStart; +#ifdef MAPBASE + QAngle angStart; + m_vecTossVelocity.x = 15; + m_vecTossVelocity.y = 0; + m_vecTossVelocity.z = 0; + + GetAttachment( "lefthand", vecStart, angStart ); + + CBaseEntity *pGrenade = NULL; + if (m_NPCState == NPC_STATE_SCRIPT) + { + // While scripting, have the grenade face upwards like it was originally and also don't decrement grenade count. + pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vec3_origin, this, COMBINE_GRENADE_TIMER, true ); + } + else + { + pGrenade = Fraggrenade_Create( vecStart, angStart, m_vecTossVelocity, vec3_origin, this, COMBINE_GRENADE_TIMER, true ); + AddGrenades(-1); + } + + // Well, technically we're not throwing, but...still. + m_OnThrowGrenade.Set(pGrenade, pGrenade, this); +#else GetAttachment( "lefthand", vecStart ); Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vec3_origin, this, COMBINE_GRENADE_TIMER, true ); m_iNumGrenades--; +#endif } handledEvent = true; break; @@ -2461,15 +2905,23 @@ void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) EmitSound( "NPC_Combine.WeaponBash" ); } - } + } +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_KICK ); +#else m_Sentences.Speak( "COMBINE_KICK" ); +#endif handledEvent = true; break; } case COMBINE_AE_CAUGHT_ENEMY: +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_ENEMY ); //SpeakIfAllowed( "TLK_CMB_ALERT" ); +#else m_Sentences.Speak( "COMBINE_ALERT" ); +#endif handledEvent = true; break; @@ -2539,9 +2991,9 @@ Vector CNPC_Combine::Weapon_ShootPosition( ) // being able to execute the intended action. It's really lame // when a grunt says 'COVER ME' and then doesn't move. The problem // is that the sentences were played when the decision to TRY -// to move to cover was made. Now the sentence is played after +// to move to cover was made. Now the sentence is played after // we know for sure that there is a valid path. The schedule -// may still fail but in most cases, well after the grunt has +// may still fail but in most cases, well after the grunt has // started moving. //========================================================= void CNPC_Combine::SpeakSentence( int sentenceType ) @@ -2556,16 +3008,82 @@ void CNPC_Combine::SpeakSentence( int sentenceType ) // If I'm moving more than 20ft, I need to talk about it if ( GetNavigator()->GetPath()->GetPathLength() > 20 * 12.0f ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_FLANK ); +#else m_Sentences.Speak( "COMBINE_FLANK" ); +#endif } break; } } +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM +//========================================================= +bool CNPC_Combine::SpeakIfAllowed( const char *rrConcept, const char *modifiers, SentencePriority_t sentencepriority, SentenceCriteria_t sentencecriteria ) +{ + AI_CriteriaSet set; + if (modifiers) + { +#ifdef NEW_RESPONSE_SYSTEM + GatherCriteria( &set, rrConcept, modifiers ); +#else + GetExpresser()->MergeModifiers(set, modifiers); +#endif + } + return SpeakIfAllowed( rrConcept, set, sentencepriority, sentencecriteria ); +} + +//========================================================= +//========================================================= +bool CNPC_Combine::SpeakIfAllowed( const char *rrConcept, AI_CriteriaSet& modifiers, SentencePriority_t sentencepriority, SentenceCriteria_t sentencecriteria ) +{ + if ( sentencepriority != SENTENCE_PRIORITY_INVALID && !FOkToMakeSound( sentencepriority ) ) + return false; + + if ( !GetExpresser()->CanSpeakConcept( rrConcept ) ) + return false; + + // Don't interrupt scripted VCD dialogue + if ( IsRunningScriptedSceneWithSpeechAndNotPaused( this, true ) ) + return false; + + if ( Speak( rrConcept, modifiers ) ) + { + JustMadeSound( sentencepriority, 2.0f /*GetTimeSpeechComplete()*/ ); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_Combine::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); + + set.AppendCriteria( "numgrenades", UTIL_VarArgs("%d", m_iNumGrenades) ); + + if (IsElite()) + { + set.AppendCriteria( "elite", "1" ); + } + else + { + set.AppendCriteria( "elite", "0" ); + } +} +#endif + //========================================================= // PainSound //========================================================= +#ifdef MAPBASE +void CNPC_Combine::PainSound ( const CTakeDamageInfo &info ) +#else void CNPC_Combine::PainSound ( void ) +#endif { // NOTE: The response system deals with this at the moment if ( GetFlags() & FL_DISSOLVING ) @@ -2573,6 +3091,11 @@ void CNPC_Combine::PainSound ( void ) if ( gpGlobals->curtime > m_flNextPainSoundTime ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + SpeakIfAllowed( TLK_CMB_PAIN, set, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#else const char *pSentenceName = "COMBINE_PAIN"; float healthRatio = (float)GetHealth() / (float)GetMaxHealth(); if ( !HasMemory(bits_MEMORY_PAIN_LIGHT_SOUND) && healthRatio > 0.9 ) @@ -2587,6 +3110,7 @@ void CNPC_Combine::PainSound ( void ) } m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif m_flNextPainSoundTime = gpGlobals->curtime + 1; } } @@ -2602,10 +3126,16 @@ void CNPC_Combine::LostEnemySound( void) if ( gpGlobals->curtime <= m_flNextLostSoundTime ) return; +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + if (SpeakIfAllowed( TLK_CMB_LOSTENEMY, UTIL_VarArgs("lastseenenemy:%d", GetEnemyLastTimeSeen()) )) + { + m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0); + } +#else const char *pSentence; if (!(CBaseEntity*)GetEnemy() || gpGlobals->curtime - GetEnemyLastTimeSeen() > 10) { - pSentence = "COMBINE_LOST_LONG"; + pSentence = "COMBINE_LOST_LONG"; } else { @@ -2616,6 +3146,7 @@ void CNPC_Combine::LostEnemySound( void) { m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0); } +#endif } //----------------------------------------------------------------------------- @@ -2626,7 +3157,11 @@ void CNPC_Combine::LostEnemySound( void) //----------------------------------------------------------------------------- void CNPC_Combine::FoundEnemySound( void) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_REFINDENEMY, SENTENCE_PRIORITY_HIGH ); +#else m_Sentences.Speak( "COMBINE_REFIND_ENEMY", SENTENCE_PRIORITY_HIGH ); +#endif } //----------------------------------------------------------------------------- @@ -2641,7 +3176,11 @@ void CNPC_Combine::AlertSound( void) { if ( gpGlobals->curtime > m_flNextAlertSoundTime ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_GOALERT, SENTENCE_PRIORITY_HIGH ); +#else m_Sentences.Speak( "COMBINE_GO_ALERT", SENTENCE_PRIORITY_HIGH ); +#endif m_flNextAlertSoundTime = gpGlobals->curtime + 10.0f; } } @@ -2651,34 +3190,50 @@ void CNPC_Combine::AlertSound( void) //========================================================= void CNPC_Combine::NotifyDeadFriend ( CBaseEntity* pFriend ) { +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM if ( GetSquad()->NumMembers() < 2 ) { m_Sentences.Speak( "COMBINE_LAST_OF_SQUAD", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_NORMAL ); JustMadeSound(); return; } +#endif // relaxed visibility test so that guys say this more often //if( FInViewCone( pFriend ) && FVisible( pFriend ) ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_MANDOWN ); +#else m_Sentences.Speak( "COMBINE_MAN_DOWN" ); +#endif } BaseClass::NotifyDeadFriend(pFriend); } //========================================================= -// DeathSound +// DeathSound //========================================================= +#ifdef MAPBASE +void CNPC_Combine::DeathSound ( const CTakeDamageInfo &info ) +#else void CNPC_Combine::DeathSound ( void ) +#endif { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + SpeakIfAllowed(TLK_CMB_DIE, set, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS); +#else // NOTE: The response system deals with this at the moment if ( GetFlags() & FL_DISSOLVING ) return; m_Sentences.Speak( "COMBINE_DIE", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif } //========================================================= -// IdleSound +// IdleSound //========================================================= void CNPC_Combine::IdleSound( void ) { @@ -2686,6 +3241,11 @@ void CNPC_Combine::IdleSound( void ) { if (!g_fCombineQuestion) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + int iRandom = random->RandomInt(0, 2); + SpeakIfAllowed( TLK_CMB_QUESTION, UTIL_VarArgs("combinequestion:%d", iRandom) ); + g_fCombineQuestion = iRandom + 1; +#else // ask question or make statement switch (random->RandomInt(0,2)) { @@ -2707,9 +3267,14 @@ void CNPC_Combine::IdleSound( void ) m_Sentences.Speak( "COMBINE_IDLE" ); break; } +#endif } else { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_CMB_ANSWER, UTIL_VarArgs("combinequestion:%d", g_fCombineQuestion) ); + g_fCombineQuestion = 0; +#else switch (g_fCombineQuestion) { case 1: // check in @@ -2718,19 +3283,20 @@ void CNPC_Combine::IdleSound( void ) g_fCombineQuestion = 0; } break; - case 2: // question + case 2: // question if ( m_Sentences.Speak( "COMBINE_ANSWER" ) >= 0 ) { g_fCombineQuestion = 0; } break; } +#endif } } } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // This is for Grenade attacks. As the test for grenade attacks // is expensive we don't want to do it every frame. Return true @@ -2739,15 +3305,16 @@ void CNPC_Combine::IdleSound( void ) // Input : // Output : //----------------------------------------------------------------------------- -int CNPC_Combine::RangeAttack2Conditions( float flDot, float flDist ) +int CNPC_Combine::RangeAttack2Conditions( float flDot, float flDist ) { return COND_NONE; } +#ifndef MAPBASE //----------------------------------------------------------------------------- // Purpose: Return true if the combine has grenades, hasn't checked lately, and // can throw a grenade at the target point. -// Input : &vecTarget - +// Input : &vecTarget - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_Combine::CanThrowGrenade( const Vector &vecTarget ) @@ -2784,7 +3351,7 @@ bool CNPC_Combine::CanThrowGrenade( const Vector &vecTarget ) Vector vecEnemyLKP = GetEnemyLKP(); if ( !( GetEnemy()->GetFlags() & FL_ONGROUND ) && GetEnemy()->GetWaterLevel() == 0 && vecEnemyLKP.z > (GetAbsOrigin().z + WorldAlignMaxs().z) ) { - //!!!BUGBUG - we should make this check movetype and make sure it isn't FLY? Players who jump a lot are unlikely to + //!!!BUGBUG - we should make this check movetype and make sure it isn't FLY? Players who jump a lot are unlikely to // be grenaded. // don't throw grenades at anything that isn't on the ground! return COND_NONE; @@ -2812,7 +3379,7 @@ bool CNPC_Combine::CanThrowGrenade( const Vector &vecTarget ) //----------------------------------------------------------------------------- // Purpose: Returns true if the combine can throw a grenade at the specified target point -// Input : &vecTarget - +// Input : &vecTarget - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_Combine::CheckCanThrowGrenade( const Vector &vecTarget ) @@ -2858,12 +3425,17 @@ bool CNPC_Combine::CheckCanThrowGrenade( const Vector &vecTarget ) return false; } } +#endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool CNPC_Combine::CanAltFireEnemy( bool bUseFreeKnowledge ) { - if (!IsElite() ) +#ifdef MAPBASE + if ( !IsAltFireCapable() ) +#else + if ( !IsElite() ) +#endif return false; if (IsCrouching()) @@ -2884,7 +3456,14 @@ bool CNPC_Combine::CanAltFireEnemy( bool bUseFreeKnowledge ) CBaseEntity *pEnemy = GetEnemy(); +#ifdef MAPBASE + // "Our weapons alone cannot take down the antlion guard!" + // "Wait, you're an elite, don't you have, like, disintegration balls or somethi--" + // "SHUT UP!" + if ( !npc_combine_altfire_not_allies_only.GetBool() && !pEnemy->IsPlayer() && (!pEnemy->IsNPC() || !pEnemy->MyNPCPointer()->IsPlayerAlly()) ) +#else if( !pEnemy->IsPlayer() && (!pEnemy->IsNPC() || !pEnemy->MyNPCPointer()->IsPlayerAlly()) ) +#endif return false; Vector vecTarget; @@ -2913,14 +3492,23 @@ bool CNPC_Combine::CanAltFireEnemy( bool bUseFreeKnowledge ) } // Trace a hull about the size of the combine ball. +#ifdef MAPBASE + UTIL_TraceHull( vShootPosition, vecTarget, mins, maxs, MASK_COMBINE_BALL_LOS, this, COLLISION_GROUP_NONE, &tr ); +#else UTIL_TraceHull( vShootPosition, vecTarget, mins, maxs, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); +#endif float flLength = (vShootPosition - vecTarget).Length(); flLength *= tr.fraction; //If the ball can travel at least 65% of the distance to the player then let the NPC shoot it. +#ifdef MAPBASE + // (unless it hit the world) + if( tr.fraction >= 0.65 && (!tr.m_pEnt || !tr.m_pEnt->IsWorld()) && flLength > 128.0f ) +#else if( tr.fraction >= 0.65 && flLength > 128.0f ) +#endif { // Target is valid m_vecAltFireTarget = vecTarget; @@ -2938,7 +3526,11 @@ bool CNPC_Combine::CanAltFireEnemy( bool bUseFreeKnowledge ) //----------------------------------------------------------------------------- bool CNPC_Combine::CanGrenadeEnemy( bool bUseFreeKnowledge ) { - if( IsElite() ) +#ifdef MAPBASE + if ( !IsGrenadeCapable() ) +#else + if ( IsElite() ) +#endif return false; CBaseEntity *pEnemy = GetEnemy(); @@ -2991,7 +3583,7 @@ int CNPC_Combine::MeleeAttack1Conditions ( float flDot, float flDist ) return COND_NONE; } - // Make sure not trying to kick through a window or something. + // Make sure not trying to kick through a window or something. trace_t tr; Vector vecSrc, vecEnd; @@ -3008,10 +3600,10 @@ int CNPC_Combine::MeleeAttack1Conditions ( float flDot, float flDist ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Vector //----------------------------------------------------------------------------- -Vector CNPC_Combine::EyePosition( void ) +Vector CNPC_Combine::EyePosition( void ) { if ( !IsCrouching() ) { @@ -3029,6 +3621,7 @@ Vector CNPC_Combine::EyePosition( void ) */ } +#ifndef MAPBASE //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- Vector CNPC_Combine::GetAltFireTarget() @@ -3037,10 +3630,11 @@ Vector CNPC_Combine::GetAltFireTarget() return m_vecAltFireTarget; } +#endif //----------------------------------------------------------------------------- -// Purpose: -// Input : nActivity - +// Purpose: +// Input : nActivity - // Output : Vector //----------------------------------------------------------------------------- Vector CNPC_Combine::EyeOffset( Activity nActivity ) @@ -3063,20 +3657,53 @@ Vector CNPC_Combine::EyeOffset( Activity nActivity ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Vector CNPC_Combine::GetCrouchEyeOffset( void ) { return COMBINE_EYE_CROUCHING_POSITION; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CNPC_Combine::IsCrouchedActivity( Activity activity ) +{ + if (BaseClass::IsCrouchedActivity( activity )) + return true; + + Activity realActivity = TranslateActivity(activity); + + // Soldiers need to consider these crouched activities, but not all NPCs should. + switch ( realActivity ) + { + case ACT_RANGE_AIM_LOW: + case ACT_RANGE_AIM_AR2_LOW: + case ACT_RANGE_AIM_SMG1_LOW: + case ACT_RANGE_AIM_PISTOL_LOW: + case ACT_RANGE_ATTACK1_LOW: + case ACT_RANGE_ATTACK_AR2_LOW: + case ACT_RANGE_ATTACK_SMG1_LOW: + case ACT_RANGE_ATTACK_SHOTGUN_LOW: + case ACT_RANGE_ATTACK_PISTOL_LOW: + case ACT_RANGE_ATTACK2_LOW: + return true; + } + + return false; +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Combine::SetActivity( Activity NewActivity ) { BaseClass::SetActivity( NewActivity ); +#ifndef MAPBASE // CAI_GrenadeUser m_iLastAnimEventHandled = -1; +#endif } //----------------------------------------------------------------------------- @@ -3138,7 +3765,11 @@ void CNPC_Combine::OnEndMoveAndShoot() //----------------------------------------------------------------------------- WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { +#ifdef MAPBASE + if( pWeapon->ClassMatches( gm_isz_class_AR2 ) ) +#else if( FClassnameIs( pWeapon, "weapon_ar2" ) ) +#endif { if( hl2_episodic.GetBool() ) { @@ -3149,19 +3780,36 @@ WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWea return WEAPON_PROFICIENCY_GOOD; } } +#ifdef MAPBASE + else if( pWeapon->ClassMatches( gm_isz_class_Shotgun ) ) +#else else if( FClassnameIs( pWeapon, "weapon_shotgun" ) ) +#endif { +#ifndef MAPBASE // Moved so soldiers don't change skin unnaturally and uncontrollably if( m_nSkin != COMBINE_SKIN_SHOTGUNNER ) { m_nSkin = COMBINE_SKIN_SHOTGUNNER; } +#endif return WEAPON_PROFICIENCY_PERFECT; } +#ifdef MAPBASE + else if( pWeapon->ClassMatches( gm_isz_class_SMG1 ) ) +#else else if( FClassnameIs( pWeapon, "weapon_smg1" ) ) +#endif { return WEAPON_PROFICIENCY_GOOD; } +#ifdef MAPBASE + else if ( pWeapon->ClassMatches( gm_isz_class_Pistol ) ) + { + // Mods which need a lower soldier pistol accuracy can either change this value or use proficiency override in Hammer. + return WEAPON_PROFICIENCY_VERY_GOOD; + } +#endif return BaseClass::CalcWeaponProficiency( pWeapon ); } @@ -3207,7 +3855,7 @@ bool CNPC_Combine::HandleInteraction(int interactionType, void *data, CBaseComba { if ( interactionType == g_interactionTurretStillStanding ) { - // A turret that I've kicked recently is still standing 5 seconds later. + // A turret that I've kicked recently is still standing 5 seconds later. if ( sourceEnt == GetEnemy() ) { // It's still my enemy. Time to grenade it. @@ -3230,11 +3878,11 @@ const char* CNPC_Combine::GetSquadSlotDebugName( int iSquadSlot ) { switch( iSquadSlot ) { - case SQUAD_SLOT_GRENADE1: return "SQUAD_SLOT_GRENADE1"; + case SQUAD_SLOT_GRENADE1: return "SQUAD_SLOT_GRENADE1"; break; - case SQUAD_SLOT_GRENADE2: return "SQUAD_SLOT_GRENADE2"; + case SQUAD_SLOT_GRENADE2: return "SQUAD_SLOT_GRENADE2"; break; - case SQUAD_SLOT_ATTACK_OCCLUDER: return "SQUAD_SLOT_ATTACK_OCCLUDER"; + case SQUAD_SLOT_ATTACK_OCCLUDER: return "SQUAD_SLOT_ATTACK_OCCLUDER"; break; case SQUAD_SLOT_OVERWATCH: return "SQUAD_SLOT_OVERWATCH"; break; @@ -3258,8 +3906,8 @@ bool CNPC_Combine::IsUsingTacticalVariant( int variant ) //----------------------------------------------------------------------------- // For the purpose of determining whether to use a pathfinding variant, this -// function determines whether the current schedule is a schedule that -// 'approaches' the enemy. +// function determines whether the current schedule is a schedule that +// 'approaches' the enemy. //----------------------------------------------------------------------------- bool CNPC_Combine::IsRunningApproachEnemySchedule() { @@ -3275,9 +3923,14 @@ bool CNPC_Combine::IsRunningApproachEnemySchedule() return false; } -bool CNPC_Combine::ShouldPickADeathPose( void ) -{ - return !IsCrouching(); +bool CNPC_Combine::ShouldPickADeathPose( void ) +{ +#ifdef MAPBASE + // Check base class as well + return !IsCrouching() && BaseClass::ShouldPickADeathPose(); +#else + return !IsCrouching(); +#endif } //----------------------------------------------------------------------------- @@ -3300,12 +3953,21 @@ DECLARE_TASK( TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS ) DECLARE_TASK( TASK_COMBINE_SET_STANDING ) //Activities +#if !SHARED_COMBINE_ACTIVITIES DECLARE_ACTIVITY( ACT_COMBINE_THROW_GRENADE ) +#endif DECLARE_ACTIVITY( ACT_COMBINE_LAUNCH_GRENADE ) DECLARE_ACTIVITY( ACT_COMBINE_BUGBAIT ) +#if !SHARED_COMBINE_ACTIVITIES DECLARE_ACTIVITY( ACT_COMBINE_AR2_ALTFIRE ) +#endif DECLARE_ACTIVITY( ACT_WALK_EASY ) DECLARE_ACTIVITY( ACT_WALK_MARCH ) +#ifdef MAPBASE +DECLARE_ACTIVITY( ACT_TURRET_CARRY_IDLE ) +DECLARE_ACTIVITY( ACT_TURRET_CARRY_WALK ) +DECLARE_ACTIVITY( ACT_TURRET_CARRY_RUN ) +#endif DECLARE_ANIMEVENT( COMBINE_AE_BEGIN_ALTFIRE ) DECLARE_ANIMEVENT( COMBINE_AE_ALTFIRE ) @@ -3328,7 +3990,7 @@ DECLARE_INTERACTION( g_interactionCombineBash ); // // hide from the loudest sound source (to run from grenade) //========================================================= -DEFINE_SCHEDULE +DEFINE_SCHEDULE ( SCHED_COMBINE_TAKE_COVER_FROM_BEST_SOUND, @@ -3345,7 +4007,7 @@ DEFINE_SCHEDULE " Interrupts" ) - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_RUN_AWAY_FROM_BEST_SOUND, @@ -3360,7 +4022,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_COMBAT_FAIL //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_COMBAT_FAIL, @@ -3380,7 +4042,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_VICTORY_DANCE //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_VICTORY_DANCE, @@ -3403,7 +4065,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_ASSAULT //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_ASSAULT, @@ -3431,7 +4093,7 @@ DEFINE_SCHEDULE " COND_HEAR_MOVE_AWAY" ) - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_ESTABLISH_LINE_OF_FIRE, @@ -3461,7 +4123,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_PRESS_ATTACK //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_PRESS_ATTACK, @@ -3508,7 +4170,7 @@ DEFINE_SCHEDULE ) //========================================================= - // SCHED_HIDE_AND_RELOAD + // SCHED_HIDE_AND_RELOAD //========================================================= DEFINE_SCHEDULE ( @@ -3562,7 +4224,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_SUPPRESS //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_SUPPRESS, @@ -3589,7 +4251,7 @@ DEFINE_SCHEDULE // Parks a combine soldier in place looking at the player's // last known position, ready to attack if the player pops out //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_ENTER_OVERWATCH, @@ -3611,7 +4273,7 @@ DEFINE_SCHEDULE // Parks a combine soldier in place looking at the player's // last known position, ready to attack if the player pops out //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_OVERWATCH, @@ -3659,7 +4321,7 @@ DEFINE_SCHEDULE //========================================================= // SCHED_COMBINE_TAKE_COVER1 //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_TAKE_COVER1 , @@ -3815,7 +4477,7 @@ DEFINE_SCHEDULE ) //========================================================= - // SCHED_COMBINE_RANGE_ATTACK2 + // SCHED_COMBINE_RANGE_ATTACK2 // // secondary range attack. Overriden because base class stops attacking when the enemy is occluded. // combines's grenade toss requires the enemy be occluded. @@ -3854,13 +4516,13 @@ DEFINE_SCHEDULE " Interrupts" ) - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_PATROL, " Tasks" " TASK_STOP_MOVING 0" - " TASK_WANDER 900540" + " TASK_WANDER 900540" " TASK_WALK_PATH 0" " TASK_WAIT_FOR_MOVEMENT 0" " TASK_STOP_MOVING 0" @@ -3980,14 +4642,14 @@ DEFINE_SCHEDULE // Used instead if SCHED_COMBINE_PATROL if I have an enemy. // Wait for the enemy a bit in the hopes of ambushing him. //========================================================= - DEFINE_SCHEDULE + DEFINE_SCHEDULE ( SCHED_COMBINE_PATROL_ENEMY, " Tasks" " TASK_STOP_MOVING 0" - " TASK_WAIT_FACE_ENEMY 1" - " TASK_WAIT_FACE_ENEMY_RANDOM 3" + " TASK_WAIT_FACE_ENEMY 1" + " TASK_WAIT_FACE_ENEMY_RANDOM 3" "" " Interrupts" " COND_ENEMY_DEAD" diff --git a/game/server/hl2/npc_combine.h b/game/server/hl2/npc_combine.h index ab166723c..6cd8eef8 100644 --- a/game/server/hl2/npc_combine.h +++ b/game/server/hl2/npc_combine.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -21,6 +21,15 @@ #include "ai_behavior_actbusy.h" #include "ai_sentence.h" #include "ai_baseactor.h" +#ifdef MAPBASE +#include "mapbase/ai_grenade.h" +#include "ai_behavior_police.h" +#endif +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE +#include "mapbase/expandedrs_combine.h" +//#define CAI_Sentence CAI_SentenceTalker +#define COMBINE_SOLDIER_USES_RESPONSE_SYSTEM 1 +#endif // Used when only what combine to react to what the spotlight sees #define SF_COMBINE_NO_LOOK (1 << 16) @@ -30,11 +39,19 @@ //========================================================= // >> CNPC_Combine //========================================================= +#ifdef MAPBASE +class CNPC_Combine : public CAI_GrenadeUser +{ + DECLARE_DATADESC(); + DEFINE_CUSTOM_AI; + DECLARE_CLASS( CNPC_Combine, CAI_GrenadeUser ); +#else class CNPC_Combine : public CAI_BaseActor { DECLARE_DATADESC(); DEFINE_CUSTOM_AI; DECLARE_CLASS( CNPC_Combine, CAI_BaseActor ); +#endif public: CNPC_Combine(); @@ -42,8 +59,10 @@ class CNPC_Combine : public CAI_BaseActor // Create components virtual bool CreateComponents(); +#ifndef MAPBASE // CAI_GrenadeUser bool CanThrowGrenade( const Vector &vecTarget ); bool CheckCanThrowGrenade( const Vector &vecTarget ); +#endif virtual bool CanGrenadeEnemy( bool bUseFreeKnowledge = true ); virtual bool CanAltFireEnemy( bool bUseFreeKnowledge ); int GetGrenadeConditions( float flDot, float flDist ); @@ -56,6 +75,10 @@ class CNPC_Combine : public CAI_BaseActor virtual Vector GetCrouchEyeOffset( void ); +#ifdef MAPBASE + virtual bool IsCrouchedActivity( Activity activity ); +#endif + void Event_Killed( const CTakeDamageInfo &info ); @@ -69,7 +92,17 @@ class CNPC_Combine : public CAI_BaseActor void InputStopPatrolling( inputdata_t &inputdata ); void InputAssault( inputdata_t &inputdata ); void InputHitByBugbait( inputdata_t &inputdata ); +#ifndef MAPBASE void InputThrowGrenadeAtTarget( inputdata_t &inputdata ); +#else + void InputSetElite( inputdata_t &inputdata ); + + void InputDropGrenade( inputdata_t &inputdata ); + + void InputSetTacticalVariant( inputdata_t &inputdata ); + + void InputSetPoliceGoal( inputdata_t &inputdata ); +#endif bool UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position, CBaseEntity *pInformer = NULL ); @@ -79,8 +112,16 @@ class CNPC_Combine : public CAI_BaseActor Class_T Classify( void ); bool IsElite() { return m_fIsElite; } +#ifdef MAPBASE + bool IsAltFireCapable(); + bool IsGrenadeCapable(); + const char* GetGrenadeAttachment() { return "lefthand"; } +#else +#endif +#ifndef MAPBASE // CAI_GrenadeUser void DelayAltFireAttack( float flDelay ); void DelaySquadAltFireAttack( float flDelay ); +#endif float MaxYawSpeed( void ); bool ShouldMoveAndShoot(); bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );; @@ -90,7 +131,9 @@ class CNPC_Combine : public CAI_BaseActor Vector EyeOffset( Activity nActivity ); Vector EyePosition( void ); Vector BodyTarget( const Vector &posSrc, bool bNoisy = true ); +#ifndef MAPBASE // CAI_GrenadeUser Vector GetAltFireTarget(); +#endif void StartTask( const Task_t *pTask ); void RunTask( const Task_t *pTask ); @@ -98,6 +141,10 @@ class CNPC_Combine : public CAI_BaseActor void GatherConditions(); virtual void PrescheduleThink(); +#ifdef MAPBASE + Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL ); + Activity NPC_BackupActivity( Activity eNewActivity ); +#endif Activity NPC_TranslateActivity( Activity eNewActivity ); void BuildScheduleTestBits( void ); virtual int SelectSchedule( void ); @@ -125,8 +172,13 @@ class CNPC_Combine : public CAI_BaseActor // ------------- // Sounds // ------------- +#ifdef MAPBASE + void DeathSound( const CTakeDamageInfo &info ); + void PainSound( const CTakeDamageInfo &info ); +#else void DeathSound( void ); void PainSound( void ); +#endif void IdleSound( void ); void AlertSound( void ); void LostEnemySound( void ); @@ -143,6 +195,15 @@ class CNPC_Combine : public CAI_BaseActor // Speaking void SpeakSentence( int sentType ); +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + bool SpeakIfAllowed( const char *rrConcept, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ) + { + return SpeakIfAllowed( rrConcept, NULL, sentencepriority, sentencecriteria ); + } + bool SpeakIfAllowed( const char *rrConcept, const char *modifiers, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ); + bool SpeakIfAllowed( const char *rrConcept, AI_CriteriaSet& modifiers, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ); + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); +#endif virtual int TranslateSchedule( int scheduleType ); void OnStartSchedule( int scheduleType ); @@ -151,7 +212,9 @@ class CNPC_Combine : public CAI_BaseActor protected: void SetKickDamage( int nDamage ) { m_nKickDamage = nDamage; } +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM CAI_Sentence< CNPC_Combine > *GetSentences() { return &m_Sentences; } +#endif private: //========================================================= @@ -198,7 +261,7 @@ class CNPC_Combine : public CAI_BaseActor //========================================================= // Combine Tasks //========================================================= - enum + enum { TASK_COMBINE_FACE_TOSS_DIR = BaseClass::NEXT_TASK, TASK_COMBINE_IGNORE_ATTACKS, @@ -257,37 +320,58 @@ class CNPC_Combine : public CAI_BaseActor private: int m_nKickDamage; +#ifndef MAPBASE // CAI_GrenadeUser Vector m_vecTossVelocity; EHANDLE m_hForcedGrenadeTarget; +#else + // Underthrow grenade at target + bool m_bUnderthrow; + bool m_bAlternateCapable; +#endif bool m_bShouldPatrol; bool m_bFirstEncounter;// only put on the handsign show in the squad's first encounter. // Time Variables float m_flNextPainSoundTime; float m_flNextAlertSoundTime; - float m_flNextGrenadeCheck; +#ifndef MAPBASE // CAI_GrenadeUser + float m_flNextGrenadeCheck; +#endif float m_flNextLostSoundTime; float m_flAlertPatrolTime; // When to stop doing alert patrol +#ifndef MAPBASE // CAI_GrenadeUser float m_flNextAltFireTime; // Elites only. Next time to begin considering alt-fire attack. +#endif int m_nShots; float m_flShotDelay; float m_flStopMoveShootTime; +#ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM CAI_Sentence< CNPC_Combine > m_Sentences; +#endif +#ifndef MAPBASE // CAI_GrenadeUser int m_iNumGrenades; +#endif CAI_AssaultBehavior m_AssaultBehavior; CCombineStandoffBehavior m_StandoffBehavior; CAI_FollowBehavior m_FollowBehavior; CAI_FuncTankBehavior m_FuncTankBehavior; CAI_RappelBehavior m_RappelBehavior; CAI_ActBusyBehavior m_ActBusyBehavior; +#ifdef MAPBASE + CAI_PolicingBehavior m_PolicingBehavior; +#endif public: +#ifndef MAPBASE // CAI_GrenadeUser int m_iLastAnimEventHandled; +#endif bool m_fIsElite; +#ifndef MAPBASE // CAI_GrenadeUser Vector m_vecAltFireTarget; +#endif int m_iTacticalVariant; int m_iPathfindingVariant; diff --git a/game/server/hl2/npc_combinecamera.cpp b/game/server/hl2/npc_combinecamera.cpp index 26d1f07e..13bbba1b 100644 --- a/game/server/hl2/npc_combinecamera.cpp +++ b/game/server/hl2/npc_combinecamera.cpp @@ -547,7 +547,11 @@ bool CNPC_CombineCamera::FVisible(CBaseEntity *pEntity, int traceMask, CBaseEnti // If we hit something that's okay to hit anyway, still fire if ( pHitEntity && pHitEntity->MyCombatCharacterPointer() ) { +#ifdef MAPBASE + if (IRelationType(pHitEntity) <= D_FR) +#else if (IRelationType(pHitEntity) == D_HT) +#endif return true; } @@ -623,6 +627,14 @@ void CNPC_CombineCamera::ActiveThink() if ( !pTarget ) { // Nobody suspicious. Go back to being idle. +#ifdef MAPBASE + if (m_hEnemyTarget) + { + m_OnLostEnemy.FireOutput( m_hEnemyTarget, this ); + if (m_hEnemyTarget->IsPlayer()) + m_OnLostPlayer.FireOutput( m_hEnemyTarget, this ); + } +#endif m_hEnemyTarget = NULL; EmitSound("NPC_CombineCamera.BecomeIdle"); SetAngry(false); diff --git a/game/server/hl2/npc_combinedropship.cpp b/game/server/hl2/npc_combinedropship.cpp index ffe1befd..572d60a5 100644 --- a/game/server/hl2/npc_combinedropship.cpp +++ b/game/server/hl2/npc_combinedropship.cpp @@ -175,6 +175,11 @@ class CCombineDropshipContainer : public CPhysicsProp virtual int OnTakeDamage( const CTakeDamageInfo &info ); virtual void Event_Killed( const CTakeDamageInfo &info ); +#ifdef MAPBASE + // NOTE: This function is shared across containers and dropships; this is the container's version + bool AllowsAnyDamage( const CTakeDamageInfo &info ); +#endif + private: enum { @@ -247,6 +252,11 @@ class CNPC_CombineDropship : public CBaseHelicopter void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ); int OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ); +#ifdef MAPBASE + // NOTE: This function is shared across containers and dropships; this is the dropship's version + bool AllowsAnyDamage() { return m_bAllowAnyDamage; } +#endif + // Input handlers. void InputLandLeave( inputdata_t &inputdata ); void InputLandTake( inputdata_t &inputdata ); @@ -254,6 +264,9 @@ class CNPC_CombineDropship : public CBaseHelicopter void InputDropMines( inputdata_t &inputdata ); void InputDropStrider( inputdata_t &inputdata ); void InputDropAPC( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDropCargo( inputdata_t &inputdata ); +#endif void InputPickup( inputdata_t &inputdata ); void InputSetGunRange( inputdata_t &inputdata ); @@ -317,6 +330,9 @@ class CNPC_CombineDropship : public CBaseHelicopter EHANDLE m_hPickupTarget; int m_iContainerMoveType; bool m_bWaitForDropoffInput; +#ifdef MAPBASE + bool m_bDontEmitDanger; +#endif DECLARE_DATADESC(); DEFINE_CUSTOM_AI; @@ -357,6 +373,10 @@ class CNPC_CombineDropship : public CBaseHelicopter COutputFloat m_OnContainerShotDownBeforeDropoff; COutputEvent m_OnContainerShotDownAfterDropoff; +#ifdef MAPBASE + COutputEHANDLE m_OnSpawnNPC; +#endif + protected: // Because the combine dropship is a leaf class, we can use // static variables to store this information, and save some memory. @@ -614,6 +634,23 @@ void CCombineDropshipContainer::Event_Killed( const CTakeDamageInfo &info ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCombineDropshipContainer::AllowsAnyDamage( const CTakeDamageInfo &info ) +{ + if (GetOwnerEntity()) + { + CNPC_CombineDropship *pDropship = assert_cast(GetOwnerEntity()); + return pDropship->AllowsAnyDamage() && pDropship->PassesDamageFilter(info); + } + + return false; +} +#endif + + //----------------------------------------------------------------------------- // Damage effects //----------------------------------------------------------------------------- @@ -623,7 +660,11 @@ int CCombineDropshipContainer::OnTakeDamage( const CTakeDamageInfo &info ) return 0; // Airboat guns + explosive damage is all that can hurt it +#ifdef MAPBASE + if (( info.GetDamageType() & (DMG_BLAST | DMG_AIRBOAT) ) == 0 && !AllowsAnyDamage(info) ) +#else if (( info.GetDamageType() & (DMG_BLAST | DMG_AIRBOAT) ) == 0 ) +#endif return 0; CTakeDamageInfo dmgInfo = info; @@ -648,9 +689,15 @@ int CCombineDropshipContainer::OnTakeDamage( const CTakeDamageInfo &info ) if ( m_iHealth <= 0 ) { - m_iHealth = 0; - Event_Killed( dmgInfo ); - return 0; +#ifdef MAPBASE_VSCRIPT + // False = Cheat death + if (ScriptDeathHook( const_cast(&info) ) != false) +#endif + { + m_iHealth = 0; + Event_Killed( dmgInfo ); + return 0; + } } // Spawn damage effects @@ -764,6 +811,9 @@ BEGIN_DATADESC( CNPC_CombineDropship ) DEFINE_FIELD( m_hPickupTarget, FIELD_EHANDLE ), DEFINE_FIELD( m_iContainerMoveType, FIELD_INTEGER ), DEFINE_FIELD( m_bWaitForDropoffInput, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDontEmitDanger, FIELD_BOOLEAN, "DontEmitDanger" ), +#endif DEFINE_FIELD( m_hLandTarget, FIELD_EHANDLE ), DEFINE_FIELD( m_bHasDroppedOff, FIELD_BOOLEAN ), DEFINE_KEYFIELD( m_bInvulnerable, FIELD_BOOLEAN, "Invulnerable" ), @@ -810,6 +860,9 @@ BEGIN_DATADESC( CNPC_CombineDropship ) DEFINE_INPUTFUNC( FIELD_INTEGER, "DropMines", InputDropMines ), DEFINE_INPUTFUNC( FIELD_VOID, "DropStrider", InputDropStrider ), DEFINE_INPUTFUNC( FIELD_VOID, "DropAPC", InputDropAPC ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DropCargo", InputDropCargo ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "Pickup", InputPickup ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetGunRange", InputSetGunRange ), DEFINE_INPUTFUNC( FIELD_STRING, "NPCFinishDustoff", InputNPCFinishDustoff ), @@ -823,6 +876,10 @@ BEGIN_DATADESC( CNPC_CombineDropship ) DEFINE_OUTPUT( m_OnContainerShotDownBeforeDropoff, "OnCrateShotDownBeforeDropoff" ), DEFINE_OUTPUT( m_OnContainerShotDownAfterDropoff, "OnCrateShotDownAfterDropoff" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnSpawnNPC, "OnSpawnNPC" ), +#endif + END_DATADESC() @@ -896,6 +953,11 @@ void CNPC_CombineDropship::Spawn( void ) m_iMachineGunBaseAttachment = m_hContainer->LookupAttachment( "gun_base" ); // NOTE: gun_ref must have the same position as gun_base, but rotates with the gun m_iMachineGunRefAttachment = m_hContainer->LookupAttachment( "gun_ref" ); + +#ifdef MAPBASE + m_poseWeapon_Pitch = m_hContainer->LookupPoseParameter("weapon_pitch"); //added these two lines + m_poseWeapon_Yaw = m_hContainer->LookupPoseParameter("weapon_yaw"); +#endif } break; @@ -907,6 +969,9 @@ void CNPC_CombineDropship::Spawn( void ) m_hContainer->SetOwnerEntity(this); m_hContainer->Spawn(); m_hContainer->SetAbsOrigin( GetAbsOrigin() - Vector( 0, 0 , 100 ) ); +#ifdef MAPBASE + m_OnSpawnNPC.Set( m_hContainer, m_hContainer, this ); +#endif break; case CRATE_APC: @@ -934,7 +999,11 @@ void CNPC_CombineDropship::Spawn( void ) IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { +#ifdef MAPBASE + pPhysicsObject->SetShadow( 1e4, 1e4, true, true ); // (allowing physics movement and rotation) +#else pPhysicsObject->SetShadow( 1e4, 1e4, false, false ); +#endif } m_hContainer->SetParent(this, 0); @@ -1399,7 +1468,11 @@ int CNPC_CombineDropship::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) // code above to see how to do it. if ( m_hContainer && !m_bInvulnerable ) { +#ifdef MAPBASE + if ( (inputInfo.GetDamageType() & DMG_AIRBOAT) || (m_iCrateType == CRATE_SOLDIER) || m_bAllowAnyDamage ) +#else if ( (inputInfo.GetDamageType() & DMG_AIRBOAT) || (m_iCrateType == CRATE_SOLDIER) ) +#endif { m_hContainer->TakeDamage( inputInfo ); } @@ -1754,11 +1827,59 @@ void CNPC_CombineDropship::InputDropAPC( inputdata_t &inputdata ) UTIL_SetSize( this, DROPSHIP_BBOX_MIN, DROPSHIP_BBOX_MAX ); +#ifdef MAPBASE + m_OnFinishedDropoff.FireOutput( m_hContainer, this ); + m_hContainer = NULL; +#else m_hContainer = NULL; m_OnFinishedDropoff.FireOutput( this, this ); +#endif + SetLandingState( LANDING_NO ); + m_hLandTarget = NULL; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_CombineDropship::InputDropCargo( inputdata_t &inputdata ) +{ + if ( !m_hContainer ) + { + Warning("npc_combinedropship %s was told to drop cargo, but isn't carrying any!\n", STRING(GetEntityName()) ); + return; + } + + m_hContainer->SetParent(NULL, 0); +// m_hContainer->SetOwnerEntity(NULL); + + Vector vecAbsVelocity = GetAbsVelocity(); + if ( vecAbsVelocity.z > 0 ) + { + vecAbsVelocity.z = 0.0f; + } + if ( m_hContainer->GetHealth() > 0 ) + { + vecAbsVelocity = vec3_origin; + } + + m_hContainer->SetAbsVelocity( vecAbsVelocity ); + m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType ); + + // If the container has a physics object, remove it's shadow + IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); + if ( pPhysicsObject ) + { + pPhysicsObject->RemoveShadowController(); + } + + UTIL_SetSize( this, DROPSHIP_BBOX_MIN, DROPSHIP_BBOX_MAX ); + + m_OnFinishedDropoff.FireOutput( m_hContainer, this ); + m_hContainer = NULL; SetLandingState( LANDING_NO ); m_hLandTarget = NULL; } +#endif //----------------------------------------------------------------------------- @@ -1796,13 +1917,19 @@ void CNPC_CombineDropship::DropSoldierContainer( ) UTIL_SetSize( this, DROPSHIP_BBOX_MIN, DROPSHIP_BBOX_MAX ); +#ifndef MAPBASE m_hContainer = NULL; +#endif SetLandingState( LANDING_NO ); m_hLandTarget = NULL; if ( m_bHasDroppedOff ) { +#ifdef MAPBASE + m_OnContainerShotDownAfterDropoff.FireOutput( m_hContainer, this ); +#else m_OnContainerShotDownAfterDropoff.FireOutput( this, this ); +#endif } else { @@ -1812,8 +1939,16 @@ void CNPC_CombineDropship::DropSoldierContainer( ) Msg("Dropship died, troops not unloaded: %d\n", iTroopsNotUnloaded ); } +#ifdef MAPBASE + m_OnContainerShotDownBeforeDropoff.Set( iTroopsNotUnloaded, m_hContainer, this ); +#else m_OnContainerShotDownBeforeDropoff.Set( iTroopsNotUnloaded, this, this ); +#endif } + +#ifdef MAPBASE + m_hContainer = NULL; +#endif } @@ -2082,10 +2217,17 @@ void CNPC_CombineDropship::PrescheduleThink( void ) // place danger sounds 1 foot above ground to get troops to scatter if they are below dropship Vector vecBottom = GetAbsOrigin(); vecBottom.z += WorldAlignMins().z; +#ifdef MAPBASE + if (!m_bDontEmitDanger) + { +#endif Vector vecSpot = vecBottom + Vector(0, 0, -1) * (flAltitude - 12 ); CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.1, this, 0 ); CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.1, this, 1 ); // NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f ); +#ifdef MAPBASE + } +#endif // now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move) trace_t tr; @@ -2257,7 +2399,11 @@ void CNPC_CombineDropship::PrescheduleThink( void ) SetLandingState( LANDING_NO ); m_hLandTarget = NULL; m_bHasDroppedOff = true; +#ifdef MAPBASE + m_OnFinishedDropoff.FireOutput( m_hContainer, this ); +#else m_OnFinishedDropoff.FireOutput( this, this ); +#endif } if ( m_hContainer ) @@ -2290,7 +2436,7 @@ void CNPC_CombineDropship::PrescheduleThink( void ) float flSpeed = GetAbsVelocity().Length(); Vector vecVelocity = vecToTarget; VectorNormalize( vecVelocity ); - SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) ); + SetAbsVelocity( vecVelocity * MIN(flSpeed,flDistance) ); } else */ @@ -2317,7 +2463,11 @@ void CNPC_CombineDropship::PrescheduleThink( void ) m_hContainer->SetMoveType( MOVETYPE_PUSH ); m_hContainer->SetGroundEntity( NULL ); +#ifdef MAPBASE + m_OnFinishedPickup.FireOutput( m_hContainer, this ); +#else m_OnFinishedPickup.FireOutput( this, this ); +#endif SetLandingState( LANDING_NO ); } } @@ -2395,6 +2545,9 @@ void CNPC_CombineDropship::SpawnTroop( void ) QAngle vecDeployEndAngles; m_hContainer->GetAttachment( m_iAttachmentTroopDeploy, vecDeployEndPoint, vecDeployEndAngles ); vecDeployEndPoint = GetDropoffFinishPosition( vecDeployEndPoint, NULL, vecNPCMins, vecNPCMaxs ); +#ifdef MAPBASE + if (!m_bDontEmitDanger) +#endif CSoundEnt::InsertSound( SOUND_DANGER, vecDeployEndPoint, 120.0f, 2.0f, this ); // Make sure there are no NPCs on the spot @@ -2470,6 +2623,10 @@ void CNPC_CombineDropship::SpawnTroop( void ) pSequence->AcceptInput( "BeginSequence", this, this, emptyVariant, 0 ); m_hLastTroopToLeave = pNPC; + +#ifdef MAPBASE + m_OnSpawnNPC.Set( pNPC, pNPC, this ); +#endif } //----------------------------------------------------------------------------- @@ -2633,7 +2790,12 @@ float CNPC_CombineDropship::GetAltitude( void ) //----------------------------------------------------------------------------- void CNPC_CombineDropship::DropMine( void ) { +#ifdef MAPBASE + CBaseEntity *pMine = NPC_Rollermine_DropFromPoint( GetAbsOrigin(), this, STRING( m_sRollermineTemplateData ) ); + m_OnSpawnNPC.Set( pMine, pMine, this ); +#else NPC_Rollermine_DropFromPoint( GetAbsOrigin(), this, STRING(m_sRollermineTemplateData) ); +#endif } //------------------------------------------------------------------------------ diff --git a/game/server/hl2/npc_combinegunship.cpp b/game/server/hl2/npc_combinegunship.cpp index 25831053..dfe0aa20 100644 --- a/game/server/hl2/npc_combinegunship.cpp +++ b/game/server/hl2/npc_combinegunship.cpp @@ -51,6 +51,10 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +#define BELLYBLAST +#endif + #define GUNSHIP_MSG_BIG_SHOT 1 #define GUNSHIP_MSG_STREAKS 2 @@ -370,6 +374,10 @@ class CNPC_CombineGunship : public CBaseHelicopter int m_iDoSmokePuff; int m_iAmmoType; int m_iBurstSize; + +#ifdef MAPBASE + int m_iHealthIncrements; +#endif bool m_fBlindfire; bool m_fOmniscient; @@ -420,7 +428,11 @@ BEGIN_DATADESC( CNPC_CombineGunship ) DEFINE_FIELD( m_flNextGroundAttack,FIELD_TIME ), DEFINE_FIELD( m_bIsGroundAttacking,FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bCanGroundAttack, FIELD_BOOLEAN, "CanGroundAttack" ), +#else DEFINE_FIELD( m_bCanGroundAttack, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_flGroundAttackTime,FIELD_TIME ), DEFINE_FIELD( m_pRotorWashModel, FIELD_CLASSPTR ), DEFINE_FIELD( m_pSmokeTrail, FIELD_EHANDLE ), @@ -437,6 +449,9 @@ BEGIN_DATADESC( CNPC_CombineGunship ) DEFINE_FIELD( m_iDoSmokePuff, FIELD_INTEGER ), DEFINE_FIELD( m_iAmmoType, FIELD_INTEGER ), DEFINE_FIELD( m_iBurstSize, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iHealthIncrements, FIELD_INTEGER, "HealthIncrements" ), +#endif DEFINE_FIELD( m_flBurstDelay, FIELD_FLOAT ), DEFINE_FIELD( m_fBlindfire, FIELD_BOOLEAN ), DEFINE_FIELD( m_fOmniscient, FIELD_BOOLEAN ), @@ -552,6 +567,11 @@ void CNPC_CombineGunship::Spawn( void ) m_iMaxHealth = m_iHealth = 100; +#ifdef MAPBASE + if (m_iHealthIncrements == 0) + m_iHealthIncrements = sk_gunship_health_increments.GetInt(); +#endif + m_flFieldOfView = -0.707; // 270 degrees m_fHelicopterFlags |= BITS_HELICOPTER_GUN_ON; @@ -601,8 +621,10 @@ void CNPC_CombineGunship::Spawn( void ) m_bPreFire = false; m_bInvulnerable = false; +#ifndef MAPBASE // Spawnflag has been replaced with KV // See if we should start being able to attack m_bCanGroundAttack = ( m_spawnflags & SF_GUNSHIP_NO_GROUND_ATTACK ) ? false : true; +#endif m_flEndDestructTime = 0; @@ -2831,7 +2853,13 @@ void CNPC_CombineGunship::MakeTracer( const Vector &vecTracerSrc, const trace_t void CNPC_CombineGunship::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ) { // Reflect bullets +#ifdef MAPBASE + // There's a keyvalue that allows any damage, but still reflect if the bullets wouldn't pass our damage filter. + if ( info.GetDamageType() & DMG_BULLET && + (!m_bAllowAnyDamage || !PassesDamageFilter(info)) ) +#else if ( info.GetDamageType() & DMG_BULLET ) +#endif { if ( random->RandomInt( 0, 2 ) == 0 ) { @@ -2912,7 +2940,11 @@ void CNPC_CombineGunship::FireDamageOutputsUpto( int iDamageNumber ) int CNPC_CombineGunship::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) { // Allow npc_kill to kill me +#ifdef MAPBASE + if ( inputInfo.GetDamageType() != DMG_GENERIC && !m_bAllowAnyDamage ) +#else if ( inputInfo.GetDamageType() != DMG_GENERIC ) +#endif { // Ignore mundane bullet damage. if ( ( inputInfo.GetDamageType() & DMG_BLAST ) == false ) @@ -2945,7 +2977,11 @@ int CNPC_CombineGunship::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) { // Take a percentage of our health away // Adjust health for damage +#ifdef MAPBASE + int iHealthIncrements = m_iHealthIncrements; +#else int iHealthIncrements = sk_gunship_health_increments.GetInt(); +#endif if ( g_pGameRules->IsSkillLevel( SKILL_EASY ) ) { iHealthIncrements = ceil( iHealthIncrements * 0.5 ); diff --git a/game/server/hl2/npc_combines.cpp b/game/server/hl2/npc_combines.cpp index 9addfbeb..be85d895 100644 --- a/game/server/hl2/npc_combines.cpp +++ b/game/server/hl2/npc_combines.cpp @@ -96,7 +96,12 @@ void CNPC_CombineS::Precache() { const char *pModelName = STRING( GetModelName() ); +#ifdef MAPBASE + // Need to do this for dirt variant + if( !Q_strnicmp( pModelName, "models/combine_super_sold", 25 ) ) +#else if( !Q_stricmp( pModelName, "models/combine_super_soldier.mdl" ) ) +#endif { m_fIsElite = true; } @@ -122,14 +127,21 @@ void CNPC_CombineS::Precache() void CNPC_CombineS::DeathSound( const CTakeDamageInfo &info ) { +#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + SpeakIfAllowed( TLK_CMB_DIE, set, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#else // NOTE: The response system deals with this at the moment if ( GetFlags() & FL_DISSOLVING ) return; GetSentences()->Speak( "COMBINE_DIE", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif } +#ifndef MAPBASE // Moved to CAI_GrenadeUser //----------------------------------------------------------------------------- // Purpose: Soldiers use CAN_RANGE_ATTACK2 to indicate whether they can throw // a grenade. Because they check only every half-second or so, this @@ -151,6 +163,7 @@ void CNPC_CombineS::ClearAttackConditions( ) SetCondition( COND_CAN_RANGE_ATTACK2 ); } } +#endif void CNPC_CombineS::PrescheduleThink( void ) { @@ -307,7 +320,15 @@ void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info ) if ( HasSpawnFlags( SF_COMBINE_NO_AR2DROP ) == false ) #endif { +#ifdef MAPBASE + CBaseEntity *pItem; + if (GetActiveWeapon() && FClassnameIs(GetActiveWeapon(), "weapon_smg1")) + pItem = DropItem( "item_ammo_smg1_grenade", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); + else + pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); +#else CBaseEntity *pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); +#endif if ( pItem ) { diff --git a/game/server/hl2/npc_combines.h b/game/server/hl2/npc_combines.h index e9dc75b2..7c7d8fbe 100644 --- a/game/server/hl2/npc_combines.h +++ b/game/server/hl2/npc_combines.h @@ -35,7 +35,9 @@ class CNPC_CombineS : public CNPC_Combine void Event_Killed( const CTakeDamageInfo &info ); void OnListened(); +#ifndef MAPBASE // Moved to CAI_GrenadeUser void ClearAttackConditions( void ); +#endif bool m_fIsBlocking; diff --git a/game/server/hl2/npc_eli.cpp b/game/server/hl2/npc_eli.cpp index 4b42c6c0..c66e9273 100644 --- a/game/server/hl2/npc_eli.cpp +++ b/game/server/hl2/npc_eli.cpp @@ -37,6 +37,11 @@ class CNPC_Eli : public CAI_BaseActor int GetSoundInterests( void ); void SetupWithoutParent( void ); void PrescheduleThink( void ); + +#ifdef MAPBASE + // Use Eli's default subtitle color (255,208,172) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 255; params.g1 = 208; params.b1 = 172; return BaseClass::GetGameTextSpeechParams( params ); } +#endif }; LINK_ENTITY_TO_CLASS( npc_eli, CNPC_Eli ); diff --git a/game/server/hl2/npc_enemyfinder.cpp b/game/server/hl2/npc_enemyfinder.cpp index 02afc08b..d9855815 100644 --- a/game/server/hl2/npc_enemyfinder.cpp +++ b/game/server/hl2/npc_enemyfinder.cpp @@ -59,6 +59,10 @@ class CNPC_EnemyFinder : public CAI_BaseNPC void InputTurnOff( inputdata_t &inputdata ); virtual void Wake( bool bFireOutput = true ); +#ifdef MAPBASE + // A version of Wake() that takes an activator + virtual void Wake(CBaseEntity* pActivator); +#endif private: int m_nStartOn; @@ -69,6 +73,10 @@ class CNPC_EnemyFinder : public CAI_BaseNPC bool m_bEnemyStatus; +#ifdef MAPBASE + Class_T m_iClassify = CLASS_NONE; +#endif + COutputEvent m_OnLostEnemies; COutputEvent m_OnAcquireEnemies; @@ -103,6 +111,10 @@ BEGIN_DATADESC( CNPC_EnemyFinder ) DEFINE_FIELD( m_bEnemyStatus, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_INPUT( m_iClassify, FIELD_INTEGER, "SetClassify" ), +#endif + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), @@ -226,6 +238,16 @@ void CNPC_EnemyFinder::Wake( bool bFireOutput ) AddEffects( EF_NODRAW ); } +#ifdef MAPBASE +void CNPC_EnemyFinder::Wake(CBaseEntity* pActivator) +{ + BaseClass::Wake(pActivator); + + //Enemy finder is not allowed to become visible. + AddEffects(EF_NODRAW); +} +#endif // MAPBASE + //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ @@ -417,7 +439,11 @@ bool CNPC_EnemyFinder::ShouldAlwaysThink() return true; CBasePlayer *pPlayer = AI_GetSinglePlayer(); +#ifdef MAPBASE + if ( pPlayer && IRelationType( pPlayer ) <= D_FR ) +#else if ( pPlayer && IRelationType( pPlayer ) == D_HT ) +#endif { float playerDistSqr = GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() ); @@ -454,6 +480,11 @@ void CNPC_EnemyFinder::GatherConditions() //----------------------------------------------------------------------------- Class_T CNPC_EnemyFinder::Classify( void ) { +#ifdef MAPBASE + if (m_iClassify != CLASS_NONE) + return m_iClassify; +#endif + if ( GetSquad() ) { AISquadIter_t iter; diff --git a/game/server/hl2/npc_fastzombie.cpp b/game/server/hl2/npc_fastzombie.cpp index 0ecd7155..6e5ec136 100644 --- a/game/server/hl2/npc_fastzombie.cpp +++ b/game/server/hl2/npc_fastzombie.cpp @@ -61,6 +61,12 @@ enum COND_FASTZOMBIE_CLIMB_TOUCH = LAST_BASE_ZOMBIE_CONDITION, }; +#ifdef MAPBASE +ConVar sk_zombie_fast_health( "sk_zombie_fast_health", "50"); +ConVar sk_zombie_fast_dmg_one_slash( "sk_zombie_fast_dmg_claw","3"); +ConVar sk_zombie_fast_dmg_both_slash( "sk_zombie_fast_dmg_leap","5"); +#endif + envelopePoint_t envFastZombieVolumeJump[] = { { 1.0f, 1.0f, @@ -255,7 +261,9 @@ class CFastZombie : public CNPC_BaseZombie void OnChangeActivity( Activity NewActivity ); void OnStateChange( NPC_STATE OldState, NPC_STATE NewState ); void Event_Killed( const CTakeDamageInfo &info ); +#ifndef MAPBASE bool ShouldBecomeTorso( const CTakeDamageInfo &info, float flDamageThreshold ); +#endif virtual Vector GetAutoAimCenter() { return WorldSpaceCenter() - Vector( 0, 0, 12.0f ); } @@ -652,7 +660,9 @@ void CFastZombie::Spawn( void ) m_fJustJumped = false; +#ifndef MAPBASE // Controlled by KV m_fIsTorso = m_fIsHeadless = false; +#endif if( FClassnameIs( this, "npc_fastzombie" ) ) { @@ -670,7 +680,11 @@ void CFastZombie::Spawn( void ) SetBloodColor( BLOOD_COLOR_YELLOW ); #endif // HL2_EPISODIC +#ifdef MAPBASE + m_iHealth = sk_zombie_fast_health.GetInt(); +#else m_iHealth = 50; +#endif m_flFieldOfView = 0.2; CapabilitiesClear(); @@ -1084,7 +1098,11 @@ void CFastZombie::HandleAnimEvent( animevent_t *pEvent ) right = right * -50; QAngle angle( -3, -5, -3 ); +#ifdef MAPBASE + ClawAttack( GetClawAttackRange(), sk_zombie_fast_dmg_one_slash.GetInt(), angle, right, ZOMBIE_BLOOD_RIGHT_HAND ); +#else ClawAttack( GetClawAttackRange(), 3, angle, right, ZOMBIE_BLOOD_RIGHT_HAND ); +#endif return; } @@ -1094,7 +1112,11 @@ void CFastZombie::HandleAnimEvent( animevent_t *pEvent ) AngleVectors( GetLocalAngles(), NULL, &right, NULL ); right = right * 50; QAngle angle( -3, 5, -3 ); +#ifdef MAPBASE + ClawAttack( GetClawAttackRange(), sk_zombie_fast_dmg_one_slash.GetInt(), angle, right, ZOMBIE_BLOOD_LEFT_HAND ); +#else ClawAttack( GetClawAttackRange(), 3, angle, right, ZOMBIE_BLOOD_LEFT_HAND ); +#endif return; } @@ -1274,7 +1296,11 @@ void CFastZombie::StartTask( const Task_t *pTask ) CBaseEntity *pEnemy = GetEnemy(); Vector vecJumpDir; - if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN ) + if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN +#if EXPANDED_NAVIGATION_ACTIVITIES + || GetActivity() == ACT_CLIMB_ALL +#endif + ) { // Jump off the pipe backwards! Vector forward; @@ -1427,7 +1453,11 @@ int CFastZombie::TranslateSchedule( int scheduleType ) break; case SCHED_FASTZOMBIE_UNSTICK_JUMP: - if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN || GetActivity() == ACT_CLIMB_DISMOUNT ) + if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN || GetActivity() == ACT_CLIMB_DISMOUNT +#if EXPANDED_NAVIGATION_ACTIVITIES + || (GetActivity() >= ACT_CLIMB_ALL && GetActivity() <= ACT_CLIMB_DISMOUNT_BOTTOM) +#endif + ) { return SCHED_FASTZOMBIE_CLIMBING_UNSTICK_JUMP; } @@ -1455,8 +1485,10 @@ int CFastZombie::TranslateSchedule( int scheduleType ) //--------------------------------------------------------- Activity CFastZombie::NPC_TranslateActivity( Activity baseAct ) { +#ifndef MAPBASE // Now covered by CAI_BaseNPC::NPC_BackupActivity if ( baseAct == ACT_CLIMB_DOWN ) return ACT_CLIMB_UP; +#endif return BaseClass::NPC_TranslateActivity( baseAct ); } @@ -1480,7 +1512,11 @@ void CFastZombie::LeapAttackTouch( CBaseEntity *pOther ) forward *= 500; QAngle qaPunch( 15, random->RandomInt(-5,5), random->RandomInt(-5,5) ); +#ifdef MAPBASE + ClawAttack( GetClawAttackRange(), sk_zombie_fast_dmg_both_slash.GetInt(), qaPunch, forward, ZOMBIE_BLOOD_BOTH_HANDS ); +#else ClawAttack( GetClawAttackRange(), 5, qaPunch, forward, ZOMBIE_BLOOD_BOTH_HANDS ); +#endif SetTouch( NULL ); } @@ -1848,6 +1884,7 @@ void CFastZombie::Event_Killed( const CTakeDamageInfo &info ) BaseClass::Event_Killed( dInfo ); } +#ifndef MAPBASE //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool CFastZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDamageThreshold ) @@ -1868,6 +1905,7 @@ bool CFastZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDamage return false; } +#endif //============================================================================= #ifdef HL2_EPISODIC diff --git a/game/server/hl2/npc_fisherman.cpp b/game/server/hl2/npc_fisherman.cpp index 4530f261..967c5795 100644 --- a/game/server/hl2/npc_fisherman.cpp +++ b/game/server/hl2/npc_fisherman.cpp @@ -64,8 +64,10 @@ class CNPC_Fisherman : public CNPC_PlayerCompanion virtual void Precache() { +#ifndef MAPBASE // This is now done in CNPC_PlayerCompanion::Precache() // Prevents a warning - SelectModel( ); + SelectModel(); +#endif BaseClass::Precache(); PrecacheScriptSound( "NPC_Fisherman.FootstepLeft" ); diff --git a/game/server/hl2/npc_headcrab.cpp b/game/server/hl2/npc_headcrab.cpp index 6e7d3e71..b1b8db81 100644 --- a/game/server/hl2/npc_headcrab.cpp +++ b/game/server/hl2/npc_headcrab.cpp @@ -72,6 +72,10 @@ ConVar g_debug_headcrab( "g_debug_headcrab", "0", FCVAR_CHEAT ); //------------------------------------ #define SF_HEADCRAB_START_HIDDEN (1 << 16) #define SF_HEADCRAB_START_HANGING (1 << 17) +#ifdef MAPBASE +#define SF_HEADCRAB_DONT_DROWN (1 << 18) +#define SF_HEADCRAB_NO_MELEE_INSTAKILL (1 << 19) +#endif //----------------------------------------------------------------------------- @@ -218,6 +222,10 @@ BEGIN_DATADESC( CBaseHeadcrab ) DEFINE_INPUTFUNC( FIELD_VOID, "StartHangingFromCeiling", InputStartHangingFromCeiling ), DEFINE_INPUTFUNC( FIELD_VOID, "DropFromCeiling", InputDropFromCeiling ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnLeap, "OnLeap" ), +#endif + // Function Pointers DEFINE_THINKFUNC( EliminateRollAndPitch ), DEFINE_THINKFUNC( ThrowThink ), @@ -482,6 +490,11 @@ void CBaseHeadcrab::Leap( const Vector &vecVel ) m_bMidJump = true; SetThink( &CBaseHeadcrab::ThrowThink ); SetNextThink( gpGlobals->curtime ); + +#ifdef MAPBASE + // We usually leap at an enemy, so use that as the activator + m_OnLeap.FireOutput(GetEnemy(), this); +#endif } @@ -926,7 +939,11 @@ void CBaseHeadcrab::LeapTouch( CBaseEntity *pOther ) { m_bMidJump = false; +#ifdef MAPBASE + if ( IRelationType( pOther ) <= D_FR ) +#else if ( IRelationType( pOther ) == D_HT ) +#endif { // Don't hit if back on ground if ( !( GetFlags() & FL_ONGROUND ) ) @@ -1032,7 +1049,11 @@ void CBaseHeadcrab::GatherConditions( void ) BaseClass::GatherConditions(); +#ifdef MAPBASE + if (GetWaterLevel() > 1 && m_lifeState == LIFE_ALIVE && !HasSpawnFlags( SF_HEADCRAB_DONT_DROWN )) +#else if( m_lifeState == LIFE_ALIVE && GetWaterLevel() > 1 ) +#endif { // Start Drowning! SetCondition( COND_HEADCRAB_IN_WATER ); @@ -1712,7 +1733,12 @@ int CBaseHeadcrab::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) // // Certain death from melee bludgeon weapons! // +#ifdef MAPBASE + // (unless the mapper said no) + if ( info.GetDamageType() & DMG_CLUB && !HasSpawnFlags( SF_HEADCRAB_NO_MELEE_INSTAKILL ) ) +#else if ( info.GetDamageType() & DMG_CLUB ) +#endif { info.SetDamage( m_iHealth ); } @@ -2230,6 +2256,9 @@ void CBaseHeadcrab::GrabHintNode( CAI_Hint *pHint ) { SetHintNode( pHint ); pHint->Lock( this ); +#ifdef MAPBASE + pHint->NPCStartedUsing( this ); +#endif } } @@ -2404,7 +2433,7 @@ void CBaseHeadcrab::CreateDust( bool placeDecal ) //----------------------------------------------------------------------------- void CHeadcrab::Precache( void ) { - PrecacheModel( "models/headcrabclassic.mdl" ); + PrecacheModel( DefaultOrCustomModel( "models/headcrabclassic.mdl" ) ); PrecacheScriptSound( "NPC_HeadCrab.Gib" ); PrecacheScriptSound( "NPC_HeadCrab.Idle" ); @@ -2426,7 +2455,7 @@ void CHeadcrab::Precache( void ) void CHeadcrab::Spawn( void ) { Precache(); - SetModel( "models/headcrabclassic.mdl" ); + SetModel( DefaultOrCustomModel( "models/headcrabclassic.mdl" ) ); BaseClass::Spawn(); @@ -2541,7 +2570,7 @@ END_DATADESC() //----------------------------------------------------------------------------- void CFastHeadcrab::Precache( void ) { - PrecacheModel( "models/headcrab.mdl" ); + PrecacheModel( DefaultOrCustomModel( "models/headcrab.mdl" ) ); PrecacheScriptSound( "NPC_FastHeadcrab.Idle" ); PrecacheScriptSound( "NPC_FastHeadcrab.Alert" ); @@ -2560,7 +2589,7 @@ void CFastHeadcrab::Precache( void ) void CFastHeadcrab::Spawn( void ) { Precache(); - SetModel( "models/headcrab.mdl" ); + SetModel( DefaultOrCustomModel( "models/headcrab.mdl" ) ); BaseClass::Spawn(); @@ -3060,7 +3089,7 @@ void CBlackHeadcrab::TelegraphSound( void ) void CBlackHeadcrab::Spawn( void ) { Precache(); - SetModel( "models/headcrabblack.mdl" ); + SetModel( DefaultOrCustomModel( "models/headcrabblack.mdl" ) ); BaseClass::Spawn(); @@ -3077,7 +3106,7 @@ void CBlackHeadcrab::Spawn( void ) //----------------------------------------------------------------------------- void CBlackHeadcrab::Precache( void ) { - PrecacheModel( "models/headcrabblack.mdl" ); + PrecacheModel( DefaultOrCustomModel( "models/headcrabblack.mdl" ) ); PrecacheScriptSound( "NPC_BlackHeadcrab.Telegraph" ); PrecacheScriptSound( "NPC_BlackHeadcrab.Attack" ); diff --git a/game/server/hl2/npc_headcrab.h b/game/server/hl2/npc_headcrab.h index daf79b46..8c4103ad 100644 --- a/game/server/hl2/npc_headcrab.h +++ b/game/server/hl2/npc_headcrab.h @@ -149,6 +149,10 @@ abstract_class CBaseHeadcrab : public CAI_BaseNPC bool m_bHangingFromCeiling; float m_flIlluminatedTime; + +#ifdef MAPBASE + COutputEvent m_OnLeap; +#endif }; diff --git a/game/server/hl2/npc_houndeye.cpp b/game/server/hl2/npc_houndeye.cpp index 9b4b7c14..c121d11a 100644 --- a/game/server/hl2/npc_houndeye.cpp +++ b/game/server/hl2/npc_houndeye.cpp @@ -29,8 +29,6 @@ #include "engine/IEngineSound.h" #include "movevars_shared.h" -#pragma warning(disable:4706) - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -523,7 +521,7 @@ void CNPC_Houndeye::AlertSound ( void ) //========================================================= // DeathSound //========================================================= -void CNPC_Houndeye::DeathSound (const CTakeDamageInfo &info) +void CNPC_Houndeye::DeathSound ( void ) { EmitSound( "NPC_Houndeye.Die" ); } @@ -531,7 +529,7 @@ void CNPC_Houndeye::DeathSound (const CTakeDamageInfo &info) //========================================================= // PainSound //========================================================= -void CNPC_Houndeye::PainSound (const CTakeDamageInfo &info) +void CNPC_Houndeye::PainSound ( void ) { EmitSound( "NPC_Houndeye.Pain" ); } @@ -804,7 +802,7 @@ void CNPC_Houndeye::StartTask( const Task_t *pTask ) Vector vTargetPos = GetEnemyLKP(); vTargetPos.z = GetFloorZ(vTargetPos); - if (GetNavigator()->SetRadialGoal(vTargetPos, vTargetPos, random->RandomInt(50, 500), 90, 175, m_bLoopClockwise)) + if (GetNavigator()->SetRadialGoal(vTargetPos, random->RandomInt(50,500), 90, 175, m_bLoopClockwise)) { TaskComplete(); return; diff --git a/game/server/hl2/npc_kleiner.cpp b/game/server/hl2/npc_kleiner.cpp index e8081762..4e5e5cf8 100644 --- a/game/server/hl2/npc_kleiner.cpp +++ b/game/server/hl2/npc_kleiner.cpp @@ -35,6 +35,11 @@ class CNPC_Kleiner : public CAI_BaseActor Class_T Classify ( void ); void HandleAnimEvent( animevent_t *pEvent ); int GetSoundInterests ( void ); + +#ifdef MAPBASE + // Use Kleiner's default subtitle color (255,255,200) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 255; params.g1 = 255; params.b1 = 200; return BaseClass::GetGameTextSpeechParams( params ); } +#endif }; LINK_ENTITY_TO_CLASS( npc_kleiner, CNPC_Kleiner ); diff --git a/game/server/hl2/npc_launcher.cpp b/game/server/hl2/npc_launcher.cpp index 9e942862..817bab23 100644 --- a/game/server/hl2/npc_launcher.cpp +++ b/game/server/hl2/npc_launcher.cpp @@ -62,6 +62,9 @@ class CNPC_Launcher : public CAI_BaseNPC // Outputs // ---------------- COutputEvent m_OnLaunch; // Triggered when missile is launched. +#ifdef MAPBASE + COutputEHANDLE m_OutMissile; // Passes the missile. +#endif // ---------------- // Inputs @@ -126,6 +129,9 @@ BEGIN_DATADESC( CNPC_Launcher ) DEFINE_INPUTFUNC( FIELD_VOID, "ClearEnemyEntity", InputClearEnemy ), DEFINE_OUTPUT( m_OnLaunch, "OnLaunch" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OutMissile, "OutMissile" ), +#endif // Function Pointers DEFINE_THINKFUNC( LauncherThink ), @@ -278,6 +284,13 @@ void CNPC_Launcher::LaunchGrenade( CBaseEntity* pEnemy ) pGrenade->SetDamage(m_flDamage); pGrenade->SetDamageRadius(m_flDamageRadius); pGrenade->Launch(m_flLaunchSpeed,m_sPathCornerName); + +#ifdef MAPBASE + if (GetOwnerEntity()) + pGrenade->SetOwnerEntity(GetOwnerEntity()); + + m_OutMissile.Set(pGrenade, pGrenade, this); +#endif } else { @@ -292,6 +305,13 @@ void CNPC_Launcher::LaunchGrenade( CBaseEntity* pEnemy ) pGrenade->SetDamage(m_flDamage); pGrenade->SetDamageRadius(m_flDamageRadius); pGrenade->Launch(this,pEnemy,vLaunchVelocity,m_flHomingSpeed,GetGravity(),m_nSmokeTrail); + +#ifdef MAPBASE + if (GetOwnerEntity()) + pGrenade->SetOwnerEntity(GetOwnerEntity()); + + m_OutMissile.Set(pGrenade, pGrenade, this); +#endif } CPASAttenuationFilter filter( this, 0.3 ); diff --git a/game/server/hl2/npc_manhack.cpp b/game/server/hl2/npc_manhack.cpp index 48812d1a..8ed24bdd 100644 --- a/game/server/hl2/npc_manhack.cpp +++ b/game/server/hl2/npc_manhack.cpp @@ -78,6 +78,10 @@ #define MANHACK_CHARGE_MIN_DIST 200 +#if defined(MAPBASE) && defined(HL2_EPISODIC) +extern ConVar npc_alyx_interact_manhacks; +#endif + ConVar sk_manhack_health( "sk_manhack_health","0"); ConVar sk_manhack_melee_dmg( "sk_manhack_melee_dmg","0"); ConVar sk_manhack_v2( "sk_manhack_v2","1"); @@ -149,7 +153,11 @@ BEGIN_DATADESC( CNPC_Manhack ) DEFINE_FIELD( m_bGib, FIELD_BOOLEAN), DEFINE_FIELD( m_bHeld, FIELD_BOOLEAN), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bHackedByAlyx, FIELD_BOOLEAN, "Hacked" ), +#else DEFINE_FIELD( m_bHackedByAlyx, FIELD_BOOLEAN), +#endif DEFINE_FIELD( m_vecLoiterPosition, FIELD_POSITION_VECTOR), DEFINE_FIELD( m_fTimeNextLoiterPulse, FIELD_TIME), @@ -159,6 +167,10 @@ BEGIN_DATADESC( CNPC_Manhack ) DEFINE_FIELD( m_flBladeSpeed, FIELD_FLOAT), DEFINE_KEYFIELD( m_bIgnoreClipbrushes, FIELD_BOOLEAN, "ignoreclipbrushes" ), DEFINE_FIELD( m_hSmokeTrail, FIELD_EHANDLE), +#ifdef MAPBASE + DEFINE_FIELD( m_hPrevOwner, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_bNoSprites, FIELD_BOOLEAN, "NoSprites" ), +#endif // DEFINE_FIELD( m_pLightGlow, FIELD_CLASSPTR ), // DEFINE_FIELD( m_pEyeGlow, FIELD_CLASSPTR ), @@ -187,6 +199,10 @@ BEGIN_DATADESC( CNPC_Manhack ) // Function Pointers DEFINE_INPUTFUNC( FIELD_VOID, "DisableSwarm", InputDisableSwarm ), DEFINE_INPUTFUNC( FIELD_VOID, "Unpack", InputUnpack ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "EnableSprites", InputEnableSprites ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableSprites", InputDisableSprites ), +#endif DEFINE_ENTITYFUNC( CrashTouch ), @@ -236,10 +252,11 @@ CNPC_Manhack::~CNPC_Manhack() } #ifdef VANCE -void CNPC_Manhack::Hack(void) +void CNPC_Manhack::Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) { m_bHackedByAlyx = true; - SetEyeState(MANHACK_EYE_STATE_CHARGE); + SetEyeState( MANHACK_EYE_STATE_CHARGE ); + BaseClass::Hack( pActivator, pCaller ); } #endif @@ -1527,7 +1544,11 @@ void CNPC_Manhack::Slice( CBaseEntity *pHitEntity, float flInterval, trace_t &tr pHitEntity->TakeDamage( info ); // Spawn some extra blood where we hit +#ifdef MAPBASE + if ( pHitEntity->BloodColor() == DONT_BLEED || (IRelationType(pHitEntity) > D_FR && !pHitEntity->PassesDamageFilter(info)) ) +#else if ( pHitEntity->BloodColor() == DONT_BLEED ) +#endif { CEffectData data; Vector velocity = GetCurrentVelocity(); @@ -2181,9 +2202,9 @@ void CNPC_Manhack::Precache(void) // // Model. // - PrecacheModel("models/manhack.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/manhack.mdl" ) ); PrecacheModel( MANHACK_GLOW_SPRITE ); - PropBreakablePrecacheAll( MAKE_STRING("models/manhack.mdl") ); + PropBreakablePrecacheAll( MAKE_STRING( DefaultOrCustomModel( "models/manhack.mdl" ) ) ); PrecacheScriptSound( "NPC_Manhack.Die" ); PrecacheScriptSound( "NPC_Manhack.Bat" ); @@ -2377,7 +2398,7 @@ void CNPC_Manhack::Spawn(void) AddSpawnFlags( SF_NPC_FADE_CORPSE ); #endif // _XBOX - SetModel( "models/manhack.mdl" ); + SetModel( DefaultOrCustomModel( "models/manhack.mdl" ) ); SetHullType(HULL_TINY_CENTERED); SetHullSizeNormal(); @@ -2461,7 +2482,9 @@ void CNPC_Manhack::Spawn(void) SetCollisionGroup( COLLISION_GROUP_NONE ); m_bHeld = false; +#ifndef MAPBASE m_bHackedByAlyx = false; +#endif StopLoitering(); } @@ -2470,6 +2493,11 @@ void CNPC_Manhack::Spawn(void) //----------------------------------------------------------------------------- void CNPC_Manhack::StartEye( void ) { +#ifdef MAPBASE + if (m_bNoSprites) + return; +#endif + //Create our Eye sprite if ( m_pEyeGlow == NULL ) { @@ -2989,6 +3017,26 @@ void CNPC_Manhack::InputUnpack( inputdata_t &inputdata ) SetCondition( COND_LIGHT_DAMAGE ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Creates the sprite if it has been destroyed +//----------------------------------------------------------------------------- +void CNPC_Manhack::InputEnableSprites( inputdata_t &inputdata ) +{ + m_bNoSprites = false; + StartEye(); +} + +//----------------------------------------------------------------------------- +// Purpose: Destroys the sprite +//----------------------------------------------------------------------------- +void CNPC_Manhack::InputDisableSprites( inputdata_t &inputdata ) +{ + KillSprites( 0.0 ); + m_bNoSprites = true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : *pPhysGunUser - @@ -3015,6 +3063,11 @@ void CNPC_Manhack::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t r } else { +#ifdef MAPBASE + // Store the previous owner in case of npc_maker + m_hPrevOwner.Set(GetOwnerEntity()); +#endif + // Suppress collisions between the manhack and the player; we're currently bumping // almost certainly because it's not purely a physics object. SetOwnerEntity( pPhysGunUser ); @@ -3031,7 +3084,13 @@ void CNPC_Manhack::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t r void CNPC_Manhack::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ) { // Stop suppressing collisions between the manhack and the player +#ifndef MAPBASE SetOwnerEntity( NULL ); +#else + SetOwnerEntity( m_hPrevOwner ); + + m_hPrevOwner = NULL; +#endif m_bHeld = false; @@ -3096,6 +3155,20 @@ float CNPC_Manhack::GetMaxEnginePower() return 1.0f; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Option to restore Alyx's interactions with non-rollermines +//----------------------------------------------------------------------------- +bool CNPC_Manhack::CanInteractWith( CAI_BaseNPC *pUser ) +{ +#ifdef HL2_EPISODIC + return npc_alyx_interact_manhacks.GetBool(); +#else + return false; +#endif +} +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -3207,16 +3280,43 @@ void CNPC_Manhack::SetEyeState( int state ) if ( m_pEyeGlow ) { //Toggle our state +#ifdef MAPBASE + // Makes it easier to distinguish between hostile and friendly manhacks. + if( m_bHackedByAlyx ) + { + m_pEyeGlow->SetColor( 0, 0, 255 ); + m_pEyeGlow->SetScale( 0.35f, 0.6f ); + } + else + { + m_pEyeGlow->SetColor( 255, 128, 0 ); + m_pEyeGlow->SetScale( 0.15f, 0.1f ); + } +#else m_pEyeGlow->SetColor( 255, 128, 0 ); m_pEyeGlow->SetScale( 0.15f, 0.1f ); +#endif m_pEyeGlow->SetBrightness( 164, 0.1f ); m_pEyeGlow->m_nRenderFX = kRenderFxStrobeFast; } if ( m_pLightGlow ) { +#ifdef MAPBASE + if( m_bHackedByAlyx ) + { + m_pLightGlow->SetColor( 0, 0, 255 ); + m_pLightGlow->SetScale( 0.35f, 0.6f ); + } + else + { + m_pLightGlow->SetColor( 255, 128, 0 ); + m_pLightGlow->SetScale( 0.15f, 0.1f ); + } +#else m_pLightGlow->SetColor( 255, 128, 0 ); m_pLightGlow->SetScale( 0.15f, 0.1f ); +#endif m_pLightGlow->SetBrightness( 164, 0.1f ); m_pLightGlow->m_nRenderFX = kRenderFxStrobeFast; } diff --git a/game/server/hl2/npc_manhack.h b/game/server/hl2/npc_manhack.h index fd376972..84af93a5 100644 --- a/game/server/hl2/npc_manhack.h +++ b/game/server/hl2/npc_manhack.h @@ -60,11 +60,6 @@ DECLARE_SERVERCLASS(); CNPC_Manhack(); ~CNPC_Manhack(); -#ifdef VANCE - bool IsHackable(void) { return true; } - void Hack(void); -#endif - Class_T Classify(void); bool CorpseGib( const CTakeDamageInfo &info ); @@ -150,6 +145,10 @@ DECLARE_SERVERCLASS(); void InputDisableSwarm( inputdata_t &inputdata ); void InputUnpack( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputEnableSprites( inputdata_t &inputdata ); + void InputDisableSprites( inputdata_t &inputdata ); +#endif // CDefaultPlayerPickupVPhysics virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); @@ -160,7 +159,11 @@ DECLARE_SERVERCLASS(); float GetMaxEnginePower(); // INPCInteractive Functions +#ifdef MAPBASE + virtual bool CanInteractWith( CAI_BaseNPC *pUser ); +#else virtual bool CanInteractWith( CAI_BaseNPC *pUser ) { return false; } // Disabled for now (sjb) +#endif virtual bool HasBeenInteractedWith() { return m_bHackedByAlyx; } virtual void NotifyInteraction( CAI_BaseNPC *pUser ) { @@ -168,6 +171,9 @@ DECLARE_SERVERCLASS(); KillSprites(0.0f); m_bHackedByAlyx = true; StartEye(); +#ifdef MAPBASE + m_OnHacked.FireOutput(pUser, this); +#endif } virtual void InputPowerdown( inputdata_t &inputdata ) @@ -175,6 +181,10 @@ DECLARE_SERVERCLASS(); m_iHealth = 0; } +#ifdef VANCE + bool IsHackable() const override { return true; } + void Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) override; +#endif DEFINE_CUSTOM_AI; @@ -259,6 +269,11 @@ DECLARE_SERVERCLASS(); CSprite *m_pLightGlow; CHandle m_hSmokeTrail; +#ifdef MAPBASE + EHANDLE m_hPrevOwner; + + bool m_bNoSprites; +#endif int m_iPanel1; int m_iPanel2; diff --git a/game/server/hl2/npc_metropolice.cpp b/game/server/hl2/npc_metropolice.cpp index 01d66258..b7054f56 100644 --- a/game/server/hl2/npc_metropolice.cpp +++ b/game/server/hl2/npc_metropolice.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -19,6 +19,10 @@ #include "iservervehicle.h" #include "items.h" #include "hl2_gamerules.h" +#ifdef MAPBASE +#include "grenade_frag.h" +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -65,7 +69,7 @@ enum METROPOLICE_SENTENCE_FREEZE = 0, METROPOLICE_SENTENCE_HES_OVER_HERE = 1, METROPOLICE_SENTENCE_HES_RUNNING = 2, - METROPOLICE_SENTENCE_TAKE_HIM_DOWN = 3, + METROPOLICE_SENTENCE_TAKE_HIM_DOWN = 3, METROPOLICE_SENTENCE_ARREST_IN_POSITION = 4, METROPOLICE_SENTENCE_DEPLOY_MANHACK = 5, METROPOLICE_SENTENCE_MOVE_INTO_POSITION = 6, @@ -119,6 +123,10 @@ ConVar metropolice_chase_use_follow( "metropolice_chase_use_follow", "0" ); ConVar metropolice_move_and_melee("metropolice_move_and_melee", "1" ); ConVar metropolice_charge("metropolice_charge", "1" ); +#ifdef MAPBASE +ConVar metropolice_new_component_behavior("metropolice_new_component_behavior", "1"); +#endif + // How many clips of pistol ammo a metropolice carries. #define METROPOLICE_NUM_CLIPS 5 #define METROPOLICE_BURST_RELOAD_COUNT 20 @@ -159,12 +167,12 @@ int ACT_PUSH_PLAYER; int ACT_MELEE_ATTACK_THRUST; int ACT_ACTIVATE_BATON; int ACT_DEACTIVATE_BATON; - + LINK_ENTITY_TO_CLASS( npc_metropolice, CNPC_MetroPolice ); BEGIN_DATADESC( CNPC_MetroPolice ) - DEFINE_EMBEDDED( m_BatonSwingTimer ), + DEFINE_EMBEDDED( m_BatonSwingTimer ), DEFINE_EMBEDDED( m_NextChargeTimer ), DEFINE_FIELD( m_flBatonDebounceTime, FIELD_FLOAT ), DEFINE_FIELD( m_bShouldActivateBaton, FIELD_BOOLEAN ), @@ -172,7 +180,9 @@ BEGIN_DATADESC( CNPC_MetroPolice ) DEFINE_KEYFIELD( m_fWeaponDrawn, FIELD_BOOLEAN, "weapondrawn" ), DEFINE_FIELD( m_LastShootSlot, FIELD_INTEGER ), DEFINE_EMBEDDED( m_TimeYieldShootSlot ), +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM DEFINE_EMBEDDED( m_Sentences ), +#endif DEFINE_FIELD( m_bPlayerIsNear, FIELD_BOOLEAN ), DEFINE_FIELD( m_vecBurstTargetPos, FIELD_POSITION_VECTOR ), @@ -225,13 +235,34 @@ BEGIN_DATADESC( CNPC_MetroPolice ) DEFINE_KEYFIELD( m_iManhacks, FIELD_INTEGER, "manhacks" ), DEFINE_INPUTFUNC( FIELD_VOID, "EnableManhackToss", InputEnableManhackToss ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DisableManhackToss", InputDisableManhackToss ), + DEFINE_INPUTFUNC( FIELD_VOID, "DeployManhack", InputDeployManhack ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddManhacks", InputAddManhacks ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetManhacks", InputSetManhacks ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetPoliceGoal", InputSetPoliceGoal ), DEFINE_INPUTFUNC( FIELD_VOID, "ActivateBaton", InputActivateBaton ), - +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "AdministerJustice", InputAdministerJustice ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddWarnings", InputAddWarnings ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetWarnings", InputSetWarnings ), +#endif + DEFINE_USEFUNC( PrecriminalUse ), DEFINE_OUTPUT( m_OnStunnedPlayer, "OnStunnedPlayer" ), DEFINE_OUTPUT( m_OnCupCopped, "OnCupCopped" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnHitByPhysicsObject, "OnHitByPhysicsObject" ), + DEFINE_OUTPUT( m_OutManhack, "OutManhack" ), +#endif + +#ifdef MAPBASE + DEFINE_AIGRENADE_DATADESC() + DEFINE_INPUT( m_iGrenadeCapabilities, FIELD_INTEGER, "SetGrenadeCapabilities" ), + DEFINE_INPUT( m_iGrenadeDropCapabilities, FIELD_INTEGER, "SetGrenadeDropCapabilities" ), +#endif END_DATADESC() @@ -240,7 +271,7 @@ END_DATADESC() float CNPC_MetroPolice::gm_flTimeLastSpokePeek; //------------------------------------------------------------------------------ -// Purpose +// Purpose //------------------------------------------------------------------------------ CBaseEntity *CNPC_MetroPolice::CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float forceScale, bool bDamageAnyNPC ) { @@ -250,7 +281,7 @@ CBaseEntity *CNPC_MetroPolice::CheckTraceHullAttack( float flDist, const Vector Vector vStart = GetAbsOrigin(); // The ideal place to start the trace is in the center of the attacker's bounding box. - // however, we need to make sure there's enough clearance. Some of the smaller monsters aren't + // however, we need to make sure there's enough clearance. Some of the smaller monsters aren't // as big as the hull we try to trace with. (SJB) float flVerticalOffset = WorldAlignSize().z * 0.5; @@ -274,12 +305,12 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly public: // It does have a base, but we'll never network anything below here.. DECLARE_CLASS_NOBASE( CTraceFilterMetroPolice ); - + CTraceFilterMetroPolice( const IHandleEntity *passentity, int collisionGroup, CTakeDamageInfo *dmgInfo, float flForceScale, bool bDamageAnyNPC ) : m_pPassEnt(passentity), m_collisionGroup(collisionGroup), m_dmgInfo(dmgInfo), m_pHit(NULL), m_flForceScale(flForceScale), m_bDamageAnyNPC(bDamageAnyNPC) { } - + virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) { if ( !StandardFilterRules( pHandleEntity, contentsMask ) ) @@ -290,12 +321,12 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly // Don't test if the game code tells us we should ignore this collision... CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); - + if ( pEntity ) { if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) ) return false; - + if ( !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) ) return false; @@ -312,11 +343,11 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly pEntity = pDriver; } } - + Vector attackDir = pEntity->WorldSpaceCenter() - m_dmgInfo->GetAttacker()->WorldSpaceCenter(); VectorNormalize( attackDir ); - CTakeDamageInfo info = (*m_dmgInfo); + CTakeDamageInfo info = (*m_dmgInfo); CalculateMeleeDamageForce( &info, attackDir, info.GetAttacker()->WorldSpaceCenter(), m_flForceScale ); if( !(pEntity->GetFlags() & FL_ONGROUND) ) @@ -333,7 +364,11 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly if ( pBCC && pVictimBCC ) { // Can only damage other NPCs that we hate +#ifdef MAPBASE + if ( m_bDamageAnyNPC || pBCC->IRelationType( pEntity ) <= D_FR || pEntity->IsPlayer() ) +#else if ( m_bDamageAnyNPC || pBCC->IRelationType( pEntity ) == D_HT || pEntity->IsPlayer() ) +#endif { if ( info.GetDamage() ) { @@ -349,7 +384,7 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly pEntity->TakeDamage( info ); } } - + m_pHit = pEntity; return true; } @@ -380,7 +415,7 @@ class CTraceFilterMetroPolice : public CTraceFilterEntitiesOnly }; //------------------------------------------------------------------------------ -// Purpose : start and end trace position, amount +// Purpose : start and end trace position, amount // of damage to do, and damage type. Returns a pointer to // the damaged entity in case the NPC wishes to do // other stuff to the victim (punchangle, etc) @@ -393,7 +428,7 @@ CBaseEntity *CNPC_MetroPolice::CheckTraceHullAttack( const Vector &vStart, const { CTakeDamageInfo dmgInfo( this, this, iDamage, DMG_SLASH ); - + CTraceFilterMetroPolice traceFilter( this, COLLISION_GROUP_NONE, &dmgInfo, flForceScale, bDamageAnyNPC ); Ray_t ray; @@ -403,7 +438,7 @@ CBaseEntity *CNPC_MetroPolice::CheckTraceHullAttack( const Vector &vStart, const enginetrace->TraceRay( ray, MASK_SHOT, &traceFilter, &tr ); CBaseEntity *pEntity = traceFilter.m_pHit; - + if ( pEntity == NULL ) { // See if perhaps I'm trying to claw/bash someone who is standing on my head. @@ -417,7 +452,7 @@ CBaseEntity *CNPC_MetroPolice::CheckTraceHullAttack( const Vector &vStart, const vecTopCenter.z = vecMaxs.z + 1.0f; vecEnd = vecTopCenter; vecEnd.z += 2.0f; - + ray.Init( vecTopCenter, vEnd, mins, maxs ); enginetrace->TraceRay( ray, MASK_SHOT_HULL, &traceFilter, &tr ); @@ -434,9 +469,20 @@ void CNPC_MetroPolice::NotifyDeadFriend( CBaseEntity* pFriend ) { BaseClass::NotifyDeadFriend(pFriend); +#ifdef MAPBASE + // m_hManhack is set to NULL after it's finished deploying, which means this has no chance of playing unless the manhack + // was still being deployed. This is thought to be an unintended oversight. + // Mapbase stores the metrocop thrower as the manhack's owner entity, so this code is now able to check that instead. + if ( pFriend->GetOwnerEntity() == this ) +#else if ( pFriend == m_hManhack ) +#endif { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_MANHACKKILLED, "my_manhack:1", SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL); +#else m_Sentences.Speak( "METROPOLICE_MANHACK_KILLED", SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL ); +#endif DevMsg("My manhack died!\n"); m_hManhack = NULL; return; @@ -452,6 +498,9 @@ void CNPC_MetroPolice::NotifyDeadFriend( CBaseEntity* pFriend ) m_nIdleChatterType = METROPOLICE_CHATTER_ASK_QUESTION; } +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_MANDOWN, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL); +#else if ( GetSquad()->NumMembers() < 2 ) { m_Sentences.Speak( "METROPOLICE_LAST_OF_SQUAD", SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); @@ -459,6 +508,7 @@ void CNPC_MetroPolice::NotifyDeadFriend( CBaseEntity* pFriend ) } m_Sentences.Speak( "METROPOLICE_MAN_DOWN", SENTENCE_PRIORITY_MEDIUM ); +#endif } @@ -466,11 +516,19 @@ void CNPC_MetroPolice::NotifyDeadFriend( CBaseEntity* pFriend ) //----------------------------------------------------------------------------- CNPC_MetroPolice::CNPC_MetroPolice() { +#ifdef MAPBASE + m_iGrenadeCapabilities = GRENCAP_GRENADE; + + if (ai_grenade_always_drop.GetBool()) + { + m_iGrenadeDropCapabilities = (eGrenadeDropCapabilities)(GRENDROPCAP_GRENADE | GRENDROPCAP_ALTFIRE | GRENDROPCAP_INTERRUPTED); + } +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::OnScheduleChange() { @@ -484,26 +542,28 @@ void CNPC_MetroPolice::OnScheduleChange() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM // Speak any queued sentences m_Sentences.UpdateSentenceQueue(); +#endif // Look at near players, always m_bPlayerIsNear = false; if ( PlayerIsCriminal() == false ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); - + if ( pPlayer && ( pPlayer->WorldSpaceCenter() - WorldSpaceCenter() ).LengthSqr() < (128*128) ) { m_bPlayerIsNear = true; AddLookTarget( pPlayer, 0.75f, 5.0f ); - + if ( ( m_PolicingBehavior.IsEnabled() == false ) && ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS ) ) { m_flBatonDebounceTime = gpGlobals->curtime + random->RandomFloat( 2.5f, 4.0f ); @@ -511,7 +571,7 @@ void CNPC_MetroPolice::PrescheduleThink( void ) SetBatonState( true ); } } - else + else { if ( m_PolicingBehavior.IsEnabled() == false && gpGlobals->curtime > m_flBatonDebounceTime ) { @@ -539,9 +599,9 @@ void CNPC_MetroPolice::PrescheduleThink( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &move - -// flInterval - +// Purpose: +// Input : &move - +// flInterval - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ) @@ -549,12 +609,12 @@ bool CNPC_MetroPolice::OverrideMoveFacing( const AILocalMoveGoal_t &move, float // Don't do this if we're scripted if ( IsInAScript() ) return BaseClass::OverrideMoveFacing( move, flInterval ); - + // ROBIN: Disabled at request of mapmakers for now /* // If we're moving during a police sequence, always face our target if ( m_PolicingBehavior.IsEnabled() ) - { + { CBaseEntity *pTarget = m_PolicingBehavior.GetGoalTarget(); if ( pTarget ) @@ -568,10 +628,15 @@ bool CNPC_MetroPolice::OverrideMoveFacing( const AILocalMoveGoal_t &move, float } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::Precache( void ) { +#ifdef MAPBASE + // It doesn't matter if we can't find models/police.mdl in the string pool because then we know this NPC doesn't have that model. + if ( GetModelName() == NULL_STRING || GetModelName() == FindPooledString("models/police.mdl") ) + { +#endif if ( HasSpawnFlags( SF_NPC_START_EFFICIENT ) ) { SetModelName( AllocPooledString("models/police_cheaple.mdl" ) ); @@ -580,6 +645,9 @@ void CNPC_MetroPolice::Precache( void ) { SetModelName( AllocPooledString("models/police.mdl") ); } +#ifdef MAPBASE + } +#endif PrecacheModel( STRING( GetModelName() ) ); @@ -602,13 +670,15 @@ bool CNPC_MetroPolice::CreateComponents() if ( !BaseClass::CreateComponents() ) return false; +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM m_Sentences.Init( this, "NPC_Metropolice.SentenceParameters" ); +#endif return true; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -630,7 +700,7 @@ void CNPC_MetroPolice::Spawn( void ) AddSolidFlags( FSOLID_NOT_STANDABLE ); SetMoveType( MOVETYPE_STEP ); SetBloodColor( BLOOD_COLOR_RED ); - m_nIdleChatterType = METROPOLICE_CHATTER_ASK_QUESTION; + m_nIdleChatterType = METROPOLICE_CHATTER_ASK_QUESTION; m_bSimpleCops = HasSpawnFlags( SF_METROPOLICE_SIMPLE_VERSION ); if ( HasSpawnFlags( SF_METROPOLICE_NOCHATTER ) ) { @@ -681,12 +751,16 @@ void CNPC_MetroPolice::Spawn( void ) pWeapon = GetActiveWeapon(); +#ifdef MAPBASE + if (!EntIsClass(pWeapon, gm_isz_class_Pistol) && !EntIsClass(pWeapon, gm_isz_class_357)) +#else if( !FClassnameIs( pWeapon, "weapon_pistol" ) ) +#endif { m_fWeaponDrawn = true; } - - if( !m_fWeaponDrawn ) + + if( !m_fWeaponDrawn ) { GetActiveWeapon()->AddEffects( EF_NODRAW ); } @@ -706,7 +780,11 @@ void CNPC_MetroPolice::Spawn( void ) // Clear out spawnflag if we're missing the smg1 if( HasSpawnFlags( SF_METROPOLICE_ALWAYS_STITCH ) ) { +#ifdef MAPBASE + if ( !Weapon_OwnsThisType( STRING(gm_isz_class_SMG1) ) ) +#else if ( !Weapon_OwnsThisType( "weapon_smg1" ) ) +#endif { Warning( "Warning! Metrocop is trying to use the stitch behavior but he has no smg1!\n" ); RemoveSpawnFlags( SF_METROPOLICE_ALWAYS_STITCH ); @@ -752,6 +830,23 @@ void CNPC_MetroPolice::SpeakFuncTankSentence( int nSentenceType ) { switch ( nSentenceType ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + case FUNCTANK_SENTENCE_MOVE_TO_MOUNT: + SpeakIfAllowed( TLK_COP_FT_APPROACH, SENTENCE_PRIORITY_MEDIUM ); + break; + + case FUNCTANK_SENTENCE_JUST_MOUNTED: + SpeakIfAllowed( TLK_COP_FT_MOUNT, SENTENCE_PRIORITY_HIGH ); + break; + + case FUNCTANK_SENTENCE_SCAN_FOR_ENEMIES: + SpeakIfAllowed( TLK_COP_FT_SCAN, SENTENCE_PRIORITY_NORMAL ); + break; + + case FUNCTANK_SENTENCE_DISMOUNTING: + SpeakIfAllowed( TLK_COP_FT_DISMOUNT, SENTENCE_PRIORITY_HIGH ); + break; +#else case FUNCTANK_SENTENCE_MOVE_TO_MOUNT: m_Sentences.Speak( "METROPOLICE_FT_APPROACH", SENTENCE_PRIORITY_MEDIUM ); break; @@ -767,6 +862,7 @@ void CNPC_MetroPolice::SpeakFuncTankSentence( int nSentenceType ) case FUNCTANK_SENTENCE_DISMOUNTING: m_Sentences.Speak( "METROPOLICE_FT_DISMOUNT", SENTENCE_PRIORITY_HIGH ); break; +#endif } } @@ -778,6 +874,31 @@ void CNPC_MetroPolice::SpeakStandoffSentence( int nSentenceType ) { switch ( nSentenceType ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + case STANDOFF_SENTENCE_BEGIN_STANDOFF: + SpeakIfAllowed( TLK_COP_SO_BEGIN, SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_SQUAD_LEADER ); + break; + + case STANDOFF_SENTENCE_END_STANDOFF: + SpeakIfAllowed( TLK_COP_SO_END, SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_SQUAD_LEADER ); + break; + + case STANDOFF_SENTENCE_OUT_OF_AMMO: + AnnounceOutOfAmmo( ); + break; + + case STANDOFF_SENTENCE_FORCED_TAKE_COVER: + SpeakIfAllowed( TLK_COP_SO_FORCE_COVER ); + break; + + case STANDOFF_SENTENCE_STAND_CHECK_TARGET: + if ( gm_flTimeLastSpokePeek != 0 && gpGlobals->curtime - gm_flTimeLastSpokePeek > 20 ) + { + SpeakIfAllowed( TLK_COP_SO_PEEK ); + gm_flTimeLastSpokePeek = gpGlobals->curtime; + } + break; +#else case STANDOFF_SENTENCE_BEGIN_STANDOFF: m_Sentences.Speak( "METROPOLICE_SO_BEGIN", SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_SQUAD_LEADER ); break; @@ -801,6 +922,7 @@ void CNPC_MetroPolice::SpeakStandoffSentence( int nSentenceType ) gm_flTimeLastSpokePeek = gpGlobals->curtime; } break; +#endif } } @@ -811,6 +933,37 @@ void CNPC_MetroPolice::SpeakAssaultSentence( int nSentenceType ) { switch ( nSentenceType ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + case ASSAULT_SENTENCE_HIT_RALLY_POINT: + SpeakIfAllowed( TLK_COP_AS_HIT_RALLY, SENTENCE_PRIORITY_NORMAL ); + break; + + case ASSAULT_SENTENCE_HIT_ASSAULT_POINT: + SpeakIfAllowed( TLK_COP_AS_HIT_ASSAULT, SENTENCE_PRIORITY_NORMAL ); + break; + + case ASSAULT_SENTENCE_SQUAD_ADVANCE_TO_RALLY: + if ( SpeakIfAllowed( TLK_COP_AS_ADV_RALLY, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_SQUAD_LEADER ) ) + { + GetSquad()->BroadcastInteraction( g_interactionMetrocopClearSentenceQueues, NULL ); + } + break; + + case ASSAULT_SENTENCE_SQUAD_ADVANCE_TO_ASSAULT: + if ( SpeakIfAllowed( TLK_COP_AS_ADV_ASSAULT, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_SQUAD_LEADER ) ) + { + GetSquad()->BroadcastInteraction( g_interactionMetrocopClearSentenceQueues, NULL ); + } + break; + + case ASSAULT_SENTENCE_COVER_NO_AMMO: + AnnounceOutOfAmmo( ); + break; + + case ASSAULT_SENTENCE_UNDER_ATTACK: + SpeakIfAllowed( TLK_COP_GO_ALERT ); + break; +#else case ASSAULT_SENTENCE_HIT_RALLY_POINT: m_Sentences.SpeakQueued( "METROPOLICE_AS_HIT_RALLY", SENTENCE_PRIORITY_NORMAL ); break; @@ -840,6 +993,7 @@ void CNPC_MetroPolice::SpeakAssaultSentence( int nSentenceType ) case ASSAULT_SENTENCE_UNDER_ATTACK: m_Sentences.Speak( "METROPOLICE_GO_ALERT" ); break; +#endif } } @@ -860,7 +1014,12 @@ void CNPC_MetroPolice::SpeakSentence( int nSentenceType ) return; } +#ifdef MAPBASE + // Fixed issues with standoff sentences not playing when they should + if ( m_StandoffBehavior.IsActive() ) +#else if ( GetRunningBehavior() == &m_StandoffBehavior ) +#endif { SpeakStandoffSentence( nSentenceType ); return; @@ -875,6 +1034,70 @@ void CNPC_MetroPolice::SpeakSentence( int nSentenceType ) switch ( nSentenceType ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + case METROPOLICE_SENTENCE_FREEZE: + SpeakIfAllowed( TLK_COP_FREEZE, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); + break; + + case METROPOLICE_SENTENCE_HES_OVER_HERE: + SpeakIfAllowed( TLK_COP_OVER_HERE, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); + break; + + case METROPOLICE_SENTENCE_HES_RUNNING: + SpeakIfAllowed( TLK_COP_HES_RUNNING, SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_NORMAL ); + break; + + case METROPOLICE_SENTENCE_TAKE_HIM_DOWN: + SpeakIfAllowed( TLK_COP_TAKE_HIM_DOWN, SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_NORMAL ); + break; + + case METROPOLICE_SENTENCE_ARREST_IN_POSITION: + SpeakIfAllowed( TLK_COP_ARREST_IN_POS, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); + break; + + case METROPOLICE_SENTENCE_DEPLOY_MANHACK: + SpeakIfAllowed( TLK_COP_DEPLOY_MANHACK ); + break; + + case METROPOLICE_SENTENCE_MOVE_INTO_POSITION: + { + CBaseEntity *pEntity = GetEnemy(); + + // NOTE: This is a good time to check to see if the player is hurt. + // Have the cops notice this and call out + if ( pEntity && !HasSpawnFlags( SF_METROPOLICE_ARREST_ENEMY ) ) + { + if ( pEntity->IsPlayer() && (pEntity->GetHealth() <= 20) ) + { + if ( !HasMemory(bits_MEMORY_PLAYER_HURT) ) + { + if ( SpeakIfAllowed( TLK_COP_PLAYERHIT, SENTENCE_PRIORITY_HIGH ) ) + { +#ifdef MAPBASE + if (GetSquad()) + GetSquad()->SquadRemember(bits_MEMORY_PLAYER_HURT); +#else + m_pSquad->SquadRemember(bits_MEMORY_PLAYER_HURT); +#endif + } + } + } + + if ( GetNavigator()->GetPath()->GetPathLength() > 20 * 12.0f ) + { + SpeakIfAllowed( TLK_COP_FLANK ); + } + } + } + break; + + case METROPOLICE_SENTENCE_HEARD_SOMETHING: + if ( ( GetState() == NPC_STATE_ALERT ) || ( GetState() == NPC_STATE_IDLE ) ) + { + SpeakIfAllowed( TLK_COP_HEARD_SOMETHING, SENTENCE_PRIORITY_MEDIUM ); + } + break; +#else case METROPOLICE_SENTENCE_FREEZE: m_Sentences.Speak( "METROPOLICE_FREEZE", SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); break; @@ -902,14 +1125,14 @@ void CNPC_MetroPolice::SpeakSentence( int nSentenceType ) case METROPOLICE_SENTENCE_MOVE_INTO_POSITION: { CBaseEntity *pEntity = GetEnemy(); - + // NOTE: This is a good time to check to see if the player is hurt. // Have the cops notice this and call out if ( pEntity && !HasSpawnFlags( SF_METROPOLICE_ARREST_ENEMY ) ) { if ( pEntity->IsPlayer() && (pEntity->GetHealth() <= 20) ) { - if ( !HasMemory(bits_MEMORY_PLAYER_HURT) ) + if ( !HasMemory(bits_MEMORY_PLAYER_HURT) ) { if ( m_Sentences.Speak( "METROPOLICE_PLAYERHIT", SENTENCE_PRIORITY_HIGH ) >= 0 ) { @@ -932,9 +1155,56 @@ void CNPC_MetroPolice::SpeakSentence( int nSentenceType ) m_Sentences.Speak( "METROPOLICE_HEARD_SOMETHING", SENTENCE_PRIORITY_MEDIUM ); } break; +#endif + } +} + +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM +//========================================================= +//========================================================= +bool CNPC_MetroPolice::SpeakIfAllowed( const char *rrConcept, const char *modifiers, SentencePriority_t sentencepriority, SentenceCriteria_t sentencecriteria ) +{ + AI_CriteriaSet set; + if (modifiers) + { +#ifdef NEW_RESPONSE_SYSTEM + GatherCriteria( &set, rrConcept, modifiers ); +#else + GetExpresser()->MergeModifiers(set, modifiers); +#endif + } + return SpeakIfAllowed( rrConcept, set, sentencepriority, sentencecriteria ); +} + +//========================================================= +//========================================================= +bool CNPC_MetroPolice::SpeakIfAllowed( const char *rrConcept, AI_CriteriaSet& modifiers, SentencePriority_t sentencepriority, SentenceCriteria_t sentencecriteria ) +{ + if ( sentencepriority != SENTENCE_PRIORITY_INVALID && !FOkToMakeSound( sentencepriority ) ) + return false; + + if ( !GetExpresser()->CanSpeakConcept( rrConcept ) ) + return false; + + if ( Speak( rrConcept, modifiers ) ) + { + JustMadeSound( sentencepriority, 2.0f /*GetTimeSpeechComplete()*/ ); + return true; } + + return false; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_MetroPolice::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); + + set.AppendCriteria( "numwarnings", UTIL_VarArgs("%d", m_nNumWarnings) ); +} +#endif + //----------------------------------------------------------------------------- // Speaking @@ -954,6 +1224,24 @@ void CNPC_MetroPolice::AnnounceEnemyType( CBaseEntity *pEnemy ) if ( m_pSquad->IsLeader( this ) || ( m_pSquad->GetLeader() && m_pSquad->GetLeader()->GetEnemy() != GetEnemy() ) ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + // First contact, and I'm the squad leader. + bool bEnemyInVehicle = false; + switch ( pEnemy->Classify() ) + { + case CLASS_PLAYER: + { + CBasePlayer *pPlayer = assert_cast( pEnemy ); + if ( pPlayer && pPlayer->IsInAVehicle() ) + { + bEnemyInVehicle = true; + } + } + break; + } + + SpeakIfAllowed( TLK_COP_ENEMY, UTIL_VarArgs("enemy_in_vehicle:%d", bEnemyInVehicle), SENTENCE_PRIORITY_HIGH ); +#else // First contact, and I'm the squad leader. const char *pSentenceName = "METROPOLICE_MONST"; switch ( pEnemy->Classify() ) @@ -998,13 +1286,14 @@ void CNPC_MetroPolice::AnnounceEnemyType( CBaseEntity *pEnemy ) } m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_HIGH ); +#endif } else { if ( m_pSquad->GetLeader() && FOkToMakeSound( SENTENCE_PRIORITY_MEDIUM ) ) { // squelch anything that isn't high priority so the leader can speak - JustMadeSound( SENTENCE_PRIORITY_MEDIUM ); + JustMadeSound( SENTENCE_PRIORITY_MEDIUM ); } } @@ -1019,6 +1308,11 @@ void CNPC_MetroPolice::AnnounceEnemyKill( CBaseEntity *pEnemy ) if ( !pEnemy ) return; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendEnemyCriteria(set, pEnemy); + SpeakIfAllowed( TLK_COP_KILLENEMY, set, SENTENCE_PRIORITY_HIGH ); +#else const char *pSentenceName = "METROPOLICE_KILL_MONST"; switch ( pEnemy->Classify() ) { @@ -1053,6 +1347,7 @@ void CNPC_MetroPolice::AnnounceEnemyKill( CBaseEntity *pEnemy ) } m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_HIGH ); +#endif } @@ -1061,6 +1356,16 @@ void CNPC_MetroPolice::AnnounceEnemyKill( CBaseEntity *pEnemy ) //----------------------------------------------------------------------------- void CNPC_MetroPolice::AnnounceOutOfAmmo( ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + if ( HasCondition( COND_NO_PRIMARY_AMMO ) ) + { + SpeakIfAllowed( TLK_COP_NOAMMO ); + } + else + { + SpeakIfAllowed( TLK_COP_LOWAMMO ); + } +#else if ( HasCondition( COND_NO_PRIMARY_AMMO ) ) { m_Sentences.Speak( "METROPOLICE_COVER_NO_AMMO" ); @@ -1069,6 +1374,7 @@ void CNPC_MetroPolice::AnnounceOutOfAmmo( ) { m_Sentences.Speak( "METROPOLICE_COVER_LOW_AMMO" ); } +#endif } //----------------------------------------------------------------------------- @@ -1076,6 +1382,38 @@ void CNPC_MetroPolice::AnnounceOutOfAmmo( ) //----------------------------------------------------------------------------- void CNPC_MetroPolice::AnnounceTakeCoverFromDanger( CSound *pSound ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + bool bGrenade = false; + bool bVehicle = false; + bool bManhack = false; + + CBaseEntity *pSoundOwner = pSound->m_hOwner; + if ( pSoundOwner ) + { + CBaseGrenade *pGrenade = dynamic_cast(pSoundOwner); + if ( pGrenade ) + { + if ( IRelationType( pGrenade->GetThrower() ) != D_LI ) + { + // special case call out for enemy grenades + bGrenade = true; + } + } + else if ( pSoundOwner->GetServerVehicle() ) + { + bVehicle = true; + } + else if ( FClassnameIs( pSoundOwner, "npc_manhack" ) ) + { + if ( pSoundOwner->HasPhysicsAttacker( 1.0f ) ) + { + bManhack = true; + } + } + } + + SpeakIfAllowed(TLK_COP_DANGER, UTIL_VarArgs("grenade:%d,vehicle:%d,manhack:%d", bGrenade, bVehicle, bManhack), SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_NORMAL); +#else CBaseEntity *pSoundOwner = pSound->m_hOwner; if ( pSoundOwner ) { @@ -1110,10 +1448,11 @@ void CNPC_MetroPolice::AnnounceTakeCoverFromDanger( CSound *pSound ) // dangerous sound nearby!, call it out const char *pSentenceName = "METROPOLICE_DANGER"; m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_HIGH, SENTENCE_CRITERIA_NORMAL ); +#endif } - + //----------------------------------------------------------------------------- // Are we currently firing a burst? //----------------------------------------------------------------------------- @@ -1132,7 +1471,7 @@ bool CNPC_MetroPolice::IsEnemyInAnAirboat() const if ( !GetEnemy() || !GetEnemy()->IsPlayer() ) return false; - CBaseEntity *pVehicle = static_cast( GetEnemy() )->GetVehicleEntity(); + CBaseEntity *pVehicle = static_cast( GetEnemy() )->GetVehicleEntity(); if ( !pVehicle ) return false; @@ -1150,7 +1489,7 @@ CBaseEntity *CNPC_MetroPolice::GetEnemyAirboat() const if ( !GetEnemy() || !GetEnemy()->IsPlayer() ) return NULL; - return static_cast( GetEnemy() )->GetVehicleEntity(); + return static_cast( GetEnemy() )->GetVehicleEntity(); } @@ -1164,7 +1503,7 @@ CBaseEntity *CNPC_MetroPolice::GetShootTarget() if ( !pEnemy || !pEnemy->IsPlayer() ) return pEnemy; - CBaseEntity *pVehicle = static_cast( pEnemy )->GetVehicleEntity(); + CBaseEntity *pVehicle = static_cast( pEnemy )->GetVehicleEntity(); return pVehicle ? pVehicle : pEnemy; } @@ -1197,24 +1536,29 @@ void CNPC_MetroPolice::OnUpdateShotRegulator( ) { BaseClass::OnUpdateShotRegulator(); - // FIXME: This code (except the burst interval) could be used for all weapon types + // FIXME: This code (except the burst interval) could be used for all weapon types +#ifdef MAPBASE + // Only if we actually have the pistol out + if ( GetActiveWeapon() && EntIsClass( GetActiveWeapon(), gm_isz_class_Pistol ) ) +#else if( Weapon_OwnsThisType( "weapon_pistol" ) ) +#endif { if ( m_nBurstMode == BURST_NOT_ACTIVE ) { if ( GetEnemy() ) { float dist = WorldSpaceCenter().DistTo( GetEnemy()->WorldSpaceCenter() ); - + dist = clamp( dist, MIN_PISTOL_MODIFY_DIST, MAX_PISTOL_MODIFY_DIST ); - + float factor = (dist - MIN_PISTOL_MODIFY_DIST) / (MAX_PISTOL_MODIFY_DIST - MIN_PISTOL_MODIFY_DIST); - + int nMinBurst = MIN_MIN_PISTOL_BURST + ( MAX_MIN_PISTOL_BURST - MIN_MIN_PISTOL_BURST ) * (1.0 - factor); int nMaxBurst = MIN_MAX_PISTOL_BURST + ( MAX_MAX_PISTOL_BURST - MIN_MAX_PISTOL_BURST ) * (1.0 - factor); float flMinRestInterval = MIN_MIN_PISTOL_REST_INTERVAL + ( MAX_MIN_PISTOL_REST_INTERVAL - MIN_MIN_PISTOL_REST_INTERVAL ) * factor; float flMaxRestInterval = MIN_MAX_PISTOL_REST_INTERVAL + ( MAX_MAX_PISTOL_REST_INTERVAL - MIN_MAX_PISTOL_REST_INTERVAL ) * factor; - + GetShotRegulator()->SetRestInterval( flMinRestInterval, flMaxRestInterval ); GetShotRegulator()->SetBurstShotCountRange( nMinBurst, nMaxBurst ); } @@ -1296,8 +1640,13 @@ bool CNPC_MetroPolice::ShouldAttemptToStitch() //----------------------------------------------------------------------------- // position to shoot at //----------------------------------------------------------------------------- -Vector CNPC_MetroPolice::StitchAimTarget( const Vector &posSrc, bool bNoisy ) +Vector CNPC_MetroPolice::StitchAimTarget( const Vector &posSrc, bool bNoisy ) { +#ifdef MAPBASE + if ( !GetEnemy() ) + return vec3_origin; +#endif + // This will make us aim a stitch at the feet of the player so we can see it if ( !GetEnemy()->IsPlayer() ) return GetShootTarget()->BodyTarget( posSrc, bNoisy ); @@ -1319,7 +1668,7 @@ Vector CNPC_MetroPolice::StitchAimTarget( const Vector &posSrc, bool bNoisy ) trace_t trace; GetEnemy()->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 1.0f ), &vecBodyTarget ); float flHeight = GetEnemy()->WorldAlignSize().z; - UTIL_TraceLine( vecBodyTarget, vecBodyTarget + Vector( 0, 0, -flHeight -80 ), + UTIL_TraceLine( vecBodyTarget, vecBodyTarget + Vector( 0, 0, -flHeight -80 ), (MASK_SOLID_BRUSHONLY | MASK_WATER), NULL, COLLISION_GROUP_NONE, &trace ); return trace.endpos; } @@ -1448,7 +1797,7 @@ void CNPC_MetroPolice::PredictShootTargetPosition( float flDeltaTime, float flMi } *pVecTargetVelocity = vecLeadVector; - + if ( (vecLeadVector.LengthSqr() * flDeltaTime * flDeltaTime) < flMinLeadDist * flMinLeadDist ) { VectorNormalize( vecLeadVector ); @@ -1603,7 +1952,7 @@ void CNPC_MetroPolice::AimBurstTightGrouping( float flShotTime ) Vector vecTargetVel; GetShootTarget()->GetVelocity( &vecTargetVel, NULL ); - if (( flDistToTargetSqr > TIGHT_GROUP_MIN_DIST*TIGHT_GROUP_MIN_DIST ) || + if (( flDistToTargetSqr > TIGHT_GROUP_MIN_DIST*TIGHT_GROUP_MIN_DIST ) || ( vecTargetVel.LengthSqr() > TIGHT_GROUP_MIN_SPEED * TIGHT_GROUP_MIN_SPEED )) { m_nMaxBurstHits = random->RandomInt( nHitCount, nHitCount + 1 ); @@ -1662,7 +2011,7 @@ float CNPC_MetroPolice::AimBurstAtReactionTime( float flReactionTime, float flDi flReactionTime *= flReactionFactor; } } - + return flReactionTime; } @@ -1805,7 +2154,7 @@ void CNPC_MetroPolice::AimBurstAtEnemy( float flReactionTime ) Vector vecAcross; CrossProduct( vecEnemyVelocity, Vector( 0, 0, 1 ), vecAcross ); VectorNormalize( vecAcross ); - + Vector eyeForward; AngleVectors( GetEnemy()->EyeAngles(), &eyeForward ); if ( DotProduct( vecAcross, eyeForward ) < 0.0f ) @@ -1821,7 +2170,7 @@ void CNPC_MetroPolice::AimBurstAtEnemy( float flReactionTime ) Vector vecStitchStart, vecStitchEnd; VectorMA( vecShootAt, -MIN( flStitchLength * flReactionFraction, flMaxStitchDistance ), vecDelta, vecStitchStart ); VectorMA( vecShootAt, flStitchLength * (1.0f - flReactionFraction), vecDelta, vecStitchEnd ); - + // Trace down a bit to hit the ground if we're above the ground... trace_t trace; UTIL_TraceLine( vecStitchStart, vecStitchStart + Vector( 0, 0, -512 ), (MASK_SOLID_BRUSHONLY | MASK_WATER), NULL, COLLISION_GROUP_NONE, &trace ); @@ -1866,7 +2215,7 @@ void CNPC_MetroPolice::AimBurstInFrontOfEnemy( float flReactionTime ) // The goal here is to slow him down. Choose a target position such that we predict // where he'd be in he accelerated by N over the reaction time. Prevent him from getting there. Vector vecShootAt, vecShootAtVel, vecAcross; - PredictShootTargetPosition( flReactionTime * AIM_IN_FRONT_REACTION_FRACTION, + PredictShootTargetPosition( flReactionTime * AIM_IN_FRONT_REACTION_FRACTION, AIM_IN_FRONT_OF_MINIMUM_DISTANCE, 0.0f, &vecShootAt, &vecShootAtVel ); // Now add in some extra vel in a random direction + try to prevent that.... @@ -1946,7 +2295,7 @@ void CNPC_MetroPolice::AimBurstBehindEnemy( float flShotTime ) Vector vecEndPoint1, vecEndPoint2; VectorMA( vecShootAt, -flStitchLength * 0.5f, vecAcross, vecEndPoint1 ); VectorMA( vecShootAt, flStitchLength * 0.5f, vecAcross, vecEndPoint2 ); - + m_vecBurstTargetPos = vecEndPoint1; VectorSubtract( vecEndPoint2, vecEndPoint1, m_vecBurstDelta ); @@ -1989,7 +2338,7 @@ void CNPC_MetroPolice::AimBurstAlongSideOfEnemy( float flFollowTime ) VectorNormalize( vecAcross ); // Choose the side of the vehicle which is closer to the shooter - Vector vecSidePoint; + Vector vecSidePoint; Vector vecTargetToGun; VectorSubtract( Weapon_ShootPosition(), vecShootAt, vecTargetToGun ); float flSign = ( DotProduct( vecTargetToGun, vecAcross ) > 0.0f ) ? 1.0f : -1.0f; @@ -2029,7 +2378,7 @@ void CNPC_MetroPolice::AimBurstAlongSideOfEnemy( float flFollowTime ) //----------------------------------------------------------------------------- // Different burst steering modes //----------------------------------------------------------------------------- -void CNPC_MetroPolice::SteerBurstTowardTargetUseSpeedOnly( const Vector &vecShootAt, +void CNPC_MetroPolice::SteerBurstTowardTargetUseSpeedOnly( const Vector &vecShootAt, const Vector &vecShootAtVelocity, float flPredictTime, int nShotsTillPredict ) { // Only account for changes in *speed*; ignore all changes in velocity direction, etc. @@ -2040,7 +2389,7 @@ void CNPC_MetroPolice::SteerBurstTowardTargetUseSpeedOnly( const Vector &vecShoo vecBurstDir *= (flActualSpeed - m_vecBurstPredictedSpeed) * flPredictTime; vecBurstDir /= (nShotsTillPredict - 1); - m_vecBurstPredictedSpeed = flActualSpeed; + m_vecBurstPredictedSpeed = flActualSpeed; m_vecBurstDelta += vecBurstDir; } @@ -2151,7 +2500,7 @@ void CNPC_MetroPolice::SteerBurstTowardTarget( ) // Necessary to get the cop looking at the target m_vecBurstTargetPos = GetEnemy()->WorldSpaceCenter(); return; - + case BURST_STEER_ADJUST_FOR_SPEED_CHANGES: { // Predict the airboat position at the point where we were expecting to hit them @@ -2245,10 +2594,10 @@ Vector CNPC_MetroPolice::ComputeBurstTrajectory( const Vector &shootOrigin ) // Allow for steering towards the target. SteerBurstTowardTarget(); } - + // Update the burst target position m_vecBurstTargetPos += m_vecBurstDelta; - + // NDebugOverlay::Cross3D( m_vecBurstTargetPos, -Vector(32,32,32), Vector(32,32,32), 255, 0, 255, false, 1.0f ); return vecPos; @@ -2389,7 +2738,7 @@ void CNPC_MetroPolice::FireBullets( const FireBulletsInfo_t &info ) { CBasePlayer *pPlayer = assert_cast(pEnemy); - // This makes it so that if the player gets hit underwater, + // This makes it so that if the player gets hit underwater, // he won't take damage if his viewpoint is above water. if ( !IsEnemyInAnAirboat() && ( pPlayer->GetWaterLevel() != 3 ) ) { @@ -2410,7 +2759,7 @@ void CNPC_MetroPolice::FireBullets( const FireBulletsInfo_t &info ) else { actualInfo.m_pAdditionalIgnoreEnt = pEnemy; - BaseClass::FireBullets( actualInfo ); + BaseClass::FireBullets( actualInfo ); } } else @@ -2432,7 +2781,7 @@ bool CNPC_MetroPolice::CreateBehaviors() AddBehavior( &m_AssaultBehavior ); AddBehavior( &m_StandoffBehavior ); AddBehavior( &m_FuncTankBehavior ); - + return BaseClass::CreateBehaviors(); } @@ -2444,12 +2793,54 @@ void CNPC_MetroPolice::InputEnableManhackToss( inputdata_t &inputdata ) } } +#ifdef MAPBASE +void CNPC_MetroPolice::InputDisableManhackToss( inputdata_t &inputdata ) +{ + if ( !HasSpawnFlags( SF_METROPOLICE_NO_MANHACK_DEPLOY ) ) + { + AddSpawnFlags( SF_METROPOLICE_NO_MANHACK_DEPLOY ); + } +} + +void CNPC_MetroPolice::InputDeployManhack( inputdata_t &inputdata ) +{ + // I am aware this bypasses regular deployment conditions, but the mapper wants us to deploy a manhack, damn it! + // We do have to have one, though. + if ( m_iManhacks > 0 ) + { + SetSchedule(SCHED_METROPOLICE_DEPLOY_MANHACK); + } +} + +void CNPC_MetroPolice::InputAddManhacks( inputdata_t &inputdata ) +{ + m_iManhacks += inputdata.value.Int(); + + SetBodygroup( METROPOLICE_BODYGROUP_MANHACK, (m_iManhacks > 0) ); +} + +void CNPC_MetroPolice::InputSetManhacks( inputdata_t &inputdata ) +{ + m_iManhacks = inputdata.value.Int(); + + SetBodygroup( METROPOLICE_BODYGROUP_MANHACK, (m_iManhacks > 0) ); +} +#endif + //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CNPC_MetroPolice::InputSetPoliceGoal( inputdata_t &inputdata ) { +#ifdef MAPBASE + if (/*!inputdata.value.String() ||*/ inputdata.value.String()[0] == 0) + { + m_PolicingBehavior.Disable(); + return; + } +#endif + CBaseEntity *pGoal = gEntList.FindEntityByName( NULL, inputdata.value.String() ); if ( pGoal == NULL ) @@ -2470,27 +2861,60 @@ void CNPC_MetroPolice::InputSetPoliceGoal( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CNPC_MetroPolice::InputActivateBaton( inputdata_t &inputdata ) { SetBatonState( inputdata.value.Bool() ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_MetroPolice::InputAdministerJustice( inputdata_t &inputdata ) +{ + AdministerJustice(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_MetroPolice::InputAddWarnings( inputdata_t &inputdata ) +{ + m_nNumWarnings += inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CNPC_MetroPolice::InputSetWarnings( inputdata_t &inputdata ) +{ + m_nNumWarnings = inputdata.value.Int(); +} +#endif + //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // //----------------------------------------------------------------------------- void CNPC_MetroPolice::AlertSound( void ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_GO_ALERT ); +#else m_Sentences.Speak( "METROPOLICE_GO_ALERT" ); +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // //----------------------------------------------------------------------------- void CNPC_MetroPolice::DeathSound( const CTakeDamageInfo &info ) @@ -2498,7 +2922,13 @@ void CNPC_MetroPolice::DeathSound( const CTakeDamageInfo &info ) if ( IsOnFire() ) return; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + SpeakIfAllowed( TLK_COP_DIE, set, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#else m_Sentences.Speak( "METROPOLICE_DIE", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif } @@ -2517,10 +2947,16 @@ void CNPC_MetroPolice::LostEnemySound( void) if ( gpGlobals->curtime <= m_flNextLostSoundTime ) return; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + if (SpeakIfAllowed(TLK_COP_LOSTENEMY)) + { + m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0); + } +#else const char *pSentence; if (!(CBaseEntity*)GetEnemy() || gpGlobals->curtime - GetEnemyLastTimeSeen() > 10) { - pSentence = "METROPOLICE_LOST_LONG"; + pSentence = "METROPOLICE_LOST_LONG"; } else { @@ -2531,6 +2967,7 @@ void CNPC_MetroPolice::LostEnemySound( void) { m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0); } +#endif } @@ -2546,7 +2983,11 @@ void CNPC_MetroPolice::FoundEnemySound( void) if ( HasSpawnFlags( SF_METROPOLICE_ARREST_ENEMY ) ) return; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_REFINDENEMY, SENTENCE_PRIORITY_HIGH ); +#else m_Sentences.Speak( "METROPOLICE_REFIND_ENEMY", SENTENCE_PRIORITY_HIGH ); +#endif } @@ -2567,10 +3008,63 @@ bool CNPC_MetroPolice::ShouldPlayIdleSound( void ) //----------------------------------------------------------------------------- -// IdleSound +// IdleSound //----------------------------------------------------------------------------- void CNPC_MetroPolice::IdleSound( void ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + // This happens when the NPC is waiting for his buddies to respond to him + switch( m_nIdleChatterType ) + { + case METROPOLICE_CHATTER_WAIT_FOR_RESPONSE: + break; + + case METROPOLICE_CHATTER_ASK_QUESTION: + { + if ( m_bPlayerIsNear && !HasMemory(bits_MEMORY_PLAYER_HARASSED) ) + { + if ( SpeakIfAllowed( TLK_COP_HARASS, SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL ) ) + { + Remember( bits_MEMORY_PLAYER_HARASSED ); + if ( GetSquad() ) + { + GetSquad()->SquadRemember(bits_MEMORY_PLAYER_HARASSED); + } + } + return; + } + + if ( !random->RandomInt(0,1) ) + break; + + int nQuestionType = random->RandomInt( 0, METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT ); + if ( !IsInSquad() || ( nQuestionType == METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT ) ) + { + SpeakIfAllowed(TLK_COP_IDLE); + break; + } + + if ( SpeakIfAllowed( TLK_COP_QUESTION, UTIL_VarArgs("combinequestion:%d", nQuestionType) ) ) + { + GetSquad()->BroadcastInteraction( g_interactionMetrocopIdleChatter, (void*)(METROPOLICE_CHATTER_RESPONSE + nQuestionType), this ); + m_nIdleChatterType = METROPOLICE_CHATTER_WAIT_FOR_RESPONSE; + } + } + break; + + default: + { + int nResponseType = m_nIdleChatterType - METROPOLICE_CHATTER_RESPONSE; + + if ( SpeakIfAllowed( TLK_COP_ANSWER, UTIL_VarArgs("combinequestion:%d", nResponseType) ) ) + { + GetSquad()->BroadcastInteraction( g_interactionMetrocopIdleChatter, (void*)(METROPOLICE_CHATTER_ASK_QUESTION), this ); + m_nIdleChatterType = METROPOLICE_CHATTER_ASK_QUESTION; + } + } + break; + } +#else bool bIsCriminal = PlayerIsCriminal(); // This happens when the NPC is waiting for his buddies to respond to him @@ -2604,7 +3098,7 @@ void CNPC_MetroPolice::IdleSound( void ) break; } - static const char *pQuestion[2][METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT] = + static const char *pQuestion[2][METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT] = { { "METROPOLICE_IDLE_CHECK", "METROPOLICE_IDLE_QUEST" }, { "METROPOLICE_IDLE_CHECK_CR", "METROPOLICE_IDLE_QUEST_CR" }, @@ -2622,7 +3116,7 @@ void CNPC_MetroPolice::IdleSound( void ) { int nResponseType = m_nIdleChatterType - METROPOLICE_CHATTER_RESPONSE; - static const char *pResponse[2][METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT] = + static const char *pResponse[2][METROPOLICE_CHATTER_RESPONSE_TYPE_COUNT] = { { "METROPOLICE_IDLE_CLEAR", "METROPOLICE_IDLE_ANSWER" }, { "METROPOLICE_IDLE_CLEAR_CR", "METROPOLICE_IDLE_ANSWER_CR" }, @@ -2636,11 +3130,12 @@ void CNPC_MetroPolice::IdleSound( void ) } break; } +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::PainSound( const CTakeDamageInfo &info ) { @@ -2651,6 +3146,12 @@ void CNPC_MetroPolice::PainSound( const CTakeDamageInfo &info ) if ( IsOnFire() ) return; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + AI_CriteriaSet set; + ModifyOrAppendDamageCriteria(set, info); + SpeakIfAllowed(TLK_COP_PAIN, set, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS); + m_flNextPainSoundTime = gpGlobals->curtime + 1; +#else float healthRatio = (float)GetHealth() / (float)GetMaxHealth(); if ( healthRatio > 0.0f ) { @@ -2665,24 +3166,25 @@ void CNPC_MetroPolice::PainSound( const CTakeDamageInfo &info ) Remember( bits_MEMORY_PAIN_LIGHT_SOUND ); pSentenceName = "METROPOLICE_PAIN_LIGHT"; } - + // This causes it to speak it no matter what; doesn't bother with setting sounds. m_Sentences.Speak( pSentenceName, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); m_flNextPainSoundTime = gpGlobals->curtime + 1; } +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CNPC_MetroPolice::GetSoundInterests( void ) { - return SOUND_WORLD | SOUND_COMBAT | SOUND_PLAYER | SOUND_PLAYER_VEHICLE | SOUND_DANGER | + return SOUND_WORLD | SOUND_COMBAT | SOUND_PLAYER | SOUND_PLAYER_VEHICLE | SOUND_DANGER | SOUND_PHYSICS_DANGER | SOUND_BULLET_IMPACT | SOUND_MOVE_AWAY; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- float CNPC_MetroPolice::MaxYawSpeed( void ) { @@ -2708,7 +3210,7 @@ float CNPC_MetroPolice::MaxYawSpeed( void ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -2718,7 +3220,7 @@ Class_T CNPC_MetroPolice::Classify ( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::PlayerIsCriminal( void ) @@ -2760,16 +3262,16 @@ Disposition_t CNPC_MetroPolice::IRelationType(CBaseEntity *pTarget) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pEvent - +// Purpose: +// Input : *pEvent - //----------------------------------------------------------------------------- void CNPC_MetroPolice::OnAnimEventStartDeployManhack( void ) { Assert( m_iManhacks ); - + if ( m_iManhacks <= 0 ) { - DevMsg( "Error: Throwing manhack but out of manhacks!\n" ); + CGMsg( 1, CON_GROUP_NPC_AI, "Error: Throwing manhack but out of manhacks!\n" ); return; } @@ -2783,7 +3285,7 @@ void CNPC_MetroPolice::OnAnimEventStartDeployManhack( void ) // Create the manhack to throw CNPC_Manhack *pManhack = (CNPC_Manhack *)CreateEntityByName( "npc_manhack" ); - + Vector vecOrigin; QAngle vecAngles; @@ -2793,7 +3295,7 @@ void CNPC_MetroPolice::OnAnimEventStartDeployManhack( void ) pManhack->SetLocalOrigin( vecOrigin ); pManhack->SetLocalAngles( vecAngles ); pManhack->AddSpawnFlags( (SF_MANHACK_PACKED_UP|SF_MANHACK_CARRIED|SF_NPC_WAIT_FOR_SCRIPT) ); - + // Also fade if our parent is marked to do it if ( HasSpawnFlags( SF_NPC_FADE_CORPSE ) ) { @@ -2806,6 +3308,10 @@ void CNPC_MetroPolice::OnAnimEventStartDeployManhack( void ) pManhack->SetParent( this, handAttachment ); m_hManhack = pManhack; + +#ifdef MAPBASE + m_OutManhack.Set(m_hManhack, pManhack, this); +#endif } //----------------------------------------------------------------------------- @@ -2837,7 +3343,7 @@ void CNPC_MetroPolice::OnAnimEventDeployManhack( animevent_t *pEvent ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::OnAnimEventShove( void ) { @@ -2879,11 +3385,11 @@ void CNPC_MetroPolice::OnAnimEventShove( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::OnAnimEventBatonOn( void ) { -#ifndef HL2MP +#if !defined(HL2MP) || defined(MAPBASE) CWeaponStunStick *pStick = dynamic_cast(GetActiveWeapon()); @@ -2896,14 +3402,14 @@ void CNPC_MetroPolice::OnAnimEventBatonOn( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::OnAnimEventBatonOff( void ) { -#ifndef HL2MP +#if !defined(HL2MP) || defined(MAPBASE) CWeaponStunStick *pStick = dynamic_cast(GetActiveWeapon()); - + if ( pStick ) { pStick->SetStunState( false ); @@ -2912,9 +3418,9 @@ void CNPC_MetroPolice::OnAnimEventBatonOff( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // -// Input : *pEvent - +// Input : *pEvent - // //----------------------------------------------------------------------------- void CNPC_MetroPolice::HandleAnimEvent( animevent_t *pEvent ) @@ -2989,7 +3495,9 @@ bool CNPC_MetroPolice::HandleInteraction(int interactionType, void *data, CBaseC if ( interactionType == g_interactionMetrocopClearSentenceQueues ) { +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM m_Sentences.ClearQueue(); +#endif return true; } @@ -3010,8 +3518,15 @@ bool CNPC_MetroPolice::HandleInteraction(int interactionType, void *data, CBaseC CBaseProp *pProp = (CBaseProp*)data; if( pProp != NULL ) { +#ifdef MAPBASE + if( pProp->NameMatches("cupcop_can") ) + m_OnCupCopped.FireOutput( sourceEnt, this ); + + m_OnHitByPhysicsObject.Set(pProp, sourceEnt, this); +#else if( pProp->NameMatches("cupcop_can") ) m_OnCupCopped.FireOutput( this, NULL ); +#endif } return true; @@ -3033,22 +3548,88 @@ Activity CNPC_MetroPolice::NPC_TranslateActivity( Activity newActivity ) // If we're shoving, see if we should be more forceful in doing so if ( newActivity == ACT_PUSH_PLAYER ) { +#ifdef MAPBASE + if ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS && Weapon_TranslateActivity( ACT_MELEE_ATTACK1, NULL ) == ACT_MELEE_ATTACK_SWING ) +#else if ( m_nNumWarnings >= METROPOLICE_MAX_WARNINGS ) +#endif return ACT_MELEE_ATTACK1; } newActivity = BaseClass::NPC_TranslateActivity( newActivity ); // This will put him into an angry idle, which will then be translated - // by the weapon to the appropriate type. + // by the weapon to the appropriate type. if ( m_fWeaponDrawn && newActivity == ACT_IDLE && ( GetState() == NPC_STATE_COMBAT || BatonActive() ) ) { newActivity = ACT_IDLE_ANGRY; } +#ifdef MAPBASE + if (newActivity == ACT_RANGE_ATTACK2) + { + return ACT_COMBINE_THROW_GRENADE; + } +#endif + return newActivity; } +#ifdef MAPBASE +Activity CNPC_MetroPolice::Weapon_TranslateActivity( Activity baseAct, bool *pRequired ) +{ + Activity translated = BaseClass::Weapon_TranslateActivity(baseAct, pRequired); + + if (!m_fWeaponDrawn) + { + // If our pistol is holstered, don't act like we have one in our hands. + switch (translated) + { + case ACT_WALK_PISTOL: return ACT_WALK; + case ACT_RUN_PISTOL: return ACT_RUN; + case ACT_IDLE_PISTOL: return ACT_IDLE; + } + } + + return translated; +} + +int CNPC_MetroPolice::UnholsterWeapon() +{ +#if 0 + if (!m_fWeaponDrawn && (!IsCurSchedule(SCHED_METROPOLICE_DRAW_PISTOL))) + SetSchedule(SCHED_METROPOLICE_DRAW_PISTOL); + + return -1; +#else + // Remain compatible with the original behavior + if (IsCurSchedule(SCHED_METROPOLICE_DRAW_PISTOL)) + return -1; + else if (!m_fWeaponDrawn) + { + SetSchedule(SCHED_METROPOLICE_DRAW_PISTOL); + return -1; + } + + return BaseClass::UnholsterWeapon(); +#endif +} + +void CNPC_MetroPolice::OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior ) +{ + BaseClass::OnChangeRunningBehavior( pOldBehavior, pNewBehavior ); + + // Fix the npc_metropolice using an invisible gun + if (!m_fWeaponDrawn) + { + // We can't just stop and draw, so fall back to gesture unholstering. + // Our implementation of UnholsterWeapon() just handles stopping and drawing, which we can skip in this case. + m_fWeaponDrawn = true; + BaseClass::UnholsterWeapon(); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Makes the held manhack solid //----------------------------------------------------------------------------- @@ -3068,7 +3649,13 @@ void CNPC_MetroPolice::ReleaseManhack( void ) // Make us active m_hManhack->RemoveSpawnFlags( SF_NPC_WAIT_FOR_SCRIPT ); m_hManhack->ClearSchedule( "Manhack released by metropolice" ); - + +#ifdef MAPBASE + // FSOLID_COLLIDE_WITH_OWNER allows us to be remembered as the manhack's owner without making us invulnerable to it + m_hManhack->SetOwnerEntity( this ); + m_hManhack->AddSolidFlags( FSOLID_COLLIDE_WITH_OWNER ); +#endif + // Start him with knowledge of our current enemy if ( GetEnemy() ) { @@ -3086,7 +3673,7 @@ void CNPC_MetroPolice::ReleaseManhack( void ) } //----------------------------------------------------------------------------- -// +// //----------------------------------------------------------------------------- void CNPC_MetroPolice::Event_Killed( const CTakeDamageInfo &info ) { @@ -3109,13 +3696,18 @@ void CNPC_MetroPolice::Event_Killed( const CTakeDamageInfo &info ) DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedHealth(); } + +#ifdef MAPBASE + // Drop grenades if we should + DropGrenadeItemsOnDeath( info, pPlayer ); +#endif } BaseClass::Event_Killed( info ); } //----------------------------------------------------------------------------- -// Try to enter a slot where we shoot a pistol +// Try to enter a slot where we shoot a pistol //----------------------------------------------------------------------------- bool CNPC_MetroPolice::TryToEnterPistolSlot( int nSquadSlot ) { @@ -3137,7 +3729,7 @@ bool CNPC_MetroPolice::TryToEnterPistolSlot( int nSquadSlot ) //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectRangeAttackSchedule() { @@ -3151,7 +3743,7 @@ int CNPC_MetroPolice::SelectRangeAttackSchedule() // Range attack if we're able if( TryToEnterPistolSlot( SQUAD_SLOT_ATTACK1 ) || TryToEnterPistolSlot( SQUAD_SLOT_ATTACK2 )) return SCHED_RANGE_ATTACK1; - + // We're not in a shoot slot... so we've allowed someone else to grab it m_LastShootSlot = SQUAD_SLOT_NONE; @@ -3160,6 +3752,17 @@ int CNPC_MetroPolice::SelectRangeAttackSchedule() return SCHED_METROPOLICE_DEPLOY_MANHACK; } +#ifdef MAPBASE + // Throw a grenade if not allowed to engage with weapon. + if ( CanGrenadeEnemy() ) + { + if ( OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_METROPOLICE_RANGE_ATTACK2; + } + } +#endif + return SCHED_METROPOLICE_ADVANCE; } @@ -3189,7 +3792,7 @@ int CNPC_MetroPolice::SquadArrestCount() //----------------------------------------------------------------------------- -// Arrest schedule selection +// Arrest schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectScheduleArrestEnemy() { @@ -3212,7 +3815,7 @@ int CNPC_MetroPolice::SelectScheduleArrestEnemy() //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectScheduleNewEnemy() { @@ -3245,7 +3848,7 @@ int CNPC_MetroPolice::SelectScheduleNewEnemy() //----------------------------------------------------------------------------- -// Sound investigation +// Sound investigation //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectScheduleInvestigateSound() { @@ -3267,7 +3870,7 @@ int CNPC_MetroPolice::SelectScheduleInvestigateSound() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CNPC_MetroPolice::OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) { @@ -3289,7 +3892,7 @@ bool CNPC_MetroPolice::OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, floa } //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectScheduleNoDirectEnemy() { @@ -3305,12 +3908,21 @@ int CNPC_MetroPolice::SelectScheduleNoDirectEnemy() return SCHED_METROPOLICE_SMASH_PROP; } +#ifdef MAPBASE + // If you see your enemy and you're still arming yourself, wait and don't just charge in + // (if your weapon is holstered, you're probably about to arm yourself) + if ( HasCondition( COND_SEE_ENEMY ) && GetWeapon(0) && (IsWeaponHolstered() || FindGestureLayer( TranslateActivity( ACT_ARM ) ) != -1) ) + { + return SCHED_COMBAT_FACE; + } +#endif + return SCHED_METROPOLICE_CHASE_ENEMY; } //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectCombatSchedule() { @@ -3333,7 +3945,11 @@ int CNPC_MetroPolice::SelectCombatSchedule() { m_nRecentDamage = 0; m_flRecentDamageTime = 0; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_COVER_HEAVY_DAMAGE, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL); +#else m_Sentences.Speak( "METROPOLICE_COVER_HEAVY_DAMAGE", SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); +#endif return SCHED_TAKE_COVER_FROM_ENEMY; } @@ -3363,7 +3979,7 @@ int CNPC_MetroPolice::SelectCombatSchedule() { return SCHED_BACK_AWAY_FROM_ENEMY; } - + if ( HasCondition( COND_LOW_PRIMARY_AMMO ) || HasCondition( COND_NO_PRIMARY_AMMO ) ) { AnnounceOutOfAmmo( ); @@ -3376,7 +3992,11 @@ int CNPC_MetroPolice::SelectCombatSchedule() CBaseEntity *pBlocker = GetEnemyOccluder(); if ( pBlocker && pBlocker->GetHealth() > 0 && OccupyStrategySlotRange( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER1, SQUAD_SLOT_POLICE_ATTACK_OCCLUDER2 ) ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_SHOOTCOVER); +#else m_Sentences.Speak( "METROPOLICE_SHOOT_COVER" ); +#endif return SCHED_SHOOT_ENEMY_COVER; } } @@ -3385,6 +4005,27 @@ int CNPC_MetroPolice::SelectCombatSchedule() { if ( GetEnemy() && !(GetEnemy()->GetFlags() & FL_NOTARGET) ) { +#ifdef MAPBASE + if ( HasGrenades() ) + { + // We don't see our enemy. If it hasn't been long since I last saw him, + // and he's pretty close to the last place I saw him, throw a grenade in + // to flush him out. A wee bit of cheating here... + + float flTime; + float flDist; + + flTime = gpGlobals->curtime - GetEnemies()->LastTimeSeen( GetEnemy() ); + flDist = ( GetEnemy()->GetAbsOrigin() - GetEnemies()->LastSeenPosition( GetEnemy() ) ).Length(); + + //Msg("Time: %f Dist: %f\n", flTime, flDist ); + if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_METROPOLICE_RANGE_ATTACK2; + } + } +#endif + // Charge in and break the enemy's cover! return SCHED_ESTABLISH_LINE_OF_FIRE; } @@ -3421,7 +4062,7 @@ void CNPC_MetroPolice::KnockOutTarget( CBaseEntity *pTarget ) } //----------------------------------------------------------------------------- -// Can me enemy see me? +// Can me enemy see me? //----------------------------------------------------------------------------- bool CNPC_MetroPolice::CanEnemySeeMe( ) { @@ -3437,7 +4078,7 @@ bool CNPC_MetroPolice::CanEnemySeeMe( ) //----------------------------------------------------------------------------- -// Choose weights about where we can use particular stitching behaviors +// Choose weights about where we can use particular stitching behaviors //----------------------------------------------------------------------------- #define STITCH_MIN_DISTANCE 1000.0f #define STITCH_MIN_DISTANCE_SLOW 1250.0f @@ -3479,7 +4120,7 @@ float CNPC_MetroPolice::StitchAtWeight( float flDist, float flSpeed, float flDot if ( DotProduct2D( vecGunToTarget, vecGunToPredictedTarget.AsVector2D() ) <= STITCH_AT_COS_MIN_SPIN_ANGLE ) return 0.0f; - // If the cop is in the view cone, then up the cone in which the stitch will occur + // If the cop is in the view cone, then up the cone in which the stitch will occur float flConeAngle = STITCH_AT_CONE; if ( CanEnemySeeMe() ) { @@ -3618,7 +4259,7 @@ float CNPC_MetroPolice::StitchTightWeight( float flDist, float flSpeed, const Ve //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- #define STITCH_REACTION_TIME 2.0f #define STITCH_SCHEDULE_COUNT 5 @@ -3699,7 +4340,7 @@ int CNPC_MetroPolice::SelectStitchSchedule() //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectMoveToLedgeSchedule() { @@ -3730,13 +4371,13 @@ int CNPC_MetroPolice::SelectMoveToLedgeSchedule() if (tr.endpos.z >= GetAbsOrigin().z - 25.0f ) return SCHED_METROPOLICE_ESTABLISH_STITCH_LINE_OF_FIRE; } - + return SCHED_NONE; } //----------------------------------------------------------------------------- -// Combat schedule selection +// Combat schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectAirboatRangeAttackSchedule() { @@ -3780,7 +4421,7 @@ int CNPC_MetroPolice::SelectAirboatCombatSchedule() { return SelectAirboatRangeAttackSchedule(); } - + if ( HasCondition( COND_WEAPON_SIGHT_OCCLUDED ) ) { // If they are hiding behind something also attack. Don't bother @@ -3800,9 +4441,124 @@ int CNPC_MetroPolice::SelectAirboatCombatSchedule() } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Standoff schedule selection +//----------------------------------------------------------------------------- +int CNPC_MetroPolice::SelectBehaviorOverrideSchedule() +{ + // Announce a new enemy + if ( HasCondition( COND_NEW_ENEMY ) ) + { + AnnounceEnemyType( GetEnemy() ); + } + + int nResult = SelectScheduleNewEnemy(); + if ( nResult != SCHED_NONE ) + return nResult; + + if (!HasBaton() && ((float)m_nRecentDamage / (float)GetMaxHealth()) > RECENT_DAMAGE_THRESHOLD) + { + m_nRecentDamage = 0; + m_flRecentDamageTime = 0; +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_COVER_HEAVY_DAMAGE, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL); +#else + m_Sentences.Speak( "METROPOLICE_COVER_HEAVY_DAMAGE", SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); +#endif + + return SCHED_TAKE_COVER_FROM_ENEMY; + } + + if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) + { + nResult = SelectRangeAttackSchedule(); + if ( !GetShotRegulator()->IsInRestInterval() && nResult != SCHED_METROPOLICE_ADVANCE && nResult != SCHED_RANGE_ATTACK1 ) + return nResult; + } + + if ( HasCondition( COND_TOO_CLOSE_TO_ATTACK ) ) + { + return SCHED_BACK_AWAY_FROM_ENEMY; + } + + if ( HasCondition( COND_LOW_PRIMARY_AMMO ) || HasCondition( COND_NO_PRIMARY_AMMO ) ) + { + AnnounceOutOfAmmo( ); + return SCHED_HIDE_AND_RELOAD; + } + + if ( HasCondition(COND_WEAPON_SIGHT_OCCLUDED) && !HasBaton() ) + { + // If they are hiding behind something that we can destroy, start shooting at it. + CBaseEntity *pBlocker = GetEnemyOccluder(); + if ( pBlocker && pBlocker->GetHealth() > 0 && OccupyStrategySlotRange( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER1, SQUAD_SLOT_POLICE_ATTACK_OCCLUDER2 ) ) + { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_SHOOTCOVER); +#else + m_Sentences.Speak( "METROPOLICE_SHOOT_COVER" ); +#endif + return SCHED_SHOOT_ENEMY_COVER; + } + } + + if (HasCondition(COND_ENEMY_OCCLUDED)) + { + if ( GetEnemy() && !(GetEnemy()->GetFlags() & FL_NOTARGET) ) + { + if ( HasGrenades() ) + { + // We don't see our enemy. If it hasn't been long since I last saw him, + // and he's pretty close to the last place I saw him, throw a grenade in + // to flush him out. A wee bit of cheating here... + + float flTime; + float flDist; + + flTime = gpGlobals->curtime - GetEnemies()->LastTimeSeen( GetEnemy() ); + flDist = ( GetEnemy()->GetAbsOrigin() - GetEnemies()->LastSeenPosition( GetEnemy() ) ).Length(); + + //Msg("Time: %f Dist: %f\n", flTime, flDist ); + if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_METROPOLICE_RANGE_ATTACK2; + } + } + } + } + + // If you can't attack, but you can deploy a manhack, do it! + if( CanDeployManhack() && OccupyStrategySlot( SQUAD_SLOT_POLICE_DEPLOY_MANHACK ) ) + return SCHED_METROPOLICE_DEPLOY_MANHACK; + + return SCHED_NONE; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CNPC_MetroPolice::IsCrouchedActivity( Activity activity ) +{ + return BaseClass::IsCrouchedActivity( activity ); +} + +//----------------------------------------------------------------------------- +// Standoff schedule selection +//----------------------------------------------------------------------------- +int CNPC_MetroPolice::CMetroPoliceStandoffBehavior::SelectScheduleAttack() +{ + int result = metropolice_new_component_behavior.GetBool() ? GetOuter()->SelectBehaviorOverrideSchedule() : SCHED_NONE; + if (result == SCHED_NONE) + result = BaseClass::SelectScheduleAttack(); + return result; +} +#endif + + //----------------------------------------------------------------------------- -// Purpose: -// Input : &info - +// Purpose: +// Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::IsHeavyDamage( const CTakeDamageInfo &info ) @@ -3869,7 +4625,7 @@ Activity CNPC_MetroPolice::GetFlinchActivity( bool bHeavyDamage, bool bGesture ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::PlayFlinchGesture( void ) { @@ -3884,7 +4640,10 @@ void CNPC_MetroPolice::PlayFlinchGesture( void ) //----------------------------------------------------------------------------- void CNPC_MetroPolice::AnnounceHarrassment( void ) { - static const char *pWarnings[3] = +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_BACK_UP, SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL); +#else + static const char *pWarnings[3] = { "METROPOLICE_BACK_UP_A", "METROPOLICE_BACK_UP_B", @@ -3892,10 +4651,11 @@ void CNPC_MetroPolice::AnnounceHarrassment( void ) }; m_Sentences.Speak( pWarnings[ random->RandomInt( 0, ARRAYSIZE(pWarnings)-1 ) ], SENTENCE_PRIORITY_MEDIUM, SENTENCE_CRITERIA_NORMAL ); +#endif } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::IncrementPlayerCriminalStatus( void ) { @@ -3925,7 +4685,7 @@ void CNPC_MetroPolice::IncrementPlayerCriminalStatus( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : int //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectShoveSchedule( void ) @@ -3938,7 +4698,7 @@ int CNPC_MetroPolice::SelectShoveSchedule( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : float //----------------------------------------------------------------------------- float CNPC_MetroPolice::GetIdealAccel( void ) const @@ -3989,7 +4749,7 @@ void CNPC_MetroPolice::AdministerJustice( void ) if ( pNPC->HasSpawnFlags( SF_METROPOLICE_ALLOWED_TO_RESPOND ) ) { // Is he within site & range? - if ( FVisible(pNPC) && pNPC->FVisible( UTIL_PlayerByIndex(1) ) && + if ( FVisible(pNPC) && pNPC->FVisible( UTIL_PlayerByIndex(1) ) && UTIL_DistApprox( WorldSpaceCenter(), pNPC->WorldSpaceCenter() ) < 512 ) { pNPC->AdministerJustice(); @@ -4002,7 +4762,7 @@ void CNPC_MetroPolice::AdministerJustice( void ) } //----------------------------------------------------------------------------- -// Schedule selection +// Schedule selection //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectSchedule( void ) { @@ -4013,7 +4773,11 @@ int CNPC_MetroPolice::SelectSchedule( void ) if ( HasCondition(COND_METROPOLICE_ON_FIRE) ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_ON_FIRE, "hurt_by_fire:1", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS); +#else m_Sentences.Speak( "METROPOLICE_ON_FIRE", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif return SCHED_METROPOLICE_BURNING_STAND; } @@ -4025,16 +4789,65 @@ int CNPC_MetroPolice::SelectSchedule( void ) // See which state our player relationship is in if ( PlayerIsCriminal() == false ) { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_HIT_BY_PHYSOBJ, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#else m_Sentences.Speak( "METROPOLICE_HIT_BY_PHYSOBJECT", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif m_nNumWarnings = METROPOLICE_MAX_WARNINGS; AdministerJustice(); } else if ( GlobalEntity_GetState( "gordon_precriminal" ) == GLOBAL_ON ) { // We're not allowed to respond, but warn them +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_HARASS, SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#else m_Sentences.Speak( "METROPOLICE_IDLE_HARASS_PLAYER", SENTENCE_PRIORITY_INVALID, SENTENCE_CRITERIA_ALWAYS ); +#endif + } + } + +#ifdef MAPBASE + if ( m_hForcedGrenadeTarget ) + { + if ( m_flNextGrenadeCheck < gpGlobals->curtime ) + { + Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); + + // The fact we have a forced grenade target overrides whether we're marked as "capable". + // If we're *only* alt-fire capable, use an energy ball. If not, throw a grenade. + if (!IsAltFireCapable() || IsGrenadeCapable()) + { + Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); + { + // If we can, throw a grenade at the target. + // Ignore grenade count / distance / etc + if ( CheckCanThrowGrenade( vecTarget ) ) + { + m_hForcedGrenadeTarget = NULL; + return SCHED_METROPOLICE_FORCED_GRENADE_THROW; + } + } + } + else + { + if ( FVisible( m_hForcedGrenadeTarget ) ) + { + m_vecAltFireTarget = vecTarget; + m_hForcedGrenadeTarget = NULL; + return SCHED_METROPOLICE_AR2_ALTFIRE; + } + } + } + + // Can't throw at the target, so lets try moving to somewhere where I can see it + if ( !FVisible( m_hForcedGrenadeTarget ) ) + { + return SCHED_METROPOLICE_MOVE_TO_FORCED_GREN_LOS; } } +#endif int nSched = SelectFlinchSchedule(); if ( nSched != SCHED_NONE ) @@ -4071,15 +4884,15 @@ int CNPC_MetroPolice::SelectSchedule( void ) { ClearCondition( COND_METROPOLICE_PLAYER_TOO_CLOSE ); m_bPlayerTooClose = false; - + return SelectShoveSchedule(); } } else if ( m_iNumPlayerHits ) { // If we're not in combat, and we've got a pre-chase origin, move back to it - if ( ( m_NPCState != NPC_STATE_COMBAT ) && - ( m_vecPreChaseOrigin != vec3_origin ) && + if ( ( m_NPCState != NPC_STATE_COMBAT ) && + ( m_vecPreChaseOrigin != vec3_origin ) && ( m_flChasePlayerTime < gpGlobals->curtime ) ) { return SCHED_METROPOLICE_RETURN_TO_PRECHASE; @@ -4123,9 +4936,18 @@ int CNPC_MetroPolice::SelectSchedule( void ) // This will cause the cops to run backwards + shoot at the same time if ( !bHighHealth && !HasBaton() ) { +#ifdef MAPBASE + // Don't do this with low-capacity weapons or weapons which don't use clips + if ( GetActiveWeapon() && GetActiveWeapon()->UsesClipsForAmmo1() && GetActiveWeapon()->GetMaxClip1() > 10 && (GetActiveWeapon()->m_iClip1 <= 5) ) +#else if ( GetActiveWeapon() && (GetActiveWeapon()->m_iClip1 <= 5) ) +#endif { +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_LOWAMMO ); +#else m_Sentences.Speak( "METROPOLICE_COVER_LOW_AMMO" ); +#endif return SCHED_HIDE_AND_RELOAD; } } @@ -4168,7 +4990,11 @@ int CNPC_MetroPolice::SelectSchedule( void ) break; case NPC_STATE_COMBAT: +#ifdef MAPBASE + if (!IsEnemyInAnAirboat() || !GetActiveWeapon() || !EntIsClass(GetActiveWeapon(), gm_isz_class_SMG1)) +#else if (!IsEnemyInAnAirboat() || !Weapon_OwnsThisType( "weapon_smg1" ) ) +#endif { int nResult = SelectCombatSchedule(); if ( nResult != SCHED_NONE ) @@ -4185,8 +5011,8 @@ int CNPC_MetroPolice::SelectSchedule( void ) } // If we're not in combat, and we've got a pre-chase origin, move back to it - if ( ( m_NPCState != NPC_STATE_COMBAT ) && - ( m_vecPreChaseOrigin != vec3_origin ) && + if ( ( m_NPCState != NPC_STATE_COMBAT ) && + ( m_vecPreChaseOrigin != vec3_origin ) && ( m_flChasePlayerTime < gpGlobals->curtime ) ) { return SCHED_METROPOLICE_RETURN_TO_PRECHASE; @@ -4197,10 +5023,10 @@ int CNPC_MetroPolice::SelectSchedule( void ) //----------------------------------------------------------------------------- -// Purpose: -// Input : failedSchedule - -// failedTask - -// taskFailCode - +// Purpose: +// Input : failedSchedule - +// failedTask - +// taskFailCode - // Output : int //----------------------------------------------------------------------------- int CNPC_MetroPolice::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode ) @@ -4228,12 +5054,12 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) return SCHED_ALERT_FACE_BESTSOUND; case SCHED_CHASE_ENEMY: - + if ( !IsRunningBehavior() ) { return SCHED_METROPOLICE_CHASE_ENEMY; } - + break; case SCHED_ESTABLISH_LINE_OF_FIRE: @@ -4244,13 +5070,21 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) if ( nSched != SCHED_NONE ) return nSched; } - return SCHED_METROPOLICE_ESTABLISH_LINE_OF_FIRE; - +#ifdef MAPBASE + if ( CanAltFireEnemy(false) && OccupyStrategySlot(SQUAD_SLOT_SPECIAL_ATTACK) ) + { + // If this metrocop has the balls to alt-fire the enemy's last known position, + // do so! + return SCHED_METROPOLICE_AR2_ALTFIRE; + } +#endif + return SCHED_METROPOLICE_ESTABLISH_LINE_OF_FIRE; + case SCHED_WAKE_ANGRY: return SCHED_METROPOLICE_WAKE_ANGRY; case SCHED_FAIL_TAKE_COVER: - + if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { // Must be able to shoot now @@ -4270,7 +5104,21 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) return SCHED_METROPOLICE_DRAW_PISTOL; } +#ifdef MAPBASE + if (CanAltFireEnemy( true ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK )) + { + // Since I'm holding this squadslot, no one else can try right now. If I die before the shot + // goes off, I won't have affected anyone else's ability to use this attack at their nearest + // convenience. + return SCHED_METROPOLICE_AR2_ALTFIRE; + } +#endif + +#ifdef MAPBASE + if (GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_SMG1)) +#else if( Weapon_OwnsThisType( "weapon_smg1" ) ) +#endif { if ( IsEnemyInAnAirboat() ) { @@ -4289,10 +5137,44 @@ int CNPC_MetroPolice::TranslateSchedule( int scheduleType ) } } break; +#ifdef MAPBASE + case SCHED_TAKE_COVER_FROM_ENEMY: + { + if ( m_pSquad ) + { + // Have to explicitly check innate range attack condition as may have weapon with range attack 2 + if ( g_pGameRules->IsSkillLevel( SKILL_HARD ) && + HasCondition(COND_CAN_RANGE_ATTACK2) && + OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + #ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed( TLK_COP_THROWGRENADE ); + #else + m_Sentences.Speak( "COMBINE_THROW_GRENADE" ); + #endif + return SCHED_METROPOLICE_RANGE_ATTACK2; + } + } + } + break; + case SCHED_HIDE_AND_RELOAD: + { + if( CanGrenadeEnemy() && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) && random->RandomInt( 0, 100 ) < 20 ) + { + // If I COULD throw a grenade and I need to reload, 20% chance I'll throw a grenade before I hide to reload. + return SCHED_METROPOLICE_RANGE_ATTACK2; + } + } + break; +#endif case SCHED_METROPOLICE_ADVANCE: if ( m_NextChargeTimer.Expired() && metropolice_charge.GetBool() ) - { + { +#ifdef MAPBASE + if (GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_Pistol)) +#else if ( Weapon_OwnsThisType( "weapon_pistol" ) ) +#endif { if ( GetEnemy() && GetEnemy()->GetAbsOrigin().DistToSqr( GetAbsOrigin() ) > 300*300 ) { @@ -4358,8 +5240,8 @@ void CNPC_MetroPolice::OnEndMoveAndShoot() //----------------------------------------------------------------------------- -// Purpose: -// Input : pTask - +// Purpose: +// Input : pTask - //----------------------------------------------------------------------------- void CNPC_MetroPolice::StartTask( const Task_t *pTask ) { @@ -4417,7 +5299,11 @@ void CNPC_MetroPolice::StartTask( const Task_t *pTask ) break; } +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_ACTIVATE_BATON, SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL); +#else m_Sentences.Speak( "METROPOLICE_ACTIVATE_BATON", SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL ); +#endif SetIdealActivity( (Activity) ACT_ACTIVATE_BATON ); } else @@ -4428,7 +5314,11 @@ void CNPC_MetroPolice::StartTask( const Task_t *pTask ) break; } +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + SpeakIfAllowed(TLK_COP_DEACTIVATE_BATON, SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL); +#else m_Sentences.Speak( "METROPOLICE_DEACTIVATE_BATON", SENTENCE_PRIORITY_NORMAL, SENTENCE_CRITERIA_NORMAL ); +#endif SetIdealActivity( (Activity) ACT_DEACTIVATE_BATON ); } } @@ -4465,6 +5355,23 @@ void CNPC_MetroPolice::StartTask( const Task_t *pTask ) TaskComplete(); break; +#ifdef MAPBASE + case TASK_METROPOLICE_GET_PATH_TO_FORCED_GREN_LOS: + StartTask_GetPathToForced( pTask ); + break; + + case TASK_METROPOLICE_DEFER_SQUAD_GRENADES: + StartTask_DeferSquad( pTask ); + break; + + case TASK_METROPOLICE_FACE_TOSS_DIR: + break; + + case TASK_METROPOLICE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: + StartTask_FaceAltFireTarget( pTask ); + break; +#endif + case TASK_METROPOLICE_GET_PATH_TO_STITCH: { if ( !ShouldAttemptToStitch() ) @@ -4647,7 +5554,7 @@ void CNPC_MetroPolice::EnemyResistingArrest() { // Prevent any other arrest from being made in this squad // and tell them all that the player is resisting arrest! - + if ( m_pSquad != NULL ) { AISquadIter_t iter; @@ -4663,8 +5570,8 @@ void CNPC_MetroPolice::EnemyResistingArrest() //----------------------------------------------------------------------------- -// Purpose: -// Input : pTask - +// Purpose: +// Input : pTask - //----------------------------------------------------------------------------- #define FLEEING_DISTANCE_SQR (100 * 100) @@ -4687,11 +5594,11 @@ void CNPC_MetroPolice::RunTask( const Task_t *pTask ) case TASK_METROPOLICE_ACTIVATE_BATON: AutoMovement(); - + if ( IsActivityFinished() ) { TaskComplete(); - } + } break; case TASK_METROPOLICE_BURST_ATTACK: @@ -4769,7 +5676,7 @@ void CNPC_MetroPolice::RunTask( const Task_t *pTask ) if ( fabs(UTIL_AngleDiff( GetMotor()->GetIdealYaw(), flNewIdealYaw )) >= 45.0f ) { GetMotor()->SetIdealYawToTarget( GetEnemy()->EyePosition() ); - SetTurnActivity(); + SetTurnActivity(); } } GetMotor()->UpdateYaw(); @@ -4828,6 +5735,20 @@ void CNPC_MetroPolice::RunTask( const Task_t *pTask ) } break; +#ifdef MAPBASE + case TASK_METROPOLICE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: + RunTask_FaceAltFireTarget( pTask ); + break; + + case TASK_METROPOLICE_GET_PATH_TO_FORCED_GREN_LOS: + RunTask_GetPathToForced( pTask ); + break; + + case TASK_METROPOLICE_FACE_TOSS_DIR: + RunTask_FaceTossDir( pTask ); + break; +#endif + default: BaseClass::RunTask( pTask ); break; @@ -4835,13 +5756,13 @@ void CNPC_MetroPolice::RunTask( const Task_t *pTask ) } - + //----------------------------------------------------------------------------- -// Purpose: -// Input : pevInflictor - -// pAttacker - -// flDamage - -// bitsDamageType - +// Purpose: +// Input : pevInflictor - +// pAttacker - +// flDamage - +// bitsDamageType - // Output : int //----------------------------------------------------------------------------- int CNPC_MetroPolice::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) @@ -4869,7 +5790,7 @@ int CNPC_MetroPolice::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) m_flRecentDamageTime = gpGlobals->curtime; } - return BaseClass::OnTakeDamage_Alive( info ); + return BaseClass::OnTakeDamage_Alive( info ); } @@ -4891,7 +5812,7 @@ bool CNPC_MetroPolice::CanDeployManhack( void ) return true; } - + //----------------------------------------------------------------------------- // Purpose: Allows for modification of the interrupt mask for the current schedule. // In the most cases the base implementation should be called first. @@ -4906,10 +5827,10 @@ void CNPC_MetroPolice::BuildScheduleTestBits( void ) } //FIXME: Always interrupt for now - if ( !IsInAScript() && + if ( !IsInAScript() && !IsCurSchedule( SCHED_METROPOLICE_SHOVE ) && !IsCurSchedule( SCHED_MELEE_ATTACK1 ) && - !IsCurSchedule( SCHED_RELOAD ) && + !IsCurSchedule( SCHED_RELOAD ) && !IsCurSchedule( SCHED_METROPOLICE_ACTIVATE_BATON ) ) { SetCustomInterruptCondition( COND_METROPOLICE_PLAYER_TOO_CLOSE ); @@ -4929,7 +5850,7 @@ void CNPC_MetroPolice::BuildScheduleTestBits( void ) if ( !IsCurSchedule( SCHED_CHASE_ENEMY ) && !IsCurSchedule( SCHED_METROPOLICE_ACTIVATE_BATON ) && !IsCurSchedule( SCHED_METROPOLICE_DEACTIVATE_BATON ) && - !IsCurSchedule( SCHED_METROPOLICE_SHOVE ) && + !IsCurSchedule( SCHED_METROPOLICE_SHOVE ) && !IsCurSchedule( SCHED_METROPOLICE_RETURN_TO_PRECHASE ) ) { SetCustomInterruptCondition( COND_METROPOLICE_CHANGE_BATON_STATE ); @@ -4947,18 +5868,34 @@ void CNPC_MetroPolice::BuildScheduleTestBits( void ) { ClearCustomInterruptCondition( COND_CAN_MELEE_ATTACK1 ); } + +#ifdef MAPBASE + if (gpGlobals->curtime < m_flNextAttack) + { + ClearCustomInterruptCondition( COND_CAN_RANGE_ATTACK1 ); + ClearCustomInterruptCondition( COND_CAN_RANGE_ATTACK2 ); + } +#endif } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- WeaponProficiency_t CNPC_MetroPolice::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { +#ifdef MAPBASE + if (EntIsClass(pWeapon, gm_isz_class_Pistol)) +#else if( FClassnameIs( pWeapon, "weapon_pistol" ) ) +#endif { return WEAPON_PROFICIENCY_POOR; } +#ifdef MAPBASE + if (EntIsClass(pWeapon, gm_isz_class_SMG1)) +#else if( FClassnameIs( pWeapon, "weapon_smg1" ) ) +#endif { return WEAPON_PROFICIENCY_VERY_GOOD; } @@ -4967,7 +5904,7 @@ WeaponProficiency_t CNPC_MetroPolice::CalcWeaponProficiency( CBaseCombatWeapon * } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CNPC_MetroPolice::GatherConditions( void ) { @@ -4979,13 +5916,13 @@ void CNPC_MetroPolice::GatherConditions( void ) } CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); - + // FIXME: Player can be NULL here during level transitions. if ( !pPlayer ) return; float distToPlayerSqr = ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); - + // See if we're too close if ( pPlayer->GetGroundEntity() == this ) { @@ -5032,7 +5969,7 @@ void CNPC_MetroPolice::GatherConditions( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::HasBaton( void ) @@ -5040,18 +5977,22 @@ bool CNPC_MetroPolice::HasBaton( void ) CBaseCombatWeapon *pWeapon = GetActiveWeapon(); if ( pWeapon ) +#ifdef MAPBASE + return EntIsClass(pWeapon, gm_isz_class_Stunstick); +#else return FClassnameIs( pWeapon, "weapon_stunstick" ); +#endif return false; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::BatonActive( void ) { -#ifndef HL2MP +#if !defined(HL2MP) || defined(MAPBASE) CWeaponStunStick *pStick = dynamic_cast(GetActiveWeapon()); @@ -5063,8 +6004,8 @@ bool CNPC_MetroPolice::BatonActive( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : state - +// Purpose: +// Input : state - //----------------------------------------------------------------------------- void CNPC_MetroPolice::SetBatonState( bool state ) { @@ -5079,8 +6020,8 @@ void CNPC_MetroPolice::SetBatonState( bool state ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pSound - +// Purpose: +// Input : *pSound - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CNPC_MetroPolice::QueryHearSound( CSound *pSound ) @@ -5097,16 +6038,16 @@ bool CNPC_MetroPolice::QueryHearSound( CSound *pSound ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : index - -// *pEvent - +// Purpose: +// Input : index - +// *pEvent - //----------------------------------------------------------------------------- void CNPC_MetroPolice::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) { BaseClass::VPhysicsCollision( index, pEvent ); int otherIndex = !index; - + CBaseEntity *pHitEntity = pEvent->pEntities[otherIndex]; if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) @@ -5128,8 +6069,8 @@ void CNPC_MetroPolice::VPhysicsCollision( int index, gamevcollisionevent_t *pEve } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pTarget - +// Purpose: +// Input : *pTarget - //----------------------------------------------------------------------------- void CNPC_MetroPolice::StunnedTarget( CBaseEntity *pTarget ) { @@ -5180,12 +6121,20 @@ AI_BEGIN_CUSTOM_NPC( npc_metropolice, CNPC_MetroPolice ) DECLARE_ANIMEVENT( AE_METROPOLICE_START_DEPLOY ); DECLARE_ANIMEVENT( AE_METROPOLICE_DRAW_PISTOL ); DECLARE_ANIMEVENT( AE_METROPOLICE_DEPLOY_MANHACK ); +#ifdef MAPBASE + DECLARE_ANIMEVENT( COMBINE_AE_BEGIN_ALTFIRE ) + DECLARE_ANIMEVENT( COMBINE_AE_ALTFIRE ) +#endif DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_CHARGE_ENEMY ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_HARASS ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_DEPLOY_MANHACK ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER1 ); DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ATTACK_OCCLUDER2 ); +#ifdef MAPBASE + DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_COVERING_FIRE1 ); + DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_COVERING_FIRE2 ); +#endif DECLARE_SQUADSLOT( SQUAD_SLOT_POLICE_ARREST_ENEMY ); DECLARE_ACTIVITY( ACT_METROPOLICE_DRAW_PISTOL ); @@ -5198,8 +6147,8 @@ AI_BEGIN_CUSTOM_NPC( npc_metropolice, CNPC_MetroPolice ) DECLARE_ACTIVITY( ACT_WALK_BATON ); DECLARE_ACTIVITY( ACT_IDLE_ANGRY_BATON ); - DECLARE_INTERACTION( g_interactionMetrocopStartedStitch ); - DECLARE_INTERACTION( g_interactionMetrocopIdleChatter ); + DECLARE_INTERACTION( g_interactionMetrocopStartedStitch ); + DECLARE_INTERACTION( g_interactionMetrocopIdleChatter ); DECLARE_INTERACTION( g_interactionMetrocopClearSentenceQueues ); DECLARE_TASK( TASK_METROPOLICE_HARASS ); @@ -5223,6 +6172,12 @@ AI_BEGIN_CUSTOM_NPC( npc_metropolice, CNPC_MetroPolice ) DECLARE_TASK( TASK_METROPOLICE_WAIT_FOR_SENTENCE ); DECLARE_TASK( TASK_METROPOLICE_GET_PATH_TO_PRECHASE ); DECLARE_TASK( TASK_METROPOLICE_CLEAR_PRECHASE ); +#ifdef MAPBASE + DECLARE_TASK( TASK_METROPOLICE_GET_PATH_TO_FORCED_GREN_LOS ) + DECLARE_TASK( TASK_METROPOLICE_DEFER_SQUAD_GRENADES ) + DECLARE_TASK( TASK_METROPOLICE_FACE_TOSS_DIR ) + DECLARE_TASK( TASK_METROPOLICE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET ) +#endif DECLARE_CONDITION( COND_METROPOLICE_ON_FIRE ); DECLARE_CONDITION( COND_METROPOLICE_ENEMY_RESISTING_ARREST ); @@ -5403,7 +6358,7 @@ DEFINE_SCHEDULE //========================================================= -// The uninterruptible portion of this behavior, whereupon +// The uninterruptible portion of this behavior, whereupon // the police actually releases the manhack. //========================================================= DEFINE_SCHEDULE @@ -5431,7 +6386,7 @@ DEFINE_SCHEDULE " TASK_SET_ACTIVITY ACTIVITY:ACT_IDLE_ANGRY" " TASK_FACE_ENEMY 0" " TASK_WAIT_FACE_ENEMY 1" // give the guy some time to come out on his own - " TASK_WAIT_FACE_ENEMY_RANDOM 3" + " TASK_WAIT_FACE_ENEMY_RANDOM 3" " TASK_GET_PATH_TO_ENEMY_LOS 0" " TASK_RUN_PATH 0" " TASK_WAIT_FOR_MOVEMENT 0" @@ -5481,7 +6436,7 @@ DEFINE_SCHEDULE " TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_METROPOLICE_BURNING_STAND" " TASK_SET_TOLERANCE_DISTANCE 24" " TASK_GET_PATH_TO_ENEMY 0" - " TASK_RUN_PATH_TIMED 10" + " TASK_RUN_PATH_TIMED 10" " TASK_METROPOLICE_DIE_INSTANTLY 0" " " " Interrupts" @@ -5842,5 +6797,85 @@ DEFINE_SCHEDULE " COND_ENEMY_DEAD" ); +#ifdef MAPBASE +//========================================================= + // Mapmaker forced grenade throw + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_METROPOLICE_FORCED_GRENADE_THROW, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_METROPOLICE_FACE_TOSS_DIR 0" + " TASK_ANNOUNCE_ATTACK 2" // 2 = grenade + " TASK_PLAY_SEQUENCE ACTIVITY:ACT_RANGE_ATTACK2" + " TASK_METROPOLICE_DEFER_SQUAD_GRENADES 0" + "" + " Interrupts" + ) + + //========================================================= + // Move to LOS of the mapmaker's forced grenade throw target + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_METROPOLICE_MOVE_TO_FORCED_GREN_LOS, + + " Tasks " + " TASK_SET_TOLERANCE_DISTANCE 48" + " TASK_METROPOLICE_GET_PATH_TO_FORCED_GREN_LOS 0" + " TASK_SPEAK_SENTENCE 1" + " TASK_RUN_PATH 0" + " TASK_WAIT_FOR_MOVEMENT 0" + " " + " Interrupts " + " COND_NEW_ENEMY" + " COND_ENEMY_DEAD" + " COND_CAN_MELEE_ATTACK1" + " COND_CAN_MELEE_ATTACK2" + " COND_HEAR_DANGER" + " COND_HEAR_MOVE_AWAY" + " COND_HEAVY_DAMAGE" + ) + + //========================================================= + // SCHED_METROPOLICE_RANGE_ATTACK2 + // + // secondary range attack. Overriden because base class stops attacking when the enemy is occluded. + // combines's grenade toss requires the enemy be occluded. + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_METROPOLICE_RANGE_ATTACK2, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_METROPOLICE_FACE_TOSS_DIR 0" + " TASK_ANNOUNCE_ATTACK 2" // 2 = grenade + " TASK_PLAY_SEQUENCE ACTIVITY:ACT_RANGE_ATTACK2" + " TASK_METROPOLICE_DEFER_SQUAD_GRENADES 0" + " TASK_SET_SCHEDULE SCHEDULE:SCHED_HIDE_AND_RELOAD" // don't run immediately after throwing grenade. + "" + " Interrupts" + ) + + //========================================================= + // AR2 Alt Fire Attack + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_METROPOLICE_AR2_ALTFIRE, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_ANNOUNCE_ATTACK 1" + " TASK_METROPOLICE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET ACTIVITY:ACT_COMBINE_AR2_ALTFIRE" + "" + " Interrupts" + " COND_TOO_CLOSE_TO_ATTACK" + ) +#endif + AI_END_CUSTOM_NPC() diff --git a/game/server/hl2/npc_metropolice.h b/game/server/hl2/npc_metropolice.h index 544fc68b..9478e207 100644 --- a/game/server/hl2/npc_metropolice.h +++ b/game/server/hl2/npc_metropolice.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -24,13 +24,26 @@ #include "ai_behavior_police.h" #include "ai_behavior_follow.h" #include "ai_sentence.h" +#ifdef MAPBASE +#include "mapbase/ai_grenade.h" +#endif #include "props.h" +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE +#include "mapbase/expandedrs_combine.h" +#define METROPOLICE_USES_RESPONSE_SYSTEM 1 +#endif class CNPC_MetroPolice; +#ifdef MAPBASE +class CNPC_MetroPolice : public CAI_GrenadeUser +{ + DECLARE_CLASS( CNPC_MetroPolice, CAI_GrenadeUser ); +#else class CNPC_MetroPolice : public CAI_BaseActor { DECLARE_CLASS( CNPC_MetroPolice, CAI_BaseActor ); +#endif DECLARE_DATADESC(); public: @@ -46,6 +59,21 @@ class CNPC_MetroPolice : public CAI_BaseActor float MaxYawSpeed( void ); void HandleAnimEvent( animevent_t *pEvent ); Activity NPC_TranslateActivity( Activity newActivity ); +#ifdef MAPBASE + Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired ); + + virtual int UnholsterWeapon( void ); + virtual void OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior ); + + const char* GetGrenadeAttachment() { return "LHand"; } + + virtual bool IsAltFireCapable() { return (m_iGrenadeCapabilities & GRENCAP_ALTFIRE) != 0 && BaseClass::IsAltFireCapable(); } + virtual bool IsGrenadeCapable() { return (m_iGrenadeCapabilities & GRENCAP_GRENADE) != 0; } + + virtual bool ShouldDropGrenades() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_GRENADE) != 0 && BaseClass::ShouldDropGrenades(); } + virtual bool ShouldDropInterruptedGrenades() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_INTERRUPTED) != 0 && BaseClass::ShouldDropInterruptedGrenades(); } + virtual bool ShouldDropAltFire() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_ALTFIRE) != 0 && BaseClass::ShouldDropAltFire(); } +#endif Vector EyeDirection3D( void ) { return CAI_BaseHumanoid::EyeDirection3D(); } // cops don't have eyes @@ -87,6 +115,15 @@ class CNPC_MetroPolice : public CAI_BaseActor // Speaking virtual void SpeakSentence( int nSentenceType ); +#ifdef METROPOLICE_USES_RESPONSE_SYSTEM + bool SpeakIfAllowed( const char *rrConcept, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ) + { + return SpeakIfAllowed( rrConcept, NULL, sentencepriority, sentencecriteria ); + } + bool SpeakIfAllowed( const char *rrConcept, const char *modifiers, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ); + bool SpeakIfAllowed( const char *rrConcept, AI_CriteriaSet& modifiers, SentencePriority_t sentencepriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t sentencecriteria = SENTENCE_CRITERIA_IN_SQUAD ); + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); +#endif // Set up the shot regulator based on the equipped weapon virtual void OnUpdateShotRegulator( ); @@ -101,7 +138,9 @@ class CNPC_MetroPolice : public CAI_BaseActor void SetBatonState( bool state ); bool BatonActive( void ); +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM CAI_Sentence< CNPC_MetroPolice > *GetSentences() { return &m_Sentences; } +#endif virtual bool AllowedToIgnite( void ) { return true; } @@ -153,7 +192,7 @@ class CNPC_MetroPolice : public CAI_BaseActor bool ShouldHitPlayer( const Vector &targetDir, float targetDist ); void PrescheduleThink( void ); - + void SetPlayerCriminalDuration( float time ); void IncrementPlayerCriminalStatus( void ); @@ -164,8 +203,19 @@ class CNPC_MetroPolice : public CAI_BaseActor // Inputs void InputEnableManhackToss( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDisableManhackToss( inputdata_t &inputdata ); + void InputDeployManhack( inputdata_t &inputdata ); + void InputAddManhacks( inputdata_t &inputdata ); + void InputSetManhacks( inputdata_t &inputdata ); +#endif void InputSetPoliceGoal( inputdata_t &inputdata ); void InputActivateBaton( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputAdministerJustice( inputdata_t &inputdata ); + void InputAddWarnings( inputdata_t &inputdata ); + void InputSetWarnings( inputdata_t &inputdata ); +#endif void NotifyDeadFriend ( CBaseEntity* pFriend ); @@ -187,7 +237,7 @@ class CNPC_MetroPolice : public CAI_BaseActor bool HasBaton( void ); - // Normal schedule selection + // Normal schedule selection int SelectCombatSchedule(); int SelectScheduleNewEnemy(); int SelectScheduleArrestEnemy(); @@ -202,6 +252,21 @@ class CNPC_MetroPolice : public CAI_BaseActor int SelectAirboatCombatSchedule(); int SelectAirboatRangeAttackSchedule(); +#ifdef MAPBASE + int SelectBehaviorOverrideSchedule(); + + bool IsCrouchedActivity( Activity activity ); + + // This is something Valve did with Combine soldiers so they would throw grenades during standoffs. + // We're using a similar thing here so metrocops deploy manhacks. + class CMetroPoliceStandoffBehavior : public CAI_ComponentWithOuter + { + typedef CAI_ComponentWithOuter BaseClass; + + virtual int SelectScheduleAttack(); + }; +#endif + // Handle flinching bool IsHeavyDamage( const CTakeDamageInfo &info ); @@ -266,10 +331,10 @@ class CNPC_MetroPolice : public CAI_BaseActor float StitchTightWeight( float flDist, float flSpeed, const Vector &vecTargetToGun, const Vector &vecVelocity ); int SelectStitchSchedule(); - // Can me enemy see me? + // Can me enemy see me? bool CanEnemySeeMe( ); - // Combat schedule selection + // Combat schedule selection int SelectMoveToLedgeSchedule(); // position to shoot at @@ -361,9 +426,15 @@ class CNPC_MetroPolice : public CAI_BaseActor SCHED_METROPOLICE_ALERT_FACE_BESTSOUND, SCHED_METROPOLICE_RETURN_TO_PRECHASE, SCHED_METROPOLICE_SMASH_PROP, +#ifdef MAPBASE + SCHED_METROPOLICE_FORCED_GRENADE_THROW, + SCHED_METROPOLICE_MOVE_TO_FORCED_GREN_LOS, + SCHED_METROPOLICE_RANGE_ATTACK2, + SCHED_METROPOLICE_AR2_ALTFIRE, +#endif }; - enum + enum { TASK_METROPOLICE_HARASS = BaseClass::NEXT_TASK, TASK_METROPOLICE_DIE_INSTANTLY, @@ -387,6 +458,12 @@ class CNPC_MetroPolice : public CAI_BaseActor TASK_METROPOLICE_WAIT_FOR_SENTENCE, TASK_METROPOLICE_GET_PATH_TO_PRECHASE, TASK_METROPOLICE_CLEAR_PRECHASE, +#ifdef MAPBASE + TASK_METROPOLICE_GET_PATH_TO_FORCED_GREN_LOS, + TASK_METROPOLICE_DEFER_SQUAD_GRENADES, + TASK_METROPOLICE_FACE_TOSS_DIR, + TASK_METROPOLICE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET, +#endif }; private: @@ -417,12 +494,12 @@ class CNPC_MetroPolice : public CAI_BaseActor float m_flValidStitchTime; float m_flNextLedgeCheckTime; float m_flTaskCompletionTime; - + bool m_bShouldActivateBaton; float m_flBatonDebounceTime; // Minimum amount of time before turning the baton off float m_flLastPhysicsFlinchTime; float m_flLastDamageFlinchTime; - + // Sentences float m_flNextPainSoundTime; float m_flNextLostSoundTime; @@ -441,19 +518,33 @@ class CNPC_MetroPolice : public CAI_BaseActor // Outputs COutputEvent m_OnStunnedPlayer; COutputEvent m_OnCupCopped; +#ifdef MAPBASE + COutputEHANDLE m_OnHitByPhysicsObject; + COutputEHANDLE m_OutManhack; + + // Determines whether this NPC is allowed to use grenades or alt-fire stuff. + eGrenadeCapabilities m_iGrenadeCapabilities; + eGrenadeDropCapabilities m_iGrenadeDropCapabilities; +#endif AIHANDLE m_hManhack; CHandle m_hBlockingProp; CAI_ActBusyBehavior m_ActBusyBehavior; +#ifdef MAPBASE + CMetroPoliceStandoffBehavior m_StandoffBehavior; +#else CAI_StandoffBehavior m_StandoffBehavior; +#endif CAI_AssaultBehavior m_AssaultBehavior; CAI_FuncTankBehavior m_FuncTankBehavior; CAI_RappelBehavior m_RappelBehavior; CAI_PolicingBehavior m_PolicingBehavior; CAI_FollowBehavior m_FollowBehavior; +#ifndef METROPOLICE_USES_RESPONSE_SYSTEM CAI_Sentence< CNPC_MetroPolice > m_Sentences; +#endif int m_nRecentDamage; float m_flRecentDamageTime; diff --git a/game/server/hl2/npc_monk.cpp b/game/server/hl2/npc_monk.cpp index c20f558c..e517a6fe 100644 --- a/game/server/hl2/npc_monk.cpp +++ b/game/server/hl2/npc_monk.cpp @@ -16,6 +16,9 @@ #include "ai_behavior.h" #include "ai_behavior_assault.h" #include "ai_behavior_lead.h" +#ifdef MAPBASE +#include "ai_behavior_functank.h" +#endif #include "npcevent.h" #include "ai_playerally.h" #include "ai_senses.h" @@ -103,6 +106,10 @@ class CNPC_Monk : public CAI_PlayerAlly CAI_AssaultBehavior m_AssaultBehavior; CAI_LeadBehavior m_LeadBehavior; +#ifdef MAPBASE + CAI_FuncTankBehavior m_FuncTankBehavior; +#endif + int m_iNumZombies; int m_iDangerousZombies; bool m_bPerfectAccuracy; @@ -113,6 +120,9 @@ class CNPC_Monk : public CAI_PlayerAlly BEGIN_DATADESC( CNPC_Monk ) // m_AssaultBehavior // m_LeadBehavior +#ifdef MAPBASE +// m_FuncTankBehavior +#endif DEFINE_FIELD( m_iNumZombies, FIELD_INTEGER ), DEFINE_FIELD( m_iDangerousZombies, FIELD_INTEGER ), DEFINE_FIELD( m_bPerfectAccuracy, FIELD_BOOLEAN ), @@ -132,6 +142,9 @@ bool CNPC_Monk::CreateBehaviors() { AddBehavior( &m_LeadBehavior ); AddBehavior( &m_AssaultBehavior ); +#ifdef MAPBASE + AddBehavior( &m_FuncTankBehavior ); +#endif return BaseClass::CreateBehaviors(); } @@ -183,6 +196,9 @@ Class_T CNPC_Monk::Classify( void ) return CLASS_PLAYER_ALLY_VITAL; } +#ifdef MAPBASE +ConVar npc_monk_use_old_acts( "npc_monk_use_old_acts", "1" ); +#endif //----------------------------------------------------------------------------- // Purpose: @@ -216,6 +232,45 @@ Activity CNPC_Monk::NPC_TranslateActivity( Activity eNewActivity ) } } +#if defined(EXPANDED_HL2_WEAPON_ACTIVITIES) && AR2_ACTIVITY_FIX == 1 + if (npc_monk_use_old_acts.GetBool()) + { + // HACKHACK: Don't break the balcony scene + if ( FStrEq( STRING(gpGlobals->mapname), "d1_town_02" ) && eNewActivity == ACT_IDLE ) + { + eNewActivity = ACT_IDLE_SMG1; + } + else + { + switch (eNewActivity) + { + case ACT_IDLE_AR2: + eNewActivity = ACT_IDLE_SMG1; + break; + + case ACT_IDLE_ANGRY_SHOTGUN: + case ACT_IDLE_ANGRY_AR2: + eNewActivity = ACT_IDLE_ANGRY_SMG1; + break; + + case ACT_WALK_AIM_SHOTGUN: + case ACT_WALK_AIM_AR2: + eNewActivity = ACT_WALK_AIM_RIFLE; + break; + + case ACT_RUN_AIM_SHOTGUN: + case ACT_RUN_AIM_AR2: + eNewActivity = ACT_RUN_AIM_RIFLE; + break; + + case ACT_RANGE_ATTACK_SHOTGUN_LOW: + case ACT_RANGE_ATTACK_AR2_LOW: + eNewActivity = ACT_RANGE_ATTACK_SMG1_LOW; + break; + } + } + } +#else // We need these so that we can pick up the shotgun to throw it in the balcony scene if ( eNewActivity == ACT_IDLE_ANGRY_SHOTGUN ) { @@ -233,6 +288,7 @@ Activity CNPC_Monk::NPC_TranslateActivity( Activity eNewActivity ) { return ACT_RANGE_ATTACK_SMG1_LOW; } +#endif return eNewActivity; } @@ -665,6 +721,17 @@ int CNPC_Monk::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFa { if( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { +#ifdef MAPBASE + // I thought it would be a nice touch. + if (RandomInt(1, 2) == 1 && CanRunAScriptedNPCInteraction(false)) + { + for ( int i = 0; i < m_ScriptedInteractions.Count(); i++ ) + { + m_ScriptedInteractions[i].flNextAttemptTime = gpGlobals->curtime; + } + } +#endif + // Most likely backed into a corner. Just blaze away. return SCHED_MONK_RANGE_ATTACK1; } diff --git a/game/server/hl2/npc_mossman.cpp b/game/server/hl2/npc_mossman.cpp index ff924cd2..f92a8f51 100644 --- a/game/server/hl2/npc_mossman.cpp +++ b/game/server/hl2/npc_mossman.cpp @@ -41,6 +41,11 @@ class CNPC_Mossman : public CAI_PlayerAlly bool CreateBehaviors( void ); int SelectSchedule( void ); +#ifdef MAPBASE + // Use Mossman's default subtitle color (220,255,198) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 220; params.g1 = 255; params.b1 = 198; return BaseClass::GetGameTextSpeechParams( params ); } +#endif + private: CAI_FollowBehavior m_FollowBehavior; }; diff --git a/game/server/hl2/npc_playercompanion.cpp b/game/server/hl2/npc_playercompanion.cpp index a03a752f..68568a72 100644 --- a/game/server/hl2/npc_playercompanion.cpp +++ b/game/server/hl2/npc_playercompanion.cpp @@ -31,12 +31,21 @@ #include "grenade_frag.h" #include #include "physics_npc_solver.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#include "world.h" +#include "vehicle_base.h" +#endif ConVar ai_debug_readiness("ai_debug_readiness", "0" ); ConVar ai_use_readiness("ai_use_readiness", "1" ); // 0 = off, 1 = on, 2 = on for player squad only ConVar ai_readiness_decay( "ai_readiness_decay", "120" );// How many seconds it takes to relax completely ConVar ai_new_aiming( "ai_new_aiming", "1" ); +#ifdef COMPANION_MELEE_ATTACK +ConVar sk_companion_melee_damage("sk_companion_melee_damage", "25"); +#endif + #define GetReadinessUse() ai_use_readiness.GetInt() extern ConVar g_debug_transitions; @@ -46,6 +55,15 @@ extern ConVar g_debug_transitions; int AE_COMPANION_PRODUCE_FLARE; int AE_COMPANION_LIGHT_FLARE; int AE_COMPANION_RELEASE_FLARE; +#if COMPANION_MELEE_ATTACK +#define AE_PC_MELEE 3 + +#define COMPANION_MELEE_DIST 64.0 +#endif + +#ifdef MAPBASE +ConVar ai_allow_new_weapons( "ai_allow_new_weapons", "1", FCVAR_NONE, "Allows companion NPCs to automatically pick up and use weapons they were unable pick up before, i.e. 357s or crossbows." ); +#endif #define MAX_TIME_BETWEEN_BARRELS_EXPLODING 5.0f #define MAX_TIME_BETWEEN_CONSECUTIVE_PLAYER_KILLS 3.0f @@ -97,7 +115,9 @@ BEGIN_DATADESC( CNPC_PlayerCompanion ) #endif // HL2_EPISODIC //------------------------------------------------------------------------------ +#ifndef MAPBASE DEFINE_INPUTFUNC( FIELD_STRING, "GiveWeapon", InputGiveWeapon ), +#endif DEFINE_FIELD( m_flReadiness, FIELD_FLOAT ), DEFINE_FIELD( m_flReadinessSensitivity, FIELD_FLOAT ), @@ -130,6 +150,16 @@ BEGIN_DATADESC( CNPC_PlayerCompanion ) DEFINE_OUTPUT( m_OnWeaponPickup, "OnWeaponPickup" ), +#ifdef MAPBASE + DEFINE_AIGRENADE_DATADESC() + DEFINE_INPUT( m_iGrenadeCapabilities, FIELD_INTEGER, "SetGrenadeCapabilities" ), + DEFINE_INPUT( m_iGrenadeDropCapabilities, FIELD_INTEGER, "SetGrenadeDropCapabilities" ), +#endif + +#ifdef COMPANION_MELEE_ATTACK + DEFINE_FIELD( m_nMeleeDamage, FIELD_INTEGER ), +#endif + END_DATADESC() //----------------------------------------------------------------------------- @@ -137,11 +167,33 @@ END_DATADESC() CNPC_PlayerCompanion::eCoverType CNPC_PlayerCompanion::gm_fCoverSearchType; bool CNPC_PlayerCompanion::gm_bFindingCoverFromAllEnemies; +#ifdef MAPBASE +string_t CNPC_PlayerCompanion::gm_iszMortarClassname; +string_t CNPC_PlayerCompanion::gm_iszGroundTurretClassname; +#else string_t CNPC_PlayerCompanion::gm_iszMortarClassname; string_t CNPC_PlayerCompanion::gm_iszFloorTurretClassname; string_t CNPC_PlayerCompanion::gm_iszGroundTurretClassname; string_t CNPC_PlayerCompanion::gm_iszShotgunClassname; string_t CNPC_PlayerCompanion::gm_iszRollerMineClassname; +#ifdef MAPBASE +string_t CNPC_PlayerCompanion::gm_iszSMG1Classname; +string_t CNPC_PlayerCompanion::gm_iszAR2Classname; +#endif +#endif + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +CNPC_PlayerCompanion::CNPC_PlayerCompanion() +{ +#ifdef MAPBASE + if (ai_grenade_always_drop.GetBool()) + { + m_iGrenadeDropCapabilities = (eGrenadeDropCapabilities)(GRENDROPCAP_GRENADE | GRENDROPCAP_ALTFIRE | GRENDROPCAP_INTERRUPTED); + } +#endif +} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -167,6 +219,10 @@ bool CNPC_PlayerCompanion::CreateBehaviors() AddBehavior( &m_FollowBehavior ); AddBehavior( &m_LeadBehavior ); #endif//HL2_EPISODIC + +#ifdef MAPBASE + AddBehavior( &m_FuncTankBehavior ); +#endif return BaseClass::CreateBehaviors(); } @@ -175,11 +231,25 @@ bool CNPC_PlayerCompanion::CreateBehaviors() //----------------------------------------------------------------------------- void CNPC_PlayerCompanion::Precache() { +#ifdef MAPBASE + gm_iszMortarClassname = AllocPooledString( "func_tankmortar" ); + gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); +#else gm_iszMortarClassname = AllocPooledString( "func_tankmortar" ); gm_iszFloorTurretClassname = AllocPooledString( "npc_turret_floor" ); gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); gm_iszShotgunClassname = AllocPooledString( "weapon_shotgun" ); gm_iszRollerMineClassname = AllocPooledString( "npc_rollermine" ); +#ifdef MAPBASE + gm_iszSMG1Classname = AllocPooledString( "weapon_smg1" ); + gm_iszAR2Classname = AllocPooledString( "weapon_ar2" ); +#endif +#endif + +#ifdef MAPBASE + // Moved from Spawn() + SelectModel(); +#endif PrecacheModel( STRING( GetModelName() ) ); @@ -188,6 +258,10 @@ void CNPC_PlayerCompanion::Precache() PrecacheModel( "models/props_junk/flare.mdl" ); #endif // HL2_EPISODIC +#ifdef MAPBASE + PrecacheScriptSound( "Weapon_CombineGuard.Special1" ); +#endif + BaseClass::Precache(); } @@ -195,7 +269,9 @@ void CNPC_PlayerCompanion::Precache() //----------------------------------------------------------------------------- void CNPC_PlayerCompanion::Spawn() { +#ifndef MAPBASE // Moved to Precache() SelectModel(); +#endif Precache(); @@ -234,7 +310,7 @@ void CNPC_PlayerCompanion::Spawn() m_AnnounceAttackTimer.Set( 10, 30 ); -#ifdef HL2_EPISODIC +#if HL2_EPISODIC && !MAPBASE // Mapbase permits this flag since the warning can be distracting and stripping the flag might break some HL2 maps in Episodic mods // We strip this flag because it's been made obsolete by the StartScripting behavior if ( HasSpawnFlags( SF_NPC_ALTCOLLISION ) ) { @@ -245,6 +321,10 @@ void CNPC_PlayerCompanion::Spawn() m_hFlare = NULL; #endif // HL2_EPISODIC +#if COMPANION_MELEE_ATTACK + m_nMeleeDamage = sk_companion_melee_damage.GetInt(); +#endif + BaseClass::Spawn(); } @@ -260,7 +340,7 @@ int CNPC_PlayerCompanion::Restore( IRestore &restore ) m_StandoffBehavior.SetActive( false ); } -#ifdef HL2_EPISODIC +#if HL2_EPISODIC && !MAPBASE // Mapbase permits this flag since the warning can be distracting and stripping the flag might break some HL2 maps in Episodic mods // We strip this flag because it's been made obsolete by the StartScripting behavior if ( HasSpawnFlags( SF_NPC_ALTCOLLISION ) ) { @@ -315,8 +395,13 @@ Disposition_t CNPC_PlayerCompanion::IRelationType( CBaseEntity *pTarget ) else if ( baseRelationship == D_HT && pTarget->IsNPC() && ((CAI_BaseNPC *)pTarget)->GetActiveWeapon() && +#ifdef MAPBASE + (EntIsClass( ((CAI_BaseNPC *)pTarget)->GetActiveWeapon(), gm_iszShotgunClassname ) && + ( !GetActiveWeapon() || !EntIsClass( GetActiveWeapon(), gm_iszShotgunClassname ) ) ) ) +#else ((CAI_BaseNPC *)pTarget)->GetActiveWeapon()->ClassMatches( gm_iszShotgunClassname ) && ( !GetActiveWeapon() || !GetActiveWeapon()->ClassMatches( gm_iszShotgunClassname ) ) ) +#endif { if ( (pTarget->GetAbsOrigin() - GetAbsOrigin()).LengthSqr() < Square( 25 * 12 ) ) { @@ -496,6 +581,14 @@ void CNPC_PlayerCompanion::GatherConditions() DoCustomSpeechAI(); } +#ifdef MAPBASE + // Alyx's custom combat AI copied to CNPC_PlayerCompanion for reasons specified in said function. + if ( m_NPCState == NPC_STATE_COMBAT ) + { + DoCustomCombatAI(); + } +#endif + if ( AI_IsSinglePlayer() && hl2_episodic.GetBool() && !GetEnemy() && HasCondition( COND_HEAR_PLAYER ) ) { Vector los = ( UTIL_GetLocalPlayer()->EyePosition() - EyePosition() ); @@ -538,7 +631,12 @@ void CNPC_PlayerCompanion::DoCustomSpeechAI( void ) } // Mention the player is dead +#ifdef MAPBASE + // (unless we hate them) + if ( HasCondition( COND_TALKER_PLAYER_DEAD ) && (!pPlayer || IRelationType(pPlayer) > D_FR) ) +#else if ( HasCondition( COND_TALKER_PLAYER_DEAD ) ) +#endif { SpeakIfAllowed( TLK_PLDEAD ); } @@ -573,6 +671,15 @@ void CNPC_PlayerCompanion::BuildScheduleTestBits() SetCustomInterruptCondition( COND_PLAYER_PUSHING ); } +#if COMPANION_MELEE_ATTACK + if (IsCurSchedule(SCHED_RANGE_ATTACK1) || + IsCurSchedule(SCHED_BACK_AWAY_FROM_ENEMY) || + IsCurSchedule(SCHED_RUN_FROM_ENEMY)) + { + SetCustomInterruptCondition( COND_CAN_MELEE_ATTACK1 ); + } +#endif + if ( ( ConditionInterruptsCurSchedule( COND_GIVE_WAY ) || IsCurSchedule(SCHED_HIDE_AND_RELOAD ) || IsCurSchedule(SCHED_RELOAD ) || @@ -715,6 +822,46 @@ int CNPC_PlayerCompanion::SelectSchedule() } } +#ifdef MAPBASE + if ( m_hForcedGrenadeTarget ) + { + // Can't throw at the target, so lets try moving to somewhere where I can see it + if ( !FVisible( m_hForcedGrenadeTarget ) ) + { + return SCHED_PC_MOVE_TO_FORCED_GREN_LOS; + } + else if ( m_flNextGrenadeCheck < gpGlobals->curtime ) + { + Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); + + // The fact we have a forced grenade target overrides whether we're marked as "capable". + // If we're *only* alt-fire capable, use an energy ball. If not, throw a grenade. + if (!IsAltFireCapable() || IsGrenadeCapable()) + { + Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); + { + // If we can, throw a grenade at the target. + // Ignore grenade count / distance / etc + if ( CheckCanThrowGrenade( vecTarget ) ) + { + m_hForcedGrenadeTarget = NULL; + return SCHED_PC_FORCED_GRENADE_THROW; + } + } + } + else + { + if ( FVisible( m_hForcedGrenadeTarget ) ) + { + m_vecAltFireTarget = vecTarget; + m_hForcedGrenadeTarget = NULL; + return SCHED_PC_AR2_ALTFIRE; + } + } + } + } +#endif + int nSched = SelectFlinchSchedule(); if ( nSched != SCHED_NONE ) return nSched; @@ -873,10 +1020,39 @@ bool CNPC_PlayerCompanion::IgnorePlayerPushing( void ) //----------------------------------------------------------------------------- int CNPC_PlayerCompanion::SelectScheduleCombat() { +#if COMPANION_MELEE_ATTACK + if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) ) + { + DevMsg("Returning melee attack schedule\n"); + return SCHED_MELEE_ATTACK1; + } +#endif + if ( CanReload() && (HasCondition ( COND_NO_PRIMARY_AMMO ) || HasCondition(COND_LOW_PRIMARY_AMMO)) ) { return SCHED_HIDE_AND_RELOAD; } + +#ifdef MAPBASE + if ( HasGrenades() && GetEnemy() && !HasCondition(COND_SEE_ENEMY) ) + { + // We don't see our enemy. If it hasn't been long since I last saw him, + // and he's pretty close to the last place I saw him, throw a grenade in + // to flush him out. A wee bit of cheating here... + + float flTime; + float flDist; + + flTime = gpGlobals->curtime - GetEnemies()->LastTimeSeen( GetEnemy() ); + flDist = ( GetEnemy()->GetAbsOrigin() - GetEnemies()->LastSeenPosition( GetEnemy() ) ).Length(); + + //Msg("Time: %f Dist: %f\n", flTime, flDist ); + if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_PC_RANGE_ATTACK2; + } + } +#endif return SCHED_NONE; } @@ -908,6 +1084,14 @@ bool CNPC_PlayerCompanion::ShouldDeferToFollowBehavior() return false; } +#if COMPANION_MELEE_ATTACK + if (HasCondition(COND_CAN_MELEE_ATTACK1) /*&& !GetFollowBehavior().IsActive()*/) + { + // We should only get melee condition if we're not moving + return false; + } +#endif + // Even though assault and act busy are placed ahead of the follow behavior in precedence, the below // code is necessary because we call ShouldDeferToFollowBehavior BEFORE we call the generic // BehaviorSelectSchedule, which tries the behaviors in priority order. @@ -943,6 +1127,12 @@ bool CNPC_PlayerCompanion::IsValidReasonableFacing( const Vector &vecSightDir, f if( ai_new_aiming.GetBool() ) { +#ifdef MAPBASE + // Hint node facing should still be obeyed + if (GetHintNode() && GetHintNode()->GetIgnoreFacing() != HIF_YES) + return true; +#endif + Vector vecEyePositionCentered = GetAbsOrigin(); vecEyePositionCentered.z = EyePosition().z; @@ -978,6 +1168,10 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) pWeapon->Clip1() < ( pWeapon->GetMaxClip1() * .75 ) && pPlayer->GetAmmoCount( pWeapon->GetPrimaryAmmoType() ) ) { +#ifdef MAPBASE + // Less annoying + if ( !pWeapon->m_bInReload && (gpGlobals->curtime - GetLastEnemyTime()) > 5.0f ) +#endif SpeakIfAllowed( TLK_PLRELOAD ); } } @@ -1009,6 +1203,14 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) return SCHED_PC_FLEE_FROM_BEST_SOUND; case SCHED_ESTABLISH_LINE_OF_FIRE: +#ifdef MAPBASE + if ( CanAltFireEnemy(false) && OccupyStrategySlot(SQUAD_SLOT_SPECIAL_ATTACK) ) + { + // If this companion has the balls to alt-fire the enemy's last known position, + // do so! + return SCHED_PC_AR2_ALTFIRE; + } +#endif case SCHED_MOVE_TO_WEAPON_RANGE: if ( IsMortar( GetEnemy() ) ) return SCHED_TAKE_COVER_FROM_ENEMY; @@ -1017,13 +1219,21 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) case SCHED_CHASE_ENEMY: if ( IsMortar( GetEnemy() ) ) return SCHED_TAKE_COVER_FROM_ENEMY; +#ifdef MAPBASE + if ( GetEnemy() && EntIsClass( GetEnemy(), gm_isz_class_Gunship ) ) +#else if ( GetEnemy() && FClassnameIs( GetEnemy(), "npc_combinegunship" ) ) +#endif return SCHED_ESTABLISH_LINE_OF_FIRE; break; case SCHED_ESTABLISH_LINE_OF_FIRE_FALLBACK: // If we're fighting a gunship, try again +#ifdef MAPBASE + if ( GetEnemy() && EntIsClass( GetEnemy(), gm_isz_class_Gunship ) ) +#else if ( GetEnemy() && FClassnameIs( GetEnemy(), "npc_combinegunship" ) ) +#endif return SCHED_ESTABLISH_LINE_OF_FIRE; break; @@ -1034,10 +1244,44 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) if ( GetShotRegulator()->IsInRestInterval() ) return SCHED_STANDOFF; +#ifdef MAPBASE + if (CanAltFireEnemy( true ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK )) + { + // Since I'm holding this squadslot, no one else can try right now. If I die before the shot + // goes off, I won't have affected anyone else's ability to use this attack at their nearest + // convenience. + return SCHED_PC_AR2_ALTFIRE; + } + + if ( !OccupyStrategySlotRange( SQUAD_SLOT_ATTACK1, SQUAD_SLOT_ATTACK2 ) ) + { + // Throw a grenade if not allowed to engage with weapon. + if ( CanGrenadeEnemy() ) + { + if ( OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + return SCHED_PC_RANGE_ATTACK2; + } + } + + return SCHED_STANDOFF; + } +#else if( !OccupyStrategySlotRange( SQUAD_SLOT_ATTACK1, SQUAD_SLOT_ATTACK2 ) ) return SCHED_STANDOFF; +#endif break; +#if COMPANION_MELEE_ATTACK + //case SCHED_BACK_AWAY_FROM_ENEMY: + // if (HasCondition(COND_CAN_MELEE_ATTACK1)) + // return SCHED_MELEE_ATTACK1; + // break; + + case SCHED_MELEE_ATTACK1: + return SCHED_PC_MELEE_AND_MOVE_AWAY; +#endif + case SCHED_FAIL_TAKE_COVER: if ( IsEnemyTurret() ) { @@ -1046,17 +1290,53 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) break; case SCHED_RUN_FROM_ENEMY_FALLBACK: { +#if COMPANION_MELEE_ATTACK + if (HasCondition(COND_CAN_MELEE_ATTACK1) && !HasCondition(COND_HEAVY_DAMAGE)) + { + return SCHED_MELEE_ATTACK1; + } +#endif if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { return SCHED_RANGE_ATTACK1; } break; } + +#ifdef MAPBASE + case SCHED_TAKE_COVER_FROM_ENEMY: + { + if ( m_pSquad ) + { + // Have to explicitly check innate range attack condition as may have weapon with range attack 2 + if ( HasCondition(COND_CAN_RANGE_ATTACK2) && + OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) + { + SpeakIfAllowed("TLK_THROWGRENADE"); + return SCHED_PC_RANGE_ATTACK2; + } + } + } + break; + case SCHED_HIDE_AND_RELOAD: + { + if( CanGrenadeEnemy() && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) && random->RandomInt( 0, 100 ) < 20 ) + { + // If I COULD throw a grenade and I need to reload, 20% chance I'll throw a grenade before I hide to reload. + return SCHED_PC_RANGE_ATTACK2; + } + } + break; +#endif } return BaseClass::TranslateSchedule( scheduleType ); } +#ifdef MAPBASE +//extern float GetCurrentGravity( void ); +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_PlayerCompanion::StartTask( const Task_t *pTask ) @@ -1114,6 +1394,23 @@ void CNPC_PlayerCompanion::StartTask( const Task_t *pTask ) } break; +#ifdef MAPBASE + case TASK_PC_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: + StartTask_FaceAltFireTarget( pTask ); + break; + + case TASK_PC_GET_PATH_TO_FORCED_GREN_LOS: + StartTask_GetPathToForced( pTask ); + break; + + case TASK_PC_DEFER_SQUAD_GRENADES: + StartTask_DeferSquad( pTask ); + break; + + case TASK_PC_FACE_TOSS_DIR: + break; +#endif + default: BaseClass::StartTask( pTask ); break; @@ -1161,6 +1458,20 @@ void CNPC_PlayerCompanion::RunTask( const Task_t *pTask ) } break; +#ifdef MAPBASE + case TASK_PC_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET: + RunTask_FaceAltFireTarget( pTask ); + break; + + case TASK_PC_GET_PATH_TO_FORCED_GREN_LOS: + RunTask_GetPathToForced( pTask ); + break; + + case TASK_PC_FACE_TOSS_DIR: + RunTask_FaceTossDir( pTask ); + break; +#endif + default: BaseClass::RunTask( pTask ); break; @@ -1343,6 +1654,19 @@ Activity CNPC_PlayerCompanion::TranslateActivityReadiness( Activity activity ) continue; } +#ifdef MAPBASE + // If we don't have the readiness activity we selected and there's no backup activity available, break the loop and return the base act. + bool bRequired; + if ( !HaveSequenceForActivity( actremap.mappedActivity ) && !HaveSequenceForActivity( Weapon_TranslateActivity( actremap.mappedActivity, &bRequired ) ) ) + { + Activity backupAct = Weapon_BackupActivity( actremap.mappedActivity, bRequired ); + if ( backupAct != actremap.mappedActivity ) + return backupAct; + else + break; + } +#endif + // We've successfully passed all criteria for remapping this return actremap.mappedActivity; } @@ -1376,6 +1700,15 @@ Activity CNPC_PlayerCompanion::NPC_TranslateActivity( Activity activity ) } } +#ifdef MAPBASE + // Vorts use ACT_RANGE_ATTACK2, but they should translate to ACT_VORTIGAUNT_DISPEL + // before that reaches this code... + if (activity == ACT_RANGE_ATTACK2) + { + activity = ACT_COMBINE_THROW_GRENADE; + } +#endif + return TranslateActivityReadiness( activity ); } @@ -1449,14 +1782,44 @@ void CNPC_PlayerCompanion::HandleAnimEvent( animevent_t *pEvent ) case EVENT_WEAPON_RELOAD: if ( GetActiveWeapon() ) { +#ifdef MAPBASE + GetActiveWeapon()->Reload_NPC(); +#else GetActiveWeapon()->WeaponSound( RELOAD_NPC ); GetActiveWeapon()->m_iClip1 = GetActiveWeapon()->GetMaxClip1(); +#endif ClearCondition(COND_LOW_PRIMARY_AMMO); ClearCondition(COND_NO_PRIMARY_AMMO); ClearCondition(COND_NO_SECONDARY_AMMO); } break; +#if COMPANION_MELEE_ATTACK + case AE_PC_MELEE: + { + CBaseEntity *pHurt = CheckTraceHullAttack(COMPANION_MELEE_DIST, -Vector(16, 16, 18), Vector(16, 16, 18), 0, DMG_CLUB); + CBaseCombatCharacter* pBCC = ToBaseCombatCharacter(pHurt); + if (pBCC) + { + Vector forward, up; + AngleVectors(GetLocalAngles(), &forward, NULL, &up); + + if (pBCC->IsPlayer()) + { + pBCC->ViewPunch(QAngle(-12, -7, 0)); + pHurt->ApplyAbsVelocityImpulse(forward * 100 + up * 50); + } + + CTakeDamageInfo info(this, this, m_nMeleeDamage, DMG_CLUB); + CalculateMeleeDamageForce(&info, forward, pBCC->GetAbsOrigin()); + pBCC->TakeDamage(info); + + EmitSound("NPC_Combine.WeaponBash"); + } + break; + } +#endif + default: BaseClass::HandleAnimEvent( pEvent ); break; @@ -1533,6 +1896,20 @@ void CNPC_PlayerCompanion::ModifyOrAppendCriteria( AI_CriteriaSet& set ) set.AppendCriteria( "hurt_by_fire", "1" ); } +#ifdef MAPBASE + // Ported from Alyx. + AIEnemiesIter_t iter; + int iNumEnemies = 0; + for ( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) ) + { + if ( pEMemory->hEnemy->IsAlive() && ( pEMemory->hEnemy->Classify() != CLASS_BULLSEYE ) ) + { + iNumEnemies++; + } + } + set.AppendCriteria( "num_enemies", UTIL_VarArgs( "%d", iNumEnemies ) ); +#endif + if ( m_bReadinessCapable ) { switch( GetReadinessLevel() ) @@ -1574,11 +1951,33 @@ bool CNPC_PlayerCompanion::IsReadinessCapable() return false; #endif +#ifdef MAPBASE +#ifdef HL2_EPISODIC + if (GetActiveWeapon()) +#else + // We already know we have a weapon due to the check above +#endif + { + // Rather than looking up the activity string, we just make sure our weapon accepts a few basic readiness activity overrides. + // This lets us make sure our weapon is readiness-capable to begin with. + if ( TranslateActivity( ACT_IDLE_RELAXED ) == ACT_IDLE_RELAXED && + TranslateActivity( ACT_IDLE_STIMULATED ) == ACT_IDLE_STIMULATED && + TranslateActivity( ACT_IDLE_AGITATED ) == ACT_IDLE_AGITATED ) + return false; + + if (LookupActivity( "ACT_IDLE_AIM_RIFLE_STIMULATED" ) == ACT_INVALID) + return false; + + if (EntIsClass(GetActiveWeapon(), gm_isz_class_RPG)) + return false; + } +#else if( GetActiveWeapon() && LookupActivity("ACT_IDLE_AIM_RIFLE_STIMULATED") == ACT_INVALID ) return false; if( GetActiveWeapon() && FClassnameIs( GetActiveWeapon(), "weapon_rpg" ) ) return false; +#endif return true; } @@ -2329,7 +2728,11 @@ Vector CNPC_PlayerCompanion::GetActualShootPosition( const Vector &shootOrigin ) //------------------------------------------------------------------------------ WeaponProficiency_t CNPC_PlayerCompanion::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ) { +#ifdef MAPBASE + if ( EntIsClass(pWeapon, gm_iszAR2Classname) ) +#else if( FClassnameIs( pWeapon, "weapon_ar2" ) ) +#endif { return WEAPON_PROFICIENCY_VERY_GOOD; } @@ -2346,10 +2749,21 @@ bool CNPC_PlayerCompanion::Weapon_CanUse( CBaseCombatWeapon *pWeapon ) // If this weapon is a shotgun, take measures to control how many // are being used in this squad. Don't allow a companion to pick up // a shotgun if a squadmate already has one. +#ifdef MAPBASE + if (EntIsClass(pWeapon, gm_iszShotgunClassname)) +#else if( pWeapon->ClassMatches( gm_iszShotgunClassname ) ) +#endif { return (NumWeaponsInSquad("weapon_shotgun") < 1 ); } +#ifdef MAPBASE + else if (EntIsClass( pWeapon, gm_isz_class_Pistol ) || EntIsClass( pWeapon, gm_isz_class_357 ) || EntIsClass( pWeapon, gm_isz_class_Crossbow )) + { + // The AI automatically detects these weapons as usable now that there's animations for them, so ensure this behavior can be toggled in situations where that's not desirable + return ai_allow_new_weapons.GetBool(); + } +#endif else { return true; @@ -2366,6 +2780,15 @@ bool CNPC_PlayerCompanion::ShouldLookForBetterWeapon() if ( m_bDontPickupWeapons ) return false; +#ifdef MAPBASE + // Now that citizens can holster weapons, they might look for a new one while unarmed. + // Since that could already be worked around with OnHolster > DisableWeaponPickup, I decided to keep it that way in case it's desirable. + + // Don't look for a new weapon if we have secondary ammo for our current one. + if (m_iNumGrenades > 0 && IsAltFireCapable() && GetActiveWeapon() && GetActiveWeapon()->UsesSecondaryAmmo()) + return false; +#endif + return BaseClass::ShouldLookForBetterWeapon(); } @@ -2377,14 +2800,113 @@ void CNPC_PlayerCompanion::Weapon_Equip( CBaseCombatWeapon *pWeapon ) m_bReadinessCapable = IsReadinessCapable(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CNPC_PlayerCompanion::DoUnholster() +{ + if ( BaseClass::DoUnholster() ) + { + m_bReadinessCapable = IsReadinessCapable(); + return true; + } + + return false; +} +#endif + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void CNPC_PlayerCompanion::PickupWeapon( CBaseCombatWeapon *pWeapon ) { BaseClass::PickupWeapon( pWeapon ); +#ifdef MAPBASE + SetPotentialSpeechTarget( pWeapon ); + SetSpeechTarget(pWeapon); + SpeakIfAllowed( TLK_NEWWEAPON ); + m_OnWeaponPickup.FireOutput( pWeapon, this ); +#else SpeakIfAllowed( TLK_NEWWEAPON ); m_OnWeaponPickup.FireOutput( this, this ); +#endif +} + +#if COMPANION_MELEE_ATTACK +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CNPC_PlayerCompanion::KeyValue( const char *szKeyName, const char *szValue ) +{ + // MeleeAttack01 restoration, see CNPC_PlayerCompanion::MeleeAttack1Conditions + if (FStrEq(szKeyName, "EnableMeleeAttack")) + { + if (!FStrEq(szValue, "0")) + CapabilitiesAdd( bits_CAP_INNATE_MELEE_ATTACK1 ); + else + CapabilitiesRemove( bits_CAP_INNATE_MELEE_ATTACK1 ); + + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: For unused citizen melee attack (vorts might use this too) +// Input : +// Output : +//----------------------------------------------------------------------------- +int CNPC_PlayerCompanion::MeleeAttack1Conditions ( float flDot, float flDist ) +{ + if (!GetActiveWeapon()) + return COND_NONE; + + if (IsMoving()) + { + // Is moving, cond_none + return COND_NONE; + } + + if (flDist > COMPANION_MELEE_DIST) + { + return COND_NONE; // COND_TOO_FAR_TO_ATTACK; + } + else if (flDot < 0.7) + { + return COND_NONE; // COND_NOT_FACING_ATTACK; + } + + if (GetEnemy()) + { + // Check Z + if ( fabs(GetEnemy()->GetAbsOrigin().z - GetAbsOrigin().z) > 64 ) + return COND_NONE; + + if ( GetEnemy()->MyCombatCharacterPointer() && GetEnemy()->MyCombatCharacterPointer()->GetHullType() == HULL_TINY ) + { + return COND_NONE; + } + } + + // Make sure not trying to kick through a window or something. + trace_t tr; + Vector vecSrc, vecEnd; + + vecSrc = WorldSpaceCenter(); + vecEnd = GetEnemy()->WorldSpaceCenter(); + + AI_TraceLine(vecSrc, vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr); + if( tr.m_pEnt != GetEnemy() ) + { + return COND_NONE; + } + + return COND_CAN_MELEE_ATTACK1; } +#endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -2880,11 +3402,19 @@ bool CNPC_PlayerCompanion::OverrideMove( float flInterval ) if ( !overrode && GetNavigator()->GetGoalType() != GOALTYPE_NONE ) { +#ifdef MAPBASE + #define iszEnvFire gm_isz_class_EnvFire +#else string_t iszEnvFire = AllocPooledString( "env_fire" ); +#endif string_t iszBounceBomb = AllocPooledString( "combine_mine" ); #ifdef HL2_EPISODIC +#ifdef MAPBASE + #define iszNPCTurretFloor gm_isz_class_FloorTurret +#else string_t iszNPCTurretFloor = AllocPooledString( "npc_turret_floor" ); +#endif string_t iszEntityFlame = AllocPooledString( "entityflame" ); #endif // HL2_EPISODIC @@ -2946,7 +3476,7 @@ bool CNPC_PlayerCompanion::OverrideMove( float flInterval ) else if ( pEntity->m_iClassname == iszBounceBomb ) { CBounceBomb *pBomb = static_cast(pEntity); - if ( pBomb && !pBomb->IsPlayerPlaced() && pBomb->IsAwake() ) + if ( pBomb && pBomb->ShouldBeAvoidedByCompanions() ) { UTIL_TraceLine( WorldSpaceCenter(), pEntity->WorldSpaceCenter(), MASK_BLOCKLOS, pEntity, COLLISION_GROUP_NONE, &tr ); if (tr.fraction == 1.0 && !tr.startsolid) @@ -3503,6 +4033,7 @@ void CNPC_PlayerCompanion::InputDisableWeaponPickup( inputdata_t &inputdata ) m_bDontPickupWeapons = true; } +#ifndef MAPBASE // See CAI_BaseNPC::InputGiveWeapon() //------------------------------------------------------------------------------ // Purpose: Give the NPC in question the weapon specified //------------------------------------------------------------------------------ @@ -3522,6 +4053,7 @@ void CNPC_PlayerCompanion::InputGiveWeapon( inputdata_t &inputdata ) } } } +#endif #if HL2_EPISODIC //------------------------------------------------------------------------------ @@ -3570,6 +4102,9 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak } CBaseEntity *pInflictor = info.GetInflictor(); +#ifdef MAPBASE + AI_CriteriaSet modifiers; +#else int iNumBarrels = 0; int iConsecutivePlayerKills = 0; bool bPuntedGrenade = false; @@ -3578,6 +4113,7 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak bool bVictimWasAttacker = false; bool bHeadshot = false; bool bOneShot = false; +#endif if ( dynamic_cast( pInflictor ) && ( info.GetDamageType() & DMG_BLAST ) ) { @@ -3590,7 +4126,11 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak m_iNumConsecutiveBarrelsExploded++; m_fLastBarrelExploded = gpGlobals->curtime; +#ifdef MAPBASE + modifiers.AppendCriteria( "num_barrels", UTIL_VarArgs("%i", m_iNumConsecutiveBarrelsExploded) ); +#else iNumBarrels = m_iNumConsecutiveBarrelsExploded; +#endif } else { @@ -3602,7 +4142,11 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak } m_iNumConsecutivePlayerKills++; m_fLastPlayerKill = gpGlobals->curtime; +#ifdef MAPBASE + modifiers.AppendCriteria( "consecutive_player_kills", UTIL_VarArgs("%i", m_iNumConsecutivePlayerKills) ); +#else iConsecutivePlayerKills = m_iNumConsecutivePlayerKills; +#endif } // don't comment on kills when she can't see the victim @@ -3612,29 +4156,53 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak } // check if the player killed an enemy by punting a grenade +#ifdef MAPBASE + modifiers.AppendCriteria( "punted_grenade", ( pInflictor && Fraggrenade_WasPunted( pInflictor ) && Fraggrenade_WasCreatedByCombine( pInflictor ) ) ? "1" : "0" ); +#else if ( pInflictor && Fraggrenade_WasPunted( pInflictor ) && Fraggrenade_WasCreatedByCombine( pInflictor ) ) { bPuntedGrenade = true; } +#endif // check if the victim was Alyx's enemy +#ifdef MAPBASE + modifiers.AppendCriteria( "victim_was_enemy", GetEnemy() == pVictim ? "1" : "0" ); +#else if ( GetEnemy() == pVictim ) { bVictimWasEnemy = true; } +#endif AI_EnemyInfo_t *pEMemory = GetEnemies()->Find( pVictim ); if ( pEMemory != NULL ) { // was Alyx being mobbed by this enemy? +#ifdef MAPBASE + modifiers.AppendCriteria( "victim_was_mob", pEMemory->bMobbedMe ? "1" : "0" ); + modifiers.AppendCriteria( "victim_was_attacker", pEMemory->timeLastReceivedDamageFrom > 0 ? "1" : "0" ); +#else bVictimWasMob = pEMemory->bMobbedMe; // has Alyx recieved damage from this enemy? if ( pEMemory->timeLastReceivedDamageFrom > 0 ) { bVictimWasAttacker = true; } +#endif } +#ifdef MAPBASE + else + { + modifiers.AppendCriteria( "victim_was_mob", "0" ); + modifiers.AppendCriteria( "victim_was_attacker", "0" ); + } +#endif +#ifdef MAPBASE + modifiers.AppendCriteria( "headshot", ((pCombatVictim->LastHitGroup() == HITGROUP_HEAD) && (info.GetDamageType() & DMG_BULLET)) ? "1" : "0" ); + modifiers.AppendCriteria( "oneshot", ((pCombatVictim->GetDamageCount() == 1) && (info.GetDamageType() & DMG_BULLET)) ? "1" : "0" ); +#else // Was it a headshot? if ( ( pCombatVictim->LastHitGroup() == HITGROUP_HEAD ) && ( info.GetDamageType() & DMG_BULLET ) ) { @@ -3646,18 +4214,171 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak { bOneShot = true; } +#endif +#ifdef MAPBASE + ModifyOrAppendEnemyCriteria(modifiers, pVictim); +#else // set up the speech modifiers CFmtStrN<512> modifiers( "num_barrels:%d,distancetoplayerenemy:%f,playerAmmo:%s,consecutive_player_kills:%d," "punted_grenade:%d,victim_was_enemy:%d,victim_was_mob:%d,victim_was_attacker:%d,headshot:%d,oneshot:%d", iNumBarrels, EnemyDistance( pVictim ), info.GetAmmoName(), iConsecutivePlayerKills, bPuntedGrenade, bVictimWasEnemy, bVictimWasMob, bVictimWasAttacker, bHeadshot, bOneShot ); +#endif SpeakIfAllowed( TLK_PLAYER_KILLED_NPC, modifiers ); BaseClass::OnPlayerKilledOther( pVictim, info ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CNPC_PlayerCompanion::Event_Killed( const CTakeDamageInfo &info ) +{ + // For now, allied player companions are set to always drop grenades and other items + // even if the player did not kill them + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if (!IsPlayerAlly( pPlayer )) + { + pPlayer = ToBasePlayer( info.GetAttacker() ); + + // See if there's a player in a vehicle instead (from CNPC_CombineS) + if ( !pPlayer ) + { + CPropVehicleDriveable *pVehicle = dynamic_cast( info.GetAttacker() ) ; + if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) + { + pPlayer = assert_cast( pVehicle->GetDriver() ); + } + } + } + + if ( pPlayer != NULL ) + { + // Drop grenades if we should + DropGrenadeItemsOnDeath( info, pPlayer ); + } + + BaseClass::Event_Killed( info ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_PlayerCompanion::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) +{ + BaseClass::Event_KilledOther( pVictim, info ); + + if ( pVictim ) + { + if (pVictim->IsPlayer() || (pVictim->IsNPC() && + ( pVictim->MyNPCPointer()->GetLastPlayerDamageTime() == 0 || + gpGlobals->curtime - pVictim->MyNPCPointer()->GetLastPlayerDamageTime() > 5 )) ) + { + AI_CriteriaSet modifiers; + + AI_EnemyInfo_t *pEMemory = GetEnemies()->Find( pVictim ); + if ( pEMemory != NULL ) + { + modifiers.AppendCriteria( "victim_was_mob", pEMemory->bMobbedMe ? "1" : "0" ); + modifiers.AppendCriteria( "victim_was_attacker", pEMemory->timeLastReceivedDamageFrom > 0 ? "1" : "0" ); + } + else + { + modifiers.AppendCriteria( "victim_was_mob", "0" ); + modifiers.AppendCriteria( "victim_was_attacker", "0" ); + } + + CBaseCombatCharacter *pCombatVictim = pVictim->MyCombatCharacterPointer(); + if (pCombatVictim) + { + modifiers.AppendCriteria( "headshot", ((pCombatVictim->LastHitGroup() == HITGROUP_HEAD) && (info.GetDamageType() & DMG_BULLET)) ? "1" : "0" ); + modifiers.AppendCriteria( "oneshot", ((pCombatVictim->GetDamageCount() == 1) && (info.GetDamageType() & DMG_BULLET)) ? "1" : "0" ); + } + else + { + modifiers.AppendCriteria( "headshot", "0" ); + modifiers.AppendCriteria( "oneshot", "0" ); + } + + SetPotentialSpeechTarget( pVictim ); + SetSpeechTarget( pVictim ); + SpeakIfAllowed( TLK_ENEMY_DEAD, modifiers ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Handles custom combat speech stuff ported from Alyx. +//----------------------------------------------------------------------------- +void CNPC_PlayerCompanion::DoCustomCombatAI( void ) +{ + #define COMPANION_MIN_MOB_DIST_SQR Square(120) // Any enemy closer than this adds to the 'mob' + #define COMPANION_MIN_CONSIDER_DIST Square(1200) // Only enemies within this range are counted and considered to generate AI speech + + AIEnemiesIter_t iter; + + float visibleEnemiesScore = 0.0f; + float closeEnemiesScore = 0.0f; + + for ( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) ) + { + if ( IRelationType( pEMemory->hEnemy ) != D_NU && IRelationType( pEMemory->hEnemy ) != D_LI && pEMemory->hEnemy->GetAbsOrigin().DistToSqr(GetAbsOrigin()) <= COMPANION_MIN_CONSIDER_DIST ) + { + if( pEMemory->hEnemy && pEMemory->hEnemy->IsAlive() && gpGlobals->curtime - pEMemory->timeLastSeen <= 0.5f && pEMemory->hEnemy->Classify() != CLASS_BULLSEYE ) + { + if( pEMemory->hEnemy->GetAbsOrigin().DistToSqr(GetAbsOrigin()) <= COMPANION_MIN_MOB_DIST_SQR ) + { + closeEnemiesScore += 1.0f; + } + else + { + visibleEnemiesScore += 1.0f; + } + } + } + } + + if( closeEnemiesScore > 2 ) + { + SetCondition( COND_MOBBED_BY_ENEMIES ); + + // mark anyone in the mob as having mobbed me + for ( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) ) + { + if ( pEMemory->bMobbedMe ) + continue; + + if ( IRelationType( pEMemory->hEnemy ) != D_NU && IRelationType( pEMemory->hEnemy ) != D_LI && pEMemory->hEnemy->GetAbsOrigin().DistToSqr(GetAbsOrigin()) <= COMPANION_MIN_CONSIDER_DIST ) + { + if( pEMemory->hEnemy && pEMemory->hEnemy->IsAlive() && gpGlobals->curtime - pEMemory->timeLastSeen <= 0.5f && pEMemory->hEnemy->Classify() != CLASS_BULLSEYE ) + { + if( pEMemory->hEnemy->GetAbsOrigin().DistToSqr(GetAbsOrigin()) <= COMPANION_MIN_MOB_DIST_SQR ) + { + pEMemory->bMobbedMe = true; + } + } + } + } + } + else + { + ClearCondition( COND_MOBBED_BY_ENEMIES ); + } + + // Say a combat thing + if( HasCondition( COND_MOBBED_BY_ENEMIES ) ) + { + SpeakIfAllowed( TLK_MOBBED ); + } + else if( visibleEnemiesScore > 4 ) + { + SpeakIfAllowed( TLK_MANY_ENEMIES ); + } +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool CNPC_PlayerCompanion::IsNavigationUrgent( void ) @@ -3712,10 +4433,20 @@ AI_BEGIN_CUSTOM_NPC( player_companion_base, CNPC_PlayerCompanion ) DECLARE_TASK( TASK_PC_WAITOUT_MORTAR ) DECLARE_TASK( TASK_PC_GET_PATH_OFF_COMPANION ) +#ifdef MAPBASE + DECLARE_TASK( TASK_PC_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET ) + DECLARE_TASK( TASK_PC_GET_PATH_TO_FORCED_GREN_LOS ) + DECLARE_TASK( TASK_PC_DEFER_SQUAD_GRENADES ) + DECLARE_TASK( TASK_PC_FACE_TOSS_DIR ) +#endif DECLARE_ANIMEVENT( AE_COMPANION_PRODUCE_FLARE ) DECLARE_ANIMEVENT( AE_COMPANION_LIGHT_FLARE ) DECLARE_ANIMEVENT( AE_COMPANION_RELEASE_FLARE ) +#ifdef MAPBASE + DECLARE_ANIMEVENT( COMBINE_AE_BEGIN_ALTFIRE ) + DECLARE_ANIMEVENT( COMBINE_AE_ALTFIRE ) +#endif //========================================================= // > TakeCoverFromBestSound @@ -3845,6 +4576,107 @@ AI_BEGIN_CUSTOM_NPC( player_companion_base, CNPC_PlayerCompanion ) "" ) +#ifdef COMPANION_MELEE_ATTACK + DEFINE_SCHEDULE + ( + SCHED_PC_MELEE_AND_MOVE_AWAY, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_FACE_ENEMY 0" + " TASK_ANNOUNCE_ATTACK 1" // 1 = primary attack + " TASK_MELEE_ATTACK1 0" + " TASK_SET_SCHEDULE SCHEDULE:SCHED_MOVE_AWAY_FROM_ENEMY" + "" + " Interrupts" + " COND_NEW_ENEMY" + " COND_ENEMY_DEAD" + //" COND_LIGHT_DAMAGE" + " COND_HEAVY_DAMAGE" + " COND_ENEMY_OCCLUDED" + ) +#endif + +#ifdef MAPBASE + //========================================================= + // AR2 Alt Fire Attack + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_PC_AR2_ALTFIRE, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_ANNOUNCE_ATTACK 1" + " TASK_PC_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET ACTIVITY:ACT_COMBINE_AR2_ALTFIRE" + "" + " Interrupts" + " COND_TOO_CLOSE_TO_ATTACK" + ) + + //========================================================= + // Move to LOS of the mapmaker's forced grenade throw target + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_PC_MOVE_TO_FORCED_GREN_LOS, + + " Tasks " + " TASK_SET_TOLERANCE_DISTANCE 48" + " TASK_PC_GET_PATH_TO_FORCED_GREN_LOS 0" + " TASK_SPEAK_SENTENCE 1" + " TASK_RUN_PATH 0" + " TASK_WAIT_FOR_MOVEMENT 0" + " " + " Interrupts " + " COND_NEW_ENEMY" + " COND_ENEMY_DEAD" + " COND_CAN_MELEE_ATTACK1" + " COND_CAN_MELEE_ATTACK2" + " COND_HEAR_DANGER" + " COND_HEAR_MOVE_AWAY" + " COND_HEAVY_DAMAGE" + ) + + //========================================================= + // Mapmaker forced grenade throw + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_PC_FORCED_GRENADE_THROW, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_PC_FACE_TOSS_DIR 0" + " TASK_ANNOUNCE_ATTACK 2" // 2 = grenade + " TASK_PLAY_SEQUENCE ACTIVITY:ACT_RANGE_ATTACK2" + " TASK_PC_DEFER_SQUAD_GRENADES 0" + "" + " Interrupts" + ) + + //========================================================= + // SCHED_PC_RANGE_ATTACK2 + // + // secondary range attack. Overriden because base class stops attacking when the enemy is occluded. + // combines's grenade toss requires the enemy be occluded. + //========================================================= + DEFINE_SCHEDULE + ( + SCHED_PC_RANGE_ATTACK2, + + " Tasks" + " TASK_STOP_MOVING 0" + " TASK_PC_FACE_TOSS_DIR 0" + " TASK_ANNOUNCE_ATTACK 2" // 2 = grenade + " TASK_PLAY_SEQUENCE ACTIVITY:ACT_RANGE_ATTACK2" + " TASK_PC_DEFER_SQUAD_GRENADES 0" + " TASK_SET_SCHEDULE SCHEDULE:SCHED_HIDE_AND_RELOAD" // don't run immediately after throwing grenade. + "" + " Interrupts" + ) +#endif + AI_END_CUSTOM_NPC() diff --git a/game/server/hl2/npc_playercompanion.h b/game/server/hl2/npc_playercompanion.h index f1c3b1f3..8dcf1aa1 100644 --- a/game/server/hl2/npc_playercompanion.h +++ b/game/server/hl2/npc_playercompanion.h @@ -22,6 +22,11 @@ #include "ai_behavior_passenger_companion.h" #endif +#ifdef MAPBASE +#include "ai_behavior_functank.h" +#include "mapbase/ai_grenade.h" +#endif + #if defined( _WIN32 ) #pragma once #endif @@ -85,17 +90,29 @@ class CCompanionActivityRemap : public CActivityRemap class CPhysicsProp; +#ifdef MAPBASE +// If you think about it, this is really unnecessary. +//#define COMPANION_MELEE_ATTACK 1 +#endif + //----------------------------------------------------------------------------- // // CLASS: CNPC_PlayerCompanion // //----------------------------------------------------------------------------- - +#ifdef MAPBASE +class CNPC_PlayerCompanion : public CAI_GrenadeUser +{ + DECLARE_CLASS( CNPC_PlayerCompanion, CAI_GrenadeUser ); +#else class CNPC_PlayerCompanion : public CAI_PlayerAlly { DECLARE_CLASS( CNPC_PlayerCompanion, CAI_PlayerAlly ); - +#endif public: + + CNPC_PlayerCompanion(); + //--------------------------------- bool CreateBehaviors(); void Precache(); @@ -189,7 +206,9 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly virtual void ReadinessLevelChanged( int iPriorLevel ) { } +#ifndef MAPBASE void InputGiveWeapon( inputdata_t &inputdata ); +#endif #ifdef HL2_EPISODIC //--------------------------------- @@ -217,6 +236,14 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly public: virtual void OnPlayerKilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ); +#ifdef MAPBASE + // This is just here to overwrite ai_playerally's TLK_ENEMY_DEAD + virtual void OnKilledNPC(CBaseCombatCharacter *pKilled) {} + + virtual void Event_Killed( const CTakeDamageInfo &info ); + virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ); + virtual void DoCustomCombatAI( void ); +#endif //--------------------------------- //--------------------------------- @@ -255,7 +282,15 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly bool ShouldLookForBetterWeapon(); bool Weapon_CanUse( CBaseCombatWeapon *pWeapon ); void Weapon_Equip( CBaseCombatWeapon *pWeapon ); +#ifdef MAPBASE + bool DoUnholster( void ); +#endif void PickupWeapon( CBaseCombatWeapon *pWeapon ); + +#if COMPANION_MELEE_ATTACK + bool KeyValue( const char *szKeyName, const char *szValue ); + int MeleeAttack1Conditions( float flDot, float flDist ); +#endif bool FindCoverPos( CBaseEntity *pEntity, Vector *pResult); bool FindCoverPosInRadius( CBaseEntity *pEntity, const Vector &goalPos, float coverRadius, Vector *pResult ); @@ -308,6 +343,21 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly bool AllowReadinessValueChange( void ); +#ifdef MAPBASE + virtual bool IsAltFireCapable() { return (m_iGrenadeCapabilities & GRENCAP_ALTFIRE) != 0 && BaseClass::IsAltFireCapable(); } + virtual bool IsGrenadeCapable() { return (m_iGrenadeCapabilities & GRENCAP_GRENADE) != 0; } + + virtual bool ShouldDropGrenades() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_GRENADE) != 0 && BaseClass::ShouldDropGrenades(); } + virtual bool ShouldDropInterruptedGrenades() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_INTERRUPTED) != 0 && BaseClass::ShouldDropInterruptedGrenades(); } + virtual bool ShouldDropAltFire() { return (m_iGrenadeDropCapabilities & GRENDROPCAP_ALTFIRE) != 0 && BaseClass::ShouldDropAltFire(); } + +private: + + // Determines whether this NPC is allowed to use grenades or alt-fire stuff. + eGrenadeCapabilities m_iGrenadeCapabilities; + eGrenadeDropCapabilities m_iGrenadeDropCapabilities; +#endif + protected: //----------------------------------------------------- // Conditions, Schedules, Tasks @@ -326,10 +376,25 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly SCHED_PC_FAIL_TAKE_COVER_TURRET, SCHED_PC_FAKEOUT_MORTAR, SCHED_PC_GET_OFF_COMPANION, +#ifdef COMPANION_MELEE_ATTACK + SCHED_PC_MELEE_AND_MOVE_AWAY, +#endif +#ifdef MAPBASE + SCHED_PC_AR2_ALTFIRE, + SCHED_PC_MOVE_TO_FORCED_GREN_LOS, + SCHED_PC_FORCED_GRENADE_THROW, + SCHED_PC_RANGE_ATTACK2, // Grenade throw +#endif NEXT_SCHEDULE, TASK_PC_WAITOUT_MORTAR = BaseClass::NEXT_TASK, TASK_PC_GET_PATH_OFF_COMPANION, +#ifdef MAPBASE + TASK_PC_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET, + TASK_PC_GET_PATH_TO_FORCED_GREN_LOS, + TASK_PC_DEFER_SQUAD_GRENADES, + TASK_PC_FACE_TOSS_DIR, +#endif NEXT_TASK, }; @@ -371,6 +436,9 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly CAI_OperatorBehavior m_OperatorBehavior; CAI_PassengerBehaviorCompanion m_PassengerBehavior; CAI_FearBehavior m_FearBehavior; +#endif +#ifdef MAPBASE + CAI_FuncTankBehavior m_FuncTankBehavior; #endif //----------------------------------------------------- @@ -406,11 +474,25 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly //----------------------------------------------------- +#ifdef MAPBASE + static string_t gm_iszMortarClassname; + #define gm_iszFloorTurretClassname gm_isz_class_FloorTurret + static string_t gm_iszGroundTurretClassname; + #define gm_iszShotgunClassname gm_isz_class_Shotgun + #define gm_iszRollerMineClassname gm_isz_class_Rollermine + #define gm_iszSMG1Classname gm_isz_class_SMG1 + #define gm_iszAR2Classname gm_isz_class_AR2 +#else static string_t gm_iszMortarClassname; static string_t gm_iszFloorTurretClassname; static string_t gm_iszGroundTurretClassname; static string_t gm_iszShotgunClassname; static string_t gm_iszRollerMineClassname; +#ifdef MAPBASE + static string_t gm_iszSMG1Classname; + static string_t gm_iszAR2Classname; +#endif +#endif //----------------------------------------------------- @@ -424,6 +506,10 @@ class CNPC_PlayerCompanion : public CAI_PlayerAlly COutputEvent m_OnWeaponPickup; +#if COMPANION_MELEE_ATTACK + int m_nMeleeDamage; +#endif + CStopwatch m_SpeechWatch_PlayerLooking; DECLARE_DATADESC(); diff --git a/game/server/hl2/npc_rollermine.cpp b/game/server/hl2/npc_rollermine.cpp index 9ac5a745..ddbfd934 100644 --- a/game/server/hl2/npc_rollermine.cpp +++ b/game/server/hl2/npc_rollermine.cpp @@ -263,10 +263,6 @@ class CNPC_RollerMine : public CNPCBaseInteractive, public CDefault virtual void OnStateChange( NPC_STATE OldState, NPC_STATE NewState ); -#ifdef VANCE - bool IsHackable() { return true; } -#endif - // Vehicle interception bool EnemyInVehicle( void ); float VehicleHeading( CBaseEntity *pVehicle ); @@ -293,6 +289,11 @@ class CNPC_RollerMine : public CNPCBaseInteractive, public CDefault void SetRollerSkin( void ); +#ifdef VANCE + bool IsHackable() const override { return true; } + void Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) override; +#endif + COutputEvent m_OnPhysGunDrop; COutputEvent m_OnPhysGunPickup; @@ -314,6 +315,16 @@ class CNPC_RollerMine : public CNPCBaseInteractive, public CDefault bool IsActive() { return m_flActiveTime > gpGlobals->curtime ? false : true; } + inline float GetForwardSpeed() const + { +#ifdef MAPBASE + if (m_flSpeedModifier != 1.0f) + return m_flForwardSpeed * m_flSpeedModifier; + else +#endif + return m_flForwardSpeed; + } + // INPCInteractive Functions virtual bool CanInteractWith( CAI_BaseNPC *pUser ) { return true; } virtual bool HasBeenInteractedWith() { return m_bHackedByAlyx; } @@ -392,7 +403,11 @@ BEGIN_DATADESC( CNPC_RollerMine ) DEFINE_FIELD( m_bBuried, FIELD_BOOLEAN ), DEFINE_FIELD( m_wakeUp, FIELD_BOOLEAN ), DEFINE_FIELD( m_bEmbedOnGroundImpact, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bHackedByAlyx, FIELD_BOOLEAN, "Hacked" ), +#else DEFINE_FIELD( m_bHackedByAlyx, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_bPowerDown, FIELD_BOOLEAN ), DEFINE_FIELD( m_flPowerDownTime, FIELD_TIME ), @@ -488,6 +503,14 @@ CNPC_RollerMine::~CNPC_RollerMine( void ) UnstickFromVehicle(); } +#ifdef VANCE +void CNPC_RollerMine::Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + m_bHackedByAlyx = true; + BaseClass::Hack( pActivator, pCaller ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : @@ -547,6 +570,9 @@ void CNPC_RollerMine::Spawn( void ) BaseClass::Spawn(); AddEFlags( EFL_NO_DISSOLVE ); +#ifdef MAPBASE + AddEFlags( EFL_NO_MEGAPHYSCANNON_RAGDOLL ); +#endif CapabilitiesClear(); CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_SQUAD ); @@ -1310,7 +1336,7 @@ void CNPC_RollerMine::RunTask( const Task_t *pTask ) Vector vecRight; AngleVectors( QAngle( 0, yaw, 0 ), NULL, &vecRight, NULL ); - m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, -m_flForwardSpeed * 5 ); + m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, -GetForwardSpeed() * 5 ); TaskComplete(); return; @@ -1320,6 +1346,8 @@ void CNPC_RollerMine::RunTask( const Task_t *pTask ) } { + float flForwardSpeed = GetForwardSpeed(); + float yaw = UTIL_VecToYaw( GetNavigator()->GetCurWaypointPos() - GetLocalOrigin() ); Vector vecRight; @@ -1359,17 +1387,17 @@ void CNPC_RollerMine::RunTask( const Task_t *pTask ) vecCompensate.y = -vecVelocity.x; vecCompensate.z = 0; - m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, m_flForwardSpeed * -0.75 ); + m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, flForwardSpeed * -0.75 ); } if( m_bHackedByAlyx ) { // Move faster. - m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed * 2.0f ); + m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, flForwardSpeed * 2.0f ); } else { - m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed ); + m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, flForwardSpeed ); } } break; @@ -1493,8 +1521,10 @@ void CNPC_RollerMine::RunTask( const Task_t *pTask ) vecCompensate.z = 0; VectorNormalize( vecCompensate ); - m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, m_flForwardSpeed * -0.75 ); - m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed * flTorqueFactor ); + float flForwardSpeed = GetForwardSpeed(); + + m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, flForwardSpeed * -0.75 ); + m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, flForwardSpeed * flTorqueFactor ); // Taunt when I get closer if( !(m_iSoundEventFlags & ROLLERMINE_SE_TAUNT) && UTIL_DistApprox( GetLocalOrigin(), vecTargetPosition ) <= 400 ) @@ -1612,8 +1642,10 @@ void CNPC_RollerMine::RunTask( const Task_t *pTask ) vecCompensate.z = 0; VectorNormalize( vecCompensate ); - m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, m_flForwardSpeed * -0.75 ); - m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed * flTorqueFactor ); + float flForwardSpeed = GetForwardSpeed(); + + m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, flForwardSpeed * -0.75 ); + m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, flForwardSpeed * flTorqueFactor ); // Once we're near the player, slow & stop if ( GetAbsOrigin().DistToSqr( vecTargetPosition ) < (ROLLERMINE_RETURN_TO_PLAYER_DIST*2.0) ) @@ -1961,6 +1993,10 @@ void CNPC_RollerMine::NotifyInteraction( CAI_BaseNPC *pUser ) // Force the rollermine open here. At very least, this ensures that the // correct, smaller bounding box is recomputed around it. Open(); + +#ifdef MAPBASE + m_OnHacked.FireOutput(pUser, this); +#endif } //----------------------------------------------------------------------------- @@ -2565,6 +2601,12 @@ float CNPC_RollerMine::RollingSpeed() float rollingSpeed = angVel.Length() - 90; rollingSpeed = clamp( rollingSpeed, 1, MAX_ROLLING_SPEED ); rollingSpeed *= (1/MAX_ROLLING_SPEED); +#ifdef MAPBASE + if (m_flSpeedModifier != 1.0f) + { + rollingSpeed *= m_flSpeedModifier; + } +#endif return rollingSpeed; } return 0; diff --git a/game/server/hl2/npc_scanner.cpp b/game/server/hl2/npc_scanner.cpp index 86cfcad2..0323afcc 100644 --- a/game/server/hl2/npc_scanner.cpp +++ b/game/server/hl2/npc_scanner.cpp @@ -179,6 +179,11 @@ BEGIN_DATADESC( CNPC_CScanner ) DEFINE_INPUTFUNC( FIELD_STRING, "DeployMine", InputDeployMine ), DEFINE_INPUTFUNC( FIELD_STRING, "EquipMine", InputEquipMine ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DisablePhotos", InputDisablePhotos ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnablePhotos", InputEnablePhotos ), +#endif + DEFINE_OUTPUT( m_OnPhotographPlayer, "OnPhotographPlayer" ), DEFINE_OUTPUT( m_OnPhotographNPC, "OnPhotographNPC" ), @@ -217,6 +222,10 @@ CNPC_CScanner::CNPC_CScanner() { m_bIsClawScanner = false; } + +#ifdef MAPBASE + CapabilitiesAdd( bits_CAP_INNATE_MELEE_ATTACK1 ); +#endif } //----------------------------------------------------------------------------- @@ -247,11 +256,11 @@ void CNPC_CScanner::Spawn(void) if( m_bIsClawScanner ) { - SetModel( "models/shield_scanner.mdl"); + SetModel( DefaultOrCustomModel( "models/shield_scanner.mdl" ) ); } else { - SetModel( "models/combine_scanner.mdl"); + SetModel( DefaultOrCustomModel( "models/combine_scanner.mdl" ) ); } m_iHealth = sk_scanner_health.GetFloat(); @@ -289,7 +298,9 @@ void CNPC_CScanner::Spawn(void) // -------------------------------------------- +#ifndef MAPBASE // Moved to constructor so keyvalue works CapabilitiesAdd( bits_CAP_INNATE_MELEE_ATTACK1 ); +#endif m_bPhotoTaken = false; @@ -319,6 +330,27 @@ void CNPC_CScanner::Activate() m_pEyeFlash->SetScale( 1.4 ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CNPC_CScanner::KeyValue( const char *szKeyName, const char *szValue ) +{ + // Any "Counter" outputs are changed to "OutCounter" before spawning. + if (FStrEq(szKeyName, "DisablePhotos") && FStrEq(szValue, "1")) + { + CapabilitiesRemove(bits_CAP_INNATE_MELEE_ATTACK1); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif + //------------------------------------------------------------------------------ // Purpose: Override to split in two when attacked //------------------------------------------------------------------------------ @@ -533,7 +565,7 @@ void CNPC_CScanner::Precache(void) // Model if( m_bIsClawScanner ) { - PrecacheModel("models/shield_scanner.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/shield_scanner.mdl" ) ); PrecacheModel("models/gibs/Shield_Scanner_Gib1.mdl"); PrecacheModel("models/gibs/Shield_Scanner_Gib2.mdl"); @@ -559,7 +591,7 @@ void CNPC_CScanner::Precache(void) } else { - PrecacheModel("models/combine_scanner.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/combine_scanner.mdl" ) ); PrecacheModel("models/gibs/scanner_gib01.mdl" ); PrecacheModel("models/gibs/scanner_gib02.mdl" ); @@ -958,7 +990,12 @@ void CNPC_CScanner::DeployMine() //----------------------------------------------------------------------------- float CNPC_CScanner::GetMaxSpeed() { +#ifdef MAPBASE + // Don't stomp custom max speed in base class + if( IsStriderScout() && m_flCustomMaxSpeed <= 0.0f ) +#else if( IsStriderScout() ) +#endif { return SCANNER_SCOUT_MAX_SPEED; } @@ -1034,6 +1071,24 @@ void CNPC_CScanner::InputEquipMine(inputdata_t &inputdata) pEnt->Spawn(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_CScanner::InputDisablePhotos( inputdata_t &inputdata ) +{ + CapabilitiesRemove(bits_CAP_INNATE_MELEE_ATTACK1); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_CScanner::InputEnablePhotos( inputdata_t &inputdata ) +{ + CapabilitiesAdd(bits_CAP_INNATE_MELEE_ATTACK1); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Tells the scanner to go photograph an entity. @@ -1450,6 +1505,10 @@ int CNPC_CScanner::SelectSchedule(void) return SCHED_CSCANNER_SPOTLIGHT_HOVER; // Melee attack if possible +#ifdef MAPBASE + if ( CapabilitiesGet() & bits_CAP_INNATE_MELEE_ATTACK1 ) + { +#endif if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) ) { if ( random->RandomInt(0,1) ) @@ -1458,6 +1517,13 @@ int CNPC_CScanner::SelectSchedule(void) // TODO: a schedule where he makes an alarm sound? return SCHED_SCANNER_CHASE_ENEMY; } +#ifdef MAPBASE + } + else + { + return SCHED_CSCANNER_SPOTLIGHT_HOVER; + } +#endif // If I'm far from the enemy, stay up high and approach in spotlight mode float fAttack2DDist = ( GetEnemyLKP() - GetAbsOrigin() ).Length2D(); @@ -1866,6 +1932,15 @@ void CNPC_CScanner::UpdateOnRemove( void ) //------------------------------------------------------------------------------ void CNPC_CScanner::TakePhoto(void) { +#ifdef MAPBASE + // Only take photos if we're allowed + if (!(CapabilitiesGet() & bits_CAP_INNATE_MELEE_ATTACK1)) + { + m_bPhotoTaken = true; + return; + } +#endif + ScannerEmitSound( "TakePhoto" ); m_pEyeFlash->SetScale( 1.4 ); @@ -1988,7 +2063,7 @@ void CNPC_CScanner::BlindFlashTarget( CBaseEntity *pTarget ) if ( tr.startsolid == false && tr.fraction == 1.0) { - color32 white = { 255, 255, 255, (byte)(SCANNER_FLASH_MAX_VALUE * dotPr) }; + color32 white = { 255, 255, 255, SCANNER_FLASH_MAX_VALUE * dotPr }; if ( ( g_pMaterialSystemHardwareConfig != NULL ) && ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) ) { @@ -2492,6 +2567,14 @@ void CNPC_CScanner::MoveToTarget( float flInterval, const Vector &vecMoveTarget myZAccel = flDist / flInterval; } +#ifdef MAPBASE + if (m_flSpeedModifier != 1.0f) + { + myAccel *= m_flSpeedModifier; + //myZAccel *= m_flSpeedModifier; + } +#endif + MoveInDirection( flInterval, targetDir, myAccel, myZAccel, myDecay ); // calc relative banking targets diff --git a/game/server/hl2/npc_scanner.h b/game/server/hl2/npc_scanner.h index f34eba35..109b2a7d 100644 --- a/game/server/hl2/npc_scanner.h +++ b/game/server/hl2/npc_scanner.h @@ -51,6 +51,9 @@ class CNPC_CScanner : public CNPC_BaseScanner virtual char *GetScannerSoundPrefix( void ); void Spawn(void); void Activate(); +#ifdef MAPBASE + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif void StartTask( const Task_t *pTask ); void UpdateOnRemove( void ); void DeployMine(); @@ -67,6 +70,10 @@ class CNPC_CScanner : public CNPC_BaseScanner void InputInspectTargetSpotlight( inputdata_t &inputdata ); void InputDeployMine( inputdata_t &inputdata ); void InputEquipMine( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDisablePhotos( inputdata_t &inputdata ); + void InputEnablePhotos( inputdata_t &inputdata ); +#endif void InputShouldInspect( inputdata_t &inputdata ); void InspectTarget( inputdata_t &inputdata, ScannerFlyMode_t eFlyMode ); diff --git a/game/server/hl2/npc_stalker.cpp b/game/server/hl2/npc_stalker.cpp index 204d7a55..67ed567a 100644 --- a/game/server/hl2/npc_stalker.cpp +++ b/game/server/hl2/npc_stalker.cpp @@ -126,7 +126,14 @@ BEGIN_DATADESC( CNPC_Stalker ) DEFINE_FIELD( m_flNextBreatheSoundTime, FIELD_TIME ), DEFINE_FIELD( m_flNextScrambleSoundTime, FIELD_TIME ), DEFINE_FIELD( m_nextSmokeTime, FIELD_TIME ), +#ifdef MAPBASE + // Funnily enough, we can very easily treat this as a boolean value in Hammer + // since "0" means don't attack and "1" means attack. There is no unique behavior beyond 1. + DEFINE_KEYFIELD( m_iPlayerAggression, FIELD_INTEGER, "Aggression" ), + DEFINE_KEYFIELD( m_bBleed, FIELD_BOOLEAN, "Bleed" ), +#else DEFINE_FIELD( m_iPlayerAggression, FIELD_INTEGER ), +#endif DEFINE_FIELD( m_flNextScreamTime, FIELD_TIME ), // Function Pointers @@ -271,7 +278,7 @@ void CNPC_Stalker::Spawn( void ) { Precache( ); - SetModel( "models/stalker.mdl" ); + SetModel( DefaultOrCustomModel( "models/stalker.mdl" ) ); SetHullType(HULL_HUMAN); SetHullSizeNormal(); @@ -300,7 +307,9 @@ void CNPC_Stalker::Spawn( void ) m_flDistTooFar = MAX_STALKER_FIRE_RANGE; +#ifndef MAPBASE m_iPlayerAggression = 0; +#endif GetSenses()->SetDistLook(MAX_STALKER_FIRE_RANGE - 1); } @@ -312,7 +321,7 @@ void CNPC_Stalker::Spawn( void ) //----------------------------------------------------------------------------- void CNPC_Stalker::Precache( void ) { - PrecacheModel("models/stalker.mdl"); + PrecacheModel( DefaultOrCustomModel( "models/stalker.mdl" ) ); PrecacheModel("sprites/laser.vmt"); PrecacheModel("sprites/redglow1.vmt"); @@ -329,6 +338,11 @@ void CNPC_Stalker::Precache( void ) PrecacheScriptSound( "NPC_Stalker.Pain" ); PrecacheScriptSound( "NPC_Stalker.Die" ); +#ifdef MAPBASE + if (m_bBleed) + PrecacheParticleSystem( "blood_impact_synth_01" ); +#endif + BaseClass::Precache(); } @@ -389,6 +403,33 @@ void CNPC_Stalker::Event_Killed( const CTakeDamageInfo &info ) BaseClass::Event_Killed( info ); } +#ifdef MAPBASE +extern void DispatchParticleEffect( const char *pszParticleName, Vector vecOrigin, QAngle vecAngles, CBaseEntity *pEntity = NULL ); + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CNPC_Stalker::TraceAttack( const CTakeDamageInfo &inputInfo, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ) +{ + // Is it insane to desire for stalkers to bleed? No. + // Is it insane to port the hunter's blood particle system because + // it fits with the fact stalkers probably don't run on regular blood anymore? Maybe. + if (m_bBleed) + { + if ( ( inputInfo.GetDamageType() & DMG_BULLET ) || + ( inputInfo.GetDamageType() & DMG_BUCKSHOT ) || + ( inputInfo.GetDamageType() & DMG_CLUB ) || + ( inputInfo.GetDamageType() & DMG_NEVERGIB ) ) + { + QAngle vecAngles; + VectorAngles( ptr->plane.normal, vecAngles ); + DispatchParticleEffect( "blood_impact_synth_01", ptr->endpos, vecAngles ); + } + } + + BaseClass::TraceAttack( inputInfo, vecDir, ptr, pAccumulator ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : @@ -1106,6 +1147,30 @@ void CNPC_Stalker::DrawAttackBeam(void) */ } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Fixes stalker beam cleanup not working correctly +//------------------------------------------------------------------------------ +void CNPC_Stalker::UpdateOnRemove( void ) +{ + if (m_pBeam) + { + StopSound(m_pBeam->entindex(), "NPC_Stalker.BurnWall" ); + StopSound(m_pBeam->entindex(), "NPC_Stalker.BurnFlesh" ); + + UTIL_Remove( m_pLightGlow ); + UTIL_Remove( m_pBeam); + m_pBeam = NULL; + m_bPlayingHitWall = false; + m_bPlayingHitFlesh = false; + + SetThink(NULL); + } + + BaseClass::UpdateOnRemove(); +} +#endif + //------------------------------------------------------------------------------ // Purpose : Draw attack beam and do damage / decals // Input : @@ -1168,7 +1233,11 @@ bool CNPC_Stalker::InnateWeaponLOSCondition( const Vector &ownerPos, const Vecto } else if (pBCC) { +#ifdef MAPBASE + if (IRelationType( pBCC ) <= D_FR) +#else if (IRelationType( pBCC ) == D_HT) +#endif { return true; } diff --git a/game/server/hl2/npc_stalker.h b/game/server/hl2/npc_stalker.h index dc2c08e5..206d199d 100644 --- a/game/server/hl2/npc_stalker.h +++ b/game/server/hl2/npc_stalker.h @@ -46,9 +46,19 @@ class CNPC_Stalker : public CAI_BaseStalker float m_bPlayingHitFlesh; CBeam* m_pBeam; CSprite* m_pLightGlow; +#ifdef MAPBASE + // This is a keyvalue now, so we have to initialize the value through somewhere that isn't Spawn() + int m_iPlayerAggression = 0; + bool m_bBleed; +#else int m_iPlayerAggression; +#endif float m_flNextScreamTime; +#ifdef MAPBASE + void UpdateOnRemove( void ); +#endif + void KillAttackBeam(void); void DrawAttackBeam(void); void CalcBeamPosition(void); @@ -97,6 +107,9 @@ class CNPC_Stalker : public CAI_BaseStalker void PainSound( const CTakeDamageInfo &info ); void Event_Killed( const CTakeDamageInfo &info ); +#ifdef MAPBASE + void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); +#endif void DoSmokeEffect( const Vector &position ); void AddZigZagToPath(void); diff --git a/game/server/hl2/npc_strider.cpp b/game/server/hl2/npc_strider.cpp index 60d37cdf..a4289fdb 100644 --- a/game/server/hl2/npc_strider.cpp +++ b/game/server/hl2/npc_strider.cpp @@ -54,6 +54,10 @@ #include "filters.h" #include "saverestore_utlvector.h" #include "eventqueue.h" +#ifdef MAPBASE +#include "npc_basescanner.h" +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -328,6 +332,11 @@ BEGIN_DATADESC( CNPC_Strider ) DEFINE_FIELD( m_hCannonTarget, FIELD_EHANDLE ), DEFINE_EMBEDDED( m_AttemptCannonLOSTimer ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_strStompFilter, FIELD_STRING, "stompfilter" ), + DEFINE_FIELD( m_hStompFilter, FIELD_EHANDLE ), +#endif + DEFINE_FIELD( m_flSpeedScale, FIELD_FLOAT ), DEFINE_FIELD( m_flTargetSpeedScale, FIELD_FLOAT ), @@ -386,12 +395,19 @@ BEGIN_DATADESC( CNPC_Strider ) DEFINE_INPUTFUNC( FIELD_VOID, "EnableMinigun", InputEnableMinigun ), DEFINE_INPUTFUNC( FIELD_FLOAT, "StopShootingMinigunForSeconds", InputStopShootingMinigunForSeconds ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableCrouch", InputDisableCrouch ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "EnableCrouch", InputEnableCrouch ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "DisableMoveToLOS", InputDisableMoveToLOS ), DEFINE_INPUTFUNC( FIELD_STRING, "DisableCollisionWith", InputDisableCollisionWith ), DEFINE_INPUTFUNC( FIELD_STRING, "EnableCollisionWith", InputEnableCollisionWith ), DEFINE_INPUTFUNC( FIELD_VOID, "Explode", InputExplode ), DEFINE_INPUTFUNC( FIELD_FLOAT, "ScaleGroundSpeed", InputScaleGroundSpeed ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetStompFilter", InputSetStompFilter ), +#endif + // Function Pointers // DEFINE_FUNCTION( JumpTouch ), DEFINE_THINKFUNC( CarriedThink ), @@ -429,6 +445,11 @@ CNPC_Strider::CNPC_Strider() //--------------------------------------------------------- CNPC_Strider::~CNPC_Strider() { +#ifdef MAPBASE + if (m_hFocus) + UTIL_Remove( m_hFocus ); +#endif + delete m_pMinigun; } @@ -1105,7 +1126,11 @@ void CNPC_Strider::GatherConditions() // Don't switch targets if shooting at a bullseye! Level designers depend on bullseyes. if( GetEnemy() && m_pMinigun->IsShooting() && GetTimeEnemyAcquired() != gpGlobals->curtime ) { +#ifdef MAPBASE + if( m_pMinigun->IsOnTarget( 3 ) && !EntIsClass( GetEnemy(), gm_isz_class_Bullseye ) ) +#else if( m_pMinigun->IsOnTarget( 3 ) && !FClassnameIs( GetEnemy(), "npc_bullseye" ) ) +#endif { if( m_iVisibleEnemies > 1 ) { @@ -1993,7 +2018,11 @@ Disposition_t CNPC_Strider::IRelationType( CBaseEntity *pTarget ) //--------------------------------------------------------- void CNPC_Strider::AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ) { +#ifdef MAPBASE + if ( nDisposition == D_HT && EntIsClass(pEntity, gm_isz_class_Bullseye) ) +#else if ( nDisposition == D_HT && pEntity->ClassMatches("npc_bullseye") ) +#endif UpdateEnemyMemory( pEntity, pEntity->GetAbsOrigin() ); BaseClass::AddEntityRelationship( pEntity, nDisposition, nPriority ); } @@ -2336,6 +2365,15 @@ void CNPC_Strider::InputDisableCrouch( inputdata_t &inputdata ) m_bDontCrouch = true; } +#ifdef MAPBASE +//--------------------------------------------------------- +//--------------------------------------------------------- +void CNPC_Strider::InputEnableCrouch( inputdata_t &inputdata ) +{ + m_bDontCrouch = false; +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Strider::InputDisableMoveToLOS( inputdata_t &inputdata ) @@ -2361,6 +2399,16 @@ void CNPC_Strider::InputScaleGroundSpeed( inputdata_t &inputdata ) m_flTargetSpeedScale = inputdata.value.Float(); } +#ifdef MAPBASE +//--------------------------------------------------------- +//--------------------------------------------------------- +void CNPC_Strider::InputSetStompFilter( inputdata_t &inputdata ) +{ + m_strStompFilter = inputdata.value.StringID(); + m_hStompFilter = NULL; +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- bool CNPC_Strider::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity **ppBlocker ) @@ -2426,7 +2474,11 @@ bool CNPC_Strider::IsValidEnemy( CBaseEntity *pTarget ) //--------------------------------------------------------- bool CNPC_Strider::UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position, CBaseEntity *pInformer ) { +#ifdef MAPBASE + if (dynamic_cast(pInformer)) +#else if( pInformer && FClassnameIs( pInformer, "npc_cscanner" ) ) +#endif { EmitSound( "NPC_Strider.Alert" ); // Move Strider's focus to this location and make strider mad at it @@ -2557,6 +2609,14 @@ int CNPC_Strider::MeleeAttack1Conditions( float flDot, float flDist ) return COND_NONE; } +#ifdef MAPBASE + if (GetStompFilter()) + { + if (!GetStompFilter()->PassesFilter(this, pEnemy)) + return COND_NONE; + } +#endif + // recompute this because the base class function does not work for the strider flDist = StriderEnemyDistance( pEnemy ); @@ -4378,6 +4438,35 @@ void CNPC_Strider::StompHit( int followerBoneIndex ) } } +#ifdef MAPBASE +//--------------------------------------------------------- +//--------------------------------------------------------- +CBaseFilter *CNPC_Strider::GetStompFilter() +{ + if (m_hStompFilter) + return m_hStompFilter; + + if (m_strStompFilter != NULL_STRING) + { + CBaseEntity *pEntity = gEntList.FindEntityByName(NULL, m_strStompFilter); + if (pEntity) + { + m_hStompFilter = dynamic_cast(pEntity); + if (m_hStompFilter) + return m_hStompFilter; + else + Warning("%s stomp filter %s not a filter!", GetDebugName(), STRING(m_strStompFilter)); + } + else + { + Warning("%s stomp filter %s not found!", GetDebugName(), STRING(m_strStompFilter)); + } + } + + return NULL; +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Strider::FootFX( const Vector &origin ) diff --git a/game/server/hl2/npc_strider.h b/game/server/hl2/npc_strider.h index dd645781..d5bdd209 100644 --- a/game/server/hl2/npc_strider.h +++ b/game/server/hl2/npc_strider.h @@ -14,6 +14,9 @@ #include "smoke_trail.h" #include "physics_bone_follower.h" #include "physics_prop_ragdoll.h" +#ifdef MAPBASE +#include "filters.h" +#endif #if defined( _WIN32 ) #pragma once @@ -168,10 +171,17 @@ class CNPC_Strider : public CAI_BlendingHost, void InputDisableAggressiveBehavior( inputdata_t &inputdata ); void InputStopShootingMinigunForSeconds( inputdata_t &inputdata ); void InputDisableCrouch( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputEnableCrouch( inputdata_t &inputdata ); +#endif void InputDisableMoveToLOS( inputdata_t &inputdata ); void InputExplode( inputdata_t &inputdata ); void InputScaleGroundSpeed( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetStompFilter( inputdata_t &inputdata ); +#endif + //--------------------------------- // Combat //--------------------------------- @@ -356,6 +366,10 @@ class CNPC_Strider : public CAI_BlendingHost, Vector BackFootHit( float eventtime ); void StompHit( int followerBoneIndex ); +#ifdef MAPBASE + CBaseFilter *GetStompFilter(); +#endif + void FootFX( const Vector &origin ); Vector CalculateStompHitPosition( CBaseEntity *pEnemy ); bool IsLegBoneFollower( CBoneFollower *pFollower ); @@ -452,6 +466,11 @@ class CNPC_Strider : public CAI_BlendingHost, EHANDLE m_hCannonTarget; CSimpleSimTimer m_AttemptCannonLOSTimer; +#ifdef MAPBASE + string_t m_strStompFilter; + CHandle m_hStompFilter; +#endif + float m_flSpeedScale; float m_flTargetSpeedScale; diff --git a/game/server/hl2/npc_turret_ceiling.cpp b/game/server/hl2/npc_turret_ceiling.cpp index ec8b4207..0637525a 100644 --- a/game/server/hl2/npc_turret_ceiling.cpp +++ b/game/server/hl2/npc_turret_ceiling.cpp @@ -26,7 +26,11 @@ //Debug visualization ConVar g_debug_turret_ceiling( "g_debug_turret_ceiling", "0" ); +#ifdef MAPBASE +#define CEILING_TURRET_MODEL GetTurretModel() +#else #define CEILING_TURRET_MODEL "models/combine_turrets/ceiling_turret.mdl" +#endif #define CEILING_TURRET_GLOW_SPRITE "sprites/glow1.vmt" /* // we now inherit these from the ai_basenpc baseclass #define CEILING_TURRET_BC_YAW "aim_yaw" @@ -49,6 +53,9 @@ ConVar g_debug_turret_ceiling( "g_debug_turret_ceiling", "0" ); #define SF_CEILING_TURRET_STARTINACTIVE 0x00000040 #define SF_CEILING_TURRET_NEVERRETIRE 0x00000080 #define SF_CEILING_TURRET_OUT_OF_AMMO 0x00000100 +#ifdef MAPBASE +#define SF_CEILING_TURRET_NO_SPRITE 0x00000400 +#endif //Heights #define CEILING_TURRET_RETRACT_HEIGHT 24 @@ -110,6 +117,14 @@ class CNPC_CeilingTurret : public CAI_BaseNPC void InputToggle( inputdata_t &inputdata ); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDepleteAmmo( inputdata_t &inputdata ); + void InputRestoreAmmo( inputdata_t &inputdata ); + void InputCreateSprite( inputdata_t &inputdata ); + void InputDestroySprite( inputdata_t &inputdata ); + + virtual void StopLoopingSounds( void ) { StopSound(GetMoveSound()); } +#endif void SetLastSightTime(); @@ -147,8 +162,31 @@ class CNPC_CeilingTurret : public CAI_BaseNPC } protected: + +#ifdef MAPBASE + virtual const char *GetTurretModel() { return "models/combine_turrets/ceiling_turret.mdl"; } + + virtual const char *GetRetireSound() { return "NPC_CeilingTurret.Retire"; } + virtual const char *GetDeploySound() { return "NPC_CeilingTurret.Deploy"; } + virtual const char *GetMoveSound() { return "NPC_CeilingTurret.Move"; } + virtual const char *GetActiveSound() { return "NPC_CeilingTurret.Active"; } + virtual const char *GetAlertSound() { return "NPC_CeilingTurret.Alert"; } + virtual const char *GetShootSound() { return "NPC_CeilingTurret.ShotSounds"; } + virtual const char *GetPingSound() { return "NPC_CeilingTurret.Ping"; } + virtual const char *GetDieSound() { return "NPC_CeilingTurret.Die"; } + + virtual float GetFireRate(bool bFightingPlayer = false) { return bFightingPlayer ? 0.5f : 0.1f; } + + virtual void SetIdleGoalAngles() { m_vecGoalAngles = GetAbsAngles(); } +#endif +#ifdef MAPBASE + virtual bool PreThink( turretState_e state ); + void DryFire( void ); + const char *GetTracerType( void ) { return "AR2Tracer"; } +#else bool PreThink( turretState_e state ); +#endif void Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy ); void SetEyeState( eyeState_t state ); void Ping( void ); @@ -157,8 +195,14 @@ class CNPC_CeilingTurret : public CAI_BaseNPC void Disable( void ); void SpinUp( void ); void SpinDown( void ); +#ifdef MAPBASE + virtual +#endif void SetHeight( float height ); +#ifdef MAPBASE + virtual +#endif bool UpdateFacing( void ); int m_iAmmoType; @@ -179,7 +223,9 @@ class CNPC_CeilingTurret : public CAI_BaseNPC COutputEvent m_OnDeploy; COutputEvent m_OnRetire; +#ifndef MAPBASE COutputEvent m_OnTipped; +#endif DECLARE_DATADESC(); }; @@ -198,6 +244,9 @@ BEGIN_DATADESC( CNPC_CeilingTurret ) DEFINE_FIELD( m_flPingTime, FIELD_TIME ), DEFINE_FIELD( m_vecGoalAngles, FIELD_VECTOR ), DEFINE_FIELD( m_pEyeGlow, FIELD_CLASSPTR ), +#ifdef MAPBASE + DEFINE_INPUT( m_flFieldOfView, FIELD_FLOAT, "FieldOfView" ), +#endif DEFINE_THINKFUNC( Retire ), DEFINE_THINKFUNC( Deploy ), @@ -210,10 +259,18 @@ BEGIN_DATADESC( CNPC_CeilingTurret ) DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DepleteAmmo", InputDepleteAmmo ), + DEFINE_INPUTFUNC( FIELD_VOID, "RestoreAmmo", InputRestoreAmmo ), + DEFINE_INPUTFUNC( FIELD_VOID, "CreateSprite", InputCreateSprite ), + DEFINE_INPUTFUNC( FIELD_VOID, "DestroySprite", InputDestroySprite ), +#endif DEFINE_OUTPUT( m_OnDeploy, "OnDeploy" ), DEFINE_OUTPUT( m_OnRetire, "OnRetire" ), +#ifndef MAPBASE DEFINE_OUTPUT( m_OnTipped, "OnTipped" ), +#endif END_DATADESC() @@ -247,7 +304,7 @@ CNPC_CeilingTurret::~CNPC_CeilingTurret( void ) //----------------------------------------------------------------------------- void CNPC_CeilingTurret::Precache( void ) { - PrecacheModel( CEILING_TURRET_MODEL ); + PrecacheModel( DefaultOrCustomModel( CEILING_TURRET_MODEL ) ); PrecacheModel( CEILING_TURRET_GLOW_SPRITE ); // Activities @@ -258,6 +315,16 @@ void CNPC_CeilingTurret::Precache( void ) ADD_CUSTOM_ACTIVITY( CNPC_CeilingTurret, ACT_CEILING_TURRET_FIRE ); ADD_CUSTOM_ACTIVITY( CNPC_CeilingTurret, ACT_CEILING_TURRET_DRYFIRE ); +#ifdef MAPBASE + PrecacheScriptSound( GetRetireSound() ); + PrecacheScriptSound( GetDeploySound() ); + PrecacheScriptSound( GetMoveSound() ); + PrecacheScriptSound( GetActiveSound() ); + PrecacheScriptSound( GetAlertSound() ); + PrecacheScriptSound( GetShootSound() ); + PrecacheScriptSound( GetPingSound() ); + PrecacheScriptSound( GetDieSound() ); +#else PrecacheScriptSound( "NPC_CeilingTurret.Retire" ); PrecacheScriptSound( "NPC_CeilingTurret.Deploy" ); PrecacheScriptSound( "NPC_CeilingTurret.Move" ); @@ -266,6 +333,7 @@ void CNPC_CeilingTurret::Precache( void ) PrecacheScriptSound( "NPC_CeilingTurret.ShotSounds" ); PrecacheScriptSound( "NPC_CeilingTurret.Ping" ); PrecacheScriptSound( "NPC_CeilingTurret.Die" ); +#endif PrecacheScriptSound( "NPC_FloorTurret.DryFire" ); @@ -279,15 +347,22 @@ void CNPC_CeilingTurret::Spawn( void ) { Precache(); - SetModel( CEILING_TURRET_MODEL ); + SetModel( DefaultOrCustomModel( CEILING_TURRET_MODEL ) ); BaseClass::Spawn(); m_HackedGunPos = Vector( 0, 0, 12.75 ); SetViewOffset( EyeOffset( ACT_IDLE ) ); +#ifndef MAPBASE // We use this as a keyvalue now. m_flFieldOfView = 0.0f; +#endif m_takedamage = DAMAGE_YES; +#ifdef MAPBASE + if (m_iHealth == 0) + m_iHealth = 1000; +#else m_iHealth = 1000; +#endif m_bloodColor = BLOOD_COLOR_MECH; SetSolid( SOLID_BBOX ); @@ -304,9 +379,16 @@ void CNPC_CeilingTurret::Spawn( void ) m_iAmmoType = GetAmmoDef()->Index( "AR2" ); //Create our eye sprite +#ifdef MAPBASE + if (!HasSpawnFlags(SF_CEILING_TURRET_NO_SPRITE)) + { +#endif m_pEyeGlow = CSprite::SpriteCreate( CEILING_TURRET_GLOW_SPRITE, GetLocalOrigin(), false ); m_pEyeGlow->SetTransparency( kRenderTransAdd, 255, 0, 0, 128, kRenderFxNoDissipation ); m_pEyeGlow->SetAttachment( this, 2 ); +#ifdef MAPBASE + } +#endif //Set our autostart state m_bAutoStart = !!( m_spawnflags & SF_CEILING_TURRET_AUTOACTIVATE ); @@ -361,7 +443,11 @@ int CNPC_CeilingTurret::OnTakeDamage( const CTakeDamageInfo &inputInfo ) ExplosionCreate( GetAbsOrigin(), GetLocalAngles(), this, 100, 100, false ); SetThink( &CNPC_CeilingTurret::DeathThink ); +#ifdef MAPBASE + StopSound( GetAlertSound() ); +#else StopSound( "NPC_CeilingTurret.Alert" ); +#endif m_OnDamaged.FireOutput( info.GetInflictor(), this ); @@ -397,7 +483,11 @@ void CNPC_CeilingTurret::Retire( void ) if ( UpdateFacing() == false ) { SetActivity( (Activity) ACT_CEILING_TURRET_CLOSE ); +#ifdef MAPBASE + EmitSound( GetRetireSound() ); +#else EmitSound( "NPC_CeilingTurret.Retire" ); +#endif //Notify of the retraction m_OnRetire.FireOutput( NULL, this ); @@ -424,6 +514,10 @@ void CNPC_CeilingTurret::Retire( void ) SetEyeState( TURRET_EYE_DISABLED ); SetThink( &CNPC_CeilingTurret::SUB_DoNothing ); } + +#ifdef MAPBASE + StopLoopingSounds(); +#endif } } @@ -447,10 +541,18 @@ void CNPC_CeilingTurret::Deploy( void ) { m_bActive = true; SetActivity( (Activity) ACT_CEILING_TURRET_OPEN ); +#ifdef MAPBASE + EmitSound( GetDeploySound() ); +#else EmitSound( "NPC_CeilingTurret.Deploy" ); +#endif //Notify we're deploying +#ifdef MAPBASE + m_OnDeploy.FireOutput( GetEnemy(), this ); +#else m_OnDeploy.FireOutput( NULL, this ); +#endif } //If we're done, then start searching @@ -465,7 +567,11 @@ void CNPC_CeilingTurret::Deploy( void ) m_flPlaybackRate = 0; SetThink( &CNPC_CeilingTurret::SearchThink ); +#ifdef MAPBASE + EmitSound( GetMoveSound() ); +#else EmitSound( "NPC_CeilingTurret.Move" ); +#endif } SetLastSightTime(); @@ -569,7 +675,11 @@ bool CNPC_CeilingTurret::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEnt // If we hit something that's okay to hit anyway, still fire if ( pHitEntity && pHitEntity->MyCombatCharacterPointer() ) { +#ifdef MAPBASE + if (IRelationType(pHitEntity) <= D_FR) +#else if (IRelationType(pHitEntity) == D_HT) +#endif return true; } @@ -671,6 +781,20 @@ void CNPC_CeilingTurret::ActiveThink( void ) //Fire the gun if ( DotProduct( vecDirToEnemy, vecMuzzleDir ) >= 0.9848 ) // 10 degree slop { +#ifdef MAPBASE + if ( m_spawnflags & SF_CEILING_TURRET_OUT_OF_AMMO ) + { + ResetActivity(); + SetActivity( (Activity) ACT_CEILING_TURRET_DRYFIRE ); + DryFire(); + } + else + { + ResetActivity(); + SetActivity( (Activity) ACT_CEILING_TURRET_FIRE ); + Shoot( vecMuzzle, vecMuzzleDir ); + } +#else if ( m_spawnflags & SF_CEILING_TURRET_OUT_OF_AMMO ) { SetActivity( (Activity) ACT_CEILING_TURRET_DRYFIRE ); @@ -682,6 +806,7 @@ void CNPC_CeilingTurret::ActiveThink( void ) //Fire the weapon Shoot( vecMuzzle, vecMuzzleDir ); +#endif } } else @@ -733,6 +858,9 @@ void CNPC_CeilingTurret::SearchThink( void ) //If we've found a target, spin up the barrel and start to attack if ( GetEnemy() != NULL ) { +#ifdef MAPBASE + m_flShotTime = gpGlobals->curtime + GetFireRate( GetEnemy()->IsPlayer() ); +#else //Give players a grace period if ( GetEnemy()->IsPlayer() ) { @@ -742,13 +870,18 @@ void CNPC_CeilingTurret::SearchThink( void ) { m_flShotTime = gpGlobals->curtime + 0.1f; } +#endif m_flLastSight = 0; SetThink( &CNPC_CeilingTurret::ActiveThink ); SetEyeState( TURRET_EYE_SEE_TARGET ); SpinUp(); +#ifdef MAPBASE + EmitSound( GetActiveSound() ); +#else EmitSound( "NPC_CeilingTurret.Active" ); +#endif return; } @@ -799,10 +932,76 @@ void CNPC_CeilingTurret::AutoSearchThink( void ) if ( GetEnemy() != NULL ) { SetThink( &CNPC_CeilingTurret::Deploy ); +#ifdef MAPBASE + EmitSound( GetAlertSound() ); +#else EmitSound( "NPC_CeilingTurret.Alert" ); +#endif + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// I decided to move dry firing to its own function instead of keeping it in Shoot, similar to npc_turret_floor +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::DryFire( void ) +{ + EmitSound( "NPC_FloorTurret.DryFire"); + EmitSound( GetActiveSound() ); + + if ( RandomFloat( 0, 1 ) > 0.7 ) + { + m_flShotTime = gpGlobals->curtime + random->RandomFloat( 0.5, 1.5 ); + } + else + { + m_flShotTime = gpGlobals->curtime; } } +//----------------------------------------------------------------------------- +// Purpose: Fire! +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy ) +{ + FireBulletsInfo_t info; + + if ( GetEnemy() != NULL ) + { + Vector vecDir = GetActualShootTrajectory( vecSrc ); + + info.m_vecSrc = vecSrc; + info.m_vecDirShooting = vecDir; + info.m_iTracerFreq = 1; + info.m_iShots = 1; + info.m_pAttacker = this; + info.m_vecSpread = VECTOR_CONE_PRECALCULATED; + info.m_flDistance = MAX_COORD_RANGE; + info.m_iAmmoType = m_iAmmoType; + } + else + { + // Just shoot where you're facing! + + info.m_vecSrc = vecSrc; + info.m_vecDirShooting = vecDirToEnemy; + info.m_iTracerFreq = 1; + info.m_iShots = 1; + info.m_pAttacker = this; + info.m_vecSpread = GetAttackSpread( NULL, NULL ); + info.m_flDistance = MAX_COORD_RANGE; + info.m_iAmmoType = m_iAmmoType; + } + + FireBullets( info ); +#ifdef MAPBASE + EmitSound( GetShootSound() ); +#else + EmitSound( "NPC_CeilingTurret.ShotSounds" ); +#endif + DoMuzzleFlash(); +} +#else //----------------------------------------------------------------------------- // Purpose: Fire! //----------------------------------------------------------------------------- @@ -859,6 +1058,7 @@ void CNPC_CeilingTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnem EmitSound( "NPC_CeilingTurret.ShotSounds" ); DoMuzzleFlash(); } +#endif //----------------------------------------------------------------------------- // Purpose: Allows a generic think function before the others are called @@ -946,7 +1146,11 @@ void CNPC_CeilingTurret::Ping( void ) return; //Ping! +#ifdef MAPBASE + EmitSound( GetPingSound() ); +#else EmitSound( "NPC_CeilingTurret.Ping" ); +#endif SetEyeState( TURRET_EYE_SEEKING_TARGET ); @@ -1023,6 +1227,52 @@ void CNPC_CeilingTurret::InputDisable( inputdata_t &inputdata ) Disable(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Stops the turret from firing live rounds (still attempts to though) +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::InputDepleteAmmo( inputdata_t &inputdata ) +{ + AddSpawnFlags( SF_CEILING_TURRET_OUT_OF_AMMO ); +} + +//----------------------------------------------------------------------------- +// Purpose: Allows the turret to fire live rounds again +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::InputRestoreAmmo( inputdata_t &inputdata ) +{ + RemoveSpawnFlags( SF_CEILING_TURRET_OUT_OF_AMMO ); +} + +//----------------------------------------------------------------------------- +// Purpose: Creates the sprite if it has been destroyed +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::InputCreateSprite( inputdata_t &inputdata ) +{ + if (m_pEyeGlow) + return; + + m_pEyeGlow = CSprite::SpriteCreate( CEILING_TURRET_GLOW_SPRITE, GetLocalOrigin(), false ); + m_pEyeGlow->SetTransparency( kRenderTransAdd, 255, 0, 0, 128, kRenderFxNoDissipation ); + m_pEyeGlow->SetAttachment( this, 2 ); + + RemoveSpawnFlags(SF_CEILING_TURRET_NO_SPRITE); +} + +//----------------------------------------------------------------------------- +// Purpose: Destroys the sprite +//----------------------------------------------------------------------------- +void CNPC_CeilingTurret::InputDestroySprite( inputdata_t &inputdata ) +{ + if (!m_pEyeGlow) + return; + + UTIL_Remove(m_pEyeGlow); + m_pEyeGlow = NULL; + AddSpawnFlags(SF_CEILING_TURRET_NO_SPRITE); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1048,14 +1298,26 @@ void CNPC_CeilingTurret::DeathThink( void ) return; //Level out our angles +#ifdef MAPBASE + SetIdleGoalAngles(); +#else m_vecGoalAngles = GetAbsAngles(); +#endif SetNextThink( gpGlobals->curtime ); if ( m_lifeState != LIFE_DEAD ) { m_lifeState = LIFE_DEAD; +#ifdef MAPBASE + StopLoopingSounds(); +#endif + +#ifdef MAPBASE + EmitSound( GetDieSound() ); +#else EmitSound( "NPC_CeilingTurret.Die" ); +#endif SetActivity( (Activity) ACT_CEILING_TURRET_CLOSE ); } @@ -1124,4 +1386,367 @@ bool CNPC_CeilingTurret::CanBeAnEnemyOf( CBaseEntity *pEnemy ) } return BaseClass::CanBeAnEnemyOf( pEnemy ); -} \ No newline at end of file +} + + + +#ifdef MAPBASE +// +// Eli's Lab Turret +// + +//#define LAB_TURRET_MANUAL_YAW 1 + +int ACT_CEILING_TURRET_MIRROR_CLOSED_IDLE; +int ACT_CEILING_TURRET_MIRROR_OPEN; +int ACT_CEILING_TURRET_MIRROR_CLOSE; + +class CNPC_LabTurret : public CNPC_CeilingTurret +{ + DECLARE_CLASS( CNPC_LabTurret, CNPC_CeilingTurret ); +public: + CNPC_LabTurret(); + + Class_T Classify( void ) + { + if( m_bEnabled ) + return CLASS_PLAYER_ALLY; + + return CLASS_NONE; + } + + const char *GetTracerType( void ) { return "Tracer"; } + bool PreThink( turretState_e state ); + + void SetIdleGoalAngles(); + + void Precache( void ); + void Spawn(); + Activity NPC_TranslateActivity( Activity activity ); + +#ifdef LAB_TURRET_MANUAL_YAW + void SetArmYaw( float flYaw ); + void ArmYawThink(); + + void InputSetArmYaw( inputdata_t &inputdata ); +#else + inline void SetArmYaw( float flYaw ) { SetPoseParameter( m_poseMove_Yaw, flYaw ); } +#endif + + void StopLoopingSounds( void ) { StopSound(GetMoveSound()); } + +protected: + + const char *GetTurretModel() { return "models/props_lab/labturret_npc.mdl"; } + + const char *GetRetireSound() { return "NPC_LabTurret.Retire"; } + const char *GetDeploySound() { return "NPC_LabTurret.Deploy"; } + const char *GetMoveSound() { return "NPC_LabTurret.Move"; } + const char *GetActiveSound() { return "NPC_LabTurret.Active"; } + const char *GetAlertSound() { return "NPC_LabTurret.Alert"; } + const char *GetShootSound() { return "NPC_LabTurret.ShotSounds"; } + const char *GetPingSound() { return "NPC_LabTurret.Ping"; } + const char *GetDieSound() { return "NPC_LabTurret.Die"; } + + float GetFireRate(bool bFightingPlayer = false) { return 1.0f; } + + void SetHeight( float height ); + + bool UpdateFacing( void ); + + bool m_bManualArmYaw; + +#ifdef LAB_TURRET_MANUAL_YAW + // The arm must reset each retire and be restored each deploy + float m_flStoredArmYaw; + float m_flGoalArmYaw; +#endif + + bool m_bMirrored; + + DECLARE_DATADESC(); +}; + +BEGIN_DATADESC( CNPC_LabTurret ) + + DEFINE_KEYFIELD( m_bManualArmYaw, FIELD_BOOLEAN, "ManualArmYaw" ), +#ifdef LAB_TURRET_MANUAL_YAW + DEFINE_KEYFIELD( m_flStoredArmYaw, FIELD_FLOAT, "ArmYaw" ), + DEFINE_FIELD( m_flGoalArmYaw, FIELD_FLOAT ), +#endif + DEFINE_KEYFIELD( m_bMirrored, FIELD_BOOLEAN, "Mirrored" ), + +#ifdef LAB_TURRET_MANUAL_YAW + DEFINE_THINKFUNC( ArmYawThink ), +#endif + + // Inputs +#ifdef LAB_TURRET_MANUAL_YAW + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetArmYaw", InputSetArmYaw ), +#endif + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( npc_turret_lab, CNPC_LabTurret ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CNPC_LabTurret::CNPC_LabTurret() +{ + // Lab turrets can rotate much more, so they can see from more angles than regular turrets. + m_flFieldOfView = -0.5; +} + +//----------------------------------------------------------------------------- +// Purpose: Precache +//----------------------------------------------------------------------------- +void CNPC_LabTurret::Precache( void ) +{ + BaseClass::Precache(); + + // Activities + ADD_CUSTOM_ACTIVITY( CNPC_LabTurret, ACT_CEILING_TURRET_MIRROR_CLOSED_IDLE ); + ADD_CUSTOM_ACTIVITY( CNPC_LabTurret, ACT_CEILING_TURRET_MIRROR_OPEN ); + ADD_CUSTOM_ACTIVITY( CNPC_LabTurret, ACT_CEILING_TURRET_MIRROR_CLOSE ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_LabTurret::Spawn( void ) +{ + BaseClass::Spawn(); + + m_iAmmoType = GetAmmoDef()->Index( "SMG1" ); + + if (m_bMirrored) + SetActivity((Activity)ACT_CEILING_TURRET_MIRROR_CLOSED_IDLE); + + SetPoseParameter( m_poseMove_Yaw, 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: Override base class activiites +//----------------------------------------------------------------------------- +Activity CNPC_LabTurret::NPC_TranslateActivity( Activity activity ) +{ + if (m_bMirrored) + { + if (activity == ACT_CEILING_TURRET_CLOSED_IDLE) + return (Activity)ACT_CEILING_TURRET_MIRROR_CLOSED_IDLE; + if (activity == ACT_CEILING_TURRET_OPEN) + return (Activity)ACT_CEILING_TURRET_MIRROR_OPEN; + if (activity == ACT_CEILING_TURRET_CLOSE) + return (Activity)ACT_CEILING_TURRET_MIRROR_CLOSE; + } + + return BaseClass::NPC_TranslateActivity(activity); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CNPC_LabTurret::PreThink( turretState_e state ) +{ + if (state == TURRET_RETIRING || state == TURRET_DEAD) + { +#ifdef LAB_TURRET_MANUAL_YAW + if (m_bManualArmYaw) + m_flStoredArmYaw = GetPoseParameter(m_poseMove_Yaw); +#endif + + SetArmYaw( 0 ); + } +#ifdef LAB_TURRET_MANUAL_YAW + else if (state == TURRET_DEPLOYING) + { + if (m_bManualArmYaw) + SetArmYaw( m_flStoredArmYaw ); + } +#endif + + return BaseClass::PreThink(state); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_LabTurret::SetIdleGoalAngles( void ) +{ + m_vecGoalAngles = GetAbsAngles(); + + if (m_bMirrored) + { + //m_vecGoalAngles.x = AngleNormalize( m_vecGoalAngles.x + 90 ); + m_vecGoalAngles.y = AngleNormalize( m_vecGoalAngles.y + 270 ); + } + else + { + //m_vecGoalAngles.x = AngleNormalize( m_vecGoalAngles.x + 270 ); + m_vecGoalAngles.y = AngleNormalize( m_vecGoalAngles.y + 90 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : height - +//----------------------------------------------------------------------------- +void CNPC_LabTurret::SetHeight( float height ) +{ + Vector forward, right, up; + AngleVectors( GetLocalAngles(), &forward, &right, &up ); + + height /= 2; + + Vector mins = ( forward * -8.0f ) + ( right * -height ) + ( up * -8.0f ); + Vector maxs = ( forward * height ) + ( right * height ) + ( up * CEILING_TURRET_RETRACT_HEIGHT ); + + if ( mins.x > maxs.x ) + { + V_swap( mins.x, maxs.x ); + } + + if ( mins.y > maxs.y ) + { + V_swap( mins.y, maxs.y ); + } + + if ( mins.z > maxs.z ) + { + V_swap( mins.z, maxs.z ); + } + + SetCollisionBounds( mins, maxs ); +} + +//----------------------------------------------------------------------------- +// Purpose: Causes the turret to face its desired angles +//----------------------------------------------------------------------------- +bool CNPC_LabTurret::UpdateFacing( void ) +{ + bool bMoved = false; + + matrix3x4_t localToWorld; + + GetAttachment( LookupAttachment( "eyes" ), localToWorld ); + + Vector vecGoalDir; + AngleVectors( m_vecGoalAngles, &vecGoalDir ); + + Vector vecGoalLocalDir; + VectorIRotate( vecGoalDir, localToWorld, vecGoalLocalDir ); + + if ( g_debug_turret_ceiling.GetBool() ) + { + Vector vecMuzzle, vecMuzzleDir; + QAngle vecMuzzleAng; + + GetAttachment( "eyes", vecMuzzle, vecMuzzleAng ); + AngleVectors( vecMuzzleAng, &vecMuzzleDir ); + + NDebugOverlay::Cross3D( vecMuzzle, -Vector(2,2,2), Vector(2,2,2), 255, 255, 0, false, 0.05 ); + NDebugOverlay::Cross3D( vecMuzzle+(vecMuzzleDir*256), -Vector(2,2,2), Vector(2,2,2), 255, 255, 0, false, 0.05 ); + NDebugOverlay::Line( vecMuzzle, vecMuzzle+(vecMuzzleDir*256), 255, 255, 0, false, 0.05 ); + + NDebugOverlay::Cross3D( vecMuzzle, -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 0.05 ); + NDebugOverlay::Cross3D( vecMuzzle+(vecGoalDir*256), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 0.05 ); + NDebugOverlay::Line( vecMuzzle, vecMuzzle+(vecGoalDir*256), 255, 0, 0, false, 0.05 ); + } + + QAngle vecGoalLocalAngles; + VectorAngles( vecGoalLocalDir, vecGoalLocalAngles ); + +#ifdef LAB_TURRET_MANUAL_YAW + if ( !m_bManualArmYaw && m_flGoalArmYaw == 0.0f ) +#else + if ( !m_bManualArmYaw ) +#endif + { + // Update yaw + float flDiff = AngleNormalize( UTIL_ApproachAngle( vecGoalLocalAngles.y, 0.0, 0.1f * MaxYawSpeed() ) ); + + SetPoseParameter( m_poseMove_Yaw, GetPoseParameter( m_poseMove_Yaw ) + ( flDiff / 1.5f ) * 0.5f ); + + // Recalculate muzzle + GetAttachment( LookupAttachment( "eyes" ), localToWorld ); + VectorIRotate( vecGoalDir, localToWorld, vecGoalLocalDir ); + VectorAngles( vecGoalLocalDir, vecGoalLocalAngles ); + + if ( fabs( flDiff ) > 0.1f ) + { + bMoved = true; + } + } + + // Update pitch + // Pitch is faster than the others, but it also kind of jiggles when targetting. + float flDiff = AngleNormalize( UTIL_ApproachAngle( vecGoalLocalAngles.x, 0.0, (GetActivity() != ACT_CEILING_TURRET_CLOSE ? 0.15f : 0.1f) * MaxYawSpeed() ) ); + + SetPoseParameter( m_poseAim_Pitch, GetPoseParameter( m_poseAim_Pitch ) + ( flDiff * 2.0f ) ); + + if ( fabs( flDiff ) > 0.1f ) + { + bMoved = true; + } + + // Update yaw + flDiff = AngleNormalize( UTIL_ApproachAngle( vecGoalLocalAngles.y, 0.0, 0.1f * MaxYawSpeed() ) ); + + SetPoseParameter( m_poseAim_Yaw, GetPoseParameter( m_poseAim_Yaw ) + ( flDiff / 1.5f ) ); + + if ( fabs( flDiff ) > 0.1f ) + { + bMoved = true; + } + + InvalidateBoneCache(); + + return bMoved; +} + +#ifdef LAB_TURRET_MANUAL_YAW +//----------------------------------------------------------------------------- +// Purpose: Change move yaw +//----------------------------------------------------------------------------- +void CNPC_LabTurret::SetArmYaw( float flYaw ) +{ + m_flGoalArmYaw = flYaw; + + SetContextThink(&CNPC_LabTurret::ArmYawThink, gpGlobals->curtime, "SetArmYaw"); +} + +//----------------------------------------------------------------------------- +// Purpose: Change move yaw +//----------------------------------------------------------------------------- +void CNPC_LabTurret::ArmYawThink() +{ + //GetBoneTransform( LookupBone( "eyes" ), localToWorld ); + + // Update yaw + float flDiff = AngleNormalize( UTIL_ApproachAngle( m_flGoalArmYaw, GetPoseParameter( m_poseMove_Yaw ), 0.05f * MaxYawSpeed() ) ); + + SetPoseParameter( m_poseMove_Yaw, GetPoseParameter( m_poseAim_Pitch ) + ( flDiff / 1.5f ) ); + + InvalidateBoneCache(); + + if ( fabs( flDiff ) > 0.1f ) + { + SetNextThink(gpGlobals->curtime, "SetArmYaw"); + } + else + { + m_flGoalArmYaw = 0.0f; + SetContextThink(NULL, gpGlobals->curtime, "SetArmYaw"); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Change move yaw +//----------------------------------------------------------------------------- +void CNPC_LabTurret::InputSetArmYaw( inputdata_t &inputdata ) +{ + SetArmYaw( inputdata.value.Float() ); +} +#endif +#endif diff --git a/game/server/hl2/npc_turret_floor.cpp b/game/server/hl2/npc_turret_floor.cpp index 17396bee..fed9ffb2 100644 --- a/game/server/hl2/npc_turret_floor.cpp +++ b/game/server/hl2/npc_turret_floor.cpp @@ -40,6 +40,15 @@ ConVar g_debug_turret( "g_debug_turret", "0" ); extern ConVar physcannon_tracelength; +#if defined(MAPBASE) && defined(HL2_EPISODIC) +extern ConVar npc_alyx_interact_turrets; +#endif + +#ifdef MAPBASE +// m_iKeySkin has been replaced with the original m_nSkin so we can make it show up in Hammer, etc. +#define m_iKeySkin m_nSkin +#endif + // Interactions int g_interactionTurretStillStanding = 0; @@ -132,6 +141,10 @@ BEGIN_DATADESC( CNPC_FloorTurret ) DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), DEFINE_INPUTFUNC( FIELD_VOID, "DepleteAmmo", InputDepleteAmmo ), DEFINE_INPUTFUNC( FIELD_VOID, "RestoreAmmo", InputRestoreAmmo ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "CreateSprite", InputCreateSprite ), + DEFINE_INPUTFUNC( FIELD_VOID, "DestroySprite", InputDestroySprite ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "SelfDestruct", InputSelfDestruct ), DEFINE_OUTPUT( m_OnDeploy, "OnDeploy" ), @@ -176,9 +189,10 @@ CNPC_FloorTurret::CNPC_FloorTurret( void ) : } #ifdef VANCE -void CNPC_FloorTurret::Hack(void) +void CNPC_FloorTurret::Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) { m_bHackedByAlyx = true; + BaseClass::Hack( pActivator, pCaller ); } #endif @@ -295,10 +309,12 @@ void CNPC_FloorTurret::Spawn( void ) // add one mod 4 nextSkin = (nextSkin + 1) & 0x03; } +#ifndef MAPBASE else { // at least make sure that it's in the right range m_nSkin = clamp(m_iKeySkin,1,4); } +#endif } BaseClass::Spawn(); @@ -1552,7 +1568,11 @@ bool CNPC_FloorTurret::PreThink( turretState_e state ) void CNPC_FloorTurret::SetEyeState( eyeState_t state ) { // Must have a valid eye to affect +#ifdef MAPBASE + if ( !m_hEyeGlow && !HasSpawnFlags(SF_FLOOR_TURRET_NO_SPRITE) ) +#else if ( !m_hEyeGlow ) +#endif { // Create our eye sprite m_hEyeGlow = CSprite::SpriteCreate( FLOOR_TURRET_GLOW_SPRITE, GetLocalOrigin(), false ); @@ -1782,6 +1802,39 @@ void CNPC_FloorTurret::InputRestoreAmmo( inputdata_t &inputdata ) RemoveSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Creates the sprite if it has been destroyed +//----------------------------------------------------------------------------- +void CNPC_FloorTurret::InputCreateSprite( inputdata_t &inputdata ) +{ + if (m_hEyeGlow) + return; + + m_hEyeGlow = CSprite::SpriteCreate( FLOOR_TURRET_GLOW_SPRITE, GetLocalOrigin(), false ); + if ( !m_hEyeGlow ) + return; + + m_hEyeGlow->SetTransparency( kRenderWorldGlow, 255, 0, 0, 128, kRenderFxNoDissipation ); + m_hEyeGlow->SetAttachment( this, m_iEyeAttachment ); + + RemoveSpawnFlags(SF_FLOOR_TURRET_NO_SPRITE); +} + +//----------------------------------------------------------------------------- +// Purpose: Destroys the sprite +//----------------------------------------------------------------------------- +void CNPC_FloorTurret::InputDestroySprite( inputdata_t &inputdata ) +{ + if (!m_hEyeGlow) + return; + + UTIL_Remove(m_hEyeGlow); + m_hEyeGlow = NULL; + AddSpawnFlags(SF_FLOOR_TURRET_NO_SPRITE); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Allow players and npc's to turn the turret on and off //----------------------------------------------------------------------------- @@ -2001,6 +2054,20 @@ int CNPC_FloorTurret::DrawDebugTextOverlays( void ) return text_offset; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Option to restore Alyx's interactions with non-rollermines +//----------------------------------------------------------------------------- +bool CNPC_FloorTurret::CanInteractWith( CAI_BaseNPC *pUser ) +{ +#ifdef HL2_EPISODIC + return npc_alyx_interact_turrets.GetBool(); +#else + return false; +#endif +} +#endif + void CNPC_FloorTurret::UpdateMuzzleMatrix() { if ( gpGlobals->tickcount != m_muzzleToWorldTick ) diff --git a/game/server/hl2/npc_turret_floor.h b/game/server/hl2/npc_turret_floor.h index f698c09d..05a76155 100644 --- a/game/server/hl2/npc_turret_floor.h +++ b/game/server/hl2/npc_turret_floor.h @@ -43,6 +43,9 @@ enum eyeState_t #define SF_FLOOR_TURRET_FASTRETIRE 0x00000080 #define SF_FLOOR_TURRET_OUT_OF_AMMO 0x00000100 #define SF_FLOOR_TURRET_CITIZEN 0x00000200 // Citizen modified turret +#ifdef MAPBASE +#define SF_FLOOR_TURRET_NO_SPRITE 0x00000400 +#endif class CTurretTipController; class CBeam; @@ -68,16 +71,16 @@ class CNPC_FloorTurret : public CNPCBaseInteractive, public CDefaul virtual int VPhysicsTakeDamage( const CTakeDamageInfo &info ); virtual bool CanBecomeServerRagdoll( void ) { return false; } -#ifdef VANCE - virtual bool IsHackable(void) { return true; } - virtual void Hack(void); -#endif - #ifdef HL2_EPISODIC // We don't want to be NPCSOLID because we'll collide with NPC clips virtual unsigned int PhysicsSolidMaskForEntity( void ) const { return MASK_SOLID; } #endif // HL2_EPISODIC +#ifdef VANCE + bool IsHackable() const override { return true; } + void Hack( CBaseEntity *pActivator, CBaseEntity *pCaller ) override; +#endif + // Player pickup virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ); @@ -136,6 +139,11 @@ class CNPC_FloorTurret : public CNPCBaseInteractive, public CDefaul void InputDepleteAmmo( inputdata_t &inputdata ); void InputRestoreAmmo( inputdata_t &inputdata ); void InputSelfDestruct( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputCreateSprite( inputdata_t &inputdata ); + void InputDestroySprite( inputdata_t &inputdata ); + void InputPowerdown( inputdata_t &inputdata ) { InputSelfDestruct(inputdata); } +#endif virtual bool IsValidEnemy( CBaseEntity *pEnemy ); bool CanBeAnEnemyOf( CBaseEntity *pEnemy ); @@ -173,13 +181,20 @@ class CNPC_FloorTurret : public CNPCBaseInteractive, public CDefaul int DrawDebugTextOverlays( void ); // INPCInteractive Functions +#ifdef MAPBASE + virtual bool CanInteractWith( CAI_BaseNPC *pUser ); +#else virtual bool CanInteractWith( CAI_BaseNPC *pUser ) { return false; } // Disabled for now (sjb) +#endif virtual bool HasBeenInteractedWith() { return m_bHackedByAlyx; } virtual void NotifyInteraction( CAI_BaseNPC *pUser ) { // For now, turn green so we can tell who is hacked. SetRenderColor( 0, 255, 0 ); m_bHackedByAlyx = true; +#ifdef MAPBASE + m_OnHacked.FireOutput(pUser, this); +#endif } static float fMaxTipControllerVelocity; @@ -225,7 +240,9 @@ class CNPC_FloorTurret : public CNPCBaseInteractive, public CDefaul bool m_bCarriedByPlayer; bool m_bUseCarryAngles; float m_flPlayerDropTime; +#ifndef MAPBASE // Replaced with m_nSkin. int m_iKeySkin; +#endif CHandle m_hLastNPCToKickMe; // Stores the last NPC who tried to knock me over float m_flKnockOverFailedTime; // Time at which we should tell the NPC that he failed to knock me over diff --git a/game/server/hl2/npc_turret_ground.cpp b/game/server/hl2/npc_turret_ground.cpp index bacaac0a..c7dceeae 100644 --- a/game/server/hl2/npc_turret_ground.cpp +++ b/game/server/hl2/npc_turret_ground.cpp @@ -69,7 +69,7 @@ END_DATADESC() void CNPC_GroundTurret::Precache( void ) { PrecacheModel( GROUNDTURRET_BEAM_SPRITE ); - PrecacheModel( "models/combine_turrets/ground_turret.mdl" ); + PrecacheModel( DefaultOrCustomModel( "models/combine_turrets/ground_turret.mdl" ) ); PrecacheScriptSound( "NPC_CeilingTurret.Deploy" ); m_ShotSounds = PrecacheScriptSound( "NPC_FloorTurret.ShotSounds" ); @@ -88,7 +88,7 @@ void CNPC_GroundTurret::Spawn( void ) { Precache(); - UTIL_SetModel( this, "models/combine_turrets/ground_turret.mdl" ); + UTIL_SetModel( this, DefaultOrCustomModel( "models/combine_turrets/ground_turret.mdl" ) ); SetNavType( NAV_FLY ); SetSolid( SOLID_VPHYSICS ); @@ -130,8 +130,10 @@ void CNPC_GroundTurret::Spawn( void ) if( !GetParent() ) { DevMsg("ERROR! npc_ground_turret with no parent!\n"); +#ifndef MAPBASE UTIL_Remove(this); return; +#endif } m_flTimeNextShoot = gpGlobals->curtime; diff --git a/game/server/hl2/npc_vortigaunt_episodic.cpp b/game/server/hl2/npc_vortigaunt_episodic.cpp index 3337a65b..218da1a5 100644 --- a/game/server/hl2/npc_vortigaunt_episodic.cpp +++ b/game/server/hl2/npc_vortigaunt_episodic.cpp @@ -581,6 +581,31 @@ bool CNPC_Vortigaunt::InnateWeaponLOSCondition( const Vector &ownerPos, const Ve UTIL_PredictedPosition( this, flTimeDelta, &vecNewOwnerPos ); UTIL_PredictedPosition( GetEnemy(), flTimeDelta, &vecNewTargetPos ); +#ifdef MAPBASE + // There's apparently a null pointer crash here + if (!GetEnemy()) + return false; + + // The fix below and its accompanying comment were created by DKY. + + /* + + Fix for LOS test failures when the Vort is attempting to find a viable + shoot position-- Valve's "predict where we'll be in a moment" hack (as + described above) completely breaks SCHED_ESTABLISH_LINE_OF_FIRE because it + causes all LOS checks to fail for every node if the Vort's current position + is not a valid shooting position. + - Thank you, dky.tehkingd.u! + + */ + + // Determine the Vort's predicted position delta + Vector ownerDelta = vecNewOwnerPos - GetAbsOrigin(); + + // Offset our requested LOS check location by the predicted delta. + vecNewOwnerPos = ownerPos + ownerDelta; +#endif + Vector vecDelta = vecNewTargetPos - GetEnemy()->GetAbsOrigin(); Vector vecFinalTargetPos = GetEnemy()->BodyTarget( vecNewOwnerPos ) + vecDelta; @@ -1045,9 +1070,17 @@ Activity CNPC_Vortigaunt::NPC_TranslateActivity( Activity eNewActivity ) if ( GetReadinessLevel() >= AIRL_STIMULATED ) return ACT_IDLE_STIMULATED; } - + if ( eNewActivity == ACT_RANGE_ATTACK2 ) + { +#ifdef MAPBASE + // If we're capable of using grenades, use ACT_COMBINE_THROW_GRENADE + if (IsGrenadeCapable()) + return ACT_COMBINE_THROW_GRENADE; + else +#endif return (Activity) ACT_VORTIGAUNT_DISPEL; + } return BaseClass::NPC_TranslateActivity( eNewActivity ); } @@ -2693,6 +2726,15 @@ void CNPC_Vortigaunt::OnSquishedGrub( const CBaseEntity *pGrub ) //----------------------------------------------------------------------------- void CNPC_Vortigaunt::AimGun( void ) { +#ifdef MAPBASE + // Use base for func_tank + if (m_FuncTankBehavior.IsRunning()) + { + BaseClass::AimGun(); + return; + } +#endif + // If our aim lock is on, don't bother if ( m_flAimDelay >= gpGlobals->curtime ) return; @@ -2776,7 +2818,12 @@ bool CNPC_Vortigaunt::CanFlinch( void ) if ( IsCurSchedule( SCHED_VORTIGAUNT_DISPEL_ANTLIONS ) || IsCurSchedule( SCHED_RANGE_ATTACK1 ) ) return false; +#ifdef MAPBASE + // This skips CAI_PlayerAlly's CanFlinch() function since Episodic vorts can flinch to begin with. + return CAI_BaseActor::CanFlinch(); +#else return BaseClass::CanFlinch(); +#endif } //----------------------------------------------------------------------------- diff --git a/game/server/hl2/npc_vortigaunt_episodic.h b/game/server/hl2/npc_vortigaunt_episodic.h index e0da23d3..91e6a3c6 100644 --- a/game/server/hl2/npc_vortigaunt_episodic.h +++ b/game/server/hl2/npc_vortigaunt_episodic.h @@ -138,6 +138,13 @@ class CNPC_Vortigaunt : public CNPC_PlayerCompanion // used so a grub can notify me that I stepped on it. Says a line. void OnSquishedGrub( const CBaseEntity *pGrub ); +#ifdef MAPBASE + // Use the vortigaunts' default subtitle color (188,241,174) + bool GetGameTextSpeechParams( hudtextparms_t ¶ms ) { params.r1 = 188; params.g1 = 241; params.b1 = 174; return BaseClass::GetGameTextSpeechParams( params ); } + + const char* GetGrenadeAttachment() { return "rightclaw"; } +#endif + private: int NumAntlionsInRadius( float flRadius ); diff --git a/game/server/hl2/npc_zombie.cpp b/game/server/hl2/npc_zombie.cpp index 6762c45c..ecaf8c0a 100644 --- a/game/server/hl2/npc_zombie.cpp +++ b/game/server/hl2/npc_zombie.cpp @@ -17,6 +17,10 @@ #include "soundenvelope.h" #include "engine/IEngineSound.h" #include "ammodef.h" +#ifdef MAPBASE +#include "AI_ResponseSystem.h" +#include "ai_speech.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -75,6 +79,18 @@ envelopePoint_t envZombieMoanIgnited[] = }, }; +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Move these to CNPC_BaseZombie if other zombies end up using the response system +//------------------------------------------------------------------------------ +#define TLK_ZOMBIE_PAIN "TLK_WOUND" +#define TLK_ZOMBIE_DEATH "TLK_DEATH" +#define TLK_ZOMBIE_ALERT "TLK_STARTCOMBAT" +#define TLK_ZOMBIE_IDLE "TLK_QUESTION" +#define TLK_ZOMBIE_ATTACK "TLK_MELEE" +#define TLK_ZOMBIE_MOAN "TLK_MOAN" +#endif + //============================================================================= //============================================================================= @@ -120,9 +136,9 @@ class CZombie : public CAI_BlendingHost virtual const char *GetHeadcrabClassname( void ); virtual const char *GetHeadcrabModel( void ); - virtual bool OnObstructingDoor( AILocalMoveGoal_t *pMoveGoal, + virtual bool OnObstructingDoor( AILocalMoveGoal_t *pMoveGoal, CBaseDoor *pDoor, - float distClear, + float distClear, AIMoveResult_t *pResult ); Activity SelectDoorBash(); @@ -148,7 +164,7 @@ class CZombie : public CAI_BlendingHost void FootscuffSound( bool fRightFoot ); const char *GetMoanSound( int nSound ); - + public: DEFINE_CUSTOM_AI; @@ -159,7 +175,7 @@ class CZombie : public CAI_BlendingHost private: CHandle< CBaseDoor > m_hBlockingDoor; float m_flDoorBashYaw; - + CRandSimTimer m_DurationDoorBash; CSimTimer m_NextTimeToStartDoorBash; @@ -228,7 +244,7 @@ END_DATADESC() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CZombie::Precache( void ) { @@ -263,6 +279,17 @@ void CZombie::Spawn( void ) { Precache(); +#ifdef MAPBASE + if( Q_strstr( GetClassname(), "torso" ) ) + { + // This was placed as an npc_zombie_torso + m_fIsTorso = true; + } + else + { + m_fIsTorso = false; + } +#else if( FClassnameIs( this, "npc_zombie" ) ) { m_fIsTorso = false; @@ -274,6 +301,7 @@ void CZombie::Spawn( void ) } m_fIsHeadless = false; +#endif #ifdef HL2_EPISODIC SetBloodColor( BLOOD_COLOR_ZOMBIE ); @@ -375,7 +403,7 @@ void CZombie::AttackMissSound( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CZombie::PainSound( const CTakeDamageInfo &info ) { @@ -390,13 +418,13 @@ void CZombie::PainSound( const CTakeDamageInfo &info ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CZombie::DeathSound( const CTakeDamageInfo &info ) +void CZombie::DeathSound( const CTakeDamageInfo &info ) { EmitSound( "Zombie.Die" ); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CZombie::AlertSound( void ) { @@ -459,7 +487,7 @@ const char *CZombie::GetHeadcrabModel( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- const char *CZombie::GetLegsModel( void ) { @@ -524,12 +552,12 @@ void CZombie::MoanSound( envelopePoint_t *pEnvelope, int iEnvelopeSize ) //--------------------------------------------------------- bool CZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDamageThreshold ) { - if( IsSlumped() ) + if( IsSlumped() ) { // Never break apart a slouched zombie. This is because the most fun // slouched zombies to kill are ones sleeping leaning against explosive // barrels. If you break them in half in the blast, the force of being - // so close to the explosion makes the body pieces fly at ridiculous + // so close to the explosion makes the body pieces fly at ridiculous // velocities because the pieces weigh less than the whole. return false; } @@ -543,7 +571,7 @@ void CZombie::GatherConditions( void ) { BaseClass::GatherConditions(); - static int conditionsToClear[] = + static int conditionsToClear[] = { COND_BLOCKED_BY_DOOR, COND_DOOR_OPENED, @@ -552,8 +580,8 @@ void CZombie::GatherConditions( void ) ClearConditions( conditionsToClear, ARRAYSIZE( conditionsToClear ) ); - if ( m_hBlockingDoor == NULL || - ( m_hBlockingDoor->m_toggle_state == TS_AT_TOP || + if ( m_hBlockingDoor == NULL || + ( m_hBlockingDoor->m_toggle_state == TS_AT_TOP || m_hBlockingDoor->m_toggle_state == TS_GOING_UP ) ) { ClearCondition( COND_BLOCKED_BY_DOOR ); @@ -576,7 +604,7 @@ void CZombie::GatherConditions( void ) { SetCondition( COND_ZOMBIE_CHARGE_TARGET_MOVED ); } - + } } } @@ -594,7 +622,7 @@ int CZombie::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFail m_hBlockingDoor = NULL; } - if ( failedSchedule != SCHED_ZOMBIE_CHARGE_ENEMY && + if ( failedSchedule != SCHED_ZOMBIE_CHARGE_ENEMY && IsPathTaskFailure( taskFailCode ) && random->RandomInt( 1, 100 ) < 50 ) { @@ -602,7 +630,7 @@ int CZombie::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFail } if ( failedSchedule != SCHED_ZOMBIE_WANDER_ANGRILY && - ( failedSchedule == SCHED_TAKE_COVER_FROM_ENEMY || + ( failedSchedule == SCHED_TAKE_COVER_FROM_ENEMY || failedSchedule == SCHED_CHASE_ENEMY_FAILED ) ) { return SCHED_ZOMBIE_WANDER_ANGRILY; @@ -633,7 +661,7 @@ Activity CZombie::NPC_TranslateActivity( Activity newActivity ) if ( newActivity == ACT_RUN ) return ACT_WALK; - + if ( m_fIsTorso && ( newActivity == ACT_ZOMBIE_TANTRUM ) ) return ACT_IDLE; @@ -751,7 +779,7 @@ void CZombie::RunTask( const Task_t *pTask ) //--------------------------------------------------------- //--------------------------------------------------------- -bool CZombie::OnObstructingDoor( AILocalMoveGoal_t *pMoveGoal, CBaseDoor *pDoor, +bool CZombie::OnObstructingDoor( AILocalMoveGoal_t *pMoveGoal, CBaseDoor *pDoor, float distClear, AIMoveResult_t *pResult ) { if ( BaseClass::OnObstructingDoor( pMoveGoal, pDoor, distClear, pResult ) ) @@ -759,7 +787,7 @@ bool CZombie::OnObstructingDoor( AILocalMoveGoal_t *pMoveGoal, CBaseDoor *pDoor, if ( IsMoveBlocked( *pResult ) && pMoveGoal->directTrace.vHitNormal != vec3_origin ) { m_hBlockingDoor = pDoor; - m_flDoorBashYaw = UTIL_VecToYaw( pMoveGoal->directTrace.vHitNormal * -1 ); + m_flDoorBashYaw = UTIL_VecToYaw( pMoveGoal->directTrace.vHitNormal * -1 ); } return true; } @@ -880,7 +908,7 @@ bool CZombie::IsSquashed( const CTakeDamageInfo &info ) return false; } - if( info.GetDamageType() & DMG_CRUSH ) + if( info.GetDamageType() & DMG_CRUSH && info.GetInflictor() ) // Mapbase - Fixes a crash with inflictor-less crush damage { IPhysicsObject *pCrusher = info.GetInflictor()->VPhysicsGetObject(); if( pCrusher && pCrusher->GetMass() >= ZOMBIE_SQUASH_MASS && info.GetInflictor()->WorldSpaceCenter().z > EyePosition().z ) @@ -907,7 +935,7 @@ void CZombie::BuildScheduleTestBits( void ) } } - + //============================================================================= AI_BEGIN_CUSTOM_NPC( npc_zombie, CZombie ) @@ -920,12 +948,12 @@ AI_BEGIN_CUSTOM_NPC( npc_zombie, CZombie ) DECLARE_TASK( TASK_ZOMBIE_YAW_TO_DOOR ) DECLARE_TASK( TASK_ZOMBIE_ATTACK_DOOR ) DECLARE_TASK( TASK_ZOMBIE_CHARGE_ENEMY ) - + DECLARE_ACTIVITY( ACT_ZOMBIE_TANTRUM ); DECLARE_ACTIVITY( ACT_ZOMBIE_WALLPOUND ); DEFINE_SCHEDULE - ( + ( SCHED_ZOMBIE_BASH_DOOR, " Tasks" @@ -999,3 +1027,281 @@ AI_BEGIN_CUSTOM_NPC( npc_zombie, CZombie ) AI_END_CUSTOM_NPC() //============================================================================= + +#ifdef MAPBASE +class CZombieCustom : public CAI_ExpresserHost +{ + DECLARE_DATADESC(); + DECLARE_CLASS( CZombieCustom, CAI_ExpresserHost ); + +public: + CZombieCustom(); + + void Spawn( void ); + void Precache( void ); + + void SpeakIfAllowed( const char *rrConcept, AI_CriteriaSet *modifiers = NULL ); + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); + virtual CAI_Expresser *CreateExpresser( void ); + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } + virtual void PostConstructor( const char *szClassname ); + + void PainSound( const CTakeDamageInfo &info ); + void DeathSound( const CTakeDamageInfo &info ); + void AlertSound( void ); + void IdleSound( void ); + void AttackSound( void ); + + const char *GetMoanSound( int nSound ); + + void SetZombieModel( void ); + + virtual const char *GetLegsModel( void ) { return STRING(m_iszLegsModel); } + virtual const char *GetTorsoModel( void ) { return STRING(m_iszTorsoModel); } + virtual const char *GetHeadcrabClassname( void ) { return STRING(m_iszHeadcrabClassname); } + virtual const char *GetHeadcrabModel( void ) { return STRING(m_iszHeadcrabModel); } + + string_t m_iszLegsModel; + string_t m_iszTorsoModel; + string_t m_iszHeadcrabClassname; + string_t m_iszHeadcrabModel; + + CAI_Expresser *m_pExpresser; +}; + +BEGIN_DATADESC( CZombieCustom ) + + DEFINE_KEYFIELD( m_iszLegsModel, FIELD_STRING, "LegsModel" ), + DEFINE_KEYFIELD( m_iszTorsoModel, FIELD_STRING, "TorsoModel" ), + DEFINE_KEYFIELD( m_iszHeadcrabClassname, FIELD_STRING, "HeadcrabClassname" ), + DEFINE_KEYFIELD( m_iszHeadcrabModel, FIELD_STRING, "HeadcrabModel" ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( npc_zombie_custom, CZombieCustom ); +LINK_ENTITY_TO_CLASS( npc_zombie_custom_torso, CZombieCustom ); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CZombieCustom::CZombieCustom() +{ + m_iszLegsModel = AllocPooledString( CZombie::GetLegsModel() ); + m_iszTorsoModel = AllocPooledString( CZombie::GetTorsoModel() ); + m_iszHeadcrabClassname = AllocPooledString( CZombie::GetHeadcrabClassname() ); + m_iszHeadcrabModel = AllocPooledString( CZombie::GetHeadcrabModel() ); + + SetModelName( AllocPooledString("models/zombie/classic.mdl") ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::Spawn( void ) +{ + int iHealth = m_iHealth; + + BaseClass::Spawn(); + + if (iHealth > 0) + { + m_iMaxHealth = iHealth; + m_iHealth = iHealth; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::Precache( void ) +{ + BaseClass::Precache(); + + PrecacheModel(STRING(GetModelName())); + + if (m_iszLegsModel != NULL_STRING) + PrecacheModel( STRING(m_iszLegsModel) ); + + if (m_iszTorsoModel != NULL_STRING) + PrecacheModel( STRING(m_iszTorsoModel) ); + + if (m_iszHeadcrabClassname != NULL_STRING) + UTIL_PrecacheOther( STRING(m_iszHeadcrabClassname) ); + + if (m_iszHeadcrabModel != NULL_STRING) + PrecacheModel( STRING(m_iszHeadcrabModel) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::SetZombieModel( void ) +{ + Hull_t lastHull = GetHullType(); + + if ( m_fIsTorso ) + { + SetModel( GetTorsoModel() ); + SetHullType( HULL_TINY ); + } + else + { + SetModel( STRING(GetModelName()) ); + SetHullType( HULL_HUMAN ); + } + + SetBodygroup( ZOMBIE_BODYGROUP_HEADCRAB, !m_fIsHeadless ); + + SetHullSizeNormal( true ); + SetDefaultEyeOffset(); + SetActivity( ACT_IDLE ); + + // hull changed size, notify vphysics + // UNDONE: Solve this generally, systematically so other + // NPCs can change size + if ( lastHull != GetHullType() ) + { + if ( VPhysicsGetObject() ) + { + SetupVPhysicsHull(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::PainSound( const CTakeDamageInfo &info ) +{ + AI_CriteriaSet modifiers; + ModifyOrAppendDamageCriteria( modifiers, info ); + SpeakIfAllowed( TLK_ZOMBIE_PAIN, &modifiers ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::DeathSound( const CTakeDamageInfo &info ) +{ + AI_CriteriaSet modifiers; + ModifyOrAppendDamageCriteria( modifiers, info ); + SpeakIfAllowed( TLK_ZOMBIE_DEATH, &modifiers ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::AlertSound( void ) +{ + SpeakIfAllowed( TLK_ZOMBIE_ALERT ); + + // Don't let a moan sound cut off the alert sound. + m_flNextMoanSound += random->RandomFloat( 2.0, 4.0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: Returns a moan sound for this class of zombie. +//----------------------------------------------------------------------------- +const char *CZombieCustom::GetMoanSound( int nSound ) +{ + AI_CriteriaSet modifiers; + + // We could probably do this through the response system alone now, but whatever. + modifiers.AppendCriteria( "moansound", UTIL_VarArgs("%i", nSound & 4) ); + +#ifdef NEW_RESPONSE_SYSTEM + AI_Response response; + CAI_Concept rrConcept = "TLK_ZOMBIE_MOAN"; + rrConcept.SetSpeaker( this ); + if (!FindResponse( response, rrConcept, &modifiers )) + return "NPC_BaseZombie.Moan1"; +#else + AI_Response *response = SpeakFindResponse(TLK_ZOMBIE_MOAN, modifiers); + + if ( !response ) + return "NPC_BaseZombie.Moan1"; +#endif + + // Must be static so it could be returned + static char szSound[128]; +#ifdef NEW_RESPONSE_SYSTEM + response.GetName(szSound, sizeof(szSound)); +#else + response->GetName(szSound, sizeof(szSound)); + delete response; +#endif + + return szSound; +} + +//----------------------------------------------------------------------------- +// Purpose: Play a random idle sound. +//----------------------------------------------------------------------------- +void CZombieCustom::IdleSound( void ) +{ + if( GetState() == NPC_STATE_IDLE && random->RandomFloat( 0, 1 ) == 0 ) + { + // Moan infrequently in IDLE state. + return; + } + + SpeakIfAllowed( TLK_ZOMBIE_IDLE ); + MakeAISpookySound( 360.0f ); +} + +//----------------------------------------------------------------------------- +// Purpose: Play a random attack sound. +//----------------------------------------------------------------------------- +void CZombieCustom::AttackSound( void ) +{ + SpeakIfAllowed( TLK_ZOMBIE_ATTACK ); +} + +//----------------------------------------------------------------------------- +// Purpose: Speak concept +//----------------------------------------------------------------------------- +void CZombieCustom::SpeakIfAllowed(const char *rrConcept, AI_CriteriaSet *modifiers) +{ + AI_CriteriaSet empty; + Speak( rrConcept, modifiers ? *modifiers : empty ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CZombieCustom::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); + + set.AppendCriteria( "slumped", IsSlumped() ? "1" : "0" ); + + // Does this or a name already exist? + set.AppendCriteria( "onfire", IsOnFire() ? "1" : "0" ); + + // Custom zombies (and zombie torsos) must make zombie sounds. + // This can be overridden with response contexts. + set.AppendCriteria( "classname", "npc_zombie" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_Expresser *CZombieCustom::CreateExpresser( void ) +{ + m_pExpresser = new CAI_Expresser(this); + if (!m_pExpresser) + return NULL; + + m_pExpresser->Connect(this); + return m_pExpresser; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CZombieCustom::PostConstructor(const char *szClassname) +{ + BaseClass::PostConstructor(szClassname); + CreateExpresser(); +} +#endif diff --git a/game/server/hl2/npc_zombine.cpp b/game/server/hl2/npc_zombine.cpp index 479d220b..c25104d2 100644 --- a/game/server/hl2/npc_zombine.cpp +++ b/game/server/hl2/npc_zombine.cpp @@ -167,8 +167,15 @@ class CNPC_Zombine : public CAI_BlendingHost, public CDefaultPl float m_flSuperFastAttackTime; float m_flGrenadePullTime; +#ifdef MAPBASE + int m_iGrenadeCount = ZOMBINE_MAX_GRENADES; +#else int m_iGrenadeCount; +#endif +#ifdef MAPBASE + COutputEHANDLE m_OnGrenade; +#endif EHANDLE m_hGrenade; protected: @@ -184,7 +191,12 @@ BEGIN_DATADESC( CNPC_Zombine ) DEFINE_FIELD( m_flSuperFastAttackTime, FIELD_TIME ), DEFINE_FIELD( m_hGrenade, FIELD_EHANDLE ), DEFINE_FIELD( m_flGrenadePullTime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iGrenadeCount, FIELD_INTEGER, "NumGrenades" ), + DEFINE_OUTPUT( m_OnGrenade, "OnPullGrenade" ), +#else DEFINE_FIELD( m_iGrenadeCount, FIELD_INTEGER ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "StartSprint", InputStartSprint ), DEFINE_INPUTFUNC( FIELD_VOID, "PullGrenade", InputPullGrenade ), END_DATADESC() @@ -201,7 +213,9 @@ void CNPC_Zombine::Spawn( void ) Precache(); m_fIsTorso = false; +#ifndef MAPBASE // Controlled by KV m_fIsHeadless = false; +#endif #ifdef HL2_EPISODIC SetBloodColor( BLOOD_COLOR_ZOMBIE ); @@ -226,7 +240,9 @@ void CNPC_Zombine::Spawn( void ) g_flZombineGrenadeTimes = gpGlobals->curtime; m_flGrenadePullTime = gpGlobals->curtime; +#ifndef MAPBASE m_iGrenadeCount = ZOMBINE_MAX_GRENADES; +#endif } void CNPC_Zombine::Precache( void ) @@ -560,6 +576,9 @@ void CNPC_Zombine::HandleAnimEvent( animevent_t *pEvent ) pGrenade->SetParent( this, iAttachment ); pGrenade->SetDamage( 200.0f ); +#ifdef MAPBASE + m_OnGrenade.Set(pGrenade, pGrenade, this); +#endif m_hGrenade = pGrenade; EmitSound( "Zombine.ReadyGrenade" ); diff --git a/game/server/hl2/prop_combine_ball.cpp b/game/server/hl2/prop_combine_ball.cpp index b9370349..7a6f287b 100644 --- a/game/server/hl2/prop_combine_ball.cpp +++ b/game/server/hl2/prop_combine_ball.cpp @@ -227,6 +227,10 @@ BEGIN_DATADESC( CPropCombineBall ) DEFINE_INPUTFUNC( FIELD_VOID, "FadeAndRespawn", InputFadeAndRespawn ), DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ), DEFINE_INPUTFUNC( FIELD_VOID, "Socketed", InputSocketed ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLifetime", InputSetLifetime ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "AddLifetime", InputAddLifetime ), +#endif END_DATADESC() @@ -566,6 +570,10 @@ void CPropCombineBall::InputKill( inputdata_t &inputdata ) SetOwnerEntity( NULL ); } +#ifdef MAPBASE + m_OnKilled.FireOutput( inputdata.pActivator, this ); +#endif + UTIL_Remove( this ); NotifySpawnerOfRemoval(); @@ -596,6 +604,86 @@ void CPropCombineBall::InputSocketed( inputdata_t &inputdata ) NotifySpawnerOfRemoval(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropCombineBall::InputSetLifetime( inputdata_t &inputdata ) +{ + if (m_bHeld) + { + // Special handling when held + float dt = inputdata.value.Float(); + float flSoundRampTime = GetBallHoldDissolveTime() - GetBallHoldSoundRampTime(); + + if (dt > flSoundRampTime) + { + if ( m_pHoldingSound ) + { + // Reset holding sound to regular pitch + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + controller.SoundChangePitch( m_pHoldingSound, 100, flSoundRampTime ); + } + + SetContextThink( &CPropCombineBall::DissolveRampSoundThink, gpGlobals->curtime + dt - flSoundRampTime, s_pHoldDissolveContext ); + } + else + { + if ( m_pHoldingSound ) + { + // Do pitch ramp based on our custom time, which is less than the normal pitch ramp time + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + controller.SoundChangePitch( m_pHoldingSound, 150, dt ); + } + SetContextThink( &CPropCombineBall::DissolveThink, gpGlobals->curtime + dt, s_pHoldDissolveContext ); + } + } + else + { + SetContextThink( &CPropCombineBall::ExplodeThink, gpGlobals->curtime + inputdata.value.Float(), s_pExplodeTimerContext ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropCombineBall::InputAddLifetime( inputdata_t &inputdata ) +{ + if (m_bHeld) + { + // Special handling when held + float dt = (GetNextThink( s_pHoldDissolveContext ) - gpGlobals->curtime + inputdata.value.Float()); + float flSoundRampTime = GetBallHoldDissolveTime() - GetBallHoldSoundRampTime(); + + if (dt > flSoundRampTime) + { + if ( m_pHoldingSound ) + { + // Reset holding sound to regular pitch + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + controller.SoundChangePitch( m_pHoldingSound, 100, flSoundRampTime ); + } + + SetContextThink( &CPropCombineBall::DissolveRampSoundThink, gpGlobals->curtime + dt - flSoundRampTime, s_pHoldDissolveContext ); + } + else + { + if ( m_pHoldingSound ) + { + // Do pitch ramp based on our custom time, which is less than the normal pitch ramp time + CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); + controller.SoundChangePitch( m_pHoldingSound, 150, dt ); + } + SetContextThink( &CPropCombineBall::DissolveThink, gpGlobals->curtime + dt, s_pHoldDissolveContext ); + } + } + else + { + SetContextThink( &CPropCombineBall::ExplodeThink, gpGlobals->curtime + (GetNextThink( s_pExplodeTimerContext ) + inputdata.value.Float()), s_pExplodeTimerContext ); + } +} +#endif + //----------------------------------------------------------------------------- // Cleanup. //----------------------------------------------------------------------------- @@ -706,9 +794,63 @@ void CPropCombineBall::WhizSoundThink() pPhysicsObject->GetPosition( &vecPosition, NULL ); pPhysicsObject->GetVelocity( &vecVelocity, NULL ); - if ( gpGlobals->maxClients == 1 ) + // Multiplayer equivelent, loops through players and decides if it should go or not, like SP. + if ( gpGlobals->maxClients > 1 ) + { + CBasePlayer *pPlayer = NULL; + + for (int i = 1;i <= gpGlobals->maxClients; i++) + { + pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer ) + { + Vector vecDelta; + VectorSubtract( pPlayer->GetAbsOrigin(), vecPosition, vecDelta ); + VectorNormalize( vecDelta ); + if ( DotProduct( vecDelta, vecVelocity ) > 0.5f ) + { + Vector vecEndPoint; + VectorMA( vecPosition, 2.0f * TICK_INTERVAL, vecVelocity, vecEndPoint ); + float flDist = CalcDistanceToLineSegment( pPlayer->GetAbsOrigin(), vecPosition, vecEndPoint ); + if ( flDist < 200.0f ) + { + // We're basically doing what CPASAttenuationFilter does, on a per-user basis, if it passes we create the filter and send off the sound + // if it doesn't, we skip the player. + float distance, maxAudible; + Vector vecRelative; + + VectorSubtract( pPlayer->EarPosition(), vecPosition, vecRelative ); + distance = VectorLength( vecRelative ); + maxAudible = ( 2 * SOUND_NORMAL_CLIP_DIST ) / ATTN_NORM; + if ( distance <= maxAudible ) + continue; + + // Set the recipient to the player it checked against so multiple sounds don't play. + CSingleUserRecipientFilter filter( pPlayer ); + + EmitSound_t ep; + ep.m_nChannel = CHAN_STATIC; + if ( hl2_episodic.GetBool() ) + { + ep.m_pSoundName = "NPC_CombineBall_Episodic.WhizFlyby"; + } + else + { + ep.m_pSoundName = "NPC_CombineBall.WhizFlyby"; + } + ep.m_flVolume = 1.0f; + ep.m_SoundLevel = SNDLVL_NORM; + + EmitSound( filter, entindex(), ep ); + } + } + } + } + } + else { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer ) { Vector vecDelta; @@ -743,6 +885,7 @@ void CPropCombineBall::WhizSoundThink() } } } + } SetContextThink( &CPropCombineBall::WhizSoundThink, gpGlobals->curtime + 2.0f * TICK_INTERVAL, s_pWhizThinkContext ); @@ -1245,6 +1388,12 @@ void CPropCombineBall::OnHitEntity( CBaseEntity *pHitEntity, float flSpeed, int m_flNextDamageTime = gpGlobals->curtime + 0.1f; } +#ifdef MAPBASE + // Damage forces for NPC balls. + info.SetDamagePosition( GetAbsOrigin() ); + info.SetDamageForce( GetAbsVelocity() ); +#endif + pHitEntity->TakeDamage( info ); } } diff --git a/game/server/hl2/prop_combine_ball.h b/game/server/hl2/prop_combine_ball.h index 1de4390d..d750d6ad 100644 --- a/game/server/hl2/prop_combine_ball.h +++ b/game/server/hl2/prop_combine_ball.h @@ -65,6 +65,10 @@ class CPropCombineBall : public CBaseAnimating, public CDefaultPlayerPickupVPhys void InputFadeAndRespawn( inputdata_t &inputdata ); void InputKill( inputdata_t &inputdata ); void InputSocketed( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetLifetime( inputdata_t &inputdata ); + void InputAddLifetime( inputdata_t &inputdata ); +#endif enum { diff --git a/game/server/hl2/proto_sniper.cpp b/game/server/hl2/proto_sniper.cpp index fe9844eb..85c9ab33 100644 --- a/game/server/hl2/proto_sniper.cpp +++ b/game/server/hl2/proto_sniper.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -33,6 +33,13 @@ #include "effect_color_tables.h" #include "npc_rollermine.h" #include "eventqueue.h" +#ifdef MAPBASE +#include "CRagdollMagnet.h" +#endif +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE +#include "mapbase/expandedrs_combine.h" +#include "ai_speech.h" +#endif #include "effect_dispatch_data.h" #include "te_effect_dispatch.h" @@ -62,13 +69,16 @@ extern ConVar sk_dmg_sniper_penetrate_npc; #define SF_SNIPER_STARTDISABLED (1 << 19) #define SF_SNIPER_FAST (1 << 20) ///< This is faster-shooting sniper. Paint time is decreased 25%. Bullet speed increases 150%. #define SF_SNIPER_NOSWEEP (1 << 21) ///< This sniper doesn't sweep to the target or use decoys. +#ifdef MAPBASE +#define SF_SNIPER_DIE_ON_FIRE (1 << 22) // This sniper dies on fire. +#endif // If the last time I fired at someone was between 0 and this many seconds, draw // a bead on them much faster. (use subsequent paint time) #define SNIPER_FASTER_ATTACK_PERIOD 3.0f // These numbers determine the interval between shots. They used to be constants, -// but are now keyfields. HL2 backwards compatibility was maintained by supplying +// but are now keyfields. HL2 backwards compatibility was maintained by supplying // default values in the constructor. #if 0 // How long to aim at someone before shooting them. @@ -185,7 +195,7 @@ class CSniperBullet : public CBaseEntity // hit, the shooter must wait. bool m_fActive; - // This tracks how many times this single bullet has + // This tracks how many times this single bullet has // struck. This is for penetration, so the bullet can // go through things. int m_iImpacts; @@ -194,9 +204,15 @@ class CSniperBullet : public CBaseEntity //========================================================= //========================================================= +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE +class CProtoSniper : public CAI_ExpresserHost +{ + DECLARE_CLASS( CProtoSniper, CAI_ExpresserHost ); +#else class CProtoSniper : public CAI_BaseNPC { DECLARE_CLASS( CProtoSniper, CAI_BaseNPC ); +#endif public: CProtoSniper( void ); @@ -234,6 +250,10 @@ class CProtoSniper : public CAI_BaseNPC virtual int SelectSchedule( void ); virtual int TranslateSchedule( int scheduleType ); +#ifdef MAPBASE + Activity NPC_TranslateActivity( Activity eNewActivity ); +#endif + bool KeyValue( const char *szKeyName, const char *szValue ); void PrescheduleThink( void ); @@ -262,8 +282,22 @@ class CProtoSniper : public CAI_BaseNPC void NotifyShotMissedTarget(); +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + //DeclareResponseSystem() + bool SpeakIfAllowed(const char *rrConcept, const char *modifiers = NULL); + void ModifyOrAppendCriteria( AI_CriteriaSet& set ); + + virtual CAI_Expresser *CreateExpresser( void ); + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } + virtual void PostConstructor( const char *szClassname ); +#endif + private: - + +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + CAI_Expresser * m_pExpresser; +#endif + bool ShouldSnapShot( void ); void ClearTargetGroup( void ); @@ -304,6 +338,10 @@ class CProtoSniper : public CAI_BaseNPC bool IsPlayerAllySniper(); +#ifdef MAPBASE + const Vector &GetPaintCursor() { return m_vecPaintCursor; } +#endif + private: /// This is the variable from which m_flPaintTime gets set. @@ -314,7 +352,7 @@ class CProtoSniper : public CAI_BaseNPC /// to yield m_flPaintTime's initial delay. float m_flKeyfieldPaintTimeNoise; - // This keeps track of the last spot the laser painted. For + // This keeps track of the last spot the laser painted. For // continuous sweeping that changes direction. Vector m_vecPaintCursor; float m_flPaintTime; @@ -363,11 +401,19 @@ class CProtoSniper : public CAI_BaseNPC bool m_bKilledPlayer; bool m_bShootZombiesInChest; ///< if true, do not try to shoot zombies in the headcrab +#ifdef MAPBASE + string_t m_iszBeamName; // Custom beam texture + color32 m_BeamColor; // Custom beam color +#endif + COutputEvent m_OnShotFired; - + DEFINE_CUSTOM_AI; DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif }; @@ -377,13 +423,13 @@ class CProtoSniper : public CAI_BaseNPC // // PATIENCE: // The concept of "patience" is simply a restriction placed -// on how close a target has to be to the sniper before the +// on how close a target has to be to the sniper before the // sniper will take his first shot at the target. This // distance is referred to as "patience" is set by the ` -// designer in Worldcraft. The sniper won't attack unless -// the target enters this radius. Once the sniper takes +// designer in Worldcraft. The sniper won't attack unless +// the target enters this radius. Once the sniper takes // this first shot, he will not return to a patient state. -// He will then shoot at any/all targets to which there is +// He will then shoot at any/all targets to which there is // a clear shot, regardless of distance. (sjb) // // @@ -440,6 +486,11 @@ BEGIN_DATADESC( CProtoSniper ) DEFINE_FIELD( m_bWarnedTargetEntity, FIELD_BOOLEAN ), DEFINE_FIELD( m_flTimeLastShotMissed, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iszBeamName, FIELD_STRING, "BeamName" ), + DEFINE_KEYFIELD( m_BeamColor, FIELD_COLOR32, "BeamColor" ), +#endif + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "EnableSniper", InputEnableSniper ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableSniper", InputDisableSniper ), @@ -457,9 +508,29 @@ BEGIN_DATADESC( CProtoSniper ) // Outputs DEFINE_OUTPUT( m_OnShotFired, "OnShotFired" ), - + END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CProtoSniper, CAI_BaseNPC, "Combine sniper NPC." ) + + DEFINE_SCRIPTFUNC( GetBulletSpeed, "" ) + DEFINE_SCRIPTFUNC( GetBulletOrigin, "" ) + DEFINE_SCRIPTFUNC( ScopeGlint, "" ) + + DEFINE_SCRIPTFUNC( GetPositionParameter, "" ) + DEFINE_SCRIPTFUNC( IsSweepingRandomly, "" ) + DEFINE_SCRIPTFUNC( FindFrustratedShot, "" ) + + DEFINE_SCRIPTFUNC( IsLaserOn, "" ) + DEFINE_SCRIPTFUNC( LaserOn, "" ) + DEFINE_SCRIPTFUNC( LaserOff, "" ) + + DEFINE_SCRIPTFUNC( GetPaintCursor, "Get the point the sniper is currently aiming at." ) + +END_SCRIPTDESC() +#endif + //========================================================= @@ -496,6 +567,10 @@ enum Sniper_Conds COND_SNIPER_FRUSTRATED, COND_SNIPER_SWEEP_TARGET, COND_SNIPER_NO_SHOT, +#ifdef MAPBASE + // Using COND_ENEMY_DEAD made us take credit for other people's kills + COND_SNIPER_KILLED_ENEMY, +#endif }; @@ -536,9 +611,9 @@ enum -CProtoSniper::CProtoSniper( void ) : m_flKeyfieldPaintTime(SNIPER_DEFAULT_PAINT_ENEMY_TIME), +CProtoSniper::CProtoSniper( void ) : m_flKeyfieldPaintTime(SNIPER_DEFAULT_PAINT_ENEMY_TIME), m_flKeyfieldPaintTimeNoise(SNIPER_DEFAULT_PAINT_NPC_TIME_NOISE) -{ +{ #ifdef _DEBUG m_vecPaintCursor.Init(); m_vecDecoyObjectTarget.Init(); @@ -546,9 +621,9 @@ CProtoSniper::CProtoSniper( void ) : m_flKeyfieldPaintTime(SNIPER_DEFAULT_PAINT_ m_vecPaintStart.Init(); #endif - m_iMisses = 0; - m_flDecoyRadius = SNIPER_DECOY_RADIUS; - m_fSnapShot = false; + m_iMisses = 0; + m_flDecoyRadius = SNIPER_DECOY_RADIUS; + m_fSnapShot = false; m_iBeamBrightness = 100; } @@ -557,7 +632,11 @@ CProtoSniper::CProtoSniper( void ) : m_flKeyfieldPaintTime(SNIPER_DEFAULT_PAINT_ bool CProtoSniper::QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC ) { Disposition_t disp = IRelationType(pEntity); +#ifdef MAPBASE + if( disp > D_FR ) +#else if( disp != D_HT ) +#endif { // Don't bother with anything I wouldn't shoot. return false; @@ -565,7 +644,7 @@ bool CProtoSniper::QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfN if( !FInViewCone(pEntity) ) { - // Yes, this does call FInViewCone twice a frame for all entities checked for + // Yes, this does call FInViewCone twice a frame for all entities checked for // visibility, but doing this allows us to cut out a bunch of traces that would // be done by VerifyShot for entities that aren't even in our viewcone. return false; @@ -643,8 +722,13 @@ void CProtoSniper::LaserOn( const Vector &vecTarget, const Vector &vecDeviance ) { if (!m_pBeam) { +#ifdef MAPBASE + m_pBeam = CBeam::BeamCreate( STRING(m_iszBeamName), 1.0f ); + m_pBeam->SetColor( m_BeamColor.r, m_BeamColor.g, m_BeamColor.b ); +#else m_pBeam = CBeam::BeamCreate( "effects/bluelaser1.vmt", 1.0f ); m_pBeam->SetColor( 0, 100, 255 ); +#endif } else { @@ -668,7 +752,7 @@ void CProtoSniper::LaserOn( const Vector &vecTarget, const Vector &vecDeviance ) vecInitialAim.x += random->RandomFloat( -vecDeviance.x, vecDeviance.x ); vecInitialAim.y += random->RandomFloat( -vecDeviance.y, vecDeviance.y ); vecInitialAim.z += random->RandomFloat( -vecDeviance.z, vecDeviance.z ); - + // The beam is backwards, sortof. The endpoint is the sniper. This is // so that the beam can be tapered to very thin where it emits from the sniper. m_pBeam->PointsInit( vecInitialAim, GetBulletOrigin() ); @@ -683,7 +767,7 @@ void CProtoSniper::LaserOn( const Vector &vecTarget, const Vector &vecDeviance ) m_vecPaintStart = vecInitialAim; - // Think faster whilst painting. Higher resolution on the + // Think faster whilst painting. Higher resolution on the // beam movement. SetNextThink( gpGlobals->curtime + 0.02 ); } @@ -803,7 +887,7 @@ void CProtoSniper::PaintTarget( const Vector &vecTarget, float flPaintTime ) #if 1 #define THRESHOLD 0.8f float flNoiseScale; - + if ( P >= THRESHOLD ) { flNoiseScale = 1 - (1 / (1 - THRESHOLD)) * ( P - THRESHOLD ); @@ -841,7 +925,7 @@ bool CProtoSniper::IsPlayerAllySniper() return IRelationType( pPlayer ) == D_LI; } - + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CProtoSniper::InputSetDecoyRadius( inputdata_t &inputdata ) @@ -856,6 +940,14 @@ void CProtoSniper::OnScheduleChange( void ) { LaserOff(); +#ifdef MAPBASE + if ( m_bKilledPlayer && HasCondition( COND_SEE_PLAYER ) ) + { + // IMPOSSIBLE! (possible when SP respawn is enabled) + m_bKilledPlayer = false; + } +#endif + BaseClass::OnScheduleChange(); } @@ -869,7 +961,7 @@ bool CProtoSniper::KeyValue( const char *szKeyName, const char *szValue ) m_flPatience = atof(szValue); // If the designer specifies a patience radius of 0, the - // sniper won't have any patience at all. The sniper will + // sniper won't have any patience at all. The sniper will // shoot at the first target it sees regardless of distance. if( m_flPatience == 0.0 ) { @@ -898,16 +990,46 @@ LINK_ENTITY_TO_CLASS( proto_sniper, CProtoSniper ); LINK_ENTITY_TO_CLASS( sniperbullet, CSniperBullet ); //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- void CProtoSniper::Precache( void ) { +#ifdef MAPBASE + if (GetModelName() == NULL_STRING) + SetModelName(AllocPooledString("models/combine_soldier.mdl")); + + PrecacheModel(STRING(GetModelName())); + + // Should we bother to make these customizable? These are static, too. + sHaloSprite = PrecacheModel("sprites/light_glow03.vmt"); + sFlashSprite = PrecacheModel( "sprites/muzzleflash1.vmt" ); + + if (m_iszBeamName == NULL_STRING) + { + m_iszBeamName = AllocPooledString("effects/bluelaser1.vmt"); + m_BeamColor.r = 0; + m_BeamColor.g = 100; + m_BeamColor.b = 255; + } + else if (Q_GetFileExtension(STRING(m_iszBeamName)) == NULL) + { + // The path doesn't have a .vmt. Fix this or we crash! + // + // I know I warn against using .vmt even though this code ultimately ensures there is no consequence other than a warning, + // but it's bad practice and remember: That old string without the .vmt would likely be floating around somewhere doing nothing. + Warning("%s beam name \"%s\" lacks .vmt!\n", GetDebugName(), STRING(m_iszBeamName)); + m_iszBeamName = AllocPooledString(UTIL_VarArgs("%s.vmt", STRING(m_iszBeamName))); + } + + PrecacheModel(STRING(m_iszBeamName)); +#else PrecacheModel("models/combine_soldier.mdl"); sHaloSprite = PrecacheModel("sprites/light_glow03.vmt"); sFlashSprite = PrecacheModel( "sprites/muzzleflash1.vmt" ); - PrecacheModel("effects/bluelaser1.vmt"); + PrecacheModel("effects/bluelaser1.vmt"); +#endif UTIL_PrecacheOther( "sniperbullet" ); @@ -923,7 +1045,7 @@ void CProtoSniper::Precache( void ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -931,8 +1053,12 @@ void CProtoSniper::Spawn( void ) { Precache(); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else /// HACK: SetModel( "models/combine_soldier.mdl" ); +#endif //m_hBullet = (CSniperBullet *)Create( "sniperbullet", GetBulletOrigin(), GetLocalAngles(), NULL ); @@ -985,7 +1111,11 @@ void CProtoSniper::Spawn( void ) // Point the cursor straight ahead so that the sniper's // first sweep of the laser doesn't look weird. Vector vecForward; +#ifdef MAPBASE + AngleVectors( GetAbsAngles(), &vecForward ); +#else AngleVectors( GetLocalAngles(), &vecForward ); +#endif m_vecPaintCursor = GetBulletOrigin() + vecForward * 1024; m_fWeaponLoaded = true; @@ -1106,8 +1236,8 @@ void CProtoSniper::InputStopSweeping( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CProtoSniper::InputProtectTarget( inputdata_t &inputdata ) { @@ -1143,8 +1273,8 @@ void CProtoSniper::InputSetPaintIntervalVariance( inputdata_t &inputdata ) //----------------------------------------------------------------------------- -// Purpose: -// Input : *pTarget - +// Purpose: +// Input : *pTarget - // Output : int //----------------------------------------------------------------------------- int CProtoSniper::IRelationPriority( CBaseEntity *pTarget ) @@ -1171,10 +1301,10 @@ int CProtoSniper::IRelationPriority( CBaseEntity *pTarget ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // -// Output : +// Output : //----------------------------------------------------------------------------- Class_T CProtoSniper::Classify( void ) { @@ -1200,7 +1330,11 @@ Vector CProtoSniper::GetBulletOrigin( void ) else { Vector vecForward; +#ifdef MAPBASE + AngleVectors( GetAbsAngles(), &vecForward ); +#else AngleVectors( GetLocalAngles(), &vecForward ); +#endif return WorldSpaceCenter() + vecForward * 20; } } @@ -1237,14 +1371,14 @@ bool CProtoSniper::HasOldDecoy( CBaseEntity *pDecoy ) return true; } } -#endif +#endif return false; } //----------------------------------------------------------------------------- -// The list of old decoys is just a circular list. We put decoys that we've +// The list of old decoys is just a circular list. We put decoys that we've // already fired at in this list. When they've been pushed off the list by others, // then they are valid targets again. //----------------------------------------------------------------------------- @@ -1266,7 +1400,7 @@ void CProtoSniper::AddOldDecoy( CBaseEntity *pDecoy ) // Purpose: Only blast damage can hurt a sniper. // // -// Output : +// Output : //----------------------------------------------------------------------------- #define SNIPER_MAX_INFLICTOR_DIST 15.0f * 12.0f // 15 feet. int CProtoSniper::OnTakeDamage_Alive( const CTakeDamageInfo &info ) @@ -1301,9 +1435,9 @@ int CProtoSniper::OnTakeDamage_Alive( const CTakeDamageInfo &info ) float flDist = GetAbsOrigin().DistTo( info.GetInflictor()->GetAbsOrigin() ); if( flDist > SNIPER_MAX_INFLICTOR_DIST ) { - // Sniper only takes damage from explosives that are nearby. This makes a sniper + // Sniper only takes damage from explosives that are nearby. This makes a sniper // susceptible to a grenade that lands in his nest, but not to a large explosion - // that goes off elsewhere and just happens to be able to trace into the sniper's + // that goes off elsewhere and just happens to be able to trace into the sniper's // nest. return 0; } @@ -1321,18 +1455,39 @@ int CProtoSniper::OnTakeDamage_Alive( const CTakeDamageInfo &info ) // sniper was blasted out of his nest. // // -// Output : +// Output : //----------------------------------------------------------------------------- void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) { if( !(m_spawnflags & SF_SNIPER_NOCORPSE) ) { +#ifdef MAPBASE + Vector vecForce; + + // See if there's a ragdoll magnet that should influence our force. + // However, to avoid conflicts with existing maps, only allow magnets that have us as their target. + CRagdollMagnet *pMagnet = CRagdollMagnet::FindBestMagnet( this ); + if( pMagnet && pMagnet->m_target == GetEntityName() ) + { + vecForce = pMagnet->GetForceVector( this ); + pMagnet->m_OnUsed.Set(vecForce, this, pMagnet); + } + else + { + Vector vecForward; + AngleVectors( GetAbsAngles(), &vecForward ); + float flForce = random->RandomFloat( 500, 700 ) * 10; + + vecForce = (vecForward * flForce) + Vector(0, 0, 600); + } +#else Vector vecForward; - + float flForce = random->RandomFloat( 500, 700 ) * 10; AngleVectors( GetLocalAngles(), &vecForward ); - +#endif + float flFadeTime = 0.0; if( HasSpawnFlags( SF_NPC_FADE_CORPSE ) ) @@ -1341,8 +1496,13 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) } CBaseEntity *pGib; +#ifdef MAPBASE + bool bShouldIgnite = IsOnFire() || HasSpawnFlags(SF_SNIPER_DIE_ON_FIRE); + pGib = CreateRagGib( STRING(GetModelName()), GetAbsOrigin(), GetAbsAngles(), vecForce, flFadeTime, bShouldIgnite ); +#else bool bShouldIgnite = IsOnFire() || hl2_episodic.GetBool(); pGib = CreateRagGib( "models/combine_soldier.mdl", GetLocalOrigin(), GetLocalAngles(), (vecForward * flForce) + Vector(0, 0, 600), flFadeTime, bShouldIgnite ); +#endif } @@ -1357,7 +1517,11 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) LaserOff(); +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + SpeakIfAllowed( TLK_SNIPER_DIE ); +#else EmitSound( "NPC_Sniper.Die" ); +#endif UTIL_Remove( this ); } @@ -1366,6 +1530,13 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) //--------------------------------------------------------- void CProtoSniper::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) { +#ifdef MAPBASE + BaseClass::Event_KilledOther( pVictim, info ); + + if (pVictim == GetEnemy()) + SetCondition(COND_SNIPER_KILLED_ENEMY); +#endif + if( pVictim && pVictim->IsPlayer() ) { m_bKilledPlayer = true; @@ -1384,10 +1555,18 @@ void CProtoSniper::UpdateOnRemove( void ) //--------------------------------------------------------- int CProtoSniper::SelectSchedule ( void ) { +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + if (HasCondition(COND_SNIPER_KILLED_ENEMY)) + { + SpeakIfAllowed(TLK_SNIPER_TARGETDESTROYED); + ClearCondition(COND_SNIPER_KILLED_ENEMY); + } +#else if( HasCondition(COND_ENEMY_DEAD) && sniperspeak.GetBool() ) { EmitSound( "NPC_Sniper.TargetDestroyed" ); } +#endif if( !m_fWeaponLoaded ) { @@ -1402,7 +1581,7 @@ int CProtoSniper::SelectSchedule ( void ) return SCHED_PSNIPER_PLAYER_DEAD; } } - + if( HasCondition( COND_HEAR_DANGER ) ) { // Next priority is to be suppressed! @@ -1420,10 +1599,14 @@ int CProtoSniper::SelectSchedule ( void ) // probably won't harm him. // Also, don't play the sound effect if we're an ally. +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE + SpeakIfAllowed(TLK_SNIPER_DANGER); +#else if ( IsPlayerAllySniper() == false ) { EmitSound( "NPC_Sniper.HearDanger" ); } +#endif } return SCHED_PSNIPER_SUPPRESSED; @@ -1584,7 +1767,7 @@ bool CProtoSniper::FindDecoyObject( void ) Vector vecDelta; m_hDecoyObject = NULL; - + for( i = 0 ; i < SNIPER_NUM_DECOYS ; i++ ) { pDecoys[ i ] = NULL; @@ -1596,7 +1779,7 @@ bool CProtoSniper::FindDecoyObject( void ) count = UTIL_EntitiesInBox( pList, SEARCH_DEPTH, vecTarget - vecDelta, vecTarget + vecDelta, 0 ); - // Now we have the list of entities near the target. + // Now we have the list of entities near the target. // Dig through that list and build the list of decoys. int iIterator = 0; @@ -1609,7 +1792,7 @@ bool CProtoSniper::FindDecoyObject( void ) if( !pCurrent->VPhysicsGetObject() ) continue; - if( pCurrent->VPhysicsGetObject()->GetMass() > SNIPER_DECOY_MAX_MASS ) + if( pCurrent->VPhysicsGetObject()->GetMass() > SNIPER_DECOY_MAX_MASS ) { // Skip this very heavy object. Probably a car or dumpster. continue; @@ -1626,7 +1809,7 @@ bool CProtoSniper::FindDecoyObject( void ) } } - // This item meets criteria for a decoy object to shoot at. + // This item meets criteria for a decoy object to shoot at. // But have we shot at this item recently? If we HAVE, don't add it. #if 0 @@ -1654,7 +1837,7 @@ bool CProtoSniper::FindDecoyObject( void ) // try 4 times to pick a random object from the list // and trace to it. If the trace goes off, that's the object! - + for( i = 0 ; i < 4 ; i++ ) { CBaseEntity *pProspect; @@ -1670,16 +1853,16 @@ bool CProtoSniper::FindDecoyObject( void ) vecBulletOrigin = GetBulletOrigin(); pProspect->CollisionProp()->RandomPointInBounds( Vector( .1, .1, .1 ), Vector( .6, .6, .6 ), &vecDecoyTarget ); - // When trying to trace to an object using its absmin + some fraction of its size, it's best + // When trying to trace to an object using its absmin + some fraction of its size, it's best // to lengthen the trace a little beyond the object's bounding box in case it's a more complex - // object, or not axially aligned. + // object, or not axially aligned. vecDirToDecoy = vecDecoyTarget - vecBulletOrigin; VectorNormalize(vecDirToDecoy); - + // Right now, tracing with MASK_BLOCKLOS and checking the fraction as well as the object the trace - // has hit makes it possible for the decoy behavior to shoot through glass. - UTIL_TraceLine( vecBulletOrigin, vecDecoyTarget + vecDirToDecoy * 32, + // has hit makes it possible for the decoy behavior to shoot through glass. + UTIL_TraceLine( vecBulletOrigin, vecDecoyTarget + vecDirToDecoy * 32, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr); if( tr.m_pEnt == pProspect || tr.fraction == 1.0 ) @@ -1735,8 +1918,8 @@ bool CProtoSniper::VerifyShot( CBaseEntity *pTarget ) { if( pTarget->IsPlayer() ) { - // if the target is the player, do another trace to see if we can shoot his eyeposition. This should help - // improve sniper responsiveness in cases where the player is hiding his chest from the sniper with his + // if the target is the player, do another trace to see if we can shoot his eyeposition. This should help + // improve sniper responsiveness in cases where the player is hiding his chest from the sniper with his // head in full view. UTIL_TraceLine( GetBulletOrigin(), pTarget->EyePosition(), MASK_SHOT, pTarget, COLLISION_GROUP_NONE, &tr ); @@ -1795,7 +1978,11 @@ int CProtoSniper::RangeAttack1Conditions ( float flDot, float flDist ) float flDist; +#ifdef MAPBASE + flDist = ( GetAbsOrigin() - GetEnemy()->GetAbsOrigin() ).Length2D(); +#else flDist = ( GetLocalOrigin() - GetEnemy()->GetLocalOrigin() ).Length2D(); +#endif if( flDist <= m_flPatience ) { @@ -1822,7 +2009,7 @@ int CProtoSniper::RangeAttack1Conditions ( float flDot, float flDist ) // If I don't have a decoy, try to find one and shoot it. return COND_SNIPER_CANATTACKDECOY; } - + if( fFrustration >= 2.5 ) { @@ -1837,7 +2024,7 @@ int CProtoSniper::RangeAttack1Conditions ( float flDot, float flDist ) //--------------------------------------------------------- //--------------------------------------------------------- -int CProtoSniper::TranslateSchedule( int scheduleType ) +int CProtoSniper::TranslateSchedule( int scheduleType ) { switch( scheduleType ) { @@ -1861,6 +2048,23 @@ int CProtoSniper::TranslateSchedule( int scheduleType ) return BaseClass::TranslateSchedule( scheduleType ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CProtoSniper::NPC_TranslateActivity( Activity eNewActivity ) +{ + // ACT_IDLE is now just the soldier's unarmed idle animation. + // Use a gun-holding animation like what unhidden snipers were using before. + if (!HasSpawnFlags( SF_SNIPER_HIDDEN ) && eNewActivity == ACT_IDLE) + { + eNewActivity = ACT_IDLE_SMG1; + } + + return BaseClass::NPC_TranslateActivity( eNewActivity ); +} +#endif + //--------------------------------------------------------- //--------------------------------------------------------- void CProtoSniper::ScopeGlint() @@ -1878,12 +2082,12 @@ void CProtoSniper::ScopeGlint() //--------------------------------------------------------- // This starts the bullet state machine. The actual effects -// of the bullet will happen later. This function schedules +// of the bullet will happen later. This function schedules // those effects. // // fDirectShot indicates whether the bullet is a "direct shot" // that is - fired with the intent that it will strike the -// enemy. Otherwise, the bullet is intended to strike a +// enemy. Otherwise, the bullet is intended to strike a // decoy object or nothing at all in particular. //--------------------------------------------------------- bool CProtoSniper::FireBullet( const Vector &vecTarget, bool bDirectShot ) @@ -1893,7 +2097,11 @@ bool CProtoSniper::FireBullet( const Vector &vecTarget, bool bDirectShot ) vecBulletOrigin = GetBulletOrigin(); +#ifdef MAPBASE + pBullet = (CSniperBullet *)Create( "sniperbullet", GetBulletOrigin(), GetAbsAngles(), NULL ); +#else pBullet = (CSniperBullet *)Create( "sniperbullet", GetBulletOrigin(), GetLocalAngles(), NULL ); +#endif Assert( pBullet != NULL ); @@ -1910,7 +2118,7 @@ bool CProtoSniper::FireBullet( const Vector &vecTarget, bool bDirectShot ) CPVSFilter filter( vecBulletOrigin ); te->Sprite( filter, 0.0, &vecBulletOrigin, sFlashSprite, 0.3, 255 ); - + // force a reload when we're done m_fWeaponLoaded = false; @@ -1974,7 +2182,7 @@ void CProtoSniper::StartTask( const Task_t *pTask ) // We fall through to RunTask() which will keep trying to take // the shot until the weapon is ready to fire. In some rare cases, // the weapon may be ready to fire before the single bullet allocated - // to the sniper has hit its target. + // to the sniper has hit its target. break; case TASK_RANGE_ATTACK2: @@ -1989,15 +2197,23 @@ void CProtoSniper::StartTask( const Task_t *pTask ) } SetWait( m_hSweepTarget->m_flSpeed ); - + // Snap directly to this target if this spawnflag is set. // Otherwise, sweep from wherever the cursor was. if( m_hSweepTarget->HasSpawnFlags( SF_SNIPERTARGET_SNAPTO ) ) { +#ifdef MAPBASE + m_vecPaintCursor = m_hSweepTarget->GetAbsOrigin(); +#else m_vecPaintCursor = m_hSweepTarget->GetLocalOrigin(); +#endif } +#ifdef MAPBASE + LaserOn( m_hSweepTarget->GetAbsOrigin(), vec3_origin ); +#else LaserOn( m_hSweepTarget->GetLocalOrigin(), vec3_origin ); +#endif break; case TASK_SNIPER_PAINT_ENEMY: @@ -2043,7 +2259,7 @@ void CProtoSniper::StartTask( const Task_t *pTask ) } else { - m_flPaintTime = m_flKeyfieldPaintTimeNoise > 0 ? + m_flPaintTime = m_flKeyfieldPaintTimeNoise > 0 ? m_flKeyfieldPaintTime + random->RandomFloat( 0, m_flKeyfieldPaintTimeNoise ) : m_flKeyfieldPaintTime ; @@ -2066,12 +2282,16 @@ void CProtoSniper::StartTask( const Task_t *pTask ) else { // Try to start the laser where the player can't miss seeing it! +#ifdef MAPBASE + AngleVectors( GetEnemy()->GetAbsAngles(), &vecCursor ); +#else AngleVectors( GetEnemy()->GetLocalAngles(), &vecCursor ); +#endif vecCursor = vecCursor * 300; - vecCursor += GetEnemy()->EyePosition(); + vecCursor += GetEnemy()->EyePosition(); LaserOn( vecCursor, Vector( 16, 16, 16 ) ); } - + } // Scope glints if shooting at player. @@ -2200,7 +2420,11 @@ void CProtoSniper::RunTask( const Task_t *pTask ) if ( m_hSweepTarget->HasSpawnFlags( SF_SNIPERTARGET_SHOOTME ) ) { +#ifdef MAPBASE + FireBullet( m_hSweepTarget->GetAbsOrigin(), false ); +#else FireBullet( m_hSweepTarget->GetLocalOrigin(), false ); +#endif TaskComplete(); // Force a reload. } @@ -2209,7 +2433,11 @@ void CProtoSniper::RunTask( const Task_t *pTask ) // Bump the timer up, update the cursor, paint the new target! // This is done regardless of whether we just fired at the current target. +#ifdef MAPBASE + m_vecPaintCursor = m_hSweepTarget->GetAbsOrigin(); +#else m_vecPaintCursor = m_hSweepTarget->GetLocalOrigin(); +#endif if( IsSweepingRandomly() ) { // If sweeping randomly, just pick another target. @@ -2240,7 +2468,7 @@ void CProtoSniper::RunTask( const Task_t *pTask ) m_hSweepTarget = NULL; LaserOff(); TaskComplete(); - } + } #if 0 NDebugOverlay::Line(GetBulletOrigin(), m_hSweepTarget->GetLocalOrigin(), 0,255,0, true, 20 ); @@ -2280,7 +2508,7 @@ void CProtoSniper::RunTask( const Task_t *pTask ) if( IsWaitFinished() ) { //HACKHACK(sjb) - // This condition should be turned off + // This condition should be turned off // by a task. ClearCondition( COND_SNIPER_NO_SHOT ); TaskComplete(); @@ -2333,7 +2561,7 @@ int CProtoSniper::Restore( IRestore &restore ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // // //----------------------------------------------------------------------------- @@ -2347,7 +2575,7 @@ float CProtoSniper::MaxYawSpeed( void ) void CProtoSniper::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); - + // If a sweep target is set, keep asking the AI to sweep the target if( m_hSweepTarget != NULL ) { @@ -2399,7 +2627,11 @@ Vector CProtoSniper::EyePosition( void ) { if( m_spawnflags & SF_SNIPER_HIDDEN ) { +#ifdef MAPBASE + return GetAbsOrigin(); +#else return GetLocalOrigin(); +#endif } else { @@ -2414,6 +2646,19 @@ Vector CProtoSniper::DesiredBodyTarget( CBaseEntity *pTarget ) // By default, aim for the center Vector vecTarget = pTarget->WorldSpaceCenter(); +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope(m_ScriptScope)) + { + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { GetBulletOrigin(), ToHScript( pTarget ) }; + if (g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args )) + { + if (functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f) + return *functionReturn.m_pVector; + } + } +#endif + float flTimeSinceLastMiss = gpGlobals->curtime - m_flTimeLastShotMissed; if( pTarget->GetFlags() & FL_CLIENT ) @@ -2499,8 +2744,8 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) // Get bullet time to target targetDist = (vecTarget - GetBulletOrigin() ).Length(); targetTime = targetDist / GetBulletSpeed(); - - // project target's velocity over that time. + + // project target's velocity over that time. Vector vecVelocity = vec3_origin; if( pTarget->IsPlayer() || pTarget->Classify() == CLASS_MISSILE ) @@ -2538,7 +2783,11 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) vecAngle.x = 0; vecAngle.z = 0; +#ifdef MAPBASE + vecAngle.y += pTarget->GetAbsAngles().y; +#else vecAngle.y += pTarget->GetLocalAngles().y; +#endif AngleVectors( vecAngle, &vecVelocity ); @@ -2550,7 +2799,7 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) { // I'm supposed to miss this shot, so aim above the target's head. // BUT DON'T miss bullseyes, and don't count the shot. - vecAdjustedShot = vecTarget; + vecAdjustedShot = vecTarget; vecAdjustedShot.z += 16; m_iMisses--; @@ -2563,7 +2812,7 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) vecAdjustedShot = vecTarget + ( vecVelocity * targetTime ); // if the adjusted shot falls well short of the target, take the straight shot. - // it's not very interesting for the bullet to hit something far away from the + // it's not very interesting for the bullet to hit something far away from the // target. (for instance, if a sign or ledge or something is between the player // and the sniper, and the sniper would hit this object if he tries to lead the player) @@ -2573,7 +2822,11 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) { Vector vecBulletOrigin; vecBulletOrigin = GetBulletOrigin(); +#ifdef MAPBASE + CPVSFilter filter( GetAbsOrigin() ); +#else CPVSFilter filter( GetLocalOrigin() ); +#endif te->ShowLine( filter, 0.0, &vecBulletOrigin, &vecAdjustedShot ); } @@ -2615,7 +2868,7 @@ CBaseEntity *CProtoSniper::PickDeadPlayerTarget() { int i; - // Try a few times to randomly select a target. + // Try a few times to randomly select a target. for( i = 0 ; i < 10 ; i++ ) { CBaseEntity *pCandidate = pEntities[ random->RandomInt(0, iNumEntities - 1) ]; @@ -2668,7 +2921,7 @@ bool CProtoSniper::FindFrustratedShot( float flNoise ) } // Just pick a spot somewhere around the target. - // Try a handful of times to pick a spot that guarantees the + // Try a handful of times to pick a spot that guarantees the // target will see the laser. #define MAX_TRIES 15 for( int i = 0 ; i < MAX_TRIES ; i++ ) @@ -2692,7 +2945,7 @@ bool CProtoSniper::FindFrustratedShot( float flNoise ) Vector vecSrc, vecDir; - vecSrc = GetAbsOrigin(); + vecSrc = GetAbsOrigin(); vecDir = vecSpot - vecSrc; VectorNormalize( vecDir ); @@ -2725,7 +2978,7 @@ bool CProtoSniper::FindFrustratedShot( float flNoise ) //--------------------------------------------------------- // See all NPC's easily. // -// Only see the player if you can trace to both of his +// Only see the player if you can trace to both of his // eyeballs. That is, allow the player to peek around corners. // This is a little more expensive than the base class' check! //--------------------------------------------------------- @@ -2760,7 +3013,7 @@ bool CProtoSniper::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** if( fabs( GetAbsOrigin().z - pEntity->WorldSpaceCenter().z ) <= 120.f ) { - // If the player is around the same elevation, look straight at his eyes. + // If the player is around the same elevation, look straight at his eyes. // At the same elevation, the vertical peeking allowance makes it too easy // for a player to dispatch the sniper from cover. vecVerticalOffset = vec3_origin; @@ -2772,7 +3025,11 @@ bool CProtoSniper::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** vecVerticalOffset = SNIPER_TARGET_VERTICAL_OFFSET; } +#ifdef MAPBASE + AngleVectors( pEntity->GetAbsAngles(), NULL, &vecRight, NULL ); +#else AngleVectors( pEntity->GetLocalAngles(), NULL, &vecRight, NULL ); +#endif vecEye = vecRight * SNIPER_EYE_DIST - vecVerticalOffset; UTIL_TraceLine( EyePosition(), pEntity->EyePosition() + vecEye, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr ); @@ -2796,7 +3053,7 @@ bool CProtoSniper::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** #if 0 NDebugOverlay::Line(EyePosition(), tr.endpos, 0,255,0, true, 0.1); -#endif +#endif if( tr.fraction != 1.0 ) { @@ -2809,9 +3066,9 @@ bool CProtoSniper::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** // Can see the player. return true; } - + // Now, if the check failed, see if the player is ducking and has recently - // fired a muzzleflash. If yes, see if you'd be able to see the player if + // fired a muzzleflash. If yes, see if you'd be able to see the player if // they were standing in their current position instead of ducking. Since // the sniper doesn't have a clear shot in this situation, he will harrass // near the player. @@ -2890,7 +3147,7 @@ int CProtoSniper::DrawDebugTextOverlays() //----------------------------------------------------------------------------- // Inform the sniper that a bullet missed its intended target. We don't know -// which bullet or which target. +// which bullet or which target. //----------------------------------------------------------------------------- void CProtoSniper::NotifyShotMissedTarget() { @@ -2901,6 +3158,52 @@ void CProtoSniper::NotifyShotMissedTarget() // in these NPCs' walk and run animations. } +#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE +//----------------------------------------------------------------------------- +// Purpose: Speak concept +//----------------------------------------------------------------------------- +bool CProtoSniper::SpeakIfAllowed(const char *rrConcept, const char *modifiers) +{ + if (!GetExpresser()->CanSpeakConcept(rrConcept)) + return false; + + return Speak(rrConcept, modifiers); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CProtoSniper::ModifyOrAppendCriteria( AI_CriteriaSet& set ) +{ + BaseClass::ModifyOrAppendCriteria( set ); + + // We still need this + set.AppendCriteria( "sniperspeak", UTIL_VarArgs("%i", sniperspeak.GetInt()) ); + set.AppendCriteria( "playerally", UTIL_VarArgs("%d", IsPlayerAllySniper()) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_Expresser *CProtoSniper::CreateExpresser( void ) +{ + m_pExpresser = new CAI_Expresser(this); + if (!m_pExpresser) + return NULL; + + m_pExpresser->Connect(this); + return m_pExpresser; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CProtoSniper::PostConstructor(const char *szClassname) +{ + BaseClass::PostConstructor(szClassname); + CreateExpresser(); +} +#endif + //----------------------------------------------------------------------------- // // Schedules @@ -2914,8 +3217,11 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper ) DECLARE_CONDITION( COND_SNIPER_ENABLED ); DECLARE_CONDITION( COND_SNIPER_DISABLED ); DECLARE_CONDITION( COND_SNIPER_FRUSTRATED ); - DECLARE_CONDITION( COND_SNIPER_SWEEP_TARGET ); - DECLARE_CONDITION( COND_SNIPER_NO_SHOT ); + DECLARE_CONDITION( COND_SNIPER_SWEEP_TARGET ); + DECLARE_CONDITION( COND_SNIPER_NO_SHOT ); +#ifdef MAPBASE + DECLARE_CONDITION( COND_SNIPER_KILLED_ENEMY ); +#endif DECLARE_TASK( TASK_SNIPER_FRUSTRATED_ATTACK ); DECLARE_TASK( TASK_SNIPER_PAINT_ENEMY ); @@ -2983,7 +3289,7 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper ) " COND_HEAR_DANGER" " COND_SNIPER_DISABLED" ) - + //========================================================= // ATTACK //========================================================= @@ -3141,6 +3447,7 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper ) //========================================================= //========================================================= +#ifdef MAPBASE DEFINE_SCHEDULE ( SCHED_PSNIPER_PLAYER_DEAD, @@ -3149,7 +3456,19 @@ AI_BEGIN_CUSTOM_NPC( proto_sniper, CProtoSniper ) " TASK_SNIPER_PLAYER_DEAD 0" " " " Interrupts" + " COND_SEE_PLAYER" ) +#else + DEFINE_SCHEDULE + ( + SCHED_PSNIPER_PLAYER_DEAD, + + " Tasks" + " TASK_SNIPER_PLAYER_DEAD 0" + " " + " Interrupts" + ) +#endif AI_END_CUSTOM_NPC() @@ -3232,12 +3551,12 @@ void CSniperBullet::BulletThink( void ) #ifdef HL2_EPISODIC if( tr.m_pEnt->IsNPC() || m_iImpacts == NUM_PENETRATIONS ) -#else +#else if( tr.m_pEnt->m_takedamage == DAMAGE_YES || m_iImpacts == NUM_PENETRATIONS ) #endif//HL2_EPISODIC { // Bullet stops when it hits an NPC, or when it has penetrated enough times. - + if( tr.m_pEnt && tr.m_pEnt->VPhysicsGetObject() ) { if( tr.m_pEnt->VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) @@ -3253,9 +3572,9 @@ void CSniperBullet::BulletThink( void ) { #define STEP_SIZE 2 #define NUM_STEPS 6 - // Try to slide a 'cursor' through the object that was hit. + // Try to slide a 'cursor' through the object that was hit. Vector vecCursor = tr.endpos; - + for( int i = 0 ; i < NUM_STEPS ; i++ ) { //Msg("-"); @@ -3263,7 +3582,7 @@ void CSniperBullet::BulletThink( void ) if( UTIL_PointContents( vecCursor ) != CONTENTS_SOLID ) { - // Passed out of a solid! + // Passed out of a solid! SetAbsOrigin( vecCursor ); // Fire another tracer. @@ -3306,13 +3625,13 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa // This guy doesn't have a REAL weapon, per say, but he does fire // sniper rounds. Since there's no weapon to index the ammo type, // do it manually here. - m_AmmoType = GetAmmoDef()->Index("SniperRound"); + m_AmmoType = GetAmmoDef()->Index("SniperRound"); // This is the bullet that is used for all subsequent FireBullets() calls after the first // call penetrates a surface and keeps going. m_PenetratedAmmoType = GetAmmoDef()->Index("SniperPenetratedRound"); } - + if( m_fActive ) { return false; @@ -3345,7 +3664,7 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa float flElapsedTime = ( (tr.startpos - tr.endpos).Length() / m_Speed ); m_SoundTime = gpGlobals->curtime + flElapsedTime * 0.5; - + SetThink( &CSniperBullet::BulletThink ); SetNextThink( gpGlobals->curtime ); m_fActive = true; @@ -3363,13 +3682,13 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa trace_t tr; - + // Elapsed time counts how long the bullet is in motion through this simulation. float flElapsedTime = 0; for( i = 0 ; i < NUM_PENETRATIONS ; i++ ) { - // Trace to the target. + // Trace to the target. UTIL_TraceLine( GetAbsOrigin(), vecTarget, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); flShotDist = (tr.endpos - GetAbsOrigin()).Length(); @@ -3392,7 +3711,7 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa pEnt = tr.m_pEnt; if( !pEnt || - pEnt->MyNPCPointer() || + pEnt->MyNPCPointer() || UTIL_DistApprox2D( tr.endpos, vecTarget ) <= 4 || FClassnameIs( pEnt, "prop_physics" ) ) { @@ -3407,7 +3726,7 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa break; } - // We're going to try to penetrate whatever the bullet has hit. + // We're going to try to penetrate whatever the bullet has hit. // Push through the object by the penetration distance, then trace back. Vector vecCursor; @@ -3427,14 +3746,14 @@ bool CSniperBullet::Start( const Vector &vecOrigin, const Vector &vecTarget, CBa break; } #endif - + // Now put the bullet at this point and continue. UTIL_SetOrigin( this, vecCursor ); } //------------------------------- //------------------------------- -*/ - +*/ + /* #ifdef SNIPER_DEBUG @@ -3457,8 +3776,8 @@ void CSniperBullet::Init( void ) #endif // SNIPER_DEBUG m_fActive = false; - m_vecDir.Init(); - m_AmmoType = -1; + m_vecDir.Init(); + m_AmmoType = -1; m_SoundTime = 1e9; m_iImpacts = 0; } diff --git a/game/server/hl2/script_intro.cpp b/game/server/hl2/script_intro.cpp index 2798af2c..6ac28e10 100644 --- a/game/server/hl2/script_intro.cpp +++ b/game/server/hl2/script_intro.cpp @@ -46,6 +46,13 @@ BEGIN_DATADESC(CScriptIntro) DEFINE_KEYFIELD( m_bAlternateFOV, FIELD_BOOLEAN, "alternatefovchange" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDrawSky, FIELD_BOOLEAN, "DrawSky" ), + DEFINE_KEYFIELD( m_bDrawSky2, FIELD_BOOLEAN, "DrawSky2" ), + + DEFINE_KEYFIELD( m_bUseEyePosition, FIELD_BOOLEAN, "UseEyePosition" ), +#endif + // Inputs DEFINE_INPUTFUNC(FIELD_STRING, "SetCameraViewEntity", InputSetCameraViewEntity ), DEFINE_INPUTFUNC(FIELD_INTEGER, "SetBlendMode", InputSetBlendMode ), @@ -58,6 +65,10 @@ BEGIN_DATADESC(CScriptIntro) DEFINE_INPUTFUNC(FIELD_VOID, "Deactivate", InputDeactivate ), DEFINE_INPUTFUNC(FIELD_STRING, "FadeTo", InputFadeTo ), DEFINE_INPUTFUNC(FIELD_STRING, "SetFadeColor", InputSetFadeColor ), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetDrawSky", InputSetDrawSky ), + DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetDrawSky2", InputSetDrawSky2 ), +#endif DEFINE_THINKFUNC( BlendComplete ), @@ -71,7 +82,11 @@ IMPLEMENT_SERVERCLASS_ST( CScriptIntro, DT_ScriptIntro ) SendPropFloat( SENDINFO( m_flNextBlendTime ), 10 ), SendPropFloat( SENDINFO( m_flBlendStartTime ), 10 ), SendPropBool( SENDINFO( m_bActive ) ), - +#ifdef MAPBASE + SendPropBool( SENDINFO( m_bDrawSky ) ), + SendPropBool( SENDINFO( m_bDrawSky2 ) ), + SendPropBool( SENDINFO( m_bUseEyePosition ) ), +#endif // Fov & fov blends SendPropInt( SENDINFO( m_iFOV ), 9 ), @@ -394,3 +409,256 @@ void CScriptIntro::InputSetFadeColor( inputdata_t &inputdata ) m_flFadeColor.Set( 1, flG ); m_flFadeColor.Set( 2, flB ); } + +#ifdef MAPBASE +class CPlayerViewProxy : public CBaseEntity +{ +public: + DECLARE_CLASS( CPlayerViewProxy, CBaseEntity ); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CPlayerViewProxy(); + + void Spawn( void ); + int UpdateTransmitState( void ); + + void ActivateEnt( CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ); + void DeactivateEnt(); + void MeasureThink(); + + Vector EyePosition( void ); // position of eyes + const QAngle &EyeAngles( void ); // Direction of eyes in world space + const QAngle &LocalEyeAngles( void ); // Direction of eyes + Vector EarPosition( void ); // position of ears + + // Inputs + void InputActivate( inputdata_t &inputdata ); + void InputDeactivate( inputdata_t &inputdata ); + +#ifdef MAPBASE_MP + // TODO: Mapbase MP should use reception filter or something to determine which player's eye position is offset + CNetworkVar( CHandle, m_hPlayer ); +#else + CHandle m_hPlayer; +#endif + + string_t m_iszMeasureReference; + EHANDLE m_hMeasureReference; + string_t m_iszTargetReference; + EHANDLE m_hTargetReference; + + CNetworkVar( float, m_flScale ); + + CNetworkVar( bool, m_bEnabled ); +}; + +LINK_ENTITY_TO_CLASS( info_player_view_proxy, CPlayerViewProxy ); + +BEGIN_DATADESC( CPlayerViewProxy ) + + // Keys + DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iszMeasureReference, FIELD_STRING, "MeasureReference" ), + DEFINE_FIELD( m_hMeasureReference, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iszTargetReference, FIELD_STRING, "TargetReference" ), + DEFINE_FIELD( m_hTargetReference, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_flScale, FIELD_FLOAT, "TargetScale" ), + DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "Enabled" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), + + DEFINE_THINKFUNC( MeasureThink ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CPlayerViewProxy, DT_PlayerViewProxy ) +#ifdef MAPBASE_MP + SendPropEHandle( SENDINFO( m_hPlayer ) ), +#endif + SendPropBool( SENDINFO( m_bEnabled ) ), +END_SEND_TABLE() + +CPlayerViewProxy::CPlayerViewProxy() +{ + m_flScale = 1.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerViewProxy::Spawn( void ) +{ + if (m_bEnabled) + ActivateEnt(); +} + +//------------------------------------------------------------------------------ +// Purpose : Send even though we don't have a model. +//------------------------------------------------------------------------------ +int CPlayerViewProxy::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerViewProxy::MeasureThink( void ) +{ + if (m_hPlayer.Get() == NULL) + { + // Player has disappeared! Stopping measure + return; + } + + if (m_bEnabled && m_hMeasureReference.Get() && m_hTargetReference.Get()) + { + matrix3x4_t matRefToMeasure, matWorldToMeasure; + MatrixInvert( m_hPlayer.Get()->EntityToWorldTransform(), matWorldToMeasure ); + ConcatTransforms( matWorldToMeasure, m_hMeasureReference.Get()->EntityToWorldTransform(), matRefToMeasure ); + + // Apply the scale factor + if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) + { + Vector vecTranslation; + MatrixGetColumn( matRefToMeasure, 3, vecTranslation ); + vecTranslation /= m_flScale; + MatrixSetColumn( vecTranslation, 3, matRefToMeasure ); + } + + // Now apply the new matrix to the new reference point + matrix3x4_t matMeasureToRef, matNewTargetToWorld; + MatrixInvert( matRefToMeasure, matMeasureToRef ); + ConcatTransforms( m_hTargetReference.Get()->EntityToWorldTransform(), matMeasureToRef, matNewTargetToWorld ); + + Vector vecOrigin; + QAngle angAngles; + MatrixAngles( matNewTargetToWorld, angAngles, vecOrigin ); + Teleport( &vecOrigin, &angAngles, NULL ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } + //else + //{ + // SetAbsOrigin( m_hPlayer.Get()->GetAbsOrigin() ); + // SetAbsAngles( m_hPlayer.Get()->GetAbsAngles() ); + //} +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Vector CPlayerViewProxy::EyePosition( void ) +{ + if (m_hPlayer.Get()) + { + //Vector vecPlayerOffset = m_hPlayer.Get()->EyePosition() - m_hPlayer.Get()->GetAbsOrigin(); + //return GetAbsOrigin() + vecPlayerOffset; + + Vector vecOrigin; + QAngle angAngles; + float fldummy; + m_hPlayer->CalcView( vecOrigin, angAngles, fldummy, fldummy, fldummy ); + + return GetAbsOrigin() + (vecOrigin - m_hPlayer->GetAbsOrigin()); + } + else + return BaseClass::EyePosition(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const QAngle &CPlayerViewProxy::EyeAngles( void ) +{ + if (m_hPlayer.Get()) + { + Vector vecOrigin; + static QAngle angAngles; + float fldummy; + m_hPlayer->CalcView( vecOrigin, angAngles, fldummy, fldummy, fldummy ); + + angAngles = GetAbsAngles() + (angAngles - m_hPlayer->GetAbsAngles()); + return angAngles; + + //return m_hPlayer.Get()->EyeAngles(); + } + else + return BaseClass::EyeAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const QAngle &CPlayerViewProxy::LocalEyeAngles( void ) +{ + if (m_hPlayer.Get()) { + static QAngle angAngles = GetAbsAngles() + (m_hPlayer->LocalEyeAngles() - m_hPlayer->GetAbsAngles()); + return angAngles; + } else + return BaseClass::LocalEyeAngles(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Vector CPlayerViewProxy::EarPosition( void ) +{ + if (m_hPlayer.Get()) + { + Vector vecPlayerOffset = m_hPlayer.Get()->EarPosition() - m_hPlayer.Get()->GetAbsOrigin(); + return GetAbsOrigin() + vecPlayerOffset; + } + else + return BaseClass::EarPosition(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerViewProxy::ActivateEnt( CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + m_bEnabled = true; + + m_hMeasureReference = gEntList.FindEntityByName( NULL, m_iszMeasureReference, this, pActivator, pCaller ); + m_hTargetReference = gEntList.FindEntityByName( NULL, m_iszTargetReference, this, pActivator, pCaller ); + + // Do something else in Mapbase MP + m_hPlayer = UTIL_GetLocalPlayer(); + + SetThink( &CPlayerViewProxy::MeasureThink ); + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerViewProxy::DeactivateEnt( void ) +{ + m_bEnabled = false; + + m_hMeasureReference = NULL; + m_hTargetReference = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPlayerViewProxy::InputActivate( inputdata_t &inputdata ) +{ + ActivateEnt(inputdata.pActivator, inputdata.pCaller); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPlayerViewProxy::InputDeactivate( inputdata_t &inputdata ) +{ + DeactivateEnt(); +} +#endif diff --git a/game/server/hl2/script_intro.h b/game/server/hl2/script_intro.h index 5e59fa33..552c6188 100644 --- a/game/server/hl2/script_intro.h +++ b/game/server/hl2/script_intro.h @@ -44,6 +44,11 @@ class CScriptIntro : public CBaseEntity void InputFadeTo( inputdata_t &inputdata ); void InputSetFadeColor( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetDrawSky( inputdata_t &inputdata ) { m_bDrawSky = inputdata.value.Bool(); } + void InputSetDrawSky2( inputdata_t &inputdata ) { m_bDrawSky2 = inputdata.value.Bool(); } +#endif + bool GetIncludedPVSOrigin( Vector *pOrigin, CBaseEntity **ppCamera ); private: @@ -61,6 +66,11 @@ class CScriptIntro : public CBaseEntity CNetworkVar( float, m_flBlendStartTime ); CNetworkVar( int, m_iStartFOV ); CNetworkVar( bool, m_bActive ); +#ifdef MAPBASE + CNetworkVar( bool, m_bDrawSky ); + CNetworkVar( bool, m_bDrawSky2 ); + CNetworkVar( bool, m_bUseEyePosition ); +#endif // Fov & fov blends CNetworkVar( int, m_iNextFOV ); diff --git a/game/server/hl2/vehicle_airboat.cpp b/game/server/hl2/vehicle_airboat.cpp index c8a49ddb..120ffcaf 100644 --- a/game/server/hl2/vehicle_airboat.cpp +++ b/game/server/hl2/vehicle_airboat.cpp @@ -1573,6 +1573,8 @@ void CPropAirboat::FireGun( ) Vector vecForward; GetAttachment( m_nGunBarrelAttachment, vecGunPosition, &vecForward ); + CDisablePredictionFiltering disabler; + // NOTE: For the airboat, unable to fire really means the aim is clamped Vector vecAimPoint; if ( !m_bUnableToFire ) diff --git a/game/server/hl2/vehicle_apc.cpp b/game/server/hl2/vehicle_apc.cpp index 80c4291f..63d5e3ed 100644 --- a/game/server/hl2/vehicle_apc.cpp +++ b/game/server/hl2/vehicle_apc.cpp @@ -561,9 +561,15 @@ int CPropAPC::OnTakeDamage( const CTakeDamageInfo &info ) m_iHealth -= dmgInfo.GetDamage(); if ( m_iHealth <= 0 ) { - m_iHealth = 0; - Event_Killed( dmgInfo ); - return 0; +#ifdef MAPBASE_VSCRIPT + // False = Cheat death + if (ScriptDeathHook( const_cast(&info) ) != false) +#endif + { + m_iHealth = 0; + Event_Killed( dmgInfo ); + return 0; + } } // Chain diff --git a/game/server/hl2/vehicle_jeep.cpp b/game/server/hl2/vehicle_jeep.cpp index 80eb1368..0b47f3cb 100644 --- a/game/server/hl2/vehicle_jeep.cpp +++ b/game/server/hl2/vehicle_jeep.cpp @@ -135,6 +135,10 @@ BEGIN_DATADESC( CPropJeep ) DEFINE_INPUTFUNC( FIELD_VOID, "ShowHudHint", InputShowHudHint ), DEFINE_INPUTFUNC( FIELD_VOID, "StartRemoveTauCannon", InputStartRemoveTauCannon ), DEFINE_INPUTFUNC( FIELD_VOID, "FinishRemoveTauCannon", InputFinishRemoveTauCannon ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DisablePhysGun", InputDisablePhysGun ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnablePhysGun", InputEnablePhysGun ), +#endif DEFINE_THINKFUNC( JeepSeagullThink ), END_DATADESC() @@ -148,6 +152,11 @@ END_SEND_TABLE(); LINK_ENTITY_TO_CLASS( prop_vehicle_jeep, CPropJeep ); #endif +#ifdef MAPBASE +// Shortcut to old jeep for those who want to use the scout car in Episodic +LINK_ENTITY_TO_CLASS( prop_vehicle_jeep_old, CPropJeep ); +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -898,6 +907,8 @@ void CPropJeep::FireCannon( void ) if ( m_bUnableToFire ) return; + CDisablePredictionFiltering disabler; + m_flCannonTime = gpGlobals->curtime + 0.2f; m_bCannonCharging = false; @@ -936,6 +947,8 @@ void CPropJeep::FireCannon( void ) //----------------------------------------------------------------------------- void CPropJeep::FireChargedCannon( void ) { + CDisablePredictionFiltering disabler; + bool penetrated = false; m_bCannonCharging = false; @@ -1674,6 +1687,23 @@ void CPropJeep::InputFinishRemoveTauCannon( inputdata_t &inputdata ) m_bHasGun = false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Stop players punting the car around. +//----------------------------------------------------------------------------- +void CPropJeep::InputDisablePhysGun( inputdata_t &data ) +{ + AddEFlags( EFL_NO_PHYSCANNON_INTERACTION ); +} +//----------------------------------------------------------------------------- +// Purpose: Return to normal +//----------------------------------------------------------------------------- +void CPropJeep::InputEnablePhysGun( inputdata_t &data ) +{ + RemoveEFlags( EFL_NO_PHYSCANNON_INTERACTION ); +} +#endif + //======================================================================================================================================== // JEEP FOUR WHEEL PHYSICS VEHICLE SERVER VEHICLE //======================================================================================================================================== diff --git a/game/server/hl2/vehicle_jeep.h b/game/server/hl2/vehicle_jeep.h index ba08c2c4..982ee6db 100644 --- a/game/server/hl2/vehicle_jeep.h +++ b/game/server/hl2/vehicle_jeep.h @@ -118,6 +118,10 @@ class CPropJeep : public CPropVehicleDriveable void InputShowHudHint( inputdata_t &inputdata ); void InputStartRemoveTauCannon( inputdata_t &inputdata ); void InputFinishRemoveTauCannon( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDisablePhysGun( inputdata_t &data ); + void InputEnablePhysGun( inputdata_t &data ); +#endif protected: diff --git a/game/server/hl2/weapon_357.cpp b/game/server/hl2/weapon_357.cpp index 2b3a3a12..a3c05371 100644 --- a/game/server/hl2/weapon_357.cpp +++ b/game/server/hl2/weapon_357.cpp @@ -27,6 +27,11 @@ // CWeapon357 //----------------------------------------------------------------------------- +#ifdef MAPBASE +extern acttable_t *GetPistolActtable(); +extern int GetPistolActtableCount(); +#endif + class CWeapon357 : public CBaseHLCombatWeapon { DECLARE_CLASS( CWeapon357, CBaseHLCombatWeapon ); @@ -39,8 +44,46 @@ class CWeapon357 : public CBaseHLCombatWeapon float WeaponAutoAimScale() { return 0.6f; } +#ifdef MAPBASE + int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; } + + virtual int GetMinBurst() { return 1; } + virtual int GetMaxBurst() { return 1; } + virtual float GetMinRestTime( void ) { return 1.0f; } + virtual float GetMaxRestTime( void ) { return 2.5f; } + + virtual float GetFireRate( void ) { return 1.0f; } + + virtual const Vector& GetBulletSpread( void ) + { + static Vector cone = VECTOR_CONE_15DEGREES; + if (!GetOwner() || !GetOwner()->IsNPC()) + return cone; + + static Vector AllyCone = VECTOR_CONE_2DEGREES; + static Vector NPCCone = VECTOR_CONE_5DEGREES; + + if( GetOwner()->MyNPCPointer()->IsPlayerAlly() ) + { + // 357 allies should be cooler + return AllyCone; + } + + return NPCCone; + } + + void FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, Vector &vecShootOrigin, Vector &vecShootDir ); + void Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ); + + virtual acttable_t *GetBackupActivityList() { return GetPistolActtable(); } + virtual int GetBackupActivityListCount() { return GetPistolActtableCount(); } +#endif + DECLARE_SERVERCLASS(); DECLARE_DATADESC(); +#ifdef MAPBASE + DECLARE_ACTTABLE(); +#endif }; LINK_ENTITY_TO_CLASS( weapon_357, CWeapon357 ); @@ -53,6 +96,148 @@ END_SEND_TABLE() BEGIN_DATADESC( CWeapon357 ) END_DATADESC() +#ifdef MAPBASE +acttable_t CWeapon357::m_acttable[] = +{ +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_IDLE, ACT_IDLE_REVOLVER, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_REVOLVER, true }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_REVOLVER, true }, + { ACT_RELOAD, ACT_RELOAD_REVOLVER, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_REVOLVER, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_REVOLVER, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_REVOLVER, true }, + { ACT_RELOAD_LOW, ACT_RELOAD_REVOLVER_LOW, false }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_REVOLVER_LOW, false }, + { ACT_COVER_LOW, ACT_COVER_REVOLVER_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_REVOLVER_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_REVOLVER, false }, + { ACT_WALK, ACT_WALK_REVOLVER, true }, + { ACT_RUN, ACT_RUN_REVOLVER, true }, +#else + { ACT_IDLE, ACT_IDLE_PISTOL, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_PISTOL, true }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, true }, + { ACT_RELOAD, ACT_RELOAD_PISTOL, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_PISTOL, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_PISTOL, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_PISTOL,true }, + { ACT_RELOAD_LOW, ACT_RELOAD_PISTOL_LOW, false }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_PISTOL_LOW, false }, + { ACT_COVER_LOW, ACT_COVER_PISTOL_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_PISTOL_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_PISTOL, false }, + { ACT_WALK, ACT_WALK_PISTOL, false }, + { ACT_RUN, ACT_RUN_PISTOL, false }, +#endif + + // + // Activities ported from weapon_alyxgun below + // + + // Readiness activities (not aiming) +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_PISTOL_STIMULATED, false }, +#else + { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_STIMULATED, false }, +#endif + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_WALK_RELAXED, ACT_WALK_PISTOL_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_PISTOL_STIMULATED, false }, +#else + { ACT_WALK_RELAXED, ACT_WALK, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_STIMULATED, false }, +#endif + { ACT_WALK_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_STEALTH, ACT_WALK_STEALTH_PISTOL, false }, + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RUN_RELAXED, ACT_RUN_PISTOL_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_PISTOL_STIMULATED, false }, +#else + { ACT_RUN_RELAXED, ACT_RUN, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_STIMULATED, false }, +#endif + { ACT_RUN_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_STEALTH, ACT_RUN_STEALTH_PISTOL, false }, + + // Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_PISTOL, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_ANGRY_PISTOL, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_AIM_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + + { ACT_WALK_AIM_RELAXED, ACT_WALK, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_PISTOL, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_AIM_STEALTH, ACT_WALK_AIM_STEALTH_PISTOL, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_PISTOL, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_AIM_STEALTH, ACT_RUN_AIM_STEALTH_PISTOL, false },//always aims + //End readiness activities + + // Crouch activities + { ACT_CROUCHIDLE_STIMULATED, ACT_CROUCHIDLE_STIMULATED, false }, + { ACT_CROUCHIDLE_AIM_STIMULATED,ACT_RANGE_AIM_PISTOL_LOW, false },//always aims + { ACT_CROUCHIDLE_AGITATED, ACT_RANGE_AIM_PISTOL_LOW, false },//always aims + + // Readiness translations + { ACT_READINESS_RELAXED_TO_STIMULATED, ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED, false }, + { ACT_READINESS_RELAXED_TO_STIMULATED_WALK, ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED_WALK, false }, + { ACT_READINESS_AGITATED_TO_STIMULATED, ACT_READINESS_PISTOL_AGITATED_TO_STIMULATED, false }, + { ACT_READINESS_STIMULATED_TO_RELAXED, ACT_READINESS_PISTOL_STIMULATED_TO_RELAXED, false }, + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_REVOLVER_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_REVOLVER_MED, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_REVOLVER, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_REVOLVER, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_REVOLVER, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_REVOLVER, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_REVOLVER, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_REVOLVER, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_REVOLVER, false }, +#else + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, +#endif +#endif +}; + + +IMPLEMENT_ACTTABLE( CWeapon357 ); + +// Allows Weapon_BackupActivity() to access the 357's activity table. +acttable_t *Get357Acttable() +{ + return CWeapon357::m_acttable; +} + +int Get357ActtableCount() +{ + return ARRAYSIZE(CWeapon357::m_acttable); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- @@ -60,6 +245,13 @@ CWeapon357::CWeapon357( void ) { m_bReloadsSingly = false; m_bFiresUnderwater = false; + +#ifdef MAPBASE + m_fMinRange1 = 24; + m_fMaxRange1 = 1000; + m_fMinRange2 = 24; + m_fMaxRange2 = 200; +#endif } //----------------------------------------------------------------------------- @@ -87,9 +279,57 @@ void CWeapon357::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatChara break; } +#ifdef MAPBASE + case EVENT_WEAPON_PISTOL_FIRE: + { + Vector vecShootOrigin, vecShootDir; + vecShootOrigin = pOperator->Weapon_ShootPosition(); + + CAI_BaseNPC *npc = pOperator->MyNPCPointer(); + ASSERT( npc != NULL ); + + vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); + + FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir ); + } + break; + default: + BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); + break; +#endif } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeapon357::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, Vector &vecShootOrigin, Vector &vecShootDir ) +{ + CSoundEnt::InsertSound( SOUND_COMBAT|SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy() ); + + WeaponSound( SINGLE_NPC ); + pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 1 ); + pOperator->DoMuzzleFlash(); + m_iClip1 = m_iClip1 - 1; +} + +//----------------------------------------------------------------------------- +// Purpose: Some things need this. (e.g. the new Force(X)Fire inputs or blindfire actbusy) +//----------------------------------------------------------------------------- +void CWeapon357::Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ) +{ + // Ensure we have enough rounds in the clip + m_iClip1++; + + Vector vecShootOrigin, vecShootDir; + QAngle angShootDir; + GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir ); + AngleVectors( angShootDir, &vecShootDir ); + FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/server/hl2/weapon_alyxgun.cpp b/game/server/hl2/weapon_alyxgun.cpp index 270a503c..5bf20eb6 100644 --- a/game/server/hl2/weapon_alyxgun.cpp +++ b/game/server/hl2/weapon_alyxgun.cpp @@ -37,20 +37,40 @@ acttable_t CWeaponAlyxGun::m_acttable[] = { ACT_RELOAD_LOW, ACT_RELOAD_PISTOL_LOW, true }, { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_PISTOL_LOW, true }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_PISTOL, true }, +#ifdef MAPBASE + // For non-Alyx NPCs + { ACT_WALK, ACT_WALK_PISTOL, false }, + { ACT_RUN, ACT_RUN_PISTOL, false }, +#endif // Readiness activities (not aiming) +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_PISTOL_STIMULATED, false }, +#else { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL, false },//never aims { ACT_IDLE_STIMULATED, ACT_IDLE_STIMULATED, false }, +#endif { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims { ACT_IDLE_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_WALK_RELAXED, ACT_WALK_PISTOL_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_PISTOL_STIMULATED, false }, +#else { ACT_WALK_RELAXED, ACT_WALK, false },//never aims { ACT_WALK_STIMULATED, ACT_WALK_STIMULATED, false }, +#endif { ACT_WALK_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims { ACT_WALK_STEALTH, ACT_WALK_STEALTH_PISTOL, false }, - + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RUN_RELAXED, ACT_RUN_PISTOL_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_PISTOL_STIMULATED, false }, +#else { ACT_RUN_RELAXED, ACT_RUN, false },//never aims { ACT_RUN_STIMULATED, ACT_RUN_STIMULATED, false }, +#endif { ACT_RUN_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims { ACT_RUN_STEALTH, ACT_RUN_STEALTH_PISTOL, false }, @@ -85,6 +105,21 @@ acttable_t CWeaponAlyxGun::m_acttable[] = // { ACT_ARM, ACT_ARM_PISTOL, true }, // { ACT_DISARM, ACT_DISARM_PISTOL, true }, + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_PISTOL, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponAlyxGun); diff --git a/game/server/hl2/weapon_alyxgun.h b/game/server/hl2/weapon_alyxgun.h index cc3e862c..4dd95532 100644 --- a/game/server/hl2/weapon_alyxgun.h +++ b/game/server/hl2/weapon_alyxgun.h @@ -13,6 +13,11 @@ #pragma once #endif +#ifdef MAPBASE +extern acttable_t *GetPistolActtable(); +extern int GetPistolActtableCount(); +#endif + class CWeaponAlyxGun : public CHLSelectFireMachineGun { DECLARE_DATADESC(); @@ -51,6 +56,11 @@ class CWeaponAlyxGun : public CHLSelectFireMachineGun SetTouch(NULL); } +#ifdef MAPBASE + virtual acttable_t *GetBackupActivityList() { return GetPistolActtable(); } + virtual int GetBackupActivityListCount() { return GetPistolActtableCount(); } +#endif + float m_flTooCloseTimer; DECLARE_ACTTABLE(); diff --git a/game/server/hl2/weapon_annabelle.cpp b/game/server/hl2/weapon_annabelle.cpp index 94a8a1a8..6b7ecdd9 100644 --- a/game/server/hl2/weapon_annabelle.cpp +++ b/game/server/hl2/weapon_annabelle.cpp @@ -20,6 +20,11 @@ extern ConVar sk_auto_reload_time; +#ifdef MAPBASE +extern acttable_t *GetShotgunActtable(); +extern int GetShotgunActtableCount(); +#endif + class CWeaponAnnabelle : public CBaseHLCombatWeapon { DECLARE_DATADESC(); @@ -41,6 +46,16 @@ class CWeaponAnnabelle : public CBaseHLCombatWeapon virtual const Vector& GetBulletSpread( void ) { static Vector cone = vec3_origin; + +#ifdef MAPBASE + if (GetOwner() && GetOwner()->OverridingWeaponProficiency()) + { + // If the owner's weapon proficiency is being overridden, return a more realistic spread + static Vector cone2 = VECTOR_CONE_6DEGREES; + return cone2; + } +#endif + return cone; } @@ -61,6 +76,11 @@ class CWeaponAnnabelle : public CBaseHLCombatWeapon void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + virtual acttable_t *GetBackupActivityList() { return GetShotgunActtable(); } + virtual int GetBackupActivityListCount() { return GetShotgunActtableCount(); } +#endif + DECLARE_ACTTABLE(); CWeaponAnnabelle(void); @@ -82,6 +102,31 @@ END_DATADESC() acttable_t CWeaponAnnabelle::m_acttable[] = { +#if defined(EXPANDED_HL2_WEAPON_ACTIVITIES) && AR2_ACTIVITY_FIX == 1 + { ACT_IDLE, ACT_IDLE_AR2, false }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_AR2, true }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_AR2_LOW, false }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_ANNABELLE, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_ANNABELLE_LOW, true }, + { ACT_RELOAD, ACT_RELOAD_ANNABELLE, true }, + { ACT_WALK, ACT_WALK_AR2, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_AR2, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, false }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, false }, + { ACT_RUN, ACT_RUN_AR2, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_AR2, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, false }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, false }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_ANNABELLE, true }, + { ACT_RELOAD_LOW, ACT_RELOAD_ANNABELLE_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_ANNABELLE, false }, + + { ACT_ARM, ACT_ARM_RIFLE, true }, + { ACT_DISARM, ACT_DISARM_RIFLE, true }, +#else +#ifdef MAPBASE + { ACT_IDLE, ACT_IDLE_SMG1, false }, +#endif { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true }, { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, true }, { ACT_RELOAD, ACT_RELOAD_SMG1, true }, @@ -96,6 +141,22 @@ acttable_t CWeaponAnnabelle::m_acttable[] = { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SHOTGUN, true }, { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR2, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_AR2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SHOTGUN, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponAnnabelle); @@ -172,6 +233,13 @@ bool CWeaponAnnabelle::StartReload( void ) pOwner->m_flNextAttack = gpGlobals->curtime; m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +#ifdef MAPBASE + if ( pOwner->IsPlayer() ) + { + static_cast(pOwner)->SetAnimation( PLAYER_RELOAD ); + } +#endif + m_bInReload = true; return true; } diff --git a/game/server/hl2/weapon_ar1.cpp b/game/server/hl2/weapon_ar1.cpp index 994cdabb..0d9c0240 100644 --- a/game/server/hl2/weapon_ar1.cpp +++ b/game/server/hl2/weapon_ar1.cpp @@ -37,6 +37,10 @@ float Damage[ MAX_SETTINGS ] = 20, }; +#ifdef MAPBASE +extern acttable_t *GetAR2Acttable(); +extern int GetAR2ActtableCount(); +#endif //========================================================= //========================================================= @@ -93,6 +97,12 @@ class CWeaponAR1 : public CHLMachineGun break; } } + +#ifdef MAPBASE + virtual acttable_t *GetBackupActivityList() { return GetAR2Acttable(); } + virtual int GetBackupActivityListCount() { return GetAR2ActtableCount(); } +#endif + DECLARE_ACTTABLE(); }; @@ -105,6 +115,77 @@ PRECACHE_WEAPON_REGISTER(weapon_ar1); acttable_t CWeaponAR1::m_acttable[] = { { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR1, true }, + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // Optional new NPC activities + // (these should fall back to AR2 animations when they don't exist on an NPC) + { ACT_RELOAD, ACT_RELOAD_AR1, true }, + { ACT_IDLE, ACT_IDLE_AR1, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_AR1, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_AR1_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_AR1_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_AR1, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_AR1_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_AR1_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_AR1, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_AR1_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_AR1_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_AR1, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_AR1_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_AR1_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_AR1, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_AR1_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_AR1_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_AR1, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_AR1_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_AR1_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_AR1, false },//always aims +//End readiness activities + + { ACT_WALK, ACT_WALK_AR1, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_AR1, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_AR1, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_AR1, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_AR1, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_AR1_LOW, true }, + { ACT_COVER_LOW, ACT_COVER_AR1_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_AR1_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_AR1_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_AR1, true }, + + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_AR1_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_AR1_MED, false }, +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR1, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR1, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR1, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR1, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR1, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR1, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_AR1, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponAR1); diff --git a/game/server/hl2/weapon_ar2.cpp b/game/server/hl2/weapon_ar2.cpp index d9c7ec25..6e7d4cac 100644 --- a/game/server/hl2/weapon_ar2.cpp +++ b/game/server/hl2/weapon_ar2.cpp @@ -27,6 +27,9 @@ #include "npc_combine.h" #include "rumble_shared.h" #include "gamestats.h" +#ifdef MAPBASE +#include "npc_playercompanion.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -54,6 +57,56 @@ PRECACHE_WEAPON_REGISTER(weapon_ar2); acttable_t CWeaponAR2::m_acttable[] = { +#if AR2_ACTIVITY_FIX == 1 + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, true }, + { ACT_RELOAD, ACT_RELOAD_AR2, true }, + { ACT_IDLE, ACT_IDLE_AR2, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_AR2, false }, + + { ACT_WALK, ACT_WALK_AR2, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_AR2_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_AR2_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_AR2, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_AR2_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_AR2_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_AR2, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_AR2_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_AR2_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_AR2_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_AR2_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_AR2, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_AR2_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_AR2_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_AR2, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_AR2_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_AR2_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims +//End readiness activities + + { ACT_WALK_AIM, ACT_WALK_AIM_AR2, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_AR2, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_AR2, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_AR2, false }, + { ACT_COVER_LOW, ACT_COVER_AR2_LOW, true }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_AR2_LOW, false }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_AR2_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_AR2_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_AR2, true }, +// { ACT_RANGE_ATTACK2, ACT_RANGE_ATTACK_AR2_GRENADE, true }, +#else { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, true }, { ACT_RELOAD, ACT_RELOAD_SMG1, true }, // FIXME: hook to AR2 unique { ACT_IDLE, ACT_IDLE_SMG1, true }, // FIXME: hook to AR2 unique @@ -102,10 +155,54 @@ acttable_t CWeaponAR2::m_acttable[] = { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true }, // { ACT_RANGE_ATTACK2, ACT_RANGE_ATTACK_AR2_GRENADE, true }, +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_AR2_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_AR2_MED, false }, + + { ACT_COVER_WALL_R, ACT_COVER_WALL_R_RIFLE, false }, + { ACT_COVER_WALL_L, ACT_COVER_WALL_L_RIFLE, false }, + { ACT_COVER_WALL_LOW_R, ACT_COVER_WALL_LOW_R_RIFLE, false }, + { ACT_COVER_WALL_LOW_L, ACT_COVER_WALL_LOW_L_RIFLE, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR2, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_AR2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR2, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponAR2); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the AR2's activity table. +acttable_t *GetAR2Acttable() +{ + return CWeaponAR2::m_acttable; +} + +int GetAR2ActtableCount() +{ + return ARRAYSIZE(CWeaponAR2::m_acttable); +} +#endif + CWeaponAR2::CWeaponAR2( ) { m_fMinRange1 = 65; @@ -285,6 +382,9 @@ void CWeaponAR2::SecondaryAttack( void ) if( pPlayer ) { pPlayer->RumbleEffect(RUMBLE_AR2_ALT_FIRE, 0, RUMBLE_FLAG_RESTART ); +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK2 ); +#endif } SendWeaponAnim( ACT_VM_FIDGET ); @@ -382,6 +482,10 @@ void CWeaponAR2::FireNPCSecondaryAttack( CBaseCombatCharacter *pOperator, bool b Vector vecTarget; +#ifdef MAPBASE + // It's shared across all NPCs now that it's available on more than just soldiers on more than just the AR2. + vecTarget = pNPC->GetAltFireTarget(); +#else CNPC_Combine *pSoldier = dynamic_cast( pNPC ); if ( pSoldier ) { @@ -389,6 +493,13 @@ void CWeaponAR2::FireNPCSecondaryAttack( CBaseCombatCharacter *pOperator, bool b // Therefore, we must ask them specifically what direction they are shooting. vecTarget = pSoldier->GetAltFireTarget(); } +#ifdef MAPBASE + else if ( CNPC_PlayerCompanion *pCompanion = dynamic_cast( pNPC ) ) + { + // Companions can use energy balls now. Isn't that lovely? + vecTarget = pCompanion->GetAltFireTarget(); + } +#endif else { // All other users of the AR2 alt-fire shoot directly at their enemy. @@ -397,6 +508,7 @@ void CWeaponAR2::FireNPCSecondaryAttack( CBaseCombatCharacter *pOperator, bool b vecTarget = pNPC->GetEnemy()->BodyTarget( vecSrc ); } +#endif vecAiming = vecTarget - vecSrc; VectorNormalize( vecAiming ); @@ -412,12 +524,25 @@ void CWeaponAR2::FireNPCSecondaryAttack( CBaseCombatCharacter *pOperator, bool b Vector vecVelocity = vecAiming * 1000.0f; // Fire the combine ball +#ifdef MAPBASE + CBaseEntity *pBall = CreateCombineBall( vecSrc, + vecVelocity, + flRadius, + sk_weapon_ar2_alt_fire_mass.GetFloat(), + flDuration, + pNPC ); + + variant_t var; + var.SetEntity(pBall); + pNPC->FireNamedOutput("OnThrowGrenade", var, pBall, pNPC); +#else CreateCombineBall( vecSrc, vecVelocity, flRadius, sk_weapon_ar2_alt_fire_mass.GetFloat(), flDuration, pNPC ); +#endif } //----------------------------------------------------------------------------- diff --git a/game/server/hl2/weapon_ar2.h b/game/server/hl2/weapon_ar2.h index d5376a83..5a855f2c 100644 --- a/game/server/hl2/weapon_ar2.h +++ b/game/server/hl2/weapon_ar2.h @@ -71,6 +71,9 @@ class CWeaponAR2 : public CHLMachineGun bool m_bShotDelayed; int m_nVentPose; +#ifdef MAPBASE // Make act table accessible outside class +public: +#endif DECLARE_ACTTABLE(); DECLARE_DATADESC(); }; diff --git a/game/server/hl2/weapon_bugbait.cpp b/game/server/hl2/weapon_bugbait.cpp index 38c02239..d9e6f94c 100644 --- a/game/server/hl2/weapon_bugbait.cpp +++ b/game/server/hl2/weapon_bugbait.cpp @@ -58,6 +58,9 @@ class CWeaponBugBait : public CBaseHLCombatWeapon bool ShouldDisplayHUDHint() { return true; } DECLARE_DATADESC(); +#ifdef MAPBASE + DECLARE_ACTTABLE(); +#endif protected: @@ -86,6 +89,26 @@ BEGIN_DATADESC( CWeaponBugBait ) END_DATADESC() +#ifdef MAPBASE +acttable_t CWeaponBugBait::m_acttable[] = +{ + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_GRENADE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_GRENADE, false }, +#endif +}; + +IMPLEMENT_ACTTABLE( CWeaponBugBait ); +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -292,6 +315,10 @@ void CWeaponBugBait::ThrowGrenade( CBasePlayer *pPlayer ) } m_bRedraw = true; + +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif } //----------------------------------------------------------------------------- @@ -349,6 +376,14 @@ void CWeaponBugBait::ItemPostFrame( void ) if ( pOwner == NULL ) return; +#ifdef MAPBASE + if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING )) + { + WeaponIdle(); + return; + } +#endif + // See if we're cocked and ready to throw if ( m_bDrawBackFinished ) { diff --git a/game/server/hl2/weapon_cguard.cpp b/game/server/hl2/weapon_cguard.cpp index 572a90c5..4b8a67d4 100644 --- a/game/server/hl2/weapon_cguard.cpp +++ b/game/server/hl2/weapon_cguard.cpp @@ -86,6 +86,10 @@ void TE_ConcussiveExplosion( IRecipientFilter& filter, float delay, //Temp ent for the blast +#ifdef MAPBASE +#define SF_CONCUSSIVEBLAST_REPEATABLE 0x00000001 +#endif + class CConcussiveBlast : public CBaseEntity { DECLARE_DATADESC(); @@ -94,6 +98,13 @@ class CConcussiveBlast : public CBaseEntity int m_spriteTexture; +#ifdef MAPBASE + float m_flDamage = 200; + float m_flRadius = 256; + float m_flMagnitude = 1.0; + string_t m_iszSoundName; +#endif + CConcussiveBlast( void ) {} //----------------------------------------------------------------------------- @@ -104,6 +115,11 @@ class CConcussiveBlast : public CBaseEntity { m_spriteTexture = PrecacheModel( "sprites/lgtning.vmt" ); +#ifdef MAPBASE + if (m_iszSoundName != NULL_STRING) + PrecacheScriptSound(STRING(m_iszSoundName)); +#endif + BaseClass::Precache(); } @@ -150,10 +166,32 @@ class CConcussiveBlast : public CBaseEntity ); //Do the radius damage +#ifdef MAPBASE + RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), m_flDamage, DMG_BLAST|DMG_DISSOLVE ), GetAbsOrigin(), m_flRadius, CLASS_NONE, NULL ); +#else RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), 200, DMG_BLAST|DMG_DISSOLVE ), GetAbsOrigin(), 256, CLASS_NONE, NULL ); +#endif + +#ifdef MAPBASE + if (m_iszSoundName != NULL_STRING) + EmitSound(STRING(m_iszSoundName)); + if (!HasSpawnFlags(SF_CONCUSSIVEBLAST_REPEATABLE)) +#endif UTIL_Remove( this ); } + +#ifdef MAPBASE + void InputExplode( inputdata_t &inputdata ) + { + Explode(m_flMagnitude); + } + + void InputExplodeWithMagnitude( inputdata_t &inputdata ) + { + Explode(inputdata.value.Int()); + } +#endif }; LINK_ENTITY_TO_CLASS( concussiveblast, CConcussiveBlast ); @@ -165,6 +203,16 @@ BEGIN_DATADESC( CConcussiveBlast ) // DEFINE_FIELD( m_spriteTexture, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "damage" ), + DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "radius" ), + DEFINE_KEYFIELD( m_flMagnitude, FIELD_FLOAT, "magnitude" ), + DEFINE_KEYFIELD( m_iszSoundName, FIELD_SOUNDNAME, "soundname" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Explode", InputExplode ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "ExplodeWithMagnitude", InputExplodeWithMagnitude ), +#endif + END_DATADESC() diff --git a/game/server/hl2/weapon_citizenpackage.cpp b/game/server/hl2/weapon_citizenpackage.cpp index cdb9378a..95a02296 100644 --- a/game/server/hl2/weapon_citizenpackage.cpp +++ b/game/server/hl2/weapon_citizenpackage.cpp @@ -23,6 +23,13 @@ acttable_t CWeaponCitizenPackage::m_acttable[] = { { ACT_IDLE, ACT_IDLE_PACKAGE, false }, { ACT_WALK, ACT_WALK_PACKAGE, false }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RUN, ACT_RUN_PACKAGE, false }, + + { ACT_IDLE_ANGRY, ACT_IDLE_PACKAGE, false }, + { ACT_WALK_AIM, ACT_WALK_PACKAGE, false }, + { ACT_RUN_AIM, ACT_RUN_PACKAGE, false }, +#endif }; IMPLEMENT_ACTTABLE(CWeaponCitizenPackage); @@ -70,5 +77,12 @@ acttable_t CWeaponCitizenSuitcase::m_acttable[] = { { ACT_IDLE, ACT_IDLE_SUITCASE, false }, { ACT_WALK, ACT_WALK_SUITCASE, false }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RUN, ACT_RUN_SUITCASE, false }, + + { ACT_IDLE_ANGRY, ACT_IDLE_SUITCASE, false }, + { ACT_WALK_AIM, ACT_WALK_SUITCASE, false }, + { ACT_RUN_AIM, ACT_RUN_SUITCASE, false }, +#endif }; IMPLEMENT_ACTTABLE(CWeaponCitizenSuitcase); diff --git a/game/server/hl2/weapon_crossbow.cpp b/game/server/hl2/weapon_crossbow.cpp index badd50d8..b55fa441 100644 --- a/game/server/hl2/weapon_crossbow.cpp +++ b/game/server/hl2/weapon_crossbow.cpp @@ -41,6 +41,10 @@ extern ConVar sk_plr_dmg_crossbow; extern ConVar sk_npc_dmg_crossbow; +#ifdef MAPBASE +ConVar weapon_crossbow_new_hit_locations( "weapon_crossbow_new_hit_locations", "1", FCVAR_NONE, "Toggles new crossbow knockback that properly pushes back the correct limbs." ); +#endif + void TE_StickyBolt( IRecipientFilter& filter, float delay, Vector vecDirection, const Vector *origin ); #define BOLT_SKIN_NORMAL 0 @@ -54,7 +58,11 @@ class CCrossbowBolt : public CBaseCombatCharacter DECLARE_CLASS( CCrossbowBolt, CBaseCombatCharacter ); public: +#ifdef MAPBASE + CCrossbowBolt(); +#else CCrossbowBolt() { }; +#endif ~CCrossbowBolt(); Class_T Classify( void ) { return CLASS_NONE; } @@ -66,7 +74,16 @@ class CCrossbowBolt : public CBaseCombatCharacter void BoltTouch( CBaseEntity *pOther ); bool CreateVPhysics( void ); unsigned int PhysicsSolidMaskForEntity() const; +#ifdef MAPBASE + static CCrossbowBolt *BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBaseCombatCharacter *pentOwner = NULL ); + + void InputSetDamage( inputdata_t &inputdata ); + float m_flDamage; + + virtual void SetDamage(float flDamage) { m_flDamage = flDamage; } +#else static CCrossbowBolt *BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBasePlayer *pentOwner = NULL ); +#endif protected: @@ -89,12 +106,23 @@ BEGIN_DATADESC( CCrossbowBolt ) DEFINE_FIELD( m_pGlowSprite, FIELD_EHANDLE ), //DEFINE_FIELD( m_pGlowTrail, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "Damage" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDamage", InputSetDamage ), +#endif + END_DATADESC() IMPLEMENT_SERVERCLASS_ST( CCrossbowBolt, DT_CrossbowBolt ) END_SEND_TABLE() +#ifdef MAPBASE +CCrossbowBolt *CCrossbowBolt::BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBaseCombatCharacter *pentOwner ) +#else CCrossbowBolt *CCrossbowBolt::BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, CBasePlayer *pentOwner ) +#endif { // Create a new entity with CCrossbowBolt private data CCrossbowBolt *pBolt = (CCrossbowBolt *)CreateEntityByName( "crossbow_bolt" ); @@ -102,10 +130,27 @@ CCrossbowBolt *CCrossbowBolt::BoltCreate( const Vector &vecOrigin, const QAngle pBolt->SetAbsAngles( angAngles ); pBolt->Spawn(); pBolt->SetOwnerEntity( pentOwner ); +#ifdef MAPBASE + if (pentOwner && pentOwner->IsNPC()) + pBolt->m_flDamage = sk_npc_dmg_crossbow.GetFloat(); + //else + // pBolt->m_flDamage = sk_plr_dmg_crossbow.GetFloat(); +#endif return pBolt; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CCrossbowBolt::CCrossbowBolt( void ) +{ + // Independent bolts without m_flDamage set need damage + m_flDamage = sk_plr_dmg_crossbow.GetFloat(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -194,6 +239,16 @@ void CCrossbowBolt::Precache( void ) PrecacheModel( "sprites/light_glow02_noz.vmt" ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCrossbowBolt::InputSetDamage( inputdata_t &inputdata ) +{ + m_flDamage = inputdata.value.Float(); +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) @@ -201,7 +256,19 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) if ( pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER) ) { // Some NPCs are triggers that can take damage (like antlion grubs). We should hit them. +#ifdef MAPBASE + // But some physics objects that are also triggers (like weapons) shouldn't go through this check. + // + // Note: rpg_missile has the same code, except it properly accounts for weapons in a different way. + // This was discovered after I implemented this and both work fine, but if this ever causes problems, + // use rpg_missile's implementation: + // + // if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER|FSOLID_VOLUME_CONTENTS) && pOther->GetCollisionGroup() != COLLISION_GROUP_WEAPON ) + // + if ( pOther->GetMoveType() == MOVETYPE_NONE && (( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY )) ) +#else if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) ) +#endif return; } @@ -226,9 +293,45 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) } #endif//HL2_EPISODIC +#ifdef MAPBASE + if (weapon_crossbow_new_hit_locations.GetInt() > 0) + { + // A very experimental and weird way of getting a crossbow bolt to deal accurate knockback. + CBaseAnimating *pOtherAnimating = pOther->GetBaseAnimating(); + if (pOtherAnimating && pOtherAnimating->GetModelPtr() && pOtherAnimating->GetModelPtr()->numbones() > 1) + { + int iClosestBone = -1; + float flCurDistSqr = Square(128.0f); + matrix3x4_t bonetoworld; + Vector vecBonePos; + for (int i = 0; i < pOtherAnimating->GetModelPtr()->numbones(); i++) + { + pOtherAnimating->GetBoneTransform( i, bonetoworld ); + MatrixPosition( bonetoworld, vecBonePos ); + + float flDist = vecBonePos.DistToSqr(GetLocalOrigin()); + if (flDist < flCurDistSqr) + { + iClosestBone = i; + flCurDistSqr = flDist; + } + } + + if (iClosestBone != -1) + { + tr.physicsbone = pOtherAnimating->GetPhysicsBone(iClosestBone); + } + } + } +#endif + if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() ) { +#ifdef MAPBASE + CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_flDamage, DMG_NEVERGIB ); +#else CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_NEVERGIB ); +#endif dmgInfo.AdjustPlayerDamageInflictedForSkillLevel(); CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); @@ -243,7 +346,11 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) } else { +#ifdef MAPBASE + CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_flDamage, DMG_BULLET | DMG_NEVERGIB ); +#else CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_BULLET | DMG_NEVERGIB ); +#endif CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); @@ -434,17 +541,48 @@ class CWeaponCrossbow : public CBaseHLCombatWeapon virtual void Drop( const Vector &vecVelocity ); virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); virtual bool Reload( void ); +#ifdef MAPBASE + virtual void Reload_NPC( bool bPlaySound = true ); +#endif virtual void ItemPostFrame( void ); virtual void ItemBusyFrame( void ); virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + virtual void Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ); +#endif virtual bool SendWeaponAnim( int iActivity ); virtual bool IsWeaponZoomed() { return m_bInZoom; } bool ShouldDisplayHUDHint() { return true; } +#ifdef MAPBASE + int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; } + + virtual int GetMinBurst() { return 1; } + virtual int GetMaxBurst() { return 1; } + + virtual float GetMinRestTime( void ) { return 3.0f; } // 1.5f + virtual float GetMaxRestTime( void ) { return 3.0f; } // 2.0f + + virtual float GetFireRate( void ) { return 5.0f; } + + virtual const Vector& GetBulletSpread( void ) + { + static Vector cone = VECTOR_CONE_15DEGREES; + if (!GetOwner() || !GetOwner()->IsNPC()) + return cone; + + static Vector NPCCone = VECTOR_CONE_5DEGREES; + + return NPCCone; + } +#endif DECLARE_SERVERCLASS(); DECLARE_DATADESC(); +#ifdef MAPBASE + DECLARE_ACTTABLE(); +#endif private: @@ -452,6 +590,10 @@ class CWeaponCrossbow : public CBaseHLCombatWeapon void SetSkin( int skinNum ); void CheckZoomToggle( void ); void FireBolt( void ); +#ifdef MAPBASE + void SetBolt( int iSetting ); + void FireNPCBolt( CAI_BaseNPC *pOwner, Vector &vecShootOrigin, Vector &vecShootDir ); +#endif void ToggleZoom( void ); // Various states for the crossbow's charger @@ -494,6 +636,134 @@ BEGIN_DATADESC( CWeaponCrossbow ) END_DATADESC() +#ifdef MAPBASE +acttable_t CWeaponCrossbow::m_acttable[] = +{ +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_CROSSBOW, true }, + { ACT_RELOAD, ACT_RELOAD_CROSSBOW, true }, + { ACT_IDLE, ACT_IDLE_CROSSBOW, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_CROSSBOW, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_CROSSBOW_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_CROSSBOW_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_CROSSBOW, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_CROSSBOW_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_CROSSBOW_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_CROSSBOW, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_CROSSBOW_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_CROSSBOW_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_CROSSBOW, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_CROSSBOW_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_CROSSBOW_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_CROSSBOW, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_CROSSBOW_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_CROSSBOW_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_CROSSBOW, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_CROSSBOW_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_CROSSBOW_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_CROSSBOW, false },//always aims +//End readiness activities + + { ACT_WALK, ACT_WALK_CROSSBOW, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_CROSSBOW, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_CROSSBOW, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_CROSSBOW, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_CROSSBOW, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_CROSSBOW_LOW, true }, + { ACT_COVER_LOW, ACT_COVER_CROSSBOW_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_CROSSBOW_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_CROSSBOW_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_CROSSBOW, true }, + + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, +#else + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true }, + { ACT_RELOAD, ACT_RELOAD_SMG1, true }, + { ACT_IDLE, ACT_IDLE_SMG1, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true }, + + { ACT_WALK, ACT_WALK_RIFLE, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_SMG1_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_RIFLE_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_RIFLE_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_RIFLE_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_RIFLE_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_RIFLE_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims +//End readiness activities + + { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_RIFLE, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_RIFLE, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SMG1, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SMG1_LOW, true }, + { ACT_COVER_LOW, ACT_COVER_SMG1_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG1_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_CROSSBOW_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_CROSSBOW_MED, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_CROSSBOW, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_CROSSBOW, false }, +#endif +#endif +}; + +IMPLEMENT_ACTTABLE(CWeaponCrossbow); +#endif + //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- @@ -504,6 +774,13 @@ CWeaponCrossbow::CWeaponCrossbow( void ) m_bAltFiresUnderwater = true; m_bInZoom = false; m_bMustReload = false; + +#ifdef MAPBASE + m_fMinRange1 = 24; + m_fMaxRange1 = 5000; + m_fMinRange2 = 24; + m_fMaxRange2 = 5000; +#endif } #define CROSSBOW_GLOW_SPRITE "sprites/light_glow02_noz.vmt" @@ -551,6 +828,10 @@ void CWeaponCrossbow::PrimaryAttack( void ) { m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); + +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif } } @@ -577,6 +858,18 @@ bool CWeaponCrossbow::Reload( void ) return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCrossbow::Reload_NPC( bool bPlaySound ) +{ + BaseClass::Reload_NPC( bPlaySound ); + + SetBolt( 0 ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -678,6 +971,10 @@ void CWeaponCrossbow::FireBolt( void ) m_iClip1--; +#ifdef MAPBASE + SetBolt( 1 ); +#endif + pOwner->ViewPunch( QAngle( -2, 0, 0 ) ); WeaponSound( SINGLE ); @@ -699,6 +996,56 @@ void CWeaponCrossbow::FireBolt( void ) SetChargerState( CHARGER_STATE_DISCHARGE ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets whether or not the bolt is visible +//----------------------------------------------------------------------------- +inline void CWeaponCrossbow::SetBolt( int iSetting ) +{ + int iBody = FindBodygroupByName( "bolt" ); + if (iBody != -1 /*|| (GetOwner() && GetOwner()->IsPlayer())*/) // TODO: Player models check the viewmodel instead of the worldmodel, but setting the bodygroup regardless can cause a crash, so we need a better solution + SetBodygroup( iBody, iSetting ); + else + m_nSkin = iSetting; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCrossbow::FireNPCBolt( CAI_BaseNPC *pOwner, Vector &vecShootOrigin, Vector &vecShootDir ) +{ + Assert(pOwner); + + QAngle angAiming; + VectorAngles( vecShootDir, angAiming ); + + CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate( vecShootOrigin, angAiming, pOwner ); + + if ( pOwner->GetWaterLevel() == 3 ) + { + pBolt->SetAbsVelocity( vecShootDir * BOLT_WATER_VELOCITY ); + } + else + { + pBolt->SetAbsVelocity( vecShootDir * BOLT_AIR_VELOCITY ); + } + + m_iClip1--; + + SetBolt( 1 ); + + WeaponSound( SINGLE_NPC ); + WeaponSound( SPECIAL2 ); + + CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 ); + + m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 2.5f; + + SetSkin( BOLT_SKIN_GLOW ); + SetChargerState( CHARGER_STATE_DISCHARGE ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. @@ -707,11 +1054,18 @@ bool CWeaponCrossbow::Deploy( void ) { if ( m_iClip1 <= 0 ) { +#ifdef MAPBASE + SetBolt( 1 ); +#endif return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_CROSSBOW_DRAW_UNLOADED, (char*)GetAnimPrefix() ); } SetSkin( BOLT_SKIN_GLOW ); +#ifdef MAPBASE + SetBolt( 0 ); +#endif + return BaseClass::Deploy(); } @@ -761,7 +1115,11 @@ void CWeaponCrossbow::CreateChargerEffects( void ) { CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); +#ifdef MAPBASE + if ( m_hChargerSprite != NULL || pOwner == NULL ) +#else if ( m_hChargerSprite != NULL ) +#endif return; m_hChargerSprite = CSprite::SpriteCreate( CROSSBOW_GLOW_SPRITE, GetAbsOrigin(), false ); @@ -855,6 +1213,10 @@ void CWeaponCrossbow::SetChargerState( ChargerState_t state ) // Shoot some sparks and draw a beam between the two outer points DoLoadEffect(); +#ifdef MAPBASE + SetBolt( 0 ); +#endif + break; case CHARGER_STATE_START_CHARGE: @@ -933,12 +1295,46 @@ void CWeaponCrossbow::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombat SetChargerState( CHARGER_STATE_READY ); break; +#ifdef MAPBASE + case EVENT_WEAPON_SMG1: + { + CAI_BaseNPC *pNPC = pOperator->MyNPCPointer(); + Assert(pNPC); + + Vector vecSrc = pNPC->Weapon_ShootPosition(); + Vector vecAiming = pNPC->GetActualShootTrajectory( vecSrc ); + + FireNPCBolt( pNPC, vecSrc, vecAiming ); + //m_bMustReload = true; + } + break; +#endif + default: BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); break; } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCrossbow::Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ) +{ + // Ensure we have enough rounds in the clip + m_iClip1++; + + Vector vecShootOrigin, vecShootDir; + QAngle angShootDir; + GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir ); + AngleVectors( angShootDir, &vecShootDir ); + FireNPCBolt( pOperator->MyNPCPointer(), vecShootOrigin, vecShootDir ); + + //m_bMustReload = true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Set the desired activity for the weapon and its viewmodel counterpart // Input : iActivity - activity to play diff --git a/game/server/hl2/weapon_crowbar.cpp b/game/server/hl2/weapon_crowbar.cpp index fdbc7943..7cc34b9c 100644 --- a/game/server/hl2/weapon_crowbar.cpp +++ b/game/server/hl2/weapon_crowbar.cpp @@ -42,6 +42,29 @@ acttable_t CWeaponCrowbar::m_acttable[] = { ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK_SWING, true }, { ACT_IDLE, ACT_IDLE_ANGRY_MELEE, false }, { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, false }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RUN, ACT_RUN_MELEE, false }, + { ACT_WALK, ACT_WALK_MELEE, false }, + + { ACT_ARM, ACT_ARM_MELEE, false }, + { ACT_DISARM, ACT_DISARM_MELEE, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_MELEE, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponCrowbar); diff --git a/game/server/hl2/weapon_crowbar.h b/game/server/hl2/weapon_crowbar.h index 1890ef6e..26bb961f 100644 --- a/game/server/hl2/weapon_crowbar.h +++ b/game/server/hl2/weapon_crowbar.h @@ -46,6 +46,12 @@ class CWeaponCrowbar : public CBaseHLBludgeonWeapon // Animation event virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + // Don't use backup activities + acttable_t *GetBackupActivityList() { return NULL; } + int GetBackupActivityListCount() { return 0; } +#endif + private: // Animation event handlers void HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); diff --git a/game/server/hl2/weapon_flaregun.cpp b/game/server/hl2/weapon_flaregun.cpp index d3fd6b15..110f5c66 100644 --- a/game/server/hl2/weapon_flaregun.cpp +++ b/game/server/hl2/weapon_flaregun.cpp @@ -19,6 +19,7 @@ #include "tier0/memdbgon.h" +#ifndef MAPBASE /******************************************************************** NOTE: if you are looking at this file becase you would like flares to be considered as fires (and thereby trigger gas traps), be aware @@ -37,6 +38,13 @@ For some partial work towards this end, see changelist 192474. ********************************************************************/ +#else +// ================================================================ // +// I've fixed this...more or less. env_firesensor detects flares now. +// I tried to integrate it with the greater fire system, but I found that too difficult. +// I probably didn't try hard enough. You could fix this yourself if you think it's a big issue. +// ================================================================ // +#endif #define FLARE_LAUNCH_SPEED 1500 @@ -120,6 +128,21 @@ void KillFlare( CBaseEntity *pOwnerEntity, CBaseEntity *pEntity, float flKillTim } } +#ifdef MAPBASE +// For prop_flare debugging. +float GetEnvFlareLifetime( CBaseEntity *pEntity ) +{ + CFlare *pFlare = static_cast< CFlare *>( pEntity ); + + if ( pFlare ) + { + return pFlare->m_flTimeBurnOut - gpGlobals->curtime; + } + + return 0.0f; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/server/hl2/weapon_frag.cpp b/game/server/hl2/weapon_frag.cpp index b0e188aa..91eddcd3 100644 --- a/game/server/hl2/weapon_frag.cpp +++ b/game/server/hl2/weapon_frag.cpp @@ -82,6 +82,21 @@ END_DATADESC() acttable_t CWeaponFrag::m_acttable[] = { { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_GRENADE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_GRENADE, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponFrag); @@ -404,6 +419,10 @@ void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) WeaponSound( SINGLE ); +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif + m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); } @@ -428,6 +447,10 @@ void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer ) WeaponSound( WPN_DOUBLE ); +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK2 ); +#endif + m_bRedraw = true; m_iPrimaryAttacks++; @@ -472,6 +495,10 @@ void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer ) WeaponSound( SPECIAL1 ); +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK2 ); +#endif + m_bRedraw = true; m_iPrimaryAttacks++; diff --git a/game/server/hl2/weapon_physcannon.cpp b/game/server/hl2/weapon_physcannon.cpp index 1e477fb5..2e985460 100644 --- a/game/server/hl2/weapon_physcannon.cpp +++ b/game/server/hl2/weapon_physcannon.cpp @@ -40,6 +40,9 @@ #include "ai_interactions.h" #include "rumble_shared.h" #include "gamestats.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#endif // NVNT haptic utils #include "haptics/haptic_utils.h" @@ -141,6 +144,10 @@ class CTraceFilterPhyscannon : public CTraceFilterSimple // Handle grate entities differently if ( HasContentsGrate( pEntity ) ) { +#ifdef MAPBASE + if (pEntity->CanBePickedUpByPhyscannon()) + return true; +#else // See if it's a grabbable physics prop CPhysicsProp *pPhysProp = dynamic_cast(pEntity); if ( pPhysProp != NULL ) @@ -166,6 +173,7 @@ class CTraceFilterPhyscannon : public CTraceFilterSimple // Somehow had a classname that didn't match the class! Assert(0); } +#endif // Don't bother with any other sort of grated entity return false; @@ -438,10 +446,12 @@ static void ComputePlayerMatrix( CBasePlayer *pPlayer, matrix3x4_t &out ) // Purpose: //----------------------------------------------------------------------------- // derive from this so we can add save/load data to it +#ifndef MAPBASE // Moved to weapon_physcannon.h for point_physics_control struct game_shadowcontrol_params_t : public hlshadowcontrol_params_t { DECLARE_SIMPLE_DATADESC(); }; +#endif BEGIN_SIMPLE_DATADESC( game_shadowcontrol_params_t ) @@ -808,7 +818,14 @@ void CGrabController::AttachEntity( CBasePlayer *pPlayer, CBaseEntity *pEntity, CPhysicsProp *pProp = dynamic_cast(pEntity); if ( pProp ) { +#ifdef MAPBASE + // If the prop has custom carry angles, don't override them + // (regular PreferredCarryAngles() code should cover it) + if (!pProp->m_bUsesCustomCarryAngles) + m_bHasPreferredCarryAngles = pProp->GetPropDataAngles( "preferred_carryangles", m_vecPreferredCarryAngles ); +#else m_bHasPreferredCarryAngles = pProp->GetPropDataAngles( "preferred_carryangles", m_vecPreferredCarryAngles ); +#endif m_flDistanceOffset = pProp->GetCarryDistanceOffset(); } else @@ -1017,12 +1034,11 @@ void CPlayerPickupController::Init( CBasePlayer *pPlayer, CBaseEntity *pObject ) // Holster player's weapon if ( pPlayer->GetActiveWeapon() ) { - if ( !pPlayer->GetActiveWeapon()->CanHolster() || !pPlayer->GetActiveWeapon()->Holster(NULL) ) + if ( !pPlayer->GetActiveWeapon()->CanHolster() || !pPlayer->GetActiveWeapon()->Holster() ) { Shutdown(); return; } - //pPlayer->GetActiveWeapon()->m_pSwitchingTo = NULL; } CHL2_Player *pOwner = (CHL2_Player *)ToBasePlayer( pPlayer ); @@ -1147,7 +1163,11 @@ void CPlayerPickupController::Use( CBaseEntity *pActivator, CBaseEntity *pCaller Vector vecLaunch; m_pPlayer->EyeVectors( &vecLaunch ); // JAY: Scale this with mass because some small objects really go flying +#ifdef MAPBASE + float massFactor = pPhys ? clamp( pPhys->GetMass(), 0.5, 15 ) : 7.5; +#else float massFactor = clamp( pPhys->GetMass(), 0.5, 15 ); +#endif massFactor = RemapVal( massFactor, 0.5, 15, 0.5, 4 ); vecLaunch *= player_throwforce.GetFloat() * massFactor; @@ -1218,6 +1238,9 @@ class CWeaponPhysCannon : public CBaseHLCombatWeapon DECLARE_SERVERCLASS(); DECLARE_DATADESC(); +#ifdef MAPBASE + DECLARE_ACTTABLE(); +#endif CWeaponPhysCannon( void ); @@ -1435,6 +1458,30 @@ BEGIN_DATADESC( CWeaponPhysCannon ) END_DATADESC() +#ifdef MAPBASE +acttable_t CWeaponPhysCannon::m_acttable[] = +{ + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_PHYSGUN, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_PHYSGUN, false }, +#endif + + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, +}; + +IMPLEMENT_ACTTABLE( CWeaponPhysCannon ); +#endif + enum { @@ -1718,6 +1765,9 @@ void CWeaponPhysCannon::DryFire( void ) if ( pOwner ) { pOwner->RumbleEffect( RUMBLE_PISTOL, 0, RUMBLE_FLAG_RESTART ); +#ifdef MAPBASE // TODO: Is this animation too dramatic? + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif } } @@ -1774,6 +1824,11 @@ void CWeaponPhysCannon::PuntNonVPhysics( CBaseEntity *pEntity, const Vector &for PrimaryFireEffect(); SendWeaponAnim( ACT_VM_SECONDARYATTACK ); +#ifdef MAPBASE + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + if (pPlayer) + pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif m_nChangeState = ELEMENT_STATE_CLOSED; m_flElementDebounce = gpGlobals->curtime + 0.5f; @@ -1924,6 +1979,10 @@ void CWeaponPhysCannon::PuntVPhysics( CBaseEntity *pEntity, const Vector &vecFor PrimaryFireEffect(); SendWeaponAnim( ACT_VM_SECONDARYATTACK ); +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif + m_nChangeState = ELEMENT_STATE_CLOSED; m_flElementDebounce = gpGlobals->curtime + 0.5f; m_flCheckSuppressTime = gpGlobals->curtime + 0.25f; @@ -2042,6 +2101,10 @@ void CWeaponPhysCannon::PuntRagdoll( CBaseEntity *pEntity, const Vector &vecForw PrimaryFireEffect(); SendWeaponAnim( ACT_VM_SECONDARYATTACK ); +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif + m_nChangeState = ELEMENT_STATE_CLOSED; m_flElementDebounce = gpGlobals->curtime + 0.5f; m_flCheckSuppressTime = gpGlobals->curtime + 0.25f; @@ -2085,6 +2148,10 @@ bool CWeaponPhysCannon::EntityAllowsPunts( CBaseEntity *pEntity ) if ( pEntity->HasSpawnFlags( SF_WEAPON_NO_PHYSCANNON_PUNT ) ) { +#ifdef MAPBASE + if (pEntity->IsBaseCombatWeapon() || pEntity->IsCombatItem()) + return false; +#else CBaseCombatWeapon *pWeapon = dynamic_cast(pEntity); if ( pWeapon != NULL ) @@ -2094,6 +2161,7 @@ bool CWeaponPhysCannon::EntityAllowsPunts( CBaseEntity *pEntity ) return false; } } +#endif } return true; @@ -2142,6 +2210,9 @@ void CWeaponPhysCannon::PrimaryAttack( void ) PrimaryFireEffect(); SendWeaponAnim( ACT_VM_SECONDARYATTACK ); +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif return; } @@ -2449,7 +2520,11 @@ bool CWeaponPhysCannon::AttachObject( CBaseEntity *pObject, const Vector &vPosit } #if defined(HL2_DLL) +#ifdef MAPBASE + if( physcannon_right_turrets.GetBool() && EntIsClass(pObject, gm_isz_class_FloorTurret) ) +#else if( physcannon_right_turrets.GetBool() && pObject->ClassMatches("npc_turret_floor") ) +#endif { // We just picked up a turret. Is it already upright? Vector vecUp; @@ -3288,6 +3363,15 @@ void CWeaponPhysCannon::ItemPostFrame() return; } +#ifdef MAPBASE + if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING )) + { + m_nAttack2Debounce = 0; + WeaponIdle(); + return; + } +#endif + //Check for object in pickup range if ( m_bActive == false ) { @@ -3460,6 +3544,12 @@ bool CWeaponPhysCannon::CanPickupObject( CBaseEntity *pTarget ) if ( pOwner && pOwner->GetGroundEntity() == pTarget ) return false; +#ifdef MAPBASE + // The gravity gun can't pick up vehicles. + if ( pTarget->GetServerVehicle() ) + return false; +#endif + if ( !IsMegaPhysCannon() ) { if ( pTarget->VPhysicsIsFlesh( ) ) diff --git a/game/server/hl2/weapon_physcannon.h b/game/server/hl2/weapon_physcannon.h index d7ce48ee..01356d26 100644 --- a/game/server/hl2/weapon_physcannon.h +++ b/game/server/hl2/weapon_physcannon.h @@ -30,4 +30,11 @@ CBaseEntity *GetPlayerHeldEntity( CBasePlayer *pPlayer ); bool PhysCannonAccountableForObject( CBaseCombatWeapon *pPhysCannon, CBaseEntity *pObject ); +#ifdef MAPBASE // Moved here so point_physics_control can access, datadesc is still in weapon_physcannon.cpp +struct game_shadowcontrol_params_t : public hlshadowcontrol_params_t +{ + DECLARE_SIMPLE_DATADESC(); +}; +#endif + #endif // WEAPON_PHYSCANNON_H diff --git a/game/server/hl2/weapon_pistol.cpp b/game/server/hl2/weapon_pistol.cpp index d0a25412..9819f748 100644 --- a/game/server/hl2/weapon_pistol.cpp +++ b/game/server/hl2/weapon_pistol.cpp @@ -52,6 +52,10 @@ class CWeaponPistol : public CBaseHLCombatWeapon void AddViewKick( void ); void DryFire( void ); void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + void FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, Vector &vecShootOrigin, Vector &vecShootDir ); + void Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ); +#endif void UpdatePenaltyTime( void ); @@ -104,6 +108,12 @@ class CWeaponPistol : public CBaseHLCombatWeapon return 0.5f; } +#ifdef MAPBASE + // Pistols are their own backup activities + virtual acttable_t *GetBackupActivityList() { return NULL; } + virtual int GetBackupActivityListCount() { return 0; } +#endif + DECLARE_ACTTABLE(); private: @@ -145,11 +155,141 @@ acttable_t CWeaponPistol::m_acttable[] = { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_PISTOL, false }, { ACT_WALK, ACT_WALK_PISTOL, false }, { ACT_RUN, ACT_RUN_PISTOL, false }, + +#ifdef MAPBASE + // + // Activities ported from weapon_alyxgun below + // + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_PISTOL_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + + { ACT_WALK_RELAXED, ACT_WALK_PISTOL_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_PISTOL_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_STEALTH, ACT_WALK_STEALTH_PISTOL, false }, + + { ACT_RUN_RELAXED, ACT_RUN_PISTOL_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_PISTOL_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_STEALTH, ACT_RUN_STEALTH_PISTOL, false }, + + // Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_PISTOL_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_PISTOL_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_AIM_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + + { ACT_WALK_AIM_RELAXED, ACT_WALK_PISTOL_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_PISTOL, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_AIM_STEALTH, ACT_WALK_AIM_STEALTH_PISTOL, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_PISTOL_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_PISTOL, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_AIM_STEALTH, ACT_RUN_AIM_STEALTH_PISTOL, false },//always aims + //End readiness activities +#else + // Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_PISTOL, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + + { ACT_WALK_RELAXED, ACT_WALK, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_STEALTH, ACT_WALK_STEALTH_PISTOL, false }, + + { ACT_RUN_RELAXED, ACT_RUN, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_STEALTH, ACT_RUN_STEALTH_PISTOL, false }, + + // Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_PISTOL, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_ANGRY_PISTOL, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_PISTOL, false },//always aims + { ACT_IDLE_AIM_STEALTH, ACT_IDLE_STEALTH_PISTOL, false }, + + { ACT_WALK_AIM_RELAXED, ACT_WALK, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_PISTOL, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_PISTOL, false },//always aims + { ACT_WALK_AIM_STEALTH, ACT_WALK_AIM_STEALTH_PISTOL, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_PISTOL, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_PISTOL, false },//always aims + { ACT_RUN_AIM_STEALTH, ACT_RUN_AIM_STEALTH_PISTOL, false },//always aims + //End readiness activities +#endif + + // Crouch activities + { ACT_CROUCHIDLE_STIMULATED, ACT_CROUCHIDLE_STIMULATED, false }, + { ACT_CROUCHIDLE_AIM_STIMULATED,ACT_RANGE_AIM_PISTOL_LOW, false },//always aims + { ACT_CROUCHIDLE_AGITATED, ACT_RANGE_AIM_PISTOL_LOW, false },//always aims + + // Readiness translations + { ACT_READINESS_RELAXED_TO_STIMULATED, ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED, false }, + { ACT_READINESS_RELAXED_TO_STIMULATED_WALK, ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED_WALK, false }, + { ACT_READINESS_AGITATED_TO_STIMULATED, ACT_READINESS_PISTOL_AGITATED_TO_STIMULATED, false }, + { ACT_READINESS_STIMULATED_TO_RELAXED, ACT_READINESS_PISTOL_STIMULATED_TO_RELAXED, false }, +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_PISTOL, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_PISTOL, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_PISTOL, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_PISTOL, true }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_PISTOL_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_PISTOL_MED, false }, + + { ACT_COVER_WALL_R, ACT_COVER_WALL_R_PISTOL, false }, + { ACT_COVER_WALL_L, ACT_COVER_WALL_L_PISTOL, false }, + { ACT_COVER_WALL_LOW_R, ACT_COVER_WALL_LOW_R_PISTOL, false }, + { ACT_COVER_WALL_LOW_L, ACT_COVER_WALL_LOW_L_PISTOL, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_PISTOL, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE( CWeaponPistol ); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the pistol's activity table. +acttable_t *GetPistolActtable() +{ + return CWeaponPistol::m_acttable; +} + +int GetPistolActtableCount() +{ + return ARRAYSIZE(CWeaponPistol::m_acttable); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- @@ -193,12 +333,16 @@ void CWeaponPistol::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCh vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); +#ifdef MAPBASE + FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir ); +#else CSoundEnt::InsertSound( SOUND_COMBAT|SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy() ); WeaponSound( SINGLE_NPC ); pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 ); pOperator->DoMuzzleFlash(); m_iClip1 = m_iClip1 - 1; +#endif } break; default: @@ -207,6 +351,36 @@ void CWeaponPistol::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCh } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponPistol::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, Vector &vecShootOrigin, Vector &vecShootDir ) +{ + CSoundEnt::InsertSound( SOUND_COMBAT|SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy() ); + + WeaponSound( SINGLE_NPC ); + pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 ); + pOperator->DoMuzzleFlash(); + m_iClip1 = m_iClip1 - 1; +} + +//----------------------------------------------------------------------------- +// Purpose: Some things need this. (e.g. the new Force(X)Fire inputs or blindfire actbusy) +//----------------------------------------------------------------------------- +void CWeaponPistol::Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ) +{ + // Ensure we have enough rounds in the clip + m_iClip1++; + + Vector vecShootOrigin, vecShootDir; + QAngle angShootDir; + GetAttachment( LookupAttachment( "muzzle" ), vecShootOrigin, angShootDir ); + AngleVectors( angShootDir, &vecShootDir ); + FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/server/hl2/weapon_rpg.cpp b/game/server/hl2/weapon_rpg.cpp index e6278593..1ffc0326 100644 --- a/game/server/hl2/weapon_rpg.cpp +++ b/game/server/hl2/weapon_rpg.cpp @@ -43,6 +43,10 @@ static ConVar sk_apc_missile_damage("sk_apc_missile_damage", "15"); ConVar rpg_missle_use_custom_detonators( "rpg_missle_use_custom_detonators", "1" ); +#ifdef MAPBASE +ConVar weapon_rpg_use_old_behavior( "weapon_rpg_use_old_behavior", "0" ); +ConVar weapon_rpg_fire_rate( "weapon_rpg_fire_rate", "4.0" ); +#endif #define APC_MISSILE_DAMAGE sk_apc_missile_damage.GetFloat() @@ -1395,10 +1399,22 @@ PRECACHE_WEAPON_REGISTER(weapon_rpg); acttable_t CWeaponRPG::m_acttable[] = { { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_RPG, true }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_RPG_LOW, false }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_RPG_LOW, false }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_RPG, false }, +#endif +#ifdef MAPBASE + // Readiness activities should not be required + { ACT_IDLE_RELAXED, ACT_IDLE_RPG_RELAXED, false }, + { ACT_IDLE_STIMULATED, ACT_IDLE_ANGRY_RPG, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_RPG, false }, +#else { ACT_IDLE_RELAXED, ACT_IDLE_RPG_RELAXED, true }, { ACT_IDLE_STIMULATED, ACT_IDLE_ANGRY_RPG, true }, { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_RPG, true }, +#endif { ACT_IDLE, ACT_IDLE_RPG, true }, { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_RPG, true }, @@ -1407,6 +1423,31 @@ acttable_t CWeaponRPG::m_acttable[] = { ACT_RUN, ACT_RUN_RPG, true }, { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RPG, true }, { ACT_COVER_LOW, ACT_COVER_LOW_RPG, true }, + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_ARM, ACT_ARM_RPG, false }, + { ACT_DISARM, ACT_DISARM_RPG, false }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_RPG_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_RPG_MED, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_RPG, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_RPG, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_RPG, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_RPG, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_RPG, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_RPG, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_RPG, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_RPG, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponRPG); @@ -1555,6 +1596,54 @@ void CWeaponRPG::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatChara } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponRPG::Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ) +{ + if ( m_hMissile != NULL ) + return; + + Vector muzzlePoint, vecShootDir; + QAngle angShootDir; + GetAttachment( LookupAttachment( "muzzle" ), muzzlePoint, angShootDir ); + AngleVectors( angShootDir, &vecShootDir ); + + // look for a better launch location + Vector altLaunchPoint; + if (GetAttachment( "missile", altLaunchPoint )) + { + // check to see if it's relativly free + trace_t tr; + AI_TraceHull( altLaunchPoint, altLaunchPoint + vecShootDir * (10.0f*12.0f), Vector( -24, -24, -24 ), Vector( 24, 24, 24 ), MASK_NPCSOLID, NULL, &tr ); + + if( tr.fraction == 1.0) + { + muzzlePoint = altLaunchPoint; + } + } + + m_hMissile = CMissile::Create( muzzlePoint, angShootDir, pOperator->edict() ); + m_hMissile->m_hOwner = this; + + // NPCs always get a grace period + m_hMissile->SetGracePeriod( 0.5 ); + + pOperator->DoMuzzleFlash(); + + WeaponSound( SINGLE_NPC ); + + // Make sure our laserdot is off + m_bGuiding = false; + + if ( m_hLaserDot ) + { + m_hLaserDot->TurnOff(); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1630,6 +1719,10 @@ void CWeaponRPG::PrimaryAttack( void ) SendWeaponAnim( ACT_VM_PRIMARYATTACK ); WeaponSound( SINGLE ); + +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_ATTACK1 ); +#endif pOwner->RumbleEffect( RUMBLE_SHOTGUN_SINGLE, 0, RUMBLE_FLAG_RESTART ); @@ -2039,7 +2132,20 @@ bool CWeaponRPG::WeaponLOSCondition( const Vector &ownerPos, const Vector &targe Vector vecShootDir = npcOwner->GetActualShootTrajectory( vecMuzzle ); // Make sure I have a good 10 feet of wide clearance in front, or I'll blow my teeth out. +#ifdef MAPBASE + // Oh, and don't collide with ourselves or our owner. That would be stupid. + if (!weapon_rpg_use_old_behavior.GetBool()) + { + CTraceFilterSkipTwoEntities pTraceFilter( this, GetOwner(), COLLISION_GROUP_NONE ); + AI_TraceHull( vecMuzzle, vecMuzzle + vecShootDir * (10.0f*12.0f), Vector( -24, -24, -24 ), Vector( 24, 24, 24 ), MASK_NPCSOLID, &pTraceFilter, &tr ); + } + else + { +#endif AI_TraceHull( vecMuzzle, vecMuzzle + vecShootDir * (10.0f*12.0f), Vector( -24, -24, -24 ), Vector( 24, 24, 24 ), MASK_NPCSOLID, NULL, &tr ); +#ifdef MAPBASE + } +#endif if( tr.fraction != 1.0f ) bResult = false; @@ -2089,7 +2195,20 @@ int CWeaponRPG::WeaponRangeAttack1Condition( float flDot, float flDist ) Vector vecShootDir = pOwner->GetActualShootTrajectory( vecMuzzle ); // Make sure I have a good 10 feet of wide clearance in front, or I'll blow my teeth out. +#ifdef MAPBASE + // Oh, and don't collide with ourselves or our owner. That would be stupid. + if (!weapon_rpg_use_old_behavior.GetBool()) + { + CTraceFilterSkipTwoEntities pTraceFilter( this, GetOwner(), COLLISION_GROUP_NONE ); + AI_TraceHull( vecMuzzle, vecMuzzle + vecShootDir * (10.0f*12.0f), Vector( -24, -24, -24 ), Vector( 24, 24, 24 ), MASK_NPCSOLID, &pTraceFilter, &tr ); + } + else + { +#endif AI_TraceHull( vecMuzzle, vecMuzzle + vecShootDir * (10.0f*12.0f), Vector( -24, -24, -24 ), Vector( 24, 24, 24 ), MASK_NPCSOLID, NULL, &tr ); +#ifdef MAPBASE + } +#endif if( tr.fraction != 1.0 ) { @@ -2213,6 +2332,23 @@ void CWeaponRPG::UpdateLaserEffects( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponRPG::SupportsBackupActivity(Activity activity) +{ + // NPCs shouldn't use their SMG activities to aim and fire RPGs while running. + if (activity == ACT_RUN_AIM || + activity == ACT_WALK_AIM || + activity == ACT_RUN_CROUCH_AIM || + activity == ACT_WALK_CROUCH_AIM) + return false; + + return true; +} +#endif + //============================================================================= // Laser Dot //============================================================================= diff --git a/game/server/hl2/weapon_rpg.h b/game/server/hl2/weapon_rpg.h index b8ca99af..a536d1c2 100644 --- a/game/server/hl2/weapon_rpg.h +++ b/game/server/hl2/weapon_rpg.h @@ -165,6 +165,9 @@ class CAPCMissile : public CMissile //----------------------------------------------------------------------------- CAPCMissile *FindAPCMissileInCone( const Vector &vecOrigin, const Vector &vecDirection, float flAngle ); +#ifdef MAPBASE +extern ConVar weapon_rpg_fire_rate; +#endif //----------------------------------------------------------------------------- // RPG @@ -182,7 +185,11 @@ class CWeaponRPG : public CBaseHLCombatWeapon void Precache( void ); void PrimaryAttack( void ); +#ifdef MAPBASE + virtual float GetFireRate( void ) { return weapon_rpg_fire_rate.GetFloat(); }; +#else virtual float GetFireRate( void ) { return 1; }; +#endif void ItemPostFrame( void ); void Activate( void ); @@ -196,6 +203,10 @@ class CWeaponRPG : public CBaseHLCombatWeapon virtual void Drop( const Vector &vecVelocity ); +#ifdef MAPBASE + bool SupportsBackupActivity(Activity activity); +#endif + int GetMinBurst() { return 1; } int GetMaxBurst() { return 1; } float GetMinRestTime() { return 4.0; } @@ -205,6 +216,9 @@ class CWeaponRPG : public CBaseHLCombatWeapon int WeaponRangeAttack1Condition( float flDot, float flDist ); void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + void Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool bSecondary ); +#endif void StartGuiding( void ); void StopGuiding( void ); void ToggleGuiding( void ); diff --git a/game/server/hl2/weapon_shotgun.cpp b/game/server/hl2/weapon_shotgun.cpp index a832a3d6..5348e08a 100644 --- a/game/server/hl2/weapon_shotgun.cpp +++ b/game/server/hl2/weapon_shotgun.cpp @@ -24,6 +24,10 @@ extern ConVar sk_auto_reload_time; extern ConVar sk_plr_num_shotgun_pellets; +#ifdef MAPBASE +extern ConVar sk_plr_num_shotgun_pellets_double; +extern ConVar sk_npc_num_shotgun_pellets; +#endif class CWeaponShotgun : public CBaseHLCombatWeapon { @@ -104,6 +108,57 @@ END_DATADESC() acttable_t CWeaponShotgun::m_acttable[] = { +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Note that ACT_IDLE_SHOTGUN_AGITATED seems to be a stand-in for ACT_IDLE_SHOTGUN on citizens, + // but that isn't acceptable for NPCs which don't use readiness activities. + { ACT_IDLE, ACT_IDLE_SHOTGUN, true }, + + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, true }, + { ACT_RELOAD, ACT_RELOAD_SHOTGUN, false }, + { ACT_WALK, ACT_WALK_SHOTGUN, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SHOTGUN, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_SHOTGUN_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_SHOTGUN_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SHOTGUN, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_SHOTGUN_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_SHOTGUN_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_SHOTGUN, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_SHOTGUN_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_SHOTGUN_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_SHOTGUN, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_SHOTGUN_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_SHOTGUN_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SHOTGUN, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_SHOTGUN_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_SHOTGUN_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_SHOTGUN, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_SHOTGUN_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_SHOTGUN_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_SHOTGUN, false },//always aims +//End readiness activities + + { ACT_WALK_AIM, ACT_WALK_AIM_SHOTGUN, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_SHOTGUN, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_SHOTGUN, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SHOTGUN, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SHOTGUN_LOW, true }, + { ACT_RELOAD_LOW, ACT_RELOAD_SHOTGUN_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SHOTGUN, false }, + { ACT_COVER_LOW, ACT_COVER_SHOTGUN_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SHOTGUN_LOW, false }, +#else { ACT_IDLE, ACT_IDLE_SMG1, true }, // FIXME: hook to shotgun unique { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, true }, @@ -149,10 +204,49 @@ acttable_t CWeaponShotgun::m_acttable[] = { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SHOTGUN_LOW, true }, { ACT_RELOAD_LOW, ACT_RELOAD_SHOTGUN_LOW, false }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SHOTGUN, false }, +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_ARM, ACT_ARM_SHOTGUN, true }, + { ACT_DISARM, ACT_DISARM_SHOTGUN, true }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_SHOTGUN_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_SHOTGUN_MED, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SHOTGUN, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponShotgun); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the shotgun's activity table. +acttable_t *GetShotgunActtable() +{ + return CWeaponShotgun::m_acttable; +} + +int GetShotgunActtableCount() +{ + return ARRAYSIZE(CWeaponShotgun::m_acttable); +} +#endif + void CWeaponShotgun::Precache( void ) { CBaseCombatWeapon::Precache(); @@ -183,7 +277,11 @@ void CWeaponShotgun::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, bool vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); } +#ifdef MAPBASE + pOperator->FireBullets( sk_npc_num_shotgun_pellets.GetInt(), vecShootOrigin, vecShootDir, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 ); +#else pOperator->FireBullets( 8, vecShootOrigin, vecShootDir, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 ); +#endif } //----------------------------------------------------------------------------- @@ -308,6 +406,13 @@ bool CWeaponShotgun::StartReload( void ) pOwner->m_flNextAttack = gpGlobals->curtime; m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +#ifdef MAPBASE + if ( pOwner->IsPlayer() ) + { + static_cast(pOwner)->SetAnimation( PLAYER_RELOAD ); + } +#endif + m_bInReload = true; return true; } @@ -461,7 +566,11 @@ void CWeaponShotgun::PrimaryAttack( void ) pPlayer->SetAnimation( PLAYER_ATTACK1 ); // Don't fire again until fire animation has completed +#ifdef MAPBASE + m_flNextPrimaryAttack = gpGlobals->curtime + GetViewModelSequenceDuration(); +#else m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +#endif m_iClip1 -= 1; Vector vecSrc = pPlayer->Weapon_ShootPosition( ); @@ -516,17 +625,29 @@ void CWeaponShotgun::SecondaryAttack( void ) SendWeaponAnim( ACT_VM_SECONDARYATTACK ); // player "shoot" animation +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK2 ); +#else pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif // Don't fire again until fire animation has completed +#ifdef MAPBASE + m_flNextPrimaryAttack = gpGlobals->curtime + GetViewModelSequenceDuration(); +#else m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +#endif m_iClip1 -= 2; // Shotgun uses same clip for primary and secondary attacks Vector vecSrc = pPlayer->Weapon_ShootPosition(); Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT ); // Fire the bullets +#ifdef MAPBASE + pPlayer->FireBullets( sk_plr_num_shotgun_pellets_double.GetInt(), vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0, -1, -1, 0, NULL, false, false ); +#else pPlayer->FireBullets( 12, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0, -1, -1, 0, NULL, false, false ); +#endif pPlayer->ViewPunch( QAngle(random->RandomFloat( -5, 5 ),0,0) ); pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 1.0 ); diff --git a/game/server/hl2/weapon_smg1.cpp b/game/server/hl2/weapon_smg1.cpp index cc9934a4..b11fbedc 100644 --- a/game/server/hl2/weapon_smg1.cpp +++ b/game/server/hl2/weapon_smg1.cpp @@ -22,6 +22,9 @@ #include "tier0/memdbgon.h" extern ConVar sk_plr_dmg_smg1_grenade; +#ifdef MAPBASE +extern ConVar sk_npc_dmg_smg1_grenade; +#endif class CWeaponSMG1 : public CHLSelectFireMachineGun { @@ -131,10 +134,53 @@ acttable_t CWeaponSMG1::m_acttable[] = { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG1_LOW, false }, { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true }, + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_SMG1_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_SMG1_MED, false }, + + { ACT_COVER_WALL_R, ACT_COVER_WALL_R_RIFLE, false }, + { ACT_COVER_WALL_L, ACT_COVER_WALL_L_RIFLE, false }, + { ACT_COVER_WALL_LOW_R, ACT_COVER_WALL_LOW_R_RIFLE, false }, + { ACT_COVER_WALL_LOW_L, ACT_COVER_WALL_LOW_L_RIFLE, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG1, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_SMG1, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG1, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponSMG1); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the SMG1's activity table. +acttable_t *GetSMG1Acttable() +{ + return CWeaponSMG1::m_acttable; +} + +int GetSMG1ActtableCount() +{ + return ARRAYSIZE(CWeaponSMG1::m_acttable); +} +#endif + //========================================================= CWeaponSMG1::CWeaponSMG1( ) { @@ -202,6 +248,10 @@ void CWeaponSMG1::Operator_ForceNPCFire( CBaseCombatCharacter *pOperator, bool b FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir ); } +#ifdef MAPBASE +float GetCurrentGravity( void ); +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -228,6 +278,56 @@ void CWeaponSMG1::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatChar } break; +#ifdef MAPBASE + case EVENT_WEAPON_AR2_ALTFIRE: + { + WeaponSound( WPN_DOUBLE ); + + CAI_BaseNPC *npc = pOperator->MyNPCPointer(); + if (!npc) + return; + + Vector vecShootOrigin, vecShootDir; + vecShootOrigin = pOperator->Weapon_ShootPosition(); + vecShootDir = npc->GetShootEnemyDir( vecShootOrigin ); + + Vector vecTarget = npc->GetAltFireTarget(); + Vector vecThrow; + if (vecTarget == vec3_origin) + AngleVectors( npc->EyeAngles(), &vecThrow ); // Not much else to do, unfortunately + else + { + // Because this is happening right now, we can't "VecCheckThrow" and can only "VecDoThrow", you know what I mean? + // ...Anyway, this borrows from that so we'll never return vec3_origin. + //vecThrow = VecCheckThrow( this, vecShootOrigin, vecTarget, 600.0, 0.5 ); + + vecThrow = (vecTarget - vecShootOrigin); + + // throw at a constant time + float time = vecThrow.Length() / 600.0; + vecThrow = vecThrow * (1.0 / time); + + // adjust upward toss to compensate for gravity loss + vecThrow.z += (GetCurrentGravity() * 0.5) * time * 0.5; + } + + CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create( "grenade_ar2", vecShootOrigin, vec3_angle, npc ); + pGrenade->SetAbsVelocity( vecThrow ); + pGrenade->SetLocalAngularVelocity( QAngle( 0, 400, 0 ) ); + pGrenade->SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); + + pGrenade->SetThrower( npc ); + + pGrenade->SetGravity(0.5); // lower gravity since grenade is aerodynamic and engine doesn't know it. + + pGrenade->SetDamage(sk_npc_dmg_smg1_grenade.GetFloat()); + + variant_t var; + var.SetEntity(pGrenade); + npc->FireNamedOutput("OnThrowGrenade", var, pGrenade, npc); + } + break; +#else /*//FIXME: Re-enable case EVENT_WEAPON_AR2_GRENADE: { @@ -254,6 +354,7 @@ void CWeaponSMG1::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatChar } break; */ +#endif default: BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); @@ -368,7 +469,11 @@ void CWeaponSMG1::SecondaryAttack( void ) CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 1000, 0.2, GetOwner(), SOUNDENT_CHANNEL_WEAPON ); // player "shoot" animation +#ifdef MAPBASE + pPlayer->SetAnimation( PLAYER_ATTACK2 ); +#else pPlayer->SetAnimation( PLAYER_ATTACK1 ); +#endif // Decrease ammo pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType ); diff --git a/game/server/hl2/weapon_smg2.cpp b/game/server/hl2/weapon_smg2.cpp index 498faddd..9c5037b9 100644 --- a/game/server/hl2/weapon_smg2.cpp +++ b/game/server/hl2/weapon_smg2.cpp @@ -46,6 +46,77 @@ PRECACHE_WEAPON_REGISTER(weapon_smg2); acttable_t CWeaponSMG2::m_acttable[] = { { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG2, true }, + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // Optional new NPC activities + // (these should fall back to SMG animations when they don't exist on an NPC) + { ACT_RELOAD, ACT_RELOAD_SMG2, true }, + { ACT_IDLE, ACT_IDLE_SMG2, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG2, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_SMG2_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_SMG2_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SMG2, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_SMG2_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_SMG2_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_SMG2, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_SMG2_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_SMG2_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_SMG2, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_SMG2_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_SMG2_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SMG2, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_SMG2_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_SMG2_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_SMG2, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_SMG2_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_SMG2_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_SMG2, false },//always aims +//End readiness activities + + { ACT_WALK, ACT_WALK_SMG2, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_SMG2, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_SMG2, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_SMG2, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SMG2, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SMG2_LOW, true }, + { ACT_COVER_LOW, ACT_COVER_SMG2_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG2_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_SMG2_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG2, true }, + + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_SMG2_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_SMG2_MED, false }, +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG2, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG2, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG2, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG2, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG2, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_SMG2, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponSMG2); diff --git a/game/server/hl2/weapon_sniperrifle.cpp b/game/server/hl2/weapon_sniperrifle.cpp index 901a73ae..89887507 100644 --- a/game/server/hl2/weapon_sniperrifle.cpp +++ b/game/server/hl2/weapon_sniperrifle.cpp @@ -46,6 +46,10 @@ static int g_nZoomFOV[] = 5 }; +#ifdef MAPBASE +extern acttable_t *GetAR2Acttable(); +extern int GetAR2ActtableCount(); +#endif class CWeaponSniperRifle : public CBaseHLCombatWeapon { @@ -72,6 +76,11 @@ class CWeaponSniperRifle : public CBaseHLCombatWeapon void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#ifdef MAPBASE + virtual acttable_t *GetBackupActivityList() { return GetAR2Acttable(); } + virtual int GetBackupActivityListCount() { return GetAR2ActtableCount(); } +#endif + DECLARE_ACTTABLE(); protected: @@ -98,7 +107,78 @@ END_DATADESC() //----------------------------------------------------------------------------- acttable_t CWeaponSniperRifle::m_acttable[] = { - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SNIPER_RIFLE, true } + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SNIPER_RIFLE, true }, + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // Optional new NPC activities + // (these should fall back to AR2 animations when they don't exist on an NPC) + { ACT_RELOAD, ACT_RELOAD_SNIPER_RIFLE, true }, + { ACT_IDLE, ACT_IDLE_SNIPER_RIFLE, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SNIPER_RIFLE, true }, + +// Readiness activities (not aiming) + { ACT_IDLE_RELAXED, ACT_IDLE_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_IDLE_STIMULATED, ACT_IDLE_SNIPER_RIFLE_STIMULATED, false }, + { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SNIPER_RIFLE, false },//always aims + + { ACT_WALK_RELAXED, ACT_WALK_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_WALK_STIMULATED, ACT_WALK_SNIPER_RIFLE_STIMULATED, false }, + { ACT_WALK_AGITATED, ACT_WALK_AIM_SNIPER_RIFLE, false },//always aims + + { ACT_RUN_RELAXED, ACT_RUN_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_RUN_STIMULATED, ACT_RUN_SNIPER_RIFLE_STIMULATED, false }, + { ACT_RUN_AGITATED, ACT_RUN_AIM_SNIPER_RIFLE, false },//always aims + +// Readiness activities (aiming) + { ACT_IDLE_AIM_RELAXED, ACT_IDLE_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED, false }, + { ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SNIPER_RIFLE, false },//always aims + + { ACT_WALK_AIM_RELAXED, ACT_WALK_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED, false }, + { ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_SNIPER_RIFLE, false },//always aims + + { ACT_RUN_AIM_RELAXED, ACT_RUN_SNIPER_RIFLE_RELAXED, false },//never aims + { ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED, false }, + { ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_SNIPER_RIFLE, false },//always aims +//End readiness activities + + { ACT_WALK, ACT_WALK_SNIPER_RIFLE, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_SNIPER_RIFLE, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true }, + { ACT_RUN, ACT_RUN_SNIPER_RIFLE, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_SNIPER_RIFLE, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE, true }, + { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SNIPER_RIFLE_LOW, true }, + { ACT_COVER_LOW, ACT_COVER_SNIPER_RIFLE_LOW, false }, + { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SNIPER_RIFLE_LOW, false }, + { ACT_RELOAD_LOW, ACT_RELOAD_SNIPER_RIFLE_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SNIPER_RIFLE, true }, + + { ACT_ARM, ACT_ARM_RIFLE, false }, + { ACT_DISARM, ACT_DISARM_RIFLE, false }, + +#if EXPANDED_HL2_COVER_ACTIVITIES + { ACT_RANGE_AIM_MED, ACT_RANGE_AIM_SNIPER_RIFLE_MED, false }, + { ACT_RANGE_ATTACK1_MED, ACT_RANGE_ATTACK_SNIPER_RIFLE_MED, false }, +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + // HL2:DM activities (for third-person animations in SP) + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SNIPER_RIFLE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SNIPER_RIFLE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SNIPER_RIFLE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SNIPER_RIFLE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SNIPER_RIFLE, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_SNIPER_RIFLE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponSniperRifle); diff --git a/game/server/hl2/weapon_stunstick.h b/game/server/hl2/weapon_stunstick.h index 901b4721..9d3942c8 100644 --- a/game/server/hl2/weapon_stunstick.h +++ b/game/server/hl2/weapon_stunstick.h @@ -4,6 +4,13 @@ // //=============================================================================// +#ifdef MAPBASE + +// Redirect to HL2:DM's stunstick. +// It has NPC support now. +#include "hl2mp/weapon_stunstick.h" + +#else #ifndef WEAPON_STUNSTICK_H #define WEAPON_STUNSTICK_H #ifdef _WIN32 @@ -13,7 +20,12 @@ #include "basebludgeonweapon.h" #define STUNSTICK_RANGE 75.0f +#ifdef MAPBASE +// MP refire +#define STUNSTICK_REFIRE 0.8f +#else #define STUNSTICK_REFIRE 0.6f +#endif class CWeaponStunStick : public CBaseHLBludgeonWeapon { @@ -56,3 +68,4 @@ class CWeaponStunStick : public CBaseHLBludgeonWeapon }; #endif // WEAPON_STUNSTICK_H +#endif diff --git a/game/server/hl2mp/grenade_tripmine.cpp b/game/server/hl2mp/grenade_tripmine.cpp index e14a929d..39918869 100644 --- a/game/server/hl2mp/grenade_tripmine.cpp +++ b/game/server/hl2mp/grenade_tripmine.cpp @@ -34,6 +34,18 @@ BEGIN_DATADESC( CTripmineGrenade ) DEFINE_FIELD( m_pBeam, FIELD_CLASSPTR ), DEFINE_FIELD( m_posOwner, FIELD_POSITION_VECTOR ), DEFINE_FIELD( m_angleOwner, FIELD_VECTOR ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flPowerUpTime, FIELD_FLOAT, "PowerUpTime" ), + DEFINE_FIELD( m_hAttacker, FIELD_EHANDLE ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetOwner", InputSetOwner ), + + // Outputs + DEFINE_OUTPUT( m_OnExplode, "OnExplode" ), +#endif // Function Pointers DEFINE_THINKFUNC( WarningThink ), @@ -49,6 +61,10 @@ CTripmineGrenade::CTripmineGrenade() m_vecEnd.Init(); m_posOwner.Init(); m_angleOwner.Init(); + +#ifdef MAPBASE + m_flPowerUpTime = 2.0; +#endif } void CTripmineGrenade::Spawn( void ) @@ -65,18 +81,46 @@ void CTripmineGrenade::Spawn( void ) SetCycle( 0.0f ); m_nBody = 3; +#ifdef MAPBASE + if (m_flDamage == 0) + m_flDamage = sk_plr_dmg_tripmine.GetFloat(); + if (m_DmgRadius == 0) + m_DmgRadius = sk_tripmine_radius.GetFloat(); +#else m_flDamage = sk_plr_dmg_tripmine.GetFloat(); m_DmgRadius = sk_tripmine_radius.GetFloat(); +#endif ResetSequenceInfo( ); m_flPlaybackRate = 0; UTIL_SetSize(this, Vector( -4, -4, -2), Vector(4, 4, 2)); +#ifdef MAPBASE + if (!HasSpawnFlags(SF_TRIPMINE_START_INACTIVE)) + { + if (m_flPowerUpTime > 0) + { + m_flPowerUp = gpGlobals->curtime + m_flPowerUpTime; + + SetThink( &CTripmineGrenade::PowerupThink ); + SetNextThink( gpGlobals->curtime + 0.2 ); + } + else + { + MakeBeam( ); + RemoveSolidFlags( FSOLID_NOT_SOLID ); + m_bIsLive = true; + + //EmitSound( "TripmineGrenade.Activate" ); + } + } +#else m_flPowerUp = gpGlobals->curtime + 2.0; SetThink( &CTripmineGrenade::PowerupThink ); SetNextThink( gpGlobals->curtime + 0.2 ); +#endif m_takedamage = DAMAGE_YES; @@ -222,7 +266,11 @@ void CTripmineGrenade::BeamBreakThink( void ) if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001) { m_iHealth = 0; +#ifdef MAPBASE + Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, pEntity, 100, GIB_NORMAL ) ); +#else Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) ); +#endif return; } @@ -254,6 +302,10 @@ void CTripmineGrenade::Event_Killed( const CTakeDamageInfo &info ) { m_takedamage = DAMAGE_NO; +#ifdef MAPBASE + m_hAttacker = info.GetAttacker(); +#endif + SetThink( &CTripmineGrenade::DelayDeathThink ); SetNextThink( gpGlobals->curtime + 0.25 ); @@ -271,6 +323,48 @@ void CTripmineGrenade::DelayDeathThink( void ) ExplosionCreate( GetAbsOrigin() + m_vecDir * 8, GetAbsAngles(), m_hOwner, GetDamage(), 200, SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this); +#ifdef MAPBASE + m_OnExplode.FireOutput(m_hAttacker.Get(), this); +#endif + UTIL_Remove( this ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CTripmineGrenade::InputActivate( inputdata_t &inputdata ) +{ + if (m_flPowerUpTime > 0) + { + m_flPowerUp = gpGlobals->curtime + m_flPowerUpTime; + + SetThink( &CTripmineGrenade::PowerupThink ); + SetNextThink( gpGlobals->curtime + 0.2 ); + } + else + { + MakeBeam( ); + RemoveSolidFlags( FSOLID_NOT_SOLID ); + m_bIsLive = true; + + //EmitSound( "TripmineGrenade.Activate" ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CTripmineGrenade::InputDeactivate( inputdata_t &inputdata ) +{ + KillBeam( ); + //AddSolidFlags( FSOLID_NOT_SOLID ); + m_bIsLive = false; +} +#endif + diff --git a/game/server/hl2mp/grenade_tripmine.h b/game/server/hl2mp/grenade_tripmine.h index e1887096..9ec9e726 100644 --- a/game/server/hl2mp/grenade_tripmine.h +++ b/game/server/hl2mp/grenade_tripmine.h @@ -15,6 +15,9 @@ class CBeam; +#ifdef MAPBASE +#define SF_TRIPMINE_START_INACTIVE (1 << 0) +#endif class CTripmineGrenade : public CBaseGrenade { @@ -37,9 +40,24 @@ class CTripmineGrenade : public CBaseGrenade void MakeBeam( void ); void KillBeam( void ); +#ifdef MAPBASE + void PowerUp(); + + void InputActivate( inputdata_t &inputdata ); + void InputDeactivate( inputdata_t &inputdata ); + void InputSetOwner( inputdata_t &inputdata ) { m_hOwner = inputdata.value.Entity(); } + + COutputEvent m_OnExplode; +#endif + public: EHANDLE m_hOwner; +#ifdef MAPBASE + float m_flPowerUpTime; + EHANDLE m_hAttacker; +#endif + private: float m_flPowerUp; Vector m_vecDir; diff --git a/game/server/hltvdirector.h b/game/server/hltvdirector.h index 653bf1dd..1b390e83 100644 --- a/game/server/hltvdirector.h +++ b/game/server/hltvdirector.h @@ -67,7 +67,7 @@ class CHLTVDirector : public CGameEventListener, public CBaseGameSystemPerFrame, virtual void Shutdown(); virtual void FrameUpdatePostEntityThink(); virtual void LevelInitPostEntity(); - virtual char *GetFixedCameraEntityName( void ) { return "point_viewcontrol"; } + virtual const char *GetFixedCameraEntityName( void ) { return "point_viewcontrol"; } bool SetCameraMan( int iPlayerIndex ); int GetCameraMan() { return m_iCameraManIndex; } diff --git a/game/server/ilagcompensationmanager.h b/game/server/ilagcompensationmanager.h index b8749040..507d29bf 100644 --- a/game/server/ilagcompensationmanager.h +++ b/game/server/ilagcompensationmanager.h @@ -23,7 +23,6 @@ abstract_class ILagCompensationManager // Called during player movement to set up/restore after lag compensation virtual void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) = 0; virtual void FinishLagCompensation( CBasePlayer *player ) = 0; - virtual bool IsCurrentlyDoingLagCompensation() const = 0; }; extern ILagCompensationManager *lagcompensation; diff --git a/game/server/item_world.cpp b/game/server/item_world.cpp index e4233172..6f124280 100644 --- a/game/server/item_world.cpp +++ b/game/server/item_world.cpp @@ -103,6 +103,14 @@ BEGIN_DATADESC( CItem ) DEFINE_THINKFUNC( FallThink ), #endif +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "EnablePlayerPickup", InputEnablePlayerPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisablePlayerPickup", InputDisablePlayerPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableNPCPickup", InputEnableNPCPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableNPCPickup", InputDisableNPCPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "BreakConstraint", InputBreakConstraint ), +#endif + // Outputs DEFINE_OUTPUT( m_OnPlayerTouch, "OnPlayerTouch" ), DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ), @@ -344,6 +352,19 @@ bool UTIL_ItemCanBeTouchedByPlayer( CBaseEntity *pItem, CBasePlayer *pPlayer ) if ( pItem == NULL || pPlayer == NULL ) return false; +#ifdef MAPBASE + // Weapons go through this, but this is identical to SF_WEAPON_NO_PLAYER_PICKUP and that would be a convenient coincidence, + // but OnCacheInteraction worked with "No player pickup" before and SF_WEAPON_NO_PLAYER_PICKUP is often checked after this, + // so we have to make sure we're not dealing with a weapon for this check after all. + if (pItem->HasSpawnFlags(SF_ITEM_NO_PLAYER_PICKUP) && !pItem->IsBaseCombatWeapon()) + return false; + + // Fortunately, unlike the above code, this flag is identical in between weapons and items + // and can safely be used without identifying the entity. + if (pItem->HasSpawnFlags(SF_ITEM_ALWAYS_TOUCHABLE)) + return true; +#endif + // For now, always allow a vehicle riding player to pick up things they're driving over if ( pPlayer->IsInAVehicle() ) return true; @@ -545,3 +566,49 @@ void CItem::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason ) // Restore the pickup box to the original CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT ); } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem::InputEnablePlayerPickup( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_ITEM_NO_PLAYER_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem::InputDisablePlayerPickup( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_ITEM_NO_PLAYER_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem::InputEnableNPCPickup( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_ITEM_NO_NPC_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem::InputDisableNPCPickup( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_ITEM_NO_NPC_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem::InputBreakConstraint( inputdata_t &inputdata ) +{ + if ( m_pConstraint != NULL ) + { + physenv->DestroyConstraint( m_pConstraint ); + m_pConstraint = NULL; + } +} +#endif diff --git a/game/server/items.h b/game/server/items.h index bc1bb77e..6209c15e 100644 --- a/game/server/items.h +++ b/game/server/items.h @@ -36,6 +36,15 @@ #define SIZE_AMMO_AR2_ALTFIRE 1 #define SF_ITEM_START_CONSTRAINED 0x00000001 +#ifdef MAPBASE +// Copied from CBaseCombatWeapon's flags, including any additions we made to those. +// I really, REALLY hope no item uses their own spawnflags either. +#define SF_ITEM_NO_PLAYER_PICKUP (1<<1) +#define SF_ITEM_NO_PHYSCANNON_PUNT (1<<2) +#define SF_ITEM_NO_NPC_PICKUP (1<<3) + +#define SF_ITEM_ALWAYS_TOUCHABLE (1<<6) // This needs to stay synced with the weapon spawnflag +#endif class CItem : public CBaseAnimating, public CDefaultPlayerPickupVPhysics @@ -79,13 +88,27 @@ class CItem : public CBaseAnimating, public CDefaultPlayerPickupVPhysics float m_flNextResetCheckTime; #endif +#ifdef MAPBASE + // This appeared to have no prior use in Source SDK 2013. + // It may have been originally intended for TF2 or some other game-specific item class. + virtual bool IsCombatItem() const { return true; } + + // Used to access item_healthkit values, etc. from outside of the class + virtual float GetItemAmount() { return 1.0f; } + + void InputEnablePlayerPickup( inputdata_t &inputdata ); + void InputDisablePlayerPickup( inputdata_t &inputdata ); + void InputEnableNPCPickup( inputdata_t &inputdata ); + void InputDisableNPCPickup( inputdata_t &inputdata ); + void InputBreakConstraint( inputdata_t &inputdata ); +#endif + DECLARE_DATADESC(); protected: virtual void ComeToRest( void ); - bool m_bActivateWhenAtRest; private: - + bool m_bActivateWhenAtRest; COutputEvent m_OnPlayerTouch; COutputEvent m_OnCacheInteraction; diff --git a/game/server/lightglow.cpp b/game/server/lightglow.cpp index 59d0505d..d941f033 100644 --- a/game/server/lightglow.cpp +++ b/game/server/lightglow.cpp @@ -33,6 +33,10 @@ class CLightGlow : public CBaseEntity virtual int UpdateTransmitState( void ); void InputColor(inputdata_t &data); +#ifdef MAPBASE + void InputEnable( inputdata_t &data ) { m_bDisabled = false; } + void InputDisable( inputdata_t &data ) { m_bDisabled = true; } +#endif public: CNetworkVar( int, m_nHorizontalSize ); @@ -43,6 +47,10 @@ class CLightGlow : public CBaseEntity CNetworkVar( float, m_flGlowProxySize ); CNetworkVar( float, m_flHDRColorScale ); + +#ifdef MAPBASE + CNetworkVar( bool, m_bDisabled ); +#endif }; extern void SendProxy_Angles( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); @@ -60,6 +68,9 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CLightGlow, DT_LightGlow ) SendPropEHandle (SENDINFO_NAME(m_hMoveParent, moveparent)), SendPropFloat( SENDINFO(m_flGlowProxySize ), 6, SPROP_ROUNDUP, 0.0f, 64.0f ), SendPropFloat( SENDINFO_NAME( m_flHDRColorScale, HDRColorScale ), 0, SPROP_NOSCALE, 0.0f, 100.0f ), +#ifdef MAPBASE + SendPropBool( SENDINFO( m_bDisabled ) ), +#endif END_SEND_TABLE() LINK_ENTITY_TO_CLASS( env_lightglow, CLightGlow ); @@ -73,6 +84,11 @@ BEGIN_DATADESC( CLightGlow ) DEFINE_KEYFIELD( m_nOuterMaxDist, FIELD_INTEGER, "OuterMaxDist" ), DEFINE_KEYFIELD( m_flGlowProxySize, FIELD_FLOAT, "GlowProxySize" ), DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#endif DEFINE_INPUTFUNC( FIELD_COLOR32, "Color", InputColor ), END_DATADESC() diff --git a/game/server/logic_measure_movement.cpp b/game/server/logic_measure_movement.cpp index bf074bd0..06c3da45 100644 --- a/game/server/logic_measure_movement.cpp +++ b/game/server/logic_measure_movement.cpp @@ -7,10 +7,31 @@ #include "cbase.h" #include "baseentity.h" +#ifdef MAPBASE +#include "filters.h" +#include "ai_basenpc.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +// These spawnflags were originally only on logic_measure_direction. +#define SF_LOGIC_MEASURE_MOVEMENT_IGNORE_X ( 1 << 0 ) +#define SF_LOGIC_MEASURE_MOVEMENT_IGNORE_Y ( 1 << 1 ) +#define SF_LOGIC_MEASURE_MOVEMENT_IGNORE_Z ( 1 << 2 ) + +// Uses the "Ignore X/Y/Z" flags for the origin instead of the angles. +// logic_measure_direction uses this flag to control trace direction. +#define SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN ( 1 << 3 ) + +// Uses "Teleport" instead of "SetAbsOrigin" for smoother movement +#define SF_LOGIC_MEASURE_MOVEMENT_TELEPORT ( 1 << 4 ) + +// Specifically refuse to set the target's angles, rather than just turning them to 0 +#define SF_LOGIC_MEASURE_MOVEMENT_DONT_SET_ANGLES ( 1 << 5 ) +#endif + //----------------------------------------------------------------------------- // This will measure the movement of a target entity and move // another entity to match the movement of the first. @@ -23,7 +44,11 @@ class CLogicMeasureMovement : public CLogicalEntity public: virtual void Activate(); +#ifdef MAPBASE +public: +#else private: +#endif void SetMeasureTarget( const char *pName ); void SetMeasureReference( const char *pName ); void SetTarget( const char *pName ); @@ -37,13 +62,30 @@ class CLogicMeasureMovement : public CLogicalEntity void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + // Allows for derived class trickery + void MeasureThink(); //{ DoMeasure(); } + + // Allows for InputGetPosition(), etc. + virtual void DoMeasure(Vector &vecOrigin, QAngle &angAngles); + void HandleIgnoreFlags( float *vec ); + + void InputSetMeasureAttachment( inputdata_t &inputdata ); + void InputSetMeasureType( inputdata_t &inputdata ) { m_nMeasureType = inputdata.value.Int(); } + void InputGetPosition( inputdata_t &inputdata ); +#else void MeasureThink(); private: +#endif enum { MEASURE_POSITION = 0, MEASURE_EYE_POSITION, +#ifdef MAPBASE + MEASURE_ATTACHMENT, + //MEASURE_BARREL_POSITION, +#endif }; string_t m_strMeasureTarget; @@ -55,6 +97,16 @@ class CLogicMeasureMovement : public CLogicalEntity EHANDLE m_hTarget; EHANDLE m_hTargetReference; +#ifdef MAPBASE + string_t m_strAttachment; + int m_iAttachment; + + bool m_bOutputPosition; + + COutputVector m_OutPosition; + COutputVector m_OutAngles; +#endif + float m_flScale; int m_nMeasureType; }; @@ -70,6 +122,17 @@ BEGIN_DATADESC( CLogicMeasureMovement ) DEFINE_KEYFIELD( m_strTargetReference, FIELD_STRING, "TargetReference" ), DEFINE_KEYFIELD( m_flScale, FIELD_FLOAT, "TargetScale" ), DEFINE_KEYFIELD( m_nMeasureType, FIELD_INTEGER, "MeasureType" ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMeasureType", InputSetMeasureType ), + + DEFINE_KEYFIELD( m_strAttachment, FIELD_STRING, "MeasureAttachment" ), + DEFINE_FIELD( m_iAttachment, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetMeasureAttachment", InputSetMeasureAttachment ), + + DEFINE_INPUT( m_bOutputPosition, FIELD_BOOLEAN, "ShouldOutputPosition" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "GetPosition", InputGetPosition ), +#endif DEFINE_FIELD( m_hMeasureTarget, FIELD_EHANDLE ), DEFINE_FIELD( m_hMeasureReference, FIELD_EHANDLE ), @@ -79,12 +142,20 @@ BEGIN_DATADESC( CLogicMeasureMovement ) DEFINE_INPUTFUNC( FIELD_STRING, "SetMeasureTarget", InputSetMeasureTarget ), DEFINE_INPUTFUNC( FIELD_STRING, "SetMeasureReference", InputSetMeasureReference ), DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget", InputSetTarget ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "Target", InputSetTarget ), // For legacy support...even though that name was broken before. +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetTargetReference", InputSetTargetReference ), DEFINE_INPUTFUNC( FIELD_FLOAT, "SetTargetScale", InputSetTargetScale ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OutPosition, "OutPosition" ), + DEFINE_OUTPUT( m_OutAngles, "OutAngles" ), +#endif + DEFINE_THINKFUNC( MeasureThink ), END_DATADESC() @@ -112,40 +183,75 @@ void CLogicMeasureMovement::Activate() //----------------------------------------------------------------------------- void CLogicMeasureMovement::SetMeasureTarget( const char *pName ) { +#ifdef MAPBASE + m_hMeasureTarget = gEntList.FindEntityByName( NULL, pName, this ); +#else m_hMeasureTarget = gEntList.FindEntityByName( NULL, pName ); +#endif if ( !m_hMeasureTarget ) { if ( Q_strnicmp( STRING(m_strMeasureTarget), "!player", 8 ) ) { +#ifdef MAPBASE + Warning( "%s: Unable to find measure target entity %s\n", GetDebugName(), pName ); +#else Warning("logic_measure_movement: Unable to find measure target entity %s\n", pName ); +#endif } } +#ifdef MAPBASE + m_iAttachment = 0; +#endif } void CLogicMeasureMovement::SetMeasureReference( const char *pName ) { +#ifdef MAPBASE + m_hMeasureReference = gEntList.FindEntityByName( NULL, pName, this ); +#else m_hMeasureReference = gEntList.FindEntityByName( NULL, pName ); +#endif if ( !m_hMeasureReference ) { +#ifdef MAPBASE + Warning( "%s: Unable to find measure reference entity %s\n", GetDebugName(), pName ); +#else Warning("logic_measure_movement: Unable to find measure reference entity %s\n", pName ); +#endif } } void CLogicMeasureMovement::SetTarget( const char *pName ) { +#ifdef MAPBASE + m_hTarget = gEntList.FindEntityByName( NULL, pName, this ); +#else m_hTarget = gEntList.FindEntityByName( NULL, pName ); +#endif if ( !m_hTarget ) { +#ifdef MAPBASE + Warning( "%s: Unable to find movement target entity %s\n", GetDebugName(), pName ); +#else Warning("logic_measure_movement: Unable to find movement target entity %s\n", pName ); +#endif } } void CLogicMeasureMovement::SetTargetReference( const char *pName ) { +#ifdef MAPBASE + m_hTargetReference = gEntList.FindEntityByName( NULL, pName, this ); +#else m_hTargetReference = gEntList.FindEntityByName( NULL, pName ); +#endif if ( !m_hTargetReference ) { +#ifdef MAPBASE + Warning( "%s: Unable to find movement reference entity %s\n", GetDebugName(), pName ); +#else Warning("logic_measure_movement: Unable to find movement reference entity %s\n", pName ); +#endif } } @@ -165,6 +271,29 @@ void CLogicMeasureMovement::MeasureThink( ) // Make sure all entities are valid if ( m_hMeasureTarget.Get() && m_hMeasureReference.Get() && m_hTarget.Get() && m_hTargetReference.Get() ) { +#ifdef MAPBASE + Vector vecNewOrigin; + QAngle vecNewAngles; + DoMeasure(vecNewOrigin, vecNewAngles); + + if (m_bOutputPosition) + { + m_OutPosition.Set(vecNewOrigin, m_hTarget.Get(), this); + m_OutAngles.Set(vecNewAngles, m_hTarget.Get(), this); + } + + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_TELEPORT )) + { + m_hTarget->Teleport( &vecNewOrigin, !HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_DONT_SET_ANGLES) ? &vecNewAngles : NULL, NULL ); + } + else + { + m_hTarget->SetAbsOrigin( vecNewOrigin ); + + if (!HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_DONT_SET_ANGLES)) + m_hTarget->SetAbsAngles( vecNewAngles ); + } +#else matrix3x4_t matRefToMeasure, matWorldToMeasure; switch( m_nMeasureType ) { @@ -175,7 +304,6 @@ void CLogicMeasureMovement::MeasureThink( ) case MEASURE_EYE_POSITION: AngleIMatrix( m_hMeasureTarget->EyeAngles(), m_hMeasureTarget->EyePosition(), matWorldToMeasure ); break; - // FIXME: Could add attachment point measurement here easily } @@ -201,11 +329,103 @@ void CLogicMeasureMovement::MeasureThink( ) MatrixAngles( matNewTargetToWorld, vecNewAngles, vecNewOrigin ); m_hTarget->SetAbsOrigin( vecNewOrigin ); m_hTarget->SetAbsAngles( vecNewAngles ); +#endif } SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Moves logic_measure_movement's movement measurements to its own function, +// primarily to allow for the GetPosition input without any hacks. +// Also helps with derivative entities that would otherwise have to find a way to re-define the think function. +// Warning: Doesn't account for whether these handles are null! +//----------------------------------------------------------------------------- +void CLogicMeasureMovement::DoMeasure( Vector &vecOrigin, QAngle &angAngles ) +{ + matrix3x4_t matRefToMeasure, matWorldToMeasure; + switch( m_nMeasureType ) + { + case MEASURE_POSITION: + MatrixInvert( m_hMeasureTarget->EntityToWorldTransform(), matWorldToMeasure ); + break; + + case MEASURE_EYE_POSITION: + AngleIMatrix( m_hMeasureTarget->EyeAngles(), m_hMeasureTarget->EyePosition(), matWorldToMeasure ); + break; + + case MEASURE_ATTACHMENT: + if (CBaseAnimating *pAnimating = m_hMeasureTarget->GetBaseAnimating()) + { + if (m_iAttachment <= 0) + m_iAttachment = m_hMeasureTarget->GetBaseAnimating()->LookupAttachment(STRING(m_strAttachment)); + + if (m_iAttachment == -1) + Warning("WARNING: %s requesting invalid attachment %s on %s!\n", GetDebugName(), STRING(m_strAttachment), m_hMeasureTarget->GetDebugName()); + else + pAnimating->GetAttachment(m_iAttachment, matWorldToMeasure); + } + else + { + Warning("WARNING: %s requesting attachment point on non-animating entity %s!\n", GetDebugName(), m_hMeasureTarget->GetDebugName()); + } + break; + } + + ConcatTransforms( matWorldToMeasure, m_hMeasureReference->EntityToWorldTransform(), matRefToMeasure ); + + // Apply the scale factor + if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) + { + Vector vecTranslation; + MatrixGetColumn( matRefToMeasure, 3, vecTranslation ); + vecTranslation /= m_flScale; + MatrixSetColumn( vecTranslation, 3, matRefToMeasure ); + } + + // Now apply the new matrix to the new reference point + matrix3x4_t matMeasureToRef, matNewTargetToWorld; + MatrixInvert( matRefToMeasure, matMeasureToRef ); + + // Handle origin ignorance + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN )) + { + // Get the position from the matrix's column directly and re-assign it + Vector vecPosition; + MatrixGetColumn( matMeasureToRef, 3, vecPosition ); + + HandleIgnoreFlags( vecPosition.Base() ); + + MatrixSetColumn( vecPosition, 3, matMeasureToRef ); + } + + ConcatTransforms( m_hTargetReference->EntityToWorldTransform(), matMeasureToRef, matNewTargetToWorld ); + + MatrixAngles( matNewTargetToWorld, angAngles, vecOrigin ); + + // If our spawnflags are greater than 0 (and don't just contain our default "TELEPORT" flag), we might need to ignore one of our angles. + if (GetSpawnFlags() && GetSpawnFlags() != SF_LOGIC_MEASURE_MOVEMENT_TELEPORT && !HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN)) + { + HandleIgnoreFlags( angAngles.Base() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Handles logic_measure_movement's ignore flags on the specified Vector/QAngle +//----------------------------------------------------------------------------- +FORCEINLINE void CLogicMeasureMovement::HandleIgnoreFlags( float *vec ) +{ + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_IGNORE_X )) + vec[0] = 0.0f; + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_IGNORE_Y )) + vec[1] = 0.0f; + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_IGNORE_Z )) + vec[2] = 0.0f; +} +#endif + //----------------------------------------------------------------------------- // Enable, disable @@ -225,6 +445,84 @@ void CLogicMeasureMovement::InputDisable( inputdata_t &inputdata ) //----------------------------------------------------------------------------- // Methods to change various targets //----------------------------------------------------------------------------- +#ifdef MAPBASE + +// +// Inputs work differently now so they could take !activator, etc. +// + +void CLogicMeasureMovement::InputSetMeasureTarget( inputdata_t &inputdata ) +{ + m_strMeasureTarget = inputdata.value.StringID(); + m_hMeasureTarget = gEntList.FindEntityByName( NULL, STRING(m_strMeasureTarget), this, inputdata.pActivator, inputdata.pCaller ); + if ( !m_hMeasureTarget ) + { + if ( Q_strnicmp( STRING(m_strMeasureTarget), "!player", 8 ) ) + { + Warning( "%s: Unable to find measure target entity %s\n", GetDebugName(), STRING(m_strMeasureTarget) ); + } + } + + m_iAttachment = 0; + + if (!m_hTarget) + SetTarget( STRING(m_target) ); + if (!m_hTargetReference) + SetTargetReference( STRING(m_strTargetReference) ); +} + +void CLogicMeasureMovement::InputSetMeasureReference( inputdata_t &inputdata ) +{ + m_strMeasureReference = inputdata.value.StringID(); + m_hMeasureReference = gEntList.FindEntityByName( NULL, STRING(m_strMeasureReference), this, inputdata.pActivator, inputdata.pCaller ); + if ( !m_hMeasureReference ) + { + Warning( "%s: Unable to find measure reference entity %s\n", GetDebugName(), STRING(m_strMeasureReference) ); + } +} + +void CLogicMeasureMovement::InputSetTarget( inputdata_t &inputdata ) +{ + m_target = inputdata.value.StringID(); + m_hTarget = gEntList.FindEntityByName( NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller ); + if ( !m_hTarget ) + { + Warning( "%s: Unable to find movement target entity %s\n", GetDebugName(), STRING(m_target) ); + } +} + +void CLogicMeasureMovement::InputSetTargetReference( inputdata_t &inputdata ) +{ + m_strTargetReference = inputdata.value.StringID(); + m_hTargetReference = gEntList.FindEntityByName( NULL, STRING(m_strTargetReference), this, inputdata.pActivator, inputdata.pCaller ); + if ( !m_hTargetReference ) + { + Warning( "%s: Unable to find movement reference entity %s\n", GetDebugName(), STRING(m_strTargetReference) ); + } +} + +void CLogicMeasureMovement::InputSetMeasureAttachment( inputdata_t &inputdata ) +{ + m_strAttachment = inputdata.value.StringID(); + m_iAttachment = 0; +} + +// Just gets the position once and fires outputs without moving anything. +// We don't even need a target for this. +void CLogicMeasureMovement::InputGetPosition( inputdata_t &inputdata ) +{ + if ( !m_hMeasureTarget.Get() || !m_hMeasureReference.Get() || !m_hTargetReference.Get() ) + return; + + Vector vecNewOrigin; + QAngle vecNewAngles; + DoMeasure(vecNewOrigin, vecNewAngles); + + // m_bOutputPosition has been repurposed here to toggle between using the target or the input activator as the activator. + m_OutPosition.Set(vecNewOrigin, m_bOutputPosition ? m_hTarget.Get() : inputdata.pActivator, this); + m_OutAngles.Set(Vector(vecNewAngles.x, vecNewAngles.y, vecNewAngles.z), m_bOutputPosition ? m_hTarget.Get() : inputdata.pActivator, this); +} +#else void CLogicMeasureMovement::InputSetMeasureTarget( inputdata_t &inputdata ) { m_strMeasureTarget = MAKE_STRING( inputdata.value.String() ); @@ -250,8 +548,354 @@ void CLogicMeasureMovement::InputSetTargetReference( inputdata_t &inputdata ) m_strTargetReference = MAKE_STRING( inputdata.value.String() ); SetTargetReference( inputdata.value.String() ); } +#endif void CLogicMeasureMovement::InputSetTargetScale( inputdata_t &inputdata ) { m_flScale = inputdata.value.Float(); } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// This will measure the direction of a target entity and move +// another entity to where the target entity is facing. +// +// m_hMeasureTarget; // Whose direction is measured +// m_hMeasureReference; // Position where direction is measured +// m_hTarget; // Target whose origin is applied +// m_hTargetReference; // From where the target's origin is applied +//----------------------------------------------------------------------------- +class CLogicMeasureDirection : public CLogicMeasureMovement +{ + DECLARE_DATADESC(); + DECLARE_CLASS( CLogicMeasureDirection, CLogicMeasureMovement ); + +public: + + virtual void DoMeasure(Vector &vecOrigin, QAngle &angAngles); + + CBaseFilter *GetTraceFilter(); + //void InputSetTraceFilter( inputdata_t &inputdata ) { InputSetDamageFilter(inputdata); } + +private: + + float m_flTraceDistance; + int m_iMask; + int m_iCollisionGroup; + bool m_bHitIfPassed; + //string_t m_iszTraceFilter; + //CHandle m_hTraceFilter; + + bool m_bTraceTargetReference; + +}; + + +LINK_ENTITY_TO_CLASS( logic_measure_direction, CLogicMeasureDirection ); + + +BEGIN_DATADESC( CLogicMeasureDirection ) + + DEFINE_KEYFIELD( m_flTraceDistance, FIELD_FLOAT, "TraceDistance" ), + DEFINE_KEYFIELD( m_iMask, FIELD_INTEGER, "Mask" ), + DEFINE_KEYFIELD( m_iCollisionGroup, FIELD_INTEGER, "CollisionGroup" ), + DEFINE_KEYFIELD( m_bHitIfPassed, FIELD_BOOLEAN, "HitIfPassed" ), + DEFINE_KEYFIELD( m_bTraceTargetReference, FIELD_BOOLEAN, "TraceTargetReference" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetTraceFilter", InputSetDamageFilter ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Gets our "trace filter". +//----------------------------------------------------------------------------- +inline CBaseFilter *CLogicMeasureDirection::GetTraceFilter() +{ + return static_cast(m_hDamageFilter.Get()); // pranked +} + +//----------------------------------------------------------------------------- +// Purpose: Does measure. +//----------------------------------------------------------------------------- +void CLogicMeasureDirection::DoMeasure( Vector &vecOrigin, QAngle &angAngles ) +{ + trace_t tr; + Vector vecStart, vecDir; + QAngle angStart; + switch( m_nMeasureType ) + { + case MEASURE_POSITION: + vecStart = m_hMeasureReference->GetAbsOrigin(); + angStart = m_hMeasureTarget->GetAbsAngles(); + break; + + case MEASURE_EYE_POSITION: + vecStart = m_hMeasureReference->EyePosition(); + angStart = m_hMeasureTarget->EyeAngles(); + break; + + case MEASURE_ATTACHMENT: + CBaseAnimating *pAnimating = m_hMeasureTarget->GetBaseAnimating(); + if (pAnimating) + { + if (m_iAttachment <= 0) + m_iAttachment = m_hMeasureTarget->GetBaseAnimating()->LookupAttachment(STRING(m_strAttachment)); + + if (m_iAttachment == -1) + Warning("WARNING: %s requesting invalid attachment %s on %s!\n", GetDebugName(), STRING(m_strAttachment), m_hMeasureTarget->GetDebugName()); + else + { + pAnimating->GetAttachment(m_iAttachment, vecStart, angStart); + } + } + else + { + Warning("WARNING: %s requesting attachment point on non-animating entity %s!\n", GetDebugName(), m_hMeasureTarget->GetDebugName()); + } + break; + } + + // If we have spawn flags, we might be supposed to ignore something + if (GetSpawnFlags() > 0) + { + if (!HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN)) + AngleVectors(angStart, &vecDir); + + HandleIgnoreFlags( angStart.Base() ); + + if (HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN)) + AngleVectors(angStart, &vecDir); + } + else + { + AngleVectors(angStart, &vecDir); + } + + CTraceFilterEntityFilter traceFilter(m_hMeasureReference, m_iCollisionGroup); + traceFilter.m_pFilter = GetTraceFilter(); + traceFilter.m_bHitIfPassed = m_bHitIfPassed; + UTIL_TraceLine( vecStart, vecStart + vecDir * (m_flTraceDistance != 0 ? m_flTraceDistance : MAX_TRACE_LENGTH), m_iMask, &traceFilter, &tr ); //MASK_BLOCKLOS_AND_NPCS + + Vector vecEnd = tr.endpos; + + // Apply the scale factor + float flScale = m_flScale; + if ( ( flScale != 0.0f ) && ( flScale != 1.0f ) ) + { + vecEnd = (vecStart + ((vecEnd - vecStart) / flScale)); + } + + Vector refPos = m_hTargetReference->GetAbsOrigin(); + Vector vecPos = refPos + (vecEnd - vecStart); + + if (m_bTraceTargetReference) + { + // Make sure we can go the whole distance there + UTIL_TraceLine( refPos, vecPos, m_iMask, &traceFilter, &tr ); + vecPos = tr.endpos; + } + + vecOrigin = vecPos; + angAngles = angStart; +} + + + +//----------------------------------------------------------------------------- +// The unused, "forgotten" entity brought back to life. +// Mirrors an entity's movement across a reference. +// It derives from logic_measure_movement now so it could use its features. +// This is unfinished and I'm still figuring out how it works. +// +// m_hMeasureTarget; // Whose position is mirrored (m_hRemoteTarget) +// m_hMeasureReference; // Position where position is mirrored (m_hMirrorRelative) +// m_hTarget; // Target whose origin is mirrored (m_hMovementTarget) +// m_hTargetReference; // From where the target's origin is mirrored (m_hMirrorTarget) +//----------------------------------------------------------------------------- +class CLogicMirrorMovement : public CLogicMeasureMovement +{ + DECLARE_DATADESC(); + DECLARE_CLASS( CLogicMirrorMovement, CLogicMeasureMovement ); + +public: + virtual void DoMeasure(Vector &vecOrigin, QAngle &angAngles); +}; + + +LINK_ENTITY_TO_CLASS( logic_mirror_movement, CLogicMirrorMovement ); + +BEGIN_DATADESC( CLogicMirrorMovement ) +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Does measure. +//----------------------------------------------------------------------------- +void CLogicMirrorMovement::DoMeasure( Vector &vecOrigin, QAngle &angAngles ) +{ + + matrix3x4_t matRefToMeasure, matWorldToMeasure; + switch( m_nMeasureType ) + { + case MEASURE_POSITION: + MatrixInvert( m_hMeasureTarget->EntityToWorldTransform(), matWorldToMeasure ); + break; + + case MEASURE_EYE_POSITION: + AngleIMatrix( m_hMeasureTarget->EyeAngles(), m_hMeasureTarget->EyePosition(), matWorldToMeasure ); + break; + + case MEASURE_ATTACHMENT: + if (CBaseAnimating *pAnimating = m_hMeasureTarget->GetBaseAnimating()) + { + if (m_iAttachment <= 0) + m_iAttachment = m_hMeasureTarget->GetBaseAnimating()->LookupAttachment(STRING(m_strAttachment)); + + if (m_iAttachment == -1) + Warning("WARNING: %s requesting invalid attachment %s on %s!\n", GetDebugName(), STRING(m_strAttachment), m_hMeasureTarget->GetDebugName()); + else + pAnimating->GetAttachment(m_iAttachment, matWorldToMeasure); + } + else + { + Warning("WARNING: %s requesting attachment point on non-animating entity %s!\n", GetDebugName(), m_hMeasureTarget->GetDebugName()); + } + break; + } + + ConcatTransforms( matWorldToMeasure, m_hMeasureReference->EntityToWorldTransform(), matRefToMeasure ); + + // Apply the scale factor + if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) + { + Vector vecTranslation; + MatrixGetColumn( matRefToMeasure, 3, vecTranslation ); + vecTranslation /= m_flScale; + MatrixSetColumn( vecTranslation, 3, matRefToMeasure ); + } + + MatrixScaleBy( -1.0f, matRefToMeasure ); + + QAngle angRot; + Vector vecPos; + MatrixAngles( matRefToMeasure, angRot ); + MatrixPosition( matRefToMeasure, vecPos ); + angRot.z *= -1.0f; + vecPos.z *= -1.0f; + AngleMatrix( angRot, vecPos, matWorldToMeasure ); + + // Now apply the new matrix to the new reference point + matrix3x4_t matMeasureToRef, matNewTargetToWorld; + MatrixInvert( matRefToMeasure, matMeasureToRef ); + + // Handle origin ignorance + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN )) + { + // Get the position from the matrix's column directly and re-assign it + Vector vecPosition; + MatrixGetColumn( matRefToMeasure, 3, vecPosition ); + + HandleIgnoreFlags( vecPosition.Base() ); + + MatrixSetColumn( vecPosition, 3, matRefToMeasure ); + } + + ConcatTransforms( m_hTargetReference->EntityToWorldTransform(), matMeasureToRef, matNewTargetToWorld ); + + MatrixAngles( matNewTargetToWorld, angAngles, vecOrigin ); + + // If our spawnflags are greater than 0 (and don't just contain our default "TELEPORT" flag), we might need to ignore one of our angles. + if (GetSpawnFlags() && GetSpawnFlags() != SF_LOGIC_MEASURE_MOVEMENT_TELEPORT && !HasSpawnFlags(SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN)) + { + HandleIgnoreFlags( angAngles.Base() ); + } + + /* + VMatrix matPortal1ToWorldInv, matPortal2ToWorld; + MatrixInverseGeneral( m_hMeasureReference->EntityToWorldTransform(), matPortal1ToWorldInv ); + switch( m_nMeasureType ) + { + case MEASURE_POSITION: + matPortal2ToWorld = m_hMeasureTarget->EntityToWorldTransform(); + break; + + case MEASURE_EYE_POSITION: + matPortal2ToWorld.SetupMatrixOrgAngles( m_hMeasureTarget->EyePosition(), m_hMeasureTarget->EyeAngles() ); + break; + + case MEASURE_ATTACHMENT: + CBaseAnimating *pAnimating = m_hMeasureTarget->GetBaseAnimating(); + if (pAnimating) + { + if (m_iAttachment <= 0) + m_iAttachment = m_hMeasureTarget->GetBaseAnimating()->LookupAttachment(STRING(m_strAttachment)); + + if (m_iAttachment == -1) + Warning("WARNING: %s requesting invalid attachment %s on %s!\n", GetDebugName(), STRING(m_strAttachment), m_hMeasureTarget->GetDebugName()); + else + { + pAnimating->GetAttachment( m_iAttachment, matPortal2ToWorld.As3x4() ); + } + } + else + { + Warning("WARNING: %s requesting attachment point on non-animating entity %s!\n", GetDebugName(), m_hMeasureTarget->GetDebugName()); + } + break; + } + + // If we have spawn flags, we might be supposed to ignore something + if (GetSpawnFlags() > 0) + { + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN )) + { + // Get the position from the matrix's column directly and re-assign it + Vector vecPosition; + MatrixGetColumn( matPortal2ToWorld, 3, &vecPosition ); + + HandleIgnoreFlags( vecPosition.Base() ); + + MatrixSetColumn( matPortal2ToWorld, 3, vecPosition ); + } + else + { + // Get the angles from the matrix and re-assign it + QAngle angAngles; + MatrixToAngles( matPortal2ToWorld, angAngles ); + + HandleIgnoreFlags( angAngles.Base() ); + + matPortal2ToWorld.SetupMatrixAngles( angAngles ); + } + } + + // Apply the scale factor + if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) + { + Vector vecTranslation; + MatrixGetColumn( matPortal2ToWorld.As3x4(), 3, vecTranslation ); + vecTranslation /= m_flScale; + MatrixSetColumn( vecTranslation, 3, matPortal2ToWorld.As3x4() ); + } + + // Get our scene camera's current orientation + Vector ptCameraPosition, vCameraLook, vCameraRight, vCameraUp; + ptCameraPosition = m_hTargetReference->EyePosition(); + m_hTargetReference->GetVectors( &vCameraLook, &vCameraRight, &vCameraUp ); + + // map this position and orientation to the remote portal, mirrored (invert the result) + Vector ptNewPosition, vNewLook; + ptNewPosition = matPortal1ToWorldInv * ptCameraPosition; + ptNewPosition = matPortal2ToWorld*(Vector( -ptNewPosition.x, -ptNewPosition.y, ptNewPosition.z )); + + vNewLook = matPortal1ToWorldInv.ApplyRotation( vCameraLook ); + vNewLook = matPortal2ToWorld.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z ) ); + + // Set the point camera to the new location/orientation + QAngle qNewAngles; + VectorAngles( vNewLook, qNewAngles ); + + vecOrigin = ptNewPosition; + angAngles = qNewAngles; + */ +} +#endif diff --git a/game/server/logic_playmovie.cpp b/game/server/logic_playmovie.cpp new file mode 100644 index 00000000..4e62f738 --- /dev/null +++ b/game/server/logic_playmovie.cpp @@ -0,0 +1,136 @@ +//===== Copyright 1996-2009, Valve Corporation, All rights reserved. ======// +// +// Purpose: Plays a movie and reports on finish +// +//===========================================================================// + +#include "cbase.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CLogicPlayMovie : public CLogicalEntity +{ +public: + DECLARE_CLASS( CLogicPlayMovie, CLogicalEntity ); + DECLARE_DATADESC(); + + CLogicPlayMovie( void ) { } + ~CLogicPlayMovie( void ) { } + + virtual void Precache( void ); + virtual void Spawn( void ); + +private: + + void InputPlayMovie( inputdata_t &data ); +#ifdef MAPBASE + void InputStopMovie( inputdata_t &data ); +#endif + void InputMovieFinished( inputdata_t &data ); + + string_t m_strMovieFilename; + bool m_bAllowUserSkip; +#ifdef MAPBASE + bool m_bLooping; + bool m_bMuted; + + bool m_bPlayingVideo; +#endif + + COutputEvent m_OnPlaybackFinished; +}; + +LINK_ENTITY_TO_CLASS( logic_playmovie, CLogicPlayMovie ); + +BEGIN_DATADESC( CLogicPlayMovie ) + + DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "MovieFilename" ), + DEFINE_KEYFIELD( m_bAllowUserSkip, FIELD_BOOLEAN, "allowskip" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "loopvideo" ), + DEFINE_KEYFIELD( m_bMuted, FIELD_BOOLEAN, "mute" ), + + DEFINE_FIELD( m_bPlayingVideo, FIELD_BOOLEAN ), +#endif + + DEFINE_INPUTFUNC( FIELD_VOID, "PlayMovie", InputPlayMovie ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "StopMovie", InputStopMovie ), +#endif + DEFINE_INPUTFUNC( FIELD_VOID, "__MovieFinished", InputMovieFinished ), + + DEFINE_OUTPUT( m_OnPlaybackFinished, "OnPlaybackFinished" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicPlayMovie::Precache( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicPlayMovie::Spawn( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicPlayMovie::InputPlayMovie( inputdata_t &data ) +{ + // Build the hacked string + + char szClientCmd[256]; + Q_snprintf( szClientCmd, sizeof(szClientCmd), + "playvideo_complex %s \"ent_fire %s __MovieFinished\" %d %d %d\n", + STRING(m_strMovieFilename), + GetEntityNameAsCStr(), + m_bAllowUserSkip, +#ifdef MAPBASE + m_bLooping, + m_bMuted +#else + 0, + 0 +#endif + ); + + // Send it on + engine->ServerCommand( szClientCmd ); + +#ifdef MAPBASE + m_bPlayingVideo = true; +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicPlayMovie::InputStopMovie( inputdata_t &data ) +{ + if (m_bPlayingVideo) + { + // Send it on + engine->ServerCommand( "stopvideos\n" ); + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicPlayMovie::InputMovieFinished( inputdata_t &data ) +{ + // Simply fire our output + m_OnPlaybackFinished.FireOutput( this, this ); + +#ifdef MAPBASE + m_bPlayingVideo = false; +#endif +} diff --git a/game/server/logic_random_outputs.cpp b/game/server/logic_random_outputs.cpp new file mode 100644 index 00000000..b5c9f64b --- /dev/null +++ b/game/server/logic_random_outputs.cpp @@ -0,0 +1,221 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ==== +// +// When triggered, will attempt to fire off each of its outputs. Each output +// has its own chance of firing. +// +//============================================================================= + +#include "cbase.h" +#include "entityinput.h" +#include "entityoutput.h" +#include "eventqueue.h" +#include "soundent.h" +#include "logic_random_outputs.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +const int SF_REMOVE_ON_FIRE = 0x001; // Relay will remove itself after being triggered. +const int SF_ALLOW_FAST_RETRIGGER = 0x002; // Unless set, entity will disable itself until the last output is sent. + +LINK_ENTITY_TO_CLASS(logic_random_outputs, CLogicRandomOutputs); + + +BEGIN_DATADESC( CLogicRandomOutputs ) + + DEFINE_FIELD(m_bWaitForRefire, FIELD_BOOLEAN), + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"), + + DEFINE_AUTO_ARRAY( m_flOnTriggerChance, FIELD_FLOAT ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), + DEFINE_INPUTFUNC(FIELD_VOID, "EnableRefire", InputEnableRefire), + DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), + DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), + DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger), + DEFINE_INPUTFUNC(FIELD_VOID, "CancelPending", InputCancelPending), + + // Outputs + DEFINE_OUTPUT(m_OnSpawn, "OnSpawn"), + DEFINE_OUTPUT(m_Output[0], "OnTrigger1"), + DEFINE_OUTPUT(m_Output[1], "OnTrigger2"), + DEFINE_OUTPUT(m_Output[2], "OnTrigger3"), + DEFINE_OUTPUT(m_Output[3], "OnTrigger4"), + DEFINE_OUTPUT(m_Output[4], "OnTrigger5"), + DEFINE_OUTPUT(m_Output[5], "OnTrigger6"), + DEFINE_OUTPUT(m_Output[6], "OnTrigger7"), + DEFINE_OUTPUT(m_Output[7], "OnTrigger8"), + +END_DATADESC() + + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CLogicRandomOutputs::CLogicRandomOutputs(void) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Read in the chance of firing each output +//----------------------------------------------------------------------------- +bool CLogicRandomOutputs::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( szValue && szValue[0] ) + { + for ( int i=0; i < NUM_RANDOM_OUTPUTS; i++ ) + { + if ( FStrEq( szKeyName, UTIL_VarArgs( "OnTriggerChance%d", i ) ) ) + { + m_flOnTriggerChance[i] = atof( szValue ); + return true; + } + } + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Give out the chance of firing each output +//----------------------------------------------------------------------------- +bool CLogicRandomOutputs::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + if ( !Q_strnicmp(szKeyName, "OnTriggerChance", 15) ) + { + for ( int i=0; i < NUM_RANDOM_OUTPUTS; i++ ) + { + if ( FStrEq( szKeyName, UTIL_VarArgs( "OnTriggerChance%d", i ) ) ) + { + Q_snprintf( szValue, iMaxLen, "%f", m_flOnTriggerChance[i] ); + return true; + } + } + } + + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); +} +#endif + +//------------------------------------------------------------------------------ +// Kickstarts a think if we have OnSpawn connections. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::Activate() +{ + BaseClass::Activate(); + + if ( m_OnSpawn.NumberOfElements() > 0) + { + SetNextThink( gpGlobals->curtime + 0.01 ); + } +} + + +//----------------------------------------------------------------------------- +// If we have OnSpawn connections, this is called shortly after spawning to +// fire the OnSpawn output. +//----------------------------------------------------------------------------- +void CLogicRandomOutputs::Think() +{ + // Fire an output when we spawn. This is used for self-starting an entity + // template -- since the logic_random_outputs is inside the template, it gets all the + // name and I/O connection fixup, so can target other entities in the template. + m_OnSpawn.FireOutput( this, this ); + + // We only get here if we had OnSpawn connections, so this is safe. + if ( m_spawnflags & SF_REMOVE_ON_FIRE ) + { + UTIL_Remove(this); + } +} + + +//------------------------------------------------------------------------------ +// Purpose: Turns on the entity, allowing it to fire outputs. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} + +//------------------------------------------------------------------------------ +// Purpose: Enables us to fire again. This input is only posted from our Trigger +// function to prevent rapid refire. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::InputEnableRefire( inputdata_t &inputdata ) +{ + Msg(" now enabling refire\n" ); + m_bWaitForRefire = false; +} + + +//------------------------------------------------------------------------------ +// Purpose: Cancels any I/O events in the queue that were fired by us. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::InputCancelPending( inputdata_t &inputdata ) +{ + g_EventQueue.CancelEvents( this ); + + // Stop waiting; allow another Trigger. + m_bWaitForRefire = false; +} + + +//------------------------------------------------------------------------------ +// Purpose: Turns off the entity, preventing it from firing outputs. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + + +//------------------------------------------------------------------------------ +// Purpose: Toggles the enabled/disabled state of the entity. +//------------------------------------------------------------------------------ +void CLogicRandomOutputs::InputToggle( inputdata_t &inputdata ) +{ + m_bDisabled = !m_bDisabled; +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that triggers the logic_random_outputs. +//----------------------------------------------------------------------------- +void CLogicRandomOutputs::InputTrigger( inputdata_t &inputdata ) +{ + if ((!m_bDisabled) && (!m_bWaitForRefire)) + { + for ( int i=0 ; i < NUM_RANDOM_OUTPUTS ; i++ ) + { + if ( RandomFloat() <= m_flOnTriggerChance[i] ) + { + m_Output[i].FireOutput( inputdata.pActivator, this ); + } + } + + if (m_spawnflags & SF_REMOVE_ON_FIRE) + { + UTIL_Remove(this); + } + else if (!(m_spawnflags & SF_ALLOW_FAST_RETRIGGER)) + { + // find the max delay from all our outputs + float fMaxDelay = 0; + for ( int i=0 ; i < NUM_RANDOM_OUTPUTS ; i++ ) + { + fMaxDelay = MAX( fMaxDelay, m_Output[i].GetMaxDelay() ); + } + if ( fMaxDelay > 0 ) + { + // Disable the relay so that it cannot be refired until after the last output + // has been fired and post an input to re-enable ourselves. + m_bWaitForRefire = true; + g_EventQueue.AddEvent(this, "EnableRefire", fMaxDelay + 0.001, this, this); + } + } + } +} diff --git a/game/server/logic_random_outputs.h b/game/server/logic_random_outputs.h new file mode 100644 index 00000000..aeb60bff --- /dev/null +++ b/game/server/logic_random_outputs.h @@ -0,0 +1,54 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef LOGICRANDOMOUTPUTS_H +#define LOGICRANDOMOUTPUTS_H + +#include "cbase.h" +#include "entityinput.h" +#include "entityoutput.h" +#include "eventqueue.h" + +#define NUM_RANDOM_OUTPUTS 8 + +class CLogicRandomOutputs : public CLogicalEntity +{ +public: + DECLARE_CLASS( CLogicRandomOutputs, CLogicalEntity ); + + CLogicRandomOutputs(); + + void Activate(); + void Think(); + virtual bool KeyValue( const char *szKeyName, const char *szValue ); +#ifdef MAPBASE + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); +#endif + + // Input handlers + void InputEnable( inputdata_t &inputdata ); + void InputEnableRefire( inputdata_t &inputdata ); // Private input handler, not in FGD + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + void InputTrigger( inputdata_t &inputdata ); + void InputCancelPending( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + + // Outputs + COutputEvent m_Output[ NUM_RANDOM_OUTPUTS ]; + COutputEvent m_OnSpawn; + + float m_flOnTriggerChance[ NUM_RANDOM_OUTPUTS ]; + +private: + + bool m_bDisabled; + bool m_bWaitForRefire; // Set to disallow a refire while we are waiting for our outputs to finish firing. +}; + +#endif //LOGICRANDOMOUTPUTS_H diff --git a/game/server/logicentities.cpp b/game/server/logicentities.cpp index cc8e6b73..aa838a35 100644 --- a/game/server/logicentities.cpp +++ b/game/server/logicentities.cpp @@ -14,6 +14,12 @@ #include "saverestore_utlvector.h" #include "vstdlib/random.h" #include "gameinterface.h" +#ifdef MAPBASE +#include "mapbase/variant_tools.h" +#include "mapbase/matchers.h" +#include "mapbase/datadesc_mod.h" +#include "activitylist.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -21,6 +27,126 @@ extern CServerGameDLL g_ServerGameDLL; +//----------------------------------------------------------------------------- +// Purpose: An entity that acts as a container for game scripts. +//----------------------------------------------------------------------------- + +#define MAX_SCRIPT_GROUP 16 + +class CLogicScript : public CPointEntity +{ +public: + DECLARE_CLASS( CLogicScript, CPointEntity ); + DECLARE_DATADESC(); + + void RunVScripts() + { + /* + EntityGroup <- []; + function __AppendToScriptGroup( name ) + { + if ( name.len() == 0 ) + { + EntityGroup.append( null ); + } + else + { + local ent = Entities.FindByName( null, name ); + EntityGroup.append( ent ); + if ( ent != null ) + { + ent.ValidateScriptScope(); + ent.GetScriptScope().EntityGroup <- EntityGroup; + } + } + } + */ + + static const char szAddCode[] = + { + 0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x20,0x3c,0x2d,0x20,0x5b,0x5d,0x3b,0x0d,0x0a, + 0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x5f,0x5f,0x41,0x70,0x70,0x65,0x6e,0x64,0x54,0x6f,0x53, + 0x63,0x72,0x69,0x70,0x74,0x47,0x72,0x6f,0x75,0x70,0x28,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x20,0x0d, + 0x0a,0x7b,0x0d,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x6e,0x61,0x6d,0x65,0x2e,0x6c,0x65,0x6e,0x28,0x29, + 0x20,0x3d,0x3d,0x20,0x30,0x20,0x29,0x20,0x0d,0x0a,0x09,0x7b,0x20,0x0d,0x0a,0x09,0x09,0x45,0x6e,0x74, + 0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x20,0x6e,0x75,0x6c, + 0x6c,0x20,0x29,0x3b,0x20,0x0d,0x0a,0x09,0x7d,0x20,0x0d,0x0a,0x09,0x65,0x6c,0x73,0x65,0x0d,0x0a,0x09, + 0x7b,0x20,0x0d,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65,0x6e,0x74,0x20,0x3d,0x20,0x45,0x6e, + 0x74,0x69,0x74,0x69,0x65,0x73,0x2e,0x46,0x69,0x6e,0x64,0x42,0x79,0x4e,0x61,0x6d,0x65,0x28,0x20,0x6e, + 0x75,0x6c,0x6c,0x2c,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x45,0x6e,0x74,0x69, + 0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x20,0x65,0x6e,0x74,0x20, + 0x29,0x3b,0x0d,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x65,0x6e,0x74,0x20,0x21,0x3d,0x20,0x6e,0x75, + 0x6c,0x6c,0x20,0x29,0x0d,0x0a,0x09,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x65,0x6e,0x74,0x2e,0x56,0x61, + 0x6c,0x69,0x64,0x61,0x74,0x65,0x53,0x63,0x72,0x69,0x70,0x74,0x53,0x63,0x6f,0x70,0x65,0x28,0x29,0x3b, + 0x0d,0x0a,0x09,0x09,0x09,0x65,0x6e,0x74,0x2e,0x47,0x65,0x74,0x53,0x63,0x72,0x69,0x70,0x74,0x53,0x63, + 0x6f,0x70,0x65,0x28,0x29,0x2e,0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x20,0x3c,0x2d, + 0x20,0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a, + 0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,0x00 + }; + + int iLastMember; + for ( iLastMember = MAX_SCRIPT_GROUP - 1; iLastMember >= 0; iLastMember-- ) + { + if ( m_iszGroupMembers[iLastMember] != NULL_STRING ) + { + break; + } + } + + if ( iLastMember >= 0 ) + { + HSCRIPT hAddScript = g_pScriptVM->CompileScript( szAddCode ); + if ( hAddScript ) + { + ValidateScriptScope(); + m_ScriptScope.Run( hAddScript ); + HSCRIPT hAddFunc = m_ScriptScope.LookupFunction( "__AppendToScriptGroup" ); + if ( hAddFunc ) + { + for ( int i = 0; i <= iLastMember; i++ ) + { + m_ScriptScope.Call( hAddFunc, NULL, STRING(m_iszGroupMembers[i]) ); + } + g_pScriptVM->ReleaseFunction( hAddFunc ); + m_ScriptScope.ClearValue( "__AppendToScriptGroup" ); + } + + g_pScriptVM->ReleaseScript( hAddScript ); + } + } + BaseClass::RunVScripts(); + } + + string_t m_iszGroupMembers[MAX_SCRIPT_GROUP]; + +}; + +LINK_ENTITY_TO_CLASS( logic_script, CLogicScript ); + +BEGIN_DATADESC( CLogicScript ) + // Silence, Classcheck! + // DEFINE_ARRAY( m_iszGroupMembers, FIELD_STRING, MAX_NUM_TEMPLATES ), + + DEFINE_KEYFIELD( m_iszGroupMembers[0], FIELD_STRING, "Group00"), + DEFINE_KEYFIELD( m_iszGroupMembers[1], FIELD_STRING, "Group01"), + DEFINE_KEYFIELD( m_iszGroupMembers[2], FIELD_STRING, "Group02"), + DEFINE_KEYFIELD( m_iszGroupMembers[3], FIELD_STRING, "Group03"), + DEFINE_KEYFIELD( m_iszGroupMembers[4], FIELD_STRING, "Group04"), + DEFINE_KEYFIELD( m_iszGroupMembers[5], FIELD_STRING, "Group05"), + DEFINE_KEYFIELD( m_iszGroupMembers[6], FIELD_STRING, "Group06"), + DEFINE_KEYFIELD( m_iszGroupMembers[7], FIELD_STRING, "Group07"), + DEFINE_KEYFIELD( m_iszGroupMembers[8], FIELD_STRING, "Group08"), + DEFINE_KEYFIELD( m_iszGroupMembers[9], FIELD_STRING, "Group09"), + DEFINE_KEYFIELD( m_iszGroupMembers[10], FIELD_STRING, "Group10"), + DEFINE_KEYFIELD( m_iszGroupMembers[11], FIELD_STRING, "Group11"), + DEFINE_KEYFIELD( m_iszGroupMembers[12], FIELD_STRING, "Group12"), + DEFINE_KEYFIELD( m_iszGroupMembers[13], FIELD_STRING, "Group13"), + DEFINE_KEYFIELD( m_iszGroupMembers[14], FIELD_STRING, "Group14"), + DEFINE_KEYFIELD( m_iszGroupMembers[15], FIELD_STRING, "Group15"), + +END_DATADESC() + + //----------------------------------------------------------------------------- // Purpose: Compares a set of integer inputs to the one main input @@ -32,12 +158,24 @@ class CLogicCompareInteger : public CLogicalEntity DECLARE_CLASS( CLogicCompareInteger, CLogicalEntity ); // outputs +#ifdef MAPBASE + COutputVariant m_OnEqual; + COutputVariant m_OnNotEqual; +#else COutputEvent m_OnEqual; COutputEvent m_OnNotEqual; +#endif // data +#ifdef MAPBASE + variant_t m_iValue; + bool m_iShouldCompareToValue; + bool m_bStrLenAllowed = true; + int DrawDebugTextOverlays(void); +#else int m_iIntegerValue; int m_iShouldCompareToValue; +#endif DECLARE_DATADESC(); @@ -45,6 +183,10 @@ class CLogicCompareInteger : public CLogicalEntity // Input handlers void InputValue( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputValueNoFire( inputdata_t &inputdata ); + void InputSetIntegerValue( inputdata_t &inputdata ); +#endif void InputCompareValues( inputdata_t &inputdata ); }; @@ -57,12 +199,22 @@ BEGIN_DATADESC( CLogicCompareInteger ) DEFINE_OUTPUT( m_OnEqual, "OnEqual" ), DEFINE_OUTPUT( m_OnNotEqual, "OnNotEqual" ), +#ifdef MAPBASE + DEFINE_KEYVARIANT( m_iValue, "IntegerValue" ), + DEFINE_KEYFIELD( m_iShouldCompareToValue, FIELD_BOOLEAN, "ShouldComparetoValue" ), + DEFINE_KEYFIELD( m_bStrLenAllowed, FIELD_BOOLEAN, "StrLenAllowed" ), +#else DEFINE_KEYFIELD( m_iIntegerValue, FIELD_INTEGER, "IntegerValue" ), DEFINE_KEYFIELD( m_iShouldCompareToValue, FIELD_INTEGER, "ShouldComparetoValue" ), +#endif DEFINE_FIELD( m_AllIntCompares, FIELD_INPUT ), DEFINE_INPUTFUNC( FIELD_INPUT, "InputValue", InputValue ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INPUT, "InputValueNoFire", InputValueNoFire ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetReferenceValue", InputSetIntegerValue ), +#endif DEFINE_INPUTFUNC( FIELD_INPUT, "CompareValues", InputCompareValues ), END_DATADESC() @@ -75,9 +227,14 @@ END_DATADESC() //----------------------------------------------------------------------------- void CLogicCompareInteger::InputValue( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Parse the input value, regardless of field type + inputdata.value = Variant_ParseInput(inputdata); +#else // make sure it's an int, if it can't be converted just throw it away if ( !inputdata.value.Convert(FIELD_INTEGER) ) return; +#endif // update the value list with the new value m_AllIntCompares.AddValue( inputdata.value, inputdata.nOutputID ); @@ -85,12 +242,38 @@ void CLogicCompareInteger::InputValue( inputdata_t &inputdata ) // if we haven't already this frame, send a message to ourself to update and fire if ( !m_AllIntCompares.m_bUpdatedThisFrame ) { +#ifdef MAPBASE + // Need to wait for all inputs to arrive + g_EventQueue.AddEvent( this, "CompareValues", 0.01, inputdata.pActivator, this, inputdata.nOutputID ); +#else // TODO: need to add this event with a lower priority, so it gets called after all inputs have arrived g_EventQueue.AddEvent( this, "CompareValues", 0, inputdata.pActivator, this, inputdata.nOutputID ); +#endif m_AllIntCompares.m_bUpdatedThisFrame = TRUE; } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Adds to the list of compared values without firing +//----------------------------------------------------------------------------- +void CLogicCompareInteger::InputValueNoFire( inputdata_t &inputdata ) +{ + // Parse the input value, regardless of field type + inputdata.value = Variant_ParseInput(inputdata); + + // update the value list with the new value + m_AllIntCompares.AddValue( inputdata.value, inputdata.nOutputID ); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets our reference value +//----------------------------------------------------------------------------- +void CLogicCompareInteger::InputSetIntegerValue( inputdata_t &inputdata ) +{ + m_iValue = Variant_ParseInput(inputdata); +} +#endif //----------------------------------------------------------------------------- // Purpose: Forces a recompare @@ -100,6 +283,30 @@ void CLogicCompareInteger::InputCompareValues( inputdata_t &inputdata ) m_AllIntCompares.m_bUpdatedThisFrame = FALSE; // loop through all the values comparing them +#ifdef MAPBASE + variant_t value = m_iValue; + CMultiInputVar::inputitem_t *input = m_AllIntCompares.m_InputList; + + if ( !m_iShouldCompareToValue && input ) + { + value = input->value; + } + + while ( input ) + { + if ( !Variant_Equal(value, input->value, m_bStrLenAllowed) ) + { + // false + m_OnNotEqual.Set( input->value, inputdata.pActivator, this ); + return; + } + + input = input->next; + } + + // true! all values equal + m_OnEqual.Set( value, inputdata.pActivator, this ); +#else int value = m_iIntegerValue; CMultiInputVar::inputitem_t *input = m_AllIntCompares.m_InputList; @@ -122,7 +329,41 @@ void CLogicCompareInteger::InputCompareValues( inputdata_t &inputdata ) // true! all values equal m_OnEqual.FireOutput( inputdata.pActivator, this ); +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CLogicCompareInteger::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + Q_snprintf(tempstr, sizeof(tempstr), " Reference Value: %s", m_iValue.GetDebug()); + EntityText(text_offset, tempstr, 0); + text_offset++; + + int count = 1; + CMultiInputVar::inputitem_t *input = m_AllIntCompares.m_InputList; + while ( input ) + { + Q_snprintf(tempstr, sizeof(tempstr), " Value %i: %s", count, input->value.GetDebug()); + EntityText(text_offset, tempstr, 0); + text_offset++; + + count++; + input = input->next; + } + } + return text_offset; } +#endif //----------------------------------------------------------------------------- @@ -171,6 +412,9 @@ class CTimerEntity : public CLogicalEntity int m_iUseRandomTime; float m_flLowerRandomBound; float m_flUpperRandomBound; +#ifdef MAPBASE + bool m_bUseBoundsForTimerInputs; +#endif // methods void ResetTimer( void ); @@ -189,6 +433,10 @@ BEGIN_DATADESC( CTimerEntity ) DEFINE_FIELD( m_bUpDownState, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bUseBoundsForTimerInputs, FIELD_BOOLEAN, "UseBoundsForTimerInputs" ), +#endif + // Inputs DEFINE_INPUTFUNC( FIELD_FLOAT, "RefireTime", InputRefireTime ), DEFINE_INPUTFUNC( FIELD_VOID, "FireTimer", InputFireTimer ), @@ -409,7 +657,24 @@ void CTimerEntity::InputAddToTimer( inputdata_t &inputdata ) // Add time to timer float flNextThink = GetNextThink(); +#ifdef MAPBASE + if (m_bUseBoundsForTimerInputs) + { + // Make sure it's not above our min or max bounds + if (flNextThink - gpGlobals->curtime > m_flUpperRandomBound) + return; + + flNextThink += inputdata.value.Float(); + flNextThink = clamp( flNextThink - gpGlobals->curtime, m_flLowerRandomBound, m_flUpperRandomBound ); + SetNextThink( gpGlobals->curtime + flNextThink ); + } + else + { + SetNextThink( flNextThink + inputdata.value.Float() ); + } +#else SetNextThink( flNextThink += inputdata.value.Float() ); +#endif } //----------------------------------------------------------------------------- @@ -424,6 +689,23 @@ void CTimerEntity::InputSubtractFromTimer( inputdata_t &inputdata ) // Subtract time from the timer but don't let the timer go negative float flNextThink = GetNextThink(); +#ifdef MAPBASE + if (m_bUseBoundsForTimerInputs) + { + // Make sure it's not above our min or max bounds + if (flNextThink - gpGlobals->curtime < m_flLowerRandomBound) + return; + + flNextThink -= inputdata.value.Float(); + flNextThink = clamp( flNextThink - gpGlobals->curtime, m_flLowerRandomBound, m_flUpperRandomBound ); + SetNextThink( gpGlobals->curtime + flNextThink ); + } + else + { + flNextThink -= inputdata.value.Float(); + SetNextThink( (flNextThink <= gpGlobals->curtime) ? gpGlobals->curtime : flNextThink ); + } +#else if ( ( flNextThink - gpGlobals->curtime ) <= inputdata.value.Float() ) { SetNextThink( gpGlobals->curtime ); @@ -432,6 +714,7 @@ void CTimerEntity::InputSubtractFromTimer( inputdata_t &inputdata ) { SetNextThink( flNextThink -= inputdata.value.Float() ); } +#endif } //----------------------------------------------------------------------------- @@ -844,6 +1127,39 @@ void CC_Global_Set( const CCommand &args ) static ConCommand global_set( "global_set", CC_Global_Set, "global_set : Sets the state of the given env_global (0 = OFF, 1 = ON, 2 = DEAD).", FCVAR_CHEAT ); +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Console command to set the counter of a global +//----------------------------------------------------------------------------- +void CC_Global_Counter( const CCommand &args ) +{ + const char *szGlobal = args[1]; + const char *szCounter = args[2]; + + if ( szGlobal == NULL || szCounter == NULL ) + { + Msg( "Usage: global_counter : Sets the counter of the given env_global.\n" ); + return; + } + + int nCounter = atoi( szCounter ); + + int nIndex = GlobalEntity_GetIndex( szGlobal ); + + if ( nIndex >= 0 ) + { + GlobalEntity_SetCounter( nIndex, nCounter ); + } + else + { + nIndex = GlobalEntity_Add( szGlobal, STRING( gpGlobals->mapname ), GLOBAL_ON ); + GlobalEntity_SetCounter( nIndex, nCounter ); + } +} + +static ConCommand global_counter( "global_counter", CC_Global_Counter, "global_counter : Sets the counter of the given env_global.", FCVAR_CHEAT ); +#endif + //----------------------------------------------------------------------------- // Purpose: Holds a global state that can be queried by other entities to change @@ -858,6 +1174,10 @@ class CEnvGlobal : public CLogicalEntity void Spawn( void ); +#ifdef MAPBASE + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + // Input handlers void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); @@ -897,7 +1217,11 @@ BEGIN_DATADESC( CEnvGlobal ) DEFINE_INPUTFUNC( FIELD_INTEGER, "AddToCounter", InputAddToCounter ), DEFINE_INPUTFUNC( FIELD_VOID, "GetCounter", InputGetCounter ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_outCounter, "OutCounter" ), +#else DEFINE_OUTPUT( m_outCounter, "Counter" ), +#endif END_DATADESC() @@ -938,6 +1262,24 @@ void CEnvGlobal::Spawn( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CEnvGlobal::KeyValue( const char *szKeyName, const char *szValue ) +{ + // Any "Counter" outputs are changed to "OutCounter" before spawning. + if (FStrEq(szKeyName, "Counter") && strchr(szValue, ',')) + { + return BaseClass::KeyValue( "OutCounter", szValue ); + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} +#endif //------------------------------------------------------------------------------ // Purpose: @@ -1297,7 +1639,11 @@ void CMultiSource::Register(void) class CMathCounter : public CLogicalEntity { DECLARE_CLASS( CMathCounter, CLogicalEntity ); +#ifdef MAPBASE +protected: +#else private: +#endif float m_flMin; // Minimum clamp value. If min and max are BOTH zero, no clamping is done. float m_flMax; // Maximum clamp value. bool m_bHitMin; // Set when we reach or go below our minimum value, cleared if we go above it again. @@ -1310,6 +1656,9 @@ class CMathCounter : public CLogicalEntity int DrawDebugTextOverlays(void); +#ifdef MAPBASE + virtual +#endif void UpdateOutValue(CBaseEntity *pActivator, float fNewValue); // Inputs @@ -1324,12 +1673,20 @@ class CMathCounter : public CLogicalEntity void InputGetValue( inputdata_t &inputdata ); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetMinValueNoFire( inputdata_t &inputdata ); + void InputSetMaxValueNoFire( inputdata_t &inputdata ); +#endif // Outputs COutputFloat m_OutValue; COutputFloat m_OnGetValue; // Used for polling the counter value. COutputEvent m_OnHitMin; COutputEvent m_OnHitMax; +#ifdef MAPBASE + COutputEvent m_OnChangedFromMin; + COutputEvent m_OnChangedFromMax; +#endif DECLARE_DATADESC(); }; @@ -1360,12 +1717,20 @@ BEGIN_DATADESC( CMathCounter ) DEFINE_INPUTFUNC(FIELD_VOID, "GetValue", InputGetValue), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxValueNoFire", InputSetMaxValueNoFire ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMinValueNoFire", InputSetMinValueNoFire ), +#endif // Outputs DEFINE_OUTPUT(m_OutValue, "OutValue"), DEFINE_OUTPUT(m_OnHitMin, "OnHitMin"), DEFINE_OUTPUT(m_OnHitMax, "OnHitMax"), DEFINE_OUTPUT(m_OnGetValue, "OnGetValue"), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnChangedFromMin, "OnChangedFromMin" ), + DEFINE_OUTPUT( m_OnChangedFromMax, "OnChangedFromMax" ), +#endif END_DATADESC() @@ -1382,7 +1747,11 @@ bool CMathCounter::KeyValue(const char *szKeyName, const char *szValue) // if (!stricmp(szKeyName, "startvalue")) { +#ifdef MAPBASE + m_OutValue.Init(atof(szValue)); +#else m_OutValue.Init(atoi(szValue)); +#endif return(true); } @@ -1478,6 +1847,29 @@ void CMathCounter::InputSetHitMin( inputdata_t &inputdata ) UpdateOutValue( inputdata.pActivator, m_OutValue.Get() ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Change min/max +//----------------------------------------------------------------------------- +void CMathCounter::InputSetMaxValueNoFire( inputdata_t &inputdata ) +{ + m_flMax = inputdata.value.Float(); + if ( m_flMax < m_flMin ) + { + m_flMin = m_flMax; + } +} + +void CMathCounter::InputSetMinValueNoFire( inputdata_t &inputdata ) +{ + m_flMin = inputdata.value.Float(); + if ( m_flMax < m_flMin ) + { + m_flMax = m_flMin; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Input handler for adding to the accumulator value. @@ -1636,6 +2028,14 @@ void CMathCounter::UpdateOutValue(CBaseEntity *pActivator, float fNewValue) } else { +#ifdef MAPBASE + // Fire an output if we just changed from the maximum value + if ( m_OutValue.Get() == m_flMax ) + { + m_OnChangedFromMax.FireOutput( pActivator, this ); + } +#endif + m_bHitMax = false; } @@ -1652,6 +2052,13 @@ void CMathCounter::UpdateOutValue(CBaseEntity *pActivator, float fNewValue) } else { +#ifdef MAPBASE + // Fire an output if we just changed from the maximum value + if ( m_OutValue.Get() == m_flMin ) + { + m_OnChangedFromMin.FireOutput( pActivator, this ); + } +#endif m_bHitMin = false; } @@ -1662,1087 +2069,5110 @@ void CMathCounter::UpdateOutValue(CBaseEntity *pActivator, float fNewValue) } - +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: Compares a single string input to up to 16 case values, firing an -// output corresponding to the case value that matched, or a default -// output if the input value didn't match any of the case values. -// -// This can also be used to fire a random output from a set of outputs. +// Purpose: Advanced math_counter with advanced calculation capabilities. //----------------------------------------------------------------------------- -#define MAX_LOGIC_CASES 16 - -class CLogicCase : public CLogicalEntity +class CMathCounterAdvanced : public CMathCounter { - DECLARE_CLASS( CLogicCase, CLogicalEntity ); + DECLARE_CLASS( CMathCounterAdvanced, CMathCounter ); private: - string_t m_nCase[MAX_LOGIC_CASES]; - int m_nShuffleCases; - int m_nLastShuffleCase; - unsigned char m_uchShuffleCaseMap[MAX_LOGIC_CASES]; + bool m_bPreserveValue; + bool m_bAlwaysOutputAsInt; + float m_flLerpPercent; - void Spawn(void); + void UpdateOutValue(CBaseEntity *pActivator, float fNewValue); - int BuildCaseMap(unsigned char *puchMap); + void InputSetValueToPi( inputdata_t &inputdata ); - // Inputs - void InputValue( inputdata_t &inputdata ); - void InputPickRandom( inputdata_t &inputdata ); - void InputPickRandomShuffle( inputdata_t &inputdata ); + void InputPower( inputdata_t &inputdata ); + void InputSquareRoot( inputdata_t &inputdata ); - // Outputs - COutputEvent m_OnCase[MAX_LOGIC_CASES]; // Fired when the input value matches one of the case values. - COutputVariant m_OnDefault; // Fired when no match was found. + void InputRound( inputdata_t &inputdata ); + void InputFloor( inputdata_t &inputdata ); + void InputCeiling( inputdata_t &inputdata ); + void InputTrunc( inputdata_t &inputdata ); + + void InputSine( inputdata_t &inputdata ); + void InputCosine( inputdata_t &inputdata ); + void InputTangent( inputdata_t &inputdata ); + + void InputRandomInt( inputdata_t &inputdata ); + void InputRandomFloat( inputdata_t &inputdata ); + + void InputLerpTo( inputdata_t &inputdata ); DECLARE_DATADESC(); }; -LINK_ENTITY_TO_CLASS(logic_case, CLogicCase); - +LINK_ENTITY_TO_CLASS(math_counter_advanced, CMathCounterAdvanced); -BEGIN_DATADESC( CLogicCase ) -// Silence, Classcheck! -// DEFINE_ARRAY( m_nCase, FIELD_STRING, MAX_LOGIC_CASES ), +BEGIN_DATADESC( CMathCounterAdvanced ) // Keys - DEFINE_KEYFIELD(m_nCase[0], FIELD_STRING, "Case01"), - DEFINE_KEYFIELD(m_nCase[1], FIELD_STRING, "Case02"), - DEFINE_KEYFIELD(m_nCase[2], FIELD_STRING, "Case03"), - DEFINE_KEYFIELD(m_nCase[3], FIELD_STRING, "Case04"), - DEFINE_KEYFIELD(m_nCase[4], FIELD_STRING, "Case05"), - DEFINE_KEYFIELD(m_nCase[5], FIELD_STRING, "Case06"), - DEFINE_KEYFIELD(m_nCase[6], FIELD_STRING, "Case07"), - DEFINE_KEYFIELD(m_nCase[7], FIELD_STRING, "Case08"), - DEFINE_KEYFIELD(m_nCase[8], FIELD_STRING, "Case09"), - DEFINE_KEYFIELD(m_nCase[9], FIELD_STRING, "Case10"), - DEFINE_KEYFIELD(m_nCase[10], FIELD_STRING, "Case11"), - DEFINE_KEYFIELD(m_nCase[11], FIELD_STRING, "Case12"), - DEFINE_KEYFIELD(m_nCase[12], FIELD_STRING, "Case13"), - DEFINE_KEYFIELD(m_nCase[13], FIELD_STRING, "Case14"), - DEFINE_KEYFIELD(m_nCase[14], FIELD_STRING, "Case15"), - DEFINE_KEYFIELD(m_nCase[15], FIELD_STRING, "Case16"), - - DEFINE_FIELD( m_nShuffleCases, FIELD_INTEGER ), - DEFINE_FIELD( m_nLastShuffleCase, FIELD_INTEGER ), - DEFINE_ARRAY( m_uchShuffleCaseMap, FIELD_CHARACTER, MAX_LOGIC_CASES ), + DEFINE_INPUT(m_bPreserveValue, FIELD_BOOLEAN, "PreserveValue"), + DEFINE_INPUT(m_bAlwaysOutputAsInt, FIELD_BOOLEAN, "AlwaysOutputAsInt"), + DEFINE_INPUT(m_flLerpPercent, FIELD_FLOAT, "SetLerpPercent"), // Inputs - DEFINE_INPUTFUNC(FIELD_INPUT, "InValue", InputValue), - DEFINE_INPUTFUNC(FIELD_VOID, "PickRandom", InputPickRandom), - DEFINE_INPUTFUNC(FIELD_VOID, "PickRandomShuffle", InputPickRandomShuffle), + DEFINE_INPUTFUNC(FIELD_VOID, "SetValueToPi", InputSetValueToPi), - // Outputs - DEFINE_OUTPUT(m_OnCase[0], "OnCase01"), - DEFINE_OUTPUT(m_OnCase[1], "OnCase02"), - DEFINE_OUTPUT(m_OnCase[2], "OnCase03"), - DEFINE_OUTPUT(m_OnCase[3], "OnCase04"), - DEFINE_OUTPUT(m_OnCase[4], "OnCase05"), - DEFINE_OUTPUT(m_OnCase[5], "OnCase06"), - DEFINE_OUTPUT(m_OnCase[6], "OnCase07"), - DEFINE_OUTPUT(m_OnCase[7], "OnCase08"), - DEFINE_OUTPUT(m_OnCase[8], "OnCase09"), - DEFINE_OUTPUT(m_OnCase[9], "OnCase10"), - DEFINE_OUTPUT(m_OnCase[10], "OnCase11"), - DEFINE_OUTPUT(m_OnCase[11], "OnCase12"), - DEFINE_OUTPUT(m_OnCase[12], "OnCase13"), - DEFINE_OUTPUT(m_OnCase[13], "OnCase14"), - DEFINE_OUTPUT(m_OnCase[14], "OnCase15"), - DEFINE_OUTPUT(m_OnCase[15], "OnCase16"), + DEFINE_INPUTFUNC(FIELD_VOID, "SquareRoot", InputSquareRoot), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Power", InputPower), - DEFINE_OUTPUT(m_OnDefault, "OnDefault"), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Round", InputRound), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Floor", InputFloor), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Ceil", InputCeiling), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Trunc", InputTrunc), -END_DATADESC() + DEFINE_INPUTFUNC(FIELD_VOID, "Sin", InputSine), + DEFINE_INPUTFUNC(FIELD_VOID, "Cos", InputCosine), + DEFINE_INPUTFUNC(FIELD_VOID, "Tan", InputTangent), + DEFINE_INPUTFUNC(FIELD_STRING, "RandomInt", InputRandomInt), + DEFINE_INPUTFUNC(FIELD_STRING, "RandomFloat", InputRandomFloat), + DEFINE_INPUTFUNC(FIELD_FLOAT, "LerpTo", InputLerpTo), +END_DATADESC() //----------------------------------------------------------------------------- -// Purpose: Called before spawning, after key values have been set. +// Purpose: Input handler for setting the current value to pi. //----------------------------------------------------------------------------- -void CLogicCase::Spawn( void ) +void CMathCounterAdvanced::InputSetValueToPi( inputdata_t &inputdata ) { - m_nLastShuffleCase = -1; -} + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring SET TO PI because it is disabled\n", GetDebugName() ); + return; + } + float fNewValue = M_PI; + UpdateOutValue( inputdata.pActivator, fNewValue ); +} //----------------------------------------------------------------------------- -// Purpose: Evaluates the new input value, firing the appropriate OnCaseX output -// if the input value matches one of the "CaseX" keys. -// Input : Value - Variant value to compare against the values of the case fields. -// We use a variant so that we can convert any input type to a string. +// Purpose: Input handler for calculating the square root of the current value. //----------------------------------------------------------------------------- -void CLogicCase::InputValue( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputSquareRoot( inputdata_t &inputdata ) { - const char *pszValue = inputdata.value.String(); - for (int i = 0; i < MAX_LOGIC_CASES; i++) + if( m_bDisabled ) { - if ((m_nCase[i] != NULL_STRING) && !stricmp(STRING(m_nCase[i]), pszValue)) - { - m_OnCase[i].FireOutput( inputdata.pActivator, this ); - return; - } + DevMsg("Math Counter %s ignoring SQUARE ROOT because it is disabled\n", GetDebugName() ); + return; } - - m_OnDefault.Set( inputdata.value, inputdata.pActivator, this ); -} + float fNewValue = sqrt(m_OutValue.Get()); + UpdateOutValue( inputdata.pActivator, fNewValue ); +} //----------------------------------------------------------------------------- -// Count the number of valid cases, building a packed array -// that maps 0..NumCases to the actual CaseX values. -// -// This allows our zany mappers to set up cases sparsely if they desire. -// NOTE: assumes pnMap points to an array of MAX_LOGIC_CASES +// Purpose: Input handler for exponentiation of the current value. Use 2 to square it. +// Input : Integer value to raise the current value's power. //----------------------------------------------------------------------------- -int CLogicCase::BuildCaseMap(unsigned char *puchCaseMap) +void CMathCounterAdvanced::InputPower( inputdata_t &inputdata ) { - memset(puchCaseMap, 0, sizeof(unsigned char) * MAX_LOGIC_CASES); - - int nNumCases = 0; - for (int i = 0; i < MAX_LOGIC_CASES; i++) + if( m_bDisabled ) { - if (m_OnCase[i].NumberOfElements() > 0) - { - puchCaseMap[nNumCases] = (unsigned char)i; - nNumCases++; - } + DevMsg("Math Counter %s ignoring POWER!!! because it is disabled\n", GetDebugName() ); + return; } - - return nNumCases; + + float fNewValue = pow(m_OutValue.Get(), inputdata.value.Int()); + UpdateOutValue( inputdata.pActivator, fNewValue ); +} + +// +// For some reason, I had trouble finding the original math functions at first. +// Then I just randomly stumbled upon them, bright as day. +// Oh well. These might be faster anyway. +// +FORCEINLINE int RoundToNumber(int input, int number) +{ + (input < 0 && number > 0) ? number *= -1 : 0; + int result = (input + (number / 2)); + result -= (result % number); + return result; +} + +// Warning: Negative numbers should be ceiled +FORCEINLINE int FloorToNumber(int input, int number) +{ + return (input - (input % number)); } +FORCEINLINE int CeilToNumber(int input, int number) +{ + (input < 0 && number > 0) ? number *= -1 : 0; + int result = (input - (input % number)); + return result != input ? result + number : result; +} + +FORCEINLINE int TruncToNumber(int input, int number) +{ + //(input < 0 && number > 0) ? number *= -1 : 0; + return (input - (input % number)); +} //----------------------------------------------------------------------------- -// Purpose: Makes the case statement choose a case at random. +// Purpose: Input handler for rounding an integer to the specified number. (e.g. 126 rounding to 10 = 130, 1523 rounding to 5 = 1525) +// Input : Integer value to round the current value to. //----------------------------------------------------------------------------- -void CLogicCase::InputPickRandom( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputRound( inputdata_t &inputdata ) { - unsigned char uchCaseMap[MAX_LOGIC_CASES]; - int nNumCases = BuildCaseMap( uchCaseMap ); - - // - // Choose a random case from the ones that were set up by the level designer. - // - if ( nNumCases > 0 ) + if( m_bDisabled ) { - int nRandom = random->RandomInt(0, nNumCases - 1); - int nCase = (unsigned char)uchCaseMap[nRandom]; - - Assert(nCase < MAX_LOGIC_CASES); + DevMsg("Math Counter %s ignoring ROUND because it is disabled\n", GetDebugName() ); + return; + } - if (nCase < MAX_LOGIC_CASES) - { - m_OnCase[nCase].FireOutput( inputdata.pActivator, this ); - } + int iMultiple = inputdata.value.Int(); + int iNewValue; + if (iMultiple != 0) + { + // Round to the nearest input number. + iNewValue = RoundToNumber(m_OutValue.Get(), iMultiple); } else { - DevMsg( 1, "Firing PickRandom input on logic_case %s with no cases set up\n", GetDebugName() ); + // 0 just rounds floats. + iNewValue = static_cast(m_OutValue.Get() + 0.5f); } -} + UpdateOutValue( inputdata.pActivator, iNewValue ); +} //----------------------------------------------------------------------------- -// Purpose: Makes the case statement choose a case at random. +// Purpose: Input handler for flooring an integer to the specified number. (e.g. 126 flooring to 10 = 120, 1528 flooring to 5 = 1525) +// Input : Integer value to floor the current value to. //----------------------------------------------------------------------------- -void CLogicCase::InputPickRandomShuffle( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputFloor( inputdata_t &inputdata ) { - int nAvoidCase = -1; - int nCaseCount = m_nShuffleCases; - - if ( nCaseCount == 0 ) + if( m_bDisabled ) { - // Starting a new shuffle batch. - nCaseCount = m_nShuffleCases = BuildCaseMap( m_uchShuffleCaseMap ); - - if ( ( m_nShuffleCases > 1 ) && ( m_nLastShuffleCase != -1 ) ) - { - // Remove the previously picked case from the case map for this pick only. - // This avoids repeats across shuffle batch boundaries. - nAvoidCase = m_nLastShuffleCase; - - for (int i = 0; i < m_nShuffleCases; i++ ) - { - if ( m_uchShuffleCaseMap[i] == nAvoidCase ) - { - unsigned char uchSwap = m_uchShuffleCaseMap[i]; - m_uchShuffleCaseMap[i] = m_uchShuffleCaseMap[nCaseCount - 1]; - m_uchShuffleCaseMap[nCaseCount - 1] = uchSwap; - nCaseCount--; - break; - } - } - } + DevMsg("Math Counter %s ignoring FLOOR because it is disabled\n", GetDebugName() ); + return; } - - // - // Choose a random case from the ones that were set up by the level designer. - // Never repeat a case within a shuffle batch, nor consecutively across batches. - // - if ( nCaseCount > 0 ) - { - int nRandom = random->RandomInt( 0, nCaseCount - 1 ); - - int nCase = m_uchShuffleCaseMap[nRandom]; - Assert(nCase < MAX_LOGIC_CASES); - if (nCase < MAX_LOGIC_CASES) + int iMultiple = inputdata.value.Int(); + int iNewValue; + if (iMultiple != 0) + { + iNewValue = m_OutValue.Get(); + if (iNewValue >= 0) { - m_OnCase[nCase].FireOutput( inputdata.pActivator, this ); + // Floor to the nearest input number. + iNewValue = FloorToNumber(m_OutValue.Get(), iMultiple); + } + else + { + // We have to do it differently for negatives. + iNewValue = CeilToNumber(m_OutValue.Get(), iMultiple); } - - m_uchShuffleCaseMap[nRandom] = m_uchShuffleCaseMap[m_nShuffleCases - 1]; - m_nShuffleCases--; - - m_nLastShuffleCase = nCase; } else { - DevMsg( 1, "Firing PickRandom input on logic_case %s with no cases set up\n", GetDebugName() ); + // 0 just floors floats. + iNewValue = static_cast(m_OutValue.Get()); } -} + UpdateOutValue( inputdata.pActivator, iNewValue ); +} //----------------------------------------------------------------------------- -// Purpose: Compares a floating point input to a predefined value, firing an -// output to indicate the result of the comparison. +// Purpose: Input handler for ceiling an integer to the specified number. (e.g. 126 ceiling to 10 = 130, 1523 ceiling to 50 = 1550) +// Input : Integer value to ceil the current value to. //----------------------------------------------------------------------------- -class CLogicCompare : public CLogicalEntity +void CMathCounterAdvanced::InputCeiling( inputdata_t &inputdata ) { - DECLARE_CLASS( CLogicCompare, CLogicalEntity ); - -public: - int DrawDebugTextOverlays(void); - -private: - // Inputs - void InputSetValue( inputdata_t &inputdata ); - void InputSetValueCompare( inputdata_t &inputdata ); - void InputSetCompareValue( inputdata_t &inputdata ); - void InputCompare( inputdata_t &inputdata ); - - void DoCompare(CBaseEntity *pActivator, float flInValue); - - float m_flInValue; // Place to hold the last input value for a recomparison. - float m_flCompareValue; // The value to compare the input value against. - - // Outputs - COutputFloat m_OnLessThan; // Fired when the input value is less than the compare value. - COutputFloat m_OnEqualTo; // Fired when the input value is equal to the compare value. - COutputFloat m_OnNotEqualTo; // Fired when the input value is not equal to the compare value. - COutputFloat m_OnGreaterThan; // Fired when the input value is greater than the compare value. - - DECLARE_DATADESC(); -}; - -LINK_ENTITY_TO_CLASS(logic_compare, CLogicCompare); - - -BEGIN_DATADESC( CLogicCompare ) - - // Keys - DEFINE_KEYFIELD(m_flCompareValue, FIELD_FLOAT, "CompareValue"), - DEFINE_KEYFIELD(m_flInValue, FIELD_FLOAT, "InitialValue"), - - // Inputs - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetValue", InputSetValue), - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetValueCompare", InputSetValueCompare), - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetCompareValue", InputSetCompareValue), - DEFINE_INPUTFUNC(FIELD_VOID, "Compare", InputCompare), - - // Outputs - DEFINE_OUTPUT(m_OnEqualTo, "OnEqualTo"), - DEFINE_OUTPUT(m_OnNotEqualTo, "OnNotEqualTo"), - DEFINE_OUTPUT(m_OnGreaterThan, "OnGreaterThan"), - DEFINE_OUTPUT(m_OnLessThan, "OnLessThan"), - -END_DATADESC() - + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring CEIL because it is disabled\n", GetDebugName() ); + return; + } + int iMultiple = inputdata.value.Int(); + int iNewValue; + if (iMultiple != 0) + { + // Ceil to the nearest input number. + iNewValue = CeilToNumber(m_OutValue.Get(), iMultiple); + } + else + { + // 0 just ceils floats. + iNewValue = static_cast(m_OutValue.Get()) + (m_OutValue.Get() != 0 ? 1 : 0); + } + UpdateOutValue( inputdata.pActivator, iNewValue ); +} //----------------------------------------------------------------------------- -// Purpose: Input handler for a new input value without performing a comparison. +// Purpose: Input handler for truncating an integer to the specified number. (e.g. 126 rounding to 10 = 120, -1523 rounding to 5 = 1520) +// Input : Integer value to truncate the current value to. //----------------------------------------------------------------------------- -void CLogicCompare::InputSetValue( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputTrunc( inputdata_t &inputdata ) { - m_flInValue = inputdata.value.Float(); + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring TRUNC because it is disabled\n", GetDebugName() ); + return; + } + + int iMultiple = inputdata.value.Int(); + int iNewValue; + if (iMultiple != 0) + { + // Floor always truncates negative numbers if we don't tell it not to + iNewValue = FloorToNumber(m_OutValue.Get(), iMultiple); + } + else + { + // 0 just ceils floats. + iNewValue = static_cast(m_OutValue.Get()); + if (iNewValue < 0) + iNewValue += 1; + } + + UpdateOutValue( inputdata.pActivator, iNewValue ); } //----------------------------------------------------------------------------- -// Purpose: Input handler for a setting a new value and doing the comparison. +// Purpose: Input handler for applying sine to the current value. //----------------------------------------------------------------------------- -void CLogicCompare::InputSetValueCompare( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputSine( inputdata_t &inputdata ) { - m_flInValue = inputdata.value.Float(); - DoCompare( inputdata.pActivator, m_flInValue ); + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring SINE because it is disabled\n", GetDebugName() ); + return; + } + + float fNewValue = sin(m_OutValue.Get()); + UpdateOutValue( inputdata.pActivator, fNewValue ); } //----------------------------------------------------------------------------- -// Purpose: Input handler for a new input value without performing a comparison. +// Purpose: Input handler for applying cosine to the current value. //----------------------------------------------------------------------------- -void CLogicCompare::InputSetCompareValue( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputCosine( inputdata_t &inputdata ) { - m_flCompareValue = inputdata.value.Float(); + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring SINE because it is disabled\n", GetDebugName() ); + return; + } + + float fNewValue = cos(m_OutValue.Get()); + UpdateOutValue( inputdata.pActivator, fNewValue ); } //----------------------------------------------------------------------------- -// Purpose: Input handler for forcing a recompare of the last input value. +// Purpose: Input handler for applying tangent to the current value. //----------------------------------------------------------------------------- -void CLogicCompare::InputCompare( inputdata_t &inputdata ) +void CMathCounterAdvanced::InputTangent( inputdata_t &inputdata ) { - DoCompare( inputdata.pActivator, m_flInValue ); -} + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring SINE because it is disabled\n", GetDebugName() ); + return; + } + float fNewValue = tan(m_OutValue.Get()); + UpdateOutValue( inputdata.pActivator, fNewValue ); +} //----------------------------------------------------------------------------- -// Purpose: Compares the input value to the compare value, firing the appropriate -// output(s) based on the comparison result. -// Input : flInValue - Value to compare against the comparison value. +// Purpose: Input handler for random int generation. //----------------------------------------------------------------------------- -void CLogicCompare::DoCompare(CBaseEntity *pActivator, float flInValue) +void CMathCounterAdvanced::InputRandomInt( inputdata_t &inputdata ) { - if (flInValue == m_flCompareValue) + if( m_bDisabled ) { - m_OnEqualTo.Set(flInValue, pActivator, this); + DevMsg("Math Counter %s ignoring RANDOMINT because it is disabled\n", GetDebugName() ); + return; + } + + int i1 = 0; + int i2 = 0; + + char szInput[128]; + Q_strncpy( szInput, inputdata.value.String(), sizeof(szInput) ); + char *sSpace = strchr( szInput, ' ' ); + if ( sSpace ) + { + i1 = atoi(szInput); + i2 = atoi(sSpace+1); } else { - m_OnNotEqualTo.Set(flInValue, pActivator, this); - - if (flInValue > m_flCompareValue) - { - m_OnGreaterThan.Set(flInValue, pActivator, this); - } - else - { - m_OnLessThan.Set(flInValue, pActivator, this); - } + // No space, assume anything from 0 to X + i2 = atoi(szInput); } + + float fNewValue = RandomInt(i1, i2); + UpdateOutValue( inputdata.pActivator, fNewValue ); } //----------------------------------------------------------------------------- -// Purpose: Draw any debug text overlays -// Output : Current text offset from the top +// Purpose: Input handler for random float generation. //----------------------------------------------------------------------------- -int CLogicCompare::DrawDebugTextOverlays( void ) +void CMathCounterAdvanced::InputRandomFloat( inputdata_t &inputdata ) { - int text_offset = BaseClass::DrawDebugTextOverlays(); + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring RANDOMFLOAT because it is disabled\n", GetDebugName() ); + return; + } - if (m_debugOverlays & OVERLAY_TEXT_BIT) + float f1 = 0; + float f2 = 0; + + char szInput[128]; + Q_strncpy( szInput, inputdata.value.String(), sizeof(szInput) ); + char *sSpace = strchr( szInput, ' ' ); + if ( sSpace ) { - char tempstr[512]; + f1 = atof(szInput); + f2 = atof(sSpace+1); + } + else + { + // No space, assume anything from 0 to X + f2 = atof(szInput); + } - // print duration - Q_snprintf(tempstr,sizeof(tempstr)," Initial Value: %f", m_flInValue); - EntityText(text_offset,tempstr,0); - text_offset++; + float fNewValue = RandomFloat(f1, f2); + UpdateOutValue( inputdata.pActivator, fNewValue ); +} - // print hold time - Q_snprintf(tempstr,sizeof(tempstr)," Compare Value: %f", m_flCompareValue); - EntityText(text_offset,tempstr,0); - text_offset++; +//----------------------------------------------------------------------------- +// Purpose: Input handler for random float generation. +//----------------------------------------------------------------------------- +void CMathCounterAdvanced::InputLerpTo( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Counter %s ignoring LERPTO because it is disabled\n", GetDebugName() ); + return; } - return text_offset; + + float fNewValue = m_OutValue.Get() + (inputdata.value.Float() - m_OutValue.Get()) * m_flLerpPercent; + UpdateOutValue( inputdata.pActivator, fNewValue ); } //----------------------------------------------------------------------------- -// Purpose: Tests a boolean value, firing an output to indicate whether the -// value was true or false. +// Purpose: Sets the value to the new value, clamping and firing the output value. +// Input : fNewValue - Value to set. //----------------------------------------------------------------------------- -class CLogicBranch : public CLogicalEntity +void CMathCounterAdvanced::UpdateOutValue(CBaseEntity *pActivator, float fNewValue) { - DECLARE_CLASS( CLogicBranch, CLogicalEntity ); - -public: + if (m_bAlwaysOutputAsInt) + fNewValue = roundf(fNewValue); - void UpdateOnRemove(); + if (m_bPreserveValue) + { + //float fOriginal = m_OutValue.Get(); + //DevMsg("Preserve Before: %f\n", fOriginal); + //BaseClass::UpdateOutValue(pActivator, fNewValue); + //DevMsg("Preserve After: %f\n", fOriginal); + //m_OutValue.Init(fOriginal); + + variant_t var; + var.SetFloat(fNewValue); + m_OutValue.FireOutput( var, pActivator, this ); + } + else + { + BaseClass::UpdateOutValue(pActivator, fNewValue); + } +} +#endif - void AddLogicBranchListener( CBaseEntity *pEntity ); - inline bool GetLogicBranchState(); - virtual int DrawDebugTextOverlays( void ); + +//----------------------------------------------------------------------------- +// Purpose: Compares a single string input to up to 16 case values, firing an +// output corresponding to the case value that matched, or a default +// output if the input value didn't match any of the case values. +// +// This can also be used to fire a random output from a set of outputs. +//----------------------------------------------------------------------------- +#define MAX_LOGIC_CASES 16 + +class CLogicCase : public CLogicalEntity +{ + DECLARE_CLASS( CLogicCase, CLogicalEntity ); private: + string_t m_nCase[MAX_LOGIC_CASES]; - enum LogicBranchFire_t - { - LOGIC_BRANCH_FIRE, - LOGIC_BRANCH_NO_FIRE, - }; +#ifdef MAPBASE + bool m_bMultipleCasesAllowed; +#endif - // Inputs - void InputSetValue( inputdata_t &inputdata ); - void InputSetValueTest( inputdata_t &inputdata ); - void InputToggle( inputdata_t &inputdata ); - void InputToggleTest( inputdata_t &inputdata ); - void InputTest( inputdata_t &inputdata ); + int m_nShuffleCases; + int m_nLastShuffleCase; + unsigned char m_uchShuffleCaseMap[MAX_LOGIC_CASES]; - void UpdateValue(bool bNewValue, CBaseEntity *pActivator, LogicBranchFire_t eFire); + void Spawn(void); - bool m_bInValue; // Place to hold the last input value for a future test. - - CUtlVector m_Listeners; // A list of logic_branch_listeners that are monitoring us. + int BuildCaseMap(unsigned char *puchMap); + + // Inputs + void InputValue( inputdata_t &inputdata ); + void InputPickRandom( inputdata_t &inputdata ); + void InputPickRandomShuffle( inputdata_t &inputdata ); // Outputs - COutputEvent m_OnTrue; // Fired when the value is true. - COutputEvent m_OnFalse; // Fired when the value is false. + COutputEvent m_OnCase[MAX_LOGIC_CASES]; // Fired when the input value matches one of the case values. + COutputVariant m_OnDefault; // Fired when no match was found. +#ifdef MAPBASE + COutputVariant m_OnUsed; // Fired when this entity receives any input at all. +#endif DECLARE_DATADESC(); }; -LINK_ENTITY_TO_CLASS(logic_branch, CLogicBranch); +LINK_ENTITY_TO_CLASS(logic_case, CLogicCase); -BEGIN_DATADESC( CLogicBranch ) +BEGIN_DATADESC( CLogicCase ) + +// Silence, Classcheck! +// DEFINE_ARRAY( m_nCase, FIELD_STRING, MAX_LOGIC_CASES ), // Keys - DEFINE_KEYFIELD(m_bInValue, FIELD_BOOLEAN, "InitialValue"), + DEFINE_KEYFIELD(m_nCase[0], FIELD_STRING, "Case01"), + DEFINE_KEYFIELD(m_nCase[1], FIELD_STRING, "Case02"), + DEFINE_KEYFIELD(m_nCase[2], FIELD_STRING, "Case03"), + DEFINE_KEYFIELD(m_nCase[3], FIELD_STRING, "Case04"), + DEFINE_KEYFIELD(m_nCase[4], FIELD_STRING, "Case05"), + DEFINE_KEYFIELD(m_nCase[5], FIELD_STRING, "Case06"), + DEFINE_KEYFIELD(m_nCase[6], FIELD_STRING, "Case07"), + DEFINE_KEYFIELD(m_nCase[7], FIELD_STRING, "Case08"), + DEFINE_KEYFIELD(m_nCase[8], FIELD_STRING, "Case09"), + DEFINE_KEYFIELD(m_nCase[9], FIELD_STRING, "Case10"), + DEFINE_KEYFIELD(m_nCase[10], FIELD_STRING, "Case11"), + DEFINE_KEYFIELD(m_nCase[11], FIELD_STRING, "Case12"), + DEFINE_KEYFIELD(m_nCase[12], FIELD_STRING, "Case13"), + DEFINE_KEYFIELD(m_nCase[13], FIELD_STRING, "Case14"), + DEFINE_KEYFIELD(m_nCase[14], FIELD_STRING, "Case15"), + DEFINE_KEYFIELD(m_nCase[15], FIELD_STRING, "Case16"), - DEFINE_UTLVECTOR( m_Listeners, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD(m_bMultipleCasesAllowed, FIELD_BOOLEAN, "MultipleCasesAllowed"), +#endif + + DEFINE_FIELD( m_nShuffleCases, FIELD_INTEGER ), + DEFINE_FIELD( m_nLastShuffleCase, FIELD_INTEGER ), + DEFINE_ARRAY( m_uchShuffleCaseMap, FIELD_CHARACTER, MAX_LOGIC_CASES ), // Inputs - DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetValue", InputSetValue), - DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetValueTest", InputSetValueTest), - DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), - DEFINE_INPUTFUNC(FIELD_VOID, "ToggleTest", InputToggleTest), - DEFINE_INPUTFUNC(FIELD_VOID, "Test", InputTest), + DEFINE_INPUTFUNC(FIELD_INPUT, "InValue", InputValue), + DEFINE_INPUTFUNC(FIELD_VOID, "PickRandom", InputPickRandom), + DEFINE_INPUTFUNC(FIELD_VOID, "PickRandomShuffle", InputPickRandomShuffle), // Outputs - DEFINE_OUTPUT(m_OnTrue, "OnTrue"), - DEFINE_OUTPUT(m_OnFalse, "OnFalse"), + DEFINE_OUTPUT(m_OnCase[0], "OnCase01"), + DEFINE_OUTPUT(m_OnCase[1], "OnCase02"), + DEFINE_OUTPUT(m_OnCase[2], "OnCase03"), + DEFINE_OUTPUT(m_OnCase[3], "OnCase04"), + DEFINE_OUTPUT(m_OnCase[4], "OnCase05"), + DEFINE_OUTPUT(m_OnCase[5], "OnCase06"), + DEFINE_OUTPUT(m_OnCase[6], "OnCase07"), + DEFINE_OUTPUT(m_OnCase[7], "OnCase08"), + DEFINE_OUTPUT(m_OnCase[8], "OnCase09"), + DEFINE_OUTPUT(m_OnCase[9], "OnCase10"), + DEFINE_OUTPUT(m_OnCase[10], "OnCase11"), + DEFINE_OUTPUT(m_OnCase[11], "OnCase12"), + DEFINE_OUTPUT(m_OnCase[12], "OnCase13"), + DEFINE_OUTPUT(m_OnCase[13], "OnCase14"), + DEFINE_OUTPUT(m_OnCase[14], "OnCase15"), + DEFINE_OUTPUT(m_OnCase[15], "OnCase16"), + + DEFINE_OUTPUT(m_OnDefault, "OnDefault"), +#ifdef MAPBASE + DEFINE_OUTPUT(m_OnUsed, "OnUsed"), +#endif END_DATADESC() -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CLogicBranch::UpdateOnRemove() -{ - for ( int i = 0; i < m_Listeners.Count(); i++ ) - { - CBaseEntity *pEntity = m_Listeners.Element( i ).Get(); - if ( pEntity ) - { - g_EventQueue.AddEvent( this, "_OnLogicBranchRemoved", 0, this, this ); - } - } - - BaseClass::UpdateOnRemove(); -} - + //----------------------------------------------------------------------------- -// Purpose: Input handler to set a new input value without firing outputs. -// Input : Boolean value to set. +// Purpose: Called before spawning, after key values have been set. //----------------------------------------------------------------------------- -void CLogicBranch::InputSetValue( inputdata_t &inputdata ) +void CLogicCase::Spawn( void ) { - UpdateValue( inputdata.value.Bool(), inputdata.pActivator, LOGIC_BRANCH_NO_FIRE ); + m_nLastShuffleCase = -1; } //----------------------------------------------------------------------------- -// Purpose: Input handler to set a new input value and fire appropriate outputs. -// Input : Boolean value to set. +// Purpose: Evaluates the new input value, firing the appropriate OnCaseX output +// if the input value matches one of the "CaseX" keys. +// Input : Value - Variant value to compare against the values of the case fields. +// We use a variant so that we can convert any input type to a string. //----------------------------------------------------------------------------- -void CLogicBranch::InputSetValueTest( inputdata_t &inputdata ) +void CLogicCase::InputValue( inputdata_t &inputdata ) { - UpdateValue( inputdata.value.Bool(), inputdata.pActivator, LOGIC_BRANCH_FIRE ); +#ifdef MAPBASE + m_OnUsed.Set(inputdata.value, inputdata.pActivator, this); + bool bFoundCase = false; +#endif + const char *pszValue = inputdata.value.String(); + for (int i = 0; i < MAX_LOGIC_CASES; i++) + { +#ifdef MAPBASE + if ((m_nCase[i] != NULL_STRING) && Matcher_Match(STRING(m_nCase[i]), pszValue)) + { + m_OnCase[i].FireOutput( inputdata.pActivator, this ); + + if (!m_bMultipleCasesAllowed) + return; + else if (!bFoundCase) + bFoundCase = true; + } +#else + if ((m_nCase[i] != NULL_STRING) && !stricmp(STRING(m_nCase[i]), pszValue)) + { + m_OnCase[i].FireOutput( inputdata.pActivator, this ); + return; + } +#endif + } + +#ifdef MAPBASE + if (!bFoundCase) +#endif + m_OnDefault.Set( inputdata.value, inputdata.pActivator, this ); } //----------------------------------------------------------------------------- -// Purpose: Input handler for toggling the boolean value without firing outputs. +// Count the number of valid cases, building a packed array +// that maps 0..NumCases to the actual CaseX values. +// +// This allows our zany mappers to set up cases sparsely if they desire. +// NOTE: assumes pnMap points to an array of MAX_LOGIC_CASES //----------------------------------------------------------------------------- -void CLogicBranch::InputToggle( inputdata_t &inputdata ) +int CLogicCase::BuildCaseMap(unsigned char *puchCaseMap) { - UpdateValue( !m_bInValue, inputdata.pActivator, LOGIC_BRANCH_NO_FIRE ); + memset(puchCaseMap, 0, sizeof(unsigned char) * MAX_LOGIC_CASES); + + int nNumCases = 0; + for (int i = 0; i < MAX_LOGIC_CASES; i++) + { + if (m_OnCase[i].NumberOfElements() > 0) + { + puchCaseMap[nNumCases] = (unsigned char)i; + nNumCases++; + } + } + + return nNumCases; } //----------------------------------------------------------------------------- -// Purpose: Input handler for toggling the boolean value and then firing the -// appropriate output based on the new value. +// Purpose: Makes the case statement choose a case at random. +//----------------------------------------------------------------------------- +void CLogicCase::InputPickRandom( inputdata_t &inputdata ) +{ + unsigned char uchCaseMap[MAX_LOGIC_CASES]; + int nNumCases = BuildCaseMap( uchCaseMap ); + + // + // Choose a random case from the ones that were set up by the level designer. + // + if ( nNumCases > 0 ) + { + int nRandom = random->RandomInt(0, nNumCases - 1); + int nCase = (unsigned char)uchCaseMap[nRandom]; + + Assert(nCase < MAX_LOGIC_CASES); + + if (nCase < MAX_LOGIC_CASES) + { + m_OnCase[nCase].FireOutput( inputdata.pActivator, this ); + } + } + else + { + DevMsg( 1, "Firing PickRandom input on logic_case %s with no cases set up\n", GetDebugName() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Makes the case statement choose a case at random. +//----------------------------------------------------------------------------- +void CLogicCase::InputPickRandomShuffle( inputdata_t &inputdata ) +{ + int nAvoidCase = -1; + int nCaseCount = m_nShuffleCases; + + if ( nCaseCount == 0 ) + { + // Starting a new shuffle batch. + nCaseCount = m_nShuffleCases = BuildCaseMap( m_uchShuffleCaseMap ); + + if ( ( m_nShuffleCases > 1 ) && ( m_nLastShuffleCase != -1 ) ) + { + // Remove the previously picked case from the case map for this pick only. + // This avoids repeats across shuffle batch boundaries. + nAvoidCase = m_nLastShuffleCase; + + for (int i = 0; i < m_nShuffleCases; i++ ) + { + if ( m_uchShuffleCaseMap[i] == nAvoidCase ) + { + unsigned char uchSwap = m_uchShuffleCaseMap[i]; + m_uchShuffleCaseMap[i] = m_uchShuffleCaseMap[nCaseCount - 1]; + m_uchShuffleCaseMap[nCaseCount - 1] = uchSwap; + nCaseCount--; + break; + } + } + } + } + + // + // Choose a random case from the ones that were set up by the level designer. + // Never repeat a case within a shuffle batch, nor consecutively across batches. + // + if ( nCaseCount > 0 ) + { + int nRandom = random->RandomInt( 0, nCaseCount - 1 ); + + int nCase = m_uchShuffleCaseMap[nRandom]; + Assert(nCase < MAX_LOGIC_CASES); + + if (nCase < MAX_LOGIC_CASES) + { + m_OnCase[nCase].FireOutput( inputdata.pActivator, this ); + } + + m_uchShuffleCaseMap[nRandom] = m_uchShuffleCaseMap[m_nShuffleCases - 1]; + m_nShuffleCases--; + + m_nLastShuffleCase = nCase; + } + else + { + DevMsg( 1, "Firing PickRandom input on logic_case %s with no cases set up\n", GetDebugName() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Compares a floating point input to a predefined value, firing an +// output to indicate the result of the comparison. +//----------------------------------------------------------------------------- +class CLogicCompare : public CLogicalEntity +{ + DECLARE_CLASS( CLogicCompare, CLogicalEntity ); + +public: + int DrawDebugTextOverlays(void); + +#ifdef MAPBASE + void Spawn(); +#endif + +private: + // Inputs + void InputSetValue( inputdata_t &inputdata ); + void InputSetValueCompare( inputdata_t &inputdata ); + void InputSetCompareValue( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetCompareValueCompare( inputdata_t &inputdata ); +#endif + void InputCompare( inputdata_t &inputdata ); + +#ifdef MAPBASE + void DoCompare(CBaseEntity *pActivator, variant_t value); +#else + void DoCompare(CBaseEntity *pActivator, float flInValue); +#endif + +#ifdef MAPBASE + bool m_bStrLenAllowed = true; + bool m_bGreaterThanOrEqual; + variant_t m_InValue; // Place to hold the last input value for a recomparison. + variant_t m_CompareValue; // The value to compare the input value against. +#else + float m_flInValue; // Place to hold the last input value for a recomparison. + float m_flCompareValue; // The value to compare the input value against. +#endif + + // Outputs +#ifdef MAPBASE + COutputVariant m_OnLessThan; // Fired when the input value is less than the compare value. + COutputVariant m_OnEqualTo; // Fired when the input value is equal to the compare value. + COutputVariant m_OnNotEqualTo; // Fired when the input value is not equal to the compare value. + COutputVariant m_OnGreaterThan; // Fired when the input value is greater than the compare value. + COutputVariant m_OnLessThanOrEqualTo; // Fired when the input value is less than or equal to the compare value. + COutputVariant m_OnGreaterThanOrEqualTo; // Fired when the input value is greater than or equal to the compare value. +#else + COutputFloat m_OnLessThan; // Fired when the input value is less than the compare value. + COutputFloat m_OnEqualTo; // Fired when the input value is equal to the compare value. + COutputFloat m_OnNotEqualTo; // Fired when the input value is not equal to the compare value. + COutputFloat m_OnGreaterThan; // Fired when the input value is greater than the compare value. +#endif + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_compare, CLogicCompare); + + +BEGIN_DATADESC( CLogicCompare ) + + // Keys +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bStrLenAllowed, FIELD_BOOLEAN, "StrLenAllowed" ), + DEFINE_KEYVARIANT(m_CompareValue, "CompareValue"), + DEFINE_KEYVARIANT(m_InValue, "InitialValue"), +#else + DEFINE_KEYFIELD(m_flCompareValue, FIELD_FLOAT, "CompareValue"), + DEFINE_KEYFIELD(m_flInValue, FIELD_FLOAT, "InitialValue"), +#endif + + // Inputs +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_INPUT, "SetValue", InputSetValue), + DEFINE_INPUTFUNC(FIELD_INPUT, "SetValueCompare", InputSetValueCompare), + DEFINE_INPUTFUNC(FIELD_INPUT, "SetCompareValue", InputSetCompareValue), + DEFINE_INPUTFUNC(FIELD_INPUT, "SetCompareValueCompare", InputSetCompareValueCompare), +#else + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetValue", InputSetValue), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetValueCompare", InputSetValueCompare), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetCompareValue", InputSetCompareValue), +#endif + DEFINE_INPUTFUNC(FIELD_VOID, "Compare", InputCompare), + + // Outputs + DEFINE_OUTPUT(m_OnEqualTo, "OnEqualTo"), + DEFINE_OUTPUT(m_OnNotEqualTo, "OnNotEqualTo"), + DEFINE_OUTPUT(m_OnGreaterThan, "OnGreaterThan"), + DEFINE_OUTPUT(m_OnLessThan, "OnLessThan"), +#ifdef MAPBASE + DEFINE_OUTPUT(m_OnGreaterThanOrEqualTo, "OnGreaterThanOrEqualTo"), + DEFINE_OUTPUT(m_OnLessThanOrEqualTo, "OnLessThanOrEqualTo"), +#endif + +END_DATADESC() + + + + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for a new input value without performing a comparison. +//----------------------------------------------------------------------------- +void CLogicCompare::Spawn() +{ + // Empty initial values are equivalent to 0 + if (m_InValue.FieldType() == FIELD_STRING && m_InValue.String()[0] == '\0') + m_InValue.SetInt( 0 ); + + BaseClass::Spawn(); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Input handler for a new input value without performing a comparison. +//----------------------------------------------------------------------------- +void CLogicCompare::InputSetValue( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + m_InValue = Variant_ParseInput(inputdata); +#else + m_flInValue = inputdata.value.Float(); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for a setting a new value and doing the comparison. +//----------------------------------------------------------------------------- +void CLogicCompare::InputSetValueCompare( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + m_InValue = Variant_ParseInput(inputdata); + DoCompare( inputdata.pActivator, m_InValue ); +#else + m_flInValue = inputdata.value.Float(); + DoCompare( inputdata.pActivator, m_flInValue ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for a new input value without performing a comparison. +//----------------------------------------------------------------------------- +void CLogicCompare::InputSetCompareValue( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + m_CompareValue = Variant_ParseInput(inputdata); +#else + m_flCompareValue = inputdata.value.Float(); +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for a new input value and doing the comparison. +//----------------------------------------------------------------------------- +void CLogicCompare::InputSetCompareValueCompare( inputdata_t &inputdata ) +{ + m_CompareValue = Variant_ParseInput(inputdata); + DoCompare( inputdata.pActivator, m_InValue ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Input handler for forcing a recompare of the last input value. +//----------------------------------------------------------------------------- +void CLogicCompare::InputCompare( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + DoCompare( inputdata.pActivator, m_InValue ); +#else + DoCompare( inputdata.pActivator, m_flInValue ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: Compares the input value to the compare value, firing the appropriate +// output(s) based on the comparison result. +// Input : flInValue - Value to compare against the comparison value. +//----------------------------------------------------------------------------- +#ifdef MAPBASE +void CLogicCompare::DoCompare(CBaseEntity *pActivator, variant_t value) +{ + if (Variant_Equal(value, m_CompareValue, m_bStrLenAllowed)) + { + m_OnEqualTo.Set(value, pActivator, this); + + m_OnLessThanOrEqualTo.Set(value, pActivator, this); + m_OnGreaterThanOrEqualTo.Set(value, pActivator, this); + } + else + { + m_OnNotEqualTo.Set(value, pActivator, this); + + if (Variant_Greater(m_InValue, m_CompareValue, m_bStrLenAllowed)) + { + m_OnGreaterThan.Set(value, pActivator, this); + m_OnGreaterThanOrEqualTo.Set(value, pActivator, this); + } + else + { + m_OnLessThan.Set(value, pActivator, this); + m_OnLessThanOrEqualTo.Set(value, pActivator, this); + } + } +} +#else +void CLogicCompare::DoCompare(CBaseEntity *pActivator, float flInValue) +{ + if (flInValue == m_flCompareValue) + { + m_OnEqualTo.Set(flInValue, pActivator, this); + } + else + { + m_OnNotEqualTo.Set(flInValue, pActivator, this); + + if (flInValue > m_flCompareValue) + { + m_OnGreaterThan.Set(flInValue, pActivator, this); + } + else + { + m_OnLessThan.Set(flInValue, pActivator, this); + } + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CLogicCompare::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + // print duration +#ifdef MAPBASE + Q_snprintf(tempstr,sizeof(tempstr)," Initial Value: %s", m_InValue.GetDebug()); +#else + Q_snprintf(tempstr,sizeof(tempstr)," Initial Value: %f", m_flInValue); +#endif + EntityText(text_offset,tempstr,0); + text_offset++; + + // print hold time +#ifdef MAPBASE + Q_snprintf(tempstr,sizeof(tempstr)," Compare Value: %s", m_CompareValue.GetDebug()); +#else + Q_snprintf(tempstr,sizeof(tempstr)," Compare Value: %f", m_flCompareValue); +#endif + EntityText(text_offset,tempstr,0); + text_offset++; + } + return text_offset; +} + +//----------------------------------------------------------------------------- +// Purpose: Tests a boolean value, firing an output to indicate whether the +// value was true or false. +//----------------------------------------------------------------------------- +class CLogicBranch : public CLogicalEntity +{ + DECLARE_CLASS( CLogicBranch, CLogicalEntity ); + +public: + + void UpdateOnRemove(); + + void AddLogicBranchListener( CBaseEntity *pEntity ); + inline bool GetLogicBranchState(); + virtual int DrawDebugTextOverlays( void ); + +private: + + enum LogicBranchFire_t + { + LOGIC_BRANCH_FIRE, + LOGIC_BRANCH_NO_FIRE, + }; + + // Inputs + void InputSetValue( inputdata_t &inputdata ); + void InputSetValueTest( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + void InputToggleTest( inputdata_t &inputdata ); + void InputTest( inputdata_t &inputdata ); + + void UpdateValue(bool bNewValue, CBaseEntity *pActivator, LogicBranchFire_t eFire); + + bool m_bInValue; // Place to hold the last input value for a future test. + + CUtlVector m_Listeners; // A list of logic_branch_listeners that are monitoring us. + + // Outputs + COutputEvent m_OnTrue; // Fired when the value is true. + COutputEvent m_OnFalse; // Fired when the value is false. + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_branch, CLogicBranch); + + +BEGIN_DATADESC( CLogicBranch ) + + // Keys + DEFINE_KEYFIELD(m_bInValue, FIELD_BOOLEAN, "InitialValue"), + + DEFINE_UTLVECTOR( m_Listeners, FIELD_EHANDLE ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetValue", InputSetValue), + DEFINE_INPUTFUNC(FIELD_BOOLEAN, "SetValueTest", InputSetValueTest), + DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), + DEFINE_INPUTFUNC(FIELD_VOID, "ToggleTest", InputToggleTest), + DEFINE_INPUTFUNC(FIELD_VOID, "Test", InputTest), + + // Outputs + DEFINE_OUTPUT(m_OnTrue, "OnTrue"), + DEFINE_OUTPUT(m_OnFalse, "OnFalse"), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicBranch::UpdateOnRemove() +{ + for ( int i = 0; i < m_Listeners.Count(); i++ ) + { + CBaseEntity *pEntity = m_Listeners.Element( i ).Get(); + if ( pEntity ) + { + g_EventQueue.AddEvent( this, "_OnLogicBranchRemoved", 0, this, this ); + } + } + + BaseClass::UpdateOnRemove(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler to set a new input value without firing outputs. +// Input : Boolean value to set. +//----------------------------------------------------------------------------- +void CLogicBranch::InputSetValue( inputdata_t &inputdata ) +{ + UpdateValue( inputdata.value.Bool(), inputdata.pActivator, LOGIC_BRANCH_NO_FIRE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler to set a new input value and fire appropriate outputs. +// Input : Boolean value to set. +//----------------------------------------------------------------------------- +void CLogicBranch::InputSetValueTest( inputdata_t &inputdata ) +{ + UpdateValue( inputdata.value.Bool(), inputdata.pActivator, LOGIC_BRANCH_FIRE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for toggling the boolean value without firing outputs. +//----------------------------------------------------------------------------- +void CLogicBranch::InputToggle( inputdata_t &inputdata ) +{ + UpdateValue( !m_bInValue, inputdata.pActivator, LOGIC_BRANCH_NO_FIRE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for toggling the boolean value and then firing the +// appropriate output based on the new value. +//----------------------------------------------------------------------------- +void CLogicBranch::InputToggleTest( inputdata_t &inputdata ) +{ + UpdateValue( !m_bInValue, inputdata.pActivator, LOGIC_BRANCH_FIRE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for forcing a test of the last input value. +//----------------------------------------------------------------------------- +void CLogicBranch::InputTest( inputdata_t &inputdata ) +{ + UpdateValue( m_bInValue, inputdata.pActivator, LOGIC_BRANCH_FIRE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Tests the last input value, firing the appropriate output based on +// the test result. +// Input : bInValue - +//----------------------------------------------------------------------------- +void CLogicBranch::UpdateValue( bool bNewValue, CBaseEntity *pActivator, LogicBranchFire_t eFire ) +{ + if ( m_bInValue != bNewValue ) + { + m_bInValue = bNewValue; + + for ( int i = 0; i < m_Listeners.Count(); i++ ) + { + CBaseEntity *pEntity = m_Listeners.Element( i ).Get(); + if ( pEntity ) + { + g_EventQueue.AddEvent( pEntity, "_OnLogicBranchChanged", 0, this, this ); + } + } + } + + if ( eFire == LOGIC_BRANCH_FIRE ) + { + if ( m_bInValue ) + { + m_OnTrue.FireOutput( pActivator, this ); + } + else + { + m_OnFalse.FireOutput( pActivator, this ); + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Accessor for logic_branchlist to test the value of the branch on demand. +//----------------------------------------------------------------------------- +bool CLogicBranch::GetLogicBranchState() +{ + return m_bInValue; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicBranch::AddLogicBranchListener( CBaseEntity *pEntity ) +{ + if ( m_Listeners.Find( pEntity ) == -1 ) + { + m_Listeners.AddToTail( pEntity ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CLogicBranch::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + // print refire time + Q_snprintf( tempstr, sizeof(tempstr), "Branch value: %s", (m_bInValue) ? "TRUE" : "FALSE" ); + EntityText( text_offset, tempstr, 0 ); + text_offset++; + } + + return text_offset; +} + +#ifdef MAPBASE +extern void MapbaseGameLog_Record( const char *szContext ); +extern ConVar mapbase_game_log_on_autosave; +#endif + +//----------------------------------------------------------------------------- +// Purpose: Autosaves when triggered +//----------------------------------------------------------------------------- +class CLogicAutosave : public CLogicalEntity +{ + DECLARE_CLASS( CLogicAutosave, CLogicalEntity ); + +protected: + // Inputs + void InputSave( inputdata_t &inputdata ); + void InputSaveDangerous( inputdata_t &inputdata ); + void InputSetMinHitpointsThreshold( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + bool m_bForceNewLevelUnit; + int m_minHitPoints; + int m_minHitPointsToCommit; +}; + +LINK_ENTITY_TO_CLASS(logic_autosave, CLogicAutosave); + +BEGIN_DATADESC( CLogicAutosave ) + DEFINE_KEYFIELD( m_bForceNewLevelUnit, FIELD_BOOLEAN, "NewLevelUnit" ), + DEFINE_KEYFIELD( m_minHitPoints, FIELD_INTEGER, "MinimumHitPoints" ), + DEFINE_KEYFIELD( m_minHitPointsToCommit, FIELD_INTEGER, "MinHitPointsToCommit" ), + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Save", InputSave ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SaveDangerous", InputSaveDangerous ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMinHitpointsThreshold", InputSetMinHitpointsThreshold ), +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Save! +//----------------------------------------------------------------------------- +void CLogicAutosave::InputSave( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + if (mapbase_game_log_on_autosave.GetBool()) + { + MapbaseGameLog_Record( "autosave" ); + } +#endif + + if ( m_bForceNewLevelUnit ) + { + engine->ClearSaveDir(); + } + + engine->ServerCommand( "autosave\n" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Save safely! +//----------------------------------------------------------------------------- +void CLogicAutosave::InputSaveDangerous( inputdata_t &inputdata ) +{ +#ifdef MAPBASE + if (mapbase_game_log_on_autosave.GetBool()) + { + MapbaseGameLog_Record( "autosave_dangerous" ); + } +#endif + + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + + if ( g_ServerGameDLL.m_fAutoSaveDangerousTime != 0.0f && g_ServerGameDLL.m_fAutoSaveDangerousTime >= gpGlobals->curtime ) + { + // A previous dangerous auto save was waiting to become safe + + if ( pPlayer->GetDeathTime() == 0.0f || pPlayer->GetDeathTime() > gpGlobals->curtime ) + { + // The player isn't dead, so make the dangerous auto save safe + engine->ServerCommand( "autosavedangerousissafe\n" ); + } + } + + if ( m_bForceNewLevelUnit ) + { + engine->ClearSaveDir(); + } + + if ( pPlayer->GetHealth() >= m_minHitPoints ) + { + engine->ServerCommand( "autosavedangerous\n" ); + g_ServerGameDLL.m_fAutoSaveDangerousTime = gpGlobals->curtime + inputdata.value.Float(); + + // Player must have this much health when we go to commit, or we don't commit. + g_ServerGameDLL.m_fAutoSaveDangerousMinHealthToCommit = m_minHitPointsToCommit; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Autosaves when triggered +//----------------------------------------------------------------------------- +class CLogicActiveAutosave : public CLogicAutosave +{ + DECLARE_CLASS( CLogicActiveAutosave, CLogicAutosave ); + + void InputEnable( inputdata_t &inputdata ) + { + m_flStartTime = -1; + SetThink( &CLogicActiveAutosave::SaveThink ); + SetNextThink( gpGlobals->curtime ); + } + + void InputDisable( inputdata_t &inputdata ) + { + SetThink( NULL ); + } + + void SaveThink() + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer ) + { + if ( m_flStartTime < 0 ) + { + if ( pPlayer->GetHealth() <= m_minHitPoints ) + { + m_flStartTime = gpGlobals->curtime; + } + } + else + { + if ( pPlayer->GetHealth() >= m_TriggerHitPoints ) + { + inputdata_t inputdata; + DevMsg( 2, "logic_active_autosave (%s, %d) triggered\n", STRING( GetEntityName() ), entindex() ); + if ( !m_flDangerousTime ) + { + InputSave( inputdata ); + } + else + { + inputdata.value.SetFloat( m_flDangerousTime ); + InputSaveDangerous( inputdata ); + } + m_flStartTime = -1; + } + else if ( m_flTimeToTrigger > 0 && gpGlobals->curtime - m_flStartTime > m_flTimeToTrigger ) + { + m_flStartTime = -1; + } + } + } + + float thinkInterval = ( m_flStartTime < 0 ) ? 1.0 : 0.5; + SetNextThink( gpGlobals->curtime + thinkInterval ); + } + + DECLARE_DATADESC(); + + int m_TriggerHitPoints; + float m_flTimeToTrigger; + float m_flStartTime; + float m_flDangerousTime; +}; + +LINK_ENTITY_TO_CLASS(logic_active_autosave, CLogicActiveAutosave); + +BEGIN_DATADESC( CLogicActiveAutosave ) + DEFINE_KEYFIELD( m_TriggerHitPoints, FIELD_INTEGER, "TriggerHitPoints" ), + DEFINE_KEYFIELD( m_flTimeToTrigger, FIELD_FLOAT, "TimeToTrigger" ), + DEFINE_KEYFIELD( m_flDangerousTime, FIELD_FLOAT, "DangerousTime" ), + DEFINE_FIELD( m_flStartTime, FIELD_TIME ), + DEFINE_THINKFUNC( SaveThink ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: Keyfield set func +//----------------------------------------------------------------------------- +void CLogicAutosave::InputSetMinHitpointsThreshold( inputdata_t &inputdata ) +{ + int setTo = inputdata.value.Int(); + AssertMsg1(setTo >= 0 && setTo <= 100, "Tried to set autosave MinHitpointsThreshold to %d!\n", setTo); + m_minHitPoints = setTo; +} + +// Finds the named physics object. If no name, returns the world +// If a name is specified and an object not found - errors are reported +IPhysicsObject *FindPhysicsObjectByNameOrWorld( string_t name, CBaseEntity *pErrorEntity ) +{ + if ( !name ) + return g_PhysWorldObject; + + IPhysicsObject *pPhysics = FindPhysicsObjectByName( name.ToCStr(), pErrorEntity ); + if ( !pPhysics ) + { + DevWarning("%s: can't find %s\n", pErrorEntity->GetClassname(), name.ToCStr()); + } + return pPhysics; +} + +class CLogicCollisionPair : public CLogicalEntity +{ + DECLARE_CLASS( CLogicCollisionPair, CLogicalEntity ); +public: + +#ifdef MAPBASE + // !activator, !caller, etc. support + void EnableCollisions( bool bEnable, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) + { + IPhysicsObject *pPhysics0 = NULL; + IPhysicsObject *pPhysics1 = NULL; + + CBaseEntity *pEntity0 = gEntList.FindEntityByName( NULL, m_nameAttach1, this, pActivator, pCaller ); + if (pEntity0) + pPhysics0 = pEntity0->VPhysicsGetObject(); + + CBaseEntity *pEntity1 = gEntList.FindEntityByName( NULL, m_nameAttach2, this, pActivator, pCaller ); + if (pEntity1) + pPhysics1 = pEntity1->VPhysicsGetObject(); +#else + void EnableCollisions( bool bEnable ) + { + IPhysicsObject *pPhysics0 = FindPhysicsObjectByNameOrWorld( m_nameAttach1, this ); + IPhysicsObject *pPhysics1 = FindPhysicsObjectByNameOrWorld( m_nameAttach2, this ); +#endif + + // need two different objects to do anything + if ( pPhysics0 && pPhysics1 && pPhysics0 != pPhysics1 ) + { + m_disabled = !bEnable; + m_succeeded = true; + if ( bEnable ) + { + PhysEnableEntityCollisions( pPhysics0, pPhysics1 ); + } + else + { + PhysDisableEntityCollisions( pPhysics0, pPhysics1 ); + } + } + else + { + m_succeeded = false; + } + } + + void Activate( void ) + { + if ( m_disabled ) + { + EnableCollisions( false ); + } + BaseClass::Activate(); + } + + void InputDisableCollisions( inputdata_t &inputdata ) + { + if ( m_succeeded && m_disabled ) + return; +#ifdef MAPBASE + EnableCollisions( false, inputdata.pActivator, inputdata.pCaller ); +#else + EnableCollisions( false ); +#endif + } + + void InputEnableCollisions( inputdata_t &inputdata ) + { + if ( m_succeeded && !m_disabled ) + return; +#ifdef MAPBASE + EnableCollisions( true, inputdata.pActivator, inputdata.pCaller ); +#else + EnableCollisions( true ); +#endif + } + // If Activate() becomes PostSpawn() + //void OnRestore() { Activate(); } + + DECLARE_DATADESC(); + +private: + string_t m_nameAttach1; + string_t m_nameAttach2; + bool m_disabled; + bool m_succeeded; +}; + +BEGIN_DATADESC( CLogicCollisionPair ) + DEFINE_KEYFIELD( m_nameAttach1, FIELD_STRING, "attach1" ), + DEFINE_KEYFIELD( m_nameAttach2, FIELD_STRING, "attach2" ), + DEFINE_KEYFIELD( m_disabled, FIELD_BOOLEAN, "startdisabled" ), + DEFINE_FIELD( m_succeeded, FIELD_BOOLEAN ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "DisableCollisions", InputDisableCollisions ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableCollisions", InputEnableCollisions ), +END_DATADESC() + +LINK_ENTITY_TO_CLASS( logic_collision_pair, CLogicCollisionPair ); + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#define MAX_LOGIC_BRANCH_NAMES 16 + +class CLogicBranchList : public CLogicalEntity +{ + DECLARE_CLASS( CLogicBranchList, CLogicalEntity ); + + virtual void Spawn(); + virtual void Activate(); + virtual int DrawDebugTextOverlays( void ); + +private: + + enum LogicBranchListenerLastState_t + { + LOGIC_BRANCH_LISTENER_NOT_INIT = 0, + LOGIC_BRANCH_LISTENER_ALL_TRUE, + LOGIC_BRANCH_LISTENER_ALL_FALSE, + LOGIC_BRANCH_LISTENER_MIXED, + }; + + void DoTest( CBaseEntity *pActivator ); + + string_t m_nLogicBranchNames[MAX_LOGIC_BRANCH_NAMES]; + CUtlVector m_LogicBranchList; + LogicBranchListenerLastState_t m_eLastState; + + // Inputs + void Input_OnLogicBranchRemoved( inputdata_t &inputdata ); + void Input_OnLogicBranchChanged( inputdata_t &inputdata ); + void InputTest( inputdata_t &inputdata ); + + // Outputs + COutputEvent m_OnAllTrue; // Fired when all the registered logic_branches become true. + COutputEvent m_OnAllFalse; // Fired when all the registered logic_branches become false. + COutputEvent m_OnMixed; // Fired when one of the registered logic branches changes, but not all are true or false. + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_branch_listener, CLogicBranchList); + + +BEGIN_DATADESC( CLogicBranchList ) + + // Silence, classcheck! + //DEFINE_ARRAY( m_nLogicBranchNames, FIELD_STRING, MAX_LOGIC_BRANCH_NAMES ), + + // Keys + DEFINE_KEYFIELD( m_nLogicBranchNames[0], FIELD_STRING, "Branch01" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[1], FIELD_STRING, "Branch02" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[2], FIELD_STRING, "Branch03" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[3], FIELD_STRING, "Branch04" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[4], FIELD_STRING, "Branch05" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[5], FIELD_STRING, "Branch06" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[6], FIELD_STRING, "Branch07" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[7], FIELD_STRING, "Branch08" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[8], FIELD_STRING, "Branch09" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[9], FIELD_STRING, "Branch10" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[10], FIELD_STRING, "Branch11" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[11], FIELD_STRING, "Branch12" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[12], FIELD_STRING, "Branch13" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[13], FIELD_STRING, "Branch14" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[14], FIELD_STRING, "Branch15" ), + DEFINE_KEYFIELD( m_nLogicBranchNames[15], FIELD_STRING, "Branch16" ), + + DEFINE_UTLVECTOR( m_LogicBranchList, FIELD_EHANDLE ), + + DEFINE_FIELD( m_eLastState, FIELD_INTEGER ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_INPUT, "Test", InputTest ), + DEFINE_INPUTFUNC( FIELD_INPUT, "_OnLogicBranchChanged", Input_OnLogicBranchChanged ), + DEFINE_INPUTFUNC( FIELD_INPUT, "_OnLogicBranchRemoved", Input_OnLogicBranchRemoved ), + + // Outputs + DEFINE_OUTPUT( m_OnAllTrue, "OnAllTrue" ), + DEFINE_OUTPUT( m_OnAllFalse, "OnAllFalse" ), + DEFINE_OUTPUT( m_OnMixed, "OnMixed" ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: Called before spawning, after key values have been set. +//----------------------------------------------------------------------------- +void CLogicBranchList::Spawn( void ) +{ +} + + +//----------------------------------------------------------------------------- +// Finds all the logic_branches that we are monitoring and register ourselves with them. +//----------------------------------------------------------------------------- +void CLogicBranchList::Activate( void ) +{ + for ( int i = 0; i < MAX_LOGIC_BRANCH_NAMES; i++ ) + { + CBaseEntity *pEntity = NULL; + while ( ( pEntity = gEntList.FindEntityGeneric( pEntity, STRING( m_nLogicBranchNames[i] ), this ) ) != NULL ) + { + if ( FClassnameIs( pEntity, "logic_branch" ) ) + { + CLogicBranch *pBranch = (CLogicBranch *)pEntity; + pBranch->AddLogicBranchListener( this ); + m_LogicBranchList.AddToTail( pBranch ); + } + else + { + DevWarning( "logic_branchlist %s refers to entity %s, which is not a logic_branch\n", GetDebugName(), pEntity->GetDebugName() ); + } + } + } + + BaseClass::Activate(); +} + + +//----------------------------------------------------------------------------- +// Called when a monitored logic branch is deleted from the world, since that +// might affect our final result. +//----------------------------------------------------------------------------- +void CLogicBranchList::Input_OnLogicBranchRemoved( inputdata_t &inputdata ) +{ + int nIndex = m_LogicBranchList.Find( inputdata.pActivator ); + if ( nIndex != -1 ) + { + m_LogicBranchList.FastRemove( nIndex ); + } + + // See if this logic_branch's deletion affects the final result. + DoTest( inputdata.pActivator ); +} + + +//----------------------------------------------------------------------------- +// Called when the value of a monitored logic branch changes. +//----------------------------------------------------------------------------- +void CLogicBranchList::Input_OnLogicBranchChanged( inputdata_t &inputdata ) +{ + DoTest( inputdata.pActivator ); +} + + +//----------------------------------------------------------------------------- +// Input handler to manually test the monitored logic branches and fire the +// appropriate output. +//----------------------------------------------------------------------------- +void CLogicBranchList::InputTest( inputdata_t &inputdata ) +{ + // Force an output. + m_eLastState = LOGIC_BRANCH_LISTENER_NOT_INIT; + + DoTest( inputdata.pActivator ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicBranchList::DoTest( CBaseEntity *pActivator ) +{ + bool bOneTrue = false; + bool bOneFalse = false; + + for ( int i = 0; i < m_LogicBranchList.Count(); i++ ) + { + CLogicBranch *pBranch = (CLogicBranch *)m_LogicBranchList.Element( i ).Get(); + if ( pBranch && pBranch->GetLogicBranchState() ) + { + bOneTrue = true; + } + else + { + bOneFalse = true; + } + } + + // Only fire the output if the new result differs from the last result. + if ( bOneTrue && !bOneFalse ) + { + if ( m_eLastState != LOGIC_BRANCH_LISTENER_ALL_TRUE ) + { + m_OnAllTrue.FireOutput( pActivator, this ); + m_eLastState = LOGIC_BRANCH_LISTENER_ALL_TRUE; + } + } + else if ( bOneFalse && !bOneTrue ) + { + if ( m_eLastState != LOGIC_BRANCH_LISTENER_ALL_FALSE ) + { + m_OnAllFalse.FireOutput( pActivator, this ); + m_eLastState = LOGIC_BRANCH_LISTENER_ALL_FALSE; + } + } + else + { + if ( m_eLastState != LOGIC_BRANCH_LISTENER_MIXED ) + { + m_OnMixed.FireOutput( pActivator, this ); + m_eLastState = LOGIC_BRANCH_LISTENER_MIXED; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CLogicBranchList::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + for ( int i = 0; i < m_LogicBranchList.Count(); i++ ) + { + CLogicBranch *pBranch = (CLogicBranch *)m_LogicBranchList.Element( i ).Get(); + if ( pBranch ) + { + Q_snprintf( tempstr, sizeof(tempstr), "Branch (%s): %s", STRING(pBranch->GetEntityName()), (pBranch->GetLogicBranchState()) ? "TRUE" : "FALSE" ); + EntityText( text_offset, tempstr, 0 ); + text_offset++; + } + } + } + + return text_offset; +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Prints messages to the console. +//----------------------------------------------------------------------------- +class CLogicConsole : public CLogicalEntity +{ +public: + + DECLARE_CLASS( CLogicConsole, CLogicalEntity ); + + // Keys + int m_iDevLevel = 1; + Color m_MsgColor = Color(210, 250, 255, 255); + Color m_WarningColor = Color(255, 210, 210, 255); + bool m_bNewLineNotAuto = false; + + // TODO: Replace "append" with variable arguments? + inline void LCMsg(const char *msg, const char *append = NULL) { ConColorMsg(m_MsgColor, msg, append); } + inline void LCDevMsg(int lvl, const char *msg, const char *append = NULL) { developer.GetInt() >= lvl ? ConColorMsg(m_MsgColor, msg, append) : (void)0; } + inline void LCWarning(const char *msg, const char *append = NULL) { ConColorMsg(m_WarningColor, msg, append); } + inline void LCDevWarning(int lvl, const char *msg, const char *append = NULL) { developer.GetInt() >= lvl ? ConColorMsg(m_WarningColor, msg, append) : (void)0; } + + //inline void LCMsg(const char *msg, const char *append = NULL) { ColorSpewMessage(SPEW_MESSAGE, &m_MsgColor, msg, append); } + //inline void LCDevMsg(int lvl, const char *msg, const char *append = NULL) { developer.GetInt() >= lvl ? ColorSpewMessage(SPEW_MESSAGE, &m_MsgColor, msg, append) : (void)0; } + //inline void LCWarning(const char *msg, const char *append = NULL) { ColorSpewMessage(SPEW_MESSAGE, &m_WarningColor, msg, append); } + //inline void LCDevWarning(int lvl, const char *msg, const char *append = NULL) { developer.GetInt() >= lvl ? ColorSpewMessage(SPEW_MESSAGE, &m_WarningColor, msg, append) : (void)0; } + + // Inputs + void InputSendMsg( inputdata_t &inputdata ) { !m_bNewLineNotAuto ? LCMsg("%s\n", inputdata.value.String()) : LCMsg("%s", inputdata.value.String()); } + void InputSendWarning( inputdata_t &inputdata ) { !m_bNewLineNotAuto ? LCWarning("%s\n", inputdata.value.String()) : LCWarning("%s", inputdata.value.String()); } + void InputSendDevMsg( inputdata_t &inputdata ) { !m_bNewLineNotAuto ? LCDevMsg(m_iDevLevel, "%s\n", inputdata.value.String()) : LCDevMsg(m_iDevLevel, "%s", inputdata.value.String()); } + void InputSendDevWarning( inputdata_t &inputdata ) { !m_bNewLineNotAuto ? LCDevWarning(m_iDevLevel, "%s\n", inputdata.value.String()) : LCDevWarning(m_iDevLevel, "%s", inputdata.value.String()); } + + void InputNewLine( inputdata_t &inputdata ) { LCMsg("\n"); } + void InputDevNewLine( inputdata_t &inputdata ) { LCDevMsg(m_iDevLevel, "\n"); } + + // MAPBASE MP TODO: "ClearConsoleOnTarget" + // (and make this input broadcast to all players) + void InputClearConsole( inputdata_t &inputdata ) { UTIL_GetLocalPlayer() ? engine->ClientCommand(UTIL_GetLocalPlayer()->edict(), "clear") : (void)0; } + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_console, CLogicConsole); + + +BEGIN_DATADESC( CLogicConsole ) + + DEFINE_INPUT( m_iDevLevel, FIELD_INTEGER, "SetDevLvl" ), + DEFINE_INPUT( m_MsgColor, FIELD_COLOR32, "SetMsgColor" ), + DEFINE_INPUT( m_WarningColor, FIELD_COLOR32, "SetWarningColor" ), + DEFINE_INPUT( m_bNewLineNotAuto, FIELD_BOOLEAN, "SetNewLineNotAuto" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SendMsg", InputSendMsg ), + DEFINE_INPUTFUNC( FIELD_STRING, "SendWarning", InputSendWarning ), + DEFINE_INPUTFUNC( FIELD_STRING, "SendDevMsg", InputSendDevMsg ), + DEFINE_INPUTFUNC( FIELD_STRING, "SendDevWarning", InputSendDevWarning ), + + DEFINE_INPUTFUNC( FIELD_VOID, "NewLine", InputNewLine ), + DEFINE_INPUTFUNC( FIELD_VOID, "DevNewLine", InputDevNewLine ), + + DEFINE_INPUTFUNC( FIELD_VOID, "ClearConsole", InputClearConsole ), + +END_DATADESC() + +ConVar sv_allow_logic_convar( "sv_allow_logic_convar", "1", FCVAR_NOT_CONNECTED ); + +//----------------------------------------------------------------------------- +// Purpose: Gets console variables for the evil mapper. +//----------------------------------------------------------------------------- +class CLogicConvar : public CLogicalEntity +{ +public: + + DECLARE_CLASS( CLogicConvar, CLogicalEntity ); + + // Keys + string_t m_iszConVar; + string_t m_iszCompareValue; + + const char *GetConVarString( inputdata_t &inputdata ); + + // Inputs + void InputGetValue( inputdata_t &inputdata ); + void InputTest( inputdata_t &inputdata ); + + // Outputs + COutputEvent m_OnTrue; + COutputEvent m_OnFalse; + COutputString m_OutValue; + COutputEvent m_OnDenied; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_convar, CLogicConvar); + + +BEGIN_DATADESC( CLogicConvar ) + + DEFINE_INPUT( m_iszConVar, FIELD_STRING, "SetConVar" ), + DEFINE_INPUT( m_iszCompareValue, FIELD_STRING, "SetTestValue" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "GetValue", InputGetValue ), + DEFINE_INPUTFUNC( FIELD_VOID, "Test", InputTest ), + + DEFINE_OUTPUT(m_OnTrue, "OnTrue"), + DEFINE_OUTPUT(m_OnFalse, "OnFalse"), + DEFINE_OUTPUT(m_OutValue, "OutValue"), + DEFINE_OUTPUT(m_OnDenied, "OnDenied"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const char *CLogicConvar::GetConVarString( inputdata_t &inputdata ) +{ + if (!sv_allow_logic_convar.GetBool()) + { + m_OnDenied.FireOutput(this, this); + + //return ConVarRef("", true); + return NULL; + } + + ConVarRef pCVar = ConVarRef(STRING(m_iszConVar), true); + if (!pCVar.IsValid()) + { + const char *pszCVar = STRING( m_iszConVar ); + CBasePlayer *pPlayer = ToBasePlayer( inputdata.pActivator ); + if (!pPlayer && AI_IsSinglePlayer()) + pPlayer = UTIL_PlayerByIndex( 1 ); + + if (pPlayer) + { + // Check if it's a common cheat command a player might be using + if (FStrEq( pszCVar, "god" )) + return (pPlayer->GetFlags() & FL_GODMODE) ? "1" : "0"; + if (FStrEq( pszCVar, "notarget" )) + return (pPlayer->GetFlags() & FL_NOTARGET) ? "1" : "0"; + if (FStrEq( pszCVar, "noclip" )) + return (pPlayer->IsEFlagSet(EFL_NOCLIP_ACTIVE)) ? "1" : "0"; + + // It might be a client convar + // This function returns a blank string if the convar doesn't exist, so we have to put this at the end + const char *pszClientValue = engine->GetClientConVarValue( pPlayer->GetClientIndex(), pszCVar ); + if (pszClientValue) + { + return pszClientValue; + } + } + + //Warning("Warning: %s has invalid convar \"%s\"\n", GetDebugName(), STRING(m_iszConVar)); + } + + return pCVar.GetString(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicConvar::InputGetValue( inputdata_t &inputdata ) +{ + const char *pCVarString = GetConVarString(inputdata); + if (pCVarString != NULL) + m_OutValue.Set( AllocPooledString( pCVarString ), inputdata.pActivator, this ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicConvar::InputTest( inputdata_t &inputdata ) +{ + const char *pCVarString = GetConVarString(inputdata); + if (pCVarString) + { + if (Matcher_Match( STRING( m_iszCompareValue ), pCVarString )) + { + m_OnTrue.FireOutput(inputdata.pActivator, this); + } + else + { + m_OnFalse.FireOutput(inputdata.pActivator, this); + } + } +} + +#define MAX_LOGIC_FORMAT_PARAMETERS 8 +//----------------------------------------------------------------------------- +// Purpose: Takes a string and a bunch of parameters and spits out a formatted string. +//----------------------------------------------------------------------------- +class CLogicFormat : public CLogicalEntity +{ +public: + + DECLARE_CLASS( CLogicFormat, CLogicalEntity ); + + // Keys + string_t m_iszInput; + string_t m_iszParameter[MAX_LOGIC_FORMAT_PARAMETERS]; + string_t m_iszBackupParameter; + + void FormatString(const char *szStringToFormat, char *szOutput, int outputlen); + + // Inputs + void InputGetFormattedString( inputdata_t &inputdata ); + + // Outputs + COutputString m_OutFormattedString; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_format, CLogicFormat); + + +BEGIN_DATADESC( CLogicFormat ) + + DEFINE_INPUT( m_iszInput, FIELD_STRING, "SetInputValue" ), + DEFINE_INPUT( m_iszParameter[0], FIELD_STRING, "SetParameter0" ), + DEFINE_INPUT( m_iszParameter[1], FIELD_STRING, "SetParameter1" ), + DEFINE_INPUT( m_iszParameter[2], FIELD_STRING, "SetParameter2" ), + DEFINE_INPUT( m_iszParameter[3], FIELD_STRING, "SetParameter3" ), + DEFINE_INPUT( m_iszParameter[4], FIELD_STRING, "SetParameter4" ), + DEFINE_INPUT( m_iszParameter[5], FIELD_STRING, "SetParameter5" ), + DEFINE_INPUT( m_iszParameter[6], FIELD_STRING, "SetParameter6" ), + DEFINE_INPUT( m_iszParameter[7], FIELD_STRING, "SetParameter7" ), + DEFINE_INPUT( m_iszBackupParameter, FIELD_STRING, "SetBackupParameter" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "GetFormattedValue", InputGetFormattedString ), + + DEFINE_OUTPUT(m_OutFormattedString, "OutFormattedValue"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicFormat::InputGetFormattedString( inputdata_t &inputdata ) +{ + char szFormatted[256]; + if (m_iszInput != NULL_STRING) + { + FormatString(STRING(m_iszInput), szFormatted, sizeof(szFormatted)); + m_OutFormattedString.Set(AllocPooledString(szFormatted), inputdata.pActivator, this); + } +} + +//----------------------------------------------------------------------------- +// I'm bad at coding. +//----------------------------------------------------------------------------- +void CLogicFormat::FormatString(const char *szStringToFormat, char *szOutput, int outputlen) +{ + const char *szParameters[MAX_LOGIC_FORMAT_PARAMETERS]; + for (int i = 0; i < MAX_LOGIC_FORMAT_PARAMETERS; i++) + { + if (m_iszParameter[i] != NULL_STRING) + { + szParameters[i] = STRING(m_iszParameter[i]); + } + else if (m_iszBackupParameter != NULL_STRING) + { + szParameters[i] = STRING(m_iszBackupParameter); + } + else + { + szParameters[i] = ""; + } + } + + char szFormatted[256] = { 0 }; // Needed so garbage isn't spewed at the beginning + //Q_snprintf(szFormatted, sizeof(szFormatted), szInput, szParameters); + + char szInput[256]; + Q_strncpy(szInput, szStringToFormat, sizeof(szInput)); + + bool inparam = (szInput[0] == '{'); + int curparam = 0; + char *szToken = strtok(szInput, "{"); + while (szToken != NULL) + { + if (inparam) + { + curparam = atoi(szToken); + if (curparam < MAX_LOGIC_FORMAT_PARAMETERS /*&& szParameters[curparam] != NULL*/) //if (curparam < MAX_FORMAT_PARAMETERS) + { + Q_snprintf(szFormatted, sizeof(szFormatted), "%s%s", szFormatted, szParameters[curparam]); + } + else + { + Warning("Warning: Parameter %i out of bounds in \"%s\"\n", curparam, szStringToFormat); + + // This might not be the best way to do this, but + // reaching it is supposed to be the result of a mistake anyway. + m_iszBackupParameter != NULL_STRING ? + Q_snprintf(szFormatted, sizeof(szFormatted), "%s%s", szFormatted, STRING(m_iszBackupParameter)) : + Q_snprintf(szFormatted, sizeof(szFormatted), "%s", szFormatted); + } + + inparam = false; + szToken = strtok(NULL, "{"); + } + else + { + Q_snprintf(szFormatted, sizeof(szFormatted), "%s%s", szFormatted, szToken); + + inparam = true; + szToken = strtok(NULL, "}"); + } + } + + Q_strncpy(szOutput, szFormatted, outputlen); +} + + +//----------------------------------------------------------------------------- +// Purpose: Accesses a keyvalue from a specific entity +// Mostly ported from Half-Laugh. +//----------------------------------------------------------------------------- +class CLogicKeyfieldAccessor : public CLogicalEntity +{ + DECLARE_CLASS(CLogicKeyfieldAccessor, CLogicalEntity); + +protected: + CBaseEntity *GetTarget(CBaseEntity *pCaller, CBaseEntity *pActivator); + + virtual bool TestKey(CBaseEntity *pTarget, const char *szKeyName); + virtual bool SetKeyValue(CBaseEntity *pTarget, const char *szKeyName, const char *szValue); + virtual bool SetKeyValueBits(CBaseEntity *pTarget, const char *szKeyName, int iValue, bool bRemove = false); + + // Inputs + void InputTest(inputdata_t &inputdata); + void InputTestKey(inputdata_t &inputdata); + void InputTestTarget(inputdata_t &inputdata); + + void InputSetKey(inputdata_t &inputdata); + + void InputSetValue(inputdata_t &inputdata); + void InputAddBits(inputdata_t &inputdata); + void InputRemoveBits(inputdata_t &inputdata); + + //bool ReadUnregisteredKeyfields(CBaseEntity *pTarget, const char *szKeyName, variant_t *variant); + + COutputVariant m_OutValue; + COutputEvent m_OnFailed; + + string_t m_iszKey; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_keyfield, CLogicKeyfieldAccessor); + + +BEGIN_DATADESC(CLogicKeyfieldAccessor) + +DEFINE_KEYFIELD( m_iszKey, FIELD_STRING, "keyname" ), + +// Inputs +DEFINE_INPUTFUNC(FIELD_VOID, "Test", InputTest), +DEFINE_INPUTFUNC(FIELD_STRING, "TestKey", InputTestKey), +DEFINE_INPUTFUNC(FIELD_STRING, "TestTarget", InputTestTarget), +DEFINE_INPUTFUNC(FIELD_STRING, "SetKey", InputSetKey), + +DEFINE_INPUTFUNC(FIELD_STRING, "SetValue", InputSetValue), +DEFINE_INPUTFUNC(FIELD_INTEGER, "AddBits", InputAddBits), +DEFINE_INPUTFUNC(FIELD_INTEGER, "RemoveBits", InputRemoveBits), + +DEFINE_OUTPUT( m_OutValue, "OutValue" ), +DEFINE_OUTPUT( m_OnFailed, "OnFailed" ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CBaseEntity *CLogicKeyfieldAccessor::GetTarget(CBaseEntity *pCaller, CBaseEntity *pActivator) +{ + return gEntList.FindEntityByName(NULL, m_target, this, pActivator, pCaller); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicKeyfieldAccessor::TestKey(CBaseEntity *pTarget, const char *szKeyName) +{ + variant_t variant; + if (pTarget->ReadKeyField(szKeyName, &variant) || ReadUnregisteredKeyfields(pTarget, szKeyName, &variant)) + { + m_OutValue.Set(variant, pTarget, this); + return true; + } + else + { + m_OnFailed.FireOutput(pTarget, this); + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicKeyfieldAccessor::SetKeyValue(CBaseEntity *pTarget, const char *szKeyName, const char *szValue) +{ + if (pTarget->KeyValue(szKeyName, szValue)) + { + // We'll still fire OutValue + variant_t variant; + if (!pTarget->ReadKeyField(szKeyName, &variant)) + ReadUnregisteredKeyfields(pTarget, szKeyName, &variant); + + m_OutValue.Set(variant, pTarget, this); + return true; + } + else + { + m_OnFailed.FireOutput(pTarget, this); + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicKeyfieldAccessor::SetKeyValueBits(CBaseEntity *pTarget, const char *szKeyName, int iValue, bool bRemove) +{ + variant_t variant; + if ((pTarget->ReadKeyField(szKeyName, &variant) || ReadUnregisteredKeyfields(pTarget, szKeyName, &variant)) && variant.FieldType() == FIELD_INTEGER) + { + if (bRemove) + variant.SetInt(variant.Int() & ~iValue); + else + variant.SetInt(variant.Int() | iValue); + + pTarget->KeyValue(szKeyName, UTIL_VarArgs("%i", variant.Int())); + + m_OutValue.Set(variant, pTarget, this); + return true; + } + else + { + m_OnFailed.FireOutput(pTarget, this); + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputTest(inputdata_t &inputdata) +{ + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (pTarget && m_iszKey != NULL_STRING) + { + TestKey(pTarget, STRING(m_iszKey)); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputTestKey(inputdata_t &inputdata) +{ + const char *input = inputdata.value.String(); + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (input && pTarget) + { + TestKey(pTarget, input); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputTestTarget(inputdata_t &inputdata) +{ + m_target = inputdata.value.StringID(); + CBaseEntity *pTarget = gEntList.FindEntityByName(NULL, inputdata.value.StringID(), this, inputdata.pCaller, inputdata.pActivator); + if (pTarget && m_iszKey != NULL_STRING) + { + TestKey(pTarget, STRING(m_iszKey)); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputSetKey(inputdata_t &inputdata) +{ + m_iszKey = inputdata.value.StringID(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputSetValue(inputdata_t &inputdata) +{ + const char *input = inputdata.value.String(); + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (input && pTarget) + { + SetKeyValue(pTarget, STRING(m_iszKey), input); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputAddBits(inputdata_t &inputdata) +{ + int input = inputdata.value.Int(); + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (input && pTarget) + { + SetKeyValueBits(pTarget, STRING(m_iszKey), input, false); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicKeyfieldAccessor::InputRemoveBits(inputdata_t &inputdata) +{ + int input = inputdata.value.Int(); + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (input && pTarget) + { + SetKeyValueBits(pTarget, STRING(m_iszKey), input, true); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Clamps the input value between two values +//----------------------------------------------------------------------------- +class CMathClamp : public CLogicalEntity +{ +public: + + DECLARE_CLASS( CMathClamp, CLogicalEntity ); + + // Keys + variant_t m_Max; + variant_t m_Min; + + // Inputs + void InputClampValue( inputdata_t &inputdata ); + + float ClampValue(float input, float min, float max, int *bounds); + void ClampValue(variant_t var, inputdata_t *inputdata); + + // Outputs + COutputVariant m_OutValue; + COutputVariant m_OnBeforeMin; + COutputVariant m_OnBeyondMax; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(math_clamp, CMathClamp); + + +BEGIN_DATADESC( CMathClamp ) + + DEFINE_INPUT( m_Max, FIELD_INPUT, "SetMax" ), + DEFINE_INPUT( m_Min, FIELD_INPUT, "SetMin" ), + + DEFINE_INPUTFUNC( FIELD_INPUT, "ClampValue", InputClampValue ), + + DEFINE_OUTPUT(m_OutValue, "OutValue"), + DEFINE_OUTPUT(m_OnBeforeMin, "OnBeforeMin"), + DEFINE_OUTPUT(m_OnBeyondMax, "OnBeyondMax"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathClamp::InputClampValue( inputdata_t &inputdata ) +{ + ClampValue(inputdata.value, &inputdata); +} + +//----------------------------------------------------------------------------- +// "bounds" returns 1 if the number was less than min, 2 if more than max. Must not be NULL +//----------------------------------------------------------------------------- +inline float CMathClamp::ClampValue(float input, float min, float max, int *bounds) +{ + if ( max < min ) + { + Warning("WARNING: Max value (%f) less than min value (%f) in %s!\n", max, min, GetDebugName()); + return max; + } + else if( input < min ) + { + *bounds = 1; + return min; + } + else if( input > max ) + { + *bounds = 2; + return max; + } + else + return input; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathClamp::ClampValue(variant_t var, inputdata_t *inputdata) +{ + // Don't convert up here in case of invalid type + + int nBounds = 0; + + switch (var.FieldType()) + { + case FIELD_FLOAT: + { + m_Max.Convert(var.FieldType()); + m_Min.Convert(var.FieldType()); + + var.SetFloat(ClampValue(var.Float(), m_Max.Float(), m_Min.Float(), &nBounds)); + } break; + case FIELD_INTEGER: + { + m_Max.Convert(var.FieldType()); + m_Min.Convert(var.FieldType()); + + var.SetInt(ClampValue(var.Int(), m_Max.Int(), m_Min.Int(), &nBounds)); + } break; + case FIELD_VECTOR: + { + m_Max.Convert(var.FieldType()); + m_Min.Convert(var.FieldType()); + + Vector min; + Vector max; + m_Min.Vector3D(min); + m_Max.Vector3D(max); + + Vector vec; + var.Vector3D(vec); + + vec.x = ClampValue(vec.x, min.x, max.x, &nBounds); + vec.y = ClampValue(vec.y, min.y, max.y, &nBounds); + vec.z = ClampValue(vec.z, min.z, max.z, &nBounds); + + var.SetVector3D(vec); + } break; + default: + { + Warning("Error: Unsupported value %s in math_clamp %s\n", var.GetDebug(), STRING(GetEntityName())); + return; + } + } + + if (inputdata) + { + m_OutValue.Set(var, inputdata->pActivator, this); + if (nBounds == 1) + m_OnBeforeMin.Set(var, inputdata->pActivator, this); + else if (nBounds == 2) + m_OnBeyondMax.Set(var, inputdata->pActivator, this); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Bits calculations. +//----------------------------------------------------------------------------- +class CMathBits : public CLogicalEntity +{ + DECLARE_CLASS( CMathBits, CLogicalEntity ); +private: + + bool m_bDisabled; + + bool KeyValue(const char *szKeyName, const char *szValue); + + void UpdateOutValue(CBaseEntity *pActivator, int iNewValue); + + int DrawDebugTextOverlays(void); + + // Inputs + void InputAdd( inputdata_t &inputdata ); + void InputSubtract( inputdata_t &inputdata ); + void InputShiftLeft( inputdata_t &inputdata ); + void InputShiftRight( inputdata_t &inputdata ); + void InputApplyAnd( inputdata_t &inputdata ); + void InputApplyOr( inputdata_t &inputdata ); + void InputSetValue( inputdata_t &inputdata ); + void InputSetValueNoFire( inputdata_t &inputdata ); + void InputGetValue( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputContainsBits( inputdata_t &inputdata ); + void InputContainsAllBits( inputdata_t &inputdata ); + + // Outputs + COutputInt m_OutValue; + COutputInt m_OnGetValue; + COutputEvent m_OnTrue; + COutputEvent m_OnFalse; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(math_bits, CMathBits); + + +BEGIN_DATADESC( CMathBits ) + + // Keys + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_INTEGER, "Add", InputAdd), + DEFINE_INPUTFUNC(FIELD_INTEGER, "Subtract", InputSubtract), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ShiftLeft", InputShiftLeft), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ShiftRight", InputShiftRight), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ApplyAnd", InputApplyAnd), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ApplyOr", InputApplyOr), + DEFINE_INPUTFUNC(FIELD_INTEGER, "SetValue", InputSetValue), + DEFINE_INPUTFUNC(FIELD_INTEGER, "SetValueNoFire", InputSetValueNoFire), + DEFINE_INPUTFUNC(FIELD_VOID, "GetValue", InputGetValue), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ContainsBits", InputContainsBits), + DEFINE_INPUTFUNC(FIELD_INTEGER, "ContainsAllBits", InputContainsAllBits), + + // Outputs + DEFINE_OUTPUT(m_OutValue, "OutValue"), + DEFINE_OUTPUT(m_OnGetValue, "OnGetValue"), + DEFINE_OUTPUT(m_OnTrue, "OnTrue"), + DEFINE_OUTPUT(m_OnFalse, "OnFalse"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CMathBits::KeyValue(const char *szKeyName, const char *szValue) +{ + // + // Set the initial value of the counter. + // + if (!stricmp(szKeyName, "startvalue")) + { + m_OutValue.Init(atoi(szValue)); + return(true); + } + + return(BaseClass::KeyValue(szKeyName, szValue)); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for adding to the accumulator value. +// Input : Bit value to add. +//----------------------------------------------------------------------------- +void CMathBits::InputAdd( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring ADD because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() | inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for subtracting from the current value. +// Input : Bit value to subtract. +//----------------------------------------------------------------------------- +void CMathBits::InputSubtract( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring SUBTRACT because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() & ~inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for shifting from the current value. +// Input : Bit value to shift by. +//----------------------------------------------------------------------------- +void CMathBits::InputShiftLeft( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring SHIFTLEFT because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() << inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for shifting from the current value. +// Input : Bit value to shift by. +//----------------------------------------------------------------------------- +void CMathBits::InputShiftRight( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring SHIFTRIGHT because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() >> inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for applying & to the current value. +// Input : Bit value to shift by. +//----------------------------------------------------------------------------- +void CMathBits::InputApplyAnd( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring APPLYAND because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() & inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for applying | to the current value. +// Input : Bit value to shift by. +//----------------------------------------------------------------------------- +void CMathBits::InputApplyOr( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring APPLYOR because it is disabled\n", GetDebugName() ); + return; + } + + int iNewValue = m_OutValue.Get() | inputdata.value.Int(); + UpdateOutValue( inputdata.pActivator, iNewValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for updating the value. +// Input : Bit value to set. +//----------------------------------------------------------------------------- +void CMathBits::InputSetValue( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring SETVALUE because it is disabled\n", GetDebugName() ); + return; + } + + UpdateOutValue( inputdata.pActivator, inputdata.value.Int() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for updating the value. +// Input : Bit value to set. +//----------------------------------------------------------------------------- +void CMathBits::InputSetValueNoFire( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring SETVALUENOFIRE because it is disabled\n", GetDebugName() ); + return; + } + + m_OutValue.Init( inputdata.value.Int() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathBits::InputGetValue( inputdata_t &inputdata ) +{ + int iOutValue = m_OutValue.Get(); + m_OnGetValue.Set( iOutValue, inputdata.pActivator, inputdata.pCaller ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for checking whether a bit is stored. +// Input : Bit value to check. +//----------------------------------------------------------------------------- +void CMathBits::InputContainsBits( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring CONTAINS BITS because it is disabled\n", GetDebugName() ); + return; + } + + if (m_OutValue.Get() & inputdata.value.Int()) + m_OnTrue.FireOutput(inputdata.pActivator, this); + else + m_OnFalse.FireOutput(inputdata.pActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for checking whether all of the specified bits are stored. +// Input : Bit value to check. +//----------------------------------------------------------------------------- +void CMathBits::InputContainsAllBits( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Bits %s ignoring CONTAINS ALL BITS because it is disabled\n", GetDebugName() ); + return; + } + + bool bResult = false; + int iInput = inputdata.value.Int(); + int iValue = m_OutValue.Get(); + + for (int i = 1, n = 0; n < 32; (i <<= 1), n++) + { + DevMsg("%i\n", i); + if (iInput & i) + { + if (!(iValue & i)) + { + DevMsg("%i does not go into %i\n", i, iValue); + bResult = false; + break; + } + else if (!bResult) + { + bResult = true; + } + } + } + + if (bResult) + m_OnTrue.FireOutput(inputdata.pActivator, this); + else + m_OnFalse.FireOutput(inputdata.pActivator, this); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathBits::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathBits::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the value to the new value, firing the output value. +// Input : iNewValue - Value to set. +//----------------------------------------------------------------------------- +void CMathBits::UpdateOutValue(CBaseEntity *pActivator, int iNewValue) +{ + m_OutValue.Set(iNewValue, pActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Input : +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CMathBits::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + Q_snprintf(tempstr,sizeof(tempstr),"current value: %i", m_OutValue.Get()); + EntityText(text_offset,tempstr,0); + text_offset++; + + if( m_bDisabled ) + { + Q_snprintf(tempstr,sizeof(tempstr),"*DISABLED*"); + } + else + { + Q_snprintf(tempstr,sizeof(tempstr),"Enabled."); + } + EntityText(text_offset,tempstr,0); + text_offset++; + + } + return text_offset; +} + +// These spawnflags control math_vector dimensions. +#define SF_MATH_VECTOR_DISABLE_X ( 1 << 0 ) +#define SF_MATH_VECTOR_DISABLE_Y ( 1 << 1 ) +#define SF_MATH_VECTOR_DISABLE_Z ( 1 << 2 ) + +//----------------------------------------------------------------------------- +// Purpose: Vector calculations. +//----------------------------------------------------------------------------- +class CMathVector : public CLogicalEntity +{ + DECLARE_CLASS( CMathVector, CLogicalEntity ); +private: + + bool m_bDisabled; + + bool KeyValue(const char *szKeyName, const char *szValue); + bool KeyValue( const char *szKeyName, const Vector &vecValue ); + + void UpdateOutValue(CBaseEntity *pActivator, Vector vecNewValue); + + int DrawDebugTextOverlays(void); + + // Inputs + void InputAdd( inputdata_t &inputdata ); + void InputSubtract( inputdata_t &inputdata ); + void InputDivide( inputdata_t &inputdata ); + void InputMultiply( inputdata_t &inputdata ); + void InputSetValue( inputdata_t &inputdata ); + void InputSetValueNoFire( inputdata_t &inputdata ); + void InputGetValue( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + + void PointAt( Vector &origin, Vector &target, Vector &out ); + void InputPointAtLocation( inputdata_t &inputdata ); + void InputPointAtEntity( inputdata_t &inputdata ); + + void InputNormalize( inputdata_t &inputdata ); + void InputNormalizeAngles( inputdata_t &inputdata ); + void InputVectorAngles( inputdata_t &inputdata ); + void InputAngleVectorForward( inputdata_t &inputdata ); + void InputAngleVectorRight( inputdata_t &inputdata ); + void InputAngleVectorUp( inputdata_t &inputdata ); + + void SetCoordinate(float value, char coord, CBaseEntity *pActivator); + void GetCoordinate(char coord, CBaseEntity *pActivator); + void AddCoordinate(float value, char coord, CBaseEntity *pActivator); + void SubtractCoordinate(float value, char coord, CBaseEntity *pActivator); + + void InputSetX( inputdata_t &inputdata ) { SetCoordinate(inputdata.value.Float(), 'X', inputdata.pActivator); } + void InputSetY( inputdata_t &inputdata ) { SetCoordinate(inputdata.value.Float(), 'Y', inputdata.pActivator); } + void InputSetZ( inputdata_t &inputdata ) { SetCoordinate(inputdata.value.Float(), 'Z', inputdata.pActivator); } + void InputGetX( inputdata_t &inputdata ) { GetCoordinate('X', inputdata.pActivator); } + void InputGetY( inputdata_t &inputdata ) { GetCoordinate('Y', inputdata.pActivator); } + void InputGetZ( inputdata_t &inputdata ) { GetCoordinate('Z', inputdata.pActivator); } + void InputAddX( inputdata_t &inputdata ) { AddCoordinate(inputdata.value.Float(), 'X', inputdata.pActivator); } + void InputAddY( inputdata_t &inputdata ) { AddCoordinate(inputdata.value.Float(), 'Y', inputdata.pActivator); } + void InputAddZ( inputdata_t &inputdata ) { AddCoordinate(inputdata.value.Float(), 'Z', inputdata.pActivator); } + void InputSubtractX( inputdata_t &inputdata ) { SubtractCoordinate(inputdata.value.Float(), 'X', inputdata.pActivator); } + void InputSubtractY( inputdata_t &inputdata ) { SubtractCoordinate(inputdata.value.Float(), 'Y', inputdata.pActivator); } + void InputSubtractZ( inputdata_t &inputdata ) { SubtractCoordinate(inputdata.value.Float(), 'Z', inputdata.pActivator); } + + // Outputs + COutputVector m_OutValue; + COutputFloat m_OutX; + COutputFloat m_OutY; + COutputFloat m_OutZ; + + COutputVector m_OnGetValue; + COutputFloat m_OnGetX; + COutputFloat m_OnGetY; + COutputFloat m_OnGetZ; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(math_vector, CMathVector); + + +BEGIN_DATADESC( CMathVector ) + + // Keys + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VECTOR, "Add", InputAdd), + DEFINE_INPUTFUNC(FIELD_VECTOR, "Subtract", InputSubtract), + DEFINE_INPUTFUNC(FIELD_VECTOR, "Divide", InputDivide), + DEFINE_INPUTFUNC(FIELD_VECTOR, "Multiply", InputMultiply), + DEFINE_INPUTFUNC(FIELD_VECTOR, "SetValue", InputSetValue), + DEFINE_INPUTFUNC(FIELD_VECTOR, "SetValueNoFire", InputSetValueNoFire), + DEFINE_INPUTFUNC(FIELD_VOID, "GetValue", InputGetValue), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_INPUTFUNC( FIELD_VECTOR, "PointAtLocation", InputPointAtLocation ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "PointAtEntity", InputPointAtEntity ), + + DEFINE_INPUTFUNC(FIELD_VOID, "Normalize", InputNormalize), + DEFINE_INPUTFUNC(FIELD_VOID, "NormalizeAngles", InputNormalizeAngles), + DEFINE_INPUTFUNC(FIELD_VOID, "VectorAngles", InputVectorAngles), + DEFINE_INPUTFUNC(FIELD_VOID, "AngleVectorForward", InputAngleVectorForward), + DEFINE_INPUTFUNC(FIELD_VOID, "AngleVectorRight", InputAngleVectorRight), + DEFINE_INPUTFUNC(FIELD_VOID, "AngleVectorUp", InputAngleVectorUp), + + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetX", InputSetX), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetY", InputSetY), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetZ", InputSetZ), + DEFINE_INPUTFUNC(FIELD_VOID, "GetX", InputGetX), + DEFINE_INPUTFUNC(FIELD_VOID, "GetY", InputGetY), + DEFINE_INPUTFUNC(FIELD_VOID, "GetZ", InputGetZ), + DEFINE_INPUTFUNC(FIELD_FLOAT, "AddX", InputAddX), + DEFINE_INPUTFUNC(FIELD_FLOAT, "AddY", InputAddY), + DEFINE_INPUTFUNC(FIELD_FLOAT, "AddZ", InputAddZ), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SubtractX", InputSubtractX), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SubtractY", InputSubtractY), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SubtractZ", InputSubtractZ), + + // Outputs + DEFINE_OUTPUT(m_OutValue, "OutValue"), + DEFINE_OUTPUT(m_OutX, "OutX"), + DEFINE_OUTPUT(m_OutY, "OutY"), + DEFINE_OUTPUT(m_OutZ, "OutZ"), + + DEFINE_OUTPUT(m_OnGetValue, "OnGetValue"), + DEFINE_OUTPUT(m_OnGetX, "OnGetX"), + DEFINE_OUTPUT(m_OnGetY, "OnGetY"), + DEFINE_OUTPUT(m_OnGetZ, "OnGetZ"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CMathVector::KeyValue(const char *szKeyName, const char *szValue) +{ + // + // Set the initial value of the counter. + // + if (!stricmp(szKeyName, "startvalue")) + { + Vector vec; + UTIL_StringToVector( vec.Base(), szValue ); + m_OutValue.Init(vec); + return(true); + } + + return(BaseClass::KeyValue(szKeyName, szValue)); +} + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CMathVector::KeyValue( const char *szKeyName, const Vector &vecValue ) +{ + // + // Set the initial value of the counter. + // + if (!stricmp(szKeyName, "startvalue")) + { + m_OutValue.Init(vecValue); + return true; + } + + // So, CLogicalEntity descends from CBaseEntity... + // Yup. + // ...and CBaseEntity has a version of KeyValue that takes vectors. + // Yup. + // Since it's virtual, I could easily override it just like I could with a KeyValue that takes strings, right? + // Sounds right to me. + // So let me override it. + // *No suitable function exists* + return CBaseEntity::KeyValue(szKeyName, vecValue); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for adding to the accumulator value. +// Input : Bit value to add. +//----------------------------------------------------------------------------- +void CMathVector::InputAdd( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring ADD because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + Vector cur; + m_OutValue.Get(cur); + UpdateOutValue( inputdata.pActivator, cur + vec ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for subtracting from the current value. +// Input : Bit value to subtract. +//----------------------------------------------------------------------------- +void CMathVector::InputSubtract( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SUBTRACT because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + Vector cur; + m_OutValue.Get(cur); + UpdateOutValue( inputdata.pActivator, cur - vec ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for multiplying the current value. +// Input : Float value to multiply the value by. +//----------------------------------------------------------------------------- +void CMathVector::InputDivide( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring DIVIDE because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + Vector cur; + m_OutValue.Get(cur); + + if (vec.x != 0) + cur.x /= vec.x; + if (vec.y != 0) + cur.y /= vec.y; + if (vec.z != 0) + cur.z /= vec.z; + + UpdateOutValue( inputdata.pActivator, cur ); + + //if (vec.x != 0 && vec.y != 0 && vec.z != 0) + //{ + // UpdateOutValue( inputdata.pActivator, cur / vec ); + //} + //else + //{ + // DevMsg( 1, "LEVEL DESIGN ERROR: Divide by zero in math_vector\n" ); + // UpdateOutValue( inputdata.pActivator, cur ); + //} +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for multiplying the current value. +// Input : Float value to multiply the value by. +//----------------------------------------------------------------------------- +void CMathVector::InputMultiply( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring MULTIPLY because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + Vector cur; + m_OutValue.Get(cur); + UpdateOutValue( inputdata.pActivator, cur * vec ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for updating the value. +// Input : Bit value to set. +//----------------------------------------------------------------------------- +void CMathVector::InputSetValue( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SETVALUE because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + UpdateOutValue( inputdata.pActivator, vec ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for updating the value. +// Input : Bit value to set. +//----------------------------------------------------------------------------- +void CMathVector::InputSetValueNoFire( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SETVALUENOFIRE because it is disabled\n", GetDebugName() ); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + m_OutValue.Init( vec ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputGetValue( inputdata_t &inputdata ) +{ + Vector cur; + m_OutValue.Get(cur); + m_OnGetValue.Set( cur, inputdata.pActivator, inputdata.pCaller ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::PointAt( Vector &origin, Vector &target, Vector &out ) +{ + out = origin - target; + VectorNormalize( out ); + + QAngle ang; + VectorAngles( out, ang ); + + out[0] = ang[0]; + out[1] = ang[1]; + out[2] = ang[2]; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputPointAtLocation( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring POINTATLOCATION because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + + Vector location; + inputdata.value.Vector3D( location ); + + PointAt( cur, location, cur ); + + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputPointAtEntity( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring POINTATENTITY because it is disabled\n", GetDebugName() ); + return; + } + + if (!inputdata.value.Entity()) + { + Warning("%s received no entity to point at\n", GetDebugName()); + return; + } + + Vector cur; + m_OutValue.Get(cur); + + Vector location = inputdata.value.Entity()->GetAbsOrigin(); + + PointAt( cur, location, cur ); + + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputNormalize( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring NORMALIZE because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + VectorNormalize(cur); + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputNormalizeAngles( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring NORMALIZEANGLES because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + cur.x = AngleNormalize(cur.x); + cur.y = AngleNormalize(cur.y); + cur.z = AngleNormalize(cur.z); + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputVectorAngles( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring VECTORANGLES because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + QAngle ang; + m_OutValue.Get(cur); + VectorAngles(cur, ang); + UpdateOutValue( inputdata.pActivator, Vector(ang.x, ang.y, ang.z) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputAngleVectorForward( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring ANGLEVECTORFORWARD because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + AngleVectors(QAngle(cur.x, cur.y, cur.z), &cur); + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputAngleVectorRight( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring ANGLEVECTORRIGHT because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + AngleVectors(QAngle(cur.x, cur.y, cur.z), NULL, &cur, NULL); + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::InputAngleVectorUp( inputdata_t &inputdata ) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring ANGLEVECTORUP because it is disabled\n", GetDebugName() ); + return; + } + + Vector cur; + m_OutValue.Get(cur); + AngleVectors(QAngle(cur.x, cur.y, cur.z), NULL, NULL, &cur); + UpdateOutValue( inputdata.pActivator, cur ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::SetCoordinate(float value, char coord, CBaseEntity *pActivator) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SET%c because it is disabled\n", GetDebugName(), coord ); + return; + } + + Vector vec; + m_OutValue.Get(vec); + switch (coord) + { + case 'X': vec.x = value; break; + case 'Y': vec.y = value; break; + case 'Z': vec.z = value; break; + } + UpdateOutValue( pActivator, vec ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::GetCoordinate(char coord, CBaseEntity *pActivator) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SET%c because it is disabled\n", GetDebugName(), coord ); + return; + } + + Vector vec; + m_OutValue.Get(vec); + switch (coord) + { + case 'X': m_OnGetX.Set(vec.x, pActivator, this); break; + case 'Y': m_OnGetY.Set(vec.y, pActivator, this); break; + case 'Z': m_OnGetZ.Set(vec.z, pActivator, this); break; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::AddCoordinate(float value, char coord, CBaseEntity *pActivator) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring ADD%c because it is disabled\n", GetDebugName(), coord ); + return; + } + + Vector vec; + m_OutValue.Get(vec); + switch (coord) + { + case 'X': vec.x += value; break; + case 'Y': vec.y += value; break; + case 'Z': vec.z += value; break; + } + UpdateOutValue( pActivator, vec ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathVector::SubtractCoordinate(float value, char coord, CBaseEntity *pActivator) +{ + if( m_bDisabled ) + { + DevMsg("Math Vector %s ignoring SUBTRACT%c because it is disabled\n", GetDebugName(), coord ); + return; + } + + Vector vec; + m_OutValue.Get(vec); + switch (coord) + { + case 'X': vec.x += value; break; + case 'Y': vec.y += value; break; + case 'Z': vec.z += value; break; + } + UpdateOutValue( pActivator, vec ); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the value to the new value, firing the output value. +// Input : vecNewValue - Value to set. +//----------------------------------------------------------------------------- +void CMathVector::UpdateOutValue(CBaseEntity *pActivator, Vector vecNewValue) +{ + if (HasSpawnFlags( SF_MATH_VECTOR_DISABLE_X )) + vecNewValue.x = 0; + if (HasSpawnFlags( SF_MATH_VECTOR_DISABLE_Y )) + vecNewValue.y = 0; + if (HasSpawnFlags( SF_MATH_VECTOR_DISABLE_Z )) + vecNewValue.z = 0; + + m_OutValue.Set(vecNewValue, pActivator, this); + + m_OutX.Set(vecNewValue.x, pActivator, this); + m_OutY.Set(vecNewValue.y, pActivator, this); + m_OutZ.Set(vecNewValue.z, pActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Input : +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CMathVector::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + Vector cur; + m_OutValue.Get(cur); + + Q_snprintf(tempstr, sizeof(tempstr), "current value: [%g %g %g]", (double)cur[0], (double)cur[1], (double)cur[2]); + EntityText(text_offset,tempstr,0); + text_offset++; + + if( m_bDisabled ) + { + Q_snprintf(tempstr,sizeof(tempstr),"*DISABLED*"); + } + else + { + Q_snprintf(tempstr,sizeof(tempstr),"Enabled."); + } + EntityText(text_offset,tempstr,0); + text_offset++; + + } + return text_offset; +} + +//----------------------------------------------------------------------------- +// Purpose: Accesses/modifies any field in a datadesc based on its internal name. +// Oh boy. +//----------------------------------------------------------------------------- +class CLogicFieldAccessor : public CLogicKeyfieldAccessor +{ + DECLARE_CLASS(CLogicFieldAccessor, CLogicKeyfieldAccessor); + +private: + bool TestKey(CBaseEntity *pTarget, const char *szKeyName); + bool SetKeyValue(CBaseEntity *pTarget, const char *szKeyName, const char *szValue); + bool SetKeyValueBits(CBaseEntity *pTarget, const char *szKeyName, int iValue, bool bRemove = false); + + //DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_datadesc_accessor, CLogicFieldAccessor); + + +//BEGIN_DATADESC(CLogicFieldAccessor) + +//END_DATADESC() + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicFieldAccessor::TestKey(CBaseEntity *pTarget, const char *szKeyName) +{ + variant_t var; + for ( datamap_t *dmap = pTarget->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) ) + { + DevMsg("Field Name: %s,\n", dmap->dataDesc[i].fieldName); + if ( Matcher_NamesMatch(szKeyName, dmap->dataDesc[i].fieldName) ) + { + fieldtype_t fieldtype = dmap->dataDesc[i].fieldType; + switch (fieldtype) + { + case FIELD_TIME: fieldtype = FIELD_FLOAT; break; + case FIELD_MODELNAME: fieldtype = FIELD_STRING; break; + case FIELD_SOUNDNAME: fieldtype = FIELD_STRING; break; + // There's definitely more of them. Add when demand becomes prevalent + } + + var.Set( fieldtype, ((char*)pTarget) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ] ); + DevMsg("FIELD TYPE: %i\n", fieldtype); + m_OutValue.Set(var, pTarget, this); + return true; + } + } + } + } + + m_OnFailed.FireOutput(pTarget, this); + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicFieldAccessor::SetKeyValue(CBaseEntity *pTarget, const char *szKeyName, const char *szValue) +{ + for ( datamap_t *dmap = pTarget->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) ) + { + DevMsg("Field Name: %s,\n", dmap->dataDesc[i].fieldName); + if ( Matcher_NamesMatch(szKeyName, dmap->dataDesc[i].fieldName) ) + { + // Copied from ::ParseKeyvalue... + fieldtype_t fieldtype = FIELD_VOID; + typedescription_t *pField = &dmap->dataDesc[i]; + char *data = Datadesc_SetFieldString( szValue, pTarget, pField, &fieldtype ); + + if (!data) + { + Warning( "%s cannot set field of type %i.\n", GetDebugName(), dmap->dataDesc[i].fieldType ); + } + else if (fieldtype != FIELD_VOID) + { + variant_t var; + var.Set(fieldtype, data); + m_OutValue.Set(var, pTarget, this); + return true; + } + } + } + } + } + + m_OnFailed.FireOutput(pTarget, this); + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicFieldAccessor::SetKeyValueBits(CBaseEntity *pTarget, const char *szKeyName, int iValue, bool bRemove) +{ + variant_t var; + for ( datamap_t *dmap = pTarget->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) ) + { + DevMsg("Field Name: %s,\n", dmap->dataDesc[i].fieldName); + if ( Matcher_NamesMatch(szKeyName, dmap->dataDesc[i].fieldName) ) + { + fieldtype_t fieldtype = dmap->dataDesc[i].fieldType; + if (fieldtype != FIELD_INTEGER) + break; + + var.Set( fieldtype, ((char*)pTarget) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ] ); + + if (bRemove) + var.SetInt(var.Int() & ~iValue); + else + var.SetInt(var.Int() | iValue); + + DevMsg("FIELD TYPE: %i\n", fieldtype); + m_OutValue.Set(var, pTarget, this); + return true; + } + } + } + } + + m_OnFailed.FireOutput(pTarget, this); + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Passes global variables, like curtime. +//----------------------------------------------------------------------------- +class CGameGlobalVars : public CLogicalEntity +{ + DECLARE_CLASS( CGameGlobalVars, CLogicalEntity ); +private: + + // Inputs + void InputGetCurtime( inputdata_t &inputdata ) { m_OutCurtime.Set(gpGlobals->curtime, inputdata.pActivator, this); } + void InputGetFrameCount( inputdata_t &inputdata ) { m_OutFrameCount.Set(gpGlobals->framecount, inputdata.pActivator, this); } + void InputGetFrametime( inputdata_t &inputdata ) { m_OutFrametime.Set(gpGlobals->frametime, inputdata.pActivator, this); } + void InputGetTickCount( inputdata_t &inputdata ) { m_OutTickCount.Set(gpGlobals->tickcount, inputdata.pActivator, this); } + void InputGetIntervalPerTick( inputdata_t &inputdata ) { m_OutIntervalPerTick.Set(gpGlobals->interval_per_tick, inputdata.pActivator, this); } + + // Outputs + COutputFloat m_OutCurtime; + COutputInt m_OutFrameCount; + COutputFloat m_OutFrametime; + COutputInt m_OutTickCount; + COutputInt m_OutIntervalPerTick; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(game_globalvars, CGameGlobalVars); + + +BEGIN_DATADESC( CGameGlobalVars ) + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "GetCurtime", InputGetCurtime ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetFrameCount", InputGetFrameCount ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetFrametime", InputGetFrametime ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetTickCount", InputGetTickCount ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetIntervalPerTick", InputGetIntervalPerTick ), + + // Outputs + DEFINE_OUTPUT(m_OutCurtime, "OutCurtime"), + DEFINE_OUTPUT(m_OutFrameCount, "OutFrameCount"), + DEFINE_OUTPUT(m_OutFrametime, "OutFrametime"), + DEFINE_OUTPUT(m_OutTickCount, "OutTickCount"), + DEFINE_OUTPUT(m_OutIntervalPerTick, "OutIntervalPerTick"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//void CGameGlobalVars::InputGetCurtime( inputdata_t &inputdata ) +//{ +// m_OutCurtime.Set(gpGlobals->curtime, inputdata.pActivator, this); +//} + + +#define MathModCalc(val1, val2, op) \ + switch (op) \ + { \ + case '+': val1 += val2; break; \ + case '-': val1 -= val2; break; \ + case '*': val1 *= val2; break; \ + case '/': val1 /= val2; break; \ + } \ + +//----------------------------------------------------------------------------- +// Purpose: Modifies values on the fly. +//----------------------------------------------------------------------------- +class CMathMod : public CLogicalEntity +{ + DECLARE_CLASS( CMathMod, CLogicalEntity ); +private: + + bool KeyValue(const char *szKeyName, const char *szValue); + + // Inputs + void InputSetMod( inputdata_t &inputdata ); + void InputSetOperator( inputdata_t &inputdata ); + + void InputModInt( inputdata_t &inputdata ); + void InputModFloat( inputdata_t &inputdata ); + void InputModVector( inputdata_t &inputdata ); + + // Outputs + COutputInt m_OutInt; + COutputFloat m_OutFloat; + COutputVector m_OutVector; + + int m_Operator; + + variant_t m_Mod; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(math_mod, CMathMod); + + +BEGIN_DATADESC( CMathMod ) + + DEFINE_KEYFIELD( m_Operator, FIELD_INTEGER, "SetOperator" ), + + DEFINE_VARIANT( m_Mod ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_INPUT, "SetMod", InputSetMod ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOperator", InputSetOperator ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "ModInt", InputModInt ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "ModFloat", InputModFloat ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "ModVector", InputModVector ), + + // Outputs + DEFINE_OUTPUT(m_OutInt, "OutInt"), + DEFINE_OUTPUT(m_OutFloat, "OutFloat"), + DEFINE_OUTPUT(m_OutVector, "OutVector"), + +END_DATADESC() + //----------------------------------------------------------------------------- -void CLogicBranch::InputToggleTest( inputdata_t &inputdata ) +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CMathMod::KeyValue(const char *szKeyName, const char *szValue) { - UpdateValue( !m_bInValue, inputdata.pActivator, LOGIC_BRANCH_FIRE ); + if (!stricmp(szKeyName, "startvalue")) + { + // It converts later anyway + m_Mod.SetString(AllocPooledString(szValue)); + return true; + } + + return BaseClass::KeyValue(szKeyName, szValue); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathMod::InputSetMod( inputdata_t &inputdata ) +{ + m_Mod = inputdata.value; + //if (inputdata.value.FieldType() == FIELD_STRING) + // m_Mod = Variant_Parse(inputdata.value.String()); + //else + // m_Mod = inputdata.value; +} //----------------------------------------------------------------------------- -// Purpose: Input handler for forcing a test of the last input value. //----------------------------------------------------------------------------- -void CLogicBranch::InputTest( inputdata_t &inputdata ) +void CMathMod::InputSetOperator( inputdata_t &inputdata ) { - UpdateValue( m_bInValue, inputdata.pActivator, LOGIC_BRANCH_FIRE ); + m_Operator = inputdata.value.String()[0]; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathMod::InputModInt( inputdata_t &inputdata ) +{ + m_Mod.Convert(FIELD_INTEGER); + + DevMsg("Operator is %c you see\n", m_Operator); + + int out = inputdata.value.Int(); + MathModCalc(out, m_Mod.Int(), m_Operator); + + m_OutInt.Set( out, inputdata.pActivator, this ); +} //----------------------------------------------------------------------------- -// Purpose: Tests the last input value, firing the appropriate output based on -// the test result. -// Input : bInValue - //----------------------------------------------------------------------------- -void CLogicBranch::UpdateValue( bool bNewValue, CBaseEntity *pActivator, LogicBranchFire_t eFire ) +void CMathMod::InputModFloat( inputdata_t &inputdata ) { - if ( m_bInValue != bNewValue ) + m_Mod.Convert(FIELD_FLOAT); + + float out = inputdata.value.Float(); + MathModCalc(out, m_Mod.Float(), m_Operator); + + m_OutFloat.Set( out, inputdata.pActivator, this ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathMod::InputModVector( inputdata_t &inputdata ) +{ + m_Mod.Convert(FIELD_VECTOR); + + Vector out; + inputdata.value.Vector3D(out); + Vector mod; + m_Mod.Vector3D(mod); + MathModCalc(out, mod, m_Operator); + + m_OutVector.Set( out, inputdata.pActivator, this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Gets an entity's model information. +//----------------------------------------------------------------------------- +class CLogicModelInfo : public CLogicalEntity +{ + DECLARE_CLASS( CLogicModelInfo, CLogicalEntity ); +private: + + CBaseAnimating *GetTarget(inputdata_t &inputdata); + int GetPoseParameterIndex(CBaseAnimating *pTarget); + + // Inputs + //void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); m_hTarget = NULL; } + void InputGetNumSkins( inputdata_t &inputdata ); + void InputLookupSequence( inputdata_t &inputdata ); + void InputLookupActivity( inputdata_t &inputdata ); + + void InputSetPoseParameterName( inputdata_t &inputdata ); + void InputSetPoseParameterValue( inputdata_t &inputdata ); + void InputGetPoseParameter( inputdata_t &inputdata ); + + // Outputs + COutputInt m_OutNumSkins; + COutputInt m_OnHasSequence; + COutputEvent m_OnLacksSequence; + + COutputFloat m_OutPoseParameterValue; + + // KeyValues + + string_t m_iszPoseParameterName; + int m_iPoseParameterIndex = -1; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_modelinfo, CLogicModelInfo); + + +BEGIN_DATADESC( CLogicModelInfo ) + + DEFINE_KEYFIELD( m_iszPoseParameterName, FIELD_STRING, "PoseParameterName" ), + DEFINE_FIELD( m_iPoseParameterIndex, FIELD_INTEGER ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "GetNumSkins", InputGetNumSkins ), + DEFINE_INPUTFUNC( FIELD_STRING, "LookupSequence", InputLookupSequence ), + DEFINE_INPUTFUNC( FIELD_STRING, "LookupActivity", InputLookupActivity ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetPoseParameterName", InputSetPoseParameterName ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPoseParameterValue", InputSetPoseParameterValue ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetPoseParameter", InputGetPoseParameter ), + + // Outputs + DEFINE_OUTPUT(m_OutNumSkins, "OutNumSkins"), + DEFINE_OUTPUT(m_OnHasSequence, "OnHasSequence"), + DEFINE_OUTPUT(m_OnLacksSequence, "OnLacksSequence"), + DEFINE_OUTPUT(m_OutPoseParameterValue, "OutPoseParameterValue"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline CBaseAnimating *CLogicModelInfo::GetTarget(inputdata_t &inputdata) +{ + CBaseEntity *pEntity = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + if (!pEntity || !pEntity->GetBaseAnimating()) + return NULL; + return pEntity->GetBaseAnimating(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CLogicModelInfo::GetPoseParameterIndex(CBaseAnimating *pTarget) +{ + if (m_iPoseParameterIndex == -1) + m_iPoseParameterIndex = pTarget->LookupPoseParameter(STRING(m_iszPoseParameterName)); + return m_iPoseParameterIndex; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputGetNumSkins( inputdata_t &inputdata ) +{ + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) { - m_bInValue = bNewValue; + m_OutNumSkins.Set(pAnimating->GetModelPtr()->numskinfamilies(), pAnimating, this); + } +} - for ( int i = 0; i < m_Listeners.Count(); i++ ) +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputLookupSequence( inputdata_t &inputdata ) +{ + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) + { + int index = pAnimating->LookupSequence(inputdata.value.String()); + + if (index != ACT_INVALID) + m_OnHasSequence.Set(index, pAnimating, this); + else + m_OnLacksSequence.FireOutput(pAnimating, this); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputLookupActivity( inputdata_t &inputdata ) +{ + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) + { + int iActivity = ActivityList_IndexForName(inputdata.value.String()); + if (iActivity == -1) { - CBaseEntity *pEntity = m_Listeners.Element( i ).Get(); - if ( pEntity ) + // Check if it's a raw activity ID + iActivity = atoi(inputdata.value.String()); + if (!ActivityList_NameForIndex(iActivity)) { - g_EventQueue.AddEvent( pEntity, "_OnLogicBranchChanged", 0, this, this ); + Msg("%s received invalid LookupActivity %s\n", GetDebugName(), inputdata.value.String()); + return; + } + } + + int index = pAnimating->SelectWeightedSequence((Activity)iActivity); + + if (index != ACT_INVALID) + m_OnHasSequence.Set(index, pAnimating, this); + else + m_OnLacksSequence.FireOutput(pAnimating, this); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputSetPoseParameterName( inputdata_t &inputdata ) +{ + m_iszPoseParameterName = inputdata.value.StringID(); + m_iPoseParameterIndex = -1; + + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) + { + if (GetPoseParameterIndex(pAnimating) == -1) + Warning("%s: Pose parameter \"%s\" does not exist on %s\n", GetDebugName(), inputdata.value.String(), STRING(pAnimating->GetModelName())); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputSetPoseParameterValue( inputdata_t &inputdata ) +{ + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) + { + int index = GetPoseParameterIndex(pAnimating); + if (index != -1) + { + pAnimating->SetPoseParameter( index, inputdata.value.Float() ); + } + else + Warning("%s: Pose parameter \"%s\" does not exist on %s\n", GetDebugName(), STRING(m_iszPoseParameterName), STRING(pAnimating->GetModelName())); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicModelInfo::InputGetPoseParameter( inputdata_t &inputdata ) +{ + CBaseAnimating *pAnimating = GetTarget(inputdata); + if (pAnimating && pAnimating->GetModelPtr()) + { + int index = GetPoseParameterIndex(pAnimating); + if (index != -1) + { + m_OutPoseParameterValue.Set( pAnimating->GetPoseParameter( index ), pAnimating, this ); + } + else + Warning("%s: Pose parameter \"%s\" does not exist on %s\n", GetDebugName(), inputdata.value.String(), STRING(pAnimating->GetModelName())); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Checks and calculates an entity's position. +//----------------------------------------------------------------------------- +class CLogicEntityPosition : public CLogicalEntity +{ + DECLARE_CLASS( CLogicEntityPosition, CLogicalEntity ); +private: + EHANDLE m_hTarget; + + int m_iPositionType; + enum + { + POSITION_ORIGIN = 0, + POSITION_LOCAL, + POSITION_BBOX, + POSITION_EYES, + POSITION_EARS, + POSITION_ATTACHMENT, + }; + + // Something that accompanies the position type, like an attachment name. + string_t m_iszPositionParameter; + + CBaseEntity *GetTarget(CBaseEntity *pActivator, CBaseEntity *pCaller); + + Vector GetPosition(CBaseEntity *pEntity); + QAngle GetAngles(CBaseEntity *pEntity); + + // Inputs + void InputGetPosition( inputdata_t &inputdata ); + void InputSetPosition( inputdata_t &inputdata ); + void InputPredictPosition( inputdata_t &inputdata ); + + void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); m_hTarget = NULL; } + + // Outputs + COutputVector m_OutPosition; + COutputVector m_OutAngles; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_entity_position, CLogicEntityPosition); + +BEGIN_DATADESC( CLogicEntityPosition ) + + // Keys + DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iPositionType, FIELD_INTEGER, "PositionType" ), + DEFINE_KEYFIELD( m_iszPositionParameter, FIELD_STRING, "PositionParameter" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "GetPosition", InputGetPosition ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetPosition", InputSetPosition ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "PredictPosition", InputPredictPosition ), + + // Outputs + DEFINE_OUTPUT(m_OutPosition, "OutPosition"), + DEFINE_OUTPUT(m_OutAngles, "OutAngles"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline CBaseEntity *CLogicEntityPosition::GetTarget(CBaseEntity *pActivator, CBaseEntity *pCaller) +{ + // Always reset with procedurals + if (!m_hTarget || STRING(m_target)[0] == '!') + m_hTarget = gEntList.FindEntityByName(NULL, STRING(m_target), this, pActivator, pCaller); + return m_hTarget.Get(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +Vector CLogicEntityPosition::GetPosition(CBaseEntity *pEntity) +{ + switch (m_iPositionType) + { + case POSITION_ORIGIN: return pEntity->GetAbsOrigin(); + case POSITION_LOCAL: return pEntity->GetLocalOrigin(); + case POSITION_BBOX: return pEntity->WorldSpaceCenter(); + case POSITION_EYES: return pEntity->EyePosition(); + case POSITION_EARS: return pEntity->EarPosition(); + case POSITION_ATTACHMENT: + { + CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); + if (!pAnimating) + { + Warning("%s wants to measure one of %s's attachments, but %s doesn't support them!\n", GetDebugName(), pEntity->GetDebugName(), pEntity->GetDebugName()); + break; } + + Vector vecPosition; + pAnimating->GetAttachment(STRING(m_iszPositionParameter), vecPosition); + return vecPosition; } } - - if ( eFire == LOGIC_BRANCH_FIRE ) + + return vec3_origin; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +QAngle CLogicEntityPosition::GetAngles(CBaseEntity *pEntity) +{ + switch (m_iPositionType) + { + case POSITION_BBOX: + case POSITION_EARS: + case POSITION_ORIGIN: return pEntity->GetAbsAngles(); break; + case POSITION_LOCAL: return pEntity->GetLocalAngles(); break; + case POSITION_EYES: return pEntity->EyeAngles(); break; + case POSITION_ATTACHMENT: + { + CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); + if (!pAnimating) + { + Warning("%s wants to measure one of %s's attachments, but %s doesn't support them!\n", GetDebugName(), pEntity->GetDebugName(), pEntity->GetDebugName()); + break; + } + + QAngle AttachmentAngles; + matrix3x4_t attachmentToWorld; + pAnimating->GetAttachment( pAnimating->LookupAttachment( STRING( m_iszPositionParameter ) ), attachmentToWorld ); + MatrixAngles( attachmentToWorld, AttachmentAngles ); + return AttachmentAngles; + } break; + } + + return vec3_angle; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicEntityPosition::InputGetPosition( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = GetTarget(inputdata.pActivator, inputdata.pCaller); + if (!pEntity) + { + m_OutPosition.Set( vec3_origin, NULL, this ); + m_OutAngles.Set( vec3_angle, NULL, this ); + return; + } + + m_OutPosition.Set( GetPosition(pEntity), pEntity, this ); + m_OutAngles.Set( GetAngles(pEntity), pEntity, this ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicEntityPosition::InputSetPosition( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = GetTarget(inputdata.pActivator, inputdata.pCaller); + if (!pEntity) + { + Warning("%s can't find entity %s for SetPosition!\n", GetDebugName(), STRING(m_target)); + return; + } + + Vector vec; + inputdata.value.Vector3D(vec); + + // If the position is local, they might want to move local origin instead + if (m_iPositionType == POSITION_LOCAL) + pEntity->SetLocalOrigin(vec); + else + pEntity->SetAbsOrigin(vec); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicEntityPosition::InputPredictPosition( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = GetTarget(inputdata.pActivator, inputdata.pCaller); + if (!pEntity) + { + m_OutPosition.Set( vec3_origin, NULL, this ); + m_OutAngles.Set( vec3_angle, NULL, this ); + return; + } + + Vector vecPosition; + UTIL_PredictedPosition(pEntity, GetPosition(pEntity), inputdata.value.Float(), &vecPosition); + + QAngle angAngles; + UTIL_PredictedAngles(pEntity, GetAngles(pEntity), inputdata.value.Float(), &angAngles); + + m_OutPosition.Set( vecPosition, pEntity, this ); + m_OutAngles.Set( angAngles, pEntity, this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Accesses context values +//----------------------------------------------------------------------------- +class CLogicContextAccessor : public CLogicalEntity +{ + DECLARE_CLASS(CLogicContextAccessor, CLogicalEntity); + +public: + CBaseEntity *GetTarget(CBaseEntity *pCaller, CBaseEntity *pActivator); + + bool TestContext(CBaseEntity *pTarget, const char *szKeyName); + void SetContext(CBaseEntity *pTarget, const char *szKeyName, string_t szValue); + + // Inputs + void InputTest(inputdata_t &inputdata); + void InputTestContext(inputdata_t &inputdata); + void InputTestTarget(inputdata_t &inputdata); + + void InputSetContext(inputdata_t &inputdata); + + void InputSetValue(inputdata_t &inputdata); + + //bool ReadUnregisteredKeyfields(CBaseEntity *pTarget, const char *szKeyName, variant_t *variant); + + COutputString m_OutValue; + COutputEvent m_OnFailed; + + string_t m_iszContext; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_context_accessor, CLogicContextAccessor); + + +BEGIN_DATADESC(CLogicContextAccessor) + +DEFINE_KEYFIELD( m_iszContext, FIELD_STRING, "context" ), + +// Inputs +DEFINE_INPUTFUNC(FIELD_VOID, "Test", InputTest), +DEFINE_INPUTFUNC(FIELD_STRING, "TestContext", InputTestContext), +DEFINE_INPUTFUNC(FIELD_STRING, "TestTarget", InputTestTarget), +DEFINE_INPUTFUNC(FIELD_STRING, "SetContext", InputSetContext), +DEFINE_INPUTFUNC(FIELD_STRING, "SetValue", InputSetValue), + +DEFINE_OUTPUT( m_OutValue, "OutValue" ), +DEFINE_OUTPUT( m_OnFailed, "OnFailed" ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CBaseEntity *CLogicContextAccessor::GetTarget(CBaseEntity *pCaller, CBaseEntity *pActivator) +{ + return gEntList.FindEntityByName(NULL, m_target, this, pActivator, pCaller); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicContextAccessor::TestContext(CBaseEntity *pTarget, const char *szKeyName) +{ + int idx = pTarget->FindContextByName( szKeyName ); + if ( idx != -1 ) + { + m_OutValue.Set(FindPooledString(pTarget->GetContextValue(idx)), pTarget, this); + return true; + } + else { - if ( m_bInValue ) - { - m_OnTrue.FireOutput( pActivator, this ); - } - else - { - m_OnFalse.FireOutput( pActivator, this ); - } + m_OnFailed.FireOutput(pTarget, this); + return false; } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicContextAccessor::SetContext(CBaseEntity *pTarget, const char *szKeyName, string_t szValue) +{ + pTarget->AddContext(szKeyName, STRING(szValue)); + + m_OutValue.Set(szValue, pTarget, this); +} //----------------------------------------------------------------------------- -// Purpose: Accessor for logic_branchlist to test the value of the branch on demand. +// Purpose: //----------------------------------------------------------------------------- -bool CLogicBranch::GetLogicBranchState() +void CLogicContextAccessor::InputTest(inputdata_t &inputdata) { - return m_bInValue; + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (pTarget && m_iszContext != NULL_STRING) + { + TestContext(pTarget, STRING(m_iszContext)); + } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicContextAccessor::InputTestContext(inputdata_t &inputdata) +{ + const char *input = inputdata.value.String(); + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (input && pTarget) + { + TestContext(pTarget, input); + } +} //----------------------------------------------------------------------------- +// Purpose: //----------------------------------------------------------------------------- -void CLogicBranch::AddLogicBranchListener( CBaseEntity *pEntity ) +void CLogicContextAccessor::InputTestTarget(inputdata_t &inputdata) { - if ( m_Listeners.Find( pEntity ) == -1 ) + m_target = inputdata.value.StringID(); + CBaseEntity *pTarget = gEntList.FindEntityByName(NULL, inputdata.value.StringID(), this, inputdata.pCaller, inputdata.pActivator); + if (pTarget && m_iszContext != NULL_STRING) { - m_Listeners.AddToTail( pEntity ); + TestContext(pTarget, STRING(m_iszContext)); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -int CLogicBranch::DrawDebugTextOverlays( void ) +void CLogicContextAccessor::InputSetContext(inputdata_t &inputdata) { - int text_offset = BaseClass::DrawDebugTextOverlays(); + m_iszContext = inputdata.value.StringID(); +} - if (m_debugOverlays & OVERLAY_TEXT_BIT) +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicContextAccessor::InputSetValue(inputdata_t &inputdata) +{ + CBaseEntity *pTarget = GetTarget(inputdata.pCaller, inputdata.pActivator); + if (pTarget) { - char tempstr[512]; - - // print refire time - Q_snprintf( tempstr, sizeof(tempstr), "Branch value: %s", (m_bInValue) ? "TRUE" : "FALSE" ); - EntityText( text_offset, tempstr, 0 ); - text_offset++; + SetContext(pTarget, STRING(m_iszContext), inputdata.value.StringID()); } - - return text_offset; } //----------------------------------------------------------------------------- -// Purpose: Autosaves when triggered +// Purpose: Replicates light pattern functionality. //----------------------------------------------------------------------------- -class CLogicAutosave : public CLogicalEntity +class CMathLightPattern : public CLogicalEntity { - DECLARE_CLASS( CLogicAutosave, CLogicalEntity ); + DECLARE_CLASS( CMathLightPattern, CLogicalEntity ); +private: + + + string_t m_iszPattern; + + bool m_bDisabled; + + void Spawn(); + bool KeyValue( const char *szKeyName, const char *szValue ); + + void OutputCurPattern(); + + void StartPatternThink(); + void PatternThink(); + unsigned char m_NextLetter = 0; + + // How fast the pattern should be + float m_flPatternSpeed = 0.1f; + + inline bool VerifyPatternValid() { return (m_iszPattern != NULL_STRING && STRING( m_iszPattern )[0] != '\0'); } -protected: // Inputs - void InputSave( inputdata_t &inputdata ); - void InputSaveDangerous( inputdata_t &inputdata ); - void InputSetMinHitpointsThreshold( inputdata_t &inputdata ); + void InputSetStyle( inputdata_t &inputdata ); + void InputSetPattern( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + // Outputs + COutputFloat m_OutValue; + COutputString m_OutLetter; + COutputEvent m_OnLightOn; + COutputEvent m_OnLightOff; DECLARE_DATADESC(); - bool m_bForceNewLevelUnit; - int m_minHitPoints; - int m_minHitPointsToCommit; }; -LINK_ENTITY_TO_CLASS(logic_autosave, CLogicAutosave); +LINK_ENTITY_TO_CLASS( math_lightpattern, CMathLightPattern ); + +BEGIN_DATADESC( CMathLightPattern ) + + // Keys + DEFINE_KEYFIELD(m_iszPattern, FIELD_STRING, "pattern"), + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + DEFINE_KEYFIELD(m_flPatternSpeed, FIELD_FLOAT, "PatternSpeed"), -BEGIN_DATADESC( CLogicAutosave ) - DEFINE_KEYFIELD( m_bForceNewLevelUnit, FIELD_BOOLEAN, "NewLevelUnit" ), - DEFINE_KEYFIELD( m_minHitPoints, FIELD_INTEGER, "MinimumHitPoints" ), - DEFINE_KEYFIELD( m_minHitPointsToCommit, FIELD_INTEGER, "MinHitPointsToCommit" ), // Inputs - DEFINE_INPUTFUNC( FIELD_VOID, "Save", InputSave ), - DEFINE_INPUTFUNC( FIELD_FLOAT, "SaveDangerous", InputSaveDangerous ), - DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMinHitpointsThreshold", InputSetMinHitpointsThreshold ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetStyle", InputSetStyle ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetPattern", InputSetPattern ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + + // Outputs + DEFINE_OUTPUT(m_OutValue, "OutValue"), + DEFINE_OUTPUT(m_OutLetter, "OutLetter"), + DEFINE_OUTPUT(m_OnLightOn, "OnLightOn"), + DEFINE_OUTPUT(m_OnLightOff, "OnLightOff"), + + DEFINE_THINKFUNC( PatternThink ), + DEFINE_FIELD( m_NextLetter, FIELD_CHARACTER ), + END_DATADESC() +extern const char *GetDefaultLightstyleString( int styleIndex ); + +static const char *s_pLightPatternContext = "PatternContext"; + //----------------------------------------------------------------------------- -// Purpose: Save! +// Purpose: //----------------------------------------------------------------------------- -void CLogicAutosave::InputSave( inputdata_t &inputdata ) +void CMathLightPattern::Spawn() { - if ( m_bForceNewLevelUnit ) - { - engine->ClearSaveDir(); - } + BaseClass::Spawn(); - engine->ServerCommand( "autosave\n" ); + if (!m_bDisabled && VerifyPatternValid()) + StartPatternThink(); } //----------------------------------------------------------------------------- -// Purpose: Save safely! +// Purpose: //----------------------------------------------------------------------------- -void CLogicAutosave::InputSaveDangerous( inputdata_t &inputdata ) +void CMathLightPattern::OutputCurPattern() { - CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + // This code looks messy, but it does what it's supposed to and is safe enough. + // First, we get the next letter in the pattern sequence. + // Next, we calculate its integral proximity to the character 'a' (fully dark) + // and calculate its approximate brightness by dividing it by the number of letters in the alphabet other than a. + // We output that brightness value for things like projected textures and other custom intensity values + // so they could replicate the patterns of their corresponding vrad lights. + char cLetter = STRING(m_iszPattern)[m_NextLetter]; + int iValue = (cLetter - 'a'); + float flResult = iValue != 0 ? ((float)iValue / 25.0f) : 0.0f; + m_OutValue.Set(flResult, this, this); + + // User-friendly "Light on, light off" outputs + if (flResult > 0) + m_OnLightOn.FireOutput(this, this); + else + m_OnLightOff.FireOutput(this, this); - if ( g_ServerGameDLL.m_fAutoSaveDangerousTime != 0.0f && g_ServerGameDLL.m_fAutoSaveDangerousTime >= gpGlobals->curtime ) - { - // A previous dangerous auto save was waiting to become safe + // Create a string with cLetter and a null terminator. + char szLetter[2] = { cLetter, '\0' }; + m_OutLetter.Set( AllocPooledString(szLetter), this, this ); +} - if ( pPlayer->GetDeathTime() == 0.0f || pPlayer->GetDeathTime() > gpGlobals->curtime ) - { - // The player isn't dead, so make the dangerous auto save safe - engine->ServerCommand( "autosavedangerousissafe\n" ); - } - } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::StartPatternThink() +{ + // Output our current/next one immediately. + OutputCurPattern(); - if ( m_bForceNewLevelUnit ) + // Start thinking now. + SetContextThink( &CMathLightPattern::PatternThink, gpGlobals->curtime, s_pLightPatternContext ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::PatternThink() +{ + // Output our current/next one + OutputCurPattern(); + + // Increment + m_NextLetter++; + if (STRING(m_iszPattern)[m_NextLetter] == '\0') + m_NextLetter = 0; + + //m_OutLetter.Set(AllocPooledString(UTIL_VarArgs("%c", m_NextLetter)), this, this); + + SetNextThink( gpGlobals->curtime + m_flPatternSpeed, s_pLightPatternContext ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CMathLightPattern::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "style" ) ) { - engine->ClearSaveDir(); + m_iszPattern = AllocPooledString(GetDefaultLightstyleString(atoi(szValue))); } + else + return BaseClass::KeyValue( szKeyName, szValue ); - if ( pPlayer->GetHealth() >= m_minHitPoints ) - { - engine->ServerCommand( "autosavedangerous\n" ); - g_ServerGameDLL.m_fAutoSaveDangerousTime = gpGlobals->curtime + inputdata.value.Float(); + return true; +} - // Player must have this much health when we go to commit, or we don't commit. - g_ServerGameDLL.m_fAutoSaveDangerousMinHealthToCommit = m_minHitPointsToCommit; - } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::InputSetStyle( inputdata_t &inputdata ) +{ + m_iszPattern = AllocPooledString(GetDefaultLightstyleString(inputdata.value.Int())); + m_NextLetter = 0; } //----------------------------------------------------------------------------- -// Purpose: Autosaves when triggered +// Purpose: //----------------------------------------------------------------------------- -class CLogicActiveAutosave : public CLogicAutosave +void CMathLightPattern::InputSetPattern( inputdata_t &inputdata ) { - DECLARE_CLASS( CLogicActiveAutosave, CLogicAutosave ); + m_iszPattern = inputdata.value.StringID(); + m_NextLetter = 0; +} - void InputEnable( inputdata_t &inputdata ) - { - m_flStartTime = -1; - SetThink( &CLogicActiveAutosave::SaveThink ); - SetNextThink( gpGlobals->curtime ); - } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::InputEnable( inputdata_t &inputdata ) +{ + if (VerifyPatternValid()) + StartPatternThink(); + else + Warning("%s tried to enable without valid pattern\n", GetDebugName()); +} - void InputDisable( inputdata_t &inputdata ) - { - SetThink( NULL ); - } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::InputDisable( inputdata_t &inputdata ) +{ + SetContextThink( NULL, TICK_NEVER_THINK, s_pLightPatternContext ); +} - void SaveThink() - { - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) - { - if ( m_flStartTime < 0 ) - { - if ( pPlayer->GetHealth() <= m_minHitPoints ) - { - m_flStartTime = gpGlobals->curtime; - } - } - else - { - if ( pPlayer->GetHealth() >= m_TriggerHitPoints ) - { - inputdata_t inputdata; - DevMsg( 2, "logic_active_autosave (%s, %d) triggered\n", STRING( GetEntityName() ), entindex() ); - if ( !m_flDangerousTime ) - { - InputSave( inputdata ); - } - else - { - inputdata.value.SetFloat( m_flDangerousTime ); - InputSaveDangerous( inputdata ); - } - m_flStartTime = -1; - } - else if ( m_flTimeToTrigger > 0 && gpGlobals->curtime - m_flStartTime > m_flTimeToTrigger ) - { - m_flStartTime = -1; - } - } - } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMathLightPattern::InputToggle( inputdata_t &inputdata ) +{ + if (GetNextThink(s_pLightPatternContext) != TICK_NEVER_THINK) + InputDisable(inputdata); + else + InputEnable(inputdata); +} - float thinkInterval = ( m_flStartTime < 0 ) ? 1.0 : 0.5; - SetNextThink( gpGlobals->curtime + thinkInterval ); - } +//----------------------------------------------------------------------------- +// Purpose: Sequences for keypads, etc. +//----------------------------------------------------------------------------- +#define MAX_SEQUENCE_CASES 16 + +class CLogicSequence : public CLogicalEntity +{ + DECLARE_CLASS( CLogicSequence, CLogicalEntity ); +public: + CLogicSequence(); + + void Activate(); + + bool KeyValue( const char *szKeyName, const char *szValue ); + + void TestCase( int iCase, string_t iszValue, CBaseEntity *pActivator ); + void SequenceComplete( string_t iszValue, CBaseEntity *pActivator ); + +private: + string_t m_iszCase[MAX_SEQUENCE_CASES]; + int m_iNumCases; + + bool m_bDisabled; + + bool m_bDontIncrementOnPass; + + // Inputs + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + void InputInValue( inputdata_t &inputdata ); + void InputSetCurrentCase( inputdata_t &inputdata ); + void InputSetCurrentCaseNoFire( inputdata_t &inputdata ); + void InputIncrementSequence( inputdata_t &inputdata ); + void InputResetSequence( inputdata_t &inputdata ); + + // Outputs + COutputInt m_CurCase; + COutputString m_OnCasePass; + COutputString m_OnCaseFail; + COutputString m_OnSequenceComplete; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( logic_sequence, CLogicSequence ); - DECLARE_DATADESC(); - int m_TriggerHitPoints; - float m_flTimeToTrigger; - float m_flStartTime; - float m_flDangerousTime; -}; +BEGIN_DATADESC( CLogicSequence ) -LINK_ENTITY_TO_CLASS(logic_active_autosave, CLogicActiveAutosave); + // Keys + DEFINE_KEYFIELD( m_iszCase[0], FIELD_STRING, "Case01" ), + DEFINE_KEYFIELD( m_iszCase[1], FIELD_STRING, "Case02" ), + DEFINE_KEYFIELD( m_iszCase[2], FIELD_STRING, "Case03" ), + DEFINE_KEYFIELD( m_iszCase[3], FIELD_STRING, "Case04" ), + DEFINE_KEYFIELD( m_iszCase[4], FIELD_STRING, "Case05" ), + DEFINE_KEYFIELD( m_iszCase[5], FIELD_STRING, "Case06" ), + DEFINE_KEYFIELD( m_iszCase[6], FIELD_STRING, "Case07" ), + DEFINE_KEYFIELD( m_iszCase[7], FIELD_STRING, "Case08" ), + DEFINE_KEYFIELD( m_iszCase[8], FIELD_STRING, "Case09" ), + DEFINE_KEYFIELD( m_iszCase[9], FIELD_STRING, "Case10" ), + DEFINE_KEYFIELD( m_iszCase[10], FIELD_STRING, "Case11" ), + DEFINE_KEYFIELD( m_iszCase[11], FIELD_STRING, "Case12" ), + DEFINE_KEYFIELD( m_iszCase[12], FIELD_STRING, "Case13" ), + DEFINE_KEYFIELD( m_iszCase[13], FIELD_STRING, "Case14" ), + DEFINE_KEYFIELD( m_iszCase[14], FIELD_STRING, "Case15" ), + DEFINE_KEYFIELD( m_iszCase[15], FIELD_STRING, "Case16" ), + + // This doesn't need to be saved, it can be assigned every Activate() + //DEFINE_FIELD( m_iNumCases, FIELD_INTEGER ), + + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + DEFINE_KEYFIELD( m_bDontIncrementOnPass, FIELD_BOOLEAN, "DontIncrementOnPass" ), -BEGIN_DATADESC( CLogicActiveAutosave ) - DEFINE_KEYFIELD( m_TriggerHitPoints, FIELD_INTEGER, "TriggerHitPoints" ), - DEFINE_KEYFIELD( m_flTimeToTrigger, FIELD_FLOAT, "TimeToTrigger" ), - DEFINE_KEYFIELD( m_flDangerousTime, FIELD_FLOAT, "DangerousTime" ), - DEFINE_FIELD( m_flStartTime, FIELD_TIME ), - DEFINE_THINKFUNC( SaveThink ), + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), -END_DATADESC() + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + DEFINE_INPUTFUNC( FIELD_STRING, "InValue", InputInValue ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCurrentCase", InputSetCurrentCase ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCurrentCaseNoFire", InputSetCurrentCaseNoFire ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "IncrementSequence", InputIncrementSequence ), + DEFINE_INPUTFUNC( FIELD_VOID, "ResetSequence", InputResetSequence ), + + // Outputs + DEFINE_OUTPUT( m_CurCase, "OutCurCase" ), + DEFINE_OUTPUT( m_OnCasePass, "OnCasePass" ), + DEFINE_OUTPUT( m_OnCaseFail, "OnCaseFail" ), + DEFINE_OUTPUT( m_OnSequenceComplete, "OnSequenceComplete" ), +END_DATADESC() //----------------------------------------------------------------------------- -// Purpose: Keyfield set func +// Purpose: //----------------------------------------------------------------------------- -void CLogicAutosave::InputSetMinHitpointsThreshold( inputdata_t &inputdata ) +CLogicSequence::CLogicSequence() { - int setTo = inputdata.value.Int(); - AssertMsg1(setTo >= 0 && setTo <= 100, "Tried to set autosave MinHitpointsThreshold to %d!\n", setTo); - m_minHitPoints = setTo; + m_CurCase.Init( 1 ); } -// Finds the named physics object. If no name, returns the world -// If a name is specified and an object not found - errors are reported -IPhysicsObject *FindPhysicsObjectByNameOrWorld( string_t name, CBaseEntity *pErrorEntity ) +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::Activate( void ) { - if ( !name ) - return g_PhysWorldObject; + BaseClass::Activate(); - IPhysicsObject *pPhysics = FindPhysicsObjectByName( name.ToCStr(), pErrorEntity ); - if ( !pPhysics ) + // Count number of cases + for (m_iNumCases = 0; m_iNumCases < MAX_SEQUENCE_CASES; m_iNumCases++) { - DevWarning("%s: can't find %s\n", pErrorEntity->GetClassname(), name.ToCStr()); + if (m_iszCase[m_iNumCases] == NULL_STRING) + break; } - return pPhysics; } -class CLogicCollisionPair : public CLogicalEntity +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CLogicSequence::KeyValue( const char *szKeyName, const char *szValue ) { - DECLARE_CLASS( CLogicCollisionPair, CLogicalEntity ); -public: + if (FStrEq( szKeyName, "StartCase" )) + { + m_CurCase.Init( atoi(szValue) ); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); - void EnableCollisions( bool bEnable ) + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::TestCase( int iCase, string_t iszValue, CBaseEntity *pActivator ) +{ + if (m_bDisabled) { - IPhysicsObject *pPhysics0 = FindPhysicsObjectByNameOrWorld( m_nameAttach1, this ); - IPhysicsObject *pPhysics1 = FindPhysicsObjectByNameOrWorld( m_nameAttach2, this ); + DevMsg("%s ignoring case test because it is disabled\n", GetDebugName()); + return; + } - // need two different objects to do anything - if ( pPhysics0 && pPhysics1 && pPhysics0 != pPhysics1 ) + // Arrays are 0-based, so the index is (iCase - 1) + int iIndex = iCase - 1; + if (iIndex >= m_iNumCases) + { + DevMsg("%s ignoring case test because the current case %i is greater than or equal to the number of cases %i\n", GetDebugName(), iCase, m_iNumCases); + return; + } + + if (Matcher_Match( STRING( m_iszCase[iIndex] ), STRING(iszValue) )) + { + m_OnCasePass.Set( iszValue, pActivator, this ); + + if (!m_bDontIncrementOnPass) { - m_disabled = !bEnable; - m_succeeded = true; - if ( bEnable ) - { - PhysEnableEntityCollisions( pPhysics0, pPhysics1 ); - } - else + m_CurCase.Set(iCase + 1, pActivator, this); + + if (m_CurCase.Get() > m_iNumCases) { - PhysDisableEntityCollisions( pPhysics0, pPhysics1 ); + // Sequence complete! + SequenceComplete(iszValue, pActivator); } } else { - m_succeeded = false; - } - } - - void Activate( void ) - { - if ( m_disabled ) - { - EnableCollisions( false ); + m_CurCase.Set(iCase, pActivator, this); } - BaseClass::Activate(); - } - - void InputDisableCollisions( inputdata_t &inputdata ) - { - if ( m_succeeded && m_disabled ) - return; - EnableCollisions( false ); } - - void InputEnableCollisions( inputdata_t &inputdata ) + else { - if ( m_succeeded && !m_disabled ) - return; - EnableCollisions( true ); + m_OnCaseFail.Set( iszValue, pActivator, this ); } - // If Activate() becomes PostSpawn() - //void OnRestore() { Activate(); } +} - DECLARE_DATADESC(); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::SequenceComplete( string_t iszValue, CBaseEntity *pActivator ) +{ + m_OnSequenceComplete.Set( iszValue, pActivator, this ); +} -private: - string_t m_nameAttach1; - string_t m_nameAttach2; - bool m_disabled; - bool m_succeeded; -}; +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} -BEGIN_DATADESC( CLogicCollisionPair ) - DEFINE_KEYFIELD( m_nameAttach1, FIELD_STRING, "attach1" ), - DEFINE_KEYFIELD( m_nameAttach2, FIELD_STRING, "attach2" ), - DEFINE_KEYFIELD( m_disabled, FIELD_BOOLEAN, "startdisabled" ), - DEFINE_FIELD( m_succeeded, FIELD_BOOLEAN ), +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} - // Inputs - DEFINE_INPUTFUNC( FIELD_VOID, "DisableCollisions", InputDisableCollisions ), - DEFINE_INPUTFUNC( FIELD_VOID, "EnableCollisions", InputEnableCollisions ), -END_DATADESC() +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputToggle( inputdata_t &inputdata ) +{ + m_bDisabled = (m_bDisabled == false); +} -LINK_ENTITY_TO_CLASS( logic_collision_pair, CLogicCollisionPair ); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputInValue( inputdata_t &inputdata ) +{ + TestCase( m_CurCase.Get(), inputdata.value.StringID(), inputdata.pActivator ); +} +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputSetCurrentCase( inputdata_t &inputdata ) +{ + m_CurCase.Set( inputdata.value.Int(), inputdata.pActivator, this ); +} //----------------------------------------------------------------------------- +// Purpose: //----------------------------------------------------------------------------- -#define MAX_LOGIC_BRANCH_NAMES 16 +void CLogicSequence::InputSetCurrentCaseNoFire( inputdata_t &inputdata ) +{ + m_CurCase.Init( inputdata.value.Int() ); +} -class CLogicBranchList : public CLogicalEntity +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputIncrementSequence( inputdata_t &inputdata ) { - DECLARE_CLASS( CLogicBranchList, CLogicalEntity ); + int iInc = inputdata.value.Int(); + m_CurCase.Set( m_CurCase.Get() + (iInc != 0 ? iInc : 1), inputdata.pActivator, this ); +} - virtual void Spawn(); - virtual void Activate(); - virtual int DrawDebugTextOverlays( void ); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSequence::InputResetSequence( inputdata_t &inputdata ) +{ + m_CurCase.Set( 1, inputdata.pActivator, this ); +} -private: +//----------------------------------------------------------------------------- +// Purpose: Generates various types of numbers based on existing material proxies +//----------------------------------------------------------------------------- +class CMathGenerate : public CLogicalEntity +{ +public: + DECLARE_CLASS( CMathGenerate, CLogicalEntity ); + CMathGenerate(); - enum LogicBranchListenerLastState_t + enum GenerateType_t { - LOGIC_BRANCH_LISTENER_NOT_INIT = 0, - LOGIC_BRANCH_LISTENER_ALL_TRUE, - LOGIC_BRANCH_LISTENER_ALL_FALSE, - LOGIC_BRANCH_LISTENER_MIXED, + GENERATE_SINE_WAVE, + GENERATE_LINEAR_RAMP, + GENERATE_UNIFORM_NOISE, + GENERATE_GAUSSIAN_NOISE, + GENERATE_EXPONENTIAL, }; - void DoTest( CBaseEntity *pActivator ); + // Keys + float m_flMax; + float m_flMin; - string_t m_nLogicBranchNames[MAX_LOGIC_BRANCH_NAMES]; - CUtlVector m_LogicBranchList; - LogicBranchListenerLastState_t m_eLastState; + float m_flParam1; + float m_flParam2; + + bool m_bDisabled; + + GenerateType_t m_iGenerateType; // Inputs - void Input_OnLogicBranchRemoved( inputdata_t &inputdata ); - void Input_OnLogicBranchChanged( inputdata_t &inputdata ); - void InputTest( inputdata_t &inputdata ); + void InputSetValue( inputdata_t &inputdata ); + void InputSetValueNoFire( inputdata_t &inputdata ); + void InputGetValue( inputdata_t &inputdata ); + void InputSetGenerateType( inputdata_t &inputdata ); + + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + void UpdateOutValue( float fNewValue, CBaseEntity *pActivator = NULL ); + void UpdateOutValueSine( float fNewValue, CBaseEntity *pActivator = NULL ); + + // Basic functions + void Spawn(); + bool KeyValue( const char *szKeyName, const char *szValue ); + + void StartGenerating(); + void StopGenerating(); + + // Number generation functions + void GenerateSineWave(); + void GenerateLinearRamp(); + void GenerateUniformNoise(); + void GenerateGaussianNoise(); + void GenerateExponential(); + + // The gaussian stream normally only exists on the client, so we use our own. + static CGaussianRandomStream m_GaussianStream; + + bool m_bHitMin; // Set when we reach or go below our minimum value, cleared if we go above it again. + bool m_bHitMax; // Set when we reach or exceed our maximum value, cleared if we fall below it again. // Outputs - COutputEvent m_OnAllTrue; // Fired when all the registered logic_branches become true. - COutputEvent m_OnAllFalse; // Fired when all the registered logic_branches become false. - COutputEvent m_OnMixed; // Fired when one of the registered logic branches changes, but not all are true or false. + COutputFloat m_OutValue; + COutputFloat m_OnGetValue; // Used for polling the counter value. + COutputEvent m_OnHitMin; + COutputEvent m_OnHitMax; + COutputEvent m_OnChangedFromMin; + COutputEvent m_OnChangedFromMax; DECLARE_DATADESC(); }; -LINK_ENTITY_TO_CLASS(logic_branch_listener, CLogicBranchList); +LINK_ENTITY_TO_CLASS( math_generate, CMathGenerate ); -BEGIN_DATADESC( CLogicBranchList ) +BEGIN_DATADESC( CMathGenerate ) - // Silence, classcheck! - //DEFINE_ARRAY( m_nLogicBranchNames, FIELD_STRING, MAX_LOGIC_BRANCH_NAMES ), + DEFINE_INPUT( m_flMax, FIELD_FLOAT, "SetHitMax" ), + DEFINE_INPUT( m_flMin, FIELD_FLOAT, "SetHitMin" ), + DEFINE_INPUT( m_flParam1, FIELD_FLOAT, "SetParam1" ), + DEFINE_INPUT( m_flParam2, FIELD_FLOAT, "SetParam2" ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), - // Keys - DEFINE_KEYFIELD( m_nLogicBranchNames[0], FIELD_STRING, "Branch01" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[1], FIELD_STRING, "Branch02" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[2], FIELD_STRING, "Branch03" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[3], FIELD_STRING, "Branch04" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[4], FIELD_STRING, "Branch05" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[5], FIELD_STRING, "Branch06" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[6], FIELD_STRING, "Branch07" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[7], FIELD_STRING, "Branch08" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[8], FIELD_STRING, "Branch09" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[9], FIELD_STRING, "Branch10" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[10], FIELD_STRING, "Branch11" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[11], FIELD_STRING, "Branch12" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[12], FIELD_STRING, "Branch13" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[13], FIELD_STRING, "Branch14" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[14], FIELD_STRING, "Branch15" ), - DEFINE_KEYFIELD( m_nLogicBranchNames[15], FIELD_STRING, "Branch16" ), - - DEFINE_UTLVECTOR( m_LogicBranchList, FIELD_EHANDLE ), - - DEFINE_FIELD( m_eLastState, FIELD_INTEGER ), + DEFINE_KEYFIELD( m_iGenerateType, FIELD_INTEGER, "GenerateType" ), - // Inputs - DEFINE_INPUTFUNC( FIELD_INPUT, "Test", InputTest ), - DEFINE_INPUTFUNC( FIELD_INPUT, "_OnLogicBranchChanged", Input_OnLogicBranchChanged ), - DEFINE_INPUTFUNC( FIELD_INPUT, "_OnLogicBranchRemoved", Input_OnLogicBranchRemoved ), + DEFINE_FIELD( m_bHitMax, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bHitMin, FIELD_BOOLEAN ), - // Outputs - DEFINE_OUTPUT( m_OnAllTrue, "OnAllTrue" ), - DEFINE_OUTPUT( m_OnAllFalse, "OnAllFalse" ), - DEFINE_OUTPUT( m_OnMixed, "OnMixed" ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetValue", InputSetValue ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetValueNoFire", InputSetValueNoFire ), + DEFINE_INPUTFUNC( FIELD_VOID, "GetValue", InputGetValue ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetGenerateType", InputSetGenerateType ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + + DEFINE_OUTPUT( m_OutValue, "OutValue" ), + DEFINE_OUTPUT( m_OnHitMin, "OnHitMin" ), + DEFINE_OUTPUT( m_OnHitMax, "OnHitMax" ), + DEFINE_OUTPUT( m_OnGetValue, "OnGetValue" ), + DEFINE_OUTPUT( m_OnChangedFromMin, "OnChangedFromMin" ), + DEFINE_OUTPUT( m_OnChangedFromMax, "OnChangedFromMax" ), + + DEFINE_THINKFUNC( GenerateSineWave ), + DEFINE_THINKFUNC( GenerateLinearRamp ), + DEFINE_THINKFUNC( GenerateUniformNoise ), + DEFINE_THINKFUNC( GenerateGaussianNoise ), + DEFINE_THINKFUNC( GenerateExponential ), END_DATADESC() +CGaussianRandomStream CMathGenerate::m_GaussianStream; //----------------------------------------------------------------------------- -// Purpose: Called before spawning, after key values have been set. +// Purpose: //----------------------------------------------------------------------------- -void CLogicBranchList::Spawn( void ) +CMathGenerate::CMathGenerate() { + m_GaussianStream.AttachToStream( random ); } - //----------------------------------------------------------------------------- -// Finds all the logic_branches that we are monitoring and register ourselves with them. +// Purpose: //----------------------------------------------------------------------------- -void CLogicBranchList::Activate( void ) +void CMathGenerate::Spawn() { - for ( int i = 0; i < MAX_LOGIC_BRANCH_NAMES; i++ ) - { - CBaseEntity *pEntity = NULL; - while ( ( pEntity = gEntList.FindEntityGeneric( pEntity, STRING( m_nLogicBranchNames[i] ), this ) ) != NULL ) - { - if ( FClassnameIs( pEntity, "logic_branch" ) ) - { - CLogicBranch *pBranch = (CLogicBranch *)pEntity; - pBranch->AddLogicBranchListener( this ); - m_LogicBranchList.AddToTail( pBranch ); - } - else - { - DevWarning( "logic_branchlist %s refers to entity %s, which is not a logic_branch\n", GetDebugName(), pEntity->GetDebugName() ); - } - } - } - - BaseClass::Activate(); -} + BaseClass::Spawn(); + if (!m_bDisabled) + StartGenerating(); +} //----------------------------------------------------------------------------- -// Called when a monitored logic branch is deleted from the world, since that -// might affect our final result. +// Purpose: //----------------------------------------------------------------------------- -void CLogicBranchList::Input_OnLogicBranchRemoved( inputdata_t &inputdata ) +bool CMathGenerate::KeyValue( const char *szKeyName, const char *szValue ) { - int nIndex = m_LogicBranchList.Find( inputdata.pActivator ); - if ( nIndex != -1 ) + if (FStrEq( szKeyName, "InitialValue" )) { - m_LogicBranchList.FastRemove( nIndex ); + m_OutValue.Init( atof(szValue) ); } + else + return BaseClass::KeyValue( szKeyName, szValue ); - // See if this logic_branch's deletion affects the final result. - DoTest( inputdata.pActivator ); + return true; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::InputSetValue( inputdata_t &inputdata ) +{ + UpdateOutValue(inputdata.value.Float(), inputdata.pActivator); +} //----------------------------------------------------------------------------- -// Called when the value of a monitored logic branch changes. //----------------------------------------------------------------------------- -void CLogicBranchList::Input_OnLogicBranchChanged( inputdata_t &inputdata ) +void CMathGenerate::InputSetValueNoFire( inputdata_t &inputdata ) { - DoTest( inputdata.pActivator ); + m_OutValue.Init(inputdata.value.Float()); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::InputGetValue( inputdata_t &inputdata ) +{ + float flOutValue = m_OutValue.Get(); + m_OnGetValue.Set( flOutValue, inputdata.pActivator, inputdata.pCaller ); +} //----------------------------------------------------------------------------- -// Input handler to manually test the monitored logic branches and fire the -// appropriate output. //----------------------------------------------------------------------------- -void CLogicBranchList::InputTest( inputdata_t &inputdata ) +void CMathGenerate::InputSetGenerateType( inputdata_t &inputdata ) { - // Force an output. - m_eLastState = LOGIC_BRANCH_LISTENER_NOT_INIT; + m_iGenerateType = (GenerateType_t)inputdata.value.Int(); - DoTest( inputdata.pActivator ); + if (GetNextThink() != TICK_NEVER_THINK) + { + // Change our generation function if we're already generating. + // StartGenerating() should set to the new function. + StartGenerating(); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; + StartGenerating(); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; + StopGenerating(); +} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CLogicBranchList::DoTest( CBaseEntity *pActivator ) +void CMathGenerate::InputToggle( inputdata_t &inputdata ) { - bool bOneTrue = false; - bool bOneFalse = false; - - for ( int i = 0; i < m_LogicBranchList.Count(); i++ ) + m_bDisabled ? InputEnable(inputdata) : InputDisable(inputdata); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the value to the new value, clamping and firing the output value. +// Input : fNewValue - Value to set. +//----------------------------------------------------------------------------- +void CMathGenerate::UpdateOutValue( float fNewValue, CBaseEntity *pActivator ) +{ + if ((m_flMin != 0) || (m_flMax != 0)) { - CLogicBranch *pBranch = (CLogicBranch *)m_LogicBranchList.Element( i ).Get(); - if ( pBranch && pBranch->GetLogicBranchState() ) + // + // Fire an output any time we reach or exceed our maximum value. + // + if ( fNewValue >= m_flMax || (m_iGenerateType == GENERATE_SINE_WAVE && fNewValue >= (m_flMax * 0.995f)) ) { - bOneTrue = true; + if ( !m_bHitMax ) + { + m_bHitMax = true; + m_OnHitMax.FireOutput( pActivator, this ); + } } else { - bOneFalse = true; + // Fire an output if we just changed from the maximum value + if ( m_OutValue.Get() == m_flMax ) + { + m_OnChangedFromMax.FireOutput( pActivator, this ); + } + + m_bHitMax = false; } - } - // Only fire the output if the new result differs from the last result. - if ( bOneTrue && !bOneFalse ) - { - if ( m_eLastState != LOGIC_BRANCH_LISTENER_ALL_TRUE ) + // + // Fire an output any time we reach or go below our minimum value. + // + if ( fNewValue <= m_flMin ) { - m_OnAllTrue.FireOutput( pActivator, this ); - m_eLastState = LOGIC_BRANCH_LISTENER_ALL_TRUE; + if ( !m_bHitMin ) + { + m_bHitMin = true; + m_OnHitMin.FireOutput( pActivator, this ); + } } - } - else if ( bOneFalse && !bOneTrue ) - { - if ( m_eLastState != LOGIC_BRANCH_LISTENER_ALL_FALSE ) + else { - m_OnAllFalse.FireOutput( pActivator, this ); - m_eLastState = LOGIC_BRANCH_LISTENER_ALL_FALSE; + // Fire an output if we just changed from the maximum value + if ( m_OutValue.Get() == m_flMin ) + { + m_OnChangedFromMin.FireOutput( pActivator, this ); + } + + m_bHitMin = false; } + + fNewValue = clamp(fNewValue, m_flMin, m_flMax); } - else + + m_OutValue.Set(fNewValue, pActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the value to the new value, clamping and firing the output value. +// Sine generation needs to use a different function to account for skips and imprecision. +// Input : fNewValue - Value to set. +//----------------------------------------------------------------------------- +void CMathGenerate::UpdateOutValueSine( float fNewValue, CBaseEntity *pActivator ) +{ + if ((m_flMin != 0) || (m_flMax != 0)) { - if ( m_eLastState != LOGIC_BRANCH_LISTENER_MIXED ) + // + // Fire an output any time we reach or exceed our maximum value. + // + if ( fNewValue >= (m_flMax * 0.995f) ) { - m_OnMixed.FireOutput( pActivator, this ); - m_eLastState = LOGIC_BRANCH_LISTENER_MIXED; + if ( !m_bHitMax ) + { + m_bHitMax = true; + m_OnHitMax.FireOutput( pActivator, this ); + } + } + else + { + // Fire an output if we just changed from the maximum value + if ( m_bHitMax ) + { + m_OnChangedFromMax.FireOutput( pActivator, this ); + } + + m_bHitMax = false; + } + + // + // Fire an output any time we reach or go below our minimum value. + // + if ( fNewValue <= (m_flMin * 1.005f) ) + { + if ( !m_bHitMin ) + { + m_bHitMin = true; + m_OnHitMin.FireOutput( pActivator, this ); + } + } + else + { + // Fire an output if we just changed from the maximum value + if ( m_bHitMin ) + { + m_OnChangedFromMin.FireOutput( pActivator, this ); + } + + m_bHitMin = false; } + + //fNewValue = clamp(fNewValue, m_flMin, m_flMax); } + + m_OutValue.Set(fNewValue, pActivator, this); } //----------------------------------------------------------------------------- -// Purpose: //----------------------------------------------------------------------------- -int CLogicBranchList::DrawDebugTextOverlays( void ) +void CMathGenerate::StartGenerating() { - int text_offset = BaseClass::DrawDebugTextOverlays(); + // Correct any min/max quirks here + if (m_flMin > m_flMax) + { + float flTemp = m_flMin; + m_flMin = m_flMax; + m_flMax = flTemp; + } - if (m_debugOverlays & OVERLAY_TEXT_BIT) + switch (m_iGenerateType) { - char tempstr[512]; + case GENERATE_SINE_WAVE: + SetThink( &CMathGenerate::GenerateSineWave ); + break; + case GENERATE_LINEAR_RAMP: + SetThink( &CMathGenerate::GenerateLinearRamp ); + break; + case GENERATE_UNIFORM_NOISE: + SetThink( &CMathGenerate::GenerateUniformNoise ); + break; + case GENERATE_GAUSSIAN_NOISE: + SetThink( &CMathGenerate::GenerateGaussianNoise ); + break; + case GENERATE_EXPONENTIAL: + SetThink( &CMathGenerate::GenerateExponential ); + break; - for ( int i = 0; i < m_LogicBranchList.Count(); i++ ) - { - CLogicBranch *pBranch = (CLogicBranch *)m_LogicBranchList.Element( i ).Get(); - if ( pBranch ) - { - Q_snprintf( tempstr, sizeof(tempstr), "Branch (%s): %s", STRING(pBranch->GetEntityName()), (pBranch->GetLogicBranchState()) ? "TRUE" : "FALSE" ); - EntityText( text_offset, tempstr, 0 ); - text_offset++; - } - } + default: + Warning("%s is set to invalid generation type %i! It won't do anything now.\n", GetDebugName(), m_iGenerateType); + StopGenerating(); + return; } - return text_offset; + // All valid types should fall through to this + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::StopGenerating() +{ + SetThink(NULL); + SetNextThink( TICK_NEVER_THINK ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::GenerateSineWave() +{ + // CSineProxy in mathproxy.cpp + float flSineTimeOffset = m_flParam2; + float flSinePeriod = m_flParam1; + float flValue; + + if (flSinePeriod == 0) + flSinePeriod = 1; + + // get a value in [0,1] + flValue = ( sin( 2.0f * M_PI * (gpGlobals->curtime - flSineTimeOffset) / flSinePeriod ) * 0.5f ) + 0.5f; + // get a value in [min,max] + flValue = ( m_flMax - m_flMin ) * flValue + m_flMin; + + UpdateOutValueSine( flValue ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::GenerateLinearRamp() +{ + // CLinearRampProxy in mathproxy.cpp + + // Param1 = rate + float flVal = m_flParam1 * gpGlobals->curtime + m_OutValue.Get(); + + // clamp + if (flVal < m_flMin) + flVal = m_flMin; + else if (flVal > m_flMax) + flVal = m_flMax; + + UpdateOutValue( flVal ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::GenerateUniformNoise() +{ + // CUniformNoiseProxy in mathproxy.cpp + + UpdateOutValue( random->RandomFloat( m_flMin, m_flMax ) ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::GenerateGaussianNoise() +{ + // CGaussianNoiseProxy in mathproxy.cpp + + float flMean = m_flParam1; + float flStdDev = m_flParam2; + float flVal = m_GaussianStream.RandomFloat( flMean, flStdDev ); + + // clamp + if (flVal < m_flMin) + flVal = m_flMin; + else if (flVal > m_flMax) + flVal = m_flMax; + + UpdateOutValue( flVal ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CMathGenerate::GenerateExponential() +{ + // CExponentialProxy in mathproxy.cpp + + // Param1 = scale + // Param2 = offset + float flVal = m_flParam1 * exp( m_OutValue.Get() + m_flParam2 ); + + // clamp + if (flVal < m_flMin) + flVal = m_flMin; + else if (flVal > m_flMax) + flVal = m_flMax; + + UpdateOutValue( flVal ); + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); } +#endif diff --git a/game/server/logicrelay.cpp b/game/server/logicrelay.cpp index b556ec04..6daa15f4 100644 --- a/game/server/logicrelay.cpp +++ b/game/server/logicrelay.cpp @@ -15,6 +15,10 @@ #include "eventqueue.h" #include "soundent.h" #include "logicrelay.h" +#ifdef MAPBASE +#include "mapbase/variant_tools.h" +#include "saverestore_utlvector.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -29,6 +33,11 @@ BEGIN_DATADESC( CLogicRelay ) DEFINE_FIELD(m_bWaitForRefire, FIELD_BOOLEAN), DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"), +#if RELAY_QUEUE_SYSTEM + DEFINE_KEYFIELD(m_bQueueTrigger, FIELD_BOOLEAN, "QueueDisabledTrigger"), + DEFINE_FIELD(m_bQueueWaiting, FIELD_BOOLEAN), + DEFINE_FIELD(m_flRefireTime, FIELD_TIME), +#endif // Inputs DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), @@ -36,10 +45,16 @@ BEGIN_DATADESC( CLogicRelay ) DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_INPUT, "TriggerWithParameter", InputTriggerWithParameter), +#endif DEFINE_INPUTFUNC(FIELD_VOID, "CancelPending", InputCancelPending), // Outputs DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"), +#ifdef MAPBASE + DEFINE_OUTPUT(m_OnTriggerParameter, "OnTriggerParameter"), +#endif DEFINE_OUTPUT(m_OnSpawn, "OnSpawn"), END_DATADESC() @@ -93,6 +108,11 @@ void CLogicRelay::Think() void CLogicRelay::InputEnable( inputdata_t &inputdata ) { m_bDisabled = false; + +#if RELAY_QUEUE_SYSTEM + if (m_bQueueWaiting) + m_OnTrigger.FireOutput( inputdata.pActivator, this ); +#endif } //------------------------------------------------------------------------------ @@ -132,6 +152,11 @@ void CLogicRelay::InputDisable( inputdata_t &inputdata ) void CLogicRelay::InputToggle( inputdata_t &inputdata ) { m_bDisabled = !m_bDisabled; + +#if RELAY_QUEUE_SYSTEM + if (m_bQueueWaiting) + m_OnTrigger.FireOutput( inputdata.pActivator, this ); +#endif } @@ -156,7 +181,300 @@ void CLogicRelay::InputTrigger( inputdata_t &inputdata ) // m_bWaitForRefire = true; g_EventQueue.AddEvent(this, "EnableRefire", m_OnTrigger.GetMaxDelay() + 0.001, this, this); +#if RELAY_QUEUE_SYSTEM + if (m_bQueueTrigger) + m_flRefireTime = gpGlobals->curtime + m_OnTrigger.GetMaxDelay() + 0.002; +#endif + } + } +#if RELAY_QUEUE_SYSTEM + else if (m_bQueueTrigger) + { + if (m_bDisabled) + m_bQueueWaiting = true; + else // m_bWaitForRefire + m_OnTrigger.FireOutput( inputdata.pActivator, this, (gpGlobals->curtime - m_flRefireTime) ); + } +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler that triggers the relay. +//----------------------------------------------------------------------------- +void CLogicRelay::InputTriggerWithParameter( inputdata_t &inputdata ) +{ + if ((!m_bDisabled) && (!m_bWaitForRefire)) + { + m_OnTriggerParameter.Set( inputdata.value, inputdata.pActivator, this ); + + if (m_spawnflags & SF_REMOVE_ON_FIRE) + { + UTIL_Remove(this); + } + else if (!(m_spawnflags & SF_ALLOW_FAST_RETRIGGER)) + { + // + // Disable the relay so that it cannot be refired until after the last output + // has been fired and post an input to re-enable ourselves. + // + m_bWaitForRefire = true; + g_EventQueue.AddEvent(this, "EnableRefire", m_OnTrigger.GetMaxDelay() + 0.001, this, this); + } + } +} +#endif + +#ifdef MAPBASE + +BEGIN_SIMPLE_DATADESC( LogicRelayQueueInfo_t ) + + DEFINE_FIELD( TriggerWithParameter, FIELD_BOOLEAN ), + DEFINE_FIELD( pActivator, FIELD_CLASSPTR ), + DEFINE_VARIANT( value ), + DEFINE_FIELD( outputID, FIELD_INTEGER ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS(logic_relay_queue, CLogicRelayQueue); + + +BEGIN_DATADESC( CLogicRelayQueue ) + + DEFINE_FIELD(m_bWaitForRefire, FIELD_BOOLEAN), + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"), + + DEFINE_INPUT(m_iMaxQueueItems, FIELD_INTEGER, "SetMaxQueueItems"), + DEFINE_KEYFIELD(m_bDontQueueWhenDisabled, FIELD_BOOLEAN, "DontQueueWhenDisabled"), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), + DEFINE_INPUTFUNC(FIELD_VOID, "EnableRefire", InputEnableRefire), + DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), + DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), + DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger), + DEFINE_INPUTFUNC(FIELD_INPUT, "TriggerWithParameter", InputTriggerWithParameter), + DEFINE_INPUTFUNC(FIELD_VOID, "CancelPending", InputCancelPending), + DEFINE_INPUTFUNC(FIELD_VOID, "ClearQueue", InputClearQueue), + + // Outputs + DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"), + DEFINE_OUTPUT(m_OnTriggerParameter, "OnTriggerParameter"), + + DEFINE_UTLVECTOR(m_QueueItems, FIELD_EMBEDDED), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CLogicRelayQueue::CLogicRelayQueue(void) +{ +} + + +//------------------------------------------------------------------------------ +// Purpose: Turns on the relay, allowing it to fire outputs. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; + + if (!m_bWaitForRefire && m_QueueItems.Count() > 0) + HandleNextQueueItem(); +} + +//------------------------------------------------------------------------------ +// Purpose: Enables us to fire again. This input is only posted from our Trigger +// function to prevent rapid refire. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputEnableRefire( inputdata_t &inputdata ) +{ + m_bWaitForRefire = false; + + if (!m_bDisabled && m_QueueItems.Count() > 0) + HandleNextQueueItem(); +} + + +//------------------------------------------------------------------------------ +// Purpose: Cancels any I/O events in the queue that were fired by us. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputCancelPending( inputdata_t &inputdata ) +{ + g_EventQueue.CancelEvents( this ); + + // Stop waiting; allow another Trigger. + m_bWaitForRefire = false; + + if (!m_bDisabled && m_QueueItems.Count() > 0) + HandleNextQueueItem(); +} + + +//------------------------------------------------------------------------------ +// Purpose: Clears the queue. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputClearQueue( inputdata_t &inputdata ) +{ + m_QueueItems.RemoveAll(); +} + + +//------------------------------------------------------------------------------ +// Purpose: Turns off the relay, preventing it from firing outputs. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + + +//------------------------------------------------------------------------------ +// Purpose: Toggles the enabled/disabled state of the relay. +//------------------------------------------------------------------------------ +void CLogicRelayQueue::InputToggle( inputdata_t &inputdata ) +{ + m_bDisabled = !m_bDisabled; + + if (!m_bDisabled && !m_bWaitForRefire && m_QueueItems.Count() > 0) + HandleNextQueueItem(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that triggers the relay. +//----------------------------------------------------------------------------- +void CLogicRelayQueue::InputTrigger( inputdata_t &inputdata ) +{ + if ((!m_bDisabled) && (!m_bWaitForRefire)) + { + m_OnTrigger.FireOutput( inputdata.pActivator, this ); + + // + // Disable the relay so that it cannot be refired until after the last output + // has been fired and post an input to re-enable ourselves. + // + m_bWaitForRefire = true; + g_EventQueue.AddEvent(this, "EnableRefire", m_OnTrigger.GetMaxDelay() + 0.001, this, this); + } + else if ( (!m_bDisabled || !m_bDontQueueWhenDisabled) && (m_QueueItems.Count() < m_iMaxQueueItems) ) + { + AddQueueItem(inputdata.pActivator, inputdata.nOutputID); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that triggers the relay. +//----------------------------------------------------------------------------- +void CLogicRelayQueue::InputTriggerWithParameter( inputdata_t &inputdata ) +{ + if ((!m_bDisabled) && (!m_bWaitForRefire)) + { + m_OnTriggerParameter.Set( inputdata.value, inputdata.pActivator, this ); + + // + // Disable the relay so that it cannot be refired until after the last output + // has been fired and post an input to re-enable ourselves. + // + m_bWaitForRefire = true; + g_EventQueue.AddEvent(this, "EnableRefire", m_OnTrigger.GetMaxDelay() + 0.001, this, this); + } + else if ( (!m_bDisabled || !m_bDontQueueWhenDisabled) && (m_QueueItems.Count() < m_iMaxQueueItems) ) + { + AddQueueItem(inputdata.pActivator, inputdata.nOutputID, inputdata.value); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Handles next queue item. +//----------------------------------------------------------------------------- +void CLogicRelayQueue::HandleNextQueueItem() +{ + LogicRelayQueueInfo_t info = m_QueueItems.Element(0); + + //if (!info.TriggerWithParameter) + //{ + // m_OnTrigger.FireOutput(info.pActivator, this); + //} + //else + //{ + // m_OnTriggerParameter.Set(info.value, info.pActivator, this); + //} + + AcceptInput(info.TriggerWithParameter ? "TriggerWithParameter" : "Trigger", info.pActivator, this, info.value, info.outputID); + + m_QueueItems.Remove(0); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds a queue item. +//----------------------------------------------------------------------------- +void CLogicRelayQueue::AddQueueItem(CBaseEntity *pActivator, int outputID, variant_t &value) +{ + LogicRelayQueueInfo_t info; + info.pActivator = pActivator; + info.outputID = outputID; + + info.value = value; + info.TriggerWithParameter = true; + + m_QueueItems.AddToTail(info); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds a queue item without a parameter. +//----------------------------------------------------------------------------- +void CLogicRelayQueue::AddQueueItem(CBaseEntity *pActivator, int outputID) +{ + LogicRelayQueueInfo_t info; + info.pActivator = pActivator; + info.outputID = outputID; + + info.TriggerWithParameter = false; + + m_QueueItems.AddToTail(info); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Output : Current text offset from the top +//----------------------------------------------------------------------------- +int CLogicRelayQueue::DrawDebugTextOverlays(void) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + // -------------- + // Print Target + // -------------- + char tempstr[255]; + + if (m_QueueItems.Count() > 0) + { + Q_snprintf(tempstr, sizeof(tempstr), "Queue Items: %i (%i)", m_QueueItems.Count(), m_iMaxQueueItems); + EntityText(text_offset, tempstr, 0); + text_offset++; + + for (int i = 0; i < m_QueueItems.Count(); i++) + { + Q_snprintf(tempstr, sizeof(tempstr), " Input: %s, Activator: %s, Output ID: %i", + m_QueueItems[i].TriggerWithParameter ? "TriggerWithParameter" : "Trigger", + m_QueueItems[i].pActivator ? m_QueueItems[i].pActivator->GetDebugName() : "None", + m_QueueItems[i].outputID); + EntityText(text_offset, tempstr, 0); + text_offset++; + } + } + else + { + Q_snprintf(tempstr, sizeof(tempstr), "Queue Items: 0 (%i)", m_iMaxQueueItems); + EntityText(text_offset, tempstr, 0); + text_offset++; } } + return text_offset; } +#endif diff --git a/game/server/logicrelay.h b/game/server/logicrelay.h index 8d082acc..00791579 100644 --- a/game/server/logicrelay.h +++ b/game/server/logicrelay.h @@ -13,6 +13,13 @@ #include "entityoutput.h" #include "eventqueue.h" +#ifdef MAPBASE + +// I was originally going to add something similar to that queue thing to logic_relay directly, but I later decided to relegate it to a derivative entity. +#define RELAY_QUEUE_SYSTEM 0 + +#endif + class CLogicRelay : public CLogicalEntity { public: @@ -25,16 +32,26 @@ class CLogicRelay : public CLogicalEntity // Input handlers void InputEnable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputEnableRefire( inputdata_t &inputdata ); +#else void InputEnableRefire( inputdata_t &inputdata ); // Private input handler, not in FGD +#endif void InputDisable( inputdata_t &inputdata ); void InputToggle( inputdata_t &inputdata ); void InputTrigger( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputTriggerWithParameter( inputdata_t &inputdata ); +#endif void InputCancelPending( inputdata_t &inputdata ); DECLARE_DATADESC(); // Outputs COutputEvent m_OnTrigger; +#ifdef MAPBASE + COutputVariant m_OnTriggerParameter; +#endif COutputEvent m_OnSpawn; bool IsDisabled( void ){ return m_bDisabled; } @@ -43,6 +60,66 @@ class CLogicRelay : public CLogicalEntity bool m_bDisabled; bool m_bWaitForRefire; // Set to disallow a refire while we are waiting for our outputs to finish firing. +#if RELAY_QUEUE_SYSTEM + bool m_bQueueTrigger; + bool m_bQueueWaiting; + float m_flRefireTime; +#endif +}; + +#ifdef MAPBASE +struct LogicRelayQueueInfo_t +{ + DECLARE_SIMPLE_DATADESC(); + + bool TriggerWithParameter; + CBaseEntity *pActivator; + variant_t value; + int outputID; +}; + +//#define LOGIC_RELAY_QUEUE_LIMIT 16 + +class CLogicRelayQueue : public CLogicalEntity +{ +public: + DECLARE_CLASS( CLogicRelayQueue, CLogicalEntity ); + + CLogicRelayQueue(); + + // Input handlers + void InputEnable( inputdata_t &inputdata ); + void InputEnableRefire( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + void InputTrigger( inputdata_t &inputdata ); + void InputTriggerWithParameter( inputdata_t &inputdata ); + void InputCancelPending( inputdata_t &inputdata ); + void InputClearQueue( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + + // Outputs + COutputEvent m_OnTrigger; + COutputVariant m_OnTriggerParameter; + + bool IsDisabled( void ){ return m_bDisabled; } + + void HandleNextQueueItem(); + void AddQueueItem(CBaseEntity *pActivator, int outputID, variant_t &value); + void AddQueueItem(CBaseEntity *pActivator, int outputID); + + int DrawDebugTextOverlays( void ); + +private: + + bool m_bDisabled; + bool m_bWaitForRefire; // Set to disallow a refire while we are waiting for our outputs to finish firing. + + int m_iMaxQueueItems; + bool m_bDontQueueWhenDisabled; // Don't add to queue while disabled, only when waiting for refire + CUtlVector m_QueueItems; }; +#endif #endif //LOGICRELAY_H diff --git a/game/server/mapbase/GlobalStrings.cpp b/game/server/mapbase/GlobalStrings.cpp new file mode 100644 index 00000000..4abd6f63 --- /dev/null +++ b/game/server/mapbase/GlobalStrings.cpp @@ -0,0 +1,100 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================== +// +// Purpose: See GlobalStrings.h for more information. +// +// $NoKeywords: $ +//============================================================================= + +#include "cbase.h" +#include "GlobalStrings.h" + + +// Global strings must be initially declared here. +// Be sure to sync them with the externs in GlobalStrings.h. + +// ------------------------------------------------------------- +// +// Classnames +// +// ------------------------------------------------------------- + +#ifdef HL2_DLL +string_t gm_isz_class_Shotgun; +string_t gm_isz_class_SMG1; +string_t gm_isz_class_AR2; +string_t gm_isz_class_Pistol; +string_t gm_isz_class_Stunstick; +string_t gm_isz_class_Crowbar; +string_t gm_isz_class_RPG; +string_t gm_isz_class_357; +string_t gm_isz_class_Grenade; +string_t gm_isz_class_Physcannon; +string_t gm_isz_class_Crossbow; + +string_t gm_isz_class_Strider; +string_t gm_isz_class_Gunship; +string_t gm_isz_class_Dropship; +string_t gm_isz_class_FloorTurret; +string_t gm_isz_class_CScanner; +string_t gm_isz_class_ClawScanner; +string_t gm_isz_class_Rollermine; +#endif + +string_t gm_isz_class_Bullseye; + +string_t gm_isz_class_PropPhysics; +string_t gm_isz_class_PropPhysicsOverride; +string_t gm_isz_class_FuncPhysbox; +string_t gm_isz_class_EnvFire; + +// ------------------------------------------------------------- + +string_t gm_isz_name_player; +string_t gm_isz_name_activator; + +// ------------------------------------------------------------- + +// ------------------------------------------------------------- + +// We know it hasn't been allocated yet +#define INITIALIZE_GLOBAL_STRING(string, text) string = AllocPooledString(text) //SetGlobalString(string, text) + +void InitGlobalStrings() +{ +#ifdef HL2_DLL + INITIALIZE_GLOBAL_STRING(gm_isz_class_Shotgun, "weapon_shotgun"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_SMG1, "weapon_smg1"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_AR2, "weapon_ar2"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Pistol, "weapon_pistol"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Stunstick, "weapon_stunstick"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Crowbar, "weapon_crowbar"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_RPG, "weapon_rpg"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_357, "weapon_357"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Grenade, "weapon_frag"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Physcannon, "weapon_physcannon"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Crossbow, "weapon_crossbow"); + + INITIALIZE_GLOBAL_STRING(gm_isz_class_Strider, "npc_strider"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Gunship, "npc_combinegunship"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Dropship, "npc_combinedropship"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_FloorTurret, "npc_turret_floor"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_CScanner, "npc_cscanner"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_ClawScanner, "npc_clawscanner"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_Rollermine, "npc_rollermine"); +#endif + + INITIALIZE_GLOBAL_STRING(gm_isz_class_Bullseye, "npc_bullseye"); + + INITIALIZE_GLOBAL_STRING(gm_isz_class_PropPhysics, "prop_physics"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_PropPhysicsOverride, "prop_physics_override"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_FuncPhysbox, "func_physbox"); + INITIALIZE_GLOBAL_STRING(gm_isz_class_EnvFire, "env_fire"); + + INITIALIZE_GLOBAL_STRING(gm_isz_name_player, "!player"); + INITIALIZE_GLOBAL_STRING(gm_isz_name_activator, "!activator"); +} + +// ------------------------------------------------------------- + + + diff --git a/game/server/mapbase/GlobalStrings.h b/game/server/mapbase/GlobalStrings.h new file mode 100644 index 00000000..13c4775a --- /dev/null +++ b/game/server/mapbase/GlobalStrings.h @@ -0,0 +1,86 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================== +// +// Purpose: Shared global string library. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef MAPBASE_GLOBAL_STRINGS_H +#define MAPBASE_GLOBAL_STRINGS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "cbase.h" + +// ------------------------------------------------------------- +// +// Valve uses global pooled strings in various parts of the code, particularly Episodic code, +// so they could get away with integer/pointer comparisons instead of string comparisons. +// +// This system was developed early in Mapbase's development as an attempt to make this technique more widely used. +// For the most part, this mainly just serves to apply micro-optimize parts of the code. +// +// ------------------------------------------------------------- + +// ------------------------------------------------------------- +// +// Classnames +// +// ------------------------------------------------------------- + +#ifdef HL2_DLL +extern string_t gm_isz_class_Shotgun; +extern string_t gm_isz_class_SMG1; +extern string_t gm_isz_class_AR2; +extern string_t gm_isz_class_Pistol; +extern string_t gm_isz_class_Stunstick; +extern string_t gm_isz_class_Crowbar; +extern string_t gm_isz_class_RPG; +extern string_t gm_isz_class_357; +extern string_t gm_isz_class_Grenade; +extern string_t gm_isz_class_Physcannon; +extern string_t gm_isz_class_Crossbow; + +extern string_t gm_isz_class_Strider; +extern string_t gm_isz_class_Gunship; +extern string_t gm_isz_class_Dropship; +extern string_t gm_isz_class_FloorTurret; +extern string_t gm_isz_class_CScanner; +extern string_t gm_isz_class_ClawScanner; +extern string_t gm_isz_class_Rollermine; +#endif + +extern string_t gm_isz_class_Bullseye; + +extern string_t gm_isz_class_PropPhysics; +extern string_t gm_isz_class_PropPhysicsOverride; +extern string_t gm_isz_class_FuncPhysbox; +extern string_t gm_isz_class_EnvFire; + +// ------------------------------------------------------------- + +extern string_t gm_isz_name_player; +extern string_t gm_isz_name_activator; + +// ------------------------------------------------------------- + +// Does the classname of this entity match the string_t? +// +// This function is for comparing global strings and allows us to change how we compare them quickly. +inline bool EntIsClass( CBaseEntity *ent, string_t str2 ) +{ + //return ent->ClassMatches(str2); + + // Since classnames are pooled, the global string and the entity's classname should point to the same string in memory. + // As long as this rule is preserved, we only need a pointer comparison. A string comparison isn't necessary. + return ent->m_iClassname == str2; +} + +// ------------------------------------------------------------- + +void InitGlobalStrings(); + +// ------------------------------------------------------------- + +#endif diff --git a/game/server/mapbase/SystemConvarMod.cpp b/game/server/mapbase/SystemConvarMod.cpp new file mode 100644 index 00000000..2ff4380e --- /dev/null +++ b/game/server/mapbase/SystemConvarMod.cpp @@ -0,0 +1,352 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mostly just Mapbase's convar mod code. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "saverestore_utlvector.h" +#include "SystemConvarMod.h" +#include "fmtstr.h" + +ConVar g_debug_convarmod( "g_debug_convarmod", "0" ); + +BEGIN_SIMPLE_DATADESC( modifiedconvars_t ) + DEFINE_ARRAY( pszConvar, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), + DEFINE_ARRAY( pszCurrentValue, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), + DEFINE_ARRAY( pszOrgValue, FIELD_CHARACTER, MAX_MODIFIED_CONVAR_STRING ), +END_DATADESC() + + +// ====================================================================== +// +// Everything below here is for the Mapbase convar mod system. +// ...which is based off of the Commentary convar mod system. +// +// ====================================================================== + +#define MAX_CONVARMOD_STRING_SIZE 512 + +CHandle m_hConvarsChanging; +CMapbaseCVarModEntity *ChangingCVars( void ) { return m_hConvarsChanging.Get(); } +void SetChangingCVars( CMapbaseCVarModEntity *hEnt ) { m_hConvarsChanging = hEnt; } + +CUtlVector< CHandle > m_ModEntities; +bool m_bModActive; + +void ConvarChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + ConVarRef var( pConVar ); + CMapbaseCVarModEntity *modent = ChangingCVars(); + + for ( int i = 0; i < m_ModEntities.Count(); i++ ) + { + if (!m_ModEntities[i]) + { + Warning("NULL mod entity at %i\n", i); + continue; + } + + if (m_ModEntities[i].Get()->NewCVar(&var, pOldString, modent)) + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CV_GlobalChange_Mapbase( IConVar *var, const char *pOldString, float flOldValue ) +{ + if ( !ChangingCVars() ) + { + // A convar has changed, but not due to Mapbase systems. Ignore it. + return; + } + + ConvarChanged( var, pOldString, flOldValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CC_MapbaseNotChangingCVars( void ) +{ + SetChangingCVars( NULL ); +} +static ConCommand mapbase_cvarsnotchanging("mapbase_cvarsnotchanging", CC_MapbaseNotChangingCVars, "An internal command used for ConVar modification.", FCVAR_HIDDEN); + +// ------------------------------------------------------------------------ + +void CV_InitMod() +{ + if (!m_bModActive) + { + cvar->InstallGlobalChangeCallback( CV_GlobalChange_Mapbase ); + m_bModActive = true; + } +} + +// ------------------------------------------------------------------------ + +void CVEnt_Precache(CMapbaseCVarModEntity *modent) +{ + // Now protected by FCVAR_NOT_CONNECTED + //if (Q_strstr(STRING(modent->m_target), "sv_allow_logic_convar")) + // return; + +#ifdef MAPBASE_MP + if (gpGlobals->maxClients > 1 && !modent->m_bUseServer) + { + Warning("WARNING: %s is using the local player in a multiplayer game and will not function.\n", modent->GetDebugName()); + } +#endif + + CV_InitMod(); +} +void CVEnt_Activate(CMapbaseCVarModEntity *modent) +{ + const char *pszCommands = STRING( modent->m_target ); + if ( Q_strnchr(pszCommands, '^', MAX_CONVARMOD_STRING_SIZE) ) + { + // Just like the commentary system, we convert ^s to "s here. + char szTmp[MAX_CONVARMOD_STRING_SIZE]; + Q_strncpy( szTmp, pszCommands, MAX_CONVARMOD_STRING_SIZE ); + int len = Q_strlen( szTmp ); + for ( int i = 0; i < len; i++ ) + { + if ( szTmp[i] == '^' ) + { + szTmp[i] = '"'; + } + } + + pszCommands = szTmp; + } + + CV_InitMod(); + + if (m_ModEntities.Find(modent) == m_ModEntities.InvalidIndex()) + m_ModEntities.AddToTail( modent ); + + if (modent->m_bUseServer) + { + SetChangingCVars( modent ); + + engine->ServerCommand( CFmtStr("%s\n", pszCommands) ); + engine->ServerCommand( "mapbase_cvarsnotchanging\n" ); + } + else + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + edict_t *edict = pPlayer ? pPlayer->edict() : NULL; + if (edict) + { + SetChangingCVars( modent ); + + engine->ClientCommand( edict, pszCommands ); + engine->ClientCommand( edict, "mapbase_cvarsnotchanging" ); + } + else + { + Warning("%s unable to find local player edict\n", modent->GetDebugName()); + } + } +} +void CVEnt_Deactivate(CMapbaseCVarModEntity *modent) +{ + // Remove our global convar callback + cvar->RemoveGlobalChangeCallback( CV_GlobalChange_Mapbase ); + + // Reset any convars that have been changed by the commentary + for ( int i = 0; i < modent->m_ModifiedConvars.Count(); i++ ) + { + ConVar *pConVar = (ConVar *)cvar->FindVar( modent->m_ModifiedConvars[i].pszConvar ); + if ( pConVar ) + { + pConVar->SetValue( modent->m_ModifiedConvars[i].pszOrgValue ); + } + } + + modent->m_ModifiedConvars.Purge(); + + if (m_bModActive) + { + m_ModEntities.FindAndRemove(modent); + + if (m_ModEntities.Count() == 0) + { + // No more mod entities + m_bModActive = false; + } + else + { + // We're done and we're still active, install our callback again + cvar->InstallGlobalChangeCallback( CV_GlobalChange_Mapbase ); + } + } +} +void CVEnt_Restore(CMapbaseCVarModEntity *modent) +{ + m_ModEntities.AddToTail(modent); +} + +// ------------------------------------------------------------------------ + + +LINK_ENTITY_TO_CLASS( game_convar_mod, CMapbaseCVarModEntity ); + +// This classname should be phased out after beta +LINK_ENTITY_TO_CLASS( mapbase_convar_mod, CMapbaseCVarModEntity ); + +BEGIN_DATADESC( CMapbaseCVarModEntity ) + + DEFINE_UTLVECTOR( m_ModifiedConvars, FIELD_EMBEDDED ), + DEFINE_KEYFIELD( m_bUseServer, FIELD_BOOLEAN, "UseServer" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ), + + DEFINE_THINKFUNC( CvarModActivate ), + +END_DATADESC() + + +void CMapbaseCVarModEntity::UpdateOnRemove() +{ + BaseClass::UpdateOnRemove(); + + CVEnt_Deactivate(this); +} + +void CMapbaseCVarModEntity::Precache( void ) +{ + BaseClass::Precache(); + + CVEnt_Precache(this); +} + +void CMapbaseCVarModEntity::Spawn( void ) +{ + BaseClass::Spawn(); + + if (m_target == NULL_STRING) + { + Warning("WARNING: %s has no cvars specified! Removing...\n", GetDebugName()); + UTIL_Remove(this); + return; + } + + Precache(); + + if (HasSpawnFlags(SF_CVARMOD_START_ACTIVATED)) + { + if (!m_bUseServer && !UTIL_GetLocalPlayer()) + { + // The local player doesn't exist yet, so we should wait until they do + SetThink( &CMapbaseCVarModEntity::CvarModActivate ); + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } + else + { + CVEnt_Activate( this ); + } + } +} + +void CMapbaseCVarModEntity::CvarModActivate() +{ + if (UTIL_GetLocalPlayer()) + { + CVEnt_Activate( this ); + } + else + { + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); + } +} + +void CMapbaseCVarModEntity::OnRestore( void ) +{ + BaseClass::OnRestore(); + + // Set any convars that have already been changed by the mapper before the save + if (m_ModifiedConvars.Count() > 0) + { + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + ConVar *pConVar = (ConVar *)cvar->FindVar( m_ModifiedConvars[i].pszConvar ); + if ( pConVar ) + { + if (g_debug_convarmod.GetBool()) + Msg(" %s Restoring Convar %s: value %s (org %s)\n", GetDebugName(), m_ModifiedConvars[i].pszConvar, m_ModifiedConvars[i].pszCurrentValue, m_ModifiedConvars[i].pszOrgValue ); + pConVar->SetValue( m_ModifiedConvars[i].pszCurrentValue ); + } + } + + CVEnt_Restore(this); + } +} + +void CMapbaseCVarModEntity::InputActivate(inputdata_t &inputdata) +{ + CVEnt_Activate(this); +} + +void CMapbaseCVarModEntity::InputDeactivate(inputdata_t &inputdata) +{ + CVEnt_Deactivate(this); +} + +bool CMapbaseCVarModEntity::NewCVar( ConVarRef *var, const char *pOldString, CBaseEntity *modent ) +{ + for (int i = 0; i < m_ModifiedConvars.Count(); i++) + { + // If we find it, just update the current value + modifiedconvars_t modvar = m_ModifiedConvars[i]; + if ( !Q_strncmp( var->GetName(), modvar.pszConvar, MAX_MODIFIED_CONVAR_STRING ) ) + { + if (modent == this) + { + Q_strncpy( modvar.pszCurrentValue, var->GetString(), MAX_MODIFIED_CONVAR_STRING ); + if (g_debug_convarmod.GetBool()) + Msg(" %s Updating Convar %s: value %s (org %s)\n", GetDebugName(), modvar.pszConvar, modvar.pszCurrentValue, modvar.pszOrgValue ); + return true; + } + else + { + // A different entity is using this CVar now, remove ours + m_ModifiedConvars.Remove(i); + if (g_debug_convarmod.GetBool()) + Msg(" %s Removing Convar %s: value %s (org %s)\n", GetDebugName(), modvar.pszConvar, modvar.pszCurrentValue, modvar.pszOrgValue ); + return false; + } + } + } + + // Did I do that? + if (modent == this) + { + // Add the CVar to our list. + modifiedconvars_t newConvar; + Q_strncpy( newConvar.pszConvar, var->GetName(), MAX_MODIFIED_CONVAR_STRING ); + Q_strncpy( newConvar.pszCurrentValue, var->GetString(), MAX_MODIFIED_CONVAR_STRING ); + Q_strncpy( newConvar.pszOrgValue, pOldString, MAX_MODIFIED_CONVAR_STRING ); + m_ModifiedConvars.AddToTail( newConvar ); + + if (g_debug_convarmod.GetBool()) + { + Msg(" %s changed '%s' to '%s' (was '%s')\n", GetDebugName(), var->GetName(), var->GetString(), pOldString ); + Msg(" Convars stored: %d\n", m_ModifiedConvars.Count() ); + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + Msg(" Convar %d: %s, value %s (org %s)\n", i, m_ModifiedConvars[i].pszConvar, m_ModifiedConvars[i].pszCurrentValue, m_ModifiedConvars[i].pszOrgValue ); + } + } + + return true; + } + + return false; +} diff --git a/game/server/mapbase/SystemConvarMod.h b/game/server/mapbase/SystemConvarMod.h new file mode 100644 index 00000000..faaafc27 --- /dev/null +++ b/game/server/mapbase/SystemConvarMod.h @@ -0,0 +1,49 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: modifiedconvarts_t from CommentarySystem.cpp moved to a header file so Mapbase can use it. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + + +// Convar restoration save/restore +#define MAX_MODIFIED_CONVAR_STRING 128 +struct modifiedconvars_t +{ + DECLARE_SIMPLE_DATADESC(); + + char pszConvar[MAX_MODIFIED_CONVAR_STRING]; + char pszCurrentValue[MAX_MODIFIED_CONVAR_STRING]; + char pszOrgValue[MAX_MODIFIED_CONVAR_STRING]; +}; + +// --------------------------------------------------------------------- + +#define SF_CVARMOD_START_ACTIVATED (1 << 0) + +class CMapbaseCVarModEntity : public CPointEntity +{ +public: + DECLARE_CLASS( CMapbaseCVarModEntity, CPointEntity ); + + void UpdateOnRemove(); + + void Precache( void ); + + void Spawn( void ); + void CvarModActivate(); + + void OnRestore( void ); + + void InputActivate(inputdata_t &inputdata); + void InputDeactivate(inputdata_t &inputdata); + + bool NewCVar( ConVarRef *var, const char *pOldString, CBaseEntity *modent ); + + CUtlVector< modifiedconvars_t > m_ModifiedConvars; + bool m_bUseServer; + + DECLARE_DATADESC(); +}; diff --git a/game/server/mapbase/ai_grenade.cpp b/game/server/mapbase/ai_grenade.cpp new file mode 100644 index 00000000..a9ff5302 --- /dev/null +++ b/game/server/mapbase/ai_grenade.cpp @@ -0,0 +1,15 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" + +#include "ai_grenade.h" + + +int COMBINE_AE_BEGIN_ALTFIRE; +int COMBINE_AE_ALTFIRE; + +ConVar ai_grenade_always_drop( "ai_grenade_always_drop", "0", FCVAR_NONE, "Causes non-Combine grenade user NPCs to be allowed to drop grenades, alt-fire items, etc. *IF* the keyvalue has not already been set in Hammer. This is useful for debugging purposes or if a mod which was developed before this feature was introduced wants its NPCs to drop grenades and beyond without recompiling all of the maps." ); diff --git a/game/server/mapbase/ai_grenade.h b/game/server/mapbase/ai_grenade.h new file mode 100644 index 00000000..543969c2 --- /dev/null +++ b/game/server/mapbase/ai_grenade.h @@ -0,0 +1,863 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef AI_GRENADE_H +#define AI_GRENADE_H +#ifdef _WIN32 +#pragma once +#endif + +// I wish I didn't have to #include all this, but I don't really have a choice. +// I guess something similar to CAI_BehaviorHost's backbridges could be tried. +#include "cbase.h" +#include "ai_basenpc.h" +#include "npcevent.h" +#include "grenade_frag.h" +#include "basegrenade_shared.h" +#include "ai_squad.h" +#include "GlobalStrings.h" +#include "gameweaponmanager.h" +#include "hl2_gamerules.h" +#include "weapon_physcannon.h" +#include "globalstate.h" + +#define COMBINE_AE_GREN_TOSS ( 7 ) + +#define COMBINE_GRENADE_THROW_SPEED 650 +#define COMBINE_GRENADE_TIMER 3.5 +#define COMBINE_GRENADE_FLUSH_TIME 3.0 // Don't try to flush an enemy who has been out of sight for longer than this. +#define COMBINE_GRENADE_FLUSH_DIST 256.0 // Don't try to flush an enemy who has moved farther than this distance from the last place I saw him. + +#define COMBINE_MIN_GRENADE_CLEAR_DIST 250 + +#define DEFINE_AIGRENADE_DATADESC() \ + DEFINE_KEYFIELD( m_iNumGrenades, FIELD_INTEGER, "NumGrenades" ), \ + DEFINE_FIELD( m_flNextGrenadeCheck, FIELD_TIME ), \ + DEFINE_FIELD( m_hForcedGrenadeTarget, FIELD_EHANDLE ), \ + DEFINE_FIELD( m_flNextAltFireTime, FIELD_TIME ), \ + DEFINE_FIELD( m_vecAltFireTarget, FIELD_VECTOR ), \ + DEFINE_FIELD( m_vecTossVelocity, FIELD_VECTOR ), \ + DEFINE_FIELD( m_iLastAnimEventHandled, FIELD_INTEGER ), \ + DEFINE_INPUTFUNC( FIELD_STRING, "ThrowGrenadeAtTarget", InputThrowGrenadeAtTarget ), \ + DEFINE_INPUTFUNC( FIELD_STRING, "ThrowGrenadeGestureAtTarget", InputThrowGrenadeGestureAtTarget ), \ + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetGrenades", InputSetGrenades ), \ + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddGrenades", InputAddGrenades ), \ + DEFINE_OUTPUT(m_OnThrowGrenade, "OnThrowGrenade"), \ + DEFINE_OUTPUT(m_OnOutOfGrenades, "OnOutOfGrenades"), \ + +// Use extern float GetCurrentGravity( void ); +#define SMGGrenadeArc(shootpos, targetpos) \ + Vector vecShootPos = shootpos; \ + Vector vecThrow = (targetpos - vecShootPos); \ + float time = vecThrow.Length() / 600.0; \ + vecThrow = vecThrow * (1.0 / time); \ + vecThrow.z += (GetCurrentGravity() * 0.5) * time * 0.5; \ + Vector vecFace = vecShootPos + (vecThrow * 0.5); \ + AddFacingTarget(vecFace, 1.0, 0.5); \ + +// Mask used for Combine ball hull traces. +// This used MASK_SHOT before, but this has been changed to MASK_SHOT_HULL. +// This fixes the existing problem of soldiers trying to fire energy balls through grates, +// but it's also important to prevent soldiers from blowing themselves up with their newfound SMG grenades. +#define MASK_COMBINE_BALL_LOS MASK_SHOT_HULL + +extern int COMBINE_AE_BEGIN_ALTFIRE; +extern int COMBINE_AE_ALTFIRE; + +extern ConVar ai_grenade_always_drop; + +enum eGrenadeCapabilities +{ + GRENCAP_GRENADE = (1 << 0), + GRENCAP_ALTFIRE = (1 << 1), +}; + +// What grenade/item types NPCs are capable of dropping +enum eGrenadeDropCapabilities +{ + GRENDROPCAP_GRENADE = (1 << 0), + GRENDROPCAP_ALTFIRE = (1 << 1), + GRENDROPCAP_INTERRUPTED = (1 << 2), // Drops grenades when interrupted mid-animation +}; + +//----------------------------------------------------------------------------- +// Other classes can use this and access some CAI_GrenadeUser functions. +//----------------------------------------------------------------------------- +class CAI_GrenadeUserSink +{ +public: + CAI_GrenadeUserSink() { } + + virtual bool UsingOnThrowGrenade() { return false; } +}; + +//----------------------------------------------------------------------------- +// +// Template class for NPCs using grenades or weapon alt-fire stuff. +// You'll still have to use DEFINE_AIGRENADE_DATADESC() in your derived class's datadesc. +// +// I wanted to have these functions defined in a CPP file, but template class definitions must be in the header. +// Please excuse the bloat below the class definition. +// +//----------------------------------------------------------------------------- +template +class CAI_GrenadeUser : public BASE_NPC, public CAI_GrenadeUserSink +{ + DECLARE_CLASS_NOFRIEND( CAI_GrenadeUser, BASE_NPC ); + +public: + CAI_GrenadeUser() : CAI_GrenadeUserSink() { } + + void AddGrenades( int inc, CBaseEntity *pLastGrenade = NULL ) + { + m_iNumGrenades += inc; + if (m_iNumGrenades <= 0) + m_OnOutOfGrenades.Set( pLastGrenade, pLastGrenade, this ); + } + + // Use secondary ammo as a way of checking if this is a weapon which can be alt-fired (e.g. AR2 or SMG) + virtual bool IsAltFireCapable() { return (this->GetActiveWeapon() && this->GetActiveWeapon()->UsesSecondaryAmmo()); } + virtual bool IsGrenadeCapable() { return true; } + inline bool HasGrenades() { return m_iNumGrenades > 0; } + + void InputSetGrenades( inputdata_t &inputdata ) { AddGrenades( inputdata.value.Int() - m_iNumGrenades ); } + void InputAddGrenades( inputdata_t &inputdata ) { AddGrenades( inputdata.value.Int() ); } + void InputThrowGrenadeAtTarget( inputdata_t &inputdata ); + void InputThrowGrenadeGestureAtTarget( inputdata_t &inputdata ); + + virtual void DelayGrenadeCheck( float delay ) { m_flNextGrenadeCheck = gpGlobals->curtime + delay; } + + void HandleAnimEvent( animevent_t *pEvent ); + void SetActivity( Activity NewActivity ); + + // Soldiers use "lefthand", cops use "LHand", and citizens use "anim_attachment_LH" + virtual const char* GetGrenadeAttachment() { return "anim_attachment_LH"; } + + void ClearAttackConditions( void ); + + Vector GetAltFireTarget() { return m_vecAltFireTarget; } + virtual bool CanAltFireEnemy( bool bUseFreeKnowledge ); + void DelayAltFireAttack( float flDelay ); + void DelaySquadAltFireAttack( float flDelay ); + + virtual bool CanGrenadeEnemy( bool bUseFreeKnowledge = true ); + bool CanThrowGrenade( const Vector &vecTarget ); + bool CheckCanThrowGrenade( const Vector &vecTarget ); + + // For OnThrowGrenade + point_entity_replace, see grenade_frag.cpp + bool UsingOnThrowGrenade() { return m_OnThrowGrenade.NumberOfElements() > 0; } + + // For dropping grenades and beyond + void DropGrenadeItemsOnDeath( const CTakeDamageInfo &info, CBasePlayer *pPlayer ); + virtual bool ShouldDropGrenades() { return HasGrenades(); } + virtual bool ShouldDropInterruptedGrenades() { return true; } + virtual bool ShouldDropAltFire() { return HasGrenades(); } + +protected: + + void StartTask_FaceAltFireTarget( const Task_t *pTask ); + void StartTask_GetPathToForced( const Task_t *pTask ); + void StartTask_DeferSquad( const Task_t *pTask ); + + void RunTask_FaceAltFireTarget( const Task_t *pTask ); + void RunTask_GetPathToForced( const Task_t *pTask ); + void RunTask_FaceTossDir( const Task_t *pTask ); + +protected: // We can't have any private saved variables because only derived classes use the datadescs + + int m_iNumGrenades; + float m_flNextGrenadeCheck; + EHANDLE m_hForcedGrenadeTarget; + + float m_flNextAltFireTime; + Vector m_vecAltFireTarget; + Vector m_vecTossVelocity; + + // CNPC_Combine port for determining if we tossed a grenade + int m_iLastAnimEventHandled; + + COutputEHANDLE m_OnThrowGrenade; + COutputEHANDLE m_OnOutOfGrenades; +}; + +//------------------------------------------------------------------------------ +// Purpose: Handle animation events +//------------------------------------------------------------------------------ +template +void CAI_GrenadeUser::HandleAnimEvent( animevent_t *pEvent ) +{ + if ( pEvent->event == COMBINE_AE_BEGIN_ALTFIRE ) + { + if (this->GetActiveWeapon()) + this->GetActiveWeapon()->WeaponSound( SPECIAL1 ); + + m_iLastAnimEventHandled = pEvent->event; + + //SpeakIfAllowed( TLK_CMB_THROWGRENADE, "altfire:1" ); + return; + } + if ( pEvent->event == COMBINE_AE_ALTFIRE ) + { + animevent_t fakeEvent; + + fakeEvent.pSource = this; + fakeEvent.event = EVENT_WEAPON_AR2_ALTFIRE; + + // Weapon could've been dropped while playing animation + if (this->GetActiveWeapon()) + this->GetActiveWeapon()->Operator_HandleAnimEvent( &fakeEvent, this ); + + // Stop other squad members from combine balling for a while. + DelaySquadAltFireAttack( 10.0f ); + + AddGrenades(-1); + + m_iLastAnimEventHandled = pEvent->event; + + return; + } + + if ( pEvent->event == COMBINE_AE_GREN_TOSS ) + { + Vector vecSpin; + vecSpin.x = random->RandomFloat( -1000.0, 1000.0 ); + vecSpin.y = random->RandomFloat( -1000.0, 1000.0 ); + vecSpin.z = random->RandomFloat( -1000.0, 1000.0 ); + + Vector vecStart; + this->GetAttachment( GetGrenadeAttachment(), vecStart ); + + if( this->GetState() == NPC_STATE_SCRIPT ) + { + // Use a fixed velocity for grenades thrown in scripted state. + // Grenades thrown from a script do not count against grenades remaining for the AI to use. + Vector forward, up, vecThrow; + + this->GetVectors( &forward, NULL, &up ); + vecThrow = forward * 750 + up * 175; + + // This code is used by player allies now, so it's only "combine spawned" if the thrower isn't allied with the player. + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, !this->IsPlayerAlly() ); + m_OnThrowGrenade.Set(pGrenade, pGrenade, this); + } + else + { + // Use the Velocity that AI gave us. + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, !this->IsPlayerAlly() ); + m_OnThrowGrenade.Set(pGrenade, pGrenade, this); + AddGrenades(-1, pGrenade); + } + + // wait six seconds before even looking again to see if a grenade can be thrown. + m_flNextGrenadeCheck = gpGlobals->curtime + 6; + + m_iLastAnimEventHandled = pEvent->event; + + return; + } + + BaseClass::HandleAnimEvent( pEvent ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::SetActivity( Activity NewActivity ) +{ + BaseClass::SetActivity( NewActivity ); + + m_iLastAnimEventHandled = -1; +} + +//----------------------------------------------------------------------------- +// Purpose: Force the combine soldier to throw a grenade at the target +// If I'm a combine elite, fire my combine ball at the target instead. +// Input : &inputdata - +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::InputThrowGrenadeAtTarget( inputdata_t &inputdata ) +{ + // Ignore if we're inside a scripted sequence + if ( this->GetState() == NPC_STATE_SCRIPT && this->m_hCine ) + return; + + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); + if ( !pEntity ) + { + DevMsg("%s (%s) received ThrowGrenadeAtTarget input, but couldn't find target entity '%s'\n", this->GetClassname(), this->GetDebugName(), inputdata.value.String() ); + return; + } + + m_hForcedGrenadeTarget = pEntity; + m_flNextGrenadeCheck = 0; + + this->ClearSchedule( "Told to throw grenade via input" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Force the combine soldier to throw a grenade at the target using the gesture animation. +// If I'm a combine elite, fire my combine ball at the target instead. +// Input : &inputdata - +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::InputThrowGrenadeGestureAtTarget( inputdata_t &inputdata ) +{ + // Ignore if we're inside a scripted sequence + //if ( this->GetState() == NPC_STATE_SCRIPT && this->m_hCine ) + // return; + + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); + if ( !pEntity ) + { + DevMsg("%s (%s) received ThrowGrenadeGestureAtTarget input, but couldn't find target entity '%s'\n", this->GetClassname(), this->GetDebugName(), inputdata.value.String() ); + return; + } + + m_hForcedGrenadeTarget = pEntity; + m_flNextGrenadeCheck = 0; + + Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); + +#if SHARED_COMBINE_ACTIVITIES + if (IsAltFireCapable()) + { + if (this->FVisible( m_hForcedGrenadeTarget )) + { + m_vecAltFireTarget = vecTarget; + m_hForcedGrenadeTarget = NULL; + + int iLayer = this->AddGesture( ACT_GESTURE_COMBINE_AR2_ALTFIRE ); + if (iLayer != -1) + { + this->GetShotRegulator()->FireNoEarlierThan( gpGlobals->curtime + this->GetLayerDuration( iLayer ) ); + } + } + } + else + { + // If we can, throw a grenade at the target. + // Ignore grenade count / distance / etc + if (CheckCanThrowGrenade( vecTarget )) + { + int iLayer = this->AddGesture( ACT_GESTURE_COMBINE_THROW_GRENADE ); + if (iLayer != -1) + { + this->GetShotRegulator()->FireNoEarlierThan( gpGlobals->curtime + this->GetLayerDuration( iLayer ) ); + } + } + } +#else + Warning("Gesture grenades/alt-fire not supported\n"); +#endif +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +bool CAI_GrenadeUser::CanAltFireEnemy( bool bUseFreeKnowledge ) +{ + if (!HasGrenades()) + return false; + + if (!IsAltFireCapable()) + return false; + + if (!this->GetActiveWeapon()) + return false; + + if (this->IsCrouching()) + return false; + + if ( gpGlobals->curtime < m_flNextAltFireTime || gpGlobals->curtime < m_flNextGrenadeCheck ) + return false; + + if( !this->GetEnemy() ) + return false; + + if (!EntIsClass(this->GetActiveWeapon(), gm_isz_class_AR2) && !EntIsClass(this->GetActiveWeapon(), gm_isz_class_SMG1)) + return false; + + CBaseEntity *pEnemy = this->GetEnemy(); + + Vector vecTarget; + + // Determine what point we're shooting at + if( bUseFreeKnowledge ) + { + vecTarget = this->GetEnemies()->LastKnownPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest + } + else + { + vecTarget = this->GetEnemies()->LastSeenPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest + } + + // Trace a hull about the size of the combine ball (don't shoot through grates!) + trace_t tr; + + Vector mins( -12, -12, -12 ); + Vector maxs( 12, 12, 12 ); + + Vector vShootPosition = this->EyePosition(); + + if ( this->GetActiveWeapon() ) + { + this->GetActiveWeapon()->GetAttachment( "muzzle", vShootPosition ); + } + + // Trace a hull about the size of the combine ball. + UTIL_TraceHull( vShootPosition, vecTarget, mins, maxs, MASK_COMBINE_BALL_LOS, this, COLLISION_GROUP_NONE, &tr ); + + float flLength = (vShootPosition - vecTarget).Length(); + + flLength *= tr.fraction; + + // If the ball can travel at least 65% of the distance to the player then let the NPC shoot it. + // (unless it hit the world) + if( tr.fraction >= 0.65 && (!tr.m_pEnt || !tr.m_pEnt->IsWorld()) && flLength > 128.0f ) + { + // Target is valid + m_vecAltFireTarget = vecTarget; + return true; + } + + + // Check again later + m_vecAltFireTarget = vec3_origin; + m_flNextGrenadeCheck = gpGlobals->curtime + 1.0f; + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::DelayAltFireAttack( float flDelay ) +{ + float flNextAltFire = gpGlobals->curtime + flDelay; + + if( flNextAltFire > m_flNextAltFireTime ) + { + // Don't let this delay order preempt a previous request to wait longer. + m_flNextAltFireTime = flNextAltFire; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::DelaySquadAltFireAttack( float flDelay ) +{ + // Make sure to delay my own alt-fire attack. + DelayAltFireAttack( flDelay ); + + AISquadIter_t iter; + CAI_Squad *pSquad = this->GetSquad(); + CAI_BaseNPC *pSquadmate = pSquad ? pSquad->GetFirstMember( &iter ) : NULL; + while ( pSquadmate ) + { + CAI_GrenadeUser *pUser = dynamic_cast(pSquadmate); + if( pUser && pUser->IsAltFireCapable() ) + { + pUser->DelayAltFireAttack( flDelay ); + } + + pSquadmate = pSquad->GetNextMember( &iter ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +bool CAI_GrenadeUser::CanGrenadeEnemy( bool bUseFreeKnowledge ) +{ + CBaseEntity *pEnemy = this->GetEnemy(); + + Assert( pEnemy != NULL ); + + if( pEnemy ) + { + // I'm not allowed to throw grenades during dustoff + if ( this->IsCurSchedule(SCHED_DROPSHIP_DUSTOFF) ) + return false; + + if( bUseFreeKnowledge ) + { + // throw to where we think they are. + return CanThrowGrenade( this->GetEnemies()->LastKnownPosition( pEnemy ) ); + } + else + { + // hafta throw to where we last saw them. + return CanThrowGrenade( this->GetEnemies()->LastSeenPosition( pEnemy ) ); + } + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Return true if the combine has grenades, hasn't checked lately, and +// can throw a grenade at the target point. +// Input : &vecTarget - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +template +bool CAI_GrenadeUser::CanThrowGrenade( const Vector &vecTarget ) +{ + if( m_iNumGrenades < 1 ) + { + // Out of grenades! + return false; + } + + if (!IsGrenadeCapable()) + { + // Must be capable of throwing grenades + return false; + } + + if ( gpGlobals->curtime < m_flNextGrenadeCheck ) + { + // Not allowed to throw another grenade right now. + return false; + } + + float flDist; + flDist = ( vecTarget - this->GetAbsOrigin() ).Length(); + + if( flDist > 1024 || flDist < 128 ) + { + // Too close or too far! + m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second. + return false; + } + + // ----------------------- + // If moving, don't check. + // ----------------------- + if ( this->m_flGroundSpeed != 0 ) + return false; + + // --------------------------------------------------------------------- + // Are any of my squad members near the intended grenade impact area? + // --------------------------------------------------------------------- + CAI_Squad *pSquad = this->GetSquad(); + if ( pSquad ) + { + if (pSquad->SquadMemberInRange( vecTarget, COMBINE_MIN_GRENADE_CLEAR_DIST )) + { + // crap, I might blow my own guy up. Don't throw a grenade and don't check again for a while. + m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second. + + // Tell my squad members to clear out so I can get a grenade in + // Mapbase uses a new context here that gets all nondescript allies away since this code is shared between Combine and non-Combine now. + CSoundEnt::InsertSound( SOUND_MOVE_AWAY | SOUND_CONTEXT_OWNER_ALLIES, vecTarget, COMBINE_MIN_GRENADE_CLEAR_DIST, 0.1, this ); + return false; + } + } + + return CheckCanThrowGrenade( vecTarget ); +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the combine can throw a grenade at the specified target point +// Input : &vecTarget - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +template +bool CAI_GrenadeUser::CheckCanThrowGrenade( const Vector &vecTarget ) +{ + //NDebugOverlay::Line( this->EyePosition(), vecTarget, 0, 255, 0, false, 5 ); + + // --------------------------------------------------------------------- + // Check that throw is legal and clear + // --------------------------------------------------------------------- + // FIXME: this is only valid for hand grenades, not RPG's + Vector vecToss; + Vector vecMins = -Vector(4,4,4); + Vector vecMaxs = Vector(4,4,4); + if( this->FInViewCone( vecTarget ) && CBaseEntity::FVisible( vecTarget ) ) + { + vecToss = VecCheckThrow( this, this->EyePosition(), vecTarget, COMBINE_GRENADE_THROW_SPEED, 1.0, &vecMins, &vecMaxs ); + } + else + { + // Have to try a high toss. Do I have enough room? + trace_t tr; + AI_TraceLine( this->EyePosition(), this->EyePosition() + Vector( 0, 0, 64 ), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); + if( tr.fraction != 1.0 ) + { + return false; + } + + vecToss = VecCheckToss( this, this->EyePosition(), vecTarget, -1, 1.0, true, &vecMins, &vecMaxs ); + } + + if ( vecToss != vec3_origin ) + { + m_vecTossVelocity = vecToss; + + // don't check again for a while. + m_flNextGrenadeCheck = gpGlobals->curtime + 1; // 1/3 second. + return true; + } + else + { + // don't check again for a while. + m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second. + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: This was copied from soldier code for general AI grenades. +// +// "Soldiers use CAN_RANGE_ATTACK2 to indicate whether they can throw +// a grenade. Because they check only every half-second or so, this +// condition must persist until it is updated again by the code +// that determines whether a grenade can be thrown, so prevent the +// base class from clearing it out. (sjb)" +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::ClearAttackConditions() +{ + bool fCanRangeAttack2 = IsGrenadeCapable() && this->HasCondition( COND_CAN_RANGE_ATTACK2 ); + + // Call the base class. + BaseClass::ClearAttackConditions(); + + if( fCanRangeAttack2 ) + { + // We don't allow the base class to clear this condition because we + // don't sense for it every frame. + this->SetCondition( COND_CAN_RANGE_ATTACK2 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Drops grenades and alt-fire items on death. Based on code from npc_combines.cpp and npc_combine.cpp +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::DropGrenadeItemsOnDeath( const CTakeDamageInfo &info, CBasePlayer *pPlayer ) +{ + // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. + if( IsAltFireCapable() && ShouldDropAltFire() ) + { + CBaseEntity *pItem; + if (this->GetActiveWeapon() && FClassnameIs( this->GetActiveWeapon(), "weapon_smg1" )) + pItem = this->DropItem( "item_ammo_smg1_grenade", this->WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); + else + pItem = this->DropItem( "item_ammo_ar2_altfire", this->WorldSpaceCenter() + RandomVector( -4, 4 ), RandomAngle( 0, 360 ) ); + + if ( pItem ) + { + IPhysicsObject *pObj = pItem->VPhysicsGetObject(); + + if ( pObj ) + { + Vector vel = RandomVector( -64.0f, 64.0f ); + AngularImpulse angImp = RandomAngularImpulse( -300.0f, 300.0f ); + + vel[2] = 0.0f; + pObj->AddVelocity( &vel, &angImp ); + } + + if( info.GetDamageType() & DMG_DISSOLVE ) + { + CBaseAnimating *pAnimating = dynamic_cast(pItem); + + if( pAnimating ) + { + pAnimating->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); + } + } + else + { + WeaponManager_AddManaged( pItem ); + } + } + } + + if ( IsGrenadeCapable() ) + { + if ( ShouldDropGrenades() ) + { + CHalfLife2 *pHL2GameRules = static_cast(g_pGameRules); + + // Attempt to drop a grenade + if ( pHL2GameRules->NPC_ShouldDropGrenade( pPlayer ) ) + { + this->DropItem( "weapon_frag", this->WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); + pHL2GameRules->NPC_DroppedGrenade(); + } + } + + // if I was killed before I could finish throwing my grenade, drop + // a grenade item that the player can retrieve. + if (this->GetActivity() == ACT_RANGE_ATTACK2 && ShouldDropInterruptedGrenades()) + { + if( m_iLastAnimEventHandled != COMBINE_AE_GREN_TOSS ) + { + // Drop the grenade as an item. + Vector vecStart; + this->GetAttachment( GetGrenadeAttachment(), vecStart ); + + CBaseEntity *pItem = this->DropItem( "weapon_frag", vecStart, RandomAngle(0,360) ); + + if ( pItem ) + { + IPhysicsObject *pObj = pItem->VPhysicsGetObject(); + + if ( pObj ) + { + Vector vel; + vel.x = random->RandomFloat( -100.0f, 100.0f ); + vel.y = random->RandomFloat( -100.0f, 100.0f ); + vel.z = random->RandomFloat( 800.0f, 1200.0f ); + AngularImpulse angImp = RandomAngularImpulse( -300.0f, 300.0f ); + + vel[2] = 0.0f; + pObj->AddVelocity( &vel, &angImp ); + } + + // In the Citadel we need to dissolve this + if ( PlayerHasMegaPhysCannon() && GlobalEntity_GetCounter("super_phys_gun") != 1 ) + { + CBaseCombatWeapon *pWeapon = static_cast(pItem); + + pWeapon->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); + } + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Task helpers +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::StartTask_FaceAltFireTarget( const Task_t *pTask ) +{ + this->SetIdealActivity( (Activity)(int)pTask->flTaskData ); + this->GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED ); +} + +template +void CAI_GrenadeUser::StartTask_GetPathToForced( const Task_t *pTask ) +{ + if ( !m_hForcedGrenadeTarget ) + { + this->TaskFail(FAIL_NO_ENEMY); + return; + } + + float flMaxRange = 2000; + float flMinRange = 0; + + Vector vecEnemy = m_hForcedGrenadeTarget->GetAbsOrigin(); + Vector vecEnemyEye = vecEnemy + m_hForcedGrenadeTarget->GetViewOffset(); + + Vector posLos; + bool found = false; + + if ( this->GetTacticalServices()->FindLateralLos( vecEnemyEye, &posLos ) ) + { + float dist = ( posLos - vecEnemyEye ).Length(); + if ( dist < flMaxRange && dist > flMinRange ) + found = true; + } + + if ( !found && this->GetTacticalServices()->FindLos( vecEnemy, vecEnemyEye, flMinRange, flMaxRange, 1.0, &posLos ) ) + { + found = true; + } + + if ( !found ) + { + this->TaskFail( FAIL_NO_SHOOT ); + } + else + { + // else drop into run task to offer an interrupt + this->m_vInterruptSavePosition = posLos; + } +} + +template +void CAI_GrenadeUser::StartTask_DeferSquad( const Task_t *pTask ) +{ + CAI_Squad *pSquad = this->GetSquad(); + if ( pSquad ) + { + // iterate my squad and stop everyone from throwing grenades for a little while. + AISquadIter_t iter; + + CAI_BaseNPC *pSquadmate = pSquad ? pSquad->GetFirstMember( &iter ) : NULL; + while ( pSquadmate ) + { + pSquadmate->DelayGrenadeCheck(5); + + pSquadmate = pSquad->GetNextMember( &iter ); + } + } + + this->TaskComplete(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +void CAI_GrenadeUser::RunTask_FaceAltFireTarget( const Task_t *pTask ) +{ + this->GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED ); + + // New Mapbase thing that fixes forced alt-fires not changing weapon yaw/pitch + this->SetAim( m_vecAltFireTarget - this->Weapon_ShootPosition() ); + + if (this->IsActivityFinished()) + { + this->TaskComplete(); + } +} + +template +void CAI_GrenadeUser::RunTask_GetPathToForced( const Task_t *pTask ) +{ + if ( !m_hForcedGrenadeTarget ) + { + this->TaskFail(FAIL_NO_ENEMY); + return; + } + + if ( this->GetTaskInterrupt() > 0 ) + { + this->ClearTaskInterrupt(); + + Vector vecEnemy = m_hForcedGrenadeTarget->GetAbsOrigin(); + AI_NavGoal_t goal( this->m_vInterruptSavePosition, ACT_RUN, AIN_HULL_TOLERANCE ); + + this->GetNavigator()->SetGoal( goal, AIN_CLEAR_TARGET ); + this->GetNavigator()->SetArrivalDirection( vecEnemy - goal.dest ); + } + else + { + this->TaskInterrupt(); + } +} + +template +void CAI_GrenadeUser::RunTask_FaceTossDir( const Task_t *pTask ) +{ + // project a point along the toss vector and turn to face that point. + this->GetMotor()->SetIdealYawToTargetAndUpdate( this->GetLocalOrigin() + m_vecTossVelocity * 64, AI_KEEP_YAW_SPEED ); + + if ( this->FacingIdeal() ) + { + this->TaskComplete( true ); + } +} + +#endif diff --git a/game/server/mapbase/ai_monitor.cpp b/game/server/mapbase/ai_monitor.cpp new file mode 100644 index 00000000..fa11a203 --- /dev/null +++ b/game/server/mapbase/ai_monitor.cpp @@ -0,0 +1,742 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: An entity that watches an NPC for certain things. +// +//============================================================================= + +#include "cbase.h" +#include "ai_schedule.h" +#include "ai_hint.h" +#include "ai_route.h" +#include "ai_basenpc.h" +#include "saverestore_utlvector.h" + + +//#define AI_MONITOR_MAX_TARGETS 16 + +// Uses a CUtlVector instead of a CBitVec for conditions/schedules. +// Using a CUtlVector makes this a lot easier, if you ask me. Please note that the CBitVec version is incomplete. +#define AI_MONITOR_USE_UTLVECTOR 1 + +//----------------------------------------------------------------------------- +// Purpose: AI monitoring. Probably bad. +//----------------------------------------------------------------------------- +class CAI_Monitor : public CLogicalEntity +{ + DECLARE_CLASS( CAI_Monitor, CLogicalEntity ); +public: + CAI_Monitor(); + + void Spawn(); + void Activate( void ); + + virtual int Save( ISave &save ); + virtual int Restore( IRestore &restore ); +#if !AI_MONITOR_USE_UTLVECTOR + void SaveConditions( ISave &save, const CAI_ScheduleBits &conditions ); + void RestoreConditions( IRestore &restore, CAI_ScheduleBits *pConditions ); +#endif + + virtual bool KeyValue( const char *szKeyName, const char *szValue ); + //virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + + // Populates our NPC list. + void PopulateNPCs(inputdata_t *inputdata); + + // Does evaluation, fires outputs, etc. + bool NPCDoEval(CAI_BaseNPC *pNPC); + + // Thinks. + void MonitorThink(); + + CAI_BaseNPC *GetFirstTarget(); + + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); PopulateNPCs(&inputdata); } + void InputPopulateNPCs( inputdata_t &inputdata ); + void InputTest( inputdata_t &inputdata ); + void InputTestNPC( inputdata_t &inputdata ); + + // Allows mappers to get condition/schedule names from ID + void InputGetConditionName( inputdata_t &inputdata ) { m_OutConditionName.Set(AllocPooledString(ConditionName(inputdata.value.Int())), inputdata.pActivator, this); } + void InputGetScheduleName( inputdata_t &inputdata ) { m_OutScheduleName.Set(AllocPooledString(ScheduleName(inputdata.value.Int())), inputdata.pActivator, this); } + COutputString m_OutConditionName; + COutputString m_OutScheduleName; + + void InputSetCondition( inputdata_t &inputdata ) { SetCondition(TranslateConditionString(inputdata.value.String())); } + void InputClearCondition( inputdata_t &inputdata ) { ClearCondition(TranslateConditionString(inputdata.value.String())); } +#if AI_MONITOR_USE_UTLVECTOR + void InputClearAllConditions( inputdata_t &inputdata ) { m_Conditions.RemoveAll(); } +#else + void InputClearAllConditions( inputdata_t &inputdata ) { m_Conditions.ClearAll(); } +#endif + + void InputSetSchedule( inputdata_t &inputdata ) { SetSchedule(TranslateScheduleString(inputdata.value.String())); } + void InputClearSchedule( inputdata_t &inputdata ) { ClearSchedule(TranslateScheduleString(inputdata.value.String())); } +#if AI_MONITOR_USE_UTLVECTOR + void InputClearAllSchedules( inputdata_t &inputdata ) { m_Schedules.RemoveAll(); } +#else + void InputClearAllSchedules( inputdata_t &inputdata ) { m_Schedules.ClearAll(); } +#endif + + void InputSetHint( inputdata_t &inputdata ) { SetHint(inputdata.value.Int()); } + void InputClearHint( inputdata_t &inputdata ) { ClearHint(inputdata.value.Int()); } + void InputClearAllHints( inputdata_t &inputdata ) { m_Hints.RemoveAll(); } + +public: + + bool m_bStartDisabled; + + // The NPCs. + CUtlVector pNPCs; + int m_iMaxEnts; + + // Stop and engage cooldown at first successful pass + bool m_bCooldownAtFirstSuccess; + + // Interval between monitors + float m_flThinkTime; + #define GetThinkTime() (m_flThinkTime != 0 ? m_flThinkTime : TICK_INTERVAL) + + // Cooldown after something is satisfied + float m_flCooldownTime; + #define GetCooldownTime() (m_flCooldownTime != -1 ? m_flCooldownTime : GetThinkTime()) + + // ------------------------------ + // Conditions + // ------------------------------ +#if AI_MONITOR_USE_UTLVECTOR + CUtlVector m_Conditions; +#else + CAI_ScheduleBits m_Conditions; +#endif + + COutputInt m_OnNPCHasCondition; + COutputInt m_OnNPCLacksCondition; + + // Condition functions, most of these are from CAI_BaseNPC. +#if AI_MONITOR_USE_UTLVECTOR + inline void SetCondition( int iCondition ) { m_Conditions.HasElement(iCondition) ? NULL : m_Conditions.AddToTail(iCondition); } + inline void ClearCondition( int iCondition ) { m_Conditions.FindAndRemove(iCondition); } + inline bool HasCondition( int iCondition ) { return m_Conditions.HasElement(iCondition); } +#else + inline void SetCondition( int iCondition ) { m_Conditions.Set(iCondition); } + inline void ClearCondition( int iCondition ) { m_Conditions.Clear(iCondition); } + inline bool HasCondition( int iCondition ) { return m_Conditions.IsBitSet(iCondition); } +#endif + + static int GetConditionID(const char* condName) { return CAI_BaseNPC::GetSchedulingSymbols()->ConditionSymbolToId(condName); } + const char *ConditionName(int conditionID); + + int TranslateConditionString(const char *condName); + inline int ConditionLocalToGlobal(CAI_BaseNPC *pTarget, int conditionID) { return pTarget->GetClassScheduleIdSpace()->ConditionLocalToGlobal(conditionID); } + + // ------------------------------ + // Schedules + // ------------------------------ +#if AI_MONITOR_USE_UTLVECTOR + CUtlVector m_Schedules; +#else + CAI_ScheduleBits m_Schedules; +#endif + + bool m_bTranslateSchedules; + + COutputInt m_OnNPCRunningSchedule; + COutputInt m_OnNPCNotRunningSchedule; + + // Schedule functions, some of these are from CAI_BaseNPC. +#if AI_MONITOR_USE_UTLVECTOR + inline void SetSchedule( int iSchedule ) { m_Schedules.HasElement(iSchedule) ? NULL : m_Schedules.AddToTail(iSchedule); } + inline void ClearSchedule( int iSchedule ) { m_Schedules.FindAndRemove(iSchedule); } + inline bool HasSchedule( int iSchedule ) { return m_Schedules.HasElement(iSchedule); } +#else + inline void SetSchedule( int iSchedule ) { m_Schedules.Set(iSchedule); } + inline void ClearSchedule( int iSchedule ) { m_Schedules.Clear(iSchedule); } + inline bool HasSchedule( int iSchedule ) { return m_Schedules.IsBitSet(iSchedule); } +#endif + + static int GetScheduleID(const char* schedName) { return CAI_BaseNPC::GetSchedulingSymbols()->ScheduleSymbolToId(schedName); } + const char *ScheduleName(int scheduleID); + + int TranslateScheduleString(const char *schedName); + inline int ScheduleLocalToGlobal(CAI_BaseNPC *pTarget, int scheduleID) { return pTarget->GetClassScheduleIdSpace()->ScheduleLocalToGlobal(scheduleID); } + + // ------------------------------ + // Tasks + // ------------------------------ + + // TODO + + // ------------------------------ + // Hints + // ------------------------------ + CUtlVector m_Hints; + + COutputInt m_OnNPCUsingHint; + COutputInt m_OnNPCNotUsingHint; + + inline void SetHint( int iHint ) { m_Hints.HasElement(iHint) ? NULL : m_Hints.AddToTail(iHint); } + inline void ClearHint( int iHint ) { m_Hints.FindAndRemove(iHint); } + inline bool HasHint( int iHint ) { return m_Hints.HasElement(iHint); } + + // Only register a hint as "being used" when the NPC is this distance away or less + float m_flDistanceFromHint; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( ai_monitor, CAI_Monitor ); + + +BEGIN_DATADESC( CAI_Monitor ) + +#if AI_MONITOR_USE_UTLVECTOR + DEFINE_UTLVECTOR( m_Conditions, FIELD_INTEGER ), + DEFINE_UTLVECTOR( m_Schedules, FIELD_INTEGER ), +#endif + DEFINE_UTLVECTOR( m_Hints, FIELD_INTEGER ), + + // Keys + DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ), + DEFINE_INPUT( m_flThinkTime, FIELD_FLOAT, "SetMonitorInterval" ), + DEFINE_INPUT( m_flCooldownTime, FIELD_FLOAT, "SetCooldownTime" ), + DEFINE_KEYFIELD( m_bCooldownAtFirstSuccess, FIELD_BOOLEAN, "CooldownAt" ), + + DEFINE_KEYFIELD( m_iMaxEnts, FIELD_INTEGER, "MaxEnts" ), + + DEFINE_KEYFIELD( m_bTranslateSchedules, FIELD_BOOLEAN, "TranslateSchedules" ), + + DEFINE_KEYFIELD( m_flDistanceFromHint, FIELD_FLOAT, "HintDistance" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "UpdateActors", InputPopulateNPCs ), + DEFINE_INPUTFUNC( FIELD_VOID, "Test", InputTest ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "TestNPC", InputTestNPC ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "GetConditionName", InputGetConditionName ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "GetScheduleName", InputGetScheduleName ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetCondition", InputSetCondition ), + DEFINE_INPUTFUNC( FIELD_STRING, "ClearCondition", InputClearCondition ), + DEFINE_INPUTFUNC( FIELD_STRING, "ClearAllConditions", InputClearAllConditions ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetSchedule", InputSetSchedule ), + DEFINE_INPUTFUNC( FIELD_STRING, "ClearSchedule", InputClearSchedule ), + DEFINE_INPUTFUNC( FIELD_STRING, "ClearAllSchedules", InputClearAllSchedules ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHint", InputSetHint ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "ClearHint", InputClearHint ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "ClearAllHints", InputClearAllHints ), + + // Outputs + DEFINE_OUTPUT(m_OutConditionName, "OutConditionName"), + DEFINE_OUTPUT(m_OutScheduleName, "OutScheduleName"), + DEFINE_OUTPUT(m_OnNPCHasCondition, "OnNPCHasCondition"), + DEFINE_OUTPUT(m_OnNPCLacksCondition, "OnNPCLacksCondition"), + DEFINE_OUTPUT(m_OnNPCRunningSchedule, "OnNPCRunningSchedule"), + DEFINE_OUTPUT(m_OnNPCNotRunningSchedule, "OnNPCNotRunningSchedule"), + DEFINE_OUTPUT(m_OnNPCUsingHint, "OnNPCUsingHint"), + DEFINE_OUTPUT(m_OnNPCNotUsingHint, "OnNPCNotUsingHint"), + + DEFINE_THINKFUNC( MonitorThink ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_Monitor::CAI_Monitor() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Monitor::Spawn() +{ + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Monitor::Activate( void ) +{ + BaseClass::Activate(); + + if (!m_bStartDisabled) + { + SetThink(&CAI_Monitor::MonitorThink); + SetNextThink(gpGlobals->curtime + GetThinkTime()); + } + + PopulateNPCs(NULL); +} + +//----------------------------------------------------------------------------- +// Enable, disable +//----------------------------------------------------------------------------- +void CAI_Monitor::InputEnable( inputdata_t &inputdata ) +{ + PopulateNPCs(&inputdata); + + SetThink( &CAI_Monitor::MonitorThink ); + SetNextThink( gpGlobals->curtime + GetThinkTime() ); +} + +void CAI_Monitor::InputDisable( inputdata_t &inputdata ) +{ + SetThink( NULL ); +} + +void CAI_Monitor::InputPopulateNPCs( inputdata_t &inputdata ) +{ + PopulateNPCs(&inputdata); +} + +void CAI_Monitor::InputTest( inputdata_t &inputdata ) +{ + bool bFoundResults = false; + for (int i = 0; i < pNPCs.Count(); i++) + { + if (pNPCs[i] != NULL) + { + if (!bFoundResults) + bFoundResults = NPCDoEval(pNPCs[i]); + else if (!m_bCooldownAtFirstSuccess) + NPCDoEval(pNPCs[i]); + else + break; + } + else + { + // If we have a null NPC, we should probably update. + // This could probably go wrong in more than one way... + PopulateNPCs(NULL); + i--; + } + } +} + +void CAI_Monitor::InputTestNPC( inputdata_t &inputdata ) +{ + CAI_BaseNPC *pNPC = inputdata.value.Entity()->MyNPCPointer(); + if (!inputdata.value.Entity() || !pNPC) + return; + + NPCDoEval(pNPC); +} + +//----------------------------------------------------------------------------- +// Purpose: Save/restore stuff from CAI_BaseNPC +//----------------------------------------------------------------------------- +int CAI_Monitor::Save( ISave &save ) +{ +#if !AI_MONITOR_USE_UTLVECTOR + save.StartBlock(); + SaveConditions( save, m_Conditions ); + SaveConditions( save, m_Schedules ); + save.EndBlock(); +#endif + + return BaseClass::Save(save); +} + +int CAI_Monitor::Restore( IRestore &restore ) +{ +#if !AI_MONITOR_USE_UTLVECTOR + restore.StartBlock(); + RestoreConditions( restore, &m_Conditions ); + RestoreConditions( restore, &m_Schedules ); + restore.EndBlock(); +#endif + + return BaseClass::Restore(restore); +} + +#if !AI_MONITOR_USE_UTLVECTOR +void CAI_Monitor::SaveConditions( ISave &save, const CAI_ScheduleBits &conditions ) +{ + for (int i = 0; i < MAX_CONDITIONS; i++) + { + if (conditions.IsBitSet(i)) + { + const char *pszConditionName = ConditionName(AI_RemapToGlobal(i)); + if ( !pszConditionName ) + break; + save.WriteString( pszConditionName ); + } + } + save.WriteString( "" ); +} + +//------------------------------------- + +void CAI_Monitor::RestoreConditions( IRestore &restore, CAI_ScheduleBits *pConditions ) +{ + pConditions->ClearAll(); + char szCondition[256]; + for (;;) + { + restore.ReadString( szCondition, sizeof(szCondition), 0 ); + if ( !szCondition[0] ) + break; + int iCondition = GetConditionID( szCondition ); + if ( iCondition != -1 ) + pConditions->Set( AI_RemapFromGlobal( iCondition ) ); + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Monitor::PopulateNPCs(inputdata_t *inputdata) +{ + // pNPCs[i] != NULL && !pNPCs[i]->IsMarkedForDeletion() && !pNPCs[i]->GetState() != NPC_STATE_DEAD + //pNPCs = CUtlVector>(); + pNPCs.RemoveAll(); + + CBaseEntity *pActivator = inputdata ? inputdata->pActivator : NULL; + CBaseEntity *pCaller = inputdata ? inputdata->pCaller : NULL; + + CBaseEntity *pEnt = gEntList.FindEntityGeneric(NULL, STRING(m_target), this, pActivator, pCaller); + while (pEnt) + { + if (pEnt->IsNPC()) + { + pNPCs.AddToTail(pEnt->MyNPCPointer()); + DevMsg("Added %s to element %i\n", pEnt->GetDebugName(), pNPCs.Count()); + + // 0 = no limit because the list would already have at least one element by the time this is checked. + if (pNPCs.Count() == m_iMaxEnts) + break; + } + + pEnt = gEntList.FindEntityGeneric(pEnt, STRING(m_target), this, pActivator, pCaller); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CAI_BaseNPC *CAI_Monitor::GetFirstTarget() +{ + for (int i = 0; i < pNPCs.Count(); i++) + { + if (pNPCs[i] != NULL) + return pNPCs[i]; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CAI_Monitor::NPCDoEval(CAI_BaseNPC *pNPC) +{ + // Because we return based on this + m_OnNPCHasCondition.Init(0); + m_OnNPCRunningSchedule.Init(0); + m_OnNPCUsingHint.Init(0); + + + // ---------- + // Conditions + // ---------- +#if AI_MONITOR_USE_UTLVECTOR + for (int cond = 0; cond < m_Conditions.Count(); cond++) +#else + for (int cond = 0; cond < m_Conditions.GetNumBits(); cond++) +#endif + { + if (pNPC->HasCondition(m_Conditions[cond])) + { + DevMsg("NPC has condition %i, index %i, name %s\n", m_Conditions[cond], cond, ConditionName(m_Conditions[cond])); + m_OnNPCHasCondition.Set(m_Conditions[cond], pNPC, this); + m_OutConditionName.Set(MAKE_STRING(ConditionName(m_Conditions[cond])), pNPC, this); + } + else + { + DevMsg("NPC does not have condition %i, index %i, name %s\n", m_Conditions[cond], cond, ConditionName(m_Conditions[cond])); + m_OnNPCLacksCondition.Set(m_Conditions[cond], pNPC, this); + m_OutConditionName.Set(MAKE_STRING(ConditionName(m_Conditions[cond])), pNPC, this); + } + /* + bool bDecisive = false; + switch (m_ConditionsOp) + { + case AIMONITOR_CONDITIONAL_NOR: + bConditionsTrue = true; + case AIMONITOR_CONDITIONAL_OR: + { + if (pNPC->HasCondition(m_Conditions[cond])) + { + // One is valid, pass conditions + bConditionsTrue = !bConditionsTrue; + bDecisive = true; + break; + } + } break; + case AIMONITOR_CONDITIONAL_NAND: + bConditionsTrue = true; + case AIMONITOR_CONDITIONAL_AND: + { + if (!pNPCs[i]->HasCondition(m_Conditions[cond])) + { + // One is invalid, don't pass conditions + bConditionsTrue = !bConditionsTrue; + bDecisive = true; + break; + } + } break; + } + + if (bDecisive) + break; + */ + } + + // ---------- + // Schedules + // ---------- +#if AI_MONITOR_USE_UTLVECTOR + for (int sched = 0; sched < m_Schedules.Count(); sched++) +#else + for (int sched = 0; sched < m_Schedules.GetNumBits(); sched++) +#endif + { + if (pNPC->IsCurSchedule(m_bTranslateSchedules ? pNPC->TranslateSchedule(m_Schedules[sched]) : m_Schedules[sched])) + { + DevMsg("NPC is running schedule %i, index %i, name %s\n", m_Schedules[sched], sched, ScheduleName(m_Schedules[sched])); + m_OnNPCRunningSchedule.Set(m_Schedules[sched], pNPC, this); + m_OutScheduleName.Set(AllocPooledString(ScheduleName(m_Schedules[sched])), pNPC, this); + } + else + { + DevMsg("NPC is not running schedule %i, index %i, name %s\n", m_Schedules[sched], sched, ScheduleName(m_Schedules[sched])); + m_OnNPCNotRunningSchedule.Set(m_Schedules[sched], pNPC, this); + m_OutScheduleName.Set(AllocPooledString(ScheduleName(m_Schedules[sched])), pNPC, this); + } + } + + // ---------- + // Hints + // ---------- + CAI_Hint *pHint = pNPC->GetHintNode(); + if (m_Hints.Count() > 0) + { + if (!pHint || (m_flDistanceFromHint > 0 && pHint->GetLocalOrigin().DistTo(pNPC->GetLocalOrigin()) > m_flDistanceFromHint)) + { + for (int hint = 0; hint < m_Hints.Count(); hint++) + { + m_OnNPCNotUsingHint.Set(m_Hints[hint], pNPC, this); + } + } + else + { + for (int hint = 0; hint < m_Hints.Count(); hint++) + { + if (pHint->HintType() == m_Hints[hint]) + { + DevMsg("NPC is using hint %i, index %i\n", m_Hints[hint], hint); + m_OnNPCUsingHint.Set(m_Hints[hint], pNPC, this); + } + else + { + DevMsg("NPC is not using hint %i, index %i\n", m_Hints[hint], hint); + m_OnNPCNotUsingHint.Set(m_Hints[hint], pNPC, this); + } + } + } + } + + + // Return whether any of our "valid" outputs fired. + return (m_OnNPCHasCondition.Get() != 0 + || m_OnNPCRunningSchedule.Get() != 0 + || m_OnNPCUsingHint.Get() != 0 + ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Monitor::MonitorThink() +{ + bool bMonitorFoundResults = false; + for (int i = 0; i < pNPCs.Count(); i++) + { + if (pNPCs[i] != NULL) + { + if (!bMonitorFoundResults) + bMonitorFoundResults = NPCDoEval(pNPCs[i]); + else if (!m_bCooldownAtFirstSuccess) + NPCDoEval(pNPCs[i]); + else + break; + } + else + { + // If we have a null NPC, we should probably update. + // This could probably go wrong in more than one way... + PopulateNPCs(NULL); + i--; + } + } + + if (bMonitorFoundResults) + SetNextThink(gpGlobals->curtime + GetCooldownTime()); + else + SetNextThink(gpGlobals->curtime + GetThinkTime()); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const char *CAI_Monitor::ConditionName(int conditionID) +{ + if ( AI_IdIsLocal( conditionID ) ) + { + // Get our first target and find a local condition + CAI_BaseNPC *pTarget = GetFirstTarget(); + if (!pTarget) + return NULL; + + conditionID = ConditionLocalToGlobal(pTarget, conditionID); + } + + return CAI_BaseNPC::GetSchedulingSymbols()->ConditionIdToSymbol(conditionID); +} + +const char *CAI_Monitor::ScheduleName(int scheduleID) +{ + if ( AI_IdIsLocal( scheduleID ) ) + { + // Get our first target and find a local condition + CAI_BaseNPC *pTarget = GetFirstTarget(); + if (!pTarget) + return NULL; + + scheduleID = ScheduleLocalToGlobal(pTarget, scheduleID); + } + + return CAI_BaseNPC::GetSchedulingSymbols()->ScheduleIdToSymbol(scheduleID); +} + +int CAI_Monitor::TranslateConditionString(const char *condName) +{ + if (condName[0] == 'C') + { + // String + int cond = GetConditionID(condName); + if (cond > -1) + { + DevMsg("Setting condition %i from %s\n", cond, condName); + return cond; + } + } + else + { + // Int + DevMsg("Setting condition %s\n", condName); + + // Assume the mapper didn't compensate for global ID stuff. + // (as if either of us understand it) + return atoi(condName) + GLOBAL_IDS_BASE; + } + return 0; +} + +int CAI_Monitor::TranslateScheduleString(const char *schedName) +{ + if (schedName[0] == 'S') + { + // String + int sched = GetScheduleID(schedName); + if (sched > -1) + { + DevMsg("Setting schedule %i from %s\n", sched, schedName); + return sched; + } + } + else + { + // Int + DevMsg("Setting schedule %s\n", schedName); + return atoi(schedName); + } + return 0; +} + +template +static void SetForEachDelimited( CAI_Monitor &monitor, const char *szValue, const char *delimiters, void (CAI_Monitor::*setter)(int), Translator translator) +{ + char *value = strdup(szValue); + char *token = strtok(value, ":"); + while (token) + { + (monitor.*setter)(translator(token)); + + token = strtok(NULL, ":"); + } + free(value); +} + +template +struct CAI_MonitorTranslator +{ + CAI_Monitor &monitor; + + CAI_MonitorTranslator(CAI_Monitor &monitor) : monitor(monitor) {} + + int operator()(const char *value) + { + return (monitor.*translator)(value); + } +}; + +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (FStrEq(szKeyName, "ConditionsSimple")) + { + // Hammer SmartEdit helper that shouldn't be overridden. + // It's not supposed to be overridden. + SetCondition(atoi(szValue)); + } + else if (FStrEq(szKeyName, "Conditions")) + { + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetCondition, CAI_MonitorTranslator<&CAI_Monitor::TranslateConditionString>(*this)); + } + else if (FStrEq(szKeyName, "SchedulesSimple")) + { + // Hammer SmartEdit helper that shouldn't be overridden. + SetCondition(atoi(szValue)); + } + else if (FStrEq(szKeyName, "Schedules")) + { + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetSchedule, CAI_MonitorTranslator<&CAI_Monitor::TranslateScheduleString>(*this)); + } + else if (FStrEq(szKeyName, "HintsSimple")) + { + // Hammer SmartEdit helper that shouldn't be overridden. + SetHint(atoi(szValue)); + } + else if (FStrEq(szKeyName, "Hints")) + { + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetHint, atoi); + } + else + return CBaseEntity::KeyValue( szKeyName, szValue ); + + return true; +} diff --git a/game/server/mapbase/ai_weaponmodifier.cpp b/game/server/mapbase/ai_weaponmodifier.cpp new file mode 100644 index 00000000..2ddec2ea --- /dev/null +++ b/game/server/mapbase/ai_weaponmodifier.cpp @@ -0,0 +1,250 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Be warned, because this entity is TERRIBLE! +// +//============================================================================= + +#include "cbase.h" +#include "ai_basenpc.h" +#include "saverestore_utlvector.h" + + + +//----------------------------------------------------------------------------- +// Purpose: A special CAI_ShotRegulator class designed to be used with ai_weaponmodifier. +// I'm too chicken to do anything fun with it. +//----------------------------------------------------------------------------- +typedef CAI_ShotRegulator CAI_CustomShotRegulator; +/* +class CAI_CustomShotRegulator : public CAI_ShotRegulator +{ + DECLARE_CLASS( CAI_CustomShotRegulator, CAI_ShotRegulator ); +public: + void SetMinBurstInterval( float flMinBurstInterval ) { m_flMinBurstInterval = flMinBurstInterval; } + void SetMaxBurstInterval( float flMaxBurstInterval ) { m_flMaxBurstInterval = flMaxBurstInterval; } +}; +*/ + +// A lot of functions can't set each range individually, so we have to do this for a lot of them. +// (again, too chicken to do something useful with CAI_CustomShotRegulator) +#define WeaponModifierSetRange(string, function) float minimum = 0; \ + float maximum = 0; \ + if (sscanf(string, "%f:%f", &minimum, &maximum)) \ + function(minimum, maximum); + +#define WEAPONMODIFIER_MAX_NPCS 16 + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CAI_WeaponModifier : public CLogicalEntity +{ + DECLARE_CLASS( CAI_WeaponModifier, CLogicalEntity ); + DECLARE_DATADESC(); +public: + + void Spawn(); + + virtual int Save( ISave &save ); + virtual int Restore( IRestore &restore ); + + bool KeyValue(const char *szKeyName, const char *szValue); + + void EnableOnNPC(CAI_BaseNPC *pNPC); + void DisableOnNPC(CAI_BaseNPC *pNPC); + + // Inputs + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputEnableOnNPC( inputdata_t &inputdata ); + void InputDisableOnNPC( inputdata_t &inputdata ); + + void InputSetBurstInterval( inputdata_t &inputdata ) { WeaponModifierSetRange(inputdata.value.String(), m_ModdedRegulator.SetBurstInterval); } + void InputSetRestInterval( inputdata_t &inputdata ) { WeaponModifierSetRange(inputdata.value.String(), m_ModdedRegulator.SetRestInterval); } + void InputSetBurstShotCountRange( inputdata_t &inputdata ) { WeaponModifierSetRange(inputdata.value.String(), m_ModdedRegulator.SetBurstShotCountRange); } + void InputSetBurstShotsRemaining( inputdata_t &inputdata ) { m_ModdedRegulator.SetBurstShotsRemaining(inputdata.value.Int()); } + + void InputEnableShooting( inputdata_t &inputdata ) { m_ModdedRegulator.EnableShooting(); } + void InputDisableShooting( inputdata_t &inputdata ) { m_ModdedRegulator.DisableShooting(); } + void InputFireNoEarlierThan( inputdata_t &inputdata ) { m_ModdedRegulator.FireNoEarlierThan(gpGlobals->curtime + inputdata.value.Float()); } + void InputReset( inputdata_t &inputdata ) { m_ModdedRegulator.Reset(inputdata.value.Bool()); } + + // The NPCs and their original regulators. + AIHANDLE m_hNPCs[WEAPONMODIFIER_MAX_NPCS]; + CAI_ShotRegulator m_StoredRegulators[WEAPONMODIFIER_MAX_NPCS]; + + CAI_CustomShotRegulator m_ModdedRegulator; + + bool m_bDisabled; +}; + +LINK_ENTITY_TO_CLASS(ai_weaponmodifier, CAI_WeaponModifier); + +BEGIN_DATADESC( CAI_WeaponModifier ) + + DEFINE_EMBEDDED( m_ModdedRegulator ), + + DEFINE_ARRAY( m_hNPCs, FIELD_EHANDLE, WEAPONMODIFIER_MAX_NPCS ), + DEFINE_EMBEDDED_ARRAY( m_StoredRegulators, WEAPONMODIFIER_MAX_NPCS ), + + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "EnableOnNPC", InputEnableOnNPC ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "DisableOnNPC", InputDisableOnNPC ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetBurstInterval", InputSetBurstInterval ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetRestInterval", InputSetRestInterval ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetBurstShotCountRange", InputSetBurstShotCountRange ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetBurstShotsRemaining", InputSetBurstShotsRemaining ), + + DEFINE_INPUTFUNC( FIELD_VOID, "EnableShooting", InputEnableShooting ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableShooting", InputDisableShooting ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "FireNoEarlierThan", InputFireNoEarlierThan ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "Reset", InputReset ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_WeaponModifier::Spawn() +{ + if (!m_bDisabled) + { + inputdata_t inputdata; + InputEnable(inputdata); + } + + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CAI_WeaponModifier::Save( ISave &save ) +{ + return BaseClass::Save(save); +} + +int CAI_WeaponModifier::Restore( IRestore &restore ) +{ + return BaseClass::Restore(restore); +} + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CAI_WeaponModifier::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (FStrEq(szKeyName, "BurstInterval")) + { + WeaponModifierSetRange(szValue, m_ModdedRegulator.SetBurstInterval); + } + else if (FStrEq(szKeyName, "RestInterval")) + { + WeaponModifierSetRange(szValue, m_ModdedRegulator.SetRestInterval); + } + else if (FStrEq(szKeyName, "BurstShotCountRange")) + { + WeaponModifierSetRange(szValue, m_ModdedRegulator.SetBurstShotCountRange); + } + else if (FStrEq(szKeyName, "BurstShotsRemaining")) + { + m_ModdedRegulator.SetBurstShotsRemaining(atoi(szValue)); + } + else + return BaseClass::KeyValue(szKeyName, szValue); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_WeaponModifier::EnableOnNPC( CAI_BaseNPC *pNPC ) +{ + for (int i = 0; i < WEAPONMODIFIER_MAX_NPCS; i++) + { + if (m_hNPCs[i] == NULL) + { + m_hNPCs[i] = pNPC; + m_StoredRegulators[i] = *pNPC->GetShotRegulator(); + + pNPC->SetShotRegulator(m_ModdedRegulator); + } + else if (m_hNPCs[i] == pNPC) + { + // We're already in it + return; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_WeaponModifier::DisableOnNPC( CAI_BaseNPC *pNPC ) +{ + for (int i = 0; i < WEAPONMODIFIER_MAX_NPCS; i++) + { + if (m_hNPCs[i] == pNPC) + { + pNPC->SetShotRegulator(m_StoredRegulators[i]); + m_hNPCs[i] = NULL; + + // Just reset it to our modded one + m_StoredRegulators[i] = m_ModdedRegulator; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_WeaponModifier::InputEnable( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + while (pEntity) + { + if (pEntity->IsNPC()) + { + EnableOnNPC(pEntity->MyNPCPointer()); + } + + pEntity = gEntList.FindEntityByName(pEntity, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + } +} + +void CAI_WeaponModifier::InputDisable( inputdata_t &inputdata ) +{ + for (int i = 0; i < WEAPONMODIFIER_MAX_NPCS; i++) + { + m_hNPCs[i]->SetShotRegulator(m_StoredRegulators[i]); + m_hNPCs[i] = NULL; + + // Just reset it to our modded one + m_StoredRegulators[i] = m_ModdedRegulator; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_WeaponModifier::InputEnableOnNPC( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity() && inputdata.value.Entity()->IsNPC()) + { + EnableOnNPC(inputdata.value.Entity()->MyNPCPointer()); + } +} + +void CAI_WeaponModifier::InputDisableOnNPC( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity() && inputdata.value.Entity()->IsNPC()) + { + DisableOnNPC(inputdata.value.Entity()->MyNPCPointer()); + } +} diff --git a/game/server/mapbase/closecaption_entity.cpp b/game/server/mapbase/closecaption_entity.cpp new file mode 100644 index 00000000..a166660e --- /dev/null +++ b/game/server/mapbase/closecaption_entity.cpp @@ -0,0 +1,81 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" + + +class CEnvCloseCaption : public CBaseEntity +{ + DECLARE_CLASS( CEnvCloseCaption, CBaseEntity ); +public: + + bool AllPlayers() { return true; } + + void InputSend( inputdata_t &inputdata ); + + //bool m_bCustom; + int m_iFlags; + float m_flDuration; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( env_closecaption, CEnvCloseCaption ); + +BEGIN_DATADESC( CEnvCloseCaption ) + + //DEFINE_KEYFIELD( m_bCustom, FIELD_BOOLEAN, "custom" ), + DEFINE_KEYFIELD( m_iFlags, FIELD_INTEGER, "flags" ), + DEFINE_INPUT( m_flDuration, FIELD_FLOAT, "SetDuration" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_STRING, "Send", InputSend ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEnvCloseCaption::InputSend( inputdata_t &inputdata ) +{ + char szCC[512]; + Q_strncpy(szCC, inputdata.value.String(), sizeof(szCC)); + + byte byteflags = m_iFlags; + if ( AllPlayers() ) + { + CReliableBroadcastRecipientFilter user; + UserMessageBegin( user, "CloseCaption" ); + WRITE_STRING( szCC ); + WRITE_SHORT( MIN( 255, (int)( m_flDuration * 10.0f ) ) ), + WRITE_BYTE( byteflags ), + MessageEnd(); + } + else + { + CBaseEntity *pPlayer = NULL; + + if ( inputdata.pActivator && inputdata.pActivator->IsPlayer() ) + { + pPlayer = inputdata.pActivator; + } + else + { + pPlayer = UTIL_GetLocalPlayer(); + } + + if ( !pPlayer || !pPlayer->IsNetClient() ) + return; + + CSingleUserRecipientFilter user( (CBasePlayer *)pPlayer ); + user.MakeReliable(); + UserMessageBegin( user, "CloseCaption" ); + WRITE_STRING( szCC ); + WRITE_SHORT( MIN( 255, (int)( m_flDuration * 10.0f ) ) ), + WRITE_BYTE( byteflags ), + MessageEnd(); + } +} diff --git a/game/server/mapbase/datadesc_mod.cpp b/game/server/mapbase/datadesc_mod.cpp new file mode 100644 index 00000000..6ef4c6c0 --- /dev/null +++ b/game/server/mapbase/datadesc_mod.cpp @@ -0,0 +1,199 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "datadesc_mod.h" +#include "saverestore.h" + + +// Sets a field's value to a specific string. +char *Datadesc_SetFieldString( const char *szValue, CBaseEntity *pObject, typedescription_t *pField, fieldtype_t *pFieldType ) +{ + // Copied from ::ParseKeyvalue... + fieldtype_t fieldtype = FIELD_VOID; + int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ]; + switch( pField->fieldType ) + { + case FIELD_MODELNAME: + case FIELD_SOUNDNAME: + case FIELD_STRING: + (*(string_t *)((char *)pObject + fieldOffset)) = AllocPooledString( szValue ); + fieldtype = FIELD_STRING; + break; + + case FIELD_TIME: + case FIELD_FLOAT: + (*(float *)((char *)pObject + fieldOffset)) = atof( szValue ); + fieldtype = FIELD_FLOAT; + break; + + case FIELD_BOOLEAN: + (*(bool *)((char *)pObject + fieldOffset)) = (bool)(atoi( szValue ) != 0); + fieldtype = FIELD_BOOLEAN; + break; + + case FIELD_CHARACTER: + (*(char *)((char *)pObject + fieldOffset)) = (char)atoi( szValue ); + fieldtype = FIELD_CHARACTER; + break; + + case FIELD_SHORT: + (*(short *)((char *)pObject + fieldOffset)) = (short)atoi( szValue ); + fieldtype = FIELD_SHORT; + break; + + case FIELD_INTEGER: + case FIELD_TICK: + (*(int *)((char *)pObject + fieldOffset)) = atoi( szValue ); + fieldtype = FIELD_INTEGER; + break; + + case FIELD_POSITION_VECTOR: + case FIELD_VECTOR: + UTIL_StringToVector( (float *)((char *)pObject + fieldOffset), szValue ); + fieldtype = FIELD_VECTOR; + break; + + case FIELD_VMATRIX: + case FIELD_VMATRIX_WORLDSPACE: + UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue ); + fieldtype = FIELD_VMATRIX; // ??? + break; + + case FIELD_MATRIX3X4_WORLDSPACE: + UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue ); + fieldtype = FIELD_VMATRIX; // ??? + break; + + case FIELD_COLOR32: + UTIL_StringToColor32( (color32 *) ((char *)pObject + fieldOffset), szValue ); + fieldtype = FIELD_COLOR32; + break; + + case FIELD_CUSTOM: + { + SaveRestoreFieldInfo_t fieldInfo = + { + (char *)pObject + fieldOffset, + pObject, + pField + }; + pField->pSaveRestoreOps->Parse( fieldInfo, szValue ); + fieldtype = FIELD_STRING; + break; + } + + default: + case FIELD_INTERVAL: + case FIELD_CLASSPTR: + case FIELD_MODELINDEX: + case FIELD_MATERIALINDEX: + case FIELD_EDICT: + return NULL; + //Warning( "%s cannot set field of type %i.\n", GetDebugName(), dmap->dataDesc[i].fieldType ); + break; + } + + if (pFieldType) + *pFieldType = fieldtype; + + return ((char*)pObject) + fieldOffset; +} + +//----------------------------------------------------------------------------- +// Purpose: ReadUnregisteredKeyfields() was a feeble attempt to obtain non-keyfield keyvalues from KeyValue() with variant_t. +// +// I didn't know about GetKeyValue() until 9/29/2018. +// I don't remember why I decided to write down the date I found out about it. Maybe I considered that monumental of a discovery. +// +// However, we still use ReadUnregisteredKeyfields() since GetKeyValue() only supports a string while this function was used for entire variant_ts. +// It now calls GetKeyValue() and returns it as an allocated string. +//----------------------------------------------------------------------------- +bool ReadUnregisteredKeyfields(CBaseEntity *pTarget, const char *szKeyName, variant_t *variant) +{ + if (!pTarget) + return false; + + char szValue[256]; + if (pTarget->GetKeyValue(szKeyName, szValue, sizeof(szValue))) + { + variant->SetString(AllocPooledString(szValue)); // MAKE_STRING causes badness, must pool + return true; + } + +#if 0 + if ( FStrEq( szKeyName, "targetname" ) ) + { + variant->SetString(pTarget->GetEntityName()); + return true; + } + + if( FStrEq( szKeyName, "origin" ) ) + { + variant->SetPositionVector3D(pTarget->GetAbsOrigin()); + return true; + } + + if( FStrEq( szKeyName, "angles" ) /*|| FStrEq( szKeyName, "angle" )*/ ) + { + Vector angles; + AngleVectors(pTarget->GetAbsAngles(), &angles); + variant->SetVector3D(angles); + return true; + } + + if ( FStrEq( szKeyName, "rendercolor" ) || FStrEq( szKeyName, "rendercolor32" )) + { + // Copy it over since we're not going to use the alpha + color32 theircolor = pTarget->GetRenderColor(); + color32 color; + color.r = theircolor.r; + color.g = theircolor.g; + color.b = theircolor.b; + variant->SetColor32(color); + return true; + } + + if ( FStrEq( szKeyName, "renderamt" ) ) + { + char szAlpha = pTarget->GetRenderColor().a; + variant->SetString(MAKE_STRING(&szAlpha)); + return true; + } + + if ( FStrEq( szKeyName, "disableshadows" )) + { + variant->SetBool((pTarget->GetEffects() & EF_NOSHADOW) != NULL); + return true; + } + + if ( FStrEq( szKeyName, "mins" )) + { + variant->SetVector3D(pTarget->CollisionProp()->OBBMinsPreScaled()); + return true; + } + + if ( FStrEq( szKeyName, "maxs" )) + { + variant->SetVector3D(pTarget->CollisionProp()->OBBMaxsPreScaled()); + return true; + } + + if ( FStrEq( szKeyName, "disablereceiveshadows" )) + { + variant->SetBool((pTarget->GetEffects() & EF_NORECEIVESHADOW) != NULL); + return true; + } + + if ( FStrEq( szKeyName, "nodamageforces" )) + { + variant->SetBool((pTarget->GetEFlags() & EFL_NO_DAMAGE_FORCES) != NULL); + return true; + } +#endif + + return false; +} diff --git a/game/server/mapbase/datadesc_mod.h b/game/server/mapbase/datadesc_mod.h new file mode 100644 index 00000000..e724259b --- /dev/null +++ b/game/server/mapbase/datadesc_mod.h @@ -0,0 +1,11 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" + +char *Datadesc_SetFieldString( const char *szValue, CBaseEntity *pObject, typedescription_t *pField, fieldtype_t *pFieldType = NULL ); + +bool ReadUnregisteredKeyfields( CBaseEntity *pTarget, const char *szKeyName, variant_t *variant ); diff --git a/game/server/mapbase/expandedrs_combine.h b/game/server/mapbase/expandedrs_combine.h new file mode 100644 index 00000000..01206d2f --- /dev/null +++ b/game/server/mapbase/expandedrs_combine.h @@ -0,0 +1,173 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Response system properties (concepts, etc.) shared by npc_combine_s and npc_metropolice +// +//=============================================================================// + +#ifndef EXPANDEDRS_COMBINE_H +#define EXPANDEDRS_COMBINE_H + +#ifdef _WIN32 +#pragma once +#endif + +#if 0 +#include "ai_component.h" +#include "ai_basenpc.h" +#include "ai_sentence.h" +#endif + +// +// Concepts +// +// These should be consistent with player allies and each other. +// + +// +// Combine Soldiers +// +#define TLK_CMB_ANNOUNCE "TLK_ANNOUNCE" +#define TLK_CMB_THROWGRENADE "TLK_THROWGRENADE" +#define TLK_CMB_PLAYERHIT "TLK_PLAYERHIT" +#define TLK_CMB_ASSAULT "TLK_ASSAULT" +#define TLK_CMB_ENEMY "TLK_STARTCOMBAT" +#define TLK_CMB_KILLENEMY "TLK_ENEMY_DEAD" +#define TLK_CMB_DANGER "TLK_DANGER" +#define TLK_CMB_KICK "TLK_KICK" +#define TLK_CMB_FLANK "TLK_FLANK" +#define TLK_CMB_PAIN "TLK_WOUND" +#define TLK_CMB_LOSTENEMY "TLK_LOSTENEMY" +#define TLK_CMB_REFINDENEMY "TLK_REFINDENEMY" +#define TLK_CMB_GOALERT "TLK_GOALERT" +//#define TLK_CMB_LASTOFSQUAD "TLK_LASTOFSQUAD" +#define TLK_CMB_MANDOWN "TLK_ALLY_KILLED" +#define TLK_CMB_DIE "TLK_DEATH" +#define TLK_CMB_QUESTION "TLK_QUESTION" +#define TLK_CMB_ANSWER "TLK_ANSWER" + +// +// Metrocops +// +#define TLK_COP_MANHACKKILLED "TLK_ALLY_KILLED" +#define TLK_COP_MANDOWN "TLK_ALLY_KILLED" +#define TLK_COP_GO_ALERT "TLK_GOALERT" +#define TLK_COP_FREEZE "TLK_FREEZE" +#define TLK_COP_OVER_HERE "TLK_OVER_HERE" +#define TLK_COP_HES_RUNNING "TLK_HES_RUNNING" +#define TLK_COP_TAKE_HIM_DOWN "TLK_TAKE_HIM_DOWN" +#define TLK_COP_ARREST_IN_POS "TLK_ARREST_IN_POS" +#define TLK_COP_DEPLOY_MANHACK "TLK_DEPLOY_MANHACK" +#define TLK_COP_PLAYERHIT "TLK_PLAYERHIT" +#define TLK_COP_FLANK "TLK_FLANK" +#define TLK_COP_HEARD_SOMETHING "TLK_DARKNESS_HEARDSOUND" +#define TLK_COP_ENEMY "TLK_STARTCOMBAT" +#define TLK_COP_KILLENEMY "TLK_ENEMY_DEAD" +#define TLK_COP_NOAMMO "TLK_NOAMMO" +#define TLK_COP_LOWAMMO "TLK_LOWAMMO" +#define TLK_COP_DANGER "TLK_DANGER" +#define TLK_COP_DIE "TLK_DEATH" +#define TLK_COP_LOSTENEMY "TLK_LOSTENEMY" +#define TLK_COP_REFINDENEMY "TLK_REFINDENEMY" +#define TLK_COP_HARASS "TLK_STARE" +#define TLK_COP_IDLE "TLK_IDLE" +#define TLK_COP_QUESTION "TLK_QUESTION" +#define TLK_COP_ANSWER "TLK_ANSWER" +#define TLK_COP_PAIN "TLK_WOUND" +#define TLK_COP_COVER_HEAVY_DAMAGE "TLK_HEAVYDAMAGE" +#define TLK_COP_SHOOTCOVER "TLK_SHOOTCOVER" +#define TLK_COP_BACK_UP "TLK_BACK_UP" +#define TLK_COP_ON_FIRE "TLK_WOUND" +#define TLK_COP_HIT_BY_PHYSOBJ "TLK_PLYR_PHYSATK" +#define TLK_COP_THROWGRENADE "TLK_THROWGRENADE" +#define TLK_COP_ACTIVATE_BATON "TLK_ACTIVATE_BATON" +#define TLK_COP_DEACTIVATE_BATON "TLK_DEACTIVATE_BATON" + +#define TLK_COP_MOVE_ALONG "TLK_MOVE_ALONG" + +#define TLK_COP_FT_APPROACH "TLK_FT_APPROACH" +#define TLK_COP_FT_MOUNT "TLK_FT_MOUNT" +#define TLK_COP_FT_SCAN "TLK_FT_SCAN" +#define TLK_COP_FT_DISMOUNT "TLK_FT_DISMOUNT" +#define TLK_COP_SO_BEGIN "TLK_SO_BEGIN" +#define TLK_COP_SO_END "TLK_SO_END" +#define TLK_COP_SO_FORCE_COVER "TLK_SO_FORCE_COVER" +#define TLK_COP_SO_PEEK "TLK_SO_PEEK" +#define TLK_COP_AS_HIT_RALLY "TLK_AS_HIT_RALLY" +#define TLK_COP_AS_HIT_ASSAULT "TLK_AS_HIT_ASSAULT" +#define TLK_COP_AS_ADV_RALLY "TLK_AS_ADV_RALLY" +#define TLK_COP_AS_ADV_ASSAULT "TLK_AS_ADV_ASSAULT" + +// +// Snipers +// +#define TLK_SNIPER_DIE "TLK_DEATH" +#define TLK_SNIPER_TARGETDESTROYED "TLK_ENEMY_DEAD" +#define TLK_SNIPER_DANGER "TLK_DANGER" + + +#if 0 +static void FixupSentence(const char **ppSentence, const char **ppPrefix); + +//----------------------------------------------------------------------------- +// This is the met of the class +//----------------------------------------------------------------------------- +template< class NPC_CLASS > +class CAI_SentenceTalker : public CAI_Component +{ + DECLARE_CLASS_NOBASE( CAI_SentenceTalker ); + DECLARE_SIMPLE_DATADESC(); + +public: + //CAI_SentenceTalker(); + + void Init( NPC_CLASS *pOuter, const char *pGameSound = NULL ); + + // Check for queued-up-sentences + speak them + //void UpdateSentenceQueue(); + + // Returns the sentence index played, which can be used to determine + // the sentence length of time using engine->SentenceLength + int Speak( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD ); + + // Returns the sentence index played, which can be used to determine + // the sentence length of time using engine->SentenceLength. If the sentence + // was queued, then -1 is returned, which is the same result as if the sound wasn't played + //int SpeakQueued( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD ); + + // Clears the sentence queue + //void ClearQueue(); + +protected: + virtual float GetVolume() = 0; + virtual soundlevel_t GetSoundLevel() = 0; + +private: + // Speech criteria + bool ShouldSpeak( SentencePriority_t nSoundPriority, SentenceCriteria_t nCriteria ); + bool MatchesCriteria( SentenceCriteria_t nCriteria ); + + // Play the actual sentence + //int PlaySentence( const char *pSentence ); + + // Debug output + void SentenceMsg( const char *pStatus, const char *pSentence ); + + int m_voicePitch; + int m_nQueuedSentenceIndex; + float m_flQueueTimeout; + int m_nQueueSoundPriority; + + SentencePriority_t m_LastPriority; + +public: + string_t m_iRemovePrefix; +}; + +template< class NPC_CLASS > +void CAI_SentenceTalker< NPC_CLASS >::Init( NPC_CLASS *pOuter, const char *pGameSound ) +{ + SetOuter( pOuter ); +} +#endif + +#endif \ No newline at end of file diff --git a/game/server/mapbase/func_clientclip.cpp b/game/server/mapbase/func_clientclip.cpp new file mode 100644 index 00000000..1bfbf1d7 --- /dev/null +++ b/game/server/mapbase/func_clientclip.cpp @@ -0,0 +1,191 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: A special brush that collides with clientside entities, primarily ragdolls. +// +//=============================================================================// + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Purpose: basic solid geometry +// enabled state: brush is visible +// disabled staute: brush not visible +//----------------------------------------------------------------------------- +class CFuncClientClip : public CBaseEntity +{ +public: + DECLARE_CLASS( CFuncClientClip, CBaseEntity ); + DECLARE_SERVERCLASS(); + + virtual void Spawn( void ); + bool CreateVPhysics( void ); + + virtual int DrawDebugTextOverlays( void ); + + void TurnOff( void ); + void TurnOn( void ); + + // Input handlers + void InputTurnOff( inputdata_t &inputdata ); + void InputTurnOn( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + CNetworkVar( bool, m_bDisabled ); + + DECLARE_DATADESC(); + + virtual bool IsOn( void ); + + int UpdateTransmitState() // always send to all clients + { + return SetTransmitState( FL_EDICT_ALWAYS ); + } +}; + +LINK_ENTITY_TO_CLASS( func_clip_client, CFuncClientClip ); + +BEGIN_DATADESC( CFuncClientClip ) + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputTurnOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputTurnOff ), + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CFuncClientClip, DT_FuncClientClip ) + SendPropBool( SENDINFO( m_bDisabled ) ), +END_SEND_TABLE() + + +void CFuncClientClip::Spawn( void ) +{ + SetMoveType( MOVETYPE_PUSH ); // so it doesn't get pushed by anything + + SetSolid( GetParent() ? SOLID_VPHYSICS : SOLID_BSP ); + AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); + + AddSolidFlags( FSOLID_NOT_SOLID ); + + SetModel( STRING( GetModelName() ) ); + + if ( m_bDisabled ) + TurnOff(); + + // If it can't move/go away, it's really part of the world + if ( !GetEntityName() || !m_iParent ) + AddFlag( FL_WORLDBRUSH ); + + CreateVPhysics(); +} + +//----------------------------------------------------------------------------- + +bool CFuncClientClip::CreateVPhysics( void ) +{ + // NOTE: Don't init this static. It's pretty common for these to be constrained + // and dynamically parented. Initing shadow avoids having to destroy the physics + // object later and lose the constraints. + IPhysicsObject *pPhys = VPhysicsInitShadow(false, false); + if ( pPhys ) + { + int contents = modelinfo->GetModelContents( GetModelIndex() ); + if ( ! (contents & (MASK_SOLID|MASK_PLAYERSOLID|MASK_NPCSOLID)) ) + { + // leave the physics shadow there in case it has crap constrained to it + // but disable collisions with it + pPhys->EnableCollisions( false ); + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CFuncClientClip::DrawDebugTextOverlays( void ) +{ + int nOffset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + Q_snprintf( tempstr,sizeof(tempstr), "angles: %g %g %g", (double)GetLocalAngles()[PITCH], (double)GetLocalAngles()[YAW], (double)GetLocalAngles()[ROLL] ); + EntityText( nOffset, tempstr, 0 ); + nOffset++; + + Q_snprintf(tempstr, sizeof(tempstr), " enabled: %d", !m_bDisabled); + EntityText(nOffset, tempstr, 0); + nOffset++; + } + + return nOffset; +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for toggling the hidden/shown state of the brush. +//----------------------------------------------------------------------------- +void CFuncClientClip::InputToggle( inputdata_t &inputdata ) +{ + if ( IsOn() ) + { + TurnOff(); + return; + } + + TurnOn(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for hiding the brush. +//----------------------------------------------------------------------------- +void CFuncClientClip::InputTurnOff( inputdata_t &inputdata ) +{ + TurnOff(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler for showing the brush. +//----------------------------------------------------------------------------- +void CFuncClientClip::InputTurnOn( inputdata_t &inputdata ) +{ + TurnOn(); +} + +//----------------------------------------------------------------------------- +// Purpose: Hides the brush. +//----------------------------------------------------------------------------- +void CFuncClientClip::TurnOff( void ) +{ + if ( !IsOn() ) + return; + + AddEffects( EF_NODRAW ); + m_bDisabled = true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Shows the brush. +//----------------------------------------------------------------------------- +void CFuncClientClip::TurnOn( void ) +{ + if ( IsOn() ) + return; + + RemoveEffects( EF_NODRAW ); + m_bDisabled = false; +} + + +inline bool CFuncClientClip::IsOn( void ) +{ + return !m_bDisabled; +} diff --git a/game/server/mapbase/func_fake_worldportal.cpp b/game/server/mapbase/func_fake_worldportal.cpp new file mode 100644 index 00000000..6430d5df --- /dev/null +++ b/game/server/mapbase/func_fake_worldportal.cpp @@ -0,0 +1,102 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Recreates Portal 2 linked_portal_door visual functionality using SDK code only. +// (basically a combination of point_camera and func_reflective_glass) +// +//===========================================================================// + +#include "cbase.h" +#include "modelentities.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CFuncFakeWorldPortal : public CFuncBrush +{ + DECLARE_DATADESC(); + DECLARE_CLASS( CFuncFakeWorldPortal, CFuncBrush ); + DECLARE_SERVERCLASS(); + + CFuncFakeWorldPortal() + { + // Equivalent to SKYBOX_2DSKYBOX_VISIBLE, the original sky setting + m_iSkyMode = 2; + } + +public: + + virtual void Spawn( void ) + { + BaseClass::Spawn(); + + if (m_target != NULL_STRING) + { + m_hTargetPlane = gEntList.FindEntityByName( NULL, m_target, this ); + if (!m_hTargetPlane) + Warning("%s: Invalid target plane \"%s\"!\n", GetDebugName(), STRING(m_target)); + } + else + { + Warning("%s: No target plane!\n", GetDebugName()); + } + + if (m_iszFogController != NULL_STRING) + { + m_hFogController = gEntList.FindEntityByName( NULL, m_iszFogController, this ); + if (!m_hFogController) + Warning("%s: Invalid fog controller \"%s\"!\n", GetDebugName(), STRING(m_iszFogController)); + } + } + + // Input handlers + void InputSetTargetPlane( inputdata_t &inputdata ) { m_hTargetPlane = inputdata.value.Entity(); if (m_hTargetPlane) { m_target = m_hTargetPlane->GetEntityName(); } } + void InputSetTargetPlaneAngle( inputdata_t &inputdata ) { Vector vec; inputdata.value.Vector3D(vec); m_PlaneAngles.Init(vec.x, vec.y, vec.z); } + void InputSetSkyMode( inputdata_t &inputdata ) { m_iSkyMode = inputdata.value.Int(); } + void InputSetRenderTarget( inputdata_t &inputdata ) { m_iszRenderTarget = inputdata.value.StringID(); } + void InputSetFogController( inputdata_t &inputdata ) { m_hFogController = inputdata.value.Entity(); if (m_hFogController) { m_iszFogController = m_hFogController->GetEntityName(); } } + void InputSetScale( inputdata_t &inputdata ) { m_flScale = inputdata.value.Float(); } + +private: + + CNetworkHandle( CBaseEntity, m_hTargetPlane ); + CNetworkQAngle( m_PlaneAngles ); + CNetworkVar( int, m_iSkyMode ); + CNetworkVar( float, m_flScale ); + CNetworkVar( string_t, m_iszRenderTarget ); + + CNetworkHandle( CBaseEntity, m_hFogController ); + string_t m_iszFogController; +}; + +// automatically hooks in the system's callbacks +BEGIN_DATADESC( CFuncFakeWorldPortal ) + + DEFINE_FIELD( m_hTargetPlane, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_PlaneAngles, FIELD_VECTOR, "PlaneAngles" ), + DEFINE_KEYFIELD( m_iSkyMode, FIELD_INTEGER, "SkyMode" ), + DEFINE_KEYFIELD( m_flScale, FIELD_FLOAT, "scale" ), + DEFINE_KEYFIELD( m_iszRenderTarget, FIELD_STRING, "RenderTarget" ), + DEFINE_FIELD( m_hFogController, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iszFogController, FIELD_STRING, "FogController" ), + + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetTargetPlane", InputSetTargetPlane ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetTargetPlaneAngle", InputSetTargetPlaneAngle ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSkyMode", InputSetSkyMode ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetRenderTarget", InputSetRenderTarget ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetFogController", InputSetFogController ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetScale", InputSetScale ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( func_fake_worldportal, CFuncFakeWorldPortal ); + +IMPLEMENT_SERVERCLASS_ST( CFuncFakeWorldPortal, DT_FuncFakeWorldPortal ) + + SendPropEHandle( SENDINFO( m_hTargetPlane ) ), + SendPropVector( SENDINFO( m_PlaneAngles ), -1, SPROP_COORD ), + SendPropInt( SENDINFO( m_iSkyMode ) ), + SendPropFloat( SENDINFO( m_flScale ) ), + SendPropStringT( SENDINFO( m_iszRenderTarget ) ), + SendPropEHandle( SENDINFO( m_hFogController ) ), + +END_SEND_TABLE() diff --git a/game/server/mapbase/logic_eventlistener.cpp b/game/server/mapbase/logic_eventlistener.cpp new file mode 100644 index 00000000..903703f3 --- /dev/null +++ b/game/server/mapbase/logic_eventlistener.cpp @@ -0,0 +1,270 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ==== +// +// Purpose: Source SDK-based replication of logic_eventlistener from later versions +// of Source. +// +// This is based entirely on Source 2013 code and Portal 2's FGD entry. +// It does not actually use code from Portal 2 or later. +// +//============================================================================= + +#include "cbase.h" +#include "GameEventListener.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CLogicEventListener : public CPointEntity, + public CGameEventListener +{ +public: + DECLARE_CLASS( CLogicEventListener, CPointEntity ); + + CLogicEventListener(); + + void Activate(); + virtual void ListenForEvents(); + + bool KeyValue(const char *szKeyName, const char *szValue); + + virtual void FireGameEvent( IGameEvent *event ); + + // Input handlers + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + + string_t m_iszEventName; + + // Outputs + COutputEvent m_OnEventFired; + +protected: + + bool m_bDisabled; +}; + +LINK_ENTITY_TO_CLASS(logic_eventlistener, CLogicEventListener); + + +BEGIN_DATADESC( CLogicEventListener ) + + DEFINE_KEYFIELD(m_iszEventName, FIELD_STRING, "EventName"), + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), + DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), + DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), + + // Outputs + DEFINE_OUTPUT(m_OnEventFired, "OnEventFired"), + +END_DATADESC() + + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CLogicEventListener::CLogicEventListener(void) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicEventListener::Activate() +{ + BaseClass::Activate(); + ListenForEvents(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicEventListener::ListenForEvents() +{ + ListenForGameEvent(STRING(m_iszEventName)); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CLogicEventListener::KeyValue(const char *szKeyName, const char *szValue) +{ + if (FStrEq(szKeyName, "IsEnabled")) + { + m_bDisabled = !FStrEq(szValue, "0"); + } + else + return BaseClass::KeyValue(szKeyName, szValue); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: called when a game event is fired +//----------------------------------------------------------------------------- +void CLogicEventListener::FireGameEvent( IGameEvent *event ) +{ + if (m_bDisabled) + return; + + m_OnEventFired.FireOutput(this, this); +} + +//------------------------------------------------------------------------------ +// Purpose: Turns on the entity, allowing it to fire outputs. +//------------------------------------------------------------------------------ +void CLogicEventListener::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} + +//------------------------------------------------------------------------------ +// Purpose: Turns off the entity, preventing it from firing outputs. +//------------------------------------------------------------------------------ +void CLogicEventListener::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + +//------------------------------------------------------------------------------ +// Purpose: Toggles the enabled/disabled state of the entity. +//------------------------------------------------------------------------------ +void CLogicEventListener::InputToggle( inputdata_t &inputdata ) +{ + m_bDisabled = !m_bDisabled; +} + + +#define POINT_EVENT_NUM_VALUES 8 + +class CPointEvent : public CLogicEventListener +{ +public: + DECLARE_CLASS( CPointEvent, CLogicEventListener ); + + CPointEvent(); + + string_t m_KeyNames[POINT_EVENT_NUM_VALUES]; + + void ListenForEvents(); + + void FireGameEvent( IGameEvent *event ); + + // Input handlers + void InputSetAllEvents( inputdata_t &inputdata ); + void InputAddEvent( inputdata_t &inputdata ); + //void InputRemoveEvent( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + + // Outputs + COutputString m_OutEventName; + COutputString m_OutValue[POINT_EVENT_NUM_VALUES]; +}; + +LINK_ENTITY_TO_CLASS(point_event, CPointEvent); + + +BEGIN_DATADESC( CPointEvent ) + + DEFINE_KEYFIELD(m_KeyNames[0], FIELD_STRING, "KeyName01"), + DEFINE_KEYFIELD(m_KeyNames[1], FIELD_STRING, "KeyName02"), + DEFINE_KEYFIELD(m_KeyNames[2], FIELD_STRING, "KeyName03"), + DEFINE_KEYFIELD(m_KeyNames[3], FIELD_STRING, "KeyName04"), + DEFINE_KEYFIELD(m_KeyNames[4], FIELD_STRING, "KeyName05"), + DEFINE_KEYFIELD(m_KeyNames[5], FIELD_STRING, "KeyName06"), + DEFINE_KEYFIELD(m_KeyNames[6], FIELD_STRING, "KeyName07"), + DEFINE_KEYFIELD(m_KeyNames[7], FIELD_STRING, "KeyName08"), + + // Inputs + DEFINE_INPUTFUNC(FIELD_STRING, "SetAllEvents", InputSetAllEvents), + DEFINE_INPUTFUNC(FIELD_STRING, "AddEvent", InputAddEvent), + //DEFINE_INPUTFUNC(FIELD_STRING, "RemoveEvent", InputRemoveEvent), + + // Outputs + DEFINE_OUTPUT(m_OutEventName, "OutEventName"), + DEFINE_OUTPUT(m_OutValue[0], "OutValue01"), + DEFINE_OUTPUT(m_OutValue[1], "OutValue02"), + DEFINE_OUTPUT(m_OutValue[2], "OutValue03"), + DEFINE_OUTPUT(m_OutValue[3], "OutValue04"), + DEFINE_OUTPUT(m_OutValue[4], "OutValue05"), + DEFINE_OUTPUT(m_OutValue[5], "OutValue06"), + DEFINE_OUTPUT(m_OutValue[6], "OutValue07"), + DEFINE_OUTPUT(m_OutValue[7], "OutValue08"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CPointEvent::CPointEvent(void) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointEvent::ListenForEvents() +{ + // Could easily do this with strtok... + // Oh well. I don't know the performance difference. + CUtlStringList vecEvents; + Q_SplitString(STRING(m_iszEventName), ":", vecEvents); + FOR_EACH_VEC(vecEvents, i) + { + ListenForGameEvent(vecEvents[i]); + } +} + +//----------------------------------------------------------------------------- +// Purpose: called when a game event is fired +//----------------------------------------------------------------------------- +void CPointEvent::FireGameEvent( IGameEvent *event ) +{ + if (m_bDisabled) + return; + + BaseClass::FireGameEvent(event); + m_OutEventName.Set(AllocPooledString(event->GetName()), this, this); + + for (int i = 0; i < POINT_EVENT_NUM_VALUES; i++) + { + const char *szValue = event->GetString(STRING(m_KeyNames[i]), NULL); + if (szValue != NULL) + { + m_OutValue[i].Set(AllocPooledString(szValue), this, this); + } + } +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CPointEvent::InputSetAllEvents( inputdata_t &inputdata ) +{ + StopListeningForAllEvents(); + + if (inputdata.value.StringID() != NULL_STRING) + { + CUtlStringList vecEvents; + Q_SplitString(inputdata.value.String(), ":", vecEvents); + FOR_EACH_VEC(vecEvents, i) + { + ListenForGameEvent(vecEvents[i]); + } + } +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CPointEvent::InputAddEvent( inputdata_t &inputdata ) +{ + ListenForGameEvent(inputdata.value.String()); +} diff --git a/game/server/mapbase/logic_externaldata.cpp b/game/server/mapbase/logic_externaldata.cpp new file mode 100644 index 00000000..588bb6c7 --- /dev/null +++ b/game/server/mapbase/logic_externaldata.cpp @@ -0,0 +1,363 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "filesystem.h" +#include "KeyValues.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CLogicExternalData : public CLogicalEntity +{ + DECLARE_CLASS( CLogicExternalData, CLogicalEntity ); + DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif + +public: + ~CLogicExternalData(); + + void LoadFile(); + void SaveFile(); + void SetBlock(string_t iszNewTarget, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL); + + void Activate(); + + // Inputs + void InputWriteKeyValue( inputdata_t &inputdata ); + void InputRemoveKeyValue( inputdata_t &inputdata ); + void InputReadKey( inputdata_t &inputdata ); + void InputSetBlock( inputdata_t &inputdata ); + void InputSave( inputdata_t &inputdata ); + void InputReload( inputdata_t &inputdata ); + +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetKeyValues( void ); + HSCRIPT ScriptGetKeyValueBlock( void ); + + void ScriptSetKeyValues( HSCRIPT hKV ); + void ScriptSetKeyValueBlock( HSCRIPT hKV ); + + void ScriptSetBlock( const char *szNewBlock, HSCRIPT hActivator = NULL, HSCRIPT hCaller = NULL ); +#endif + + char m_iszFile[MAX_PATH]; + + // Root file + KeyValues *m_pRoot; + + // Our specific block + KeyValues *m_pBlock; + //string_t m_iszBlock; // Use m_target + + bool m_bSaveEachChange; + bool m_bReloadBeforeEachAction; + string_t m_iszMapname; + + COutputString m_OutValue; +}; + +LINK_ENTITY_TO_CLASS(logic_externaldata, CLogicExternalData); + +BEGIN_DATADESC( CLogicExternalData ) + + // Keys + //DEFINE_KEYFIELD( m_iszBlock, FIELD_STRING, "Block" ), + DEFINE_KEYFIELD( m_bSaveEachChange, FIELD_BOOLEAN, "SaveEachChange" ), + DEFINE_KEYFIELD( m_bReloadBeforeEachAction, FIELD_BOOLEAN, "ReloadBeforeEachAction" ), + DEFINE_KEYFIELD( m_iszMapname, FIELD_STRING, "Mapname" ), + + // This should be cached each load + //DEFINE_ARRAY( m_iszFile, FIELD_CHARACTER, MAX_PATH ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_STRING, "WriteKeyValue", InputWriteKeyValue ), + DEFINE_INPUTFUNC( FIELD_STRING, "RemoveKeyValue", InputRemoveKeyValue ), + DEFINE_INPUTFUNC( FIELD_STRING, "ReadKey", InputReadKey ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetBlock", InputSetBlock ), + DEFINE_INPUTFUNC( FIELD_VOID, "Save", InputSave ), + DEFINE_INPUTFUNC( FIELD_VOID, "Reload", InputReload ), + + // Outputs + DEFINE_OUTPUT(m_OutValue, "OutValue"), + +END_DATADESC() + +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CLogicExternalData, CBaseEntity, "An entity which loads keyvalues from an external data file." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValues, "GetKeyValues", "Gets the external data expressed in CScriptKeyValues." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBlock, "GetKeyValueBlock", "Gets the current external data block expressed in CScriptKeyValues." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValues, "SetKeyValues", "Sets the external data from a CScriptKeyValues object." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueBlock, "SetKeyValueBlock", "Sets the current external data block from a CScriptKeyValues object." ) + + DEFINE_SCRIPTFUNC( LoadFile, "Loads external data from the external file." ) + DEFINE_SCRIPTFUNC( SaveFile, "Saves the external data to the external file." ) + +END_SCRIPTDESC(); +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CLogicExternalData::~CLogicExternalData() +{ + if (m_pRoot) + m_pRoot->deleteThis(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::LoadFile() +{ + if (m_pRoot) + m_pRoot->deleteThis(); + + m_pRoot = new KeyValues( m_iszFile ); + m_pRoot->LoadFromFile(g_pFullFileSystem, m_iszFile, "MOD"); + + // This shold work even if the file didn't load. + if (m_target != NULL_STRING) + { + m_pBlock = m_pRoot->FindKey(STRING(m_target), true); + } + else + { + // Just do things from root + m_pBlock = m_pRoot; + } + + if (!m_pBlock) + { + Warning("WARNING! %s has NULL m_pBlock! Removing...\n", GetDebugName()); + UTIL_Remove(this); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::SaveFile() +{ + DevMsg("Saving to %s...\n", m_iszFile); + m_pRoot->SaveToFile(g_pFullFileSystem, m_iszFile, "MOD", false, true); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::SetBlock(string_t iszNewTarget, CBaseEntity *pActivator, CBaseEntity *pCaller) +{ + if (STRING(iszNewTarget)[0] == '!') + { + if (FStrEq(STRING(iszNewTarget), "!self")) + iszNewTarget = GetEntityName(); + else if (pActivator && FStrEq(STRING(iszNewTarget), "!activator")) + iszNewTarget = pActivator->GetEntityName(); + else if (pCaller && FStrEq(STRING(iszNewTarget), "!caller")) + iszNewTarget = pCaller->GetEntityName(); + } + + m_target = iszNewTarget; + LoadFile(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::Activate() +{ + BaseClass::Activate(); + + if (m_iszMapname == NULL_STRING || STRING(m_iszMapname)[0] == '\0') + m_iszMapname = gpGlobals->mapname; + + Q_snprintf(m_iszFile, sizeof(m_iszFile), "maps/%s_externaldata.txt", STRING(m_iszMapname)); + DevMsg("LOGIC_EXTERNALDATA: %s\n", m_iszFile); + + // This handles !self, etc. even though the end result could just be assigning to itself. + // Also calls LoadFile() for initial load. + SetBlock(m_target); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputWriteKeyValue( inputdata_t &inputdata ) +{ + const char *szValue = inputdata.value.String(); + char key[256]; + char value[256]; + + // Separate key from value + char *delimiter = Q_strstr(szValue, " "); + if (delimiter && delimiter[1] != '\0') + { + Q_strncpy(key, szValue, MIN((delimiter - szValue) + 1, sizeof(key))); + Q_strncpy(value, delimiter + 1, sizeof(value)); + } + else + { + // Assume the value is just supposed to be null + Q_strncpy(key, szValue, sizeof(key)); + } + + if (m_bReloadBeforeEachAction) + LoadFile(); + + m_pBlock->SetString(key, value); + + if (m_bSaveEachChange) + SaveFile(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputRemoveKeyValue( inputdata_t &inputdata ) +{ + if (m_bReloadBeforeEachAction) + LoadFile(); + + KeyValues *pKV = m_pBlock->FindKey(inputdata.value.String()); + if (pKV) + { + m_pBlock->RemoveSubKey(pKV); + + if (m_bSaveEachChange) + SaveFile(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputReadKey( inputdata_t &inputdata ) +{ + if (m_bReloadBeforeEachAction) + LoadFile(); + + m_OutValue.Set(AllocPooledString(m_pBlock->GetString(inputdata.value.String())), inputdata.pActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputSetBlock( inputdata_t &inputdata ) +{ + SetBlock(inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputSave( inputdata_t &inputdata ) +{ + SaveFile(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicExternalData::InputReload( inputdata_t &inputdata ) +{ + LoadFile(); +} + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CLogicExternalData::ScriptGetKeyValues( void ) +{ + if (m_bReloadBeforeEachAction) + LoadFile(); + + HSCRIPT hScript = NULL; + if (m_pRoot) + { + // Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't. + hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, m_pRoot, false ); + } + + return hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CLogicExternalData::ScriptGetKeyValueBlock( void ) +{ + if (m_bReloadBeforeEachAction) + LoadFile(); + + HSCRIPT hScript = NULL; + if (m_pBlock) + { + // Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't. + hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, m_pBlock, false ); + } + + return hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void CLogicExternalData::ScriptSetKeyValues( HSCRIPT hKV ) +{ + if (m_pRoot) + { + m_pRoot->deleteThis(); + m_pRoot = NULL; + } + + KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV ); + if (pKV) + { + m_pRoot = pKV; + } +} + +void CLogicExternalData::ScriptSetKeyValueBlock( HSCRIPT hKV ) +{ + if (m_pBlock) + { + m_pBlock->deleteThis(); + m_pBlock = NULL; + } + + KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV ); + if (pKV) + { + m_pBlock = pKV; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CLogicExternalData::ScriptSetBlock( const char *szNewBlock, HSCRIPT hActivator, HSCRIPT hCaller ) +{ + CBaseEntity *pActivator = ToEnt( hActivator ); + CBaseEntity *pCaller = ToEnt( hCaller ); + string_t iszNewTarget = AllocPooledString(szNewBlock); + if (STRING(iszNewTarget)[0] == '!') + { + if (FStrEq(STRING(iszNewTarget), "!self")) + iszNewTarget = GetEntityName(); + else if (pActivator && FStrEq(STRING(iszNewTarget), "!activator")) + iszNewTarget = pActivator->GetEntityName(); + else if (pCaller && FStrEq(STRING(iszNewTarget), "!caller")) + iszNewTarget = pCaller->GetEntityName(); + } + + m_target = iszNewTarget; + LoadFile(); +} +#endif diff --git a/game/server/mapbase/logic_register_activator.cpp b/game/server/mapbase/logic_register_activator.cpp new file mode 100644 index 00000000..79a61dab --- /dev/null +++ b/game/server/mapbase/logic_register_activator.cpp @@ -0,0 +1,145 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ==== +// +// Purpose: Source SDK-based replication of logic_register_activator from later versions +// of Source. +// +// This is based entirely on Source 2013 code and Portal 2's FGD entry. +// It does not actually use code from Portal 2 or later. +// +//============================================================================= + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CLogicRegisterActivator : public CLogicalEntity +{ +public: + DECLARE_CLASS( CLogicRegisterActivator, CLogicalEntity ); + + CLogicRegisterActivator(); + + // Input handlers + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + void InputFireRegisteredAsActivator1( inputdata_t &inputdata ); + void InputFireRegisteredAsActivator2( inputdata_t &inputdata ); + void InputFireRegisteredAsActivator3( inputdata_t &inputdata ); + void InputFireRegisteredAsActivator4( inputdata_t &inputdata ); + void InputRegisterEntity( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + + // Outputs + COutputEvent m_OnRegisteredActivate[ 4 ]; + + EHANDLE m_hActivator; + +private: + + bool m_bDisabled; +}; + +LINK_ENTITY_TO_CLASS(logic_register_activator, CLogicRegisterActivator); + + +BEGIN_DATADESC( CLogicRegisterActivator ) + + DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"), + + DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), + DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), + DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), + DEFINE_INPUTFUNC(FIELD_VOID, "FireRegisteredAsActivator1", InputFireRegisteredAsActivator1), + DEFINE_INPUTFUNC(FIELD_VOID, "FireRegisteredAsActivator2", InputFireRegisteredAsActivator2), + DEFINE_INPUTFUNC(FIELD_VOID, "FireRegisteredAsActivator3", InputFireRegisteredAsActivator3), + DEFINE_INPUTFUNC(FIELD_VOID, "FireRegisteredAsActivator4", InputFireRegisteredAsActivator4), + DEFINE_INPUTFUNC(FIELD_EHANDLE, "RegisterEntity", InputRegisterEntity), + + // Outputs + DEFINE_OUTPUT(m_OnRegisteredActivate[0], "OnRegisteredActivate1"), + DEFINE_OUTPUT(m_OnRegisteredActivate[1], "OnRegisteredActivate2"), + DEFINE_OUTPUT(m_OnRegisteredActivate[2], "OnRegisteredActivate3"), + DEFINE_OUTPUT(m_OnRegisteredActivate[3], "OnRegisteredActivate4"), + +END_DATADESC() + + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CLogicRegisterActivator::CLogicRegisterActivator(void) +{ +} + +//------------------------------------------------------------------------------ +// Purpose: Turns on the entity, allowing it to fire outputs. +//------------------------------------------------------------------------------ +void CLogicRegisterActivator::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; +} + +//------------------------------------------------------------------------------ +// Purpose: Turns off the entity, preventing it from firing outputs. +//------------------------------------------------------------------------------ +void CLogicRegisterActivator::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; +} + +//------------------------------------------------------------------------------ +// Purpose: Toggles the enabled/disabled state of the entity. +//------------------------------------------------------------------------------ +void CLogicRegisterActivator::InputToggle( inputdata_t &inputdata ) +{ + m_bDisabled = !m_bDisabled; +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that fires its respective OnRegisteredActivate with the stored activator. +//----------------------------------------------------------------------------- +void CLogicRegisterActivator::InputFireRegisteredAsActivator1( inputdata_t &inputdata ) +{ + m_OnRegisteredActivate[0].FireOutput(m_hActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that fires its respective OnRegisteredActivate with the stored activator. +//----------------------------------------------------------------------------- +void CLogicRegisterActivator::InputFireRegisteredAsActivator2( inputdata_t &inputdata ) +{ + m_OnRegisteredActivate[1].FireOutput(m_hActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that fires its respective OnRegisteredActivate with the stored activator. +//----------------------------------------------------------------------------- +void CLogicRegisterActivator::InputFireRegisteredAsActivator3( inputdata_t &inputdata ) +{ + m_OnRegisteredActivate[2].FireOutput(m_hActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that fires its respective OnRegisteredActivate with the stored activator. +//----------------------------------------------------------------------------- +void CLogicRegisterActivator::InputFireRegisteredAsActivator4( inputdata_t &inputdata ) +{ + m_OnRegisteredActivate[3].FireOutput(m_hActivator, this); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that stores an entity as the activator. +//----------------------------------------------------------------------------- +void CLogicRegisterActivator::InputRegisterEntity( inputdata_t &inputdata ) +{ + m_hActivator = inputdata.value.Entity(); +} diff --git a/game/server/mapbase/logic_skill.cpp b/game/server/mapbase/logic_skill.cpp new file mode 100644 index 00000000..2d47a7cb --- /dev/null +++ b/game/server/mapbase/logic_skill.cpp @@ -0,0 +1,66 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Controls and detects difficulty level changes +// +//============================================================================= + +#include "cbase.h" + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class CLogicSkill : public CLogicalEntity +{ + DECLARE_CLASS( CLogicSkill, CLogicalEntity ); + +private: + // Inputs + void InputTest( inputdata_t &inputdata ); + void InputStartListening( inputdata_t &inputdata ) {m_bListeningForSkillChanges = true;} + void InputStopListening( inputdata_t &inputdata ) {m_bListeningForSkillChanges = false;} + + // Used by gamerules to fire OnSkillChanged. + // Passes the level it changed to as well. + void InputSkillLevelChanged(inputdata_t &inputdata) { m_bListeningForSkillChanges ? m_OnSkillChanged.Set(inputdata.value.Int(), inputdata.pActivator, this) : (void)0; } + + COutputInt m_OnSkillChanged; + COutputEvent m_OnEasy; + COutputEvent m_OnMedium; + COutputEvent m_OnHard; + + bool m_bListeningForSkillChanges; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(logic_skill, CLogicSkill); + +BEGIN_DATADESC( CLogicSkill ) + + DEFINE_KEYFIELD( m_bListeningForSkillChanges, FIELD_BOOLEAN, "ListenForSkillChange" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Test", InputTest ), + DEFINE_INPUTFUNC( FIELD_VOID, "StartListening", InputStartListening ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopListening", InputStopListening ), + + DEFINE_INPUTFUNC( FIELD_INTEGER, "SkillLevelChanged", InputSkillLevelChanged ), + + DEFINE_OUTPUT( m_OnSkillChanged, "OnSkillChanged" ), + DEFINE_OUTPUT( m_OnEasy, "OnEasy" ), + DEFINE_OUTPUT( m_OnMedium, "OnNormal" ), + DEFINE_OUTPUT( m_OnHard, "OnHard" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CLogicSkill::InputTest( inputdata_t &inputdata ) +{ + switch (g_pGameRules->GetSkillLevel()) + { + case SKILL_EASY: m_OnEasy.FireOutput(this, this); break; + case SKILL_MEDIUM: m_OnMedium.FireOutput(this, this); break; + case SKILL_HARD: m_OnHard.FireOutput(this, this); break; + } +} diff --git a/game/server/mapbase/logic_substring.cpp b/game/server/mapbase/logic_substring.cpp new file mode 100644 index 00000000..7c7d153b --- /dev/null +++ b/game/server/mapbase/logic_substring.cpp @@ -0,0 +1,110 @@ +//====================== By Holly Liberatore / MoofEMP ======================// +// +// Purpose: Takes a string parameter and returns a substring defined by keyvalues +// +//===========================================================================// + +#include "cbase.h" + +#define SF_SUBSTRING_START_DISABLED (1 << 0) + +class CLogicSubstring : public CLogicalEntity +{ +public: + DECLARE_CLASS( CLogicSubstring, CLogicalEntity ); + DECLARE_DATADESC(); + + CLogicSubstring( void ) { } + + void InputDisable( inputdata_t &inputData ); + void InputEnable( inputdata_t &inputData ); + void InputInValue( inputdata_t &inputData ); + void InputSetLength( inputdata_t &inputData ); + void InputSetStartPos( inputdata_t &inputData ); + + void Spawn(void); + +private: + int m_nLength; + int m_nStartPos; + + bool m_bEnabled; + + COutputString m_OutValue; +}; + +LINK_ENTITY_TO_CLASS( logic_substring, CLogicSubstring ); + +BEGIN_DATADESC( CLogicSubstring ) + + DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), + + DEFINE_KEYFIELD(m_nLength, FIELD_INTEGER, "length" ), + DEFINE_KEYFIELD(m_nStartPos, FIELD_INTEGER, "startPos" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_STRING, "InValue", InputInValue ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetLength", InputSetLength ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetStartPos", InputSetStartPos ), + + DEFINE_OUTPUT( m_OutValue, "OutValue" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Disable or enable the entity (disabling prevents any input functions from running) +//----------------------------------------------------------------------------- +void CLogicSubstring::InputDisable( inputdata_t &inputData ) { m_bEnabled = false; } +void CLogicSubstring::InputEnable ( inputdata_t &inputData ) { m_bEnabled = true ; } + +//----------------------------------------------------------------------------- +// Purpose: Trim substring from input +// Output: Substring +//----------------------------------------------------------------------------- +void CLogicSubstring::InputInValue( inputdata_t &inputData ) +{ + if( !m_bEnabled ) return; + + int inputLength = Q_strlen(inputData.value.String()); + int startPosCheck = m_nStartPos < 0 ? inputLength + m_nStartPos : m_nStartPos; + if( startPosCheck < 0 ) + { + startPosCheck = 0; + } + int lengthCheck = (m_nLength < 0 || m_nLength > inputLength - startPosCheck ? inputLength - startPosCheck : m_nLength) + 1; + if( lengthCheck < 1 || startPosCheck > inputLength ) + { + m_OutValue.Set( MAKE_STRING(""), inputData.pActivator, this ); + return; + } + char* strOutValue = (char*)malloc( lengthCheck ); + Q_strncpy( strOutValue, inputData.value.String() + startPosCheck, lengthCheck ); + m_OutValue.Set( AllocPooledString(strOutValue), inputData.pActivator, this ); + free(strOutValue); +} + +//----------------------------------------------------------------------------- +// Purpose: Setter methods for keyvalues +//----------------------------------------------------------------------------- +void CLogicSubstring::InputSetLength( inputdata_t &inputData ) +{ + if( !m_bEnabled ) return; + + m_nLength = inputData.value.Int(); +} + +void CLogicSubstring::InputSetStartPos( inputdata_t &inputData ) +{ + if( !m_bEnabled ) return; + + m_nStartPos = inputData.value.Int(); +} + +//----------------------------------------------------------------------------- +// Purpose: Respond to spawnflags when entity spawns +//----------------------------------------------------------------------------- +void CLogicSubstring::Spawn( void ) +{ + m_bEnabled = !HasSpawnFlags( SF_SUBSTRING_START_DISABLED ); +} diff --git a/game/server/mapbase/point_advanced_finder.cpp b/game/server/mapbase/point_advanced_finder.cpp new file mode 100644 index 00000000..27f9f194 --- /dev/null +++ b/game/server/mapbase/point_advanced_finder.cpp @@ -0,0 +1,393 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: A ballsier version of point_entity_finder. +// Originally called logic_entityfinder because a lot of this was written +// before I knew about point_entity_finder in the first place. +// +//============================================================================= + +#include "cbase.h" +#include "eventqueue.h" +#include "filters.h" +#include "saverestore_utlvector.h" + +// Uses a CUtlVector instead of an array. +#define ENTITYFINDER_UTLVECTOR 1 + +// Delays outputs directly instead of relying on an input. +#define ENTITYFINDER_OUTPUT_DELAY 1 + +#if !ENTITYFINDER_STATIC_ARRAY +#define ENTITYFINDER_MAX_STORED_ENTITIES 64 +#endif + +//----------------------------------------------------------------------------- +// Purpose: Entity finder that uses filters and other criteria to search the level for a specific entity. +//----------------------------------------------------------------------------- +class CPointAdvancedFinder : public CLogicalEntity +{ + DECLARE_CLASS(CPointAdvancedFinder, CLogicalEntity); + +private: + // Inputs + void InputSearch(inputdata_t &inputdata); + void InputSetSearchFilter(inputdata_t &inputdata); + void InputSetSearchPoint(inputdata_t &inputdata); + void InputSetRadius(inputdata_t &inputdata) { m_flRadius = inputdata.value.Float(); } + void InputSetMaxResults(inputdata_t &inputdata) { m_iNumSearches = inputdata.value.Int(); } + void InputSetOutputDelay(inputdata_t &inputdata) { m_flOutputDelay = inputdata.value.Float(); } + void InputSetFiringMethod(inputdata_t &inputdata) { m_iFiringMethod = inputdata.value.Int(); } +#ifndef ENTITYFINDER_OUTPUT_DELAY + void InputFoundEntity(inputdata_t &inputdata); +#endif + + void Spawn(); + + Vector GetSearchOrigin(); + bool SearchForEntities(inputdata_t &inputdata); + void FoundEntity(CBaseEntity *pEntity, inputdata_t &inputdata); + + + string_t m_iszSearchFilter; + CHandle m_hSearchFilter; + + string_t m_iszSearchPoint; + EHANDLE m_hSearchPoint; + + float m_flRadius; + int m_iNumSearches; + int m_iFiringMethod; + enum + { + FIRINGMETHOD_NONE = -1, // -1 for point_entity_finder compatibility + FIRINGMETHOD_NEAREST, + FIRINGMETHOD_FARTHEST, + FIRINGMETHOD_RANDOM, + }; + + float m_flOutputDelay; + float m_flLastOutputDelay = 0.0f; + +#if ENTITYFINDER_UTLVECTOR + CUtlVector m_StoredEntities; +#else + CBaseEntity *m_StoredEntities[ENTITYFINDER_MAX_STORED_ENTITIES]; +#endif + + // Outputs + COutputEHANDLE m_OnFoundEntity; + COutputEvent m_OnSearchFailed; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(point_advanced_finder, CPointAdvancedFinder); + + +BEGIN_DATADESC(CPointAdvancedFinder) + + // Keys + DEFINE_KEYFIELD(m_iszSearchFilter, FIELD_STRING, "SearchFilter"), + DEFINE_FIELD(m_hSearchFilter, FIELD_EHANDLE), + DEFINE_KEYFIELD(m_iszSearchPoint, FIELD_STRING, "SearchPoint"), + DEFINE_FIELD(m_hSearchPoint, FIELD_EHANDLE), + DEFINE_KEYFIELD(m_flRadius, FIELD_FLOAT, "radius"), + DEFINE_KEYFIELD(m_iNumSearches, FIELD_INTEGER, "NumberOfEntities"), + DEFINE_KEYFIELD(m_flOutputDelay, FIELD_FLOAT, "OutputDelay"), + DEFINE_KEYFIELD(m_iFiringMethod, FIELD_INTEGER, "Method"), +#if ENTITYFINDER_UTLVECTOR + DEFINE_UTLVECTOR( m_StoredEntities, FIELD_CLASSPTR ), +#else + DEFINE_ARRAY(m_StoredEntities, FIELD_CLASSPTR, ENTITYFINDER_MAX_STORED_ENTITIES), +#endif + DEFINE_FIELD(m_flLastOutputDelay, FIELD_FLOAT), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "BeginSearch", InputSearch), + DEFINE_INPUTFUNC(FIELD_STRING, "SetSearchFilter", InputSetSearchFilter), + DEFINE_INPUTFUNC(FIELD_STRING, "SetSearchPoint", InputSetSearchPoint), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetRadius", InputSetRadius), + DEFINE_INPUTFUNC(FIELD_INTEGER, "SetMaxResults", InputSetMaxResults), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetOutputDelay", InputSetOutputDelay), + DEFINE_INPUTFUNC(FIELD_INTEGER, "SetFiringMethod", InputSetFiringMethod), +#ifndef ENTITYFINDER_OUTPUT_DELAY + DEFINE_INPUTFUNC(FIELD_EHANDLE, "FoundEntity", InputFoundEntity), +#endif + + // Outputs + DEFINE_OUTPUT(m_OnFoundEntity, "OnFoundEntity"), + DEFINE_OUTPUT(m_OnSearchFailed, "OnSearchFailed"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::Spawn() +{ + if (m_iszSearchFilter == NULL_STRING) + { + Warning("%s (%s) has no search filter!\n", GetClassname(), GetDebugName()); + UTIL_Remove(this); + return; + } + + m_hSearchFilter = dynamic_cast(gEntList.FindEntityByName( NULL, m_iszSearchFilter, this )); + + m_hSearchPoint = gEntList.FindEntityByName( NULL, m_iszSearchPoint, this ); + + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::InputSearch(inputdata_t &inputdata) +{ + SearchForEntities(inputdata); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::InputSetSearchFilter(inputdata_t &inputdata) +{ + m_iszSearchFilter = inputdata.value.StringID(); + m_hSearchFilter = dynamic_cast(gEntList.FindEntityByName( NULL, m_iszSearchFilter, this, inputdata.pActivator, inputdata.pCaller )); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::InputSetSearchPoint(inputdata_t &inputdata) +{ + m_iszSearchPoint = inputdata.value.StringID(); + m_hSearchPoint = gEntList.FindEntityByName( NULL, m_iszSearchPoint, this, inputdata.pActivator, inputdata.pCaller ); +} + +#ifndef ENTITYFINDER_OUTPUT_DELAY +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::InputFoundEntity(inputdata_t &inputdata) +{ + CBaseEntity *pEntity = inputdata.value.Entity(); + if (!pEntity) + return; + + m_OnFoundEntity.Set(pEntity, pEntity, inputdata.pCaller); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline Vector CPointAdvancedFinder::GetSearchOrigin() +{ + if (m_hSearchPoint == NULL) + m_hSearchPoint = this; + + return m_hSearchPoint->GetAbsOrigin(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CPointAdvancedFinder::SearchForEntities(inputdata_t &inputdata) +{ + if ( !m_hSearchFilter ) + return false; + + m_flLastOutputDelay = 0.0f; + + int iNumResults = 0; + + float flRadius = m_flRadius * m_flRadius; + + bool bShouldStoreEntities = (m_iFiringMethod > FIRINGMETHOD_NONE || m_flOutputDelay > 0); +#if !ENTITYFINDER_UTLVECTOR + if (bShouldStoreEntities) + { + if (m_iNumSearches > ENTITYFINDER_MAX_STORED_ENTITIES) + { + Warning("%s (%s) needs to store entities, but we're asked to look for more than the maximum, %i, with %i! Reducing to max...\n", GetClassname(), GetDebugName(), ENTITYFINDER_MAX_STORED_ENTITIES, m_iNumSearches); + m_iNumSearches = ENTITYFINDER_MAX_STORED_ENTITIES; + } + else if (m_iNumSearches == 0) + { + m_iNumSearches = ENTITYFINDER_MAX_STORED_ENTITIES; + } + } + else +#endif + if (m_iNumSearches == 0) + { + m_iNumSearches = MAX_EDICTS; + } + + const CEntInfo *pInfo = gEntList.FirstEntInfo(); + + for ( ;pInfo; pInfo = pInfo->m_pNext ) + { + CBaseEntity *ent = (CBaseEntity *)pInfo->m_pEntity; + if ( !ent ) + { + DevWarning( "NULL entity in global entity list!\n" ); + continue; + } + + if (iNumResults >= m_iNumSearches) + break; + + if ( m_hSearchFilter && !m_hSearchFilter->PassesFilter( this, ent ) ) + continue; + + if (flRadius > 0 && (ent->GetAbsOrigin() - GetSearchOrigin()).LengthSqr() > flRadius) + continue; + + if ( bShouldStoreEntities ) + { + // Fire it later +#if ENTITYFINDER_UTLVECTOR + m_StoredEntities.AddToTail(ent); +#else + m_StoredEntities[ iNumResults ] = ent; +#endif + } + else + { + // Fire it now + FoundEntity(ent, inputdata); + } + + iNumResults++; + } + + if (iNumResults > 0) + { + if (bShouldStoreEntities) + { + if (m_iFiringMethod == FIRINGMETHOD_NEAREST || m_iFiringMethod == FIRINGMETHOD_FARTHEST) + { + bool bNotFarthest = m_iFiringMethod != FIRINGMETHOD_FARTHEST; + float flMaxDist = m_flRadius; + float flMinDist = 0; + + if (flMaxDist == 0) + flMaxDist = MAX_TRACE_LENGTH; + + for (int iCur = 0; iCur < iNumResults; iCur++) + { + float flClosest = bNotFarthest ? flMaxDist : 0; + float flDistance = 0; + CBaseEntity *pClosest = NULL; + for (int i = 0; i < iNumResults; i++) + { + if (!m_StoredEntities[i]) + continue; + + flDistance = (m_StoredEntities[i]->GetAbsOrigin() - GetSearchOrigin()).Length(); + if (flDistance < flMaxDist && flDistance > flMinDist) + { + if (bNotFarthest ? (flDistance < flClosest) : (flDistance > flClosest)) + { + pClosest = m_StoredEntities[i]; + flClosest = flDistance; + } + } + } + + if (pClosest) + { + bNotFarthest ? flMinDist = flClosest : flMaxDist = flClosest; + FoundEntity(pClosest, inputdata); + } + else + { + DevWarning("%s (%s): NO CLOSEST!!!\n", GetClassname(), GetDebugName()); + } + } + } + else if (m_iFiringMethod == FIRINGMETHOD_RANDOM) + { + // This could probaly be better... + CUtlVector iResultIndices; + for (int i = 0; i < iNumResults; i++) + iResultIndices.AddToTail(i); + + while (iResultIndices.Count() > 0) + { + int index = iResultIndices[RandomInt(0, iResultIndices.Count() - 1)]; + + if (m_StoredEntities[index]) + { + FoundEntity(m_StoredEntities[index], inputdata); + } + else + { + DevWarning("%s (%s): Found entity is null: %i\n", GetClassname(), GetDebugName(), index); + } + + iResultIndices.FindAndRemove(index); + } + } + else if (m_iFiringMethod == FIRINGMETHOD_NONE) + { + for (int i = 0; i < iNumResults; i++) + { + if (m_StoredEntities[i]) + { + FoundEntity(m_StoredEntities[i], inputdata); + } + else + { + DevWarning("%s (%s): Found entity is null: %i\n", GetClassname(), GetDebugName(), i); + } + } + } + + m_StoredEntities.RemoveAll(); + } + return true; + } + else + { + m_OnSearchFailed.FireOutput(inputdata.pActivator, inputdata.pCaller); + return false; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointAdvancedFinder::FoundEntity(CBaseEntity *pEntity, inputdata_t &inputdata) +{ +#ifdef ENTITYFINDER_OUTPUT_DELAY + variant_t variant; + variant.SetEntity(pEntity); + + DevMsg("%s (%s): Firing entity output in %f, added from %f\n", GetClassname(), GetDebugName(), m_flLastOutputDelay, m_flOutputDelay); + m_OnFoundEntity.FireOutput(variant, pEntity, this, m_flLastOutputDelay); +#else + if (m_flOutputDelay == 0) + { + // Just fire it now + m_OnFoundEntity.Set(pEntity, pEntity, inputdata.pCaller); + DevMsg("%s (%s): Delay 0, firing now\n", GetClassname(), GetDebugName()); + return; + } + + //if (m_flLastOutputDelay == 0) + //m_flLastOutputDelay = gpGlobals->curtime; + + variant_t variant; + variant.SetEntity(pEntity); + + DevMsg("%s (%s): Firing entity output in %f, added from %f\n", GetClassname(), GetDebugName(), m_flLastOutputDelay, m_flOutputDelay); + g_EventQueue.AddEvent(this, "FoundEntity", variant, m_flLastOutputDelay, inputdata.pActivator, inputdata.pCaller); +#endif + + m_flLastOutputDelay += m_flOutputDelay; +} diff --git a/game/server/mapbase/point_copy_size.cpp b/game/server/mapbase/point_copy_size.cpp new file mode 100644 index 00000000..379a6579 --- /dev/null +++ b/game/server/mapbase/point_copy_size.cpp @@ -0,0 +1,143 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Copies size. +// +//============================================================================= + +#include "cbase.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPointCopySize : public CLogicalEntity +{ + DECLARE_CLASS( CPointCopySize, CLogicalEntity ); +private: + // The entity to copy the size from. + // m_target is the target that receives it. + string_t m_iszSizeSource; + EHANDLE m_hSizeSource; + EHANDLE m_hTarget; + + float m_flScale; + + void CopySize(CBaseEntity *pSource, CBaseEntity *pTarget); + + // Inputs + void InputCopySize( inputdata_t &inputdata ); + void InputCopySizeToEntity( inputdata_t &inputdata ); + void InputCopySizeFromEntity( inputdata_t &inputdata ); + + void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); m_hTarget = NULL; } + void InputSetSource( inputdata_t &inputdata ) { m_iszSizeSource = inputdata.value.StringID(); m_hSizeSource = NULL; } + + // Outputs + COutputEvent m_OnCopy; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS(point_copy_size, CPointCopySize); + + +BEGIN_DATADESC( CPointCopySize ) + + // Keys + DEFINE_KEYFIELD(m_iszSizeSource, FIELD_STRING, "source"), + DEFINE_FIELD(m_hSizeSource, FIELD_EHANDLE), + DEFINE_FIELD(m_hTarget, FIELD_EHANDLE), + + DEFINE_INPUT(m_flScale, FIELD_FLOAT, "SetScale"), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "CopySize", InputCopySize ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "CopySizeToEntity", InputCopySizeToEntity ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "CopySizeFromEntity", InputCopySizeFromEntity ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetSource", InputSetSource ), + + // Outputs + DEFINE_OUTPUT(m_OnCopy, "OnCopy"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCopySize::CopySize(CBaseEntity *pSource, CBaseEntity *pTarget) +{ + const Vector cvecAlignMins = pSource->WorldAlignMins(); + const Vector cvecAlignMaxs = pSource->WorldAlignMaxs(); + + Vector vecAlignMins = Vector(cvecAlignMins); + Vector vecAlignMaxs = Vector(cvecAlignMaxs); + + if (m_flScale != 0.0f && m_flScale != 1.0f) + { + vecAlignMins *= m_flScale; + vecAlignMaxs *= m_flScale; + } + + pTarget->SetCollisionBounds(vecAlignMins, vecAlignMins); + m_OnCopy.FireOutput(pTarget, this); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCopySize::InputCopySize( inputdata_t &inputdata ) +{ + if (!m_hSizeSource) + m_hSizeSource = gEntList.FindEntityByName(NULL, STRING(m_iszSizeSource), this, inputdata.pActivator, inputdata.pCaller); + if (!m_hTarget) + m_hTarget = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + + if (!m_hSizeSource || !m_hTarget) + { + Warning("%s (%s): Could not find %s\n", GetClassname(), GetDebugName(), !m_hSizeSource ? "size source" : "target to copy size to"); + return; + } + + CopySize(m_hSizeSource, m_hTarget); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCopySize::InputCopySizeToEntity( inputdata_t &inputdata ) +{ + if (!m_hSizeSource) + m_hSizeSource = gEntList.FindEntityByName(NULL, STRING(m_iszSizeSource), this, inputdata.pActivator, inputdata.pCaller); + + if (!m_hSizeSource) + { + Warning("%s (%s): Could not find size source\n", GetClassname(), GetDebugName()); + return; + } + + if (!inputdata.value.Entity()) + return; + + CopySize(m_hSizeSource, inputdata.value.Entity()); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCopySize::InputCopySizeFromEntity( inputdata_t &inputdata ) +{ + if (!m_hTarget) + m_hTarget = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + + if (!m_hTarget) + { + Warning("%s (%s): Could not find target to copy size to\n", GetClassname(), GetDebugName()); + return; + } + + if (!inputdata.value.Entity()) + return; + + CopySize(inputdata.value.Entity(), m_hTarget); +} diff --git a/game/server/mapbase/point_damageinfo.cpp b/game/server/mapbase/point_damageinfo.cpp new file mode 100644 index 00000000..74e7b406 --- /dev/null +++ b/game/server/mapbase/point_damageinfo.cpp @@ -0,0 +1,394 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: A special entity for afflicting damage as specific as possible. +// +//============================================================================= + +#include "cbase.h" + + +//----------------------------------------------------------------------------- +// Purpose: Advanced damage information afflicting. +//----------------------------------------------------------------------------- +class CPointDamageInfo : public CLogicalEntity +{ + DECLARE_CLASS( CPointDamageInfo, CLogicalEntity ); + DECLARE_DATADESC(); + + virtual bool KeyValue( const char *szKeyName, const char *szValue ); + virtual bool KeyValue( const char *szKeyName, const Vector &vecValue ); + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + +public: + CPointDamageInfo(); + + CTakeDamageInfo m_info; + + // The actual inflictor, attacker, and weapon in CTakeDamageInfo are direct entity pointers. + // This is needed to ensure !activator functionality, entities that might not exist yet, etc. + string_t m_iszInflictor; + string_t m_iszAttacker; + string_t m_iszWeapon; + + // The maximum number of entities to be damaged if they share m_target's targetname or classname. + int m_iMaxEnts; + + // Suppresses death sounds in the best way we possibly can. + bool m_bSuppressDeathSound; + + //bool m_bDisabled; + + // Inputs + void InputSetInflictor( inputdata_t &inputdata ) { m_iszInflictor = inputdata.value.StringID(); } //{ m_info.SetInflictor(inputdata.value.Entity()); } + void InputSetAttacker( inputdata_t &inputdata ) { m_iszAttacker = inputdata.value.StringID(); } //{ m_info.SetAttacker(inputdata.value.Entity()); } + void InputSetWeapon( inputdata_t &inputdata ) { m_iszWeapon = inputdata.value.StringID(); } //{ m_info.SetWeapon(inputdata.value.Entity()); } + + void InputSetDamage( inputdata_t &inputdata ) { m_info.SetDamage(inputdata.value.Float()); } + void InputSetMaxDamage( inputdata_t &inputdata ) { m_info.SetMaxDamage(inputdata.value.Float()); } + void InputSetDamageBonus( inputdata_t &inputdata ) { m_info.SetDamageBonus(inputdata.value.Float()); } + + void InputSetDamageType( inputdata_t &inputdata ) { m_info.SetDamageType(inputdata.value.Int()); } + void InputSetDamageCustom( inputdata_t &inputdata ) { m_info.SetDamageCustom(inputdata.value.Int()); } + void InputSetDamageStats( inputdata_t &inputdata ) { m_info.SetDamageStats(inputdata.value.Int()); } + void InputSetForceFriendlyFire( inputdata_t &inputdata ) { m_info.SetForceFriendlyFire(inputdata.value.Bool()); } + + void InputSetAmmoType( inputdata_t &inputdata ) { m_info.SetAmmoType(inputdata.value.Int()); } + + void InputSetPlayerPenetrationCount( inputdata_t &inputdata ) { m_info.SetPlayerPenetrationCount( inputdata.value.Int() ); } + void InputSetDamagedOtherPlayers( inputdata_t &inputdata ) { m_info.SetDamagedOtherPlayers( inputdata.value.Int() ); } + + void InputSetDamageForce( inputdata_t &inputdata ) { Vector vec; inputdata.value.Vector3D(vec); m_info.SetDamageForce(vec); } + void InputSetDamagePosition( inputdata_t &inputdata ) { Vector vec; inputdata.value.Vector3D(vec); m_info.SetDamagePosition(vec); } + void InputSetReportedPosition( inputdata_t &inputdata ) { Vector vec; inputdata.value.Vector3D(vec); m_info.SetReportedPosition(vec); } + + void HandleDamage(CBaseEntity *pTarget); + + void ApplyDamage( const char *target, inputdata_t &inputdata ); + void ApplyDamage( CBaseEntity *target, inputdata_t &inputdata ); + + void InputApplyDamage( inputdata_t &inputdata ); + void InputApplyDamageToEntity( inputdata_t &inputdata ); + + // Outputs + COutputEvent m_OnApplyDamage; + COutputEvent m_OnApplyDeath; +}; + +LINK_ENTITY_TO_CLASS(point_damageinfo, CPointDamageInfo); + + +BEGIN_DATADESC( CPointDamageInfo ) + + DEFINE_EMBEDDED( m_info ), + + // Keys + DEFINE_KEYFIELD( m_iszInflictor, FIELD_STRING, "Inflictor" ), + DEFINE_KEYFIELD( m_iszAttacker, FIELD_STRING, "Attacker" ), + DEFINE_KEYFIELD( m_iszWeapon, FIELD_STRING, "Weapon" ), + + DEFINE_KEYFIELD( m_iMaxEnts, FIELD_INTEGER, "MaxEnts" ), + DEFINE_KEYFIELD( m_bSuppressDeathSound, FIELD_BOOLEAN, "SuppressDeathSound" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_STRING, "SetInflictor", InputSetInflictor ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetAttacker", InputSetAttacker ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetWeapon", InputSetWeapon ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDamage", InputSetDamage ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxDamage", InputSetMaxDamage ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDamageBonus", InputSetDamageBonus ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetDamageType", InputSetDamageType ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetDamageCustom", InputSetDamageCustom ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetDamageStats", InputSetDamageStats ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetForceFriendlyFire", InputSetForceFriendlyFire ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetAmmoType", InputSetAmmoType ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetPlayerPenetrationCount", InputSetPlayerPenetrationCount ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetDamagedOtherPlayers", InputSetDamagedOtherPlayers ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetDamageForce", InputSetDamageForce ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetDamagePosition", InputSetDamagePosition ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetReportedPosition", InputSetReportedPosition ), + + DEFINE_INPUTFUNC( FIELD_VOID, "ApplyDamage", InputApplyDamage ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "ApplyDamageToEntity", InputApplyDamageToEntity ), + + // Outputs + DEFINE_OUTPUT(m_OnApplyDamage, "OnApplyDamage"), + DEFINE_OUTPUT(m_OnApplyDeath, "OnApplyDeath"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPointDamageInfo::CPointDamageInfo() +{ + m_info = CTakeDamageInfo(this, this, 24, DMG_GENERIC); + m_iMaxEnts = 1; +} + +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CPointDamageInfo::KeyValue( const char *szKeyName, const char *szValue ) +{ + /*if (FStrEq(szKeyName, "Inflictor")) + m_info.SetInflictor(gEntList.FindEntityByName(NULL, szValue, this, NULL, NULL)); + else if (FStrEq(szKeyName, "Attacker")) + m_info.SetAttacker(gEntList.FindEntityByName(NULL, szValue, this, NULL, NULL)); + else if (FStrEq(szKeyName, "Weapon")) + m_info.SetWeapon(gEntList.FindEntityByName(NULL, szValue, this, NULL, NULL)); + + else*/ if (FStrEq(szKeyName, "Damage")) + m_info.SetDamage(atof(szValue)); + else if (FStrEq(szKeyName, "MaxDamage")) + m_info.SetMaxDamage(atof(szValue)); + else if (FStrEq(szKeyName, "DamageBonus")) + m_info.SetDamageBonus(atof(szValue)); + + else if (FStrEq(szKeyName, "DamageType") || FStrEq(szKeyName, "DamagePresets")) + m_info.AddDamageType(atoi(szValue)); + else if (FStrEq(szKeyName, "DamageOr")) + m_info.AddDamageType(atoi(szValue)); + else if (FStrEq(szKeyName, "DamageCustom")) + m_info.SetDamageCustom(atoi(szValue)); + else if (FStrEq(szKeyName, "DamageStats")) + m_info.SetDamageStats(atoi(szValue)); + else if (FStrEq(szKeyName, "ForceFriendlyFire")) + m_info.SetForceFriendlyFire(FStrEq(szValue, "1")); + + else if (FStrEq(szKeyName, "AmmoType")) + m_info.SetAmmoType(atoi(szValue)); + + else if (FStrEq(szKeyName, "PlayerPenetrationCount")) + m_info.SetPlayerPenetrationCount(atoi(szValue)); + else if (FStrEq(szKeyName, "DamagedOtherPlayers")) + m_info.SetDamagedOtherPlayers(atoi(szValue)); + + else + { + if (!BaseClass::KeyValue(szKeyName, szValue)) + { + // Ripped from variant_t::Convert()... + Vector tmpVec = vec3_origin; + if (sscanf(szValue, "[%f %f %f]", &tmpVec[0], &tmpVec[1], &tmpVec[2]) == 0) + { + // Try sucking out 3 floats with no []s + sscanf(szValue, "%f %f %f", &tmpVec[0], &tmpVec[1], &tmpVec[2]); + } + return KeyValue(szKeyName, tmpVec); + } + } + + return true; +} + +bool CPointDamageInfo::KeyValue( const char *szKeyName, const Vector &vecValue ) +{ + if (FStrEq(szKeyName, "DamageForce")) + m_info.SetDamageForce(vecValue); + else if (FStrEq(szKeyName, "DamagePosition")) + m_info.SetDamagePosition(vecValue); + else if (FStrEq(szKeyName, "ReportedPosition")) + m_info.SetReportedPosition(vecValue); + else + return CBaseEntity::KeyValue( szKeyName, vecValue ); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CPointDamageInfo::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + /* + if (FStrEq(szKeyName, "Inflictor")) + Q_snprintf(szValue, iMaxLen, "%s", m_info.GetInflictor() ? "" : m_info.GetInflictor()->GetDebugName()); + else if (FStrEq(szKeyName, "Attacker")) + Q_snprintf(szValue, iMaxLen, "%s", m_info.GetAttacker() ? "" : m_info.GetAttacker()->GetDebugName()); + else if (FStrEq(szKeyName, "Weapon")) + Q_snprintf(szValue, iMaxLen, "%s", m_info.GetWeapon() ? "" : m_info.GetWeapon()->GetDebugName()); + + else*/ if (FStrEq(szKeyName, "Damage")) + Q_snprintf(szValue, iMaxLen, "%f", m_info.GetDamage()); + else if (FStrEq(szKeyName, "MaxDamage")) + Q_snprintf(szValue, iMaxLen, "%f", m_info.GetMaxDamage()); + else if (FStrEq(szKeyName, "DamageBonus")) + Q_snprintf(szValue, iMaxLen, "%f", m_info.GetDamageBonus()); + + else if (FStrEq(szKeyName, "DamageType")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetDamageType()); + else if (FStrEq(szKeyName, "DamageCustom")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetDamageCustom()); + else if (FStrEq(szKeyName, "DamageStats")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetDamageStats()); + else if (FStrEq(szKeyName, "ForceFriendlyFire")) + Q_snprintf(szValue, iMaxLen, "%s", m_info.IsForceFriendlyFire() ? "1" : "0"); + + else if (FStrEq(szKeyName, "AmmoType")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetAmmoType()); + + else if (FStrEq(szKeyName, "PlayerPenetrationCount")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetPlayerPenetrationCount()); + else if (FStrEq(szKeyName, "DamagedOtherPlayers")) + Q_snprintf(szValue, iMaxLen, "%i", m_info.GetDamagedOtherPlayers()); + + else if (FStrEq(szKeyName, "DamageForce")) + Q_snprintf(szValue, iMaxLen, "%f %f %f", m_info.GetDamageForce().x, m_info.GetDamageForce().y, m_info.GetDamageForce().z); + else if (FStrEq(szKeyName, "DamagePosition")) + Q_snprintf(szValue, iMaxLen, "%f %f %f", m_info.GetDamagePosition().x, m_info.GetDamagePosition().y, m_info.GetDamagePosition().z); + else if (FStrEq(szKeyName, "ReportedPosition")) + Q_snprintf(szValue, iMaxLen, "%f %f %f", m_info.GetReportedPosition().x, m_info.GetReportedPosition().y, m_info.GetReportedPosition().z); + else + return BaseClass::GetKeyValue(szKeyName, szValue, iMaxLen); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointDamageInfo::HandleDamage( CBaseEntity *pTarget ) +{ + pTarget->TakeDamage(m_info); + m_OnApplyDamage.FireOutput(pTarget, this); + if (pTarget->m_lifeState == LIFE_DYING) + m_OnApplyDeath.FireOutput(pTarget, this); + + // This is the best we could do, as nodeathsound is exclusive to response system NPCs + if (m_bSuppressDeathSound) + pTarget->EmitSound("AI_BaseNPC.SentenceStop"); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CPointDamageInfo::ApplyDamage( const char *target, inputdata_t &inputdata ) +{ + if (m_iszAttacker != NULL_STRING) + m_info.SetAttacker( gEntList.FindEntityByName(NULL, STRING(m_iszAttacker), this, inputdata.pActivator, inputdata.pCaller) ); + + if (m_iszInflictor != NULL_STRING) + m_info.SetInflictor( gEntList.FindEntityByName(NULL, STRING(m_iszInflictor), this, inputdata.pActivator, inputdata.pCaller) ); + else + { + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(m_info.GetAttacker()); + if (pBCC != NULL && pBCC->GetActiveWeapon()) + { + m_info.SetInflictor(pBCC->GetActiveWeapon()); + } + } + + if (m_iszWeapon != NULL_STRING) + m_info.SetWeapon( gEntList.FindEntityByName(NULL, STRING(m_iszWeapon), this, inputdata.pActivator, inputdata.pCaller) ); + else + { + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(m_info.GetAttacker()); + if (pBCC != NULL && pBCC->GetActiveWeapon()) + { + m_info.SetWeapon(pBCC->GetActiveWeapon()); + } + } + + if (!m_info.GetAttacker()) + m_info.SetAttacker( this ); + + if (!m_info.GetInflictor()) + m_info.SetInflictor( this ); + + if (!m_info.GetWeapon()) + m_info.SetWeapon( this ); + + CBaseEntity *pTarget = NULL; + if (m_iMaxEnts > 0) + { + for (int i = 0; i < m_iMaxEnts; i++) + { + pTarget = gEntList.FindEntityGeneric(pTarget, target, this, inputdata.pActivator, inputdata.pCaller); + if (pTarget) + { + HandleDamage( pTarget ); + } + } + } + else + { + pTarget = gEntList.FindEntityGeneric(NULL, target, this, inputdata.pActivator, inputdata.pCaller); + while (pTarget) + { + HandleDamage( pTarget ); + pTarget = gEntList.FindEntityGeneric(pTarget, target, this, inputdata.pActivator, inputdata.pCaller); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Applies damage to a specific entity +// Input : +// Output : +//----------------------------------------------------------------------------- +void CPointDamageInfo::ApplyDamage( CBaseEntity *target, inputdata_t &inputdata ) +{ + if (!target) + return; + + if (m_iszAttacker != NULL_STRING) + m_info.SetAttacker( gEntList.FindEntityByName(NULL, STRING(m_iszAttacker), this, inputdata.pActivator, inputdata.pCaller) ); + else + m_info.SetAttacker( this ); + + if (m_iszInflictor != NULL_STRING) + m_info.SetInflictor( gEntList.FindEntityByName(NULL, STRING(m_iszInflictor), this, inputdata.pActivator, inputdata.pCaller) ); + else + { + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(m_info.GetAttacker()); + if (pBCC != NULL && pBCC->GetActiveWeapon()) + { + m_info.SetInflictor(pBCC->GetActiveWeapon()); + } + else + m_info.SetInflictor(this); + } + + if (m_iszWeapon != NULL_STRING) + m_info.SetWeapon( gEntList.FindEntityByName(NULL, STRING(m_iszWeapon), this, inputdata.pActivator, inputdata.pCaller) ); + else + { + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(m_info.GetAttacker()); + if (pBCC != NULL && pBCC->GetActiveWeapon()) + { + m_info.SetWeapon(pBCC->GetActiveWeapon()); + } + else + m_info.SetWeapon(this); + } + + target->TakeDamage(m_info); + m_OnApplyDamage.FireOutput(target, this); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CPointDamageInfo::InputApplyDamage( inputdata_t &inputdata ) +{ + ApplyDamage(STRING(m_target), inputdata); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CPointDamageInfo::InputApplyDamageToEntity( inputdata_t &inputdata ) +{ + ApplyDamage(inputdata.value.Entity(), inputdata); +} diff --git a/game/server/mapbase/point_entity_replace.cpp b/game/server/mapbase/point_entity_replace.cpp new file mode 100644 index 00000000..6152d24c --- /dev/null +++ b/game/server/mapbase/point_entity_replace.cpp @@ -0,0 +1,496 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Replaces a thing with another thing. +// +//============================================================================= + +#include "cbase.h" +#include "TemplateEntities.h" +#include "point_template.h" +#include "saverestore_utlvector.h" +#include "datadesc_mod.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPointEntityReplace : public CLogicalEntity +{ + DECLARE_CLASS( CPointEntityReplace, CLogicalEntity ); + DECLARE_DATADESC(); + +public: + + // The entity that will replace the target. + string_t m_iszReplacementEntity; + + // Only used with certain replacement types + EHANDLE m_hReplacementEntity; + + // How we should get the replacement entity. + int m_iReplacementType; + enum + { + REPLACEMENTTYPE_TARGET_TELEPORT, // Replace with target entity + REPLACEMENTTYPE_CLASSNAME, // Replace with entity of specified classname + REPLACEMENTTYPE_TEMPLATE, // Replace with a point_template's contents + REPLACEMENTTYPE_TEMPLATE_RELATIVE, // Replace with a point_template's contents, maintaining relative position + REPLACEMENTTYPE_RANDOM_TEMPLATE, // Replace with one of a point_template's templates, randomly selected + REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE, // Replace with one of a point_template's templates, randomly selected, maintaining relative position + }; + + // Where the replacement entit(ies) should replace at. + int m_iReplacementLocation; + enum + { + REPLACEMENTLOC_ABSOLUTEORIGIN, + REPLACEMENTLOC_WORLDSPACECENTER, + }; + + // Do we actually replace the target entity or just function as a glorified point_teleport? + bool m_bRemoveOriginalEntity; + + // What stuff we should take. + int m_iTakeStuff; + enum + { + REPLACEMENTTAKE_NAME = (1 << 0), // Takes the target's name + REPLACEMENTTAKE_PARENT = (1 << 1), // Takes parent and transfers children + REPLACEMENTTAKE_OWNER = (1 << 2), // Takes owner entity + REPLACEMENTTAKE_MODELSTUFF = (1 << 3), // Takes model stuff + }; + + // Used to cause it to take other fields, most of that has been moved to m_bTakeModelStuff and m_iszOtherTakes + //bool m_bTakeStuff; + + // Other keyvalues to copy. + CUtlVector m_iszOtherTakes; + + // Fire OnReplace with the original entity as the caller. + bool m_bFireOriginalEntityAsCaller; + + bool KeyValue(const char *szKeyName, const char *szValue); + + void HandleReplacement(CBaseEntity *pEntity, CBaseEntity *pReplacement); + + CBaseEntity *GetReplacementEntity(inputdata_t *inputdata); + + void ReplaceEntity(CBaseEntity *pEntity, inputdata_t &inputdata); + + // Inputs + void InputReplace( inputdata_t &inputdata ); + void InputReplaceEntity( inputdata_t &inputdata ); + + void InputSetReplacementEntity( inputdata_t &inputdata ); + + COutputEHANDLE m_OnReplace; // Passes the entity we replaced the target with, fired multiple times if REPLACEMENTTYPE_TEMPLATE created multiple entities +}; + +LINK_ENTITY_TO_CLASS(point_entity_replace, CPointEntityReplace); + +BEGIN_DATADESC( CPointEntityReplace ) + + // Keys + DEFINE_KEYFIELD( m_iszReplacementEntity, FIELD_STRING, "ReplacementEntity" ), + DEFINE_FIELD( m_hReplacementEntity, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iReplacementType, FIELD_INTEGER, "ReplacementType" ), + DEFINE_KEYFIELD( m_iReplacementLocation, FIELD_INTEGER, "ReplacementLocation" ), + DEFINE_KEYFIELD( m_bRemoveOriginalEntity, FIELD_BOOLEAN, "RemoveOriginalEntity" ), + DEFINE_FIELD( m_iTakeStuff, FIELD_INTEGER ), + DEFINE_UTLVECTOR( m_iszOtherTakes, FIELD_STRING ), + DEFINE_KEYFIELD( m_bFireOriginalEntityAsCaller, FIELD_BOOLEAN, "TargetIsCaller" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Replace", InputReplace ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "ReplaceEntity", InputReplaceEntity ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetReplacementEntity", InputSetReplacementEntity ), + + // Outputs + DEFINE_OUTPUT(m_OnReplace, "OnReplace"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CPointEntityReplace::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (!stricmp(szKeyName, "OtherStuff")) + { + if (szValue && szValue[0] != '\0') + { + CUtlStringList vecKeyList; + Q_SplitString(szValue, ",", vecKeyList); + FOR_EACH_VEC(vecKeyList, i) + { + m_iszOtherTakes.AddToTail(AllocPooledString(vecKeyList[i])); + } + } + return true; + } + else if (strnicmp(szKeyName, "Take", 4) == 0) + { + const char *subject = (szKeyName + 4); + int flag = 0; + if (FStrEq(subject, "Targetname")) + flag |= REPLACEMENTTAKE_NAME; + else if (FStrEq(subject, "Parent")) + flag |= REPLACEMENTTAKE_PARENT; + else if (FStrEq(subject, "Owner")) + flag |= REPLACEMENTTAKE_OWNER; + else if (FStrEq(subject, "ModelStuff")) + flag |= REPLACEMENTTAKE_MODELSTUFF; + else + return BaseClass::KeyValue(szKeyName, szValue); + + // Remove the flag if 0, add the flag if not 0 + !FStrEq(szValue, "0") ? (m_iTakeStuff |= flag) : (m_iTakeStuff &= ~flag); + + return true; + } + + return BaseClass::KeyValue(szKeyName, szValue); +} + +//----------------------------------------------------------------------------- +// Purpose: Takes targetname, fields, etc. Keep in mind neither are checked for null! +//----------------------------------------------------------------------------- +void CPointEntityReplace::HandleReplacement(CBaseEntity *pEntity, CBaseEntity *pReplacement) +{ + if (m_iTakeStuff & REPLACEMENTTAKE_NAME) + pReplacement->SetName(pEntity->GetEntityName()); + + if (m_iTakeStuff & REPLACEMENTTAKE_PARENT) + { + if (pEntity->GetParent()) + pReplacement->SetParent(pEntity->GetParent(), pEntity->GetParentAttachment()); + + TransferChildren(pEntity, pReplacement); + } + + if (m_iTakeStuff & REPLACEMENTTAKE_OWNER) + { + if (pEntity->GetOwnerEntity()) + pReplacement->SetOwnerEntity(pEntity->GetOwnerEntity()); + } + + if (m_iTakeStuff & REPLACEMENTTAKE_MODELSTUFF) + { + pReplacement->m_nRenderMode = pEntity->m_nRenderMode; + pReplacement->m_nRenderFX = pEntity->m_nRenderFX; + pReplacement->m_clrRender = pEntity->m_clrRender; + if (pEntity->GetBaseAnimating() && pReplacement->GetBaseAnimating()) + { + CBaseAnimating *pEntityAnimating = pEntity->GetBaseAnimating(); + CBaseAnimating *pReplacementAnimating = pReplacement->GetBaseAnimating(); + + pReplacementAnimating->CopyAnimationDataFrom(pEntityAnimating); + + for ( int iPose = 0; iPose < MAXSTUDIOPOSEPARAM; ++iPose ) + { + pReplacementAnimating->SetPoseParameter( iPose, pEntityAnimating->GetPoseParameter( iPose ) ); + } + } + } + + if (m_iszOtherTakes.Count() > 0) + { + CUtlVector szValues; + szValues.AddMultipleToTail( m_iszOtherTakes.Count() ); + + for ( datamap_t *dmap = pEntity->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) && dmap->dataDesc[i].fieldName ) + { + DevMsg("Target Field Name: %s,\n", dmap->dataDesc[i].fieldName); + for (int i2 = 0; i2 < m_iszOtherTakes.Count(); i2++) + { + if ( FStrEq(dmap->dataDesc[i].fieldName, STRING(m_iszOtherTakes[i2])) ) + { + //szValues[i2] = (((char *)pEntity) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ]); + szValues[i2].Set( dmap->dataDesc[i].fieldType, ((char*)pEntity) + dmap->dataDesc[i].fieldOffset[TD_OFFSET_NORMAL] ); + break; + } + } + } + } + } + + for ( datamap_t *dmap = pReplacement->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_SAVE | FTYPEDESC_KEY) && dmap->dataDesc[i].fieldName ) + { + DevMsg("Replacement Field Name: %s,\n", dmap->dataDesc[i].fieldName); + for (int i2 = 0; i2 < m_iszOtherTakes.Count(); i2++) + { + if ( FStrEq(dmap->dataDesc[i].fieldName, STRING(m_iszOtherTakes[i2])) ) + { + //(void*)(((char *)pReplacement) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ]) = szValues[i2]; + + //char *data = (((char *)pReplacement) + dmap->dataDesc[i].fieldOffset[TD_OFFSET_NORMAL]); + //memcpy(data, szValues[i2], sizeof(*data)); + + //Datadesc_SetFieldString( szValues[i2], pReplacement, &dmap->dataDesc[i] ); + + szValues[i2].SetOther( (((char *)pReplacement) + dmap->dataDesc[i].fieldOffset[TD_OFFSET_NORMAL]) ); + break; + } + } + } + } + } + } + + /* + // This is largely duplicated from phys_convert + if (m_bTakeStuff) + { + pReplacement->m_nRenderMode = pEntity->m_nRenderMode; + pReplacement->m_nRenderFX = pEntity->m_nRenderFX; + const color32 rclr = pEntity->GetRenderColor(); + pReplacement->SetRenderColor(rclr.r, rclr.g, rclr.b, rclr.a); + if (pEntity->GetBaseAnimating() && pReplacement->GetBaseAnimating()) + { + CBaseAnimating *pEntityAnimating = pEntity->GetBaseAnimating(); + CBaseAnimating *pReplacementAnimating = pReplacement->GetBaseAnimating(); + + pReplacementAnimating->CopyAnimationDataFrom(pEntityAnimating); + + //pReplacementAnimating->SetCycle(pEntityAnimating->GetCycle()); + //pReplacementAnimating->IncrementInterpolationFrame(); + //pReplacementAnimating->SetSequence(pEntityAnimating->GetSequence()); + //pReplacementAnimating->m_flAnimTime = pEntityAnimating->m_flAnimTime; + //pReplacementAnimating->m_nBody = pEntityAnimating->m_nBody; + //pReplacementAnimating->m_nSkin = pEntityAnimating->m_nSkin; + //pReplacementAnimating->SetModelScale(pEntityAnimating->GetModelScale()); + } + + UTIL_TransferPoseParameters(pEntity, pReplacement); + TransferChildren(pEntity, pReplacement); + } + */ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CBaseEntity *CPointEntityReplace::GetReplacementEntity(inputdata_t *inputdata) +{ + if (!m_hReplacementEntity) + m_hReplacementEntity.Set(gEntList.FindEntityByName(NULL, STRING(m_iszReplacementEntity), this, inputdata ? inputdata->pActivator : NULL, inputdata ? inputdata->pCaller : NULL)); + return m_hReplacementEntity; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointEntityReplace::ReplaceEntity(CBaseEntity *pEntity, inputdata_t &inputdata) +{ + Vector vecOrigin; + if (m_iReplacementLocation == REPLACEMENTLOC_WORLDSPACECENTER) + vecOrigin = pEntity->WorldSpaceCenter(); + else + vecOrigin = pEntity->GetAbsOrigin(); + + QAngle angAngles = pEntity->GetAbsAngles(); + Vector vecVelocity; + QAngle angVelocity; + if (pEntity->VPhysicsGetObject()) + { + AngularImpulse angImpulse; + pEntity->VPhysicsGetObject()->GetVelocity(&vecVelocity, &angImpulse); + AngularImpulseToQAngle(angImpulse, angVelocity); + } + else + { + vecVelocity = pEntity->GetAbsVelocity(); + angVelocity = pEntity->GetLocalAngularVelocity(); + } + + // No conflicts with the replacement entity until we're finished + if (m_bRemoveOriginalEntity && !(m_iTakeStuff & REPLACEMENTTAKE_MODELSTUFF)) + { + pEntity->AddSolidFlags( FSOLID_NOT_SOLID ); + pEntity->AddEffects( EF_NODRAW ); + } + + CBaseEntity *pCaller = m_bFireOriginalEntityAsCaller ? pEntity : this; + + switch (m_iReplacementType) + { + case REPLACEMENTTYPE_TARGET_TELEPORT: + { + CBaseEntity *pReplacementEntity = GetReplacementEntity(&inputdata); + if (pReplacementEntity) + { + HandleReplacement(pEntity, pReplacementEntity); + pReplacementEntity->Teleport(&vecOrigin, &angAngles, &vecVelocity); + + if (pReplacementEntity->VPhysicsGetObject()) + { + AngularImpulse angImpulse; + QAngleToAngularImpulse(angAngles, angImpulse); + pReplacementEntity->VPhysicsGetObject()->SetVelocityInstantaneous(&vecVelocity, &angImpulse); + } + else + { + pReplacementEntity->SetAbsVelocity(vecVelocity); + pReplacementEntity->SetBaseVelocity( vec3_origin ); + pReplacementEntity->SetLocalAngularVelocity(angVelocity); + } + + m_OnReplace.Set(pReplacementEntity, pReplacementEntity, pCaller); + } + } break; + case REPLACEMENTTYPE_CLASSNAME: + { + CBaseEntity *pReplacementEntity = CreateNoSpawn(STRING(m_iszReplacementEntity), vecOrigin, angAngles); + if (pReplacementEntity) + { + HandleReplacement(pEntity, pReplacementEntity); + + DispatchSpawn(pReplacementEntity); + + if (pReplacementEntity->VPhysicsGetObject()) + { + IPhysicsObject *pPhys = pReplacementEntity->VPhysicsGetObject(); + AngularImpulse angImpulse; + QAngleToAngularImpulse(angAngles, angImpulse); + pPhys->SetVelocityInstantaneous(&vecVelocity, &angImpulse); + } + else + { + pReplacementEntity->SetAbsVelocity(vecVelocity); + pReplacementEntity->SetBaseVelocity( vec3_origin ); + pReplacementEntity->SetLocalAngularVelocity(angVelocity); + } + + m_OnReplace.Set(pReplacementEntity, pReplacementEntity, pCaller); + } + } break; + case REPLACEMENTTYPE_TEMPLATE: + case REPLACEMENTTYPE_TEMPLATE_RELATIVE: + { + CPointTemplate *pTemplate = dynamic_cast(GetReplacementEntity(&inputdata)); + if (!pTemplate) + { + Warning("%s unable to retrieve entity %s. It either does not exist or is not a point_template.\n", GetDebugName(), STRING(m_iszReplacementEntity)); + return; + } + + CUtlVector hNewEntities; + if ( !pTemplate->CreateInstance( vecOrigin, angAngles, &hNewEntities ) || hNewEntities.Count() == 0 ) + return; + + CBaseEntity *pTemplateEntity = NULL; + for (int i = 0; i < hNewEntities.Count(); i++) + { + pTemplateEntity = hNewEntities[i]; + if (pTemplateEntity) + { + HandleReplacement(pEntity, pTemplateEntity); + + if (m_iReplacementType != REPLACEMENTTYPE_TEMPLATE_RELATIVE) + { + // We have to do this again. + pTemplateEntity->Teleport( &vecOrigin, &angAngles, &vecVelocity ); + } + + if (pTemplateEntity->VPhysicsGetObject()) + { + AngularImpulse angImpulse; + QAngleToAngularImpulse(angAngles, angImpulse); + pTemplateEntity->VPhysicsGetObject()->SetVelocityInstantaneous(&vecVelocity, &angImpulse); + } + else + { + pTemplateEntity->SetAbsVelocity(vecVelocity); + pTemplateEntity->SetBaseVelocity( vec3_origin ); + pTemplateEntity->SetLocalAngularVelocity(angVelocity); + } + + m_OnReplace.Set(pTemplateEntity, pTemplateEntity, pCaller); + } + } + } break; + case REPLACEMENTTYPE_RANDOM_TEMPLATE: + case REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE: + { + CPointTemplate *pTemplate = dynamic_cast(GetReplacementEntity(&inputdata)); + if (!pTemplate) + { + Warning("%s unable to retrieve entity %s. It either does not exist or is not a point_template.\n", GetDebugName(), STRING(m_iszReplacementEntity)); + return; + } + + CBaseEntity *pTemplateEntity = NULL; + if ( !pTemplate->CreateSpecificInstance( RandomInt(0, pTemplate->GetNumTemplates() - 1), vecOrigin, angAngles, &pTemplateEntity ) ) + return; + + if (pTemplateEntity) + { + HandleReplacement(pEntity, pTemplateEntity); + + if (m_iReplacementType != REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE) + { + // We have to do this again. + pTemplateEntity->Teleport( &vecOrigin, &angAngles, &vecVelocity ); + } + + if (pTemplateEntity->VPhysicsGetObject()) + { + AngularImpulse angImpulse; + QAngleToAngularImpulse(angAngles, angImpulse); + pTemplateEntity->VPhysicsGetObject()->SetVelocityInstantaneous(&vecVelocity, &angImpulse); + } + else + { + pTemplateEntity->SetAbsVelocity(vecVelocity); + pTemplateEntity->SetBaseVelocity( vec3_origin ); + pTemplateEntity->SetLocalAngularVelocity(angVelocity); + } + + m_OnReplace.Set(pTemplateEntity, pTemplateEntity, pCaller); + } + } break; + } + + if (m_bRemoveOriginalEntity) + UTIL_Remove(pEntity); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointEntityReplace::InputReplace( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = gEntList.FindEntityByName(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + if (pEntity) + ReplaceEntity(pEntity, inputdata); + else + Warning("%s unable to find replacement target %s.\n", GetDebugName(), STRING(m_target)); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointEntityReplace::InputReplaceEntity( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity()) + ReplaceEntity(inputdata.value.Entity(), inputdata); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointEntityReplace::InputSetReplacementEntity( inputdata_t &inputdata ) +{ + m_iszReplacementEntity = inputdata.value.StringID(); + m_hReplacementEntity = NULL; +} diff --git a/game/server/mapbase/point_glow.cpp b/game/server/mapbase/point_glow.cpp new file mode 100644 index 00000000..877aec83 --- /dev/null +++ b/game/server/mapbase/point_glow.cpp @@ -0,0 +1,73 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase off-shoot of tf_glow (created using SDK code only) +// +//============================================================================= + +#include "cbase.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPointGlow : public CPointEntity +{ + DECLARE_CLASS( CPointGlow, CPointEntity ); +public: + + int UpdateTransmitState( void ) { return SetTransmitState( FL_EDICT_ALWAYS ); } + + void Spawn( void ); + + void SetGlowTarget( CBaseEntity *pActivator, CBaseEntity *pCaller ) { m_hGlowTarget = gEntList.FindEntityByName(NULL, m_target, this, pActivator, pCaller); } + + // Inputs + void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); SetGlowTarget( inputdata.pActivator, inputdata.pCaller ); } + + void InputEnable( inputdata_t &inputdata ) { m_bGlowDisabled = false; SetGlowTarget( inputdata.pActivator, inputdata.pCaller ); } + void InputDisable( inputdata_t &inputdata ) { m_bGlowDisabled = true; } + void InputToggle( inputdata_t &inputdata ) { m_bGlowDisabled ? InputEnable(inputdata) : InputDisable(inputdata); } + + void InputSetGlowColor( inputdata_t &inputdata ) { m_GlowColor = inputdata.value.Color32(); } + + CNetworkHandle( CBaseEntity, m_hGlowTarget ); + CNetworkColor32( m_GlowColor ); + CNetworkVar( bool, m_bGlowDisabled ); + + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); +}; + +LINK_ENTITY_TO_CLASS( point_glow, CPointGlow ); + + +BEGIN_DATADESC( CPointGlow ) + + // Keys + DEFINE_KEYFIELD( m_GlowColor, FIELD_COLOR32, "GlowColor" ), + DEFINE_FIELD( m_hGlowTarget, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_bGlowDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + DEFINE_INPUTFUNC( FIELD_COLOR32, "SetGlowColor", InputSetGlowColor ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CPointGlow, DT_PointGlow ) + SendPropEHandle( SENDINFO( m_hGlowTarget ) ), + SendPropInt( SENDINFO( m_GlowColor ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt ), + SendPropBool( SENDINFO( m_bGlowDisabled ) ), +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointGlow::Spawn() +{ + m_hGlowTarget = gEntList.FindEntityByName( NULL, m_target, this ); + + BaseClass::Spawn(); +} diff --git a/game/server/mapbase/point_projectile.cpp b/game/server/mapbase/point_projectile.cpp new file mode 100644 index 00000000..7909c55d --- /dev/null +++ b/game/server/mapbase/point_projectile.cpp @@ -0,0 +1,197 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Fires projectiles. What else is there to say? +// +//============================================================================= + +#include "cbase.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPointProjectile : public CBaseEntity +{ + DECLARE_CLASS( CPointProjectile, CBaseEntity ); + DECLARE_DATADESC(); + +public: + + void Precache(); + void Spawn(); + + // m_target is projectile class + + // Owner + // Handle is m_hOwnerEntity + string_t m_iszOwner; + + // Damage + float m_flDamage; + + // Speed + float m_flSpeed; + + bool m_bFireProjectilesFromOwner; + + CBaseEntity *CalculateOwner( CBaseEntity *pActivator, CBaseEntity *pCaller ); + + CBaseEntity *CreateProjectile( Vector &vecOrigin, QAngle &angAngles, Vector &vecDir, CBaseEntity *pOwner ); + + // Inputs + void InputFire( inputdata_t &inputdata ); + void InputFireAtEntity( inputdata_t &inputdata ); + void InputFireAtPosition( inputdata_t &inputdata ); + + void InputSetDamage( inputdata_t &inputdata ) { m_flDamage = inputdata.value.Float(); } + void InputSetOwner( inputdata_t &inputdata ) { m_iszOwner = inputdata.value.StringID(); SetOwnerEntity(NULL); } + void InputSetSpeed( inputdata_t &inputdata ) { m_flSpeed = inputdata.value.Float(); } + + void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); UTIL_PrecacheOther(inputdata.value.String()); } + + COutputEHANDLE m_OnFire; +}; + +LINK_ENTITY_TO_CLASS(point_projectile, CPointProjectile); + +BEGIN_DATADESC( CPointProjectile ) + + // Keys + DEFINE_KEYFIELD( m_iszOwner, FIELD_STRING, "Owner" ), + DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "Damage" ), + DEFINE_KEYFIELD( m_flSpeed, FIELD_FLOAT, "Speed" ), + DEFINE_KEYFIELD( m_bFireProjectilesFromOwner, FIELD_BOOLEAN, "FireFromOwner" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Fire", InputFire ), + DEFINE_INPUTFUNC( FIELD_EHANDLE, "FireAtEntity", InputFireAtEntity ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "FireAtPosition", InputFireAtPosition ), + + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDamage", InputSetDamage ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOwnerEntity", InputSetOwner ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeed", InputSetSpeed ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetProjectileClass", InputSetTarget ), + + // Outputs + DEFINE_OUTPUT(m_OnFire, "OnFire"), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointProjectile::Precache() +{ + UTIL_PrecacheOther(STRING(m_target)); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointProjectile::Spawn() +{ + Precache(); + + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: Calculates owner entity +//----------------------------------------------------------------------------- +inline CBaseEntity *CPointProjectile::CalculateOwner( CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + if (m_iszOwner != NULL_STRING && !GetOwnerEntity()) + { + CBaseEntity *pOwner = gEntList.FindEntityByName(NULL, STRING(m_iszOwner), this, pActivator, pCaller); + if (pOwner) + SetOwnerEntity(pOwner); + } + + return GetOwnerEntity() ? GetOwnerEntity() : this; +} + +//----------------------------------------------------------------------------- +// Purpose: Fires projectile and output +//----------------------------------------------------------------------------- +inline CBaseEntity *CPointProjectile::CreateProjectile( Vector &vecOrigin, QAngle &angAngles, Vector &vecDir, CBaseEntity *pOwner ) +{ + CBaseEntity *pProjectile = CreateNoSpawn(STRING(m_target), vecOrigin, angAngles, pOwner); + if (!pProjectile) + { + Warning("WARNING: %s unable to create projectile class %s!\n", GetDebugName(), STRING(m_target)); + return NULL; + } + + pProjectile->SetAbsVelocity(vecDir * m_flSpeed); + DispatchSpawn(pProjectile); + + pProjectile->SetDamage(m_flDamage); + + m_OnFire.Set(pProjectile, pProjectile, pOwner); + + return pProjectile; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointProjectile::InputFire( inputdata_t &inputdata ) +{ + Vector vecOrigin = GetAbsOrigin(); + QAngle angAngles = GetAbsAngles(); + + CBaseEntity *pOwner = CalculateOwner(inputdata.pActivator, inputdata.pCaller); + if (pOwner && m_bFireProjectilesFromOwner) + vecOrigin = pOwner->GetAbsOrigin(); + + Vector vecDir; + AngleVectors(angAngles, &vecDir); + + CreateProjectile(vecOrigin, angAngles, vecDir, pOwner); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointProjectile::InputFireAtEntity( inputdata_t &inputdata ) +{ + CBaseEntity *pTarget = inputdata.value.Entity(); + if (!pTarget) + return; + + Vector vecOrigin = GetAbsOrigin(); + + CBaseEntity *pOwner = CalculateOwner(inputdata.pActivator, inputdata.pCaller); + if (pOwner && m_bFireProjectilesFromOwner) + vecOrigin = pOwner->GetAbsOrigin(); + + Vector vecDir = (pTarget->WorldSpaceCenter() - vecOrigin); + VectorNormalize(vecDir); + + QAngle angAngles; + VectorAngles(vecDir, angAngles); + + CreateProjectile(vecOrigin, angAngles, vecDir, pOwner); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointProjectile::InputFireAtPosition( inputdata_t &inputdata ) +{ + Vector vecInput; + inputdata.value.Vector3D(vecInput); + + Vector vecOrigin = GetAbsOrigin(); + + CBaseEntity *pOwner = CalculateOwner(inputdata.pActivator, inputdata.pCaller); + if (pOwner && m_bFireProjectilesFromOwner) + vecOrigin = pOwner->GetAbsOrigin(); + + Vector vecDir = (vecInput - vecOrigin); + VectorNormalize(vecDir); + + QAngle angAngles; + VectorAngles(vecDir, angAngles); + + CreateProjectile(vecOrigin, angAngles, vecDir, pOwner); +} diff --git a/game/server/mapbase/point_radiation_source.cpp b/game/server/mapbase/point_radiation_source.cpp new file mode 100644 index 00000000..febe0c1a --- /dev/null +++ b/game/server/mapbase/point_radiation_source.cpp @@ -0,0 +1,140 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ==== +// +// An entity that triggers the player's geiger counter. +// +// Doesn't cause any actual damage. Should be parentable. +// +//============================================================================= + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + + +class CPointRadiationSource : public CPointEntity +{ +public: + DECLARE_CLASS( CPointRadiationSource, CPointEntity ); + DECLARE_DATADESC(); + + void Spawn(); + + void RadiationThink(); + + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + + bool m_bTestPVS; + float m_flRadius; + float m_flIntensity = 1.0f; + + bool m_bDisabled; +}; + +BEGIN_DATADESC( CPointRadiationSource ) + + // Function Pointers + DEFINE_FUNCTION( RadiationThink ), + + // Fields + DEFINE_KEYFIELD( m_bTestPVS, FIELD_BOOLEAN, "TestPVS" ), + DEFINE_INPUT( m_flRadius, FIELD_FLOAT, "SetRadius" ), + DEFINE_INPUT( m_flIntensity, FIELD_FLOAT, "SetIntensity" ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + +END_DATADESC() + + +LINK_ENTITY_TO_CLASS( point_radiation_source, CPointRadiationSource ); + + +//----------------------------------------------------------------------------- +// Purpose: Called when spawning, after keyvalues have been handled. +//----------------------------------------------------------------------------- +void CPointRadiationSource::Spawn( void ) +{ + BaseClass::Spawn(); + + if (!m_bDisabled) + { + SetThink( &CPointRadiationSource::RadiationThink ); + SetNextThink( gpGlobals->curtime + random->RandomFloat(0.0, 0.5) ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointRadiationSource::InputEnable( inputdata_t &inputdata ) +{ + m_bDisabled = false; + + SetThink( &CPointRadiationSource::RadiationThink ); + SetNextThink( gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointRadiationSource::InputDisable( inputdata_t &inputdata ) +{ + m_bDisabled = true; + + SetThink( NULL ); + SetNextThink( TICK_NEVER_THINK ); + + // Must update player + //CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + //if (pPlayer) + //{ + // pPlayer->NotifyNearbyRadiationSource(1000); + //} +} + +//----------------------------------------------------------------------------- +// Purpose: Trigger hurt that causes radiation will do a radius check and set +// the player's geiger counter level according to distance from center +// of trigger. +//----------------------------------------------------------------------------- +void CPointRadiationSource::RadiationThink( void ) +{ + CBasePlayer *pPlayer = NULL; + if (m_bTestPVS) + { + CBaseEntity *pPVSPlayer = CBaseEntity::Instance(UTIL_FindClientInPVS(edict())); + if (pPVSPlayer) + { + pPlayer = static_cast(pPVSPlayer); + } + } + else + { + pPlayer = UTIL_GetLocalPlayer(); + } + + if (pPlayer) + { + // get range to player; + float flRange = pPlayer->GetAbsOrigin().DistTo((GetAbsOrigin())); + if (m_flRadius <= 0 || flRange < m_flRadius) + { + if (m_flIntensity == 0) + { + Warning("%s: INTENSITY IS ZERO!!! Can't notify of radiation\n", GetDebugName()); + return; + } + + //flRange *= 3.0f; + flRange /= m_flIntensity; + pPlayer->NotifyNearbyRadiationSource(flRange); + } + } + + SetNextThink( gpGlobals->curtime + 0.25 ); +} diff --git a/game/server/mapbase/variant_tools.h b/game/server/mapbase/variant_tools.h new file mode 100644 index 00000000..21e631fb --- /dev/null +++ b/game/server/mapbase/variant_tools.h @@ -0,0 +1,43 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VARIANT_TOOLS_H +#define VARIANT_TOOLS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "cbase.h" + +// Quick way to define variants in a datadesc. +extern ISaveRestoreOps *variantFuncs; +#define DEFINE_VARIANT(name) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, variantFuncs, NULL } +#define DEFINE_KEYVARIANT(name,mapname) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, variantFuncs, NULL } + +// Most of these are defined in variant_t.cpp. + +// Creates a variant_t from the given string. +// It could return as a String or a Float. +variant_t Variant_Parse(const char *szValue); + +// Intended to convert FIELD_INPUT I/O parameters to other values, like integers, floats, or even entities. +// This only changes FIELD_STRING variants. Other data like FIELD_EHANDLE or FIELD_INTEGER are not affected. +variant_t Variant_ParseInput(inputdata_t inputdata); + +// A simpler version of Variant_ParseInput that does not allow FIELD_EHANDLE. +variant_t Variant_ParseString(variant_t value); + +// val1 == val2 +bool Variant_Equal(variant_t val1, variant_t val2, bool bLenAllowed = true); + +// val1 > val2 +bool Variant_Greater(variant_t val1, variant_t val2, bool bLenAllowed = true); + +// val1 >= val2 +bool Variant_GreaterOrEqual(variant_t val1, variant_t val2, bool bLenAllowed = true); + +#endif \ No newline at end of file diff --git a/game/server/mapbase/vgui_text_display.cpp b/game/server/mapbase/vgui_text_display.cpp new file mode 100644 index 00000000..84e0ac63 --- /dev/null +++ b/game/server/mapbase/vgui_text_display.cpp @@ -0,0 +1,437 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Displays easy, flexible VGui text. Mapbase equivalent of point_worldtext. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "vguiscreen.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define SF_TESTDISPLAY_START_DISABLED (1 << 0) + +//----------------------------------------------------------------------------- +// vgui_text_display +//----------------------------------------------------------------------------- +class CVGuiTextDisplay : public CBaseEntity +{ +public: + + DECLARE_CLASS( CVGuiTextDisplay, CBaseEntity ); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CVGuiTextDisplay(); + virtual ~CVGuiTextDisplay(); + + virtual bool KeyValue( const char *szKeyName, const char *szValue ); + + virtual int UpdateTransmitState(); + virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ); + + virtual void Spawn( void ); + virtual void Precache( void ); + virtual void OnRestore( void ); + + void ScreenVisible( bool bVisible ); + + void Disable( void ); + void Enable( void ); + + void InputDisable( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + void InputToggle( inputdata_t &inputdata ); + + void InputSetMessage( inputdata_t &inputdata ); + void InputSetTextAlignment( inputdata_t &inputdata ); + void InputSetFont( inputdata_t &inputdata ); + void InputSetResolution( inputdata_t &inputdata ); + void InputSetTextSize( inputdata_t &inputdata ); + +private: + + // Control panel + void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ); + void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName ); + void SpawnControlPanels( void ); + void RestoreControlPanels( void ); + +private: + CNetworkVar( bool, m_bEnabled ); + + CNetworkString( m_szDisplayText, 256 ); + CNetworkVar( int, m_iContentAlignment ); + CNetworkString( m_szFont, 64 ); + CNetworkVar( int, m_iResolution ); + float m_flTextSize; + + //CNetworkColor32( m_DisplayColor ); // Use render color + + bool m_bDoFullTransmit; + + CHandle m_hScreen; +}; + +LINK_ENTITY_TO_CLASS( vgui_text_display, CVGuiTextDisplay ); + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- +BEGIN_DATADESC( CVGuiTextDisplay ) + + DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), + + DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "message" ), + DEFINE_KEYFIELD( m_iContentAlignment, FIELD_INTEGER, "alignment" ), + DEFINE_AUTO_ARRAY_KEYFIELD( m_szFont, FIELD_CHARACTER, "font" ), + DEFINE_KEYFIELD( m_iResolution, FIELD_INTEGER, "resolution" ), + DEFINE_KEYFIELD( m_flTextSize, FIELD_FLOAT, "textsize" ), + + DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ), + + DEFINE_FIELD( m_hScreen, FIELD_EHANDLE ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetMessage", InputSetMessage ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTextAlignment", InputSetTextAlignment ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFont", InputSetFont ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetResolution", InputSetResolution ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPanelSize", InputSetTextSize ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CVGuiTextDisplay, DT_VGuiTextDisplay ) + SendPropBool( SENDINFO( m_bEnabled ) ), + SendPropString( SENDINFO( m_szDisplayText ) ), + SendPropInt( SENDINFO( m_iContentAlignment ) ), + SendPropString( SENDINFO( m_szFont ) ), + SendPropInt( SENDINFO( m_iResolution ) ), +END_SEND_TABLE() + +CVGuiTextDisplay::CVGuiTextDisplay() +{ + m_flTextSize = 100.0f; + m_iResolution = 200; + m_iContentAlignment = 7; // a_south +} + +CVGuiTextDisplay::~CVGuiTextDisplay() +{ + DestroyVGuiScreen( m_hScreen.Get() ); +} + +//----------------------------------------------------------------------------- +// Read in Hammer data +//----------------------------------------------------------------------------- +bool CVGuiTextDisplay::KeyValue( const char *szKeyName, const char *szValue ) +{ + // NOTE: Have to do these separate because they set two values instead of one + if( FStrEq( szKeyName, "angles" ) ) + { + Assert( GetMoveParent() == NULL ); + QAngle angles; + UTIL_StringToVector( angles.Base(), szValue ); + + // Because the vgui screen basis is strange (z is front, y is up, x is right) + // we need to rotate the typical basis before applying it + VMatrix mat, rotation, tmp; + MatrixFromAngles( angles, mat ); + MatrixBuildRotationAboutAxis( rotation, Vector( 0, 1, 0 ), 90 ); + MatrixMultiply( mat, rotation, tmp ); + MatrixBuildRotateZ( rotation, 90 ); + MatrixMultiply( tmp, rotation, mat ); + MatrixToAngles( mat, angles ); + SetAbsAngles( angles ); + } + else if( FStrEq( szKeyName, "message" ) ) + { + Q_strcpy( m_szDisplayText.GetForModify(), szValue ); + } + else if( FStrEq( szKeyName, "font" ) ) + { + Q_strcpy( m_szFont.GetForModify(), szValue ); + } + else if( FStrEq( szKeyName, "color" ) ) + { + // Use render color + return BaseClass::KeyValue( "rendercolor", szValue ); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +int CVGuiTextDisplay::UpdateTransmitState() +{ + if ( m_bDoFullTransmit ) + { + m_bDoFullTransmit = false; + return SetTransmitState( FL_EDICT_ALWAYS ); + } + + return SetTransmitState( FL_EDICT_FULLCHECK ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ) +{ + // Are we already marked for transmission? + if ( pInfo->m_pTransmitEdict->Get( entindex() ) ) + return; + + BaseClass::SetTransmit( pInfo, bAlways ); + + // Force our screen to be sent too. + m_hScreen->SetTransmit( pInfo, bAlways ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::Spawn( void ) +{ + Precache(); + + BaseClass::Spawn(); + + m_bEnabled = !HasSpawnFlags( SF_TESTDISPLAY_START_DISABLED ); + + SpawnControlPanels(); + + ScreenVisible( m_bEnabled ); + + m_bDoFullTransmit = true; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::Precache( void ) +{ + BaseClass::Precache(); + + PrecacheVGuiScreen( "text_display_panel" ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::OnRestore( void ) +{ + BaseClass::OnRestore(); + + RestoreControlPanels(); + + ScreenVisible( m_bEnabled ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::ScreenVisible( bool bVisible ) +{ + // Set its active state + m_hScreen->SetActive( bVisible ); + + if ( bVisible ) + { + m_hScreen->RemoveEffects( EF_NODRAW ); + } + else + { + m_hScreen->AddEffects( EF_NODRAW ); + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::Disable( void ) +{ + if ( !m_bEnabled ) + return; + + m_bEnabled = false; + + ScreenVisible( false ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::Enable( void ) +{ + if ( m_bEnabled ) + return; + + m_bEnabled = true; + + ScreenVisible( true ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputDisable( inputdata_t &inputdata ) +{ + Disable(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputEnable( inputdata_t &inputdata ) +{ + Enable(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputToggle( inputdata_t &inputdata ) +{ + m_bEnabled ? Disable() : Enable(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputSetMessage( inputdata_t &inputdata ) +{ + Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputSetTextAlignment( inputdata_t &inputdata ) +{ + m_iContentAlignment = inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputSetFont( inputdata_t &inputdata ) +{ + Q_strcpy( m_szFont.GetForModify(), inputdata.value.String() ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputSetResolution( inputdata_t &inputdata ) +{ + m_iResolution = inputdata.value.Int(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::InputSetTextSize( inputdata_t &inputdata ) +{ + m_flTextSize = inputdata.value.Float(); + + if (m_hScreen) + { + m_hScreen->SetActualSize( m_flTextSize, m_flTextSize ); + m_hScreen->SetLocalOrigin( m_hScreen->CollisionProp()->OBBCenter() * -1.0f ); + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ) +{ + pPanelName = "text_display_panel"; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName ) +{ + pPanelName = "vgui_screen"; +} + +//----------------------------------------------------------------------------- +// This is called by the base object when it's time to spawn the control panels +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::SpawnControlPanels() +{ + int nPanel; + for ( nPanel = 0; true; ++nPanel ) + { + const char *pScreenName; + GetControlPanelInfo( nPanel, pScreenName ); + if (!pScreenName) + continue; + + const char *pScreenClassname; + GetControlPanelClassName( nPanel, pScreenClassname ); + if ( !pScreenClassname ) + continue; + + float flWidth = m_flTextSize; + float flHeight = m_flTextSize; + + CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, this, this, 0 ); + pScreen->ChangeTeam( GetTeamNumber() ); + pScreen->SetActualSize( flWidth, flHeight ); + pScreen->SetLocalOrigin( pScreen->CollisionProp()->OBBCenter() * -1.0f ); + pScreen->SetActive( true ); + pScreen->MakeVisibleOnlyToTeammates( false ); + pScreen->SetTransparency( true ); + m_hScreen = pScreen; + + return; + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CVGuiTextDisplay::RestoreControlPanels( void ) +{ + int nPanel; + for ( nPanel = 0; true; ++nPanel ) + { + const char *pScreenName; + GetControlPanelInfo( nPanel, pScreenName ); + if (!pScreenName) + continue; + + const char *pScreenClassname; + GetControlPanelClassName( nPanel, pScreenClassname ); + if ( !pScreenClassname ) + continue; + + CVGuiScreen *pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( NULL, pScreenClassname ); + + while ( ( pScreen && pScreen->GetOwnerEntity() != this ) || Q_strcmp( pScreen->GetPanelName(), pScreenName ) != 0 ) + { + pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( pScreen, pScreenClassname ); + } + + if ( pScreen ) + { + m_hScreen = pScreen; + m_hScreen->SetActive( true ); + } + + return; + } +} diff --git a/game/server/mapentities.cpp b/game/server/mapentities.cpp index a08ad1ec..0ee82206 100644 --- a/game/server/mapentities.cpp +++ b/game/server/mapentities.cpp @@ -86,7 +86,7 @@ string_t ExtractParentName(string_t parentName) return parentName; char szToken[256]; - nexttoken(szToken, STRING(parentName), ','); + nexttoken(szToken, STRING(parentName), ',', sizeof(szToken)); return AllocPooledString(szToken); } @@ -208,7 +208,7 @@ void SetupParentsForSpawnList( int nEntities, HierarchicalSpawn_t *pSpawnList ) if ( strchr(STRING(pEntity->m_iParent), ',') ) { char szToken[256]; - const char *pAttachmentName = nexttoken(szToken, STRING(pEntity->m_iParent), ','); + const char *pAttachmentName = nexttoken(szToken, STRING(pEntity->m_iParent), ',', sizeof(szToken)); pEntity->m_iParent = AllocPooledString(szToken); CBaseEntity *pParent = gEntList.FindEntityByName( NULL, pEntity->m_iParent ); diff --git a/game/server/maprules.cpp b/game/server/maprules.cpp index 64001b57..91049ad8 100644 --- a/game/server/maprules.cpp +++ b/game/server/maprules.cpp @@ -12,6 +12,9 @@ #include "entitylist.h" #include "ai_hull.h" #include "entityoutput.h" +#ifdef MAPBASE +#include "eventqueue.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -224,6 +227,9 @@ class CGameEnd : public CRulePointEntity DECLARE_DATADESC(); void InputGameEnd( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputGameEndSP( inputdata_t &inputdata ); +#endif void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); private: }; @@ -232,6 +238,9 @@ BEGIN_DATADESC( CGameEnd ) // inputs DEFINE_INPUTFUNC( FIELD_VOID, "EndGame", InputGameEnd ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "EndGameSP", InputGameEndSP ), +#endif END_DATADESC() @@ -243,6 +252,17 @@ void CGameEnd::InputGameEnd( inputdata_t &inputdata ) g_pGameRules->EndMultiplayerGame(); } +#ifdef MAPBASE +void CGameEnd::InputGameEndSP( inputdata_t &inputdata ) +{ + // This basically just acts as a shortcut for the "startupmenu force"/disconnection command. + // Things like mapping competitions could change this code based on given strings for specific endings (e.g. background maps). + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + if (pPlayer) + engine->ClientCommand(pPlayer->edict(), "startupmenu force"); +} +#endif + void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if ( !CanFireForActivator( pActivator ) ) @@ -274,6 +294,12 @@ class CGameText : public CRulePointEntity void InputDisplay( inputdata_t &inputdata ); void Display( CBaseEntity *pActivator ); +#ifdef MAPBASE + void InputSetText ( inputdata_t &inputdata ); + void SetText( const char* pszStr ); + + void InputSetFont( inputdata_t &inputdata ) { m_strFont = inputdata.value.StringID(); } +#endif void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { @@ -284,6 +310,11 @@ class CGameText : public CRulePointEntity string_t m_iszMessage; hudtextparms_t m_textParms; + +#ifdef MAPBASE + string_t m_strFont; + bool m_bAutobreak; +#endif }; LINK_ENTITY_TO_CLASS( game_text, CGameText ); @@ -303,10 +334,19 @@ BEGIN_DATADESC( CGameText ) DEFINE_KEYFIELD( m_textParms.holdTime, FIELD_FLOAT, "holdtime" ), DEFINE_KEYFIELD( m_textParms.fxTime, FIELD_FLOAT, "fxtime" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_strFont, FIELD_STRING, "font" ), + DEFINE_KEYFIELD( m_bAutobreak, FIELD_BOOLEAN, "autobreak" ), +#endif + DEFINE_ARRAY( m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ), // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Display", InputDisplay ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetText", InputSetText ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFont", InputSetFont ), +#endif END_DATADESC() @@ -332,6 +372,13 @@ bool CGameText::KeyValue( const char *szKeyName, const char *szValue ) m_textParms.b2 = color[2]; m_textParms.a2 = color[3]; } +#ifdef MAPBASE + else if (FStrEq( szKeyName, "message" )) + { + // Needed for newline support + SetText( szValue ); + } +#endif else return BaseClass::KeyValue( szKeyName, szValue ); @@ -351,7 +398,11 @@ void CGameText::Display( CBaseEntity *pActivator ) if ( MessageToAll() ) { +#ifdef MAPBASE + UTIL_HudMessageAll( m_textParms, MessageGet(), STRING(m_strFont), m_bAutobreak ); +#else UTIL_HudMessageAll( m_textParms, MessageGet() ); +#endif } else { @@ -359,16 +410,54 @@ void CGameText::Display( CBaseEntity *pActivator ) if ( gpGlobals->maxClients == 1 ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); +#ifdef MAPBASE + UTIL_HudMessage( pPlayer, m_textParms, MessageGet(), STRING(m_strFont), m_bAutobreak ); +#else UTIL_HudMessage( pPlayer, m_textParms, MessageGet() ); +#endif } // Otherwise show the message to the player that triggered us. else if ( pActivator && pActivator->IsNetClient() ) { +#ifdef MAPBASE + UTIL_HudMessage( ToBasePlayer( pActivator ), m_textParms, MessageGet(), STRING(m_strFont), m_bAutobreak ); +#else UTIL_HudMessage( ToBasePlayer( pActivator ), m_textParms, MessageGet() ); +#endif } } } +#ifdef MAPBASE +void CGameText::InputSetText( inputdata_t &inputdata ) +{ + SetText( inputdata.value.String() ); +} + +void CGameText::SetText( const char* pszStr ) +{ + // Replace /n with \n + if (Q_strstr( pszStr, "/n" )) + { + CUtlStringList vecLines; + Q_SplitString( pszStr, "/n", vecLines ); + + char szMsg[512]; + Q_strncpy( szMsg, vecLines[0], sizeof( szMsg ) ); + + for (int i = 1; i < vecLines.Count(); i++) + { + Q_snprintf( szMsg, sizeof( szMsg ), "%s\n%s", szMsg, vecLines[i] ); + } + m_iszMessage = AllocPooledString( szMsg ); + } + else + { + m_iszMessage = AllocPooledString( pszStr ); + } +} +#endif + /* TODO: Replace with an entity I/O version // diff --git a/game/server/message_entity.cpp b/game/server/message_entity.cpp index e5bb114b..903947c1 100644 --- a/game/server/message_entity.cpp +++ b/game/server/message_entity.cpp @@ -17,6 +17,12 @@ #include "vstdlib/random.h" #include "engine/IEngineSound.h" #include "game.h" +#ifdef MAPBASE +#include +#include +#include "utlbuffer.h" +#include "saverestore_utlvector.h" +#endif #include "player.h" #include "entitylist.h" @@ -38,12 +44,18 @@ class CMessageEntity : public CPointEntity void Spawn( void ); void Activate( void ); void Think( void ); +#ifdef MAPBASE + virtual +#endif void DrawOverlays(void); virtual void UpdateOnRemove(); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + virtual void InputSetMessage( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); @@ -68,6 +80,9 @@ BEGIN_DATADESC( CMessageEntity ) // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetMessage", InputSetMessage ), +#endif END_DATADESC() @@ -172,6 +187,19 @@ void CMessageEntity::InputDisable( inputdata_t &inputdata ) m_bEnabled = false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMessageEntity::InputSetMessage( inputdata_t &inputdata ) +{ + char newmessage[256]; + Q_strncpy(newmessage, inputdata.value.String(), sizeof(newmessage)); + + m_messageText = AllocPooledString(newmessage); +} +#endif + // This is a hack to make point_message stuff appear in developer 0 release builds // for now void DrawMessageEntities() @@ -189,3 +217,124 @@ void DrawMessageEntities() me->DrawOverlays(); } } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CMessageEntityLocalized : public CMessageEntity +{ + DECLARE_CLASS( CMessageEntityLocalized, CMessageEntity ); + +public: + bool KeyValue(const char *szKeyName, const char *szValue); + void SetMessage(const char *szValue); + void DrawOverlays(void); + void InputSetMessage( inputdata_t &inputdata ); + + CUtlVector m_messageLines; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( point_message_localized, CMessageEntityLocalized ); + +BEGIN_DATADESC( CMessageEntityLocalized ) + + DEFINE_UTLVECTOR( m_messageLines, FIELD_STRING ), + + //DEFINE_INPUTFUNC( FIELD_STRING, "SetMessage", InputSetMessage ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Handles key values from the BSP before spawn is called. +//----------------------------------------------------------------------------- +bool CMessageEntityLocalized::KeyValue(const char *szKeyName, const char *szValue) +{ + if (FStrEq(szKeyName, "message")) + { + SetMessage(szValue); + return true; + } + + return BaseClass::KeyValue(szKeyName, szValue); +} + +// I would use "\\n", but Hammer doesn't let you use back slashes. +#define CONVERSION_CHAR "/n" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMessageEntityLocalized::SetMessage(const char *szValue) +{ + // Find a localization token matching this string + wchar_t *pszMessage = g_pVGuiLocalize->Find(szValue); + + // If this is a localized string, convert it back to char. + // If it isn't, just copy it right into this. + char szBackToChar[256]; + if (pszMessage) + g_pVGuiLocalize->ConvertUnicodeToANSI(pszMessage, szBackToChar, sizeof(szBackToChar)); + else + Q_strncpy(szBackToChar, szValue, sizeof(szBackToChar)); + + // szTemp is used to turn \n from localized strings into /n. + char szTemp[256]; + if (Q_strstr(szBackToChar, "\n")) + { + char *token = strtok(szBackToChar, "\n"); + while (token) + { + Q_snprintf(szTemp, sizeof(szTemp), "%s%s%s", szTemp, token, CONVERSION_CHAR); + token = strtok(NULL, "\n"); + } + } + else + { + Q_strncpy(szTemp, szBackToChar, sizeof(szTemp)); + } + + m_messageLines.RemoveAll(); + + CUtlStringList vecLines; + Q_SplitString(szTemp, CONVERSION_CHAR, vecLines); + FOR_EACH_VEC( vecLines, i ) + { + m_messageLines.AddToTail( AllocPooledString(vecLines[i]) ); + } + + vecLines.PurgeAndDeleteElements(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMessageEntityLocalized::InputSetMessage( inputdata_t &inputdata ) +{ + SetMessage(inputdata.value.String()); +} + +//------------------------------------------- +//------------------------------------------- +void CMessageEntityLocalized::DrawOverlays(void) +{ + if ( !m_drawText ) + return; + + if ( m_bDeveloperOnly && !g_pDeveloper->GetInt() ) + return; + + if ( !m_bEnabled ) + return; + + // display text if they are within range + int offset = 0; + FOR_EACH_VEC( m_messageLines, i ) + { + EntityText( offset, STRING(m_messageLines[i]), 0 ); + offset++; + } +} +#endif diff --git a/game/server/modelentities.cpp b/game/server/modelentities.cpp index 0c565ac4..3b6e3e3b 100644 --- a/game/server/modelentities.cpp +++ b/game/server/modelentities.cpp @@ -191,7 +191,7 @@ void CFuncBrush::TurnOn( void ) } -bool CFuncBrush::IsOn( void ) const +bool CFuncBrush::IsOn( void ) { return !IsEffectActive( EF_NODRAW ); } diff --git a/game/server/modelentities.h b/game/server/modelentities.h index 36cf5a7d..a8003b2d 100644 --- a/game/server/modelentities.h +++ b/game/server/modelentities.h @@ -18,7 +18,7 @@ //----------------------------------------------------------------------------- // Purpose: basic solid geometry // enabled state: brush is visible -// disabled state: brush not visible +// disabled staute: brush not visible //----------------------------------------------------------------------------- class CFuncBrush : public CBaseEntity { @@ -32,8 +32,8 @@ class CFuncBrush : public CBaseEntity virtual int DrawDebugTextOverlays( void ); - virtual void TurnOff( void ); - virtual void TurnOn( void ); + void TurnOff( void ); + void TurnOn( void ); // Input handlers void InputTurnOff( inputdata_t &inputdata ); @@ -56,7 +56,7 @@ class CFuncBrush : public CBaseEntity DECLARE_DATADESC(); - virtual bool IsOn( void ) const; + virtual bool IsOn( void ); }; diff --git a/game/server/monstermaker.cpp b/game/server/monstermaker.cpp index 98f1e02f..5d56eabf 100644 --- a/game/server/monstermaker.cpp +++ b/game/server/monstermaker.cpp @@ -18,6 +18,8 @@ #include "IEffects.h" #include "props.h" +#include "point_template.h" + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -114,6 +116,8 @@ END_DATADESC() //----------------------------------------------------------------------------- void CBaseNPCMaker::Spawn( void ) { + ScriptInstallPreSpawnHook(); + SetSolid( SOLID_NONE ); m_nLiveChildren = 0; Precache(); @@ -830,6 +834,12 @@ void CTemplateNPCMaker::MakeNPC( void ) pent->SetAbsAngles( angles ); } + if ( !ScriptPreInstanceSpawn( &m_ScriptScope, pEntity, m_iszTemplateData ) ) + { + UTIL_RemoveImmediate( pEntity ); + return; + } + m_OnSpawnNPC.Set( pEntity, pEntity, this ); if ( m_spawnflags & SF_NPCMAKER_FADE ) @@ -867,6 +877,8 @@ void CTemplateNPCMaker::MakeNPC( void ) SetUse( NULL ); } } + + ScriptPostSpawn( &m_ScriptScope, &pEntity, 1 ); } //----------------------------------------------------------------------------- diff --git a/game/server/movie_display.cpp b/game/server/movie_display.cpp new file mode 100644 index 00000000..b5a4476c --- /dev/null +++ b/game/server/movie_display.cpp @@ -0,0 +1,378 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: Allows movies to be played as a VGUI screen in the world +// +//=====================================================================================// + +#include "cbase.h" +#include "EnvMessage.h" +#include "fmtstr.h" +#include "vguiscreen.h" +#include "filesystem.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +class CMovieDisplay : public CBaseEntity +{ +public: + + DECLARE_CLASS( CMovieDisplay, CBaseEntity ); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CMovieDisplay() { m_bMuted = true; } + + virtual ~CMovieDisplay(); + + virtual bool KeyValue( const char *szKeyName, const char *szValue ); + + virtual int UpdateTransmitState(); + virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ); + + virtual void Spawn( void ); + virtual void Precache( void ); + virtual void OnRestore( void ); + + void ScreenVisible( bool bVisible ); + + void Disable( void ); + void Enable( void ); + + void InputDisable( inputdata_t &inputdata ); + void InputEnable( inputdata_t &inputdata ); + + void InputSetDisplayText( inputdata_t &inputdata ); + +private: + + // Control panel + void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ); + void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName ); + void SpawnControlPanels( void ); + void RestoreControlPanels( void ); + +private: + CNetworkVar( bool, m_bEnabled ); + CNetworkVar( bool, m_bLooping ); + CNetworkVar( bool, m_bMuted); + + CNetworkString( m_szDisplayText, 128 ); + + // Filename of the movie to play + CNetworkString( m_szMovieFilename, 128 ); + string_t m_strMovieFilename; + + // "Group" name. Screens of the same group name will play the same movie at the same time + // Effectively this lets multiple screens tune to the same "channel" in the world + CNetworkString( m_szGroupName, 128 ); + string_t m_strGroupName; + + int m_iScreenWidth; + int m_iScreenHeight; + + bool m_bDoFullTransmit; + + CHandle m_hScreen; +}; + +LINK_ENTITY_TO_CLASS( vgui_movie_display, CMovieDisplay ); + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- +BEGIN_DATADESC( CMovieDisplay ) + + DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), + + DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "displaytext" ), + + DEFINE_AUTO_ARRAY( m_szMovieFilename, FIELD_CHARACTER ), + DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "moviefilename" ), + + DEFINE_AUTO_ARRAY( m_szGroupName, FIELD_CHARACTER ), + DEFINE_KEYFIELD( m_strGroupName, FIELD_STRING, "groupname" ), + + DEFINE_KEYFIELD( m_iScreenWidth, FIELD_INTEGER, "width" ), + DEFINE_KEYFIELD( m_iScreenHeight, FIELD_INTEGER, "height" ), + DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "looping" ), + DEFINE_KEYFIELD( m_bMuted, FIELD_BOOLEAN, "muted"), + + DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ), + + DEFINE_FIELD( m_hScreen, FIELD_EHANDLE ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + + DEFINE_INPUTFUNC( FIELD_STRING, "SetDisplayText", InputSetDisplayText ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CMovieDisplay, DT_MovieDisplay ) + SendPropBool( SENDINFO( m_bEnabled ) ), + SendPropBool( SENDINFO( m_bLooping ) ), + SendPropBool( SENDINFO( m_bMuted ) ), + SendPropString( SENDINFO( m_szMovieFilename ) ), + SendPropString( SENDINFO( m_szGroupName ) ), +END_SEND_TABLE() + +CMovieDisplay::~CMovieDisplay() +{ + DestroyVGuiScreen( m_hScreen.Get() ); +} + +//----------------------------------------------------------------------------- +// Read in Hammer data +//----------------------------------------------------------------------------- + +bool CMovieDisplay::KeyValue( const char *szKeyName, const char *szValue ) +{ + // NOTE: Have to do these separate because they set two values instead of one + if( FStrEq( szKeyName, "angles" ) ) + { + Assert( GetMoveParent() == NULL ); + QAngle angles; + UTIL_StringToVector( angles.Base(), szValue ); + + // Because the vgui screen basis is strange (z is front, y is up, x is right) + // we need to rotate the typical basis before applying it + VMatrix mat, rotation, tmp; + MatrixFromAngles( angles, mat ); + MatrixBuildRotationAboutAxis( rotation, Vector( 0, 1, 0 ), 90 ); + MatrixMultiply( mat, rotation, tmp ); + MatrixBuildRotateZ( rotation, 90 ); + MatrixMultiply( tmp, rotation, mat ); + MatrixToAngles( mat, angles ); + SetAbsAngles( angles ); + + return true; + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +int CMovieDisplay::UpdateTransmitState() +{ + if ( m_bDoFullTransmit ) + { + m_bDoFullTransmit = false; + return SetTransmitState( FL_EDICT_ALWAYS ); + } + + return SetTransmitState( FL_EDICT_FULLCHECK ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ) +{ + // Are we already marked for transmission? + if ( pInfo->m_pTransmitEdict->Get( entindex() ) ) + return; + + BaseClass::SetTransmit( pInfo, bAlways ); + + // Force our screen to be sent too. + m_hScreen->SetTransmit( pInfo, bAlways ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::Spawn( void ) +{ + // Move the strings into a networkable form + Q_strcpy( m_szMovieFilename.GetForModify(), m_strMovieFilename.ToCStr() ); + Q_strcpy( m_szGroupName.GetForModify(), m_strGroupName.ToCStr() ); + + Precache(); + + BaseClass::Spawn(); + + m_bEnabled = false; + + SpawnControlPanels(); + + ScreenVisible( m_bEnabled ); + + m_bDoFullTransmit = true; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::Precache( void ) +{ + BaseClass::Precache(); + + PrecacheVGuiScreen( "video_display_screen" ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::OnRestore( void ) +{ + BaseClass::OnRestore(); + + RestoreControlPanels(); + + ScreenVisible( m_bEnabled ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::ScreenVisible( bool bVisible ) +{ + // Set its active state + m_hScreen->SetActive( bVisible ); + + if ( bVisible ) + { + m_hScreen->RemoveEffects( EF_NODRAW ); + } + else + { + m_hScreen->AddEffects( EF_NODRAW ); + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::Disable( void ) +{ + if ( !m_bEnabled ) + return; + + m_bEnabled = false; + + ScreenVisible( false ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::Enable( void ) +{ + if ( m_bEnabled ) + return; + + m_bEnabled = true; + + ScreenVisible( true ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::InputDisable( inputdata_t &inputdata ) +{ + Disable(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::InputEnable( inputdata_t &inputdata ) +{ + Enable(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::InputSetDisplayText( inputdata_t &inputdata ) +{ + Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ) +{ + pPanelName = "movie_display_screen"; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName ) +{ + pPanelName = "vgui_screen"; +} + +//----------------------------------------------------------------------------- +// This is called by the base object when it's time to spawn the control panels +//----------------------------------------------------------------------------- +void CMovieDisplay::SpawnControlPanels() +{ + int nPanel; + for ( nPanel = 0; true; ++nPanel ) + { + const char *pScreenName; + GetControlPanelInfo( nPanel, pScreenName ); + if (!pScreenName) + continue; + + const char *pScreenClassname; + GetControlPanelClassName( nPanel, pScreenClassname ); + if ( !pScreenClassname ) + continue; + + float flWidth = m_iScreenWidth; + float flHeight = m_iScreenHeight; + + CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, this, this, 0 ); + pScreen->ChangeTeam( GetTeamNumber() ); + pScreen->SetActualSize( flWidth, flHeight ); + pScreen->SetActive( true ); + pScreen->MakeVisibleOnlyToTeammates( false ); + pScreen->SetTransparency( true ); + m_hScreen = pScreen; + + return; + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CMovieDisplay::RestoreControlPanels( void ) +{ + int nPanel; + for ( nPanel = 0; true; ++nPanel ) + { + const char *pScreenName; + GetControlPanelInfo( nPanel, pScreenName ); + if (!pScreenName) + continue; + + const char *pScreenClassname; + GetControlPanelClassName( nPanel, pScreenClassname ); + if ( !pScreenClassname ) + continue; + + CVGuiScreen *pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( NULL, pScreenClassname ); + + while ( ( pScreen && pScreen->GetOwnerEntity() != this ) || Q_strcmp( pScreen->GetPanelName(), pScreenName ) != 0 ) + { + pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( pScreen, pScreenClassname ); + } + + if ( pScreen ) + { + m_hScreen = pScreen; + m_hScreen->SetActive( true ); + } + + return; + } +} diff --git a/game/server/nav.h b/game/server/nav.h index a955c3a8..0319991a 100644 --- a/game/server/nav.h +++ b/game/server/nav.h @@ -334,11 +334,11 @@ inline void DirectionToVector2D( NavDirType dir, Vector2D *v ) { switch( dir ) { - default: Assert(0); case NORTH: v->x = 0.0f; v->y = -1.0f; break; case SOUTH: v->x = 0.0f; v->y = 1.0f; break; case EAST: v->x = 1.0f; v->y = 0.0f; break; case WEST: v->x = -1.0f; v->y = 0.0f; break; + default: break; } } @@ -348,11 +348,11 @@ inline void CornerToVector2D( NavCornerType dir, Vector2D *v ) { switch( dir ) { - default: Assert(0); case NORTH_WEST: v->x = -1.0f; v->y = -1.0f; break; case NORTH_EAST: v->x = 1.0f; v->y = -1.0f; break; case SOUTH_EAST: v->x = 1.0f; v->y = 1.0f; break; case SOUTH_WEST: v->x = -1.0f; v->y = 1.0f; break; + default: break; } v->NormalizeInPlace(); @@ -365,8 +365,6 @@ inline void GetCornerTypesInDirection( NavDirType dir, NavCornerType *first, Nav { switch ( dir ) { - default: - Assert(0); case NORTH: *first = NORTH_WEST; *second = NORTH_EAST; @@ -383,6 +381,8 @@ inline void GetCornerTypesInDirection( NavDirType dir, NavCornerType *first, Nav *first = NORTH_WEST; *second = SOUTH_WEST; break; + default: + break; } } diff --git a/game/server/nav_area.cpp b/game/server/nav_area.cpp index 656f675d..73379f15 100644 --- a/game/server/nav_area.cpp +++ b/game/server/nav_area.cpp @@ -192,8 +192,6 @@ CNavArea::CNavArea( void ) m_avoidanceObstacleHeight = 0.0f; m_totalCost = 0.0f; - m_costSoFar = 0.0f; - m_pathLengthSoFar = 0.0f; ResetNodes(); @@ -246,8 +244,6 @@ CNavArea::CNavArea( void ) m_isInheritedFrom = false; m_funcNavCostVector.RemoveAll(); - - m_nVisTestCounter = (uint32)-1; } //-------------------------------------------------------------------------------------------------------------- @@ -3385,10 +3381,16 @@ void CNavArea::AddToOpenList( void ) } // insert self in ascending cost order + // Since costs are positive, IEEE754 let's us compare as integers (see http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm) CNavArea *area, *last = NULL; + int thisCostBits = *reinterpret_cast(&m_totalCost); + + Assert ( m_totalCost >= 0.0f ); for( area = m_openList; area; area = area->m_nextOpen ) { - if ( GetTotalCost() < area->GetTotalCost() ) + Assert ( area->GetTotalCost() >= 0.0f ); + int thoseCostBits = *reinterpret_cast(&area->m_totalCost); + if ( thisCostBits < thoseCostBits ) { break; } @@ -3707,7 +3709,7 @@ static Vector FindPositionInArea( CNavArea *area, NavCornerType corner ) pos = cornerPos + Vector( area->GetSizeX()*0.5f*multX, area->GetSizeY()*0.5f*multY, 0.0f ); if ( !area->IsOverlapping( pos ) ) { - AssertMsg( false, "A Hiding Spot can't be placed on its area at (%.0f %.0f %.0f)", cornerPos.x, cornerPos.y, cornerPos.z ); + AssertMsg( false, UTIL_VarArgs( "A Hiding Spot can't be placed on its area at (%.0f %.0f %.0f)", cornerPos.x, cornerPos.y, cornerPos.z) ); // Just pull the position to a small offset pos = cornerPos + Vector( 1.0f*multX, 1.0f*multY, 0.0f ); @@ -4285,9 +4287,6 @@ bool CNavArea::ComputeLighting( void ) //-------------------------------------------------------------------------------------------------------------- CON_COMMAND_F( nav_update_lighting, "Recomputes lighting values", FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - int numComputed = 0; if ( args.ArgC() == 2 ) { @@ -5631,7 +5630,7 @@ void CNavArea::ComputeVisibilityToMesh( void ) /** * The center and all four corners must ALL be visible */ -bool CNavArea::IsEntirelyVisible( const Vector &eye, const CBaseEntity *ignore ) const +bool CNavArea::IsEntirelyVisible( const Vector &eye, CBaseEntity *ignore ) const { Vector corner; trace_t result; @@ -5664,7 +5663,7 @@ bool CNavArea::IsEntirelyVisible( const Vector &eye, const CBaseEntity *ignore ) /** * The center or any of the four corners may be visible */ -bool CNavArea::IsPartiallyVisible( const Vector &eye, const CBaseEntity *ignore ) const +bool CNavArea::IsPartiallyVisible( const Vector &eye, CBaseEntity *ignore ) const { Vector corner; trace_t result; diff --git a/game/server/nav_area.h b/game/server/nav_area.h index 0c97a662..7c18a5e0 100644 --- a/game/server/nav_area.h +++ b/game/server/nav_area.h @@ -18,15 +18,6 @@ // BOTPORT: Clean up relationship between team index and danger storage in nav areas enum { MAX_NAV_TEAMS = 2 }; -#ifdef STAGING_ONLY -inline void DebuggerBreakOnNaN_StagingOnly( float val ) -{ - if ( IS_NAN( val ) ) - DebuggerBreak(); -} -#else -#define DebuggerBreakOnNaN_StagingOnly( _val ) -#endif class CFuncElevator; class CFuncNavPrerequisite; @@ -454,14 +445,14 @@ class CNavArea : protected CNavAreaCriticalData static void ClearSearchLists( void ); // clears the open and closed lists for a new search - void SetTotalCost( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_totalCost = value; } - float GetTotalCost( void ) const { DebuggerBreakOnNaN_StagingOnly( m_totalCost ); return m_totalCost; } + void SetTotalCost( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_totalCost = value; } + float GetTotalCost( void ) const { return m_totalCost; } - void SetCostSoFar( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_costSoFar = value; } - float GetCostSoFar( void ) const { DebuggerBreakOnNaN_StagingOnly( m_costSoFar ); return m_costSoFar; } + void SetCostSoFar( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_costSoFar = value; } + float GetCostSoFar( void ) const { return m_costSoFar; } - void SetPathLengthSoFar( float value ) { DebuggerBreakOnNaN_StagingOnly( value ); Assert( value >= 0.0 && !IS_NAN(value) ); m_pathLengthSoFar = value; } - float GetPathLengthSoFar( void ) const { DebuggerBreakOnNaN_StagingOnly( m_pathLengthSoFar ); return m_pathLengthSoFar; } + void SetPathLengthSoFar( float value ) { Assert( value >= 0.0 && !IS_NAN(value) ); m_pathLengthSoFar = value; } + float GetPathLengthSoFar( void ) const { return m_pathLengthSoFar; } //- editing ----------------------------------------------------------------------------------------- virtual void Draw( void ) const; // draw area for debugging & editing @@ -524,8 +515,8 @@ class CNavArea : protected CNavAreaCriticalData } }; - virtual bool IsEntirelyVisible( const Vector &eye, const CBaseEntity *ignore = NULL ) const; // return true if entire area is visible from given eyepoint (CPU intensive) - virtual bool IsPartiallyVisible( const Vector &eye, const CBaseEntity *ignore = NULL ) const; // return true if any portion of the area is visible from given eyepoint (CPU intensive) + virtual bool IsEntirelyVisible( const Vector &eye, CBaseEntity *ignore = NULL ) const; // return true if entire area is visible from given eyepoint (CPU intensive) + virtual bool IsPartiallyVisible( const Vector &eye, CBaseEntity *ignore = NULL ) const; // return true if any portion of the area is visible from given eyepoint (CPU intensive) virtual bool IsPotentiallyVisible( const CNavArea *area ) const; // return true if given area is potentially visible from somewhere in this area (very fast) virtual bool IsPotentiallyVisibleToTeam( int team ) const; // return true if any portion of this area is visible to anyone on the given team (very fast) @@ -823,9 +814,14 @@ inline bool CNavArea::IsDegenerate( void ) const //-------------------------------------------------------------------------------------------------------------- inline CNavArea *CNavArea::GetAdjacentArea( NavDirType dir, int i ) const { - if ( ( i < 0 ) || ( i >= m_connect[dir].Count() ) ) - return NULL; - return m_connect[dir][i].area; + for( int iter = 0; iter < m_connect[dir].Count(); ++iter ) + { + if (i == 0) + return m_connect[dir][iter].area; + --i; + } + + return NULL; } //-------------------------------------------------------------------------------------------------------------- diff --git a/game/server/nav_entities.cpp b/game/server/nav_entities.cpp index 04951113..83a7dd83 100644 --- a/game/server/nav_entities.cpp +++ b/game/server/nav_entities.cpp @@ -91,7 +91,8 @@ void CFuncNavCost::Spawn( void ) // chop space-delimited string into individual tokens if ( tags ) { - char *buffer = V_strdup ( tags ); + char *buffer = new char [ strlen( tags ) + 1 ]; + Q_strcpy( buffer, tags ); for( char *token = strtok( buffer, " " ); token; token = strtok( NULL, " " ) ) { diff --git a/game/server/nav_file.cpp b/game/server/nav_file.cpp index ea3bf5ad..7de114ec 100644 --- a/game/server/nav_file.cpp +++ b/game/server/nav_file.cpp @@ -1318,11 +1318,12 @@ const CUtlVector< Place > *CNavMesh::GetPlacesFromNavFile( bool *hasUnnamedPlace if ( IsX360() ) { // 360 has compressed NAVs - if ( CLZMA::IsCompressed( (unsigned char *)fileBuffer.Base() ) ) + CLZMA lzma; + if ( lzma.IsCompressed( (unsigned char *)fileBuffer.Base() ) ) { - int originalSize = CLZMA::GetActualSize( (unsigned char *)fileBuffer.Base() ); + int originalSize = lzma.GetActualSize( (unsigned char *)fileBuffer.Base() ); unsigned char *pOriginalData = new unsigned char[originalSize]; - CLZMA::Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData ); + lzma.Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData ); fileBuffer.AssumeMemory( pOriginalData, originalSize, originalSize, CUtlBuffer::READ_ONLY ); } } @@ -1410,11 +1411,12 @@ NavErrorType CNavMesh::Load( void ) if ( IsX360() ) { // 360 has compressed NAVs - if ( CLZMA::IsCompressed( (unsigned char *)fileBuffer.Base() ) ) + CLZMA lzma; + if ( lzma.IsCompressed( (unsigned char *)fileBuffer.Base() ) ) { - int originalSize = CLZMA::GetActualSize( (unsigned char *)fileBuffer.Base() ); + int originalSize = lzma.GetActualSize( (unsigned char *)fileBuffer.Base() ); unsigned char *pOriginalData = new unsigned char[originalSize]; - CLZMA::Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData ); + lzma.Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData ); fileBuffer.AssumeMemory( pOriginalData, originalSize, originalSize, CUtlBuffer::READ_ONLY ); } } diff --git a/game/server/nav_generate.cpp b/game/server/nav_generate.cpp index e10d01ea..c9d2ea4b 100644 --- a/game/server/nav_generate.cpp +++ b/game/server/nav_generate.cpp @@ -1229,12 +1229,9 @@ void CNavMesh::RemoveOverlappingObstacleTopAreas() static void CommandNavCheckStairs( void ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - TheNavMesh->MarkStairAreas(); } -static ConCommand nav_check_stairs( "nav_check_stairs", CommandNavCheckStairs, "Update the nav mesh STAIRS attribute", FCVAR_CHEAT ); +static ConCommand nav_check_stairs( "nav_check_stairs", CommandNavCheckStairs, "Update the nav mesh STAIRS attribute" ); //-------------------------------------------------------------------------------------------------------------- /** @@ -1448,9 +1445,6 @@ bool CNavArea::TestStairs( void ) //-------------------------------------------------------------------------------------------------------------- CON_COMMAND_F( nav_test_stairs, "Test the selected set for being on stairs", FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - int count = 0; const NavAreaVector &selectedSet = TheNavMesh->GetSelectedSet(); @@ -1815,8 +1809,6 @@ void CNavMesh::StitchAreaIntoMesh( CNavArea *area, NavDirType dir, Functor &func Vector corner1, corner2; switch ( dir ) { - default: - Assert(0); case NORTH: corner1 = area->GetCorner( NORTH_WEST ); corner2 = area->GetCorner( NORTH_EAST ); @@ -4938,8 +4930,5 @@ void CNavMesh::PostProcessCliffAreas() CON_COMMAND_F( nav_gen_cliffs_approx, "Mark cliff areas, post-processing approximation", FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - TheNavMesh->PostProcessCliffAreas(); } diff --git a/game/server/nav_merge.cpp b/game/server/nav_merge.cpp index d62764ab..1d5330ca 100644 --- a/game/server/nav_merge.cpp +++ b/game/server/nav_merge.cpp @@ -303,7 +303,7 @@ void CNavMesh::CommandNavMergeMesh( const CCommand &args ) //-------------------------------------------------------------------------------------------------------- int NavMeshMergeAutocomplete( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ) { - char *commandName = "nav_merge_mesh"; + const char *commandName = "nav_merge_mesh"; int numMatches = 0; partial += Q_strlen( commandName ) + 1; int partialLength = Q_strlen( partial ); diff --git a/game/server/nav_mesh.cpp b/game/server/nav_mesh.cpp index 09326aaf..8a15b39e 100644 --- a/game/server/nav_mesh.cpp +++ b/game/server/nav_mesh.cpp @@ -49,9 +49,7 @@ ConVar nav_max_vis_delta_list_length( "nav_max_vis_delta_list_length", "64", FCV extern ConVar nav_show_potentially_visible; -#ifdef STAGING_ONLY int g_DebugPathfindCounter = 0; -#endif bool FindGroundForNode( Vector *pos, Vector *normal ); @@ -1700,9 +1698,6 @@ static ConCommand nav_clear_selected_set( "nav_clear_selected_set", CommandNavCl //---------------------------------------------------------------------------------- CON_COMMAND_F( nav_dump_selected_set_positions, "Write the (x,y,z) coordinates of the centers of all selected nav areas to a file.", FCVAR_GAMEDLL | FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - const NavAreaVector &selectedSet = TheNavMesh->GetSelectedSet(); CUtlBuffer fileBuffer( 4096, 1024*1024, CUtlBuffer::TEXT_BUFFER ); @@ -1735,9 +1730,6 @@ CON_COMMAND_F( nav_dump_selected_set_positions, "Write the (x,y,z) coordinates o //---------------------------------------------------------------------------------- CON_COMMAND_F( nav_show_dumped_positions, "Show the (x,y,z) coordinate positions of the given dump file.", FCVAR_GAMEDLL | FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - CUtlBuffer fileBuffer( 4096, 1024*1024, CUtlBuffer::TEXT_BUFFER ); // filename is local to game dir for Steam, so we need to prepend game dir for regular file save @@ -1770,9 +1762,6 @@ CON_COMMAND_F( nav_show_dumped_positions, "Show the (x,y,z) coordinate positions //---------------------------------------------------------------------------------- CON_COMMAND_F( nav_select_larger_than, "Select nav areas where both dimensions are larger than the given size.", FCVAR_GAMEDLL | FCVAR_CHEAT ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - if ( args.ArgC() > 1 ) { float minSize = atof( args[1] ); @@ -2674,9 +2663,6 @@ void CNavMesh::CommandNavMarkWalkable( void ) { Vector pos; - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - if (nav_edit.GetBool()) { // we are in edit mode, use the edit cursor's location diff --git a/game/server/nav_mesh.h b/game/server/nav_mesh.h index a69cdc03..24faed41 100644 --- a/game/server/nav_mesh.h +++ b/game/server/nav_mesh.h @@ -1259,10 +1259,8 @@ extern CNavMesh *TheNavMesh; // factory for creating the Navigation Mesh extern CNavMesh *NavMeshFactory( void ); -#ifdef STAGING_ONLY // for debugging the A* algorithm, if nonzero, show debug display and decrement for each pathfind extern int g_DebugPathfindCounter; -#endif //-------------------------------------------------------------------------------------------------------------- diff --git a/game/server/nav_pathfind.h b/game/server/nav_pathfind.h index e9c2d7ec..b06b46a0 100644 --- a/game/server/nav_pathfind.h +++ b/game/server/nav_pathfind.h @@ -16,9 +16,7 @@ #include "mathlib/ssemath.h" #include "nav_area.h" -#ifdef STAGING_ONLY extern int g_DebugPathfindCounter; -#endif //------------------------------------------------------------------------------------------------------------------- @@ -110,9 +108,7 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go *closestArea = startArea; } -#ifdef STAGING_ONLY bool isDebug = ( g_DebugPathfindCounter-- > 0 ); -#endif if (startArea == NULL) return false; @@ -158,12 +154,10 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go // get next area to check CNavArea *area = CNavArea::PopOpenList(); -#ifdef STAGING_ONLY if ( isDebug ) { area->DrawFilled( 0, 255, 0, 128, 30.0f ); } -#endif // don't consider blocked areas if ( area->IsBlocked( teamID, ignoreNavBlockers ) ) @@ -345,13 +339,7 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go continue; float newCostSoFar = costFunc( newArea, area, ladder, elevator, length ); - - // NaNs really mess this function up causing tough to track down hangs. If - // we get inf back, clamp it down to a really high number. - DebuggerBreakOnNaN_StagingOnly( newCostSoFar ); - if ( IS_NAN( newCostSoFar ) ) - newCostSoFar = 1e30f; - + // check if cost functor says this area is a dead-end if ( newCostSoFar < 0.0f ) continue; @@ -364,7 +352,7 @@ bool NavAreaBuildPath( CNavArea *startArea, CNavArea *goalArea, const Vector *go // Make sure that any jump to a new area incurs some pathfinsing // cost, to avoid us spinning our wheels over insignificant cost // benefit, floating point precision bug, or busted cost functor. - float minNewCostSoFar = area->GetCostSoFar() * 1.00001f + 0.00001f; + float minNewCostSoFar = area->GetCostSoFar() * 1.00001 + 0.00001; newCostSoFar = Max( newCostSoFar, minNewCostSoFar ); // stop if path length limit reached diff --git a/game/server/networkstringtable_gamedll.h b/game/server/networkstringtable_gamedll.h index 20965aa7..903c7c6c 100644 --- a/game/server/networkstringtable_gamedll.h +++ b/game/server/networkstringtable_gamedll.h @@ -24,11 +24,11 @@ class CStringTableSaveRestoreOps; #define MAX_MATERIAL_STRINGS ( 1 << MAX_MATERIAL_STRING_BITS ) #define OVERLAY_MATERIAL_INVALID_STRING ( MAX_MATERIAL_STRINGS - 1 ) -#define MAX_CHOREO_SCENES_STRING_BITS 13 +#define MAX_CHOREO_SCENES_STRING_BITS 12 #define MAX_CHOREO_SCENES_STRINGS ( 1 << MAX_CHOREO_SCENES_STRING_BITS ) #define CHOREO_SCENES_INVALID_STRING ( MAX_CHOREO_SCENES_STRINGS - 1 ) -#define MAX_PARTICLESYSTEMS_STRING_BITS 12 +#define MAX_PARTICLESYSTEMS_STRING_BITS 11 #define MAX_PARTICLESYSTEMS_STRINGS ( 1 << MAX_PARTICLESYSTEMS_STRING_BITS ) #define PARTICLESYSTEMS_INVALID_STRING ( MAX_PARTICLESYSTEMS_STRINGS - 1 ) diff --git a/game/server/npc_talker.cpp b/game/server/npc_talker.cpp index a04c9ff3..ebb94583 100644 --- a/game/server/npc_talker.cpp +++ b/game/server/npc_talker.cpp @@ -373,7 +373,11 @@ void CNPCSimpleTalker::AlertFriends( CBaseEntity *pKiller ) } else { +#ifdef MAPBASE + if( IRelationType(pKiller) <= D_FR) +#else if( IRelationType(pKiller) == D_HT) +#endif { // Killed by an enemy!!! CNPCSimpleTalker *pAlly = (CNPCSimpleTalker *)pNPC; diff --git a/game/server/npc_vehicledriver.cpp b/game/server/npc_vehicledriver.cpp index 45da78dd..8e38d769 100644 --- a/game/server/npc_vehicledriver.cpp +++ b/game/server/npc_vehicledriver.cpp @@ -721,7 +721,13 @@ bool CNPC_VehicleDriver::OverridePathMove( float flInterval ) // Have we reached our target? See if we've passed the current waypoint's plane. Vector vecAbsMins, vecAbsMaxs; +#ifdef MAPBASE + vecAbsMins = m_hVehicleEntity->CollisionProp()->OBBMins(); + vecAbsMaxs = m_hVehicleEntity->CollisionProp()->OBBMaxs(); + m_hVehicleEntity->CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs ); +#else CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs ); +#endif if ( BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pCurrentWaypoint->planeWaypoint ) == 3 ) { if ( WaypointReached() ) diff --git a/game/server/particle_system.cpp b/game/server/particle_system.cpp index 33fcd322..23e98eaf 100644 --- a/game/server/particle_system.cpp +++ b/game/server/particle_system.cpp @@ -25,9 +25,13 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CParticleSystem, DT_ParticleSystem) SendPropInt( SENDINFO(m_iEffectIndex), MAX_PARTICLESYSTEMS_STRING_BITS, SPROP_UNSIGNED ), SendPropBool( SENDINFO(m_bActive) ), +#ifdef MAPBASE + SendPropBool( SENDINFO(m_bDestroyImmediately) ), +#endif SendPropFloat( SENDINFO(m_flStartTime) ), SendPropArray3( SENDINFO_ARRAY3(m_hControlPointEnts), SendPropEHandle( SENDINFO_ARRAY(m_hControlPointEnts) ) ), + SendPropArray3( SENDINFO_ARRAY3(m_vControlPointVecs), SendPropVector( SENDINFO_ARRAY(m_vControlPointVecs) ) ), SendPropArray3( SENDINFO_ARRAY3(m_iControlPointParents), SendPropInt( SENDINFO_ARRAY(m_iControlPointParents), 3, SPROP_UNSIGNED ) ), SendPropBool( SENDINFO(m_bWeatherEffect) ), END_SEND_TABLE() @@ -36,6 +40,9 @@ BEGIN_DATADESC( CParticleSystem ) DEFINE_KEYFIELD( m_bStartActive, FIELD_BOOLEAN, "start_active" ), DEFINE_KEYFIELD( m_bWeatherEffect, FIELD_BOOLEAN, "flag_as_weather" ), DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_FIELD( m_bDestroyImmediately, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_flStartTime, FIELD_TIME ), DEFINE_KEYFIELD( m_iszEffectName, FIELD_STRING, "effect_name" ), //DEFINE_FIELD( m_iEffectIndex, FIELD_INTEGER ), // Don't save. Refind after loading. @@ -116,12 +123,16 @@ BEGIN_DATADESC( CParticleSystem ) DEFINE_INPUTFUNC( FIELD_VOID, "Start", InputStart ), DEFINE_INPUTFUNC( FIELD_VOID, "Stop", InputStop ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "DestroyImmediately", InputDestroyImmediately ), +#endif DEFINE_THINKFUNC( StartParticleSystemThink ), END_DATADESC() LINK_ENTITY_TO_CLASS( info_particle_system, CParticleSystem ); +LINK_ENTITY_TO_CLASS( info_particle_system_coordinate, CParticleSystemCoordinate ); //----------------------------------------------------------------------------- // Purpose: @@ -199,6 +210,9 @@ void CParticleSystem::StartParticleSystem( void ) { m_flStartTime = gpGlobals->curtime; m_bActive = true; +#ifdef MAPBASE + m_bDestroyImmediately = false; +#endif // Setup our control points at this time (in case our targets weren't around at spawn time) ReadControlPointEnts(); @@ -229,6 +243,17 @@ void CParticleSystem::InputStop( inputdata_t &inputdata ) StopParticleSystem(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CParticleSystem::InputDestroyImmediately( inputdata_t &inputdata ) +{ + m_bDestroyImmediately = true; + StopParticleSystem(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Find each entity referred to by m_iszControlPointNames and // resolve it into the corresponding slot in m_hControlPointEnts @@ -237,17 +262,28 @@ void CParticleSystem::ReadControlPointEnts( void ) { for ( int i = 0 ; i < kMAXCONTROLPOINTS; ++i ) { - if ( m_iszControlPointNames[i] == NULL_STRING ) - continue; - - CBaseEntity *pPointEnt = gEntList.FindEntityGeneric( NULL, STRING( m_iszControlPointNames[i] ), this ); - Assert( pPointEnt != NULL ); - if ( pPointEnt == NULL ) + if (UsesCoordinates()) { - Warning("Particle system %s could not find control point entity (%s)\n", GetEntityName().ToCStr(), m_iszControlPointNames[i].ToCStr() ); - continue; + Vector vecCoords; + // cast str to vector, add vector to array + const char* pszVector = STRING(m_iszControlPointNames[i]); + UTIL_StringToVector(vecCoords.Base(), pszVector); + m_vControlPointVecs.Set(i, vecCoords); } + else + { + if ( m_iszControlPointNames[i] == NULL_STRING ) + continue; - m_hControlPointEnts.Set( i, pPointEnt ); + CBaseEntity *pPointEnt = gEntList.FindEntityGeneric( NULL, STRING( m_iszControlPointNames[i] ), this ); + Assert( pPointEnt != NULL ); + if ( pPointEnt == NULL ) + { + Warning("Particle system %s could not find control point entity (%s)\n", GetEntityName().ToCStr(), m_iszControlPointNames[i].ToCStr() ); + continue; + } + + m_hControlPointEnts.Set( i, pPointEnt ); + } } } diff --git a/game/server/particle_system.h b/game/server/particle_system.h index ecf758c2..42e213f5 100644 --- a/game/server/particle_system.h +++ b/game/server/particle_system.h @@ -34,10 +34,15 @@ class CParticleSystem : public CBaseEntity void InputStart( inputdata_t &inputdata ); void InputStop( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputDestroyImmediately( inputdata_t &inputdata ); +#endif void StartParticleSystemThink( void ); enum { kMAXCONTROLPOINTS = 63 }; ///< actually one less than the total number of cpoints since 0 is assumed to be me + virtual bool UsesCoordinates( void ) { return false; } + protected: /// Load up and resolve the entities that are supposed to be the control points @@ -47,13 +52,27 @@ class CParticleSystem : public CBaseEntity string_t m_iszEffectName; CNetworkVar( bool, m_bActive ); +#ifdef MAPBASE + CNetworkVar( bool, m_bDestroyImmediately ); +#endif CNetworkVar( int, m_iEffectIndex ) CNetworkVar( float, m_flStartTime ); // Time at which this effect was started. This is used after restoring an active effect. string_t m_iszControlPointNames[kMAXCONTROLPOINTS]; CNetworkArray( EHANDLE, m_hControlPointEnts, kMAXCONTROLPOINTS ); + CNetworkArray( Vector, m_vControlPointVecs, kMAXCONTROLPOINTS ); CNetworkArray( unsigned char, m_iControlPointParents, kMAXCONTROLPOINTS ); CNetworkVar( bool, m_bWeatherEffect ); }; +//----------------------------------------------------------------------------- +// Purpose: An entity that spawns and controls a particle system using coordinates. +//----------------------------------------------------------------------------- +class CParticleSystemCoordinate : public CParticleSystem +{ + DECLARE_CLASS( CParticleSystemCoordinate, CParticleSystem ); +public: + virtual bool UsesCoordinates( void ) { return true; } +}; + #endif // PARTICLE_SYSTEM_H diff --git a/game/server/pathtrack.cpp b/game/server/pathtrack.cpp index 539a6e03..2a77666d 100644 --- a/game/server/pathtrack.cpp +++ b/game/server/pathtrack.cpp @@ -17,9 +17,15 @@ //----------------------------------------------------------------------------- BEGIN_DATADESC( CPathTrack ) +#ifdef MAPBASE + DEFINE_FIELD( m_pnext, FIELD_EHANDLE ), + DEFINE_FIELD( m_pprevious, FIELD_EHANDLE ), + DEFINE_FIELD( m_paltpath, FIELD_EHANDLE ), +#else DEFINE_FIELD( m_pnext, FIELD_CLASSPTR ), DEFINE_FIELD( m_pprevious, FIELD_CLASSPTR ), DEFINE_FIELD( m_paltpath, FIELD_CLASSPTR ), +#endif DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "radius" ), DEFINE_FIELD( m_length, FIELD_FLOAT ), diff --git a/game/server/physconstraint.cpp b/game/server/physconstraint.cpp index 8fa25cdd..467c7cfb 100644 --- a/game/server/physconstraint.cpp +++ b/game/server/physconstraint.cpp @@ -569,6 +569,8 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) // Missing one object, assume the world instead if ( info.pObjects[0] == NULL && info.pObjects[1] ) { + // This brokens hanging lamps in hl2mp +#if !defined ( HL2MP ) if ( Q_strlen(STRING(m_nameAttach1)) ) { Warning("Bogus constraint %s (attaches ENTITY NOT FOUND:%s to %s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); @@ -577,11 +579,15 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) return; #endif // HL2_EPISODIC } +#endif info.pObjects[0] = g_PhysWorldObject; info.massScale[0] = info.massScale[1] = 1.0f; // no mass scale on world constraint + } else if ( info.pObjects[0] && !info.pObjects[1] ) { + // This brokens hanging lamps in hl2mp +#if !defined ( HL2MP ) if ( Q_strlen(STRING(m_nameAttach2)) ) { Warning("Bogus constraint %s (attaches %s to ENTITY NOT FOUND:%s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); @@ -590,6 +596,7 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) return; #endif // HL2_EPISODIC } +#endif info.pObjects[1] = info.pObjects[0]; info.pObjects[0] = g_PhysWorldObject; // Try to make the world object consistently object0 for ease of implementation info.massScale[0] = info.massScale[1] = 1.0f; // no mass scale on world constraint @@ -1038,6 +1045,16 @@ class CPhysBallSocket : public CPhysConstraint for ( int i = 0; i < 2; i++ ) { info.pObjects[i]->WorldToLocal( &ballsocket.constraintPosition[i], GetAbsOrigin() ); + // HACKHACK - the mapper forgot to put in some sane physics damping + float damping, adamping; + info.pObjects[i]->GetDamping(&damping, &adamping); + if (damping < .2f) { + damping = .2f; + } + if (adamping < .2f) { + adamping = .2f; + } + info.pObjects[i]->SetDamping(&damping, &adamping); } GetBreakParams( ballsocket.constraint, info ); ballsocket.constraint.torqueLimit = 0; diff --git a/game/server/physics.cpp b/game/server/physics.cpp index bec86f5f..3e2ab69c 100644 --- a/game/server/physics.cpp +++ b/game/server/physics.cpp @@ -514,7 +514,12 @@ int CCollisionEvent::ShouldCollide_2( IPhysicsObject *pObj0, IPhysicsObject *pOb if ( pEntity0->edict() && pEntity1->edict() ) { // don't collide with your owner +#ifdef MAPBASE + if ( (pEntity0->GetOwnerEntity() == pEntity1 && !pEntity0->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER)) + || (pEntity1->GetOwnerEntity() == pEntity0 && !pEntity1->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER)) ) +#else if ( pEntity0->GetOwnerEntity() == pEntity1 || pEntity1->GetOwnerEntity() == pEntity0 ) +#endif return 0; } @@ -719,7 +724,7 @@ bool CCollisionEvent::ShouldFreezeContacts( IPhysicsObject **pObjectList, int ob { if ( m_lastTickFrictionError > gpGlobals->tickcount || m_lastTickFrictionError < (gpGlobals->tickcount-1) ) { - DevWarning("Performance Warning: large friction system (%d objects)!!!\n", objectCount ); + CGWarning( 1, CON_GROUP_PHYSICS, "Performance Warning: large friction system (%d objects)!!!\n", objectCount ); #if _DEBUG for ( int i = 0; i < objectCount; i++ ) { @@ -992,7 +997,7 @@ int CCollisionEvent::ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObje { if ( pObj0->GetGameFlags() & FVPHYSICS_PART_OF_RAGDOLL ) { - DevMsg(2, "Solving ragdoll self penetration! %s (%s) (%d v %d)\n", pObj0->GetName(), pEntity0->GetDebugName(), pObj0->GetGameIndex(), pObj1->GetGameIndex() ); + CGMsg( 2, CON_GROUP_PHYSICS, "Solving ragdoll self penetration! %s (%s) (%d v %d)\n", pObj0->GetName(), pEntity0->GetDebugName(), pObj0->GetGameIndex(), pObj1->GetGameIndex() ); ragdoll_t *pRagdoll = Ragdoll_GetRagdoll( pEntity0 ); pRagdoll->pGroup->SolvePenetration( pObj0, pObj1 ); return false; @@ -1025,11 +1030,11 @@ int CCollisionEvent::ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObje { int index0 = physcollision->CollideIndex( pObj0->GetCollide() ); int index1 = physcollision->CollideIndex( pObj1->GetCollide() ); - DevMsg(1, "***Inter-penetration on %s (%d & %d) (%.0f, %.0f)\n", pName1?pName1:"(null)", index0, index1, gpGlobals->curtime, eventTime ); + CGMsg( 1, CON_GROUP_PHYSICS, "***Inter-penetration on %s (%d & %d) (%.0f, %.0f)\n", pName1?pName1:"(null)", index0, index1, gpGlobals->curtime, eventTime ); } else { - DevMsg(1, "***Inter-penetration between %s(%s) AND %s(%s) (%.0f, %.0f)\n", pName1?pName1:"(null)", pEntity0->GetDebugName(), pName2?pName2:"(null)", pEntity1->GetDebugName(), gpGlobals->curtime, eventTime ); + CGMsg( 1, CON_GROUP_PHYSICS, "***Inter-penetration between %s(%s) AND %s(%s) (%.0f, %.0f)\n", pName1?pName1:"(null)", pEntity0->GetDebugName(), pName2?pName2:"(null)", pEntity1->GetDebugName(), gpGlobals->curtime, eventTime ); } } #endif @@ -1148,13 +1153,13 @@ void PhysSolidOverride( solid_t &solid, string_t overrideScript ) // suck out the comma delimited tokens and turn them into quoted key/values char szToken[256]; - const char *pStr = nexttoken(szToken, STRING(overrideScript), ','); + const char *pStr = nexttoken(szToken, STRING(overrideScript), ',', sizeof(szToken)); while ( szToken[0] != 0 ) { Q_strncat( pTmpString, "\"", sizeof(pTmpString), COPY_ALL_CHARACTERS ); Q_strncat( pTmpString, szToken, sizeof(pTmpString), COPY_ALL_CHARACTERS ); Q_strncat( pTmpString, "\" ", sizeof(pTmpString), COPY_ALL_CHARACTERS ); - pStr = nexttoken(szToken, pStr, ','); + pStr = nexttoken(szToken, pStr, ',', sizeof(szToken)); } // terminate the script Q_strncat( pTmpString, "}", sizeof(pTmpString), COPY_ALL_CHARACTERS ); @@ -1328,8 +1333,8 @@ CON_COMMAND_F(surfaceprop, "Reports the surface properties at the cursor", FCVAR Vector vecVelocity = tr.startpos - tr.endpos; int length = vecVelocity.Length(); - Msg("Hit surface \"%s\" (entity %s, model \"%s\" %s), texture \"%s\"\n", physprops->GetPropName( tr.surface.surfaceProps ), tr.m_pEnt->GetClassname(), pModelName, modelStuff.Access(), tr.surface.name); - Msg("Distance to surface: %d\n", length ); + CGMsg( 0, CON_GROUP_PHYSICS, "Hit surface \"%s\" (entity %s, model \"%s\" %s), texture \"%s\"\n", physprops->GetPropName( tr.surface.surfaceProps ), tr.m_pEnt->GetClassname(), pModelName, modelStuff.Access(), tr.surface.name ); + CGMsg( 0, CON_GROUP_PHYSICS, "Distance to surface: %d\n", length ); } } @@ -1337,12 +1342,12 @@ static void OutputVPhysicsDebugInfo( CBaseEntity *pEntity ) { if ( pEntity ) { - Msg("Entity %s (%s) %s Collision Group %d\n", pEntity->GetClassname(), pEntity->GetDebugName(), pEntity->IsNavIgnored() ? "NAV IGNORE" : "", pEntity->GetCollisionGroup() ); + CGMsg( 0, CON_GROUP_PHYSICS, "Entity %s (%s) %s Collision Group %d\n", pEntity->GetClassname(), pEntity->GetDebugName(), pEntity->IsNavIgnored() ? "NAV IGNORE" : "", pEntity->GetCollisionGroup() ); CUtlVector list; g_Collisions.GetListOfPenetratingEntities( pEntity, list ); for ( int i = 0; i < list.Count(); i++ ) { - Msg(" penetration with entity %s (%s)\n", list[i]->GetDebugName(), STRING(list[i]->GetModelName()) ); + CGMsg( 0, CON_GROUP_PHYSICS, " penetration with entity %s (%s)\n", list[i]->GetDebugName(), STRING( list[i]->GetModelName() ) ); } IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; @@ -1353,7 +1358,7 @@ static void OutputVPhysicsDebugInfo( CBaseEntity *pEntity ) { for ( int i = 0; i < physCount; i++ ) { - Msg("Object %d (of %d) =========================\n", i+1, physCount ); + CGMsg( 0, CON_GROUP_PHYSICS, "Object %d (of %d) =========================\n", i + 1, physCount ); pList[i]->OutputDebugInfo(); } } @@ -1491,7 +1496,7 @@ static void DebugConstraints( CBaseEntity *pEntity ) pModel1 = STRING(pAttach[1]->GetModelName()); index1 = pAttachVPhysics[1]->GetGameIndex(); } - Msg("**********************\n%s connects %s(%s:%d) to %s(%s:%d)\n", constraints[i]->GetClassname(), pName0, pModel0, index0, pName1, pModel1, index1 ); + CGMsg( 0, CON_GROUP_PHYSICS, "**********************\n%s connects %s(%s:%d) to %s(%s:%d)\n", constraints[i]->GetClassname(), pName0, pModel0, index0, pName1, pModel1, index1 ); DebugConstraint(constraints[i]); constraints[i]->m_debugOverlays |= OVERLAY_BBOX_BIT | OVERLAY_TEXT_BIT; } @@ -1637,7 +1642,7 @@ CON_COMMAND( physics_budget, "Times the cost of each active object" ) for ( i = 0; i < ents.Count(); i++ ) { float fraction = times[i] / totalTime; - Msg( "%s (%s): %.3fms (%.3f%%) @ %s\n", ents[i]->GetClassname(), ents[i]->GetDebugName(), fraction * totalTime * 1000.0f, fraction * 100.0f, VecToString(ents[i]->GetAbsOrigin()) ); + CGMsg( 0, CON_GROUP_PHYSICS, "%s (%s): %.3fms (%.3f%%) @ %s\n", ents[i]->GetClassname(), ents[i]->GetDebugName(), fraction * totalTime * 1000.0f, fraction * 100.0f, VecToString( ents[i]->GetAbsOrigin() ) ); } g_Collisions.BufferTouchEvents( false ); } @@ -1680,7 +1685,7 @@ void PhysFrame( float deltaTime ) if ( deltaTime > 1.0f || deltaTime < 0.0f ) { deltaTime = 0; - Msg( "Reset physics clock\n" ); + CGMsg( 0, CON_GROUP_PHYSICS, "Reset physics clock\n" ); } else if ( deltaTime > 0.1f ) // limit incoming time to 100ms { @@ -1738,7 +1743,7 @@ void PhysFrame( float deltaTime ) CBaseEntity *pEntity = pItem->hEnt.Get(); if ( !pEntity ) { - Msg( "Dangling pointer to physics entity!!!\n" ); + CGMsg( 0, CON_GROUP_PHYSICS, "Dangling pointer to physics entity!!!\n" ); continue; } @@ -1760,7 +1765,7 @@ void PhysFrame( float deltaTime ) g_PhysAverageSimTime += (simRealTime * 0.2); if ( lastObjectCount != 0 || activeCount != 0 ) { - Msg( "Physics: %3d objects, %4.1fms / AVG: %4.1fms\n", activeCount, simRealTime * 1000, g_PhysAverageSimTime * 1000 ); + CGMsg( 0, CON_GROUP_PHYSICS, "Physics: %3d objects, %4.1fms / AVG: %4.1fms\n", activeCount, simRealTime * 1000, g_PhysAverageSimTime * 1000 ); } lastObjectCount = activeCount; @@ -1924,7 +1929,7 @@ void PhysForceEntityToSleep( CBaseEntity *pEntity, IPhysicsObject *pObject ) if ( !pObject || !pObject->IsMoveable() ) return; - DevMsg(2, "Putting entity to sleep: %s\n", pEntity->GetClassname() ); + CGMsg( 2, CON_GROUP_PHYSICS, "Putting entity to sleep: %s\n", pEntity->GetClassname() ); MEM_ALLOC_CREDIT(); IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; int physCount = pEntity->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) ); @@ -2019,7 +2024,7 @@ void CCollisionEvent::FlushQueuedOperations() // testing, if this assert fires it proves we've fixed the crash // after that the assert + warning can safely be removed Assert(0); - Warning("Physics queue not empty, error!\n"); + CGWarning( 0, CON_GROUP_PHYSICS, "Physics queue not empty, error!\n" ); loopCount++; UpdateTouchEvents(); UpdateDamageEvents(); @@ -2768,7 +2773,7 @@ void PhysCallbackDamage( CBaseEntity *pEntity, const CTakeDamageInfo &info ) g_Collisions.AddDamageEvent( pEntity, info, pInflictorPhysics, false, vec3_origin, vec3_origin ); if ( pEntity && info.GetInflictor() ) { - DevMsg( 2, "Warning: Physics damage event with no recovery info!\nObjects: %s, %s\n", pEntity->GetClassname(), info.GetInflictor()->GetClassname() ); + CGMsg( 2, CON_GROUP_PHYSICS, "Warning: Physics damage event with no recovery info!\nObjects: %s, %s\n", pEntity->GetClassname(), info.GetInflictor()->GetClassname() ); } } else @@ -2827,10 +2832,10 @@ IPhysicsObject *FindPhysicsObjectByName( const char *pName, CBaseEntity *pErrorE { const char *pErrorName = pErrorEntity ? pErrorEntity->GetClassname() : "Unknown"; Vector origin = pErrorEntity ? pErrorEntity->GetAbsOrigin() : vec3_origin; - DevWarning("entity %s at %s has physics attachment to more than one entity with the name %s!!!\n", pErrorName, VecToString(origin), pName ); + CGWarning( 1, CON_GROUP_PHYSICS, "entity %s at %s has physics attachment to more than one entity with the name %s!!!\n", pErrorName, VecToString( origin ), pName ); while ( ( pEntity = gEntList.FindEntityByName( pEntity, pName ) ) != NULL ) { - DevWarning("Found %s\n", pEntity->GetClassname() ); + CGWarning( 1, CON_GROUP_PHYSICS, "Found %s\n", pEntity->GetClassname() ); } break; @@ -2848,7 +2853,7 @@ void CC_AirDensity( const CCommand &args ) if ( args.ArgC() < 2 ) { - Msg( "air_density \nCurrent air density is %.2f\n", physenv->GetAirDensity() ); + CGMsg( 0, CON_GROUP_PHYSICS, "air_density \nCurrent air density is %.2f\n", physenv->GetAirDensity() ); } else { diff --git a/game/server/physics_impact_damage.cpp b/game/server/physics_impact_damage.cpp index 164568e2..312b8a1e 100644 --- a/game/server/physics_impact_damage.cpp +++ b/game/server/physics_impact_damage.cpp @@ -335,15 +335,32 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { - if ( gpGlobals->maxClients == 1 ) + // if the player is holding the object, use its real mass (player holding reduced the mass) + CBasePlayer *pPlayer = NULL; + + if ( 1 == gpGlobals->maxClients ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + else { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) + { + pPlayer = tempPlayer; + break; + } } } + + if ( pPlayer ) + { + otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + } } // NOTE: sum the mass of each object in this system for the purpose of damage @@ -438,16 +455,23 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co } else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { - if ( gpGlobals->maxClients == 1 ) + // if the player is holding the object, use it's real mass (player holding reduced the mass) + CBasePlayer *pPlayer = NULL; + if ( 1 == gpGlobals->maxClients ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + else { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] ); - if ( mass > 0 ) + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) { - invMass = 1.0f / mass; + pPlayer = tempPlayer; + break; } } } diff --git a/game/server/physics_main.cpp b/game/server/physics_main.cpp index a27a669a..eb6ceee6 100644 --- a/game/server/physics_main.cpp +++ b/game/server/physics_main.cpp @@ -7,12 +7,12 @@ #include "cbase.h" -#ifdef _WIN32 +#if POSIX || _MSC_VER >= 1900 +#include +#elif defined(_WIN32) #include "typeinfo.h" // BUGBUG: typeinfo stomps some of the warning settings (in yvals.h) #pragma warning(disable:4244) -#elif POSIX -#include #else #error "need typeinfo defined" #endif @@ -742,9 +742,7 @@ void CPhysicsPushedEntities::GenerateBlockingEntityListAddBox( const Vector &vec } } -#ifdef TF_DLL -#include "tf_logic_robot_destruction.h" -#endif + //----------------------------------------------------------------------------- // Purpose: Gets a list of all entities hierarchically attached to the root //----------------------------------------------------------------------------- @@ -944,8 +942,8 @@ void CBaseEntity::PhysicsDispatchThink( BASEPTR thinkFunc ) if ( thinkLimit ) { // calculate running time of the AI in milliseconds - float time = ( engine->Time() - startTime ) * 1000.0f; - if ( time > thinkLimit ) + float flTime = ( engine->Time() - startTime ) * 1000.0f; + if ( flTime > thinkLimit ) { #if defined( _XBOX ) && !defined( _RETAIL ) if ( vprof_think_limit.GetBool() ) @@ -958,14 +956,14 @@ void CBaseEntity::PhysicsDispatchThink( BASEPTR thinkFunc ) CAI_BaseNPC *pNPC = MyNPCPointer(); if (pNPC && pNPC->GetCurSchedule()) { - pNPC->ReportOverThinkLimit( time ); + pNPC->ReportOverThinkLimit( flTime ); } else { #ifdef _WIN32 - Msg( "%s(%s) thinking for %.02f ms!!!\n", GetClassname(), typeid(this).raw_name(), time ); + Msg( "%s(%s) thinking for %.02f ms!!!\n", GetClassname(), typeid(this).raw_name(), flTime ); #elif POSIX - Msg( "%s(%s) thinking for %.02f ms!!!\n", GetClassname(), typeid(this).name(), time ); + Msg( "%s(%s) thinking for %.02f ms!!!\n", GetClassname(), typeid(this).name(), flTime ); #else #error "typeinfo" #endif @@ -1843,9 +1841,7 @@ void CBaseEntity::PhysicsStepRunTimestep( float timestep ) { bool wasonground; bool inwater; -#if 0 bool hitsound = false; -#endif float speed, newspeed, control; float friction; @@ -1866,12 +1862,10 @@ void CBaseEntity::PhysicsStepRunTimestep( float timestep ) { if ( !( ( GetFlags() & FL_SWIM ) && ( GetWaterLevel() > 0 ) ) ) { -#if 0 if ( GetAbsVelocity()[2] < ( GetCurrentGravity() * -0.1 ) ) { hitsound = true; } -#endif if ( !inwater ) { diff --git a/game/server/physics_prop_ragdoll.cpp b/game/server/physics_prop_ragdoll.cpp index 72635ea8..93efddc7 100644 --- a/game/server/physics_prop_ragdoll.cpp +++ b/game/server/physics_prop_ragdoll.cpp @@ -20,10 +20,18 @@ #include "AI_Criteria.h" #include "ragdoll_shared.h" #include "hierarchy.h" +#ifdef MAPBASE +#include "decals.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +ConVar ragdoll_autointeractions("ragdoll_autointeractions", "1", FCVAR_NONE, "Controls whether we should rely on hardcoded keyvalues or automatic flesh checks for ragdoll physgun interactions."); +#define IsBody() VPhysicsIsFlesh() +#endif + //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- @@ -48,6 +56,9 @@ const float ATTACHED_DAMPING_SCALE = 50.0f; #define SF_RAGDOLLPROP_MOTIONDISABLED 0x4000 #define SF_RAGDOLLPROP_ALLOW_STRETCH 0x8000 #define SF_RAGDOLLPROP_STARTASLEEP 0x10000 +#ifdef MAPBASE +#define SF_RAGDOLLPROP_FIXED_CONSTRAINTS 0x20000 +#endif //----------------------------------------------------------------------------- // Networking @@ -83,9 +94,17 @@ BEGIN_DATADESC(CRagdollProp) DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "StartRagdollBoogie", InputStartRadgollBoogie ), +#else DEFINE_INPUTFUNC( FIELD_VOID, "StartRagdollBoogie", InputStartRadgollBoogie ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "EnableMotion", InputEnableMotion ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableMotion", InputDisableMotion ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "Wake", InputWake ), + DEFINE_INPUTFUNC( FIELD_VOID, "Sleep", InputSleep ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputTurnOff ), DEFINE_INPUTFUNC( FIELD_FLOAT, "FadeAndRemove", InputFadeAndRemove ), @@ -140,9 +159,33 @@ BEGIN_DATADESC(CRagdollProp) DEFINE_RAGDOLL_ELEMENT( 21 ), DEFINE_RAGDOLL_ELEMENT( 22 ), DEFINE_RAGDOLL_ELEMENT( 23 ), +#ifdef MAPBASE + DEFINE_RAGDOLL_ELEMENT( 24 ), + DEFINE_RAGDOLL_ELEMENT( 25 ), + DEFINE_RAGDOLL_ELEMENT( 26 ), + DEFINE_RAGDOLL_ELEMENT( 27 ), + DEFINE_RAGDOLL_ELEMENT( 28 ), + DEFINE_RAGDOLL_ELEMENT( 29 ), + DEFINE_RAGDOLL_ELEMENT( 30 ), + DEFINE_RAGDOLL_ELEMENT( 31 ), +#endif END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CRagdollProp, CBaseAnimating, "Ragdoll physics prop." ) + + DEFINE_SCRIPTFUNC_NAMED( GetSourceClassNameAsCStr, "GetSourceClassName", "Gets the ragdoll's source classname." ) + DEFINE_SCRIPTFUNC( SetSourceClassName, "Sets the ragdoll's source classname." ) + DEFINE_SCRIPTFUNC( HasPhysgunInteraction, "Checks if the ragdoll has the specified interaction." ) + + // TODO: Proper shared ragdoll funcs? + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRagdollObject, "GetRagdollObject", "Gets the ragdoll object of the specified index." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetRagdollObjectCount, "GetRagdollObjectCount", "Gets the number of ragdoll objects on this ragdoll." ) + +END_SCRIPTDESC() +#endif + //----------------------------------------------------------------------------- // Disable auto fading under dx7 or when level fades are specified //----------------------------------------------------------------------------- @@ -158,8 +201,10 @@ void CRagdollProp::Spawn( void ) // Starts out as the default fade scale value m_flDefaultFadeScale = m_flFadeScale; +#ifndef MAPBASE // NOTE: If this fires, then the assert or the datadesc is wrong! (see DEFINE_RAGDOLL_ELEMENT above) Assert( RAGDOLL_MAX_ELEMENTS == 24 ); +#endif Precache(); SetModel( STRING( GetModelName() ) ); @@ -359,7 +404,11 @@ void CRagdollProp::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t r } m_bHasBeenPhysgunned = true; +#ifdef MAPBASE + if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" ) ) +#else if( HasPhysgunInteraction( "onpickup", "boogie" ) ) +#endif { if ( reason == PUNTED_BY_CANNON ) { @@ -397,7 +446,11 @@ void CRagdollProp::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reaso m_hPhysicsAttacker = pPhysGunUser; m_flLastPhysicsInfluenceTime = gpGlobals->curtime; +#ifdef MAPBASE + if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" ) ) +#else if( HasPhysgunInteraction( "onpickup", "boogie" ) ) +#endif { CRagdollBoogie::Create( this, 150, gpGlobals->curtime, 3.0f, SF_RAGDOLL_BOOGIE_ELECTRICAL ); } @@ -416,7 +469,11 @@ void CRagdollProp::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reaso if ( Reason != LAUNCHED_BY_CANNON ) return; +#ifdef MAPBASE + if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onlaunch", "spin_zaxis" ) ) +#else if( HasPhysgunInteraction( "onlaunch", "spin_zaxis" ) ) +#endif { Vector vecAverageCenter( 0, 0, 0 ); @@ -615,8 +672,21 @@ void CRagdollProp::HandleFirstCollisionInteractions( int index, gamevcollisionev } } +#ifdef MAPBASE + int iVPhysicsFlesh = VPhysicsGetFlesh(); + bool bRagdollAutoInt = (ragdoll_autointeractions.GetBool() == true && iVPhysicsFlesh); + bool bAlienBloodSplat = HasPhysgunInteraction( "onfirstimpact", "alienbloodsplat" ); + if (bRagdollAutoInt && !bAlienBloodSplat) + { + // Alien blood? + bAlienBloodSplat = (iVPhysicsFlesh == CHAR_TEX_ALIENFLESH || iVPhysicsFlesh == CHAR_TEX_ANTLION); + } + + if( bRagdollAutoInt || bAlienBloodSplat || HasPhysgunInteraction( "onfirstimpact", "bloodsplat" ) ) +#else bool bAlienBloodSplat = HasPhysgunInteraction( "onfirstimpact", "alienbloodsplat" ); if( bAlienBloodSplat || HasPhysgunInteraction( "onfirstimpact", "bloodsplat" ) ) +#endif { IPhysicsObject *pObj = VPhysicsGetObject(); @@ -646,7 +716,11 @@ void CRagdollProp::ClearFlagsThink( void ) //----------------------------------------------------------------------------- AngularImpulse CRagdollProp::PhysGunLaunchAngularImpulse() { +#ifdef MAPBASE + if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onlaunch", "spin_zaxis" ) ) +#else if( HasPhysgunInteraction( "onlaunch", "spin_zaxis" ) ) +#endif { // Don't add in random angular impulse if this object is supposed to spin in a specific way. AngularImpulse ang( 0, 0, 0 ); @@ -700,20 +774,24 @@ void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const params.pCurrentBones = pBoneToWorld; params.jointFrictionScale = 1.0; params.allowStretch = HasSpawnFlags(SF_RAGDOLLPROP_ALLOW_STRETCH); +#ifdef MAPBASE + params.fixedConstraints = HasSpawnFlags(SF_RAGDOLLPROP_FIXED_CONSTRAINTS); +#else params.fixedConstraints = false; +#endif RagdollCreate( m_ragdoll, params, physenv ); RagdollApplyAnimationAsVelocity( m_ragdoll, pPrevBones, pBoneToWorld, dt ); if ( m_anglesOverrideString != NULL_STRING && Q_strlen(m_anglesOverrideString.ToCStr()) > 0 ) { char szToken[2048]; - const char *pStr = nexttoken(szToken, STRING(m_anglesOverrideString), ','); + const char *pStr = nexttoken(szToken, STRING(m_anglesOverrideString), ',', sizeof(szToken)); // anglesOverride is index,angles,index,angles (e.g. "1, 22.5 123.0 0.0, 2, 0 0 0, 3, 0 0 180.0") while ( szToken[0] != 0 ) { int objectIndex = atoi(szToken); // sanity check to make sure this token is an integer Assert( atof(szToken) == ((float)objectIndex) ); - pStr = nexttoken(szToken, pStr, ','); + pStr = nexttoken(szToken, pStr, ',', sizeof(szToken)); Assert( szToken[0] ); if ( objectIndex >= m_ragdoll.listCount ) { @@ -740,7 +818,7 @@ void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const MatrixSetColumn( out, 3, pBoneToWorld[boneIndex] ); element.pObject->SetPositionMatrix( pBoneToWorld[boneIndex], true ); } - pStr = nexttoken(szToken, pStr, ','); + pStr = nexttoken(szToken, pStr, ',', sizeof(szToken)); } } @@ -1069,6 +1147,23 @@ int CRagdollProp::VPhysicsGetObjectList( IPhysicsObject **pList, int listMax ) return m_ragdoll.listCount; } +#ifdef MAPBASE +int CRagdollProp::VPhysicsGetFlesh() +{ + IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; + int count = VPhysicsGetObjectList( pList, ARRAYSIZE(pList) ); + for ( int i = 0; i < count; i++ ) + { + int material = pList[i]->GetMaterialIndex(); + const surfacedata_t *pSurfaceData = physprops->GetSurfaceData( material ); + // Is flesh ?, don't allow pickup + if ( pSurfaceData->game.material == CHAR_TEX_ANTLION || pSurfaceData->game.material == CHAR_TEX_FLESH || pSurfaceData->game.material == CHAR_TEX_BLOODYFLESH || pSurfaceData->game.material == CHAR_TEX_ALIENFLESH ) + return pSurfaceData->game.material; + } + return 0; +} +#endif + void CRagdollProp::UpdateNetworkDataFromVPhysics( IPhysicsObject *pPhysics, int index ) { Assert(index < m_ragdoll.listCount); @@ -1278,6 +1373,16 @@ CBaseAnimating *CreateServerRagdollSubmodel( CBaseAnimating *pOwner, const char matrix3x4_t pBoneToWorld[MAXSTUDIOBONES], pBoneToWorldNext[MAXSTUDIOBONES]; pRagdoll->ResetSequence( 0 ); +#ifdef MAPBASE_VSCRIPT + // Hook for pre-spawn ragdolling + if (pOwner && pOwner->m_ScriptScope.IsInitialized() && CBaseAnimating::g_Hook_OnServerRagdoll.CanRunInScope( pOwner->m_ScriptScope )) + { + // ragdoll, submodel + ScriptVariant_t args[] = { ScriptVariant_t( pRagdoll->GetScriptInstance() ), true }; + CBaseAnimating::g_Hook_OnServerRagdoll.Call( pOwner->m_ScriptScope, NULL, args ); + } +#endif + // let bone merging do the work of copying everything over for us pRagdoll->SetParent( pOwner ); pRagdoll->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING ); @@ -1302,6 +1407,16 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con pRagdoll->CopyAnimationDataFrom( pAnimating ); pRagdoll->SetOwnerEntity( pAnimating ); +#ifdef MAPBASE_VSCRIPT + // Hook for pre-spawn ragdolling + if (pAnimating->m_ScriptScope.IsInitialized() && CBaseAnimating::g_Hook_OnServerRagdoll.CanRunInScope( pAnimating->m_ScriptScope )) + { + // ragdoll, submodel + ScriptVariant_t args[] = { ScriptVariant_t( pRagdoll->GetScriptInstance() ), false }; + CBaseAnimating::g_Hook_OnServerRagdoll.Call( pAnimating->m_ScriptScope, NULL, args ); + } +#endif + pRagdoll->InitRagdollAnimation(); matrix3x4_t pBoneToWorld[MAXSTUDIOBONES], pBoneToWorldNext[MAXSTUDIOBONES]; @@ -1441,6 +1556,12 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con maxs = pAnimating->CollisionProp()->OBBMaxs(); pRagdoll->CollisionProp()->SetCollisionBounds( mins, maxs ); +#ifdef MAPBASE + variant_t variant; + variant.SetEntity(pRagdoll); + pAnimating->FireNamedOutput("OnServerRagdoll", variant, pRagdoll, pAnimating); +#endif + return pRagdoll; } @@ -1683,6 +1804,38 @@ void CRagdollProp::InputDisableMotion( inputdata_t &inputdata ) DisableMotion(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler to start the physics prop simulating. +//----------------------------------------------------------------------------- +void CRagdollProp::InputWake( inputdata_t &inputdata ) +{ + for ( int iRagdoll = 0; iRagdoll < m_ragdoll.listCount; ++iRagdoll ) + { + IPhysicsObject *pPhysicsObject = m_ragdoll.list[ iRagdoll ].pObject; + if ( pPhysicsObject != NULL ) + { + pPhysicsObject->Wake(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler to stop the physics prop simulating. +//----------------------------------------------------------------------------- +void CRagdollProp::InputSleep( inputdata_t &inputdata ) +{ + for ( int iRagdoll = 0; iRagdoll < m_ragdoll.listCount; ++iRagdoll ) + { + IPhysicsObject *pPhysicsObject = m_ragdoll.list[ iRagdoll ].pObject; + if ( pPhysicsObject != NULL ) + { + pPhysicsObject->Sleep(); + } + } +} +#endif + void CRagdollProp::InputTurnOn( inputdata_t &inputdata ) { RemoveEffects( EF_NODRAW ); @@ -1703,6 +1856,24 @@ void CRagdollProp::InputFadeAndRemove( inputdata_t &inputdata ) FadeOut( 0.0f, flFadeDuration ); } +#ifdef MAPBASE_VSCRIPT +HSCRIPT CRagdollProp::ScriptGetRagdollObject( int iIndex ) +{ + if (iIndex < 0 || iIndex > m_ragdoll.listCount) + { + Warning("%s GetRagdollObject: Index %i not valid (%i objects)\n", GetDebugName(), iIndex, m_ragdoll.listCount); + return NULL; + } + + return g_pScriptVM->RegisterInstance( m_ragdoll.list[iIndex].pObject ); +} + +int CRagdollProp::ScriptGetRagdollObjectCount() +{ + return m_ragdoll.listCount; +} +#endif + void Ragdoll_GetAngleOverrideString( char *pOut, int size, CBaseEntity *pEntity ) { CRagdollProp *pRagdoll = dynamic_cast(pEntity); diff --git a/game/server/physics_prop_ragdoll.h b/game/server/physics_prop_ragdoll.h index 7c24b47e..46e527c3 100644 --- a/game/server/physics_prop_ragdoll.h +++ b/game/server/physics_prop_ragdoll.h @@ -22,6 +22,9 @@ class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics { DECLARE_CLASS( CRagdollProp, CBaseAnimating ); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif public: CRagdollProp( void ); @@ -49,6 +52,9 @@ class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics virtual void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ); virtual void VPhysicsUpdate( IPhysicsObject *pPhysics ); virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax ); +#ifdef MAPBASE + int VPhysicsGetFlesh(); +#endif virtual int DrawDebugTextOverlays(void); @@ -56,6 +62,9 @@ class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics virtual IResponseSystem *GetResponseSystem(); virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); void SetSourceClassName( const char *pClassname ); +#ifdef MAPBASE + const char *GetSourceClassNameAsCStr() { return STRING( m_strSourceClassName ); } +#endif // Physics attacker virtual CBasePlayer *HasPhysicsAttacker( float dt ); @@ -101,10 +110,19 @@ class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics void InputStartRadgollBoogie( inputdata_t &inputdata ); void InputEnableMotion( inputdata_t &inputdata ); void InputDisableMotion( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputWake( inputdata_t &inputdata ); + void InputSleep( inputdata_t &inputdata ); +#endif void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); void InputFadeAndRemove( inputdata_t &inputdata ); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetRagdollObject( int iIndex ); + int ScriptGetRagdollObjectCount(); +#endif + DECLARE_DATADESC(); protected: diff --git a/game/server/physobj.cpp b/game/server/physobj.cpp index efaffd07..c486fa80 100644 --- a/game/server/physobj.cpp +++ b/game/server/physobj.cpp @@ -387,6 +387,9 @@ BEGIN_DATADESC( CPhysBox ) DEFINE_INPUTFUNC( FIELD_VOID, "DisableMotion", InputDisableMotion ), DEFINE_INPUTFUNC( FIELD_VOID, "ForceDrop", InputForceDrop ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableFloating", InputDisableFloating ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetDebris", InputSetDebris ), +#endif // Function pointers DEFINE_ENTITYFUNC( BreakTouch ), @@ -562,6 +565,13 @@ int CPhysBox::ObjectCaps() } } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_PHYSBOX_RADIUS_PICKUP ) ) + { + caps |= FCAP_USE_IN_RADIUS; + } +#endif + return caps; } @@ -689,6 +699,25 @@ void CPhysBox::InputDisableFloating( inputdata_t &inputdata ) PhysEnableFloating( VPhysicsGetObject(), false ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Adds or removes the debris spawnflag. +//----------------------------------------------------------------------------- +void CPhysBox::InputSetDebris( inputdata_t &inputdata ) +{ + if (inputdata.value.Bool()) + { + AddSpawnFlags(SF_PHYSBOX_DEBRIS); + SetCollisionGroup(COLLISION_GROUP_DEBRIS); + } + else + { + RemoveSpawnFlags(SF_PHYSBOX_DEBRIS); + SetCollisionGroup(COLLISION_GROUP_INTERACTIVE); // Is this the default collision group? + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: If we're being held by the player's hand/physgun, force it to drop us //----------------------------------------------------------------------------- @@ -871,6 +900,9 @@ BEGIN_DATADESC( CPhysExplosion ) // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Explode", InputExplode ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "ExplodeAndRemove", InputExplodeAndRemove ), +#endif // Outputs DEFINE_OUTPUT( m_OnPushedPlayer, "OnPushedPlayer" ), @@ -888,10 +920,19 @@ void CPhysExplosion::Spawn( void ) float CPhysExplosion::GetRadius( void ) { float radius = m_radius; +#ifdef MAPBASE + if ( radius == 0 ) +#else if ( radius <= 0 ) +#endif { // Use the same radius as combat radius = m_damage * 2.5; + +#ifdef MAPBASE + if (radius < 0) + radius *= -1; +#endif } return radius; @@ -924,6 +965,17 @@ void CPhysExplosion::InputExplode( inputdata_t &inputdata ) Explode( inputdata.pActivator, inputdata.pCaller ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPhysExplosion::InputExplodeAndRemove( inputdata_t &inputdata ) +{ + Explode( inputdata.pActivator, inputdata.pCaller ); + UTIL_Remove(this); +} +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -936,6 +988,13 @@ void CPhysExplosion::Explode( CBaseEntity *pActivator, CBaseEntity *pCaller ) falloff = 1.0 / 2.5; +#ifdef MAPBASE + // For negative damage handling + float damage = m_damage; + if (damage < 0) + damage *= -1.0f; +#endif + // iterate on all entities in the vicinity. // I've removed the traceline heuristic from phys explosions. SO right now they will // affect entities through walls. (sjb) @@ -986,7 +1045,11 @@ void CPhysExplosion::Explode( CBaseEntity *pActivator, CBaseEntity *pCaller ) } adjustedDamage = flDist * falloff; +#ifdef MAPBASE + adjustedDamage = damage - adjustedDamage; +#else adjustedDamage = m_damage - adjustedDamage; +#endif if ( adjustedDamage < 1 ) { @@ -994,7 +1057,19 @@ void CPhysExplosion::Explode( CBaseEntity *pActivator, CBaseEntity *pCaller ) } CTakeDamageInfo info( this, this, adjustedDamage, DMG_BLAST ); +#ifdef MAPBASE + // Negative damage handling + Vector vecDir = (vecSpot - vecOrigin); + if (m_damage < 0) + { + vecDir *= -1.0f; + vecOrigin += vecDir; + NDebugOverlay::Cross3D(vecOrigin, 2.0f, 255, 255, 0, true, 1.0f); + } + CalculateExplosiveDamageForce( &info, vecDir, vecOrigin ); +#else CalculateExplosiveDamageForce( &info, (vecSpot - vecOrigin), vecOrigin ); +#endif if ( HasSpawnFlags( SF_PHYSEXPLOSION_PUSH_PLAYER ) ) { @@ -1019,7 +1094,11 @@ void CPhysExplosion::Explode( CBaseEntity *pActivator, CBaseEntity *pCaller ) pEntity->ViewPunch( vecDeltaAngles ); } +#ifdef MAPBASE + Vector vecPush = (vecPushDir*damage*flFalloff*2.0f); +#else Vector vecPush = (vecPushDir*m_damage*flFalloff*2.0f); +#endif if ( pEntity->GetFlags() & FL_BASEVELOCITY ) { vecPush = vecPush + pEntity->GetBaseVelocity(); @@ -1242,6 +1321,16 @@ class CSimplePhysicsBrush : public CBaseEntity SetMoveType( MOVETYPE_VPHYSICS ); SetSolid( SOLID_VPHYSICS ); m_takedamage = DAMAGE_EVENTS_ONLY; + +#ifdef MAPBASE + // If we don't have an owner entity, it means this wasn't spawned by a phys_convert and this is safe. + if ( !GetOwnerEntity() ) + { + VPhysicsInitNormal( SOLID_VPHYSICS, 0, HasSpawnFlags(SF_PHYSBOX_DEBRIS) ); + if ( HasSpawnFlags(SF_PHYSBOX_ASLEEP) ) + SetCollisionGroup( COLLISION_GROUP_DEBRIS ); + } +#endif } }; @@ -1258,6 +1347,16 @@ class CSimplePhysicsProp : public CBaseProp SetMoveType( MOVETYPE_VPHYSICS ); SetSolid( SOLID_VPHYSICS ); m_takedamage = DAMAGE_EVENTS_ONLY; + +#ifdef MAPBASE + // If we don't have an owner entity, it means this wasn't spawned by a phys_convert and this is safe. + if ( !GetOwnerEntity() ) + { + VPhysicsInitNormal( SOLID_VPHYSICS, 0, HasSpawnFlags(SF_PHYSPROP_DEBRIS) ); + if ( HasSpawnFlags(SF_PHYSPROP_START_ASLEEP) ) + SetCollisionGroup( COLLISION_GROUP_DEBRIS ); + } +#endif } int ObjectCaps() @@ -1330,6 +1429,39 @@ static CBaseEntity *CreateSimplePhysicsObject( CBaseEntity *pEntity, bool create pPhysEntity = CreateEntityByName( "simple_physics_prop" ); } + pPhysEntity->KeyValue( "model", STRING(pEntity->GetModelName()) ); + pPhysEntity->SetAbsOrigin( pEntity->GetAbsOrigin() ); + pPhysEntity->SetAbsAngles( pEntity->GetAbsAngles() ); +#ifdef MAPBASE + // So the entity knows it's being spawned by a phys_convert + pPhysEntity->SetOwnerEntity( pEntity ); +#endif + pPhysEntity->Spawn(); + if ( !TransferPhysicsObject( pEntity, pPhysEntity, !createAsleep ) ) + { + pPhysEntity->VPhysicsInitNormal( SOLID_VPHYSICS, 0, createAsleep ); + if ( createAsDebris ) + pPhysEntity->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); + } + return pPhysEntity; +} + +#ifdef MAPBASE +// Creates func_brush and prop_physics instead, because why not? +static CBaseEntity *CreateConventionalPhysicsObject( CBaseEntity *pEntity, bool createAsleep, bool createAsDebris ) +{ + CBaseEntity *pPhysEntity = NULL; + int modelindex = pEntity->GetModelIndex(); + const model_t *model = modelinfo->GetModel( modelindex ); + if ( model && modelinfo->GetModelType(model) == mod_brush ) + { + pPhysEntity = CreateEntityByName( "func_physbox" ); + } + else + { + pPhysEntity = CreateEntityByName( "prop_physics_override" ); + } + pPhysEntity->KeyValue( "model", STRING(pEntity->GetModelName()) ); pPhysEntity->SetAbsOrigin( pEntity->GetAbsOrigin() ); pPhysEntity->SetAbsAngles( pEntity->GetAbsAngles() ); @@ -1342,6 +1474,7 @@ static CBaseEntity *CreateSimplePhysicsObject( CBaseEntity *pEntity, bool create } return pPhysEntity; } +#endif #define SF_CONVERT_ASLEEP 0x0001 #define SF_CONVERT_AS_DEBRIS 0x0002 @@ -1357,11 +1490,22 @@ class CPhysConvert : public CLogicalEntity // Input handlers void InputConvertTarget( inputdata_t &inputdata ); +#ifdef MAPBASE + enum + { + CONVERT_ENTITYTYPE_SIMPLE, // simple_physics_prop, simple_physics_brush, etc. + CONVERT_ENTITYTYPE_CONVENTIONAL, // prop_physics, func_physbox, etc. + }; +#endif + DECLARE_DATADESC(); private: string_t m_swapModel; float m_flMassOverride; +#ifdef MAPBASE + int m_iPhysicsEntityType = CONVERT_ENTITYTYPE_SIMPLE; +#endif }; LINK_ENTITY_TO_CLASS( phys_convert, CPhysConvert ); @@ -1370,6 +1514,9 @@ BEGIN_DATADESC( CPhysConvert ) DEFINE_KEYFIELD( m_swapModel, FIELD_STRING, "swapmodel" ), DEFINE_KEYFIELD( m_flMassOverride, FIELD_FLOAT, "massoverride" ), +#ifdef MAPBASE + DEFINE_INPUT( m_iPhysicsEntityType, FIELD_INTEGER, "SetConversionType" ), +#endif // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "ConvertTarget", InputConvertTarget ), @@ -1432,7 +1579,16 @@ void CPhysConvert::InputConvertTarget( inputdata_t &inputdata ) } // created phys object, now move hierarchy over +#ifdef MAPBASE + CBaseEntity *pPhys; + switch (m_iPhysicsEntityType) + { + case CONVERT_ENTITYTYPE_CONVENTIONAL: pPhys = CreateConventionalPhysicsObject( pEntity, createAsleep, createAsDebris ); break; + default: pPhys = CreateSimplePhysicsObject( pEntity, createAsleep, createAsDebris ); break; + } +#else CBaseEntity *pPhys = CreateSimplePhysicsObject( pEntity, createAsleep, createAsDebris ); +#endif if ( pPhys ) { // Override the mass if specified @@ -1445,6 +1601,22 @@ void CPhysConvert::InputConvertTarget( inputdata_t &inputdata ) } } +#ifdef MAPBASE + pPhys->m_nRenderMode = pEntity->m_nRenderMode; + pPhys->m_nRenderFX = pEntity->m_nRenderFX; + const color32 rclr = pEntity->GetRenderColor(); + pPhys->SetRenderColor(rclr.r, rclr.g, rclr.b, rclr.a); + if (pEntity->GetBaseAnimating() /*&& pPhys->GetBaseAnimating()*/) + { + CBaseAnimating *pEntityAnimating = pEntity->GetBaseAnimating(); + CBaseAnimating *pPhysAnimating = pPhys->GetBaseAnimating(); + + pPhysAnimating->m_nSkin = pEntityAnimating->m_nSkin; + pPhysAnimating->m_nBody = pEntityAnimating->m_nBody; + pPhysAnimating->SetModelScale(pEntityAnimating->GetModelScale()); + } +#endif + pPhys->SetName( pEntity->GetEntityName() ); UTIL_TransferPoseParameters( pEntity, pPhys ); TransferChildren( pEntity, pPhys ); @@ -1463,6 +1635,9 @@ void CPhysConvert::InputConvertTarget( inputdata_t &inputdata ) #define SF_MAGNET_SUCK 0x0004 #define SF_MAGNET_ALLOWROTATION 0x0008 #define SF_MAGNET_COAST_HACK 0x0010 +#ifdef MAPBASE +#define SF_MAGNET_PREVENT_PICKUP 0x0020 +#endif LINK_ENTITY_TO_CLASS( phys_magnet, CPhysMagnet ); @@ -1559,6 +1734,16 @@ CPhysMagnet::~CPhysMagnet( void ) //----------------------------------------------------------------------------- void CPhysMagnet::Spawn( void ) { +#ifdef MAPBASE + // Crashes otherwise + if (GetModelName() == NULL_STRING) + { + Warning("WARNING: %s spawned with no model name\n", GetDebugName()); + UTIL_Remove(this); + return; + } +#endif + Precache(); SetMoveType( MOVETYPE_NONE ); @@ -1587,6 +1772,13 @@ void CPhysMagnet::Spawn( void ) VPhysicsGetObject()->EnableMotion( false ); } +#ifdef MAPBASE + if ( HasSpawnFlags(SF_MAGNET_PREVENT_PICKUP) ) + { + PhysSetGameFlags(VPhysicsGetObject(), FVPHYSICS_NO_PLAYER_PICKUP); + } +#endif + m_bActive = true; m_pConstraintGroup = NULL; m_flTotalMass = 0; @@ -1741,6 +1933,20 @@ void CPhysMagnet::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) BaseClass::VPhysicsCollision( index, pEvent ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CPhysMagnet::CanBePickedUpByPhyscannon( void ) +{ + if ( HasSpawnFlags( SF_MAGNET_PREVENT_PICKUP ) ) + return false; + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/game/server/physobj.h b/game/server/physobj.h index a6e9e5a5..09d333c5 100644 --- a/game/server/physobj.h +++ b/game/server/physobj.h @@ -37,6 +37,9 @@ #define SF_PHYSBOX_NEVER_PICK_UP 0x200000 // Physcannon will never be able to pick this up. #define SF_PHYSBOX_NEVER_PUNT 0x400000 // Physcannon will never be able to punt this object. #define SF_PHYSBOX_PREVENT_PLAYER_TOUCH_ENABLE 0x800000 // If set, the player will not cause the object to enable its motion when bumped into +#ifdef MAPBASE +#define SF_PHYSBOX_RADIUS_PICKUP 0x1000000 // Allows this object to be picked up in a radius, useful for smaller objects. Based on the prop_physics input +#endif // UNDONE: Hook collisions into the physics system to generate touch functions and take damage on falls // UNDONE: Base class PhysBrush @@ -76,6 +79,9 @@ DECLARE_CLASS( CPhysBox, CBreakable ); void InputDisableMotion( inputdata_t &inputdata ); void InputForceDrop( inputdata_t &inputdata ); void InputDisableFloating( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetDebris( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); @@ -120,6 +126,9 @@ class CPhysExplosion : public CPointEntity // Input handlers void InputExplode( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputExplodeAndRemove( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); private: @@ -187,6 +196,9 @@ class CPhysMagnet : public CBaseAnimating, public IPhysicsConstraintEvent void Precache( void ); void Touch( CBaseEntity *pOther ); void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); +#ifdef MAPBASE + bool CanBePickedUpByPhyscannon( void ); +#endif void DoMagnetSuck( CBaseEntity *pOther ); void SetConstraintGroup( IPhysicsConstraintGroup *pGroup ); diff --git a/game/server/player.cpp b/game/server/player.cpp index e0e7ccd2..a68bf982 100644 --- a/game/server/player.cpp +++ b/game/server/player.cpp @@ -59,6 +59,10 @@ #include "env_zoom.h" #include "rumble_shared.h" #include "gamestats.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "env_tonemap_controller.h" +#include "fogvolume.h" +#endif #include "npcevent.h" #include "datacache/imdlcache.h" #include "hintsystem.h" @@ -80,6 +84,14 @@ #ifdef HL2_DLL #include "combine_mine.h" #include "weapon_physcannon.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#include "mapbase/matchers.h" +#endif +#endif + +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" #endif ConVar autoaim_max_dist( "autoaim_max_dist", "2160" ); // 2160 = 180 feet @@ -191,6 +203,10 @@ ConVar sv_player_display_usercommand_errors( "sv_player_display_usercommand_err ConVar player_debug_print_damage( "player_debug_print_damage", "0", FCVAR_CHEAT, "When true, print amount and type of all damage received by player to console." ); +#ifdef MAPBASE +ConVar player_use_visibility_cache( "player_use_visibility_cache", "0", FCVAR_NONE, "Allows the player to use the visibility cache." ); +#endif + void CC_GiveCurrentAmmo( void ) { @@ -435,14 +451,29 @@ BEGIN_DATADESC( CBasePlayer ) DEFINE_FIELD( m_autoKickDisabled, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_FIELD( m_bInTriggerFall, FIELD_BOOLEAN ), + + DEFINE_FIELD( m_bDrawPlayerModelExternally, FIELD_BOOLEAN ), +#endif + // Function Pointers DEFINE_FUNCTION( PlayerDeathThink ), // Inputs DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetHUDVisibility", InputSetHUDVisibility ), +#ifdef MAPBASE // From Alien Swarm SDK (kind of) + DEFINE_INPUTFUNC( FIELD_INPUT, "SetFogController", InputSetFogController ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetPostProcessController", InputSetPostProcessController ), + DEFINE_INPUTFUNC( FIELD_INPUT, "SetColorCorrectionController", InputSetColorCorrectionController ), +#else DEFINE_INPUTFUNC( FIELD_STRING, "SetFogController", InputSetFogController ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "HandleMapEvent", InputHandleMapEvent ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetSuppressAttacks", InputSetSuppressAttacks ), +#endif DEFINE_FIELD( m_nNumCrouches, FIELD_INTEGER ), DEFINE_FIELD( m_bDuckToggled, FIELD_BOOLEAN ), @@ -452,7 +483,10 @@ BEGIN_DATADESC( CBasePlayer ) DEFINE_FIELD( m_nNumCrateHudHints, FIELD_INTEGER ), - +#ifdef MAPBASE // From Alien Swarm SDK + DEFINE_FIELD( m_hPostProcessCtrl, FIELD_EHANDLE ), + DEFINE_FIELD( m_hColorCorrectionCtrl, FIELD_EHANDLE ), +#endif // DEFINE_FIELD( m_nBodyPitchPoseParam, FIELD_INTEGER ), // DEFINE_ARRAY( m_StepSoundCache, StepSoundCache_t, 2 ), @@ -461,6 +495,78 @@ BEGIN_DATADESC( CBasePlayer ) // DEFINE_UTLVECTOR( m_vecPlayerSimInfo ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +// TODO: Better placement? +ScriptHook_t g_Hook_PlayerRunCommand; + +BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptIsPlayerNoclipping, "IsNoclipping", "Returns true if the player is in noclip mode." ) + + DEFINE_SCRIPTFUNC_NAMED( VScriptGetExpresser, "GetExpresser", "Gets a handle for this player's expresser." ) + + DEFINE_SCRIPTFUNC( GetPlayerName, "Gets the player's name." ) + DEFINE_SCRIPTFUNC( GetUserID, "Gets the player's user ID." ) + DEFINE_SCRIPTFUNC_NAMED( GetUserID, "GetPlayerUserId", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC( GetNetworkIDString, "Gets the player's network (i.e. Steam) ID." ) + + DEFINE_SCRIPTFUNC( FragCount, "Gets the number of frags (kills) this player has in a multiplayer game." ) + DEFINE_SCRIPTFUNC( DeathCount, "Gets the number of deaths this player has had in a multiplayer game." ) + DEFINE_SCRIPTFUNC( IsConnected, "Returns true if this player is connected." ) + DEFINE_SCRIPTFUNC( IsDisconnecting, "Returns true if this player is disconnecting." ) + DEFINE_SCRIPTFUNC( IsSuitEquipped, "Returns true if this player had the HEV suit equipped." ) + + DEFINE_SCRIPTFUNC_NAMED( ArmorValue, "GetArmor", "Gets the player's armor." ) + DEFINE_SCRIPTFUNC_NAMED( SetArmorValue, "SetArmor", "Sets the player's armor." ) + + DEFINE_SCRIPTFUNC( FlashlightIsOn, "Returns true if the flashlight is on." ) + DEFINE_SCRIPTFUNC( FlashlightTurnOn, "Turns on the flashlight." ) + DEFINE_SCRIPTFUNC( FlashlightTurnOff, "Turns off the flashlight." ) + + DEFINE_SCRIPTFUNC( DisableButtons, "Disables the specified button mask." ) + DEFINE_SCRIPTFUNC( EnableButtons, "Enables the specified button mask if it was disabled before." ) + DEFINE_SCRIPTFUNC( ForceButtons, "Forces the specified button mask." ) + DEFINE_SCRIPTFUNC( UnforceButtons, "Unforces the specified button mask if it was forced before." ) + + DEFINE_SCRIPTFUNC( GetButtons, "Gets the player's active buttons." ) + DEFINE_SCRIPTFUNC( GetButtonPressed, "Gets the player's currently pressed buttons." ) + DEFINE_SCRIPTFUNC( GetButtonReleased, "Gets the player's just-released buttons." ) + DEFINE_SCRIPTFUNC( GetButtonLast, "Gets the player's previously active buttons." ) + DEFINE_SCRIPTFUNC( GetButtonDisabled, "Gets the player's currently unusable buttons." ) + DEFINE_SCRIPTFUNC( GetButtonForced, "Gets the player's currently forced buttons." ) + + DEFINE_SCRIPTFUNC( GetFOV, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFOVOwner, "GetFOVOwner", "Gets current view owner." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetFOV, "SetFOV", "Sets player FOV regardless of view owner." ) + + DEFINE_SCRIPTFUNC( ViewPunch, "Punches the player's view with the specified vector." ) + DEFINE_SCRIPTFUNC( SetMuzzleFlashTime, "Sets the player's muzzle flash time for AI." ) + DEFINE_SCRIPTFUNC( SetSuitUpdate, "Sets an update for the player's HEV suit." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAutoaimVector, "GetAutoaimVector", "Gets the player's autoaim shooting direction with the specified scale." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAutoaimVectorCustomMaxDist, "GetAutoaimVectorCustomMaxDist", "Gets the player's autoaim shooting direction with the specified scale and a custom max distance." ) + DEFINE_SCRIPTFUNC( ShouldAutoaim, "Returns true if the player should be autoaiming." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeForward, "GetEyeForward", "Gets the player's forward eye vector." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeRight, "GetEyeRight", "Gets the player's right eye vector." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeUp, "GetEyeUp", "Gets the player's up eye vector." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetViewModel, "GetViewModel", "Returns the viewmodel of the specified index." ) + + // + // Hooks + // + BEGIN_SCRIPTHOOK( g_Hook_PlayerRunCommand, "PlayerRunCommand", FIELD_VOID, "Called when running a player command on the server." ) + DEFINE_SCRIPTHOOK_PARAM( "command", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + +END_SCRIPTDESC(); +#else +BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseAnimating, "The player entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsPlayerNoclipping, "IsNoclipping", "Returns true if the player is in noclip mode." ) +END_SCRIPTDESC(); +#endif + int giPrecacheGrunt = 0; edict_t *CBasePlayer::s_PlayerEdict = NULL; @@ -527,6 +633,46 @@ void CBasePlayer::DestroyViewModels( void ) } } +#ifdef MAPBASE +extern char g_szDefaultHandsModel[MAX_PATH]; +extern int g_iDefaultHandsSkin; +extern int g_iDefaultHandsBody; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBasePlayer::CreateHandModel(int index, int iOtherVm) +{ + Assert(index >= 0 && index < MAX_VIEWMODELS && iOtherVm >= 0 && iOtherVm < MAX_VIEWMODELS ); + + if (GetViewModel( index )) + { + // This can happen if the player respawns + // Don't draw unless we're already using a hands weapon + if ( !GetActiveWeapon() || !GetActiveWeapon()->UsesHands() ) + GetViewModel( index )->AddEffects( EF_NODRAW ); + return; + } + + CBaseViewModel *vm = (CBaseViewModel *)CreateEntityByName("hand_viewmodel"); + if (vm) + { + vm->SetAbsOrigin(GetAbsOrigin()); + vm->SetOwner(this); + vm->SetIndex(index); + + vm->SetModel( g_szDefaultHandsModel ); + vm->m_nSkin = g_iDefaultHandsSkin; + vm->m_nBody = g_iDefaultHandsBody; + + DispatchSpawn(vm); + vm->FollowEntity(GetViewModel(iOtherVm), true); + m_hViewModel.Set(index, vm); + vm->AddEffects( EF_NODRAW ); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Static member function to create a player of the specified class // Input : *className - @@ -585,9 +731,7 @@ CBasePlayer::CBasePlayer( ) m_bForceOrigin = false; m_hVehicle = NULL; m_pCurrentCommand = NULL; - m_iLockViewanglesTickNumber = 0; - m_qangLockViewangles.Init(); - + // Setup our default FOV m_iDefaultFOV = g_pGameRules->DefaultFOV(); @@ -638,7 +782,7 @@ CBasePlayer::CBasePlayer( ) m_flLastUserCommandTime = 0.f; m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; - m_flLastObjectiveTime = -1.f; + m_hPostProcessCtrl.Set( NULL ); } CBasePlayer::~CBasePlayer( ) @@ -653,6 +797,11 @@ CBasePlayer::~CBasePlayer( ) //----------------------------------------------------------------------------- void CBasePlayer::UpdateOnRemove( void ) { + if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM ) + { + g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL ); + } + VPhysicsDestroyObject(); // Remove him from his current team @@ -731,9 +880,13 @@ int CBasePlayer::ShouldTransmit( const CCheckTransmitInfo *pInfo ) bool CBasePlayer::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec *pEntityTransmitBits ) const { - // Team members shouldn't be adjusted unless friendly fire is on. - if ( !friendlyfire.GetInt() && pPlayer->GetTeamNumber() == GetTeamNumber() ) - return false; + //Tony; only check teams in teamplay + if ( gpGlobals->teamplay ) + { + // Team members shouldn't be adjusted unless friendly fire is on. + if ( !friendlyfire.GetInt() && pPlayer->GetTeamNumber() == GetTeamNumber() ) + return false; + } // If this entity hasn't been transmitted to us and acked, then don't bother lag compensating it. if ( pEntityTransmitBits && !pEntityTransmitBits->Get( pPlayer->entindex() ) ) @@ -910,7 +1063,11 @@ void CBasePlayer::TraceAttack( const CTakeDamageInfo &inputInfo, const Vector &v // If an NPC check if friendly fire is disallowed // -------------------------------------------------- CAI_BaseNPC *pNPC = info.GetAttacker()->MyNPCPointer(); +#ifdef MAPBASE + if ( pNPC && (pNPC->CapabilitiesGet() & bits_CAP_NO_HIT_PLAYER) && pNPC->IRelationType( this ) > D_FR ) +#else if ( pNPC && (pNPC->CapabilitiesGet() & bits_CAP_NO_HIT_PLAYER) && pNPC->IRelationType( this ) != D_HT ) +#endif return; // Prevent team damage here so blood doesn't appear @@ -949,10 +1106,22 @@ void CBasePlayer::TraceAttack( const CTakeDamageInfo &inputInfo, const Vector &v break; } +#ifdef MAPBASE + + // Damage filter bleed control needs to exist on all DLLs + bool bShouldBleed = +#ifdef HL2_EPISODIC + !g_pGameRules->Damage_ShouldNotBleed( info.GetDamageType() ) && +#endif + DamageFilterAllowsBlood( info ); + + if ( bShouldBleed ) +#else #ifdef HL2_EPISODIC // If this damage type makes us bleed, then do so bool bShouldBleed = !g_pGameRules->Damage_ShouldNotBleed( info.GetDamageType() ); if ( bShouldBleed ) +#endif #endif { SpawnBlood(ptr->endpos, vecDir, BloodColor(), info.GetDamage());// a little surface blood. @@ -978,7 +1147,7 @@ void CBasePlayer::DamageEffect(float flDamage, int fDamageType) } else if (fDamageType & DMG_DROWN) { - //Blue damage indicator + //Red damage indicator color32 blue = {0,0,128,128}; UTIL_ScreenFade( this, blue, 1.0f, 0.1f, FFADE_IN ); } @@ -1556,6 +1725,15 @@ void CBasePlayer::RemoveAllItems( bool removeSuit ) RemoveAllWeapons(); RemoveAllAmmo(); +#ifdef MAPBASE + // Hide hand viewmodel + CBaseViewModel *vm = GetViewModel( 1 ); + if ( vm ) + { + vm->AddEffects( EF_NODRAW ); + } +#endif + if ( removeSuit ) { RemoveSuit(); @@ -1564,9 +1742,10 @@ void CBasePlayer::RemoveAllItems( bool removeSuit ) UpdateClientData(); } +//Tony; correct this for base code so that IsDead will be correct accross all games. bool CBasePlayer::IsDead() const { - return m_lifeState == LIFE_DEAD; + return m_lifeState != LIFE_ALIVE; } static float DamageForce( const Vector &size, float damage ) @@ -2327,7 +2506,6 @@ bool CBasePlayer::SetObserverMode(int mode ) break; case OBS_MODE_CHASE : - case OBS_MODE_POI: // PASSTIME case OBS_MODE_IN_EYE : // udpate FOV and viewmodels SetObserverTarget( m_hObserverTarget ); @@ -2423,7 +2601,8 @@ void CBasePlayer::CheckObserverSettings() } // check if our spectating target is still a valid one - if ( m_iObserverMode == OBS_MODE_IN_EYE || m_iObserverMode == OBS_MODE_CHASE || m_iObserverMode == OBS_MODE_FIXED || m_iObserverMode == OBS_MODE_POI ) + + if ( m_iObserverMode == OBS_MODE_IN_EYE || m_iObserverMode == OBS_MODE_CHASE || m_iObserverMode == OBS_MODE_FIXED ) { ValidateCurrentObserverTarget(); @@ -2477,7 +2656,6 @@ void CBasePlayer::ValidateCurrentObserverTarget( void ) } else { -#if !defined( TF_DLL ) // couldn't find new target, switch to temporary mode if ( mp_forcecamera.GetInt() == OBS_ALLOW_ALL ) { @@ -2485,11 +2663,10 @@ void CBasePlayer::ValidateCurrentObserverTarget( void ) ForceObserverMode( OBS_MODE_ROAMING ); } else -#endif { // fix player view right where it is ForceObserverMode( OBS_MODE_FIXED ); - m_hObserverTarget.Set( NULL ); // no target to follow + m_hObserverTarget.Set( NULL ); // no traget to follow } } } @@ -2635,10 +2812,7 @@ bool CBasePlayer::SetObserverTarget(CBaseEntity *target) Vector dir, end; Vector start = target->EyePosition(); - QAngle ang = target->EyeAngles(); - ang.z = 0; // PASSTIME no view roll when spectating ball - - AngleVectors( ang, &dir ); + AngleVectors( target->EyeAngles(), &dir ); VectorNormalize( dir ); VectorMA( start, -64.0f, dir, end ); @@ -2648,7 +2822,7 @@ bool CBasePlayer::SetObserverTarget(CBaseEntity *target) trace_t tr; UTIL_TraceRay( ray, MASK_PLAYERSOLID, target, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); - JumptoPosition( tr.endpos, ang ); + JumptoPosition( tr.endpos, target->EyeAngles() ); } return true; @@ -2872,6 +3046,10 @@ float CBasePlayer::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return 0; } +CBaseEntity *CBasePlayer::GetHeldObject( void ) +{ + return NULL; +} //----------------------------------------------------------------------------- // Purpose: Server side of jumping rules. Most jumping logic is already @@ -3416,8 +3594,6 @@ void CBasePlayer::ForceSimulation() m_nSimulationTick = -1; } -ConVar sv_usercmd_custom_random_seed( "sv_usercmd_custom_random_seed", "1", FCVAR_CHEAT, "When enabled server will populate an additional random seed independent of the client" ); - //----------------------------------------------------------------------------- // Purpose: // Input : *buf - @@ -3444,16 +3620,6 @@ void CBasePlayer::ProcessUsercmds( CUserCmd *cmds, int numcmds, int totalcmds, pCmd->MakeInert(); } - if ( sv_usercmd_custom_random_seed.GetBool() ) - { - float fltTimeNow = float( Plat_FloatTime() * 1000.0 ); - pCmd->server_random_seed = *reinterpret_cast( (char*)&fltTimeNow ); - } - else - { - pCmd->server_random_seed = pCmd->random_seed; - } - ctx->cmds.AddToTail( *pCmd ); } ctx->numcmds = numcmds; @@ -3697,6 +3863,20 @@ void CBasePlayer::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper) } } } + +#ifdef MAPBASE_VSCRIPT + // Movement hook for VScript + if (m_ScriptScope.IsInitialized() && g_Hook_PlayerRunCommand.CanRunInScope(m_ScriptScope)) + { + HSCRIPT hCmd = g_pScriptVM->RegisterInstance( reinterpret_cast(ucmd) ); + + // command + ScriptVariant_t args[] = { hCmd }; + g_Hook_PlayerRunCommand.Call( m_ScriptScope, NULL, args ); + + g_pScriptVM->RemoveInstance( hCmd ); + } +#endif PlayerMove()->RunCommand(this, ucmd, moveHelper); } @@ -4047,6 +4227,12 @@ void CBasePlayer::CheckTimeBasedDamage() case itbd_Acid: // OnTakeDamage(pev, pev, ACID_DAMAGE, DMG_GENERIC); bDuration = ACID_DURATION; +#ifdef MAPBASE + // Prevents ant workers from inducing the Flash Plague, flashing the player's screen every time they take damage henceforth. + // I think people came up with a different name, but I can't bother to look for it right now. + // This fix might prevent other acid damage stuff as well, so it's not episodic-exclusive. + m_bitsDamageType &= ~(DMG_ACID); +#endif break; case itbd_SlowBurn: // OnTakeDamage(pev, pev, SLOWBURN_DAMAGE, DMG_GENERIC); @@ -4167,6 +4353,12 @@ void CBasePlayer::UpdateGeigerCounter( void ) range = clamp( (int)range * 4, 0, 255 ); } +#ifdef MAPBASE + // If the geiger is disabled, just use 255 + if (HasSpawnFlags(SF_PLAYER_NO_GEIGER)) + range = 255; +#endif + if (range != m_igeigerRangePrev) { m_igeigerRangePrev = range; @@ -4513,6 +4705,55 @@ void CBasePlayer::ForceOrigin( const Vector &vecOrigin ) m_vForcedOrigin = vecOrigin; } +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::OnTonemapTriggerStartTouch( CTonemapTrigger *pTonemapTrigger ) +{ + m_hTriggerTonemapList.FindAndRemove( pTonemapTrigger ); + m_hTriggerTonemapList.AddToTail( pTonemapTrigger ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::OnTonemapTriggerEndTouch( CTonemapTrigger *pTonemapTrigger ) +{ + m_hTriggerTonemapList.FindAndRemove( pTonemapTrigger ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::UpdateTonemapController( void ) +{ + // For now, Mapbase uses Tony Sergi's Source 2007 tonemap fixes. + // Alien Swarm SDK tonemap controller code copies the parameters instead. + + CEnvTonemapController *pController = NULL; + + if (m_hTriggerTonemapList.Count() > 0) + { + pController = static_cast(m_hTriggerTonemapList.Tail()->GetTonemapController()); + } + else if (TheTonemapSystem()->GetMasterTonemapController()) + { + pController = static_cast(TheTonemapSystem()->GetMasterTonemapController()); + } + + if (pController) + { + //m_hTonemapController = TheTonemapSystem()->GetMasterTonemapController(); + + if (pController->m_bUseCustomAutoExposureMax) + m_Local.m_TonemapParams.m_flAutoExposureMax = pController->m_flCustomAutoExposureMax; + + if (pController->m_bUseCustomAutoExposureMin) + m_Local.m_TonemapParams.m_flAutoExposureMin = pController->m_flCustomAutoExposureMin; + + if (pController->m_bUseCustomBloomScale) + m_Local.m_TonemapParams.m_flBloomScale = pController->m_flCustomBloomScale; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -4520,6 +4761,11 @@ void CBasePlayer::PostThink() { m_vecSmoothedVelocity = m_vecSmoothedVelocity * SMOOTHING_FACTOR + GetAbsVelocity() * ( 1 - SMOOTHING_FACTOR ); +#ifdef MAPBASE // From Alien Swarm SDK + UpdateTonemapController(); + UpdateFXVolume(); +#endif + if ( !g_fGameOver && !m_iPlayerLocked ) { if ( IsAlive() ) @@ -4896,6 +5142,55 @@ void CBasePlayer::InitialSpawn( void ) gamestats->Event_PlayerConnected( this ); } +//----------------------------------------------------------------------------- +// Purpose: clear our m_Local.m_TonemapParams to -1. +//----------------------------------------------------------------------------- +void CBasePlayer::ClearTonemapParams( void ) +{ + //Tony; clear all the variables to -1.0 + m_Local.m_TonemapParams.m_flAutoExposureMin = -1.0f; + m_Local.m_TonemapParams.m_flAutoExposureMax = -1.0f; + m_Local.m_TonemapParams.m_flTonemapScale = -1.0f; + m_Local.m_TonemapParams.m_flBloomScale = -1.0f; + m_Local.m_TonemapParams.m_flTonemapRate = -1.0f; +} +void CBasePlayer::InputSetTonemapScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flTonemapScale = inputdata.value.Float(); +} + +void CBasePlayer::InputSetTonemapRate( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flTonemapRate = inputdata.value.Float(); +} +void CBasePlayer::InputSetAutoExposureMin( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMin = inputdata.value.Float(); +} + +void CBasePlayer::InputSetAutoExposureMax( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMax = inputdata.value.Float(); +} + +void CBasePlayer::InputSetBloomScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flBloomScale = inputdata.value.Float(); +} + +//Tony; restore defaults (set min/max to -1.0 so nothing gets overridden) +void CBasePlayer::InputUseDefaultAutoExposure( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMin = -1.0f; + m_Local.m_TonemapParams.m_flAutoExposureMax = -1.0f; + m_Local.m_TonemapParams.m_flTonemapRate = -1.0f; +} +void CBasePlayer::InputUseDefaultBloomScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flBloomScale = -1.0f; +} +// void InputSetBloomScaleRange( inputdata_t &inputdata ); + //----------------------------------------------------------------------------- // Purpose: Called everytime the player respawns //----------------------------------------------------------------------------- @@ -4907,6 +5202,9 @@ void CBasePlayer::Spawn( void ) Hints()->ResetHints(); } + //Tony; make sure tonemap params is cleared. + ClearTonemapParams(); + SetClassname( "player" ); // Shared spawning code.. @@ -4944,6 +5242,9 @@ void CBasePlayer::Spawn( void ) // Initialize the fog and postprocess controllers. InitFogController(); +#ifdef MAPBASE // From Alien Swarm SDK + InitPostProcessController(); +#endif m_DmgTake = 0; m_DmgSave = 0; @@ -4968,7 +5269,12 @@ void CBasePlayer::Spawn( void ) if ( !m_fGameHUDInitialized ) g_pGameRules->SetDefaultPlayerTeam( this ); +#ifdef MAPBASE + CBaseEntity *pSpawnPoint = g_pGameRules->GetPlayerSpawnSpot( this ); + SpawnedAtPoint( pSpawnPoint ); +#else g_pGameRules->GetPlayerSpawnSpot( this ); +#endif m_Local.m_bDucked = false;// This will persist over round restart if you hold duck otherwise. m_Local.m_bDucking = false; @@ -5004,6 +5310,9 @@ void CBasePlayer::Spawn( void ) enginesound->SetPlayerDSP( user, 0, false ); CreateViewModel(); +#ifdef MAPBASE + CreateHandModel(); +#endif SetCollisionGroup( COLLISION_GROUP_PLAYER ); @@ -5035,6 +5344,11 @@ void CBasePlayer::Spawn( void ) m_vecSmoothedVelocity = vec3_origin; InitVCollision( GetAbsOrigin(), GetAbsVelocity() ); + if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM ) + { + g_pScriptVM->SetValue( "player", GetScriptInstance() ); + } + #if !defined( TF_DLL ) IGameEvent *event = gameeventmanager->CreateEvent( "player_spawn" ); @@ -5131,6 +5445,10 @@ void CBasePlayer::Precache( void ) m_iTrain = TRAIN_NEW; #endif +#ifdef MAPBASE + PrecacheModel( g_szDefaultHandsModel ); +#endif + m_iClientBattery = -1; m_iUpdateTime = 5; // won't update for 1/2 a second @@ -5249,6 +5567,14 @@ void CBasePlayer::OnRestore( void ) m_nVehicleViewSavedFrame = 0; m_nBodyPitchPoseParam = LookupPoseParameter( "body_pitch" ); + + // HACK: (03/25/09) Then the player goes across a transition it doesn't spawn and register + // it's instance. We're hacking around this for now, but this will go away when we get around to + // having entities cross transitions and keep their script state. + if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM && (gpGlobals->eLoadType == MapLoad_Transition) ) + { + g_pScriptVM->SetValue( "player", GetScriptInstance() ); + } } /* void CBasePlayer::SetTeamName( const char *pTeamName ) @@ -5702,6 +6028,25 @@ CBaseEntity *CBasePlayer::GiveNamedItem( const char *pszName, int iSubType ) DispatchSpawn( pent ); +#ifdef MAPBASE + if ( pWeapon ) + { + for (int i=0;iGetSlot() == pWeapon->GetSlot() && m_hMyWeapons[i]->GetPosition() == pWeapon->GetPosition() ) + { + // Make sure it matches the subtype + if ( m_hMyWeapons[i]->GetSubType() == iSubType ) + { + // Don't use this weapon if the slot is already occupied + UTIL_Remove( pWeapon ); + return NULL; + } + } + } + } +#endif + if ( pent != NULL && !(pent->IsMarkedForDeletion()) ) { pent->Touch( this ); @@ -5911,6 +6256,10 @@ void CBasePlayer::ImpulseCommands( ) CBaseCombatWeapon *pWeapon; pWeapon = GetActiveWeapon(); +#ifdef MAPBASE + if (!pWeapon) + return; +#endif if( pWeapon->IsEffectActive( EF_NODRAW ) ) { @@ -6038,7 +6387,12 @@ static void CreateJeep( CBasePlayer *pPlayer ) // Cheat to create a jeep in front of the player Vector vecForward; AngleVectors( pPlayer->EyeAngles(), &vecForward ); + //Tony; in sp sdk, we have prop_vehicle_hl2buggy; because episode 2 modified the jeep code to turn it into the jalopy instead of the regular buggy +#if defined ( HL2_EPISODIC ) + CBaseEntity *pJeep = (CBaseEntity *)CreateEntityByName( "prop_vehicle_hl2buggy" ); +#else CBaseEntity *pJeep = (CBaseEntity *)CreateEntityByName( "prop_vehicle_jeep" ); +#endif if ( pJeep ) { Vector vecOrigin = pPlayer->GetAbsOrigin() + vecForward * 256 + Vector(0,0,64); @@ -6047,7 +6401,11 @@ static void CreateJeep( CBasePlayer *pPlayer ) pJeep->SetAbsAngles( vecAngles ); pJeep->KeyValue( "model", "models/buggy.mdl" ); pJeep->KeyValue( "solid", "6" ); +#if defined ( HL2_EPISODIC ) + pJeep->KeyValue( "targetname", "hl2buggy" ); +#else pJeep->KeyValue( "targetname", "jeep" ); +#endif pJeep->KeyValue( "vehiclescript", "scripts/vehicles/jeep_test.txt" ); DispatchSpawn( pJeep ); pJeep->Activate(); @@ -6540,7 +6898,22 @@ bool CBasePlayer::ClientCommand( const CCommand &args ) angle.y = atof( args[5] ); angle.z = 0.0f; +#ifdef MAPBASE + #define SPECGOTO_MAX_VALUE 0xFFFF/2.0f + + // This could crash the game somehow if not checked.. Thanks to Nairda. + if (abs(angle.x) <= 360.0f && abs(angle.y) <= 360.0f && abs(origin.x) < SPECGOTO_MAX_VALUE && + abs(origin.y) < SPECGOTO_MAX_VALUE && abs(origin.z) < SPECGOTO_MAX_VALUE) + { + JumptoPosition(origin, angle); + } + else + { + engine->ClientPrintf(edict(), "spec_goto: Out-of-bounds"); + } +#else JumptoPosition( origin, angle ); +#endif } return true; @@ -6603,7 +6976,11 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) else { // Don't let the player fetch weapons through walls (use MASK_SOLID so that you can't pickup through windows) +#ifdef MAPBASE + if( (pWeapon->FVisible( this, MASK_SOLID ) == false && !(GetFlags() & FL_NOTARGET)) && !HasSpawnFlags(SF_WEAPON_ALWAYS_TOUCHABLE) ) +#else if( pWeapon->FVisible( this, MASK_SOLID ) == false && !(GetFlags() & FL_NOTARGET) ) +#endif return false; } @@ -6615,7 +6992,11 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) if( Weapon_EquipAmmoOnly( pWeapon ) ) { // Only remove me if I have no ammo left +#ifdef MAPBASE + if ( pWeapon->HasPrimaryAmmo() || pWeapon->HasSecondaryAmmo() ) +#else if ( pWeapon->HasPrimaryAmmo() ) +#endif return false; UTIL_Remove( pWeapon ); @@ -6626,10 +7007,56 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) return false; } } +#ifdef MAPBASE + // -------------------------------------------------------------------------------- + // If we own a weapon in the same position take the ammo but leave the weapon behind + // -------------------------------------------------------------------------------- + if (!pWeapon->HasSpawnFlags(SF_WEAPON_USED)) // Make sure we're being used and not being bumped + { + for (int i=0;iGetSlot() == m_hMyWeapons[i]->GetSlot() && + pWeapon->GetPosition() == m_hMyWeapons[i]->GetPosition()) + { + //Weapon_EquipAmmoOnly( pWeapon ); + + // I'm too lazy to make my own version of Weapon_EquipAmmoOnly that doesn't check if we already have the weapon first + int primaryGiven = (pWeapon->UsesClipsForAmmo1()) ? pWeapon->m_iClip1 : pWeapon->GetPrimaryAmmoCount(); + int secondaryGiven = (pWeapon->UsesClipsForAmmo2()) ? pWeapon->m_iClip2 : pWeapon->GetSecondaryAmmoCount(); + + int takenPrimary = GiveAmmo( primaryGiven, pWeapon->m_iPrimaryAmmoType); + int takenSecondary = GiveAmmo( secondaryGiven, pWeapon->m_iSecondaryAmmoType); + + if( pWeapon->UsesClipsForAmmo1() ) + { + pWeapon->m_iClip1 -= takenPrimary; + } + else + { + pWeapon->SetPrimaryAmmoCount( pWeapon->GetPrimaryAmmoCount() - takenPrimary ); + } + + if( pWeapon->UsesClipsForAmmo2() ) + { + pWeapon->m_iClip2 -= takenSecondary; + } + else + { + pWeapon->SetSecondaryAmmoCount( pWeapon->GetSecondaryAmmoCount() - takenSecondary ); + } + + return false; + } + } + } +#endif // ------------------------- // Otherwise take the weapon // ------------------------- +#ifndef MAPBASE else +#endif { pWeapon->CheckRespawn(); @@ -6652,6 +7079,7 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) UTIL_HudHintText( this, hint.Access() ); } +#ifndef MAPBASE // See CBasePlayer::Weapon_Equip. // Always switch to a newly-picked up weapon if ( !PlayerHasMegaPhysCannon() ) { @@ -6663,6 +7091,7 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) Weapon_Switch( pWeapon ); } +#endif #endif } return true; @@ -6715,6 +7144,43 @@ void CBasePlayer::ShowCrosshair( bool bShow ) } } +//----------------------------------------------------------------------------- +// Used by vscript to determine if the player is noclipping +//----------------------------------------------------------------------------- +bool CBasePlayer::ScriptIsPlayerNoclipping(void) +{ + return (GetMoveType() == MOVETYPE_NOCLIP); +} + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBasePlayer::VScriptGetExpresser() +{ + HSCRIPT hScript = NULL; + CAI_Expresser *pExpresser = GetExpresser(); + if (pExpresser) + { + hScript = g_pScriptVM->RegisterInstance( pExpresser ); + } + + return hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CBasePlayer::ScriptGetViewModel( int viewmodelindex ) +{ + if (viewmodelindex < 0 || viewmodelindex >= MAX_VIEWMODELS) + { + Warning( "GetViewModel: Invalid index '%i'\n", viewmodelindex ); + return NULL; + } + + return ToHScript( GetViewModel( viewmodelindex ) ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -7342,6 +7808,10 @@ void CBasePlayer::Weapon_DropSlot( int weaponSlot ) } } +#ifdef MAPBASE +ConVar player_autoswitch_on_first_pickup("player_autoswitch_on_pickup", "1", FCVAR_NONE, "Determines how the player should autoswitch when picking up a new weapon. 0 = no autoswitch, 1 = always (default), 2 = use unused weighting system"); +#endif + //----------------------------------------------------------------------------- // Purpose: Override to add weapon to the hud //----------------------------------------------------------------------------- @@ -7349,7 +7819,26 @@ void CBasePlayer::Weapon_Equip( CBaseCombatWeapon *pWeapon ) { BaseClass::Weapon_Equip( pWeapon ); +#ifdef MAPBASE + // BumpWeapon's code appeared to be deprecated; The same operation is already handled here, but with much more code involved. + // There's also an unused weighting system which was overridden by that deprecated code. The unused weighting code can be enabled + // via player_autoswitch_on_first_pickup. + bool bShouldSwitch = false; + switch (player_autoswitch_on_first_pickup.GetInt()) + { + // Unused Weighting + case 2: + bShouldSwitch = g_pGameRules->FShouldSwitchWeapon( this, pWeapon ); + break; + + // Always (old behavior) + case 1: + bShouldSwitch = true; + break; + } +#else bool bShouldSwitch = g_pGameRules->FShouldSwitchWeapon( this, pWeapon ); +#endif #ifdef HL2_DLL if ( bShouldSwitch == false && PhysCannonGetHeldEntity( GetActiveWeapon() ) == pWeapon && @@ -7366,6 +7855,33 @@ void CBasePlayer::Weapon_Equip( CBaseCombatWeapon *pWeapon ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CBasePlayer::Weapon_TranslateActivity( Activity baseAct, bool *pRequired ) +{ + Activity weaponTranslation = BaseClass::Weapon_TranslateActivity( baseAct, pRequired ); + + if ( GetActiveWeapon() && GetActiveWeapon()->IsEffectActive(EF_NODRAW) && baseAct != ACT_ARM ) + { + // Our weapon is holstered. Use the base activity. + return baseAct; + } + if ( GetModelPtr() && (!GetModelPtr()->HaveSequenceForActivity(weaponTranslation) || baseAct == weaponTranslation) ) + { + // This is used so players can fall back to backup activities in the same way NPCs in Mapbase can + Activity backupActivity = Weapon_BackupActivity(baseAct, pRequired ? *pRequired : false); + if ( baseAct != backupActivity && GetModelPtr()->HaveSequenceForActivity(backupActivity) ) + return backupActivity; + + return baseAct; + } + + return weaponTranslation; +} +#endif + //========================================================= // HasNamedPlayerItem Does the player already have this item? @@ -7400,7 +7916,7 @@ void CBasePlayer::EquipWearable( CEconWearable *pItem ) pItem->Equip( this ); } -#ifdef DBGFLAG_ASSERT +#ifdef DEBUG // Double check list integrity. for ( int i = m_hMyWearables.Count()-1; i >= 0; --i ) { @@ -7439,7 +7955,7 @@ void CBasePlayer::RemoveWearable( CEconWearable *pItem ) } } -#ifdef DBGFLAG_ASSERT +#ifdef DEBUG // Double check list integrity. for ( int i = m_hMyWearables.Count()-1; i >= 0; --i ) { @@ -7464,6 +7980,23 @@ void CBasePlayer::PlayWearableAnimsForPlaybackEvent( wearableanimplayback_t iPla } #endif // USES_ECON_ITEMS +#ifdef MAPBASE +bool CBasePlayer::ShouldUseVisibilityCache( CBaseEntity *pEntity ) +{ + // In CBaseEntity::FVisible(), players are allowed to see through CONTENTS_BLOCKLOS, which is used for + // nodraw, block LOS brushes, etc. This is so some code doesn't erronesouly assume the player can't see + // an entity (when the player can, in fact, see it) and therefore do something the player is not supposed to see. + // + // However, to reduce the number of traces FVisible() runs, CBaseCombatCharacter uses a "visibility cache" shared + // by all entities derived from it. The player is normally a part of this visibility cache, so when it runs a trace + // through a CONTENTS_BLOCKLOS surface, the visibility cache assumes entities can now see through it and therefore + // NPCs to see through the brush which should normally block their LOS. + // + // This solution stops the player from using the visibility cache altogether, toggled by a convar. + return player_use_visibility_cache.GetBool(); +} +#endif + //================================================================================ // TEAM HANDLING //================================================================================ @@ -7785,6 +8318,11 @@ void CRevertSaved::LoadThink( void ) #define SF_SPEED_MOD_SUPPRESS_SPEED (1<<5) #define SF_SPEED_MOD_SUPPRESS_ATTACK (1<<6) #define SF_SPEED_MOD_SUPPRESS_ZOOM (1<<7) +#ifdef MAPBASE +// Needs to be inverse because suppressing the flashlight is already default behavior +// and we don't want to break compatibility for existing speedmods +#define SF_SPEED_MOD_DONT_SUPPRESS_FLASHLIGHT (1<<8) +#endif class CMovementSpeedMod : public CPointEntity { @@ -7792,9 +8330,20 @@ class CMovementSpeedMod : public CPointEntity public: void InputSpeedMod(inputdata_t &data); +#ifdef MAPBASE + void InputEnable(inputdata_t &data); + void InputDisable(inputdata_t &data); + + void InputSetAdditionalButtons(inputdata_t &data); +#endif + private: int GetDisabledButtonMask( void ); +#ifdef MAPBASE + int m_iAdditionalButtons; +#endif + DECLARE_DATADESC(); }; @@ -7802,6 +8351,13 @@ LINK_ENTITY_TO_CLASS( player_speedmod, CMovementSpeedMod ); BEGIN_DATADESC( CMovementSpeedMod ) DEFINE_INPUTFUNC( FIELD_FLOAT, "ModifySpeed", InputSpeedMod ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + + DEFINE_KEYFIELD( m_iAdditionalButtons, FIELD_INTEGER, "AdditionalButtons" ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetAdditionalButtons", InputSetAdditionalButtons ), +#endif END_DATADESC() int CMovementSpeedMod::GetDisabledButtonMask( void ) @@ -7838,6 +8394,13 @@ int CMovementSpeedMod::GetDisabledButtonMask( void ) nMask |= IN_ZOOM; } +#ifdef MAPBASE + if ( m_iAdditionalButtons != 0 ) + { + nMask |= m_iAdditionalButtons; + } +#endif + return nMask; } @@ -7871,6 +8434,10 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data) pPlayer->HideViewModels(); } +#ifdef MAPBASE + if ( !HasSpawnFlags( SF_SPEED_MOD_DONT_SUPPRESS_FLASHLIGHT ) ) + { +#endif // Turn off the flashlight if ( pPlayer->FlashlightIsOn() ) { @@ -7879,6 +8446,9 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data) // Disable the flashlight's further use pPlayer->SetFlashlightEnabled( false ); +#ifdef MAPBASE + } +#endif pPlayer->DisableButtons( GetDisabledButtonMask() ); // Hide the HUD @@ -7892,15 +8462,22 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data) // Bring the weapon back if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_WEAPONS ) && pPlayer->GetActiveWeapon() == NULL ) { - pPlayer->SetActiveWeapon( pPlayer->GetLastWeapon() ); + pPlayer->SetActiveWeapon( pPlayer->Weapon_GetLast() ); if ( pPlayer->GetActiveWeapon() ) { pPlayer->GetActiveWeapon()->Deploy(); } } +#ifdef MAPBASE + if ( !HasSpawnFlags( SF_SPEED_MOD_DONT_SUPPRESS_FLASHLIGHT ) ) + { +#endif // Allow the flashlight again pPlayer->SetFlashlightEnabled( true ); +#ifdef MAPBASE + } +#endif pPlayer->EnableButtons( GetDisabledButtonMask() ); // Restore the HUD @@ -7914,6 +8491,205 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data) } } +#ifdef MAPBASE +void CMovementSpeedMod::InputEnable(inputdata_t &data) +{ + CBasePlayer *pPlayer = NULL; + + if ( data.pActivator && data.pActivator->IsPlayer() ) + { + pPlayer = (CBasePlayer *)data.pActivator; + } + else if ( !g_pGameRules->IsDeathmatch() ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + + if ( pPlayer ) + { + // Holster weapon immediately, to allow it to cleanup + if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_WEAPONS ) ) + { + if ( pPlayer->GetActiveWeapon() ) + { + pPlayer->Weapon_SetLast( pPlayer->GetActiveWeapon() ); + pPlayer->GetActiveWeapon()->Holster(); + pPlayer->ClearActiveWeapon(); + } + + pPlayer->HideViewModels(); + } + + // Turn off the flashlight + if ( pPlayer->FlashlightIsOn() ) + { + pPlayer->FlashlightTurnOff(); + } + + // Disable the flashlight's further use + pPlayer->SetFlashlightEnabled( false ); + pPlayer->DisableButtons( GetDisabledButtonMask() ); + + // Hide the HUD + if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_HUD ) ) + { + pPlayer->m_Local.m_iHideHUD |= HIDEHUD_ALL; + } + } +} + +void CMovementSpeedMod::InputDisable(inputdata_t &data) +{ + CBasePlayer *pPlayer = NULL; + + if ( data.pActivator && data.pActivator->IsPlayer() ) + { + pPlayer = (CBasePlayer *)data.pActivator; + } + else if ( !g_pGameRules->IsDeathmatch() ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + + if ( pPlayer ) + { + // Bring the weapon back + if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_WEAPONS ) && pPlayer->GetActiveWeapon() == NULL ) + { + pPlayer->SetActiveWeapon( pPlayer->Weapon_GetLast() ); + if ( pPlayer->GetActiveWeapon() ) + { + pPlayer->GetActiveWeapon()->Deploy(); + } + } + + // Allow the flashlight again + pPlayer->SetFlashlightEnabled( true ); + pPlayer->EnableButtons( GetDisabledButtonMask() ); + + // Restore the HUD + if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_HUD ) ) + { + pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_ALL; + } + } +} + +void CMovementSpeedMod::InputSetAdditionalButtons(inputdata_t &data) +{ + CBasePlayer *pPlayer = NULL; + + if ( data.pActivator && data.pActivator->IsPlayer() ) + { + pPlayer = (CBasePlayer *)data.pActivator; + } + else if ( !g_pGameRules->IsDeathmatch() ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + + bool bAlreadyDisabled = false; + if ( pPlayer ) + { + bAlreadyDisabled = (pPlayer->m_afButtonDisabled & GetDisabledButtonMask()) != 0; + } + + m_iAdditionalButtons = data.value.Int(); + + // If we were already disabling buttons, re-disable them + if ( bAlreadyDisabled ) + { + // We should probably do something better than this. + pPlayer->m_afButtonForced = GetDisabledButtonMask(); + } +} +#endif + +#ifdef MAPBASE +class CLogicPlayerInfo : public CPointEntity +{ + DECLARE_CLASS( CLogicPlayerInfo, CPointEntity ); +public: + void InputGetPlayerInfo( inputdata_t &inputdata ); + void InputGetPlayerByID( inputdata_t &inputdata ); + void InputGetPlayerByName( inputdata_t &inputdata ); + + void GetPlayerInfo( CBasePlayer *pPlayer ); + + COutputInt m_OutUserID; + COutputString m_OutPlayerName; + COutputEHANDLE m_OutPlayerEntity; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( logic_playerinfo, CLogicPlayerInfo ); + +BEGIN_DATADESC( CLogicPlayerInfo ) + DEFINE_INPUTFUNC( FIELD_EHANDLE, "GetPlayerInfo", InputGetPlayerInfo ), + DEFINE_INPUTFUNC( FIELD_STRING, "GetPlayerByID", InputGetPlayerByID ), + DEFINE_INPUTFUNC( FIELD_STRING, "GetPlayerByName", InputGetPlayerByName ), + + DEFINE_OUTPUT( m_OutUserID, "OutUserID" ), + DEFINE_OUTPUT( m_OutPlayerName, "OutPlayerName" ), + DEFINE_OUTPUT( m_OutPlayerEntity, "OutPlayerEntity" ), +END_DATADESC() + + +void CLogicPlayerInfo::InputGetPlayerInfo( inputdata_t &inputdata ) +{ + CBasePlayer *pPlayer = ToBasePlayer(inputdata.value.Entity()); + + // If there was no entity to begin with, try the local player + if (!pPlayer && !inputdata.value.Entity()) + pPlayer = UTIL_GetLocalPlayer(); + + if (pPlayer) + GetPlayerInfo( pPlayer ); +} + +void CLogicPlayerInfo::InputGetPlayerByID( inputdata_t &inputdata ) +{ + for (int i = 1; i < gpGlobals->maxClients; i++) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + if (pPlayer) + { + if (Matcher_NamesMatch( inputdata.value.String(), UTIL_VarArgs("%i", pPlayer->GetUserID()) )) + { + GetPlayerInfo( pPlayer ); + return; + } + } + } +} + +void CLogicPlayerInfo::InputGetPlayerByName( inputdata_t &inputdata ) +{ + for (int i = 1; i < gpGlobals->maxClients; i++) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + if (pPlayer) + { + if (Matcher_NamesMatch( inputdata.value.String(), pPlayer->GetPlayerName() )) + { + GetPlayerInfo( pPlayer ); + return; + } + } + } +} + +void CLogicPlayerInfo::GetPlayerInfo( CBasePlayer *pPlayer ) +{ + m_OutUserID.Set( pPlayer->GetUserID(), pPlayer, this ); + + m_OutPlayerName.Set( AllocPooledString(pPlayer->GetPlayerName()), pPlayer, this ); + + m_OutPlayerEntity.Set( pPlayer, pPlayer, this ); +} +#endif + void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID) { @@ -7922,6 +8698,17 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi pOut->m_Int = ( data & mask ); } + +#ifdef MAPBASE +// Needs to shift bits since network table only sends the player ones +void SendProxy_ShiftPlayerSpawnflags( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID ) +{ + int *pInt = (int *)pVarData; + + pOut->m_Int = (*pInt) >> 16; +} +#endif + // -------------------------------------------------------------------------------- // // SendTable for CPlayerState. // -------------------------------------------------------------------------------- // @@ -7978,6 +8765,15 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ), SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ), +#ifdef MAPBASE + // Transmitted from the server for internal player spawnflags. + // See baseplayer_shared.h for more details. + SendPropInt ( SENDINFO( m_spawnflags ), 3, SPROP_UNSIGNED, SendProxy_ShiftPlayerSpawnflags ), + + SendPropBool ( SENDINFO( m_bDrawPlayerModelExternally ) ), + SendPropBool ( SENDINFO( m_bInTriggerFall ) ), +#endif + END_SEND_TABLE() @@ -8015,6 +8811,12 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi SendPropArray ( SendPropEHandle( SENDINFO_ARRAY( m_hViewModel ) ), m_hViewModel ), SendPropString (SENDINFO(m_szLastPlaceName) ), +#ifdef MAPBASE // From Alien Swarm SDK + // Postprocess data + SendPropEHandle ( SENDINFO(m_hPostProcessCtrl) ), + SendPropEHandle ( SENDINFO(m_hColorCorrectionCtrl) ), +#endif + #if defined USES_ECON_ITEMS SendPropUtlVector( SENDINFO_UTLVECTOR( m_hMyWearables ), MAX_WEARABLES_SENT_FROM_SERVER, SendPropEHandle( NULL, 0 ) ), #endif // USES_ECON_ITEMS @@ -8506,6 +9308,18 @@ void CBasePlayer::SetDefaultFOV( int FOV ) m_iDefaultFOV = ( FOV == 0 ) ? g_pGameRules->DefaultFOV() : FOV; } +#ifdef MAPBASE_VSCRIPT +void CBasePlayer::ScriptSetFOV(int iFOV, float flRate) +{ + m_iFOVStart = GetFOV(); + + m_flFOVTime = gpGlobals->curtime; + m_iFOV = iFOV; + + m_Local.m_flFOVRate = flRate; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // static func // Input : set - @@ -8697,6 +9511,19 @@ void CBasePlayer::InputSetHUDVisibility( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetSuppressAttacks( inputdata_t &inputdata ) +{ + inputdata.value.Bool() ? + AddSpawnFlags( SF_PLAYER_SUPPRESS_FIRING ) : + RemoveSpawnFlags( SF_PLAYER_SUPPRESS_FIRING ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Set the fog controller data per player. // Input : &inputdata - @@ -8704,7 +9531,19 @@ void CBasePlayer::InputSetHUDVisibility( inputdata_t &inputdata ) void CBasePlayer::InputSetFogController( inputdata_t &inputdata ) { // Find the fog controller with the given name. +#ifdef MAPBASE // From Alien Swarm SDK + CFogController *pFogController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) + { + pFogController = dynamic_cast( inputdata.value.Entity().Get() ); + } + else + { + pFogController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); + } +#else CFogController *pFogController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); +#endif if ( pFogController ) { m_Local.m_PlayerFog.m_hCtrl.Set( pFogController ); @@ -8720,6 +9559,70 @@ void CBasePlayer::InitFogController( void ) m_Local.m_PlayerFog.m_hCtrl = FogSystem()->GetMasterFogController(); } +#ifdef MAPBASE // From Alien Swarm SDK +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InitPostProcessController( void ) +{ + // Setup with the default master controller. + m_hPostProcessCtrl = PostProcessSystem()->GetMasterPostProcessController(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InitColorCorrectionController( void ) +{ + m_hColorCorrectionCtrl = ColorCorrectionSystem()->GetMasterColorCorrection(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetPostProcessController( inputdata_t &inputdata ) +{ + // Find the fog controller with the given name. + CPostProcessController *pController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) + { + pController = dynamic_cast( inputdata.value.Entity().Get() ); + } + else + { + pController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); + } + + if ( pController ) + { + m_hPostProcessCtrl.Set( pController ); + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBasePlayer::InputSetColorCorrectionController( inputdata_t &inputdata ) +{ + // Find the fog controller with the given name. + CColorCorrection *pController = NULL; + if ( inputdata.value.FieldType() == FIELD_EHANDLE ) + { + pController = dynamic_cast( inputdata.value.Entity().Get() ); + } + else + { + pController = dynamic_cast( gEntList.FindEntityByName( NULL, inputdata.value.String() ) ); + } + + if ( pController ) + { + m_hColorCorrectionCtrl.Set( pController ); + } + +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - @@ -8857,6 +9760,14 @@ bool CBasePlayer::HandleVoteCommands( const CCommand &args ) //----------------------------------------------------------------------------- const char *CBasePlayer::GetNetworkIDString() { + //Tony; bots don't have network id's, and this can potentially crash, especially with plugins creating them. + if (IsBot()) + return "__BOT__"; + + //Tony; if networkidstring is null for any reason, the strncpy will crash! + if (!m_szNetworkIDString) + return "NULLID"; + const char *pStr = engine->GetPlayerNetworkIDString( edict() ); Q_strncpy( m_szNetworkIDString, pStr ? pStr : "", sizeof(m_szNetworkIDString) ); return m_szNetworkIDString; @@ -8968,27 +9879,8 @@ void CBasePlayer::HandleAnimEvent( animevent_t *pEvent ) BaseClass::HandleAnimEvent( pEvent ); } - //----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CBasePlayer::ShouldAnnounceAchievement( void ) -{ - m_flAchievementTimes.AddToTail( gpGlobals->curtime ); - if ( m_flAchievementTimes.Count() > 3 ) - { - m_flAchievementTimes.Remove( 0 ); - if ( m_flAchievementTimes.Tail() - m_flAchievementTimes.Head() <= 60.0 ) - { - return false; - } - } - - return true; -} - -//----------------------------------------------------------------------------- -// CPlayerInfo functions (simple pass-through to get around the CBasePlayer multiple inheritance limitation) +// CPlayerInfo functions (simple passthroughts to get around the CBasePlayer multiple inheritence limitation) //----------------------------------------------------------------------------- const char *CPlayerInfo::GetName() { @@ -9402,3 +10294,70 @@ uint64 CBasePlayer::GetSteamIDAsUInt64( void ) return 0; } #endif // NO_STEAM + +#ifdef MAPBASE // From Alien Swarm SDK +//-------------------------------------------------------------------------------------------------------- +void CBasePlayer::UpdateFXVolume( void ) +{ + CFogController *pFogController = NULL; + CPostProcessController *pPostProcessController = NULL; + CColorCorrection* pColorCorrectionEnt = NULL; + + Vector eyePos; + CBaseEntity *pViewEntity = GetViewEntity(); + if ( pViewEntity ) + { + eyePos = pViewEntity->GetAbsOrigin(); + } + else + { + eyePos = EyePosition(); + } + + CFogVolume *pFogVolume = CFogVolume::FindFogVolumeForPosition( eyePos ); + if ( pFogVolume ) + { + pFogController = pFogVolume->GetFogController(); + pPostProcessController = pFogVolume->GetPostProcessController(); + pColorCorrectionEnt = pFogVolume->GetColorCorrectionController(); + + if ( !pFogController ) + { + pFogController = FogSystem()->GetMasterFogController(); + } + + if ( !pPostProcessController ) + { + pPostProcessController = PostProcessSystem()->GetMasterPostProcessController(); + } + + if ( !pColorCorrectionEnt ) + { + pColorCorrectionEnt = ColorCorrectionSystem()->GetMasterColorCorrection(); + } + } + else if ( TheFogVolumes.Count() > 0 ) + { + // If we're not in a fog volume, clear our fog volume, if the map has any. + // This will get us back to using the master fog controller. + pFogController = FogSystem()->GetMasterFogController(); + pPostProcessController = PostProcessSystem()->GetMasterPostProcessController(); + pColorCorrectionEnt = ColorCorrectionSystem()->GetMasterColorCorrection(); + } + + if ( pFogController && m_Local.m_PlayerFog.m_hCtrl.Get() != pFogController ) + { + m_Local.m_PlayerFog.m_hCtrl.Set( pFogController ); + } + + if ( pPostProcessController ) + { + m_hPostProcessCtrl.Set( pPostProcessController ); + } + + if ( pColorCorrectionEnt ) + { + m_hColorCorrectionCtrl.Set( pColorCorrectionEnt ); + } +} +#endif diff --git a/game/server/player.h b/game/server/player.h index e87af06d..0bfba8fb 100644 --- a/game/server/player.h +++ b/game/server/player.h @@ -88,6 +88,10 @@ class CNavArea; class CHintSystem; class CAI_Expresser; +#ifdef MAPBASE // From Alien Swarm SDK +class CTonemapTrigger; +#endif + #if defined USES_ECON_ITEMS class CEconWearable; #endif // USES_ECON_ITEMS @@ -233,7 +237,6 @@ class CPlayerInfo : public IBotController, public IPlayerInfo CBasePlayer *m_pParent; }; - class CBasePlayer : public CBaseCombatCharacter { public: @@ -245,6 +248,8 @@ class CBasePlayer : public CBaseCombatCharacter public: DECLARE_DATADESC(); DECLARE_SERVERCLASS(); + // script description + DECLARE_ENT_SCRIPTDESC(); CBasePlayer(); ~CBasePlayer(); @@ -265,6 +270,10 @@ class CBasePlayer : public CBaseCombatCharacter void HideViewModels( void ); void DestroyViewModels( void ); +#ifdef MAPBASE + virtual void CreateHandModel( int viewmodelindex = 1, int iOtherVm = 0 ); +#endif + CPlayerState *PlayerData( void ) { return &pl; } int RequiredEdictIndex( void ) { return ENTINDEX(edict()); } @@ -289,6 +298,11 @@ class CBasePlayer : public CBaseCombatCharacter virtual void SharedSpawn(); // Shared between client and server. virtual void ForceRespawn( void ); +#ifdef MAPBASE + // For the logic_playerproxy output + virtual void SpawnedAtPoint( CBaseEntity *pSpawnPoint ) {} +#endif + virtual void InitialSpawn( void ); virtual void InitHUD( void ) {} virtual void ShowViewPortPanel( const char * name, bool bShow = true, KeyValues *data = NULL ); @@ -383,6 +397,25 @@ class CBasePlayer : public CBaseCombatCharacter void ShowViewModel( bool bShow ); void ShowCrosshair( bool bShow ); + bool ScriptIsPlayerNoclipping(void); + +#ifdef MAPBASE_VSCRIPT + HSCRIPT VScriptGetExpresser(); + + int GetButtons() { return m_nButtons; } + int GetButtonPressed() { return m_afButtonPressed; } + int GetButtonReleased() { return m_afButtonReleased; } + int GetButtonLast() { return m_afButtonLast; } + int GetButtonDisabled() { return m_afButtonDisabled; } + int GetButtonForced() { return m_afButtonForced; } + + const Vector& ScriptGetEyeForward() { static Vector vecForward; EyeVectors( &vecForward, NULL, NULL ); return vecForward; } + const Vector& ScriptGetEyeRight() { static Vector vecRight; EyeVectors( NULL, &vecRight, NULL ); return vecRight; } + const Vector& ScriptGetEyeUp() { static Vector vecUp; EyeVectors( NULL, NULL, &vecUp ); return vecUp; } + + HSCRIPT ScriptGetViewModel( int viewmodelindex ); +#endif + // View model prediction setup void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov ); @@ -415,7 +448,10 @@ class CBasePlayer : public CBaseCombatCharacter virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) { return true; } virtual bool Weapon_ShouldSelectItem( CBaseCombatWeapon *pWeapon ); void Weapon_DropSlot( int weaponSlot ); - CBaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); } + CBaseCombatWeapon *Weapon_GetLast( void ) { return m_hLastWeapon.Get(); } +#ifdef MAPBASE + virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL ); +#endif virtual void OnMyWeaponFired( CBaseCombatWeapon *weapon ); // call this when this player fires a weapon to allow other systems to react virtual float GetTimeSinceWeaponFired( void ) const; // returns the time, in seconds, since this player fired a weapon @@ -550,8 +586,9 @@ class CBasePlayer : public CBaseCombatCharacter virtual void PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {} virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {} virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *GetHeldObject( void ); - void CheckSuitUpdate(); + virtual void CheckSuitUpdate(); void SetSuitUpdate(const char *name, int fgroup, int iNoRepeat); virtual void UpdateGeigerCounter( void ); void CheckTimeBasedDamage( void ); @@ -561,6 +598,10 @@ class CBasePlayer : public CBaseCombatCharacter virtual Vector GetAutoaimVector( float flScale ); virtual Vector GetAutoaimVector( float flScale, float flMaxDist ); virtual void GetAutoaimVector( autoaim_params_t ¶ms ); +#ifdef MAPBASE_VSCRIPT + Vector ScriptGetAutoaimVector( float flScale ) { return GetAutoaimVector( flScale ); } + Vector ScriptGetAutoaimVectorCustomMaxDist( float flScale, float flMaxDist ) { return GetAutoaimVector( flScale, flMaxDist ); } +#endif float GetAutoaimScore( const Vector &eyePosition, const Vector &viewDir, const Vector &vecTarget, CBaseEntity *pTarget, float fScale, CBaseCombatWeapon *pActiveWeapon ); QAngle AutoaimDeflection( Vector &vecSrc, autoaim_params_t ¶ms ); @@ -612,7 +653,7 @@ class CBasePlayer : public CBaseCombatCharacter virtual void HandleAnimEvent( animevent_t *pEvent ); - virtual bool ShouldAnnounceAchievement( void ); + virtual bool ShouldAnnounceAchievement( void ){ return true; } #if defined USES_ECON_ITEMS // Wearables @@ -621,6 +662,12 @@ class CBasePlayer : public CBaseCombatCharacter void PlayWearableAnimsForPlaybackEvent( wearableanimplayback_t iPlayback ); #endif +#ifdef MAPBASE + bool ShouldUseVisibilityCache( CBaseEntity *pEntity ); + + void UpdateFXVolume( void ); // From Alien Swarm SDK +#endif + public: // Player Physics Shadow void SetupVPhysicsShadow( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity, CPhysCollide *pStandModel, const char *pStandHullName, CPhysCollide *pCrouchModel, const char *pCrouchHullName ); @@ -662,7 +709,7 @@ class CBasePlayer : public CBaseCombatCharacter bool IsConnected() const { return m_iConnected != PlayerDisconnected; } bool IsDisconnecting() const { return m_iConnected == PlayerDisconnecting; } bool IsSuitEquipped() const { return m_Local.m_bWearingSuit; } - int ArmorValue() const { return m_ArmorValue; } + virtual int ArmorValue() const { return m_ArmorValue; } bool HUDNeedsRestart() const { return m_fInitHUD; } float MaxSpeed() const { return m_flMaxspeed; } Activity GetActivity( ) const { return m_Activity; } @@ -735,13 +782,15 @@ class CBasePlayer : public CBaseCombatCharacter bool IsPredictingWeapons( void ) const; int CurrentCommandNumber() const; const CUserCmd *GetCurrentUserCommand() const; - int GetLockViewanglesTickNumber() const { return m_iLockViewanglesTickNumber; } - QAngle GetLockViewanglesData() const { return m_qangLockViewangles; } int GetFOV( void ); // Get the current FOV value int GetDefaultFOV( void ) const; // Default FOV if not specified otherwise int GetFOVForNetworking( void ); // Get the current FOV used for network computations bool SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate = 0.0f, int iZoomStart = 0 ); // Alters the base FOV of the player (must have a valid requester) +#ifdef MAPBASE_VSCRIPT + void ScriptSetFOV(int iFOV, float flSpeed); // Overrides player FOV, ignores zoom owner + HSCRIPT ScriptGetFOVOwner() { return ToHScript(m_hZoomOwner); } +#endif void SetDefaultFOV( int FOV ); // Sets the base FOV if nothing else is affecting it by zooming CBaseEntity *GetFOVOwner( void ) { return m_hZoomOwner; } float GetFOVDistanceAdjustFactor(); // shared between client and server @@ -768,6 +817,9 @@ class CBasePlayer : public CBaseCombatCharacter void InputSetHealth( inputdata_t &inputdata ); void InputSetHUDVisibility( inputdata_t &inputdata ); void InputHandleMapEvent( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetSuppressAttacks( inputdata_t &inputdata ); +#endif surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; } void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; } @@ -822,9 +874,7 @@ class CBasePlayer : public CBaseCombatCharacter public: - // How long since this player last interacted with something the game considers an objective/target/goal - float GetTimeSinceLastObjective( void ) const { return ( m_flLastObjectiveTime == -1.f ) ? 999.f : gpGlobals->curtime - m_flLastObjectiveTime; } - void SetLastObjectiveTime( float flTime ) { m_flLastObjectiveTime = flTime; } + // Used by gamemovement to check if the entity is stuck. int m_StuckLast; @@ -842,6 +892,19 @@ class CBasePlayer : public CBaseCombatCharacter void InitFogController( void ); void InputSetFogController( inputdata_t &inputdata ); +#ifdef MAPBASE // From Alien Swarm SDK + void OnTonemapTriggerStartTouch( CTonemapTrigger *pTonemapTrigger ); + void OnTonemapTriggerEndTouch( CTonemapTrigger *pTonemapTrigger ); + CUtlVector< CHandle< CTonemapTrigger > > m_hTriggerTonemapList; + + CNetworkHandle( CPostProcessController, m_hPostProcessCtrl ); // active postprocessing controller + CNetworkHandle( CColorCorrection, m_hColorCorrectionCtrl ); // active FXVolume color correction + void InitPostProcessController( void ); + void InputSetPostProcessController( inputdata_t &inputdata ); + void InitColorCorrectionController( void ); + void InputSetColorCorrectionController( inputdata_t &inputdata ); +#endif + // Used by env_soundscape_triggerable to manage when the player is touching multiple // soundscape triggers simultaneously. // The one at the HEAD of the list is always the current soundscape for the player. @@ -893,14 +956,16 @@ class CBasePlayer : public CBaseCombatCharacter #if defined USES_ECON_ITEMS CEconWearable *GetWearable( int i ) { return m_hMyWearables[i]; } - const CEconWearable *GetWearable( int i ) const { return m_hMyWearables[i]; } - int GetNumWearables( void ) const { return m_hMyWearables.Count(); } + int GetNumWearables( void ) { return m_hMyWearables.Count(); } +#endif + +#ifdef MAPBASE + CNetworkVar( bool, m_bInTriggerFall ); #endif private: Activity m_Activity; - float m_flLastObjectiveTime; // Last curtime player touched/killed something the gamemode considers an objective protected: @@ -983,6 +1048,13 @@ class CBasePlayer : public CBaseCombatCharacter float m_fReplayEnd; // time to stop replay mode int m_iReplayEntity; // follow this entity in replay +#ifdef MAPBASE // From Alien Swarm SDK + // For now, Mapbase uses Tony Sergi's Source 2007 tonemap fixes. + // Alien Swarm SDK tonemap controller code copies the parameters instead. + virtual void UpdateTonemapController( void ); + //CNetworkHandle( CBaseEntity, m_hTonemapController ); +#endif + private: void HandleFuncTrain(); @@ -1061,8 +1133,6 @@ class CBasePlayer : public CBaseCombatCharacter // Last received usercmd (in case we drop a lot of packets ) CUserCmd m_LastCmd; CUserCmd *m_pCurrentCommand; - int m_iLockViewanglesTickNumber; - QAngle m_qangLockViewangles; float m_flStepSoundTime; // time to check for next footstep sound @@ -1100,6 +1170,11 @@ class CBasePlayer : public CBaseCombatCharacter float m_flSideMove; int m_nNumCrateHudHints; +#ifdef MAPBASE + bool GetDrawPlayerModelExternally( void ) { return m_bDrawPlayerModelExternally; } + void SetDrawPlayerModelExternally( bool bToggle ) { m_bDrawPlayerModelExternally.Set( bToggle ); } +#endif + private: // Used in test code to teleport the player to random locations in the map. @@ -1138,6 +1213,10 @@ class CBasePlayer : public CBaseCombatCharacter // Player name char m_szNetname[MAX_PLAYER_NAME_LENGTH]; +#ifdef MAPBASE + CNetworkVar( bool, m_bDrawPlayerModelExternally ); +#endif + protected: // HACK FOR TF2 Prediction friend class CTFGameMovementRecon; @@ -1218,12 +1297,26 @@ class CBasePlayer : public CBaseCombatCharacter // Store the last time we successfully processed a usercommand float m_flLastUserCommandTime; - // used to prevent achievement announcement spam - CUtlVector< float > m_flAchievementTimes; - public: virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set +private: + // + //Tony; new tonemap controller changes, specifically for multiplayer. + // + void ClearTonemapParams(); //Tony; we need to clear our tonemap params every time we spawn to -1, if we trigger an input, the values will be set again. +public: + void InputSetTonemapScale( inputdata_t &inputdata ); //Set m_Local. +// void InputBlendTonemapScale( inputdata_t &inputdata ); //TODO; this should be calculated on the client, if we use it; perhaps an entity message would suffice? .. hmm.. + void InputSetTonemapRate( inputdata_t &inputdata ); + void InputSetAutoExposureMin( inputdata_t &inputdata ); + void InputSetAutoExposureMax( inputdata_t &inputdata ); + void InputSetBloomScale( inputdata_t &inputdata ); + + //Tony; restore defaults (set min/max to -1.0 so nothing gets overridden) + void InputUseDefaultAutoExposure( inputdata_t &inputdata ); + void InputUseDefaultBloomScale( inputdata_t &inputdata ); + }; typedef CHandle CBasePlayerHandle; diff --git a/game/server/player_command.cpp b/game/server/player_command.cpp index bf77b5d4..d5a6a1f0 100644 --- a/game/server/player_command.cpp +++ b/game/server/player_command.cpp @@ -18,12 +18,18 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifdef MAPBASE +// This turned out to be causing major issues with VPhysics collision. +// It's deactivated until a fix is found. +// See prediction.cpp as well. +//#define PLAYER_COMMAND_FIX 1 +#endif + extern IGameMovement *g_pGameMovement; extern CMoveData *g_pMoveData; // This is a global because it is subclassed by each game. extern ConVar sv_noclipduringpause; ConVar sv_maxusrcmdprocessticks_warning( "sv_maxusrcmdprocessticks_warning", "-1", FCVAR_NONE, "Print a warning when user commands get dropped due to insufficient usrcmd ticks allocated, number of seconds to throttle, negative disabled" ); -static ConVar sv_maxusrcmdprocessticks_holdaim( "sv_maxusrcmdprocessticks_holdaim", "1", FCVAR_CHEAT, "Hold client aim for multiple server sim ticks when client-issued usrcmd contains multiple actions (0: off; 1: hold this server tick; 2+: hold multiple ticks)" ); //----------------------------------------------------------------------------- // Purpose: @@ -53,21 +59,26 @@ void CPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd ) #if defined (HL2_DLL) // pull out backchannel data and move this out - int i; - for (i = 0; i < cmd->entitygroundcontact.Count(); i++) + // Let's not bother with IK Ground Contact Info in MP games -- the system needs to be re-worked, every client sends down the same info for each entity, so how would it determine which to use? + if ( 1 == gpGlobals->maxClients ) { - int entindex = cmd->entitygroundcontact[i].entindex; - CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( entindex) ); - if (pEntity) + int i; + for (i = 0; i < cmd->entitygroundcontact.Count(); i++) { - CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); - if (pAnimating) + int entindex = cmd->entitygroundcontact[i].entindex; + CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( entindex) ); + if (pEntity) { - pAnimating->SetIKGroundContactInfo( cmd->entitygroundcontact[i].minheight, cmd->entitygroundcontact[i].maxheight ); + CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); + if (pAnimating) + { + pAnimating->SetIKGroundContactInfo( cmd->entitygroundcontact[i].minheight, cmd->entitygroundcontact[i].maxheight ); + } } } } + #endif } @@ -418,6 +429,13 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper player->pl.v_angle = ucmd->viewangles + player->pl.anglechange; } +#ifdef PLAYER_COMMAND_FIX + // Let server invoke any needed impact functions + VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" ); + moveHelper->ProcessImpacts(); + VPROF_SCOPE_END(); +#endif + // Call standard client pre-think RunPreThink( player ); @@ -439,22 +457,22 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper VPROF( "pVehicle->ProcessMovement()" ); pVehicle->ProcessMovement( player, g_pMoveData ); } + +#ifdef PLAYER_COMMAND_FIX + RunPostThink( player ); +#endif // Copy output FinishMove( player, ucmd, g_pMoveData ); - // If we have to restore the view angle then do so right now - if ( !player->IsBot() && ( gpGlobals->tickcount - player->GetLockViewanglesTickNumber() < sv_maxusrcmdprocessticks_holdaim.GetInt() ) ) - { - player->pl.v_angle = player->GetLockViewanglesData(); - } - +#ifndef PLAYER_COMMAND_FIX // Let server invoke any needed impact functions VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" ); moveHelper->ProcessImpacts(); VPROF_SCOPE_END(); RunPostThink( player ); +#endif g_pGameMovement->FinishTrackPredictionErrors( player ); diff --git a/game/server/player_lagcompensation.cpp b/game/server/player_lagcompensation.cpp index 37f322e5..08503652 100644 --- a/game/server/player_lagcompensation.cpp +++ b/game/server/player_lagcompensation.cpp @@ -172,7 +172,6 @@ class CLagCompensationManager : public CAutoGameSystemPerFrame, public ILagCompe public: CLagCompensationManager( char const *name ) : CAutoGameSystemPerFrame( name ), m_flTeleportDistanceSqr( 64 *64 ) { - m_isCurrentlyDoingCompensation = false; } // IServerSystem stuff @@ -195,8 +194,6 @@ class CLagCompensationManager : public CAutoGameSystemPerFrame, public ILagCompe void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ); void FinishLagCompensation( CBasePlayer *player ); - bool IsCurrentlyDoingLagCompensation() const OVERRIDE { return m_isCurrentlyDoingCompensation; } - private: void BacktrackPlayer( CBasePlayer *player, float flTargetTime ); @@ -219,8 +216,6 @@ class CLagCompensationManager : public CAutoGameSystemPerFrame, public ILagCompe CBasePlayer *m_pCurrentPlayer; // The player we are doing lag compensation for float m_flTeleportDistanceSqr; - - bool m_isCurrentlyDoingCompensation; // Sentinel to prevent calling StartLagCompensation a second time before a Finish. }; static CLagCompensationManager g_LagCompensationManager( "CLagCompensationManager" ); @@ -327,8 +322,6 @@ void CLagCompensationManager::FrameUpdatePostEntityThink() // Called during player movement to set up/restore after lag compensation void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) { - Assert( !m_isCurrentlyDoingCompensation ); - //DONT LAG COMP AGAIN THIS FRAME IF THERES ALREADY ONE IN PROGRESS //IF YOU'RE HITTING THIS THEN IT MEANS THERES A CODE BUG if ( m_pCurrentPlayer ) @@ -357,8 +350,6 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm Q_memset( m_RestoreData, 0, sizeof( m_RestoreData ) ); Q_memset( m_ChangeData, 0, sizeof( m_ChangeData ) ); - m_isCurrentlyDoingCompensation = true; - // Get true latency // correct is the amout of time we have to correct game time @@ -743,10 +734,7 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player ) m_pCurrentPlayer = NULL; if ( !m_bNeedToRestore ) - { - m_isCurrentlyDoingCompensation = false; return; // no player was changed at all - } // Iterate all active players for ( int i = 1; i <= gpGlobals->maxClients; i++ ) @@ -840,8 +828,6 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player ) pPlayer->SetSimulationTime( restore->m_flSimulationTime ); } } - - m_isCurrentlyDoingCompensation = false; } diff --git a/game/server/playerinfomanager.cpp b/game/server/playerinfomanager.cpp index 903efb6f..69917511 100644 --- a/game/server/playerinfomanager.cpp +++ b/game/server/playerinfomanager.cpp @@ -9,6 +9,16 @@ #include "playerinfomanager.h" #include "edict.h" +#if defined( TF_DLL ) +#include "tf_shareddefs.h" +#elif defined( CSTRIKE_DLL ) +#include "weapon_csbase.h" +#elif defined( DOD_DLL ) +#include "weapon_dodbase.h" +#elif defined( SDK_DLL ) +#include "weapon_sdkbase.h" +#endif + extern CGlobalVars *gpGlobals; static CPlayerInfoManager s_PlayerInfoManager; static CPluginBotManager s_BotManager; @@ -19,74 +29,43 @@ namespace // // Old version support // - abstract_class IPlayerInfo_V1 - { - public: - // returns the players name (UTF-8 encoded) - virtual const char *GetName() = 0; - // returns the userid (slot number) - virtual int GetUserID() = 0; - // returns the string of their network (i.e Steam) ID - virtual const char *GetNetworkIDString() = 0; - // returns the team the player is on - virtual int GetTeamIndex() = 0; - // changes the player to a new team (if the game dll logic allows it) - virtual void ChangeTeam( int iTeamNum ) = 0; - // returns the number of kills this player has (exact meaning is mod dependent) - virtual int GetFragCount() = 0; - // returns the number of deaths this player has (exact meaning is mod dependent) - virtual int GetDeathCount() = 0; - // returns if this player slot is actually valid - virtual bool IsConnected() = 0; - // returns the armor/health of the player (exact meaning is mod dependent) - virtual int GetArmorValue() = 0; - }; - - abstract_class IPlayerInfoManager_V1 - { - public: - virtual IPlayerInfo_V1 *GetPlayerInfo( edict_t *pEdict ) = 0; - }; - - - class CPlayerInfoManager_V1: public IPlayerInfoManager_V1 - { - public: - virtual IPlayerInfo_V1 *GetPlayerInfo( edict_t *pEdict ); - }; - static CPlayerInfoManager_V1 s_PlayerInfoManager_V1; - - - IPlayerInfo_V1 *CPlayerInfoManager_V1::GetPlayerInfo( edict_t *pEdict ) - { - CBasePlayer *pPlayer = ( ( CBasePlayer * )CBaseEntity::Instance( pEdict )); - if ( pPlayer ) - { - return (IPlayerInfo_V1 *)pPlayer->GetPlayerInfo(); - } - else - { - return NULL; - } - } - - EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CPlayerInfoManager_V1, IPlayerInfoManager_V1, "PlayerInfoManager001", s_PlayerInfoManager_V1); + //Tony; pulled out version 1 and 2 support for orange box, we're starting fresh now with v3 player and v2 of the bot interface. } IPlayerInfo *CPlayerInfoManager::GetPlayerInfo( edict_t *pEdict ) { CBasePlayer *pPlayer = ( ( CBasePlayer * )CBaseEntity::Instance( pEdict )); if ( pPlayer ) - { return pPlayer->GetPlayerInfo(); - } else - { return NULL; - } +} +IPlayerInfo *CPlayerInfoManager::GetPlayerInfo( int index ) +{ + return GetPlayerInfo( engine->PEntityOfEntIndex( index ) ); } +// Games implementing advanced bot support should override this. +int CPlayerInfoManager::AliasToWeaponId(const char *weaponName) +{ + //Tony; TF doesn't support this. Should it? +#if defined ( CSTRIKE_DLL ) || defined ( DOD_DLL ) || defined ( SDK_DLL ) + return AliasToWeaponID(weaponName); +#endif + return -1; +} + +// Games implementing advanced bot support should override this. +const char *CPlayerInfoManager::WeaponIdToAlias(int weaponId) +{ +#if defined( TF_DLL ) + return WeaponIdToAlias(weaponId); +#elif defined ( CSTRIKE_DLL ) || defined ( DOD_DLL ) || defined ( SDK_DLL ) + return WeaponIDToAlias(weaponId); +#endif + return "MOD_DIDNT_IMPLEMENT_ME"; +} CGlobalVars *CPlayerInfoManager::GetGlobalVars() { return gpGlobals; @@ -121,8 +100,8 @@ edict_t *CPluginBotManager::CreateBot( const char *botname ) pPlayer->ClearFlags(); pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT ); - pPlayer->ChangeTeam( TEAM_UNASSIGNED ); + pPlayer->AddEFlags( EFL_PLUGIN_BASED_BOT ); // Mark it as a plugin based bot pPlayer->RemoveAllItems( true ); pPlayer->Spawn(); diff --git a/game/server/playerinfomanager.h b/game/server/playerinfomanager.h index 33eb1fa9..2b110562 100644 --- a/game/server/playerinfomanager.h +++ b/game/server/playerinfomanager.h @@ -19,7 +19,13 @@ class CPlayerInfoManager: public IPlayerInfoManager { public: virtual IPlayerInfo *GetPlayerInfo( edict_t *pEdict ); + virtual IPlayerInfo *GetPlayerInfo( int index ); virtual CGlobalVars *GetGlobalVars(); + // accessor to hook into aliastoweaponid + virtual int AliasToWeaponId(const char *weaponName); + // accessor to hook into weaponidtoalias + virtual const char *WeaponIdToAlias(int weaponId); + }; class CPluginBotManager: public IBotManager diff --git a/game/server/playerlocaldata.cpp b/game/server/playerlocaldata.cpp index ac7cf5e9..3b9aea08 100644 --- a/game/server/playerlocaldata.cpp +++ b/game/server/playerlocaldata.cpp @@ -59,6 +59,11 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local ) // 3d skybox data SendPropInt(SENDINFO_STRUCTELEM(m_skybox3d.scale), 12), SendPropVector (SENDINFO_STRUCTELEM(m_skybox3d.origin), -1, SPROP_COORD), +#ifdef MAPBASE + SendPropVector (SENDINFO_STRUCTELEM(m_skybox3d.angles), -1, SPROP_COORD), + SendPropEHandle (SENDINFO_STRUCTELEM(m_skybox3d.skycamera)), + SendPropInt (SENDINFO_STRUCTELEM(m_skybox3d.skycolor), 32, (SPROP_COORD|SPROP_UNSIGNED), SendProxy_Color32ToInt), +#endif SendPropInt (SENDINFO_STRUCTELEM(m_skybox3d.area), 8, SPROP_UNSIGNED ), SendPropInt( SENDINFO_STRUCTELEM( m_skybox3d.fog.enable ), 1, SPROP_UNSIGNED ), SendPropInt( SENDINFO_STRUCTELEM( m_skybox3d.fog.blend ), 1, SPROP_UNSIGNED ), @@ -68,6 +73,9 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local ) SendPropFloat( SENDINFO_STRUCTELEM( m_skybox3d.fog.start ), 0, SPROP_NOSCALE ), SendPropFloat( SENDINFO_STRUCTELEM( m_skybox3d.fog.end ), 0, SPROP_NOSCALE ), SendPropFloat( SENDINFO_STRUCTELEM( m_skybox3d.fog.maxdensity ), 0, SPROP_NOSCALE ), +#ifdef MAPBASE + SendPropFloat( SENDINFO_STRUCTELEM( m_skybox3d.fog.farz ), 0, SPROP_NOSCALE ), +#endif SendPropEHandle( SENDINFO_STRUCTELEM( m_PlayerFog.m_hCtrl ) ), @@ -83,6 +91,14 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local ) SendPropInt( SENDINFO_STRUCTELEM( m_audio.soundscapeIndex ), 17, 0 ), SendPropInt( SENDINFO_STRUCTELEM( m_audio.localBits ), NUM_AUDIO_LOCAL_SOUNDS, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO_STRUCTELEM( m_audio.ent ) ), + + //Tony; tonemap stuff! -- TODO! Optimize this with bit sizes from env_tonemap_controller. + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flTonemapScale ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flTonemapRate ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flBloomScale ), 0, SPROP_NOSCALE ), + + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flAutoExposureMin ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flAutoExposureMax ), 0, SPROP_NOSCALE ), END_SEND_TABLE() BEGIN_SIMPLE_DATADESC( fogplayerparams_t ) @@ -119,6 +135,11 @@ BEGIN_SIMPLE_DATADESC( sky3dparams_t ) DEFINE_FIELD( scale, FIELD_INTEGER ), DEFINE_FIELD( origin, FIELD_VECTOR ), +#ifdef MAPBASE + DEFINE_FIELD( angles, FIELD_VECTOR ), + DEFINE_FIELD( skycamera, FIELD_EHANDLE ), + DEFINE_FIELD( skycolor, FIELD_COLOR32 ), +#endif DEFINE_FIELD( area, FIELD_INTEGER ), DEFINE_EMBEDDED( fog ), @@ -133,6 +154,16 @@ BEGIN_SIMPLE_DATADESC( audioparams_t ) END_DATADESC() +//Tony; tonepam params!! +BEGIN_SIMPLE_DATADESC ( tonemap_params_t ) + DEFINE_FIELD( m_flTonemapScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flTonemapRate, FIELD_FLOAT ), + DEFINE_FIELD( m_flBloomScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flAutoExposureMin, FIELD_FLOAT ), + DEFINE_FIELD( m_flAutoExposureMax, FIELD_FLOAT ), +END_DATADESC() + + BEGIN_SIMPLE_DATADESC( CPlayerLocalData ) DEFINE_AUTO_ARRAY( m_chAreaBits, FIELD_CHARACTER ), DEFINE_AUTO_ARRAY( m_chAreaPortalBits, FIELD_CHARACTER ), @@ -159,6 +190,9 @@ BEGIN_SIMPLE_DATADESC( CPlayerLocalData ) DEFINE_EMBEDDED( m_PlayerFog ), DEFINE_EMBEDDED( m_fog ), DEFINE_EMBEDDED( m_audio ), + + //Tony; added + DEFINE_EMBEDDED( m_TonemapParams ), // "Why don't we save this field, grandpa?" // @@ -223,6 +257,18 @@ void ClientData_Update( CBasePlayer *pl ) // HACKHACK: for 3d skybox // UNDONE: Support multiple sky cameras? CSkyCamera *pSkyCamera = GetCurrentSkyCamera(); +#ifdef MAPBASE + // Needs null protection now that the sky can go from valid to null + if ( !pSkyCamera ) + { + pl->m_Local.m_skybox3d.area = 255; + } + else if ( pSkyCamera != pl->m_Local.m_pOldSkyCamera ) + { + pl->m_Local.m_pOldSkyCamera = pSkyCamera; + pl->m_Local.m_skybox3d.CopyFrom(pSkyCamera->m_skyboxData); + } +#else if ( pSkyCamera != pl->m_Local.m_pOldSkyCamera ) { pl->m_Local.m_pOldSkyCamera = pSkyCamera; @@ -232,6 +278,7 @@ void ClientData_Update( CBasePlayer *pl ) { pl->m_Local.m_skybox3d.area = 255; } +#endif } diff --git a/game/server/playerlocaldata.h b/game/server/playerlocaldata.h index 04dc3a8f..f9ceef70 100644 --- a/game/server/playerlocaldata.h +++ b/game/server/playerlocaldata.h @@ -15,6 +15,10 @@ #include "playernet_vars.h" #include "networkvar.h" #include "fogcontroller.h" +#ifdef MAPBASE // From Alien Swarm SDK +#include "postprocesscontroller.h" +#include "colorcorrection.h" +#endif //----------------------------------------------------------------------------- // Purpose: Player specific data ( sent only to local player, too ) @@ -83,6 +87,9 @@ class CPlayerLocalData // audio environment CNetworkVarEmbedded( audioparams_t, m_audio ); + //Tony; added so tonemap controller can work in multiplayer with inputs. + CNetworkVarEmbedded( tonemap_params_t, m_TonemapParams ); + CNetworkVar( bool, m_bSlowMovement ); }; diff --git a/game/server/point_camera.cpp b/game/server/point_camera.cpp index df4338b5..72a40b26 100644 --- a/game/server/point_camera.cpp +++ b/game/server/point_camera.cpp @@ -28,6 +28,58 @@ CPointCamera* GetPointCameraList() return g_PointCameraList.m_pClassList; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Returns true if a camera is in the PVS of the specified entity +//----------------------------------------------------------------------------- +edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict ) +{ + CBaseEntity *pe = GetContainingEntity( pEdict ); + if ( !pe ) + return NULL; + + bool bGotPVS = false; + Vector org; + static byte pvs[ MAX_MAP_CLUSTERS/8 ]; + static int pvssize = sizeof( pvs ); + + for ( CPointCamera *pCameraEnt = GetPointCameraList(); pCameraEnt != NULL; pCameraEnt = pCameraEnt->m_pNext ) + { + if (!pCameraEnt->IsActive()) + continue; + + if (!bGotPVS) + { + // Getting the PVS during the loop like this makes sure we only get the PVS if there's actually an active camera in the level + org = pe->EyePosition(); + int clusterIndex = engine->GetClusterForOrigin( org ); + Assert( clusterIndex >= 0 ); + engine->GetPVSForCluster( clusterIndex, pvssize, pvs ); + bGotPVS = true; + } + + Vector vecCameraEye = pCameraEnt->EyePosition(); + + Vector vecCameraDirection; + pCameraEnt->GetVectors( &vecCameraDirection, NULL, NULL ); + + Vector los = (org - vecCameraEye); + float flDot = DotProduct( los, vecCameraDirection ); + + // Make sure we're in the camera's FOV before checking PVS + if ( flDot <= cos( DEG2RAD( pCameraEnt->GetFOV() / 2 ) ) ) + continue; + + if ( engine->CheckOriginInPVS( vecCameraEye, pvs, pvssize ) ) + { + return pCameraEnt->edict(); + } + } + + return NULL; +} +#endif + // These are already built into CBaseEntity // DEFINE_KEYFIELD( m_iName, FIELD_STRING, "targetname" ), // DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ), @@ -51,6 +103,13 @@ CPointCamera::CPointCamera() m_bFogEnable = false; +#ifdef MAPBASE + // Equivalent to SKYBOX_2DSKYBOX_VISIBLE, the original sky setting + m_iSkyMode = 2; + + m_iszRenderTarget = AllocPooledString( "_rt_Camera" ); +#endif + g_PointCameraList.Insert( this ); } @@ -187,6 +246,13 @@ void CPointCamera::InputSetOnAndTurnOthersOff( inputdata_t &inputdata ) while ((pEntity = gEntList.FindEntityByClassname( pEntity, "point_camera" )) != NULL) { CPointCamera *pCamera = (CPointCamera*)pEntity; + +#ifdef MAPBASE + // Do not turn off cameras which use different render targets + if (pCamera->m_iszRenderTarget.Get() != m_iszRenderTarget.Get()) + continue; +#endif + pCamera->InputSetOff( inputdata ); } @@ -222,6 +288,10 @@ BEGIN_DATADESC( CPointCamera ) DEFINE_KEYFIELD( m_flFogEnd, FIELD_FLOAT, "fogEnd" ), DEFINE_KEYFIELD( m_flFogMaxDensity, FIELD_FLOAT, "fogMaxDensity" ), DEFINE_KEYFIELD( m_bUseScreenAspectRatio, FIELD_BOOLEAN, "UseScreenAspectRatio" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iSkyMode, FIELD_INTEGER, "SkyMode" ), + DEFINE_KEYFIELD( m_iszRenderTarget, FIELD_STRING, "RenderTarget" ), +#endif DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ), DEFINE_FIELD( m_bIsOn, FIELD_BOOLEAN ), @@ -237,6 +307,10 @@ BEGIN_DATADESC( CPointCamera ) DEFINE_INPUTFUNC( FIELD_VOID, "SetOnAndTurnOthersOff", InputSetOnAndTurnOthersOff ), DEFINE_INPUTFUNC( FIELD_VOID, "SetOn", InputSetOn ), DEFINE_INPUTFUNC( FIELD_VOID, "SetOff", InputSetOff ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSkyMode", InputSetSkyMode ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetRenderTarget", InputSetRenderTarget ), +#endif END_DATADESC() @@ -250,4 +324,215 @@ IMPLEMENT_SERVERCLASS_ST( CPointCamera, DT_PointCamera ) SendPropFloat( SENDINFO( m_flFogMaxDensity ), 0, SPROP_NOSCALE ), SendPropInt( SENDINFO( m_bActive ), 1, SPROP_UNSIGNED ), SendPropInt( SENDINFO( m_bUseScreenAspectRatio ), 1, SPROP_UNSIGNED ), +#ifdef MAPBASE + SendPropInt( SENDINFO( m_iSkyMode ) ), + SendPropStringT( SENDINFO( m_iszRenderTarget ) ), +#endif END_SEND_TABLE() + +#ifdef MAPBASE + +//============================================================================= +// Orthographic point_camera +//============================================================================= + +BEGIN_DATADESC( CPointCameraOrtho ) + + DEFINE_KEYFIELD( m_bOrtho, FIELD_BOOLEAN, "IsOrtho" ), + DEFINE_ARRAY( m_OrthoDimensions, FIELD_FLOAT, CPointCameraOrtho::NUM_ORTHO_DIMENSIONS ), + + DEFINE_ARRAY( m_TargetOrtho, FIELD_FLOAT, CPointCameraOrtho::NUM_ORTHO_DIMENSIONS ), + DEFINE_FIELD( m_TargetOrthoDPS, FIELD_FLOAT ), + + DEFINE_FUNCTION( ChangeOrthoThink ), + + // Input + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetOrthoEnabled", InputSetOrthoEnabled ), + DEFINE_INPUTFUNC( FIELD_STRING, "ScaleOrtho", InputScaleOrtho ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoTop", InputSetOrthoTop ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoBottom", InputSetOrthoBottom ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoLeft", InputSetOrthoLeft ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoRight", InputSetOrthoRight ), + +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CPointCameraOrtho, DT_PointCameraOrtho ) + SendPropInt( SENDINFO( m_bOrtho ), 1, SPROP_UNSIGNED ), + SendPropArray( SendPropFloat(SENDINFO_ARRAY(m_OrthoDimensions), CPointCameraOrtho::NUM_ORTHO_DIMENSIONS, SPROP_NOSCALE ), m_OrthoDimensions ), +END_SEND_TABLE() + +LINK_ENTITY_TO_CLASS( point_camera_ortho, CPointCameraOrtho ); + +CPointCameraOrtho::~CPointCameraOrtho() +{ +} + +CPointCameraOrtho::CPointCameraOrtho() +{ +} + +void CPointCameraOrtho::Spawn( void ) +{ + BaseClass::Spawn(); + + // If 0, get the FOV + if (m_OrthoDimensions[ORTHO_TOP] == 0.0f) + m_OrthoDimensions.Set( ORTHO_TOP, GetFOV() ); + + // If 0, get the negative top ortho + if (m_OrthoDimensions[ORTHO_BOTTOM] == 0.0f) + m_OrthoDimensions.Set( ORTHO_BOTTOM, -m_OrthoDimensions[ORTHO_TOP] ); + + // If 0, get the top ortho + if (m_OrthoDimensions[ORTHO_LEFT] == 0.0f) + m_OrthoDimensions.Set( ORTHO_LEFT, m_OrthoDimensions[ORTHO_TOP] ); + + // If 0, get the negative left ortho + if (m_OrthoDimensions[ORTHO_RIGHT] == 0.0f) + m_OrthoDimensions.Set( ORTHO_RIGHT, -m_OrthoDimensions[ORTHO_LEFT] ); +} + +bool CPointCameraOrtho::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( strncmp( szKeyName, "Ortho", 5 ) == 0 ) + { + int iOrtho = atoi(szKeyName + 5); + m_OrthoDimensions.Set( iOrtho, atof( szValue ) ); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} + +bool CPointCameraOrtho::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + if ( strncmp( szKeyName, "Ortho", 5 ) ) + { + int iOrtho = atoi(szKeyName + 5); + Q_snprintf( szValue, iMaxLen, "%f", m_OrthoDimensions[iOrtho] ); + } + else + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCameraOrtho::ChangeOrtho( int iType, const char *szChange ) +{ + // Parse the keyvalue data + char parseString[255]; + Q_strncpy( parseString, szChange, sizeof( parseString ) ); + + // Get Ortho + char *pszParam = strtok( parseString, " " ); + if (pszParam) + { + m_TargetOrtho[iType] = atof( pszParam ); + } + else + { + // Assume no change + m_TargetOrtho[iType] = m_OrthoDimensions[iType]; + } + + // Get Time + float flChangeTime; + pszParam = strtok( NULL, " " ); + if (pszParam) + { + flChangeTime = atof( pszParam ); + } + else + { + // Assume 1 second + flChangeTime = 1.0; + } + + m_TargetOrthoDPS = ( m_TargetOrtho[iType] - m_OrthoDimensions[iType] ) / flChangeTime; + + SetThink( &CPointCameraOrtho::ChangeOrthoThink ); + SetNextThink( gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCameraOrtho::InputScaleOrtho( inputdata_t &inputdata ) +{ + // Parse the keyvalue data + char parseString[255]; + Q_strncpy( parseString, inputdata.value.String(), sizeof( parseString ) ); + + // Get Scale + float flScale = 1.0f; + char *pszParam = strtok( parseString, " " ); + if (pszParam) + { + flScale = atof( pszParam ); + } + + // Get Time + float flChangeTime = 1.0f; + pszParam = strtok( NULL, " " ); + if (pszParam) + { + flChangeTime = atof( pszParam ); + } + + int iLargest = 0; + for (int i = 0; i < NUM_ORTHO_DIMENSIONS; i++) + { + m_TargetOrtho[i] = flScale * m_OrthoDimensions[i]; + + if (m_TargetOrtho[iLargest] <= m_TargetOrtho[i]) + iLargest = i; + } + + m_TargetOrthoDPS = (m_TargetOrtho[iLargest] - m_OrthoDimensions[iLargest]) / flChangeTime; + + SetThink( &CPointCameraOrtho::ChangeOrthoThink ); + SetNextThink( gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPointCameraOrtho::ChangeOrthoThink( void ) +{ + SetNextThink( gpGlobals->curtime + CAM_THINK_INTERVAL ); + + int iChanging = 0; + for (int i = 0; i < NUM_ORTHO_DIMENSIONS; i++) + { + float newDim = m_OrthoDimensions[i]; + if (newDim == m_TargetOrtho[i]) + continue; + + newDim += m_TargetOrthoDPS * CAM_THINK_INTERVAL; + + if (m_TargetOrthoDPS < 0) + { + if (newDim <= m_TargetOrtho[i]) + { + newDim = m_TargetOrtho[i]; + } + } + else + { + if (newDim >= m_TargetOrtho[i]) + { + newDim = m_TargetOrtho[i]; + } + } + + m_OrthoDimensions.Set(i, newDim); + } + + if (iChanging == 0) + SetThink( NULL ); +} +#endif diff --git a/game/server/point_camera.h b/game/server/point_camera.h index 499b3a36..9cb7d3c4 100644 --- a/game/server/point_camera.h +++ b/game/server/point_camera.h @@ -37,6 +37,13 @@ class CPointCamera : public CBaseEntity void InputSetOnAndTurnOthersOff( inputdata_t &inputdata ); void InputSetOn( inputdata_t &inputdata ); void InputSetOff( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetSkyMode( inputdata_t &inputdata ) { m_iSkyMode = inputdata.value.Int(); } + void InputSetRenderTarget( inputdata_t &inputdata ) { m_iszRenderTarget = inputdata.value.StringID(); } + + float GetFOV() const { return m_FOV; } + bool IsActive() const { return m_bIsOn; } +#endif private: float m_TargetFOV; @@ -51,6 +58,10 @@ class CPointCamera : public CBaseEntity CNetworkVar( float, m_flFogMaxDensity ); CNetworkVar( bool, m_bActive ); CNetworkVar( bool, m_bUseScreenAspectRatio ); +#ifdef MAPBASE + CNetworkVar( int, m_iSkyMode ); + CNetworkVar( string_t, m_iszRenderTarget ); +#endif // Allows the mapmaker to control whether a camera is active or not bool m_bIsOn; @@ -59,5 +70,56 @@ class CPointCamera : public CBaseEntity CPointCamera *m_pNext; }; +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPointCameraOrtho : public CPointCamera +{ +public: + DECLARE_CLASS( CPointCameraOrtho, CPointCamera ); + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + CPointCameraOrtho(); + ~CPointCameraOrtho(); + + enum + { + ORTHO_TOP, + ORTHO_BOTTOM, + ORTHO_LEFT, + ORTHO_RIGHT, + + NUM_ORTHO_DIMENSIONS + }; + + void Spawn( void ); + + bool KeyValue( const char *szKeyName, const char *szValue ); + bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + + void ChangeOrtho( int iType, const char *szChange ); + void ChangeOrthoThink( void ); + + void InputSetOrthoEnabled( inputdata_t &inputdata ) { m_bOrtho = inputdata.value.Bool(); } + void InputScaleOrtho( inputdata_t &inputdata ); + void InputSetOrthoTop( inputdata_t &inputdata ) { ChangeOrtho(ORTHO_TOP, inputdata.value.String()); } + void InputSetOrthoBottom( inputdata_t &inputdata ) { ChangeOrtho( ORTHO_BOTTOM, inputdata.value.String() ); } + void InputSetOrthoLeft( inputdata_t &inputdata ) { ChangeOrtho( ORTHO_LEFT, inputdata.value.String() ); } + void InputSetOrthoRight( inputdata_t &inputdata ) { ChangeOrtho( ORTHO_RIGHT, inputdata.value.String() ); } + +private: + float m_TargetOrtho[NUM_ORTHO_DIMENSIONS]; + float m_TargetOrthoDPS; + + CNetworkVar( bool, m_bOrtho ); + CNetworkArray( float, m_OrthoDimensions, NUM_ORTHO_DIMENSIONS ); +}; +#endif + CPointCamera *GetPointCameraList(); + +#ifdef MAPBASE +edict_t *UTIL_FindRTCameraInEntityPVS( edict_t *pEdict ); +#endif #endif // CAMERA_H diff --git a/game/server/point_devshot_camera.cpp b/game/server/point_devshot_camera.cpp index 3e2e2dbd..4d476664 100644 --- a/game/server/point_devshot_camera.cpp +++ b/game/server/point_devshot_camera.cpp @@ -53,24 +53,6 @@ END_DATADESC() LINK_ENTITY_TO_CLASS( point_devshot_camera, CPointDevShotCamera ); -//----------------------------------------------------------------------------- -// Purpose: Convenience function so we don't have to make this check all over -//----------------------------------------------------------------------------- -static CBasePlayer * UTIL_GetLocalPlayerOrListenServerHost( void ) -{ - if ( gpGlobals->maxClients > 1 ) - { - if ( engine->IsDedicatedServer() ) - { - return NULL; - } - - return UTIL_GetListenServerHost(); - } - - return UTIL_GetLocalPlayer(); -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -245,6 +227,10 @@ class CDevShotSystem : public CAutoGameSystemPerFrame } } +#ifdef MAPBASE // VDC Memory Leak Fixes + pkvMapCameras->deleteThis(); +#endif + if ( !g_iDevShotCameraCount ) { Warning( "Devshots: No point_devshot_camera in %s. Moving to next map.\n", STRING( gpGlobals->mapname ) ); diff --git a/game/server/point_entity_finder.cpp b/game/server/point_entity_finder.cpp new file mode 100644 index 00000000..d26b71f4 --- /dev/null +++ b/game/server/point_entity_finder.cpp @@ -0,0 +1,207 @@ +//----------------------------------------------------------------------------- +// class CPointEntityFinder +// +// Purpose: Finds an entity using a specified heuristic and outputs it as !caller +// with the OnFoundEntity output. +//----------------------------------------------------------------------------- + +#include "cbase.h" +#include "filters.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +enum EntFinderMethod_t +{ + ENT_FIND_METHOD_NEAREST = 0, + ENT_FIND_METHOD_FARTHEST, + ENT_FIND_METHOD_RANDOM, +}; + +class CPointEntityFinder : public CBaseEntity +{ + void Activate( void ); + + DECLARE_CLASS( CPointEntityFinder, CBaseEntity ); + +private: + + EHANDLE m_hEntity; + string_t m_iFilterName; + CHandle m_hFilter; + string_t m_iRefName; + EHANDLE m_hReference; + + EntFinderMethod_t m_FindMethod; + + void FindEntity( void ); + void FindByDistance( void ); + void FindByRandom( void ); + + // Input handlers + void InputFindEntity( inputdata_t &inputdata ); + + // Output handlers + COutputEvent m_OnFoundEntity; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( point_entity_finder, CPointEntityFinder ); + +BEGIN_DATADESC( CPointEntityFinder ) + + DEFINE_KEYFIELD( m_FindMethod, FIELD_INTEGER, "method" ), + DEFINE_KEYFIELD( m_iFilterName, FIELD_STRING, "filtername" ), + DEFINE_FIELD( m_hFilter, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_iRefName, FIELD_STRING, "referencename" ), + DEFINE_FIELD( m_hReference, FIELD_EHANDLE ), + + DEFINE_OUTPUT( m_OnFoundEntity, "OnFoundEntity" ), + + //--------------------------------- + + DEFINE_INPUTFUNC( FIELD_VOID, "FindEntity", InputFindEntity ), + +END_DATADESC() + + +void CPointEntityFinder::Activate( void ) +{ + // Get the filter, if it exists. + if (m_iFilterName != NULL_STRING) + { + m_hFilter = dynamic_cast(gEntList.FindEntityByName( NULL, m_iFilterName )); + } + + BaseClass::Activate(); +} + + +void CPointEntityFinder::FindEntity( void ) +{ + // Get the reference entity, if it exists. + if (m_iRefName != NULL_STRING) + { + m_hReference = gEntList.FindEntityByName( NULL, m_iRefName ); + } + + switch ( m_FindMethod ) + { + + case ( ENT_FIND_METHOD_NEAREST ): + FindByDistance(); + break; + case ( ENT_FIND_METHOD_FARTHEST ): + FindByDistance(); + break; + case ( ENT_FIND_METHOD_RANDOM ): + FindByRandom(); + break; + } +} + +void CPointEntityFinder::FindByDistance( void ) +{ + m_hEntity = NULL; + CBaseFilter *pFilter = m_hFilter.Get(); + +// go through each entity and determine whether it's closer or farther from the current entity. Pick according to Method selected. + + float flBestDist = 0; + CBaseEntity *pEntity = gEntList.FirstEnt(); + while ( pEntity ) + { + if ( FStrEq( STRING( pEntity->m_iClassname ), "worldspawn" ) + || FStrEq( STRING( pEntity->m_iClassname ), "soundent" ) + || FStrEq( STRING( pEntity->m_iClassname ), "player_manager" ) + || FStrEq( STRING( pEntity->m_iClassname ), "bodyque" ) + || FStrEq( STRING( pEntity->m_iClassname ), "ai_network" ) + || pEntity == this + || ( pFilter && !( pFilter->PassesFilter( this, pEntity ) ) ) ) + { + pEntity = gEntList.NextEnt( pEntity ); + continue; + } + + // if we have a reference entity, use that, otherwise, check against 'this' + Vector vecStart; + if ( m_hReference ) + { + vecStart = m_hReference->GetAbsOrigin(); + } + else + { + vecStart = GetAbsOrigin(); + } + + // init m_hEntity with a valid entity. + if (m_hEntity == NULL ) + { + m_hEntity = pEntity; + flBestDist = ( pEntity->GetAbsOrigin() - vecStart ).LengthSqr(); + } + + float flNewDist = ( pEntity->GetAbsOrigin() - vecStart ).LengthSqr(); + + switch ( m_FindMethod ) + { + + case ( ENT_FIND_METHOD_NEAREST ): + if ( flNewDist < flBestDist ) + { + m_hEntity = pEntity; + flBestDist = flNewDist; + } + break; + + case ( ENT_FIND_METHOD_FARTHEST ): + if ( flNewDist > flBestDist ) + { + m_hEntity = pEntity; + flBestDist = flNewDist; + } + break; + + default: + Assert( false ); + break; + } + + pEntity = gEntList.NextEnt( pEntity ); + } +} + +void CPointEntityFinder::FindByRandom( void ) +{ + // TODO: optimize the case where there is no filter + m_hEntity = NULL; + CBaseFilter *pFilter = m_hFilter.Get(); + CUtlVector ValidEnts; + + CBaseEntity *pEntity = gEntList.FirstEnt(); + do // note all valid entities. + { + if ( pFilter && pFilter->PassesFilter( this, pEntity ) ) + { + ValidEnts.AddToTail( pEntity ); + } + + pEntity = gEntList.NextEnt( pEntity ); + + } while ( pEntity ); + + // pick one at random + if ( ValidEnts.Count() != 0 ) + { + m_hEntity = ValidEnts[ RandomInt( 0, ValidEnts.Count() - 1 )]; + } +} + +void CPointEntityFinder::InputFindEntity( inputdata_t &inputdata ) +{ + FindEntity(); + + m_OnFoundEntity.FireOutput( inputdata.pActivator, m_hEntity ); +} \ No newline at end of file diff --git a/game/server/point_spotlight.cpp b/game/server/point_spotlight.cpp index 030537ed..d5901714 100644 --- a/game/server/point_spotlight.cpp +++ b/game/server/point_spotlight.cpp @@ -26,6 +26,9 @@ class CPointSpotlight : public CPointEntity DECLARE_DATADESC(); CPointSpotlight(); +#ifdef MAPBASE + ~CPointSpotlight(); +#endif void Precache(void); void Spawn(void); @@ -46,6 +49,9 @@ class CPointSpotlight : public CPointEntity // ------------------------------ void InputLightOn( inputdata_t &inputdata ); void InputLightOff( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputLightToggle( inputdata_t &inputdata ) { m_bSpotlightOn ? InputLightOff(inputdata) : InputLightOn(inputdata); } +#endif // Creates the efficient spotlight void CreateEfficientSpotlight(); @@ -56,7 +62,6 @@ class CPointSpotlight : public CPointEntity private: bool m_bSpotlightOn; bool m_bEfficientSpotlight; - bool m_bIgnoreSolid; Vector m_vSpotlightTargetPos; Vector m_vSpotlightCurrentPos; Vector m_vSpotlightDir; @@ -70,6 +75,12 @@ class CPointSpotlight : public CPointEntity float m_flHDRColorScale; int m_nMinDXLevel; +#ifdef MAPBASE + float m_flHaloScale; + string_t m_iszHaloMaterial; + string_t m_iszSpotlightMaterial; +#endif + public: COutputEvent m_OnOn, m_OnOff; ///< output fires when turned on, off }; @@ -89,15 +100,22 @@ BEGIN_DATADESC( CPointSpotlight ) DEFINE_FIELD( m_vSpotlightDir, FIELD_VECTOR ), DEFINE_FIELD( m_nHaloSprite, FIELD_INTEGER ), - DEFINE_KEYFIELD( m_bIgnoreSolid, FIELD_BOOLEAN, "IgnoreSolid" ), DEFINE_KEYFIELD( m_flSpotlightMaxLength,FIELD_FLOAT, "SpotlightLength"), DEFINE_KEYFIELD( m_flSpotlightGoalWidth,FIELD_FLOAT, "SpotlightWidth"), DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ), DEFINE_KEYFIELD( m_nMinDXLevel, FIELD_INTEGER, "mindxlevel" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flHaloScale, FIELD_FLOAT, "HaloScale" ), + DEFINE_KEYFIELD( m_iszHaloMaterial, FIELD_STRING, "HaloMaterial" ), + DEFINE_KEYFIELD( m_iszSpotlightMaterial, FIELD_STRING, "SpotlightMaterial" ), +#endif // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "LightOn", InputLightOn ), DEFINE_INPUTFUNC( FIELD_VOID, "LightOff", InputLightOff ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "LightToggle", InputLightToggle ), +#endif DEFINE_OUTPUT( m_OnOn, "OnLightOn" ), DEFINE_OUTPUT( m_OnOff, "OnLightOff" ), @@ -120,9 +138,21 @@ CPointSpotlight::CPointSpotlight() #endif m_flHDRColorScale = 1.0f; m_nMinDXLevel = 0; - m_bIgnoreSolid = false; +#ifdef MAPBASE + m_flHaloScale = 60.0f; +#endif } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPointSpotlight::~CPointSpotlight() +{ + SpotlightDestroy(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: @@ -132,8 +162,23 @@ void CPointSpotlight::Precache(void) BaseClass::Precache(); // Sprites. +#ifdef MAPBASE + if (m_iszHaloMaterial == NULL_STRING) + { + m_iszHaloMaterial = AllocPooledString( "sprites/light_glow03.vmt" ); + } + + if (m_iszSpotlightMaterial == NULL_STRING) + { + m_iszSpotlightMaterial = AllocPooledString( "sprites/glow_test02.vmt" ); + } + + m_nHaloSprite = PrecacheModel( STRING( m_iszHaloMaterial ) ); + PrecacheModel( STRING( m_iszSpotlightMaterial ) ); +#else m_nHaloSprite = PrecacheModel("sprites/light_glow03.vmt"); PrecacheModel( "sprites/glow_test02.vmt" ); +#endif } @@ -335,21 +380,12 @@ void CPointSpotlight::SpotlightCreate(void) AngleVectors( GetAbsAngles(), &m_vSpotlightDir ); - Vector vTargetPos; - if ( m_bIgnoreSolid ) - { - vTargetPos = GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength; - } - else - { - trace_t tr; - UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); - vTargetPos = tr.endpos; - } + trace_t tr; + UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); m_hSpotlightTarget = (CSpotlightEnd*)CreateEntityByName( "spotlight_end" ); m_hSpotlightTarget->Spawn(); - m_hSpotlightTarget->SetAbsOrigin( vTargetPos ); + m_hSpotlightTarget->SetAbsOrigin( tr.endpos ); m_hSpotlightTarget->SetOwnerEntity( this ); m_hSpotlightTarget->m_clrRender = m_clrRender; m_hSpotlightTarget->m_Radius = m_flSpotlightMaxLength; @@ -360,13 +396,21 @@ void CPointSpotlight::SpotlightCreate(void) } //m_hSpotlight = CBeam::BeamCreate( "sprites/spotlight.vmt", m_flSpotlightGoalWidth ); +#ifdef MAPBASE + m_hSpotlight = CBeam::BeamCreate( STRING(m_iszSpotlightMaterial), m_flSpotlightGoalWidth ); +#else m_hSpotlight = CBeam::BeamCreate( "sprites/glow_test02.vmt", m_flSpotlightGoalWidth ); +#endif // Set the temporary spawnflag on the beam so it doesn't save (we'll recreate it on restore) m_hSpotlight->SetHDRColorScale( m_flHDRColorScale ); m_hSpotlight->AddSpawnFlags( SF_BEAM_TEMPORARY ); m_hSpotlight->SetColor( m_clrRender->r, m_clrRender->g, m_clrRender->b ); m_hSpotlight->SetHaloTexture(m_nHaloSprite); +#ifdef MAPBASE + m_hSpotlight->SetHaloScale(m_flHaloScale); +#else m_hSpotlight->SetHaloScale(60); +#endif m_hSpotlight->SetEndWidth(m_flSpotlightGoalWidth); m_hSpotlight->SetBeamFlags( (FBEAM_SHADEOUT|FBEAM_NOTILE) ); m_hSpotlight->SetBrightness( 64 ); @@ -393,17 +437,9 @@ Vector CPointSpotlight::SpotlightCurrentPos(void) AngleVectors( GetAbsAngles(), &m_vSpotlightDir ); // Get beam end point. Only collide with solid objects, not npcs - Vector vEndPos = GetAbsOrigin() + ( m_vSpotlightDir * 2 * m_flSpotlightMaxLength ); - if ( m_bIgnoreSolid ) - { - return vEndPos; - } - else - { - trace_t tr; - UTIL_TraceLine( GetAbsOrigin(), vEndPos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); - return tr.endpos; - } + trace_t tr; + UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + (m_vSpotlightDir * 2 * m_flSpotlightMaxLength), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); + return tr.endpos; } //------------------------------------------------------------------------------ diff --git a/game/server/point_template.cpp b/game/server/point_template.cpp index b933bd2d..3cb654ca 100644 --- a/game/server/point_template.cpp +++ b/game/server/point_template.cpp @@ -55,14 +55,23 @@ BEGIN_DATADESC( CPointTemplate ) DEFINE_KEYFIELD( m_iszTemplateEntityNames[14], FIELD_STRING, "Template15"), DEFINE_KEYFIELD( m_iszTemplateEntityNames[15], FIELD_STRING, "Template16"), DEFINE_UTLVECTOR( m_hTemplateEntities, FIELD_CLASSPTR ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bFixupExpanded, FIELD_BOOLEAN, "FixupMode" ), +#endif DEFINE_UTLVECTOR( m_hTemplates, FIELD_EMBEDDED ), // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "ForceSpawn", InputForceSpawn ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "ForceSpawnRandomTemplate", InputForceSpawnRandomTemplate ), +#endif // Outputs DEFINE_OUTPUT( m_pOutputOnSpawned, "OnEntitySpawned" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_pOutputOutEntity, "OutSpawnedEntity" ), +#endif END_DATADESC() @@ -127,6 +136,8 @@ void PrecachePointTemplates() void CPointTemplate::Spawn( void ) { Precache(); + ScriptInstallPreSpawnHook(); + ValidateScriptScope(); } void CPointTemplate::Precache() @@ -339,7 +350,7 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA // Some templates have Entity I/O connecting the entities within the template. // Unique versions of these templates need to be created whenever they're instanced. - if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) + if ( AllowNameFixup() && ( Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) || m_ScriptScope.IsInitialized() ) ) { // This template requires instancing. // Create a new mapdata block and ask the template system to fill it in with @@ -375,7 +386,15 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA pEntity->SetAbsOrigin( vecNewOrigin ); pEntity->SetAbsAngles( vecNewAngles ); - pSpawnList[i].m_pEntity = pEntity; + if (ScriptPreInstanceSpawn(&m_ScriptScope, pEntity, Templates_FindByIndex(iTemplateIndex))) + { + pSpawnList[i].m_pEntity = pEntity; + } + else + { + pSpawnList[i].m_pEntity = NULL; + UTIL_RemoveImmediate(pEntity); + } pSpawnList[i].m_nDepth = 0; pSpawnList[i].m_pDeferredParent = NULL; } @@ -393,6 +412,92 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA return true; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Spawn one of the entities I contain +// Input : &vecOrigin - +// &vecAngles - +// pEntities - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CPointTemplate::CreateSpecificInstance( int iTemplate, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity **pOutEntity ) +{ + // Go through all our templated map data and spawn all the entities in it + int iTemplates = m_hTemplates.Count(); + if ( !iTemplates ) + { + Msg("CreateInstance called on a point_template that has no templates: %s\n", STRING(GetEntityName()) ); + return false; + } + + // Tell the template system we're about to start a new template + Templates_StartUniqueInstance(); + + CBaseEntity *pEntity = NULL; + char *pMapData; + int iTemplateIndex = m_hTemplates[iTemplate].iTemplateIndex; + + // Some templates have Entity I/O connecting the entities within the template. + // Unique versions of these templates need to be created whenever they're instanced. + if ( AllowNameFixup() && ( Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) || m_ScriptScope.IsInitialized() ) ) + { + // This template requires instancing. + // Create a new mapdata block and ask the template system to fill it in with + // a unique version (with fixed Entity I/O connections). + pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); + } + else + { + // Use the unmodified mapdata + pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); + } + + // Create the entity from the mapdata + MapEntity_ParseEntity( pEntity, pMapData, NULL ); + if ( pEntity == NULL ) + { + Msg("Failed to initialize templated entity with mapdata: %s\n", pMapData ); + return false; + } + + // Get a matrix that'll convert from world to the new local space + VMatrix matNewTemplateToWorld, matStoredLocalToWorld; + matNewTemplateToWorld.SetupMatrixOrgAngles( vecOrigin, vecAngles ); + MatrixMultiply( matNewTemplateToWorld, m_hTemplates[iTemplate].matEntityToTemplate, matStoredLocalToWorld ); + + // Get the world origin & angles from the stored local coordinates + Vector vecNewOrigin; + QAngle vecNewAngles; + vecNewOrigin = matStoredLocalToWorld.GetTranslation(); + MatrixToAngles( matStoredLocalToWorld, vecNewAngles ); + + // Set its origin & angles + pEntity->SetAbsOrigin( vecNewOrigin ); + pEntity->SetAbsAngles( vecNewAngles ); + + // Spawn it + DispatchSpawn( pEntity ); + + if (pOutEntity) + { + *pOutEntity = pEntity; + } + + return true; +} +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CPointTemplate::CreationComplete( const CUtlVector &entities ) +{ + if ( !entities.Count() ) + return; + + ScriptPostSpawn( &m_ScriptScope, (CBaseEntity **)entities.Base(), entities.Count() ); +} + //----------------------------------------------------------------------------- // Purpose: // Input : &inputdata - @@ -406,4 +511,104 @@ void CPointTemplate::InputForceSpawn( inputdata_t &inputdata ) // Fire our output m_pOutputOnSpawned.FireOutput( this, this ); + +#ifdef MAPBASE + for ( int i = 0; i < hNewEntities.Count(); i++ ) + { + m_pOutputOutEntity.Set(hNewEntities[i], hNewEntities[i], this); + } +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Randomly spawns one of our templates. +// This is copied from CreateInstance(). +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPointTemplate::InputForceSpawnRandomTemplate( inputdata_t &inputdata ) +{ + // Spawn our template + CBaseEntity *pEntity = NULL; + if ( !CreateSpecificInstance( RandomInt(0, GetNumTemplates() - 1), GetAbsOrigin(), GetAbsAngles(), &pEntity ) ) + return; + + // Fire our output + m_pOutputOnSpawned.FireOutput( this, this ); + m_pOutputOutEntity.Set(pEntity, pEntity, this); +} +#endif + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void ScriptInstallPreSpawnHook() +{ +#ifdef MAPBASE_VSCRIPT + if ( !g_pScriptVM ) + return; +#endif + +#ifdef IS_WINDOWS_PC + if ( !g_pScriptVM->ValueExists( "__ExecutePreSpawn " ) ) + { + //g_pScriptVM->Run( g_Script_spawn_helper ); + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: This function is called after a spawner creates its child entity +// but before the keyvalues are injected. This gives us an +// opportunity to change any keyvalues before the entity is +// configured and spawned. In this case, we see if there is a VScript +// that wants to change anything about this entity. +//----------------------------------------------------------------------------- +bool ScriptPreInstanceSpawn( CScriptScope *pScriptScope, CBaseEntity *pChild, string_t iszKeyValueData ) +{ + if ( !pScriptScope->IsInitialized() ) + return true; + + ScriptVariant_t result; + if ( pScriptScope->Call( "__ExecutePreSpawn", &result, ToHScript( pChild ) ) != SCRIPT_DONE ) + return true; + + if ( ( result.m_type == FIELD_BOOLEAN && !result.m_bool ) || ( result.m_type == FIELD_INTEGER && !result.m_int ) ) + return false; + + return true; + +} + +void ScriptPostSpawn( CScriptScope *pScriptScope, CBaseEntity **ppEntities, int nEntities ) +{ + if ( !pScriptScope->IsInitialized() ) + return; + + HSCRIPT hPostSpawnFunc = pScriptScope->LookupFunction( "PostSpawn" ); + + if ( !hPostSpawnFunc ) + return; + + ScriptVariant_t varEntityMakerResultTable; + if ( !g_pScriptVM->GetValue( *pScriptScope, "__EntityMakerResult", &varEntityMakerResultTable ) ) + return; + + if ( varEntityMakerResultTable.m_type != FIELD_HSCRIPT ) + return; + + HSCRIPT hEntityMakerResultTable = varEntityMakerResultTable.m_hScript; + char szEntName[256]; + for ( int i = 0; i < nEntities; i++ ) + { + V_strncpy( szEntName, ppEntities[i]->GetEntityNameAsCStr(), ARRAYSIZE(szEntName) ); + char *pAmpersand = V_strrchr( szEntName, '&' ); + if ( pAmpersand ) + *pAmpersand = 0; + g_pScriptVM->SetValue( hEntityMakerResultTable, szEntName, ToHScript( ppEntities[i] ) ); + } + pScriptScope->Call( hPostSpawnFunc, NULL, hEntityMakerResultTable ); + pScriptScope->Call( "__FinishSpawn" ); + g_pScriptVM->ReleaseValue( varEntityMakerResultTable ); + g_pScriptVM->ReleaseFunction( hPostSpawnFunc ); } diff --git a/game/server/point_template.h b/game/server/point_template.h index 94e37424..283a4b62 100644 --- a/game/server/point_template.h +++ b/game/server/point_template.h @@ -20,6 +20,10 @@ struct template_t DECLARE_SIMPLE_DATADESC(); }; +void ScriptInstallPreSpawnHook(); +bool ScriptPreInstanceSpawn( CScriptScope *pScriptScope, CBaseEntity *pChild, string_t iszKeyValueData ); +void ScriptPostSpawn( CScriptScope *pScriptScope, CBaseEntity **ppEntities, int nEntities ); + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -42,6 +46,9 @@ class CPointTemplate : public CLogicalEntity void AddTemplate( CBaseEntity *pEntity, const char *pszMapData, int nLen ); bool ShouldRemoveTemplateEntities( void ); bool AllowNameFixup(); +#ifdef MAPBASE + bool NameFixupExpanded() { return m_bFixupExpanded; } +#endif // Templates accessors int GetNumTemplates( void ); @@ -49,9 +56,16 @@ class CPointTemplate : public CLogicalEntity // Template instancing bool CreateInstance( const Vector &vecOrigin, const QAngle &vecAngles, CUtlVector *pEntities ); +#ifdef MAPBASE + bool CreateSpecificInstance( int iTemplate, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity **pOutEntity ); +#endif + void CreationComplete(const CUtlVector& entities); // Inputs void InputForceSpawn( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputForceSpawnRandomTemplate( inputdata_t &inputdata ); +#endif virtual void PerformPrecache(); @@ -63,10 +77,19 @@ class CPointTemplate : public CLogicalEntity // code removes all the entities in it once it finishes turning them into templates. CUtlVector< CBaseEntity * > m_hTemplateEntities; +#ifdef MAPBASE + // Allows name fixup to target all instances of a name in a keyvalue, including output parameters. + // TODO: Support for multiple fixup modes? + bool m_bFixupExpanded; +#endif + // List of templates, generated from our template entities. CUtlVector< template_t > m_hTemplates; COutputEvent m_pOutputOnSpawned; +#ifdef MAPBASE + COutputEHANDLE m_pOutputOutEntity; +#endif }; #endif // POINT_TEMPLATE_H diff --git a/game/server/pointhurt.cpp b/game/server/pointhurt.cpp index 137f0432..ce103e86 100644 --- a/game/server/pointhurt.cpp +++ b/game/server/pointhurt.cpp @@ -30,6 +30,10 @@ class CPointHurt : public CPointEntity void InputTurnOff(inputdata_t &inputdata); void InputToggle(inputdata_t &inputdata); void InputHurt(inputdata_t &inputdata); + +#ifdef MAPBASE + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif DECLARE_DATADESC(); @@ -180,3 +184,21 @@ void CPointHurt::InputHurt( inputdata_t &data ) HurtThink(); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CPointHurt::KeyValue( const char *szKeyName, const char *szValue ) +{ + // Additional OR flags + if (FStrEq( szKeyName, "damageor" ) || FStrEq( szKeyName, "damagepresets" )) + { + m_bitsDamageType |= atoi(szValue); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif + diff --git a/game/server/pointteleport.cpp b/game/server/pointteleport.cpp index 171ee780..e79f6fc3 100644 --- a/game/server/pointteleport.cpp +++ b/game/server/pointteleport.cpp @@ -23,7 +23,15 @@ class CPointTeleport : public CBaseEntity public: void Activate( void ); +#ifdef MAPBASE + void TeleportEntity( CBaseEntity *pTarget, const Vector &vecPosition, const QAngle &angAngles ); +#endif + void InputTeleport( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputTeleportEntity( inputdata_t &inputdata ); + void InputTeleportToCurrentPos( inputdata_t &inputdata ); +#endif private: @@ -45,6 +53,10 @@ BEGIN_DATADESC( CPointTeleport ) DEFINE_FIELD( m_vSaveAngles, FIELD_VECTOR ), DEFINE_INPUTFUNC( FIELD_VOID, "Teleport", InputTeleport ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "TeleportEntity", InputTeleportEntity ), + DEFINE_INPUTFUNC( FIELD_VOID, "TeleportToCurrentPos", InputTeleportToCurrentPos ), +#endif END_DATADESC() @@ -107,6 +119,34 @@ void CPointTeleport::Activate( void ) BaseClass::Activate(); } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CPointTeleport::TeleportEntity( CBaseEntity *pTarget, const Vector &vecPosition, const QAngle &angAngles ) +{ + // in episodic, we have a special spawn flag that forces Gordon into a duck +#ifdef HL2_EPISODIC + if ( (m_spawnflags & SF_TELEPORT_INTO_DUCK) && pTarget->IsPlayer() ) + { + CBasePlayer *pPlayer = ToBasePlayer( pTarget ); + if ( pPlayer != NULL ) + { + pPlayer->m_nButtons |= IN_DUCK; + pPlayer->AddFlag( FL_DUCKING ); + pPlayer->m_Local.m_bDucked = true; + pPlayer->m_Local.m_bDucking = true; + pPlayer->m_Local.m_flDucktime = 0.0f; + pPlayer->SetViewOffset( VEC_DUCK_VIEW_SCALED( pPlayer ) ); + pPlayer->SetCollisionBounds( VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX ); + } + } +#endif + + pTarget->Teleport( &vecPosition, &angAngles, NULL ); +} +#endif + //------------------------------------------------------------------------------ // Purpose: //------------------------------------------------------------------------------ @@ -124,6 +164,9 @@ void CPointTeleport::InputTeleport( inputdata_t &inputdata ) return; } +#ifdef MAPBASE + TeleportEntity( pTarget, m_vSaveOrigin, m_vSaveAngles ); +#else // in episodic, we have a special spawn flag that forces Gordon into a duck #ifdef HL2_EPISODIC if ( (m_spawnflags & SF_TELEPORT_INTO_DUCK) && pTarget->IsPlayer() ) @@ -143,5 +186,49 @@ void CPointTeleport::InputTeleport( inputdata_t &inputdata ) #endif pTarget->Teleport( &m_vSaveOrigin, &m_vSaveAngles, NULL ); +#endif +} + +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CPointTeleport::InputTeleportEntity( inputdata_t &inputdata ) +{ + if ( !inputdata.value.Entity() ) + { + Warning( "%s unable to find entity from TeleportEntity\n", GetDebugName() ); + return; + } + + // If teleport object is in a movement hierarchy, remove it first + if ( EntityMayTeleport( inputdata.value.Entity() ) == false ) + { + Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),inputdata.value.Entity()->GetDebugName(),inputdata.value.Entity()->GetMoveParent()->GetDebugName()); + return; + } + + TeleportEntity( inputdata.value.Entity(), m_vSaveOrigin, m_vSaveAngles ); +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CPointTeleport::InputTeleportToCurrentPos( inputdata_t &inputdata ) +{ + // Attempt to find the entity in question + CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target, this, inputdata.pActivator, inputdata.pCaller ); + if ( pTarget == NULL ) + return; + + // If teleport object is in a movement hierarchy, remove it first + if ( EntityMayTeleport( pTarget ) == false ) + { + Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName()); + return; + } + + TeleportEntity( pTarget, GetAbsOrigin(), GetAbsAngles() ); } +#endif diff --git a/game/server/postprocesscontroller.cpp b/game/server/postprocesscontroller.cpp new file mode 100644 index 00000000..3e3fd6b5 --- /dev/null +++ b/game/server/postprocesscontroller.cpp @@ -0,0 +1,207 @@ +//========= Copyright 1996-2007, Valve Corporation, All rights reserved. ========== +// +// An entity that allows level designer control over the post-processing parameters. +// +//=================================================================================== + +#include "cbase.h" +#include "postprocesscontroller.h" +#include "entityinput.h" +#include "entityoutput.h" +#include "eventqueue.h" +#include "player.h" +#include "world.h" +#include "ndebugoverlay.h" +#include "triggers.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CPostProcessSystem s_PostProcessSystem( "PostProcessSystem" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPostProcessSystem *PostProcessSystem() +{ + return &s_PostProcessSystem; +} + + +LINK_ENTITY_TO_CLASS( postprocess_controller, CPostProcessController ); + +BEGIN_DATADESC( CPostProcessController ) + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FADE_TIME ], FIELD_FLOAT, "fadetime" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_LOCAL_CONTRAST_STRENGTH ], FIELD_FLOAT, "localcontraststrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_LOCAL_CONTRAST_EDGE_STRENGTH ], FIELD_FLOAT, "localcontrastedgestrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_START ], FIELD_TIME, "vignettestart" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_END ], FIELD_TIME, "vignetteend" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_VIGNETTE_BLUR_STRENGTH ], FIELD_FLOAT, "vignetteblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FADE_TO_BLACK_STRENGTH ], FIELD_FLOAT, "fadetoblackstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_DEPTH_BLUR_FOCAL_DISTANCE ], FIELD_FLOAT, "depthblurfocaldistance" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_DEPTH_BLUR_STRENGTH ], FIELD_FLOAT, "depthblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_SCREEN_BLUR_STRENGTH ], FIELD_FLOAT, "screenblurstrength" ), + DEFINE_KEYFIELD( m_flPostProcessParameters[ PPPN_FILM_GRAIN_STRENGTH ], FIELD_FLOAT, "filmgrainstrength" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeTime", InputSetFadeTime ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLocalContrastStrength", InputSetLocalContrastStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLocalContrastEdgeStrength", InputSetLocalContrastEdgeStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteStart", InputSetVignetteStart ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteEnd", InputSetVignetteEnd ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVignetteBlurStrength", InputSetVignetteBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFadeToBlackStrength", InputSetFadeToBlackStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDepthBlurFocalDistance", InputSetDepthBlurFocalDistance), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDepthBlurStrength", InputSetDepthBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetScreenBlurStrength", InputSetScreenBlurStrength ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFilmGrainStrength", InputSetFilmGrainStrength ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CPostProcessController, DT_PostProcessController ) + SendPropArray3( SENDINFO_ARRAY3( m_flPostProcessParameters ), SendPropFloat( SENDINFO_ARRAY( m_flPostProcessParameters ) ) ), + SendPropBool( SENDINFO(m_bMaster) ), +END_SEND_TABLE() + + +CPostProcessController::CPostProcessController() +{ + m_bMaster = false; +} + +CPostProcessController::~CPostProcessController() +{ +} + +void CPostProcessController::Spawn() +{ + BaseClass::Spawn(); + + m_bMaster = IsMaster(); +} + +int CPostProcessController::UpdateTransmitState() +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +void CPostProcessController::InputSetFadeTime( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FADE_TIME, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetLocalContrastStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_LOCAL_CONTRAST_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetLocalContrastEdgeStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_LOCAL_CONTRAST_EDGE_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteStart( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_START, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteEnd( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_END, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetVignetteBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_VIGNETTE_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetFadeToBlackStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FADE_TO_BLACK_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetDepthBlurFocalDistance( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_DEPTH_BLUR_FOCAL_DISTANCE, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetDepthBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_DEPTH_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetScreenBlurStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_SCREEN_BLUR_STRENGTH, inputdata.value.Float() ); +} + +void CPostProcessController::InputSetFilmGrainStrength( inputdata_t &inputdata ) +{ + m_flPostProcessParameters.Set( PPPN_FILM_GRAIN_STRENGTH, inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Clear out the PostProcess controller. +//----------------------------------------------------------------------------- +void CPostProcessSystem::LevelInitPreEntity() +{ + m_hMasterController = nullptr; + ListenForGameEvent( "round_start" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Find the master controller. If no controller is +// set as Master, use the first controller found. +//----------------------------------------------------------------------------- +void CPostProcessSystem::InitMasterController() +{ + CPostProcessController *pPostProcessController = nullptr; + + do + { + pPostProcessController = dynamic_cast( gEntList.FindEntityByClassname( pPostProcessController, "postprocess_controller" ) ); + if ( pPostProcessController ) + { + if ( m_hMasterController.Get() == nullptr ) + { + m_hMasterController = pPostProcessController; + } + else + { + if ( pPostProcessController->IsMaster() ) + { + m_hMasterController = pPostProcessController; + } + } + } + } while ( pPostProcessController ); +} + +//----------------------------------------------------------------------------- +// Purpose: On a multiplayer map restart, re-find the master controller. +//----------------------------------------------------------------------------- +void CPostProcessSystem::FireGameEvent( IGameEvent *pEvent ) +{ + InitMasterController(); +} + +//----------------------------------------------------------------------------- +// Purpose: On level load find the master PostProcess controller. If no controller is +// set as Master, use the first PostProcess controller found. +//----------------------------------------------------------------------------- +void CPostProcessSystem::LevelInitPostEntity() +{ + InitMasterController(); + + // HACK: Singleplayer games don't get a call to CBasePlayer::Spawn on level transitions. + // CBasePlayer::Activate is called before this is called so that's too soon to set up the PostProcess controller. + // We don't have a hook similar to Activate that happens after LevelInitPostEntity + // is called, or we could just do this in the player itself. + if ( gpGlobals->maxClients == 1 ) + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer && ( pPlayer->m_hPostProcessCtrl.Get() == nullptr ) ) + { + pPlayer->InitPostProcessController(); + } + } +} diff --git a/game/server/postprocesscontroller.h b/game/server/postprocesscontroller.h new file mode 100644 index 00000000..5608394a --- /dev/null +++ b/game/server/postprocesscontroller.h @@ -0,0 +1,80 @@ +#pragma once + +#include "GameEventListener.h" +#include "postprocess_shared.h" + +// Spawn Flags +#define SF_POSTPROCESS_MASTER 0x0001 + +//============================================================================= +// Class Postprocess Controller: +//============================================================================= +class CPostProcessController : public CBaseEntity +{ +public: + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + DECLARE_CLASS( CPostProcessController, CBaseEntity ); + + CPostProcessController(); + virtual ~CPostProcessController(); + + virtual int UpdateTransmitState(); + + // Input handlers + void InputSetFadeTime(inputdata_t &data); + void InputSetLocalContrastStrength(inputdata_t &data); + void InputSetLocalContrastEdgeStrength(inputdata_t &data); + void InputSetVignetteStart(inputdata_t &data); + void InputSetVignetteEnd(inputdata_t &data); + void InputSetVignetteBlurStrength(inputdata_t &data); + void InputSetFadeToBlackStrength(inputdata_t &data); + void InputSetDepthBlurFocalDistance(inputdata_t &data); + void InputSetDepthBlurStrength(inputdata_t &data); + void InputSetScreenBlurStrength(inputdata_t &data); + void InputSetFilmGrainStrength(inputdata_t &data); + + void InputTurnOn(inputdata_t &data); + void InputTurnOff(inputdata_t &data); + + void Spawn(); + + bool IsMaster() const { return HasSpawnFlags( SF_FOG_MASTER ); } + +public: + CNetworkArray( float, m_flPostProcessParameters, POST_PROCESS_PARAMETER_COUNT ); + + CNetworkVar( bool, m_bMaster ); +}; + +//============================================================================= +// +// Postprocess Controller System. +// +class CPostProcessSystem : public CAutoGameSystem, public CGameEventListener +{ +public: + + // Creation/Init. + CPostProcessSystem( char const *name ) : CAutoGameSystem( name ) + { + m_hMasterController = nullptr; + } + + ~CPostProcessSystem() + { + m_hMasterController = nullptr; + } + + virtual void LevelInitPreEntity(); + virtual void LevelInitPostEntity(); + virtual void FireGameEvent( IGameEvent *pEvent ); + CPostProcessController *GetMasterPostProcessController() { return m_hMasterController; } + +private: + + void InitMasterController(); + CHandle< CPostProcessController > m_hMasterController; +}; + +CPostProcessSystem *PostProcessSystem(); diff --git a/game/server/projectile_bullet.cpp b/game/server/projectile_bullet.cpp index cb50a1e9..f0d22ba3 100644 --- a/game/server/projectile_bullet.cpp +++ b/game/server/projectile_bullet.cpp @@ -12,7 +12,7 @@ BEGIN_DATADESC(CProjectileBulletTrace) END_DATADESC() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CProjectileBulletTrace::Spawn(void) { @@ -33,7 +33,7 @@ void CProjectileBulletTrace::Spawn(void) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CProjectileBulletTrace* CProjectileBulletTrace::Create(const ProjectileBulletsInfo_t& info, Vector vecDir) { @@ -64,12 +64,12 @@ CProjectileBulletTrace* CProjectileBulletTrace::Create(const ProjectileBulletsIn // Purpose: //----------------------------------------------------------------------------- unsigned int CProjectileBulletTrace::PhysicsSolidMaskForEntity(void) const -{ +{ return MASK_BULLETSCANTOUCH; } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CProjectileBulletTrace::BulletTouch(CBaseEntity *pOther) { @@ -100,7 +100,7 @@ void CProjectileBulletTrace::BulletTouch(CBaseEntity *pOther) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CProjectileBulletTrace::Hit(trace_t *pTrace, CBaseEntity *pOther) { @@ -145,4 +145,4 @@ void CProjectileBulletTrace::Hit(trace_t *pTrace, CBaseEntity *pOther) pOther->DispatchTraceAttack(info, m_BulletsInfo.m_vecDirShooting, pTrace); UTIL_Remove(this); -} \ No newline at end of file +} diff --git a/game/server/projectile_bullet.h b/game/server/projectile_bullet.h index 1d038c99..1035e51d 100644 --- a/game/server/projectile_bullet.h +++ b/game/server/projectile_bullet.h @@ -31,4 +31,4 @@ class CProjectileBulletTrace : public CBaseEntity ProjectileBulletsInfo_t m_BulletsInfo; }; -#endif // PROJECTILE_BULLET_H \ No newline at end of file +#endif // PROJECTILE_BULLET_H diff --git a/game/server/props.cpp b/game/server/props.cpp index 4a8b2931..da632cea 100644 --- a/game/server/props.cpp +++ b/game/server/props.cpp @@ -41,6 +41,11 @@ #include "physics_collisionevent.h" #include "gamestats.h" #include "vehicle_base.h" +#ifdef MAPBASE +#include "mapbase/GlobalStrings.h" +#include "collisionutils.h" +#include "vstdlib/IKeyValuesSystem.h" // From Alien Swarm SDK +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -79,8 +84,17 @@ ConVar func_breakdmg_explosive( "func_breakdmg_explosive", "1.25" ); ConVar sv_turbophysics( "sv_turbophysics", "0", FCVAR_REPLICATED, "Turns on turbo physics" ); +#ifdef MAPBASE +ConVar mapbase_prop_consistency_noremove("mapbase_prop_consistency_noremove", "1", FCVAR_NONE, "Prevents the removal of props when their classes do not match up with their models' propdata."); +#endif + #ifdef HL2_EPISODIC +#ifdef MAPBASE + #define PROP_FLARE_LIFETIME GetFlareLifetime() + float GetEnvFlareLifetime( CBaseEntity *pEntity ); +#else #define PROP_FLARE_LIFETIME 30.0f +#endif #define PROP_FLARE_IGNITE_SUBSTRACT 5.0f CBaseEntity *CreateFlare( Vector vOrigin, QAngle Angles, CBaseEntity *pOwner, float flDuration ); void KillFlare( CBaseEntity *pOwnerEntity, CBaseEntity *pEntity, float flKillTime ); @@ -193,6 +207,35 @@ void CBaseProp::Spawn( void ) int iResult = ParsePropData(); if ( !OverridePropdata() ) { +#ifdef MAPBASE + if (mapbase_prop_consistency_noremove.GetBool()) + { + switch (iResult) + { + case PARSE_FAILED_BAD_DATA: + Warning("%s at %.0f %.0f %0.f uses model %s, which has an invalid prop_data type. Not deleted due to mapbase_prop_consistency_noremove.\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, szModel); + break; + case PARSE_FAILED_NO_DATA: + { + if ( FClassnameIs( this, "prop_physics" ) ) + { + Warning("%s at %.0f %.0f %0.f uses model %s, which has no propdata which means it should be used on a prop_static. Not deleted due to mapbase_prop_consistency_noremove.\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, szModel); + } + } break; + case PARSE_SUCCEEDED: + { + if (!IsPropPhysics()) + { + Warning( "%s at %.0f %.0f %0.f uses model %s, which has propdata which means that it should be used on a prop_physics. Not deleted due to mapbase_prop_consistency_noremove.\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, szModel ); + } + } + } + } + else + { + // No comment. + #define DevWarning Warning +#endif if ( iResult == PARSE_FAILED_BAD_DATA ) { DevWarning( "%s at %.0f %.0f %0.f uses model %s, which has an invalid prop_data type. DELETED.\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, szModel ); @@ -212,13 +255,21 @@ void CBaseProp::Spawn( void ) else if ( iResult == PARSE_SUCCEEDED ) { // If we have data, and we're not a physics prop, fail +#ifdef MAPBASE + if ( !IsPropPhysics() ) +#else if ( !dynamic_cast(this) ) +#endif { DevWarning( "%s at %.0f %.0f %0.f uses model %s, which has propdata which means that it be used on a prop_physics. DELETED.\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, szModel ); UTIL_Remove( this ); return; } } +#ifdef MAPBASE + #undef DevWarning + } +#endif } SetMoveType( MOVETYPE_PUSH ); @@ -275,7 +326,11 @@ bool CBaseProp::KeyValue( const char *szKeyName, const char *szValue ) if ( FStrEq(szKeyName, "health") ) { // Only override props are allowed to override health. +#ifdef MAPBASE + if ( OverridePropdata() && !FStrEq(szValue, "-1") ) +#else if ( FClassnameIs( this, "prop_physics_override" ) || FClassnameIs( this, "prop_dynamic_override" ) ) +#endif return BaseClass::KeyValue( szKeyName, szValue ); return true; @@ -333,8 +388,15 @@ int CBaseProp::ParsePropData( void ) return PARSE_FAILED_NO_DATA; } +#ifdef MAPBASE // From Alien Swarm SDK + static int keyPropData = KeyValuesSystem()->GetSymbolForString( "prop_data" ); + + // Do we have a props section? + KeyValues *pkvPropData = modelKeyValues->FindKey( keyPropData ); +#else // Do we have a props section? KeyValues *pkvPropData = modelKeyValues->FindKey("prop_data"); +#endif if ( !pkvPropData ) { modelKeyValues->deleteThis(); @@ -702,6 +764,41 @@ void CBreakableProp::HandleInteractionStick( int index, gamevcollisionevent_t *p } } +#ifdef MAPBASE +extern int g_interactionBarnacleVictimBite; +extern ConVar npc_barnacle_ignite; +//----------------------------------------------------------------------------- +// Purpose: Uses the new CBaseEntity interaction implementation +// Input : The type of interaction, extra info pointer, and who started it +// Output : true - if sub-class has a response for the interaction +// false - if sub-class has no response +//----------------------------------------------------------------------------- +bool CBreakableProp::HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) +{ +#ifdef HL2_EPISODIC + // Allows flares to ignite barnacles. + if ( interactionType == g_interactionBarnacleVictimBite ) + { + if ( npc_barnacle_ignite.GetBool() && sourceEnt->IsOnFire() == false ) + { + sourceEnt->Ignite( 25.0f ); + KillFlare( this, m_hFlareEnt, PROP_FLARE_IGNITE_SUBSTRACT ); + IGameEvent *event = gameeventmanager->CreateEvent( "flare_ignite_npc" ); + if ( event ) + { + event->SetInt( "entindex", sourceEnt->entindex() ); + gameeventmanager->FireEvent( event ); + } + } + + return true; + } +#endif + + return BaseClass::HandleInteraction(interactionType, data, sourceEnt); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Turn on prop debugging mode //----------------------------------------------------------------------------- @@ -759,6 +856,9 @@ BEGIN_DATADESC( CBreakableProp ) DEFINE_KEYFIELD( m_flPressureDelay, FIELD_FLOAT, "PressureDelay" ), DEFINE_FIELD( m_preferredCarryAngles, FIELD_VECTOR ), +#ifdef MAPBASE + DEFINE_FIELD( m_bUsesCustomCarryAngles, FIELD_BOOLEAN ), +#endif DEFINE_FIELD( m_flDefaultFadeScale, FIELD_FLOAT ), DEFINE_FIELD( m_bUsePuntSound, FIELD_BOOLEAN ), // DEFINE_FIELD( m_mpBreakMode, mp_break_t ), @@ -768,6 +868,10 @@ BEGIN_DATADESC( CBreakableProp ) DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ), DEFINE_INPUTFUNC( FIELD_INTEGER, "AddHealth", InputAddHealth ), DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveHealth", InputRemoveHealth ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetInteraction", InputSetInteraction ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveInteraction", InputRemoveInteraction ), +#endif DEFINE_INPUT( m_impactEnergyScale, FIELD_FLOAT, "physdamagescale" ), DEFINE_INPUTFUNC( FIELD_VOID, "EnablePhyscannonPickup", InputEnablePhyscannonPickup ), DEFINE_INPUTFUNC( FIELD_VOID, "DisablePhyscannonPickup", InputDisablePhyscannonPickup ), @@ -899,6 +1003,9 @@ void CBreakableProp::Spawn() m_impactEnergyScale = 0.1f; } +#ifdef MAPBASE + if (!m_bUsesCustomCarryAngles) +#endif m_preferredCarryAngles = QAngle( -5, 0, 0 ); // The presence of this activity causes us to have to detach it before it can be grabbed. @@ -922,6 +1029,57 @@ void CBreakableProp::Spawn() SetTouch( &CBreakableProp::BreakablePropTouch ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Handles keyvalues from the BSP. Called before spawning. +//----------------------------------------------------------------------------- +bool CBreakableProp::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( OverridePropdata() ) + { + if ( FStrEq(szKeyName, "InitialInteractions") ) + { + // Only override props are allowed to override interactions. + if (strchr(szValue, ' ')) + { + // How many interactions could there possibly be? + char szInteractions[64]; + Q_strncpy(szInteractions, szValue, sizeof(szInteractions)); + + char *token = strtok(szInteractions, " ,"); + while (token) + { + SetInteraction((propdata_interactions_t)atoi(token)); + token = strtok(token, " ,"); + } + } + else + SetInteraction((propdata_interactions_t)atoi(szValue)); + } + else if ( FStrEq(szKeyName, "preferredcarryangles") ) + { + // Only detect as custom if it's non-zero + if (!FStrEq( szValue, "0" )) + { + QAngle angCarryAngles; + UTIL_StringToVector( angCarryAngles.Base(), szValue ); + + m_preferredCarryAngles = angCarryAngles; + m_bUsesCustomCarryAngles = true; + } + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + } + else + { + return BaseClass::KeyValue( szKeyName, szValue ); + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Disable auto fading under dx7 or when level fades are specified @@ -1050,6 +1208,17 @@ int CBreakableProp::OnTakeDamage( const CTakeDamageInfo &inputInfo ) { m_hLastAttacker.Set( info.GetAttacker() ); } +#ifdef MAPBASE // From Alien Swarm SDK + else if ( info.GetAttacker() ) + { + CBaseEntity *attacker = info.GetAttacker(); + CBaseEntity *attackerOwner = attacker->GetOwnerEntity(); + if ( attackerOwner && attackerOwner->MyCombatCharacterPointer() ) + { + m_hLastAttacker.Set( attackerOwner ); + } + } +#endif float flPropDamage = GetBreakableDamage( info, assert_cast(this) ); info.SetDamage( flPropDamage ); @@ -1218,6 +1387,25 @@ void CBreakableProp::InputSetHealth( inputdata_t &inputdata ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler for setting interactions. +//----------------------------------------------------------------------------- +void CBreakableProp::InputSetInteraction( inputdata_t &inputdata ) +{ + SetInteraction( (propdata_interactions_t)inputdata.value.Int() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler for Adding interactions. +//----------------------------------------------------------------------------- +void CBreakableProp::InputRemoveInteraction( inputdata_t &inputdata ) +{ + RemoveInteraction( (propdata_interactions_t)inputdata.value.Int() ); +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Choke point for changes to breakable health. Ensures outputs are fired. // Input : iNewHealth - @@ -1485,7 +1673,12 @@ void CBreakableProp::CreateFlare( float flLifetime ) int iAttachment = LookupAttachment( "fuse" ); Vector vOrigin; +#ifdef MAPBASE + if (!GetAttachment( iAttachment, vOrigin )) + vOrigin = GetLocalOrigin(); +#else GetAttachment( iAttachment, vOrigin ); +#endif pFlare->SetMoveType( MOVETYPE_NONE ); pFlare->SetSolid( SOLID_NONE ); @@ -1811,8 +2004,6 @@ LINK_ENTITY_TO_CLASS( dynamic_prop, CDynamicProp ); LINK_ENTITY_TO_CLASS( prop_dynamic, CDynamicProp ); LINK_ENTITY_TO_CLASS( prop_dynamic_override, CDynamicProp ); -IMPLEMENT_AUTO_LIST( IPhysicsPropAutoList ); - BEGIN_DATADESC( CDynamicProp ) // Fields @@ -1827,9 +2018,16 @@ BEGIN_DATADESC( CDynamicProp ) DEFINE_KEYFIELD( m_bDisableBoneFollowers, FIELD_BOOLEAN, "DisableBoneFollowers" ), DEFINE_FIELD( m_bUseHitboxesForRenderBox, FIELD_BOOLEAN ), DEFINE_FIELD( m_nPendingSequence, FIELD_SHORT ), +#ifdef MAPBASE // From Alien Swarm SDK + DEFINE_KEYFIELD( m_bUpdateAttachedChildren, FIELD_BOOLEAN, "updatechildren" ), + DEFINE_KEYFIELD( m_bHoldAnimation, FIELD_BOOLEAN, "HoldAnimation" ), +#endif // Inputs DEFINE_INPUTFUNC( FIELD_STRING, "SetAnimation", InputSetAnimation ), +#ifdef MAPBASE // From Alien Swarm SDK + DEFINE_INPUTFUNC( FIELD_STRING, "SetAnimationNoReset", InputSetAnimationNoReset ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetDefaultAnimation", InputSetDefaultAnimation ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), @@ -2054,9 +2252,8 @@ void CDynamicProp::CreateBoneFollowers() pBone = pBone->GetNextKey(); } } - - modelKeyValues->deleteThis(); } + modelKeyValues->deleteThis(); // if we got here, we don't have a bone follower section, but if we have a ragdoll // go ahead and create default bone followers for it @@ -2194,10 +2391,23 @@ void CDynamicProp::AnimThink( void ) } else { +#ifdef MAPBASE // From Alien Swarm SDK + if ( m_iszDefaultAnim != NULL_STRING && m_bHoldAnimation == false ) + { + PropSetAnim( STRING( m_iszDefaultAnim ) ); + } + + // We need to wait for an animation change to come in + if ( m_bHoldAnimation ) + { + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#else if (m_iszDefaultAnim != NULL_STRING) { PropSetAnim( STRING( m_iszDefaultAnim ) ); } +#endif } } } @@ -2209,6 +2419,17 @@ void CDynamicProp::AnimThink( void ) StudioFrameAdvance(); DispatchAnimEvents(this); m_BoneFollowerManager.UpdateBoneFollowers(this); + +#ifdef MAPBASE // From Alien Swarm SDK + // Update any SetParentAttached children + if ( m_bUpdateAttachedChildren ) + { + for ( CBaseEntity *pChild = FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() ) + { + pChild->PhysicsTouchTriggers(); + } + } +#endif } @@ -2247,6 +2468,19 @@ void CDynamicProp::InputSetAnimation( inputdata_t &inputdata ) PropSetAnim( inputdata.value.String() ); } +#ifdef MAPBASE // From Alien Swarm SDK +//------------------------------------------------------------------------------ +// Purpose: Set the animation unless the prop is already set to this particular animation +//------------------------------------------------------------------------------ +void CDynamicProp::InputSetAnimationNoReset( inputdata_t &inputdata ) +{ + if ( GetSequence() != LookupSequence( inputdata.value.String() ) ) + { + PropSetAnim( inputdata.value.String() ); + } +} +#endif + //------------------------------------------------------------------------------ // Purpose: //------------------------------------------------------------------------------ @@ -2387,21 +2621,373 @@ void COrnamentProp::InputSetAttached( inputdata_t &inputdata ) AttachTo( inputdata.value.String(), inputdata.pActivator, inputdata.pCaller ); } -void COrnamentProp::AttachTo( const char *pAttachName, CBaseEntity *pActivator, CBaseEntity *pCaller ) -{ - // find and notify the new parent - CBaseEntity *pAttach = gEntList.FindEntityByName( NULL, pAttachName, NULL, pActivator, pCaller ); - if ( pAttach ) - { - RemoveEffects( EF_NODRAW ); - FollowEntity( pAttach ); - } -} +void COrnamentProp::AttachTo( const char *pAttachName, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + // find and notify the new parent + CBaseEntity *pAttach = gEntList.FindEntityByName( NULL, pAttachName, NULL, pActivator, pCaller ); + if ( pAttach ) + { + RemoveEffects( EF_NODRAW ); + FollowEntity( pAttach ); + } +} + +void COrnamentProp::InputDetach( inputdata_t &inputdata ) +{ + DetachFromOwner(); +} + +#ifdef MAPBASE +#define SF_INTERACTABLE_USE_INTERACTS 512 // Allows +USE interaction. +#define SF_INTERACTABLE_TOUCH_INTERACTS 1024 // Allows touch interaction. +#define SF_INTERACTABLE_IGNORE_COMMANDS_WHEN_LOCKED 2048 // Completely ignores player commands when locked. +#define SF_INTERACTABLE_RADIUS_USE 4096 // Uses radius +USE + +//----------------------------------------------------------------------------- +// Purpose: Button prop for +USEable dynamic props +//----------------------------------------------------------------------------- +class CInteractableProp : public CDynamicProp +{ + DECLARE_CLASS( CInteractableProp, CDynamicProp ); +public: + DECLARE_DATADESC(); + + void Spawn(); + void Precache(); + //void Activate(); + + int ObjectCaps() + { + int caps = BaseClass::ObjectCaps(); + + if (HasSpawnFlags(SF_INTERACTABLE_USE_INTERACTS) && (!HasSpawnFlags( SF_INTERACTABLE_IGNORE_COMMANDS_WHEN_LOCKED ) || !m_bLocked)) + { + caps |= FCAP_IMPULSE_USE; + + if (HasSpawnFlags(SF_INTERACTABLE_RADIUS_USE)) + caps |= FCAP_USE_IN_RADIUS; + } + + return caps; + }; + + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void InteractablePropTouch( CBaseEntity *pOther ); + + void SetPushSequence(int iSequence); + void PushThink(); + + // Input handlers + void InputLock( inputdata_t &inputdata ); + void InputUnlock( inputdata_t &inputdata ); + void InputPress( inputdata_t &inputdata ); + + void InputEnableUseInteraction( inputdata_t &inputdata ) { AddSpawnFlags(SF_INTERACTABLE_USE_INTERACTS); } + void InputDisableUseInteraction( inputdata_t &inputdata ) { RemoveSpawnFlags(SF_INTERACTABLE_USE_INTERACTS); } + void InputEnableTouchInteraction( inputdata_t &inputdata ) { AddSpawnFlags( SF_INTERACTABLE_TOUCH_INTERACTS ); } + void InputDisableTouchInteraction( inputdata_t &inputdata ) { RemoveSpawnFlags( SF_INTERACTABLE_TOUCH_INTERACTS ); } + void InputStartIgnoringCommandsWhenLocked( inputdata_t &inputdata ) { AddSpawnFlags( SF_INTERACTABLE_IGNORE_COMMANDS_WHEN_LOCKED ); } + void InputStopIgnoringCommandsWhenLocked( inputdata_t &inputdata ) { RemoveSpawnFlags( SF_INTERACTABLE_IGNORE_COMMANDS_WHEN_LOCKED ); } + void InputEnableRadiusInteract( inputdata_t &inputdata ) { AddSpawnFlags( SF_INTERACTABLE_RADIUS_USE ); } + void InputDisableRadiusInteract( inputdata_t &inputdata ) { RemoveSpawnFlags( SF_INTERACTABLE_RADIUS_USE ); } + + COutputEvent m_OnPressed; + COutputEvent m_OnLockedUse; + COutputEvent m_OnIn; + COutputEvent m_OnOut; + + bool m_bLocked; + + float m_flCooldown; + +private: + float m_flCooldownTime; + + int m_iCurSequence = INTERACTSEQ_NONE; // Currently in a sequence + enum + { + INTERACTSEQ_NONE = -1, + INTERACTSEQ_IN, + INTERACTSEQ_OUT, + INTERACTSEQ_LOCKED, + }; + + string_t m_iszPressedSound; + string_t m_iszLockedSound; + + string_t m_iszInSequence; + string_t m_iszOutSequence; + string_t m_iszLockedSequence; + + Vector m_vecUseMins; + Vector m_vecUseMaxs; +}; + +LINK_ENTITY_TO_CLASS( prop_interactable, CInteractableProp ); + +BEGIN_DATADESC( CInteractableProp ) + + DEFINE_KEYFIELD( m_bLocked, FIELD_BOOLEAN, "Locked" ), + DEFINE_INPUT( m_flCooldown, FIELD_FLOAT, "SetCooldown" ), + DEFINE_FIELD( m_flCooldownTime, FIELD_TIME ), + DEFINE_FIELD( m_iCurSequence, FIELD_INTEGER ), + + DEFINE_KEYFIELD( m_iszPressedSound, FIELD_STRING, "PressedSound" ), + DEFINE_KEYFIELD( m_iszLockedSound, FIELD_STRING, "LockedSound" ), + DEFINE_KEYFIELD( m_iszInSequence, FIELD_STRING, "InSequence" ), + DEFINE_KEYFIELD( m_iszOutSequence, FIELD_STRING, "OutSequence" ), + DEFINE_KEYFIELD( m_iszLockedSequence, FIELD_STRING, "LockedSequence" ), + + DEFINE_KEYFIELD( m_vecUseMins, FIELD_VECTOR, "use_mins" ), + DEFINE_KEYFIELD( m_vecUseMaxs, FIELD_VECTOR, "use_maxs" ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "Lock", InputLock ), + DEFINE_INPUTFUNC( FIELD_VOID, "Unlock", InputUnlock ), + DEFINE_INPUTFUNC( FIELD_VOID, "Press", InputPress ), + + DEFINE_INPUTFUNC( FIELD_VOID, "EnableUseInteraction", InputEnableUseInteraction ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableUseInteraction", InputDisableUseInteraction ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableTouchInteraction", InputEnableTouchInteraction ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableTouchInteraction", InputDisableTouchInteraction ), + DEFINE_INPUTFUNC( FIELD_VOID, "StartIgnoringCommandsWhenLocked", InputStartIgnoringCommandsWhenLocked ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopIgnoringCommandsWhenLocked", InputStopIgnoringCommandsWhenLocked ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableRadiusInteract", InputEnableRadiusInteract ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableRadiusInteract", InputDisableRadiusInteract ), + + // Outputs + DEFINE_OUTPUT( m_OnPressed, "OnPressed" ), + DEFINE_OUTPUT( m_OnLockedUse, "OnLockedUse" ), + DEFINE_OUTPUT( m_OnIn, "OnIn" ), + DEFINE_OUTPUT( m_OnOut, "OnOut" ), + + DEFINE_THINKFUNC( PushThink ), + DEFINE_ENTITYFUNC( InteractablePropTouch ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::Spawn( void ) +{ + BaseClass::Spawn(); + + SetTouch( &CInteractableProp::InteractablePropTouch ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::Precache( void ) +{ + BaseClass::Precache(); + + if (m_iszPressedSound != NULL_STRING) + PrecacheScriptSound( STRING(m_iszPressedSound) ); + if (m_iszLockedSound != NULL_STRING) + PrecacheScriptSound( STRING(m_iszLockedSound) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pActivator - +// *pCaller - +// useType - +// value - +//----------------------------------------------------------------------------- +void CInteractableProp::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) +{ + if (m_flCooldownTime > gpGlobals->curtime) + return; + + // If we're using +USE mins/maxs, make sure this is being +USE'd from the right place + if (m_vecUseMins.LengthSqr() != 0.0f && m_vecUseMaxs.LengthSqr() != 0.0f) + { + CBasePlayer *pPlayer = ToBasePlayer(pActivator); + if (pPlayer) + { + Vector forward; + pPlayer->EyeVectors(&forward, NULL, NULL); + + // This might be a little convoluted and/or seem needlessly expensive, but I couldn't figure out any better way to do this. + // TOOD: Can we calculate a box in local space instead of world space? + Vector vecWorldMins, vecWorldMaxs; + RotateAABB(EntityToWorldTransform(), m_vecUseMins, m_vecUseMaxs, vecWorldMins, vecWorldMaxs); + TransformAABB(EntityToWorldTransform(), vecWorldMins, vecWorldMaxs, vecWorldMins, vecWorldMaxs); + if (!IsBoxIntersectingRay(vecWorldMins, vecWorldMaxs, pPlayer->EyePosition(), forward * 1024)) + { + // Reject this +USE if it's not in our box + DevMsg("Outside of +USE box\n"); + return; + } + } + } + + int nSequence = -1; + + if (m_bLocked) + { + m_OnLockedUse.FireOutput(pActivator, this); + EmitSound(STRING(m_iszLockedSound)); + nSequence = LookupSequence(STRING(m_iszLockedSequence)); + m_iCurSequence = INTERACTSEQ_LOCKED; + } + else + { + m_OnPressed.FireOutput(pActivator, this); + EmitSound(STRING(m_iszPressedSound)); + nSequence = LookupSequence(STRING(m_iszInSequence)); + m_iCurSequence = INTERACTSEQ_IN; + } + + if (nSequence > ACTIVITY_NOT_AVAILABLE) + { + SetPushSequence(nSequence); + + // We still fire our inherited animation outputs + m_pOutputAnimBegun.FireOutput(pActivator, this); + } + + if (m_flCooldown == -1 && !m_bLocked){ + m_flCooldownTime = FLT_MAX; // yeah we're not going to hit this any time soon + } + else if (m_flCooldown == -1){ + m_flCooldownTime = gpGlobals->curtime + 1.0f; // 1s cooldown if locked + } + else{ + m_flCooldownTime = gpGlobals->curtime + m_flCooldown; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pOther - +//----------------------------------------------------------------------------- +void CInteractableProp::InteractablePropTouch( CBaseEntity *pOther ) +{ + // Do base touch function first + BreakablePropTouch( pOther ); + + if ( HasSpawnFlags(SF_INTERACTABLE_TOUCH_INTERACTS) && (!HasSpawnFlags(SF_INTERACTABLE_IGNORE_COMMANDS_WHEN_LOCKED) || !m_bLocked) && pOther->IsPlayer() ) + { + Use( pOther, pOther, USE_ON, 0 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::InputLock( inputdata_t &inputdata ) +{ + m_bLocked = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::InputUnlock( inputdata_t &inputdata ) +{ + m_bLocked = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::InputPress( inputdata_t &inputdata ) +{ + Use( inputdata.pActivator, inputdata.pCaller, USE_ON, 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::SetPushSequence( int iSequence ) +{ + m_iGoalSequence = iSequence; + + int nNextSequence; + float nextCycle; + float flInterval = 0.1f; + + if (GotoSequence( GetSequence(), GetCycle(), GetPlaybackRate(), m_iGoalSequence, nNextSequence, nextCycle, m_iTransitionDirection )) + { + FinishSetSequence( nNextSequence ); + } + + SetThink( &CInteractableProp::PushThink ); + if ( GetNextThink() <= gpGlobals->curtime ) + SetNextThink( gpGlobals->curtime + flInterval ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CInteractableProp::PushThink() +{ + if ( m_nPendingSequence != -1 ) + { + FinishSetSequence( m_nPendingSequence ); + m_nPendingSequence = -1; + } + + SetNextThink( gpGlobals->curtime + 0.1f ); + + if ( ((m_iTransitionDirection > 0 && GetCycle() >= 0.999f) || (m_iTransitionDirection < 0 && GetCycle() <= 0.0f)) && !SequenceLoops() ) + { + if (!SequenceLoops()) + { + // We still fire our inherited animation outputs + m_pOutputAnimOver.FireOutput(NULL, this); + } + + if (m_iCurSequence == INTERACTSEQ_OUT) + { + m_OnOut.FireOutput( NULL, this ); + + m_iCurSequence = INTERACTSEQ_NONE; + } + else + { + m_OnIn.FireOutput( NULL, this ); + } + } + + StudioFrameAdvance(); + DispatchAnimEvents(this); + m_BoneFollowerManager.UpdateBoneFollowers(this); + + if (m_flCooldownTime < gpGlobals->curtime) + { + if (m_iCurSequence == INTERACTSEQ_IN) + { + int nSequence = LookupSequence( STRING(m_iszOutSequence) ); + if ( m_iszOutSequence != NULL_STRING && nSequence > ACTIVITY_NOT_AVAILABLE ) + { + m_iCurSequence = INTERACTSEQ_OUT; + SetPushSequence(nSequence); + + // We still fire our inherited animation outputs + m_pOutputAnimBegun.FireOutput( NULL, this ); + } + else + { + m_iCurSequence = INTERACTSEQ_NONE; + } + } + + if (m_iCurSequence == INTERACTSEQ_NONE) + { + if (m_iszDefaultAnim != NULL_STRING) + { + PropSetAnim( STRING( m_iszDefaultAnim ) ); + } -void COrnamentProp::InputDetach( inputdata_t &inputdata ) -{ - DetachFromOwner(); + SetNextThink( TICK_NEVER_THINK ); + } + } } +#endif //============================================================================= @@ -2418,6 +3004,9 @@ BEGIN_DATADESC( CPhysicsProp ) DEFINE_INPUTFUNC( FIELD_VOID, "Wake", InputWake ), DEFINE_INPUTFUNC( FIELD_VOID, "Sleep", InputSleep ), DEFINE_INPUTFUNC( FIELD_VOID, "DisableFloating", InputDisableFloating ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetDebris", InputSetDebris ), +#endif DEFINE_FIELD( m_bAwake, FIELD_BOOLEAN ), @@ -2482,10 +3071,15 @@ void CPhysicsProp::Spawn( ) { g_ActiveGibCount++; } + // Condense classname's to one, except for "prop_physics_override" if ( FClassnameIs( this, "physics_prop" ) ) { +#ifdef MAPBASE + m_iClassname = gm_isz_class_PropPhysics; +#else SetClassname( "prop_physics" ); +#endif } BaseClass::Spawn(); @@ -2494,10 +3088,17 @@ void CPhysicsProp::Spawn( ) return; // Now condense all classnames to one +#ifdef MAPBASE + if ( EntIsClass( this, gm_isz_class_PropPhysicsOverride ) ) + { + m_iClassname = gm_isz_class_PropPhysics; + } +#else if ( FClassnameIs( this, "prop_physics_override") ) { SetClassname( "prop_physics" ); } +#endif if ( HasSpawnFlags( SF_PHYSPROP_DEBRIS ) || HasInteraction( PROPINTER_PHYSGUN_CREATE_FLARE ) ) { @@ -2647,7 +3248,11 @@ bool CPhysicsProp::CanBePickedUpByPhyscannon( void ) //----------------------------------------------------------------------------- bool CPhysicsProp::OverridePropdata( void ) { +#ifdef MAPBASE + return EntIsClass(this, gm_isz_class_PropPhysicsOverride); +#else return ( FClassnameIs(this, "prop_physics_override" ) ); +#endif } //----------------------------------------------------------------------------- @@ -2700,6 +3305,25 @@ void CPhysicsProp::InputDisableFloating( inputdata_t &inputdata ) PhysEnableFloating( VPhysicsGetObject(), false ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Adds or removes the debris spawnflag. +//----------------------------------------------------------------------------- +void CPhysicsProp::InputSetDebris( inputdata_t &inputdata ) +{ + if (inputdata.value.Bool()) + { + AddSpawnFlags(SF_PHYSPROP_DEBRIS); + SetCollisionGroup(HasSpawnFlags(SF_PHYSPROP_FORCE_TOUCH_TRIGGERS) ? COLLISION_GROUP_DEBRIS_TRIGGER : COLLISION_GROUP_DEBRIS); + } + else + { + RemoveSpawnFlags(SF_PHYSPROP_DEBRIS); + SetCollisionGroup(COLLISION_GROUP_INTERACTIVE); // Is this the default collision group? + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -3519,6 +4143,11 @@ enum void PlayLockSounds(CBaseEntity *pEdict, locksound_t *pls, int flocked, int fbutton); +#ifdef MAPBASE +ConVar ai_door_enable_acts( "ai_door_enable_acts", "0", FCVAR_NONE, "Enables the new door-opening activities by default. Override keyvalues will override this cvar." ); +ConVar ai_door_open_dist_override( "ai_door_open_dist_override", "-1", FCVAR_NONE, "Overrides the distance from a door a NPC has to navigate to in order to open a door." ); +#endif + BEGIN_DATADESC_NO_BASE(locksound_t) DEFINE_FIELD( sLockedSound, FIELD_STRING), @@ -3545,6 +4174,11 @@ BEGIN_DATADESC(CBasePropDoor) DEFINE_KEYFIELD(m_SoundClose, FIELD_SOUNDNAME, "soundcloseoverride"), DEFINE_KEYFIELD(m_ls.sLockedSound, FIELD_SOUNDNAME, "soundlockedoverride"), DEFINE_KEYFIELD(m_ls.sUnlockedSound, FIELD_SOUNDNAME, "soundunlockedoverride"), +#ifdef MAPBASE + DEFINE_KEYFIELD(m_flNPCOpenDistance, FIELD_FLOAT, "opendistoverride"), + DEFINE_KEYFIELD(m_eNPCOpenFrontActivity, FIELD_INTEGER, "openfrontactivityoverride"), + DEFINE_KEYFIELD(m_eNPCOpenBackActivity, FIELD_INTEGER, "openbackactivityoverride"), +#endif DEFINE_KEYFIELD(m_SlaveName, FIELD_STRING, "slavename" ), DEFINE_FIELD(m_bLocked, FIELD_BOOLEAN), //DEFINE_KEYFIELD(m_flBlockDamage, FIELD_FLOAT, "dmg"), @@ -3561,6 +4195,10 @@ BEGIN_DATADESC(CBasePropDoor) DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle), DEFINE_INPUTFUNC(FIELD_VOID, "Lock", InputLock), DEFINE_INPUTFUNC(FIELD_VOID, "Unlock", InputUnlock), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_VOID, "AllowPlayerUse", InputAllowPlayerUse), + DEFINE_INPUTFUNC(FIELD_VOID, "DisallowPlayerUse", InputDisallowPlayerUse), +#endif DEFINE_OUTPUT(m_OnBlockedOpening, "OnBlockedOpening"), DEFINE_OUTPUT(m_OnBlockedClosing, "OnBlockedClosing"), @@ -3577,10 +4215,6 @@ BEGIN_DATADESC(CBasePropDoor) DEFINE_THINKFUNC(DoorOpenMoveDone), DEFINE_THINKFUNC(DoorCloseMoveDone), DEFINE_THINKFUNC(DoorAutoCloseThink), - -#ifdef VANCE - DEFINE_KEYFIELD(m_bCanBeKickedOpen, FIELD_BOOLEAN, "canbekickedopen"), -#endif END_DATADESC() IMPLEMENT_SERVERCLASS_ST(CBasePropDoor, DT_BasePropDoor) @@ -3589,6 +4223,11 @@ END_SEND_TABLE() CBasePropDoor::CBasePropDoor( void ) { m_hMaster = NULL; +#ifdef MAPBASE + m_flNPCOpenDistance = -1; + m_eNPCOpenFrontActivity = ACT_INVALID; + m_eNPCOpenBackActivity = ACT_INVALID; +#endif } //----------------------------------------------------------------------------- @@ -3660,6 +4299,32 @@ void CBasePropDoor::Precache(void) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Handles keyvalues from the BSP. Called before spawning. +//----------------------------------------------------------------------------- +bool CBasePropDoor::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq(szKeyName, "openfrontactivityoverride") ) + { + m_eNPCOpenFrontActivity = (Activity)CAI_BaseNPC::GetActivityID( szValue ); + if (m_eNPCOpenFrontActivity == ACT_INVALID) + m_eNPCOpenFrontActivity = ActivityList_RegisterPrivateActivity( szValue ); + } + else if ( FStrEq(szKeyName, "openbackactivityoverride") ) + { + m_eNPCOpenBackActivity = (Activity)CAI_BaseNPC::GetActivityID( szValue ); + if (m_eNPCOpenBackActivity == ACT_INVALID) + m_eNPCOpenBackActivity = ActivityList_RegisterPrivateActivity( szValue ); + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -3786,8 +4451,44 @@ void CBasePropDoor::CalcDoorSounds() { strSoundLocked = AllocPooledString( pkvHardwareData->GetString( "locked" ) ); strSoundUnlocked = AllocPooledString( pkvHardwareData->GetString( "unlocked" ) ); + +#ifdef MAPBASE + if (ai_door_enable_acts.GetBool()) + { + if (m_eNPCOpenFrontActivity == ACT_INVALID) + { + const char *pszActivity = pkvHardwareData->GetString( "activity_front" ); + if (pszActivity[0] != '\0') + { + m_eNPCOpenFrontActivity = (Activity)CAI_BaseNPC::GetActivityID( pszActivity ); + if (m_eNPCOpenFrontActivity == ACT_INVALID) + m_eNPCOpenFrontActivity = ActivityList_RegisterPrivateActivity( pszActivity ); + } + } + if (m_eNPCOpenBackActivity == ACT_INVALID) + { + const char *pszActivity = pkvHardwareData->GetString( "activity_back" ); + if (pszActivity[0] != '\0') + { + m_eNPCOpenBackActivity = (Activity)CAI_BaseNPC::GetActivityID( pszActivity ); + if (m_eNPCOpenBackActivity == ACT_INVALID) + m_eNPCOpenBackActivity = ActivityList_RegisterPrivateActivity( pszActivity ); + } + } + } + + if (m_flNPCOpenDistance == -1) + m_flNPCOpenDistance = pkvHardwareData->GetFloat( "npc_distance", ai_door_enable_acts.GetBool() ? 32.0 : 64.0 ); +#endif } +#ifdef MAPBASE + // This would still be -1 if the hardware wasn't valid + if (m_flNPCOpenDistance == -1) + m_flNPCOpenDistance = ai_door_enable_acts.GetBool() ? 32.0 : 64.0; +#endif + + // If any sounds were missing, try the "defaults" block. if ( ( strSoundOpen == NULL_STRING ) || ( strSoundClose == NULL_STRING ) || ( strSoundMoving == NULL_STRING ) || ( strSoundLocked == NULL_STRING ) || ( strSoundUnlocked == NULL_STRING ) ) @@ -3847,7 +4548,12 @@ void CBasePropDoor::UpdateAreaPortals(bool isOpen) return; CBaseEntity *pPortal = NULL; +#ifdef MAPBASE + // For func_areaportal_oneway. + while ((pPortal = gEntList.FindEntityByClassname(pPortal, "func_areaportal*")) != NULL) +#else while ((pPortal = gEntList.FindEntityByClassname(pPortal, "func_areaportal")) != NULL) +#endif { if (pPortal->HasTarget(name)) { @@ -4040,6 +4746,25 @@ void CBasePropDoor::InputUnlock(inputdata_t &inputdata) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Input handler that makes the door usable for players. +//----------------------------------------------------------------------------- +void CBasePropDoor::InputAllowPlayerUse(inputdata_t &inputdata) +{ + RemoveSpawnFlags(SF_DOOR_IGNORE_USE); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that makes the door unusable for players. +//----------------------------------------------------------------------------- +void CBasePropDoor::InputDisallowPlayerUse(inputdata_t &inputdata) +{ + AddSpawnFlags(SF_DOOR_IGNORE_USE); +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Locks the door so that it cannot be opened. //----------------------------------------------------------------------------- @@ -4628,6 +5353,12 @@ class CTraceFilterDoor : public CTraceFilterEntitiesOnly if ( pPhysics->IsMoveable() && pPhysics->GetMass() < 32 ) return false; } + +#ifdef MAPBASE + // They're children, for goodness sake! + if (pEntity->GetParent() == EntityFromEntityHandle(m_pDoor)) + return false; +#endif } return true; @@ -4650,6 +5381,11 @@ inline void TraceHull_Door( const CBasePropDoor *pDoor, const Vector &vecAbsStar enginetrace->TraceRay( ray, mask, &traceFilter, ptr ); } +#ifdef MAPBASE +// This was still broken when it was scrapped. +//#define DOOR_BREAKING_STUFF 1 +#endif + // Check directions for door movement enum doorCheck_e { @@ -4674,6 +5410,15 @@ enum PropDoorRotatingOpenDirection_e DOOR_ROTATING_OPEN_BACKWARD, }; +#ifdef DOOR_BREAKING_STUFF +enum PropDoorRotatingBreakType_e +{ + DOOR_ROTATING_BREAK_NORMAL = 0, // Base behavior. + DOOR_ROTATING_BREAK_PHYS, // Turn into a physics prop via phys_conversion. + DOOR_ROTATING_BREAK_PHYS_HINGE, // Same as above, but use a phys_hinge. +}; +#endif + //=============================================== // Rotating prop door //=============================================== @@ -4714,6 +5459,15 @@ class CPropDoorRotating : public CBasePropDoor void InputSetSpeed(inputdata_t &inputdata); +#ifdef DOOR_BREAKING_STUFF + void Break( CBaseEntity *pBreaker, const CTakeDamageInfo &info ); +#endif + +#ifdef MAPBASE + // Filters don't work well with the way doors are considered obstructions, so it's just a spawnflag that stops all NPCs for now. + virtual bool PassesDoorFilter(CBaseEntity *pEntity) { return !HasSpawnFlags(SF_DOOR_NONPCS); } +#endif + DECLARE_DATADESC(); private: @@ -4736,6 +5490,9 @@ class CPropDoorRotating : public CBasePropDoor PropDoorRotatingSpawnPos_t m_eSpawnPosition; PropDoorRotatingOpenDirection_e m_eOpenDirection; +#ifdef DOOR_BREAKING_STUFF + PropDoorRotatingBreakType_e m_eBreakType; +#endif QAngle m_angRotationAjar; // Angles to spawn at if we are set to spawn ajar. QAngle m_angRotationClosed; // Our angles when we are fully closed. @@ -4756,6 +5513,9 @@ class CPropDoorRotating : public CBasePropDoor BEGIN_DATADESC(CPropDoorRotating) DEFINE_KEYFIELD(m_eSpawnPosition, FIELD_INTEGER, "spawnpos"), DEFINE_KEYFIELD(m_eOpenDirection, FIELD_INTEGER, "opendir" ), +#ifdef DOOR_BREAKING_STUFF + DEFINE_KEYFIELD(m_eBreakType, FIELD_INTEGER, "breaktype" ), +#endif DEFINE_KEYFIELD(m_vecAxis, FIELD_VECTOR, "axis"), DEFINE_KEYFIELD(m_flDistance, FIELD_FLOAT, "distance"), DEFINE_KEYFIELD( m_angRotationAjar, FIELD_VECTOR, "ajarangles" ), @@ -5283,12 +6043,7 @@ void CPropDoorRotating::BeginOpening(CBaseEntity *pOpenAwayFrom) } } -#ifdef VANCE - AngularMove(angOpen, m_bKickedOpen ? m_flSpeed * 3.0f : m_flSpeed); - m_bKickedOpen = false; -#else AngularMove(angOpen, m_flSpeed); -#endif } @@ -5310,12 +6065,8 @@ void CPropDoorRotating::BeginClosing( void ) NDebugOverlay::Box( GetAbsOrigin(), m_hDoorBlocker->CollisionProp()->OBBMins(), m_hDoorBlocker->CollisionProp()->OBBMaxs(), 255, 0, 0, true, 1.0f ); } } - -#ifdef VANCE - AngularMove(m_angRotationClosed, m_bKickedOpen ? m_flSpeed * 3.0f : m_flSpeed); -#else + AngularMove(m_angRotationClosed, m_flSpeed); -#endif } //----------------------------------------------------------------------------- @@ -5357,20 +6108,37 @@ void CPropDoorRotating::GetNPCOpenData(CAI_BaseNPC *pNPC, opendata_t &opendata) Vector vecNPCOrigin = pNPC->GetAbsOrigin(); +#ifdef MAPBASE + float flPosOffset = ai_door_open_dist_override.GetFloat() >= 0.0f ? ai_door_open_dist_override.GetFloat() : GetNPCOpenDistance(); +#else + float flPosOffset = 64; +#endif + if (pNPC->GetAbsOrigin().Dot(vecForward) > GetAbsOrigin().Dot(vecForward)) { // In front of the door relative to the door's forward vector. - opendata.vecStandPos += vecForward * 64; + opendata.vecStandPos += vecForward * flPosOffset; opendata.vecFaceDir = -vecForward; +#ifdef MAPBASE + opendata.eActivity = GetNPCOpenFrontActivity(); +#endif } else { // Behind the door relative to the door's forward vector. - opendata.vecStandPos -= vecForward * 64; + opendata.vecStandPos -= vecForward * flPosOffset; opendata.vecFaceDir = vecForward; +#ifdef MAPBASE + opendata.eActivity = GetNPCOpenBackActivity(); +#endif } +#ifdef MAPBASE + if (opendata.eActivity == ACT_INVALID) + opendata.eActivity = ACT_OPEN_DOOR; +#else opendata.eActivity = ACT_OPEN_DOOR; +#endif } @@ -5383,11 +6151,7 @@ float CPropDoorRotating::GetOpenInterval() QAngle vecDestDelta = m_angRotationOpenForward - GetLocalAngles(); // divide by speed to get time to reach dest -#ifdef VANCE - return vecDestDelta.Length() / (m_bKickedOpen ? 2.0f * m_flSpeed : m_flSpeed); -#else return vecDestDelta.Length() / m_flSpeed; -#endif } @@ -5406,6 +6170,14 @@ int CPropDoorRotating::DrawDebugTextOverlays(void) EntityText( text_offset, tempstr, 0); text_offset++; +#ifdef MAPBASE // From Alien Swarm SDK + if ( IsDoorLocked() ) + { + EntityText( text_offset, "LOCKED", 0); + text_offset++; + } +#endif + if ( IsDoorOpen() ) { Q_strncpy(tempstr, "DOOR STATE: OPEN", sizeof(tempstr)); @@ -5446,19 +6218,133 @@ void CPropDoorRotating::InputSetRotationDistance( inputdata_t &inputdata ) CalculateDoorVolume( GetLocalAngles(), m_angRotationOpenBack, &m_vecBackBoundsMin, &m_vecBackBoundsMax ); } +#ifdef DOOR_BREAKING_STUFF +//extern bool TransferPhysicsObject( CBaseEntity *pFrom, CBaseEntity *pTo, bool wakeUp ); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropDoorRotating::Break( CBaseEntity *pBreaker, const CTakeDamageInfo &info ) +{ + if (m_eBreakType == DOOR_ROTATING_BREAK_NORMAL) + return BaseClass::Break( pBreaker, info ); + + if (m_eBreakType == DOOR_ROTATING_BREAK_PHYS || m_eBreakType == DOOR_ROTATING_BREAK_PHYS_HINGE) + { + DevMsg("Should break into physics\n"); + UnlinkFromParent( this ); + + CBaseEntity *pPhys = CreateNoSpawn( "prop_physics", GetLocalOrigin(), GetLocalAngles() ); + if ( pPhys ) + { + pPhys->SetModelName( GetModelName() ); + + pPhys->m_nRenderMode = m_nRenderMode; + pPhys->m_nRenderFX = m_nRenderFX; + const color32 rclr = GetRenderColor(); + pPhys->SetRenderColor(rclr.r, rclr.g, rclr.b, rclr.a); + + CBaseAnimating *pPhysAnimating = pPhys->GetBaseAnimating(); + + pPhysAnimating->m_nSkin = m_nSkin; + pPhysAnimating->m_nBody = m_nBody; + pPhysAnimating->SetModelScale(GetModelScale()); + + pPhys->SetName( GetEntityName() ); + + UTIL_TransferPoseParameters( this, pPhys ); + TransferChildren( this, pPhys ); + + AddSolidFlags( FSOLID_NOT_SOLID ); + AddEffects( EF_NODRAW ); + + + PhysBreakSound( this, VPhysicsGetObject(), WorldSpaceCenter() ); + + DispatchSpawn(pPhys); + + // Transferring the physics object in this case has proven to be buggy. + if (pPhys->VPhysicsGetObject()) //if ( !TransferPhysicsObject( this, pPhys, true ) ) + { + //pPhys->VPhysicsInitNormal( SOLID_VPHYSICS, 0, false ); + + pPhys->VPhysicsGetObject()->SetMaterialIndex( VPhysicsGetObject()->GetMaterialIndex() ); + } + + if (m_eBreakType == DOOR_ROTATING_BREAK_PHYS_HINGE) + { + DevMsg("Should break with hinge\n"); + // This is the point where names get a little weird. + if (GetEntityName() != NULL_STRING) + SetName(NULL_STRING); + else + { + // Since we don't have a name, but the designer wants a hinge, give the new prop a name for the hinge to target. + pPhys->SetName(AllocPooledString(UTIL_VarArgs("_physdoor%i", entindex()))); + } + + CBaseEntity *pHinge = CreateNoSpawn("phys_hinge", GetLocalOrigin(), GetLocalAngles()); + pHinge->SetName(AllocPooledString(UTIL_VarArgs("%s_createdhinge", STRING(pPhys->GetEntityName())))); + pHinge->KeyValue("attach1", STRING(pPhys->GetEntityName())); + pHinge->KeyValue("hingeaxis", m_vecAxis); + pHinge->KeyValue("breaksound", "Metal_Box.BulletImpact"); + + DispatchSpawn(pHinge); + } + + BaseClass::Break( pBreaker, info ); + + //UTIL_Remove( this ); + + pPhys->VPhysicsTakeDamage(info); + + //if (pPhys->VPhysicsGetObject()) + // pPhys->VPhysicsGetObject()->ApplyForceOffset(info.GetDamageForce(), info.GetDamagePosition()); + } + else + { + BaseClass::Break( pBreaker, info ); + } + } +} +#endif + +#ifdef MAPBASE +void CPropDoorRotating::InputSetSpeed(inputdata_t &inputdata) +{ + AssertMsg1(inputdata.value.Float() > 0.0f, "InputSetSpeed on %s called with negative parameter!", GetDebugName() ); + m_flSpeed = inputdata.value.Float(); + DoorResume(); +} +#endif + // Debug sphere class CPhysSphere : public CPhysicsProp { DECLARE_CLASS( CPhysSphere, CPhysicsProp ); +#ifdef MAPBASE + DECLARE_DATADESC(); +#endif public: +#ifdef MAPBASE + float m_fRadius; +#else virtual bool OverridePropdata() { return true; } +#endif bool CreateVPhysics() { SetSolid( SOLID_BBOX ); +#ifdef MAPBASE + SetCollisionBounds( -Vector(m_fRadius), Vector(m_fRadius) ); +#else SetCollisionBounds( -Vector(12,12,12), Vector(12,12,12) ); +#endif objectparams_t params = g_PhysDefaultObjectParams; params.pGameData = static_cast(this); +#ifdef MAPBASE + IPhysicsObject *pPhysicsObject = physenv->CreateSphereObject( m_fRadius, GetModelPtr()->GetRenderHdr()->textureindex, GetAbsOrigin(), GetAbsAngles(), ¶ms, false ); +#else IPhysicsObject *pPhysicsObject = physenv->CreateSphereObject( 12, 0, GetAbsOrigin(), GetAbsAngles(), ¶ms, false ); +#endif if ( pPhysicsObject ) { VPhysicsSetObject( pPhysicsObject ); @@ -5470,16 +6356,144 @@ class CPhysSphere : public CPhysicsProp } }; +#ifdef MAPBASE +BEGIN_DATADESC( CPhysSphere ) + DEFINE_KEYFIELD( m_fRadius, FIELD_FLOAT, "radius"), +END_DATADESC() +#endif + +#ifndef MAPBASE // Yes, all I'm doing is moving this up a few lines and I'm still using the preprocessor. void CPropDoorRotating::InputSetSpeed(inputdata_t &inputdata) { AssertMsg1(inputdata.value.Float() > 0.0f, "InputSetSpeed on %s called with negative parameter!", GetDebugName() ); m_flSpeed = inputdata.value.Float(); DoorResume(); } +#endif LINK_ENTITY_TO_CLASS( prop_sphere, CPhysSphere ); +#if defined(MAPBASE) && defined(HL2_EPISODIC) +// ------------------------------------------------------------------------------------------ // +// Flare class for higher interaction possibilities, inspired by Black Mesa +// ------------------------------------------------------------------------------------------ // +class CPropFlare : public CPhysicsProp +{ + DECLARE_CLASS( CPropFlare, CPhysicsProp ); + DECLARE_DATADESC(); +public: + + void Precache() + { + BaseClass::Precache(); + + if (GetModelName() != NULL_STRING) + { + PrecacheModel(STRING(GetModelName())); + } + else + { + PrecacheModel("models/props_junk/flare.mdl"); + } + } + + void Spawn() + { + if (GetModelName() == NULL_STRING) + { + // Must've been spawned with ent_create or something + SetModelName(AllocPooledString("models/props_junk/flare.mdl")); + //SetModel("models/props_junk/flare.mdl"); + } + + if (!HasInteraction(PROPINTER_PHYSGUN_CREATE_FLARE)) + { + SetInteraction(PROPINTER_PHYSGUN_CREATE_FLARE); + } + + SetClassname( "prop_physics" ); + + return BaseClass::Spawn(); + } + + bool OverridePropdata( void ) { return true; } + + virtual float GetFlareLifetime() { return m_flFlareLifetime; } + + void InputStartFlare( inputdata_t &inputdata ) + { + CreateFlare( PROP_FLARE_LIFETIME ); + } + void InputStopFlare( inputdata_t &inputdata ) + { + KillFlare( this, m_hFlareEnt, PROP_FLARE_IGNITE_SUBSTRACT ); + } + + void InputAddFlareLifetime( inputdata_t &inputdata ) + { + if (m_hFlareEnt) + { + KillFlare( this, m_hFlareEnt, (inputdata.value.Float() * -1) ); + } + else + { + CreateFlare( inputdata.value.Float() ); + } + } + + void InputRemoveFlare( inputdata_t &inputdata ) + { + UTIL_Remove(m_hFlareEnt); + m_nSkin = 1; + } + + void InputRestoreFlare( inputdata_t &inputdata ) + { + if (!HasInteraction(PROPINTER_PHYSGUN_CREATE_FLARE) && !m_hFlareEnt) + { + SetInteraction(PROPINTER_PHYSGUN_CREATE_FLARE); + m_OnRestored.FireOutput(inputdata.pActivator, inputdata.pCaller); + m_nSkin = 0; + } + } + + int DrawDebugTextOverlays(void) + { + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + Q_snprintf(tempstr, sizeof(tempstr), "Flare Duration: %f", GetEnvFlareLifetime(m_hFlareEnt)); + EntityText(text_offset, tempstr, 0); + text_offset++; + } + + return text_offset; + } + + COutputEvent m_OnRestored; + float m_flFlareLifetime = 30.0f; +}; + +LINK_ENTITY_TO_CLASS( prop_flare, CPropFlare ); + +BEGIN_DATADESC( CPropFlare ) + + DEFINE_KEYFIELD( m_flFlareLifetime, FIELD_FLOAT, "FlareLifetime" ), + + DEFINE_INPUTFUNC( FIELD_VOID, "StartFlare", InputStartFlare ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopFlare", InputStopFlare ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "AddFlareLifetime", InputAddFlareLifetime ), + DEFINE_INPUTFUNC( FIELD_VOID, "RemoveFlare", InputRemoveFlare ), + DEFINE_INPUTFUNC( FIELD_VOID, "RestoreFlare", InputRestoreFlare ), + DEFINE_OUTPUT( m_OnRestored, "OnRestored" ), + +END_DATADESC() +#endif + + // ------------------------------------------------------------------------------------------ // // Special version of func_physbox. // ------------------------------------------------------------------------------------------ // diff --git a/game/server/props.h b/game/server/props.h index 7dc9f48a..ebd87c4d 100644 --- a/game/server/props.h +++ b/game/server/props.h @@ -39,6 +39,11 @@ class CBaseProp : public CBaseAnimating // Don't treat as a live target virtual bool IsAlive( void ) { return false; } virtual bool OverridePropdata() { return true; } + +#ifdef MAPBASE + // Attempt to replace a dynamic_cast + virtual bool IsPropPhysics() { return false; } +#endif }; @@ -58,10 +63,18 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C virtual void Precache(); virtual float GetAutoAimRadius() { return 24.0f; } +#ifdef MAPBASE + virtual bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + void BreakablePropTouch( CBaseEntity *pOther ); virtual int OnTakeDamage( const CTakeDamageInfo &info ); void Event_Killed( const CTakeDamageInfo &info ); +#ifdef MAPBASE + // Marks Break() as virtual + virtual +#endif void Break( CBaseEntity *pBreaker, const CTakeDamageInfo &info ); void BreakThink( void ); void AnimateThink( void ); @@ -72,6 +85,10 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C void InputAddHealth( inputdata_t &inputdata ); void InputRemoveHealth( inputdata_t &inputdata ); void InputSetHealth( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetInteraction( inputdata_t &inputdata ); + void InputRemoveInteraction( inputdata_t &inputdata ); +#endif int GetNumBreakableChunks( void ) { return m_iNumBreakableChunks; } @@ -86,6 +103,11 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C if ( HasInteraction( PROPINTER_PHYSGUN_LAUNCH_SPIN_Z ) ) return true; +#ifdef MAPBASE + if ( m_bUsesCustomCarryAngles ) + return true; +#endif + return false; } @@ -97,6 +119,11 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C void HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent ); void HandleInteractionStick( int index, gamevcollisionevent_t *pEvent ); void StickAtPosition( const Vector &stickPosition, const Vector &savePosition, const QAngle &saveAngles ); + +#ifdef MAPBASE + // Uses the new CBaseEntity interaction implementation + bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); +#endif // Disable auto fading under dx7 or when level fades are specified void DisableAutoFade(); @@ -111,6 +138,10 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C int m_iMinHealthDmg; QAngle m_preferredCarryAngles; +#ifdef MAPBASE + // Indicates whether the prop is using the keyvalue carry angles. + bool m_bUsesCustomCarryAngles; +#endif public: // IBreakableWithPropData @@ -196,6 +227,9 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C virtual CBasePlayer *HasPhysicsAttacker( float dt ); #ifdef HL2_EPISODIC +#ifdef MAPBASE + virtual float GetFlareLifetime() { return 30.0f; } +#endif void CreateFlare( float flLifetime ); #endif //HL2_EPISODIC @@ -243,7 +277,14 @@ class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public C mp_break_t m_mpBreakMode; EHANDLE m_hLastAttacker; // Last attacker that harmed me. +#ifdef MAPBASE +protected: + // Needs to be protected for prop_flare entity usage + EHANDLE m_hFlareEnt; +private: +#else EHANDLE m_hFlareEnt; +#endif string_t m_iszPuntSound; bool m_bUsePuntSound; }; @@ -288,6 +329,9 @@ class CDynamicProp : public CBreakableProp, public IPositionWatcher // Input handlers void InputSetAnimation( inputdata_t &inputdata ); +#ifdef MAPBASE // From Alien Swarm SDK + void InputSetAnimationNoReset( inputdata_t &inputdata ); +#endif void InputSetDefaultAnimation( inputdata_t &inputdata ); void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); @@ -304,6 +348,9 @@ class CDynamicProp : public CBreakableProp, public IPositionWatcher int m_iTransitionDirection; // Random animations +#ifdef MAPBASE // From Alien Swarm SDK + bool m_bHoldAnimation; +#endif bool m_bRandomAnimator; float m_flNextRandAnim; float m_flMinRandAnimTime; @@ -312,6 +359,9 @@ class CDynamicProp : public CBreakableProp, public IPositionWatcher bool m_bStartDisabled; bool m_bDisableBoneFollowers; +#ifdef MAPBASE // From Alien Swarm SDK + bool m_bUpdateAttachedChildren; // For props with children on attachment points, update their child touches as we animate +#endif CNetworkVar( bool, m_bUseHitboxesForRenderBox ); @@ -327,8 +377,7 @@ class CDynamicProp : public CBreakableProp, public IPositionWatcher //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -DECLARE_AUTO_LIST( IPhysicsPropAutoList ); -class CPhysicsProp : public CBreakableProp, public IPhysicsPropAutoList +class CPhysicsProp : public CBreakableProp { DECLARE_CLASS( CPhysicsProp, CBreakableProp ); DECLARE_SERVERCLASS(); @@ -344,6 +393,11 @@ class CPhysicsProp : public CBreakableProp, public IPhysicsPropAutoList bool CreateVPhysics( void ); bool OverridePropdata( void ); +#ifdef MAPBASE + // Attempt to replace a dynamic_cast + virtual bool IsPropPhysics() { return true; } +#endif + virtual void VPhysicsUpdate( IPhysicsObject *pPhysics ); virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); @@ -352,6 +406,9 @@ class CPhysicsProp : public CBreakableProp, public IPhysicsPropAutoList void InputEnableMotion( inputdata_t &inputdata ); void InputDisableMotion( inputdata_t &inputdata ); void InputDisableFloating( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetDebris( inputdata_t &inputdata ); +#endif void EnableMotion( void ); bool CanBePickedUpByPhyscannon( void ); diff --git a/game/server/recipientfilter.cpp b/game/server/recipientfilter.cpp index 64889b31..b7687fbe 100644 --- a/game/server/recipientfilter.cpp +++ b/game/server/recipientfilter.cpp @@ -98,7 +98,7 @@ void CRecipientFilter::AddAllPlayers( void ) } } -void CRecipientFilter::AddRecipient( const CBasePlayer *player ) +void CRecipientFilter::AddRecipient( CBasePlayer *player ) { Assert( player ); @@ -341,7 +341,7 @@ CTeamRecipientFilter::CTeamRecipientFilter( int team, bool isReliable ) if ( pPlayer->GetTeamNumber() != team ) { //If we're in the spectator team then we should be getting whatever messages the person I'm spectating gets. - if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR && (pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE || pPlayer->GetObserverMode() == OBS_MODE_POI) ) + if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR && (pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE) ) { if ( pPlayer->GetObserverTarget() ) { diff --git a/game/server/recipientfilter.h b/game/server/recipientfilter.h index 30af93ac..3f48e4fa 100644 --- a/game/server/recipientfilter.h +++ b/game/server/recipientfilter.h @@ -46,7 +46,7 @@ class CRecipientFilter : public IRecipientFilter void AddRecipientsByPVS( const Vector& origin ); void RemoveRecipientsByPVS( const Vector& origin ); void AddRecipientsByPAS( const Vector& origin ); - void AddRecipient( const CBasePlayer *player ); + void AddRecipient( CBasePlayer *player ); void RemoveAllRecipients( void ); void RemoveRecipient( CBasePlayer *player ); void RemoveRecipientByPlayerIndex( int playerindex ); @@ -82,7 +82,7 @@ class CRecipientFilter : public IRecipientFilter class CSingleUserRecipientFilter : public CRecipientFilter { public: - CSingleUserRecipientFilter( const CBasePlayer *player ) + CSingleUserRecipientFilter( CBasePlayer *player ) { AddRecipient( player ); } diff --git a/game/server/rope.cpp b/game/server/rope.cpp index 7ca53298..23f44c39 100644 --- a/game/server/rope.cpp +++ b/game/server/rope.cpp @@ -37,6 +37,9 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CRopeKeyframe, DT_RopeKeyframe ) SendPropInt( SENDINFO(m_Slack), 12 ), SendPropInt( SENDINFO(m_RopeLength), 15 ), SendPropInt( SENDINFO(m_fLockedPoints), 4, SPROP_UNSIGNED ), +#ifdef MAPBASE + SendPropInt( SENDINFO(m_nChangeCount), 8, SPROP_UNSIGNED ), +#endif SendPropInt( SENDINFO(m_RopeFlags), ROPE_NUMFLAGS, SPROP_UNSIGNED ), SendPropInt( SENDINFO(m_nSegments), 4, SPROP_UNSIGNED ), SendPropBool( SENDINFO(m_bConstrainBetweenEndpoints) ), @@ -86,6 +89,15 @@ BEGIN_DATADESC( CRopeKeyframe ) DEFINE_INPUTFUNC( FIELD_VECTOR, "SetForce", InputSetForce ), DEFINE_INPUTFUNC( FIELD_VOID, "Break", InputBreak ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSlack", InputSetSlack ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetWidth", InputSetWidth ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSubdivision", InputSetSubdivision ), + + // Outputs + DEFINE_OUTPUT( m_OnBreak, "OnBreak" ), +#endif + END_DATADESC() @@ -109,7 +121,12 @@ CRopeKeyframe::CRopeKeyframe() m_RopeLength = 20; m_fLockedPoints = (int) (ROPE_LOCK_START_POINT | ROPE_LOCK_END_POINT); // by default, both points are locked m_flScrollSpeed = 0; +#ifdef MAPBASE + // Because of the keyvalue switch + m_RopeFlags = ROPE_SIMULATE | ROPE_INITIAL_HANG | ROPE_USE_WIND; +#else m_RopeFlags = ROPE_SIMULATE | ROPE_INITIAL_HANG; +#endif m_iRopeMaterialModelIndex = -1; m_Subdiv = 2; @@ -201,10 +218,19 @@ CRopeKeyframe* CRopeKeyframe::Create( int iEndAttachment, int ropeWidth, const char *pMaterialName, +#ifdef MAPBASE + int numSegments, + const char *pClassName +#else int numSegments +#endif ) { +#ifdef MAPBASE + CRopeKeyframe *pRet = (CRopeKeyframe*)CreateEntityByName( pClassName ); +#else CRopeKeyframe *pRet = (CRopeKeyframe*)CreateEntityByName( "keyframe_rope" ); +#endif if( !pRet ) return NULL; @@ -218,6 +244,9 @@ CRopeKeyframe* CRopeKeyframe::Create( pRet->SetMaterial( pMaterialName ); pRet->m_Width = ropeWidth; pRet->m_nSegments = clamp( numSegments, 2, ROPE_MAX_SEGMENTS ); +#ifdef MAPBASE + pRet->Spawn(); +#endif return pRet; } @@ -230,10 +259,19 @@ CRopeKeyframe* CRopeKeyframe::CreateWithSecondPointDetached( int ropeWidth, const char *pMaterialName, int numSegments, +#ifdef MAPBASE + bool bInitialHang, + const char *pClassName +#else bool bInitialHang +#endif ) { +#ifdef MAPBASE + CRopeKeyframe *pRet = (CRopeKeyframe*)CreateEntityByName( pClassName ); +#else CRopeKeyframe *pRet = (CRopeKeyframe*)CreateEntityByName( "keyframe_rope" ); +#endif if( !pRet ) return NULL; @@ -329,6 +367,26 @@ void CRopeKeyframe::Init() m_bStartPointValid = (m_hStartPoint.Get() != NULL); m_bEndPointValid = (m_hEndPoint.Get() != NULL); + +#ifdef MAPBASE + // Sanity-check the rope texture scale before it goes over the wire + if ( m_TextureScale < 0.1f ) + { + Vector origin = GetAbsOrigin(); + GetEndPointPos( 0, origin ); + DevMsg( "move_rope has TextureScale less than 0.1 at (%2.2f, %2.2f, %2.2f)\n", + origin.x, origin.y, origin.z ); + m_TextureScale = 0.1f; + } + else if ( m_TextureScale > 10.0f ) + { + Vector origin = GetAbsOrigin(); + GetEndPointPos( 0, origin ); + DevMsg( "move_rope has TextureScale greater than 10 at (%2.2f, %2.2f, %2.2f)\n", + origin.x, origin.y, origin.z ); + m_TextureScale = 10.0f; + } +#endif } @@ -552,17 +610,74 @@ void CRopeKeyframe::InputSetForce( inputdata_t &inputdata ) void CRopeKeyframe::InputBreak( inputdata_t &inputdata ) { //Route through the damage code +#ifdef MAPBASE + Break(inputdata.pActivator); +#else Break(); +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets the slack +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CRopeKeyframe::InputSetSlack( inputdata_t &inputdata ) +{ + m_Slack = inputdata.value.Int(); + + // Must resize in order for changes to occur + m_RopeFlags |= ROPE_RESIZE; + + if (!(m_RopeFlags & ROPE_USE_WIND)) + { + Warning( "WARNING: SetSlack on %s may need wind enabled in order to function\n", GetDebugName() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the width +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CRopeKeyframe::InputSetWidth( inputdata_t &inputdata ) +{ + m_Width = inputdata.value.Float(); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the subdivision +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CRopeKeyframe::InputSetSubdivision( inputdata_t &inputdata ) +{ + m_Subdiv = inputdata.value.Int(); + + // Must resize in order for changes to occur + m_RopeFlags |= ROPE_RESIZE; + + if (!(m_RopeFlags & ROPE_USE_WIND)) + { + Warning( "WARNING: SetSubdivision on %s may need wind enabled in order to function\n", GetDebugName() ); + } } +#endif //----------------------------------------------------------------------------- // Purpose: Breaks the rope // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- +#ifdef MAPBASE +bool CRopeKeyframe::Break( CBaseEntity *pActivator ) +#else bool CRopeKeyframe::Break( void ) +#endif { DetachPoint( 0 ); +#ifdef MAPBASE + m_OnBreak.FireOutput(pActivator ? pActivator : this, this); +#endif + // Find whoever references us and detach us from them. // UNDONE: PERFORMANCE: This is very slow!!! CRopeKeyframe *pTest = NULL; @@ -585,6 +700,10 @@ bool CRopeKeyframe::Break( void ) //----------------------------------------------------------------------------- void CRopeKeyframe::NotifyPositionChanged( CBaseEntity *pEntity ) { +#ifdef MAPBASE + ++m_nChangeCount; +#endif + // Update our bbox? UpdateBBox( false ); @@ -619,7 +738,11 @@ int CRopeKeyframe::OnTakeDamage( const CTakeDamageInfo &info ) if( !(m_RopeFlags & ROPE_BREAKABLE) ) return false; +#ifdef MAPBASE + Break(info.GetAttacker()); +#else Break(); +#endif return 0; } @@ -630,6 +753,14 @@ void CRopeKeyframe::Precache() BaseClass::Precache(); } +#ifdef MAPBASE +void CRopeKeyframe::Spawn( void ) +{ + BaseClass::Spawn(); + Precache(); +} +#endif + void CRopeKeyframe::DetachPoint( int iPoint ) { @@ -650,10 +781,17 @@ void CRopeKeyframe::EnableCollision() void CRopeKeyframe::EnableWind( bool bEnable ) { int flag = 0; +#ifdef MAPBASE + if ( bEnable ) + flag |= ROPE_USE_WIND; + + if ( (m_RopeFlags & ROPE_USE_WIND) != flag ) +#else if ( !bEnable ) flag |= ROPE_NO_WIND; if ( (m_RopeFlags & ROPE_NO_WIND) != flag ) +#endif { m_RopeFlags |= flag; } @@ -698,6 +836,20 @@ bool CRopeKeyframe::KeyValue( const char *szKeyName, const char *szValue ) { // Legacy support for the RopeShader parameter. int iShader = atoi( szValue ); +#ifdef MAPBASE + if ( iShader == 0 ) + { + m_strRopeMaterialModel = AllocPooledString( "cable/cable.vmt" ); + } + else if ( iShader == 1 ) + { + m_strRopeMaterialModel = AllocPooledString( "cable/rope.vmt" ); + } + else + { + m_strRopeMaterialModel = AllocPooledString( "cable/chain.vmt" ); + } +#else if ( iShader == 0 ) { m_iRopeMaterialModelIndex = PrecacheModel( "cable/cable.vmt" ); @@ -710,6 +862,7 @@ bool CRopeKeyframe::KeyValue( const char *szKeyName, const char *szValue ) { m_iRopeMaterialModelIndex = PrecacheModel( "cable/chain.vmt" ); } +#endif } else if ( stricmp( szKeyName, "RopeMaterial" ) == 0 ) { @@ -725,12 +878,28 @@ bool CRopeKeyframe::KeyValue( const char *szKeyName, const char *szValue ) SetMaterial( str ); } } +#ifdef MAPBASE + else if( stricmp( szKeyName, "UseWind" ) == 0 ) + { + if( atoi( szValue ) == 1 ) + m_RopeFlags |= ROPE_USE_WIND; + else + m_RopeFlags &= ~ROPE_USE_WIND; + } +#endif else if ( stricmp( szKeyName, "NoWind" ) == 0 ) { +#ifdef MAPBASE + if ( atoi( szValue ) != 1 ) + m_RopeFlags |= ROPE_USE_WIND; + else + m_RopeFlags &= ~ROPE_USE_WIND; +#else if ( atoi( szValue ) == 1 ) { m_RopeFlags |= ROPE_NO_WIND; } +#endif } return BaseClass::KeyValue( szKeyName, szValue ); @@ -749,7 +918,9 @@ void CRopeKeyframe::InputSetScrollSpeed( inputdata_t &inputdata ) void CRopeKeyframe::SetMaterial( const char *pName ) { m_strRopeMaterialModel = AllocPooledString( pName ); +#ifndef MAPBASE m_iRopeMaterialModelIndex = PrecacheModel( STRING( m_strRopeMaterialModel ) ); +#endif } int CRopeKeyframe::UpdateTransmitState() diff --git a/game/server/rope.h b/game/server/rope.h index 7ab96044..44fc7102 100644 --- a/game/server/rope.h +++ b/game/server/rope.h @@ -37,7 +37,12 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher const char *pMaterialName = "cable/cable.vmt", // Note: whoever creates the rope must // use PrecacheModel for whatever material // it specifies here. +#ifdef MAPBASE + int numSegments = 5, + const char *pClassName = "keyframe_rope" +#else int numSegments = 5 +#endif ); static CRopeKeyframe* CreateWithSecondPointDetached( @@ -49,7 +54,12 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher // use PrecacheModel for whatever material // it specifies here. int numSegments = 5, +#ifdef MAPBASE + bool bInitialHang = false, + const char *pClassName = "keyframe_rope" +#else bool bInitialHang = false +#endif ); bool SetupHangDistance( float flHangDist ); @@ -68,6 +78,9 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } virtual void Activate(); virtual void Precache(); +#ifdef MAPBASE + virtual void Spawn(); +#endif virtual int OnTakeDamage( const CTakeDamageInfo &info ); virtual bool KeyValue( const char *szKeyName, const char *szValue ); @@ -89,10 +102,19 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher void InputSetScrollSpeed( inputdata_t &inputdata ); void InputSetForce( inputdata_t &inputdata ); void InputBreak( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetSlack( inputdata_t &inputdata ); + void InputSetWidth( inputdata_t &inputdata ); + void InputSetSubdivision( inputdata_t &inputdata ); +#endif public: +#ifdef MAPBASE + bool Break( CBaseEntity *pActivator = NULL ); +#else bool Break( void ); +#endif void DetachPoint( int iPoint ); void EndpointsChanged(); @@ -103,12 +125,21 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher // Toggle wind. void EnableWind( bool bEnable ); +#ifdef MAPBASE + CBaseEntity* GetStartPoint() { return m_hStartPoint.Get(); } + int GetStartAttachment() { return m_iStartAttachment; }; +#else // Unless this is called during initialization, the caller should have done // PrecacheModel on whatever material they specify in here. void SetMaterial( const char *pName ); +#endif CBaseEntity* GetEndPoint() { return m_hEndPoint.Get(); } +#ifdef MAPBASE + int GetEndAttachment() { return m_iEndAttachment; }; +#else int GetEndAttachment() { return m_iStartAttachment; }; +#endif void SetStartPoint( CBaseEntity *pStartPoint, int attachment = 0 ); void SetEndPoint( CBaseEntity *pEndPoint, int attachment = 0 ); @@ -122,11 +153,25 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher private: +#ifdef MAPBASE + // Unless this is called during initialization, the caller should have done + // PrecacheModel on whatever material they specify in here. + void SetMaterial( const char *pName ); + +protected: +#endif + void SetAttachmentPoint( CBaseHandle &hOutEnt, short &iOutAttachment, CBaseEntity *pEnt, int iAttachment ); // This is normally called by Activate but if you create the rope at runtime, // you must call it after you have setup its variables. +#ifdef MAPBASE + virtual void Init(); + +private: +#else void Init(); +#endif // These work just like the client-side versions. bool GetEndPointPos2( CBaseEntity *pEnt, int iAttachment, Vector &v ); @@ -151,6 +196,11 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher // Number of subdivisions in between segments. CNetworkVar( int, m_Subdiv ); + +#ifdef MAPBASE + // Used simply to wake up rope on the client side if it has gone to sleep + CNetworkVar( unsigned char, m_nChangeCount ); +#endif //EHANDLE m_hNextLink; @@ -171,6 +221,10 @@ class CRopeKeyframe : public CBaseEntity, public IPositionWatcher CNetworkHandle( CBaseEntity, m_hEndPoint ); CNetworkVar( short, m_iStartAttachment ); // StartAttachment/EndAttachment are attachment points. CNetworkVar( short, m_iEndAttachment ); + +#ifdef MAPBASE + COutputEvent m_OnBreak; +#endif }; diff --git a/game/server/saverestore_gamedll.cpp b/game/server/saverestore_gamedll.cpp index 768262e1..a1f9505d 100644 --- a/game/server/saverestore_gamedll.cpp +++ b/game/server/saverestore_gamedll.cpp @@ -93,6 +93,17 @@ bool ParseKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, c UTIL_StringToColor32( (color32 *) ((char *)pObject + fieldOffset), szValue ); return true; +#ifdef MAPBASE + case FIELD_EHANDLE: + ((CBaseHandle*)((char*)pObject + fieldOffset))->Set(gEntList.FindEntityByName(NULL, szValue)); + return true; + + case FIELD_INTERVAL: + extern interval_t ReadInterval( const char *pString ); + (*(interval_t*)((char *)pObject + fieldOffset)) = ReadInterval( szValue ); + return true; +#endif + case FIELD_CUSTOM: { SaveRestoreFieldInfo_t fieldInfo = @@ -106,7 +117,9 @@ bool ParseKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, c } default: +#ifndef MAPBASE case FIELD_INTERVAL: // Fixme, could write this if needed +#endif case FIELD_CLASSPTR: case FIELD_MODELINDEX: case FIELD_MATERIALINDEX: diff --git a/game/server/sceneentity.cpp b/game/server/sceneentity.cpp index f092624f..e8f0c82d 100644 --- a/game/server/sceneentity.cpp +++ b/game/server/sceneentity.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -32,7 +32,10 @@ #include "scenefilecache/ISceneFileCache.h" #include "SceneCache.h" #include "scripted.h" +#include "basemultiplayerplayer.h" #include "env_debughistory.h" +#include "team.h" +#include "triggers.h" #ifdef HL2_EPISODIC #include "npc_alyx_episodic.h" @@ -58,7 +61,7 @@ static ConVar scene_maxcaptionradius( "scene_maxcaptionradius", "1200", 0, "Only #define SOUND_SYSTEM_LATENCY_DEFAULT ( 0.1f ) // Think every 50 msec (FIXME: Try 10hz?) -#define SCENE_THINK_INTERVAL 0.001 // FIXME: make scene's think in concert with their npc's +#define SCENE_THINK_INTERVAL 0.001 // FIXME: make scene's think in concert with their npc's #define FINDNAMEDENTITY_MAX_ENTITIES 32 // max number of entities to be considered for random entity selection in FindNamedEntity @@ -70,6 +73,17 @@ static int speechListIndex = 0; #define SCENE_MIN_PITCH 0.25f #define SCENE_MAX_PITCH 2.5f +// New macros introduced for Mapbase's console message color changes. +#ifdef MAPBASE +#define ChoreoMsg( lvl, msg ) CGMsg( lvl, CON_GROUP_CHOREO, msg ) +#define ChoreoMsg1( lvl, msg, a ) CGMsg( lvl, CON_GROUP_CHOREO, msg, a ) +#define ChoreoMsg2( lvl, msg, a, b ) CGMsg( lvl, CON_GROUP_CHOREO, msg, a, b ) +#else +#define ChoreoMsg( lvl, msg ) DevMsg( lvl, msg ) +#define ChoreoMsg1( lvl, msg, a ) DevMsg( lvl, msg, a ) +#define ChoreoMsg2( lvl, msg, a, b ) DevMsg( lvl, msg, a, b ) +#endif + //=========================================================================================================== // SCENE LIST MANAGER //=========================================================================================================== @@ -83,6 +97,11 @@ class CSceneListManager : public CLogicalEntity DECLARE_CLASS( CSceneListManager, CLogicalEntity ); public: DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); + + HSCRIPT ScriptGetScene( int iIndex ); +#endif virtual void Activate( void ); @@ -127,7 +146,7 @@ class CSceneManager : public CBaseEntity void QueueRestoredSound( CBaseFlex *actor, char const *soundname, soundlevel_t soundlevel, float time_in_past ); void OnClientActive( CBasePlayer *player ); - + void RemoveActorFromScenes( CBaseFlex *pActor, bool bInstancedOnly, bool bNonIdleOnly, const char *pszThisSceneOnly ); void RemoveScenesInvolvingActor( CBaseFlex *pActor ); void PauseActorsScenes( CBaseFlex *pActor, bool bInstancedOnly ); @@ -139,6 +158,13 @@ class CSceneManager : public CBaseEntity bool IsRunningScriptedSceneWithSpeech( CBaseFlex *pActor, bool bIgnoreInstancedScenes ); bool IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes ); +#ifdef MAPBASE + bool IsRunningScriptedSceneWithFlexAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes, const char *pszNotThisScene = NULL ); + bool IsTalkingInAScriptedScene( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); + + CUtlVector< CHandle< CSceneEntity > > *GetActiveSceneList(); +#endif + private: @@ -177,9 +203,9 @@ END_DATADESC() #define LocalScene_Printf Scene_Printf #else //----------------------------------------------------------------------------- -// Purpose: -// Input : *pFormat - -// ... - +// Purpose: +// Input : *pFormat - +// ... - // Output : static void //----------------------------------------------------------------------------- void LocalScene_Printf( const char *pFormat, ... ) @@ -189,7 +215,7 @@ void LocalScene_Printf( const char *pFormat, ... ) va_start(marker, pFormat); Q_vsnprintf(msg, sizeof(msg), pFormat, marker); - va_end(marker); + va_end(marker); Scene_Printf( "%s", msg ); ADD_DEBUG_HISTORY( HISTORY_SCENE_PRINT, UTIL_VarArgs( "(%0.2f) %s", gpGlobals->curtime, msg ) ); @@ -197,9 +223,9 @@ void LocalScene_Printf( const char *pFormat, ... ) #endif //----------------------------------------------------------------------------- -// Purpose: -// Input : *filename - -// **buffer - +// Purpose: +// Input : *filename - +// **buffer - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CopySceneFileIntoMemory( char const *pFilename, void **pBuffer, int *pSize ) @@ -218,7 +244,7 @@ bool CopySceneFileIntoMemory( char const *pFilename, void **pBuffer, int *pSize } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void FreeSceneFileMemory( void *buffer ) { @@ -249,7 +275,7 @@ class CChoreoStringPool : public IChoreoStringPool } V_strncpy( buff, pString, buffSize ); return true; - } + } }; CChoreoStringPool g_ChoreoStringPool; @@ -276,8 +302,8 @@ CSceneManager *GetSceneManager() } //----------------------------------------------------------------------------- -// Purpose: -// Input : *player - +// Purpose: +// Input : *player - //----------------------------------------------------------------------------- void SceneManager_ClientActive( CBasePlayer *player ) { @@ -317,10 +343,12 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback DECLARE_CLASS( CSceneEntity, CPointEntity ); DECLARE_SERVERCLASS(); + // script description + DECLARE_ENT_SCRIPTDESC(); CSceneEntity( void ); ~CSceneEntity( void ); - + // From IChoreoEventCallback virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ); virtual void EndEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ); @@ -408,10 +436,10 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback bool GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *player, char *buf, size_t buflen, CBaseEntity *pActor ); - void BuildSortedSpeakEventSoundsPrefetchList( - CChoreoScene *scene, - CUtlSymbolTable& table, - CUtlRBTree< SpeakEventSound_t >& soundnames, + void BuildSortedSpeakEventSoundsPrefetchList( + CChoreoScene *scene, + CUtlSymbolTable& table, + CUtlRBTree< SpeakEventSound_t >& soundnames, float timeOffset ); void PrefetchSpeakEventSounds( CUtlSymbolTable& table, CUtlRBTree< SpeakEventSound_t >& soundnames ); @@ -449,7 +477,7 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback virtual void DispatchStopPoint( CChoreoScene *scene, const char *parameters ); virtual float EstimateLength( void ); - + void CancelIfSceneInvolvesActor( CBaseEntity *pActor ); bool InvolvesActor( CBaseEntity *pActor ); // NOTE: returns false if scene hasn't loaded yet @@ -459,11 +487,16 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback bool HasUnplayedSpeech( void ); bool HasFlexAnimation( void ); +#ifdef MAPBASE + bool IsPlayingSpeech( void ); +#endif void SetCurrentTime( float t, bool forceClientSync ); void InputScriptPlayerDeath( inputdata_t &inputdata ); + void AddBroadcastTeamTarget( int nTeamIndex ); + void RemoveBroadcastTeamTarget( int nTeamIndex ); // Data public: string_t m_iszSceneFile; @@ -481,6 +514,18 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback string_t m_iszTarget7; string_t m_iszTarget8; +#ifdef MAPBASE + void SetTarget(int nTarget, string_t pTargetName, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL); + void InputSetTarget1(inputdata_t &inputdata); + void InputSetTarget2(inputdata_t &inputdata); + void InputSetTarget3(inputdata_t &inputdata); + void InputSetTarget4(inputdata_t &inputdata); + void InputSetTarget5(inputdata_t &inputdata); + void InputSetTarget6(inputdata_t &inputdata); + void InputSetTarget7(inputdata_t &inputdata); + void InputSetTarget8(inputdata_t &inputdata); +#endif + EHANDLE m_hTarget1; EHANDLE m_hTarget2; EHANDLE m_hTarget3; @@ -525,6 +570,9 @@ class CSceneEntity : public CPointEntity, public IChoreoEventCallback virtual CBaseEntity *FindNamedEntity( const char *name, CBaseEntity *pActor = NULL, bool bBaseFlexOnly = false, bool bUseClear = false ); CBaseEntity *FindNamedTarget( string_t iszTarget, bool bBaseFlexOnly = false ); virtual CBaseEntity *FindNamedEntityClosest( const char *name, CBaseEntity *pActor = NULL, bool bBaseFlexOnly = false, bool bUseClear = false, const char *pszSecondary = NULL ); + HSCRIPT ScriptFindNamedEntity( const char *name ); + bool ScriptLoadSceneFromString( const char * pszFilename, const char *pszData ); + private: @@ -672,7 +720,7 @@ BEGIN_DATADESC( CSceneEntity ) DEFINE_UTLVECTOR( m_hActorList, FIELD_EHANDLE ), DEFINE_UTLVECTOR( m_hRemoveActorList, FIELD_EHANDLE ), - + // DEFINE_FIELD( m_pScene, FIELD_XXXX ) // Special processing used for this // These are set up in the constructor @@ -710,6 +758,17 @@ BEGIN_DATADESC( CSceneEntity ) DEFINE_INPUTFUNC( FIELD_VOID, "StopWaitingForActor", InputStopWaitingForActor ), DEFINE_INPUTFUNC( FIELD_INTEGER, "Trigger", InputTriggerEvent ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget1", InputSetTarget1 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget2", InputSetTarget2 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget3", InputSetTarget3 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget4", InputSetTarget4 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget5", InputSetTarget5 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget6", InputSetTarget6 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget7", InputSetTarget7 ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget8", InputSetTarget8 ), +#endif + DEFINE_KEYFIELD( m_iPlayerDeathBehavior, FIELD_INTEGER, "onplayerdeath" ), DEFINE_INPUTFUNC( FIELD_VOID, "ScriptPlayerDeath", InputScriptPlayerDeath ), @@ -735,10 +794,21 @@ BEGIN_DATADESC( CSceneEntity ) DEFINE_OUTPUT( m_OnTrigger16, "OnTrigger16"), END_DATADESC() + +BEGIN_ENT_SCRIPTDESC( CSceneEntity, CBaseEntity, "Choreographed scene which controls animation and/or dialog on one or more actors." ) + DEFINE_SCRIPTFUNC( EstimateLength, "Returns length of this scene in seconds." ) + DEFINE_SCRIPTFUNC( IsPlayingBack, "If this scene is currently playing." ) + DEFINE_SCRIPTFUNC( IsPaused, "If this scene is currently paused." ) + DEFINE_SCRIPTFUNC( AddBroadcastTeamTarget, "Adds a team (by index) to the broadcast list" ) + DEFINE_SCRIPTFUNC( RemoveBroadcastTeamTarget, "Removes a team (by index) from the broadcast list" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFindNamedEntity, "FindNamedEntity", "given an entity reference, such as !target, get actual entity from scene object" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptLoadSceneFromString, "LoadSceneFromString", "given a dummy scene name and a vcd string, load the scene" ) +END_SCRIPTDESC(); + const ConVar *CSceneEntity::m_pcvSndMixahead = NULL; //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CSceneEntity::CSceneEntity( void ) { @@ -775,7 +845,7 @@ CSceneEntity::CSceneEntity( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- CSceneEntity::~CSceneEntity( void ) { @@ -785,7 +855,7 @@ CSceneEntity::~CSceneEntity( void ) //----------------------------------------------------------------------------- // Purpose: Resets time such that the client version of the .vcd is also updated, if appropriate -// Input : t - +// Input : t - // forceClientSync - forces new timestamp down to client .dll via networking //----------------------------------------------------------------------------- void CSceneEntity::SetCurrentTime( float t, bool bForceClientSync ) @@ -798,7 +868,7 @@ void CSceneEntity::SetCurrentTime( float t, bool bForceClientSync ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::UpdateOnRemove( void ) { @@ -812,9 +882,9 @@ void CSceneEntity::UpdateOnRemove( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *soundname - +// Purpose: +// Input : *actor - +// *soundname - // Output : CChoreoScene //----------------------------------------------------------------------------- CChoreoScene *CSceneEntity::GenerateSceneForSound( CBaseFlex *pFlexActor, const char *soundname ) @@ -861,7 +931,7 @@ CChoreoScene *CSceneEntity::GenerateSceneForSound( CBaseFlex *pFlexActor, const // Add to actor actor->AddChannel( channel ); - + // Set us up the eventz event->SetType( CChoreoEvent::SPEAK ); event->SetName( soundname ); @@ -884,7 +954,7 @@ CChoreoScene *CSceneEntity::GenerateSceneForSound( CBaseFlex *pFlexActor, const } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::Activate() { @@ -902,7 +972,7 @@ void CSceneEntity::Activate() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : float //----------------------------------------------------------------------------- float CSceneEntity::GetSoundSystemLatency( void ) @@ -911,14 +981,76 @@ float CSceneEntity::GetSoundSystemLatency( void ) { return m_pcvSndMixahead->GetFloat(); } - + // Assume 100 msec sound system latency return SOUND_SYSTEM_LATENCY_DEFAULT; } - + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// I copied CSceneEntity's PrecacheScene to a unique static function so PrecacheInstancedScene() +// can precache loose scene files without having to use a CSceneEntity. +//----------------------------------------------------------------------------- +void PrecacheChoreoScene( CChoreoScene *scene ) +{ + Assert( scene ); + + // Iterate events and precache necessary resources + for ( int i = 0; i < scene->GetNumEvents(); i++ ) + { + CChoreoEvent *event = scene->GetEvent( i ); + if ( !event ) + continue; + + // load any necessary data + switch (event->GetType() ) + { + default: + break; + case CChoreoEvent::SPEAK: + { + // Defined in SoundEmitterSystem.cpp + // NOTE: The script entries associated with .vcds are forced to preload to avoid + // loading hitches during triggering + CBaseEntity::PrecacheScriptSound( event->GetParameters() ); + + if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && + event->GetNumSlaves() > 0 ) + { + char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ]; + if ( event->GetPlaybackCloseCaptionToken( tok, sizeof( tok ) ) ) + { + CBaseEntity::PrecacheScriptSound( tok ); + } + } + } + break; + case CChoreoEvent::SUBSCENE: + { + // Only allow a single level of subscenes for now + if ( !scene->IsSubScene() ) + { + CChoreoScene *subscene = event->GetSubScene(); + if ( !subscene ) + { + subscene = ChoreoLoadScene( event->GetParameters(), NULL, &g_TokenProcessor, LocalScene_Printf ); + subscene->SetSubScene( true ); + event->SetSubScene( subscene ); + + // Now precache it's resources, if any + PrecacheChoreoScene( subscene ); + } + } + } + break; + } + } +} +#endif + //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - +// Purpose: +// Input : *scene - //----------------------------------------------------------------------------- void CSceneEntity::PrecacheScene( CChoreoScene *scene ) { @@ -943,7 +1075,7 @@ void CSceneEntity::PrecacheScene( CChoreoScene *scene ) // loading hitches during triggering PrecacheScriptSound( event->GetParameters() ); - if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && + if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && event->GetNumSlaves() > 0 ) { char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ]; @@ -976,7 +1108,7 @@ void CSceneEntity::PrecacheScene( CChoreoScene *scene ) } } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::Precache( void ) { @@ -995,9 +1127,9 @@ void CSceneEntity::Precache( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pActor - -// *soundname - +// Purpose: +// Input : *pActor - +// *soundname - //----------------------------------------------------------------------------- void CSceneEntity::GenerateSoundScene( CBaseFlex *pActor, const char *soundname ) { @@ -1007,7 +1139,7 @@ void CSceneEntity::GenerateSoundScene( CBaseFlex *pActor, const char *soundname } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSceneEntity::HasUnplayedSpeech( void ) @@ -1019,7 +1151,7 @@ bool CSceneEntity::HasUnplayedSpeech( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSceneEntity::HasFlexAnimation( void ) @@ -1030,10 +1162,35 @@ bool CSceneEntity::HasFlexAnimation( void ) return false; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CSceneEntity::IsPlayingSpeech( void ) +{ + if ( m_pScene ) + { + float flTime = m_pScene->GetTime(); + for ( int i = 0; i < m_pScene->GetNumEvents(); i++ ) + { + CChoreoEvent *e = m_pScene->GetEvent( i ); + if ( e->GetType() == CChoreoEvent::SPEAK ) + { + if ( /*flTime >= e->GetStartTime() &&*/ flTime <= e->GetEndTime() ) + return true; + } + } + } + + return false; +} +#endif + //----------------------------------------------------------------------------- -// Purpose: -// Output : +// Purpose: +// Output : //----------------------------------------------------------------------------- void CSceneEntity::SetBackground( bool bIsBackground ) @@ -1045,7 +1202,7 @@ void CSceneEntity::SetBackground( bool bIsBackground ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- @@ -1059,7 +1216,7 @@ bool CSceneEntity::IsBackground( void ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::OnRestore() { @@ -1082,7 +1239,7 @@ void CSceneEntity::OnRestore() } OnLoaded(); - + if ( ShouldNetwork() ) { m_nSceneStringIndex = g_pStringTableClientSideChoreoScenes->AddString( CBaseEntity::IsServer(), STRING( m_iszSceneFile ) ); @@ -1154,7 +1311,7 @@ void CSceneEntity::SetRestoring( bool bRestoring ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::Spawn( void ) { @@ -1254,7 +1411,7 @@ void CSceneEntity::PauseThink( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::DispatchPauseScene( CChoreoScene *scene, const char *parameters ) { @@ -1305,9 +1462,9 @@ void CSceneEntity::DispatchPauseScene( CChoreoScene *scene, const char *paramete } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - -// *event - +// Purpose: +// Input : *scene - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchProcessLoop( CChoreoScene *scene, CChoreoEvent *event ) { @@ -1344,8 +1501,8 @@ void CSceneEntity::DispatchProcessLoop( CChoreoScene *scene, CChoreoEvent *event //----------------------------------------------------------------------------- // Purpose: Flag the scene as already "completed" -// Input : *scene - -// *parameters - +// Input : *scene - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStopPoint( CChoreoScene *scene, const char *parameters ) { @@ -1361,7 +1518,7 @@ void CSceneEntity::DispatchStopPoint( CChoreoScene *scene, const char *parameter } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSceneEntity::IsInterruptable() @@ -1370,10 +1527,10 @@ bool CSceneEntity::IsInterruptable() } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - -// *actor - -// *event - +// Purpose: +// Input : *scene - +// *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartInterrupt( CChoreoScene *scene, CChoreoEvent *event ) { @@ -1394,10 +1551,10 @@ void CSceneEntity::DispatchStartInterrupt( CChoreoScene *scene, CChoreoEvent *ev } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - -// *actor - -// *event - +// Purpose: +// Input : *scene - +// *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndInterrupt( CChoreoScene *scene, CChoreoEvent *event ) { @@ -1414,9 +1571,9 @@ void CSceneEntity::DispatchEndInterrupt( CChoreoScene *scene, CChoreoEvent *even } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *event - +// Purpose: +// Input : *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartExpression( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1424,9 +1581,9 @@ void CSceneEntity::DispatchStartExpression( CChoreoScene *scene, CBaseFlex *acto } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *event - +// Purpose: +// Input : *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndExpression( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1434,9 +1591,9 @@ void CSceneEntity::DispatchEndExpression( CChoreoScene *scene, CBaseFlex *actor, } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *event - +// Purpose: +// Input : *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartFlexAnimation( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1444,9 +1601,9 @@ void CSceneEntity::DispatchStartFlexAnimation( CChoreoScene *scene, CBaseFlex *a } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *event - +// Purpose: +// Input : *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndFlexAnimation( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1454,9 +1611,9 @@ void CSceneEntity::DispatchEndFlexAnimation( CChoreoScene *scene, CBaseFlex *act } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *parameters - +// Purpose: +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartGesture( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1464,14 +1621,14 @@ void CSceneEntity::DispatchStartGesture( CChoreoScene *scene, CBaseFlex *actor, if ( !Q_stricmp( event->GetName(), "NULL" ) ) return; - actor->AddSceneEvent( scene, event); + actor->AddSceneEvent( scene, event); } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *parameters - +// Purpose: +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndGesture( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1483,21 +1640,25 @@ void CSceneEntity::DispatchEndGesture( CChoreoScene *scene, CBaseFlex *actor, CC } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *parameters - +// Purpose: +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartGeneric( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { CBaseEntity *pTarget = FindNamedEntity( event->GetParameters2( ) ); +#ifdef MAPBASE + actor->AddSceneEvent( scene, event, pTarget, this ); +#else actor->AddSceneEvent( scene, event, pTarget ); +#endif } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *parameters - +// Purpose: +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndGeneric( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1505,9 +1666,9 @@ void CSceneEntity::DispatchEndGeneric( CChoreoScene *scene, CBaseFlex *actor, CC } //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *actor2 - +// Purpose: +// Input : *actor - +// *actor2 - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartLookAt( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) { @@ -1525,8 +1686,8 @@ void CSceneEntity::DispatchEndLookAt( CChoreoScene *scene, CBaseFlex *actor, CCh // Purpose: Move to spot/actor // FIXME: Need to allow this to take arbitrary amount of time and pause playback // while waiting for actor to move into position -// Input : *actor - -// *parameters - +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartMoveTo( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) { @@ -1540,10 +1701,10 @@ void CSceneEntity::DispatchEndMoveTo( CChoreoScene *scene, CBaseFlex *actor, CCh } //----------------------------------------------------------------------------- -// Purpose: -// Input : *token - -// listener - -// soundorigins - +// Purpose: +// Input : *token - +// listener - +// soundorigins - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool AttenuateCaption( const char *token, const Vector& listener, CUtlVector< Vector >& soundorigins ) @@ -1578,10 +1739,10 @@ bool AttenuateCaption( const char *token, const Vector& listener, CUtlVector< Ve } //----------------------------------------------------------------------------- -// Purpose: -// Input : *event - which event -// player - which recipient -// buf, buflen: where to put the data +// Purpose: +// Input : *event - which event +// player - which recipient +// buf, buflen: where to put the data // Output : Returns true if the sound should be played/prefetched //----------------------------------------------------------------------------- bool CSceneEntity::GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *player, char *buf, size_t buflen, CBaseEntity *pActor ) @@ -1639,7 +1800,7 @@ bool CSceneEntity::GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *play // English sounds always play return true; } - + if ( ismasterevent ) { // Master event sounds always play too (master will be the combined .wav) @@ -1656,8 +1817,8 @@ bool CSceneEntity::GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *play //----------------------------------------------------------------------------- // Purpose: Playback sound file that contains phonemes -// Input : *actor - -// *parameters - +// Input : *actor - +// *parameters - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event, soundlevel_t iSoundlevel ) { @@ -1689,7 +1850,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC { filter.RemoveRecipientByPlayerIndex( playerindex ); } - } + } } float time_in_past = m_flCurrentTime - event->GetStartTime() ; @@ -1704,7 +1865,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC return; } - // Add padding to prevent any other talker talking right after I'm done, because I might + // Add padding to prevent any other talker talking right after I'm done, because I might // be continuing speaking with another scene. float flDuration = event->GetDuration() - time_in_past; @@ -1760,7 +1921,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC speechListSounds[ speechListIndex ].time = gpGlobals->curtime; Q_strncpy( speechListSounds[ speechListIndex ].name, soundname, sizeof( speechListSounds[ 0 ].name ) ); Q_strncpy( speechListSounds[ speechListIndex ].sceneName, ( scene ) ? scene->GetFilename() : "", sizeof( speechListSounds[ 0 ].sceneName ) ); - + speechListIndex++; if ( speechListIndex >= SPEECH_LIST_MAX_SOUNDS ) { @@ -1782,7 +1943,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC EmitSound( filter2, actor->entindex(), es ); actor->AddSceneEvent( scene, event ); } - + // Close captioning only on master token no matter what... if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER ) { @@ -1798,7 +1959,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC CBaseEntity::RemoveRecipientsIfNotCloseCaptioning( filter ); // Certain events are marked "don't attenuate", (breencast), skip those here - if ( !event->IsSuppressingCaptionAttenuation() && + if ( !event->IsSuppressingCaptionAttenuation() && ( filter.GetRecipientCount() > 0 ) ) { int c = filter.GetRecipientCount(); @@ -1847,7 +2008,7 @@ void CSceneEntity::DispatchStartSpeak( CChoreoScene *scene, CBaseFlex *actor, CC byteflags |= CLOSE_CAPTION_GENDER_MALE; } else if ( gender == GENDER_FEMALE ) - { + { byteflags |= CLOSE_CAPTION_GENDER_FEMALE; } @@ -1870,9 +2031,9 @@ void CSceneEntity::DispatchEndSpeak( CChoreoScene *scene, CBaseFlex *actor, CCho //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *actor2 - +// Purpose: +// Input : *actor - +// *actor2 - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartFace( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) { @@ -1882,9 +2043,9 @@ void CSceneEntity::DispatchStartFace( CChoreoScene *scene, CBaseFlex *actor, CBa //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *actor2 - +// Purpose: +// Input : *actor - +// *actor2 - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndFace( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1894,8 +2055,8 @@ void CSceneEntity::DispatchEndFace( CChoreoScene *scene, CBaseFlex *actor, CChor //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - +// Purpose: +// Input : *actor - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1905,8 +2066,8 @@ void CSceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - +// Purpose: +// Input : *actor - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1915,9 +2076,9 @@ void CSceneEntity::DispatchEndSequence( CChoreoScene *scene, CBaseFlex *actor, C //----------------------------------------------------------------------------- // Purpose: NPC can play interstitial vcds (such as responding to the player doing something during a scene) -// Input : *scene - -// *actor - -// *event - +// Input : *scene - +// *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartPermitResponses( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1925,10 +2086,10 @@ void CSceneEntity::DispatchStartPermitResponses( CChoreoScene *scene, CBaseFlex } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - -// *actor - -// *event - +// Purpose: +// Input : *scene - +// *actor - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchEndPermitResponses( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) { @@ -1936,7 +2097,7 @@ void CSceneEntity::DispatchEndPermitResponses( CChoreoScene *scene, CBaseFlex *a } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- float CSceneEntity::EstimateLength( void ) { @@ -1948,7 +2109,7 @@ float CSceneEntity::EstimateLength( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // NOTE: returns false if scene hasn't loaded yet //----------------------------------------------------------------------------- void CSceneEntity::CancelIfSceneInvolvesActor( CBaseEntity *pActor ) @@ -1961,13 +2122,13 @@ void CSceneEntity::CancelIfSceneInvolvesActor( CBaseEntity *pActor ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // NOTE: returns false if scene hasn't loaded yet //----------------------------------------------------------------------------- bool CSceneEntity::InvolvesActor( CBaseEntity *pActor ) { if ( !m_pScene ) - return false; + return false; int i; for ( i = 0 ; i < m_pScene->GetNumActors(); i++ ) @@ -1983,7 +2144,7 @@ bool CSceneEntity::InvolvesActor( CBaseEntity *pActor ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::DoThink( float frametime ) { @@ -2031,12 +2192,12 @@ void CSceneEntity::DoThink( float frametime ) if ( m_pScene->SimulationFinished() ) { OnSceneFinished( false, true ); - + // Stop them from doing anything special ClearSchedules( m_pScene ); } } - else + else { // Drive simulation time for scene SetCurrentTime( m_pScene->GetTime(), true ); @@ -2109,7 +2270,11 @@ void CSceneEntity::InputPitchShiftPlayback( inputdata_t &inputdata ) void CSceneEntity::InputTriggerEvent( inputdata_t &inputdata ) { +#ifdef MAPBASE + CBaseEntity *pActivator = inputdata.pActivator; +#else CBaseEntity *pActivator = this; // at some point, find this from the inputdata +#endif switch ( inputdata.value.Int() ) { case 1: @@ -2163,43 +2328,57 @@ void CSceneEntity::InputTriggerEvent( inputdata_t &inputdata ) } } +struct NPCInterjection +{ + AI_Response *response; + CAI_BaseActor *npc; +}; //----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - +// Purpose: +// Input : &inputdata - //----------------------------------------------------------------------------- void CSceneEntity::InputInterjectResponse( inputdata_t &inputdata ) { // Not currently playing a scene if ( !m_pScene ) + { return; + } - CUtlVector candidates; - - for ( int i = 0 ; i < m_pScene->GetNumActors(); i++ ) + CUtlVector< CAI_BaseActor * > candidates; + int i; + for ( i = 0 ; i < m_pScene->GetNumActors(); i++ ) { CBaseFlex *pTestActor = FindNamedActor( i ); if ( !pTestActor ) continue; - CAI_BaseActor *pBaseActor = dynamic_cast(pTestActor); - if ( !pBaseActor || !pBaseActor->IsAlive() ) + CAI_BaseActor *pBaseActor = dynamic_cast(pTestActor); + if ( !pBaseActor ) + continue; + + if ( !pBaseActor->IsAlive() ) continue; candidates.AddToTail( pBaseActor ); } int c = candidates.Count(); + if ( !c ) + { return; + } + int useIndex = 0; if ( !m_bIsPlayingBack ) { // Use any actor if not playing a scene - // int useIndex = RandomInt( 0, c - 1 ); - Assert( !"m_bIsPlayBack is false and this code does nothing. Should it?"); + useIndex = RandomInt( 0, c - 1 ); } else { +#ifdef NEW_RESPONSE_SYSTEM CUtlString modifiers("scene:"); modifiers += STRING( GetEntityName() ); @@ -2212,15 +2391,19 @@ void CSceneEntity::InputInterjectResponse( inputdata_t &inputdata ) // Try to find the response for this slot. AI_Response response; - bool result = npc->SpeakFindResponse( response, inputdata.value.String(), modifiers.Get() ); + CAI_Concept rrConcept(inputdata.value.String()); + rrConcept.SetSpeaker(npc); + AI_CriteriaSet set; + npc->GatherCriteria(&set, rrConcept, modifiers.Get()); + bool result = npc->FindResponse( response, rrConcept, &set); if ( result ) { - float duration = npc->GetResponseDuration( response ); + float duration = npc->GetResponseDuration( &response ); if ( ( duration > 0.0f ) && npc->PermitResponse( duration ) ) { // If we could look it up, dispatch it and bail. - npc->SpeakDispatchResponse( inputdata.value.String(), response ); + npc->SpeakDispatchResponse( rrConcept, &response, &set); return; } } @@ -2228,9 +2411,163 @@ void CSceneEntity::InputInterjectResponse( inputdata_t &inputdata ) // Remove this entry and look for another one. candidates.FastRemove(slot); } +#else + CUtlVector< NPCInterjection > validResponses; + + char modifiers[ 512 ]; + Q_snprintf( modifiers, sizeof( modifiers ), "scene:%s", STRING( GetEntityName() ) ); + + for ( int i = 0; i < c; i++ ) + { + CAI_BaseActor *npc = candidates[ i ]; + Assert( npc ); + + AI_Response *response = npc->SpeakFindResponse( inputdata.value.String(), modifiers ); + if ( !response ) + continue; + + float duration = npc->GetResponseDuration( response ); + // Couldn't look it up + if ( duration <= 0.0f ) + continue; + + if ( !npc->PermitResponse( duration ) ) + { + delete response; + continue; + } + + // + NPCInterjection inter; + inter.response = response; + inter.npc = npc; + + validResponses.AddToTail( inter ); + } + + int rcount = validResponses.Count(); + if ( rcount >= 1 ) + { + int slot = RandomInt( 0, rcount - 1 ); + + for ( int i = 0; i < rcount; i++ ) + { + NPCInterjection *pInterjection = &validResponses[ i ]; + if ( i == slot ) + { + pInterjection->npc->SpeakDispatchResponse( inputdata.value.String(), pInterjection->response ); + } + else + { + delete pInterjection->response; + } + } + } +#endif + } +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CSceneEntity::SetTarget( int nTarget, string_t pTargetName, CBaseEntity *pActivator, CBaseEntity *pCaller ) +{ + if (/*m_bIsPlayingBack ||*/ !nTarget) + { + return; + } + + switch (nTarget) + { + case 1: m_iszTarget1 = pTargetName; break; + case 2: m_iszTarget2 = pTargetName; break; + case 3: m_iszTarget3 = pTargetName; break; + case 4: m_iszTarget4 = pTargetName; break; + case 5: m_iszTarget5 = pTargetName; break; + case 6: m_iszTarget6 = pTargetName; break; + case 7: m_iszTarget7 = pTargetName; break; + case 8: m_iszTarget8 = pTargetName; break; + } + + // Reset our handle. + // Internal functions set them when they're null anyway. + switch (nTarget) + { + case 1: m_hTarget1 = NULL; break; + case 2: m_hTarget2 = NULL; break; + case 3: m_hTarget3 = NULL; break; + case 4: m_hTarget4 = NULL; break; + case 5: m_hTarget5 = NULL; break; + case 6: m_hTarget6 = NULL; break; + case 7: m_hTarget7 = NULL; break; + case 8: m_hTarget8 = NULL; break; + } + + //CBaseEntity *pTarget = gEntList.FindEntityByName(NULL, pTargetName, this, pActivator, pCaller); + //if (!pTarget) + //{ + // DevWarning("%s (%s) could not find SetTarget entity %s!\n", GetClassname(), GetDebugName(), pTargetName); + // return; + //} + + /* + switch (nTarget) + { + case 1: m_hTarget1 = pTarget; break; + case 2: m_hTarget2 = pTarget; break; + case 3: m_hTarget3 = pTarget; break; + case 4: m_hTarget4 = pTarget; break; + case 5: m_hTarget5 = pTarget; break; + case 6: m_hTarget6 = pTarget; break; + case 7: m_hTarget7 = pTarget; break; + case 8: m_hTarget8 = pTarget; break; } + */ +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CSceneEntity::InputSetTarget1( inputdata_t &inputdata ) +{ + SetTarget(1, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget2( inputdata_t &inputdata ) +{ + SetTarget(2, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget3( inputdata_t &inputdata ) +{ + SetTarget(3, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); } +void CSceneEntity::InputSetTarget4( inputdata_t &inputdata ) +{ + SetTarget(4, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget5( inputdata_t &inputdata ) +{ + SetTarget(5, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget6( inputdata_t &inputdata ) +{ + SetTarget(6, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget7( inputdata_t &inputdata ) +{ + SetTarget(7, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} + +void CSceneEntity::InputSetTarget8( inputdata_t &inputdata ) +{ + SetTarget(8, inputdata.value.StringID(), inputdata.pActivator, inputdata.pCaller); +} +#endif + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CSceneEntity::InputStopWaitingForActor( inputdata_t &inputdata ) @@ -2277,9 +2614,9 @@ bool CSceneEntity::CheckActors() { bShouldWait = true; } - + #ifdef HL2_EPISODIC - // HACK: Alyx cannot play scenes when she's in the middle of transitioning + // HACK: Alyx cannot play scenes when she's in the middle of transitioning if ( pActor->IsInAVehicle() ) { CNPC_Alyx *pAlyx = dynamic_cast(pActor); @@ -2304,22 +2641,46 @@ bool CSceneEntity::CheckActors() return false; } } - } - else if ( m_BusyActor == SCENE_BUSYACTOR_INTERRUPT || m_BusyActor == SCENE_BUSYACTOR_INTERRUPT_CANCEL ) - { - CBaseCombatCharacter *pActor = pTestActor->MyCombatCharacterPointer(); - if ( pActor && !IsInInterruptableScenes( pActor ) ) - { - // One of the actors is in a scene that's not at an interrupt point. - // Wait until the scene finishes or an interrupt point is reached. - m_bWaitingForInterrupt = true; - return false; - } - - if ( m_BusyActor == SCENE_BUSYACTOR_INTERRUPT_CANCEL ) +#ifdef MAPBASE + else if ( pTestActor->IsPlayer() ) { - // Cancel existing scenes - RemoveActorFromScriptedScenes( pActor, false ); + // Blixibon - Player speech handling + CBasePlayer *pPlayer = static_cast(pTestActor); + bool bShouldWait = false; + if ( pPlayer->GetExpresser() && pPlayer->GetExpresser()->IsSpeaking() ) + { + bShouldWait = true; + } + else if ( IsTalkingInAScriptedScene( pPlayer ) ) + { + bShouldWait = true; + } + + if ( bShouldWait ) + { + // One of the actors for this scene is talking already. + // Try again next think. + m_bWaitingForActor = true; + return false; + } + } +#endif + } + else if ( m_BusyActor == SCENE_BUSYACTOR_INTERRUPT || m_BusyActor == SCENE_BUSYACTOR_INTERRUPT_CANCEL ) + { + CBaseCombatCharacter *pActor = pTestActor->MyCombatCharacterPointer(); + if ( pActor && !IsInInterruptableScenes( pActor ) ) + { + // One of the actors is in a scene that's not at an interrupt point. + // Wait until the scene finishes or an interrupt point is reached. + m_bWaitingForInterrupt = true; + return false; + } + + if ( m_BusyActor == SCENE_BUSYACTOR_INTERRUPT_CANCEL ) + { + // Cancel existing scenes + RemoveActorFromScriptedScenes( pActor, false ); } else { @@ -2345,11 +2706,11 @@ void CSceneEntity::PrefetchAnimBlocks( CChoreoScene *scene ) // Build a fast lookup, too CUtlMap< CChoreoActor *, CBaseFlex *> actorMap( 0, 0, DefLessFunc( CChoreoActor * ) ); - - int spew = + + int spew = #if !defined( _RETAIL ) scene_async_prefetch_spew.GetInt(); -#else +#else 0; #endif @@ -2464,7 +2825,7 @@ void CSceneEntity::StartPlayback( void ) m_pScene = LoadScene( STRING( m_iszSceneFile ), this ); if ( !m_pScene ) { - DevMsg( "%s missing from scenes.image\n", STRING( m_iszSceneFile ) ); + ChoreoMsg1( 1, "%s missing from scenes.image\n", STRING( m_iszSceneFile ) ); m_bSceneMissing = true; return; } @@ -2545,16 +2906,16 @@ void CSceneEntity::PrefetchSpeakEventSounds( CUtlSymbolTable& table, CUtlRBTree< // Warning( "Prefetch %s\n", soundname ); - PrefetchScriptSound( soundname ); + PrefetchScriptSound( soundname ); } } //----------------------------------------------------------------------------- -// Purpose: Builds list of sounds sorted by start time for prefetching +// Purpose: Builds list of sounds sorted by start time for prefetching //----------------------------------------------------------------------------- -void CSceneEntity::BuildSortedSpeakEventSoundsPrefetchList( - CChoreoScene *scene, - CUtlSymbolTable& table, +void CSceneEntity::BuildSortedSpeakEventSoundsPrefetchList( + CChoreoScene *scene, + CUtlSymbolTable& table, CUtlRBTree< SpeakEventSound_t >& soundnames, float timeOffset ) { @@ -2574,17 +2935,17 @@ void CSceneEntity::BuildSortedSpeakEventSoundsPrefetchList( break; case CChoreoEvent::SPEAK: { - + // NOTE: The script entries associated with .vcds are forced to preload to avoid // loading hitches during triggering char soundname[ CChoreoEvent::MAX_CCTOKEN_STRING ]; Q_strncpy( soundname, event->GetParameters(), sizeof( soundname ) ); - + if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER ) { event->GetPlaybackCloseCaptionToken( soundname, sizeof( soundname ) ); } - + // In single player, try to use the combined or regular .wav files as needed if ( gpGlobals->maxClients == 1 ) { @@ -2633,7 +2994,7 @@ void CSceneEntity::BuildSortedSpeakEventSoundsPrefetchList( } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::PausePlayback( void ) { @@ -2647,7 +3008,7 @@ void CSceneEntity::PausePlayback( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::ResumePlayback( void ) { @@ -2664,7 +3025,7 @@ void CSceneEntity::ResumePlayback( void ) return; } - // FIXME: Iterate using m_pScene->IterateResumeConditionEvents and + // FIXME: Iterate using m_pScene->IterateResumeConditionEvents and // only resume if the event conditions have all been satisfied // FIXME: Just resume for now @@ -2675,7 +3036,7 @@ void CSceneEntity::ResumePlayback( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::CancelPlayback( void ) { @@ -2709,7 +3070,7 @@ void CSceneEntity::PitchShiftPlayback( float fPitch ) continue; char szBuff[ 256 ]; - + if ( m_pScene->GetPlayingSoundName( szBuff, sizeof( szBuff ) ) ) { CPASAttenuationFilter filter( pTestActor ); @@ -2733,7 +3094,7 @@ void CSceneEntity::QueueResumePlayback( void ) bool bStartedScene = false; // If it has ".vcd" somewhere in the string, try using it as a scene file first - if ( Q_stristr( STRING(m_iszResumeSceneFile), ".vcd" ) ) + if ( Q_stristr( STRING(m_iszResumeSceneFile), ".vcd" ) ) { bStartedScene = InstancedScriptedScene( NULL, STRING(m_iszResumeSceneFile), &m_hWaitingForThisResumeScene, 0, false ) != 0; } @@ -2747,13 +3108,24 @@ void CSceneEntity::QueueResumePlayback( void ) CAI_BaseActor *pBaseActor = dynamic_cast(pActor); if ( pBaseActor ) { +#ifdef NEW_RESPONSE_SYSTEM AI_Response response; - bool result = pBaseActor->SpeakFindResponse( response, STRING(m_iszResumeSceneFile), NULL ); + CAI_Concept rrConcept(STRING(m_iszResumeSceneFile)); + bool result = pBaseActor->FindResponse( response, rrConcept, NULL ); if ( result ) { - const char *szResponse = response.GetResponsePtr(); + const char* szResponse = response.GetResponsePtr(); bStartedScene = InstancedScriptedScene( NULL, szResponse, &m_hWaitingForThisResumeScene, 0, false ) != 0; } +#else + AI_Response *result = pBaseActor->SpeakFindResponse( STRING(m_iszResumeSceneFile), NULL ); + if ( result ) + { + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + bStartedScene = InstancedScriptedScene( NULL, response, &m_hWaitingForThisResumeScene, 0, false ) != 0; + } +#endif } } } @@ -2785,10 +3157,10 @@ bool CSceneEntity::ValidScene() const } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pActor - -// *scene - -// *event - +// Purpose: +// Input : *pActor - +// *scene - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::DispatchStartSubScene( CChoreoScene *scene, CBaseFlex *pActor, CChoreoEvent *event) { @@ -2807,6 +3179,12 @@ void CSceneEntity::DispatchStartSubScene( CChoreoScene *scene, CBaseFlex *pActor if ( subscene ) { +#ifdef MAPBASE + // Somes may not be created with a CSceneEntity as the event callback + if (!scene->GetEventCallbackInterface()) + scene->SetEventCallbackInterface( this ); +#endif + subscene->ResetSimulation(); } } @@ -2814,8 +3192,8 @@ void CSceneEntity::DispatchStartSubScene( CChoreoScene *scene, CBaseFlex *pActor //----------------------------------------------------------------------------- // Purpose: All events are leading edge triggered -// Input : currenttime - -// *event - +// Input : currenttime - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) { @@ -2826,11 +3204,11 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv LocalScene_Printf( "%s : %8.2f: ignored %s\n", STRING( m_iszSceneFile ), currenttime, event->GetDescription() ); return; } - + CBaseFlex *pActor = NULL; CChoreoActor *actor = event->GetActor(); - if ( actor ) + if ( actor && (event->GetType() != CChoreoEvent::SCRIPT) && (event->GetType() != CChoreoEvent::CAMERA) ) { pActor = FindNamedActor( actor ); if (pActor == NULL) @@ -2993,6 +3371,80 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv } } break; + + case CChoreoEvent::CAMERA: + { + // begin the camera shot + const char *pszShotType = event->GetParameters(); + + CBaseEntity *pActor1 = FindNamedEntity( event->GetParameters2( ), pActor ); + CBaseEntity *pActor2 = FindNamedEntity( event->GetParameters3( ), pActor ); + float duration = event->GetDuration(); + + // grab any camera we find in the map + // TODO: find camera that is nearest this scene entity? + CTriggerCamera *pCamera = (CTriggerCamera *)gEntList.FindEntityByClassname( NULL, "point_viewcontrol" ); + + if ( !pCamera ) + { + Warning( "CSceneEntity %s unable to find a camera (point_viewcontrol) in this map!\n", STRING(GetEntityName()) ); + } + else + { + pCamera->StartCameraShot( pszShotType, this, pActor1, pActor2, duration ); + } + } + break; + + case CChoreoEvent::SCRIPT: + { + // NOTE: this is only used by auto-generated vcds to embed script commands to map entities. + + // vscript call - param1 is entity name, param2 is function name, param3 is function parameter string + // calls a vscript function defined on the scope of the named CBaseEntity object/actor. + // script call is of the format FunctionName(pActor, pThisSceneEntity, pszScriptParameters, duration) + const char *pszActorName = event->GetParameters(); + const char *pszFunctionName = event->GetParameters2(); + const char *pszScriptParameters = event->GetParameters3(); + + float duration = event->GetDuration(); + + // TODO: should be new method CBaseEntity::CallScriptFunctionParams() + CBaseEntity *pEntity = (CBaseEntity *)gEntList.FindEntityByName( NULL, pszActorName ); + + //START_VMPROFILE + if ( !pEntity ) + { + Warning( "CSceneEntity::SCRIPT event - unable to find entity named '%s' in this map!\n", pszActorName ); + } + else + { + + if( !pEntity->ValidateScriptScope() ) + { + ChoreoMsg(1, "\n***\nCChoreoEvent::SCRIPT - FAILED to create private ScriptScope. ABORTING script call\n***\n"); + break; + } + + HSCRIPT hFunc = pEntity->m_ScriptScope.LookupFunction( pszFunctionName ); + + if( hFunc ) + { + pEntity->m_ScriptScope.Call( hFunc, NULL, ToHScript(this), pszScriptParameters, duration ); + pEntity->m_ScriptScope.ReleaseFunction( hFunc ); + + //UPDATE_VMPROFILE + } + else + { + Warning("CSceneEntity::SCRIPT event - '%s' entity has no script function '%s' defined!\n", pszActorName,pszFunctionName); + } + } + + } + break; + + case CChoreoEvent::FIRETRIGGER: { if ( IsMultiplayer() ) @@ -3109,7 +3561,10 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv if ( IsMultiplayer() ) break; - DispatchStartPermitResponses( scene, pActor, event ); + if ( pActor ) + { + DispatchStartPermitResponses( scene, pActor, event ); + } } break; default: @@ -3122,9 +3577,9 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv } //----------------------------------------------------------------------------- -// Purpose: -// Input : currenttime - -// *event - +// Purpose: +// Input : currenttime - +// *event - //----------------------------------------------------------------------------- void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) { @@ -3201,6 +3656,19 @@ void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEven } } break; + + case CChoreoEvent::CAMERA: + { + // call the end of camera or call a dispatch function + } + break; + + case CChoreoEvent::SCRIPT: + { + // call the end of script or call a dispatch function + } + break; + case CChoreoEvent::SEQUENCE: { if ( pActor ) @@ -3254,7 +3722,10 @@ void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEven if ( IsMultiplayer() ) break; - DispatchEndPermitResponses( scene, pActor, event ); + if ( pActor ) + { + DispatchEndPermitResponses( scene, pActor, event ); + } } break; default: @@ -3266,7 +3737,7 @@ void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEven //----------------------------------------------------------------------------- // Purpose: Only spew one time per missing scene!!! -// Input : *scenename - +// Input : *scenename - //----------------------------------------------------------------------------- void MissingSceneWarning( char const *scenename ) { @@ -3285,8 +3756,8 @@ bool CSceneEntity::ShouldNetwork() const { if ( m_bMultiplayer ) { - if ( m_pScene && - ( m_pScene->HasEventsOfType( CChoreoEvent::FLEXANIMATION ) || + if ( m_pScene && + ( m_pScene->HasEventsOfType( CChoreoEvent::FLEXANIMATION ) || m_pScene->HasEventsOfType( CChoreoEvent::EXPRESSION )|| m_pScene->HasEventsOfType( CChoreoEvent::GESTURE ) || m_pScene->HasEventsOfType( CChoreoEvent::SEQUENCE ) ) ) @@ -3296,8 +3767,8 @@ bool CSceneEntity::ShouldNetwork() const } else { - if ( m_pScene && - ( m_pScene->HasEventsOfType( CChoreoEvent::FLEXANIMATION ) || + if ( m_pScene && + ( m_pScene->HasEventsOfType( CChoreoEvent::FLEXANIMATION ) || m_pScene->HasEventsOfType( CChoreoEvent::EXPRESSION ) ) ) { return true; @@ -3309,7 +3780,7 @@ bool CSceneEntity::ShouldNetwork() const CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallback *pCallback ) { - DevMsg( 2, "Blocking load of scene from '%s'\n", filename ); + ChoreoMsg1( 2, "Blocking load of scene from '%s'\n", filename ); char loadfile[MAX_PATH]; Q_strncpy( loadfile, filename, sizeof( loadfile ) ); @@ -3317,7 +3788,46 @@ CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallbac Q_FixSlashes( loadfile ); // binary compiled vcd - void *pBuffer; + void *pBuffer = NULL; +#ifdef MAPBASE + // + // Raw scene file support + // + CChoreoScene *pScene; + int fileSize; + + // First, check if it's in scenes.image... + if ( CopySceneFileIntoMemory( loadfile, &pBuffer, &fileSize ) ) + { + pScene = new CChoreoScene( NULL ); + CUtlBuffer buf( pBuffer, fileSize, CUtlBuffer::READ_ONLY ); + if ( !pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) ) + { + Warning( "CSceneEntity::LoadScene: Unable to load binary scene '%s'\n", loadfile ); + delete pScene; + pScene = NULL; + } + } + // Next, check if it's a loose file... + else if (filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true )) + { + g_TokenProcessor.SetBuffer((char*)pBuffer); + pScene = ChoreoLoadScene( loadfile, NULL, &g_TokenProcessor, LocalScene_Printf ); + g_TokenProcessor.SetBuffer(NULL); + } + // Okay, it's definitely missing. + else + { + MissingSceneWarning( loadfile ); + pScene = NULL; + } + + if (pScene) + { + pScene->SetPrintFunc( LocalScene_Printf ); + pScene->SetEventCallbackInterface( pCallback ); + } +#else int fileSize; if ( !CopySceneFileIntoMemory( loadfile, &pBuffer, &fileSize ) ) { @@ -3338,6 +3848,7 @@ CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallbac pScene->SetPrintFunc( LocalScene_Printf ); pScene->SetEventCallbackInterface( pCallback ); } +#endif FreeSceneFileMemory( pBuffer ); return pScene; @@ -3349,7 +3860,7 @@ CChoreoScene *BlockingLoadScene( const char *filename ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::UnloadScene( void ) { @@ -3363,7 +3874,7 @@ void CSceneEntity::UnloadScene( void ) if ( !pTestActor ) continue; - + pTestActor->RemoveChoreoScene( m_pScene ); } } @@ -3374,7 +3885,7 @@ void CSceneEntity::UnloadScene( void ) //----------------------------------------------------------------------------- // Purpose: Called every frame that an event is active (Start/EndEvent as also // called) -// Input : *event - +// Input : *event - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CSceneEntity::ProcessEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) @@ -3391,7 +3902,7 @@ void CSceneEntity::ProcessEvent( float currenttime, CChoreoScene *scene, CChoreo if ( subscene->SimulationFinished() ) return; - + // Have subscenes think for appropriate time subscene->Think( m_flFrameTime ); } @@ -3400,7 +3911,7 @@ void CSceneEntity::ProcessEvent( float currenttime, CChoreoScene *scene, CChoreo default: break; } - + return; } @@ -3408,7 +3919,7 @@ void CSceneEntity::ProcessEvent( float currenttime, CChoreoScene *scene, CChoreo //----------------------------------------------------------------------------- // Purpose: Called for events that are part of a pause condition -// Input : *event - +// Input : *event - // Output : Returns true on event completed, false on non-completion. //----------------------------------------------------------------------------- bool CSceneEntity::CheckEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) @@ -3439,14 +3950,14 @@ bool CSceneEntity::CheckEvent( float currenttime, CChoreoScene *scene, CChoreoEv } break; } - + return true; } //----------------------------------------------------------------------------- // Purpose: Get a sticky version of a named actor -// Input : CChoreoActor +// Input : CChoreoActor // Output : CBaseFlex //----------------------------------------------------------------------------- @@ -3471,7 +3982,7 @@ CBaseFlex *CSceneEntity::FindNamedActor( int index ) CChoreoActor *pChoreoActor = m_pScene->GetActor( index ); if ( !pChoreoActor ) return NULL; - + pActor = FindNamedActor( pChoreoActor->GetName() ); if (pActor) @@ -3487,7 +3998,7 @@ CBaseFlex *CSceneEntity::FindNamedActor( int index ) //----------------------------------------------------------------------------- // Purpose: Get a sticky version of a named actor -// Input : CChoreoActor +// Input : CChoreoActor // Output : CBaseFlex //----------------------------------------------------------------------------- @@ -3505,7 +4016,7 @@ CBaseFlex *CSceneEntity::FindNamedActor( CChoreoActor *pChoreoActor ) //----------------------------------------------------------------------------- // Purpose: Search for an actor by name, make sure it can do face poses -// Input : *name - +// Input : *name - // Output : CBaseFlex //----------------------------------------------------------------------------- CBaseFlex *CSceneEntity::FindNamedActor( const char *name ) @@ -3531,7 +4042,7 @@ CBaseFlex *CSceneEntity::FindNamedActor( const char *name ) //----------------------------------------------------------------------------- // Purpose: Find an entity specified by a target name -// Input : *name - +// Input : *name - // Output : CBaseEntity //----------------------------------------------------------------------------- CBaseEntity *CSceneEntity::FindNamedTarget( string_t iszTarget, bool bBaseFlexOnly ) @@ -3671,7 +4182,7 @@ class CSceneFindNearestMarkFilter : public IEntityFindFilter m_pNearestToActor = pEntity; m_flNearestToActor = dist2; } - // find that node that's closest to both, but the distance to it from the actor isn't farther than + // find that node that's closest to both, but the distance to it from the actor isn't farther than // the distance to the second node. This should keep the actor from walking past their point of interest if (dist1 <= m_flMaxSegmentDistance && dist2 <= m_flMaxSegmentDistance && dist2 < m_flNearestToTarget) { @@ -3683,8 +4194,8 @@ class CSceneFindNearestMarkFilter : public IEntityFindFilter return false; } - CBaseEntity *GetFilterResult( void ) - { + CBaseEntity *GetFilterResult( void ) + { if (m_pNearestToTarget) return m_pNearestToTarget; return m_pNearestToActor; @@ -3703,7 +4214,7 @@ class CSceneFindNearestMarkFilter : public IEntityFindFilter //----------------------------------------------------------------------------- // Purpose: Search for an actor by name, make sure it can do face poses -// Input : *name - +// Input : *name - // Output : CBaseFlex //----------------------------------------------------------------------------- CBaseEntity *CSceneEntity::FindNamedEntity( const char *name, CBaseEntity *pActor, bool bBaseFlexOnly, bool bUseClear ) @@ -3792,7 +4303,7 @@ CBaseEntity *CSceneEntity::FindNamedEntity( const char *name, CBaseEntity *pActo { entity = pFilter->GetFilterResult(); } - } + } else { // search for up to 32 entities with the same name and choose one randomly @@ -3823,10 +4334,82 @@ CBaseEntity *CSceneEntity::FindNamedEntity( const char *name, CBaseEntity *pActo return entity; } +#ifdef MAPBASE +const char *GetFirstSoundInScene(const char *pszScene) +{ + const char *soundName = NULL; + SceneCachedData_t sceneData; + if ( scenefilecache->GetSceneCachedData( pszScene, &sceneData ) ) + { + if ( sceneData.numSounds > 0 ) + { + // 0 is the first index...right? + short stringId = scenefilecache->GetSceneCachedSound( sceneData.sceneId, 0 ); + + // Trust that it's been precached + soundName = scenefilecache->GetSceneString( stringId ); + } + } + else + { + void *pBuffer = NULL; + if (filesystem->ReadFileEx( pszScene, "MOD", &pBuffer, true )) + { + g_TokenProcessor.SetBuffer((char*)pBuffer); + CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf ); + g_TokenProcessor.SetBuffer(NULL); + if (pScene) + { + for (int i = 0; i < pScene->GetNumEvents(); i++) + { + CChoreoEvent *pEvent = pScene->GetEvent(i); + + if (pEvent->GetType() == CChoreoEvent::SPEAK) + { + soundName = pEvent->GetParameters(); + break; + } + } + } + } + FreeSceneFileMemory( pBuffer ); + } + + return soundName; +} + +const char *GetFirstSoundInScene(CChoreoScene *scene) +{ + for ( int i = 0; i < scene->GetNumEvents(); i++ ) + { + CChoreoEvent *pEvent = scene->GetEvent( i ); + + if (pEvent->GetType() == CChoreoEvent::SPEAK) + return pEvent->GetParameters(); + } + + return NULL; +} + +CBaseEntity *UTIL_FindNamedSceneEntity(const char *name, CBaseEntity *pActor, CSceneEntity *scene, bool bBaseFlexOnly, bool bUseClear) +{ + if (scene) + { + CBaseEntity *pEnt = scene->FindNamedEntity(name, pActor, bBaseFlexOnly, bUseClear); + return pEnt; + } + else + { + //Warning("SCENE NOT FOUND!\n"); + return NULL; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Search for an actor by name, make sure it can do face poses -// Input : *name - +// Input : *name - // Output : CBaseFlex //----------------------------------------------------------------------------- CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity *pActor, bool bBaseFlexOnly, bool bUseClear, const char *pszSecondary ) @@ -3836,7 +4419,7 @@ CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity if ( !stricmp( name, "!activator" ) ) { return m_hActivator; - } + } else if ( !stricmp( name, "Player" ) || !stricmp( name, "!player" )) { entity = ( gpGlobals->maxClients == 1 ) ? ( CBaseEntity * )UTIL_GetLocalPlayer() : NULL; @@ -3903,7 +4486,7 @@ CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity entity = pFilter->GetFilterResult(); } } - } + } else { // search for up to 32 entities with the same name and choose one randomly @@ -3927,6 +4510,55 @@ CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity } +HSCRIPT CSceneEntity::ScriptFindNamedEntity(const char* name) +{ + return ToHScript(FindNamedEntity(name, NULL, false, false)); +} + +//----------------------------------------------------------------------------- +// Purpose: vscript - create a scene directly from a buffer containing +// a vcd description, and load it into the scene entity. +//----------------------------------------------------------------------------- +bool CSceneEntity::ScriptLoadSceneFromString(const char* pszFilename, const char* pszData) +{ + CChoreoScene* pScene = new CChoreoScene(NULL); + + // CSceneTokenProcessor SceneTokenProcessor; + // SceneTokenProcessor.SetBuffer( pszData ); + g_TokenProcessor.SetBuffer((char*)pszData); + + if (!pScene->ParseFromBuffer(pszFilename, &g_TokenProcessor)) //&SceneTokenProcessor ) ) + { + Warning("CSceneEntity::LoadSceneFromString: Unable to parse scene data '%s'\n", pszFilename); + delete pScene; + pScene = NULL; + } + else + { + pScene->SetPrintFunc(LocalScene_Printf); + pScene->SetEventCallbackInterface(this); + + + // precache all sounds for the newly constructed scene + PrecacheScene(pScene); + } + + g_TokenProcessor.SetBuffer(NULL); + + if (pScene != NULL) + { + // release prior scene if present + UnloadScene(); + m_pScene = pScene; + return true; + } + else + { + return false; + } +} + + //----------------------------------------------------------------------------- // Purpose: Remove all "scene" expressions from all actors in this scene //----------------------------------------------------------------------------- @@ -4042,7 +4674,7 @@ void CSceneEntity::ClearSchedules( CChoreoScene *scene ) //----------------------------------------------------------------------------- // Purpose: If we are currently interruptable, pause this scene and wait for the other // scene to finish -// Input : *otherScene - +// Input : *otherScene - //----------------------------------------------------------------------------- bool CSceneEntity::InterruptThisScene( CSceneEntity *otherScene ) { @@ -4094,7 +4726,7 @@ static ConCommand interruptscene( "int", scene_interrupt, "interrupt scene 1 wit */ //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::CheckInterruptCompletion() { @@ -4102,7 +4734,7 @@ void CSceneEntity::CheckInterruptCompletion() return; // If the interruptor goes away it's the same as having that scene finish up... - if ( m_hInterruptScene != NULL && + if ( m_hInterruptScene != NULL && !m_bInterruptSceneFinished ) { return; @@ -4115,7 +4747,7 @@ void CSceneEntity::CheckInterruptCompletion() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::ClearInterrupt() { @@ -4126,7 +4758,7 @@ void CSceneEntity::ClearInterrupt() //----------------------------------------------------------------------------- // Purpose: Another scene is asking us to notify upon completion -// Input : *notify - +// Input : *notify - //----------------------------------------------------------------------------- void CSceneEntity::RequestCompletionNotification( CSceneEntity *notify ) { @@ -4141,7 +4773,7 @@ void CSceneEntity::RequestCompletionNotification( CSceneEntity *notify ) //----------------------------------------------------------------------------- // Purpose: An interrupt scene has finished or been canceled, we can resume once we pick up this state in CheckInterruptCompletion -// Input : *interruptor - +// Input : *interruptor - //----------------------------------------------------------------------------- void CSceneEntity::NotifyOfCompletion( CSceneEntity *interruptor ) { @@ -4153,7 +4785,7 @@ void CSceneEntity::NotifyOfCompletion( CSceneEntity *interruptor ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneEntity::AddListManager( CSceneListManager *pManager ) { @@ -4257,7 +4889,7 @@ void CSceneEntity::OnSceneFinished( bool canceled, bool fireoutput ) m_bIsPlayingBack = false; m_bPaused = false; SetCurrentTime( 0.0f, false ); - + // Clear interrupt state if we were interrupted for some reason ClearInterrupt(); @@ -4266,6 +4898,33 @@ void CSceneEntity::OnSceneFinished( bool canceled, bool fireoutput ) m_OnCompletion.FireOutput( this, this, 0 ); } +#ifdef NEW_RESPONSE_SYSTEM + { + CBaseFlex *pFlex = FindNamedActor( 0 ) ; + if ( pFlex ) + { +#ifdef MAPBASE + CBasePlayer *pAsPlayer = ToBasePlayer(pFlex); +#else + CBaseMultiplayerPlayer *pAsPlayer = dynamic_cast(pFlex); +#endif + if (pAsPlayer) + { + CAI_Expresser *pExpresser = pAsPlayer->GetExpresser(); +#ifdef MAPBASE + if (pExpresser) +#endif + pExpresser->OnSpeechFinished(); + } + else if ( CAI_BaseActor *pActor = dynamic_cast( pFlex ) ) + { + CAI_Expresser *pExpresser = pActor->GetExpresser(); + pExpresser->OnSpeechFinished(); + } + } + } +#endif + // Put face back in neutral pose ClearSceneEvents( m_pScene, canceled ); @@ -4350,16 +5009,54 @@ void CSceneEntity::SetRecipientFilter( IRecipientFilter *filter ) } } +//----------------------------------------------------------------------------- +// Purpose: Adds a player (by index) to the recipient filter +//----------------------------------------------------------------------------- +void CSceneEntity::AddBroadcastTeamTarget(int nTeamIndex) +{ + if (m_pRecipientFilter == NULL) + { + CRecipientFilter filter; + SetRecipientFilter(&filter); + } + + CTeam* pTeam = GetGlobalTeam(nTeamIndex); + Assert(pTeam); + if (pTeam == NULL) + return; + + m_pRecipientFilter->AddRecipientsByTeam(pTeam); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes a player (by index) from the recipient filter +//----------------------------------------------------------------------------- +void CSceneEntity::RemoveBroadcastTeamTarget(int nTeamIndex) +{ + if (m_pRecipientFilter == NULL) + { + CRecipientFilter filter; + SetRecipientFilter(&filter); + } + + CTeam* pTeam = GetGlobalTeam(nTeamIndex); + Assert(pTeam); + if (pTeam == NULL) + return; + + m_pRecipientFilter->RemoveRecipientsByTeam(pTeam); +} + //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Input : // Output : //----------------------------------------------------------------------------- class CInstancedSceneEntity : public CSceneEntity { DECLARE_DATADESC(); - DECLARE_CLASS( CInstancedSceneEntity, CSceneEntity ); + DECLARE_CLASS( CInstancedSceneEntity, CSceneEntity ); public: EHANDLE m_hOwner; bool m_bHadOwner; @@ -4380,34 +5077,34 @@ class CInstancedSceneEntity : public CSceneEntity virtual void OnLoaded(); virtual void DispatchStartMoveTo( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) - { - if (PassThrough( actor )) BaseClass::DispatchStartMoveTo( scene, actor, actor2, event ); + { + if (PassThrough( actor )) BaseClass::DispatchStartMoveTo( scene, actor, actor2, event ); }; - virtual void DispatchEndMoveTo( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) - { - if (PassThrough( actor )) BaseClass::DispatchEndMoveTo( scene, actor, event ); + virtual void DispatchEndMoveTo( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) + { + if (PassThrough( actor )) BaseClass::DispatchEndMoveTo( scene, actor, event ); }; - virtual void DispatchStartFace( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) - { - if (PassThrough( actor )) BaseClass::DispatchStartFace( scene, actor, actor2, event ); + virtual void DispatchStartFace( CChoreoScene *scene, CBaseFlex *actor, CBaseEntity *actor2, CChoreoEvent *event ) + { + if (PassThrough( actor )) BaseClass::DispatchStartFace( scene, actor, actor2, event ); }; - virtual void DispatchEndFace( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) - { - if (PassThrough( actor )) BaseClass::DispatchEndFace( scene, actor, event ); + virtual void DispatchEndFace( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) + { + if (PassThrough( actor )) BaseClass::DispatchEndFace( scene, actor, event ); }; - virtual void DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) - { + virtual void DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) + { if ( IsMultiplayer() ) { BaseClass::DispatchStartSequence( scene, actor, event ); } }; virtual void DispatchEndSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event ) - { + { if ( IsMultiplayer() ) { BaseClass::DispatchEndSequence( scene, actor, event ); @@ -4476,7 +5173,7 @@ float InstancedScriptedScene( CBaseFlex *pActor, const char *pszScene, EHANDLE * pScene->SetBackground( bIsBackground ); pScene->SetRecipientFilter( filter ); - + if ( response ) { float flPreDelay = response->GetPreDelay(); @@ -4503,13 +5200,19 @@ float InstancedScriptedScene( CBaseFlex *pActor, const char *pszScene, EHANDLE * } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pActor - -// *soundnmame - -// *phSceneEnt - +// Purpose: +// Input : *pActor - +// *soundnmame - +// *phSceneEnt - // Output : float //----------------------------------------------------------------------------- +#ifdef MAPBASE +float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, const char *soundname, EHANDLE *phSceneEnt, + float flPostDelay, bool bIsBackground, AI_Response *response, + bool bMultiplayer, IRecipientFilter *filter /* = NULL */ ) +#else float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt /*= NULL*/ ) +#endif { if ( !pActor ) { @@ -4527,10 +5230,38 @@ float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname pScene->GenerateSoundScene( pActor, soundname ); +#ifdef MAPBASE + pScene->m_bMultiplayer = bMultiplayer; + pScene->SetPostSpeakDelay( flPostDelay ); + DispatchSpawn( pScene ); + pScene->Activate(); + pScene->m_bIsBackground = bIsBackground; + + pScene->SetBackground( bIsBackground ); + pScene->SetRecipientFilter( filter ); + + if ( response ) + { + float flPreDelay = response->GetPreDelay(); + if ( flPreDelay ) + { + pScene->SetPreDelay( flPreDelay ); + } + } +#else pScene->Spawn(); pScene->Activate(); +#endif pScene->StartPlayback(); +#ifdef MAPBASE + if ( response ) + { + // If the response wants us to abort on NPC state switch, remember that + pScene->SetBreakOnNonIdle( response->ShouldBreakOnNonIdle() ); + } +#endif + if ( phSceneEnt ) { *phSceneEnt = pScene; @@ -4554,8 +5285,8 @@ void StopScriptedScene( CBaseFlex *pActor, EHANDLE hSceneEnt ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pszScene - +// Purpose: +// Input : *pszScene - // Output : float //----------------------------------------------------------------------------- float GetSceneDuration( char const *pszScene ) @@ -4572,8 +5303,36 @@ float GetSceneDuration( char const *pszScene ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pszScene - +// Purpose: +// Input : *pszScene - +// Output : float +//----------------------------------------------------------------------------- +float GetSceneSpeechDuration( char const* pszScene ) +{ + float flSecs = 0.0f; + + CChoreoScene* pScene = CSceneEntity::LoadScene( pszScene, nullptr ); + if (pScene) + { + for (int i = pScene->GetNumEvents() - 1; i >= 0; i--) + { + CChoreoEvent* pEvent = pScene->GetEvent( i ); + + if (pEvent->GetType() == CChoreoEvent::SPEAK) + { + flSecs = pEvent->GetStartTime() + pEvent->GetDuration(); + break; + } + } + delete pScene; + } + + return flSecs; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pszScene - // Output : int //----------------------------------------------------------------------------- int GetSceneSpeechCount( char const *pszScene ) @@ -4583,17 +5342,64 @@ int GetSceneSpeechCount( char const *pszScene ) { return cachedData.numSounds; } +#ifdef MAPBASE + else + { + void *pBuffer = NULL; + int iNumSounds = 0; + if (filesystem->ReadFileEx( pszScene, "MOD", &pBuffer, true )) + { + g_TokenProcessor.SetBuffer((char*)pBuffer); + CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf ); + g_TokenProcessor.SetBuffer(NULL); + if (pScene) + { + for (int i = 0; i < pScene->GetNumEvents(); i++) + { + CChoreoEvent *pEvent = pScene->GetEvent(i); + + if (pEvent->GetType() == CChoreoEvent::SPEAK) + iNumSounds++; + } + } + } + + FreeSceneFileMemory( pBuffer ); + + return iNumSounds; + } +#endif return 0; } +HSCRIPT ScriptCreateSceneEntity( const char* pszScene ) +{ + if ( IsEntityCreationAllowedInScripts() == false ) + { + Warning( "VScript error: A script attempted to create a scene entity mid-game. Entity creation from scripts is only allowed during map init.\n" ); + return NULL; + } + + g_pScriptVM->RegisterClass( GetScriptDescForClass( CSceneEntity ) ); + CSceneEntity *pScene = (CSceneEntity *)CBaseEntity::CreateNoSpawn( "logic_choreographed_scene", vec3_origin, vec3_angle ); + + if ( pScene ) + { + pScene->m_iszSceneFile = AllocPooledString( pszScene ); + DispatchSpawn( pScene ); + } + + return ToHScript( pScene ); +} + //----------------------------------------------------------------------------- // Purpose: Used for precaching instanced scenes -// Input : *pszScene - +// Input : *pszScene - //----------------------------------------------------------------------------- void PrecacheInstancedScene( char const *pszScene ) { static int nMakingReslists = -1; - + if ( nMakingReslists == -1 ) { nMakingReslists = CommandLine()->FindParm( "-makereslists" ) > 0 ? 1 : 0; @@ -4609,12 +5415,33 @@ void PrecacheInstancedScene( char const *pszScene ) SceneCachedData_t sceneData; if ( !scenefilecache->GetSceneCachedData( pszScene, &sceneData ) ) { +#ifdef MAPBASE + char loadfile[MAX_PATH]; + Q_strncpy( loadfile, pszScene, sizeof( loadfile ) ); + Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) ); + Q_FixSlashes( loadfile ); + + // Attempt to precache manually + void *pBuffer = NULL; + if (filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true )) + { + g_TokenProcessor.SetBuffer((char*)pBuffer); + CChoreoScene *pScene = ChoreoLoadScene( loadfile, NULL, &g_TokenProcessor, LocalScene_Printf ); + if (pScene) + { + PrecacheChoreoScene(pScene); + } + g_TokenProcessor.SetBuffer(NULL); + } + FreeSceneFileMemory( pBuffer ); +#else // Scenes are sloppy and don't always exist. // A scene that is not in the pre-built cache image, but on disk, is a true error. if ( developer.GetInt() && ( IsX360() && ( g_pFullFileSystem->GetDVDMode() != DVDMODE_STRICT ) && g_pFullFileSystem->FileExists( pszScene, "GAME" ) ) ) { Warning( "PrecacheInstancedScene: Missing scene '%s' from scene image cache.\nRebuild scene image cache!\n", pszScene ); } +#endif } else { @@ -4629,7 +5456,7 @@ void PrecacheInstancedScene( char const *pszScene ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CInstancedSceneEntity::StartPlayback( void ) { @@ -4693,7 +5520,7 @@ void CInstancedSceneEntity::DoThink( float frametime ) //----------------------------------------------------------------------------- // Purpose: Search for an actor by name, make sure it can do face poses -// Input : *name - +// Input : *name - // Output : CBaseFlex //----------------------------------------------------------------------------- CBaseFlex *CInstancedSceneEntity::FindNamedActor( const char *name ) @@ -4715,7 +5542,7 @@ CBaseFlex *CInstancedSceneEntity::FindNamedActor( const char *name ) //----------------------------------------------------------------------------- // Purpose: Search for an actor by name, make sure it can do face poses -// Input : *name - +// Input : *name - // Output : CBaseFlex //----------------------------------------------------------------------------- CBaseEntity *CInstancedSceneEntity::FindNamedEntity( const char *name ) @@ -4770,7 +5597,7 @@ bool CInstancedSceneEntity::PassThrough( CBaseFlex *actor ) CAI_ScheduleBits testBits; myNpc->GetCurSchedule()->GetInterruptMask( &testBits ); - if (testBits.IsBitSet( COND_IDLE_INTERRUPT )) + if (testBits.IsBitSet( COND_IDLE_INTERRUPT )) { return true; } @@ -4800,7 +5627,7 @@ void CInstancedSceneEntity::OnRestore() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- float CInstancedSceneEntity::EstimateLength( void ) { @@ -4812,6 +5639,15 @@ void CInstancedSceneEntity::OnLoaded() { BaseClass::OnLoaded(); SetBackground( m_bIsBackground ); + +#ifdef MAPBASE + // It looks like !Target1 in those default NPC scenes was a freaking lie. + if (m_hOwner) + { + m_hTarget1 = m_hOwner; + m_iszTarget1 = m_hOwner->GetEntityName(); + } +#endif } bool g_bClientFlex = true; @@ -4819,7 +5655,7 @@ bool g_bClientFlex = true; LINK_ENTITY_TO_CLASS( scene_manager, CSceneManager ); //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneManager::Think() { @@ -4871,7 +5707,7 @@ void CSceneManager::Think() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneManager::ClearAllScenes() { @@ -4879,13 +5715,13 @@ void CSceneManager::ClearAllScenes() } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - +// Purpose: +// Input : *scene - //----------------------------------------------------------------------------- void CSceneManager::AddSceneEntity( CSceneEntity *scene ) { CHandle< CSceneEntity > h; - + h = scene; // Already added/activated @@ -4898,21 +5734,21 @@ void CSceneManager::AddSceneEntity( CSceneEntity *scene ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *scene - +// Purpose: +// Input : *scene - //----------------------------------------------------------------------------- void CSceneManager::RemoveSceneEntity( CSceneEntity *scene ) { CHandle< CSceneEntity > h; - + h = scene; m_ActiveScenes.FindAndRemove( h ); } //----------------------------------------------------------------------------- -// Purpose: -// Input : *player - +// Purpose: +// Input : *player - //----------------------------------------------------------------------------- void CSceneManager::OnClientActive( CBasePlayer *player ) { @@ -4929,7 +5765,7 @@ void CSceneManager::OnClientActive( CBasePlayer *player ) continue; CPASAttenuationFilter filter( sound->actor ); - + EmitSound_t es; es.m_nChannel = CHAN_VOICE; es.m_flVolume = 1; @@ -4951,9 +5787,8 @@ void CSceneManager::RemoveScenesInvolvingActor( CBaseFlex *pActor ) if ( !pActor ) return; - // This loop can remove items from m_ActiveScenes array, so loop through backwards. int c = m_ActiveScenes.Count(); - for ( int i = c - 1 ; i >= 0; --i ) + for ( int i = 0; i < c; i++ ) { CSceneEntity *pScene = m_ActiveScenes[ i ].Get(); if ( !pScene ) @@ -4999,9 +5834,9 @@ void CSceneManager::RemoveActorFromScenes( CBaseFlex *pActor, bool bInstancedOnl { continue; } - + // If only stopping instanced scenes, then skip it if it can't cast to an instanced scene - if ( bInstancedOnly && + if ( bInstancedOnly && ( dynamic_cast< CInstancedSceneEntity * >( pScene ) == NULL ) ) { continue; @@ -5040,7 +5875,7 @@ void CSceneManager::PauseActorsScenes( CBaseFlex *pActor, bool bInstancedOnly ) } // If only stopping instanced scenes, then skip it if it can't cast to an instanced scene - if ( bInstancedOnly && + if ( bInstancedOnly && ( dynamic_cast< CInstancedSceneEntity * >( pScene ) == NULL ) ) { continue; @@ -5097,7 +5932,7 @@ void CSceneManager::ResumeActorsScenes( CBaseFlex *pActor, bool bInstancedOnly } // If only stopping instanced scenes, then skip it if it can't cast to an instanced scene - if ( bInstancedOnly && + if ( bInstancedOnly && ( dynamic_cast< CInstancedSceneEntity * >( pScene ) == NULL ) ) { continue; @@ -5128,7 +5963,7 @@ void CSceneManager::QueueActorsScenesToResume( CBaseFlex *pActor, bool bInstance } // If only stopping instanced scenes, then skip it if it can't cast to an instanced scene - if ( bInstancedOnly && + if ( bInstancedOnly && ( dynamic_cast< CInstancedSceneEntity * >( pScene ) == NULL ) ) { continue; @@ -5157,7 +5992,7 @@ bool CSceneManager::IsRunningScriptedScene( CBaseFlex *pActor, bool bIgnoreInsta { continue; } - + if ( pScene->InvolvesActor( pActor ) ) { return true; @@ -5180,7 +6015,7 @@ bool CSceneManager::IsRunningScriptedSceneAndNotPaused( CBaseFlex *pActor, bool { continue; } - + if ( pScene->InvolvesActor( pActor ) ) { return true; @@ -5190,8 +6025,8 @@ bool CSceneManager::IsRunningScriptedSceneAndNotPaused( CBaseFlex *pActor, bool } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pActor - +// Purpose: +// Input : *pActor - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSceneManager::IsRunningScriptedSceneWithSpeech( CBaseFlex *pActor, bool bIgnoreInstancedScenes ) @@ -5207,7 +6042,7 @@ bool CSceneManager::IsRunningScriptedSceneWithSpeech( CBaseFlex *pActor, bool bI { continue; } - + if ( pScene->InvolvesActor( pActor ) ) { if ( pScene->HasUnplayedSpeech() ) @@ -5232,7 +6067,7 @@ bool CSceneManager::IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pAc { continue; } - + if ( pScene->InvolvesActor( pActor ) ) { if ( pScene->HasUnplayedSpeech() ) @@ -5243,12 +6078,71 @@ bool CSceneManager::IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pAc } +#ifdef MAPBASE +bool CSceneManager::IsRunningScriptedSceneWithFlexAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes, const char *pszNotThisScene ) +{ + int c = m_ActiveScenes.Count(); + for ( int i = 0; i < c; i++ ) + { + CSceneEntity *pScene = m_ActiveScenes[ i ].Get(); + if ( !pScene || + !pScene->IsPlayingBack() || + pScene->IsPaused() || + ( bIgnoreInstancedScenes && dynamic_cast(pScene) != NULL ) || + ( pszNotThisScene == NULL || Q_strcmp( pszNotThisScene, STRING(pScene->m_iszSceneFile) ) == 0 ) + ) + { + continue; + } + + if ( pScene->InvolvesActor( pActor ) ) + { + if ( pScene->HasFlexAnimation() ) + return true; + } + } + return false; +} + + +bool CSceneManager::IsTalkingInAScriptedScene( CBaseFlex *pActor, bool bIgnoreInstancedScenes ) +{ + int c = m_ActiveScenes.Count(); + for ( int i = 0; i < c; i++ ) + { + CSceneEntity *pScene = m_ActiveScenes[ i ].Get(); + if ( !pScene || + !pScene->IsPlayingBack() || + pScene->IsPaused() || + ( bIgnoreInstancedScenes && dynamic_cast(pScene) != NULL ) + ) + { + continue; + } + + if ( pScene->InvolvesActor( pActor ) ) + { + if ( pScene->IsPlayingSpeech() ) + return true; + } + } + return false; +} + + +CUtlVector< CHandle< CSceneEntity > > *CSceneManager::GetActiveSceneList() +{ + return &m_ActiveScenes; +} +#endif + + //----------------------------------------------------------------------------- -// Purpose: -// Input : *actor - -// *soundname - -// soundlevel - -// soundtime - +// Purpose: +// Input : *actor - +// *soundname - +// soundlevel - +// soundtime - //----------------------------------------------------------------------------- void CSceneManager::QueueRestoredSound( CBaseFlex *actor, char const *soundname, soundlevel_t soundlevel, float time_in_past ) { @@ -5328,6 +6222,23 @@ bool IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pActor, bool bIgno return GetSceneManager()->IsRunningScriptedSceneWithSpeechAndNotPaused( pActor, bIgnoreInstancedScenes ); } +#ifdef MAPBASE +bool IsRunningScriptedSceneWithFlexAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes, const char *pszNotThisScene ) +{ + return GetSceneManager()->IsRunningScriptedSceneWithFlexAndNotPaused( pActor, bIgnoreInstancedScenes, pszNotThisScene ); +} + +bool IsTalkingInAScriptedScene( CBaseFlex *pActor, bool bIgnoreInstancedScenes ) +{ + return GetSceneManager()->IsTalkingInAScriptedScene( pActor, bIgnoreInstancedScenes ); +} + +CUtlVector< CHandle< CSceneEntity > > *GetActiveSceneList() +{ + return GetSceneManager()->GetActiveSceneList(); +} +#endif + //=========================================================================================================== // SCENE LIST MANAGER @@ -5376,9 +6287,17 @@ BEGIN_DATADESC( CSceneListManager ) DEFINE_INPUTFUNC( FIELD_VOID, "Shutdown", InputShutdown ), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CSceneListManager, CBaseEntity, "Stores choreo scenes and cleans them up when a later scene in the list begins playing." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetScene, "GetScene", "Gets the specified scene index from this manager." ) + +END_SCRIPTDESC(); +#endif + //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneListManager::Activate( void ) { @@ -5399,7 +6318,7 @@ void CSceneListManager::Activate( void ) { pScene->AddListManager( this ); } - else + else { CSceneListManager *pList = dynamic_cast(m_hScenes[i].Get()); if ( pList ) @@ -5424,7 +6343,7 @@ void CSceneListManager::Activate( void ) //----------------------------------------------------------------------------- // Purpose: A scene or manager in our list has started playing. -// Remove all scenes earlier in the list. +// Remove all scenes earlier in the list. //----------------------------------------------------------------------------- void CSceneListManager::SceneStarted( CBaseEntity *pSceneOrManager ) { @@ -5460,7 +6379,7 @@ void CSceneListManager::SceneStarted( CBaseEntity *pSceneOrManager ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneListManager::AddListManager( CSceneListManager *pManager ) { @@ -5482,7 +6401,7 @@ void CSceneListManager::InputShutdown( inputdata_t &inputdata ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneListManager::ShutdownList( void ) { @@ -5498,7 +6417,7 @@ void CSceneListManager::ShutdownList( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CSceneListManager::RemoveScene( int iIndex ) { @@ -5518,6 +6437,19 @@ void CSceneListManager::RemoveScene( int iIndex ) } } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HSCRIPT CSceneListManager::ScriptGetScene( int iIndex ) +{ + if ( iIndex < 0 || iIndex >= SCENE_LIST_MANAGER_MAX_SCENES ) + return NULL; + + return ToHScript( m_hScenes[iIndex] ); +} +#endif + void ReloadSceneFromDisk( CBaseEntity *ent ) { CSceneEntity *scene = dynamic_cast< CSceneEntity * >( ent ); @@ -5527,8 +6459,8 @@ void ReloadSceneFromDisk( CBaseEntity *ent ) Assert( 0 ); } -// Purpose: -// Input : *ent - +// Purpose: +// Input : *ent - // Output : char const //----------------------------------------------------------------------------- char const *GetSceneFilename( CBaseEntity *ent ) @@ -5564,9 +6496,9 @@ int GetRecentNPCSpeech( recentNPCSpeech_t speech[ SPEECH_LIST_MAX_SOUNDS ] ) // copy the sound names into the list in order they were played num = 0; index = speechListIndex; - for( i = 0; i < SPEECH_LIST_MAX_SOUNDS; i++ ) + for( i = 0; i < SPEECH_LIST_MAX_SOUNDS; i++ ) { - if ( speechListSounds[ index ].name[ 0 ] ) + if ( speechListSounds[ index ].name[ 0 ] ) { // only copy names that are not zero length speech[ num ] = speechListSounds[ index ]; @@ -5574,7 +6506,7 @@ int GetRecentNPCSpeech( recentNPCSpeech_t speech[ SPEECH_LIST_MAX_SOUNDS ] ) } index++; - if ( index >= SPEECH_LIST_MAX_SOUNDS ) + if ( index >= SPEECH_LIST_MAX_SOUNDS ) { index = 0; } @@ -5586,7 +6518,7 @@ int GetRecentNPCSpeech( recentNPCSpeech_t speech[ SPEECH_LIST_MAX_SOUNDS ] ) //----------------------------------------------------------------------------- // Purpose: Displays a list of the last 5 lines of speech from NPCs // Input : -// Output : +// Output : //----------------------------------------------------------------------------- static void ListRecentNPCSpeech( void ) diff --git a/game/server/sceneentity.h b/game/server/sceneentity.h index f1580798..ea286fe9 100644 --- a/game/server/sceneentity.h +++ b/game/server/sceneentity.h @@ -13,7 +13,9 @@ // List of the last 5 lines of speech from NPCs for bug reports #define SPEECH_LIST_MAX_SOUNDS 5 +#ifndef NEW_RESPONSE_SYSTEM class AI_Response; +#endif struct recentNPCSpeech_t { @@ -24,7 +26,11 @@ struct recentNPCSpeech_t int GetRecentNPCSpeech( recentNPCSpeech_t speech[ SPEECH_LIST_MAX_SOUNDS ] ); float InstancedScriptedScene( CBaseFlex *pActor, const char *pszScene, EHANDLE *phSceneEnt = NULL, float flPostDelay = 0.0f, bool bIsBackground = false, AI_Response *response = NULL, bool bMultiplayer = false, IRecipientFilter *filter = NULL ); +#ifdef MAPBASE +float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt = NULL, float flPostDelay = 0.0f, bool bIsBackground = false, AI_Response *response = NULL, bool bMultiplayer = false, IRecipientFilter *filter = NULL ); +#else float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt = NULL ); +#endif void StopScriptedScene( CBaseFlex *pActor, EHANDLE hSceneEnt ); void RemoveActorFromScriptedScenes( CBaseFlex *pActor, bool instancedscenesonly, bool nonidlescenesonly = false, const char *pszThisSceneOnly = NULL ); void RemoveAllScenesInvolvingActor( CBaseFlex *pActor ); @@ -35,14 +41,28 @@ bool IsRunningScriptedScene( CBaseFlex *pActor, bool bIgnoreInstancedScenes = tr bool IsRunningScriptedSceneAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes = true ); bool IsRunningScriptedSceneWithSpeech( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); bool IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); +#ifdef MAPBASE +bool IsRunningScriptedSceneWithFlexAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false, const char *pszNotThisScene = NULL ); +bool IsTalkingInAScriptedScene( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); +CUtlVector< CHandle< CSceneEntity > > *GetActiveSceneList(); +#endif float GetSceneDuration( char const *pszScene ); +float GetSceneSpeechDuration( char const* pszScene ); int GetSceneSpeechCount( char const *pszScene ); bool IsInInterruptableScenes( CBaseFlex *pActor ); void PrecacheInstancedScene( char const *pszScene ); +HSCRIPT ScriptCreateSceneEntity( char const *pszScene ); char const *GetSceneFilename( CBaseEntity *ent ); void ReloadSceneFromDisk( CBaseEntity *ent ); +#ifdef MAPBASE +const char *GetFirstSoundInScene(const char *pszScene); +const char *GetFirstSoundInScene(CChoreoScene *scene); + +CBaseEntity *UTIL_FindNamedSceneEntity(const char *name, CBaseEntity *pActor, CSceneEntity *scene, bool bBaseFlexOnly = false, bool bUseClear = false); +#endif + #endif // SCENEENTITY_H diff --git a/game/server/scripted.cpp b/game/server/scripted.cpp index 6a492708..37b45844 100644 --- a/game/server/scripted.cpp +++ b/game/server/scripted.cpp @@ -31,6 +31,23 @@ ConVar ai_task_pre_script( "ai_task_pre_script", "0", FCVAR_NONE ); +// New macros introduced for Mapbase's console message color changes. +#ifdef MAPBASE +#define ScriptMsg( lvl, msg ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg ) +#define ScriptMsg1( lvl, msg, a ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg, a ) +#define ScriptMsg2( lvl, msg, a, b ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg, a, b ) +#define ScriptMsg3( lvl, msg, a, b, c ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg, a, b, c ) +#define ScriptMsg4( lvl, msg, a, b, c, d ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg, a, b, c, d ) +#define ScriptMsg5( lvl, msg, a, b, c, d, e ) CGMsg( lvl, CON_GROUP_NPC_SCRIPTS, msg, a, b, c, d, e ) +#else +#define ScriptMsg( lvl, msg ) DevMsg( lvl, msg ) +#define ScriptMsg1( lvl, msg, a ) DevMsg( lvl, msg, a ) +#define ScriptMsg2( lvl, msg, a, b ) DevMsg( lvl, msg, a, b ) +#define ScriptMsg3( lvl, msg, a, b, c ) DevMsg( lvl, msg, a, b, c ) +#define ScriptMsg4( lvl, msg, a, b, c, d ) DevMsg( lvl, msg, a, b, c, d ) +#define ScriptMsg5( lvl, msg, a, b, c, d, e ) DevMsg( lvl, msg, a, b, c, d, e ) +#endif + // // targetname "me" - there can be more than one with the same name, and they act in concert @@ -100,6 +117,10 @@ BEGIN_DATADESC( CAI_ScriptedSequence ) DEFINE_KEYFIELD( m_iPlayerDeathBehavior, FIELD_INTEGER, "onplayerdeath" ), DEFINE_INPUTFUNC( FIELD_VOID, "ScriptPlayerDeath", InputScriptPlayerDeath ), +#ifdef MAPBASE + DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), +#endif + // Outputs DEFINE_OUTPUT(m_OnBeginSequence, "OnBeginSequence"), DEFINE_OUTPUT(m_OnEndSequence, "OnEndSequence"), @@ -114,6 +135,12 @@ BEGIN_DATADESC( CAI_ScriptedSequence ) DEFINE_OUTPUT(m_OnScriptEvent[5], "OnScriptEvent06"), DEFINE_OUTPUT(m_OnScriptEvent[6], "OnScriptEvent07"), DEFINE_OUTPUT(m_OnScriptEvent[7], "OnScriptEvent08"), +#ifdef MAPBASE + DEFINE_OUTPUT(m_OnEntrySequence, "OnEntrySequence"), + DEFINE_OUTPUT(m_OnActionSequence, "OnActionSequence"), + DEFINE_OUTPUT(m_OnPreIdleSequence, "OnPreIdleSequence"), + DEFINE_OUTPUT(m_OnFoundNPC, "OnFoundNPC"), +#endif END_DATADESC() @@ -179,18 +206,31 @@ void CAI_ScriptedSequence::ScriptEntityCancel( CBaseEntity *pentCine, bool bPret if ( bPretendSuccess ) { // We need to pretend that this sequence actually finished fully +#ifdef MAPBASE + pCineTarget->m_OnEndSequence.FireOutput(pEntity, pCineTarget); + pCineTarget->m_OnPostIdleEndSequence.FireOutput(pEntity, pCineTarget); +#else pCineTarget->m_OnEndSequence.FireOutput(NULL, pCineTarget); pCineTarget->m_OnPostIdleEndSequence.FireOutput(NULL, pCineTarget); +#endif } else { // Fire the cancel +#ifdef MAPBASE + pCineTarget->m_OnCancelSequence.FireOutput(pEntity, pCineTarget); +#else pCineTarget->m_OnCancelSequence.FireOutput(NULL, pCineTarget); +#endif if ( pCineTarget->m_startTime == 0 ) { // If start time is 0, this sequence never actually ran. Fire the failed output. +#ifdef MAPBASE + pCineTarget->m_OnCancelFailedSequence.FireOutput(pEntity, pCineTarget); +#else pCineTarget->m_OnCancelFailedSequence.FireOutput(NULL, pCineTarget); +#endif } } } @@ -332,6 +372,18 @@ void CAI_ScriptedSequence::InputMoveToPosition( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets our target NPC with the generic SetTarget input. +//----------------------------------------------------------------------------- +void CAI_ScriptedSequence::InputSetTarget( inputdata_t &inputdata ) +{ + m_hActivator = inputdata.pActivator; + m_iszEntity = AllocPooledString(inputdata.value.String()); + m_hTargetEnt = NULL; +} +#endif + //----------------------------------------------------------------------------- // Purpose: Input handler that activates the scripted sequence. @@ -343,6 +395,14 @@ void CAI_ScriptedSequence::InputBeginSequence( inputdata_t &inputdata ) // Start the script as soon as possible. m_bWaitForBeginSequence = false; + +#ifdef MAPBASE + m_hActivator = inputdata.pActivator; + + // TODO: Investigate whether this is necessary + //if (FStrEq(STRING(m_iszEntity), "!activator")) + // SetTarget(NULL); +#endif // do I already know who I should use? CBaseEntity *pEntity = GetTarget(); @@ -407,7 +467,7 @@ void CAI_ScriptedSequence::InputCancelSequence( inputdata_t &inputdata ) // We don't call CancelScript because entity I/O will handle dispatching // this input to all other scripts with our same name. // - DevMsg( 2, "InputCancelScript: Cancelling script '%s'\n", STRING( m_iszPlay )); + ScriptMsg1( 2, "InputCancelScript: Cancelling script '%s'\n", STRING( m_iszPlay )); StopThink(); ScriptEntityCancel( this ); } @@ -423,7 +483,7 @@ void CAI_ScriptedSequence::InputScriptPlayerDeath( inputdata_t &inputdata ) // We don't call CancelScript because entity I/O will handle dispatching // this input to all other scripts with our same name. // - DevMsg( 2, "InputCancelScript: Cancelling script '%s'\n", STRING( m_iszPlay )); + ScriptMsg1( 2, "InputCancelScript: Cancelling script '%s'\n", STRING( m_iszPlay )); StopThink(); ScriptEntityCancel( this ); } @@ -472,7 +532,7 @@ void CAI_ScriptedSequence::Blocked( CBaseEntity *pOther ) void CAI_ScriptedSequence::Touch( CBaseEntity *pOther ) { /* - DevMsg( 2, "Cine Touch\n" ); + ScriptMsg( 2, "Cine Touch\n" ); if (m_pentTarget && OFFSET(pOther->pev) == OFFSET(m_pentTarget)) { CAI_BaseNPC *pTarget = GetClassPtr((CAI_BaseNPC *)VARS(m_pentTarget)); @@ -521,7 +581,11 @@ CAI_BaseNPC *CAI_ScriptedSequence::FindScriptEntity( ) { interrupt = SS_INTERRUPT_BY_NAME; +#ifdef MAPBASE + pEntity = gEntList.FindEntityByNameWithin( m_hLastFoundEntity, STRING( m_iszEntity ), GetAbsOrigin(), m_flRadius, this, m_hActivator ); +#else pEntity = gEntList.FindEntityByNameWithin( m_hLastFoundEntity, STRING( m_iszEntity ), GetAbsOrigin(), m_flRadius ); +#endif if (!pEntity) { pEntity = gEntList.FindEntityByClassnameWithin( m_hLastFoundEntity, STRING( m_iszEntity ), GetAbsOrigin(), m_flRadius ); @@ -551,7 +615,7 @@ CAI_BaseNPC *CAI_ScriptedSequence::FindScriptEntity( ) else if (!(m_spawnflags & SF_SCRIPT_NO_COMPLAINTS)) { // They cannot play the script. - DevMsg( "Found %s, but can't play!\n", STRING( m_iszEntity )); + ScriptMsg1( 1, "Found %s, but can't play!\n", STRING( m_iszEntity )); } } @@ -638,7 +702,7 @@ void CAI_ScriptedSequence::StartScript( void ) // Don't clear the currently playing script's target! pCine->SetTarget( NULL ); } - DevMsg( 2, "script \"%s\" kicking script \"%s\" out of the queue\n", GetDebugName(), pCine->GetDebugName() ); + ScriptMsg2( 2, "script \"%s\" kicking script \"%s\" out of the queue\n", GetDebugName(), pCine->GetDebugName() ); } pTarget->m_hCine->m_hNextCine = this; @@ -744,7 +808,7 @@ void CAI_ScriptedSequence::StartScript( void ) //pTarget->SetGroundEntity( NULL ); break; } - //DevMsg( 2, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->m_iName ), FBitSet(m_spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" ); + //ScriptMsg2( 2, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->m_iName ), FBitSet(m_spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" ); // Wait until all scripts of the same name are ready to play. @@ -759,6 +823,10 @@ void CAI_ScriptedSequence::StartScript( void ) DevWarning( "scripted_sequence %d:%s - restarting dormant entity %d:%s : %.1f:%.1f\n", entindex(), GetDebugName(), pTarget->entindex(), pTarget->GetDebugName(), gpGlobals->curtime, pTarget->GetNextThink() ); pTarget->SetNextThink( gpGlobals->curtime ); } + +#ifdef MAPBASE + m_OnFoundNPC.FireOutput( pTarget, this ); +#endif } } @@ -775,12 +843,12 @@ void CAI_ScriptedSequence::ScriptThink( void ) else if (FindEntity()) { StartScript( ); - DevMsg( 2, "scripted_sequence %d:\"%s\" using NPC %d:\"%s\"(%s)\n", entindex(), GetDebugName(), GetTarget()->entindex(), GetTarget()->GetEntityName().ToCStr(), STRING( m_iszEntity ) ); + ScriptMsg5( 2, "scripted_sequence %d:\"%s\" using NPC %d:\"%s\"(%s)\n", entindex(), GetDebugName(), GetTarget()->entindex(), GetTarget()->GetEntityName().ToCStr(), STRING( m_iszEntity ) ); } else { CancelScript( ); - DevMsg( 2, "scripted_sequence %d:\"%s\" can't find NPC \"%s\"\n", entindex(), GetDebugName(), STRING( m_iszEntity ) ); + ScriptMsg3( 2, "scripted_sequence %d:\"%s\" can't find NPC \"%s\"\n", entindex(), GetDebugName(), STRING( m_iszEntity ) ); // FIXME: just trying again is bad. This should fire an output instead. // FIXME: Think about puting output triggers in both StartScript() and CancelScript(). SetNextThink( gpGlobals->curtime + 1.0f ); @@ -792,10 +860,32 @@ void CAI_ScriptedSequence::ScriptThink( void ) // Purpose: Callback for firing the begin sequence output. Called by the NPC that // is running the script as it starts the action seqeunce. //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CAI_ScriptedSequence::OnBeginSequence( CBaseEntity *pActor ) +{ + m_OnBeginSequence.FireOutput( pActor, this ); +} + +void CAI_ScriptedSequence::OnEntrySequence( CBaseEntity *pActor ) +{ + m_OnEntrySequence.FireOutput( pActor, this ); +} + +void CAI_ScriptedSequence::OnActionSequence( CBaseEntity *pActor ) +{ + m_OnActionSequence.FireOutput( pActor, this ); +} + +void CAI_ScriptedSequence::OnPreIdleSequence( CBaseEntity *pActor ) +{ + m_OnPreIdleSequence.FireOutput( pActor, this ); +} +#else void CAI_ScriptedSequence::OnBeginSequence( void ) { m_OnBeginSequence.FireOutput( this, this ); } +#endif //----------------------------------------------------------------------------- @@ -841,7 +931,7 @@ bool CAI_ScriptedSequence::StartSequence( CAI_BaseNPC *pTarget, string_t iszSeq, // Don't blend... pTarget->IncrementInterpolationFrame(); } - //DevMsg( 2, "%s (%s): started \"%s\":INT:%s\n", STRING( pTarget->m_iName ), pTarget->GetClassname(), STRING( iszSeq), (m_spawnflags & SF_SCRIPT_NOINTERRUPT) ? "No" : "Yes" ); + //ScriptMsg4( 2, "%s (%s): started \"%s\":INT:%s\n", STRING( pTarget->m_iName ), pTarget->GetClassname(), STRING( iszSeq), (m_spawnflags & SF_SCRIPT_NOINTERRUPT) ? "No" : "Yes" ); return true; } @@ -921,7 +1011,7 @@ bool CAI_ScriptedSequence::FinishedActionSequence( CAI_BaseNPC *pNPC ) //----------------------------------------------------------------------------- void CAI_ScriptedSequence::SequenceDone( CAI_BaseNPC *pNPC ) { - //DevMsg( 2, "Sequence %s finished\n", STRING( pNPC->m_hCine->m_iszPlay ) ); + //ScriptMsg1( 2, "Sequence %s finished\n", STRING( pNPC->m_hCine->m_iszPlay ) ); //Msg("%s SequenceDone() at %0.2f\n", pNPC->GetDebugName(), gpGlobals->curtime ); @@ -964,7 +1054,11 @@ void CAI_ScriptedSequence::SequenceDone( CAI_BaseNPC *pNPC ) } } +#ifdef MAPBASE + m_OnEndSequence.FireOutput(pNPC, this); +#else m_OnEndSequence.FireOutput(NULL, this); +#endif } //----------------------------------------------------------------------------- @@ -1027,7 +1121,7 @@ void CAI_ScriptedSequence::PostIdleDone( CAI_BaseNPC *pNPC ) // Only do so if we're selected, to prevent spam if ( pNPC->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) { - DevMsg( 2, "Post Idle %s finished for %s\n", STRING( pNPC->m_hCine->m_iszPostIdle ), pNPC->GetDebugName() ); + ScriptMsg2( 2, "Post Idle %s finished for %s\n", STRING( pNPC->m_hCine->m_iszPostIdle ), pNPC->GetDebugName() ); } pNPC->m_scriptState = CAI_BaseNPC::SCRIPT_POST_IDLE; @@ -1073,7 +1167,11 @@ void CAI_ScriptedSequence::PostIdleDone( CAI_BaseNPC *pNPC ) } //Msg("%s finished post idle at %0.2f\n", pNPC->GetDebugName(), gpGlobals->curtime ); +#ifdef MAPBASE + m_OnPostIdleEndSequence.FireOutput(pNPC, this); +#else m_OnPostIdleEndSequence.FireOutput(NULL, this); +#endif } @@ -1189,7 +1287,7 @@ bool CAI_ScriptedSequence::CanEnqueueAfter( void ) if ( m_iszNextScript != NULL_STRING ) { - DevMsg( 2, "%s is specified as the 'Next Script' and cannot be kicked out of the queue\n", m_hNextCine->GetDebugName() ); + ScriptMsg1( 2, "%s is specified as the 'Next Script' and cannot be kicked out of the queue\n", m_hNextCine->GetDebugName() ); return false; } @@ -1198,7 +1296,7 @@ bool CAI_ScriptedSequence::CanEnqueueAfter( void ) return true; } - DevMsg( 2, "%s is a priority script and cannot be kicked out of the queue\n", m_hNextCine->GetDebugName() ); + ScriptMsg1( 2, "%s is a priority script and cannot be kicked out of the queue\n", m_hNextCine->GetDebugName() ); return false; } @@ -1333,7 +1431,7 @@ void CAI_ScriptedSequence::ModifyScriptedAutoMovement( Vector *vecNewPos ) //----------------------------------------------------------------------------- void CAI_ScriptedSequence::CancelScript( void ) { - DevMsg( 2, "Cancelling script: %s\n", STRING( m_iszPlay )); + ScriptMsg1( 2, "Cancelling script: %s\n", STRING( m_iszPlay )); // Don't cancel matching sequences if we're asked not to, unless we didn't actually // succeed in starting, in which case we should always cancel. This fixes @@ -1576,6 +1674,9 @@ class CAI_ScriptedSchedule : public CBaseEntity // Input handlers void InputStartSchedule( inputdata_t &inputdata ); void InputStopSchedule( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetTarget( inputdata_t &inputdata ); +#endif CAI_BaseNPC *FindScriptEntity( bool bCyclic ); @@ -1660,7 +1761,7 @@ void CAI_ScriptedSchedule::ScriptThink( void ) pTarget = FindScriptEntity( (m_spawnflags & SF_SCRIPT_SEARCH_CYCLICALLY) != 0 ); if ( pTarget ) { - DevMsg( 2, "scripted_schedule \"%s\" using NPC \"%s\"(%s)\n", GetDebugName(), STRING( m_iszEntity ), pTarget->GetEntityName().ToCStr() ); + ScriptMsg3( 2, "scripted_schedule \"%s\" using NPC \"%s\"(%s)\n", GetDebugName(), STRING( m_iszEntity ), pTarget->GetEntityName().ToCStr() ); StartSchedule( pTarget ); success = true; } @@ -1670,7 +1771,7 @@ void CAI_ScriptedSchedule::ScriptThink( void ) m_hLastFoundEntity = NULL; while ( ( pTarget = FindScriptEntity( true ) ) != NULL ) { - DevMsg( 2, "scripted_schedule \"%s\" using NPC \"%s\"(%s)\n", GetDebugName(), pTarget->GetEntityName().ToCStr(), STRING( m_iszEntity ) ); + ScriptMsg3( 2, "scripted_schedule \"%s\" using NPC \"%s\"(%s)\n", GetDebugName(), pTarget->GetEntityName().ToCStr(), STRING( m_iszEntity ) ); StartSchedule( pTarget ); success = true; } @@ -1678,7 +1779,7 @@ void CAI_ScriptedSchedule::ScriptThink( void ) if ( !success ) { - DevMsg( 2, "scripted_schedule \"%s\" can't find NPC \"%s\"\n", GetDebugName(), STRING( m_iszEntity ) ); + ScriptMsg2( 2, "scripted_schedule \"%s\" can't find NPC \"%s\"\n", GetDebugName(), STRING( m_iszEntity ) ); // FIXME: just trying again is bad. This should fire an output instead. // FIXME: Think about puting output triggers on success true and sucess false // FIXME: also needs to check the result of StartSchedule(), which can fail and not complain @@ -1739,7 +1840,7 @@ void CAI_ScriptedSchedule::StartSchedule( CAI_BaseNPC *pTarget ) CAI_Hint *pHint = CAI_HintManager::FindHint( pTarget->GetAbsOrigin(), hintCriteria ); if ( !pHint ) { - DevMsg( 1, "Can't find goal entity %s\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); + ScriptMsg2( 1, "Can't find goal entity %s\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); return; } pGoalEnt = pHint; @@ -1780,7 +1881,7 @@ void CAI_ScriptedSchedule::StartSchedule( CAI_BaseNPC *pTarget ) pTarget->SetCondition( COND_SCHEDULE_DONE ); } else - DevMsg( "Scripted schedule %s specified an invalid enemy %s\n", STRING( GetEntityName() ), STRING( m_sGoalEnt ) ); + ScriptMsg2( 1, "Scripted schedule %s specified an invalid enemy %s\n", STRING( GetEntityName() ), STRING( m_sGoalEnt ) ); } bool bDidSetSchedule = false; @@ -1805,7 +1906,7 @@ void CAI_ScriptedSchedule::StartSchedule( CAI_BaseNPC *pTarget ) { if (!(m_spawnflags & SF_SCRIPT_NO_COMPLAINTS)) { - DevMsg( 1, "ScheduledMoveToGoalEntity to goal entity %s failed\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); + ScriptMsg2( 1, "ScheduledMoveToGoalEntity to goal entity %s failed\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); } return; } @@ -1827,7 +1928,7 @@ void CAI_ScriptedSchedule::StartSchedule( CAI_BaseNPC *pTarget ) { if (!(m_spawnflags & SF_SCRIPT_NO_COMPLAINTS)) { - DevMsg( 1, "ScheduledFollowPath to goal entity %s failed\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); + ScriptMsg2( 1, "ScheduledFollowPath to goal entity %s failed\nCan't execute script %s\n", STRING(m_sGoalEnt), GetDebugName() ); } return; } @@ -1852,7 +1953,7 @@ void CAI_ScriptedSchedule::InputStartSchedule( inputdata_t &inputdata ) { if (( m_nForceState == 0 ) && ( m_nSchedule == 0 )) { - DevMsg( 2, "aiscripted_schedule - no schedule or state has been set!\n" ); + ScriptMsg( 2, "aiscripted_schedule - no schedule or state has been set!\n" ); } if ( !m_bDidFireOnce || ( m_spawnflags & SF_SCRIPT_REPEATABLE ) ) @@ -1864,7 +1965,7 @@ void CAI_ScriptedSchedule::InputStartSchedule( inputdata_t &inputdata ) } else { - DevMsg( 2, "aiscripted_schedule - not playing schedule again: not flagged to repeat\n" ); + ScriptMsg( 2, "aiscripted_schedule - not playing schedule again: not flagged to repeat\n" ); } } @@ -1875,7 +1976,7 @@ void CAI_ScriptedSchedule::InputStopSchedule( inputdata_t &inputdata ) { if ( !m_bDidFireOnce ) { - DevMsg( 2, "aiscripted_schedule - StopSchedule called, but schedule's never started.\n" ); + ScriptMsg( 2, "aiscripted_schedule - StopSchedule called, but schedule's never started.\n" ); return; } @@ -1898,6 +1999,17 @@ void CAI_ScriptedSchedule::InputStopSchedule( inputdata_t &inputdata ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets our target NPC with the generic SetTarget input. +//----------------------------------------------------------------------------- +void CAI_ScriptedSchedule::InputSetTarget( inputdata_t &inputdata ) +{ + m_hActivator = inputdata.pActivator; + m_iszEntity = AllocPooledString( inputdata.value.String() ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: If the target entity appears to be running this scripted schedule break it //----------------------------------------------------------------------------- @@ -1905,7 +2017,7 @@ void CAI_ScriptedSchedule::StopSchedule( CAI_BaseNPC *pTarget ) { if ( pTarget->IsCurSchedule( SCHED_IDLE_WALK ) ) { - DevMsg( 2, "%s (%s): StopSchedule called on NPC %s.\n", GetClassname(), GetDebugName(), pTarget->GetDebugName() ); + ScriptMsg3( 2, "%s (%s): StopSchedule called on NPC %s.\n", GetClassname(), GetDebugName(), pTarget->GetDebugName() ); pTarget->ClearSchedule( "Stopping scripted schedule" ); } } @@ -2189,7 +2301,7 @@ int CAI_ScriptedSentence::StartSentence( CAI_BaseNPC *pTarget ) { if ( !pTarget ) { - DevMsg( 2, "Not Playing sentence %s\n", STRING(m_iszSentence) ); + ScriptMsg1( 2, "Not Playing sentence %s\n", STRING(m_iszSentence) ); return -1; } @@ -2214,13 +2326,179 @@ int CAI_ScriptedSentence::StartSentence( CAI_BaseNPC *pTarget ) } int sentenceIndex = pTarget->PlayScriptedSentence( STRING(m_iszSentence), m_flDelay, m_flVolume, m_iSoundLevel, bConcurrent, pListener ); - DevMsg( 2, "Playing sentence %s\n", STRING(m_iszSentence) ); + ScriptMsg1( 2, "Playing sentence %s\n", STRING(m_iszSentence) ); m_OnBeginSentence.FireOutput(NULL, this); return sentenceIndex; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// This isn't exclusive to NPCs, so it could be moved if needed. +//----------------------------------------------------------------------------- +class CScriptedSound : public CPointEntity +{ +public: + DECLARE_CLASS( CScriptedSound, CPointEntity ); + DECLARE_DATADESC(); + + void Precache(); + + CBaseEntity *GetTarget(inputdata_t &inputdata); + + // Input handlers + void InputPlaySound( inputdata_t &inputdata ); + void InputPlaySoundOnEntity( inputdata_t &inputdata ); + void InputStopSound( inputdata_t &inputdata ); + void InputSetSound( inputdata_t &inputdata ); + +private: + string_t m_message; + + bool m_bGrabAll; +}; + + +BEGIN_DATADESC( CScriptedSound ) + + DEFINE_KEYFIELD( m_message, FIELD_STRING, "message" ), + DEFINE_KEYFIELD( m_bGrabAll, FIELD_BOOLEAN, "GrabAll" ), + + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "PlaySound", InputPlaySound), + DEFINE_INPUTFUNC(FIELD_EHANDLE, "PlaySoundOnEntity", InputPlaySoundOnEntity), + DEFINE_INPUTFUNC(FIELD_VOID, "StopSound", InputStopSound), + DEFINE_INPUTFUNC(FIELD_STRING, "SetSound", InputSetSound), + +END_DATADESC() + + + +LINK_ENTITY_TO_CLASS( scripted_sound, CScriptedSound ); + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CScriptedSound::Precache() +{ + //PrecacheScriptSound(STRING(m_message)); + + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +CBaseEntity *CScriptedSound::GetTarget(inputdata_t &inputdata) +{ + CBaseEntity *pEntity = NULL; + if (m_target == NULL_STRING) + { + // Use this as the default source entity + pEntity = this; + m_bGrabAll = false; + } + else + { + pEntity = gEntList.FindEntityGeneric(NULL, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + } + + return pEntity; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CScriptedSound::InputPlaySound( inputdata_t &inputdata ) +{ + PrecacheScriptSound(STRING(m_message)); + + CBaseEntity *pEntity = GetTarget(inputdata); + const char *sound = STRING(m_message); + if (m_bGrabAll) + { + //if (pEntity) + //{ + // pEntity->PrecacheScriptSound(sound); + //} + + while (pEntity) + { + pEntity->EmitSound(sound); + pEntity = gEntList.FindEntityGeneric(pEntity, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + } + } + else if (pEntity) + { + //pEntity->PrecacheScriptSound(sound); + pEntity->EmitSound(sound); + } + else + { + Warning("%s unable to find target entity %s!\n", GetDebugName(), STRING(m_target)); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CScriptedSound::InputPlaySoundOnEntity( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity()) + { + inputdata.value.Entity()->PrecacheScriptSound(STRING(m_message)); + inputdata.value.Entity()->EmitSound(STRING(m_message)); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CScriptedSound::InputStopSound( inputdata_t &inputdata ) +{ + CBaseEntity *pEntity = GetTarget(inputdata); + const char *sound = STRING(m_message); + if (m_bGrabAll) + { + while (pEntity) + { + pEntity->StopSound(sound); + pEntity = gEntList.FindEntityGeneric(pEntity, STRING(m_target), this, inputdata.pActivator, inputdata.pCaller); + } + } + else if (pEntity) + { + pEntity->StopSound(sound); + } + else + { + Warning("%s unable to find target entity %s!\n", GetDebugName(), STRING(m_target)); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CScriptedSound::InputSetSound( inputdata_t &inputdata ) +{ + PrecacheScriptSound(inputdata.value.String()); + m_message = inputdata.value.StringID(); +} +#endif + // HACKHACK: This is a little expensive with the dynamic_cast<> and all, but it lets us solve diff --git a/game/server/scripted.h b/game/server/scripted.h index 574fcbd5..7b1d8254 100644 --- a/game/server/scripted.h +++ b/game/server/scripted.h @@ -95,7 +95,14 @@ class CAI_ScriptedSequence : public CBaseEntity bool FindEntity( void ); void StartScript( void ); void FireScriptEvent( int nEvent ); +#ifdef MAPBASE + void OnBeginSequence( CBaseEntity *pActor ); + void OnEntrySequence( CBaseEntity *pActor ); + void OnActionSequence( CBaseEntity *pActor ); + void OnPreIdleSequence( CBaseEntity *pActor ); +#else void OnBeginSequence( void ); +#endif void SetTarget( CBaseEntity *pTarget ) { m_hTargetEnt = pTarget; }; CBaseEntity *GetTarget( void ) { return m_hTargetEnt; }; @@ -104,6 +111,9 @@ class CAI_ScriptedSequence : public CBaseEntity void InputBeginSequence( inputdata_t &inputdata ); void InputCancelSequence( inputdata_t &inputdata ); void InputMoveToPosition( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetTarget( inputdata_t &inputdata ); +#endif bool IsTimeToStart( void ); bool IsWaitingForBegin( void ); @@ -211,6 +221,12 @@ class CAI_ScriptedSequence : public CBaseEntity COutputEvent m_OnCancelSequence; COutputEvent m_OnCancelFailedSequence; // Fired when a scene is cancelled before it's ever run COutputEvent m_OnScriptEvent[MAX_SCRIPT_EVENTS]; +#ifdef MAPBASE + COutputEvent m_OnEntrySequence; + COutputEvent m_OnActionSequence; + COutputEvent m_OnPreIdleSequence; + COutputEvent m_OnFoundNPC; +#endif static void ScriptEntityCancel( CBaseEntity *pentCine, bool bPretendSuccess = false ); @@ -223,6 +239,11 @@ class CAI_ScriptedSequence : public CBaseEntity EHANDLE m_hInteractionRelativeEntity; int m_iPlayerDeathBehavior; + +#ifdef MAPBASE + // !activator functionality + EHANDLE m_hActivator; +#endif }; diff --git a/game/server/sendproxy.cpp b/game/server/sendproxy.cpp index 71e2a071..ad017c64 100644 --- a/game/server/sendproxy.cpp +++ b/game/server/sendproxy.cpp @@ -27,7 +27,7 @@ void SendProxy_EHandleToInt( const SendProp *pProp, const void *pStruct, const v if ( pHandle && pHandle->Get() ) { - int iSerialNum = pHandle->GetSerialNumber() & ( (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1 ); + int iSerialNum = pHandle->GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; pOut->m_Int = pHandle->GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS); } else @@ -106,7 +106,6 @@ REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_OnlyToTeam ); #define TIME_BITS 24 // This table encodes edict data. -#if 0 static void SendProxy_Time( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID ) { float clock_base = floor( gpGlobals->curtime ); @@ -120,7 +119,6 @@ static void SendProxy_Time( const SendProp *pProp, const void *pStruct, const vo pOut->m_Int = addt; } -#endif //----------------------------------------------------------------------------- // Purpose: diff --git a/game/server/server_base.vpc b/game/server/server_base.vpc index faf1bb55..64558734 100644 --- a/game/server/server_base.vpc +++ b/game/server/server_base.vpc @@ -18,6 +18,9 @@ $include "$SRCDIR\vpc_scripts\protobuf_builder.vpc" $Include "$SRCDIR\vpc_scripts\source_replay.vpc" [$TF] $Include "$SRCDIR\game\protobuf_include.vpc" +// Mapbase stuff +$Include "$SRCDIR\game\server\server_mapbase.vpc" [$MAPBASE] + $Configuration "Debug" { $General @@ -123,8 +126,10 @@ $Project $File "ai_concommands.cpp" $File "ai_condition.cpp" $File "ai_condition.h" - $File "AI_Criteria.cpp" + $File "AI_Criteria.cpp" [!$NEW_RESPONSE_SYSTEM] $File "AI_Criteria.h" + $File "$SRCDIR\game\shared\ai_criteria_new.cpp" [$NEW_RESPONSE_SYSTEM] + $File "$SRCDIR\game\shared\ai_criteria_new.h" [$NEW_RESPONSE_SYSTEM] $File "ai_debug.h" $File "$SRCDIR\game\shared\ai_debug_shared.h" $File "ai_default.cpp" @@ -179,8 +184,10 @@ $Project $File "ai_planesolver.h" $File "ai_playerally.cpp" $File "ai_playerally.h" - $File "AI_ResponseSystem.cpp" + $File "AI_ResponseSystem.cpp" [!$NEW_RESPONSE_SYSTEM] $File "AI_ResponseSystem.h" + $File "$SRCDIR\game\shared\ai_responsesystem_new.cpp" [$NEW_RESPONSE_SYSTEM] + $File "$SRCDIR\game\shared\ai_responsesystem_new.h" [$NEW_RESPONSE_SYSTEM] $File "ai_route.cpp" $File "ai_route.h" $File "ai_routedist.h" @@ -194,8 +201,10 @@ $Project $File "ai_senses.h" $File "ai_sentence.cpp" $File "ai_sentence.h" - $File "ai_speech.cpp" + $File "ai_speech.cpp" [!$NEW_RESPONSE_SYSTEM] $File "ai_speech.h" + $File "ai_speech_new.cpp" [$NEW_RESPONSE_SYSTEM] + $File "ai_speech_new.h" [$NEW_RESPONSE_SYSTEM] $File "ai_speechfilter.cpp" $File "ai_speechfilter.h" $File "ai_squad.cpp" @@ -425,7 +434,6 @@ $Project $File "init_factory.h" $File "intermission.cpp" $File "$SRCDIR\public\interpolatortypes.h" - $File "$SRCDIR\game\shared\interval.h" $File "$SRCDIR\public\iregistry.h" $File "$SRCDIR\game\shared\iscenetokenprocessor.h" $File "iservervehicle.h" @@ -645,6 +653,11 @@ $Project $File "$SRCDIR\game\shared\voice_common.h" $File "$SRCDIR\game\shared\voice_gamemgr.cpp" $File "$SRCDIR\game\shared\voice_gamemgr.h" + $File "vscript_server.cpp" + $File "vscript_server.h" + $File "vscript_server.nut" + $File "$SRCDIR\game\shared\vscript_shared.cpp" + $File "$SRCDIR\game\shared\vscript_shared.h" $File "waterbullet.cpp" $File "waterbullet.h" $File "WaterLODControl.cpp" @@ -664,11 +677,6 @@ $Project //Haptics $File "$SRCDIR\public\haptics\haptic_msgs.cpp" $File "$SRCDIR\public\haptics\haptic_utils.cpp" [$WIN32] - $File "env_skydome.cpp" - $File "env_global_light.cpp" - $File "env_music.cpp" - $File "projectile_bullet.cpp" - $File "projectile_bullet.h" // Not using precompiled header cbase.h @@ -683,7 +691,6 @@ $Project "h_export.cpp" \ "init_factory.cpp" \ "$SRCDIR\public\interpolatortypes.cpp" \ - "$SRCDIR\game\shared\interval.cpp" \ "$SRCDIR\public\keyframe\keyframe.cpp" \ "$SRCDIR\common\language.cpp" \ "$SRCDIR\public\map_utils.cpp" \ @@ -997,6 +1004,7 @@ $Project $File "$SRCDIR\public\winlite.h" $File "$SRCDIR\public\worldsize.h" $File "$SRCDIR\public\zip_uncompressed.h" + $File "$SRCDIR\public\tier1\interval.h" $File "$SRCDIR\game\shared\mp_shareddefs.h" $File "$SRCDIR\game\shared\econ\ihasowner.h" //Haptics diff --git a/game/server/server_episodic.vpc b/game/server/server_episodic.vpc new file mode 100644 index 00000000..7c7ca5da --- /dev/null +++ b/game/server/server_episodic.vpc @@ -0,0 +1,303 @@ +//----------------------------------------------------------------------------- +// SERVER_EPISODIC.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "episodic" [!$SOURCESDK] +$Macro GAMENAME "mod_episodic" [$SOURCESDK] + +$Include "$SRCDIR\game\server\server_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2;$SRCDIR\game\shared\episodic;.\hl2;.\episodic" + $PreprocessorDefinitions "$BASE;HL2_DLL;HL2_EPISODIC;USES_SAVERESTORE" + } +} + +$Project "Server (Episodic)" +{ + $Folder "Source Files" + { + $File "ai_eventresponse.cpp" + $File "ai_eventresponse.h" + $File "ai_relationship.cpp" + $File "base_gameinterface.cpp" + $File "basegrenade_concussion.cpp" + $File "basegrenade_contact.cpp" + $File "basegrenade_timed.cpp" + $File "grenadethrown.cpp" + $File "grenadethrown.h" + $File "h_cycler.cpp" + $File "h_cycler.h" + $File "logic_achievement.cpp" + $File "monstermaker.cpp" + $File "monstermaker.h" + $File "physics_bone_follower.h" + $File "$SRCDIR\game\shared\ragdoll_shared.h" + $File "$SRCDIR\game\shared\solidsetdefaults.h" + $File "$SRCDIR\game\shared\hl2\survival_gamerules.cpp" + $File "team_spawnpoint.cpp" + $File "team_spawnpoint.h" + $File "$SRCDIR\game\shared\touchlink.h" + $File "vehicle_choreo_generic.cpp" + $File "$SRCDIR\game\shared\vehicle_choreo_generic_shared.h" + $File "$SRCDIR\game\shared\weapon_parse_default.cpp" + + $Folder "HL2 DLL" + { + $File "$SRCDIR\game\shared\episodic\achievements_ep1.cpp" + $File "$SRCDIR\game\shared\episodic\achievements_ep2.cpp" + $File "$SRCDIR\game\shared\episodic\achievements_epx.cpp" + $File "hl2\ai_allymanager.cpp" + $File "hl2\ai_behavior_actbusy.cpp" + $File "hl2\ai_behavior_actbusy.h" + $File "episodic\ai_behavior_alyx_injured.cpp" + $File "episodic\ai_behavior_alyx_injured.h" + $File "hl2\ai_behavior_functank.cpp" + $File "hl2\ai_behavior_functank.h" + $File "hl2\ai_behavior_holster.cpp" + $File "hl2\ai_behavior_holster.h" + $File "hl2\ai_behavior_operator.cpp" + $File "hl2\ai_behavior_operator.h" + $File "ai_behavior_passenger.cpp" + $File "ai_behavior_passenger.h" + $File "episodic\ai_behavior_passenger_companion.cpp" + $File "episodic\ai_behavior_passenger_companion.h" + $File "episodic\ai_behavior_passenger_zombie.cpp" + $File "episodic\ai_behavior_passenger_zombie.h" + $File "hl2\ai_behavior_police.cpp" + $File "hl2\ai_behavior_police.h" + $File "hl2\ai_goal_police.cpp" + $File "hl2\ai_goal_police.h" + $File "hl2\ai_interactions.h" + $File "hl2\ai_spotlight.cpp" + $File "hl2\ai_spotlight.h" + $File "hl2\antlion_dust.cpp" + $File "hl2\antlion_dust.h" + $File "hl2\antlion_maker.cpp" + $File "hl2\antlion_maker.h" + $File "hl2\ar2_explosion.cpp" + $File "hl2\ar2_explosion.h" + $File "basebludgeonweapon.cpp" + $File "basebludgeonweapon.h" + $File "hl2\basehlcombatweapon.cpp" + $File "hl2\basehlcombatweapon.h" + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.h" + $File "hl2\cbasehelicopter.cpp" + $File "hl2\cbasehelicopter.h" + $File "hl2\cbasespriteprojectile.cpp" + $File "hl2\cbasespriteprojectile.h" + $File "hl2\citadel_effects.cpp" + $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" + $File "hl2\combine_mine.cpp" + $File "hl2\combine_mine.h" + $File "hl2\energy_wave.h" + $File "hl2\env_alyxemp.cpp" + $File "$SRCDIR\game\shared\hl2\env_alyxemp_shared.h" + $File "hl2\env_headcrabcanister.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" + $File "hl2\env_speaker.cpp" + $File "hl2\env_starfield.cpp" + $File "hl2\Func_Monitor.cpp" + $File "hl2\func_recharge.cpp" + $File "hl2\func_tank.cpp" + $File "hl2\func_tank.h" + $File "hl2\grenade_ar2.cpp" + $File "hl2\grenade_ar2.h" + $File "hl2\grenade_bugbait.cpp" + $File "hl2\grenade_bugbait.h" + $File "hl2\grenade_frag.cpp" + $File "hl2\grenade_frag.h" + $File "hl2\grenade_spit.cpp" + $File "hl2\grenade_spit.h" + $File "hl2\hl2_ai_network.cpp" + $File "hl2\hl2_client.cpp" + $File "hl2\hl2_eventlog.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" + $File "hl2\hl2_player.cpp" + $File "hl2\hl2_player.h" + $File "$SRCDIR\game\shared\hl2\hl2_player_shared.h" + $File "hl2\hl2_playerlocaldata.cpp" + $File "hl2\hl2_playerlocaldata.h" + $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" + $File "hl2\hl2_triggers.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" + $File "$SRCDIR\game\shared\hl2\hl_movedata.h" + $File "hl2\hl_playermove.cpp" + $File "hl2\info_darknessmode_lightsource.cpp" + $File "hl2\info_darknessmode_lightsource.h" + $File "hl2\info_teleporter_countdown.cpp" + $File "hl2\item_ammo.cpp" + $File "hl2\item_battery.cpp" + $File "hl2\item_dynamic_resupply.cpp" + $File "hl2\item_dynamic_resupply.h" + $File "hl2\item_healthkit.cpp" + $File "hl2\item_itemcrate.cpp" + $File "hl2\item_suit.cpp" + $File "hl2\look_door.cpp" + $File "hl2\monster_dummy.cpp" + $File "$SRCDIR\game\shared\episodic\npc_advisor_shared.h" + $File "episodic\npc_advisor.cpp" + $File "hl2\npc_alyx_episodic.cpp" + $File "hl2\npc_alyx_episodic.h" + $File "hl2\npc_antlion.cpp" + $File "hl2\npc_antlion.h" + $File "hl2\npc_antlionguard.cpp" + $File "hl2\npc_antliongrub.cpp" + $File "hl2\npc_apcdriver.cpp" + $File "hl2\npc_attackchopper.cpp" + $File "hl2\npc_attackchopper.h" + $File "hl2\npc_barnacle.cpp" + $File "hl2\npc_barnacle.h" + $File "hl2\npc_barney.cpp" + $File "hl2\npc_basescanner.cpp" + $File "hl2\npc_basescanner.h" + $File "hl2\npc_BaseZombie.cpp" + $File "hl2\npc_BaseZombie.h" + $File "hl2\npc_breen.cpp" + $File "hl2\npc_bullseye.cpp" + $File "hl2\npc_bullseye.h" + $File "hl2\npc_citizen17.cpp" + $File "hl2\npc_citizen17.h" + $File "episodic\npc_combine_cannon.cpp" + $File "hl2\npc_combine.cpp" + $File "hl2\npc_combine.h" + $File "hl2\npc_combinecamera.cpp" + $File "hl2\npc_combinedropship.cpp" + $File "hl2\npc_combinegunship.cpp" + $File "hl2\npc_combines.cpp" + $File "hl2\npc_combines.h" + $File "hl2\npc_cranedriver.cpp" + $File "hl2\npc_crow.cpp" + $File "hl2\npc_crow.h" + $File "hl2\npc_dog.cpp" + $File "hl2\npc_eli.cpp" + $File "hl2\npc_enemyfinder.cpp" + $File "hl2\npc_fastzombie.cpp" + $File "hl2\npc_fisherman.cpp" + $File "hl2\npc_gman.cpp" + $File "hl2\npc_headcrab.cpp" + $File "hl2\npc_headcrab.h" + $File "episodic\npc_hunter.cpp" + $File "episodic\npc_hunter.h" + $File "hl2\npc_ichthyosaur.cpp" + $File "hl2\npc_kleiner.cpp" + $File "hl2\npc_launcher.cpp" + $File "episodic\npc_magnusson.cpp" + $File "hl2\npc_manhack.cpp" + $File "hl2\npc_manhack.h" + $File "hl2\npc_metropolice.cpp" + $File "hl2\npc_metropolice.h" + $File "hl2\npc_monk.cpp" + $File "hl2\npc_mossman.cpp" + $File "hl2\npc_playercompanion.cpp" + $File "hl2\npc_playercompanion.h" + $File "hl2\npc_PoisonZombie.cpp" + $File "hl2\npc_rollermine.cpp" + $File "hl2\npc_rollermine.h" + $File "hl2\npc_scanner.cpp" + $File "hl2\npc_scanner.h" + $File "hl2\npc_stalker.cpp" + $File "hl2\npc_stalker.h" + $File "hl2\npc_strider.cpp" + $File "hl2\npc_strider.h" + $File "npc_talker.cpp" + $File "npc_talker.h" + $File "hl2\npc_turret_ceiling.cpp" + $File "hl2\npc_turret_floor.cpp" + $File "hl2\npc_turret_ground.cpp" + $File "hl2\npc_vortigaunt_episodic.cpp" + $File "hl2\npc_vortigaunt_episodic.h" + $File "hl2\npc_zombie.cpp" + $File "hl2\npc_zombine.cpp" + $File "hl2\point_apc_controller.cpp" + $File "hl2\prop_combine_ball.cpp" + $File "hl2\prop_combine_ball.h" + $File "episodic\prop_scalable.cpp" + $File "hl2\prop_thumper.cpp" + $File "hl2\proto_sniper.cpp" + $File "hl2\rotorwash.cpp" + $File "hl2\rotorwash.h" + $File "hl2\script_intro.cpp" + $File "hl2\script_intro.h" + $File "$SRCDIR\game\shared\script_intro_shared.cpp" + $File "hl2\vehicle_airboat.cpp" + $File "hl2\vehicle_apc.h" + $File "hl2\vehicle_cannon.cpp" + $File "hl2\vehicle_crane.cpp" + $File "hl2\vehicle_crane.h" + $File "hl2\vehicle_jeep.cpp" + $File "episodic\vehicle_jeep_episodic.cpp" + $File "episodic\vehicle_jeep_episodic.h" + $File "hl2\vehicle_prisoner_pod.cpp" + $File "hl2\vehicle_viewcontroller.cpp" + $File "hl2\weapon_357.cpp" + $File "hl2\weapon_alyxgun.cpp" + $File "hl2\weapon_alyxgun.h" + $File "hl2\weapon_annabelle.cpp" + $File "hl2\weapon_ar2.cpp" + $File "hl2\weapon_ar2.h" + $File "hl2\weapon_bugbait.cpp" + $File "hl2\weapon_citizenpackage.cpp" + $File "hl2\weapon_citizenpackage.h" + $File "hl2\weapon_crossbow.cpp" + $File "hl2\weapon_crowbar.cpp" + $File "hl2\weapon_crowbar.h" + $File "weapon_cubemap.cpp" + $File "hl2\weapon_frag.cpp" + $File "hl2\weapon_physcannon.cpp" + $File "hl2\weapon_physcannon.h" + $File "hl2\weapon_pistol.cpp" + $File "hl2\weapon_rpg.cpp" + $File "hl2\weapon_rpg.h" + $File "hl2\weapon_shotgun.cpp" + $File "hl2\weapon_smg1.cpp" + $File "episodic\weapon_striderbuster.cpp" + $File "episodic\weapon_striderbuster.h" + $File "hl2\weapon_stunstick.cpp" [!$MAPBASE] // See server_mapbase.vpc + $File "hl2\weapon_stunstick.h" [!$MAPBASE] // See server_mapbase.vpc + $File "episodic\ep1_gamestats.h" + $File "episodic\ep2_gamestats.h" + $File "episodic\ep1_gamestats.cpp" \ + "episodic\ep2_gamestats.cpp" + { + $Configuration + { + $Compiler + { + $Create/UsePrecompiledHeader "Not Using Precompiled Headers" + } + } + } + $File "hl2\func_bulletshield.cpp" + $File "hl2\func_bulletshield.h" + $File "episodic\npc_puppet.cpp" + + + $Folder "unused" + { + $File "hl2\grenade_beam.cpp" + $File "hl2\grenade_beam.h" + $File "hl2\grenade_homer.cpp" + $File "hl2\grenade_homer.h" + $File "hl2\grenade_pathfollower.cpp" + $File "hl2\grenade_pathfollower.h" + $File "hl2\npc_missiledefense.cpp" + $File "hl2\vehicle_apc.cpp" + $File "hl2\weapon_cguard.cpp" + $File "hl2\weapon_flaregun.cpp" + $File "hl2\weapon_flaregun.h" + } + } + } +} diff --git a/game/server/server_hl2.vpc b/game/server/server_hl2.vpc new file mode 100644 index 00000000..d5b83f45 --- /dev/null +++ b/game/server/server_hl2.vpc @@ -0,0 +1,269 @@ +//----------------------------------------------------------------------------- +// SERVER_HL2.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "hl2" [!$SOURCESDK] +$Macro GAMENAME "mod_hl2" [$SOURCESDK] + +$Include "$SRCDIR\game\server\server_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2;.\hl2" + $PreprocessorDefinitions "$BASE;HL2_DLL;USES_SAVERESTORE" + } +} + +$Project "Server (HL2)" +{ + $Folder "Source Files" + { + $File "ai_eventresponse.cpp" + $File "ai_eventresponse.h" + $File "ai_relationship.cpp" + $File "base_gameinterface.cpp" + $File "basegrenade_concussion.cpp" + $File "basegrenade_contact.cpp" + $File "basegrenade_timed.cpp" + $File "EntityFlame.h" + $File "hl2\Func_Monitor.cpp" + $File "grenadethrown.cpp" + $File "grenadethrown.h" + $File "h_cycler.cpp" + $File "h_cycler.h" + $File "logic_achievement.cpp" + $File "monstermaker.cpp" + $File "monstermaker.h" + $File "physics_bone_follower.h" + $File "$SRCDIR\game\shared\ragdoll_shared.h" + $File "$SRCDIR\game\shared\solidsetdefaults.h" + $File "$SRCDIR\game\shared\hl2\survival_gamerules.cpp" + $File "team_spawnpoint.cpp" + $File "team_spawnpoint.h" + $File "$SRCDIR\game\shared\touchlink.h" + $File "vehicle_choreo_generic.cpp" + $File "$SRCDIR\game\shared\vehicle_choreo_generic_shared.h" + $File "$SRCDIR\game\shared\weapon_parse_default.cpp" + + $Folder "HL2 DLL" + { + $File "$SRCDIR\game\shared\hl2\achievements_hl2.cpp" + $File "hl2\ai_allymanager.cpp" + $File "hl2\ai_behavior_actbusy.cpp" + $File "hl2\ai_behavior_actbusy.h" + $File "hl2\ai_behavior_functank.cpp" + $File "hl2\ai_behavior_functank.h" + $File "hl2\ai_behavior_holster.cpp" + $File "hl2\ai_behavior_holster.h" + $File "hl2\ai_behavior_operator.cpp" + $File "hl2\ai_behavior_operator.h" + $File "hl2\ai_behavior_police.cpp" + $File "hl2\ai_behavior_police.h" + $File "hl2\ai_goal_police.cpp" + $File "hl2\ai_goal_police.h" + $File "hl2\ai_interactions.h" + $File "hl2\ai_spotlight.cpp" + $File "hl2\ai_spotlight.h" + $File "hl2\antlion_dust.cpp" + $File "hl2\antlion_dust.h" + $File "hl2\antlion_maker.cpp" + $File "hl2\antlion_maker.h" + $File "hl2\ar2_explosion.cpp" + $File "hl2\ar2_explosion.h" + $File "basebludgeonweapon.cpp" + $File "basebludgeonweapon.h" + $File "hl2\basehlcombatweapon.cpp" + $File "hl2\basehlcombatweapon.h" + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" + $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.h" + $File "hl2\cbasehelicopter.cpp" + $File "hl2\cbasehelicopter.h" + $File "hl2\cbasespriteprojectile.cpp" + $File "hl2\cbasespriteprojectile.h" + $File "hl2\citadel_effects.cpp" + $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" + $File "hl2\combine_mine.cpp" + $File "hl2\combine_mine.h" + $File "hl2\energy_wave.h" + $File "hl2\env_alyxemp.cpp" + $File "$SRCDIR\game\shared\hl2\env_alyxemp_shared.h" + $File "hl2\env_headcrabcanister.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" + $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" + $File "hl2\env_speaker.cpp" + $File "hl2\env_speaker.h" + $File "hl2\env_starfield.cpp" + $File "hl2\func_recharge.cpp" + $File "hl2\func_tank.cpp" + $File "hl2\func_tank.h" + $File "hl2\grenade_ar2.cpp" + $File "hl2\grenade_ar2.h" + $File "hl2\grenade_bugbait.cpp" + $File "hl2\grenade_bugbait.h" + $File "hl2\grenade_frag.cpp" + $File "hl2\grenade_frag.h" + $File "hl2\hl2_ai_network.cpp" + $File "hl2\hl2_client.cpp" + $File "hl2\hl2_eventlog.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" + $File "hl2\hl2_gamestats.cpp" + $File "hl2\hl2_gamestats.h" + $File "hl2\hl2_player.cpp" + $File "hl2\hl2_player.h" + $File "$SRCDIR\game\shared\hl2\hl2_player_shared.h" + $File "hl2\hl2_playerlocaldata.cpp" + $File "hl2\hl2_playerlocaldata.h" + $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" + $File "hl2\hl2_triggers.cpp" + $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" + $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" + $File "$SRCDIR\game\shared\hl2\hl_movedata.h" + $File "hl2\hl_playermove.cpp" + $File "hl2\info_darknessmode_lightsource.cpp" + $File "hl2\info_darknessmode_lightsource.h" + $File "hl2\info_teleporter_countdown.cpp" + $File "hl2\item_ammo.cpp" + $File "hl2\item_battery.cpp" + $File "hl2\item_dynamic_resupply.cpp" + $File "hl2\item_dynamic_resupply.h" + $File "hl2\item_healthkit.cpp" + $File "hl2\item_itemcrate.cpp" + $File "hl2\item_suit.cpp" + $File "hl2\look_door.cpp" + $File "hl2\monster_dummy.cpp" + $File "hl2\npc_alyx.cpp" + $File "hl2\npc_alyx.h" + $File "hl2\npc_alyx_episodic.h" + $File "hl2\npc_antlion.cpp" + $File "hl2\npc_antlion.h" + $File "hl2\npc_antlionguard.cpp" + $File "hl2\npc_apcdriver.cpp" + $File "hl2\npc_attackchopper.cpp" + $File "hl2\npc_attackchopper.h" + $File "hl2\npc_barnacle.cpp" + $File "hl2\npc_barnacle.h" + $File "hl2\npc_barney.cpp" + $File "hl2\npc_basescanner.cpp" + $File "hl2\npc_basescanner.h" + $File "hl2\npc_BaseZombie.cpp" + $File "hl2\npc_BaseZombie.h" + $File "hl2\npc_blob.cpp" + $File "hl2\npc_breen.cpp" + $File "hl2\npc_bullseye.cpp" + $File "hl2\npc_bullseye.h" + $File "hl2\npc_citizen17.cpp" + $File "hl2\npc_citizen17.h" + $File "hl2\npc_combine.cpp" + $File "hl2\npc_combine.h" + $File "hl2\npc_combinecamera.cpp" + $File "hl2\npc_combinedropship.cpp" + $File "hl2\npc_combinegunship.cpp" + $File "hl2\npc_combines.cpp" + $File "hl2\npc_combines.h" + $File "hl2\npc_cranedriver.cpp" + $File "hl2\npc_crow.cpp" + $File "hl2\npc_crow.h" + $File "hl2\npc_dog.cpp" + $File "hl2\npc_eli.cpp" + $File "hl2\npc_enemyfinder.cpp" + $File "hl2\npc_fastzombie.cpp" + $File "hl2\npc_fisherman.cpp" + $File "hl2\npc_gman.cpp" + $File "hl2\npc_headcrab.cpp" + $File "hl2\npc_headcrab.h" + $File "hl2\npc_ichthyosaur.cpp" + $File "hl2\npc_kleiner.cpp" + $File "hl2\npc_launcher.cpp" + $File "hl2\npc_manhack.cpp" + $File "hl2\npc_manhack.h" + $File "hl2\npc_metropolice.cpp" + $File "hl2\npc_metropolice.h" + $File "hl2\npc_monk.cpp" + $File "hl2\npc_mossman.cpp" + $File "hl2\npc_playercompanion.cpp" + $File "hl2\npc_playercompanion.h" + $File "hl2\npc_PoisonZombie.cpp" + $File "hl2\npc_rollermine.cpp" + $File "hl2\npc_rollermine.h" + $File "hl2\npc_scanner.cpp" + $File "hl2\npc_scanner.h" + $File "hl2\npc_stalker.cpp" + $File "hl2\npc_stalker.h" + $File "hl2\npc_strider.cpp" + $File "hl2\npc_strider.h" + $File "npc_talker.cpp" + $File "npc_talker.h" + $File "hl2\npc_turret_ceiling.cpp" + $File "hl2\npc_turret_floor.cpp" + $File "hl2\npc_turret_floor.h" + $File "hl2\npc_turret_ground.cpp" + $File "hl2\npc_turret_ground.h" + $File "hl2\npc_vortigaunt_episodic.cpp" + $File "hl2\npc_vortigaunt_episodic.h" + $File "hl2\npc_zombie.cpp" + $File "hl2\point_apc_controller.cpp" + $File "hl2\prop_combine_ball.cpp" + $File "hl2\prop_combine_ball.h" + $File "hl2\prop_thumper.cpp" + $File "hl2\proto_sniper.cpp" + $File "hl2\rotorwash.cpp" + $File "hl2\rotorwash.h" + $File "hl2\script_intro.cpp" + $File "hl2\script_intro.h" + $File "$SRCDIR\game\shared\script_intro_shared.cpp" + $File "hl2\vehicle_airboat.cpp" + $File "hl2\vehicle_apc.h" + $File "hl2\vehicle_cannon.cpp" + $File "hl2\vehicle_crane.cpp" + $File "hl2\vehicle_crane.h" + $File "hl2\vehicle_jeep.cpp" + $File "hl2\vehicle_prisoner_pod.cpp" + $File "hl2\vehicle_viewcontroller.cpp" + $File "hl2\weapon_357.cpp" + $File "hl2\weapon_alyxgun.cpp" + $File "hl2\weapon_alyxgun.h" + $File "hl2\weapon_annabelle.cpp" + $File "hl2\weapon_ar2.cpp" + $File "hl2\weapon_ar2.h" + $File "hl2\weapon_bugbait.cpp" + $File "hl2\weapon_citizenpackage.cpp" + $File "hl2\weapon_citizenpackage.h" + $File "hl2\weapon_crossbow.cpp" + $File "hl2\weapon_crowbar.cpp" + $File "hl2\weapon_crowbar.h" + $File "weapon_cubemap.cpp" + $File "hl2\weapon_frag.cpp" + $File "hl2\weapon_physcannon.cpp" + $File "hl2\weapon_physcannon.h" + $File "hl2\weapon_pistol.cpp" + $File "hl2\weapon_rpg.cpp" + $File "hl2\weapon_rpg.h" + $File "hl2\weapon_shotgun.cpp" + $File "hl2\weapon_smg1.cpp" + $File "hl2\weapon_stunstick.cpp" [!$MAPBASE] // See server_mapbase.vpc + $File "hl2\weapon_stunstick.h" [!$MAPBASE] // See server_mapbase.vpc + + $Folder "Unused" + { + $File "hl2\grenade_beam.cpp" + $File "hl2\grenade_beam.h" + $File "hl2\grenade_homer.cpp" + $File "hl2\grenade_homer.h" + $File "hl2\grenade_pathfollower.cpp" + $File "hl2\grenade_pathfollower.h" + $File "hl2\npc_missiledefense.cpp" + $File "hl2\vehicle_apc.cpp" + $File "hl2\weapon_cguard.cpp" + $File "hl2\weapon_flaregun.cpp" + $File "hl2\weapon_flaregun.h" + } + } + } +} diff --git a/game/server/server_hl2mp.vpc b/game/server/server_hl2mp.vpc deleted file mode 100644 index 46d039db..00000000 --- a/game/server/server_hl2mp.vpc +++ /dev/null @@ -1,296 +0,0 @@ -//----------------------------------------------------------------------------- -// SERVER_HL2MP.VPC -// -// Project Script -//----------------------------------------------------------------------------- - -$Macro SRCDIR "..\.." -$Macro GAMENAME "hl2mp" [!$SOURCESDK] -$Macro GAMENAME "mod_hl2mp" [$SOURCESDK] - -$Include "$SRCDIR\game\server\server_base.vpc" -$Include "$SRCDIR\game\server\nav_mesh.vpc" [$SOURCESDK] - -$Configuration -{ - $Compiler - { - $AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2,.\hl2,.\hl2mp,$SRCDIR\game\shared\hl2mp" - $PreprocessorDefinitions "$BASE;HL2MP;HL2_DLL" - } -} - -$Project "Server (HL2MP)" -{ - $Folder "Source Files" - { - $File "ai_relationship.cpp" - $File "basegrenade_concussion.cpp" - $File "basegrenade_contact.cpp" - $File "basegrenade_timed.cpp" - $File "EntityFlame.h" - $File "hl2\Func_Monitor.cpp" - $File "grenadethrown.cpp" - $File "grenadethrown.h" - $File "h_cycler.cpp" - $File "h_cycler.h" - $File "monstermaker.cpp" - $File "monstermaker.h" - $File "physics_bone_follower.h" - $File "$SRCDIR\game\shared\predicted_viewmodel.cpp" - $File "$SRCDIR\game\shared\predicted_viewmodel.h" - $File "$SRCDIR\game\shared\ragdoll_shared.h" - $File "$SRCDIR\game\shared\solidsetdefaults.h" - $File "$SRCDIR\game\shared\hl2\survival_gamerules.cpp" - $File "team_objectiveresource.cpp" - $File "team_objectiveresource.h" - $File "team_spawnpoint.cpp" - $File "team_spawnpoint.h" - $File "team_control_point.cpp" - $File "team_control_point.h" - $File "team_control_point_master.cpp" - $File "team_control_point_master.h" - $File "team_control_point_round.cpp" - $File "team_control_point_round.h" - $File "team_train_watcher.cpp" - $File "team_train_watcher.h" - $File "$SRCDIR\game\shared\teamplayroundbased_gamerules.cpp" - $File "$SRCDIR\game\shared\touchlink.h" - $File "trigger_area_capture.cpp" - $File "trigger_area_capture.h" - $File "$SRCDIR\game\shared\teamplay_round_timer.cpp" - $File "$SRCDIR\game\shared\teamplay_round_timer.h" - - $Folder "HL2 DLL" - { - $File "hl2\ai_allymanager.cpp" - $File "hl2\ai_behavior_actbusy.cpp" - $File "hl2\ai_behavior_actbusy.h" - $File "hl2\ai_behavior_functank.cpp" - $File "hl2\ai_behavior_functank.h" - $File "hl2\ai_behavior_holster.cpp" - $File "hl2\ai_behavior_holster.h" - $File "hl2\ai_behavior_police.cpp" - $File "hl2\ai_behavior_police.h" - $File "hl2\ai_goal_police.cpp" - $File "hl2\ai_goal_police.h" - $File "hl2\ai_interactions.h" - $File "hl2\ai_spotlight.cpp" - $File "hl2\ai_spotlight.h" - $File "hl2\antlion_dust.cpp" - $File "hl2\antlion_dust.h" - $File "hl2\antlion_maker.cpp" - $File "hl2\antlion_maker.h" - $File "hl2\ar2_explosion.cpp" - $File "hl2\ar2_explosion.h" - $File "basebludgeonweapon.cpp" - $File "basebludgeonweapon.h" - $File "hl2\basehlcombatweapon.cpp" - $File "hl2\basehlcombatweapon.h" - $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.cpp" - $File "$SRCDIR\game\shared\hl2\basehlcombatweapon_shared.h" - $File "hl2\cbasehelicopter.cpp" - $File "hl2\cbasehelicopter.h" - $File "hl2\cbasespriteprojectile.cpp" - $File "hl2\cbasespriteprojectile.h" - $File "hl2\citadel_effects.cpp" - $File "$SRCDIR\game\shared\hl2\citadel_effects_shared.h" - $File "hl2\combine_mine.cpp" - $File "hl2\combine_mine.h" - $File "hl2\energy_wave.h" - $File "hl2\env_alyxemp.cpp" - $File "$SRCDIR\game\shared\hl2\env_alyxemp_shared.h" - $File "hl2\env_headcrabcanister.cpp" - $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.cpp" - $File "$SRCDIR\game\shared\hl2\env_headcrabcanister_shared.h" - $File "hl2\env_speaker.cpp" - $File "hl2\env_starfield.cpp" - $File "hl2\func_recharge.cpp" - $File "hl2\func_tank.cpp" - $File "hl2\func_tank.h" - $File "hl2\grenade_ar2.cpp" - $File "hl2\grenade_ar2.h" - $File "hl2\grenade_bugbait.cpp" - $File "hl2\grenade_bugbait.h" - $File "hl2\grenade_frag.cpp" - $File "hl2\grenade_frag.h" - $File "hl2\hl2_ai_network.cpp" - $File "hl2\hl2_eventlog.cpp" - $File "$SRCDIR\game\shared\hl2\hl2_gamerules.cpp" - $File "$SRCDIR\game\shared\hl2\hl2_gamerules.h" - $File "hl2\hl2_player.cpp" - $File "hl2\hl2_player.h" - $File "$SRCDIR\game\shared\hl2\hl2_player_shared.h" - $File "hl2\hl2_playerlocaldata.cpp" - $File "hl2\hl2_playerlocaldata.h" - $File "$SRCDIR\game\shared\hl2\hl2_shareddefs.h" - $File "hl2\hl2_triggers.cpp" - $File "$SRCDIR\game\shared\hl2\hl2_usermessages.cpp" - $File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp" - $File "$SRCDIR\game\shared\hl2\hl_gamemovement.h" - $File "$SRCDIR\game\shared\hl2\hl_movedata.h" - $File "hl2\hl_playermove.cpp" - $File "hl2\info_teleporter_countdown.cpp" - $File "hl2\item_ammo.cpp" - $File "hl2\item_battery.cpp" - $File "hl2\item_dynamic_resupply.cpp" - $File "hl2\item_dynamic_resupply.h" - $File "hl2\item_healthkit.cpp" - $File "hl2\item_itemcrate.cpp" - $File "hl2\item_suit.cpp" - $File "hl2\look_door.cpp" - $File "hl2\monster_dummy.cpp" - $File "hl2\npc_alyx.cpp" - $File "hl2\npc_alyx.h" - $File "hl2\npc_antlion.cpp" - $File "hl2\npc_antlion.h" - $File "hl2\npc_antlionguard.cpp" - $File "hl2\npc_apcdriver.cpp" - $File "hl2\npc_attackchopper.cpp" - $File "hl2\npc_attackchopper.h" - $File "hl2\npc_barnacle.cpp" - $File "hl2\npc_barnacle.h" - $File "hl2\npc_barney.cpp" - $File "hl2\npc_basescanner.cpp" - $File "hl2\npc_basescanner.h" - $File "hl2\npc_BaseZombie.cpp" - $File "hl2\npc_BaseZombie.h" - $File "hl2\npc_breen.cpp" - $File "hl2\npc_bullseye.cpp" - $File "hl2\npc_bullseye.h" - $File "hl2\npc_citizen17.cpp" - $File "hl2\npc_citizen17.h" - $File "hl2\npc_combine.cpp" - $File "hl2\npc_combine.h" - $File "hl2\npc_combinecamera.cpp" - $File "hl2\npc_combinedropship.cpp" - $File "hl2\npc_combinegunship.cpp" - $File "hl2\npc_combines.cpp" - $File "hl2\npc_combines.h" - $File "hl2\npc_cranedriver.cpp" - $File "hl2\npc_crow.cpp" - $File "hl2\npc_crow.h" - $File "hl2\npc_dog.cpp" - $File "hl2\npc_eli.cpp" - $File "hl2\npc_enemyfinder.cpp" - $File "hl2\npc_fisherman.cpp" - $File "hl2\npc_gman.cpp" - $File "hl2\npc_headcrab.cpp" - $File "hl2\npc_headcrab.h" - $File "hl2\npc_ichthyosaur.cpp" - $File "hl2\npc_kleiner.cpp" - $File "hl2\npc_launcher.cpp" - $File "hl2\npc_manhack.cpp" - $File "hl2\npc_manhack.h" - $File "hl2\npc_metropolice.cpp" - $File "hl2\npc_metropolice.h" - $File "hl2\npc_monk.cpp" - $File "hl2\npc_mossman.cpp" - $File "hl2\npc_playercompanion.cpp" - $File "hl2\npc_playercompanion.h" - $File "hl2\npc_PoisonZombie.cpp" - $File "hl2\npc_rollermine.cpp" - $File "hl2\npc_rollermine.h" - $File "hl2\npc_scanner.cpp" - $File "hl2\npc_stalker.cpp" - $File "hl2\npc_stalker.h" - $File "hl2\npc_strider.cpp" - $File "hl2\npc_strider.h" - $File "npc_talker.cpp" - $File "npc_talker.h" - $File "hl2\npc_turret_ceiling.cpp" - $File "hl2\npc_turret_floor.cpp" - $File "hl2\npc_turret_ground.cpp" - $File "hl2\npc_vortigaunt_episodic.cpp" - $File "hl2\npc_vortigaunt_episodic.h" - $File "hl2\npc_zombie.cpp" - $File "hl2\point_apc_controller.cpp" - $File "hl2\prop_combine_ball.cpp" - $File "hl2\prop_combine_ball.h" - $File "hl2\prop_thumper.cpp" - $File "hl2\proto_sniper.cpp" - $File "hl2\rotorwash.cpp" - $File "hl2\rotorwash.h" - $File "hl2\script_intro.cpp" - $File "hl2\script_intro.h" - $File "$SRCDIR\game\shared\script_intro_shared.cpp" - $File "hl2\vehicle_airboat.cpp" - $File "hl2\vehicle_apc.h" - $File "hl2\vehicle_crane.cpp" - $File "hl2\vehicle_crane.h" - $File "hl2\vehicle_prisoner_pod.cpp" - $File "hl2\vehicle_viewcontroller.cpp" - $File "hl2\weapon_alyxgun.h" - $File "hl2\weapon_annabelle.cpp" - $File "hl2\weapon_bugbait.cpp" - $File "hl2\weapon_crowbar.h" - $File "weapon_cubemap.cpp" - - $Folder "unused" - { - $File "hl2\grenade_beam.cpp" - $File "hl2\grenade_beam.h" - $File "hl2\grenade_homer.cpp" - $File "hl2\grenade_homer.h" - $File "hl2\grenade_pathfollower.cpp" - $File "hl2\grenade_pathfollower.h" - $File "hl2\npc_missiledefense.cpp" - $File "hl2\vehicle_apc.cpp" - $File "hl2\weapon_cguard.cpp" - $File "hl2\weapon_flaregun.cpp" - $File "hl2\weapon_flaregun.h" - } - } - - $Folder "HL2MP" - { - $File "hl2mp\hl2mp_bot_temp.cpp" - $File "hl2mp\hl2mp_bot_temp.h" - $File "hl2mp\hl2mp_client.cpp" - $File "hl2mp\hl2mp_cvars.cpp" - $File "hl2mp\hl2mp_gameinterface.cpp" - $File "hl2mp\hl2mp_gameinterface.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_gamerules.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_gamerules.h" - $File "hl2mp\hl2mp_player.cpp" - $File "hl2mp\hl2mp_player.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp" - $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h" - - $Folder "Weapons" - { - $File "hl2mp\grenade_satchel.cpp" - $File "hl2mp\grenade_satchel.h" - $File "hl2mp\grenade_tripmine.cpp" - $File "hl2mp\grenade_tripmine.h" - $File "hl2mp\te_hl2mp_shotgun_shot.cpp" - $File "hl2mp\te_hl2mp_shotgun_shot.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_357.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_ar2.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_ar2.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_crossbow.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_crowbar.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_frag.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase_machinegun.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbase_machinegun.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasebasebludgeon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasehlmpcombatweapon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_hl2mpbasehlmpcombatweapon.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_physcannon.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_physcannon.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_pistol.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_rpg.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_rpg.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_shotgun.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_slam.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_slam.h" - $File "$SRCDIR\game\shared\hl2mp\weapon_smg1.cpp" - $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.cpp" - } - } - } -} diff --git a/game/server/server_mapbase.vpc b/game/server/server_mapbase.vpc new file mode 100644 index 00000000..b04706d4 --- /dev/null +++ b/game/server/server_mapbase.vpc @@ -0,0 +1,121 @@ +//----------------------------------------------------------------------------- +// SERVER_MAPBASE.VPC +// +// Project Base Script +//----------------------------------------------------------------------------- + +$Configuration +{ + $Compiler + { + $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS;GLOWS_ENABLE" + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] + $PreprocessorDefinitions "$BASE;NEW_RESPONSE_SYSTEM" [$NEW_RESPONSE_SYSTEM] + } +} + +$Project +{ + $Folder "Source Files" + { + $File "logic_random_outputs.cpp" + $File "point_entity_finder.cpp" + $File "env_projectedtexture.h" + $File "env_global_light.cpp" + $File "skyboxswapper.cpp" + $File "env_instructor_hint.cpp" + $File "postprocesscontroller.cpp" + $File "postprocesscontroller.h" + $File "env_dof_controller.cpp" + $File "env_dof_controller.h" + $File "logic_playmovie.cpp" + $File "movie_display.cpp" + $File "fogvolume.cpp" + $File "fogvolume.h" + $File "ai_expresserfollowup.cpp" [$NEW_RESPONSE_SYSTEM] + $File "ai_speechqueue.cpp" [$NEW_RESPONSE_SYSTEM] + $File "ai_speechqueue.h" [$NEW_RESPONSE_SYSTEM] + + $Folder "Mapbase" + { + $File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_usermessages.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp" + $File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp" + $File "$SRCDIR\game\shared\mapbase\MapEdit.cpp" + $File "$SRCDIR\game\shared\mapbase\MapEdit.h" + $File "$SRCDIR\game\shared\mapbase\matchers.cpp" + $File "$SRCDIR\game\shared\mapbase\matchers.h" + $File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.cpp" + $File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.h" + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_singletons.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_consts_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_consts_weapons.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\weapon_custom_scripted.h" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\logic_script_client.cpp" [$MAPBASE_VSCRIPT] + + $File "mapbase\ai_grenade.cpp" + $File "mapbase\ai_grenade.h" + $File "mapbase\ai_monitor.cpp" + $File "mapbase\ai_weaponmodifier.cpp" + $File "mapbase\closecaption_entity.cpp" + $File "mapbase\datadesc_mod.cpp" + $File "mapbase\datadesc_mod.h" + $File "mapbase\expandedrs_combine.h" + $File "mapbase\func_clientclip.cpp" + $File "mapbase\func_fake_worldportal.cpp" + $File "mapbase\GlobalStrings.cpp" + $File "mapbase\GlobalStrings.h" + $File "mapbase\logic_externaldata.cpp" + $File "mapbase\logic_skill.cpp" + $File "mapbase\logic_substring.cpp" + $File "mapbase\point_advanced_finder.cpp" + $File "mapbase\point_copy_size.cpp" + $File "mapbase\point_damageinfo.cpp" + $File "mapbase\point_entity_replace.cpp" + //$File "mapbase\point_physics_control.cpp" // Backlogged + $File "mapbase\point_projectile.cpp" + $File "mapbase\point_radiation_source.cpp" + $File "mapbase\point_glow.cpp" + $File "mapbase\SystemConvarMod.cpp" + $File "mapbase\SystemConvarMod.h" + $File "mapbase\variant_tools.h" + $File "mapbase\vgui_text_display.cpp" + + $File "mapbase\logic_eventlistener.cpp" + $File "mapbase\logic_register_activator.cpp" + } + + $Folder "HL2 DLL" + { + // Original stunstick files are conditional'd out in the HL2 VPCs + $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.cpp" + $File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.h" + } + + $Folder "HL2MP" + { + $Folder "Weapons" + { + $File "hl2mp\grenade_satchel.cpp" + $File "hl2mp\grenade_satchel.h" + $File "hl2mp\grenade_tripmine.cpp" + $File "hl2mp\grenade_tripmine.h" + + $File "$SRCDIR\game\shared\hl2mp\weapon_slam.cpp" + $File "$SRCDIR\game\shared\hl2mp\weapon_slam.h" + } + } + } + + $Folder "Link Libraries" + { + $Lib "vscript" [$MAPBASE_VSCRIPT] + $Lib "responserules" [$NEW_RESPONSE_SYSTEM] + } +} diff --git a/game/server/server_vance.vpc b/game/server/server_vance.vpc index 8a7e954b..02f8a7fc 100644 --- a/game/server/server_vance.vpc +++ b/game/server/server_vance.vpc @@ -46,16 +46,19 @@ $Project "Server (Vance)" $File "vehicle_choreo_generic.cpp" $File "$SRCDIR\game\shared\vehicle_choreo_generic_shared.h" $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h" - + -$File "env_global_light.cpp" + $Folder "VANCE" { + $File "vance\env_global_light.cpp" + $File "vance\vance_client.cpp" $File "vance\npc_assassin.cpp" $File "vance\npc_assassin.h" - $File "vance\npc_combine.cpp" - $File "vance\npc_combine.h" - $File "vance\npc_combines.cpp" - $File "vance\npc_combines.h" + //$File "vance\npc_combine.cpp" + //$File "vance\npc_combine.h" + //$File "vance\npc_combines.cpp" + //$File "vance\npc_combines.h" $File "vance\npc_houndeye.cpp" $File "vance\npc_houndeye.h" $File "vance\npc_bullsquid.cpp" @@ -92,19 +95,21 @@ $Project "Server (Vance)" $File "vance\vance_player.h" $File "vance\lights_deferred.cpp" $File "vance\lights_deferred.h" - + $File "projectile_bullet.cpp" + $File "projectile_bullet.h" + $File "$SRCDIR\game\shared\vance\vance_baseweapon_shared.cpp" $File "$SRCDIR\game\shared\vance\vance_baseweapon_shared.h" $File "$SRCDIR\game\shared\vance\vance_weapon_parse.cpp" $File "$SRCDIR\game\shared\vance\vance_weapon_parse.h" $File "$SRCDIR\game\shared\vance\vance_viewmodel.cpp" $File "$SRCDIR\game\shared\vance\vance_viewmodel.h" - $File "$SRCDIR\game\shared\vance\singleplayer_animstate.cpp" - $File "$SRCDIR\game\shared\vance\singleplayer_animstate.h" + //$File "$SRCDIR\game\shared\vance\singleplayer_animstate.cpp" + //$File "$SRCDIR\game\shared\vance\singleplayer_animstate.h" $File "$SRCDIR\game\shared\vance\vance_gamerules.cpp" $File "$SRCDIR\game\shared\vance\vance_gamerules.h" $File "$SRCDIR\game\shared\vance\vance_shareddefs.h" - + $File "$SRCDIR\game\shared\vance\weapon_akms.cpp" $File "$SRCDIR\game\shared\vance\weapon_melee.cpp" } @@ -226,9 +231,13 @@ $Project "Server (Vance)" $File "hl2\npc_citizen17.cpp" $File "hl2\npc_citizen17.h" $File "episodic\npc_combine_cannon.cpp" + $File "hl2\npc_combine.cpp" + $File "hl2\npc_combine.h" $File "hl2\npc_combinecamera.cpp" $File "hl2\npc_combinedropship.cpp" $File "hl2\npc_combinegunship.cpp" + $File "hl2\npc_combines.cpp" + $File "hl2\npc_combines.h" $File "hl2\npc_cranedriver.cpp" $File "hl2\npc_crow.cpp" $File "hl2\npc_crow.h" @@ -306,8 +315,8 @@ $Project "Server (Vance)" $File "hl2\weapon_pistol.cpp" $File "episodic\weapon_striderbuster.cpp" $File "episodic\weapon_striderbuster.h" - $File "hl2\weapon_stunstick.cpp" - $File "hl2\weapon_stunstick.h" + $File "hl2\weapon_stunstick.cpp" [!$MAPBASE] // See server_mapbase.vpc + $File "hl2\weapon_stunstick.h" [!$MAPBASE] // See server_mapbase.vpc $File "episodic\ep1_gamestats.h" $File "episodic\ep2_gamestats.h" $File "episodic\ep1_gamestats.cpp" \ diff --git a/game/server/shadowcontrol.cpp b/game/server/shadowcontrol.cpp index 36c23c28..8db9665d 100644 --- a/game/server/shadowcontrol.cpp +++ b/game/server/shadowcontrol.cpp @@ -40,6 +40,9 @@ class CShadowControl : public CBaseEntity CNetworkColor32( m_shadowColor ); CNetworkVar( float, m_flShadowMaxDist ); CNetworkVar( bool, m_bDisableShadows ); +#ifdef MAPBASE + CNetworkVar( bool, m_bEnableLocalLightShadows ); +#endif }; LINK_ENTITY_TO_CLASS(shadow_control, CShadowControl); @@ -48,12 +51,18 @@ BEGIN_DATADESC( CShadowControl ) DEFINE_KEYFIELD( m_flShadowMaxDist, FIELD_FLOAT, "distance" ), DEFINE_KEYFIELD( m_bDisableShadows, FIELD_BOOLEAN, "disableallshadows" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bEnableLocalLightShadows, FIELD_BOOLEAN, "enableshadowsfromlocallights" ), +#endif // Inputs DEFINE_INPUT( m_shadowColor, FIELD_COLOR32, "color" ), DEFINE_INPUT( m_shadowDirection, FIELD_VECTOR, "direction" ), DEFINE_INPUT( m_flShadowMaxDist, FIELD_FLOAT, "SetDistance" ), DEFINE_INPUT( m_bDisableShadows, FIELD_BOOLEAN, "SetShadowsDisabled" ), +#ifdef MAPBASE + DEFINE_INPUT( m_bEnableLocalLightShadows, FIELD_BOOLEAN, "SetShadowsFromLocalLightsEnabled" ), +#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetAngles", InputSetAngles ), @@ -62,9 +71,17 @@ END_DATADESC() IMPLEMENT_SERVERCLASS_ST_NOBASE(CShadowControl, DT_ShadowControl) SendPropVector(SENDINFO(m_shadowDirection), -1, SPROP_NOSCALE ), +#ifdef MAPBASE + /*SendPropInt(SENDINFO(m_shadowColor), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),*/ + SendPropInt(SENDINFO(m_shadowColor), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt ), +#else SendPropInt(SENDINFO(m_shadowColor), 32, SPROP_UNSIGNED), +#endif SendPropFloat(SENDINFO(m_flShadowMaxDist), 0, SPROP_NOSCALE ), SendPropBool(SENDINFO(m_bDisableShadows)), +#ifdef MAPBASE + SendPropBool(SENDINFO(m_bEnableLocalLightShadows)), +#endif END_SEND_TABLE() @@ -74,6 +91,9 @@ CShadowControl::CShadowControl() m_flShadowMaxDist = 50.0f; m_shadowColor.Init( 64, 64, 64, 0 ); m_bDisableShadows = false; +#ifdef MAPBASE + m_bEnableLocalLightShadows = false; +#endif } diff --git a/game/server/skyboxswapper.cpp b/game/server/skyboxswapper.cpp new file mode 100644 index 00000000..40d1f2ba --- /dev/null +++ b/game/server/skyboxswapper.cpp @@ -0,0 +1,80 @@ +//=========== Copyright (c) Valve Corporation, All rights reserved. =========== +// +// Simple entity to switch the map's 2D skybox texture when triggered. +// +//============================================================================= + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// CSkyboxSwapper +//----------------------------------------------------------------------------- +class CSkyboxSwapper : public CServerOnlyPointEntity +{ + DECLARE_CLASS( CSkyboxSwapper, CServerOnlyPointEntity ); +public: + DECLARE_DATADESC(); + + virtual void Spawn( void ); + virtual void Precache( void ); + + void InputTrigger( inputdata_t &inputdata ); + +protected: + string_t m_iszSkyboxName; +}; + +LINK_ENTITY_TO_CLASS(skybox_swapper, CSkyboxSwapper); + +BEGIN_DATADESC( CSkyboxSwapper ) + DEFINE_KEYFIELD( m_iszSkyboxName, FIELD_STRING, "SkyboxName" ), + // Inputs + DEFINE_INPUTFUNC(FIELD_VOID, "Trigger", InputTrigger), +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: not much +//----------------------------------------------------------------------------- +void CSkyboxSwapper::Spawn( void ) +{ + Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: Precache the skybox materials. +//----------------------------------------------------------------------------- +void CSkyboxSwapper::Precache( void ) +{ + if ( Q_strlen( m_iszSkyboxName.ToCStr() ) == 0 ) + { + Warning( "skybox_swapper (%s) has no skybox specified!\n", STRING(GetEntityName()) ); + return; + } + + char name[ MAX_PATH ]; + char *skyboxsuffix[ 6 ] = { "rt", "bk", "lf", "ft", "up", "dn" }; + for ( int i = 0; i < 6; i++ ) + { + Q_snprintf( name, sizeof( name ), "skybox/%s%s", m_iszSkyboxName.ToCStr(), skyboxsuffix[i] ); + PrecacheMaterial( name ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that triggers the skybox swap. +//----------------------------------------------------------------------------- +void CSkyboxSwapper::InputTrigger( inputdata_t &inputdata ) +{ + static ConVarRef skyname( "sv_skyname", false ); + if ( !skyname.IsValid() ) + { + Warning( "skybox_swapper (%s) trigger input failed - cannot find 'sv_skyname' convar!\n", STRING(GetEntityName()) ); + return; + } + skyname.SetValue( m_iszSkyboxName.ToCStr() ); +} diff --git a/game/server/slideshow_display.cpp b/game/server/slideshow_display.cpp index 12e19ceb..79e78841 100644 --- a/game/server/slideshow_display.cpp +++ b/game/server/slideshow_display.cpp @@ -528,8 +528,8 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void ) if ( bLoaded ) { - char szKeywords[ 256 ] = {0}; - V_strcpy_safe( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) ); + char szKeywords[ 256 ]; + Q_strcpy( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) ); char *pchKeyword = szKeywords; @@ -562,7 +562,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void ) { // Couldn't find the list, so create it iList = m_SlideKeywordList.AddToTail( new SlideKeywordList_t ); - V_strcpy_safe( m_SlideKeywordList[iList]->szSlideKeyword, pchKeyword ); + Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, pchKeyword ); } pchKeyword = pNextKeyword; @@ -581,7 +581,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void ) { // Couldn't find the generic list, so create it iList = m_SlideKeywordList.AddToHead( new SlideKeywordList_t ); - V_strcpy_safe( m_SlideKeywordList[iList]->szSlideKeyword, "" ); + Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, "" ); } if ( IsX360() ) diff --git a/game/server/sound.cpp b/game/server/sound.cpp index 1a83fafd..cb7df905 100644 --- a/game/server/sound.cpp +++ b/game/server/sound.cpp @@ -173,6 +173,9 @@ class CAmbientGeneric : public CPointEntity void ToggleSound(); void SendSound( SoundFlags_t flags ); +#ifdef MAPBASE + void SoundEnd(); +#endif // Input handlers void InputPlaySound( inputdata_t &inputdata ); @@ -182,6 +185,9 @@ class CAmbientGeneric : public CPointEntity void InputVolume( inputdata_t &inputdata ); void InputFadeIn( inputdata_t &inputdata ); void InputFadeOut( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetSound( inputdata_t &inputdata ); +#endif DECLARE_DATADESC(); @@ -197,6 +203,12 @@ class CAmbientGeneric : public CPointEntity string_t m_sSourceEntName; EHANDLE m_hSoundSource; // entity from which the sound comes int m_nSoundSourceEntIndex; // In case the entity goes away before we finish stopping the sound... + +#ifdef MAPBASE + int m_iSoundFlags; + + COutputEvent m_OnSoundFinished; +#endif }; LINK_ENTITY_TO_CLASS( ambient_generic, CAmbientGeneric ); @@ -210,6 +222,10 @@ BEGIN_DATADESC( CAmbientGeneric ) // DEFINE_FIELD( m_hSoundSource, EHANDLE ), // DEFINE_FIELD( m_nSoundSourceEntIndex, FIELD_INTERGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iSoundFlags, FIELD_INTEGER, "soundflags" ), +#endif + DEFINE_FIELD( m_flMaxRadius, FIELD_FLOAT ), DEFINE_FIELD( m_fActive, FIELD_BOOLEAN ), DEFINE_FIELD( m_fLooping, FIELD_BOOLEAN ), @@ -224,6 +240,9 @@ BEGIN_DATADESC( CAmbientGeneric ) // Function Pointers DEFINE_FUNCTION( RampThink ), +#ifdef MAPBASE + DEFINE_THINKFUNC( SoundEnd ), +#endif // Inputs DEFINE_INPUTFUNC(FIELD_VOID, "PlaySound", InputPlaySound ), @@ -233,6 +252,11 @@ BEGIN_DATADESC( CAmbientGeneric ) DEFINE_INPUTFUNC(FIELD_FLOAT, "Volume", InputVolume ), DEFINE_INPUTFUNC(FIELD_FLOAT, "FadeIn", InputFadeIn ), DEFINE_INPUTFUNC(FIELD_FLOAT, "FadeOut", InputFadeOut ), +#ifdef MAPBASE + DEFINE_INPUTFUNC(FIELD_STRING, "SetSound", InputSetSound ), + + DEFINE_OUTPUT( m_OnSoundFinished, "OnSoundFinished" ), +#endif END_DATADESC() @@ -241,6 +265,10 @@ END_DATADESC() #define SF_AMBIENT_SOUND_START_SILENT 16 #define SF_AMBIENT_SOUND_NOT_LOOPING 32 +#ifdef MAPBASE +static const char *g_SoundEndContext = "SoundEnd"; +#endif + //----------------------------------------------------------------------------- // Spawn @@ -419,6 +447,24 @@ void CAmbientGeneric::InputFadeOut( inputdata_t &inputdata ) SetNextThink( gpGlobals->curtime + 0.1f ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAmbientGeneric::InputSetSound( inputdata_t &inputdata ) +{ + m_iszSound = inputdata.value.StringID(); + if (STRING(m_iszSound)[0] != '!') + { + PrecacheScriptSound(STRING(m_iszSound)); + } + + // Try to refresh the sound + if (m_fActive) + SendSound(SND_NOFLAGS); +} +#endif + void CAmbientGeneric::Precache( void ) { @@ -858,6 +904,19 @@ void CAmbientGeneric::InputPlaySound( inputdata_t &inputdata ) { //Adrian: Stop our current sound before starting a new one! SendSound( SND_STOP ); + +#ifdef MAPBASE + // Procedural handling like !activator + if (STRING(m_sSourceEntName)[0] == '!') + { + CBaseEntity *pEntity = gEntList.FindEntityProcedural(STRING(m_sSourceEntName), this, inputdata.pActivator, inputdata.pCaller); + if (pEntity) + { + m_hSoundSource = pEntity; + m_nSoundSourceEntIndex = pEntity->entindex(); + } + } +#endif ToggleSound(); } @@ -877,6 +936,52 @@ void CAmbientGeneric::InputStopSound( inputdata_t &inputdata ) void CAmbientGeneric::SendSound( SoundFlags_t flags) { +#ifdef MAPBASE + int iFlags = flags != SND_STOP ? ((int)flags | m_iSoundFlags) : flags; + char *szSoundFile = (char *)STRING( m_iszSound ); + CBaseEntity* pSoundSource = m_hSoundSource; + if ( pSoundSource ) + { + if ( iFlags & SND_STOP ) + { + UTIL_EmitAmbientSound(pSoundSource->GetSoundSourceIndex(), pSoundSource->GetAbsOrigin(), szSoundFile, + 0, SNDLVL_NONE, iFlags, 0); + + SetContextThink( NULL, TICK_NEVER_THINK, g_SoundEndContext ); + + m_fActive = false; + } + else + { + float duration = 0.0f; + UTIL_EmitAmbientSound(pSoundSource->GetSoundSourceIndex(), pSoundSource->GetAbsOrigin(), szSoundFile, + (m_dpv.vol * 0.01), m_iSoundLevel, iFlags, m_dpv.pitch, 0.0f, &duration); + + SetContextThink( &CAmbientGeneric::SoundEnd, gpGlobals->curtime + duration, g_SoundEndContext ); + + // Only mark active if this is a looping sound. If not looping, each + // trigger will cause the sound to play. If the sound is still + // playing from a previous trigger press, it will be shut off + // and then restarted. + + if (m_fLooping) + m_fActive = true; + } + } + else + { + if ( ( iFlags & SND_STOP ) && + ( m_nSoundSourceEntIndex != -1 ) ) + { + UTIL_EmitAmbientSound(m_nSoundSourceEntIndex, GetAbsOrigin(), szSoundFile, + 0, SNDLVL_NONE, iFlags, 0); + + SetContextThink( NULL, TICK_NEVER_THINK, g_SoundEndContext ); + + m_fActive = false; + } + } +#else char *szSoundFile = (char *)STRING( m_iszSound ); CBaseEntity* pSoundSource = m_hSoundSource; if ( pSoundSource ) @@ -901,14 +1006,35 @@ void CAmbientGeneric::SendSound( SoundFlags_t flags) 0, SNDLVL_NONE, flags, 0); } } +#endif } +#ifdef MAPBASE +void CAmbientGeneric::SoundEnd() +{ + m_OnSoundFinished.FireOutput(this, this); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Input handler that stops playing the sound. //----------------------------------------------------------------------------- void CAmbientGeneric::InputToggleSound( inputdata_t &inputdata ) { +#ifdef MAPBASE + // Procedural handling like !activator + if (STRING(m_sSourceEntName)[0] == '!') + { + CBaseEntity *pEntity = gEntList.FindEntityProcedural(STRING(m_sSourceEntName), this, inputdata.pActivator, inputdata.pCaller); + if (pEntity) + { + m_hSoundSource = pEntity; + m_nSoundSourceEntIndex = pEntity->entindex(); + } + } +#endif + ToggleSound(); } @@ -1187,7 +1313,7 @@ int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, name[0] = 0; ipick = engine->SentenceGroupPick( isentenceg, name, sizeof( name ) ); - if ( ( ipick > 0 ) && name[0] ) + if (ipick > 0 && name) { int sentenceIndex = SENTENCEG_Lookup( name ); CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); diff --git a/game/server/soundent.cpp b/game/server/soundent.cpp index 4a735637..59273206 100644 --- a/game/server/soundent.cpp +++ b/game/server/soundent.cpp @@ -45,6 +45,31 @@ BEGIN_SIMPLE_DATADESC( CSound ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CSound, "A sound NPCs can hear." ) + + DEFINE_SCRIPTFUNC( DoesSoundExpire, "Returns true if the sound expires." ) + DEFINE_SCRIPTFUNC( SoundExpirationTime, "Gets the sound's expiration time." ) + DEFINE_SCRIPTFUNC( SetSoundOrigin, "Sets the sound's origin." ) + DEFINE_SCRIPTFUNC( GetSoundOrigin, "Gets the sound's origin." ) + DEFINE_SCRIPTFUNC( GetSoundReactOrigin, "Gets the sound's react origin." ) + DEFINE_SCRIPTFUNC_NAMED( FIsSound, "IsSound", "Returns true if this is a type of sound (as opposed to a scent)." ) + DEFINE_SCRIPTFUNC_NAMED( FIsScent, "IsScent", "Returns true if this is a type of scent (as opposed to a sound)." ) + DEFINE_SCRIPTFUNC( IsSoundType, "Returns true if the sound type is the specified type." ) + DEFINE_SCRIPTFUNC( SoundType, "Gets the raw sound type." ) + DEFINE_SCRIPTFUNC( SoundContext, "Gets the sound type with contexts only." ) + DEFINE_SCRIPTFUNC( SoundTypeNoContext, "Gets the sound type with contexts excluded." ) + DEFINE_SCRIPTFUNC( Volume, "Gets the sound's volume." ) + DEFINE_SCRIPTFUNC( OccludedVolume, "Gets the sound's occluded volume." ) + DEFINE_SCRIPTFUNC( Reset, "Clears the volume, type, and origin for the sound without actually removing it." ) + DEFINE_SCRIPTFUNC( SoundChannel, "Gets the sound's channel." ) + DEFINE_SCRIPTFUNC( ValidateOwner, "Returns true if the sound's owner is still valid or if the sound never had an owner in the first place." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetOwner, "GetOwner", "Gets the sound's owner." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTarget, "GetTarget", "Gets the sound's target." ) + +END_SCRIPTDESC(); +#endif + //========================================================= // CSound - Clear - zeros all fields for a sound @@ -769,7 +794,11 @@ void CAISound::InputInsertSound( inputdata_t &inputdata ) if( m_iszProxyEntityName != NULL_STRING ) { +#ifdef MAPBASE + CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_iszProxyEntityName, this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_iszProxyEntityName ); +#endif if( pProxy ) { @@ -781,7 +810,26 @@ void CAISound::InputInsertSound( inputdata_t &inputdata ) } } +#ifdef MAPBASE + EHANDLE hOwner = this; + if (m_target != NULL_STRING) + { + CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_target, this, inputdata.pActivator, inputdata.pCaller ); + + if( pProxy ) + { + hOwner = pProxy; + } + else + { + DevWarning("Warning- ai_sound cannot find owner entity named '%s'. Using self.\n", STRING(m_target) ); + } + } + + g_pSoundEnt->InsertSound( m_iSoundType | m_iSoundContext, vecLocation, iVolume, m_flDuration, hOwner ); +#else g_pSoundEnt->InsertSound( m_iSoundType, vecLocation, iVolume, m_flDuration, this ); +#endif } void CAISound::InputEmitAISound( inputdata_t &inputdata ) @@ -790,7 +838,11 @@ void CAISound::InputEmitAISound( inputdata_t &inputdata ) if( m_iszProxyEntityName != NULL_STRING ) { +#ifdef MAPBASE + CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_iszProxyEntityName, this, inputdata.pActivator, inputdata.pCaller ); +#else CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_iszProxyEntityName ); +#endif if( pProxy ) { @@ -802,7 +854,26 @@ void CAISound::InputEmitAISound( inputdata_t &inputdata ) } } +#ifdef MAPBASE + EHANDLE hOwner = this; + if (m_target != NULL_STRING) + { + CBaseEntity *pProxy = gEntList.FindEntityByName( NULL, m_target, this, inputdata.pActivator, inputdata.pCaller ); + + if( pProxy ) + { + hOwner = pProxy; + } + else + { + DevWarning("Warning- ai_sound cannot find owner entity named '%s'. Using self.\n", STRING(m_target) ); + } + } + + g_pSoundEnt->InsertSound( m_iSoundType | m_iSoundContext, vecLocation, m_iVolume, m_flDuration, hOwner ); +#else g_pSoundEnt->InsertSound( m_iSoundType | m_iSoundContext, vecLocation, m_iVolume, m_flDuration, this ); +#endif } diff --git a/game/server/soundent.h b/game/server/soundent.h index 4de733f4..7ce3d401 100644 --- a/game/server/soundent.h +++ b/game/server/soundent.h @@ -57,6 +57,16 @@ enum SOUND_CONTEXT_ALLIES_ONLY = 0x10000000, // Only player allies can hear this sound SOUND_CONTEXT_PLAYER_VEHICLE = 0x20000000, // HACK: need this because we're not treating the SOUND_xxx values as true bit values! See switch in OnListened. +#ifdef MAPBASE + // You know, I wouldn't mind this approach of leaving types and contexts on the same int + // since it was important in the GoldSrc era with how many CSounds there can be at any given time. + // I'm just frustrated that this system was retained in Source with very specific and/or useless contexts with very little room to expand. + // If this doesn't work, replace SOUND_CONTEXT_PLAYER_VEHICLE with owner server vehicle checks. + + // Only heard by NPCs the owner likes. Needed for shared grenade code. + SOUND_CONTEXT_OWNER_ALLIES = 0x40000000, +#endif + ALL_CONTEXTS = 0xFFF00000, ALL_SCENTS = SOUND_CARCASS | SOUND_MEAT | SOUND_GARBAGE, @@ -126,6 +136,12 @@ class CSound int SoundChannel( void ) const; bool ValidateOwner() const; +#ifdef MAPBASE_VSCRIPT + // For VScript functions + HSCRIPT ScriptGetOwner() const { return ToHScript( m_hOwner ); } + HSCRIPT ScriptGetTarget() const { return ToHScript( m_hTarget ); } +#endif + EHANDLE m_hOwner; // sound's owner EHANDLE m_hTarget; // Sounds's target - an odd concept. For a gunfire sound, the target is the entity being fired at int m_iVolume; // how loud the sound is diff --git a/game/server/soundscape_system.cpp b/game/server/soundscape_system.cpp index 29b29402..fc81579f 100644 --- a/game/server/soundscape_system.cpp +++ b/game/server/soundscape_system.cpp @@ -136,6 +136,16 @@ bool CSoundscapeSystem::Init() mapSoundscapeFilename = UTIL_VarArgs( "scripts/soundscapes_%s.txt", mapname ); } +#ifdef MAPBASE + if (filesystem->FileExists(UTIL_VarArgs("maps/%s_soundscapes.txt", mapname))) + { + // A Mapbase-specific file exists. Load that instead. + // Any additional soundscape files, like the original scripts/soundscapes version, + // could be loaded through #include and/or #base. + mapSoundscapeFilename = UTIL_VarArgs("maps/%s_soundscapes.txt", mapname); + } +#endif + KeyValues *manifest = new KeyValues( SOUNDSCAPE_MANIFEST_FILE ); if ( filesystem->LoadKeyValues( *manifest, IFileSystem::TYPE_SOUNDSCAPE, SOUNDSCAPE_MANIFEST_FILE, "GAME" ) ) { diff --git a/game/server/subs.cpp b/game/server/subs.cpp index b2bf003f..0a37e4c1 100644 --- a/game/server/subs.cpp +++ b/game/server/subs.cpp @@ -38,6 +38,11 @@ void CNullEntity::Spawn( void ) } LINK_ENTITY_TO_CLASS(info_null,CNullEntity); +#ifdef MAPBASE +// Eh, good enough. +LINK_ENTITY_TO_CLASS(func_null,CNullEntity); +#endif + class CBaseDMStart : public CPointEntity { public: diff --git a/game/server/team_control_point.cpp b/game/server/team_control_point.cpp index a1288ad7..1bbec70a 100644 --- a/game/server/team_control_point.cpp +++ b/game/server/team_control_point.cpp @@ -17,7 +17,6 @@ #ifdef TF_DLL #include "tf_shareddefs.h" -#include "tf_gamerules.h" #endif #define CONTROL_POINT_UNLOCK_THINK "UnlockThink" @@ -270,7 +269,6 @@ void CTeamControlPoint::Precache( void ) #ifdef TF_DLL PrecacheScriptSound( "Announcer.ControlPointContested" ); - PrecacheScriptSound( "Announcer.ControlPointContested_Neutral" ); #endif } @@ -655,15 +653,7 @@ void CTeamControlPoint::InternalSetOwner( int iCapTeam, bool bMakeSound, int iNu Assert( playerIndex > 0 && playerIndex <= gpGlobals->maxClients ); - CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( playerIndex ) ); - PlayerCapped( pPlayer ); - -#ifdef TF_DLL - if ( TFGameRules() && TFGameRules()->IsHolidayActive( kHoliday_EOTL ) ) - { - TFGameRules()->DropBonusDuck( pPlayer->GetAbsOrigin(), ToTFPlayer( pPlayer ), NULL, NULL, false, true ); - } -#endif + PlayerCapped( ToBaseMultiplayerPlayer(UTIL_PlayerByIndex( playerIndex )) ); } // Remap team to get first game team = 1 @@ -743,7 +733,7 @@ void CTeamControlPoint::SendCapString( int iCapTeam, int iNumCappingPlayers, int //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer, CBaseMultiplayerPlayer *pVictim ) +void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer ) { if( strlen( STRING(m_iszPrintName) ) <= 0 ) return; @@ -756,10 +746,6 @@ void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer, CBaseMu event->SetString( "cpname", STRING(m_iszPrintName) ); event->SetInt( "blocker", pPlayer->entindex() ); event->SetInt( "priority", 9 ); - if ( pVictim ) - { - event->SetInt( "victim", pVictim->entindex() ); - } gameeventmanager->FireEvent( event ); } diff --git a/game/server/team_control_point.h b/game/server/team_control_point.h index bfcfe100..816a3ac1 100644 --- a/game/server/team_control_point.h +++ b/game/server/team_control_point.h @@ -82,7 +82,7 @@ class CTeamControlPoint : public CBaseAnimating void SetCappersRequiredForTeam( int iGameTeam, int iCappers ); - void CaptureBlocked( CBaseMultiplayerPlayer *pPlayer, CBaseMultiplayerPlayer *pVictim ); + void CaptureBlocked( CBaseMultiplayerPlayer *pPlayer ); int PointValue( void ); diff --git a/game/server/team_control_point_master.cpp b/game/server/team_control_point_master.cpp index 9b007e06..8ad9796d 100644 --- a/game/server/team_control_point_master.cpp +++ b/game/server/team_control_point_master.cpp @@ -1056,44 +1056,65 @@ bool CTeamControlPointMaster::IsBaseControlPoint( int iPointIndex ) int CTeamControlPointMaster::GetBaseControlPoint( int iTeam ) { int iRetVal = -1; - int nLowestValue = 999; - int nHighestValue = -1; - CTeamControlPoint *pLowestPoint = NULL; - CTeamControlPoint *pHighestPoint = NULL; + int nLowestValue = 999, nHighestValue = -1; + int iLowestIndex = 0, iHighestIndex = 0; - for( unsigned int i = 0 ; i < m_ControlPoints.Count() ; i++ ) + for( int i = 0 ; i < (int)m_ControlPoints.Count() ; i++ ) { CTeamControlPoint *pPoint = m_ControlPoints[i]; - if ( !PlayingMiniRounds() || ( IsInRound( pPoint ) && ( iTeam > LAST_SHARED_TEAM ) ) ) + int iPointIndex = m_ControlPoints[i]->GetPointIndex(); + + if ( PlayingMiniRounds() && iTeam > LAST_SHARED_TEAM ) { - int nTempValue = pPoint->GetPointIndex(); + if ( IsInRound( pPoint ) ) // is this point in the current round? + { + if ( iPointIndex > nHighestValue ) + { + nHighestValue = iPointIndex; + iHighestIndex = i; + } - if ( nTempValue > nHighestValue ) + if ( iPointIndex < nLowestValue ) + { + nLowestValue = iPointIndex; + iLowestIndex = i; + } + } + } + else + { + if ( pPoint->GetDefaultOwner() != iTeam ) { - nHighestValue = nTempValue; - pHighestPoint = pPoint; + continue; } - if ( nTempValue < nLowestValue ) + // If it's the first or the last point, it's their base + if ( iPointIndex == 0 || iPointIndex == (((int)m_ControlPoints.Count())-1) ) { - nLowestValue = nTempValue; - pLowestPoint = pPoint; + iRetVal = iPointIndex; + break; } } } - if ( pLowestPoint && pHighestPoint ) + if ( PlayingMiniRounds() && iTeam > LAST_SHARED_TEAM ) { - // which point is owned by this team? - if ( ( pLowestPoint->GetDefaultOwner() == iTeam && pHighestPoint->GetDefaultOwner() == iTeam ) || // if the same team owns both, take the highest value to be the last point - ( pHighestPoint->GetDefaultOwner() == iTeam ) ) - { - iRetVal = nHighestValue; - } - else if ( pLowestPoint->GetDefaultOwner() == iTeam ) + if ( nLowestValue != 999 && nHighestValue != -1 ) { - iRetVal = nLowestValue; + CTeamControlPoint *pLowestPoint = m_ControlPoints[iLowestIndex]; + CTeamControlPoint *pHighestPoint = m_ControlPoints[iHighestIndex]; + + // which point is owned by this team? + if ( ( pLowestPoint->GetDefaultOwner() == iTeam && pHighestPoint->GetDefaultOwner() == iTeam ) || // if the same team owns both, take the highest value to be the last point + ( pHighestPoint->GetDefaultOwner() == iTeam ) ) + { + iRetVal = nHighestValue; + } + else if ( pLowestPoint->GetDefaultOwner() == iTeam ) + { + iRetVal = nLowestValue; + } } } @@ -1246,7 +1267,7 @@ float CTeamControlPointMaster::GetPartialCapturePointRate( void ) return m_flPartialCapturePointsRate; } -#ifdef STAGING_ONLY +/* //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1323,4 +1344,4 @@ void cc_PlayRound( const CCommand& args ) } static ConCommand playround( "playround", cc_PlayRound, "Play the selected round\n\tArgument: {round name given by \"listrounds\" command}", FCVAR_CHEAT ); -#endif \ No newline at end of file +*/ \ No newline at end of file diff --git a/game/server/team_control_point_master.h b/game/server/team_control_point_master.h index 465a67dd..b6a7d35d 100644 --- a/game/server/team_control_point_master.h +++ b/game/server/team_control_point_master.h @@ -121,19 +121,14 @@ class CTeamControlPointMaster : public CBaseEntity bool ShouldScorePerCapture( void ){ return m_bScorePerCapture; } bool ShouldPlayAllControlPointRounds( void ){ return m_bPlayAllRounds; } int NumPlayableControlPointRounds( void ); // checks to see if there are any more rounds to play (but doesn't actually "get" one to play) - -#ifdef STAGING_ONLY - void ListRounds( void ); -#endif + +// void ListRounds( void ); float GetPartialCapturePointRate( void ); void SetLastOwnershipChangeTime( float m_flTime ) { m_flLastOwnershipChangeTime = m_flTime; } float GetLastOwnershipChangeTime( void ) { return m_flLastOwnershipChangeTime; } - int GetCurrentRoundIndex() { return m_iCurrentRoundIndex; } - bool ShouldSwitchTeamsOnRoundWin( void ) { return m_bSwitchTeamsOnWin; } - private: void EXPORT CPMThink( void ); diff --git a/game/server/team_train_watcher.cpp b/game/server/team_train_watcher.cpp index 0d6ebdbd..b8ef36c3 100644 --- a/game/server/team_train_watcher.cpp +++ b/game/server/team_train_watcher.cpp @@ -73,7 +73,6 @@ BEGIN_DATADESC( CTeamTrainWatcher ) DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeedForwardModifier", InputSetSpeedForwardModifier ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTrainRecedeTime", InputSetTrainRecedeTime ), DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetTrainCanRecede", InputSetTrainCanRecede ), - DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTrainRecedeTimeAndUpdate", InputSetTrainRecedeTimeAndUpdate ), // Outputs DEFINE_OUTPUT( m_OnTrainStartRecede, "OnTrainStartRecede" ), @@ -715,24 +714,6 @@ void CTeamTrainWatcher::InputSetTrainRecedeTime( inputdata_t &inputdata ) } } -void CTeamTrainWatcher::InputSetTrainRecedeTimeAndUpdate(inputdata_t &inputdata) -{ - InputSetTrainRecedeTime( inputdata ); - - // update our time if we're already counting down - if ( m_flRecedeTime > 0 ) - { - m_flRecedeTotalTime = tf_escort_recede_time.GetFloat(); - if ( m_nTrainRecedeTime > 0 ) - { - m_flRecedeTotalTime = m_nTrainRecedeTime; - } - - m_flRecedeStartTime = gpGlobals->curtime; - m_flRecedeTime = m_flRecedeStartTime + m_flRecedeTotalTime; - } -} - void CTeamTrainWatcher::InputSetTrainCanRecede( inputdata_t &inputdata ) { m_bTrainCanRecede = inputdata.value.Bool(); diff --git a/game/server/team_train_watcher.h b/game/server/team_train_watcher.h index 663b6141..22b82c6f 100644 --- a/game/server/team_train_watcher.h +++ b/game/server/team_train_watcher.h @@ -58,7 +58,6 @@ class CTeamTrainWatcher : public CBaseEntity, public CGameEventListener, public void InputSetSpeedForwardModifier( inputdata_t &inputdata ); void InputSetTrainRecedeTime( inputdata_t &inputdata ); void InputSetTrainCanRecede( inputdata_t &inputdata ); - void InputSetTrainRecedeTimeAndUpdate( inputdata_t &inputdata ); // ========================================================== // given a start node and a list of goal nodes @@ -95,8 +94,6 @@ class CTeamTrainWatcher : public CBaseEntity, public CGameEventListener, public void DumpStats( void ); #endif // STAGING_ONLY && TF_DLL - float GetTrainProgress() { return m_flTotalProgress; } - private: void StartCaptureAlarm( CTeamControlPoint *pPoint ); diff --git a/game/server/trigger_area_capture.cpp b/game/server/trigger_area_capture.cpp index 979ef4bc..2839200b 100644 --- a/game/server/trigger_area_capture.cpp +++ b/game/server/trigger_area_capture.cpp @@ -366,7 +366,6 @@ void CTriggerAreaCapture::CaptureThink( void ) } iNumBlockablePlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer ); - pPlayer->SetLastObjectiveTime( gpGlobals->curtime ); } continue; } @@ -379,7 +378,6 @@ void CTriggerAreaCapture::CaptureThink( void ) } iNumPlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer ); - pPlayer->SetLastObjectiveTime( gpGlobals->curtime ); } } } @@ -535,7 +533,7 @@ void CTriggerAreaCapture::CaptureThink( void ) if ( !bRepeatBlocker ) { - m_hPoint->CaptureBlocked( pBlockingPlayer, NULL ); + m_hPoint->CaptureBlocked( pBlockingPlayer ); // Add this guy to our blocker list int iNew = m_Blockers.AddToTail(); @@ -882,12 +880,6 @@ void CTriggerAreaCapture::EndCapture( int team ) m_nCapturingTeam = TEAM_UNASSIGNED; SetCapTimeRemaining( 0 ); - // play any special cap sounds. need to do this before we update the owner of the point. - if ( TeamplayRoundBasedRules() ) - { - TeamplayRoundBasedRules()->PlaySpecialCapSounds( m_nOwningTeam, m_hPoint.Get() ); - } - //there may have been more than one capper, but only report this one. //he hasn't gotten points yet, and his name will go in the cap string if its needed //first capper gets name sent and points given by flag. @@ -918,6 +910,12 @@ void CTriggerAreaCapture::EndCapture( int team ) } } } + + // play any special cap sounds + if ( TeamplayRoundBasedRules() ) + { + TeamplayRoundBasedRules()->PlaySpecialCapSounds( m_nOwningTeam ); + } } //----------------------------------------------------------------------------- @@ -1140,7 +1138,7 @@ bool CTriggerAreaCapture::CheckIfDeathCausesBlock( CBaseMultiplayerPlayer *pVict if ( bBreakCap ) { - m_hPoint->CaptureBlocked( pKiller, pVictim ); + m_hPoint->CaptureBlocked( pKiller ); //BreakCapture( true ); } diff --git a/game/server/triggers.cpp b/game/server/triggers.cpp index 1e317567..2361f8fa 100644 --- a/game/server/triggers.cpp +++ b/game/server/triggers.cpp @@ -33,12 +33,15 @@ #include "ai_behavior_follow.h" #include "ai_behavior_lead.h" #include "gameinterface.h" -#include "ilagcompensationmanager.h" #ifdef HL2_DLL #include "hl2_player.h" #endif +#ifdef MAPBASE +#include "ai_hint.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -103,6 +106,12 @@ BEGIN_DATADESC( CBaseTrigger ) DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), DEFINE_UTLVECTOR( m_hTouchingEntities, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flWait, FIELD_FLOAT, "wait" ), + DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), + DEFINE_KEYFIELD( m_sMaster, FIELD_STRING, "master" ), +#endif + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), @@ -122,6 +131,24 @@ BEGIN_DATADESC( CBaseTrigger ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT + +BEGIN_ENT_SCRIPTDESC( CBaseTrigger, CBaseEntity, "Trigger entity" ) + DEFINE_SCRIPTFUNC( Enable, "" ) + DEFINE_SCRIPTFUNC( Disable, "" ) + DEFINE_SCRIPTFUNC( TouchTest, "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptIsTouching, "IsTouching", "Checks whether the passed entity is touching the trigger." ) + + DEFINE_SCRIPTFUNC( UsesFilter, "Returns true if this trigger uses a filter." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptPassesTriggerFilters, "PassesTriggerFilters", "Returns whether a target entity satisfies the trigger's spawnflags, filter, etc." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTouchedEntityOfType, "GetTouchedEntityOfType", "Gets the first touching entity which matches the specified class." ) + + DEFINE_SCRIPTFUNC( PointIsWithin, "Checks if the given vector is within the trigger's volume." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTouchingEntities, "GetTouchingEntities", "Gets all entities touching this trigger (and satisfying its criteria). This function copies them to a table with a maximum number of elements." ) +END_SCRIPTDESC(); + +#endif // MAPBASE_VSCRIPT LINK_ENTITY_TO_CLASS( trigger, CBaseTrigger ); @@ -266,8 +293,11 @@ void CBaseTrigger::TouchTest( void ) { if ( m_hTouchingEntities.Count() !=0 ) { - +#ifdef MAPBASE + m_OnTouching.FireOutput( m_hTouchingEntities[0], this ); +#else m_OnTouching.FireOutput( this, this ); +#endif } else { @@ -362,6 +392,10 @@ bool CBaseTrigger::PassesTriggerFilters(CBaseEntity *pOther) (HasSpawnFlags(SF_TRIGGER_ALLOW_NPCS) && (pOther->GetFlags() & FL_NPC)) || (HasSpawnFlags(SF_TRIGGER_ALLOW_PUSHABLES) && FClassnameIs(pOther, "func_pushable")) || (HasSpawnFlags(SF_TRIGGER_ALLOW_PHYSICS) && pOther->GetMoveType() == MOVETYPE_VPHYSICS) +#ifdef MAPBASE + || + (HasSpawnFlags(SF_TRIGGER_ALLOW_ITEMS) && pOther->GetMoveType() == MOVETYPE_FLYGRAVITY) +#endif #if defined( HL2_EPISODIC ) || defined( TF_DLL ) || ( HasSpawnFlags(SF_TRIG_TOUCH_DEBRIS) && @@ -475,7 +509,6 @@ void CBaseTrigger::StartTouch(CBaseEntity *pOther) { // First entity to touch us that passes our filters m_OnStartTouchAll.FireOutput( pOther, this ); - StartTouchAll(); } } } @@ -515,10 +548,7 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther) else if ( hOther->IsPlayer() && !hOther->IsAlive() ) { #ifdef STAGING_ONLY - if ( !HushAsserts() ) - { - AssertMsg( false, "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) ); - } + AssertMsg( 0, CFmtStr( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) ) ); Warning( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) ); #endif m_hTouchingEntities.Remove( i ); @@ -534,7 +564,6 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther) if ( !bFoundOtherTouchee /*&& !m_bDisabled*/ ) { m_OnEndTouchAll.FireOutput(pOther, this); - EndTouchAll(); } } } @@ -549,6 +578,19 @@ bool CBaseTrigger::IsTouching( CBaseEntity *pOther ) return ( m_hTouchingEntities.Find( hOther ) != m_hTouchingEntities.InvalidIndex() ); } +#ifdef MAPBASE_VSCRIPT +bool CBaseTrigger::ScriptIsTouching( HSCRIPT hOther ) +{ + CBaseEntity *pOther = ToEnt(hOther); + if ( !pOther ) + return false; + + EHANDLE eOther; + eOther = pOther; + return ( m_hTouchingEntities.Find( eOther ) != m_hTouchingEntities.InvalidIndex() ); +} +#endif // MAPBASE_VSCRIPT + //----------------------------------------------------------------------------- // Purpose: Return a pointer to the first entity of the specified type being touched by this trigger //----------------------------------------------------------------------------- @@ -582,6 +624,19 @@ void CBaseTrigger::InputToggle( inputdata_t &inputdata ) PhysicsTouchTriggers(); } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: Copies touching entities to a script table +//----------------------------------------------------------------------------- +void CBaseTrigger::ScriptGetTouchingEntities( HSCRIPT hTable ) +{ + for (int i = 0; i < m_hTouchingEntities.Count(); i++) + { + g_pScriptVM->ArrayAppend( hTable, ToHScript( m_hTouchingEntities[i] ) ); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Removes anything that touches it. If the trigger has a targetname, @@ -639,8 +694,8 @@ void CTriggerRemove::Touch( CBaseEntity *pOther ) BEGIN_DATADESC( CTriggerHurt ) // Function Pointers - DEFINE_FUNCTION( CTriggerHurtShim::RadiationThinkShim ), - DEFINE_FUNCTION( CTriggerHurtShim::HurtThinkShim ), + DEFINE_FUNCTION( RadiationThink ), + DEFINE_FUNCTION( HurtThink ), // Fields DEFINE_FIELD( m_flOriginalDamage, FIELD_FLOAT ), @@ -649,6 +704,9 @@ BEGIN_DATADESC( CTriggerHurt ) DEFINE_KEYFIELD( m_bitsDamageInflict, FIELD_INTEGER, "damagetype" ), DEFINE_KEYFIELD( m_damageModel, FIELD_INTEGER, "damagemodel" ), DEFINE_KEYFIELD( m_bNoDmgForce, FIELD_BOOLEAN, "nodmgforce" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flHurtRate, FIELD_FLOAT, "hurtrate" ), +#endif DEFINE_FIELD( m_flLastDmgTime, FIELD_TIME ), DEFINE_FIELD( m_flDmgResetTime, FIELD_TIME ), @@ -666,7 +724,6 @@ END_DATADESC() LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt ); -IMPLEMENT_AUTO_LIST( ITriggerHurtAutoList ); //----------------------------------------------------------------------------- // Purpose: Called when spawning, after keyvalues have been handled. @@ -683,7 +740,7 @@ void CTriggerHurt::Spawn( void ) SetThink( NULL ); if (m_bitsDamageInflict & DMG_RADIATION) { - SetThink ( &CTriggerHurtShim::RadiationThinkShim ); + SetThink ( &CTriggerHurt::RadiationThink ); SetNextThink( gpGlobals->curtime + random->RandomFloat(0.0, 0.5) ); } } @@ -711,7 +768,11 @@ void CTriggerHurt::RadiationThink( void ) } float dt = gpGlobals->curtime - m_flLastDmgTime; +#ifdef MAPBASE + if ( dt >= m_flHurtRate ) +#else if ( dt >= 0.5 ) +#endif { HurtAllTouchers( dt ); } @@ -729,15 +790,6 @@ bool CTriggerHurt::HurtEntity( CBaseEntity *pOther, float damage ) if ( !pOther->m_takedamage || !PassesTriggerFilters(pOther) ) return false; - // If player is disconnected, we're probably in this routine via the - // PhysicsRemoveTouchedList() function to make sure all Untouch()'s are called for the - // player. Calling TakeDamage() in this case can get into the speaking criteria, which - // will then loop through the control points and the touched list again. We shouldn't - // need to hurt players that are disconnected, so skip all of this... - bool bPlayerDisconnected = pOther->IsPlayer() && ( ((CBasePlayer *)pOther)->IsConnected() == false ); - if ( bPlayerDisconnected ) - return false; - if ( damage < 0 ) { pOther->TakeHealth( -damage, m_bitsDamageInflict ); @@ -787,7 +839,11 @@ void CTriggerHurt::HurtThink() } else { +#ifdef MAPBASE + SetNextThink( gpGlobals->curtime + m_flHurtRate ); +#else SetNextThink( gpGlobals->curtime + 0.5f ); +#endif } } @@ -877,28 +933,28 @@ void CTriggerHurt::Touch( CBaseEntity *pOther ) { if ( m_pfnThink == NULL ) { - SetThink( &CTriggerHurtShim::HurtThinkShim ); + SetThink( &CTriggerHurt::HurtThink ); SetNextThink( gpGlobals->curtime ); } } +#ifdef MAPBASE //----------------------------------------------------------------------------- -// Purpose: Checks if this point is in any trigger_hurt zones with positive damage +// Purpose: //----------------------------------------------------------------------------- -bool IsTakingTriggerHurtDamageAtPoint( const Vector &vecPoint ) +bool CTriggerHurt::KeyValue( const char *szKeyName, const char *szValue ) { - for ( int i = 0; i < ITriggerHurtAutoList::AutoList().Count(); i++ ) + // Additional OR flags + if (FStrEq( szKeyName, "damageor" ) || FStrEq( szKeyName, "damagepresets" )) { - // Some maps use trigger_hurt with negative values as healing triggers; don't consider those - CTriggerHurt *pTrigger = static_cast( ITriggerHurtAutoList::AutoList()[i] ); - if ( !pTrigger->m_bDisabled && pTrigger->PointIsWithin( vecPoint ) && pTrigger->m_flDamage > 0.f ) - { - return true; - } + m_bitsDamageInflict |= atoi(szValue); } + else + return BaseClass::KeyValue( szKeyName, szValue ); - return false; + return true; } +#endif // ################################################################################## @@ -1024,7 +1080,11 @@ class CTriggerLook : public CTriggerOnce DECLARE_CLASS( CTriggerLook, CTriggerOnce ); public: +#ifdef MAPBASE + CUtlVector m_hLookTargets; +#else EHANDLE m_hLookTarget; +#endif float m_flFieldOfView; float m_flLookTime; // How long must I look for float m_flLookTimeTotal; // How long have I looked @@ -1032,6 +1092,10 @@ class CTriggerLook : public CTriggerOnce float m_flTimeoutDuration; // Number of seconds after start touch to fire anyway bool m_bTimeoutFired; // True if the OnTimeout output fired since the last StartTouch. EHANDLE m_hActivator; // The entity that triggered us. +#ifdef MAPBASE + bool m_bUseLOS; // Makes lookers use LOS calculations in addition to viewcone calculations + bool m_bUseLookEntityAsCaller; // Fires OnTrigger with the seen entity +#endif void Spawn( void ); void Touch( CBaseEntity *pOther ); @@ -1043,7 +1107,11 @@ class CTriggerLook : public CTriggerOnce private: +#ifdef MAPBASE + void Trigger(CBaseEntity *pActivator, bool bTimeout, CBaseEntity *pCaller = NULL); +#else void Trigger(CBaseEntity *pActivator, bool bTimeout); +#endif void TimeoutThink(); COutputEvent m_OnTimeout; @@ -1052,12 +1120,20 @@ class CTriggerLook : public CTriggerOnce LINK_ENTITY_TO_CLASS( trigger_look, CTriggerLook ); BEGIN_DATADESC( CTriggerLook ) +#ifdef MAPBASE + DEFINE_UTLVECTOR( m_hLookTargets, FIELD_EHANDLE ), +#else DEFINE_FIELD( m_hLookTarget, FIELD_EHANDLE ), +#endif DEFINE_FIELD( m_flLookTimeTotal, FIELD_FLOAT ), DEFINE_FIELD( m_flLookTimeLast, FIELD_TIME ), DEFINE_KEYFIELD( m_flTimeoutDuration, FIELD_FLOAT, "timeout" ), DEFINE_FIELD( m_bTimeoutFired, FIELD_BOOLEAN ), DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bUseLOS, FIELD_BOOLEAN, "UseLOS" ), + DEFINE_KEYFIELD( m_bUseLookEntityAsCaller, FIELD_BOOLEAN, "LookEntityCaller" ), +#endif DEFINE_OUTPUT( m_OnTimeout, "OnTimeout" ), @@ -1075,7 +1151,9 @@ END_DATADESC() //------------------------------------------------------------------------------ void CTriggerLook::Spawn( void ) { +#ifndef MAPBASE m_hLookTarget = NULL; +#endif m_flLookTimeTotal = -1; m_bTimeoutFired = false; @@ -1140,6 +1218,17 @@ void CTriggerLook::Touch(CBaseEntity *pOther) // -------------------------------- // Make sure we have a look target // -------------------------------- +#ifdef MAPBASE + if (m_hLookTargets.Count() <= 0) + { + CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, m_target, this, m_hActivator, this ); + while (pEntity) + { + m_hLookTargets.AddToTail(pEntity); + pEntity = gEntList.FindEntityByName( pEntity, m_target, this, m_hActivator, this ); + } + } +#else if (m_hLookTarget == NULL) { m_hLookTarget = GetNextTarget(); @@ -1148,6 +1237,7 @@ void CTriggerLook::Touch(CBaseEntity *pOther) return; } } +#endif // This is designed for single player only // so we'll always have the same player @@ -1176,6 +1266,50 @@ void CTriggerLook::Touch(CBaseEntity *pOther) vLookDir = ((CBaseCombatCharacter*)pOther)->EyeDirection3D( ); } +#ifdef MAPBASE + // Check if the player is looking at any of the entities, even if they turn to look at another entity candidate. + // This is how we're doing support for multiple entities without redesigning trigger_look. + EHANDLE hLookingAtEntity = NULL; + for (int i = 0; i < m_hLookTargets.Count(); i++) + { + if (!m_hLookTargets[i]) + continue; + + Vector vTargetDir = m_hLookTargets[i]->GetAbsOrigin() - pOther->EyePosition(); + VectorNormalize(vTargetDir); + + float fDotPr = DotProduct(vLookDir,vTargetDir); + if (fDotPr > m_flFieldOfView && (!m_bUseLOS || pOther->FVisible(m_hLookTargets[i]))) + { + hLookingAtEntity = m_hLookTargets[i]; + break; + } + } + + if (hLookingAtEntity != NULL) + { + // Is it the first time I'm looking? + if (m_flLookTimeTotal == -1) + { + m_flLookTimeLast = gpGlobals->curtime; + m_flLookTimeTotal = 0; + } + else + { + m_flLookTimeTotal += gpGlobals->curtime - m_flLookTimeLast; + m_flLookTimeLast = gpGlobals->curtime; + } + + if (m_flLookTimeTotal >= m_flLookTime) + { + Trigger(pOther, false, hLookingAtEntity); + } + } + else + { + m_flLookTimeTotal = -1; + } +#else Vector vTargetDir = m_hLookTarget->GetAbsOrigin() - pOther->EyePosition(); VectorNormalize(vTargetDir); @@ -1203,6 +1337,7 @@ void CTriggerLook::Touch(CBaseEntity *pOther) { m_flLookTimeTotal = -1; } +#endif } } @@ -1210,7 +1345,11 @@ void CTriggerLook::Touch(CBaseEntity *pOther) //----------------------------------------------------------------------------- // Purpose: Called when the trigger is fired by look logic or timeout. //----------------------------------------------------------------------------- +#ifdef MAPBASE +void CTriggerLook::Trigger(CBaseEntity *pActivator, bool bTimeout, CBaseEntity *pCaller) +#else void CTriggerLook::Trigger(CBaseEntity *pActivator, bool bTimeout) +#endif { if (bTimeout) { @@ -1223,7 +1362,11 @@ void CTriggerLook::Trigger(CBaseEntity *pActivator, bool bTimeout) else { // Fire because the player looked at the target. +#ifdef MAPBASE + m_OnTrigger.FireOutput(pActivator, m_bUseLookEntityAsCaller ? pCaller : this); +#else m_OnTrigger.FireOutput(pActivator, this); +#endif m_flLookTimeTotal = -1; // Cancel the timeout think. @@ -1760,7 +1903,11 @@ struct collidelist_t // NOTE: This routine is relatively slow. If you need to use it for per-frame work, consider that fact. // UNDONE: Expand this to the full matrix of solid types on each side and move into enginetrace +#ifdef MAPBASE // Other files may use this +bool TestEntityTriggerIntersection_Accurate( CBaseEntity *pTrigger, CBaseEntity *pEntity ) +#else static bool TestEntityTriggerIntersection_Accurate( CBaseEntity *pTrigger, CBaseEntity *pEntity ) +#endif { Assert( pTrigger->GetSolid() == SOLID_BSP ); @@ -2174,6 +2321,11 @@ class CTriggerPush : public CBaseTrigger void Touch( CBaseEntity *pOther ); void Untouch( CBaseEntity *pOther ); +#ifdef MAPBASE + void InputSetSpeed( inputdata_t &inputdata ); + void InputSetPushDir( inputdata_t &inputdata ); +#endif + Vector m_vecPushDir; DECLARE_DATADESC(); @@ -2186,6 +2338,10 @@ BEGIN_DATADESC( CTriggerPush ) DEFINE_KEYFIELD( m_vecPushDir, FIELD_VECTOR, "pushdir" ), DEFINE_KEYFIELD( m_flAlternateTicksFix, FIELD_FLOAT, "alternateticksfix" ), //DEFINE_FIELD( m_flPushSpeed, FIELD_FLOAT ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeed", InputSetSpeed ), + DEFINE_INPUTFUNC( FIELD_VECTOR, "SetPushDir", InputSetPushDir ), +#endif END_DATADESC() LINK_ENTITY_TO_CLASS( trigger_push, CTriggerPush ); @@ -2303,7 +2459,7 @@ void CTriggerPush::Touch( CBaseEntity *pOther ) #endif Vector vecPush = (m_flPushSpeed * vecAbsDir); - if ( ( pOther->GetFlags() & FL_BASEVELOCITY ) && !lagcompensation->IsCurrentlyDoingLagCompensation() ) + if ( pOther->GetFlags() & FL_BASEVELOCITY ) { vecPush = vecPush + pOther->GetBaseVelocity(); } @@ -2332,6 +2488,35 @@ void CTriggerPush::Touch( CBaseEntity *pOther ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTriggerPush::InputSetSpeed( inputdata_t &inputdata ) +{ + m_flSpeed = inputdata.value.Float(); + + // Need to update push speed/alternative ticks + Activate(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTriggerPush::InputSetPushDir( inputdata_t &inputdata ) +{ + inputdata.value.Vector3D( m_vecPushDir ); + + // Convert pushdir from angles to a vector + Vector vecAbsDir; + QAngle angPushDir = QAngle( m_vecPushDir.x, m_vecPushDir.y, m_vecPushDir.z ); + AngleVectors( angPushDir, &vecAbsDir ); + + // Transform the vector into entity space + VectorIRotate( vecAbsDir, EntityToWorldTransform(), m_vecPushDir ); +} +#endif + //----------------------------------------------------------------------------- // Teleport trigger @@ -2343,8 +2528,8 @@ class CTriggerTeleport : public CBaseTrigger public: DECLARE_CLASS( CTriggerTeleport, CBaseTrigger ); - virtual void Spawn( void ) OVERRIDE; - virtual void Touch( CBaseEntity *pOther ) OVERRIDE; + void Spawn( void ); + void Touch( CBaseEntity *pOther ); string_t m_iLandmark; @@ -2359,11 +2544,14 @@ BEGIN_DATADESC( CTriggerTeleport ) END_DATADESC() + + void CTriggerTeleport::Spawn( void ) { InitTrigger(); } + //----------------------------------------------------------------------------- // Purpose: Teleports the entity that touched us to the location of our target, // setting the toucher's angles to our target's angles if they are a @@ -2756,6 +2944,9 @@ class CAI_ChangeHintGroup : public CBaseEntity string_t m_strNewHintGroup; float m_flRadius; bool m_bHintGroupNavLimiting; +#ifdef MAPBASE + bool m_bChangeHints; +#endif }; LINK_ENTITY_TO_CLASS( ai_changehintgroup, CAI_ChangeHintGroup ); @@ -2766,6 +2957,9 @@ BEGIN_DATADESC( CAI_ChangeHintGroup ) DEFINE_KEYFIELD( m_strNewHintGroup, FIELD_STRING, "NewHintGroup" ), DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "Radius" ), DEFINE_KEYFIELD( m_bHintGroupNavLimiting, FIELD_BOOLEAN, "hintlimiting" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bChangeHints, FIELD_BOOLEAN, "changehints" ), +#endif DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), @@ -2822,6 +3016,35 @@ void CAI_ChangeHintGroup::InputActivate( inputdata_t &inputdata ) { pTarget->SetHintGroup( m_strNewHintGroup, m_bHintGroupNavLimiting ); } + +#ifdef MAPBASE + if (m_bChangeHints) + { + AIHintIter_t iter; + CAI_Hint *pHint = CAI_HintManager::GetFirstHint( &iter ); + while ( pHint != NULL ) + { + if ((GetAbsOrigin() - pHint->GetAbsOrigin()).Length() < m_flRadius) + { + bool bValid = false; + switch (m_iSearchType) + { + case 0: { bValid = pHint->NameMatches(STRING(m_strSearchName)); } break; + case 1: { bValid = pHint->ClassMatches(STRING(m_strSearchName)); } break; + + // These should be pooled, so if they're the same hintgroup, they should point to the same string... + case 2: { bValid = pHint->GetGroup() == m_strSearchName; } break; + } + + if (bValid) + pHint->SetGroup(m_strNewHintGroup); + } + + // Move to the next + pHint = CAI_HintManager::GetNextHint( &iter ); + } + } +#endif } @@ -2834,72 +3057,11 @@ void CAI_ChangeHintGroup::InputActivate( inputdata_t &inputdata ) #define SF_CAMERA_PLAYER_SNAP_TO 16 #define SF_CAMERA_PLAYER_NOT_SOLID 32 #define SF_CAMERA_PLAYER_INTERRUPT 64 - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -class CTriggerCamera : public CBaseEntity -{ -public: - DECLARE_CLASS( CTriggerCamera, CBaseEntity ); - - void Spawn( void ); - bool KeyValue( const char *szKeyName, const char *szValue ); - void Enable( void ); - void Disable( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void FollowTarget( void ); - void Move(void); - - // Always transmit to clients so they know where to move the view to - virtual int UpdateTransmitState(); - - DECLARE_DATADESC(); - - // Input handlers - void InputEnable( inputdata_t &inputdata ); - void InputDisable( inputdata_t &inputdata ); - -private: - EHANDLE m_hPlayer; - EHANDLE m_hTarget; - - // used for moving the camera along a path (rail rides) - CBaseEntity *m_pPath; - string_t m_sPath; - float m_flWait; - float m_flReturnTime; - float m_flStopTime; - float m_moveDistance; - float m_targetSpeed; - float m_initialSpeed; - float m_acceleration; - float m_deceleration; - int m_state; - Vector m_vecMoveDir; - - - string_t m_iszTargetAttachment; - int m_iAttachmentIndex; - bool m_bSnapToGoal; - -#if HL2_EPISODIC - bool m_bInterpolatePosition; - - // these are interpolation vars used for interpolating the camera over time - Vector m_vStartPos, m_vEndPos; - float m_flInterpStartTime; - - const static float kflPosInterpTime; // seconds +#ifdef MAPBASE +#define SF_CAMERA_PLAYER_SETFOV 128 +#define SF_CAMERA_PLAYER_NEW_BEHAVIOR 256 // In case anyone or anything relied on the broken features #endif - int m_nPlayerButtons; - int m_nOldTakeDamage; - -private: - COutputEvent m_OnEndFollow; -}; #if HL2_EPISODIC const float CTriggerCamera::kflPosInterpTime = 2.0f; @@ -2935,16 +3097,69 @@ BEGIN_DATADESC( CTriggerCamera ) DEFINE_FIELD( m_nPlayerButtons, FIELD_INTEGER ), DEFINE_FIELD( m_nOldTakeDamage, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_fov, FIELD_FLOAT, "fov" ), + DEFINE_KEYFIELD( m_fovSpeed, FIELD_FLOAT, "fov_rate" ), + DEFINE_KEYFIELD( m_flTrackSpeed, FIELD_FLOAT, "trackspeed" ), + + DEFINE_KEYFIELD( m_bDontSetPlayerView, FIELD_BOOLEAN, "DontSetPlayerView" ), +#endif + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFOV", InputSetFOV ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFOVRate", InputSetFOVRate ), + + //DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget", InputSetTarget ), // Defined by base class + DEFINE_INPUTFUNC( FIELD_STRING, "SetTargetAttachment", InputSetTargetAttachment ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetTrackSpeed", InputSetTrackSpeed ), +#endif // Function Pointers +#ifdef MAPBASE + DEFINE_FUNCTION( MoveThink ), +#endif DEFINE_FUNCTION( FollowTarget ), DEFINE_OUTPUT( m_OnEndFollow, "OnEndFollow" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnStartFollow, "OnStartFollow" ), +#endif END_DATADESC() +// VScript: publish class and select members to script language +BEGIN_ENT_SCRIPTDESC( CTriggerCamera, CBaseEntity, "Server-side camera entity" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFov, "GetFov", "get camera's current fov setting as integer" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetFov, "SetFov", "set camera's current fov in integer degrees and fov change rate as float" ) +END_SCRIPTDESC(); + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTriggerCamera::CTriggerCamera() +{ + m_fov = 90; + m_fovSpeed = 1; + m_flTrackSpeed = 40.0f; +} + +//------------------------------------------------------------------------------ +// Cleanup +//------------------------------------------------------------------------------ +void CTriggerCamera::UpdateOnRemove() +{ + if (m_state == USE_ON && HasSpawnFlags(SF_CAMERA_PLAYER_NEW_BEHAVIOR)) + { + Disable(); + } + + BaseClass::UpdateOnRemove(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -3029,6 +3244,84 @@ void CTriggerCamera::InputDisable( inputdata_t &inputdata ) Disable(); } +#ifdef MAPBASE +//------------------------------------------------------------------------------ +// Purpose: Input handler to set FOV. +//------------------------------------------------------------------------------ +void CTriggerCamera::InputSetFOV( inputdata_t &inputdata ) +{ + m_fov = inputdata.value.Float(); + + if ( m_state == USE_ON && m_hPlayer ) + { + ((CBasePlayer*)m_hPlayer.Get())->SetFOV( this, m_fov, m_fovSpeed ); + } +} + +//------------------------------------------------------------------------------ +// Purpose: Input handler to set FOV rate. +//------------------------------------------------------------------------------ +void CTriggerCamera::InputSetFOVRate( inputdata_t &inputdata ) +{ + m_fovSpeed = inputdata.value.Float(); +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CTriggerCamera::InputSetTarget( inputdata_t &inputdata ) +{ + BaseClass::InputSetTarget( inputdata ); + + if ( FStrEq(STRING(m_target), "!player") ) + { + AddSpawnFlags( SF_CAMERA_PLAYER_TARGET ); + m_hTarget = m_hPlayer; + } + else + { + RemoveSpawnFlags( SF_CAMERA_PLAYER_TARGET ); + m_hTarget = GetNextTarget(); + } +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CTriggerCamera::InputSetTargetAttachment( inputdata_t &inputdata ) +{ + m_iszTargetAttachment = inputdata.value.StringID(); + m_iAttachmentIndex = 0; + + if (m_hTarget) + { + if ( m_iszTargetAttachment != NULL_STRING ) + { + if ( !m_hTarget->GetBaseAnimating() ) + { + Warning("%s tried to target an attachment (%s) on target %s, which has no model.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) ); + } + else + { + m_iAttachmentIndex = m_hTarget->GetBaseAnimating()->LookupAttachment( STRING(m_iszTargetAttachment) ); + if ( m_iAttachmentIndex <= 0 ) + { + Warning("%s could not find attachment %s on target %s.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) ); + } + } + } + } +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +void CTriggerCamera::InputSetTrackSpeed( inputdata_t &inputdata ) +{ + m_flTrackSpeed = inputdata.value.Float(); +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -3105,6 +3398,20 @@ void CTriggerCamera::Enable( void ) m_bSnapToGoal = true; } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_CAMERA_PLAYER_SETFOV ) ) + { + if ( pPlayer ) + { + if ( pPlayer->GetFOVOwner() && (/*FClassnameIs( pPlayer->GetFOVOwner(), "point_viewcontrol_multiplayer" ) ||*/ FClassnameIs( pPlayer->GetFOVOwner(), "point_viewcontrol" )) ) + { + pPlayer->ClearZoomOwner(); + } + pPlayer->SetFOV( this, m_fov, m_fovSpeed ); + } + } +#endif + if ( HasSpawnFlags(SF_CAMERA_PLAYER_TARGET ) ) { m_hTarget = m_hPlayer; @@ -3187,12 +3494,17 @@ void CTriggerCamera::Enable( void ) } - pPlayer->SetViewEntity( this ); - - // Hide the player's viewmodel - if ( pPlayer->GetActiveWeapon() ) +#ifdef MAPBASE + if (!m_bDontSetPlayerView) +#endif { - pPlayer->GetActiveWeapon()->AddEffects( EF_NODRAW ); + pPlayer->SetViewEntity( this ); + + // Hide the player's viewmodel + if ( pPlayer->GetActiveWeapon() ) + { + pPlayer->GetActiveWeapon()->AddEffects( EF_NODRAW ); + } } // Only track if we have a target @@ -3202,6 +3514,18 @@ void CTriggerCamera::Enable( void ) SetThink( &CTriggerCamera::FollowTarget ); SetNextThink( gpGlobals->curtime ); } +#ifdef MAPBASE + else if (m_pPath && HasSpawnFlags(SF_CAMERA_PLAYER_NEW_BEHAVIOR)) + { + // Move if we have a path + SetThink( &CTriggerCamera::MoveThink ); + SetNextThink( gpGlobals->curtime ); + } +#endif + +#ifdef MAPBASE + m_OnStartFollow.FireOutput( pPlayer, this ); +#endif m_moveDistance = 0; Move(); @@ -3214,6 +3538,39 @@ void CTriggerCamera::Enable( void ) //----------------------------------------------------------------------------- void CTriggerCamera::Disable( void ) { +#ifdef MAPBASE + if ( m_hPlayer ) + { + CBasePlayer *pBasePlayer = (CBasePlayer*)m_hPlayer.Get(); + + if ( pBasePlayer->IsAlive() ) + { + if ( HasSpawnFlags( SF_CAMERA_PLAYER_NOT_SOLID ) ) + { + pBasePlayer->RemoveSolidFlags( FSOLID_NOT_SOLID ); + } + + if ( HasSpawnFlags( SF_CAMERA_PLAYER_TAKECONTROL ) ) + { + pBasePlayer->EnableControl( TRUE ); + } + + if (!m_bDontSetPlayerView) + { + pBasePlayer->SetViewEntity( NULL ); + pBasePlayer->m_Local.m_bDrawViewmodel = true; + } + } + + if ( HasSpawnFlags( SF_CAMERA_PLAYER_SETFOV ) ) + { + pBasePlayer->SetFOV( this, 0, m_fovSpeed ); + } + + //return the player to previous takedamage state + m_hPlayer->m_takedamage = m_nOldTakeDamage; + } +#else if ( m_hPlayer && m_hPlayer->IsAlive() ) { if ( HasSpawnFlags( SF_CAMERA_PLAYER_NOT_SOLID ) ) @@ -3232,6 +3589,7 @@ void CTriggerCamera::Disable( void ) //return the player to previous takedamage state m_hPlayer->m_takedamage = m_nOldTakeDamage; } +#endif m_state = USE_OFF; m_flReturnTime = gpGlobals->curtime; @@ -3336,7 +3694,11 @@ void CTriggerCamera::FollowTarget( ) dy = dy - 360; QAngle vecAngVel; +#ifdef MAPBASE + vecAngVel.Init( dx * m_flTrackSpeed * gpGlobals->frametime, dy * m_flTrackSpeed * gpGlobals->frametime, GetLocalAngularVelocity().z ); +#else vecAngVel.Init( dx * 40 * gpGlobals->frametime, dy * 40 * gpGlobals->frametime, GetLocalAngularVelocity().z ); +#endif SetLocalAngularVelocity(vecAngVel); } @@ -3354,6 +3716,75 @@ void CTriggerCamera::FollowTarget( ) Move(); } +void CTriggerCamera::StartCameraShot( const char *pszShotType, CBaseEntity *pSceneEntity, CBaseEntity *pActor1, CBaseEntity *pActor2, float duration ) +{ + // called from SceneEntity in response to a CChoreoEvent::CAMERA sent from a VCD. + // talk to vscript, start a camera move + + HSCRIPT hStartCameraShot = NULL; + + // switch to this camera + // Enable(); + + // get script module associated with this ent, lookup function in module + if( m_iszVScripts != NULL_STRING ) + { + hStartCameraShot = m_ScriptScope.LookupFunction( "ScriptStartCameraShot" ); + } + + // call the script function to begin the camera move + if ( hStartCameraShot ) + { + g_pScriptVM->Call( hStartCameraShot, m_ScriptScope, true, NULL, pszShotType, ToHScript(pSceneEntity), ToHScript(pActor1), ToHScript(pActor2), duration ); + g_pScriptVM->ReleaseFunction( hStartCameraShot ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: vscript callback to get the player's fov +//----------------------------------------------------------------------------- +int CTriggerCamera::ScriptGetFov(void) +{ + if (m_hPlayer) + { + CBasePlayer* pBasePlayer = (CBasePlayer*)m_hPlayer.Get(); + int iFOV = pBasePlayer->GetFOV(); + return iFOV; + } + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: vscript callback to slam the player's fov +//----------------------------------------------------------------------------- +void CTriggerCamera::ScriptSetFov(int iFOV, float fovSpeed) +{ +#ifdef MAPBASE + m_fov = iFOV; + m_fovSpeed = fovSpeed; + + if ( m_state == USE_ON && m_hPlayer ) + { +#else + if ( m_hPlayer ) + { + m_fov = iFOV; + m_fovSpeed = fovSpeed; +#endif + + CBasePlayer* pBasePlayer = (CBasePlayer*)m_hPlayer.Get(); + pBasePlayer->SetFOV(this, iFOV, fovSpeed); + } +} + +#ifdef MAPBASE +void CTriggerCamera::MoveThink() +{ + Move(); + SetNextThink( gpGlobals->curtime ); +} +#endif + void CTriggerCamera::Move() { if ( HasSpawnFlags( SF_CAMERA_PLAYER_INTERRUPT ) ) @@ -4217,6 +4648,10 @@ int CTriggerImpact::DrawDebugTextOverlays(void) const int SF_TRIGGER_MOVE_AUTODISABLE = 0x80; // disable auto movement const int SF_TRIGGER_AUTO_DUCK = 0x800; // Duck automatically +#ifdef MAPBASE +const int SF_TRIGGER_AUTO_WALK = 0x1000; +const int SF_TRIGGER_DISABLE_JUMP = 0x2000; +#endif class CTriggerPlayerMovement : public CBaseTrigger { @@ -4274,6 +4709,18 @@ void CTriggerPlayerMovement::StartTouch( CBaseEntity *pOther ) pPlayer->ForceButtons( IN_DUCK ); } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_TRIGGER_AUTO_WALK ) ) + { + pPlayer->ForceButtons( IN_WALK ); + } + + if ( HasSpawnFlags( SF_TRIGGER_DISABLE_JUMP ) ) + { + pPlayer->DisableButtons( IN_JUMP ); + } +#endif + // UNDONE: Currently this is the only operation this trigger can do if ( HasSpawnFlags(SF_TRIGGER_MOVE_AUTODISABLE) ) { @@ -4296,6 +4743,18 @@ void CTriggerPlayerMovement::EndTouch( CBaseEntity *pOther ) pPlayer->UnforceButtons( IN_DUCK ); } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_TRIGGER_AUTO_WALK ) ) + { + pPlayer->UnforceButtons( IN_WALK ); + } + + if ( HasSpawnFlags( SF_TRIGGER_DISABLE_JUMP ) ) + { + pPlayer->EnableButtons( IN_JUMP ); + } +#endif + if ( HasSpawnFlags(SF_TRIGGER_MOVE_AUTODISABLE) ) { pPlayer->m_Local.m_bAllowAutoMovement = true; @@ -4452,9 +4911,89 @@ void CBaseVPhysicsTrigger::EndTouch( CBaseEntity *pOther ) //----------------------------------------------------------------------------- bool CBaseVPhysicsTrigger::PassesTriggerFilters( CBaseEntity *pOther ) { +#ifdef MAPBASE + if ( !pOther->VPhysicsGetObject() ) +#else if ( pOther->GetMoveType() != MOVETYPE_VPHYSICS && !pOther->IsPlayer() ) +#endif return false; +#ifdef MAPBASE + // Copied and pasted code from CBaseTrigger::PassesTriggerFilters(). + if ( HasSpawnFlags(SF_TRIGGER_ALLOW_ALL) || + (HasSpawnFlags(SF_TRIGGER_ALLOW_CLIENTS) && (pOther->GetFlags() & FL_CLIENT)) || + (HasSpawnFlags(SF_TRIGGER_ALLOW_NPCS) && (pOther->GetFlags() & FL_NPC)) || + (HasSpawnFlags(SF_TRIGGER_ALLOW_PUSHABLES) && FClassnameIs(pOther, "func_pushable")) || + (HasSpawnFlags(SF_TRIGGER_ALLOW_PHYSICS) && pOther->GetMoveType() == MOVETYPE_VPHYSICS) || + (HasSpawnFlags(SF_TRIGGER_ALLOW_ITEMS) && pOther->GetMoveType() == MOVETYPE_FLYGRAVITY) +#if defined( HL2_EPISODIC ) || defined( TF_DLL ) + || + ( HasSpawnFlags(SF_TRIG_TOUCH_DEBRIS) && + (pOther->GetCollisionGroup() == COLLISION_GROUP_DEBRIS || + pOther->GetCollisionGroup() == COLLISION_GROUP_DEBRIS_TRIGGER || + pOther->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS) + ) +#endif + ) + { + if ( pOther->GetFlags() & FL_NPC ) + { + CAI_BaseNPC *pNPC = pOther->MyNPCPointer(); + + if ( HasSpawnFlags( SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS ) ) + { + if ( !pNPC || !pNPC->IsPlayerAlly() ) + { + return false; + } + } + + if ( HasSpawnFlags( SF_TRIGGER_ONLY_NPCS_IN_VEHICLES ) ) + { + if ( !pNPC || !pNPC->IsInAVehicle() ) + return false; + } + } + + bool bOtherIsPlayer = pOther->IsPlayer(); + + if ( bOtherIsPlayer ) + { + CBasePlayer *pPlayer = (CBasePlayer*)pOther; + if ( !pPlayer->IsAlive() ) + return false; + + if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES) ) + { + if ( !pPlayer->IsInAVehicle() ) + return false; + + // Make sure we're also not exiting the vehicle at the moment + IServerVehicle *pVehicleServer = pPlayer->GetVehicle(); + if ( pVehicleServer == NULL ) + return false; + + if ( pVehicleServer->IsPassengerExiting() ) + return false; + } + + if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES) ) + { + if ( pPlayer->IsInAVehicle() ) + return false; + } + + if ( HasSpawnFlags( SF_TRIGGER_DISALLOW_BOTS ) ) + { + if ( pPlayer->IsFakeClient() ) + return false; + } + } + + CBaseFilter *pFilter = m_hFilter.Get(); + return (!pFilter) ? true : pFilter->PassesFilter( this, pOther ); + } +#else // First test spawn flag filters if ( HasSpawnFlags(SF_TRIGGER_ALLOW_ALL) || (HasSpawnFlags(SF_TRIGGER_ALLOW_CLIENTS) && (pOther->GetFlags() & FL_CLIENT)) || @@ -4488,6 +5027,7 @@ bool CBaseVPhysicsTrigger::PassesTriggerFilters( CBaseEntity *pOther ) CBaseFilter *pFilter = m_hFilter.Get(); return (!pFilter) ? true : pFilter->PassesFilter( this, pOther ); } +#endif return false; } @@ -4859,6 +5399,13 @@ void CServerRagdollTrigger::Spawn( void ) { BaseClass::Spawn(); +#ifdef MAPBASE + // This didn't use PassesTriggerFilters() before, so a trigger_serverragdoll could work regardless of flags. + // Because of this, using trigger filters now will break existing trigger_serverragdolls that functioned without the right flags ticked. + // NPCs are going to be using this in almost all circumstances, so SF_TRIGGER_ALLOW_NPCS is pretty much the main flag of concern. + AddSpawnFlags(SF_TRIGGER_ALLOW_NPCS); +#endif + InitTrigger(); } @@ -4869,10 +5416,25 @@ void CServerRagdollTrigger::StartTouch(CBaseEntity *pOther) if ( pOther->IsPlayer() ) return; +#ifdef MAPBASE + // This means base class didn't accept it (trigger filters) + if (m_hTouchingEntities.Find(pOther) == m_hTouchingEntities.InvalidIndex()) + return; +#endif + CBaseCombatCharacter *pCombatChar = pOther->MyCombatCharacterPointer(); if ( pCombatChar ) { +#ifdef MAPBASE + // The mapper or some other force might've changed it themselves. + // Pretend it never touched us... + if (pCombatChar->m_bForceServerRagdoll == true) + { + BaseClass::EndTouch(pOther); + return; + } +#endif pCombatChar->m_bForceServerRagdoll = true; } } @@ -4892,7 +5454,6 @@ void CServerRagdollTrigger::EndTouch(CBaseEntity *pOther) } } - //----------------------------------------------------------------------------- // Purpose: A trigger that adds impulse to touching entities //----------------------------------------------------------------------------- @@ -4964,6 +5525,76 @@ void CTriggerApplyImpulse::InputApplyImpulse( inputdata_t& ) } } +#ifdef MAPBASE +class CTriggerFall : public CBaseTrigger +{ + DECLARE_CLASS( CTriggerFall, CBaseTrigger ); + +public: + + virtual void StartTouch( CBaseEntity *pOther ); + virtual void EndTouch( CBaseEntity *pOther ); + virtual void Spawn( void ); + + bool m_bStayLethal; + + DECLARE_DATADESC(); +}; + +LINK_ENTITY_TO_CLASS( trigger_fall, CTriggerFall ); + +BEGIN_DATADESC( CTriggerFall ) + + DEFINE_KEYFIELD( m_bStayLethal, FIELD_BOOLEAN, "StayLethal" ), + +END_DATADESC() + +void CTriggerFall::Spawn( void ) +{ + BaseClass::Spawn(); + + InitTrigger(); +} + +void CTriggerFall::StartTouch(CBaseEntity *pOther) +{ + BaseClass::StartTouch( pOther ); + + if ( !pOther->IsPlayer() ) + return; + + static_cast(pOther)->m_bInTriggerFall = true; +} + +void CTriggerFall::EndTouch(CBaseEntity *pOther) +{ + BaseClass::EndTouch( pOther ); + + if ( !pOther->IsPlayer() || m_bStayLethal ) + return; + + static_cast(pOther)->m_bInTriggerFall = false; +} + + + +class CTriggerWorld : public CTriggerMultiple +{ + DECLARE_CLASS( CTriggerWorld, CTriggerMultiple ); + +public: + + virtual bool PassesTriggerFilters(CBaseEntity *pOther); +}; + +LINK_ENTITY_TO_CLASS( trigger_world, CTriggerWorld ); + +bool CTriggerWorld::PassesTriggerFilters( CBaseEntity *pOther ) +{ + return pOther->IsWorld(); +} +#endif + #ifdef HL1_DLL //---------------------------------------------------------------------------------- // func_friction diff --git a/game/server/triggers.h b/game/server/triggers.h index 6ae7312f..47bf82be 100644 --- a/game/server/triggers.h +++ b/game/server/triggers.h @@ -11,7 +11,11 @@ #pragma once #endif +#ifdef MAPBASE +#include "baseentity.h" +#else #include "basetoggle.h" +#endif #include "entityoutput.h" // @@ -33,15 +37,24 @@ enum SF_TRIG_TOUCH_DEBRIS = 0x400, // Will touch physics debris objects SF_TRIGGER_ONLY_NPCS_IN_VEHICLES = 0X800, // *if* NPCs can fire this trigger, only NPCs in vehicles do so (respects player ally flag too) SF_TRIGGER_DISALLOW_BOTS = 0x1000, // Bots are not allowed to fire this trigger +#ifdef MAPBASE + SF_TRIGGER_ALLOW_ITEMS = 0x2000, // MOVETYPE_FLYGRAVITY (Weapons, items, flares, etc.) can fire this trigger +#endif }; // DVS TODO: get rid of CBaseToggle //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- +#ifdef MAPBASE +#define CBaseToggle CBaseEntity +#endif class CBaseTrigger : public CBaseToggle { DECLARE_CLASS( CBaseTrigger, CBaseToggle ); +#ifdef MAPBASE +#undef CBaseToggle +#endif public: CBaseTrigger(); @@ -68,9 +81,10 @@ class CBaseTrigger : public CBaseToggle virtual bool PassesTriggerFilters(CBaseEntity *pOther); virtual void StartTouch(CBaseEntity *pOther); virtual void EndTouch(CBaseEntity *pOther); - virtual void StartTouchAll() {} - virtual void EndTouchAll() {} bool IsTouching( CBaseEntity *pOther ); +#ifdef MAPBASE_VSCRIPT + bool ScriptIsTouching( HSCRIPT hOther ); +#endif CBaseEntity *GetTouchedEntityOfType( const char *sClassName ); @@ -81,6 +95,13 @@ class CBaseTrigger : public CBaseToggle bool PointIsWithin( const Vector &vecPoint ); +#ifdef MAPBASE_VSCRIPT + bool ScriptPassesTriggerFilters( HSCRIPT hOther ) { return ToEnt(hOther) ? PassesTriggerFilters( ToEnt(hOther) ) : NULL; } + HSCRIPT ScriptGetTouchedEntityOfType( const char *sClassName ) { return ToHScript( GetTouchedEntityOfType(sClassName) ); } + + void ScriptGetTouchingEntities( HSCRIPT hTable ); +#endif + bool m_bDisabled; string_t m_iFilterName; CHandle m_hFilter; @@ -98,7 +119,23 @@ class CBaseTrigger : public CBaseToggle // Entities currently being touched by this trigger CUtlVector< EHANDLE > m_hTouchingEntities; +#ifdef MAPBASE + // We don't descend from CBaseToggle anymore. These have to be defined here now. + EHANDLE m_hActivator; + float m_flWait; + string_t m_sMaster; // If this button has a master switch, this is the targetname. + // A master switch must be of the multisource type. If all + // of the switches in the multisource have been triggered, then + // the button will be allowed to operate. Otherwise, it will be + // deactivated. + + virtual float GetDelay( void ) { return m_flWait; } +#endif + DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif }; //----------------------------------------------------------------------------- @@ -166,30 +203,20 @@ class CBaseVPhysicsTrigger : public CBaseEntity // Purpose: Hurts anything that touches it. If the trigger has a targetname, // firing it will toggle state. //----------------------------------------------------------------------------- - -// This class is to get around the fact that DEFINE_FUNCTION doesn't like multiple inheritance -class CTriggerHurtShim : public CBaseTrigger -{ - virtual void RadiationThink( void ) = 0; - virtual void HurtThink( void ) = 0; - -public: - - void RadiationThinkShim( void ){ RadiationThink(); } - void HurtThinkShim( void ){ HurtThink(); } -}; - -DECLARE_AUTO_LIST( ITriggerHurtAutoList ); -class CTriggerHurt : public CTriggerHurtShim, public ITriggerHurtAutoList +class CTriggerHurt : public CBaseTrigger { public: CTriggerHurt() { // This field came along after levels were built so the field defaults to 20 here in the constructor. m_flDamageCap = 20.0f; +#ifdef MAPBASE + // Uh, same here. + m_flHurtRate = 0.5f; +#endif } - DECLARE_CLASS( CTriggerHurt, CTriggerHurtShim ); + DECLARE_CLASS( CTriggerHurt, CBaseTrigger ); void Spawn( void ); void RadiationThink( void ); @@ -199,6 +226,10 @@ class CTriggerHurt : public CTriggerHurtShim, public ITriggerHurtAutoList bool HurtEntity( CBaseEntity *pOther, float damage ); int HurtAllTouchers( float dt ); +#ifdef MAPBASE + bool KeyValue( const char *szKeyName, const char *szValue ); +#endif + DECLARE_DATADESC(); float m_flOriginalDamage; // Damage as specified by the level designer. @@ -209,6 +240,9 @@ class CTriggerHurt : public CTriggerHurtShim, public ITriggerHurtAutoList int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does int m_damageModel; bool m_bNoDmgForce; // Should damage from this trigger impart force on what it's hurting +#ifdef MAPBASE + float m_flHurtRate; +#endif enum { @@ -223,6 +257,103 @@ class CTriggerHurt : public CTriggerHurtShim, public ITriggerHurtAutoList CUtlVector m_hurtEntities; }; -bool IsTakingTriggerHurtDamageAtPoint( const Vector &vecPoint ); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CTriggerCamera : public CBaseEntity +{ +public: + DECLARE_CLASS( CTriggerCamera, CBaseEntity ); + // script description + DECLARE_ENT_SCRIPTDESC(); + +#ifdef MAPBASE + CTriggerCamera(); + + void UpdateOnRemove(); +#endif + + void Spawn( void ); + bool KeyValue( const char *szKeyName, const char *szValue ); + void Enable( void ); + void Disable( void ); + + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void FollowTarget( void ); + void StartCameraShot( const char *pszShotType, CBaseEntity *pSceneEntity, CBaseEntity *pActor1, CBaseEntity *pActor2, float duration ); + int ScriptGetFov(void); + void ScriptSetFov(int iFOV, float rate); +#ifdef MAPBASE + void MoveThink( void ); +#endif + void Move(void); + + // Always transmit to clients so they know where to move the view to + virtual int UpdateTransmitState(); + + DECLARE_DATADESC(); + + // Input handlers + void InputEnable( inputdata_t &inputdata ); + void InputDisable( inputdata_t &inputdata ); + +#ifdef MAPBASE + void InputSetFOV( inputdata_t &inputdata ); + void InputSetFOVRate( inputdata_t &inputdata ); + + void InputSetTarget( inputdata_t &inputdata ); + void InputSetTargetAttachment( inputdata_t &inputdata ); + void InputSetTrackSpeed( inputdata_t &inputdata ); +#endif + +private: + EHANDLE m_hPlayer; + EHANDLE m_hTarget; + + // used for moving the camera along a path (rail rides) + CBaseEntity *m_pPath; + string_t m_sPath; + float m_flWait; + float m_flReturnTime; + float m_flStopTime; + float m_moveDistance; + float m_targetSpeed; + float m_initialSpeed; + float m_acceleration; + float m_deceleration; + int m_state; + Vector m_vecMoveDir; + +#ifdef MAPBASE + float m_fov; + float m_fovSpeed; + float m_flTrackSpeed; + + bool m_bDontSetPlayerView; +#endif + + string_t m_iszTargetAttachment; + int m_iAttachmentIndex; + bool m_bSnapToGoal; + +#if HL2_EPISODIC + bool m_bInterpolatePosition; + + // these are interpolation vars used for interpolating the camera over time + Vector m_vStartPos, m_vEndPos; + float m_flInterpStartTime; + + const static float kflPosInterpTime; // seconds +#endif + + int m_nPlayerButtons; + int m_nOldTakeDamage; + +private: + COutputEvent m_OnEndFollow; +#ifdef MAPBASE + COutputEvent m_OnStartFollow; +#endif +}; #endif // TRIGGERS_H diff --git a/game/server/util.cpp b/game/server/util.cpp index 4b2008df..8a97695a 100644 --- a/game/server/util.cpp +++ b/game/server/util.cpp @@ -36,6 +36,9 @@ #include "datacache/imdlcache.h" #include "util.h" #include "cdll_int.h" +#ifdef MAPBASE +#include "fmtstr.h" +#endif #ifdef PORTAL #include "PortalSimulation.h" @@ -54,12 +57,7 @@ void DBG_AssertFunction( bool fExpr, const char *szExpr, const char *szFile, int { if (fExpr) return; - char szOut[512]; - if (szMessage != NULL) - Q_snprintf(szOut,sizeof(szOut), "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage); - else - Q_snprintf(szOut,sizeof(szOut), "ASSERT FAILED:\n %s \n(%s@%d)\n", szExpr, szFile, szLine); - Warning( "%s", szOut); + Warning("ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage ? szMessage : ""); } #endif // DEBUG @@ -161,11 +159,6 @@ IServerNetworkable *CEntityFactoryDictionary::Create( const char *pClassName ) IEntityFactory *pFactory = FindFactory( pClassName ); if ( !pFactory ) { -#ifdef STAGING_ONLY - static ConVarRef tf_bot_use_items( "tf_bot_use_items" ); - if ( tf_bot_use_items.IsValid() && tf_bot_use_items.GetInt() ) - return NULL; -#endif Warning("Attempted to create unknown entity type %s!\n", pClassName ); return NULL; } @@ -205,9 +198,49 @@ void CEntityFactoryDictionary::ReportEntitySizes() { for ( int i = m_Factories.First(); i != m_Factories.InvalidIndex(); i = m_Factories.Next( i ) ) { - Msg( " %s: %llu", m_Factories.GetElementName( i ), (uint64)(m_Factories[i]->GetEntitySize()) ); + Msg( " %s: %d", m_Factories.GetElementName( i ), m_Factories[i]->GetEntitySize() ); + } +} + +#ifdef MAPBASE +int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 ) +{ + CEntityFactoryDictionary *pFactoryDict = (CEntityFactoryDictionary*)EntityFactoryDictionary(); + for ( int i = pFactoryDict->m_Factories.First(); i != pFactoryDict->m_Factories.InvalidIndex(); i = pFactoryDict->m_Factories.Next( i ) ) + { + const char *name = pFactoryDict->m_Factories.GetElementName( i ); + if (Q_strnicmp(name, substring, checklen)) + continue; + + CUtlString sym = name; + int idx = symbols.Find(sym); + if (idx == symbols.InvalidIndex()) + { + symbols.Insert(sym); + } + + // Too many + if (symbols.Count() >= COMMAND_COMPLETION_MAXITEMS) + break; + } + + // Now fill in the results + for (int i = symbols.FirstInorder(); i != symbols.InvalidIndex(); i = symbols.NextInorder(i)) + { + const char *name = symbols[i].String(); + + char buf[512]; + Q_strncpy(buf, name, sizeof(buf)); + Q_strlower(buf); + + CUtlString command; + command = CFmtStr("%s %s", cmdname, buf); + commands.AddToTail(command); } + + return symbols.Count(); } +#endif //----------------------------------------------------------------------------- @@ -300,6 +333,14 @@ int UTIL_EntitiesInSphere( const Vector ¢er, float radius, CFlaggedEntitiesE return pEnum->GetCount(); } +#ifdef MAPBASE +int UTIL_EntitiesAtPoint( const Vector &point, CFlaggedEntitiesEnum *pEnum ) +{ + partition->EnumerateElementsAtPoint( PARTITION_ENGINE_NON_STATIC_EDICTS, point, false, pEnum ); + return pEnum->GetCount(); +} +#endif + CEntitySphereQuery::CEntitySphereQuery( const Vector ¢er, float radius, int flagMask ) { m_listIndex = 0; @@ -573,24 +614,6 @@ CBasePlayer *UTIL_PlayerByIndex( int playerIndex ) return pPlayer; } -CBasePlayer *UTIL_PlayerBySteamID( const CSteamID &steamID ) -{ - CSteamID steamIDPlayer; - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); - if ( !pPlayer ) - continue; - - if ( !pPlayer->GetSteamID( &steamIDPlayer ) ) - continue; - - if ( steamIDPlayer == steamID ) - return pPlayer; - } - return NULL; -} - CBasePlayer* UTIL_PlayerByName( const char *name ) { if ( !name || !name[0] ) @@ -1049,7 +1072,7 @@ void UTIL_ScreenFade( CBaseEntity *pEntity, const color32 &color, float fadeTime } -void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, const char *pMessage ) +void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, const char *pMessage, const char *pszFont, bool bAutobreak ) { CRecipientFilter filter; @@ -1082,12 +1105,19 @@ void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, c WRITE_FLOAT( textparms.holdTime ); WRITE_FLOAT( textparms.fxTime ); WRITE_STRING( pMessage ); +#ifdef MAPBASE + WRITE_STRING( pszFont ); + if (bAutobreak) + { + WRITE_BYTE ( Q_strlen( pMessage ) ); + } +#endif MessageEnd(); } -void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ) +void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage, const char *pszFont, bool bAutobreak ) { - UTIL_HudMessage( NULL, textparms, pMessage ); + UTIL_HudMessage( NULL, textparms, pMessage, pszFont, bAutobreak ); } void UTIL_HudHintText( CBaseEntity *pEntity, const char *pMessage ) @@ -1313,9 +1343,19 @@ void UTIL_SetModel( CBaseEntity *pEntity, const char *pModelName ) int i = modelinfo->GetModelIndex( pModelName ); if ( i == -1 ) { +#if defined(MAPBASE) && !defined(_DEBUG) + // Throwing a program-terminating error might be a little too much since we could just precache it here. + // If we're not in debug mode, just let it off with a nice warning. + if (int newi = CBaseEntity::PrecacheModel(pModelName)) + { + i = newi; + Warning("%s was not precached\n", pModelName); + } +#else Error("%i/%s - %s: UTIL_SetModel: not precached: %s\n", pEntity->entindex(), STRING( pEntity->GetEntityName() ), pEntity->GetClassname(), pModelName); +#endif } CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); @@ -1371,7 +1411,7 @@ void UTIL_SnapDirectionToAxis( Vector &direction, float epsilon ) } } -const char *UTIL_VarArgs( const char *format, ... ) +char *UTIL_VarArgs( const char *format, ... ) { va_list argptr; static char string[1024]; @@ -1807,6 +1847,40 @@ void UTIL_PrecacheOther( const char *szClassname, const char *modelName ) UTIL_RemoveImmediate( pEntity ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Tests whether this entity exists in the dictionary and if it does, precaches it. (as opposed to complaining when it's missing) +// Input : *szClassname - +// *modelName - +//----------------------------------------------------------------------------- +bool UTIL_TestPrecacheOther( const char *szClassname, const char *modelName ) +{ +#if defined( PRECACHE_OTHER_ONCE ) + // already done this one?, if not, mark as done + if ( !g_PrecacheOtherList.AddOrMarkPrecached( szClassname ) ) + return true; +#endif + + // If we can't create it, it probably does not exist + CBaseEntity *pEntity = CreateEntityByName( szClassname ); + if (!pEntity) + return false; + + // If we have a specified model, set it before calling precache + if ( modelName && modelName[0] ) + { + pEntity->SetModelName( AllocPooledString( modelName ) ); + } + + if (pEntity) + pEntity->Precache( ); + + UTIL_RemoveImmediate( pEntity ); + + return true; +} +#endif + //========================================================= // UTIL_LogPrintf - Prints a logged message to console. // Preceded by LOG: ( timestamp ) < message > @@ -1887,7 +1961,7 @@ extern "C" void Sys_Error( char *error, ... ) // *mapData - pointer a block of entity map data // Output : -1 if the entity was not successfully created; 0 on success //----------------------------------------------------------------------------- -int DispatchSpawn( CBaseEntity *pEntity ) +int DispatchSpawn( CBaseEntity *pEntity, bool bRunVScripts ) { if ( pEntity ) { @@ -1902,6 +1976,12 @@ int DispatchSpawn( CBaseEntity *pEntity ) //pEntity->SetAbsMins( pEntity->GetOrigin() - Vector(1,1,1) ); //pEntity->SetAbsMaxs( pEntity->GetOrigin() + Vector(1,1,1) ); + if (bRunVScripts) + { + pEntity->RunVScripts(); + pEntity->RunPrecacheScripts(); + } + #if defined(TRACK_ENTITY_MEMORY) && defined(USE_MEM_DEBUG) const char *pszClassname = NULL; int iClassname = ((CEntityFactoryDictionary*)EntityFactoryDictionary())->m_Factories.Find( pEntity->GetClassname() ); @@ -1968,6 +2048,11 @@ int DispatchSpawn( CBaseEntity *pEntity ) } gEntList.NotifySpawn( pEntity ); + + if( bRunVScripts ) + { + pEntity->RunOnPostSpawnScripts(); + } } return 0; @@ -2066,11 +2151,14 @@ void UTIL_ValidateSoundName( string_t &name, const char *defaultStr ) // sep - Character to use as separator. UNDONE: allow multiple separator chars // Output : Returns a pointer to the next token to be parsed. //----------------------------------------------------------------------------- -const char *nexttoken(char *token, const char *str, char sep) +const char *nexttoken(char *token, const char *str, char sep, size_t tokenLen) { if ((str == NULL) || (*str == '\0')) { - *token = '\0'; + if(tokenLen) + { + *token = '\0'; + } return(NULL); } @@ -2078,11 +2166,25 @@ const char *nexttoken(char *token, const char *str, char sep) // Copy everything up to the first separator into the return buffer. // Do not include separators in the return buffer. // + while ((*str != sep) && (*str != '\0') && (tokenLen > 1)) + { + *token++ = *str++; + tokenLen--; + } + + // + // If token is to big for return buffer, skip rest of token. + // while ((*str != sep) && (*str != '\0')) { - *token++ = *str++; + str++; } - *token = '\0'; + + if(tokenLen) + { + *token = '\0'; + tokenLen--; + } // // Advance the pointer unless we hit the end of the input string. @@ -2461,6 +2563,10 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *ve if ( pAnimating != NULL ) { vecPredictedVel = pAnimating->GetGroundSpeedVelocity(); +#ifdef MAPBASE + if (vecPredictedVel.IsZero()) + vecPredictedVel = pAnimating->GetSmoothedVelocity(); +#endif } else { @@ -2474,6 +2580,80 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *ve (*vecPredictedPosition) = pTarget->GetAbsOrigin() + ( vecPredictedVel * flTimeDelta ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Same as above, except you don't have to use the absolute origin and can use your own position to predict from. +//----------------------------------------------------------------------------- +void UTIL_PredictedPosition( CBaseEntity *pTarget, const Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition ) +{ + if ( ( pTarget == NULL ) || ( vecPredictedPosition == NULL ) ) + return; + + Vector vecPredictedVel; + CBasePlayer *pPlayer = ToBasePlayer( pTarget ); + if ( pPlayer != NULL ) + { + if ( pPlayer->IsInAVehicle() ) + vecPredictedVel = pPlayer->GetVehicleEntity()->GetSmoothedVelocity(); + else + vecPredictedVel = pPlayer->GetSmoothedVelocity(); + } + else + { + CBaseCombatCharacter *pCCTarget = pTarget->MyCombatCharacterPointer(); + if ( pCCTarget != NULL && pCCTarget->IsInAVehicle() ) + vecPredictedVel = pCCTarget->GetVehicleEntity()->GetSmoothedVelocity(); + else + { + CBaseAnimating *pAnimating = dynamic_cast(pTarget); + if ( pAnimating != NULL ) + { + vecPredictedVel = pAnimating->GetGroundSpeedVelocity(); + if (vecPredictedVel.IsZero()) + vecPredictedVel = pAnimating->GetSmoothedVelocity(); + } + else + vecPredictedVel = pTarget->GetSmoothedVelocity(); + } + } + + // Get the result + (*vecPredictedPosition) = vecActualPosition + ( vecPredictedVel * flTimeDelta ); +} + +//----------------------------------------------------------------------------- +// Purpose: Predicts angles through angular velocity instead of predicting origin through regular velocity. +//----------------------------------------------------------------------------- +void UTIL_PredictedAngles( CBaseEntity *pTarget, const QAngle &angActualAngles, float flTimeDelta, QAngle *angPredictedAngles ) +{ + if ( ( pTarget == NULL ) || ( angPredictedAngles == NULL ) ) + return; + + QAngle angPredictedVel; + CBasePlayer *pPlayer = ToBasePlayer( pTarget ); + if ( pPlayer != NULL ) + { + if ( pPlayer->IsInAVehicle() ) + angPredictedVel = pPlayer->GetVehicleEntity()->GetLocalAngularVelocity(); + else + angPredictedVel = pPlayer->GetLocalAngularVelocity(); + } + else + { + CBaseCombatCharacter *pCCTarget = pTarget->MyCombatCharacterPointer(); + if ( pCCTarget != NULL && pCCTarget->IsInAVehicle() ) + angPredictedVel = pCCTarget->GetVehicleEntity()->GetLocalAngularVelocity(); + else + { + angPredictedVel = pTarget->GetLocalAngularVelocity(); + } + } + + // Get the result + (*angPredictedAngles) = angActualAngles + ( angPredictedVel * flTimeDelta ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Points the destination entity at the target entity // Input : *pDest - entity to be pointed at the target diff --git a/game/server/util.h b/game/server/util.h index c06cbfe9..82f485ba 100644 --- a/game/server/util.h +++ b/game/server/util.h @@ -187,7 +187,13 @@ extern CGlobalVars *gpGlobals; // Misc useful inline bool FStrEq(const char *sz1, const char *sz2) { +#ifdef MAPBASE + // V_stricmp() already checks if the pointers are equal, so having a pointer comparison here is pointless. + // I'm not sure if this was already automatically phased out by the compiler, but if it wasn't, then this is a very good change. + return ( V_stricmp(sz1, sz2) == 0 ); +#else return ( sz1 == sz2 || V_stricmp(sz1, sz2) == 0 ); +#endif } #if 0 @@ -200,7 +206,7 @@ inline bool FStrEq( string_t str1, string_t str2 ) } #endif -const char *nexttoken(char *token, const char *str, char sep); +const char *nexttoken(char *token, const char *str, char sep, size_t tokenLen); // Misc. Prototypes void UTIL_SetSize (CBaseEntity *pEnt, const Vector &vecMin, const Vector &vecMax); @@ -222,7 +228,6 @@ float UTIL_GetSimulationInterval(); // NOTENOTE: Use UTIL_GetLocalPlayer instead of UTIL_PlayerByIndex IF you're in single player // and you want the player. CBasePlayer *UTIL_PlayerByIndex( int playerIndex ); -CBasePlayer *UTIL_PlayerBySteamID( const CSteamID &steamID ); // NOTENOTE: Use this instead of UTIL_PlayerByIndex IF you're in single player // and you want the player. @@ -232,6 +237,24 @@ CBasePlayer* UTIL_GetLocalPlayer( void ); // get the local player on a listen server CBasePlayer *UTIL_GetListenServerHost( void ); +//----------------------------------------------------------------------------- +// Purpose: Convenience function so we don't have to make this check all over +//----------------------------------------------------------------------------- +static CBasePlayer * UTIL_GetLocalPlayerOrListenServerHost( void ) +{ + if ( gpGlobals->maxClients > 1 ) + { + if ( engine->IsDedicatedServer() ) + { + return NULL; + } + + return UTIL_GetListenServerHost(); + } + + return UTIL_GetLocalPlayer(); +} + CBasePlayer* UTIL_PlayerByUserId( int userID ); CBasePlayer* UTIL_PlayerByName( const char *name ); // not case sensitive @@ -281,6 +304,9 @@ class CFlaggedEntitiesEnum : public IPartitionEnumerator int UTIL_EntitiesInBox( const Vector &mins, const Vector &maxs, CFlaggedEntitiesEnum *pEnum ); int UTIL_EntitiesAlongRay( const Ray_t &ray, CFlaggedEntitiesEnum *pEnum ); int UTIL_EntitiesInSphere( const Vector ¢er, float radius, CFlaggedEntitiesEnum *pEnum ); +#ifdef MAPBASE +int UTIL_EntitiesAtPoint( const Vector &point, CFlaggedEntitiesEnum *pEnum ); +#endif inline int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ) { @@ -300,6 +326,14 @@ inline int UTIL_EntitiesInSphere( CBaseEntity **pList, int listMax, const Vector return UTIL_EntitiesInSphere( center, radius, &sphereEnum ); } +#ifdef MAPBASE +inline int UTIL_EntitiesAtPoint( CBaseEntity **pList, int listMax, const Vector &point, int flagMask ) +{ + CFlaggedEntitiesEnum pointEnum( pList, listMax, flagMask ); + return UTIL_EntitiesAtPoint( point, &pointEnum ); +} +#endif + // marks the entity for deletion so it will get removed next frame void UTIL_Remove( IServerNetworkable *oldObj ); void UTIL_Remove( CBaseEntity *oldObj ); @@ -362,11 +396,15 @@ void UTIL_AxisStringToPointPoint( Vector &start, Vector &end, const char *pStri void UTIL_AxisStringToUnitDir( Vector &dir, const char *pString ); void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip ); void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *vecPredictedPosition ); +#ifdef MAPBASE +void UTIL_PredictedPosition( CBaseEntity *pTarget, const Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition ); +void UTIL_PredictedAngles( CBaseEntity *pTarget, const QAngle &angActualAngles, float flTimeDelta, QAngle *angPredictedAngles ); +#endif void UTIL_Beam( Vector &Start, Vector &End, int nModelIndex, int nHaloIndex, unsigned char FrameStart, unsigned char FrameRate, float Life, unsigned char Width, unsigned char EndWidth, unsigned char FadeLength, unsigned char Noise, unsigned char Red, unsigned char Green, unsigned char Blue, unsigned char Brightness, unsigned char Speed); -const char *UTIL_VarArgs( PRINTF_FORMAT_STRING const char *format, ... ) FMTFUNCTION( 1, 2 ); +char *UTIL_VarArgs( PRINTF_FORMAT_STRING const char *format, ... ); bool UTIL_IsValidEntity( CBaseEntity *pEnt ); bool UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); @@ -393,6 +431,11 @@ void UTIL_BubbleTrail( const Vector& from, const Vector& to, int count ); // allows precacheing of other entities void UTIL_PrecacheOther( const char *szClassname, const char *modelName = NULL ); +#ifdef MAPBASE +// Tests whether this entity exists in the dictionary and if it does, precaches it. (as opposed to complaining when it's missing) +bool UTIL_TestPrecacheOther( const char *szClassname, const char *modelName = NULL ); +#endif + // prints a message to each client void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); inline void UTIL_CenterPrintAll( const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ) @@ -469,14 +512,14 @@ void UTIL_SetModel( CBaseEntity *pEntity, const char *pModelName ); // prints as transparent 'title' to the HUD -void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ); -void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, const char *pMessage ); +void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage, const char *pszFont = NULL, bool bAutobreak = false ); +void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, const char *pMessage, const char *pszFont = NULL, bool bAutobreak = false ); // brings up hud keyboard hints display void UTIL_HudHintText( CBaseEntity *pEntity, const char *pMessage ); // Writes message to console with timestamp and FragLog header. -void UTIL_LogPrintf( PRINTF_FORMAT_STRING const char *fmt, ... ) FMTFUNCTION( 1, 2 ); +void UTIL_LogPrintf( PRINTF_FORMAT_STRING const char *fmt, ... ); // Sorta like FInViewCone, but for nonNPCs. float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); @@ -509,12 +552,17 @@ float UTIL_ScaleForGravity( float desiredGravity ); #define SF_BRUSH_ROTATE_BACKWARDS 2 #define SF_BRUSH_ROTATE_Z_AXIS 4 #define SF_BRUSH_ROTATE_X_AXIS 8 -#define SF_BRUSH_ROTATE_CLIENTSIDE 16 +// brought over from bmodels.cpp +#define SF_BRUSH_ACCDCC 16 // brush should accelerate and decelerate when toggled +#define SF_BRUSH_HURT 32 // rotating brush that inflicts pain based on rotation speed +#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. #define SF_BRUSH_ROTATE_SMALLRADIUS 128 #define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 #define SF_BRUSH_ROTATE_LARGERADIUS 512 +// changed bit to not conflict with much older flag SF_BRUSH_ACCDCC +#define SF_BRUSH_ROTATE_CLIENTSIDE 1024 #define PUSH_BLOCK_ONLY_X 1 #define PUSH_BLOCK_ONLY_Y 2 diff --git a/game/server/vance/env_global_light.cpp b/game/server/vance/env_global_light.cpp new file mode 100644 index 00000000..1ccd5211 --- /dev/null +++ b/game/server/vance/env_global_light.cpp @@ -0,0 +1,303 @@ +//========= Copyright � 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: global dynamic light. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.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 : Sunlight shadow control entity +//------------------------------------------------------------------------------ +class CGlobalLight : public CBaseEntity +{ +public: + DECLARE_CLASS(CGlobalLight, CBaseEntity); + + CGlobalLight(); + + void Spawn(void); + bool KeyValue(const char* szKeyName, const char* szValue); + virtual bool GetKeyValue(const char* szKeyName, char* szValue, int iMaxLen); + int UpdateTransmitState(); + + // Inputs + void InputSetAngles(inputdata_t& inputdata); + void InputEnable(inputdata_t& inputdata); + void InputDisable(inputdata_t& inputdata); + void InputSetTexture(inputdata_t& inputdata); + void InputSetEnableShadows(inputdata_t& inputdata); + void InputSetLightColor(inputdata_t& inputdata); + + void InputSetEnableDynamicSky(inputdata_t& inputdata); + void InputSetTimescale(inputdata_t& inputdata); + void InputSetTime(inputdata_t& inputdata); + + virtual int ObjectCaps(void) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + +private: + CNetworkVector(m_shadowDirection); + + CNetworkVar(bool, m_bEnabled); + bool m_bStartDisabled; + + CNetworkString(m_TextureName, MAX_PATH); + CNetworkVector(m_LinearFloatLightColor); + CNetworkVector(m_LinearFloatAmbientColor); + CNetworkVar(float, m_flColorTransitionTime); + CNetworkVar(float, m_flSunDistance); + CNetworkVar(float, m_flFOV); + CNetworkVar(float, m_flNearZ); + CNetworkVar(float, m_flNorthOffset); + CNetworkVar(bool, m_bEnableShadows); + CNetworkVar(bool, m_bEnableVolumetrics); + + CNetworkVar(bool, m_bEnableDynamicSky); + CNetworkVar(bool, m_bEnableTimeAngles); + CNetworkVar(float, m_flDayNightTimescale); + CNetworkVar(float, m_fTime); +}; + +LINK_ENTITY_TO_CLASS(env_global_light, CGlobalLight); +LINK_ENTITY_TO_CLASS(env_environment, CGlobalLight); + +BEGIN_DATADESC(CGlobalLight) + +DEFINE_KEYFIELD(m_bEnabled, FIELD_BOOLEAN, "enabled"), +DEFINE_KEYFIELD(m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled"), +DEFINE_AUTO_ARRAY_KEYFIELD(m_TextureName, FIELD_CHARACTER, "texturename"), +DEFINE_KEYFIELD(m_flSunDistance, FIELD_FLOAT, "distance"), +DEFINE_KEYFIELD(m_flFOV, FIELD_FLOAT, "fov"), +DEFINE_KEYFIELD(m_flNearZ, FIELD_FLOAT, "nearz"), +DEFINE_KEYFIELD(m_flNorthOffset, FIELD_FLOAT, "northoffset"), +DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), +DEFINE_KEYFIELD(m_bEnableVolumetrics, FIELD_BOOLEAN, "enablevolumetrics"), +DEFINE_KEYFIELD(m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime"), + +DEFINE_KEYFIELD(m_bEnableDynamicSky, FIELD_BOOLEAN, "enabledynamicsky"), +DEFINE_KEYFIELD(m_bEnableTimeAngles, FIELD_BOOLEAN, "usetimeforangles"), + +DEFINE_KEYFIELD(m_flDayNightTimescale, FIELD_FLOAT, "timescale"), +DEFINE_KEYFIELD(m_fTime, FIELD_FLOAT, "time"), + +// Inputs +DEFINE_INPUT(m_flSunDistance, FIELD_FLOAT, "SetDistance"), +DEFINE_INPUT(m_flFOV, FIELD_FLOAT, "SetFOV"), +DEFINE_INPUT(m_flNearZ, FIELD_FLOAT, "SetNearZDistance"), +DEFINE_INPUT(m_flNorthOffset, FIELD_FLOAT, "SetNorthOffset"), + +DEFINE_INPUTFUNC(FIELD_COLOR32, "LightColor", InputSetLightColor), +DEFINE_INPUTFUNC(FIELD_STRING, "SetAngles", InputSetAngles), +DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable), +DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable), +DEFINE_INPUTFUNC(FIELD_STRING, "SetTexture", InputSetTexture), +DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows), +DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableDynamicSky", InputSetEnableDynamicSky), +DEFINE_INPUTFUNC(FIELD_FLOAT, "EnableSetTimescale", InputSetTimescale), +DEFINE_INPUTFUNC(FIELD_FLOAT, "SetTime", InputSetTime), + +DEFINE_FIELD(m_LinearFloatLightColor, FIELD_VECTOR), +DEFINE_FIELD(m_LinearFloatAmbientColor, FIELD_VECTOR), + +END_DATADESC() + + +IMPLEMENT_SERVERCLASS_ST_NOBASE(CGlobalLight, DT_GlobalLight) +SendPropVector(SENDINFO(m_shadowDirection), -1, SPROP_NOSCALE), +SendPropBool(SENDINFO(m_bEnabled)), +SendPropString(SENDINFO(m_TextureName)), +SendPropVector(SENDINFO(m_LinearFloatLightColor)), +SendPropVector(SENDINFO(m_LinearFloatAmbientColor)), +SendPropFloat(SENDINFO(m_flColorTransitionTime)), +SendPropFloat(SENDINFO(m_flSunDistance), 0, SPROP_NOSCALE), +SendPropFloat(SENDINFO(m_flFOV), 0, SPROP_NOSCALE), +SendPropFloat(SENDINFO(m_flNearZ), 0, SPROP_NOSCALE), +SendPropFloat(SENDINFO(m_flNorthOffset), 0, SPROP_NOSCALE), +SendPropBool(SENDINFO(m_bEnableShadows)), + +SendPropBool(SENDINFO(m_bEnableDynamicSky)), +SendPropFloat(SENDINFO(m_flDayNightTimescale)), +SendPropFloat(SENDINFO(m_fTime)), +END_SEND_TABLE() + + +CGlobalLight::CGlobalLight() +{ +#if defined( _X360 ) + Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight_border"); +#else + Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight001"); +#endif + m_flColorTransitionTime = 0.5f; + m_flSunDistance = 10000.0f; + m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); + m_flFOV = 5.0f; + m_bEnableShadows = false; + + m_bEnableDynamicSky = false; + m_bEnableTimeAngles = false; + m_flDayNightTimescale = 1.0f; + m_fTime = 0.0f; +} + + +//------------------------------------------------------------------------------ +// Purpose : Send even though we don't have a model +//------------------------------------------------------------------------------ +int CGlobalLight::UpdateTransmitState() +{ + // ALWAYS transmit to all clients. + return SetTransmitState(FL_EDICT_ALWAYS); +} + +extern void UTIL_ColorStringToLinearFloatColor(Vector& color, const char* pString); + +bool CGlobalLight::KeyValue(const char* szKeyName, const char* szValue) +{ + if (FStrEq(szKeyName, "color")) + { + Vector tmp; + UTIL_ColorStringToLinearFloatColor(tmp, szValue); + m_LinearFloatLightColor = tmp; + } + else if (FStrEq(szKeyName, "ambient")) + { + Vector tmp; + UTIL_ColorStringToLinearFloatColor(tmp, szValue); + m_LinearFloatAmbientColor = tmp; + } + else if (FStrEq(szKeyName, "angles")) + { + QAngle angles; + UTIL_StringToVector(angles.Base(), szValue); + if (angles == vec3_angle) + { + angles.Init(80, 30, 0); + } + Vector vForward; + AngleVectors(angles, &vForward); + m_shadowDirection = vForward; + return true; + } + else if (FStrEq(szKeyName, "texturename")) + { +#if defined( _X360 ) + if (Q_strcmp(szValue, "effects/flashlight001") == 0) + { + // Use this as the default for Xbox + Q_strcpy(m_TextureName.GetForModify(), "effects/flashlight_border"); + } + else + { + Q_strcpy(m_TextureName.GetForModify(), szValue); + } +#else + Q_strcpy(m_TextureName.GetForModify(), szValue); +#endif + } + + return BaseClass::KeyValue(szKeyName, szValue); +} + +bool CGlobalLight::GetKeyValue(const char* szKeyName, char* szValue, int iMaxLen) +{ + if (FStrEq(szKeyName, "color")) + { + //Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() ); + return true; + } + else if (FStrEq(szKeyName, "texturename")) + { + Q_snprintf(szValue, iMaxLen, "%s", m_TextureName.Get()); + return true; + } + return BaseClass::GetKeyValue(szKeyName, szValue, iMaxLen); +} + +//------------------------------------------------------------------------------ +// Purpose : +//------------------------------------------------------------------------------ +void CGlobalLight::Spawn(void) +{ + Precache(); + SetSolid(SOLID_NONE); + + if (m_bStartDisabled) + { + m_bEnabled = false; + } + else + { + m_bEnabled = true; + } +} + +//------------------------------------------------------------------------------ +// Input values +//------------------------------------------------------------------------------ +void CGlobalLight::InputSetAngles(inputdata_t& inputdata) +{ + const char* pAngles = inputdata.value.String(); + + QAngle angles; + UTIL_StringToVector(angles.Base(), pAngles); + + Vector vTemp; + AngleVectors(angles, &vTemp); + m_shadowDirection = vTemp; +} + +//------------------------------------------------------------------------------ +// Purpose : Input handlers +//------------------------------------------------------------------------------ +void CGlobalLight::InputEnable(inputdata_t& inputdata) +{ + m_bEnabled = true; +} + +void CGlobalLight::InputDisable(inputdata_t& inputdata) +{ + m_bEnabled = false; +} + +void CGlobalLight::InputSetTexture(inputdata_t& inputdata) +{ + Q_strcpy(m_TextureName.GetForModify(), inputdata.value.String()); +} + +void CGlobalLight::InputSetEnableShadows(inputdata_t& inputdata) +{ + m_bEnableShadows = inputdata.value.Bool(); +} + +void CGlobalLight::InputSetLightColor(inputdata_t& inputdata) +{ + //m_LightColor = inputdata.value.Color32(); +} + +void CGlobalLight::InputSetEnableDynamicSky(inputdata_t& inputdata) +{ + m_bEnableDynamicSky = inputdata.value.Bool(); +} + +void CGlobalLight::InputSetTimescale(inputdata_t& inputdata) +{ + m_flDayNightTimescale = inputdata.value.Float(); +} + +void CGlobalLight::InputSetTime(inputdata_t& inputdata) +{ + m_fTime = inputdata.value.Float(); +} diff --git a/game/server/vance/npc_BaseZombie.cpp b/game/server/vance/npc_BaseZombie.cpp index 9a02401c..95d59328 100644 --- a/game/server/vance/npc_BaseZombie.cpp +++ b/game/server/vance/npc_BaseZombie.cpp @@ -1626,7 +1626,7 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) const char *pString = pEvent->options; char token[128]; - pString = nexttoken( token, pString, ' ' ); + pString = nexttoken( token, pString, ' ', sizeof(token) ); int boneIndex = GetInteractionPartner()->LookupBone( token ); @@ -1636,7 +1636,7 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) return; } - pString = nexttoken( token, pString, ' ' ); + pString = nexttoken( token, pString, ' ', sizeof( token ) ); if ( !token ) { diff --git a/game/server/vance/npc_assassin.cpp b/game/server/vance/npc_assassin.cpp index 4ff35d93..86a495bf 100644 --- a/game/server/vance/npc_assassin.cpp +++ b/game/server/vance/npc_assassin.cpp @@ -1,26 +1,24 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // //=============================================================================// #include "cbase.h" #include "ammodef.h" -#include "AI_Hint.h" -#include "AI_Navigator.h" #include "npc_assassin.h" #include "game.h" #include "npcevent.h" #include "engine/IEngineSound.h" -#include "ai_squad.h" -#include "AI_SquadSlot.h" #include "ai_moveprobe.h" #include "ai_scheduleobject.h" #include "ai_tacticalservices.h" #include "ai_motor.h" #include "ai_squadslot.h" #include "ai_squad.h" +#include "ai_hint.h" +#include "ai_navigator.h" #include "movevars_shared.h" #include "basegrenade_shared.h" #include "grenade_frag.h" @@ -117,7 +115,7 @@ Class_T CNPC_HAssassin::Classify(void) } //========================================================= -// CheckMeleeAttack1 - jump like crazy if the enemy gets too close. +// CheckMeleeAttack1 - jump like crazy if the enemy gets too close. //========================================================= int CNPC_HAssassin::MeleeAttack1Conditions(float flDot, float flDist) { @@ -179,7 +177,7 @@ int CNPC_HAssassin::RangeAttack1Conditions(float flDot, float flDist) } //========================================================= -// CheckRangeAttack2 - toss grenade is enemy gets in the way and is too close. +// CheckRangeAttack2 - toss grenade is enemy gets in the way and is too close. //========================================================= int CNPC_HAssassin::RangeAttack2Conditions(float flDot, float flDist) { @@ -245,7 +243,7 @@ void CNPC_HAssassin::StartTask(const Task_t* pTask) //========================================================= -// RunTask +// RunTask //========================================================= void CNPC_HAssassin::RunTask(const Task_t* pTask) { @@ -613,12 +611,12 @@ void CNPC_HAssassin::RunAI(void) EmitSound(filter, entindex(), "HAssassin.Beamsound"); } - SetRenderColorA(max(GetRenderColor().a - 50, m_iTargetRanderamt)); + SetRenderColorA(MAX(GetRenderColor().a - 50, m_iTargetRanderamt)); m_nRenderMode = kRenderTransTexture; } else if (GetRenderColor().a < m_iTargetRanderamt) { - SetRenderColorA(min(GetRenderColor().a + 50, m_iTargetRanderamt)); + SetRenderColorA(MIN(GetRenderColor().a + 50, m_iTargetRanderamt)); if (GetRenderColor().a == 255) m_nRenderMode = kRenderNormal; } diff --git a/game/server/vance/npc_bullsquid.cpp b/game/server/vance/npc_bullsquid.cpp index 873791d2..31ddecf4 100644 --- a/game/server/vance/npc_bullsquid.cpp +++ b/game/server/vance/npc_bullsquid.cpp @@ -7,12 +7,14 @@ #include "cbase.h" #include "game.h" -#include "AI_Default.h" -#include "AI_Schedule.h" -#include "AI_Hull.h" -#include "AI_Navigator.h" -#include "AI_Motor.h" +#include "ai_default.h" +#include "ai_schedule.h" +#include "ai_hull.h" +#include "ai_navigator.h" +#include "ai_motor.h" #include "ai_squad.h" +#include "ai_hint.h" +#include "ai_senses.h" #include "npc_bullsquid.h" #include "npcevent.h" #include "soundent.h" @@ -30,9 +32,6 @@ #include "engine/IEngineSound.h" #include "movevars_shared.h" -#include "AI_Hint.h" -#include "AI_Senses.h" - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/game/server/vance/npc_combine.cpp b/game/server/vance/npc_combine.cpp index d5b73bed..30c06696 100644 --- a/game/server/vance/npc_combine.cpp +++ b/game/server/vance/npc_combine.cpp @@ -74,13 +74,17 @@ int g_interactionCombineBash = 0; // melee bash attack #define COMBINE_AE_RELOAD ( 2 ) #define COMBINE_AE_KICK ( 3 ) #define COMBINE_AE_AIM ( 4 ) +#ifndef MAPBASE #define COMBINE_AE_GREN_TOSS ( 7 ) +#endif #define COMBINE_AE_GREN_LAUNCH ( 8 ) #define COMBINE_AE_GREN_DROP ( 9 ) #define COMBINE_AE_CAUGHT_ENEMY ( 10) // grunt established sight with an enemy (player only) that had previously eluded the squad. +#ifndef MAPBASE int COMBINE_AE_BEGIN_ALTFIRE; int COMBINE_AE_ALTFIRE; +#endif //========================================================= // Combine activities @@ -92,12 +96,21 @@ int COMBINE_AE_ALTFIRE; //Activity ACT_COMBINE_WALKING_AR2; //Activity ACT_COMBINE_STANDING_SHOTGUN; //Activity ACT_COMBINE_CROUCHING_SHOTGUN; +#if !SHARED_COMBINE_ACTIVITIES Activity ACT_COMBINE_THROW_GRENADE; +#endif Activity ACT_COMBINE_LAUNCH_GRENADE; Activity ACT_COMBINE_BUGBAIT; +#if !SHARED_COMBINE_ACTIVITIES Activity ACT_COMBINE_AR2_ALTFIRE; +#endif Activity ACT_WALK_EASY; Activity ACT_WALK_MARCH; +#ifdef MAPBASE +Activity ACT_TURRET_CARRY_IDLE; +Activity ACT_TURRET_CARRY_WALK; +Activity ACT_TURRET_CARRY_RUN; +#endif // ----------------------------------------------- // > Squad slots @@ -3514,43 +3527,51 @@ bool CNPC_Combine::ShouldPickADeathPose(void) // //----------------------------------------------------------------------------- -AI_BEGIN_CUSTOM_NPC(npc_combine, CNPC_Combine) +AI_BEGIN_CUSTOM_NPC( npc_combine, CNPC_Combine ) //Tasks -DECLARE_TASK(TASK_COMBINE_FACE_TOSS_DIR) -DECLARE_TASK(TASK_COMBINE_IGNORE_ATTACKS) -DECLARE_TASK(TASK_COMBINE_SIGNAL_BEST_SOUND) -DECLARE_TASK(TASK_COMBINE_DEFER_SQUAD_GRENADES) -DECLARE_TASK(TASK_COMBINE_CHASE_ENEMY_CONTINUOUSLY) -DECLARE_TASK(TASK_COMBINE_DIE_INSTANTLY) -DECLARE_TASK(TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET) -DECLARE_TASK(TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS) -DECLARE_TASK(TASK_COMBINE_SET_STANDING) -DECLARE_TASK(TASK_COMBINE_BEGIN_FLANK) +DECLARE_TASK( TASK_COMBINE_FACE_TOSS_DIR ) +DECLARE_TASK( TASK_COMBINE_IGNORE_ATTACKS ) +DECLARE_TASK( TASK_COMBINE_SIGNAL_BEST_SOUND ) +DECLARE_TASK( TASK_COMBINE_DEFER_SQUAD_GRENADES ) +DECLARE_TASK( TASK_COMBINE_CHASE_ENEMY_CONTINUOUSLY ) +DECLARE_TASK( TASK_COMBINE_DIE_INSTANTLY ) +DECLARE_TASK( TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET ) +DECLARE_TASK( TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS ) +DECLARE_TASK( TASK_COMBINE_SET_STANDING ) //Activities -DECLARE_ACTIVITY(ACT_COMBINE_THROW_GRENADE) -DECLARE_ACTIVITY(ACT_COMBINE_LAUNCH_GRENADE) -DECLARE_ACTIVITY(ACT_COMBINE_BUGBAIT) -DECLARE_ACTIVITY(ACT_COMBINE_AR2_ALTFIRE) -DECLARE_ACTIVITY(ACT_WALK_EASY) -DECLARE_ACTIVITY(ACT_WALK_MARCH) - -DECLARE_ANIMEVENT(COMBINE_AE_BEGIN_ALTFIRE) -DECLARE_ANIMEVENT(COMBINE_AE_ALTFIRE) - -DECLARE_SQUADSLOT(SQUAD_SLOT_GRENADE1) -DECLARE_SQUADSLOT(SQUAD_SLOT_GRENADE2) - -DECLARE_CONDITION(COND_COMBINE_NO_FIRE) -DECLARE_CONDITION(COND_COMBINE_DEAD_FRIEND) -DECLARE_CONDITION(COND_COMBINE_SHOULD_PATROL) -DECLARE_CONDITION(COND_COMBINE_HIT_BY_BUGBAIT) -DECLARE_CONDITION(COND_COMBINE_DROP_GRENADE) -DECLARE_CONDITION(COND_COMBINE_ON_FIRE) -DECLARE_CONDITION(COND_COMBINE_ATTACK_SLOT_AVAILABLE) - -DECLARE_INTERACTION(g_interactionCombineBash); +#if !SHARED_COMBINE_ACTIVITIES +DECLARE_ACTIVITY( ACT_COMBINE_THROW_GRENADE ) +#endif +DECLARE_ACTIVITY( ACT_COMBINE_LAUNCH_GRENADE ) +DECLARE_ACTIVITY( ACT_COMBINE_BUGBAIT ) +#if !SHARED_COMBINE_ACTIVITIES +DECLARE_ACTIVITY( ACT_COMBINE_AR2_ALTFIRE ) +#endif +DECLARE_ACTIVITY( ACT_WALK_EASY ) +DECLARE_ACTIVITY( ACT_WALK_MARCH ) +#ifdef MAPBASE +DECLARE_ACTIVITY( ACT_TURRET_CARRY_IDLE ) +DECLARE_ACTIVITY( ACT_TURRET_CARRY_WALK ) +DECLARE_ACTIVITY( ACT_TURRET_CARRY_RUN ) +#endif + +DECLARE_ANIMEVENT( COMBINE_AE_BEGIN_ALTFIRE ) +DECLARE_ANIMEVENT( COMBINE_AE_ALTFIRE ) + +DECLARE_SQUADSLOT( SQUAD_SLOT_GRENADE1 ) +DECLARE_SQUADSLOT( SQUAD_SLOT_GRENADE2 ) + +DECLARE_CONDITION( COND_COMBINE_NO_FIRE ) +DECLARE_CONDITION( COND_COMBINE_DEAD_FRIEND ) +DECLARE_CONDITION( COND_COMBINE_SHOULD_PATROL ) +DECLARE_CONDITION( COND_COMBINE_HIT_BY_BUGBAIT ) +DECLARE_CONDITION( COND_COMBINE_DROP_GRENADE ) +DECLARE_CONDITION( COND_COMBINE_ON_FIRE ) +DECLARE_CONDITION( COND_COMBINE_ATTACK_SLOT_AVAILABLE ) + +DECLARE_INTERACTION( g_interactionCombineBash ); //========================================================= // SCHED_COMBINE_TAKE_COVER_FROM_BEST_SOUND diff --git a/game/server/vance/npc_houndeye.cpp b/game/server/vance/npc_houndeye.cpp index 26013704..0c776d11 100644 --- a/game/server/vance/npc_houndeye.cpp +++ b/game/server/vance/npc_houndeye.cpp @@ -1,4 +1,4 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: Cute hound like Alien. // @@ -7,15 +7,15 @@ #include "cbase.h" #include "game.h" -#include "AI_Default.h" -#include "AI_Schedule.h" -#include "AI_Hull.h" -#include "AI_Navigator.h" -#include "AI_Route.h" -#include "AI_Squad.h" -#include "AI_SquadSlot.h" -#include "AI_Hint.h" -#include "NPCEvent.h" +#include "ai_default.h" +#include "ai_schedule.h" +#include "ai_hull.h" +#include "ai_navigator.h" +#include "ai_route.h" +#include "ai_squad.h" +#include "ai_squadslot.h" +#include "ai_hint.h" +#include "npcevent.h" #include "animation.h" #include "npc_houndeye.h" #include "gib.h" diff --git a/game/server/vance/npc_roach.cpp b/game/server/vance/npc_roach.cpp index 77ea5c9d..7de73764 100644 --- a/game/server/vance/npc_roach.cpp +++ b/game/server/vance/npc_roach.cpp @@ -1,44 +1,43 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// -#include "cbase.h" -#include "ai_basenpc.h" -#include "AI_Default.h" -#include "AI_Task.h" -#include "AI_Schedule.h" -#include "AI_Node.h" -#include "AI_Hull.h" -#include "AI_Hint.h" -#include "AI_Memory.h" -#include "AI_Route.h" -#include "AI_Motor.h" -#include "AI_Senses.h" -#include "soundent.h" -#include "game.h" -#include "NPCEvent.h" -#include "EntityList.h" -#include "activitylist.h" -#include "animation.h" -#include "basecombatweapon.h" -#include "IEffects.h" -#include "vstdlib/random.h" -#include "engine/IEngineSound.h" -#include "ammodef.h" -#include "AI_Behavior_Follow.h" -#include "AI_Navigator.h" -#include "decals.h" - - -#define ROACH_IDLE 0 -#define ROACH_BORED 1 -#define ROACH_SCARED_BY_ENT 2 -#define ROACH_SCARED_BY_LIGHT 3 -#define ROACH_SMELL_FOOD 4 -#define ROACH_EAT 5 +#include "cbase.h" +#include "ai_basenpc.h" +#include "ai_default.h" +#include "ai_task.h" +#include "ai_schedule.h" +#include "ai_node.h" +#include "ai_hull.h" +#include "ai_hint.h" +#include "ai_memory.h" +#include "ai_route.h" +#include "ai_motor.h" +#include "ai_senses.h" +#include "ai_behavior_follow.h" +#include "ai_navigator.h" +#include "soundent.h" +#include "game.h" +#include "npcevent.h" +#include "entitylist.h" +#include "activitylist.h" +#include "animation.h" +#include "basecombatweapon.h" +#include "IEffects.h" +#include "vstdlib/random.h" +#include "engine/IEngineSound.h" +#include "ammodef.h" +#include "decals.h" + +#define ROACH_IDLE 0 +#define ROACH_BORED 1 +#define ROACH_SCARED_BY_ENT 2 +#define ROACH_SCARED_BY_LIGHT 3 +#define ROACH_SMELL_FOOD 4 +#define ROACH_EAT 5 //========================================================= // Monster's Anim Events Go Here diff --git a/game/server/vance/vance_player.cpp b/game/server/vance/vance_player.cpp index eb7ec0a3..8ea3b24b 100644 --- a/game/server/vance/vance_player.cpp +++ b/game/server/vance/vance_player.cpp @@ -9,7 +9,7 @@ #include "ai_speech.h" #include "ai_playerally.h" #include "vance_viewmodel.h" -#include "singleplayer_animstate.h" +//#include "singleplayer_animstate.h" #include "datacache/imdlcache.h" #include "in_buttons.h" #include "trains.h" @@ -149,8 +149,8 @@ ConCommand bleed( "bleed", Cmd_Bleed, "Makes the executing Player start bleeding CVancePlayer::CVancePlayer() { // Here we create and init the player animation state. - m_pPlayerAnimState = CreatePlayerAnimationState(this); - m_angEyeAngles.Init(); + //m_pPlayerAnimState = CreatePlayerAnimationState(this); + //m_angEyeAngles.Init(); // Code originally written by Valve. m_nNumMissPositions = 0; @@ -165,11 +165,11 @@ CVancePlayer::CVancePlayer() CVancePlayer::~CVancePlayer() { // Clears the animation state. - if (m_pPlayerAnimState != NULL) + /*if (m_pPlayerAnimState != NULL) { m_pPlayerAnimState->Release(); m_pPlayerAnimState = NULL; - } + }*/ } CVancePlayer *CVancePlayer::Create( edict_t *pEdict ) @@ -1424,13 +1424,13 @@ void CVancePlayer::PostThink() } }*/ - m_angEyeAngles = EyeAngles(); + /*m_angEyeAngles = EyeAngles(); QAngle angles = GetLocalAngles(); angles[PITCH] = 0; SetLocalAngles(angles); - m_pPlayerAnimState->Update(); + m_pPlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );*/ } void CVancePlayer::StartAdmireGlovesAnimation() diff --git a/game/server/vance/vance_player.h b/game/server/vance/vance_player.h index 46c6cc59..1ed06a7f 100644 --- a/game/server/vance/vance_player.h +++ b/game/server/vance/vance_player.h @@ -2,7 +2,7 @@ #define VANCE_PLAYER_H #include "hl2_player.h" -#include "singleplayer_animstate.h" +//#include "singleplayer_animstate.h" #define P_PLAYER_ALYX "models/player/alyx.mdl" #define P_PLAYER_HEV "models/player/hev.mdl" @@ -118,8 +118,8 @@ class CVancePlayer : public CHL2_Player CAI_Expresser *m_pExpresser; bool m_bInAScript; - CSinglePlayerAnimState *m_pPlayerAnimState; - QAngle m_angEyeAngles; + //CSinglePlayerAnimState *m_pPlayerAnimState; + //QAngle m_angEyeAngles; CNetworkVar(float, m_flNextKickAttack); CNetworkVar(float, m_flNextKick); diff --git a/game/server/vance/weapon_357.cpp b/game/server/vance/weapon_357.cpp index 22e9d824..93ac7a69 100644 --- a/game/server/vance/weapon_357.cpp +++ b/game/server/vance/weapon_357.cpp @@ -61,6 +61,17 @@ acttable_t CWeapon357::m_acttable[] = IMPLEMENT_ACTTABLE(CWeapon357); +// Allows Weapon_BackupActivity() to access the 357's activity table. +acttable_t *Get357Acttable() +{ + return CWeapon357::m_acttable; +} + +int Get357ActtableCount() +{ + return ARRAYSIZE(CWeapon357::m_acttable); +} + PRECACHE_WEAPON_REGISTER( weapon_357 ); IMPLEMENT_SERVERCLASS_ST( CWeapon357, DT_Weapon357 ) diff --git a/game/server/vance/weapon_ar2.cpp b/game/server/vance/weapon_ar2.cpp index 96d78a15..5cb4543d 100644 --- a/game/server/vance/weapon_ar2.cpp +++ b/game/server/vance/weapon_ar2.cpp @@ -111,6 +111,19 @@ acttable_t CWeaponAR2::m_acttable[] = IMPLEMENT_ACTTABLE(CWeaponAR2); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the AR2's activity table. +acttable_t *GetAR2Acttable() +{ + return CWeaponAR2::m_acttable; +} + +int GetAR2ActtableCount() +{ + return ARRAYSIZE(CWeaponAR2::m_acttable); +} +#endif + CWeaponAR2::CWeaponAR2( ) { m_fMinRange1 = 65; diff --git a/game/server/vance/weapon_gauss.cpp b/game/server/vance/weapon_gauss.cpp index b6007b6c..413e00dc 100644 --- a/game/server/vance/weapon_gauss.cpp +++ b/game/server/vance/weapon_gauss.cpp @@ -1,4 +1,4 @@ -//========= Copyright 1996-2001, Valve LLC, All rights reserved. ============ +//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -10,7 +10,7 @@ #include "basehlcombatweapon.h" #include "decals.h" #include "beam_shared.h" -#include "AmmoDef.h" +#include "ammodef.h" #include "IEffects.h" #include "engine/IEngineSound.h" #include "in_buttons.h" diff --git a/game/server/vance/weapon_shotgun.cpp b/game/server/vance/weapon_shotgun.cpp index f11f6d8b..e3f9bfeb 100644 --- a/game/server/vance/weapon_shotgun.cpp +++ b/game/server/vance/weapon_shotgun.cpp @@ -158,6 +158,19 @@ acttable_t CWeaponShotgun::m_acttable[] = IMPLEMENT_ACTTABLE(CWeaponShotgun); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the shotgun's activity table. +acttable_t *GetShotgunActtable() +{ + return CWeaponShotgun::m_acttable; +} + +int GetShotgunActtableCount() +{ + return ARRAYSIZE( CWeaponShotgun::m_acttable ); +} +#endif + void CWeaponShotgun::Precache( void ) { CBaseCombatWeapon::Precache(); diff --git a/game/server/vance/weapon_smg1.cpp b/game/server/vance/weapon_smg1.cpp index d2a03fa5..d7ffdd5f 100644 --- a/game/server/vance/weapon_smg1.cpp +++ b/game/server/vance/weapon_smg1.cpp @@ -139,6 +139,19 @@ acttable_t CWeaponSMG1::m_acttable[] = IMPLEMENT_ACTTABLE(CWeaponSMG1); +#ifdef MAPBASE +// Allows Weapon_BackupActivity() to access the SMG1's activity table. +acttable_t *GetSMG1Acttable() +{ + return CWeaponSMG1::m_acttable; +} + +int GetSMG1ActtableCount() +{ + return ARRAYSIZE(CWeaponSMG1::m_acttable); +} +#endif + CWeaponSMG1::CWeaponSMG1( ) { m_fMinRange1 = 0;// No minimum range. diff --git a/game/server/variant_t.cpp b/game/server/variant_t.cpp index 82edcfd4..3b45275b 100644 --- a/game/server/variant_t.cpp +++ b/game/server/variant_t.cpp @@ -6,6 +6,10 @@ #include "cbase.h" #include "variant_t.h" +#ifdef MAPBASE +#include "mapbase/variant_tools.h" +#include "mapbase/matchers.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -16,4 +20,265 @@ void variant_t::SetEntity( CBaseEntity *val ) fieldType = FIELD_EHANDLE; } +#ifdef MAPBASE +const char *variant_t::GetDebug() +{ + /* + case FIELD_BOOLEAN: *((bool *)data) = bVal != 0; break; + case FIELD_CHARACTER: *((char *)data) = iVal; break; + case FIELD_SHORT: *((short *)data) = iVal; break; + case FIELD_INTEGER: *((int *)data) = iVal; break; + case FIELD_STRING: *((string_t *)data) = iszVal; break; + case FIELD_FLOAT: *((float *)data) = flVal; break; + case FIELD_COLOR32: *((color32 *)data) = rgbaVal; break; + + case FIELD_VECTOR: + case FIELD_POSITION_VECTOR: + { + ((float *)data)[0] = vecVal[0]; + ((float *)data)[1] = vecVal[1]; + ((float *)data)[2] = vecVal[2]; + break; + } + + case FIELD_EHANDLE: *((EHANDLE *)data) = eVal; break; + case FIELD_CLASSPTR: *((CBaseEntity **)data) = eVal; break; + */ + + const char *fieldtype = "unknown"; + switch (FieldType()) + { + case FIELD_VOID: fieldtype = "Void"; break; + case FIELD_FLOAT: fieldtype = "Float"; break; + case FIELD_STRING: fieldtype = "String"; break; + case FIELD_INTEGER: fieldtype = "Integer"; break; + case FIELD_BOOLEAN: fieldtype = "Boolean"; break; + case FIELD_EHANDLE: fieldtype = "Entity"; break; + case FIELD_CLASSPTR: fieldtype = "EntityPtr"; break; + case FIELD_POSITION_VECTOR: + case FIELD_VECTOR: fieldtype = "Vector"; break; + case FIELD_CHARACTER: fieldtype = "Character"; break; + case FIELD_SHORT: fieldtype = "Short"; break; + case FIELD_COLOR32: fieldtype = "Color32"; break; + default: fieldtype = UTIL_VarArgs("unknown: %i", FieldType()); + } + return UTIL_VarArgs("%s (%s)", String(), fieldtype); +} + +#ifdef MAPBASE_VSCRIPT +void variant_t::SetScriptVariant( ScriptVariant_t &var ) +{ + switch (FieldType()) + { + case FIELD_VOID: var = NULL; break; + case FIELD_INTEGER: var = iVal; break; + case FIELD_FLOAT: var = flVal; break; + case FIELD_STRING: var = STRING(iszVal); break; + case FIELD_POSITION_VECTOR: + case FIELD_VECTOR: var = reinterpret_cast(&flVal); break; // HACKHACK + case FIELD_BOOLEAN: var = bVal; break; + case FIELD_EHANDLE: var = ToHScript( eVal ); break; + case FIELD_CLASSPTR: var = ToHScript( eVal ); break; + case FIELD_SHORT: var = (short)iVal; break; + case FIELD_CHARACTER: var = (char)iVal; break; + case FIELD_COLOR32: + { + Color *clr = new Color( rgbaVal.r, rgbaVal.g, rgbaVal.b, rgbaVal.a ); + var = g_pScriptVM->RegisterInstance( clr, true ); + break; + } + default: var = ToString(); break; + } +} +#endif + +// cmp1 = val1 float +// cmp2 = val2 float +#define VariantToFloat(val1, val2, lenallowed) \ + float cmp1 = val1.Float() ? val1.Float() : val1.Int(); \ + float cmp2 = val2.Float() ? val2.Float() : val2.Int(); \ + if (lenallowed && val2.FieldType() == FIELD_STRING) \ + cmp2 = strlen(val2.String()); + +// Integer parsing has been deactivated for consistency's sake. They now become floats only. +#define INTEGER_PARSING_DEACTIVATED 1 + +// "intchar" is the result of me not knowing where to find a version of isdigit that applies to negative numbers and floats. +#define intchar(c) (c >= '-' && c <= '9') + +// Attempts to determine the field type from whatever is in the string and creates a variant_t with the converted value and resulting field type. +// Right now, Int/Float, String, and Vector are the only fields likely to be used by entities in variant_t parsing, so they're the only ones supported. +// Expand to other fields when necessary. +variant_t Variant_Parse(const char *szValue) +{ +#ifdef INTEGER_PARSING_DEACTIVATED + bool isint = true; + bool isvector = false; + for (size_t i = 0; i < strlen(szValue); i++) + { + if (!intchar(szValue[i])) + { + isint = false; + + if (szValue[i] == ' ') + isvector = true; + else + isvector = false; + } + } + + variant_t var; + + if (isint) + var.SetFloat(atof(szValue)); + else if (isvector) + { + var.SetString(MAKE_STRING(szValue)); + var.Convert(FIELD_VECTOR); + } + else + var.SetString(MAKE_STRING(szValue)); +#else + bool isint = true; + bool isfloat = false; + for (size_t i = 0; i < strlen(szValue); i++) + { + if (szValue[i] == '.') + isfloat = true; + else if (!intchar(szValue[i])) + isint = false; + } + + variant_t var = variant_t(); + + if (isint) + { + if (isfloat) + var.SetFloat(atof(szValue)); + else + var.SetInt(atoi(szValue)); + } + else + var.SetString(MAKE_STRING(szValue)); +#endif + + return var; +} + +// Passes strings to Variant_Parse, uses the other input data for finding procedural entities. +variant_t Variant_ParseInput(inputdata_t inputdata) +{ + if (inputdata.value.FieldType() == FIELD_STRING) + { + if (inputdata.value.String()[0] == '!') + { + variant_t var = variant_t(); + var.SetEntity(gEntList.FindEntityProcedural(inputdata.value.String(), inputdata.pCaller, inputdata.pActivator, inputdata.pCaller)); + if (var.Entity()) + return var; + } + } + + return Variant_Parse(inputdata.value.String()); +} + +// Passes string variants to Variant_Parse +variant_t Variant_ParseString(variant_t value) +{ + if (value.FieldType() != FIELD_STRING) + return value; + + return Variant_Parse(value.String()); +} + +bool Variant_Equal(variant_t val1, variant_t val2, bool bLenAllowed) +{ + //if (!val2.Convert(val1.FieldType())) + // return false; + + // Add more fields if they become necessary + switch (val1.FieldType()) + { + case FIELD_INTEGER: + case FIELD_FLOAT: + { + VariantToFloat(val1, val2, bLenAllowed); + return cmp1 == cmp2; + } + case FIELD_BOOLEAN: return val1.Bool() == val2.Bool(); + case FIELD_EHANDLE: return val1.Entity() == val2.Entity(); + case FIELD_VECTOR: + { + Vector vec1; val1.Vector3D(vec1); + Vector vec2; val2.Vector3D(vec2); + return vec1 == vec2; + } +#ifdef MAPBASE_MATCHERS + // logic_compare allows wildcards on either string + default: return Matcher_NamesMatch_MutualWildcard(val1.String(), val2.String()); +#else + default: return FStrEq(val1.String(), val2.String()); +#endif + } + + return false; +} + +// val1 > val2 +bool Variant_Greater(variant_t val1, variant_t val2, bool bLenAllowed) +{ + //if (!val2.Convert(val1.FieldType())) + // return false; + + // Add more fields if they become necessary + switch (val1.FieldType()) + { + case FIELD_INTEGER: + case FIELD_FLOAT: + { + VariantToFloat(val1, val2, bLenAllowed); + return cmp1 > cmp2; + } + case FIELD_BOOLEAN: return val1.Bool() && !val2.Bool(); + case FIELD_VECTOR: + { + Vector vec1; val1.Vector3D(vec1); + Vector vec2; val2.Vector3D(vec2); + return (vec1.x > vec2.x) && (vec1.y > vec2.y) && (vec1.z > vec2.z); + } + default: return strlen(val1.String()) > strlen(val2.String()); + } + + return false; +} + +// val1 >= val2 +bool Variant_GreaterOrEqual(variant_t val1, variant_t val2, bool bLenAllowed) +{ + //if (!val2.Convert(val1.FieldType())) + // return false; + + // Add more fields if they become necessary + switch (val1.FieldType()) + { + case FIELD_INTEGER: + case FIELD_FLOAT: + { + VariantToFloat(val1, val2, bLenAllowed); + return cmp1 >= cmp2; + } + case FIELD_BOOLEAN: return val1.Bool() >= val2.Bool(); + case FIELD_VECTOR: + { + Vector vec1; val1.Vector3D(vec1); + Vector vec2; val2.Vector3D(vec2); + return (vec1.x >= vec2.x) && (vec1.y >= vec2.y) && (vec1.z >= vec2.z); + } + default: return strlen(val1.String()) >= strlen(val2.String()); + } + + return false; +} +#endif + diff --git a/game/server/variant_t.h b/game/server/variant_t.h index d5e93ea4..fc460bfe 100644 --- a/game/server/variant_t.h +++ b/game/server/variant_t.h @@ -17,6 +17,10 @@ class CBaseEntity; +#ifdef MAPBASE_VSCRIPT +struct ScriptVariant_t; +#endif + // // A variant class for passing data in entity input/output connections. @@ -49,6 +53,10 @@ class variant_t inline const CHandle &Entity(void) const; inline color32 Color32(void) const { return rgbaVal; } inline void Vector3D(Vector &vec) const; +#ifdef MAPBASE + // Gets angles from a vector + inline void Angle3D(QAngle &ang) const; +#endif fieldtype_t FieldType( void ) { return fieldType; } @@ -59,11 +67,26 @@ class variant_t void SetEntity( CBaseEntity *val ); void SetVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_VECTOR; } void SetPositionVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_POSITION_VECTOR; } +#ifdef MAPBASE + // Passes in angles as a vector + void SetAngle3D( const QAngle &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_VECTOR; } +#endif void SetColor32( color32 val ) { rgbaVal = val; fieldType = FIELD_COLOR32; } void SetColor32( int r, int g, int b, int a ) { rgbaVal.r = r; rgbaVal.g = g; rgbaVal.b = b; rgbaVal.a = a; fieldType = FIELD_COLOR32; } void Set( fieldtype_t ftype, void *data ); void SetOther( void *data ); bool Convert( fieldtype_t newType ); +#ifdef MAPBASE + // Special conversion specifically for FIELD_EHANDLE with !activator, etc. + bool Convert( fieldtype_t newType, CBaseEntity *pSelf, CBaseEntity *pActivator, CBaseEntity *pCaller ); + // Hands over the value + the field type. + // ex: "Otis (String)", "3 (Integer)", or "npc_combine_s (Entity)" + const char *GetDebug(); +#endif + +#ifdef MAPBASE_VSCRIPT + void SetScriptVariant( ScriptVariant_t &var ); +#endif static typedescription_t m_SaveBool[]; static typedescription_t m_SaveInt[]; @@ -105,6 +128,25 @@ inline void variant_t::Vector3D(Vector &vec) const } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Returns this variant as angles. +//----------------------------------------------------------------------------- +inline void variant_t::Angle3D(QAngle &ang) const +{ + if (( fieldType == FIELD_VECTOR ) || ( fieldType == FIELD_POSITION_VECTOR )) + { + ang[0] = vecVal[0]; + ang[1] = vecVal[1]; + ang[2] = vecVal[2]; + } + else + { + ang = vec3_angle; + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Returns this variant as an EHANDLE. //----------------------------------------------------------------------------- diff --git a/game/server/vehicle_base.cpp b/game/server/vehicle_base.cpp index f916ba69..5e348ee9 100644 --- a/game/server/vehicle_base.cpp +++ b/game/server/vehicle_base.cpp @@ -66,6 +66,15 @@ BEGIN_DATADESC( CPropVehicle ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CPropVehicle, CBaseAnimating, "The base class for four-wheel physics vehicles." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetVehicleType, "GetVehicleType", "Get a vehicle's type." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysics, "GetPhysics", "Get a vehicle's physics." ) + +END_SCRIPTDESC(); +#endif + LINK_ENTITY_TO_CLASS( prop_vehicle, CPropVehicle ); //----------------------------------------------------------------------------- @@ -226,6 +235,23 @@ void CPropVehicle::InputHandBrakeOff( inputdata_t &inputdata ) m_VehiclePhysics.ReleaseHandbrake(); } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HSCRIPT CPropVehicle::ScriptGetPhysics() +{ + HSCRIPT hScript = NULL; + CFourWheelVehiclePhysics *pPhysics = GetPhysics(); + if (pPhysics) + { + hScript = g_pScriptVM->RegisterInstance( pPhysics ); + } + + return hScript; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -334,6 +360,12 @@ BEGIN_DATADESC( CPropVehicleDriveable ) DEFINE_INPUTFUNC( FIELD_VOID, "Unlock", InputUnlock ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ), DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "EnterVehicle", InputEnterVehicle ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnterVehicleImmediate", InputEnterVehicleImmediate ), + DEFINE_INPUTFUNC( FIELD_VOID, "ExitVehicle", InputExitVehicle ), + DEFINE_INPUTFUNC( FIELD_VOID, "ExitVehicleImmediate", InputExitVehicleImmediate ), +#endif DEFINE_INPUT( m_bHasGun, FIELD_BOOLEAN, "EnableGun" ), // Outputs @@ -343,6 +375,9 @@ BEGIN_DATADESC( CPropVehicleDriveable ) DEFINE_OUTPUT( m_pressedAttack2, "PressedAttack2" ), DEFINE_OUTPUT( m_attackaxis, "AttackAxis" ), DEFINE_OUTPUT( m_attack2axis, "Attack2Axis" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ), +#endif DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ), DEFINE_EMBEDDEDBYREF( m_pServerVehicle ), @@ -370,6 +405,19 @@ BEGIN_DATADESC( CPropVehicleDriveable ) END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CPropVehicleDriveable, CPropVehicle, "The base class for driveable vehicles." ) + + DEFINE_SCRIPTFUNC( IsOverturned, "Check if the vehicle is overturned." ) + DEFINE_SCRIPTFUNC( IsVehicleBodyInWater, "Check if the vehicle's body is submerged in water." ) + DEFINE_SCRIPTFUNC( StartEngine, "Start the engine." ) + DEFINE_SCRIPTFUNC( StopEngine, "Stop the engine." ) + DEFINE_SCRIPTFUNC( IsEngineOn, "Check if the engine is on." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetDriver, "GetDriver", "Get a vehicle's driver, which could be either a player or a npc_vehicledriver." ) + +END_SCRIPTDESC(); +#endif + LINK_ENTITY_TO_CLASS( prop_vehicle_driveable, CPropVehicleDriveable ); @@ -557,6 +605,10 @@ void CPropVehicleDriveable::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, ResetUseKey( pPlayer ); +#ifdef MAPBASE + m_OnPlayerUse.FireOutput(pActivator, this); +#endif + m_pServerVehicle->HandlePassengerEntry( pPlayer, (value>0) ); } @@ -847,6 +899,99 @@ void CPropVehicleDriveable::InputTurnOff( inputdata_t &inputdata ) m_VehiclePhysics.SetDisableEngine( true ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropVehicleDriveable::InputEnterVehicle( inputdata_t &inputdata ) +{ + if ( m_bEnterAnimOn ) + return; + + // Try the activator first & use them if they are a player. + CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator ); + if ( pPassenger == NULL ) + { + // Activator was not a player, just grab the singleplayer player. + pPassenger = UTIL_PlayerByIndex( 1 ); + if ( pPassenger == NULL ) + return; + } + + // FIXME: I hate code like this. I should really add a parameter to HandlePassengerEntry + // to allow entry into locked vehicles + bool bWasLocked = m_bLocked; + m_bLocked = false; + GetServerVehicle()->HandlePassengerEntry( pPassenger, true ); + m_bLocked = bWasLocked; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CPropVehicleDriveable::InputEnterVehicleImmediate( inputdata_t &inputdata ) +{ + if ( m_bEnterAnimOn ) + return; + + // Try the activator first & use them if they are a player. + CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator ); + if ( pPassenger == NULL ) + { + // Activator was not a player, just grab the singleplayer player. + pPassenger = UTIL_PlayerByIndex( 1 ); + if ( pPassenger == NULL ) + return; + } + + CBasePlayer *pPlayer = ToBasePlayer( pPassenger ); + if ( pPlayer != NULL ) + { + if ( pPlayer->IsInAVehicle() ) + { + // Force the player out of whatever vehicle they are in. + pPlayer->LeaveVehicle(); + } + + pPlayer->GetInVehicle( GetServerVehicle(), VEHICLE_ROLE_DRIVER ); + } + else + { + // NPCs are not currently supported - jdw + Assert( 0 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropVehicleDriveable::InputExitVehicle( inputdata_t &inputdata ) +{ + if (!GetDriver()) + return; + + if ( CanExitVehicle(GetDriver()) ) + { + GetServerVehicle()->HandlePassengerExit(GetDriver()->MyCombatCharacterPointer()); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPropVehicleDriveable::InputExitVehicleImmediate( inputdata_t &inputdata ) +{ + if (!GetDriver()) + return; + + if (GetDriver()->IsPlayer()) + { + static_cast(GetDriver())->LeaveVehicle(); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Check to see if the engine is on. //----------------------------------------------------------------------------- diff --git a/game/server/vehicle_base.h b/game/server/vehicle_base.h index ab63005a..831ea6b4 100644 --- a/game/server/vehicle_base.h +++ b/game/server/vehicle_base.h @@ -109,6 +109,12 @@ class CPropVehicle : public CBaseProp, public CDefaultPlayerPickupVPhysics void InputHandBrakeOff( inputdata_t &inputdata ); DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); + + HSCRIPT ScriptGetPhysics(); + int ScriptGetVehicleType() { return GetVehicleType(); } +#endif #ifdef HL2_EPISODIC void AddPhysicsChild( CBaseEntity *pChild ); @@ -166,6 +172,9 @@ class CPropVehicleDriveable : public CPropVehicle, public IDrivableVehicle, publ DECLARE_CLASS( CPropVehicleDriveable, CPropVehicle ); DECLARE_SERVERCLASS(); DECLARE_DATADESC(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif public: CPropVehicleDriveable( void ); ~CPropVehicleDriveable( void ); @@ -192,6 +201,12 @@ class CPropVehicleDriveable : public CPropVehicle, public IDrivableVehicle, publ void InputUnlock( inputdata_t &inputdata ); void InputTurnOn( inputdata_t &inputdata ); void InputTurnOff( inputdata_t &inputdata ); +#ifdef MAPBASE + virtual void InputEnterVehicle( inputdata_t &inputdata ); + virtual void InputEnterVehicleImmediate( inputdata_t &inputdata ); + virtual void InputExitVehicle( inputdata_t &inputdata ); + virtual void InputExitVehicleImmediate( inputdata_t &inputdata ); +#endif // Locals void ResetUseKey( CBasePlayer *pPlayer ); @@ -232,6 +247,10 @@ class CPropVehicleDriveable : public CPropVehicle, public IDrivableVehicle, publ // If this is a vehicle, returns the vehicle interface virtual IServerVehicle *GetServerVehicle() { return m_pServerVehicle; } +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetDriver() { return ToHScript( GetDriver() ); } +#endif + protected: virtual bool ShouldThink() { return ( GetDriver() != NULL ); } @@ -251,6 +270,10 @@ class CPropVehicleDriveable : public CPropVehicle, public IDrivableVehicle, publ COutputFloat m_attackaxis; COutputFloat m_attack2axis; +#ifdef MAPBASE + COutputEvent m_OnPlayerUse; +#endif + CNetworkHandle( CBasePlayer, m_hPlayer ); public: diff --git a/game/server/vehicle_choreo_generic.cpp b/game/server/vehicle_choreo_generic.cpp index b644a7a4..3b3a53f9 100644 --- a/game/server/vehicle_choreo_generic.cpp +++ b/game/server/vehicle_choreo_generic.cpp @@ -197,6 +197,11 @@ class CPropVehicleChoreoGeneric : public CDynamicProp, public IDrivableVehicle // If this is a vehicle, returns the vehicle interface virtual IServerVehicle *GetServerVehicle() { return &m_ServerVehicle; } +#ifdef MAPBASE + virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return m_bAllowStandardWeapons; } + CNetworkVar( bool, m_bAllowStandardWeapons ); +#endif + bool ShouldCollide( int collisionGroup, int contentsMask ) const; bool m_bForcePlayerEyePoint; // Uses player's eyepoint instead of 'vehicle_driver_eyes' attachment @@ -256,6 +261,10 @@ BEGIN_DATADESC( CPropVehicleChoreoGeneric ) DEFINE_KEYFIELD( m_bIgnorePlayerCollisions, FIELD_BOOLEAN, "ignoreplayer" ), DEFINE_KEYFIELD( m_bForcePlayerEyePoint, FIELD_BOOLEAN, "useplayereyes" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bAllowStandardWeapons, FIELD_BOOLEAN, "AllowStandardWeapons" ), +#endif + DEFINE_OUTPUT( m_playerOn, "PlayerOn" ), DEFINE_OUTPUT( m_playerOff, "PlayerOff" ), DEFINE_OUTPUT( m_OnOpen, "OnOpen" ), @@ -281,6 +290,9 @@ IMPLEMENT_SERVERCLASS_ST(CPropVehicleChoreoGeneric, DT_PropVehicleChoreoGeneric) SendPropFloat( SENDINFO_STRUCTELEM( m_vehicleView.flYawMax ) ), SendPropFloat( SENDINFO_STRUCTELEM( m_vehicleView.flPitchMin ) ), SendPropFloat( SENDINFO_STRUCTELEM( m_vehicleView.flPitchMax ) ), +#ifdef MAPBASE + SendPropBool( SENDINFO( m_bAllowStandardWeapons ) ), +#endif END_SEND_TABLE(); diff --git a/game/server/vote_controller.cpp b/game/server/vote_controller.cpp index a29b449f..316974ad 100644 --- a/game/server/vote_controller.cpp +++ b/game/server/vote_controller.cpp @@ -10,11 +10,9 @@ #include "eiface.h" #include "team.h" #include "gameinterface.h" -#include "fmtstr.h" #ifdef TF_DLL #include "tf/tf_gamerules.h" -#include "tf/tf_voteissues.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -39,139 +37,17 @@ LINK_ENTITY_TO_CLASS( vote_controller, CVoteController ); CVoteController *g_voteController = NULL; -ConVar sv_vote_timer_duration( "sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue" ); -ConVar sv_vote_command_delay( "sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0.f, true, 4.5f ); -ConVar sv_allow_votes( "sv_allow_votes", "1", FCVAR_NONE, "Allow voting?" ); -ConVar sv_vote_failure_timer( "sv_vote_failure_timer", "300", FCVAR_NONE, "A vote that fails cannot be re-submitted for this long" ); +ConVar sv_vote_timer_duration("sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue"); +ConVar sv_vote_command_delay("sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0, true, 4.5); +ConVar sv_allow_votes("sv_allow_votes", "1", 0, "Allow voting?"); +ConVar sv_vote_failure_timer("sv_vote_failure_timer", "300", 0, "A vote that fails cannot be re-submitted for this long"); #ifdef TF_DLL -ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", FCVAR_NONE, "A vote that fails in MvM cannot be re-submitted for this long" ); +ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", 0, "A vote that fails in MvM cannot be re-submitted for this long" ); #endif // TF_DLL -ConVar sv_vote_creation_timer( "sv_vote_creation_timer", "150", FCVAR_NONE, "How long before a player can attempt to call another vote (in seconds)." ); -ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", FCVAR_NOTIFY, "The minimum ratio of eligible players needed to pass a vote. Min 0.5, Max 1.0.", true, 0.1f, true, 1.0f ); -ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", FCVAR_NONE, "Allow spectators to vote?" ); -ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", FCVAR_NONE, "Suppress listing of disabled issues in the vote setup screen." ); - -static const int k_nKickWatchListMaxDuration = 300; - -//----------------------------------------------------------------------------- -// Purpose: Game system to detect maps without cameras in them, and move on -//----------------------------------------------------------------------------- -class CVoteControllerSystem : public CAutoGameSystemPerFrame -{ -public: - CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name ) - { - SetDefLessFunc( m_mapKickWatchList ); - SetDefLessFunc( m_mapNameLockedList ); - m_flNextKickCheckTime = 0.f; - m_flNextNameLockCheckTime = 0.f; - } - - virtual void LevelInitPreEntity() - { - } - - virtual void FrameUpdatePostEntityThink( void ) - { - // Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and - // blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after - // you in Physics_RunThinkFunctions() to get grumpy and crash. - if ( g_voteController ) - { - // Vote passed - execute the command - if ( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() ) - { - g_voteController->m_executeCommandTimer.Invalidate(); - g_voteController->m_potentialIssues[g_voteController->m_iActiveIssueIndex]->ExecuteCommand(); - } - - // Kick watch - if ( m_flNextKickCheckTime < gpGlobals->curtime ) - { - FOR_EACH_MAP( m_mapKickWatchList, i ) - { - if ( gpGlobals->curtime > m_mapKickWatchList[i] ) - { - m_mapKickWatchList.RemoveAt( i ); - break; // Constantly called code - resume on next pass - } - - CBasePlayer *pTarget = UTIL_PlayerBySteamID( m_mapKickWatchList.Key( i ) ); - if ( pTarget ) - { - // Welcome back - engine->ServerCommand( CFmtStr( "kickid %d %s;", pTarget->GetUserID(), "Kicked by server." ) ); - } - } - - m_flNextKickCheckTime = gpGlobals->curtime + 0.2f; - } - - // Name lock management - if ( m_flNextNameLockCheckTime < gpGlobals->curtime ) - { - FOR_EACH_MAP( m_mapNameLockedList, i ) - { - CBasePlayer *pPlayer = UTIL_PlayerBySteamID( m_mapNameLockedList.Key( i ) ); - - // Time up? - if ( gpGlobals->curtime > m_mapNameLockedList[i] ) - { - // Disable the lock if they're still here - if ( pPlayer ) - { - engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", pPlayer->GetUserID(), 0 ) ); - } - - // Remove and break - this will re-run in 1 second - m_mapNameLockedList.RemoveAt( i ); - break; - } - // See if they reconnected - else if ( pPlayer && !engine->IsPlayerNameLocked( pPlayer->edict() ) ) - { - engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", pPlayer->GetUserID(), 1 ) ); - } - } - - m_flNextNameLockCheckTime = gpGlobals->curtime + 1.f; - } - } - } - - void AddPlayerToKickWatchList( CSteamID steamID, float flDuration ) - { - if ( !steamID.IsValid() || !steamID.BIndividualAccount() ) - return; - - flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration ); - if ( m_mapKickWatchList.Find( steamID ) == m_mapKickWatchList.InvalidIndex() ) - { - m_mapKickWatchList.Insert( steamID, ( gpGlobals->curtime + flDuration ) ); - } - } - - void AddPlayerToNameLockedList( CSteamID steamID, float flDuration ) - { - if ( !steamID.IsValid() || !steamID.BIndividualAccount() ) - return; - - flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration ); - if ( m_mapNameLockedList.Find( steamID ) == m_mapNameLockedList.InvalidIndex() ) - { - m_mapNameLockedList.Insert( steamID, ( gpGlobals->curtime + flDuration ) ); - } - } - -private: - - CUtlMap< CSteamID, float > m_mapKickWatchList; - CUtlMap< CSteamID, float > m_mapNameLockedList; - float m_flNextKickCheckTime; - float m_flNextNameLockCheckTime; -}; - -CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" ); +ConVar sv_vote_creation_timer("sv_vote_creation_timer", "120", FCVAR_DEVELOPMENTONLY, "How often someone can individually call a vote."); +ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", 1, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 ); +ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", 0, "Allow spectators to vote?" ); +ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", 0, "Suppress listing of disabled issues in the vote setup screen." ); //----------------------------------------------------------------------------- // Purpose: @@ -218,33 +94,27 @@ CON_COMMAND( callvote, "Start a vote on an issue." ) } CBasePlayer *pVoteCaller = UTIL_GetCommandClient(); - if ( !pVoteCaller ) + if( !pVoteCaller ) return; if ( !sv_vote_allow_spectators.GetBool() ) { if ( pVoteCaller->GetTeamNumber() == TEAM_SPECTATOR ) { - g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller ); + g_voteController->SendVoteFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller ); return; } } - if ( g_voteController->IsVoteActive() ) - { - ClientPrint( pVoteCaller, HUD_PRINTCENTER, "#GameUI_vote_failed_vote_in_progress" ); - return; - } - - // Ask the controller if this is allowed + // Prevent spamming commands +#ifndef _DEBUG int nCooldown = 0; - vote_create_failed_t nError = VOTE_FAILED_GENERIC; - - if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown, nError ) ) + if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown ) ) { - g_voteController->SendVoteCreationFailedMessage( nError, pVoteCaller, nCooldown ); + g_voteController->SendVoteFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown ); return; } +#endif // Parameters char szEmptyDetails[MAX_VOTE_DETAILS_LENGTH]; @@ -253,7 +123,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." ) const char *arg3 = args.ArgC() >= 3 ? args[2] : szEmptyDetails; // If we don't have any arguments, invoke VoteSetup UI - if ( args.ArgC() < 2 ) + if( args.ArgC() < 2 ) { g_voteController->SetupVote( pVoteCaller->entindex() ); return; @@ -291,7 +161,7 @@ void CVoteController::ResetData( void ) m_acceptingVotesTimer.Invalidate(); m_executeCommandTimer.Invalidate(); m_iEntityHoldingVote = -1; - m_iOnlyTeamToVote = TEAM_UNASSIGNED; + m_iOnlyTeamToVote = TEAM_INVALID; m_bIsYesNoVote = true; for( int voteIndex = 0; voteIndex < ARRAYSIZE( m_nVotesCast ); ++voteIndex ) @@ -326,25 +196,12 @@ int CVoteController::UpdateTransmitState( void ) return SetTransmitState( FL_EDICT_ALWAYS ); } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CVoteController::IsVoteSystemEnabled( void ) -{ -#ifdef TF_DLL - if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() ) - return false; -#endif // TF_DLL - - return sv_allow_votes.GetBool(); -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CVoteController::CanTeamCastVote( int iTeam ) const { - if ( m_iOnlyTeamToVote == TEAM_UNASSIGNED ) + if ( m_iOnlyTeamToVote == TEAM_INVALID ) return true; return iTeam == m_iOnlyTeamToVote; @@ -362,7 +219,7 @@ bool CVoteController::SetupVote( int iEntIndex ) int nIssueCount = 0; // Passing an nIssueCount of 0 triggers a "Voting disabled on server" message in the setup UI - if ( IsVoteSystemEnabled() ) + if ( sv_allow_votes.GetBool() ) { for( int iIndex = 0; iIndex < m_potentialIssues.Count(); ++iIndex ) { @@ -382,28 +239,28 @@ bool CVoteController::SetupVote( int iEntIndex ) filter.MakeReliable(); UserMessageBegin( filter, "VoteSetup" ); WRITE_BYTE( nIssueCount ); - int nMsgSize = 0; for( int iIndex = 0; iIndex < m_potentialIssues.Count(); ++iIndex ) { CBaseIssue *pCurrentIssue = m_potentialIssues[iIndex]; if ( pCurrentIssue ) { - // Don't send/display disabled issues when set - if ( !pCurrentIssue->IsEnabled() && sv_vote_ui_hide_disabled_issues.GetBool() ) - continue; - - // Don't exceed MAX_USER_MSG_DATA (hack) - nMsgSize += ( V_strlen( pCurrentIssue->GetTypeString() ) + 1 ); - nMsgSize += ( V_strlen( pCurrentIssue->GetTypeStringLocalized() ) + 1 ); - ++nMsgSize; - Assert( nMsgSize <= MAX_USER_MSG_DATA ); - if ( nMsgSize > MAX_USER_MSG_DATA ) - continue; - - WRITE_STRING( pCurrentIssue->GetTypeString() ); - WRITE_STRING( pCurrentIssue->GetTypeStringLocalized() ); - WRITE_BYTE( pCurrentIssue->IsEnabled() ); + if ( pCurrentIssue->IsEnabled() ) + { + WRITE_STRING( pCurrentIssue->GetTypeString() ); + } + else + { + // Don't send/display disabled issues when set + if ( sv_vote_ui_hide_disabled_issues.GetBool() ) + continue; + + char szDisabledIssueStr[MAX_COMMAND_LENGTH + 12]; + V_strcpy( szDisabledIssueStr, pCurrentIssue->GetTypeString() ); + V_strcat( szDisabledIssueStr, " (Disabled on Server)", sizeof(szDisabledIssueStr) ); + + WRITE_STRING( szDisabledIssueStr ); + } } } @@ -420,29 +277,29 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons // Terrible Hack: Dedicated servers pass 99 as the EntIndex bool bDedicatedServer = ( iEntIndex == DEDICATED_SERVER ) ? true : false; - if ( !IsVoteSystemEnabled() ) + if( !sv_allow_votes.GetBool() ) return false; // Already running a vote? - if ( IsVoteActive() ) + if( IsVoteActive() ) return false; CBasePlayer *pVoteCaller = UTIL_PlayerByIndex( iEntIndex ); - if ( !pVoteCaller && !bDedicatedServer ) + if( !pVoteCaller && !bDedicatedServer ) return false; // Find the issue the user is asking for - for ( int issueIndex = 0; issueIndex < m_potentialIssues.Count(); ++issueIndex ) + for( int issueIndex = 0; issueIndex < m_potentialIssues.Count(); ++issueIndex ) { CBaseIssue *pCurrentIssue = m_potentialIssues[issueIndex]; if ( !pCurrentIssue ) return false; - if ( FStrEq( pszTypeString, pCurrentIssue->GetTypeString() ) ) + if( FStrEq( pszTypeString, pCurrentIssue->GetTypeString() ) ) { vote_create_failed_t nErrorCode = VOTE_FAILED_GENERIC; int nTime = 0; - if ( pCurrentIssue->CanCallVote( iEntIndex, pszDetailString, nErrorCode, nTime ) ) + if( pCurrentIssue->CanCallVote( iEntIndex, pszDetailString, nErrorCode, nTime ) ) { // Establish a bunch of data on this particular issue pCurrentIssue->SetIssueDetails( pszDetailString ); @@ -451,7 +308,14 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons m_iEntityHoldingVote = iEntIndex; if ( !bDedicatedServer ) { - m_iOnlyTeamToVote = ( pCurrentIssue->IsTeamRestrictedVote() ) ? GetVoterTeam( pVoteCaller ) : TEAM_UNASSIGNED; + if( pCurrentIssue->IsAllyRestrictedVote() ) + { + m_iOnlyTeamToVote = GetVoterTeam( pVoteCaller ); + } + else + { + m_iOnlyTeamToVote = TEAM_INVALID; + } } // Now get our choices @@ -487,10 +351,10 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons // Now the vote handling and UI m_nPotentialVotes = pCurrentIssue->CountPotentialVoters(); - m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() + random->RandomFloat( -1.f, 1.f ) ); + m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() ); // Force the vote holder to agree with a Yes/No vote - if ( pCurrentIssue->IsYesNoVote() && !bDedicatedServer ) + if ( m_bIsYesNoVote && !bDedicatedServer ) { TryCastVote( iEntIndex, "Option1" ); } @@ -503,7 +367,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons WRITE_BYTE( m_iEntityHoldingVote ); WRITE_STRING( pCurrentIssue->GetDisplayString() ); WRITE_STRING( pCurrentIssue->GetDetailsString() ); - WRITE_BOOL( pCurrentIssue->IsYesNoVote() ); + WRITE_BOOL( m_bIsYesNoVote ); MessageEnd(); if ( !bDedicatedServer ) @@ -517,7 +381,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons { if ( !bDedicatedServer ) { - SendVoteCreationFailedMessage( nErrorCode, pVoteCaller, nTime ); + SendVoteFailedMessage( nErrorCode, pVoteCaller, nTime ); } } } @@ -527,39 +391,35 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons } //----------------------------------------------------------------------------- -// Purpose: The vote failed to start - let the caller know why -//----------------------------------------------------------------------------- -void CVoteController::SendVoteCreationFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime /*= -1*/ ) -{ - Assert( pVoteCaller ); - if ( !pVoteCaller ) - return; - - CSingleUserRecipientFilter user( pVoteCaller ); - user.MakeReliable(); - - UserMessageBegin( user, "CallVoteFailed" ); - WRITE_BYTE( nReason ); - WRITE_SHORT( nTime ); - MessageEnd(); -} - -//----------------------------------------------------------------------------- -// Purpose: The vote was called, but failed to pass - let everyone know why +// Purpose: Sent to everyone, unless we pass a player pointer //----------------------------------------------------------------------------- -void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason ) +void CVoteController::SendVoteFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime ) { - Assert( m_potentialIssues[m_iActiveIssueIndex] ); + // driller: need to merge all failure case stuff into a single path + if ( pVoteCaller ) + { + CSingleUserRecipientFilter user( pVoteCaller ); + user.MakeReliable(); - UTIL_LogPrintf( "Vote failed \"%s %s\" with code %i\n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), (int)nReason ); + UserMessageBegin( user, "CallVoteFailed" ); + WRITE_BYTE( nReason ); + WRITE_SHORT( nTime ); + MessageEnd(); + } + else + { + UTIL_LogPrintf("Vote failed \"%s %s\" \n", + m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), + m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() ); - CBroadcastRecipientFilter filter; - filter.MakeReliable(); + CBroadcastRecipientFilter filter; + filter.MakeReliable(); - UserMessageBegin( filter, "VoteFailed" ); - WRITE_BYTE( m_iOnlyTeamToVote ); - WRITE_BYTE( nReason ); - MessageEnd(); + UserMessageBegin( filter, "VoteFailed" ); + WRITE_BYTE( m_iOnlyTeamToVote ); + WRITE_BYTE( nReason ); + MessageEnd(); + } } //----------------------------------------------------------------------------- @@ -567,24 +427,24 @@ void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason //----------------------------------------------------------------------------- CVoteController::TryCastVoteResult CVoteController::TryCastVote( int iEntIndex, const char *pszVoteString ) { - if ( !IsVoteSystemEnabled() ) + if( !sv_allow_votes.GetBool() ) return CAST_FAIL_SERVER_DISABLE; - if ( iEntIndex >= ARRAYSIZE( m_nVotesCast ) ) + if( iEntIndex >= ARRAYSIZE( m_nVotesCast ) ) return CAST_FAIL_SYSTEM_ERROR; - if ( !IsVoteActive() ) + if( !IsVoteActive() ) return CAST_FAIL_NO_ACTIVE_ISSUE; - if ( m_executeCommandTimer.HasStarted() ) + if( m_executeCommandTimer.HasStarted() ) return CAST_FAIL_VOTE_CLOSED; - if ( m_potentialIssues[m_iActiveIssueIndex] && m_potentialIssues[m_iActiveIssueIndex]->IsTeamRestrictedVote() ) + if( m_potentialIssues[m_iActiveIssueIndex] && m_potentialIssues[m_iActiveIssueIndex]->IsAllyRestrictedVote() ) { CBaseEntity *pVoteHolder = UTIL_EntityByIndex( m_iEntityHoldingVote ); CBaseEntity *pVoter = UTIL_EntityByIndex( iEntIndex ); - if ( ( pVoteHolder == NULL ) || ( pVoter == NULL ) || ( GetVoterTeam( pVoteHolder ) != GetVoterTeam( pVoter ) ) ) + if( ( pVoteHolder == NULL ) || ( pVoter == NULL ) || ( GetVoterTeam( pVoteHolder ) != GetVoterTeam( pVoter ) ) ) { return CAST_FAIL_TEAM_RESTRICTED; } @@ -593,7 +453,7 @@ CVoteController::TryCastVoteResult CVoteController::TryCastVote( int iEntIndex, // Look for a previous vote int nOldVote = m_nVotesCast[iEntIndex]; #ifndef DEBUG - if ( nOldVote != VOTE_UNCAST ) + if( nOldVote != VOTE_UNCAST ) { return CAST_FAIL_NO_CHANGES; } @@ -685,54 +545,65 @@ void CVoteController::VoteControllerThink( void ) } // Vote time is up - process the result - if ( m_acceptingVotesTimer.HasStarted() && m_acceptingVotesTimer.IsElapsed() ) + if( m_acceptingVotesTimer.HasStarted() && m_acceptingVotesTimer.IsElapsed() ) { m_acceptingVotesTimer.Invalidate(); - // For GC record-keeping + int nVoteTally = 0; + for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) + { + nVoteTally += m_nVoteOptionCount.Get( index ); + } + + bool bVotePassed = true; + + // for record-keeping if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ) { m_potentialIssues[m_iActiveIssueIndex]->SetYesNoVoteCount( m_nVoteOptionCount[VOTE_OPTION1], m_nVoteOptionCount[VOTE_OPTION2], m_nPotentialVotes ); } - bool bVotePassed = false; - - if ( GetNumVotesCast() >= ( m_nPotentialVotes * m_potentialIssues[m_iActiveIssueIndex]->GetQuorumRatio() ) ) + // Have we exceeded the required ratio of Voted-vs-Abstained? + if ( nVoteTally >= m_nPotentialVotes * sv_vote_quorum_ratio.GetFloat() ) { - int nPassingVoteOptionIndex = GetVoteIssueIndexWithHighestCount(); - if ( nPassingVoteOptionIndex >= 0 && nPassingVoteOptionIndex < MAX_VOTE_OPTIONS ) + int nWinningVoteOption = GetWinningVoteOption(); + Assert( nWinningVoteOption >= 0 && nWinningVoteOption < m_VoteOptions.Count() ); + + if ( nWinningVoteOption >= 0 && nWinningVoteOption < MAX_VOTE_OPTIONS ) { - // YES/NO VOTES - hard-wired to VOTE_OPTION1 (Yes) + // YES/NO VOTES if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ) { - if ( nPassingVoteOptionIndex == VOTE_OPTION1 ) + // Option1 is Yes + if ( nWinningVoteOption != VOTE_OPTION1 ) { - bVotePassed = true; - } + SendVoteFailedMessage( VOTE_FAILED_YES_MUST_EXCEED_NO ); + bVotePassed = false; + } } - // GENERAL VOTES - as long as there's a quorum, go with the most popular choice - else + // GENERAL VOTES: + // We set the details string after the vote, since that's when + // we finally have a parameter to pass along and execute + else if ( nWinningVoteOption < m_VoteOptions.Count() ) { - bVotePassed = true; - - // We set the details string after the vote, since that's when - // we finally have a parameter to pass along and execute - m_potentialIssues[m_iActiveIssueIndex]->SetIssueDetails( m_VoteOptions[nPassingVoteOptionIndex] ); + m_potentialIssues[m_iActiveIssueIndex]->SetIssueDetails( m_VoteOptions[nWinningVoteOption] ); } } } - - if ( bVotePassed ) + else { - // Always NULL check, as some votes don't target players (i.e. ChangeLevel) - CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget; + SendVoteFailedMessage( VOTE_FAILED_QUORUM_FAILURE ); + bVotePassed = false; + } - // Don't delay successful kick votes - float flDelay = IsPlayerBeingKicked( pVoteTarget ) ? 0.f : sv_vote_command_delay.GetFloat(); - m_executeCommandTimer.Start( flDelay ); - m_resetVoteTimer.Start( 5.f ); + if ( bVotePassed ) + { + m_executeCommandTimer.Start( sv_vote_command_delay.GetFloat() ); + m_resetVoteTimer.Start( 5.0 ); - UTIL_LogPrintf( "Vote succeeded \"%s %s\"\n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() ); + UTIL_LogPrintf("Vote succeeded \"%s %s\"\n", + m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), + m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() ); CBroadcastRecipientFilter filter; filter.MakeReliable(); @@ -745,10 +616,8 @@ void CVoteController::VoteControllerThink( void ) } else { - vote_create_failed_t nReason = m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ? VOTE_FAILED_YES_MUST_EXCEED_NO : VOTE_FAILED_QUORUM_FAILURE; - SendVoteFailedToPassMessage( nReason ); m_potentialIssues[m_iActiveIssueIndex]->OnVoteFailed( m_iEntityHoldingVote ); - m_resetVoteTimer.Start( 5.f ); + m_resetVoteTimer.Start( 5.0 ); } } @@ -798,15 +667,12 @@ void CVoteController::CheckForEarlyVoteClose( void ) //----------------------------------------------------------------------------- bool CVoteController::IsValidVoter( CBasePlayer *pWhom ) { - if ( !pWhom ) + if ( pWhom == NULL ) return false; if ( !pWhom->IsConnected() ) return false; - if ( pWhom->GetTeamNumber() == TEAM_UNASSIGNED ) - return false; - if ( !sv_vote_allow_spectators.GetBool() ) { if ( pWhom->GetTeamNumber() == TEAM_SPECTATOR ) @@ -851,7 +717,7 @@ void CVoteController::RegisterIssue( CBaseIssue *pszNewIssue ) //----------------------------------------------------------------------------- void CVoteController::ListIssues( CBasePlayer *pForWhom ) { - if ( !IsVoteSystemEnabled() ) + if( !sv_allow_votes.GetBool() ) return; ClientPrint( pForWhom, HUD_PRINTCONSOLE, "---Vote commands---\n" ); @@ -865,34 +731,45 @@ void CVoteController::ListIssues( CBasePlayer *pForWhom ) } //----------------------------------------------------------------------------- -// Purpose: -1 when invalid +// Purpose: //----------------------------------------------------------------------------- -int CVoteController::GetVoteIssueIndexWithHighestCount( void ) +int CVoteController::GetWinningVoteOption( void ) { - int nMaxIndex = -1; - - // Legacy Yes/No system - if ( m_iActiveIssueIndex != INVALID_ISSUE && m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ) + if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ) { return ( m_nVoteOptionCount[VOTE_OPTION1] > m_nVoteOptionCount[VOTE_OPTION2] ) ? VOTE_OPTION1 : VOTE_OPTION2; } - // Which option had the most votes? else { - int nMaxCount = 0; + CUtlVector pVoteCounts; - // TODO: Handle ties + // Which option had the most votes? + // driller: Need to handle ties + int nHighest = m_nVoteOptionCount[0]; for ( int iIndex = 0; iIndex < m_nVoteOptionCount.Count(); iIndex ++ ) { - if ( m_nVoteOptionCount[iIndex] && m_nVoteOptionCount[iIndex] > nMaxCount ) + nHighest = ( ( nHighest < m_nVoteOptionCount[iIndex] ) ? m_nVoteOptionCount[iIndex] : nHighest ); + pVoteCounts.AddToTail( m_nVoteOptionCount[iIndex] ); + } + + m_nHighestCountIndex = -1; + for ( int iIndex = 0; iIndex < m_nVoteOptionCount.Count(); iIndex++ ) + { + if ( m_nVoteOptionCount[iIndex] == nHighest ) { - nMaxCount = m_nVoteOptionCount[iIndex]; - nMaxIndex = iIndex; + m_nHighestCountIndex = iIndex; + // henryg: break on first match, not last. this avoids a crash + // if we are all tied at zero and we pick something beyond the + // last vote option. this code really ought to ignore attempts + // to tally votes for options beyond the last valid one! + break; } } + + return m_nHighestCountIndex; } - return nMaxIndex; + return -1; } //----------------------------------------------------------------------------- @@ -920,12 +797,11 @@ void CVoteController::TrackVoteCaller( CBasePlayer *pPlayer ) //----------------------------------------------------------------------------- // Purpose: Check the history of steamIDs that called votes and test against a timer //----------------------------------------------------------------------------- -bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown, vote_create_failed_t &nErrorCode ) +bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown ) { if ( !pPlayer ) return false; - -#ifndef _DEBUG + CSteamID steamID; pPlayer->GetSteamID( &steamID ); @@ -936,82 +812,25 @@ bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown, v // Timer elapsed? nCooldown = (int)( m_VoteCallers[ iIdx ] - gpGlobals->curtime ); if ( nCooldown > 0 ) - { - nErrorCode = VOTE_FAILED_RATE_EXCEEDED; return false; - } // Expired m_VoteCallers.Remove( iIdx ); } -#endif return true; }; -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CVoteController::GetNumVotesCast( void ) -{ - int nVoteTally = 0; - - for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) - { - nVoteTally += m_nVoteOptionCount.Get( index ); - } - - return nVoteTally; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CVoteController::AddPlayerToKickWatchList( CSteamID steamID, float flDuration ) -{ - VoteControllerSystem.AddPlayerToKickWatchList( steamID, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CVoteController::AddPlayerToNameLockedList( CSteamID steamID, float flDuration, int nUserID ) -{ - engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", nUserID, 1 ) ); - - VoteControllerSystem.AddPlayerToNameLockedList( steamID, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CVoteController::IsPlayerBeingKicked( CBasePlayer *pPlayer ) -{ -#ifdef TF_DLL - if ( pPlayer && m_iActiveIssueIndex != INVALID_ISSUE ) - { - CKickIssue *pKickIssue = dynamic_cast< CKickIssue* >( m_potentialIssues[m_iActiveIssueIndex] ); - if ( pKickIssue ) - { - return pKickIssue->m_hPlayerTarget == pPlayer; - } - } -#endif // TF_DLL - - return false; -} - //----------------------------------------------------------------------------- // Purpose: BaseIssue //----------------------------------------------------------------------------- CBaseIssue::CBaseIssue( const char *pszTypeString ) { - V_strcpy_safe( m_szTypeString, pszTypeString ); + Q_strcpy( m_szTypeString, pszTypeString ); m_iNumYesVotes = 0; m_iNumNoVotes = 0; m_iNumPotentialVotes = 0; - m_flNextCallTime = -1.f; ASSERT( g_voteController ); g_voteController->RegisterIssue( this ); @@ -1050,13 +869,13 @@ const char *CBaseIssue::GetDetailsString( void ) //----------------------------------------------------------------------------- void CBaseIssue::SetIssueDetails( const char *pszDetails ) { - V_strcpy_safe( m_szDetailsString, pszDetails ); + Q_strcpy( m_szDetailsString, pszDetails ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CBaseIssue::IsTeamRestrictedVote( void ) +bool CBaseIssue::IsAllyRestrictedVote( void ) { return false; } @@ -1101,7 +920,7 @@ void CBaseIssue::OnVoteFailed( int iEntityHoldingVote ) // Need to create a new one FailedVote *pNewFailedVote = new FailedVote; int iIndex = m_FailedVotes.AddToTail( pNewFailedVote ); - V_strcpy_safe( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() ); + Q_strcpy( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() ); m_FailedVotes[iIndex]->flLockoutTime = gpGlobals->curtime + sv_vote_failure_timer.GetFloat(); } } @@ -1124,17 +943,8 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create return true; // Bogus player - if ( iEntIndex == -1 ) - return false; - - // Note: Issue timers reset on level change because the class is created/destroyed during transitions. - // It'd be nice to refactor the basic framework of the system to get rid of side-effects like this. - if ( m_flNextCallTime != -1.f && gpGlobals->curtime < m_flNextCallTime ) - { - nFailCode = VOTE_FAILED_ON_COOLDOWN; - nTime = m_flNextCallTime - gpGlobals->curtime; + if( iEntIndex == -1 ) return false; - } #ifdef TF_DLL if ( TFGameRules() && TFGameRules()->IsInWaitingForPlayers() && !TFGameRules()->IsInTournamentMode() ) @@ -1145,14 +955,14 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create #endif // TF_DLL CBaseEntity *pVoteCaller = UTIL_EntityByIndex( iEntIndex ); - if ( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) ) + if( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) ) { nFailCode = VOTE_FAILED_TEAM_CANT_CALL; return false; } // Did this fail recently? - for ( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ ) + for( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ ) { FailedVote *pCurrentFailure = m_FailedVotes[iIndex]; int nTimeRemaining = pCurrentFailure->flLockoutTime - gpGlobals->curtime; @@ -1178,7 +988,7 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create if ( bFailed ) { - nFailCode = VOTE_FAILED_ON_COOLDOWN; + nFailCode = VOTE_FAILED_FAILED_RECENTLY; nTime = nTimeRemaining; return false; } @@ -1256,11 +1066,35 @@ bool CBaseIssue::GetVoteOptions( CUtlVector &vecNames ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: Game system to detect maps without cameras in them, and move on //----------------------------------------------------------------------------- -float CBaseIssue::GetQuorumRatio( void ) +class CVoteControllerSystem : public CAutoGameSystemPerFrame { - return sv_vote_quorum_ratio.GetFloat(); -} +public: + CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name ) + { + } + virtual void LevelInitPreEntity() + { + } + + virtual void FrameUpdatePostEntityThink( void ) + { + // Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and + // blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after + // you in Physics_RunThinkFunctions() to get grumpy and crash. + if( g_voteController ) + { + // Vote passed - execute the command + if( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() ) + { + g_voteController->m_executeCommandTimer.Invalidate(); + g_voteController->m_potentialIssues[ g_voteController->m_iActiveIssueIndex ]->ExecuteCommand(); + } + } + } +}; + +CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" ); diff --git a/game/server/vote_controller.h b/game/server/vote_controller.h index a3f82ff6..0376d6a6 100644 --- a/game/server/vote_controller.h +++ b/game/server/vote_controller.h @@ -17,21 +17,20 @@ #define MAX_COMMAND_LENGTH 64 #define MAX_CREATE_ERROR_STRING 96 -class CBaseIssue // Base class concept for vote issues (i.e. Kick Player). Created per level-load and destroyed by CVoteController's dtor. +class CBaseIssue // Abstract base class for all things-that-can-be-voted-on. { public: - CBaseIssue( const char *typeString ); - virtual ~CBaseIssue(); + CBaseIssue(const char *typeString); + virtual ~CBaseIssue(); const char *GetTypeString( void ); // Connection between console command and specific type of issue - virtual const char *GetTypeStringLocalized( void ) { return ""; } // When empty, the client uses the classname string and prepends "#Vote_" - virtual const char *GetDetailsString( void ); + virtual const char *GetDetailsString(); virtual void SetIssueDetails( const char *pszDetails ); // We need to know the details part of the con command for later virtual void OnVoteFailed( int iEntityHoldingVote ); // The moment the vote fails, also has some time for feedback before the window goes away virtual void OnVoteStarted( void ) {} // Called as soon as the vote starts virtual bool IsEnabled( void ) { return false; } // Query the issue to see if it's enabled virtual bool CanTeamCallVote( int iTeam ) const; // Can someone on the given team call this vote? virtual bool CanCallVote( int nEntIndex, const char *pszDetails, vote_create_failed_t &nFailCode, int &nTime ); // Can this guy hold a vote on this issue? - virtual bool IsTeamRestrictedVote( void ); // Restrict access and visibility of this vote to a specific team? + virtual bool IsAllyRestrictedVote( void ); // Can only members of the same team vote on this? virtual const char *GetDisplayString( void ) = 0; // The string that will be passed to the client for display virtual void ExecuteCommand( void ) = 0; // Where the magic happens. Do your thing. virtual void ListIssueDetails( CBasePlayer *pForWhom ) = 0; // Someone would like to know all your valid details @@ -42,10 +41,6 @@ class CBaseIssue // Base class concept for vote issues (i.e. Kick Player). Crea virtual void SetYesNoVoteCount( int iNumYesVotes, int iNumNoVotes, int iNumPotentialVotes ); virtual bool GetVoteOptions( CUtlVector &vecNames ); // We use this to generate options for voting virtual bool BRecordVoteFailureEventForEntity( int iVoteCallingEntityIndex ) const { return iVoteCallingEntityIndex != DEDICATED_SERVER; } - void SetIssueCooldownDuration( float flDuration ) { m_flNextCallTime = gpGlobals->curtime + flDuration; } // The issue can not be raised again for this period of time (in seconds) - virtual float GetQuorumRatio( void ); // Each issue can decide the required ratio of voted-vs-abstained - - CHandle< CBasePlayer > m_hPlayerTarget; // If the target of the issue is a player, we should store them here protected: static void ListStandardNoArgCommand( CBasePlayer *forWhom, const char *issueString ); // List a Yes vote command @@ -56,13 +51,14 @@ class CBaseIssue // Base class concept for vote issues (i.e. Kick Player). Crea float flLockoutTime; }; - CUtlVector< FailedVote* > m_FailedVotes; - char m_szTypeString[MAX_COMMAND_LENGTH]; - char m_szDetailsString[MAX_VOTE_DETAILS_LENGTH]; + CUtlVector m_FailedVotes; + + char m_szTypeString[MAX_COMMAND_LENGTH]; + char m_szDetailsString[MAX_VOTE_DETAILS_LENGTH]; + int m_iNumYesVotes; int m_iNumNoVotes; int m_iNumPotentialVotes; - float m_flNextCallTime; }; class CVoteController : public CBaseEntity @@ -89,7 +85,6 @@ class CVoteController : public CBaseEntity virtual void Spawn( void ); virtual int UpdateTransmitState( void ); - virtual bool IsVoteSystemEnabled( void ); bool SetupVote( int iEntIndex ); // This creates a list of issues for the UI bool CreateVote( int iEntIndex, const char *pszTypeString, const char *pszDetailString ); // This is what the UI passes in @@ -98,19 +93,13 @@ class CVoteController : public CBaseEntity void ListIssues( CBasePlayer *pForWhom ); bool IsValidVoter( CBasePlayer *pWhom ); bool CanTeamCastVote( int iTeam ) const; - void SendVoteCreationFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime = -1 ); - void SendVoteFailedToPassMessage( vote_create_failed_t nReason ); + void SendVoteFailedMessage( vote_create_failed_t nReason = VOTE_FAILED_GENERIC, CBasePlayer *pVoteCaller = NULL, int nTime = -1 ); void VoteChoice_Increment( int nVoteChoice ); void VoteChoice_Decrement( int nVoteChoice ); - int GetVoteIssueIndexWithHighestCount( void ); + int GetWinningVoteOption( void ); void TrackVoteCaller( CBasePlayer *pPlayer ); - bool CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown, vote_create_failed_t &nErrorCode ); + bool CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown ); bool IsVoteActive( void ) { return m_iActiveIssueIndex != INVALID_ISSUE; } - int GetNumVotesCast( void ); - - void AddPlayerToKickWatchList( CSteamID steamID, float flDuration ); // Band-aid until we figure out how player's avoid kick votes - void AddPlayerToNameLockedList( CSteamID steamID, float flDuration, int nUserID ); - bool IsPlayerBeingKicked( CBasePlayer *pPlayer ); protected: void ResetData( void ); @@ -127,6 +116,7 @@ class CVoteController : public CBaseEntity CountdownTimer m_resetVoteTimer; // when the current vote will end int m_nVotesCast[MAX_PLAYERS + 1]; // arrays are zero-based and player indices are one-based int m_iEntityHoldingVote; + int m_nHighestCountIndex; CUtlVector m_potentialIssues; CUtlVector m_VoteOptions; diff --git a/game/server/vscript_server.cpp b/game/server/vscript_server.cpp new file mode 100644 index 00000000..40e35f00 --- /dev/null +++ b/game/server/vscript_server.cpp @@ -0,0 +1,874 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "vscript_server.h" +#include "icommandline.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "filesystem.h" +#include "eventqueue.h" +#include "characterset.h" +#include "sceneentity.h" // for exposing scene precache function +#include "gamerules.h" +#include "vscript_server.nut" +#ifdef MAPBASE_VSCRIPT +#include "world.h" +#include "mapbase/vscript_singletons.h" +#endif + +extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); + +// #define VMPROFILE 1 + +#ifdef VMPROFILE + +#define VMPROF_START float debugStartTime = Plat_FloatTime(); +#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 ); + +#else // !VMPROFILE + +#define VMPROF_START +#define VMPROF_SHOW + +#endif // VMPROFILE + + +#ifdef MAPBASE_VSCRIPT +static ScriptHook_t g_Hook_OnEntityCreated; +static ScriptHook_t g_Hook_OnEntitySpawned; +static ScriptHook_t g_Hook_OnEntityDeleted; +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CScriptEntityIterator : public IEntityListener +{ +public: +#ifdef MAPBASE_VSCRIPT + HSCRIPT GetLocalPlayer() + { + return ToHScript( UTIL_GetLocalPlayerOrListenServerHost() ); + } +#endif + HSCRIPT First() { return Next(NULL); } + + HSCRIPT Next( HSCRIPT hStartEntity ) + { + return ToHScript( gEntList.NextEnt( ToEnt( hStartEntity ) ) ); + } + + HSCRIPT CreateByClassname( const char *className ) + { + return ToHScript( CreateEntityByName( className ) ); + } + + HSCRIPT FindByClassname( HSCRIPT hStartEntity, const char *szName ) + { + return ToHScript( gEntList.FindEntityByClassname( ToEnt( hStartEntity ), szName ) ); + } + + HSCRIPT FindByName( HSCRIPT hStartEntity, const char *szName ) + { + return ToHScript( gEntList.FindEntityByName( ToEnt( hStartEntity ), szName ) ); + } + + HSCRIPT FindInSphere( HSCRIPT hStartEntity, const Vector &vecCenter, float flRadius ) + { + return ToHScript( gEntList.FindEntityInSphere( ToEnt( hStartEntity ), vecCenter, flRadius ) ); + } + + HSCRIPT FindByTarget( HSCRIPT hStartEntity, const char *szName ) + { + return ToHScript( gEntList.FindEntityByTarget( ToEnt( hStartEntity ), szName ) ); + } + + HSCRIPT FindByModel( HSCRIPT hStartEntity, const char *szModelName ) + { + return ToHScript( gEntList.FindEntityByModel( ToEnt( hStartEntity ), szModelName ) ); + } + + HSCRIPT FindByNameNearest( const char *szName, const Vector &vecSrc, float flRadius ) + { + return ToHScript( gEntList.FindEntityByNameNearest( szName, vecSrc, flRadius ) ); + } + + HSCRIPT FindByNameWithin( HSCRIPT hStartEntity, const char *szName, const Vector &vecSrc, float flRadius ) + { + return ToHScript( gEntList.FindEntityByNameWithin( ToEnt( hStartEntity ), szName, vecSrc, flRadius ) ); + } + + HSCRIPT FindByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ) + { + return ToHScript( gEntList.FindEntityByClassnameNearest( szName, vecSrc, flRadius ) ); + } + + HSCRIPT FindByClassnameWithin( HSCRIPT hStartEntity , const char *szName, const Vector &vecSrc, float flRadius ) + { + return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecSrc, flRadius ) ); + } +#ifdef MAPBASE_VSCRIPT + HSCRIPT FindByClassnameWithinBox( HSCRIPT hStartEntity , const char *szName, const Vector &vecMins, const Vector &vecMaxs ) + { + return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecMins, vecMaxs ) ); + } + + HSCRIPT FindByClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, const char *classname ) + { + return ToHScript( gEntList.FindEntityClassNearestFacing( origin, facing, threshold, const_cast(classname) ) ); + } + + HSCRIPT FindByClassnameNearest2D( const char *szName, const Vector &vecSrc, float flRadius ) + { + return ToHScript( gEntList.FindEntityByClassnameNearest2D( szName, vecSrc, flRadius ) ); + } + + // + // Custom Procedurals + // + void AddCustomProcedural( const char *pszName, HSCRIPT hFunc, bool bCanReturnMultiple ) + { + gEntList.AddCustomProcedural( pszName, hFunc, bCanReturnMultiple ); + } + + void RemoveCustomProcedural( const char *pszName ) + { + gEntList.RemoveCustomProcedural( pszName ); + } + + void EnableEntityListening() + { + // Start getting entity updates! + gEntList.AddListenerEntity( this ); + } + + void DisableEntityListening() + { + // Stop getting entity updates! + gEntList.RemoveListenerEntity( this ); + } + + void OnEntityCreated( CBaseEntity *pEntity ) + { + if ( g_pScriptVM && GetScriptHookManager().IsEventHooked( "OnEntityCreated" ) ) + { + // entity + ScriptVariant_t args[] = { ScriptVariant_t( pEntity->GetScriptInstance() ) }; + g_Hook_OnEntityCreated.Call( NULL, NULL, args ); + } + }; + + void OnEntitySpawned( CBaseEntity *pEntity ) + { + if ( g_pScriptVM && GetScriptHookManager().IsEventHooked( "OnEntitySpawned" ) ) + { + // entity + ScriptVariant_t args[] = { ScriptVariant_t( pEntity->GetScriptInstance() ) }; + g_Hook_OnEntitySpawned.Call( NULL, NULL, args ); + } + }; + + void OnEntityDeleted( CBaseEntity *pEntity ) + { + if ( g_pScriptVM && GetScriptHookManager().IsEventHooked( "OnEntityDeleted" ) ) + { + // entity + ScriptVariant_t args[] = { ScriptVariant_t( pEntity->GetScriptInstance() ) }; + g_Hook_OnEntityDeleted.Call( NULL, NULL, args ); + } + }; +#endif +private: +} g_ScriptEntityIterator; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( GetLocalPlayer, "Get local player or listen server host" ) +#endif + DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" ) + DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" ) + DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" ) + DEFINE_SCRIPTFUNC( FindByClassname, "Find entities by class name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByName, "Find entities by name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindInSphere, "Find entities within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByTarget, "Find entities by targetname. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByModel, "Find entities by model name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByNameNearest, "Find entities by name nearest to a point." ) + DEFINE_SCRIPTFUNC( FindByNameWithin, "Find entities by name within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByClassnameNearest, "Find entities by class name nearest to a point." ) + DEFINE_SCRIPTFUNC( FindByClassnameWithin, "Find entities by class name within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( FindByClassnameWithinBox, "Find entities by class name within an AABB. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" ) + DEFINE_SCRIPTFUNC( FindByClassNearestFacing, "Find the nearest entity along the facing direction from the given origin within the angular threshold with the given classname." ) + DEFINE_SCRIPTFUNC( FindByClassnameNearest2D, "Find entities by class name nearest to a point in 2D space." ) + + DEFINE_SCRIPTFUNC( AddCustomProcedural, "Adds a custom '!' target name. The first parameter is the name of the procedural (which should NOT include the '!'), the second parameter is a function which should support 5 arguments (name, startEntity, searchingEntity, activator, caller), and the third parameter is whether or not this procedural can return multiple entities. Note that these are NOT saved and must be redeclared on restore!" ) + DEFINE_SCRIPTFUNC( RemoveCustomProcedural, "Removes a custom '!' target name previously defined with AddCustomProcedural." ) + + DEFINE_SCRIPTFUNC( EnableEntityListening, "Enables the 'OnEntity' hooks. This function must be called before using them." ) + DEFINE_SCRIPTFUNC( DisableEntityListening, "Disables the 'OnEntity' hooks." ) + + BEGIN_SCRIPTHOOK( g_Hook_OnEntityCreated, "OnEntityCreated", FIELD_VOID, "Called when an entity is created. Requires EnableEntityListening() to be fired beforehand." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_OnEntitySpawned, "OnEntitySpawned", FIELD_VOID, "Called when an entity spawns. Requires EnableEntityListening() to be fired beforehand." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_OnEntityDeleted, "OnEntityDeleted", FIELD_VOID, "Called when an entity is deleted. Requires EnableEntityListening() to be fired beforehand." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + END_SCRIPTHOOK() +#endif +END_SCRIPTDESC(); + +#ifndef MAPBASE_VSCRIPT // Mapbase adds this to the base library so that CScriptKeyValues can be accessed anywhere, like VBSP. +// ---------------------------------------------------------------------------- +// KeyValues access - CBaseEntity::ScriptGetKeyFromModel returns root KeyValues +// ---------------------------------------------------------------------------- + +BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance" ) + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPTFUNC_NAMED( ScriptFindKey, "FindKey", "Given a KeyValues object and a key name, find a KeyValues object associated with the key name" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFirstSubKey, "GetFirstSubKey", "Given a KeyValues object, return the first sub key object" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNextKey, "GetNextKey", "Given a KeyValues object, return the next key object in a sub key group" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueInt, "GetKeyInt", "Given a KeyValues object and a key name, return associated integer value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueFloat, "GetKeyFloat", "Given a KeyValues object and a key name, return associated float value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBool, "GetKeyBool", "Given a KeyValues object and a key name, return associated bool value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueString, "GetKeyString", "Given a KeyValues object and a key name, return associated string value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptIsKeyValueEmpty, "IsKeyEmpty", "Given a KeyValues object and a key name, return true if key name has no value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", "Given a root KeyValues object, release its contents" ); +END_SCRIPTDESC(); + +HSCRIPT CScriptKeyValues::ScriptFindKey( const char *pszName ) +{ + KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +HSCRIPT CScriptKeyValues::ScriptGetFirstSubKey( void ) +{ + KeyValues *pKeyValues = m_pKeyValues->GetFirstSubKey(); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +HSCRIPT CScriptKeyValues::ScriptGetNextKey( void ) +{ + KeyValues *pKeyValues = m_pKeyValues->GetNextKey(); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +int CScriptKeyValues::ScriptGetKeyValueInt( const char *pszName ) +{ + int i = m_pKeyValues->GetInt( pszName ); + return i; +} + +float CScriptKeyValues::ScriptGetKeyValueFloat( const char *pszName ) +{ + float f = m_pKeyValues->GetFloat( pszName ); + return f; +} + +const char *CScriptKeyValues::ScriptGetKeyValueString( const char *pszName ) +{ + const char *psz = m_pKeyValues->GetString( pszName ); + return psz; +} + +bool CScriptKeyValues::ScriptIsKeyValueEmpty( const char *pszName ) +{ + bool b = m_pKeyValues->IsEmpty( pszName ); + return b; +} + +bool CScriptKeyValues::ScriptGetKeyValueBool( const char *pszName ) +{ + bool b = m_pKeyValues->GetBool( pszName ); + return b; +} + +void CScriptKeyValues::ScriptReleaseKeyValues( ) +{ + m_pKeyValues->deleteThis(); + m_pKeyValues = NULL; +} + + +// constructors +CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL ) +{ + m_pKeyValues = pKeyValues; +} + +// destructor +CScriptKeyValues::~CScriptKeyValues( ) +{ + if (m_pKeyValues) + { + m_pKeyValues->deleteThis(); + } + m_pKeyValues = NULL; +} +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +static float Time() +{ + return gpGlobals->curtime; +} + +static float FrameTime() +{ + return gpGlobals->frametime; +} + +#ifdef MAPBASE_VSCRIPT +static int MaxPlayers() +{ + return gpGlobals->maxClients; +} + +static int GetLoadType() +{ + return gpGlobals->eLoadType; +} +#endif + +static void SendToConsole( const char *pszCommand ) +{ + CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); + if ( !pPlayer ) + { +#ifdef MAPBASE + CGMsg( 1, CON_GROUP_VSCRIPT, "Cannot execute \"%s\", no player\n", pszCommand ); +#else + DevMsg ("Cannot execute \"%s\", no player\n", pszCommand ); +#endif + return; + } + + engine->ClientCommand( pPlayer->edict(), pszCommand ); +} + +static void SendToConsoleServer( const char *pszCommand ) +{ + // TODO: whitelist for multiplayer + engine->ServerCommand( UTIL_VarArgs("%s\n", pszCommand) ); +} + +static const char *GetMapName() +{ + return STRING( gpGlobals->mapname ); +} + +static const char *DoUniqueString( const char *pszBase ) +{ + static char szBuf[512]; + g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) ); + return szBuf; +} + +#ifdef MAPBASE_VSCRIPT +static int DoEntFire( const char *pszTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller ) +#else +static void DoEntFire( const char *pszTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller ) +#endif +{ + const char *target = "", *action = "Use"; + variant_t value; + + target = STRING( AllocPooledString( pszTarget ) ); + + // Don't allow them to run anything on a point_servercommand unless they're the host player. Otherwise they can ent_fire + // and run any command on the server. Admittedly, they can only do the ent_fire if sv_cheats is on, but + // people complained about users resetting the rcon password if the server briefly turned on cheats like this: + // give point_servercommand + // ent_fire point_servercommand command "rcon_password mynewpassword" + if ( gpGlobals->maxClients > 1 && V_stricmp( target, "point_servercommand" ) == 0 ) + { +#ifdef MAPBASE_VSCRIPT + return 0; +#else + return; +#endif + } + + if ( *pszAction ) + { + action = STRING( AllocPooledString( pszAction ) ); + } + if ( *pszValue ) + { + value.SetString( AllocPooledString( pszValue ) ); + } + if ( delay < 0 ) + { + delay = 0; + } + +#ifdef MAPBASE_VSCRIPT + return +#endif + g_EventQueue.AddEvent( target, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) ); +} + + +bool DoIncludeScript( const char *pszScript, HSCRIPT hScope ) +{ + if ( !VScriptRunScript( pszScript, hScope, true ) ) + { + g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) ); + return false; + } + return true; +} + +HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char *pszModelName, int iAnim ) +{ + CBaseAnimating *pBaseEntity = (CBaseAnimating *)CreateEntityByName( pszEntityName ); + pBaseEntity->SetAbsOrigin( vOrigin ); + pBaseEntity->SetModel( pszModelName ); + pBaseEntity->SetPlaybackRate( 1.0f ); + + int iSequence = pBaseEntity->SelectWeightedSequence( (Activity)iAnim ); + + if ( iSequence != -1 ) + { + pBaseEntity->SetSequence( iSequence ); + } + + return ToHScript( pBaseEntity ); +} + +//-------------------------------------------------------------------------------------------------- +// Use an entity's script instance to add an entity IO event (used for firing events on unnamed entities from vscript) +//-------------------------------------------------------------------------------------------------- +#ifdef MAPBASE_VSCRIPT +static int DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller ) +#else +static void DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller ) +#endif +{ + const char *action = "Use"; + variant_t value; + + if ( *pszAction ) + { + action = STRING( AllocPooledString( pszAction ) ); + } + if ( *pszValue ) + { + value.SetString( AllocPooledString( pszValue ) ); + } + if ( delay < 0 ) + { + delay = 0; + } + + CBaseEntity* pTarget = ToEnt(hTarget); + + if ( !pTarget ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "VScript error: DoEntFire was passed an invalid entity instance.\n" ); +#ifdef MAPBASE_VSCRIPT + return 0; +#else + return; +#endif + } + +#ifdef MAPBASE_VSCRIPT + return +#endif + g_EventQueue.AddEvent( pTarget, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) ); +} + +static float ScriptTraceLine( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore ) +{ + // UTIL_TraceLine( vecAbsStart, vecAbsEnd, MASK_BLOCKLOS, pLooker, COLLISION_GROUP_NONE, ptr ); + trace_t tr; + CBaseEntity *pLooker = ToEnt(entIgnore); + UTIL_TraceLine( vecStart, vecEnd, MASK_NPCWORLDSTATIC, pLooker, COLLISION_GROUP_NONE, &tr); + if (tr.fractionleftsolid && tr.startsolid) + { + return 1.0 - tr.fractionleftsolid; + } + else + { + return tr.fraction; + } +} + +#ifdef MAPBASE_VSCRIPT +static bool CancelEntityIOEvent( int event ) +{ + return g_EventQueue.RemoveEvent(event); +} + +static float GetEntityIOEventTimeLeft( int event ) +{ + return g_EventQueue.GetTimeLeft(event); +} +#endif // MAPBASE_VSCRIPT + +bool VScriptServerInit() +{ + VMPROF_START + + if( scriptmanager != NULL ) + { + ScriptLanguage_t scriptLanguage = SL_DEFAULT; + + char const *pszScriptLanguage; +#ifdef MAPBASE_VSCRIPT + if (GetWorldEntity()->GetScriptLanguage() != SL_NONE) + { + // Allow world entity to override script language + scriptLanguage = GetWorldEntity()->GetScriptLanguage(); + + // Less than SL_NONE means the script language should literally be none + if (scriptLanguage < SL_NONE) + scriptLanguage = SL_NONE; + } + else +#endif + if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) ) + { + if( !Q_stricmp(pszScriptLanguage, "gamemonkey") ) + { + scriptLanguage = SL_GAMEMONKEY; + } + else if( !Q_stricmp(pszScriptLanguage, "squirrel") ) + { + scriptLanguage = SL_SQUIRREL; + } + else if( !Q_stricmp(pszScriptLanguage, "python") ) + { + scriptLanguage = SL_PYTHON; + } +#ifdef MAPBASE_VSCRIPT + else if( !Q_stricmp(pszScriptLanguage, "lua") ) + { + scriptLanguage = SL_LUA; + } +#endif + else + { + CGWarning( 1, CON_GROUP_VSCRIPT, "-server_script does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage ); + scriptLanguage = SL_NONE; + } + + } + if( scriptLanguage != SL_NONE ) + { + if ( g_pScriptVM == NULL ) + g_pScriptVM = scriptmanager->CreateVM( scriptLanguage ); + + if( g_pScriptVM ) + { +#ifdef MAPBASE_VSCRIPT + CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT SERVER: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#else + Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#endif + +#ifdef MAPBASE_VSCRIPT + GetScriptHookManager().OnInit(); +#endif + +#ifdef MAPBASE_VSCRIPT + // MULTIPLAYER + // ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByIndex, "GetPlayerByIndex", "PlayerInstanceFromIndex" ); + // ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByUserId, "GetPlayerByUserId", "GetPlayerFromUserID" ); + // ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByName, "GetPlayerByName", "" ); + // ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGetPlayerByNetworkID, "GetPlayerByNetworkID", "" ); + + ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" ); +#else + ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" ); +#endif + + ScriptRegisterFunction( g_pScriptVM, SendToConsole, "Send a string to the console as a command" ); + ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map."); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLine, "TraceLine", "given 2 points & ent to ignore, return fraction along line that hits world or models" ); + + ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" ); + ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the server in the last frame" ); +#ifdef MAPBASE_VSCRIPT + ScriptRegisterFunction( g_pScriptVM, SendToConsoleServer, "Send a string to the server console as a command" ); + ScriptRegisterFunction( g_pScriptVM, MaxPlayers, "Get the maximum number of players allowed on this server" ); + ScriptRegisterFunction( g_pScriptVM, GetLoadType, "Get the way the current game was loaded (corresponds to the MapLoad enum)" ); + ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate an entity i/o event" ) ); + ScriptRegisterFunction( g_pScriptVM, DoEntFireByInstanceHandle, SCRIPT_ALIAS( "EntFireByHandle", "Generate an entity i/o event. First parameter is an entity instance." ) ); + // ScriptRegisterFunction( g_pScriptVM, IsValidEntity, "Returns true if the entity is valid." ); + + ScriptRegisterFunction( g_pScriptVM, CancelEntityIOEvent, "Remove entity I/O event." ); + ScriptRegisterFunction( g_pScriptVM, GetEntityIOEventTimeLeft, "Get time left on entity I/O event." ); +#else + ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate and entity i/o event" ) ); + ScriptRegisterFunctionNamed( g_pScriptVM, DoEntFireByInstanceHandle, "EntFireByHandle", "Generate and entity i/o event. First parameter is an entity instance." ); +#endif + ScriptRegisterFunction( g_pScriptVM, DoUniqueString, SCRIPT_ALIAS( "UniqueString", "Generate a string guaranteed to be unique across the life of the script VM, with an optional root string. Useful for adding data to tables when not sure what keys are already in use in that table." ) ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateSceneEntity, "CreateSceneEntity", "Create a scene entity to play the specified scene." ); +#ifndef MAPBASE_VSCRIPT + ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Box, "DebugDrawBox", "Draw a debug overlay box" ); + ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Line, "DebugDrawLine", "Draw a debug overlay box" ); +#endif + ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" ); + ScriptRegisterFunction( g_pScriptVM, CreateProp, "Create a physics prop" ); + + if ( GameRules() ) + { + GameRules()->RegisterScriptFunctions(); + } + + g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" ); + + +#ifdef MAPBASE_VSCRIPT + g_pScriptVM->RegisterAllClasses(); + g_pScriptVM->RegisterAllEnums(); + + IGameSystem::RegisterVScriptAllSystems(); + + RegisterSharedScriptConstants(); + RegisterSharedScriptFunctions(); +#endif + + if (scriptLanguage == SL_SQUIRREL) + { + g_pScriptVM->Run( g_Script_vscript_server ); + } + + VScriptRunScript( "vscript_server", true ); + VScriptRunScript( "mapspawn", false ); + +#ifdef MAPBASE_VSCRIPT + RunAddonScripts(); + + // Since the world entity spawns before VScript is initted, RunVScripts() is called before the VM has started, so no scripts are run. + // This gets around that by calling the same function right after the VM is initted. + GetWorldEntity()->RunVScripts(); +#endif + + VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" ); + + return true; + } + else + { + CGWarning( 1, CON_GROUP_VSCRIPT, "VM Did not start!\n" ); + } + } +#ifdef MAPBASE_VSCRIPT + else + { + CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT SERVER: Not starting because language is set to 'none'\n" ); + } +#endif + } + else + { + CGMsg( 0, CON_GROUP_VSCRIPT, "\nVSCRIPT: Scripting is disabled.\n" ); + } + g_pScriptVM = NULL; + return false; +} + +void VScriptServerTerm() +{ + if( g_pScriptVM != NULL ) + { + if( g_pScriptVM ) + { + scriptmanager->DestroyVM( g_pScriptVM ); + g_pScriptVM = NULL; + } + } +} + + +bool VScriptServerReplaceClosures( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing ) +{ + if ( !g_pScriptVM ) + { + return false; + } + + HSCRIPT hReplaceClosuresFunc = g_pScriptVM->LookupFunction( "__ReplaceClosures" ); + if ( !hReplaceClosuresFunc ) + { + return false; + } + HSCRIPT hNewScript = VScriptCompileScript( pszScriptName, bWarnMissing ); + if ( !hNewScript ) + { + return false; + } + + g_pScriptVM->Call( hReplaceClosuresFunc, NULL, true, NULL, hNewScript, hScope ); + return true; +} + +CON_COMMAND( script_reload_code, "Execute a vscript file, replacing existing functions with the functions in the run script" ) +{ + if ( !*args[1] ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "No script specified\n" ); + return; + } + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + + VScriptServerReplaceClosures( args[1], NULL, true ); +} + +CON_COMMAND( script_reload_entity_code, "Execute all of this entity's VScripts, replacing existing functions with the functions in the run scripts" ) +{ + extern CBaseEntity *GetNextCommandEntity( CBasePlayer *pPlayer, const char *name, CBaseEntity *ent ); + + const char *pszTarget = ""; + if ( *args[1] ) + { + pszTarget = args[1]; + } + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + + CBasePlayer *pPlayer = UTIL_GetCommandClient(); + if ( !pPlayer ) + return; + + CBaseEntity *pEntity = NULL; + while ( (pEntity = GetNextCommandEntity( pPlayer, pszTarget, pEntity )) != NULL ) + { + if ( pEntity->m_ScriptScope.IsInitialized() && pEntity->m_iszVScripts != NULL_STRING ) + { + char szScriptsList[255]; + Q_strcpy( szScriptsList, STRING(pEntity->m_iszVScripts) ); + CUtlStringList szScripts; + V_SplitString( szScriptsList, " ", szScripts); + + for( int i = 0 ; i < szScripts.Count() ; i++ ) + { + VScriptServerReplaceClosures( szScripts[i], pEntity->m_ScriptScope, true ); + } + } + } +} + +CON_COMMAND( script_reload_think, "Execute an activation script, replacing existing functions with the functions in the run script" ) +{ + extern CBaseEntity *GetNextCommandEntity( CBasePlayer *pPlayer, const char *name, CBaseEntity *ent ); + + const char *pszTarget = ""; + if ( *args[1] ) + { + pszTarget = args[1]; + } + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + + CBasePlayer *pPlayer = UTIL_GetCommandClient(); + if ( !pPlayer ) + return; + + CBaseEntity *pEntity = NULL; + while ( (pEntity = GetNextCommandEntity( pPlayer, pszTarget, pEntity )) != NULL ) + { + if ( pEntity->m_ScriptScope.IsInitialized() && pEntity->m_iszScriptThinkFunction != NULL_STRING ) + { + VScriptServerReplaceClosures( STRING(pEntity->m_iszScriptThinkFunction), pEntity->m_ScriptScope, true ); + } + } +} + +class CVScriptGameSystem : public CAutoGameSystemPerFrame +{ +public: + // Inherited from IAutoServerSystem + virtual void LevelInitPreEntity( void ) + { + m_bAllowEntityCreationInScripts = true; + VScriptServerInit(); + } + + virtual void LevelInitPostEntity( void ) + { + m_bAllowEntityCreationInScripts = false; + } + + virtual void LevelShutdownPostEntity( void ) + { +#ifdef MAPBASE_VSCRIPT + g_ScriptNetMsg->LevelShutdownPreVM(); + + GetScriptHookManager().OnShutdown(); +#endif + VScriptServerTerm(); + } + + virtual void FrameUpdatePostEntityThink() + { + if ( g_pScriptVM ) + g_pScriptVM->Frame( gpGlobals->frametime ); + } + + bool m_bAllowEntityCreationInScripts; +}; + +CVScriptGameSystem g_VScriptGameSystem; + +#ifdef MAPBASE_VSCRIPT +ConVar script_allow_entity_creation_midgame( "script_allow_entity_creation_midgame", "1", FCVAR_NOT_CONNECTED, "Allows VScript files to create entities mid-game, as opposed to only creating entities on startup." ); +#endif + +bool IsEntityCreationAllowedInScripts( void ) +{ +#ifdef MAPBASE_VSCRIPT + if (script_allow_entity_creation_midgame.GetBool()) + return true; +#endif + + return g_VScriptGameSystem.m_bAllowEntityCreationInScripts; +} diff --git a/game/server/vscript_server.h b/game/server/vscript_server.h new file mode 100644 index 00000000..2808f3eb --- /dev/null +++ b/game/server/vscript_server.h @@ -0,0 +1,47 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_SERVER_H +#define VSCRIPT_SERVER_H + +#include "vscript/ivscript.h" +#include "tier1/KeyValues.h" +#include "vscript_shared.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +bool VScriptServerReplaceClosures( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing = false ); + +// Only allow scripts to create entities during map initialization +bool IsEntityCreationAllowedInScripts( void ); + +#ifndef MAPBASE_VSCRIPT // Mapbase adds this to the base library so that CScriptKeyValues can be accessed anywhere, like VBSP. +// ---------------------------------------------------------------------------- +// KeyValues access +// ---------------------------------------------------------------------------- +class CScriptKeyValues +{ +public: + CScriptKeyValues( KeyValues *pKeyValues ); + ~CScriptKeyValues( ); + + HSCRIPT ScriptFindKey( const char *pszName ); + HSCRIPT ScriptGetFirstSubKey( void ); + HSCRIPT ScriptGetNextKey( void ); + int ScriptGetKeyValueInt( const char *pszName ); + float ScriptGetKeyValueFloat( const char *pszName ); + const char *ScriptGetKeyValueString( const char *pszName ); + bool ScriptIsKeyValueEmpty( const char *pszName ); + bool ScriptGetKeyValueBool( const char *pszName ); + void ScriptReleaseKeyValues( ); + + KeyValues *m_pKeyValues; // actual KeyValue entity +}; +#endif + +#endif // VSCRIPT_SERVER_H diff --git a/game/server/vscript_server.nut b/game/server/vscript_server.nut new file mode 100644 index 00000000..ad48da19 --- /dev/null +++ b/game/server/vscript_server.nut @@ -0,0 +1,183 @@ +static char g_Script_vscript_server[] = R"vscript( +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +local DoEntFire = DoEntFire +local DoEntFireByInstanceHandle = DoEntFireByInstanceHandle +local DoDispatchParticleEffect = DoDispatchParticleEffect +local DoUniqueString = DoUniqueString + +function UniqueString( string = "" ) +{ + return DoUniqueString( "" + string ); +} + +function EntFire( target, action, value = null, delay = 0.0, activator = null, caller = null ) +{ + if ( !value ) + { + value = ""; + } + + if ( "self" in this ) + { + if ( !caller ) + { + caller = self; + } + + if ( !activator ) + { + activator = self; + } + } + + return DoEntFire( "" + target, "" + action, "" + value, delay, activator, caller ); +} + +function EntFireByHandle( target, action, value = null, delay = 0.0, activator = null, caller = null ) +{ + if ( !value ) + { + value = ""; + } + + if ( "self" in this ) + { + if ( !caller ) + { + caller = self; + } + + if ( !activator ) + { + activator = self; + } + } + + return DoEntFireByInstanceHandle( target, "" + action, "" + value, delay, activator, caller ); +} + +function DispatchParticleEffect( particleName, origin, angles, entity = null ) +{ + return DoDispatchParticleEffect( particleName, origin, angles, entity ); +} + +function ImpulseScale( flTargetMass, flDesiredSpeed ) +{ + return flTargetMass * flDesiredSpeed; +} +__Documentation.RegisterHelp( "ImpulseScale", "float ImpulseScale(float, float)", "Returns an impulse scale required to push an object." ); + +local PrecacheModel = PrecacheModel +function PrecacheModel( a, b = true ) +{ + return PrecacheModel( a, b ) +} + +local PrecacheOther = PrecacheOther +function PrecacheOther( a, b = "" ) +{ + PrecacheOther( a, b ) +} + +function __ReplaceClosures( script, scope ) +{ + if ( !scope ) + { + scope = getroottable(); + } + + local tempParent = { getroottable = function() { return null; } }; + local temp = { runscript = script }; + temp.setdelegate(tempParent); + + temp.runscript() + foreach( key,val in temp ) + { + if ( typeof(val) == "function" && key != "runscript" ) + { + printl( " Replacing " + key ); + scope[key] <- val; + } + } +} + +local __OutputsPattern = regexp("^On.*Output$"); + +function ConnectOutputs( table ) +{ + local nCharsToStrip = 6; + foreach( key, val in table ) + { + if ( typeof( val ) == "function" && __OutputsPattern.match( key ) ) + { + //printl(key.slice( 0, nCharsToStrip ) ); + table.self.ConnectOutput( key.slice( 0, key.len() - nCharsToStrip ), key ); + } + } +} + +function IncludeScript( name, scope = null ) +{ + if ( !scope ) + { + scope = this; + } + return ::DoIncludeScript( name, scope ); +} + +//--------------------------------------------------------- +// Text dump this scope's contents to the console. +//--------------------------------------------------------- +function __DumpScope( depth, table ) +{ + local indent=function( count ) + { + local i; + for( i = 0 ; i < count ; i++ ) + { + print(" "); + } + } + + foreach(key, value in table) + { + indent(depth); + print( key ); + switch (type(value)) + { + case "table": + print("(TABLE)\n"); + indent(depth); + print("{\n"); + __DumpScope( depth + 1, value); + indent(depth); + print("}"); + break; + case "array": + print("(ARRAY)\n"); + indent(depth); + print("[\n") + __DumpScope( depth + 1, value); + indent(depth); + print("]"); + break; + case "string": + print(" = \""); + print(value); + print("\""); + break; + default: + print(" = "); + print(value); + break; + } + print("\n"); + } +} + +)vscript"; \ No newline at end of file diff --git a/game/server/wcedit.cpp b/game/server/wcedit.cpp index 43307dfc..5a454e6b 100644 --- a/game/server/wcedit.cpp +++ b/game/server/wcedit.cpp @@ -450,6 +450,19 @@ Vector *g_EntityPositions = NULL; QAngle *g_EntityOrientations = NULL; string_t *g_EntityClassnames = NULL; +#ifdef MAPBASE // VDC Memory Leak Fixes +class GlobalCleanUp : public CAutoGameSystem +{ + void Shutdown() + { + delete [] g_EntityPositions; + delete [] g_EntityOrientations; + delete [] g_EntityClassnames; + delete this; + } +}; +#endif + //----------------------------------------------------------------------------- // Purpose: Saves the entity's position for future communication with Hammer //----------------------------------------------------------------------------- @@ -460,6 +473,9 @@ void NWCEdit::RememberEntityPosition( CBaseEntity *pEntity ) if ( !g_EntityPositions ) { +#ifdef MAPBASE // VDC Memory Leak Fixes + new GlobalCleanUp(); +#endif g_EntityPositions = new Vector[NUM_ENT_ENTRIES]; g_EntityOrientations = new QAngle[NUM_ENT_ENTRIES]; // have to save these too because some entities change the classname on spawn (e.g. prop_physics_override, physics_prop) diff --git a/game/server/weapon_lmg.cpp b/game/server/weapon_lmg.cpp deleted file mode 100644 index addad55b..00000000 --- a/game/server/weapon_lmg.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "cbase.h" -#include "vance_baseweapon_shared.h" -#include "basecombatweapon.h" -#include "basecombatcharacter.h" -#include "ai_basenpc.h" -#include "player.h" -#include "soundent.h" -#include "game.h" - -class CWeaponLMG : public CVanceMachineGun -{ - DECLARE_CLASS( CWeaponLMG, CVanceMachineGun ); - DECLARE_SERVERCLASS(); -public: - -}; \ No newline at end of file diff --git a/game/server/world.cpp b/game/server/world.cpp index 55c1e7b5..fc3d59ae 100644 --- a/game/server/world.cpp +++ b/game/server/world.cpp @@ -376,6 +376,9 @@ BEGIN_DATADESC( CWorld ) // keyvalues are parsed from map, but not saved/loaded DEFINE_KEYFIELD( m_iszChapterTitle, FIELD_STRING, "chaptertitle" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bChapterTitleNoMessage, FIELD_BOOLEAN, "chaptertitlenomessage" ), +#endif DEFINE_KEYFIELD( m_bStartDark, FIELD_BOOLEAN, "startdark" ), DEFINE_KEYFIELD( m_bDisplayTitle, FIELD_BOOLEAN, "gametitle" ), DEFINE_FIELD( m_WorldMins, FIELD_VECTOR ), @@ -390,8 +393,16 @@ BEGIN_DATADESC( CWorld ) DEFINE_KEYFIELD( m_flMaxPropScreenSpaceWidth, FIELD_FLOAT, "maxpropscreenwidth" ), DEFINE_KEYFIELD( m_flMinPropScreenSpaceWidth, FIELD_FLOAT, "minpropscreenwidth" ), DEFINE_KEYFIELD( m_iszDetailSpriteMaterial, FIELD_STRING, "detailmaterial" ), +#ifdef MAPBASE_VSCRIPT + DEFINE_KEYFIELD( m_iScriptLanguage, FIELD_INTEGER, "vscriptlanguage" ), + //DEFINE_KEYFIELD( m_iScriptLanguageClient, FIELD_INTEGER, "vscriptlanguage_client" ), +#endif DEFINE_KEYFIELD( m_bColdWorld, FIELD_BOOLEAN, "coldworld" ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_STRING, "SetChapterTitle", InputSetChapterTitle ), +#endif + END_DATADESC() @@ -407,6 +418,9 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD) SendPropFloat (SENDINFO(m_flMinPropScreenSpaceWidth), 0, SPROP_NOSCALE ), SendPropStringT (SENDINFO(m_iszDetailSpriteMaterial) ), SendPropInt (SENDINFO(m_bColdWorld), 1, SPROP_UNSIGNED ), +#ifdef MAPBASE + SendPropStringT (SENDINFO(m_iszChapterTitle) ), +#endif END_SEND_TABLE() // @@ -449,7 +463,7 @@ bool CWorld::KeyValue( const char *szKeyName, const char *szValue ) extern bool g_fGameOver; -static CWorld *g_WorldEntity = NULL; +CWorld *g_WorldEntity = NULL; CWorld* GetWorldEntity() { @@ -466,6 +480,11 @@ CWorld::CWorld( ) SetSolid( SOLID_BSP ); SetMoveType( MOVETYPE_NONE ); +#ifdef MAPBASE_VSCRIPT + m_iScriptLanguage = SL_NONE; + //m_iScriptLanguageClient = -2; +#endif + m_bColdWorld = false; } @@ -678,6 +697,23 @@ void CWorld::Precache( void ) // Call all registered precachers. CPrecacheRegister::Precache(); +#ifdef MAPBASE + if ( m_iszChapterTitle.Get() != NULL_STRING && !m_bChapterTitleNoMessage ) + { + DevMsg( 2, "Chapter title: %s\n", STRING(m_iszChapterTitle.Get()) ); + CMessage *pMessage = (CMessage *)CBaseEntity::Create( "env_message", vec3_origin, vec3_angle, NULL ); + if ( pMessage ) + { + pMessage->SetMessage( m_iszChapterTitle.Get() ); + m_iszChapterTitle.Set( NULL_STRING ); + + // send the message entity a play message command, delayed by 1 second + pMessage->AddSpawnFlags( SF_MESSAGE_ONCE ); + pMessage->SetThink( &CMessage::SUB_CallUseToggle ); + pMessage->SetNextThink( gpGlobals->curtime + 1.0f ); + } + } +#else if ( m_iszChapterTitle != NULL_STRING ) { DevMsg( 2, "Chapter title: %s\n", STRING(m_iszChapterTitle) ); @@ -693,6 +729,7 @@ void CWorld::Precache( void ) pMessage->SetNextThink( gpGlobals->curtime + 1.0f ); } } +#endif g_iszFuncBrushClassname = AllocPooledString("func_brush"); } @@ -731,3 +768,10 @@ bool CWorld::IsColdWorld( void ) { return m_bColdWorld; } + +#ifdef MAPBASE +void CWorld::InputSetChapterTitle( inputdata_t &inputdata ) +{ + m_iszChapterTitle.Set( inputdata.value.StringID() ); +} +#endif diff --git a/game/server/world.h b/game/server/world.h index a8547d3c..5d75a64b 100644 --- a/game/server/world.h +++ b/game/server/world.h @@ -52,10 +52,32 @@ class CWorld : public CBaseEntity bool IsColdWorld( void ); +#ifdef MAPBASE + inline const char *GetChapterTitle() + { + return STRING(m_iszChapterTitle.Get()); + } + + void InputSetChapterTitle( inputdata_t &inputdata ); +#endif + +#ifdef MAPBASE_VSCRIPT + ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguage); } +#endif + private: DECLARE_DATADESC(); +#ifdef MAPBASE + // Now needs to show up on the client for RPC + CNetworkVar( string_t, m_iszChapterTitle ); + + // Suppresses m_iszChapterTitle's env_message creation, + // allowing it to only be used for saves and RPC + bool m_bChapterTitleNoMessage; +#else string_t m_iszChapterTitle; +#endif CNetworkVar( float, m_flWaveHeight ); CNetworkVector( m_WorldMins ); @@ -66,6 +88,11 @@ class CWorld : public CBaseEntity CNetworkVar( float, m_flMaxPropScreenSpaceWidth ); CNetworkVar( string_t, m_iszDetailSpriteMaterial ); +#ifdef MAPBASE_VSCRIPT + int m_iScriptLanguage; + //CNetworkVar( int, m_iScriptLanguageClient ); // Now entirely on client +#endif + // start flags CNetworkVar( bool, m_bStartDark ); CNetworkVar( bool, m_bColdWorld ); diff --git a/game/shared/GameEventListener.h b/game/shared/GameEventListener.h index 42d2ebaa..9378257d 100644 --- a/game/shared/GameEventListener.h +++ b/game/shared/GameEventListener.h @@ -25,7 +25,7 @@ class CGameEventListener : public IGameEventListener2 { } - ~CGameEventListener() + virtual ~CGameEventListener() { StopListeningForAllEvents(); } diff --git a/game/shared/GameStats.cpp b/game/shared/GameStats.cpp index 7351647b..695dc553 100644 --- a/game/shared/GameStats.cpp +++ b/game/shared/GameStats.cpp @@ -46,11 +46,6 @@ extern const ConVar *sv_cheats; #endif #endif -#ifdef CLIENT_DLL - // Ensure this is declared in the client dll so everyone finds the same one. - ConVar dev_loadtime_mainmenu("dev_loadtime_mainmenu", "0.0", FCVAR_HIDDEN ); -#endif - // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" @@ -146,7 +141,7 @@ CBaseGameStats_Driver::CBaseGameStats_Driver( void ) : m_bDidVoiceChat( false ) { - m_szLoadedUserID[0] = 0; + m_szLoadedUserID[0] = 0;; m_tLastUpload = 0; m_LastUserCmd.Reset(); } @@ -1066,33 +1061,6 @@ void CBaseGameStats_Driver::SendData() ResetData(); } -#ifdef CLIENT_DLL - // Adds the main menu load time to the specified key values, but only ever does the work once. - static void AddLoadTimeMainMenu( KeyValues* pKV ) - { - Assert( pKV ); - float loadTimeMainMenu = dev_loadtime_mainmenu.GetFloat(); - if ( loadTimeMainMenu > 0.0f ) { - pKV->SetFloat( "LoadTimeMainMenu", loadTimeMainMenu ); - // Only want to set this once, clear it to 0.0 here. The other code will only ever set it once. - dev_loadtime_mainmenu.SetValue( 0.0f ); - } - } - - // Adds the map load time to the specified key values, but clears the elapsed data to 0.0 for next computation. - static void AddLoadTimeMap(KeyValues* pKV) - { - static ConVarRef dev_loadtime_map_elapsed( "dev_loadtime_map_elapsed" ); - float loadTimeMap = dev_loadtime_map_elapsed.GetFloat(); - if ( loadTimeMap > 0.0f ) - { - pKV->SetFloat( "LoadTimeMap", loadTimeMap ); - dev_loadtime_map_elapsed.SetValue( 0.0f ); - } - } - -#endif - bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t sendType ) { switch ( sendType ) @@ -1106,12 +1074,6 @@ bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t s pKVData->SetInt( "TotalLevelTime", m_flTotalTimeInLevels ); pKVData->SetInt( "NumLevels", m_iNumLevels ); pKV->AddSubKey( pKVData ); - - AddLoadTimeMainMenu( pKV ); - // If the user quits directly from the map, we still want to (possibly) capture their map load time, so - // do add it here. It will not be added if it was already attached to a session. - AddLoadTimeMap( pKV ); - return true; } #endif @@ -1179,9 +1141,6 @@ bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t s int mapTime = gpGlobals->realtime - m_flLevelStartTime; pKV->SetInt( "MapTime", mapTime ); - AddLoadTimeMainMenu(pKV); - AddLoadTimeMap(pKV); - return true; } #endif @@ -1218,10 +1177,6 @@ void CBaseGameStats_Driver::ResetData() OverWriteCharsWeHate( cpu.m_szProcessorID ); pKV->SetString( "CPUID", cpu.m_szProcessorID ); pKV->SetFloat( "CPUGhz", cpu.m_Speed * ( 1.0 / 1.0e9 ) ); - pKV->SetUint64( "CPUModel", cpu.m_nModel ); - pKV->SetUint64( "CPUFeatures0", cpu.m_nFeatures[ 0 ] ); - pKV->SetUint64( "CPUFeatures1", cpu.m_nFeatures[ 1 ] ); - pKV->SetUint64( "CPUFeatures2", cpu.m_nFeatures[ 2 ] ); pKV->SetInt( "NumCores", cpu.m_nPhysicalProcessors ); MaterialAdapterInfo_t gpu; @@ -1244,7 +1199,6 @@ void CBaseGameStats_Driver::ResetData() pKV->SetInt( "Height", dest_height ); const MaterialSystem_Config_t &config = materials->GetCurrentConfigForVideoCard(); pKV->SetInt( "Windowed", config.Windowed() == true ); - pKV->SetInt( "MaxDxLevel", g_pMaterialSystemHardwareConfig->GetMaxDXSupportLevel() ); engine->SetGamestatsData( m_pGamestatsData ); #endif diff --git a/game/shared/ModelSoundsCache.cpp b/game/shared/ModelSoundsCache.cpp index 4f4f10fb..e6ad628b 100644 --- a/game/shared/ModelSoundsCache.cpp +++ b/game/shared/ModelSoundsCache.cpp @@ -68,7 +68,7 @@ void CModelSoundsCache::Restore( CUtlBuffer& buf ) { char soundname[ 512 ]; - buf.GetString( soundname ); + buf.GetString( soundname, sizeof( soundname ) ); int idx = soundemitterbase->GetSoundIndex( soundname ); if ( idx != -1 ) diff --git a/game/shared/Multiplayer/multiplayer_animstate.cpp b/game/shared/Multiplayer/multiplayer_animstate.cpp index 2734eba0..4d1ad4fe 100644 --- a/game/shared/Multiplayer/multiplayer_animstate.cpp +++ b/game/shared/Multiplayer/multiplayer_animstate.cpp @@ -91,10 +91,6 @@ CMultiPlayerAnimState::CMultiPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerM m_flMaxGroundSpeed = 0.0f; - // If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between - // teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window, - // and the fact that m_flEyeYaw is never propogated from the server to the client. - // TODO: Fix this after Halloween 2014. m_bForceAimYaw = false; Init( pPlayer, movementData ); @@ -1659,10 +1655,6 @@ void CMultiPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr ) bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false; // If we are moving or are prone and undeployed. - // If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between - // teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window, - // and the fact that m_flEyeYaw is never propogated from the server to the client. - // TODO: Fix this after Halloween 2014. if ( bMoving || m_bForceAimYaw ) { // The feet match the eye direction when moving - the move yaw takes care of the rest. @@ -1696,10 +1688,6 @@ void CMultiPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr ) m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw ); if ( m_flGoalFeetYaw != m_flCurrentFeetYaw ) { - // If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between - // teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window, - // and the fact that m_flEyeYaw is never propogated from the server to the client. - // TODO: Fix this after Halloween 2014. if ( m_bForceAimYaw ) { m_flCurrentFeetYaw = m_flGoalFeetYaw; diff --git a/game/shared/Multiplayer/multiplayer_animstate.h b/game/shared/Multiplayer/multiplayer_animstate.h index ee93fdbf..bbbc837d 100644 --- a/game/shared/Multiplayer/multiplayer_animstate.h +++ b/game/shared/Multiplayer/multiplayer_animstate.h @@ -63,10 +63,6 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_STUN_BEGIN, PLAYERANIMEVENT_STUN_MIDDLE, PLAYERANIMEVENT_STUN_END, - PLAYERANIMEVENT_PASSTIME_THROW_BEGIN, - PLAYERANIMEVENT_PASSTIME_THROW_MIDDLE, - PLAYERANIMEVENT_PASSTIME_THROW_END, - PLAYERANIMEVENT_PASSTIME_THROW_CANCEL, PLAYERANIMEVENT_ATTACK_PRIMARY_SUPER, @@ -207,10 +203,6 @@ class CMultiPlayerAnimState bool VerifyAnimLayerInSlot( int iGestureSlot ); // Feet. - // If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between - // teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window, - // and the fact that m_flEyeYaw is never propogated from the server to the client. - // TODO: Fix this after Halloween 2014. bool m_bForceAimYaw; protected: @@ -297,7 +289,6 @@ class CMultiPlayerAnimState // Pose parameters. bool m_bPoseParameterInit; MultiPlayerPoseData_t m_PoseParameterData; - DebugPlayerAnimData_t m_DebugAnimData; bool m_bCurrentFeetYawInitialized; float m_flLastAnimationStateClearTime; @@ -331,7 +322,6 @@ class CMultiPlayerAnimState // Weapon data. CHandle m_hActiveWeapon; -protected: // Ground speed interpolators. #ifdef CLIENT_DLL @@ -343,6 +333,14 @@ class CMultiPlayerAnimState // movement playback options int m_nMovementSequence; LegAnimType_t m_LegAnimType; + + //Tony; moved debuganim data to a private block and made the 2 sdk animstates friendly. I override the base classes + //but want complete functionality. +private: + friend class CSDKPlayerAnimState; + friend class CHL2MPPlayerAnimState; + DebugPlayerAnimData_t m_DebugAnimData; + }; // If this is set, then the game code needs to make sure to send player animation events diff --git a/game/shared/SceneCache.cpp b/game/shared/SceneCache.cpp index c993ef46..0728c27b 100644 --- a/game/shared/SceneCache.cpp +++ b/game/shared/SceneCache.cpp @@ -59,7 +59,7 @@ void CSceneCache::Restore( CUtlBuffer& buf ) for ( int i = 0; i < c; ++i ) { char soundname[ 512 ]; - buf.GetString( soundname ); + buf.GetString( soundname, sizeof( soundname ) ); int idx = soundemitterbase->GetSoundIndex( soundname ); if ( idx != -1 ) diff --git a/game/shared/SoundEmitterSystem.cpp b/game/shared/SoundEmitterSystem.cpp index 39aca858..6b10c6fe 100644 --- a/game/shared/SoundEmitterSystem.cpp +++ b/game/shared/SoundEmitterSystem.cpp @@ -130,6 +130,25 @@ void Hack_FixEscapeChars( char *str ) Q_strncpy( str, osave, len ); } +#ifdef MAPBASE +static const ConVar *pHostTimescale; +static ConVar host_pitchscale( "host_pitchscale", "-1", FCVAR_REPLICATED, "If greater than 0, controls the pitch scale of sounds instead of host_timescale." ); + +static float GetSoundPitchScale() +{ + static ConVarRef sv_cheats( "sv_cheats" ); + if (sv_cheats.GetBool()) + { + if (host_pitchscale.GetFloat() > 0.0f) + return host_pitchscale.GetFloat(); + else + return pHostTimescale->GetFloat(); + } + + return 1.0f; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -323,6 +342,10 @@ class CSoundEmitterSystem : public CBaseGameSystem } } #endif + +#ifdef MAPBASE + pHostTimescale = cvar->FindVar( "host_timescale" ); +#endif } virtual void LevelInitPostEntity() @@ -337,15 +360,6 @@ class CSoundEmitterSystem : public CBaseGameSystem FinishLog(); #endif } - - void Flush() - { - Assert( soundemitterbase ); -#if !defined( CLIENT_DLL ) - FinishLog(); -#endif - soundemitterbase->Flush(); - } void InternalPrecacheWaves( int soundIndex ) { @@ -474,6 +488,7 @@ class CSoundEmitterSystem : public CBaseGameSystem { return; } +#endif // STAGING_ONLY if ( !Q_strncasecmp( params.soundname, "vo", 2 ) && !( params.channel == CHAN_STREAM || @@ -483,7 +498,6 @@ class CSoundEmitterSystem : public CBaseGameSystem DevMsg( "EmitSound: Voice wave file %s doesn't specify CHAN_VOICE, CHAN_VOICE2 or CHAN_STREAM for sound %s\n", params.soundname, ep.m_pSoundName ); } -#endif // STAGING_ONLY // handle SND_CHANGEPITCH/SND_CHANGEVOL and other sound flags.etc. if( ep.m_nFlags & SND_CHANGE_PITCH ) @@ -534,7 +548,11 @@ class CSoundEmitterSystem : public CBaseGameSystem params.volume, (soundlevel_t)params.soundlevel, ep.m_nFlags, +#ifdef MAPBASE + params.pitch * GetSoundPitchScale(), +#else params.pitch, +#endif ep.m_nSpecialDSP, ep.m_pOrigin, NULL, @@ -613,7 +631,11 @@ class CSoundEmitterSystem : public CBaseGameSystem ep.m_flVolume, ep.m_SoundLevel, ep.m_nFlags, +#ifdef MAPBASE + ep.m_nPitch * GetSoundPitchScale(), +#else ep.m_nPitch, +#endif ep.m_nSpecialDSP, ep.m_pOrigin, NULL, @@ -835,6 +857,10 @@ class CSoundEmitterSystem : public CBaseGameSystem params.volume = flVolume; } +#ifdef MAPBASE + params.pitch *= GetSoundPitchScale(); +#endif + #if defined( CLIENT_DLL ) enginesound->EmitAmbientSound( params.soundname, params.volume, params.pitch, iFlags, soundtime ); #else @@ -963,6 +989,10 @@ class CSoundEmitterSystem : public CBaseGameSystem if ( pSample && ( Q_stristr( pSample, ".wav" ) || Q_stristr( pSample, ".mp3" )) ) { +#ifdef MAPBASE + pitch *= GetSoundPitchScale(); +#endif + #if defined( CLIENT_DLL ) enginesound->EmitAmbientSound( pSample, volume, pitch, flags, soundtime ); #else @@ -1007,7 +1037,10 @@ void S_SoundEmitterSystemFlush( void ) // save the current soundscape // kill the system - g_SoundEmitterSystem.Flush(); + g_SoundEmitterSystem.Shutdown(); + + // restart the system + g_SoundEmitterSystem.Init(); #if !defined( CLIENT_DLL ) // Redo precache all wave files... (this should work now that we have dynamic string tables) @@ -1193,6 +1226,24 @@ void CBaseEntity::EmitSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle, EmitSound( filter, entindex(), params, handle ); } +#if !defined ( CLIENT_DLL ) || defined( MAPBASE_VSCRIPT ) +void CBaseEntity::ScriptEmitSound( const char *soundname ) +{ + EmitSound( soundname ); +} + +void CBaseEntity::ScriptStopSound( const char *soundname ) +{ + StopSound( soundname ); +} + +float CBaseEntity::ScriptSoundDuration( const char *soundname, const char *actormodel ) +{ + float duration = CBaseEntity::GetSoundDuration( soundname, actormodel ); + return duration; +} +#endif // !CLIENT + //----------------------------------------------------------------------------- // Purpose: // Input : filter - @@ -1372,6 +1423,52 @@ int SENTENCEG_Lookup(const char *sample) } #endif +#if defined(MAPBASE) && defined(GAME_DLL) +//----------------------------------------------------------------------------- +// Purpose: Wrapper to emit a sentence and also a close caption token for the sentence as appropriate. +// Input : filter - +// iEntIndex - +// iChannel - +// iSentenceIndex - +// flVolume - +// iSoundlevel - +// iFlags - +// iPitch - +// bUpdatePositions - +// soundtime - +//----------------------------------------------------------------------------- +void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, + float flVolume, soundlevel_t iSoundlevel, int iFlags /*= 0*/, int iPitch /*=PITCH_NORM*/, + const Vector *pOrigin /*=NULL*/, const Vector *pDirection /*=NULL*/, + bool bUpdatePositions /*=true*/, float soundtime /*=0.0f*/, int iSpecialDSP /*= 0*/, int iSpeakerIndex /*= 0*/ ) +{ + CUtlVector< Vector > soundOrigins; + + bool bSwallowed = CEnvMicrophone::OnSentencePlayed( + iEntIndex, + iSentenceIndex, + iSoundlevel, + flVolume, + iFlags, + iPitch, + pOrigin, + soundtime, + soundOrigins ); + if ( bSwallowed ) + return; + + CBaseEntity *pEntity = UTIL_EntityByIndex( iEntIndex ); + if ( pEntity ) + { + pEntity->ModifySentenceParams( iSentenceIndex, iChannel, flVolume, iSoundlevel, iFlags, iPitch, + &pOrigin, &pDirection, bUpdatePositions, soundtime, iSpecialDSP, iSpeakerIndex ); + } + + enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex, + flVolume, iSoundlevel, iFlags, iPitch * GetSoundPitchScale(), iSpecialDSP, pOrigin, pDirection, &soundOrigins, bUpdatePositions, soundtime, iSpeakerIndex ); +} +#endif + void UTIL_EmitAmbientSound( int entindex, const Vector &vecOrigin, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float soundtime /*= 0.0f*/, float *duration /*=NULL*/ ) { #ifdef STAGING_ONLY @@ -1426,7 +1523,17 @@ static const char *UTIL_TranslateSoundName( const char *soundname, const char *a void CBaseEntity::GenderExpandString( char const *in, char *out, int maxlen ) { +#ifdef MAPBASE + // This is so models without globalactors.txt declarations can still play scenes. + gender_t gender = soundemitterbase->GetActorGender(STRING(GetModelName())); + + if (gender == GENDER_NONE) + gender = GENDER_MALE; + + soundemitterbase->GenderExpandString(gender, in, out, maxlen); +#else soundemitterbase->GenderExpandString( STRING( GetModelName() ), in, out, maxlen ); +#endif } bool CBaseEntity::GetParametersForSound( const char *soundname, CSoundParameters ¶ms, const char *actormodel ) @@ -1452,6 +1559,14 @@ HSOUNDSCRIPTHANDLE CBaseEntity::PrecacheScriptSound( const char *soundname ) #endif } +#if !defined ( CLIENT_DLL ) || defined( MAPBASE_VSCRIPT ) +// Same as server version of above, but signiture changed so it can be deduced by the macros +void CBaseEntity::VScriptPrecacheScriptSound(const char* soundname) +{ + g_SoundEmitterSystem.PrecacheScriptSound(soundname); +} +#endif // !CLIENT_DLL + void CBaseEntity::PrefetchScriptSound( const char *soundname ) { g_SoundEmitterSystem.PrefetchScriptSound( soundname ); diff --git a/game/shared/SpriteTrail.h b/game/shared/SpriteTrail.h index 2248dc99..3e4fb763 100644 --- a/game/shared/SpriteTrail.h +++ b/game/shared/SpriteTrail.h @@ -82,8 +82,8 @@ class CSpriteTrail : public CSprite enum { // NOTE: # of points max must be a power of two! - MAX_SPRITE_TRAIL_POINTS = 256, - MAX_SPRITE_TRAIL_MASK = MAX_SPRITE_TRAIL_POINTS - 1, + MAX_SPRITE_TRAIL_POINTS = 64, + MAX_SPRITE_TRAIL_MASK = 0x3F, }; TrailPoint_t *GetTrailPoint( int n ); @@ -114,11 +114,6 @@ class CSpriteTrail : public CSprite string_t m_iszSpriteName; bool m_bAnimate; bool m_bDrawForMoveParent; - -#if defined( CLIENT_DLL ) -public: - void SetUpdateTime(float setTo){ m_flUpdateTime = setTo; } -#endif }; #endif // SPRITETRAIL_H diff --git a/game/shared/achievementmgr.cpp b/game/shared/achievementmgr.cpp index ffc95d46..add1f05d 100644 --- a/game/shared/achievementmgr.cpp +++ b/game/shared/achievementmgr.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //============================================================================= @@ -66,14 +66,6 @@ extern ConVar developer; #define DEBUG_ACHIEVEMENTS_IN_RELEASE 0 -#ifdef SWDS -// Hack this for now until we get steam_api recompiling in the Steam codebase. -ISteamUserStats *SteamUserStats() -{ - return NULL; -} -#endif - //----------------------------------------------------------------------------- // Purpose: Write helper //----------------------------------------------------------------------------- @@ -134,8 +126,8 @@ static void WriteAchievementGlobalState( KeyValues *pKV, bool bPersistToSteamClo if (pRemoteStorage) { - int32 availableBytes = 0; - int32 totalBytes = 0; + uint64 availableBytes = 0; + uint64 totalBytes = 0; if ( pRemoteStorage->GetQuota( &totalBytes, &availableBytes ) ) { if ( totalBytes > 0 ) @@ -189,13 +181,13 @@ static void WriteAchievementGlobalState( KeyValues *pKV, bool bPersistToSteamClo //----------------------------------------------------------------------------- // Purpose: Async save thread //----------------------------------------------------------------------------- -class CAchievementSaveThread : public CWorkerThread +class CAchievementSaveThread : public CWorkerThread { public: CAchievementSaveThread() : m_pKV( NULL ) { - SetName( "AchievementSaveThread" ); + SetName( "AchievementSaveThread" ); } ~CAchievementSaveThread() @@ -300,7 +292,7 @@ m_CallbackUserStatsStored( this, &CAchievementMgr::Steam_OnUserStatsStored ) bool CAchievementMgr::Init() { // We can be created on either client (for multiplayer games) or server - // (for single player), so register ourselves with the engine so UI has a uniform place + // (for single player), so register ourselves with the engine so UI has a uniform place // to go get the pointer to us #ifdef _DEBUG @@ -325,7 +317,7 @@ bool CAchievementMgr::Init() #ifdef TF_CLIENT_DLL ListenForGameEvent( "localplayer_changeclass" ); ListenForGameEvent( "localplayer_changeteam" ); - ListenForGameEvent( "teamplay_round_start" ); + ListenForGameEvent( "teamplay_round_start" ); ListenForGameEvent( "teamplay_round_win" ); #endif // TF_CLIENT_DLL @@ -495,11 +487,11 @@ void CAchievementMgr::LevelInitPreEntity() #ifdef GAME_DLL // For single-player games, achievement mgr must live on the server. (Only the server has detailed knowledge of game state.) - Assert( !GameRules()->IsMultiplayer() ); + Assert( !GameRules()->IsMultiplayer() ); #else // For multiplayer games, achievement mgr must live on the client. (Only the client can read/write player state from Steam/XBox Live.) Assert( GameRules()->IsMultiplayer() ); -#endif +#endif // clear list of achievements listening for events m_vecKillEventListeners.RemoveAll(); @@ -512,9 +504,9 @@ void CAchievementMgr::LevelInitPreEntity() m_flTeamplayStartTime = 0; m_iMiniroundsCompleted = 0; - // client and server have map names available in different forms (full path on client, just file base name on server), + // client and server have map names available in different forms (full path on client, just file base name on server), // cache it in base file name form here so we don't have to have different code paths each time we access it -#ifdef CLIENT_DLL +#ifdef CLIENT_DLL Q_FileBase( engine->GetLevelName(), m_szMap, ARRAYSIZE( m_szMap ) ); #else Q_strncpy( m_szMap, gpGlobals->mapname.ToCStr(), ARRAYSIZE( m_szMap ) ); @@ -570,7 +562,7 @@ void CAchievementMgr::LevelInitPreEntity() //----------------------------------------------------------------------------- void CAchievementMgr::LevelShutdownPreEntity() { - // make all achievements stop listening for events + // make all achievements stop listening for events FOR_EACH_MAP( m_mapAchievement, iAchievement ) { CBaseAchievement *pAchievement = m_mapAchievement[iAchievement]; @@ -658,7 +650,7 @@ void CAchievementMgr::DownloadUserData() Warning( "Enumerate Achievements failed! Error %d", ret ); bDownloadSuccessful = false; } - + // Enumerate the achievements from Live void *pBuffer = new byte[bytes]; if ( bDownloadSuccessful ) @@ -950,7 +942,7 @@ void CAchievementMgr::AwardAchievement( int iAchievementID ) SetDirty( true ); if ( IsPC() ) - { + { #ifndef NO_STEAM if ( steamapicontext->SteamUserStats() ) { @@ -1086,7 +1078,7 @@ bool CAchievementMgr::CheckAchievementsEnabled() //============================================================================= // HPE_END //============================================================================= -#endif // CSTRIKE_DLL +#endif // CSTRIKE_DLL #if defined(TF_DLL) || defined(TF_CLIENT_DLL) // no achievements for now in training @@ -1109,7 +1101,7 @@ bool CAchievementMgr::CheckAchievementsEnabled() if ( IsPC() ) { - // Don't award achievements if cheats are turned on. + // Don't award achievements if cheats are turned on. if ( WereCheatsEverOn() ) { #ifndef NO_STEAM @@ -1214,7 +1206,7 @@ bool CalcPlayersOnFriendsList( int iMinFriends ) //----------------------------------------------------------------------------- // Purpose: Returns whether there are a specified # of teammates who all belong -// to same clan as local player. Involves cross-process calls to Steam +// to same clan as local player. Involves cross-process calls to Steam // so this is mildly expensive, don't call this every frame. //----------------------------------------------------------------------------- bool CalcHasNumClanPlayers( int iClanTeammates ) @@ -1246,7 +1238,7 @@ bool CalcHasNumClanPlayers( int iClanTeammates ) { player_info_t pi; if ( engine->GetPlayerInfo( iPlayerIndex, &pi ) && ( pi.friendsID ) ) - { + { // check and see if they're on the local player's friends list CSteamID steamID( pi.friendsID, 1, steamapicontext->SteamUtils()->GetConnectedUniverse(), k_EAccountTypeIndividual ); if ( steamapicontext->SteamFriends()->IsUserInSource( steamID, clanID ) ) @@ -1267,7 +1259,7 @@ bool CalcHasNumClanPlayers( int iClanTeammates ) // TODO: implement for 360 return false; } - else + else { // other platforms...? return false; @@ -1298,7 +1290,7 @@ int CalcTeammateCount() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CalcPlayerCount() { @@ -1400,7 +1392,7 @@ void CAchievementMgr::PrintAchievementStatus() { CBaseAchievement *pAchievement = m_mapAchievement[i]; - Msg( "%42s ", pAchievement->GetName() ); + Msg( "%42s ", pAchievement->GetName() ); CFailableAchievement *pFailableAchievement = dynamic_cast( pAchievement ); if ( pAchievement->IsAchieved() ) @@ -1411,7 +1403,7 @@ void CAchievementMgr::PrintAchievementStatus() { Msg( "%-20s", "FAILED" ); } - else + else { char szBuf[255]; Q_snprintf( szBuf, ARRAYSIZE( szBuf ), "(%d/%d)%s", pAchievement->GetCount(), pAchievement->GetGoal(), @@ -1477,14 +1469,14 @@ void CAchievementMgr::FireGameEvent( IGameEvent *event ) { // player transitioned from no/spectator team to a game team, mark the time m_flTeamplayStartTime = gpGlobals->curtime; - } + } } else { // player transitioned to no/spectator team, clear the teamplay start time m_flTeamplayStartTime = 0; - } - } + } + } } else if ( 0 == Q_strcmp( name, "teamplay_round_start" ) ) { @@ -1537,7 +1529,11 @@ void CAchievementMgr::OnKillEvent( CBaseEntity *pVictim, CBaseEntity *pAttacker, } CBaseCombatCharacter *pBCC = dynamic_cast( pVictim ); +#ifdef MAPBASE + if ( pBCC && ( D_FR >= pBCC->IRelationType( pLocalPlayer ) ) ) +#else if ( pBCC && ( D_HT == pBCC->IRelationType( pLocalPlayer ) ) ) +#endif { bVictimIsPlayerEnemy = true; } @@ -1598,7 +1594,7 @@ void CAchievementMgr::OnKillEvent( CBaseEntity *pVictim, CBaseEntity *pAttacker, // we pass all filters for this achievement, notify the achievement of the kill pAchievement->Event_EntityKilled( pVictim, pAttacker, pInflictor, event ); - } + } } void CAchievementMgr::OnAchievementEvent( int iAchievementID, int iCount ) @@ -1625,7 +1621,7 @@ void CAchievementMgr::OnAchievementEvent( int iAchievementID, int iCount ) void CAchievementMgr::OnMapEvent( const char *pchEventName ) { Assert( pchEventName && *pchEventName ); - if ( !pchEventName || !*pchEventName ) + if ( !pchEventName || !*pchEventName ) return; // see if this event matches the prefix for an achievement component @@ -1647,11 +1643,18 @@ void CAchievementMgr::OnMapEvent( const char *pchEventName ) CBaseAchievement *pAchievement = m_vecMapEventListeners[iAchievement]; pAchievement->OnMapEvent( pchEventName ); } + +#ifdef MAPBASE + if (cc_achievement_debug.GetBool()) + { + Msg( "CAchievementMgr::OnMapEvent: Achievement \"%s\" not found\n", pchEventName ); + } +#endif } //----------------------------------------------------------------------------- // Purpose: Returns an achievement as it's abstract object. This interface is used by gameui.dll for getting achievement info. -// Input : index - +// Input : index - // Output : IBaseAchievement* //----------------------------------------------------------------------------- IAchievement* CAchievementMgr::GetAchievementByIndex( int index ) @@ -1662,7 +1665,7 @@ IAchievement* CAchievementMgr::GetAchievementByIndex( int index ) //----------------------------------------------------------------------------- // Purpose: Returns total achievement count. This interface is used by gameui.dll for getting achievement info. -// Input : - +// Input : - // Output : Count of achievements in manager's vector. //----------------------------------------------------------------------------- int CAchievementMgr::GetAchievementCount() @@ -1708,7 +1711,7 @@ void CAchievementMgr::Steam_OnUserStatsStored( UserStatsStored_t *pUserStatsStor if ( k_EResultOK != pUserStatsStored->m_eResult && k_EResultInvalidParam != pUserStatsStored->m_eResult ) { // We had some failure (like not connected or timeout) that means the stats were not stored. Redirty to try again - SetDirty( true ); + SetDirty( true ); } else { @@ -1718,7 +1721,7 @@ void CAchievementMgr::Steam_OnUserStatsStored( UserStatsStored_t *pUserStatsStor // synch, we get the current values/state from Steam. UpdateStateFromSteam_Internal(); - // In the case of k_EResultInvalidParam, some of the stats may have been stored, so we should still fall through to + // In the case of k_EResultInvalidParam, some of the stats may have been stored, so we should still fall through to // fire events related to achievements being awarded. } @@ -1753,7 +1756,7 @@ void CAchievementMgr::Steam_OnUserStatsStored( UserStatsStored_t *pUserStatsStor } } } -#endif +#endif m_AchievementsAwarded.Remove( 0 ); } @@ -1795,11 +1798,11 @@ void CAchievementMgr::ResetAchievement_Internal( CBaseAchievement *pAchievement #ifndef NO_STEAM if ( steamapicontext->SteamUserStats() ) { - steamapicontext->SteamUserStats()->ClearAchievement( pAchievement->GetName() ); + steamapicontext->SteamUserStats()->ClearAchievement( pAchievement->GetName() ); } -#endif +#endif pAchievement->SetAchieved( false ); - pAchievement->SetCount( 0 ); + pAchievement->SetCount( 0 ); if ( pAchievement->HasComponents() ) { pAchievement->SetComponentBits( 0 ); @@ -1852,7 +1855,7 @@ void CAchievementMgr::UpdateStateFromSteam_Internal() uint32 unlockTime; // Get the achievement status, and the time it was unlocked if unlocked. - // If the return value is true, but the unlock time is zero, that means it was unlocked before Steam + // If the return value is true, but the unlock time is zero, that means it was unlocked before Steam // began tracking achievement unlock times (December 2009). Time is seconds since January 1, 1970. bool bRet = steamapicontext->SteamUserStats()->GetAchievementAndUnlockTime( pAchievement->GetName(), &bAchieved, &unlockTime ); @@ -1982,7 +1985,7 @@ CON_COMMAND_F( achievement_unlock_all, "Unlocks all achievements", FCVAR_CHEAT ) { pAchievementMgr->AwardAchievement( pAchievement->GetAchievementID() ); } - } + } } CON_COMMAND_F( achievement_evaluate, " Causes failable achievement to be evaluated", FCVAR_CHEAT ) diff --git a/game/shared/activitylist.cpp b/game/shared/activitylist.cpp index cfe96330..b3021738 100644 --- a/game/shared/activitylist.cpp +++ b/game/shared/activitylist.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -21,7 +21,7 @@ extern IFileSystem *filesystem; // NOTE: If CStringRegistry allowed storing arbitrary data, we could just use that. -// in this case we have the "isPrivate" member and the replacement rules +// in this case we have the "isPrivate" member and the replacement rules // (activityIndex can be reused by private activities), so a custom table is necessary struct activitylist_t { @@ -34,7 +34,7 @@ CUtlVector g_ActivityList; static CUtlDict< CActivityRemapCache, int > m_ActivityRemapDatabase; -// This stores the actual activity names. Also, the string ID in the registry is simply an index +// This stores the actual activity names. Also, the string ID in the registry is simply an index // into the g_ActivityList array. CStringRegistry g_ActivityStrings; @@ -68,7 +68,7 @@ activitylist_t *ActivityList_AddActivityEntry( const char *pName, int iActivityI pList->activityIndex = iActivityIndex; pList->stringKey = g_ActivityStrings.AddString( pName, index ); pList->isPrivate = isPrivate; - + // UNDONE: This implies that ALL shared activities are added before ANY custom activities // UNDONE: Segment these instead? It's a 32-bit int, how many activities do we need? if ( iActivityIndex > g_HighestActivity ) @@ -116,7 +116,7 @@ bool ActivityList_RegisterSharedActivity( const char *pszActivityName, int iActi Assert( iActivityIndex < LAST_SHARED_ACTIVITY && (iActivityIndex == lastActivityIndex + 1 || iActivityIndex == 0) ); lastActivityIndex = iActivityIndex; - // first, check to make sure the slot we're asking for is free. It must be for + // first, check to make sure the slot we're asking for is free. It must be for // a shared activity. activitylist_t *pList = ListFromString( pszActivityName ); if ( !pList ) @@ -142,7 +142,7 @@ Activity ActivityList_RegisterPrivateActivity( const char *pszActivityName ) activitylist_t *pList = ListFromString( pszActivityName ); if ( pList ) { - // this activity is already in the list. If the activity we collided with is also private, + // this activity is already in the list. If the activity we collided with is also private, // then the collision is OK. Otherwise, it's a bug. if ( pList->isPrivate ) { @@ -264,7 +264,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_RELOAD_LOW ); REGISTER_SHARED_ACTIVITY( ACT_ARM ); REGISTER_SHARED_ACTIVITY( ACT_DISARM ); - + REGISTER_SHARED_ACTIVITY( ACT_DROP_WEAPON ); REGISTER_SHARED_ACTIVITY( ACT_DROP_WEAPON_SHOTGUN ); @@ -315,7 +315,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_WALK_SCARED ); REGISTER_SHARED_ACTIVITY( ACT_RUN_SCARED ); REGISTER_SHARED_ACTIVITY( ACT_VICTORY_DANCE ); - + REGISTER_SHARED_ACTIVITY( ACT_DIE_HEADSHOT ); REGISTER_SHARED_ACTIVITY( ACT_DIE_CHESTSHOT ); REGISTER_SHARED_ACTIVITY( ACT_DIE_GUTSHOT ); @@ -340,7 +340,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_180_RIGHT ); REGISTER_SHARED_ACTIVITY( ACT_90_LEFT ); REGISTER_SHARED_ACTIVITY( ACT_90_RIGHT ); - REGISTER_SHARED_ACTIVITY( ACT_STEP_LEFT ); + REGISTER_SHARED_ACTIVITY( ACT_STEP_LEFT ); REGISTER_SHARED_ACTIVITY( ACT_STEP_RIGHT ); REGISTER_SHARED_ACTIVITY( ACT_STEP_BACK ); REGISTER_SHARED_ACTIVITY( ACT_STEP_FORE ); @@ -352,7 +352,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK1_LOW ); REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK2_LOW ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ATTACK_SWING_GESTURE ); - + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SMALL_FLINCH ); REGISTER_SHARED_ACTIVITY( ACT_GESTURE_BIG_FLINCH ); REGISTER_SHARED_ACTIVITY( ACT_GESTURE_FLINCH_BLAST ); @@ -462,10 +462,10 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_ND_ATTACH2); REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_DETONATE); REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_DETONATOR_HOLSTER); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_ND_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_TO_THROW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_TO_THROW_ND); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_ND_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_TO_THROW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_TO_THROW_ND); REGISTER_SHARED_ACTIVITY( ACT_SLAM_STICKWALL_TO_TRIPMINE_ND ); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_IDLE); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_ND_IDLE); @@ -473,25 +473,25 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_THROW2); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_THROW_ND); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_THROW_ND2); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_ND_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_TO_STICKWALL); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_TO_STICKWALL_ND); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_ND_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_TO_STICKWALL); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_TO_STICKWALL_ND); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_DETONATE); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_DETONATOR_HOLSTER); REGISTER_SHARED_ACTIVITY( ACT_SLAM_THROW_TO_TRIPMINE_ND ); REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_IDLE); REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_ATTACH); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_ATTACH2); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_ATTACH); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_ATTACH2); REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_TO_STICKWALL_ND ); REGISTER_SHARED_ACTIVITY( ACT_SLAM_TRIPMINE_TO_THROW_ND ); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_IDLE); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_IDLE); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_DRAW); REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_DETONATE); REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_HOLSTER); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_STICKWALL_DRAW); - REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_THROW_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_STICKWALL_DRAW); + REGISTER_SHARED_ACTIVITY( ACT_SLAM_DETONATOR_THROW_DRAW); // SHOTGUN specialty activities REGISTER_SHARED_ACTIVITY( ACT_SHOTGUN_RELOAD_START); @@ -600,14 +600,14 @@ void ActivityList_RegisterSharedActivities( void ) // RPG activities REGISTER_SHARED_ACTIVITY( ACT_IDLE_RPG_RELAXED ); - REGISTER_SHARED_ACTIVITY( ACT_IDLE_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_RPG ); REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_RPG ); - REGISTER_SHARED_ACTIVITY( ACT_COVER_LOW_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_LOW_RPG ); REGISTER_SHARED_ACTIVITY( ACT_WALK_RPG ); - REGISTER_SHARED_ACTIVITY( ACT_RUN_RPG ); - REGISTER_SHARED_ACTIVITY( ACT_WALK_CROUCH_RPG ); - REGISTER_SHARED_ACTIVITY( ACT_RUN_CROUCH_RPG ); - REGISTER_SHARED_ACTIVITY( ACT_WALK_RPG_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROUCH_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROUCH_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_RPG_RELAXED ); REGISTER_SHARED_ACTIVITY( ACT_RUN_RPG_RELAXED ); REGISTER_SHARED_ACTIVITY( ACT_WALK_RIFLE ); @@ -659,7 +659,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_BUSY_SIT_CHAIR_EXIT ); REGISTER_SHARED_ACTIVITY( ACT_BUSY_STAND ); REGISTER_SHARED_ACTIVITY( ACT_BUSY_QUEUE ); - + // Dodge animations REGISTER_SHARED_ACTIVITY( ACT_DUCK_DODGE ); @@ -837,8 +837,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_DEEPIDLE2 ); REGISTER_SHARED_ACTIVITY ( ACT_DEEPIDLE3 ); REGISTER_SHARED_ACTIVITY ( ACT_DEEPIDLE4 ); - - REGISTER_SHARED_ACTIVITY ( ACT_VM_RELOAD_DEPLOYED ); + + REGISTER_SHARED_ACTIVITY ( ACT_VM_RELOAD_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_VM_RELOAD_IDLE ); REGISTER_SHARED_ACTIVITY ( ACT_VM_DRAW_DEPLOYED ); @@ -907,7 +907,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_8 ); REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_7 ); - REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_6 ); + REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_6 ); REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_5 ); REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_4 ); REGISTER_SHARED_ACTIVITY ( ACT_VM_PRIMARYATTACK_DEPLOYED_3 ); @@ -929,7 +929,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRIMARYATTACK_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRIMARYATTACK_PRONE_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_RELOAD_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_DOD_RELOAD_PRONE_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_DOD_RELOAD_PRONE_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRIMARYATTACK_PRONE ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_SECONDARYATTACK_PRONE ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_RELOAD_CROUCH ); @@ -1362,7 +1362,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRONE_ZOOM_FORWARD_BOLT ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRONE_ZOOM_FORWARD_BAZOOKA ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRONE_ZOOM_FORWARD_PSCHRECK ); - + // Crouch attack. REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRIMARYATTACK_CROUCH ); REGISTER_SHARED_ACTIVITY ( ACT_DOD_PRIMARYATTACK_CROUCH_SPADE ); @@ -1416,7 +1416,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_GESTURE_RANGE_ATTACK ); REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_GESTURE_RELOAD ); REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_JUMP ); - + REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_IDLE_PISTOL ); REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_RUN_PISTOL ); REGISTER_SHARED_ACTIVITY ( ACT_HL2MP_IDLE_CROUCH_PISTOL ); @@ -1499,47 +1499,47 @@ void ActivityList_RegisterSharedActivities( void ) // Portal REGISTER_SHARED_ACTIVITY ( ACT_VM_FIZZLE ); - + // Multiplayer - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_IDLE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_IDLE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_IDLE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_IDLE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_DEPLOYED_IDLE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_DEPLOYED_IDLE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN ); REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK ); REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SPRINT ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SPRINT ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND ); REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_VCD ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARYFIRE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARYFIRE_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARYFIRE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARYFIRE_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARYFIRE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PRIMARYFIRE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PRIMARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARYFIRE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_PRIMARYFIRE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_PRIMARYFIRE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARYFIRE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_LOOP ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_END ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_LOOP ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_END ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_SWIM ); @@ -1557,33 +1557,33 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_POSTFIRE ); // Multiplayer - Primary - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_DEPLOYED_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_DEPLOYED_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_DEPLOYED_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_DEPLOYED_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_DEPLOYED_IDLE_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PRIMARY_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARY_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARY_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_LOOP ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_END ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_END ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_LOOP ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_END ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_SWIM_PRIMARY ); @@ -1595,8 +1595,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_LOOP_2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_END_2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_PRIMARY_END_2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_LOOP_2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_CROUCH_PRIMARY_END_2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_SWIM_PRIMARY_2 ); @@ -1623,28 +1623,28 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_PRIMARY_SUPER ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PRIMARY_SUPER ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_PRIMARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_PRIMARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_PRIMARY ); // Secondary - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_SECONDARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_SECONDARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_SECONDARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_SECONDARY ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_SECONDARY_LOOP ); @@ -1664,28 +1664,28 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_SWIM_SECONDARY_2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_AIRWALK_SECONDARY_2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_SECONDARY ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_SECONDARY ); // Secondary2 - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_SECONDARY2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_SECONDARY2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_SECONDARY2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARY2 ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_SECONDARY2 ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_SECONDARY2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_SECONDARY2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_STAND_SECONDARY2_LOOP ); @@ -1701,29 +1701,29 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_RELOAD_AIRWALK_SECONDARY2_END ); // Melee - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_MELEE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_MELEE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_MELEE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_MELEE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_MELEE_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_MELEE ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_MELEE_SECONDARY ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_MELEE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_MELEE ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_MELEE ); // Item1 REGISTER_SHARED_ACTIVITY( ACT_MP_STAND_ITEM1 ); @@ -1802,11 +1802,6 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MP_ATTACK_SWIM_GRENADE_ITEM2 ); REGISTER_SHARED_ACTIVITY( ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2 ); - // Passtime - REGISTER_SHARED_ACTIVITY( ACT_MP_STAND_PASSTIME ); - REGISTER_SHARED_ACTIVITY( ACT_MP_RUN_PASSTIME ); - REGISTER_SHARED_ACTIVITY( ACT_MP_CROUCHWALK_PASSTIME ); - // Flinches REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_FLINCH ); REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_FLINCH_PRIMARY ); @@ -1867,63 +1862,63 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_ITEM2_GRENADE2_ATTACK ); // Building - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_BUILDING ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_BUILDING ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_BUILDING ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_BUILDING ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_BUILDING ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_BUILDING ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_BUILDING ); // Building - Deployed - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_BUILDING_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_BUILDING_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_BUILDING_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_BUILDING_DEPLOYED ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_BUILDING_DEPLOYED ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_GRENADE_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_CROUCH_GRENADE_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_GRENADE_BUILDING_DEPLOYED ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_AIRWALK_GRENADE_BUILDING_DEPLOYED ); // PDA - REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_STAND_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCH_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_RUN_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_WALK_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_AIRWALK_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_CROUCHWALK_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_PDA ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_START_PDA ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_FLOAT_PDA ); REGISTER_SHARED_ACTIVITY ( ACT_MP_JUMP_LAND_PDA ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_PDA ); + REGISTER_SHARED_ACTIVITY ( ACT_MP_SWIM_PDA ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_STAND_PDA ); REGISTER_SHARED_ACTIVITY ( ACT_MP_ATTACK_SWIM_PDA ); @@ -1948,7 +1943,6 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_ITEM1 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_ITEM2 ); REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE ); - REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME ); REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_VC_HANDMOUTH ); REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_VC_FINGERPOINT ); @@ -2010,11 +2004,6 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MP_STUN_MIDDLE ); REGISTER_SHARED_ACTIVITY( ACT_MP_STUN_END ); - REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_BEGIN ); - REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_MIDDLE ); - REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_END ); - REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_CANCEL ); - REGISTER_SHARED_ACTIVITY ( ACT_VM_UNUSABLE ); REGISTER_SHARED_ACTIVITY ( ACT_VM_UNUSABLE_TO_USABLE ); REGISTER_SHARED_ACTIVITY ( ACT_VM_USABLE_TO_UNUSABLE ); @@ -2025,20 +2014,20 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_FINISH ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_FINISH ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_LOWERED_TO_IDLE ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_RELOAD_2 ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START_2 ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START_2 ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_FINISH_2 ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_RELOAD_3 ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START_3 ); + REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_START_3 ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_RELOAD_FINISH_3 ); REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_PRIMARYATTACK_3 ); @@ -2048,11 +2037,11 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_RELOAD ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_RELOAD_START ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_RELOAD_FINISH ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_RELOAD2 ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_RELOAD2 ); + REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_LOWERED_TO_IDLE ); @@ -2068,8 +2057,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_LOWERED_TO_IDLE ); @@ -2083,8 +2072,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_PDA_VM_LOWERED_TO_IDLE ); @@ -2103,19 +2092,19 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_LOWERED_TO_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_RELOAD_START ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_RELOAD_FINISH ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_HITCENTER ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_SWINGHARD ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_UP ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_DOWN ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_ITEM1_STUN ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_RELOAD_START ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_RELOAD_FINISH ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_HITCENTER ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_VM_SWINGHARD ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_UP ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_DOWN ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM1_BACKSTAB_VM_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_ITEM1_STUN ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_DRAW ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_HOLSTER ); @@ -2123,8 +2112,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_LOWERED_TO_IDLE ); @@ -2134,9 +2123,9 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_CHARGE_IDLE_3 ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_HITCENTER ); REGISTER_SHARED_ACTIVITY( ACT_ITEM2_VM_SWINGHARD ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_UP ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_DOWN ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_IDLE ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_UP ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_DOWN ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM2_BACKSTAB_VM_IDLE ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_ITEM2_STUN ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_DRAW ); @@ -2145,8 +2134,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_ITEM3_VM_LOWERED_TO_IDLE ); @@ -2163,10 +2152,10 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_SECONDARY2ATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_RELOAD ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_RELOAD_START ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_RELOAD_FINISH ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_RELOAD2 ); + REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_RELOAD2 ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_SECONDARY2_VM_IDLE_LOWERED ); @@ -2241,29 +2230,29 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_PULLBACK ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_PRIMARYATTACK ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_SECONDARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_RELOAD ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_DRYFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_RELOAD ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_DRYFIRE ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_IDLE_TO_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_IDLE_LOWERED ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_LOWERED_TO_IDLE ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_STUN ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_HITCENTER ); + REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_HITCENTER ); REGISTER_SHARED_ACTIVITY( ACT_MELEE_ALLCLASS_VM_SWINGHARD ); - + REGISTER_SHARED_ACTIVITY( ACT_MP_STAND_BOMB ); REGISTER_SHARED_ACTIVITY( ACT_MP_JUMP_START_BOMB ); REGISTER_SHARED_ACTIVITY( ACT_MP_JUMP_FLOAT_BOMB ); REGISTER_SHARED_ACTIVITY( ACT_MP_JUMP_LAND_BOMB ); REGISTER_SHARED_ACTIVITY( ACT_MP_RUN_BOMB ); REGISTER_SHARED_ACTIVITY( ACT_MP_SWIM_BOMB ); - + REGISTER_SHARED_ACTIVITY( ACT_VM_DRAW_QRL ); REGISTER_SHARED_ACTIVITY( ACT_VM_IDLE_QRL ); REGISTER_SHARED_ACTIVITY( ACT_VM_PULLBACK_QRL ); REGISTER_SHARED_ACTIVITY( ACT_VM_PRIMARYATTACK_QRL ); REGISTER_SHARED_ACTIVITY( ACT_VM_RELOAD_QRL ); - REGISTER_SHARED_ACTIVITY( ACT_VM_RELOAD_START_QRL ); - REGISTER_SHARED_ACTIVITY( ACT_VM_RELOAD_FINISH_QRL ); + REGISTER_SHARED_ACTIVITY( ACT_VM_RELOAD_START_QRL ); + REGISTER_SHARED_ACTIVITY( ACT_VM_RELOAD_FINISH_QRL ); REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_STAND_PRIMARY3 ); REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_CROUCH_PRIMARY3 ); @@ -2275,7 +2264,7 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_CROUCH_PRIMARY3_END ); REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_AIRWALK_PRIMARY3_END ); REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_SWIM_PRIMARY3 ); - + REGISTER_SHARED_ACTIVITY( ACT_MP_THROW ); REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_DRAW ); REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_IDLE ); @@ -2286,70 +2275,521 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_ARM ); REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_FIRE ); - REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_DRAW ); - REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_IDLE ); - - REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITLEFT ); - REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITRIGHT ); - REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_SWINGHARD ); - REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_DRAW ); - - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITRIGHT ); - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITUP ); - - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_DRAW ); - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_PRIMARYATTACK ); - - REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY ); - REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT ); - REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT_IDLE ); - - REGISTER_SHARED_ACTIVITY( ACT_BOT_SPAWN ); - REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC ); - REGISTER_SHARED_ACTIVITY( ACT_BOT_PRIMARY_MOVEMENT ); - REGISTER_SHARED_ACTIVITY( ACT_BOT_GESTURE_FLINCH ); - REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_START ); - REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_END ); - - REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_DRAW ); - REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_PRIMARYATTACK ); - REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_RELOAD ); - - REGISTER_SHARED_ACTIVITY( ACT_KART_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_KART_ACTION_SHOOT ); - REGISTER_SHARED_ACTIVITY( ACT_KART_ACTION_DASH ); - REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_START ); - REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_FLOAT ); - REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_LAND ); - REGISTER_SHARED_ACTIVITY( ACT_KART_IMPACT ); - REGISTER_SHARED_ACTIVITY( ACT_KART_IMPACT_BIG ); - REGISTER_SHARED_ACTIVITY( ACT_KART_GESTURE_POSITIVE ); - REGISTER_SHARED_ACTIVITY( ACT_KART_GESTURE_NEGATIVE ); - - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_DRAW ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_FIRE_START ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_FIRE_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_START ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_END ); - - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_START ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_END ); - - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_START ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_END ); - - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_START ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_IDLE ); - REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_END ); +#if AR2_ACTIVITY_FIX == 1 + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_AR2 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR2_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_AR2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR2_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR2 ); + + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR2_LOW ); + + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_AR2 ); + + REGISTER_SHARED_ACTIVITY( ACT_COVER_AR2_LOW ); +#endif + +#if SHARED_COMBINE_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_COMBINE_THROW_GRENADE ); + REGISTER_SHARED_ACTIVITY( ACT_COMBINE_AR2_ALTFIRE ); + + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_COMBINE_THROW_GRENADE ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_COMBINE_AR2_ALTFIRE ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SPECIAL_ATTACK1 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SPECIAL_ATTACK2 ); + + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_ADVANCE ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_FORWARD ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_GROUP ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_HALT ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_LEFT ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_RIGHT ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_SIGNAL_TAKECOVER ); +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_IDLE_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_REVOLVER_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_REVOLVER_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_REVOLVER_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_REVOLVER_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_REVOLVER ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_CROSSBOW_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_CROSSBOW_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_CROSSBOW_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_CROSSBOW_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_CROSSBOW ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_CROSSBOW_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_CROSSBOW_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROSSBOW_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROSSBOW_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROSSBOW_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROSSBOW_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_CROSSBOW_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_CROSSBOW_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_CROSSBOW_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_PISTOL_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_PISTOL_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_PISTOL_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_PISTOL_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_PISTOL_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_PISTOL_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_PISTOL_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_PISTOL_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_PISTOL_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROUCH_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_CROUCH_AIM_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROUCH_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_CROUCH_AIM_PISTOL ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SHOTGUN ); + + REGISTER_SHARED_ACTIVITY( ACT_COVER_SHOTGUN_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SHOTGUN_LOW ); + + REGISTER_SHARED_ACTIVITY( ACT_WALK_SHOTGUN_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SHOTGUN_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SHOTGUN_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SHOTGUN_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SHOTGUN_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SHOTGUN_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SHOTGUN_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_RPG_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_RPG_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_RPG ); + + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_ANNABELLE ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_ANNABELLE_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_ANNABELLE ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_ANNABELLE ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_ANNABELLE_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_ANNABELLE ); + + REGISTER_SHARED_ACTIVITY( ACT_WALK_MELEE ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_MELEE ); + + REGISTER_SHARED_ACTIVITY( ACT_RUN_PACKAGE ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SUITCASE ); + + REGISTER_SHARED_ACTIVITY( ACT_ARM_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_ARM_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_ARM_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_ARM_MELEE ); + REGISTER_SHARED_ACTIVITY( ACT_DISARM_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_DISARM_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_DISARM_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_DISARM_MELEE ); +#endif + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR1 ); + //REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_AR1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_AR1_LOW ); + //REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_AR1 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR1_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_AR1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR1_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_AR3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_AR3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_AR3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_AR3 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AR3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AR3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AR3_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_AR3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_AR3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_AR3_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SMG2 ); + //REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG2_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SMG2_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_SMG2_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SMG2_LOW ); + //REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_SMG2 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG2_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG2_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SMG2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SMG2_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SMG2_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SMG3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_SMG3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SMG3_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_SMG3 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SMG3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG3_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SMG3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SMG3_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SMG3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SMG3_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SMG3_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_HMG1 ); + //REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_HMG1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_HMG1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_HMG1_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_HMG1_LOW ); + //REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_HMG1 ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_HMG1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_HMG1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_HMG1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_HMG1_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_HMG1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_HMG1_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_HMG1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_HMG1_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_HMG1_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SNIPER_RIFLE ); + //REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SNIPER_RIFLE_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_SNIPER_RIFLE_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_SNIPER_RIFLE_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SNIPER_RIFLE_LOW ); + //REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_SNIPER_RIFLE ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SNIPER_RIFLE_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_SNIPER_RIFLE_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SNIPER_RIFLE_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SNIPER_RIFLE_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_SNIPER_RIFLE_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_SNIPER_RIFLE_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_ANGRY_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RELOAD_DUAL_PISTOLS_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_DUAL_PISTOLS_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_DUAL_PISTOLS_LOW ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_GESTURE_RELOAD_DUAL_PISTOLS ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_IDLE_DUAL_PISTOLS_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS_RELAXED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_DUAL_PISTOLS_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_DUAL_PISTOLS_STIMULATED ); + + REGISTER_SHARED_ACTIVITY( ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED ); + REGISTER_SHARED_ACTIVITY( ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED ); +#endif + +#if EXPANDED_NAVIGATION_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_CLIMB_ALL ); + REGISTER_SHARED_ACTIVITY( ACT_CLIMB_IDLE ); + + REGISTER_SHARED_ACTIVITY( ACT_CLIMB_MOUNT_TOP ); + REGISTER_SHARED_ACTIVITY( ACT_CLIMB_MOUNT_BOTTOM ); + REGISTER_SHARED_ACTIVITY( ACT_CLIMB_DISMOUNT_BOTTOM ); +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK2_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_MED ); + + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR2_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SHOTGUN_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_PISTOL_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_RPG_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_REVOLVER_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_CROSSBOW_MED ); + + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_AR2_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SMG1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SHOTGUN_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_PISTOL_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_RPG_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_REVOLVER_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_CROSSBOW_MED ); + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_AR1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_AR3_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_AR3_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SMG2_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG2_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SMG3_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SMG3_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_HMG1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_HMG1_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_SNIPER_RIFLE_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_SNIPER_RIFLE_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_AIM_DUAL_PISTOLS_MED ); + REGISTER_SHARED_ACTIVITY( ACT_RANGE_ATTACK_DUAL_PISTOLS_MED ); +#endif + + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_R ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_L ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_R ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_L ); + + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_R_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_L_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_R_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_L_RIFLE ); + + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_R_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_L_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_R_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_COVER_WALL_LOW_L_PISTOL ); +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_PHYSGUN ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_GRENADE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_MELEE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SLAM ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_PISTOL ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SHOTGUN ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_PHYSGUN ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_GRENADE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_RPG ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_CROSSBOW ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_REVOLVER ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_REVOLVER ); + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_AR1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_AR1 ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_AR3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_AR3 ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SMG2 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SMG2 ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SMG3 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SMG3 ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_HMG1 ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_HMG1 ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SNIPER_RIFLE ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_DUAL_PISTOLS ); +#endif + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_USE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_USE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_USE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_USE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_USE ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_USE ); + + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_USE_HEAVY ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_USE_HEAVY ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_USE_HEAVY ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_CROUCH_USE_HEAVY ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_CROUCH_USE_HEAVY ); + REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_USE_HEAVY ); +#endif #ifdef VANCE REGISTER_SHARED_ACTIVITY( ACT_VM_WALK ); @@ -2373,8 +2813,8 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_VM_THROW_IDLE ); #endif - AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" ); -} + AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" ); +} // HACKHACK: Keep backwards compatibility on broken activities temporarily #define ACTIVITY_FILE_TAG 0x80800000 @@ -2383,7 +2823,7 @@ class CActivityDataOps : public CDefSaveRestoreOps { public: // save data type interface - virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) { int activityIndex = *((int *)fieldInfo.pField); const char *pActivityName = ActivityList_NameForIndex( activityIndex ); @@ -2393,7 +2833,7 @@ class CActivityDataOps : public CDefSaveRestoreOps pActivityName = ActivityList_NameForIndex( 0 ); } int len = strlen(pActivityName) + 1; - + // Use the high 16-bits of this int to signify this file format // this makes this backwards compatible. // UNDONE: Remove after playtest save files are no longer needed @@ -2402,7 +2842,7 @@ class CActivityDataOps : public CDefSaveRestoreOps pSave->WriteString( pActivityName ); } - virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) { char nameBuf[1024]; @@ -2424,13 +2864,13 @@ class CActivityDataOps : public CDefSaveRestoreOps } } - virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) - { + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { int *pActivityIndex = (int *)fieldInfo.pField; return (*pActivityIndex == 0); } - virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) { int *pActivityIndex = (int *)fieldInfo.pField; *pActivityIndex = 0; diff --git a/game/shared/ai_activity.h b/game/shared/ai_activity.h index c46bd464..e4ff27a3 100644 --- a/game/shared/ai_activity.h +++ b/game/shared/ai_activity.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -11,6 +11,57 @@ #pragma once #endif +#ifdef MAPBASE + +// +// Mapbase adds many new shared activities, primarily for NPCs. +// +// These are at the bottom of the enum to prevent disruptions in the order of existing activities. +// + +// AR2 ACTIVITY FIX +// Citizens and Combine soldiers have several activities for the SMG1 and AR2 which differ from each other. +// Across both NPCs, there are around 20-40 different AR2 animations. Most of these animations are similar to the +// SMG1 animations, except their hand positions are adjusted to use the AR2 instead. +// +// Unfortunately, the vast majority of the AR2 animations in those models are not declared as real activities in +// code. The AR2 instead falls back to its SMG1 animation counterparts. +// This is thought to be an oversight which dates back to late in Half-Life 2's development. +// +// This preprocessor declares those activities and implements them on the AR2. In-game, they work surprisingly well +// despite presumably never being tested in-game during HL2's development. +#define AR2_ACTIVITY_FIX 1 + +// SHARED COMBINE ACTIVITIES +// This turns ACT_COMBINE_AR2_ALTFIRE, ACT_COMBINE_THROW_GRENADE, and their new gesture counterparts into shared activities. +// This is necessary for other NPCs to use them without having to rely on private custom activities declared through the AI definition system. +#define SHARED_COMBINE_ACTIVITIES 1 + +// EXPANDED HL2 WEAPON ACTIVITIES +// This enables a bunch of new activities for Half-Life 2 weapons, including new 357 animations and readiness activities for pistols. +#define EXPANDED_HL2_WEAPON_ACTIVITIES 1 + +// EXPANDED HL2 UNUSED WEAPON ACTIVITIES +// This enables a bunch of new activities for unused Half-Life 2 weapons, particularly those which exist in the SDK, but are deactivated by default. +// This essentially just means mods which restore those weapons have the option of using custom activities for them. +// Mapbase's backup activity system would allow them to fall back to other weapons if the relevant activities do not exist. +// Also includes activity names for "AR3", "SMG3", and "DUAL_PISTOLS", which were never used in HL2, but may be useful when additional animation sets are needed. +#define EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES 0 + +// EXPANDED NAVIGATION ACTIVITIES +// This enables some new navigation-related activities. +#define EXPANDED_NAVIGATION_ACTIVITIES 1 + +// EXPANDED HL2 COVER ACTIVITIES +// This enables some new cover-related activities. +#define EXPANDED_HL2_COVER_ACTIVITIES 1 + +// EXPANDED HL2DM ACTIVITIES +// This enables some new activities for the HL2:DM set. +#define EXPANDED_HL2DM_ACTIVITIES 1 + +#endif + #define ACTIVITY_NOT_AVAILABLE -1 typedef enum @@ -80,7 +131,7 @@ typedef enum ACT_LOOKBACK_LEFT, ACT_COWER, // FIXME: unused, should be more extreme version of crouching ACT_SMALL_FLINCH, // FIXME: needed? shouldn't flinching be down with overlays? - ACT_BIG_FLINCH, + ACT_BIG_FLINCH, ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK2, ACT_RELOAD, @@ -110,7 +161,7 @@ typedef enum ACT_RUN_STIMULATED, ACT_RUN_AGITATED, ACT_RUN_STEALTH, - + ACT_IDLE_AIM_RELAXED, ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_AGITATED, @@ -133,12 +184,12 @@ typedef enum ACT_WALK_HURT, // limp (loop) ACT_RUN_HURT, // limp (loop) ACT_SPECIAL_ATTACK1, // very monster specific special attacks. - ACT_SPECIAL_ATTACK2, + ACT_SPECIAL_ATTACK2, ACT_COMBAT_IDLE, // FIXME: unused? agitated idle. ACT_WALK_SCARED, ACT_RUN_SCARED, ACT_VICTORY_DANCE, // killed a player, do a victory dance. - ACT_DIE_HEADSHOT, // die, hit in head. + ACT_DIE_HEADSHOT, // die, hit in head. ACT_DIE_CHESTSHOT, // die, hit in chest ACT_DIE_GUTSHOT, // die, hit in gut ACT_DIE_BACKSHOT, // die, hit in back @@ -153,7 +204,7 @@ typedef enum ACT_IDLE_ON_FIRE, // ON FIRE animations ACT_WALK_ON_FIRE, - ACT_RUN_ON_FIRE, + ACT_RUN_ON_FIRE, ACT_RAPPEL_LOOP, // Rappel down a rope! @@ -227,9 +278,9 @@ typedef enum ACT_VM_PULLPIN, ACT_VM_PRIMARYATTACK, // fire ACT_VM_SECONDARYATTACK, // alt. fire - ACT_VM_RELOAD, - ACT_VM_RELOAD_START, - ACT_VM_RELOAD_FINISH, + ACT_VM_RELOAD, + ACT_VM_RELOAD_START, + ACT_VM_RELOAD_FINISH, ACT_VM_DRYFIRE, // fire with no ammo loaded. ACT_VM_HITLEFT, // bludgeon, swing to left - hit (primary attk) ACT_VM_HITLEFT2, // bludgeon, swing to left - hit (secondary attk) @@ -255,7 +306,7 @@ typedef enum ACT_VM_RECOIL3, ACT_VM_PICKUP, ACT_VM_RELEASE, - + ACT_VM_ATTACH_SILENCER, ACT_VM_DETACH_SILENCER, @@ -290,10 +341,10 @@ typedef enum ACT_SLAM_STICKWALL_ND_ATTACH2, ACT_SLAM_STICKWALL_DETONATE, ACT_SLAM_STICKWALL_DETONATOR_HOLSTER, - ACT_SLAM_STICKWALL_DRAW, - ACT_SLAM_STICKWALL_ND_DRAW, - ACT_SLAM_STICKWALL_TO_THROW, - ACT_SLAM_STICKWALL_TO_THROW_ND, + ACT_SLAM_STICKWALL_DRAW, + ACT_SLAM_STICKWALL_ND_DRAW, + ACT_SLAM_STICKWALL_TO_THROW, + ACT_SLAM_STICKWALL_TO_THROW_ND, ACT_SLAM_STICKWALL_TO_TRIPMINE_ND, ACT_SLAM_THROW_IDLE, ACT_SLAM_THROW_ND_IDLE, @@ -301,21 +352,21 @@ typedef enum ACT_SLAM_THROW_THROW2, ACT_SLAM_THROW_THROW_ND, ACT_SLAM_THROW_THROW_ND2, - ACT_SLAM_THROW_DRAW, + ACT_SLAM_THROW_DRAW, ACT_SLAM_THROW_ND_DRAW, - ACT_SLAM_THROW_TO_STICKWALL, - ACT_SLAM_THROW_TO_STICKWALL_ND, + ACT_SLAM_THROW_TO_STICKWALL, + ACT_SLAM_THROW_TO_STICKWALL_ND, ACT_SLAM_THROW_DETONATE, ACT_SLAM_THROW_DETONATOR_HOLSTER, ACT_SLAM_THROW_TO_TRIPMINE_ND, ACT_SLAM_TRIPMINE_IDLE, - ACT_SLAM_TRIPMINE_DRAW, - ACT_SLAM_TRIPMINE_ATTACH, - ACT_SLAM_TRIPMINE_ATTACH2, + ACT_SLAM_TRIPMINE_DRAW, + ACT_SLAM_TRIPMINE_ATTACH, + ACT_SLAM_TRIPMINE_ATTACH2, ACT_SLAM_TRIPMINE_TO_STICKWALL_ND, ACT_SLAM_TRIPMINE_TO_THROW_ND, - ACT_SLAM_DETONATOR_IDLE, - ACT_SLAM_DETONATOR_DRAW, + ACT_SLAM_DETONATOR_IDLE, + ACT_SLAM_DETONATOR_DRAW, ACT_SLAM_DETONATOR_DETONATE, ACT_SLAM_DETONATOR_HOLSTER, ACT_SLAM_DETONATOR_STICKWALL_DRAW, @@ -334,7 +385,7 @@ typedef enum ACT_SMG2_DRYFIRE2, ACT_SMG2_TOAUTO, ACT_SMG2_TOBURST, - + // Physcannon special activities ACT_PHYSCANNON_UPGRADE, @@ -420,22 +471,22 @@ typedef enum // Manned guns ACT_IDLE_MANNEDGUN, - + // Melee weapon ACT_IDLE_MELEE, ACT_IDLE_ANGRY_MELEE, // RPG activities ACT_IDLE_RPG_RELAXED, - ACT_IDLE_RPG, + ACT_IDLE_RPG, ACT_IDLE_ANGRY_RPG, - ACT_COVER_LOW_RPG, + ACT_COVER_LOW_RPG, ACT_WALK_RPG, - ACT_RUN_RPG, - ACT_WALK_CROUCH_RPG, - ACT_RUN_CROUCH_RPG, - ACT_WALK_RPG_RELAXED, - ACT_RUN_RPG_RELAXED, + ACT_RUN_RPG, + ACT_WALK_CROUCH_RPG, + ACT_RUN_CROUCH_RPG, + ACT_WALK_RPG_RELAXED, + ACT_RUN_RPG_RELAXED, ACT_WALK_RIFLE, ACT_WALK_AIM_RIFLE, @@ -492,9 +543,9 @@ typedef enum // For NPCs being lifted/eaten by barnacles: // being swallowed by a barnacle - ACT_DIE_BARNACLE_SWALLOW, + ACT_DIE_BARNACLE_SWALLOW, // being lifted by a barnacle - ACT_GESTURE_BARNACLE_STRANGLE, + ACT_GESTURE_BARNACLE_STRANGLE, ACT_PHYSCANNON_DETACH, // An activity to be played if we're picking this up with the physcannon ACT_PHYSCANNON_ANIMATE, // An activity to be played by an object being picked up with the physcannon, but has different behavior to DETACH @@ -647,16 +698,16 @@ typedef enum ACT_PLAYER_CROUCH_WALK_FIRE, ACT_PLAYER_WALK_FIRE, ACT_PLAYER_RUN_FIRE, - + ACT_IDLETORUN, ACT_RUNTOIDLE, - + //=========================== // DoD Specific Activities //=========================== ACT_SPRINT, - + ACT_GET_DOWN_STAND, ACT_GET_UP_STAND, ACT_GET_DOWN_CROUCH, @@ -669,7 +720,7 @@ typedef enum ACT_DEEPIDLE3, ACT_DEEPIDLE4, - ACT_VM_RELOAD_DEPLOYED, + ACT_VM_RELOAD_DEPLOYED, ACT_VM_RELOAD_IDLE, ACT_VM_DRAW_DEPLOYED, @@ -738,7 +789,7 @@ typedef enum ACT_VM_PRIMARYATTACK_DEPLOYED, ACT_VM_PRIMARYATTACK_DEPLOYED_8, ACT_VM_PRIMARYATTACK_DEPLOYED_7, - ACT_VM_PRIMARYATTACK_DEPLOYED_6, + ACT_VM_PRIMARYATTACK_DEPLOYED_6, ACT_VM_PRIMARYATTACK_DEPLOYED_5, ACT_VM_PRIMARYATTACK_DEPLOYED_4, ACT_VM_PRIMARYATTACK_DEPLOYED_3, @@ -758,7 +809,7 @@ typedef enum ACT_DOD_PRIMARYATTACK_DEPLOYED, ACT_DOD_PRIMARYATTACK_PRONE_DEPLOYED, ACT_DOD_RELOAD_DEPLOYED, - ACT_DOD_RELOAD_PRONE_DEPLOYED, + ACT_DOD_RELOAD_PRONE_DEPLOYED, ACT_DOD_PRIMARYATTACK_PRONE, ACT_DOD_SECONDARYATTACK_PRONE, ACT_DOD_RELOAD_CROUCH, @@ -1244,7 +1295,7 @@ typedef enum ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_JUMP, - + ACT_HL2MP_IDLE_PISTOL, ACT_HL2MP_RUN_PISTOL, ACT_HL2MP_IDLE_CROUCH_PISTOL, @@ -1423,8 +1474,8 @@ typedef enum ACT_MP_RELOAD_STAND_PRIMARY_2, ACT_MP_RELOAD_STAND_PRIMARY_LOOP_2, - ACT_MP_RELOAD_STAND_PRIMARY_END_2, - ACT_MP_RELOAD_CROUCH_PRIMARY_2, + ACT_MP_RELOAD_STAND_PRIMARY_END_2, + ACT_MP_RELOAD_CROUCH_PRIMARY_2, ACT_MP_RELOAD_CROUCH_PRIMARY_LOOP_2, ACT_MP_RELOAD_CROUCH_PRIMARY_END_2, ACT_MP_RELOAD_SWIM_PRIMARY_2, @@ -1601,7 +1652,7 @@ typedef enum ACT_MP_ATTACK_SWIM_ITEM2, ACT_MP_ATTACK_AIRWALK_ITEM2, - ACT_MP_ATTACK_STAND_HARD_ITEM2, + ACT_MP_ATTACK_STAND_HARD_ITEM2, ACT_MP_ATTACK_CROUCH_HARD_ITEM2, ACT_MP_ATTACK_SWIM_HARD_ITEM2, @@ -1631,11 +1682,6 @@ typedef enum ACT_MP_ATTACK_SWIM_GRENADE_ITEM2, ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2, - // Passtime - ACT_MP_STAND_PASSTIME, - ACT_MP_RUN_PASSTIME, - ACT_MP_CROUCHWALK_PASSTIME, - // Flinches ACT_MP_GESTURE_FLINCH, ACT_MP_GESTURE_FLINCH_PRIMARY, @@ -1776,7 +1822,6 @@ typedef enum ACT_MP_DOUBLEJUMP_CROUCH_ITEM1, ACT_MP_DOUBLEJUMP_CROUCH_ITEM2, ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE, - ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME, ACT_MP_GESTURE_VC_HANDMOUTH, ACT_MP_GESTURE_VC_FINGERPOINT, @@ -1838,11 +1883,6 @@ typedef enum ACT_MP_STUN_MIDDLE, ACT_MP_STUN_END, - ACT_MP_PASSTIME_THROW_BEGIN, - ACT_MP_PASSTIME_THROW_MIDDLE, - ACT_MP_PASSTIME_THROW_END, - ACT_MP_PASSTIME_THROW_CANCEL, - ACT_VM_UNUSABLE, ACT_VM_UNUSABLE_TO_USABLE, ACT_VM_USABLE_TO_UNUSABLE, @@ -1854,18 +1894,18 @@ typedef enum ACT_PRIMARY_VM_PULLBACK, ACT_PRIMARY_VM_PRIMARYATTACK, ACT_PRIMARY_VM_SECONDARYATTACK, - ACT_PRIMARY_VM_RELOAD, - ACT_PRIMARY_RELOAD_START, - ACT_PRIMARY_RELOAD_FINISH, - ACT_PRIMARY_VM_DRYFIRE, + ACT_PRIMARY_VM_RELOAD, + ACT_PRIMARY_RELOAD_START, + ACT_PRIMARY_RELOAD_FINISH, + ACT_PRIMARY_VM_DRYFIRE, ACT_PRIMARY_VM_IDLE_TO_LOWERED, ACT_PRIMARY_VM_IDLE_LOWERED, ACT_PRIMARY_VM_LOWERED_TO_IDLE, ACT_PRIMARY_VM_RELOAD_2, - ACT_PRIMARY_RELOAD_START_2, + ACT_PRIMARY_RELOAD_START_2, ACT_PRIMARY_RELOAD_FINISH_2, ACT_PRIMARY_VM_RELOAD_3, - ACT_PRIMARY_RELOAD_START_3, + ACT_PRIMARY_RELOAD_START_3, ACT_PRIMARY_RELOAD_FINISH_3, ACT_PRIMARY_VM_PRIMARYATTACK_3, @@ -1875,11 +1915,11 @@ typedef enum ACT_SECONDARY_VM_PULLBACK, ACT_SECONDARY_VM_PRIMARYATTACK, ACT_SECONDARY_VM_SECONDARYATTACK, - ACT_SECONDARY_VM_RELOAD, + ACT_SECONDARY_VM_RELOAD, ACT_SECONDARY_RELOAD_START, ACT_SECONDARY_RELOAD_FINISH, - ACT_SECONDARY_VM_RELOAD2, - ACT_SECONDARY_VM_DRYFIRE, + ACT_SECONDARY_VM_RELOAD2, + ACT_SECONDARY_VM_DRYFIRE, ACT_SECONDARY_VM_IDLE_TO_LOWERED, ACT_SECONDARY_VM_IDLE_LOWERED, ACT_SECONDARY_VM_LOWERED_TO_IDLE, @@ -1895,13 +1935,13 @@ typedef enum ACT_MELEE_VM_PULLBACK, ACT_MELEE_VM_PRIMARYATTACK, ACT_MELEE_VM_SECONDARYATTACK, - ACT_MELEE_VM_RELOAD, - ACT_MELEE_VM_DRYFIRE, + ACT_MELEE_VM_RELOAD, + ACT_MELEE_VM_DRYFIRE, ACT_MELEE_VM_IDLE_TO_LOWERED, ACT_MELEE_VM_IDLE_LOWERED, ACT_MELEE_VM_LOWERED_TO_IDLE, ACT_MELEE_VM_STUN, - ACT_MELEE_VM_HITCENTER, + ACT_MELEE_VM_HITCENTER, ACT_MELEE_VM_SWINGHARD, ACT_PDA_VM_DRAW, @@ -1910,8 +1950,8 @@ typedef enum ACT_PDA_VM_PULLBACK, ACT_PDA_VM_PRIMARYATTACK, ACT_PDA_VM_SECONDARYATTACK, - ACT_PDA_VM_RELOAD, - ACT_PDA_VM_DRYFIRE, + ACT_PDA_VM_RELOAD, + ACT_PDA_VM_DRYFIRE, ACT_PDA_VM_IDLE_TO_LOWERED, ACT_PDA_VM_IDLE_LOWERED, ACT_PDA_VM_LOWERED_TO_IDLE, @@ -1930,13 +1970,13 @@ typedef enum ACT_ITEM1_VM_PULLBACK, ACT_ITEM1_VM_PRIMARYATTACK, ACT_ITEM1_VM_SECONDARYATTACK, - ACT_ITEM1_VM_RELOAD, - ACT_ITEM1_VM_DRYFIRE, + ACT_ITEM1_VM_RELOAD, + ACT_ITEM1_VM_DRYFIRE, ACT_ITEM1_VM_IDLE_TO_LOWERED, ACT_ITEM1_VM_IDLE_LOWERED, ACT_ITEM1_VM_LOWERED_TO_IDLE, - ACT_ITEM1_RELOAD_START, - ACT_ITEM1_RELOAD_FINISH, + ACT_ITEM1_RELOAD_START, + ACT_ITEM1_RELOAD_FINISH, ACT_ITEM1_VM_HITCENTER, ACT_ITEM1_VM_SWINGHARD, ACT_ITEM1_BACKSTAB_VM_UP, @@ -1950,8 +1990,8 @@ typedef enum ACT_ITEM2_VM_PULLBACK, ACT_ITEM2_VM_PRIMARYATTACK, ACT_ITEM2_VM_SECONDARYATTACK, - ACT_ITEM2_VM_RELOAD, - ACT_ITEM2_VM_DRYFIRE, + ACT_ITEM2_VM_RELOAD, + ACT_ITEM2_VM_DRYFIRE, ACT_ITEM2_VM_IDLE_TO_LOWERED, ACT_ITEM2_VM_IDLE_LOWERED, ACT_ITEM2_VM_LOWERED_TO_IDLE, @@ -1972,8 +2012,8 @@ typedef enum ACT_ITEM3_VM_PULLBACK, ACT_ITEM3_VM_PRIMARYATTACK, ACT_ITEM3_VM_SECONDARYATTACK, - ACT_ITEM3_VM_RELOAD, - ACT_ITEM3_VM_DRYFIRE, + ACT_ITEM3_VM_RELOAD, + ACT_ITEM3_VM_DRYFIRE, ACT_ITEM3_VM_IDLE_TO_LOWERED, ACT_ITEM3_VM_IDLE_LOWERED, ACT_ITEM3_VM_LOWERED_TO_IDLE, @@ -1990,15 +2030,15 @@ typedef enum ACT_SECONDARY2_VM_PULLBACK, ACT_SECONDARY2_VM_PRIMARYATTACK, ACT_SECONDARY2_VM_SECONDARY2ATTACK, - ACT_SECONDARY2_VM_RELOAD, + ACT_SECONDARY2_VM_RELOAD, ACT_SECONDARY2_RELOAD_START, ACT_SECONDARY2_RELOAD_FINISH, - ACT_SECONDARY2_VM_RELOAD2, - ACT_SECONDARY2_VM_DRYFIRE, + ACT_SECONDARY2_VM_RELOAD2, + ACT_SECONDARY2_VM_DRYFIRE, ACT_SECONDARY2_VM_IDLE_TO_LOWERED, ACT_SECONDARY2_VM_IDLE_LOWERED, ACT_SECONDARY2_VM_LOWERED_TO_IDLE, - + ACT_BACKSTAB_VM_UP, ACT_BACKSTAB_VM_DOWN, ACT_BACKSTAB_VM_IDLE, @@ -2068,13 +2108,13 @@ typedef enum ACT_MELEE_ALLCLASS_VM_PULLBACK, ACT_MELEE_ALLCLASS_VM_PRIMARYATTACK, ACT_MELEE_ALLCLASS_VM_SECONDARYATTACK, - ACT_MELEE_ALLCLASS_VM_RELOAD, - ACT_MELEE_ALLCLASS_VM_DRYFIRE, + ACT_MELEE_ALLCLASS_VM_RELOAD, + ACT_MELEE_ALLCLASS_VM_DRYFIRE, ACT_MELEE_ALLCLASS_VM_IDLE_TO_LOWERED, ACT_MELEE_ALLCLASS_VM_IDLE_LOWERED, ACT_MELEE_ALLCLASS_VM_LOWERED_TO_IDLE, ACT_MELEE_ALLCLASS_VM_STUN, - ACT_MELEE_ALLCLASS_VM_HITCENTER, + ACT_MELEE_ALLCLASS_VM_HITCENTER, ACT_MELEE_ALLCLASS_VM_SWINGHARD, // BOMB activities for TD mode. @@ -2091,8 +2131,8 @@ typedef enum ACT_VM_PULLBACK_QRL, ACT_VM_PRIMARYATTACK_QRL, ACT_VM_RELOAD_QRL, - ACT_VM_RELOAD_START_QRL, - ACT_VM_RELOAD_FINISH_QRL, + ACT_VM_RELOAD_START_QRL, + ACT_VM_RELOAD_FINISH_QRL, // Third person anims for the Soldier Quake RL ACT_MP_RELOAD_STAND_PRIMARY3, @@ -2114,101 +2154,568 @@ typedef enum // Spell Animations ACT_SPELL_VM_DRAW, - ACT_SPELL_VM_IDLE, - ACT_SPELL_VM_ARM, + ACT_SPELL_VM_IDLE, + ACT_SPELL_VM_ARM, ACT_SPELL_VM_FIRE, - // Bread Monster Sapper - ACT_BREADSAPPER_VM_DRAW, - ACT_BREADSAPPER_VM_IDLE, - - // Bread Gloves - ACT_BREADGLOVES_VM_HITLEFT, - ACT_BREADGLOVES_VM_HITRIGHT, - ACT_BREADGLOVES_VM_SWINGHARD, - ACT_BREADGLOVES_VM_IDLE, - ACT_BREADGLOVES_VM_DRAW, - - ACT_BREADMONSTER_GLOVES_IDLE, - ACT_BREADMONSTER_GLOVES_HITRIGHT, - ACT_BREADMONSTER_GLOVES_HITUP, - - ACT_BREADMONSTER_VM_DRAW, - ACT_BREADMONSTER_VM_IDLE, - ACT_BREADMONSTER_VM_PRIMARYATTACK, - - ACT_PARACHUTE_DEPLOY, - ACT_PARACHUTE_DEPLOY_IDLE, - ACT_PARACHUTE_RETRACT, - ACT_PARACHUTE_RETRACT_IDLE, - - ACT_BOT_SPAWN, - ACT_BOT_PANIC, - ACT_BOT_PRIMARY_MOVEMENT, - ACT_BOT_GESTURE_FLINCH, - ACT_BOT_PANIC_START, - ACT_BOT_PANIC_END, - - ACT_ENGINEER_REVOLVER_DRAW, - ACT_ENGINEER_REVOLVER_IDLE, - ACT_ENGINEER_REVOLVER_PRIMARYATTACK, - ACT_ENGINEER_REVOLVER_RELOAD, - - // Kart! - ACT_KART_IDLE, - ACT_KART_ACTION_SHOOT, - ACT_KART_ACTION_DASH, - ACT_KART_JUMP_START, - ACT_KART_JUMP_FLOAT, - ACT_KART_JUMP_LAND, - ACT_KART_IMPACT, - ACT_KART_IMPACT_BIG, - ACT_KART_GESTURE_POSITIVE, - ACT_KART_GESTURE_NEGATIVE, - - // grappling hook - ACT_GRAPPLE_DRAW, - ACT_GRAPPLE_IDLE, - ACT_GRAPPLE_FIRE_START, - ACT_GRAPPLE_FIRE_IDLE, - ACT_GRAPPLE_PULL_START, - ACT_GRAPPLE_PULL_IDLE, - ACT_GRAPPLE_PULL_END, - - // inspect - ACT_PRIMARY_VM_INSPECT_START, - ACT_PRIMARY_VM_INSPECT_IDLE, - ACT_PRIMARY_VM_INSPECT_END, - - ACT_SECONDARY_VM_INSPECT_START, - ACT_SECONDARY_VM_INSPECT_IDLE, - ACT_SECONDARY_VM_INSPECT_END, - - ACT_MELEE_VM_INSPECT_START, - ACT_MELEE_VM_INSPECT_IDLE, - ACT_MELEE_VM_INSPECT_END, +#if AR2_ACTIVITY_FIX == 1 + ACT_IDLE_AR2, + ACT_IDLE_ANGRY_AR2, + + ACT_IDLE_AR2_RELAXED, + ACT_IDLE_AR2_STIMULATED, + + ACT_WALK_AR2_RELAXED, + ACT_RUN_AR2_RELAXED, + ACT_WALK_AR2_STIMULATED, + ACT_RUN_AR2_STIMULATED, + + ACT_IDLE_AIM_AR2_STIMULATED, + ACT_WALK_AIM_AR2_STIMULATED, + ACT_RUN_AIM_AR2_STIMULATED, + + ACT_WALK_AR2, + ACT_WALK_AIM_AR2, + ACT_RUN_AR2, + ACT_RUN_AIM_AR2, + + ACT_RELOAD_AR2, + ACT_RELOAD_AR2_LOW, + + ACT_GESTURE_RELOAD_AR2, + + ACT_COVER_AR2_LOW, +#endif + +#if SHARED_COMBINE_ACTIVITIES + ACT_COMBINE_THROW_GRENADE, + ACT_COMBINE_AR2_ALTFIRE, + + // Gesture versions for existing Combine signal and grenade activities + ACT_GESTURE_COMBINE_THROW_GRENADE, + ACT_GESTURE_COMBINE_AR2_ALTFIRE, + ACT_GESTURE_SPECIAL_ATTACK1, + ACT_GESTURE_SPECIAL_ATTACK2, + + ACT_GESTURE_SIGNAL_ADVANCE, + ACT_GESTURE_SIGNAL_FORWARD, + ACT_GESTURE_SIGNAL_GROUP, + ACT_GESTURE_SIGNAL_HALT, + ACT_GESTURE_SIGNAL_LEFT, + ACT_GESTURE_SIGNAL_RIGHT, + ACT_GESTURE_SIGNAL_TAKECOVER, +#endif + +#if EXPANDED_HL2_WEAPON_ACTIVITIES + // Revolver (357) + ACT_IDLE_REVOLVER, + ACT_IDLE_ANGRY_REVOLVER, + ACT_WALK_REVOLVER, + ACT_RUN_REVOLVER, + ACT_WALK_AIM_REVOLVER, + ACT_RUN_AIM_REVOLVER, + ACT_RANGE_ATTACK_REVOLVER, + ACT_RELOAD_REVOLVER, + ACT_RANGE_ATTACK_REVOLVER_LOW, + ACT_RELOAD_REVOLVER_LOW, + ACT_COVER_REVOLVER_LOW, + ACT_RANGE_AIM_REVOLVER_LOW, + ACT_GESTURE_RANGE_ATTACK_REVOLVER, + ACT_GESTURE_RELOAD_REVOLVER, + + // Crossbow + ACT_IDLE_CROSSBOW, + ACT_IDLE_ANGRY_CROSSBOW, + ACT_WALK_CROSSBOW, + ACT_RUN_CROSSBOW, + ACT_WALK_AIM_CROSSBOW, + ACT_RUN_AIM_CROSSBOW, + ACT_RANGE_ATTACK_CROSSBOW, + ACT_RELOAD_CROSSBOW, + ACT_RANGE_ATTACK_CROSSBOW_LOW, + ACT_RELOAD_CROSSBOW_LOW, + ACT_COVER_CROSSBOW_LOW, + ACT_RANGE_AIM_CROSSBOW_LOW, + ACT_GESTURE_RANGE_ATTACK_CROSSBOW, + ACT_GESTURE_RELOAD_CROSSBOW, + + ACT_IDLE_CROSSBOW_RELAXED, + ACT_IDLE_CROSSBOW_STIMULATED, + ACT_WALK_CROSSBOW_RELAXED, + ACT_RUN_CROSSBOW_RELAXED, + ACT_WALK_CROSSBOW_STIMULATED, + ACT_RUN_CROSSBOW_STIMULATED, + + ACT_IDLE_AIM_CROSSBOW_STIMULATED, + ACT_WALK_AIM_CROSSBOW_STIMULATED, + ACT_RUN_AIM_CROSSBOW_STIMULATED, + + // Pistol + ACT_IDLE_PISTOL_RELAXED, + ACT_IDLE_PISTOL_STIMULATED, + ACT_WALK_PISTOL_RELAXED, + ACT_WALK_PISTOL_STIMULATED, + ACT_RUN_PISTOL_RELAXED, + ACT_RUN_PISTOL_STIMULATED, + + ACT_IDLE_AIM_PISTOL_STIMULATED, + ACT_WALK_AIM_PISTOL_STIMULATED, + ACT_RUN_AIM_PISTOL_STIMULATED, + + ACT_WALK_CROUCH_PISTOL, + ACT_WALK_CROUCH_AIM_PISTOL, + ACT_RUN_CROUCH_PISTOL, + ACT_RUN_CROUCH_AIM_PISTOL, + + // Shotgun + ACT_IDLE_SHOTGUN, + ACT_WALK_SHOTGUN, + ACT_RUN_SHOTGUN, + + ACT_COVER_SHOTGUN_LOW, + ACT_RANGE_AIM_SHOTGUN_LOW, + + ACT_WALK_SHOTGUN_RELAXED, + ACT_WALK_SHOTGUN_STIMULATED, + ACT_RUN_SHOTGUN_RELAXED, + ACT_RUN_SHOTGUN_STIMULATED, + + ACT_IDLE_AIM_SHOTGUN_STIMULATED, + ACT_WALK_AIM_SHOTGUN_STIMULATED, + ACT_RUN_AIM_SHOTGUN_STIMULATED, + + // RPG + ACT_RANGE_AIM_RPG_LOW, + ACT_RANGE_ATTACK_RPG_LOW, + ACT_GESTURE_RANGE_ATTACK_RPG, + + // Annabelle + ACT_RANGE_ATTACK_ANNABELLE, + ACT_RANGE_ATTACK_ANNABELLE_LOW, + ACT_GESTURE_RANGE_ATTACK_ANNABELLE, + ACT_RELOAD_ANNABELLE, + ACT_RELOAD_ANNABELLE_LOW, + ACT_GESTURE_RELOAD_ANNABELLE, + + // Melee + ACT_WALK_MELEE, + ACT_RUN_MELEE, + + // Citizen accessories + ACT_RUN_PACKAGE, + ACT_RUN_SUITCASE, + + // Holster/Unholster + ACT_ARM_RIFLE, + ACT_ARM_SHOTGUN, + ACT_ARM_RPG, + ACT_ARM_MELEE, + ACT_DISARM_RIFLE, + ACT_DISARM_SHOTGUN, + ACT_DISARM_RPG, + ACT_DISARM_MELEE, +#endif + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // AR1 + ACT_IDLE_AR1, + ACT_IDLE_ANGRY_AR1, + ACT_WALK_AR1, + ACT_RUN_AR1, + ACT_WALK_AIM_AR1, + ACT_RUN_AIM_AR1, + //ACT_RANGE_ATTACK_AR1, + ACT_RELOAD_AR1, + ACT_RANGE_ATTACK_AR1_LOW, + ACT_RELOAD_AR1_LOW, + ACT_COVER_AR1_LOW, + ACT_RANGE_AIM_AR1_LOW, + //ACT_GESTURE_RANGE_ATTACK_AR1, + ACT_GESTURE_RELOAD_AR1, + + ACT_IDLE_AR1_RELAXED, + ACT_IDLE_AR1_STIMULATED, + ACT_WALK_AR1_RELAXED, + ACT_RUN_AR1_RELAXED, + ACT_WALK_AR1_STIMULATED, + ACT_RUN_AR1_STIMULATED, + + ACT_IDLE_AIM_AR1_STIMULATED, + ACT_WALK_AIM_AR1_STIMULATED, + ACT_RUN_AIM_AR1_STIMULATED, + + // AR3 (new) + ACT_IDLE_AR3, + ACT_IDLE_ANGRY_AR3, + ACT_WALK_AR3, + ACT_RUN_AR3, + ACT_WALK_AIM_AR3, + ACT_RUN_AIM_AR3, + ACT_RANGE_ATTACK_AR3, + ACT_RELOAD_AR3, + ACT_RANGE_ATTACK_AR3_LOW, + ACT_RELOAD_AR3_LOW, + ACT_COVER_AR3_LOW, + ACT_RANGE_AIM_AR3_LOW, + ACT_GESTURE_RANGE_ATTACK_AR3, + ACT_GESTURE_RELOAD_AR3, + + ACT_IDLE_AR3_RELAXED, + ACT_IDLE_AR3_STIMULATED, + ACT_WALK_AR3_RELAXED, + ACT_RUN_AR3_RELAXED, + ACT_WALK_AR3_STIMULATED, + ACT_RUN_AR3_STIMULATED, + + ACT_IDLE_AIM_AR3_STIMULATED, + ACT_WALK_AIM_AR3_STIMULATED, + ACT_RUN_AIM_AR3_STIMULATED, + + // SMG2 + ACT_IDLE_SMG2, + ACT_IDLE_ANGRY_SMG2, + ACT_WALK_SMG2, + ACT_RUN_SMG2, + ACT_WALK_AIM_SMG2, + ACT_RUN_AIM_SMG2, + //ACT_RANGE_ATTACK_SMG2, + ACT_RELOAD_SMG2, + ACT_RANGE_ATTACK_SMG2_LOW, + ACT_RELOAD_SMG2_LOW, + ACT_COVER_SMG2_LOW, + ACT_RANGE_AIM_SMG2_LOW, + //ACT_GESTURE_RANGE_ATTACK_SMG2, + ACT_GESTURE_RELOAD_SMG2, + + ACT_IDLE_SMG2_RELAXED, + ACT_IDLE_SMG2_STIMULATED, + ACT_WALK_SMG2_RELAXED, + ACT_RUN_SMG2_RELAXED, + ACT_WALK_SMG2_STIMULATED, + ACT_RUN_SMG2_STIMULATED, + + ACT_IDLE_AIM_SMG2_STIMULATED, + ACT_WALK_AIM_SMG2_STIMULATED, + ACT_RUN_AIM_SMG2_STIMULATED, + + // SMG3 (new) + ACT_IDLE_SMG3, + ACT_IDLE_ANGRY_SMG3, + ACT_WALK_SMG3, + ACT_RUN_SMG3, + ACT_WALK_AIM_SMG3, + ACT_RUN_AIM_SMG3, + ACT_RANGE_ATTACK_SMG3, + ACT_RELOAD_SMG3, + ACT_RANGE_ATTACK_SMG3_LOW, + ACT_RELOAD_SMG3_LOW, + ACT_COVER_SMG3_LOW, + ACT_RANGE_AIM_SMG3_LOW, + ACT_GESTURE_RANGE_ATTACK_SMG3, + ACT_GESTURE_RELOAD_SMG3, + + ACT_IDLE_SMG3_RELAXED, + ACT_IDLE_SMG3_STIMULATED, + ACT_WALK_SMG3_RELAXED, + ACT_RUN_SMG3_RELAXED, + ACT_WALK_SMG3_STIMULATED, + ACT_RUN_SMG3_STIMULATED, + + ACT_IDLE_AIM_SMG3_STIMULATED, + ACT_WALK_AIM_SMG3_STIMULATED, + ACT_RUN_AIM_SMG3_STIMULATED, + + // HMG1 + ACT_IDLE_HMG1, + ACT_IDLE_ANGRY_HMG1, + ACT_WALK_HMG1, + ACT_RUN_HMG1, + ACT_WALK_AIM_HMG1, + ACT_RUN_AIM_HMG1, + //ACT_RANGE_ATTACK_HMG1, + ACT_RELOAD_HMG1, + ACT_RANGE_ATTACK_HMG1_LOW, + ACT_RELOAD_HMG1_LOW, + ACT_COVER_HMG1_LOW, + ACT_RANGE_AIM_HMG1_LOW, + //ACT_GESTURE_RANGE_ATTACK_HMG1, + ACT_GESTURE_RELOAD_HMG1, + + ACT_IDLE_HMG1_RELAXED, + ACT_IDLE_HMG1_STIMULATED, + ACT_WALK_HMG1_RELAXED, + ACT_RUN_HMG1_RELAXED, + ACT_WALK_HMG1_STIMULATED, + ACT_RUN_HMG1_STIMULATED, + + ACT_IDLE_AIM_HMG1_STIMULATED, + ACT_WALK_AIM_HMG1_STIMULATED, + ACT_RUN_AIM_HMG1_STIMULATED, + + // Sniper Rifle + ACT_IDLE_SNIPER_RIFLE, + ACT_IDLE_ANGRY_SNIPER_RIFLE, + ACT_WALK_SNIPER_RIFLE, + ACT_RUN_SNIPER_RIFLE, + ACT_WALK_AIM_SNIPER_RIFLE, + ACT_RUN_AIM_SNIPER_RIFLE, + //ACT_RANGE_ATTACK_SNIPER_RIFLE, + ACT_RELOAD_SNIPER_RIFLE, + ACT_RANGE_ATTACK_SNIPER_RIFLE_LOW, + ACT_RELOAD_SNIPER_RIFLE_LOW, + ACT_COVER_SNIPER_RIFLE_LOW, + ACT_RANGE_AIM_SNIPER_RIFLE_LOW, + //ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE, + ACT_GESTURE_RELOAD_SNIPER_RIFLE, + + ACT_IDLE_SNIPER_RIFLE_RELAXED, + ACT_IDLE_SNIPER_RIFLE_STIMULATED, + ACT_WALK_SNIPER_RIFLE_RELAXED, + ACT_RUN_SNIPER_RIFLE_RELAXED, + ACT_WALK_SNIPER_RIFLE_STIMULATED, + ACT_RUN_SNIPER_RIFLE_STIMULATED, + + ACT_IDLE_AIM_SNIPER_RIFLE_STIMULATED, + ACT_WALK_AIM_SNIPER_RIFLE_STIMULATED, + ACT_RUN_AIM_SNIPER_RIFLE_STIMULATED, + + // Dual Pistols + ACT_IDLE_DUAL_PISTOLS, + ACT_IDLE_ANGRY_DUAL_PISTOLS, + ACT_WALK_DUAL_PISTOLS, + ACT_RUN_DUAL_PISTOLS, + ACT_WALK_AIM_DUAL_PISTOLS, + ACT_RUN_AIM_DUAL_PISTOLS, + ACT_RANGE_ATTACK_DUAL_PISTOLS, + ACT_RELOAD_DUAL_PISTOLS, + ACT_RANGE_ATTACK_DUAL_PISTOLS_LOW, + ACT_RELOAD_DUAL_PISTOLS_LOW, + ACT_COVER_DUAL_PISTOLS_LOW, + ACT_RANGE_AIM_DUAL_PISTOLS_LOW, + ACT_GESTURE_RANGE_ATTACK_DUAL_PISTOLS, + ACT_GESTURE_RELOAD_DUAL_PISTOLS, + + ACT_IDLE_DUAL_PISTOLS_RELAXED, + ACT_IDLE_DUAL_PISTOLS_STIMULATED, + ACT_WALK_DUAL_PISTOLS_RELAXED, + ACT_RUN_DUAL_PISTOLS_RELAXED, + ACT_WALK_DUAL_PISTOLS_STIMULATED, + ACT_RUN_DUAL_PISTOLS_STIMULATED, + + ACT_IDLE_AIM_DUAL_PISTOLS_STIMULATED, + ACT_WALK_AIM_DUAL_PISTOLS_STIMULATED, + ACT_RUN_AIM_DUAL_PISTOLS_STIMULATED, +#endif + +#if EXPANDED_NAVIGATION_ACTIVITIES + ACT_CLIMB_ALL, // An actual blend animation which uses pose parameters for direction + ACT_CLIMB_IDLE, + + ACT_CLIMB_MOUNT_TOP, + ACT_CLIMB_MOUNT_BOTTOM, + ACT_CLIMB_DISMOUNT_BOTTOM, +#endif + +#if EXPANDED_HL2_COVER_ACTIVITIES + // Crouch Cover Medium + ACT_RANGE_ATTACK1_MED, + ACT_RANGE_ATTACK2_MED, + ACT_RANGE_AIM_MED, + + ACT_RANGE_ATTACK_AR2_MED, + ACT_RANGE_ATTACK_SMG1_MED, + ACT_RANGE_ATTACK_SHOTGUN_MED, + ACT_RANGE_ATTACK_PISTOL_MED, + ACT_RANGE_ATTACK_RPG_MED, + ACT_RANGE_ATTACK_REVOLVER_MED, + ACT_RANGE_ATTACK_CROSSBOW_MED, + + ACT_RANGE_AIM_AR2_MED, + ACT_RANGE_AIM_SMG1_MED, + ACT_RANGE_AIM_SHOTGUN_MED, + ACT_RANGE_AIM_PISTOL_MED, + ACT_RANGE_AIM_RPG_MED, + ACT_RANGE_AIM_REVOLVER_MED, + ACT_RANGE_AIM_CROSSBOW_MED, + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // MED activities for unused weapons + ACT_RANGE_AIM_AR1_MED, + ACT_RANGE_ATTACK_AR1_MED, + ACT_RANGE_AIM_AR3_MED, + ACT_RANGE_ATTACK_AR3_MED, + ACT_RANGE_AIM_SMG2_MED, + ACT_RANGE_ATTACK_SMG2_MED, + ACT_RANGE_AIM_SMG3_MED, + ACT_RANGE_ATTACK_SMG3_MED, + ACT_RANGE_AIM_HMG1_MED, + ACT_RANGE_ATTACK_HMG1_MED, + ACT_RANGE_AIM_SNIPER_RIFLE_MED, + ACT_RANGE_ATTACK_SNIPER_RIFLE_MED, + ACT_RANGE_AIM_DUAL_PISTOLS_MED, + ACT_RANGE_ATTACK_DUAL_PISTOLS_MED, +#endif + + // Wall Cover (for use in custom cover hints) + ACT_COVER_WALL_R, + ACT_COVER_WALL_L, + ACT_COVER_WALL_LOW_R, + ACT_COVER_WALL_LOW_L, + + ACT_COVER_WALL_R_RIFLE, + ACT_COVER_WALL_L_RIFLE, + ACT_COVER_WALL_LOW_R_RIFLE, + ACT_COVER_WALL_LOW_L_RIFLE, + + ACT_COVER_WALL_R_PISTOL, + ACT_COVER_WALL_L_PISTOL, + ACT_COVER_WALL_LOW_R_PISTOL, + ACT_COVER_WALL_LOW_L_PISTOL, +#endif + +#if EXPANDED_HL2DM_ACTIVITIES + ACT_HL2MP_WALK, + ACT_HL2MP_WALK_PISTOL, + ACT_HL2MP_WALK_SHOTGUN, + ACT_HL2MP_WALK_SMG1, + ACT_HL2MP_WALK_AR2, + ACT_HL2MP_WALK_PHYSGUN, + ACT_HL2MP_WALK_GRENADE, + ACT_HL2MP_WALK_RPG, + ACT_HL2MP_WALK_CROSSBOW, + ACT_HL2MP_WALK_MELEE, + ACT_HL2MP_WALK_SLAM, + + ACT_HL2MP_GESTURE_RANGE_ATTACK2, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_PISTOL, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SHOTGUN, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG1, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR2, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_PHYSGUN, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_GRENADE, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_RPG, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_CROSSBOW, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM, + + ACT_HL2MP_IDLE_REVOLVER, + ACT_HL2MP_RUN_REVOLVER, + ACT_HL2MP_WALK_REVOLVER, + ACT_HL2MP_IDLE_CROUCH_REVOLVER, + ACT_HL2MP_WALK_CROUCH_REVOLVER, + ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER, + ACT_HL2MP_GESTURE_RELOAD_REVOLVER, + ACT_HL2MP_JUMP_REVOLVER, + +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + // Player activities for unused weapons + ACT_HL2MP_IDLE_AR1, + ACT_HL2MP_RUN_AR1, + ACT_HL2MP_WALK_AR1, + ACT_HL2MP_IDLE_CROUCH_AR1, + ACT_HL2MP_WALK_CROUCH_AR1, + ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1, + ACT_HL2MP_GESTURE_RELOAD_AR1, + ACT_HL2MP_JUMP_AR1, + + ACT_HL2MP_IDLE_AR3, + ACT_HL2MP_RUN_AR3, + ACT_HL2MP_WALK_AR3, + ACT_HL2MP_IDLE_CROUCH_AR3, + ACT_HL2MP_WALK_CROUCH_AR3, + ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3, + ACT_HL2MP_GESTURE_RELOAD_AR3, + ACT_HL2MP_JUMP_AR3, + + ACT_HL2MP_IDLE_SMG2, + ACT_HL2MP_RUN_SMG2, + ACT_HL2MP_WALK_SMG2, + ACT_HL2MP_IDLE_CROUCH_SMG2, + ACT_HL2MP_WALK_CROUCH_SMG2, + ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2, + ACT_HL2MP_GESTURE_RELOAD_SMG2, + ACT_HL2MP_JUMP_SMG2, + + ACT_HL2MP_IDLE_SMG3, + ACT_HL2MP_RUN_SMG3, + ACT_HL2MP_WALK_SMG3, + ACT_HL2MP_IDLE_CROUCH_SMG3, + ACT_HL2MP_WALK_CROUCH_SMG3, + ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3, + ACT_HL2MP_GESTURE_RELOAD_SMG3, + ACT_HL2MP_JUMP_SMG3, + + ACT_HL2MP_IDLE_HMG1, + ACT_HL2MP_RUN_HMG1, + ACT_HL2MP_WALK_HMG1, + ACT_HL2MP_IDLE_CROUCH_HMG1, + ACT_HL2MP_WALK_CROUCH_HMG1, + ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1, + ACT_HL2MP_GESTURE_RELOAD_HMG1, + ACT_HL2MP_JUMP_HMG1, + + ACT_HL2MP_IDLE_SNIPER_RIFLE, + ACT_HL2MP_RUN_SNIPER_RIFLE, + ACT_HL2MP_WALK_SNIPER_RIFLE, + ACT_HL2MP_IDLE_CROUCH_SNIPER_RIFLE, + ACT_HL2MP_WALK_CROUCH_SNIPER_RIFLE, + ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE, + ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE, + ACT_HL2MP_JUMP_SNIPER_RIFLE, + + ACT_HL2MP_IDLE_DUAL_PISTOLS, + ACT_HL2MP_RUN_DUAL_PISTOLS, + ACT_HL2MP_WALK_DUAL_PISTOLS, + ACT_HL2MP_IDLE_CROUCH_DUAL_PISTOLS, + ACT_HL2MP_WALK_CROUCH_DUAL_PISTOLS, + ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS, + ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS, + ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS, + ACT_HL2MP_JUMP_DUAL_PISTOLS, +#endif + + ACT_HL2MP_IDLE_USE, + ACT_HL2MP_RUN_USE, + ACT_HL2MP_WALK_USE, + ACT_HL2MP_IDLE_CROUCH_USE, + ACT_HL2MP_WALK_CROUCH_USE, + ACT_HL2MP_JUMP_USE, + + ACT_HL2MP_IDLE_USE_HEAVY, + ACT_HL2MP_RUN_USE_HEAVY, + ACT_HL2MP_WALK_USE_HEAVY, + ACT_HL2MP_IDLE_CROUCH_USE_HEAVY, + ACT_HL2MP_WALK_CROUCH_USE_HEAVY, + ACT_HL2MP_JUMP_USE_HEAVY, +#endif #ifdef VANCE - ACT_VM_WALK, - ACT_VM_SPRINT, - ACT_VM_FIRSTDRAW, - ACT_VM_LAND, - ACT_VM_KICK, - ACT_VM_EXTEND, - ACT_VM_IDLE_EXTENDED, - ACT_VM_DRAW_EXTENDED, - ACT_VM_RELOAD_EXTENDED, - ACT_VM_SPRINT_EXTENDED, - ACT_VM_FIRE_EXTENDED, - ACT_VM_WALK_EXTENDED, - ACT_VM_HOLSTER_EXTENDED, - ACT_VM_KICK_EXTENDED, - ACT_VM_RETRACT, - - ACT_VM_SWING_LEFT, - ACT_VM_SWING_RIGHT, - ACT_VM_IDLE_TO_THROW, - ACT_VM_THROW_IDLE, + ACT_VM_WALK, + ACT_VM_SPRINT, + ACT_VM_FIRSTDRAW, + ACT_VM_LAND, + ACT_VM_KICK, + ACT_VM_EXTEND, + ACT_VM_IDLE_EXTENDED, + ACT_VM_DRAW_EXTENDED, + ACT_VM_RELOAD_EXTENDED, + ACT_VM_SPRINT_EXTENDED, + ACT_VM_FIRE_EXTENDED, + ACT_VM_WALK_EXTENDED, + ACT_VM_HOLSTER_EXTENDED, + ACT_VM_KICK_EXTENDED, + ACT_VM_RETRACT, + ACT_VM_SWING_LEFT, + ACT_VM_SWING_RIGHT, + ACT_VM_IDLE_TO_THROW, + ACT_VM_THROW_IDLE, #endif // this is the end of the global activities, private per-monster activities start here. diff --git a/game/shared/ai_criteria_new.cpp b/game/shared/ai_criteria_new.cpp new file mode 100644 index 00000000..837c61aa --- /dev/null +++ b/game/shared/ai_criteria_new.cpp @@ -0,0 +1,38 @@ +//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "cbase.h" +#include "AI_Criteria.h" + +#ifdef GAME_DLL +#include "ai_speech.h" +#endif + +#include +#include "engine/IEngineSound.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include + + + +BEGIN_SIMPLE_DATADESC( AI_ResponseParams ) + DEFINE_FIELD( flags, FIELD_SHORT ), + DEFINE_FIELD( odds, FIELD_SHORT ), + DEFINE_FIELD( soundlevel, FIELD_CHARACTER ), + DEFINE_FIELD( delay, FIELD_INTEGER ), // These are compressed down to two float16s, so treat as an INT for saverestore + DEFINE_FIELD( respeakdelay, FIELD_INTEGER ), // +END_DATADESC() + +BEGIN_SIMPLE_DATADESC( AI_Response ) + DEFINE_FIELD( m_Type, FIELD_CHARACTER ), + DEFINE_ARRAY( m_szResponseName, FIELD_CHARACTER, AI_Response::MAX_RESPONSE_NAME ), + DEFINE_ARRAY( m_szMatchingRule, FIELD_CHARACTER, AI_Response::MAX_RULE_NAME ), + // DEFINE_FIELD( m_pCriteria, FIELD_??? ), // Don't need to save this probably + DEFINE_EMBEDDED( m_Params ), +END_DATADESC() + diff --git a/game/shared/ai_criteria_new.h b/game/shared/ai_criteria_new.h new file mode 100644 index 00000000..b5d2c4fd --- /dev/null +++ b/game/shared/ai_criteria_new.h @@ -0,0 +1,41 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef AI_CRITERIA_H +#define AI_CRITERIA_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/interval.h" +#include "mathlib/compressed_vector.h" +#include "../../public/responserules/response_types.h" + + +using ResponseRules::ResponseType_t; + +extern const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration, const char *entireContext ); + +#ifndef AI_CriteriaSet +#define AI_CriteriaSet ResponseRules::CriteriaSet +#endif + +typedef ResponseRules::ResponseParams AI_ResponseParams ; +typedef ResponseRules::CRR_Response AI_Response; + + + +/* +// An AI response that is dynamically new'ed up and returned from SpeakFindResponse. +class AI_ResponseReturnValue : AI_Response +{ + +}; +*/ + +#endif // AI_CRITERIA_H diff --git a/game/shared/ai_responsesystem_new.cpp b/game/shared/ai_responsesystem_new.cpp new file mode 100644 index 00000000..b639f270 --- /dev/null +++ b/game/shared/ai_responsesystem_new.cpp @@ -0,0 +1,1388 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + + +#include "cbase.h" +#include "SoundEmitterSystem/isoundemittersystembase.h" +#include "AI_ResponseSystem.h" +#include "igamesystem.h" +#include "AI_Criteria.h" +#include +#include "filesystem.h" +#include "utldict.h" +#ifdef GAME_DLL +#include "ai_speech.h" +#endif +#include "tier0/icommandline.h" +#include +#include "isaverestore.h" +#include "utlbuffer.h" +#include "stringpool.h" +#include "fmtstr.h" +#include "multiplay_gamerules.h" +#include "characterset.h" +#include "responserules/response_host_interface.h" +#include "../../responserules/runtime/response_types_internal.h" + +#include "scenefilecache/ISceneFileCache.h" + +#ifdef GAME_DLL +#include "sceneentity.h" +#endif + +#include "networkstringtabledefs.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#undef IResponseSystem +using namespace ResponseRules; + +extern ConVar rr_debugresponses; // ( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose matching output (1 for simple, 2 for rule scoring, 3 for noisy). If set to 4, it will only show response success/failure for npc_selected NPCs." ); +extern ConVar rr_debugrule; // ( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); +extern ConVar rr_dumpresponses; // ( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +extern ConVar rr_debugresponseconcept; // ( "rr_debugresponseconcept", "", FCVAR_NONE, "If set, rr_debugresponses will print only responses testing for the specified concept" ); + +static void CC_RR_DumpHashInfo( const CCommand &args ); + +#ifdef MAPBASE +ConVar rr_enhanced_saverestore( "rr_enhanced_saverestore", "0", FCVAR_NONE, "Enables enhanced save/restore capabilities for the Response System." ); +#endif + +extern ISceneFileCache *scenefilecache; +extern INetworkStringTable *g_pStringTableClientSideChoreoScenes; + +static characterset_t g_BreakSetIncludingColons; + +// Simple class to initialize breakset +class CBreakInit +{ +public: + CBreakInit() + { + CharacterSetBuild( &g_BreakSetIncludingColons, "{}()':" ); + } +} g_BreakInit; + +inline char rr_tolower( char c ) +{ + if ( c >= 'A' && c <= 'Z' ) + return c - 'A' + 'a'; + return c; +} +// BUG BUG: Note that this function doesn't check for data overruns!!! +// Also, this function lowercases the token as it parses!!! +inline const char *RR_Parse(const char *data, char *token ) +{ + unsigned char c; + int len; + characterset_t *breaks = &g_BreakSetIncludingColons; + len = 0; + token[0] = 0; + + if (!data) + return NULL; + + // skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file; + data++; + } + + // skip // comments + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + + + // handle quoted strings specially + if (c == '\"') + { + data++; + while (1) + { + c = rr_tolower( *data++ ); + if (c=='\"' || !c) + { + token[len] = 0; + return data; + } + token[len] = c; + len++; + } + } + + // parse single characters + if ( IN_CHARACTERSET( *breaks, c ) ) + { + token[len] = c; + len++; + token[len] = 0; + return data+1; + } + + // parse a regular word + do + { + token[len] = rr_tolower( c ); + data++; + len++; + c = rr_tolower( *data ); + if ( IN_CHARACTERSET( *breaks, c ) ) + break; + } while (c>32); + + token[len] = 0; + return data; +} + +#ifdef MAPBASE +// A version of the above which preserves casing and supports escaped quotes +inline const char *RR_Parse_Preserve(const char *data, char *token ) +{ + unsigned char c; + int len; + characterset_t *breaks = &g_BreakSetIncludingColons; + len = 0; + token[0] = 0; + + if (!data) + return NULL; + + // skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file; + data++; + } + + // skip // comments + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + + // handle quoted strings specially + if (c == '\"') + { + bool escaped = false; + data++; + while (1) + { + c = *data++; + if ((c=='\"' && !escaped) || !c) + { + token[len] = 0; + return data; + } + else if (c != '\"' && escaped) + { + // Not an escape character, just a back slash + token[len] = '\\'; + len++; + } + + escaped = (c == '\\'); + if (!escaped) + { + token[len] = c; + len++; + } + } + } + + // parse single characters + if ( IN_CHARACTERSET( *breaks, c ) ) + { + token[len] = c; + len++; + token[len] = 0; + return data+1; + } + + // parse a regular word + do + { + token[len] = c; + data++; + len++; + c = *data; + if ( IN_CHARACTERSET( *breaks, c ) ) + break; + } while (c>32); + + token[len] = 0; + return data; +} +#endif + +namespace ResponseRules +{ + extern const char *ResponseCopyString( const char *in ); +} + +// Host functions required by the ResponseRules::IEngineEmulator interface +class CResponseRulesToEngineInterface : public ResponseRules::IEngineEmulator +{ + /// Given an input text buffer data pointer, parses a single token into the variable token and returns the new + /// reading position + virtual const char *ParseFile( const char *data, char *token, int maxlen ) + { + NOTE_UNUSED( maxlen ); + return RR_Parse( data, token ); + } + +#ifdef MAPBASE + /// (Optional) Same as ParseFile, but with casing preserved and escaped quotes supported + virtual const char *ParseFilePreserve( const char *data, char *token, int maxlen ) + { + NOTE_UNUSED( maxlen ); + return RR_Parse_Preserve( data, token ); + } +#endif + + /// Return a pointer to an IFileSystem we can use to read and process scripts. + virtual IFileSystem *GetFilesystem() + { + return filesystem; + } + + /// Return a pointer to an instance of an IUniformRandomStream + virtual IUniformRandomStream *GetRandomStream() + { + return random; + } + + /// Return a pointer to a tier0 ICommandLine + virtual ICommandLine *GetCommandLine() + { + return CommandLine(); + } + + /// Emulates the server's UTIL_LoadFileForMe + virtual byte *LoadFileForMe( const char *filename, int *pLength ) + { + return UTIL_LoadFileForMe( filename, pLength ); + } + + /// Emulates the server's UTIL_FreeFile + virtual void FreeFile( byte *buffer ) + { + return UTIL_FreeFile( buffer ); + } + +}; + +CResponseRulesToEngineInterface g_ResponseRulesEngineWrapper; +IEngineEmulator *IEngineEmulator::s_pSingleton = &g_ResponseRulesEngineWrapper; + + +BEGIN_SIMPLE_DATADESC( ParserResponse ) + // DEFINE_FIELD( type, FIELD_INTEGER ), + // DEFINE_ARRAY( value, FIELD_CHARACTER ), + // DEFINE_FIELD( weight, FIELD_FLOAT ), + DEFINE_FIELD( depletioncount, FIELD_CHARACTER ), + // DEFINE_FIELD( first, FIELD_BOOLEAN ), + // DEFINE_FIELD( last, FIELD_BOOLEAN ), +END_DATADESC() + + +BEGIN_SIMPLE_DATADESC( ResponseGroup ) + // DEFINE_FIELD( group, FIELD_UTLVECTOR ), + // DEFINE_FIELD( rp, FIELD_EMBEDDED ), + // DEFINE_FIELD( m_bDepleteBeforeRepeat, FIELD_BOOLEAN ), + DEFINE_FIELD( m_nDepletionCount, FIELD_CHARACTER ), + // DEFINE_FIELD( m_bHasFirst, FIELD_BOOLEAN ), + // DEFINE_FIELD( m_bHasLast, FIELD_BOOLEAN ), + // DEFINE_FIELD( m_bSequential, FIELD_BOOLEAN ), + // DEFINE_FIELD( m_bNoRepeat, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), + DEFINE_FIELD( m_nCurrentIndex, FIELD_CHARACTER ), +END_DATADESC() + + +/// Add some game-specific code to the basic response system +/// (eg, the scene precacher, which requires the client and server +/// to work) + +class CGameResponseSystem : public CResponseSystem +{ +public: + CGameResponseSystem(); + + virtual void Precache(); + virtual void PrecacheResponses( bool bEnable ) + { + m_bPrecache = bEnable; + } + bool ShouldPrecache() { return m_bPrecache; } + +protected: + bool m_bPrecache; +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CGameResponseSystem::CGameResponseSystem() : m_bPrecache(true) +{}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +#if 0 +class CScenePrecacheSystem : public CAutoGameSystem +{ +public: + CScenePrecacheSystem() : CAutoGameSystem( "CScenePrecacheSystem" ), m_RepeatCounts( 0, 0, DefLessFunc( int ) ) + { + } + + // Level init, shutdown + virtual void LevelShutdownPreEntity() + { + m_RepeatCounts.Purge(); + } + + bool ShouldPrecache( char const *pszScene ) + { + int hash = HashStringCaselessConventional( pszScene ); + + int slot = m_RepeatCounts.Find( hash ); + if ( slot != m_RepeatCounts.InvalidIndex() ) + { + m_RepeatCounts[ slot ]++; + return false; + } + + m_RepeatCounts.Insert( hash, 0 ); + return true; + } + +private: + + CUtlMap< int, int > m_RepeatCounts; +}; + +static CScenePrecacheSystem g_ScenePrecacheSystem; +//----------------------------------------------------------------------------- +// Purpose: Used for precaching instanced scenes +// Input : *pszScene - +//----------------------------------------------------------------------------- +void PrecacheInstancedScene( char const *pszScene ) +{ + static int nMakingReslists = -1; + + if ( !g_ScenePrecacheSystem.ShouldPrecache( pszScene ) ) + return; + + if ( nMakingReslists == -1 ) + { + nMakingReslists = CommandLine()->FindParm( "-makereslists" ) > 0 ? 1 : 0; + } + + if ( nMakingReslists == 1 ) + { + // Just stat the file to add to reslist + g_pFullFileSystem->Size( pszScene ); + } + + // verify existence, cache is pre-populated, should be there + SceneCachedData_t sceneData; + if ( !scenefilecache->GetSceneCachedData( pszScene, &sceneData ) ) + { + // Scenes are sloppy and don't always exist. + // A scene that is not in the pre-built cache image, but on disk, is a true error. + if ( IsX360() && ( g_pFullFileSystem->GetDVDMode() != DVDMODE_STRICT ) && g_pFullFileSystem->FileExists( pszScene, "GAME" ) ) + { + Warning( "PrecacheInstancedScene: Missing scene '%s' from scene image cache.\nRebuild scene image cache!\n", pszScene ); + } + } + else + { + for ( int i = 0; i < sceneData.numSounds; ++i ) + { + short stringId = scenefilecache->GetSceneCachedSound( sceneData.sceneId, i ); + CBaseEntity::PrecacheScriptSound( scenefilecache->GetSceneString( stringId ) ); + } + } + + g_pStringTableClientSideChoreoScenes->AddString( CBaseEntity::IsServer(), pszScene ); +} +#endif + +static void TouchFile( char const *pchFileName ) +{ + IEngineEmulator::Get()->GetFilesystem()->Size( pchFileName ); +} + +void CGameResponseSystem::Precache() +{ + bool bTouchFiles = CommandLine()->FindParm( "-makereslists" ) != 0; + + // enumerate and mark all the scripts so we know they're referenced + for ( int i = 0; i < (int)m_Responses.Count(); i++ ) + { + ResponseGroup &group = m_Responses[i]; + + for ( int j = 0; j < group.group.Count(); j++) + { + ParserResponse &response = group.group[j]; + + switch ( response.type ) + { + default: + break; + case RESPONSE_SCENE: + { + // fixup $gender references + char file[_MAX_PATH]; + Q_strncpy( file, response.value, sizeof(file) ); + char *gender = strstr( file, "$gender" ); + if ( gender ) + { + // replace with male & female + const char *postGender = gender + strlen("$gender"); + *gender = 0; + char genderFile[_MAX_PATH]; + // male + Q_snprintf( genderFile, sizeof(genderFile), "%smale%s", file, postGender); + + PrecacheInstancedScene( genderFile ); + if ( bTouchFiles ) + { + TouchFile( genderFile ); + } + + Q_snprintf( genderFile, sizeof(genderFile), "%sfemale%s", file, postGender); + + PrecacheInstancedScene( genderFile ); + if ( bTouchFiles ) + { + TouchFile( genderFile ); + } + } + else + { + PrecacheInstancedScene( file ); + if ( bTouchFiles ) + { + TouchFile( file ); + } + } + } + break; + case RESPONSE_SPEAK: + { + CBaseEntity::PrecacheScriptSound( response.value ); + } + break; + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: A special purpose response system associated with a custom entity +//----------------------------------------------------------------------------- +class CInstancedResponseSystem : public CGameResponseSystem +{ + typedef CGameResponseSystem BaseClass; + +public: + CInstancedResponseSystem( const char *scriptfile ) : + m_pszScriptFile( 0 ) + { + Assert( scriptfile ); + + int len = Q_strlen( scriptfile ) + 1; + m_pszScriptFile = new char[ len ]; + Assert( m_pszScriptFile ); + Q_strncpy( m_pszScriptFile, scriptfile, len ); + } + + ~CInstancedResponseSystem() + { + delete[] m_pszScriptFile; + } + virtual const char *GetScriptFile( void ) + { + Assert( m_pszScriptFile ); + return m_pszScriptFile; + } + + // CAutoGameSystem + virtual bool Init() + { + const char *basescript = GetScriptFile(); + LoadRuleSet( basescript ); + return true; + } + + virtual void LevelInitPostEntity() + { +#ifdef MAPBASE + if (!rr_enhanced_saverestore.GetBool() || gpGlobals->eLoadType != MapLoad_Transition) +#endif + ResetResponseGroups(); + } + + virtual void Release() + { + Clear(); + delete this; + } +private: + + char *m_pszScriptFile; +}; + +//----------------------------------------------------------------------------- +// Purpose: The default response system for expressive AIs +//----------------------------------------------------------------------------- +class CDefaultResponseSystem : public CGameResponseSystem, public CAutoGameSystem +{ + typedef CAutoGameSystem BaseClass; + +public: + CDefaultResponseSystem() : CAutoGameSystem( "CDefaultResponseSystem" ) + { + } + + virtual const char *GetScriptFile( void ) + { + return "scripts/talker/response_rules.txt"; + } + + // CAutoServerSystem + virtual bool Init(); + virtual void Shutdown(); + + virtual void LevelInitPostEntity() + { +#ifdef MAPBASE + // CInstancedResponseSystem is not a CAutoGameSystem, so this needs to be called manually. + // The same could've been accomplished by making CInstancedResponseSystem derive from CAutoGameSystem, + // but their instanced nature would've complicated things a lot. + int c = m_InstancedSystems.Count(); + for ( int i = c - 1 ; i >= 0; i-- ) + { + m_InstancedSystems[i]->LevelInitPostEntity(); + } +#endif + } + + virtual void Release() + { + Assert( 0 ); + } + + void AddInstancedResponseSystem( const char *scriptfile, CInstancedResponseSystem *sys ) + { + m_InstancedSystems.Insert( scriptfile, sys ); + } + + CInstancedResponseSystem *FindResponseSystem( const char *scriptfile ) + { + int idx = m_InstancedSystems.Find( scriptfile ); + if ( idx == m_InstancedSystems.InvalidIndex() ) + return NULL; + return m_InstancedSystems[ idx ]; + } + + IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) + { + COM_TimestampedLog( "PrecacheCustomResponseSystem %s - Start", scriptfile ); + CInstancedResponseSystem *sys = ( CInstancedResponseSystem * )FindResponseSystem( scriptfile ); + if ( !sys ) + { + sys = new CInstancedResponseSystem( scriptfile ); + if ( !sys ) + { + Error( "Failed to load response system data from %s", scriptfile ); + } + + if ( !sys->Init() ) + { + Error( "CInstancedResponseSystem: Failed to init response system from %s!", scriptfile ); + } + + AddInstancedResponseSystem( scriptfile, sys ); + } + + sys->Precache(); + + COM_TimestampedLog( "PrecacheCustomResponseSystem %s - Finish", scriptfile ); + + return ( IResponseSystem * )sys; + } + + IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ); + void DestroyCustomResponseSystems(); + + virtual void LevelInitPreEntity() + { + // This will precache the default system + // All user installed systems are init'd by PrecacheCustomResponseSystem which will call sys->Precache() on the ones being used + + // FIXME: This is SLOW the first time you run the engine (can take 3 - 10 seconds!!!) + if ( ShouldPrecache() ) + { + Precache(); + } + +#ifdef MAPBASE + if (!rr_enhanced_saverestore.GetBool() || gpGlobals->eLoadType != MapLoad_Transition) +#endif + ResetResponseGroups(); + } + + void ReloadAllResponseSystems() + { + Clear(); + Init(); + + int c = m_InstancedSystems.Count(); + for ( int i = c - 1 ; i >= 0; i-- ) + { + CInstancedResponseSystem *sys = m_InstancedSystems[ i ]; + if ( !IsCustomManagable() ) + { + sys->Clear(); + sys->Init(); + } + else + { + // Custom reponse rules will manage/reload themselves - remove them. + m_InstancedSystems.RemoveAt( i ); + } + } + + // precache sounds in case we added new ones + Precache(); + + } + +private: + + void ClearInstanced() + { + int c = m_InstancedSystems.Count(); + for ( int i = c - 1 ; i >= 0; i-- ) + { + CInstancedResponseSystem *sys = m_InstancedSystems[ i ]; + sys->Release(); + } + m_InstancedSystems.RemoveAll(); + } + + CUtlDict< CInstancedResponseSystem *, int > m_InstancedSystems; + friend void CC_RR_DumpHashInfo( const CCommand &args ); +}; + +IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) +{ + // Create a instanced response system. + CInstancedResponseSystem *pCustomSystem = new CInstancedResponseSystem( pszCustomName ); + if ( !pCustomSystem ) + { + Error( "BuildCustomResponseSystemGivenCriterea: Failed to create custom response system %s!", pszCustomName ); + } + + pCustomSystem->Clear(); + + // Copy the relevant rules and data. + /* + int nRuleCount = m_Rules.Count(); + for ( int iRule = 0; iRule < nRuleCount; ++iRule ) + */ + for ( ResponseRulePartition::tIndex iIdx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(iIdx) ; + iIdx = m_RulePartitions.Next( iIdx ) ) + { + Rule *pRule = &m_RulePartitions[iIdx]; + if ( pRule ) + { + float flScore = 0.0f; + + int nCriteriaCount = pRule->m_Criteria.Count(); + for ( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) + { + int iRuleCriteria = pRule->m_Criteria[iCriteria]; + + flScore += LookForCriteria( criteriaSet, iRuleCriteria ); + if ( flScore >= flCriteriaScore ) + { + CopyRuleFrom( pRule, iIdx, pCustomSystem ); + break; + } + } + } + } + + // Set as a custom response system. + m_bCustomManagable = true; + AddInstancedResponseSystem( pszCustomName, pCustomSystem ); + + // pCustomSystem->DumpDictionary( pszCustomName ); + + return pCustomSystem; +} + +void CDefaultResponseSystem::DestroyCustomResponseSystems() +{ + ClearInstanced(); +} + + +static CDefaultResponseSystem defaultresponsesytem; +IResponseSystem *g_pResponseSystem = &defaultresponsesytem; + +CON_COMMAND( rr_reloadresponsesystems, "Reload all response system scripts." ) +{ +#ifdef GAME_DLL + if ( !UTIL_IsCommandIssuedByServerAdmin() ) + return; +#endif + + defaultresponsesytem.ReloadAllResponseSystems(); +} + +#if RR_DUMPHASHINFO_ENABLED +static void CC_RR_DumpHashInfo( const CCommand &args ) +{ + defaultresponsesytem.m_RulePartitions.PrintBucketInfo( &defaultresponsesytem ); +} +static ConCommand rr_dumphashinfo( "rr_dumphashinfo", CC_RR_DumpHashInfo, "Statistics on primary hash bucketing of response rule partitions"); +#endif + +#ifdef MAPBASE +// Designed for extern magic, this gives the <, >, etc. of response system criteria to the outside world. +// Mostly just used for Matcher_Match in matchers.h. +bool ResponseSystemCompare( const char *criterion, const char *value ) +{ + Criteria criteria; + criteria.value = criterion; + defaultresponsesytem.ComputeMatcher( &criteria, criteria.matcher ); + return defaultresponsesytem.CompareUsingMatcher( value, criteria.matcher, true ); + + return false; +} + +//----------------------------------------------------------------------------- +// CResponseFilePrecacher +// +// Purpose: Precaches a single talker file. That's it. +// +// It copies from a bunch of the original Response System class and therefore it's really messy. +// Despite the horrors a normal programmer might find in here, I think it performs better than anything else I could've come up with. +//----------------------------------------------------------------------------- +/* +class CResponseFilePrecacher +{ +public: + + // Stuff copied from the Response System. + // Direct copy-pastes are very compact, to say the least. + inline bool ParseToken( void ) + { + if ( m_bUnget ) + { m_bUnget = false; return true; } + if ( m_ScriptStack.Count() <= 0 ) + { return false; } + + m_ScriptStack[ 0 ].currenttoken = engine->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); + m_ScriptStack[ 0 ].tokencount++; + return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + } + + CUtlVector< CResponseSystem::ScriptEntry > m_ScriptStack; + bool m_bUnget; + char token[ 1204 ]; + + + void PrecacheResponse( const char *response, byte type ) + { + switch ( type ) + { + default: + break; + case RESPONSE_SCENE: + { + DevMsg("Precaching scene %s...\n", response); + + // fixup $gender references + char file[_MAX_PATH]; + Q_strncpy( file, response, sizeof(file) ); + char *gender = strstr( file, "$gender" ); + if ( gender ) + { + // replace with male & female + const char *postGender = gender + strlen("$gender"); + *gender = 0; + char genderFile[_MAX_PATH]; + + Q_snprintf( genderFile, sizeof(genderFile), "%smale%s", file, postGender); + PrecacheInstancedScene( genderFile ); + + Q_snprintf( genderFile, sizeof(genderFile), "%sfemale%s", file, postGender); + PrecacheInstancedScene( genderFile ); + } + else + { + PrecacheInstancedScene( file ); + } + } + break; + case RESPONSE_SPEAK: + { + DevMsg("Precaching sound %s...\n", response); + CBaseEntity::PrecacheScriptSound( response ); + } + break; + } + } + + bool IsRootCommand() + { + if (!Q_stricmp( token, "#include" ) || !Q_stricmp( token, "response" ) + || !Q_stricmp( token, "enumeration" ) || !Q_stricmp( token, "criteria" ) + || !Q_stricmp( token, "criterion" ) || !Q_stricmp( token, "rule" )) + return true; + return false; + } + + void ParseResponse( void ) + { + // Must go to response group name + ParseToken(); + + while ( 1 ) + { + ParseToken(); + + if ( !Q_stricmp( token, "{" ) ) + { + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + byte type = ComputeResponseType( token ); + if (type == RESPONSE_NONE) + continue; + + ParseToken(); + char *value = CopyString( token ); + + PrecacheResponse(value, type); + } + break; + } + + byte type = ComputeResponseType( token ); + if (type == RESPONSE_NONE) + break; + + ParseToken(); + char *value = CopyString( token ); + + PrecacheResponse(value, type); + + break; + } + } + + bool LoadFromBuffer(const char *scriptfile, unsigned char *buffer, CStringPool &includedFiles) + { + includedFiles.Allocate( scriptfile ); + + CResponseSystem::ScriptEntry e; + e.name = filesystem->FindOrAddFileName( scriptfile ); + e.buffer = buffer; + e.currenttoken = (char *)e.buffer; + e.tokencount = 0; + m_ScriptStack.AddToHead( e ); + + while ( 1 ) + { + ParseToken(); + if ( !token[0] ) + { + break; + } + + if ( !Q_stricmp( token, "response" ) ) + { + ParseResponse(); + } + else if ( !Q_stricmp( token, "#include" ) || !Q_stricmp( token, "#base" ) ) + { + // Compacted version of ParseInclude(), including new changes. + // Look at that if you want to read. + char includefile[ 256 ]; + ParseToken(); + if (scriptfile) { size_t len = strlen(scriptfile)-1; + for (size_t i = 0; i < len; i++) + { if (scriptfile[i] == CORRECT_PATH_SEPARATOR || scriptfile[i] == INCORRECT_PATH_SEPARATOR) + { len = i; } + } Q_strncpy(includefile, scriptfile, len+1); + if (len+1 != strlen(scriptfile)) + { Q_snprintf(includefile, sizeof(includefile), "%s/%s", includefile, token); } + else includefile[0] = '\0'; + } if (!includefile[0]) Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); + + if ( includedFiles.Find( includefile ) == NULL ) + { + MEM_ALLOC_CREDIT(); + + // Try and load it + CUtlBuffer buf; + if ( filesystem->ReadFile( includefile, "GAME", buf ) ) + { + LoadFromBuffer( includefile, (unsigned char *)buf.PeekGet(), includedFiles ); + } + } + } + } + + if ( m_ScriptStack.Count() > 0 ) + m_ScriptStack.Remove( 0 ); + + return true; + } +}; +*/ + +// Loads a file directly to the main response system +bool LoadResponseSystemFile(const char *scriptfile) +{ + CUtlBuffer buf; + if ( !filesystem->ReadFile( scriptfile, "GAME", buf ) ) + { + return false; + } + + // This is a really messy and specialized system that precaches the responses and only the responses of a talker file. + /* + CStringPool includedFiles; + CResponseFilePrecacher *rs = new CResponseFilePrecacher(); + if (!rs || !rs->LoadFromBuffer(scriptfile, (unsigned char *)buf.PeekGet(), includedFiles)) + { + Warning( "Failed to load response system data from %s", scriptfile ); + delete rs; + return false; + } + delete rs; + */ + + // HACKHACK: This is not very efficient + /* + CInstancedResponseSystem *tempSys = new CInstancedResponseSystem( scriptfile ); + if ( tempSys && tempSys->Init() ) + { + tempSys->Precache(); + + for ( ResponseRulePartition::tIndex idx = tempSys->m_RulePartitions.First() ; + tempSys->m_RulePartitions.IsValid(idx) ; + idx = tempSys->m_RulePartitions.Next(idx) ) + { + Rule &rule = tempSys->m_RulePartitions[idx]; + tempSys->CopyRuleFrom( &rule, idx, &defaultresponsesytem ); + } + + tempSys->Release(); + } + */ + + // HACKHACK: This is even less efficient + defaultresponsesytem.LoadFromBuffer( scriptfile, (const char *)buf.PeekGet() ); + defaultresponsesytem.Precache(); + + return true; +} + +// Called from Mapbase manifests to flush +void ReloadResponseSystem() +{ + defaultresponsesytem.ReloadAllResponseSystems(); +} +#endif + +static short RESPONSESYSTEM_SAVE_RESTORE_VERSION = 1; + +// note: this won't save/restore settings from instanced response systems. Could add that with a CDefSaveRestoreOps implementation if needed +// +class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler +{ +public: + const char *GetBlockName() + { + return "ResponseSystem"; + } + + void WriteSaveHeaders( ISave *pSave ) + { + pSave->WriteShort( &RESPONSESYSTEM_SAVE_RESTORE_VERSION ); + } + + void ReadRestoreHeaders( IRestore *pRestore ) + { + // No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so. + short version; + pRestore->ReadShort( &version ); + m_fDoLoad = ( version == RESPONSESYSTEM_SAVE_RESTORE_VERSION ); + } + + void Save( ISave *pSave ) + { + CDefaultResponseSystem& rs = defaultresponsesytem; + + int count = rs.m_Responses.Count(); + pSave->WriteInt( &count ); + for ( int i = 0; i < count; ++i ) + { + pSave->StartBlock( "ResponseGroup" ); + + pSave->WriteString( rs.m_Responses.GetElementName( i ) ); + const ResponseGroup *group = &rs.m_Responses[ i ]; + pSave->WriteAll( group ); + + short groupCount = group->group.Count(); + pSave->WriteShort( &groupCount ); + for ( int j = 0; j < groupCount; ++j ) + { + const ParserResponse *response = &group->group[ j ]; + pSave->StartBlock( "Response" ); + pSave->WriteString( response->value ); + pSave->WriteAll( response ); + pSave->EndBlock(); + } + + pSave->EndBlock(); + } + +#ifdef MAPBASE + // Enhanced Response System save/restore + int count2 = 0; + if (rr_enhanced_saverestore.GetBool()) + { + // Rule state save/load + count2 = rs.m_RulePartitions.Count(); + pSave->WriteInt( &count2 ); + for ( ResponseRulePartition::tIndex idx = rs.m_RulePartitions.First() ; + rs.m_RulePartitions.IsValid(idx) ; + idx = rs.m_RulePartitions.Next(idx) ) + { + pSave->StartBlock( "Rule" ); + + pSave->WriteString( rs.m_RulePartitions.GetElementName( idx ) ); + const Rule &rule = rs.m_RulePartitions[ idx ]; + + bool bEnabled = rule.m_bEnabled; + pSave->WriteBool( &bEnabled ); + + pSave->EndBlock(); + } + } + else + { + // Indicate this isn't using enhanced save/restore + pSave->WriteInt( &count2 ); + } +#endif + } + + void Restore( IRestore *pRestore, bool createPlayers ) + { + if ( !m_fDoLoad ) + return; + + CDefaultResponseSystem& rs = defaultresponsesytem; + + int count = pRestore->ReadInt(); + for ( int i = 0; i < count; ++i ) + { + char szResponseGroupBlockName[SIZE_BLOCK_NAME_BUF]; + pRestore->StartBlock( szResponseGroupBlockName ); + if ( !Q_stricmp( szResponseGroupBlockName, "ResponseGroup" ) ) + { + + char groupname[ 256 ]; + pRestore->ReadString( groupname, sizeof( groupname ), 0 ); + + // Try and find it + int idx = rs.m_Responses.Find( groupname ); + if ( idx != rs.m_Responses.InvalidIndex() ) + { + ResponseGroup *group = &rs.m_Responses[ idx ]; + pRestore->ReadAll( group ); + + short groupCount = pRestore->ReadShort(); + for ( int j = 0; j < groupCount; ++j ) + { + char szResponseBlockName[SIZE_BLOCK_NAME_BUF]; + + char responsename[ 256 ]; + pRestore->StartBlock( szResponseBlockName ); + if ( !Q_stricmp( szResponseBlockName, "Response" ) ) + { + pRestore->ReadString( responsename, sizeof( responsename ), 0 ); + + // Find it by name + int ri; + for ( ri = 0; ri < group->group.Count(); ++ri ) + { + ParserResponse *response = &group->group[ ri ]; + if ( !Q_stricmp( response->value, responsename ) ) + { + break; + } + } + + if ( ri < group->group.Count() ) + { + ParserResponse *response = &group->group[ ri ]; + pRestore->ReadAll( response ); + } + } + + pRestore->EndBlock(); + } + } + } + + pRestore->EndBlock(); + } + +#ifdef MAPBASE + // Enhanced Response System save/restore + count = pRestore->ReadInt(); + for ( int i = 0; i < count; ++i ) + { + char szRuleBlockName[SIZE_BLOCK_NAME_BUF]; + pRestore->StartBlock( szRuleBlockName ); + if ( !Q_stricmp( szRuleBlockName, "Rule" ) ) + { + char groupname[ 256 ]; + pRestore->ReadString( groupname, sizeof( groupname ), 0 ); + + // Try and find it + Rule *rule = rs.m_RulePartitions.FindByName( groupname ); + if ( rule ) + { + bool bEnabled; + pRestore->ReadBool( &bEnabled ); + rule->m_bEnabled = bEnabled; + } + else + { + Warning("Warning: Can't find rule %s\n", groupname); + } + } + + pRestore->EndBlock(); + } +#endif + } +private: + + bool m_fDoLoad; + +} g_DefaultResponseSystemSaveRestoreBlockHandler; + +ISaveRestoreBlockHandler *GetDefaultResponseSystemSaveRestoreBlockHandler() +{ + return &g_DefaultResponseSystemSaveRestoreBlockHandler; +} + +//----------------------------------------------------------------------------- +// CResponseSystemSaveRestoreOps +// +// Purpose: Handles save and load for instanced response systems... +// +// BUGBUG: This will save the same response system to file multiple times for "shared" response systems and +// therefore it'll restore the same data onto the same pointer N times on reload (probably benign for now, but we could +// write code to save/restore the instanced ones by filename in the block handler above maybe? +//----------------------------------------------------------------------------- + +class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps +{ +public: + + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) + { + CResponseSystem *pRS = *(CResponseSystem **)fieldInfo.pField; + if ( !pRS || pRS == &defaultresponsesytem ) + return; + + int count = pRS->m_Responses.Count(); + pSave->WriteInt( &count ); + for ( int i = 0; i < count; ++i ) + { + pSave->StartBlock( "ResponseGroup" ); + + pSave->WriteString( pRS->m_Responses.GetElementName( i ) ); + const ResponseGroup *group = &pRS->m_Responses[ i ]; + pSave->WriteAll( group ); + + short groupCount = group->group.Count(); + pSave->WriteShort( &groupCount ); + for ( int j = 0; j < groupCount; ++j ) + { + const ParserResponse *response = &group->group[ j ]; + pSave->StartBlock( "Response" ); + pSave->WriteString( response->value ); + pSave->WriteAll( response ); + pSave->EndBlock(); + } + + pSave->EndBlock(); + } + } + + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) + { + CResponseSystem *pRS = *(CResponseSystem **)fieldInfo.pField; + if ( !pRS || pRS == &defaultresponsesytem ) + return; + + int count = pRestore->ReadInt(); + for ( int i = 0; i < count; ++i ) + { + char szResponseGroupBlockName[SIZE_BLOCK_NAME_BUF]; + pRestore->StartBlock( szResponseGroupBlockName ); + if ( !Q_stricmp( szResponseGroupBlockName, "ResponseGroup" ) ) + { + + char groupname[ 256 ]; + pRestore->ReadString( groupname, sizeof( groupname ), 0 ); + + // Try and find it + int idx = pRS->m_Responses.Find( groupname ); + if ( idx != pRS->m_Responses.InvalidIndex() ) + { + ResponseGroup *group = &pRS->m_Responses[ idx ]; + pRestore->ReadAll( group ); + + short groupCount = pRestore->ReadShort(); + for ( int j = 0; j < groupCount; ++j ) + { + char szResponseBlockName[SIZE_BLOCK_NAME_BUF]; + + char responsename[ 256 ]; + pRestore->StartBlock( szResponseBlockName ); + if ( !Q_stricmp( szResponseBlockName, "Response" ) ) + { + pRestore->ReadString( responsename, sizeof( responsename ), 0 ); + + // Find it by name + int ri; + for ( ri = 0; ri < group->group.Count(); ++ri ) + { + ParserResponse *response = &group->group[ ri ]; + if ( !Q_stricmp( response->value, responsename ) ) + { + break; + } + } + + if ( ri < group->group.Count() ) + { + ParserResponse *response = &group->group[ ri ]; + pRestore->ReadAll( response ); + } + } + + pRestore->EndBlock(); + } + } + } + + pRestore->EndBlock(); + } + } + +} g_ResponseSystemSaveRestoreOps; + +ISaveRestoreOps *responseSystemSaveRestoreOps = &g_ResponseSystemSaveRestoreOps; + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CDefaultResponseSystem::Init() +{ + /* + Warning( "sizeof( Response ) == %d\n", sizeof( Response ) ); + Warning( "sizeof( ResponseGroup ) == %d\n", sizeof( ResponseGroup ) ); + Warning( "sizeof( Criteria ) == %d\n", sizeof( Criteria ) ); + Warning( "sizeof( AI_ResponseParams ) == %d\n", sizeof( AI_ResponseParams ) ); + */ + const char *basescript = GetScriptFile(); + + LoadRuleSet( basescript ); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDefaultResponseSystem::Shutdown() +{ + // Wipe instanced versions + ClearInstanced(); + + // Clear outselves + Clear(); + // IServerSystem chain + BaseClass::Shutdown(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Instance a custom response system +// Input : *scriptfile - +// Output : IResponseSystem +//----------------------------------------------------------------------------- +IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) +{ + return defaultresponsesytem.PrecacheCustomResponseSystem( scriptfile ); +} + +//----------------------------------------------------------------------------- +// Purpose: Instance a custom response system +// Input : *scriptfile - +// set - +// Output : IResponseSystem +//----------------------------------------------------------------------------- +IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) +{ + return defaultresponsesytem.BuildCustomResponseSystemGivenCriteria( pszBaseFile, pszCustomName, criteriaSet, flCriteriaScore ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void DestroyCustomResponseSystems() +{ + defaultresponsesytem.DestroyCustomResponseSystems(); +} diff --git a/game/shared/ai_responsesystem_new.h b/game/shared/ai_responsesystem_new.h new file mode 100644 index 00000000..9d2fff6b --- /dev/null +++ b/game/shared/ai_responsesystem_new.h @@ -0,0 +1,29 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef AI_RESPONSESYSTEM_H +#define AI_RESPONSESYSTEM_H + +#include "utlvector.h" + +#ifdef _WIN32 +#pragma once +#endif + +#include "AI_Criteria.h" +#include "../../public/responserules/response_types.h" + +// using ResponseRules::IResponseFilter; +// using ResponseRules::IResponseSystem; + +ResponseRules::IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ); +ResponseRules::IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ); +void DestroyCustomResponseSystems(); + +class ISaveRestoreBlockHandler *GetDefaultResponseSystemSaveRestoreBlockHandler(); +class ISaveRestoreOps *GetResponseSystemSaveRestoreOps(); + +#endif // AI_RESPONSESYSTEM_H diff --git a/game/shared/ai_speechconcept.cpp b/game/shared/ai_speechconcept.cpp new file mode 100644 index 00000000..c0ae8e36 --- /dev/null +++ b/game/shared/ai_speechconcept.cpp @@ -0,0 +1,28 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "ai_speechconcept.h" + +#ifdef GAME_DLL +#include "game.h" +#include "ai_basenpc.h" +#include "sceneentity.h" +#endif + +#include "engine/ienginesound.h" +#include "keyvalues.h" +#include "ai_criteria.h" +#include "isaverestore.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include + + +// empty \ No newline at end of file diff --git a/game/shared/ai_speechconcept.h b/game/shared/ai_speechconcept.h new file mode 100644 index 00000000..3e375a0a --- /dev/null +++ b/game/shared/ai_speechconcept.h @@ -0,0 +1,45 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Class data for an AI Concept, an atom of response-driven dialog. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SPEECHCONCEPT_H +#define AI_SPEECHCONCEPT_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "responserules/response_types.h" + +class CAI_Concept : public ResponseRules::CRR_Concept +{ +public: + CAI_Concept() {}; + // construct concept from a string. + CAI_Concept(const char *fromString) : CRR_Concept(fromString) {} ; + + // get/set BS + inline EHANDLE GetSpeaker() const { return m_hSpeaker; } + inline void SetSpeaker(EHANDLE val) { m_hSpeaker = val; } + + /* + inline EHANDLE GetTarget() const { return m_hTarget; } + inline void SetTarget(EHANDLE val) { m_hTarget = val; } + inline EHANDLE GetTopic() const { return m_hTopic; } + inline void SetTopic(EHANDLE val) { m_hTopic = val; } + */ + +protected: + EHANDLE m_hSpeaker; + + /* + EHANDLE m_hTarget; + EHANDLE m_hTopic; + */ +}; + + +#endif diff --git a/game/shared/ammodef.cpp b/game/shared/ammodef.cpp index 257e8569..cf3ad3e8 100644 --- a/game/shared/ammodef.cpp +++ b/game/shared/ammodef.cpp @@ -24,6 +24,21 @@ Ammo_t *CAmmoDef::GetAmmoOfIndex(int nAmmoIndex) return &m_AmmoType[ nAmmoIndex ]; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +const char* CAmmoDef::Name(int nAmmoIndex) +{ + if ( nAmmoIndex < 1 || nAmmoIndex >= m_nAmmoIndex ) + return NULL; + + return m_AmmoType[nAmmoIndex].pName; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : @@ -292,4 +307,24 @@ CAmmoDef::~CAmmoDef( void ) } } +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CAmmoDef, SCRIPT_SINGLETON "The ammo type definition manager." ) + + DEFINE_SCRIPTFUNC( Name, "Gets the name of the specified ammo type index." ) + DEFINE_SCRIPTFUNC( Index, "Gets the index of the specified ammo type name." ) + DEFINE_SCRIPTFUNC( PlrDamage, "Gets the damage players deal for the specified ammo type." ) + DEFINE_SCRIPTFUNC( NPCDamage, "Gets the damage NPCs deal for the specified ammo type." ) + DEFINE_SCRIPTFUNC( MaxCarry, "Gets the maximum amount of this ammo type which players should be able to carry." ) + DEFINE_SCRIPTFUNC( DamageType, "Gets the type of damage this ammo type deals." ) + DEFINE_SCRIPTFUNC( TracerType, "Gets the type of tracer this ammo type uses." ) + DEFINE_SCRIPTFUNC( DamageForce, "Gets the amount of force this ammo type deals." ) + DEFINE_SCRIPTFUNC( MinSplashSize, "Gets the minimum size of water splashes caused by impacts from this ammo type." ) + DEFINE_SCRIPTFUNC( MaxSplashSize, "Gets the maximum size of water splashes caused by impacts from this ammo type." ) + DEFINE_SCRIPTFUNC( Flags, "Gets the flags this ammo type uses." ) + + DEFINE_SCRIPTFUNC( GetNumAmmoTypes, "Gets the number of ammo types which currently exist." ) + +END_SCRIPTDESC(); +#endif + diff --git a/game/shared/ammodef.h b/game/shared/ammodef.h index 71c1707f..d5607e02 100644 --- a/game/shared/ammodef.h +++ b/game/shared/ammodef.h @@ -72,6 +72,9 @@ class CAmmoDef Ammo_t m_AmmoType[MAX_AMMO_TYPES]; Ammo_t *GetAmmoOfIndex(int nAmmoIndex); +#ifdef MAPBASE + const char* Name(int nAmmoIndex); +#endif int Index(const char *psz); int PlrDamage(int nAmmoIndex); int NPCDamage(int nAmmoIndex); @@ -91,6 +94,11 @@ class CAmmoDef private: bool AddAmmoType(char const* name, int damageType, int tracerType, int nFlags, int minSplashSize, int maxSplashSize ); + +#ifdef MAPBASE_VSCRIPT + ALLOW_SCRIPT_ACCESS(); + int GetNumAmmoTypes() { return m_nAmmoIndex; } +#endif }; diff --git a/game/shared/animation.cpp b/game/shared/animation.cpp index 97561581..0f6dd754 100644 --- a/game/shared/animation.cpp +++ b/game/shared/animation.cpp @@ -339,77 +339,6 @@ int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequence( CStudioHdr * } -int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequenceFromModifiers( CStudioHdr *pstudiohdr, int activity, CUtlSymbol *pActivityModifiers, int iModifierCount ) -{ - if ( !pstudiohdr->SequencesAvailable() ) - { - return ACTIVITY_NOT_AVAILABLE; - } - - VerifySequenceIndex( pstudiohdr ); - - if ( pstudiohdr->GetNumSeq() == 1 ) - { - return ( ::GetSequenceActivity( pstudiohdr, 0, NULL ) == activity ) ? 0 : ACTIVITY_NOT_AVAILABLE; - } - - if (!ValidateAgainst(pstudiohdr)) - { - AssertMsg1(false, "CStudioHdr %s has changed its vmodel pointer without reinitializing its activity mapping! Now performing emergency reinitialization.", pstudiohdr->pszName()); - ExecuteOnce(DebuggerBreakIfDebugging()); - Reinitialize(pstudiohdr); - } - - // a null m_pSequenceTuples just means that this studio header has no activities. - if (!m_pSequenceTuples) - return ACTIVITY_NOT_AVAILABLE; - - // get the data for the given activity - HashValueType dummy( activity, 0, 0, 0 ); - UtlHashHandle_t handle = m_ActToSeqHash.Find(dummy); - if (!m_ActToSeqHash.IsValidHandle(handle)) - { - return ACTIVITY_NOT_AVAILABLE; - } - const HashValueType * __restrict actData = &m_ActToSeqHash[handle]; - - // go through each sequence and give it a score - int top_score = -1; - CUtlVector topScoring( actData->count, actData->count ); - for ( int i = 0; i < actData->count; i++ ) - { - SequenceTuple * __restrict sequenceInfo = m_pSequenceTuples + actData->startingIdx + i; - int score = 0; - // count matching activity modifiers - for ( int m = 0; m < iModifierCount; m++ ) - { - int num_modifiers = sequenceInfo->iNumActivityModifiers; - for ( int k = 0; k < num_modifiers; k++ ) - { - if ( sequenceInfo->pActivityModifiers[ k ] == pActivityModifiers[ m ] ) - { - score++; - break; - } - } - } - if ( score > top_score ) - { - topScoring.RemoveAll(); - topScoring.AddToTail( sequenceInfo->seqnum ); - top_score = score; - } - } - - // randomly pick between the highest scoring sequences ( NOTE: this method of selecting a sequence ignores activity weights ) - if ( IsInPrediction() ) - { - return topScoring[ SharedRandomInt( "SelectWeightedSequence", 0, topScoring.Count() - 1 ) ]; - } - - return topScoring[ RandomInt( 0, topScoring.Count() - 1 ) ]; -} - #endif @@ -517,9 +446,9 @@ int LookupSequence( CStudioHdr *pstudiohdr, const char *label ) void GetSequenceLinearMotion( CStudioHdr *pstudiohdr, int iSequence, const float poseParameter[], Vector *pVec ) { - if ( !pstudiohdr) + if (! pstudiohdr) { - ExecuteNTimes( 20, Msg( "Bad pstudiohdr in GetSequenceLinearMotion()!\n" ) ); + Msg( "Bad pstudiohdr in GetSequenceLinearMotion()!\n" ); return; } @@ -531,7 +460,11 @@ void GetSequenceLinearMotion( CStudioHdr *pstudiohdr, int iSequence, const float // Don't spam on bogus model if ( pstudiohdr->GetNumSeq() > 0 ) { - ExecuteNTimes( 20, Msg( "Bad sequence (%i out of %i max) in GetSequenceLinearMotion() for model '%s'!\n", iSequence, pstudiohdr->GetNumSeq(), pstudiohdr->pszName() ) ); + static int msgCount = 0; + while ( ++msgCount <= 10 ) + { + Msg( "Bad sequence (%i out of %i max) in GetSequenceLinearMotion() for model '%s'!\n", iSequence, pstudiohdr->GetNumSeq(), pstudiohdr->pszName() ); + } } pVec->Init(); return; @@ -916,7 +849,7 @@ const char *GetBodygroupName( CStudioHdr *pstudiohdr, int iGroup ) int FindBodygroupByName( CStudioHdr *pstudiohdr, const char *name ) { - if ( !pstudiohdr || !pstudiohdr->IsValid() ) + if ( !pstudiohdr ) return -1; int group; diff --git a/game/shared/apparent_velocity_helper.h b/game/shared/apparent_velocity_helper.h index 65e28fbd..765a419d 100644 --- a/game/shared/apparent_velocity_helper.h +++ b/game/shared/apparent_velocity_helper.h @@ -46,10 +46,9 @@ template< class T, class Functor=CDefaultCalcDistance > class CApparentVelocity { public: - CApparentVelocity(const T& t0) + CApparentVelocity() { m_LastTime = -1; - m_LastValue = t0; } float AddSample( float time, T value ) diff --git a/game/shared/base_playeranimstate.cpp b/game/shared/base_playeranimstate.cpp index 768e4f17..82cb75aa 100644 --- a/game/shared/base_playeranimstate.cpp +++ b/game/shared/base_playeranimstate.cpp @@ -269,7 +269,7 @@ void CBasePlayerAnimState::ComputeMainSequence() int animDesired = SelectWeightedSequence( TranslateActivity(idealActivity) ); #if !defined( HL1_CLIENT_DLL ) && !defined ( HL1_DLL ) - if ( !ShouldResetMainSequence( pPlayer->GetSequence(), animDesired ) ) + if ( pPlayer->GetSequenceActivity( pPlayer->GetSequence() ) == pPlayer->GetSequenceActivity( animDesired ) ) return; #endif @@ -289,13 +289,8 @@ void CBasePlayerAnimState::ComputeMainSequence() #endif } -bool CBasePlayerAnimState::ShouldResetMainSequence( int iCurrentSequence, int iNewSequence ) -{ - if ( !GetOuter() ) - return false; - return GetOuter()->GetSequenceActivity( iCurrentSequence ) != GetOuter()->GetSequenceActivity( iNewSequence ); -} + void CBasePlayerAnimState::UpdateAimSequenceLayers( @@ -544,7 +539,26 @@ bool CBasePlayerAnimState::CanThePlayerMove() void CBasePlayerAnimState::ComputePlaybackRate() { VPROF( "CBasePlayerAnimState::ComputePlaybackRate" ); +#ifdef MAPBASE + if ( m_AnimConfig.m_LegAnimType == LEGANIM_9WAY ) + { + // If the movement would be greater than the pose range, set playback rate anyway + if ( abs(m_vLastMovePose.x) > 1.0f || abs(m_vLastMovePose.y) > 1.0f ) + { + bool bIsMoving; + float flRate = CalcMovementPlaybackRate( &bIsMoving ); + if ( bIsMoving ) + GetOuter()->SetPlaybackRate( flRate ); + else + GetOuter()->SetPlaybackRate( 1 ); + } + else + GetOuter()->SetPlaybackRate( 1 ); + } + else // Allow LEGANIM_8WAY to change playback rate +#else if ( m_AnimConfig.m_LegAnimType != LEGANIM_9WAY && m_AnimConfig.m_LegAnimType != LEGANIM_8WAY ) +#endif { // When using a 9-way blend, playback rate is always 1 and we just scale the pose params // to speed up or slow down the animation. diff --git a/game/shared/base_playeranimstate.h b/game/shared/base_playeranimstate.h index 5c84755a..0b1f6b34 100644 --- a/game/shared/base_playeranimstate.h +++ b/game/shared/base_playeranimstate.h @@ -234,7 +234,6 @@ abstract_class CBasePlayerAnimState : virtual public IPlayerAnimState void EstimateYaw(); - virtual bool ShouldResetMainSequence( int iCurrentSequence, int iNewSequence ); void ComputeMainSequence(); void ComputeAimSequence(); diff --git a/game/shared/basecombatcharacter_shared.cpp b/game/shared/basecombatcharacter_shared.cpp index 84993b2b..1dc696a2 100644 --- a/game/shared/basecombatcharacter_shared.cpp +++ b/game/shared/basecombatcharacter_shared.cpp @@ -59,12 +59,8 @@ bool CBaseCombatCharacter::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmo if ( m_hActiveWeapon ) { - if (!m_hActiveWeapon->Holster(pWeapon)) + if ( !m_hActiveWeapon->Holster( pWeapon ) ) return false; - -#ifdef VANCE - return true; -#endif } m_hActiveWeapon = pWeapon; @@ -86,7 +82,7 @@ bool CBaseCombatCharacter::Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon ) #else IClientVehicle *pVehicle = pPlayer->GetVehicle(); #endif - if ( pVehicle && !pPlayer->UsingStandardWeaponsInVehicle() ) + if (pVehicle && !pPlayer->UsingStandardWeaponsInVehicle()) return false; #ifdef VANCE @@ -97,10 +93,13 @@ bool CBaseCombatCharacter::Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon ) return false; #endif #endif - } +#ifdef MAPBASE + if ( !pWeapon->HasAnyAmmo() && !GetAmmoCount( pWeapon->m_iPrimaryAmmoType ) && !pWeapon->HasSpawnFlags(SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY) ) +#else if ( !pWeapon->HasAnyAmmo() && !GetAmmoCount( pWeapon->m_iPrimaryAmmoType ) ) +#endif return false; if ( !pWeapon->CanDeploy() ) @@ -108,23 +107,8 @@ bool CBaseCombatCharacter::Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon ) if ( m_hActiveWeapon ) { - if ( !m_hActiveWeapon->CanHolster() && !pWeapon->ForceWeaponSwitch() ) + if ( !m_hActiveWeapon->CanHolster() ) return false; - - if ( IsPlayer() ) - { - CBasePlayer *pPlayer = (CBasePlayer *)this; - // check if active weapon force the last weapon to switch - if ( m_hActiveWeapon->ForceWeaponSwitch() ) - { - // last weapon wasn't allowed to switch, don't allow to switch to new weapon - CBaseCombatWeapon *pLastWeapon = pPlayer->GetLastWeapon(); - if ( pLastWeapon && pWeapon != pLastWeapon && !pLastWeapon->CanHolster() && !pWeapon->ForceWeaponSwitch() ) - { - return false; - } - } - } } return true; @@ -252,6 +236,16 @@ void CBaseCombatCharacter::SetBloodColor( int nBloodColor ) m_bloodColor = nBloodColor; } +#if defined(MAPBASE) && defined(GAME_DLL) +//----------------------------------------------------------------------------- +// Purpose: Sets blood color +//----------------------------------------------------------------------------- +void CBaseCombatCharacter::InputSetBloodColor( inputdata_t &inputdata ) +{ + SetBloodColor(inputdata.value.Int()); +} +#endif + //----------------------------------------------------------------------------- /** The main visibility check. Checks all the entity specific reasons that could diff --git a/game/shared/basecombatweapon_shared.cpp b/game/shared/basecombatweapon_shared.cpp index 2802050d..a6a36b21 100644 --- a/game/shared/basecombatweapon_shared.cpp +++ b/game/shared/basecombatweapon_shared.cpp @@ -12,7 +12,6 @@ #include "physics_saverestore.h" #include "datacache/imdlcache.h" #include "activitylist.h" -#include "particle_parse.h" // NVNT start extra includes #include "haptics/haptic_utils.h" @@ -39,8 +38,6 @@ #endif -#include "vprof.h" - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -63,8 +60,6 @@ ConVar tf_weapon_criticals_bucket_bottom( "tf_weapon_criticals_bucket_bottom", " ConVar tf_weapon_criticals_bucket_default( "tf_weapon_criticals_bucket_default", "300.0", FCVAR_REPLICATED | FCVAR_CHEAT ); #endif // TF -ConVar cl_useparticletracers("cl_useparticletracers", "1", FCVAR_ARCHIVE, "Determines whether or not particle tracers should be used (or the legacy hardcoded ones)"); - CBaseCombatWeapon::CBaseCombatWeapon() { // Constructor must call this @@ -169,20 +164,8 @@ void CBaseCombatWeapon::GiveDefaultAmmo( void ) //----------------------------------------------------------------------------- void CBaseCombatWeapon::Spawn( void ) { - bool bPrecacheAllowed = CBaseEntity::IsPrecacheAllowed(); - if (!bPrecacheAllowed) - { - tmEnter( TELEMETRY_LEVEL1, TMZF_NONE, "LateWeaponPrecache" ); - } - Precache(); - if (!bPrecacheAllowed) - { - tmLeave( TELEMETRY_LEVEL1 ); - } - - BaseClass::Spawn(); SetSolid( SOLID_BBOX ); @@ -195,11 +178,19 @@ void CBaseCombatWeapon::Spawn( void ) // Assume m_nViewModelIndex = 0; +#ifdef MAPBASE + // Don't reset to default ammo if we're supposed to use the keyvalue + if (!HasSpawnFlags( SF_WEAPON_PRESERVE_AMMO )) +#endif GiveDefaultAmmo(); if ( GetWorldModel() ) { +#ifdef MAPBASE + SetModel( (GetDroppedModel() && GetDroppedModel()[0]) ? GetDroppedModel() : GetWorldModel() ); +#else SetModel( GetWorldModel() ); +#endif } #if !defined( CLIENT_DLL ) @@ -255,7 +246,13 @@ void CBaseCombatWeapon::Precache( void ) // Add this weapon to the weapon registry, and get our index into it // Get weapon data from script file +#ifdef MAPBASE + // Allow custom scripts to be loaded on a map-by-map basis + if ( ReadCustomWeaponDataFromFileForSlot( filesystem, GetWeaponScriptName(), &m_hWeaponFileInfo, GetEncryptionKey() ) || + ReadWeaponDataFromFileForSlot( filesystem, GetWeaponScriptName(), &m_hWeaponFileInfo, GetEncryptionKey() ) ) +#else if ( ReadWeaponDataFromFileForSlot( filesystem, GetClassname(), &m_hWeaponFileInfo, GetEncryptionKey() ) ) +#endif { // Get the ammo indexes for the ammo's specified in the data file if ( GetWpnData().szAmmo1[0] ) @@ -298,6 +295,18 @@ void CBaseCombatWeapon::Precache( void ) { m_iWorldModelIndex = CBaseEntity::PrecacheModel( GetWorldModel() ); } +#ifdef MAPBASE + m_iDroppedModelIndex = 0; + if ( GetDroppedModel() && GetDroppedModel()[0] ) + { + m_iDroppedModelIndex = CBaseEntity::PrecacheModel( GetDroppedModel() ); + } + else + { + // Use the world model index + m_iDroppedModelIndex = m_iWorldModelIndex; + } +#endif // Precache sounds, too for ( int i = 0; i < NUM_SHOOT_SOUND_TYPES; ++i ) @@ -308,7 +317,6 @@ void CBaseCombatWeapon::Precache( void ) CBaseEntity::PrecacheScriptSound( shootsound ); } } - PrecacheParticleSystem("bullet_tracer02_red_crit"); } else { @@ -318,6 +326,64 @@ void CBaseCombatWeapon::Precache( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Sets ammo based on mapper value +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::SetAmmoFromMapper( float flAmmo, bool bSecondary ) +{ + int iFinalAmmo; + if (flAmmo > 0.0f && flAmmo < 1.0f) + { + // Ratio from max ammo + iFinalAmmo = ((float)(!bSecondary ? GetMaxClip1() : GetMaxClip2()) * flAmmo); + } + else + { + // Actual ammo value + iFinalAmmo = (int)flAmmo; + } + + !bSecondary ? + m_iClip1 = iFinalAmmo : + m_iClip2 = iFinalAmmo; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CBaseCombatWeapon::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq(szKeyName, "SetAmmo1") ) + { + SetAmmoFromMapper(atof(szValue)); + } + if ( FStrEq(szKeyName, "SetAmmo2") ) + { + SetAmmoFromMapper(atof(szValue), true); + } + else if ( FStrEq(szKeyName, "spawnflags") ) + { + m_spawnflags = atoi(szValue); +#ifndef CLIENT_DLL + // Some spawnflags have to be on the client right now + if (m_spawnflags != 0) + DispatchUpdateTransmitState(); +#endif + } + else + return BaseClass::KeyValue( szKeyName, szValue ); + + return true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CBaseCombatWeapon::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + return BaseClass::GetKeyValue(szKeyName, szValue, iMaxLen); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Get my data in the file weapon info array //----------------------------------------------------------------------------- @@ -411,6 +477,38 @@ bool CBaseCombatWeapon::IsMeleeWeapon() const return GetWpnData().m_bMeleeWeapon; } +#ifdef MAPBASE +float CBaseCombatWeapon::GetViewmodelFOVOverride() const +{ + return GetWpnData().m_flViewmodelFOV; +} + +float CBaseCombatWeapon::GetBobScale() const +{ + return GetWpnData().m_flBobScale; +} + +float CBaseCombatWeapon::GetSwayScale() const +{ + return GetWpnData().m_flSwayScale; +} + +float CBaseCombatWeapon::GetSwaySpeedScale() const +{ + return GetWpnData().m_flSwaySpeedScale; +} + +const char *CBaseCombatWeapon::GetDroppedModel() const +{ + return GetWpnData().szDroppedModel; +} + +bool CBaseCombatWeapon::UsesHands() const +{ + return GetWpnData().m_bUsesHands; +} +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -719,6 +817,12 @@ void CBaseCombatWeapon::Drop( const Vector &vecVelocity ) SetOwnerEntity( NULL ); SetOwner( NULL ); +#ifdef MAPBASE + m_bInReload = false; + + m_OnDropped.FireOutput(pOwner, this); +#endif + // If we're not allowing to spawn due to the gamerules, // remove myself when I'm dropped by an NPC. if ( pOwner && pOwner->IsNPC() ) @@ -764,6 +868,10 @@ void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner ) // Robin: We don't want to delete weapons the player has picked up, so // clear the name of the weapon. This prevents wildcards that are meant // to find NPCs finding weapons dropped by the NPCs as well. +#ifdef MAPBASE + // Level designers might want some weapons to preserve their original names, however. + if ( !HasSpawnFlags(SF_WEAPON_PRESERVE_NAME) ) +#endif SetName( NULL_STRING ); } else @@ -808,24 +916,16 @@ void CBaseCombatWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &t int iAttachment = GetTracerAttachment(); - if (cl_useparticletracers.GetBool()) - { - DispatchParticleEffect("bullet_tracer02_red_crit", vNewSrc, tr.endpos, vec3_angle, NULL); - } - else + switch ( iTracerType ) { - switch (iTracerType) - { - case TRACER_LINE: - UTIL_Tracer(vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName); - break; + case TRACER_LINE: + UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName ); + break; - case TRACER_LINE_AND_WHIZ: - UTIL_Tracer(vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName); - break; - } + case TRACER_LINE_AND_WHIZ: + UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName ); + break; } - } void CBaseCombatWeapon::GiveTo( CBaseEntity *pOther ) @@ -983,6 +1083,161 @@ void CBaseCombatWeapon::SetPickupTouch( void ) } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +WeaponClass_t CBaseCombatWeapon::WeaponClassify() +{ + // For now, check how we map our "angry idle" activity. + // The function is virtual, so derived weapons can override this. + Activity idleact = ActivityOverride(ACT_IDLE_ANGRY, NULL); + switch (idleact) + { +#if EXPANDED_HL2_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_REVOLVER: +#endif + case ACT_IDLE_ANGRY_PISTOL: return WEPCLASS_HANDGUN; +#if EXPANDED_HL2_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_CROSSBOW: // For now, crossbows are rifles +#endif +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_AR1: + case ACT_IDLE_ANGRY_SMG2: + case ACT_IDLE_ANGRY_SNIPER_RIFLE: +#endif + case ACT_IDLE_ANGRY_SMG1: + case ACT_IDLE_ANGRY_AR2: return WEPCLASS_RIFLE; + case ACT_IDLE_ANGRY_SHOTGUN: return WEPCLASS_SHOTGUN; + case ACT_IDLE_ANGRY_RPG: return WEPCLASS_HEAVY; + + case ACT_IDLE_ANGRY_MELEE: return WEPCLASS_MELEE; + } + return WEPCLASS_INVALID; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +WeaponClass_t CBaseCombatWeapon::WeaponClassFromString(const char *str) +{ + if (FStrEq(str, "WEPCLASS_HANDGUN")) + return WEPCLASS_HANDGUN; + else if (FStrEq(str, "WEPCLASS_RIFLE")) + return WEPCLASS_RIFLE; + else if (FStrEq(str, "WEPCLASS_SHOTGUN")) + return WEPCLASS_SHOTGUN; + else if (FStrEq(str, "WEPCLASS_HEAY")) + return WEPCLASS_HEAVY; + + else if (FStrEq(str, "WEPCLASS_MELEE")) + return WEPCLASS_MELEE; + + return WEPCLASS_INVALID; +} + +#ifdef HL2_DLL +extern acttable_t *GetSMG1Acttable(); +extern int GetSMG1ActtableCount(); + +extern acttable_t *GetAR2Acttable(); +extern int GetAR2ActtableCount(); + +extern acttable_t *GetShotgunActtable(); +extern int GetShotgunActtableCount(); + +extern acttable_t *GetPistolActtable(); +extern int GetPistolActtableCount(); + +extern acttable_t *Get357Acttable(); +extern int Get357ActtableCount(); +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CBaseCombatWeapon::SupportsBackupActivity(Activity activity) +{ + // Derived classes should override this. + +#ifdef HL2_DLL + // Melee users should not use SMG animations for missing activities. + if (IsMeleeWeapon() && GetBackupActivityList() == GetSMG1Acttable()) + return false; +#endif + + return true; +} + +acttable_t *CBaseCombatWeapon::GetBackupActivityList() +{ + return NULL; +} + +int CBaseCombatWeapon::GetBackupActivityListCount() +{ + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +acttable_t *CBaseCombatWeapon::GetDefaultBackupActivityList( acttable_t *pTable, int &actCount ) +{ +#ifdef HL2_DLL + // Ensure this isn't already a default backup activity list + if (pTable == GetSMG1Acttable() || pTable == GetPistolActtable()) + return NULL; + + // Use a backup table based on what ACT_IDLE_ANGRY is translated to + Activity actTranslated = ACT_INVALID; + for ( int i = 0; i < actCount; i++, pTable++ ) + { + if ( pTable->baseAct == ACT_IDLE_ANGRY ) + { + actTranslated = (Activity)pTable->weaponAct; + break; + } + } + + if (actTranslated == ACT_INVALID) + return NULL; + + switch (actTranslated) + { +#if EXPANDED_HL2_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_REVOLVER: +#endif + case ACT_IDLE_ANGRY_PISTOL: + { + actCount = GetPistolActtableCount(); + return GetPistolActtable(); + } +#if EXPANDED_HL2_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_CROSSBOW: // For now, crossbows are rifles +#endif +#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES + case ACT_IDLE_ANGRY_AR1: + case ACT_IDLE_ANGRY_SMG2: + case ACT_IDLE_ANGRY_SNIPER_RIFLE: +#endif + case ACT_IDLE_ANGRY_SMG1: + case ACT_IDLE_ANGRY_AR2: + case ACT_IDLE_ANGRY_SHOTGUN: + case ACT_IDLE_ANGRY_RPG: + { + actCount = GetSMG1ActtableCount(); + return GetSMG1Acttable(); + } + } +#endif + + actCount = 0; + return NULL; +} +#endif + + //----------------------------------------------------------------------------- // Purpose: Become a child of the owner (MOVETYPE_FOLLOW) // disables collisions, touch functions, thinking @@ -1009,6 +1264,12 @@ void CBaseCombatWeapon::Equip( CBaseCombatCharacter *pOwner ) } #endif +#ifdef MAPBASE + // Ammo may be overridden to 0, in which case we shouldn't autoswitch + if (m_iClip1 <= 0 && m_iClip2 <= 0) + AddSpawnFlags(SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY); +#endif + m_flNextPrimaryAttack = gpGlobals->curtime; m_flNextSecondaryAttack = gpGlobals->curtime; @@ -1161,7 +1422,7 @@ float CBaseCombatWeapon::GetViewModelSequenceDuration() return vm->SequenceDuration(); } -bool CBaseCombatWeapon::IsViewModelSequenceFinished( void ) const +bool CBaseCombatWeapon::IsViewModelSequenceFinished( void ) { // These are not valid activities and always complete immediately if ( GetActivity() == ACT_RESET || GetActivity() == ACT_INVALID ) @@ -1377,7 +1638,12 @@ bool CBaseCombatWeapon::ReloadOrSwitchWeapons( void ) if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime && m_flNextSecondaryAttack < gpGlobals->curtime ) { // weapon isn't useable, switch. +#ifdef MAPBASE + // Ammo might be overridden to 0, in which case we shouldn't do this + if ( ( (GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) == false ) && !HasSpawnFlags(SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY) && ( g_pGameRules->SwitchToNextBestWeapon( pOwner, this ) ) ) +#else if ( ( (GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) == false ) && ( g_pGameRules->SwitchToNextBestWeapon( pOwner, this ) ) ) +#endif { m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; return true; @@ -1429,6 +1695,10 @@ bool CBaseCombatWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, i SetViewModel(); SendWeaponAnim( iActivity ); + +#ifdef MAPBASE + pOwner->SetAnimation( PLAYER_UNHOLSTER ); +#endif pOwner->SetNextAttack( gpGlobals->curtime + SequenceDuration() ); } @@ -1464,12 +1734,7 @@ selects and deploys each weapon as you pass it. (sjb) bool CBaseCombatWeapon::Deploy( ) { MDLCACHE_CRITICAL_SECTION(); - bool bResult = DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), GetDrawActivity(), (char*)GetAnimPrefix() ); - - // override pose parameters - PoseParameterOverride( false ); - - return bResult; + return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), GetDrawActivity(), (char*)GetAnimPrefix() ); } Activity CBaseCombatWeapon::GetDrawActivity( void ) @@ -1505,32 +1770,42 @@ bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo ) if (pOwner) { pOwner->SetNextAttack( gpGlobals->curtime + flSequenceDuration ); + +#ifdef MAPBASE + if (IsWeaponVisible() && pOwner->IsPlayer()) + static_cast(pOwner)->SetAnimation( PLAYER_HOLSTER ); +#endif } - m_flNextPrimaryAttack = gpGlobals->curtime + flSequenceDuration + 0.1; - m_flNextSecondaryAttack = gpGlobals->curtime + flSequenceDuration + 0.1; +#ifdef VANCE m_pSwitchingTo = pSwitchingTo; +#endif // If we don't have a holster anim, hide immediately to avoid timing issues if ( !flSequenceDuration ) { SetWeaponVisible( false ); - if (pSwitchingTo) +#ifdef VANCE + if ( pSwitchingTo ) { #ifdef GAME_DLL - GetOwner()->SetActiveWeapon(m_pSwitchingTo); -#elif CLIENT_DLL - GetOwner()->m_hActiveWeapon = m_pSwitchingTo; -#endif // GAME_DLL + GetOwner()->SetActiveWeapon( m_pSwitchingTo ); +//#else +// GetOwner()->m_hActiveWeapon = m_pSwitchingTo; +#endif GetOwner()->GetActiveWeapon()->Deploy(); - m_pSwitchingTo = NULL; + m_pSwitchingTo = nullptr; } + +#endif } else { // Hide the weapon when the holster animation's finished - SetThink( &CBaseCombatWeapon::HideThink); - SetNextThink(gpGlobals->curtime); + SetContextThink( &CBaseCombatWeapon::HideThink, gpGlobals->curtime + flSequenceDuration, HIDEWEAPON_THINK_CONTEXT ); +#ifdef VANCE + SetNextThink( gpGlobals->curtime ); +#endif } // if we were displaying a hud hint, squelch it. @@ -1543,10 +1818,17 @@ bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo ) RescindReloadHudHint(); } +#ifdef MAPBASE + if (HasSpawnFlags(SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY)) + RemoveSpawnFlags(SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY); +#endif + +#ifdef VANCE // reset pose parameters m_flHolsterTime = gpGlobals->curtime + flSequenceDuration; m_bHolstering = true; PoseParameterOverride( true ); +#endif return true; } @@ -1567,46 +1849,178 @@ bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo ) } #else + +#ifdef MAPBASE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CBaseCombatWeapon::InputHideWeapon( inputdata_t &inputdata ) +void CBaseCombatWeapon::InputSetAmmo1( inputdata_t &inputdata ) { - // Only hide if we're still the active weapon. If we're not the active weapon - if ( GetOwner() && GetOwner()->GetActiveWeapon() == this ) + SetAmmoFromMapper(inputdata.value.Float()); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputSetAmmo2( inputdata_t &inputdata ) +{ + SetAmmoFromMapper(inputdata.value.Float(), true); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputGiveDefaultAmmo( inputdata_t &inputdata ) +{ + GiveDefaultAmmo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputEnablePlayerPickup( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_WEAPON_NO_PLAYER_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputDisablePlayerPickup( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_WEAPON_NO_PLAYER_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputEnableNPCPickup( inputdata_t &inputdata ) +{ + RemoveSpawnFlags(SF_WEAPON_NO_NPC_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputDisableNPCPickup( inputdata_t &inputdata ) +{ + AddSpawnFlags(SF_WEAPON_NO_NPC_PICKUP); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputBreakConstraint( inputdata_t &inputdata ) +{ + if ( m_pConstraint != NULL ) { - SetWeaponVisible( false ); + physenv->DestroyConstraint( m_pConstraint ); + m_pConstraint = NULL; } } -#endif //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CBaseCombatWeapon::HideThink( void ) +void CBaseCombatWeapon::InputForceFire( inputdata_t &inputdata, bool bSecondary ) { - // Only hide if we're still the active weapon. If we're not the active weapon - /*if ( GetOwner() && GetOwner()->GetActiveWeapon() == this ) + CBaseCombatCharacter *pOperator = GetOwner(); + + if (!pOperator) { - SetWeaponVisible( false ); - }*/ - if (m_bHolstering) + // No owner. This means they want us to fire while possibly on the floor independent of any NPC...the madmapper! + pOperator = ToBaseCombatCharacter(inputdata.pActivator); + if (pOperator && pOperator->IsNPC()) + { + // Use this guy, I guess + Operator_ForceNPCFire(pOperator, bSecondary); + } + else + { + // Well...I learned this trick from ent_info. If you have any better ideas, be my guest. + pOperator = CreateEntityByName("generic_actor")->MyCombatCharacterPointer(); + pOperator->SetAbsOrigin(GetAbsOrigin()); + pOperator->SetAbsAngles(GetAbsAngles()); + SetOwnerEntity(pOperator); + + Operator_ForceNPCFire(pOperator, bSecondary); + + UTIL_RemoveImmediate(pOperator); + } + } + else if (pOperator->IsPlayer()) { - if (m_flHolsterTime < gpGlobals->curtime && m_pSwitchingTo) + // Owner exists and is a player. + bSecondary ? SecondaryAttack() : PrimaryAttack(); + } + else + { + // Owner exists and is a NPC. + Operator_ForceNPCFire(pOperator, bSecondary); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputForcePrimaryFire( inputdata_t &inputdata ) +{ + InputForceFire(inputdata, false); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputForceSecondaryFire( inputdata_t &inputdata ) +{ + InputForceFire(inputdata, true); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::InputHideWeapon( inputdata_t &inputdata ) +{ +#ifdef VANCE + if ( m_bHolstering ) + { + if ( m_flHolsterTime < gpGlobals->curtime && m_pSwitchingTo ) { - SetWeaponVisible(false); + SetWeaponVisible( false ); #ifdef GAME_DLL - GetOwner()->SetActiveWeapon(m_pSwitchingTo); -#elif CLIENT_DLL + GetOwner()->SetActiveWeapon( m_pSwitchingTo ); +#else GetOwner()->m_hActiveWeapon = m_pSwitchingTo; -#endif // GAME_DLL +#endif GetOwner()->GetActiveWeapon()->Deploy(); - m_pSwitchingTo = NULL; + m_pSwitchingTo = nullptr; m_bHolstering = false; - SetThink(NULL); + SetThink( nullptr ); } } SetNextThink(gpGlobals->curtime); + +#else + // Only hide if we're still the active weapon. If we're not the active weapon + if ( GetOwner() && GetOwner()->GetActiveWeapon() == this ) + { + SetWeaponVisible( false ); + } +#endif +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::HideThink( void ) +{ + // Only hide if we're still the active weapon. If we're not the active weapon + if ( GetOwner() && GetOwner()->GetActiveWeapon() == this ) + { + SetWeaponVisible( false ); + } } bool CBaseCombatWeapon::CanReload( void ) @@ -1711,11 +2125,6 @@ void CBaseCombatWeapon::ItemPreFrame( void ) #endif } -bool CBaseCombatWeapon::CanPerformSecondaryAttack() const -{ - return m_flNextSecondaryAttack <= gpGlobals->curtime; -} - //==================================================================================== // WEAPON BEHAVIOUR //==================================================================================== @@ -1740,8 +2149,16 @@ void CBaseCombatWeapon::ItemPostFrame( void ) bool bFired = false; // Secondary attack has priority - if ((pOwner->m_nButtons & IN_ATTACK2) && CanPerformSecondaryAttack() ) + if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) { +#ifdef MAPBASE + if (pOwner->HasSpawnFlags(SF_PLAYER_SUPPRESS_FIRING)) + { + // Don't do anything, just cancel the whole function + return; + } + else +#endif if (UsesSecondaryAmmo() && pOwner->GetAmmoCount(m_iSecondaryAmmoType)<=0 ) { if (m_flNextEmptySoundTime < gpGlobals->curtime) @@ -1787,6 +2204,14 @@ void CBaseCombatWeapon::ItemPostFrame( void ) if ( !bFired && (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) { +#ifdef MAPBASE + if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING )) + { + // Don't do anything, just cancel the whole function + return; + } + else +#endif // Clip empty? Or out of ammo on a no-clip weapon? if ( !IsMeleeWeapon() && (( UsesClipsForAmmo1() && m_iClip1 <= 0) || ( !UsesClipsForAmmo1() && pOwner->GetAmmoCount(m_iPrimaryAmmoType)<=0 )) ) @@ -1829,8 +2254,8 @@ void CBaseCombatWeapon::ItemPostFrame( void ) // ----------------------- // Reload pressed / Clip Empty - // Can only start the Reload Cycle after the firing cycle - if ( ( pOwner->m_nButtons & IN_RELOAD ) && m_flNextPrimaryAttack <= gpGlobals->curtime && UsesClipsForAmmo1() && !m_bInReload ) + // ----------------------- + if ( ( pOwner->m_nButtons & IN_RELOAD ) && UsesClipsForAmmo1() && !m_bInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. Reload(); @@ -2116,6 +2541,28 @@ bool CBaseCombatWeapon::Reload( void ) return DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::Reload_NPC( bool bPlaySound ) +{ + if (bPlaySound) + WeaponSound( RELOAD_NPC ); + + if (UsesClipsForAmmo1()) + { + m_iClip1 = GetMaxClip1(); + } + else + { + // For weapons which don't use clips, give the owner ammo. + if (GetOwner()) + GetOwner()->SetAmmoCount( GetDefaultClip1(), m_iPrimaryAmmoType ); + } +} +#endif + //========================================================= void CBaseCombatWeapon::WeaponIdle( void ) { @@ -2494,25 +2941,24 @@ bool CBaseCombatWeapon::IsLocked( CBaseEntity *pAsker ) //----------------------------------------------------------------------------- Activity CBaseCombatWeapon::ActivityOverride( Activity baseAct, bool *pRequired ) { - int actCount = 0; - acttable_t *pTable = ActivityList( actCount ); + acttable_t *pTable = ActivityList(); + int actCount = ActivityListCount(); - for ( int i = 0; i < actCount; i++ ) + for ( int i = 0; i < actCount; i++, pTable++ ) { - const acttable_t& act = pTable[i]; - if ( baseAct == act.baseAct ) + if ( baseAct == pTable->baseAct ) { if (pRequired) { - *pRequired = act.required; + *pRequired = pTable->required; } - return (Activity)act.weaponAct; + return (Activity)pTable->weaponAct; } } return baseAct; } - +#ifdef VANCE //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -2539,7 +2985,25 @@ void CBaseCombatWeapon::PoseParameterOverride( bool bReset ) } } } +#endif + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HSCRIPT CBaseCombatWeapon::ScriptGetOwner() +{ + return ToHScript( GetOwner() ); +} +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseCombatWeapon::ScriptSetOwner( HSCRIPT owner ) +{ + return SetOwner( ToEnt( owner ) ? ToEnt( owner )->MyCombatCharacterPointer() : NULL ); +} +#endif //----------------------------------------------------------------------------- // Purpose: @@ -2675,6 +3139,111 @@ END_PREDICTION_DATA() // Special hack since we're aliasing the name C_BaseCombatWeapon with a macro on the client IMPLEMENT_NETWORKCLASS_ALIASED( BaseCombatWeapon, DT_BaseCombatWeapon ) +#ifdef MAPBASE_VSCRIPT + +// Don't allow client to use Set functions. +// They will only cause visual discrepancies, +// and will be reverted on the next update from the server. +#ifdef GAME_DLL +#define DEFINE_SCRIPTFUNC_SV( p1, p2 ) DEFINE_SCRIPTFUNC( p1, p2 ) +#define DEFINE_SCRIPTFUNC_NAMED_SV( p1, p2, p3 ) DEFINE_SCRIPTFUNC_NAMED( p1, p2, p3 ) + +#define DEFINE_SCRIPTFUNC_CL( p1, p2 ) +#define DEFINE_SCRIPTFUNC_NAMED_CL( p1, p2, p3 ) +#else +#define DEFINE_SCRIPTFUNC_SV( p1, p2 ) +#define DEFINE_SCRIPTFUNC_NAMED_SV( p1, p2, p3 ) + +#define DEFINE_SCRIPTFUNC_CL( p1, p2 ) DEFINE_SCRIPTFUNC( p1, p2 ) +#define DEFINE_SCRIPTFUNC_NAMED_CL( p1, p2, p3 ) DEFINE_SCRIPTFUNC_NAMED( p1, p2, p3 ) +#endif + +BEGIN_ENT_SCRIPTDESC( CBaseCombatWeapon, CBaseAnimating, "The base class for all equippable weapons." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetOwner, "GetOwner", "Get the weapon's owner." ) + DEFINE_SCRIPTFUNC_NAMED_SV( ScriptSetOwner, "SetOwner", "Set the weapon's owner." ) + + DEFINE_SCRIPTFUNC( Clip1, "Get the weapon's current primary ammo." ) + DEFINE_SCRIPTFUNC( Clip2, "Get the weapon's current secondary ammo." ) + DEFINE_SCRIPTFUNC_NAMED_SV( ScriptSetClip1, "SetClip1", "Set the weapon's current primary ammo." ) + DEFINE_SCRIPTFUNC_NAMED_SV( ScriptSetClip2, "SetClip2", "Set the weapon's current secondary ammo." ) + DEFINE_SCRIPTFUNC( GetMaxClip1, "Get the weapon's maximum primary ammo." ) + DEFINE_SCRIPTFUNC( GetMaxClip2, "Get the weapon's maximum secondary ammo." ) + DEFINE_SCRIPTFUNC( GetDefaultClip1, "Get the weapon's default primary ammo." ) + DEFINE_SCRIPTFUNC( GetDefaultClip2, "Get the weapon's default secondary ammo." ) + + DEFINE_SCRIPTFUNC( HasAnyAmmo, "Check if the weapon currently has ammo or doesn't need ammo." ) + DEFINE_SCRIPTFUNC( HasPrimaryAmmo, "Check if the weapon currently has ammo or doesn't need primary ammo." ) + DEFINE_SCRIPTFUNC( HasSecondaryAmmo, "Check if the weapon currently has ammo or doesn't need secondary ammo." ) + DEFINE_SCRIPTFUNC( UsesPrimaryAmmo, "Check if the weapon uses primary ammo." ) + DEFINE_SCRIPTFUNC( UsesSecondaryAmmo, "Check if the weapon uses secondary ammo." ) + DEFINE_SCRIPTFUNC_SV( GiveDefaultAmmo, "Fill the weapon back up to default ammo." ) + + DEFINE_SCRIPTFUNC( UsesClipsForAmmo1, "Check if the weapon uses clips for primary ammo." ) + DEFINE_SCRIPTFUNC( UsesClipsForAmmo2, "Check if the weapon uses clips for secondary ammo." ) + + DEFINE_SCRIPTFUNC( GetPrimaryAmmoType, "Get the weapon's primary ammo type." ) + DEFINE_SCRIPTFUNC( GetSecondaryAmmoType, "Get the weapon's secondary ammo type." ) + + DEFINE_SCRIPTFUNC( GetSubType, "Get the weapon's subtype." ) + DEFINE_SCRIPTFUNC_SV( SetSubType, "Set the weapon's subtype." ) + + DEFINE_SCRIPTFUNC( GetFireRate, "Get the weapon's firing rate." ) + DEFINE_SCRIPTFUNC( AddViewKick, "Applies the weapon's view kick." ) + + DEFINE_SCRIPTFUNC( GetWorldModel, "Get the weapon's world model." ) + DEFINE_SCRIPTFUNC( GetViewModel, "Get the weapon's view model." ) + DEFINE_SCRIPTFUNC( GetDroppedModel, "Get the weapon's unique dropped model if it has one." ) + + DEFINE_SCRIPTFUNC( GetWeight, "Get the weapon's weight." ) + DEFINE_SCRIPTFUNC( GetPrintName, "" ) + + DEFINE_SCRIPTFUNC_CL( GetSlot, "" ) + DEFINE_SCRIPTFUNC_CL( GetPosition, "" ) + + DEFINE_SCRIPTFUNC( CanBePickedUpByNPCs, "Check if the weapon can be picked up by NPCs." ) + + DEFINE_SCRIPTFUNC_SV( CapabilitiesGet, "Get the capabilities the weapon currently possesses." ) + + DEFINE_SCRIPTFUNC( HasWeaponIdleTimeElapsed, "Returns true if the idle time has elapsed." ) + DEFINE_SCRIPTFUNC( GetWeaponIdleTime, "Returns the next time WeaponIdle() will run." ) + DEFINE_SCRIPTFUNC_SV( SetWeaponIdleTime, "Sets the next time WeaponIdle() will run." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptWeaponClassify, "WeaponClassify", "Returns the weapon's classify class from the WEPCLASS_ constant group" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptWeaponSound, "WeaponSound", "Plays one of the weapon's sounds." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBulletSpread, "GetBulletSpread", "Returns the weapon's default bullet spread." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBulletSpreadForProficiency, "GetBulletSpreadForProficiency", "Returns the weapon's bullet spread for the specified proficiency level." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetPrimaryAttackActivity, "GetPrimaryAttackActivity", "Returns the weapon's primary attack activity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSecondaryAttackActivity, "GetSecondaryAttackActivity", "Returns the weapon's secondary attack activity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetDrawActivity, "GetDrawActivity", "Returns the weapon's draw activity." ) + DEFINE_SCRIPTFUNC( GetDefaultAnimSpeed, "Returns the weapon's default animation speed." ) + DEFINE_SCRIPTFUNC( SendWeaponAnim, "Sends a weapon animation." ) + DEFINE_SCRIPTFUNC( GetViewModelSequenceDuration, "Gets the sequence duration of the current view model animation." ) + DEFINE_SCRIPTFUNC( IsViewModelSequenceFinished, "Returns true if the current view model animation is finished." ) + + DEFINE_SCRIPTFUNC( FiresUnderwater, "Returns true if this weapon can fire underwater." ) + DEFINE_SCRIPTFUNC_SV( SetFiresUnderwater, "Sets whether this weapon can fire underwater." ) + DEFINE_SCRIPTFUNC( AltFiresUnderwater, "Returns true if this weapon can alt-fire underwater." ) + DEFINE_SCRIPTFUNC_SV( SetAltFiresUnderwater, "Sets whether this weapon can alt-fire underwater." ) + DEFINE_SCRIPTFUNC( MinRange1, "Returns the closest this weapon can be used." ) + DEFINE_SCRIPTFUNC_SV( SetMinRange1, "Sets the closest this weapon can be used." ) + DEFINE_SCRIPTFUNC( MinRange2, "Returns the closest this weapon can be used." ) + DEFINE_SCRIPTFUNC_SV( SetMinRange2, "Sets the closest this weapon can be used." ) + DEFINE_SCRIPTFUNC( ReloadsSingly, "Returns true if this weapon reloads 1 round at a time." ) + DEFINE_SCRIPTFUNC_SV( SetReloadsSingly, "Sets whether this weapon reloads 1 round at a time." ) + DEFINE_SCRIPTFUNC( FireDuration, "Returns the amount of time that the weapon has sustained firing." ) + DEFINE_SCRIPTFUNC_SV( SetFireDuration, "Sets the amount of time that the weapon has sustained firing." ) + + DEFINE_SCRIPTFUNC( NextPrimaryAttack, "Returns the next time PrimaryAttack() will run when the player is pressing +ATTACK." ) + DEFINE_SCRIPTFUNC_SV( SetNextPrimaryAttack, "Sets the next time PrimaryAttack() will run when the player is pressing +ATTACK." ) + DEFINE_SCRIPTFUNC( NextSecondaryAttack, "Returns the next time SecondaryAttack() will run when the player is pressing +ATTACK2." ) + DEFINE_SCRIPTFUNC_SV( SetNextSecondaryAttack, "Sets the next time SecondaryAttack() will run when the player is pressing +ATTACK2." ) + +END_SCRIPTDESC(); +#endif + #if !defined( CLIENT_DLL ) //----------------------------------------------------------------------------- // Purpose: Save Data for Base Weapon object @@ -2750,11 +3319,27 @@ BEGIN_DATADESC( CBaseCombatWeapon ) DEFINE_THINKFUNC( HideThink ), DEFINE_INPUTFUNC( FIELD_VOID, "HideWeapon", InputHideWeapon ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetAmmo1", InputSetAmmo1 ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetAmmo2", InputSetAmmo2 ), + DEFINE_INPUTFUNC( FIELD_VOID, "GiveDefaultAmmo", InputGiveDefaultAmmo ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnablePlayerPickup", InputEnablePlayerPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisablePlayerPickup", InputDisablePlayerPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnableNPCPickup", InputEnableNPCPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisableNPCPickup", InputDisableNPCPickup ), + DEFINE_INPUTFUNC( FIELD_VOID, "BreakConstraint", InputBreakConstraint ), + DEFINE_INPUTFUNC( FIELD_VOID, "ForcePrimaryFire", InputForcePrimaryFire ), + DEFINE_INPUTFUNC( FIELD_VOID, "ForceSecondaryFire", InputForceSecondaryFire ), +#endif + // Outputs DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse"), DEFINE_OUTPUT( m_OnPlayerPickup, "OnPlayerPickup"), DEFINE_OUTPUT( m_OnNPCPickup, "OnNPCPickup"), DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnDropped, "OnDropped" ), +#endif END_DATADESC() @@ -2801,6 +3386,16 @@ void* SendProxy_SendLocalWeaponDataTable( const SendProp *pProp, const void *pSt pRecipients->SetOnly( pPlayer->GetClientIndex() ); return (void*)pVarData; } +#ifdef MAPBASE + else if (pWeapon->HasSpawnFlags( SF_WEAPON_PRESERVE_AMMO )) + { + // Ammo values are sent to the client using this proxy. + // Preserved ammo values from the server need to be sent to the client ASAP to avoid HUD issues, etc. + // I've tried many nasty hacks, but this is the one that works well enough and there's not much else we could do. + pRecipients->SetAllRecipients(); + return (void*)pVarData; + } +#endif } return NULL; @@ -2829,13 +3424,6 @@ void* SendProxy_SendNonLocalWeaponDataTable( const SendProp *pProp, const void * } REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendNonLocalWeaponDataTable ); -#else -void CBaseCombatWeapon::RecvProxy_WeaponState( const CRecvProxyData *pData, void *pStruct, void *pOut ) -{ - CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pStruct; - pWeapon->m_iState = pData->m_Value.m_Int; - pWeapon->UpdateVisibility(); -} #endif #if PREDICTION_ERROR_CHECK_LEVEL > 1 @@ -2902,14 +3490,30 @@ BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon) SendPropDataTable("LocalActiveWeaponData", 0, &REFERENCE_SEND_TABLE(DT_LocalActiveWeaponData), SendProxy_SendActiveLocalWeaponDataTable ), SendPropModelIndex( SENDINFO(m_iViewModelIndex) ), SendPropModelIndex( SENDINFO(m_iWorldModelIndex) ), +#ifdef MAPBASE + SendPropModelIndex( SENDINFO(m_iDroppedModelIndex) ), +#endif SendPropInt( SENDINFO(m_iState ), 8, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO(m_hOwner) ), + +#ifdef MAPBASE + SendPropInt( SENDINFO(m_spawnflags), 8, SPROP_UNSIGNED ), +#endif + #else RecvPropDataTable("LocalWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalWeaponData)), RecvPropDataTable("LocalActiveWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalActiveWeaponData)), RecvPropInt( RECVINFO(m_iViewModelIndex)), RecvPropInt( RECVINFO(m_iWorldModelIndex)), - RecvPropInt( RECVINFO(m_iState), 0, &CBaseCombatWeapon::RecvProxy_WeaponState ), +#ifdef MAPBASE + RecvPropInt( RECVINFO(m_iDroppedModelIndex) ), +#endif + RecvPropInt( RECVINFO(m_iState )), RecvPropEHandle( RECVINFO(m_hOwner ) ), + +#ifdef MAPBASE + RecvPropInt( RECVINFO( m_spawnflags ) ), +#endif + #endif END_NETWORK_TABLE() diff --git a/game/shared/basecombatweapon_shared.h b/game/shared/basecombatweapon_shared.h index e40e6bea..08b6b345 100644 --- a/game/shared/basecombatweapon_shared.h +++ b/game/shared/basecombatweapon_shared.h @@ -48,6 +48,23 @@ class CUserCmd; #define SF_WEAPON_START_CONSTRAINED (1<<0) #define SF_WEAPON_NO_PLAYER_PICKUP (1<<1) #define SF_WEAPON_NO_PHYSCANNON_PUNT (1<<2) +#ifdef MAPBASE +// I really, REALLY hope no weapon uses their own spawnflags. +// If you want yours to use spawnflags, start at 16 just to be safe. + +#define SF_WEAPON_NO_NPC_PICKUP (1<<3) // Prevents NPCs from picking up the weapon. +#define SF_WEAPON_PRESERVE_AMMO (1<<4) // Prevents the weapon from filling up to max automatically when dropped or picked up by players. +#define SF_WEAPON_PRESERVE_NAME (1<<5) // Prevents the weapon's name from being cleared upon being picked up by a player. +#define SF_WEAPON_ALWAYS_TOUCHABLE (1<<6) // Makes a weapon always touchable/pickupable, even through walls. + +// ---------------------------------------------- +// These spawnflags are not supposed to be used by level designers. +// They're just my way of trying to avoid adding new variables +// that have to stay in memory and save/load. +// ---------------------------------------------- +#define SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY (1<<6) // So weapons with ammo preserved at 0 don't switch. +#define SF_WEAPON_USED (1<<7) // Weapon is being +USE'd, not bumped +#endif //Percent #define CLIP_PERC_THRESHOLD 0.75f @@ -55,7 +72,8 @@ class CUserCmd; // Put this in your derived class definition to declare it's activity table // UNDONE: Cascade these? #define DECLARE_ACTTABLE() static acttable_t m_acttable[];\ - virtual acttable_t *ActivityList( int &iActivityCount ) OVERRIDE; + acttable_t *ActivityList( void );\ + int ActivityListCount( void ); // You also need to include the activity table itself in your class' implementation: // e.g. @@ -72,7 +90,8 @@ class CUserCmd; // activity table. // UNDONE: Cascade these? #define IMPLEMENT_ACTTABLE(className) \ - acttable_t *className::ActivityList( int &iActivityCount ) { iActivityCount = ARRAYSIZE(m_acttable); return m_acttable; } + acttable_t *className::ActivityList( void ) { return m_acttable; } \ + int className::ActivityListCount( void ) { return ARRAYSIZE(m_acttable); } \ typedef struct { @@ -81,7 +100,7 @@ typedef struct bool required; } acttable_t; - +#ifdef VANCE struct poseparamtable_t { const char *pszName; @@ -89,8 +108,8 @@ struct poseparamtable_t }; // Put this in your derived class definition to declare it's poseparam table -#define DECLARE_POSEPARAMTABLE() static poseparamtable_t m_poseparamtable[];\ - virtual poseparamtable_t* PoseParamList( int &iPoseParamCount ) { return NULL; } +#define DECLARE_POSEPARAMTABLE() static poseparamtable_t m_poseparamtable[]; \ + virtual poseparamtable_t *PoseParamList( int &iPoseParamCount ) { return nullptr; } // You also need to include the activity table itself in your class' implementation: // e.g. @@ -102,7 +121,8 @@ struct poseparamtable_t // The grapplinghook overrides the r_arm pose param, value to 2. #define IMPLEMENT_POSEPARAMTABLE(className)\ - poseparamtable_t* className::PoseParamList( int &iPoseParamCount ) { iPoseParamCount = ARRAYSIZE(m_poseparamtable); return m_poseparamtable; } + poseparamtable_t *className::PoseParamList( int &iPoseParamCount ) { iPoseParamCount = ARRAYSIZE( m_poseparamtable ); return m_poseparamtable; } +#endif class CHudTexture; class Color; @@ -112,6 +132,26 @@ namespace vgui2 typedef unsigned long HFont; } +#ifdef MAPBASE +// ------------------ +// Weapon classes +// ------------------ +// I found myself in situations where this is useful. +// Their purpose is similar to Class_T on NPCs. + +enum WeaponClass_t +{ + WEPCLASS_INVALID = 0, + + WEPCLASS_HANDGUN, + WEPCLASS_RIFLE, + WEPCLASS_SHOTGUN, + WEPCLASS_HEAVY, + + WEPCLASS_MELEE, +}; +#endif + // ----------------------------------------- // Vector cones // ----------------------------------------- @@ -180,6 +220,9 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM DECLARE_CLASS( CBaseCombatWeapon, BASECOMBATWEAPON_DERIVED_FROM ); DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif CBaseCombatWeapon(); virtual ~CBaseCombatWeapon(); @@ -194,12 +237,28 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual void Spawn( void ); virtual void Precache( void ); - virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ); +#ifdef MAPBASE + void SetAmmoFromMapper( float flAmmo, bool bSecondary = false ); + virtual bool KeyValue( const char *szKeyName, const char *szValue ); + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); +#endif + + void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ); // Subtypes are used to manage multiple weapons of the same type on the player. virtual int GetSubType( void ) { return m_iSubType; } virtual void SetSubType( int iType ) { m_iSubType = iType; } +#ifdef MAPBASE + virtual WeaponClass_t WeaponClassify(); + static WeaponClass_t WeaponClassFromString(const char *str); + + virtual bool SupportsBackupActivity(Activity activity); + virtual acttable_t *GetBackupActivityList(); + virtual int GetBackupActivityListCount(); + static acttable_t *GetDefaultBackupActivityList( acttable_t *pTable, int &actCount ); +#endif + virtual void Equip( CBaseCombatCharacter *pOwner ); virtual void Drop( const Vector &vecVelocity ); @@ -229,7 +288,7 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual bool SendWeaponAnim( int iActivity ); virtual void SendViewModelAnim( int nSequence ); float GetViewModelSequenceDuration(); // Return how long the current view model sequence is. - bool IsViewModelSequenceFinished( void ) const; // Returns if the viewmodel's current animation is finished + bool IsViewModelSequenceFinished( void ); // Returns if the viewmodel's current animation is finished virtual void SetViewModel(); @@ -245,7 +304,7 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM bool UsesSecondaryAmmo( void ); // returns true if the weapon actually uses secondary ammo void GiveDefaultAmmo( void ); - virtual bool CanHolster( void ) const { return TRUE; }; // returns true if the weapon can be holstered + virtual bool CanHolster( void ) { return TRUE; }; // returns true if the weapon can be holstered virtual bool DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt ); virtual bool CanDeploy( void ) { return true; } // return true if the weapon's allowed to deploy virtual bool Deploy( void ); // returns true is deploy was successful @@ -268,7 +327,6 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual void HandleFireOnEmpty(); // Called when they have the attack button down // but they are out of ammo. The default implementation // either reloads, switches weapons, or plays an empty sound. - virtual bool CanPerformSecondaryAttack() const; virtual bool ShouldBlockPrimaryFire() { return false; } @@ -286,8 +344,13 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual bool Reload( void ); bool DefaultReload( int iClipSize1, int iClipSize2, int iActivity ); bool ReloadsSingly( void ) const; +#ifdef MAPBASE + // Originally created for the crossbow, can be used to add special NPC reloading behavior + virtual void Reload_NPC( bool bPlaySound = true ); +#endif - virtual bool AutoFiresFullClip( void ) const { return false; } + virtual bool AutoFiresFullClip( void ) { return false; } + virtual bool CanOverload( void ) { return false; } virtual void UpdateAutoFire( void ); // Weapon firing @@ -328,7 +391,7 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual void SetActivity( Activity act, float duration ); inline void SetActivity( Activity eActivity ) { m_Activity = eActivity; } - inline Activity GetActivity( void ) const { return m_Activity; } + inline Activity GetActivity( void ) { return m_Activity; } virtual void AddViewKick( void ); // Add in the view kick for the weapon @@ -369,7 +432,6 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual int GetWeight( void ) const; virtual bool AllowsAutoSwitchTo( void ) const; virtual bool AllowsAutoSwitchFrom( void ) const; - virtual bool ForceWeaponSwitch( void ) const { return false; } virtual int GetWeaponFlags( void ) const; virtual int GetSlot( void ) const; virtual int GetPosition( void ) const; @@ -380,6 +442,14 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual bool UsesClipsForAmmo1( void ) const; virtual bool UsesClipsForAmmo2( void ) const; bool IsMeleeWeapon() const; +#ifdef MAPBASE + float GetViewmodelFOVOverride() const; + float GetBobScale() const; + float GetSwayScale() const; + float GetSwaySpeedScale() const; + virtual const char *GetDroppedModel( void ) const; + bool UsesHands( void ) const; +#endif // derive this function if you mod uses encrypted weapon info files virtual const unsigned char *GetEncryptionKey( void ); @@ -408,16 +478,67 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual CHudTexture const *GetSpriteZoomedAutoaim( void ) const; virtual Activity ActivityOverride( Activity baseAct, bool *pRequired ); - virtual acttable_t* ActivityList( int &iActivityCount ) { return NULL; } + virtual acttable_t* ActivityList( void ) { return NULL; } + virtual int ActivityListCount( void ) { return 0; } - virtual void PoseParameterOverride( bool bReset ); - virtual poseparamtable_t* PoseParamList( int &iPoseParamCount ) { return NULL; } +#ifdef VANCE + virtual void PoseParameterOverride( bool bReset ); + virtual poseparamtable_t *PoseParamList( int &iPoseParamCount ) { return nullptr; } +#endif virtual void Activate( void ); virtual bool ShouldUseLargeViewModelVROverride() { return false; } - CBaseCombatWeapon* m_pSwitchingTo; +#ifdef VANCE + CBaseCombatWeapon *m_pSwitchingTo = nullptr; +#endif + +#ifdef MAPBASE + // Gets the weapon script name to load. + virtual const char* GetWeaponScriptName() { return GetClassname(); } +#endif + +#ifdef MAPBASE_VSCRIPT + void ScriptSetClip1( int ammo ) { m_iClip1 = ammo; } + void ScriptSetClip2( int ammo ) { m_iClip2 = ammo; } + + HSCRIPT ScriptGetOwner(); + void ScriptSetOwner( HSCRIPT owner ); + + int ScriptWeaponClassify() { return WeaponClassify(); } + void ScriptWeaponSound( int sound_type, float soundtime = 0.0f ) { WeaponSound( (WeaponSound_t)sound_type, soundtime ); } + + const Vector& ScriptGetBulletSpread( void ) { return GetBulletSpread(); } + Vector ScriptGetBulletSpreadForProficiency( int proficiency ) { return GetBulletSpread( (WeaponProficiency_t)proficiency ); } + + int ScriptGetPrimaryAttackActivity( void ) { return GetPrimaryAttackActivity(); } + int ScriptGetSecondaryAttackActivity( void ) { return GetSecondaryAttackActivity(); } + int ScriptGetDrawActivity( void ) { return GetDrawActivity(); } + + bool FiresUnderwater() { return m_bFiresUnderwater; } + void SetFiresUnderwater( bool bVal ) { m_bFiresUnderwater = bVal; } + bool AltFiresUnderwater() { return m_bAltFiresUnderwater; } + void SetAltFiresUnderwater( bool bVal ) { m_bAltFiresUnderwater = bVal; } + float MinRange1() { return m_fMinRange1; } + void SetMinRange1( float flVal ) { m_fMinRange1 = flVal; } + float MinRange2() { return m_fMinRange2; } + void SetMinRange2( float flVal ) { m_fMinRange2 = flVal; } + float MaxRange1() { return m_fMaxRange1; } + void SetMaxRange1( float flVal ) { m_fMaxRange1 = flVal; } + float MaxRange2() { return m_fMaxRange2; } + void SetMaxRange2( float flVal ) { m_fMaxRange2 = flVal; } + //bool ReloadsSingly() { return m_bReloadsSingly; } + void SetReloadsSingly( bool bVal ) { m_bReloadsSingly = bVal; } + float FireDuration() { return m_fFireDuration; } + void SetFireDuration( float flVal ) { m_fFireDuration = flVal; } + + float NextPrimaryAttack() { return m_flNextPrimaryAttack; } + void SetNextPrimaryAttack( float flVal ) { m_flNextPrimaryAttack = flVal; } + float NextSecondaryAttack() { return m_flNextSecondaryAttack; } + void SetNextSecondaryAttack( float flVal ) { m_flNextSecondaryAttack = flVal; } +#endif + public: // Server Only Methods #if !defined( CLIENT_DLL ) @@ -464,6 +585,19 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual int UpdateTransmitState( void ); +#ifdef MAPBASE + void InputSetAmmo1( inputdata_t &inputdata ); + void InputSetAmmo2( inputdata_t &inputdata ); + void InputGiveDefaultAmmo( inputdata_t &inputdata ); + void InputEnablePlayerPickup( inputdata_t &inputdata ); + void InputDisablePlayerPickup( inputdata_t &inputdata ); + void InputEnableNPCPickup( inputdata_t &inputdata ); + void InputDisableNPCPickup( inputdata_t &inputdata ); + void InputBreakConstraint( inputdata_t &inputdata ); + void InputForceFire( inputdata_t &inputdata, bool bSecondary = false ); + void InputForcePrimaryFire( inputdata_t &inputdata ); + void InputForceSecondaryFire( inputdata_t &inputdata ); +#endif void InputHideWeapon( inputdata_t &inputdata ); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); @@ -526,6 +660,7 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM virtual int GetWorldModelIndex( void ); virtual void GetToolRecordingState( KeyValues *msg ); + void EnsureCorrectRenderingModel(); virtual void GetWeaponCrosshairScale( float &flScale ) { flScale = 1.f; } @@ -538,6 +673,9 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM bool WantsToOverrideViewmodelAttachments( void ) { return false; } #endif + //Tony; notifications of any third person switches. + virtual void ThirdPersonSwitch( bool bThirdPerson ) {}; + #endif // End client-only methods virtual bool CanLower( void ) { return false; } @@ -579,6 +717,9 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM // Weapon art CNetworkVar( int, m_iViewModelIndex ); CNetworkVar( int, m_iWorldModelIndex ); +#ifdef MAPBASE + CNetworkVar( int, m_iDroppedModelIndex ); +#endif // Sounds float m_flNextEmptySoundTime; // delay on empty sound playing @@ -591,6 +732,7 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM protected: float m_flHolsterTime; bool m_bHolstering; + private: Activity m_Activity; int m_nIdealSequence; @@ -601,14 +743,10 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM int m_iPrimaryAmmoCount; int m_iSecondaryAmmoCount; - public: IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_nNextThinkTick ); -#ifdef CLIENT_DLL - static void RecvProxy_WeaponState( const CRecvProxyData *pData, void *pStruct, void *pOut ); -#endif int WeaponState() const { return m_iState; } // Weapon data @@ -633,6 +771,18 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM CNetworkVar( bool, m_bFlipViewModel ); +#ifdef MAPBASE +#ifdef CLIENT_DLL + int m_spawnflags; + + inline bool HasSpawnFlags( int flags ) { return (m_spawnflags & flags) != 0; } + inline void RemoveSpawnFlags( int flags ) { m_spawnflags &= ~flags; } + inline void AddSpawnFlags( int flags ) { m_spawnflags |= flags; } +#else + //IMPLEMENT_NETWORK_VAR_FOR_DERIVED(m_spawnflags); +#endif +#endif + IPhysicsConstraint *GetConstraint() { return m_pConstraint; } private: @@ -655,6 +805,9 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM COutputEvent m_OnPlayerPickup; // Fired when the player picks up the weapon. COutputEvent m_OnNPCPickup; // Fired when an NPC picks up the weapon. COutputEvent m_OnCacheInteraction; // For awarding lambda cache achievements in HL2 on 360. See .FGD file for details +#ifdef MAPBASE + COutputEvent m_OnDropped; +#endif #else // Client .dll only bool m_bJustRestored; diff --git a/game/shared/baseentity_shared.cpp b/game/shared/baseentity_shared.cpp index 7c171a97..b35ba19f 100644 --- a/game/shared/baseentity_shared.cpp +++ b/game/shared/baseentity_shared.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -29,7 +29,9 @@ #include "player_pickup.h" #include "waterbullet.h" #include "func_break.h" - #include "projectile_bullet.h" +#ifdef VANCE + #include "projectile_bullet.h" +#endif #ifdef HL2MP #include "te_hl2mp_shotgun_shot.h" @@ -54,6 +56,10 @@ ConVar hl2_episodic( "hl2_episodic", "0", FCVAR_REPLICATED ); #include "tf_weaponbase.h" #endif // TF_DLL +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" +#endif + #include "rumble_shared.h" // memdbgon must be the last include file in a .cpp file!!! @@ -80,7 +86,7 @@ ConVar ai_shot_bias_min( "ai_shot_bias_min", "-1.0", FCVAR_REPLICATED ); ConVar ai_shot_bias_max( "ai_shot_bias_max", "1.0", FCVAR_REPLICATED ); ConVar ai_debug_shoot_positions( "ai_debug_shoot_positions", "0", FCVAR_REPLICATED | FCVAR_CHEAT ); -ConVar sv_bulletspeed_override("sv_bulletspeed_override", "0", FCVAR_CHEAT | FCVAR_REPLICATED); +ConVar sv_bulletspeed_override( "sv_bulletspeed_override", "0", FCVAR_CHEAT | FCVAR_REPLICATED ); // Utility func to throttle rate at which the "reasonable position" spew goes out static double s_LastEntityReasonableEmitTime; @@ -133,8 +139,8 @@ void CBaseEntity::UnsetPlayerSimulated( void ) // position of eyes Vector CBaseEntity::EyePosition( void ) -{ - return GetAbsOrigin() + GetViewOffset(); +{ + return GetAbsOrigin() + GetViewOffset(); } const QAngle &CBaseEntity::EyeAngles( void ) @@ -149,25 +155,25 @@ const QAngle &CBaseEntity::LocalEyeAngles( void ) // position of ears Vector CBaseEntity::EarPosition( void ) -{ - return EyePosition(); +{ + return EyePosition(); } -void CBaseEntity::SetViewOffset( const Vector& v ) -{ - m_vecViewOffset = v; +void CBaseEntity::SetViewOffset( const Vector& v ) +{ + m_vecViewOffset = v; } -const Vector& CBaseEntity::GetViewOffset() const -{ - return m_vecViewOffset; +const Vector& CBaseEntity::GetViewOffset() const +{ + return m_vecViewOffset; } //----------------------------------------------------------------------------- // center point of entity //----------------------------------------------------------------------------- -const Vector &CBaseEntity::WorldSpaceCenter( ) const +const Vector &CBaseEntity::WorldSpaceCenter( ) const { return CollisionProp()->WorldSpaceCenter(); } @@ -229,8 +235,8 @@ void CBaseEntity::SetEffects( int nEffects ) } } -void CBaseEntity::AddEffects( int nEffects ) -{ +void CBaseEntity::AddEffects( int nEffects ) +{ #if !defined( CLIENT_DLL ) #ifdef HL2_EPISODIC if ( (nEffects & (EF_BRIGHTLIGHT|EF_DIMLIGHT)) && !(m_fEffects & (EF_BRIGHTLIGHT|EF_DIMLIGHT)) ) @@ -244,7 +250,7 @@ void CBaseEntity::AddEffects( int nEffects ) #endif // HL2_EPISODIC #endif // !CLIENT_DLL - m_fEffects |= nEffects; + m_fEffects |= nEffects; if ( nEffects & EF_NODRAW) { @@ -268,9 +274,9 @@ void CBaseEntity::SetBlocksLOS( bool bBlocksLOS ) } } -bool CBaseEntity::BlocksLOS( void ) -{ - return !IsEFlagSet(EFL_DONTBLOCKLOS); +bool CBaseEntity::BlocksLOS( void ) +{ + return !IsEFlagSet(EFL_DONTBLOCKLOS); } void CBaseEntity::SetAIWalkable( bool bBlocksLOS ) @@ -285,8 +291,8 @@ void CBaseEntity::SetAIWalkable( bool bBlocksLOS ) } } -bool CBaseEntity::IsAIWalkable( void ) -{ +bool CBaseEntity::IsAIWalkable( void ) +{ return !IsEFlagSet(EFL_DONTWALKON); } @@ -309,10 +315,10 @@ void CBaseEntity::ParseMapData( CEntityMapData *mapData ) // loop through all keys in the data block and pass the info back into the object if ( mapData->GetFirstKey(keyName, value) ) { - do + do { KeyValue( keyName, value ); - } + } while ( mapData->GetNextKey(keyName, value) ); } } @@ -320,7 +326,7 @@ void CBaseEntity::ParseMapData( CEntityMapData *mapData ) //----------------------------------------------------------------------------- // Parse data from a map file //----------------------------------------------------------------------------- -bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) +bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) { //!! temp hack, until worldcraft is fixed // strip the # tokens from (duplicate) key names @@ -338,7 +344,7 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) // don't copy alpha, legacy support uses renderamt return true; } - + if ( FStrEq( szKeyName, "renderamt" ) ) { SetRenderColorA( atoi( szValue ) ); @@ -411,7 +417,11 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) } // Do this so inherited classes looking for 'angles' don't have to bother with 'angle' +#ifdef MAPBASE + return KeyValue( "angles", szBuf ); +#else return KeyValue( szKeyName, szBuf ); +#endif } // NOTE: Have to do these separate because they set two values instead of one @@ -439,8 +449,17 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) return true; } -#ifdef GAME_DLL - +#ifdef MAPBASE + if ( FStrEq( szKeyName, "eflags" ) ) + { + // Can't use DEFINE_KEYFIELD since eflags might be set before KV are parsed + AddEFlags( atoi( szValue ) ); + return true; + } +#endif + +#ifdef GAME_DLL + if ( FStrEq( szKeyName, "targetname" ) ) { m_iName = AllocPooledString( szValue ); @@ -483,7 +502,7 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) { if ( printKeyHits ) Msg( "(%s) key: %-16s value: %s\n", debugName, szKeyName, szValue ); - + return true; } } @@ -498,7 +517,7 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const char *szValue ) return false; } -bool CBaseEntity::KeyValue( const char *szKeyName, float flValue ) +bool CBaseEntity::KeyValue( const char *szKeyName, float flValue ) { char string[256]; @@ -507,7 +526,7 @@ bool CBaseEntity::KeyValue( const char *szKeyName, float flValue ) return KeyValue( szKeyName, string ); } -bool CBaseEntity::KeyValue( const char *szKeyName, const Vector &vecValue ) +bool CBaseEntity::KeyValue( const char *szKeyName, const Vector &vecValue ) { char string[256]; @@ -517,7 +536,7 @@ bool CBaseEntity::KeyValue( const char *szKeyName, const Vector &vecValue ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Input : // Output : //----------------------------------------------------------------------------- @@ -530,7 +549,7 @@ bool CBaseEntity::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen Q_snprintf( szValue, iMaxLen, "%d %d %d %d", tmp.r, tmp.g, tmp.b, tmp.a ); return true; } - + if ( FStrEq( szKeyName, "renderamt" ) ) { color32 tmp = GetRenderColor(); @@ -590,8 +609,8 @@ bool CBaseEntity::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen return true; } -#ifdef GAME_DLL - +#ifdef GAME_DLL + if ( FStrEq( szKeyName, "targetname" ) ) { Q_snprintf( szValue, iMaxLen, "%s", STRING( GetEntityName() ) ); @@ -615,8 +634,8 @@ bool CBaseEntity::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen } //----------------------------------------------------------------------------- -// Purpose: -// Input : collisionGroup - +// Purpose: +// Input : collisionGroup - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CBaseEntity::ShouldCollide( int collisionGroup, int contentsMask ) const @@ -631,25 +650,18 @@ bool CBaseEntity::ShouldCollide( int collisionGroup, int contentsMask ) const //----------------------------------------------------------------------------- -// Purpose: -// Input : seed - +// Purpose: +// Input : seed - //----------------------------------------------------------------------------- void CBaseEntity::SetPredictionRandomSeed( const CUserCmd *cmd ) { if ( !cmd ) { m_nPredictionRandomSeed = -1; -#ifdef GAME_DLL - m_nPredictionRandomSeedServer = -1; -#endif - return; } m_nPredictionRandomSeed = ( cmd->random_seed ); -#ifdef GAME_DLL - m_nPredictionRandomSeedServer = ( cmd->server_random_seed ); -#endif } @@ -678,7 +690,7 @@ void CBaseEntity::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCu Assert( pTrace->m_pEnt ); CBaseEntity *pEntity = pTrace->m_pEnt; - + // Build the impact data CEffectData data; data.m_vOrigin = pTrace->endpos; @@ -724,7 +736,7 @@ char const *CBaseEntity::DamageDecal( int bitsDamageType, int gameMaterial ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int CBaseEntity::GetIndexForThinkContext( const char *pszContext ) { @@ -758,7 +770,7 @@ int CBaseEntity::RegisterThinkContext( const char *szContext ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- BASEPTR CBaseEntity::ThinkSet( BASEPTR func, float thinkTime, const char *szContext ) { @@ -778,7 +790,7 @@ BASEPTR CBaseEntity::ThinkSet( BASEPTR func, float thinkTime, const char *szCont m_pfnThink = func; #if !defined( CLIENT_DLL ) #ifdef _DEBUG - FunctionCheck( *(reinterpret_cast(&m_pfnThink)), "BaseThinkFunc" ); + FunctionCheck( *(reinterpret_cast(&m_pfnThink)), "BaseThinkFunc" ); #endif #endif return m_pfnThink; @@ -794,7 +806,7 @@ BASEPTR CBaseEntity::ThinkSet( BASEPTR func, float thinkTime, const char *szCont m_aThinkFunctions[ iIndex ].m_pfnThink = func; #if !defined( CLIENT_DLL ) #ifdef _DEBUG - FunctionCheck( *(reinterpret_cast(&m_aThinkFunctions[ iIndex ].m_pfnThink)), szContext ); + FunctionCheck( *(reinterpret_cast(&m_aThinkFunctions[ iIndex ].m_pfnThink)), szContext ); #endif #endif @@ -808,7 +820,7 @@ BASEPTR CBaseEntity::ThinkSet( BASEPTR func, float thinkTime, const char *szCont } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseEntity::SetNextThink( float thinkTime, const char *szContext ) { @@ -846,7 +858,7 @@ void CBaseEntity::SetNextThink( float thinkTime, const char *szContext ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- float CBaseEntity::GetNextThink( const char *szContext ) { @@ -920,7 +932,7 @@ int CBaseEntity::GetNextThinkTick( const char *szContext /*= NULL*/ ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- float CBaseEntity::GetLastThink( const char *szContext ) { @@ -945,7 +957,7 @@ float CBaseEntity::GetLastThink( const char *szContext ) return m_aThinkFunctions[ iIndex ].m_nLastThinkTick * TICK_INTERVAL; } - + int CBaseEntity::GetLastThinkTick( const char *szContext /*= NULL*/ ) { // Are we currently in a think function with a context? @@ -1030,7 +1042,7 @@ bool CBaseEntity::WillSimulateGamePhysics() if ( !IsPlayer() ) { MoveType_t movetype = GetMoveType(); - + if ( movetype == MOVETYPE_NONE || movetype == MOVETYPE_VPHYSICS ) return false; @@ -1099,7 +1111,7 @@ float CBaseEntity::GetNextThink( int nContextIndex ) const if (nContextIndex < 0) return m_nNextThinkTick * TICK_INTERVAL; - return m_aThinkFunctions[nContextIndex].m_nNextThinkTick * TICK_INTERVAL; + return m_aThinkFunctions[nContextIndex].m_nNextThinkTick * TICK_INTERVAL; } int CBaseEntity::GetNextThinkTick( int nContextIndex ) const @@ -1107,7 +1119,7 @@ int CBaseEntity::GetNextThinkTick( int nContextIndex ) const if (nContextIndex < 0) return m_nNextThinkTick; - return m_aThinkFunctions[nContextIndex].m_nNextThinkTick; + return m_aThinkFunctions[nContextIndex].m_nNextThinkTick; } @@ -1161,7 +1173,7 @@ void CBaseEntity::VPhysicsUpdate( IPhysicsObject *pPhysics ) } angles = vec3_angle; } -#ifndef CLIENT_DLL +#ifndef CLIENT_DLL Vector prevOrigin = GetAbsOrigin(); #endif @@ -1189,7 +1201,7 @@ void CBaseEntity::VPhysicsUpdate( IPhysicsObject *pPhysics ) SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } -#ifndef CLIENT_DLL +#ifndef CLIENT_DLL PhysicsTouchTriggers( &prevOrigin ); PhysicsRelinkChildren(gpGlobals->frametime); #endif @@ -1248,8 +1260,8 @@ IPhysicsObject *CBaseEntity::VPhysicsInitStatic( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pPhysics - +// Purpose: +// Input : *pPhysics - //----------------------------------------------------------------------------- void CBaseEntity::VPhysicsSetObject( IPhysicsObject *pPhysics ) { @@ -1265,7 +1277,7 @@ void CBaseEntity::VPhysicsSetObject( IPhysicsObject *pPhysics ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CBaseEntity::VPhysicsDestroyObject( void ) { @@ -1280,7 +1292,7 @@ void CBaseEntity::VPhysicsDestroyObject( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseEntity::VPhysicsInitSetup() { @@ -1379,7 +1391,7 @@ IPhysicsObject *CBaseEntity::VPhysicsInitShadow( bool allowPhysicsMovement, bool //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool CBaseEntity::CreateVPhysics() { @@ -1388,20 +1400,20 @@ bool CBaseEntity::CreateVPhysics() bool CBaseEntity::IsStandable() const { - if (GetSolidFlags() & FSOLID_NOT_STANDABLE) + if (GetSolidFlags() & FSOLID_NOT_STANDABLE) return false; if ( GetSolid() == SOLID_BSP || GetSolid() == SOLID_VPHYSICS || GetSolid() == SOLID_BBOX ) return true; - return IsBSPModel( ); + return IsBSPModel( ); } bool CBaseEntity::IsBSPModel() const { if ( GetSolid() == SOLID_BSP ) return true; - + const model_t *model = modelinfo->GetModel( GetModelIndex() ); if ( GetSolid() == SOLID_VPHYSICS && modelinfo->GetModelType( model ) == mod_brush ) @@ -1417,10 +1429,10 @@ bool CBaseEntity::IsBSPModel() const void CBaseEntity::InvalidatePhysicsRecursive( int nChangeFlags ) { // Main entry point for dirty flag setting for the 90% case - // 1) If the origin changes, then we have to update abstransform, Shadow projection, PVS, KD-tree, + // 1) If the origin changes, then we have to update abstransform, Shadow projection, PVS, KD-tree, // client-leaf system. // 2) If the angles change, then we have to update abstransform, Shadow projection, - // shadow render-to-texture, client-leaf system, and surrounding bounds. + // shadow render-to-texture, client-leaf system, and surrounding bounds. // Children have to additionally update absvelocity, KD-tree, and PVS. // If the surrounding bounds actually update, when we also need to update the KD-tree and the PVS. // 3) If it's due to attachment, then all children who are attached to an attachment point @@ -1428,7 +1440,7 @@ void CBaseEntity::InvalidatePhysicsRecursive( int nChangeFlags ) // Other stuff: // 1) Marking the surrounding bounds dirty will automatically mark KD tree + PVS dirty. - + int nDirtyFlags = 0; if ( nChangeFlags & VELOCITY_CHANGED ) @@ -1526,7 +1538,7 @@ void CBaseEntity::InvalidatePhysicsRecursive( int nChangeFlags ) // { // C_BaseAnimating *pAnim = GetBaseAnimating(); // if ( pAnim ) - // pAnim->InvalidateBoneCache(); + // pAnim->InvalidateBoneCache(); // } //#endif } @@ -1560,7 +1572,7 @@ bool CBaseEntity::IsPrecacheAllowed() //----------------------------------------------------------------------------- // Purpose: static method -// Input : allow - +// Input : allow - //----------------------------------------------------------------------------- void CBaseEntity::SetAllowPrecache( bool allow ) { @@ -1587,8 +1599,8 @@ class CBulletsTraceFilter : public CTraceFilterSimpleList { CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); CBaseEntity *pPassEntity = EntityFromEntityHandle( m_PassEntities[0] ); - if ( pEntity && pPassEntity && pEntity->GetOwnerEntity() == pPassEntity && - pPassEntity->IsSolidFlagSet(FSOLID_NOT_SOLID) && pPassEntity->IsSolidFlagSet( FSOLID_CUSTOMBOXTEST ) && + if ( pEntity && pPassEntity && pEntity->GetOwnerEntity() == pPassEntity && + pPassEntity->IsSolidFlagSet(FSOLID_NOT_SOLID) && pPassEntity->IsSolidFlagSet( FSOLID_CUSTOMBOXTEST ) && pPassEntity->IsSolidFlagSet( FSOLID_CUSTOMRAYTEST ) ) { // It's a bone follower of the entity to ignore (toml 8/3/2007) @@ -1603,6 +1615,7 @@ class CBulletsTraceFilter : public CTraceFilterSimpleList typedef CTraceFilterSimpleList CBulletsTraceFilter; #endif + #ifdef VANCE void CBaseEntity::FireBulletProjectiles(const ProjectileBulletsInfo_t& info) { @@ -1709,12 +1722,29 @@ void CBaseEntity::FireBulletProjectiles(const ProjectileBulletsInfo_t& info) void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) { +#if defined(MAPBASE_VSCRIPT) && defined(GAME_DLL) + if ( m_ScriptScope.IsInitialized() && g_Hook_FireBullets.CanRunInScope( m_ScriptScope ) ) + { + HSCRIPT hInfo = g_pScriptVM->RegisterInstance( const_cast(&info) ); + + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { hInfo }; + if (g_Hook_FireBullets.Call( m_ScriptScope, &functionReturn, args )) + { + if (!functionReturn.m_bool) + return; + } + + g_pScriptVM->RemoveInstance( hInfo ); + } +#endif + static int tracerCount; trace_t tr; CAmmoDef* pAmmoDef = GetAmmoDef(); int nDamageType = pAmmoDef->DamageType(info.m_iAmmoType); int nAmmoFlags = pAmmoDef->Flags(info.m_iAmmoType); - + bool bDoServerEffects = true; #if defined( HL2MP ) && defined( GAME_DLL ) @@ -1761,13 +1791,13 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) { ApplyMultiDamage(); } - + ClearMultiDamage(); g_MultiDamage.SetDamageType( nDamageType | DMG_NEVERGIB ); Vector vecDir; Vector vecEnd; - + // Skip multiple entities when tracing CBulletsTraceFilter traceFilter( COLLISION_GROUP_NONE ); traceFilter.SetPassEntity( this ); // Standard pass entity for THIS so that it can be easily removed from the list after passing through a portal @@ -1782,6 +1812,19 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) } #endif // SERVER_DLL +#ifdef MAPBASE + if (info.m_pIgnoreEntList != NULL) + { + for (int i = 0; i < info.m_pIgnoreEntList->Count(); i++) + { + if (info.m_pIgnoreEntList->Element(i)) + { + traceFilter.AddEntityToIgnore(info.m_pIgnoreEntList->Element(i)); + } + } + } +#endif + bool bUnderwaterBullets = ShouldDrawUnderwaterBulletBubbles(); bool bStartedInWater = false; if ( bUnderwaterBullets ) @@ -1793,7 +1836,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) int iSeed = 0; if ( IsPlayer() ) { - iSeed = CBaseEntity::GetPredictionRandomSeed( info.m_bUseServerRandomSeed ) & 255; + iSeed = CBaseEntity::GetPredictionRandomSeed() & 255; } #if defined( HL2MP ) && defined( GAME_DLL ) @@ -1806,7 +1849,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) bool bDoImpacts = false; bool bDoTracers = false; - + float flCumulativeDamage = 0.0f; for (int iShot = 0; iShot < info.m_iShots; iShot++) @@ -1883,7 +1926,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) // Tracker 70354/63250: ywb 8/2/07 // Fixes bug where trace from turret with attachment point outside of Vcollide - // starts solid so doesn't hit anything else in the world and the final coord + // starts solid so doesn't hit anything else in the world and the final coord // is outside of the MAX_COORD_FLOAT range. This cause trying to send the end pos // of the tracer down to the client with an origin which is out-of-range for networking if ( tr.startsolid ) @@ -1920,7 +1963,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) #endif //#ifdef PORTAL CreateBubbleTrailTracer( vBubbleStart, vBubbleEnd, vecDir ); - + #ifdef PORTAL if ( pShootThroughPortal ) { @@ -1998,7 +2041,11 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) { flActualDamage = g_pGameRules->GetAmmoDamage( pAttacker, tr.m_pEnt, info.m_iAmmoType ); } +#ifdef MAPBASE + else if ((info.m_nFlags & FIRE_BULLETS_NO_AUTO_GIB_TYPE) == 0) +#else else +#endif { nActualDamageType = nDamageType | ((flActualDamage > 16) ? DMG_ALWAYSGIB : DMG_NEVERGIB ); } @@ -2012,7 +2059,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) dmgInfo.ScaleDamageForce( info.m_flDamageForceScale ); dmgInfo.SetAmmoType( info.m_iAmmoType ); tr.m_pEnt->DispatchTraceAttack( dmgInfo, vecDir, &tr ); - + if ( ToBaseCombatCharacter( tr.m_pEnt ) ) { flCumulativeDamage += dmgInfo.GetDamage(); @@ -2036,15 +2083,15 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) data.m_vStart = tr.startpos; data.m_vOrigin = tr.endpos; data.m_nDamageType = nDamageType; - + DispatchEffect( "RagdollImpact", data ); } - + #ifdef GAME_DLL if ( nAmmoFlags & AMMO_FORCE_DROP_IF_CARRIED ) { // Make sure if the player is holding this, he drops it - Pickup_ForcePlayerToDropThisObject( tr.m_pEnt ); + Pickup_ForcePlayerToDropThisObject( tr.m_pEnt ); } #endif } @@ -2165,14 +2212,14 @@ bool CBaseEntity::ShouldDrawUnderwaterBulletBubbles() //----------------------------------------------------------------------------- // Handle shot entering water //----------------------------------------------------------------------------- -bool CBaseEntity::HandleShotImpactingWater( const FireBulletsInfo_t &info, +bool CBaseEntity::HandleShotImpactingWater( const FireBulletsInfo_t &info, const Vector &vecEnd, ITraceFilter *pTraceFilter, Vector *pVecTracerDest ) { trace_t waterTrace; // Trace again with water enabled AI_TraceLine( info.m_vecSrc, vecEnd, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), pTraceFilter, &waterTrace ); - + // See if this is the point we entered if ( ( enginetrace->GetPointContents( waterTrace.endpos - Vector(0,0,0.1f) ) & (CONTENTS_WATER|CONTENTS_SLIME) ) == 0 ) return false; @@ -2200,7 +2247,7 @@ bool CBaseEntity::HandleShotImpactingWater( const FireBulletsInfo_t &info, if ( pWaterBullet ) { pWaterBullet->Spawn( waterTrace.endpos, info.m_vecDirShooting ); - + CEffectData tracerData; tracerData.m_vStart = waterTrace.endpos; tracerData.m_vOrigin = waterTrace.endpos + info.m_vecDirShooting * 400.0f; @@ -2251,8 +2298,12 @@ void CBaseEntity::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir } int blood = BloodColor(); - + +#if defined(MAPBASE) && defined(GAME_DLL) + if ( blood != DONT_BLEED && DamageFilterAllowsBlood( info ) ) +#else if ( blood != DONT_BLEED ) +#endif { SpawnBlood( vecOrigin, vecDir, blood, info.GetDamage() );// a little surface blood. TraceBleed( info.GetDamage(), vecDir, ptr, info.GetDamageType() ); @@ -2268,7 +2319,7 @@ void CBaseEntity::DoImpactEffect( trace_t &tr, int nDamageType ) { // give shooter a chance to do a custom impact. UTIL_ImpactTrace( &tr, nDamageType ); -} +} //----------------------------------------------------------------------------- @@ -2285,7 +2336,7 @@ void CBaseEntity::ComputeTracerStartPosition( const Vector &vecShotSrc, Vector * return; } #endif - + if ( IsPlayer() ) { // adjust tracer position for player @@ -2354,33 +2405,20 @@ void CBaseEntity::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int //----------------------------------------------------------------------------- int CBaseEntity::GetTracerAttachment( void ) { -#ifdef VANCE - int iAttachment = 1; -#else int iAttachment = TRACER_DONT_USE_ATTACHMENT; - + if ( g_pGameRules->IsMultiplayer() ) { iAttachment = 1; } -#endif return iAttachment; } -float CBaseEntity::HealthFraction() const -{ - if ( GetMaxHealth() == 0 ) - return 1.0f; - - float flFraction = ( float )GetHealth() / ( float )GetMaxHealth(); - flFraction = clamp( flFraction, 0.0f, 1.0f ); - return flFraction; -} int CBaseEntity::BloodColor() { - return DONT_BLEED; + return DONT_BLEED; } @@ -2469,8 +2507,67 @@ void CBaseEntity::ModifyEmitSoundParams( EmitSound_t ¶ms ) params.m_pSoundName = GameRules()->TranslateEffectForVisionFilter( "sounds", params.m_pSoundName ); } #endif + +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_ModifyEmitSoundParams.CanRunInScope( m_ScriptScope )) + { + HSCRIPT hParams = g_pScriptVM->RegisterInstance( reinterpret_cast(¶ms) ); + + // params + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ScriptVariant_t( hParams ) }; + g_Hook_ModifyEmitSoundParams.Call( m_ScriptScope, &functionReturn, args ); + + g_pScriptVM->RemoveInstance( hParams ); + } +#endif } +#if defined(MAPBASE) && defined(GAME_DLL) +void CBaseEntity::ModifySentenceParams( int &iSentenceIndex, int &iChannel, float &flVolume, soundlevel_t &iSoundlevel, int &iFlags, int &iPitch, + const Vector **pOrigin, const Vector **pDirection, bool &bUpdatePositions, float &soundtime, int &iSpecialDSP, int &iSpeakerIndex ) +{ +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_ModifySentenceParams.CanRunInScope( m_ScriptScope )) + { + // This is a bit of a hack, but for consistency with ModifyEmitSoundParams, put them into an EmitSound_t params + ScriptEmitSound_t params; + params.m_pSoundName = engine->SentenceNameFromIndex( iSentenceIndex ); + params.m_nChannel = iChannel; + params.m_flVolume = flVolume; + params.m_SoundLevel = iSoundlevel; + params.m_nFlags = iFlags; + params.m_nPitch = iPitch; + params.m_pOrigin = *pOrigin; + params.m_flSoundTime = soundtime; + params.m_nSpecialDSP = iSpecialDSP; + params.m_nSpeakerEntity = iSpeakerIndex; + + HSCRIPT hParams = g_pScriptVM->RegisterInstance( ¶ms ); + + // params + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ScriptVariant_t( hParams ) }; + if (g_Hook_ModifySentenceParams.Call( m_ScriptScope, &functionReturn, args )) + { + iSentenceIndex = engine->SentenceIndexFromName( params.m_pSoundName ); + iChannel = params.m_nChannel; + flVolume = params.m_flVolume; + iSoundlevel = params.m_SoundLevel; + iFlags = params.m_nFlags; + iPitch = params.m_nPitch; + *pOrigin = params.m_pOrigin; + soundtime = params.m_flSoundTime; + iSpecialDSP = params.m_nSpecialDSP; + iSpeakerIndex = params.m_nSpeakerEntity; + } + + g_pScriptVM->RemoveInstance( hParams ); + } +#endif +} +#endif + //----------------------------------------------------------------------------- // These methods encapsulate MOVETYPE_FOLLOW, which became obsolete //----------------------------------------------------------------------------- @@ -2480,7 +2577,7 @@ void CBaseEntity::FollowEntity( CBaseEntity *pBaseEntity, bool bBoneMerge ) { SetParent( pBaseEntity ); SetMoveType( MOVETYPE_NONE ); - + if ( bBoneMerge ) AddEffects( EF_BONEMERGE ); @@ -2494,6 +2591,18 @@ void CBaseEntity::FollowEntity( CBaseEntity *pBaseEntity, bool bBoneMerge ) } } +#ifdef MAPBASE_VSCRIPT +void CBaseEntity::ScriptFollowEntity( HSCRIPT hBaseEntity, bool bBoneMerge ) +{ + FollowEntity( ToEnt( hBaseEntity ), bBoneMerge ); +} + +HSCRIPT CBaseEntity::ScriptGetFollowedEntity() +{ + return ToHScript( GetFollowedEntity() ); +} +#endif + void CBaseEntity::SetEffectEntity( CBaseEntity *pEffectEnt ) { if ( m_hEffectEntity.Get() != pEffectEnt ) @@ -2505,7 +2614,7 @@ void CBaseEntity::SetEffectEntity( CBaseEntity *pEffectEnt ) void CBaseEntity::ApplyLocalVelocityImpulse( const Vector &inVecImpulse ) { // NOTE: Don't have to use GetVelocity here because local values - // are always guaranteed to be correct, unlike abs values which may + // are always guaranteed to be correct, unlike abs values which may // require recomputation if ( inVecImpulse != vec3_origin ) { @@ -2655,7 +2764,7 @@ void CBaseEntity::SetWaterType( int nType ) ConVar sv_alternateticks( "sv_alternateticks", ( IsX360() ) ? "1" : "0", FCVAR_SPONLY, "If set, server only simulates entities on even numbered ticks.\n" ); //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CBaseEntity::IsSimulatingOnAlternateTicks() @@ -2670,8 +2779,8 @@ bool CBaseEntity::IsSimulatingOnAlternateTicks() #ifdef CLIENT_DLL //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CBaseEntity::IsToolRecording() const @@ -2683,3 +2792,357 @@ bool CBaseEntity::IsToolRecording() const #endif } #endif + +#ifdef MAPBASE_VSCRIPT +HSCRIPT CBaseEntity::GetOrCreatePrivateScriptScope() +{ + ValidateScriptScope(); + return m_ScriptScope; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptSetParent(HSCRIPT hParent, const char *szAttachment) +{ + CBaseEntity *pParent = ToEnt(hParent); + if ( !pParent ) + { + SetParent(NULL); + return; + } + + // if an attachment is specified, the parent needs to be CBaseAnimating + if ( szAttachment && szAttachment[0] != '\0' ) + { + CBaseAnimating *pAnimating = pParent->GetBaseAnimating(); + if ( !pAnimating ) + { + Warning("ERROR: Tried to set parent for entity %s (%s), but its parent has no model.\n", GetClassname(), GetDebugName()); + return; + } + + int iAttachment = pAnimating->LookupAttachment(szAttachment); + if ( iAttachment <= 0 ) + { + Warning("ERROR: Tried to set parent for entity %s (%s), but it has no attachment named %s.\n", GetClassname(), GetDebugName(), szAttachment); + return; + } + + SetParent(pParent, iAttachment); + SetMoveType(MOVETYPE_NONE); + return; + } + + SetParent(pParent); +} + +HSCRIPT CBaseEntity::GetScriptOwnerEntity() +{ + return ToHScript(GetOwnerEntity()); +} + +void CBaseEntity::SetScriptOwnerEntity(HSCRIPT pOwner) +{ + SetOwnerEntity(ToEnt(pOwner)); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const Vector& CBaseEntity::ScriptGetColorVector() +{ + static Vector vecColor; + vecColor.Init( m_clrRender.GetR(), m_clrRender.GetG(), m_clrRender.GetB() ); + return vecColor; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptSetColorVector( const Vector& vecColor ) +{ + SetRenderColor( vecColor.x, vecColor.y, vecColor.z ); +} + +void CBaseEntity::ScriptSetColor( int r, int g, int b ) +{ + SetRenderColor( r, g, b ); +} + +//----------------------------------------------------------------------------- +// Vscript: Gets the entity matrix transform +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptEntityToWorldTransform( void ) +{ + return g_pScriptVM->RegisterInstance( &EntityToWorldTransform() ); +} + +//----------------------------------------------------------------------------- +// Vscript: Gets the entity's physics object if it has one +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void ) +{ + if (VPhysicsGetObject()) + return g_pScriptVM->RegisterInstance( VPhysicsGetObject() ); + else + return NULL; +} + + +#ifdef GAME_DLL +#define SCRIPT_NEVER_THINK TICK_NEVER_THINK +#else +#define SCRIPT_NEVER_THINK CLIENT_THINK_NEVER +#endif + +static inline void ScriptStopContextThink( scriptthinkfunc_t *context ) +{ + Assert( context->m_hfnThink ); + Assert( context->m_flNextThink == SCRIPT_NEVER_THINK ); + + g_pScriptVM->ReleaseScript( context->m_hfnThink ); + context->m_hfnThink = NULL; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptContextThink() +{ + float flNextThink = FLT_MAX; + float flScheduled = 0.0f; + + ScriptVariant_t arg = m_hScriptInstance; + + for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i ) + { + scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i]; + + if ( cur->m_flNextThink == SCRIPT_NEVER_THINK ) + { + continue; + } + + if ( cur->m_flNextThink > gpGlobals->curtime ) + { + if ( ( flScheduled == 0.0f ) || ( flScheduled > cur->m_flNextThink ) ) + { + flScheduled = cur->m_flNextThink; + } + continue; + } + +#ifdef _DEBUG + // going to run the script func + cur->m_flNextThink = 0; +#endif + + ScriptVariant_t varReturn; + +#ifndef CLIENT_DLL + if ( !cur->m_bNoParam ) + { +#endif + g_pScriptVM->ExecuteFunction( cur->m_hfnThink, &arg, 1, &varReturn, NULL, true ); +#ifndef CLIENT_DLL + } + else + { + g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ); + } +#endif + + if ( cur->m_flNextThink == SCRIPT_NEVER_THINK ) + { + // stopped from script while thinking + continue; + } + + float flReturn; + if ( !varReturn.AssignTo( &flReturn ) ) + { + varReturn.Free(); + cur->m_flNextThink = SCRIPT_NEVER_THINK; + continue; + } + + if ( flReturn < 0.0f ) + { + cur->m_flNextThink = SCRIPT_NEVER_THINK; + continue; + } + + if ( flReturn < flNextThink ) + { + flNextThink = flReturn; + } + + cur->m_flNextThink = gpGlobals->curtime + flReturn - 0.001f; + } + + // deferred safe removal + for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ) + { + scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i]; + if ( cur->m_flNextThink == SCRIPT_NEVER_THINK ) + { + ScriptStopContextThink( cur ); + delete cur; + m_ScriptThinkFuncs.Remove(i); + } + else ++i; + } + + if ( flNextThink < FLT_MAX ) + { + if ( flScheduled > 0.0f ) + { + flNextThink = MIN( gpGlobals->curtime + flNextThink, flScheduled ); + } + else + { + flNextThink = gpGlobals->curtime + flNextThink; + } + } + else + { + if ( flScheduled > 0.0f ) + { + flNextThink = flScheduled; + } + else + { + flNextThink = SCRIPT_NEVER_THINK; + } + } + +#ifdef _DEBUG +#ifdef GAME_DLL + int nNextThinkTick = GetNextThinkTick("ScriptContextThink"); + float flNextThinkTime = TICKS_TO_TIME(nNextThinkTick); + + // If internal next think tick is earlier than what we have here with flNextThink, + // whoever set that think may fail. In worst case scenario the entity may stop thinking. + if ( nNextThinkTick > gpGlobals->tickcount ) + { + if ( flNextThink == SCRIPT_NEVER_THINK ) + Assert(0); + if ( flNextThinkTime < flNextThink ) + Assert(0); + } +#endif +#endif + +#ifdef GAME_DLL + SetNextThink( flNextThink, "ScriptContextThink" ); +#else + SetNextClientThink( flNextThink ); +#endif +} + +#ifndef CLIENT_DLL +// see ScriptSetThink +static bool s_bScriptContextThinkNoParam = false; +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime ) +{ +#ifdef CLIENT_DLL + // Context thinking is not yet supported on client, entities can only have 1 think function. + // C_World does not have one by default, so it is safe to set its. + if ( !IsWorld() ) + { + g_pScriptVM->RaiseException("SetContextThink is only supported on C_World"); + return; + } +#endif + + scriptthinkfunc_t *pf = NULL; + unsigned hash = szContext ? HashString( szContext ) : 0; + + FOR_EACH_VEC( m_ScriptThinkFuncs, i ) + { + scriptthinkfunc_t *f = m_ScriptThinkFuncs[i]; + if ( hash == f->m_iContextHash ) + { + pf = f; + break; + } + } + + if ( hFunc ) + { + // add new + if ( !pf ) + { + pf = new scriptthinkfunc_t; + + m_ScriptThinkFuncs.SetGrowSize(1); + m_ScriptThinkFuncs.AddToTail( pf ); + + pf->m_iContextHash = hash; +#ifndef CLIENT_DLL + pf->m_bNoParam = s_bScriptContextThinkNoParam; +#endif + } + // update existing + else + { +#ifdef _DEBUG + if ( pf->m_flNextThink == 0 ) + { + Warning("Script think ('%s') was changed while it was thinking!\n", szContext); + } +#endif + g_pScriptVM->ReleaseScript( pf->m_hfnThink ); + } + + float nextthink = gpGlobals->curtime + flTime; + + pf->m_hfnThink = hFunc; + pf->m_flNextThink = nextthink; + +#ifdef GAME_DLL + int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) ); + if ( nexttick <= 0 || TICKS_TO_TIME(nexttick) > nextthink ) + { + SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" ); + } +#else + { + // let it self adjust + SetNextClientThink( gpGlobals->curtime ); + } +#endif + } + // null func input, think exists + else if ( pf ) + { + pf->m_flNextThink = SCRIPT_NEVER_THINK; + } +} + +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility +// and are an alternative to this script closure: +// +// function CBaseEntity::SetThink( func, time ) +// { +// SetContextThink( "", function(_){ return func() }, time ) +// } +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time ) +{ + s_bScriptContextThinkNoParam = true; + ScriptSetContextThink( NULL, hFunc, time ); + s_bScriptContextThinkNoParam = false; +} + +void CBaseEntity::ScriptStopThink() +{ + ScriptSetContextThink( NULL, NULL, 0.0f ); +} +#endif +#endif diff --git a/game/shared/baseentity_shared.h b/game/shared/baseentity_shared.h index 52a90ab4..85a0ffd8 100644 --- a/game/shared/baseentity_shared.h +++ b/game/shared/baseentity_shared.h @@ -68,6 +68,9 @@ enum InvalidatePhysicsBits_t #endif +#include "vscript/ivscript.h" +#include "vscript_shared.h" + #if !defined( NO_ENTITY_PREDICTION ) // CBaseEntity inlines inline bool CBaseEntity::IsPlayerSimulated( void ) const @@ -119,13 +122,9 @@ inline CBaseEntity *CBaseEntity::GetEffectEntity() const return m_hEffectEntity.Get(); } -inline int CBaseEntity::GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime ) +inline int CBaseEntity::GetPredictionRandomSeed( void ) { -#ifdef GAME_DLL - return bUseUnSyncedServerPlatTime ? m_nPredictionRandomSeedServer : m_nPredictionRandomSeed; -#else return m_nPredictionRandomSeed; -#endif } inline CBasePlayer *CBaseEntity::GetPredictionPlayer( void ) @@ -251,6 +250,17 @@ inline bool CBaseEntity::IsEffectActive( int nEffects ) const return (m_fEffects & nEffects) != 0; } +inline HSCRIPT ToHScript(CBaseEntity* pEnt) +{ + return (pEnt) ? pEnt->GetScriptInstance() : NULL; +} + +template <> ScriptClassDesc_t* GetScriptDesc(CBaseEntity*); +inline CBaseEntity* ToEnt(HSCRIPT hScript) +{ + return (hScript) ? (CBaseEntity*)g_pScriptVM->GetInstanceValue(hScript, GetScriptDescForClass(CBaseEntity)) : NULL; +} + // Shared EntityMessage between game and client .dlls #define BASEENTITY_MSG_REMOVE_DECALS 1 diff --git a/game/shared/basegrenade_shared.cpp b/game/shared/basegrenade_shared.cpp index b981d078..0d616099 100644 --- a/game/shared/basegrenade_shared.cpp +++ b/game/shared/basegrenade_shared.cpp @@ -34,13 +34,29 @@ BEGIN_DATADESC( CBaseGrenade ) DEFINE_FIELD( m_hThrower, FIELD_EHANDLE ), // m_fRegisteredSound ??? DEFINE_FIELD( m_bIsLive, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_DmgRadius, FIELD_FLOAT, "Radius" ), +#else DEFINE_FIELD( m_DmgRadius, FIELD_FLOAT ), +#endif DEFINE_FIELD( m_flDetonateTime, FIELD_TIME ), DEFINE_FIELD( m_flWarnAITime, FIELD_TIME ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "Damage" ), +#else DEFINE_FIELD( m_flDamage, FIELD_FLOAT ), +#endif DEFINE_FIELD( m_iszBounceSound, FIELD_STRING ), DEFINE_FIELD( m_bHasWarnedAI, FIELD_BOOLEAN ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDamage", InputSetDamage ), + DEFINE_INPUTFUNC( FIELD_VOID, "Detonate", InputDetonate ), + + DEFINE_OUTPUT( m_OnDetonate, "OnDetonate" ), + DEFINE_OUTPUT( m_OnDetonate_OutPosition, "OnDetonate_OutPosition" ), +#endif + // Function Pointers DEFINE_THINKFUNC( Smoke ), DEFINE_ENTITYFUNC( BounceTouch ), @@ -58,6 +74,28 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi #endif +#ifdef MAPBASE_VSCRIPT +BEGIN_ENT_SCRIPTDESC( CBaseGrenade, CBaseAnimating, "The base class for grenades." ) + + DEFINE_SCRIPTFUNC( GetBlastForce, "Gets the grenade's blast force override. Grenades which use base damage force calculations return 0,0,0" ) + + DEFINE_SCRIPTFUNC( GetDamage, "Gets the grenade's blast damage." ) + DEFINE_SCRIPTFUNC( GetDamageRadius, "Gets the grenade's blast damage radius." ) + DEFINE_SCRIPTFUNC( SetDamage, "Sets the grenade's blast damage." ) + DEFINE_SCRIPTFUNC( SetDamageRadius, "Sets the grenade's blast damage radius." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetThrower, "GetThrower", "Gets the grenade's thrower." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetThrower, "SetThrower", "Sets the grenade's thrower." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetOriginalThrower, "GetOriginalThrower", "Gets the grenade's original thrower after the thrower was changed due to being picked up by a gravity gun or something." ) + + DEFINE_SCRIPTFUNC_NAMED( GetDetonateTime, "GetTimer", "Gets the grenade's detonate time if it has one." ) + DEFINE_SCRIPTFUNC( HasWarnedAI, "Whether or not the grenade has issued its DANGER sound to the world sound list yet." ) + DEFINE_SCRIPTFUNC( IsLive, "Whether or not the grenade has issued its DANGER sound to the world sound list yet." ) + DEFINE_SCRIPTFUNC( GetWarnAITime, "Gets the time at which the grenade will warn/has warned AI." ) + +END_SCRIPTDESC(); +#endif + IMPLEMENT_NETWORKCLASS_ALIASED( BaseGrenade, DT_BaseGrenade ) BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade ) @@ -180,6 +218,11 @@ void CBaseGrenade::Explode( trace_t *pTrace, int bitsDamageType ) EmitSound( "BaseGrenade.Explode" ); +#ifdef MAPBASE + m_OnDetonate.FireOutput(GetThrower(), this); + m_OnDetonate_OutPosition.Set(GetAbsOrigin(), GetThrower(), this); +#endif + SetThink( &CBaseGrenade::SUB_Remove ); SetTouch( NULL ); SetSolid( SOLID_NONE ); @@ -258,6 +301,25 @@ void CBaseGrenade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE // Pass up so we still call any custom Use function BaseClass::Use( pActivator, pCaller, useType, value ); } + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseGrenade::InputSetDamage( inputdata_t &inputdata ) +{ + SetDamage( inputdata.value.Float() ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseGrenade::InputDetonate( inputdata_t &inputdata ) +{ + Detonate(); +} +#endif + #endif //----------------------------------------------------------------------------- diff --git a/game/shared/basegrenade_shared.h b/game/shared/basegrenade_shared.h index 38bb684d..47840dc4 100644 --- a/game/shared/basegrenade_shared.h +++ b/game/shared/basegrenade_shared.h @@ -49,6 +49,9 @@ class CBaseGrenade : public CBaseProjectile #if !defined( CLIENT_DLL ) DECLARE_DATADESC(); #endif +#ifdef MAPBASE_VSCRIPT + DECLARE_ENT_SCRIPTDESC(); +#endif virtual void Precache( void ); @@ -103,6 +106,17 @@ class CBaseGrenade : public CBaseProjectile void SetThrower( CBaseCombatCharacter *pThrower ); CBaseEntity *GetOriginalThrower() { return m_hOriginalThrower; } +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetThrower( void ) { return ToHScript( GetThrower() ); } + void ScriptSetThrower( HSCRIPT hThrower ) { SetThrower( ToEnt(hThrower) ? ToEnt(hThrower)->MyCombatCharacterPointer() : NULL ); } + HSCRIPT ScriptGetOriginalThrower() { return ToHScript( GetOriginalThrower() ); } + + float GetDetonateTime() { return m_flDetonateTime; } + bool HasWarnedAI() { return m_bHasWarnedAI; } + bool IsLive() { return m_bIsLive; } + float GetWarnAITime() { return m_flWarnAITime; } +#endif + #if !defined( CLIENT_DLL ) // Allow +USE pickup int ObjectCaps() @@ -111,6 +125,12 @@ class CBaseGrenade : public CBaseProjectile } void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + +#ifdef MAPBASE + void InputSetDamage( inputdata_t &inputdata ); + void InputDetonate( inputdata_t &inputdata ); +#endif + #endif public: @@ -129,6 +149,11 @@ class CBaseGrenade : public CBaseProjectile CNetworkVar( float, m_flDamage ); // Damage to inflict. string_t m_iszBounceSound; // The sound to make on bouncing. If not NULL, overrides the BounceSound() function. +#if defined(MAPBASE) && !defined(CLIENT_DLL) + COutputEvent m_OnDetonate; + COutputVector m_OnDetonate_OutPosition; +#endif + private: CNetworkHandle( CBaseEntity, m_hThrower ); // Who threw this grenade EHANDLE m_hOriginalThrower; // Who was the original thrower of this grenade diff --git a/game/shared/baseplayer_shared.cpp b/game/shared/baseplayer_shared.cpp index 70056463..5ad7d453 100644 --- a/game/shared/baseplayer_shared.cpp +++ b/game/shared/baseplayer_shared.cpp @@ -163,12 +163,30 @@ void CBasePlayer::ItemPreFrame() // Handle use events PlayerUse(); - CBaseCombatWeapon *pActive = GetActiveWeapon(); + //Tony; re-ordered this for efficiency and to make sure that certain things happen in the correct order! + if ( gpGlobals->curtime < m_flNextAttack ) + { + return; + } + + if (!GetActiveWeapon()) + return; + +#if defined( CLIENT_DLL ) + // Not predicting this weapon + if ( !GetActiveWeapon()->IsPredicted() ) + return; +#endif + + GetActiveWeapon()->ItemPreFrame(); + CBaseCombatWeapon *pWeapon; + + CBaseCombatWeapon *pActive = GetActiveWeapon(); // Allow all the holstered weapons to update for ( int i = 0; i < WeaponCount(); ++i ) { - CBaseCombatWeapon *pWeapon = GetWeapon( i ); + pWeapon = GetWeapon( i ); if ( pWeapon == NULL ) continue; @@ -178,20 +196,6 @@ void CBasePlayer::ItemPreFrame() pWeapon->ItemHolsterFrame(); } - - if ( gpGlobals->curtime < m_flNextAttack ) - return; - - if (!pActive) - return; - -#if defined( CLIENT_DLL ) - // Not predicting this weapon - if ( !pActive->IsPredicted() ) - return; -#endif - - pActive->ItemPreFrame(); } //----------------------------------------------------------------------------- @@ -342,7 +346,7 @@ Vector CBasePlayer::EyePosition( ) #ifdef CLIENT_DLL if ( IsObserver() ) { - if ( GetObserverMode() == OBS_MODE_CHASE || GetObserverMode() == OBS_MODE_POI ) + if ( GetObserverMode() == OBS_MODE_CHASE ) { if ( IsLocalPlayer() ) { @@ -1035,7 +1039,7 @@ void CBasePlayer::SelectItem( const char *pstr, int iSubType ) // Make sure the current weapon can be holstered if ( GetActiveWeapon() ) { - if ( !GetActiveWeapon()->CanHolster() && !pItem->ForceWeaponSwitch() ) + if ( !GetActiveWeapon()->CanHolster() ) return; ResetAutoaim( ); @@ -1703,7 +1707,6 @@ void CBasePlayer::CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& case OBS_MODE_IN_EYE : CalcInEyeCamView( eyeOrigin, eyeAngles, fov ); break; - case OBS_MODE_POI : // PASSTIME case OBS_MODE_CHASE : CalcChaseCamView( eyeOrigin, eyeAngles, fov ); break; diff --git a/game/shared/baseplayer_shared.h b/game/shared/baseplayer_shared.h index 8bdc0950..fc5fdf0f 100644 --- a/game/shared/baseplayer_shared.h +++ b/game/shared/baseplayer_shared.h @@ -53,6 +53,20 @@ enum stepsoundtimes_t void CopySoundNameWithModifierToken( char *pchDest, const char *pchSource, int nMaxLenInChars, const char *pchToken ); +#ifdef MAPBASE +// Internal player spawnflags. +// These are only meant to be used internally or accessed via logic_playerproxy. +// I'm sure this isn't a bad idea whatsoever... +// +// They start at 16 because some NPC spawnflags (e.g. Wait Till Seen) +// used in places with both NPCs and players don't check whether the target is a NPC or a player. +// Spawnflags are also transmitted to the client and use a special network proxy to get around this without having to transmit unused bits. +// Be sure to update the SendPropInt() entry for m_spawnflags in player.cpp when you add any new spawnflags! +#define SF_PLAYER_NO_GEIGER (1 << 16) +#define SF_PLAYER_HIDE_SQUAD_HUD (1 << 17) +#define SF_PLAYER_SUPPRESS_FIRING (1 << 18) +#endif + // Shared header file for players #if defined( CLIENT_DLL ) #define CBasePlayer C_BasePlayer diff --git a/game/shared/baseprojectile.cpp b/game/shared/baseprojectile.cpp index f2ff3fdd..c695db93 100644 --- a/game/shared/baseprojectile.cpp +++ b/game/shared/baseprojectile.cpp @@ -12,19 +12,9 @@ IMPLEMENT_NETWORKCLASS_ALIASED( BaseProjectile, DT_BaseProjectile ) BEGIN_NETWORK_TABLE( CBaseProjectile, DT_BaseProjectile ) -#if !defined( CLIENT_DLL ) - SendPropEHandle( SENDINFO( m_hOriginalLauncher ) ), -#else - RecvPropEHandle( RECVINFO( m_hOriginalLauncher ) ), -#endif // CLIENT_DLL END_NETWORK_TABLE() -#ifndef CLIENT_DLL -IMPLEMENT_AUTO_LIST( IBaseProjectileAutoList ); -#endif // !CLIENT_DLL - - //----------------------------------------------------------------------------- // Purpose: Constructor. //----------------------------------------------------------------------------- @@ -32,63 +22,5 @@ CBaseProjectile::CBaseProjectile() { #ifdef GAME_DLL m_iDestroyableHitCount = 0; - - m_bCanCollideWithTeammates = false; #endif - m_hOriginalLauncher = NULL; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseProjectile::SetLauncher( CBaseEntity *pLauncher ) -{ - if ( m_hOriginalLauncher == NULL ) - { - m_hOriginalLauncher = pLauncher; - } - -#ifdef GAME_DLL - ResetCollideWithTeammates(); -#endif // GAME_DLL } - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseProjectile::Spawn() -{ - BaseClass::Spawn(); - -#ifdef GAME_DLL - ResetCollideWithTeammates(); -#endif // GAME_DLL -} - - -#ifdef GAME_DLL - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseProjectile::CollideWithTeammatesThink() -{ - m_bCanCollideWithTeammates = true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseProjectile::ResetCollideWithTeammates() -{ - // Don't collide with players on the owner's team for the first bit of our life - m_bCanCollideWithTeammates = false; - - SetContextThink( &CBaseProjectile::CollideWithTeammatesThink, gpGlobals->curtime + GetCollideWithTeammatesDelay(), "CollideWithTeammates" ); -} - -#endif // GAME_DLL - diff --git a/game/shared/baseprojectile.h b/game/shared/baseprojectile.h index 9f16f828..2ff00fc5 100644 --- a/game/shared/baseprojectile.h +++ b/game/shared/baseprojectile.h @@ -28,12 +28,7 @@ // Base Projectile. // //============================================================================= -#ifdef CLIENT_DLL class CBaseProjectile : public CBaseAnimating -#else // CLIENT_DLL -DECLARE_AUTO_LIST( IBaseProjectileAutoList ); -class CBaseProjectile : public CBaseAnimating, public IBaseProjectileAutoList -#endif // !CLIENT_DLL { public: DECLARE_CLASS( CBaseProjectile, CBaseAnimating ); @@ -41,39 +36,18 @@ class CBaseProjectile : public CBaseAnimating, public IBaseProjectileAutoList CBaseProjectile(); - virtual void Spawn(); - #ifdef GAME_DLL - virtual int GetBaseProjectileType() const { return -1; } // no base - virtual int GetProjectileType() const { return -1; } // no type virtual int GetDestroyableHitCount( void ) const { return m_iDestroyableHitCount; } void IncrementDestroyableHitCount( void ) { ++m_iDestroyableHitCount; } - - virtual bool CanCollideWithTeammates() const { return m_bCanCollideWithTeammates; } - virtual float GetCollideWithTeammatesDelay() const { return 0.25f; } #endif // GAME_DLL virtual bool IsDestroyable( void ) { return false; } virtual void Destroy( bool bBlinkOut = true, bool bBreakRocket = false ) {} - virtual void SetLauncher( CBaseEntity *pLauncher ); - CBaseEntity *GetOriginalLauncher() const { return m_hOriginalLauncher; } protected: #ifdef GAME_DLL - void CollideWithTeammatesThink(); - int m_iDestroyableHitCount; #endif // GAME_DLL - -private: - -#ifdef GAME_DLL - void ResetCollideWithTeammates(); - - bool m_bCanCollideWithTeammates; -#endif // GAME_DLL - - CNetworkHandle( CBaseEntity, m_hOriginalLauncher ); }; #endif // BASEPROJECTILE_H diff --git a/game/shared/baseviewmodel_shared.cpp b/game/shared/baseviewmodel_shared.cpp index 7ab9467c..5f9c0f10 100644 --- a/game/shared/baseviewmodel_shared.cpp +++ b/game/shared/baseviewmodel_shared.cpp @@ -289,6 +289,19 @@ void CBaseViewModel::AddEffects( int nEffects ) SetControlPanelsActive( false ); } +#ifdef MAPBASE + if (GetOwningWeapon() && GetOwningWeapon()->UsesHands()) + { + // If using hands, apply effect changes to any viewmodel children as well + // (fixes hand models) + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + pChild->AddEffects( nEffects ); + } + } +#endif + BaseClass::AddEffects( nEffects ); } @@ -302,6 +315,19 @@ void CBaseViewModel::RemoveEffects( int nEffects ) SetControlPanelsActive( true ); } +#ifdef MAPBASE + if (GetOwningWeapon() && GetOwningWeapon()->UsesHands()) + { + // If using hands, apply effect changes to any viewmodel children as well + // (fixes hand models) + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + pChild->RemoveEffects( nEffects ); + } + } +#endif + BaseClass::RemoveEffects( nEffects ); } @@ -339,6 +365,18 @@ void CBaseViewModel::SetWeaponModel( const char *modelname, CBaseCombatWeapon *w SetControlPanelsActive( showControlPanels ); } #endif + +#ifdef MAPBASE + // If our owning weapon doesn't support hands, disable the hands viewmodel(s) + bool bSupportsHands = weapon != NULL ? weapon->UsesHands() : false; + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + { + bSupportsHands ? pChild->RemoveEffects( EF_NODRAW ) : pChild->AddEffects( EF_NODRAW ); + } + } +#endif } //----------------------------------------------------------------------------- @@ -398,28 +436,22 @@ void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePos if ( !prediction->InPrediction() ) #endif { -#ifndef VANCE // add weapon-specific bob pWeapon->AddViewmodelBob( this, vmorigin, vmangles ); -#endif #if defined ( CSTRIKE_DLL ) CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); #endif } } -#ifndef VANCE // Add model-specific bob even if no weapon associated (for head bob for off hand models) AddViewModelBob( owner, vmorigin, vmangles ); -#endif -#if !defined ( CSTRIKE_DLL ) - // This was causing weapon jitter when rotating in updated CS:S; original Source had this in above InPrediction block 07/14/10 - // Add lag - CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); -#endif #if defined( CLIENT_DLL ) if ( !prediction->InPrediction() ) { + // Add lag + CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); + // Let the viewmodel shake at about 10% of the amplitude of the player's view vieweffects->ApplyShake( vmorigin, vmangles, 0.1 ); } @@ -430,6 +462,21 @@ void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePos g_ClientVirtualReality.OverrideViewModelTransform( vmorigin, vmangles, pWeapon && pWeapon->ShouldUseLargeViewModelVROverride() ); } +#ifdef MAPBASE + // Flip the view if we should be flipping + if (ShouldFlipViewModel()) + { + Vector vecOriginDiff = (eyePosition - vmorigin); + QAngle angAnglesDiff = (eyeAngles - vmangles); + + vmorigin.x = (eyePosition.x + vecOriginDiff.x); + vmorigin.y = (eyePosition.y + vecOriginDiff.y); + + vmangles.y = (eyeAngles.y + angAnglesDiff.y); + vmangles.z = (eyeAngles.z + angAnglesDiff.z); + } +#endif + SetLocalOrigin( vmorigin ); SetLocalAngles( vmangles ); @@ -484,6 +531,23 @@ void CBaseViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& o float flSpeed = 5.0f; +#ifdef MAPBASE + CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); + if (pWeapon) + { + const FileWeaponInfo_t *pInfo = &pWeapon->GetWpnData(); + if (pInfo->m_flSwayScale != 1.0f) + { + vDifference *= pInfo->m_flSwayScale; + pInfo->m_flSwayScale != 0.0f ? flSpeed /= pInfo->m_flSwayScale : flSpeed = 0.0f; + } + if (pInfo->m_flSwaySpeedScale != 1.0f) + { + flSpeed *= pInfo->m_flSwaySpeedScale; + } + } +#endif + // If we start to lag too far behind, we'll increase the "catch up" speed. Solves the problem with fast cl_yawspeed, m_yaw or joysticks // rotating quickly. The old code would slam lastfacing with origin causing the viewmodel to pop to a new position float flDiff = vDifference.Length(); @@ -693,3 +757,63 @@ bool CBaseViewModel::GetAttachmentVelocity( int number, Vector &originVel, Quate } #endif + +#ifdef MAPBASE +#if defined( CLIENT_DLL ) +#define CHandViewModel C_HandViewModel +#endif + +// --------------------------------------- +// OzxyBox's hand viewmodel code. +// All credit goes to him. +// --------------------------------------- +class CHandViewModel : public CBaseViewModel +{ + DECLARE_CLASS( CHandViewModel, CBaseViewModel ); +public: + DECLARE_NETWORKCLASS(); + + CBaseViewModel *GetVMOwner(); + + CBaseCombatWeapon *GetOwningWeapon( void ); + +private: + CHandle m_hVMOwner; +}; + +LINK_ENTITY_TO_CLASS(hand_viewmodel, CHandViewModel); +IMPLEMENT_NETWORKCLASS_ALIASED(HandViewModel, DT_HandViewModel) + +// for whatever reason the parent doesn't get sent +// I don't really want to mess with the baseviewmodel +// so now it does +BEGIN_NETWORK_TABLE(CHandViewModel, DT_HandViewModel) +#ifndef CLIENT_DLL + SendPropEHandle(SENDINFO_NAME(m_hMoveParent, moveparent)), +#else + RecvPropInt(RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent), +#endif +END_NETWORK_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseViewModel *CHandViewModel::GetVMOwner() +{ + if (!m_hVMOwner) + m_hVMOwner = assert_cast(GetMoveParent()); + return m_hVMOwner; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseCombatWeapon *CHandViewModel::GetOwningWeapon() +{ + CBaseViewModel *pVM = GetVMOwner(); + if (pVM) + return pVM->GetOwningWeapon(); + else + return NULL; +} +#endif diff --git a/game/shared/baseviewmodel_shared.h b/game/shared/baseviewmodel_shared.h index 15d3be53..7e9c79a6 100644 --- a/game/shared/baseviewmodel_shared.h +++ b/game/shared/baseviewmodel_shared.h @@ -145,7 +145,11 @@ class CBaseViewModel : public CBaseAnimating, public IHasOwner // Should this object receive shadows? virtual bool ShouldReceiveProjectedTextures( int flags ) { +#ifdef MAPBASE + return true; +#else return false; +#endif } // Add entity to visible view models list? diff --git a/game/shared/beam_shared.cpp b/game/shared/beam_shared.cpp index 77e5d5c2..fcefa3f9 100644 --- a/game/shared/beam_shared.cpp +++ b/game/shared/beam_shared.cpp @@ -42,6 +42,9 @@ class CInfoTarget : public CPointEntity DECLARE_CLASS( CInfoTarget, CPointEntity ); void Spawn( void ); +#ifdef MAPBASE + virtual int UpdateTransmitState(); +#endif }; //info targets are like point entities except you can force them to spawn on the client @@ -55,6 +58,19 @@ void CInfoTarget::Spawn( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Always transmitted to clients +//----------------------------------------------------------------------------- +int CInfoTarget::UpdateTransmitState() +{ + // Spawn flags 2 means we always transmit + if ( HasSpawnFlags(0x02) ) + return SetTransmitState( FL_EDICT_ALWAYS ); + return BaseClass::UpdateTransmitState(); +} +#endif + LINK_ENTITY_TO_CLASS( info_target, CInfoTarget ); #endif @@ -773,7 +789,9 @@ void CBeam::BeamDamage( trace_t *ptr ) if ( ptr->fraction != 1.0 && ptr->m_pEnt != NULL ) { CBaseEntity *pHit = ptr->m_pEnt; +#ifndef MAPBASE if ( pHit ) +#endif { ClearMultiDamage(); Vector dir = ptr->endpos - GetAbsOrigin(); diff --git a/game/shared/cam_thirdperson.cpp b/game/shared/cam_thirdperson.cpp index 02d7753b..81db62d4 100644 --- a/game/shared/cam_thirdperson.cpp +++ b/game/shared/cam_thirdperson.cpp @@ -21,6 +21,10 @@ static Vector CAM_HULL_MAX( CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET); extern const ConVar *sv_cheats; +extern ConVar cam_idealdist; +extern ConVar cam_idealdistright; +extern ConVar cam_idealdistup; + void CAM_ToThirdPerson(void); void CAM_ToFirstPerson(void); @@ -99,6 +103,16 @@ void CThirdPersonManager::Update( void ) } +Vector CThirdPersonManager::GetDesiredCameraOffset( void ) +{ + if ( IsOverridingThirdPerson() == true ) + { + return Vector( cam_idealdist.GetFloat(), cam_idealdistright.GetFloat(), cam_idealdistup.GetFloat() ); + } + + return m_vecDesiredCameraOffset; +} + Vector CThirdPersonManager::GetFinalCameraOffset( void ) { Vector vDesired = GetDesiredCameraOffset(); @@ -143,7 +157,7 @@ Vector CThirdPersonManager::GetDistanceFraction( void ) return Vector( flFraction, flFraction, flUpFraction ); } -void CThirdPersonManager::PositionCamera( CBasePlayer *pPlayer, const QAngle& angles ) +void CThirdPersonManager::PositionCamera( CBasePlayer *pPlayer, QAngle angles ) { if ( pPlayer ) { diff --git a/game/shared/cam_thirdperson.h b/game/shared/cam_thirdperson.h index 54dfecaa..8271a642 100644 --- a/game/shared/cam_thirdperson.h +++ b/game/shared/cam_thirdperson.h @@ -42,25 +42,25 @@ class CThirdPersonManager public: CThirdPersonManager(); - void SetCameraOffsetAngles( const Vector& vecOffset ) { m_vecCameraOffset = vecOffset; } - const Vector& GetCameraOffsetAngles( void ) const { return m_vecCameraOffset; } + void SetCameraOffsetAngles( Vector vecOffset ) { m_vecCameraOffset = vecOffset; } + Vector GetCameraOffsetAngles( void ) { return m_vecCameraOffset; } - void SetDesiredCameraOffset( const Vector& vecOffset ) { m_vecDesiredCameraOffset = vecOffset; } - const Vector& GetDesiredCameraOffset( void ) const { return m_vecDesiredCameraOffset; } + void SetDesiredCameraOffset( Vector vecOffset ) { m_vecDesiredCameraOffset = vecOffset; } + Vector GetDesiredCameraOffset( void ); Vector GetFinalCameraOffset( void ); - void SetCameraOrigin( const Vector& vecOffset ) { m_vecCameraOrigin = vecOffset; } - const Vector& GetCameraOrigin( void ) const { return m_vecCameraOrigin; } + void SetCameraOrigin( Vector vecOffset ) { m_vecCameraOrigin = vecOffset; } + Vector GetCameraOrigin( void ) { return m_vecCameraOrigin; } void Update( void ); - void PositionCamera( CBasePlayer *pPlayer, const QAngle& angles ); + void PositionCamera( CBasePlayer *pPlayer, QAngle angles ); void UseCameraOffsets( bool bUse ) { m_bUseCameraOffsets = bUse; } bool UsingCameraOffsets( void ) { return m_bUseCameraOffsets; } - const QAngle& GetCameraViewAngles( void ) const { return m_ViewAngles; } + QAngle GetCameraViewAngles( void ) { return m_ViewAngles; } Vector GetDistanceFraction( void ); diff --git a/game/shared/choreoevent.cpp b/game/shared/choreoevent.cpp index 9afb938b..1623a37d 100644 --- a/game/shared/choreoevent.cpp +++ b/game/shared/choreoevent.cpp @@ -2064,6 +2064,8 @@ static EventNameMap_t g_NameMap[] = { CChoreoEvent::STOPPOINT, "stoppoint" }, { CChoreoEvent::PERMIT_RESPONSES, "permitresponses" }, { CChoreoEvent::GENERIC, "generic" }, + { CChoreoEvent::CAMERA, "camera" }, + { CChoreoEvent::SCRIPT, "script" }, }; //----------------------------------------------------------------------------- @@ -2076,8 +2078,8 @@ class CCheckEventNames { if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES ) { - Error( "g_NameMap contains %llu entries, CChoreoEvent::NUM_TYPES == %i!", - (uint64)(ARRAYSIZE( g_NameMap )), CChoreoEvent::NUM_TYPES ); + Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!", + ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES ); } for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i ) { @@ -2158,8 +2160,8 @@ class CCheckCCNames { if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES ) { - Error( "g_CCNameMap contains %llu entries, CChoreoEvent::NUM_CC_TYPES == %i!", - (uint64)(ARRAYSIZE( g_CCNameMap )), CChoreoEvent::NUM_CC_TYPES ); + Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!", + ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES ); } for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i ) { diff --git a/game/shared/choreoevent.h b/game/shared/choreoevent.h index ad4828d3..64db52af 100644 --- a/game/shared/choreoevent.h +++ b/game/shared/choreoevent.h @@ -307,6 +307,12 @@ class CChoreoEvent : public ICurveDataAccessor // A string passed to the game code for interpretation GENERIC, + // Camera control + CAMERA, + + // Script function call + SCRIPT, + // THIS MUST BE LAST!!! NUM_TYPES, } EVENTTYPE; diff --git a/game/shared/choreoscene.cpp b/game/shared/choreoscene.cpp index b77c94b8..734e89be 100644 --- a/game/shared/choreoscene.cpp +++ b/game/shared/choreoscene.cpp @@ -156,7 +156,6 @@ CChoreoScene& CChoreoScene::operator=( const CChoreoScene& src ) m_pTokenizer = src.m_pTokenizer; m_flCurrentTime = src.m_flCurrentTime; - m_flStartLoopTime = src.m_flStartLoopTime; m_flStartTime = src.m_flStartTime; m_flEndTime = src.m_flEndTime; m_flSoundSystemLatency = src.m_flSoundSystemLatency; @@ -235,7 +234,6 @@ void CChoreoScene::Init( IChoreoEventCallback *callback ) m_szMapname[ 0 ] = 0; m_flCurrentTime = 0.0f; - m_flStartLoopTime = -1.f; m_flStartTime = 0.0f; m_flEndTime = 0.0f; m_flSoundSystemLatency = 0.0f; @@ -2314,8 +2312,6 @@ void CChoreoScene::ResetSimulation( bool forward /*= true*/, float starttime /*= m_flCurrentTime = forward ? m_flEarliestTime : m_flLatestTime; - m_flStartLoopTime = -1.f; - // choreoprintf( 0, "Start time %f\n", m_flCurrentTime ); m_flLastActiveTime = 0.0f; @@ -2477,15 +2473,6 @@ int CChoreoScene::EventThink( CChoreoEvent *e, float frame_start_time, float fra } } */ - - if ( !suppressed ) - { - // if this SPEAK event starts before the beginning of the current loop, don't play the SPEAK event again in the loop - if ( m_flStartLoopTime >= 0.f && starttime < m_flStartLoopTime ) - { - return iret; - } - } } break; case CChoreoEvent::SUBSCENE: @@ -2849,8 +2836,6 @@ void CChoreoScene::SetTime( float t ) void CChoreoScene::LoopToTime( float t ) { m_flCurrentTime = t; - - m_flStartLoopTime = t; } //----------------------------------------------------------------------------- diff --git a/game/shared/choreoscene.h b/game/shared/choreoscene.h index d8203c14..0cf281d6 100644 --- a/game/shared/choreoscene.h +++ b/game/shared/choreoscene.h @@ -84,6 +84,9 @@ class CChoreoScene : public ICurveDataAccessor // Event callback handler void SetEventCallbackInterface( IChoreoEventCallback *callback ); +#ifdef MAPBASE + IChoreoEventCallback *GetEventCallbackInterface() { return m_pIChoreoEventCallback; } +#endif // Loading bool ParseFromBuffer( char const *pFilename, ISceneTokenProcessor *tokenizer ); @@ -326,8 +329,6 @@ class CChoreoScene : public ICurveDataAccessor // Current simulation time float m_flCurrentTime; - float m_flStartLoopTime; - float m_flStartTime; float m_flEndTime; diff --git a/game/shared/effect_color_tables.h b/game/shared/effect_color_tables.h index 348e894f..322d0e08 100644 --- a/game/shared/effect_color_tables.h +++ b/game/shared/effect_color_tables.h @@ -33,10 +33,10 @@ enum // Commander mode table static colorentry_t commandercolors[] = { - { COMMAND_POINT_RED, 1, 0, 0 }, - { COMMAND_POINT_BLUE, 0, 0, 1 }, - { COMMAND_POINT_GREEN, 0, 1, 0 }, - { COMMAND_POINT_YELLOW, 1, 1, 0 }, + { COMMAND_POINT_RED, 1.0, 0.0, 0.0 }, + { COMMAND_POINT_BLUE, 0.0, 0.0, 1.0 }, + { COMMAND_POINT_GREEN, 0.0, 1.0, 0.0 }, + { COMMAND_POINT_YELLOW, 1.0, 1.0, 0.0 }, }; static colorentry_t bloodcolors[] = diff --git a/game/shared/effect_dispatch_data.cpp b/game/shared/effect_dispatch_data.cpp index 8128468e..e295991f 100644 --- a/game/shared/effect_dispatch_data.cpp +++ b/game/shared/effect_dispatch_data.cpp @@ -116,7 +116,7 @@ SendPropInt( SENDINFO_NOCHECK( m_nMaterial ), MAX_MODEL_INDEX_BITS, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NOCHECK( m_nDamageType ), 32, SPROP_UNSIGNED ), - SendPropInt( SENDINFO_NOCHECK( m_nHitBox ), 12, SPROP_UNSIGNED ), + SendPropInt( SENDINFO_NOCHECK( m_nHitBox ), 11, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ), diff --git a/game/shared/env_wind_shared.cpp b/game/shared/env_wind_shared.cpp index 422e9e99..02df324a 100644 --- a/game/shared/env_wind_shared.cpp +++ b/game/shared/env_wind_shared.cpp @@ -70,6 +70,9 @@ #include "IEffects.h" #include "engine/IEngineSound.h" #include "sharedInterface.h" +#ifdef CLIENT_DLL +#include "renderparm.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -77,12 +80,20 @@ //----------------------------------------------------------------------------- // globals //----------------------------------------------------------------------------- +#ifdef MAPBASE +static CUtlLinkedList< CEnvWindShared * > s_windControllers; +#else static Vector s_vecWindVelocity( 0, 0, 0 ); - +#endif CEnvWindShared::CEnvWindShared() : m_WindAveQueue(10), m_WindVariationQueue(10) { m_pWindSound = NULL; +#ifdef MAPBASE + s_windControllers.AddToTail( this ); + m_windRadius = -1.0f; + m_flTreeSwayScale = 1.0f; +#endif } CEnvWindShared::~CEnvWindShared() @@ -91,6 +102,9 @@ CEnvWindShared::~CEnvWindShared() { CSoundEnvelopeController::GetController().Shutdown( m_pWindSound ); } +#ifdef MAPBASE + s_windControllers.FindAndRemove( this ); +#endif } void CEnvWindShared::Init( int nEntIndex, int iRandomSeed, float flTime, @@ -103,6 +117,13 @@ void CEnvWindShared::Init( int nEntIndex, int iRandomSeed, float flTime, m_Stream.SetSeed( iRandomSeed ); m_WindVariationStream.SetSeed( iRandomSeed ); m_iWindDir = m_iInitialWindDir = iInitialWindYaw; +#ifdef MAPBASE + // Bound it for networking as a postive integer + m_iInitialWindDir = (int)( anglemod( m_iInitialWindDir ) ); + + if (m_windRadiusInner == 0.0f) + m_windRadiusInner = m_windRadius; +#endif m_flAveWindSpeed = m_flWindSpeed = m_flInitialWindSpeed = flInitialWindSpeed; @@ -163,6 +184,31 @@ void CEnvWindShared::UpdateWindSound( float flTotalWindSpeed ) } +#ifdef MAPBASE +#define TREE_SWAY_UPDATE_TIME 2.0f + +void CEnvWindShared::UpdateTreeSway( float flTime ) +{ +#ifdef CLIENT_DLL + while( flTime >= m_flSwayTime ) + { + // Since the wind is constantly changing, but we need smooth values, we cache them off here. + m_PrevSwayVector = m_CurrentSwayVector; + m_CurrentSwayVector = m_flTreeSwayScale != 1.0f ? (m_currentWindVector * m_flTreeSwayScale) : m_currentWindVector; + m_flSwayTime += TREE_SWAY_UPDATE_TIME; + } + + // Update vertex shader + float flPercentage = ( 1 - ( ( m_flSwayTime - flTime ) / TREE_SWAY_UPDATE_TIME ) ); + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + // Dividing by 2 helps the numbers the shader is expecting stay in line with other expected game values. + Vector vecWind = Lerp( flPercentage, m_PrevSwayVector, m_CurrentSwayVector ) / 25.f; + pRenderContext->SetVectorRenderingParameter( VECTOR_RENDERPARM_WIND_DIRECTION, vecWind ); +#endif +} +#endif + + //----------------------------------------------------------------------------- // Updates the wind speed //----------------------------------------------------------------------------- @@ -179,6 +225,14 @@ float CEnvWindShared::WindThink( float flTime ) ComputeWindVariation( flTime ); +#if defined(MAPBASE) && defined(CLIENT_DLL) + if (m_flTreeSwayScale != 0.0f) + { + // Update Tree Sway + UpdateTreeSway( flTime ); + } +#endif + while (true) { // First, simulate up to the next switch time... @@ -218,9 +272,15 @@ float CEnvWindShared::WindThink( float flTime ) // We're about to exit, let's set the wind velocity... QAngle vecWindAngle( 0, m_iWindDir + m_flWindAngleVariation, 0 ); +#ifdef MAPBASE + AngleVectors( vecWindAngle, &m_currentWindVector ); + float flTotalWindSpeed = m_flWindSpeed * m_flWindSpeedVariation; + m_currentWindVector *= flTotalWindSpeed; +#else AngleVectors( vecWindAngle, &s_vecWindVelocity ); float flTotalWindSpeed = m_flWindSpeed * m_flWindSpeedVariation; s_vecWindVelocity *= flTotalWindSpeed; +#endif // If we reached a steady state, we don't need to be called until the switch time // Otherwise, we should be called immediately @@ -278,9 +338,66 @@ float CEnvWindShared::WindThink( float flTime ) //----------------------------------------------------------------------------- void ResetWindspeed() { +#ifdef MAPBASE + FOR_EACH_LL( s_windControllers, it ) + { + s_windControllers[it]->m_currentWindVector.Init( 0, 0, 0 ); + } +#else s_vecWindVelocity.Init( 0, 0, 0 ); +#endif } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// GetWindspeedAtTime was never finished to actually take time in to consideration. We don't need +// features that aren't written, but we do need to have multiple wind controllers on a map, so +// we need to find the one that is affecting the given location and return its speed. +// +// NEW WITH MAPBASE: Inner-radius! +// You can now choose an inner-radius for your wind, which allows for varying intensities at different distances. +// This can mix in with a global wind controller or even other wind controllers. +//----------------------------------------------------------------------------- +Vector GetWindspeedAtLocation( const Vector &location ) +{ + Vector wind = Vector( 0, 0, 0 ); + + FOR_EACH_LL( s_windControllers, it ) + { + CEnvWindShared *thisWindController = s_windControllers[it]; + float distance = (thisWindController->m_location - location).Length(); + + if( distance < thisWindController->m_windRadius ) + { + if (distance > thisWindController->m_windRadiusInner) + { + // New with Mapbase: Inner-radius! + wind += thisWindController->m_currentWindVector * + ((distance - thisWindController->m_windRadiusInner) / (thisWindController->m_windRadius - thisWindController->m_windRadiusInner)); + } + else + { + // This location is within our area of influence, so return our computer wind vector + return thisWindController->m_currentWindVector; + } + } + } + + FOR_EACH_LL( s_windControllers, it ) + { + CEnvWindShared *thisWindController = s_windControllers[it]; + + if( thisWindController->m_windRadius == -1.0f ) + { + // We do a second search for a global controller so you don't have to worry about order in the list. + //wind += thisWindController->m_currentWindVector; + wind = VectorLerp( wind, thisWindController->m_currentWindVector, 1.0f ); + } + } + + return wind;// No wind +} +#endif //----------------------------------------------------------------------------- // Method to sample the windspeed at a particular time @@ -289,5 +406,16 @@ void GetWindspeedAtTime( float flTime, Vector &vecVelocity ) { // For now, ignore history and time.. fix later when we use wind to affect // client-side prediction +#ifdef MAPBASE + if ( s_windControllers.Count() == 0 ) + { + vecVelocity.Init( 0, 0, 0 ); + } + else + { + VectorCopy( s_windControllers[ s_windControllers.Head() ]->m_currentWindVector, vecVelocity ); + } +#else VectorCopy( s_vecWindVelocity, vecVelocity ); +#endif } diff --git a/game/shared/env_wind_shared.h b/game/shared/env_wind_shared.h index e1084e9f..bea9ea62 100644 --- a/game/shared/env_wind_shared.h +++ b/game/shared/env_wind_shared.h @@ -145,6 +145,10 @@ class CEnvWindShared void Init( int iEntIndex, int iRandomSeed, float flTime, int iWindDir, float flInitialWindSpeed ); +#ifdef MAPBASE + void SetLocation( const Vector &location ); +#endif + // Method to update the wind speed // Time passed in here is global time, not delta time // The function returns the time at which it must be called again @@ -157,6 +161,10 @@ class CEnvWindShared CNetworkVar( int, m_iMinWind ); // the slowest the wind can normally blow CNetworkVar( int, m_iMaxWind ); // the fastest the wind can normally blow +#ifdef MAPBASE + CNetworkVar( float, m_windRadius ); // the radius this entity affects with its windiness, so a map can have multiple + CNetworkVar( float, m_windRadiusInner ); // the inner-radius for noticable distance fading +#endif CNetworkVar( int, m_iMinGust ); // the slowest that a gust can be CNetworkVar( int, m_iMaxGust ); // the fastest that a gust can be @@ -166,10 +174,21 @@ class CEnvWindShared CNetworkVar( float, m_flGustDuration ); // max time between gusts CNetworkVar( int, m_iGustDirChange ); // max number of degrees wind dir changes on gusts. +#ifdef MAPBASE + CNetworkVector( m_location ); // The location of this wind controller +#endif int m_iszGustSound; // name of the wind sound to play for gusts. int m_iWindDir; // wind direction (yaw) float m_flWindSpeed; // the wind speed +#ifdef MAPBASE + Vector m_currentWindVector; // For all the talk of proper prediction, we ended up just storing and returning through a static vector. Now we can have multiple env_wind, so we need this in here. + Vector m_CurrentSwayVector; + Vector m_PrevSwayVector; + + CNetworkVar( float, m_flTreeSwayScale ); +#endif + CNetworkVar( int, m_iInitialWindDir ); CNetworkVar( float, m_flInitialWindSpeed ); @@ -196,7 +215,12 @@ class CEnvWindShared // Updates the wind sound void UpdateWindSound( float flTotalWindSpeed ); +#ifdef MAPBASE + void UpdateTreeSway( float flTime ); +#endif + float m_flVariationTime; + float m_flSwayTime; float m_flSimTime; // What's the time I last simulated up to? float m_flSwitchTime; // when do I actually switch from gust to not gust float m_flAveWindSpeed; // the average wind speed @@ -227,6 +251,19 @@ class CEnvWindShared CEnvWindShared( const CEnvWindShared & ); // not defined, not accessible }; +#ifdef MAPBASE +//----------------------------------------------------------------------------- +inline void CEnvWindShared::SetLocation( const Vector &location ) +{ + m_location = location; +} + + +//----------------------------------------------------------------------------- +// Method to sample the wind speed at a particular location +//----------------------------------------------------------------------------- +Vector GetWindspeedAtLocation( const Vector &location ); +#endif //----------------------------------------------------------------------------- // Method to sample the windspeed at a particular time diff --git a/game/shared/eventlist.cpp b/game/shared/eventlist.cpp index f52f8021..043293bc 100644 --- a/game/shared/eventlist.cpp +++ b/game/shared/eventlist.cpp @@ -248,8 +248,9 @@ void EventList_RegisterSharedEvents( void ) REGISTER_SHARED_ANIMEVENT( AE_WPN_UNHIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_PLAYWPNSOUND, AE_TYPE_CLIENT | AE_TYPE_SERVER ); - REGISTER_SHARED_ANIMEVENT( AE_RD_ROBOT_POP_PANELS_OFF, AE_TYPE_CLIENT | AE_TYPE_SERVER ); - REGISTER_SHARED_ANIMEVENT( AE_TAUNT_ENABLE_MOVE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); - REGISTER_SHARED_ANIMEVENT( AE_TAUNT_DISABLE_MOVE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); +#ifdef MAPBASE + REGISTER_SHARED_ANIMEVENT( AE_NPC_RESPONSE, AE_TYPE_SERVER ); + REGISTER_SHARED_ANIMEVENT( AE_NPC_RESPONSE_FORCED, AE_TYPE_SERVER ); +#endif } \ No newline at end of file diff --git a/game/shared/eventlist.h b/game/shared/eventlist.h index 69c6f0ca..ee8b38df 100644 --- a/game/shared/eventlist.h +++ b/game/shared/eventlist.h @@ -85,10 +85,10 @@ typedef enum AE_WPN_PLAYWPNSOUND, // Play a weapon sound from the weapon script file - AE_RD_ROBOT_POP_PANELS_OFF, - - AE_TAUNT_ENABLE_MOVE, - AE_TAUNT_DISABLE_MOVE, +#ifdef MAPBASE + AE_NPC_RESPONSE, // Play a response system concept if we're not speaking + AE_NPC_RESPONSE_FORCED, // Always play a response system concept +#endif LAST_SHARED_ANIMEVENT, } Animevent; diff --git a/game/shared/expressionsample.h b/game/shared/expressionsample.h index 006db6d0..663328dc 100644 --- a/game/shared/expressionsample.h +++ b/game/shared/expressionsample.h @@ -69,7 +69,6 @@ struct CExpressionSample class ICurveDataAccessor { public: - virtual ~ICurveDataAccessor(){} virtual float GetDuration() = 0; virtual bool CurveHasEndTime() = 0; // only matters for events virtual int GetDefaultCurveType() = 0; diff --git a/game/shared/func_ladder.cpp b/game/shared/func_ladder.cpp index 05f81571..306ae77d 100644 --- a/game/shared/func_ladder.cpp +++ b/game/shared/func_ladder.cpp @@ -5,6 +5,9 @@ //=============================================================================// #include "cbase.h" #include "func_ladder.h" +#ifdef MAPBASE +#include "hl_gamemovement.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -13,6 +16,10 @@ /*static*/ ConVar sv_showladders( "sv_showladders", "0", 0, "Show bbox and dismount points for all ladders (must be set before level load.)\n" ); #endif +#if MAPBASE +extern IGameMovement *g_pGameMovement; +#endif + CUtlVector< CFuncLadder * > CFuncLadder::s_Ladders; //----------------------------------------------------------------------------- // Purpose: @@ -105,7 +112,11 @@ void CFuncLadder::Spawn() } // Force geometry overlays on, but only if developer 2 is set... +#ifdef MAPBASE + if ( sv_showladders.GetBool() ) +#else if ( developer.GetInt() > 1 ) +#endif { m_debugOverlays |= OVERLAY_TEXT_BIT; } @@ -385,6 +396,26 @@ void CFuncLadder::InputDisable( inputdata_t &inputdata ) m_bDisabled = true; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CFuncLadder::InputForcePlayerOn( inputdata_t &inputdata ) +{ + static_cast(g_pGameMovement)->ForcePlayerOntoLadder(this); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CFuncLadder::InputCheckPlayerOn( inputdata_t &inputdata ) +{ + static_cast(g_pGameMovement)->MountPlayerOntoLadder(this); +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - @@ -462,6 +493,10 @@ BEGIN_DATADESC( CFuncLadder ) DEFINE_KEYFIELD( m_surfacePropName,FIELD_STRING, "ladderSurfaceProperties" ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_VOID, "ForcePlayerOn", InputForcePlayerOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "CheckPlayerOn", InputCheckPlayerOn ), +#endif DEFINE_OUTPUT( m_OnPlayerGotOnLadder, "OnPlayerGotOnLadder" ), DEFINE_OUTPUT( m_OnPlayerGotOffLadder, "OnPlayerGotOffLadder" ), diff --git a/game/shared/func_ladder.h b/game/shared/func_ladder.h index 914389d0..50c76eac 100644 --- a/game/shared/func_ladder.h +++ b/game/shared/func_ladder.h @@ -59,6 +59,11 @@ class CFuncLadder : public CBaseEntity void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputForcePlayerOn( inputdata_t &inputdata ); + void InputCheckPlayerOn( inputdata_t &inputdata ); +#endif + bool IsEnabled() const; void PlayerGotOn( CBasePlayer *pPlayer ); diff --git a/game/shared/gamemovement.cpp b/game/shared/gamemovement.cpp index aaff5f59..46afe4f2 100644 --- a/game/shared/gamemovement.cpp +++ b/game/shared/gamemovement.cpp @@ -55,6 +55,10 @@ ConVar player_limit_jump_speed( "player_limit_jump_speed", "1", FCVAR_REPLICATED // duck controls. Its value is meaningless anytime we don't have the options window open. ConVar option_duck_method("option_duck_method", "1", FCVAR_REPLICATED|FCVAR_ARCHIVE );// 0 = HOLD to duck, 1 = Duck is a toggle +#ifdef MAPBASE +ConVar player_crouch_multiplier( "player_crouch_multiplier", "0.33333333", FCVAR_NONE ); +#endif + #ifdef STAGING_ONLY #ifdef CLIENT_DLL ConVar debug_latch_reset_onduck( "debug_latch_reset_onduck", "1", FCVAR_CHEAT ); @@ -518,7 +522,7 @@ void CGameMovement::DiffPrint( char const *fmt, ... ) #endif // !PREDICTION_ERROR_CHECK_LEVEL #ifndef _XBOX -void COM_Log( const char *pszFile, const char *fmt, ...) +void COM_Log( char *pszFile, const char *fmt, ...) { va_list argptr; char string[1024]; @@ -2147,7 +2151,7 @@ void CGameMovement::FullObserverMove( void ) { int mode = player->GetObserverMode(); - if ( mode == OBS_MODE_IN_EYE || mode == OBS_MODE_CHASE || mode == OBS_MODE_POI ) + if ( mode == OBS_MODE_IN_EYE || mode == OBS_MODE_CHASE ) { CBaseEntity * target = player->GetObserverTarget(); @@ -2420,15 +2424,6 @@ bool CGameMovement::CheckJumpButton( void ) SetGroundEntity( NULL ); player->PlayStepSound( (Vector &)mv->GetAbsOrigin(), player->m_pSurfaceData, 1.0, true ); -#ifdef VANCE - CPASAttenuationFilter filter(player); - filter.UsePredictionRules(); - if (random->RandomInt(0, 3) == 0) - { - player->EmitSound(filter, player->entindex(), "AlyxPlayer.Jump"); - } - player->EmitSound(filter, player->entindex(), "AlyxPlayer.JumpGear"); -#endif MoveHelper()->PlayerSetAnimation( PLAYER_JUMP ); @@ -2849,7 +2844,7 @@ inline bool CGameMovement::OnLadder( trace_t &trace ) // HPE_BEGIN // [sbodenbender] make ladders easier to climb in cstrike //============================================================================= -#if defined (CSTRIKE_DLL) +#if defined (CSTRIKE_DLL) || defined(HL2_USES_FUNC_LADDER_CODE) ConVar sv_ladder_dampen ( "sv_ladder_dampen", "0.2", FCVAR_REPLICATED, "Amount to dampen perpendicular movement on a ladder", true, 0.0f, true, 1.0f ); ConVar sv_ladder_angle( "sv_ladder_angle", "-0.707", FCVAR_REPLICATED, "Cos of angle of incidence to ladder perpendicular for applying ladder_dampen", true, -1.0f, true, 1.0f ); #endif @@ -3911,12 +3906,24 @@ void CGameMovement::CheckFalling( void ) if ( player->GetGroundEntity() == NULL || player->m_Local.m_flFallVelocity <= 0 ) return; +#ifdef MAPBASE + if ( player->m_bInTriggerFall ) + { + // This value lets the existing fall damage functions ensure a fatal fall. + player->m_Local.m_flFallVelocity += (PLAYER_FATAL_FALL_SPEED + PLAYER_LAND_ON_FLOATING_OBJECT); + } +#endif + if ( !IsDead() && player->m_Local.m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHOLD ) { bool bAlive = true; float fvol = 0.5; +#ifdef MAPBASE + if ( player->GetWaterLevel() > 0 && !player->m_bInTriggerFall ) +#else if ( player->GetWaterLevel() > 0 ) +#endif { // They landed in water. } @@ -3983,14 +3990,7 @@ void CGameMovement::PlayerRoughLandingEffects( float fvol ) // Play step sound for current texture. player->PlayStepSound( (Vector &)mv->GetAbsOrigin(), player->m_pSurfaceData, fvol, true ); -#ifdef VANCE - if (fvol > 0.25f) - { - CPASAttenuationFilter filter(player); - filter.UsePredictionRules(); - player->EmitSound(filter, player->entindex(), "AlyxPlayer.Land"); - } -#endif + // // Knock the screen around a little bit, temporary effect. // @@ -4309,7 +4309,8 @@ void CGameMovement::HandleDuckingSpeedCrop( void ) { if ( !( m_iSpeedCropped & SPEED_CROPPED_DUCK ) && ( player->GetFlags() & FL_DUCKING ) && ( player->GetGroundEntity() != NULL ) ) { - float frac = 0.33333333f; + // Mapbase makes this an adjustable convar + float frac = player_crouch_multiplier.GetFloat(); mv->m_flForwardMove *= frac; mv->m_flSideMove *= frac; mv->m_flUpMove *= frac; diff --git a/game/shared/gamemovement.h b/game/shared/gamemovement.h index 79c83fc1..1c7a3d0f 100644 --- a/game/shared/gamemovement.h +++ b/game/shared/gamemovement.h @@ -25,6 +25,13 @@ #define GAMEMOVEMENT_TIME_TO_UNDUCK ( TIME_TO_UNDUCK * 1000.0f ) // ms #define GAMEMOVEMENT_TIME_TO_UNDUCK_INV ( GAMEMOVEMENT_DUCK_TIME - GAMEMOVEMENT_TIME_TO_UNDUCK ) +#ifdef MAPBASE +// reddit.com/r/SourceEngine/comments/8vx53b/how_to_get_brush_ladders_working/ +// +// Implements code that allows func_ladder to be used in HL2. +#define HL2_USES_FUNC_LADDER_CODE 1 +#endif + enum { SPEED_CROPPED_RESET = 0, diff --git a/game/shared/gamerules.cpp b/game/shared/gamerules.cpp index 81fa7bfa..cb199617 100644 --- a/game/shared/gamerules.cpp +++ b/game/shared/gamerules.cpp @@ -71,6 +71,67 @@ IMPLEMENT_NETWORKCLASS_ALIASED( GameRulesProxy, DT_GameRulesProxy ) BEGIN_NETWORK_TABLE_NOBASE( CGameRulesProxy, DT_GameRulesProxy ) END_NETWORK_TABLE() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CGameRules, SCRIPT_SINGLETON "The container of the game's rules, handling behavior which could be different on a game-by-game basis." ) + + DEFINE_SCRIPTFUNC( Name, "Gets the name of these rules." ) + + DEFINE_SCRIPTFUNC( Damage_IsTimeBased, "Damage types that are time-based." ) + DEFINE_SCRIPTFUNC( Damage_ShouldGibCorpse, "Damage types that gib the corpse." ) + DEFINE_SCRIPTFUNC( Damage_ShowOnHUD, "Damage types that have client HUD art." ) + DEFINE_SCRIPTFUNC( Damage_NoPhysicsForce, "Damage types that don't have to supply a physics force & position." ) + DEFINE_SCRIPTFUNC( Damage_ShouldNotBleed, "Damage types that don't make the player bleed." ) + + DEFINE_SCRIPTFUNC( ShouldCollide, "Returns whether two collision groups collide with each other in this game." ) + + DEFINE_SCRIPTFUNC( DefaultFOV, "Default player FOV in this game." ) + + DEFINE_SCRIPTFUNC( GetDamageMultiplier, "Ammo type damage multiplier." ) + + DEFINE_SCRIPTFUNC( IsMultiplayer, "Returns true if this is a multiplayer game (like co-op or deathmatch)." ) + + DEFINE_SCRIPTFUNC( InRoundRestart, "Returns true if the round is restarting." ) + + DEFINE_SCRIPTFUNC( AllowThirdPersonCamera, "Returns true if third-person camera is allowed." ) + +#ifdef CLIENT_DLL + + DEFINE_SCRIPTFUNC( IsBonusChallengeTimeBased, "" ) + DEFINE_SCRIPTFUNC( AllowMapParticleEffect, "" ) + DEFINE_SCRIPTFUNC( AllowWeatherParticles, "" ) + DEFINE_SCRIPTFUNC( AllowMapVisionFilterShaders, "" ) + DEFINE_SCRIPTFUNC( TranslateEffectForVisionFilter, "" ) + DEFINE_SCRIPTFUNC( IsLocalPlayer, "" ) + DEFINE_SCRIPTFUNC( ShouldWarnOfAbandonOnQuit, "" ) + +#else + + DEFINE_SCRIPTFUNC( RefreshSkillData, "" ) + + DEFINE_SCRIPTFUNC( IsSkillLevel, "Returns true if the game is set to the specified difficulty/skill level." ) + DEFINE_SCRIPTFUNC( GetSkillLevel, "Returns the game's difficulty/skill level." ) + DEFINE_SCRIPTFUNC( SetSkillLevel, "Sets the game's difficulty/skill level." ) + + DEFINE_SCRIPTFUNC_NAMED( FAllowFlashlight, "AllowFlashlight", "Returns true if players are allowed to switch on their flashlight." ) + + DEFINE_SCRIPTFUNC( IsDeathmatch, "" ) + DEFINE_SCRIPTFUNC( IsTeamplay, "" ) + DEFINE_SCRIPTFUNC( IsCoOp, "" ) + + DEFINE_SCRIPTFUNC( GetGameDescription, "This is the game description that gets seen in server browsers." ) + + DEFINE_SCRIPTFUNC( AllowSPRespawn, "" ) + + DEFINE_SCRIPTFUNC_NAMED( FAllowNPCs, "AllowNPCs", "Returns true if NPCs are allowed." ) + +#endif + + DEFINE_SCRIPTFUNC( GetGameTypeName, "" ) + DEFINE_SCRIPTFUNC( GetGameType, "" ) + +END_SCRIPTDESC() +#endif + CGameRulesProxy::CGameRulesProxy() { @@ -607,6 +668,30 @@ void CGameRules::EndGameFrame( void ) } } +#ifdef MAPBASE +void CGameRules::OnSkillLevelChanged( int iNewLevel ) +{ + variant_t varNewLevel; + varNewLevel.SetInt(iNewLevel); + + // Iterate through all logic_skill entities and fire them + CBaseEntity *pEntity = gEntList.FindEntityByClassname(NULL, "logic_skill"); + while (pEntity) + { + pEntity->AcceptInput("SkillLevelChanged", UTIL_GetLocalPlayer(), NULL, varNewLevel, 0); + pEntity = gEntList.FindEntityByClassname(pEntity, "logic_skill"); + } + + // Fire game event for difficulty level changed + IGameEvent *event = gameeventmanager->CreateEvent("skill_changed"); + if (event) + { + event->SetInt("skill_level", iNewLevel); + gameeventmanager->FireEvent(event); + } +} +#endif + //----------------------------------------------------------------------------- // trace line rules //----------------------------------------------------------------------------- diff --git a/game/shared/gamerules.h b/game/shared/gamerules.h index 5ba66820..9ae672b6 100644 --- a/game/shared/gamerules.h +++ b/game/shared/gamerules.h @@ -173,6 +173,8 @@ abstract_class CGameRules : public CAutoGameSystemPerFrame virtual bool InRoundRestart( void ) { return false; } + virtual void RegisterScriptFunctions( void ){ }; + //Allow thirdperson camera. virtual bool AllowThirdPersonCamera( void ) { return false; } @@ -205,8 +207,6 @@ abstract_class CGameRules : public CAutoGameSystemPerFrame #else - virtual void Status( void (*print) (const char *fmt, ...) ) {} - virtual void GetTaggedConVarList( KeyValues *pCvarTagList ) {} // NVNT see if the client of the player entered is using a haptic device. @@ -235,7 +235,11 @@ abstract_class CGameRules : public CAutoGameSystemPerFrame virtual bool IsSkillLevel( int iLevel ) { return GetSkillLevel() == iLevel; } virtual int GetSkillLevel() { return g_iSkillLevel; } +#ifdef MAPBASE + virtual void OnSkillLevelChanged( int iNewLevel ); +#else virtual void OnSkillLevelChanged( int iNewLevel ) {}; +#endif virtual void SetSkillLevel( int iLevel ) { int oldLevel = g_iSkillLevel; @@ -294,6 +298,10 @@ abstract_class CGameRules : public CAutoGameSystemPerFrame virtual CBaseEntity *GetPlayerSpawnSpot( CBasePlayer *pPlayer );// Place this player on their spawnspot and face them the proper direction. virtual bool IsSpawnPointValid( CBaseEntity *pSpot, CBasePlayer *pPlayer ); +#ifdef MAPBASE + virtual bool AllowSPRespawn() { return false; } +#endif + virtual bool AllowAutoTargetCrosshair( void ) { return TRUE; }; virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args ); // handles the user commands; returns TRUE if command handled properly virtual void ClientSettingsChanged( CBasePlayer *pPlayer ); // the player has changed cvars @@ -418,8 +426,6 @@ abstract_class CGameRules : public CAutoGameSystemPerFrame virtual bool IsHolidayActive( /*EHoliday*/ int eHoliday ) const { return false; } - virtual bool IsManualMapChangeOkay( const char **pszReason ){ return true; } - #ifndef CLIENT_DLL private: float m_flNextVerboseLogOutput; diff --git a/game/shared/gamestringpool.cpp b/game/shared/gamestringpool.cpp index f75d4ff9..ee529bf1 100644 --- a/game/shared/gamestringpool.cpp +++ b/game/shared/gamestringpool.cpp @@ -12,6 +12,9 @@ #include "igamesystem.h" #endif #include "gamestringpool.h" +#if defined(MAPBASE) && defined(GAME_DLL) +#include "mapbase/GlobalStrings.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -26,6 +29,9 @@ class CGameStringPool : public CBaseGameSystem #endif { virtual char const *Name() { return "CGameStringPool"; } +#if defined(MAPBASE) && defined(GAME_DLL) + virtual void LevelInitPreEntity() { InitGlobalStrings(); } +#endif virtual void LevelShutdownPostEntity() { FreeAll(); } void FreeAll() @@ -50,15 +56,16 @@ class CGameStringPool : public CBaseGameSystem void Dump( void ) { CUtlVector strings( 0, m_Strings.Count() ); - for (UtlHashHandle_t i = m_Strings.FirstHandle(); i != m_Strings.InvalidHandle(); i = m_Strings.NextHandle(i)) + for ( UtlHashHandle_t i = m_Strings.FirstHandle(); i != m_Strings.InvalidHandle(); i = m_Strings.NextHandle(i) ) { - strings.AddToTail( strings[i] ); + strings.AddToTail( m_Strings[i] ); } + struct _Local { static int __cdecl F(const char * const *a, const char * const *b) { return strcmp(*a, *b); } }; strings.Sort( _Local::F ); - + for ( int i = 0; i < strings.Count(); ++i ) { DevMsg( " %d (0x%p) : %s\n", i, strings[i], strings[i] ); diff --git a/game/shared/hl2/basehlcombatweapon_shared.cpp b/game/shared/hl2/basehlcombatweapon_shared.cpp index 8d64f4a5..06c69df7 100644 --- a/game/shared/hl2/basehlcombatweapon_shared.cpp +++ b/game/shared/hl2/basehlcombatweapon_shared.cpp @@ -317,6 +317,14 @@ float CBaseHLCombatWeapon::CalcViewmodelBob( void ) g_lateralBob = speed*0.005f; g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle); g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f ); + +#ifdef MAPBASE + if (GetBobScale() != 1.0f) + { + //g_verticalBob *= GetBobScale(); + g_lateralBob *= GetBobScale(); + } +#endif //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!) return 0.0f; diff --git a/game/shared/hl2/hl2_gamerules.cpp b/game/shared/hl2/hl2_gamerules.cpp index 0d070517..614783f0 100644 --- a/game/shared/hl2/hl2_gamerules.cpp +++ b/game/shared/hl2/hl2_gamerules.cpp @@ -38,10 +38,217 @@ BEGIN_NETWORK_TABLE_NOBASE( CHalfLife2, DT_HL2GameRules ) #endif END_NETWORK_TABLE() +#if MAPBASE && GAME_DLL +extern bool g_bUseLegacyFlashlight; +extern bool g_bCacheLegacyFlashlightStatus; + +BEGIN_DATADESC( CHalfLife2Proxy ) + + // These get the gamerules values on save and write to them on restore + DEFINE_FIELD( m_save_DefaultCitizenType, FIELD_INTEGER ), + DEFINE_FIELD( m_save_LegacyFlashlight, FIELD_CHARACTER ), + DEFINE_FIELD( m_save_PlayerSquadAutosummonDisabled, FIELD_BOOLEAN ), + DEFINE_FIELD( m_save_StunstickPickupBehavior, FIELD_INTEGER ), + DEFINE_FIELD( m_save_AllowSPRespawn, FIELD_BOOLEAN ), + + // Inputs + DEFINE_INPUTFUNC( FIELD_VOID, "EpisodicOn", InputEpisodicOn ), + DEFINE_INPUTFUNC( FIELD_VOID, "EpisodicOff", InputEpisodicOff ), + + // These are FIELD_STRING because they call KeyValue() directly + DEFINE_INPUTFUNC( FIELD_STRING, "SetFriendlyFire", InputSetFriendlyFire ), + DEFINE_INPUTFUNC( FIELD_STRING, "DefaultCitizenType", InputSetDefaultCitizenType ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetLegacyFlashlight", InputSetLegacyFlashlight ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetPlayerSquadAutosummon", InputSetPlayerSquadAutosummon ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetStunstickPickupBehavior", InputSetStunstickPickupBehavior ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetAllowSPRespawn", InputSetAllowSPRespawn ), + +END_DATADESC() +#endif LINK_ENTITY_TO_CLASS( hl2_gamerules, CHalfLife2Proxy ); IMPLEMENT_NETWORKCLASS_ALIASED( HalfLife2Proxy, DT_HalfLife2Proxy ) +#if defined(MAPBASE) && defined(GAME_DLL) +void CHalfLife2Proxy::InputEpisodicOn( inputdata_t &inputdata ) { KeyValue("SetEpisodic", "1"); } +void CHalfLife2Proxy::InputEpisodicOff( inputdata_t &inputdata ) { KeyValue("SetEpisodic", "0"); } +void CHalfLife2Proxy::InputSetFriendlyFire( inputdata_t &inputdata ) { KeyValue("GlobalFriendlyFire", inputdata.value.String()); } +void CHalfLife2Proxy::InputSetDefaultCitizenType( inputdata_t &inputdata ) { KeyValue("DefaultCitizenType", inputdata.value.String()); } +void CHalfLife2Proxy::InputSetLegacyFlashlight( inputdata_t &inputdata ) { KeyValue("SetLegacyFlashlight", inputdata.value.String()); } +void CHalfLife2Proxy::InputSetPlayerSquadAutosummon( inputdata_t &inputdata ) { KeyValue("SetPlayerSquadAutosummon", inputdata.value.String()); } +void CHalfLife2Proxy::InputSetStunstickPickupBehavior( inputdata_t &inputdata ) { KeyValue("SetStunstickPickupBehavior", inputdata.value.String()); } +void CHalfLife2Proxy::InputSetAllowSPRespawn( inputdata_t &inputdata ) { KeyValue( "SetAllowSPRespawn", inputdata.value.String() ); } + +//----------------------------------------------------------------------------- +// Purpose: Cache user entity field values until spawn is called. +// Input : szKeyName - Key to handle. +// szValue - Value for key. +// Output : Returns true if the key was handled, false if not. +//----------------------------------------------------------------------------- +bool CHalfLife2Proxy::KeyValue( const char *szKeyName, const char *szValue ) +{ + if (FStrEq(szKeyName, "DefaultCitizenType")) + { + HL2GameRules()->SetDefaultCitizenType(atoi(szValue)); + } + else if (FStrEq(szKeyName, "GlobalFriendlyFire")) + { + HL2GameRules()->SetGlobalFriendlyFire(TO_THREESTATE(atoi(szValue))); + } + else if (FStrEq(szKeyName, "SetEpisodic") && !FStrEq(szValue, "2")) + { + hl2_episodic.SetValue(!FStrEq(szValue, "0")); + } + else if (FStrEq(szKeyName, "SetLegacyFlashlight")) + { + // Turn off flashlights first + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + + if ( pPlayer ) + { + if (pPlayer->FlashlightIsOn()) + pPlayer->FlashlightTurnOff(); + } + } + + g_bUseLegacyFlashlight = !FStrEq(szValue, "0"); + + // We have overridden it, don't test directory + g_bCacheLegacyFlashlightStatus = false; + + // Tell our save/load we've modified it + // 1 = modified, 2 = legacy enabled + m_save_LegacyFlashlight |= 1; + if (g_bUseLegacyFlashlight) + m_save_LegacyFlashlight |= 2; + } + else if (FStrEq(szKeyName, "SetPlayerSquadAutosummon")) + { + HL2GameRules()->SetAutosummonDisabled(FStrEq(szValue, "0")); + } + else if (FStrEq(szKeyName, "SetStunstickPickupBehavior")) + { + HL2GameRules()->SetStunstickPickupBehavior(atoi(szValue)); + } + else if (FStrEq(szKeyName, "SetAllowSPRespawn")) + { + HL2GameRules()->SetAllowSPRespawn(!FStrEq(szValue, "0")); + } + else + { + return BaseClass::KeyValue( szKeyName, szValue ); + } + + return true; +} + +bool CHalfLife2Proxy::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + if (FStrEq(szKeyName, "DefaultCitizenType")) + { + Q_snprintf( szValue, iMaxLen, "%i", HL2GameRules()->GetDefaultCitizenType() ); + } + else if (FStrEq(szKeyName, "GlobalFriendlyFire")) + { + Q_snprintf( szValue, iMaxLen, "%i", HL2GameRules()->GlobalFriendlyFire() ); + } + else if (FStrEq(szKeyName, "SetEpisodic") && !FStrEq(szValue, "2")) + { + Q_snprintf( szValue, iMaxLen, "%s", hl2_episodic.GetString() ); + } + else if (FStrEq(szKeyName, "SetLegacyFlashlight")) + { + Q_snprintf( szValue, iMaxLen, "%d", g_bUseLegacyFlashlight ); + } + else if (FStrEq(szKeyName, "SetPlayerSquadAutosummon")) + { + Q_snprintf( szValue, iMaxLen, "%d", HL2GameRules()->AutosummonDisabled() ); + } + else if (FStrEq(szKeyName, "SetStunstickPickupBehavior")) + { + Q_snprintf( szValue, iMaxLen, "%i", HL2GameRules()->GetStunstickPickupBehavior() ); + } + else if (FStrEq(szKeyName, "SetAllowSPRespawn")) + { + Q_snprintf( szValue, iMaxLen, "%d", HL2GameRules()->AllowSPRespawn() ); + } + else + { + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Saves the current object out to disk, by iterating through the objects +// data description hierarchy +// Input : &save - save buffer which the class data is written to +// Output : int - 0 if the save failed, 1 on success +//----------------------------------------------------------------------------- +int CHalfLife2Proxy::Save( ISave &save ) +{ + m_save_DefaultCitizenType = HL2GameRules()->GetDefaultCitizenType(); + m_save_PlayerSquadAutosummonDisabled = HL2GameRules()->AutosummonDisabled(); + + // As a static variable, this is actually kept across save games, but lost when the game exits. + // NOTE: Now set in KeyValue() directly + //m_save_LegacyFlashlight = (g_bUseLegacyFlashlight); + + m_save_StunstickPickupBehavior = HL2GameRules()->GetStunstickPickupBehavior(); + + m_save_AllowSPRespawn = HL2GameRules()->AllowSPRespawn(); + + return BaseClass::Save(save); +} + +//----------------------------------------------------------------------------- +// Purpose: Restores the current object from disk, by iterating through the objects +// data description hierarchy +// Input : &restore - restore buffer which the class data is read from +// Output : int - 0 if the restore failed, 1 on success +//----------------------------------------------------------------------------- +int CHalfLife2Proxy::Restore( IRestore &restore ) +{ + int base = BaseClass::Restore(restore); + + HL2GameRules()->SetDefaultCitizenType(m_save_DefaultCitizenType); + HL2GameRules()->SetAutosummonDisabled(m_save_PlayerSquadAutosummonDisabled); + + // Are we modding the legacy flashlight? + if (m_save_LegacyFlashlight & 1) + { + g_bUseLegacyFlashlight = (m_save_LegacyFlashlight & 2) != 0; + + // If we've got the desired legacy flashlight state saved, don't bother caching. + g_bCacheLegacyFlashlightStatus = false; + } + + HL2GameRules()->SetStunstickPickupBehavior(m_save_StunstickPickupBehavior); + + HL2GameRules()->SetAllowSPRespawn(m_save_AllowSPRespawn); + + return base; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHalfLife2Proxy::UpdateOnRemove() +{ + // Were we modding the legacy flashlight? + if (m_save_LegacyFlashlight & 1) + { + // Restore the default state. + g_bCacheLegacyFlashlightStatus = true; + } + + BaseClass::UpdateOnRemove(); +} +#endif + #ifdef CLIENT_DLL void RecvProxy_HL2GameRules( const RecvProp *pProp, void **pOut, void *pData, int objectID ) @@ -122,12 +329,16 @@ ConVar sk_max_smg1 ( "sk_max_smg1","0", FCVAR_REPLICATED); // FIXME: remove these //ConVar sk_plr_dmg_flare_round ( "sk_plr_dmg_flare_round","0", FCVAR_REPLICATED); //ConVar sk_npc_dmg_flare_round ( "sk_npc_dmg_flare_round","0", FCVAR_REPLICATED); -//ConVar sk_max_flare_round ( "sk_max_flare_round","15", FCVAR_REPLICATED); +//ConVar sk_max_flare_round ( "sk_max_flare_round","0", FCVAR_REPLICATED); ConVar sk_plr_dmg_buckshot ( "sk_plr_dmg_buckshot","0", FCVAR_REPLICATED); ConVar sk_npc_dmg_buckshot ( "sk_npc_dmg_buckshot","0", FCVAR_REPLICATED); ConVar sk_max_buckshot ( "sk_max_buckshot","0", FCVAR_REPLICATED); ConVar sk_plr_num_shotgun_pellets( "sk_plr_num_shotgun_pellets","7", FCVAR_REPLICATED); +#ifdef MAPBASE +ConVar sk_plr_num_shotgun_pellets_double( "sk_plr_num_shotgun_pellets_double","12", FCVAR_REPLICATED); +ConVar sk_npc_num_shotgun_pellets( "sk_npc_num_shotgun_pellets","8", FCVAR_REPLICATED); +#endif ConVar sk_plr_dmg_rpg_round ( "sk_plr_dmg_rpg_round","0", FCVAR_REPLICATED); ConVar sk_npc_dmg_rpg_round ( "sk_npc_dmg_rpg_round","0", FCVAR_REPLICATED); @@ -206,7 +417,11 @@ bool CHalfLife2::Damage_IsTimeBased( int iDmgType ) // Damage types that are time-based. #ifdef HL2_EPISODIC // This makes me think EP2 should have its own rules, but they are #ifdef all over in here. +#ifdef MAPBASE + return ( ( iDmgType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) ) != 0 ); +#else return ( ( iDmgType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_SLOWBURN ) ) != 0 ); +#endif #else return BaseClass::Damage_IsTimeBased( iDmgType ); #endif @@ -253,6 +468,12 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP m_flLastHealthDropTime = 0.0f; m_flLastGrenadeDropTime = 0.0f; + +#ifdef MAPBASE + m_DefaultCitizenType = 0; + m_bPlayerSquadAutosummonDisabled = false; + m_bAllowSPRespawn = false; +#endif } //----------------------------------------------------------------------------- @@ -380,7 +601,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_PLAYER, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_COMBINE, D_HT, 0); @@ -389,7 +610,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_MILITARY, D_HT, 0); @@ -416,7 +639,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BARNACLE, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_COMBINE, D_HT, 0); @@ -425,7 +648,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_MANHACK, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_MILITARY, D_HT, 0); @@ -448,7 +673,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_ANTLION, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_COMBINE, D_NU, 0); @@ -457,7 +682,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_MILITARY, D_NU, 0); @@ -475,7 +702,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP // ------------------------------------------------------------ // > CLASS_BULLSQUID // ------------------------------------------------------------ - + /* CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_NONE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_ANTLION, D_HT, 0); @@ -504,7 +731,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER_ALLY, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER_ALLY_VITAL,D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_HACKED_ROLLERMINE,D_HT, 0); - + */ // ------------------------------------------------------------ // > CLASS_CITIZEN_PASSIVE // ------------------------------------------------------------ @@ -513,7 +740,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BARNACLE, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BULLSQUID, D_FR, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BULLSQUID, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_COMBINE, D_NU, 0); @@ -522,7 +749,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_HEADCRAB, D_FR, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_HOUNDEYE, D_FR, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_MANHACK, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_MILITARY, D_NU, 0); @@ -545,7 +774,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BARNACLE, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BULLSQUID, D_FR, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BULLSQUID, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_COMBINE, D_HT, 0); @@ -554,7 +783,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_MILITARY, D_HT, 0); @@ -577,7 +808,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BARNACLE, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_COMBINE, D_LI, 0); @@ -586,7 +817,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_MILITARY, D_NU, 0); @@ -609,7 +842,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_COMBINE, D_LI, 0); @@ -618,7 +851,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_MILITARY, D_NU, 0); @@ -641,7 +876,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_COMBINE, D_LI, 0); @@ -650,7 +885,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_HUNTER, CLASS_MILITARY, D_NU, 0); @@ -673,7 +910,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BARNACLE, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_COMBINE, D_HT, 0); @@ -682,7 +919,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_MILITARY, D_HT, 0); @@ -705,7 +944,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_ANTLION, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_COMBINE, D_NU, 0); @@ -714,7 +953,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_MILITARY, D_NU, 0); @@ -738,7 +979,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BULLSQUID, D_FR, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BULLSQUID, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_COMBINE, D_HT, 0); @@ -747,7 +988,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_MILITARY, D_NU, 0); @@ -762,10 +1005,10 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_PLAYER_ALLY_VITAL,D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HACKED_ROLLERMINE,D_FR, 0); +#ifdef VANCE // ------------------------------------------------------------ // > CLASS_HOUNDEYE // ------------------------------------------------------------ - CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_NONE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_ANTLION, D_HT, 0); @@ -794,7 +1037,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER_ALLY, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_HACKED_ROLLERMINE,D_HT, 0); - +#endif // ------------------------------------------------------------ // > CLASS_MANHACK @@ -804,7 +1047,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_COMBINE, D_NU, 0); @@ -813,7 +1056,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_HEADCRAB, D_HT,-1); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_HOUNDEYE, D_HT,-1); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_MILITARY, D_NU, 0); @@ -836,7 +1081,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_COMBINE, D_NU, 0); @@ -845,7 +1090,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_MILITARY, D_NU, 0); @@ -868,7 +1115,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_COMBINE, D_NU, 0); @@ -877,7 +1124,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_MILITARY, D_NU, 0); @@ -900,7 +1149,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_COMBINE, D_NU, 0); @@ -909,7 +1158,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_MILITARY, D_NU, 0); @@ -932,7 +1183,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_ANTLION, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_COMBINE, D_NU, 0); @@ -941,7 +1192,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_MILITARY, D_NU, 0); @@ -963,7 +1216,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BARNACLE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BULLSEYE, D_HT, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CITIZEN_PASSIVE, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CITIZEN_REBEL, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_COMBINE, D_HT, 0); @@ -972,7 +1225,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_MILITARY, D_HT, 0); @@ -995,7 +1250,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BARNACLE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_COMBINE, D_HT, 0); @@ -1004,7 +1259,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_HEADCRAB, D_FR, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_MILITARY, D_HT, 0); @@ -1027,7 +1284,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BARNACLE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_COMBINE, D_HT, 0); @@ -1036,7 +1293,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_MILITARY, D_HT, 0); @@ -1059,7 +1318,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_COMBINE, D_LI, 0); @@ -1068,7 +1327,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MANHACK, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_METROPOLICE, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MILITARY, D_LI, 0); @@ -1091,7 +1352,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_COMBINE, D_NU, 0); @@ -1100,7 +1361,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_MILITARY, D_NU, 0); @@ -1123,7 +1386,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BARNACLE, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CITIZEN_PASSIVE, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CITIZEN_REBEL, D_LI, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_COMBINE, D_HT, 0); @@ -1132,7 +1395,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_MANHACK, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_MILITARY, D_HT, 0); @@ -1155,7 +1420,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_COMBINE, D_HT, 0); @@ -1164,7 +1429,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_HEADCRAB, D_NU, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_MANHACK, D_FR, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_MILITARY, D_FR, 0); @@ -1187,7 +1454,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BULLSQUID, D_NU, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BULLSQUID, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CITIZEN_PASSIVE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CITIZEN_REBEL, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_COMBINE, D_NU, 0); @@ -1196,7 +1463,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CONSCRIPT, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HOUNDEYE, D_NU, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_METROPOLICE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_MILITARY, D_NU, 0); @@ -1217,33 +1486,35 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP // Hates pretty much everything equally except other earth fauna. // This will make the critter choose the nearest thing as its enemy. // ------------------------------------------------------------ - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_NONE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ANTLION, D_FR, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_NONE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSQUID, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_PASSIVE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_REBEL, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE_GUNSHIP, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE_HUNTER, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CONSCRIPT, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_FLARE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HEADCRAB, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HOUNDEYE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MANHACK, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_METROPOLICE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MILITARY, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MISSILE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_SCANNER, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_STALKER, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_VORTIGAUNT, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ZOMBIE, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PROTOSNIPER, D_FR, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSQUID, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_PASSIVE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_REBEL, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE_GUNSHIP, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE_HUNTER, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CONSCRIPT, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_FLARE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HOUNDEYE, D_HT, 0); +#endif + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MANHACK, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_METROPOLICE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MILITARY, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MISSILE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_SCANNER, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_STALKER, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_VORTIGAUNT, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ZOMBIE, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PROTOSNIPER, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_EARTH_FAUNA, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY, D_FR, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY_VITAL,D_FR, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY, D_HT, 0); + CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY_VITAL,D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HACKED_ROLLERMINE,D_NU, 0); // ------------------------------------------------------------ @@ -1254,7 +1525,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_ANTLION, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BARNACLE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BULLSEYE, D_NU, 0); - CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BULLSQUID, D_HT, 0); + //CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BULLSQUID, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CITIZEN_PASSIVE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CITIZEN_REBEL, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_COMBINE, D_HT, 0); @@ -1263,7 +1534,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CONSCRIPT, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_FLARE, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_HEADCRAB, D_HT, 0); +#ifdef VANCE CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_HOUNDEYE, D_HT, 0); +#endif CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_MANHACK, D_NU, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_METROPOLICE, D_HT, 0); CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_MILITARY, D_HT, 0); @@ -1291,10 +1564,14 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP { case CLASS_NONE: return "CLASS_NONE"; case CLASS_PLAYER: return "CLASS_PLAYER"; +#ifdef MAPBASE + case CLASS_PLAYER_ALLY: return "CLASS_PLAYER_ALLY"; + case CLASS_PLAYER_ALLY_VITAL: return "CLASS_PLAYER_ALLY_VITAL"; +#endif case CLASS_ANTLION: return "CLASS_ANTLION"; case CLASS_BARNACLE: return "CLASS_BARNACLE"; case CLASS_BULLSEYE: return "CLASS_BULLSEYE"; - case CLASS_BULLSQUID: return "CLASS_BULLSQUID"; + //case CLASS_BULLSQUID: return "CLASS_BULLSQUID"; case CLASS_CITIZEN_PASSIVE: return "CLASS_CITIZEN_PASSIVE"; case CLASS_CITIZEN_REBEL: return "CLASS_CITIZEN_REBEL"; case CLASS_COMBINE: return "CLASS_COMBINE"; @@ -1302,7 +1579,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP case CLASS_COMBINE_HUNTER: return "CLASS_COMBINE_HUNTER"; case CLASS_CONSCRIPT: return "CLASS_CONSCRIPT"; case CLASS_HEADCRAB: return "CLASS_HEADCRAB"; +#ifdef VANCE case CLASS_HOUNDEYE: return "CLASS_HOUNDEYE"; +#endif case CLASS_MANHACK: return "CLASS_MANHACK"; case CLASS_METROPOLICE: return "CLASS_METROPOLICE"; case CLASS_MILITARY: return "CLASS_MILITARY"; @@ -1314,6 +1593,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP case CLASS_MISSILE: return "CLASS_MISSILE"; case CLASS_FLARE: return "CLASS_FLARE"; case CLASS_EARTH_FAUNA: return "CLASS_EARTH_FAUNA"; +#ifdef MAPBASE + case CLASS_HACKED_ROLLERMINE: return "CLASS_HACKED_ROLLERMINE"; +#endif default: return "MISSING CLASS in ClassifyText()"; } @@ -1400,7 +1682,12 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP // came from the player's physcannon. CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); +#ifdef MAPBASE + // Friendly fire needs to be handled here. + if ( pPlayer && !pVictim->MyNPCPointer()->FriendlyFireEnabled() ) +#else if( pPlayer ) +#endif { CBaseEntity *pWeapon = pPlayer->HasNamedPlayerItem("weapon_physcannon"); @@ -1769,6 +2056,96 @@ bool CHalfLife2::ShouldBurningPropsEmitLight() } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Gets the default citizen type. +//----------------------------------------------------------------------------- +int CHalfLife2::GetDefaultCitizenType() +{ + return m_DefaultCitizenType; +} + +//----------------------------------------------------------------------------- +// Sets the default citizen type. +//----------------------------------------------------------------------------- +void CHalfLife2::SetDefaultCitizenType(int val) +{ + m_DefaultCitizenType = val; +} + +//----------------------------------------------------------------------------- +// Gets our global friendly fire override. +//----------------------------------------------------------------------------- +ThreeState_t CHalfLife2::GlobalFriendlyFire() +{ + return GlobalEntity_IsInTable(FRIENDLY_FIRE_GLOBALNAME) ? TO_THREESTATE(GlobalEntity_GetState(FRIENDLY_FIRE_GLOBALNAME)) : TRS_NONE; +} + +//----------------------------------------------------------------------------- +// Sets our global friendly fire override. +//----------------------------------------------------------------------------- +void CHalfLife2::SetGlobalFriendlyFire(ThreeState_t val) +{ + GlobalEntity_Add(MAKE_STRING(FRIENDLY_FIRE_GLOBALNAME), gpGlobals->mapname, (GLOBALESTATE)val); +} + +//----------------------------------------------------------------------------- +// Gets our autosummon setting. +//----------------------------------------------------------------------------- +bool CHalfLife2::AutosummonDisabled() +{ + return m_bPlayerSquadAutosummonDisabled; +} + +//----------------------------------------------------------------------------- +// Sets our autosummon setting. +//----------------------------------------------------------------------------- +void CHalfLife2::SetAutosummonDisabled(bool toggle) +{ + m_bPlayerSquadAutosummonDisabled = toggle; +} + +//----------------------------------------------------------------------------- +// Gets our stunstick pickup setting. +//----------------------------------------------------------------------------- +int CHalfLife2::GetStunstickPickupBehavior() +{ + return m_StunstickPickupBehavior; +} + +//----------------------------------------------------------------------------- +// Sets our stunstick pickup setting. +//----------------------------------------------------------------------------- +void CHalfLife2::SetStunstickPickupBehavior(int val) +{ + m_StunstickPickupBehavior = val; +} + +//----------------------------------------------------------------------------- +// Gets our SP respawn setting. +//----------------------------------------------------------------------------- +bool CHalfLife2::AllowSPRespawn() +{ + return m_bAllowSPRespawn; +} + +//----------------------------------------------------------------------------- +// Sets our SP respawn setting. +//----------------------------------------------------------------------------- +void CHalfLife2::SetAllowSPRespawn( bool toggle ) +{ + m_bAllowSPRespawn = toggle; +} + +//BEGIN_SIMPLE_DATADESC( CHalfLife2 ) +// +// DEFINE_FIELD( m_DefaultCitizenType, FIELD_INTEGER ), +// DEFINE_FIELD( m_bPlayerSquadAutosummonDisabled, FIELD_BOOLEAN ), +// +//END_DATADESC() +#endif + + #endif//CLIENT_DLL // ------------------------------------------------------------------------------------ // @@ -1797,9 +2174,7 @@ CAmmoDef *GetAmmoDef() if ( !bInitted ) { bInitted = true; -#ifdef VANCE - def.AddAmmoType("AR1", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar1", "sk_npc_dmg_ar1", "sk_max_ar1", BULLET_IMPULSE(200, 1225), 0); -#endif // VANCE + def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar2", "sk_npc_dmg_ar2", "sk_max_ar2", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 ); @@ -1810,8 +2185,8 @@ CAmmoDef *GetAmmoDef() def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", "sk_npc_dmg_buckshot", "sk_max_buckshot", BULLET_IMPULSE(400, 1200), 0 ); def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 ); def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 ); - def.AddAmmoType("SniperRound", DMG_BULLET | DMG_SNIPER | DMG_DISSOLVE, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_sniper_round", "sk_npc_dmg_sniper_round", "sk_max_sniper_round", BULLET_IMPULSE(650, 6000), 0 ); - def.AddAmmoType("SniperPenetratedRound", DMG_BULLET | DMG_SNIPER | DMG_DISSOLVE, TRACER_LINE_AND_WHIZ, "sk_dmg_sniper_penetrate_plr", "sk_dmg_sniper_penetrate_npc", "sk_max_sniper_round", BULLET_IMPULSE(150, 6000), 0 ); + def.AddAmmoType("SniperRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_plr_dmg_sniper_round", "sk_npc_dmg_sniper_round", "sk_max_sniper_round", BULLET_IMPULSE(650, 6000), 0 ); + def.AddAmmoType("SniperPenetratedRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_dmg_sniper_penetrate_plr", "sk_dmg_sniper_penetrate_npc", "sk_max_sniper_round", BULLET_IMPULSE(150, 6000), 0 ); def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0); def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 ); def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 ); @@ -1870,9 +2245,20 @@ CAmmoDef *GetAmmoDef() def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0); #ifdef HL2_EPISODIC def.AddAmmoType("Hopwire", DMG_BLAST, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_hopwire", 0, 0); +#ifdef MAPBASE + // + // Always gibbing would make it look better on antlions, etc. + // Hopefully this is very good and isn't bad. + // + def.AddAmmoType("CombineHeavyCannon", DMG_BULLET | DMG_ALWAYSGIB, TRACER_LINE, 40, 40, NULL, 10 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 10 kg weight at 750 ft/s +#else def.AddAmmoType("CombineHeavyCannon", DMG_BULLET, TRACER_LINE, 40, 40, NULL, 10 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 10 kg weight at 750 ft/s +#endif def.AddAmmoType("ammo_proto1", DMG_BULLET, TRACER_LINE, 0, 0, 10, 0, 0 ); #endif // HL2_EPISODIC +#ifdef MAPBASE + def.AddAmmoType("slam", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); +#endif } return &def; diff --git a/game/shared/hl2/hl2_gamerules.h b/game/shared/hl2/hl2_gamerules.h index 4f64793f..a8eace12 100644 --- a/game/shared/hl2/hl2_gamerules.h +++ b/game/shared/hl2/hl2_gamerules.h @@ -19,12 +19,46 @@ #define CHalfLife2Proxy C_HalfLife2Proxy #endif +#if MAPBASE && GAME_DLL +#define FRIENDLY_FIRE_GLOBALNAME "friendly_fire_override" +#endif + class CHalfLife2Proxy : public CGameRulesProxy { public: DECLARE_CLASS( CHalfLife2Proxy, CGameRulesProxy ); DECLARE_NETWORKCLASS(); + +#if defined(MAPBASE) && defined(GAME_DLL) + bool KeyValue( const char *szKeyName, const char *szValue ); + bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + + virtual int Save( ISave &save ); + virtual int Restore( IRestore &restore ); + virtual void UpdateOnRemove(); + + // Inputs + void InputEpisodicOn( inputdata_t &inputdata ); + void InputEpisodicOff( inputdata_t &inputdata ); + void InputSetFriendlyFire( inputdata_t &inputdata ); + void InputSetDefaultCitizenType( inputdata_t &inputdata ); + void InputSetLegacyFlashlight( inputdata_t &inputdata ); + void InputSetPlayerSquadAutosummon( inputdata_t &inputdata ); + void InputSetStunstickPickupBehavior( inputdata_t &inputdata ); + void InputSetAllowSPRespawn( inputdata_t &inputdata ); + + // Gamerules classes don't seem to support datadescs, so the hl2_gamerules entity takes the current values + // from the actual gamerules and saves them in the entity itself, where they're saved via the entity's own datadesc. + // When the save is loaded, the entity sets the main gamerules values according to what was saved. + int m_save_DefaultCitizenType; + char m_save_LegacyFlashlight; + bool m_save_PlayerSquadAutosummonDisabled; + int m_save_StunstickPickupBehavior; + bool m_save_AllowSPRespawn; + + DECLARE_DATADESC(); +#endif }; @@ -47,6 +81,10 @@ class CHalfLife2 : public CSingleplayRules virtual void LevelInitPreEntity(); #endif +#ifdef MAPBASE_VSCRIPT + virtual void RegisterScriptFunctions( void ); +#endif + private: // Rules change for the mega physgun CNetworkVar( bool, m_bMegaPhysgun ); @@ -88,11 +126,35 @@ class CHalfLife2 : public CSingleplayRules virtual bool IsAlyxInDarknessMode(); +#ifdef MAPBASE + int GetDefaultCitizenType(); + void SetDefaultCitizenType(int val); + + ThreeState_t GlobalFriendlyFire(); + void SetGlobalFriendlyFire(ThreeState_t val); + + bool AutosummonDisabled(); + void SetAutosummonDisabled(bool toggle); + + int GetStunstickPickupBehavior(); + void SetStunstickPickupBehavior(int val); + + virtual bool AllowSPRespawn(); + void SetAllowSPRespawn( bool toggle ); +#endif + private: float m_flLastHealthDropTime; float m_flLastGrenadeDropTime; +#ifdef MAPBASE + int m_DefaultCitizenType; + bool m_bPlayerSquadAutosummonDisabled; + int m_StunstickPickupBehavior; + bool m_bAllowSPRespawn; +#endif + void AdjustPlayerDamageTaken( CTakeDamageInfo *pInfo ); float AdjustPlayerDamageInflicted( float damage ); diff --git a/game/shared/hl2/hl2_usermessages.cpp b/game/shared/hl2/hl2_usermessages.cpp index a5c81329..93ca871e 100644 --- a/game/shared/hl2/hl2_usermessages.cpp +++ b/game/shared/hl2/hl2_usermessages.cpp @@ -41,8 +41,14 @@ void RegisterUserMessages( void ) usermessages->Register( "KeyHintText", -1 ); // Displays hint text display usermessages->Register( "SquadMemberDied", 0 ); usermessages->Register( "AmmoDenied", 2 ); +#ifdef MAPBASE + // This sends the credits file now + usermessages->Register( "CreditsMsg", -1 ); + usermessages->Register( "LogoTimeMsg", -1 ); +#else usermessages->Register( "CreditsMsg", 1 ); usermessages->Register( "LogoTimeMsg", 4 ); +#endif usermessages->Register( "AchievementEvent", -1 ); usermessages->Register( "UpdateJalopyRadar", -1 ); diff --git a/game/shared/hl2/hl_gamemovement.cpp b/game/shared/hl2/hl_gamemovement.cpp index 146b9416..d4fc3aef 100644 --- a/game/shared/hl2/hl_gamemovement.cpp +++ b/game/shared/hl2/hl_gamemovement.cpp @@ -9,23 +9,17 @@ #include "utlrbtree.h" #include "hl2_shareddefs.h" -/* -// MY CODE : Gravity Well -#ifdef CLIENT_DLL -#include "c_gravityplayer.h" -#else -#include "gravity_player.h" +#ifdef HL2MP +#include "hl2mp_gamerules.h" #endif -// -*/ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -static ConVar sv_autoladderdismount("sv_autoladderdismount", "1", FCVAR_REPLICATED, "Automatically dismount from ladders when you reach the end (don't have to +USE)."); -static ConVar sv_ladderautomountdot("sv_ladderautomountdot", "0.4", FCVAR_REPLICATED, "When auto-mounting a ladder by looking up its axis, this is the tolerance for looking now directly along the ladder axis."); +static ConVar sv_autoladderdismount( "sv_autoladderdismount", "1", FCVAR_REPLICATED, "Automatically dismount from ladders when you reach the end (don't have to +USE)." ); +static ConVar sv_ladderautomountdot( "sv_ladderautomountdot", "0.4", FCVAR_REPLICATED, "When auto-mounting a ladder by looking up its axis, this is the tolerance for looking now directly along the ladder axis." ); -static ConVar sv_ladder_useonly("sv_ladder_useonly", "0", FCVAR_REPLICATED, "If set, ladders can only be mounted by pressing +USE"); +static ConVar sv_ladder_useonly( "sv_ladder_useonly", "0", FCVAR_REPLICATED, "If set, ladders can only be mounted by pressing +USE" ); #define USE_DISMOUNT_SPEED 100 @@ -41,13 +35,13 @@ CHL2GameMovement::CHL2GameMovement() // Input : type - // Output : int //----------------------------------------------------------------------------- -int CHL2GameMovement::GetCheckInterval(IntervalType_t type) +int CHL2GameMovement::GetCheckInterval( IntervalType_t type ) { // HL2 ladders need to check every frame!!! - if (type == LADDER) + if ( type == LADDER ) return 1; - return BaseClass::GetCheckInterval(type); + return BaseClass::GetCheckInterval( type ); } //----------------------------------------------------------------------------- @@ -76,53 +70,53 @@ void CHL2GameMovement::SwallowUseKey() // can move into this spot and cause us to get stuck when we get there class CReservePlayerSpot : public CBaseEntity { - DECLARE_CLASS(CReservePlayerSpot, CBaseEntity) + DECLARE_CLASS( CReservePlayerSpot, CBaseEntity ) public: - static CReservePlayerSpot *ReserveSpot(CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot); + static CReservePlayerSpot *ReserveSpot( CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot ); virtual void Spawn(); }; -CReservePlayerSpot *CReservePlayerSpot::ReserveSpot( - CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot) +CReservePlayerSpot *CReservePlayerSpot::ReserveSpot( + CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot ) { - CReservePlayerSpot *spot = (CReservePlayerSpot *)CreateEntityByName("reserved_spot"); - Assert(spot); + CReservePlayerSpot *spot = ( CReservePlayerSpot * )CreateEntityByName( "reserved_spot" ); + Assert( spot ); - spot->SetAbsOrigin(org); - UTIL_SetSize(spot, mins, maxs); - spot->SetOwnerEntity(owner); + spot->SetAbsOrigin( org ); + UTIL_SetSize( spot, mins, maxs ); + spot->SetOwnerEntity( owner ); spot->Spawn(); // See if spot is valid trace_t tr; UTIL_TraceHull( - org, - org, + org, + org, mins, maxs, MASK_PLAYERSOLID, owner, COLLISION_GROUP_PLAYER_MOVEMENT, - &tr); + &tr ); validspot = !tr.startsolid; - if (!validspot) + if ( !validspot ) { - Vector org2 = org + Vector(0, 0, 1); + Vector org2 = org + Vector( 0, 0, 1 ); // See if spot is valid trace_t tr; UTIL_TraceHull( - org2, - org2, + org2, + org2, mins, maxs, MASK_PLAYERSOLID, owner, COLLISION_GROUP_PLAYER_MOVEMENT, - &tr); + &tr ); validspot = !tr.startsolid; } @@ -136,13 +130,13 @@ void CReservePlayerSpot::Spawn() { BaseClass::Spawn(); - SetSolid(SOLID_BBOX); - SetMoveType(MOVETYPE_NONE); + SetSolid( SOLID_BBOX ); + SetMoveType( MOVETYPE_NONE ); // Make entity invisible - AddEffects(EF_NODRAW); + AddEffects( EF_NODRAW ); } -LINK_ENTITY_TO_CLASS(reserved_spot, CReservePlayerSpot); +LINK_ENTITY_TO_CLASS( reserved_spot, CReservePlayerSpot ); #endif //----------------------------------------------------------------------------- @@ -152,40 +146,40 @@ LINK_ENTITY_TO_CLASS(reserved_spot, CReservePlayerSpot); // goalpos - // *ladder - //----------------------------------------------------------------------------- -void CHL2GameMovement::StartForcedMove(bool mounting, float transit_speed, const Vector& goalpos, CFuncLadder *ladder) +void CHL2GameMovement::StartForcedMove( bool mounting, float transit_speed, const Vector& goalpos, CFuncLadder *ladder ) { LadderMove_t* lm = GetLadderMove(); - Assert(lm); + Assert( lm ); // Already active, just ignore - if (lm->m_bForceLadderMove) + if ( lm->m_bForceLadderMove ) { return; } #if !defined( CLIENT_DLL ) - if (ladder) + if ( ladder ) { - ladder->PlayerGotOn(GetHL2Player()); + ladder->PlayerGotOn( GetHL2Player() ); // If the Ladder only wants to be there for automount checking, abort now - if (ladder->DontGetOnLadder()) + if ( ladder->DontGetOnLadder() ) return; } - + // Reserve goal slot here bool valid = false; - lm->m_hReservedSpot = CReservePlayerSpot::ReserveSpot( - player, - goalpos, - GetPlayerMins((player->GetFlags() & FL_DUCKING) ? true : false), - GetPlayerMaxs((player->GetFlags() & FL_DUCKING) ? true : false), - valid); - if (!valid) + lm->m_hReservedSpot = CReservePlayerSpot::ReserveSpot( + player, + goalpos, + GetPlayerMins( ( player->GetFlags() & FL_DUCKING ) ? true : false ), + GetPlayerMaxs( ( player->GetFlags() & FL_DUCKING ) ? true : false ), + valid ); + if ( !valid ) { // FIXME: Play a deny sound? - if (lm->m_hReservedSpot) + if ( lm->m_hReservedSpot ) { - UTIL_Remove(lm->m_hReservedSpot); + UTIL_Remove( lm->m_hReservedSpot ); lm->m_hReservedSpot = NULL; } return; @@ -193,36 +187,36 @@ void CHL2GameMovement::StartForcedMove(bool mounting, float transit_speed, const #endif // Use current player origin as start and new origin as dest - lm->m_vecGoalPosition = goalpos; - lm->m_vecStartPosition = mv->GetAbsOrigin(); + lm->m_vecGoalPosition = goalpos; + lm->m_vecStartPosition = mv->GetAbsOrigin(); // Figure out how long it will take to make the gap based on transit_speed Vector delta = lm->m_vecGoalPosition - lm->m_vecStartPosition; float distance = delta.Length(); - - Assert(transit_speed > 0.001f); + + Assert( transit_speed > 0.001f ); // Compute time required to move that distance float transit_time = distance / transit_speed; - if (transit_time < 0.001f) + if ( transit_time < 0.001f ) { transit_time = 0.001f; } - lm->m_bForceLadderMove = true; - lm->m_bForceMount = mounting; + lm->m_bForceLadderMove = true; + lm->m_bForceMount = mounting; - lm->m_flStartTime = gpGlobals->curtime; - lm->m_flArrivalTime = lm->m_flStartTime + transit_time; + lm->m_flStartTime = gpGlobals->curtime; + lm->m_flArrivalTime = lm->m_flStartTime + transit_time; - lm->m_hForceLadder = ladder; + lm->m_hForceLadder = ladder; // Don't get stuck during this traversal since we'll just be slamming the player origin - player->SetMoveType(MOVETYPE_NONE); - player->SetMoveCollide(MOVECOLLIDE_DEFAULT); - player->SetSolid(SOLID_NONE); - SetLadder(ladder); + player->SetMoveType( MOVETYPE_NONE ); + player->SetMoveCollide( MOVECOLLIDE_DEFAULT ); + player->SetSolid( SOLID_NONE ); + SetLadder( ladder ); // Debounce the use key SwallowUseKey(); @@ -234,8 +228,8 @@ void CHL2GameMovement::StartForcedMove(bool mounting, float transit_speed, const bool CHL2GameMovement::ContinueForcedMove() { LadderMove_t* lm = GetLadderMove(); - Assert(lm); - Assert(lm->m_bForceLadderMove); + Assert( lm ); + Assert( lm->m_bForceLadderMove ); // Suppress regular motion mv->m_flForwardMove = 0.0f; @@ -243,40 +237,40 @@ bool CHL2GameMovement::ContinueForcedMove() mv->m_flUpMove = 0.0f; // How far along are we - float frac = (gpGlobals->curtime - lm->m_flStartTime) / (lm->m_flArrivalTime - lm->m_flStartTime); - if (frac > 1.0f) + float frac = ( gpGlobals->curtime - lm->m_flStartTime ) / ( lm->m_flArrivalTime - lm->m_flStartTime ); + if ( frac > 1.0f ) { lm->m_bForceLadderMove = false; #if !defined( CLIENT_DLL ) // Remove "reservation entity" - if (lm->m_hReservedSpot) + if ( lm->m_hReservedSpot ) { - UTIL_Remove(lm->m_hReservedSpot); + UTIL_Remove( lm->m_hReservedSpot ); lm->m_hReservedSpot = NULL; } #endif } - frac = clamp(frac, 0.0f, 1.0f); + frac = clamp( frac, 0.0f, 1.0f ); // Move origin part of the way Vector delta = lm->m_vecGoalPosition - lm->m_vecStartPosition; // Compute interpolated position Vector org; - VectorMA(lm->m_vecStartPosition, frac, delta, org); - mv->SetAbsOrigin(org); + VectorMA( lm->m_vecStartPosition, frac, delta, org ); + mv->SetAbsOrigin( org ); // If finished moving, reset player to correct movetype (or put them on the ladder) - if (!lm->m_bForceLadderMove) + if ( !lm->m_bForceLadderMove ) { - player->SetSolid(SOLID_BBOX); - player->SetMoveType(MOVETYPE_WALK); + player->SetSolid( SOLID_BBOX ); + player->SetMoveType( MOVETYPE_WALK ); - if (lm->m_bForceMount && lm->m_hForceLadder != NULL) + if ( lm->m_bForceMount && lm->m_hForceLadder != NULL ) { - player->SetMoveType(MOVETYPE_LADDER); - SetLadder(lm->m_hForceLadder); + player->SetMoveType( MOVETYPE_LADDER ); + SetLadder( lm->m_hForceLadder ); } // Zero out any velocity @@ -287,23 +281,16 @@ bool CHL2GameMovement::ContinueForcedMove() return lm->m_bForceLadderMove; } -// MY CODE Old Ladder //----------------------------------------------------------------------------- // Purpose: Returns true if the player is on a ladder // Input : &trace - ignored //----------------------------------------------------------------------------- -bool CHL2GameMovement::OnLadder(trace_t &trace) -//{ -// return ( GetLadder() != NULL ) ? true : false; -//} +bool CHL2GameMovement::OnLadder( trace_t &trace ) { -#if defined(HL2_DLL) - if (GetLadder() == nullptr) - return BaseClass::OnLadder(trace); - else - return true; +#ifdef HL2_USES_FUNC_LADDER_CODE + return ( GetLadder() != NULL ) ? true : BaseClass::OnLadder(trace); #else - return (GetLadder() != NULL) ? true : false; + return ( GetLadder() != NULL ) ? true : false; #endif } @@ -314,7 +301,7 @@ bool CHL2GameMovement::OnLadder(trace_t &trace) // **ppLadder - // ladderOrigin - //----------------------------------------------------------------------------- -void CHL2GameMovement::Findladder(float maxdist, CFuncLadder **ppLadder, Vector& ladderOrigin, const CFuncLadder *skipLadder) +void CHL2GameMovement::Findladder( float maxdist, CFuncLadder **ppLadder, Vector& ladderOrigin, const CFuncLadder *skipLadder ) { CFuncLadder *bestLadder = NULL; float bestDist = MAX_COORD_INTEGER; @@ -326,29 +313,29 @@ void CHL2GameMovement::Findladder(float maxdist, CFuncLadder **ppLadder, Vector& int c = CFuncLadder::GetLadderCount(); - for (int i = 0; i < c; i++) + for ( int i = 0 ; i < c; i++ ) { - CFuncLadder *ladder = CFuncLadder::GetLadder(i); + CFuncLadder *ladder = CFuncLadder::GetLadder( i ); - if (!ladder->IsEnabled()) + if ( !ladder->IsEnabled() ) continue; - if (skipLadder && ladder == skipLadder) + if ( skipLadder && ladder == skipLadder ) continue; Vector topPosition; Vector bottomPosition; - ladder->GetTopPosition(topPosition); - ladder->GetBottomPosition(bottomPosition); + ladder->GetTopPosition( topPosition ); + ladder->GetBottomPosition( bottomPosition ); Vector closest; - CalcClosestPointOnLineSegment(mv->GetAbsOrigin(), bottomPosition, topPosition, closest, NULL); + CalcClosestPointOnLineSegment( mv->GetAbsOrigin(), bottomPosition, topPosition, closest, NULL ); - float distSqr = (closest - mv->GetAbsOrigin()).LengthSqr(); + float distSqr = ( closest - mv->GetAbsOrigin() ).LengthSqr(); // Too far away - if (distSqr > maxdistSqr) + if ( distSqr > maxdistSqr ) { continue; } @@ -356,36 +343,36 @@ void CHL2GameMovement::Findladder(float maxdist, CFuncLadder **ppLadder, Vector& // Need to trace to see if it's clear trace_t tr; - UTIL_TraceLine(mv->GetAbsOrigin(), closest, + UTIL_TraceLine( mv->GetAbsOrigin(), closest, MASK_PLAYERSOLID, player, COLLISION_GROUP_NONE, - &tr); + &tr ); - if (tr.fraction != 1.0f && - tr.m_pEnt && - tr.m_pEnt != ladder) + if ( tr.fraction != 1.0f && + tr.m_pEnt && + tr.m_pEnt != ladder ) { // Try a trace stepped up from the ground a bit, in case there's something at ground level blocking us. float sizez = GetPlayerMaxs().z - GetPlayerMins().z; - UTIL_TraceLine(mv->GetAbsOrigin() + Vector(0, 0, sizez * 0.5f), closest, + UTIL_TraceLine( mv->GetAbsOrigin() + Vector( 0, 0, sizez * 0.5f ), closest, MASK_PLAYERSOLID, player, COLLISION_GROUP_NONE, - &tr); + &tr ); - if (tr.fraction != 1.0f && - tr.m_pEnt && - tr.m_pEnt != ladder && - !tr.m_pEnt->IsSolidFlagSet(FSOLID_TRIGGER)) + if ( tr.fraction != 1.0f && + tr.m_pEnt && + tr.m_pEnt != ladder && + !tr.m_pEnt->IsSolidFlagSet( FSOLID_TRIGGER ) ) { continue; } } // See if this is the best one so far - if (distSqr < bestDist) + if ( distSqr < bestDist ) { bestDist = distSqr; bestLadder = ladder; @@ -399,32 +386,130 @@ void CHL2GameMovement::Findladder(float maxdist, CFuncLadder **ppLadder, Vector& } -static bool NearbyDismountLessFunc(const NearbyDismount_t& lhs, const NearbyDismount_t& rhs) +#ifdef MAPBASE +bool CHL2GameMovement::ForcePlayerOntoLadder(CFuncLadder *ladder) +{ + Vector topPosition; + Vector bottomPosition; + + ladder->GetTopPosition(topPosition); + ladder->GetBottomPosition(bottomPosition); + + Vector closest; + CalcClosestPointOnLineSegment(mv->GetAbsOrigin(), bottomPosition, topPosition, closest, NULL); + + StartForcedMove( true, player->MaxSpeed(), closest, ladder ); + + return true; +} + +bool CHL2GameMovement::MountPlayerOntoLadder(CFuncLadder *ladder) +{ + Vector topPosition; + Vector bottomPosition; + + ladder->GetTopPosition(topPosition); + ladder->GetBottomPosition(bottomPosition); + + Vector closest; + CalcClosestPointOnLineSegment(mv->GetAbsOrigin(), bottomPosition, topPosition, closest, NULL); + +#if 0 + // Compute parametric distance along ladder vector... + float oldt; + CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &oldt ); + + // Perform the move accounting for any base velocity. + VectorAdd (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); + TryPlayerMove(); + VectorSubtract (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); + + // Pressed buttons are "changed(xor)" and'ed with the mask of currently held buttons + bool pressing_forward_or_side = mv->m_flForwardMove != 0.0f || mv->m_flSideMove != 0.0f; + + Vector ladderVec = topPosition - bottomPosition; + float LadderLength = VectorNormalize( ladderVec ); + // This test is not perfect by any means, but should help a bit + bool moving_along_ladder = false; + if ( pressing_forward_or_side ) + { + float fwdDot = m_vecForward.Dot( ladderVec ); + if ( fabs( fwdDot ) > 0.9f ) + { + moving_along_ladder = true; + } + } + + // Compute parametric distance along ladder vector... + float newt; + CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &newt ); + + // Fudge of 2 units + float tolerance = 1.0f / LadderLength; + + bool wouldleaveladder = false; + // Moving pPast top or bottom? + if ( newt < -tolerance ) + { + wouldleaveladder = newt < oldt; + } + else if ( newt > ( 1.0f + tolerance ) ) + { + wouldleaveladder = newt > oldt; + } + + // See if we are near the top or bottom but not moving + float dist1sqr, dist2sqr; + + dist1sqr = ( topPosition - mv->GetAbsOrigin() ).LengthSqr(); + dist2sqr = ( bottomPosition - mv->GetAbsOrigin() ).LengthSqr(); + + float dist = MIN( dist1sqr, dist2sqr ); + bool neardismountnode = ( dist < 16.0f * 16.0f ) ? true : false; + float ladderUnitsPerTick = ( MAX_CLIMB_SPEED * gpGlobals->interval_per_tick ); + bool neardismountnode2 = ( dist < ladderUnitsPerTick * ladderUnitsPerTick ) ? true : false; + + // Really close to node, cvar is set, and pressing a key, then simulate a +USE + bool auto_dismount_use = ( neardismountnode2 && + sv_autoladderdismount.GetBool() && + pressing_forward_or_side && + !moving_along_ladder ); + + bool fully_underwater = ( player->GetWaterLevel() == WL_Eyes ) ? true : false; +#endif + + StartForcedMove( true, player->MaxSpeed(), closest, ladder ); + + return true; +} +#endif + +static bool NearbyDismountLessFunc( const NearbyDismount_t& lhs, const NearbyDismount_t& rhs ) { return lhs.distSqr < rhs.distSqr; } -void CHL2GameMovement::GetSortedDismountNodeList(const Vector &org, float radius, CFuncLadder *ladder, CUtlRBTree< NearbyDismount_t, int >& list) +void CHL2GameMovement::GetSortedDismountNodeList( const Vector &org, float radius, CFuncLadder *ladder, CUtlRBTree< NearbyDismount_t, int >& list ) { float radiusSqr = radius * radius; int i; int c = ladder->GetDismountCount(); - for (i = 0; i < c; i++) + for ( i = 0; i < c; i++ ) { - CInfoLadderDismount *spot = ladder->GetDismount(i); - if (!spot) + CInfoLadderDismount *spot = ladder->GetDismount( i ); + if ( !spot ) continue; - float distSqr = (spot->GetAbsOrigin() - org).LengthSqr(); - if (distSqr > radiusSqr) + float distSqr = ( spot->GetAbsOrigin() - org ).LengthSqr(); + if ( distSqr > radiusSqr ) continue; NearbyDismount_t nd; nd.dismount = spot; nd.distSqr = distSqr; - list.Insert(nd); + list.Insert( nd ); } } @@ -433,7 +518,7 @@ void CHL2GameMovement::GetSortedDismountNodeList(const Vector &org, float radius // *ladder - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- -bool CHL2GameMovement::ExitLadderViaDismountNode(CFuncLadder *ladder, bool strict, bool useAlternate) +bool CHL2GameMovement::ExitLadderViaDismountNode( CFuncLadder *ladder, bool strict, bool useAlternate ) { // Find the best ladder exit node float bestDot = -99999.0f; @@ -446,52 +531,52 @@ bool CHL2GameMovement::ExitLadderViaDismountNode(CFuncLadder *ladder, bool stric Vector alternateDest; float alternateDist = 99999.0f; - CUtlRBTree< NearbyDismount_t, int > nearbyDismounts(0, 0, NearbyDismountLessFunc); + CUtlRBTree< NearbyDismount_t, int > nearbyDismounts( 0, 0, NearbyDismountLessFunc ); - GetSortedDismountNodeList(mv->GetAbsOrigin(), 100.0f, ladder, nearbyDismounts); + GetSortedDismountNodeList( mv->GetAbsOrigin(), 100.0f, ladder, nearbyDismounts ); int i; - for (i = nearbyDismounts.FirstInorder(); i != nearbyDismounts.InvalidIndex(); i = nearbyDismounts.NextInorder(i)) + for ( i = nearbyDismounts.FirstInorder(); i != nearbyDismounts.InvalidIndex() ; i = nearbyDismounts.NextInorder( i ) ) { - CInfoLadderDismount *spot = nearbyDismounts[i].dismount; - if (!spot) + CInfoLadderDismount *spot = nearbyDismounts[ i ].dismount; + if ( !spot ) { - Assert(!"What happened to the spot!!!"); + Assert( !"What happened to the spot!!!" ); continue; } // See if it's valid to put the player there... - Vector org = spot->GetAbsOrigin() + Vector(0, 0, 1); + Vector org = spot->GetAbsOrigin() + Vector( 0, 0, 1 ); trace_t tr; UTIL_TraceHull( - org, - org, - GetPlayerMins((player->GetFlags() & FL_DUCKING) ? true : false), - GetPlayerMaxs((player->GetFlags() & FL_DUCKING) ? true : false), + org, + org, + GetPlayerMins( ( player->GetFlags() & FL_DUCKING ) ? true : false ), + GetPlayerMaxs( ( player->GetFlags() & FL_DUCKING ) ? true : false ), MASK_PLAYERSOLID, player, COLLISION_GROUP_PLAYER_MOVEMENT, - &tr); + &tr ); // Nope... - if (tr.startsolid) + if ( tr.startsolid ) { continue; } // Find the best dot product - Vector vecToSpot = org - (mv->GetAbsOrigin() + player->GetViewOffset()); + Vector vecToSpot = org - ( mv->GetAbsOrigin() + player->GetViewOffset() ); vecToSpot.z = 0.0f; - float d = VectorNormalize(vecToSpot); + float d = VectorNormalize( vecToSpot ); - float dot = vecToSpot.Dot(m_vecForward); + float dot = vecToSpot.Dot( m_vecForward ); // We're not facing at it...ignore - if (dot < 0.5f) + if ( dot < 0.5f ) { - if (useAlternate && d < alternateDist) + if( useAlternate && d < alternateDist ) { alternateDest = org; alternateDist = d; @@ -501,7 +586,7 @@ bool CHL2GameMovement::ExitLadderViaDismountNode(CFuncLadder *ladder, bool stric continue; } - if (dot > bestDot) + if ( dot > bestDot ) { bestDest = org; bestDistance = d; @@ -510,26 +595,26 @@ bool CHL2GameMovement::ExitLadderViaDismountNode(CFuncLadder *ladder, bool stric } } - if (found) + if ( found ) { // Require a more specific - if (strict && - ((bestDot < 0.7f) || (bestDistance > 40.0f))) + if ( strict && + ( ( bestDot < 0.7f ) || ( bestDistance > 40.0f ) ) ) { return false; } - StartForcedMove(false, player->MaxSpeed(), bestDest, NULL); + StartForcedMove( false, player->MaxSpeed(), bestDest, NULL ); return true; } - if (useAlternate) + if( useAlternate ) { // Desperate. Don't refuse to let a person off of a ladder if it can be helped. Use the // alternate dismount if there is one. - if (foundAlternate && alternateDist <= 60.0f) + if( foundAlternate && alternateDist <= 60.0f ) { - StartForcedMove(false, player->MaxSpeed(), alternateDest, NULL); + StartForcedMove( false, player->MaxSpeed(), alternateDest, NULL ); return true; } } @@ -543,27 +628,21 @@ bool CHL2GameMovement::ExitLadderViaDismountNode(CFuncLadder *ladder, bool stric //----------------------------------------------------------------------------- void CHL2GameMovement::FullLadderMove() { - // MY CODE Old Ladder -#if defined(HL2_DLL) - if (GetLadder() == nullptr) - { - BaseClass::FullLadderMove(); - return; - } -#endif - //////////////////////// #if !defined( CLIENT_DLL ) CFuncLadder *ladder = GetLadder(); - Assert(ladder); - if (!ladder) + Assert( ladder ); + if ( !ladder ) { +#ifdef HL2_USES_FUNC_LADDER_CODE + BaseClass::FullLadderMove(); +#endif return; } CheckWater(); // Was jump button pressed? If so, don't do anything here - if (mv->m_nButtons & IN_JUMP) + if ( mv->m_nButtons & IN_JUMP ) { CheckJumpButton(); return; @@ -573,41 +652,41 @@ void CHL2GameMovement::FullLadderMove() mv->m_nOldButtons &= ~IN_JUMP; } - player->SetGroundEntity(NULL); + player->SetGroundEntity( NULL ); // Remember old positions in case we cancel this movement - Vector oldVelocity = mv->m_vecVelocity; - Vector oldOrigin = mv->GetAbsOrigin(); + Vector oldVelocity = mv->m_vecVelocity; + Vector oldOrigin = mv->GetAbsOrigin(); Vector topPosition; Vector bottomPosition; - ladder->GetTopPosition(topPosition); - ladder->GetBottomPosition(bottomPosition); + ladder->GetTopPosition( topPosition ); + ladder->GetBottomPosition( bottomPosition ); // Compute parametric distance along ladder vector... float oldt; - CalcDistanceSqrToLine(mv->GetAbsOrigin(), topPosition, bottomPosition, &oldt); - + CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &oldt ); + // Perform the move accounting for any base velocity. - VectorAdd(mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); + VectorAdd (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); TryPlayerMove(); - VectorSubtract(mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); + VectorSubtract (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); // Pressed buttons are "changed(xor)" and'ed with the mask of currently held buttons - int buttonsChanged = (mv->m_nOldButtons ^ mv->m_nButtons); // These buttons have changed this frame + int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame int buttonsPressed = buttonsChanged & mv->m_nButtons; - bool pressed_use = (buttonsPressed & IN_USE) ? true : false; + bool pressed_use = ( buttonsPressed & IN_USE ) ? true : false; bool pressing_forward_or_side = mv->m_flForwardMove != 0.0f || mv->m_flSideMove != 0.0f; Vector ladderVec = topPosition - bottomPosition; - float LadderLength = VectorNormalize(ladderVec); + float LadderLength = VectorNormalize( ladderVec ); // This test is not perfect by any means, but should help a bit bool moving_along_ladder = false; - if (pressing_forward_or_side) + if ( pressing_forward_or_side ) { - float fwdDot = m_vecForward.Dot(ladderVec); - if (fabs(fwdDot) > 0.9f) + float fwdDot = m_vecForward.Dot( ladderVec ); + if ( fabs( fwdDot ) > 0.9f ) { moving_along_ladder = true; } @@ -615,18 +694,18 @@ void CHL2GameMovement::FullLadderMove() // Compute parametric distance along ladder vector... float newt; - CalcDistanceSqrToLine(mv->GetAbsOrigin(), topPosition, bottomPosition, &newt); + CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &newt ); // Fudge of 2 units float tolerance = 1.0f / LadderLength; bool wouldleaveladder = false; // Moving pPast top or bottom? - if (newt < -tolerance) + if ( newt < -tolerance ) { wouldleaveladder = newt < oldt; } - else if (newt > (1.0f + tolerance)) + else if ( newt > ( 1.0f + tolerance ) ) { wouldleaveladder = newt > oldt; } @@ -634,30 +713,30 @@ void CHL2GameMovement::FullLadderMove() // See if we are near the top or bottom but not moving float dist1sqr, dist2sqr; - dist1sqr = (topPosition - mv->GetAbsOrigin()).LengthSqr(); - dist2sqr = (bottomPosition - mv->GetAbsOrigin()).LengthSqr(); + dist1sqr = ( topPosition - mv->GetAbsOrigin() ).LengthSqr(); + dist2sqr = ( bottomPosition - mv->GetAbsOrigin() ).LengthSqr(); - float dist = MIN(dist1sqr, dist2sqr); - bool neardismountnode = (dist < 16.0f * 16.0f) ? true : false; - float ladderUnitsPerTick = (MAX_CLIMB_SPEED * gpGlobals->interval_per_tick); - bool neardismountnode2 = (dist < ladderUnitsPerTick * ladderUnitsPerTick) ? true : false; + float dist = MIN( dist1sqr, dist2sqr ); + bool neardismountnode = ( dist < 16.0f * 16.0f ) ? true : false; + float ladderUnitsPerTick = ( MAX_CLIMB_SPEED * gpGlobals->interval_per_tick ); + bool neardismountnode2 = ( dist < ladderUnitsPerTick * ladderUnitsPerTick ) ? true : false; // Really close to node, cvar is set, and pressing a key, then simulate a +USE - bool auto_dismount_use = (neardismountnode2 && - sv_autoladderdismount.GetBool() && - pressing_forward_or_side && - !moving_along_ladder); + bool auto_dismount_use = ( neardismountnode2 && + sv_autoladderdismount.GetBool() && + pressing_forward_or_side && + !moving_along_ladder ); - bool fully_underwater = (player->GetWaterLevel() == WL_Eyes) ? true : false; + bool fully_underwater = ( player->GetWaterLevel() == WL_Eyes ) ? true : false; // If the user manually pressed use or we're simulating it, then use_dismount will occur bool use_dismount = pressed_use || auto_dismount_use; - if (fully_underwater && !use_dismount) + if ( fully_underwater && !use_dismount ) { // If fully underwater, we require looking directly at a dismount node /// to "float off" a ladder mid way... - if (ExitLadderViaDismountNode(ladder, true)) + if ( ExitLadderViaDismountNode( ladder, true ) ) { // See if they +used a dismount point mid-span.. return; @@ -665,96 +744,96 @@ void CHL2GameMovement::FullLadderMove() } // If the movement would leave the ladder and they're not automated or pressing use, disallow the movement - if (!use_dismount) + if ( !use_dismount ) { - if (wouldleaveladder) + if ( wouldleaveladder ) { // Don't let them leave the ladder if they were on it mv->m_vecVelocity = oldVelocity; - mv->SetAbsOrigin(oldOrigin); + mv->SetAbsOrigin( oldOrigin ); } return; } // If the move would not leave the ladder and we're near close to the end, then just accept the move - if (!wouldleaveladder && !neardismountnode) + if ( !wouldleaveladder && !neardismountnode ) { // Otherwise, if the move would leave the ladder, disallow it. - if (pressed_use) + if ( pressed_use ) { - if (ExitLadderViaDismountNode(ladder, false, IsX360())) + if ( ExitLadderViaDismountNode( ladder, false, IsX360() ) ) { // See if they +used a dismount point mid-span.. return; } - player->SetMoveType(MOVETYPE_WALK); - player->SetMoveCollide(MOVECOLLIDE_DEFAULT); - SetLadder(NULL); + player->SetMoveType( MOVETYPE_WALK ); + player->SetMoveCollide( MOVECOLLIDE_DEFAULT ); + SetLadder( NULL ); GetHL2Player()->m_bPlayUseDenySound = false; // Dismount with a bit of velocity in facing direction - VectorScale(m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity); + VectorScale( m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity ); mv->m_vecVelocity.z = 50; } return; } // Debounce the use key - if (pressed_use) + if ( pressed_use ) { SwallowUseKey(); } // Try auto exit, if possible - if (ExitLadderViaDismountNode(ladder, false, pressed_use)) + if ( ExitLadderViaDismountNode( ladder, false, pressed_use ) ) { return; } - if (wouldleaveladder) + if ( wouldleaveladder ) { // Otherwise, if the move would leave the ladder, disallow it. - if (pressed_use) + if ( pressed_use ) { - player->SetMoveType(MOVETYPE_WALK); - player->SetMoveCollide(MOVECOLLIDE_DEFAULT); - SetLadder(NULL); + player->SetMoveType( MOVETYPE_WALK ); + player->SetMoveCollide( MOVECOLLIDE_DEFAULT ); + SetLadder( NULL ); // Dismount with a bit of velocity in facing direction - VectorScale(m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity); + VectorScale( m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity ); mv->m_vecVelocity.z = 50; } else { mv->m_vecVelocity = oldVelocity; - mv->SetAbsOrigin(oldOrigin); + mv->SetAbsOrigin( oldOrigin ); } } #endif } -bool CHL2GameMovement::CheckLadderAutoMountEndPoint(CFuncLadder *ladder, const Vector& bestOrigin) +bool CHL2GameMovement::CheckLadderAutoMountEndPoint( CFuncLadder *ladder, const Vector& bestOrigin ) { // See if we're really near an endpoint - if (!ladder) + if ( !ladder ) return false; Vector top, bottom; - ladder->GetTopPosition(top); - ladder->GetBottomPosition(bottom); + ladder->GetTopPosition( top ); + ladder->GetBottomPosition( bottom ); float d1, d2; - d1 = (top - mv->GetAbsOrigin()).LengthSqr(); - d2 = (bottom - mv->GetAbsOrigin()).LengthSqr(); + d1 = ( top - mv->GetAbsOrigin() ).LengthSqr(); + d2 = ( bottom - mv->GetAbsOrigin() ).LengthSqr(); - if (d1 > 16 * 16 && d2 > 16 * 16) + if ( d1 > 16 * 16 && d2 > 16 * 16 ) return false; Vector ladderAxis; - if (d1 < 16 * 16) + if ( d1 < 16 * 16 ) { // Close to top ladderAxis = bottom - top; @@ -764,73 +843,73 @@ bool CHL2GameMovement::CheckLadderAutoMountEndPoint(CFuncLadder *ladder, const V ladderAxis = top - bottom; } - VectorNormalize(ladderAxis); + VectorNormalize( ladderAxis ); - if (ladderAxis.Dot(m_vecForward) > sv_ladderautomountdot.GetFloat()) + if ( ladderAxis.Dot( m_vecForward ) > sv_ladderautomountdot.GetFloat() ) { - StartForcedMove(true, player->MaxSpeed(), bestOrigin, ladder); + StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder ); return true; } return false; } -bool CHL2GameMovement::CheckLadderAutoMountCone(CFuncLadder *ladder, const Vector& bestOrigin, float maxAngleDelta, float maxDistToLadder) +bool CHL2GameMovement::CheckLadderAutoMountCone( CFuncLadder *ladder, const Vector& bestOrigin, float maxAngleDelta, float maxDistToLadder ) { // Never 'back' onto ladders or stafe onto ladders - if (ladder != NULL && - (mv->m_flForwardMove > 0.0f)) + if ( ladder != NULL && + ( mv->m_flForwardMove > 0.0f ) ) { Vector top, bottom; - ladder->GetTopPosition(top); - ladder->GetBottomPosition(bottom); + ladder->GetTopPosition( top ); + ladder->GetBottomPosition( bottom ); Vector ladderAxis = top - bottom; - VectorNormalize(ladderAxis); + VectorNormalize( ladderAxis ); Vector probe = mv->GetAbsOrigin(); Vector closest; - CalcClosestPointOnLineSegment(probe, bottom, top, closest, NULL); + CalcClosestPointOnLineSegment( probe, bottom, top, closest, NULL ); Vector vecToLadder = closest - probe; - float dist = VectorNormalize(vecToLadder); + float dist = VectorNormalize( vecToLadder ); Vector flatLadder = vecToLadder; flatLadder.z = 0.0f; Vector flatForward = m_vecForward; flatForward.z = 0.0f; - VectorNormalize(flatLadder); - VectorNormalize(flatForward); + VectorNormalize( flatLadder ); + VectorNormalize( flatForward ); - float facingDot = flatForward.Dot(flatLadder); - float angle = acos(facingDot) * 180 / M_PI; + float facingDot = flatForward.Dot( flatLadder ); + float angle = acos( facingDot ) * 180 / M_PI; - bool closetoladder = (dist != 0.0f && dist < maxDistToLadder) ? true : false; - bool reallyclosetoladder = (dist != 0.0f && dist < 4.0f) ? true : false; + bool closetoladder = ( dist != 0.0f && dist < maxDistToLadder ) ? true : false; + bool reallyclosetoladder = ( dist != 0.0f && dist < 4.0f ) ? true : false; - bool facingladderaxis = (angle < maxAngleDelta) ? true : false; - bool facingalongaxis = ((float)fabs(ladderAxis.Dot(m_vecForward)) > sv_ladderautomountdot.GetFloat()) ? true : false; + bool facingladderaxis = ( angle < maxAngleDelta ) ? true : false; + bool facingalongaxis = ( (float)fabs( ladderAxis.Dot( m_vecForward ) ) > sv_ladderautomountdot.GetFloat() ) ? true : false; #if 0 - Msg("close %i length %.3f maxdist %.3f facing %.3f dot %.3f ang %.3f\n", + Msg( "close %i length %.3f maxdist %.3f facing %.3f dot %.3f ang %.3f\n", closetoladder ? 1 : 0, dist, maxDistToLadder, - (float)fabs(ladderAxis.Dot(m_vecForward)), - facingDot, + (float)fabs( ladderAxis.Dot( m_vecForward ) ), + facingDot, angle); #endif // Tracker 21776: Don't mount ladders this way if strafing - bool strafing = (fabs(mv->m_flSideMove) < 1.0f) ? false : true; + bool strafing = ( fabs( mv->m_flSideMove ) < 1.0f ) ? false : true; - if (((facingDot > 0.0f && !strafing) || facingalongaxis) && - (facingladderaxis || reallyclosetoladder) && - closetoladder) + if ( ( ( facingDot > 0.0f && !strafing ) || facingalongaxis ) && + ( facingladderaxis || reallyclosetoladder ) && + closetoladder ) { - StartForcedMove(true, player->MaxSpeed(), bestOrigin, ladder); + StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder ); return true; } } @@ -843,21 +922,21 @@ bool CHL2GameMovement::CheckLadderAutoMountCone(CFuncLadder *ladder, const Vecto // Input : *ladder - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- -bool CHL2GameMovement::LookingAtLadder(CFuncLadder *ladder) +bool CHL2GameMovement::LookingAtLadder( CFuncLadder *ladder ) { - if (!ladder) + if ( !ladder ) { return false; } // Get ladder end points Vector top, bottom; - ladder->GetTopPosition(top); - ladder->GetBottomPosition(bottom); + ladder->GetTopPosition( top ); + ladder->GetBottomPosition( bottom ); // Find closest point on ladder to player (could be an endpoint) Vector closest; - CalcClosestPointOnLineSegment(mv->GetAbsOrigin(), bottom, top, closest, NULL); + CalcClosestPointOnLineSegment( mv->GetAbsOrigin(), bottom, top, closest, NULL ); // Flatten our view direction to 2D Vector flatForward = m_vecForward; @@ -876,16 +955,16 @@ bool CHL2GameMovement::LookingAtLadder(CFuncLadder *ladder) flatLadder.z = 0.0f; // Normalize the vectors (unnecessary) - VectorNormalize(flatLadder); - VectorNormalize(flatForward); + VectorNormalize( flatLadder ); + VectorNormalize( flatForward ); // Compute dot product to see if forward is in same direction as vec to ladder - float facingDot = flatForward.Dot(flatLadder); + float facingDot = flatForward.Dot( flatLadder ); - float requiredDot = (sv_ladder_useonly.GetBool()) ? -0.99 : 0.0; + float requiredDot = ( sv_ladder_useonly.GetBool() ) ? -0.99 : 0.0; // Facing same direction if dot > = requiredDot... - bool facingladder = (facingDot >= requiredDot); + bool facingladder = ( facingDot >= requiredDot ); return facingladder; } @@ -894,13 +973,13 @@ bool CHL2GameMovement::LookingAtLadder(CFuncLadder *ladder) // Purpose: // Input : &trace - //----------------------------------------------------------------------------- -bool CHL2GameMovement::CheckLadderAutoMount(CFuncLadder *ladder, const Vector& bestOrigin) +bool CHL2GameMovement::CheckLadderAutoMount( CFuncLadder *ladder, const Vector& bestOrigin ) { #if !defined( CLIENT_DLL ) - if (ladder != NULL) + if ( ladder != NULL ) { - StartForcedMove(true, player->MaxSpeed(), bestOrigin, ladder); + StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder ); return true; } @@ -911,236 +990,221 @@ bool CHL2GameMovement::CheckLadderAutoMount(CFuncLadder *ladder, const Vector& b //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CHL2GameMovement::LadderMove(void) +bool CHL2GameMovement::LadderMove( void ) { - if (player->GetMoveType() == MOVETYPE_NOCLIP) + if ( player->GetMoveType() == MOVETYPE_NOCLIP ) { - SetLadder(NULL); - //return false; - // MY CODE Old Ladder -#if defined(HL2_DLL) + SetLadder( NULL ); +#ifdef HL2_USES_FUNC_LADDER_CODE return BaseClass::LadderMove(); #else return false; #endif - ///////////////// } // If being forced to mount/dismount continue to act like we are on the ladder - if (IsForceMoveActive() && ContinueForcedMove()) + if ( IsForceMoveActive() && ContinueForcedMove() ) { return true; } CFuncLadder *bestLadder = NULL; - Vector bestOrigin(0, 0, 0); + Vector bestOrigin( 0, 0, 0 ); CFuncLadder *ladder = GetLadder(); // Something 1) deactivated the ladder... or 2) something external applied // a force to us. In either case make the player fall, etc. - if (ladder && - (!ladder->IsEnabled() || - (player->GetBaseVelocity().LengthSqr() > 1.0f))) + if ( ladder && + ( !ladder->IsEnabled() || + ( player->GetBaseVelocity().LengthSqr() > 1.0f ) ) ) { GetHL2Player()->ExitLadder(); ladder = NULL; } - if (!ladder) + if ( !ladder ) { - Findladder(64.0f, &bestLadder, bestOrigin, NULL); + Findladder( 64.0f, &bestLadder, bestOrigin, NULL ); } #if !defined (CLIENT_DLL) - if (!ladder && bestLadder && sv_ladder_useonly.GetBool()) + if( !ladder && bestLadder && sv_ladder_useonly.GetBool() ) { GetHL2Player()->DisplayLadderHudHint(); } #endif - int buttonsChanged = (mv->m_nOldButtons ^ mv->m_nButtons); // These buttons have changed this frame + int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame int buttonsPressed = buttonsChanged & mv->m_nButtons; - bool pressed_use = (buttonsPressed & IN_USE) ? true : false; + bool pressed_use = ( buttonsPressed & IN_USE ) ? true : false; // If I'm already moving on a ladder, use the previous ladder direction - if (!ladder && !pressed_use) + if ( !ladder && !pressed_use ) { // If flying through air, allow mounting ladders if we are facing < 15 degress from the ladder and we are close - if (!ladder && !sv_ladder_useonly.GetBool()) + if ( !ladder && !sv_ladder_useonly.GetBool() ) { // Tracker 6625: Don't need to be leaping to auto mount using this method... // But if we are on the ground, then we must not be backing into the ladder (Tracker 12961) bool onground = player->GetGroundEntity() ? true : false; - if (!onground || (mv->m_flForwardMove > 0.0f)) + if ( !onground || ( mv->m_flForwardMove > 0.0f ) ) { - if (CheckLadderAutoMountCone(bestLadder, bestOrigin, 15.0f, 32.0f)) + if ( CheckLadderAutoMountCone( bestLadder, bestOrigin, 15.0f, 32.0f ) ) { return true; } } - + // Pressing forward while looking at ladder and standing (or floating) near a mounting point - if (mv->m_flForwardMove > 0.0f) + if ( mv->m_flForwardMove > 0.0f ) { - if (CheckLadderAutoMountEndPoint(bestLadder, bestOrigin)) + if ( CheckLadderAutoMountEndPoint( bestLadder, bestOrigin ) ) { return true; } } } - //return false; - // MY CODE Old Ladder -#if defined(HL2_DLL) +#ifdef HL2_USES_FUNC_LADDER_CODE return BaseClass::LadderMove(); #else return false; #endif - //////////////// } - if (!ladder && - LookingAtLadder(bestLadder) && - CheckLadderAutoMount(bestLadder, bestOrigin)) + if ( !ladder && + LookingAtLadder( bestLadder ) && + CheckLadderAutoMount( bestLadder, bestOrigin ) ) { return true; } // Reassign the ladder ladder = GetLadder(); - if (!ladder) + if ( !ladder ) { - //return false; - // MY CODE Old Ladder -#if defined(HL2_DLL) +#ifdef HL2_USES_FUNC_LADDER_CODE return BaseClass::LadderMove(); #else return false; #endif - //////////////// } // Don't play the deny sound - if (pressed_use) + if ( pressed_use ) { GetHL2Player()->m_bPlayUseDenySound = false; } // Make sure we are on the ladder - player->SetMoveType(MOVETYPE_LADDER); - player->SetMoveCollide(MOVECOLLIDE_DEFAULT); - - player->SetGravity(0.0f); + player->SetMoveType( MOVETYPE_LADDER ); + player->SetMoveCollide( MOVECOLLIDE_DEFAULT ); + player->SetGravity( 0.0f ); + float forwardSpeed = 0.0f; float rightSpeed = 0.0f; float speed = player->MaxSpeed(); - if (mv->m_nButtons & IN_BACK) + if ( mv->m_nButtons & IN_BACK ) { forwardSpeed -= speed; } - - if (mv->m_nButtons & IN_FORWARD) + + if ( mv->m_nButtons & IN_FORWARD ) { forwardSpeed += speed; } - - if (mv->m_nButtons & IN_MOVELEFT) + + if ( mv->m_nButtons & IN_MOVELEFT ) { rightSpeed -= speed; } - - if (mv->m_nButtons & IN_MOVERIGHT) + + if ( mv->m_nButtons & IN_MOVERIGHT ) { rightSpeed += speed; } - - if (mv->m_nButtons & IN_JUMP) + + if ( mv->m_nButtons & IN_JUMP ) { - player->SetMoveType(MOVETYPE_WALK); + player->SetMoveType( MOVETYPE_WALK ); // Remove from ladder - SetLadder(NULL); + SetLadder( NULL ); // Jump in view direction Vector jumpDir = m_vecForward; // unless pressing backward or something like that - if (mv->m_flForwardMove < 0.0f) + if ( mv->m_flForwardMove < 0.0f ) { jumpDir = -jumpDir; } - VectorNormalize(jumpDir); + VectorNormalize( jumpDir ); - VectorScale(jumpDir, MAX_CLIMB_SPEED, mv->m_vecVelocity); + VectorScale( jumpDir, MAX_CLIMB_SPEED, mv->m_vecVelocity ); // Tracker 13558: Don't add any extra z velocity if facing downward at all - if (m_vecForward.z >= 0.0f) + if ( m_vecForward.z >= 0.0f ) { mv->m_vecVelocity.z = mv->m_vecVelocity.z + 50; } - //return false; - // MY CODE Old Ladder -#if defined(HL2_DLL) +#ifdef HL2_USES_FUNC_LADDER_CODE return BaseClass::LadderMove(); #else return false; #endif - //////////////// } - if (forwardSpeed != 0 || rightSpeed != 0) + if ( forwardSpeed != 0 || rightSpeed != 0 ) { // See if the player is looking toward the top or the bottom Vector velocity; - VectorScale(m_vecForward, forwardSpeed, velocity); - VectorMA(velocity, rightSpeed, m_vecRight, velocity); + VectorScale( m_vecForward, forwardSpeed, velocity ); + VectorMA( velocity, rightSpeed, m_vecRight, velocity ); - VectorNormalize(velocity); + VectorNormalize( velocity ); Vector ladderUp; - ladder->ComputeLadderDir(ladderUp); - VectorNormalize(ladderUp); + ladder->ComputeLadderDir( ladderUp ); + VectorNormalize( ladderUp ); Vector topPosition; Vector bottomPosition; - ladder->GetTopPosition(topPosition); - ladder->GetBottomPosition(bottomPosition); + ladder->GetTopPosition( topPosition ); + ladder->GetBottomPosition( bottomPosition ); // Check to see if we've mounted the ladder in a bogus spot and, if so, just fall off the ladder... float dummyt = 0.0f; - float distFromLadderSqr = CalcDistanceSqrToLine(mv->GetAbsOrigin(), topPosition, bottomPosition, &dummyt); - if (distFromLadderSqr > 36.0f) + float distFromLadderSqr = CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &dummyt ); + if ( distFromLadderSqr > 36.0f ) { // Uh oh, we fell off zee ladder... - player->SetMoveType(MOVETYPE_WALK); + player->SetMoveType( MOVETYPE_WALK ); // Remove from ladder - SetLadder(NULL); - //return false; - // MY CODE Old Ladder -#if defined(HL2_DLL) + SetLadder( NULL ); +#ifdef HL2_USES_FUNC_LADDER_CODE return BaseClass::LadderMove(); #else return false; #endif - /////////////// } - bool ishorizontal = fabs(topPosition.z - bottomPosition.z) < 64.0f ? true : false; + bool ishorizontal = fabs( topPosition.z - bottomPosition.z ) < 64.0f ? true : false; float changeover = ishorizontal ? 0.0f : 0.3f; float factor = 1.0f; - if (velocity.z >= 0) + if ( velocity.z >= 0 ) { - float dotTop = ladderUp.Dot(velocity); - if (dotTop < -changeover) + float dotTop = ladderUp.Dot( velocity ); + if ( dotTop < -changeover ) { // Aimed at bottom factor = -1.0f; @@ -1148,22 +1212,22 @@ bool CHL2GameMovement::LadderMove(void) } else { - float dotBottom = -ladderUp.Dot(velocity); - if (dotBottom > changeover) + float dotBottom = -ladderUp.Dot( velocity ); + if ( dotBottom > changeover ) { factor = -1.0f; } } #ifdef _XBOX - if (sv_ladders_useonly.GetBool()) + if( sv_ladders_useonly.GetBool() ) { // Stick up climbs up, stick down climbs down. No matter which way you're looking. - if (mv->m_nButtons & IN_FORWARD) + if ( mv->m_nButtons & IN_FORWARD ) { factor = 1.0f; } - else if (mv->m_nButtons & IN_BACK) + else if( mv->m_nButtons & IN_BACK ) { factor = -1.0f; } @@ -1180,23 +1244,23 @@ bool CHL2GameMovement::LadderMove(void) return true; } -void CHL2GameMovement::SetGroundEntity(trace_t *pm) +void CHL2GameMovement::SetGroundEntity( trace_t *pm ) { CBaseEntity *newGround = pm ? pm->m_pEnt : NULL; //Adrian: Special case for combine balls. - if (newGround && newGround->GetCollisionGroup() == HL2COLLISION_GROUP_COMBINE_BALL_NPC) + if ( newGround && newGround->GetCollisionGroup() == HL2COLLISION_GROUP_COMBINE_BALL_NPC ) { return; } - BaseClass::SetGroundEntity(pm); + BaseClass::SetGroundEntity( pm ); } bool CHL2GameMovement::CanAccelerate() { #ifdef HL2MP - if (player->IsObserver()) + if ( player->IsObserver() ) { return true; } @@ -1207,11 +1271,34 @@ bool CHL2GameMovement::CanAccelerate() return true; } +//----------------------------------------------------------------------------- +// Purpose: Allow bots etc to use slightly different solid masks +//----------------------------------------------------------------------------- +unsigned int CHL2GameMovement::PlayerSolidMask( bool brushOnly ) +{ + int mask = 0; +#ifdef HL2MP + if ( HL2MPRules()->IsTeamplay() ) + { + switch ( player->GetTeamNumber() ) + { + case TEAM_REBELS: + mask = CONTENTS_TEAM1; + break; + + case TEAM_COMBINE: + mask = CONTENTS_TEAM2; + break; + } + } +#endif + return ( mask | BaseClass::PlayerSolidMask( brushOnly ) ); +} #ifndef PORTAL // Portal inherits from this but needs to declare it's own global interface -// Expose our interface. -static CHL2GameMovement g_GameMovement; -IGameMovement *g_pGameMovement = (IGameMovement *)&g_GameMovement; + // Expose our interface. + static CHL2GameMovement g_GameMovement; + IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement; -EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameMovement, IGameMovement, INTERFACENAME_GAMEMOVEMENT, g_GameMovement); + EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameMovement, IGameMovement,INTERFACENAME_GAMEMOVEMENT, g_GameMovement ); #endif \ No newline at end of file diff --git a/game/shared/hl2/hl_gamemovement.h b/game/shared/hl2/hl_gamemovement.h index 1e9abefe..fba5c8c1 100644 --- a/game/shared/hl2/hl_gamemovement.h +++ b/game/shared/hl2/hl_gamemovement.h @@ -44,6 +44,15 @@ class CHL2GameMovement : public CGameMovement virtual void SetGroundEntity( trace_t *pm ); virtual bool CanAccelerate( void ); + virtual unsigned int PlayerSolidMask( bool brushOnly = false ); + +#ifdef MAPBASE + // Called by mappers who need a player to be on a ladder. + bool ForcePlayerOntoLadder(CFuncLadder *ladder); + // Called by mappers who want a player to be on a ladder. + bool MountPlayerOntoLadder(CFuncLadder *ladder); +#endif + private: // See if we are pressing use near a ladder "mount" point and if so, latch us onto the ladder diff --git a/game/shared/hl2mp/weapon_crowbar.h b/game/shared/hl2mp/weapon_crowbar.h index d7ca42ac..2cd10fb9 100644 --- a/game/shared/hl2mp/weapon_crowbar.h +++ b/game/shared/hl2mp/weapon_crowbar.h @@ -18,7 +18,6 @@ #include "weapon_hl2mpbasehlmpcombatweapon.h" #include "weapon_hl2mpbasebasebludgeon.h" -#include "vance_bludgeonweapon.h" #ifdef CLIENT_DLL diff --git a/game/shared/hl2mp/weapon_slam.cpp b/game/shared/hl2mp/weapon_slam.cpp index bcdec40c..c4eb7140 100644 --- a/game/shared/hl2mp/weapon_slam.cpp +++ b/game/shared/hl2mp/weapon_slam.cpp @@ -11,9 +11,17 @@ #include "engine/IEngineSound.h" #if defined( CLIENT_DLL ) +#ifdef HL2MP #include "c_hl2mp_player.h" #else + #include "hl2_player_shared.h" +#endif +#else +#ifdef HL2MP #include "hl2mp_player.h" +#else + #include "hl2_player.h" +#endif #include "grenade_tripmine.h" #include "grenade_satchel.h" #include "entitylist.h" @@ -25,6 +33,11 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#ifndef HL2MP +#define ToHL2MPPlayer(ent) dynamic_cast(ent) +#define CHL2MP_Player CHL2_Player +#endif + #define SLAM_PRIMARY_VOLUME 450 IMPLEMENT_NETWORKCLASS_ALIASED( Weapon_SLAM, DT_Weapon_SLAM ) @@ -102,6 +115,10 @@ acttable_t CWeapon_SLAM::m_acttable[] = { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false }, { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SLAM, false }, { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SLAM, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_SLAM, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM, false }, +#endif }; IMPLEMENT_ACTTABLE(CWeapon_SLAM); @@ -114,7 +131,9 @@ void CWeapon_SLAM::Spawn( ) Precache( ); +#if defined(HL2MP) || !defined(CLIENT_DLL) FallInit();// get ready to fall down +#endif m_tSlamState = (int)SLAM_SATCHEL_THROW; m_flWallSwitchTime = 0; @@ -755,6 +774,14 @@ void CWeapon_SLAM::ItemPostFrame( void ) SLAMThink(); +#ifdef MAPBASE + if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING )) + { + WeaponIdle(); + return; + } +#endif + if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) { SecondaryAttack(); diff --git a/game/shared/hl2mp/weapon_slam.h b/game/shared/hl2mp/weapon_slam.h index 0b59bed7..51a48155 100644 --- a/game/shared/hl2mp/weapon_slam.h +++ b/game/shared/hl2mp/weapon_slam.h @@ -15,7 +15,11 @@ #define WEAPONSLAM_H #include "basegrenade_shared.h" +#ifdef HL2MP #include "weapon_hl2mpbasehlmpcombatweapon.h" +#else +#include "basehlcombatweapon_shared.h" +#endif enum { @@ -28,6 +32,10 @@ enum #define CWeapon_SLAM C_Weapon_SLAM #endif +#ifndef HL2MP +#define CBaseHL2MPCombatWeapon CBaseHLCombatWeapon +#endif + class CWeapon_SLAM : public CBaseHL2MPCombatWeapon { public: diff --git a/game/shared/hl2mp/weapon_stunstick.cpp b/game/shared/hl2mp/weapon_stunstick.cpp index 9f706983..1d6ae161 100644 --- a/game/shared/hl2mp/weapon_stunstick.cpp +++ b/game/shared/hl2mp/weapon_stunstick.cpp @@ -7,7 +7,10 @@ #include "cbase.h" #include "npcevent.h" +#include "weapon_stunstick.h" +#ifdef HL2MP #include "weapon_hl2mpbasebasebludgeon.h" +#endif #include "IEffects.h" #include "debugoverlay_shared.h" @@ -26,7 +29,7 @@ #include "fx_quad.h" #include "fx.h" - extern void DrawHalo( IMaterial* pMaterial, const Vector &source, float scale, float const *color, float flHDRColorScale ); + extern void DrawHalo( IMaterial* pMaterial, const Vector &source, float scale, float const *color, float flHDRColorScale = 1.0f ); extern void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ); #endif @@ -36,98 +39,11 @@ extern ConVar metropolice_move_and_melee; -#define STUNSTICK_RANGE 75.0f -#define STUNSTICK_REFIRE 0.8f -#define STUNSTICK_BEAM_MATERIAL "sprites/lgtning.vmt" -#define STUNSTICK_GLOW_MATERIAL "sprites/light_glow02_add" -#define STUNSTICK_GLOW_MATERIAL2 "effects/blueflare1" -#define STUNSTICK_GLOW_MATERIAL_NOZ "sprites/light_glow02_add_noz" - -#ifdef CLIENT_DLL -#define CWeaponStunStick C_WeaponStunStick -#endif - -class CWeaponStunStick : public CBaseHL2MPBludgeonWeapon -{ - DECLARE_CLASS( CWeaponStunStick, CBaseHL2MPBludgeonWeapon ); - -public: - - CWeaponStunStick(); - - DECLARE_NETWORKCLASS(); - DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL - DECLARE_ACTTABLE(); +#ifdef MAPBASE +ConVar sk_plr_dmg_stunstick ( "sk_plr_dmg_stunstick","0"); +ConVar sk_npc_dmg_stunstick ( "sk_npc_dmg_stunstick","0"); #endif -#ifdef CLIENT_DLL - virtual int DrawModel( int flags ); - virtual void ClientThink( void ); - virtual void OnDataChanged( DataUpdateType_t updateType ); - virtual RenderGroup_t GetRenderGroup( void ); - virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel ); - -#endif - - virtual void Precache(); - - void Spawn(); - - float GetRange( void ) { return STUNSTICK_RANGE; } - float GetFireRate( void ) { return STUNSTICK_REFIRE; } - - - bool Deploy( void ); - bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); - - void Drop( const Vector &vecVelocity ); - void ImpactEffect( trace_t &traceHit ); - void SecondaryAttack( void ) {} - void SetStunState( bool state ); - bool GetStunState( void ); - -#ifndef CLIENT_DLL - void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); - int WeaponMeleeAttack1Condition( float flDot, float flDist ); -#endif - - float GetDamageForActivity( Activity hitActivity ); - - CWeaponStunStick( const CWeaponStunStick & ); - -private: - -#ifdef CLIENT_DLL - - #define NUM_BEAM_ATTACHMENTS 9 - - struct stunstickBeamInfo_t - { - int IDs[2]; // 0 - top, 1 - bottom - }; - - stunstickBeamInfo_t m_BeamAttachments[NUM_BEAM_ATTACHMENTS]; // Lookup for arc attachment points on the head of the stick - int m_BeamCenterAttachment; // "Core" of the effect (center of the head) - - void SetupAttachmentPoints( void ); - void DrawFirstPersonEffects( void ); - void DrawThirdPersonEffects( void ); - void DrawEffects( void ); - bool InSwing( void ); - - bool m_bSwungLastFrame; - - #define FADE_DURATION 0.25f - - float m_flFadeTime; - -#endif - - CNetworkVar( bool, m_bActive ); -}; - //----------------------------------------------------------------------------- // CWeaponStunStick //----------------------------------------------------------------------------- @@ -153,6 +69,7 @@ PRECACHE_WEAPON_REGISTER( weapon_stunstick ); acttable_t CWeaponStunStick::m_acttable[] = { +#ifdef HL2MP { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, @@ -161,6 +78,30 @@ acttable_t CWeaponStunStick::m_acttable[] = { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, +#endif + { ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK_SWING, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, true }, +#if EXPANDED_HL2_WEAPON_ACTIVITIES + { ACT_IDLE, ACT_IDLE_MELEE, false }, + { ACT_RUN, ACT_RUN_MELEE, false }, + { ACT_WALK, ACT_WALK_MELEE, false }, +#endif + +#ifdef MAPBASE + // HL2:DM activities (for third-person animations in SP) + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, +#if EXPANDED_HL2DM_ACTIVITIES + { ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE, false }, + { ACT_HL2MP_WALK, ACT_HL2MP_WALK_MELEE, false }, +#endif +#endif }; IMPLEMENT_ACTTABLE(CWeaponStunStick); @@ -213,7 +154,14 @@ void CWeaponStunStick::Precache() //----------------------------------------------------------------------------- float CWeaponStunStick::GetDamageForActivity( Activity hitActivity ) { +#ifdef MAPBASE + if ( ( GetOwner() != NULL ) && ( GetOwner()->IsPlayer() ) ) + return sk_plr_dmg_stunstick.GetFloat(); + + return sk_npc_dmg_stunstick.GetFloat(); +#else return 40.0f; +#endif } //----------------------------------------------------------------------------- @@ -358,6 +306,35 @@ void CWeaponStunStick::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseComba CBasePlayer *pPlayer = ToBasePlayer( pHurt ); bool bFlashed = false; + +#ifdef MAPBASE + CNPC_MetroPolice *pCop = dynamic_cast(pOperator); + + if ( pCop != NULL && pPlayer != NULL ) + { + // See if we need to knock out this target + if ( pCop->ShouldKnockOutTarget( pHurt ) ) + { + float yawKick = random->RandomFloat( -48, -24 ); + + //Kick the player angles + pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) ); + + color32 white = {255,255,255,255}; + UTIL_ScreenFade( pPlayer, white, 0.2f, 1.0f, FFADE_OUT|FFADE_PURGE|FFADE_STAYOUT ); + bFlashed = true; + + pCop->KnockOutTarget( pHurt ); + + break; + } + else + { + // Notify that we've stunned a target + pCop->StunnedTarget( pHurt ); + } + } +#endif // Punch angles if ( pPlayer != NULL && !(pPlayer->GetFlags() & FL_GODMODE) ) @@ -474,8 +451,19 @@ void CWeaponStunStick::Drop( const Vector &vecVelocity ) SetStunState( false ); #ifndef CLIENT_DLL +#ifdef MAPBASE +#ifdef HL2MP + if (!GetOwner() || GetOwner()->IsNPC()) + BaseClass::Drop(vecVelocity); + else + UTIL_Remove( this ); +#else + BaseClass::Drop(vecVelocity); +#endif +#else UTIL_Remove( this ); #endif +#endif } @@ -566,7 +554,11 @@ int C_WeaponStunStick::DrawModel( int flags ) return 0; // Only render these on the transparent pass +#ifdef MAPBASE + if ( m_bActive && flags & STUDIO_TRANSPARENCY ) +#else if ( flags & STUDIO_TRANSPARENCY ) +#endif { DrawEffects(); return 1; @@ -842,6 +834,40 @@ void C_WeaponStunStick::DrawFirstPersonEffects( void ) } } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Draw our special effects +//----------------------------------------------------------------------------- +void C_WeaponStunStick::DrawNPCEffects( void ) +{ + if ( m_bActive ) + { + Vector vecOrigin; + QAngle vecAngles; + float color[3]; + + color[0] = color[1] = color[2] = random->RandomFloat( 0.1f, 0.2f ); + + GetAttachment( 1, vecOrigin, vecAngles ); + + Vector vForward; + AngleVectors( vecAngles, &vForward ); + + Vector vEnd = vecOrigin - vForward * 1.0f; + + IMaterial *pMaterial = materials->FindMaterial( "effects/stunstick", NULL, false ); + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( pMaterial ); + DrawHalo( pMaterial, vEnd, random->RandomFloat( 4.0f, 6.0f ), color ); + + color[0] = color[1] = color[2] = random->RandomFloat( 0.9f, 1.0f ); + + DrawHalo( pMaterial, vEnd, random->RandomFloat( 2.0f, 3.0f ), color ); + } +} +#endif + //----------------------------------------------------------------------------- // Purpose: Draw our special effects //----------------------------------------------------------------------------- @@ -851,6 +877,13 @@ void C_WeaponStunStick::DrawEffects( void ) { DrawFirstPersonEffects(); } +#ifdef MAPBASE + else if ( GetOwner() && GetOwner()->IsNPC() ) + { + // Original HL2 stunstick FX + DrawNPCEffects(); + } +#endif else { DrawThirdPersonEffects(); diff --git a/game/shared/hl2mp/weapon_stunstick.h b/game/shared/hl2mp/weapon_stunstick.h new file mode 100644 index 00000000..93688915 --- /dev/null +++ b/game/shared/hl2mp/weapon_stunstick.h @@ -0,0 +1,128 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This is technically a Mapbase addition, but it's just weapon_stunstick's class declaration. +// All actual changes are still nested in #ifdef MAPBASE. +// +//=============================================================================// + +#ifndef WEAPON_STUNSTICK_H +#define WEAPON_STUNSTICK_H +#ifdef _WIN32 +#pragma once +#endif + +#ifdef CLIENT_DLL +#include "c_basehlcombatweapon.h" +#else +#include "basebludgeonweapon.h" +#endif + +#define STUNSTICK_RANGE 75.0f +#define STUNSTICK_REFIRE 0.8f +#define STUNSTICK_BEAM_MATERIAL "sprites/lgtning.vmt" +#define STUNSTICK_GLOW_MATERIAL "sprites/light_glow02_add" +#define STUNSTICK_GLOW_MATERIAL2 "effects/blueflare1" +#define STUNSTICK_GLOW_MATERIAL_NOZ "sprites/light_glow02_add_noz" + +#ifdef CLIENT_DLL +#define CWeaponStunStick C_WeaponStunStick +#define CBaseHLBludgeonWeapon C_BaseHLBludgeonWeapon +#endif + +#ifndef HL2MP +class CWeaponStunStick : public CBaseHLBludgeonWeapon +{ + DECLARE_CLASS( CWeaponStunStick, CBaseHLBludgeonWeapon ); +#else +class CWeaponStunStick : public CBaseHL2MPBludgeonWeapon +{ + DECLARE_CLASS( CWeaponStunStick, CBaseHL2MPBludgeonWeapon ); +#endif + +public: + + CWeaponStunStick(); + + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif + +#ifdef CLIENT_DLL + virtual int DrawModel( int flags ); + virtual void ClientThink( void ); + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual RenderGroup_t GetRenderGroup( void ); + virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel ); + +#endif + + virtual void Precache(); + + void Spawn(); + + float GetRange( void ) { return STUNSTICK_RANGE; } + float GetFireRate( void ) { return STUNSTICK_REFIRE; } + + + bool Deploy( void ); + bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); + + void Drop( const Vector &vecVelocity ); + void ImpactEffect( trace_t &traceHit ); + void SecondaryAttack( void ) {} + void SetStunState( bool state ); + bool GetStunState( void ); + +#ifndef CLIENT_DLL + void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); + int WeaponMeleeAttack1Condition( float flDot, float flDist ); +#endif + + float GetDamageForActivity( Activity hitActivity ); + +#ifdef MAPBASE + // Don't use backup activities + acttable_t *GetBackupActivityList() { return NULL; } + int GetBackupActivityListCount() { return 0; } +#endif + + CWeaponStunStick( const CWeaponStunStick & ); + +private: + +#ifdef CLIENT_DLL + + #define NUM_BEAM_ATTACHMENTS 9 + + struct stunstickBeamInfo_t + { + int IDs[2]; // 0 - top, 1 - bottom + }; + + stunstickBeamInfo_t m_BeamAttachments[NUM_BEAM_ATTACHMENTS]; // Lookup for arc attachment points on the head of the stick + int m_BeamCenterAttachment; // "Core" of the effect (center of the head) + + void SetupAttachmentPoints( void ); + void DrawFirstPersonEffects( void ); + void DrawThirdPersonEffects( void ); +#ifdef MAPBASE + void DrawNPCEffects( void ); +#endif + void DrawEffects( void ); + bool InSwing( void ); + + bool m_bSwungLastFrame; + + #define FADE_DURATION 0.25f + + float m_flFadeTime; + +#endif + + CNetworkVar( bool, m_bActive ); +}; + +#endif // WEAPON_STUNSTICK_H diff --git a/game/shared/igamesystem.cpp b/game/shared/igamesystem.cpp index 6a4d7f4f..19cbc78c 100644 --- a/game/shared/igamesystem.cpp +++ b/game/shared/igamesystem.cpp @@ -344,6 +344,15 @@ void IGameSystem::PreClientUpdateAllSystems() #endif +#ifdef MAPBASE_VSCRIPT + +void IGameSystem::RegisterVScriptAllSystems() +{ + InvokeMethod( &IGameSystem::RegisterVScript ); +} + +#endif + //----------------------------------------------------------------------------- // Invokes a method on all installed game systems in proper order diff --git a/game/shared/igamesystem.h b/game/shared/igamesystem.h index 6dc98350..85621924 100644 --- a/game/shared/igamesystem.h +++ b/game/shared/igamesystem.h @@ -98,6 +98,13 @@ abstract_class IGameSystem static CBasePlayer *RunCommandPlayer(); static CUserCmd *RunCommandUserCmd(); #endif + +#ifdef MAPBASE_VSCRIPT + // This should be abstract, but there's a lot of systems which derive from + // this interface that would need to have this declared + virtual void RegisterVScript() { ; } + static void RegisterVScriptAllSystems(); +#endif }; class IGameSystemPerFrame : public IGameSystem diff --git a/game/shared/in_buttons.h b/game/shared/in_buttons.h index 38e985d2..6dc1fc13 100644 --- a/game/shared/in_buttons.h +++ b/game/shared/in_buttons.h @@ -11,6 +11,11 @@ #pragma once #endif +#ifdef MAPBASE +// That one article on the VDC. +//#define VGUI_SCREEN_FIX 1 +#endif + #define IN_ATTACK (1 << 0) #define IN_JUMP (1 << 1) #define IN_DUCK (1 << 2) @@ -39,4 +44,8 @@ #define IN_ATTACK3 (1 << 25) #define IN_THROWGRENADE (1 << 26) +#ifdef VGUI_SCREEN_FIX +#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix +#endif + #endif // IN_BUTTONS_H diff --git a/game/shared/mapbase/MapEdit.cpp b/game/shared/mapbase/MapEdit.cpp new file mode 100644 index 00000000..0891c29e --- /dev/null +++ b/game/shared/mapbase/MapEdit.cpp @@ -0,0 +1,893 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: The flimsy MapEdit system that was +// heavily inspired by Synergy's MapEdit, completely based on the Commentary System +// and originally used for Lambda Fortress. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "MapEdit.h" +#include "filesystem.h" + +#ifndef CLIENT_DLL +#include +#include "utldict.h" +#include "isaverestore.h" +#include "eventqueue.h" +#include "saverestore_utlvector.h" +#include "ai_basenpc.h" +#include "triggers.h" +#include "mapbase/SystemConvarMod.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifndef CLIENT_DLL + +#define MAPEDIT_SPAWNED_SEMAPHORE "mapedit_semaphore" +#define MAPEDIT_DEFAULT_FILE UTIL_VarArgs("maps/%s_auto.txt", STRING(gpGlobals->mapname)) + +ConVar mapedit_enabled("mapedit_enabled", "1", FCVAR_ARCHIVE, "Is automatic MapEdit enabled?"); +ConVar mapedit_stack("mapedit_stack", "1", FCVAR_ARCHIVE, "If multiple MapEdit scripts are loaded, should they stack or replace each other?"); +ConVar mapedit_debug("mapedit_debug", "0", FCVAR_NONE, "Should MapEdit give debug messages?"); + +inline void DebugMsg(const tchar *pMsg, ...) +{ + if (mapedit_debug.GetBool() == true) + { + Msg("%s", pMsg); + } +} + +//bool g_bMapEditAvailable; +bool g_bMapEditLoaded = false; +bool IsMapEditLoaded( void ) +{ + return g_bMapEditLoaded; +} + +bool IsAutoMapEditAllowed(void) +{ + return mapedit_enabled.GetBool(); +} + +void CV_GlobalChange_MapEdit( IConVar *var, const char *pOldString, float flOldValue ); + +//----------------------------------------------------------------------------- +// Purpose: Game system for MapEdit stuff +//----------------------------------------------------------------------------- +class CMapEdit : public CAutoGameSystemPerFrame +{ +public: + DECLARE_DATADESC(); + + virtual void LevelInitPreEntity() + { + m_bMapEditConvarsChanging = false; + CalculateAvailableState(); + } + + void CalculateAvailableState( void ) + { + // Set the available cvar if we can find commentary data for this level + char szFullName[512]; + Q_snprintf(szFullName,sizeof(szFullName), "maps/%s_auto.txt", STRING( gpGlobals->mapname) ); + if ( filesystem->FileExists( szFullName ) ) + { + bool bAllowed = IsAutoMapEditAllowed(); + g_bMapEditLoaded = bAllowed; + //if (bAllowed) + // gEntList.AddListenerEntity( this ); + } + else + { + g_bMapEditLoaded = false; + //gEntList.RemoveListenerEntity( this ); + } + } + + virtual void LevelShutdownPreEntity() + { + ShutDownMapEdit(); + } + + void ParseEntKVBlock( CBaseEntity *pNode, KeyValues *pkvNode ) + { + KeyValues *pkvNodeData = pkvNode->GetFirstSubKey(); + while ( pkvNodeData ) + { + // Handle the connections block + if ( !Q_strcmp(pkvNodeData->GetName(), "connections") ) + { + ParseEntKVBlock( pNode, pkvNodeData ); + } + else + { + #define MAPEDIT_STRING_LENGTH_MAX 1024 + + const char *pszValue = pkvNodeData->GetString(); + Assert( Q_strlen(pszValue) < MAPEDIT_STRING_LENGTH_MAX ); + if ( Q_strnchr(pszValue, '^', MAPEDIT_STRING_LENGTH_MAX) ) + { + // We want to support quotes in our strings so that we can specify multiple parameters in + // an output inside our commentary files. We convert ^s to "s here. + char szTmp[MAPEDIT_STRING_LENGTH_MAX]; + Q_strncpy( szTmp, pszValue, MAPEDIT_STRING_LENGTH_MAX ); + int len = Q_strlen( szTmp ); + for ( int i = 0; i < len; i++ ) + { + if ( szTmp[i] == '^' ) + { + szTmp[i] = '"'; + } + } + + pszValue = szTmp; + } + + char cOperatorChar = pszValue[0]; + if (cOperatorChar == '+') + { + pszValue++; + char szExistingValue[MAPEDIT_STRING_LENGTH_MAX]; + if (pNode->GetKeyValue(pkvNodeData->GetName(), szExistingValue, sizeof(szExistingValue) )) + { + // Right now, this only supports adding floats/integers. + // Add Vector support later. + float flResult = atof(szExistingValue) + atof(pszValue); + pszValue = UTIL_VarArgs("%f", flResult); + } + } + else if (cOperatorChar == '-') + { + pszValue++; + char szExistingValue[MAPEDIT_STRING_LENGTH_MAX]; + if (pNode->GetKeyValue(pkvNodeData->GetName(), szExistingValue, sizeof(szExistingValue) )) + { + // Right now, this only supports subtracting floats/integers. + // Add Vector support later. + float flResult = atof(szExistingValue) - atof(pszValue); + pszValue = UTIL_VarArgs("%f", flResult); + } + } + else if (cOperatorChar == '|' /*&& pszValue[1] == '='*/) + { + pszValue++; + char szExistingValue[MAPEDIT_STRING_LENGTH_MAX]; + if (pNode->GetKeyValue(pkvNodeData->GetName(), szExistingValue, sizeof(szExistingValue))) + { + int iResult = atoi(szExistingValue) | atoi(pszValue); + pszValue = UTIL_VarArgs("%i", iResult); + } + } + + pNode->KeyValue(pkvNodeData->GetName(), pszValue); + } + + pkvNodeData = pkvNodeData->GetNextKey(); + } + } + + virtual void LevelInitPostEntity( void ) + { + if ( !IsMapEditLoaded() ) + { + return; + } + + if ( gpGlobals->eLoadType == MapLoad_LoadGame || gpGlobals->eLoadType == MapLoad_Background ) + { + return; + } + + m_bMapEditLoadedMidGame = false; + InitMapEdit(); + + //IGameEvent *event = gameeventmanager->CreateEvent( "playing_mapedit" ); + //gameeventmanager->FireEventClientSide( event ); + } + + bool MapEditConvarsChanging( void ) + { + return m_bMapEditConvarsChanging; + } + + void SetMapEditConvarsChanging( bool bChanging ) + { + m_bMapEditConvarsChanging = bChanging; + } + + void ConvarChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) + { + ConVarRef var( pConVar ); + + // A convar has been changed by a commentary node. We need to store + // the old state. If the engine shuts down, we need to restore any + // convars that the commentary changed to their previous values. + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + // If we find it, just update the current value + if ( !Q_strncmp( var.GetName(), m_ModifiedConvars[i].pszConvar, MAX_MODIFIED_CONVAR_STRING ) ) + { + Q_strncpy( m_ModifiedConvars[i].pszCurrentValue, var.GetString(), MAX_MODIFIED_CONVAR_STRING ); + //Msg(" Updating Convar %s: value %s (org %s)\n", m_ModifiedConvars[i].pszConvar, m_ModifiedConvars[i].pszCurrentValue, m_ModifiedConvars[i].pszOrgValue ); + return; + } + } + + // We didn't find it in our list, so add it + modifiedconvars_t newConvar; + Q_strncpy( newConvar.pszConvar, var.GetName(), MAX_MODIFIED_CONVAR_STRING ); + Q_strncpy( newConvar.pszCurrentValue, var.GetString(), MAX_MODIFIED_CONVAR_STRING ); + Q_strncpy( newConvar.pszOrgValue, pOldString, MAX_MODIFIED_CONVAR_STRING ); + m_ModifiedConvars.AddToTail( newConvar ); + + /* + Msg(" Commentary changed '%s' to '%s' (was '%s')\n", var->GetName(), var->GetString(), pOldString ); + Msg(" Convars stored: %d\n", m_ModifiedConvars.Count() ); + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + Msg(" Convar %d: %s, value %s (org %s)\n", i, m_ModifiedConvars[i].pszConvar, m_ModifiedConvars[i].pszCurrentValue, m_ModifiedConvars[i].pszOrgValue ); + } + */ + } + + CBaseEntity *FindMapEditEntity( CBaseEntity *pStartEntity, const char *szName, const char *szValue = NULL ) + { + CBaseEntity *pEntity = NULL; + DebugMsg("MapEdit Find Debug: Starting Search, Name: %s, Value: %s\n", szName, szValue); + + // First, find by targetname/classname + pEntity = gEntList.FindEntityGeneric(pStartEntity, szName); + + if (!pEntity) + { + DebugMsg("MapEdit Find Debug: \"%s\" not found as targetname or classname\n", szName); + + if (szValue) + { + if (!Q_strnicmp(szName, "#find_", 6)) + { + const char *pName = szName + 6; + if (!Q_stricmp(pName, "by_keyfield")) + { + char key[64]; + char value[64]; + + // Separate key from value + char *delimiter = Q_strstr(szValue, " "); + if (delimiter) + { + Q_strncpy(key, szValue, MIN((delimiter - szValue) + 1, sizeof(key))); + Q_strncpy(value, delimiter + 1, sizeof(value)); + } + else + { + // Assume the value doesn't matter and we're just looking for the key + Q_strncpy(key, szValue, sizeof(key)); + } + + if (!key) + { + Warning("MapEdit: Possible find_by_keyfield syntax error: key not detected in \"%s\"\n", szValue); + } + + // Find entities with matching keyfield + variant_t variant; + const CEntInfo *pInfo = pStartEntity ? gEntList.GetEntInfoPtr(pStartEntity->GetRefEHandle())->m_pNext : gEntList.FirstEntInfo(); + for (; pInfo; pInfo = pInfo->m_pNext) + { + CBaseEntity *ent = (CBaseEntity *)pInfo->m_pEntity; + if (!ent) + { + DevWarning("NULL entity in global entity list!\n"); + continue; + } + + if (!ent->edict()) + continue; + + if (ent->ReadKeyField(key, &variant)) + { + // Does the value matter? + if (value) + { + if (Q_stricmp(variant.String(), value) == 0) + { + // The entity has the keyfield and it matches the value. + return ent; + } + } + else + { + // The value doesn't matter and the entity has the keyfield. + return ent; + } + } + } + } + else if (!Q_stricmp(pName, "by_origin")) + { + // Find entities at this origin + Vector vecOrigin; + UTIL_StringToVector(vecOrigin.Base(), szValue); + if (vecOrigin.IsValid()) + { + DebugMsg("MapEdit Find Debug: \"%s\" is valid vector\n", szValue); + const CEntInfo *pInfo = pStartEntity ? gEntList.GetEntInfoPtr(pStartEntity->GetRefEHandle())->m_pNext : gEntList.FirstEntInfo(); + for (; pInfo; pInfo = pInfo->m_pNext) + { + CBaseEntity *ent = (CBaseEntity *)pInfo->m_pEntity; + if (!ent) + { + DevWarning("NULL entity in global entity list!\n"); + continue; + } + + if (!ent->edict()) + continue; + + if (ent->GetLocalOrigin() == vecOrigin) + return ent; + } + } + } + } + else if (!pStartEntity) + { + // Try the entity index + int iEntIndex = atoi(szName); + if (!pStartEntity && UTIL_EntityByIndex(iEntIndex)) + { + DebugMsg("MapEdit Find Debug: \"%s\" is valid index\n", szName); + return CBaseEntity::Instance(iEntIndex); + } + } + } + + DebugMsg("MapEdit Find Debug: \"%s\" not found\n", szName); + return NULL; + } + + DebugMsg("MapEdit Find Debug: \"%s\" found as targetname or classname\n", szName); + return pEntity; + } + + void InitMapEdit( const char* pFile = MAPEDIT_DEFAULT_FILE ) + { + // Install the global cvar callback + cvar->InstallGlobalChangeCallback( CV_GlobalChange_MapEdit ); + + + // If we find the commentary semaphore, the commentary entities already exist. + // This occurs when you transition back to a map that has saved commentary nodes in it. + if ( gEntList.FindEntityByName( NULL, MAPEDIT_SPAWNED_SEMAPHORE ) ) + return; + + // Spawn the commentary semaphore entity + CBaseEntity *pSemaphore = CreateEntityByName( "info_target" ); + pSemaphore->SetName( MAKE_STRING(MAPEDIT_SPAWNED_SEMAPHORE) ); + + bool oldLock = engine->LockNetworkStringTables( false ); + + SpawnMapEdit(pFile); + + engine->LockNetworkStringTables( oldLock ); + } + + void LoadFromFormat_Original(KeyValues *pkvFile) + { + KeyValues *pkvNode = pkvFile->GetFirstSubKey(); + while ( pkvNode ) + { + const char *pNodeName = pkvNode->GetName(); + if (FStrEq(pNodeName, "create")) + { + KeyValues *pkvClassname = pkvNode->GetFirstSubKey(); + while (pkvClassname) + { + pNodeName = pkvClassname->GetName(); + + CBaseEntity *pNode = CreateEntityByName(pNodeName); + if (pNode) + { + ParseEntKVBlock(pNode, pkvClassname); + + EHANDLE hHandle; + hHandle = pNode; + m_hSpawnedEntities.AddToTail(hHandle); + DebugMsg("MapEdit Debug: Spawned entity %s\n", pNodeName); + } + else + { + Warning("MapEdit: Failed to spawn mapedit entity, type: '%s'\n", pNodeName); + } + + pkvClassname = pkvClassname->GetNextKey(); + } + } + else if (FStrEq(pNodeName, "edit")) + { + KeyValues *pName = pkvNode->GetFirstSubKey(); + while (pName) + { + pNodeName = pName->GetName(); + + CBaseEntity *pNode = NULL; + + pNode = FindMapEditEntity(NULL, pNodeName, pName->GetString()); + + while (pNode) + { + DebugMsg("MapEdit Debug: Editing %s (%s)\n", pNodeName, pNode->GetDebugName()); + + ParseEntKVBlock(pNode, pName); + pNode = FindMapEditEntity(pNode, pNodeName, pName->GetString()); + } + + pName = pName->GetNextKey(); + } + } + else if (FStrEq(pNodeName, "delete")) + { + KeyValues *pName = pkvNode->GetFirstSubKey(); + while (pName) + { + pNodeName = pName->GetName(); + + CBaseEntity *pNode = NULL; + + pNode = FindMapEditEntity(NULL, pNodeName, pName->GetString()); + + while (pNode) + { + DebugMsg("MapEdit Debug: Deleting %s (%s)\n", pNodeName, pNode->GetDebugName()); + + UTIL_Remove(pNode); + pNode = FindMapEditEntity(pNode, pNodeName, pName->GetString()); + } + + pName = pName->GetNextKey(); + } + } + else if (FStrEq(pNodeName, "fire")) + { + KeyValues *pName = pkvNode->GetFirstSubKey(); + while (pName) + { + pNodeName = pName->GetName(); + + string_t pInputName = NULL_STRING; + variant_t varInputParam; + float flInputDelay = 0.0f; + CBaseEntity *pActivator = NULL; + CBaseEntity *pCaller = NULL; + int iOutputID = 0; + + char *pszValue = strdup(pName->GetString()); + int iter = 0; + char *inputparams = strtok(pszValue, ","); + while (inputparams) + { + switch (iter) + { + // Input name + case 0: + pInputName = AllocPooledString(inputparams); break; + // Input parameter + case 1: + varInputParam.SetString(AllocPooledString(inputparams)); break; + // Input delay + case 2: + flInputDelay = atof(inputparams); break; + // Activator + case 3: + pActivator = gEntList.FindEntityByName(NULL, inputparams); break; + // Caller + case 4: + pCaller = gEntList.FindEntityByName(NULL, inputparams); break; + // Output ID + case 5: + iOutputID = atoi(inputparams); break; + } + iter++; + inputparams = strtok(NULL, ","); + } + free(pszValue); + + DebugMsg("MapEdit Debug: Firing input %s on %s\n", pInputName, pNodeName); + g_EventQueue.AddEvent(pNodeName, STRING(pInputName), varInputParam, flInputDelay, pActivator, pCaller, iOutputID); + + pName = pName->GetNextKey(); + } + } + else if (FStrEq(pNodeName, "console")) + { + KeyValues *pkvNodeData = pkvNode->GetFirstSubKey(); + const char *pKey; + const char *pValue; + while (pkvNodeData) + { + SetMapEditConvarsChanging(true); + + pKey = pkvNodeData->GetName(); + pValue = pkvNodeData->GetString(); + + engine->ServerCommand(UTIL_VarArgs("%s %s", pKey, pValue)); + engine->ServerCommand("mapedit_cvarsnotchanging\n"); + + pkvNodeData = pkvNodeData->GetNextKey(); + } + } + + pkvNode = pkvNode->GetNextKey(); + } + } + + void SpawnMapEdit(const char *pFile = NULL) + { + // Find the commentary file + char szFullName[512]; + if (pFile == NULL) + { + DebugMsg("MapEdit Debug: NULL file, loading default\n"); + Q_snprintf(szFullName,sizeof(szFullName), "maps/%s_auto.txt", STRING( gpGlobals->mapname )); + } + else + { + DebugMsg("MapEdit Debug: File not NULL, loading %s\n", pFile); + Q_strncpy(szFullName, pFile, sizeof(szFullName)); + } + KeyValues *pkvFile = new KeyValues( "MapEdit" ); + if ( pkvFile->LoadFromFile( filesystem, szFullName, "MOD" ) ) + { + Msg( "MapEdit: Loading MapEdit data from %s. \n", szFullName ); + + if (gpGlobals->eLoadType != MapLoad_LoadGame) + { + // Support for multiple formats + const char *szVersion = pkvFile->GetString("version", "original"); + if (FStrEq(szVersion, "original")) + LoadFromFormat_Original(pkvFile); + // TODO: More formats + } + + // Then activate all the entities + for ( int i = 0; i < m_hSpawnedEntities.Count(); i++ ) + { + DispatchSpawn(m_hSpawnedEntities[i]); + } + } + else + { + Msg( "MapEdit: Could not find MapEdit data file '%s'. \n", szFullName ); + } + + pkvFile->deleteThis(); + } + + void ShutDownMapEdit( void ) + { + // Destroy all the entities created by commentary + for ( int i = m_hSpawnedEntities.Count()-1; i >= 0; i-- ) + { + if ( m_hSpawnedEntities[i] ) + { + UTIL_Remove( m_hSpawnedEntities[i] ); + } + } + m_hSpawnedEntities.Purge(); + + // Remove the semaphore + CBaseEntity *pSemaphore = gEntList.FindEntityByName( NULL, MAPEDIT_SPAWNED_SEMAPHORE ); + if ( pSemaphore ) + { + UTIL_Remove( pSemaphore ); + } + + // Remove our global convar callback + cvar->RemoveGlobalChangeCallback( CV_GlobalChange_MapEdit ); + + // Reset any convars that have been changed by the commentary + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + ConVar *pConVar = (ConVar *)cvar->FindVar( m_ModifiedConvars[i].pszConvar ); + if ( pConVar ) + { + pConVar->SetValue( m_ModifiedConvars[i].pszOrgValue ); + } + } + m_ModifiedConvars.Purge(); + } + + void SetMapEdit( bool bMapEdit, const char *pFile = NULL ) + { + //g_bMapEditLoaded = bMapEdit; + //CalculateAvailableState(); + + // If we're turning on commentary, create all the entities. + if ( bMapEdit ) + { + if (filesystem->FileExists(pFile) || pFile == NULL) + { + g_bMapEditLoaded = true; + m_bMapEditLoadedMidGame = true; + InitMapEdit(pFile); + } + else + { + Warning("MapEdit: No such file \"%s\"!\n", pFile); + } + } + else + { + ShutDownMapEdit(); + } + } + + void OnRestore( void ) + { + cvar->RemoveGlobalChangeCallback( CV_GlobalChange_MapEdit ); + + if ( !IsMapEditLoaded() ) + return; + + // Set any convars that have already been changed by the commentary before the save + for ( int i = 0; i < m_ModifiedConvars.Count(); i++ ) + { + ConVar *pConVar = (ConVar *)cvar->FindVar( m_ModifiedConvars[i].pszConvar ); + if ( pConVar ) + { + //Msg(" Restoring Convar %s: value %s (org %s)\n", m_ModifiedConvars[i].pszConvar, m_ModifiedConvars[i].pszCurrentValue, m_ModifiedConvars[i].pszOrgValue ); + pConVar->SetValue( m_ModifiedConvars[i].pszCurrentValue ); + } + } + + // Install the global cvar callback + cvar->InstallGlobalChangeCallback( CV_GlobalChange_MapEdit ); + } + + bool MapEditLoadedMidGame( void ) + { + return m_bMapEditLoadedMidGame; + } + +private: + bool m_bMapEditConvarsChanging; + bool m_bMapEditLoadedMidGame; + + CUtlVector< modifiedconvars_t > m_ModifiedConvars; + CUtlVector m_hSpawnedEntities; +}; + +CMapEdit g_MapEdit; + +BEGIN_DATADESC_NO_BASE( CMapEdit ) + + DEFINE_FIELD( m_bMapEditLoadedMidGame, FIELD_BOOLEAN ), + + DEFINE_UTLVECTOR( m_ModifiedConvars, FIELD_EMBEDDED ), + DEFINE_UTLVECTOR( m_hSpawnedEntities, FIELD_EHANDLE ), + + //DEFINE_UTLVECTOR( m_SpawnEditLookup, FIELD_EMBEDDED ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: We need to revert back any convar changes that are made by the +// commentary system during commentary. This code stores convar changes +// made by the commentary system, and reverts them when finished. +//----------------------------------------------------------------------------- +void CV_GlobalChange_MapEdit( IConVar *var, const char *pOldString, float flOldValue ) +{ + if ( !g_MapEdit.MapEditConvarsChanging() ) + { + // A convar has changed, but not due to mapedit. Ignore it. + return; + } + + g_MapEdit.ConvarChanged( var, pOldString, flOldValue ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CC_MapEditNotChanging( void ) +{ + g_MapEdit.SetMapEditConvarsChanging( false ); +} +static ConCommand mapedit_cvarsnotchanging( "mapedit_cvarsnotchanging", CC_MapEditNotChanging, 0 ); + +// ======================================================== +// Static functions that can be accessed from outside +// ======================================================== + +//----------------------------------------------------------------------------- +// Purpose: Reloads automatic MapEdit after cleanup +//----------------------------------------------------------------------------- +void MapEdit_MapReload( void ) +{ + Msg("MapEdit: Map reloading\n"); + + g_MapEdit.ShutDownMapEdit(); + + g_MapEdit.LevelInitPreEntity(); + + g_MapEdit.LevelInitPostEntity(); +} + +//----------------------------------------------------------------------------- +// Purpose: Loads a specific MapEdit file. +//----------------------------------------------------------------------------- +void MapEdit_LoadFile(const char *pFile, bool bStack) +{ + if (!filesystem->FileExists(pFile)) + { + Warning("MapEdit: No such file \"%s\"!\n", pFile); + return; + } + + if (IsMapEditLoaded()) + { + if (bStack) + { + g_MapEdit.SpawnMapEdit(pFile); + return; + } + else + { + g_MapEdit.SetMapEdit(false); + } + } + + g_MapEdit.SetMapEdit(true, pFile); +} + + +//----------------------------------------------------------------------------- +// Purpose: MapEdit specific logic_auto replacement. +// Fires outputs based upon how MapEdit has been activated. +//----------------------------------------------------------------------------- +class CMapEditAuto : public CBaseEntity +{ + DECLARE_CLASS( CMapEditAuto, CBaseEntity ); +public: + DECLARE_DATADESC(); + + void Spawn(void); + void Think(void); + +private: + // fired if loaded due to new map + COutputEvent m_OnMapEditNewGame; + + // fired if loaded in the middle of a map + COutputEvent m_OnMapEditMidGame; +}; + +LINK_ENTITY_TO_CLASS(mapedit_auto, CMapEditAuto); + +BEGIN_DATADESC( CMapEditAuto ) + // Outputs + DEFINE_OUTPUT(m_OnMapEditNewGame, "OnMapEditNewGame"), + DEFINE_OUTPUT(m_OnMapEditMidGame, "OnMapEditMidGame"), +END_DATADESC() + +//------------------------------------------------------------------------------ +// Purpose : Fire my outputs here if I fire on map reload +//------------------------------------------------------------------------------ +void CMapEditAuto::Spawn(void) +{ + BaseClass::Spawn(); + SetNextThink( gpGlobals->curtime + 0.1 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMapEditAuto::Think(void) +{ + if ( g_MapEdit.MapEditLoadedMidGame() ) + { + m_OnMapEditMidGame.FireOutput(NULL, this); + } + else + { + m_OnMapEditNewGame.FireOutput(NULL, this); + } +} + +//------------------------------------------------------------------------------ +// Purpose : +// Input : +// Output : +//------------------------------------------------------------------------------ +void CC_MapEdit_Load( const CCommand& args ) +{ + const char *sFile = args[1] ? args[1] : NULL; + + MapEdit_LoadFile(sFile, mapedit_stack.GetBool()); +} +static ConCommand mapedit_load("mapedit_load", CC_MapEdit_Load, "Forces mapedit to load a specific file. If there is no input value, it will load the map's default file.", FCVAR_CHEAT); + +//------------------------------------------------------------------------------ +// Purpose : Unloads all MapEdit entities. Does not undo modifications or deletions. +// Input : +// Output : +//------------------------------------------------------------------------------ +void CC_MapEdit_Unload( const CCommand& args ) +{ + g_MapEdit.SetMapEdit(false); +} +static ConCommand mapedit_unload("mapedit_unload", CC_MapEdit_Unload, "Forces mapedit to unload.", FCVAR_CHEAT); + +#else + +//------------------------------------------------------------------------------ +// Purpose : Prints MapEdit data from a specific file to the console. +// Input : The file to print +// Output : The file's data +//------------------------------------------------------------------------------ +void CC_MapEdit_Print( const CCommand& args ) +{ + const char *szFullName = args[1]; + if (szFullName && filesystem->FileExists(szFullName)) + { + KeyValues *pkvFile = new KeyValues( "MapEdit" ); + if ( pkvFile->LoadFromFile( filesystem, szFullName, "MOD" ) ) + { + Msg( "MapEdit: Printing MapEdit data from %s. \n", szFullName ); + + // Load each commentary block, and spawn the entities + KeyValues *pkvNode = pkvFile->GetFirstSubKey(); + while ( pkvNode ) + { + // Get node name + const char *pNodeName = pkvNode->GetName(); + Msg("- Section Name: %s\n", pNodeName); + + // Skip the trackinfo + if ( !Q_strncmp( pNodeName, "trackinfo", 9 ) ) + { + pkvNode = pkvNode->GetNextKey(); + continue; + } + + KeyValues *pClassname = pkvNode->GetFirstSubKey(); + while (pClassname) + { + // Use the classname instead + pNodeName = pClassname->GetName(); + + Msg(" %s\n", pNodeName); + for ( KeyValues *sub = pClassname->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) + { + if (!Q_strcmp(sub->GetName(), "connections")) + { + Msg("- connections\n"); + for ( KeyValues *sub2 = sub->GetFirstSubKey(); sub2; sub2 = sub2->GetNextKey() ) + { + Msg("- \"%s\", \"%s\"\n", sub2->GetName(), sub2->GetString()); + } + continue; + } + Msg("- %s, %s\n", sub->GetName(), sub->GetString()); + } + + pClassname = pClassname->GetNextKey(); + } + + pkvNode = pkvNode->GetNextKey(); + } + + } + pkvFile->deleteThis(); + } +} +static ConCommand mapedit_print("mapedit_print", CC_MapEdit_Print, "Prints a mapedit file in the console."); + +#endif diff --git a/game/shared/mapbase/MapEdit.h b/game/shared/mapbase/MapEdit.h new file mode 100644 index 00000000..899f6712 --- /dev/null +++ b/game/shared/mapbase/MapEdit.h @@ -0,0 +1,14 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Accessing MapEdit +// +// $NoKeywords: $ +//=============================================================================// + +extern ConVar mapedit_enabled; +extern ConVar mapedit_stack; +extern ConVar mapedit_debug; + +void MapEdit_MapReload( void ); + +void MapEdit_LoadFile( const char *pFile, bool bStack = mapedit_stack.GetBool() ); diff --git a/game/shared/mapbase/logic_script_client.cpp b/game/shared/mapbase/logic_script_client.cpp new file mode 100644 index 00000000..97edfe30 --- /dev/null +++ b/game/shared/mapbase/logic_script_client.cpp @@ -0,0 +1,276 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Custom client-side equivalent of logic_script. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "vscript_shared.h" +#include "tier1/fmtstr.h" + +#ifdef CLIENT_DLL +ConVar cl_script_think_interval( "cl_script_think_interval", "0.1" ); +#endif + +//----------------------------------------------------------------------------- +// Purpose: An entity that acts as a container for client-side game scripts. +//----------------------------------------------------------------------------- + +#define MAX_SCRIPT_GROUP_CLIENT 8 + +class CLogicScriptClient : public CBaseEntity +{ +public: + DECLARE_CLASS( CLogicScriptClient, CBaseEntity ); + DECLARE_DATADESC(); + DECLARE_NETWORKCLASS(); + +#ifdef CLIENT_DLL + void OnDataChanged( DataUpdateType_t type ) + { + BaseClass::OnDataChanged( type ); + + if ( !m_ScriptScope.IsInitialized() ) + { + RunVScripts(); + } + } +#else + int UpdateTransmitState() { return SetTransmitState( FL_EDICT_ALWAYS ); } +#endif + + bool KeyValue( const char *szKeyName, const char *szValue ) + { + if ( FStrEq( szKeyName, "vscripts" ) ) + { + Q_strcpy( m_iszClientScripts.GetForModify(), szValue ); + } + + return BaseClass::KeyValue( szKeyName, szValue ); + } + + void RunVScripts() + { +#ifdef CLIENT_DLL + if (m_iszClientScripts == NULL_STRING) + { + CGMsg( 0, CON_GROUP_VSCRIPT, "%s has no client scripts", GetDebugName() ); + return; + } + + if (g_pScriptVM == NULL) + { + return; + } + + ValidateScriptScope(); + + // All functions we want to have call chained instead of overwritten + // by other scripts in this entities list. + static const char* sCallChainFunctions[] = + { + "OnPostSpawn", + "Precache" + }; + + ScriptLanguage_t language = g_pScriptVM->GetLanguage(); + + // Make a call chainer for each in this entities scope + for (int j = 0; j < ARRAYSIZE( sCallChainFunctions ); ++j) + { + + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter + HSCRIPT hCreateChainScript = g_pScriptVM->CompileScript( CFmtStr( "%sCallChain <- CSimpleCallChainer(\"%s\", self.GetScriptScope(), true)", sCallChainFunctions[j], sCallChainFunctions[j] ) ); + g_pScriptVM->Run( hCreateChainScript, (HSCRIPT)m_ScriptScope ); + } + } + + char szScriptsList[255]; + Q_strcpy( szScriptsList, m_iszClientScripts.Get() ); + CUtlStringList szScripts; + + V_SplitString( szScriptsList, " ", szScripts ); + + for (int i = 0; i < szScripts.Count(); i++) + { + CGMsg( 0, CON_GROUP_VSCRIPT, "%s executing script: %s\n", GetDebugName(), szScripts[i] ); + + RunScriptFile( szScripts[i], IsWorld() ); + + for (int j = 0; j < ARRAYSIZE( sCallChainFunctions ); ++j) + { + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter. + HSCRIPT hRunPostScriptExecute = g_pScriptVM->CompileScript( CFmtStr( "%sCallChain.PostScriptExecute()", sCallChainFunctions[j] ) ); + g_pScriptVM->Run( hRunPostScriptExecute, (HSCRIPT)m_ScriptScope ); + } + } + } + + if (m_bClientThink) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +#else + // Avoids issues from having m_iszVScripts set without actually having a script scope + ValidateScriptScope(); + + if (m_bRunOnServer) + { + BaseClass::RunVScripts(); + } +#endif + } + +#ifdef CLIENT_DLL + void ClientThink() + { + ScriptVariant_t varThinkRetVal; + if (CallScriptFunction("ClientThink", &varThinkRetVal)) + { + float flThinkFrequency = 0.0f; + if (!varThinkRetVal.AssignTo(&flThinkFrequency)) + { + // use default think interval if script think function doesn't provide one + flThinkFrequency = cl_script_think_interval.GetFloat(); + } + + if (flThinkFrequency == CLIENT_THINK_ALWAYS) + SetNextClientThink( CLIENT_THINK_ALWAYS ); + else + SetNextClientThink( gpGlobals->curtime + flThinkFrequency ); + } + else + { + DevWarning("%s FAILED to call client script think function!\n", GetDebugName()); + } + + BaseClass::ClientThink(); + } + + void OnSave() + { + // HACKHACK: Save the next think in the VM since the VM is saved + if (m_bClientThink) + { + g_pScriptVM->SetValue( m_ScriptScope, "__c_think", GetNextThink() ); + } + + BaseClass::OnSave(); + } + + void OnRestore() + { + // HACKHACK: See OnSave() + if (m_bClientThink) + { + ScriptVariant_t flNextThink; + if (g_pScriptVM->GetValue( m_ScriptScope, "__c_think", &flNextThink )) + { + SetNextClientThink( flNextThink ); + } + } + + BaseClass::OnRestore(); + } + + void ReceiveMessage( int classID, bf_read &msg ) + { + if ( classID != GetClientClass()->m_ClassID ) + { + BaseClass::ReceiveMessage( classID, msg ); + return; + } + + char szFunction[64]; + msg.ReadString( szFunction, sizeof( szFunction ) ); + + if ( m_ScriptScope.IsInitialized() ) + { + CallScriptFunction( szFunction, NULL ); + } + else + { + CGMsg( 0, CON_GROUP_VSCRIPT, "%s script scope not initialized!\n", GetDebugName() ); + } + } +#endif + +#ifdef GAME_DLL + void InputCallScriptFunctionClient( inputdata_t &inputdata ) + { + const char *pszFunction = inputdata.value.String(); + if ( V_strlen( pszFunction ) >= 64 ) + { + Msg( "%s CallScriptFunctionClient: \"%s\" is too long at %i characters, must be 64 or less\n", GetDebugName(), pszFunction, V_strlen(pszFunction)+1 ); + return; + } + + EntityMessageBegin( this, true ); + WRITE_STRING( pszFunction ); + MessageEnd(); + } +#endif + + //CNetworkArray( string_t, m_iszGroupMembers, MAX_SCRIPT_GROUP_CLIENT ); + CNetworkString( m_iszClientScripts, 128 ); + CNetworkVar( bool, m_bClientThink ); + +#ifndef CLIENT_DLL + bool m_bRunOnServer; +#endif +}; + +LINK_ENTITY_TO_CLASS( logic_script_client, CLogicScriptClient ); + +BEGIN_DATADESC( CLogicScriptClient ) + + // TODO: Does this need to be saved? + //DEFINE_AUTO_ARRAY( m_iszClientScripts, FIELD_CHARACTER ), + + //DEFINE_KEYFIELD( m_iszGroupMembers[0], FIELD_STRING, "Group00"), + //DEFINE_KEYFIELD( m_iszGroupMembers[1], FIELD_STRING, "Group01"), + //DEFINE_KEYFIELD( m_iszGroupMembers[2], FIELD_STRING, "Group02"), + //DEFINE_KEYFIELD( m_iszGroupMembers[3], FIELD_STRING, "Group03"), + //DEFINE_KEYFIELD( m_iszGroupMembers[4], FIELD_STRING, "Group04"), + //DEFINE_KEYFIELD( m_iszGroupMembers[5], FIELD_STRING, "Group05"), + //DEFINE_KEYFIELD( m_iszGroupMembers[6], FIELD_STRING, "Group06"), + //DEFINE_KEYFIELD( m_iszGroupMembers[7], FIELD_STRING, "Group07"), + + DEFINE_KEYFIELD( m_bClientThink, FIELD_BOOLEAN, "ClientThink" ), + +#ifndef CLIENT_DLL + DEFINE_KEYFIELD( m_bRunOnServer, FIELD_BOOLEAN, "RunOnServer" ), + + DEFINE_INPUTFUNC( FIELD_STRING, "CallScriptFunctionClient", InputCallScriptFunctionClient ), +#endif + +END_DATADESC() + +IMPLEMENT_NETWORKCLASS_DT( CLogicScriptClient, DT_LogicScriptClient ) + +#ifdef CLIENT_DLL + //RecvPropArray( RecvPropString( RECVINFO( m_iszGroupMembers[0] ) ), m_iszGroupMembers ), + RecvPropString( RECVINFO( m_iszClientScripts ) ), + RecvPropBool( RECVINFO( m_bClientThink ) ), +#else + //SendPropArray( SendPropStringT( SENDINFO_ARRAY( m_iszGroupMembers ) ), m_iszGroupMembers ), + SendPropString( SENDINFO( m_iszClientScripts ) ), + SendPropBool( SENDINFO( m_bClientThink ) ), +#endif + +END_NETWORK_TABLE() diff --git a/game/shared/mapbase/mapbase_game_log.cpp b/game/shared/mapbase/mapbase_game_log.cpp new file mode 100644 index 00000000..c51ab0c4 --- /dev/null +++ b/game/shared/mapbase/mapbase_game_log.cpp @@ -0,0 +1,243 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: A special system designed to record game information for map testing. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "tier0/icommandline.h" +#include "igamesystem.h" +#include "filesystem.h" +#include "utlbuffer.h" +#ifdef CLIENT_DLL +#else +#include "ammodef.h" +#include "ai_basenpc.h" +#include "ai_squad.h" +#include "fmtstr.h" +#include "GameEventListener.h" +#include "saverestore_utlvector.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef GAME_DLL +// ------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------ + +class CMapbaseGameLogger : public CLogicalEntity, public CGameEventListener +{ +public: + DECLARE_DATADESC(); + DECLARE_CLASS( CMapbaseGameLogger, CLogicalEntity ); + + CMapbaseGameLogger() + { + pGameLoggerEnt = this; + } + + void Activate() + { + BaseClass::Activate(); + + ListenForGameEvent("skill_changed"); + } + + void FireGameEvent( IGameEvent *event ) + { + if (FStrEq(event->GetName(), "skill_changed")) + { + m_ListSkillChanged.AddToTail(event->GetInt("skill_level")); + m_ListSkillChangedTime.AddToTail(gpGlobals->curtime); + } + } + + float m_flLastLogTime; + int m_iSaveID; + + CUtlVector m_ListSkillChanged; + CUtlVector m_ListSkillChangedTime; + + static CMapbaseGameLogger *GetGameLoggerEnt() + { + if (!pGameLoggerEnt) + pGameLoggerEnt = static_cast(CBaseEntity::Create("mapbase_game_logger", vec3_origin, vec3_angle)); + + return pGameLoggerEnt; + } + +private: + static CHandle pGameLoggerEnt; +}; + +LINK_ENTITY_TO_CLASS( mapbase_game_logger, CMapbaseGameLogger ); + +BEGIN_DATADESC( CMapbaseGameLogger ) + + DEFINE_FIELD( m_flLastLogTime, FIELD_TIME ), + DEFINE_FIELD( m_iSaveID, FIELD_INTEGER ), + + DEFINE_UTLVECTOR( m_ListSkillChanged, FIELD_INTEGER ), + DEFINE_UTLVECTOR( m_ListSkillChangedTime, FIELD_TIME ), + +END_DATADESC() + +CHandle CMapbaseGameLogger::pGameLoggerEnt; + +void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ); +ConVar mapbase_game_log_on_autosave( "mapbase_game_log_on_autosave", "0", FCVAR_NONE, "Logs information to %mapname%_log_%number%.txt on each autosave", MapbaseGameLog_CVarToggle ); + +void MapbaseGameLog_Init() +{ + if (mapbase_game_log_on_autosave.GetBool()) + { + // Create the game logger ent + CMapbaseGameLogger::GetGameLoggerEnt(); + } +} + +void MapbaseGameLog_Record( const char *szContext ) +{ + CMapbaseGameLogger *pGameLoggerEnt = CMapbaseGameLogger::GetGameLoggerEnt(); + if (!pGameLoggerEnt) + { + Warning("Failed to get game logger ent\n"); + return; + } + + KeyValues *pKV = new KeyValues( "Log" ); + + KeyValues *pKVLogInfo = pKV->FindKey( "logging_info", true ); + if ( pKVLogInfo ) + { + pKVLogInfo->SetString("context", szContext); + pKVLogInfo->SetFloat("last_log", pGameLoggerEnt->m_flLastLogTime > 0.0f ? gpGlobals->curtime - pGameLoggerEnt->m_flLastLogTime : -1.0f); + } + + KeyValues *pKVGameInfo = pKV->FindKey( "game_info", true ); + if ( pKVGameInfo ) + { + pKVGameInfo->SetInt("skill", g_pGameRules->GetSkillLevel()); + + if (pGameLoggerEnt->m_ListSkillChanged.Count() > 0) + { + KeyValues *pKVSkill = pKVGameInfo->FindKey("skill_changes", true); + for (int i = 0; i < pGameLoggerEnt->m_ListSkillChanged.Count(); i++) + { + float flTime = pGameLoggerEnt->m_ListSkillChangedTime[i]; + switch (pGameLoggerEnt->m_ListSkillChanged[i]) + { + case SKILL_EASY: pKVSkill->SetString(CNumStr(flTime), "easy"); break; + case SKILL_MEDIUM: pKVSkill->SetString(CNumStr(flTime), "normal"); break; + case SKILL_HARD: pKVSkill->SetString(CNumStr(flTime), "hard"); break; + } + } + } + } + + KeyValues *pKVPlayer = pKV->FindKey( "player", true ); + if ( pKVPlayer ) + { + CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + + if ( pPlayer ) + { + pKVPlayer->SetInt("health", pPlayer->GetHealth()); + pKVPlayer->SetInt("armor", pPlayer->ArmorValue()); + + pKVPlayer->SetString("position", CFmtStrN<128>("[%f %f %f]", pPlayer->GetAbsOrigin().x, pPlayer->GetAbsOrigin().y, pPlayer->GetAbsOrigin().z)); + pKVPlayer->SetString("angles", CFmtStrN<128>("[%f %f %f]", pPlayer->EyeAngles().x, pPlayer->EyeAngles().y, pPlayer->EyeAngles().z)); + + KeyValues *pKVWeapons = pKVPlayer->FindKey( "weapons", true ); + if ( pKVWeapons ) + { + // Cycle through all of the player's weapons + for ( int i = 0; i < pPlayer->WeaponCount(); i++ ) + { + CBaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i); + if ( !pWeapon ) + continue; + + if ( pPlayer->GetActiveWeapon() == pWeapon ) + pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i (active)", pWeapon->m_iClip1.Get(), pWeapon->m_iClip2.Get())); + else + pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i", pWeapon->m_iClip1.Get(), pWeapon->m_iClip2.Get())); + } + } + + KeyValues *pKVAmmo = pKVPlayer->FindKey( "ammo", true ); + if ( pKVAmmo ) + { + // Cycle through all of the player's ammo + for ( int i = 0; i < GetAmmoDef()->m_nAmmoIndex; i++ ) + { + int iAmmo = pPlayer->GetAmmoCount( i ); + if ( iAmmo > 0 ) + pKVAmmo->SetInt( GetAmmoDef()->m_AmmoType[i].pName, iAmmo ); + } + } + } + } + + CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); + int nAIs = g_AI_Manager.NumAIs(); + for (int i = 0; i < nAIs; i++) + { + CAI_BaseNPC *pNPC = ppAIs[i]; + + if (!pNPC->IsAlive() || pNPC->GetSleepState() != AISS_AWAKE) + continue; + + KeyValues *pKVNPC = pKV->FindKey( CNumStr( pNPC->entindex() ), true ); + if (pKVNPC) + { + pKVNPC->SetString("classname", pNPC->GetClassname()); + pKVNPC->SetString("name", STRING(pNPC->GetEntityName())); + + pKVNPC->SetString("position", CFmtStrN<128>("[%f %f %f]", pNPC->GetAbsOrigin().x, pNPC->GetAbsOrigin().y, pNPC->GetAbsOrigin().z)); + + pKVNPC->SetInt("health", pNPC->GetHealth()); + + if (pNPC->GetActiveWeapon()) + pKVNPC->SetString("weapon", pNPC->GetActiveWeapon()->GetClassname()); + + if (pNPC->GetSquad()) + pKVNPC->SetString("squad", pNPC->GetSquad()->GetName()); + } + } + + CFmtStrN pathfmt("map_logs/%s_log_%i.txt", STRING(gpGlobals->mapname), pGameLoggerEnt->m_iSaveID); + + pGameLoggerEnt->m_flLastLogTime = gpGlobals->curtime; + pGameLoggerEnt->m_iSaveID++; + + // Create the folder first, since "map_logs" is not standard and is unlikely to exist + g_pFullFileSystem->CreateDirHierarchy( "map_logs", "MOD" ); + + if (pKV->SaveToFile( g_pFullFileSystem, pathfmt, "MOD" )) + { + Msg("Saved game log file to \"%s\"\n", pathfmt.Get()); + } + + pKV->deleteThis(); +} + +static void CC_Mapbase_GameLogRecord( const CCommand& args ) +{ + MapbaseGameLog_Record( "command" ); +} + +static ConCommand mapbase_game_log_record("mapbase_game_log_record", CC_Mapbase_GameLogRecord, "Records game data to %mapname%_log_%number%." ); + +void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ) +{ + if (mapbase_game_log_on_autosave.GetBool()) + { + // Create the game logger ent + CMapbaseGameLogger::GetGameLoggerEnt(); + } +} +#endif diff --git a/game/shared/mapbase/mapbase_rpc.cpp b/game/shared/mapbase/mapbase_rpc.cpp new file mode 100644 index 00000000..ecbb36ca --- /dev/null +++ b/game/shared/mapbase/mapbase_rpc.cpp @@ -0,0 +1,606 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase's RPC implementation. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#ifdef CLIENT_DLL + +#ifdef STEAM_RPC +#include "clientsteamcontext.h" +#include "steam/steamclientpublic.h" +#endif + +#ifdef DISCORD_RPC +#include "discord_rpc.h" +#include +#include "c_world.h" +#endif + +#include "filesystem.h" +#include "c_playerresource.h" +#include +#include + +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// From mapbase_shared.cpp +extern const char *g_MapName; + +// The game's name found in gameinfo.txt. Mostly used for Discord RPC. +extern char g_iszGameName[128]; + +#ifdef MAPBASE_RPC +void MapbaseRPC_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ); + +ConVar mapbase_rpc_enabled("mapbase_rpc_enabled", "1", FCVAR_ARCHIVE, "Controls whether Mapbase's RPC stuff is enabled on this client.", MapbaseRPC_CVarToggle); + +//----------------------------------------------------------------------------- +// RPC Stuff +// +// Mapbase has some special "RPC" integration stuff for things like Discord. +// There's a section that goes into more detail below. +//----------------------------------------------------------------------------- + +void MapbaseRPC_Init(); +void MapbaseRPC_Shutdown(); + +void MapbaseRPC_Update( int iType, const char *pMapName ); +void MapbaseRPC_Update( int iRPCMask, int iType, const char *pMapName ); + +#ifdef STEAM_RPC +void MapbaseRPC_UpdateSteam( int iType, const char *pMapName ); +#endif + +#ifdef DISCORD_RPC +void MapbaseRPC_UpdateDiscord( int iType, const char *pMapName ); +void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int iType, const char *pMapName ); +#endif + +enum RPCClients_t +{ + RPC_STEAM, + RPC_DISCORD, + + NUM_RPCS, +}; + +static const char *g_pszRPCNames[] = { + "Steam", + "Discord", +}; + +// This is a little dodgy, but it stops us from having to add spawnflag definitions for each RPC. +#define RPCFlag(rpc) (1 << rpc) + +// The global game_metadata entity. +// There can be only one...for each RPC. +static EHANDLE g_Metadata[NUM_RPCS]; + +// Don't update constantly +#define RPC_UPDATE_COOLDOWN 5.0f + +// How long to wait before updating in case multiple variables are changing +#define RPC_UPDATE_WAIT 0.25f +#endif + +#ifdef CLIENT_DLL +#define CMapbaseMetadata C_MapbaseMetadata +#endif + +class CMapbaseMetadata : public CBaseEntity +{ +public: +#ifndef CLIENT_DLL + DECLARE_DATADESC(); +#endif + DECLARE_NETWORKCLASS(); + DECLARE_CLASS( CMapbaseMetadata, CBaseEntity ); + +#ifdef MAPBASE_RPC +#ifdef CLIENT_DLL + ~C_MapbaseMetadata() + { + for (int i = 0; i < NUM_RPCS; i++) + { + if (g_Metadata[i] == this) + { + g_Metadata[i] = NULL; + } + } + } + + void OnDataChanged( DataUpdateType_t updateType ) + { + if (updateType == DATA_UPDATE_CREATED) + { + for (int i = 0; i < NUM_RPCS; i++) + { + // See if we're updating this RPC. + if (m_spawnflags & RPCFlag(i)) + { + if (g_Metadata[i]) + { + Warning("Warning: Metadata entity for %s already exists, replacing with new one\n", g_pszRPCNames[i]); + + // Inherit their update timer + m_flRPCUpdateTimer = static_cast(g_Metadata[i].Get())->m_flRPCUpdateTimer; + + g_Metadata[i].Get()->Remove(); + } + + DevMsg("Becoming metadata entity for %s\n", g_pszRPCNames[i]); + g_Metadata[i] = this; + } + } + } + + // Avoid spamming updates + if (gpGlobals->curtime > (m_flRPCUpdateTimer - RPC_UPDATE_WAIT)) + { + // Multiple variables might be changing, wait until they're probably all finished + m_flRPCUpdateTimer = gpGlobals->curtime + RPC_UPDATE_WAIT; + } + + DevMsg("Metadata changed; updating in %f\n", m_flRPCUpdateTimer - gpGlobals->curtime); + + // Update when the cooldown is over + SetNextClientThink( m_flRPCUpdateTimer ); + } + + void ClientThink() + { + // NOTE: Client thinking should be limited by the update timer! + UpdateRPCThink(); + + // Wait until our data is changed again + SetNextClientThink( CLIENT_THINK_NEVER ); + } + + void UpdateRPCThink() + { + DevMsg("Global metadata entity: %s\n", g_Metadata != NULL ? "Valid" : "Invalid!?"); + + MapbaseRPC_Update(m_spawnflags, RPCSTATE_UPDATE, g_MapName); + + m_flRPCUpdateTimer = gpGlobals->curtime + RPC_UPDATE_COOLDOWN; + } +#else + int UpdateTransmitState() // always send to all clients + { + return SetTransmitState( FL_EDICT_ALWAYS ); + } +#endif +#endif + +#ifdef CLIENT_DLL + char m_iszRPCState[128]; + char m_iszRPCDetails[128]; + +#ifdef MAPBASE_RPC + // Built-in update spam limiter + float m_flRPCUpdateTimer = RPC_UPDATE_COOLDOWN; + + int m_spawnflags; +#endif +#else + CNetworkVar( string_t, m_iszRPCState ); + CNetworkVar( string_t, m_iszRPCDetails ); +#endif + + // TODO: Player-specific control + //CNetworkVar( int, m_iLimitingID ); +}; + +LINK_ENTITY_TO_CLASS( game_metadata, CMapbaseMetadata ); + +IMPLEMENT_NETWORKCLASS_ALIASED(MapbaseMetadata, DT_MapbaseMetadata) + +BEGIN_NETWORK_TABLE_NOBASE(CMapbaseMetadata, DT_MapbaseMetadata) + +#ifdef MAPBASE_RPC +#ifdef CLIENT_DLL + RecvPropString(RECVINFO(m_iszRPCState)), + RecvPropString(RECVINFO(m_iszRPCDetails)), + RecvPropInt( RECVINFO( m_spawnflags ) ), +#else + SendPropStringT(SENDINFO(m_iszRPCState) ), + SendPropStringT(SENDINFO(m_iszRPCDetails) ), + SendPropInt( SENDINFO(m_spawnflags), 8, SPROP_UNSIGNED ), +#endif +#endif + +END_NETWORK_TABLE() + +#ifndef CLIENT_DLL +BEGIN_DATADESC( CMapbaseMetadata ) + + // Inputs + DEFINE_INPUT( m_iszRPCState, FIELD_STRING, "SetRPCState" ), + DEFINE_INPUT( m_iszRPCDetails, FIELD_STRING, "SetRPCDetails" ), + +END_DATADESC() +#endif + +#ifdef MAPBASE_RPC +//----------------------------------------------------------------------------- +// Purpose: Mapbase's special integration with rich presence clients, most notably Discord. +// +// This only has Discord and crude groundwork for Steam as of writing, +//----------------------------------------------------------------------------- + +//----------------------------------------- +// !!! FOR MODS !!! +// +// Create your own Discord "application" if you want to change what info/images show up, etc. +// You can change the app ID in "scripts/mapbase_rpc.txt". It's located in the shared content VPK and the mod templates. +// You could override that file in your mod to change it to your own app ID. +// +// This code automatically shows the mod's title in the details, but it's easy to change this code if you want things to be chapter-specific, etc. +// +//----------------------------------------- + +// Changing the default value of the convars below will not work. +// Use "scripts/mapbase_rpc.txt" instead. +static ConVar cl_discord_appid("cl_discord_appid", "582595088719413250", FCVAR_NONE); +static ConVar cl_discord_largeimage("cl_discord_largeimage", "mb_logo_episodic", FCVAR_NONE); +static ConVar cl_discord_largeimage_text("cl_discord_largeimage_text", "Half-Life 2", FCVAR_NONE); +static int64_t startTimestamp = time(0); + +// + +int MapbaseRPC_GetPlayerCount() +{ + int iNumPlayers = 0; + + if (g_PR) + { + for (; iNumPlayers <= gpGlobals->maxClients; iNumPlayers++) + { + if (!g_PR->IsConnected( iNumPlayers )) + break; + } + } + + return iNumPlayers; +} + +//----------------------------------------------------------------------------- +// Discord RPC handlers +//----------------------------------------------------------------------------- +static void HandleDiscordReady(const DiscordUser* connectedUser) +{ + DevMsg("Discord: Connected to user %s#%s - %s\n", + connectedUser->username, + connectedUser->discriminator, + connectedUser->userId); +} + +static void HandleDiscordDisconnected(int errcode, const char* message) +{ + DevMsg("Discord: Disconnected (%d: %s)\n", errcode, message); +} + +static void HandleDiscordError(int errcode, const char* message) +{ + DevMsg("Discord: Error (%d: %s)\n", errcode, message); +} + +static void HandleDiscordJoin(const char* secret) +{ + // Not implemented +} + +static void HandleDiscordSpectate(const char* secret) +{ + // Not implemented +} + +static void HandleDiscordJoinRequest(const DiscordUser* request) +{ + // Not implemented +} + +void MapbaseRPC_Init() +{ + // Only init if RPC is enabled + if (mapbase_rpc_enabled.GetInt() <= 0) + return; + + // First, load the config + // (we need its values immediately) + KeyValues *pKV = new KeyValues( "MapbaseRPC" ); + if (pKV->LoadFromFile( filesystem, "scripts/mapbase_rpc.txt" )) + { + const char *szAppID = pKV->GetString("discord_appid", cl_discord_appid.GetString()); + cl_discord_appid.SetValue(szAppID); + + const char *szLargeImage = pKV->GetString("discord_largeimage", cl_discord_largeimage.GetString()); + cl_discord_largeimage.SetValue(szLargeImage); + + const char *szLargeImageText = pKV->GetString("discord_largeimage_text", cl_discord_largeimage_text.GetString()); + cl_discord_largeimage_text.SetValue( szLargeImageText ); + } + pKV->deleteThis(); + + // Steam RPC + if (steamapicontext) + { + if (steamapicontext->SteamFriends()) + steamapicontext->SteamFriends()->ClearRichPresence(); + } + + // Discord RPC + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + + handlers.ready = HandleDiscordReady; + handlers.disconnected = HandleDiscordDisconnected; + handlers.errored = HandleDiscordError; + handlers.joinGame = HandleDiscordJoin; + handlers.spectateGame = HandleDiscordSpectate; + handlers.joinRequest = HandleDiscordJoinRequest; + + char appid[255]; + sprintf(appid, "%d", engine->GetAppID()); + Discord_Initialize(cl_discord_appid.GetString(), &handlers, 1, appid); + + if (!g_bTextMode) + { + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + + MapbaseRPC_GetDiscordParameters(discordPresence, RPCSTATE_INIT, NULL); + + discordPresence.startTimestamp = startTimestamp; + + Discord_UpdatePresence(&discordPresence); + } +} + +void MapbaseRPC_Shutdown() +{ + // Discord RPC + Discord_ClearPresence(); + Discord_Shutdown(); + + // Steam RPC + if (steamapicontext) + { + if (steamapicontext->SteamFriends()) + steamapicontext->SteamFriends()->ClearRichPresence(); + } +} + +void MapbaseRPC_Update( int iType, const char *pMapName ) +{ + // All RPCs + MapbaseRPC_Update( INT_MAX, iType, pMapName ); +} + +void MapbaseRPC_Update( int iRPCMask, int iType, const char *pMapName ) +{ + // Only update if RPC is enabled + if (mapbase_rpc_enabled.GetInt() <= 0) + return; + + if (iRPCMask & RPCFlag(RPC_STEAM)) + MapbaseRPC_UpdateSteam(iType, pMapName); + if (iRPCMask & RPCFlag(RPC_DISCORD)) + MapbaseRPC_UpdateDiscord(iType, pMapName); +} + +#ifdef STEAM_RPC +void MapbaseRPC_UpdateSteam( int iType, const char *pMapName ) +{ + // No Steam + if (!steamapicontext || !steamapicontext->SteamFriends()) + return; + + const char *pszStatus = NULL; + + if (g_Metadata[RPC_STEAM] != NULL) + { + C_MapbaseMetadata *pMetadata = static_cast(g_Metadata[RPC_STEAM].Get()); + + if (pMetadata->m_iszRPCDetails[0] != NULL) + pszStatus = pMetadata->m_iszRPCDetails; + else if (pMetadata->m_iszRPCState[0] != NULL) + pszStatus = pMetadata->m_iszRPCState; + else + { + if (engine->IsLevelMainMenuBackground()) + pszStatus = VarArgs("Main Menu (%s)", pMapName ? pMapName : "N/A"); + else + pszStatus = VarArgs("Map: %s", pMapName ? pMapName : "N/A"); + } + } + else + { + switch (iType) + { + case RPCSTATE_INIT: + case RPCSTATE_LEVEL_SHUTDOWN: + { + pszStatus = "Main Menu"; + } break; + case RPCSTATE_LEVEL_INIT: + default: + { + // Say we're in the main menu if it's a background map + if (engine->IsLevelMainMenuBackground()) + { + pszStatus = VarArgs("Main Menu (%s)", pMapName ? pMapName : "N/A"); + } + else + { + pszStatus = VarArgs("Map: %s", pMapName ? pMapName : "N/A"); + } + } break; + } + } + + DevMsg( "Updating Steam\n" ); + + if (pszStatus) + { + steamapicontext->SteamFriends()->SetRichPresence( "gamestatus", pszStatus ); + steamapicontext->SteamFriends()->SetRichPresence( "steam_display", "#SteamRPC_Status" ); + + if (gpGlobals->maxClients > 1) + { + // Players in server + const CSteamID *serverID = serverengine->GetGameServerSteamID(); + if (serverID) + { + char szGroupID[32]; + Q_snprintf(szGroupID, sizeof(szGroupID), "%i", serverID->GetAccountID()); + + char szGroupSize[8]; + Q_snprintf(szGroupSize, sizeof(szGroupSize), "%i", MapbaseRPC_GetPlayerCount()); + + steamapicontext->SteamFriends()->SetRichPresence( "steam_player_group", szGroupID ); + steamapicontext->SteamFriends()->SetRichPresence( "steam_player_group_size", szGroupSize ); + } + else + { + DevWarning("Steam RPC cannot update player count (no server ID)\n"); + } + } + } +} +#endif + +#ifdef DISCORD_RPC +void MapbaseRPC_GetDiscordMapInfo( char *pDetails, size_t iSize, const char *pMapName ) +{ + if (!pMapName) + pMapName = "N/A"; + + // Say we're in the main menu if it's a background map + if (engine->IsLevelMainMenuBackground()) + { + Q_snprintf( pDetails, iSize, "Main Menu (%s)", pMapName ); + } + else + { + // Show the chapter title first + const char *szChapterTitle = NULL; + + C_World *pWorld = GetClientWorldEntity(); + if ( pWorld && pWorld->m_iszChapterTitle[0] != '\0' ) + { + szChapterTitle = g_pVGuiLocalize->FindAsUTF8( pWorld->m_iszChapterTitle ); + if (!szChapterTitle || szChapterTitle[0] == '\0') + szChapterTitle = pWorld->m_iszChapterTitle; + } + + if (szChapterTitle) + { + Q_snprintf( pDetails, iSize, "%s (%s)", szChapterTitle, pMapName ); + } + else + { + Q_snprintf( pDetails, iSize, "%s", pMapName ); + } + } +} + +void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int iType, const char *pMapName ) +{ + static char details[128]; + static char state[128]; + + details[0] = '\0'; + state[0] = '\0'; + + if (g_Metadata[RPC_DISCORD] != NULL) + { + C_MapbaseMetadata *pMetadata = static_cast(g_Metadata[RPC_DISCORD].Get()); + + if (pMetadata->m_iszRPCState[0] != NULL) + Q_strncpy( state, pMetadata->m_iszRPCState, sizeof(state) ); + else + Q_strncpy( state, g_iszGameName, sizeof(state) ); + + if (pMetadata->m_iszRPCDetails[0] != NULL) + Q_strncpy( details, pMetadata->m_iszRPCDetails, sizeof(details) ); + else + { + MapbaseRPC_GetDiscordMapInfo( details, sizeof(details), pMapName ); + } + } + else + { + Q_strncpy( state, g_iszGameName, sizeof(state) ); + + switch (iType) + { + case RPCSTATE_INIT: + case RPCSTATE_LEVEL_SHUTDOWN: + { + Q_strncpy( details, "Main Menu", sizeof(details) ); + } break; + case RPCSTATE_LEVEL_INIT: + default: + { + MapbaseRPC_GetDiscordMapInfo( details, sizeof(details), pMapName ); + } break; + } + } + + if (gpGlobals->maxClients > 1) + { + Q_snprintf( details, sizeof(details), "%s (%i/%i)", details, MapbaseRPC_GetPlayerCount(), gpGlobals->maxClients ); + } + + if (state[0] != '\0') + discordPresence.state = state; + if (details[0] != '\0') + discordPresence.details = details; + + // Generic Mapbase logo. Specific to the Mapbase Discord application. + discordPresence.smallImageKey = "mb_logo_general"; + discordPresence.smallImageText = "Mapbase"; + + discordPresence.largeImageKey = cl_discord_largeimage.GetString(); + discordPresence.largeImageText = cl_discord_largeimage_text.GetString(); +} + +void MapbaseRPC_UpdateDiscord( int iType, const char *pMapName ) +{ + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + + DevMsg("Updating Discord\n"); + + discordPresence.startTimestamp = startTimestamp; + + MapbaseRPC_GetDiscordParameters( discordPresence, iType, pMapName ); + + Discord_UpdatePresence(&discordPresence); +} + +void MapbaseRPC_CVarToggle( IConVar *var, const char *pOldString, float flOldValue ) +{ + if (flOldValue <= 0 && mapbase_rpc_enabled.GetInt() > 0) + { + // Turning on + MapbaseRPC_Init(); + MapbaseRPC_Update( g_MapName != NULL ? RPCSTATE_UPDATE : RPCSTATE_INIT, g_MapName ); + } + else if (mapbase_rpc_enabled.GetInt() <= 0) + { + // Turning off + MapbaseRPC_Shutdown(); + } +} +#endif + +#endif diff --git a/game/shared/mapbase/mapbase_shared.cpp b/game/shared/mapbase/mapbase_shared.cpp new file mode 100644 index 00000000..ba40aaf6 --- /dev/null +++ b/game/shared/mapbase/mapbase_shared.cpp @@ -0,0 +1,837 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Carries the Mapbase CAutoGameSystem that loads manifest among other things. +// Also includes code that does not fit anywhere else. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "tier0/icommandline.h" +#include "tier1/mapbase_con_groups.h" +#include "igamesystem.h" +#include "filesystem.h" +#include +#include +#include +#include "saverestore_utlvector.h" +#include "props_shared.h" +#include "utlbuffer.h" +#include "usermessages.h" +#ifdef CLIENT_DLL +#include "hud_closecaption.h" +#include "panelmetaclassmgr.h" +#include "c_soundscape.h" +#include "hud_macros.h" +#include "clientmode_shared.h" +#else +#include "soundscape_system.h" +#include "AI_ResponseSystem.h" +#include "mapbase/SystemConvarMod.h" +#include "gameinterface.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt" + +#ifdef CLIENT_DLL +#define AUTOLOADED_MANIFEST_FILE VarArgs("maps/%s_manifest.txt", g_MapName) +#else +#define AUTOLOADED_MANIFEST_FILE UTIL_VarArgs("maps/%s_manifest.txt", g_MapName) +#endif + +const char *g_MapName; + +extern ISoundEmitterSystemBase *soundemitterbase; + +ConVar mapbase_load_default_manifest("mapbase_load_default_manifest", "1", FCVAR_ARCHIVE, "Should we automatically load our default manifest file? (\"maps/%mapname%_manifest.txt\")"); + +#ifdef GAME_DLL +// This constant should change with each Mapbase update +ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" ); + +ConVar mapbase_flush_talker("mapbase_flush_talker", "1", FCVAR_NONE, "Normally, when a map with custom talker files is unloaded, the response system resets to rid itself of the custom file(s). Turn this convar off to prevent that from happening."); + +extern void MapbaseGameLog_Init(); + +extern void ParseCustomActbusyFile(const char *file); + +extern bool LoadResponseSystemFile(const char *scriptfile); +extern void ReloadResponseSystem(); + +// Reloads the response system when the map changes to avoid custom talker leaking +static bool g_bMapContainsCustomTalker; +#else +// This constant should change with each Mapbase update +ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" ); + +// This is from the vgui_controls library +extern vgui::HScheme g_iCustomClientSchemeOverride; + +bool g_bUsingCustomHudLayout = false; +#endif + +extern void AddSurfacepropFile( const char *pFileName, IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem ); + +// Indicates this is a core Mapbase mod and not a mod using its code. +static bool g_bMapbaseCore; + +// The game's name found in gameinfo.txt. Mostly used for Discord RPC. +char g_iszGameName[128]; + +#ifdef GAME_DLL +// Default player configuration +char g_szDefaultPlayerModel[MAX_PATH]; +bool g_bDefaultPlayerDrawExternally; + +char g_szDefaultHandsModel[MAX_PATH]; +int g_iDefaultHandsSkin; +int g_iDefaultHandsBody; +#endif + +enum +{ + MANIFEST_SOUNDSCRIPTS, + //MANIFEST_PROPDATA, + //MANIFEST_SOUNDSCAPES, + MANIFEST_LOCALIZATION, + MANIFEST_SURFACEPROPS, +#ifdef CLIENT_DLL + MANIFEST_CLOSECAPTION, + MANIFEST_VGUI, + MANIFEST_CLIENTSCHEME, + MANIFEST_HUDANIMATIONS, + MANIFEST_HUDLAYOUT, +#else + MANIFEST_TALKER, + //MANIFEST_SENTENCES, + MANIFEST_ACTBUSY, +#endif +#ifdef MAPBASE_VSCRIPT + MANIFEST_VSCRIPT, +#endif + + // Must always be kept below + MANIFEST_NUM_TYPES, +}; + +struct ManifestType_t +{ + ManifestType_t( const char *_string, const char *cvarname, const char *cvardesc ) : cvar( cvarname, "1", FCVAR_ARCHIVE, cvardesc ) + { + string = _string; + } + + //int type; + const char *string; + ConVar cvar; +}; + +#define DECLARE_MANIFEST_TYPE(name, cvar, desc) { #name, ConVar(#cvar, "1", FCVAR_ARCHIVE, #desc) } + +// KEEP THS IN SYNC WITH THE ENUM! +static const ManifestType_t gm_szManifestFileStrings[MANIFEST_NUM_TYPES] = { + { "soundscripts", "mapbase_load_soundscripts", "Should we load map-specific soundscripts? e.g. \"maps/_level_sounds.txt\"" }, + //{ "propdata", "mapbase_load_propdata", "Should we load map-specific soundscripts? e.g. \"maps/_level_sounds.txt\"" }, + //{ "soundscapes", "mapbase_load_soundscapes", "Should we load map-specific soundscapes? e.g. \"maps/_soundscapes.txt\"" }, + { "localization", "mapbase_load_localization", "Should we load map-specific localized text files? e.g. \"maps/_english.txt\"" }, + { "surfaceprops", "mapbase_load_surfaceprops", "Should we load map-specific surfaceproperties files? e.g. \"maps/_surfaceproperties.txt\"" }, +#ifdef CLIENT_DLL + { "closecaption", "mapbase_load_closecaption", "Should we load map-specific closed captioning? e.g. \"maps/_closecaption_english.txt\" and \"maps/_closecaption_english.dat\"" }, + { "vgui", "mapbase_load_vgui", "Should we load map-specific VGUI screens? e.g. \"maps/_screens.txt\"" }, + { "clientscheme", "mapbase_load_clientscheme", "Should we load map-specific ClientScheme.res overrides? e.g. \"maps/_clientscheme.res\"" }, + { "hudanimations", "mapbase_load_hudanimations", "Should we load map-specific HUD animation overrides? e.g. \"maps/_hudanimations.txt\"" }, + { "hudlayout", "mapbase_load_hudlayout", "Should we load map-specific HUD layout overrides? e.g. \"maps/_hudlayout.res\"" }, +#else + { "talker", "mapbase_load_talker", "Should we load map-specific talker files? e.g. \"maps/_talker.txt\"" }, + //{ "sentences", "mapbase_load_sentences", "Should we load map-specific sentences? e.g. \"maps/_sentences.txt\"" }, + { "actbusy", "mapbase_load_actbusy", "Should we load map-specific actbusy files? e.g. \"maps/_actbusy.txt\"" }, +#endif +#ifdef MAPBASE_VSCRIPT + { "vscript", "mapbase_load_vscript", "Should we load map-specific VScript map spawn files? e.g. \"maps/_mapspawn.nut\"" }, +#endif +}; + +//----------------------------------------------------------------------------- +// Purpose: System used to load map-specific files, etc. +//----------------------------------------------------------------------------- +class CMapbaseSystem : public CAutoGameSystem +{ +public: + DECLARE_DATADESC(); + + CMapbaseSystem() : CAutoGameSystem( "CMapbaseSystem" ) + { + } + + inline bool GetGameInfoKeyValues(KeyValues *pKeyValues) + { + return pKeyValues->LoadFromFile( filesystem, "gameinfo.txt", "MOD" ); + } + + virtual bool Init() + { + InitConsoleGroups( g_pFullFileSystem ); + + // Checks gameinfo.txt for additional command line options + KeyValues *gameinfo = new KeyValues("GameInfo"); + if (GetGameInfoKeyValues(gameinfo)) + { + KeyValues *pCommandLineList = gameinfo->FindKey("CommandLine", false); + if (pCommandLineList) + { + for (KeyValues *pKey = pCommandLineList->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) + { + CommandLine()->AppendParm( pKey->GetName(), pKey->GetString() ); + } + } + } + gameinfo->deleteThis(); + +#ifdef CLIENT_DLL + InitializeRTs(); +#endif + + return true; + } + + void RefreshCustomTalker() + { +#ifdef GAME_DLL + if (g_bMapContainsCustomTalker && mapbase_flush_talker.GetBool()) + { + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Mapbase: Reloading response system to flush custom talker\n" ); + ReloadResponseSystem(); + g_bMapContainsCustomTalker = false; + } +#endif + } + + virtual void LevelInitPreEntity() + { +#ifdef GAME_DLL + CGMsg( 0, CON_GROUP_MAPBASE_MISC, "Mapbase system loaded\n" ); +#endif + + // Checks gameinfo.txt for Mapbase-specific options + KeyValues *gameinfo = new KeyValues("GameInfo"); + if (GetGameInfoKeyValues(gameinfo)) + { + // Indicates this is a core Mapbase mod and not a mod using its code + g_bMapbaseCore = gameinfo->GetBool("mapbase_core", false); + + if (!gameinfo->GetBool("hide_mod_name", false)) + { + // Store the game's name + const char *pszGameName = gameinfo->GetString("game_rpc", NULL); + if (pszGameName == NULL) + pszGameName = gameinfo->GetString("game"); + + Q_strncpy(g_iszGameName, pszGameName, sizeof(g_iszGameName)); + } + +#ifdef GAME_DLL + Q_strncpy( g_szDefaultPlayerModel, gameinfo->GetString( "player_default_model", "models/player.mdl" ), sizeof( g_szDefaultPlayerModel ) ); + g_bDefaultPlayerDrawExternally = gameinfo->GetBool( "player_default_draw_externally", false ); + + Q_strncpy( g_szDefaultHandsModel, gameinfo->GetString( "player_default_hands", "models/weapons/v_hands.mdl" ), sizeof( g_szDefaultHandsModel ) ); + g_iDefaultHandsSkin = gameinfo->GetInt( "player_default_hands_skin", 0 ); + g_iDefaultHandsBody = gameinfo->GetInt( "player_default_hands_body", 0 ); +#endif + } + gameinfo->deleteThis(); + + RefreshMapName(); + + // Shared Mapbase scripts to avoid overwriting mod files + g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" ); +#ifdef CLIENT_DLL + PanelMetaClassMgr()->LoadMetaClassDefinitionFile( "scripts/vgui_screens_mapbase.txt" ); +#endif + } + + virtual void OnRestore() + { + RefreshMapName(); + } + + virtual void LevelInitPostEntity() + { + // Check for a generic "mapname_manifest.txt" file and load it. + if (filesystem->FileExists( AUTOLOADED_MANIFEST_FILE, "GAME" )) + { + AddManifestFile( AUTOLOADED_MANIFEST_FILE ); + } + else + { + // Load the generic script instead. + ParseGenericManifest(); + } + +#ifdef GAME_DLL + MapbaseGameLog_Init(); +#endif + } + + virtual void LevelShutdownPreEntity() + { + // How would we make sure they don't last between maps? + // TODO: Investigate ReloadLocalizationFiles() + //g_pVGuiLocalize->RemoveAll(); + //g_pVGuiLocalize->ReloadLocalizationFiles(); + } + + virtual void LevelShutdownPostEntity() + { + g_MapName = NULL; + + RefreshCustomTalker(); + +#ifdef CLIENT_DLL + CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption ); + FOR_EACH_VEC( m_CloseCaptionFileNames, i ) + { + hudCloseCaption->RemoveCaptionDictionary( m_CloseCaptionFileNames[i] ); + } + m_CloseCaptionFileNames.RemoveAll(); + + if (g_iCustomClientSchemeOverride != 0 || g_bUsingCustomHudAnimations || g_bUsingCustomHudLayout) + { + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Mapbase: Reloading client mode and viewport scheme\n" ); + + // TODO: We currently have no way of actually cleaning up custom schemes upon level unload. + // That may or may not be sustainable if there's a ton of custom schemes loaded at once + g_iCustomClientSchemeOverride = 0; + + g_bUsingCustomHudAnimations = false; + g_bUsingCustomHudLayout = false; + + // Reload scheme + ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); + if ( mode ) + { + mode->ReloadScheme(); + + // We need to reload default values, so load a special "hudlayout_mapbase.res" file that only contains + // default Mapbase definitions identical to the defaults in the code + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) + { + KeyValuesAD pConditions( "conditions" ); + g_pClientMode->ComputeVguiResConditions( pConditions ); + + // reload the .res file from disk + pViewport->LoadControlSettings( "scripts/hudlayout_mapbase.res", NULL, NULL, pConditions ); + } + } + } +#endif + } + + bool RefreshMapName() + { +#ifdef GAME_DLL + const char *pszMapName = STRING(gpGlobals->mapname); +#else + //char mapname[128]; + //Q_StripExtension(MapName(), mapname, sizeof(mapname)); + const char *pszMapName = MapName(); +#endif + + if (g_MapName == NULL || !FStrEq(pszMapName, g_MapName)) + { + g_MapName = pszMapName; + return true; + } + + return false; + } + +#ifdef CLIENT_DLL + //----------------------------------------------------------------------------- + // Initialize custom RT textures if necessary + //----------------------------------------------------------------------------- + void InitializeRTs() + { + if (!m_bInitializedRTs) + { + int iNumCameras = CommandLine()->ParmValue( "-numcameratextures", 3 ); + + materials->BeginRenderTargetAllocation(); + + for (int i = 0; i < iNumCameras; i++) + { + char szName[32]; + Q_snprintf( szName, sizeof(szName), "_rt_Camera%i", i ); + + int iRefIndex = m_CameraTextures.AddToTail(); + + //m_CameraTextures[iRefIndex].InitRenderTarget( + // 256, 256, RT_SIZE_DEFAULT, + // g_pMaterialSystem->GetBackBufferFormat(), + // MATERIAL_RT_DEPTH_SHARED, true, szName ); + + m_CameraTextures[iRefIndex].Init( g_pMaterialSystem->CreateNamedRenderTargetTextureEx2( + szName, + 256, 256, RT_SIZE_DEFAULT, + g_pMaterialSystem->GetBackBufferFormat(), + MATERIAL_RT_DEPTH_SHARED, + 0, + CREATERENDERTARGETFLAGS_HDR ) ); + } + + materials->EndRenderTargetAllocation(); + + m_bInitializedRTs = true; + } + } + + void Shutdown() + { + if (m_bInitializedRTs) + { + for (int i = 0; i < m_CameraTextures.Count(); i++) + { + m_CameraTextures[i].Shutdown(); + } + m_bInitializedRTs = false; + } + } +#endif + + // Get a generic, hardcoded manifest with hardcoded names. + void ParseGenericManifest() + { + if (!mapbase_load_default_manifest.GetBool()) + return; + + KeyValues *pKV = new KeyValues("DefaultManifest"); + pKV->LoadFromFile(filesystem, GENERIC_MANIFEST_FILE); + + AddManifestFile(pKV, g_MapName/*, true*/); + + pKV->deleteThis(); + } + + void AddManifestFile( const char *file ) + { + KeyValues *pKV = new KeyValues(file); + if ( !pKV->LoadFromFile( filesystem, file ) ) + { + Warning("Mapbase Manifest: \"%s\" is unreadable or missing (can't load KV, check for syntax errors)\n", file); + pKV->deleteThis(); + return; + } + + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "===== Mapbase Manifest: Loading manifest file %s =====\n", file ); + + AddManifestFile(pKV, g_MapName, false); + + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "==============================================================================\n" ); + + pKV->deleteThis(); + } + + void LoadFromValue( const char *value, int type, bool bDontWarn ) + { + if (type != MANIFEST_VSCRIPT && !filesystem->FileExists(value, "MOD")) + { + if (!bDontWarn) + { + Warning("Mapbase Manifest: WARNING! \"%s\" does not exist!\n", value); + } + return; + } + + switch (type) + { + case MANIFEST_SOUNDSCRIPTS: { soundemitterbase->AddSoundOverrides(value); } break; + //case MANIFEST_PROPDATA: { g_PropDataSystem.ParsePropDataFile(value); } break; + case MANIFEST_LOCALIZATION: { g_pVGuiLocalize->AddFile( value, "MOD", true ); } break; + case MANIFEST_SURFACEPROPS: { AddSurfacepropFile( value, physprops, filesystem ); } break; +#ifdef CLIENT_DLL + case MANIFEST_CLOSECAPTION: { ManifestLoadCustomCloseCaption( value ); } break; + case MANIFEST_VGUI: { PanelMetaClassMgr()->LoadMetaClassDefinitionFile( value ); } break; + case MANIFEST_CLIENTSCHEME: { ManifestLoadCustomScheme( value ); } break; + case MANIFEST_HUDANIMATIONS: { ManifestLoadCustomHudAnimations( value ); } break; + case MANIFEST_HUDLAYOUT: { ManifestLoadCustomHudLayout( value ); } break; + //case MANIFEST_SOUNDSCAPES: { Soundscape_AddFile(value); } break; +#else + case MANIFEST_TALKER: { + g_bMapContainsCustomTalker = true; + LoadResponseSystemFile(value); //PrecacheCustomResponseSystem( value ); + } break; + //case MANIFEST_SOUNDSCAPES: { g_SoundscapeSystem.AddSoundscapeFile(value); } break; + //case MANIFEST_SENTENCES: { engine->PrecacheSentenceFile(value); } break; + case MANIFEST_ACTBUSY: { ParseCustomActbusyFile(value); } break; +#endif +#ifdef MAPBASE_VSCRIPT + case MANIFEST_VSCRIPT: { VScriptRunScript(value, false); } break; +#endif + } + } + + // This doesn't call deleteThis()! + void AddManifestFile(KeyValues *pKV, const char *pszMapName, bool bDontWarn = false) + { + char value[MAX_PATH]; + const char *name; + for (KeyValues *pKey = pKV->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey()) + { + value[0] = '\0'; + name = pKey->GetName(); + + // Parse %mapname%, etc. + bool inparam = false; + CUtlStringList outStrings; + V_SplitString( pKey->GetString(), "%", outStrings ); + FOR_EACH_VEC( outStrings, i ) + { + if (inparam) + { + if (FStrEq( outStrings[i], "mapname" )) + { + Q_strncat( value, pszMapName, sizeof( value ) ); + } + else if (FStrEq( outStrings[i], "language" )) + { +#ifdef CLIENT_DLL + char uilanguage[64]; + engine->GetUILanguage(uilanguage, sizeof(uilanguage)); + Q_strncat( value, uilanguage, sizeof( value ) ); +#else + // Give up, use English + Q_strncat( value, "english", sizeof( value ) ); +#endif + } + } + else + { + Q_strncat( value, outStrings[i], sizeof( value ) ); + } + + inparam = !inparam; + } + + outStrings.PurgeAndDeleteElements(); + + if (FStrEq(name, "NoErrors")) + { + bDontWarn = pKey->GetBool(); + } + + for (int i = 0; i < MANIFEST_NUM_TYPES; i++) + { + if (FStrEq(name, gm_szManifestFileStrings[i].string)) + { + if (gm_szManifestFileStrings[i].cvar.GetBool()) + { + LoadFromValue(value, i, bDontWarn); + } + break; + } + } + } + } + +private: + +#ifdef CLIENT_DLL + void ManifestLoadCustomCloseCaption( const char *pszFile ) + { + if (GET_HUDELEMENT( CHudCloseCaption )) + (GET_HUDELEMENT( CHudCloseCaption ))->AddCustomCaptionFile( pszFile, m_CloseCaptionFileNames ); + } + + // Custom scheme loading + void ManifestLoadCustomScheme( const char *pszFile ) + { + g_iCustomClientSchemeOverride = vgui::scheme()->LoadSchemeFromFile( pszFile, "CustomClientScheme" ); + + // Reload scheme + ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); + if ( mode ) + { + mode->ReloadScheme(); + } + } + + void ManifestLoadCustomHudAnimations( const char *pszFile ) + { + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) + { + g_bUsingCustomHudAnimations = true; + if (!pViewport->LoadCustomHudAnimations( pszFile )) + { + g_bUsingCustomHudAnimations = false; + CGWarning( 0, CON_GROUP_MAPBASE_MISC, "Custom HUD animations file \"%s\" failed to load\n", pszFile ); + pViewport->ReloadHudAnimations(); + } + else + { + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Loaded custom HUD animations file \"%s\"\n", pszFile );; + } + } + } + + void ManifestLoadCustomHudLayout( const char *pszFile ) + { + CBaseViewport *pViewport = dynamic_cast(g_pClientMode->GetViewport()); + if (pViewport) + { + g_bUsingCustomHudLayout = true; + + KeyValuesAD pConditions( "conditions" ); + g_pClientMode->ComputeVguiResConditions( pConditions ); + + // reload the .res file from disk + pViewport->LoadControlSettings( pszFile, NULL, NULL, pConditions ); + + CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Loaded custom HUD layout file \"%s\"\n", pszFile );; + } + } +#endif + +public: + + void LoadCustomSoundscriptFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SOUNDSCRIPTS, false ); } + void LoadCustomLocalizationFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_LOCALIZATION, false ); } + void LoadCustomSurfacePropsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_SURFACEPROPS, false ); } +#ifdef CLIENT_DLL + void LoadCustomCloseCaptionFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLOSECAPTION, false ); } + void LoadCustomVGUIFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_VGUI, false ); } + void LoadCustomClientSchemeFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_CLIENTSCHEME, false ); } + void LoadCustomHUDAnimationsFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDANIMATIONS, false ); } + void LoadCustomHUDLayoutFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_HUDLAYOUT, false ); } +#else + void LoadCustomTalkerFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_TALKER, false ); } + void LoadCustomActbusyFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_ACTBUSY, false ); } +#endif + + const char *GetModName() { return g_iszGameName; } + bool IsCoreMapbase() { return g_bMapbaseCore; } + +#ifdef MAPBASE_VSCRIPT + void ScriptAddManifestFile( const char *szScript ) { AddManifestFile( szScript ); } + + virtual void RegisterVScript() + { + g_pScriptVM->RegisterInstance( this, "Mapbase" ); + } +#endif + +private: + +#ifdef CLIENT_DLL + bool m_bInitializedRTs = false; + CUtlVector m_CameraTextures; + + CUtlVector m_CloseCaptionFileNames; +#endif +}; + +CMapbaseSystem g_MapbaseSystem; + +BEGIN_DATADESC_NO_BASE( CMapbaseSystem ) + + //DEFINE_UTLVECTOR( m_StoredManifestFiles, FIELD_STRING ), + +END_DATADESC() + +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CMapbaseSystem, SCRIPT_SINGLETON "All-purpose Mapbase system primarily used for map-specific files." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddManifestFile, "AddManifestFile", "Loads a manifest file." ) + DEFINE_SCRIPTFUNC( LoadCustomSoundscriptFile, "Loads a custom soundscript file." ) + DEFINE_SCRIPTFUNC( LoadCustomLocalizationFile, "Loads a custom localization file." ) + DEFINE_SCRIPTFUNC( LoadCustomSurfacePropsFile, "Loads a custom surface properties file." ) +#ifdef CLIENT_DLL + DEFINE_SCRIPTFUNC( LoadCustomCloseCaptionFile, "Loads a custom closed captions file." ) + DEFINE_SCRIPTFUNC( LoadCustomVGUIFile, "Loads a custom VGUI definitions file." ) + DEFINE_SCRIPTFUNC( LoadCustomClientSchemeFile, "Loads a custom ClientScheme.res override file." ) + DEFINE_SCRIPTFUNC( LoadCustomHUDAnimationsFile, "Loads a custom HUD animations override file." ) + DEFINE_SCRIPTFUNC( LoadCustomHUDLayoutFile, "Loads a custom HUD layout override file." ) +#else + DEFINE_SCRIPTFUNC( LoadCustomTalkerFile, "Loads a custom talker file." ) + DEFINE_SCRIPTFUNC( LoadCustomActbusyFile, "Loads a custom actbusy file." ) +#endif + + DEFINE_SCRIPTFUNC( GetModName, "Gets the name of the mod. This is the name which shows up on Steam, RPC, etc." ) + DEFINE_SCRIPTFUNC( IsCoreMapbase, "Indicates whether this is one of the original Mapbase mods or just a separate mod using its code." ) + + // Legacy + DEFINE_SCRIPTFUNC_NAMED( LoadCustomSoundscriptFile, "LoadSoundscriptFile", SCRIPT_HIDE ) +#ifndef CLIENT_DLL + DEFINE_SCRIPTFUNC_NAMED( LoadCustomTalkerFile, "LoadTalkerFile", SCRIPT_HIDE ) + DEFINE_SCRIPTFUNC_NAMED( LoadCustomActbusyFile, "LoadActbusyFile", SCRIPT_HIDE ) +#endif + +END_SCRIPTDESC(); +#endif + +static void CC_Mapbase_LoadManifestFile( const CCommand& args ) +{ + g_MapbaseSystem.AddManifestFile(args[1]); +} + +#ifdef CLIENT_DLL +static ConCommand mapbase_loadmanifestfile("mapbase_loadmanifestfile_client", CC_Mapbase_LoadManifestFile, "Loads a Mapbase manifest file on the client. If you don't want this to be saved and found when reloaded, type a '1' after the file path." ); +#else +static ConCommand mapbase_loadmanifestfile("mapbase_loadmanifestfile", CC_Mapbase_LoadManifestFile, "Loads a Mapbase manifest file. If you don't want this to be saved and found when reloaded, type a '1' after the file path." ); +#endif + +#ifdef GAME_DLL +static CUtlVector g_MapbaseChapterMaps; +static CUtlVector g_MapbaseChapterList; +CUtlVector *Mapbase_GetChapterMaps() +{ + if (g_MapbaseChapterMaps.Count() == 0) + { + // Check the chapter list + KeyValues *chapterlist = new KeyValues("ChapterList"); + if (chapterlist->LoadFromFile(filesystem, "scripts/chapters.txt", "MOD")) + { + KeyValues *pKey = chapterlist->GetFirstSubKey(); + if (pKey) + { + if (Q_stricmp( pKey->GetName(), "Chapters" ) == 0) + { + for (KeyValues *pChapters = pKey->GetFirstSubKey(); pChapters; pChapters = pChapters->GetNextKey()) + { + int index = g_MapbaseChapterList.AddToTail(); + g_MapbaseChapterList[index].iChapter = atoi(pChapters->GetName()); + Q_strncpy(g_MapbaseChapterList[index].pChapterName, pChapters->GetString(), sizeof(g_MapbaseChapterList[index])); + } + } + + for (pKey = pKey->GetNextKey(); pKey; pKey = pKey->GetNextKey()) + { + int index = g_MapbaseChapterMaps.AddToTail(); + Q_strncpy(g_MapbaseChapterMaps[index].pBSPName, pKey->GetName(), sizeof(g_MapbaseChapterMaps[index].pBSPName)); + Q_strncpy(g_MapbaseChapterMaps[index].pTitleName, pKey->GetString(), sizeof(g_MapbaseChapterMaps[index].pTitleName)); + + //comment.pBSPName = pKey->GetName(); + //comment.pTitleName = pKey->GetString(); + } + } + } + chapterlist->deleteThis(); + } + + return &g_MapbaseChapterMaps; +} + +CUtlVector *Mapbase_GetChapterList() +{ + return &g_MapbaseChapterList; +} + +int Mapbase_GetChapterCount() +{ + return g_MapbaseChapterList.Count(); +} + +ThreeState_t Flashlight_GetLegacyVersionKey() +{ + KeyValues *gameinfo = new KeyValues( "GameInfo" ); + if (g_MapbaseSystem.GetGameInfoKeyValues( gameinfo )) + { + // -1 = default + int iUseLegacyFlashlight = gameinfo->GetInt( "use_legacy_flashlight", -1 ); + if (iUseLegacyFlashlight > -1) + return iUseLegacyFlashlight != 0 ? TRS_TRUE : TRS_FALSE; + } + gameinfo->deleteThis(); + + return TRS_NONE; +} + +#define SF_MANIFEST_START_ACTIVATED (1 << 0) + +class CMapbaseManifestEntity : public CPointEntity +{ +public: + DECLARE_DATADESC(); + + DECLARE_CLASS( CMapbaseManifestEntity, CPointEntity ); + + void Spawn( void ) + { + BaseClass::Spawn(); + if (HasSpawnFlags(SF_MANIFEST_START_ACTIVATED)) + { + LoadManifestFile(); + } + } + + void LoadManifestFile( void ) + { + const char *scriptfile = STRING(m_target); + if ( filesystem->FileExists( scriptfile, "MOD" ) ) + { + CGMsg(0, CON_GROUP_MAPBASE_MISC, "Mapbase: Adding manifest file \"%s\"\n", scriptfile); + g_MapbaseSystem.AddManifestFile(scriptfile); + } + else + { + Warning("Mapbase: Manifest file \"%s\" does not exist!", scriptfile); + } + } + + void InputActivate(inputdata_t &inputdata) + { + LoadManifestFile(); + } +}; + +LINK_ENTITY_TO_CLASS( mapbase_manifest, CMapbaseManifestEntity ); + +BEGIN_DATADESC( CMapbaseManifestEntity ) + + // Needs to be set up in the Activate methods of derived classes + //DEFINE_CUSTOM_FIELD( m_pInstancedResponseSystem, responseSystemSaveRestoreOps ), + + // Function Pointers + DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), + +END_DATADESC() +#endif + +//----------------------------------------------------------------------------- + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ); + +#ifdef CLIENT_DLL +ConVar con_group_include_name_client( "con_group_include_name_client", "0", FCVAR_NONE, "Includes groups when printing on the client.", CV_IncludeNameChanged ); + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + SetConsoleGroupIncludeNames( con_group_include_name_client.GetBool() ); +} +#else +ConVar con_group_include_name( "con_group_include_name", "0", FCVAR_NONE, "Includes groups when printing.", CV_IncludeNameChanged ); + +void CV_IncludeNameChanged( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + SetConsoleGroupIncludeNames( con_group_include_name.GetBool() ); +} +#endif + +CON_COMMAND_SHARED( con_group_reload, "Reloads all console groups." ) +{ + InitConsoleGroups( g_pFullFileSystem ); +} + +CON_COMMAND_SHARED( con_group_list, "Prints a list of all console groups." ) +{ + PrintAllConsoleGroups(); +} + +CON_COMMAND_SHARED( con_group_toggle, "Toggles a console group." ) +{ + ToggleConsoleGroups( args.Arg( 1 ) ); +} diff --git a/game/shared/mapbase/mapbase_usermessages.cpp b/game/shared/mapbase/mapbase_usermessages.cpp new file mode 100644 index 00000000..5af946e6 --- /dev/null +++ b/game/shared/mapbase/mapbase_usermessages.cpp @@ -0,0 +1,35 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase-specific user messages. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "usermessages.h" +#ifdef CLIENT_DLL +#include "hud_macros.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef CLIENT_DLL +void HookMapbaseUserMessages( void ) +{ + // VScript + //HOOK_MESSAGE( ScriptMsg ); // Hooked in CNetMsgScriptHelper +} +#endif + +void RegisterMapbaseUserMessages( void ) +{ + // VScript + usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper + +#ifdef CLIENT_DLL + // TODO: Better placement? + HookMapbaseUserMessages(); +#endif +} diff --git a/game/shared/mapbase/matchers.cpp b/game/shared/mapbase/matchers.cpp new file mode 100644 index 00000000..b8b915f4 --- /dev/null +++ b/game/shared/mapbase/matchers.cpp @@ -0,0 +1,54 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: General matching functions for things like wildcards and !=. +// +// $NoKeywords: $ +//============================================================================= + +#include "cbase.h" + +#include "matchers.h" +#include "fmtstr.h" + +#ifdef CLIENT_DLL +// FIXME: There is no clientside equivalent to the RS code +static bool ResponseSystemCompare(const char *criterion, const char *value) { return Matcher_NamesMatch(criterion, value); } +#else +extern bool ResponseSystemCompare(const char *criterion, const char *value); +#endif + +//============================================================================= +// These are the "matchers" that compare with wildcards ("any*" for text starting with "any") +// and operators (<3 for numbers less than 3). +// +// Matcher_Match - Matching function using RS operators and NamesMatch wildcards/regex. +// Matcher_Regex - Uses regex functions from the std library. +// Matcher_NamesMatch - Based on Valve's original NamesMatch function, using wildcards and regex. +// +// AppearsToBeANumber - Response System-based function which checks if the string might be a number. +//============================================================================= + +bool Matcher_Match(const char *pszQuery, const char *szValue) +{ + // I wasn't kidding when I said all this did was hijack response system matching. + return ResponseSystemCompare(pszQuery, szValue); +} + +bool Matcher_Match(const char *pszQuery, int iValue) { return Matcher_Match(pszQuery, CNumStr(iValue)); } +bool Matcher_Match(const char *pszQuery, float flValue) { return Matcher_Match(pszQuery, CNumStr(flValue)); } + +// Matcher_Compare is a deprecated alias originally used when Matcher_Match didn't support wildcards. +/* +bool Matcher_Compare(const char *pszQuery, const char *szValue) +{ + return Matcher_Match(pszQuery, szValue); +#if 0 + // I have to do this so wildcards could test *before* the response system comparison. + // I know it removes the operators twice, but I won't worry about it. + bool match = Matcher_NamesMatch(Matcher_RemoveOperators(pszQuery), szValue); + if (match) + return Matcher_Match(pszQuery, szValue); + return false; +#endif +} +*/ diff --git a/game/shared/mapbase/matchers.h b/game/shared/mapbase/matchers.h new file mode 100644 index 00000000..7d86ad63 --- /dev/null +++ b/game/shared/mapbase/matchers.h @@ -0,0 +1,27 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: General matching functions for things like wildcards and !=. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef MAPBASE_MATCHERS_H +#define MAPBASE_MATCHERS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/mapbase_matchers_base.h" + +// Compares with != and the like. Basically hijacks the response system matching. +// This also loops back around to Matcher_NamesMatch. +// pszQuery = The value that should have the operator(s) at the beginning. +// szValue = The value tested against the criterion. +bool Matcher_Match( const char *pszQuery, const char *szValue ); +bool Matcher_Match( const char *pszQuery, int iValue ); +bool Matcher_Match( const char *pszQuery, float flValue ); + +// Deprecated; do not use +//static inline bool Matcher_Compare( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); } + +#endif diff --git a/game/shared/mapbase/singleplayer_animstate.cpp b/game/shared/mapbase/singleplayer_animstate.cpp new file mode 100644 index 00000000..7c8b92c9 --- /dev/null +++ b/game/shared/mapbase/singleplayer_animstate.cpp @@ -0,0 +1,669 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Single Player animation state 'handler'. This utility is used +// to evaluate the pose parameter value based on the direction +// and speed of the player. +// +// ------------------------------------------------------------------------------ +// +// This was originally based on the following VDC article: +// https://developer.valvesoftware.com/wiki/Fixing_the_player_animation_state_(Single_Player) +// +// It has been modified by Blixibon to derive from CBasePlayerAnimState instead and support 9-way blends. +// Much of the work done to make this derive from CBasePlayerAnimState utilized code from the Alien Swarm SDK. +// +//=============================================================================// + +#include "cbase.h" +#include "singleplayer_animstate.h" +#include "tier0/vprof.h" +#include "animation.h" +#include "studio.h" +#include "apparent_velocity_helper.h" +#include "utldict.h" +#include "filesystem.h" +#include "in_buttons.h" +#include "datacache/imdlcache.h" + +extern ConVar mp_facefronttime, mp_feetyawrate, mp_ik; + +ConVar sv_playeranimstate_animtype( "sv_playeranimstate_animtype", "0", FCVAR_NONE, "The leg animation type used by the singleplayer animation state. 9way = 0, 8way = 1, GoldSrc = 2" ); +ConVar sv_playeranimstate_bodyyaw( "sv_playeranimstate_bodyyaw", "45.0", FCVAR_NONE, "The maximum body yaw used by the singleplayer animation state." ); +ConVar sv_playeranimstate_use_aim_sequences( "sv_playeranimstate_use_aim_sequences", "1", FCVAR_NONE, "Allows the singleplayer animation state to use aim sequences." ); + +#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f + +#define FIRESEQUENCE_LAYER (AIMSEQUENCE_LAYER+NUM_AIMSEQUENCE_LAYERS) +#define RELOADSEQUENCE_LAYER (FIRESEQUENCE_LAYER + 1) +#define NUM_LAYERS_WANTED (RELOADSEQUENCE_LAYER + 1) + +CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer ) +{ + MDLCACHE_CRITICAL_SECTION(); + + CSinglePlayerAnimState *pState = new CSinglePlayerAnimState( pPlayer ); + + // Setup the movement data. + CModAnimConfig movementData; + movementData.m_LegAnimType = (LegAnimType_t)sv_playeranimstate_animtype.GetInt(); + movementData.m_flMaxBodyYawDegrees = sv_playeranimstate_bodyyaw.GetFloat(); + movementData.m_bUseAimSequences = sv_playeranimstate_use_aim_sequences.GetBool(); + + pState->Init( pPlayer, movementData ); + + return pState; +} + +// Below this many degrees, slow down turning rate linearly +#define FADE_TURN_DEGREES 45.0f +// After this, need to start turning feet +#define MAX_TORSO_ANGLE 90.0f +// Below this amount, don't play a turning animation/perform IK +#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f + +//static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." ); +extern ConVar sv_backspeed; +extern ConVar mp_feetyawrate; +extern ConVar mp_facefronttime; +extern ConVar mp_ik; + +CSinglePlayerAnimState::CSinglePlayerAnimState( CBasePlayer *pPlayer ): m_pPlayer( pPlayer ) +{ +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CSinglePlayerAnimState::CalcMainActivity() +{ +#ifdef CLIENT_DLL + return ACT_IDLE; +#else + float speed = GetOuter()->GetAbsVelocity().Length2D(); + + if ( HandleJumping() ) + { + return ACT_HL2MP_JUMP; + } + else + { + Activity idealActivity = ACT_HL2MP_IDLE; + + if ( GetOuter()->GetFlags() & ( FL_FROZEN | FL_ATCONTROLS ) ) + { + speed = 0; + } + else + { + if ( GetOuter()->GetFlags() & FL_DUCKING ) + { + if ( speed > 0 ) + { + idealActivity = ACT_HL2MP_WALK_CROUCH; + } + else + { + idealActivity = ACT_HL2MP_IDLE_CROUCH; + } + } + else + { + if ( speed > 0 ) + { +#if EXPANDED_HL2DM_ACTIVITIES + if ( m_pPlayer->GetButtons() & IN_WALK ) + { + idealActivity = ACT_HL2MP_WALK; + } + else +#endif + { + idealActivity = ACT_HL2MP_RUN; + } + } + else + { + idealActivity = ACT_HL2MP_IDLE; + } + } + } + + return idealActivity; + } + + //return m_pPlayer->GetActivity(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim ) +{ + if ( playerAnim == PLAYER_ATTACK1 ) + { + m_iFireSequence = SelectWeightedSequence( TranslateActivity( ACT_HL2MP_GESTURE_RANGE_ATTACK ) ); + m_bFiring = m_iFireSequence != -1; + m_flFireCycle = 0; + } + else if ( playerAnim == PLAYER_ATTACK2 ) + { +#if EXPANDED_HL2DM_ACTIVITIES + m_iFireSequence = SelectWeightedSequence( TranslateActivity( ACT_HL2MP_GESTURE_RANGE_ATTACK2 ) ); +#else + m_iFireSequence = SelectWeightedSequence( TranslateActivity( ACT_HL2MP_GESTURE_RANGE_ATTACK ) ); +#endif + m_bFiring = m_iFireSequence != -1; + m_flFireCycle = 0; + } + else if ( playerAnim == PLAYER_JUMP ) + { + // Play the jump animation. + if (!m_bJumping) + { + m_bJumping = true; + m_bFirstJumpFrame = true; + m_flJumpStartTime = gpGlobals->curtime; + } + } + else if ( playerAnim == PLAYER_RELOAD ) + { + m_iReloadSequence = SelectWeightedSequence( TranslateActivity( ACT_HL2MP_GESTURE_RELOAD ) ); + if (m_iReloadSequence != -1) + { + // clear other events that might be playing in our layer + m_bWeaponSwitching = false; + m_fReloadPlaybackRate = 1.0f; + m_bReloading = true; + m_flReloadCycle = 0; + } + } + else if ( playerAnim == PLAYER_UNHOLSTER || playerAnim == PLAYER_HOLSTER ) + { + m_iWeaponSwitchSequence = SelectWeightedSequence( TranslateActivity( playerAnim == PLAYER_UNHOLSTER ? ACT_ARM : ACT_DISARM ) ); + if (m_iWeaponSwitchSequence != -1) + { + // clear other events that might be playing in our layer + m_bPlayingMisc = false; + m_bReloading = false; + + m_bWeaponSwitching = true; + m_flWeaponSwitchCycle = 0; + m_flMiscBlendOut = 0.1f; + m_flMiscBlendIn = 0.1f; + m_bMiscNoOverride = false; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Activity CSinglePlayerAnimState::TranslateActivity( Activity actDesired ) +{ +#ifdef CLIENT_DLL + return actDesired; +#else + return m_pPlayer->Weapon_TranslateActivity( actDesired ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CSinglePlayerAnimState::HandleJumping() +{ + if ( m_bJumping ) + { + if ( m_bFirstJumpFrame ) + { + m_bFirstJumpFrame = false; + RestartMainSequence(); // Reset the animation. + } + + // Don't check if he's on the ground for a sec.. sometimes the client still has the + // on-ground flag set right when the message comes in. + if (m_flJumpStartTime > gpGlobals->curtime) + m_flJumpStartTime = gpGlobals->curtime; + if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f) + { + if ( m_pOuter->GetFlags() & FL_ONGROUND || GetOuter()->GetGroundEntity() != NULL) + { + m_bJumping = false; + RestartMainSequence(); // Reset the animation. + } + } + } + + // Are we still jumping? If so, keep playing the jump animation. + return m_bJumping; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr ) +{ + CBasePlayerAnimState::ComputeSequences(pStudioHdr); + + ComputeFireSequence(); + ComputeMiscSequence(); + ComputeReloadSequence(); + ComputeWeaponSwitchSequence(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::AddMiscSequence( int iSequence, float flBlendIn, float flBlendOut, float flPlaybackRate, bool bHoldAtEnd, bool bOnlyWhenStill ) +{ + Assert( iSequence != -1 ); + + m_iMiscSequence = iSequence; + m_flMiscBlendIn = flBlendIn; + m_flMiscBlendOut = flBlendOut; + + m_bPlayingMisc = true; + m_bMiscHoldAtEnd = bHoldAtEnd; + m_bReloading = false; + m_flMiscCycle = 0; + m_bMiscOnlyWhenStill = bOnlyWhenStill; + m_bMiscNoOverride = true; + m_fMiscPlaybackRate = flPlaybackRate; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ClearAnimationState() +{ + m_bJumping = false; + m_bFiring = false; + m_bReloading = false; + m_bWeaponSwitching = false; + m_bPlayingMisc = false; + m_flReloadBlendIn = 0.0f; + m_flReloadBlendOut = 0.0f; + m_flMiscBlendIn = 0.0f; + m_flMiscBlendOut = 0.0f; + CBasePlayerAnimState::ClearAnimationState(); +} + +void CSinglePlayerAnimState::ClearAnimationLayers() +{ + VPROF( "CBasePlayerAnimState::ClearAnimationLayers" ); + if ( !m_pOuter ) + return; + + m_pOuter->SetNumAnimOverlays( NUM_LAYERS_WANTED ); + for ( int i=0; i < m_pOuter->GetNumAnimOverlays(); i++ ) + { + m_pOuter->GetAnimOverlay( i )->SetOrder( CBaseAnimatingOverlay::MAX_OVERLAYS ); +#ifndef CLIENT_DLL + m_pOuter->GetAnimOverlay( i )->m_fFlags = 0; +#endif + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CSinglePlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle ) +{ + // TODO? + return m_pOuter->LookupSequence( "soldier_Aim_9_directions" ); +} + +void CSinglePlayerAnimState::UpdateLayerSequenceGeneric( int iLayer, bool &bEnabled, + float &flCurCycle, int &iSequence, bool bWaitAtEnd, + float fBlendIn, float fBlendOut, bool bMoveBlend, float fPlaybackRate, bool bUpdateCycle /* = true */ ) +{ + if ( !bEnabled ) + return; + + CStudioHdr *hdr = GetOuter()->GetModelPtr(); + if ( !hdr ) + return; + + if ( iSequence < 0 || iSequence >= hdr->GetNumSeq() ) + return; + + // Increment the fire sequence's cycle. + if ( bUpdateCycle ) + { + flCurCycle += m_pOuter->GetSequenceCycleRate( hdr, iSequence ) * gpGlobals->frametime * fPlaybackRate; + } + + // temp: if the sequence is looping, don't override it - we need better handling of looping anims, + // especially in misc layer from melee (right now the same melee attack is looped manually in asw_melee_system.cpp) + bool bLooping = m_pOuter->IsSequenceLooping( hdr, iSequence ); + + if ( flCurCycle > 1 && !bLooping ) + { + if ( iLayer == RELOADSEQUENCE_LAYER ) + { + m_bReloading = false; + } + if ( bWaitAtEnd ) + { + flCurCycle = 1; + } + else + { + // Not firing anymore. + bEnabled = false; + iSequence = 0; + return; + } + } + + // if this animation should blend out as we move, then check for dropping it completely since we're moving too fast + float speed = 0; + if (bMoveBlend) + { + Vector vel; + GetOuterAbsVelocity( vel ); + + float speed = vel.Length2D(); + + if (speed > 50) + { + bEnabled = false; + iSequence = 0; + return; + } + } + + // Now dump the state into its animation layer. + CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( iLayer ); + + pLayer->m_flCycle = flCurCycle; + pLayer->m_nSequence = iSequence; + + pLayer->m_flPlaybackRate = fPlaybackRate; + pLayer->m_flWeight = 1.0f; + + if (iLayer == RELOADSEQUENCE_LAYER) + { + // blend this layer in and out for smooth reloading + if (flCurCycle < fBlendIn && fBlendIn>0) + { + pLayer->m_flWeight = ( clamp(flCurCycle / fBlendIn, + 0.001f, 1.0f) ); + } + else if (flCurCycle >= (1.0f - fBlendOut) && fBlendOut>0) + { + pLayer->m_flWeight = ( clamp((1.0f - flCurCycle) / fBlendOut, + 0.001f, 1.0f) ); + } + else + { + pLayer->m_flWeight = 1.0f; + } + } + else + { + pLayer->m_flWeight = 1.0f; + } + if (bMoveBlend) + { + // blend the animation out as we move faster + if (speed <= 50) + pLayer->m_flWeight = ( pLayer->m_flWeight * (50.0f - speed) / 50.0f ); + } + +#ifndef CLIENT_DLL + pLayer->m_fFlags |= ANIM_LAYER_ACTIVE; +#endif + pLayer->SetOrder( iLayer ); +} + +void CSinglePlayerAnimState::ComputeFireSequence() +{ + UpdateLayerSequenceGeneric( FIRESEQUENCE_LAYER, m_bFiring, m_flFireCycle, m_iFireSequence, false ); +} + +void CSinglePlayerAnimState::ComputeReloadSequence() +{ + UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bReloading, m_flReloadCycle, m_iReloadSequence, false, m_flReloadBlendIn, m_flReloadBlendOut, false, m_fReloadPlaybackRate ); +} + +void CSinglePlayerAnimState::ComputeWeaponSwitchSequence() +{ + UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bWeaponSwitching, m_flWeaponSwitchCycle, m_iWeaponSwitchSequence, false, 0, 0.5f ); +} + +// does misc gestures if we're not firing +void CSinglePlayerAnimState::ComputeMiscSequence() +{ + UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bPlayingMisc, m_flMiscCycle, m_iMiscSequence, m_bMiscHoldAtEnd, m_flMiscBlendIn, m_flMiscBlendOut, m_bMiscOnlyWhenStill, m_fMiscPlaybackRate ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : - +// Output : float +//----------------------------------------------------------------------------- +float CSinglePlayerAnimState::GetCurrentMaxGroundSpeed() +{ + CStudioHdr *pStudioHdr = GetOuter()->GetModelPtr(); + + if ( pStudioHdr == NULL ) + return 1.0f; + + int iMoveX = GetOuter()->LookupPoseParameter( "move_x" ); + int iMoveY = GetOuter()->LookupPoseParameter( "move_y" ); + + float prevX = GetOuter()->GetPoseParameter( iMoveX ); + float prevY = GetOuter()->GetPoseParameter( iMoveY ); + + float d = MAX( fabs( prevX ), fabs( prevY ) ); + float newX, newY; + if ( d == 0.0 ) + { + newX = 1.0; + newY = 0.0; + } + else + { + newX = prevX / d; + newY = prevY / d; + } + + GetOuter()->SetPoseParameter( pStudioHdr, iMoveX, newX ); + GetOuter()->SetPoseParameter( pStudioHdr, iMoveY, newY ); + + float speed = GetOuter()->GetSequenceGroundSpeed(GetOuter()->GetSequence() ); + + GetOuter()->SetPoseParameter( pStudioHdr, iMoveX, prevX ); + GetOuter()->SetPoseParameter( pStudioHdr, iMoveY, prevY ); + + return speed; +} + +//----------------------------------------------------------------------------- +// Purpose: Override for backpeddling +// Input : dt - +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_BodyYaw( void ) +{ + CBasePlayerAnimState::ComputePoseParam_BodyYaw(); + + //ComputePoseParam_BodyLookYaw(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw( void ) +{ + // See if we even have a blender for pitch + int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" ); + if ( upper_body_yaw < 0 ) + { + return; + } + + // Assume upper and lower bodies are aligned and that we're not turning + float flGoalTorsoYaw = 0.0f; + int turning = TURN_NONE; + float turnrate = 360.0f; + + Vector vel; + + GetOuterAbsVelocity( vel ); + + bool isMoving = ( vel.Length() > 1.0f ) ? true : false; + + if ( !isMoving ) + { + // Just stopped moving, try and clamp feet + if ( m_flLastTurnTime <= 0.0f ) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetOuter()->EyeAngles().y; + // Snap feet to be perfectly aligned with torso/eyes + m_flGoalFeetYaw = GetOuter()->EyeAngles().y; + m_flCurrentFeetYaw = m_flGoalFeetYaw; + m_nTurningInPlace = TURN_NONE; + } + + // If rotating in place, update stasis timer + + if ( m_flLastYaw != GetOuter()->EyeAngles().y ) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetOuter()->EyeAngles().y; + } + + if ( m_flGoalFeetYaw != m_flCurrentFeetYaw ) + { + m_flLastTurnTime = gpGlobals->curtime; + } + + turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, m_AnimConfig.m_flMaxBodyYawDegrees, gpGlobals->frametime, m_flCurrentFeetYaw ); + + QAngle eyeAngles = GetOuter()->EyeAngles(); + QAngle vAngle = GetOuter()->GetLocalAngles(); + + // See how far off current feetyaw is from true yaw + float yawdelta = GetOuter()->EyeAngles().y - m_flCurrentFeetYaw; + yawdelta = AngleNormalize( yawdelta ); + + bool rotated_too_far = false; + + float yawmagnitude = fabs( yawdelta ); + + // If too far, then need to turn in place + if ( yawmagnitude > 45 ) + { + rotated_too_far = true; + } + + // Standing still for a while, rotate feet around to face forward + // Or rotated too far + // FIXME: Play an in place turning animation + if ( rotated_too_far || + ( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) ) + { + m_flGoalFeetYaw = GetOuter()->EyeAngles().y; + m_flLastTurnTime = gpGlobals->curtime; + + /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw; + if ( yd > 0 ) + { + m_nTurningInPlace = TURN_RIGHT; + } + else if ( yd < 0 ) + { + m_nTurningInPlace = TURN_LEFT; + } + else + { + m_nTurningInPlace = TURN_NONE; + } + + turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); + yawdelta = GetOuter()->EyeAngles().y - m_flCurrentFeetYaw;*/ + + } + + // Snap upper body into position since the delta is already smoothed for the feet + flGoalTorsoYaw = yawdelta; + m_flCurrentTorsoYaw = flGoalTorsoYaw; + } + else + { + m_flLastTurnTime = 0.0f; + m_nTurningInPlace = TURN_NONE; + m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->EyeAngles().y; + flGoalTorsoYaw = 0.0f; + m_flCurrentTorsoYaw = GetOuter()->EyeAngles().y - m_flCurrentFeetYaw; + } + + if ( turning == TURN_NONE ) + { + m_nTurningInPlace = turning; + } + + if ( m_nTurningInPlace != TURN_NONE ) + { + // If we're close to finishing the turn, then turn off the turning animation + if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION ) + { + m_nTurningInPlace = TURN_NONE; + } + } + + GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) ); + + /* + // FIXME: Adrian, what is this? + int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" ); + + if ( body_yaw >= 0 ) + { + GetOuter()->SetPoseParameter( body_yaw, 30 ); + } + */ + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr ) +{ + // Get pitch from v_angle + float flPitch = m_flEyePitch; + + if ( flPitch > 180.0f ) + { + flPitch -= 360.0f; + } + flPitch = clamp( flPitch, -90, 90 ); + + // See if we have a blender for pitch + GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch ); + + ComputePoseParam_HeadPitch( pStudioHdr ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr ) +{ + // Get pitch from v_angle + int iHeadPitch = GetOuter()->LookupPoseParameter("head_pitch"); + + float flPitch = m_flEyePitch; + + if ( flPitch > 180.0f ) + { + flPitch -= 360.0f; + } + flPitch = clamp( flPitch, -90, 90 ); + + GetOuter()->SetPoseParameter( pStudioHdr, iHeadPitch, flPitch ); +} diff --git a/game/shared/mapbase/singleplayer_animstate.h b/game/shared/mapbase/singleplayer_animstate.h new file mode 100644 index 00000000..a805dffc --- /dev/null +++ b/game/shared/mapbase/singleplayer_animstate.h @@ -0,0 +1,110 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Single Player animation state 'handler'. This utility is used +// to evaluate the pose parameter value based on the direction +// and speed of the player. +// +// ------------------------------------------------------------------------------ +// +// This was originally based on the following VDC article: +// https://developer.valvesoftware.com/wiki/Fixing_the_player_animation_state_(Single_Player) +// +// It has been modified by Blixibon to derive from CBasePlayerAnimState instead and support 9-way blends. +// Much of the work done to make this derive from CBasePlayerAnimState utilized code from the Alien Swarm SDK. +// +//=============================================================================// + +#ifndef SINGLEPLAYER_ANIMSTATE_H +#define SINGLEPLAYER_ANIMSTATE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "cbase.h" +#include "base_playeranimstate.h" + +#ifdef CLIENT_DLL +#include "c_baseplayer.h" +#else +#include "player.h" +#endif + +#ifdef MAPBASE +// Special definition for differentiating between SP and HL2:DM anim states +#define SP_ANIM_STATE 1 +#endif + +class CSinglePlayerAnimState : public CBasePlayerAnimState +{ +public: + CSinglePlayerAnimState( CBasePlayer *pPlayer ); + + Activity CalcMainActivity(); + int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle ); + float GetCurrentMaxGroundSpeed(); + + void SetPlayerAnimation( PLAYER_ANIM playerAnim ); + Activity TranslateActivity( Activity actDesired ); + + void ComputeSequences( CStudioHdr *pStudioHdr ); + + void AddMiscSequence( int iSequence, float flBlendIn = 0.0f, float flBlendOut = 0.0f, float flPlaybackRate = 1.0f, bool bHoldAtEnd = false, bool bOnlyWhenStill = false ); + + void ClearAnimationState(); + void ClearAnimationLayers(); + +private: + + bool HandleJumping(); + + void ComputeFireSequence(); + void ComputeReloadSequence(); + void ComputeWeaponSwitchSequence(); + void ComputeMiscSequence(); + + void UpdateLayerSequenceGeneric( int iLayer, bool &bEnabled, float &flCurCycle, + int &iSequence, bool bWaitAtEnd, + float fBlendIn=0.15f, float fBlendOut=0.15f, bool bMoveBlend = false, + float fPlaybackRate=1.0f, bool bUpdateCycle = true ); + + void ComputePoseParam_BodyYaw( void ); + void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr ); + void ComputePoseParam_BodyLookYaw( void ); + void ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr ); + + CBasePlayer* m_pPlayer; + + // Current state variables. + bool m_bJumping; // Set on a jump event. + float m_flJumpStartTime; + bool m_bFirstJumpFrame; + + // Aim sequence plays reload while this is on. + bool m_bReloading; + float m_flReloadCycle; + int m_iReloadSequence; + float m_flReloadBlendOut, m_flReloadBlendIn; + float m_fReloadPlaybackRate; + + bool m_bWeaponSwitching; + float m_flWeaponSwitchCycle; + int m_iWeaponSwitchSequence; + + bool m_bPlayingMisc; + float m_flMiscCycle, m_flMiscBlendOut, m_flMiscBlendIn; + int m_iMiscSequence; + bool m_bMiscOnlyWhenStill, m_bMiscHoldAtEnd; + bool m_bMiscNoOverride; + float m_fMiscPlaybackRate; + bool m_bMiscCycleRewound; + float m_flMiscRewindCycle; + // This is set to true if ANY animation is being played in the fire layer. + bool m_bFiring; // If this is on, then it'll continue the fire animation in the fire layer + // until it completes. + int m_iFireSequence; // (For any sequences in the fire layer, including grenade throw). + float m_flFireCycle; +}; + +CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer ); + +#endif // SINGLEPLAYER_ANIMSTATE_H diff --git a/game/shared/mapbase/vscript_consts_shared.cpp b/game/shared/mapbase/vscript_consts_shared.cpp new file mode 100644 index 00000000..d7e496cd --- /dev/null +++ b/game/shared/mapbase/vscript_consts_shared.cpp @@ -0,0 +1,624 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript constants and enums shared between the server and client. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "activitylist.h" +#include "in_buttons.h" +#include "rope_shared.h" +#include "eventlist.h" +#ifdef CLIENT_DLL +#include "c_ai_basenpc.h" +#else +#include "ai_basenpc.h" +#include "globalstate.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//============================================================================= +//============================================================================= + +BEGIN_SCRIPTENUM( IN, "Button mask bindings" ) + + DEFINE_ENUMCONST_NAMED( IN_ATTACK, "ATTACK", "Button for +attack" ) + DEFINE_ENUMCONST_NAMED( IN_JUMP, "JUMP", "Button for +jump" ) + DEFINE_ENUMCONST_NAMED( IN_DUCK, "DUCK", "Button for +duck" ) + DEFINE_ENUMCONST_NAMED( IN_FORWARD, "FORWARD", "Button for +forward" ) + DEFINE_ENUMCONST_NAMED( IN_BACK, "BACK", "Button for +back" ) + DEFINE_ENUMCONST_NAMED( IN_USE, "USE", "Button for +use" ) + DEFINE_ENUMCONST_NAMED( IN_CANCEL, "CANCEL", "Special button flag for attack cancel" ) + DEFINE_ENUMCONST_NAMED( IN_LEFT, "LEFT", "Button for +left" ) + DEFINE_ENUMCONST_NAMED( IN_RIGHT, "RIGHT", "Button for +right" ) + DEFINE_ENUMCONST_NAMED( IN_MOVELEFT, "MOVELEFT", "Button for +moveleft" ) + DEFINE_ENUMCONST_NAMED( IN_MOVERIGHT, "MOVERIGHT", "Button for +moveright" ) + DEFINE_ENUMCONST_NAMED( IN_ATTACK2, "ATTACK2", "Button for +attack2" ) + DEFINE_ENUMCONST_NAMED( IN_RUN, "RUN", "Unused button (see IN.SPEED for sprint)" ) + DEFINE_ENUMCONST_NAMED( IN_RELOAD, "RELOAD", "Button for +reload" ) + DEFINE_ENUMCONST_NAMED( IN_ALT1, "ALT1", "Button for +alt1" ) + DEFINE_ENUMCONST_NAMED( IN_ALT2, "ALT2", "Button for +alt2" ) + DEFINE_ENUMCONST_NAMED( IN_SCORE, "SCORE", "Button for +score" ) + DEFINE_ENUMCONST_NAMED( IN_SPEED, "SPEED", "Button for +speed" ) + DEFINE_ENUMCONST_NAMED( IN_WALK, "WALK", "Button for +walk" ) + DEFINE_ENUMCONST_NAMED( IN_ZOOM, "ZOOM", "Button for +zoom" ) + DEFINE_ENUMCONST_NAMED( IN_WEAPON1, "WEAPON1", "Special button used by weapons themselves" ) + DEFINE_ENUMCONST_NAMED( IN_WEAPON2, "WEAPON2", "Special button used by weapons themselves" ) + DEFINE_ENUMCONST_NAMED( IN_BULLRUSH, "BULLRUSH", "Unused button" ) + DEFINE_ENUMCONST_NAMED( IN_GRENADE1, "GRENADE1", "Button for +grenade1" ) + DEFINE_ENUMCONST_NAMED( IN_GRENADE2, "GRENADE2", "Button for +grenade2" ) + DEFINE_ENUMCONST_NAMED( IN_ATTACK3, "ATTACK3", "Button for +attack3" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + +BEGIN_SCRIPTENUM( RenderMode, "Render modes used by Get/SetRenderMode" ) + + DEFINE_ENUMCONST_NAMED( kRenderNormal, "Normal", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransColor, "Color", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransTexture, "Texture", "" ) + DEFINE_ENUMCONST_NAMED( kRenderGlow, "Glow", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransAlpha, "Solid", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransAdd, "Additive", "" ) + DEFINE_ENUMCONST_NAMED( kRenderEnvironmental, "Environmental", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransAddFrameBlend, "AdditiveFractionalFrame", "" ) + DEFINE_ENUMCONST_NAMED( kRenderTransAlphaAdd, "AlphaAdd", "" ) + DEFINE_ENUMCONST_NAMED( kRenderWorldGlow, "WorldSpaceGlow", "" ) + DEFINE_ENUMCONST_NAMED( kRenderNone, "None", "" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + +BEGIN_SCRIPTENUM( Hitgroup, "Hit groups from traces" ) + + DEFINE_ENUMCONST_NAMED( HITGROUP_GENERIC, "Generic", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_HEAD, "Head", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_CHEST, "Chest", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_STOMACH, "Stomach", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_LEFTARM, "LeftArm", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_RIGHTARM, "RightArm", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_LEFTLEG, "LeftLeg", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_RIGHTLEG, "RightLeg", "" ) + DEFINE_ENUMCONST_NAMED( HITGROUP_GEAR, "Gear", "" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + +BEGIN_SCRIPTENUM( MapLoad, "Map load enum for GetLoadType()" ) + + DEFINE_ENUMCONST_NAMED( MapLoad_NewGame, "NewGame", "Map was loaded from a new game" ) + DEFINE_ENUMCONST_NAMED( MapLoad_LoadGame, "LoadGame", "Map was loaded from a save file" ) + DEFINE_ENUMCONST_NAMED( MapLoad_Transition, "Transition", "Map was loaded from a level transition" ) + DEFINE_ENUMCONST_NAMED( MapLoad_Background, "Background", "Map was loaded as a background map" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + +void RegisterActivityConstants() +{ + // Make sure there are no activities declared yet + if (g_pScriptVM->ValueExists( "ACT_RESET" )) + return; + + // Register activity constants by just iterating through the entire activity list + for (int i = 0; i < ActivityList_HighestIndex(); i++) + { + ScriptRegisterConstantNamed( g_pScriptVM, i, ActivityList_NameForIndex(i), "" ); + } +} + +//============================================================================= +//============================================================================= + +extern void RegisterWeaponScriptConstants(); + +void RegisterSharedScriptConstants() +{ + // "SERVER_DLL" is used in Source 2. +#ifdef GAME_DLL + ScriptRegisterConstantNamed( g_pScriptVM, 1, "SERVER_DLL", "" ); + ScriptRegisterConstantNamed( g_pScriptVM, 0, "CLIENT_DLL", "" ); +#else + ScriptRegisterConstantNamed( g_pScriptVM, 0, "SERVER_DLL", "" ); + ScriptRegisterConstantNamed( g_pScriptVM, 1, "CLIENT_DLL", "" ); +#endif + + // + // Activities + // + + // Scripts have to use this function before using any activity constants. + // This is because initializing 1,700+ constants every time a level loads and letting them lay around + // usually doing nothing sounds like a bad idea. + ScriptRegisterFunction( g_pScriptVM, RegisterActivityConstants, "Registers all activity IDs as usable constants." ); + + + // + // Damage Types + // + ScriptRegisterConstant( g_pScriptVM, DMG_GENERIC, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_CRUSH, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_BULLET, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_SLASH, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_BURN, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_VEHICLE, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_FALL, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_BLAST, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_CLUB, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_SHOCK, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_SONIC, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_ENERGYBEAM, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_PREVENT_PHYSICS_FORCE, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_NEVERGIB, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_ALWAYSGIB, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_DROWN, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_PARALYZE, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_NERVEGAS, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_POISON, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_RADIATION, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_DROWNRECOVER, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_ACID, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_SLOWBURN, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_REMOVENORAGDOLL, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_PHYSGUN, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_PLASMA, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_AIRBOAT, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_DISSOLVE, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_BLAST_SURFACE, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_DIRECT, "Damage type used in damage information." ); + ScriptRegisterConstant( g_pScriptVM, DMG_BUCKSHOT, "Damage type used in damage information." ); + + // + // Collision Groups + // + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_NONE, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_DEBRIS, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_DEBRIS_TRIGGER, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_INTERACTIVE_DEBRIS, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_INTERACTIVE, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_PLAYER, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_BREAKABLE_GLASS, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_VEHICLE, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_PLAYER_MOVEMENT, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_NPC, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_IN_VEHICLE, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_WEAPON, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_VEHICLE_CLIP, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_PROJECTILE, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_DOOR_BLOCKER, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_PASSABLE_DOOR, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_DISSOLVING, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_PUSHAWAY, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_NPC_ACTOR, "Collision group used in GetCollisionGroup(), etc." ); + ScriptRegisterConstant( g_pScriptVM, COLLISION_GROUP_NPC_SCRIPTED, "Collision group used in GetCollisionGroup(), etc." ); + + // + // Flags + // + ScriptRegisterConstant( g_pScriptVM, FL_ONGROUND, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_DUCKING, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_WATERJUMP, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_ONTRAIN, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_INRAIN, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_FROZEN, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_ATCONTROLS, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_CLIENT, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_FAKECLIENT, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_INWATER, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_FLY, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_SWIM, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_CONVEYOR, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_NPC, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_GODMODE, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_NOTARGET, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_AIMTARGET, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_PARTIALGROUND, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_STATICPROP, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_GRAPHED, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_GRENADE, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_STEPMOVEMENT, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_DONTTOUCH, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_BASEVELOCITY, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_WORLDBRUSH, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_OBJECT, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_KILLME, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_ONFIRE, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_DISSOLVING, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_TRANSRAGDOLL, "Flag used in GetFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FL_UNBLOCKABLE_BY_PLAYER, "Flag used in GetFlags(), etc." ); + + // + // Entity Flags + // + ScriptRegisterConstant( g_pScriptVM, EFL_KILLME, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DORMANT, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NOCLIP_ACTIVE, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_SETTING_UP_BONES, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_KEEP_ON_RECREATE_ENTITIES, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_HAS_PLAYER_CHILD, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_SHADOWUPDATE, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NOTIFY, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_FORCE_CHECK_TRANSMIT, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_BOT_FROZEN, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_SERVER_ONLY, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_AUTO_EDICT_ATTACH, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_ABSTRANSFORM, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_ABSVELOCITY, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_ABSANGVELOCITY, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_SURROUNDING_COLLISION_BOUNDS, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DIRTY_SPATIAL_PARTITION, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_PLUGIN_BASED_BOT, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_IN_SKYBOX, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_USE_PARTITION_WHEN_NOT_SOLID, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_TOUCHING_FLUID, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_IS_BEING_LIFTED_BY_BARNACLE, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_ROTORWASH_PUSH, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_THINK_FUNCTION, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_GAME_PHYSICS_SIMULATION, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_CHECK_UNTOUCH, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DONTBLOCKLOS, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_DONTWALKON, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_DISSOLVE, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_MEGAPHYSCANNON_RAGDOLL, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_WATER_VELOCITY_CHANGE, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_PHYSCANNON_INTERACTION, "Entity flag used in GetEFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EFL_NO_DAMAGE_FORCES, "Entity flag used in GetEFlags(), etc." ); + + // + // Effects + // + ScriptRegisterConstant( g_pScriptVM, EF_BONEMERGE, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_BRIGHTLIGHT, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_DIMLIGHT, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_NOINTERP, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_NOSHADOW, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_NODRAW, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_NORECEIVESHADOW, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_BONEMERGE_FASTCULL, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_ITEM_BLINK, "Effect flag used in GetEffects(), etc." ); + ScriptRegisterConstant( g_pScriptVM, EF_PARENT_ANIMATES, "Effect flag used in GetEffects(), etc." ); + + // + // Solid Flags + // + ScriptRegisterConstant( g_pScriptVM, FSOLID_CUSTOMRAYTEST, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_CUSTOMBOXTEST, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_NOT_SOLID, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_TRIGGER, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_NOT_STANDABLE, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_VOLUME_CONTENTS, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_FORCE_WORLD_ALIGNED, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_USE_TRIGGER_BOUNDS, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_ROOT_PARENT_ALIGNED, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_TRIGGER_TOUCH_DEBRIS, "Solid flag used in GetSolidFlags(), etc." ); + ScriptRegisterConstant( g_pScriptVM, FSOLID_COLLIDE_WITH_OWNER, "Solid flag used in GetSolidFlags(), etc." ); + + // + // Movetypes + // + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_NONE, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_ISOMETRIC, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_WALK, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_STEP, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_FLY, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_FLYGRAVITY, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_VPHYSICS, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_PUSH, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_NOCLIP, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_LADDER, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_OBSERVER, "Move type used in GetMoveType(), etc." ); + ScriptRegisterConstant( g_pScriptVM, MOVETYPE_CUSTOM, "Move type used in GetMoveType(), etc." ); + + // + // Animation Stuff + // + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_SERVER, "Animation event flag which indicates an event is supposed to be serverside only." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_SCRIPTED, "Animation event flag with an unknown purpose." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_SHARED, "Animation event flag which indicates an event is supposed to be shared between the server and client." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_WEAPON, "Animation event flag which indicates an event is part of a weapon." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_CLIENT, "Animation event flag which indicates an event is supposed to be clientside only." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_FACEPOSER, "Animation event flag with an unknown purpose. Presumably related to Faceposer." ); + ScriptRegisterConstant( g_pScriptVM, AE_TYPE_NEWEVENTSYSTEM, "Animation event flag which indicates an event is using the new system. This is often used by class-specific events from NPCs." ); + + // + // Ropes + // + ScriptRegisterConstant( g_pScriptVM, ROPE_RESIZE, "Try to keep the rope dangling the same amount even as the rope length changes. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_BARBED, "Hack option to draw like a barbed wire. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_COLLIDE, "Collide with the world. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_SIMULATE, "Is the rope valid? (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_BREAKABLE, "Can the endpoints detach? (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_USE_WIND, "Wind simulation on this rope. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_INITIAL_HANG, "By default, ropes will simulate for a bit internally when they are created so they sag, but dynamically created ropes for things like harpoons don't want this. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_PLAYER_WPN_ATTACH, "If this flag is set, then the second attachment must be a player. The rope will attach to \"buff_attach\" on the player's active weapon. This is a flag because it requires special code on the client to find the weapon. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_NO_GRAVITY, "Disable gravity on this rope. (for use in rope flags)" ); + ScriptRegisterConstant( g_pScriptVM, ROPE_NUMFLAGS, "The number of rope flags recognized by the game." ); + + ScriptRegisterConstantNamed( g_pScriptVM, Vector( ROPE_GRAVITY ), "ROPE_GRAVITY", "Default rope gravity vector." ); + + // + // Sounds + // + ScriptRegisterConstant( g_pScriptVM, CHAN_REPLACE, "The sound channel used when playing sounds through console commands." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_AUTO, "The default generic sound channel." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_WEAPON, "The sound channel for player and NPC weapons." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE, "The sound channel used for dialogue, voice lines, etc." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_ITEM, "The sound channel used for generic physics impact sounds, health/suit chargers, +use sounds." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_BODY, "The sound channel used for clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_STREAM, "The sound channel for sounds that can be delayed by an async load, i.e. aren't responses to particular events." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_STATIC, "The sound channel for constant/background sound that doesn't require any reaction." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE2, "An additional sound channel for voices. Used in TF2 for the announcer." ); + ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE_BASE, "The sound channel used for network voice data (online voice communications)." ); + + ScriptRegisterConstant( g_pScriptVM, VOL_NORM, "The standard volume value." ); + ScriptRegisterConstant( g_pScriptVM, PITCH_NORM, "The standard pitch value." ); + ScriptRegisterConstant( g_pScriptVM, PITCH_LOW, "The standard low pitch value." ); + ScriptRegisterConstant( g_pScriptVM, PITCH_HIGH, "The standard high pitch value." ); + + ScriptRegisterConstant( g_pScriptVM, SNDLVL_NONE, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_20dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_25dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_30dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_35dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_40dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_45dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_50dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_55dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_IDLE, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_60dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_65dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_STATIC, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_70dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_NORM, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_75dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_80dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_TALKING, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_85dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_90dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_95dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_100dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_105dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_110dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_120dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_130dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_GUNFIRE, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_140dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_150dB, "A standard value used for a sound's sound level." ); + ScriptRegisterConstant( g_pScriptVM, SNDLVL_180dB, "A standard value used for a sound's sound level." ); + + ScriptRegisterConstant( g_pScriptVM, SND_CHANGE_VOL, "Indicates a sound is a volume change to an already-playing sound." ); + ScriptRegisterConstant( g_pScriptVM, SND_CHANGE_PITCH, "Indicates a sound is a pitch change to an already-playing sound." ); + ScriptRegisterConstant( g_pScriptVM, SND_STOP, "Indicates a sound is stopping an already-playing sound." ); + ScriptRegisterConstant( g_pScriptVM, SND_SPAWNING, "Indicates a sound is spawning, used in some cases for ambients. Not networked." ); + ScriptRegisterConstant( g_pScriptVM, SND_DELAY, "Indicates a sound has an initial delay." ); + ScriptRegisterConstant( g_pScriptVM, SND_STOP_LOOPING, "Stops all looping sounds on an entity." ); + ScriptRegisterConstant( g_pScriptVM, SND_SPEAKER, "Indicates a sound is being played again by a microphone through a speaker." ); + ScriptRegisterConstant( g_pScriptVM, SND_SHOULDPAUSE, "Forces a sound to pause if the game is paused." ); + ScriptRegisterConstant( g_pScriptVM, SND_IGNORE_PHONEMES, "Prevents the entity emitting this sound from using its phonemes (no lip-syncing)." ); + ScriptRegisterConstant( g_pScriptVM, SND_IGNORE_NAME, "Used to change all sounds emitted by an entity, regardless of name." ); + ScriptRegisterConstant( g_pScriptVM, SND_DO_NOT_OVERWRITE_EXISTING_ON_CHANNEL, "Prevents a sound from interrupting other sounds on a channel (if the channel supports interruption)." ); + + ScriptRegisterConstant( g_pScriptVM, GENDER_NONE, "A standard value used to represent no specific gender. Usually used for sounds." ); + ScriptRegisterConstant( g_pScriptVM, GENDER_MALE, "A standard value used to represent male gender. Usually used for sounds." ); + ScriptRegisterConstant( g_pScriptVM, GENDER_FEMALE, "A standard value used to represent female gender. Usually used for sounds." ); + +#ifdef GAME_DLL + // + // AI Sounds + // (QueryHearSound hook can use these) + // + ScriptRegisterConstant( g_pScriptVM, SOUND_NONE, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_COMBAT, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_WORLD, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_PLAYER, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_DANGER, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_BULLET_IMPACT, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CARCASS, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_MEAT, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_GARBAGE, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_THUMPER, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_BUGBAIT, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_PHYSICS_DANGER, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_DANGER_SNIPERONLY, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_MOVE_AWAY, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_PLAYER_VEHICLE, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_READINESS_LOW, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_READINESS_MEDIUM, "Sound type used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_READINESS_HIGH, "Sound type used in QueryHearSound hooks, etc." ); + + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_FROM_SNIPER, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_GUNFIRE, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_MORTAR, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_COMBINE_ONLY, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_REACT_TO_SOURCE, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_EXPLOSION, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_EXCLUDE_COMBINE, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_DANGER_APPROACH, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_ALLIES_ONLY, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_PLAYER_VEHICLE, "Sound context used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUND_CONTEXT_OWNER_ALLIES, "Sound context used in QueryHearSound hooks, etc." ); + + ScriptRegisterConstant( g_pScriptVM, ALL_CONTEXTS, "All sound contexts useable in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, ALL_SCENTS, "All \"scent\" sound types useable in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, ALL_SOUNDS, "All sound types useable in QueryHearSound hooks, etc." ); + + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_UNSPECIFIED, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_REPEATING, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_REPEATED_DANGER, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_REPEATED_PHYSICS_DANGER, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_WEAPON, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_INJURY, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_BULLET_IMPACT, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_NPC_FOOTSTEP, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_SPOOKY_NOISE, "Sound channel used in QueryHearSound hooks, etc." ); + ScriptRegisterConstant( g_pScriptVM, SOUNDENT_CHANNEL_ZOMBINE_GRENADE, "Sound channel used in QueryHearSound hooks, etc." ); + + ScriptRegisterConstantNamed( g_pScriptVM, (int)SOUNDENT_VOLUME_MACHINEGUN, "SOUNDENT_VOLUME_MACHINEGUN", "Sound volume preset for use in InsertAISound, etc." ); + ScriptRegisterConstantNamed( g_pScriptVM, (int)SOUNDENT_VOLUME_SHOTGUN, "SOUNDENT_VOLUME_SHOTGUN", "Sound volume preset for use in InsertAISound, etc." ); + ScriptRegisterConstantNamed( g_pScriptVM, (int)SOUNDENT_VOLUME_PISTOL, "SOUNDENT_VOLUME_PISTOL", "Sound volume preset for use in InsertAISound, etc." ); + ScriptRegisterConstantNamed( g_pScriptVM, (int)SOUNDENT_VOLUME_EMPTY, "SOUNDENT_VOLUME_PISTOL", "Sound volume preset for use in InsertAISound, etc." ); + + // + // Capabilities + // + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_GROUND, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_JUMP, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_FLY, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_CLIMB, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_SWIM, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_CRAWL, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MOVE_SHOOT, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_SKIP_NAV_GROUND_CHECK, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_USE, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + //ScriptRegisterConstant( g_pScriptVM, bits_CAP_HEAR, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_AUTO_DOORS, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_OPEN_DOORS, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_TURN_HEAD, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_WEAPON_RANGE_ATTACK1, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_WEAPON_RANGE_ATTACK2, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_WEAPON_MELEE_ATTACK1, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_WEAPON_MELEE_ATTACK2, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_INNATE_RANGE_ATTACK1, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_INNATE_RANGE_ATTACK2, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_INNATE_MELEE_ATTACK1, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_INNATE_MELEE_ATTACK2, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_USE_WEAPONS, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + //ScriptRegisterConstant( g_pScriptVM, bits_CAP_STRAFE, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_ANIMATEDFACE, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_USE_SHOT_REGULATOR, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_FRIENDLY_DMG_IMMUNE, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_SQUAD, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_DUCK, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_NO_HIT_PLAYER, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_AIM_GUN, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_NO_HIT_SQUADMATES, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_SIMPLE_RADIUS_DAMAGE, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + + ScriptRegisterConstant( g_pScriptVM, bits_CAP_DOORS_GROUP, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_RANGE_ATTACK_GROUP, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + ScriptRegisterConstant( g_pScriptVM, bits_CAP_MELEE_ATTACK_GROUP, "NPC/player/weapon capability used in GetCapabilities(), etc." ); + + // + // Class_T classes + // + ScriptRegisterConstant( g_pScriptVM, CLASS_NONE, "No class." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER, "Used by players." ); + +#ifdef HL2_DLL + + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER_ALLY, "Used by citizens, hacked manhacks, and other misc. allies." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER_ALLY_VITAL, "Used by Alyx, Barney, and other allies vital to HL2." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ANTLION, "Used by antlions, antlion guards, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_BARNACLE, "Used by barnacles." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_BULLSEYE, "Used by npc_bullseye." ); + //ScriptRegisterConstant( g_pScriptVM, CLASS_BULLSQUID, "Used by bullsquids." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_CITIZEN_PASSIVE, "Used by citizens when the \"gordon_precriminal\" or \"citizens_passive\" states are enabled." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_CITIZEN_REBEL, "UNUSED IN HL2. Rebels normally use CLASS_PLAYER_ALLY." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_COMBINE, "Used by Combine soldiers, Combine turrets, and other misc. Combine NPCs." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_COMBINE_GUNSHIP, "Used by Combine gunships, helicopters, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_CONSCRIPT, "UNUSED IN HL2. Would've been used by conscripts." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_HEADCRAB, "Used by headcrabs." ); +#ifdef VANCE + ScriptRegisterConstant( g_pScriptVM, CLASS_HOUNDEYE, "Used by houndeyes." ); +#endif + ScriptRegisterConstant( g_pScriptVM, CLASS_MANHACK, "Used by Combine manhacks." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_METROPOLICE, "Used by Combine metrocops." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_MILITARY, "In HL2, this is only used by npc_combinecamera and func_guntarget. This appears to be recognized as a Combine class." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_SCANNER, "Used by Combine city scanners and claw scanners." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_STALKER, "Used by Combine stalkers." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_VORTIGAUNT, "Used by vortigaunts." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ZOMBIE, "Used by zombies." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_PROTOSNIPER, "Used by Combine snipers." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_MISSILE, "Used by RPG and APC missiles." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_FLARE, "Used by env_flares." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_EARTH_FAUNA, "Used by birds and other terrestrial animals." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_HACKED_ROLLERMINE, "Used by rollermines which were hacked by Alyx." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_COMBINE_HUNTER, "Used by Combine hunters." ); + +#elif defined( HL1_DLL ) + + ScriptRegisterConstant( g_pScriptVM, CLASS_HUMAN_PASSIVE, "Used by scientists." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_HUMAN_MILITARY, "Used by HECU marines, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ALIEN_MILITARY, "Used by alien grunts, alien slaves/vortigaunts, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ALIEN_MONSTER, "Used by zombies, houndeyes, barnacles, and other misc. monsters." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ALIEN_PREY, "Used by headcrabs, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ALIEN_PREDATOR, "Used by bullsquids, etc." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_INSECT, "Used by cockroaches." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER_ALLY, "Used by security guards/Barneys." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER_BIOWEAPON, "Used by a player's hivehand hornets." ); + ScriptRegisterConstant( g_pScriptVM, CLASS_ALIEN_BIOWEAPON, "Used by an alien grunt's hivehand hornets." ); + +#else + + ScriptRegisterConstant( g_pScriptVM, CLASS_PLAYER_ALLY, "Used by player allies." ); + +#endif + + ScriptRegisterConstant( g_pScriptVM, NUM_AI_CLASSES, "Number of AI classes." ); + + // + // Misc. AI + // + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_INVALID, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_NONE, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_IDLE, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_ALERT, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_COMBAT, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_SCRIPT, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_PLAYDEAD, "NPC state type used in GetNPCState(), etc." ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_PRONE, "When in clutches of barnacle (NPC state type used in GetNPCState(), etc.)" ); + ScriptRegisterConstant( g_pScriptVM, NPC_STATE_DEAD, "NPC state type used in GetNPCState(), etc." ); + + ScriptRegisterConstant( g_pScriptVM, AISS_AWAKE, "NPC is awake. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_THREAT, "NPC is asleep and will awaken upon seeing an enemy. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_PVS, "NPC is asleep and will awaken upon entering a player's PVS. (NPC sleep state used in Get/SetSleepState())" ); + ScriptRegisterConstant( g_pScriptVM, AISS_WAITING_FOR_INPUT, "NPC is asleep and will only awaken upon receiving the Wake input. (NPC sleep state used in Get/SetSleepState())" ); + //ScriptRegisterConstant( g_pScriptVM, AISS_AUTO_PVS, "" ); + //ScriptRegisterConstant( g_pScriptVM, AISS_AUTO_PVS_AFTER_PVS, "" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAGS_NONE, "No sleep flags. (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS, "Indicates a NPC will sleep upon exiting PVS. (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS_AFTER_PVS, "Indicates a NPC will sleep upon exiting PVS after entering PVS for the first time(?) (NPC sleep flag used in Add/Remove/HasSleepFlags())" ); + + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Playing the action animation." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WAIT, "SCRIPT_WAIT", "Waiting on everyone in the script to be ready. Plays the pre idle animation if there is one." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_POST_IDLE, "SCRIPT_POST_IDLE", "Playing the post idle animation after playing the action animation." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_CLEANUP, "SCRIPT_CLEANUP", "Cancelling the script / cleaning up." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WALK_TO_MARK, "SCRIPT_WALK_TO_MARK", "Walking to the scripted sequence position." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_RUN_TO_MARK, "SCRIPT_RUN_TO_MARK", "Running to the scripted sequence position." ); + ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Moving to the scripted sequence position while playing a custom movement animation." ); + + ScriptRegisterConstant( g_pScriptVM, D_ER, "'Error' relationship definition. Used by NPCs and players for relationship disposition." ); + ScriptRegisterConstant( g_pScriptVM, D_HT, "Denotes a 'Hate' relationship. Used by NPCs and players for relationship disposition." ); + ScriptRegisterConstant( g_pScriptVM, D_FR, "Denotes a 'Fear' relationship. Used by NPCs and players for relationship disposition." ); + ScriptRegisterConstant( g_pScriptVM, D_LI, "Denotes a 'Like' relationship. Used by NPCs and players for relationship disposition." ); + ScriptRegisterConstant( g_pScriptVM, D_NU, "Denotes a 'Neutral' relationship. Used by NPCs and players for relationship disposition." ); +#endif + + // + // Misc. General + // + ScriptRegisterConstant( g_pScriptVM, DAMAGE_NO, "Don't take damage (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_EVENTS_ONLY, "Call damage functions, but don't modify health (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_YES, "Allow damage to be taken (Use with GetTakeDamage/SetTakeDamage)" ); + ScriptRegisterConstant( g_pScriptVM, DAMAGE_AIM, "(Use with GetTakeDamage/SetTakeDamage)" ); + +#ifdef GAME_DLL + ScriptRegisterConstant( g_pScriptVM, GLOBAL_OFF, "Global state used by the Globals singleton." ); + ScriptRegisterConstant( g_pScriptVM, GLOBAL_ON, "Global state used by the Globals singleton." ); + ScriptRegisterConstant( g_pScriptVM, GLOBAL_DEAD, "Global state used by the Globals singleton." ); +#endif + + RegisterWeaponScriptConstants(); +} diff --git a/game/shared/mapbase/vscript_consts_weapons.cpp b/game/shared/mapbase/vscript_consts_weapons.cpp new file mode 100644 index 00000000..ad63efb7 --- /dev/null +++ b/game/shared/mapbase/vscript_consts_weapons.cpp @@ -0,0 +1,98 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript constants and enums shared between the server and client. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "basecombatweapon_shared.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//============================================================================= +//============================================================================= + +BEGIN_SCRIPTENUM( WeaponSound, "Weapon sounds." ) + + DEFINE_ENUMCONST( EMPTY, "" ) + DEFINE_ENUMCONST( SINGLE, "" ) + DEFINE_ENUMCONST( SINGLE_NPC, "" ) + DEFINE_ENUMCONST( WPN_DOUBLE, "" ) + DEFINE_ENUMCONST( DOUBLE_NPC, "" ) + DEFINE_ENUMCONST( BURST, "" ) + DEFINE_ENUMCONST( RELOAD, "" ) + DEFINE_ENUMCONST( RELOAD_NPC, "" ) + DEFINE_ENUMCONST( MELEE_MISS, "" ) + DEFINE_ENUMCONST( MELEE_HIT, "" ) + DEFINE_ENUMCONST( MELEE_HIT_WORLD, "" ) + DEFINE_ENUMCONST( SPECIAL1, "" ) + DEFINE_ENUMCONST( SPECIAL2, "" ) + DEFINE_ENUMCONST( SPECIAL3, "" ) + DEFINE_ENUMCONST( TAUNT, "" ) + DEFINE_ENUMCONST( DEPLOY, "" ) + + DEFINE_ENUMCONST( NUM_SHOOT_SOUND_TYPES, "" ) + +END_SCRIPTENUM(); + +//============================================================================= +//============================================================================= + +void RegisterWeaponScriptConstants() +{ + // + // Weapon classify + // + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_INVALID, "Invalid weapon class." ); + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_HANDGUN, "Weapon class for pistols, revolvers, etc." ); + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_RIFLE, "Weapon class for (assault) rifles, SMGs, etc." ); + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_SHOTGUN, "Weapon class for shotguns." ); + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_HEAVY, "Weapon class for RPGs, etc." ); + + ScriptRegisterConstant( g_pScriptVM, WEPCLASS_MELEE, "Weapon class for melee weapons." ); + + // + // Vector cones + // + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_PRECALCULATED, "This is just a zero vector, but it adds some context indicating that the person writing the code is not allowing " + "FireBullets() to modify the direction of the shot because the shot direction " + "being passed into the function has already been modified by another piece of " + "code and should be fired as specified." ); + + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_1DEGREES, "1-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_2DEGREES, "2-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_3DEGREES, "3-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_4DEGREES, "4-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_5DEGREES, "5-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_6DEGREES, "6-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_7DEGREES, "7-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_8DEGREES, "8-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_9DEGREES, "9-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_10DEGREES, "10-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_15DEGREES, "15-degree weapon vector cone." ); + ScriptRegisterConstantFromTemp( g_pScriptVM, VECTOR_CONE_20DEGREES, "20-degree weapon vector cone." ); + + // + // Weapon proficiency + // + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_INVALID, "Invalid weapon proficiency." ); + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_POOR, "Poor weapon proficiency. Causes low accuracy." ); + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_AVERAGE, "Average weapon proficiency. Causes average accuracy." ); + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_GOOD, "Good weapon proficiency. Causes good accuracy." ); + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_VERY_GOOD, "Very good weapon proficiency. Causes very good accuracy." ); + ScriptRegisterConstant( g_pScriptVM, WEAPON_PROFICIENCY_PERFECT, "Perfect weapon proficiency. Causes perfect accuracy." ); + + // + // Autoaim + // + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_2DEGREES, "2-degree autoaim cone." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_5DEGREES, "5-degree autoaim cone." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_8DEGREES, "8-degree autoaim cone." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_10DEGREES, "10-degree autoaim cone." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_20DEGREES, "20-degree autoaim cone." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_SCALE_DEFAULT, "Indicates default auto aim scale." ); + ScriptRegisterConstant( g_pScriptVM, AUTOAIM_SCALE_DIRECT_ONLY, "Indicates auto aim should not be used except for direct hits." ); +} diff --git a/game/shared/mapbase/vscript_funcs_hl2.cpp b/game/shared/mapbase/vscript_funcs_hl2.cpp new file mode 100644 index 00000000..189f8883 --- /dev/null +++ b/game/shared/mapbase/vscript_funcs_hl2.cpp @@ -0,0 +1,63 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript functions for Half-Life 2. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "hl2_gamerules.h" +#ifndef CLIENT_DLL +#include "eventqueue.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +#ifndef CLIENT_DLL +extern CBaseEntity *CreatePlayerLoadSave( Vector vOrigin, float flDuration, float flHoldTime, float flLoadTime ); + +HSCRIPT ScriptGameOver( const char *pszMessage, float flDelay, float flFadeTime, float flLoadTime, int r, int g, int b ) +{ + CBaseEntity *pPlayer = AI_GetSinglePlayer(); + if (pPlayer) + { + UTIL_ShowMessage( pszMessage, ToBasePlayer( pPlayer ) ); + ToBasePlayer( pPlayer )->NotifySinglePlayerGameEnding(); + } + else + { + // TODO: How should MP handle this? + return NULL; + } + + CBaseEntity *pReload = CreatePlayerLoadSave( vec3_origin, flFadeTime, flLoadTime + 1.0f, flLoadTime ); + if (pReload) + { + pReload->SetRenderColor( r, g, b, 255 ); + g_EventQueue.AddEvent( pReload, "Reload", flDelay, pReload, pReload ); + } + + return ToHScript( pReload ); +} + +bool ScriptMegaPhyscannonActive() +{ + return HL2GameRules()->MegaPhyscannonActive(); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHalfLife2::RegisterScriptFunctions( void ) +{ + BaseClass::RegisterScriptFunctions(); + +#ifndef CLIENT_DLL + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGameOver, "GameOver", "Ends the game and reloads the last save." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMegaPhyscannonActive, "MegaPhyscannonActive", "Checks if supercharged gravity gun mode is enabled." ); +#endif +} diff --git a/game/shared/mapbase/vscript_funcs_shared.cpp b/game/shared/mapbase/vscript_funcs_shared.cpp new file mode 100644 index 00000000..4c6d4817 --- /dev/null +++ b/game/shared/mapbase/vscript_funcs_shared.cpp @@ -0,0 +1,1106 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: This file contains general shared VScript bindings which Mapbase adds onto +// what was ported from Alien Swarm instead of cluttering the existing files. +// +// This includes various functions, classes, etc. which were either created from +// scratch or were based on/inspired by things documented in APIs from L4D2 or even +// Source 2 games like Dota 2 or Half-Life: Alyx. +// +// Other VScript bindings can be found in files like vscript_singletons.cpp and +// things not exclusive to the game DLLs are embedded/recreated in the library itself +// via vscript_bindings_base.cpp. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "matchers.h" +#include "takedamageinfo.h" + +#ifndef CLIENT_DLL +#include "globalstate.h" +#include "vscript_server.h" +#include "soundent.h" +#include "rope.h" +#include "ai_basenpc.h" +#else +#include "c_rope.h" +#endif // CLIENT_DLL + +#include "con_nprint.h" +#include "particle_parse.h" +#include "npcevent.h" + +#include "vscript_funcs_shared.h" +#include "vscript_singletons.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern IScriptManager *scriptmanager; + +#ifndef CLIENT_DLL +void EmitSoundOn( const char *pszSound, HSCRIPT hEnt ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + if (!pEnt) + return; + + pEnt->EmitSound( pszSound ); +} + +void EmitSoundOnClient( const char *pszSound, HSCRIPT hEnt, HSCRIPT hPlayer ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + CBasePlayer *pPlayer = ToBasePlayer( ToEnt( hPlayer ) ); + if (!pEnt || !pPlayer) + return; + + CSingleUserRecipientFilter filter( pPlayer ); + + EmitSound_t params; + params.m_pSoundName = pszSound; + params.m_flSoundTime = 0.0f; + params.m_pflSoundDuration = NULL; + params.m_bWarnOnDirectWaveReference = true; + + pEnt->EmitSound( filter, pEnt->entindex(), params ); +} + +void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName ) +{ + CBaseEntity *pEntity = ToEnt( entity ); + if (!pEntity) + return; + + pEntity->ScriptSetThinkFunction(pszFuncName, TICK_INTERVAL); +} + +void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV ) +{ + int nIterator = -1; + ScriptVariant_t varKey, varValue; + while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1) + { + switch (varValue.m_type) + { + case FIELD_CSTRING: pEntity->KeyValue( varKey.m_pszString, varValue.m_pszString ); break; + case FIELD_INTEGER: pEntity->KeyValueFromInt( varKey.m_pszString, varValue.m_int ); break; + case FIELD_FLOAT: pEntity->KeyValue( varKey.m_pszString, varValue.m_float ); break; + case FIELD_VECTOR: pEntity->KeyValue( varKey.m_pszString, *varValue.m_pVector ); break; + case FIELD_HSCRIPT: + { + if ( varValue.m_hScript ) + { + // Entity + if (ToEnt( varValue.m_hScript )) + { + pEntity->KeyValue( varKey.m_pszString, STRING( ToEnt( varValue.m_hScript )->GetEntityName() ) ); + } + + // Color + else if (Color *color = HScriptToClass( varValue.m_hScript )) + { + char szTemp[64]; + Q_snprintf( szTemp, sizeof( szTemp ), "%i %i %i %i", color->r(), color->g(), color->b(), color->a() ); + pEntity->KeyValue( varKey.m_pszString, szTemp ); + } + } + break; + } + } + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } +} + +void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV ) +{ + if ( IsEntityCreationAllowedInScripts() == false ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return; + } + + // This is similar to UTIL_PrecacheOther(), but we can't check if we can only precache it once. + // Probably for the best anyway, as similar classes can still have different precachable properties. + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); + if (!pEntity) + { + Assert( !"PrecacheEntityFromTable: only works for CBaseEntities" ); + return; + } + + ParseScriptTableKeyValues( pEntity, hKV ); + + pEntity->Precache(); + + UTIL_RemoveImmediate( pEntity ); +} + +HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV ) +{ + if ( IsEntityCreationAllowedInScripts() == false ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return NULL; + } + + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); + if ( !pEntity ) + { + Assert( !"SpawnEntityFromTable: only works for CBaseEntities" ); + return NULL; + } + + gEntList.NotifyCreateEntity( pEntity ); + + ParseScriptTableKeyValues( pEntity, hKV ); + + DispatchSpawn( pEntity ); + pEntity->Activate(); + + return ToHScript( pEntity ); +} +#endif + +HSCRIPT EntIndexToHScript( int index ) +{ +#ifdef GAME_DLL + edict_t *e = INDEXENT(index); + if ( e && !e->IsFree() ) + { + return ToHScript( GetContainingEntity( e ) ); + } +#else // CLIENT_DLL + if ( index < NUM_ENT_ENTRIES ) + { + return ToHScript( CBaseEntity::Instance( index ) ); + } +#endif + return NULL; +} + +//----------------------------------------------------------------------------- +// Mapbase-specific functions start here +//----------------------------------------------------------------------------- + +#ifndef CLIENT_DLL +void SaveEntityKVToTable( HSCRIPT hEnt, HSCRIPT hTable ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + if (pEnt == NULL) + return; + + variant_t var; // For Set() + ScriptVariant_t varScript, varTable = hTable; + + // loop through the data description list, reading each data desc block + for ( datamap_t *dmap = pEnt->GetDataDescMap(); dmap != NULL; dmap = dmap->baseMap ) + { + // search through all the readable fields in the data description, looking for a match + for ( int i = 0; i < dmap->dataNumFields; i++ ) + { + if ( dmap->dataDesc[i].flags & (FTYPEDESC_KEY) ) + { + var.Set( dmap->dataDesc[i].fieldType, ((char*)pEnt) + dmap->dataDesc[i].fieldOffset[ TD_OFFSET_NORMAL ] ); + var.SetScriptVariant( varScript ); + g_pScriptVM->SetValue( varTable, dmap->dataDesc[i].externalName, varScript ); + } + } + } +} + +HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) +{ + if ( IsEntityCreationAllowedInScripts() == false ) + { + Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return NULL; + } + + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); + if ( !pEntity ) + { + Assert( !"SpawnEntityFromKeyValues: only works for CBaseEntities" ); + return NULL; + } + + gEntList.NotifyCreateEntity( pEntity ); + + KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV ); + for (pKV = pKV->GetFirstSubKey(); pKV != NULL; pKV = pKV->GetNextKey()) + { + pEntity->KeyValue( pKV->GetName(), pKV->GetString() ); + } + + DispatchSpawn( pEntity ); + pEntity->Activate(); + + return ToHScript( pEntity ); +} + +void ScriptDispatchSpawn( HSCRIPT hEntity ) +{ + CBaseEntity *pEntity = ToEnt( hEntity ); + if (pEntity) + { + DispatchSpawn( pEntity ); + } +} +#endif // !CLIENT_DLL + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +static HSCRIPT CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Vector &vecForce, const Vector &vecDamagePos, float flDamage, int iDamageType ) +{ + // The script is responsible for deleting this via DestroyDamageInfo(). + CTakeDamageInfo *damageInfo = new CTakeDamageInfo( ToEnt(hInflictor), ToEnt(hAttacker), flDamage, iDamageType ); + HSCRIPT hScript = g_pScriptVM->RegisterInstance( damageInfo ); + + damageInfo->SetDamagePosition( vecDamagePos ); + damageInfo->SetDamageForce( vecForce ); + + return hScript; +} + +static void DestroyDamageInfo( HSCRIPT hDamageInfo ) +{ + CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( hDamageInfo ); + if ( pInfo ) + { + g_pScriptVM->RemoveInstance( hDamageInfo ); + delete pInfo; + } +} + +void ScriptCalculateExplosiveDamageForce( HSCRIPT info, const Vector &vecDir, const Vector &vecForceOrigin, float flScale ) +{ + CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( info ); + if ( pInfo ) + { + CalculateExplosiveDamageForce( pInfo, vecDir, vecForceOrigin, flScale ); + } +} + +void ScriptCalculateBulletDamageForce( HSCRIPT info, int iBulletType, const Vector &vecBulletDir, const Vector &vecForceOrigin, float flScale ) +{ + CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( info ); + if ( pInfo ) + { + CalculateBulletDamageForce( pInfo, iBulletType, vecBulletDir, vecForceOrigin, flScale ); + } +} + +void ScriptCalculateMeleeDamageForce( HSCRIPT info, const Vector &vecMeleeDir, const Vector &vecForceOrigin, float flScale ) +{ + CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( info ); + if ( pInfo ) + { + CalculateMeleeDamageForce( pInfo, vecMeleeDir, vecForceOrigin, flScale ); + } +} + +void ScriptGuessDamageForce( HSCRIPT info, const Vector &vecForceDir, const Vector &vecForceOrigin, float flScale ) +{ + CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( info ); + if ( pInfo ) + { + GuessDamageForce( pInfo, vecForceDir, vecForceOrigin, flScale ); + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptGameTrace, "CGameTrace", "trace_t" ) + DEFINE_SCRIPTFUNC( DidHitWorld, "Returns whether the trace hit the world entity or not." ) + DEFINE_SCRIPTFUNC( DidHitNonWorldEntity, "Returns whether the trace hit something other than the world entity." ) + DEFINE_SCRIPTFUNC( GetEntityIndex, "Returns the index of whatever entity this trace hit." ) + DEFINE_SCRIPTFUNC( DidHit, "Returns whether the trace hit anything." ) + + DEFINE_SCRIPTFUNC( FractionLeftSolid, "If this trace started within a solid, this is the point in the trace's fraction at which it left that solid." ) + DEFINE_SCRIPTFUNC( HitGroup, "Returns the specific hit group this trace hit if it hit an entity." ) + DEFINE_SCRIPTFUNC( PhysicsBone, "Returns the physics bone this trace hit if it hit an entity." ) + DEFINE_SCRIPTFUNC( Entity, "Returns the entity this trace has hit." ) + DEFINE_SCRIPTFUNC( HitBox, "Returns the hitbox of the entity this trace has hit. If it hit the world entity, this returns the static prop index." ) + + DEFINE_SCRIPTFUNC( IsDispSurface, "Returns whether this trace hit a displacement." ) + DEFINE_SCRIPTFUNC( IsDispSurfaceWalkable, "Returns whether DISPSURF_FLAG_WALKABLE is ticked on the displacement this trace hit." ) + DEFINE_SCRIPTFUNC( IsDispSurfaceBuildable, "Returns whether DISPSURF_FLAG_BUILDABLE is ticked on the displacement this trace hit." ) + DEFINE_SCRIPTFUNC( IsDispSurfaceProp1, "Returns whether DISPSURF_FLAG_SURFPROP1 is ticked on the displacement this trace hit." ) + DEFINE_SCRIPTFUNC( IsDispSurfaceProp2, "Returns whether DISPSURF_FLAG_SURFPROP2 is ticked on the displacement this trace hit." ) + + DEFINE_SCRIPTFUNC( StartPos, "Gets the trace's start position." ) + DEFINE_SCRIPTFUNC( EndPos, "Gets the trace's end position." ) + + DEFINE_SCRIPTFUNC( Fraction, "Gets the fraction of the trace completed. For example, if the trace stopped exactly halfway to the end position, this would be 0.5." ) + DEFINE_SCRIPTFUNC( Contents, "Gets the contents of the surface the trace has hit." ) + DEFINE_SCRIPTFUNC( DispFlags, "Gets the displacement flags of the surface the trace has hit." ) + + DEFINE_SCRIPTFUNC( AllSolid, "Returns whether the trace is completely within a solid." ) + DEFINE_SCRIPTFUNC( StartSolid, "Returns whether the trace started within a solid." ) + + DEFINE_SCRIPTFUNC( Surface, "" ) + DEFINE_SCRIPTFUNC( Plane, "" ) + + DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." ) +END_SCRIPTDESC(); + +BEGIN_SCRIPTDESC_ROOT_NAMED( scriptsurfacedata_t, "surfacedata_t", "" ) + DEFINE_SCRIPTFUNC( GetFriction, "" ) + DEFINE_SCRIPTFUNC( GetThickness, "" ) + + DEFINE_SCRIPTFUNC( GetJumpFactor, "" ) + DEFINE_SCRIPTFUNC( GetMaterialChar, "" ) + + DEFINE_SCRIPTFUNC( GetSoundStepLeft, "" ) + DEFINE_SCRIPTFUNC( GetSoundStepRight, "" ) + DEFINE_SCRIPTFUNC( GetSoundImpactSoft, "" ) + DEFINE_SCRIPTFUNC( GetSoundImpactHard, "" ) + DEFINE_SCRIPTFUNC( GetSoundScrapeSmooth, "" ) + DEFINE_SCRIPTFUNC( GetSoundScrapeRough, "" ) + DEFINE_SCRIPTFUNC( GetSoundBulletImpact, "" ) + DEFINE_SCRIPTFUNC( GetSoundRolling, "" ) + DEFINE_SCRIPTFUNC( GetSoundBreak, "" ) + DEFINE_SCRIPTFUNC( GetSoundStrain, "" ) +END_SCRIPTDESC(); + +BEGIN_SCRIPTDESC_ROOT_NAMED( CSurfaceScriptHelper, "csurface_t", "" ) + DEFINE_SCRIPTFUNC( Name, "" ) + DEFINE_SCRIPTFUNC( SurfaceProps, "The surface's properties." ) +END_SCRIPTDESC(); + +CPlaneTInstanceHelper g_PlaneTInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT( cplane_t, "" ) + DEFINE_SCRIPT_INSTANCE_HELPER( &g_PlaneTInstanceHelper ) +END_SCRIPTDESC(); + +static HSCRIPT ScriptTraceLineComplex( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore, int iMask, int iCollisionGroup ) +{ + // The script is responsible for deleting this via Destroy(). + CScriptGameTrace *tr = new CScriptGameTrace(); + + CBaseEntity *pIgnore = ToEnt( entIgnore ); + UTIL_TraceLine( vecStart, vecEnd, iMask, pIgnore, iCollisionGroup, tr ); + + tr->RegisterSurface(); + tr->RegisterPlane(); + + return tr->GetScriptInstance(); +} + +static HSCRIPT ScriptTraceHullComplex( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax, + HSCRIPT entIgnore, int iMask, int iCollisionGroup ) +{ + // The script is responsible for deleting this via Destroy(). + CScriptGameTrace *tr = new CScriptGameTrace(); + + CBaseEntity *pIgnore = ToEnt( entIgnore ); + UTIL_TraceHull( vecStart, vecEnd, hullMin, hullMax, iMask, pIgnore, iCollisionGroup, tr ); + + tr->RegisterSurface(); + tr->RegisterPlane(); + + return tr->GetScriptInstance(); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT( FireBulletsInfo_t, "" ) + DEFINE_SCRIPT_CONSTRUCTOR() + + DEFINE_SCRIPTFUNC( GetShots, "Gets the number of shots which should be fired." ) + DEFINE_SCRIPTFUNC( SetShots, "Sets the number of shots which should be fired." ) + + DEFINE_SCRIPTFUNC( GetSource, "" ) + DEFINE_SCRIPTFUNC( SetSource, "" ) + DEFINE_SCRIPTFUNC( GetDirShooting, "" ) + DEFINE_SCRIPTFUNC( SetDirShooting, "" ) + DEFINE_SCRIPTFUNC( GetSpread, "" ) + DEFINE_SCRIPTFUNC( SetSpread, "" ) + + DEFINE_SCRIPTFUNC( GetDistance, "Gets the distance the bullets should travel." ) + DEFINE_SCRIPTFUNC( SetDistance, "Sets the distance the bullets should travel." ) + + DEFINE_SCRIPTFUNC( GetAmmoType, "" ) + DEFINE_SCRIPTFUNC( SetAmmoType, "" ) + + DEFINE_SCRIPTFUNC( GetTracerFreq, "" ) + DEFINE_SCRIPTFUNC( SetTracerFreq, "" ) + + DEFINE_SCRIPTFUNC( GetDamage, "Gets the damage the bullets should deal. 0 = use ammo type" ) + DEFINE_SCRIPTFUNC( SetDamage, "Sets the damage the bullets should deal. 0 = use ammo type" ) + DEFINE_SCRIPTFUNC( GetPlayerDamage, "Gets the damage the bullets should deal when hitting the player. 0 = use regular damage" ) + DEFINE_SCRIPTFUNC( SetPlayerDamage, "Sets the damage the bullets should deal when hitting the player. 0 = use regular damage" ) + + DEFINE_SCRIPTFUNC( GetFlags, "Gets the flags the bullets should use." ) + DEFINE_SCRIPTFUNC( SetFlags, "Sets the flags the bullets should use." ) + + DEFINE_SCRIPTFUNC( GetDamageForceScale, "" ) + DEFINE_SCRIPTFUNC( SetDamageForceScale, "" ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttacker, "GetAttacker", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAttacker, "SetAttacker", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAdditionalIgnoreEnt, "GetAdditionalIgnoreEnt", "" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAdditionalIgnoreEnt, "SetAdditionalIgnoreEnt", "" ) + + DEFINE_SCRIPTFUNC( GetPrimaryAttack, "Gets whether the bullets came from a primary attack." ) + DEFINE_SCRIPTFUNC( SetPrimaryAttack, "Sets whether the bullets came from a primary attack." ) +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +HSCRIPT FireBulletsInfo_t::ScriptGetAttacker() +{ + return ToHScript( m_pAttacker ); +} + +void FireBulletsInfo_t::ScriptSetAttacker( HSCRIPT value ) +{ + m_pAttacker = ToEnt( value ); +} + +HSCRIPT FireBulletsInfo_t::ScriptGetAdditionalIgnoreEnt() +{ + return ToHScript( m_pAdditionalIgnoreEnt ); +} + +void FireBulletsInfo_t::ScriptSetAdditionalIgnoreEnt( HSCRIPT value ) +{ + m_pAdditionalIgnoreEnt = ToEnt( value ); +} + +static HSCRIPT CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Vector &vecDirShooting, + const Vector &vecSpread, float iDamage, HSCRIPT pAttacker ) +{ + // The script is responsible for deleting this via DestroyFireBulletsInfo(). + FireBulletsInfo_t *info = new FireBulletsInfo_t(); + HSCRIPT hScript = g_pScriptVM->RegisterInstance( info ); + + info->SetShots( cShots ); + info->SetSource( vecSrc ); + info->SetDirShooting( vecDirShooting ); + info->SetSpread( vecSpread ); + info->SetDamage( iDamage ); + info->ScriptSetAttacker( pAttacker ); + + return hScript; +} + +static void DestroyFireBulletsInfo( HSCRIPT hBulletsInfo ) +{ + FireBulletsInfo_t *pInfo = HScriptToClass< FireBulletsInfo_t >( hBulletsInfo ); + if ( pInfo ) + { + g_pScriptVM->RemoveInstance( hBulletsInfo ); + delete pInfo; + } +} + +//----------------------------------------------------------------------------- +// animevent_t +//----------------------------------------------------------------------------- +CAnimEventTInstanceHelper g_AnimEventTInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT( scriptanimevent_t, "" ) + DEFINE_SCRIPT_INSTANCE_HELPER( &g_AnimEventTInstanceHelper ) + + DEFINE_SCRIPTFUNC( GetEvent, "" ) + DEFINE_SCRIPTFUNC( SetEvent, "" ) + + DEFINE_SCRIPTFUNC( GetOptions, "" ) + DEFINE_SCRIPTFUNC( SetOptions, "" ) + + DEFINE_SCRIPTFUNC( GetCycle, "" ) + DEFINE_SCRIPTFUNC( SetCycle, "" ) + + DEFINE_SCRIPTFUNC( GetEventTime, "" ) + DEFINE_SCRIPTFUNC( SetEventTime, "" ) + + DEFINE_SCRIPTFUNC( GetType, "Gets the event's type flags. See the 'AE_TYPE_' set of constants for valid flags." ) + DEFINE_SCRIPTFUNC( SetType, "Sets the event's type flags. See the 'AE_TYPE_' set of constants for valid flags." ) + + DEFINE_SCRIPTFUNC( GetSource, "Gets the event's source entity." ) + DEFINE_SCRIPTFUNC( SetSource, "Sets the event's source entity." ) +END_SCRIPTDESC(); + +bool CAnimEventTInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + DevWarning( "VScript animevent_t.%s: animevent_t metamethod members are deprecated! Use 'script_help animevent_t' to see the correct functions.\n", pszKey ); + + animevent_t *ani = ((animevent_t *)p); + if (FStrEq( pszKey, "event" )) + variant = ani->event; + else if (FStrEq( pszKey, "options" )) + variant = ani->options; + else if (FStrEq( pszKey, "cycle" )) + variant = ani->cycle; + else if (FStrEq( pszKey, "eventtime" )) + variant = ani->eventtime; + else if (FStrEq( pszKey, "type" )) + variant = ani->type; + else if (FStrEq( pszKey, "source" )) + variant = ToHScript(ani->pSource); + else + return false; + + return true; +} + +bool CAnimEventTInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + DevWarning( "VScript animevent_t.%s: animevent_t metamethod members are deprecated! Use 'script_help animevent_t' to see the correct functions.\n", pszKey ); + + animevent_t *ani = ((animevent_t *)p); + if (FStrEq( pszKey, "event" )) + ani->event = variant; + else if (FStrEq( pszKey, "options" )) + ani->options = variant; + else if (FStrEq( pszKey, "cycle" )) + ani->cycle = variant; + else if (FStrEq( pszKey, "eventtime" )) + ani->eventtime = variant; + else if (FStrEq( pszKey, "type" )) + ani->type = variant; + else if (FStrEq( pszKey, "source" )) + { + CBaseEntity *pEnt = ToEnt( variant.m_hScript ); + if (pEnt) + ani->pSource = pEnt->GetBaseAnimating(); + } + else + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// EmitSound_t +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT_NAMED( ScriptEmitSound_t, "EmitSound_t", "" ) + DEFINE_SCRIPT_CONSTRUCTOR() + + DEFINE_SCRIPTFUNC( GetChannel, "" ) + DEFINE_SCRIPTFUNC( SetChannel, "" ) + + DEFINE_SCRIPTFUNC( GetSoundName, "Gets the sound's file path or soundscript name." ) + DEFINE_SCRIPTFUNC( SetSoundName, "Sets the sound's file path or soundscript name." ) + + DEFINE_SCRIPTFUNC( GetVolume, "(Note that this may not apply to soundscripts)" ) + DEFINE_SCRIPTFUNC( SetVolume, "(Note that this may not apply to soundscripts)" ) + + DEFINE_SCRIPTFUNC( GetSoundLevel, "Gets the sound's level in decibels. (Note that this may not apply to soundscripts)" ) + DEFINE_SCRIPTFUNC( SetSoundLevel, "Sets the sound's level in decibels. (Note that this may not apply to soundscripts)" ) + + DEFINE_SCRIPTFUNC( GetFlags, "Gets the sound's flags. See the 'SND_' set of constants." ) + DEFINE_SCRIPTFUNC( SetFlags, "Sets the sound's flags. See the 'SND_' set of constants." ) + + DEFINE_SCRIPTFUNC( GetSpecialDSP, "" ) + DEFINE_SCRIPTFUNC( SetSpecialDSP, "" ) + + DEFINE_SCRIPTFUNC( HasOrigin, "Returns true if the sound has an origin override." ) + DEFINE_SCRIPTFUNC( GetOrigin, "Gets the sound's origin override." ) + DEFINE_SCRIPTFUNC( SetOrigin, "Sets the sound's origin override." ) + DEFINE_SCRIPTFUNC( ClearOrigin, "Clears the sound's origin override if it has one." ) + + DEFINE_SCRIPTFUNC( GetSoundTime, "Gets the time the sound will begin, relative to Time()." ) + DEFINE_SCRIPTFUNC( SetSoundTime, "Sets the time the sound will begin, relative to Time()." ) + + DEFINE_SCRIPTFUNC( GetEmitCloseCaption, "Gets whether or not the sound will emit closed captioning/subtitles." ) + DEFINE_SCRIPTFUNC( SetEmitCloseCaption, "Sets whether or not the sound will emit closed captioning/subtitles." ) + + DEFINE_SCRIPTFUNC( GetWarnOnMissingCloseCaption, "Gets whether or not the sound will send a message to the console if there is no corresponding closed captioning token." ) + DEFINE_SCRIPTFUNC( SetWarnOnMissingCloseCaption, "Sets whether or not the sound will send a message to the console if there is no corresponding closed captioning token." ) + + DEFINE_SCRIPTFUNC( GetWarnOnDirectWaveReference, "Gets whether or not the sound will send a message to the console if it references a direct sound file instead of a soundscript." ) + DEFINE_SCRIPTFUNC( SetWarnOnDirectWaveReference, "Sets whether or not the sound will send a message to the console if it references a direct sound file instead of a soundscript." ) + + DEFINE_SCRIPTFUNC( GetSpeakerEntity, "Gets the sound's original source if it is being transmitted by a microphone." ) + DEFINE_SCRIPTFUNC( SetSpeakerEntity, "Sets the sound's original source if it is being transmitted by a microphone." ) + + DEFINE_SCRIPTFUNC( GetSoundScriptHandle, "" ) + DEFINE_SCRIPTFUNC( SetSoundScriptHandle, "" ) +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptUserCmd, "CUserCmd", "" ) + DEFINE_SCRIPTFUNC( GetCommandNumber, "For matching server and client commands for debugging." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTickCount, "GetTickCount", "The tick the client created this command." ) + + DEFINE_SCRIPTFUNC( GetViewAngles, "Player instantaneous view angles." ) + DEFINE_SCRIPTFUNC( SetViewAngles, "Sets player instantaneous view angles." ) + + DEFINE_SCRIPTFUNC( GetForwardMove, "" ) + DEFINE_SCRIPTFUNC( SetForwardMove, "" ) + DEFINE_SCRIPTFUNC( GetSideMove, "" ) + DEFINE_SCRIPTFUNC( SetSideMove, "" ) + DEFINE_SCRIPTFUNC( GetUpMove, "" ) + DEFINE_SCRIPTFUNC( SetUpMove, "" ) + + DEFINE_SCRIPTFUNC( GetButtons, "Input button state." ) + DEFINE_SCRIPTFUNC( SetButtons, "Sets input button state." ) + DEFINE_SCRIPTFUNC( GetImpulse, "Impulse command issued." ) + DEFINE_SCRIPTFUNC( SetImpulse, "Sets impulse command issued." ) + + DEFINE_SCRIPTFUNC( GetWeaponSelect, "Current weapon id." ) + DEFINE_SCRIPTFUNC( SetWeaponSelect, "Sets current weapon id." ) + DEFINE_SCRIPTFUNC( GetWeaponSubtype, "Current weapon subtype id." ) + DEFINE_SCRIPTFUNC( SetWeaponSubtype, "Sets current weapon subtype id." ) + + DEFINE_SCRIPTFUNC( GetRandomSeed, "For shared random functions." ) + + DEFINE_SCRIPTFUNC( GetMouseX, "Mouse accum in x from create move." ) + DEFINE_SCRIPTFUNC( SetMouseX, "Sets mouse accum in x from create move." ) + DEFINE_SCRIPTFUNC( GetMouseY, "Mouse accum in y from create move." ) + DEFINE_SCRIPTFUNC( SetMouseY, "Sets mouse accum in y from create move." ) +END_SCRIPTDESC(); + +#ifdef GAME_DLL +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +#define DEFINE_ENEMY_INFO_SCRIPTFUNCS(name, desc) \ + DEFINE_SCRIPTFUNC_NAMED( Get##name, #name, "Get " desc ) \ + DEFINE_SCRIPTFUNC( Set##name, "Set " desc ) + +BEGIN_SCRIPTDESC_ROOT_NAMED( Script_AI_EnemyInfo_t, "AI_EnemyInfo_t", "Accessor for information about an enemy." ) + DEFINE_SCRIPTFUNC( Enemy, "" ) + DEFINE_SCRIPTFUNC( SetEnemy, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( LastKnownLocation, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( LastSeenLocation, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastSeen, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeFirstSeen, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastReacquired, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeValidEnemy, "the time at which the enemy can be selected (reaction delay)." ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastReceivedDamageFrom, "the last time damage was received from this enemy." ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeAtFirstHand, "the time at which the enemy was seen firsthand." ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( DangerMemory, "the memory of danger position w/o enemy pointer." ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( EludedMe, "whether the enemy is not at the last known location." ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( Unforgettable, "" ) + DEFINE_ENEMY_INFO_SCRIPTFUNCS( MobbedMe, "whether the enemy was part of a mob at some point." ) +END_SCRIPTDESC(); +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT( IPhysicsObject, "VPhysics object class." ) + + DEFINE_SCRIPTFUNC( IsStatic, "" ) + DEFINE_SCRIPTFUNC( IsAsleep, "" ) + DEFINE_SCRIPTFUNC( IsTrigger, "" ) + DEFINE_SCRIPTFUNC( IsFluid, "" ) + DEFINE_SCRIPTFUNC( IsHinged, "" ) + DEFINE_SCRIPTFUNC( IsCollisionEnabled, "" ) + DEFINE_SCRIPTFUNC( IsGravityEnabled, "" ) + DEFINE_SCRIPTFUNC( IsDragEnabled, "" ) + DEFINE_SCRIPTFUNC( IsMotionEnabled, "" ) + DEFINE_SCRIPTFUNC( IsMoveable, "" ) + DEFINE_SCRIPTFUNC( IsAttachedToConstraint, "" ) + + DEFINE_SCRIPTFUNC( EnableCollisions, "" ) + DEFINE_SCRIPTFUNC( EnableGravity, "" ) + DEFINE_SCRIPTFUNC( EnableDrag, "" ) + DEFINE_SCRIPTFUNC( EnableMotion, "" ) + + DEFINE_SCRIPTFUNC( Wake, "" ) + DEFINE_SCRIPTFUNC( Sleep, "" ) + + DEFINE_SCRIPTFUNC( SetMass, "" ) + DEFINE_SCRIPTFUNC( GetMass, "" ) + DEFINE_SCRIPTFUNC( GetInvMass, "" ) + DEFINE_SCRIPTFUNC( GetInertia, "" ) + DEFINE_SCRIPTFUNC( GetInvInertia, "" ) + DEFINE_SCRIPTFUNC( SetInertia, "" ) + + DEFINE_SCRIPTFUNC( ApplyForceCenter, "" ) + DEFINE_SCRIPTFUNC( ApplyForceOffset, "" ) + DEFINE_SCRIPTFUNC( ApplyTorqueCenter, "" ) + + DEFINE_SCRIPTFUNC( GetName, "" ) + +END_SCRIPTDESC(); + +static const Vector &GetPhysVelocity( HSCRIPT hPhys ) +{ + IPhysicsObject *pPhys = HScriptToClass( hPhys ); + if (!pPhys) + return vec3_origin; + + static Vector vecVelocity; + pPhys->GetVelocity( &vecVelocity, NULL ); + return vecVelocity; +} + +static const Vector &GetPhysAngVelocity( HSCRIPT hPhys ) +{ + IPhysicsObject *pPhys = HScriptToClass( hPhys ); + if (!pPhys) + return vec3_origin; + + static Vector vecAngVelocity; + pPhys->GetVelocity( NULL, &vecAngVelocity ); + return vecAngVelocity; +} + +static void SetPhysVelocity( HSCRIPT hPhys, const Vector& vecVelocity, const Vector& vecAngVelocity ) +{ + IPhysicsObject *pPhys = HScriptToClass( hPhys ); + if (!pPhys) + return; + + pPhys->SetVelocity( &vecVelocity, &vecAngVelocity ); +} + +static void AddPhysVelocity( HSCRIPT hPhys, const Vector& vecVelocity, const Vector& vecAngVelocity ) +{ + IPhysicsObject *pPhys = HScriptToClass( hPhys ); + if (!pPhys) + return; + + pPhys->AddVelocity( &vecVelocity, &vecAngVelocity ); +} + +//============================================================================= +//============================================================================= + +#ifdef CLIENT_DLL +static int ScriptPrecacheModel( const char *modelname ) +{ + return CBaseEntity::PrecacheModel( modelname ); +} + +static void ScriptPrecacheOther( const char *classname ) +{ + UTIL_PrecacheOther( classname ); +} +#else +static int ScriptPrecacheModel( const char *modelname, bool bPreload ) +{ + return CBaseEntity::PrecacheModel( modelname, bPreload ); +} + +static void ScriptPrecacheOther( const char *classname, const char *modelName ) +{ + UTIL_PrecacheOther( classname, modelName ); +} + +// TODO: Move this? +static void ScriptInsertSound( int iType, const Vector &vecOrigin, int iVolume, float flDuration, HSCRIPT hOwner, int soundChannelIndex, HSCRIPT hSoundTarget ) +{ + CSoundEnt::InsertSound( iType, vecOrigin, iVolume, flDuration, ToEnt(hOwner), soundChannelIndex, ToEnt(hSoundTarget) ); +} +#endif + +//============================================================================= +//============================================================================= + +static void ScriptEntitiesInBox( HSCRIPT hTable, int listMax, const Vector &hullMin, const Vector &hullMax, int iMask ) +{ + CBaseEntity *list[1024]; + int count = UTIL_EntitiesInBox( list, listMax, hullMin, hullMax, iMask ); + + for ( int i = 0; i < count; i++ ) + { + g_pScriptVM->ArrayAppend( hTable, ToHScript(list[i]) ); + } +} + +static void ScriptEntitiesAtPoint( HSCRIPT hTable, int listMax, const Vector &point, int iMask ) +{ + CBaseEntity *list[1024]; + int count = UTIL_EntitiesAtPoint( list, listMax, point, iMask ); + + for ( int i = 0; i < count; i++ ) + { + g_pScriptVM->ArrayAppend( hTable, ToHScript(list[i]) ); + } +} + +static void ScriptEntitiesInSphere( HSCRIPT hTable, int listMax, const Vector ¢er, float radius, int iMask ) +{ + CBaseEntity *list[1024]; + int count = UTIL_EntitiesInSphere( list, listMax, center, radius, iMask ); + + for ( int i = 0; i < count; i++ ) + { + g_pScriptVM->ArrayAppend( hTable, ToHScript(list[i]) ); + } +} + +//----------------------------------------------------------------------------- + +static void ScriptDecalTrace( HSCRIPT hTrace, const char *decalName ) +{ + CScriptGameTrace *tr = HScriptToClass< CScriptGameTrace >( hTrace ); + if ( tr ) + { + UTIL_DecalTrace( tr, decalName ); + } +} + +static HSCRIPT ScriptCreateRope( HSCRIPT hStart, HSCRIPT hEnd, int iStartAttachment, int iEndAttachment, float ropeWidth, const char *pMaterialName, int numSegments, int ropeFlags ) +{ +#ifdef CLIENT_DLL + C_RopeKeyframe *pRope = C_RopeKeyframe::Create( ToEnt( hStart ), ToEnt( hEnd ), iStartAttachment, iEndAttachment, ropeWidth, pMaterialName, numSegments, ropeFlags ); +#else + CRopeKeyframe *pRope = CRopeKeyframe::Create( ToEnt( hStart ), ToEnt( hEnd ), iStartAttachment, iEndAttachment, ropeWidth, pMaterialName, numSegments ); + if (pRope) + pRope->m_RopeFlags |= ropeFlags; // HACKHACK +#endif + + return ToHScript( pRope ); +} + +#ifndef CLIENT_DLL +static HSCRIPT ScriptCreateRopeWithSecondPointDetached( HSCRIPT hStart, int iStartAttachment, int ropeLength, float ropeWidth, const char *pMaterialName, int numSegments, bool initialHang, int ropeFlags ) +{ + CRopeKeyframe *pRope = CRopeKeyframe::CreateWithSecondPointDetached( ToEnt( hStart ), iStartAttachment, ropeLength, ropeWidth, pMaterialName, numSegments, initialHang ); + if (pRope) + pRope->m_RopeFlags |= ropeFlags; // HACKHACK + + return ToHScript( pRope ); +} +#endif + +static void EmitSoundParamsOn( HSCRIPT hParams, HSCRIPT hEnt ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + if (!pEnt) + return; + + ScriptEmitSound_t *pParams = (ScriptEmitSound_t*)g_pScriptVM->GetInstanceValue( hParams, GetScriptDescForClass( ScriptEmitSound_t ) ); + if (!pParams) + return; + + CPASAttenuationFilter filter( pEnt, pParams->m_pSoundName ); + + CBaseEntity::EmitSound( filter, pEnt->entindex(), *pParams ); +} + +//----------------------------------------------------------------------------- +// Simple particle effect dispatch +//----------------------------------------------------------------------------- +static void ScriptDispatchParticleEffect( const char *pszParticleName, const Vector &vecOrigin, const QAngle &vecAngles, HSCRIPT hEntity ) +{ + DispatchParticleEffect( pszParticleName, vecOrigin, vecAngles, ToEnt(hEntity) ); +} + +#ifndef CLIENT_DLL +const Vector& ScriptPredictedPosition( HSCRIPT hTarget, float flTimeDelta ) +{ + static Vector predicted; + UTIL_PredictedPosition( ToEnt(hTarget), flTimeDelta, &predicted ); + return predicted; +} +#endif + +//============================================================================= +//============================================================================= + +bool ScriptMatcherMatch( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); } + +//============================================================================= +//============================================================================= + +#ifndef CLIENT_DLL +bool IsDedicatedServer() +{ + return engine->IsDedicatedServer(); +} +#endif + +bool ScriptIsServer() +{ +#ifdef GAME_DLL + return true; +#else + return false; +#endif +} + +bool ScriptIsClient() +{ +#ifdef CLIENT_DLL + return true; +#else + return false; +#endif +} + +bool ScriptIsWindows() +{ + return IsWindows(); +} + +bool ScriptIsLinux() +{ + return IsLinux(); +} + +bool ScriptIsOSX() +{ + return IsOSX(); +} + +bool ScriptIsPosix() +{ + return IsPosix(); +} + +// Notification printing on the right edge of the screen +void NPrint( int pos, const char* fmt ) +{ + engine->Con_NPrintf( pos, "%s", fmt ); +} + +void NXPrint( int pos, int r, int g, int b, bool fixed, float ftime, const char* fmt ) +{ + con_nprint_t info; + + info.index = pos; + info.time_to_live = ftime; + info.color[0] = r / 255.f; + info.color[1] = g / 255.f; + info.color[2] = b / 255.f; + info.fixed_width_font = fixed; + + engine->Con_NXPrintf( &info, "%s", fmt ); +} + +static float IntervalPerTick() +{ + return gpGlobals->interval_per_tick; +} + +static int GetFrameCount() +{ + return gpGlobals->framecount; +} + + +//============================================================================= +//============================================================================= + +void RegisterSharedScriptFunctions() +{ + // + // Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to + // some of the code normally available in games like L4D2 or Valve's original VScript DLL. + // Instead, that code is recreated here, shared between server and client. + // + +#ifndef CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, EmitSoundOn, "Play named sound on an entity." ); + ScriptRegisterFunction( g_pScriptVM, EmitSoundOnClient, "Play named sound only on the client for the specified player." ); + + ScriptRegisterFunction( g_pScriptVM, AddThinkToEnt, "This will put a think function onto an entity, or pass null to remove it. This is NOT chained, so be careful." ); + ScriptRegisterFunction( g_pScriptVM, PrecacheEntityFromTable, "Precache an entity from KeyValues in a table." ); + ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromTable, "Native function for entity spawning." ); +#endif // !CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, EntIndexToHScript, "Returns the script handle for the given entity index." ); + + //----------------------------------------------------------------------------- + // Functions, etc. unique to Mapbase + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- + + ScriptRegisterFunction( g_pScriptVM, NPrint, "Notification print" ); + ScriptRegisterFunction( g_pScriptVM, NXPrint, "Notification print, customised" ); + +#ifndef CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, SaveEntityKVToTable, "Saves an entity's keyvalues to a table." ); + ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromKeyValues, "Spawns an entity with the keyvalues in a CScriptKeyValues handle." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchSpawn, "DispatchSpawn", "Spawns an unspawned entity." ); +#endif + + ScriptRegisterFunction( g_pScriptVM, CreateDamageInfo, "" ); + ScriptRegisterFunction( g_pScriptVM, DestroyDamageInfo, "" ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateExplosiveDamageForce, "CalculateExplosiveDamageForce", "Fill out a damage info handle with a damage force for an explosive." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateBulletDamageForce, "CalculateBulletDamageForce", "Fill out a damage info handle with a damage force for a bullet impact." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateMeleeDamageForce, "CalculateMeleeDamageForce", "Fill out a damage info handle with a damage force for a melee impact." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGuessDamageForce, "GuessDamageForce", "Try and guess the physics force to use." ); + + ScriptRegisterFunction( g_pScriptVM, CreateFireBulletsInfo, "" ); + ScriptRegisterFunction( g_pScriptVM, DestroyFireBulletsInfo, "" ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLineComplex, "TraceLineComplex", "Complex version of TraceLine which takes 2 points, an ent to ignore, a trace mask, and a collision group. Returns a handle which can access all trace info." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceHullComplex, "TraceHullComplex", "Takes 2 points, min/max hull bounds, an ent to ignore, a trace mask, and a collision group to trace to a point using a hull. Returns a handle which can access all trace info." ); + + // + // VPhysics + // + ScriptRegisterFunction( g_pScriptVM, GetPhysVelocity, "Gets physics velocity for the given VPhysics object" ); + ScriptRegisterFunction( g_pScriptVM, GetPhysAngVelocity, "Gets physics angular velocity for the given VPhysics object" ); + ScriptRegisterFunction( g_pScriptVM, SetPhysVelocity, "Sets physics velocity for the given VPhysics object" ); + ScriptRegisterFunction( g_pScriptVM, AddPhysVelocity, "Adds physics velocity for the given VPhysics object" ); + + // + // Precaching + // + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPrecacheModel, "PrecacheModel", "Precaches a model for later usage." ); + ScriptRegisterFunction( g_pScriptVM, PrecacheMaterial, "Precaches a material for later usage." ); + ScriptRegisterFunction( g_pScriptVM, PrecacheParticleSystem, "Precaches a particle system for later usage." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPrecacheOther, "PrecacheOther", "Precaches an entity class for later usage." ); + + // + // NPCs + // +#ifndef CLIENT_DLL + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptInsertSound, "InsertAISound", "Inserts an AI sound." ); + + ScriptRegisterFunctionNamed( g_pScriptVM, CAI_BaseNPC::GetActivityName, "GetActivityName", "Gets the name of the specified activity index." ); +#endif + + // + // Misc. Utility + // + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesInBox, "EntitiesInBox", "Gets all entities which are within a worldspace box. This function copies them to an array with a maximum number of elements." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesAtPoint, "EntitiesAtPoint", "Gets all entities which are intersecting a point in space. This function copies them to an array with a maximum number of elements." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesInSphere, "EntitiesInSphere", "Gets all entities which are within a sphere. This function copies them to an array with a maximum number of elements." ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDecalTrace, "DecalTrace", "Creates a dynamic decal based on the given trace info. The trace information can be generated by TraceLineComplex() and the decal name must be from decals_subrect.txt." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchParticleEffect, "DoDispatchParticleEffect", SCRIPT_ALIAS( "DispatchParticleEffect", "Dispatches a one-off particle system" ) ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateRope, "CreateRope", "Creates a single rope between two entities. Can optionally follow specific attachments." ); +#ifndef CLIENT_DLL + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateRopeWithSecondPointDetached, "CreateRopeWithSecondPointDetached", "Creates a single detached rope hanging from a point. Can optionally follow a specific start attachment." ); +#endif + + ScriptRegisterFunction( g_pScriptVM, EmitSoundParamsOn, "Play EmitSound_t params on an entity." ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." ); + ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." ); + ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." ); + +#ifndef CLIENT_DLL + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPredictedPosition, "PredictedPosition", "Predicts what an entity's position will be in a given amount of time." ); +#endif + +#ifndef CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, IsDedicatedServer, "Is this a dedicated server?" ); +#endif + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsServer, "IsServer", "Returns true if the script is being run on the server." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsClient, "IsClient", "Returns true if the script is being run on the client." ); + ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Simulation tick interval" ); + ScriptRegisterFunction( g_pScriptVM, GetFrameCount, "Absolute frame counter" ); + //ScriptRegisterFunction( g_pScriptVM, GetTickCount, "Simulation ticks" ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsWindows, "IsWindows", "Returns true if the game is being run on a Windows machine." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsLinux, "IsLinux", "Returns true if the game is being run on a Linux machine." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsOSX, "IsOSX", "Returns true if the game is being run on an OSX machine." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsPosix, "IsPosix", "Returns true if the game is being run on a Posix machine." ); + + RegisterScriptSingletons(); +} diff --git a/game/shared/mapbase/vscript_funcs_shared.h b/game/shared/mapbase/vscript_funcs_shared.h new file mode 100644 index 00000000..bcf91741 --- /dev/null +++ b/game/shared/mapbase/vscript_funcs_shared.h @@ -0,0 +1,320 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: See vscript_funcs_shared.cpp +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_FUNCS_SHARED +#define VSCRIPT_FUNCS_SHARED +#ifdef _WIN32 +#pragma once +#endif + +#include "npcevent.h" +#ifdef GAME_DLL +#include "ai_memory.h" +#endif + +//----------------------------------------------------------------------------- +// Exposes surfacedata_t to VScript +//----------------------------------------------------------------------------- +struct scriptsurfacedata_t : public surfacedata_t +{ +public: + float GetFriction() const { return physics.friction; } + float GetThickness() const { return physics.thickness; } + + float GetJumpFactor() const { return game.jumpFactor; } + char GetMaterialChar() const { return game.material; } + + const char* GetSoundStepLeft() const { return physprops->GetString( sounds.stepleft ); } + const char* GetSoundStepRight() const { return physprops->GetString( sounds.stepright ); } + const char* GetSoundImpactSoft() const { return physprops->GetString( sounds.impactSoft ); } + const char* GetSoundImpactHard() const { return physprops->GetString( sounds.impactHard ); } + const char* GetSoundScrapeSmooth() const { return physprops->GetString( sounds.scrapeSmooth ); } + const char* GetSoundScrapeRough() const { return physprops->GetString( sounds.scrapeRough ); } + const char* GetSoundBulletImpact() const { return physprops->GetString( sounds.bulletImpact ); } + const char* GetSoundRolling() const { return physprops->GetString( sounds.rolling ); } + const char* GetSoundBreak() const { return physprops->GetString( sounds.breakSound ); } + const char* GetSoundStrain() const { return physprops->GetString( sounds.strainSound ); } +}; + +//----------------------------------------------------------------------------- +// Exposes csurface_t to VScript +//----------------------------------------------------------------------------- +class CSurfaceScriptHelper +{ +public: + // This class is owned by CScriptGameTrace, and cannot be accessed without being initialised in CScriptGameTrace::RegisterSurface() + //CSurfaceScriptHelper() : m_pSurface(NULL), m_hSurfaceData(NULL) {} + + ~CSurfaceScriptHelper() + { + g_pScriptVM->RemoveInstance( m_hSurfaceData ); + } + + void Init( csurface_t *surf ) + { + m_pSurface = surf; + m_hSurfaceData = g_pScriptVM->RegisterInstance( + reinterpret_cast< scriptsurfacedata_t* >( physprops->GetSurfaceData( m_pSurface->surfaceProps ) ) ); + } + + const char* Name() const { return m_pSurface->name; } + HSCRIPT SurfaceProps() const { return m_hSurfaceData; } + +private: + csurface_t *m_pSurface; + HSCRIPT m_hSurfaceData; +}; + +//----------------------------------------------------------------------------- +// Exposes cplane_t to VScript +//----------------------------------------------------------------------------- +class CPlaneTInstanceHelper : public IScriptInstanceHelper +{ + bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ) + { + cplane_t *pi = ((cplane_t *)p); + if (FStrEq(pszKey, "normal")) + variant = pi->normal; + else if (FStrEq(pszKey, "dist")) + variant = pi->dist; + else + return false; + + return true; + } + + //bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); +}; + +//----------------------------------------------------------------------------- +// Exposes trace_t to VScript +//----------------------------------------------------------------------------- +class CScriptGameTrace : public CGameTrace +{ +public: + CScriptGameTrace() : m_surfaceAccessor(NULL), m_planeAccessor(NULL) + { + m_hScriptInstance = g_pScriptVM->RegisterInstance( this ); + } + + ~CScriptGameTrace() + { + if ( m_hScriptInstance ) + { + g_pScriptVM->RemoveInstance( m_hScriptInstance ); + } + + if ( m_surfaceAccessor ) + { + g_pScriptVM->RemoveInstance( m_surfaceAccessor ); + } + + if ( m_planeAccessor ) + { + g_pScriptVM->RemoveInstance( m_planeAccessor ); + } + } + + void RegisterSurface() + { + m_surfaceHelper.Init( &surface ); + m_surfaceAccessor = g_pScriptVM->RegisterInstance( &m_surfaceHelper ); + } + + void RegisterPlane() + { + m_planeAccessor = g_pScriptVM->RegisterInstance( &plane ); + } + + HSCRIPT GetScriptInstance() const + { + return m_hScriptInstance; + } + +public: + float FractionLeftSolid() const { return fractionleftsolid; } + int HitGroup() const { return hitgroup; } + int PhysicsBone() const { return physicsbone; } + + HSCRIPT Entity() const { return ToHScript( m_pEnt ); } + int HitBox() const { return hitbox; } + + const Vector& StartPos() const { return startpos; } + const Vector& EndPos() const { return endpos; } + + float Fraction() const { return fraction; } + + int Contents() const { return contents; } + int DispFlags() const { return dispFlags; } + + bool AllSolid() const { return allsolid; } + bool StartSolid() const { return startsolid; } + + HSCRIPT Surface() const { return m_surfaceAccessor; } + HSCRIPT Plane() const { return m_planeAccessor; } + + void Destroy() { delete this; } + +private: + HSCRIPT m_surfaceAccessor; + HSCRIPT m_planeAccessor; + HSCRIPT m_hScriptInstance; + + CSurfaceScriptHelper m_surfaceHelper; + + CScriptGameTrace( const CScriptGameTrace& v ); +}; + +//----------------------------------------------------------------------------- +// Exposes animevent_t to VScript +//----------------------------------------------------------------------------- +struct scriptanimevent_t : public animevent_t +{ + int GetEvent() { return event; } + void SetEvent( int nEvent ) { event = nEvent; } + + const char *GetOptions() { return options; } + void SetOptions( const char *pOptions ) { options = pOptions; } + + float GetCycle() { return cycle; } + void SetCycle( float flCycle ) { cycle = flCycle; } + + float GetEventTime() { return eventtime; } + void SetEventTime( float flEventTime ) { eventtime = flEventTime; } + + int GetType() { return type; } + void SetType( int nType ) { eventtime = type; } + + HSCRIPT GetSource() { return ToHScript( pSource ); } + void SetSource( HSCRIPT hSource ) + { + CBaseEntity *pEnt = ToEnt( hSource ); + if (pEnt) + pSource = pEnt->GetBaseAnimating(); + } +}; + +class CAnimEventTInstanceHelper : public IScriptInstanceHelper +{ + bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ); + bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); +}; + +//----------------------------------------------------------------------------- +// Exposes EmitSound_t to VScript +//----------------------------------------------------------------------------- +struct ScriptEmitSound_t : public EmitSound_t +{ + int GetChannel() { return m_nChannel; } + void SetChannel( int nChannel ) { m_nChannel = nChannel; } + + const char *GetSoundName() { return m_pSoundName; } + void SetSoundName( const char *pSoundName ) { m_pSoundName = pSoundName; } + + float GetVolume() { return m_flVolume; } + void SetVolume( float flVolume ) { m_flVolume = flVolume; } + + int GetSoundLevel() { return m_SoundLevel; } + void SetSoundLevel( int iSoundLevel ) { m_SoundLevel = (soundlevel_t)iSoundLevel; } + + int GetFlags() { return m_nFlags; } + void SetFlags( int nFlags ) { m_nFlags = nFlags; } + + int GetSpecialDSP() { return m_nSpecialDSP; } + void SetSpecialDSP( int nSpecialDSP ) { m_nSpecialDSP = nSpecialDSP; } + + bool HasOrigin() { return m_pOrigin ? true : false; } + const Vector &GetOrigin() { return m_pOrigin ? *m_pOrigin : vec3_origin; } + void SetOrigin( const Vector &origin ) { static Vector tempOrigin; tempOrigin = origin; m_pOrigin = &tempOrigin; } + void ClearOrigin() { m_pOrigin = NULL; } + + float GetSoundTime() { return m_flSoundTime; } + void SetSoundTime( float flSoundTime ) { m_flSoundTime = flSoundTime; } + + float GetEmitCloseCaption() { return m_bEmitCloseCaption; } + void SetEmitCloseCaption( bool bEmitCloseCaption ) { m_bEmitCloseCaption = bEmitCloseCaption; } + + float GetWarnOnMissingCloseCaption() { return m_bWarnOnMissingCloseCaption; } + void SetWarnOnMissingCloseCaption( bool bWarnOnMissingCloseCaption ) { m_bWarnOnMissingCloseCaption = bWarnOnMissingCloseCaption; } + + float GetWarnOnDirectWaveReference() { return m_bWarnOnDirectWaveReference; } + void SetWarnOnDirectWaveReference( bool bWarnOnDirectWaveReference ) { m_bWarnOnDirectWaveReference = bWarnOnDirectWaveReference; } + + int GetSpeakerEntity() { return m_nSpeakerEntity; } + void SetSpeakerEntity( int nSpeakerEntity ) { m_nSpeakerEntity = nSpeakerEntity; } + + int GetSoundScriptHandle() { return m_hSoundScriptHandle; } + void SetSoundScriptHandle( int hSoundScriptHandle ) { m_hSoundScriptHandle = hSoundScriptHandle; } +}; + +//----------------------------------------------------------------------------- +// Exposes CUserCmd to VScript +//----------------------------------------------------------------------------- +class CScriptUserCmd : public CUserCmd +{ +public: + int GetCommandNumber() { return command_number; } + + int ScriptGetTickCount() { return tick_count; } + + const QAngle& GetViewAngles() { return viewangles; } + void SetViewAngles( const QAngle& val ) { viewangles = val; } + + float GetForwardMove() { return forwardmove; } + void SetForwardMove( float val ) { forwardmove = val; } + float GetSideMove() { return sidemove; } + void SetSideMove( float val ) { sidemove = val; } + float GetUpMove() { return upmove; } + void SetUpMove( float val ) { upmove = val; } + + int GetButtons() { return buttons; } + void SetButtons( int val ) { buttons = val; } + int GetImpulse() { return impulse; } + void SetImpulse( int val ) { impulse = val; } + + int GetWeaponSelect() { return weaponselect; } + void SetWeaponSelect( int val ) { weaponselect = val; } + int GetWeaponSubtype() { return weaponsubtype; } + void SetWeaponSubtype( int val ) { weaponsubtype = val; } + + int GetRandomSeed() { return random_seed; } + + int GetMouseX() { return mousedx; } + void SetMouseX( int val ) { mousedx = val; } + int GetMouseY() { return mousedy; } + void SetMouseY( int val ) { mousedy = val; } +}; + +#ifdef GAME_DLL +//----------------------------------------------------------------------------- +// Exposes AI_EnemyInfo_t to VScript +//----------------------------------------------------------------------------- +struct Script_AI_EnemyInfo_t : public AI_EnemyInfo_t +{ + #define ENEMY_INFO_SCRIPT_FUNCS(type, name, var) \ + type Get##name() { return var; } \ + void Set##name( type v ) { var = v; } + + HSCRIPT Enemy() { return ToHScript(hEnemy); } + void SetEnemy( HSCRIPT ent ) { hEnemy = ToEnt(ent); } + + ENEMY_INFO_SCRIPT_FUNCS( Vector, LastKnownLocation, vLastKnownLocation ); + ENEMY_INFO_SCRIPT_FUNCS( Vector, LastSeenLocation, vLastSeenLocation ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastSeen, timeLastSeen ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeFirstSeen, timeFirstSeen ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastReacquired, timeLastReacquired ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeValidEnemy, timeValidEnemy ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastReceivedDamageFrom, timeLastReceivedDamageFrom ); + ENEMY_INFO_SCRIPT_FUNCS( float, TimeAtFirstHand, timeAtFirstHand ); + ENEMY_INFO_SCRIPT_FUNCS( bool, DangerMemory, bDangerMemory ); + ENEMY_INFO_SCRIPT_FUNCS( bool, EludedMe, bEludedMe ); + ENEMY_INFO_SCRIPT_FUNCS( bool, Unforgettable, bUnforgettable ); + ENEMY_INFO_SCRIPT_FUNCS( bool, MobbedMe, bMobbedMe ); +}; +#endif + +#endif diff --git a/game/shared/mapbase/vscript_singletons.cpp b/game/shared/mapbase/vscript_singletons.cpp new file mode 100644 index 00000000..ed24aaec --- /dev/null +++ b/game/shared/mapbase/vscript_singletons.cpp @@ -0,0 +1,3337 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: This file contains brand new VScript singletons and singletons replicated from API +// documentation in other games. +// +// See vscript_funcs_shared.cpp for more information. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include +#include +#include "ammodef.h" +#include "tier1/utlcommon.h" +#include "utlbuffer.h" + +#ifndef CLIENT_DLL +#include "ai_squad.h" +#endif // !CLIENT_DLL + +#include "usermessages.h" +#include "filesystem.h" +#include "igameevents.h" +#include "engine/ivdebugoverlay.h" + +#ifdef CLIENT_DLL +#include "IEffects.h" +#include "fx.h" +#include "itempents.h" +#include "c_te_legacytempents.h" +#include "iefx.h" +#include "dlight.h" + +#if !defined(NO_STEAM) +#include "steam/steam_api.h" +#endif +#endif + +#include "vscript_singletons.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern IScriptManager *scriptmanager; + +//============================================================================= +// Net Prop Manager +// Based on L4D2 API +//============================================================================= +class CScriptNetPropManager +{ +public: + +#ifdef CLIENT_DLL + RecvProp *RecurseTable( RecvTable *pTable, const char *pszPropName ) +#else + SendProp *RecurseTable( SendTable *pTable, const char *pszPropName ) +#endif + { +#ifdef CLIENT_DLL + RecvProp *pProp = NULL; +#else + SendProp *pProp = NULL; +#endif + for (int i = 0; i < pTable->GetNumProps(); i++) + { + pProp = pTable->GetProp( i ); + if (pProp->GetType() == DPT_DataTable) + { + pProp = RecurseTable(pProp->GetDataTable(), pszPropName); + if (pProp) + return pProp; + } + else + { + if (FStrEq( pProp->GetName(), pszPropName )) + return pProp; + } + } + + return NULL; + } + +#ifdef CLIENT_DLL + RecvProp *RecurseNetworkClass( ClientClass *pClass, const char *pszPropName ) +#else + SendProp *RecurseNetworkClass( ServerClass *pClass, const char *pszPropName ) +#endif + { +#ifdef CLIENT_DLL + RecvProp *pProp = RecurseTable( pClass->m_pRecvTable, pszPropName ); +#else + SendProp *pProp = RecurseTable( pClass->m_pTable, pszPropName ); +#endif + if (pProp) + return pProp; + + if (pClass->m_pNext) + return RecurseNetworkClass( pClass->m_pNext, pszPropName ); + else + return NULL; + } + +#ifdef CLIENT_DLL + RecvProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName ) + { + if (pEnt) + { + return RecurseNetworkClass( pEnt->GetClientClass(), pszPropName ); + } + + return NULL; + } +#else + SendProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName ) + { + if (pEnt) + { + return RecurseNetworkClass( pEnt->GetServerClass(), pszPropName ); + } + + return NULL; + } +#endif + + int GetPropArraySize( HSCRIPT hEnt, const char *pszPropName ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp) + { + // TODO: Is this what this function wants? + return pProp->GetNumElements(); + } + + return -1; + } + + #define GetPropFunc( name, varType, propType, defaultval ) \ + varType name( HSCRIPT hEnt, const char *pszPropName ) \ + { \ + CBaseEntity *pEnt = ToEnt( hEnt ); \ + auto *pProp = GetPropByName( pEnt, pszPropName ); \ + if (pProp && pProp->GetType() == propType) \ + { \ + return *(varType*)((char *)pEnt + pProp->GetOffset()); \ + } \ + return defaultval; \ + } \ + + #define GetPropFuncArray( name, varType, propType, defaultval ) \ + varType name( HSCRIPT hEnt, const char *pszPropName, int iArrayElement ) \ + { \ + CBaseEntity *pEnt = ToEnt( hEnt ); \ + auto *pProp = GetPropByName( pEnt, pszPropName ); \ + if (pProp && pProp->GetType() == propType) \ + { \ + return ((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement]; \ + } \ + return defaultval; \ + } \ + + GetPropFunc( GetPropFloat, float, DPT_Float, -1 ); + GetPropFuncArray( GetPropFloatArray, float, DPT_Float, -1 ); + GetPropFunc( GetPropInt, int, DPT_Int, -1 ); + GetPropFuncArray( GetPropIntArray, int, DPT_Int, -1 ); + GetPropFunc( GetPropVector, Vector, DPT_Vector, vec3_invalid ); + GetPropFuncArray( GetPropVectorArray, Vector, DPT_Vector, vec3_invalid ); + + HSCRIPT GetPropEntity( HSCRIPT hEnt, const char *pszPropName ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + return ToHScript( *(CHandle*)((char *)pEnt + pProp->GetOffset()) ); + } + + return NULL; + } + + HSCRIPT GetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + return ToHScript( ((CHandle*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] ); + } + + return NULL; + } + + const char *GetPropString( HSCRIPT hEnt, const char *pszPropName ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + return (const char*)((char *)pEnt + pProp->GetOffset()); + } + + return NULL; + } + + const char *GetPropStringArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + return ((const char**)((char *)pEnt + pProp->GetOffset()))[iArrayElement]; + } + + return NULL; + } + + const char *GetPropType( HSCRIPT hEnt, const char *pszPropName ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp) + { + switch (pProp->GetType()) + { + case DPT_Int: return "integer"; + case DPT_Float: return "float"; + case DPT_Vector: return "vector"; + case DPT_VectorXY: return "vector2d"; + case DPT_String: return "string"; + case DPT_Array: return "array"; + case DPT_DataTable: return "datatable"; + } + } + + return NULL; + } + + bool HasProp( HSCRIPT hEnt, const char *pszPropName ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + return GetPropByName( pEnt, pszPropName ) != NULL; + } + + #define SetPropFunc( name, varType, propType ) \ + void name( HSCRIPT hEnt, const char *pszPropName, varType value ) \ + { \ + CBaseEntity *pEnt = ToEnt( hEnt ); \ + auto *pProp = GetPropByName( pEnt, pszPropName ); \ + if (pProp && pProp->GetType() == propType) \ + { \ + *(varType*)((char *)pEnt + pProp->GetOffset()) = value; \ + } \ + } \ + + #define SetPropFuncArray( name, varType, propType ) \ + void name( HSCRIPT hEnt, const char *pszPropName, varType value, int iArrayElement ) \ + { \ + CBaseEntity *pEnt = ToEnt( hEnt ); \ + auto *pProp = GetPropByName( pEnt, pszPropName ); \ + if (pProp && pProp->GetType() == propType) \ + { \ + ((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = value; \ + } \ + } \ + + SetPropFunc( SetPropFloat, float, DPT_Float ); + SetPropFuncArray( SetPropFloatArray, float, DPT_Float ); + SetPropFunc( SetPropInt, int, DPT_Int ); + SetPropFuncArray( SetPropIntArray, int, DPT_Int ); + SetPropFunc( SetPropVector, Vector, DPT_Vector ); + SetPropFuncArray( SetPropVectorArray, Vector, DPT_Vector ); + SetPropFunc( SetPropString, const char*, DPT_String ); + SetPropFuncArray( SetPropStringArray, const char*, DPT_String ); + + void SetPropEntity( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + *((CHandle*)((char *)pEnt + pProp->GetOffset())) = ToEnt(value); + } + } + + HSCRIPT SetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value, int iArrayElement ) + { + CBaseEntity *pEnt = ToEnt( hEnt ); + auto *pProp = GetPropByName( pEnt, pszPropName ); + if (pProp && pProp->GetType() == DPT_Int) + { + ((CHandle*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = ToEnt(value); + } + + return NULL; + } + +private: +} g_ScriptNetPropManager; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptNetPropManager, "CNetPropManager", SCRIPT_SINGLETON "Allows reading and updating the network properties of an entity." ) + DEFINE_SCRIPTFUNC( GetPropArraySize, "Returns the size of an netprop array, or -1." ) + DEFINE_SCRIPTFUNC( GetPropEntity, "Reads an EHANDLE valued netprop (21 bit integer). Returns the script handle of the entity." ) + DEFINE_SCRIPTFUNC( GetPropEntityArray, "Reads an EHANDLE valued netprop (21 bit integer) from an array. Returns the script handle of the entity." ) + DEFINE_SCRIPTFUNC( GetPropFloat, "Reads a float valued netprop." ) + DEFINE_SCRIPTFUNC( GetPropFloatArray, "Reads a float valued netprop from an array." ) + DEFINE_SCRIPTFUNC( GetPropInt, "Reads an integer valued netprop." ) + DEFINE_SCRIPTFUNC( GetPropIntArray, "Reads an integer valued netprop from an array." ) + DEFINE_SCRIPTFUNC( GetPropString, "Reads a string valued netprop." ) + DEFINE_SCRIPTFUNC( GetPropStringArray, "Reads a string valued netprop from an array." ) + DEFINE_SCRIPTFUNC( GetPropVector, "Reads a 3D vector valued netprop." ) + DEFINE_SCRIPTFUNC( GetPropVectorArray, "Reads a 3D vector valued netprop from an array." ) + DEFINE_SCRIPTFUNC( GetPropType, "Returns the name of the netprop type as a string." ) + DEFINE_SCRIPTFUNC( HasProp, "Checks if a netprop exists." ) + DEFINE_SCRIPTFUNC( SetPropEntity, "Sets an EHANDLE valued netprop (21 bit integer) to reference the specified entity." ) + DEFINE_SCRIPTFUNC( SetPropEntityArray, "Sets an EHANDLE valued netprop (21 bit integer) from an array to reference the specified entity." ) + DEFINE_SCRIPTFUNC( SetPropFloat, "Sets a netprop to the specified float." ) + DEFINE_SCRIPTFUNC( SetPropFloatArray, "Sets a netprop from an array to the specified float." ) + DEFINE_SCRIPTFUNC( SetPropInt, "Sets a netprop to the specified integer." ) + DEFINE_SCRIPTFUNC( SetPropIntArray, "Sets a netprop from an array to the specified integer." ) + DEFINE_SCRIPTFUNC( SetPropString, "Sets a netprop to the specified string." ) + DEFINE_SCRIPTFUNC( SetPropStringArray, "Sets a netprop from an array to the specified string." ) + DEFINE_SCRIPTFUNC( SetPropVector, "Sets a netprop to the specified vector." ) + DEFINE_SCRIPTFUNC( SetPropVectorArray, "Sets a netprop from an array to the specified vector." ) +END_SCRIPTDESC(); + +//============================================================================= +// Localization Interface +// Unique to Mapbase +//============================================================================= +class CScriptLocalize +{ +public: + + const char *GetTokenAsUTF8( const char *pszToken ) + { + const char *pText = g_pVGuiLocalize->FindAsUTF8( pszToken ); + if ( pText ) + { + return pText; + } + + return NULL; + } + + void AddStringAsUTF8( const char *pszToken, const char *pszString ) + { + wchar_t wpszString[256]; + g_pVGuiLocalize->ConvertANSIToUnicode( pszString, wpszString, sizeof(wpszString) ); + + // TODO: This is a fake file name! Should "fileName" mean anything? + g_pVGuiLocalize->AddString( pszToken, wpszString, "resource/vscript_localization.txt" ); + } + +private: +} g_ScriptLocalize; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptLocalize, "CLocalize", SCRIPT_SINGLETON "Accesses functions related to localization strings." ) + + DEFINE_SCRIPTFUNC( GetTokenAsUTF8, "Gets the current language's token as a UTF-8 string (not Unicode)." ) + + DEFINE_SCRIPTFUNC( AddStringAsUTF8, "Adds a new localized token as a UTF-8 string (not Unicode)." ) + +END_SCRIPTDESC(); + +//============================================================================= +// Game Event Listener +// Based on Source 2 API +// +// NOTE: In Source 2 vscript (Lua) event listener contexts are tables that are +// passed to the callback function as the call environment. +// In mapbase implementation these are string identifiers because unlike Lua, +// Squirrel has closure methods such as 'bindenv' which can bind functions to specified environments. +//============================================================================= + +// Define to use the older code that loads all events manually independent from the game event manager. +// Otherwise access event descriptors directly from engine. +//#define USE_OLD_EVENT_DESCRIPTORS 1 + +class CScriptGameEventListener : public IGameEventListener2, public CAutoGameSystem +{ +public: + CScriptGameEventListener() : m_bActive(false) + { +#ifdef _DEBUG + m_nEventTick = 0; +#endif + } + + ~CScriptGameEventListener() + { + StopListeningForEvent(); + } + + int ListenToGameEvent( const char* szEvent, HSCRIPT hFunc, const char* szContext ); + void StopListeningForEvent(); + +public: + static bool StopListeningToGameEvent( int listener ); + static void StopListeningToAllGameEvents( const char* szContext ); + +public: + void FireGameEvent( IGameEvent *event ); + void LevelShutdownPreEntity(); + +private: + //int m_index; + HSCRIPT m_hCallback; + unsigned int m_iContextHash; + bool m_bActive; +#ifdef _DEBUG + int m_nEventTick; +#endif + + static StringHashFunctor Hash; + static inline unsigned int HashContext( const char* c ) { return c ? Hash(c) : 0; } + + inline int GetIndex() + { + Assert( sizeof(CScriptGameEventListener*) == sizeof(int) ); + return reinterpret_cast(this); + } + +public: + enum // event data types, dependant on engine definitions + { + TYPE_LOCAL = 0, + TYPE_STRING = 1, + TYPE_FLOAT = 2, + TYPE_LONG = 3, + TYPE_SHORT = 4, + TYPE_BYTE = 5, + TYPE_BOOL = 6 + }; + static void WriteEventData( IGameEvent *event, HSCRIPT hTable ); + +#ifdef USE_OLD_EVENT_DESCRIPTORS + static void LoadAllEvents(); + static void LoadEventsFromFile( const char *filename, const char *pathID = NULL ); + static CUtlMap< unsigned int, KeyValues* > s_GameEvents; + static CUtlVector< KeyValues* > s_LoadedFiles; +#endif + +public: + //static int g_nIndexCounter; + static CUtlVectorAutoPurge< CScriptGameEventListener* > s_Listeners; +#if _DEBUG + static void DumpEventListeners(); +#endif + +}; + +CUtlVectorAutoPurge< CScriptGameEventListener* > CScriptGameEventListener::s_Listeners; +StringHashFunctor CScriptGameEventListener::Hash; + +#ifdef USE_OLD_EVENT_DESCRIPTORS +CUtlMap< unsigned int, KeyValues* > CScriptGameEventListener::s_GameEvents( DefLessFunc(unsigned int) ); +CUtlVector< KeyValues* > CScriptGameEventListener::s_LoadedFiles; +#endif + + +#if _DEBUG +#ifdef CLIENT_DLL +CON_COMMAND_F( cl_dump_script_game_event_listeners, "Dump all game event listeners created from script.", FCVAR_CHEAT ) +{ + CScriptGameEventListener::DumpEventListeners(); +} +#else +CON_COMMAND_F( dump_script_game_event_listeners, "Dump all game event listeners created from script.", FCVAR_CHEAT ) +{ + CScriptGameEventListener::DumpEventListeners(); +} +#endif +#endif + + +#ifdef USE_OLD_EVENT_DESCRIPTORS +//----------------------------------------------------------------------------- +// Executed in LevelInitPreEntity +//----------------------------------------------------------------------------- +void CScriptGameEventListener::LoadAllEvents() +{ + // Listed in the same order they are loaded in GameEventManager + const char *filenames[] = + { + "resource/serverevents.res", + "resource/gameevents.res", + "resource/mapbaseevents.res", + "resource/modevents.res" + }; + + const char *pathlist[] = + { + "GAME", + "MOD" + }; + + // Destroy old KeyValues + if ( s_LoadedFiles.Count() ) + { + for ( int i = s_LoadedFiles.Count(); i--; ) + s_LoadedFiles[i]->deleteThis(); + s_LoadedFiles.Purge(); + s_GameEvents.Purge(); + } + + for ( int j = 0; j < ARRAYSIZE(pathlist); ++j ) + for ( int i = 0; i < ARRAYSIZE(filenames); ++i ) + { + LoadEventsFromFile( filenames[i], pathlist[j] ); + } +} + +//----------------------------------------------------------------------------- +// Load event files into a lookup array to be able to return the event data to the VM. +//----------------------------------------------------------------------------- +void CScriptGameEventListener::LoadEventsFromFile( const char *filename, const char *pathID ) +{ + KeyValues *pKV = new KeyValues("GameEvents"); + + if ( !pKV->LoadFromFile( filesystem, filename, pathID ) ) + { + // CGMsg( 1, CON_GROUP_VSCRIPT, "CScriptGameEventListener::LoadEventsFromFile: Failed to load file [%s]%s\n", pathID, filename ); + pKV->deleteThis(); + return; + } + + int count = 0; + + for ( KeyValues *key = pKV->GetFirstSubKey(); key; key = key->GetNextKey() ) + { + for ( KeyValues *sub = key->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) + { + if ( sub->GetDataType() == KeyValues::TYPE_STRING ) + { + const char *szVal = sub->GetString(); + if ( !V_stricmp( szVal, "string" ) ) + { + sub->SetInt( NULL, TYPE_STRING ); + } + else if ( !V_stricmp( szVal, "bool" ) ) + { + sub->SetInt( NULL, TYPE_BOOL ); + } + else if ( !V_stricmp( szVal, "byte" ) ) + { + sub->SetInt( NULL, TYPE_BYTE ); + } + else if ( !V_stricmp( szVal, "short" ) ) + { + sub->SetInt( NULL, TYPE_SHORT ); + } + else if ( !V_stricmp( szVal, "long" ) ) + { + sub->SetInt( NULL, TYPE_LONG ); + } + else if ( !V_stricmp( szVal, "float" ) ) + { + sub->SetInt( NULL, TYPE_FLOAT ); + } + } + // none : value is not networked + // string : a zero terminated string + // bool : unsigned int, 1 bit + // byte : unsigned int, 8 bit + // short : signed int, 16 bit + // long : signed int, 32 bit + // float : float, 32 bit + } + + // Store event subkeys + // Replace key so modevents can overwrite gameevents. + // It does not check for hash collisions, however. + s_GameEvents.InsertOrReplace( Hash( key->GetName() ), key ); + ++count; + } + + // Store files (allocated KV) + s_LoadedFiles.AddToTail( pKV ); + + CGMsg( 2, CON_GROUP_VSCRIPT, "CScriptGameEventListener::LoadEventsFromFile: Loaded [%s]%s (%i)\n", pathID, filename, count ); +} +#endif + +#if _DEBUG +void CScriptGameEventListener::DumpEventListeners() +{ + CGMsg( 0, CON_GROUP_VSCRIPT, "--- Script game event listener dump start\n" ); + CGMsg( 0, CON_GROUP_VSCRIPT, "# ID CONTEXT\n" ); + FOR_EACH_VEC( s_Listeners, i ) + { + CGMsg( 0, CON_GROUP_VSCRIPT, " %d : %d : %u\n", i, + s_Listeners[i]->GetIndex(), + s_Listeners[i]->m_iContextHash ); + } + CGMsg( 0, CON_GROUP_VSCRIPT, "--- Script game event listener dump end\n" ); +} +#endif + +void CScriptGameEventListener::LevelShutdownPreEntity() +{ + s_Listeners.FindAndFastRemove(this); + delete this; +} + +void CScriptGameEventListener::FireGameEvent( IGameEvent *event ) +{ +#ifdef _DEBUG + m_nEventTick = gpGlobals->tickcount; +#endif + ScriptVariant_t hTable; + g_pScriptVM->CreateTable( hTable ); + WriteEventData( event, hTable ); + g_pScriptVM->SetValue( hTable, "game_event_listener", GetIndex() ); + // g_pScriptVM->SetValue( hTable, "game_event_name", event->GetName() ); + g_pScriptVM->ExecuteFunction( m_hCallback, &hTable, 1, NULL, NULL, true ); + g_pScriptVM->ReleaseScript( hTable ); +} + +struct CGameEventDescriptor +{ + byte _0[36]; + KeyValues *m_pEventKeys; + //byte _1[22]; +}; + +class CGameEvent__// : public IGameEvent +{ +public: + virtual ~CGameEvent__(); // [0] + CGameEventDescriptor *m_pDescriptor; // 0x04 + //KeyValues *m_pEventData; // 0x08 +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CScriptGameEventListener::WriteEventData( IGameEvent *event, HSCRIPT hTable ) +{ +#ifdef USE_OLD_EVENT_DESCRIPTORS + int i = s_GameEvents.Find( Hash( event->GetName() ) ); + if ( i == s_GameEvents.InvalidIndex() ) + return; + KeyValues *pKV = s_GameEvents[i]; +#endif + +#if defined(_DEBUG) && !defined(USE_OLD_EVENT_DESCRIPTORS) + try + { +#endif + +#if !defined(USE_OLD_EVENT_DESCRIPTORS) + KeyValues *pKV = reinterpret_cast< CGameEvent__* >(event)->m_pDescriptor->m_pEventKeys; +#endif + + for ( KeyValues *sub = pKV->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) + { + const char *szKey = sub->GetName(); + switch ( sub->GetInt() ) + { + case TYPE_LOCAL: + case TYPE_STRING: g_pScriptVM->SetValue( hTable, szKey, event->GetString( szKey ) ); break; + case TYPE_FLOAT: g_pScriptVM->SetValue( hTable, szKey, event->GetFloat ( szKey ) ); break; + case TYPE_BOOL: g_pScriptVM->SetValue( hTable, szKey, event->GetBool ( szKey ) ); break; + default: g_pScriptVM->SetValue( hTable, szKey, event->GetInt ( szKey ) ); + } + } + +#if defined(_DEBUG) && !defined(USE_OLD_EVENT_DESCRIPTORS) + // Access a bunch of KeyValues functions to validate it is the correct address. + // This may not always throw an exception when it is incorrect, but eventually it will. + } + catch (...) + { + // CGameEvent or CGameEventDescriptor offsets did not match! + // This should mean these were modified in engine.dll. + // + // Implement this utility yourself by adding a function to get event descriptor keys + // either on CGameEventManager or on CGameEvent interfaces. + // On CGameEventManager downcast IGameEvent input to CGameEvent, then return event->descriptor->keys + // On CGameEvent return (member) descriptor->keys + // + // Finally assign it to pKV above. + + Warning("CScriptGameEventListener::WriteEventData internal error\n"); + Assert(0); + } +#endif +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +int CScriptGameEventListener::ListenToGameEvent( const char* szEvent, HSCRIPT hFunc, const char* szContext ) +{ + bool bValid; + + if ( gameeventmanager && hFunc ) +#ifdef CLIENT_DLL + bValid = gameeventmanager->AddListener( this, szEvent, false ); +#else + bValid = gameeventmanager->AddListener( this, szEvent, true ); +#endif + else bValid = false; + + if ( bValid ) + { + m_iContextHash = HashContext( szContext ); + m_hCallback = hFunc; + m_bActive = true; + + s_Listeners.AddToTail( this ); + + return GetIndex(); + } + else + { + delete this; + return 0; + } +} + +//----------------------------------------------------------------------------- +// Free stuff. Called from the destructor, does not remove itself from the listener list. +//----------------------------------------------------------------------------- +void CScriptGameEventListener::StopListeningForEvent() +{ + if ( !m_bActive ) + return; + + if ( g_pScriptVM ) + g_pScriptVM->ReleaseScript( m_hCallback ); + + m_hCallback = NULL; + m_bActive = false; + + if ( gameeventmanager ) + gameeventmanager->RemoveListener( this ); + +#ifdef _DEBUG + // Event listeners are iterated forwards in the game event manager, + // removing while iterating will cause it to skip one listener. + // + // Fix this in engine without altering any behaviour by + // changing event exeuction order to tail->head, + // changing listener removal to tail->head, + // changing listener addition to head + if ( m_nEventTick == gpGlobals->tickcount ) + { + Warning("CScriptGameEventListener stopped in the same frame it was fired. This will break other event listeners!\n"); + } +#endif +} + +//----------------------------------------------------------------------------- +// Stop the specified event listener. +//----------------------------------------------------------------------------- +bool CScriptGameEventListener::StopListeningToGameEvent( int listener ) +{ + CScriptGameEventListener *p = reinterpret_cast(listener); // INT_TO_POINTER + + bool bRemoved = s_Listeners.FindAndFastRemove(p); + if ( bRemoved ) + { + delete p; + } + + return bRemoved; +} + +//----------------------------------------------------------------------------- +// Stops listening to all events within a context. +//----------------------------------------------------------------------------- +void CScriptGameEventListener::StopListeningToAllGameEvents( const char* szContext ) +{ + unsigned int hash = HashContext( szContext ); + for ( int i = s_Listeners.Count(); i--; ) + { + CScriptGameEventListener *pCur = s_Listeners[i]; + if ( pCur->m_iContextHash == hash ) + { + s_Listeners.FastRemove(i); + delete pCur; + } + } +} + +//============================================================================= +//============================================================================= + +static int ListenToGameEvent( const char* szEvent, HSCRIPT hFunc, const char* szContext ) +{ + CScriptGameEventListener *p = new CScriptGameEventListener(); + return p->ListenToGameEvent( szEvent, hFunc, szContext ); +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +static void FireGameEvent( const char* szEvent, HSCRIPT hTable ) +{ + IGameEvent *event = gameeventmanager->CreateEvent( szEvent ); + if ( event ) + { + ScriptVariant_t key, val; + int nIterator = -1; + while ( ( nIterator = g_pScriptVM->GetKeyValue( hTable, nIterator, &key, &val ) ) != -1 ) + { + switch ( val.m_type ) + { + case FIELD_FLOAT: event->SetFloat ( key.m_pszString, val.m_float ); break; + case FIELD_INTEGER: event->SetInt ( key.m_pszString, val.m_int ); break; + case FIELD_BOOLEAN: event->SetBool ( key.m_pszString, val.m_bool ); break; + case FIELD_CSTRING: event->SetString( key.m_pszString, val.m_pszString ); break; + } + + g_pScriptVM->ReleaseValue(key); + g_pScriptVM->ReleaseValue(val); + } + +#ifdef CLIENT_DLL + gameeventmanager->FireEventClientSide(event); +#else + gameeventmanager->FireEvent(event); +#endif + } +} + +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// Copy of FireGameEvent, server only with no broadcast to clients. +//----------------------------------------------------------------------------- +static void FireGameEventLocal( const char* szEvent, HSCRIPT hTable ) +{ + IGameEvent *event = gameeventmanager->CreateEvent( szEvent ); + if ( event ) + { + ScriptVariant_t key, val; + int nIterator = -1; + while ( ( nIterator = g_pScriptVM->GetKeyValue( hTable, nIterator, &key, &val ) ) != -1 ) + { + switch ( val.m_type ) + { + case FIELD_FLOAT: event->SetFloat ( key.m_pszString, val.m_float ); break; + case FIELD_INTEGER: event->SetInt ( key.m_pszString, val.m_int ); break; + case FIELD_BOOLEAN: event->SetBool ( key.m_pszString, val.m_bool ); break; + case FIELD_CSTRING: event->SetString( key.m_pszString, val.m_pszString ); break; + } + + g_pScriptVM->ReleaseValue(key); + g_pScriptVM->ReleaseValue(val); + } + + gameeventmanager->FireEvent(event,true); + } +} +#endif // !CLIENT_DLL + +static ScriptHook_t g_Hook_OnSave; +static ScriptHook_t g_Hook_OnRestore; + +//============================================================================= +// Save/Restore Utility +// Based on L4D2 API +//============================================================================= +class CScriptSaveRestoreUtil : public CAutoGameSystem +{ +public: + static void SaveTable( const char *szId, HSCRIPT hTable ); + static void RestoreTable( const char *szId, HSCRIPT hTable ); + static void ClearSavedTable( const char *szId ); + +public: // IGameSystem + + void OnSave() + { + if ( g_pScriptVM ) + { + if ( GetScriptHookManager().IsEventHooked( "OnSave" ) ) + g_Hook_OnSave.Call( NULL, NULL, NULL ); + + // Legacy hook + HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnSave" ); + if ( hFunc ) + { + g_pScriptVM->Call( hFunc ); + g_pScriptVM->ReleaseScript( hFunc ); + } + } + } + +#ifdef CLIENT_DLL + // On the client, OnRestore() is called before VScript is actually restored, so this has to be called manually from VScript save/restore instead + void OnVMRestore() +#else + void OnRestore() +#endif + { + if ( g_pScriptVM ) + { + if ( GetScriptHookManager().IsEventHooked( "OnRestore" ) ) + g_Hook_OnRestore.Call( NULL, NULL, NULL ); + + // Legacy hook + HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnRestore" ); + if ( hFunc ) + { + g_pScriptVM->Call( hFunc ); + g_pScriptVM->ReleaseScript( hFunc ); + } + } + } + + void Shutdown() + { + FOR_EACH_MAP_FAST( m_Lookup, i ) + m_Lookup[i]->deleteThis(); + m_Lookup.Purge(); + } + +private: + static StringHashFunctor Hash; + static CUtlMap< unsigned int, KeyValues* > m_Lookup; + +} g_ScriptSaveRestoreUtil; + +#ifdef CLIENT_DLL +void VScriptSaveRestoreUtil_OnVMRestore() +{ + g_ScriptSaveRestoreUtil.OnVMRestore(); +} +#endif + +CUtlMap< unsigned int, KeyValues* > CScriptSaveRestoreUtil::m_Lookup( DefLessFunc(unsigned int) ); +StringHashFunctor CScriptSaveRestoreUtil::Hash; + +//----------------------------------------------------------------------------- +// Store a table with primitive values that will persist across level transitions and save loads. +// Case sensitive +//----------------------------------------------------------------------------- +void CScriptSaveRestoreUtil::SaveTable( const char *szId, HSCRIPT hTable ) +{ + KeyValues *pKV; + unsigned int hash = Hash(szId); + + int idx = m_Lookup.Find( hash ); + if ( idx == m_Lookup.InvalidIndex() ) + { + pKV = new KeyValues("ScriptSavedTable"); + m_Lookup.Insert( hash, pKV ); + } + else + { + pKV = m_Lookup[idx]; + pKV->Clear(); + } + + ScriptVariant_t key, val; + int nIterator = -1; + while ( ( nIterator = g_pScriptVM->GetKeyValue( hTable, nIterator, &key, &val ) ) != -1 ) + { + switch ( val.m_type ) + { + case FIELD_FLOAT: pKV->SetFloat ( key.m_pszString, val.m_float ); break; + case FIELD_INTEGER: pKV->SetInt ( key.m_pszString, val.m_int ); break; + case FIELD_BOOLEAN: pKV->SetBool ( key.m_pszString, val.m_bool ); break; + case FIELD_CSTRING: pKV->SetString( key.m_pszString, val.m_pszString ); break; + } + + g_pScriptVM->ReleaseValue(key); + g_pScriptVM->ReleaseValue(val); + } +} + +//----------------------------------------------------------------------------- +// Retrieves a table from storage. Write into input table. +//----------------------------------------------------------------------------- +void CScriptSaveRestoreUtil::RestoreTable( const char *szId, HSCRIPT hTable ) +{ + int idx = m_Lookup.Find( Hash(szId) ); + if ( idx == m_Lookup.InvalidIndex() ) + { + // DevWarning( 2, "RestoreTable could not find saved table with context '%s'\n", szId ); + return; + } + + KeyValues *pKV = m_Lookup[idx]; + FOR_EACH_SUBKEY( pKV, key ) + { + switch ( key->GetDataType() ) + { + case KeyValues::TYPE_STRING: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetString() ); break; + case KeyValues::TYPE_INT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetInt() ); break; + case KeyValues::TYPE_FLOAT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetFloat() ); break; + } + } +} + +//----------------------------------------------------------------------------- +// Remove a saved table. +//----------------------------------------------------------------------------- +void CScriptSaveRestoreUtil::ClearSavedTable( const char *szId ) +{ + int idx = m_Lookup.Find( Hash(szId) ); + if ( idx != m_Lookup.InvalidIndex() ) + { + m_Lookup[idx]->deleteThis(); + m_Lookup.RemoveAt( idx ); + } + else + { + // DevWarning( 2, "ClearSavedTable could not find saved table with context '%s'\n", szId ); + } +} + +//============================================================================= +// Read/Write to File +// Based on L4D2/Source 2 API +//============================================================================= +#define SCRIPT_MAX_FILE_READ_SIZE (64 * 1024 * 1024) // 64MB +#define SCRIPT_MAX_FILE_WRITE_SIZE (64 * 1024 * 1024) // 64MB +#define SCRIPT_RW_PATH_ID "MOD" +#define SCRIPT_RW_FULL_PATH_FMT "vscript_io/%s" + +class CScriptReadWriteFile : public CAutoGameSystem +{ + // A singleton class with all static members is used to be able to free the read string on level shutdown, + // and register script funcs directly. Same reason applies to CScriptSaveRestoreUtil +public: + static bool FileWrite( const char *szFile, const char *szInput ); + static const char *FileRead( const char *szFile ); + static bool FileExists( const char *szFile ); + + // NOTE: These two functions are new with Mapbase and have no Valve equivalent + static bool KeyValuesWrite( const char *szFile, HSCRIPT hInput ); + static HSCRIPT KeyValuesRead( const char *szFile ); + + void LevelShutdownPostEntity() + { + if ( m_pszReturnReadFile ) + { + delete[] m_pszReturnReadFile; + m_pszReturnReadFile = NULL; + } + } + +private: + static char *m_pszReturnReadFile; + +} g_ScriptReadWrite; + +char *CScriptReadWriteFile::m_pszReturnReadFile = NULL; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CScriptReadWriteFile::FileWrite( const char *szFile, const char *szInput ) +{ + size_t len = strlen(szInput); + if ( len > SCRIPT_MAX_FILE_WRITE_SIZE ) + { + DevWarning( 2, "Input is too large for a ScriptFileWrite ( %s / %d MB )\n", V_pretifymem(len,2,true), (SCRIPT_MAX_FILE_WRITE_SIZE >> 20) ); + return false; + } + + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + return false; + } + + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + buf.PutString(szInput); + + int nSize = V_strlen(pszFullName) + 1; + char *pszDir = (char*)stackalloc(nSize); + V_memcpy( pszDir, pszFullName, nSize ); + V_StripFilename( pszDir ); + + g_pFullFileSystem->CreateDirHierarchy( pszDir, SCRIPT_RW_PATH_ID ); + bool res = g_pFullFileSystem->WriteFile( pszFullName, SCRIPT_RW_PATH_ID, buf ); + buf.Purge(); + return res; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +const char *CScriptReadWriteFile::FileRead( const char *szFile ) +{ + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + return NULL; + } + + unsigned int size = g_pFullFileSystem->Size( pszFullName, SCRIPT_RW_PATH_ID ); + if ( size >= SCRIPT_MAX_FILE_READ_SIZE ) + { + DevWarning( 2, "File '%s' (from '%s') is too large for a ScriptFileRead ( %s / %u bytes )\n", pszFullName, szFile, V_pretifymem(size,2,true), SCRIPT_MAX_FILE_READ_SIZE ); + return NULL; + } + + FileHandle_t file = g_pFullFileSystem->Open( pszFullName, "rb", SCRIPT_RW_PATH_ID ); + if ( !file ) + { + return NULL; + } + + // Close the previous buffer + if (m_pszReturnReadFile) + g_pFullFileSystem->FreeOptimalReadBuffer( m_pszReturnReadFile ); + + unsigned bufSize = g_pFullFileSystem->GetOptimalReadSize( file, size + 2 ); + m_pszReturnReadFile = (char*)g_pFullFileSystem->AllocOptimalReadBuffer( file, bufSize ); + + bool bRetOK = ( g_pFullFileSystem->ReadEx( m_pszReturnReadFile, bufSize, size, file ) != 0 ); + g_pFullFileSystem->Close( file ); // close file after reading + + if ( bRetOK ) + { + m_pszReturnReadFile[size] = 0; // null terminate file as EOF + //buffer[size+1] = 0; // double NULL terminating in case this is a unicode file + return m_pszReturnReadFile; + } + else + { + return NULL; + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CScriptReadWriteFile::FileExists( const char *szFile ) +{ + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + return NULL; + } + + return g_pFullFileSystem->FileExists( pszFullName, SCRIPT_RW_PATH_ID ); +} + +//----------------------------------------------------------------------------- +// Get the checksum of any file. Can be used to check the existence or validity of a file. +// Returns unsigned int as hex string. +//----------------------------------------------------------------------------- +/* +const char *CScriptReadWriteFile::CRC32_Checksum( const char *szFilename ) +{ + CUtlBuffer buf( 0, 0, CUtlBuffer::READ_ONLY ); + if ( !g_pFullFileSystem->ReadFile( szFilename, NULL, buf ) ) + return NULL; + + // first time calling, allocate + if ( !m_pszReturnCRC32 ) + m_pszReturnCRC32 = new char[9]; // 'FFFFFFFF\0' + + V_snprintf( const_cast(m_pszReturnCRC32), 9, "%X", CRC32_ProcessSingleBuffer( buf.Base(), buf.Size()-1 ) ); + buf.Purge(); + + return m_pszReturnCRC32; +} +*/ + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +bool CScriptReadWriteFile::KeyValuesWrite( const char *szFile, HSCRIPT hInput ) +{ + KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hInput ); + if (!pKV) + { + return false; + } + + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + pKV->RecursiveSaveToFile( buf, 0 ); + + if ( buf.Size() > SCRIPT_MAX_FILE_WRITE_SIZE ) + { + DevWarning( 2, "Input is too large for a ScriptKeyValuesWrite ( %s / %d MB )\n", V_pretifymem(buf.Size(),2,true), (SCRIPT_MAX_FILE_WRITE_SIZE >> 20) ); + buf.Purge(); + return false; + } + + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + buf.Purge(); + return false; + } + + int nSize = V_strlen(pszFullName) + 1; + char *pszDir = (char*)stackalloc(nSize); + V_memcpy( pszDir, pszFullName, nSize ); + V_StripFilename( pszDir ); + + g_pFullFileSystem->CreateDirHierarchy( pszDir, SCRIPT_RW_PATH_ID ); + bool res = g_pFullFileSystem->WriteFile( pszFullName, SCRIPT_RW_PATH_ID, buf ); + buf.Purge(); + return res; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +HSCRIPT CScriptReadWriteFile::KeyValuesRead( const char *szFile ) +{ + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + return NULL; + } + + unsigned int size = g_pFullFileSystem->Size( pszFullName, SCRIPT_RW_PATH_ID ); + if ( size >= SCRIPT_MAX_FILE_READ_SIZE ) + { + DevWarning( 2, "File '%s' (from '%s') is too large for a ScriptKeyValuesRead ( %s / %u bytes )\n", pszFullName, szFile, V_pretifymem(size,2,true), SCRIPT_MAX_FILE_READ_SIZE ); + return NULL; + } + + KeyValues *pKV = new KeyValues( szFile ); + if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFullName, SCRIPT_RW_PATH_ID ) ) + { + pKV->deleteThis(); + return NULL; + } + + HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true ); // bAllowDestruct is supposed to automatically remove the involved KV + + return hScript; +} + + +//============================================================================= +// Network message helper +// (Unique to mapbase) +// +// Uses usermessages for server to client, UserCmd for client to server communication. +// The custom message name is hashed and sent as word with the message. +//============================================================================= + +static CNetMsgScriptHelper scriptnetmsg; +CNetMsgScriptHelper *g_ScriptNetMsg = &scriptnetmsg; + +#ifdef GAME_DLL +#define m_MsgIn_() m_MsgIn-> +#define DLL_LOC_STR "[Server]" +#else +#define m_MsgIn_() m_MsgIn. +#define DLL_LOC_STR "[Client]" +#endif + +#ifdef GAME_DLL +#define SCRIPT_NETMSG_WRITE_FUNC +#else +#define SCRIPT_NETMSG_WRITE_FUNC if ( m_bWriteIgnore ) { return; } +#endif + +#ifdef _DEBUG +#ifdef GAME_DLL +ConVar script_net_debug("script_net_debug", "0"); +#define DebugNetMsg( l, ... ) do { if (script_net_debug.GetInt() >= l) ConColorMsg( Color(100, 225, 255, 255), __VA_ARGS__ ); } while (0); +#else +ConVar script_net_debug("script_net_debug_client", "0"); +#define DebugNetMsg( l, ... ) do { if (script_net_debug.GetInt() >= l) ConColorMsg( Color(100, 225, 175, 255), __VA_ARGS__ ); } while (0); +#endif +#define DebugWarning(...) Warning( __VA_ARGS__ ) +#else +#define DebugNetMsg(...) (void)(0) +#define DebugWarning(...) (void)(0) +#endif + + +// Keep track of message names to print on failure +#ifdef _DEBUG +struct NetMsgHook_t +{ + void Set( const char *s ) + { + hash = CNetMsgScriptHelper::Hash( s ); + name = strdup(s); + } + + ~NetMsgHook_t() + { + free( name ); + } + + int hash; + char *name; +}; + +CUtlVector< NetMsgHook_t > g_NetMsgHooks; + +static const char *GetNetMsgName( int hash ) +{ + FOR_EACH_VEC( g_NetMsgHooks, i ) + { + if ( g_NetMsgHooks[i].hash == hash ) + return g_NetMsgHooks[i].name; + } + return 0; +} + +static const char *HasNetMsgCollision( int hash, const char *ignore ) +{ + FOR_EACH_VEC( g_NetMsgHooks, i ) + { + if ( g_NetMsgHooks[i].hash == hash && V_strcmp( g_NetMsgHooks[i].name, ignore ) != 0 ) + { + return g_NetMsgHooks[i].name; + } + } + return 0; +} +#endif // _DEBUG + + + +inline int CNetMsgScriptHelper::Hash( const char *key ) +{ + int hash = HashStringCaseless( key ); + Assert( hash < (1 << SCRIPT_NETMSG_HEADER_BITS) ); + return hash; +} + +void CNetMsgScriptHelper::WriteToBuffer( bf_write *bf ) +{ +#ifdef CLIENT_DLL + Assert( m_nQueueCount < ( 1 << SCRIPT_NETMSG_QUEUE_BITS ) ); + bf->WriteUBitLong( m_nQueueCount, SCRIPT_NETMSG_QUEUE_BITS ); + + DebugNetMsg( 2, DLL_LOC_STR " CNetMsgScriptHelper::WriteToBuffer() count(%d) size(%d)\n", + m_nQueueCount, m_MsgOut.GetNumBitsWritten() + SCRIPT_NETMSG_QUEUE_BITS ); +#endif + + bf->WriteBits( m_MsgOut.GetData(), m_MsgOut.GetNumBitsWritten() ); +} + +//----------------------------------------------------------------------------- +// Reset the current network message buffer +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::Reset() +{ + m_MsgOut.StartWriting( m_MsgData, sizeof(m_MsgData), 0 ); +#ifdef GAME_DLL + m_filter.Reset(); +#else + m_iLastBit = 0; +#endif +} + +//----------------------------------------------------------------------------- +// Create the storage for the receiver callback functions. +// Functions are handled in the VM, the storage table is here. +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::InitPostVM() +{ + ScriptVariant_t hHooks; + g_pScriptVM->CreateTable( hHooks ); + m_Hooks = (HSCRIPT)hHooks; +} + +void CNetMsgScriptHelper::LevelShutdownPreVM() +{ + Reset(); + if ( m_Hooks ) + g_pScriptVM->ReleaseScript( m_Hooks ); + m_Hooks = NULL; + +#ifdef CLIENT_DLL + m_bWriteReady = m_bWriteIgnore = false; + m_MsgIn.Reset(); +#else + m_MsgIn = NULL; +#endif + +#ifdef _DEBUG + g_NetMsgHooks.Purge(); +#endif +} + +#ifdef CLIENT_DLL + +bool CNetMsgScriptHelper::Init() // IGameSystem +{ + usermessages->HookMessage( "ScriptMsg", __MsgFunc_ScriptMsg ); + return true; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::__MsgFunc_ScriptMsg( bf_read &msg ) +{ + g_ScriptNetMsg->ReceiveMessage( msg ); +} + +#endif // CLIENT_DLL + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +#ifdef GAME_DLL +void CNetMsgScriptHelper::ReceiveMessage( bf_read *msg, CBaseEntity *pPlayer ) +{ + m_MsgIn = msg; +#else +void CNetMsgScriptHelper::ReceiveMessage( bf_read &msg ) +{ + m_MsgIn.StartReading( msg.m_pData, msg.m_nDataBytes ); +#endif + + DebugNetMsg( 2, DLL_LOC_STR " %s()\n", __FUNCTION__ ); + + // Don't do anything if there's no VM here. This can happen if a message from the server goes to a VM-less client, or vice versa. + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, DLL_LOC_STR " CNetMsgScriptHelper: No VM on receiving side\n" ); + return; + } + +#ifdef GAME_DLL + int count = m_MsgIn_()ReadUBitLong( SCRIPT_NETMSG_QUEUE_BITS ); + DebugNetMsg( 2, " msg count %d\n", count ); + while ( count-- ) +#endif + { + int hash = m_MsgIn_()ReadWord(); + +#ifdef _DEBUG + const char *msgName = GetNetMsgName( hash ); + DebugNetMsg( 2, " -- begin msg [%d]%s\n", hash, msgName ); +#endif + + ScriptVariant_t hfn; + if ( g_pScriptVM->GetValue( m_Hooks, hash, &hfn ) ) + { +#ifdef GAME_DLL + if ( g_pScriptVM->Call( hfn, NULL, true, NULL, pPlayer->m_hScriptInstance ) == SCRIPT_ERROR ) +#else + if ( g_pScriptVM->ExecuteFunction( hfn, NULL, 0, NULL, NULL, true ) == SCRIPT_ERROR ) +#endif + { +#ifdef _DEBUG + DevWarning( 1, DLL_LOC_STR " NetMsg: invalid callback '%s'\n", GetNetMsgName( hash ) ); +#else + DevWarning( 1, DLL_LOC_STR " NetMsg: invalid callback [%d]\n", hash ); +#endif + } + g_pScriptVM->ReleaseValue( hfn ); + } + else + { + DevWarning( 1, DLL_LOC_STR " NetMsg hook not found [%d]\n", hash ); + } + + DebugNetMsg( 2, " -- end msg\n" ); + } +} + +//----------------------------------------------------------------------------- +// Start writing new custom network message +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::Start( const char *msg ) +{ + if ( !msg || !msg[0] ) + { + g_pScriptVM->RaiseException( DLL_LOC_STR "NetMsg: invalid message name" ); + return; + } + + DebugNetMsg( 1, DLL_LOC_STR " %s() [%d]%s\n", __FUNCTION__, Hash( msg ), msg ); + +#ifdef CLIENT_DLL + // Client can write multiple messages in a frame before the usercmd is sent, + // this queue system ensures client messages are written to the cmd all at once. + // NOTE: All messages share the same buffer. + if ( !m_bWriteReady ) + { + Reset(); + m_nQueueCount = 0; + m_bWriteIgnore = false; + } + else if ( m_nQueueCount == ((1< client +// +// Sends an exclusive usermessage. +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::Send( HSCRIPT player, bool bReliable ) +{ + DebugNetMsg( 1, DLL_LOC_STR " %s() size(%d)\n", __FUNCTION__, GetNumBitsWritten() ); + + CBaseEntity *pPlayer = ToEnt(player); + if ( pPlayer ) + { + m_filter.AddRecipient( (CBasePlayer*)pPlayer ); + } + + if ( bReliable ) + { + m_filter.MakeReliable(); + } + + Assert( usermessages->LookupUserMessage( "ScriptMsg" ) != -1 ); + + DoSendUserMsg( &m_filter, usermessages->LookupUserMessage( "ScriptMsg" ) ); +} +#else // CLIENT_DLL +//----------------------------------------------------------------------------- +// client -> server +// +// Mark UserCmd delta ready. +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::Send() +{ + DebugNetMsg( 1, DLL_LOC_STR " %s() size(%d)\n", __FUNCTION__, m_bWriteIgnore ? 0 : GetNumBitsWritten() ); + + m_bWriteReady = true; +} +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::Receive( const char *msg, HSCRIPT func ) +{ + if ( !msg || !msg[0] ) + { + g_pScriptVM->RaiseException( DLL_LOC_STR "NetMsg: invalid message name" ); + return; + } + +#ifdef _DEBUG + int hash = Hash( msg ); + + const char *psz = HasNetMsgCollision( hash, msg ); + AssertMsg3( !psz, DLL_LOC_STR " NetMsg hash collision! [%d] '%s', '%s'\n", hash, msg, psz ); + + NetMsgHook_t &hook = g_NetMsgHooks[ g_NetMsgHooks.AddToTail() ]; + hook.Set( msg ); +#endif + + if ( func ) + { + g_pScriptVM->SetValue( m_Hooks, Hash( msg ), func ); + } + else + { + g_pScriptVM->ClearValue( m_Hooks, Hash( msg ) ); + } +} + +#ifdef GAME_DLL +void CNetMsgScriptHelper::DoSendUserMsg( CRecipientFilter *filter, int type ) +{ + WriteToBuffer( engine->UserMessageBegin( filter, type ) ); + engine->MessageEnd(); +} + +void CNetMsgScriptHelper::DoSendEntityMsg( CBaseEntity *entity, bool reliable ) +{ + WriteToBuffer( engine->EntityMessageBegin( entity->entindex(), entity->GetServerClass(), reliable ) ); + engine->MessageEnd(); +} + +//----------------------------------------------------------------------------- +// Send a usermessage from the server to the client +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::SendUserMessage( HSCRIPT hPlayer, const char *msg, bool bReliable ) +{ + int msg_type = usermessages->LookupUserMessage(msg); + if ( msg_type == -1 ) + { + g_pScriptVM->RaiseException( UTIL_VarArgs("SendUserMessage: Unregistered message '%s'", msg) ); + return; + } + + CBaseEntity *pPlayer = ToEnt(hPlayer); + if ( pPlayer ) + { + m_filter.AddRecipient( (CBasePlayer*)pPlayer ); + } + + if ( bReliable ) + { + m_filter.MakeReliable(); + } + + DoSendUserMsg( &m_filter, msg_type ); +} + +//----------------------------------------------------------------------------- +// Send a message from a server side entity to its client side counterpart +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::SendEntityMessage( HSCRIPT hEnt, bool bReliable ) +{ + CBaseEntity *entity = ToEnt(hEnt); + if ( !entity ) + { + g_pScriptVM->RaiseException("SendEntityMessage: invalid entity"); + return; + } + + DoSendEntityMsg( entity, bReliable ); +} +#else +//----------------------------------------------------------------------------- +// Dispatch a usermessage on client +//----------------------------------------------------------------------------- +void CNetMsgScriptHelper::DispatchUserMessage( const char *msg ) +{ + bf_read buffer( m_MsgOut.GetData(), m_MsgOut.GetNumBytesWritten() ); + usermessages->DispatchUserMessage( usermessages->LookupUserMessage(msg), buffer ); +} +#endif // GAME_DLL + +void CNetMsgScriptHelper::WriteInt( int iValue, int bits ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteSBitLong( iValue, bits ); +} + +void CNetMsgScriptHelper::WriteUInt( int iValue, int bits ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteUBitLong( iValue, bits ); +} + +void CNetMsgScriptHelper::WriteByte( int iValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteByte( iValue ); +} + +void CNetMsgScriptHelper::WriteChar( int iValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteChar( iValue ); +} + +void CNetMsgScriptHelper::WriteShort( int iValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteShort( iValue ); +} + +void CNetMsgScriptHelper::WriteWord( int iValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteWord( iValue ); +} + +void CNetMsgScriptHelper::WriteLong( int iValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteLong( iValue ); +} + +void CNetMsgScriptHelper::WriteFloat( float flValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteFloat( flValue ); +} + +void CNetMsgScriptHelper::WriteNormal( float flValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitNormal( flValue ); +} + +void CNetMsgScriptHelper::WriteAngle( float flValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitAngle( flValue, 8 ); +} + +void CNetMsgScriptHelper::WriteCoord( float flValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitCoord( flValue ); +} + +void CNetMsgScriptHelper::WriteVec3Coord( const Vector& rgflValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitVec3Coord( rgflValue ); +} + +void CNetMsgScriptHelper::WriteVec3Normal( const Vector& rgflValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitVec3Normal( rgflValue ); +} + +void CNetMsgScriptHelper::WriteAngles( const QAngle& rgflValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteBitAngles( rgflValue ); +} + +void CNetMsgScriptHelper::WriteString( const char *sz ) +{ + SCRIPT_NETMSG_WRITE_FUNC + + // Larger strings can be written but cannot be read + Assert( V_strlen(sz) < SCRIPT_NETMSG_STRING_SIZE ); + + m_MsgOut.WriteString( sz ); +} + +void CNetMsgScriptHelper::WriteBool( bool bValue ) +{ + SCRIPT_NETMSG_WRITE_FUNC + m_MsgOut.WriteOneBit( bValue ? 1 : 0 ); +} + +void CNetMsgScriptHelper::WriteEntity( HSCRIPT hEnt ) +{ + SCRIPT_NETMSG_WRITE_FUNC + CBaseEntity *p = ToEnt(hEnt); + int i = p ? p->entindex() : 0; + m_MsgOut.WriteUBitLong( i, MAX_EDICT_BITS ); +} + +void CNetMsgScriptHelper::WriteEHandle( HSCRIPT hEnt ) +{ + SCRIPT_NETMSG_WRITE_FUNC + CBaseEntity *pEnt = ToEnt( hEnt ); + long iEncodedEHandle; + if ( pEnt ) + { + EHANDLE hEnt = pEnt; + int iSerialNum = hEnt.GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1; + iEncodedEHandle = hEnt.GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS); + } + else + { + iEncodedEHandle = INVALID_NETWORKED_EHANDLE_VALUE; + } + m_MsgOut.WriteLong( iEncodedEHandle ); +} + +int CNetMsgScriptHelper::ReadInt( int bits ) +{ + return m_MsgIn_()ReadSBitLong(bits); +} + +int CNetMsgScriptHelper::ReadUInt( int bits ) +{ + return m_MsgIn_()ReadUBitLong(bits); +} + +int CNetMsgScriptHelper::ReadByte() +{ + return m_MsgIn_()ReadByte(); +} + +int CNetMsgScriptHelper::ReadChar() +{ + return m_MsgIn_()ReadChar(); +} + +int CNetMsgScriptHelper::ReadShort() +{ + return m_MsgIn_()ReadShort(); +} + +int CNetMsgScriptHelper::ReadWord() +{ + return m_MsgIn_()ReadWord(); +} + +int CNetMsgScriptHelper::ReadLong() +{ + return m_MsgIn_()ReadLong(); +} + +float CNetMsgScriptHelper::ReadFloat() +{ + return m_MsgIn_()ReadFloat(); +} + +float CNetMsgScriptHelper::ReadNormal() +{ + return m_MsgIn_()ReadBitNormal(); +} + +float CNetMsgScriptHelper::ReadAngle() +{ + return m_MsgIn_()ReadBitAngle( 8 ); +} + +float CNetMsgScriptHelper::ReadCoord() +{ + return m_MsgIn_()ReadBitCoord(); +} + +const Vector& CNetMsgScriptHelper::ReadVec3Coord() +{ + static Vector vec3; + m_MsgIn_()ReadBitVec3Coord(vec3); + return vec3; +} + +const Vector& CNetMsgScriptHelper::ReadVec3Normal() +{ + static Vector vec3; + m_MsgIn_()ReadBitVec3Normal(vec3); + return vec3; +} + +const QAngle& CNetMsgScriptHelper::ReadAngles() +{ + static QAngle vec3; + m_MsgIn_()ReadBitAngles(vec3); + return vec3; +} + +const char* CNetMsgScriptHelper::ReadString() +{ + static char buf[ SCRIPT_NETMSG_STRING_SIZE ]; + m_MsgIn_()ReadString( buf, sizeof(buf) ); + return buf; +} + +bool CNetMsgScriptHelper::ReadBool() +{ + return m_MsgIn_()ReadOneBit(); +} + +HSCRIPT CNetMsgScriptHelper::ReadEntity() +{ + int index = m_MsgIn_()ReadUBitLong( MAX_EDICT_BITS ); + + if ( !index ) + return NULL; + +#ifdef GAME_DLL + edict_t *e = INDEXENT(index); + if ( e && !e->IsFree() ) + { + return ToHScript( GetContainingEntity(e) ); + } +#else // CLIENT_DLL + if ( index < NUM_ENT_ENTRIES ) + { + return ToHScript( CBaseEntity::Instance(index) ); + } +#endif + return NULL; +} + +HSCRIPT CNetMsgScriptHelper::ReadEHandle() +{ + int iEncodedEHandle = m_MsgIn_()ReadLong(); + if ( iEncodedEHandle == INVALID_NETWORKED_EHANDLE_VALUE ) + return NULL; + int iEntry = iEncodedEHandle & ( (1 << MAX_EDICT_BITS) - 1 ); + int iSerialNum = iEncodedEHandle >> MAX_EDICT_BITS; + return ToHScript( EHANDLE( iEntry, iSerialNum ) ); +} + +inline int CNetMsgScriptHelper::GetNumBitsWritten() +{ +#ifdef GAME_DLL + return m_MsgOut.GetNumBitsWritten() - SCRIPT_NETMSG_HEADER_BITS; +#else + return m_MsgOut.m_iCurBit - m_iLastBit - SCRIPT_NETMSG_HEADER_BITS; +#endif +} + + +BEGIN_SCRIPTDESC_ROOT_NAMED( CNetMsgScriptHelper, "CNetMsg", SCRIPT_SINGLETON "Network messages" ) + +#ifdef GAME_DLL + DEFINE_SCRIPTFUNC( SendUserMessage, "Send a usermessage from the server to the client" ) + DEFINE_SCRIPTFUNC( SendEntityMessage, "Send a message from a server side entity to its client side counterpart" ) + + // TODO: multiplayer +#else + DEFINE_SCRIPTFUNC( DispatchUserMessage, "Dispatch a usermessage on client" ) +#endif + + DEFINE_SCRIPTFUNC( Reset, "Reset the current network message buffer" ) + DEFINE_SCRIPTFUNC( Start, "Start writing new custom network message" ) + DEFINE_SCRIPTFUNC( Receive, "Set custom network message callback" ) + DEFINE_SCRIPTFUNC_NAMED( Receive, "Recieve", SCRIPT_HIDE ) // This was a typo until v6.3 +#ifdef GAME_DLL + DEFINE_SCRIPTFUNC( Send, "Send a custom network message from the server to the client (max 252 bytes)" ) +#else + DEFINE_SCRIPTFUNC( Send, "Send a custom network message from the client to the server (max 2044 bytes)" ) +#endif + + DEFINE_SCRIPTFUNC( WriteInt, "variable bit signed int" ) + DEFINE_SCRIPTFUNC( WriteUInt, "variable bit unsigned int" ) + DEFINE_SCRIPTFUNC( WriteByte, "8 bit unsigned char" ) + DEFINE_SCRIPTFUNC( WriteChar, "8 bit char" ) + DEFINE_SCRIPTFUNC( WriteShort, "16 bit short" ) + DEFINE_SCRIPTFUNC( WriteWord, "16 bit unsigned short" ) + DEFINE_SCRIPTFUNC( WriteLong, "32 bit long" ) + DEFINE_SCRIPTFUNC( WriteFloat, "32 bit float" ) + DEFINE_SCRIPTFUNC( WriteNormal, "12 bit" ) + DEFINE_SCRIPTFUNC( WriteAngle, "8 bit unsigned char" ) + DEFINE_SCRIPTFUNC( WriteCoord, "" ) + DEFINE_SCRIPTFUNC( WriteVec3Coord, "" ) + DEFINE_SCRIPTFUNC( WriteVec3Normal, "27 bit" ) + DEFINE_SCRIPTFUNC( WriteAngles, "" ) + DEFINE_SCRIPTFUNC( WriteString, "max 512 bytes at once" ) + DEFINE_SCRIPTFUNC( WriteBool, "1 bit" ) + DEFINE_SCRIPTFUNC( WriteEntity, "11 bit (entindex)" ) + DEFINE_SCRIPTFUNC( WriteEHandle, "32 bit long" ) + + DEFINE_SCRIPTFUNC( ReadInt, "" ) + DEFINE_SCRIPTFUNC( ReadUInt, "" ) + DEFINE_SCRIPTFUNC( ReadByte, "" ) + DEFINE_SCRIPTFUNC( ReadChar, "" ) + DEFINE_SCRIPTFUNC( ReadShort, "" ) + DEFINE_SCRIPTFUNC( ReadWord, "" ) + DEFINE_SCRIPTFUNC( ReadLong, "" ) + DEFINE_SCRIPTFUNC( ReadFloat, "" ) + DEFINE_SCRIPTFUNC( ReadNormal, "" ) + DEFINE_SCRIPTFUNC( ReadAngle, "" ) + DEFINE_SCRIPTFUNC( ReadCoord, "" ) + DEFINE_SCRIPTFUNC( ReadVec3Coord, "" ) + DEFINE_SCRIPTFUNC( ReadVec3Normal, "" ) + DEFINE_SCRIPTFUNC( ReadAngles, "" ) + DEFINE_SCRIPTFUNC( ReadString, "" ) + DEFINE_SCRIPTFUNC( ReadBool, "" ) + DEFINE_SCRIPTFUNC( ReadEntity, "" ) + DEFINE_SCRIPTFUNC( ReadEHandle, "" ) + + DEFINE_SCRIPTFUNC( GetNumBitsWritten, "" ) + +END_SCRIPTDESC(); + + + +#define RETURN_IF_CANNOT_DRAW_OVERLAY\ + if (engine->IsPaused())\ + return; +class CDebugOverlayScriptHelper +{ +public: + + void Box( const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddBoxOverlay(origin, mins, maxs, vec3_angle, r, g, b, a, flDuration); + } + void BoxDirection( const Vector &origin, const Vector &mins, const Vector &maxs, const Vector &forward, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + QAngle f_angles = vec3_angle; + f_angles.y = UTIL_VecToYaw(forward); + + debugoverlay->AddBoxOverlay(origin, mins, maxs, f_angles, r, g, b, a, flDuration); + } + void BoxAngles( const Vector &origin, const Vector &mins, const Vector &maxs, const QAngle &angles, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddBoxOverlay(origin, mins, maxs, angles, r, g, b, a, flDuration); + } + void SweptBox( const Vector& start, const Vector& end, const Vector& mins, const Vector& maxs, const QAngle & angles, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddSweptBoxOverlay(start, end, mins, maxs, angles, r, g, b, a, flDuration); + } + void EntityBounds( HSCRIPT pEntity, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + CBaseEntity *pEnt = ToEnt(pEntity); + if (!pEnt) + return; + + const CCollisionProperty *pCollide = pEnt->CollisionProp(); + debugoverlay->AddBoxOverlay(pCollide->GetCollisionOrigin(), pCollide->OBBMins(), pCollide->OBBMaxs(), pCollide->GetCollisionAngles(), r, g, b, a, flDuration); + } + void Line( const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddLineOverlay(origin, target, r, g, b, noDepthTest, flDuration); + } + void Triangle( const Vector &p1, const Vector &p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddTriangleOverlay(p1, p2, p3, r, g, b, a, noDepthTest, duration); + } + void EntityText( int entityID, int text_offset, const char *text, float flDuration, int r, int g, int b, int a ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddEntityTextOverlay(entityID, text_offset, flDuration, + (int)clamp(r * 255.f, 0.f, 255.f), (int)clamp(g * 255.f, 0.f, 255.f), (int)clamp(b * 255.f, 0.f, 255.f), + (int)clamp(a * 255.f, 0.f, 255.f), text); + } + void EntityTextAtPosition( const Vector &origin, int text_offset, const char *text, float flDuration, int r, int g, int b, int a ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddTextOverlayRGB(origin, text_offset, flDuration, r, g, b, a, "%s", text); + } + void Grid( const Vector &vPosition ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddGridOverlay(vPosition); + } + void Text( const Vector &origin, const char *text, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddTextOverlay(origin, flDuration, "%s", text); + } + void ScreenText( float fXpos, float fYpos, const char *text, int r, int g, int b, int a, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + debugoverlay->AddScreenTextOverlay(fXpos, fYpos, flDuration, r, g, b, a, text); + } + void Cross3D( const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Line( position + Vector(size,0,0), position - Vector(size,0,0), r, g, b, noDepthTest, flDuration ); + Line( position + Vector(0,size,0), position - Vector(0,size,0), r, g, b, noDepthTest, flDuration ); + Line( position + Vector(0,0,size), position - Vector(0,0,size), r, g, b, noDepthTest, flDuration ); + } + void Cross3DOriented( const Vector &position, const QAngle &angles, float size, int r, int g, int b, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector forward, right, up; + AngleVectors( angles, &forward, &right, &up ); + + forward *= size; + right *= size; + up *= size; + + Line( position + right, position - right, r, g, b, noDepthTest, flDuration ); + Line( position + forward, position - forward, r, g, b, noDepthTest, flDuration ); + Line( position + up, position - up, r, g, b, noDepthTest, flDuration ); + } + void DrawTickMarkedLine( const Vector &startPos, const Vector &endPos, float tickDist, int tickTextDist, int r, int g, int b, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector lineDir = (endPos - startPos); + float lineDist = VectorNormalize(lineDir); + int numTicks = lineDist / tickDist; + + Vector upVec = Vector(0,0,4); + Vector sideDir; + Vector tickPos = startPos; + int tickTextCnt = 0; + + CrossProduct(lineDir, upVec, sideDir); + + Line(startPos, endPos, r, g, b, noDepthTest, flDuration); + + for (int i = 0; i 0 ) + { + Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); + Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); + Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); + + Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); + Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); + Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); + } + } + void YawArrow( const Vector &startPos, float yaw, float length, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector forward = UTIL_YawToVector( yaw ); + HorzArrow( startPos, startPos + forward * length, width, r, g, b, a, noDepthTest, flDuration ); + } + void VertArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector lineDir = (endPos - startPos); + VectorNormalize( lineDir ); + Vector upVec; + Vector sideDir; + float radius = width / 2.0; + + VectorVectors( lineDir, sideDir, upVec ); + + Vector p1 = startPos - upVec * radius; + Vector p2 = endPos - lineDir * width - upVec * radius; + Vector p3 = endPos - lineDir * width - upVec * width; + Vector p4 = endPos; + Vector p5 = endPos - lineDir * width + upVec * width; + Vector p6 = endPos - lineDir * width + upVec * radius; + Vector p7 = startPos + upVec * radius; + + Line(p1, p2, r,g,b,noDepthTest,flDuration); + Line(p2, p3, r,g,b,noDepthTest,flDuration); + Line(p3, p4, r,g,b,noDepthTest,flDuration); + Line(p4, p5, r,g,b,noDepthTest,flDuration); + Line(p5, p6, r,g,b,noDepthTest,flDuration); + Line(p6, p7, r,g,b,noDepthTest,flDuration); + + if ( a > 0 ) + { + Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); + Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); + Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); + + Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); + Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); + Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); + } + } + void Axis( const Vector &position, const QAngle &angles, float size, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector xvec, yvec, zvec; + AngleVectors( angles, &xvec, &yvec, &zvec ); + + xvec = position + (size * xvec); + yvec = position - (size * yvec); + zvec = position + (size * zvec); + + Line( position, xvec, 255, 0, 0, noDepthTest, flDuration ); + Line( position, yvec, 0, 255, 0, noDepthTest, flDuration ); + Line( position, zvec, 0, 0, 255, noDepthTest, flDuration ); + } + void Sphere( const Vector ¢er, float radius, int r, int g, int b, bool noDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + Vector edge, lastEdge; + + float axisSize = radius; + Line( center + Vector( 0, 0, -axisSize ), center + Vector( 0, 0, axisSize ), r, g, b, noDepthTest, flDuration ); + Line( center + Vector( 0, -axisSize, 0 ), center + Vector( 0, axisSize, 0 ), r, g, b, noDepthTest, flDuration ); + Line( center + Vector( -axisSize, 0, 0 ), center + Vector( axisSize, 0, 0 ), r, g, b, noDepthTest, flDuration ); + + lastEdge = Vector( radius + center.x, center.y, center.z ); + float angle; + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; + edge.y = center.y; + edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } + + lastEdge = Vector( center.x, radius + center.y, center.z ); + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = center.x; + edge.y = radius * cosf( angle / 180.0f * M_PI ) + center.y; + edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } + + lastEdge = Vector( center.x, radius + center.y, center.z ); + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; + edge.y = radius * sinf( angle / 180.0f * M_PI ) + center.y; + edge.z = center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } + } + void CircleOriented( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + matrix3x4_t xform; + AngleMatrix(angles, position, xform); + Vector xAxis, yAxis; + MatrixGetColumn(xform, 2, xAxis); + MatrixGetColumn(xform, 1, yAxis); + Circle(position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration); + } + void Circle( const Vector &position, const Vector &xAxis, const Vector &yAxis, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) + { + RETURN_IF_CANNOT_DRAW_OVERLAY + + const unsigned int nSegments = 16; + const float flRadStep = (M_PI*2.0f) / (float) nSegments; + + Vector vecLastPosition; + Vector vecStart = position + xAxis * radius; + Vector vecPosition = vecStart; + + for ( int i = 1; i <= nSegments; i++ ) + { + vecLastPosition = vecPosition; + + float flSin, flCos; + SinCos( flRadStep*i, &flSin, &flCos ); + vecPosition = position + (xAxis * flCos * radius) + (yAxis * flSin * radius); + + Line( vecLastPosition, vecPosition, r, g, b, bNoDepthTest, flDuration ); + + if ( a && i > 1 ) + { + debugoverlay->AddTriangleOverlay( vecStart, vecLastPosition, vecPosition, r, g, b, a, bNoDepthTest, flDuration ); + } + } + } +#ifndef CLIENT_DLL + void SetDebugBits( HSCRIPT hEntity, int bit ) // DebugOverlayBits_t + { + CBaseEntity *pEnt = ToEnt(hEntity); + if (!pEnt) + return; + + if (pEnt->m_debugOverlays & bit) + { + pEnt->m_debugOverlays &= ~bit; + } + else + { + pEnt->m_debugOverlays |= bit; + +#ifdef AI_MONITOR_FOR_OSCILLATION + if (pEnt->IsNPC()) + { + pEnt->MyNPCPointer()->m_ScheduleHistory.RemoveAll(); + } +#endif//AI_MONITOR_FOR_OSCILLATION + } + } +#endif + void ClearAllOverlays() + { +#ifndef CLIENT_DLL + // Clear all entities of their debug overlays + for (CBaseEntity *pEntity = gEntList.FirstEnt(); pEntity; pEntity = gEntList.NextEnt(pEntity)) + { + pEntity->m_debugOverlays = 0; + } +#endif + + debugoverlay->ClearAllOverlays(); + } + +private: +} g_ScriptDebugOverlay; + +BEGIN_SCRIPTDESC_ROOT( CDebugOverlayScriptHelper, SCRIPT_SINGLETON "CDebugOverlayScriptHelper" ) + DEFINE_SCRIPTFUNC( Box, "Draws a world-space axis-aligned box. Specify bounds in world space." ) + DEFINE_SCRIPTFUNC( BoxDirection, "Draw box oriented to a Vector direction" ) + DEFINE_SCRIPTFUNC( BoxAngles, "Draws an oriented box at the origin. Specify bounds in local space." ) + DEFINE_SCRIPTFUNC( SweptBox, "Draws a swept box. Specify endpoints in world space and the bounds in local space." ) + DEFINE_SCRIPTFUNC( EntityBounds, "Draws bounds of an entity" ) + DEFINE_SCRIPTFUNC( Line, "Draws a line between two points" ) + DEFINE_SCRIPTFUNC( Triangle, "Draws a filled triangle. Specify vertices in world space." ) + DEFINE_SCRIPTFUNC( EntityText, "Draws text on an entity" ) + DEFINE_SCRIPTFUNC( EntityTextAtPosition, "Draw entity text overlay at a specific position" ) + DEFINE_SCRIPTFUNC( Grid, "Add grid overlay" ) + DEFINE_SCRIPTFUNC( Text, "Draws 2D text. Specify origin in world space." ) + DEFINE_SCRIPTFUNC( ScreenText, "Draws 2D text. Specify coordinates in screen space." ) + DEFINE_SCRIPTFUNC( Cross3D, "Draws a world-aligned cross. Specify origin in world space." ) + DEFINE_SCRIPTFUNC( Cross3DOriented, "Draws an oriented cross. Specify origin in world space." ) + DEFINE_SCRIPTFUNC( DrawTickMarkedLine, "Draws a dashed line. Specify endpoints in world space." ) + DEFINE_SCRIPTFUNC( HorzArrow, "Draws a horizontal arrow. Specify endpoints in world space." ) + DEFINE_SCRIPTFUNC( YawArrow, "Draws a arrow associated with a specific yaw. Specify endpoints in world space." ) + DEFINE_SCRIPTFUNC( VertArrow, "Draws a vertical arrow. Specify endpoints in world space." ) + DEFINE_SCRIPTFUNC( Axis, "Draws an axis. Specify origin + orientation in world space." ) + DEFINE_SCRIPTFUNC( Sphere, "Draws a wireframe sphere. Specify center in world space." ) + DEFINE_SCRIPTFUNC( CircleOriented, "Draws a circle oriented. Specify center in world space." ) + DEFINE_SCRIPTFUNC( Circle, "Draws a circle. Specify center in world space." ) +#ifndef CLIENT_DLL + DEFINE_SCRIPTFUNC( SetDebugBits, "Set debug bits on entity" ) +#endif + DEFINE_SCRIPTFUNC( ClearAllOverlays, "Clear all debug overlays at once" ) +END_SCRIPTDESC(); + + + +//============================================================================= +// ConVars +//============================================================================= +class CScriptConCommand : public ConCommand, public ICommandCallback, public ICommandCompletionCallback +{ + typedef ConCommand BaseClass; + +public: + ~CScriptConCommand() + { + Unregister(); + } + + CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags, ConCommand *pLinked = NULL ) + : BaseClass( name, this, helpString, flags, 0 ), + m_pLinked(pLinked), + m_hCallback(fn), + m_hCompletionCallback(NULL) + { + m_nCmdNameLen = V_strlen(name) + 1; + Assert( m_nCmdNameLen - 1 <= 128 ); + } + + void CommandCallback( const CCommand &command ) + { + int count = command.ArgC(); + ScriptVariant_t *vArgv = (ScriptVariant_t*)stackalloc( sizeof(ScriptVariant_t) * count ); + for ( int i = 0; i < count; ++i ) + { + vArgv[i] = command[i]; + } + ScriptVariant_t ret; + if ( g_pScriptVM->ExecuteFunction( m_hCallback, vArgv, count, &ret, NULL, true ) == SCRIPT_ERROR ) + { + DevWarning( 1, "CScriptConCommand: invalid callback for '%s'\n", command[0] ); + } + if ( m_pLinked && (ret.m_type == FIELD_BOOLEAN) && ret.m_bool ) + { + m_pLinked->Dispatch( command ); + } + } + + int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands ) + { + Assert( g_pScriptVM ); + Assert( m_hCompletionCallback ); + + ScriptVariant_t hArray; + g_pScriptVM->CreateArray( hArray ); + + // split command name from partial, pass both separately to the script function + char *cmdname = (char*)stackalloc( m_nCmdNameLen ); + V_memcpy( cmdname, partial, m_nCmdNameLen - 1 ); + cmdname[ m_nCmdNameLen - 1 ] = 0; + + char argPartial[256]; + V_StrRight( partial, V_strlen(partial) - m_nCmdNameLen, argPartial, sizeof(argPartial) ); + + ScriptVariant_t args[3] = { cmdname, argPartial, hArray }; + if ( g_pScriptVM->ExecuteFunction( m_hCompletionCallback, args, 3, NULL, NULL, true ) == SCRIPT_ERROR ) + { + DevWarning( 1, "CScriptConCommand: invalid command completion callback for '%s'\n", cmdname ); + g_pScriptVM->ReleaseScript( hArray ); + return 0; + } + + int count = 0; + ScriptVariant_t val; + int it = -1; + while ( ( it = g_pScriptVM->GetKeyValue( hArray, it, NULL, &val ) ) != -1 ) + { + if ( val.m_type == FIELD_CSTRING ) + { + CUtlString &s = commands.Element( commands.AddToTail() ); + int len = V_strlen( val.m_pszString ); + + if ( len <= COMMAND_COMPLETION_ITEM_LENGTH - 1 ) + { + s.Set( val.m_pszString ); + } + else + { + s.SetDirect( val.m_pszString, COMMAND_COMPLETION_ITEM_LENGTH - 1 ); + } + + ++count; + } + g_pScriptVM->ReleaseValue(val); + + if ( count == COMMAND_COMPLETION_MAXITEMS ) + break; + } + g_pScriptVM->ReleaseScript( hArray ); + return count; + } + + void SetCompletionCallback( HSCRIPT fn ) + { + if ( m_hCompletionCallback ) + g_pScriptVM->ReleaseScript( m_hCompletionCallback ); + + if (fn) + { + if ( !BaseClass::IsRegistered() ) + return; + + BaseClass::m_pCommandCompletionCallback = this; + BaseClass::m_bHasCompletionCallback = true; + m_hCompletionCallback = fn; + } + else + { + BaseClass::m_pCommandCompletionCallback = NULL; + BaseClass::m_bHasCompletionCallback = false; + m_hCompletionCallback = NULL; + } + } + + void SetCallback( HSCRIPT fn ) + { + if (fn) + { + if ( !BaseClass::IsRegistered() ) + Register(); + + if ( m_hCallback ) + g_pScriptVM->ReleaseScript( m_hCallback ); + m_hCallback = fn; + } + else + { + Unregister(); + } + } + + inline void Unregister() + { + if ( g_pCVar && BaseClass::IsRegistered() ) + g_pCVar->UnregisterConCommand( this ); + + if ( g_pScriptVM ) + { + if ( m_hCallback ) + { + g_pScriptVM->ReleaseScript( m_hCallback ); + m_hCallback = NULL; + } + + SetCompletionCallback( NULL ); + } + } + + inline void Register() + { + if ( g_pCVar ) + g_pCVar->RegisterConCommand( this ); + } + + HSCRIPT m_hCallback; + ConCommand *m_pLinked; + HSCRIPT m_hCompletionCallback; + int m_nCmdNameLen; +}; + +class CScriptConVar : public ConVar +{ + typedef ConVar BaseClass; + +public: + ~CScriptConVar() + { + Unregister(); + } + + CScriptConVar( const char *pName, const char *pDefaultValue, const char *pHelpString, int flags/*, float fMin, float fMax*/ ) + : BaseClass( pName, pDefaultValue, flags, pHelpString ), + m_hCallback(NULL) + {} + + void SetChangeCallback( HSCRIPT fn ) + { + void ScriptConVarCallback( IConVar*, const char*, float ); + + if ( m_hCallback ) + g_pScriptVM->ReleaseScript( m_hCallback ); + + if (fn) + { + m_hCallback = fn; + BaseClass::InstallChangeCallback( (FnChangeCallback_t)ScriptConVarCallback ); + } + else + { + m_hCallback = NULL; + BaseClass::InstallChangeCallback( NULL ); + } + } + + inline void Unregister() + { + if ( g_pCVar && BaseClass::IsRegistered() ) + g_pCVar->UnregisterConCommand( this ); + + if ( g_pScriptVM ) + { + SetChangeCallback( NULL ); + } + } + + HSCRIPT m_hCallback; +}; + +static CUtlMap< unsigned int, bool > g_ConVarsBlocked( DefLessFunc(unsigned int) ); +static CUtlMap< unsigned int, bool > g_ConCommandsOverridable( DefLessFunc(unsigned int) ); +static CUtlMap< unsigned int, CScriptConCommand* > g_ScriptConCommands( DefLessFunc(unsigned int) ); +static CUtlMap< unsigned int, CScriptConVar* > g_ScriptConVars( DefLessFunc(unsigned int) ); + + +class CScriptConvarAccessor : public CAutoGameSystem +{ +public: + static inline unsigned int Hash( const char*sz ){ return HashStringCaseless(sz); } + +public: + inline void AddOverridable( const char *name ) + { + g_ConCommandsOverridable.InsertOrReplace( Hash(name), true ); + } + + inline bool IsOverridable( unsigned int hash ) + { + int idx = g_ConCommandsOverridable.Find( hash ); + return ( idx != g_ConCommandsOverridable.InvalidIndex() ); + } + + inline void AddBlockedConVar( const char *name ) + { + g_ConVarsBlocked.InsertOrReplace( Hash(name), true ); + } + + inline bool IsBlockedConvar( const char *name ) + { + int idx = g_ConVarsBlocked.Find( Hash(name) ); + return ( idx != g_ConVarsBlocked.InvalidIndex() ); + } + +public: + void RegisterCommand( const char *name, HSCRIPT fn, const char *helpString, int flags ); + void SetCompletionCallback( const char *name, HSCRIPT fn ); + void UnregisterCommand( const char *name ); + void RegisterConvar( const char *name, const char *pDefaultValue, const char *helpString, int flags ); + void SetChangeCallback( const char *name, HSCRIPT fn ); + + HSCRIPT GetCommandClient() + { +#ifdef GAME_DLL + return ToHScript( UTIL_GetCommandClient() ); +#else + return ToHScript( C_BasePlayer::GetLocalPlayer() ); +#endif + } +#ifdef GAME_DLL + const char *GetClientConvarValue( int index, const char* cvar ) + { + return engine->GetClientConVarValue( index, cvar ); + } +#endif +public: + bool Init(); + + void LevelShutdownPostEntity() + { + g_ScriptConCommands.PurgeAndDeleteElements(); + g_ScriptConVars.PurgeAndDeleteElements(); + } + +public: + float GetFloat( const char *pszConVar ) + { + ConVarRef cvar( pszConVar ); + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return NULL; + return cvar.GetFloat(); + } + + int GetInt( const char *pszConVar ) + { + ConVarRef cvar( pszConVar ); + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return NULL; + return cvar.GetInt(); + } + + bool GetBool( const char *pszConVar ) + { + ConVarRef cvar( pszConVar ); + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return NULL; + return cvar.GetBool(); + } + + const char *GetStr( const char *pszConVar ) + { + ConVarRef cvar( pszConVar ); + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return NULL; + return cvar.GetString(); + } + + const char *GetDefaultValue( const char *pszConVar ) + { + ConVarRef cvar( pszConVar ); + return cvar.GetDefault(); + } + + bool IsFlagSet( const char *pszConVar, int nFlags ) + { + ConVarRef cvar( pszConVar ); + return cvar.IsFlagSet( nFlags ); + } + + void SetFloat( const char *pszConVar, float value ) + { + SetValue( pszConVar, value ); + } + + void SetInt( const char *pszConVar, int value ) + { + SetValue( pszConVar, value ); + } + + void SetBool( const char *pszConVar, bool value ) + { + SetValue( pszConVar, value ); + } + + void SetStr( const char *pszConVar, const char *value ) + { + SetValue( pszConVar, value ); + } + + template + void SetValue( const char *pszConVar, T value ) + { + ConVarRef cvar( pszConVar ); + if ( !cvar.IsValid() ) + return; + + if ( cvar.IsFlagSet( FCVAR_NOT_CONNECTED | FCVAR_SERVER_CANNOT_QUERY ) ) + return; + + if ( IsBlockedConvar( pszConVar ) ) + return; + + cvar.SetValue( value ); + } + +} g_ScriptConvarAccessor; + + +void CScriptConvarAccessor::RegisterCommand( const char *name, HSCRIPT fn, const char *helpString, int flags ) +{ + unsigned int hash = Hash(name); + int idx = g_ScriptConCommands.Find(hash); + if ( idx == g_ScriptConCommands.InvalidIndex() ) + { + ConCommandBase *pBase = g_pCVar->FindCommandBase(name); + if ( pBase && ( !pBase->IsCommand() || !IsOverridable(hash) ) ) + { + DevWarning( 1, "CScriptConvarAccessor::RegisterCommand unable to register blocked ConCommand: %s\n", name ); + return; + } + + if ( !fn ) + return; + + CScriptConCommand *p = new CScriptConCommand( name, fn, helpString, flags, static_cast< ConCommand* >(pBase) ); + g_ScriptConCommands.Insert( hash, p ); + } + else + { + CScriptConCommand *pCmd = g_ScriptConCommands[idx]; + pCmd->SetCallback( fn ); + //CGMsg( 1, CON_GROUP_VSCRIPT, "CScriptConvarAccessor::RegisterCommand replacing command already registered: %s\n", name ); + } +} + +void CScriptConvarAccessor::SetCompletionCallback( const char *name, HSCRIPT fn ) +{ + unsigned int hash = Hash(name); + int idx = g_ScriptConCommands.Find(hash); + if ( idx != g_ScriptConCommands.InvalidIndex() ) + { + g_ScriptConCommands[idx]->SetCompletionCallback( fn ); + } +} + +void CScriptConvarAccessor::UnregisterCommand( const char *name ) +{ + unsigned int hash = Hash(name); + int idx = g_ScriptConCommands.Find(hash); + if ( idx != g_ScriptConCommands.InvalidIndex() ) + { + g_ScriptConCommands[idx]->Unregister(); + } +} + +void CScriptConvarAccessor::RegisterConvar( const char *name, const char *pDefaultValue, const char *helpString, int flags ) +{ + Assert( g_pCVar ); + unsigned int hash = Hash(name); + int idx = g_ScriptConVars.Find(hash); + if ( idx == g_ScriptConVars.InvalidIndex() ) + { + if ( g_pCVar->FindCommandBase(name) ) + { + DevWarning( 1, "CScriptConvarAccessor::RegisterConvar unable to register blocked ConCommand: %s\n", name ); + return; + } + + CScriptConVar *p = new CScriptConVar( name, pDefaultValue, helpString, flags ); + g_ScriptConVars.Insert( hash, p ); + } + else + { + //CGMsg( 1, CON_GROUP_VSCRIPT, "CScriptConvarAccessor::RegisterConvar convar %s already registered\n", name ); + } +} + +void CScriptConvarAccessor::SetChangeCallback( const char *name, HSCRIPT fn ) +{ + unsigned int hash = Hash(name); + int idx = g_ScriptConVars.Find(hash); + if ( idx != g_ScriptConVars.InvalidIndex() ) + { + g_ScriptConVars[idx]->SetChangeCallback( fn ); + } +} + +void ScriptConVarCallback( IConVar *var, const char* pszOldValue, float flOldValue ) +{ + ConVar *cvar = (ConVar*)var; + const char *name = cvar->GetName(); + unsigned int hash = CScriptConvarAccessor::Hash( name ); + int idx = g_ScriptConVars.Find(hash); + if ( idx != g_ScriptConVars.InvalidIndex() ) + { + Assert( g_ScriptConVars[idx]->m_hCallback ); + + ScriptVariant_t args[5] = { name, pszOldValue, flOldValue, cvar->GetString(), cvar->GetFloat() }; + if ( g_pScriptVM->ExecuteFunction( g_ScriptConVars[idx]->m_hCallback, args, 5, NULL, NULL, true ) == SCRIPT_ERROR ) + { + DevWarning( 1, "CScriptConVar: invalid change callback for '%s'\n", name ); + } + } +} + + +bool CScriptConvarAccessor::Init() +{ + static bool bExecOnce = false; + if ( bExecOnce ) + return true; + bExecOnce = true; + + AddOverridable( "+attack" ); + AddOverridable( "+attack2" ); + AddOverridable( "+attack3" ); + AddOverridable( "+forward" ); + AddOverridable( "+back" ); + AddOverridable( "+moveleft" ); + AddOverridable( "+moveright" ); + AddOverridable( "+use" ); + AddOverridable( "+jump" ); + AddOverridable( "+zoom" ); + AddOverridable( "+reload" ); + AddOverridable( "+speed" ); + AddOverridable( "+walk" ); + AddOverridable( "+duck" ); + AddOverridable( "+strafe" ); + AddOverridable( "+alt1" ); + AddOverridable( "+alt2" ); + AddOverridable( "+grenade1" ); + AddOverridable( "+grenade2" ); + AddOverridable( "+showscores" ); + AddOverridable( "+voicerecord" ); + + AddOverridable( "-attack" ); + AddOverridable( "-attack2" ); + AddOverridable( "-attack3" ); + AddOverridable( "-forward" ); + AddOverridable( "-back" ); + AddOverridable( "-moveleft" ); + AddOverridable( "-moveright" ); + AddOverridable( "-use" ); + AddOverridable( "-jump" ); + AddOverridable( "-zoom" ); + AddOverridable( "-reload" ); + AddOverridable( "-speed" ); + AddOverridable( "-walk" ); + AddOverridable( "-duck" ); + AddOverridable( "-strafe" ); + AddOverridable( "-alt1" ); + AddOverridable( "-alt2" ); + AddOverridable( "-grenade1" ); + AddOverridable( "-grenade2" ); + AddOverridable( "-showscores" ); + AddOverridable( "-voicerecord" ); + + AddOverridable( "toggle_duck" ); + AddOverridable( "impulse" ); + AddOverridable( "use" ); + AddOverridable( "lastinv" ); + AddOverridable( "invnext" ); + AddOverridable( "invprev" ); + AddOverridable( "phys_swap" ); + AddOverridable( "slot0" ); + AddOverridable( "slot1" ); + AddOverridable( "slot2" ); + AddOverridable( "slot3" ); + AddOverridable( "slot4" ); + AddOverridable( "slot5" ); + AddOverridable( "slot6" ); + AddOverridable( "slot7" ); + AddOverridable( "slot8" ); + AddOverridable( "slot9" ); + AddOverridable( "slot10" ); + + AddOverridable( "save" ); + AddOverridable( "load" ); + + AddOverridable( "say" ); + AddOverridable( "say_team" ); + + + AddBlockedConVar( "con_enable" ); + AddBlockedConVar( "cl_allowdownload" ); + AddBlockedConVar( "cl_allowupload" ); + AddBlockedConVar( "cl_downloadfilter" ); + + return true; +} + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarAccessor, "CConvars", SCRIPT_SINGLETON "Provides an interface to convars." ) + DEFINE_SCRIPTFUNC( RegisterConvar, "register a new console variable." ) + DEFINE_SCRIPTFUNC( RegisterCommand, "register a console command." ) + DEFINE_SCRIPTFUNC( SetCompletionCallback, "callback is called with 3 parameters (cmd, partial, commands), user strings must be appended to 'commands' array" ) + DEFINE_SCRIPTFUNC( SetChangeCallback, "callback is called with 5 parameters (var, szOldValue, flOldValue, szNewValue, flNewValue)" ) + DEFINE_SCRIPTFUNC( UnregisterCommand, "unregister a console command." ) + DEFINE_SCRIPTFUNC( GetCommandClient, "returns the player who issued this console command." ) +#ifdef GAME_DLL + DEFINE_SCRIPTFUNC( GetClientConvarValue, "Get a convar keyvalue for a specified client" ) +#endif + DEFINE_SCRIPTFUNC( GetFloat, "Returns the convar as a float. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( GetInt, "Returns the convar as an int. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( GetBool, "Returns the convar as a bool. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( GetStr, "Returns the convar as a string. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( GetDefaultValue, "Returns the convar's default value as a string. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( IsFlagSet, "Returns the convar's flags. May return null if no such convar." ) + DEFINE_SCRIPTFUNC( SetFloat, "Sets the value of the convar as a float." ) + DEFINE_SCRIPTFUNC( SetInt, "Sets the value of the convar as an int." ) + DEFINE_SCRIPTFUNC( SetBool, "Sets the value of the convar as a bool." ) + DEFINE_SCRIPTFUNC( SetStr, "Sets the value of the convar as a string." ) +END_SCRIPTDESC(); + + +//============================================================================= +// Effects +// (Unique to mapbase) +// +// At the moment only clientside until a filtering method on server is finalised. +// +// TEs most of the time call IEffects (g_pEffects) or ITempEnts (tempents) on client, +// but they also record for tools recording mode. +// +// On client no TE is suppressed. +// TE flags are found at tempent.h +// +// TODO: +//============================================================================= +#ifdef CLIENT_DLL + +class CEffectsScriptHelper +{ +public: + void DynamicLight( int index, const Vector& origin, int r, int g, int b, int exponent, + float radius, float die, float decay, int style = 0, int flags = 0 ) + { + //te->DynamicLight( filter, delay, &origin, r, g, b, exponent, radius, die, decay ); + dlight_t *dl = effects->CL_AllocDlight( index ); + dl->origin = origin; + dl->color.r = r; + dl->color.g = g; + dl->color.b = b; + dl->color.exponent = exponent; + dl->radius = radius; + dl->die = gpGlobals->curtime + die; + dl->decay = decay; + dl->style = style; + dl->flags = flags; + } + + void Explosion( const Vector& pos, float scale, int radius, int magnitude, int flags ) + { + C_RecipientFilter filter; + filter.AddAllPlayers(); + // framerate, modelindex, normal and materialtype are unused + // radius for ragdolls + extern short g_sModelIndexFireball; + te->Explosion( filter, 0.0f, &pos, g_sModelIndexFireball, scale, 15, flags, radius, magnitude, &vec3_origin ); + } + +// void FXExplosion( const Vector& pos, const Vector& normal, int materialType = 'C' ) +// { +// // just the particles +// // materialtype only for debris. can be 'C','W' or anything else. +// FX_Explosion( const_cast(pos), const_cast(normal), materialType ); +// } + +// void ConcussiveExplosion( const Vector& pos, const Vector& normal ) +// { +// FX_ConcussiveExplosion( const_cast(pos), const_cast(normal) ); +// } + +// void MicroExplosion( const Vector& pos, const Vector& normal ) +// { +// FX_MicroExplosion( const_cast(pos), const_cast(normal) ); +// } + +// void MuzzleFlash( int type, HSCRIPT hEntity, int attachment, bool firstPerson ) +// { +// C_BaseEntity *p = ToEnt(hEntity); +// ClientEntityHandle_t ent = p ? (ClientEntityList().EntIndexToHandle)( p->entindex() ) : NULL;; +// tempents->MuzzleFlash( type, ent, attachment, firstPerson ); +// } + + void Sparks( const Vector& pos, int nMagnitude, int nTrailLength, const Vector& pDir ) + { + //te->Sparks( filter, delay, &pos, nMagnitude, nTrailLength, &pDir ); + //g_pEffects->Sparks( pos, nMagnitude, nTrailLength, &pDir ); + FX_ElectricSpark( pos, nMagnitude, nTrailLength, &pDir ); + } + + void MetalSparks( const Vector& pos, const Vector& dir ) + { + //g_pEffects->MetalSparks( pos, dir ); + FX_MetalSpark( pos, dir, dir ); + } + +// void Smoke( const Vector& pos, float scale, int framerate) +// { +// extern short g_sModelIndexSmoke; +// //te->Smoke( filter, 0.0, &pos, g_sModelIndexSmoke, scale * 10.0f, framerate ); +// g_pEffects->Smoke( pos, g_sModelIndexSmoke, scale, framerate ); +// } + + void Dust( const Vector &pos, const Vector &dir, float size, float speed ) + { + //te->Dust( filter, delay, pos, dir, size, speed ); + //g_pEffects->Dust( pos, dir, size, speed ); + FX_Dust( pos, dir, size, speed ); + } + + void Bubbles( const Vector &mins, const Vector &maxs, float height, int modelindex, int count, float speed ) + { + //int bubbles = modelinfo->GetModelIndex( "sprites/bubble.vmt" ); + //te->Bubbles( filter, delay, &mins, &maxs, height, modelindex, count, speed ); + tempents->Bubbles( mins, maxs, height, modelindex, count, speed ); + } + +// void Fizz( const Vector& mins, const Vector& maxs, int modelIndex, int density, int current/*, int flags*/ ) +// { +// //te->Fizz( filter, delay, ent, modelindex, density, current ); +// //tempents->FizzEffect( ToEnt(ent), modelindex, density, current ); +// } + + void Sprite( const Vector &pos, const Vector &dir, float scale, int modelIndex, int rendermode, + int renderfx, int brightness, float life, int flags ) + { + //te->Sprite( filter, delay, &pos, modelindex, size, brightness ); + float a = (1.0 / 255.0) * brightness; + tempents->TempSprite( pos, dir, scale, modelIndex, rendermode, renderfx, a, life, flags ); + } + +// void PhysicsProp( float delay, int modelindex, int skin, const Vector& pos, const QAngle &angles, +// const Vector& vel, int flags, int effects ) +// { +// //te->PhysicsProp( filter, delay, modelindex, skin, pos, angles, vel, flags, effects ); +// tempents->PhysicsProp( modelindex, skin, pos, angles, vel, flags, effects ); +// } + + void ClientProjectile( const Vector& vecOrigin, const Vector& vecVelocity, const Vector& vecAccel, int modelindex, + int lifetime, HSCRIPT pOwner, const char *pszImpactEffect = NULL, const char *pszParticleEffect = NULL ) + { + //te->ClientProjectile( filter, delay, &vecOrigin, &vecVelocity, modelindex, lifetime, ToEnt(pOwner) ); + if ( pszImpactEffect && !(*pszImpactEffect) ) + pszImpactEffect = NULL; + if ( pszParticleEffect && !(*pszParticleEffect) ) + pszParticleEffect = NULL; + tempents->ClientProjectile( vecOrigin, vecVelocity, vecAccel, modelindex, lifetime, ToEnt(pOwner), pszImpactEffect, pszParticleEffect ); + } + +} g_ScriptEffectsHelper; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CEffectsScriptHelper, "CEffects", SCRIPT_SINGLETON "" ) + DEFINE_SCRIPTFUNC( DynamicLight, "" ) + DEFINE_SCRIPTFUNC( Explosion, "" ) + DEFINE_SCRIPTFUNC( Sparks, "" ) + DEFINE_SCRIPTFUNC( MetalSparks, "" ) + DEFINE_SCRIPTFUNC( Dust, "" ) + DEFINE_SCRIPTFUNC( Bubbles, "" ) + DEFINE_SCRIPTFUNC( Sprite, "" ) + DEFINE_SCRIPTFUNC( ClientProjectile, "" ) +END_SCRIPTDESC(); + + + +//============================================================================= +//============================================================================= + +extern CGlowObjectManager g_GlowObjectManager; + +class CScriptGlowObjectManager : public CAutoGameSystem +{ +public: + CUtlVector m_RegisteredObjects; + + void LevelShutdownPostEntity() + { + FOR_EACH_VEC( m_RegisteredObjects, i ) + g_GlowObjectManager.UnregisterGlowObject( m_RegisteredObjects[i] ); + m_RegisteredObjects.Purge(); + } + +public: + int Register( HSCRIPT hEntity, int r, int g, int b, int a, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded ) + { + Vector vGlowColor; + vGlowColor.x = r * ( 1.0f / 255.0f ); + vGlowColor.y = g * ( 1.0f / 255.0f ); + vGlowColor.z = b * ( 1.0f / 255.0f ); + float flGlowAlpha = a * ( 1.0f / 255.0f ); + int idx = g_GlowObjectManager.RegisterGlowObject( ToEnt(hEntity), vGlowColor, flGlowAlpha, bRenderWhenOccluded, bRenderWhenUnoccluded, -1 ); + m_RegisteredObjects.AddToTail( idx ); + return idx; + } + + void Unregister( int nGlowObjectHandle ) + { + if ( (nGlowObjectHandle < 0) || (nGlowObjectHandle >= g_GlowObjectManager.m_GlowObjectDefinitions.Count()) ) + return; + g_GlowObjectManager.UnregisterGlowObject( nGlowObjectHandle ); + m_RegisteredObjects.FindAndFastRemove( nGlowObjectHandle ); + } + + void SetEntity( int nGlowObjectHandle, HSCRIPT hEntity ) + { + g_GlowObjectManager.SetEntity( nGlowObjectHandle, ToEnt(hEntity) ); + } + + void SetColor( int nGlowObjectHandle, int r, int g, int b ) + { + Vector vGlowColor; + vGlowColor.x = r * ( 1.0f / 255.0f ); + vGlowColor.y = g * ( 1.0f / 255.0f ); + vGlowColor.z = b * ( 1.0f / 255.0f ); + g_GlowObjectManager.SetColor( nGlowObjectHandle, vGlowColor ); + } + + void SetAlpha( int nGlowObjectHandle, int a ) + { + float flGlowAlpha = a * ( 1.0f / 255.0f ); + g_GlowObjectManager.SetAlpha( nGlowObjectHandle, flGlowAlpha ); + } + + void SetRenderFlags( int nGlowObjectHandle, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded ) + { + g_GlowObjectManager.SetRenderFlags( nGlowObjectHandle, bRenderWhenOccluded, bRenderWhenUnoccluded ); + } + +} g_ScriptGlowObjectManager; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptGlowObjectManager, "CGlowObjectManager", SCRIPT_SINGLETON "" ) + DEFINE_SCRIPTFUNC( Register, "( HSCRIPT hEntity, int r, int g, int b, int a, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded )" ) + DEFINE_SCRIPTFUNC( Unregister, "" ) + DEFINE_SCRIPTFUNC( SetEntity, "" ) + DEFINE_SCRIPTFUNC( SetColor, "" ) + DEFINE_SCRIPTFUNC( SetAlpha, "" ) + DEFINE_SCRIPTFUNC( SetRenderFlags, "" ) +END_SCRIPTDESC(); + + +//============================================================================= +//============================================================================= + + +#if !defined(NO_STEAM) +class CScriptSteamAPI +{ +public: + const char *GetSteam2ID() + { + if ( !steamapicontext || !steamapicontext->SteamUser() ) + return NULL; + + CSteamID id = steamapicontext->SteamUser()->GetSteamID(); + + uint32 accountID = id.GetAccountID(); + uint32 steamInstanceID = 0; + uint32 high32bits = accountID % 2; + uint32 low32bits = accountID / 2; + + static char ret[48]; + V_snprintf( ret, sizeof(ret), "STEAM_%u:%u:%u", steamInstanceID, high32bits, low32bits ); + return ret; + } + + int GetSecondsSinceComputerActive() + { + if ( !steamapicontext || !steamapicontext->SteamUtils() ) + return 0; + + return steamapicontext->SteamUtils()->GetSecondsSinceComputerActive(); + } + + int GetCurrentBatteryPower() + { + if ( !steamapicontext || !steamapicontext->SteamUtils() ) + return 0; + + return steamapicontext->SteamUtils()->GetCurrentBatteryPower(); + } +#if 0 + const char *GetIPCountry() + { + if ( !steamapicontext || !steamapicontext->SteamUtils() ) + return NULL; + + const char *get = steamapicontext->SteamUtils()->GetIPCountry(); + if ( !get ) + return NULL; + + static char ret[3]; + V_strncpy( ret, get, 3 ); + + return ret; + } +#endif + const char *GetCurrentGameLanguage() + { + if ( !steamapicontext || !steamapicontext->SteamApps() ) + return NULL; + + const char *lang = steamapicontext->SteamApps()->GetCurrentGameLanguage(); + if ( !lang ) + return NULL; + + static char ret[16]; + V_strncpy( ret, lang, sizeof(ret) ); + + return ret; + } + const char *GetCurrentBetaName() + { + if ( !steamapicontext || !steamapicontext->SteamApps() ) + return NULL; + + static char ret[16]; + steamapicontext->SteamApps()->GetCurrentBetaName( ret, sizeof( ret ) ); + return ret; + } +#if 0 + bool IsSubscribedApp( int nAppID ) + { + if ( !steamapicontext || !steamapicontext->SteamApps() ) + return false; + + return steamapicontext->SteamApps()->BIsSubscribedApp( nAppID ); + } +#endif + bool IsAppInstalled( int nAppID ) + { + if ( !steamapicontext || !steamapicontext->SteamApps() ) + return false; + + return steamapicontext->SteamApps()->BIsAppInstalled( nAppID ); + } + +} g_ScriptSteamAPI; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptSteamAPI, "CSteamAPI", SCRIPT_SINGLETON "" ) + DEFINE_SCRIPTFUNC( GetSteam2ID, "" ) + //DEFINE_SCRIPTFUNC( IsVACBanned, "" ) + DEFINE_SCRIPTFUNC( GetSecondsSinceComputerActive, "Returns the number of seconds since the user last moved the mouse." ) + DEFINE_SCRIPTFUNC( GetCurrentBatteryPower, "Return the amount of battery power left in the current system in % [0..100], 255 for being on AC power" ) + //DEFINE_SCRIPTFUNC( GetIPCountry, "Returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)" ) + DEFINE_SCRIPTFUNC( GetCurrentGameLanguage, "Gets the current language that the user has set as API language code. This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title." ) + DEFINE_SCRIPTFUNC( GetCurrentBetaName, "Gets the name of the user's current beta branch. In Source SDK Base 2013 Singleplayer, this will usually return 'upcoming'." ) + //DEFINE_SCRIPTFUNC( IsSubscribedApp, "Returns true if the user is subscribed to the specified app ID." ) + DEFINE_SCRIPTFUNC( IsAppInstalled, "Returns true if the user has the specified app ID installed on their computer." ) +END_SCRIPTDESC(); +#endif // !NO_STEAM + +#endif // CLIENT_DLL + + +void RegisterScriptSingletons() +{ + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::SaveTable, "SaveTable", "Store a table with primitive values that will persist across level transitions and save loads." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::RestoreTable, "RestoreTable", "Retrieves a table from storage. Write into input table." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::ClearSavedTable, "ClearSavedTable", "Removes the table with the given context." ); + ScriptRegisterSimpleHook( g_pScriptVM, g_Hook_OnSave, "OnSave", FIELD_VOID, "Called when the game is saved." ); + ScriptRegisterSimpleHook( g_pScriptVM, g_Hook_OnRestore, "OnRestore", FIELD_VOID, "Called when the game is restored." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileWrite, "StringToFile", "Stores the string into the file" ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileRead, "FileToString", "Returns the string from the file, null if no file or file is too big." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileExists, "FileExists", "Returns true if the file exists." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::KeyValuesWrite, "KeyValuesToFile", "Stores the CScriptKeyValues into the file" ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::KeyValuesRead, "FileToKeyValues", "Returns the CScriptKeyValues from the file, null if no file or file is too big." ); + + ScriptRegisterFunction( g_pScriptVM, ListenToGameEvent, "Register as a listener for a game event from script." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptGameEventListener::StopListeningToGameEvent, "StopListeningToGameEvent", "Stop the specified event listener." ); + ScriptRegisterFunctionNamed( g_pScriptVM, CScriptGameEventListener::StopListeningToAllGameEvents, "StopListeningToAllGameEvents", "Stop listening to all game events within a specific context." ); + ScriptRegisterFunction( g_pScriptVM, FireGameEvent, "Fire a game event." ); +#ifndef CLIENT_DLL + ScriptRegisterFunction( g_pScriptVM, FireGameEventLocal, "Fire a game event without broadcasting to the client." ); +#endif + + g_pScriptVM->RegisterInstance( &g_ScriptNetPropManager, "NetProps" ); + g_pScriptVM->RegisterInstance( &g_ScriptLocalize, "Localize" ); + g_pScriptVM->RegisterInstance( g_ScriptNetMsg, "NetMsg" ); + g_pScriptVM->RegisterInstance( &g_ScriptDebugOverlay, "debugoverlay" ); + g_pScriptVM->RegisterInstance( &g_ScriptConvarAccessor, "Convars" ); +#ifdef CLIENT_DLL + g_pScriptVM->RegisterInstance( &g_ScriptEffectsHelper, "effects" ); + g_pScriptVM->RegisterInstance( &g_ScriptGlowObjectManager, "GlowObjectManager" ); + +#if !defined(NO_STEAM) + g_pScriptVM->RegisterInstance( &g_ScriptSteamAPI, "steam" ); +#endif +#endif + + // Singletons not unique to VScript (not declared or defined here) + g_pScriptVM->RegisterInstance( GameRules(), "GameRules" ); + g_pScriptVM->RegisterInstance( GetAmmoDef(), "AmmoDef" ); +#ifndef CLIENT_DLL + g_pScriptVM->RegisterInstance( &g_AI_SquadManager, "Squads" ); +#endif + +#ifdef USE_OLD_EVENT_DESCRIPTORS + CScriptGameEventListener::LoadAllEvents(); +#endif + + g_ScriptNetMsg->InitPostVM(); +} diff --git a/game/shared/mapbase/vscript_singletons.h b/game/shared/mapbase/vscript_singletons.h new file mode 100644 index 00000000..e514f4d9 --- /dev/null +++ b/game/shared/mapbase/vscript_singletons.h @@ -0,0 +1,155 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: See vscript_singletons.cpp +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_SINGLETONS_H +#define VSCRIPT_SINGLETONS_H +#ifdef _WIN32 +#pragma once +#endif + +void RegisterScriptSingletons(); + + + +#ifdef CLIENT_DLL +// usercmd +#define SCRIPT_NETMSG_DATA_SIZE ( ( 1 << 11 ) - 1 ) +#else +// usermsg +#define SCRIPT_NETMSG_DATA_SIZE MAX_USER_MSG_DATA +#endif + +#define SCRIPT_NETMSG_QUEUE_BITS 3 // determines the number of custom messages client can write to a usercmd +#define SCRIPT_NETMSG_HEADER_BITS (sizeof(word) << 3) +#define SCRIPT_NETMSG_STRING_SIZE 512 + + +#ifdef CLIENT_DLL +class CNetMsgScriptHelper : public CAutoGameSystem +#else +class CNetMsgScriptHelper +#endif +{ +#ifdef CLIENT_DLL +public: + bool m_bWriteReady; // dt ready to send +#endif + +private: +#ifdef GAME_DLL + bf_read *m_MsgIn; + CRecipientFilter m_filter; +#else + bf_read m_MsgIn; + unsigned int m_nQueueCount; + bool m_bWriteIgnore; +#endif + HSCRIPT m_Hooks; + bf_write m_MsgOut; + byte m_MsgData[ PAD_NUMBER( SCRIPT_NETMSG_DATA_SIZE, 4 ) ]; + +#ifdef CLIENT_DLL + int m_iLastBit; +#endif + +public: + CNetMsgScriptHelper() : m_Hooks(NULL) + +#ifdef CLIENT_DLL + , m_bWriteReady(0), m_bWriteIgnore(0), m_nQueueCount(0), m_iLastBit(0) +#else + , m_MsgIn(0) +#endif + + {} + +public: +#ifdef CLIENT_DLL + bool Init(); // IGameSystem + static void __MsgFunc_ScriptMsg( bf_read &msg ); +#endif + void LevelShutdownPreVM(); // Executed in CVScriptGameSystem + void InitPostVM(); + +#ifdef GAME_DLL + void ReceiveMessage( bf_read *msg, CBaseEntity *pPlayer ); +#else + void ReceiveMessage( bf_read &msg ); +#endif + void WriteToBuffer( bf_write *bf ); + +public: + inline void Reset(); + void Start( const char *msg ); +#ifdef GAME_DLL + void Send( HSCRIPT player, bool bReliable ); +#else + void Send(); +#endif + void Receive( const char *msg, HSCRIPT func ); + +#ifdef GAME_DLL + inline void DoSendUserMsg( CRecipientFilter *filter, int type ); + inline void DoSendEntityMsg( CBaseEntity *entity, bool reliable ); + + void SendUserMessage( HSCRIPT hPlayer, const char *msg, bool bReliable ); + void SendEntityMessage( HSCRIPT hEnt, bool bReliable ); +#else // CLIENT_DLL + void DispatchUserMessage( const char *msg ); +#endif + +public: + void WriteInt( int iValue, int bits ); + void WriteUInt( int iValue, int bits ); + void WriteByte( int iValue ); // 8 bit unsigned char + void WriteChar( int iValue ); // 8 bit char + void WriteShort( int iValue ); // 16 bit short + void WriteWord( int iValue ); // 16 bit unsigned short + void WriteLong( int iValue ); // 32 bit long + void WriteFloat( float flValue ); // 32 bit float + void WriteNormal( float flValue ); // 12 bit (1 + NORMAL_FRACTIONAL_BITS) + void WriteAngle( float flValue ); // 8 bit unsigned char + void WriteCoord( float flValue ); + void WriteVec3Coord( const Vector& rgflValue ); + void WriteVec3Normal( const Vector& rgflValue ); // 27 bit ( 3 + 2 * (1 + NORMAL_FRACTIONAL_BITS) ) + void WriteAngles( const QAngle& rgflValue ); + void WriteString( const char *sz ); + void WriteBool( bool bValue ); // 1 bit + void WriteEntity( HSCRIPT hEnt ); // 11 bit (entindex) + void WriteEHandle( HSCRIPT hEnt ); // 32 bit long + int ReadInt( int bits ); + int ReadUInt( int bits ); + int ReadByte(); + int ReadChar(); + int ReadShort(); + int ReadWord(); + int ReadLong(); + float ReadFloat(); + float ReadNormal(); + float ReadAngle(); + float ReadCoord(); + const Vector& ReadVec3Coord(); + const Vector& ReadVec3Normal(); + const QAngle& ReadAngles(); + const char* ReadString(); + bool ReadBool(); + HSCRIPT ReadEntity(); + HSCRIPT ReadEHandle(); + //int GetNumBitsLeft(); // unreliable on server because of usercmds. so just do away with it + int GetNumBitsWritten(); + +public: + static inline int Hash( const char *key ); +}; + +extern CNetMsgScriptHelper *g_ScriptNetMsg; + +#ifdef CLIENT_DLL +void VScriptSaveRestoreUtil_OnVMRestore(); +#endif + +#endif diff --git a/game/shared/mapbase/weapon_custom_scripted.cpp b/game/shared/mapbase/weapon_custom_scripted.cpp new file mode 100644 index 00000000..4d5c744d --- /dev/null +++ b/game/shared/mapbase/weapon_custom_scripted.cpp @@ -0,0 +1,606 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript-driven custom weapon class. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "tier1/fmtstr.h" +#include "weapon_custom_scripted.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//========================================================= +//========================================================= + +BEGIN_DATADESC( CWeaponCustomScripted ) + + DEFINE_AUTO_ARRAY( m_iszClientScripts, FIELD_CHARACTER ), + DEFINE_AUTO_ARRAY( m_iszWeaponScriptName, FIELD_CHARACTER ), + +END_DATADESC() + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCustomScripted, DT_WeaponCustomScripted ) + +BEGIN_NETWORK_TABLE( CWeaponCustomScripted, DT_WeaponCustomScripted ) + +#ifdef CLIENT_DLL + RecvPropString( RECVINFO(m_iszClientScripts) ), + RecvPropString( RECVINFO(m_iszWeaponScriptName) ), +#else + SendPropString( SENDINFO(m_iszClientScripts) ), + SendPropString( SENDINFO(m_iszWeaponScriptName) ), +#endif + +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CWeaponCustomScripted ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( weapon_custom_scripted1, CWeaponCustomScripted ); + +// Only need one of the names +PRECACHE_WEAPON_REGISTER( weapon_custom_scripted1 ); + +//IMPLEMENT_ACTTABLE( CWeaponCustomScripted ); + +#define DEFINE_STATIC_HOOK( name ) ScriptHook_t CWeaponCustomScripted::g_Hook_##name + +DEFINE_STATIC_HOOK( HasAnyAmmo ); +DEFINE_STATIC_HOOK( HasPrimaryAmmo ); +DEFINE_STATIC_HOOK( HasSecondaryAmmo ); + +DEFINE_STATIC_HOOK( CanHolster ); +DEFINE_STATIC_HOOK( CanDeploy ); +DEFINE_STATIC_HOOK( Deploy ); +DEFINE_STATIC_HOOK( Holster ); + +DEFINE_STATIC_HOOK( ItemPreFrame ); +DEFINE_STATIC_HOOK( ItemPostFrame ); +DEFINE_STATIC_HOOK( ItemBusyFrame ); +DEFINE_STATIC_HOOK( ItemHolsterFrame ); +DEFINE_STATIC_HOOK( WeaponIdle ); +DEFINE_STATIC_HOOK( HandleFireOnEmpty ); + +DEFINE_STATIC_HOOK( CheckReload ); +DEFINE_STATIC_HOOK( FinishReload ); +DEFINE_STATIC_HOOK( AbortReload ); +DEFINE_STATIC_HOOK( Reload ); +DEFINE_STATIC_HOOK( Reload_NPC ); + +DEFINE_STATIC_HOOK( PrimaryAttack ); +DEFINE_STATIC_HOOK( SecondaryAttack ); + +DEFINE_STATIC_HOOK( GetPrimaryAttackActivity ); +DEFINE_STATIC_HOOK( GetSecondaryAttackActivity ); +DEFINE_STATIC_HOOK( GetDrawActivity ); +DEFINE_STATIC_HOOK( GetDefaultAnimSpeed ); + +DEFINE_STATIC_HOOK( GetBulletSpread ); +DEFINE_STATIC_HOOK( GetBulletSpreadForProficiency ); +DEFINE_STATIC_HOOK( GetFireRate ); +DEFINE_STATIC_HOOK( GetMinBurst ); +DEFINE_STATIC_HOOK( GetMaxBurst ); +DEFINE_STATIC_HOOK( GetMinRestTime ); +DEFINE_STATIC_HOOK( GetMaxRestTime ); + +DEFINE_STATIC_HOOK( AddViewKick ); + +#ifndef CLIENT_DLL +DEFINE_STATIC_HOOK( WeaponLOSCondition ); +DEFINE_STATIC_HOOK( WeaponRangeAttack1Condition ); +DEFINE_STATIC_HOOK( WeaponRangeAttack2Condition ); +DEFINE_STATIC_HOOK( WeaponMeleeAttack1Condition ); +DEFINE_STATIC_HOOK( WeaponMeleeAttack2Condition ); +#endif + +DEFINE_STATIC_HOOK( ActivityList ); +DEFINE_STATIC_HOOK( ActivityListCount ); + +#define DEFINE_SIMPLE_WEAPON_HOOK( name, returnType, description ) DEFINE_SIMPLE_SCRIPTHOOK( CWeaponCustomScripted::g_Hook_##name, #name, returnType, description ) +#define BEGIN_WEAPON_HOOK( name, returnType, description ) BEGIN_SCRIPTHOOK( CWeaponCustomScripted::g_Hook_##name, #name, returnType, description ) + +BEGIN_ENT_SCRIPTDESC( CWeaponCustomScripted, CBaseCombatWeapon, "Special weapon class with tons of hooks" ) + + DEFINE_SIMPLE_WEAPON_HOOK( HasAnyAmmo, FIELD_BOOLEAN, "Should return true if weapon has ammo" ) + DEFINE_SIMPLE_WEAPON_HOOK( HasPrimaryAmmo, FIELD_BOOLEAN, "Should return true if weapon has primary ammo" ) + DEFINE_SIMPLE_WEAPON_HOOK( HasSecondaryAmmo, FIELD_BOOLEAN, "Should return true if weapon has secondary ammo" ) + + DEFINE_SIMPLE_WEAPON_HOOK( CanHolster, FIELD_BOOLEAN, "Should return true if weapon can be holstered" ) + DEFINE_SIMPLE_WEAPON_HOOK( CanDeploy, FIELD_BOOLEAN, "Should return true if weapon can be deployed" ) + DEFINE_SIMPLE_WEAPON_HOOK( Deploy, FIELD_BOOLEAN, "Called when weapon is being deployed" ) + BEGIN_WEAPON_HOOK( Holster, FIELD_BOOLEAN, "Called when weapon is being holstered" ) + DEFINE_SCRIPTHOOK_PARAM( "switchingto", FIELD_HSCRIPT ) + END_SCRIPTHOOK() + + DEFINE_SIMPLE_WEAPON_HOOK( ItemPreFrame, FIELD_VOID, "Called each frame by the player PreThink" ) + DEFINE_SIMPLE_WEAPON_HOOK( ItemPostFrame, FIELD_VOID, "Called each frame by the player PostThink" ) + DEFINE_SIMPLE_WEAPON_HOOK( ItemBusyFrame, FIELD_VOID, "Called each frame by the player PostThink, if the player's not ready to attack yet" ) + DEFINE_SIMPLE_WEAPON_HOOK( ItemHolsterFrame, FIELD_VOID, "Called each frame by the player PreThink, if the weapon is holstered" ) + DEFINE_SIMPLE_WEAPON_HOOK( WeaponIdle, FIELD_VOID, "Called when no buttons pressed" ) + DEFINE_SIMPLE_WEAPON_HOOK( HandleFireOnEmpty, FIELD_VOID, "Called when they have the attack button down but they are out of ammo. The default implementation either reloads, switches weapons, or plays an empty sound." ) + + DEFINE_SIMPLE_WEAPON_HOOK( CheckReload, FIELD_VOID, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( FinishReload, FIELD_VOID, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( AbortReload, FIELD_VOID, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( Reload, FIELD_BOOLEAN, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( Reload_NPC, FIELD_VOID, "" ) + + DEFINE_SIMPLE_WEAPON_HOOK( PrimaryAttack, FIELD_VOID, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( SecondaryAttack, FIELD_VOID, "" ) + + DEFINE_SIMPLE_WEAPON_HOOK( GetPrimaryAttackActivity, FIELD_VARIANT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetSecondaryAttackActivity, FIELD_VARIANT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetDrawActivity, FIELD_VARIANT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetDefaultAnimSpeed, FIELD_FLOAT, "" ) + + DEFINE_SIMPLE_WEAPON_HOOK( GetBulletSpread, FIELD_VECTOR, "" ) + BEGIN_WEAPON_HOOK( GetBulletSpreadForProficiency, FIELD_VECTOR, "Returns the bullet spread of a specific proficiency level. If this isn't defined, it will fall back to GetBulletSpread." ) + DEFINE_SCRIPTHOOK_PARAM( "proficiency", FIELD_INTEGER ) + END_SCRIPTHOOK() + DEFINE_SIMPLE_WEAPON_HOOK( GetFireRate, FIELD_FLOAT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetMinBurst, FIELD_INTEGER, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetMaxBurst, FIELD_INTEGER, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetMinRestTime, FIELD_FLOAT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( GetMaxRestTime, FIELD_FLOAT, "" ) + + DEFINE_SIMPLE_WEAPON_HOOK( AddViewKick, FIELD_VOID, "" ) + +#ifndef CLIENT_DLL + DEFINE_SIMPLE_WEAPON_HOOK( WeaponLOSCondition, FIELD_BOOLEAN, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( WeaponRangeAttack1Condition, FIELD_INTEGER, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( WeaponRangeAttack2Condition, FIELD_INTEGER, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( WeaponMeleeAttack1Condition, FIELD_INTEGER, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( WeaponMeleeAttack2Condition, FIELD_INTEGER, "" ) +#endif + + DEFINE_SIMPLE_WEAPON_HOOK( ActivityList, FIELD_HSCRIPT, "" ) + DEFINE_SIMPLE_WEAPON_HOOK( ActivityListCount, FIELD_INTEGER, "" ) + +END_SCRIPTDESC(); + +CWeaponCustomScripted::CWeaponCustomScripted() +{ + //m_fMinRange1 = 65; + //m_fMaxRange1 = 2048; + // + //m_fMinRange2 = 256; + //m_fMaxRange2 = 1024; + // + //m_nShotsFired = 0; + //m_nVentPose = -1; + // + //m_bAltFiresUnderwater = false; +} + +bool CWeaponCustomScripted::RunWeaponHook( ScriptHook_t &hook, HSCRIPT &cached, ScriptVariant_t *retVal, ScriptVariant_t *pArgs ) +{ + if ( !cached ) + { + if ( hook.CanRunInScope( m_ScriptScope ) ) + { + cached = hook.m_hFunc; + } + } + + if (cached) + { + return hook.Call( m_ScriptScope, retVal, pArgs, false ); + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCustomScripted::Spawn( void ) +{ +#ifdef CLIENT_DLL + if (m_iszClientScripts[0] != '\0' && ValidateScriptScope()) + { + RunScriptFile( m_iszClientScripts ); + } +#endif + + BaseClass::Spawn(); +} + +bool CWeaponCustomScripted::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( FStrEq( szKeyName, "vscripts_client" ) ) + { + Q_strcpy( m_iszClientScripts.GetForModify(), szValue ); + } + else if ( FStrEq( szKeyName, "weapondatascript_name" ) ) + { + Q_strcpy( m_iszWeaponScriptName.GetForModify(), szValue ); + } + else + { + return BaseClass::KeyValue( szKeyName, szValue ); + } + + return true; +} + +bool CWeaponCustomScripted::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) +{ + if ( FStrEq( szKeyName, "vscripts_client" ) ) + { + Q_snprintf( szValue, iMaxLen, "%s", m_iszClientScripts.Get() ); + return true; + } + else if ( FStrEq( szKeyName, "weapondatascript_name" ) ) + { + Q_snprintf( szValue, iMaxLen, "%s", m_iszWeaponScriptName.Get() ); + return true; + } + return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +#define SIMPLE_VOID_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_bool == false) \ + return; + +#define SIMPLE_BOOL_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_type == FIELD_BOOLEAN) \ + return retVal.m_bool; + +#define SIMPLE_FLOAT_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_type == FIELD_FLOAT) \ + return retVal.m_float; + +#define SIMPLE_INT_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_type == FIELD_INTEGER) \ + return retVal.m_int; + +#define SIMPLE_VECTOR_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_type == FIELD_VECTOR) \ + return *retVal.m_pVector; + +#define SIMPLE_VECTOR_REF_OVERRIDE( name, pArgs ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal, pArgs ) && retVal.m_type == FIELD_VECTOR) \ + { \ + static Vector vec = *retVal.m_pVector; \ + return vec; \ + } + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponCustomScripted::HasAnyAmmo( void ) +{ + SIMPLE_BOOL_OVERRIDE( HasAnyAmmo, NULL ); + + return BaseClass::HasAnyAmmo(); +} + +bool CWeaponCustomScripted::HasPrimaryAmmo( void ) +{ + SIMPLE_BOOL_OVERRIDE( HasPrimaryAmmo, NULL ); + + return BaseClass::HasPrimaryAmmo(); +} + +bool CWeaponCustomScripted::HasSecondaryAmmo( void ) +{ + SIMPLE_BOOL_OVERRIDE( HasSecondaryAmmo, NULL ); + + return BaseClass::HasSecondaryAmmo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponCustomScripted::CanHolster( void ) +{ + SIMPLE_BOOL_OVERRIDE( CanHolster, NULL ); + + return BaseClass::CanHolster(); +} + +bool CWeaponCustomScripted::CanDeploy( void ) +{ + SIMPLE_BOOL_OVERRIDE( CanDeploy, NULL ); + + return BaseClass::CanDeploy(); +} + +bool CWeaponCustomScripted::Deploy( void ) +{ + SIMPLE_BOOL_OVERRIDE( Deploy, NULL ); + + return BaseClass::Deploy(); +} + +bool CWeaponCustomScripted::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + ScriptVariant_t pArgs[] = { ToHScript( pSwitchingTo ) }; + SIMPLE_BOOL_OVERRIDE( Holster, pArgs ); + + return BaseClass::Holster( pSwitchingTo ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCustomScripted::ItemPreFrame( void ) +{ + SIMPLE_VOID_OVERRIDE( ItemPreFrame, NULL ); + + BaseClass::ItemPostFrame(); +} + +void CWeaponCustomScripted::ItemPostFrame( void ) +{ + SIMPLE_VOID_OVERRIDE( ItemPostFrame, NULL ); + + BaseClass::ItemPostFrame(); +} + +void CWeaponCustomScripted::ItemBusyFrame( void ) +{ + SIMPLE_VOID_OVERRIDE( ItemBusyFrame, NULL ); + + BaseClass::ItemBusyFrame(); +} + +void CWeaponCustomScripted::ItemHolsterFrame( void ) +{ + SIMPLE_VOID_OVERRIDE( ItemHolsterFrame, NULL ); + + BaseClass::ItemHolsterFrame(); +} + +void CWeaponCustomScripted::WeaponIdle( void ) +{ + SIMPLE_VOID_OVERRIDE( WeaponIdle, NULL ); + + BaseClass::WeaponIdle(); +} + +void CWeaponCustomScripted::HandleFireOnEmpty( void ) +{ + SIMPLE_VOID_OVERRIDE( HandleFireOnEmpty, NULL ); + + BaseClass::HandleFireOnEmpty(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCustomScripted::CheckReload( void ) +{ + SIMPLE_VOID_OVERRIDE( CheckReload, NULL ); + + BaseClass::CheckReload(); +} + +void CWeaponCustomScripted::FinishReload( void ) +{ + SIMPLE_VOID_OVERRIDE( FinishReload, NULL ); + + BaseClass::FinishReload(); +} + +void CWeaponCustomScripted::AbortReload( void ) +{ + SIMPLE_VOID_OVERRIDE( AbortReload, NULL ); + + BaseClass::AbortReload(); +} + +bool CWeaponCustomScripted::Reload( void ) +{ + SIMPLE_BOOL_OVERRIDE( Reload, NULL ); + + return BaseClass::Reload(); +} + +void CWeaponCustomScripted::Reload_NPC( bool bPlaySound ) +{ + ScriptVariant_t pArgs[] = { bPlaySound }; + SIMPLE_VOID_OVERRIDE( Reload_NPC, pArgs ); + + BaseClass::Reload_NPC(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCustomScripted::PrimaryAttack( void ) +{ + SIMPLE_VOID_OVERRIDE( PrimaryAttack, NULL ); + + BaseClass::PrimaryAttack(); +} + +void CWeaponCustomScripted::SecondaryAttack( void ) +{ + SIMPLE_VOID_OVERRIDE( SecondaryAttack, NULL ); + + BaseClass::SecondaryAttack(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +#define ACTIVITY_FUNC_OVERRIDE( name ) ScriptVariant_t retVal; \ + if (RunWeaponHook( g_Hook_##name, m_Func_##name, &retVal ) && retVal.m_bool == false) \ + { \ + if (retVal.m_type == FIELD_INTEGER) \ + { \ + Activity activity = (Activity)retVal.m_int; \ + if (activity != ACT_INVALID) \ + return (Activity)retVal.m_int; \ + } \ + else \ + { \ + Activity activity = (Activity)LookupActivity( retVal.m_pszString ); \ + if (activity != ACT_INVALID) \ + return activity; \ + } \ + } + +Activity CWeaponCustomScripted::GetPrimaryAttackActivity( void ) +{ + ACTIVITY_FUNC_OVERRIDE( GetPrimaryAttackActivity ); + + return BaseClass::GetPrimaryAttackActivity(); +} + +Activity CWeaponCustomScripted::GetSecondaryAttackActivity( void ) +{ + ACTIVITY_FUNC_OVERRIDE( GetSecondaryAttackActivity ); + + return BaseClass::GetSecondaryAttackActivity(); +} + +Activity CWeaponCustomScripted::GetDrawActivity( void ) +{ + ACTIVITY_FUNC_OVERRIDE( GetDrawActivity ); + + return BaseClass::GetDrawActivity(); +} + +float CWeaponCustomScripted::GetDefaultAnimSpeed( void ) +{ + SIMPLE_FLOAT_OVERRIDE( GetDefaultAnimSpeed, NULL ); + + return BaseClass::GetDefaultAnimSpeed(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const Vector& CWeaponCustomScripted::GetBulletSpread( void ) +{ + SIMPLE_VECTOR_REF_OVERRIDE( GetBulletSpread, NULL ); + + // HACKHACK: Need to skip CBaseHLCombatWeapon here to recognize this overload for some reason + return CBaseCombatWeapon::GetBulletSpread(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Vector CWeaponCustomScripted::GetBulletSpread( WeaponProficiency_t proficiency ) +{ + ScriptVariant_t pArgs[] = { (int)proficiency }; + SIMPLE_VECTOR_OVERRIDE( GetBulletSpreadForProficiency, pArgs ); + + return BaseClass::GetBulletSpread( proficiency ); +} + +float CWeaponCustomScripted::GetFireRate( void ) +{ + SIMPLE_FLOAT_OVERRIDE( GetFireRate, NULL ); + + return BaseClass::GetFireRate(); +} + +int CWeaponCustomScripted::GetMinBurst( void ) +{ + SIMPLE_INT_OVERRIDE( GetMinBurst, NULL ); + + return BaseClass::GetMinBurst(); +} + +int CWeaponCustomScripted::GetMaxBurst( void ) +{ + SIMPLE_INT_OVERRIDE( GetMaxBurst, NULL ); + + return BaseClass::GetMaxBurst(); +} + +float CWeaponCustomScripted::GetMinRestTime( void ) +{ + SIMPLE_FLOAT_OVERRIDE( GetMinRestTime, NULL ); + + return BaseClass::GetMinRestTime(); +} + +float CWeaponCustomScripted::GetMaxRestTime( void ) +{ + SIMPLE_FLOAT_OVERRIDE( GetMaxRestTime, NULL ); + + return BaseClass::GetMaxRestTime(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCustomScripted::AddViewKick( void ) +{ + SIMPLE_VOID_OVERRIDE( AddViewKick, NULL ); + + return BaseClass::AddViewKick(); +} + +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponCustomScripted::WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions ) +{ + ScriptVariant_t pArgs[] = { ownerPos, targetPos, bSetConditions }; + SIMPLE_BOOL_OVERRIDE( WeaponLOSCondition, pArgs ); + + return BaseClass::WeaponLOSCondition( ownerPos, targetPos, bSetConditions ); +} + +int CWeaponCustomScripted::WeaponRangeAttack1Condition( float flDot, float flDist ) +{ + ScriptVariant_t pArgs[] = { flDot, flDist }; + SIMPLE_INT_OVERRIDE( WeaponRangeAttack1Condition, pArgs ); + + return BaseClass::WeaponRangeAttack1Condition( flDot, flDist ); +} + +int CWeaponCustomScripted::WeaponRangeAttack2Condition( float flDot, float flDist ) +{ + ScriptVariant_t pArgs[] = { flDot, flDist }; + SIMPLE_INT_OVERRIDE( WeaponRangeAttack2Condition, pArgs ); + + return BaseClass::WeaponRangeAttack2Condition( flDot, flDist ); +} + +int CWeaponCustomScripted::WeaponMeleeAttack1Condition( float flDot, float flDist ) +{ + ScriptVariant_t pArgs[] = { flDot, flDist }; + SIMPLE_INT_OVERRIDE( WeaponMeleeAttack1Condition, pArgs ); + + return BaseClass::WeaponMeleeAttack1Condition( flDot, flDist ); +} + +int CWeaponCustomScripted::WeaponMeleeAttack2Condition( float flDot, float flDist ) +{ + ScriptVariant_t pArgs[] = { flDot, flDist }; + SIMPLE_INT_OVERRIDE( WeaponMeleeAttack2Condition, pArgs ); + + return BaseClass::WeaponMeleeAttack2Condition( flDot, flDist ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +acttable_t *CWeaponCustomScripted::ActivityList( void ) +{ + // TODO + + return BaseClass::ActivityList(); +} + +int CWeaponCustomScripted::ActivityListCount( void ) +{ + // TODO + + return BaseClass::ActivityListCount(); +} diff --git a/game/shared/mapbase/weapon_custom_scripted.h b/game/shared/mapbase/weapon_custom_scripted.h new file mode 100644 index 00000000..924f1031 --- /dev/null +++ b/game/shared/mapbase/weapon_custom_scripted.h @@ -0,0 +1,202 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: VScript-driven custom weapon class. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef WEAPON_CUSTOM_SCRIPTED_H +#define WEAPON_CUSTOM_SCRIPTED_H +#ifdef _WIN32 +#pragma once +#endif + +#include "basecombatweapon_shared.h" +#ifdef CLIENT_DLL +#include "vscript_client.h" +#endif + +// The base class of the scripted weapon is game-specific. +#if defined(HL2_DLL) || defined(HL2_CLIENT_DLL) +#include "basehlcombatweapon_shared.h" +#define SCRIPTED_WEAPON_DERIVED_FROM CBaseHLCombatWeapon +#else +#define SCRIPTED_WEAPON_DERIVED_FROM CBaseCombatWeapon +#endif + +#ifdef CLIENT_DLL +#define CWeaponCustomScripted C_WeaponCustomScripted +#endif + +#define DECLARE_CACHED_HOOK(name) static ScriptHook_t g_Hook_##name; \ + HSCRIPT m_Func_##name; + +class CWeaponCustomScripted : public SCRIPTED_WEAPON_DERIVED_FROM +{ +public: + DECLARE_CLASS( CWeaponCustomScripted, SCRIPTED_WEAPON_DERIVED_FROM ); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + + CWeaponCustomScripted(); + + bool RunWeaponHook( ScriptHook_t &hook, HSCRIPT &cached, ScriptVariant_t *retVal = NULL, ScriptVariant_t *pArgs = NULL ); + + bool KeyValue( const char *szKeyName, const char *szValue ); + bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + + // Base script has a function for this + //void Precache( void ); + + void Spawn( void ); + + bool IsPredicted( void ) const { return m_iszClientScripts[0] != '\0'; } + + const char* GetWeaponScriptName() { return m_iszWeaponScriptName[0] != '\0' ? m_iszWeaponScriptName : BaseClass::GetWeaponScriptName(); } + + // Weapon selection + bool HasAnyAmmo( void ); // Returns true is weapon has ammo + bool HasPrimaryAmmo( void ); // Returns true is weapon has ammo + bool HasSecondaryAmmo( void ); // Returns true is weapon has ammo + + bool CanHolster( void ); // returns true if the weapon can be holstered + bool CanDeploy( void ); // return true if the weapon's allowed to deploy + bool Deploy( void ); // returns true is deploy was successful + bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); + + // Weapon behaviour + void ItemPreFrame( void ); // called each frame by the player PreThink + void ItemPostFrame( void ); // called each frame by the player PostThink + void ItemBusyFrame( void ); // called each frame by the player PostThink, if the player's not ready to attack yet + void ItemHolsterFrame( void ); // called each frame by the player PreThink, if the weapon is holstered + void WeaponIdle( void ); // called when no buttons pressed + void HandleFireOnEmpty(); // Called when they have the attack button down + + // Reloading + void CheckReload( void ); + void FinishReload( void ); + void AbortReload( void ); + bool Reload( void ); + void Reload_NPC( bool bPlaySound = true ); + + // Weapon firing + void PrimaryAttack( void ); // do "+ATTACK" + void SecondaryAttack( void ); // do "+ATTACK2" + + // Firing animations + Activity GetPrimaryAttackActivity( void ); + Activity GetSecondaryAttackActivity( void ); + Activity GetDrawActivity( void ); + float GetDefaultAnimSpeed( void ); + + // Bullet launch information + const Vector& GetBulletSpread( void ); + Vector GetBulletSpread( WeaponProficiency_t proficiency ); + float GetFireRate( void ); + int GetMinBurst(); + int GetMaxBurst(); + float GetMinRestTime(); + float GetMaxRestTime(); + + void AddViewKick( void ); + +#ifndef CLIENT_DLL + bool WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions ); + int WeaponRangeAttack1Condition( float flDot, float flDist ); + int WeaponRangeAttack2Condition( float flDot, float flDist ); + int WeaponMeleeAttack1Condition( float flDot, float flDist ); + int WeaponMeleeAttack2Condition( float flDot, float flDist ); +#endif + + ALLOW_SCRIPT_ACCESS(); +private: + + // Weapon selection + DECLARE_CACHED_HOOK( HasAnyAmmo ); + DECLARE_CACHED_HOOK( HasPrimaryAmmo ); + DECLARE_CACHED_HOOK( HasSecondaryAmmo ); + + DECLARE_CACHED_HOOK( CanHolster ); + DECLARE_CACHED_HOOK( CanDeploy ); + DECLARE_CACHED_HOOK( Deploy ); + DECLARE_CACHED_HOOK( Holster ); + + // Weapon behaviour + DECLARE_CACHED_HOOK( ItemPreFrame ); + DECLARE_CACHED_HOOK( ItemPostFrame ); + DECLARE_CACHED_HOOK( ItemBusyFrame ); + DECLARE_CACHED_HOOK( ItemHolsterFrame ); + DECLARE_CACHED_HOOK( WeaponIdle ); + DECLARE_CACHED_HOOK( HandleFireOnEmpty ); + + // Reloading + DECLARE_CACHED_HOOK( CheckReload ); + DECLARE_CACHED_HOOK( FinishReload ); + DECLARE_CACHED_HOOK( AbortReload ); + DECLARE_CACHED_HOOK( Reload ); + DECLARE_CACHED_HOOK( Reload_NPC ); + + // Weapon firing + DECLARE_CACHED_HOOK( PrimaryAttack ); + DECLARE_CACHED_HOOK( SecondaryAttack ); + + // Firing animations + DECLARE_CACHED_HOOK( GetPrimaryAttackActivity ); + DECLARE_CACHED_HOOK( GetSecondaryAttackActivity ); + DECLARE_CACHED_HOOK( GetDrawActivity ); + DECLARE_CACHED_HOOK( GetDefaultAnimSpeed ); + + // Bullet launch information + DECLARE_CACHED_HOOK( GetBulletSpread ); + DECLARE_CACHED_HOOK( GetBulletSpreadForProficiency ); + DECLARE_CACHED_HOOK( GetFireRate ); + DECLARE_CACHED_HOOK( GetMinBurst ); + DECLARE_CACHED_HOOK( GetMaxBurst ); + DECLARE_CACHED_HOOK( GetMinRestTime ); + DECLARE_CACHED_HOOK( GetMaxRestTime ); + + DECLARE_CACHED_HOOK( AddViewKick ); + +#ifndef CLIENT_DLL + DECLARE_CACHED_HOOK( WeaponLOSCondition ); + DECLARE_CACHED_HOOK( WeaponRangeAttack1Condition ); + DECLARE_CACHED_HOOK( WeaponRangeAttack2Condition ); + DECLARE_CACHED_HOOK( WeaponMeleeAttack1Condition ); + DECLARE_CACHED_HOOK( WeaponMeleeAttack2Condition ); +#endif + + DECLARE_CACHED_HOOK( ActivityList ); + DECLARE_CACHED_HOOK( ActivityListCount ); + +private: + + CNetworkString( m_iszClientScripts, 256 ); + CNetworkString( m_iszWeaponScriptName, 256 ); + +protected: + + DECLARE_ACTTABLE(); + DECLARE_DATADESC(); + DECLARE_ENT_SCRIPTDESC(); +}; + +/* +class CWeaponCustomScripted1 : public CWeaponCustomScripted +{ + DECLARE_PREDICTABLE(); +}; +class CWeaponCustomScripted2 : public CWeaponCustomScripted +{ + DECLARE_PREDICTABLE(); +}; +class CWeaponCustomScripted3 : public CWeaponCustomScripted +{ + DECLARE_PREDICTABLE(); +}; +class CWeaponCustomScripted4 : public CWeaponCustomScripted +{ + DECLARE_PREDICTABLE(); +}; +*/ + +#endif diff --git a/game/shared/mapentities_shared.cpp b/game/shared/mapentities_shared.cpp index 2cd6fe01..420c3e1d 100644 --- a/game/shared/mapentities_shared.cpp +++ b/game/shared/mapentities_shared.cpp @@ -125,7 +125,7 @@ const char *MapEntity_ParseToken( const char *data, char *newToken ) for ( const char *c = s_BraceChars; *c; c++ ) { - s_BraceCharacters[(unsigned)*c] = true; + s_BraceCharacters[*c] = true; } } diff --git a/game/shared/movevars_shared.cpp b/game/shared/movevars_shared.cpp index 7311cdfd..563d96e3 100644 --- a/game/shared/movevars_shared.cpp +++ b/game/shared/movevars_shared.cpp @@ -36,7 +36,7 @@ float GetCurrentGravity( void ) ConVar sv_gravity ( "sv_gravity", DEFAULT_GRAVITY_STRING, FCVAR_NOTIFY | FCVAR_REPLICATED, "World gravity." ); -#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) +#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_stopspeed ( "sv_stopspeed","100", FCVAR_NOTIFY | FCVAR_REPLICATED, "Minimum stopping speed when on ground." ); #else ConVar sv_stopspeed ( "sv_stopspeed","100", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Minimum stopping speed when on ground." ); @@ -48,21 +48,17 @@ ConVar sv_specaccelerate( "sv_specaccelerate", "5", FCVAR_NOTIFY | FCVAR_ARCHIVE ConVar sv_specspeed ( "sv_specspeed", "3", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_REPLICATED); ConVar sv_specnoclip ( "sv_specnoclip", "1", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_REPLICATED); -#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) -ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED); -#else -#ifdef VANCE +#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED); #else ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY); -#endif #endif // CSTRIKE_DLL #ifdef _XBOX ConVar sv_accelerate ( "sv_accelerate", "7", FCVAR_NOTIFY | FCVAR_REPLICATED); #else -#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) +#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_accelerate ( "sv_accelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED); #else ConVar sv_accelerate ( "sv_accelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY); @@ -70,7 +66,7 @@ ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FC #endif//_XBOX -#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) +#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_airaccelerate( "sv_airaccelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED); ConVar sv_wateraccelerate( "sv_wateraccelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED); ConVar sv_waterfriction( "sv_waterfriction", "1", FCVAR_NOTIFY | FCVAR_REPLICATED); @@ -83,22 +79,16 @@ ConVar sv_wateraccelerate( "sv_wateraccelerate", "10", FCVAR_NOTIFY | FCVAR_REP ConVar sv_waterfriction( "sv_waterfriction", "1", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY ); ConVar sv_footsteps ( "sv_footsteps", "1", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Play footstep sound for players" ); ConVar sv_rollspeed ( "sv_rollspeed", "200", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY); -#ifdef VANCE -ConVar sv_rollangle ( "sv_rollangle", "2", FCVAR_NOTIFY | FCVAR_REPLICATED, "Max view roll angle"); -#else ConVar sv_rollangle ( "sv_rollangle", "0", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Max view roll angle"); -#endif #endif // CSTRIKE_DLL - - -#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) +#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_friction ( "sv_friction","4", FCVAR_NOTIFY | FCVAR_REPLICATED, "World friction." ); #else ConVar sv_friction ( "sv_friction","4", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "World friction." ); #endif // DOD_DLL || CSTRIKE_DLL -#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) +#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( MAPBASE ) ConVar sv_bounce ( "sv_bounce","0", FCVAR_NOTIFY | FCVAR_REPLICATED, "Bounce multiplier for when physically simulated objects collide with other objects." ); ConVar sv_maxvelocity ( "sv_maxvelocity","3500", FCVAR_REPLICATED, "Maximum speed any ballistically moving object is allowed to attain per axis." ); ConVar sv_stepsize ( "sv_stepsize","18", FCVAR_NOTIFY | FCVAR_REPLICATED ); diff --git a/game/shared/mp_shareddefs.cpp b/game/shared/mp_shareddefs.cpp index a4204357..b555a88f 100644 --- a/game/shared/mp_shareddefs.cpp +++ b/game/shared/mp_shareddefs.cpp @@ -158,7 +158,6 @@ const char *g_pszMPConcepts[] = "TLK_PLAYER_CAST_MONOCULOUS", // MP_CONCEPT_PLAYER_CAST_MONOCULOUS "TLK_PLAYER_CAST_METEOR_SWARM", // MP_CONCEPT_PLAYER_CAST_METEOR_SWARM "TLK_PLAYER_CAST_SKELETON_HORDE", // MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE - "TLK_PLAYER_CAST_BOMB_HEAD_CURSE", // MP_CONCEPT_PLAYER_CAST_BOMB_HEAD_CURSE "TLK_PLAYER_SPELL_FIREBALL", // MP_CONCEPT_PLAYER_SPELL_FIREBALL "TLK_PLAYER_SPELL_MERASMUS_ZAP", // MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP @@ -172,7 +171,6 @@ const char *g_pszMPConcepts[] = "TLK_PLAYER_SPELL_MONOCULOUS", // MP_CONCEPT_PLAYER_SPELL_MONOCULOUS "TLK_PLAYER_SPELL_METEOR_SWARM", // MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM "TLK_PLAYER_SPELL_SKELETON_HORDE", // MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE - "TLK_PLAYER_SPELL_BOMB_HEAD_CURSE", // MP_CONCEPT_PLAYER_SPELL_BOMB_HEAD_CURSE // Events. "TLK_PLAYER_SPELL_PICKUP_COMMON", // MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON @@ -187,12 +185,6 @@ const char *g_pszMPConcepts[] = "TLK_MVM_LOOT_RARE", // MP_CONCEPT_MVM_LOOT_RARE "TLK_MVM_LOOT_ULTRARARE", // MP_CONCEPT_MVM_LOOT_ULTRARARE "TLK_MEDIC_HEAL_SHIELD", // MP_CONCEPT_MEDIC_HEAL_SHIELD - - "TLK_TAUNT_EUREKA_EFFECT", // MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT - - "TLK_COMBO_KILLED", // MP_CONCEPT_COMBO_KILLED - - "TLK_PLAYER_ASK_FOR_BALL", // MP_CONCEPT_PLAYER_ASK_FOR_BALL }; COMPILE_TIME_ASSERT( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT ); diff --git a/game/shared/mp_shareddefs.h b/game/shared/mp_shareddefs.h index c65cbac2..8ad6011b 100644 --- a/game/shared/mp_shareddefs.h +++ b/game/shared/mp_shareddefs.h @@ -167,7 +167,6 @@ enum MP_CONCEPT_PLAYER_CAST_MONOCULOUS, // "TLK_PLAYER_CAST_MONOCULOUS" MP_CONCEPT_PLAYER_CAST_METEOR_SWARM, // "TLK_PLAYER_CAST_METEOR_SWARM" MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE, // "TLK_PLAYER_CAST_SKELETON_HORDE" - MP_CONCEPT_PLAYER_CAST_BOMB_HEAD_CURSE, // "TLK_PLAYER_CAST_BOMB_HEAD_CURSE" MP_CONCEPT_PLAYER_SPELL_FIREBALL, // "TLK_PLAYER_SPELL_FIREBALL" MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP, // "TLK_PLAYER_SPELL_MERASMUS_ZAP" @@ -181,7 +180,6 @@ enum MP_CONCEPT_PLAYER_SPELL_MONOCULOUS, // "TLK_PLAYER_SPELL_MONOCULOUS" MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM, // "TLK_PLAYER_SPELL_METEOR_SWARM" MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE, // "TLK_PLAYER_SPELL_SKELETON_HORDE" - MP_CONCEPT_PLAYER_SPELL_BOMB_HEAD_CURSE, // "TLK_PLAYER_SPELL_BOMB_HEAD_CURSE" // Events. MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON, // "TLK_PLAYER_SPELL_PICKUP_COMMON" @@ -197,11 +195,6 @@ enum MP_CONCEPT_MVM_LOOT_ULTRARARE, // "TLK_MVM_LOOT_ULTRARARE" MP_CONCEPT_MEDIC_HEAL_SHIELD, // "TLK_MEDIC_HEAL_SHIELD" - MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT,// "TLK_TAUNT_EUREKA_EFFECT" - - MP_CONCEPT_COMBO_KILLED, // "TLK_COMBO_KILLED" - MP_CONCEPT_PLAYER_ASK_FOR_BALL, // "TLK_PLAYER_ASK_FOR_BALL" - MP_TF_CONCEPT_COUNT // Other MP_CONCEPT_* start he using MP_TF_CONCEPT_COUNT + 1 as start. diff --git a/game/shared/multiplay_gamerules.cpp b/game/shared/multiplay_gamerules.cpp index ae26bde6..49ed4efe 100644 --- a/game/shared/multiplay_gamerules.cpp +++ b/game/shared/multiplay_gamerules.cpp @@ -85,8 +85,7 @@ ConVar mp_show_voice_icons( "mp_show_voice_icons", "1", FCVAR_REPLICATED, "Show #ifdef GAME_DLL -ConVar tv_delaymapchange( "tv_delaymapchange", "0", FCVAR_NONE, "Delays map change until broadcast is complete" ); -ConVar tv_delaymapchange_protect( "tv_delaymapchange_protect", "1", FCVAR_NONE, "Protect against doing a manual map change if HLTV is broadcasting and has not caught up with a major game event such as round_end" ); +ConVar tv_delaymapchange( "tv_delaymapchange", "0", 0, "Delays map change until broadcast is complete" ); ConVar mp_restartgame( "mp_restartgame", "0", FCVAR_GAMEDLL, "If non-zero, game will restart in the specified number of seconds" ); ConVar mp_restartgame_immediate( "mp_restartgame_immediate", "0", FCVAR_GAMEDLL, "If non-zero, game will restart immediately" ); @@ -205,7 +204,8 @@ int CMultiplayRules::Damage_GetShouldNotBleed( void ) bool CMultiplayRules::Damage_IsTimeBased( int iDmgType ) { // Damage types that are time-based. - return ( ( iDmgType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) ) != 0 ); + //Tony; fixed. return Damage_GetTimeBased instead of checking them directly. + return ( ( iDmgType & Damage_GetTimeBased() ) != 0 ); } //----------------------------------------------------------------------------- @@ -279,7 +279,7 @@ CMultiplayRules::CMultiplayRules() if ( cfgfile && cfgfile[0] ) { - char szCommand[MAX_PATH]; + char szCommand[256]; Log( "Executing dedicated server config file %s\n", cfgfile ); Q_snprintf( szCommand,sizeof(szCommand), "exec %s\n", cfgfile ); @@ -293,7 +293,7 @@ CMultiplayRules::CMultiplayRules() if ( cfgfile && cfgfile[0] ) { - char szCommand[MAX_PATH]; + char szCommand[256]; Log( "Executing listen server config file %s\n", cfgfile ); Q_snprintf( szCommand,sizeof(szCommand), "exec %s\n", cfgfile ); @@ -369,7 +369,9 @@ ConVarRef suitcharger( "sk_suitcharger" ); if ( g_fGameOver ) // someone else quit the game already { - ChangeLevel(); // intermission is over + // Tony; wait for intermission to end + if ( m_flIntermissionEndTime && ( m_flIntermissionEndTime < gpGlobals->curtime ) ) + ChangeLevel(); // intermission is over return; } @@ -1150,22 +1152,19 @@ ConVarRef suitcharger( "sk_suitcharger" ); } } - // Strip ' ' and '\n' characters from string. - static void StripWhitespaceChars( char *szBuffer ) + void StripChar(char *szBuffer, const char cWhiteSpace ) { - char *szOut = szBuffer; - for ( char *szIn = szOut; *szIn; szIn++ ) + while ( char *pSpace = strchr( szBuffer, cWhiteSpace ) ) { - if ( *szIn != ' ' && *szIn != '\r' ) - *szOut++ = *szIn; + char *pNextChar = pSpace + sizeof(char); + V_strcpy( pSpace, pNextChar ); } - *szOut = '\0'; } void CMultiplayRules::GetNextLevelName( char *pszNextMap, int bufsize, bool bRandom /* = false */ ) { - char mapcfile[MAX_PATH]; + char mapcfile[256]; DetermineMapCycleFilename( mapcfile, sizeof(mapcfile), false ); // Check the time of the mapcycle file and re-populate the list of level names if the file has been modified @@ -1183,7 +1182,10 @@ ConVarRef suitcharger( "sk_suitcharger" ); // If map cycle file has changed or this is the first time through ... if ( m_nMapCycleTimeStamp != nMapCycleTimeStamp ) { - // Reload + // Reset map index and map cycle timestamp + m_nMapCycleTimeStamp = nMapCycleTimeStamp; + m_nMapCycleindex = 0; + LoadMapCycleFile(); } } @@ -1207,7 +1209,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); void CMultiplayRules::DetermineMapCycleFilename( char *pszResult, int nSizeResult, bool bForceSpew ) { - static char szLastResult[ MAX_PATH ]; + static char szLastResult[ 256]; const char *pszVar = mapcyclefile.GetString(); if ( *pszVar == '\0' ) @@ -1221,7 +1223,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); return; } - char szRecommendedName[ MAX_PATH ]; + char szRecommendedName[ 256 ]; V_sprintf_safe( szRecommendedName, "cfg/%s", pszVar ); // First, look for a mapcycle file in the cfg directory, which is preferred @@ -1272,12 +1274,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); } } - void CMultiplayRules::LoadMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector &mapList ) - { - CMultiplayRules::RawLoadMapCycleFileIntoVector( pszMapCycleFile, mapList ); - } - - void CMultiplayRules::RawLoadMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector &mapList ) + void CMultiplayRules::LoapMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector &mapList ) { CUtlBuffer buf; if ( !filesystem->ReadFile( pszMapCycleFile, "GAME", buf ) ) @@ -1289,13 +1286,21 @@ ConVarRef suitcharger( "sk_suitcharger" ); { bool bIgnore = false; - // Strip out ' ' and '\r' chars. - StripWhitespaceChars( mapList[i] ); + // Strip out the spaces in the name + StripChar( mapList[i] , '\r'); + StripChar( mapList[i] , ' '); if ( !Q_strncmp( mapList[i], "//", 2 ) || mapList[i][0] == '\0' ) { bIgnore = true; } + else if ( !engine->IsMapValid( mapList[i] ) ) + { + bIgnore = true; + + // If the engine doesn't consider it a valid map remove it from the lists + Warning( "Invalid map '%s' included in map cycle file. Ignored.\n", mapList[i] ); + } if ( bIgnore ) { @@ -1317,27 +1322,6 @@ ConVarRef suitcharger( "sk_suitcharger" ); mapList.RemoveAll(); } - bool CMultiplayRules::IsManualMapChangeOkay( const char **pszReason ) - { - if ( HLTVDirector()->IsActive() && ( HLTVDirector()->GetDelay() >= HLTV_MIN_DIRECTOR_DELAY ) ) - { - if ( tv_delaymapchange.GetBool() && tv_delaymapchange_protect.GetBool() ) - { - float flLastEvent = GetLastMajorEventTime(); - if ( flLastEvent > -1 ) - { - if ( flLastEvent > ( gpGlobals->curtime - ( HLTVDirector()->GetDelay() + 3 ) ) ) // +3 second delay to prevent instant change after a major event - { - *pszReason = "\n***WARNING*** Map change blocked. HLTV is broadcasting and has not caught up to the last major game event yet.\nYou can disable this check by setting the value of the server convar \"tv_delaymapchange_protect\" to 0.\n"; - return false; - } - } - } - } - - return true; - } - bool CMultiplayRules::IsMapInMapCycle( const char *pszName ) { for ( int i = 0; i < m_MapList.Count(); i++ ) @@ -1355,7 +1339,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); { char szNextMap[MAX_MAP_NAME]; - if ( nextlevel.GetString() && *nextlevel.GetString() ) + if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) ) { Q_strncpy( szNextMap, nextlevel.GetString(), sizeof( szNextMap ) ); } @@ -1370,19 +1354,13 @@ ConVarRef suitcharger( "sk_suitcharger" ); void CMultiplayRules::LoadMapCycleFile( void ) { - int nOldCycleIndex = m_nMapCycleindex; - m_nMapCycleindex = 0; - - char mapcfile[MAX_PATH]; + char mapcfile[256]; DetermineMapCycleFilename( mapcfile, sizeof(mapcfile), false ); FreeMapCycleFileVector( m_MapList ); - const int nMapCycleTimeStamp = filesystem->GetPathTime( mapcfile, "GAME" ); - m_nMapCycleTimeStamp = nMapCycleTimeStamp; - // Repopulate map list from mapcycle file - LoadMapCycleFileIntoVector( mapcfile, m_MapList ); + LoapMapCycleFileIntoVector( mapcfile, m_MapList ); // Load server's mapcycle into network string table for client-side voting if ( g_pStringTableServerMapCycle ) @@ -1489,29 +1467,16 @@ ConVarRef suitcharger( "sk_suitcharger" ); } #endif - // If the current map is in the same location in the new map cycle, keep that index. This gives better behavior - // when reloading a map cycle that has the current map in it multiple times. - int nOldPreviousMap = ( nOldCycleIndex == 0 ) ? ( m_MapList.Count() - 1 ) : ( nOldCycleIndex - 1 ); - if ( nOldCycleIndex >= 0 && nOldCycleIndex < m_MapList.Count() && - nOldPreviousMap >= 0 && nOldPreviousMap < m_MapList.Count() && - V_strcmp( STRING( gpGlobals->mapname ), m_MapList[ nOldPreviousMap ] ) == 0 ) - { - // The old index is still valid, and falls after our current map in the new cycle, use it - m_nMapCycleindex = nOldCycleIndex; - } - else + // If the current map selection is in the list, set m_nMapCycleindex to the map that follows it. + for ( int i = 0; i < m_MapList.Count(); i++ ) { - // Otherwise, if the current map selection is in the list, set m_nMapCycleindex to the map that follows it. - for ( int i = 0; i < m_MapList.Count(); i++ ) + if ( V_strcmp( STRING( gpGlobals->mapname ), m_MapList[i] ) == 0 ) { - if ( V_strcmp( STRING( gpGlobals->mapname ), m_MapList[i] ) == 0 ) - { - m_nMapCycleindex = i; - IncrementMapCycleIndex(); - break; - } + m_nMapCycleindex = i; + IncrementMapCycleIndex(); + break; } - } + } } void CMultiplayRules::ChangeLevelToMap( const char *pszMap ) @@ -1592,7 +1557,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); Msg( "Skipping: %s\tNext map: %s\n", szSkippedMap, szNextMap ); - if ( nextlevel.GetString() && *nextlevel.GetString() ) + if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) ) { Msg( "Warning! \"nextlevel\" is set to \"%s\" and will override the next map to be played.\n", nextlevel.GetString() ); } @@ -1660,6 +1625,10 @@ ConVarRef suitcharger( "sk_suitcharger" ); pPlayer->OnAchievementEarned( nAchievementID ); } } + else if ( FStrEq( pszCommand, "SendServerMapCycle" ) ) + { + LoadMapCycleFile(); + } } } diff --git a/game/shared/multiplay_gamerules.h b/game/shared/multiplay_gamerules.h index b74dd34f..08e06e4a 100644 --- a/game/shared/multiplay_gamerules.h +++ b/game/shared/multiplay_gamerules.h @@ -239,26 +239,20 @@ class CMultiplayRules : public CGameRules virtual void GetNextLevelName( char *szNextMap, int bufsize, bool bRandom = false ); static void DetermineMapCycleFilename( char *pszResult, int nSizeResult, bool bForceSpew ); - virtual void LoadMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector &mapList ); + static void LoapMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector &mapList ); static void FreeMapCycleFileVector ( CUtlVector &mapList ); - // LoadMapCycleFileIntoVector without the fixups inherited versions of gamerules may provide - static void RawLoadMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector &mapList ); - bool IsMapInMapCycle( const char *pszName ); - virtual bool IsManualMapChangeOkay( const char **pszReason ) OVERRIDE; - protected: virtual bool UseSuicidePenalty() { return true; } // apply point penalty for suicide? - virtual float GetLastMajorEventTime( void ){ return -1.0f; } public: virtual void ChangeLevel( void ); protected: virtual void GoToIntermission( void ); - virtual void LoadMapCycleFile( void ); + void LoadMapCycleFile( void ); void ChangeLevelToMap( const char *pszMap ); float m_flIntermissionEndTime; diff --git a/game/shared/particle_parse.cpp b/game/shared/particle_parse.cpp index 28c559e2..db15685d 100644 --- a/game/shared/particle_parse.cpp +++ b/game/shared/particle_parse.cpp @@ -567,37 +567,4 @@ void StopParticleEffects( CBaseEntity *pEntity ) } static ConCommand particle_test_stop("particle_test_stop", CC_Particle_Test_Stop, "Stops all particle systems on the selected entities.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT); -#endif //!CLIENT_DLL - -#if defined( CLIENT_DLL ) && defined( STAGING_ONLY ) - - void CC_DispatchParticle( const CCommand& args ) - { - C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); - if ( !pLocalPlayer ) - return; - - if ( args.ArgC() < 2 ) - { - DevMsg( "Use: dispatch_particle {particle_name} {surface_offset_distance}\n" ); - return; - } - - float flSurfaceOffsetDistance = 0.f; - if ( args.ArgC() == 3 ) - { - flSurfaceOffsetDistance = atof( args[2] ); - } - - Vector vForward; - pLocalPlayer->GetVectors( &vForward, NULL, NULL ); - trace_t tr; - UTIL_TraceLine( pLocalPlayer->EyePosition(), pLocalPlayer->EyePosition() + vForward * 3000, MASK_SOLID_BRUSHONLY, NULL, &tr ); - - Vector vTargetDeathPos = tr.endpos; - DispatchParticleEffect( args[1], vTargetDeathPos + flSurfaceOffsetDistance * tr.plane.normal, vec3_angle ); - } - - static ConCommand dispatch_particle( "dispatch_particle", CC_DispatchParticle, "Dispatch specified particle effect 50 units away from the lookat surface normal.\n\tArguments: {particle_name} {surface_offset_distance}", FCVAR_CHEAT ); - -#endif // CLIENT_DLL && STAGING_ONLY +#endif //CLIENT_DLL diff --git a/game/shared/particle_property.cpp b/game/shared/particle_property.cpp index fe108721..c1c44a1a 100644 --- a/game/shared/particle_property.cpp +++ b/game/shared/particle_property.cpp @@ -365,7 +365,7 @@ void CParticleProperty::StopParticlesInvolving( CBaseEntity *pEntity ) // Purpose: Stop all effects that were created using the given definition // name. //----------------------------------------------------------------------------- -void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */, bool bInverse /*= false*/ ) +void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); AssertMsg1(pDef, "Could not find particle definition %s", pszEffectName ); @@ -384,15 +384,13 @@ void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bFor { // for each effect... CNewParticleEffect *pParticleEffect = m_ParticleEffects[i].pParticleEffect.GetObject(); - bool bMatches = pParticleEffect->m_pDef() == pDef; - if ( bMatches == !bInverse ) + if (pParticleEffect->m_pDef() == pDef) { pParticleEffect->StopEmission( false, bRemoveInstantly ); } } } - void CParticleProperty::StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly /* =false */ ) { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName ); @@ -564,7 +562,7 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i #ifdef TF_CLIENT_DLL CBaseEntity *pWearable = (CBaseEntity*) pPoint->hEntity.Get(); - if ( pWearable && GetAttribInterface( pWearable ) && !pWearable->IsPlayer() ) + if ( pWearable && dynamic_cast( pWearable ) && !pWearable->IsPlayer() ) { C_BaseAnimating *pAnimating = pPoint->hEntity->GetBaseAnimating(); if ( pAnimating ) @@ -618,9 +616,7 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i if ( !pAnimating->C_BaseAnimating::GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) ) { Warning( "Cannot update control point %d for effect '%s'.\n", pPoint->iAttachmentPoint, pEffect->pParticleEffect->GetEffectName() ); - // Remove the effect cause this warning means something is orphaned - StopParticlesNamed( pEffect->pParticleEffect->GetEffectName() ); - return; + attachmentToWorld = pAnimating->RenderableToWorldTransform(); } } @@ -629,7 +625,7 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i MatrixVectors( vMat.As3x4(), &vecForward, &vecRight, &vecUp ); MatrixPosition( vMat.As3x4(), vecOrigin ); - if ( pEffect->pParticleEffect->GetIsViewModelEffect() ) + if ( pEffect->pParticleEffect->m_pDef->IsViewModelEffect() ) { FormatViewModelAttachment( vecOrigin, true ); } diff --git a/game/shared/particle_property.h b/game/shared/particle_property.h index 7978d8e7..30d62e9e 100644 --- a/game/shared/particle_property.h +++ b/game/shared/particle_property.h @@ -90,7 +90,7 @@ class CParticleProperty // kill all particle systems involving a given entity for their control points void StopParticlesInvolving( CBaseEntity *pEntity ); - void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false, bool bInverse = false ); ///< kills all particles using the given definition name + void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name void StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name // Particle System hooks diff --git a/game/shared/particlesystemquery.cpp b/game/shared/particlesystemquery.cpp index abd33c77..b97a334b 100644 --- a/game/shared/particlesystemquery.cpp +++ b/game/shared/particlesystemquery.cpp @@ -231,7 +231,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( { bSucesss = true; - Vector vecWorldPosition(0, 0, 0); + Vector vecWorldPosition; float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; @@ -308,7 +308,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( - Vector vecWorldPosition(0, 0, 0); + Vector vecWorldPosition; float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; diff --git a/game/shared/physics_shared.cpp b/game/shared/physics_shared.cpp index ba5e0d2a..2ab9396a 100644 --- a/game/shared/physics_shared.cpp +++ b/game/shared/physics_shared.cpp @@ -1003,7 +1003,11 @@ void PhysFrictionSound( CBaseEntity *pEntity, IPhysicsObject *pObject, float ene if ( psurf->sounds.scrapeSmooth && phit->audio.roughnessFactor < psurf->audio.roughThreshold ) { soundName = psurf->sounds.scrapeSmooth; +#ifdef MAPBASE + soundHandle = &psurf->soundhandles.scrapeSmooth; +#else soundHandle = &psurf->soundhandles.scrapeRough; +#endif } const char *pSoundName = physprops->GetString( soundName ); diff --git a/game/shared/playernet_vars.h b/game/shared/playernet_vars.h index ac9f7766..961e0796 100644 --- a/game/shared/playernet_vars.h +++ b/game/shared/playernet_vars.h @@ -98,6 +98,16 @@ struct sky3dparams_t // 3d skybox camera data CNetworkVar( int, scale ); CNetworkVector( origin ); +#ifdef MAPBASE + // Skybox angle support + CNetworkQAngle( angles ); + + // Skybox entity-based option + CNetworkHandle( CBaseEntity, skycamera ); + + // Sky clearcolor + CNetworkColor32( skycolor ); +#endif CNetworkVar( int, area ); // 3d skybox fog data @@ -119,5 +129,50 @@ struct audioparams_t CNetworkHandle( CBaseEntity, ent ); // the entity setting the soundscape }; +//Tony; new tonemap information. +// In single player the values are coped directly from the single env_tonemap_controller entity. +// This will allow the controller to work as it always did. +// That way nothing in ep2 will break. With these new params, the controller can properly be used in mp. + + +// Map specific objectives, such as blowing out a wall ( and bringing in more light ) +// can still change values on a particular controller as necessary via inputs, but the +// effects will not directly affect any players who are referencing this controller +// unless the option to update on inputs is set. ( otherwise the values are simply cached +// and changes only take effect when the players controller target is changed ) + +struct tonemap_params_t +{ + DECLARE_CLASS_NOBASE( tonemap_params_t ); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + tonemap_params_t() + { + m_flAutoExposureMin = -1.0f; + m_flAutoExposureMax = -1.0f; + m_flTonemapScale = -1.0f; + m_flBloomScale = -1.0f; + m_flTonemapRate = -1.0f; + } + //Tony; all of these are initialized to -1! + CNetworkVar( float, m_flTonemapScale ); + CNetworkVar( float, m_flTonemapRate ); + CNetworkVar( float, m_flBloomScale ); + + CNetworkVar( float, m_flAutoExposureMin ); + CNetworkVar( float, m_flAutoExposureMax ); + +// BLEND TODO +// +// //Tony; Time it takes for a blend to finish, default to 0; this is for the the effect of InputBlendTonemapScale. +// //When +// CNetworkVar( float, m_flBlendTime ); + + //Tony; these next 4 variables do not have to be networked; but I want to update them on the client whenever m_flBlendTime changes. + //TODO +}; #endif // PLAYERNET_VARS_H diff --git a/game/shared/point_posecontroller.cpp b/game/shared/point_posecontroller.cpp index 660d6248..43404fc8 100644 --- a/game/shared/point_posecontroller.cpp +++ b/game/shared/point_posecontroller.cpp @@ -326,6 +326,13 @@ void CPoseController::InputGetFMod( inputdata_t &inputdata ) m_fFModAmplitude.Get() ); } +#ifdef MAPBASE +void CPoseController::InputSetTarget( inputdata_t &inputdata ) +{ + SetPropName( inputdata.value.String() ); +} +#endif + #else //#ifndef CLIENT_DLL //----------------------------------------------------------------------------- diff --git a/game/shared/point_posecontroller.h b/game/shared/point_posecontroller.h index 2e11bc5e..ab8e2e83 100644 --- a/game/shared/point_posecontroller.h +++ b/game/shared/point_posecontroller.h @@ -73,6 +73,10 @@ class CPoseController : public CBaseEntity void InputRandomizeFMod( inputdata_t &inputdata ); void InputGetFMod( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetTarget( inputdata_t &inputdata ); +#endif + private: CNetworkArray( EHANDLE, m_hProps, MAX_POSE_CONTROLLED_PROPS ); // Handles to controlled models diff --git a/game/shared/postprocess_shared.h b/game/shared/postprocess_shared.h new file mode 100644 index 00000000..9d3c7df0 --- /dev/null +++ b/game/shared/postprocess_shared.h @@ -0,0 +1,54 @@ +//====== Copyright 1996-2009, Valve Corporation, All rights reserved. ======= +// +// Purpose: common definitions for post-processing effects +// +//============================================================================= + +#ifndef POSTPROCESS_SHARED_H +#define POSTPROCESS_SHARED_H + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +enum PostProcessParameterNames_t +{ + PPPN_FADE_TIME = 0, + PPPN_LOCAL_CONTRAST_STRENGTH, + PPPN_LOCAL_CONTRAST_EDGE_STRENGTH, + PPPN_VIGNETTE_START, + PPPN_VIGNETTE_END, + PPPN_VIGNETTE_BLUR_STRENGTH, + PPPN_FADE_TO_BLACK_STRENGTH, + PPPN_DEPTH_BLUR_FOCAL_DISTANCE, + PPPN_DEPTH_BLUR_STRENGTH, + PPPN_SCREEN_BLUR_STRENGTH, + PPPN_FILM_GRAIN_STRENGTH, + + POST_PROCESS_PARAMETER_COUNT +}; + +struct PostProcessParameters_t +{ + PostProcessParameters_t() + { + memset( m_flParameters, 0, sizeof( m_flParameters ) ); + m_flParameters[ PPPN_VIGNETTE_START ] = 0.8f; + m_flParameters[ PPPN_VIGNETTE_END ] = 1.1f; + } + + float m_flParameters[ POST_PROCESS_PARAMETER_COUNT ]; + + bool operator !=(PostProcessParameters_t other) + { + for (int i = 0; i < POST_PROCESS_PARAMETER_COUNT; ++i) + { + if (m_flParameters[i] != other.m_flParameters[i]) + return true; + } + + return false; + } +}; + +#endif // POSTPROCESS_SHARED_H \ No newline at end of file diff --git a/game/shared/precipitation_shared.h b/game/shared/precipitation_shared.h index 791ec29f..cb5f819c 100644 --- a/game/shared/precipitation_shared.h +++ b/game/shared/precipitation_shared.h @@ -18,8 +18,29 @@ enum PrecipitationType_t PRECIPITATION_TYPE_SNOW, PRECIPITATION_TYPE_ASH, PRECIPITATION_TYPE_SNOWFALL, + PRECIPITATION_TYPE_PARTICLERAIN, + PRECIPITATION_TYPE_PARTICLEASH, + PRECIPITATION_TYPE_PARTICLERAINSTORM, + PRECIPITATION_TYPE_PARTICLESNOW, NUM_PRECIPITATION_TYPES }; +// Returns true if the precipitation type involves the new particle system code +// +// NOTE: We can get away with >= PARTICLERAIN, but if you're adding any new precipitation types +// which DO NOT use the new particle system, please change this code to prevent it from being recognized +// as a particle type. +inline bool IsParticleRainType( PrecipitationType_t type ) +{ + // m_nPrecipType == PRECIPITATION_TYPE_PARTICLERAIN || m_nPrecipType == PRECIPITATION_TYPE_PARTICLEASH + // || m_nPrecipType == PRECIPITATION_TYPE_PARTICLERAINSTORM || m_nPrecipType == PRECIPITATION_TYPE_PARTICLESNOW + return type >= PRECIPITATION_TYPE_PARTICLERAIN; +} + +#ifdef MAPBASE +#define SF_PRECIP_PARTICLE_CLAMP (1 << 0) // Clamps particle types to the precipitation bounds; Mapbase uses this to compensate for the lack of blocker support. +#define SF_PRECIP_PARTICLE_NO_OUTER (1 << 1) // Suppresses the outer particle system. +#endif + #endif // PRECIPITATION_SHARED_H diff --git a/game/shared/predicted_viewmodel.cpp b/game/shared/predicted_viewmodel.cpp index 06691d02..53c024c2 100644 --- a/game/shared/predicted_viewmodel.cpp +++ b/game/shared/predicted_viewmodel.cpp @@ -6,6 +6,10 @@ #include "cbase.h" #include "predicted_viewmodel.h" +#ifdef CLIENT_DLL +#include "prediction.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -24,6 +28,7 @@ CPredictedViewModel::CPredictedViewModel() : m_LagAnglesHistory("CPredictedViewM { m_vLagAngles.Init(); m_LagAnglesHistory.Setup( &m_vLagAngles, 0 ); + m_vPredictedOffset.Init(); } #else CPredictedViewModel::CPredictedViewModel() @@ -46,26 +51,53 @@ ConVar cl_wpn_sway_scale( "cl_wpn_sway_scale", "1.0", FCVAR_CLIENTDLL|FCVAR_CHEA void CPredictedViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) { - #ifdef CLIENT_DLL - // Calculate our drift - Vector forward, right, up; - AngleVectors( angles, &forward, &right, &up ); - - // Add an entry to the history. - m_vLagAngles = angles; - m_LagAnglesHistory.NoteChanged( gpGlobals->curtime, cl_wpn_sway_interp.GetFloat(), false ); - - // Interpolate back 100ms. - m_LagAnglesHistory.Interpolate( gpGlobals->curtime, cl_wpn_sway_interp.GetFloat() ); - - // Now take the 100ms angle difference and figure out how far the forward vector moved in local space. - Vector vLaggedForward; - QAngle angleDiff = m_vLagAngles - angles; - AngleVectors( -angleDiff, &vLaggedForward, 0, 0 ); - Vector vForwardDiff = Vector(1,0,0) - vLaggedForward; - - // Now offset the origin using that. - vForwardDiff *= cl_wpn_sway_scale.GetFloat(); - origin += forward*vForwardDiff.x + right*-vForwardDiff.y + up*vForwardDiff.z; - #endif +#ifdef CLIENT_DLL +#ifdef SDK_DLL + //DM- take care of prediction first + if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) + { + origin += m_vPredictedOffset; + return; + } + + Vector oldOrigin = origin; + BaseClass::CalcViewModelLag( origin, angles, original_angles ); + + m_vPredictedOffset = origin - oldOrigin; + + return; //kick it back off to CBaseViewModel for proper computation, + //don't perform the unnecessary checks below +#endif + float interp = cl_wpn_sway_interp.GetFloat(); + if ( !interp ) + return; + + if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) + { + origin += m_vPredictedOffset; + return; + } + + // Calculate our drift + Vector forward, right, up; + AngleVectors( angles, &forward, &right, &up ); + + // Add an entry to the history. + m_vLagAngles = angles; + m_LagAnglesHistory.NoteChanged( gpGlobals->curtime, interp, false ); + + // Interpolate back 100ms. + m_LagAnglesHistory.Interpolate( gpGlobals->curtime, interp ); + + // Now take the 100ms angle difference and figure out how far the forward vector moved in local space. + Vector vLaggedForward; + QAngle angleDiff = m_vLagAngles - angles; + AngleVectors( -angleDiff, &vLaggedForward, 0, 0 ); + Vector vForwardDiff = Vector(1,0,0) - vLaggedForward; + + // Now offset the origin using that. + vForwardDiff *= cl_wpn_sway_scale.GetFloat(); + m_vPredictedOffset = forward*vForwardDiff.x + right*-vForwardDiff.y + up*vForwardDiff.z; + origin += m_vPredictedOffset; +#endif } \ No newline at end of file diff --git a/game/shared/predicted_viewmodel.h b/game/shared/predicted_viewmodel.h index 8e5af39c..5284d508 100644 --- a/game/shared/predicted_viewmodel.h +++ b/game/shared/predicted_viewmodel.h @@ -49,6 +49,7 @@ class CPredictedViewModel : public CBaseViewModel // This is used to lag the angles. CInterpolatedVar m_LagAnglesHistory; QAngle m_vLagAngles; + Vector m_vPredictedOffset; CPredictedViewModel( const CPredictedViewModel & ); // not defined, not accessible diff --git a/game/shared/predictioncopy.cpp b/game/shared/predictioncopy.cpp index 9721326e..72c3ae52 100644 --- a/game/shared/predictioncopy.cpp +++ b/game/shared/predictioncopy.cpp @@ -514,7 +514,7 @@ void CPredictionCopy::DescribeQuaternion( difftype_t dt, Quaternion* outValue, c for ( int j = 0; j < 4; j++ ) { - delta[j] = outValue[i][j] - inValue[i][j]; + delta[i] = outValue[i][j] - inValue[i][j]; } ReportFieldsDiffer( "quaternion[] differs (1st diff) (net %f %f %f %f - pred %f %f %f %f) delta(%f %f %f %f)\n", @@ -933,7 +933,7 @@ CPredictionCopy::difftype_t CPredictionCopy::CompareQuaternion( Quaternion* outV for ( int j = 0; j < 4; j++ ) { - delta[j] = outValue[i][j] - inValue[i][j]; + delta[i] = outValue[i][j] - inValue[i][j]; } if ( tolerance > 0.0f ) diff --git a/game/shared/props_shared.cpp b/game/shared/props_shared.cpp index 7bb0c03b..6d0f9209 100644 --- a/game/shared/props_shared.cpp +++ b/game/shared/props_shared.cpp @@ -600,10 +600,6 @@ class CBreakParser : public IVPhysicsKeyHandler pModel->mpBreakMode = MULTIPLAYER_BREAK_CLIENTSIDE; } } - else if ( !strcmpi( pKey, "velocity" ) ) - { - UTIL_StringToVector( pModel->velocity.Base(), pValue ); - } } virtual void SetDefaults( void *pData ) { @@ -621,7 +617,6 @@ class CBreakParser : public IVPhysicsKeyHandler pModel->placementName[0] = 0; pModel->placementIsBone = false; pModel->mpBreakMode = MULTIPLAYER_BREAK_DEFAULT; - pModel->velocity = vec3_origin; m_wroteCollisionGroup = false; } @@ -631,7 +626,7 @@ class CBreakParser : public IVPhysicsKeyHandler bool m_wroteCollisionGroup; }; -void BuildPropList( const char *pszBlockName, CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) +void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelindex ); if ( !pCollide ) @@ -643,7 +638,7 @@ void BuildPropList( const char *pszBlockName, CUtlVector &list, in CBreakParser breakParser( defBurstScale, defCollisionGroup ); const char *pBlock = pParse->GetCurrentBlockName(); - if ( !strcmpi( pBlock, pszBlockName ) ) + if ( !strcmpi( pBlock, "break" ) ) { int index = list.AddToTail(); breakmodel_t &breakModel = list[index]; @@ -657,11 +652,6 @@ void BuildPropList( const char *pszBlockName, CUtlVector &list, in physcollision->VPhysicsKeyParserDestroy( pParse ); } -void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ) -{ - BuildPropList( "break", list, modelindex, defBurstScale, defCollisionGroup ); -} - #if !defined(_STATIC_LINKED) || defined(CLIENT_DLL) int GetAutoMultiplayerPhysicsMode( Vector size, float mass ) { @@ -1236,8 +1226,9 @@ void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vec // Purpose: // Input : modelindex - //----------------------------------------------------------------------------- -void PrecachePropsForModel( int iModel, const char *pszBlockName ) +void PrecacheGibsForModel( int iModel ) { + VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER ); vcollide_t *pCollide = modelinfo->GetVCollide( iModel ); if ( !pCollide ) return; @@ -1250,7 +1241,7 @@ void PrecachePropsForModel( int iModel, const char *pszBlockName ) while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); - if ( !strcmpi( pBlock, pszBlockName ) ) + if ( !strcmpi( pBlock, "break" ) ) { breakmodel_t breakModel; pParse->ParseCustom( &breakModel, &breakParser ); @@ -1266,12 +1257,6 @@ void PrecachePropsForModel( int iModel, const char *pszBlockName ) physcollision->VPhysicsKeyParserDestroy( pParse ); } -void PrecacheGibsForModel( int iModel ) -{ - VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER ); - PrecachePropsForModel( iModel, "break" ); -} - //----------------------------------------------------------------------------- // Purpose: // Input : &list - @@ -1463,21 +1448,12 @@ CBaseEntity *CreateGibsFromList( CUtlVector &list, int modelindex, } Vector objectVelocity = params.velocity; - Vector gibVelocity = vec3_origin; - if ( !list[i].velocity.IsZero() ) - { - VectorRotate( list[i].velocity, matrix, gibVelocity ); - objectVelocity = gibVelocity; - } - else - { - float flScale = VectorNormalize( objectVelocity ); - objectVelocity.x += RandomFloat( -1.f, 1.0f ); - objectVelocity.y += RandomFloat( -1.0f, 1.0f ); - objectVelocity.z += RandomFloat( 0.0f, 1.0f ); - VectorNormalize( objectVelocity ); - objectVelocity *= flScale; - } + float flScale = VectorNormalize( objectVelocity ); + objectVelocity.x += RandomFloat( -1.f, 1.0f ); + objectVelocity.y += RandomFloat( -1.0f, 1.0f ); + objectVelocity.z += RandomFloat( 0.0f, 1.0f ); + VectorNormalize( objectVelocity ); + objectVelocity *= flScale; if (pPhysics) { diff --git a/game/shared/props_shared.h b/game/shared/props_shared.h index 07878d82..87ce823d 100644 --- a/game/shared/props_shared.h +++ b/game/shared/props_shared.h @@ -32,6 +32,9 @@ #define SF_PHYSPROP_ALWAYS_PICK_UP 0x100000 // Physcannon can always pick this up, no matter what mass or constraints may apply. #define SF_PHYSPROP_NO_COLLISIONS 0x200000 // Don't enable collisions on spawn #define SF_PHYSPROP_IS_GIB 0x400000 // Limit # of active gibs +#ifdef MAPBASE +#define SF_PHYSPROP_NO_ZOMBIE_SWAT 0x800000 // Zombies are not allowed to swat this +#endif // Any barrel farther away than this is ignited rather than exploded. #define PROP_EXPLOSION_IGNITE_RADIUS 32.0f @@ -217,7 +220,6 @@ struct breakmodel_t bool placementIsBone; bool isMotionDisabled; mp_break_t mpBreakMode; - Vector velocity; }; struct breakablepropparams_t @@ -243,13 +245,11 @@ struct breakablepropparams_t const char *GetMassEquivalent(float flMass); int GetAutoMultiplayerPhysicsMode( Vector size, float mass ); -void BuildPropList( const char *pszBlockName, CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); void BreakModelList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true ); void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vector &origin, const QAngle &angles, const Vector &velocity, const AngularImpulse &angularVelocity, float impactEnergyScale, float burstScale, int collisionGroup, CBaseEntity *pEntity = NULL, bool defaultLocation = true ); // Player gibs. -void PrecachePropsForModel( int iModel, const char *pszBlockName ); void PrecacheGibsForModel( int iModel ); void BuildGibList( CUtlVector &list, int modelindex, float defBurstScale, int defCollisionGroup ); CBaseEntity *CreateGibsFromList( CUtlVector &list, int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true, CUtlVector *pGibList = NULL, bool bBurning = false ); diff --git a/game/shared/ragdoll_shared.cpp b/game/shared/ragdoll_shared.cpp index 0fc50772..a9da2613 100644 --- a/game/shared/ragdoll_shared.cpp +++ b/game/shared/ragdoll_shared.cpp @@ -40,7 +40,7 @@ void CRagdollLowViolenceManager::SetLowViolence( const char *pMapName ) #if !defined( CLIENT_DLL ) // the server doesn't worry about low violence during multiplayer games - if ( g_pGameRules && g_pGameRules->IsMultiplayer() ) + if ( g_pGameRules->IsMultiplayer() ) { m_bLowViolence = false; } @@ -90,9 +90,9 @@ class CRagdollCollisionRules : public IVPhysicsKeyHandler if ( m_bSelfCollisions ) { char szToken[256]; - const char *pStr = nexttoken(szToken, pValue, ','); + const char *pStr = nexttoken(szToken, pValue, ',', sizeof(szToken)); int index0 = atoi(szToken); - nexttoken( szToken, pStr, ',' ); + nexttoken( szToken, pStr, ',' , sizeof(szToken) ); int index1 = atoi(szToken); m_pSet->EnableCollisions( index0, index1 ); @@ -174,6 +174,10 @@ void RagdollSetupAnimatedFriction( IPhysicsEnvironment *pPhysEnv, ragdoll_t *rag } } +#ifdef MAPBASE +ConVar g_ragdoll_fixed_constraints_mass( "g_ragdoll_fixed_constraints_mass", "1000", FCVAR_REPLICATED ); +#endif + static void RagdollAddSolid( IPhysicsEnvironment *pPhysEnv, ragdoll_t &ragdoll, const ragdollparams_t ¶ms, solid_t &solid ) { if ( solid.index >= 0 && solid.index < params.pCollide->solidCount) @@ -186,7 +190,12 @@ static void RagdollAddSolid( IPhysicsEnvironment *pPhysEnv, ragdoll_t &ragdoll, { if ( params.fixedConstraints ) { +#ifdef MAPBASE + if (g_ragdoll_fixed_constraints_mass.GetFloat() != -1) + solid.params.mass = g_ragdoll_fixed_constraints_mass.GetFloat(); +#else solid.params.mass = 1000.f; +#endif } solid.params.rotInertiaLimit = 0.1; @@ -742,12 +751,8 @@ bool ShouldRemoveThisRagdoll( CBaseAnimating *pRagdoll ) return false; */ - // Bail if we have a null ragdoll pointer. - if ( !pRagdoll->m_pRagdoll ) - return true; - Vector vMins, vMaxs; - + Vector origin = pRagdoll->m_pRagdoll->GetRagdollOrigin(); pRagdoll->m_pRagdoll->GetRagdollBounds( vMins, vMaxs ); @@ -825,6 +830,33 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; +#ifdef MAPBASE // From Alien Swarm SDK + // remove ragdolls with a forced retire time + for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) + { + next = m_LRU.Next(i); + + CBaseAnimating *pRagdoll = m_LRU[i].Get(); + + //Just ignore it until we're done burning/dissolving. + if ( pRagdoll && pRagdoll->GetEffectEntity() ) + continue; + + // ignore if it's not time to force retire this ragdoll + if ( m_LRU[i].GetForcedRetireTime() == 0.0f || gpGlobals->curtime < m_LRU[i].GetForcedRetireTime() ) + continue; + + //Msg(" Removing ragdoll %s due to forced retire time of %f (now = %f)\n", pRagdoll->GetModelName(), m_LRU[i].GetForcedRetireTime(), gpGlobals->curtime ); + +#ifdef CLIENT_DLL + pRagdoll->SUB_Remove(); +#else + pRagdoll->SUB_StartFadeOut( 0 ); +#endif + m_LRU.Remove(i); + } +#endif + // First, find ragdolls that are good candidates for deletion because they are not // visible at all, or are in a culled visibility box for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) @@ -842,12 +874,12 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. - if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true ) + if ( ShouldRemoveThisRagdoll( pRagdoll ) == true ) { #ifdef CLIENT_DLL - m_LRU[ i ]->SUB_Remove(); + pRagdoll->SUB_Remove(); #else - m_LRU[ i ]->SUB_StartFadeOut( 0 ); + pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); @@ -881,6 +913,27 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { +#ifdef MAPBASE + next = m_LRU.Next(i); + + CBaseAnimating *pRagdoll = m_LRU[i].Get(); + + if ( pRagdoll ) + { + IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); + if ( pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) + continue; + + // float distToPlayer = (pPlayer->GetAbsOrigin() - pRagdoll->GetAbsOrigin()).LengthSqr(); + float distToPlayer = (PlayerOrigin - pRagdoll->GetAbsOrigin()).LengthSqr(); + + if (distToPlayer > furthestDistSq) + { + furthestOne = i; + furthestDistSq = distToPlayer; + } + } +#else CBaseAnimating *pRagdoll = m_LRU[i].Get(); next = m_LRU.Next(i); @@ -899,6 +952,7 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION furthestDistSq = distToPlayer; } } +#endif else // delete bad rags first. { furthestOne = i; @@ -906,10 +960,11 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION } } + CBaseAnimating *pRemoveRagdoll = m_LRU[ furthestOne ].Get(); #ifdef CLIENT_DLL - m_LRU[ furthestOne ]->SUB_Remove(); + pRemoveRagdoll->SUB_Remove(); #else - m_LRU[ furthestOne ]->SUB_StartFadeOut( 0 ); + pRemoveRagdoll->SUB_StartFadeOut( 0 ); #endif } @@ -930,9 +985,9 @@ void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION continue; #ifdef CLIENT_DLL - m_LRU[ i ]->SUB_Remove(); + pRagdoll->SUB_Remove(); #else - m_LRU[ i ]->SUB_StartFadeOut( 0 ); + pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } @@ -962,6 +1017,33 @@ void CRagdollLRURetirement::Update( float frametime ) // Non-episodic version m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; +#ifdef MAPBASE // From Alien Swarm SDK + // remove ragdolls with a forced retire time + for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) + { + next = m_LRU.Next(i); + + CBaseAnimating *pRagdoll = m_LRU[i].Get(); + + //Just ignore it until we're done burning/dissolving. + if ( pRagdoll && pRagdoll->GetEffectEntity() ) + continue; + + // ignore if it's not time to force retire this ragdoll + if ( m_LRU[i].GetForcedRetireTime() == 0.0f || gpGlobals->curtime < m_LRU[i].GetForcedRetireTime() ) + continue; + + //Msg(" Removing ragdoll %s due to forced retire time of %f (now = %f)\n", pRagdoll->GetModelName(), m_LRU[i].GetForcedRetireTime(), gpGlobals->curtime ); + +#ifdef CLIENT_DLL + pRagdoll->SUB_Remove(); +#else + pRagdoll->SUB_StartFadeOut( 0 ); +#endif + m_LRU.Remove(i); + } +#endif + for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); @@ -977,12 +1059,12 @@ void CRagdollLRURetirement::Update( float frametime ) // Non-episodic version if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. - if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true ) + if ( ShouldRemoveThisRagdoll( pRagdoll ) == true ) { #ifdef CLIENT_DLL - m_LRU[ i ]->SUB_Remove(); + pRagdoll->SUB_Remove(); #else - m_LRU[ i ]->SUB_StartFadeOut( 0 ); + pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); @@ -1011,14 +1093,24 @@ void CRagdollLRURetirement::Update( float frametime ) // Non-episodic version CBaseAnimating *pRagdoll = m_LRU[i].Get(); +#ifdef MAPBASE + if ( pRagdoll ) + { + //Just ignore it until we're done burning/dissolving. + IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); + if ( pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) + continue; + } +#else //Just ignore it until we're done burning/dissolving. if ( pRagdoll && pRagdoll->GetEffectEntity() ) continue; +#endif #ifdef CLIENT_DLL - m_LRU[ i ]->SUB_Remove(); + pRagdoll->SUB_Remove(); #else - m_LRU[ i ]->SUB_StartFadeOut( 0 ); + pRagdoll->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } @@ -1037,11 +1129,19 @@ ConVar g_ragdoll_important_maxcount( "g_ragdoll_important_maxcount", "2", FCVAR_ //----------------------------------------------------------------------------- // Move it to the top of the LRU //----------------------------------------------------------------------------- +#ifdef MAPBASE // From Alien Swarm SDK +void CRagdollLRURetirement::MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant, float flForcedRetireTime ) +#else void CRagdollLRURetirement::MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant ) +#endif { if ( bImportant ) { +#ifdef MAPBASE // From Alien Swarm SDK + m_LRUImportantRagdolls.AddToTail( CRagdollEntry( pRagdoll, flForcedRetireTime ) ); +#else m_LRUImportantRagdolls.AddToTail( pRagdoll ); +#endif if ( m_LRUImportantRagdolls.Count() > g_ragdoll_important_maxcount.GetInt() ) { @@ -1071,7 +1171,11 @@ void CRagdollLRURetirement::MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImpo } } +#ifdef MAPBASE // From Alien Swarm SDK + m_LRU.AddToTail( CRagdollEntry( pRagdoll, flForcedRetireTime ) ); +#else m_LRU.AddToTail( pRagdoll ); +#endif } diff --git a/game/shared/ragdoll_shared.h b/game/shared/ragdoll_shared.h index f230e99f..5f4f7058 100644 --- a/game/shared/ragdoll_shared.h +++ b/game/shared/ragdoll_shared.h @@ -27,7 +27,11 @@ class CBoneAccessor; #include "bone_accessor.h" // UNDONE: Remove and make dynamic? +#ifdef MAPBASE +#define RAGDOLL_MAX_ELEMENTS 32 // Mapbase boosts this limit to the level of later Source games. +#else #define RAGDOLL_MAX_ELEMENTS 24 +#endif #define RAGDOLL_INDEX_BITS 5 // NOTE 1<= RAGDOLL_MAX_ELEMENTS #define CORE_DISSOLVE_FADE_START 0.2f @@ -79,6 +83,22 @@ struct ragdollparams_t bool fixedConstraints; }; +#ifdef MAPBASE // From Alien Swarm SDK +class CRagdollEntry +{ +public: + CRagdollEntry( CBaseAnimating *pRagdoll, float flForcedRetireTime ) : m_hRagdoll( pRagdoll ), m_flForcedRetireTime( flForcedRetireTime ) + { + } + CBaseAnimating* Get() { return m_hRagdoll.Get(); } + float GetForcedRetireTime() { return m_flForcedRetireTime; } + +private: + CHandle m_hRagdoll; + float m_flForcedRetireTime; +}; +#endif + //----------------------------------------------------------------------------- // This hooks the main game systems callbacks to allow the AI system to manage memory //----------------------------------------------------------------------------- @@ -94,7 +114,11 @@ class CRagdollLRURetirement : public CAutoGameSystemPerFrame virtual void FrameUpdatePostEntityThink( void ); // Move it to the top of the LRU +#ifdef MAPBASE // From Alien Swarm SDK + void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false, float flForcedRetireTime = 0.0f ); +#else void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false ); +#endif void SetMaxRagdollCount( int iMaxCount ){ m_iMaxRagdolls = iMaxCount; } virtual void LevelInitPreEntity( void ); @@ -102,8 +126,13 @@ class CRagdollLRURetirement : public CAutoGameSystemPerFrame private: typedef CHandle CRagdollHandle; +#ifdef MAPBASE + CUtlLinkedList< CRagdollEntry > m_LRU; + CUtlLinkedList< CRagdollEntry > m_LRUImportantRagdolls; +#else CUtlLinkedList< CRagdollHandle > m_LRU; CUtlLinkedList< CRagdollHandle > m_LRUImportantRagdolls; +#endif int m_iMaxRagdolls; int m_iSimulatedRagdollCount; diff --git a/game/shared/sceneentity_shared.cpp b/game/shared/sceneentity_shared.cpp index 80fcdc71..e8cb1905 100644 --- a/game/shared/sceneentity_shared.cpp +++ b/game/shared/sceneentity_shared.cpp @@ -44,7 +44,11 @@ void Scene_Printf( const char *pFormat, ... ) Q_vsnprintf(msg, sizeof(msg), pFormat, marker); va_end(marker); +#ifdef MAPBASE + CGMsg( 0, CON_GROUP_CHOREO, "%8.3f[%d] %s: %s", gpGlobals->curtime, gpGlobals->tickcount, CBaseEntity::IsServer() ? "sv" : "cl", msg ); +#else Msg( "%8.3f[%d] %s: %s", gpGlobals->curtime, gpGlobals->tickcount, CBaseEntity::IsServer() ? "sv" : "cl", msg ); +#endif } //----------------------------------------------------------------------------- @@ -109,7 +113,7 @@ void CSceneTokenProcessor::Error( const char *fmt, ... ) va_end( argptr ); Warning( "%s", string ); - Assert(0); + AssertMsg(0, "%s", string); } //----------------------------------------------------------------------------- diff --git a/game/shared/sceneentity_shared.h b/game/shared/sceneentity_shared.h index 6293e23b..a190e53b 100644 --- a/game/shared/sceneentity_shared.h +++ b/game/shared/sceneentity_shared.h @@ -36,6 +36,7 @@ class CSceneEventInfo m_pEvent( 0 ), m_pScene( 0 ), m_pActor( 0 ), + m_hSceneEntity(0), m_bStarted( false ), m_iLayer( -1 ), m_iPriority( 0 ), @@ -63,6 +64,8 @@ class CSceneEventInfo // Current actor CChoreoActor *m_pActor; + CHandle< CSceneEntity > m_hSceneEntity; + // Set after the first time the event has been configured ( allows // bumping markov index only at start of event playback, not every frame ) bool m_bStarted; diff --git a/game/shared/sceneimage.cpp b/game/shared/sceneimage.cpp index 053d0506..55426008 100644 --- a/game/shared/sceneimage.cpp +++ b/game/shared/sceneimage.cpp @@ -368,7 +368,7 @@ bool CSceneImage::CreateSceneImageFile( CUtlBuffer &targetBuffer, char const *pc if ( !bQuiet ) { - Msg( "Scenes: String Table: %llu bytes\n", (uint64)(stringOffsets.Count() * sizeof( int )) ); + Msg( "Scenes: String Table: %d bytes\n", stringOffsets.Count() * sizeof( int ) ); Msg( "Scenes: String Pool: %d bytes\n", stringPool.TellMaxPut() ); } diff --git a/game/shared/shareddefs.h b/game/shared/shareddefs.h index 388ebe28..2f6cc865 100644 --- a/game/shared/shareddefs.h +++ b/game/shared/shareddefs.h @@ -32,7 +32,7 @@ class CViewVectors public: CViewVectors() {} - CViewVectors( + CViewVectors( Vector vView, Vector vHullMin, Vector vHullMax, @@ -56,17 +56,17 @@ class CViewVectors // Height above entity position where the viewer's eye is. Vector m_vView; - + Vector m_vHullMin; Vector m_vHullMax; - + Vector m_vDuckHullMin; Vector m_vDuckHullMax; Vector m_vDuckView; - + Vector m_vObsHullMin; Vector m_vObsHullMax; - + Vector m_vDeadViewHeight; }; @@ -108,7 +108,7 @@ class CViewVectors #else #define TIME_TO_DUCK 0.4 #define TIME_TO_DUCK_MS 400.0f -#endif +#endif #define TIME_TO_UNDUCK 0.2 #define TIME_TO_UNDUCK_MS 200.0f @@ -140,7 +140,7 @@ typedef enum VOTE_FAILED_ISSUE_DISABLED, VOTE_FAILED_MAP_NOT_FOUND, VOTE_FAILED_MAP_NAME_REQUIRED, - VOTE_FAILED_ON_COOLDOWN, + VOTE_FAILED_FAILED_RECENTLY, VOTE_FAILED_TEAM_CANT_CALL, VOTE_FAILED_WAITINGFORPLAYERS, VOTE_FAILED_PLAYERNOTFOUND, @@ -151,8 +151,6 @@ typedef enum VOTE_FAILED_MAP_NOT_VALID, VOTE_FAILED_CANNOT_KICK_FOR_TIME, VOTE_FAILED_CANNOT_KICK_DURING_ROUND, - VOTE_FAILED_VOTE_IN_PROGRESS, - VOTE_FAILED_KICK_LIMIT_REACHED, // TF-specific? VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE, @@ -212,7 +210,14 @@ enum CastVote #define bits_SUIT_DEVICE_FLASHLIGHT 0x00000002 #define bits_SUIT_DEVICE_BREATHER 0x00000004 -#define MAX_SUIT_DEVICES 3 +#ifdef MAPBASE +// Custom suit power devices +#define bits_SUIT_DEVICE_CUSTOM0 0x00000008 +#define bits_SUIT_DEVICE_CUSTOM1 0x00000010 +#define bits_SUIT_DEVICE_CUSTOM2 0x00000020 +#endif + +#define MAX_SUIT_DEVICES 6 // Mapbase boosts this to 6 for the custom devices //=================================================================================================================== @@ -283,7 +288,7 @@ enum CastVote // Humans only have left and right hands, though we might have aliens with more // than two, sigh -#define MAX_VIEWMODELS 3 +#define MAX_VIEWMODELS 2 #define MAX_BEAM_ENTS 10 @@ -338,7 +343,7 @@ enum #define HITGROUP_HEAD 1 #define HITGROUP_CHEST 2 #define HITGROUP_STOMACH 3 -#define HITGROUP_LEFTARM 4 +#define HITGROUP_LEFTARM 4 #define HITGROUP_RIGHTARM 5 #define HITGROUP_LEFTLEG 6 #define HITGROUP_RIGHTLEG 7 @@ -361,6 +366,14 @@ enum PLAYER_ANIM PLAYER_RELOAD, PLAYER_START_AIMING, PLAYER_LEAVE_AIMING, + +#ifdef MAPBASE + // New player animations from Mapbase + PLAYER_ATTACK2, + PLAYER_ATTACK3, + PLAYER_UNHOLSTER, + PLAYER_HOLSTER, +#endif }; #ifdef HL2_DLL @@ -396,7 +409,7 @@ enum PLAYER_ANIM // For a means of resolving these consts into debug string text, see function // CTakeDamageInfo::DebugGetDamageTypeString(unsigned int DamageType, char *outbuf, unsigned int outbuflength ) #define DMG_GENERIC 0 // generic damage -- do not use if you want players to flinch and bleed! -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object. +#define DMG_CRUSH (1 << 0) // crushed by falling or moving object. // NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage. // DON'T use DMG_CRUSH when damaging entities unless it's the result of a physics collision. You probably want DMG_CLUB instead. #define DMG_BULLET (1 << 1) // shot @@ -408,8 +421,8 @@ enum PLAYER_ANIM #define DMG_CLUB (1 << 7) // crowbar, punch, headbutt #define DMG_SHOCK (1 << 8) // electric shock #define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) // Prevent a physics force +#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam +#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) // Prevent a physics force #define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death #define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. #define DMG_DROWN (1 << 14) // Drowning @@ -457,7 +470,6 @@ enum { OBS_MODE_FIXED, // view from a fixed camera position OBS_MODE_IN_EYE, // follow a player in first person view OBS_MODE_CHASE, // follow a player in third person view - OBS_MODE_POI, // PASSTIME point of interest - game objective, big fight, anything interesting; added in the middle of the enum due to tons of hard-coded " *m_pIgnoreEntList; +#endif + +#ifdef MAPBASE_VSCRIPT // These functions are used by VScript to expose FireBulletsInfo_t to users. + int GetShots() { return m_iShots; } + void SetShots( int value ) { m_iShots = value; } + + Vector GetSource() { return m_vecSrc; } + void SetSource( Vector value ) { m_vecSrc = value; } + Vector GetDirShooting() { return m_vecDirShooting; } + void SetDirShooting( Vector value ) { m_vecDirShooting = value; } + Vector GetSpread() { return m_vecSpread; } + void SetSpread( Vector value ) { m_vecSpread = value; } + + float GetDistance() { return m_flDistance; } + void SetDistance( float value ) { m_flDistance = value; } + + int GetAmmoType() { return m_iAmmoType; } + void SetAmmoType( int value ) { m_iAmmoType = value; } + + int GetTracerFreq() { return m_iTracerFreq; } + void SetTracerFreq( int value ) { m_iTracerFreq = value; } + + float GetDamage() { return m_flDamage; } + void SetDamage( float value ) { m_flDamage = value; } + int GetPlayerDamage() { return m_iPlayerDamage; } + void SetPlayerDamage( float value ) { m_iPlayerDamage = value; } + + int GetFlags() { return m_nFlags; } + void SetFlags( float value ) { m_nFlags = value; } + + float GetDamageForceScale() { return m_flDamageForceScale; } + void SetDamageForceScale( float value ) { m_flDamageForceScale = value; } + + HSCRIPT ScriptGetAttacker(); + void ScriptSetAttacker( HSCRIPT value ); + HSCRIPT ScriptGetAdditionalIgnoreEnt(); + void ScriptSetAdditionalIgnoreEnt( HSCRIPT value ); + + bool GetPrimaryAttack() { return m_bPrimaryAttack; } + void SetPrimaryAttack( bool value ) { m_bPrimaryAttack = value; } +#endif }; + #define DEFAULT_BULLET_MODEL "models/weapons/w_bullet.mdl" #define DEFAULT_BULLET_SPEED 15000 #define DEFAULT_BULLET_SPEED_MS 300 @@ -741,7 +818,7 @@ struct ProjectileBulletsInfo_t : public FireBulletsInfo_t } ProjectileBulletsInfo_t(int nShots, const Vector& vecSrc, const Vector& vecDir, const Vector& vecSpread, float flDistance, int nAmmoType, bool bPrimaryAttack = true, - float flBulletSpeed = DEFAULT_BULLET_SPEED, float flBulletSize = 0.0f) : + float flBulletSpeed = DEFAULT_BULLET_SPEED, float flBulletSize = 0.0f) : FireBulletsInfo_t(nShots, vecSrc, vecDir, vecSpread, flDistance, nAmmoType, bPrimaryAttack) { m_flBulletSpeed = flBulletSpeed; @@ -752,9 +829,10 @@ struct ProjectileBulletsInfo_t : public FireBulletsInfo_t float m_flBulletSize; }; + //----------------------------------------------------------------------------- // Purpose: Data for making the MOVETYPE_STEP entities appear to simulate every frame -// We precompute the simulation and then meter it out each tick during networking of the +// We precompute the simulation and then meter it out each tick during networking of the // entities origin and orientation. Uses a bit more bandwidth, but it solves the NPCs interacting // with elevators/lifts bugs. //----------------------------------------------------------------------------- @@ -927,6 +1005,39 @@ enum #define COMMENTARY_BUTTONS (IN_USE) #endif +enum tprbGameInfo_e +{ + // Teamplay Roundbased Game rules shared + TPRBGAMEINFO_GAMESTATE = 1, //gets the state of the current game (waiting for players, setup, active, overtime, stalemate, roundreset) + TPRBGAMEINFO_RESERVED1, + TPRBGAMEINFO_RESERVED2, + TPRBGAMEINFO_RESERVED3, + TPRBGAMEINFO_RESERVED4, + TPRBGAMEINFO_RESERVED5, + TPRBGAMEINFO_RESERVED6, + TPRBGAMEINFO_RESERVED7, + TPRBGAMEINFO_RESERVED8, + + TPRBGAMEINFO_LASTGAMEINFO, +}; +// Mark it off so valvegame_plugin_def.h ignores it, if both headers are included in a plugin. +#define TPRBGAMEINFO_x 1 + +//Tony; (t)eam(p)lay(r)ound(b)ased gamerules -- Game Info values +#define TPRB_STATE_WAITING (1<<0) +#define TPRB_STATE_SETUP (1<<1) +#define TPRB_STATE_ACTIVE (1<<2) +#define TPRB_STATE_ROUNDWON (1<<3) +#define TPRB_STATE_OVERTIME (1<<4) +#define TPRB_STATE_STALEMATE (1<<5) +#define TPRB_STATE_ROUNDRESET (1<<6) +#define TPRB_STATE_WAITINGREADYSTART (1<<7) + +//Tony; including sdk_shareddefs.h because I use it in a _lot_ of places that needs to be seen before many other things. +#ifdef SDK_DLL +#include "sdk_shareddefs.h" +#endif + #define TEAM_TRAIN_MAX_TEAMS 4 #define TEAM_TRAIN_MAX_HILLS 5 #define TEAM_TRAIN_FLOATS_PER_HILL 2 @@ -973,4 +1084,16 @@ enum }; #endif // TF_DLL || TF_CLIENT_DLL +#ifdef MAPBASE +// Developer commentary types +enum +{ + COMMENTARY_TYPE_AUDIO, // Play commentary audio (default) + + COMMENTARY_TYPE_TEXT, // Display text data + COMMENTARY_TYPE_IMAGE, // Display an image + COMMENTARY_TYPE_SCENE, // Play a VCD file +}; +#endif + #endif // SHAREDDEFS_H diff --git a/game/shared/takedamageinfo.cpp b/game/shared/takedamageinfo.cpp index f3eb84c3..269f8043 100644 --- a/game/shared/takedamageinfo.cpp +++ b/game/shared/takedamageinfo.cpp @@ -31,6 +31,60 @@ BEGIN_SIMPLE_DATADESC( CTakeDamageInfo ) DEFINE_FIELD( m_iDamagedOtherPlayers, FIELD_INTEGER), END_DATADESC() +#ifdef MAPBASE_VSCRIPT +BEGIN_SCRIPTDESC_ROOT( CTakeDamageInfo, "Damage information handler." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetInflictor, "GetInflictor", "Gets the inflictor." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetInflictor, "SetInflictor", "Sets the inflictor." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeapon, "GetWeapon", "Gets the weapon." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetWeapon, "SetWeapon", "Sets the weapon." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttacker, "GetAttacker", "Gets the attacker." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSetAttacker, "SetAttacker", "Sets the attacker." ) + + DEFINE_SCRIPTFUNC( GetDamage, "Gets the damage." ) + DEFINE_SCRIPTFUNC( SetDamage, "Sets the damage." ) + DEFINE_SCRIPTFUNC( GetMaxDamage, "Gets the max damage." ) + DEFINE_SCRIPTFUNC( SetMaxDamage, "Sets the max damage." ) + DEFINE_SCRIPTFUNC( ScaleDamage, "Scales the damage." ) + DEFINE_SCRIPTFUNC( AddDamage, "Adds to the damage." ) + DEFINE_SCRIPTFUNC( SubtractDamage, "Removes from the damage." ) + DEFINE_SCRIPTFUNC( GetDamageBonus, "Gets the damage bonus." ) + DEFINE_SCRIPTFUNC( SetDamageBonus, "Sets the damage bonus." ) + + DEFINE_SCRIPTFUNC( GetBaseDamage, "Gets the base damage." ) + DEFINE_SCRIPTFUNC( BaseDamageIsValid, "Checks if the base damage is valid." ) + + DEFINE_SCRIPTFUNC( GetDamageForce, "Gets the damage force." ) + DEFINE_SCRIPTFUNC( SetDamageForce, "Sets the damage force." ) + DEFINE_SCRIPTFUNC( ScaleDamageForce, "Scales the damage force." ) + + DEFINE_SCRIPTFUNC( GetDamagePosition, "Gets the damage position." ) + DEFINE_SCRIPTFUNC( SetDamagePosition, "Sets the damage position." ) + + DEFINE_SCRIPTFUNC( GetReportedPosition, "Gets the reported damage position." ) + DEFINE_SCRIPTFUNC( SetReportedPosition, "Sets the reported damage position." ) + + DEFINE_SCRIPTFUNC( GetDamageType, "Gets the damage type." ) + DEFINE_SCRIPTFUNC( SetDamageType, "Sets the damage type." ) + DEFINE_SCRIPTFUNC( AddDamageType, "Adds to the damage type." ) + DEFINE_SCRIPTFUNC( GetDamageCustom, "Gets the damage custom." ) + DEFINE_SCRIPTFUNC( SetDamageCustom, "Sets the damage custom." ) + DEFINE_SCRIPTFUNC( GetDamageStats, "Gets the damage stats." ) + DEFINE_SCRIPTFUNC( SetDamageStats, "Sets the damage stats." ) + DEFINE_SCRIPTFUNC( IsForceFriendlyFire, "Gets force friendly fire." ) + DEFINE_SCRIPTFUNC( SetForceFriendlyFire, "Sets force friendly fire." ) + + DEFINE_SCRIPTFUNC( GetAmmoType, "Gets the ammo type." ) + DEFINE_SCRIPTFUNC( SetAmmoType, "Sets the ammo type." ) + DEFINE_SCRIPTFUNC( GetAmmoName, "Gets the ammo type name." ) + + DEFINE_SCRIPTFUNC( GetPlayerPenetrationCount, "Gets the player penetration count." ) + DEFINE_SCRIPTFUNC( SetPlayerPenetrationCount, "Sets the player penetration count." ) + + DEFINE_SCRIPTFUNC( GetDamagedOtherPlayers, "Gets whether other players have been damaged." ) + DEFINE_SCRIPTFUNC( SetDamagedOtherPlayers, "Sets whether other players have been damaged." ) +END_SCRIPTDESC(); +#endif + void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, const Vector &reportedPosition, float flDamage, int bitsDamageType, int iCustomDamage ) { m_hInflictor = pInflictor; @@ -61,7 +115,6 @@ void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBa m_iPlayerPenetrationCount = 0; m_flDamageBonus = 0.f; m_bForceFriendlyFire = false; - m_flDamageForForce = 0.f; } CTakeDamageInfo::CTakeDamageInfo() @@ -167,6 +220,50 @@ const char *CTakeDamageInfo::GetAmmoName() const return pszAmmoType; } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CTakeDamageInfo::ScriptGetInflictor() const +{ + return ToHScript( GetInflictor() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CTakeDamageInfo::ScriptSetInflictor( HSCRIPT pInflictor ) +{ + SetInflictor( ToEnt( pInflictor ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CTakeDamageInfo::ScriptGetWeapon() const +{ + return ToHScript( GetWeapon() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CTakeDamageInfo::ScriptSetWeapon( HSCRIPT pWeapon ) +{ + SetWeapon( ToEnt( pWeapon ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +HSCRIPT CTakeDamageInfo::ScriptGetAttacker() const +{ + return ToHScript( GetAttacker() ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CTakeDamageInfo::ScriptSetAttacker( HSCRIPT pAttacker ) +{ + SetAttacker( ToEnt( pAttacker ) ); +} +#endif + // -------------------------------------------------------------------------------------------------- // // MultiDamage // Collects multiple small damages into a single damage diff --git a/game/shared/takedamageinfo.h b/game/shared/takedamageinfo.h index 43dfdf49..046c8111 100644 --- a/game/shared/takedamageinfo.h +++ b/game/shared/takedamageinfo.h @@ -14,6 +14,10 @@ #include "networkvar.h" // todo: change this when DECLARE_CLASS is moved into a better location. +#ifdef MAPBASE_VSCRIPT +#include "vscript/ivscript.h" +#endif + // Used to initialize m_flBaseDamage to something that we know pretty much for sure // hasn't been modified by a user. #define BASEDAMAGE_NOT_SPECIFIED FLT_MAX @@ -55,8 +59,7 @@ class CTakeDamageInfo void AddDamage( float flAddAmount ); void SubtractDamage( float flSubtractAmount ); float GetDamageBonus() const; - CBaseEntity *GetDamageBonusProvider() const; - void SetDamageBonus( float flBonus, CBaseEntity *pProvider = NULL ); + void SetDamageBonus( float flBonus ); float GetBaseDamage() const; bool BaseDamageIsValid() const; @@ -64,8 +67,6 @@ class CTakeDamageInfo Vector GetDamageForce() const; void SetDamageForce( const Vector &damageForce ); void ScaleDamageForce( float flScaleAmount ); - float GetDamageForForceCalc() const; - void SetDamageForForceCalc( const float flScaleAmount ); Vector GetDamagePosition() const; void SetDamagePosition( const Vector &damagePosition ); @@ -105,6 +106,15 @@ class CTakeDamageInfo // For designer debug output. static void DebugGetDamageTypeString(unsigned int DamageType, char *outbuf, int outbuflength ); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetInflictor() const; + void ScriptSetInflictor( HSCRIPT pInflictor ); + HSCRIPT ScriptGetWeapon() const; + void ScriptSetWeapon( HSCRIPT pWeapon ); + HSCRIPT ScriptGetAttacker() const; + void ScriptSetAttacker( HSCRIPT pAttacker ); +#endif + //private: void CopyDamageToBaseDamage(); @@ -128,11 +138,8 @@ class CTakeDamageInfo int m_iDamagedOtherPlayers; int m_iPlayerPenetrationCount; float m_flDamageBonus; // Anything that increases damage (crit) - store the delta - EHANDLE m_hDamageBonusProvider; // Who gave us the ability to do extra damage? bool m_bForceFriendlyFire; // Ideally this would be a dmg type, but we can't add more - float m_flDamageForForce; - DECLARE_SIMPLE_DATADESC(); }; @@ -253,15 +260,9 @@ inline float CTakeDamageInfo::GetDamageBonus() const return m_flDamageBonus; } -inline CBaseEntity *CTakeDamageInfo::GetDamageBonusProvider() const -{ - return m_hDamageBonusProvider; -} - -inline void CTakeDamageInfo::SetDamageBonus( float flBonus, CBaseEntity *pProvider /*= NULL*/ ) +inline void CTakeDamageInfo::SetDamageBonus( float flBonus ) { m_flDamageBonus = flBonus; - m_hDamageBonusProvider = pProvider; } inline float CTakeDamageInfo::GetBaseDamage() const @@ -293,16 +294,6 @@ inline void CTakeDamageInfo::ScaleDamageForce( float flScaleAmount ) m_vecDamageForce *= flScaleAmount; } -inline float CTakeDamageInfo::GetDamageForForceCalc() const -{ - return m_flDamageForForce; -} - -inline void CTakeDamageInfo::SetDamageForForceCalc( float flDamage ) -{ - m_flDamageForForce = flDamage; -} - inline Vector CTakeDamageInfo::GetDamagePosition() const { return m_vecDamagePosition; @@ -353,12 +344,12 @@ inline void CTakeDamageInfo::SetDamageCustom( int iDamageCustom ) inline int CTakeDamageInfo::GetDamageStats() const { - return m_iDamageCustom; + return m_iDamageStats; } inline void CTakeDamageInfo::SetDamageStats( int iDamageCustom ) { - m_iDamageCustom = iDamageCustom; + m_iDamageStats = iDamageCustom; } inline int CTakeDamageInfo::GetAmmoType() const diff --git a/game/shared/teamplay_gamerules.h b/game/shared/teamplay_gamerules.h index 6be6082c..952895eb 100644 --- a/game/shared/teamplay_gamerules.h +++ b/game/shared/teamplay_gamerules.h @@ -87,7 +87,7 @@ class CTeamplayRules : public CMultiplayRules virtual bool TimerMayExpire( void ) { return true; } // A game has been won by the specified team - virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false, bool bFinal = false ) { return; } + virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false ) { return; } virtual void SetStalemate( int iReason, bool bForceMapReset = true, bool bSwitchTeams = false ) { return; } // Used to determine if all players should switch teams diff --git a/game/shared/teamplay_round_timer.cpp b/game/shared/teamplay_round_timer.cpp index e0739e77..4394fe55 100644 --- a/game/shared/teamplay_round_timer.cpp +++ b/game/shared/teamplay_round_timer.cpp @@ -44,14 +44,6 @@ #define ROUND_SETUP_2SECS "Announcer.RoundBegins2Seconds" #define ROUND_SETUP_1SECS "Announcer.RoundBegins1Seconds" -#ifdef TF_CLIENT_DLL -#define MERASMUS_SETUP_5SECS "Merasmus.RoundBegins5Seconds" -#define MERASMUS_SETUP_4SECS "Merasmus.RoundBegins4Seconds" -#define MERASMUS_SETUP_3SECS "Merasmus.RoundBegins3Seconds" -#define MERASMUS_SETUP_2SECS "Merasmus.RoundBegins2Seconds" -#define MERASMUS_SETUP_1SECS "Merasmus.RoundBegins1Seconds" -#endif - #define ROUND_START_BELL "Ambient.Siren" #define ROUND_TIMER_TIME_ADDED "Announcer.TimeAdded" @@ -253,7 +245,6 @@ CTeamRoundTimer::CTeamRoundTimer( void ) m_bResetTimeOnRoundStart = false; m_nTimeToUseAfterSetupFinished = 0; m_flNextOvertimeNag = 0; - m_flLastTime = 0.f; #endif } @@ -291,14 +282,6 @@ void CTeamRoundTimer::Precache( void ) PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_LOSER ); PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_WINNER ); PrecacheScriptSound( ROUND_START_BELL ); - -#ifdef TF_CLIENT_DLL - PrecacheScriptSound( MERASMUS_SETUP_5SECS ); - PrecacheScriptSound( MERASMUS_SETUP_4SECS ); - PrecacheScriptSound( MERASMUS_SETUP_3SECS ); - PrecacheScriptSound( MERASMUS_SETUP_2SECS ); - PrecacheScriptSound( MERASMUS_SETUP_1SECS ); -#endif // TF_CLIENT_DLL #endif // TF_DLL || TF_CLIENT_DLL } @@ -591,16 +574,7 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning ) case RT_WARNING_5SECS: if ( m_nState == RT_STATE_SETUP ) { -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) ) - { - pszRetVal = MERASMUS_SETUP_5SECS; - } - else -#endif - { - pszRetVal = ROUND_SETUP_5SECS; - } + pszRetVal = ROUND_SETUP_5SECS; } else { @@ -610,16 +584,7 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning ) case RT_WARNING_4SECS: if ( m_nState == RT_STATE_SETUP ) { -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) ) - { - pszRetVal = MERASMUS_SETUP_4SECS; - } - else -#endif - { - pszRetVal = ROUND_SETUP_4SECS; - } + pszRetVal = ROUND_SETUP_4SECS; } else { @@ -629,16 +594,7 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning ) case RT_WARNING_3SECS: if ( m_nState == RT_STATE_SETUP ) { -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) ) - { - pszRetVal = MERASMUS_SETUP_3SECS; - } - else -#endif - { - pszRetVal = ROUND_SETUP_3SECS; - } + pszRetVal = ROUND_SETUP_3SECS; } else { @@ -648,16 +604,7 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning ) case RT_WARNING_2SECS: if ( m_nState == RT_STATE_SETUP ) { -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) ) - { - pszRetVal = MERASMUS_SETUP_2SECS; - } - else -#endif - { - pszRetVal = ROUND_SETUP_2SECS; - } + pszRetVal = ROUND_SETUP_2SECS; } else { @@ -667,16 +614,7 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning ) case RT_WARNING_1SECS: if ( m_nState == RT_STATE_SETUP ) { -#ifdef TF_CLIENT_DLL - if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) ) - { - pszRetVal = MERASMUS_SETUP_1SECS; - } - else -#endif - { - pszRetVal = ROUND_SETUP_1SECS; - } + pszRetVal = ROUND_SETUP_1SECS; } else { @@ -843,9 +781,6 @@ void CTeamRoundTimer::SetTimerThink( int nType ) //----------------------------------------------------------------------------- void CTeamRoundTimer::RoundTimerSetupThink( void ) { - float flLastTime = m_flLastTime; - m_flLastTime = GetTimeRemaining(); - if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false ) { inputdata_t data; @@ -862,22 +797,6 @@ void CTeamRoundTimer::RoundTimerSetupThink( void ) float flTime = GetTimeRemaining(); TeamplayRoundBasedRules()->SetOvertime( false ); - if ( m_flLastTime > 0.f ) - { - int nLastSecond = floor( flLastTime ); - int nThisSecond = floor( flTime ); - - if ( nLastSecond != nThisSecond ) - { - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_pre_round_time_left" ); - if ( event ) - { - event->SetInt( "time", nThisSecond ); - gameeventmanager->FireEvent( event ); - } - } - } - if ( flTime <= 0.0f && m_bFireFinished ) { IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_setup_finished" ); @@ -1371,15 +1290,15 @@ void CTeamRoundTimer::InputAddTeamTime( inputdata_t &input ) int nSeconds = 0; // get the team - p = nexttoken( token, p, ' ' ); - if ( token[0] ) + p = nexttoken( token, p, ' ', sizeof(token) ); + if ( token ) { nTeam = Q_atoi( token ); } // get the time - p = nexttoken( token, p, ' ' ); - if ( token[0] ) + p = nexttoken( token, p, ' ', sizeof(token) ); + if ( token ) { nSeconds = Q_atoi( token ); } diff --git a/game/shared/teamplay_round_timer.h b/game/shared/teamplay_round_timer.h index df94a271..103b2546 100644 --- a/game/shared/teamplay_round_timer.h +++ b/game/shared/teamplay_round_timer.h @@ -80,7 +80,7 @@ class CTeamRoundTimer : public CBaseEntity bool IsStopWatchTimer( void ) { return m_bStopWatchTimer; } float GetStopWatchTotalTime( void ) { return m_flTotalTime; } bool IsRoundMaxTimerSet( void ) { return m_nTimerMaxLength > 0; } - int GetTimerInitialLength( void ) { return m_nTimerInitialLength; } + private: void CalculateOutputMessages( void ); @@ -158,7 +158,6 @@ class CTeamRoundTimer : public CBaseEntity COutputEvent m_OnSetupFinished; float m_flNextOvertimeNag; - float m_flLastTime; DECLARE_DATADESC(); diff --git a/game/shared/teamplayroundbased_gamerules.cpp b/game/shared/teamplayroundbased_gamerules.cpp index 8d2b3e00..26a75b18 100644 --- a/game/shared/teamplayroundbased_gamerules.cpp +++ b/game/shared/teamplayroundbased_gamerules.cpp @@ -35,15 +35,17 @@ #if defined(TF_CLIENT_DLL) || defined(TF_DLL) #include "tf_gamerules.h" - #include "tf_lobby.h" - #ifdef GAME_DLL - #include "player_vs_environment/tf_population_manager.h" - #include "../server/tf/tf_gc_server.h" - #include "../server/tf/tf_objective_resource.h" - #else - #include "../client/tf/tf_gc_client.h" - #include "../client/tf/c_tf_objective_resource.h" - #endif // GAME_DLL + #if defined(TF_CLIENT_DLL) || defined(TF_DLL) + #include "tf_lobby.h" + #ifdef GAME_DLL + #include "player_vs_environment/tf_population_manager.h" + #include "../server/tf/tf_gc_server.h" + #include "../server/tf/tf_objective_resource.h" + #else + #include "../client/tf/tf_gc_client.h" + #include "../client/tf/c_tf_objective_resource.h" + #endif // GAME_DLL + #endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL) #endif // memdbgon must be the last include file in a .cpp file!!! @@ -88,7 +90,6 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules RecvPropBool( RECVINFO( m_bStopWatch ) ), RecvPropBool( RECVINFO( m_bMultipleTrains ) ), RecvPropArray3( RECVINFO_ARRAY(m_bPlayerReady), RecvPropBool( RECVINFO(m_bPlayerReady[0]) ) ), - RecvPropBool( RECVINFO( m_bCheatsEnabledDuringLevel ) ), #else SendPropInt( SENDINFO( m_iRoundState ), 5 ), @@ -106,7 +107,6 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules SendPropBool( SENDINFO( m_bStopWatch ) ), SendPropBool( SENDINFO( m_bMultipleTrains ) ), SendPropArray3( SENDINFO_ARRAY3(m_bPlayerReady), SendPropBool( SENDINFO_ARRAY(m_bPlayerReady) ) ), - SendPropBool( SENDINFO( m_bCheatsEnabledDuringLevel ) ), #endif END_NETWORK_TABLE() @@ -184,7 +184,7 @@ ConVar tf_arena_round_time( "tf_arena_round_time", "0", FCVAR_NOTIFY | FCVAR_REP ConVar tf_arena_max_streak( "tf_arena_max_streak", "3", FCVAR_NOTIFY | FCVAR_REPLICATED, "Teams will be scrambled if one team reaches this streak" ); ConVar tf_arena_use_queue( "tf_arena_use_queue", "1", FCVAR_REPLICATED | FCVAR_NOTIFY, "Enables the spectator queue system for Arena." ); -ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED, +ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED | FCVAR_NOTIFY, "Teams are unbalanced when one team has this many more players than the other team. (0 disables check)", true, 0, // min value true, 30 // max value @@ -194,14 +194,9 @@ ConVar mp_maxrounds( "mp_maxrounds", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "max ConVar mp_winlimit( "mp_winlimit", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Max score one team can reach before server changes maps", true, 0, false, 0 ); ConVar mp_disable_respawn_times( "mp_disable_respawn_times", "0", FCVAR_NOTIFY | FCVAR_REPLICATED ); ConVar mp_bonusroundtime( "mp_bonusroundtime", "15", FCVAR_REPLICATED, "Time after round win until round restarts", true, 5, true, 15 ); -ConVar mp_bonusroundtime_final( "mp_bonusroundtime_final", "15", FCVAR_REPLICATED, "Time after final round ends until round restarts", true, 5, true, 300 ); ConVar mp_stalemate_meleeonly( "mp_stalemate_meleeonly", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Restrict everyone to melee weapons only while in Sudden Death." ); ConVar mp_forceautoteam( "mp_forceautoteam", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Automatically assign players to teams when joining." ); -#if defined( _DEBUG ) || defined( STAGING_ONLY ) -ConVar mp_developer( "mp_developer", "0", FCVAR_ARCHIVE | FCVAR_REPLICATED | FCVAR_NOTIFY, "1: basic conveniences (instant respawn and class change, etc). 2: add combat conveniences (infinite ammo, buddha, etc)" ); -#endif // _DEBUG || STAGING_ONLY - #ifdef GAME_DLL ConVar mp_showroundtransitions( "mp_showroundtransitions", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Show gamestate round transitions." ); ConVar mp_enableroundwaittime( "mp_enableroundwaittime", "1", FCVAR_REPLICATED, "Enable timers to wait between rounds." ); @@ -361,21 +356,25 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void ) m_flNextRespawnWave.Set( i, 0 ); m_TeamRespawnWaveTimes.Set( i, -1.0f ); + m_bTeamReady.Set( i, false ); + #ifdef GAME_DLL m_flOriginalTeamRespawnWaveTime[i] = -1.0f; #endif } + for ( int i = 0; i < MAX_PLAYERS; i++ ) + { + m_bPlayerReady.Set( i, false ); + } + m_bInOvertime = false; m_bInSetup = false; m_bSwitchedTeamsThisRound = false; m_flStopWatchTotalTime = -1.0f; m_bMultipleTrains = false; - m_bAllowBetweenRounds = true; #ifdef GAME_DLL - ListenForGameEvent( "server_changelevel_failed" ); - m_pCurStateInfo = NULL; State_Transition( GR_STATE_PREGAME ); @@ -389,8 +388,8 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void ) SetRoundToPlayNext( NULL_STRING ); m_bInWaitingForPlayers = false; m_bAwaitingReadyRestart = false; - m_flRestartRoundTime = -1.0f; - m_flMapResetTime = 0.0f; + m_flRestartRoundTime = -1; + m_flMapResetTime = 0; m_bPrevRoundWasWaitingForPlayers = false; m_iWinningTeam = TEAM_UNASSIGNED; @@ -399,13 +398,12 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void ) m_bAllowStalemateAtTimelimit = false; m_bChangelevelAfterStalemate = false; - m_flRoundStartTime = 0.0f; - m_flNewThrottledAlertTime = 0.0f; - m_flStartBalancingTeamsAt = 0.0f; + m_flRoundStartTime = 0; + m_flNewThrottledAlertTime = 0; + m_flStartBalancingTeamsAt = 0; m_bPrintedUnbalanceWarning = false; - m_flFoundUnbalancedTeamsTime = -1.0f; + m_flFoundUnbalancedTeamsTime = -1; m_flWaitingForPlayersTimeEnds = 0.0f; - m_flLastTeamWin = -1.0f; m_nRoundsPlayed = 0; m_bUseAddScoreAnim = false; @@ -413,19 +411,16 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void ) m_bStopWatch = false; m_bAwaitingReadyRestart = false; - if ( IsInTournamentMode() ) + if ( IsInTournamentMode() == true ) { m_bAwaitingReadyRestart = true; } - m_flAutoBalanceQueueTimeEnd = -1.0f; + m_flAutoBalanceQueueTimeEnd = -1; m_nAutoBalanceQueuePlayerIndex = -1; m_nAutoBalanceQueuePlayerScore = -1; SetDefLessFunc( m_GameTeams ); - m_bCheatsEnabledDuringLevel = false; - - ResetPlayerAndTeamReadyState(); #endif } @@ -556,18 +551,6 @@ float CTeamplayRoundBasedRules::GetMinTimeWhenPlayerMaySpawn( CBasePlayer *pPlay return pPlayer->GetDeathTime() + fMinDelay; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTeamplayRoundBasedRules::LevelInitPostEntity( void ) -{ - BaseClass::LevelInitPostEntity(); - -#ifdef GAME_DLL - m_bCheatsEnabledDuringLevel = sv_cheats && sv_cheats->GetBool(); -#endif // GAME_DLL -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -582,22 +565,6 @@ float CTeamplayRoundBasedRules::GetRespawnTimeScalar( int iTeam ) return flScale; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTeamplayRoundBasedRules::FireGameEvent( IGameEvent * event ) -{ -#ifdef GAME_DLL - const char *eventName = event->GetName(); - if ( g_fGameOver && !Q_strcmp( eventName, "server_changelevel_failed" ) ) - { - Warning( "In gameover, but failed to load the next map. Trying next map in cycle.\n" ); - nextlevel.SetValue( "" ); - ChangeLevel(); - } -#endif -} - #ifdef GAME_DLL //----------------------------------------------------------------------------- // Purpose: @@ -634,7 +601,7 @@ void CTeamplayRoundBasedRules::Think( void ) // Don't run this code again m_flIntermissionEndTime = 0.f; - } + } return; } @@ -664,12 +631,6 @@ void CTeamplayRoundBasedRules::Think( void ) m_flNextPeriodicThink = gpGlobals->curtime + 1.0; } - // Watch dog for cheats ever being enabled during a level - if ( !m_bCheatsEnabledDuringLevel && sv_cheats && sv_cheats->GetBool() ) - { - m_bCheatsEnabledDuringLevel = true; - } - // Bypass teamplay think. CGameRules::Think(); } @@ -871,14 +832,7 @@ void CTeamplayRoundBasedRules::CheckWaitingForPlayers( void ) mp_waitingforplayers_restart.SetValue( 0 ); } - bool bCancelWait = ( mp_waitingforplayers_cancel.GetBool() || IsInItemTestingMode() ) && !IsInTournamentMode(); - -#if defined( _DEBUG ) || defined( STAGING_ONLY ) - if ( mp_developer.GetBool() ) - bCancelWait = true; -#endif // _DEBUG || STAGING_ONLY - - if ( bCancelWait ) + if( (mp_waitingforplayers_cancel.GetBool() || IsInItemTestingMode()) && IsInTournamentMode() == false ) { // Cancel the wait period and manually Resume() the timer if // it's not supposed to start paused at the beginning of a round. @@ -1000,7 +954,7 @@ void CTeamplayRoundBasedRules::CheckRestartRound( void ) int iDelayMax = 60; #if defined(TF_CLIENT_DLL) || defined(TF_DLL) - if ( TFGameRules() && ( TFGameRules()->IsMannVsMachineMode() || TFGameRules()->IsCompetitiveMode() ) ) + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { iDelayMax = 180; } @@ -1089,7 +1043,7 @@ void CTeamplayRoundBasedRules::CheckRestartRound( void ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::CheckTimeLimit( bool bAllowEnd /*= true*/ ) +bool CTeamplayRoundBasedRules::CheckTimeLimit( void ) { if ( IsInPreMatch() == true ) return false; @@ -1116,21 +1070,18 @@ bool CTeamplayRoundBasedRules::CheckTimeLimit( bool bAllowEnd /*= true*/ ) bSwitchDueToTime = false; } - if ( GetTimeLeft() <= 0 || m_bChangelevelAfterStalemate || bSwitchDueToTime ) + if( GetTimeLeft() <= 0 || m_bChangelevelAfterStalemate || bSwitchDueToTime ) { - if ( bAllowEnd ) + IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); + if ( event ) { - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); - if ( event ) - { - event->SetString( "reason", "Reached Time Limit" ); - gameeventmanager->FireEvent( event ); - } + event->SetString( "reason", "Reached Time Limit" ); + gameeventmanager->FireEvent( event ); + } - SendTeamScoresEvent(); + SendTeamScoresEvent(); - GoToIntermission(); - } + GoToIntermission(); return true; } } @@ -1169,23 +1120,20 @@ int CTeamplayRoundBasedRules::GetTimeLeft( void ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::CheckNextLevelCvar( bool bAllowEnd /*= true*/ ) +bool CTeamplayRoundBasedRules::CheckNextLevelCvar( void ) { if ( m_bForceMapReset ) { - if ( nextlevel.GetString() && *nextlevel.GetString() ) + if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) ) { - if ( bAllowEnd ) + IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); + if ( event ) { - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); - if ( event ) - { - event->SetString( "reason", "NextLevel CVAR" ); - gameeventmanager->FireEvent( event ); - } - - GoToIntermission(); + event->SetString( "reason", "NextLevel CVAR" ); + gameeventmanager->FireEvent( event ); } + + GoToIntermission(); return true; } } @@ -1196,7 +1144,7 @@ bool CTeamplayRoundBasedRules::CheckNextLevelCvar( bool bAllowEnd /*= true*/ ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::CheckWinLimit( bool bAllowEnd /*= true*/ ) +bool CTeamplayRoundBasedRules::CheckWinLimit( void ) { // has one team won the specified number of rounds? int iWinLimit = mp_winlimit.GetInt(); @@ -1210,17 +1158,14 @@ bool CTeamplayRoundBasedRules::CheckWinLimit( bool bAllowEnd /*= true*/ ) if ( pTeam->GetScore() >= iWinLimit ) { - if ( bAllowEnd ) + IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); + if ( event ) { - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); - if ( event ) - { - event->SetString( "reason", "Reached Win Limit" ); - gameeventmanager->FireEvent( event ); - } - - GoToIntermission(); + event->SetString( "reason", "Reached Win Limit" ); + gameeventmanager->FireEvent( event ); } + + GoToIntermission(); return true; } } @@ -1232,23 +1177,20 @@ bool CTeamplayRoundBasedRules::CheckWinLimit( bool bAllowEnd /*= true*/ ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::CheckMaxRounds( bool bAllowEnd /*= true*/ ) +bool CTeamplayRoundBasedRules::CheckMaxRounds() { if ( mp_maxrounds.GetInt() > 0 && IsInPreMatch() == false ) { if ( m_nRoundsPlayed >= mp_maxrounds.GetInt() ) { - if ( bAllowEnd ) + IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); + if ( event ) { - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" ); - if ( event ) - { - event->SetString( "reason", "Reached Round Limit" ); - gameeventmanager->FireEvent( event ); - } - - GoToIntermission(); + event->SetString( "reason", "Reached Round Limit" ); + gameeventmanager->FireEvent( event ); } + + GoToIntermission(); return true; } } @@ -1468,16 +1410,10 @@ void CTeamplayRoundBasedRules::State_Enter_PREROUND( void ) m_flStateTransitionTime = gpGlobals->curtime + tf_arena_preround_time.GetInt(); } #if defined(TF_CLIENT_DLL) || defined(TF_DLL) - // Only allow at the very beginning of the game, or between waves in mvm - else if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() && m_bAllowBetweenRounds ) + else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { State_Transition( GR_STATE_BETWEEN_RNDS ); - m_bAllowBetweenRounds = false; - - if ( TFGameRules()->IsMannVsMachineMode() ) - { - TFObjectiveResource()->SetMannVsMachineBetweenWaves( true ); - } + TFObjectiveResource()->SetMannVsMachineBetweenWaves( true ); } #endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL) else @@ -1560,33 +1496,19 @@ void CTeamplayRoundBasedRules::State_Enter_RND_RUNNING( void ) void CTeamplayRoundBasedRules::CheckReadyRestart( void ) { // check round restart - if ( m_flRestartRoundTime > 0 && m_flRestartRoundTime <= gpGlobals->curtime && !g_pServerBenchmark->IsBenchmarkRunning() ) + if( m_flRestartRoundTime > 0 && m_flRestartRoundTime <= gpGlobals->curtime && !g_pServerBenchmark->IsBenchmarkRunning() ) { m_flRestartRoundTime = -1; #ifdef TF_DLL - if ( TFGameRules() ) + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager ) { - if ( TFGameRules()->IsMannVsMachineMode() ) - { - if ( g_pPopulationManager && TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() ) - { - g_pPopulationManager->StartCurrentWave(); - m_bAllowBetweenRounds = true; - return; - } - } - else if ( TFGameRules()->IsCompetitiveMode() ) - { - TFGameRules()->StartCompetitiveMatch(); - return; - } - else if ( mp_tournament.GetBool() ) + if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() ) { - // Temp - TFGameRules()->StartCompetitiveMatch(); - return; + g_pPopulationManager->StartCurrentWave(); } + + return; } #endif // TF_DLL @@ -1594,28 +1516,34 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void ) State_Transition( GR_STATE_RESTART ); } - bool bProcessReadyRestart = m_bAwaitingReadyRestart; - -#ifdef TF_DLL - bProcessReadyRestart &= TFGameRules() && !TFGameRules()->UsePlayerReadyStatusMode(); -#endif // TF_DLL - // check ready restart - if ( bProcessReadyRestart ) + if( m_bAwaitingReadyRestart ) { - bool bTeamNotReady = false; - for ( int i = LAST_SHARED_TEAM + 1; i < GetNumberOfTeams(); i++ ) + int nTime = 5; + bool bTeamReady = false; + +#ifdef TF_DLL + if ( TFGameRules() ) { - if ( !m_bTeamReady[i] ) + if ( TFGameRules()->IsMannVsMachineMode() ) { - bTeamNotReady = true; - break; + bTeamReady = AreDefendingPlayersReady(); + if ( bTeamReady ) + { + nTime = 10; + } + } + else + { + bTeamReady = m_bTeamReady[TF_TEAM_BLUE] && m_bTeamReady[TF_TEAM_RED]; } } +#endif // TF_DLL - if ( !bTeamNotReady ) + if ( bTeamReady ) { - mp_restartgame.SetValue( 5 ); + //State_Transition( GR_STATE_RESTART ); + mp_restartgame.SetValue( nTime ); m_bAwaitingReadyRestart = false; ShouldResetScores( true, true ); @@ -1628,31 +1556,31 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::AreLobbyPlayersOnTeamReady( int iTeam ) +bool CTeamplayRoundBasedRules::AreDefendingPlayersReady() { - if ( !TFGameRules() ) - return false; - - if ( TFGameRules()->IsMannVsMachineMode() && iTeam == TF_TEAM_PVE_INVADERS ) - return true; + // Get list of defenders + CUtlVector vecMvMDefenders; + GetMvMPotentialDefendersLobbyPlayerInfo( vecMvMDefenders ); + // Scan all the players, and bail as soon as we find one person + // worth waiting for bool bAtLeastOnePersonReady = false; - - CUtlVector vecLobbyPlayers; - GetPotentialPlayersLobbyPlayerInfo( vecLobbyPlayers ); - - for ( int i = 0; i < vecLobbyPlayers.Count(); i++ ) + for ( int i = 0; i < vecMvMDefenders.Count(); i++ ) { - const LobbyPlayerInfo_t &p = vecLobbyPlayers[i]; - - // Make sure all lobby players are connected - if ( !AreLobbyPlayersConnected() ) + + // Are they on the red team? + const LobbyPlayerInfo_t &p = vecMvMDefenders[i]; + if ( !p.m_bConnected || p.m_iTeam == TEAM_UNASSIGNED || p.m_nEntNum <= 0 || p.m_nEntNum >= MAX_PLAYERS ) { - return false; + // They're still getting set up. We'll wait for them, + // but only if they are in the lobby + if ( p.m_bInLobby ) + return false; } - // All are connected, make sure their team is ready - else if ( p.m_iTeam == iTeam ) + else if ( p.m_iTeam == TF_TEAM_PVE_DEFENDERS ) { + + // If he isn't ready, then we aren't ready if ( !m_bPlayerReady[ p.m_nEntNum ] ) return false; @@ -1661,12 +1589,8 @@ bool CTeamplayRoundBasedRules::AreLobbyPlayersOnTeamReady( int iTeam ) } else { - // In MvM, only the red team should pass through here - if ( TFGameRules()->IsMannVsMachineMode() ) - { - // And you may ask yourself, "How did I get here?" - Assert( p.m_iTeam == iTeam ); - } + // And you may ask yourself, "How did I get here?" + Assert( p.m_iTeam == TF_TEAM_PVE_DEFENDERS ); } } @@ -1675,32 +1599,6 @@ bool CTeamplayRoundBasedRules::AreLobbyPlayersOnTeamReady( int iTeam ) return bAtLeastOnePersonReady; } -//----------------------------------------------------------------------------- -// Purpose: Is everyone in the lobby connected to the server? -//----------------------------------------------------------------------------- -bool CTeamplayRoundBasedRules::AreLobbyPlayersConnected( void ) -{ - CUtlVector vecLobbyPlayers; - GetPotentialPlayersLobbyPlayerInfo( vecLobbyPlayers ); - - // If you're calling this, you should have lobby members - Assert( vecLobbyPlayers.Count() ); - - for ( int i = 0; i < vecLobbyPlayers.Count(); i++ ) - { - const LobbyPlayerInfo_t &pLobbyPlayer = vecLobbyPlayers[i]; - if ( !pLobbyPlayer.m_bConnected || - pLobbyPlayer.m_nEntNum <= 0 || - pLobbyPlayer.m_nEntNum >= MAX_PLAYERS || - ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && pLobbyPlayer.m_iTeam == TEAM_UNASSIGNED ) ) - { - if ( pLobbyPlayer.m_bInLobby ) - return false; - } - } - - return true; -} #endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL) //----------------------------------------------------------------------------- @@ -1719,15 +1617,6 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void ) } #endif -#ifdef TF_DLL - // Mass time-out? Clean everything up. - if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() ) - { - TFGameRules()->EndCompetitiveMatch(); - return; - } -#endif // TF_DLL - State_Transition( GR_STATE_PREGAME ); return; } @@ -1743,8 +1632,9 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void ) // check round restart CheckReadyRestart(); + // See if we're coming up to the server timelimit, in which case force a stalemate immediately. - if ( mp_timelimit.GetInt() > 0 && IsInPreMatch() == false && GetTimeLeft() <= 0 ) + if ( State_Get() == GR_STATE_RND_RUNNING && mp_timelimit.GetInt() > 0 && IsInPreMatch() == false && GetTimeLeft() <= 0 ) { if ( m_bAllowStalemateAtTimelimit || ( mp_match_end_at_timelimit.GetBool() && !IsValveMap() ) ) { @@ -1800,7 +1690,9 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void ) //----------------------------------------------------------------------------- void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void ) { - m_flStateTransitionTime = gpGlobals->curtime + GetBonusRoundTime(); + float flTime = GetBonusRoundTime(); + + m_flStateTransitionTime = gpGlobals->curtime + flTime; // if we're forcing the map to reset it must be the end of a "full" round not a mini-round if ( m_bForceMapReset ) @@ -1811,15 +1703,6 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void ) InternalHandleTeamWin( m_iWinningTeam ); SendWinPanelInfo(); - -#ifdef TF_DLL - // Do this now, so players don't leave before the usual CheckWinLimit() call happens - bool bDone = ( CheckTimeLimit( false ) || CheckWinLimit( false ) || CheckMaxRounds( false ) || CheckNextLevelCvar( false ) ); - if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() && bDone ) - { - TFGameRules()->StopCompetitiveMatch( CMsgGC_Match_Result_Status_MATCH_SUCCEEDED ); - } -#endif // TF_DLL } //----------------------------------------------------------------------------- @@ -1827,20 +1710,12 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void ) //----------------------------------------------------------------------------- void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void ) { - if ( gpGlobals->curtime > m_flStateTransitionTime ) + if( gpGlobals->curtime > m_flStateTransitionTime ) { -#ifdef TF_DLL - IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_update" ); - if ( event ) - { - gameeventmanager->FireEvent( event ); - } -#endif // TF_DLL - - bool bDone = ( CheckTimeLimit() || CheckWinLimit() || CheckMaxRounds() || CheckNextLevelCvar() ); + bool bDone = !(!CheckTimeLimit() && !CheckWinLimit() && !CheckMaxRounds() && !CheckNextLevelCvar()); // check the win limit, max rounds, time limit and nextlevel cvar before starting the next round - if ( !bDone ) + if ( bDone == false ) { PreviousRoundEnd(); @@ -1861,7 +1736,7 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void ) State_Transition( GR_STATE_PREROUND ); } } - else if ( IsInTournamentMode() ) + else if ( IsInTournamentMode() == true ) { for ( int i = 1; i <= MAX_PLAYERS; i++ ) { @@ -1875,7 +1750,7 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void ) RestartTournament(); - if ( IsInArenaMode() ) + if ( IsInArenaMode() == true ) { #if defined( REPLAY_ENABLED ) if ( g_pReplay ) @@ -1887,43 +1762,33 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void ) State_Transition( GR_STATE_PREROUND ); } -#ifdef TF_DLL - else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager ) + else { - // one of the convars mp_timelimit, mp_winlimit, mp_maxrounds, or nextlevel has been triggered - for ( int i = 1; i <= MAX_PLAYERS; i++ ) +#ifdef TF_DLL + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { - CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); - if ( !pPlayer ) - continue; + // one of the convars mp_timelimit, mp_winlimit, mp_maxrounds, or nextlevel has been triggered + if ( g_pPopulationManager ) + { + for ( int i = 1; i <= MAX_PLAYERS; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); - pPlayer->AddFlag( FL_FROZEN ); - } + if ( !pPlayer ) + continue; - g_fGameOver = true; - g_pPopulationManager->SetMapRestartTime( gpGlobals->curtime + 10.0f ); - State_Enter( GR_STATE_GAME_OVER ); - return; - } - else if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() ) - { - for ( int i = 1; i <= MAX_PLAYERS; i++ ) - { - CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); - if ( !pPlayer ) - continue; + pPlayer->AddFlag( FL_FROZEN ); + pPlayer->ShowViewPortPanel( PANEL_SCOREBOARD ); + } - pPlayer->AddFlag( FL_FROZEN ); + g_fGameOver = true; + g_pPopulationManager->SetMapRestartTime( gpGlobals->curtime + 10.0f ); + State_Enter( GR_STATE_GAME_OVER ); + return; + } } - g_fGameOver = true; - State_Enter( GR_STATE_GAME_OVER ); - m_flStateTransitionTime = gpGlobals->curtime + GetBonusRoundTime( true ); - return; - } #endif // TF_DLL - else - { State_Transition( GR_STATE_RND_RUNNING ); } } @@ -2254,7 +2119,7 @@ int TeamScoreSort( CTeam* const *pTeam1, CTeam* const *pTeam2 ) //----------------------------------------------------------------------------- // Purpose: Input for other entities to declare a round winner. //----------------------------------------------------------------------------- -void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bForceMapReset /* = true */, bool bSwitchTeams /* = false*/, bool bDontAddScore /* = false*/, bool bFinal /*= false*/ ) +void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bForceMapReset /* = true */, bool bSwitchTeams /* = false*/, bool bDontAddScore /* = false*/ ) { // Commentary doesn't let anyone win if ( IsInCommentaryMode() ) @@ -2298,8 +2163,6 @@ void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bF State_Transition( GR_STATE_TEAM_WIN ); - m_flLastTeamWin = gpGlobals->curtime; - IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_round_win" ); if ( event ) { @@ -2514,10 +2377,6 @@ void CTeamplayRoundBasedRules::RestartTournament( void ) m_flStopWatchTotalTime = -1.0f; m_bStopWatch = false; - // we might have had a stalemate during the last round - // so reset this bool each time we restart the tournament - m_bChangelevelAfterStalemate = false; - for ( int i = 0; i < MAX_TEAMS; i++ ) { m_bTeamReady.Set( i, false ); @@ -2659,30 +2518,6 @@ void CTeamplayRoundBasedRules::HandleTimeLimitChange( void ) } } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTeamplayRoundBasedRules::ResetPlayerAndTeamReadyState( void ) -{ - for ( int i = 0; i < MAX_TEAMS; i++ ) - { - m_bTeamReady.Set( i, false ); - } - - for ( int i = 0; i < MAX_PLAYERS; i++ ) - { - m_bPlayerReady.Set( i, false ); - } - -#ifdef GAME_DLL - // Note <= MAX_PLAYERS vs < MAX_PLAYERS above - for ( int i = 0; i <= MAX_PLAYERS; i++ ) - { - m_bPlayerReadyBefore[i] = false; - } -#endif // GAME_DLL -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -2710,12 +2545,6 @@ void CTeamplayRoundBasedRules::CreateTimeLimitTimer( void ) if ( IsInArenaMode () == true || IsInKothMode() == true ) return; - // this is the same check we use in State_Think_RND_RUNNING() - // don't show the timelimit timer if we're not going to end the map when it runs out - bool bAllowStalemate = ( m_bAllowStalemateAtTimelimit || ( mp_match_end_at_timelimit.GetBool() && !IsValveMap() ) ); - if ( !bAllowStalemate ) - return; - #ifndef CSTRIKE_DLL if ( !m_hTimeLimitTimer ) { @@ -2803,10 +2632,6 @@ void CTeamplayRoundBasedRules::RoundRespawn( void ) } #endif - // Free any edicts that were marked deleted. This should hopefully clear some out - // so the below function can use the now freed ones. - engine->AllowImmediateEdictReuse(); - RespawnPlayers( true ); // reset per-round scores for each player @@ -2996,11 +2821,6 @@ void CTeamplayRoundBasedRules::BalanceTeams( bool bRequireSwitcheesToBeDead ) return; } -#if defined( _DEBUG ) || defined( STAGING_ONLY ) - if ( mp_developer.GetBool() ) - return; -#endif // _DEBUG || STAGING_ONLY - if ( IsInTraining() || IsInItemTestingMode() ) { return; @@ -3200,14 +3020,6 @@ void CTeamplayRoundBasedRules::ResetScores( void ) m_bResetPlayerScores = true; m_bResetRoundsPlayed = true; //m_flStopWatchTime = -1.0f; - -#ifdef TF_DLL - IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_reset" ); - if ( event ) - { - gameeventmanager->FireEvent( event ); - } -#endif // TF_DLL } //----------------------------------------------------------------------------- @@ -3429,12 +3241,9 @@ bool CTeamplayRoundBasedRules::IsInHighlanderMode( void ) #endif } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CTeamplayRoundBasedRules::GetBonusRoundTime( bool bFinal /*= false*/ ) +int CTeamplayRoundBasedRules::GetBonusRoundTime( void ) { - return bFinal ? mp_bonusroundtime_final.GetInt() : Max( 5, mp_bonusroundtime.GetInt() ); + return MAX( 5, mp_bonusroundtime.GetFloat() ); } //----------------------------------------------------------------------------- @@ -3448,11 +3257,6 @@ bool CTeamplayRoundBasedRules::ShouldBalanceTeams( void ) if ( IsInTraining() == true || IsInItemTestingMode() ) return false; -#if defined( _DEBUG ) || defined( STAGING_ONLY ) - if ( mp_developer.GetBool() ) - return false; -#endif // _DEBUG || STAGING_ONLY - if ( mp_teams_unbalance_limit.GetInt() <= 0 ) return false; @@ -3472,11 +3276,6 @@ bool CTeamplayRoundBasedRules::WouldChangeUnbalanceTeams( int iNewTeam, int iCur if ( ShouldBalanceTeams() == false ) return false; -#if defined( _DEBUG ) || defined( STAGING_ONLY ) - if ( mp_developer.GetBool() ) - return false; -#endif // _DEBUG || STAGING_ONLY - // if they are joining a non-playing team, allow if ( iNewTeam < FIRST_GAME_TEAM ) return false; @@ -3652,30 +3451,25 @@ void CTeamplayRoundBasedRules::ResetTeamsRoundWinTracking( void ) //----------------------------------------------------------------------------- // Purpose: Are you now, or are you ever going to be, a member of the defending party? //----------------------------------------------------------------------------- -void CTeamplayRoundBasedRules::GetPotentialPlayersLobbyPlayerInfo( CUtlVector &vecLobbyPlayers, bool bIncludeBots /*= false*/ ) +void CTeamplayRoundBasedRules::GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector &vecMvMDefenders, bool bIncludeBots /*= false*/ ) { - GetAllPlayersLobbyInfo( vecLobbyPlayers, bIncludeBots ); + GetAllPlayersLobbyInfo( vecMvMDefenders, bIncludeBots ); // Now scan through and remove the spectators - for ( int i = vecLobbyPlayers.Count() - 1; i >= 0; --i ) + for (int i = vecMvMDefenders.Count() - 1 ; i >= 0 ; --i ) { - switch ( vecLobbyPlayers[i].m_iTeam ) + switch ( vecMvMDefenders[i].m_iTeam ) { case TEAM_UNASSIGNED: - case TF_TEAM_RED: - break; - - case TF_TEAM_BLUE: - if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) - vecLobbyPlayers.FastRemove( i ); + case TF_TEAM_PVE_DEFENDERS: break; + default: + AssertMsg1( false, "Bogus team %d", vecMvMDefenders[i].m_iTeam ); + case TF_TEAM_PVE_INVADERS: case TEAM_SPECTATOR: - vecLobbyPlayers.FastRemove( i ); + vecMvMDefenders.FastRemove( i ); break; - - default: - AssertMsg1( false, "Bogus team %d", vecLobbyPlayers[i].m_iTeam ); } } } diff --git a/game/shared/teamplayroundbased_gamerules.h b/game/shared/teamplayroundbased_gamerules.h index 95060d3d..cf584092 100644 --- a/game/shared/teamplayroundbased_gamerules.h +++ b/game/shared/teamplayroundbased_gamerules.h @@ -12,7 +12,6 @@ #include "teamplay_gamerules.h" #include "teamplay_round_timer.h" -#include "GameEventListener.h" #ifdef GAME_DLL #include "team_control_point.h" @@ -89,11 +88,6 @@ enum { WINREASON_TIMELIMIT, WINREASON_WINLIMIT, WINREASON_WINDIFFLIMIT, -#if defined(TF_CLIENT_DLL) || defined(TF_DLL) - WINREASON_RD_REACTOR_CAPTURED, - WINREASON_RD_CORES_COLLECTED, - WINREASON_RD_REACTOR_RETURNED, -#endif }; enum stalemate_reasons_t @@ -163,7 +157,7 @@ class CTeamplayRoundBasedRulesProxy : public CGameRulesProxy //----------------------------------------------------------------------------- // Purpose: Teamplay game rules that manage a round based structure for you //----------------------------------------------------------------------------- -class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListener +class CTeamplayRoundBasedRules : public CTeamplayRules { DECLARE_CLASS( CTeamplayRoundBasedRules, CTeamplayRules ); public: @@ -189,7 +183,6 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene virtual float GetNextRespawnWave( int iTeam, CBasePlayer *pPlayer ); virtual bool HasPassedMinRespawnTime( CBasePlayer *pPlayer ); - virtual void LevelInitPostEntity( void ); virtual float GetRespawnTimeScalar( int iTeam ); virtual float GetRespawnWaveMaxLength( int iTeam, bool bScaleWithNumPlayers = true ); virtual bool ShouldRespawnQuickly( CBasePlayer *pPlayer ) { return false; } @@ -249,7 +242,7 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene void SetMultipleTrains( bool bMultipleTrains ){ m_bMultipleTrains = bMultipleTrains; } bool HasMultipleTrains( void ){ return m_bMultipleTrains; } - virtual int GetBonusRoundTime( bool bFinal = false ); + virtual int GetBonusRoundTime( void ); #if defined(TF_CLIENT_DLL) || defined(TF_DLL) @@ -259,15 +252,10 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene // Get list of players who are on the defending team now, or are likely // to end up on the defending team (not yet connected or assigned a team) - void GetPotentialPlayersLobbyPlayerInfo( CUtlVector &vecLobbyPlayers, bool bIncludeBots = false ); + void GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector &vecMvmDefenders, bool bIncludeBots = false ); #endif - void SetAllowBetweenRounds( bool bValue ) { m_bAllowBetweenRounds = bValue; } - -public: // IGameEventListener Interface - virtual void FireGameEvent( IGameEvent * event ); - //---------------------------------------------------------------------------------- // Server specific #ifdef GAME_DLL @@ -315,7 +303,7 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene virtual bool ShouldScorePerRound( void ){ return true; } - bool CheckNextLevelCvar( bool bAllowEnd = true ); + bool CheckNextLevelCvar( void ); virtual bool TimerMayExpire( void ); @@ -338,7 +326,7 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene bool IsPreviouslyPlayedRound ( string_t strName ); string_t GetLastPlayedRound( void ); - virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false, bool bFinal = false ) OVERRIDE; + virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false ); virtual void SetStalemate( int iReason, bool bForceMapReset = true, bool bSwitchTeams = false ); virtual void SetRoundOverlayDetails( void ){ return; } @@ -371,11 +359,10 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene { m_bPlayerReady.Set( iIndex, bState ); } - void ResetPlayerAndTeamReadyState( void ); virtual void PlayTrainCaptureAlert( CTeamControlPoint *pPoint, bool bFinalPointInMap ){ return; } - virtual void PlaySpecialCapSounds( int iCappingTeam, CTeamControlPoint *pPoint ){ return; } + virtual void PlaySpecialCapSounds( int iCappingTeam ){ return; } bool PlayThrottledAlert( int iTeam, const char *sound, float fDelayBeforeNext ); @@ -400,15 +387,14 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene void CheckWaitingForPlayers( void ); virtual bool AllowWaitingForPlayers( void ) { return true; } void CheckRestartRound( void ); - bool CheckTimeLimit( bool bAllowEnd = true ); + bool CheckTimeLimit( void ); int GetTimeLeft( void ); - virtual bool CheckWinLimit( bool bAllowEnd = true ); - bool CheckMaxRounds( bool bAllowEnd = true ); + virtual bool CheckWinLimit( void ); + bool CheckMaxRounds( void ); void CheckReadyRestart( void ); #if defined(TF_CLIENT_DLL) || defined(TF_DLL) - bool AreLobbyPlayersOnTeamReady( int iTeam ); - bool AreLobbyPlayersConnected( void ); + bool AreDefendingPlayersReady(); #endif virtual bool CanChangelevelBecauseOfTimeLimit( void ) { return true; } @@ -487,8 +473,6 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene bool MapHasActiveTimer( void ); void CreateTimeLimitTimer( void ); - virtual float GetLastMajorEventTime( void ) OVERRIDE { return m_flLastTeamWin; } - protected: CGameRulesRoundStateInfo *m_pCurStateInfo; // Per-state data float m_flStateTransitionTime; // Timer for round states @@ -531,13 +515,10 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene gamerules_roundstate_t m_prevState; - bool m_bPlayerReadyBefore[MAX_PLAYERS+1]; // Test to see if a player has hit ready before - - float m_flLastTeamWin; - private: CUtlMap < int, int > m_GameTeams; // Team index, Score + #endif // End server specific //---------------------------------------------------------------------------------- @@ -560,7 +541,6 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene public: bool WouldChangeUnbalanceTeams( int iNewTeam, int iCurrentTeam ); bool AreTeamsUnbalanced( int &iHeaviestTeam, int &iLightestTeam ); - virtual bool HaveCheatsBeenEnabledDuringLevel( void ) { return m_bCheatsEnabledDuringLevel; } protected: CNetworkVar( gamerules_roundstate_t, m_iRoundState ); @@ -577,11 +557,10 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene CNetworkVar( float, m_flMapResetTime ); // Time that the map was reset CNetworkArray( float, m_flNextRespawnWave, MAX_TEAMS ); // Minor waste, but cleaner code CNetworkArray( bool, m_bTeamReady, MAX_TEAMS ); - CNetworkVar( bool, m_bStopWatch ); - CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map? + CNetworkVar( bool, m_bStopWatch ); + CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map? CNetworkArray( bool, m_bPlayerReady, MAX_PLAYERS ); - CNetworkVar( bool, m_bCheatsEnabledDuringLevel ); - + public: CNetworkArray( float, m_TeamRespawnWaveTimes, MAX_TEAMS ); // Time between each team's respawn wave @@ -595,9 +574,6 @@ class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListene int m_nAutoBalanceQueuePlayerIndex; int m_nAutoBalanceQueuePlayerScore; -protected: - bool m_bAllowBetweenRounds; - public: float m_flStopWatchTotalTime; diff --git a/game/shared/triggers_shared.h b/game/shared/triggers_shared.h deleted file mode 100644 index 1467ae93..00000000 --- a/game/shared/triggers_shared.h +++ /dev/null @@ -1,33 +0,0 @@ -//====== Copyright 1996-2005, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#ifndef TRIGGERS_SHARED_H -#define TRIGGERS_SHARED_H -#ifdef _WIN32 -#pragma once -#endif - -// -// Spawnflags -// -enum -{ - SF_TRIGGER_ALLOW_CLIENTS = 0x01, // Players can fire this trigger - SF_TRIGGER_ALLOW_NPCS = 0x02, // NPCS can fire this trigger - SF_TRIGGER_ALLOW_PUSHABLES = 0x04, // Pushables can fire this trigger - SF_TRIGGER_ALLOW_PHYSICS = 0x08, // Physics objects can fire this trigger - SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS = 0x10, // *if* NPCs can fire this trigger, this flag means only player allies do so - SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES = 0x20, // *if* Players can fire this trigger, this flag means only players inside vehicles can - SF_TRIGGER_ALLOW_ALL = 0x40, // Everything can fire this trigger EXCEPT DEBRIS! - SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES = 0x200, // *if* Players can fire this trigger, this flag means only players outside vehicles can - SF_TRIG_PUSH_ONCE = 0x80, // trigger_push removes itself after firing once - SF_TRIG_PUSH_AFFECT_PLAYER_ON_LADDER = 0x100, // if pushed object is player on a ladder, then this disengages them from the ladder (HL2only) - SF_TRIG_TOUCH_DEBRIS = 0x400, // Will touch physics debris objects - SF_TRIGGER_ONLY_NPCS_IN_VEHICLES = 0X800, // *if* NPCs can fire this trigger, only NPCs in vehicles do so (respects player ally flag too) - SF_TRIGGER_DISALLOW_BOTS = 0x1000, // Bots are not allowed to fire this trigger -}; - -#endif // TRIGGERS_SHARED_H diff --git a/game/shared/usercmd.cpp b/game/shared/usercmd.cpp index 84ffa243..1607eba3 100644 --- a/game/shared/usercmd.cpp +++ b/game/shared/usercmd.cpp @@ -10,12 +10,20 @@ #include "bitbuf.h" #include "checksum_md5.h" +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_singletons.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" // TF2 specific, need enough space for OBJ_LAST items from tf_shareddefs.h #define WEAPON_SUBTYPE_BITS 6 +#ifdef MAPBASE_VSCRIPT +extern CNetMsgScriptHelper *g_ScriptNetMsg; +#endif + //----------------------------------------------------------------------------- // Purpose: Write a delta compressed user command. // Input : *buf - @@ -187,6 +195,22 @@ void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from ) buf->WriteOneBit( 0 ); } #endif + +#if defined( MAPBASE_VSCRIPT ) && defined( CLIENT_DLL ) + Assert( g_ScriptNetMsg ); + + if ( g_ScriptNetMsg->m_bWriteReady ) + { + buf->WriteOneBit( 1 ); + g_ScriptNetMsg->WriteToBuffer( buf ); + g_ScriptNetMsg->m_bWriteReady = false; + } + else + { + buf->WriteOneBit( 0 ); + } +#endif + } //----------------------------------------------------------------------------- @@ -196,7 +220,11 @@ void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from ) // *from - // Output : static void ReadUsercmd //----------------------------------------------------------------------------- +#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL ) +void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from, CBaseEntity *pPlayer ) +#else void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from ) +#endif { // Assume no change *move = *from; @@ -303,4 +331,12 @@ void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from ) } } #endif + +#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL ) + if ( buf->ReadOneBit() ) + { + g_ScriptNetMsg->ReceiveMessage( buf, pPlayer ); + } +#endif + } diff --git a/game/shared/usercmd.h b/game/shared/usercmd.h index 0005bde9..04ff44ed 100644 --- a/game/shared/usercmd.h +++ b/game/shared/usercmd.h @@ -51,9 +51,6 @@ class CUserCmd weaponselect = 0; weaponsubtype = 0; random_seed = 0; -#ifdef GAME_DLL - server_random_seed = 0; -#endif mousedx = 0; mousedy = 0; @@ -79,9 +76,6 @@ class CUserCmd weaponselect = src.weaponselect; weaponsubtype = src.weaponsubtype; random_seed = src.random_seed; -#ifdef GAME_DLL - server_random_seed = src.server_random_seed; -#endif mousedx = src.mousedx; mousedy = src.mousedy; @@ -157,9 +151,6 @@ class CUserCmd int weaponsubtype; int random_seed; // For shared random functions -#ifdef GAME_DLL - int server_random_seed; // Only the server populates this seed -#endif short mousedx; // mouse accum in x from create move short mousedy; // mouse accum in y from create move @@ -174,7 +165,11 @@ class CUserCmd }; +#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL ) +void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from, CBaseEntity *pPlayer ); +#else void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from ); +#endif void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from ); #endif // USERCMD_H diff --git a/game/shared/usermessages.cpp b/game/shared/usermessages.cpp index cf1beae3..6b3ad681 100644 --- a/game/shared/usermessages.cpp +++ b/game/shared/usermessages.cpp @@ -13,6 +13,10 @@ void RegisterUserMessages( void ); +#ifdef MAPBASE +void RegisterMapbaseUserMessages( void ); +#endif + //----------------------------------------------------------------------------- // Purpose: Force registration on .dll load // FIXME: Should this be a client/server system? @@ -21,6 +25,11 @@ CUserMessages::CUserMessages() { // Game specific registration function; RegisterUserMessages(); + +#ifdef MAPBASE + // Mapbase registration function; + RegisterMapbaseUserMessages(); +#endif } CUserMessages::~CUserMessages() diff --git a/game/shared/util_shared.cpp b/game/shared/util_shared.cpp index de7aea4e..be44201d 100644 --- a/game/shared/util_shared.cpp +++ b/game/shared/util_shared.cpp @@ -39,7 +39,7 @@ bool NPC_CheckBrushExclude( CBaseEntity *pEntity, CBaseEntity *pBrush ); #include "tier0/memdbgon.h" ConVar r_visualizetraces( "r_visualizetraces", "0", FCVAR_CHEAT ); -ConVar developer("developer", "0", 0, "Set developer message level" ); // developer mode +ConVar developer("developer", "0", 0, "Set developer message level." ); // developer mode float UTIL_VecToYaw( const Vector &vec ) { @@ -219,6 +219,15 @@ bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *p if ( !pEntTouch || !pEntPass ) return true; +#ifdef MAPBASE + // don't clip against own missiles + if ( pEntTouch->GetOwnerEntity() == pEntPass && !pEntTouch->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER) ) + return false; + + // don't clip against owner + if ( pEntPass->GetOwnerEntity() == pEntTouch && !pEntPass->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER) ) + return false; +#else // don't clip against own missiles if ( pEntTouch->GetOwnerEntity() == pEntPass ) return false; @@ -226,6 +235,7 @@ bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *p // don't clip against owner if ( pEntPass->GetOwnerEntity() == pEntTouch ) return false; +#endif return true; @@ -986,6 +996,57 @@ void UTIL_StringToColor32( color32 *color, const char *pString ) color->a = tmp[3]; } +#ifdef MAPBASE +void UTIL_StringToFloatArray_PreserveArray( float *pVector, int count, const char *pString ) +{ + char *pstr, *pfront, tempString[128]; + int j; + + Q_strncpy( tempString, pString, sizeof(tempString) ); + pstr = pfront = tempString; + + for ( j = 0; j < count; j++ ) // lifted from pr_edict.c + { + pVector[j] = atof( pfront ); + + // skip any leading whitespace + while ( *pstr && *pstr <= ' ' ) + pstr++; + + // skip to next whitespace + while ( *pstr && *pstr > ' ' ) + pstr++; + + if (!*pstr) + break; + + pstr++; + pfront = pstr; + } +} + +void UTIL_StringToIntArray_PreserveArray( int *pVector, int count, const char *pString ) +{ + char *pstr, *pfront, tempString[128]; + int j; + + Q_strncpy( tempString, pString, sizeof(tempString) ); + pstr = pfront = tempString; + + for ( j = 0; j < count; j++ ) // lifted from pr_edict.c + { + pVector[j] = atoi( pfront ); + + while ( *pstr && *pstr != ' ' ) + pstr++; + if (!*pstr) + break; + pstr++; + pfront = pstr; + } +} +#endif + #ifndef _XBOX void UTIL_DecodeICE( unsigned char * buffer, int size, const unsigned char *key) { @@ -1065,7 +1126,7 @@ float CountdownTimer::Now( void ) const #endif -char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename ) +const char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename ) { const char *pValue = pSub->GetString( pName, NULL ); if ( !pValue ) @@ -1100,6 +1161,59 @@ int UTIL_StringFieldToInt( const char *szValue, const char **pValueStrings, int } +static char s_NumBitsInNibble[ 16 ] = +{ + 0, // 0000 = 0 + 1, // 0001 = 1 + 1, // 0010 = 2 + 2, // 0011 = 3 + 1, // 0100 = 4 + 2, // 0101 = 5 + 2, // 0110 = 6 + 3, // 0111 = 7 + 1, // 1000 = 8 + 2, // 1001 = 9 + 2, // 1010 = 10 + 3, // 1011 = 11 + 2, // 1100 = 12 + 3, // 1101 = 13 + 3, // 1110 = 14 + 4, // 1111 = 15 +}; + +int UTIL_CountNumBitsSet( unsigned int nVar ) +{ + int nNumBits = 0; + + while ( nVar > 0 ) + { + // Look up and add in bits in the bottom nibble + nNumBits += s_NumBitsInNibble[ nVar & 0x0f ]; + + // Shift one nibble to the right + nVar >>= 4; + } + + return nNumBits; +} + +int UTIL_CountNumBitsSet( uint64 nVar ) +{ + int nNumBits = 0; + + while ( nVar > 0 ) + { + // Look up and add in bits in the bottom nibble + nNumBits += s_NumBitsInNibble[ nVar & 0x0f ]; + + // Shift one nibble to the right + nVar >>= 4; + } + + return nNumBits; +} + + int find_day_of_week( struct tm& found_day, int day_of_week, int step ) { return 0; diff --git a/game/shared/util_shared.h b/game/shared/util_shared.h index 83793418..98f6ba4e 100644 --- a/game/shared/util_shared.h +++ b/game/shared/util_shared.h @@ -358,6 +358,14 @@ void UTIL_StringToIntArray( int *pVector, int count, const char *pString ); void UTIL_StringToFloatArray( float *pVector, int count, const char *pString ); void UTIL_StringToColor32( color32 *color, const char *pString ); +#ifdef MAPBASE +// Version of UTIL_StringToIntArray that doesn't set all untouched array elements to 0. +void UTIL_StringToIntArray_PreserveArray( int *pVector, int count, const char *pString ); + +// Version of UTIL_StringToFloatArray that doesn't set all untouched array elements to 0. +void UTIL_StringToFloatArray_PreserveArray( float *pVector, int count, const char *pString ); +#endif + CBasePlayer *UTIL_PlayerByIndex( int entindex ); //============================================================================= @@ -441,8 +449,8 @@ inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vec public: \ interfaceName( bool bAutoAdd = true ); \ virtual ~interfaceName(); \ - static void AddToAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \ - static void RemoveFromAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \ + static void Add( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \ + static void Remove( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \ static const CUtlVector< interfaceName* >& AutoList( void ) { return m_##interfaceName##AutoList; } \ private: \ static CUtlVector< interfaceName* > m_##interfaceName##AutoList; \ @@ -456,28 +464,14 @@ inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vec { \ if ( bAutoAdd ) \ { \ - AddToAutoList( this ); \ + Add( this ); \ } \ } \ interfaceName::~interfaceName() \ { \ - RemoveFromAutoList( this ); \ + Remove( this ); \ } -//-------------------------------------------------------------------------------------------------------------- -// This would do the same thing without requiring casts all over the place. Yes, it's a template, but -// DECLARE_AUTO_LIST requires a CUtlVector anyway. TODO ask about replacing the macros with this. -//template -//class AutoList { -//public: -// typedef CUtlVector AutoListType; -// static AutoListType& All() { return m_autolist; } -//protected: -// AutoList() { m_autolist.AddToTail(static_cast(this)); } -// virtual ~AutoList() { m_autolist.FindAndFastRemove(static_cast(this)); } -//private: -// static AutoListType m_autolist; -//}; //-------------------------------------------------------------------------------------------------------------- /** @@ -590,24 +584,35 @@ class CountdownTimer return (m_timestamp > 0.0f) ? m_duration : 0.0f; } + /// 1.0 for newly started, 0.0 for elapsed + float GetRemainingRatio( void ) const + { + if (HasStarted() && m_duration > 0.0f) + { + float left = GetRemainingTime() / m_duration; + if (left < 0.0f) + return 0.0f; + if (left > 1.0f) + return 1.0f; + return left; + } + + return 0.0f; + } + private: float m_duration; float m_timestamp; - virtual float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime -}; - -class RealTimeCountdownTimer : public CountdownTimer -{ - virtual float Now( void ) const OVERRIDE - { - return Plat_FloatTime(); - } + float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime }; -char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename = NULL ); +const char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename = NULL ); int UTIL_StringFieldToInt( const char *szValue, const char **pValueStrings, int iNumStrings ); +int UTIL_CountNumBitsSet( unsigned int nVar ); +int UTIL_CountNumBitsSet( uint64 nVar ); + //----------------------------------------------------------------------------- // Holidays //----------------------------------------------------------------------------- diff --git a/game/shared/vance/singleplayer_animstate.cpp b/game/shared/vance/singleplayer_animstate.cpp deleted file mode 100644 index 561e2d0d..00000000 --- a/game/shared/vance/singleplayer_animstate.cpp +++ /dev/null @@ -1,504 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Single Player animation state 'handler'. This utility is used -// to evaluate the pose parameter value based on the direction -// and speed of the player. -// -//====================================================================================// - -#include "cbase.h" -#include "singleplayer_animstate.h" -#include "tier0/vprof.h" -#include "animation.h" -#include "studio.h" -#include "apparent_velocity_helper.h" -#include "utldict.h" -#include "filesystem.h" -#include "..\public\datacache\imdlcache.h" - -extern ConVar mp_facefronttime, mp_feetyawrate, mp_ik; - -#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f - -CSinglePlayerAnimState *CreatePlayerAnimationState(CBasePlayer *pPlayer) -{ - MDLCACHE_CRITICAL_SECTION(); - - CSinglePlayerAnimState *pState = new CSinglePlayerAnimState(pPlayer); - pState->Init(pPlayer); - - return pState; -} - -// Below this many degrees, slow down turning rate linearly -#define FADE_TURN_DEGREES 45.0f -// After this, need to start turning feet -#define MAX_TORSO_ANGLE 90.0f -// Below this amount, don't play a turning animation/perform IK -#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f - -//static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." ); -extern ConVar sv_backspeed; -extern ConVar mp_feetyawrate; -extern ConVar mp_facefronttime; -extern ConVar mp_ik; - -CSinglePlayerAnimState::CSinglePlayerAnimState(CBasePlayer *pPlayer) : m_pPlayer(pPlayer) -{ - m_flGaitYaw = 0.0f; - m_flGoalFeetYaw = 0.0f; - m_flCurrentFeetYaw = 0.0f; - m_flCurrentTorsoYaw = 0.0f; - m_flLastYaw = 0.0f; - m_flLastTurnTime = 0.0f; - m_flTurnCorrectionTime = 0.0f; - - m_pPlayer = NULL; -}; - -void CSinglePlayerAnimState::Init(CBasePlayer *pPlayer) -{ - m_pPlayer = pPlayer; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::Update() -{ - m_angRender = GetBasePlayer()->GetLocalAngles(); - - ComputePoseParam_BodyYaw(); - ComputePoseParam_BodyPitch(GetBasePlayer()->GetModelPtr()); - ComputePoseParam_BodyLookYaw(); - ComputePoseParam_HeadPitch(GetBasePlayer()->GetModelPtr()); - - ComputePlaybackRate(); -} - -void CSinglePlayerAnimState::Release() -{ - delete this; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::ComputePlaybackRate() -{ - // Determine ideal playback rate - Vector vel; - GetOuterAbsVelocity(vel); - - float speed = vel.Length2D(); - - bool isMoving = (speed > 0.5f) ? true : false; - - float maxspeed = GetBasePlayer()->GetSequenceGroundSpeed(GetBasePlayer()->GetSequence()); - - if (isMoving && (maxspeed > 0.0f)) - { - float flFactor = 1.0f; - - // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below - GetBasePlayer()->SetPlaybackRate((speed * flFactor) / maxspeed); - - // BUG BUG: - // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed - } - else - { - GetBasePlayer()->SetPlaybackRate(1.0f); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : CBasePlayer -//----------------------------------------------------------------------------- -CBasePlayer *CSinglePlayerAnimState::GetBasePlayer() -{ - return m_pPlayer; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : dt - -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::EstimateYaw(void) -{ - float dt = gpGlobals->frametime; - - if (!dt) - { - return; - } - - Vector est_velocity; - QAngle angles; - - GetOuterAbsVelocity(est_velocity); - - angles = GetBasePlayer()->GetLocalAngles(); - - if (est_velocity[1] == 0 && est_velocity[0] == 0) - { - float flYawDiff = angles[YAW] - m_flGaitYaw; - flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; - if (flYawDiff > 180) - flYawDiff -= 360; - if (flYawDiff < -180) - flYawDiff += 360; - - if (dt < 0.25) - flYawDiff *= dt * 4; - else - flYawDiff *= dt; - - m_flGaitYaw += flYawDiff; - m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360; - } - else - { - m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); - - if (m_flGaitYaw > 180) - m_flGaitYaw = 180; - else if (m_flGaitYaw < -180) - m_flGaitYaw = -180; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Override for backpeddling -// Input : dt - -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::ComputePoseParam_BodyYaw(void) -{ - int iYaw = GetBasePlayer()->LookupPoseParameter("move_yaw"); - if (iYaw < 0) - return; - - // view direction relative to movement - float flYaw; - - EstimateYaw(); - - QAngle angles = GetBasePlayer()->GetLocalAngles(); - float ang = angles[YAW]; - if (ang > 180.0f) - { - ang -= 360.0f; - } - else if (ang < -180.0f) - { - ang += 360.0f; - } - - // calc side to side turning - flYaw = ang - m_flGaitYaw; - // Invert for mapping into 8way blend - flYaw = -flYaw; - flYaw = flYaw - (int)(flYaw / 360) * 360; - - if (flYaw < -180) - { - flYaw = flYaw + 360; - } - else if (flYaw > 180) - { - flYaw = flYaw - 360; - } - - GetBasePlayer()->SetPoseParameter(iYaw, flYaw); - -#ifndef CLIENT_DLL - //Adrian: Make the model's angle match the legs so the hitboxes match on both sides. - GetBasePlayer()->SetLocalAngles(QAngle(GetBasePlayer()->EyeAngles().x, m_flCurrentFeetYaw, 0)); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::ComputePoseParam_BodyPitch(CStudioHdr *pStudioHdr) -{ - // Get pitch from v_angle - float flPitch = GetBasePlayer()->GetLocalAngles()[PITCH]; - - if (flPitch > 180.0f) - { - flPitch -= 360.0f; - } - flPitch = clamp(flPitch, -90, 90); - - QAngle absangles = GetBasePlayer()->GetAbsAngles(); - absangles.x = 0.0f; - m_angRender = absangles; - - // See if we have a blender for pitch - GetBasePlayer()->SetPoseParameter(pStudioHdr, "aim_pitch", flPitch); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : goal - -// maxrate - -// dt - -// current - -// Output : int -//----------------------------------------------------------------------------- -int CSinglePlayerAnimState::ConvergeAngles(float goal, float maxrate, float dt, float& current) -{ - int direction = TURN_NONE; - - float anglediff = goal - current; - float anglediffabs = fabs(anglediff); - - anglediff = AngleNormalize(anglediff); - - float scale = 1.0f; - if (anglediffabs <= FADE_TURN_DEGREES) - { - scale = anglediffabs / FADE_TURN_DEGREES; - // Always do at least a bit of the turn ( 1% ) - scale = clamp(scale, 0.01f, 1.0f); - } - - float maxmove = maxrate * dt * scale; - - if (fabs(anglediff) < maxmove) - { - current = goal; - } - else - { - if (anglediff > 0) - { - current += maxmove; - direction = TURN_LEFT; - } - else - { - current -= maxmove; - direction = TURN_RIGHT; - } - } - - current = AngleNormalize(current); - - return direction; -} - -void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw(void) -{ - QAngle absangles = GetBasePlayer()->GetAbsAngles(); - absangles.y = AngleNormalize(absangles.y); - m_angRender = absangles; - - // See if we even have a blender for pitch - int upper_body_yaw = GetBasePlayer()->LookupPoseParameter("aim_yaw"); - if (upper_body_yaw < 0) - { - return; - } - - // Assume upper and lower bodies are aligned and that we're not turning - float flGoalTorsoYaw = 0.0f; - int turning = TURN_NONE; - float turnrate = 360.0f; - - Vector vel; - - GetOuterAbsVelocity(vel); - - bool isMoving = (vel.Length() > 1.0f) ? true : false; - - if (!isMoving) - { - // Just stopped moving, try and clamp feet - if (m_flLastTurnTime <= 0.0f) - { - m_flLastTurnTime = gpGlobals->curtime; - m_flLastYaw = GetBasePlayer()->EyeAngles().y; - // Snap feet to be perfectly aligned with torso/eyes - m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; - m_flCurrentFeetYaw = m_flGoalFeetYaw; - m_nTurningInPlace = TURN_NONE; - } - - // If rotating in place, update stasis timer - - if (m_flLastYaw != GetBasePlayer()->EyeAngles().y) - { - m_flLastTurnTime = gpGlobals->curtime; - m_flLastYaw = GetBasePlayer()->EyeAngles().y; - } - - if (m_flGoalFeetYaw != m_flCurrentFeetYaw) - { - m_flLastTurnTime = gpGlobals->curtime; - } - - turning = ConvergeAngles(m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw); - - QAngle eyeAngles = GetBasePlayer()->EyeAngles(); - QAngle vAngle = GetBasePlayer()->GetLocalAngles(); - - // See how far off current feetyaw is from true yaw - float yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw; - yawdelta = AngleNormalize(yawdelta); - - bool rotated_too_far = false; - - float yawmagnitude = fabs(yawdelta); - - // If too far, then need to turn in place - if (yawmagnitude > 45) - { - rotated_too_far = true; - } - - // Standing still for a while, rotate feet around to face forward - // Or rotated too far - // FIXME: Play an in place turning animation - if (rotated_too_far || - (gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat())) - { - m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; - m_flLastTurnTime = gpGlobals->curtime; - - /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw; - if ( yd > 0 ) - { - m_nTurningInPlace = TURN_RIGHT; - } - else if ( yd < 0 ) - { - m_nTurningInPlace = TURN_LEFT; - } - else - { - m_nTurningInPlace = TURN_NONE; - } - - turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); - yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw;*/ - - } - - // Snap upper body into position since the delta is already smoothed for the feet - flGoalTorsoYaw = yawdelta; - m_flCurrentTorsoYaw = flGoalTorsoYaw; - } - else - { - m_flLastTurnTime = 0.0f; - m_nTurningInPlace = TURN_NONE; - m_flCurrentFeetYaw = m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; - flGoalTorsoYaw = 0.0f; - m_flCurrentTorsoYaw = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw; - } - - if (turning == TURN_NONE) - { - m_nTurningInPlace = turning; - } - - if (m_nTurningInPlace != TURN_NONE) - { - // If we're close to finishing the turn, then turn off the turning animation - if (fabs(m_flCurrentFeetYaw - m_flGoalFeetYaw) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION) - { - m_nTurningInPlace = TURN_NONE; - } - } - - // Rotate entire body into position - absangles = GetBasePlayer()->GetAbsAngles(); - absangles.y = m_flCurrentFeetYaw; - m_angRender = absangles; - - GetBasePlayer()->SetPoseParameter(upper_body_yaw, clamp(m_flCurrentTorsoYaw, -60.0f, 60.0f)); - - /* - // FIXME: Adrian, what is this? - int body_yaw = GetBasePlayer()->LookupPoseParameter( "body_yaw" ); - - if ( body_yaw >= 0 ) - { - GetBasePlayer()->SetPoseParameter( body_yaw, 30 ); - } - */ - -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CSinglePlayerAnimState::ComputePoseParam_HeadPitch(CStudioHdr *pStudioHdr) -{ - // Get pitch from v_angle - int iHeadPitch = GetBasePlayer()->LookupPoseParameter("head_pitch"); - - float flPitch = GetBasePlayer()->EyeAngles()[PITCH]; - - if (flPitch > 180.0f) - { - flPitch -= 360.0f; - } - flPitch = clamp(flPitch, -90, 90); - - QAngle absangles = GetBasePlayer()->GetAbsAngles(); - absangles.x = 0.0f; - m_angRender = absangles; - - GetBasePlayer()->SetPoseParameter(pStudioHdr, iHeadPitch, flPitch); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : activity - -// Output : Activity -//----------------------------------------------------------------------------- -Activity CSinglePlayerAnimState::BodyYawTranslateActivity(Activity activity) -{ - // Not even standing still, sigh - if (activity != ACT_IDLE) - return activity; - - // Not turning - switch (m_nTurningInPlace) - { - default: - case TURN_NONE: - return activity; - /* - case TURN_RIGHT: - return ACT_TURNRIGHT45; - case TURN_LEFT: - return ACT_TURNLEFT45; - */ - case TURN_RIGHT: - case TURN_LEFT: - return mp_ik.GetBool() ? ACT_TURN : activity; - } - - Assert(0); - return activity; -} - -const QAngle& CSinglePlayerAnimState::GetRenderAngles() -{ - return m_angRender; -} - -void CSinglePlayerAnimState::GetOuterAbsVelocity(Vector& vel) -{ -#if defined( CLIENT_DLL ) - GetBasePlayer()->EstimateAbsVelocity(vel); -#else - vel = GetBasePlayer()->GetAbsVelocity(); -#endif -} \ No newline at end of file diff --git a/game/shared/vance/unused/singleplayer_animstate.cpp b/game/shared/vance/unused/singleplayer_animstate.cpp new file mode 100644 index 00000000..c763b7b8 --- /dev/null +++ b/game/shared/vance/unused/singleplayer_animstate.cpp @@ -0,0 +1,504 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Single Player animation state 'handler'. This utility is used +// to evaluate the pose parameter value based on the direction +// and speed of the player. +// +//====================================================================================// + +#include "cbase.h" +#include "singleplayer_animstate.h" +#include "tier0/vprof.h" +#include "animation.h" +#include "studio.h" +#include "apparent_velocity_helper.h" +#include "utldict.h" +#include "filesystem.h" +#include "datacache/imdlcache.h" + +extern ConVar mp_facefronttime, mp_feetyawrate, mp_ik; + +#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f + +CSinglePlayerAnimState *CreatePlayerAnimationState(CBasePlayer *pPlayer) +{ + MDLCACHE_CRITICAL_SECTION(); + + CSinglePlayerAnimState *pState = new CSinglePlayerAnimState(pPlayer); + pState->Init(pPlayer); + + return pState; +} + +// Below this many degrees, slow down turning rate linearly +#define FADE_TURN_DEGREES 45.0f +// After this, need to start turning feet +#define MAX_TORSO_ANGLE 90.0f +// Below this amount, don't play a turning animation/perform IK +#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f + +//static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." ); +extern ConVar sv_backspeed; +extern ConVar mp_feetyawrate; +extern ConVar mp_facefronttime; +extern ConVar mp_ik; + +CSinglePlayerAnimState::CSinglePlayerAnimState(CBasePlayer *pPlayer) : m_pPlayer(pPlayer) +{ + m_flGaitYaw = 0.0f; + m_flGoalFeetYaw = 0.0f; + m_flCurrentFeetYaw = 0.0f; + m_flCurrentTorsoYaw = 0.0f; + m_flLastYaw = 0.0f; + m_flLastTurnTime = 0.0f; + m_flTurnCorrectionTime = 0.0f; + + m_pPlayer = NULL; +}; + +void CSinglePlayerAnimState::Init(CBasePlayer *pPlayer) +{ + m_pPlayer = pPlayer; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::Update() +{ + m_angRender = GetBasePlayer()->GetLocalAngles(); + + ComputePoseParam_BodyYaw(); + ComputePoseParam_BodyPitch(GetBasePlayer()->GetModelPtr()); + ComputePoseParam_BodyLookYaw(); + ComputePoseParam_HeadPitch(GetBasePlayer()->GetModelPtr()); + + ComputePlaybackRate(); +} + +void CSinglePlayerAnimState::Release() +{ + delete this; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePlaybackRate() +{ + // Determine ideal playback rate + Vector vel; + GetOuterAbsVelocity(vel); + + float speed = vel.Length2D(); + + bool isMoving = (speed > 0.5f) ? true : false; + + float maxspeed = GetBasePlayer()->GetSequenceGroundSpeed(GetBasePlayer()->GetSequence()); + + if (isMoving && (maxspeed > 0.0f)) + { + float flFactor = 1.0f; + + // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below + GetBasePlayer()->SetPlaybackRate((speed * flFactor) / maxspeed); + + // BUG BUG: + // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed + } + else + { + GetBasePlayer()->SetPlaybackRate(1.0f); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CBasePlayer +//----------------------------------------------------------------------------- +CBasePlayer *CSinglePlayerAnimState::GetBasePlayer() +{ + return m_pPlayer; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : dt - +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::EstimateYaw(void) +{ + float dt = gpGlobals->frametime; + + if (!dt) + { + return; + } + + Vector est_velocity; + QAngle angles; + + GetOuterAbsVelocity(est_velocity); + + angles = GetBasePlayer()->GetLocalAngles(); + + if (est_velocity[1] == 0 && est_velocity[0] == 0) + { + float flYawDiff = angles[YAW] - m_flGaitYaw; + flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; + if (flYawDiff > 180) + flYawDiff -= 360; + if (flYawDiff < -180) + flYawDiff += 360; + + if (dt < 0.25) + flYawDiff *= dt * 4; + else + flYawDiff *= dt; + + m_flGaitYaw += flYawDiff; + m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360; + } + else + { + m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); + + if (m_flGaitYaw > 180) + m_flGaitYaw = 180; + else if (m_flGaitYaw < -180) + m_flGaitYaw = -180; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Override for backpeddling +// Input : dt - +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_BodyYaw(void) +{ + int iYaw = GetBasePlayer()->LookupPoseParameter("move_yaw"); + if (iYaw < 0) + return; + + // view direction relative to movement + float flYaw; + + EstimateYaw(); + + QAngle angles = GetBasePlayer()->GetLocalAngles(); + float ang = angles[YAW]; + if (ang > 180.0f) + { + ang -= 360.0f; + } + else if (ang < -180.0f) + { + ang += 360.0f; + } + + // calc side to side turning + flYaw = ang - m_flGaitYaw; + // Invert for mapping into 8way blend + flYaw = -flYaw; + flYaw = flYaw - (int)(flYaw / 360) * 360; + + if (flYaw < -180) + { + flYaw = flYaw + 360; + } + else if (flYaw > 180) + { + flYaw = flYaw - 360; + } + + GetBasePlayer()->SetPoseParameter(iYaw, flYaw); + +#ifndef CLIENT_DLL + //Adrian: Make the model's angle match the legs so the hitboxes match on both sides. + GetBasePlayer()->SetLocalAngles(QAngle(GetBasePlayer()->EyeAngles().x, m_flCurrentFeetYaw, 0)); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_BodyPitch(CStudioHdr *pStudioHdr) +{ + // Get pitch from v_angle + float flPitch = GetBasePlayer()->GetLocalAngles()[PITCH]; + + if (flPitch > 180.0f) + { + flPitch -= 360.0f; + } + flPitch = clamp(flPitch, -90, 90); + + QAngle absangles = GetBasePlayer()->GetAbsAngles(); + absangles.x = 0.0f; + m_angRender = absangles; + + // See if we have a blender for pitch + GetBasePlayer()->SetPoseParameter(pStudioHdr, "aim_pitch", flPitch); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : goal - +// maxrate - +// dt - +// current - +// Output : int +//----------------------------------------------------------------------------- +int CSinglePlayerAnimState::ConvergeAngles(float goal, float maxrate, float dt, float& current) +{ + int direction = TURN_NONE; + + float anglediff = goal - current; + float anglediffabs = fabs(anglediff); + + anglediff = AngleNormalize(anglediff); + + float scale = 1.0f; + if (anglediffabs <= FADE_TURN_DEGREES) + { + scale = anglediffabs / FADE_TURN_DEGREES; + // Always do at least a bit of the turn ( 1% ) + scale = clamp(scale, 0.01f, 1.0f); + } + + float maxmove = maxrate * dt * scale; + + if (fabs(anglediff) < maxmove) + { + current = goal; + } + else + { + if (anglediff > 0) + { + current += maxmove; + direction = TURN_LEFT; + } + else + { + current -= maxmove; + direction = TURN_RIGHT; + } + } + + current = AngleNormalize(current); + + return direction; +} + +void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw(void) +{ + QAngle absangles = GetBasePlayer()->GetAbsAngles(); + absangles.y = AngleNormalize(absangles.y); + m_angRender = absangles; + + // See if we even have a blender for pitch + int upper_body_yaw = GetBasePlayer()->LookupPoseParameter("aim_yaw"); + if (upper_body_yaw < 0) + { + return; + } + + // Assume upper and lower bodies are aligned and that we're not turning + float flGoalTorsoYaw = 0.0f; + int turning = TURN_NONE; + float turnrate = 360.0f; + + Vector vel; + + GetOuterAbsVelocity(vel); + + bool isMoving = (vel.Length() > 1.0f) ? true : false; + + if (!isMoving) + { + // Just stopped moving, try and clamp feet + if (m_flLastTurnTime <= 0.0f) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetBasePlayer()->EyeAngles().y; + // Snap feet to be perfectly aligned with torso/eyes + m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; + m_flCurrentFeetYaw = m_flGoalFeetYaw; + m_nTurningInPlace = TURN_NONE; + } + + // If rotating in place, update stasis timer + + if (m_flLastYaw != GetBasePlayer()->EyeAngles().y) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetBasePlayer()->EyeAngles().y; + } + + if (m_flGoalFeetYaw != m_flCurrentFeetYaw) + { + m_flLastTurnTime = gpGlobals->curtime; + } + + turning = ConvergeAngles(m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw); + + QAngle eyeAngles = GetBasePlayer()->EyeAngles(); + QAngle vAngle = GetBasePlayer()->GetLocalAngles(); + + // See how far off current feetyaw is from true yaw + float yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw; + yawdelta = AngleNormalize(yawdelta); + + bool rotated_too_far = false; + + float yawmagnitude = fabs(yawdelta); + + // If too far, then need to turn in place + if (yawmagnitude > 45) + { + rotated_too_far = true; + } + + // Standing still for a while, rotate feet around to face forward + // Or rotated too far + // FIXME: Play an in place turning animation + if (rotated_too_far || + (gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat())) + { + m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; + m_flLastTurnTime = gpGlobals->curtime; + + /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw; + if ( yd > 0 ) + { + m_nTurningInPlace = TURN_RIGHT; + } + else if ( yd < 0 ) + { + m_nTurningInPlace = TURN_LEFT; + } + else + { + m_nTurningInPlace = TURN_NONE; + } + + turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); + yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw;*/ + + } + + // Snap upper body into position since the delta is already smoothed for the feet + flGoalTorsoYaw = yawdelta; + m_flCurrentTorsoYaw = flGoalTorsoYaw; + } + else + { + m_flLastTurnTime = 0.0f; + m_nTurningInPlace = TURN_NONE; + m_flCurrentFeetYaw = m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y; + flGoalTorsoYaw = 0.0f; + m_flCurrentTorsoYaw = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw; + } + + if (turning == TURN_NONE) + { + m_nTurningInPlace = turning; + } + + if (m_nTurningInPlace != TURN_NONE) + { + // If we're close to finishing the turn, then turn off the turning animation + if (fabs(m_flCurrentFeetYaw - m_flGoalFeetYaw) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION) + { + m_nTurningInPlace = TURN_NONE; + } + } + + // Rotate entire body into position + absangles = GetBasePlayer()->GetAbsAngles(); + absangles.y = m_flCurrentFeetYaw; + m_angRender = absangles; + + GetBasePlayer()->SetPoseParameter(upper_body_yaw, clamp(m_flCurrentTorsoYaw, -60.0f, 60.0f)); + + /* + // FIXME: Adrian, what is this? + int body_yaw = GetBasePlayer()->LookupPoseParameter( "body_yaw" ); + + if ( body_yaw >= 0 ) + { + GetBasePlayer()->SetPoseParameter( body_yaw, 30 ); + } + */ + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSinglePlayerAnimState::ComputePoseParam_HeadPitch(CStudioHdr *pStudioHdr) +{ + // Get pitch from v_angle + int iHeadPitch = GetBasePlayer()->LookupPoseParameter("head_pitch"); + + float flPitch = GetBasePlayer()->EyeAngles()[PITCH]; + + if (flPitch > 180.0f) + { + flPitch -= 360.0f; + } + flPitch = clamp(flPitch, -90, 90); + + QAngle absangles = GetBasePlayer()->GetAbsAngles(); + absangles.x = 0.0f; + m_angRender = absangles; + + GetBasePlayer()->SetPoseParameter(pStudioHdr, iHeadPitch, flPitch); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : activity - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CSinglePlayerAnimState::BodyYawTranslateActivity(Activity activity) +{ + // Not even standing still, sigh + if (activity != ACT_IDLE) + return activity; + + // Not turning + switch (m_nTurningInPlace) + { + default: + case TURN_NONE: + return activity; + /* + case TURN_RIGHT: + return ACT_TURNRIGHT45; + case TURN_LEFT: + return ACT_TURNLEFT45; + */ + case TURN_RIGHT: + case TURN_LEFT: + return mp_ik.GetBool() ? ACT_TURN : activity; + } + + Assert(0); + return activity; +} + +const QAngle& CSinglePlayerAnimState::GetRenderAngles() +{ + return m_angRender; +} + +void CSinglePlayerAnimState::GetOuterAbsVelocity(Vector& vel) +{ +#if defined( CLIENT_DLL ) + GetBasePlayer()->EstimateAbsVelocity(vel); +#else + vel = GetBasePlayer()->GetAbsVelocity(); +#endif +} diff --git a/game/shared/vance/singleplayer_animstate.h b/game/shared/vance/unused/singleplayer_animstate.h similarity index 100% rename from game/shared/vance/singleplayer_animstate.h rename to game/shared/vance/unused/singleplayer_animstate.h diff --git a/game/shared/vance/weapon_akms.cpp b/game/shared/vance/weapon_akms.cpp index 8e8adceb..b3611bd5 100644 --- a/game/shared/vance/weapon_akms.cpp +++ b/game/shared/vance/weapon_akms.cpp @@ -98,7 +98,7 @@ void CWeaponAKMS::PrimaryAttack() m_iHeat++; m_bCoolingDown = false; m_flCooldownTime = gpGlobals->curtime + 3.0f; - + pOwner->ViewPunchReset(); @@ -114,7 +114,7 @@ void CWeaponAKMS::PrimaryAttack() WeaponSound(SINGLE); SendWeaponAnim(GetPrimaryAttackActivity()); //pOwner->ViewPunch(QAngle(-3, random->RandomFloat(-1, 1), 0)); - DoMachineGunKick(pOwner, 0.3f, 10.0f, max(1.0f, m_fFireDuration * 1.75), 5.0f); + DoMachineGunKick(pOwner, 0.3f, 10.0f, MAX(1.0f, m_fFireDuration * 1.75), 5.0f); m_iClip1 = m_iClip1 - 1; m_nShotsFired++; @@ -311,4 +311,4 @@ void C_WeaponAKMS::HandleSmoking() m_pSmoke->StopEmission(); } } -#endif \ No newline at end of file +#endif diff --git a/game/shared/voice_gamemgr.cpp b/game/shared/voice_gamemgr.cpp index 79933896..2feb048d 100644 --- a/game/shared/voice_gamemgr.cpp +++ b/game/shared/voice_gamemgr.cpp @@ -37,7 +37,7 @@ ConVar voice_serverdebug( "voice_serverdebug", "0" ); // Set game rules to allow all clients to talk to each other. // Muted players still can't talk to each other. -ConVar sv_alltalk( "sv_alltalk", "0", FCVAR_NOTIFY | FCVAR_REPLICATED, "Players can hear all other players, no team restrictions" ); +ConVar sv_alltalk( "sv_alltalk", "0", FCVAR_NOTIFY, "Players can hear all other players, no team restrictions" ); CVoiceGameMgr g_VoiceGameMgr; @@ -48,7 +48,6 @@ CVoiceGameMgr g_VoiceGameMgr; // ------------------------------------------------------------------------ // // Find a player with a case-insensitive name search. -#if 0 static CBasePlayer* FindPlayerByName(const char *pTestName) { for(int i=1; i <= gpGlobals->maxClients; i++) @@ -70,7 +69,6 @@ static CBasePlayer* FindPlayerByName(const char *pTestName) return NULL; } -#endif static void VoiceServerDebug( const char *pFmt, ... ) { @@ -289,4 +287,4 @@ bool CVoiceGameMgr::CheckProximity( int iDistance ) return true; return false; -} +} \ No newline at end of file diff --git a/game/shared/vscript_shared.cpp b/game/shared/vscript_shared.cpp new file mode 100644 index 00000000..9f1d610c --- /dev/null +++ b/game/shared/vscript_shared.cpp @@ -0,0 +1,699 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "vscript_shared.h" +#include "icommandline.h" +#include "tier1/utlbuffer.h" +#include "tier1/fmtstr.h" +#include "filesystem.h" +#include "characterset.h" +#include "isaverestore.h" +#include "gamerules.h" +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_singletons.h" +#endif + +IScriptVM * g_pScriptVM; +extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); + +// #define VMPROFILE 1 + +#ifdef VMPROFILE + +#define VMPROF_START float debugStartTime = Plat_FloatTime(); +#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 ); + +#else // !VMPROFILE + +#define VMPROF_START +#define VMPROF_SHOW + +#endif // VMPROFILE + +#ifdef MAPBASE_VSCRIPT +// This is to ensure a dependency exists between the vscript library and the game DLLs +extern int vscript_token; +int vscript_token_hack = vscript_token; +#endif + +static const char *pszExtensions[] = +{ + "", // SL_NONE + ".gm", // SL_GAMEMONKEY + ".nut", // SL_SQUIRREL + ".lua", // SL_LUA + ".py", // SL_PYTHON +}; + + + +HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing ) +{ + if ( !g_pScriptVM ) + { + return NULL; + } + + const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()]; + const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); + if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) + { +#ifdef MAPBASE_VSCRIPT + CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type (\"%s\", from \"%s\") does not match VM type (\"%s\")\n", pszIncomingExtension, pszScriptName, pszVMExtension ); +#else + CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" ); +#endif + return NULL; + } + + CFmtStr scriptPath; + if ( pszIncomingExtension ) + { + scriptPath.sprintf( "scripts/vscripts/%s", pszScriptName ); + } + else + { + scriptPath.sprintf( "scripts/vscripts/%s%s", pszScriptName, pszVMExtension ); + } + + const char *pBase; + CUtlBuffer bufferScript; + + if ( g_pScriptVM->GetLanguage() == SL_PYTHON ) + { + // python auto-loads raw or precompiled modules - don't load data here + pBase = NULL; + } + else + { + bool bResult = filesystem->ReadFile( scriptPath, "GAME", bufferScript ); + +#ifdef MAPBASE_VSCRIPT + if ( !bResult && bWarnMissing ) +#else + if( !bResult ) +#endif + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Script not found (%s) \n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + + pBase = (const char *) bufferScript.Base(); + + if ( !pBase || !*pBase ) + { + return NULL; + } + } + + + const char *pszFilename = V_strrchr( scriptPath, '/' ); + pszFilename++; + HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, pszFilename ); + if ( !hScript ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + return hScript; +} + +static int g_ScriptServerRunScriptDepth; + +bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing ) +{ + if ( !g_pScriptVM ) + { + return false; + } + + if ( !pszScriptName || !*pszScriptName ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Cannot run script: NULL script name\n" ); + return false; + } + + // Prevent infinite recursion in VM + if ( g_ScriptServerRunScriptDepth > 16 ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "IncludeScript stack overflow\n" ); + return false; + } + + g_ScriptServerRunScriptDepth++; + HSCRIPT hScript = VScriptCompileScript( pszScriptName, bWarnMissing ); + bool bSuccess = false; + if ( hScript ) + { + // player is not yet spawned, this block is always skipped. + // It is registered in CBasePlayer instead. +#ifndef MAPBASE +#ifdef GAME_DLL + if ( gpGlobals->maxClients == 1 ) + { + CBaseEntity *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer ) + { + g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() ); + } + } +#endif +#endif + bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR ); + if ( !bSuccess ) + { + Warning( "Error running script named %s\n", pszScriptName ); + Assert( "Error running script" ); + } + } + g_ScriptServerRunScriptDepth--; + return bSuccess; +} + + +#ifdef MAPBASE_VSCRIPT + +// +// These functions are currently only used for "mapspawn_addon" scripts. +// +HSCRIPT VScriptCompileScriptAbsolute( const char *pszScriptName, bool bWarnMissing, const char *pszRootFolderName ) +{ + if ( !g_pScriptVM ) + { + return NULL; + } + + const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()]; + const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); + if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) + { + // Account for cases where there is no extension and the folder names just have dots (e.g. ".local") + if ( strchr( pszIncomingExtension, CORRECT_PATH_SEPARATOR ) ) + { + pszIncomingExtension = NULL; + } + else + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type (\"%s\", from \"%s\") does not match VM type (\"%s\")\n", pszIncomingExtension, pszScriptName, pszVMExtension ); + return NULL; + } + } + + CFmtStr scriptPath; + if ( pszIncomingExtension ) + { + scriptPath = pszScriptName; + } + else + { + scriptPath.sprintf( "%s%s", pszScriptName, pszVMExtension ); + } + + const char *pBase; + CUtlBuffer bufferScript; + + if ( g_pScriptVM->GetLanguage() == SL_PYTHON ) + { + // python auto-loads raw or precompiled modules - don't load data here + pBase = NULL; + } + else + { + bool bResult = filesystem->ReadFile( scriptPath, NULL, bufferScript ); + + if ( !bResult && bWarnMissing ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Script not found (%s) \n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + + pBase = (const char *) bufferScript.Base(); + + if ( !pBase || !*pBase ) + { + return NULL; + } + } + + // Attach the folder to the script ID + const char *pszFilename = V_strrchr( scriptPath, '/' ); + scriptPath.sprintf( "%s%s", pszRootFolderName, pszFilename ); + + HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, scriptPath ); + if ( !hScript ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + return hScript; +} + +bool VScriptRunScriptAbsolute( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing, const char *pszRootFolderName ) +{ + if ( !g_pScriptVM ) + { + return false; + } + + if ( !pszScriptName || !*pszScriptName ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Cannot run script: NULL script name\n" ); + return false; + } + + // Prevent infinite recursion in VM + if ( g_ScriptServerRunScriptDepth > 16 ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "IncludeScript stack overflow\n" ); + return false; + } + + g_ScriptServerRunScriptDepth++; + HSCRIPT hScript = VScriptCompileScriptAbsolute( pszScriptName, bWarnMissing, pszRootFolderName ); + bool bSuccess = false; + if ( hScript ) + { + bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR ); + if ( !bSuccess ) + { + Warning( "Error running script named %s\n", pszScriptName ); + Assert( "Error running script" ); + } + } + g_ScriptServerRunScriptDepth--; + return bSuccess; +} +#endif + + +#ifdef GAME_DLL +#define IsCommandIssuedByServerAdmin() UTIL_IsCommandIssuedByServerAdmin() +#else +#define IsCommandIssuedByServerAdmin() true +#endif + +#ifdef CLIENT_DLL +CON_COMMAND_F( script_client, "Run the text as a script", FCVAR_CHEAT ) +#else +CON_COMMAND_F( script, "Run the text as a script", FCVAR_CHEAT ) +#endif +{ + if ( !IsCommandIssuedByServerAdmin() ) + return; + + if ( !*args[1] ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "No function name specified\n" ); + return; + } + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + + const char *pszScript = args.GetCommandString(); + +#ifdef CLIENT_DLL + pszScript += 13; +#else + pszScript += 6; +#endif + + while ( *pszScript == ' ' ) + { + pszScript++; + } + + if ( !*pszScript ) + { + return; + } + + if ( *pszScript != '\"' ) + { + g_pScriptVM->Run( pszScript ); + } + else + { + pszScript++; + const char *pszEndQuote = pszScript; + while ( *pszEndQuote != '\"' ) + { + pszEndQuote++; + } + if ( !*pszEndQuote ) + { + return; + } + *((char *)pszEndQuote) = 0; + g_pScriptVM->Run( pszScript ); + *((char *)pszEndQuote) = '\"'; + } +} + +#ifdef CLIENT_DLL +CON_COMMAND_F( script_execute_client, "Run a vscript file", FCVAR_CHEAT ) +#else +CON_COMMAND_F( script_execute, "Run a vscript file", FCVAR_CHEAT ) +#endif +{ + if ( !IsCommandIssuedByServerAdmin() ) + return; + + if ( !*args[1] ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "No script specified\n" ); + return; + } + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + + VScriptRunScript( args[1], true ); +} + +#ifdef CLIENT_DLL +CON_COMMAND_F( script_debug_client, "Connect the vscript VM to the script debugger", FCVAR_CHEAT ) +#else +CON_COMMAND_F( script_debug, "Connect the vscript VM to the script debugger", FCVAR_CHEAT ) +#endif +{ + if ( !IsCommandIssuedByServerAdmin() ) + return; + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + g_pScriptVM->ConnectDebugger(); +} + +#ifdef CLIENT_DLL +CON_COMMAND_F( script_help_client, "Output help for script functions, optionally with a search string", FCVAR_CHEAT ) +#else +CON_COMMAND_F( script_help, "Output help for script functions, optionally with a search string", FCVAR_CHEAT ) +#endif +{ + if ( !IsCommandIssuedByServerAdmin() ) + return; + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + const char *pszArg1 = "*"; + if ( *args[1] ) + { + pszArg1 = args[1]; + } + + g_pScriptVM->Run( CFmtStr( "__Documentation.PrintHelp( \"%s\" );", pszArg1 ) ); +} + +#ifdef CLIENT_DLL +CON_COMMAND_F( script_dump_all_client, "Dump the state of the VM to the console", FCVAR_CHEAT ) +#else +CON_COMMAND_F( script_dump_all, "Dump the state of the VM to the console", FCVAR_CHEAT ) +#endif +{ + if ( !IsCommandIssuedByServerAdmin() ) + return; + + if ( !g_pScriptVM ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" ); + return; + } + g_pScriptVM->DumpState(); +} + +//----------------------------------------------------------------------------- + +#ifdef MAPBASE_VSCRIPT +void RunAddonScripts() +{ + char searchPaths[4096]; + filesystem->GetSearchPath( "ADDON", true, searchPaths, sizeof( searchPaths ) ); + + for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) ) + { + char folderName[MAX_PATH]; + Q_FileBase( path, folderName, sizeof( folderName ) ); + + // mapspawn_addon + char fullpath[MAX_PATH]; + Q_snprintf( fullpath, sizeof( fullpath ), "%sscripts/vscripts/mapspawn_addon", path ); + Q_FixSlashes( fullpath ); + + VScriptRunScriptAbsolute( fullpath, NULL, false, folderName ); + } +} + +// UNDONE: "autorun" folder +/* +void RunAutorunScripts() +{ + FileFindHandle_t fileHandle; + char szDirectory[MAX_PATH]; + char szFileName[MAX_PATH]; + char szPartialScriptPath[MAX_PATH]; + + // TODO: Scanning for VM extension would make this more efficient + Q_strncpy( szDirectory, "scripts/vscripts/autorun/*", sizeof( szDirectory ) ); + + const char *pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle ); + while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE) + { + Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) ); + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/%s", szFileName ); + VScriptRunScript( szPartialScriptPath ); + + pszScriptFile = filesystem->FindNext( fileHandle ); + } + + // Non-shared scripts +#ifdef CLIENT_DLL + Q_strncpy( szDirectory, "scripts/vscripts/autorun/client/*", sizeof( szDirectory ) ); +#else + Q_strncpy( szDirectory, "scripts/vscripts/autorun/server/*", sizeof( szDirectory ) ); +#endif + + pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle ); + while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE) + { + Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) ); +#ifdef CLIENT_DLL + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/client/%s", szFileName ); +#else + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/server/%s", szFileName ); +#endif + VScriptRunScript( szPartialScriptPath ); + + pszScriptFile = filesystem->FindNext( fileHandle ); + } +} +*/ +#endif + +//----------------------------------------------------------------------------- + +static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2; + +//----------------------------------------------------------------------------- + +class CVScriptSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler +{ +public: + CVScriptSaveRestoreBlockHandler() : + m_InstanceMap( DefLessFunc(const char *) ) + { + } + const char *GetBlockName() + { +#ifdef CLIENT_DLL + return "VScriptClient"; +#else + return "VScriptServer"; +#endif + } + + //--------------------------------- + + void Save( ISave *pSave ) + { + pSave->StartBlock(); + + int temp = g_pScriptVM != NULL; + pSave->WriteInt( &temp ); + if ( g_pScriptVM ) + { + temp = g_pScriptVM->GetLanguage(); + pSave->WriteInt( &temp ); + CUtlBuffer buffer; + g_pScriptVM->WriteState( &buffer ); + temp = buffer.TellPut(); + pSave->WriteInt( &temp ); + if ( temp > 0 ) + { + pSave->WriteData( (const char *)buffer.Base(), temp ); + } + } + + pSave->EndBlock(); + } + + //--------------------------------- + + void WriteSaveHeaders( ISave *pSave ) + { + pSave->WriteShort( &VSCRIPT_SERVER_SAVE_RESTORE_VERSION ); + } + + //--------------------------------- + + void ReadRestoreHeaders( IRestore *pRestore ) + { + // No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so. + short version; + pRestore->ReadShort( &version ); + m_fDoLoad = ( version == VSCRIPT_SERVER_SAVE_RESTORE_VERSION ); + } + + //--------------------------------- + + void Restore( IRestore *pRestore, bool createPlayers ) + { + if ( !m_fDoLoad && g_pScriptVM ) + { + return; + } +#ifdef CLIENT_DLL + C_BaseEntity *pEnt = ClientEntityList().FirstBaseEntity(); +#else + CBaseEntity *pEnt = gEntList.FirstEnt(); +#endif + while ( pEnt ) + { + if ( pEnt->m_iszScriptId != NULL_STRING ) + { +#ifndef MAPBASE_VSCRIPT + g_pScriptVM->RegisterClass( pEnt->GetScriptDesc() ); +#endif + m_InstanceMap.Insert( STRING( pEnt->m_iszScriptId ), pEnt ); + } +#ifdef CLIENT_DLL + pEnt = ClientEntityList().NextBaseEntity( pEnt ); +#else + pEnt = gEntList.NextEnt( pEnt ); +#endif + } + + pRestore->StartBlock(); + if ( pRestore->ReadInt() && pRestore->ReadInt() == g_pScriptVM->GetLanguage() ) + { + int nBytes = pRestore->ReadInt(); + if ( nBytes > 0 ) + { + CUtlBuffer buffer; + buffer.EnsureCapacity( nBytes ); + pRestore->ReadData( (char *)buffer.AccessForDirectRead( nBytes ), nBytes, 0 ); + g_pScriptVM->ReadState( &buffer ); + } + } + pRestore->EndBlock(); + } + + void PostRestore( void ) + { + for ( int i = m_InstanceMap.FirstInorder(); i != m_InstanceMap.InvalidIndex(); i = m_InstanceMap.NextInorder( i ) ) + { + CBaseEntity *pEnt = m_InstanceMap[i]; + if ( pEnt->m_hScriptInstance ) + { + ScriptVariant_t variant; + if ( g_pScriptVM->GetValue( STRING(pEnt->m_iszScriptId), &variant ) && variant.m_type == FIELD_HSCRIPT ) + { + pEnt->m_ScriptScope.Init( variant.m_hScript, false ); +#ifndef CLIENT_DLL + pEnt->RunPrecacheScripts(); +#endif + } + } + else + { + // Script system probably has no internal references + pEnt->m_iszScriptId = NULL_STRING; + } + } + m_InstanceMap.Purge(); + +#ifdef MAPBASE_VSCRIPT + GetScriptHookManager().OnRestore(); +#endif + +#if defined(MAPBASE_VSCRIPT) && defined(CLIENT_DLL) + VScriptSaveRestoreUtil_OnVMRestore(); +#endif + } + + + CUtlMap m_InstanceMap; + +private: + bool m_fDoLoad; +}; + +//----------------------------------------------------------------------------- + +CVScriptSaveRestoreBlockHandler g_VScriptSaveRestoreBlockHandler; + +//------------------------------------- + +ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler() +{ + return &g_VScriptSaveRestoreBlockHandler; +} + +bool CBaseEntityScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) +{ + CBaseEntity *pEntity = (CBaseEntity *)p; +#ifdef CLIENT_DLL + if ( pEntity->GetEntityName() && pEntity->GetEntityName()[0] ) +#else + if ( pEntity->GetEntityName() != NULL_STRING ) +#endif + { + V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), pEntity->GetClassname(), STRING( pEntity->GetEntityName() ) ); + } + else + { + V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), pEntity->GetClassname() ); + } + return true; +} + +void *CBaseEntityScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ) +{ + int iEntity = g_VScriptSaveRestoreBlockHandler.m_InstanceMap.Find( pszId ); + if ( iEntity != g_VScriptSaveRestoreBlockHandler.m_InstanceMap.InvalidIndex() ) + { + CBaseEntity *pEnt = g_VScriptSaveRestoreBlockHandler.m_InstanceMap[iEntity]; + pEnt->m_hScriptInstance = hInstance; + return pEnt; + } + return NULL; +} + + +CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper; diff --git a/game/shared/vscript_shared.h b/game/shared/vscript_shared.h new file mode 100644 index 00000000..50834220 --- /dev/null +++ b/game/shared/vscript_shared.h @@ -0,0 +1,52 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_SHARED_H +#define VSCRIPT_SHARED_H + +#include "vscript/ivscript.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +extern IScriptVM * g_pScriptVM; + +HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing = false ); +bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing = false ); +inline bool VScriptRunScript( const char *pszScriptName, bool bWarnMissing = false ) { return VScriptRunScript( pszScriptName, NULL, bWarnMissing ); } + +#define DECLARE_ENT_SCRIPTDESC() ALLOW_SCRIPT_ACCESS(); virtual ScriptClassDesc_t *GetScriptDesc() + +#define BEGIN_ENT_SCRIPTDESC( className, baseClass, description ) _IMPLEMENT_ENT_SCRIPTDESC_ACCESSOR( className ); BEGIN_SCRIPTDESC( className, baseClass, description ) +#define BEGIN_ENT_SCRIPTDESC_ROOT( className, description ) _IMPLEMENT_ENT_SCRIPTDESC_ACCESSOR( className ); BEGIN_SCRIPTDESC_ROOT( className, description ) +#define BEGIN_ENT_SCRIPTDESC_NAMED( className, baseClass, scriptName, description ) _IMPLEMENT_ENT_SCRIPTDESC_ACCESSOR( className ); BEGIN_SCRIPTDESC_NAMED( className, baseClass, scriptName, description ) +#define BEGIN_ENT_SCRIPTDESC_ROOT_NAMED( className, scriptName, description ) _IMPLEMENT_ENT_SCRIPTDESC_ACCESSOR( className ); BEGIN_SCRIPTDESC_ROOT_NAMED( className, scriptName, description ) + +#define _IMPLEMENT_ENT_SCRIPTDESC_ACCESSOR( className ) template <> ScriptClassDesc_t * GetScriptDesc( className * ); ScriptClassDesc_t *className::GetScriptDesc() { return ::GetScriptDesc( this ); } + +// Only allow scripts to create entities during map initialization +bool IsEntityCreationAllowedInScripts( void ); + +class ISaveRestoreBlockHandler; +ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler(); + +class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper +{ + bool ToString( void *p, char *pBuf, int bufSize ); + void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ); +}; + +extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper; + +#ifdef MAPBASE_VSCRIPT +void RegisterSharedScriptConstants(); +void RegisterSharedScriptFunctions(); + +void RunAddonScripts(); +#endif + +#endif // VSCRIPT_SHARED_H diff --git a/game/shared/weapon_parse.cpp b/game/shared/weapon_parse.cpp index 3945dcd7..5597b2a2 100644 --- a/game/shared/weapon_parse.cpp +++ b/game/shared/weapon_parse.cpp @@ -17,7 +17,7 @@ // The sound categories found in the weapon classname.txt files // This needs to match the WeaponSound_t enum in weapon_parse.h #if !defined(_STATIC_LINKED) || defined(CLIENT_DLL) -const char *pWeaponSoundCategories[ NUM_SHOOT_SOUND_TYPES ] = +const char *pWeaponSoundCategories[ NUM_SHOOT_SOUND_TYPES ] = { "empty", "single_shot", @@ -70,21 +70,23 @@ itemFlags_t g_ItemFlags[8] = { "ITEM_FLAG_NOITEMPICKUP", ITEM_FLAG_NOITEMPICKUP } }; #else -extern itemFlags_t g_ItemFlags[8]; +extern itemFlags_t g_ItemFlags[7]; #endif static CUtlDict< FileWeaponInfo_t*, unsigned short > m_WeaponInfoDatabase; +#ifndef MAPBASE // Mapbase makes weapons in the same slot & position swap each other out, which is a feature mods can intentionally use. #ifdef _DEBUG // used to track whether or not two weapons have been mistakenly assigned the wrong slot -bool g_bUsedWeaponSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS] = { { false } }; +bool g_bUsedWeaponSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS] = { 0 }; +#endif #endif //----------------------------------------------------------------------------- -// Purpose: -// Input : *name - +// Purpose: +// Input : *name - // Output : FileWeaponInfo_t //----------------------------------------------------------------------------- static WEAPON_FILE_INFO_HANDLE FindWeaponInfoSlot( const char *name ) @@ -116,8 +118,8 @@ static FileWeaponInfo_t gNullWeaponInfo; //----------------------------------------------------------------------------- -// Purpose: -// Input : handle - +// Purpose: +// Input : handle - // Output : FileWeaponInfo_t //----------------------------------------------------------------------------- FileWeaponInfo_t *GetFileWeaponInfoFromHandle( WEAPON_FILE_INFO_HANDLE handle ) @@ -136,7 +138,7 @@ FileWeaponInfo_t *GetFileWeaponInfoFromHandle( WEAPON_FILE_INFO_HANDLE handle ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : WEAPON_FILE_INFO_HANDLE //----------------------------------------------------------------------------- WEAPON_FILE_INFO_HANDLE GetInvalidWeaponInfoHandle( void ) @@ -147,16 +149,18 @@ WEAPON_FILE_INFO_HANDLE GetInvalidWeaponInfoHandle( void ) #if 0 void ResetFileWeaponInfoDatabase( void ) { - int c = m_WeaponInfoDatabase.Count(); + int c = m_WeaponInfoDatabase.Count(); for ( int i = 0; i < c; ++i ) { delete m_WeaponInfoDatabase[ i ]; } m_WeaponInfoDatabase.RemoveAll(); +#ifndef MAPBASE // Mapbase makes weapons in the same slot & position swap each other out, which is a feature mods can intentionally use. #ifdef _DEBUG memset(g_bUsedWeaponSlots, 0, sizeof(g_bUsedWeaponSlots)); #endif +#endif } #endif @@ -227,9 +231,9 @@ KeyValues* ReadEncryptedKVFile( IFileSystem *filesystem, const char *szFilenameW // load file into a null-terminated buffer int fileSize = filesystem->Size(f); char *buffer = (char*)MemAllocScratch(fileSize + 1); - + Assert(buffer); - + filesystem->Read(buffer, fileSize, f); // read into local buffer buffer[fileSize] = 0; // null terminate file as EOF filesystem->Close( f ); // close file after reading @@ -274,12 +278,16 @@ bool ReadWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeapo Assert( 0 ); return false; } - + *phandle = FindWeaponInfoSlot( szWeaponName ); FileWeaponInfo_t *pFileInfo = GetFileWeaponInfoFromHandle( *phandle ); Assert( pFileInfo ); +#ifdef MAPBASE + if ( pFileInfo->bParsedScript && !pFileInfo->bCustom ) +#else if ( pFileInfo->bParsedScript ) +#endif return true; char sz[128]; @@ -296,12 +304,58 @@ bool ReadWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeapo if ( !pKV ) return false; +#ifdef MAPBASE + pFileInfo->bCustom = false; +#endif + pFileInfo->Parse( pKV, szWeaponName ); + + pKV->deleteThis(); + + return true; +} + +#ifdef MAPBASE +extern const char *g_MapName; + +bool ReadCustomWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, WEAPON_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey ) +{ + if ( !phandle ) + { + Assert( 0 ); + return false; + } + + *phandle = FindWeaponInfoSlot( szWeaponName ); + FileWeaponInfo_t *pFileInfo = GetFileWeaponInfoFromHandle( *phandle ); + Assert( pFileInfo ); + + // Just parse the custom script anyway even if it was already loaded. This is because after one is loaded, + // there's no way of distinguishing between maps with no custom scripts and maps with their own new custom scripts. + //if ( pFileInfo->bParsedScript && pFileInfo->bCustom ) + // return true; + + char sz[128]; + Q_snprintf( sz, sizeof( sz ), "maps/%s_%s", g_MapName, szWeaponName ); + + KeyValues *pKV = ReadEncryptedKVFile( filesystem, sz, pICEKey, +#if defined( DOD_DLL ) + true // Only read .ctx files! +#else + false +#endif + ); + + if ( !pKV ) + return false; + + pFileInfo->bCustom = true; pFileInfo->Parse( pKV, szWeaponName ); pKV->deleteThis(); return true; } +#endif //----------------------------------------------------------------------------- @@ -347,8 +401,14 @@ FileWeaponInfo_t::FileWeaponInfo_t() bShowUsageHint = false; m_bAllowFlipping = true; m_bBuiltRightHanded = true; - flBulletSpeed = DEFAULT_BULLET_SPEED; - flBulletSize = 0.0f; +#ifdef MAPBASE + m_flViewmodelFOV = 0.0f; + m_flBobScale = 1.0f; + m_flSwayScale = 1.0f; + m_flSwaySpeedScale = 1.0f; + szDroppedModel[0] = 0; + m_bUsesHands = false; +#endif } #ifdef CLIENT_DLL @@ -370,7 +430,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam Q_strncpy( szAnimationPrefix, pKeyValuesData->GetString( "anim_prefix" ), MAX_WEAPON_PREFIX ); iSlot = pKeyValuesData->GetInt( "bucket", 0 ); iPosition = pKeyValuesData->GetInt( "bucket_position", 0 ); - + // Use the console (X360) buckets if hud_fastswitch is set to 2. #ifdef CLIENT_DLL if ( hud_fastswitch.GetInt() == 2 ) @@ -388,7 +448,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam iWeight = pKeyValuesData->GetInt( "weight", 0 ); iRumbleEffect = pKeyValuesData->GetInt( "rumble", -1 ); - + // LAME old way to specify item flags. // Weapon scripts should use the flag names. iFlags = pKeyValuesData->GetInt( "item_flags", ITEM_FLAG_LIMITINWORLD ); @@ -414,6 +474,18 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam m_bAllowFlipping = ( pKeyValuesData->GetInt( "AllowFlipping", 1 ) != 0 ) ? true : false; m_bMeleeWeapon = ( pKeyValuesData->GetInt( "MeleeWeapon", 0 ) != 0 ) ? true : false; +#ifdef MAPBASE + m_flViewmodelFOV = pKeyValuesData->GetFloat( "viewmodel_fov", 0.0f ); + m_flBobScale = pKeyValuesData->GetFloat( "bob_scale", 1.0f ); + m_flSwayScale = pKeyValuesData->GetFloat( "sway_scale", 1.0f ); + m_flSwaySpeedScale = pKeyValuesData->GetFloat( "sway_speed_scale", 1.0f ); + + Q_strncpy( szDroppedModel, pKeyValuesData->GetString( "droppedmodel" ), MAX_WEAPON_STRING ); + + m_bUsesHands = ( pKeyValuesData->GetInt( "uses_hands", 0 ) != 0 ) ? true : false; +#endif + +#ifndef MAPBASE // Mapbase makes weapons in the same slot & position swap each other out, which is a feature mods can intentionally use. #if defined(_DEBUG) && defined(HL2_CLIENT_DLL) // make sure two weapons aren't in the same slot & position if ( iSlot >= MAX_WEAPON_SLOTS || @@ -430,6 +502,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam } g_bUsedWeaponSlots[iSlot][iPosition] = true; } +#endif #endif // Primary ammo used @@ -439,7 +512,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam else Q_strncpy( szAmmo1, pAmmo, sizeof( szAmmo1 ) ); iAmmoType = GetAmmoDef()->Index( szAmmo1 ); - + // Secondary ammo used pAmmo = pKeyValuesData->GetString( "secondary_ammo", "None" ); if ( strcmp("None", pAmmo) == 0) @@ -462,7 +535,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam } } } - + flBulletSpeed = ( pKeyValuesData->GetFloat( "BulletSpeed", 300 ) * 100 ) / 2; flBulletSize = pKeyValuesData->GetFloat( "BulletSize", 0.0f ); } diff --git a/game/shared/weapon_parse.h b/game/shared/weapon_parse.h index ecdfa7d9..068f2b67 100644 --- a/game/shared/weapon_parse.h +++ b/game/shared/weapon_parse.h @@ -59,7 +59,7 @@ class CHudTexture; class KeyValues; //----------------------------------------------------------------------------- -// Purpose: Contains the data read from the weapon's script file. +// Purpose: Contains the data read from the weapon's script file. // It's cached so we only read each weapon's script file once. // Each game provides a CreateWeaponInfo function so it can have game-specific // data (like CS move speeds) in the weapon script. @@ -69,14 +69,18 @@ class FileWeaponInfo_t public: FileWeaponInfo_t(); - + // Each game can override this to get whatever values it wants from the script. virtual void Parse( KeyValues *pKeyValuesData, const char *szWeaponName ); - -public: + +public: bool bParsedScript; bool bLoadedHudElements; +#ifdef MAPBASE + // Indicates the currently loaded data is from a map-specific script and should be flushed. + bool bCustom; +#endif // SHARED char szClassName[MAX_WEAPON_STRING]; @@ -100,7 +104,7 @@ class FileWeaponInfo_t char szAmmo2[MAX_WEAPON_AMMO_NAME]; // "secondary" ammo type // Sound blocks - char aShootSounds[NUM_SHOOT_SOUND_TYPES][MAX_WEAPON_STRING]; + char aShootSounds[NUM_SHOOT_SOUND_TYPES][MAX_WEAPON_STRING]; int iAmmoType; int iAmmo2Type; @@ -115,6 +119,17 @@ class FileWeaponInfo_t float flBulletSpeed; float flBulletSize; +#ifdef MAPBASE + float m_flViewmodelFOV; + float m_flBobScale; + float m_flSwayScale; + float m_flSwaySpeedScale; + + char szDroppedModel[MAX_WEAPON_STRING]; // Model of this weapon when dropped on the ground + + bool m_bUsesHands; +#endif + // CLIENT DLL // Sprite data, read from the data file int iSpriteCount; @@ -136,8 +151,14 @@ class FileWeaponInfo_t }; // The weapon parse function -bool ReadWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, +bool ReadWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, + WEAPON_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey = NULL ); + +#ifdef MAPBASE +// For map-specific weapon data +bool ReadCustomWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, WEAPON_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey = NULL ); +#endif // If weapon info has been loaded for the specified class name, this returns it. WEAPON_FILE_INFO_HANDLE LookupWeaponInfoSlot( const char *name ); @@ -147,8 +168,8 @@ WEAPON_FILE_INFO_HANDLE GetInvalidWeaponInfoHandle( void ); void PrecacheFileWeaponInfoDatabase( IFileSystem *filesystem, const unsigned char *pICEKey ); -// -// Read a possibly-encrypted KeyValues file in. +// +// Read a possibly-encrypted KeyValues file in. // If pICEKey is NULL, then it appends .txt to the filename and loads it as an unencrypted file. // If pICEKey is non-NULL, then it appends .ctx to the filename and loads it as an encrypted file. // diff --git a/game/shared/weapon_proficiency.h b/game/shared/weapon_proficiency.h index 6532b79c..e91f67cf 100644 --- a/game/shared/weapon_proficiency.h +++ b/game/shared/weapon_proficiency.h @@ -19,6 +19,11 @@ struct WeaponProficiencyInfo_t enum WeaponProficiency_t { +#ifdef MAPBASE + // For the override + WEAPON_PROFICIENCY_INVALID = -1, +#endif + WEAPON_PROFICIENCY_POOR = 0, WEAPON_PROFICIENCY_AVERAGE, WEAPON_PROFICIENCY_GOOD, diff --git a/lib/common/lzma.lib b/lib/common/lzma.lib deleted file mode 100644 index f165ed04..00000000 Binary files a/lib/common/lzma.lib and /dev/null differ diff --git a/lib/common/ubuntu12_32/libssl.a b/lib/common/ubuntu12_32/libssl.a deleted file mode 100644 index a96bdc0a..00000000 Binary files a/lib/common/ubuntu12_32/libssl.a and /dev/null differ diff --git a/lib/public/appframework.lib b/lib/public/appframework.lib index 87f29560..27006981 100644 Binary files a/lib/public/appframework.lib and b/lib/public/appframework.lib differ diff --git a/lib/public/bitmap.lib b/lib/public/bitmap.lib index 0fa0ee6a..944eb864 100644 Binary files a/lib/public/bitmap.lib and b/lib/public/bitmap.lib differ diff --git a/lib/public/choreoobjects.lib b/lib/public/choreoobjects.lib index 98b10324..9d11c2af 100644 Binary files a/lib/public/choreoobjects.lib and b/lib/public/choreoobjects.lib differ diff --git a/lib/common/discord-rpc.lib b/lib/public/discord-rpc.lib similarity index 100% rename from lib/common/discord-rpc.lib rename to lib/public/discord-rpc.lib diff --git a/lib/public/dmxloader.lib b/lib/public/dmxloader.lib index c8a1f3d9..5f61c3bf 100644 Binary files a/lib/public/dmxloader.lib and b/lib/public/dmxloader.lib differ diff --git a/lib/public/fgdlib.lib b/lib/public/fgdlib.lib index f87cb3f8..df0540b1 100644 Binary files a/lib/public/fgdlib.lib and b/lib/public/fgdlib.lib differ diff --git a/lib/public/libz.lib b/lib/public/libz.lib index 15d90ea3..dd8f463a 100644 Binary files a/lib/public/libz.lib and b/lib/public/libz.lib differ diff --git a/lib/public/linux32/bitmap.a b/lib/public/linux32/bitmap.a index 81618a08..cc942c70 100644 Binary files a/lib/public/linux32/bitmap.a and b/lib/public/linux32/bitmap.a differ diff --git a/lib/public/linux32/choreoobjects.a b/lib/public/linux32/choreoobjects.a index ccf44ac1..6c27bc5c 100644 Binary files a/lib/public/linux32/choreoobjects.a and b/lib/public/linux32/choreoobjects.a differ diff --git a/lib/public/linux32/dmxloader.a b/lib/public/linux32/dmxloader.a index 0ec68d06..553ea325 100644 Binary files a/lib/public/linux32/dmxloader.a and b/lib/public/linux32/dmxloader.a differ diff --git a/lib/public/linux32/libSDL2-2.0.so.0 b/lib/public/linux32/libSDL2-2.0.so.0 old mode 100644 new mode 100755 index 4e8ca343..4cb32b6a Binary files a/lib/public/linux32/libSDL2-2.0.so.0 and b/lib/public/linux32/libSDL2-2.0.so.0 differ diff --git a/lib/public/linux32/libSDL2.so b/lib/public/linux32/libSDL2.so deleted file mode 100644 index 027f051a..00000000 --- a/lib/public/linux32/libSDL2.so +++ /dev/null @@ -1 +0,0 @@ -libSDL2-2.0.so.0 \ No newline at end of file diff --git a/lib/public/linux32/libSDL2.so b/lib/public/linux32/libSDL2.so new file mode 120000 index 00000000..027f051a --- /dev/null +++ b/lib/public/linux32/libSDL2.so @@ -0,0 +1 @@ +libSDL2-2.0.so.0 \ No newline at end of file diff --git a/lib/public/linux32/libsteam_api.so b/lib/public/linux32/libsteam_api.so index d4680813..9476561f 100644 Binary files a/lib/public/linux32/libsteam_api.so and b/lib/public/linux32/libsteam_api.so differ diff --git a/lib/public/linux32/libtier0.so b/lib/public/linux32/libtier0.so index 8ba0224f..6cfc8341 100644 Binary files a/lib/public/linux32/libtier0.so and b/lib/public/linux32/libtier0.so differ diff --git a/lib/public/linux32/libvstdlib.so b/lib/public/linux32/libvstdlib.so index fa47f0c5..4a4af170 100644 Binary files a/lib/public/linux32/libvstdlib.so and b/lib/public/linux32/libvstdlib.so differ diff --git a/lib/public/linux32/mathlib.a b/lib/public/linux32/mathlib.a index 51797819..225b51a7 100644 Binary files a/lib/public/linux32/mathlib.a and b/lib/public/linux32/mathlib.a differ diff --git a/lib/public/linux32/matsys_controls.a b/lib/public/linux32/matsys_controls.a index f3c040bf..c389ddf7 100644 Binary files a/lib/public/linux32/matsys_controls.a and b/lib/public/linux32/matsys_controls.a differ diff --git a/lib/public/linux32/particles.a b/lib/public/linux32/particles.a index 41b07209..c2136814 100644 Binary files a/lib/public/linux32/particles.a and b/lib/public/linux32/particles.a differ diff --git a/lib/public/linux32/raytrace.a b/lib/public/linux32/raytrace.a index 575d0f78..881256ad 100644 Binary files a/lib/public/linux32/raytrace.a and b/lib/public/linux32/raytrace.a differ diff --git a/lib/public/linux32/shaderlib.a b/lib/public/linux32/shaderlib.a index cefd152a..062e7b66 100644 Binary files a/lib/public/linux32/shaderlib.a and b/lib/public/linux32/shaderlib.a differ diff --git a/lib/public/linux32/tier1.a b/lib/public/linux32/tier1.a index 4490368f..9fe363f1 100644 Binary files a/lib/public/linux32/tier1.a and b/lib/public/linux32/tier1.a differ diff --git a/lib/public/linux32/tier2.a b/lib/public/linux32/tier2.a index 207aee67..36d454ae 100644 Binary files a/lib/public/linux32/tier2.a and b/lib/public/linux32/tier2.a differ diff --git a/lib/public/linux32/tier3.a b/lib/public/linux32/tier3.a index 4b7ec24a..637239e7 100644 Binary files a/lib/public/linux32/tier3.a and b/lib/public/linux32/tier3.a differ diff --git a/lib/public/linux32/vgui_controls.a b/lib/public/linux32/vgui_controls.a index 12e4ea9e..84aa3533 100644 Binary files a/lib/public/linux32/vgui_controls.a and b/lib/public/linux32/vgui_controls.a differ diff --git a/lib/public/linux32/vtf.a b/lib/public/linux32/vtf.a index c8733982..e0fed546 100644 Binary files a/lib/public/linux32/vtf.a and b/lib/public/linux32/vtf.a differ diff --git a/lib/public/mathlib.lib b/lib/public/mathlib.lib new file mode 100644 index 00000000..9cf2266c Binary files /dev/null and b/lib/public/mathlib.lib differ diff --git a/lib/public/matsys_controls.lib b/lib/public/matsys_controls.lib index d2e68a1a..e8c38ca0 100644 Binary files a/lib/public/matsys_controls.lib and b/lib/public/matsys_controls.lib differ diff --git a/lib/public/nvtristrip.lib b/lib/public/nvtristrip.lib index 8ae02492..9b1d8702 100644 Binary files a/lib/public/nvtristrip.lib and b/lib/public/nvtristrip.lib differ diff --git a/lib/public/osx32/bitmap.a b/lib/public/osx32/bitmap.a index 38abbc8e..3a98ecb5 100644 Binary files a/lib/public/osx32/bitmap.a and b/lib/public/osx32/bitmap.a differ diff --git a/lib/public/osx32/choreoobjects.a b/lib/public/osx32/choreoobjects.a index 3215158e..399df923 100644 Binary files a/lib/public/osx32/choreoobjects.a and b/lib/public/osx32/choreoobjects.a differ diff --git a/lib/public/osx32/dmxloader.a b/lib/public/osx32/dmxloader.a index 27f82331..fb4719ed 100644 Binary files a/lib/public/osx32/dmxloader.a and b/lib/public/osx32/dmxloader.a differ diff --git a/lib/public/osx32/libSDL2-2.0.0.dylib b/lib/public/osx32/libSDL2-2.0.0.dylib index 45278b23..c8dcd704 100644 Binary files a/lib/public/osx32/libSDL2-2.0.0.dylib and b/lib/public/osx32/libSDL2-2.0.0.dylib differ diff --git a/lib/public/osx32/libsteam_api.dylib b/lib/public/osx32/libsteam_api.dylib index 7ffacb8f..80dc4752 100644 Binary files a/lib/public/osx32/libsteam_api.dylib and b/lib/public/osx32/libsteam_api.dylib differ diff --git a/lib/public/osx32/libtier0.dylib b/lib/public/osx32/libtier0.dylib index f0941cb7..65c02e87 100644 Binary files a/lib/public/osx32/libtier0.dylib and b/lib/public/osx32/libtier0.dylib differ diff --git a/lib/public/osx32/libvstdlib.dylib b/lib/public/osx32/libvstdlib.dylib index 8d723863..bcf44739 100644 Binary files a/lib/public/osx32/libvstdlib.dylib and b/lib/public/osx32/libvstdlib.dylib differ diff --git a/lib/public/osx32/mathlib.a b/lib/public/osx32/mathlib.a index 48fa10e0..60f860b0 100644 Binary files a/lib/public/osx32/mathlib.a and b/lib/public/osx32/mathlib.a differ diff --git a/lib/public/osx32/matsys_controls.a b/lib/public/osx32/matsys_controls.a index 6b8e0634..786bcf02 100644 Binary files a/lib/public/osx32/matsys_controls.a and b/lib/public/osx32/matsys_controls.a differ diff --git a/lib/public/osx32/particles.a b/lib/public/osx32/particles.a index 807793ee..2633980c 100644 Binary files a/lib/public/osx32/particles.a and b/lib/public/osx32/particles.a differ diff --git a/lib/public/osx32/raytrace.a b/lib/public/osx32/raytrace.a index 475c9a03..04df13cf 100644 Binary files a/lib/public/osx32/raytrace.a and b/lib/public/osx32/raytrace.a differ diff --git a/lib/public/osx32/shaderlib.a b/lib/public/osx32/shaderlib.a index 34ccb7d3..dbdc3e70 100644 Binary files a/lib/public/osx32/shaderlib.a and b/lib/public/osx32/shaderlib.a differ diff --git a/lib/public/osx32/tier1.a b/lib/public/osx32/tier1.a index 81093003..57974ce2 100644 Binary files a/lib/public/osx32/tier1.a and b/lib/public/osx32/tier1.a differ diff --git a/lib/public/osx32/tier2.a b/lib/public/osx32/tier2.a index 6457180e..e24448c0 100644 Binary files a/lib/public/osx32/tier2.a and b/lib/public/osx32/tier2.a differ diff --git a/lib/public/osx32/tier3.a b/lib/public/osx32/tier3.a index 3e71e482..f6cd2330 100644 Binary files a/lib/public/osx32/tier3.a and b/lib/public/osx32/tier3.a differ diff --git a/lib/public/osx32/vgui_controls.a b/lib/public/osx32/vgui_controls.a index c4797048..8e53ee2d 100644 Binary files a/lib/public/osx32/vgui_controls.a and b/lib/public/osx32/vgui_controls.a differ diff --git a/lib/public/osx32/vtf.a b/lib/public/osx32/vtf.a index 806347fb..ca0c3b05 100644 Binary files a/lib/public/osx32/vtf.a and b/lib/public/osx32/vtf.a differ diff --git a/lib/public/particles.lib b/lib/public/particles.lib index 80fd538d..f451aea4 100644 Binary files a/lib/public/particles.lib and b/lib/public/particles.lib differ diff --git a/lib/public/raytrace.lib b/lib/public/raytrace.lib new file mode 100644 index 00000000..2a3f1d4b Binary files /dev/null and b/lib/public/raytrace.lib differ diff --git a/lib/public/shaderlib.lib b/lib/public/shaderlib.lib index 2d44d4c3..e78628e1 100644 Binary files a/lib/public/shaderlib.lib and b/lib/public/shaderlib.lib differ diff --git a/lib/public/steam_api.lib b/lib/public/steam_api.lib index 28eb8335..44d01ec5 100644 Binary files a/lib/public/steam_api.lib and b/lib/public/steam_api.lib differ diff --git a/lib/public/tier0.lib b/lib/public/tier0.lib index 14afca62..9cfea1a9 100644 Binary files a/lib/public/tier0.lib and b/lib/public/tier0.lib differ diff --git a/lib/public/tier1.lib b/lib/public/tier1.lib new file mode 100644 index 00000000..5effe935 Binary files /dev/null and b/lib/public/tier1.lib differ diff --git a/lib/public/tier2.lib b/lib/public/tier2.lib index 0876b4ed..e9bac91c 100644 Binary files a/lib/public/tier2.lib and b/lib/public/tier2.lib differ diff --git a/lib/public/tier3.lib b/lib/public/tier3.lib index 208ea223..3b99bb05 100644 Binary files a/lib/public/tier3.lib and b/lib/public/tier3.lib differ diff --git a/lib/public/vgui_controls.lib b/lib/public/vgui_controls.lib new file mode 100644 index 00000000..2adab369 Binary files /dev/null and b/lib/public/vgui_controls.lib differ diff --git a/lib/public/vmpi.lib b/lib/public/vmpi.lib index e882e1c1..4080914a 100644 Binary files a/lib/public/vmpi.lib and b/lib/public/vmpi.lib differ diff --git a/lib/public/vstdlib.lib b/lib/public/vstdlib.lib index 147a915e..2e6ffe27 100644 Binary files a/lib/public/vstdlib.lib and b/lib/public/vstdlib.lib differ diff --git a/lib/public/vtf.lib b/lib/public/vtf.lib index 6ff23e83..5d35a3e7 100644 Binary files a/lib/public/vtf.lib and b/lib/public/vtf.lib differ diff --git a/materialsystem/ishadersystem.h b/materialsystem/ishadersystem.h new file mode 100644 index 00000000..049f7e1f --- /dev/null +++ b/materialsystem/ishadersystem.h @@ -0,0 +1,104 @@ +//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +// An interface that should not ever be accessed directly from shaders +// but instead is visible only to shaderlib. +//===========================================================================// + +#ifndef ISHADERSYSTEM_H +#define ISHADERSYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +enum Sampler_t; +class ITexture; +class IShader; + + +//----------------------------------------------------------------------------- +// The Shader system interface version +//----------------------------------------------------------------------------- +#define SHADERSYSTEM_INTERFACE_VERSION "ShaderSystem002" + + +//----------------------------------------------------------------------------- +// Modulation flags +//----------------------------------------------------------------------------- +enum +{ + SHADER_USING_COLOR_MODULATION = 0x1, + SHADER_USING_ALPHA_MODULATION = 0x2, + SHADER_USING_FLASHLIGHT = 0x4, + SHADER_USING_FIXED_FUNCTION_BAKED_LIGHTING = 0x8, + SHADER_USING_EDITOR = 0x10, +}; + + +//----------------------------------------------------------------------------- +// The shader system (a singleton) +//----------------------------------------------------------------------------- +abstract_class IShaderSystem +{ +public: + virtual ShaderAPITextureHandle_t GetShaderAPITextureBindHandle( ITexture *pTexture, int nFrameVar, int nTextureChannel = 0 ) =0; + + // Binds a texture + virtual void BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrameVar = 0 ) = 0; + virtual void BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrameVar = 0 ) = 0; + + // Takes a snapshot + virtual void TakeSnapshot( ) = 0; + + // Draws a snapshot + virtual void DrawSnapshot( bool bMakeActualDrawCall = true ) = 0; + + // Are we using graphics? + virtual bool IsUsingGraphics() const = 0; + + // Are we using graphics? + virtual bool CanUseEditorMaterials() const = 0; +}; + + +//----------------------------------------------------------------------------- +// The Shader plug-in DLL interface version +//----------------------------------------------------------------------------- +#define SHADER_DLL_INTERFACE_VERSION "ShaderDLL004" + + +//----------------------------------------------------------------------------- +// The Shader interface versions +//----------------------------------------------------------------------------- +abstract_class IShaderDLLInternal +{ +public: + // Here's where the app systems get to learn about each other + virtual bool Connect( CreateInterfaceFn factory, bool bIsMaterialSystem ) = 0; + virtual void Disconnect( bool bIsMaterialSystem ) = 0; + + // Returns the number of shaders defined in this DLL + virtual int ShaderCount() const = 0; + + // Returns information about each shader defined in this DLL + virtual IShader *GetShader( int nShader ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Singleton interface +//----------------------------------------------------------------------------- +IShaderDLLInternal *GetShaderDLLInternal(); + + +#endif // ISHADERSYSTEM_H diff --git a/materialsystem/stdshaders/AccumBuff4Sample.cpp b/materialsystem/stdshaders/AccumBuff4Sample.cpp deleted file mode 100644 index 61a58104..00000000 --- a/materialsystem/stdshaders/AccumBuff4Sample.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//========= Copyright 1996-2005, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "BaseVSShader.h" -#include "common_hlsl_cpp_consts.h" -#include "screenspaceeffect_vs20.inc" -#include "accumbuff4sample_ps20.inc" -#include "accumbuff4sample_ps20b.inc" -#include "convar.h" - -BEGIN_VS_SHADER_FLAGS( accumbuff4sample, "Help for AccumBuff4Sample", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - - // Four textures to sample - SHADER_PARAM( TEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - - // Corresponding weights for the four input textures - SHADER_PARAM( WEIGHTS, SHADER_PARAM_TYPE_VEC4, "", "Weight for Samples" ) - - END_SHADER_PARAMS - - SHADER_INIT - { - LoadTexture( TEXTURE0 ); - LoadTexture( TEXTURE1 ); - LoadTexture( TEXTURE2 ); - LoadTexture( TEXTURE3 ); - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if (!g_pHardwareConfig->SupportsVertexAndPixelShaders()) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - pShaderShadow->EnableAlphaWrites( false ); - pShaderShadow->EnableBlending( false ); - pShaderShadow->EnableCulling( false ); -// pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( accumbuff4sample_ps20b ); - SET_STATIC_PIXEL_SHADER( accumbuff4sample_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( accumbuff4sample_ps20 ); - SET_STATIC_PIXEL_SHADER( accumbuff4sample_ps20 ); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, TEXTURE0, -1 ); - BindTexture( SHADER_SAMPLER1, TEXTURE1, -1 ); - BindTexture( SHADER_SAMPLER2, TEXTURE2, -1 ); - BindTexture( SHADER_SAMPLER3, TEXTURE3, -1 ); - - SetPixelShaderConstant( 0, WEIGHTS ); - - DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( accumbuff4sample_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( accumbuff4sample_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( accumbuff4sample_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( accumbuff4sample_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/AccumBuff4Sample_ps2x.fxc b/materialsystem/stdshaders/AccumBuff4Sample_ps2x.fxc deleted file mode 100644 index 1a0fb967..00000000 --- a/materialsystem/stdshaders/AccumBuff4Sample_ps2x.fxc +++ /dev/null @@ -1,31 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler TexSampler0 : register( s0 ); -sampler TexSampler1 : register( s1 ); -sampler TexSampler2 : register( s2 ); -sampler TexSampler3 : register( s3 ); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - -const float4 weights : register( c0 ); - -float4 main( PS_INPUT i ) : COLOR -{ - // Just sample the four input textures - float4 sample0 = tex2D( TexSampler0, i.texCoord ); - float4 sample1 = tex2D( TexSampler1, i.texCoord ); - float4 sample2 = tex2D( TexSampler2, i.texCoord ); - float4 sample3 = tex2D( TexSampler3, i.texCoord ); - - // Compute weighted average and return - return FinalOutput( weights.x * sample0 + - weights.y * sample1 + - weights.z * sample2 + - weights.w * sample3, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/BaseVSShader.cpp b/materialsystem/stdshaders/BaseVSShader.cpp deleted file mode 100644 index 68331196..00000000 --- a/materialsystem/stdshaders/BaseVSShader.cpp +++ /dev/null @@ -1,1215 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// This is what all vs/ps (dx8+) shaders inherit from. -//===========================================================================// -#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX8_DLL_EXPORT) || defined(STDSHADER_DX9_DLL_EXPORT) - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" -#include "mathlib/bumpvects.h" -#include "cpp_shader_constant_register_map.h" -#include "convar.h" - - -#include "lightmappedgeneric_flashlight_vs30.inc" -#include "flashlight_ps30.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); - -// These functions are to be called from the shaders. - -//----------------------------------------------------------------------------- -// Pixel and vertex shader constants.... -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; - Assert( pPixelVar2 ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 3 ); - } - else - { - val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); - } - - val[3] = pPixelVar2->GetFloatValue(); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; - Assert( pPixelVar2 ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 3 ); - } - else - { - val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); - } - - val[3] = pPixelVar2->GetFloatValue(); - val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); - val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); - val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); - - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - val[3]=fWValue; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - - val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); - val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); - val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); - - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) -{ - int i; - for( i = 0; i < numConst; i++ ) - { - float vec[4]; - vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); - vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); - vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); - vec[3] = pVec[i*4+3]; - - s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce ); - } -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) -{ - int i; - for( i = 0; i < numConst; i++ ) - { - float vec[4]; - vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); - vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); - vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); - - vec[3] = pVec[i*4+3]; - - s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce ); - } -} - -// GR - special version with fix for const/lerp issue -void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 4 ); - val[0] = val[0] * 0.992f + 0.0078f; - val[1] = val[1] * 0.992f + 0.0078f; - val[2] = val[2] * 0.992f + 0.0078f; - val[3] = val[3] * 0.992f + 0.0078f; - } - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pVertexVar = s_ppParams[constantVar]; - Assert( pVertexVar ); - - float val[4]; - if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pVertexVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue(); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, val ); -} - -//----------------------------------------------------------------------------- -// Sets normalized light color for pixel shaders. -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderLightColors( int pixelReg ) -{ - int i; - int maxLights = s_pShaderAPI->GetMaxLights(); - for( i = 0; i < maxLights; i++ ) - { - const LightDesc_t & lightDesc = s_pShaderAPI->GetLight( i ); - if( lightDesc.m_Type != MATERIAL_LIGHT_DISABLE ) - { - Vector color( lightDesc.m_Color[0], lightDesc.m_Color[1], lightDesc.m_Color[2] ); - VectorNormalize( color ); - float val[4] = { color[0], color[1], color[2], 1.0f }; - s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, val, 1 ); - } - else - { - float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, zero, 1 ); - } - } -} - - -//----------------------------------------------------------------------------- -// Sets vertex shader texture transforms -//----------------------------------------------------------------------------- -void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar ) -{ - float offset[2] = {0, 0}; - - IMaterialVar* pTranslationVar = s_ppParams[translationVar]; - if (pTranslationVar) - { - if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pTranslationVar->GetVecValue( offset, 2 ); - else - offset[0] = offset[1] = pTranslationVar->GetFloatValue(); - } - - Vector4D translation[2]; - translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); - translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar ) -{ - float scale[2] = {1, 1}; - - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale, 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - Vector4D scaleMatrix[2]; - scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); - scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - - Vector2D scale( 1, 1 ); - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale.Base(), 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - // Apply the scaling - transformation[0][0] *= scale[0]; - transformation[0][1] *= scale[1]; - transformation[1][0] *= scale[0]; - transformation[1][1] *= scale[1]; - transformation[0][3] *= scale[0]; - transformation[1][3] *= scale[1]; - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); -} - - -//----------------------------------------------------------------------------- -// Sets pixel shader texture transforms -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar ) -{ - float offset[2] = {0, 0}; - - IMaterialVar* pTranslationVar = s_ppParams[translationVar]; - if (pTranslationVar) - { - if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pTranslationVar->GetVecValue( offset, 2 ); - else - offset[0] = offset[1] = pTranslationVar->GetFloatValue(); - } - - Vector4D translation[2]; - translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); - translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar ) -{ - float scale[2] = {1, 1}; - - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale, 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - Vector4D scaleMatrix[2]; - scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); - scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - - Vector2D scale( 1, 1 ); - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale.Base(), 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - // Apply the scaling - transformation[0][0] *= scale[0]; - transformation[0][1] *= scale[1]; - transformation[1][0] *= scale[0]; - transformation[1][1] *= scale[1]; - transformation[0][3] *= scale[0]; - transformation[1][3] *= scale[1]; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); -} - - -//----------------------------------------------------------------------------- -// Moves a matrix into vertex shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::SetVertexShaderMatrix2x4( int vertexReg, int matrixVar ) -{ - IMaterialVar* pTranslationVar = s_ppParams[ matrixVar ]; - if ( pTranslationVar ) - { - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue()[ 0 ][ 0 ], 2 ); - } - else - { - VMatrix matrix; - MatrixSetIdentity( matrix ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[ 0 ][ 0 ], 2 ); - } -} - -void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ) -{ - IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; - if (pTranslationVar) - { - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 ); - } - else - { - VMatrix matrix; - MatrixSetIdentity( matrix ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 ); - } -} - -void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ) -{ - IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; - if (pTranslationVar) - { - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 ); - } - else - { - VMatrix matrix; - MatrixSetIdentity( matrix ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 ); - } -} - - -//----------------------------------------------------------------------------- -// Loads the view matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix mat, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); - - MatrixTranspose( mat, transpose ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 ); -} - - -//----------------------------------------------------------------------------- -// Loads the projection matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix mat, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mat.m[0] ); - - MatrixTranspose( mat, transpose ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 ); -} - - -//----------------------------------------------------------------------------- -// Loads the projection matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix view, model, modelView, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] ); - MatrixTranspose( model, model ); - s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] ); - MatrixTranspose( view, view ); - - MatrixMultiply( view, model, modelView ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 ); -} - -//----------------------------------------------------------------------------- -// Loads a scale/offset version of the viewport transform into the specified constant. -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ) -{ - ShaderViewport_t viewport; - - s_pShaderAPI->GetViewports( &viewport, 1 ); - - int bbWidth = 0, - bbHeight = 0; - - s_pShaderAPI->GetBackBufferDimensions( bbWidth, bbHeight ); - - // (x, y, z, w) = (Width / bbWidth, Height / bbHeight, MinX / bbWidth, MinY / bbHeight) - Vector4D viewportTransform( - 1.0f * viewport.m_nWidth / bbWidth, - 1.0f * viewport.m_nHeight / bbHeight, - 1.0f * viewport.m_nTopLeftX / bbWidth, - 1.0f * viewport.m_nTopLeftY / bbHeight - ); - - s_pShaderAPI->SetVertexShaderConstant( vertexReg, viewportTransform.Base() ); -} - - - -//----------------------------------------------------------------------------- -// Loads bump lightmap coordinates into the pixel shader -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ) -{ - Vector4D basis[3]; - for (int i = 0; i < 3; ++i) - { - memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 ); -} - - -//----------------------------------------------------------------------------- -// Loads bump lightmap coordinates into the pixel shader -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ) -{ - Vector4D basis[3]; - - // transpose - int i; - for (i = 0; i < 3; ++i) - { - basis[i][0] = g_localBumpBasis[0][i]; - basis[i][1] = g_localBumpBasis[1][i]; - basis[i][2] = g_localBumpBasis[2][i]; - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 ); - for (i = 0; i < 3; ++i) - { - memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 ); -} - - -//----------------------------------------------------------------------------- -// Helper methods for pixel shader overbrighting -//----------------------------------------------------------------------------- -void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ) -{ - // can't have other overbright values with pixel shaders as it stands. - float v[4]; - if( bEnable ) - { - v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT; - } - else - { - v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f; - } - s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 ); -} - - -//----------------------------------------------------------------------------- -// Helper for dealing with modulation -//----------------------------------------------------------------------------- -void CBaseVSShader::SetModulationVertexShaderDynamicState() -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState( int modulationVar ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); - color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); - color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); - - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale; - color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale; - color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale; - - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - - -//----------------------------------------------------------------------------- -// Converts a color + alpha into a vector4 -//----------------------------------------------------------------------------- -void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ) -{ - color.Init( 1.0, 1.0, 1.0, 1.0 ); - if ( colorVar != -1 ) - { - IMaterialVar* pColorVar = s_ppParams[colorVar]; - if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR ) - { - pColorVar->GetVecValue( color.Base(), 3 ); - } - else - { - color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); - } - } - if ( alphaVar != -1 ) - { - float flAlpha = s_ppParams[alphaVar]->GetFloatValue(); - color[3] = clamp( flAlpha, 0.0f, 1.0f ); - } -} - - -//----------------------------------------------------------------------------- -// Sets a color + alpha into shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ) -{ - Vector4D color; - ColorVarsToVector( colorVar, alphaVar, color ); - s_pShaderAPI->SetVertexShaderConstant( nVertexReg, color.Base() ); -} - -void CBaseVSShader::SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ) -{ - Vector4D color; - ColorVarsToVector( colorVar, alphaVar, color ); - s_pShaderAPI->SetPixelShaderConstant( nPixelReg, color.Base() ); -} - -#ifdef _DEBUG -ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" ); -ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" ); -#endif - -//----------------------------------------------------------------------------- -// Helpers for dealing with envmap tint -//----------------------------------------------------------------------------- -// set alphaVar to -1 to ignore it. -void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) -{ - float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) - { - IMaterialVar* pAlphaVar = NULL; - if( alphaVar >= 0 ) - { - pAlphaVar = s_ppParams[alphaVar]; - } - if( pAlphaVar ) - { - color[3] = pAlphaVar->GetFloatValue(); - } - - IMaterialVar* pTintVar = s_ppParams[tintVar]; -#ifdef _DEBUG - pTintVar->GetVecValue( color, 3 ); - - float envmapTintOverride = mat_envmaptintoverride.GetFloat(); - float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); - - if( envmapTintOverride != -1.0f ) - { - color[0] = color[1] = color[2] = envmapTintOverride; - } - if( envmapTintScaleOverride != -1.0f ) - { - color[0] *= envmapTintScaleOverride; - color[1] *= envmapTintScaleOverride; - color[2] *= envmapTintScaleOverride; - } - - if( bConvertFromGammaToLinear ) - { - color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); - color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); - color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); - } -#else - if( bConvertFromGammaToLinear ) - { - pTintVar->GetLinearVecValue( color, 3 ); - } - else - { - pTintVar->GetVecValue( color, 3 ); - } -#endif - } - else - { - color[0] = color[1] = color[2] = color[3] = 0.0f; - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); -} - -void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( ) -{ - s_pShaderAPI->SetVertexShaderStateAmbientLightCube(); -} - -float CBaseVSShader::GetAmbientLightCubeLuminance( ) -{ - return s_pShaderAPI->GetAmbientLightCubeLuminance(); -} - -//----------------------------------------------------------------------------- -// Sets up hw morphing state for the vertex shader -//----------------------------------------------------------------------------- -void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ) -{ -#ifndef _X360 - if ( !s_pShaderAPI->IsHWMorphingEnabled() ) - return; - - int nMorphWidth, nMorphHeight; - s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); - - int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); - float pMorphAccumSize[4] = { (float)nMorphWidth, (float)nMorphHeight, (float)nDim, 0.0f }; - s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize ); - - int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); - int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); - int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); - int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); - float pMorphAccumSubrect[4] = { (float)nXOffset, (float)nYOffset, (float)nWidth, (float)nHeight }; - s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect ); - - s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); -#endif -} - - -//----------------------------------------------------------------------------- -// GR - translucency query -//----------------------------------------------------------------------------- -BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, - int detailTextureVar ) -{ - // Either we've got a constant modulation - bool isTranslucent = IsAlphaModulating(); - - // Or we've got a vertex alpha - isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); - - // Or we've got a texture alpha (for blending or alpha test) - isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && - !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); - - if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) - { - isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); - } - - if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) - { - return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive - } - else - { - return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending - } -} - - -void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ) -{ - Assert( !IsSnapshotting() ); - - VMatrix worldToTexture; - const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture ); - - // Set the flashlight origin - float pos[4]; - pos[0] = flashlightState.m_vecLightOrigin[0]; - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this - - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 ); - - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 ); - - // Set the flashlight attenuation factors - float atten[4]; - atten[0] = flashlightState.m_fConstantAtten; - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 ); - - if ( bDetail ) - { - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar ); - } - - if( bSetTextureTransforms ) - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM ); - if( !bDetail && bBump && bumpTransformVar != -1 ) - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform - } - } -} - - -#if defined(STDSHADER_DX9_DLL_EXPORT) || defined(STDSHADER) -void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ) -{ - // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric - if( !vars.m_bLightmappedGeneric ) - { - vars.m_bBump = false; - } - bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); - bool bSeamless = vars.m_fSeamlessScale != 0.0; - bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1); - - bool bRoughness = vars.m_nRoughness != -1 && params[vars.m_nRoughness]->IsTexture(); - bool bMetallic = vars.m_nMetallic != -1 && params[vars.m_nMetallic]->IsTexture(); - - int nDetailBlendMode = 0; - if ( bDetail ) - { - nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); - nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; - } - - if( pShaderShadow ) - { - SetInitialShadowState(); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( false ); - - // Alpha blend - SetAdditiveBlendingShadowState( BASETEXTURE, true ); - - // Alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); - if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); - } - - // Spot sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - // Base sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - - // Normalizing cubemap sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // Normalizing cubemap sampler2 or normal map sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - // RandomRotation sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - - // Flashlight depth sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); - - if( vars.m_bWorldVertexTransition ) - { - // $basetexture2 - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); - } - if( bBump2 ) - { - // Normalmap2 sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); - } - if( bDetail ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler - if ( nDetailBlendMode != 0 ) //Not Mod2X - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); - } - - pShaderShadow->EnableTexture(SHADER_SAMPLER9, true); // roughness sampler - pShaderShadow->EnableTexture(SHADER_SAMPLER10, true); // metallic sampler - - pShaderShadow->EnableSRGBWrite( true ); - - if( vars.m_bLightmappedGeneric ) - { - lightmappedgeneric_flashlight_vs30_Static_Index vshIndex; - vshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); - vshIndex.SetNORMALMAP( vars.m_bBump ); - vshIndex.SetSEAMLESS( bSeamless ); - vshIndex.SetDETAIL( bDetail ); - pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs30", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - if( vars.m_bBump ) - { - flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; - } - int numTexCoords = 1; - if( vars.m_bWorldVertexTransition ) - { - flags |= VERTEX_COLOR; - numTexCoords = 2; // need lightmap texcoords to get alpha. - } - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - } - /*else - { - vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; - vshIndex.SetTEETH( vars.m_bTeeth ); - pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int numTexCoords = 1; - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 ); - }*/ - - int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); - flashlight_ps30_Static_Index pshIndex; - pshIndex.SetNORMALMAP(vars.m_bBump ? 1 : 0); - pshIndex.SetNORMALMAP2( bBump2 ); - pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); - pshIndex.SetSEAMLESS( bSeamless ); - pshIndex.SetDETAILTEXTURE( bDetail ); - pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); - pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode ); - pShaderShadow->SetPixelShader( "flashlight_ps30", pshIndex.GetIndex() ); - - FogToBlack(); - } - else - { - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - - SetFlashLightColorFromState( flashlightState, pShaderAPI ); - - BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) - { - BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - - // Tweaks associated with a given flashlight - float tweaks[4]; - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - } - - if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - if( vars.m_bWorldVertexTransition ) - { - Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); - BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); - } - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); - if( vars.m_bBump ) - { - BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); - } - - if( bDetail ) - { - BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); - } - - if( vars.m_bWorldVertexTransition ) - { - if( bBump2 ) - { - BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); - } - } - - if (bRoughness) - { - BindTexture(SHADER_SAMPLER9, vars.m_nRoughness); - } - else - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER9, TEXTURE_WHITE); - } - if (bMetallic) - { - BindTexture(SHADER_SAMPLER10, vars.m_nRoughness); - } - else - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER10, TEXTURE_BLACK); - } - - if( vars.m_bLightmappedGeneric ) - { - DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 ); - if ( bSeamless ) - { - float const0[4]={ vars.m_fSeamlessScale,0,0,0}; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); - } - - if ( bDetail ) - { - float vDetailConstants[4] = {1,1,1,1}; - - if ( vars.m_nDetailTint != -1 ) - { - params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); - } - - if ( vars.m_nDetailTextureBlendFactor != -1 ) - { - vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); - } - - pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); - } - } - /*else - { - vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if( vars.m_bTeeth ) - { - Assert( vars.m_nTeethForwardVar >= 0 ); - Assert( vars.m_nTeethIllumFactorVar >= 0 ); - Vector4D lighting; - params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); - lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); - } - }*/ - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - - pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1); - - // Set the flashlight origin - float pos[4]; - pos[0] = flashlightState.m_vecLightOrigin[0]; - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pos[3] = 1.0f / ((0.6f * flashlightState.m_FarZ) - flashlightState.m_FarZ); // DX8 needs this - pShaderAPI->SetPixelShaderConstant(PSREG_FRESNEL_SPEC_PARAMS, pos, 1); - - DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); - SET_DYNAMIC_PIXEL_SHADER(flashlight_ps30); - - - float atten[4]; // Set the flashlight attenuation factors - atten[0] = flashlightState.m_fConstantAtten; - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); - } - Draw(); -} - -#endif - -#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT - - -// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering... -void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ) -{ - const int nTexRes = 32; - int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes; - - int nRow = nSeed / nTexRes; - int nCol = nSeed % nTexRes; - - // Div and mod to get an individual texel in the fTexRes x fTexRes grid - *fU = nRow / (float) nTexRes; // Row - *fV = nCol / (float) nTexRes; // Column -} - - -void CBaseVSShader::DrawEqualDepthToDestAlpha( void ) -{ -#if defined(STDSHADER_DX9_DLL_EXPORT) || defined(STDSHADER) - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - bool bMakeActualDrawCall = false; - if( s_pShaderShadow ) - { - s_pShaderShadow->EnableColorWrites( false ); - s_pShaderShadow->EnableAlphaWrites( true ); - s_pShaderShadow->EnableDepthWrites( false ); - s_pShaderShadow->EnableAlphaTest( false ); - s_pShaderShadow->EnableBlending( false ); - - s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - - s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 ); - s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 ); - } - if( s_pShaderAPI ) - { - s_pShaderAPI->SetVertexShaderIndex( 0 ); - s_pShaderAPI->SetPixelShaderIndex( 0 ); - - bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha(); - } - Draw( bMakeActualDrawCall ); - } -#else - Assert( 0 ); //probably just needs a shader update to the latest -#endif -} diff --git a/materialsystem/stdshaders/BaseVSShader.h b/materialsystem/stdshaders/BaseVSShader.h deleted file mode 100644 index 1e30572f..00000000 --- a/materialsystem/stdshaders/BaseVSShader.h +++ /dev/null @@ -1,329 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// This is what all vs/ps (dx8+) shaders inherit from. -//===========================================================================// - -#ifndef BASEVSSHADER_H -#define BASEVSSHADER_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "shaderlib/cshader.h" -#include "shaderlib/BaseShader.h" -#include "convar.h" -#include - -#ifdef _X360 -#define SUPPORT_DX8 0 -#define SUPPORT_DX7 0 -#else -#define SUPPORT_DX8 1 -#define SUPPORT_DX7 1 -#endif -//----------------------------------------------------------------------------- -// Helper macro for vertex shaders -//----------------------------------------------------------------------------- -#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags ) -#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 ) - - -// useful parameter initialization macro -#define INIT_FLOAT_PARM( parm, value ) \ - if ( !params[(parm)]->IsDefined() ) \ - { \ - params[(parm)]->SetFloatValue( (value) ); \ - } - -// useful pixel shader declaration macro for ps20/20b c++ code -#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ - { \ - DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \ - SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \ - } \ - else \ - { \ - DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \ - SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \ - } - -#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ - { \ - DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ - SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ - } \ - else \ - { \ - DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ - SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ - } - - -//----------------------------------------------------------------------------- -// Base class for shaders, contains helper methods. -//----------------------------------------------------------------------------- -class CBaseVSShader : public CBaseShader -{ -public: - - // Loads bump lightmap coordinates into the pixel shader - void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ); - - // Loads bump lightmap coordinates into the vertex shader - void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ); - - // Pixel and vertex shader constants.... - void SetPixelShaderConstant( int pixelReg, int constantVar ); - - // Pixel and vertex shader constants.... - void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ); - - // This version will put constantVar into x,y,z, and constantVar2 into the w - void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ); - void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ); - - // Helpers for setting constants that need to be converted to linear space (from gamma space). - void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); - void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); - - void SetVertexShaderConstant( int vertexReg, int constantVar ); - - // set rgb components of constant from a color parm and give an explicit w value - void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ); - - // GR - fix for const/lerp issues - void SetPixelShaderConstantFudge( int pixelReg, int constantVar ); - - // Sets light direction for pixel shaders. - void SetPixelShaderLightColors( int pixelReg ); - - // Sets vertex shader texture transforms - void SetVertexShaderTextureTranslation( int vertexReg, int translationVar ); - void SetVertexShaderTextureScale( int vertexReg, int scaleVar ); - void SetVertexShaderTextureTransform( int vertexReg, int transformVar ); - void SetVertexShaderTextureScaledTransform( int vertexReg, - int transformVar, int scaleVar ); - - // Set pixel shader texture transforms - void SetPixelShaderTextureTranslation( int pixelReg, int translationVar ); - void SetPixelShaderTextureScale( int pixelReg, int scaleVar ); - void SetPixelShaderTextureTransform( int pixelReg, int transformVar ); - void SetPixelShaderTextureScaledTransform( int pixelReg, - int transformVar, int scaleVar ); - - // Moves a matrix into vertex shader constants - void SetVertexShaderMatrix2x4( int vertexReg, int matrixVar ); - void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ); - void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ); - - // Loads the view matrix into vertex shader constants - void LoadViewMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads the projection matrix into vertex shader constants - void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads the model->view matrix into vertex shader constants - void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads a scale/offset version of the viewport transform into the specified constant. - void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ); - - // Sets up ambient light cube... - void SetAmbientCubeDynamicStateVertexShader( ); - float GetAmbientLightCubeLuminance( ); - - // Helpers for dealing with envmaptint - void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false ); - - // Helper methods for pixel shader overbrighting - void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ); - - // Helper for dealing with modulation - void SetModulationVertexShaderDynamicState(); - void SetModulationPixelShaderDynamicState( int modulationVar ); - void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ); - void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ); - - // Sets a color + alpha into shader constants - void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ); - void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ); - - // Sets up hw morphing state for the vertex shader - void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ); - - void SetFlashlightVertexShaderConstants(bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms); - - struct DrawFlashlight_dx90_Vars_t - { - DrawFlashlight_dx90_Vars_t() - { - // set all ints to -1 - memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) ); - // set all bools to a default value. - m_bBump = false; - m_bLightmappedGeneric = false; - m_bWorldVertexTransition = false; - m_bTeeth = false; - m_bSSBump = false; - m_fSeamlessScale = 0.0; - } - bool m_bBump; - bool m_bLightmappedGeneric; - bool m_bWorldVertexTransition; - bool m_bTeeth; - int m_nBumpmapVar; - int m_nBumpmapFrame; - int m_nBumpTransform; - int m_nFlashlightTextureVar; - int m_nFlashlightTextureFrameVar; - int m_nBaseTexture2Var; - int m_nBaseTexture2FrameVar; - int m_nBumpmap2Var; - int m_nBumpmap2Frame; - int m_nBump2Transform; - int m_nDetailVar; - int m_nDetailScale; - int m_nDetailTextureCombineMode; - int m_nDetailTextureBlendFactor; - int m_nDetailTint; - int m_nTeethForwardVar; - int m_nTeethIllumFactorVar; - int m_nAlphaTestReference; - bool m_bSSBump; - float m_fSeamlessScale; // 0.0 = not seamless - - int m_nRoughness; - int m_nMetallic; - }; - void DrawFlashlight_dx90( IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ); - - BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); - - void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ); - - //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth. - //This pass fills in the areas that passed the alpha test with depth in dest alpha - //by writing only equal depth pixels and only if we should be writing depth to dest alpha - void DrawEqualDepthToDestAlpha( void ); - -private: - // Helper methods for VertexLitGenericPass -// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin ); - void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar, - int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar, - int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar, - int envmapMaskScaleVar, int envmapTintVar ); - - // Converts a color + alpha into a vector4 - void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ); - -}; - -FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false ) -{ - // Old code - //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; - //float flFlashlightScale = 1.0f / flToneMapScale; - - // Fix to old code to keep flashlight from ever getting brighter than 1.0 - //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; - //if ( flToneMapScale < 1.0f ) - // flToneMapScale = 1.0f; - //float flFlashlightScale = 1.0f / flToneMapScale; - - // Force flashlight to 25% bright always - float flFlashlightScale = 0.25f; - - if ( !g_pHardwareConfig->GetHDREnabled() ) - { - // Non-HDR path requires 2.0 flashlight - flFlashlightScale = 2.0f; - } - - // DX10 requires some hackery due to sRGB/blend ordering change from DX9 - if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) - { - flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 - } - - // Generate pixel shader constant - float const *pFlashlightColor = state.m_Color; - float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; - vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term - - // Red flashlight for testing - //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f; - - pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst ); -} - -FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state ) -{ - // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light - if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) - return state.m_flShadowAtten * 0.1f; // magic number - - return state.m_flShadowAtten; -} - -FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state ) -{ - // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that - return state.m_flShadowFilterSize / 1024.0f; -} - - -// convenient material variable access functions for helpers to use. -FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params ) -{ - return ( nVar != -1 ) && ( params[nVar]->IsTexture() ); -} - -FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params ) -{ - return ( nVar != -1 ) && ( params[nVar]->GetIntValue() ); -} - -FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 ) -{ - return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue; -} - -FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 ) -{ - return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue; -} - -FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue ) -{ - if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) - { - params[nIndex]->SetFloatValue( flValue ); - } -} - -FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue ) -{ - if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) - { - params[nIndex]->SetIntValue( nValue ); - } -} - - -class ConVar; - -#ifdef _DEBUG -extern ConVar mat_envmaptintoverride; -extern ConVar mat_envmaptintscale; -#endif - - -#endif // BASEVSSHADER_H diff --git a/materialsystem/stdshaders/Bloom.cpp b/materialsystem/stdshaders/Bloom.cpp deleted file mode 100644 index 67dab81b..00000000 --- a/materialsystem/stdshaders/Bloom.cpp +++ /dev/null @@ -1,73 +0,0 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "SDK_screenspaceeffect_vs30.inc" -#include "SDK_Bloom_ps30.inc" - -BEGIN_VS_SHADER_FLAGS( SDK_Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) - SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[FBTEXTURE]->IsDefined() ) - { - LoadTexture( FBTEXTURE ); - } - if( params[BLURTEXTURE]->IsDefined() ) - { - LoadTexture( BLURTEXTURE ); - } - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps30 ); - SET_STATIC_PIXEL_SHADER(sdk_bloom_ps30); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); - DECLARE_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps30 ); - SET_DYNAMIC_PIXEL_SHADER(sdk_bloom_ps30); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/BlurFilterX.cpp b/materialsystem/stdshaders/BlurFilterX.cpp deleted file mode 100644 index f462423a..00000000 --- a/materialsystem/stdshaders/BlurFilterX.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" -#include "BlurFilter_vs20.inc" -#include "BlurFilter_ps20.inc" -#include "BlurFilter_ps20b.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER_FLAGS( BlurFilterX, "Help for BlurFilterX", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "BlurFilterX_DX80"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); - - // Render targets are pegged as sRGB on POSIX, so just force these reads and writes - bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); - pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); - - // Pre-cache shaders - blurfilter_vs20_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "BlurFilter_vs20", vshIndex.GetIndex() ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) - { - DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); -#ifndef _X360 - SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); -#endif - SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); - SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); - } - - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); - - float v[4]; - - // The temp buffer is 1/4 back buffer size - ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); - int width = src_texture->GetActualWidth(); - float dX = 1.0f / width; - - // Tap offsets - v[0] = 1.3366f * dX; - v[1] = 0.0f; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); - v[0] = 3.4295f * dX; - v[1] = 0.0f; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); - v[0] = 5.4264f * dX; - v[1] = 0.0f; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); - - v[0] = 7.4359f * dX; - v[1] = 0.0f; - pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); - v[0] = 9.4436f * dX; - v[1] = 0.0f; - pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); - v[0] = 11.4401f * dX; - v[1] = 0.0f; - pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); - v[0] = v[1] = v[2] = v[3] = 1.0; - pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); - - pShaderAPI->SetVertexShaderIndex( 0 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/BlurFilterX_dx80.cpp b/materialsystem/stdshaders/BlurFilterX_dx80.cpp deleted file mode 100644 index 6eecfef2..00000000 --- a/materialsystem/stdshaders/BlurFilterX_dx80.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//===========================================================================// - -#include "BaseVSShader.h" -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( BlurFilterX, BlurFilterX_DX80 ) - -BEGIN_VS_SHADER_FLAGS( BlurFilterX_DX80, "Help for BlurFilterX_DX80", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) - { - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); - - // Pre-cache shaders - pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); - pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); - - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); - - // The temp buffer is 1/4 back buffer size - ITexture *src_texture=params[BASETEXTURE]->GetTextureValue(); - int width = src_texture->GetActualWidth(); - float dX = 2.0f / width; - - // 4 Tap offsets, expected from pixel center - float v[4][4]; - v[0][0] = -1.5f * dX; - v[0][1] = 0; - v[1][0] = -0.5f * dX; - v[1][1] = 0; - v[2][0] = 0.5f * dX; - v[2][1] = 0; - v[3][0] = 1.5f * dX; - v[3][1] = 0; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); - - v[0][0] = v[0][1] = v[0][2] = v[0][3] = 1.0f; - pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); - - pShaderAPI->SetVertexShaderIndex( 0 ); - pShaderAPI->SetPixelShaderIndex( 0 ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/BlurFilterY.cpp b/materialsystem/stdshaders/BlurFilterY.cpp deleted file mode 100644 index 57db29c0..00000000 --- a/materialsystem/stdshaders/BlurFilterY.cpp +++ /dev/null @@ -1,136 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//===========================================================================// - -#include "BaseVSShader.h" -#include "BlurFilter_vs20.inc" -#include "BlurFilter_ps20.inc" -#include "BlurFilter_ps20b.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) - SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) - { - params[BLOOMAMOUNT]->SetFloatValue( 1.0 ); - } - } - - SHADER_INIT - { - if ( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "BlurFilterY_DX80"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); - - // Render targets are pegged as sRGB on POSIX, so just force these reads and writes - bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); - pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 ); - SET_STATIC_VERTEX_SHADER( blurfilter_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) - { - DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); -#ifndef _X360 - SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); -#endif - SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); - SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); - } - - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); - - // The temp buffer is 1/4 back buffer size - ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); - int height = src_texture->GetActualWidth(); - float dY = 1.0f / height; -// dY *= 0.4; - float v[4]; - - // Tap offsets - v[0] = 0.0f; - v[1] = 1.3366f * dY; - v[2] = 0; - v[3] = 0; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); - v[0] = 0.0f; - v[1] = 3.4295f * dY; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); - v[0] = 0.0f; - v[1] = 5.4264f * dY; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); - - v[0] = 0.0f; - v[1] = 7.4359f * dY; - pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); - v[0] = 0.0f; - v[1] = 9.4436f * dY; - pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); - v[0] = 0.0f; - v[1] = 11.4401f * dY; - pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); - - v[0]=v[1]=v[2]=params[BLOOMAMOUNT]->GetFloatValue(); - - pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); - SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/BlurFilterY_dx80.cpp b/materialsystem/stdshaders/BlurFilterY_dx80.cpp deleted file mode 100644 index 5e01d608..00000000 --- a/materialsystem/stdshaders/BlurFilterY_dx80.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//===========================================================================// - -#include "BaseVSShader.h" -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( BlurFilterY, BlurFilterY_DX80 ) - -BEGIN_VS_SHADER_FLAGS( BlurFilterY_DX80, "Help for BlurFilterY_DX80", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) - SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if ( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) - params[BLOOMAMOUNT]->SetFloatValue(1.0); - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) - { - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); - - // Pre-cache shaders - pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); - pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); - - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); - BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); - - int width, height; - pShaderAPI->GetBackBufferDimensions( width, height ); - - // The temp buffer is 1/4 back buffer size - float dY = 2.0f / height; - - // 4 Tap offsets, expected from pixel center - float v[4][4]; - v[0][0] = 0; - v[0][1] = -1.5f * dY; - v[1][0] = 0; - v[1][1] = -0.5f * dY; - v[2][0] = 0; - v[2][1] = 0.5f * dY; - v[3][0] = 0; - v[3][1] = 1.5f * dY; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); - - v[0][0] = v[0][1] = v[0][2] = params[BLOOMAMOUNT]->GetFloatValue(); - pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); - - pShaderAPI->SetVertexShaderIndex( 0 ); - pShaderAPI->SetPixelShaderIndex( 0 ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/BlurFilter_ps11.psh b/materialsystem/stdshaders/BlurFilter_ps11.psh deleted file mode 100644 index ee58a650..00000000 --- a/materialsystem/stdshaders/BlurFilter_ps11.psh +++ /dev/null @@ -1,18 +0,0 @@ -ps.1.1 - -// 1221 filter constants -def c0, 0.1667f, 0.1667f, 0.1667f, 0.3333f - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0.rgb, t0, c0 -mad r0.rgb, t1, c0.a, r0 -mad r0.rgb, t2, c0.a, r0 -mad r0.rgb, t3, c0, r0 - -mul r0.rgb, r0, c1 + -mov r0.a, t0.a - diff --git a/materialsystem/stdshaders/BlurFilter_ps2x.fxc b/materialsystem/stdshaders/BlurFilter_ps2x.fxc deleted file mode 100644 index bfd082b3..00000000 --- a/materialsystem/stdshaders/BlurFilter_ps2x.fxc +++ /dev/null @@ -1,91 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "APPROX_SRGB_ADAPTER" "0..1" [ps20b] [PC] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler TexSampler : register( s0 ); - -struct PS_INPUT -{ - float2 coordTap0 : TEXCOORD0; - float2 coordTap1 : TEXCOORD1; - float2 coordTap2 : TEXCOORD2; - float2 coordTap3 : TEXCOORD3; - float2 coordTap1Neg : TEXCOORD4; - float2 coordTap2Neg : TEXCOORD5; - float2 coordTap3Neg : TEXCOORD6; -}; - -float2 psTapOffs[3] : register( c0 ); -float3 scale_factor : register( c3 ); - -float4 SampleTexture( sampler texSampler, float2 uv ) -{ - float4 cSample = tex2D( texSampler, uv ); - - #if ( APPROX_SRGB_ADAPTER ) - { - cSample.rgb = max( cSample.rgb, float3( 0.00001f, 0.00001f, 0.00001f ) ); // rsqrt doesn't like inputs of zero - - float3 ooSQRT; // - ooSQRT.r = rsqrt( cSample.r ); // - ooSQRT.g = rsqrt( cSample.g ); // Approximate linear-to-sRGB conversion - ooSQRT.b = rsqrt( cSample.b ); // - cSample.rgb *= ooSQRT.rgb; // - } - #endif - - return cSample; -} - -float4 main( PS_INPUT i ) : COLOR -{ - float4 s0, s1, s2, s3, s4, s5, s6, color; - - // Sample taps with coordinates from VS - s0 = SampleTexture( TexSampler, i.coordTap0 ); - s1 = SampleTexture( TexSampler, i.coordTap1 ); - s2 = SampleTexture( TexSampler, i.coordTap2 ); - s3 = SampleTexture( TexSampler, i.coordTap3 ); - s4 = SampleTexture( TexSampler, i.coordTap1Neg ); - s5 = SampleTexture( TexSampler, i.coordTap2Neg ); - s6 = SampleTexture( TexSampler, i.coordTap3Neg ); - - color = s0 * 0.2013f; - color += ( s1 + s4 ) * 0.2185f; - color += ( s2 + s5 ) * 0.0821f; - color += ( s3 + s6 ) * 0.0461f; - - // Compute tex coords for other taps - float2 coordTap4 = i.coordTap0 + psTapOffs[0]; - float2 coordTap5 = i.coordTap0 + psTapOffs[1]; - float2 coordTap6 = i.coordTap0 + psTapOffs[2]; - float2 coordTap4Neg = i.coordTap0 - psTapOffs[0]; - float2 coordTap5Neg = i.coordTap0 - psTapOffs[1]; - float2 coordTap6Neg = i.coordTap0 - psTapOffs[2]; - - // Sample the taps - s1 = SampleTexture( TexSampler, coordTap4 ); - s2 = SampleTexture( TexSampler, coordTap5 ); - s3 = SampleTexture( TexSampler, coordTap6 ); - s4 = SampleTexture( TexSampler, coordTap4Neg ); - s5 = SampleTexture( TexSampler, coordTap5Neg ); - s6 = SampleTexture( TexSampler, coordTap6Neg ); - - color += ( s1 + s4 ) * 0.0262f; - color += ( s2 + s5 ) * 0.0162f; - color += ( s3 + s6 ) * 0.0102f; - color.xyz*=scale_factor.xyz; - - #if ( APPROX_SRGB_ADAPTER ) - { - color.xyz *= color.xyz; // Approximate sRGB-to-linear conversion - } - #endif - - return color; - //return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} - diff --git a/materialsystem/stdshaders/BlurFilter_vs11.fxc b/materialsystem/stdshaders/BlurFilter_vs11.fxc deleted file mode 100644 index 0a213522..00000000 --- a/materialsystem/stdshaders/BlurFilter_vs11.fxc +++ /dev/null @@ -1,34 +0,0 @@ -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float3 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 coordTap0 : TEXCOORD0; - float2 coordTap1 : TEXCOORD1; - float2 coordTap2 : TEXCOORD2; - float2 coordTap3 : TEXCOORD3; -}; - -float2 vsTapOffs[4] : register ( SHADER_SPECIFIC_CONST_0 ); - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.projPos = float4( v.vPos, 1.0f ); - - o.coordTap0 = v.vBaseTexCoord + vsTapOffs[0]; - o.coordTap1 = v.vBaseTexCoord + vsTapOffs[1]; - o.coordTap2 = v.vBaseTexCoord + vsTapOffs[2]; - o.coordTap3 = v.vBaseTexCoord + vsTapOffs[3]; - - return o; -} - - diff --git a/materialsystem/stdshaders/BlurFilter_vs20.fxc b/materialsystem/stdshaders/BlurFilter_vs20.fxc deleted file mode 100644 index 3c37fa74..00000000 --- a/materialsystem/stdshaders/BlurFilter_vs20.fxc +++ /dev/null @@ -1,39 +0,0 @@ -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float3 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 coordTap0 : TEXCOORD0; - float2 coordTap1 : TEXCOORD1; - float2 coordTap2 : TEXCOORD2; - float2 coordTap3 : TEXCOORD3; - float2 coordTap1Neg : TEXCOORD4; - float2 coordTap2Neg : TEXCOORD5; - float2 coordTap3Neg : TEXCOORD6; -}; - -float2 vsTapOffs[3] : register ( SHADER_SPECIFIC_CONST_0 ); - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.projPos = float4( v.vPos, 1.0f ); - o.coordTap0 = v.vBaseTexCoord; - o.coordTap1 = v.vBaseTexCoord + vsTapOffs[0]; - o.coordTap2 = v.vBaseTexCoord + vsTapOffs[1]; - o.coordTap3 = v.vBaseTexCoord + vsTapOffs[2]; - o.coordTap1Neg = v.vBaseTexCoord - vsTapOffs[0]; - o.coordTap2Neg = v.vBaseTexCoord - vsTapOffs[1]; - o.coordTap3Neg = v.vBaseTexCoord - vsTapOffs[2]; - - return o; -} - - diff --git a/materialsystem/stdshaders/BufferClearObeyStencil_dx9.cpp b/materialsystem/stdshaders/BufferClearObeyStencil_dx9.cpp deleted file mode 100644 index d9c55df4..00000000 --- a/materialsystem/stdshaders/BufferClearObeyStencil_dx9.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Clears color/depth, but obeys stencil while doing so -// -//=============================================================================// - -#include "BaseVSShader.h" - -#include "bufferclearobeystencil_vs20.inc" -#include "bufferclearobeystencil_ps20.inc" -#include "bufferclearobeystencil_ps20b.inc" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( BufferClearObeyStencil, BufferClearObeyStencil_DX9 ) - -BEGIN_VS_SHADER_FLAGS( BufferClearObeyStencil_DX9, "", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( CLEARCOLOR, SHADER_PARAM_TYPE_INTEGER, "1", "activates clearing of color" ) - SHADER_PARAM( CLEARDEPTH, SHADER_PARAM_TYPE_INTEGER, "1", "activates clearing of depth" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "BufferClearObeyStencil_DX8"; - } - return 0; - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - bool bEnableColorWrites = params[CLEARCOLOR]->GetIntValue() != 0; - - SHADOW_STATE - { - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS ); - bool bEnableDepthWrites = params[CLEARDEPTH]->GetIntValue() != 0; - pShaderShadow->EnableDepthWrites( bEnableDepthWrites ); - - pShaderShadow->EnableColorWrites( bEnableColorWrites ); - pShaderShadow->EnableAlphaWrites( bEnableColorWrites ); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION|VERTEX_COLOR, 1, NULL, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( bufferclearobeystencil_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( USESCOLOR, bEnableColorWrites ); - SET_STATIC_VERTEX_SHADER( bufferclearobeystencil_vs20 ); - - //avoid setting a pixel shader when only doing depth/stencil operations, as recommended by PIX - if( bEnableColorWrites ) - { - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20b ); - SET_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20 ); - SET_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20 ); - } - } - } - - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( bufferclearobeystencil_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( bufferclearobeystencil_vs20 ); - - //avoid setting a pixel shader when only doing depth/stencil operations, as recommended by PIX - if( bEnableColorWrites ) - { - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20 ); - } - } - } - - Draw( ); - } - -END_SHADER diff --git a/materialsystem/stdshaders/Cable.psh b/materialsystem/stdshaders/Cable.psh deleted file mode 100644 index 6ba92636..00000000 --- a/materialsystem/stdshaders/Cable.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; See the vertex shader for info -; -; This shader takes: -; t0 = normal map -; t1 = base texture -; v0 = directional light color -; t2 = directional light direction (biased into 0-1) -; c0 = percent of dirlight to add as ambient -; -; Output: -; (t0 dot t1) * v0 -;------------------------------------------------------------------------------ - -tex t0 ; Get the 3-vector from the normal map -tex t1 ; Interpret tcoord t1 as color data. -texcoord t2 - -dp3 r1, t0_bx2, t2_bx2 ; r1 = normalMap dot dirLightDir -add r0, r1, c0 ; + 0.5 - -mul r1, v0, r0 ; scale the dot product by the dirlight's actual color -mul r0.rgb, r1, t1 + ; scale by the texture color - -mul r0.a, t1.a, v0.a diff --git a/materialsystem/stdshaders/Cable.vsh b/materialsystem/stdshaders/Cable.vsh deleted file mode 100644 index 857a2e3b..00000000 --- a/materialsystem/stdshaders/Cable.vsh +++ /dev/null @@ -1,117 +0,0 @@ -vs.1.1 - -#include "macros.vsh" - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; The cable equation is: -; [L dot N] * C * T -; -; where: -; C = directional light color -; T = baseTexture -; N = particle normal (stored in the normal map) -; L = directional light direction -; -; $SHADER_SPECIFIC_CONST_0 = Directional light direction -;------------------------------------------------------------------------------ - - -;------------------------------------------------------------------------------ -; Transform position from object to projection space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Setup the tangent space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$tmp1 ); -&AllocateRegister( \$tmp2 ); -&AllocateRegister( \$tmp3 ); -&AllocateRegister( \$r ); - -; Get S crossed with T (call it R) -mov $tmp1, $vTangentS -mov $tmp2, $vTangentT - -mul $tmp3, $vTangentS.yzxw, $tmp2.zxyw -mad $r, -$vTangentS.zxyw, $tmp2.yzxw, $tmp3 - -&FreeRegister( \$tmp2 ); -&FreeRegister( \$tmp3 ); - -&AllocateRegister( \$s ); - -; Normalize S (into $s) -dp3 $s.w, $vTangentS, $vTangentS -rsq $s.w, $s.w -mul $s.xyz, $vTangentS, $s.w - -; Normalize R (into $r) -dp3 $r.w, $r, $r -rsq $r.w, $r.w -mul $r.xyz, $r, $r.w - -&AllocateRegister( \$t ); - -; Regenerate T (into $t) -mul $t, $r.yzxw, $tmp1.zxyw -mad $t, -$r.zxyw, $tmp1.yzxw, $t - -&FreeRegister( \$tmp1 ); - -;------------------------------------------------------------------------------ -; Transform the light direction (into oD1) -;------------------------------------------------------------------------------ - -&AllocateRegister( \$lightDirection ); - -dp3 $lightDirection.x, $s, $SHADER_SPECIFIC_CONST_0 -dp3 $lightDirection.y, $t, $SHADER_SPECIFIC_CONST_0 -dp3 $lightDirection.z, $r, $SHADER_SPECIFIC_CONST_0 - -&FreeRegister( \$r ); -&FreeRegister( \$s ); -&FreeRegister( \$t ); - -; Scale into 0-1 range (we're assuming light direction was normalized prior to here) -add oT2, $lightDirection, $cHalf ; + 0.5 -&FreeRegister( \$lightDirection ); - -;------------------------------------------------------------------------------ -; Copy texcoords for the normal map and base texture -;------------------------------------------------------------------------------ - -mov oT0, $vTexCoord0 -mov oT1, $vTexCoord1 - -; Pass the dirlight color through -mov oD0.xyzw, $vColor - - diff --git a/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc b/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc deleted file mode 100644 index c90ef086..00000000 --- a/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc +++ /dev/null @@ -1,23 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float4 projPos : POSITION; - float3 zValue : TEXCOORD0; -}; - -const float3 g_ZFilter : register( c1 ); -const float3 g_ModulationColor : register( c2 ); - -float4 main( PS_INPUT i ) : COLOR -{ - float z = dot( i.zValue, g_ZFilter ); - z = saturate( z ); - float4 color = float4( z, z, z, 1.0f ); - color.rgb *= g_ModulationColor; - return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc b/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc deleted file mode 100644 index 647acde0..00000000 --- a/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc +++ /dev/null @@ -1,38 +0,0 @@ -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; - -const float2 cDepthFactor : register( SHADER_SPECIFIC_CONST_0 ); - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 zValue : TEXCOORD0; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); - float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - o.zValue.x = (o.projPos.z - cDepthFactor.y) / cDepthFactor.x; - o.zValue.y = (o.projPos.w - cDepthFactor.y) / cDepthFactor.x; - return o; -} - - - - diff --git a/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp b/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp deleted file mode 100644 index 9f3c34bf..00000000 --- a/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//===========================================================================// - -#include "BaseVSShader.h" -#include "debugdrawenvmapmask_vs20.inc" -#include "debugdrawenvmapmask_ps20.inc" -#include "debugdrawenvmapmask_ps20b.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER_FLAGS( DebugDrawEnvmapMask, "Help for DebugDrawEnvmapMask", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { -// Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); - SET_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); - SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); - SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); - } - } - DYNAMIC_STATE - { - int numBones = s_pShaderAPI->GetCurrentNumBones(); - - DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); - - bool bShowAlpha = params[SHOWALPHA]->GetIntValue() ? true : false; - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); - SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); - SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); - } - - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc b/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc deleted file mode 100644 index f97589af..00000000 --- a/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc +++ /dev/null @@ -1,26 +0,0 @@ -// DYNAMIC: "SHOWALPHA" "0..1" - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler BaseTextureSampler : register( s0 ); - -struct PS_INPUT -{ - float4 projPos : POSITION; - float2 baseTexCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); -#if SHOWALPHA - float4 result = float4( baseColor.a, baseColor.a, baseColor.a, 1.0f ); -#else - float4 result = float4( baseColor.rgb, 1.0f ); -#endif - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc b/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc deleted file mode 100644 index 33aa5dac..00000000 --- a/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc +++ /dev/null @@ -1,39 +0,0 @@ -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 baseTexCoord : TEXCOORD0; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); - float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - return o; -} - - - - diff --git a/materialsystem/stdshaders/DebugTextureView.cpp b/materialsystem/stdshaders/DebugTextureView.cpp deleted file mode 100644 index 70d73d34..00000000 --- a/materialsystem/stdshaders/DebugTextureView.cpp +++ /dev/null @@ -1,104 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// - -#include "BaseVSShader.h" -#include "shaderlib/cshader.h" - -#include "debugtextureview_vs20.inc" -#include "debugtextureview_ps20.inc" -#include "debugtextureview_ps20b.inc" - -DEFINE_FALLBACK_SHADER( DebugTextureView, DebugTextureView_dx9 ) -BEGIN_VS_SHADER( DebugTextureView_dx9, "Help for DebugTextureView" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_BOOL, "0", "" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if ( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "UnlitGeneric"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaTest( true ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); - SET_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); - SET_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); - SET_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - //pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - - float cPsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - if ( ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) || - ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616 ) || - ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGB323232F ) || - ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA32323232F ) ) - { - if ( pTexture->IsCubeMap() ) - cPsConst0[0] = 1.0f; - else - cPsConst0[1] = 1.0f; - } - pShaderAPI->SetPixelShaderConstant( 0, cPsConst0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); - SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); - SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/DebugTextureView_ps2x.fxc b/materialsystem/stdshaders/DebugTextureView_ps2x.fxc deleted file mode 100644 index 4b22d55b..00000000 --- a/materialsystem/stdshaders/DebugTextureView_ps2x.fxc +++ /dev/null @@ -1,81 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "SHOWALPHA" "0..1" -// DYNAMIC: "ISCUBEMAP" "0..1" - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler g_tSampler : register( s0 ); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - -const float3 g_vConst0 : register( c0 ); -#define g_flIsHdrCube g_vConst0.x -#define g_flIsHdr2D g_vConst0.y - -float4 main( PS_INPUT i ) : COLOR -{ - float4 sample = tex2D( g_tSampler, i.texCoord ); - float4 result = { 0.0f, 0.0f, 0.0f, 1.0f }; - - result.rgb = sample.rgb; - #if SHOWALPHA - result.rgb = sample.a; - #endif - - if ( g_flIsHdr2D ) - result.rgb *= MAX_HDR_OVERBRIGHT; - - #if ISCUBEMAP - bool bNoDataForThisPixel = false; - float3 vec = float3( 0, 0, 0 ); - float x = i.texCoord.x; - float y = i.texCoord.y; - float x2 = frac( ( i.texCoord.x ) * 3.0f ) * 2.0f - 1.0f; - float y2 = frac( ( i.texCoord.y ) * 4.0f ) * 2.0f - 1.0f; - if ( ( x >= 0.3333f ) && ( x <= 0.6666f ) ) //Center row - { - if ( y >= 0.75f ) - vec = float3( x2, 1.0, y2 ); - else if ( y >= 0.5f ) - vec = float3( x2, y2, -1.0 ); - else if ( y >= 0.25f ) - vec = float3( x2, -1.0, -y2 ); - else if ( y >= 0.0f ) - vec = float3( x2, -y2, 1.0 ); - } - else if ( ( y >= 0.25f ) && ( y <= 0.5f ) ) - { - if ( x <= 0.3333f ) - vec = float3( -1.0f, -x2, -y2 ); - else if (x >= 0.6666f) - vec = float3( 1.0f, x2, -y2 ); - else - bNoDataForThisPixel = true; - } - else - { - bNoDataForThisPixel = true; - } - - float4 cBase = texCUBE( g_tSampler, vec ); - #if SHOWALPHA - cBase.rgb = cBase.a; - #endif - - if ( g_flIsHdrCube ) - cBase.rgb *= ENV_MAP_SCALE; - - if ( bNoDataForThisPixel == true ) - cBase.rgb = float3( 0.9f, 0.4f, 0.15f ); - - result.rgb = cBase.rgb; - result.a = 1.0f; // - bNoDataForThisPixel; - #endif - - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/DebugTextureView_vs20.fxc b/materialsystem/stdshaders/DebugTextureView_vs20.fxc deleted file mode 100644 index 48c3b7e4..00000000 --- a/materialsystem/stdshaders/DebugTextureView_vs20.fxc +++ /dev/null @@ -1,23 +0,0 @@ -// DYNAMIC: "COMPRESSED_VERTS" "0..1" - -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vUv0 : TEXCOORD0; -}; - -VS_OUTPUT main( const VS_INPUT i ) -{ - VS_OUTPUT o; - o.vProjPos.xyzw = mul( i.vPos.xyzw, cModelViewProj ); - o.vUv0.xy = i.vTexCoord0.xy; - return o; -} diff --git a/materialsystem/stdshaders/Eyes.psh b/materialsystem/stdshaders/Eyes.psh deleted file mode 100644 index 6909dcf6..00000000 --- a/materialsystem/stdshaders/Eyes.psh +++ /dev/null @@ -1,16 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw the eyes -; t0 - texture -; t1 - iris -; t2 - glint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -lrp r0, t1.a, t1, t0 ; Blend in the iris with the background -mad r0.rgb, r0, v0, t2 + ; Modulate by the illumination, add in the glint -mov r0.a, t0.a diff --git a/materialsystem/stdshaders/Eyes_Overbright2.psh b/materialsystem/stdshaders/Eyes_Overbright2.psh deleted file mode 100644 index f7fae257..00000000 --- a/materialsystem/stdshaders/Eyes_Overbright2.psh +++ /dev/null @@ -1,18 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw the eyes -; t0 - texture -; t1 - iris -; t2 - glint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -lrp r0, t1.a, t1, t0 ; Blend in the iris with the background -mul_x2 r0, v0, r0 ; Modulate by the illumination with overbright - -add r0.rgb, r0, t2 + ; Add in the glint -mov r0.a, t0.a diff --git a/materialsystem/stdshaders/Eyes_vs20.fxc b/materialsystem/stdshaders/Eyes_vs20.fxc deleted file mode 100644 index b055eed7..00000000 --- a/materialsystem/stdshaders/Eyes_vs20.fxc +++ /dev/null @@ -1,145 +0,0 @@ -//======= Copyright 1996-2006, Valve Corporation, All rights reserved. ====== -// $SHADER_SPECIFIC_CONST_0 = eyeball origin -// $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 -// $SHADER_SPECIFIC_CONST_2 = iris projection U -// $SHADER_SPECIFIC_CONST_3 = iris projection V -// $SHADER_SPECIFIC_CONST_4 = glint projection U -// $SHADER_SPECIFIC_CONST_5 = glint projection V -//============================================================================= - -// STATIC: "INTRO" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "vortwarp_vs20_helper.h" - -static const int g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; -static const bool g_bHalfLambert = HALFLAMBERT ? true : false; - -const float3 cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); -const float3 cHalfEyeballUp : register( SHADER_SPECIFIC_CONST_1 ); -const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); -const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); -const float4 cGlintProjectionU : register( SHADER_SPECIFIC_CONST_4 ); -const float4 cGlintProjectionV : register( SHADER_SPECIFIC_CONST_5 ); -#if INTRO -const float4 const4 : register( SHADER_SPECIFIC_CONST_6 ); -#define g_Time const4.w -#define modelOrigin const4.xyz -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_7 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_8 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - float4 vPos : POSITION; // Position - float4 vBoneWeights : BLENDWEIGHT; // Skin weights - float4 vBoneIndices : BLENDINDICES; // Skin indices - float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates - - float3 vPosFlex : POSITION1; // Delta positions for flexing -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; // Fixed-function fog factor -#endif - float2 baseTC : TEXCOORD0; // Base texture coordinate - float2 irisTC : TEXCOORD1; // Iris texture coordinates - float2 glintTC : TEXCOORD2; // Glint texture coordinates - float3 vColor : TEXCOORD3; // Vertex-lit color - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT ? true : false; - - float4 vPosition = v.vPos; - float3 dummy = v.vPos.xyz; // dummy values that can't be optimized out - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, vPosition.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, dummy, vPosition.xyz ); -#endif - - // Transform the position and dummy normal (not doing the dummy normal causes invariance issues with the flashlight!) - float3 worldNormal, worldPos; - SkinPositionAndNormal( - g_bSkinning, - vPosition, dummy, - v.vBoneWeights, v.vBoneIndices, - worldPos, worldNormal ); - -#if INTRO - WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, dummy, dummy, dummy ); -#endif - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); - -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( worldPos, vProjPos, g_FogType ); -#endif - - // Normal = (Pos - Eye origin) - just step on dummy normal created above - worldNormal = worldPos - cEyeOrigin; - - // Normal -= 0.5f * (Normal dot Eye Up) * Eye Up - float normalDotUp = -dot( worldNormal, cHalfEyeballUp) * 0.5f; - worldNormal = normalize(normalDotUp * cHalfEyeballUp + worldNormal); - - // Vertex lighting -#if ( USE_STATIC_CONTROL_FLOW || defined ( SHADER_MODEL_VS_3_0 ) ) - o.vColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); -#else - o.vColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); -#endif - - // Texture 0 is the base texture - // Texture 1 is a planar projection used for the iris - // Texture 2 is a planar projection used for the glint - o.baseTC = v.vTexCoord0; - o.irisTC.x = dot( cIrisProjectionU, float4(worldPos, 1) ); - o.irisTC.y = dot( cIrisProjectionV, float4(worldPos, 1) ); - o.glintTC.x = dot( cGlintProjectionU, float4(worldPos, 1) ); - o.glintTC.y = dot( cGlintProjectionV, float4(worldPos, 1) ); - - return o; -} - - diff --git a/materialsystem/stdshaders/LightmappedGeneric.psh b/materialsystem/stdshaders/LightmappedGeneric.psh deleted file mode 100644 index 6ec78dda..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh b/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh deleted file mode 100644 index b31054c5..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t2 ; cube map -tex t3 ; envmap mask - -mul r0.rgb, t2, 1-t3.a -mul r0.rgb, c2, r0 ; apply the envmaptint -+ mul r0.a, c2.a, v0.a diff --git a/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh deleted file mode 100644 index ad09a6d8..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t2 ; cube map -tex t3 ; envmap mask - -mul r0.rgb, t2, t3 -mul r0.rgb, c2, r0 -+ mul r0.a, c2.a, v0.a diff --git a/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh deleted file mode 100644 index 16b47fef..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t2 ; cube map - -mul r0.rgb, t2, c2 -+ mul r0.a, v0.a, c2.a diff --git a/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh b/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh deleted file mode 100644 index c8279e74..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh +++ /dev/null @@ -1,22 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul r1, t2, 1-t3.a ; envmap * envmapmask (alpha) -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh deleted file mode 100644 index 0401218d..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh +++ /dev/null @@ -1,14 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 -mul r0, t0, c0 - diff --git a/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh b/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh deleted file mode 100644 index 6cef1e5d..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh +++ /dev/null @@ -1,38 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - - diff --git a/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh b/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh deleted file mode 100644 index 8eea421f..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh +++ /dev/null @@ -1,43 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - -dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 -dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - -mov oT2, $vTexCoord1 - -; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. -mov oD0, $vColor diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh deleted file mode 100644 index 6f061278..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh +++ /dev/null @@ -1,66 +0,0 @@ -; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -ps.1.1 - -;------------------------------------------------------------------------------ -; Environment mapping on a bumped surface -; t0 - Normalmap -; t3 - Cube environment map (*must* be a cube map!) -; -; c0 - color to multiply the results by -; c1 - envmap contrast -; c2 - envmap saturation -; c3 - grey weights -; c4 - fresnel amount -; Input texture coords required here are a little wonky. -; tc0.uv <- U,V into the normal map -; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform -; from tangent space->env map space -; tc1.q, tc2.q, tc3.q <- eye vector in env map space -;------------------------------------------------------------------------------ - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -; FIXME FIXME - Need to do specialized versions of this with and without: -; - constant color -; - fresnel amount of exactly 0 or 1 or in between -; - envmap contrast of 0, 1, or in between -; - envmap saturation of 0, 1, or in between - -; r0 = constant color * result of bump into envmap -mul r0.rgb, t3, c0 - -; dot eye-vector with per-pixel normal from t0 -dp3_sat r1, v0_bx2, t0_bx2 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -mul r1.rgb, r0, r0 ; color squared -+mul r0.a, 1-r1.a, 1-r1.a ; squared - -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -+mul r0.a, r0.a, r0.a ; quartic - -dp3 r1.rgb, r0, c3 ; color greyscaled -+mul r0.a, r0.a, 1-r1.a ; quintic - -; FIXME - these should be able to pair (I think), but don't on nvidia for some reason. -; (I think) cannot pair due to use of >2 constants in single stage -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale -mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration - -mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc - -#if NORMALMAPALPHAENVMAPMASK -+mul r0.a, c0.a, t0.a ; Fade amount * alpha from the texture -#else -+mov r0.a, c0.a ; Just use the fade amount -#endif - - diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh deleted file mode 100644 index 73769dce..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh +++ /dev/null @@ -1,96 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; Shader specific constant: -; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); - -; Transform position from object to world -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -dp3 oT1.x, $vTangentS, $cModel0 -dp3 oT2.x, $vTangentS, $cModel1 -dp3 oT3.x, $vTangentS, $cModel2 - -dp3 oT1.y, $vTangentT, $cModel0 -dp3 oT2.y, $vTangentT, $cModel1 -dp3 oT3.y, $vTangentT, $cModel2 - -dp3 oT1.z, $vNormal, $cModel0 -dp3 oT2.z, $vNormal, $cModel1 -dp3 oT3.z, $vNormal, $cModel2 - -; Compute the vector from vertex to camera -&AllocateRegister( \$worldEyeVect ); -sub $worldEyeVect.xyz, $cEyePos, $worldPos -&FreeRegister( \$worldPos ); - -; Move it into the w component of the texture coords, as the wacky -; pixel shader wants it there. -mov oT1.w, $worldEyeVect.x -mov oT2.w, $worldEyeVect.y -mov oT3.w, $worldEyeVect.z - -alloc $tangentEyeVect - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal - -&FreeRegister( \$worldEyeVect ); - -&Normalize( $tangentEyeVect ); - -; stick the tangent space eye vector into oD0 -mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf - -&FreeRegister( \$tangentEyeVect ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - - diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh deleted file mode 100644 index dbd03fa3..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh +++ /dev/null @@ -1,72 +0,0 @@ -; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -ps.1.4 -;------------------------------------------------------------------------------ -; Phase 1 -;------------------------------------------------------------------------------ -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! -;mov r0.rgba, r4 - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) - -#if NORMALMAPALPHAENVMAPMASK -; Alpha gets lost after phase marker, so store it here -mov r5, r0.a -#endif - -;------------------------------------------------------------------------------ -; Phase 2 -;------------------------------------------------------------------------------ -; What's left over from the last phase: -; r0 - normal -; r1 - free -; r2 - vector to sample in envmap -; r3 - free -; r4 - normal -; r5 - normal map alpha (rgba) - -phase - -; Sample environment map -texld r3, r2 - -; dot eye-vector with per-pixel normal from r0 -dp3_sat r1, v0_bx2, r0_bx2 - -; Result goes in output color (multiply by constant color c0) -mul r0.rgb, r3, c0 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -mul r1.rgb, r0, r0 -+mul r0.a, 1-r1.a, 1-r1.a ; squared - -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -+mul r0.a, r0.a, r0.a ; quartic - -dp3 r1.rgb, r0, c3 -+mul r0.a, r0.a, 1-r1.a ; quintic - -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale -mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration - -mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc - -#if NORMALMAPALPHAENVMAPMASK -+mul r0.a, c0.a, r5.r ; Fade amount * alpha from the texture -#else -+mov r0.a, c0.a ; Just use the fade amount -#endif diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh deleted file mode 100644 index ea0f143a..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh +++ /dev/null @@ -1,92 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; Shader specific constant: -; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); - -; Transform position from object to world -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -dp3 oT1.x, $vTangentS, $cModel0 -dp3 oT2.x, $vTangentS, $cModel1 -dp3 oT3.x, $vTangentS, $cModel2 - -dp3 oT1.y, $vTangentT, $cModel0 -dp3 oT2.y, $vTangentT, $cModel1 -dp3 oT3.y, $vTangentT, $cModel2 - -dp3 oT1.z, $vNormal, $cModel0 -dp3 oT2.z, $vNormal, $cModel1 -dp3 oT3.z, $vNormal, $cModel2 - -; Compute the vector from vertex to camera -&AllocateRegister( \$worldEyeVect ); -sub $worldEyeVect.xyz, $cEyePos, $worldPos -&FreeRegister( \$worldPos ); - -; eye vector -mov oT4.xyz, $worldEyeVect - -alloc $tangentEyeVect - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal - -&FreeRegister( \$worldEyeVect ); - -&Normalize( $tangentEyeVect ); - -; stick the tangent space eye vector into oD0 -mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf - -&FreeRegister( \$tangentEyeVect ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh deleted file mode 100644 index 82b83a49..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh +++ /dev/null @@ -1,79 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Computes the diffuse component of lighting using lightmap + bumpmap -; t0 - Normalmap -; t1 - Lightmap1 -; t2 - Lightmap2 -; t3 - Lightmap3 -; -; The texture coordinates need to be defined as follows: -; tc0 - Normalmap and lightmap texture coordinates -; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space -;------------------------------------------------------------------------------ - -; Get the 3-vector from the normal map -tex t0 - -; Sample the lightmaps -tex t1 -tex t2 -tex t3 - -; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + -; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + -; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + - -; r0 = ( N dot basis[0] ) -; don't "_sat" here so that everything adds up to one even if the normal is outside of the basis!!!!! -dp3 r0, t0_bx2, c0 - -; r1 = ( N dot basis[1] ) -dp3 r1, t0_bx2, c1 - -;---- -; r0 = ( N dot basis[0] ) -; r1 = ( N dot basis[1] ) -;---- - -; r0.rgb = ( N dot basis[0] )^2 -mul r0.rgb, r0, r0 - -; r1.a = ( N dot basis[1] )^2 -+mul r1.a, r1, r1 - -;---- -; r0.rgb = ( N dot basis[0] )^2 -; r1.a = ( N dot basis[1] )^2 -;---- - -mul t1, r0, t1 - -;---- -; r1.a = ( N dot basis[1] )^2 -; t1 = lightmapColor[0] * ( N dot basis[0] )^2 -;---- - -dp3 r0, t0_bx2, c2 - -;---- -; r1.a = ( N dot basis[1] )^2 -; t1 = lightmapColor[0] * ( N dot basis[0] )^2 -; r0 = ( N dot basis[2] ) -;---- - -mad t1.rgb, r1.a, t2, t1 -+mul r0.a, r0, r0 - -;---- -; t1.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + lightmapColor[1] * ( N dot basis[1] )^2 -; r0.a = ( N dot basis[2] )^2 -;---- - -mad r0.rgba, r0.a, t3, t1 - -;---- -; r0.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + -; lightmapColor[1] * ( N dot basis[1] )^2 + -; lightmapColor[2] * ( N dot basis[2] )^2 -;---- diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh deleted file mode 100644 index 229a839a..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh +++ /dev/null @@ -1,54 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -; Compute the texture coordinates given the offset between -; each bumped lightmap -&AllocateRegister( \$offset ); -mov $offset.xy, $vTexCoord2 -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -add oT1.xy, $offset, $vTexCoord1 -mad oT2.xy, $offset, $cTwo, $vTexCoord1 -; make a 3 -alloc $three -add $three, $cOne, $cTwo -mad oT3.xy, $offset, $three, $vTexCoord1 -free $three - -&FreeRegister( \$offset ); diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh deleted file mode 100644 index 4756b5bd..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh +++ /dev/null @@ -1,39 +0,0 @@ -;------------------------------------------------------------------------------ -; Computes the diffuse component of lighting using lightmap + bumpmap -; t0 - Normalmap -; t1 - Lightmap1 -; t2 - Lightmap2 -; t3 - Lightmap3 -; t4 - Base -; -; The texture coordinates need to be defined as follows: -; tc0 - Normalmap and lightmap texture coordinates -; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space -;------------------------------------------------------------------------------ -ps.1.4 - -; Get the 3-vector from the normal map -texld r0, t0 - -; Sample the lightmaps -texld r1, t1 -texld r2, t2 -texld r3, t3 - -; Sample the base texture -texld r4, t4 - -; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + -; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + -; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * base - -dp3 r5.r, r0_bx2, c0 -dp3 r5.g, r0_bx2, c1 -dp3 r5.b, r0_bx2, c2 -mul r5.rgb, r5, r5 -mul r1, r1, r5.r -mad r1, r2, r5.g, r1 -mad r1, r3, r5.g, r1 - -; assume overbright_2 !!! -mul_x2 r0, r1, r4 diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh deleted file mode 100644 index a78d0851..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh +++ /dev/null @@ -1,55 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -; Compute the texture coordinates given the offset between -; each bumped lightmap -&AllocateRegister( \$offset ); -mov $offset.xy, $vTexCoord2 -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -add oT1.xy, $offset, $vTexCoord1 -mad oT2.xy, $offset, $cTwo, $vTexCoord1 -alloc $three -add $three, $cOne, $cTwo -mad oT3.xy, $offset, $three, $vTexCoord1 -free $three -dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 -dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - -&FreeRegister( \$offset ); diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh deleted file mode 100644 index 2b43ee33..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh +++ /dev/null @@ -1,47 +0,0 @@ -;------------------------------------------------------------------------------ -; Computes the diffuse component of lighting using lightmap + bumpmap -; t0 - Normalmap -; t1 - Lightmap1 -; t2 - Lightmap2 -; t3 - Lightmap3 -; t4 - Base1 -; t5 - Base2 -; -; The texture coordinates need to be defined as follows: -; tc0 - Normalmap and lightmap texture coordinates -; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space -;------------------------------------------------------------------------------ -ps.1.4 - -; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + -; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + -; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * lerp(base1, base2, lightmapColor[0].a) - -; Get the 3-vector from the normal map -texld r0, t0 - -dp3 r5.r, r0_bx2, c0 -dp3 r5.g, r0_bx2, c1 -dp3 r5.b, r0_bx2, c2 -mul r5.rgb, r5, r5 - -phase - -; Sample the lightmaps -texld r1, t1 -texld r2, t2 -texld r3, t3 - -; Sample the base textures -texld r4, t4 -texld r5, t5 - -mul r1, r1, r5.r -mad r1, r2, r5.g, r1 -mad r1, r3, r5.g, r1 - -; blend base textures -lrp r4, r4, r5, r1.a - -; assume overbright_2 !!! -mul_x2 r0, r1, r4 diff --git a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh b/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh deleted file mode 100644 index 7773d335..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh +++ /dev/null @@ -1,57 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -; Compute the texture coordinates given the offset between -; each bumped lightmap -&AllocateRegister( \$offset ); -mov $offset.xy, $vTexCoord2 -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -add oT1.xy, $offset, $vTexCoord1 -mad oT2.xy, $offset, $cTwo, $vTexCoord1 -alloc $three -add $three, $cOne, $cTwo -mad oT3.xy, $offset, $three, $vTexCoord1 -free $three -dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 -dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 -dp4 oT5.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 -dp4 oT5.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - -&FreeRegister( \$offset ); diff --git a/materialsystem/stdshaders/LightmappedGeneric_Decal.psh b/materialsystem/stdshaders/LightmappedGeneric_Decal.psh deleted file mode 100644 index 01984202..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_Decal.psh +++ /dev/null @@ -1,47 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Computes the diffuse component of lighting using lightmap + bumpmap -; t0 - decal texture -; t1 - Lightmap1 -; t2 - Lightmap2 -; t3 - Lightmap3 -; -; The texture coordinates need to be defined as follows: -; tc0 - Normalmap and lightmap texture coordinates -; c0, c1, c2 - ( ( N dot basis[0] )^2 ), ( ( N dot basis[1] )^2 ), ( ( N dot basis[2] )^2 ) -;------------------------------------------------------------------------------ - -; Get the decal color -tex t0 - -; Sample the lightmaps -tex t1 -tex t2 -tex t3 - -; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + -; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + -; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + - -; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) -mul r0, t1, c0 - -; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + lightmapColor[1] * ( ( N dot basis[1] )^2 ) -mad r0, t2, c1, r0 - -; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + -; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + -; lightmapColor[2] * ( ( N dot basis[2] )^2 ) -mad r0, t3, c2, r0 - -; Modulate by decal texture -mul r0.rgb, r0, t0 -+ mov r0.a, t0.a - -; Modulate by constant color -mul r0, r0, c3 - -; Modulate by per-vertex factor -mul r0, r0, v0 - diff --git a/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh b/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh deleted file mode 100644 index a9db9faa..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh +++ /dev/null @@ -1,56 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -; Compute the texture coordinates given the offset between -; each bumped lightmap -&AllocateRegister( \$offset ); -mov $offset.x, $vTexCoord2.x -mov $offset.y, $cZero -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -add oT1.xy, $offset, $vTexCoord1 -mad oT2.xy, $offset, $cTwo, $vTexCoord1 -; make a 3 -alloc $three -add $three, $cOne, $cTwo -mad oT3.xy, $offset, $three, $vTexCoord1 -free $three -mov oD0, $vColor - -&FreeRegister( \$offset ); diff --git a/materialsystem/stdshaders/LightmappedGeneric_Detail.psh b/materialsystem/stdshaders/LightmappedGeneric_Detail.psh deleted file mode 100644 index 4e3625f1..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_Detail.psh +++ /dev/null @@ -1,18 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r1.rgb, r0, t2 ; detail texture -lrp r0.rgb, c2, r1, r0 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh deleted file mode 100644 index a1d6c4e1..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh +++ /dev/null @@ -1,16 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t1 -tex t2 -mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) -mov r0.a, v0.a -mul_x2 r0.rgb, r0, t2 ; detail texture -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh b/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh deleted file mode 100644 index 575585b7..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh +++ /dev/null @@ -1,23 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r1.rgb, r0, t2 ; detail texture -lrp r0.rgb, c2, r1, r0 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, c1, t0 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh deleted file mode 100644 index 706ba7c2..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t1 -tex t2 - -mov r0.rgb, v0 + ; vertex color -mul r0.a, v0.a, t2.a ; vertex alpha * envmap alpha - -mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh b/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh deleted file mode 100644 index 05812ff1..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh +++ /dev/null @@ -1,20 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) diff --git a/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh b/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh deleted file mode 100644 index 5f740f86..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh +++ /dev/null @@ -1,45 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform -; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform -; $SHADER_SPECIFIC_CONST_4 = Modulation color -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -alloc $worldPos -if( $DOWATERFOG == 1 ) -{ - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 -} -&CalcFog( $worldPos, $projPos ); -free $worldPos - -&FreeRegister( \$projPos ); - -; YUCK! This is to make texcoords continuous for mat_softwaretl -mov oT0, $cZero -; Texture coordinates -mov oT1, $vTexCoord1 - -mov oD0, $cOne - - diff --git a/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh b/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh deleted file mode 100644 index c4f2ba23..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh +++ /dev/null @@ -1,6 +0,0 @@ -ps.1.1 - -tex t1 - -mov r0.rgba, t1 - diff --git a/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh deleted file mode 100644 index a1e63741..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh +++ /dev/null @@ -1,24 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t1 -tex t2 -tex t3 - -mov r0.rgb, v0 ; vertex color -mul r1, t2, t3 ; envmap * envmapmask - -mad r0.rgb, r1, c2, r0 + ; + envmap * envmapmask * envmaptint (color only) -mul r0.a, v0.a, r1.a ; alpha = vertex alpha * envmap alpha * envmapmask alpha - -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh b/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh deleted file mode 100644 index 83553ac8..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh +++ /dev/null @@ -1,22 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul r1, t2, t3 ; envmap * envmapmask -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh b/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh deleted file mode 100644 index 9f09397c..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh +++ /dev/null @@ -1,20 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -def c2, 1.0f, 1.0f, 1.0f, 1.0f - -tex t0 -tex t1 - -; Blend between grey and lightmap color based on total alpha - -mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap -+ mul_sat r1.a, t0, v0 ; base times vertex alpha -lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh deleted file mode 100644 index 0e52ed86..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh +++ /dev/null @@ -1,20 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -def c2, 1.0f, 1.0f, 1.0f, 1.0f - -tex t0 -tex t1 - -; Blend between grey and lightmap color based on total alpha - -mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap -+ mov_sat r1.a, v0 ; vertex alpha -lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh b/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh deleted file mode 100644 index 6c939a47..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh +++ /dev/null @@ -1,23 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -def c2, 1.0f, 1.0f, 1.0f, 1.0f - -tex t0 -tex t1 - -; Blend between white and lightmap color based on total alpha -mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap -+ mov_sat r1.a, v0 ; opacity == vertex opacity (no alpha in texture) - -lrp r0.rgb, t0.a, c1, r1 ; Blend between self-illum + lightmap -+ mov r0.a, c2.a - -lrp r0.rgb, r1.a, r0, c2 ; interpolate between white + color diff --git a/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh b/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh deleted file mode 100644 index 01b20711..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh +++ /dev/null @@ -1,14 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t1 -mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) -mov r0.a, v0.a -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh b/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh deleted file mode 100644 index 29be70ca..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh +++ /dev/null @@ -1,34 +0,0 @@ -ps.1.1 -def c0, 1,0,0,0 -def c1, 0,1,0,0 -def c2, 0,0,1,0 - -;------------------------------------------------------------------------------ -; Computes the diffuse component of lighting using lightmap + bumpmap -; t0 - Normalmap -; t1 - Lightmap1 -; t2 - Lightmap2 -; t3 - Lightmap3 -; -; The texture coordinates need to be defined as follows: -; tc0 - Normalmap and lightmap texture coordinates -;------------------------------------------------------------------------------ - -; Get the 3-vector from the normal map -tex t0 - -; Sample the lightmaps -tex t1 -tex t2 -tex t3 - -; output = lightmapColor[0] * n.r + lightmapColor[1] * n.g + lightmapColor[2] * n.b - - -mov r0, t0 -dp3 r1, t0, c0 -mul r0.rgb, r1, t1 -dp3 r1, t0, c1 -mad r0.rgb, r1, t2, r0 -dp3 r1, t0, c2 -mad r0.rgb, r1, t3, r0 diff --git a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh b/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh deleted file mode 100644 index 1ac3326d..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 - -mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, c1, t0 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh b/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh deleted file mode 100644 index 0121e928..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mul r1, t0.a, t0 ; Self illum -mad r1, c1, r1, t1 ; Self illum * tint + lightmap - -mul r0.rgb, r1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) - diff --git a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh deleted file mode 100644 index 4d32a715..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh +++ /dev/null @@ -1,28 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mul r1, c1, t0.a ; Self illum alpha * tint -mad r1, t0, r1, t1 ; Self illum * tint + lightmap -mul r0.rgb, r1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t2, t3 ; envmap * envmapmask -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) - diff --git a/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh b/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh deleted file mode 100644 index a434a941..00000000 --- a/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh +++ /dev/null @@ -1,15 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "LightmappedGeneric_inc.vsh" - -$detail = 0; -$envmap = 0; -$envmapcameraspace = 0; -$envmapsphere = 0; -$vertexcolor = 1; - -&LightmappedGeneric( $detail, $envmap, $envmapcameraspace, $envmapsphere, - $vertexcolor ); - diff --git a/materialsystem/stdshaders/LightmappedPBR_dx9.cpp b/materialsystem/stdshaders/LightmappedPBR_dx9.cpp deleted file mode 100644 index 0c739ebc..00000000 --- a/materialsystem/stdshaders/LightmappedPBR_dx9.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#include "BaseVSShader.h" -#include "convar.h" -#include "LightmappedPBR_dx9_helper.h" -#include "lightpass_helper.h" - -#ifdef STDSHADER -BEGIN_VS_SHADER(LightmappedPBR, - "Help for LightmappedPBR") -#else -BEGIN_VS_SHADER(LightmappedPBR, - "Help for LightmappedPBR") -#endif - -BEGIN_SHADER_PARAMS -SHADER_PARAM(ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "") -SHADER_PARAM(ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap") -SHADER_PARAM(BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map") -SHADER_PARAM(SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping") - -SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") -SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") -SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(AO, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(EMISSIVE, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness") - -SHADER_PARAM(ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "Origin of the env_cubemap (for sphere projected cubemap)") -SHADER_PARAM(ENVMAPRADIUS, SHADER_PARAM_TYPE_INTEGER, "0", "Radius of the env_cubemap (for sphere projected cubemap)") -END_SHADER_PARAMS - -void SetupVars(LightmappedPBR_DX9_Vars_t& info) -{ - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nAO = AO; - info.m_nEmissive = EMISSIVE; - info.m_nEnvmap = ENVMAP; - info.m_nBumpmap = BUMPMAP; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nBRDF = BRDF; - info.m_nUseSmoothness = USESMOOTHNESS; - info.m_nSeamlessMappingScale = SEAMLESS_SCALE; - info.m_nEnvmapOrigin = ENVMAPORIGIN; - info.m_nEnvmapRadius = ENVMAPRADIUS; -} - -void SetupVars(DrawLightPass_Vars_t& info) -{ - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nNoise = NOISE; - info.m_nBumpmap = BUMPMAP; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nBumpmap2 = -1; - info.m_nBumpFrame2 = -1; - info.m_nBumpTransform2 = -1; - info.m_nBaseTexture2 = -1; - info.m_nBaseTexture2Frame = -1; - info.m_nSeamlessMappingScale = -1; - info.bModel = false; - info.m_nUseSmoothness = USESMOOTHNESS; -} - -SHADER_INIT_PARAMS() -{ - LightmappedPBR_DX9_Vars_t info; - SetupVars(info); - InitParamsLightmappedPBR_DX9(this, params, pMaterialName, info); -} - -SHADER_FALLBACK -{ - return 0; -} - -SHADER_INIT -{ - LightmappedPBR_DX9_Vars_t info; - SetupVars(info); - InitLightmappedPBR_DX9(this, params, info); -} - -SHADER_DRAW -{ - bool hasFlashlight = UsingFlashlight(params); - bool bDrawStandardPass = true; - - if (bDrawStandardPass) - { - LightmappedPBR_DX9_Vars_t info; - SetupVars(info); - DrawLightmappedPBR_DX9(this, params, pShaderAPI, pShaderShadow, hasFlashlight, info, vertexCompression, pContextDataPtr); - } - else - { - // Skip this pass! - Draw(false); - } - -} - -END_SHADER - diff --git a/materialsystem/stdshaders/LightmappedPBR_dx9_helper.cpp b/materialsystem/stdshaders/LightmappedPBR_dx9_helper.cpp deleted file mode 100644 index 3f9daf64..00000000 --- a/materialsystem/stdshaders/LightmappedPBR_dx9_helper.cpp +++ /dev/null @@ -1,523 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "LightmappedPBR_dx9_helper.h" -#include "convar.h" -#include "cpp_shader_constant_register_map.h" -#include "lightmappedPBR_vs30.inc" -#include "lightmappedPBR_ps30.inc" -#include "commandbuilder.h" - -#include "IDeferredExt.h" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); - - -extern ConVar r_csm_bias; -extern ConVar r_csm_slopescalebias; -extern ConVar r_csm_performance; -extern ConVar mat_cubemapparallax; - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedPBR_DX9_Vars_t &info ) -{ - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - Assert( info.m_nFlashlightTexture >= 0 ); - - params[info.m_nBRDF]->SetStringValue("models/PBRTest/BRDF"); - - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - if (((info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined()) && g_pConfig->UseBumpmapping()) - // we don't need a tangent space if we have envmap without bumpmap - // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) - ) - { - SET_FLAGS2(MATERIAL_VAR2_NEEDS_TANGENT_SPACES); - } - - SET_FLAGS2(MATERIAL_VAR2_LIGHTING_LIGHTMAP); - if (g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined()) - { - SET_FLAGS2(MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP); - } - - - if (info.m_nEnvmapRadius != -1 && !params[info.m_nEnvmapRadius]->IsDefined()) - params[info.m_nEnvmapRadius]->SetIntValue(-1); -} - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- -void InitLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedPBR_DX9_Vars_t &info ) -{ - Assert( info.m_nFlashlightTexture >= 0 ); - pShader->LoadTexture(info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB); - - bool bIsBaseTextureTranslucent = false; - if ( params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - } - - if (info.m_nRoughness != -1 && params[info.m_nRoughness]->IsDefined()) - { - pShader->LoadTexture(info.m_nRoughness); - } - if (info.m_nMetallic != -1 && params[info.m_nMetallic]->IsDefined()) - { - pShader->LoadTexture(info.m_nMetallic); - } - if (info.m_nAO != -1 && params[info.m_nAO]->IsDefined()) - { - pShader->LoadTexture(info.m_nAO); - } - if (info.m_nEmissive != -1 && params[info.m_nEmissive]->IsDefined()) - { - pShader->LoadTexture(info.m_nEmissive); - } - if (info.m_nBRDF != -1 && params[info.m_nBRDF]->IsDefined()) - { - pShader->LoadTexture(info.m_nBRDF); - } - - if (info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined()) - { - if (!IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE)) - { - int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; - flags |= TEXTUREFLAGS_ALL_MIPS; - pShader->LoadCubeMap(info.m_nEnvmap, flags); - } - else - { - pShader->LoadTexture(info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0); - } - - if (!g_pHardwareConfig->SupportsCubeMaps()) - { - SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); - } - } - - if (g_pConfig->UseBumpmapping()) - { - if ((info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined()) - { - pShader->LoadBumpMap(info.m_nBumpmap); - SET_FLAGS2(MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL); - } - } -} - -class CLightmappedPBR_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - bool m_bFastPath; - -}; - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -static void DrawLightmappedPBR_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bHasFlashlight, LightmappedPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); - bool bHasRoughness = (info.m_nRoughness != -1) && params[info.m_nRoughness]->IsTexture(); - bool bHasMetallic = (info.m_nMetallic != -1) && params[info.m_nMetallic]->IsTexture(); - bool bHasAO = (info.m_nAO != -1) && params[info.m_nAO]->IsTexture(); - bool bHasEmissive = (info.m_nEmissive != -1) && params[info.m_nEmissive]->IsTexture(); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - bool bHasEnvmap =(info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsTexture(); - bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); - bool bHasBump = IsTextureSet(info.m_nBumpmap, params); - bool bUseSmoothness = info.m_nUseSmoothness != -1 && params[info.m_nUseSmoothness]->GetIntValue() == 1; - bool bSeamlessMapping = ((info.m_nSeamlessMappingScale != -1) && (params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0)); - - bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); - bool bHasVertexAlpha = IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA); - - BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); - bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; - - CLightmappedPBR_DX9_Context *pContextData = reinterpret_cast< CLightmappedPBR_DX9_Context *> ( *pContextDataPtr ); - if ( !pContextData ) - { - pContextData = new CLightmappedPBR_DX9_Context; - *pContextDataPtr = pContextData; - } - - if( pShader->IsSnapshotting() ) - { - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if( bHasFlashlight ) - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - - if( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - else // not flashlight pass - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); - } - } - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_SPACE; - - // Always enable...will bind white if nothing specified... - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Roughness map - pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); // Metallic map - - if (bHasEnvmap) - { - pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); - if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE) - { - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER7, true); - } - } - - - if (bHasVertexColor || bHasVertexAlpha) - { - flags |= VERTEX_COLOR; - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); - - if( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); - } - - pShaderShadow->EnableTexture(SHADER_SAMPLER8, true); // BRDF for IBL - - pShaderShadow->EnableTexture(SHADER_SAMPLER9, true); // Ambient Occlusion - pShaderShadow->EnableTexture(SHADER_SAMPLER10, true); // Emissive map - pShaderShadow->EnableTexture(SHADER_SAMPLER11, true); // Lightmap - - // Always enable, since flat normal will be bound - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map - pShaderShadow->EnableSRGBWrite( true ); - - // texcoord0 : base texcoord - // texcoord1 : lightmap texcoord - // texcoord2 : lightmap texcoord offset - int numTexCoords = 3; - - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( lightmappedpbr_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha); - SET_STATIC_VERTEX_SHADER_COMBO(BUMPMAP, bHasBump); - SET_STATIC_VERTEX_SHADER_COMBO(DIFFUSEBUMPMAP, bHasBump); - SET_STATIC_VERTEX_SHADER_COMBO(VERTEXALPHATEXBLENDFACTOR, false); - SET_STATIC_VERTEX_SHADER(lightmappedpbr_vs30); - - // Assume we're only going to get in here if we support 2b - DECLARE_STATIC_PIXEL_SHADER(lightmappedpbr_ps30); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && !bHasFlashlight); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER_COMBO(SMOOTHNESS, bUseSmoothness); - SET_STATIC_PIXEL_SHADER_COMBO(SEAMLESS, false); - SET_STATIC_PIXEL_SHADER_COMBO(BUMPMAP, bHasBump); - SET_STATIC_PIXEL_SHADER(lightmappedpbr_ps30); - - if( bHasFlashlight ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - else // not snapshotting -- begin dynamic state - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - bool isEnvmapCorrected = (info.m_nEnvmapRadius != -1 && info.m_nEnvmapOrigin != -1) && (params[info.m_nEnvmapRadius]->IsDefined() && params[info.m_nEnvmapRadius]->GetIntValue() > 0) && params[info.m_nEnvmapOrigin]->IsDefined(); - - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - pShader->ComputeModulationColor(color); - float flLScale = pShaderAPI->GetLightMapScaleFactor(); - color[0] *= flLScale; - color[1] *= flLScale; - color[2] *= flLScale; - pShaderAPI->SetPixelShaderConstant(20, color, 1); - - if (isEnvmapCorrected) - { - float* origin = (float*)params[info.m_nEnvmapOrigin]->GetVecValue(); - float radius = (float)params[info.m_nEnvmapRadius]->GetIntValue(); - float origin_And_Radius[4] = { origin[0], origin[1], origin[2], radius }; - pShaderAPI->SetPixelShaderConstant(21, origin_And_Radius); - } - - if( bHasBaseTexture ) - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - else - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - - if (bHasRoughness) - pShader->BindTexture(SHADER_SAMPLER1, info.m_nRoughness); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER1, TEXTURE_WHITE); - - if (bHasMetallic) - pShader->BindTexture(SHADER_SAMPLER2, info.m_nMetallic); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER2, TEXTURE_BLACK); - - if (bHasEnvmap) - pShader->BindTexture(SHADER_SAMPLER7, info.m_nEnvmap); - - if (bHasAO) - pShader->BindTexture(SHADER_SAMPLER9, info.m_nAO); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER9, TEXTURE_WHITE); - - if (bHasEmissive) - pShader->BindTexture(SHADER_SAMPLER10, info.m_nEmissive); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER10, TEXTURE_BLACK); - - pShaderAPI->BindStandardTexture(SHADER_SAMPLER11, TEXTURE_LIGHTMAP); - - ITexture *pCascadedDepthTexture = (ITexture *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_DEPTHTEXTURE ); - bool bUseCSM = pCascadedDepthTexture != NULL; - - if (!g_pConfig->m_bFastNoBump) - { - if (bHasBump) - { - pShader->BindTexture(SHADER_SAMPLER3, info.m_nBumpmap); - } - else - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); - } - } - else - { - if (bHasBump) - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); - } - } - - pShader->BindTexture(SHADER_SAMPLER8, info.m_nBRDF); - - LightState_t lightState = { 0, false, false }; - bool bFlashlightShadows = false; - if( bHasFlashlight ) - { - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); - - SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - } - else // no flashlight - { - pShaderAPI->GetDX9LightState( &lightState ); - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - - bool bWriteDepthToAlpha = false; - bool bWriteWaterFogToAlpha = false; - if( bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - - DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedpbr_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, true); - SET_DYNAMIC_VERTEX_SHADER(lightmappedpbr_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(lightmappedpbr_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CUBEMAPCORRECTED, isEnvmapCorrected && mat_cubemapparallax.GetBool()); - SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHT_PREVIEW, pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM, bUseCSM && !bHasFlashlight ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM_PERF, MAX( 0, MIN( r_csm_performance.GetInt(), 2 ) ) ); // i just dont know anymore - SET_DYNAMIC_PIXEL_SHADER(lightmappedpbr_ps30); - - if (bSeamlessMapping) - { - float scale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant(VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &scale); - } - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform ); - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - pShader->SetAmbientCubeDynamicStateVertexShader(); - - // handle mat_fullbright 2 (diffuse lighting only) - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1); - - if( bHasFlashlight ) - { - VMatrix worldToTexture; - float atten[4], pos[4], tweaks[4]; - - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - - float const* pFlashlightColor = flashlightState.m_Color; - float vPsConst[4] = { pFlashlightColor[0], pFlashlightColor[1], pFlashlightColor[2], 4.5f }; - pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_COLOR, vPsConst, 1); - - pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); - - // Tweaks associated with a given flashlight - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - } - else - { - if ( bUseCSM ) - { - pShader->BindTexture( SHADER_SAMPLER4, pCascadedDepthTexture ); - - VMatrix *worldToTexture0 = (VMatrix *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0 ); - pShaderAPI->SetPixelShaderConstant( 22, worldToTexture0->Base(), 4 ); - - lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); - Vector csmFwd = csmData.vecLight; - pShaderAPI->SetPixelShaderConstant( 26, csmFwd.Base() ); - - Vector csmLight = csmData.light.AsVector3D(); - pShaderAPI->SetPixelShaderConstant( 27, csmLight.Base() ); - - Vector csmAmbient = csmData.ambient.AsVector3D(); - pShaderAPI->SetPixelShaderConstant( 28, csmAmbient.Base() ); - - float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; - pShaderAPI->SetPixelShaderConstant( 31, biasVar ); - - float textureSize[2] = { pCascadedDepthTexture->GetActualWidth(), pCascadedDepthTexture->GetActualHeight() }; - pShaderAPI->SetPixelShaderConstant( 32, textureSize ); - - pShaderAPI->SetPixelShaderConstant( 33, GetDeferredExt()->GetLightData_Global().sizes.Base() ); - } - } - } - pShader->Draw(); -} - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bHasFlashlight, - LightmappedPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) - -{ - DrawLightmappedPBR_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/Refract_model_vs11.vsh b/materialsystem/stdshaders/Refract_model_vs11.vsh deleted file mode 100644 index a6eea2b7..00000000 --- a/materialsystem/stdshaders/Refract_model_vs11.vsh +++ /dev/null @@ -1,105 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -;------------------------------------------------------------------------------ -; Constants specified by the app -; c0 = (0, 1, 2, 0.5) -; c1 = (1/2.2, 0, 0, 0) -; c2 = camera position *in world space* -; c4-c7 = modelViewProj matrix (transpose) -; c8-c11 = ViewProj matrix (transpose) -; c12-c15 = model->view matrix (transpose) -; c16 = [fogStart, fogEnd, fogRange, undefined] -; -; Vertex components (as specified in the vertex DECL) -; $vPos = Position -; $vTexCoord0.xy = TexCoord0 -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -; Vertex components -; $vPos = Position -; $vNormal = normal -; $vTexCoord0.xy = TexCoord0 -; $vTangentS = S axis of Texture space -; $vTangentT = T axis of Texture space - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -alloc $worldPos -alloc $worldNormal -alloc $worldTangentS -alloc $worldTangentT - -&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, - $worldTangentS, $worldTangentT ); - -alloc $projPos - -; Transform position from world to projection space -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 - -&CalcFog( $worldPos, $projPos ); - -alloc $worldEyeVect - -; Get the eye vector in world space -add $worldEyeVect.xyz, -$worldPos, $cEyePos - -alloc $tangentEyeVect -; transform the eye vector to tangent space -dp3 oT3.x, $worldEyeVect, $worldTangentS -dp3 oT3.y, $worldEyeVect, $worldTangentT -dp3 oT3.z, $worldEyeVect, $worldNormal - -alloc $bumpTexCoord - -dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - -; dudv map -mov oT0.xy, $bumpTexCoord - -; refract tint + alpha channel -mov oT2.xy, $bumpTexCoord -mov oT3.xy, $bumpTexCoord - -free $bumpTexCoord - -mov oPos, $projPos - -; special case perspective correct texture projection so that the texture fits exactly on the screen - -; flip Y by multiplying by -1 -mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w - -; transform from [-w,w] to [0,2*w] -; The reason this is w is because we are in perspective space/homogenous clip space. -add $projPos.xy, $projPos.xy, $projPos.w - -; transform from [0,2*w] to [0,w] -; We'll end up dividing by w in the pixel shader to get to [0,1] -mul $projPos.xy, $projPos.xy, $cHalf - -mov oT1.xy, $projPos.xy - -; emit w to both z and w in case the driver screws up and divides by z -mov oT1.z, $projPos.w -mov oT1.w, $projPos.w - -free $projPos -free $worldPos -free $worldEyeVect -free $tangentEyeVect -free $w -free $worldNormal -free $worldTangentS -free $worldTangentT diff --git a/materialsystem/stdshaders/Refract_ps11.psh b/materialsystem/stdshaders/Refract_ps11.psh deleted file mode 100644 index a4e59bf6..00000000 --- a/materialsystem/stdshaders/Refract_ps11.psh +++ /dev/null @@ -1,36 +0,0 @@ -; STATIC: "REFRACTTINTTEXTURE" "0..1" -; STATIC: "NORMALMAPALPHA" "0..1" - -ps.1.1 - -; t0: -; texture: dudv map -; texcoords: dudvmap texcoords -; t1: -; texture: refraction render target -; texcoords: - -tex t0 ; sample dudv map -texbem t1, t0 ; refraction - -#if REFRACTTINTTEXTURE -tex t2 -#endif - -#if NORMALMAPALPHA -tex t3 -#endif - -; refracttint -#if REFRACTTINTTEXTURE -mul_x2 r0, t1, t2 -#else -mov r0, t1 -#endif - -#if NORMALMAPALPHA -mul r0.rgb, r0, c0 + -mov r0.a, t3.a -#else -mul r0.rgb, r0, c0 -#endif diff --git a/materialsystem/stdshaders/Refract_vs20.fxc b/materialsystem/stdshaders/Refract_vs20.fxc deleted file mode 100644 index 698dd192..00000000 --- a/materialsystem/stdshaders/Refract_vs20.fxc +++ /dev/null @@ -1,140 +0,0 @@ -//====== Copyright 1996-2005, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "MODEL" "0..1" -// STATIC: "COLORMODULATE" "0..1" - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const bool g_bModel = MODEL ? true : false; - -const float4 cBumpTexCoordTransform[4] : register( SHADER_SPECIFIC_CONST_1 ); - -const float g_flTime : register( SHADER_SPECIFIC_CONST_5 ); - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vBaseTexCoord : TEXCOORD0; -#if !MODEL - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL0; -#else - float4 vUserData : TANGENT; -#endif -#if COLORMODULATE - float4 vColor : COLOR0; -#endif -}; - -struct VS_OUTPUT -{ - float4 vProjPos_POSITION : POSITION; -#if !defined( _X360 ) - float vFog : FOG; -#endif - float4 vBumpTexCoord : TEXCOORD0; - float3 vTangentEyeVect : TEXCOORD1; - float3 vWorldNormal : TEXCOORD2; - float3 vWorldTangent : TEXCOORD3; - float3 vWorldBinormal : TEXCOORD4; - float3 vRefractXYW : TEXCOORD5; - float3 vWorldViewVector : TEXCOORD6; -#if COLORMODULATE - float4 vColor : COLOR0; -#endif - float4 fogFactorW : COLOR1; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - -#if COLORMODULATE - o.vColor = v.vColor; -#endif - - float3 worldNormal, worldPos, worldTangentS, worldTangentT; - - float3 vObjNormal; -#if MODEL - float4 vObjTangent; - DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent ); - - SkinPositionNormalAndTangentSpace( - g_bSkinning, - v.vPos, vObjNormal, vObjTangent, - v.vBoneWeights, v.vBoneIndices, - worldPos, worldNormal, worldTangentS, worldTangentT ); -#else - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - worldPos = mul( v.vPos, cModel[0] ); - worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); - worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); - worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); -#endif - - // World normal - o.vWorldNormal.xyz = normalize( worldNormal.xyz ); - - // Projected position - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.vProjPos_POSITION = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); - //o.projNormal.xyz = mul( worldNormal, cViewProj ); - - // Map projected position to the refraction texture - float2 vRefractPos; - vRefractPos.x = vProjPos.x; - vRefractPos.y = -vProjPos.y; // invert Y - vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; - - // Refraction transform - o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w); - - // Compute fog based on the position - float3 vWorldPos = mul( v.vPos, cModel[0] ); - o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); -#if !defined( _X360 ) - o.vFog = o.fogFactorW; -#endif - - // Eye vector - float3 vWorldEyeVect = normalize( cEyePos - vWorldPos ); - o.vWorldViewVector.xyz = -vWorldEyeVect.xyz; - - // Transform to the tangent space - o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS ); - o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT ); - o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal ); - - // Tranform bump coordinates - o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); - o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); - - // Tranform bump coordinates (note wz, not zw) - o.vBumpTexCoord.w = dot( v.vBaseTexCoord, cBumpTexCoordTransform[2] ); - o.vBumpTexCoord.z = dot( v.vBaseTexCoord, cBumpTexCoordTransform[3] ); - - - // Tangent space transform - o.vWorldNormal.xyz = normalize( worldNormal.xyz ); - o.vWorldTangent.xyz = worldTangentS.xyz; - o.vWorldBinormal.xyz = worldTangentT.xyz; - - return o; -} diff --git a/materialsystem/stdshaders/Refract_world_vs11.vsh b/materialsystem/stdshaders/Refract_world_vs11.vsh deleted file mode 100644 index 90f0debe..00000000 --- a/materialsystem/stdshaders/Refract_world_vs11.vsh +++ /dev/null @@ -1,168 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; Constants specified by the app -; c0 = (0, 1, 2, 0.5) -; c1 = (1/2.2, 0, 0, 0) -; c2 = camera position *in world space* -; c4-c7 = modelViewProj matrix (transpose) -; c8-c11 = ViewProj matrix (transpose) -; c12-c15 = model->view matrix (transpose) -; c16 = [fogStart, fogEnd, fogRange, undefined] -; -; Vertex components (as specified in the vertex DECL) -; $vPos = Position -; $vTexCoord0.xy = TexCoord0 -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -; Vertex components -; $vPos = Position -; $vNormal = normal -; $vTexCoord0.xy = TexCoord0 -; $vTangentS = S axis of Texture space -; $vTangentT = T axis of Texture space - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -alloc $worldPos -alloc $worldNormal -alloc $worldTangentS -alloc $worldTangentT -alloc $projPos - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -dp3 $worldPos.x, $vPos, $cModel0 -dp3 $worldPos.y, $vPos, $cModel1 -dp3 $worldPos.z, $vPos, $cModel2 - -dp3 $worldNormal.x, $vNormal, $cModel0 -dp3 $worldNormal.y, $vNormal, $cModel1 -dp3 $worldNormal.z, $vNormal, $cModel2 - -dp3 $worldTangentS.x, $vTangentS, $cModel0 -dp3 $worldTangentS.y, $vTangentS, $cModel1 -dp3 $worldTangentS.z, $vTangentS, $cModel2 - -dp3 $worldTangentT.x, $vTangentT, $cModel0 -dp3 $worldTangentT.y, $vTangentT, $cModel1 -dp3 $worldTangentT.z, $vTangentT, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -alloc $worldEyeVect - -; Get the eye vector in world space -add $worldEyeVect.xyz, -$worldPos, $cEyePos - -alloc $tangentEyeVect -alloc $bumpTexCoord - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $worldTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $worldTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $worldNormal - -&Normalize( $tangentEyeVect ); - -; stick the tangent space eye vector into oD0 -mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf - -dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - -; dudv map -mov oT0.xy, $bumpTexCoord - -; refract tint -mov oT3.xy, $bumpTexCoord - -free $bumpTexCoord - -alloc $newProjPos -alloc $w - -mov oPos, $projPos - -; special case perspective correct texture projection so that the texture fits exactly on the screen -mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w -add $projPos.xy, $projPos.xy, $projPos.w -mul $projPos.xy, $projPos.xy, $cHalf - -; Do the perspective divide here. .yuck . . we aren't going to be perspective correct -rcp $w.w, $projPos.w -mul $projPos, $projPos, $w.w - -#max $projPos.x, $projPos.x, -$cOne -#min $projPos.x, $projPos.x, $cOne -#max $projPos.z, $projPos.z, $cZero -#min $projPos.z, $projPos.z, $cOne - -;------------------------------------------------------------------------------ -; Transform the tangentS from world to view space -;------------------------------------------------------------------------------ - -alloc $projTangentS - -; we only care about x and y -dp3 $projTangentS.x, $worldTangentS, $cViewProj0 -dp3 $projTangentS.y, $worldTangentS, $cViewProj1 - -; project tangentS -mul $projTangentS.xy, $projTangentS.xy, $w.w - -;max $projTangentS.xy, $projTangentS.xy, $cOne -;min $projTangentS.xy, $projTangentS.xy, -$cOne - -;------------------------------------------------------------------------------ -; Transform the tangentT from world to view space -;------------------------------------------------------------------------------ - -alloc $projTangentT -alloc $texCoord - -; we only care about x and y -dp3 $projTangentT.x, $worldTangentT, $cViewProj0 -dp3 $projTangentT.y, $worldTangentT, $cViewProj1 - -; project tangentT -mul $projTangentT.xy, $projTangentT.xy, $w.w - -;max $projTangentT.xy, $projTangentT.xy, $cOne -;min $projTangentT.xy, $projTangentT.xy, -$cOne - -;max $projPos.xy, $projPos.xy, $cOne -;min $projPos.xy, $projPos.xy, -$cOne - -mul oT1.x, $projTangentS.x, $SHADER_SPECIFIC_CONST_3.x -mul oT1.y, $projTangentT.x, $SHADER_SPECIFIC_CONST_3.x -mov oT1.z, $projPos.x ; huh? - -mul $texCoord.x, $projTangentS.y, -$SHADER_SPECIFIC_CONST_3.x -mul $texCoord.y, $projTangentT.y, -$SHADER_SPECIFIC_CONST_3.x -mov $texCoord.z, $projPos.y -mov oT2.xyz, $texCoord -mov oT3.xyz, $texCoord - -free $texCoord -free $projPos -free $worldPos -free $worldEyeVect -free $tangentEyeVect -free $w -free $projTangentS -free $projTangentT -free $newProjPos -free $worldNormal -free $worldTangentS -free $worldTangentT diff --git a/materialsystem/stdshaders/SDK_Bloom_ps2x.fxc b/materialsystem/stdshaders/SDK_Bloom_ps2x.fxc deleted file mode 100644 index 1bad205e..00000000 --- a/materialsystem/stdshaders/SDK_Bloom_ps2x.fxc +++ /dev/null @@ -1,21 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler FBSampler : register( s0 ); -sampler BlurSampler : register( s1 ); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 fbSample = tex2D( FBSampler, i.texCoord ); - float4 blurSample = tex2D( BlurSampler, i.texCoord ); - - return FinalOutput( float4( fbSample + blurSample.rgb * blurSample.a * MAX_HDR_OVERBRIGHT, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/SDK_bloomadd_ps11.fxc b/materialsystem/stdshaders/SDK_bloomadd_ps11.fxc deleted file mode 100644 index 745c92f1..00000000 --- a/materialsystem/stdshaders/SDK_bloomadd_ps11.fxc +++ /dev/null @@ -1,18 +0,0 @@ -//======= Copyright 1996-2006, Valve Corporation, All rights reserved. ====== -#define CONVERT_TO_SRGB 0 - -#include "common_ps_fxc.h" - -sampler TexSampler : register( s0 ); - -struct PS_INPUT -{ - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 result = tex2D( TexSampler, i.baseTexCoord ); - result.a = 1.0f; - return result; //FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/SDK_lightmappedgeneric_decal_ps2x.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_decal_ps2x.fxc new file mode 100644 index 00000000..d6680511 --- /dev/null +++ b/materialsystem/stdshaders/SDK_lightmappedgeneric_decal_ps2x.fxc @@ -0,0 +1,59 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler LightMap0Sampler : register( s1 ); +sampler LightMap1Sampler : register( s2 ); +sampler LightMap2Sampler : register( s3 ); + +const float4 g_LightMap0Color : register( c0 ); +const float4 g_LightMap1Color : register( c1 ); +const float4 g_LightMap2Color : register( c2 ); +const float4 g_ModulationColor : register( c3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + + +struct PS_INPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog + + float4 vColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 resultColor; + + // output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + + // lightmapColor[1] * ( ( N dot basis[1] )^2 ) + + // lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + resultColor = tex2D( LightMap0Sampler, i.vTexCoord1 ) * g_LightMap0Color; + resultColor = (tex2D( LightMap1Sampler, i.vTexCoord2 ) * g_LightMap1Color) + resultColor; + resultColor = (tex2D( LightMap2Sampler, i.vTexCoord3 ) * g_LightMap2Color) + resultColor; + + // Modulate by decal texture + float4 decalColor = tex2D( BaseTextureSampler, i.vTexCoord0 ); + resultColor.rgb = resultColor * decalColor; + resultColor.a = decalColor.a; + + // Modulate by constant color + resultColor = resultColor * g_ModulationColor; + + // Modulate by per-vertex factor + resultColor = resultColor * i.vColor; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_decal_vs20.fxc similarity index 100% rename from materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc rename to materialsystem/stdshaders/SDK_lightmappedgeneric_decal_vs20.fxc diff --git a/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_ps2x.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_ps2x.fxc new file mode 100644 index 00000000..d8e7e885 --- /dev/null +++ b/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_ps2x.fxc @@ -0,0 +1,330 @@ +//====== Copyright c 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + + + +// STATIC: "NORMALMAP" "0..2" +// STATIC: "NORMALMAP2" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "FANCY_BLENDING" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [ps30] [PC] +// STATIC: "PHONG" "0..1" [ps20b] [ps30] +// STATIC: "PHONGMASK" "0..3" [ps20b] [ps30] +// STATIC: "BASETEXTURETRANSFORM2" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] [ps30] + +// SKIP: !$WORLDVERTEXTRANSITION && $NORMALMAP2 +// SKIP: !$NORMALMAP && $NORMALMAP2 +// SKIP: !$DETAILTEXTURE && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: !$PHONG && $PHONGMASK +// SKIP: $BASETEXTURETRANSFORM2 && !$WORLDVERTEXTRANSITION +// SKIP: $BASETEXTURETRANSFORM2 && $SEAMLESS +// SKIP: $BASETEXTURETRANSFORM2 && $PHONG + +#include "shader_constant_register_map.h" +#include "common_flashlight_fxc.h" +#include "common_lightmappedgeneric_fxc.h" + +const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FlashlightAttenuation : register( PSREG_FLASHLIGHT_ATTENUATION ); +const float4 g_DetailConstants : register( c0 ); +const float4 g_FlashlightPos : register( c1 ); +const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); + +#define g_SpecularExponent g_EyePos.w +#define g_FresnelRanges g_FresnelSpecParams.xyz +#define g_SpecularBoost g_FresnelSpecParams.w + +#define PHONGMASK_BASEALPHA 1 +#define PHONGMASK_NORMALALPHA 2 +#define PHONGMASK_STANDALONE 3 + +sampler SpotSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); +sampler NormalizingCubemapSampler : register( s2 ); + +// use a normalizing cube map here if we aren't normal mapping +sampler BumpMapSampler : register( s3 ); +sampler BaseTextureSampler2 : register( s4 ); + +#ifdef WORLDVERTEXTRANSITION +sampler NormalMap2Sampler : register( s6 ); +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s8 ); +#endif + +#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) +sampler RandomRotationSampler : register( s5 ); // Random rotation sampler +sampler FlashlightDepthSampler : register( s7 ); +#endif + +#if PHONGMASK == PHONGMASK_STANDALONE +sampler PhongMaskSampler : register( s9 ); +#endif + +#if FANCY_BLENDING +sampler BlendModulationSampler : register( s10 ); +#endif + +struct PS_INPUT +{ + float4 spotTexCoord : TEXCOORD0; +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD1; +#else +#if BASETEXTURETRANSFORM2 + // Blixibon - Using two extra floats for $basetexturetransform2 + float4 baseTexCoord : TEXCOORD1; +#else + float2 baseTexCoord : TEXCOORD1; +#endif +#endif +#if NORMALMAP +#if PHONG + float4 tangentPosToLightVector : TEXCOORD2; + float4 normalMapTexCoord : TEXCOORD3; +#else + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#endif +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + + float2 detailCoords : TEXCOORD4; + float4 worldPos_worldTransition : TEXCOORD5; + float3 projPos : TEXCOORD6; + float4 fogFactorW : TEXCOORD7; +}; + + + +float4 SampleNormal( sampler s, PS_INPUT i ) +{ +#if SEAMLESS + float4 szy=tex2D( s, i.SeamlessTexCoord.zy ); + float4 sxz=tex2D( s, i.SeamlessTexCoord.xz ); + float4 syx=tex2D( s, i.SeamlessTexCoord.xy ); + return i.fogFactorW.r*szy + i.fogFactorW.g*sxz + i.fogFactorW.b*syx; +#else +#if NORMALMAP + return tex2D( s, i.normalMapTexCoord.xy); +#else + return float4(0,0,1,1); +#endif +#endif + +} + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBase2 = WORLDVERTEXTRANSITION ? true : false; + bool bBump = (NORMALMAP != 0) ? true : false; + + // Do spot stuff early since we can bail out + float3 spotColor = float3(0,0,0); + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); + + [branch] + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + { + clip (-1); + return float4(0,0,0,0); + } + else + { + spotColor = tex2D( SpotSampler, vProjCoords ); + + [branch] + if ( dot(spotColor.xyz, float3(1,1,1)) <= 0 ) + { + clip(-1); + return float4(0,0,0,0); + } + else + { +#else + clip( vProjCoords.xyz ); +#if defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) + clip( 1-vProjCoords.xyz ); +#endif + spotColor = tex2D( SpotSampler, vProjCoords ); +#endif + + float4 baseColor = 0.0f; + float4 baseColor2 = 0.0f; + float4 vNormal = float4(0, 0, 1, 1); + float3 baseTexCoords = float3(0,0,0); + +#if SEAMLESS + baseTexCoords = i.SeamlessTexCoord.xyz; +#else + baseTexCoords.xy = i.baseTexCoord.xy; +#endif + +#if BASETEXTURETRANSFORM2 + // Blixibon - Simpler version of GetBaseTextureAndNormal() that supports $basetexturetransform2 + // (This is duplicated in the original shader, but make this its own function in common_lightmappedgeneric_fxc.h if this becomes more widespread) + baseColor = tex2D( BaseTextureSampler, baseTexCoords.xy ); + baseColor2 = tex2D( BaseTextureSampler2, i.baseTexCoord.wz ); + if ( bBump ) + { + vNormal = tex2D( BumpMapSampler, baseTexCoords.xy ); + } +#else + GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpMapSampler, bBase2, bBump, baseTexCoords, i.fogFactorW.xyz, baseColor, baseColor2, vNormal ); +#endif + +#if WORLDVERTEXTRANSITION + float lerpAlpha = i.worldPos_worldTransition.a; + + // Blixibon +#if (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING) + float4 modt=tex2D(BlendModulationSampler,baseTexCoords); + + float minb=saturate(modt.g-modt.r); + float maxb=saturate(modt.g+modt.r); + lerpAlpha=smoothstep(minb,maxb,lerpAlpha); +#endif + +#endif + +#if ( NORMALMAP == 0 ) + vNormal.xyz = normalize( i.normal.xyz ); +#endif + +#if ( NORMALMAP == 1 ) + vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // signed + +# if NORMALMAP2 + float3 normal2 = SampleNormal( NormalMap2Sampler, i ) * 2.0f - 1.0f; + vNormal.xyz = lerp( vNormal.xyz, normal2, lerpAlpha ); +# endif +#endif + +// ssbump +#if ( NORMALMAP == 2 ) + +# if NORMALMAP2 + float3 normal2 = SampleNormal( NormalMap2Sampler, i ); + vNormal.xyz = lerp( vNormal.xyz, normal2, lerpAlpha ); +# endif +#else + // Normalize normal after all of the lerps above (including the tri/bilinear texel fetches) + vNormal.xyz = normalize( vNormal.xyz ); +#endif + + spotColor.rgb *= cFlashlightColor.rgb; + + // Compute per-pixel distance attenuation + float3 delta = g_FlashlightPos.xyz - i.worldPos_worldTransition.xyz; + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + float farZ = g_FlashlightAttenuation.w; + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + float flAtten = saturate(endFalloffFactor * dot( g_FlashlightAttenuation.xyz, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + +#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, false ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate(lerp( flAttenuated, flShadow, flAtten )); // Blend between shadow and above, according to light attenuation + spotColor *= flShadow; +#endif + +#if WORLDVERTEXTRANSITION && !defined( SHADER_MODEL_PS_2_0 ) + baseColor = lerp( baseColor, baseColor2, lerpAlpha ); +#endif + +#if PHONG + float3 vSpecMask = 1; + +# if PHONGMASK == PHONGMASK_BASEALPHA + vSpecMask = baseColor.a; +# elif PHONGMASK == PHONGMASK_NORMALALPHA + vSpecMask = vNormal.a; +# elif PHONGMASK == PHONGMASK_STANDALONE + vSpecMask = tex2D( PhongMaskSampler, baseTexCoords ).rgb; +# endif +#endif + +#if DETAILTEXTURE + float4 detailColor = float4( g_DetailConstants.xyz, 1.0f ) * tex2D( DetailSampler, i.detailCoords ); + float4 vBase = TextureCombine( float4(baseColor.xyz, 1.0f), detailColor, DETAIL_BLEND_MODE, g_DetailConstants.w ); + baseColor.xyz = vBase.xyz; +#endif + +#if NORMALMAP == 0 + float3 worldPosToLightVector = texCUBE( NormalizingCubemapSampler, i.worldPosToLightVector ) * 2.0f - 1.0f; + float nDotL = dot( worldPosToLightVector, vNormal.xyz ); +#endif + +#if NORMALMAP == 1 + // flashlightfixme: wrap this! + float3 tangentPosToLightVector = texCUBE( NormalizingCubemapSampler, i.tangentPosToLightVector.xyz ) * 2.0f - 1.0f; + float nDotL = dot( tangentPosToLightVector, vNormal.xyz ); +#endif + +#if NORMALMAP == 2 + float3 tangentPosToLightVector = texCUBE( NormalizingCubemapSampler, i.tangentPosToLightVector.xyz ) * 2.0f - 1.0f; + + float nDotL = + vNormal.x*dot( tangentPosToLightVector, bumpBasis[0]) + + vNormal.y*dot( tangentPosToLightVector, bumpBasis[1]) + + vNormal.z*dot( tangentPosToLightVector, bumpBasis[2]); +#endif + + float3 outColor; +#if PHONG == 0 + outColor = spotColor * baseColor.xyz * saturate( nDotL ); + outColor *= flAtten; +#else + outColor = spotColor * baseColor.xyz * flAtten; + + // Not using normalizing cubemap here because of pixelated specular appearance. =/ +# if NORMALMAP == 0 + float3 posToLight = normalize( i.worldPosToLightVector ); + float3 posToEye = normalize( g_EyePos.xyz - i.worldPos_worldTransition.xyz); +# else + float3 posToLight = normalize( i.tangentPosToLightVector.xyz ); + float3 posToEye = normalize( float3(i.tangentPosToLightVector.w, i.normalMapTexCoord.zw) ); + +# if NORMALMAP == 2 + vNormal.xyz = bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z; + vNormal.xyz = normalize( vNormal.xyz ); +# endif +# endif + + float fFresnel = Fresnel( vNormal.xyz, posToEye, g_FresnelRanges ); + float3 specularColor = outColor * SpecularLight( vNormal.xyz, posToLight, g_SpecularExponent, posToEye, false, SpotSampler, fFresnel ); + outColor *= saturate( nDotL ); + outColor += specularColor * fFresnel * vSpecMask * g_SpecularBoost; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_worldTransition.z, i.projPos.z ); + return FinalOutput( float4(outColor, baseColor.a) , fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); + + // so we can jump over all of the above +#if ( defined( _X360 ) ) + } + } +#endif + +} \ No newline at end of file diff --git a/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_vs20.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_vs20.fxc new file mode 100644 index 00000000..19afa219 --- /dev/null +++ b/materialsystem/stdshaders/SDK_lightmappedgeneric_flashlight_vs20.fxc @@ -0,0 +1,217 @@ +//====== Copyright ? 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "NORMALMAP" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "DETAIL" "0..1" +// STATIC: "PHONG" "0..1" +// STATIC: "BASETEXTURETRANSFORM2" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +// SKIP: $BASETEXTURETRANSFORM2 && !$WORLDVERTEXTRANSITION +// SKIP: $BASETEXTURETRANSFORM2 && $SEAMLESS +// SKIP: $BASETEXTURETRANSFORM2 && $PHONG + +#include "common_vs_fxc.h" + +const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); +const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_6 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#endif +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cNormalMapOrDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); +#if PHONG +const float3 g_EyePos : register( SHADER_SPECIFIC_CONST_10 ); +#elif BASETEXTURETRANSFORM2 +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_10 ); // Blixibon - Support for $basetexturetransform2 +#endif + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float3 vPos : POSITION; //This HAS to match lightmappedgeneric_vs20.fxc's position input. Otherwise depth fighting errors occur on the 360 + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; +#if WORLDVERTEXTRANSITION + float2 vLightmapTexCoord : TEXCOORD1; + float4 vColor : COLOR0; +#endif +#if NORMALMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + + float4 spotTexCoord : TEXCOORD0; + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD1; +#else +#if BASETEXTURETRANSFORM2 + // Blixibon - Using two extra floats for $basetexturetransform2 + float4 baseTexCoord : TEXCOORD1; +#else + float2 baseTexCoord : TEXCOORD1; +#endif +#endif + +#if NORMALMAP +#if PHONG + float4 tangentPosToLightVector : TEXCOORD2; + float4 normalMapTexCoord : TEXCOORD3; +#else + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#endif +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + + float2 detailCoords : TEXCOORD4; + float4 worldPos_worldTransition : TEXCOORD5; + float3 vProjPos : TEXCOORD6; + float4 fogFactorW : TEXCOORD7; +}; + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + float3 worldNormal; + float3 eyeVector; + + //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360 + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + o.vProjPos.xyz = projPos.xyw; + + worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + + o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f ); + + o.fogFactorW = CalcFog( worldPos, projPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + +#if NORMALMAP + float3 worldTangentS = mul( v.vTangentS, cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, cModel[0] ); +#endif +#if SEAMLESS + float3 vNormal=normalize( worldNormal ); + o.fogFactorW.xyz = vNormal * vNormal; // sums to 1. + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + + // Generate new tangent and binormal with seamless projection + #if NORMALMAP + // Brute-force for prototype - This must match the projection in the pixel shader! + //float3 vVecX = { 1.0f, 0.0f, 0.0f }; + //float3 vVecY = { 0.0f, 1.0f, 0.0f }; + //float3 vVecZ = { 0.0f, 0.0f, 1.0f }; + //worldTangentS.xyz = normalize( ( o.fogFactorW.x * vVecZ.xyz ) + ( o.fogFactorW.y * vVecX.xyz ) + ( o.fogFactorW.z * vVecX.xyz ) ); + //worldTangentT.xyz = normalize( ( o.fogFactorW.x * vVecY.xyz ) + ( o.fogFactorW.y * vVecZ.xyz ) + ( o.fogFactorW.z * vVecY.xyz ) ); + + // Optimized version - This must match the projection in the pixel shader! + worldTangentS.xyz = normalize( float3( o.fogFactorW.y + o.fogFactorW.z, 0.0f, o.fogFactorW.x ) ); + worldTangentT.xyz = normalize( float3( 0.0f, o.fogFactorW.x + o.fogFactorW.z, o.fogFactorW.y ) ); + #endif +#else +#if (SEAMLESS == 0 ) + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; +#if BASETEXTURETRANSFORM2 + o.baseTexCoord.w = dot( v.vBaseTexCoord, cBaseTexCoordTransform2[0] ) + cBaseTexCoordTransform2[0].w; + o.baseTexCoord.z = dot( v.vBaseTexCoord, cBaseTexCoordTransform2[1] ) + cBaseTexCoordTransform2[1].w; +#endif +#endif +#endif + + float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.spotTexCoord = spotTexCoord.xyzw; + + float3 worldPosToLightVector = g_FlashlightPos - worldPos; +#if NORMALMAP + +#if (DETAIL == 0) + o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + +#if SEAMLESS + o.normalMapTexCoord.xy = v.vBaseTexCoord; +#else + o.normalMapTexCoord.xy = o.baseTexCoord.xy; // Blixibon - Had to change this to .xy because BASETEXTURETRANSFORM2 makes this float4 +#endif + +#endif + + o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); + o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); + o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); + +#if PHONG + float3 worldPosToEyeVector = g_EyePos - worldPos; + o.tangentPosToLightVector.w = dot( worldPosToEyeVector, worldTangentS ); + o.normalMapTexCoord.z = dot( worldPosToEyeVector, worldTangentT ); + o.normalMapTexCoord.w = dot( worldPosToEyeVector, worldNormal ); +#endif + +#else + o.worldPosToLightVector = worldPosToLightVector; + o.normal = worldNormal; +#endif + +#if DETAIL + o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + o.detailCoords = float2(0,0); +#endif + + //float3 delta = worldPosToLightVector; + //float distSquared = dot( delta, delta ); + //float dist = sqrt( distSquared ); + //float farZ = g_FlashlightAttenuationFactors.w; + //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ); + //o.projPos_atten.w = saturate( o.projPos_atten.w ); + +#if WORLDVERTEXTRANSITION + o.worldPos_worldTransition.w = v.vColor.w; +#endif + + return o; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/SDK_lightmappedgeneric_ps20b.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_ps20b.fxc new file mode 100644 index 00000000..d49a33a6 --- /dev/null +++ b/materialsystem/stdshaders/SDK_lightmappedgeneric_ps20b.fxc @@ -0,0 +1,51 @@ +// STATIC: "MASKEDBLENDING" "0..1" +// STATIC: "BASETEXTURE2" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..2" +// STATIC: "BUMPMAP2" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "BASETEXTURENOENVMAP" "0..1" +// STATIC: "BASETEXTURE2NOENVMAP" "0..1" +// STATIC: "WARPLIGHTING" "0..1" +// STATIC: "FANCY_BLENDING" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" [ps20b] +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC] +// STATIC: "DETAIL_BLEND_MODE" "0..11" +// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX] +// STATIC: "BASETEXTURETRANSFORM2" "0..1" +// STATIC: "PARALLAXCORRECT" "0..1" + +// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// SKIP: ($DETAIL_BLEND_MODE == 2 ) || ($DETAIL_BLEND_MODE == 3 ) || ($DETAIL_BLEND_MODE == 4 ) +// SKIP: ($DETAIL_BLEND_MODE == 5 ) || ($DETAIL_BLEND_MODE == 6 ) || ($DETAIL_BLEND_MODE == 7 ) +// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 ) +// SKIP ($DETAIL_BLEND_MODE == 10 ) +// SKIP ($DETAIL_BLEND_MODE == 11 ) + +// SKIP: $PARALLAXCORRECT && !$CUBEMAP + +#include "lightmappedgeneric_ps2_3_x.h" + diff --git a/materialsystem/stdshaders/SDK_lightmappedgeneric_vs20.fxc b/materialsystem/stdshaders/SDK_lightmappedgeneric_vs20.fxc new file mode 100644 index 00000000..763272fb --- /dev/null +++ b/materialsystem/stdshaders/SDK_lightmappedgeneric_vs20.fxc @@ -0,0 +1,268 @@ +// STATIC: "ENVMAP_MASK" "0..1" +// STATIC: "TANGENTSPACE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "FLASHLIGHT" "0..1" [XBOX] +// STATIC: "BASETEXTURETRANSFORM2" "0..1" + +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] + +// SKIP: $SEAMLESS && $BASETEXTURETRANSFORM2 + +// This should not be a combo since I'm a moron with the tangent space and the flashlight. +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $SEAMLESS + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; +static const bool g_bTangentSpace = TANGENTSPACE; +static const bool g_bBumpmap = BUMPMAP; +static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; +static const bool g_bVertexColor = VERTEXCOLOR; +static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; +static const bool g_BumpMask = BUMPMASK; + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#else +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +#if BASETEXTURETRANSFORM2 +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_8 ); // Blixibon - Support for $basetexturetransform2 +#endif +const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +#endif +// This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset. +const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest! + +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) && !defined(SHADER_MODEL_VS_3_0) + float fog : FOG; +#endif + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD0; // x y z + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask +#else +#if BASETEXTURETRANSFORM2 + // Blixibon - Using two extra floats for $basetexturetransform2 + float4 baseTexCoord : TEXCOORD0; +#else + float2 baseTexCoord : TEXCOORD0; +#endif + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. +#if RELIEF_MAPPING + float3 TangentSpaceViewRay : TEXCOORD1; +#else + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; +#endif +#endif + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale + float4 worldPos_projPosZ : TEXCOORD4; + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 +#endif + + float4 vertexColor : COLOR; // in seamless, r g b = blend weights + float4 vertexBlendX_fogFactorW : COLOR1; + + // Extra iterators on 360, used in flashlight combo +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; + float4 vProjPos : TEXCOORD9; +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + + float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + + #if SEAMLESS && BUMPMAP && defined( _X360 ) + float3 n = normalize( worldNormal ); + float3 n2 = n * n; // sums to 1. + + o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) ); + o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) ); + o.tangentSpaceTranspose[2] = worldNormal; + #else + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + #endif + +#endif + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + +#if SEAMLESS + { + // we need to fill in the texture coordinate projections + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + } +#else + { + if (FASTPATH) + { + o.baseTexCoord.xy = v.vBaseTexCoord; +#if BASETEXTURETRANSFORM2 + o.baseTexCoord.wz = v.vBaseTexCoord; +#endif + } + else + { + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; +#if BASETEXTURETRANSFORM2 + o.baseTexCoord.w = dot( v.vBaseTexCoord, cBaseTexCoordTransform2[0] ) + cBaseTexCoordTransform2[0].w; + o.baseTexCoord.z = dot( v.vBaseTexCoord, cBaseTexCoordTransform2[1] ) + cBaseTexCoordTransform2[1].w; +#endif + } +#if ( RELIEF_MAPPING == 0 ) + { + // calculate detailorbumptexcoord + if ( FASTPATH ) + o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; + else + { + o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w; + } + } +#endif + } +#endif + if ( FASTPATH ) + { + o.lightmapTexCoord3.zw = v.vBaseTexCoord; + } + else + { + o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w; + o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w; + } + + // compute lightmap coordinates + if( g_bBumpmap && g_bBumpmapDiffuseLighting ) + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; + } + else + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; + } + +#if ( RELIEF_MAPPING == 0) + if( g_UseSeparateEnvmapMask || g_BumpMask ) + { + // reversed component order +# if FASTPATH + o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; +# else + o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w; +# endif + } +#endif + + o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) && !defined(SHADER_MODEL_VS_3_0) + o.fog = o.vertexBlendX_fogFactorW; +#endif + + if (!g_bVertexColor) + { + o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a ); + } + else + { +#if FASTPATH + o.vertexColor = v.vColor; +#else + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexColor.rgb = v.vColor.rgb; + o.vertexColor.a = cModulationColor.a; + } + else + { + o.vertexColor = v.vColor; + o.vertexColor.a *= cModulationColor.a; + } +#endif + } +#if SEAMLESS + // compute belnd weights in rgb + float3 vNormal=normalize( worldNormal ); + o.vertexColor.xyz = vNormal * vNormal; // sums to 1. +#endif + +// On 360, we have extra iterators and can fold the flashlight into this shader +#if defined( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.vProjPos = vProjPos; +#endif + + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexBlendX_fogFactorW.r = v.vColor.a; + } + + return o; +} diff --git a/materialsystem/stdshaders/SDK_screenspaceeffect_vs20.fxc b/materialsystem/stdshaders/SDK_screenspaceeffect_vs20.fxc deleted file mode 100644 index 96cb8990..00000000 --- a/materialsystem/stdshaders/SDK_screenspaceeffect_vs20.fxc +++ /dev/null @@ -1,47 +0,0 @@ -//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============// - -// STATIC: "X360APPCHOOSER" "0..1" [= 0] - -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float3 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; - - #if X360APPCHOOSER - float4 vColor : COLOR0; - #endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 baseTexCoord : TEXCOORD0; - float2 ZeroTexCoord : TEXCOORD1; - float2 bloomTexCoord : TEXCOORD2; - - #if X360APPCHOOSER - float4 vColor : TEXCOORD3; - #endif -}; - -float4 Texel_Sizes : register (SHADER_SPECIFIC_CONST_0); - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.projPos = float4( v.vPos, 1.0f ); - o.baseTexCoord = v.vBaseTexCoord; - o.ZeroTexCoord=float2(0,0); - o.bloomTexCoord.x=v.vBaseTexCoord.x+Texel_Sizes.z; - o.bloomTexCoord.y=v.vBaseTexCoord.y+Texel_Sizes.w; - - #if X360APPCHOOSER - o.vColor.rgba = v.vColor.rgba; - o.projPos.xyzw = mul( float4( v.vPos.xyz, 1.0f ), cModelViewProj ); - #endif - - return o; -} diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps20b.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps20b.fxc new file mode 100644 index 00000000..90141399 --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps20b.fxc @@ -0,0 +1,381 @@ +//======= Copyright 1996-2008, Valve Corporation, All rights reserved. ====== + +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "ENVMAPMASK" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] + +// We don't use light combos when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// Don't do diffuse warp on flashlight +// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] + +// Only warp diffuse if we have it at all +// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Skip this since it blows ps20 instruction limits +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// Meaningless combinations +// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP +// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $ENVMAPMASK && !$CUBEMAP + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); +#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) + +const float3 cAmbientCube[6] : register( c5 ); + +// 11, 12 not used? +#if ( SELFILLUMFRESNEL == 1 ) + const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); +#endif + +const float4 g_ShaderControls : register( c12 ); +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z + + +// 2 registers each - 6 registers total +PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 + +const float4 g_EyePos_MinLight : register( c20 ); +#define g_EyePos g_EyePos_MinLight.xyz +#define g_fMinLighting g_EyePos_MinLight.w + +const float4 g_FogParams : register( c21 ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const float3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler BumpmapSampler : register( s3 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler NormalizeSampler : register( s5 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) + +struct PS_INPUT +{ + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +#endif +}; + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + +float4 main( PS_INPUT i ) : COLOR +{ + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + int nNumLights = NUM_LIGHTS; + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; +#else + float3 vWorldBinormal = i.vWorldBinormal; +#endif + + // Unpack four light attenuations + float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); + + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if ENVMAPMASK + // Blixibon - $bumpmap + $envmapmask + float3 specularFactor = 1.0f; +#else + float specularFactor = 1.0f; +#endif + +#if !DETAILTEXTURE + // Blixibon - $bumpmap transform support + float4 normalTexel = tex2D( BumpmapSampler, i.detailTexCoord_atten3.xy ); +#else + float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); +#endif + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + + if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor = normalTexel.a; + } + else if( bEnvmapMask ) + { + float4 envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + + float3 worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal.xyz, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); + if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) + { +#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + worldSpaceNormal = normalize( worldSpaceNormal ); +#else + worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); +#endif + } + + if ( bDiffuseLighting ) + { + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + +#if FLASHLIGHT + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + float2 vProjPos = float2(0, 0); +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = FLASHLIGHTSHADOWS; + vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + + } +#endif + + +#if FOGTYPE == 2 || FLASHLIGHT != 0 + float3 diffuseComponent = albedo * diffuseLighting; +#else + float3 vEyeDir = normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); + float flFresnelMinlight = saturate( dot( worldSpaceNormal, vEyeDir ) ); + + float3 diffuseComponent = albedo * lerp( diffuseLighting, 1, g_fMinLighting * flFresnelMinlight ); +#endif + + +#if !FLASHLIGHT || defined ( _X360 ) + if ( bSelfIllum ) + { + #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #else + float3 vVertexNormal = i.vWorldNormal.xyz; + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #endif + #else + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + #endif + } +#endif + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); +#if !FLASHLIGHT || defined ( _X360 ) + if( bCubemap ) + { + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if defined(SHADER_MODEL_PS_2_0) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); +#else + float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; + #endif +#else // 2b or higher + alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); +#else + return FinalOutput( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); +#endif + +} + diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc new file mode 100644 index 00000000..332b2572 --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc @@ -0,0 +1,372 @@ +//======= Copyright 1996-2008, Valve Corporation, All rights reserved. ====== + +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "ENVMAPMASK" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] + +// We don't use light combos when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// Don't do diffuse warp on flashlight +// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] + +// Only warp diffuse if we have it at all +// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Skip this since it blows ps20 instruction limits +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// Meaningless combinations +// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP +// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $ENVMAPMASK && !$CUBEMAP + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); +#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) + +const float3 cAmbientCube[6] : register( c5 ); + +// 11, 12 not used? +#if ( SELFILLUMFRESNEL == 1 ) + const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); +#endif + +const float4 g_ShaderControls : register( c12 ); +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z + + +// 2 registers each - 6 registers total +PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 + +const float3 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const float3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler BumpmapSampler : register( s3 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler NormalizeSampler : register( s5 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) + +struct PS_INPUT +{ + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +#endif +}; + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, fogParams.z, fogParams.x, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + +float4 main( PS_INPUT i ) : COLOR +{ + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + int nNumLights = NUM_LIGHTS; + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; +#else + float3 vWorldBinormal = i.vWorldBinormal; +#endif + + // Unpack four light attenuations + float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); + + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if ENVMAPMASK + // Blixibon - $bumpmap + $envmapmask + float3 specularFactor = 1.0f; +#else + float specularFactor = 1.0f; +#endif + +#if !DETAILTEXTURE + // Blixibon - $bumpmap transform support + float4 normalTexel = tex2D( BumpmapSampler, i.detailTexCoord_atten3.xy ); +#else + float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); +#endif + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + + if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor = normalTexel.a; + } + else if( bEnvmapMask ) + { + float4 envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + + float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); + if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) + { + worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); +#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + worldSpaceNormal = normalize( worldSpaceNormal ); +#else + worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); +#endif + } + + if ( bDiffuseLighting ) + { + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + +#if FLASHLIGHT + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + float2 vProjPos = float2(0, 0); +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = FLASHLIGHTSHADOWS; + vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + + } +#endif + + + float3 diffuseComponent = albedo * diffuseLighting; + + +#if !FLASHLIGHT || defined ( _X360 ) + if ( bSelfIllum ) + { + #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #else + float3 vVertexNormal = i.vWorldNormal.xyz; + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #endif + #else + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + #endif + } +#endif + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); +#if !FLASHLIGHT || defined ( _X360 ) + if( bCubemap ) + { + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if defined(SHADER_MODEL_PS_2_0) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); +#else + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; + #endif +#else // 2b or higher + alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); +#else + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); +#endif + +} + diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_vs20.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_vs20.fxc new file mode 100644 index 00000000..6095be07 --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_vs20.fxc @@ -0,0 +1,199 @@ +//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====== +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_WITH_2B" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "FLASHLIGHT" "0..1" [XBOX] +// STATIC: "SM30_VERTEXID" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); // 4 & 5 +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 + +#if defined( SHADER_MODEL_VS_3_0 ) && SM30_VERTEXID +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#if defined( SHADER_MODEL_VS_3_0 ) && SM30_VERTEXID + float vVertexID : POSITION2; +#endif +}; + + +//----------------------------------------------------------------------------- +// Output vertex format +//----------------------------------------------------------------------------- +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + // Stuff that is seen by the pixel shader + + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if USE_WITH_2B + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +}; + + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING || !SM30_VERTEXID + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL && SM30_VERTEXID + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.vWorldNormal.xyz = worldNormal.xyz; + o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + +#if USE_WITH_2B + o.vProjPos = vProjPos; +#else + o.vWorldBinormal.xyz = worldTangentT.xyz; +#endif + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + // Needed for cubemapping + parallax mapping + // FIXME: We shouldn't have to compute this all the time. + //o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = normalize( cEyePos.xyz - worldPos.xyz ); + +#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten.xyz = float3(0,0,0); + o.detailTexCoord_atten3.z = 0.0f; + #if ( NUM_LIGHTS > 0 ) + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + // Scalar light attenuation + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + // Base texture coordinate transform + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + // Detail texture coordinate transform + o.detailTexCoord_atten3.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord_atten3.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + +#if defined( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps20b.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps20b.fxc new file mode 100644 index 00000000..695faa2b --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps20b.fxc @@ -0,0 +1,523 @@ +//====== Copyright 1996-2007, Valve Corporation, All rights reserved. =======// +// +//=============================================================================// + + +//#define NEW_SHADOW_FILTERS + +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..9" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "DISTANCEALPHA" "0..1" +// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" +// STATIC: "SOFT_MASK" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "OUTER_GLOW" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "ENVMAPFRESNEL" "0..1" [ps30] +// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// detail blend mode 6 = ps20b only +// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] + +// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] +// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) + +// envmap stuff is meaningless if we're not using a cubemap +// SKIP: ( $CUBEMAP == 0 ) && ( ( $ENVMAPFRESNEL == 1 ) || ( $BASEALPHAENVMAPMASK == 1 ) ) +// SKIP: ( $CUBEMAP == 0 ) && ( $ENVMAPMASK == 1 ) && ( $SELFILLUM_ENVMAPMASK_ALPHA == 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// DISTANCEALPHA-related skips +// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA || $ENVMAPFRESNEL) +// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) + +// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); + +const float4 g_ShaderControls : register( c12 ); +const float4 g_DepthFeatheringConstants : register( c13 ); + +const float4 g_FresnelConstants : register( c14 ); +#define g_flFresnelBias g_FresnelConstants.x +#define g_flFresnelScale g_FresnelConstants.y +#define g_flFresnelExp g_FresnelConstants.z +#define g_flBaseAlphaEnvMapMaskExp g_FresnelConstants.w + +const float4 g_EyePos_MinLight : register( c20 ); +#define g_EyePos g_EyePos_MinLight.xyz +#define g_fMinLighting g_EyePos_MinLight.w + +const float4 g_FogParams : register( c21 ); + +#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz +#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w +#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz +#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending +sampler SelfIllumMaskSampler : register( s11 ); // selfillummask + +struct PS_INPUT +{ +#if SEAMLESS_BASE + HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif +#endif + + float4 projPos : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_BASE || SEAMLESS_DETAIL + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif +}; + +const float4 g_GlowParameters : register( c5 ); +const float4 g_GlowColor : register( c6 ); +#define GLOW_UV_OFFSET g_GlowParameters.xy +#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z +#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w +#define OUTER_GLOW_COLOR g_GlowColor + +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z +#define g_fVertexAlpha g_ShaderControls.w + + +const float4 g_DistanceAlphaParams : register( c7 ); +#define SOFT_MASK_MAX g_DistanceAlphaParams.x +#define SOFT_MASK_MIN g_DistanceAlphaParams.y +#define g_flBaseAlphaEnvMapMaskBias g_DistanceAlphaParams.z +#define g_flBaseAlphaEnvMapMaskScale g_DistanceAlphaParams.w + +const float4 g_OutlineColor : register( c8 ); +#define OUTLINE_COLOR g_OutlineColor + +const float4 g_OutlineParams : register( c9 ); +// these are ordered this way for optimal ps20 swizzling +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MAX_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MIN_VALUE1 g_OutlineParams.w + +#if DETAILTEXTURE +const float3 g_DetailTint : register( c10 ); +#endif + + +// Calculate unified fog +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive + float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive + // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 + float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); + return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + //return lerp( fRangeResult, fHeightResult, fPixelFogType ); + pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); +} + + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +float4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHasNormal = bCubemap || bDiffuseLighting; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if SEAMLESS_BASE + baseColor = + i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); +#else + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + +#if SRGB_INPUT_ADAPTER + baseColor.rgb = GammaToLinear( baseColor.rgb ); +#endif + +#endif // !SEAMLESS_BASE + + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) + float distAlphaMask = baseColor.a; +#endif + + +#if DETAILTEXTURE +#if SEAMLESS_DETAIL + float4 detailColor = + i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); +#else + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); +#endif + detailColor.rgb *= g_DetailTint; + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) + float distAlphaMask = detailColor.a; + detailColor.a = 1.0; // make tcombine treat as 1.0 +#endif + baseColor = + TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if DISTANCEALPHA + // now, do all distance alpha effects + //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + //{ + // float oFactor=1.0; + // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + // { + // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + // } + // else + // { + // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + // } + // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + //} + if ( OUTLINE ) + { + float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); + baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); + } + + float mskUsed; + if ( SOFT_MASK ) + { + mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); + baseColor.a *= mskUsed; + } + else + { + mskUsed = distAlphaMask >= 0.5; + if (DETAILTEXTURE ) + baseColor.a *= mskUsed; + else + baseColor.a = mskUsed; + } + + + if ( OUTER_GLOW ) + { +#if DISTANCEALPHAFROMDETAIL + float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); +#else + float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); +#endif + float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); + baseColor = lerp( glowc, baseColor, mskUsed ); + } + +#endif // DISTANCEALPHA + + float3 specularFactor = 1.0f; + float4 envmapMaskTexel; + if( bEnvmapMask ) + { +#if !DETAILTEXTURE + // Blixibon - $envmapmask transform support + envmapMaskTexel = tex2D( EnvmapMaskSampler, i.detailTexCoord.xy ); +#else + envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); +#endif + specularFactor *= envmapMaskTexel.xyz; + } + + if ( bBaseAlphaEnvmapMask ) + { + specularFactor *= saturate( g_flBaseAlphaEnvMapMaskScale * pow( baseColor.a, g_flBaseAlphaEnvMapMaskExp ) + g_flBaseAlphaEnvMapMaskBias ); + } + + #if ( ENVMAPFRESNEL ) + { + float flFresnel = 1-saturate( dot( normalize( i.worldSpaceNormal.xyz ), normalize( i.worldVertToEyeVector.xyz ) ) ); + flFresnel = g_flFresnelScale * pow( flFresnel, g_flFresnelExp ) + g_flFresnelBias; + specularFactor *= flFresnel; + } + #endif + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting || bVertexColor && !( bVertexColor && bDiffuseLighting ) ) + { + diffuseLighting = i.color.rgb; + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 + bool bUseWorldNormal = true; +#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) + bUseWorldNormal = false; +#endif + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + } + + if( bVertexColor && bDiffuseLighting ) + { + albedo *= i.color.rgb; + } + + alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); + +#if FOGTYPE == 2 || FLASHLIGHT != 0 + float3 diffuseComponent = albedo * diffuseLighting; +#else + float3 vEyeDir = normalize( i.worldVertToEyeVector.xyz ); + float flFresnelMinlight = saturate( dot( i.worldSpaceNormal, vEyeDir ) ); + + float3 diffuseComponent = albedo * lerp( diffuseLighting, 1, g_fMinLighting * flFresnelMinlight ); +#endif + +#if DETAILTEXTURE + diffuseComponent = + TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + +#if !FLASHLIGHT || defined ( _X360 ) + #if SELFILLUM_ENVMAPMASK_ALPHA + // range of alpha: + // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) + // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + half Adj_Alpha=8*envmapMaskTexel.a; + diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; + #else + if ( bSelfIllum ) + { + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); + } + #endif + + if( bCubemap ) + { +#if CUBEMAP_SPHERE_LEGACY + HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); + + specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; +#else + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW +# if LIGHTING_PREVIEW == 1 + float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); + return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +# else + LPREVIEW_PS_OUT ret; + ret.flags=float4(1,1,1,1); + ret.color=float4( albedo.xyz, alpha ); + ret.normal=float4(i.worldSpaceNormal,alpha); + ret.position=float4(i.worldPos_projPosZ.xyz, alpha); + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else + +# if (DEPTHBLEND == 1) + { + float2 vScreenPos; + vScreenPos.x = i.projPos.x; + vScreenPos.y = -i.projPos.y; + vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; + alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); + } +# endif + +#if defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); + #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); + #endif + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); +#else // 2b or higher + float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog + return FinalOutput( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); +#endif + +#endif +} + diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc new file mode 100644 index 00000000..56685c11 --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc @@ -0,0 +1,509 @@ +//====== Copyright 1996-2007, Valve Corporation, All rights reserved. =======// +// +//=============================================================================// +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..9" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "DISTANCEALPHA" "0..1" +// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" +// STATIC: "SOFT_MASK" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "OUTER_GLOW" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "ENVMAPFRESNEL" "0..1" [ps30] +// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// detail blend mode 6 = ps20b only +// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] + +// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] +// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) + +// envmap stuff is meaningless if we're not using a cubemap +// SKIP: ( $CUBEMAP == 0 ) && ( ( $ENVMAPFRESNEL == 1 ) || ( $BASEALPHAENVMAPMASK == 1 ) ) +// SKIP: ( $CUBEMAP == 0 ) && ( $ENVMAPMASK == 1 ) && ( $SELFILLUM_ENVMAPMASK_ALPHA == 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// DISTANCEALPHA-related skips +// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA || $ENVMAPFRESNEL) +// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) + +// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); + +const float4 g_ShaderControls : register( c12 ); +const float4 g_DepthFeatheringConstants : register( c13 ); + +const float4 g_FresnelConstants : register( c14 ); +#define g_flFresnelBias g_FresnelConstants.x +#define g_flFresnelScale g_FresnelConstants.y +#define g_flFresnelExp g_FresnelConstants.z +#define g_flBaseAlphaEnvMapMaskExp g_FresnelConstants.w + +const float4 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz +#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w +#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz +#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending +sampler SelfIllumMaskSampler : register( s11 ); // selfillummask + +struct PS_INPUT +{ +#if SEAMLESS_BASE + HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif +#endif + + float4 projPos : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_BASE || SEAMLESS_DETAIL + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif +}; + +const float4 g_GlowParameters : register( c5 ); +const float4 g_GlowColor : register( c6 ); +#define GLOW_UV_OFFSET g_GlowParameters.xy +#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z +#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w +#define OUTER_GLOW_COLOR g_GlowColor + +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z +#define g_fVertexAlpha g_ShaderControls.w + + +const float4 g_DistanceAlphaParams : register( c7 ); +#define SOFT_MASK_MAX g_DistanceAlphaParams.x +#define SOFT_MASK_MIN g_DistanceAlphaParams.y +#define g_flBaseAlphaEnvMapMaskBias g_DistanceAlphaParams.z +#define g_flBaseAlphaEnvMapMaskScale g_DistanceAlphaParams.w + +const float4 g_OutlineColor : register( c8 ); +#define OUTLINE_COLOR g_OutlineColor + +const float4 g_OutlineParams : register( c9 ); +// these are ordered this way for optimal ps20 swizzling +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MAX_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MIN_VALUE1 g_OutlineParams.w + +#if DETAILTEXTURE +const float3 g_DetailTint : register( c10 ); +#endif + + +// Calculate unified fog +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) +{ + /*float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive + float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive + // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 + float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); + return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) );*/ + + float fRangeFog = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, fogParams.z, fogParams.x, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + //return lerp( fRangeResult, fHeightResult, fPixelFogType ); + pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); +} + + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +float4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHasNormal = bCubemap || bDiffuseLighting; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if SEAMLESS_BASE + baseColor = + i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); +#else + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + +#if SRGB_INPUT_ADAPTER + baseColor.rgb = GammaToLinear( baseColor.rgb ); +#endif + +#endif // !SEAMLESS_BASE + + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) + float distAlphaMask = baseColor.a; +#endif + + +#if DETAILTEXTURE +#if SEAMLESS_DETAIL + float4 detailColor = + i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); +#else + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); +#endif + detailColor.rgb *= g_DetailTint; + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) + float distAlphaMask = detailColor.a; + detailColor.a = 1.0; // make tcombine treat as 1.0 +#endif + baseColor = + TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if DISTANCEALPHA + // now, do all distance alpha effects + //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + //{ + // float oFactor=1.0; + // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + // { + // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + // } + // else + // { + // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + // } + // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + //} + if ( OUTLINE ) + { + float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); + baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); + } + + float mskUsed; + if ( SOFT_MASK ) + { + mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); + baseColor.a *= mskUsed; + } + else + { + mskUsed = distAlphaMask >= 0.5; + if (DETAILTEXTURE ) + baseColor.a *= mskUsed; + else + baseColor.a = mskUsed; + } + + + if ( OUTER_GLOW ) + { +#if DISTANCEALPHAFROMDETAIL + float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); +#else + float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); +#endif + float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); + baseColor = lerp( glowc, baseColor, mskUsed ); + } + +#endif // DISTANCEALPHA + + float3 specularFactor = 1.0f; + float4 envmapMaskTexel; + #if ( ENVMAPMASK ) + { + envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + #endif + + if ( bBaseAlphaEnvmapMask ) + { + specularFactor *= saturate( g_flBaseAlphaEnvMapMaskScale * pow( baseColor.a, g_flBaseAlphaEnvMapMaskExp ) + g_flBaseAlphaEnvMapMaskBias ); + } + + #if ( ENVMAPFRESNEL ) + { + float flFresnel = 1-saturate( dot( normalize( i.worldSpaceNormal.xyz ), normalize( i.worldVertToEyeVector.xyz ) ) ); + flFresnel = g_flFresnelScale * pow( flFresnel, g_flFresnelExp ) + g_flFresnelBias; + specularFactor *= flFresnel; + } + #endif + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting || bVertexColor && !( bVertexColor && bDiffuseLighting ) ) + { + diffuseLighting = i.color.rgb; + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 + bool bUseWorldNormal = true; +#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) + bUseWorldNormal = false; +#endif + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + } + + if( bVertexColor && bDiffuseLighting ) + { + albedo *= i.color.rgb; + } + + alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); + + float3 diffuseComponent = albedo * diffuseLighting; + +#if DETAILTEXTURE + diffuseComponent = + TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + +#if !FLASHLIGHT || defined ( _X360 ) + #if SELFILLUM_ENVMAPMASK_ALPHA + // range of alpha: + // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) + // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + half Adj_Alpha=8*envmapMaskTexel.a; + diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; + #else + if ( bSelfIllum ) + { + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); + } + #endif + + if( bCubemap ) + { +#if CUBEMAP_SPHERE_LEGACY + HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); + + specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; +#else + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW +# if LIGHTING_PREVIEW == 1 + float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); + return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +# else + LPREVIEW_PS_OUT ret; + ret.flags=float4(1,1,1,1); + ret.color=float4( albedo.xyz, alpha ); + ret.normal=float4(i.worldSpaceNormal,alpha); + ret.position=float4(i.worldPos_projPosZ.xyz, alpha); + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else + +# if (DEPTHBLEND == 1) + { + float2 vScreenPos; + vScreenPos.x = i.projPos.x; + vScreenPos.y = -i.projPos.y; + vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; + alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); + } +# endif + +#if defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); + #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); + #endif + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); +#else // 2b or higher + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); +#endif + +#endif +} + diff --git a/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_vs20.fxc b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_vs20.fxc new file mode 100644 index 00000000..32550ccb --- /dev/null +++ b/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_vs20.fxc @@ -0,0 +1,292 @@ +//======= Copyright 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "SEPARATE_DETAIL_UVS" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "SM30_VERTEXID" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] +// STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" +// STATIC: "TREESWAY" "0..2" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] +// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) +// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) +// SKIP: ( $TREESWAY ) && ( $SEAMLESS_DETAIL || $SEAMLESS_BASE ) +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; +static const bool g_bCubemap = CUBEMAP ? true : false; +static const bool g_bFlashlight = FLASHLIGHT ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +#if (defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL && SM30_VERTEXID) +static const bool g_bDecalOffset = true; +#else +static const bool g_bDecalOffset = false; +#endif + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +#if SEAMLESS_DETAIL || SEAMLESS_BASE +const float cSeamlessScale : register( SHADER_SPECIFIC_CONST_2); +#define SEAMLESS_SCALE cSeamlessScale.x +#endif + +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#if defined ( _X360 ) +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 +#endif + +#if ( TREESWAY ) +const float4 g_vMiscParams1 : register( SHADER_SPECIFIC_CONST_6 ); +const float4 g_vMiscParams2 : register( SHADER_SPECIFIC_CONST_7 ); +const float4 g_vMiscParams3 : register( SHADER_SPECIFIC_CONST_8 ); +const float4 g_vMiscParams4 : register( SHADER_SPECIFIC_CONST_9 ); +#define g_flTime g_vMiscParams2.y +#define g_vWindDir g_vMiscParams2.zw + +#define g_flFastSwaySpeedScale g_vMiscParams1.x +#define g_flScrumbleFalloffCurve g_vMiscParams1.y +#define g_flSwayFalloffCurve g_vMiscParams1.z +#define g_flScrumbleSpeed g_vMiscParams1.w + +#define g_flHeight g_vMiscParams3.x +#define g_flStartHeight g_vMiscParams3.y +#define g_flRadius g_vMiscParams3.z +#define g_flStartRadius g_vMiscParams3.w + +#define g_flSwaySpeed g_vMiscParams4.x +#define g_flSwayIntensity g_vMiscParams4.y +#define g_flScrumbleWaveCount g_vMiscParams4.z +#define g_flScrumbleIntensity g_vMiscParams4.w + +#define g_flWindSpeedLerpStart cDetailTexCoordTransform[0].x +#define g_flWindSpeedLerpEnd cDetailTexCoordTransform[0].y +#include "tree_sway.h" +#endif + +#if defined( SHADER_MODEL_VS_3_0 ) && SM30_VERTEXID +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#if defined( SHADER_MODEL_VS_3_0 ) && SM30_VERTEXID + float vVertexID : POSITION2; +#endif +}; + + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; +#endif + +#if SEAMLESS_BASE + HALF3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + +#if 1 //CUBEMAP || _X360 + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps +#endif + + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif + + float4 vProjPos : TEXCOORD6; + float4 worldPos_ProjPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_DETAIL || SEAMLESS_BASE + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); + + float4 vPosition = v.vPos; + float3 vNormal = 0; + if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) + { + // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) + DecompressVertex_Normal( v.vNormal, vNormal ); + } + +#if SEAMLESS_BASE || SEAMLESS_DETAIL + // compute blend weights in rgb + float3 NNormal=normalize( vNormal ); + o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. +#endif + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING || !SM30_VERTEXID + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); +#endif + +#if ( TREESWAY ) + vPosition.xyz = ComputeTreeSway( vPosition.xyz, g_flTime ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + if ( !g_bVertexColor ) + { + worldNormal = normalize( worldNormal ); + } + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL && SM30_VERTEXID + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.worldSpaceNormal = worldNormal; + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.vProjPos = vProjPos; + o.fogFactorW.w = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + o.worldPos_ProjPosZ.xyz = worldPos.xyz; + o.worldPos_ProjPosZ.w = vProjPos.z; + + // Needed for cubemaps +#if 1 //CUBEMAP + o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); +#endif + +#if !defined (_X360) && FLASHLIGHT + o.color = float4( 0.0f, 0.0f, 0.0f, 0.0f ); +#else + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. + o.color.rgb = ( DONT_GAMMA_CONVERT_VERTEX_COLOR ) ? v.vColor.rgb : GammaToLinear( v.vColor.rgb ); + o.color.a = v.vColor.a; + } + else + { + #if ( ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) ) + { + o.color.xyz = DoLighting( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert ); + } + #else + { + o.color.xyz = DoLightingUnrolled( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); + } + #endif + } +#endif + + +#if SEAMLESS_BASE + o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; +#else + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); +#endif + +#if SEAMLESS_DETAIL + // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so + // that scale works. More smartness could allow 3d xform. + o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*cDetailTexCoordTransform[0].x) * v.vPos.xyz; +#else + #if ( TREESWAY ) + { + o.detailTexCoord.xy = v.vTexCoord0; + } + #else + { + // Detail texture coordinates + // FIXME: This shouldn't have to be computed all the time. + o.detailTexCoord.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + } + #endif +#endif + +#if SEPARATE_DETAIL_UVS + o.detailTexCoord.xy = v.vTexCoord1.xy; +#endif + +#if LIGHTING_PREVIEW + float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); + o.color.xyz=float3(dot,dot,dot); +#endif + +#if defined ( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} + + diff --git a/materialsystem/stdshaders/ShadowModel.psh b/materialsystem/stdshaders/ShadowModel.psh deleted file mode 100644 index 31b6d780..00000000 --- a/materialsystem/stdshaders/ShadowModel.psh +++ /dev/null @@ -1,22 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -def c0,1.0f, 1.0f, 1.0f, 1.0f - -tex t0 ; shadow color -texkill t1 ; Clip -texkill t2 -texkill t3 ; backface cull - -; Darkening equation, compute a color = (shadow color * shadow alpha + 1- shadow alpha) -;sub r1, t0, v0.a ; r1 = shadow alpha -lrp r0.rgb, t0.a, v0, c0 + ; r0.rgb = (shadow color * shadow alpha + 1 - shadow alpha) -mov r0.a, c0.a ; r0.a = 1 - diff --git a/materialsystem/stdshaders/ShadowModel.vsh b/materialsystem/stdshaders/ShadowModel.vsh deleted file mode 100644 index 3e4b9eba..00000000 --- a/materialsystem/stdshaders/ShadowModel.vsh +++ /dev/null @@ -1,85 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -;------------------------------------------------------------------------------ -; Constants specified by the app -; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_2 = Shadow texture matrix -; $SHADER_SPECIFIC_CONST_3 = Tex origin -; $SHADER_SPECIFIC_CONST_4 = Tex Scale -; $SHADER_SPECIFIC_CONST_5 = [Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 ] -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending (whacks r1-r7, positions in r7, normals in r8) -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -&AllocateRegister( \$worldNormal ); -&SkinPositionAndNormal( $worldPos, $worldNormal ); - -; Transform the position from world to view space -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Transform position into texture space (from 0 to 1) -;------------------------------------------------------------------------------ -&AllocateRegister( \$texturePos ); -dp4 $texturePos.x, $worldPos, $SHADER_SPECIFIC_CONST_0 -dp4 $texturePos.y, $worldPos, $SHADER_SPECIFIC_CONST_1 -dp4 $texturePos.z, $worldPos, $SHADER_SPECIFIC_CONST_2 -&FreeRegister( \$worldPos ); - -;------------------------------------------------------------------------------ -; Figure out the shadow fade amount -;------------------------------------------------------------------------------ -&AllocateRegister( \$shadowFade ); -sub $shadowFade, $texturePos.z, $SHADER_SPECIFIC_CONST_5.x -mul $shadowFade, $shadowFade, $SHADER_SPECIFIC_CONST_5.y - -;------------------------------------------------------------------------------ -; Offset it into the texture -;------------------------------------------------------------------------------ -&AllocateRegister( \$actualTextureCoord ); -mul $actualTextureCoord.xyz, $SHADER_SPECIFIC_CONST_4, $texturePos -add oT0.xyz, $actualTextureCoord, $SHADER_SPECIFIC_CONST_3 -;mov oT0.xyz, $texturePos -&FreeRegister( \$actualTextureCoord ); - -;------------------------------------------------------------------------------ -; We're doing clipping by using texkill -;------------------------------------------------------------------------------ -mov oT1.xyz, $texturePos ; also clips when shadow z < 0 ! -sub oT2.xyz, $cOne, $texturePos -sub oT2.z, $cOne, $shadowFade.z ; clips when shadow z > shadow distance -&FreeRegister( \$texturePos ); - -;------------------------------------------------------------------------------ -; We're doing backface culling by using texkill also (wow yucky) -;------------------------------------------------------------------------------ -; Transform z component of normal in texture space -; If it's negative, then don't draw the pixel -dp3 oT3, $worldNormal, -$SHADER_SPECIFIC_CONST_2 -&FreeRegister( \$worldNormal ); - -;------------------------------------------------------------------------------ -; Shadow color, falloff -;------------------------------------------------------------------------------ -mov oD0, $cModulationColor -mul oD0.w, $shadowFade.x, $SHADER_SPECIFIC_CONST_5.z -&FreeRegister( \$shadowFade ); - diff --git a/materialsystem/stdshaders/Teeth.vsh b/materialsystem/stdshaders/Teeth.vsh deleted file mode 100644 index 065f0703..00000000 --- a/materialsystem/stdshaders/Teeth.vsh +++ /dev/null @@ -1,97 +0,0 @@ -vs.1.1 - -# STATIC: "INTRO" "0..1" -# STATIC: "HALF_LAMBERT" "0..1" -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "LIGHT_COMBO" "0..21" -# DYNAMIC: "SKINNING" "0..1" - -;------------------------------------------------------------------------------ -; $SHADER_SPECIFIC_CONST_0 = xyz = mouth forward direction vector, w = illum factor -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -$WARPPARAM = $SHADER_SPECIFIC_CONST_2; -$ENTITY_ORIGIN = $SHADER_SPECIFIC_CONST_3; - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ -alloc $worldPos -alloc $worldNormal -&SkinPositionAndNormal( $worldPos, $worldNormal ); - -;------------------------------------------------------------------------------ -; Optional intro warping -;------------------------------------------------------------------------------ -if ( $INTRO == 1 ) -{ - alloc $tmp - sub $tmp.xyz, $worldPos, $ENTITY_ORIGIN - mul $tmp.xy, $tmp, $WARPPARAM - add $worldPos.xyz, $tmp, $ENTITY_ORIGIN - free $tmp -} - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -alloc $projPos - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -&CalcFog( $worldPos, $projPos ); - -free $projPos - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ -alloc $linearColor -&DoDynamicLightingToLinear( $worldPos, $worldNormal, $linearColor ); - -;------------------------------------------------------------------------------ -; Factor in teeth darkening factors -;------------------------------------------------------------------------------ - -alloc $tmp - -mul $linearColor.xyz, $SHADER_SPECIFIC_CONST_0.w, $linearColor ; FIXME Color darkened by illumination factor -dp3 $tmp, $worldNormal, $SHADER_SPECIFIC_CONST_0 ; Figure out mouth forward dot normal -max $tmp, $cZero, $tmp ; clamp from 0 to 1 -mul $linearColor.xyz, $tmp, $linearColor ; Darken by forward dot normal too - -;------------------------------------------------------------------------------ -; Output color (gamma correction) -;------------------------------------------------------------------------------ - -alloc $gammaColor -&LinearToGamma( $linearColor, $gammaColor ); -free $linearColor -mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor -mov oD0.w, $cOne ; make sure all components are defined - - -free $gammaColor -free $worldPos -free $worldNormal -free $tmp - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -mov oT0, $vTexCoord0 - - - diff --git a/materialsystem/stdshaders/UnlitGeneric.psh b/materialsystem/stdshaders/UnlitGeneric.psh deleted file mode 100644 index 409ee0d6..00000000 --- a/materialsystem/stdshaders/UnlitGeneric.psh +++ /dev/null @@ -1,13 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color - -mul r0, t0, v0 \ No newline at end of file diff --git a/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh b/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh deleted file mode 100644 index 32ec9c6e..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers -mul r0.rgb, c2, r0 ; apply the envmaptint -mad r0.rgb, t0, v0, r0 -+ mul r0.a, t0, v0 diff --git a/materialsystem/stdshaders/UnlitGeneric_Detail.psh b/materialsystem/stdshaders/UnlitGeneric_Detail.psh deleted file mode 100644 index 421d2d36..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_Detail.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t3 ; detail texture - -mul r0, t0, v0 -mul_x2 r0.rgb, r0, t3 \ No newline at end of file diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh b/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh deleted file mode 100644 index 7d234bb3..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh +++ /dev/null @@ -1,29 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -; version 1: applies the mod2x *after* environment map -;mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers -;mul r0.rgb, c2, r0 ; apply the envmaptint -;mad r0.rgb, t0, v0, r0 -;+ mul r0.a, t0, v0 -;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture - -; version 2: applies the mod2x *before* environment map -mul r0, t0, v0 ; Base times modulation color -mul_x2 r0.rgb, r0, t3 ; mod2x detail texture -mul r1, t1, 1-t2.a ; Have to invert the alpha for basealpha (feh!) -mul r1, c2, r1 ; apply the envmaptint -add r0.rgb, r0, r1 ; add in the envmap diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh b/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh deleted file mode 100644 index 6e8fde98..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh +++ /dev/null @@ -1,25 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t3 ; detail texture - -; version 1: applies the mod2x *after* environment map -;mul r1, c2, t1 -;mad r0.rgb, t0, v0, r1 -;+ mul r0.a, t0, v0 -;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture - -; version 2: applies the mod2x *before* environment map -mul r0, t0, v0 ; Base times modulation color -mul_x2 r0.rgb, r0, t3 ; mod2x detail texture -mad r0.rgb, c2, t1, r0 ; add in tinted envmap diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh b/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh deleted file mode 100644 index 93786add..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh +++ /dev/null @@ -1,29 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -; version 1: applies the mod2x *after* environment map -;mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers -;mul r0.rgb, c2, r0 ; apply the envmaptint -;mad r0.rgb, t0, v0, r0 -;+ mul r0.a, t0, v0 -;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture - -; version 2: applies the mod2x *before* environment map -mul r0, t0, v0 ; Base times modulation color -mul_x2 r0.rgb, r0, t3 ; mod2x detail texture -mul r1, t1, t2 ; Envmap * envmapmask -mul r1, c2, r1 ; apply the envmaptint -add r0.rgb, r0, r1 ; add in the envmap diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh deleted file mode 100644 index be678909..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -; version 1: applies the mod2x *after* environment map -; version 2 doesn't make sense here! -mul r0, t1, t2 -mul r0.rgb, c2, r0 -mul r0, r0, v0 -mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh deleted file mode 100644 index d3796bf9..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t1 ; cube map -tex t3 ; detail texture - -; version 1: applies the mod2x *after* environment map -; version 2 doesn't make sense here! -mul r0, v0, t1 -mul r0.rgb, r0, c2 -mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh deleted file mode 100644 index 193de81e..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh +++ /dev/null @@ -1,10 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Just use the vertex color -;------------------------------------------------------------------------------ - -tex t3 - -mul_x2 r0.rgb, v0, t3 -+ mov r0.a, v0.a \ No newline at end of file diff --git a/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh b/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh deleted file mode 100644 index 6c08ace4..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map - -mul r1, c2, t1 -mad r0.rgb, t0, v0, r1 -+ mul r0.a, t0, v0 diff --git a/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh b/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh deleted file mode 100644 index d00dca76..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers -mul r0.rgb, c2, r0 ; apply the envmaptint -mad r0.rgb, t0, v0, r0 -+ mul r0.a, t0, v0 diff --git a/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh deleted file mode 100644 index 87daff55..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0, t1, t2 -mul r0.rgb, c2, r0 -mul r0, r0, v0 diff --git a/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh deleted file mode 100644 index 4225a9e1..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c2 - envmaptint -;------------------------------------------------------------------------------ - -tex t1 ; cube map - -mul r0, v0, t1 -mul r0.rgb, r0, c2 diff --git a/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh b/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh deleted file mode 100644 index 6361c811..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh +++ /dev/null @@ -1,21 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -#include "macros.vsh" - -&AllocateRegister( \$worldPos ); -&SkinPosition( $worldPos ); - -; Transform the position from world to view space -dp4 oPos.x, $worldPos, $cViewProj0 -dp4 oPos.y, $worldPos, $cViewProj1 -dp4 oPos.z, $worldPos, $cViewProj2 -dp4 oPos.w, $worldPos, $cViewProj3 - -&FreeRegister( \$worldPos ); - -mov oD0, $cOne - - diff --git a/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc b/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc deleted file mode 100644 index f46a7617..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc +++ /dev/null @@ -1,20 +0,0 @@ -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float2 texCoord0 : TEXCOORD0; - float2 texCoord1 : TEXCOORD3; -}; - -sampler BaseTextureSampler : register( s0 ); -sampler DetailTextureSampler : register( s3 ); - -float4 main( PS_INPUT i ) : COLOR -{ - // Sample frames from texture 0 - float4 base= tex2D( BaseTextureSampler, i.texCoord0 ); - float4 detail=tex2D( DetailTextureSampler, i.texCoord1 ); - - return float4(base.rgb, base.a * detail.a); -} diff --git a/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh b/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh deleted file mode 100644 index 7e2274d9..00000000 --- a/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh +++ /dev/null @@ -1,7 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Just use the vertex color -;------------------------------------------------------------------------------ - -mov r0, v0 diff --git a/materialsystem/stdshaders/Vance_Tonemap_ps30.fxc b/materialsystem/stdshaders/Vance_Tonemap_ps30.fxc deleted file mode 100644 index f7a0417e..00000000 --- a/materialsystem/stdshaders/Vance_Tonemap_ps30.fxc +++ /dev/null @@ -1,82 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -// DYNAMIC: "MODE" "0..3" - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler FBSampler : register( s0 ); - -float m_flOverExposure : register(c0); -float m_flUnderExposure : register(c1); -float m_flExposure : register(c2); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - -float3 toHDR(float3 color) -{ - float3 underExposure = color / m_flUnderExposure; - float3 overExposure = color * m_flOverExposure; - - float3 hdrImage = lerp(underExposure, overExposure, color); - return hdrImage; -} - -float3 sRGBCorrect(float3 color) -{ - return pow(color, 1.0f / 2.2f); -} - -float3 getExposure(float3 color) -{ - float3 retColor = color * m_flExposure; - return retColor; -} - -float3 Burgess(float3 input) -{ - float3 x = max(0,input-0.004); - float3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06); - - return retColor; -} - -float3 Reinhard(float3 x) -{ - float3 retColor = x / (x + 1); - - return pow(retColor, 1/2.2f); -} - -float3 ACES(float3 x) -{ - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - float3 retColor = saturate((x*(a*x+b))/(x*(c*x+d)+e)); - return sRGBCorrect(retColor); -} - -float4 main( PS_INPUT i ) : COLOR -{ - float3 fbSample = tex2D( FBSampler, i.texCoord ).rgb; - - float3 retColor = getExposure(fbSample); - retColor = toHDR(retColor); -#if MODE == 1 - retColor = ACES(retColor); -#elif MODE == 2 - retColor = Reinhard(retColor); -#elif MODE == 3 - retColor = Burgess(retColor); -#else - retColor = sRGBCorrect(retColor); -#endif - return FinalOutput( float4( retColor, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/VertexLitGeneric.psh b/materialsystem/stdshaders/VertexLitGeneric.psh deleted file mode 100644 index 5aea47c4..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric.psh +++ /dev/null @@ -1,13 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 - -mul r0, t0, c3 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh deleted file mode 100644 index 95b80efc..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh +++ /dev/null @@ -1,17 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0, t0, c3 ; Base times modulation -mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif - diff --git a/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh b/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh deleted file mode 100644 index e74a5272..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh +++ /dev/null @@ -1,17 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 - -mul r0, c3, t0 -lrp r0.rgb, c1, c3, r0 -lrp r0.rgb, t0.a, r0, t0 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#else -+mov r0.a, c3 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_Detail.psh b/materialsystem/stdshaders/VertexLitGeneric_Detail.psh deleted file mode 100644 index cdb39b77..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_Detail.psh +++ /dev/null @@ -1,16 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t3 - -mul r0, t0, c3 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul_x2 r1.rgb, r0, t3 ; detail texture -lrp r0.rgb, c1, r1, r0 - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh deleted file mode 100644 index 3a329f20..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh +++ /dev/null @@ -1,18 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -mul r0, t0, c3 ; Base times modulation -mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul_x2 r0.rgb, r0, t3 ; detail texture -mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh deleted file mode 100644 index ce9ade83..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh +++ /dev/null @@ -1,16 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map -tex t3 ; detail texture - -mul r0, t0, c3 ; base times modulation -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul_x2 r0.rgb, r0, t3 ; detail texture -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh deleted file mode 100644 index 00945231..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh +++ /dev/null @@ -1,18 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -mul r0, t0, c3 ; Base times modulation -mul r1, t1, t2 ; Envmap * mask -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul_x2 r0.rgb, r0, t3 ; detail texture -mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh deleted file mode 100644 index f22d557f..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh +++ /dev/null @@ -1,12 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t3 - -mul r0, v0, c3 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mul_x2 r0.rgb, r0, t3 ; detail texture - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh deleted file mode 100644 index 898393ec..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh +++ /dev/null @@ -1,22 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t3 - -; interpolate between illuminated + non-selfilluminated -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul_x2 r0.rgb, r0, t3 ; detail texture - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -#if WRITEONETODESTALPHA -mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh deleted file mode 100644 index 42befc1f..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh +++ /dev/null @@ -1,24 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t1 -tex t3 - -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul_x2 r0.rgb, r0, t3 ; detail texture - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh deleted file mode 100644 index 666acb6d..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh +++ /dev/null @@ -1,26 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 ; base -tex t1 ; env map -tex t2 ; mask -tex t3 ; detail - -mul r0.rgb, t0, c3 + ; base times modulation -mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul_x2 r0.rgb, r0, t3 ; detail texture - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -mul r1, t2, t1 ; envmapmask * envmap -mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh b/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh deleted file mode 100644 index 8fcae481..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh +++ /dev/null @@ -1,15 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t3 - -lrp r0, c1, t3, t0 ; Lerp between textures -mul r0, r0, c3 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh b/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh deleted file mode 100644 index 586a5c07..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh +++ /dev/null @@ -1,15 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t3 - -mul r1, c1, t3 -mad r0, t0, c3, r1 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh b/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh deleted file mode 100644 index e40041fb..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh +++ /dev/null @@ -1,15 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t3 - -mul r0, c3, t0 -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mad r0.rgb, c1, t3, r0 - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh deleted file mode 100644 index 8e864ab4..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh +++ /dev/null @@ -1,14 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t1 ; cube map - -mul r0.rgb, t1, c2 + ; envmap * envmaptint (color only) + -mov r0.a, c3.a ; Use alpha from modulation... (?) - -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh deleted file mode 100644 index cfc6e67c..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh +++ /dev/null @@ -1,14 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map - -mul r0, t0, c3 ; base times modulation -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh deleted file mode 100644 index 7cbd38fc..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh +++ /dev/null @@ -1,36 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Environment mapping on a bumped surface -; t0 - Normalmap -; t3 - Cube environment map (*must* be a cube map!) -; -; c0 - color to multiply the results by -; Input texture coords required here are a little wonky. -; tc0.uv <- U,V into the normal map -; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform -; from tangent space->env map space -; tc1.q, tc2.q, tc3.q <- eye vector in env map space -;------------------------------------------------------------------------------ -; This version doesn't multiply by lighting. - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -; result goes in output color -mul r0.rgb, t3, c0 ; constant color -+mov r0.a, c0.a - -mul r1.rgb, r0, r0 -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -dp3 r1.rgb, r0, c3 -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale - - diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh deleted file mode 100644 index 9b72f0e4..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh +++ /dev/null @@ -1,42 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Environment mapping on a bumped surface -; t0 - Normalmap -; t3 - Cube environment map (*must* be a cube map!) -; -; c0 - color to multiply the results by -; Input texture coords required here are a little wonky. -; tc0.uv <- U,V into the normal map -; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform -; from tangent space->env map space -; tc1.q, tc2.q, tc3.q <- eye vector in env map space -;------------------------------------------------------------------------------ -; This version doesn't multiply by lighting. - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -; result goes in output color -mul r0.rgb, t3, c0 ; constant color -+mov r0.a, c0.a - -mul r1.rgb, r0, r0 -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -dp3 r1.rgb, r0, c3 -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale - -; Multiply the output color by the alpha channel of the normal map. -mul r0.rgb, t0.a, r0 - - - - - diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh deleted file mode 100644 index 912143f8..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh +++ /dev/null @@ -1,42 +0,0 @@ -ps.1.4 -;------------------------------------------------------------------------------ -; Phase 1 -;------------------------------------------------------------------------------ -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! -;mov r0.rgba, r4 - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) -; Alpha gets lost after phase marker, so store it here -mov r5, r0.a -;------------------------------------------------------------------------------ -; Phase 2 -;------------------------------------------------------------------------------ -phase -; Sample environment map -texld r3, r2 -; Result goes in output color (multiply by constant color c0) -mul r0.rgb, r3, c0 -+mov r0.a, c0.a - -mul r1.rgb, r0, r0 -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -dp3 r1.rgb, r0, c3 -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale - -; mult by alpha -mul r0.rgb, r0, r5 diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh deleted file mode 100644 index 7dec5f7d..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh +++ /dev/null @@ -1,39 +0,0 @@ -ps.1.4 -;------------------------------------------------------------------------------ -; Phase 1 -;------------------------------------------------------------------------------ -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) -; Alpha gets lost after phase marker, so store it here -mov r5, r0.a -;------------------------------------------------------------------------------ -; Phase 2 -;------------------------------------------------------------------------------ -phase -; Sample environment map -texld r3, r2 -; Result goes in output color (multiply by constant color c0) -mul r0.rgb, r3, c0 -+mov r0.a, c0.a - -mul r1.rgb, r0, r0 -lrp r0.rgb, c1, r1, r0 ; blend between color and color * color -dp3 r1.rgb, r0, c3 -lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale - diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh deleted file mode 100644 index 576e31cf..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh +++ /dev/null @@ -1,93 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -;------------------------------------------------------------------------------ -; Shader specific constant: -; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); -&AllocateRegister( \$worldNormal ); -&AllocateRegister( \$worldTangentS ); -&AllocateRegister( \$worldTangentT ); - -&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, - $worldTangentS, $worldTangentT ); - -;------------------------------------------------------------------------------ -; Transform the position from world to proj space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -; svect -mov oT1.x, $worldTangentS.x -mov oT2.x, $worldTangentS.y -mov oT3.x, $worldTangentS.z -&FreeRegister( \$worldTangentS ); - -; tvect -mov oT1.y, $worldTangentT.x -mov oT2.y, $worldTangentT.y -mov oT3.y, $worldTangentT.z -&FreeRegister( \$worldTangentT ); - -; normal -mov oT1.z, $worldNormal.x -mov oT2.z, $worldNormal.y -mov oT3.z, $worldNormal.z - -&FreeRegister( \$worldNormal ); - -; Compute the vector from vertex to camera -&AllocateRegister( \$eyeVector ); -sub $eyeVector.xyz, $cEyePos, $worldPos - -&FreeRegister( \$worldPos ); - -; Move it into the w component of the texture coords, as the wacky -; pixel shader wants it there. -mov oT1.w, $eyeVector.x -mov oT2.w, $eyeVector.y -mov oT3.w, $eyeVector.z - -&FreeRegister( \$eyeVector ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - - diff --git a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh b/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh deleted file mode 100644 index 2ac66164..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh +++ /dev/null @@ -1,90 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -;------------------------------------------------------------------------------ -; Shader specific constant: -; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); -&AllocateRegister( \$worldNormal ); -&AllocateRegister( \$worldTangentS ); -&AllocateRegister( \$worldTangentT ); - -&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, - $worldTangentS, $worldTangentT ); - -;------------------------------------------------------------------------------ -; Transform the position from world to proj space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -; svect -mov oT1.x, $worldTangentS.x -mov oT2.x, $worldTangentS.y -mov oT3.x, $worldTangentS.z -&FreeRegister( \$worldTangentS ); - -; tvect -mov oT1.y, $worldTangentT.x -mov oT2.y, $worldTangentT.y -mov oT3.y, $worldTangentT.z -&FreeRegister( \$worldTangentT ); - -; normal -mov oT1.z, $worldNormal.x -mov oT2.z, $worldNormal.y -mov oT3.z, $worldNormal.z - -&FreeRegister( \$worldNormal ); - -; Compute the vector from vertex to camera -&AllocateRegister( \$eyeVector ); -sub $eyeVector.xyz, $cEyePos, $worldPos - -&FreeRegister( \$worldPos ); - -; eye vector -mov oT4.xyz, $eyeVector - -&FreeRegister( \$eyeVector ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - - diff --git a/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh b/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh deleted file mode 100644 index a6209ab3..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh +++ /dev/null @@ -1,15 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t1 ; cube map -tex t2 ; envmap mask - -mul r1, t1, t2 ; Envmap * mask -mul r0.rgb, r1, c2 ; envmap * mask * tint -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 + ; * 2 * (overbrightFactor/2) -mul r0.a, c3.a, t2.a ; alpha = modulation * mask alpha - -#if WRITEONETODESTALPHA -mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh deleted file mode 100644 index 53519d93..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh +++ /dev/null @@ -1,16 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0, t0, c3 ; Base times modulation -mul r1, t1, t2 ; Envmap * mask -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) -mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh b/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh deleted file mode 100644 index 0bc2e455..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh +++ /dev/null @@ -1,9 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -mul r0, v0, c3 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh b/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh deleted file mode 100644 index 198ad9e4..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh +++ /dev/null @@ -1,5 +0,0 @@ -ps.1.1 - -tex t0 - -mul r0.rgba, c0, t0 diff --git a/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh b/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh deleted file mode 100644 index 40eb8d28..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh +++ /dev/null @@ -1,41 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -&SkinPosition( $worldPos ); - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -&CalcFog( $worldPos, $projPos ); -&FreeRegister( \$projPos ); -&FreeRegister( \$worldPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - diff --git a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh b/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh deleted file mode 100644 index 3d14e4b3..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh +++ /dev/null @@ -1,19 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 - -; interpolate between illuminated + non-selfilluminated -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh deleted file mode 100644 index b8ba4d13..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh +++ /dev/null @@ -1,21 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 -tex t1 - -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh deleted file mode 100644 index 44fe15d6..00000000 --- a/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh +++ /dev/null @@ -1,23 +0,0 @@ -; DYNAMIC: "WRITEONETODESTALPHA" "0..1" -ps.1.1 - -; Get the color from the texture -tex t0 ; base -tex t1 ; env map -tex t2 ; mask - -mul r0.rgb, t0, c3 + ; base times modulation -mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - -mul r1, t2, t1 ; envmapmask * envmap -mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) - -#if WRITEONETODESTALPHA -+mov r0.a, c4 ; make alpha 255 -#endif diff --git a/materialsystem/stdshaders/VertexLitTexture.psh b/materialsystem/stdshaders/VertexLitTexture.psh deleted file mode 100644 index 628cfc66..00000000 --- a/materialsystem/stdshaders/VertexLitTexture.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 - -mul r0, t0, v0 - diff --git a/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh b/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh deleted file mode 100644 index db2c4e2f..00000000 --- a/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh +++ /dev/null @@ -1,16 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 - -mul_x2 r0.rgb, t0, v0 -+ mul r0.a, t0, v0 - diff --git a/materialsystem/stdshaders/VertexlitPBR_dx9.cpp b/materialsystem/stdshaders/VertexlitPBR_dx9.cpp deleted file mode 100644 index 9775552b..00000000 --- a/materialsystem/stdshaders/VertexlitPBR_dx9.cpp +++ /dev/null @@ -1,112 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#include "BaseVSShader.h" -#include "convar.h" -#include "vertexlitpbr_dx9_helper.h" -#include "lightpass_helper.h" - -#ifdef STDSHADER -BEGIN_VS_SHADER(VertexLitPBR, - "Help for LightmappedPBR") -#else -BEGIN_VS_SHADER(VertexLitPBR, - "Help for LightmappedPBR") -#endif - -BEGIN_SHADER_PARAMS -SHADER_PARAM(ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "") -SHADER_PARAM(ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap") -SHADER_PARAM(BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map") - -SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") -SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") -SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(AO, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(EMISSIVE, SHADER_PARAM_TYPE_TEXTURE, "", "") -SHADER_PARAM(LIGHTMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "lightmap texture--will be bound by the engine") - -SHADER_PARAM(USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness") -END_SHADER_PARAMS - -void SetupVars(VertexLitPBR_DX9_Vars_t& info) -{ - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nAO = AO; - info.m_nEmissive = EMISSIVE; - info.m_nEnvmap = ENVMAP; - info.m_nBumpmap = BUMPMAP; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nBRDF = BRDF; - info.m_nUseSmoothness = USESMOOTHNESS; - info.m_nLightmap = LIGHTMAP; -} - -void SetupVars(DrawLightPass_Vars_t& info) -{ - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nNoise = NOISE; - info.m_nBumpmap = BUMPMAP; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nBumpmap2 = -1; - info.m_nBumpFrame2 = -1; - info.m_nBumpTransform2 = -1; - info.m_nBaseTexture2 = -1; - info.m_nBaseTexture2Frame = -1; - info.m_nSeamlessMappingScale = -1; - info.bModel = true; - info.m_nUseSmoothness = USESMOOTHNESS; -} - -SHADER_INIT_PARAMS() -{ - VertexLitPBR_DX9_Vars_t info; - SetupVars(info); - InitParamsVertexLitPBR_DX9(this, params, pMaterialName, info); -} - -SHADER_FALLBACK -{ - return 0; -} - -SHADER_INIT -{ - VertexLitPBR_DX9_Vars_t info; - SetupVars(info); - InitVertexLitPBR_DX9(this, params, info); -} - -SHADER_DRAW -{ - bool bDrawStandardPass = true; - bool hasFlashlight = UsingFlashlight(params); - - if (bDrawStandardPass) - { - VertexLitPBR_DX9_Vars_t info; - SetupVars(info); - DrawVertexLitPBR_DX9(this, params, pShaderAPI, pShaderShadow, hasFlashlight, info, vertexCompression, pContextDataPtr); - } - else - { - // Skip this pass! - Draw(false); - } - -} - -END_SHADER - diff --git a/materialsystem/stdshaders/VertexlitPBR_dx9_helper.cpp b/materialsystem/stdshaders/VertexlitPBR_dx9_helper.cpp deleted file mode 100644 index 1bf8b338..00000000 --- a/materialsystem/stdshaders/VertexlitPBR_dx9_helper.cpp +++ /dev/null @@ -1,516 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "vertexlitPBR_dx9_helper.h" -#include "convar.h" -#include "cpp_shader_constant_register_map.h" -#include "vertexlitPBR_vs30.inc" -#include "vertexlitPBR_ps30.inc" -#include "commandbuilder.h" - -#include "IDeferredExt.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); -static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); - -extern ConVar r_csm_bias; -extern ConVar r_csm_slopescalebias; -extern ConVar r_csm_performance; - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitPBR_DX9_Vars_t &info ) -{ - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - Assert( info.m_nFlashlightTexture >= 0 ); - - params[info.m_nBRDF]->SetStringValue("models/PBRTest/BRDF"); - - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - if (((info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined()) - // we don't need a tangent space if we have envmap without bumpmap - // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) - ) - { - SET_FLAGS2(MATERIAL_VAR2_NEEDS_TANGENT_SPACES); - } - - - // This shader can be used with hw skinning - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); -} - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- -void InitVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitPBR_DX9_Vars_t &info ) -{ - Assert( info.m_nFlashlightTexture >= 0 ); - pShader->LoadTexture(info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB); - - bool bIsBaseTextureTranslucent = false; - if ( params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - } - - if (info.m_nRoughness != -1 && params[info.m_nRoughness]->IsDefined()) - { - pShader->LoadTexture(info.m_nRoughness); - } - if (info.m_nMetallic != -1 && params[info.m_nMetallic]->IsDefined()) - { - pShader->LoadTexture(info.m_nMetallic); - } - if (info.m_nAO != -1 && params[info.m_nAO]->IsDefined()) - { - pShader->LoadTexture(info.m_nAO); - } - if (info.m_nEmissive != -1 && params[info.m_nEmissive]->IsDefined()) - { - pShader->LoadTexture(info.m_nEmissive); - } - if (info.m_nBRDF != -1 && params[info.m_nBRDF]->IsDefined()) - { - pShader->LoadTexture(info.m_nBRDF); - } - if (info.m_nLightmap != -1 && params[info.m_nLightmap]->IsDefined()) - { - pShader->LoadTexture(info.m_nLightmap); - } - - if (info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined()) - { - if (!IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE)) - { - int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; - flags |= TEXTUREFLAGS_ALL_MIPS; - pShader->LoadCubeMap(info.m_nEnvmap, flags); - } - else - { - pShader->LoadTexture(info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0); - } - - if (!g_pHardwareConfig->SupportsCubeMaps()) - { - SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); - } - } - - if (g_pConfig->UseBumpmapping()) - { - if ((info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined()) - { - pShader->LoadBumpMap(info.m_nBumpmap); - SET_FLAGS2(MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL); - } - } -} - -class CVertexLitPBR_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - bool m_bFastPath; - -}; - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -static void DrawVertexLitPBR_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bHasFlashlight, VertexLitPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); - bool bHasRoughness = (info.m_nRoughness != -1) && params[info.m_nRoughness]->IsTexture(); - bool bHasMetallic = (info.m_nMetallic != -1) && params[info.m_nMetallic]->IsTexture(); - bool bHasAO = (info.m_nAO != -1) && params[info.m_nAO]->IsTexture(); - bool bHasEmissive = (info.m_nEmissive != -1) && params[info.m_nEmissive]->IsTexture(); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - bool bHasEnvmap =(info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsTexture(); - bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); - bool bHasBump = IsTextureSet(info.m_nBumpmap, params); - bool bUseSmoothness = info.m_nUseSmoothness != -1 && params[info.m_nUseSmoothness]->GetIntValue() == 1; - bool bHasLightmap = (info.m_nLightmap != -1) && params[info.m_nLightmap]->IsTexture(); - - bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); - bool bHasVertexAlpha = IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA); - - BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); - bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; - - CVertexLitPBR_DX9_Context *pContextData = reinterpret_cast< CVertexLitPBR_DX9_Context *> ( *pContextDataPtr ); - if ( !pContextData ) - { - pContextData = new CVertexLitPBR_DX9_Context; - *pContextDataPtr = pContextData; - } - - if( pShader->IsSnapshotting() ) - { - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if( bHasFlashlight ) - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - - if( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - else // not flashlight pass - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); - } - } - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int userDataSize = 0; - - // Always enable...will bind white if nothing specified... - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Roughness map - pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); // Metallic map - - if (bHasEnvmap) - { - pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); - if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE) - { - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER7, true); - } - } - - - if (bHasVertexColor || bHasVertexAlpha) - { - flags |= VERTEX_COLOR; - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); - - if( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); - } - - pShaderShadow->EnableTexture(SHADER_SAMPLER8, true); // BRDF for IBL - - pShaderShadow->EnableTexture(SHADER_SAMPLER9, true); // Ambient Occlusion - pShaderShadow->EnableTexture(SHADER_SAMPLER10, true); // Emissive map - pShaderShadow->EnableTexture(SHADER_SAMPLER11, true); // Lightmap - - // Always enable, since flat normal will be bound - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map - userDataSize = 4; // tangent S - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map - pShaderShadow->EnableSRGBWrite( true ); - - // texcoord0 : base texcoord - int pTexCoordDim[3] = { 2, 2, 3 }; - int nTexCoordCount = 1; - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( vertexlitpbr_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha); - SET_STATIC_VERTEX_SHADER_COMBO(CUBEMAP, bHasEnvmap); - SET_STATIC_VERTEX_SHADER_COMBO(DONT_GAMMA_CONVERT_VERTEX_COLOR, bHasVertexColor); - SET_STATIC_VERTEX_SHADER(vertexlitpbr_vs30); - - // Assume we're only going to get in here if we support 2b - DECLARE_STATIC_PIXEL_SHADER(vertexlitpbr_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && !bHasFlashlight); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER_COMBO(SMOOTHNESS, bUseSmoothness); - SET_STATIC_PIXEL_SHADER(vertexlitpbr_ps30); - - if( bHasFlashlight ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - else // not snapshotting -- begin dynamic state - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - - if( bHasBaseTexture ) - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - else - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - - if (bHasRoughness) - pShader->BindTexture(SHADER_SAMPLER1, info.m_nRoughness); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER1, TEXTURE_WHITE); - - if (bHasMetallic) - pShader->BindTexture(SHADER_SAMPLER2, info.m_nMetallic); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER2, TEXTURE_BLACK); - - if (bHasEnvmap) - pShader->BindTexture(SHADER_SAMPLER7, info.m_nEnvmap); - - if (bHasAO) - pShader->BindTexture(SHADER_SAMPLER9, info.m_nAO); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER9, TEXTURE_WHITE); - - if (bHasEmissive) - pShader->BindTexture(SHADER_SAMPLER10, info.m_nEmissive); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER10, TEXTURE_BLACK); - - if (bHasLightmap) - pShader->BindTexture(SHADER_SAMPLER11, info.m_nLightmap); - else - pShaderAPI->BindStandardTexture(SHADER_SAMPLER11, TEXTURE_WHITE); - - if (!g_pConfig->m_bFastNoBump) - { - if (bHasBump) - { - pShader->BindTexture(SHADER_SAMPLER3, info.m_nBumpmap); - } - else - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); - } - } - else - { - if (bHasBump) - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); - } - } - - pShader->BindTexture(SHADER_SAMPLER8, info.m_nBRDF); - - LightState_t lightState = { 0, false, false }; - bool bFlashlightShadows = false; - if( bHasFlashlight ) - { - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); - - SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - } - else // no flashlight - { - pShaderAPI->GetDX9LightState( &lightState ); - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - int numBones = pShaderAPI->GetCurrentNumBones(); - - bool bWriteDepthToAlpha = false; - bool bWriteWaterFogToAlpha = false; - if( bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - - ITexture *pCascadedDepthTexture = (ITexture *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_DEPTHTEXTURE ); - bool bUseCSM = pCascadedDepthTexture != NULL; - - DECLARE_DYNAMIC_VERTEX_SHADER( vertexlitpbr_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER_COMBO(DYNAMIC_LIGHT, lightState.HasDynamicLight()); - SET_DYNAMIC_VERTEX_SHADER_COMBO(STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0); - SET_DYNAMIC_VERTEX_SHADER(vertexlitpbr_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(vertexlitpbr_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTMAP, bHasLightmap); - SET_DYNAMIC_PIXEL_SHADER_COMBO(LIGHT_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM, bUseCSM && !bHasFlashlight ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM_PERF, MAX( 0, MIN( r_csm_performance.GetInt(), 2 ) ) ); // i just dont know anymore - SET_DYNAMIC_PIXEL_SHADER(vertexlitpbr_ps30); - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - pShader->SetAmbientCubeDynamicStateVertexShader(); - - // handle mat_fullbright 2 (diffuse lighting only) - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - if (!bHasFlashlight) - { - pShaderAPI->BindStandardTexture(SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED); - pShaderAPI->CommitPixelShaderLighting(PSREG_LIGHT_INFO_ARRAY); - pShaderAPI->SetPixelShaderStateAmbientLightCube(PSREG_AMBIENT_CUBE); // Force to black if not bAmbientLight - } - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1); - - if( bHasFlashlight ) - { - VMatrix worldToTexture; - float atten[4], pos[4], tweaks[4]; - - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - - float const* pFlashlightColor = flashlightState.m_Color; - float vPsConst[4] = { pFlashlightColor[0], pFlashlightColor[1], pFlashlightColor[2], 4.5f }; - pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_COLOR, vPsConst, 1); - - pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); - - // Tweaks associated with a given flashlight - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - } - else - { - if ( bUseCSM ) - { - pShader->BindTexture( SHADER_SAMPLER4, pCascadedDepthTexture ); - - VMatrix *worldToTexture0 = (VMatrix *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0 ); - pShaderAPI->SetPixelShaderConstant( 32, worldToTexture0->Base(), 4 ); - - lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); - Vector csmFwd = csmData.vecLight; - pShaderAPI->SetPixelShaderConstant( 36, csmFwd.Base() ); - - Vector csmLight = csmData.light.AsVector3D(); - pShaderAPI->SetPixelShaderConstant( 37, csmLight.Base() ); - - Vector csmAmbient = csmData.ambient.AsVector3D(); - pShaderAPI->SetPixelShaderConstant( 38, csmAmbient.Base() ); - - float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; - pShaderAPI->SetPixelShaderConstant( 39, biasVar ); - - float textureSize[2] = { pCascadedDepthTexture->GetActualWidth(), pCascadedDepthTexture->GetActualHeight() }; - pShaderAPI->SetPixelShaderConstant( 40, textureSize ); - - pShaderAPI->SetPixelShaderConstant( 41, GetDeferredExt()->GetLightData_Global().sizes.Base() ); - } - } - } - pShader->Draw(); -} - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bHasFlashlight, - VertexLitPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) - -{ - DrawVertexLitPBR_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh b/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh deleted file mode 100644 index 2aff6a46..00000000 --- a/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh +++ /dev/null @@ -1,40 +0,0 @@ -ps.1.4 - -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) - -phase - -; Sample environment map -texld r3, r2 -texld r4, t5 ; Normalize the tangent-space eye vector - -; dot eye-vector with per-pixel normal from r0 -dp3_sat r1, r4_bx2, r0_bx2 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -mul r0.a, 1-r1.a, 1-r1.a ; squared -mul r0.a, r0.a, r0.a ; quartic -mul_sat r1.a, r0.a, 1-r1.a ; quintic - -; multiply color by reflecttint -mul r0, r3, c1 - -; blend between reflected color and fog color based on fresnel -lrp r0.rgb, r1.a, r0, c0 \ No newline at end of file diff --git a/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh b/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh deleted file mode 100644 index 741881be..00000000 --- a/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh +++ /dev/null @@ -1,39 +0,0 @@ -ps.1.4 - -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) - -phase - -; Sample environment map -texld r3, r2 -texld r4, t5 ; Normalize the tangent-space eye vector - -; dot eye-vector with per-pixel normal from r0 -dp3_sat r1, r4_bx2, r0_bx2 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -mul r0.a, 1-r1.a, 1-r1.a ; squared -mul r0.a, r0.a, r0.a ; quartic -mul_sat r1.a, r0.a, 1-r1.a ; quintic - -; multiply color by reflecttint -mul r0.rgb, r3, c1 -+mov_sat r0.a, v0.a -add_sat r0.a, r1.a, r0.a diff --git a/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh b/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh deleted file mode 100644 index c1a28c10..00000000 --- a/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -mul r0, t3, c1 ; multiply color by reflecttint -lrp r0.rgb, c1.a, r0, c0 ; blend between reflected color and fog color based on constant factor - - - - - diff --git a/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh b/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh deleted file mode 100644 index d63151bb..00000000 --- a/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh +++ /dev/null @@ -1,18 +0,0 @@ -ps.1.1 - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -mul r0.rgb, t3, c1 ; multiply color by reflecttint -+mov_sat r0.a, v0.a ; NOTE: This is necessary since v0.a can be outside 0 - 1! -add_sat r0.a, c1.a, r0.a ; cheap water blend factor + constant blend factor - - - diff --git a/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh b/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh deleted file mode 100644 index 9704bfde..00000000 --- a/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh +++ /dev/null @@ -1,26 +0,0 @@ -ps.1.1 - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -mul r0, t3, c1 ; envmap color * envmaptint - -dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -; NOTE: This is not perspective-correct and results in strange artifacts -mul r1.a, 1-t2.a, 1-t2.a ; squared -mul r1.a, r1.a, r1.a ; quartic -mul_sat r1.a, r1.a, 1-t2.a ; quintic - -; t1.a is now the fresnel factor -lrp r0.rgb, r1.a, r0, c0 ; blend between reflected color and fog color based on fresnel - - diff --git a/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh b/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh deleted file mode 100644 index a1b52625..00000000 --- a/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh +++ /dev/null @@ -1,31 +0,0 @@ -ps.1.4 - -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) - -phase - -; Sample environment map -texld r3, r2 - -; multiply color by reflecttint -mul r0, r3, c1 - -; blend between reflected color and fog color based on constant factor -lrp r0.rgb, c1.a, r0, c0 diff --git a/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh b/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh deleted file mode 100644 index 6ca504cf..00000000 --- a/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh +++ /dev/null @@ -1,100 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); - -; Transform position from object to world -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -dp3 oT1.x, $vTangentS, $cModel0 -dp3 oT2.x, $vTangentS, $cModel1 -dp3 oT3.x, $vTangentS, $cModel2 - -dp3 oT1.y, $vTangentT, $cModel0 -dp3 oT2.y, $vTangentT, $cModel1 -dp3 oT3.y, $vTangentT, $cModel2 - -dp3 oT1.z, $vNormal, $cModel0 -dp3 oT2.z, $vNormal, $cModel1 -dp3 oT3.z, $vNormal, $cModel2 - -; Compute the vector from vertex to camera -&AllocateRegister( \$worldEyeVect ); -sub $worldEyeVect.xyz, $cEyePos, $worldPos -&FreeRegister( \$worldPos ); - -; Move it into the w component of the texture coords, as the wacky -; pixel shader wants it there. -mov oT1.w, $worldEyeVect.x -mov oT2.w, $worldEyeVect.y -mov oT3.w, $worldEyeVect.z - -&AllocateRegister( \$tangentEyeVect ); - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal - -&Normalize( $tangentEyeVect ); -mov oD0.xyz, $tangentEyeVect - -&FreeRegister( \$tangentEyeVect ); - -; Get the magnitude of worldEyeVect -dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect -rsq $worldEyeVect.w, $worldEyeVect.w -rcp $worldEyeVect.w, $worldEyeVect.w - -; calculate the cheap water blend factor and stick it into oD0.a -; NOTE: This won't be perspective correct!!!!! -; OPTIMIZE: This could turn into a mad. -add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x -mul oD0.w, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y - -&FreeRegister( \$worldEyeVect ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - - diff --git a/materialsystem/stdshaders/WaterCheap_ps11.psh b/materialsystem/stdshaders/WaterCheap_ps11.psh deleted file mode 100644 index f12a1bc4..00000000 --- a/materialsystem/stdshaders/WaterCheap_ps11.psh +++ /dev/null @@ -1,26 +0,0 @@ -ps.1.1 - -; Get the 3-vector from the normal map -tex t0 - -; Perform matrix multiply to get a local normal bump. Then -; reflect the eye vector through the normal and sample from -; a cubic environment map. -texm3x3pad t1, t0_bx2 -texm3x3pad t2, t0_bx2 -texm3x3vspec t3, t0_bx2 - -mul r0.rgb, t3, c1 ; envmap color * envmaptint -+mov_sat r0.a, v0.a ; Put the cheap water blend factor here - -dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel -; NOTE: This is not perspective-correct and results in strange artifacts -mul r1.a, 1-t2.a, 1-t2.a ; squared -mul r1.a, r1.a, r1.a ; quartic -mul_sat r1.a, r1.a, 1-t2.a ; quintic - -; t1.a is now the fresnel factor -add_sat r0.a, r1.a, r0.a ; Now we have the final blend factor between cheap water + refraction - diff --git a/materialsystem/stdshaders/WaterCheap_ps14.psh b/materialsystem/stdshaders/WaterCheap_ps14.psh deleted file mode 100644 index e38f65ee..00000000 --- a/materialsystem/stdshaders/WaterCheap_ps14.psh +++ /dev/null @@ -1,30 +0,0 @@ -ps.1.4 - -; Get the 3-vector from the normal map -texld r0, t0 -; Get environment matrix -texcrd r1.rgb, t1 -texcrd r2.rgb, t2 -texcrd r3.rgb, t3 -; Normalize eye-ray vector through normalizer cube map -texld r4, t4 ; <---- CUBE MAP here!!! - -; Transform normal -dp3 r5.r, r1, r0_bx2 -dp3 r5.g, r2, r0_bx2 -dp3 r5.b, r3, r0_bx2 -; Reflection calculatiom -dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) -mul r3.rgb, r5, r3 ; 2N(N.Eye) -dp3 r2.rgb, r5, r5 ; N.N -mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) - -phase - -; Sample environment map -texld r3, r2 - -; multiply color by reflecttint -mul r0.rgb, r3, c1 -+mov_sat r0.a, v0.a ; Necessary since v0.a may be negative -add_sat r0.a, c1.a, r0.a diff --git a/materialsystem/stdshaders/WaterCheap_ps2x.fxc b/materialsystem/stdshaders/WaterCheap_ps2x.fxc deleted file mode 100644 index 4ca66570..00000000 --- a/materialsystem/stdshaders/WaterCheap_ps2x.fxc +++ /dev/null @@ -1,152 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "MULTITEXTURE" "0..1" -// STATIC: "FRESNEL" "0..1" -// STATIC: "BLEND" "0..1" -// STATIC: "REFRACTALPHA" "0..1" -// STATIC: "HDRTYPE" "0..2" -// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] -// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] - -// DYNAMIC: "HDRENABLED" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -#include "common_ps_fxc.h" - -const HALF3 g_WaterFogColor : register( c0 ); -const HALF4 g_CheapWaterParams : register( c1 ); -const HALF4 g_ReflectTint : register( c2 ); -const float4 g_PixelFogParams : register( c3 ); - -#define g_CheapWaterStart g_CheapWaterParams.x -#define g_CheapWaterEnd g_CheapWaterParams.y -#define g_CheapWaterDeltaRecip g_CheapWaterParams.z -#define g_CheapWaterStartDivDelta g_CheapWaterParams.w - -sampler EnvmapSampler : register( s0 ); -sampler NormalMapSampler : register( s1 ); -#if REFRACTALPHA -sampler RefractSampler : register( s2 ); -#endif -sampler NormalizeSampler : register( s6 ); - -struct PS_INPUT -{ - float2 normalMapTexCoord : TEXCOORD0; - HALF3 worldSpaceEyeVect : TEXCOORD1; - HALF3x3 tangentSpaceTranspose : TEXCOORD2; - float4 vRefract_W_ProjZ : TEXCOORD5; - -#if MULTITEXTURE - float4 vExtraBumpTexCoord : TEXCOORD6; -#endif - float4 fogFactorW : COLOR1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - bool bBlend = BLEND ? true : false; - -#if MULTITEXTURE - float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord ); - float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy ); - float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw ); - vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); - -#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) - vNormal.xy = vNormal.xy * 2.0f - 1.0f; - vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); -#else - vNormal = 2.0 * vNormal - 1.0; -#endif - -#else - float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORMAL_DECODE_MODE ); -#endif - - HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); - HALF3 worldSpaceEye; - - HALF flWorldSpaceDist = 1.0f; - -#ifdef NV3X - // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes. - if (bBlend) - { - worldSpaceEye = i.worldSpaceEyeVect; - HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye ); - HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr ); - worldSpaceEye *= rcpWorldSpaceDist; - flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist; - } - else - { - worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); - } -#else // !NV3X - if (bBlend) - { - worldSpaceEye = i.worldSpaceEyeVect; - flWorldSpaceDist = length( worldSpaceEye ); - worldSpaceEye /= flWorldSpaceDist; - } - else - { - worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); - } -#endif - - HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye ); - HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= g_ReflectTint; - -#if FRESNEL - // FIXME: It's unclear that we want to do this for cheap water - // but the code did this previously and I didn't want to change it - HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal ); - flDotResult = 1.0f - max( 0.0f, flDotResult ); - - HALF flFresnelFactor = flDotResult * flDotResult; - flFresnelFactor *= flFresnelFactor; - flFresnelFactor *= flDotResult; -#else - HALF flFresnelFactor = g_ReflectTint.a; -#endif - - HALF flAlpha; - if (bBlend) - { - HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta ); - flAlpha = saturate( flFresnelFactor + flReflectAmount ); - -#if REFRACTALPHA - // Perform division by W only once - float ooW = 1.0f / i.vRefract_W_ProjZ.z; - float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW; - float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; - // Fade on the border between the water and land. - flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f ); -#endif - } - else - { - flAlpha = 1.0f; -#if HDRTYPE == 0 || HDRENABLED == 0 - specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor ); -#else - specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor ); -#endif - } - - // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders. - - - -#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) - float fogFactor = CalcRangeFog( i.vRefract_W_ProjZ.w, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w ); -#else - float fogFactor = 0; -#endif - - return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -} diff --git a/materialsystem/stdshaders/WaterCheap_vs11.vsh b/materialsystem/stdshaders/WaterCheap_vs11.vsh deleted file mode 100644 index b1cdd61f..00000000 --- a/materialsystem/stdshaders/WaterCheap_vs11.vsh +++ /dev/null @@ -1,88 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); - -; Transform position from object to world -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -dp3 oT1.x, $vTangentS, $cModel0 -dp3 oT2.x, $vTangentS, $cModel1 -dp3 oT3.x, $vTangentS, $cModel2 - -dp3 oT1.y, $vTangentT, $cModel0 -dp3 oT2.y, $vTangentT, $cModel1 -dp3 oT3.y, $vTangentT, $cModel2 - -dp3 oT1.z, $vNormal, $cModel0 -dp3 oT2.z, $vNormal, $cModel1 -dp3 oT3.z, $vNormal, $cModel2 - -; Compute the vector from vertex to camera -&AllocateRegister( \$worldEyeVect ); -sub $worldEyeVect.xyz, $cEyePos, $worldPos -&FreeRegister( \$worldPos ); - -; Move it into the w component of the texture coords, as the wacky -; pixel shader wants it there. -mov oT1.w, $worldEyeVect.x -mov oT2.w, $worldEyeVect.y -mov oT3.w, $worldEyeVect.z - -; Get the magnitude of worldEyeVect -dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect -rsq $worldEyeVect.w, $worldEyeVect.w -rcp $worldEyeVect.w, $worldEyeVect.w - -; calculate the cheap water blend factor and stick it into oD0.a -; NOTE: This won't be perspective correct!!!!! -; OPTIMIZE: This could turn into a mad. -add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x -mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y - -&FreeRegister( \$worldEyeVect ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - - diff --git a/materialsystem/stdshaders/WaterCheap_vs14.vsh b/materialsystem/stdshaders/WaterCheap_vs14.vsh deleted file mode 100644 index 0e5a1074..00000000 --- a/materialsystem/stdshaders/WaterCheap_vs14.vsh +++ /dev/null @@ -1,96 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ - -&AllocateRegister( \$worldPos ); - -; Transform position from object to world -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&AllocateRegister( \$projPos ); - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ - -; Transform tangent space basis vectors to env map space (world space) -; This will produce a set of vectors mapping from tangent space to env space -; We'll use this to transform normals from the normal map from tangent space -; to environment map space. -; NOTE: use dp3 here since the basis vectors are vectors, not points - -dp3 oT1.x, $vTangentS, $cModel0 -dp3 oT2.x, $vTangentS, $cModel1 -dp3 oT3.x, $vTangentS, $cModel2 - -dp3 oT1.y, $vTangentT, $cModel0 -dp3 oT2.y, $vTangentT, $cModel1 -dp3 oT3.y, $vTangentT, $cModel2 - -dp3 oT1.z, $vNormal, $cModel0 -dp3 oT2.z, $vNormal, $cModel1 -dp3 oT3.z, $vNormal, $cModel2 - -; Compute the vector from vertex to camera -&AllocateRegister( \$worldEyeVect ); -sub $worldEyeVect.xyz, $cEyePos, $worldPos -&FreeRegister( \$worldPos ); - -; eye vector -mov oT4.xyz, $worldEyeVect - -alloc $tangentEyeVect - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal - -; Get the magnitude of worldEyeVect -dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect -rsq $worldEyeVect.w, $worldEyeVect.w -rcp $worldEyeVect.w, $worldEyeVect.w - -; calculate the cheap water blend factor and stick it into oD0.a -; NOTE: This won't be perspective correct!!!!! -; OPTIMIZE: This could turn into a mad. -add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x -mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y - -; stick the tangent space eye vector into oT5.xyz -mov oT5.xyz, $tangentEyeVect - -&FreeRegister( \$worldEyeVect ); -&FreeRegister( \$tangentEyeVect ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - - diff --git a/materialsystem/stdshaders/WaterCheap_vs20.fxc b/materialsystem/stdshaders/WaterCheap_vs20.fxc deleted file mode 100644 index bae02380..00000000 --- a/materialsystem/stdshaders/WaterCheap_vs20.fxc +++ /dev/null @@ -1,84 +0,0 @@ -// STATIC: "BLEND" "0..1" -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vNormal : NORMAL; - float2 vNormalMapCoord : TEXCOORD0; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 normalMapTexCoord : TEXCOORD0; - float3 worldVertToEyeVector : TEXCOORD1; - float3x3 tangentSpaceTranspose : TEXCOORD2; - float4 vRefract_W_ProjZ : TEXCOORD5; - float4 vExtraBumpTexCoord : TEXCOORD6; - float4 fogFactorW : COLOR1; -}; - -const float4 cNormalMapTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - float4 projPos; - float3 worldPos; - - projPos = mul( v.vPos, cModelViewProj ); - o.projPos = projPos; - -#if BLEND - // Map projected position to the reflection texture - o.vRefract_W_ProjZ.x = projPos.x; - o.vRefract_W_ProjZ.y = -projPos.y; // invert Y - o.vRefract_W_ProjZ.xy = (o.vRefract_W_ProjZ + projPos.w) * 0.5f; - o.vRefract_W_ProjZ.z = projPos.w; -#endif - - o.vRefract_W_ProjZ.w = projPos.z; - - worldPos = mul( v.vPos, cModel[0] ); - - float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); - float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); - float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); - o.tangentSpaceTranspose[0] = worldTangentS; - o.tangentSpaceTranspose[1] = worldTangentT; - o.tangentSpaceTranspose[2] = worldNormal; - - float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); - o.worldVertToEyeVector = worldVertToEyeVector; - - // FIXME: need to add a normalMapTransform to all of the water shaders. - //o.normalMapTexCoord.x = dot( v.vNormalMapCoord, cNormalMapTransform[0] ) + cNormalMapTransform[0].w; - //o.normalMapTexCoord.y = dot( v.vNormalMapCoord, cNormalMapTransform[1] ) + cNormalMapTransform[1].w; - o.normalMapTexCoord = v.vNormalMapCoord; - - float f45x=v.vNormalMapCoord.x+v.vNormalMapCoord.y; - float f45y=v.vNormalMapCoord.y-v.vNormalMapCoord.x; - o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; - o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; - o.vExtraBumpTexCoord.z=v.vNormalMapCoord.y*0.45+TexOffsets.z; - o.vExtraBumpTexCoord.w=v.vNormalMapCoord.x*0.45+TexOffsets.w; - - o.fogFactorW = CalcFog( worldPos, projPos, FOGTYPE_RANGE ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - return o; -} - - diff --git a/materialsystem/stdshaders/WaterReflect_ps11.psh b/materialsystem/stdshaders/WaterReflect_ps11.psh deleted file mode 100644 index 785ced64..00000000 --- a/materialsystem/stdshaders/WaterReflect_ps11.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -; t0: -; texture: dudv map -; texcoords: dudvmap texcoords -; t1: -; texture: reflection render target -; texcoords: -; t2: -; texture: normal map (usef for fresnel calculation) -; texcoords: -; t4: texture: normalization cube map -; texcoords: eye vect - -tex t0 ; sample dudv map -texbem t1, t0 ; reflection -tex t2 ; normal map -tex t3 ; eye vector (through normalization cubemap) - -; dot eye-vector with per-pixel normal from t2 -dp3_sat r1.rgba, t3_bx2, t2_bx2 - -; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 -mul r0.a, 1-r1.a, 1-r1.a // squared -mul r0.a, r0.a, r0.a // quartic -mul r0.rgb, t1, c0 // shove color from reflection render target into r0 -+mul_sat r0.a, r0.a, 1-r1.a // quintic \ No newline at end of file diff --git a/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh b/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh deleted file mode 100644 index efade0f9..00000000 --- a/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh +++ /dev/null @@ -1,24 +0,0 @@ -ps.1.1 - -; t0: -; texture: dudv map -; texcoords: dudvmap texcoords -; t1: -; texture: refraction render target -; texcoords: - -tex t0 ; sample dudv map -texbem t1, t0 ; refraction -tex t2 ; The normal map -tex t3 ; Normalize the tangent-space vector to the eye - -; dot eye-vector with per-pixel normal from t2 -dp3_sat r1.rgba, t2_bx2, t3_bx2 - -mul r0.a, 1-r1.a, 1-r1.a ; squared -mul r0.a, r0.a, r0.a ; quartic - -mul r0.rgb, t1, c0 -+mul_sat r0.a, r0.a, 1-r1.a ; quintic - -add_sat r0.a, r0.a, v0.a ; cheap water distance diff --git a/materialsystem/stdshaders/WaterRefract_ps11.psh b/materialsystem/stdshaders/WaterRefract_ps11.psh deleted file mode 100644 index fbe75475..00000000 --- a/materialsystem/stdshaders/WaterRefract_ps11.psh +++ /dev/null @@ -1,13 +0,0 @@ -ps.1.1 - -; t0: -; texture: dudv map -; texcoords: dudvmap texcoords -; t1: -; texture: refraction render target -; texcoords: - -tex t0 ; sample dudv map -texbem t1, t0 ; refraction - -mul r0, t1, c0 diff --git a/materialsystem/stdshaders/Water_ps14.psh b/materialsystem/stdshaders/Water_ps14.psh deleted file mode 100644 index 55e6b0ce..00000000 --- a/materialsystem/stdshaders/Water_ps14.psh +++ /dev/null @@ -1,96 +0,0 @@ -; STATIC: "REFLECT" "0..1" -; STATIC: "REFRACT" "0..1" -ps.1.4 -; T2 - refraction -; T3 - normal map -; T4 - reflection -; TC0 - normal map coords -; TC1 - proj tex coords (reflection) -; TC2 - proj tex coords (refraction) -; TC3 - tangent space view vec -; TC4 - displacement scale - -; sample normal map -texld r3, t0 - -#if REFLECT -; reflection coords -texcrd r4.xy, t1_dw.xyw -#endif -#if REFRACT -; refraction coords -texcrd r2.xy, t2_dw.xyw -#endif -; tangent space eye vector -texld r1, t5 ; <---- Normalizing CUBE MAP here!!! -; reflection/refraction scale (x,y) -texcrd r0.xyz, t4.xyz - -; perturb coords by constant displacement -; and by normal map alpha (which has 1/(2**miplevel in it) -mul r0.rg, r0, r3.a -#if REFLECT -mad r4.rg, r3_bx2, r0.x, r4 -#endif - -#if REFRACT -mad r2.rg, r3_bx2, r0.y, r2 -#endif - -; stuff something into z so that texld will deal -#if REFLECT -mov r4.b, c5 -#endif -#if REFRACT -mov r2.b, c5 -#endif - -phase - -#if REFLECT -; reflection -texld r4, r4 -#endif -#if REFRACT -; refraction -texld r2, r2 -#endif - -#if REFLECT -; N.V -dp3_sat r1.a, r3_bx2, r1_bx2 -#endif - -#if REFRACT -; tint refraction -mul r2.rgb, r2, c1 -#endif - -#if REFLECT -; tint reflction -mul r4.rgb, r4, c4 - -; (1-N.V) ^ 5 -+mul r0.a, 1-r1.a, 1-r1.a -mul r0.a, r0.a, r0.a -mul_sat r0.a, r0.a, 1-r1.a -#endif - -#if !REFLECT && !REFRACT -; This is wrong!!!! -mov r0.rgba, c0 -#endif - -#if !REFLECT && REFRACT -mov r0.rgba, r2 -#endif - -#if REFLECT && !REFRACT -mov r0.rgba, r4 -#endif - -#if REFLECT && REFRACT -; reflection * fresnel + refraction * ( 1 - fresnel ) -lrp r0.rgba, r0.a, r4, r2 -#endif - diff --git a/materialsystem/stdshaders/Water_ps14.vsh b/materialsystem/stdshaders/Water_ps14.vsh deleted file mode 100644 index 0ec30aa7..00000000 --- a/materialsystem/stdshaders/Water_ps14.vsh +++ /dev/null @@ -1,95 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; Constants specified by the app -; c0 = (0, 1, 2, 0.5) -; c1 = (1/2.2, 0, 0, 0) -; c2 = camera position *in world space* -; c4-c7 = modelViewProj matrix (transpose) -; c8-c11 = ViewProj matrix (transpose) -; c12-c15 = model->view matrix (transpose) -; c16 = [fogStart, fogEnd, fogRange, undefined] -; -; $SHADER_SPECIFIC_CONST_0..$SHADER_SPECIFIC_CONST_3 - special proj matrix -; -; Vertex components (as specified in the vertex DECL) -; $vPos = Position -; $vTexCoord0.xy = TexCoord0 -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -; Vertex components -; $vPos = Position -; $vNormal = normal -; $vTexCoord0.xy = TexCoord0 -; $vTangentS = S axis of Texture space -; $vTangentT = T axis of Texture space - - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - - -alloc $projPos - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -alloc $worldPos - -; Transform position from object to world space -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -alloc $worldEyeVect - -; Get the eye vector in world space -add $worldEyeVect.xyz, -$worldPos, $cEyePos - -alloc $tangentEyeVect - -; transform the eye vector to tangent space -dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS -dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT -dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal -mov $tangentEyeVect.w, $cZero - -mov oT5, $tangentEyeVect - -; base coordinates -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - -; reflection -alloc $projPosReflect - -mov $projPosReflect, $projPos -add $projPosReflect.xy, $projPosReflect, $projPosReflect.w -mul $projPosReflect.xy, $projPosReflect, $cHalf -mov oT1, $projPosReflect - -; refraction -mov $projPos.y, -$projPos.y -add $projPos.xy, $projPos, $projPos.w -mul $projPos.xy, $projPos, $cHalf -mov oT2, $projPos - -; reflectionscale, refractionscale -mov oT4, $SHADER_SPECIFIC_CONST_4 - -free $worldEyeVect -free $tangentEyeVect -free $projPosReflect -free $worldPos -free $projPos \ No newline at end of file diff --git a/materialsystem/stdshaders/Water_vs11.vsh b/materialsystem/stdshaders/Water_vs11.vsh deleted file mode 100644 index 3b0131b8..00000000 --- a/materialsystem/stdshaders/Water_vs11.vsh +++ /dev/null @@ -1,102 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -;------------------------------------------------------------------------------ -; Constants specified by the app -; c0 = (0, 1, 2, 0.5) -; c1 = (1/2.2, 0, 0, 0) -; c2 = camera position *in world space* -; c4-c7 = modelViewProj matrix (transpose) -; c8-c11 = ViewProj matrix (transpose) -; c12-c15 = model->view matrix (transpose) -; c16 = [fogStart, fogEnd, fogRange, undefined] -; -; Vertex components (as specified in the vertex DECL) -; $vPos = Position -; $vTexCoord0.xy = TexCoord0 -;------------------------------------------------------------------------------ - -#include "macros.vsh" - -; Vertex components -; $vPos = Position -; $vNormal = normal -; $vTexCoord0.xy = TexCoord0 -; $vTangentS = S axis of Texture space -; $vTangentT = T axis of Texture space - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -alloc $projPos - -; Transform position from object to projection space -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 - -alloc $worldPos - -; Transform position from object to world space -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -alloc $worldEyeVect - -; Get the eye vector in world space -add $worldEyeVect.xyz, -$worldPos, $cEyePos - -; transform the eye vector to tangent space -dp3 oT3.x, $worldEyeVect, $vTangentS -dp3 oT3.y, $worldEyeVect, $vTangentT -dp3 oT3.z, $worldEyeVect, $vNormal - -; Get the magnitude of worldEyeVect -dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect -rsq $worldEyeVect.w, $worldEyeVect.w -rcp $worldEyeVect.w, $worldEyeVect.w - -; calculate the cheap water blend factor and stick it into oD0.a -; NOTE: This won't be perspective correct!!!!! -; OPTIMIZE: This could turn into a mad. -add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_3.x -mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_3.y - -; dudv map -alloc $bumpTexCoord - -dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - -mov oT0.xy, $bumpTexCoord - -; normal map -mov oT2.xy, $bumpTexCoord - -free $bumpTexCoord - -alloc $newProjPos - -mov oPos, $projPos - -; special case perspective correct texture projection so that the texture fits exactly on the screen -mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w -add $projPos.xy, $projPos.xy, $projPos.w -mul $projPos.xy, $projPos.xy, $cHalf - -mov oT1.xy, $projPos.xy -mov oT1.z, $cZero -mov oT1.w, $projPos.w - -free $projPos -free $worldPos -free $worldEyeVect -free $projTangentS -free $projTangentT -free $newProjPos diff --git a/materialsystem/stdshaders/Water_vs20.fxc b/materialsystem/stdshaders/Water_vs20.fxc deleted file mode 100644 index 8f3a7a81..00000000 --- a/materialsystem/stdshaders/Water_vs20.fxc +++ /dev/null @@ -1,117 +0,0 @@ -// STATIC: "BASETEXTURE" "0..1" -// STATIC: "MULTITEXTURE" "0..1" - -// SKIP: $MULTITEXTURE && $BASETEXTURE - -#include "common_vs_fxc.h" - -const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); -const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vNormal : NORMAL; - float4 vBaseTexCoord : TEXCOORD0; - float2 vLightmapTexCoord : TEXCOORD1; - float2 vLightmapTexCoordOffset : TEXCOORD2; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL0; -}; - -struct VS_OUTPUT -{ - float4 vProjPos_POSITION : POSITION; -#if !defined( _X360 ) - float vFog : FOG; -#endif - float2 vBumpTexCoord : TEXCOORD0; - float3 vTangentEyeVect : TEXCOORD1; - float4 vReflectXY_vRefractYX : TEXCOORD2; - float W : TEXCOORD3; - float4 vProjPos : TEXCOORD4; - float screenCoord : TEXCOORD5; -#if MULTITEXTURE - float4 vExtraBumpTexCoord : TEXCOORD6; -#endif -#if BASETEXTURE - HALF4 lightmapTexCoord1And2 : TEXCOORD6; - HALF4 lightmapTexCoord3 : TEXCOORD7; -#endif - float4 fogFactorW : COLOR1; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - // Projected position - float4 vProjPos = mul( v.vPos, cModelViewProj ); - o.vProjPos = o.vProjPos_POSITION = vProjPos; - - // Project tangent basis - float2 vProjTangentS = mul( v.vTangentS, cViewProj ); - float2 vProjTangentT = mul( v.vTangentT, cViewProj ); - - // Map projected position to the reflection texture - float2 vReflectPos; - vReflectPos = (vProjPos.xy + vProjPos.w) * 0.5f; - - // Map projected position to the refraction texture - float2 vRefractPos; - vRefractPos.x = vProjPos.x; - vRefractPos.y = -vProjPos.y; // invert Y - vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; - - // Reflection transform - o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x ); - o.W = vProjPos.w; - - o.screenCoord = vProjPos.x; - - // Compute fog based on the position - float3 vWorldPos = mul( v.vPos, cModel[0] ); - o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); -#if !defined( _X360 ) - o.vFog = o.fogFactorW; -#endif - - // Eye vector - float3 vWorldEyeVect = cEyePos - vWorldPos; - // Transform to the tangent space - o.vTangentEyeVect.x = dot( vWorldEyeVect, v.vTangentS ); - o.vTangentEyeVect.y = dot( vWorldEyeVect, v.vTangentT ); - o.vTangentEyeVect.z = dot( vWorldEyeVect, vObjNormal ); - - // Tranform bump coordinates - o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); - o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); - float f45x=v.vBaseTexCoord.x+v.vBaseTexCoord.y; - float f45y=v.vBaseTexCoord.y-v.vBaseTexCoord.x; -#if MULTITEXTURE - o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; - o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; - o.vExtraBumpTexCoord.z=v.vBaseTexCoord.y*0.45+TexOffsets.z; - o.vExtraBumpTexCoord.w=v.vBaseTexCoord.x*0.45+TexOffsets.w; -#endif - -#if BASETEXTURE - o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; - - float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; - float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; - - // reversed component order - o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; - o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; - - o.lightmapTexCoord3.xy = lightmapTexCoord3; -#endif - - return o; -} - - diff --git a/materialsystem/stdshaders/WorldTexture.psh b/materialsystem/stdshaders/WorldTexture.psh deleted file mode 100644 index 933435bf..00000000 --- a/materialsystem/stdshaders/WorldTexture.psh +++ /dev/null @@ -1,14 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 -mov r0, t0 - diff --git a/materialsystem/stdshaders/WorldTwoTextureBlend.psh b/materialsystem/stdshaders/WorldTwoTextureBlend.psh deleted file mode 100644 index a3f3c6a4..00000000 --- a/materialsystem/stdshaders/WorldTwoTextureBlend.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mov r0.rgb, t0 + -mul r0.a, t0.a, v0.a ; Grab alpha from vertex color - -lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha -mul r0.rgb, r0, v0 ; modulate by vertex color -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh b/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh deleted file mode 100644 index d5e07368..00000000 --- a/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh +++ /dev/null @@ -1,25 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -def c1, 1.0f, 1.0f, 1.0f, 1.0f - -tex t0 -tex t1 -tex t2 - -mov_x2_sat r0.rgb, t0 + ; r0 = sat( t0 * 2 ) -mul r0.a, t0.a, v0.a ; Grab alpha from vertex color - -lrp_sat r0.rgb, t2.a, r0, c1 ; r0 = B*Da + (1-Da) - -mul r0.rgb, r0, t2 ; modulate by detail color -mul r0.rgb, r0, v0 ; modulate by vertex color -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh b/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh deleted file mode 100644 index 75ce4b5d..00000000 --- a/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mov r0.rgb, t0 + -mov r0.a, v0.a ; Grab alpha from vertex color - -lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha -mul r0.rgb, r0, v0 ; modulate by vertex color -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1.rgb, c1, t0 ; Self illum * tint -+ mul r1.a, t0.a, 1-t2.a ; Reduce self-illum amount based on 1 - detailalpha - -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap - diff --git a/materialsystem/stdshaders/WorldVertexAlpha.psh b/materialsystem/stdshaders/WorldVertexAlpha.psh deleted file mode 100644 index 67e6a1e3..00000000 --- a/materialsystem/stdshaders/WorldVertexAlpha.psh +++ /dev/null @@ -1,10 +0,0 @@ -ps.1.1 - -tex t0 ; basetexture -tex t1 ; lightmap - -mov r0.a, 1-t1.a -;mov r0.rgb, t0 ; * 2 * (overbrightFactor/2) -;mov_x2 r0.rgb, t0 ; * 2 * (overbrightFactor/2) -mul r0.rgb, t0, t1; -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldVertexAlpha.vsh b/materialsystem/stdshaders/WorldVertexAlpha.vsh deleted file mode 100644 index ae2566a6..00000000 --- a/materialsystem/stdshaders/WorldVertexAlpha.vsh +++ /dev/null @@ -1,37 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -&AllocateRegister( \$worldPos ); - -; garymcthack -dp4 $worldPos.z, $vPos, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$worldPos ); -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -; base texcoords -mov oT0, $vTexCoord0 - -; lightmap texcoords -mov oT1, $vTexCoord1 - -&FreeRegister( \$worldPos ); # garymcthack - diff --git a/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc b/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc deleted file mode 100644 index 7ccc584a..00000000 --- a/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc +++ /dev/null @@ -1,43 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "PASS" "0..1" - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -// CENTROID: TEXCOORD1 - -sampler BaseSampler : register( s0 ); -sampler LightmapSampler: register( s1 ); -sampler LightmapAlphaSampler: register( s2 ); - -struct PS_INPUT -{ - float2 baseCoord : TEXCOORD0; - float2 lightmapCoord : TEXCOORD1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - bool bAlphaPass = PASS ? true : false; - - float4 base = tex2D( BaseSampler, i.baseCoord ); - float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); - float4 alpha = tex2D( LightmapAlphaSampler, i.lightmapCoord ); - - float4 color; - - base.a = dot( base, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); - color = 2.0f * base * lightmap; // The 2x is for an assumed overbright 2 (it's always 2 on dx9) - - if( bAlphaPass ) - { - // Don't care about color, just return pre-multiplied alpha - return FinalOutput( float4( 0.0f, 0.0f, 1.0f, (1.0f - alpha.a) * color.a ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); - } - else - { - return FinalOutput( float4( color.rgb, (1.0f - alpha.a) ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); - } -} - diff --git a/materialsystem/stdshaders/WorldVertexTransition.psh b/materialsystem/stdshaders/WorldVertexTransition.psh deleted file mode 100644 index 76249b3d..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition.psh +++ /dev/null @@ -1,18 +0,0 @@ -; STATIC: "DETAIL" "0..1" -ps.1.1 - -tex t0 ; basetexture -tex t1 ; basetexture2 -tex t2 ; lightmap -#if DETAIL -tex t3 ; detail -#endif - -mov_sat r1.a, v0.a -lrp r0, r1.a, t1, t0 - -mul r0, r0, t2 -#if DETAIL -mul_x2 r0.rgb, r0, t3 -#endif -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldVertexTransition.vsh b/materialsystem/stdshaders/WorldVertexTransition.vsh deleted file mode 100644 index 81e56dbe..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition.vsh +++ /dev/null @@ -1,48 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -&AllocateRegister( \$worldPos ); - -; garymcthack -dp4 $worldPos.z, $vPos, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$worldPos ); -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -; base texcoords -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - -dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 -dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - -; lightmap texcoords -mov oT2, $vTexCoord1 - -; detail -dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 -dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - -; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. -mov oD0, $vColor - -&FreeRegister( \$worldPos ); # garymcthack - diff --git a/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh b/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh deleted file mode 100644 index 6c959f1a..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh +++ /dev/null @@ -1,16 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -mul r0.rgb, t1, t0 ; fold in lightmap (color) -+mov r0.a, v0.a ; fold in lightmap (alpha) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - diff --git a/materialsystem/stdshaders/WorldVertexTransition_Editor.psh b/materialsystem/stdshaders/WorldVertexTransition_Editor.psh deleted file mode 100644 index a8181280..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_Editor.psh +++ /dev/null @@ -1,10 +0,0 @@ -ps.1.1 - -tex t0 ; basetexture -tex t1 ; basetexture2 -tex t2 ; lightmap - -; The editor uses vertex alpha as the blend factor -lrp r0, 1-v0.a, t1, t0 -mul r0, r0, t2 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh b/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh deleted file mode 100644 index db9d0cd6..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh +++ /dev/null @@ -1,23 +0,0 @@ -ps.1.1 - -def c0, 1.0f, 0.0f, 0.0f, 0.0f -def c1, 0.0f, 1.0f, 0.0f, 0.0f -def c2, 0.0f, 0.0f, 1.0f, 0.0f - -tex t0 ; basetexture zy -tex t1 ; basetexture xz -tex t2 ; basetexture xy -tex t3 ; lightmap - -dp3_sat r1, v0, c0 -mul r0, t0, r1 - -dp3_sat r1, v0, c1 -mad r0, t1, r1, r0 - -dp3_sat r1, v0, c2 -mad r0, t2, r1, r0 - -; multiply by lightmap -mul_x2 r0.rgb, r0, t3 -+mov r0.a, v0 ; $vColor diff --git a/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh b/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh deleted file mode 100644 index dd0cc99c..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh +++ /dev/null @@ -1,54 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - -alloc $projPos - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -alloc $worldPos -alloc $worldNormal - -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 - -dp3 $worldNormal.x, $vNormal, $cModel0 -dp3 $worldNormal.y, $vNormal, $cModel1 -dp3 $worldNormal.z, $vNormal, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -free $projPos - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -; base texcoords -alloc $texcoord -mul $texcoord.xyz, $worldPos, $SHADER_SPECIFIC_CONST_0 - -mov oT0.xy, $texcoord.zy; -mov oT1.xy, $texcoord.xz; -mov oT2.xy, $texcoord.xy; - -free $texcoord - -; lightmap texcoords -mov oT3, $vTexCoord1 - -mul oD0.rgb, $worldNormal, $worldNormal - -; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. -mov oD0.a, $vColor - -free $worldPos -free $worldNormal diff --git a/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp b/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp deleted file mode 100644 index 331f8f17..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp +++ /dev/null @@ -1,537 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" -#include "convar.h" - -#include "worldvertextransition.inc" -#include "worldvertextransition_vs14.inc" -#include "worldvertextransition_seamless.inc" -#include "lightmappedgeneric_vs11.inc" -#include "writevertexalphatodestalpha_vs11.inc" -#include "worldvertextransition_dx8_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX8 ) - -ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); - -BEGIN_VS_SHADER( WorldVertexTransition_DX8, - "Help for WorldVertexTransition_DX8" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) - SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $baseTexture" ) - SHADER_PARAM( BASETEXTURETRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$baseTexture texcoord transform" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map for BASETEXTURE" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( BUMPBASETEXTURE2WITHBUMPMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) - SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "0.0", "1.0 == mirror, 0.0 == water" ) - SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) - SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) - SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) - SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) - return "WorldVertexTransition_DX6"; - return 0; - } - - void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) - { - info.m_nBaseTextureVar = BASETEXTURE; - info.m_nBaseTextureFrameVar = FRAME; - info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; - info.m_nBaseTexture2Var = BASETEXTURE2; - info.m_nBaseTexture2FrameVar = FRAME2; - info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM2; - } - - SHADER_INIT_PARAMS() - { - // Initializes FLASHLIGHTTEXTURE + MATERIAL_VAR2_LIGHTING_LIGHTMAP - WorldVertexTransitionEditor_DX8_Vars_t info; - SetupVars( info ); - InitParamsWorldVertexTransitionEditor_DX8( params, info ); - - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) - { - if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) - { - Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); - params[ENVMAP]->SetUndefined(); - } - } - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - { - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - } - - if( !params[ENVMAPTINT]->IsDefined() ) - { - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( !params[SELFILLUMTINT]->IsDefined() ) - { - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( !params[DETAILSCALE]->IsDefined() ) - { - params[DETAILSCALE]->SetFloatValue( 4.0f ); - } - - if( !params[FRESNELREFLECTION]->IsDefined() ) - { - params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); - } - - if( !params[ENVMAPMASKFRAME]->IsDefined() ) - { - params[ENVMAPMASKFRAME]->SetIntValue( 0 ); - } - - if( !params[ENVMAPFRAME]->IsDefined() ) - { - params[ENVMAPFRAME]->SetIntValue( 0 ); - } - - if( !params[BUMPFRAME]->IsDefined() ) - { - params[BUMPFRAME]->SetIntValue( 0 ); - } - - if( !params[ENVMAPCONTRAST]->IsDefined() ) - { - params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); - } - - if( !params[ENVMAPSATURATION]->IsDefined() ) - { - params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); - } - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); - } - - if( !params[BUMPBASETEXTURE2WITHBUMPMAP]->IsDefined() ) - { - params[BUMPBASETEXTURE2WITHBUMPMAP]->SetIntValue( 0 ); - } - - if( !params[DETAILSCALE]->IsDefined() ) - { - params[DETAILSCALE]->SetFloatValue( 4.0f ); - } - - if( !params[DETAILFRAME]->IsDefined() ) - { - params[DETAILFRAME]->SetIntValue( 0 ); - } - - if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) - { - // seamless scale is going to be used, so kill some other features. . might implement with these features later. - params[DETAIL]->SetUndefined(); - params[BUMPMAP]->SetUndefined(); - params[ENVMAP]->SetUndefined(); - } - - if ( !params[SEAMLESS_SCALE]->IsDefined() ) - { - // zero means don't do seamless mapping. - params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); - } - - if( params[SSBUMP]->IsDefined() && params[SSBUMP]->GetIntValue() != 0 ) - { - // turn of normal mapping since we have ssbump defined, which - // means that we didn't make a dx8 fallback for this material. - params[BUMPMAP]->SetUndefined(); - } - } - SHADER_INIT - { - // Loads BASETEXTURE, BASETEXTURE2 - WorldVertexTransitionEditor_DX8_Vars_t info; - SetupVars( info ); - InitWorldVertexTransitionEditor_DX8( this, params, info ); - - // FLASHLIGHTFIXME - if ( params[FLASHLIGHTTEXTURE]->IsDefined() ) - { - LoadTexture( FLASHLIGHTTEXTURE ); - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - if ( g_pHardwareConfig->SupportsPixelShaders_1_4() && params[BLENDMODULATETEXTURE]->IsDefined() ) - { - LoadTexture( BLENDMODULATETEXTURE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - if( params[ENVMAP]->IsDefined() && !params[BUMPMAP]->IsDefined() ) - { - Warning( "must have $bumpmap if you have $envmap for worldvertextransition\n" ); - params[ENVMAP]->SetUndefined(); - params[BUMPMAP]->SetUndefined(); - } - if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); - LoadBumpMap( BUMPMAP ); - } - if( params[ENVMAP]->IsDefined() ) - { - if( !IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) - { - LoadCubeMap( ENVMAP ); - } - else - { - Warning( "$envmapsphere not supported by worldvertextransition\n" ); - params[ENVMAP]->SetUndefined(); - } - } - } - - void WriteVertexAlphaToDestAlpha( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - if( pShaderShadow ) - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableColorWrites( false ); - - writevertexalphatodestalpha_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "writevertexalphatodestalpha_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "writevertexalphatodestalpha_ps11" ); - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); - } - else - { - writevertexalphatodestalpha_vs11_Dynamic_Index vshIndex; - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - void DrawFlashlightPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int passID ) - { - bool bBump = ( passID == 0 ) && ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture(); - DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, true, passID, BASETEXTURE2, FRAME2 ); - } - - bool ShouldUseBumpmapping( IMaterialVar **params ) - { - return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); - } - - void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - WriteVertexAlphaToDestAlpha( params, pShaderAPI, pShaderShadow ); - DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 0 ); - DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 1 ); - } - - SHADER_DRAW - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - bool bSupports14 = g_pHardwareConfig->SupportsPixelShaders_1_4(); - - // FLASHLIGHTFIXME: need to make these the same. - bool hasFlashlight = UsingFlashlight( params ); - if( hasFlashlight ) - { - DrawFlashlight( params, pShaderAPI, pShaderShadow ); - } - else if ( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) - { - // This is the seamless_scale version, which doesn't use $detail or $bumpmap - SHADOW_STATE - { - // three copies of the base texture for seamless blending - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // lightmap - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - worldvertextransition_seamless_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); - - int pshIndex = 0; - pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - // Texture 0..2 - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); - } - - // Texture 3 = lightmap - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); - - EnablePixelShaderOverbright( 0, true, true ); - - float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); - float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); - - worldvertextransition_seamless_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - SHADOW_STATE - { - // inherit state from previous pass - - EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - DYNAMIC_STATE - { - if( !bLightingOnly ) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); - BindTexture( SHADER_SAMPLER2, BASETEXTURE2, FRAME2 ); - } - } - Draw(); - } - else if( !params[BUMPMAP]->IsTexture() || !g_pConfig->UseBumpmapping() ) - { - bool bDetail = params[DETAIL]->IsTexture(); - bool bBlendModulate = params[BLENDMODULATETEXTURE]->IsTexture(); - SHADOW_STATE - { - // This is the dx8, non-worldcraft version, non-bumped version - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - if( bDetail ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - } - if ( bSupports14 && bBlendModulate ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - } - - int fmt = VERTEX_POSITION | VERTEX_COLOR; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - if ( !bSupports14 ) - { - worldvertextransition_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); - - int pshIndex = bDetail ? 1 : 0; - pShaderShadow->SetPixelShader( "WorldVertexTransition", pshIndex ); - } - else - { - worldvertextransition_vs14_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexTransition_vs14", vshIndex.GetIndex() ); - - int pshIndex = bDetail ? 1 : 0; - pshIndex += bBlendModulate ? 2 : 0; - pShaderShadow->SetPixelShader( "WorldVertexTransition_ps14", pshIndex ); - } - - FogToFogColor(); - } - - DYNAMIC_STATE - { - // Texture 1 - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); - } - if( bDetail ) - { - BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); - } - if ( bSupports14 && bBlendModulate ) - { - BindTexture( SHADER_SAMPLER4, BLENDMODULATETEXTURE ); - } - - // always set the transform for detail textures since I'm assuming that you'll - // always have a detailscale. - // go ahead and set this even if we don't have a detail texture so the vertex shader doesn't - // barf chunks with unitialized data. - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); - - if ( bSupports14 ) - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BLENDMASKTRANSFORM ); - } - - // Texture 3 = lightmap - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); - - EnablePixelShaderOverbright( 0, true, true ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM2 ); - if ( !bSupports14 ) - { - worldvertextransition_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - worldvertextransition_vs14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - Draw(); - } - else - { - if( params[BUMPBASETEXTURE2WITHBUMPMAP]->GetIntValue() ) - { - DrawWorldBumpedUsingVertexShader( BASETEXTURE, BASETEXTURETRANSFORM, - BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, - ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, - FRESNELREFLECTION, true, BASETEXTURE2, BASETEXTURETRANSFORM2, FRAME2, false ); - } - else - { - // draw the base texture with everything else you normally would for - // bumped world materials - DrawWorldBumpedUsingVertexShader( - BASETEXTURE, BASETEXTURETRANSFORM, - BUMPMAP, BUMPFRAME, BUMPTRANSFORM, - ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, ENVMAPFRAME, ENVMAPTINT, - COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, - FRESNELREFLECTION, - false, -1, -1, -1, false ); - - // blend basetexture 2 on top of everything using lightmap alpha. - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - lightmappedgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( false ); - vshIndex.SetENVMAP( false ); - vshIndex.SetENVMAPCAMERASPACE( false ); - vshIndex.SetENVMAPSPHERE( false ); - vshIndex.SetVERTEXCOLOR( true ); - pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WorldVertexTransition_BlendBase2" ); - FogToFogColor(); - } - DYNAMIC_STATE - { - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); - } - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - float half[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; - pShaderAPI->SetPixelShaderConstant( 4, half ); - EnablePixelShaderOverbright( 0, true, true ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM2 ); - - lightmappedgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/WorldVertexTransition_ps14.psh b/materialsystem/stdshaders/WorldVertexTransition_ps14.psh deleted file mode 100644 index 3ddfa02c..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_ps14.psh +++ /dev/null @@ -1,32 +0,0 @@ -; STATIC: "DETAIL" "0..1" -; STATIC: "BLENDMODULATETEXTURE" "0..1" -ps.1.4 - -def c1, 3.0, -2.0, 0.5, 0.5 - -texld r0, t0 -texld r1, t1 -texld r2, t2 -#if DETAIL -texld r3, t3 ; detail -#endif -#if BLENDMODULATETEXTURE -texld r4, t4 ; detail -#endif - -#if BLEND_MODULATETEXTURE -sub r5.a, v0.a, r4.g -add_sat r5.a, r5.a, c1.a -mad r6.a, c1.g, r5.a, c1.r -mul r6.a, r6.a, r5.a -mul r5.a, r6.a, r5.a -#else -mov_sat r5.a, v0.a -#endif -lrp r0, r5.a, r1, r0 - -mul r0, r0, r2 -#if DETAIL -mul_x2 r0.rgb, r0, r3 -#endif -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc b/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc deleted file mode 100644 index f27e870d..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc +++ /dev/null @@ -1,47 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "MACROS" "0..1" - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - - -sampler BaseSampler : register( s0 ); -// NOTE: LightmapSampler is at the same place as the lightmap sampler in lightmappedgeneric so that we have -// generally the same texture state here. -// CENTROID: TEXCOORD1 -sampler LightmapSampler: register( s1 ); -sampler BaseSampler2: register( s2 ); -sampler LightmapAlphaSampler: register( s3 ); -sampler MacrosSampler: register( s4 ); - -struct PS_INPUT -{ - float2 baseCoord : TEXCOORD0; - float2 baseCoord2 : TEXCOORD1; - float2 lightmapCoord : TEXCOORD2; - float2 macrosCoord : TEXCOORD3; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - bool bMacros = MACROS ? true : false; - - float4 base = tex2D( BaseSampler, i.baseCoord ); - float4 base2 = tex2D( BaseSampler2, i.baseCoord2 ); - - float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); - float blendFactor = lightmap.a; - - float4 color = 2.0f * lightmap * lerp( base2, base, blendFactor ); - if( bMacros ) - { - float4 macros = tex2D( MacrosSampler, i.macrosCoord ); - - // Not sure what to do with macro alpha - color.rgb *= 2.0f * lerp( macros.a, macros.b, blendFactor ); - } - - return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} - diff --git a/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh b/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh deleted file mode 100644 index eecc1c89..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh +++ /dev/null @@ -1,52 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -&AllocateRegister( \$worldPos ); - -; garymcthack -dp4 $worldPos.z, $vPos, $cModel2 - -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$worldPos ); -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -; base texcoords -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - -dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 -dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - -; lightmap texcoords -mov oT2, $vTexCoord1 - -; detail -dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 -dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - -; mask -dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 -dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 - -; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. -mov oD0, $vColor - -&FreeRegister( \$worldPos ); # garymcthack - diff --git a/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc b/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc deleted file mode 100644 index 5f18ca81..00000000 --- a/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc +++ /dev/null @@ -1,64 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 ); -const float4 cMacrosTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vColor : COLOR0; - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 baseCoord : TEXCOORD0; - float2 baseCoord2 : TEXCOORD1; - float2 lightmapCoord : TEXCOORD2; - float2 macrosCoord : TEXCOORD3; - float4 color : COLOR0; - float4 fogFactorW : COLOR1; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldNormal, worldPos; - float2 texCoord; - worldPos = mul( v.vPos, cModel[0] ); - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - o.color = v.vColor; - - o.baseCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - - o.baseCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); - o.baseCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); - - o.lightmapCoord = v.vTexCoord1; - - o.macrosCoord.x = dot( v.vTexCoord0, cMacrosTexCoordTransform[0] ); - o.macrosCoord.y = dot( v.vTexCoord0, cMacrosTexCoordTransform[1] ); - - return o; -} - - diff --git a/materialsystem/stdshaders/_buildallshaders.bat b/materialsystem/stdshaders/_buildallshaders.bat deleted file mode 100644 index 2ff8eb38..00000000 --- a/materialsystem/stdshaders/_buildallshaders.bat +++ /dev/null @@ -1,72 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -:start -set TTEXE=..\..\devtools\bin\timeprecise.exe -if not exist %TTEXE% goto no_ttexe -goto no_ttexe_end - -:no_ttexe -set TTEXE=time /t -:no_ttexe_end - -rem =================================== -rem ====== LAUNCH CONFIGURATIONS ====== - -set "GAMEDIR=%cd%\..\..\..\game\VANCE" - -@REM this will vary for people here, maybe use the appid finder i have in quiver in this -@REM Totterynine : oh god -set "ENGINEDIR=E:\SourceStuff\vancegame\vancegame\" - -set "SOURCEDIR=..\.." -set "BUILD_SHADER=call _buildshaders.bat" - -@REM dynamic shaders only builds the required files (inc) to build stdshader_*.dll -set dynamic_shaders=0 - -rem ==== LAUNCH CONFIGURATIONS END ==== -rem =================================== - -echo ============================================================================== -echo. -echo Building All Shaders -echo. - -%TTEXE% -cur-Q -set tt_all_start=%ERRORLEVEL% -set tt_all_chkpt=%tt_start% - -REM --------------------- -REM BUILD SHADERS -REM --------------------- -echo -------------------------------------------------------------------------------------------- -%BUILD_SHADER% _shaderlist_dx9_20b -game %GAMEDIR% -source %SOURCEDIR% %dynamic_shaders% -echo -------------------------------------------------------------------------------------------- -%BUILD_SHADER% _shaderlist_dx9_30 -game %GAMEDIR% -source %SOURCEDIR% %dynamic_shaders% -dx9_30 -force30 -echo -------------------------------------------------------------------------------------------- -echo. - -REM --------------------- -REM END -REM --------------------- -:end - -rem echo. -if not "%dynamic_shaders%" == "1" ( - echo Finished Building All Shaders %* -) else ( - echo Finished Building All Shaders - Dynamic %* -) - -%TTEXE% -diff %tt_all_start% -cur - -echo. -echo ============================================================================== -echo. -%TTEXE% -diff %tt_all_start% -cur -echo. -echo Press any key to rebuild game shader project and exit . . . -pause >nul - -..\..\devtools\bin\vpc.exe /f /vance +shaders \ No newline at end of file diff --git a/materialsystem/stdshaders/_buildshaders.bat b/materialsystem/stdshaders/_buildshaders.bat deleted file mode 100644 index 7dfb431f..00000000 --- a/materialsystem/stdshaders/_buildshaders.bat +++ /dev/null @@ -1,255 +0,0 @@ -@echo off - -@REM == Setup path to nmake.exe == -if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" ( - for /f "usebackq tokens=1* delims=: " %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop`) do ( - if /i "%%i"=="installationPath" ( - set VSDIR=%%j - call "!VSDIR!\Common7\Tools\VsDevCmd.bat" >nul - goto :start - ) - ) -) else if exist "%VS140COMNTOOLS%vsvars32.bat" ( - call "%VS140COMNTOOLS%vsvars32.bat" - echo Using Visual Studio 2015 nmake - -) else if exist "%VS120COMNTOOLS%vsvars32.bat" ( - call "%VS120COMNTOOLS%vsvars32.bat" - echo Using Visual Studio 2013 nmake - -) else if exist "%VS100COMNTOOLS%vsvars32.bat" ( - call "%VS100COMNTOOLS%vsvars32.bat" - echo Using Visual Studio 2010 nmake - -) else ( - echo. - echo Install Either Visual Studio Version 2010 through 2019 - pause - exit -) - -:start -set TTEXE=..\..\devtools\bin\timeprecise.exe -if not exist %TTEXE% goto no_ttexe -goto no_ttexe_end - -:no_ttexe -set TTEXE=time /t -:no_ttexe_end - -@REM echo ==================== buildshaders %* ================== -%TTEXE% -cur-Q -set tt_start=%ERRORLEVEL% -set tt_chkpt=%tt_start% - - -@REM -------------------------------------------------------- -@REM usage: buildshaders -@REM -------------------------------------------------------- - -setlocal -set arg_filename=%1 -set shadercompilecommand=ShaderCompile.exe -set SrcDirBase=..\.. -set shaderDir=shaders - -if "%1" == "" goto usage -set inputbase=%1 - -@REM TODO: replace this slow af dx_proxy with one from quiver - -set DIRECTX_SDK_VER=pc09.00 -set DIRECTX_SDK_BIN_DIR=dx9sdk\utilities - -if /i "%7" == "-dx9_30" goto dx_sdk_dx9_30 -goto dx_sdk_end -:dx_sdk_dx9_30 - set DIRECTX_SDK_VER=pc09.30 - set DIRECTX_SDK_BIN_DIR=dx10sdk\Utilities\dx9_30 - goto dx_sdk_end -:dx_sdk_end - -if /i "%8" == "-force30" goto set_force30_arg -goto set_force_end -:set_force30_arg - set DIRECTX_FORCE_MODEL=30 - goto set_force_end -:set_force_end - -if /i "%2" == "-game" goto set_mod_args -if /i "%6" == "1" set dynamic_shaders=1 -goto build_shaders - -@REM -------------------------------------------------------- -@REM USAGE -@REM -------------------------------------------------------- -:usage -echo. -echo "usage: buildshaders [-dx10 or -game] [gameDir if -game was specified] [-source sourceDir]" -echo " gameDir is where gameinfo.txt is (where it will store the compiled shaders)." -echo " sourceDir is where the source code is (where it will find scripts and compilers)." -echo "ex : buildshaders myshaders" -echo "ex : buildshaders myshaders -game c:\steam\steamapps\sourcemods\mymod -source c:\mymod\src" -goto :end - -@REM -------------------------------------------------------- -@REM MOD ARGS - look for -game or the vproject environment variable -@REM -------------------------------------------------------- -:set_mod_args - -if not exist "%ENGINEDIR%\bin\shadercompile.exe" goto NoShaderCompile - -if /i "%4" NEQ "-source" goto NoSourceDirSpecified -set "SrcDirBase=%~5" - -REM ** use the -game parameter to tell us where to put the files -set targetdir=%~3\shaders -set SDKArgs=-nompi -nop4 -game "%~3" - -if not exist "%~3\gameinfo.txt" goto InvalidGameDirectory -goto build_shaders - -@REM -------------------------------------------------------- -@REM ERRORS -@REM -------------------------------------------------------- -:InvalidGameDirectory -echo - -echo Error: "%~3" is not a valid game directory. -echo (The -game directory must have a gameinfo.txt file) -echo - -goto end - -:NoSourceDirSpecified -echo ERROR: If you specify -game on the command line, you must specify -source. -goto usage -goto end - -:NoShaderCompile -echo - -echo - ERROR: shadercompile.exe doesn't exist in %ENGINEDIR%\bin -echo - -goto end - -@REM -------------------------------------------------------- -@REM BUILD SHADERS -@REM -------------------------------------------------------- -:build_shaders - -@REM echo ------------------------------------------------------------ -@REM echo %inputbase% -@REM echo ------------------------------------------------------------ -@REM make sure that target dirs exist -@REM files will be built in these targets and copied to their final destination -if not exist %shaderDir% mkdir %shaderDir% -if not exist %shaderDir%\fxc mkdir %shaderDir%\fxc - -@REM Nuke some files that we will add to later. -if exist filelist.txt del /f /q filelist.txt -if exist filestocopy.txt del /f /q filestocopy.txt -if exist filelistgen.txt del /f /q filelistgen.txt -if exist inclist.txt del /f /q inclist.txt -if exist vcslist.txt del /f /q vcslist.txt -if exist uniquefilestocopy.txt del /f /q uniquefilestocopy.txt -if exist makefile.%inputbase% del /f /q makefile.%inputbase% - -@REM -------------------------------------------------------- -@REM Generate a makefile for the shader project -@REM creates vcslist.txt and and inclist.txt -@REM -------------------------------------------------------- -perl "%SrcDirBase%\devtools\bin\updateshaders.pl" -source "%SrcDirBase%" %inputbase% - -@REM -------------------------------------------------------- -@REM Run the makefile, generating minimal work/build list for fxc files, go ahead and compile vsh and psh files. -@REM -------------------------------------------------------- -@REM nmake /S /C -f makefile.%inputbase% clean > clean.txt 2>&1 -@REM echo Building inc files, asm vcs files, and VMPI worklist for %inputbase%... -echo Creating makefile for %inputbase%... -nmake /S /C -f ./makefile.%inputbase% - -@REM -------------------------------------------------------- -@REM Copy the inc files to their target -@REM -------------------------------------------------------- -if exist "inclist.txt" ( - echo Publishing shader inc files to target... - perl %SrcDirBase%\devtools\bin\copyshaderincfiles.pl inclist.txt -) - -@REM -------------------------------------------------------- -@REM Add the executables to the worklist. -@REM -------------------------------------------------------- - -if /i "%DIRECTX_SDK_VER%" == "pc09.00" ( - @REM echo "Copy extra files for dx 9 std -) -if /i "%DIRECTX_SDK_VER%" == "pc09.30" ( - echo %SrcDirBase%\devtools\bin\d3dx9_33.dll >> filestocopy.txt -) -if /i "%DIRECTX_SDK_VER%" == "pc10.00" ( - echo %SrcDirBase%\devtools\bin\d3dx10_33.dll >> filestocopy.txt -) - -echo %SrcDirBase%\%DIRECTX_SDK_BIN_DIR%\dx_proxy.dll >> filestocopy.txt - -echo %ENGINEDIR%\bin\shadercompile.exe >> filestocopy.txt -echo %ENGINEDIR%\bin\shadercompile_dll.dll >> filestocopy.txt -echo %ENGINEDIR%\bin\vstdlib.dll >> filestocopy.txt -echo %ENGINEDIR%\bin\tier0.dll >> filestocopy.txt - -@REM -------------------------------------------------------- -@REM Cull duplicate entries in work/build list -@REM -------------------------------------------------------- -if exist filestocopy.txt type filestocopy.txt | perl "%SrcDirBase%\devtools\bin\uniqifylist.pl" > uniquefilestocopy.txt -if exist filelistgen.txt if not "%dynamic_shaders%" == "1" ( - echo Generating action list... - copy filelistgen.txt filelist.txt >nul -) - -@REM -------------------------------------------------------- -@REM Execute distributed process on work/build list -@REM -------------------------------------------------------- -set shader_path_cd=%cd% -if exist "filelist.txt" if exist "uniquefilestocopy.txt" if not "%dynamic_shaders%" == "1" ( - @REM checking if shader compile is running - call _kill_shadercompiler.bat - - echo Building shaders... - cd /D "%ENGINEDIR%\bin" - - @REM %shadercompilecommand% -mpi_MaxWorkers %shadercompileworkers% -shaderpath "%shader_path_cd:/=\%" -allowdebug - @REM -verbose -subprocess X - echo. - @REM use all threads on your cpu - %shadercompilecommand% %SDKArgs% -threads %NUMBER_OF_PROCESSORS% -shaderpath "%shader_path_cd:/=\%" -verbose -verbose2 -verbose_preprocessor -verbose_errors - - echo. - cd /D %shader_path_cd% -) - -@REM delete the temporary files -if exist filelist.txt del /f /q filelist.txt -if exist filestocopy.txt del /f /q filestocopy.txt -if exist filelistgen.txt del /f /q filelistgen.txt -if exist inclist.txt del /f /q inclist.txt -if exist vcslist.txt del /f /q vcslist.txt -if exist uniquefilestocopy.txt del /f /q uniquefilestocopy.txt -if exist makefile.%inputbase% del /f /q makefile.%inputbase% - -@REM -------------------------------------------------------- -@REM PC Shader copy -@REM Publish the generated files to the output dir using XCOPY -@REM This batch file may have been invoked standalone or slaved (master does final smart mirror copy) -@REM -------------------------------------------------------- -:DoXCopy -if not "%dynamic_shaders%" == "1" ( - if not exist "%targetdir%" md "%targetdir%" - xcopy "%cd%\shaders" "%targetdir%" /q /e /y -) -goto end - -@REM -------------------------------------------------------- -@REM END -@REM -------------------------------------------------------- -:end - - -%TTEXE% -diff %tt_start% \ No newline at end of file diff --git a/materialsystem/stdshaders/_clean.bat b/materialsystem/stdshaders/_clean.bat deleted file mode 100644 index a4ec0749..00000000 --- a/materialsystem/stdshaders/_clean.bat +++ /dev/null @@ -1,28 +0,0 @@ -@echo off -setlocal - -if /i "%1" == "-game" goto CleanGameDir -goto CleanINCFiles - -:CleanGameDir -set __GameDir=%~2 -if not exist "%__GameDir%\gameinfo.txt" goto MissingGameInfo -if exist "%__GameDir%\shaders" rd /s /q "%2\shaders" -goto CleanINCFiles - -:CleanINCFiles -if exist fxctmp9 rd /s /q fxctmp9 -if exist fxctmp9_tmp rd /s /q fxctmp9_tmp -goto CleanOtherStuff - -:CleanOtherStuff -@REM if exist debug_dx9 rd /s /q debug_dx9 -if exist shaders rd /s /q shaders -goto end - -:MissingGameInfo -echo Invalid -game parameter specified (no "%__GameDir%\gameinfo.txt" exists). -goto end - -:end -pause \ No newline at end of file diff --git a/materialsystem/stdshaders/_kill_shadercompiler.bat b/materialsystem/stdshaders/_kill_shadercompiler.bat deleted file mode 100644 index a4bce87a..00000000 --- a/materialsystem/stdshaders/_kill_shadercompiler.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off - -tasklist /FI "IMAGENAME eq shadercompile.exe" 2>NUL | find /I /N "shadercompile.exe">NUL - -if "%ERRORLEVEL%"=="0" ( - echo Shadercompile is running still, killing - taskkill /f /im shadercompile.exe >nul -) \ No newline at end of file diff --git a/materialsystem/stdshaders/_shaderlist_dx9_20b.txt b/materialsystem/stdshaders/_shaderlist_dx9_20b.txt deleted file mode 100644 index 0d8b479a..00000000 --- a/materialsystem/stdshaders/_shaderlist_dx9_20b.txt +++ /dev/null @@ -1,26 +0,0 @@ -// -// Standard shaders collection -// -// These shaders are compiled as the following shader models: -// _ps20.vcs -// _ps20b.vcs -// _vs20.vcs -// - -//lightmappedgeneric_flashlight_vs11.fxc -//lightmappedgeneric_flashlight_vs20.fxc - -//flashlight_ps2x.fxc - -//lightmappedgeneric_ps2x.fxc -//lightmappedgeneric_vs20.fxc - -//vertexlit_and_unlit_generic_ps2x.fxc -//VertexLit_and_unlit_Generic_vs20.fxc -//vertexlit_and_unlit_generic_bump_ps2x.fxc -//VertexLit_and_unlit_Generic_bump_vs20.fxc - -//SDK_screenspaceeffect_vs20.fxc - -depthwrite_ps2x.fxc -depthwrite_vs20.fxc \ No newline at end of file diff --git a/materialsystem/stdshaders/_shaderlist_dx9_30.txt b/materialsystem/stdshaders/_shaderlist_dx9_30.txt deleted file mode 100644 index b41e3cfb..00000000 --- a/materialsystem/stdshaders/_shaderlist_dx9_30.txt +++ /dev/null @@ -1,106 +0,0 @@ -// -// vs 3.0 ps 3.0 shaders collection -// -// These shaders are forced to compile as shader model 3.0 -// using the new compiler. -// _ps30.vcs -// _vs30.vcs -// - -// There are no examples of such shaders in the SDK, but add yours here. - -unsharp_blur_ps2x.fxc -unsharp_blur_vs20.fxc - -unsharp_ps2x.fxc -unsharp_vs20.fxc - - -fxaa_ps30.fxc -fxaa_vs30.fxc - -luma_ps30.fxc - -lightmappedgeneric_ps30.fxc -lightmappedgeneric_vs30.fxc - -//lightmappedgeneric_decal_vs20.fxc -//lightmappedgeneric_decal_ps2x.fxc - -flashlight_ps2x.fxc -lightmappedgeneric_flashlight_vs20.fxc - -screenspace_simple_vs30.fxc -SDK_screenspaceeffect_vs20.fxc - -gaussianx_ps2x.fxc -gaussiany_ps2x.fxc -gaussian_depthaware_ps30.fxc -gaussian_depthaware_roughness_ps30.fxc - -vance_bloom_combine_ps30.fxc -Vance_Tonemap_ps30.fxc - -chromatic_ps2x.fxc -chromatic_vs20.fxc - -screenwater_ps2x.fxc -screenwater_vs20.fxc - -skydome_ps30.fxc -skydome_vs30.fxc - -ssgi_ps30.fxc -ssgi_combine_ps30.fxc - -ssr_ps30.fxc - -//bilateral_filter_ps30.fxc - -vertexlit_and_unlit_generic_ps30.fxc -vertexLit_and_unlit_Generic_vs30.fxc -vertexlit_and_unlit_generic_bump_ps30.fxc -VertexLit_and_unlit_Generic_bump_vs30.fxc - -VertexlitPBR_ps30.fxc -vertexlitPBR_vs30.fxc - -lightmappedPBR_ps30.fxc -lightmappedPBR_vs30.fxc - -//example_model_ps20b.fxc -//example_model_vs20.fxc - -lightpass_ps30.fxc -lightpass_vs30.fxc -//deferred_pointlights_ps30.fxc -//deferred_spotlight_ps30.fxc -//deferred_spotlight_shadow_ps30.fxc -//deferred_CSM_ps30.fxc -//deferred_volumetricfog_ps30.fxc -//deferred_sky_ps30.fxc -//deferred_composite_ps30.fxc -//deferred_composite_vs30.fxc - -//basicsample_ps30.fxc -//bicubicsample_ps30.fxc -//bilinearsample_ps30.fxc -normalmapreconstruct_ps30.fxc -light_volumetrics_ps20b.fxc -light_volumetrics_vs20.fxc - -vance_scope_ps30.fxc -vance_scope_vs30.fxc -//vance_liquid_ps30.fxc -//vance_liquid_vs30.fxc -lpreview1_ps2x.fxc - -//writez_vs20.fxc -//white_ps2x.fxc -depthwrite_ps2x.fxc -//depthwrite_vs20.fxc - -passthru_vs20.fxc - -light_mesh_ps30.fxc -light_mesh_vs30.fxc \ No newline at end of file diff --git a/materialsystem/stdshaders/accumbuff5sample.cpp b/materialsystem/stdshaders/accumbuff5sample.cpp deleted file mode 100644 index d8b2f136..00000000 --- a/materialsystem/stdshaders/accumbuff5sample.cpp +++ /dev/null @@ -1,110 +0,0 @@ -//========= Copyright 1996-2005, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "BaseVSShader.h" -#include "common_hlsl_cpp_consts.h" -#include "screenspaceeffect_vs20.inc" -#include "accumbuff5sample_ps20.inc" -#include "accumbuff5sample_ps20b.inc" -#include "convar.h" - -BEGIN_VS_SHADER_FLAGS( accumbuff5sample, "Help for AccumBuff5Sample", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - - // Four textures to sample - SHADER_PARAM( TEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE4, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - - // Corresponding weights for the four input textures - SHADER_PARAM( WEIGHTS, SHADER_PARAM_TYPE_VEC4, "", "Weight for Samples" ) - - END_SHADER_PARAMS - - SHADER_INIT - { - LoadTexture( TEXTURE0 ); - LoadTexture( TEXTURE1 ); - LoadTexture( TEXTURE2 ); - LoadTexture( TEXTURE3 ); - LoadTexture( TEXTURE4 ); - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if (!g_pHardwareConfig->SupportsVertexAndPixelShaders()) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - pShaderShadow->EnableAlphaWrites( false ); - pShaderShadow->EnableBlending( false ); - pShaderShadow->EnableCulling( false ); -// pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( accumbuff5sample_ps20b ); - SET_STATIC_PIXEL_SHADER( accumbuff5sample_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( accumbuff5sample_ps20 ); - SET_STATIC_PIXEL_SHADER( accumbuff5sample_ps20 ); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, TEXTURE0, -1 ); - BindTexture( SHADER_SAMPLER1, TEXTURE1, -1 ); - BindTexture( SHADER_SAMPLER2, TEXTURE2, -1 ); - BindTexture( SHADER_SAMPLER3, TEXTURE3, -1 ); - BindTexture( SHADER_SAMPLER4, TEXTURE4, -1 ); - - SetPixelShaderConstant( 0, WEIGHTS ); - - DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( accumbuff5sample_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( accumbuff5sample_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( accumbuff5sample_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( accumbuff5sample_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/accumbuff5sample_ps2x.fxc b/materialsystem/stdshaders/accumbuff5sample_ps2x.fxc deleted file mode 100644 index 5fa2c264..00000000 --- a/materialsystem/stdshaders/accumbuff5sample_ps2x.fxc +++ /dev/null @@ -1,34 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -sampler TexSampler0 : register( s0 ); -sampler TexSampler1 : register( s1 ); -sampler TexSampler2 : register( s2 ); -sampler TexSampler3 : register( s3 ); -sampler TexSampler4 : register( s4 ); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - -const float4 weights : register( c0 ); - -float4 main( PS_INPUT i ) : COLOR -{ - // Just sample the four input textures - float4 sample0 = tex2D( TexSampler0, i.texCoord ); - float4 sample1 = tex2D( TexSampler1, i.texCoord ); - float4 sample2 = tex2D( TexSampler2, i.texCoord ); - float4 sample3 = tex2D( TexSampler3, i.texCoord ); - float4 sample4 = tex2D( TexSampler4, i.texCoord ); - - // Compute weighted average and return - return FinalOutput( weights.x * sample0 + - weights.x * sample1 + - weights.x * sample2 + - weights.x * sample3 + - weights.y * sample4, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/basevsshader.cpp b/materialsystem/stdshaders/basevsshader.cpp new file mode 100644 index 00000000..5b063dc2 --- /dev/null +++ b/materialsystem/stdshaders/basevsshader.cpp @@ -0,0 +1,897 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// + +#include "basevsshader.h" +#include "mathlib/vmatrix.h" +#include "mathlib/bumpvects.h" +#include "cpp_shader_constant_register_map.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +// NOTE: This is externed in BaseVSShader.h so it needs to be here +ConVar r_flashlightbrightness( "r_flashlightbrightness", "0.25", FCVAR_CHEAT ); + +#ifdef MAPBASE +// This constant should change with each Mapbase update +ConVar mapbase_version_shaders( "mapbase_version_shaders", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's game_shader_dx9.dll" ); + +ConVar mat_specular_disable_on_missing( "mat_specular_disable_on_missing", "1", FCVAR_ARCHIVE, "Disables specular reflections on a material when the envmap cannot be found." ); +#endif + +// These functions are to be called from the shaders. + +//----------------------------------------------------------------------------- +// Pixel and vertex shader constants.... +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; + Assert( pPixelVar2 ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 3 ); + } + else + { + val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); + } + + val[3] = pPixelVar2->GetFloatValue(); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; + Assert( pPixelVar2 ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 3 ); + } + else + { + val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); + } + + val[3] = pPixelVar2->GetFloatValue(); + val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); + val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); + val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); + + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + val[3]=fWValue; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + + val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); + val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); + val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); + + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) +{ + int i; + for( i = 0; i < numConst; i++ ) + { + float vec[4]; + vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); + vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); + vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); + vec[3] = pVec[i*4+3]; + + s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce ); + } +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) +{ + int i; + for( i = 0; i < numConst; i++ ) + { + float vec[4]; + vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); + vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); + vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); + + vec[3] = pVec[i*4+3]; + + s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce ); + } +} + +// GR - special version with fix for const/lerp issue +void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 4 ); + val[0] = val[0] * 0.992f + 0.0078f; + val[1] = val[1] * 0.992f + 0.0078f; + val[2] = val[2] * 0.992f + 0.0078f; + val[3] = val[3] * 0.992f + 0.0078f; + } + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pVertexVar = s_ppParams[constantVar]; + Assert( pVertexVar ); + + float val[4]; + if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pVertexVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue(); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, val ); +} + +//----------------------------------------------------------------------------- +// Sets normalized light color for pixel shaders. +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderLightColors( int pixelReg ) +{ + int i; + int maxLights = s_pShaderAPI->GetMaxLights(); + for( i = 0; i < maxLights; i++ ) + { + const LightDesc_t & lightDesc = s_pShaderAPI->GetLight( i ); + if( lightDesc.m_Type != MATERIAL_LIGHT_DISABLE ) + { + Vector color( lightDesc.m_Color[0], lightDesc.m_Color[1], lightDesc.m_Color[2] ); + VectorNormalize( color ); + float val[4] = { color[0], color[1], color[2], 1.0f }; + s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, val, 1 ); + } + else + { + float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, zero, 1 ); + } + } +} + + +//----------------------------------------------------------------------------- +// Sets vertex shader texture transforms +//----------------------------------------------------------------------------- +void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar ) +{ + float offset[2] = {0, 0}; + + IMaterialVar* pTranslationVar = s_ppParams[translationVar]; + if (pTranslationVar) + { + if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pTranslationVar->GetVecValue( offset, 2 ); + else + offset[0] = offset[1] = pTranslationVar->GetFloatValue(); + } + + Vector4D translation[2]; + translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); + translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar ) +{ + float scale[2] = {1, 1}; + + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale, 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + Vector4D scaleMatrix[2]; + scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); + scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + // Apply the scaling + transformation[0][0] *= scale[0]; + transformation[0][1] *= scale[1]; + transformation[1][0] *= scale[0]; + transformation[1][1] *= scale[1]; + transformation[0][3] *= scale[0]; + transformation[1][3] *= scale[1]; + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); +} + + +//----------------------------------------------------------------------------- +// Sets pixel shader texture transforms +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar ) +{ + float offset[2] = {0, 0}; + + IMaterialVar* pTranslationVar = s_ppParams[translationVar]; + if (pTranslationVar) + { + if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pTranslationVar->GetVecValue( offset, 2 ); + else + offset[0] = offset[1] = pTranslationVar->GetFloatValue(); + } + + Vector4D translation[2]; + translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); + translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar ) +{ + float scale[2] = {1, 1}; + + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale, 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + Vector4D scaleMatrix[2]; + scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); + scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + // Apply the scaling + transformation[0][0] *= scale[0]; + transformation[0][1] *= scale[1]; + transformation[1][0] *= scale[0]; + transformation[1][1] *= scale[1]; + transformation[0][3] *= scale[0]; + transformation[1][3] *= scale[1]; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); +} + + +//----------------------------------------------------------------------------- +// Moves a matrix into vertex shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ) +{ + IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; + if (pTranslationVar) + { + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 ); + } + else + { + VMatrix matrix; + MatrixSetIdentity( matrix ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 ); + } +} + +void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ) +{ + IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; + if (pTranslationVar) + { + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 ); + } + else + { + VMatrix matrix; + MatrixSetIdentity( matrix ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 ); + } +} + + +//----------------------------------------------------------------------------- +// Loads the view matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix mat, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); + + MatrixTranspose( mat, transpose ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 ); +} + + +//----------------------------------------------------------------------------- +// Loads the projection matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix mat, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mat.m[0] ); + + MatrixTranspose( mat, transpose ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 ); +} + + +//----------------------------------------------------------------------------- +// Loads the projection matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix view, model, modelView, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] ); + MatrixTranspose( model, model ); + s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] ); + MatrixTranspose( view, view ); + + MatrixMultiply( view, model, modelView ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 ); +} + +//----------------------------------------------------------------------------- +// Loads a scale/offset version of the viewport transform into the specified constant. +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ) +{ + ShaderViewport_t viewport; + + s_pShaderAPI->GetViewports( &viewport, 1 ); + + int bbWidth = 0, + bbHeight = 0; + + s_pShaderAPI->GetBackBufferDimensions( bbWidth, bbHeight ); + + // (x, y, z, w) = (Width / bbWidth, Height / bbHeight, MinX / bbWidth, MinY / bbHeight) + Vector4D viewportTransform( + 1.0f * viewport.m_nWidth / bbWidth, + 1.0f * viewport.m_nHeight / bbHeight, + 1.0f * viewport.m_nTopLeftX / bbWidth, + 1.0f * viewport.m_nTopLeftY / bbHeight + ); + + s_pShaderAPI->SetVertexShaderConstant( vertexReg, viewportTransform.Base() ); +} + + + +//----------------------------------------------------------------------------- +// Loads bump lightmap coordinates into the pixel shader +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ) +{ + Vector4D basis[3]; + for (int i = 0; i < 3; ++i) + { + memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 ); +} + + +//----------------------------------------------------------------------------- +// Loads bump lightmap coordinates into the pixel shader +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ) +{ + Vector4D basis[3]; + + // transpose + int i; + for (i = 0; i < 3; ++i) + { + basis[i][0] = g_localBumpBasis[0][i]; + basis[i][1] = g_localBumpBasis[1][i]; + basis[i][2] = g_localBumpBasis[2][i]; + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 ); + for (i = 0; i < 3; ++i) + { + memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 ); +} + + +//----------------------------------------------------------------------------- +// Helper methods for pixel shader overbrighting +//----------------------------------------------------------------------------- +void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ) +{ + // can't have other overbright values with pixel shaders as it stands. + float v[4]; + if( bEnable ) + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT; + } + else + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f; + } + s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 ); +} + + +//----------------------------------------------------------------------------- +// Helper for dealing with modulation +//----------------------------------------------------------------------------- +void CBaseVSShader::SetModulationVertexShaderDynamicState() +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState( int modulationVar ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale; + color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale; + color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale; + + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + + +//----------------------------------------------------------------------------- +// Converts a color + alpha into a vector4 +//----------------------------------------------------------------------------- +void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ) +{ + color.Init( 1.0, 1.0, 1.0, 1.0 ); + if ( colorVar != -1 ) + { + IMaterialVar* pColorVar = s_ppParams[colorVar]; + if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR ) + { + pColorVar->GetVecValue( color.Base(), 3 ); + } + else + { + color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); + } + } + if ( alphaVar != -1 ) + { + float flAlpha = s_ppParams[alphaVar]->GetFloatValue(); + color[3] = clamp( flAlpha, 0.0f, 1.0f ); + } +} + + +//----------------------------------------------------------------------------- +// Sets a color + alpha into shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ) +{ + Vector4D color; + ColorVarsToVector( colorVar, alphaVar, color ); + s_pShaderAPI->SetVertexShaderConstant( nVertexReg, color.Base() ); +} + +void CBaseVSShader::SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ) +{ + Vector4D color; + ColorVarsToVector( colorVar, alphaVar, color ); + s_pShaderAPI->SetPixelShaderConstant( nPixelReg, color.Base() ); +} + +#ifdef _DEBUG +ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" ); +ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" ); +#endif + +//----------------------------------------------------------------------------- +// Helpers for dealing with envmap tint +//----------------------------------------------------------------------------- +// set alphaVar to -1 to ignore it. +void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) +{ + float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) + { + IMaterialVar* pAlphaVar = NULL; + if( alphaVar >= 0 ) + { + pAlphaVar = s_ppParams[alphaVar]; + } + if( pAlphaVar ) + { + color[3] = pAlphaVar->GetFloatValue(); + } + + IMaterialVar* pTintVar = s_ppParams[tintVar]; +#ifdef _DEBUG + pTintVar->GetVecValue( color, 3 ); + + float envmapTintOverride = mat_envmaptintoverride.GetFloat(); + float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); + + if( envmapTintOverride != -1.0f ) + { + color[0] = color[1] = color[2] = envmapTintOverride; + } + if( envmapTintScaleOverride != -1.0f ) + { + color[0] *= envmapTintScaleOverride; + color[1] *= envmapTintScaleOverride; + color[2] *= envmapTintScaleOverride; + } + + if( bConvertFromGammaToLinear ) + { + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + } +#else + if( bConvertFromGammaToLinear ) + { + pTintVar->GetLinearVecValue( color, 3 ); + } + else + { + pTintVar->GetVecValue( color, 3 ); + } +#endif + } + else + { + color[0] = color[1] = color[2] = color[3] = 0.0f; + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); +} + +void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( ) +{ + s_pShaderAPI->SetVertexShaderStateAmbientLightCube(); +} + +float CBaseVSShader::GetAmbientLightCubeLuminance( ) +{ + return s_pShaderAPI->GetAmbientLightCubeLuminance(); +} + +//----------------------------------------------------------------------------- +// GR - translucency query +//----------------------------------------------------------------------------- +BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, + int detailTextureVar ) +{ + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a vertex alpha + isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); + + // Or we've got a texture alpha (for blending or alpha test) + isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && + !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); + + if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) + { + isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); + } + + if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) + { + return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive + } + else + { + return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending + } +} + +void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ) +{ + Assert( !IsSnapshotting() ); + + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture ); + + // Set the flashlight origin + float pos[4]; + pos[0] = flashlightState.m_vecLightOrigin[0]; + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this + + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 ); + + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 ); + + // Set the flashlight attenuation factors + float atten[4]; + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + /*atten[3] = flashlightState.m_FarZAtten;*/ + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 ); + + if ( bDetail ) + { + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar ); + } + + if( bSetTextureTransforms ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM ); + if( !bDetail && bBump && bumpTransformVar != -1 ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform + } + } +} + +// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering... +void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ) +{ + const int nTexRes = 32; + int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes; + + int nRow = nSeed / nTexRes; + int nCol = nSeed % nTexRes; + + // Div and mod to get an individual texel in the fTexRes x fTexRes grid + *fU = nRow / (float) nTexRes; // Row + *fV = nCol / (float) nTexRes; // Column +} + +void CBaseVSShader::DrawEqualDepthToDestAlpha( void ) +{ + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + bool bMakeActualDrawCall = false; + if( s_pShaderShadow ) + { + s_pShaderShadow->EnableColorWrites( false ); + s_pShaderShadow->EnableAlphaWrites( true ); + s_pShaderShadow->EnableDepthWrites( false ); + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->EnableBlending( false ); + + s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + + s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 ); + s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 ); + } + if( s_pShaderAPI ) + { + s_pShaderAPI->SetVertexShaderIndex( 0 ); + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha(); + } + Draw( bMakeActualDrawCall ); + } +} + +//----------------------------------------------------------------------------- +// Sets up hw morphing state for the vertex shader +//----------------------------------------------------------------------------- +void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ) +{ + if ( !s_pShaderAPI->IsHWMorphingEnabled() ) + return; + + int nMorphWidth, nMorphHeight; + s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); + + int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); + float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f }; + s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize ); + + int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); + int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); + int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); + int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); + float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight }; + s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect ); + + s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); +} + diff --git a/materialsystem/stdshaders/basevsshader.h b/materialsystem/stdshaders/basevsshader.h new file mode 100644 index 00000000..b2b4c823 --- /dev/null +++ b/materialsystem/stdshaders/basevsshader.h @@ -0,0 +1,342 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// + +#ifndef BASEVSSHADER_H +#define BASEVSSHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderlib/cshader.h" +#include "shaderlib/BaseShader.h" +#include "convar.h" +#include + +#ifdef _X360 +#define SUPPORT_DX8 0 +#define SUPPORT_DX7 0 +#else +#define SUPPORT_DX8 1 +#define SUPPORT_DX7 1 +#endif + +#ifdef MAPBASE +extern ConVar mat_specular_disable_on_missing; +#endif + +//----------------------------------------------------------------------------- +// Helper macro for vertex shaders +//----------------------------------------------------------------------------- +#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags ) +#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 ) + + +// useful parameter initialization macro +#define INIT_FLOAT_PARM( parm, value ) \ + if ( !params[(parm)]->IsDefined() ) \ + { \ + params[(parm)]->SetFloatValue( (value) ); \ + } + +// useful pixel shader declaration macro for ps20/20b c++ code +#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ + { \ + DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \ + SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \ + } \ + else \ + { \ + DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \ + SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \ + } + +#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ + { \ + DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ + SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ + } \ + else \ + { \ + DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ + SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ + } + + +//----------------------------------------------------------------------------- +// Base class for shaders, contains helper methods. +//----------------------------------------------------------------------------- +class CBaseVSShader : public CBaseShader +{ +public: + + // Loads bump lightmap coordinates into the pixel shader + void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ); + + // Loads bump lightmap coordinates into the vertex shader + void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ); + + // Pixel and vertex shader constants.... + void SetPixelShaderConstant( int pixelReg, int constantVar ); + + // Pixel and vertex shader constants.... + void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ); + + // This version will put constantVar into x,y,z, and constantVar2 into the w + void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ); + void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ); + + // Helpers for setting constants that need to be converted to linear space (from gamma space). + void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); + void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); + + void SetVertexShaderConstant( int vertexReg, int constantVar ); + + // set rgb components of constant from a color parm and give an explicit w value + void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ); + + // GR - fix for const/lerp issues + void SetPixelShaderConstantFudge( int pixelReg, int constantVar ); + + // Sets light direction for pixel shaders. + void SetPixelShaderLightColors( int pixelReg ); + + // Sets vertex shader texture transforms + void SetVertexShaderTextureTranslation( int vertexReg, int translationVar ); + void SetVertexShaderTextureScale( int vertexReg, int scaleVar ); + void SetVertexShaderTextureTransform( int vertexReg, int transformVar ); + void SetVertexShaderTextureScaledTransform( int vertexReg, + int transformVar, int scaleVar ); + + // Set pixel shader texture transforms + void SetPixelShaderTextureTranslation( int pixelReg, int translationVar ); + void SetPixelShaderTextureScale( int pixelReg, int scaleVar ); + void SetPixelShaderTextureTransform( int pixelReg, int transformVar ); + void SetPixelShaderTextureScaledTransform( int pixelReg, + int transformVar, int scaleVar ); + + // Moves a matrix into vertex shader constants + void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ); + void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ); + + // Loads the view matrix into vertex shader constants + void LoadViewMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads the projection matrix into vertex shader constants + void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads the model->view matrix into vertex shader constants + void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads a scale/offset version of the viewport transform into the specified constant. + void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ); + + // Sets up ambient light cube... + void SetAmbientCubeDynamicStateVertexShader( ); + float GetAmbientLightCubeLuminance( ); + + // Helpers for dealing with envmaptint + void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false ); + + // Helper methods for pixel shader overbrighting + void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ); + + // Helper for dealing with modulation + void SetModulationVertexShaderDynamicState(); + void SetModulationPixelShaderDynamicState( int modulationVar ); + void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ); + void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ); + + // Sets a color + alpha into shader constants + void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ); + void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ); + + // Sets up hw morphing state for the vertex shader + void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ); + + // Computes the shader index for vertex lit materials + int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const; + + // Helper for setting up flashlight constants + void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ); + + struct DrawFlashlight_dx90_Vars_t + { + DrawFlashlight_dx90_Vars_t() + { + // set all ints to -1 + memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) ); + // set all bools to a default value. + m_bBump = false; + m_bLightmappedGeneric = false; + m_bWorldVertexTransition = false; + m_bTeeth = false; + m_bSSBump = false; + m_fSeamlessScale = 0.0; + } + bool m_bBump; + bool m_bLightmappedGeneric; + bool m_bWorldVertexTransition; + bool m_bTeeth; + int m_nBumpmapVar; + int m_nBumpmapFrame; + int m_nBumpTransform; + int m_nFlashlightTextureVar; + int m_nFlashlightTextureFrameVar; + int m_nBaseTexture2Var; + int m_nBaseTexture2FrameVar; +#ifdef MAPBASE + int m_nBaseTexture2TransformVar; +#endif + int m_nBumpmap2Var; + int m_nBumpmap2Frame; + int m_nBump2Transform; + int m_nDetailVar; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + int m_nTeethForwardVar; + int m_nTeethIllumFactorVar; + int m_nAlphaTestReference; + bool m_bSSBump; + float m_fSeamlessScale; // 0.0 = not seamless + }; + + BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); + + void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ); + + //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth. + //This pass fills in the areas that passed the alpha test with depth in dest alpha + //by writing only equal depth pixels and only if we should be writing depth to dest alpha + void DrawEqualDepthToDestAlpha( void ); + +private: + // Helper methods for VertexLitGenericPass +// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin ); + void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar, + int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar, + int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar, + int envmapMaskScaleVar, int envmapTintVar ); + + // Converts a color + alpha into a vector4 + void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ); + +}; + +extern ConVar r_flashlightbrightness; + +FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false ) +{ + // Old code + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //float flFlashlightScale = 1.0f / flToneMapScale; + + // Fix to old code to keep flashlight from ever getting brighter than 1.0 + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //if ( flToneMapScale < 1.0f ) + // flToneMapScale = 1.0f; + //float flFlashlightScale = 1.0f / flToneMapScale; + + float flFlashlightScale = r_flashlightbrightness.GetFloat(); + + if ( !g_pHardwareConfig->GetHDREnabled() ) + { + // Non-HDR path requires 2.0 flashlight + flFlashlightScale = 2.0f; + } + + // DX10 requires some hackery due to sRGB/blend ordering change from DX9 + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 + } + + // INSOLENCE: This causes very odd projected texture flickering bugs, so it's commented out for now + /*flFlashlightScale *= state.m_fBrightnessScale;*/ + + // Generate pixel shader constant + float const *pFlashlightColor = state.m_Color; + float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; + vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term + + // Red flashlight for testing + //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f; + + pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst ); +} + +FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state ) +{ + // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + return state.m_flShadowAtten * 0.1f; // magic number + + return state.m_flShadowAtten; +} + +FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state ) +{ + //// We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that + //return state.m_flShadowFilterSize / 1024.0f; + + // INSOLENCE: Get the shadow map resolution from the same place we get the shadow filter size + return state.m_flShadowFilterSize / state.m_flShadowMapResolution; +} + + +// convenient material variable access functions for helpers to use. +FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->IsTexture() ); +} + +FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->GetIntValue() ); +} + +FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue; +} + +FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue; +} + +FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetFloatValue( flValue ); + } +} + +FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetIntValue( nValue ); + } +} + + +class ConVar; + +#ifdef _DEBUG +extern ConVar mat_envmaptintoverride; +extern ConVar mat_envmaptintscale; +#endif + + +#endif // BASEVSSHADER_H diff --git a/materialsystem/stdshaders/bloom.cpp b/materialsystem/stdshaders/bloom.cpp new file mode 100644 index 00000000..2be846d4 --- /dev/null +++ b/materialsystem/stdshaders/bloom.cpp @@ -0,0 +1,72 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "sdk_screenspaceeffect_vs30.inc" +#include "sdk_bloom_ps30.inc" + +BEGIN_VS_SHADER_FLAGS( Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) + SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + if( params[BLURTEXTURE]->IsDefined() ) + { + LoadTexture( BLURTEXTURE ); + } + } + + SHADER_FALLBACK + { + // Requires DX9 + above + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_bloom_ps30 ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps30 ); + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/blurfilterx.cpp b/materialsystem/stdshaders/blurfilterx.cpp new file mode 100644 index 00000000..b16fda86 --- /dev/null +++ b/materialsystem/stdshaders/blurfilterx.cpp @@ -0,0 +1,122 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterX, "Help for BlurFilterX", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterX_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + blurfilter_vs20_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "BlurFilter_vs20", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + float v[4]; + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int width = src_texture->GetActualWidth(); + float dX = 1.0f / width; + + // Tap offsets + v[0] = 1.3366f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 3.4295f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 5.4264f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 7.4359f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 9.4436f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 11.4401f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + v[0] = v[1] = v[2] = v[3] = 1.0; + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/blurfiltery.cpp b/materialsystem/stdshaders/blurfiltery.cpp new file mode 100644 index 00000000..0fe72110 --- /dev/null +++ b/materialsystem/stdshaders/blurfiltery.cpp @@ -0,0 +1,136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "basevsshader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) + { + params[BLOOMAMOUNT]->SetFloatValue( 1.0 ); + } + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterY_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + SET_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int height = src_texture->GetActualWidth(); + float dY = 1.0f / height; +// dY *= 0.4; + float v[4]; + + // Tap offsets + v[0] = 0.0f; + v[1] = 1.3366f * dY; + v[2] = 0; + v[3] = 0; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 0.0f; + v[1] = 3.4295f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 0.0f; + v[1] = 5.4264f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 0.0f; + v[1] = 7.4359f * dY; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 0.0f; + v[1] = 9.4436f * dY; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 0.0f; + v[1] = 11.4401f * dY; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + + v[0]=v[1]=v[2]=params[BLOOMAMOUNT]->GetFloatValue(); + + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/bufferclearobeystencil_ps2x.fxc b/materialsystem/stdshaders/bufferclearobeystencil_ps2x.fxc deleted file mode 100644 index da2e1fa0..00000000 --- a/materialsystem/stdshaders/bufferclearobeystencil_ps2x.fxc +++ /dev/null @@ -1,13 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float4 vColor : COLOR0; -}; - -HALF4 main( PS_INPUT i ) : COLOR -{ - return i.vColor; -} diff --git a/materialsystem/stdshaders/bufferclearobeystencil_vs20.fxc b/materialsystem/stdshaders/bufferclearobeystencil_vs20.fxc deleted file mode 100644 index 170e75bf..00000000 --- a/materialsystem/stdshaders/bufferclearobeystencil_vs20.fxc +++ /dev/null @@ -1,35 +0,0 @@ -#include "common_vs_fxc.h" -// STATIC: "USESCOLOR" "0..1" - -struct VS_INPUT -{ - float4 vPos : POSITION; -# if (USESCOLOR == 1) - float4 vColor : COLOR0; -# endif -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; -# if (USESCOLOR == 1) - float4 vColor : COLOR0; -# endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.vProjPos.xyz = v.vPos.xyz; - o.vProjPos.w = 1.0f; - -# if (USESCOLOR == 1) - { - o.vColor = v.vColor; - } -# endif - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/buildshaders.bat b/materialsystem/stdshaders/buildshaders.bat new file mode 100644 index 00000000..32ec735f --- /dev/null +++ b/materialsystem/stdshaders/buildshaders.bat @@ -0,0 +1,8 @@ +@echo off + +py "%cd%\..\..\devtools\shadercompile\buildshaders.py" "%cd%\game_shader_dx9_20b.txt" -20b +py "%cd%\..\..\devtools\shadercompile\buildshaders.py" "%cd%\game_shader_dx9_30.txt" -30 +py "%cd%\..\..\devtools\shadercompile\buildshaders.py" "%cd%\vance_dx9_20b.txt" -20b +py "%cd%\..\..\devtools\shadercompile\buildshaders.py" "%cd%\vance_dx9_30.txt" -30 + +pause diff --git a/materialsystem/stdshaders/buildshaders.sh b/materialsystem/stdshaders/buildshaders.sh new file mode 100755 index 00000000..37d3a1a7 --- /dev/null +++ b/materialsystem/stdshaders/buildshaders.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +pushd "$(dirname "${BASH_SOURCE-$0}")" > /dev/null || exit +source ../../devtools/linux/env.sh +source "$SRC_DIR/devtools/linux/tools-wine.sh" + +"$SRC_DIR/devtools/shadercompile/buildshaders.py" "$(pwd)/game_shader_dx9_30.txt" -30 $@ + +popd || exit diff --git a/materialsystem/stdshaders/cable_dx6.cpp b/materialsystem/stdshaders/cable_dx6.cpp deleted file mode 100644 index 9b11551f..00000000 --- a/materialsystem/stdshaders/cable_dx6.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Cable, Cable_DX6 ) - -BEGIN_SHADER( Cable_DX6, - "Help for Cable_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Minimum amount of light (0-1 value)" ) - SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Maximum amount of light" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - int GetDrawFlagsPass1(IMaterialVar** params ) - { - int flags = SHADER_DRAW_POSITION; - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - flags |= SHADER_DRAW_COLOR; - flags |= SHADER_DRAW_TEXCOORD0; - return flags; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableConstantColor( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - SetNormalBlendingShadowState( BASETEXTURE, true ); - pShaderShadow->DrawFlags( GetDrawFlagsPass1(params) ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - Vector min, max; - params[MINLIGHT]->GetVecValue( &min.x, 3 ); - params[MAXLIGHT]->GetVecValue( &max.x, 3 ); - Vector avg = ( min + max ) * 0.5f; - pShaderAPI->Color3fv( &avg.x ); - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/cable_dx8.cpp b/materialsystem/stdshaders/cable_dx8.cpp deleted file mode 100644 index 9e3c98dd..00000000 --- a/materialsystem/stdshaders/cable_dx8.cpp +++ /dev/null @@ -1,132 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: A wet version of base * lightmap -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "cable.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Cable, Cable_DX8 ) - -BEGIN_VS_SHADER( Cable_DX8, - "Help for Cable shader" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) - SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) - SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) - { - return "UnlitGeneric_DX6"; - } - return 0; - } - - SHADER_INIT - { - LoadBumpMap( BUMPMAP ); - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - // Enable blending? - if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - } - - int tCoordDimensions[] = {2,2}; - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, - 2, tCoordDimensions, 0 ); - - cable_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Cable", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "Cable" ); - - // we are writing linear values from this shader. - // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. - // The COLOR really decides if we are gamma or linear. - if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - pShaderShadow->EnableSRGBWrite( true ); - } - - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BUMPMAP ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE ); - - - // The dot product with the light is remapped from the range - // [-1,1] to [MinLight, MaxLight]. - - // Given: - // -A + B = MinLight - // A + B = MaxLight - // then A = (MaxLight - MinLight) / 2 - // and B = (MaxLight + MinLight) / 2 - - // So here, we multiply the light direction by A to scale the dot product. - // Then in the pixel shader we add by B. - float flMinLight = params[MINLIGHT]->GetFloatValue(); - float flMaxLight = params[MAXLIGHT]->GetFloatValue(); - - float A = (flMaxLight - flMinLight) * 0.5f; - float B = (flMaxLight + flMinLight) * 0.5f; - - float b4[4] = {B,B,B,B}; - if( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - SetPixelShaderConstantGammaToLinear( 0, b4 ); - } - else - { - pShaderAPI->SetPixelShaderConstant( 0, b4 ); - } - - // This is the light direction [0,1,0,0] * A * 0.5 - float lightDir[4] = {0, A*0.5, 0, 0}; - if( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - SetVertexShaderConstantGammaToLinear( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); - } - else - { - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); - } - - cable_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/cable_dx9.cpp b/materialsystem/stdshaders/cable_dx9.cpp deleted file mode 100644 index 5b25ed61..00000000 --- a/materialsystem/stdshaders/cable_dx9.cpp +++ /dev/null @@ -1,141 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: A wet version of base * lightmap -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "cable_vs20.inc" -#include "cable_ps20.inc" -#include "cable_ps20b.inc" -#include "cpp_shader_constant_register_map.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -extern ConVar mat_fullbright; - -DEFINE_FALLBACK_SHADER( Cable, Cable_DX9 ) - -BEGIN_VS_SHADER( Cable_DX9, - "Help for Cable shader" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) - SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) - SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( !(g_pHardwareConfig->SupportsPixelShaders_2_0() && g_pHardwareConfig->SupportsVertexShaders_2_0()) || - (g_pHardwareConfig->GetDXSupportLevel() < 90) ) - { - return "Cable_DX8"; - } - return 0; - } - - SHADER_INIT - { - LoadBumpMap( BUMPMAP ); - LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); - } - - SHADER_DRAW - { - BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); - bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use - - SHADOW_STATE - { - // Enable blending? - if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - } - - int tCoordDimensions[] = {2,2}; - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, - 2, tCoordDimensions, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( cable_vs20 ); - SET_STATIC_VERTEX_SHADER( cable_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( cable_ps20b ); - SET_STATIC_PIXEL_SHADER( cable_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( cable_ps20 ); - SET_STATIC_PIXEL_SHADER( cable_ps20 ); - } - - // we are writing linear values from this shader. - // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. - // The COLOR really decides if we are gamma or linear. - pShaderShadow->EnableSRGBWrite( true ); - - FogToFogColor(); - - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - DYNAMIC_STATE - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - - BindTexture( SHADER_SAMPLER0, BUMPMAP ); - if ( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - - } - else - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( cable_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER( cable_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( cable_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( cable_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/cable_ps2x.fxc b/materialsystem/stdshaders/cable_ps2x.fxc deleted file mode 100644 index a3c7ff13..00000000 --- a/materialsystem/stdshaders/cable_ps2x.fxc +++ /dev/null @@ -1,54 +0,0 @@ -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -sampler NormalSampler : register( s0 ); -sampler BaseTextureSampler : register( s1 ); - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - -struct PS_INPUT -{ - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog - - float4 directionalLightColor : COLOR0; - float4 fogFactorW : COLOR1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float3 vNormalMapDir = tex2D( NormalSampler, i.vTexCoord0 ); // Get the 3-vector from the normal map - float4 textureColor = tex2D( BaseTextureSampler, i.vTexCoord1 ); // Interpret tcoord t1 as color data. - - //Expand compacted vectors - //TODO: find if there's a better way to expand a color normal to a full vector ( _bx2 was used in the assembly code ) - vNormalMapDir = (vNormalMapDir - 0.5) * 2.0; - float3 vLightDir = float3( 0.0f, 0.0f, 1.0f ); - - float lightDirDotNormalMap = dot( vNormalMapDir, vLightDir ); //normalMap dot dirLightDir - - // do half-lambert on the dot - lightDirDotNormalMap = lightDirDotNormalMap * 0.5 + 0.5; - lightDirDotNormalMap = lightDirDotNormalMap * lightDirDotNormalMap; - - float4 resultColor; - resultColor.xyz = lightDirDotNormalMap * ( textureColor.rgb * i.directionalLightColor.rgb ); - resultColor.a = textureColor.a * i.directionalLightColor.a; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); -} diff --git a/materialsystem/stdshaders/cable_vs20.fxc b/materialsystem/stdshaders/cable_vs20.fxc deleted file mode 100644 index adb3559e..00000000 --- a/materialsystem/stdshaders/cable_vs20.fxc +++ /dev/null @@ -1,80 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - - float4 directionalLightColor : COLOR0; - - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog - - float4 directionalLightColor : COLOR0; - - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - worldPos = mul( v.vPos, cModel[0] ); - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.vProjPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); - - o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - //------------------------------------------------------------------------------ - // Setup the tangent space - //------------------------------------------------------------------------------ - - // Get S crossed with T (call it R) - float3 r = cross( v.vTangentS, v.vTangentT ); - - // Normalize S (into s) - float3 s = normalize( v.vTangentS ); - - // Normalize R (into r) - r = normalize( r ); - - // Regenerate T (into t) - float3 t = cross( r, v.vTangentS ); - - //------------------------------------------------------------------------------ - // Copy texcoords for the normal map and base texture - //------------------------------------------------------------------------------ - o.vTexCoord0 = v.vTexCoord0; - o.vTexCoord1 = v.vTexCoord1; - - // Pass the dirlight color through - o.directionalLightColor = v.directionalLightColor; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/chromatic_ps2x.fxc b/materialsystem/stdshaders/chromatic_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/chromatic_ps2x.fxc rename to materialsystem/stdshaders/chromatic_ps30.fxc diff --git a/materialsystem/stdshaders/chromatic_vs20.fxc b/materialsystem/stdshaders/chromatic_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/chromatic_vs20.fxc rename to materialsystem/stdshaders/chromatic_vs30.fxc diff --git a/materialsystem/stdshaders/clean.bat b/materialsystem/stdshaders/clean.bat deleted file mode 100644 index efcc57db..00000000 --- a/materialsystem/stdshaders/clean.bat +++ /dev/null @@ -1,33 +0,0 @@ -@echo off -setlocal - -if /i "%1" == "-game" goto CleanGameDir - -rem Clean out hl2 -if exist ..\..\..\game\hl2\shaders rd /s /q ..\..\..\game\hl2\shaders -goto CleanOtherStuff - -:CleanGameDir -set __GameDir=%~2 -if not exist "%__GameDir%\gameinfo.txt" goto MissingGameInfo -if exist "%__GameDir%\shaders" rd /s /q "%2\shaders" -goto CleanOtherStuff - -:CleanOtherStuff -if exist debug_dx9 rd /s /q debug_dx9 - -if exist fxctmp9 rd /s /q fxctmp9 -if exist vshtmp9 rd /s /q vshtmp9 -if exist pshtmp9 rd /s /q pshtmp9 -if exist fxctmp9_tmp rd /s /q fxctmp9_tmp -if exist vshtmp9_tmp rd /s /q vshtmp9_tmp -if exist pshtmp9_tmp rd /s /q pshtmp9_tmp -if exist shaders rd /s /q shaders -goto end - -:MissingGameInfo -echo Invalid -game parameter specified (no "%__GameDir%\gameinfo.txt" exists). -goto end - - -:end \ No newline at end of file diff --git a/materialsystem/stdshaders/cleantemps.bat b/materialsystem/stdshaders/cleantemps.bat deleted file mode 100644 index 7055aaf3..00000000 --- a/materialsystem/stdshaders/cleantemps.bat +++ /dev/null @@ -1,12 +0,0 @@ -@echo off -setlocal - -if exist fxctmp9_tmp rd /s /q fxctmp9_tmp -if exist vshtmp9_tmp rd /s /q vshtmp9_tmp -if exist pshtmp9_tmp rd /s /q pshtmp9_tmp - -if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp -if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp -if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp - -if exist shaders rd /s /q shaders diff --git a/materialsystem/stdshaders/cloak_blended_pass_helper.cpp b/materialsystem/stdshaders/cloak_blended_pass_helper.cpp new file mode 100644 index 00000000..0ec02c41 --- /dev/null +++ b/materialsystem/stdshaders/cloak_blended_pass_helper.cpp @@ -0,0 +1,294 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Cloak Pass + "$cloakPassEnabled" "1" + + #include "cloak_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // This should already exist + //SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + //SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + //SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + + Add this above SHADER_INIT_PARAMS() + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + In SHADER_INIT_PARAMS() + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + Modify SHADER_DRAW to look something like this: + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + Draw_Eyes_Refract( this, params, pShaderAPI, pShaderShadow, info ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "basevsshader.h" +#include "mathlib/vmatrix.h" +#include "cloak_blended_pass_helper.h" +#include "convar.h" +#include "sdk_cloak_blended_pass_vs30.inc" +#include "sdk_cloak_blended_pass_ps30.inc" + +void InitParamsCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, CloakBlendedPassVars_t &info ) +{ + // Set material flags + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS( MATERIAL_VAR_MODEL ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + + // Set material parameter default values + if ( ( info.m_nCloakFactor != -1 ) && ( !params[info.m_nCloakFactor]->IsDefined() ) ) + { + params[info.m_nCloakFactor]->SetFloatValue( kDefaultCloakFactor ); + } + + if ( ( info.m_nRefractAmount != -1 ) && ( !params[info.m_nRefractAmount]->IsDefined() ) ) + { + params[info.m_nRefractAmount]->SetFloatValue( kDefaultRefractAmount ); + } + + if ( ( info.m_nCloakColorTint != -1 ) && ( !params[info.m_nCloakColorTint]->IsDefined() ) ) + { + params[info.m_nCloakColorTint]->SetVecValue( kDefaultCloakColorTint[0], kDefaultCloakColorTint[1], kDefaultCloakColorTint[2], kDefaultCloakColorTint[3] ); + } + + if( (info.m_nBumpFrame != -1 ) && !params[info.m_nBumpFrame]->IsDefined() ) + { + params[info.m_nBumpFrame]->SetIntValue( 0 ); + } +} + +void InitCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, CloakBlendedPassVars_t &info ) +{ + // Load textures + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBumpmap ); + } + } +} + +void DrawCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, CloakBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bBumpMapping = ( !g_pConfig->UseBumpmapping() ) || ( info.m_nBumpmap == -1 ) || !params[info.m_nBumpmap]->IsTexture() ? 0 : 1; + + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState( ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER( sdk_cloak_blended_pass_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_cloak_blended_pass_vs30 ); + + // Pixel Shader + DECLARE_STATIC_PIXEL_SHADER( sdk_cloak_blended_pass_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER( sdk_cloak_blended_pass_ps30 ); + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Refraction texture + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + if ( bBumpMapping ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Not sRGB + } + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaWrites( false ); + + // !!! We need to turn this back on because EnableAlphaBlending() above disables it! + pShaderShadow->EnableDepthWrites( true ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + // Set Vertex Shader Constants + if ( ( bBumpMapping ) && ( info.m_nBumpTransform != -1 ) ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBumpTransform ); + } + + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + // Set Vertex Shader Combos + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_cloak_blended_pass_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_cloak_blended_pass_vs30 ); + + // Set Pixel Shader Combos + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_cloak_blended_pass_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_cloak_blended_pass_ps30 ); + + // Bind textures + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map + if ( bBumpMapping ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBumpmap, info.m_nBumpFrame ); + } + + // Set Pixel Shader Constants + float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 ); + + float vPackedConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPackedConst1[0] = IS_PARAM_DEFINED( info.m_nCloakFactor ) ? params[info.m_nCloakFactor]->GetFloatValue() : kDefaultCloakFactor; + vPackedConst1[1] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount; + pShaderAPI->SetPixelShaderConstant( 6, vPackedConst1, 1 ); + + // Refract color tint + pShaderAPI->SetPixelShaderConstant( 7, IS_PARAM_DEFINED( info.m_nCloakColorTint ) ? params[info.m_nCloakColorTint]->GetVecValue() : kDefaultCloakColorTint, 1 ); + + // Set c0 and c1 to contain first two rows of ViewProj matrix + VMatrix mView, mProj; + pShaderAPI->GetMatrix( MATERIAL_VIEW, mView.m[0] ); + pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mProj.m[0] ); + VMatrix mViewProj = mView * mProj; + mViewProj = mViewProj.Transpose3x3(); + pShaderAPI->SetPixelShaderConstant( 0, mViewProj.m[0], 2 ); + } + pShader->Draw(); +} + +bool CloakBlendedPassIsFullyOpaque ( IMaterialVar** params, CloakBlendedPassVars_t &info ) +{ + float flCloakFactor = IS_PARAM_DEFINED( info.m_nCloakFactor ) ? params[info.m_nCloakFactor]->GetFloatValue() : kDefaultCloakFactor; + //float flRefractAmount = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount; + + // NOTE: If this math changes, you need to update the pixel shader code! + float flFresnel = 1.0f - ( 0.0f ); // Assume V.N = 0.0f; + float flCloakLerpFactor = clamp( Lerp( clamp( flCloakFactor, 0.0f, 1.0f ), 1.0f, flFresnel - 1.35f ), 0.0f, 1.0f ); + //flCloakLerpFactor = 1.0f - smoothstep( 0.4f, 0.425f, flCloakLerpFactor ); + + if ( flCloakLerpFactor <= 0.4f ) + return true; + + return false; +} diff --git a/materialsystem/stdshaders/cloak_blended_pass_helper.h b/materialsystem/stdshaders/cloak_blended_pass_helper.h new file mode 100644 index 00000000..2d566a66 --- /dev/null +++ b/materialsystem/stdshaders/cloak_blended_pass_helper.h @@ -0,0 +1,46 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +#ifndef CLOAK_BLENDED_PASS_HELPER_H +#define CLOAK_BLENDED_PASS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct CloakBlendedPassVars_t +{ + CloakBlendedPassVars_t() { memset( this, 0xFF, sizeof(CloakBlendedPassVars_t) ); } + + int m_nCloakFactor; + int m_nCloakColorTint; + int m_nRefractAmount; + + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpTransform; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultCloakFactor = 0.0f; +static const float kDefaultCloakColorTint[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; +static const float kDefaultRefractAmount = 0.1f; + +void InitParamsCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, CloakBlendedPassVars_t &info ); +void InitCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, CloakBlendedPassVars_t &info ); +void DrawCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, CloakBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ); +bool CloakBlendedPassIsFullyOpaque ( IMaterialVar** params, CloakBlendedPassVars_t &info ); + +#endif // CLOAK_BLENDED_PASS_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshaders/cloud.cpp b/materialsystem/stdshaders/cloud.cpp index 810e6c4d..f27d1df9 100644 --- a/materialsystem/stdshaders/cloud.cpp +++ b/materialsystem/stdshaders/cloud.cpp @@ -1,33 +1,40 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// DirectX 9 Cloud shader // -// $Header: $ -// $NoKeywords: $ -//=============================================================================// +//=============================================================================== + +#include "basevsshader.h" +#include "cloud_vs20.inc" +#include "cloud_ps20.inc" -#include "shaderlib/cshader.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -BEGIN_SHADER( Cloud, - "Help for Cloud" ) +BEGIN_VS_SHADER( Cloud, "Help for Cloud" ) + BEGIN_SHADER_PARAMS SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) END_SHADER_PARAMS + + SHADER_FALLBACK + { + return 0; + } + SHADER_INIT { - LoadTexture( BASETEXTURE ); - LoadTexture( CLOUDALPHATEXTURE ); - if( !params[CLOUDSCALE]->IsDefined() ) + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); + if ( !params[CLOUDSCALE]->IsDefined() ) { params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); } - if( !params[MASKSCALE]->IsDefined() ) + if ( !params[MASKSCALE]->IsDefined() ) { params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); } @@ -35,42 +42,48 @@ BEGIN_SHADER( Cloud, SHADER_DRAW { - if( g_pHardwareConfig->GetSamplerCount() >= 2 ) + SHADOW_STATE { - SHADOW_STATE + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - { - pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - else - { - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | - SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); - DefaultFog(); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); } - DYNAMIC_STATE + else { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); - - // handle scrolling of base texture - SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE0, - BASETEXTURETRANSFORM, CLOUDSCALE ); - SetFixedFunctionTextureScale( MATERIAL_TEXTURE1, MASKSCALE ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); } - Draw(); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( cloud_vs20 ); + SET_STATIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( cloud_ps20 ); + SET_STATIC_PIXEL_SHADER( cloud_ps20 ); + + DefaultFog(); } - else + + DYNAMIC_STATE { - ShaderWarning("Cloud not supported for single-texturing boards!\n"); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // Handle scrolling of base texture + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); + + DECLARE_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); } + + Draw(); } END_SHADER diff --git a/materialsystem/stdshaders/cloud_dx8.cpp b/materialsystem/stdshaders/cloud_dx8.cpp deleted file mode 100644 index d3bc2530..00000000 --- a/materialsystem/stdshaders/cloud_dx8.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "cloud_vs11.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER( Cloud_dx8, "Help for Cloud" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) - SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) - SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) - SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) - END_SHADER_PARAMS - - SHADER_INIT - { - LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); - LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); - if ( !params[CLOUDSCALE]->IsDefined() ) - { - params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); - } - if ( !params[MASKSCALE]->IsDefined() ) - { - params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - { - pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - else - { - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); - - cloud_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "cloud_vs11", vshIndex.GetIndex() ); - pShaderShadow->SetPixelShader( "cloud_ps11" ); - - DefaultFog(); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); - - // handle scrolling of base texture - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); - SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); - - pShaderAPI->SetVertexShaderIndex( 0 ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/cloud_dx9.cpp b/materialsystem/stdshaders/cloud_dx9.cpp deleted file mode 100644 index 4b04b8b4..00000000 --- a/materialsystem/stdshaders/cloud_dx9.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// DirectX 9 Cloud shader -// -//=============================================================================== - -#include "BaseVSShader.h" -#include "cloud_vs20.inc" -#include "cloud_ps20.inc" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Cloud, Cloud_dx9 ) - -BEGIN_VS_SHADER( Cloud_dx9, "Help for Cloud" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) - SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) - SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) - SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "Cloud_dx8"; - - return 0; - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); - LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); - if ( !params[CLOUDSCALE]->IsDefined() ) - { - params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); - } - if ( !params[MASKSCALE]->IsDefined() ) - { - params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) - { - pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - else - { - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( cloud_vs20 ); - SET_STATIC_VERTEX_SHADER( cloud_vs20 ); - - DECLARE_STATIC_PIXEL_SHADER( cloud_ps20 ); - SET_STATIC_PIXEL_SHADER( cloud_ps20 ); - - DefaultFog(); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); - - // Handle scrolling of base texture - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); - SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); - - DECLARE_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); - } - - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/cloud_ps11.psh b/materialsystem/stdshaders/cloud_ps11.psh deleted file mode 100644 index 82ed1d60..00000000 --- a/materialsystem/stdshaders/cloud_ps11.psh +++ /dev/null @@ -1,6 +0,0 @@ -ps.1.1 - -tex t0 -tex t1 - -mul r0, t0, t1 diff --git a/materialsystem/stdshaders/cloud_vs11.vsh b/materialsystem/stdshaders/cloud_vs11.vsh deleted file mode 100644 index 6348937e..00000000 --- a/materialsystem/stdshaders/cloud_vs11.vsh +++ /dev/null @@ -1,26 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..0" - -#include "macros.vsh" - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - -&AllocateRegister( \$worldPos ); -; $worldPos unused, for above water, range fog calcs -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); -&FreeRegister( \$worldPos ); - -dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 -dp4 oT1.x, $vTexCoord1, $SHADER_SPECIFIC_CONST_2 -dp4 oT1.y, $vTexCoord1, $SHADER_SPECIFIC_CONST_3 - diff --git a/materialsystem/stdshaders/commandbuilder.h b/materialsystem/stdshaders/commandbuilder.h index 278f2dce..8a07baa4 100644 --- a/materialsystem/stdshaders/commandbuilder.h +++ b/materialsystem/stdshaders/commandbuilder.h @@ -13,7 +13,7 @@ #include "shaderapi/commandbuffer.h" #endif -#include "BaseVSShader.h" +#include "basevsshader.h" #include "shaderapi/ishaderapi.h" #ifdef _WIN32 diff --git a/materialsystem/stdshaders/common_deferred.h b/materialsystem/stdshaders/common_deferred.h index 5bbaf1a3..a77a335f 100644 --- a/materialsystem/stdshaders/common_deferred.h +++ b/materialsystem/stdshaders/common_deferred.h @@ -1,3 +1,6 @@ +#ifndef COMMON_DEFERRED_FXC_H +#define COMMON_DEFERRED_FXC_H + float3 packNormals(float3 n) { //return normalize(n) * 0.5f + 1.0f; @@ -8,4 +11,6 @@ float3 unpackNormals(float3 n) { //return normalize(n * 2.0f - 1.0f); return n; -} \ No newline at end of file +} + +#endif // COMMON_DEFERRED_FXC_H diff --git a/materialsystem/stdshaders/deferred_shadows.h b/materialsystem/stdshaders/common_deferredshadows_fxc.h similarity index 100% rename from materialsystem/stdshaders/deferred_shadows.h rename to materialsystem/stdshaders/common_deferredshadows_fxc.h diff --git a/materialsystem/stdshaders/common_flashlight_fxc.h b/materialsystem/stdshaders/common_flashlight_fxc.h index 098f1848..c14f6c03 100644 --- a/materialsystem/stdshaders/common_flashlight_fxc.h +++ b/materialsystem/stdshaders/common_flashlight_fxc.h @@ -10,6 +10,9 @@ #include "common_ps_fxc.h" +#if defined(SHADER_MODEL_PS_3_0) +#define NEW_SHADOW_FILTERS // Comment if you want to enable retail shadow filter. +#endif // JasonM - TODO: remove this simpleton version float DoShadow( sampler DepthSampler, float4 texCoord ) @@ -100,12 +103,16 @@ float DoShadowNvidiaCheap( sampler DepthSampler, const float4 shadowMapPos ) return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25)); } +#if defined( NEW_SHADOW_FILTERS ) +float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float3 shadowMapPos ) +#else float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos ) +#endif { - float fTexelEpsilon = 1.0f / 1024.0f; + float fTexelEpsilon = 1.0f / 512.0f; - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + //float ooW = 1.0f; //1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz; // * ooW; // Do both projections at once float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space @@ -138,61 +145,80 @@ float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos ) // 4 20 33 20 4 // 1 4 7 4 1 // +#if defined( NEW_SHADOW_FILTERS ) +float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float3 shadowMapPos, const float2 vShadowTweaks ) +#else float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float4 shadowMapPos ) +#endif { - float fEpsilon = 1.0f / 512.0f; - float fTwoEpsilon = 2.0f * fEpsilon; +#if defined( NEW_SHADOW_FILTERS ) + float fEpsilonX = vShadowTweaks.x; + float fTwoEpsilonX = 2.0f * fEpsilonX; + float fEpsilonY = vShadowTweaks.y; + float fTwoEpsilonY = 2.0f * fEpsilonY; +#else + float fEpsilonX = 1.0 / 512.0; + float fTwoEpsilonX = 2.0f * fEpsilonX; + float fEpsilonY = fEpsilonX; + float fTwoEpsilonY = fTwoEpsilonX; +#endif +#if defined( NEW_SHADOW_FILTERS ) + // I guess we don't need this one. + // float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos; // Do both projections at once +#else float ooW = 1.0f / shadowMapPos.w; // 1 / w float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once +#endif float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space float4 vOneTaps; - vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilonX, fTwoEpsilonY ), objDepth, 1 ) ).x; + vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilonX, fTwoEpsilonY ), objDepth, 1 ) ).x; + vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilonX, -fTwoEpsilonY ), objDepth, 1 ) ).x; + vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilonX, -fTwoEpsilonY ), objDepth, 1 ) ).x; float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f)); float4 vSevenTaps; - vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, 0 ), objDepth, 1 ) ).x; - vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, 0 ), objDepth, 1 ) ).x; - vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; - vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; + vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilonX, 0 ), objDepth, 1 ) ).x; + vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilonX, 0 ), objDepth, 1 ) ).x; + vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, fTwoEpsilonY ), objDepth, 1 ) ).x; + vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilonY ), objDepth, 1 ) ).x; float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) ); float4 vFourTapsA, vFourTapsB; - vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilonX, fEpsilonY ), objDepth, 1 ) ).x; + vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilonX, fTwoEpsilonY ), objDepth, 1 ) ).x; + vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilonX, fTwoEpsilonY ), objDepth, 1 ) ).x; + vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilonX, fEpsilonY ), objDepth, 1 ) ).x; + vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilonX, -fEpsilonY ), objDepth, 1 ) ).x; + vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilonX, -fTwoEpsilonY ), objDepth, 1 ) ).x; + vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilonX, -fTwoEpsilonY ), objDepth, 1 ) ).x; + vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilonX, -fEpsilonY ), objDepth, 1 ) ).x; float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); float4 v20Taps; - v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fEpsilon ), objDepth, 1 ) ).x; - v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fEpsilon ), objDepth, 1 ) ).x; - v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilonX, fEpsilonY ), objDepth, 1 ) ).x; + v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilonX, fEpsilonY ), objDepth, 1 ) ).x; + v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilonX, -fEpsilonY ), objDepth, 1 ) ).x; + v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilonX, -fEpsilonY ), objDepth, 1 ) ).x; float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f)); float4 v33Taps; - v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, 0 ), objDepth, 1 ) ).x; - v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, 0 ), objDepth, 1 ) ).x; - v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; - v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; + v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilonX, 0 ), objDepth, 1 ) ).x; + v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilonX, 0 ), objDepth, 1 ) ).x; + v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, fEpsilonY ), objDepth, 1 ) ).x; + v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilonY ), objDepth, 1 ) ).x; float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f)); float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (55.0f / 331.0f); // Sum all 25 Taps - return flOneTaps + flSevenTaps + +flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; + return flOneTaps + flSevenTaps + flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; } @@ -601,7 +627,12 @@ float DoFlashlightShadow( sampler DepthSampler, sampler RandomRotationSampler, f #if !defined( _X360 ) //PC if( nShadowLevel == NVIDIA_PCF_POISSON ) +#if defined( NEW_SHADOW_FILTERS ) && defined( SHADER_MODEL_PS_3_0 ) + // Let's replace noise filter with gaussian blur, like in Portal 2. + flShadow = DoShadowNvidiaPCF5x5Gaussian( DepthSampler, vProjCoords, float2( vShadowTweaks.x, vShadowTweaks.x ) ); +#else flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, true, false ); +#endif else if( nShadowLevel == ATI_NOPCF ) flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false ); else if( nShadowLevel == ATI_NO_PCF_FETCH4 ) @@ -660,6 +691,12 @@ void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashli { float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; float3 flashlightColor = float3(1,1,1); + + // Blixibon - Fix for flashlight textures without Clamp S/T +#if defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + clip( vProjCoords.xyz ); + clip( 1-vProjCoords.xyz ); +#endif #if ( defined( _X360 ) ) @@ -691,6 +728,7 @@ void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashli #if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + flashlightColor *= flashlightSpacePosition.w > 0; flashlightColor *= cFlashlightColor.xyz; // Flashlight color #endif @@ -702,7 +740,7 @@ void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashli float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); // Attenuation for light and to fade out shadow over distance - float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + float fAtten = saturate( endFalloffFactor * dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); // Shadowing and coloring terms #if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) @@ -722,7 +760,9 @@ void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashli diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term #endif diffuseLighting *= flashlightColor; - diffuseLighting *= endFalloffFactor; + + // Blixibon - Now calculating endFalloffFactor directly from fAtten + //diffuseLighting *= endFalloffFactor; // Specular term (masked by diffuse) specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, bDoSpecularWarp, specularWarpSampler, fFresnel ); @@ -734,29 +774,28 @@ float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpa sampler RandomRotationSampler, int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), bool bHasNormal = true ) { - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flashlightColor = float3(1,1,1); - -#if ( defined( _X360 ) ) - - float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); - float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); - - [branch] - if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + if ( flashlightSpacePosition.w < 0 ) { - if ( bClip ) - { - clip(-1); - } return float3(0,0,0); } else { - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = float3(1,1,1); + + // Blixibon - Fix for flashlight textures without Clamp S/T +#if defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + clip( vProjCoords.xyz ); + clip( 1-vProjCoords.xyz ); +#endif + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); [branch] - if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) { if ( bClip ) { @@ -764,58 +803,74 @@ float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpa } return float3(0,0,0); } - } + else + { + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + + [branch] + if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + { + if ( bClip ) + { + clip(-1); + } + return float3(0,0,0); + } + } #else - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); #endif #if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - flashlightColor *= cFlashlightColor.xyz; // Flashlight color + flashlightColor *= cFlashlightColor.xyz; // Flashlight color #endif - float3 delta = flashlightPos - worldPos; - float3 L = normalize( delta ); - float distSquared = dot( delta, delta ); - float dist = sqrt( distSquared ); + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); - float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); - // Attenuation for light and to fade out shadow over distance - float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( endFalloffFactor * dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); - // Shadowing and coloring terms + // Shadowing and coloring terms #if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) - if ( bDoShadows ) - { - float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); - float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation - flashlightColor *= flShadow; // Shadow term - } + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } #endif - float3 diffuseLighting = fAtten; + float3 diffuseLighting = fAtten; - float flLDotWorldNormal; - if ( bHasNormal ) - { - flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); - } - else - { - flLDotWorldNormal = 1.0f; - } + float flLDotWorldNormal; + if ( bHasNormal ) + { + flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); + } + else + { + flLDotWorldNormal = 1.0f; + } #if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term + diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term #else - diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term + diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term #endif - diffuseLighting *= flashlightColor; - diffuseLighting *= endFalloffFactor; + diffuseLighting *= flashlightColor; + + // Blixibon - Now calculating endFalloffFactor directly from fAtten + //diffuseLighting *= endFalloffFactor; - return diffuseLighting; + return diffuseLighting; + } } -#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ +#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ \ No newline at end of file diff --git a/materialsystem/stdshaders/common_fxc.h b/materialsystem/stdshaders/common_fxc.h index 2103b3f9..65f0802d 100644 --- a/materialsystem/stdshaders/common_fxc.h +++ b/materialsystem/stdshaders/common_fxc.h @@ -323,4 +323,18 @@ float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); } +// returns 1.0f for no fog, 0.0f for fully fogged +float CalcRangeFogFactorFixedFunction( float3 worldPos, float3 eyePos, float flFogMaxDensity, float flFogEndOverRange, float flFogOORange ) +{ + float dist = distance( eyePos.xyz, worldPos.xyz ); + return max( flFogMaxDensity, ( -dist * flFogOORange ) + flFogEndOverRange ); +} + +// returns 0.0f for no fog, 1.0f for fully fogged which is opposite of what fixed function fog expects so that we don't have to do a "1-x" in the pixel shader. +float CalcRangeFogFactorNonFixedFunction( float3 worldPos, float3 eyePos, float flFogMaxDensity, float flFogEndOverRange, float flFogOORange ) +{ + float dist = distance( eyePos.xyz, worldPos.xyz ); + return min( flFogMaxDensity, saturate( ( dist * flFogOORange ) - flFogEndOverRange ) ); +} + #endif //#ifndef COMMON_FXC_H_ diff --git a/materialsystem/stdshaders/common_fxc2.h b/materialsystem/stdshaders/common_fxc2.h deleted file mode 100644 index 33a25aa0..00000000 --- a/materialsystem/stdshaders/common_fxc2.h +++ /dev/null @@ -1,19 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_FXC2_H_ -#define COMMON_FXC2_H_ - -// This file is here so you can add new utility functions without -// changing common_fxc.h and causing a recompile of the entire universe. - -float LinearToMonochrome ( float3 r ) -{ - return dot( r, float3( 0.299f, 0.587f, 0.114f ) ); -} - -#endif //#ifndef COMMON_FXC2_H_ diff --git a/materialsystem/stdshaders/common_lightingpreview_fxc.h b/materialsystem/stdshaders/common_lightingpreview_fxc.h new file mode 100644 index 00000000..48dc2c0e --- /dev/null +++ b/materialsystem/stdshaders/common_lightingpreview_fxc.h @@ -0,0 +1,17 @@ +#ifndef COMMON_LIGHTINGPREVIEW_FXC_H +#define COMMON_LIGHTINGPREVIEW_FXC_H + +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [ = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) != 0 ] + +// We don't want lighting preview yet. +// SKIP: $LIGHTING_PREVIEW + +// Vertex Shader +#ifdef SHADER_MODEL_VS_3_0 +#endif + +// Pixel Shader +#ifndef SHADER_MODEL_VS_3_0 +#endif + +#endif // COMMON_LIGHTINGPREVIEW_FXC_H diff --git a/materialsystem/stdshaders/common_morphing_vs_fxc.h b/materialsystem/stdshaders/common_morphing_vs_fxc.h new file mode 100644 index 00000000..e5891725 --- /dev/null +++ b/materialsystem/stdshaders/common_morphing_vs_fxc.h @@ -0,0 +1,159 @@ +#ifndef COMMON_MORPHING_VS_FXC_H +#define COMMON_MORPHING_VS_FXC_H + +// DYNAMIC: "MORPHING" "0..1" [ = pShaderAPI->IsHWMorphingEnabled() ] +// SKIP: $DECAL && $MORPHING == 0 + +// Echoes; Disabled. We likely won't ever use HW morphs. +// SKIP: $MORPHING + +//----------------------------------------------------------------------------- +// Methods to sample morph data from a vertex texture +// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex +// For position + normal morph for example, there will be 2 fields. +//----------------------------------------------------------------------------- +float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + return tex2Dlod( vt, t ); +} + +// Optimized version which reads 2 deltas +void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + delta1 = tex2Dlod( vt, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + delta2 = tex2Dlod( vt, t ); +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition ) +{ +#if MORPHING + +#if !DECAL + // Flexes coming in from a separate stream + float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); + vPosition += vPosDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; + flWrinkle = vPosDelta.w; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float4 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; + flWrinkle = vPosDelta.w * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + flWrinkle = 0.0f; + return false; + +#endif +} + +#endif diff --git a/materialsystem/stdshaders/common_ps_fxc.h b/materialsystem/stdshaders/common_ps_fxc.h index fca6511f..21d8cba4 100644 --- a/materialsystem/stdshaders/common_ps_fxc.h +++ b/materialsystem/stdshaders/common_ps_fxc.h @@ -192,7 +192,7 @@ float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMod HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input ) { // return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f; - return texCUBE( normalizeSampler, input ); + return texCUBE( normalizeSampler, input ).xyz; } /* @@ -209,8 +209,17 @@ HALF4 EnvReflect( sampler envmapSampler, } */ +// Vectorized smoothstep for doing three smoothsteps at once. Used by uberlight +float3 smoothstep3( float3 edge0, float3 edge1, float3 OneOverWidth, float3 x ) +{ + x = saturate((x - edge0) * OneOverWidth); // Scale, bias and saturate x to the range of zero to one + return x*x*(3-2*x); // Evaluate polynomial +} + float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange ) { +#if 0 + // This version is what you use if you want a line-integral throught he water for water fog. // float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp float flDepthFromWater = flWaterZ - flWorldPosZ; @@ -226,6 +235,13 @@ float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const floa // $tmp.w is now the distance that we see through water. return saturate(f * flProjPosZ * flFogOORange); +#else + // This version is simply using the depth of the water to determine fog factor, + // which is cheaper than doing the line integral and also fixes some problems with having + // a hard line on the shore when the water surface is viewed tangentially. + // hackity hack . .the 2.0 is for the DF_FUDGE_UP in view_scene.cpp + return saturate( ( flWaterZ - flWorldPosZ - 2.0f ) * flFogOORange ); +#endif } float CalcRangeFog( const float flProjPosZ, const float flFogStartOverRange, const float flFogMaxDensity, const float flFogOORange ) @@ -237,20 +253,24 @@ float CalcRangeFog( const float flProjPosZ, const float flFogStartOverRange, con #endif } -float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) { - float retVal; - if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + float retVal = 0; + /*if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) { retVal = 0.0f; - } + }*/ if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters { - retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + //retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float flFogMaxDensity = fogParams.z; + float flFogEndOverRange = fogParams.x; + float flFogOORange = fogParams.w; + retVal = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, flFogMaxDensity, flFogEndOverRange, flFogOORange ); } else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog { - retVal = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + retVal = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); } return retVal; @@ -264,48 +284,33 @@ float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE ) { + float3 flRet = 0; if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b { # if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b pixelFogFactor = saturate( pixelFogFactor ); - return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + flRet = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog # else - return vShaderColor; + flRet = vShaderColor; # endif } else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) { - return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + flRet = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); } else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) { - return vShaderColor; + flRet = vShaderColor; } + return flRet; } -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) ) -sampler1D GammaTableSampler : register( s15 ); - -float3 SRGBOutput( const float3 vShaderColor ) -{ - //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15. - float3 result; - result.r = tex1D( GammaTableSampler, vShaderColor.r ).r; - result.g = tex1D( GammaTableSampler, vShaderColor.g ).r; - result.b = tex1D( GammaTableSampler, vShaderColor.b ).r; - return result; -} - -#else - float3 SRGBOutput( const float3 vShaderColor ) { return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader } -#endif - float SoftParticleDepth( float flDepth ) { diff --git a/materialsystem/stdshaders/common_splinerope_fxc.h b/materialsystem/stdshaders/common_splinerope_fxc.h new file mode 100644 index 00000000..0893d1d2 --- /dev/null +++ b/materialsystem/stdshaders/common_splinerope_fxc.h @@ -0,0 +1,26 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +#ifdef PIXELSHADER + #define VS_OUTPUT PS_INPUT +#endif + +struct VS_OUTPUT +{ +#ifndef PIXELSHADER + float4 projPos : POSITION; +#endif + + float2 texCoord : TEXCOORD0; + float4 worldPos_projPosZ : TEXCOORD1; + float4 argbcolor : COLOR; + +#ifndef PIXELSHADER + #if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 ) + float fog : FOG; + #endif +#endif +}; + +#ifdef PIXELSHADER + #undef VS_OUTPUT +#endif diff --git a/materialsystem/stdshaders/common_vertexlitgeneric.h b/materialsystem/stdshaders/common_vertexlitgeneric.h new file mode 100644 index 00000000..c1260591 --- /dev/null +++ b/materialsystem/stdshaders/common_vertexlitgeneric.h @@ -0,0 +1,423 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ +#define COMMON_VERTEXLITGENERIC_DX9_H_ + +#include "common_ps_fxc.h" + +// We store four light colors and positions in an +// array of three of these structures like so: +// +// x y z w +// +------+------+------+------+ +// | L0.rgb | | +// +------+------+------+ | +// | L0.pos | L3 | +// +------+------+------+ rgb | +// | L1.rgb | | +// +------+------+------+------+ +// | L1.pos | | +// +------+------+------+ | +// | L2.rgb | L3 | +// +------+------+------+ pos | +// | L2.pos | | +// +------+------+------+------+ +// +struct PixelShaderLightInfo +{ + float4 color; + float4 pos; +}; + +#define cOverbright 2.0f +#define cOOOverbright 0.5f + +#define LIGHTTYPE_NONE 0 +#define LIGHTTYPE_SPOT 1 +#define LIGHTTYPE_POINT 2 +#define LIGHTTYPE_DIRECTIONAL 3 + +// Better suited to Pixel shader models, 11 instructions in pixel shader +// ... actually, now only 9: mul, cmp, cmp, mul, mad, mad, mad, mad, mad +float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 linearColor, nSquared = worldNormal * worldNormal; + float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared; + float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0; + linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + + isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + + isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; + return linearColor; +} + +// Better suited to Vertex shader models +// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) +float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCube[isNegative.x] + + nSquared.y * cAmbientCube[isNegative.y+2] + + nSquared.z * cAmbientCube[isNegative.z+4]; + return linearColor; +} + +float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + // Vertex shader cases +#ifdef SHADER_MODEL_VS_1_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_1_1 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_2_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_3_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#else + // Pixel shader case + return PixelShaderAmbientLight( worldNormal, cAmbientCube ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Compute scalar diffuse term with various optional tweaks such as +// Half Lambert and ambient occlusion +//----------------------------------------------------------------------------- +float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float fResult; + + float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) + + if ( bHalfLambert ) + { + fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range + + if ( !bDoLightingWarp ) + { + fResult *= fResult; // Square + } + } + else + { + fResult = saturate( NDotL ); // Saturate pure Lambertian term + } + + if ( bDoAmbientOcclusion ) + { + // Raise to higher powers for darker AO values +// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); +// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); + fResult *= fAmbientOcclusion; + } + + float3 fOut = float3( fResult, fResult, fResult ); + if ( bDoLightingWarp ) + { + fOut = 2.0f * tex1D( lightWarpSampler, fResult ).xyz; + } + + return fOut; +} + +float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, + in sampler NormalizeSampler, + const float3 vPosition, const float3 vColor, const bool bHalfLambert, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + float3 lightDir = normalize( vPosition - worldPos ); +#else + float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos ); +#endif + return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, bDoLightingWarp, lightWarpSampler ); +} + +float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + return normalize( vLight3Pos - worldPos ); + } + else + { + return normalize( cLightInfo[nLightIndex].pos.xyz - worldPos ); + } +} + +float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + } + else + { + return cLightInfo[nLightIndex].color.rgb; + } +} + + +void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, const float fFresnel, + const float3 color, const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + rimLighting = float3(0.0f, 0.0f, 0.0f); + + //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal + float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent + + // Optionally warp as function of scalar specular and fresnel + if ( bDoSpecularWarp ) + specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ).xyz; // Sample at { (L.R)^k, fresnel } + + specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + specularLighting *= color; // Modulate with light color + + if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion + specularLighting *= fAmbientOcclusion; + + if ( bDoRimLighting ) // Optionally do rim lighting + { + rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent + rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + rimLighting *= color; // Modulate with light color + } +} + +// Traditional fresnel term approximation +float Fresnel( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + return fresnel * fresnel; // Square for a more subtle look +} + +// Traditional fresnel term approximation which uses 4th power (square twice) +float Fresnel4( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + fresnel = fresnel * fresnel; // Square + return fresnel * fresnel; // Square again for a more subtle look +} + + +// +// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function +// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between +// low and mid while the 0.5 to 1 range blends between mid and high +// +// | +// | . M . . . H +// | . +// L +// | +// +---------------- +// 0 1 +// +float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) +{ + //float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel + //if ( f > 0.5f ) + // result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values + //else + // result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values + + // note: vRanges is now encoded as ((mid-min)*2, mid, (max-mid)*2) to optimize math + float f = saturate( 1 - dot( vNormal, vEyeDir ) ); + f = f*f - 0.5; + return vRanges.y + (f >= 0.0 ? vRanges.z : vRanges.x) * f; +} + +void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float fAtten, const float3 vLightColor, const float3 vLightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + // Compute Specular and rim terms + SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, + vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, vLightColor * fAtten, + bDoRimLighting, fRimExponent, specularLighting, rimLighting ); +} + +float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float3 linearColor = 0.0f; + + if ( bStaticLight ) + { + // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright + // need to get it into + // linear space so that we can do adds. + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if ( bAmbientLight ) + { + float3 ambient = AmbientLight( worldNormal, cAmbientCube ); + + if ( bDoAmbientOcclusion ) + ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... + + linearColor += ambient; + } + + if ( nNumLights > 0 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler, + cLightInfo[0].pos.xyz, cLightInfo[0].color.xyz, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 1 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler, + cLightInfo[1].pos.xyz, cLightInfo[1].color.xyz, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 2 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler, + cLightInfo[2].pos.xyz, cLightInfo[2].color.xyz, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 3 ) + { + // Unpack the 4th light's data from tight constant packing + float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeSampler, + vLight3Pos, vLight3Color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + } + } + } + } + + return linearColor; +} + +void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 localSpecularTerm, localRimTerm; + + if( nNumLights > 0 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 0 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 1 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 1 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + + if( nNumLights > 2 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 2 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 3 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 3 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + +} + +float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) +{ + float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal + + return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); +} + +// Called directly by newer shaders or through the following wrapper for older shaders +float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, + + // New optional/experimental parameters + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float3 linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, + bStaticLight, bAmbientLight, lightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + + // go ahead and clamp to the linear space equivalent of overbright 2 so that we match + // everything else. +// linearColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); + + return linearColor; +} + +#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ diff --git a/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h b/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h deleted file mode 100644 index 2eb7bb3c..00000000 --- a/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h +++ /dev/null @@ -1,423 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ -#define COMMON_VERTEXLITGENERIC_DX9_H_ - -#include "common_ps_fxc.h" - -// We store four light colors and positions in an -// array of three of these structures like so: -// -// x y z w -// +------+------+------+------+ -// | L0.rgb | | -// +------+------+------+ | -// | L0.pos | L3 | -// +------+------+------+ rgb | -// | L1.rgb | | -// +------+------+------+------+ -// | L1.pos | | -// +------+------+------+ | -// | L2.rgb | L3 | -// +------+------+------+ pos | -// | L2.pos | | -// +------+------+------+------+ -// -struct PixelShaderLightInfo -{ - float4 color; - float4 pos; -}; - -#define cOverbright 2.0f -#define cOOOverbright 0.5f - -#define LIGHTTYPE_NONE 0 -#define LIGHTTYPE_SPOT 1 -#define LIGHTTYPE_POINT 2 -#define LIGHTTYPE_DIRECTIONAL 3 - -// Better suited to Pixel shader models, 11 instructions in pixel shader -// ... actually, now only 9: mul, cmp, cmp, mul, mad, mad, mad, mad, mad -float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - float3 linearColor, nSquared = worldNormal * worldNormal; - float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared; - float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0; - linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + - isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + - isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; - return linearColor; -} - -// Better suited to Vertex shader models -// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) -float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - float3 nSquared = worldNormal * worldNormal; - int3 isNegative = ( worldNormal < 0.0 ); - float3 linearColor; - linearColor = nSquared.x * cAmbientCube[isNegative.x] + - nSquared.y * cAmbientCube[isNegative.y+2] + - nSquared.z * cAmbientCube[isNegative.z+4]; - return linearColor; -} - -float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - // Vertex shader cases -#ifdef SHADER_MODEL_VS_1_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_1_1 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_2_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_3_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#else - // Pixel shader case - return PixelShaderAmbientLight( worldNormal, cAmbientCube ); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Compute scalar diffuse term with various optional tweaks such as -// Half Lambert and ambient occlusion -//----------------------------------------------------------------------------- -float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float fResult; - - float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) - - if ( bHalfLambert ) - { - fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range - - if ( !bDoLightingWarp ) - { - fResult *= fResult; // Square - } - } - else - { - fResult = saturate( NDotL ); // Saturate pure Lambertian term - } - - if ( bDoAmbientOcclusion ) - { - // Raise to higher powers for darker AO values -// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); -// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); - fResult *= fAmbientOcclusion; - } - - float3 fOut = float3( fResult, fResult, fResult ); - if ( bDoLightingWarp ) - { - fOut = 2.0f * tex1D( lightWarpSampler, fResult ); - } - - return fOut; -} - -float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, - in sampler NormalizeSampler, - const float3 vPosition, const float3 vColor, const bool bHalfLambert, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ -#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) - float3 lightDir = normalize( vPosition - worldPos ); -#else - float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos ); -#endif - return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, bDoLightingWarp, lightWarpSampler ); -} - -float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex ) -{ - if ( nLightIndex == 3 ) - { - // Unpack light 3 from w components... - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - return normalize( vLight3Pos - worldPos ); - } - else - { - return normalize( cLightInfo[nLightIndex].pos - worldPos ); - } -} - -float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex ) -{ - if ( nLightIndex == 3 ) - { - // Unpack light 3 from w components... - return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - } - else - { - return cLightInfo[nLightIndex].color.rgb; - } -} - - -void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, - const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, const float fFresnel, - const float3 color, const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - rimLighting = float3(0.0f, 0.0f, 0.0f); - - //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal - float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal - float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) - specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent - - // Optionally warp as function of scalar specular and fresnel - if ( bDoSpecularWarp ) - specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } - - specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L - specularLighting *= color; // Modulate with light color - - if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion - specularLighting *= fAmbientOcclusion; - - if ( bDoRimLighting ) // Optionally do rim lighting - { - rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent - rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L - rimLighting *= color; // Modulate with light color - } -} - -// Traditional fresnel term approximation -float Fresnel( const float3 vNormal, const float3 vEyeDir ) -{ - float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term - return fresnel * fresnel; // Square for a more subtle look -} - -// Traditional fresnel term approximation which uses 4th power (square twice) -float Fresnel4( const float3 vNormal, const float3 vEyeDir ) -{ - float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term - fresnel = fresnel * fresnel; // Square - return fresnel * fresnel; // Square again for a more subtle look -} - - -// -// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function -// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between -// low and mid while the 0.5 to 1 range blends between mid and high -// -// | -// | . M . . . H -// | . -// L -// | -// +---------------- -// 0 1 -// -float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) -{ - //float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel - //if ( f > 0.5f ) - // result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values - //else - // result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values - - // note: vRanges is now encoded as ((mid-min)*2, mid, (max-mid)*2) to optimize math - float f = saturate( 1 - dot( vNormal, vEyeDir ) ); - f = f*f - 0.5; - return vRanges.y + (f >= 0.0 ? vRanges.z : vRanges.x) * f; -} - -void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, - const float fAtten, const float3 vLightColor, const float3 vLightDir, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, - const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - // Compute Specular and rim terms - SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, - vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, vLightColor * fAtten, - bDoRimLighting, fRimExponent, specularLighting, rimLighting ); -} - -float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], - in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float3 linearColor = 0.0f; - - if ( bStaticLight ) - { - // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright - // need to get it into - // linear space so that we can do adds. - linearColor += GammaToLinear( staticLightingColor * cOverbright ); - } - - if ( bAmbientLight ) - { - float3 ambient = AmbientLight( worldNormal, cAmbientCube ); - - if ( bDoAmbientOcclusion ) - ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... - - linearColor += ambient; - } - - if ( nNumLights > 0 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler, - cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 1 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler, - cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 2 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler, - cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 3 ) - { - // Unpack the 4th light's data from tight constant packing - float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeSampler, - vLight3Pos, vLight3Color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - } - } - } - } - - return linearColor; -} - -void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, - const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, - const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f ); - float3 localSpecularTerm, localRimTerm; - - if( nNumLights > 0 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 0 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - if( nNumLights > 1 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 1 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - - if( nNumLights > 2 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 2 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - if( nNumLights > 3 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 3 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - -} - -float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) -{ - float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal - - return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); -} - -// Called directly by newer shaders or through the following wrapper for older shaders -float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], - in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bHalfLambert, - - // New optional/experimental parameters - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float3 linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, - bStaticLight, bAmbientLight, lightAtten, - cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - - // go ahead and clamp to the linear space equivalent of overbright 2 so that we match - // everything else. -// linearColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); - - return linearColor; -} - -#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ diff --git a/materialsystem/stdshaders/common_vortwarp_fxc.h b/materialsystem/stdshaders/common_vortwarp_fxc.h new file mode 100644 index 00000000..20631692 --- /dev/null +++ b/materialsystem/stdshaders/common_vortwarp_fxc.h @@ -0,0 +1,41 @@ +#include "common_vs_fxc.h" + +float Sine( float min, float max, float t ) +{ + return ( sin( t ) * 0.5f + 0.5f ) * ( max - min ) + min; +} + +float3 QuadraticBezier( float3 A, float3 B, float3 C, float t ) +{ + return lerp( lerp( A, B, t ), lerp( B, C, t ), t ); +} + +float3 CubicBezier( float3 A, float3 B, float3 C, float3 D, float t ) +{ + return QuadraticBezier( lerp( A, B, t ), lerp( B, C, t ), lerp( C, D, t ), t ); +} + +void WorldSpaceVertexProcess( in float time, in float3 modelOrigin, inout float3 worldPos, inout float3 worldNormal, inout float3 worldTangentS, inout float3 worldTangentT ) +{ + float myTime = time; + myTime = saturate( 1.0f - myTime ); + myTime *= myTime; + myTime *= myTime; + myTime *= myTime; +// worldPos.z += 72.0f * myTime; + + // end + float3 A = float3( 0.0f, 0.0f, 1.0f ); + float3 B = float3( 1.0f, 1.0f, 1.0f ); + float3 C = float3( 0.0f, 0.0f, 1.0f ); + float3 D = float3( 0.0f, 0.0f, 1.0f ); + // start + +// float3 modelOrigin = float3( 70.0f, -14.0f, 0.0f ); + + float t = worldPos.z * ( 1.0f / ( 72.0f ) ); // about 72 inches tall + t = saturate( t ); + float3 worldPosDelta = ( worldPos - modelOrigin ) * CubicBezier( A, B, C, D, t ); + worldPosDelta.z += Sine( 0.0f, 10.0, worldPos.z ); + worldPos = lerp( worldPos, worldPosDelta + modelOrigin, myTime ); +} diff --git a/materialsystem/stdshaders/common_vs_fxc.h b/materialsystem/stdshaders/common_vs_fxc.h index ac966b68..04020e0a 100644 --- a/materialsystem/stdshaders/common_vs_fxc.h +++ b/materialsystem/stdshaders/common_vs_fxc.h @@ -20,7 +20,6 @@ // SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH // -------------------------------------------------------------------------------- - #ifndef COMPRESSED_VERTS // Default to no vertex compression #define COMPRESSED_VERTS 0 @@ -91,8 +90,8 @@ const float4 cViewProjZ : register(c13); const float4 cFogParams : register(c16); #define cFogEndOverFogRange cFogParams.x -#define cFogOne cFogParams.y -#define cFogMaxDensity cFogParams.z +// cFogParams.y unused +#define cRadialFogMaxDensity cFogParams.z //radial fog max density in fractional portion. height fog max density stored in integer portion and is multiplied by 1e10 #define cOOFogRange cFogParams.w const float4x4 cViewModel : register(c17); @@ -309,48 +308,6 @@ void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, o } } - -#ifdef SHADER_MODEL_VS_3_0 - -//----------------------------------------------------------------------------- -// Methods to sample morph data from a vertex texture -// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex -// For position + normal morph for example, there will be 2 fields. -//----------------------------------------------------------------------------- -float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) -{ - float flColumn = floor( flVertexID / vMorphSubrect.w ); - - float4 t; - t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; - t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; - t.xy /= vMorphTargetTextureDim.xy; - t.z = t.w = 0.f; - - return tex2Dlod( vt, t ); -} - -// Optimized version which reads 2 deltas -void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) -{ - float flColumn = floor( flVertexID / vMorphSubrect.w ); - - float4 t; - t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; - t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; - t.xy /= vMorphTargetTextureDim.xy; - t.z = t.w = 0.f; - - delta1 = tex2Dlod( vt, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - delta2 = tex2Dlod( vt, t ); -} - -#endif // SHADER_MODEL_VS_3_0 - - -#if ( defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) ) - //----------------------------------------------------------------------------- // Method to apply morphs //----------------------------------------------------------------------------- @@ -397,203 +354,48 @@ bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex, return true; } -#endif // defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) - - -#ifdef SHADER_MODEL_VS_3_0 - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition ) -{ -#if MORPHING - -#if !DECAL - // Flexes coming in from a separate stream - float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); - vPosition += vPosDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // !MORPHING - return false; -#endif -} - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal ) -{ -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // !MORPHING - return false; -#endif -} - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +float CalcFixedFunctionFog( const float3 worldPos, const bool bWaterFog ) { -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; - vTangent += vNormalDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; - vTangent += vNormalDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // MORPHING - - return false; -#endif + if( !bWaterFog ) + { + return CalcRangeFogFactorFixedFunction( worldPos, cEyePos, cRadialFogMaxDensity, cFogEndOverFogRange, cOOFogRange ); + } + else + { + return 0.0f; //all done in the pixel shader as of ps20 (current min-spec) + } } -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +float CalcFixedFunctionFog( const float3 worldPos, const int fogType ) { -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; - vTangent += vNormalDelta.xyz; - flWrinkle = vPosDelta.w; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float4 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; - vTangent += vNormalDelta.xyz * vMorphTexCoord.z; - flWrinkle = vPosDelta.w * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // MORPHING - - flWrinkle = 0.0f; - return false; - -#endif + return CalcFixedFunctionFog( worldPos, fogType != FOGTYPE_RANGE ); } -#endif // SHADER_MODEL_VS_3_0 - - -float RangeFog( const float3 projPos ) +float CalcNonFixedFunctionFog( const float3 worldPos, const bool bWaterFog ) { - return max( cFogMaxDensity, ( -projPos.z * cOOFogRange + cFogEndOverFogRange ) ); + if( !bWaterFog ) + { + return CalcRangeFogFactorNonFixedFunction( worldPos, cEyePos, cRadialFogMaxDensity, cFogEndOverFogRange, cOOFogRange ); + } + else + { + return 0.0f; //all done in the pixel shader as of ps20 (current min-spec) + } } -float WaterFog( const float3 worldPos, const float3 projPos ) +float CalcNonFixedFunctionFog( const float3 worldPos, const int fogType ) { - float4 tmp; - - tmp.xy = cEyePosWaterZ.wz - worldPos.z; - - // tmp.x is the distance from the water surface to the vert - // tmp.y is the distance from the eye position to the vert - - // if $tmp.x < 0, then set it to 0 - // This is the equivalent of moving the vert to the water surface if it's above the water surface - - tmp.x = max( 0.0f, tmp.x ); - - // $tmp.w = $tmp.x / $tmp.y - tmp.w = tmp.x / tmp.y; - - tmp.w *= projPos.z; - - // $tmp.w is now the distance that we see through water. - - return max( cFogMaxDensity, ( -tmp.w * cOOFogRange + cFogOne ) ); + return CalcNonFixedFunctionFog( worldPos, fogType != FOGTYPE_RANGE ); } float CalcFog( const float3 worldPos, const float3 projPos, const int fogType ) { -#if defined( _X360 ) - // 360 only does pixel fog - return 1.0f; -#endif - - if( fogType == FOGTYPE_RANGE ) - { - return RangeFog( projPos ); - } - else - { -#if SHADERMODEL_VS_2_0 == 1 - // We do this work in the pixel shader in dx9, so don't do any fog here. - return 1.0f; -#else - return WaterFog( worldPos, projPos ); -#endif - } + return CalcFixedFunctionFog( worldPos, fogType ); } float CalcFog( const float3 worldPos, const float3 projPos, const bool bWaterFog ) { -#if defined( _X360 ) - // 360 only does pixel fog - return 1.0f; -#endif - - float flFog; - if( !bWaterFog ) - { - flFog = RangeFog( projPos ); - } - else - { -#if SHADERMODEL_VS_2_0 == 1 - // We do this work in the pixel shader in dx9, so don't do any fog here. - flFog = 1.0f; -#else - flFog = WaterFog( worldPos, projPos ); -#endif - } - - return flFog; + return CalcFixedFunctionFog( worldPos, bWaterFog ); } float4 DecompressBoneWeights( const float4 weights ) diff --git a/materialsystem/stdshaders/core.cpp b/materialsystem/stdshaders/core.cpp new file mode 100644 index 00000000..b16e3add --- /dev/null +++ b/materialsystem/stdshaders/core.cpp @@ -0,0 +1,282 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "basevsshader.h" +#include "sdk_core_vs30.inc" +#include "sdk_core_ps30.inc" + +#define MAXBLUR 1 + +BEGIN_VS_SHADER( Core, "Help for Core" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FLOWMAP, SHADER_PARAM_TYPE_TEXTURE, "", "flowmap" ) + SHADER_PARAM( FLOWMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $flowmap" ) + SHADER_PARAM( FLOWMAPSCROLLRATE, SHADER_PARAM_TYPE_VEC2, "[0 0", "2D rate to scroll $flowmap" ) + SHADER_PARAM( CORECOLORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ); + SHADER_PARAM( CORECOLORTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ); + SHADER_PARAM( FLOWMAPTEXCOORDOFFSET, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ); +#ifdef MAPBASE + SHADER_PARAM( SPHERECENTER, SHADER_PARAM_TYPE_VEC3, "2688.0, 12139.0, 5170.0", "The sphere's worldspace center (was previously hardcoded)" ); + SHADER_PARAM( SPHERERADIUS, SHADER_PARAM_TYPE_FLOAT, "215.0", "The sphere's worldspace radius (was previously hardcoded)" ); +#endif + END_SHADER_PARAMS + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + if( !params[BASETEXTURE]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Core_dx90"; + + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if ( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP ); + } + if ( params[FLOWMAP]->IsDefined() ) + { + LoadTexture( FLOWMAP ); + } + if ( params[CORECOLORTEXTURE]->IsDefined() ) + { + LoadTexture( CORECOLORTEXTURE ); + } + } + + inline void DrawPass( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, int nPass, VertexCompressionType_t vertexCompression ) + { + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[ENVMAP]->IsTexture(); + bool bHasFlowmap = params[FLOWMAP]->IsTexture(); + bool bHasCoreColorTexture = params[CORECOLORTEXTURE]->IsTexture(); + + SHADOW_STATE + { + SetInitialShadowState( ); + + if( nPass == 0 ) + { + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + } + else + { + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap ) + { + SetDefaultBlendingShadowState( NORMALMAP, false ); + } + + // source render target that contains the image that we are warping. + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bHasEnvmap ) + { + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + } + + if( bHasFlowmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + + if( bHasCoreColorTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + } + + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBWrite( true ); + } + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + int nTexCoordCount = 1; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_core_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); + SET_STATIC_VERTEX_SHADER( sdk_core_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_core_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && ( nPass == 1 ) ); + SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CORECOLORTEXTURE, bHasCoreColorTexture && ( nPass == 0 ) ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, nPass == 0 ); + SET_STATIC_PIXEL_SHADER( sdk_core_ps30 ); + + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + if ( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); + + if( bHasEnvmap ) + { + BindTexture( SHADER_SAMPLER4, ENVMAP, ENVMAPFRAME ); + } + + if( bHasFlowmap ) + { + BindTexture( SHADER_SAMPLER6, FLOWMAP, FLOWMAPFRAME ); + } + + if( bHasCoreColorTexture ) + { + BindTexture( SHADER_SAMPLER7, CORECOLORTEXTURE, CORECOLORTEXTUREFRAME ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_core_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_core_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_core_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_core_ps30 ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + SetPixelShaderConstant( 0, ENVMAPTINT ); + SetPixelShaderConstant( 1, REFRACTTINT ); + } + else + { + SetPixelShaderConstantGammaToLinear( 0, ENVMAPTINT ); + SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); + } + SetPixelShaderConstant( 2, ENVMAPCONTRAST ); + SetPixelShaderConstant( 3, ENVMAPSATURATION ); + float c5[4] = { params[REFRACTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + float eyePos[4]; + s_pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + s_pShaderAPI->SetPixelShaderConstant( 8, eyePos, 1 ); + pShaderAPI->SetPixelShaderFogParams( 11 ); + + + + if( bHasFlowmap ) + { + float curTime = pShaderAPI->CurrentTime(); + float timeVec[4] = { curTime, curTime, curTime, curTime }; + pShaderAPI->SetPixelShaderConstant( 6, timeVec, 1 ); + + SetPixelShaderConstant( 7, FLOWMAPSCROLLRATE ); + + SetPixelShaderConstant( 9, FLOWMAPTEXCOORDOFFSET ); + } + +#ifdef MAPBASE + SetPixelShaderConstant( 12, SPHERECENTER ); + SetPixelShaderConstant( 15, SPHERERADIUS ); +#endif + } + Draw(); + } + + SHADER_DRAW + { + DrawPass( params, pShaderShadow, pShaderAPI, 0, vertexCompression ); + DrawPass( params, pShaderShadow, pShaderAPI, 1, vertexCompression ); + } +END_SHADER + diff --git a/materialsystem/stdshaders/debugdepth.cpp b/materialsystem/stdshaders/debugdepth.cpp deleted file mode 100644 index 65e55e0c..00000000 --- a/materialsystem/stdshaders/debugdepth.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "shaderlib/cshader.h" -#include "convar.h" -#include "debugdrawdepth_vs20.inc" -#include "debugdrawdepth_ps20.inc" -#include "debugdrawdepth_ps20b.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_debugdepthmode( "mat_debugdepthmode", "0" ); -static ConVar mat_debugdepthval( "mat_debugdepthval", "128.0f" ); -static ConVar mat_debugdepthvalmax( "mat_debugdepthvalmax", "256.0f" ); - -BEGIN_SHADER_FLAGS( DebugDepth, "Help for DebugDepth", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { -// Assert( 0 ); - return "WireFrame"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); - SET_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); - SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); - SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); - } - } - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, s_pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); - - Vector4D vecZFilter( 0, 0, 0, 1 ); - int nDepthMode = mat_debugdepthmode.GetInt(); - if ( nDepthMode > 1 ) - { - nDepthMode = 0; - } - - vecZFilter[nDepthMode] = 1; - s_pShaderAPI->SetPixelShaderConstant( 1, vecZFilter.Base() ); - - Vector4D vecModulationColor( 0, 0, 0, 1 ); - if ( IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) - { - vecModulationColor[0] = 0; - vecModulationColor[1] = 1; - vecModulationColor[2] = 1; - } - else - { - vecModulationColor[0] = 1; - vecModulationColor[1] = 1; - vecModulationColor[2] = 1; - } - s_pShaderAPI->SetPixelShaderConstant( 2, vecModulationColor.Base() ); - - float flDepthFactor = mat_debugdepthval.GetFloat(); - float flDepthFactorMax = mat_debugdepthvalmax.GetFloat(); - if ( flDepthFactor == 0 ) - { - flDepthFactor = 1.0f; - } - Vector4D vecZFactor( (flDepthFactorMax - flDepthFactor), flDepthFactor, 1, 1 ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vecZFactor.Base() ); - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/debugluxel.cpp b/materialsystem/stdshaders/debugluxel.cpp deleted file mode 100644 index 328dfb6b..00000000 --- a/materialsystem/stdshaders/debugluxel.cpp +++ /dev/null @@ -1,97 +0,0 @@ -//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "shaderlib/CShader.h" - -#include "debugluxel_ps20b.inc" -#include "debugluxel_ps20.inc" -#include "debugluxel_vs20.inc" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_SHADER_FLAGS( DebugLuxels, "Help for DebugLuxels", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( NOSCALE, SHADER_PARAM_TYPE_BOOL, "0", "fixme" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - DECLARE_STATIC_VERTEX_SHADER( debugluxel_vs20 ); - SET_STATIC_VERTEX_SHADER( debugluxel_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( debugluxel_ps20b ); - SET_STATIC_PIXEL_SHADER( debugluxel_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( debugluxel_ps20 ); - SET_STATIC_PIXEL_SHADER( debugluxel_ps20 ); - } - - SetDefaultBlendingShadowState( BASETEXTURE ); - DisableFog(); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, NULL, 0 ); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - int texCoordScaleX = 1, texCoordScaleY = 1; - if (!params[NOSCALE]->GetIntValue()) - { - pShaderAPI->GetLightmapDimensions( &texCoordScaleX, &texCoordScaleY ); - } - - DECLARE_DYNAMIC_VERTEX_SHADER( debugluxel_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( debugluxel_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugluxel_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( debugluxel_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugluxel_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( debugluxel_ps20 ); - } - - //texture scale transform - Vector4D transformation[2]; - transformation[0].Init( texCoordScaleX, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, texCoordScaleY, 0.0f, 0.0f ); - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/debugluxel_ps2x.fxc b/materialsystem/stdshaders/debugluxel_ps2x.fxc deleted file mode 100644 index 81c8ae00..00000000 --- a/materialsystem/stdshaders/debugluxel_ps2x.fxc +++ /dev/null @@ -1,15 +0,0 @@ -#include "common_ps_fxc.h" - -sampler TextureSampler : register( s0 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 result = tex2D( TextureSampler, i.baseTexCoord ); - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} - diff --git a/materialsystem/stdshaders/debugluxel_vs20.fxc b/materialsystem/stdshaders/debugluxel_vs20.fxc deleted file mode 100644 index 3edee90b..00000000 --- a/materialsystem/stdshaders/debugluxel_vs20.fxc +++ /dev/null @@ -1,40 +0,0 @@ -#include "common_vs_fxc.h" - -const float4 cLightmapTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); - -struct VS_INPUT -{ - float3 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; - float2 vLightmapTexCoord : TEXCOORD1; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 baseTexCoord : TEXCOORD0; -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 projPos; - float3 worldPos; - - worldPos = mul4x3( float4( v.vPos, 1 ), cModel[0] ); - projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - - o.baseTexCoord.x = dot( v.vLightmapTexCoord, cLightmapTexCoordTransform[0].xy ) + cLightmapTexCoordTransform[0].w; - o.baseTexCoord.y = dot( v.vLightmapTexCoord, cLightmapTexCoordTransform[1].xy ) + cLightmapTexCoordTransform[1].w; - -#ifdef _PS3 - // Account for OpenGL's flipped y coordinate and expanded z range [-1,1] instead of [0,1] - o.projPos.y = -o.projPos.y; - o.projPos.z = 2.0f * o.projPos.z - o.projPos.w; -#endif // _PS3 - - return o; -} diff --git a/materialsystem/stdshaders/debugmodifyvertex.cpp b/materialsystem/stdshaders/debugmodifyvertex.cpp deleted file mode 100644 index c497ca95..00000000 --- a/materialsystem/stdshaders/debugmodifyvertex.cpp +++ /dev/null @@ -1,93 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: This is an example of a material that modifies vertex data -// in the shader. NOTE: Every pass is given a clean set of vertex data. -// Modifications made in the first pass are *not* carried over to the next pass -// Modifications must take place during the DYNAMIC_STATE block. -// Use the function MeshBuilder() to build the mesh -// -// Also note: Using thie feature is *really expensive*! It makes a copy of -// the vertex data *per pass!* If you wish to modify vertex data to be used -// with all passes, your best bet is to construct a dynamic mesh instead. -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_SHADER_FLAGS( DebugModifyVertex, "Help for DebugModifyVertex", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( WAVE, SHADER_PARAM_TYPE_FLOAT, "1.0", "wave amplitude" ) - END_SHADER_PARAMS - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - if( g_pHardwareConfig->GetSamplerCount() >= 2 ) - { - // lightmap - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableVertexDataPreprocess( true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - float amp = params[WAVE]->GetFloatValue(); - float currTime = pShaderAPI->CurrentTime(); - for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) - { - float const* pPos = MeshBuilder()->Position(); - MeshBuilder()->Position3f( pPos[0] + amp * sin( currTime + pPos[2] / 4 ), - pPos[1] + amp * sin( currTime + pPos[2] / 4 + 2 * 3.14 / 3 ), - pPos[2] + amp * sin( currTime + pPos[2] / 4 + 4 * 3.14 / 3 ) ); - MeshBuilder()->AdvanceVertex(); - } - } - Draw(); - - // base * vertex color - SHADOW_STATE - { - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | - SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - // Notice here that since we didn't modify the position, and this is a second - // pass, the position has been reset to it's initial, unmodified position - float currTime = pShaderAPI->CurrentTime(); - for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) - { - float const* pPos = MeshBuilder()->Position(); - MeshBuilder()->Color3f( ( sin( currTime + pPos[0] ) + 1.0F) * 0.5, - ( sin( currTime + pPos[1] ) + 1.0F) * 0.5, - ( sin( currTime + pPos[2] ) + 1.0F) * 0.5 ); - MeshBuilder()->AdvanceVertex(); - } - } - Draw(); - } - else - { - ShaderWarning( "DebugModifyVertex: not " - "implemented for single-texturing hardware\n" ); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp b/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp deleted file mode 100644 index 2f5c6a8e..00000000 --- a/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "debugmorphaccumulator_ps30.inc" -#include "debugmorphaccumulator_vs30.inc" - -BEGIN_VS_SHADER_FLAGS( DebugMorphAccumulator, "Help for Debug Morph Accumulator", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthTest( false ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableCulling( false ); - pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBWrite( false ); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); - SET_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); - SET_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE ); - - DECLARE_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); - SET_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc b/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc deleted file mode 100644 index b479085c..00000000 --- a/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc +++ /dev/null @@ -1,16 +0,0 @@ -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float2 vTexCoord : TEXCOORD0; -}; - -sampler MorphAccumulator : register( s0 ); - -HALF4 main( PS_INPUT i ) : COLOR -{ - float4 vDeltas = tex2D( MorphAccumulator, i.vTexCoord ); - return float4( abs( vDeltas.x ), abs( vDeltas.z ), abs( vDeltas.y ) + abs( vDeltas.w ), 1.0f ); -} - diff --git a/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc b/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc deleted file mode 100644 index 4ff8a742..00000000 --- a/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc +++ /dev/null @@ -1,23 +0,0 @@ -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vTexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vTexCoord : TEXCOORD0; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.vProjPos = mul( v.vPos, cModelViewProj ); - o.vTexCoord = v.vTexCoord; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/debugmrttexture.cpp b/materialsystem/stdshaders/debugmrttexture.cpp deleted file mode 100644 index 04a1128e..00000000 --- a/materialsystem/stdshaders/debugmrttexture.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "debugmrttexture_ps20.inc" -#include "debugmrttexture_ps20b.inc" -#include "debugmrttexture_vs20.inc" - -BEGIN_VS_SHADER_FLAGS( DebugMRTTexture, "Help for DebugMRTTexture", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( MRTINDEX, SHADER_PARAM_TYPE_INTEGER, "", "" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { -// if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) -// { -// return "UnlitGeneric_DX8"; -// } - return 0; - } - - SHADER_INIT_PARAMS() - { - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - DECLARE_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); - SET_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); - } - - int numTexCoords = 2; - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, numTexCoords, 0, 0 ); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - DECLARE_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); - } - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/debugmrttexture_ps2x.fxc b/materialsystem/stdshaders/debugmrttexture_ps2x.fxc deleted file mode 100644 index 7764e529..00000000 --- a/materialsystem/stdshaders/debugmrttexture_ps2x.fxc +++ /dev/null @@ -1,26 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "MRTINDEX" "0..1" - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; -}; - -sampler BaseTextureSampler1 : register( s0 ); -sampler BaseTextureSampler2 : register( s1 ); - -float4 main( PS_INPUT i ) : COLOR -{ -#if MRTINDEX == 0 - float4 result = tex2D( BaseTextureSampler1, i.baseTexCoord ); -#else - float4 result = tex2D( BaseTextureSampler2, i.baseTexCoord ); -#endif - - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} - diff --git a/materialsystem/stdshaders/debugmrttexture_vs20.fxc b/materialsystem/stdshaders/debugmrttexture_vs20.fxc deleted file mode 100644 index db5c4863..00000000 --- a/materialsystem/stdshaders/debugmrttexture_vs20.fxc +++ /dev/null @@ -1,29 +0,0 @@ -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float3 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - float2 baseTexCoord : TEXCOORD0; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 projPos; - float3 worldPos; - - projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); - o.projPos = projPos; - - o.baseTexCoord = v.vBaseTexCoord; - return o; -} - - diff --git a/materialsystem/stdshaders/debugnormalmap.cpp b/materialsystem/stdshaders/debugnormalmap.cpp deleted file mode 100644 index 0be5246a..00000000 --- a/materialsystem/stdshaders/debugnormalmap.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. - - - -#ifdef USE_NEW_SHADER - -#include "unlitgeneric_vs20.inc" -#include "unlitgeneric_ps20.inc" -#include "unlitgeneric_ps20b.inc" - -#endif - -#include "unlitgeneric_vs11.inc" - - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER_FLAGS( DebugNormalMap, "Help for DebugNormalMap", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldDiffuseBumpMap_bump", "bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 80 ) - { -// Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, 0 ); - SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); - } - } - else -#endif - { - unlitgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( false ); - vshIndex.SetENVMAP( false ); - vshIndex.SetENVMAPCAMERASPACE( false ); - vshIndex.SetENVMAPSPHERE( false ); - vshIndex.SetVERTEXCOLOR( false ); - vshIndex.SetSEPARATEDETAILUVS( false ); - pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "unlitgeneric" ); - } - } - DYNAMIC_STATE - { - if ( params[BUMPMAP]->IsTexture() ) - { - BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); - } - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - float vVertexColor[4] = { 0, 0, 0, 0 }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); - } - } - else -#endif - { - unlitgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/debugsoftwarevertexshader.cpp b/materialsystem/stdshaders/debugsoftwarevertexshader.cpp deleted file mode 100644 index be7cedf3..00000000 --- a/materialsystem/stdshaders/debugsoftwarevertexshader.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ) -{ - float t = pShaderAPI->CurrentTime(); - for( int i = 0; i < meshBuilder.NumVertices(); i++ ) - { - const float *pPos = meshBuilder.Position(); - meshBuilder.Position3f( pPos[0], pPos[1], pPos[2] + 10.0f * sin( t + pPos[0] ) ); - meshBuilder.AdvanceVertex(); - } -} - -FORWARD_DECLARE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); - -BEGIN_SHADER_FLAGS( DebugSoftwareVertexShader, "blah", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) - END_SHADER_PARAMS - - SHADER_INIT - { - if( g_pHardwareConfig->SupportsVertexAndPixelShaders() ) - { - USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); - } - else - { - USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); - } - } - SHADER_DRAW - { - SHADOW_STATE - { - } - DYNAMIC_STATE - { - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/debugtangentspace.cpp b/materialsystem/stdshaders/debugtangentspace.cpp deleted file mode 100644 index 30279012..00000000 --- a/materialsystem/stdshaders/debugtangentspace.cpp +++ /dev/null @@ -1,133 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. - -#ifdef USE_NEW_SHADER -#include "debugtangentspace_vs11.inc" -#include "debugtangentspace_vs20.inc" -#include "unlitgeneric_notexture_ps11.inc" -#include "unlitgeneric_notexture_ps20.inc" -#include "unlitgeneric_notexture_ps20b.inc" - -#else -#include "debugtangentspace.inc" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_SHADER( DebugTangentSpace, "Help for DebugTangentSpace" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - if (g_pHardwareConfig->SupportsVertexAndPixelShaders()) - { - SHADOW_STATE - { - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 0; - int userDataSize = 4; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); - SET_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); - } - } - else - { - DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); - SET_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); - - DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); - SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); - } -#else - debugtangentspace_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "DebugTangentSpace", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "UnlitGeneric_NoTexture" ); -#endif - } - DYNAMIC_STATE - { - -#ifdef USE_NEW_SHADER - if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) - { - DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); - } - } - else // legacy hardware - { - DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); - SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); - } -#else - debugtangentspace_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); -#endif - } - Draw(); - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/debugtangentspace.vsh b/materialsystem/stdshaders/debugtangentspace.vsh deleted file mode 100644 index cb38a23b..00000000 --- a/materialsystem/stdshaders/debugtangentspace.vsh +++ /dev/null @@ -1,34 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -&AllocateRegister( \$worldNormal ); -&SkinPositionAndNormal( $worldPos, $worldNormal ); - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -&FreeRegister( \$worldPos ); - -; stick the normal in the color channel -mov oD0.xyz, $worldNormal.xyz -mov oD0.w, $cOne ; make sure all components are defined - -&FreeRegister( \$projPos ); -&FreeRegister( \$worldNormal ); diff --git a/materialsystem/stdshaders/debugtangentspace_vs11.fxc b/materialsystem/stdshaders/debugtangentspace_vs11.fxc deleted file mode 100644 index 1584ef26..00000000 --- a/materialsystem/stdshaders/debugtangentspace_vs11.fxc +++ /dev/null @@ -1,51 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float3 vNormal : NORMAL; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - - float4 vDiffuse : COLOR0; - - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos, worldNormal; - SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - - o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - - o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - // stick the normal in the color channel - o.vDiffuse.rgb = worldNormal; - o.vDiffuse.a = 1.0f; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/debugtangentspace_vs20.fxc b/materialsystem/stdshaders/debugtangentspace_vs20.fxc deleted file mode 100644 index f829bde9..00000000 --- a/materialsystem/stdshaders/debugtangentspace_vs20.fxc +++ /dev/null @@ -1,55 +0,0 @@ -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - - float4 vDiffuse : COLOR0; - - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - float3 worldPos, worldNormal; - SkinPositionAndNormal( g_bSkinning, v.vPos, vObjNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - - o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - - o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - // stick the normal in the color channel - o.vDiffuse.rgb = worldNormal; - o.vDiffuse.a = 1.0f; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/decalmodulate.cpp b/materialsystem/stdshaders/decalmodulate.cpp new file mode 100644 index 00000000..341f43f4 --- /dev/null +++ b/materialsystem/stdshaders/decalmodulate.cpp @@ -0,0 +1,246 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "cpp_shader_constant_register_map.h" +#include "sdk_decalmodulate_vs30.inc" +#include "sdk_decalmodulate_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef MAPBASE +ConVar mat_decalmodulate_flashdraw( "mat_decalmodulate_flashdraw", "0" ); +#endif + +BEGIN_VS_SHADER( DecalModulate, "Help for DecalModulate" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( FOGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "0.4", "exponent to tweak fog fade" ) + SHADER_PARAM( FOGSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale to tweak fog fade" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT_PARAMS() + { + if( !params[ FOGEXPONENT ]->IsDefined() ) + { + params[ FOGEXPONENT ]->SetFloatValue( 0.4f ); + } + + if( !params[ FOGSCALE ]->IsDefined() ) + { + params[ FOGSCALE ]->SetFloatValue( 1.0f ); + } + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + +#ifndef _X360 + if ( g_pHardwareConfig->HasFastVertexTextures() ) + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } +#endif + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { +#ifdef MAPBASE + // It is now believed the decals not appearing is a sorting issue. + // The flashlight part is transparent and overlaid on top of the decal. + // When a fix is found, this flashlight code could be removed. + bool bHasFlashlight = UsingFlashlight( params ); + if (bHasFlashlight && !mat_decalmodulate_flashdraw.GetBool()) + return; +#endif + SHADOW_STATE + { + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + //SRGB conversions hose the blend on some hardware, so keep everything in gamma space. + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + pShaderShadow->EnableSRGBWrite( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); + pShaderShadow->DisableFogGammaCorrection( true ); //fog should stay exactly middle grey + FogToGrey(); + +#ifdef MAPBASE + int userDataSize = 0; + int nShadowFilterMode = 0; + if ( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + userDataSize = 4; // tangent S + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + } +#endif + + bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) && IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_decalmodulate_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, false ); +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_decalmodulate_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_decalmodulate_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXALPHA, bHasVertexAlpha ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_decalmodulate_ps30 ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + + if ( bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } + + // The VS30 shader offsets decals along the normal (for morphed geom) + flags |= g_pHardwareConfig->HasFastVertexTextures() ? VERTEX_NORMAL : 0; + + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; +#ifndef MAPBASE + int userDataSize = 0; +#endif + + if ( g_pHardwareConfig->HasFastVertexTextures() ) + { +#ifdef MAPBASE + if (nTexCoordCount == 0) + nTexCoordCount = 3; +#else + nTexCoordCount = 3; +#endif + } + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + } + DYNAMIC_STATE + { +#ifdef MAPBASE // This fixes blood decals, etc. not showing up under flashlights. + //bHasFlashlight = pShaderAPI->InFlashlightMode(); + bool bFlashlightShadows = false; + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); + } + + SetFlashLightColorFromState( state, pShaderAPI, 28 ); + + Assert( state.m_pSpotlightTexture && state.m_nSpotlightTextureFrame >= 0 ); + BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + + float atten_pos[8]; + atten_pos[0] = state.m_fConstantAtten; // Set the flashlight attenuation factors + atten_pos[1] = state.m_fLinearAtten; + atten_pos[2] = state.m_fQuadraticAtten; + atten_pos[3] = state.m_FarZ; + atten_pos[4] = state.m_vecLightOrigin[0]; // Set the flashlight origin + atten_pos[5] = state.m_vecLightOrigin[1]; + atten_pos[6] = state.m_vecLightOrigin[2]; + atten_pos[7] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 22, atten_pos, 2 ); + + pShaderAPI->SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); + } + + //if ( pShaderAPI->InFlashlightMode() && mat_decalmodulate_noflashdraw.GetBool() ) +#else + if ( pShaderAPI->InFlashlightMode() && !IsX360() ) + { + // Don't draw anything for the flashlight pass + Draw( false ); + return; + } +#endif + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // Set an identity base texture transformation + Vector4D transformation[2]; + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + // fog tweaks + float fConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + fConsts[0] = params[ FOGEXPONENT ]->GetFloatValue(); + fConsts[1] = params[ FOGSCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 0, fConsts ); + + + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_decalmodulate_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_decalmodulate_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_decalmodulate_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); +#ifdef MAPBASE + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +#endif + SET_DYNAMIC_PIXEL_SHADER( sdk_decalmodulate_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + Draw( ); + } +END_SHADER diff --git a/materialsystem/stdshaders/deferred/deferred_CSM.cpp b/materialsystem/stdshaders/deferred/deferred_CSM.cpp deleted file mode 100644 index 76458608..00000000 --- a/materialsystem/stdshaders/deferred/deferred_CSM.cpp +++ /dev/null @@ -1,187 +0,0 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "deferred_composite_vs30.inc" -#include "deferred_CSM_ps30.inc" - -#include "IDeferredExt.h" - -ConVar csm_enabled("r_csm", "1", 0, "0 = off, 1 = on/force"); -ConVar r_csm_bias("r_csm_post_bias", "0.0"); -ConVar r_csm_slopescalebias("r_csm_post_slopescale_depthbias", "1"); - -BEGIN_VS_SHADER_FLAGS(deferred_CSM, "Help for Bloom", SHADER_NOT_EDITABLE) -BEGIN_SHADER_PARAMS -SHADER_PARAM(FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "") -SHADER_PARAM(ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "_rt_defAlbedo", "") -SHADER_PARAM(POSITION, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPosition", "") -SHADER_PARAM(NORMAL, SHADER_PARAM_TYPE_TEXTURE, "_rt_defNormal", "") -SHADER_PARAM(MR, SHADER_PARAM_TYPE_TEXTURE, "_rt_defMR", "") -SHADER_PARAM(AO, SHADER_PARAM_TYPE_TEXTURE, "_rt_SSGIFB1", "") -SHADER_PARAM(DEPTH, SHADER_PARAM_TYPE_TEXTURE, "_rt_DepthBuffer", "") -END_SHADER_PARAMS -SHADER_INIT_PARAMS() -{ - params[FBTEXTURE]->SetStringValue("_rt_FullFrameFB"); - params[AO]->SetStringValue("_rt_SSGIFB"); - params[ALBEDO]->SetStringValue("_rt_defAlbedo"); - params[POSITION]->SetStringValue("_rt_defPosition"); - params[NORMAL]->SetStringValue("_rt_defNormal"); - params[MR]->SetStringValue("_rt_defMR"); - params[DEPTH]->SetStringValue("_rt_DepthBuffer"); -} - -SHADER_INIT -{ - if (params[FBTEXTURE]->IsDefined()) - { - LoadTexture(FBTEXTURE); - } - if (params[ALBEDO]->IsDefined()) - { - LoadTexture(ALBEDO); - } - if (params[POSITION]->IsDefined()) - { - LoadTexture(POSITION); - } - if (params[NORMAL]->IsDefined()) - { - LoadTexture(NORMAL); - } - if (params[MR]->IsDefined()) - { - LoadTexture(MR); - } - if (params[AO]->IsDefined()) - { - LoadTexture(AO); - } - if (params[DEPTH]->IsDefined()) - { - LoadTexture(DEPTH); - } -} - -SHADER_FALLBACK -{ - // Requires DX9 + above - if (g_pHardwareConfig->GetDXSupportLevel() < 90) - { - Assert(0); - return "Wireframe"; - } - return 0; -} - -SHADER_DRAW -{ - - SHADOW_STATE - { - pShaderShadow->SetDefaultState(); - - pShaderShadow->EnableDepthTest(false); - - EnableAlphaBlending(SHADER_BLEND_ONE, SHADER_BLEND_ONE); - - pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER3, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER4, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER5, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER6, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER(deferred_composite_vs30); - SET_STATIC_VERTEX_SHADER(deferred_composite_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER(deferred_csm_ps30); - SET_STATIC_PIXEL_SHADER(deferred_csm_ps30); - } - } - - DYNAMIC_STATE - { - - ITexture* pCascadedDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE); - - if (!pCascadedDepthTexture) - { - Draw(false); - return; - } - pShaderAPI->SetDefaultState(); - BindTexture(SHADER_SAMPLER0, FBTEXTURE, -1); - BindTexture(SHADER_SAMPLER1, ALBEDO, -1); - BindTexture(SHADER_SAMPLER2, POSITION, -1); - BindTexture(SHADER_SAMPLER3, NORMAL, -1); - BindTexture(SHADER_SAMPLER4, MR, -1); - BindTexture(SHADER_SAMPLER5, AO, -1); - BindTexture(SHADER_SAMPLER6, DEPTH, -1); - - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions(nWidth, nHeight); - float fResolution[4]; - fResolution[0] = float(nWidth); - fResolution[1] = float(nHeight); - pShaderAPI->SetPixelShaderConstant(1, fResolution); - - // Set Pixel Shader Constants - pShaderAPI->SetPixelShaderConstant(2, GetDeferredExt()->GetOriginBase()); - - float flZDists[2]; - flZDists[0] = GetDeferredExt()->GetZDistNear(); - flZDists[1] = GetDeferredExt()->GetZDistFar(); - flZDists[2] = GetDeferredExt()->GetZScale(); - pShaderAPI->SetPixelShaderConstant(3, flZDists); - - - if (pCascadedDepthTexture) - { - BindTexture(SHADER_SAMPLER7, pCascadedDepthTexture, -1); - VMatrix* worldToTexture0 = (VMatrix*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0); - pShaderAPI->SetPixelShaderConstant(4, worldToTexture0->Base(), 4); - } - - lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); - Vector csmFwd = csmData.vecLight; - pShaderAPI->SetPixelShaderConstant(8, csmFwd.Base()); - - Vector csmLight = csmData.light.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(9, csmLight.Base()); - - Vector csmAmbient = csmData.ambient.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(10, csmAmbient.Base()); - - float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; - pShaderAPI->SetPixelShaderConstant(11, biasVar); - - float textureSize[2] = { pCascadedDepthTexture->GetMappingHeight() * 4.0f, pCascadedDepthTexture->GetMappingHeight() }; - pShaderAPI->SetPixelShaderConstant(12, textureSize); - - pShaderAPI->SetPixelShaderConstant(13, GetDeferredExt()->GetLightData_Global().sizes.Base()); - - DECLARE_DYNAMIC_VERTEX_SHADER(deferred_composite_vs30); - SET_DYNAMIC_VERTEX_SHADER(deferred_composite_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(deferred_csm_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO(AMBIENT, 0); - SET_DYNAMIC_PIXEL_SHADER(deferred_csm_ps30); - - } - Draw(); -} -END_SHADER diff --git a/materialsystem/stdshaders/deferred/deferred_csm.cpp b/materialsystem/stdshaders/deferred/deferred_csm.cpp new file mode 100644 index 00000000..5c943dc9 --- /dev/null +++ b/materialsystem/stdshaders/deferred/deferred_csm.cpp @@ -0,0 +1,187 @@ +//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" + +#include "deferred_composite_vs30.inc" +#include "deferred_CSM_ps30.inc" + +#include "IDeferredExt.h" + +ConVar csm_enabled("r_csm", "1", 0, "0 = off, 1 = on/force"); +ConVar r_csm_bias("r_csm_post_bias", "0.0"); +ConVar r_csm_slopescalebias("r_csm_post_slopescale_depthbias", "1"); + +BEGIN_VS_SHADER_FLAGS(deferred_CSM, "Help for Bloom", SHADER_NOT_EDITABLE) +BEGIN_SHADER_PARAMS +SHADER_PARAM(FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "") +SHADER_PARAM(ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "_rt_defAlbedo", "") +SHADER_PARAM(POSITION, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPosition", "") +SHADER_PARAM(NORMAL, SHADER_PARAM_TYPE_TEXTURE, "_rt_defNormal", "") +SHADER_PARAM(MR, SHADER_PARAM_TYPE_TEXTURE, "_rt_defMR", "") +SHADER_PARAM(AO, SHADER_PARAM_TYPE_TEXTURE, "_rt_SSGIFB1", "") +SHADER_PARAM(DEPTH, SHADER_PARAM_TYPE_TEXTURE, "_rt_DepthBuffer", "") +END_SHADER_PARAMS +SHADER_INIT_PARAMS() +{ + params[FBTEXTURE]->SetStringValue("_rt_FullFrameFB"); + params[AO]->SetStringValue("_rt_SSGIFB"); + params[ALBEDO]->SetStringValue("_rt_defAlbedo"); + params[POSITION]->SetStringValue("_rt_defPosition"); + params[NORMAL]->SetStringValue("_rt_defNormal"); + params[MR]->SetStringValue("_rt_defMR"); + params[DEPTH]->SetStringValue("_rt_DepthBuffer"); +} + +SHADER_INIT +{ + if (params[FBTEXTURE]->IsDefined()) + { + LoadTexture(FBTEXTURE); + } + if (params[ALBEDO]->IsDefined()) + { + LoadTexture(ALBEDO); + } + if (params[POSITION]->IsDefined()) + { + LoadTexture(POSITION); + } + if (params[NORMAL]->IsDefined()) + { + LoadTexture(NORMAL); + } + if (params[MR]->IsDefined()) + { + LoadTexture(MR); + } + if (params[AO]->IsDefined()) + { + LoadTexture(AO); + } + if (params[DEPTH]->IsDefined()) + { + LoadTexture(DEPTH); + } +} + +SHADER_FALLBACK +{ + // Requires DX9 + above + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + { + Assert(0); + return "Wireframe"; + } + return 0; +} + +SHADER_DRAW +{ + + SHADOW_STATE + { + pShaderShadow->SetDefaultState(); + + pShaderShadow->EnableDepthTest(false); + + EnableAlphaBlending(SHADER_BLEND_ONE, SHADER_BLEND_ONE); + + pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER3, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER4, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER5, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER6, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER(deferred_composite_vs30); + SET_STATIC_VERTEX_SHADER(deferred_composite_vs30); + + //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER(deferred_csm_ps30); + SET_STATIC_PIXEL_SHADER(deferred_csm_ps30); + } + } + + DYNAMIC_STATE + { + + ITexture* pCascadedDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE); + + if (!pCascadedDepthTexture) + { + Draw(false); + return; + } + pShaderAPI->SetDefaultState(); + BindTexture(SHADER_SAMPLER0, FBTEXTURE, -1); + BindTexture(SHADER_SAMPLER1, ALBEDO, -1); + BindTexture(SHADER_SAMPLER2, POSITION, -1); + BindTexture(SHADER_SAMPLER3, NORMAL, -1); + BindTexture(SHADER_SAMPLER4, MR, -1); + BindTexture(SHADER_SAMPLER5, AO, -1); + BindTexture(SHADER_SAMPLER6, DEPTH, -1); + + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions(nWidth, nHeight); + float fResolution[4]; + fResolution[0] = float(nWidth); + fResolution[1] = float(nHeight); + pShaderAPI->SetPixelShaderConstant(1, fResolution); + + // Set Pixel Shader Constants + pShaderAPI->SetPixelShaderConstant(2, GetDeferredExt()->GetOriginBase()); + + float flZDists[2]; + flZDists[0] = GetDeferredExt()->GetZDistNear(); + flZDists[1] = GetDeferredExt()->GetZDistFar(); + flZDists[2] = GetDeferredExt()->GetZScale(); + pShaderAPI->SetPixelShaderConstant(3, flZDists); + + + if (pCascadedDepthTexture) + { + BindTexture(SHADER_SAMPLER7, pCascadedDepthTexture, -1); + VMatrix* worldToTexture0 = (VMatrix*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0); + pShaderAPI->SetPixelShaderConstant(4, worldToTexture0->Base(), 4); + } + + lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); + Vector csmFwd = csmData.vecLight; + pShaderAPI->SetPixelShaderConstant(8, csmFwd.Base()); + + Vector csmLight = csmData.light.AsVector3D(); + pShaderAPI->SetPixelShaderConstant(9, csmLight.Base()); + + Vector csmAmbient = csmData.ambient.AsVector3D(); + pShaderAPI->SetPixelShaderConstant(10, csmAmbient.Base()); + + float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; + pShaderAPI->SetPixelShaderConstant(11, biasVar); + + float textureSize[2] = { pCascadedDepthTexture->GetMappingHeight() * 4.0f, pCascadedDepthTexture->GetMappingHeight() }; + pShaderAPI->SetPixelShaderConstant(12, textureSize); + + pShaderAPI->SetPixelShaderConstant(13, GetDeferredExt()->GetLightData_Global().sizes.Base()); + + DECLARE_DYNAMIC_VERTEX_SHADER(deferred_composite_vs30); + SET_DYNAMIC_VERTEX_SHADER(deferred_composite_vs30); + + DECLARE_DYNAMIC_PIXEL_SHADER(deferred_csm_ps30); + SET_DYNAMIC_PIXEL_SHADER_COMBO(AMBIENT, 0); + SET_DYNAMIC_PIXEL_SHADER(deferred_csm_ps30); + + } + Draw(); +} +END_SHADER diff --git a/materialsystem/stdshaders/deferred/deferred_pointlights.cpp b/materialsystem/stdshaders/deferred/deferred_pointlights.cpp index ee874db1..fa830a13 100644 --- a/materialsystem/stdshaders/deferred/deferred_pointlights.cpp +++ b/materialsystem/stdshaders/deferred/deferred_pointlights.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "deferred_composite_vs30.inc" #include "deferred_pointlights_ps30.inc" diff --git a/materialsystem/stdshaders/deferred/deferred_sky.cpp b/materialsystem/stdshaders/deferred/deferred_sky.cpp index a958a6a7..2c0d1f3b 100644 --- a/materialsystem/stdshaders/deferred/deferred_sky.cpp +++ b/materialsystem/stdshaders/deferred/deferred_sky.cpp @@ -1,11 +1,11 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "deferred_composite_vs30.inc" #include "deferred_sky_ps30.inc" diff --git a/materialsystem/stdshaders/deferred/deferred_volumetricfog.cpp b/materialsystem/stdshaders/deferred/deferred_volumetricfog.cpp index a2dc5406..3050e5a3 100644 --- a/materialsystem/stdshaders/deferred/deferred_volumetricfog.cpp +++ b/materialsystem/stdshaders/deferred/deferred_volumetricfog.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "deferred_composite_vs30.inc" #include "deferred_volumetricfog_ps30.inc" diff --git a/materialsystem/stdshaders/deferred/gbuffer_helper.cpp b/materialsystem/stdshaders/deferred/gbuffer_helper.cpp index d6fc3e47..c0774a2a 100644 --- a/materialsystem/stdshaders/deferred/gbuffer_helper.cpp +++ b/materialsystem/stdshaders/deferred/gbuffer_helper.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ // //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" #include "cpp_shader_constant_register_map.h" #include "gbuffer_vs30.inc" diff --git a/materialsystem/stdshaders/deferred/gbuffer_mesh.cpp b/materialsystem/stdshaders/deferred/gbuffer_mesh.cpp index 1189fae3..c3cc5232 100644 --- a/materialsystem/stdshaders/deferred/gbuffer_mesh.cpp +++ b/materialsystem/stdshaders/deferred/gbuffer_mesh.cpp @@ -4,7 +4,7 @@ // //================================================================================================== -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" #include "globallight_mesh_helper.h" diff --git a/materialsystem/stdshaders/deferred/IDeferredExt.cpp b/materialsystem/stdshaders/deferred/ideferredext.cpp similarity index 100% rename from materialsystem/stdshaders/deferred/IDeferredExt.cpp rename to materialsystem/stdshaders/deferred/ideferredext.cpp diff --git a/materialsystem/stdshaders/deferred_CSM_ps30.fxc b/materialsystem/stdshaders/deferred_CSM_ps30.fxc deleted file mode 100644 index b97680f8..00000000 --- a/materialsystem/stdshaders/deferred_CSM_ps30.fxc +++ /dev/null @@ -1,155 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" -#include "common_flashlight_fxc.h" -#include "common_pbr.h" -#include "common_deferred.h" -#include "deferred_shadows.h" - -#define PI 3.1415926 - -sampler FBSampler : register( s0 ); -sampler AlbedoSampler : register( s1 ); -sampler ViewPosSampler : register( s2 ); -sampler ViewNormalSampler : register( s3 ); -sampler MetallicRoughnessSampler : register( s4 ); -sampler AOSampler : register( s5 ); -sampler DepthSampler : register( s6 ); -sampler ShadowDepthSampler : register( s7 ); - -const float2 g_resolution : register( c1 ); -const float3 g_EyePos : register( c2 ); -const float3 g_ZDist : register( c3 ); -const float4x4 g_FlashlightWorldToTexture : register( c4 ); -const float4 g_CascadeFwd : register( c8 ); -const float4 g_CascadeLight : register( c9 ); -const float4 g_CascadeAmbient : register( c10 ); - -const float2 g_CascadeBias : register( c11 ); -const float2 g_CascadeResolution : register( c12 ); -const float4 g_CascadeSize : register( c13 ); - -#define SLOPESCALE g_CascadeBias.x -#define DEPTHBIAS g_CascadeBias.y - -#define CascadeSize g_CascadeResolution - -float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) -{ - float2 rtSize = CascadeSize;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; - float fEpsilonX = 1.0f / rtSize.y; - float fEpsilonY = 1.0f / rtSize.x; - - float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); - float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); - float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); - float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); - - float projMask = 1.0f; - if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) - { - projMask = 0.0f; - } - - float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); - - float shadowProjDiff0 = 1; - float3 shadowMapCenter_objDepth0 = cascade0; - float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; - float objDepth0 = shadowMapCenter_objDepth0.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff0; - float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); - - float shadowProjDiff1 = g_CascadeSize.y; - float3 shadowMapCenter_objDepth1 = cascade1; - float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; - float objDepth1 = shadowMapCenter_objDepth1.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff1; - float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); - - float shadowProjDiff2 = g_CascadeSize.z; - float3 shadowMapCenter_objDepth2 = cascade2; - float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; - float objDepth2 = shadowMapCenter_objDepth2.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff2; - float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); - - float shadowProjDiff3 = g_CascadeSize.w; - float3 shadowMapCenter_objDepth3 = cascade3; - float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; - float objDepth3 = shadowMapCenter_objDepth3.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff3; - float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); - - float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); - float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); - float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); - - /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); - float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); - float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); - float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); - - float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); - float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); - float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); - float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ - - - float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); - float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); - float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); - - float shadow = shadow0123; - - if(projMask == 1.0f) - { - float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); - float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); - return shadowFinal; - } - else - { - return 1.0f; - } - -} - -float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) -{ - float3 Out; - float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); - float4 flashlightSpacePosition = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); - float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); - diffuse = saturate(diffuse); - - - Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); - return Out; -} - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; - float4x4 viewProj : TEXCOORD2; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float3 fbSample = tex2D( FBSampler, i.texCoord ).rgb; - float3 AlbedoSample = tex2D( AlbedoSampler, i.texCoord ).rgb; - float3 worldPos = tex2D( ViewPosSampler, i.texCoord ).rgb + g_EyePos; - float3 worldNormal = tex2D( ViewNormalSampler, i.texCoord ).rgb; - worldNormal = unpackNormals(worldNormal); - float3 metallicRoughnessDepth = tex2D( MetallicRoughnessSampler, i.texCoord ).rgb; - float3 AOSample = tex2D( AOSampler, i.texCoord ).rgb; // Samples - float depth = metallicRoughnessDepth.z; - float ProjectionDepth = depth * (g_ZDist.y / g_ZDist.x); - - float3 ambient = DoAmbient(i.texCoord, worldPos, worldNormal, g_EyePos, metallicRoughnessDepth.y, AlbedoSample, g_CascadeAmbient, g_CascadeLight / (PI * PI)); - - float3 lighting = DoPBRCSM(worldPos, worldNormal, AlbedoSample, metallicRoughnessDepth.x, metallicRoughnessDepth.y, length(worldPos - g_EyePos)); - - return FinalOutput( float4( lighting + ambient, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/deferred_composite_ps30.fxc b/materialsystem/stdshaders/deferred_composite_ps30.fxc index 9d39697b..c7d6d8ba 100644 --- a/materialsystem/stdshaders/deferred_composite_ps30.fxc +++ b/materialsystem/stdshaders/deferred_composite_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" diff --git a/materialsystem/stdshaders/deferred_csm_ps30.fxc b/materialsystem/stdshaders/deferred_csm_ps30.fxc new file mode 100644 index 00000000..1775fea2 --- /dev/null +++ b/materialsystem/stdshaders/deferred_csm_ps30.fxc @@ -0,0 +1,154 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_pbr.h" +#include "common_deferred.h" +#include "common_deferredshadows_fxc.h" + +#define PI 3.1415926 + +sampler FBSampler : register( s0 ); +sampler AlbedoSampler : register( s1 ); +sampler ViewPosSampler : register( s2 ); +sampler ViewNormalSampler : register( s3 ); +sampler MetallicRoughnessSampler : register( s4 ); +sampler AOSampler : register( s5 ); +sampler DepthSampler : register( s6 ); +sampler ShadowDepthSampler : register( s7 ); + +const float2 g_resolution : register( c1 ); +const float3 g_EyePos : register( c2 ); +const float3 g_ZDist : register( c3 ); +const float4x4 g_FlashlightWorldToTexture : register( c4 ); +const float4 g_CascadeFwd : register( c8 ); +const float4 g_CascadeLight : register( c9 ); +const float4 g_CascadeAmbient : register( c10 ); + +const float2 g_CascadeBias : register( c11 ); +const float2 g_CascadeResolution : register( c12 ); +const float4 g_CascadeSize : register( c13 ); + +#define SLOPESCALE g_CascadeBias.x +#define DEPTHBIAS g_CascadeBias.y + +#define CascadeSize g_CascadeResolution + +float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) +{ + float2 rtSize = CascadeSize;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; + float fEpsilonX = 1.0f / rtSize.y; + float fEpsilonY = 1.0f / rtSize.x; + + float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); + float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); + float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); + float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); + + float projMask = 1.0f; + if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) + { + projMask = 0.0f; + } + + float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); + + float shadowProjDiff0 = 1; + float3 shadowMapCenter_objDepth0 = cascade0; + float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; + float objDepth0 = shadowMapCenter_objDepth0.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff0; + float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); + + float shadowProjDiff1 = g_CascadeSize.y; + float3 shadowMapCenter_objDepth1 = cascade1; + float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; + float objDepth1 = shadowMapCenter_objDepth1.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff1; + float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); + + float shadowProjDiff2 = g_CascadeSize.z; + float3 shadowMapCenter_objDepth2 = cascade2; + float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; + float objDepth2 = shadowMapCenter_objDepth2.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff2; + float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); + + float shadowProjDiff3 = g_CascadeSize.w; + float3 shadowMapCenter_objDepth3 = cascade3; + float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; + float objDepth3 = shadowMapCenter_objDepth3.z + DEPTHBIAS * (SLOPESCALE * LdN) * shadowProjDiff3; + float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); + + float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); + float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); + float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); + float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); + + /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); + float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); + float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); + float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); + + float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); + float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); + float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); + float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ + + + float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); + float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); + float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); + + float shadow = shadow0123; + + if(projMask == 1.0f) + { + float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); + float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); + return shadowFinal; + } + else + { + return 1.0f; + } + +} + +float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) +{ + float3 Out; + float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); + float4 flashlightSpacePosition = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); + float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); + diffuse = saturate(diffuse); + + + Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); + return Out; +} + +struct PS_INPUT +{ + float2 texCoord : TEXCOORD0; + float4x4 viewProj : TEXCOORD2; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 fbSample = tex2D( FBSampler, i.texCoord ).rgb; + float3 AlbedoSample = tex2D( AlbedoSampler, i.texCoord ).rgb; + float3 worldPos = tex2D( ViewPosSampler, i.texCoord ).rgb + g_EyePos; + float3 worldNormal = tex2D( ViewNormalSampler, i.texCoord ).rgb; + worldNormal = unpackNormals(worldNormal); + float3 metallicRoughnessDepth = tex2D( MetallicRoughnessSampler, i.texCoord ).rgb; + float3 AOSample = tex2D( AOSampler, i.texCoord ).rgb; // Samples + float depth = metallicRoughnessDepth.z; + float ProjectionDepth = depth * (g_ZDist.y / g_ZDist.x); + + float3 ambient = DoAmbient(i.texCoord, worldPos, worldNormal, g_EyePos, metallicRoughnessDepth.y, AlbedoSample, g_CascadeAmbient, g_CascadeLight / (PI * PI)); + + float3 lighting = DoPBRCSM(worldPos, worldNormal, AlbedoSample, metallicRoughnessDepth.x, metallicRoughnessDepth.y, length(worldPos - g_EyePos)); + + return FinalOutput( float4( lighting + ambient, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/materialsystem/stdshaders/deferred_pointlights_ps30.fxc b/materialsystem/stdshaders/deferred_pointlights_ps30.fxc index 2dddbe37..32277911 100644 --- a/materialsystem/stdshaders/deferred_pointlights_ps30.fxc +++ b/materialsystem/stdshaders/deferred_pointlights_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" diff --git a/materialsystem/stdshaders/deferred_sky_ps30.fxc b/materialsystem/stdshaders/deferred_sky_ps30.fxc index 2e09d985..183415c6 100644 --- a/materialsystem/stdshaders/deferred_sky_ps30.fxc +++ b/materialsystem/stdshaders/deferred_sky_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" diff --git a/materialsystem/stdshaders/deferred_spotlight_ps30.fxc b/materialsystem/stdshaders/deferred_spotlight_ps30.fxc index a7c4ef11..5b0b80f5 100644 --- a/materialsystem/stdshaders/deferred_spotlight_ps30.fxc +++ b/materialsystem/stdshaders/deferred_spotlight_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" @@ -26,6 +25,7 @@ float4 MixedLightData[MAX_LIGHTS_SPOT * 3]: register( c4 ); // 3 registers each float3 DoLights(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness) { float3 Out = 0.0f.xxx; + [loop] for(int iLight = 0; iLight < MAX_LIGHTS_SPOT * 3; iLight = iLight + 3) { float3 vLight = MixedLightData[iLight] - worldPos; diff --git a/materialsystem/stdshaders/deferred_spotlight_shadow_ps30.fxc b/materialsystem/stdshaders/deferred_spotlight_shadow_ps30.fxc index af2f8e1f..12af2e0b 100644 --- a/materialsystem/stdshaders/deferred_spotlight_shadow_ps30.fxc +++ b/materialsystem/stdshaders/deferred_spotlight_shadow_ps30.fxc @@ -1,11 +1,10 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" #include "common_pbr.h" #include "common_deferred.h" -#include "deferred_shadows.h" +#include "common_deferredshadows_fxc.h" #define MAX_LIGHTS_SPOTSHADOW 8 diff --git a/materialsystem/stdshaders/deferred_volumetricfog_ps30.fxc b/materialsystem/stdshaders/deferred_volumetricfog_ps30.fxc index 6b913abe..41cf44c3 100644 --- a/materialsystem/stdshaders/deferred_volumetricfog_ps30.fxc +++ b/materialsystem/stdshaders/deferred_volumetricfog_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] // DYNAMIC: "FOG" "0..1" // DYNAMIC: "CSM" "0..1" diff --git a/materialsystem/stdshaders/depth_of_field_ps30.fxc b/materialsystem/stdshaders/depth_of_field_ps30.fxc new file mode 100644 index 00000000..6eb5cb70 --- /dev/null +++ b/materialsystem/stdshaders/depth_of_field_ps30.fxc @@ -0,0 +1,137 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// DYNAMIC: "QUALITY" "0..3" + +// Includes ======================================================================================= +#include "common_ps_fxc.h" + +// Texture Samplers =============================================================================== +sampler g_tFullFB : register( s0 ); +sampler g_tSmallFB : register( s1 ); + +// Shaders Constants and Globals ================================================================== +float4 g_vDists : register( c0 ); +#define g_flNearBlurDist g_vDists.x +#define g_flNearFocusDist g_vDists.y +#define g_flFarFocusDist g_vDists.z +#define g_flFarBlurDist g_vDists.w + +float3 g_vBlurAmounts : register( c1 ); +#define g_flMaxBlurRadius g_vBlurAmounts.x +#define g_flNearBlurStrength g_vBlurAmounts.y +#define g_flFarBlurStrength g_vBlurAmounts.z + +float3 g_vNearFarDists : register( c2 ); +#define g_flNearPlaneDist g_vNearFarDists.x +#define g_flFarPlaneDist g_vNearFarDists.y +#define g_flDepthConv g_vNearFarDists.z + +float4 g_vMagicConsts : register( c3 ); + +#if ( QUALITY == 0 ) + #define NUM_SAMPLES 8 // These must match the C code +#elif ( QUALITY == 1 ) + #define NUM_SAMPLES 16 +#elif ( QUALITY == 2 ) + #define NUM_SAMPLES 16 +#elif ( QUALITY == 3 ) + #define NUM_SAMPLES 32 +#endif + +float4 g_vPoisson[ NUM_SAMPLES/2 ] : register( c4 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vUv0 : TEXCOORD0; +}; + +float DestAlphaDepthToViewSpaceDepth( float flDepth ) +{ + return g_flDepthConv * flDepth + g_flNearPlaneDist; +} + +// returns blur radius from depth as a fraction of max_blur. +float BlurAmountFromDepth( float flDestAlphaDepth ) +{ + /* + dist = DestAlphaDepthToViewSpaceDepth( flDestAlphaDepth ); + float flBlur = max( g_flNearBlurStrength * saturate( (flDestAlphaDepth - g_flNearFocusDist) / ( g_flNearBlurDist - g_flNearFocusDist ) ), + g_flFarBlurStrength * saturate( (flDestAlphaDepth - g_flFarFocusDist) / ( g_flFarBlurDist - g_flFarFocusDist ) ) ); + */ + + // A more optimized version that concatenates the math above and the one in DestAlphaDepthToViewSpaceDepth to a single muladd + float flBlur = max( g_flNearBlurStrength * saturate( g_vMagicConsts.x * flDestAlphaDepth + g_vMagicConsts.y ), + g_flFarBlurStrength * saturate( g_vMagicConsts.z * flDestAlphaDepth + g_vMagicConsts.w ) ); + return flBlur; +} + +float BlurRadiusFromDepth( float flDepth ) +{ + return g_flMaxBlurRadius * BlurAmountFromDepth( flDepth ); +} + +float4 ComputeTap( float flCenterDepth, float flCenterBlurRadius, float2 vUV, float2 vPoisson ) +{ + float4 cTapSmall; + float4 cTap; + float2 vPoissonUV = vUV.xy + flCenterBlurRadius * vPoisson.xy; + + cTapSmall = tex2D( g_tSmallFB, vPoissonUV.xy ); + cTap = tex2D( g_tFullFB, vPoissonUV.xy ); + + float flTapBlur = BlurAmountFromDepth( cTap.a ); // Maybe 50/50 mix between low and high here? + + cTap = lerp( cTap, cTapSmall, saturate( 2.2 * flTapBlur ) ); // TODO: tweak blur amount. + float flLerpedTapBlur = BlurAmountFromDepth( cTap.a ); + + float weight = ( cTap.a >= flCenterDepth ) ? 1.0 : ( flLerpedTapBlur*flLerpedTapBlur ); + return float4( cTap.rgb, 1 ) * weight; +} + +float4 ComputeTapHQ( float flCenterDepth, float flCenterBlurRadius, float2 vUV, float2 vPoisson ) +{ + float4 cTap; + + cTap = tex2D( g_tFullFB, vUV.xy + flCenterBlurRadius * vPoisson.xy ); + float flTapBlur = BlurAmountFromDepth( cTap.a ); + float weight = ( cTap.a >= flCenterDepth ) ? 1.0 : ( flTapBlur * flTapBlur ); + return float4( cTap.rgb, 1 ) * weight; +} + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // TODO: BETTER DOWNSAMPLE THAT TAKES DEPTH INTO ACCOUNT? + + float4 cOut = { 0, 0, 0, 0 }; + float4 cCenterTap = tex2D( g_tFullFB, i.vUv0 ); + float flCenterBlurRadius = BlurRadiusFromDepth( cCenterTap.a ); // circle of confusion radius for current pixel + cCenterTap.a -= 0.001; // z-bias to avoid strange banding artifact on almost orthogonal walls + +#if ( QUALITY < 2 ) + // ATI's Ruby1-style algorithm + for ( int t = 0; t < NUM_SAMPLES/2; t++ ) + { + cOut.rgba += ComputeTap( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].xy ); + cOut.rgba += ComputeTap( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].wz ); + } +#else + // Less fancy, with less fetches per tap and less math. Needs more samples to look smooth. + cOut = cCenterTap; + cOut.a = 1.0; // Use the center sample we just fetched + for ( int t = 0; t < NUM_SAMPLES/2; t++ ) + { + cOut.rgba += ComputeTapHQ( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].xy ); + cOut.rgba += ComputeTapHQ( cCenterTap.a, flCenterBlurRadius, i.vUv0, g_vPoisson[t].wz ); + } +#endif + //cOut.rgb = cOut.a / float(NUM_SAMPLES+1); + //cOut = lerp( tex2D( g_tFullFB, i.vUv0 ), tex2D( g_tSmallFB, i.vUv0 ).aaaa, 0.5 ); + if ( cOut.a > 0.0 ) + cOut.rgba /= cOut.a; + else + cOut.rgba = cCenterTap.rgba; + + return cOut; +} diff --git a/materialsystem/stdshaders/depth_of_field_vs30.fxc b/materialsystem/stdshaders/depth_of_field_vs30.fxc new file mode 100644 index 00000000..37382c7d --- /dev/null +++ b/materialsystem/stdshaders/depth_of_field_vs30.fxc @@ -0,0 +1,29 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// Includes ======================================================================================= +#include "common_vs_fxc.h" + +// Input values =================================================================================== +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +// Interpolated values ============================================================================ +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 vUv0 : TEXCOORD0; +}; + +// Main =========================================================================================== +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + o.projPos.xyzw = float4( i.vPos.xyz, 1.0f ); + o.vUv0.xy = i.vBaseTexCoord.xy; + + return o; +} diff --git a/materialsystem/stdshaders/depthoffield.cpp b/materialsystem/stdshaders/depthoffield.cpp new file mode 100644 index 00000000..6ea8d6db --- /dev/null +++ b/materialsystem/stdshaders/depthoffield.cpp @@ -0,0 +1,265 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: Depth of field material +// +//===========================================================================// + +#include "basevsshader.h" +#include "depth_of_field_vs30.inc" +#include "depth_of_field_ps30.inc" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar mat_dof_max_blur_radius( "mat_dof_max_blur_radius", "50" ); +ConVar mat_dof_quality( "mat_dof_quality", "3" ); +ConVar mat_dof_constant( "mat_dof_constant", "512" ); + +// 8 samples +static const float s_flPoissonConstsQuality0[16] = { + 0.0, 0.0, + 0.527837, -0.085868, + -0.040088, 0.536087, + -0.670445, -0.179949, + -0.419418, -0.616039, + 0.440453, -0.639399, + -0.757088, 0.349334, + 0.574619, 0.685879 +}; + +// 16 samples +static const float s_flPoissonConstsQuality1[32] = { + 0.0747, -0.8341, + -0.9138, 0.3251, + 0.8667, -0.3029, + -0.4642, 0.2187, + -0.1505, 0.7320, + 0.7310, -0.6786, + 0.2859, -0.3254, + -0.1311, -0.2292, + 0.3518, 0.6470, + -0.7485, -0.6307, + 0.1687, 0.1873, + -0.3604, -0.7483, + -0.5658, -0.1521, + 0.7102, 0.0536, + -0.6056, 0.7747, + 0.7793, 0.6194 +}; + +// 32 samples +static const float s_flPoissonConstsQuality2[64] = { + 0.0854f, -0.0644f, + 0.8744f, 0.1665f, + 0.2329f, 0.3995f, + -0.7804f, 0.5482f, + -0.4577f, 0.7647f, + -0.1936f, 0.5564f, + 0.4205f, -0.5768f, + -0.0304f, -0.9050f, + -0.5215f, 0.1854f, + 0.3161f, -0.2954f, + 0.0666f, -0.5564f, + -0.2137f, -0.0072f, + -0.4112f, -0.3311f, + 0.6438f, -0.2484f, + -0.9055f, -0.0360f, + 0.8323f, 0.5268f, + 0.5592f, 0.3459f, + -0.6797f, -0.5201f, + -0.4325f, -0.8857f, + 0.8768f, -0.4197f, + 0.3090f, -0.8646f, + 0.5034f, 0.8603f, + 0.3752f, 0.0627f, + -0.0161f, 0.2627f, + 0.0969f, 0.7054f, + -0.2291f, -0.6595f, + -0.5887f, -0.1100f, + 0.7048f, -0.6528f, + -0.8438f, 0.2706f, + -0.5061f, 0.4653f, + -0.1245f, -0.3302f, + -0.1801f, 0.8486f +}; + +BEGIN_VS_SHADER_FLAGS( DepthOfField, "Depth of Field", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SMALLFB, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallFB1", "Downsampled backbuffer" ) + SHADER_PARAM( NEARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Near plane depth" ) + SHADER_PARAM( FARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Far plane depth" ) + SHADER_PARAM( NEARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near blur plane depth" ) + SHADER_PARAM( NEARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near focus plane depth" ) + SHADER_PARAM( FARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far focus plane depth" ) + SHADER_PARAM( FARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far blur plane depth" ) + SHADER_PARAM( NEARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max near blur radius" ) + SHADER_PARAM( FARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max far blur radius" ) + SHADER_PARAM( QUALITY, SHADER_PARAM_TYPE_INTEGER, "0", "Quality level. Selects different algorithms." ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_PARAM_STRING_IF_NOT_DEFINED( SMALLFB, "_rt_SmallFB1" ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARPLANE, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARPLANE, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARFOCUSDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARFOCUSDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURDEPTH, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURRADIUS, 0.0f ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURRADIUS, 0.0f ); + SET_PARAM_INT_IF_NOT_DEFINED( QUALITY, 0 ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 92 ) + { + return "Wireframe"; + } + + return 0; + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if ( params[SMALLFB]->IsDefined() ) + { + LoadTexture( SMALLFB ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + pShaderShadow->EnableSRGBWrite( false ); + + DECLARE_STATIC_VERTEX_SHADER( depth_of_field_vs30 ); + SET_STATIC_VERTEX_SHADER( depth_of_field_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( depth_of_field_ps30 ); + SET_STATIC_PIXEL_SHADER( depth_of_field_ps30 ); + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( depth_of_field_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( depth_of_field_vs30 ); + + // Bind textures + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + BindTexture( SHADER_SAMPLER1, SMALLFB ); + + // near blur = blur of stuff in front of focus range + // far blur = blur of stuff behind focus range + + // C0: set near/far blur and focus distances + // x = near blur distance + // y = near focus distance + // z = far focus distance + // w = far blur distance + // C1: + // x = blur radius for near blur (in pixels) + // y = blur radius for far blur (in pixels) + // TODO: Specifying this stuff in pixels makes blurs look smaller on high backbuffer resolutions. + // This might be a problem for tweaking these values. + float vConst[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + + vConst[0] = params[NEARBLURDEPTH]->GetFloatValue(); + vConst[1] = params[NEARFOCUSDEPTH]->GetFloatValue(); + vConst[2] = params[FARFOCUSDEPTH]->GetFloatValue(); + vConst[3] = params[FARBLURDEPTH]->GetFloatValue();; + // max blur radius will need to be set based on quality level and screen res + vConst[4] = mat_dof_max_blur_radius.GetFloat(); + vConst[5] = MIN( params[NEARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; // near and far blur radius as fraction of max radius + vConst[6] = MIN( params[FARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; + + vConst[8] = params[NEARPLANE]->GetFloatValue(); + vConst[9] = params[FARPLANE]->GetFloatValue(); + + vConst[10] = mat_dof_constant.GetFloat() * ( vConst[9] - vConst[8] ) / vConst[9]; + + vConst[12] = vConst[10] / ( vConst[0] - vConst[1] ); + vConst[13] = ( vConst[8] - vConst[1] ) / ( vConst[0] - vConst[1] ); + vConst[14] = vConst[10] / ( vConst[3] - vConst[2] ); + vConst[15] = ( vConst[8] - vConst[2] ) / ( vConst[3] - vConst[2] ); + + pShaderAPI->SetPixelShaderConstant( 0, vConst, 4 ); + + // set up poisson sample location constants pre-divided by screen res + int nNumPoissonSamples = 0; + const float *pPoissonSrc = NULL; + switch ( params[QUALITY]->GetIntValue() ) + { + case 0: + // NOTE: These must match the shader + nNumPoissonSamples = 8; + pPoissonSrc = s_flPoissonConstsQuality0; + break; + + case 1: + case 2: + nNumPoissonSamples = 16; + pPoissonSrc = s_flPoissonConstsQuality1; + break; + + case 3: + nNumPoissonSamples = 32; + pPoissonSrc = s_flPoissonConstsQuality2; + break; + + default: + Warning( "Invalid mat_dof_quality value. Resetting to 0.\n" ); + mat_dof_quality.SetValue( 0 ); + nNumPoissonSamples = 8; + pPoissonSrc = s_flPoissonConstsQuality0; + break; + } + + float vPoissonConst[64]; // temp table + + // Get texture dimensions + ITexture *pTex = params[BASETEXTURE]->GetTextureValue(); + Assert( pTex ); + float flInvTexWidth = 1.0f / static_cast( pTex->GetActualWidth() ); + float flInvTexHeight = 1.0f / static_cast( pTex->GetActualHeight() ); + + for ( int i = 0; i < nNumPoissonSamples; i++ ) + { + vPoissonConst[ 2*i ] = pPoissonSrc[ 2*i ] * flInvTexWidth; + vPoissonConst[ 2*i+1 ] = pPoissonSrc[ 2*i+1 ] * flInvTexHeight; + } + + // swizzle every other 2-tuple so that I can use the free .wz swizzle in the shader + for ( int i = 1; i < nNumPoissonSamples; i += 2) + { + float t = vPoissonConst[ 2*i ]; + vPoissonConst[ 2*i ] = vPoissonConst[ 2*i+1 ]; + vPoissonConst[ 2*i+1 ] = t; + } + + pShaderAPI->SetPixelShaderConstant( 4, vPoissonConst, nNumPoissonSamples / 2 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( depth_of_field_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( QUALITY, params[QUALITY]->GetIntValue() ); + SET_DYNAMIC_PIXEL_SHADER( depth_of_field_ps30 ); + } + + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/depthwrite.cpp b/materialsystem/stdshaders/depthwrite.cpp index 06d7690f..01f05802 100644 --- a/materialsystem/stdshaders/depthwrite.cpp +++ b/materialsystem/stdshaders/depthwrite.cpp @@ -6,22 +6,34 @@ // $NoKeywords: $ //=============================================================================// -#include "BaseVSShader.h" - -#include "depthwrite_ps20.inc" -#include "depthwrite_ps20b.inc" -#include "depthwrite_vs20.inc" - -#if !defined( _X360 ) -#include "depthwrite_ps30.inc" -#include "depthwrite_vs30.inc" -#endif +#include "basevsshader.h" +#include "sdk_depthwrite_ps30.inc" +#include "sdk_depthwrite_vs30.inc" BEGIN_VS_SHADER_FLAGS( DepthWrite, "Help for Depth Write", SHADER_NOT_EDITABLE ) BEGIN_SHADER_PARAMS SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "", "Alpha reference value" ) SHADER_PARAM( COLOR_DEPTH, SHADER_PARAM_TYPE_BOOL, "0", "Write depth as color") + + // vertexlitgeneric tree sway animation control + SHADER_PARAM( TREESWAY, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( TREESWAYHEIGHT, SHADER_PARAM_TYPE_FLOAT, "1000", "" ) + SHADER_PARAM( TREESWAYSTARTHEIGHT, SHADER_PARAM_TYPE_FLOAT, "0.2", "" ) + SHADER_PARAM( TREESWAYRADIUS, SHADER_PARAM_TYPE_FLOAT, "300", "" ) + SHADER_PARAM( TREESWAYSTARTRADIUS, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSPEED, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + SHADER_PARAM( TREESWAYSPEEDHIGHWINDMULTIPLIER, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( TREESWAYSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "10", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESPEED, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFREQUENCY, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.5", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPSTART, SHADER_PARAM_TYPE_FLOAT, "3", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPEND, SHADER_PARAM_TYPE_FLOAT, "6", "" ) + SHADER_PARAM( TREESWAYSTATIC, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( TREESWAYSTATICVALUES, SHADER_PARAM_TYPE_VEC2, "[0.5 0.5]", "" ) END_SHADER_PARAMS SHADER_INIT_PARAMS() @@ -46,6 +58,7 @@ BEGIN_VS_SHADER_FLAGS( DepthWrite, "Help for Depth Write", SHADER_NOT_EDITABLE ) { bool bAlphaClip = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ); int nColorDepth = GetIntParam( COLOR_DEPTH, params, 0 ); + int nTreeSwayMode = clamp( GetIntParam( TREESWAY, params, 0 ), 0, 2 ); SHADOW_STATE { @@ -72,136 +85,102 @@ BEGIN_VS_SHADER_FLAGS( DepthWrite, "Help for Depth Write", SHADER_NOT_EDITABLE ) // If a material was already marked nocull, don't cull it pShaderShadow->EnableCulling( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) && !IS_FLAG_SET(MATERIAL_VAR_NOCULL) ); -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, !bAlphaClip && IsX360() && !nColorDepth ); //360 needs to know if it *shouldn't* output texture coordinates to avoid shader patches - SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); - SET_STATIC_VERTEX_SHADER( depthwrite_vs20 ); - - if ( bAlphaClip || g_pHardwareConfig->PlatformRequiresNonNullPixelShaders() || nColorDepth ) - { - if( bAlphaClip ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - } - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); - SET_STATIC_PIXEL_SHADER( depthwrite_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); - SET_STATIC_PIXEL_SHADER( depthwrite_ps20 ); - } - } - } -#ifndef _X360 - else - { - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, 0 ); //360 only combo, and this is a PC path - SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); - SET_STATIC_VERTEX_SHADER( depthwrite_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_depthwrite_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_VERTEX_SHADER_COMBO( TREESWAY, nTreeSwayMode ); + SET_STATIC_VERTEX_SHADER( sdk_depthwrite_vs30 ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); - SET_STATIC_PIXEL_SHADER( depthwrite_ps30 ); - } -#endif + DECLARE_STATIC_PIXEL_SHADER( sdk_depthwrite_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( sdk_depthwrite_ps30 ); } + DYNAMIC_STATE { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_depthwrite_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_depthwrite_vs30 ); -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif + if ( bAlphaClip ) { - depthwrite_vs20_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - if ( bAlphaClip ) + float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; + if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); + } - float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; - if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) - { - vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); - } + pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); + } - pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_depthwrite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( sdk_depthwrite_ps30 ); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + if ( nTreeSwayMode != 0 ) + { + float flParams[4]; + + flParams[0] = pShaderAPI->CurrentTime(); + if (params[TREESWAYSTATIC]->GetIntValue() == 0) { - DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); - SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); + const Vector& windDir = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_WIND_DIRECTION ); + flParams[1] = windDir.x; + flParams[2] = windDir.y; } else { - DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); - SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); + // Use a static value instead of the env_wind value. + params[TREESWAYSTATICVALUES]->GetVecValue( flParams + 1, 2 ); } + flParams[3] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flParams ); + + flParams[0] = GetFloatParam( TREESWAYSCRUMBLEFALLOFFEXP, params, 1.0f ); + flParams[1] = GetFloatParam( TREESWAYFALLOFFEXP, params, 1.0f ); + flParams[2] = GetFloatParam( TREESWAYSCRUMBLESPEED, params, 3.0f ); + flParams[3] = GetFloatParam( TREESWAYSPEEDHIGHWINDMULTIPLIER, params, 2.0f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, flParams ); + + flParams[0] = GetFloatParam( TREESWAYHEIGHT, params, 1000.0f ); + flParams[1] = GetFloatParam( TREESWAYSTARTHEIGHT, params, 0.1f ); + flParams[2] = GetFloatParam( TREESWAYRADIUS, params, 300.0f ); + flParams[3] = GetFloatParam( TREESWAYSTARTRADIUS, params, 0.2f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flParams ); + + flParams[0] = GetFloatParam( TREESWAYSPEED, params, 1.0f ); + flParams[1] = GetFloatParam( TREESWAYSTRENGTH, params, 10.0f ); + flParams[2] = GetFloatParam( TREESWAYSCRUMBLEFREQUENCY, params, 12.0f ); + flParams[3] = GetFloatParam( TREESWAYSCRUMBLESTRENGTH, params, 10.0f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, flParams ); + + flParams[0] = GetFloatParam( TREESWAYSPEEDLERPSTART, params, 3.0f ); + flParams[1] = GetFloatParam( TREESWAYSPEEDLERPEND, params, 6.0f ); + flParams[2] = 0.0f; + flParams[3] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, flParams ); } -#ifndef _X360 - else // 3.0 shader case (PC only) - { - SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); - depthwrite_vs30_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - vshIndex.SetMORPHING( pShaderAPI->IsHWMorphingEnabled() ); - vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if ( bAlphaClip ) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; - if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) - { - vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); - } - - pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); - } - - DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); - SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); - } -#endif - - Vector4D vParms; // set up arbitrary far planes, as the real ones are too far ( 30,000 ) -// pShaderAPI->SetPSNearAndFarZ( 1 ); + Vector4D vParms; vParms.x = 7.0f; // arbitrary near vParms.y = 4000.0f; // arbitrary far vParms.z = 0.0f; vParms.w = 0.0f; pShaderAPI->SetPixelShaderConstant( 1, vParms.Base(), 2 ); - } // DYNAMIC_STATE + } // DYNAMIC_STATE - Draw( ); + Draw(); } END_SHADER diff --git a/materialsystem/stdshaders/depthwrite_ps2x.fxc b/materialsystem/stdshaders/depthwrite_ps2x.fxc deleted file mode 100644 index 02ec03d8..00000000 --- a/materialsystem/stdshaders/depthwrite_ps2x.fxc +++ /dev/null @@ -1,44 +0,0 @@ -// STATIC: "COLOR_DEPTH" "0..1" - -// DYNAMIC: "ALPHACLIP" "0..1" - -const float g_AlphaThreshold : register( c0 ); - -const float2 g_vNearFarPlanes : register( c1 ); - #define g_flNearPlane g_vNearFarPlanes.x - #define g_flFarPlane g_vNearFarPlanes.y - -struct PS_INPUT -{ -#if ALPHACLIP - float2 texCoord0 : TEXCOORD0; -#endif - -#if COLOR_DEPTH - float4 vProjPos : TEXCOORD1; -#endif -}; - -sampler BaseTextureSampler : register( s0 ); - -float4 main( PS_INPUT i ) : COLOR -{ - float4 color = float4( 1, 0, 0, 1 ); // opaque alpha....the color doesn't matter for this shader - -#if ALPHACLIP - color = tex2D( BaseTextureSampler, i.texCoord0 ); - - clip( color.a - g_AlphaThreshold ); - -#endif - -#if ( COLOR_DEPTH == 1 ) - - return float4( float3(i.vProjPos.xyz / i.vProjPos.w), 1.0 ); - -#else - - return color; - -#endif -} diff --git a/materialsystem/stdshaders/depthwrite_vs20.fxc b/materialsystem/stdshaders/depthwrite_vs20.fxc deleted file mode 100644 index 7d4c957c..00000000 --- a/materialsystem/stdshaders/depthwrite_vs20.fxc +++ /dev/null @@ -1,82 +0,0 @@ -// STATIC: "ONLY_PROJECT_POSITION" "0..1" [XBOX] -// STATIC: "ONLY_PROJECT_POSITION" "0..0" [PC] -// STATIC: "COLOR_DEPTH" "0..1" - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); - -sampler2D morphSampler : register( s0 ); -#endif - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vTexCoord : TEXCOORD0; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - - // Position delta stream - float3 vPosFlex : POSITION1; - -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - -#if (ONLY_PROJECT_POSITION == 0) //360 sometimes runs without the pixel shader component, but has to patch this output if it does. - float2 texCoord : TEXCOORD0; -#endif - -#if COLOR_DEPTH - float4 vWorldPos_projPosZ : TEXCOORD1; -#endif - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - float3 vWorldPos; - float4 vPosition = v.vPos; - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, vPosition.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, - v.vVertexID, float3(0, 0, 0), vPosition.xyz ); -#endif - - SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPos ); - - float4 vProjPos = mul( float4( vWorldPos, 1.0f ), cViewProj ); - - o.vProjPos = vProjPos; - -#if (ONLY_PROJECT_POSITION == 0) - o.texCoord = v.vTexCoord; -#endif - -#if ( COLOR_DEPTH && !ONLY_PROJECT_POSITION ) - o.vWorldPos_projPosZ = vProjPos; -#endif - - return o; -} - - diff --git a/materialsystem/stdshaders/detail.cpp b/materialsystem/stdshaders/detail.cpp deleted file mode 100644 index 956bf518..00000000 --- a/materialsystem/stdshaders/detail.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER( Detail, "Help for Detail" ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); - } - - SHADER_FALLBACK - { - return "UnlitGeneric"; - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - } - -END_SHADER - diff --git a/materialsystem/stdshaders/detail_ps11.psh b/materialsystem/stdshaders/detail_ps11.psh deleted file mode 100644 index 8c49af16..00000000 --- a/materialsystem/stdshaders/detail_ps11.psh +++ /dev/null @@ -1,12 +0,0 @@ -ps.1.1 - -tex t0 -tex t1 - -mul r0.rgb, t0, v0 + - -; handle distance fade -sub r0.a, t0.a, 1-v0.a - -sub r0.a, r0.a, t1_bias.a -cnd r0.a, r0.a, c0.a, c1.a diff --git a/materialsystem/stdshaders/detail_vs11.vsh b/materialsystem/stdshaders/detail_vs11.vsh deleted file mode 100644 index 28dee2fd..00000000 --- a/materialsystem/stdshaders/detail_vs11.vsh +++ /dev/null @@ -1,56 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -dp4 $worldPos.x, $vPos, $cModel0 -dp4 $worldPos.y, $vPos, $cModel1 -dp4 $worldPos.z, $vPos, $cModel2 -mov $worldPos.w, $cOne - - -;------------------------------------------------------------------------------ -; Transform the position from world to proj space -;------------------------------------------------------------------------------ -&AllocateRegister( \$projPos ); -dp4 $projPos.x, $vPos, $cModelViewProj0 -dp4 $projPos.y, $vPos, $cModelViewProj1 -dp4 $projPos.z, $vPos, $cModelViewProj2 -dp4 $projPos.w, $vPos, $cModelViewProj3 -mov oPos, $projPos - - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); -&FreeRegister( \$worldPos ); - - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ -mov oT0.xy, $vTexCoord0.xy - -; special case perspective correct texture projection so that the texture fits exactly on the screen -mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_0.w -add $projPos.xy, $projPos.xy, $projPos.w -mul $projPos.xy, $projPos.xy, $cHalf -mul $projPos.xy, $projPos.xy, $SHADER_SPECIFIC_CONST_0.xy -mad $projPos.xy, $projPos.w, $SHADER_SPECIFIC_CONST_1.xy, $projPos.xy - -mov oT1.xy, $projPos.xy -mov oT1.z, $projPos.w -mov oT1.w, $projPos.w - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Modulation color -;------------------------------------------------------------------------------ -mov oD0, $vColor diff --git a/materialsystem/stdshaders/dx8fallbacks.cpp b/materialsystem/stdshaders/dx8fallbacks.cpp deleted file mode 100644 index a847ef38..00000000 --- a/materialsystem/stdshaders/dx8fallbacks.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "BaseVSShader.h" - -// This one isn't supported on dx8 -DEFINE_FALLBACK_SHADER( SDK_DepthWrite, Wireframe ) - -DEFINE_FALLBACK_SHADER( SDK_EyeRefract, Eyes_dx8 ) -DEFINE_FALLBACK_SHADER( SDK_VolumeClouds, UnlitGeneric_DX8 ) - -// FIXME: These aren't supported on dx8, but need to be. -DEFINE_FALLBACK_SHADER( SDK_EyeGlint, EyeGlint ) -DEFINE_FALLBACK_SHADER( SDK_AfterShock, AfterShock ) diff --git a/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.cpp b/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.cpp new file mode 100644 index 00000000..54726366 --- /dev/null +++ b/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.cpp @@ -0,0 +1,214 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Emissive Scroll Pass + "$emissiveBlendEnabled" "1" // Enables effect + "$emissiveBlendTexture" "models/vortigaunt/vortigaunt_illum" + "$emissiveBlendBaseTexture" "Models/Vortigaunt/vortigaunt_blue" + "$emissiveBlendFlowTexture" "models/vortigaunt/vortigaunt_flow" + "$emissiveBlendTint" "[10 10 10]" + "$emissiveBlendStrength" "1.0" // Set by game code + "$emissiveBlendScrollVector" "[0.11 0.124]" + "Proxies" + { + "VortEmissive" // For setting $selfillumstrength + { + } + } + + #include "emissive_scroll_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + + Add this above SHADER_INIT_PARAMS() + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + } + + In SHADER_INIT_PARAMS() + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + At the very end of SHADER_DRAW + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "basevsshader.h" +#include "mathlib/vmatrix.h" +#include "emissive_scroll_blended_pass_helper.h" +#include "convar.h" +#include "sdk_emissive_scroll_blended_pass_vs30.inc" +#include "sdk_emissive_scroll_blended_pass_ps30.inc" + +void InitParamsEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, EmissiveScrollBlendedPassVars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if ( ( info.m_nEmissiveScrollVector != -1 ) && ( !params[info.m_nEmissiveScrollVector]->IsDefined() ) ) + { + params[info.m_nEmissiveScrollVector]->SetVecValue( kDefaultEmissiveScrollVector, 4 ); + } + + if ( ( info.m_nBlendStrength != -1 ) && ( !params[info.m_nBlendStrength]->IsDefined() ) ) + { + params[info.m_nBlendStrength]->SetFloatValue( kDefaultEmissiveBlendStrength ); + } + + if ( ( info.m_nEmissiveTint != -1 ) && ( !params[info.m_nEmissiveTint]->IsDefined() ) ) + { + params[info.m_nEmissiveTint]->SetVecValue( kDefaultEmissiveTint, 4 ); + } + + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); +} + +void InitEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, EmissiveScrollBlendedPassVars_t &info ) +{ + // Load textures + pShader->LoadTexture( info.m_nBaseTexture ); + pShader->LoadTexture( info.m_nFlowTexture ); + pShader->LoadTexture( info.m_nEmissiveTexture ); +} + +void DrawEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, EmissiveScrollBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState(); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_emissive_scroll_blended_pass_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_emissive_scroll_blended_pass_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_emissive_scroll_blended_pass_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_emissive_scroll_blended_pass_ps30 ); + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Flow texture not sRGB + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + pShaderShadow->EnableAlphaWrites( false ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + // Set Vertex Shader Combos + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_emissive_scroll_blended_pass_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_emissive_scroll_blended_pass_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_emissive_scroll_blended_pass_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_emissive_scroll_blended_pass_ps30 ); + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nFlowTexture ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nEmissiveTexture ); + + // Set Pixel Shader Constants + //float vConstZero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + // This brings in the electricity and the second base texture when the second base texture is present + float vPsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + if (1) + { + // Overall blend strength + vPsConst0[0] = IS_PARAM_DEFINED( info.m_nBlendStrength ) ? params[info.m_nBlendStrength]->GetFloatValue() : kDefaultEmissiveBlendStrength; + if ( vPsConst0[0] < 0.0f ) + vPsConst0[0] = 0.0f; + if ( vPsConst0[0] > 1.0f ) + vPsConst0[0] = 1.0f; + + // Time % 1000 for scrolling + vPsConst0[1] = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + vPsConst0[1] -= (float)( (int)( vPsConst0[1] / 1000.0f ) ) * 1000.0f; + + // Dest alpha value for warping mask - NOTE: If we want to use this, we have to modify the blending mode above! + //if ( ( params[info.m_nWarpParam]->GetFloatValue() > 0.0f ) && ( params[info.m_nWarpParam]->GetFloatValue() < 1.0f ) ) + // tmpVec[2] = 1.0f; + //else + // tmpVec[2] = 0.0f; + } + pShaderAPI->SetPixelShaderConstant( 0, vPsConst0, 1 ); + + // Scroll vector + pShaderAPI->SetPixelShaderConstant( 1, IS_PARAM_DEFINED( info.m_nEmissiveScrollVector ) ? params[info.m_nEmissiveScrollVector]->GetVecValue() : kDefaultEmissiveScrollVector, 1 ); + + // Self illum tint + pShaderAPI->SetPixelShaderConstant( 2, IS_PARAM_DEFINED( info.m_nEmissiveTint ) ? params[info.m_nEmissiveTint]->GetVecValue() : kDefaultEmissiveTint, 1 ); + } + pShader->Draw(); +} diff --git a/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.h b/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.h new file mode 100644 index 00000000..8617fa6a --- /dev/null +++ b/materialsystem/stdshaders/emissive_scroll_blended_pass_helper.h @@ -0,0 +1,45 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +#ifndef EMISSIVE_SCROLL_BLENDED_PASS_HELPER_H +#define EMISSIVE_SCROLL_BLENDED_PASS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct EmissiveScrollBlendedPassVars_t +{ + EmissiveScrollBlendedPassVars_t() { memset( this, 0xFF, sizeof(EmissiveScrollBlendedPassVars_t) ); } + + int m_nBlendStrength; // Amount this layer is blended in globally + int m_nBaseTexture; + int m_nFlowTexture; + int m_nEmissiveTexture; + int m_nEmissiveTint; + int m_nEmissiveScrollVector; + int m_nTime; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultEmissiveBlendStrength = 0.0f; +static const float kDefaultEmissiveTint[4] = { 1.0f, 1.0f, 1.0f, 0.0f } ; +static const float kDefaultEmissiveScrollVector[4] = { 0.11f, 0.124f, 0.0f, 0.0f } ; + +void InitParamsEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, EmissiveScrollBlendedPassVars_t &info ); +void InitEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, EmissiveScrollBlendedPassVars_t &info ); +void DrawEmissiveScrollBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, EmissiveScrollBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // EMISSIVE_SCROLL_BLENDED_PASS_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshaders/engine_post.cpp b/materialsystem/stdshaders/engine_post.cpp new file mode 100644 index 00000000..4b771415 --- /dev/null +++ b/materialsystem/stdshaders/engine_post.cpp @@ -0,0 +1,633 @@ +//========= Copyright � 1996-2007, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "basevsshader.h" + +#include "sdk_screenspaceeffect_vs30.inc" +#include "sdk_engine_post_ps30.inc" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +ConVar mat_screen_blur_override( "mat_screen_blur_override", "-1.0" ); +ConVar mat_depth_blur_focal_distance_override( "mat_depth_blur_focal_distance_override", "-1.0" ); +ConVar mat_depth_blur_strength_override( "mat_depth_blur_strength_override", "-1.0" ); +ConVar mat_grain_scale_override( "mat_grain_scale_override", "-1.0" ); +ConVar mat_local_contrast_scale_override( "mat_local_contrast_scale_override", "0.0" ); +ConVar mat_local_contrast_midtone_mask_override( "mat_local_contrast_midtone_mask_override", "-1.0" ); +ConVar mat_local_contrast_vignette_start_override( "mat_local_contrast_vignette_start_override", "-1.0" ); +ConVar mat_local_contrast_vignette_end_override( "mat_local_contrast_vignette_end_override", "-1.0" ); +ConVar mat_local_contrast_edge_scale_override( "mat_local_contrast_edge_scale_override", "-1000.0" ); + +BEGIN_VS_SHADER_FLAGS( Engine_Post, "Engine post-processing effects (software anti-aliasing, bloom, color-correction", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "Full framebuffer texture" ) + SHADER_PARAM( AAENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable software anti-aliasing" ) + SHADER_PARAM( AAINTERNAL1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( AAINTERNAL2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( AAINTERNAL3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" ) + SHADER_PARAM( BLOOMENABLE, SHADER_PARAM_TYPE_BOOL, "1", "Enable bloom" ) + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "Bloom scale factor" ) + SHADER_PARAM( SCREENEFFECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "used for paint or vomit screen effect" ) + SHADER_PARAM( DEPTHBLURENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Inexpensive depth-of-field substitute" ) + + SHADER_PARAM( ALLOWVIGNETTE, SHADER_PARAM_TYPE_BOOL, "0", "Allow vignette" ) + SHADER_PARAM( VIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vignette" ) + SHADER_PARAM( INTERNAL_VIGNETTETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "dev/vignette", "" ) + + SHADER_PARAM( ALLOWNOISE, SHADER_PARAM_TYPE_BOOL, "0", "Allow noise" ) + SHADER_PARAM( NOISEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable noise" ) + SHADER_PARAM( NOISESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Noise scale" ) + SHADER_PARAM( NOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Noise texture" ) + + SHADER_PARAM( ALLOWLOCALCONTRAST, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" ) + SHADER_PARAM( LOCALCONTRASTMIDTONEMASK, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" ) + SHADER_PARAM( LOCALCONTRASTVIGNETTESTART, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" ) + SHADER_PARAM( LOCALCONTRASTVIGNETTEEND, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" ) + SHADER_PARAM( LOCALCONTRASTEDGESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" ) + + SHADER_PARAM( BLURREDVIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable blurred vignette" ) + SHADER_PARAM( BLURREDVIGNETTESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "blurred vignette strength" ) + SHADER_PARAM( FADETOBLACKSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "fade strength" ) + + SHADER_PARAM( DEPTHBLURFOCALDISTANCE, SHADER_PARAM_TYPE_FLOAT, "0", "Distance in dest-alpha space [0,1] of focal plane." ) + SHADER_PARAM( DEPTHBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Strength of depth-blur effect" ) + SHADER_PARAM( SCREENBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Full-screen blur factor" ) + + SHADER_PARAM( VOMITCOLOR1, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "1st vomit blend color" ) + SHADER_PARAM( VOMITCOLOR2, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "2st vomit blend color" ) + SHADER_PARAM( VOMITREFRACTSCALE, SHADER_PARAM_TYPE_FLOAT, "0.15", "vomit refract strength" ) + SHADER_PARAM( VOMITENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vomit refract" ) + + SHADER_PARAM( FADECOLOR, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "viewfade color" ) + SHADER_PARAM( FADE, SHADER_PARAM_TYPE_INTEGER, "0", "fade type. 0 = off, 1 = lerp, 2 = modulate" ) + + SHADER_PARAM( TV_GAMMA, SHADER_PARAM_TYPE_INTEGER, "0", "0 default, 1 used for laying off 360 movies" ) + SHADER_PARAM( DESATURATEENABLE, SHADER_PARAM_TYPE_INTEGER, "0", "Desaturate with math, turns off color correction" ) + SHADER_PARAM( DESATURATION, SHADER_PARAM_TYPE_FLOAT, "0", "Desaturation Amount" ) + + // Tool color correction setup + SHADER_PARAM( TOOLMODE, SHADER_PARAM_TYPE_BOOL, "1", "tool mode" ) + SHADER_PARAM( TOOLCOLORCORRECTION, SHADER_PARAM_TYPE_FLOAT, "1", "tool color correction override" ) + SHADER_PARAM( WEIGHT_DEFAULT, SHADER_PARAM_TYPE_FLOAT, "1", "weight default" ) + SHADER_PARAM( WEIGHT0, SHADER_PARAM_TYPE_FLOAT, "1", "weight0" ) + SHADER_PARAM( WEIGHT1, SHADER_PARAM_TYPE_FLOAT, "1", "weight1" ) + SHADER_PARAM( WEIGHT2, SHADER_PARAM_TYPE_FLOAT, "1", "weight2" ) + SHADER_PARAM( WEIGHT3, SHADER_PARAM_TYPE_FLOAT, "1", "weight3" ) + SHADER_PARAM( NUM_LOOKUPS, SHADER_PARAM_TYPE_FLOAT, "0", "num_lookups" ) + SHADER_PARAM( TOOLTIME, SHADER_PARAM_TYPE_FLOAT, "0", "tooltime" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !params[ INTERNAL_VIGNETTETEXTURE ]->IsDefined() ) + { + params[ INTERNAL_VIGNETTETEXTURE ]->SetStringValue( "dev/vignette" ); + } + if ( !params[ AAENABLE ]->IsDefined() ) + { + params[ AAENABLE ]->SetIntValue( 0 ); + } + if ( !params[ AAINTERNAL1 ]->IsDefined() ) + { + params[ AAINTERNAL1 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ AAINTERNAL2 ]->IsDefined() ) + { + params[ AAINTERNAL2 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ AAINTERNAL3 ]->IsDefined() ) + { + params[ AAINTERNAL3 ]->SetVecValue( 0, 0, 0, 0 ); + } + if ( !params[ BLOOMENABLE ]->IsDefined() ) + { + params[ BLOOMENABLE ]->SetIntValue( 1 ); + } + if ( !params[ BLOOMAMOUNT ]->IsDefined() ) + { + params[ BLOOMAMOUNT ]->SetFloatValue( 1.0f ); + } + if ( !params[ DEPTHBLURENABLE ]->IsDefined() ) + { + params[ DEPTHBLURENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWNOISE ]->IsDefined() ) + { + params[ ALLOWNOISE ]->SetIntValue( 1 ); + } + if ( !params[ NOISESCALE ]->IsDefined() ) + { + params[ NOISESCALE ]->SetFloatValue( 1.0f ); + } + if ( !params[ NOISEENABLE ]->IsDefined() ) + { + params[ NOISEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWVIGNETTE ]->IsDefined() ) + { + params[ ALLOWVIGNETTE ]->SetIntValue( 1 ); + } + if ( !params[ VIGNETTEENABLE ]->IsDefined() ) + { + params[ VIGNETTEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ ALLOWLOCALCONTRAST ]->IsDefined() ) + { + params[ ALLOWLOCALCONTRAST ]->SetIntValue( 1 ); + } + if ( !params[ LOCALCONTRASTSCALE ]->IsDefined() ) + { + params[ LOCALCONTRASTSCALE ]->SetFloatValue( 1.0f ); + } + if ( !params[ LOCALCONTRASTMIDTONEMASK ]->IsDefined() ) + { + params[ LOCALCONTRASTMIDTONEMASK ]->SetFloatValue( 1000.0f ); + } + if ( !params[ LOCALCONTRASTENABLE ]->IsDefined() ) + { + params[ LOCALCONTRASTENABLE ]->SetIntValue( 0 ); + } + if ( !params[ LOCALCONTRASTVIGNETTESTART ]->IsDefined() ) + { + params[ LOCALCONTRASTVIGNETTESTART ]->SetFloatValue( 0.7f ); + } + if ( !params[ LOCALCONTRASTVIGNETTEEND ]->IsDefined() ) + { + params[ LOCALCONTRASTVIGNETTEEND ]->SetFloatValue( 1.0f ); + } + if ( !params[ LOCALCONTRASTEDGESCALE ]->IsDefined() ) + { + params[ LOCALCONTRASTEDGESCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ BLURREDVIGNETTEENABLE ]->IsDefined() ) + { + params[ BLURREDVIGNETTEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ BLURREDVIGNETTESCALE ]->IsDefined() ) + { + params[ BLURREDVIGNETTESCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ FADETOBLACKSCALE ]->IsDefined() ) + { + params[ FADETOBLACKSCALE ]->SetFloatValue( 0.0f ); + } + if ( !params[ DEPTHBLURFOCALDISTANCE ]->IsDefined() ) + { + params[ DEPTHBLURFOCALDISTANCE ]->SetFloatValue( 0.0f ); + } + if ( !params[ DEPTHBLURSTRENGTH ]->IsDefined() ) + { + params[ DEPTHBLURSTRENGTH ]->SetFloatValue( 0.0f ); + } + if ( !params[ SCREENBLURSTRENGTH ]->IsDefined() ) + { + params[ SCREENBLURSTRENGTH ]->SetFloatValue( 0.0f ); + } + if ( !params[ TOOLMODE ]->IsDefined() ) + { + params[ TOOLMODE ]->SetIntValue( 0 ); + } + if ( !params[ TOOLCOLORCORRECTION ]->IsDefined() ) + { + params[ TOOLCOLORCORRECTION ]->SetFloatValue( 0.0f ); + } + if ( !params[ VOMITENABLE ]->IsDefined() ) + { + params[ VOMITENABLE ]->SetIntValue( 0 ); + } + if ( !params[ VOMITREFRACTSCALE ]->IsDefined() ) + { + params[ VOMITREFRACTSCALE ]->SetFloatValue( 0.15f ); + } + if ( !params[ VOMITCOLOR1 ]->IsDefined() ) + { + params[ VOMITCOLOR1 ]->SetVecValue( 1.0, 1.0, 0.0 ); + } + if ( !params[ VOMITCOLOR2 ]->IsDefined() ) + { + params[ VOMITCOLOR2 ]->SetVecValue( 0.0, 1.0, 0.0 ); + } + if ( !params[ FADE ]->IsDefined() ) + { + params[ FADE ]->SetIntValue( 0 ); + } + if ( !params[ FADECOLOR ]->IsDefined() ) + { + params[ FADECOLOR ]->SetVecValue( 0.0f, 0.0f, 0.0f, 0.0f ); + } + if ( !params[ TV_GAMMA ]->IsDefined() ) + { + params[ TV_GAMMA ]->SetIntValue( 0 ); + } + if ( !params[ DESATURATEENABLE ]->IsDefined() ) + { + params[ DESATURATEENABLE ]->SetIntValue( 0 ); + } + if ( !params[ DESATURATION ]->IsDefined() ) + { + params[ DESATURATION ]->SetFloatValue( 0.0f ); + } + + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE ); + } + + SHADER_FALLBACK + { + // This shader should not be *used* unless we're >= DX9 (bloomadd.vmt/screenspace_general_dx8 should be used for DX8) + return 0; + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + + if ( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + + if ( params[SCREENEFFECTTEXTURE]->IsDefined() ) + { + LoadTexture( SCREENEFFECTTEXTURE ); + } + + if ( params[NOISETEXTURE]->IsDefined() ) + { + LoadTexture( NOISETEXTURE ); + } + + if ( params[INTERNAL_VIGNETTETEXTURE]->IsDefined() ) + { + LoadTexture( INTERNAL_VIGNETTETEXTURE ); + } + } + + SHADER_DRAW + { + bool bToolMode = params[TOOLMODE]->GetIntValue() != 0; + bool bDepthBlurEnable = params[ DEPTHBLURENABLE ]->GetIntValue() != 0; + + SHADOW_STATE + { + // This shader uses opaque blending, but needs to match the behaviour of bloom_add/screen_spacegeneral, + // which uses additive blending (and is used when bloom is enabled but col-correction and AA are not). + // BUT! + // Hardware sRGB blending is incorrect (on pre-DX10 cards, sRGB values are added directly). + // SO... + // When doing the bloom addition in the pixel shader, we need to emulate that incorrect + // behaviour - by turning sRGB read OFF for the FB texture and by turning sRGB write OFF + // (which is fine, since the AA process works better on an sRGB framebuffer than a linear + // one; gamma colours more closely match luminance perception. The color-correction process + // has always taken gamma-space values as input anyway). + + pShaderShadow->EnableBlending( false ); + + // The (sRGB) bloom texture is bound to sampler 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + pShaderShadow->EnableSRGBWrite( false ); + + // The (sRGB) full framebuffer texture is bound to sampler 1: + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + + // Up to 4 (sRGB) color-correction lookup textures are bound to samplers 2-5: + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false ); + + // Noise + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); + + // Vignette + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, false ); + + // Screen effect texture + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, false ); + + pShaderShadow->EnableSRGBWrite( false ); + + int format = VERTEX_POSITION; + int numTexCoords = 1; + int * pTexCoordDimensions = NULL; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( format, numTexCoords, pTexCoordDimensions, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_engine_post_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( TOOL_MODE, bToolMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTH_BLUR_ENABLE, bDepthBlurEnable ); + SET_STATIC_PIXEL_SHADER( sdk_engine_post_ps30 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + // FIXME: need to set FBTEXTURE to be point-sampled (will speed up this shader significantly on 360) + // and assert that it's set to SHADER_TEXWRAPMODE_CLAMP (since the shader will sample offscreen) + BindTexture( SHADER_SAMPLER1, FBTEXTURE, -1 ); + + ShaderColorCorrectionInfo_t ccInfo = { false, 0, 1.0f, { 1.0f, 1.0f, 1.0f, 1.0f } }; + + float flTime; + if ( bToolMode ) + { + flTime = params[TOOLTIME]->GetFloatValue(); + } + else + { + flTime = pShaderAPI->CurrentTime(); + } + + // PC, ps20b has a desaturation control that overrides color correction + bool bDesaturateEnable = bToolMode && ( params[DESATURATEENABLE]->GetIntValue() != 0 ) && g_pHardwareConfig->SupportsPixelShaders_2_b(); + + float vPsConst16[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst16[0] = params[ DESATURATION ]->GetFloatValue(); + vPsConst16[1] = ( params[FADE]->GetIntValue() == 2 ) ? 1.0f : 0.0f; // Enable lerping to ( color * fadecolor ) for FADE_COLOR=2 + pShaderAPI->SetPixelShaderConstant( 16, vPsConst16, 1 ); + + if ( params[FADE]->GetIntValue() == 0 ) + { + // Not fading, so set the constant to cause nothing to change about the pixel color + float vConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 15, vConst ); + } + else + { + pShaderAPI->SetPixelShaderConstant( 15, params[ FADECOLOR ]->GetVecValue(), 1 ); + } + + if ( !bDesaturateEnable ) // set up color correction + { + bool bToolColorCorrection = params[TOOLCOLORCORRECTION]->GetIntValue() != 0; + if ( bToolColorCorrection ) + { + ccInfo.m_bIsEnabled = true; + + ccInfo.m_nLookupCount = (int) params[NUM_LOOKUPS]->GetFloatValue(); + ccInfo.m_flDefaultWeight = params[WEIGHT_DEFAULT]->GetFloatValue(); + ccInfo.m_pLookupWeights[0] = params[WEIGHT0]->GetFloatValue(); + ccInfo.m_pLookupWeights[1] = params[WEIGHT1]->GetFloatValue(); + ccInfo.m_pLookupWeights[2] = params[WEIGHT2]->GetFloatValue(); + ccInfo.m_pLookupWeights[3] = params[WEIGHT3]->GetFloatValue(); + } + else + { + pShaderAPI->GetCurrentColorCorrection( &ccInfo ); + } + } + + int colCorrectNumLookups = MIN( ccInfo.m_nLookupCount, 3 ); + for ( int i = 0; i < colCorrectNumLookups; i++ ) + { + pShaderAPI->BindStandardTexture( (Sampler_t)(SHADER_SAMPLER2 + i), (StandardTextureId_t)(TEXTURE_COLOR_CORRECTION_VOLUME_0 + i) ); + } + + // Upload 1-pixel X&Y offsets [ (+dX,0,+dY,-dX) is chosen to work with the allowed ps20 swizzles ] + // The shader will sample in a cross (up/down/left/right from the current sample), for 5-tap + // (quality 0) mode and add another 4 samples in a diagonal cross, for 9-tap (quality 1) mode + ITexture * pTarget = params[FBTEXTURE]->GetTextureValue(); + int width = pTarget->GetActualWidth(); + int height = pTarget->GetActualHeight(); + float dX = 1.0f / width; + float dY = 1.0f / height; + float offsets[4] = { +dX, 0, +dY, -dX }; + pShaderAPI->SetPixelShaderConstant( 0, &offsets[0], 1 ); + + // Upload AA tweakables: + // x - strength (this can be used to toggle the AA off, or to weaken it where pathological cases are showing) + // y - reduction of 1-pixel-line blurring (blurring of 1-pixel lines causes issues, so it's tunable) + // z - edge threshold multiplier (default 1.0, < 1.0 => more edges softened, > 1.0 => fewer edges softened) + // w - tap offset multiplier (default 1.0, < 1.0 => sharper image, > 1.0 => blurrier image) + float tweakables[4] = { params[ AAINTERNAL1 ]->GetVecValue()[0], + params[ AAINTERNAL1 ]->GetVecValue()[1], + params[ AAINTERNAL3 ]->GetVecValue()[0], + params[ AAINTERNAL3 ]->GetVecValue()[1] }; + pShaderAPI->SetPixelShaderConstant( 1, &tweakables[0], 1 ); + + // Upload AA UV transform (converts bloom texture UVs to framebuffer texture UVs) + // NOTE: we swap the order of the z and w components since 'wz' is an allowed ps20 swizzle, but 'zw' is not: + float uvTrans[4] = { params[ AAINTERNAL2 ]->GetVecValue()[0], + params[ AAINTERNAL2 ]->GetVecValue()[1], + params[ AAINTERNAL2 ]->GetVecValue()[3], + params[ AAINTERNAL2 ]->GetVecValue()[2] }; + pShaderAPI->SetPixelShaderConstant( 2, &uvTrans[0], 1 ); + + // Upload color-correction weights: + pShaderAPI->SetPixelShaderConstant( 3, &ccInfo.m_flDefaultWeight ); + pShaderAPI->SetPixelShaderConstant( 4, ccInfo.m_pLookupWeights ); + + int aaEnabled = 0; + int bloomEnabled = ( params[ BLOOMENABLE ]->GetIntValue() == 0 ) ? 0 : 1; + int colCorrectEnabled = ccInfo.m_bIsEnabled; + + float flBloomFactor = bloomEnabled ? 1.0f : 0.0f; + flBloomFactor *= params[BLOOMAMOUNT]->GetFloatValue(); + float bloomConstant[4] = + { + flBloomFactor, + params[ SCREENBLURSTRENGTH ]->GetFloatValue(), + params[ DEPTHBLURFOCALDISTANCE ]->GetFloatValue(), + params[ DEPTHBLURSTRENGTH ]->GetFloatValue() + }; + + if ( mat_screen_blur_override.GetFloat() >= 0.0f ) + { + bloomConstant[1] = mat_screen_blur_override.GetFloat(); + } + if ( mat_depth_blur_focal_distance_override.GetFloat() >= 0.0f ) + { + bloomConstant[2] = mat_depth_blur_focal_distance_override.GetFloat(); + } + if ( mat_depth_blur_strength_override.GetFloat() >= 0.0f ) + { + bloomConstant[3] = mat_depth_blur_strength_override.GetFloat(); + } + + pShaderAPI->SetPixelShaderConstant( 5, bloomConstant ); + + // Vignette + bool bVignetteEnable = ( params[ VIGNETTEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWVIGNETTE ]->GetIntValue() != 0 ); + if ( bVignetteEnable ) + { + BindTexture( SHADER_SAMPLER7, INTERNAL_VIGNETTETEXTURE ); + } + + // Noise + bool bNoiseEnable = ( params[ NOISEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWNOISE ]->GetIntValue() != 0 ); + + int nFbTextureHeight = params[FBTEXTURE]->GetTextureValue()->GetActualHeight(); + if ( nFbTextureHeight < 720 ) + { + // Disable noise at low resolutions + bNoiseEnable = false; + } + + if ( bNoiseEnable ) + { + BindTexture( SHADER_SAMPLER6, NOISETEXTURE ); + + // Noise scale + float vPsConst6[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst6[0] = params[ NOISESCALE ]->GetFloatValue(); + if ( mat_grain_scale_override.GetFloat() != -1.0f ) + { + vPsConst6[0] = mat_grain_scale_override.GetFloat(); + } + + if ( vPsConst6[0] <= 0.0f ) + { + bNoiseEnable = false; + } + + pShaderAPI->SetPixelShaderConstant( 6, vPsConst6 ); + + // Time % 1000 for scrolling + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = flTime; + vPsConst[0] -= (float)( (int)( vPsConst[0] / 1000.0f ) ) * 1000.0f; + pShaderAPI->SetPixelShaderConstant( 7, vPsConst, 1 ); + } + + // Local Contrast + bool bLocalContrastEnable = ( params[ LOCALCONTRASTENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWLOCALCONTRAST ]->GetIntValue() != 0 ); + bool bBlurredVignetteEnable = ( bLocalContrastEnable ) && ( params[ BLURREDVIGNETTEENABLE ]->GetIntValue() != 0 ); + + if ( bLocalContrastEnable ) + { + // Contrast scale + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = params[ LOCALCONTRASTSCALE ]->GetFloatValue(); + if ( mat_local_contrast_scale_override.GetFloat() != 0.0f ) + { + vPsConst[0] = mat_local_contrast_scale_override.GetFloat(); + } + vPsConst[1] = params[ LOCALCONTRASTMIDTONEMASK ]->GetFloatValue(); + if ( mat_local_contrast_midtone_mask_override.GetFloat() >= 0.0f ) + { + vPsConst[1] = mat_local_contrast_midtone_mask_override.GetFloat(); + } + vPsConst[2] = params[ BLURREDVIGNETTESCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 8, vPsConst, 1 ); + + vPsConst[0] = params[ LOCALCONTRASTVIGNETTESTART ]->GetFloatValue(); + if ( mat_local_contrast_vignette_start_override.GetFloat() >= 0.0f ) + { + vPsConst[0] = mat_local_contrast_vignette_start_override.GetFloat(); + } + vPsConst[1] = params[ LOCALCONTRASTVIGNETTEEND ]->GetFloatValue(); + if ( mat_local_contrast_vignette_end_override.GetFloat() >= 0.0f ) + { + vPsConst[1] = mat_local_contrast_vignette_end_override.GetFloat(); + } + vPsConst[2] = params[ LOCALCONTRASTEDGESCALE ]->GetFloatValue(); + if ( mat_local_contrast_edge_scale_override.GetFloat() >= -1.0f ) + { + vPsConst[2] = mat_local_contrast_edge_scale_override.GetFloat(); + } + pShaderAPI->SetPixelShaderConstant( 9, vPsConst, 1 ); + } + + // fade to black + float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst[0] = params[ FADETOBLACKSCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 10, vPsConst, 1 ); + + bool bVomitEnable = ( params[ VOMITENABLE ]->GetIntValue() != 0 ); + if ( bVomitEnable ) + { + BindTexture( SHADER_SAMPLER8, SCREENEFFECTTEXTURE ); + + params[ VOMITCOLOR1 ]->GetVecValue( vPsConst, 3 ); + vPsConst[3] = params[ VOMITREFRACTSCALE ]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 11, vPsConst, 1 ); + params[ VOMITCOLOR2 ]->GetVecValue( vPsConst, 3 ); + vPsConst[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 12, vPsConst, 1 ); + + // Get viewport and render target dimensions and set shader constant to do a 2D mad + ShaderViewport_t vp; + pShaderAPI->GetViewports( &vp, 1 ); + int nViewportX = vp.m_nTopLeftX; + int nViewportY = vp.m_nTopLeftY; + int nViewportWidth = vp.m_nWidth; + int nViewportHeight = vp.m_nHeight; + + int nRtWidth, nRtHeight; + ITexture *pRenderTarget = pShaderAPI->GetRenderTargetEx( 0 ); + if( pRenderTarget != nullptr ) + { + nRtWidth = pRenderTarget->GetActualWidth(); + nRtHeight = pRenderTarget->GetActualHeight(); + } + else + { + pShaderAPI->GetBackBufferDimensions( nRtWidth, nRtHeight ); + } + + float vViewportMad[4]; + + // screen->viewport transform + vViewportMad[0] = ( float )nRtWidth / ( float )nViewportWidth; + vViewportMad[1] = ( float )nRtHeight / ( float )nViewportHeight; + vViewportMad[2] = -( float )nViewportX / ( float )nViewportWidth; + vViewportMad[3] = -( float )nViewportY / ( float )nViewportHeight; + pShaderAPI->SetPixelShaderConstant( 13, vViewportMad, 1 ); + + // viewport->screen transform + vViewportMad[0] = ( float )nViewportWidth / ( float )nRtWidth; + vViewportMad[1] = ( float )nViewportHeight / ( float )nRtHeight; + vViewportMad[2] = ( float )nViewportX / ( float )nRtWidth; + vViewportMad[3] = ( float )nViewportY / ( float )nRtHeight; + pShaderAPI->SetPixelShaderConstant( 14, vViewportMad, 1 ); + } + + if ( !colCorrectEnabled ) + { + colCorrectNumLookups = 0; + } + + bool bConvertFromLinear = ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT ); + + // JasonM - double check this if the SFM needs to use the engine post FX clip in main + bool bConvertToLinear = bToolMode && bConvertFromLinear && ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_engine_post_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_FROM_LINEAR, bConvertFromLinear ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_TO_LINEAR, bConvertToLinear ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NOISE_ENABLE, bNoiseEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( VIGNETTE_ENABLE, bVignetteEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LOCAL_CONTRAST_ENABLE, bLocalContrastEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( BLURRED_VIGNETTE_ENABLE, bBlurredVignetteEnable ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( VOMIT_ENABLE, bVomitEnable ); + SET_DYNAMIC_PIXEL_SHADER( sdk_engine_post_ps30 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/example_model_dx9.cpp b/materialsystem/stdshaders/example_model_dx9.cpp deleted file mode 100644 index 12b6ee11..00000000 --- a/materialsystem/stdshaders/example_model_dx9.cpp +++ /dev/null @@ -1,60 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#include "BaseVSShader.h" -#include "convar.h" -#include "example_model_dx9_helper.h" - -#ifdef GAME_SHADER_DLL -DEFINE_FALLBACK_SHADER( Mod_Example_Model, Mod_Example_Model_DX9 ) -BEGIN_VS_SHADER( Mod_Example_Model_DX9, "Help for Example Model Shader" ) -#else -DEFINE_FALLBACK_SHADER( Example_Model, Example_Model_DX9 ) -BEGIN_VS_SHADER( Example_Model_DX9, "Help for Example Model Shader" ) -#endif - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - END_SHADER_PARAMS - - void SetupVars( ExampleModel_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - } - - SHADER_INIT_PARAMS() - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - InitParamsExampleModel_DX9( this, params, pMaterialName, info ); - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - InitExampleModel_DX9( this, params, info ); - } - - SHADER_DRAW - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - DrawExampleModel_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); - } - -END_SHADER - diff --git a/materialsystem/stdshaders/example_model_dx9_helper.cpp b/materialsystem/stdshaders/example_model_dx9_helper.cpp deleted file mode 100644 index af556358..00000000 --- a/materialsystem/stdshaders/example_model_dx9_helper.cpp +++ /dev/null @@ -1,341 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "example_model_dx9_helper.h" -#include "convar.h" -#include "cpp_shader_constant_register_map.h" -#include "example_model_vs30.inc" -#include "example_model_ps30.inc" -#include "commandbuilder.h" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); -static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); -static ConVar r_rimlight( "r_rimlight", "1", FCVAR_NONE ); - -// Textures may be bound to the following samplers: -// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha -// SHADER_SAMPLER4 Flashlight Shadow Depth Map -// SHADER_SAMPLER5 Normalization cube map -// SHADER_SAMPLER6 Flashlight Cookie - - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, ExampleModel_DX9_Vars_t &info ) -{ - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - Assert( info.m_nFlashlightTexture >= 0 ); - - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - // This shader can be used with hw skinning - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); -} - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- -void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, ExampleModel_DX9_Vars_t &info ) -{ - Assert( info.m_nFlashlightTexture >= 0 ); - pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); - - bool bIsBaseTextureTranslucent = false; - if ( params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - } -} - -class CExampleModel_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - bool m_bFastPath; - -}; - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawExampleModel_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bHasFlashlight, ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - - BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); - bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; - - CExampleModel_DX9_Context *pContextData = reinterpret_cast< CExampleModel_DX9_Context *> ( *pContextDataPtr ); - if ( !pContextData ) - { - pContextData = new CExampleModel_DX9_Context; - *pContextDataPtr = pContextData; - } - - if( pShader->IsSnapshotting() ) - { - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if( bHasFlashlight ) - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - - if( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - else // not flashlight pass - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); - } - } - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int userDataSize = 0; - - // Always enable...will bind white if nothing specified... - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - if( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); - userDataSize = 4; // tangent S - } - - // Always enable, since flat normal will be bound - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map - userDataSize = 4; // tangent S - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map - pShaderShadow->EnableSRGBWrite( true ); - - // texcoord0 : base texcoord, texcoord2 : decal hw morph delta - int pTexCoordDim[3] = { 2, 0, 3 }; - int nTexCoordCount = 1; - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( example_model_vs30 ); - SET_STATIC_VERTEX_SHADER(example_model_vs30); - - // Assume we're only going to get in here if we support 2b - DECLARE_STATIC_PIXEL_SHADER( example_model_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - //SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER(example_model_ps30); - - if( bHasFlashlight ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - else // not snapshotting -- begin dynamic state - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - - if( bHasBaseTexture ) - { - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - } - - LightState_t lightState = { 0, false, false }; - bool bFlashlightShadows = false; - if( bHasFlashlight ) - { - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); - - SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - } - else // no flashlight - { - pShaderAPI->GetDX9LightState( &lightState ); - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - int numBones = pShaderAPI->GetCurrentNumBones(); - - bool bWriteDepthToAlpha = false; - bool bWriteWaterFogToAlpha = false; - if( bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - - DECLARE_DYNAMIC_VERTEX_SHADER( example_model_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER(example_model_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER( example_model_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - //SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - //SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER(example_model_ps30); - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - pShader->SetAmbientCubeDynamicStateVertexShader(); - - if( !bHasFlashlight ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); - } - - pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight - pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); - - // handle mat_fullbright 2 (diffuse lighting only) - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - if( bHasFlashlight ) - { - VMatrix worldToTexture; - float atten[4], pos[4], tweaks[4]; - - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); - - // Tweaks associated with a given flashlight - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - } - } - pShader->Draw(); -} - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) - -{ - bool bHasFlashlight = pShader->UsingFlashlight( params ); - if ( bHasFlashlight ) - { - DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); - if ( pShaderShadow ) - { - pShader->SetInitialShadowState( ); - } - } - DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/example_model_dx9_helper.h b/materialsystem/stdshaders/example_model_dx9_helper.h deleted file mode 100644 index dfe2579c..00000000 --- a/materialsystem/stdshaders/example_model_dx9_helper.h +++ /dev/null @@ -1,46 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#ifndef EXAMPLE_MODEL_DX9_HELPER_H -#define EXAMPLE_MODEL_DX9_HELPER_H - -#include - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct ExampleModel_DX9_Vars_t -{ - ExampleModel_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } - - int m_nBaseTexture; - int m_nBaseTextureFrame; - int m_nBaseTextureTransform; - int m_nAlphaTestReference; - int m_nFlashlightTexture; - int m_nFlashlightTextureFrame; -}; - -void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, - const char *pMaterialName, ExampleModel_DX9_Vars_t &info ); - -void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, - ExampleModel_DX9_Vars_t &info ); - -void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, - ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ); - -#endif // EXAMPLE_MODEL_DX9_HELPER_H diff --git a/materialsystem/stdshaders/example_model_ps20b.fxc b/materialsystem/stdshaders/example_model_ps20b.fxc deleted file mode 100644 index 29ed629a..00000000 --- a/materialsystem/stdshaders/example_model_ps20b.fxc +++ /dev/null @@ -1,92 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example pixel shader that can be applied to models -// -//================================================================================================== - -// STATIC: "CONVERT_TO_SRGB" "0..0" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] - -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..4" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] - -// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" - -const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); -const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); -const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); -const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass -const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); -const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); -PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) - -#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz - -sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha -sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler -sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers -sampler FlashlightSampler : register( s6 ); // Flashlight cookie - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float4 lightAtten : TEXCOORD1; - float3 worldNormal : TEXCOORD2; - float3 worldPos : TEXCOORD3; - float3 projPos : TEXCOORD4; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); - - float3 diffuseLighting; - if ( FLASHLIGHT != 0 ) - { - float4 flashlightSpacePosition = mul( float4( i.worldPos, 1.0f ), g_FlashlightWorldToTexture ); - - diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos, flashlightSpacePosition, - i.worldNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, i.projPos, false, g_ShadowTweaks ); - } - else // non-flashlight path - { - // Summation of diffuse illumination from all local lights - diffuseLighting = PixelShaderDoLighting( i.worldPos, i.worldNormal, - float3( 0.0f, 0.0f, 0.0f ), false, true, i.lightAtten, - cAmbientCube, NormalizeRandRotSampler, NUM_LIGHTS, cLightInfo, true, - - // These are dummy parameters: - false, 1.0f, - false, BaseTextureSampler ); - } - - float3 result = baseColor.rgb * g_DiffuseModulation.rgb * diffuseLighting; - float alpha = g_DiffuseModulation.a * baseColor.a; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); - -#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) - alpha = fogFactor; -#endif - - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - - return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z ); -} diff --git a/materialsystem/stdshaders/example_model_vs20.fxc b/materialsystem/stdshaders/example_model_vs20.fxc deleted file mode 100644 index 6248f2b4..00000000 --- a/materialsystem/stdshaders/example_model_vs20.fxc +++ /dev/null @@ -1,91 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example vertex shader that can be applied to models -// -//================================================================================================== - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..4" - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); - -//----------------------------------------------------------------------------- -// Input vertex format -//----------------------------------------------------------------------------- -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float2 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - // Stuff that isn't seen by the pixel shader - float4 projPosSetup : POSITION; - float fog : FOG; - // Stuff that is seen by the pixel shader - float2 baseTexCoord : TEXCOORD0; - float4 lightAtten : TEXCOORD1; - float3 worldNormal : TEXCOORD2; - float3 worldPos : TEXCOORD3; - float3 projPos : TEXCOORD4; -}; - -//----------------------------------------------------------------------------- -// Main shader entry point -//----------------------------------------------------------------------------- -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vNormal; - DecompressVertex_Normal( v.vNormal, vNormal ); - - float3 worldNormal, worldPos; - SkinPositionAndNormal( g_bSkinning, v.vPos, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPosSetup = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.projPos = vProjPos.xyz; - o.fog = CalcFog( worldPos, vProjPos.xyz, g_FogType ); - - // Needed for water fog alpha and diffuse lighting - o.worldPos = worldPos; - o.worldNormal = normalize( worldNormal ); - - // Scalar attenuations for four lights - o.lightAtten.xyz = float4(0,0,0,0); - #if ( NUM_LIGHTS > 0 ) - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); - #endif - #if ( NUM_LIGHTS > 1 ) - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); - #endif - #if ( NUM_LIGHTS > 2 ) - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); - #endif - #if ( NUM_LIGHTS > 3 ) - o.lightAtten.w = GetVertexAttenForLight( worldPos, 3, false ); - #endif - - // Base texture coordinate transform - o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - - return o; -} diff --git a/materialsystem/stdshaders/eye_refract.cpp b/materialsystem/stdshaders/eye_refract.cpp index 87528028..d06e8f70 100644 --- a/materialsystem/stdshaders/eye_refract.cpp +++ b/materialsystem/stdshaders/eye_refract.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "eye_refract_helper.h" #include "cloak_blended_pass_helper.h" #include "emissive_scroll_blended_pass_helper.h" @@ -8,8 +8,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -DEFINE_FALLBACK_SHADER( EyeRefract, EyeRefract_dx9 ) -BEGIN_VS_SHADER( EyeRefract_dx9, "Help for Eyes" ) +BEGIN_VS_SHADER( EyeRefract, "Help for EyeRefract" ) BEGIN_SHADER_PARAMS SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "iris texture" ) SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) diff --git a/materialsystem/stdshaders/eye_refract_helper.cpp b/materialsystem/stdshaders/eye_refract_helper.cpp index b7aa4caf..098c98f1 100644 --- a/materialsystem/stdshaders/eye_refract_helper.cpp +++ b/materialsystem/stdshaders/eye_refract_helper.cpp @@ -1,22 +1,12 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "mathlib/vmatrix.h" #include "eye_refract_helper.h" #include "cpp_shader_constant_register_map.h" - -#include "eyes_flashlight_vs11.inc" -#include "eyes_flashlight_ps11.inc" - -#include "eye_refract_vs20.inc" -#include "eye_refract_ps20.inc" -#include "eye_refract_ps20b.inc" - -#ifndef _X360 -#include "eye_refract_vs30.inc" -#include "eye_refract_ps30.inc" -#endif +#include "sdk_eye_refract_vs30.inc" +#include "sdk_eye_refract_ps30.inc" #include "convar.h" @@ -137,80 +127,36 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, } pShaderShadow->EnableDepthWrites( false ); - pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Flashlight cookie } -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( eye_refract_vs20 ); + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); - bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); - - DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( eye_refract_ps20b ); - - if ( bDrawFlashlightAdditivePass == true ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER6 ); - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map - } - } - else - { - DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER( eye_refract_ps20 ); - } - } -#ifndef _X360 - else + DECLARE_STATIC_VERTEX_SHADER( sdk_eye_refract_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_eye_refract_vs30 ); + + bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); + bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_eye_refract_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( sdk_eye_refract_ps30 ); + + if ( bDrawFlashlightAdditivePass == true ) { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( eye_refract_vs30 ); - - bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); - bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); - - DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( eye_refract_ps30 ); - - if ( bDrawFlashlightAdditivePass == true ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map - } + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map } -#endif // On DX9, get the gamma read and write correct pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Iris @@ -249,7 +195,7 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); pShader->BindTexture( SHADER_SAMPLER2, info.m_nEnvmap ); pShader->BindTexture( SHADER_SAMPLER3, info.m_nAmbientOcclTexture ); - + if ( bDiffuseWarp ) { if ( r_lightwarpidentity.GetBool() ) @@ -280,38 +226,18 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, pShaderAPI->GetDX9LightState( &lightState ); } -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); - } -#ifndef _X360 - else - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); - } -#endif + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_eye_refract_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_eye_refract_vs30 ); // Get luminance of ambient cube and saturate it - float fAverageAmbient = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + float fAverageAmbient = MAX(0.0f, MIN( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); // Special constant for DX9 eyes: { Dilation, Glossiness, x, x }; float vPSConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -355,33 +281,10 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, } // Flashlight tax -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); - } - else // ps.2.0 - { - DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); - } - } -#ifndef _X360 - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); - } -#endif + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_eye_refract_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_eye_refract_ps30 ); pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); @@ -437,7 +340,7 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, { params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, timeVec, 1 ); } } pShader->Draw(); diff --git a/materialsystem/stdshaders/eye_refract_ps2x.fxc b/materialsystem/stdshaders/eye_refract_ps2x.fxc deleted file mode 100644 index da053d22..00000000 --- a/materialsystem/stdshaders/eye_refract_ps2x.fxc +++ /dev/null @@ -1,494 +0,0 @@ -//====== Copyright 1996-2007, Valve Corporation, All rights reserved. =========================== - -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "LIGHTWARPTEXTURE" "0..1" - -// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps20b] -// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps30] - -// STATIC: "RAYTRACESPHERE" "0..1" [ps20b] -// STATIC: "RAYTRACESPHERE" "0..1" [ps30] - -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] - -// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] - -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] - -// We don't use other lights when doing the flashlight -// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] - -// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps30] -// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps20b] - -// Debug 2.0 shader locally -//#ifdef SHADER_MODEL_PS_2_B -//#undef SHADER_MODEL_PS_2_B -//#define SHADER_MODEL_PS_2_0 -//#endif - - -// Includes ======================================================================================= -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" - -// Texture Samplers =============================================================================== -sampler g_tCorneaSampler : register( s0 ); -sampler g_tIrisSampler : register( s1 ); -sampler g_tEyeReflectionCubemapSampler : register( s2 ); -sampler g_tEyeAmbientOcclSampler : register( s3 ); -sampler g_tLightwarpSampler : register( s4 ); // 1D texture for TF NPR lighting - -sampler g_tFlashlightCookieSampler : register( s5 ); -sampler g_tFlashlightDepthSampler : register( s6 ); -sampler g_tRandomRotationSampler : register( s7 ); - -// Shaders Constants and Globals ================================================================== -const float4 g_vPackedConst0 : register( c0 ); -#define g_flDilationFactor g_vPackedConst0.x -#define g_flGlossiness g_vPackedConst0.y -#define g_flAverageAmbient g_vPackedConst0.z -#define g_flCorneaBumpStrength g_vPackedConst0.w - -const float3 g_vEyeOrigin : register( c1 ); -const float4 g_vIrisProjectionU : register( c2 ); -const float4 g_vIrisProjectionV : register( c3 ); -const float4 g_vCameraPosition : register( c4 ); -const float3 g_cAmbientOcclColor : register( c5 ); - -const float4 g_vPackedConst6 : register( c6 ); -#define g_flEyeballRadius g_vPackedConst6.y //0.51f -//#define g_bRaytraceSphere g_vPackedConst6.z //1.0f -#define g_flParallaxStrength g_vPackedConst6.w //0.25f - -// Flashlight constants -const float4 g_vFlashlightAttenuationFactors : register( c7 ); // FarZ in w -const float3 g_vFlashlightPos : register( c8 ); -const float4 g_vShadowTweaks : register( c9 ); -const float4 g_ShaderControls : register( c10 ); -#define g_fPixelFogType g_ShaderControls.x - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); - -PixelShaderLightInfo g_sLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total - -// Interpolated values ============================================================================ -struct PS_INPUT -{ - float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; - float4 cVertexLight : TEXCOORD1; // w is used for the flashlight pass - float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) - float4 vWorldPosition_ProjPosZ : TEXCOORD3; - float3 vWorldNormal : TEXCOORD4; // World-space normal - float3 vWorldTangent : TEXCOORD5; // World-space tangent - float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights - float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights - - float3 vWorldBinormal : COLOR0; // World-space normal -}; - -// Ray sphere intersect returns distance along ray to intersection ================================ -float IntersectRaySphere ( float3 cameraPos, float3 ray, float3 sphereCenter, float sphereRadius) -{ - float3 dst = cameraPos.xyz - sphereCenter.xyz; - float B = dot(dst, ray); - float C = dot(dst, dst) - (sphereRadius * sphereRadius); - float D = B*B - C; - return (D > 0) ? (-B - sqrt(D)) : 0; -} - -// Calculate both types of Fog and lerp to get result -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); - return lerp( fRangeFog, fHeightFog, fPixelFogType ); -} - -// Blend both types of Fog and lerp to get result -float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) -{ - pixelFogFactor = saturate( pixelFogFactor ); - float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog - float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - return lerp( fRangeResult, fHeightResult, fPixelFogType ); -} - -float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE ) -{ - float4 result = vShaderColor; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb *= LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb *= GAMMA_LIGHT_SCALE; - } - - result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion - - return result; -} - - -// Main =========================================================================================== -float4 main( PS_INPUT i ) : COLOR -{ - // Set bools to compile out code - bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; - bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; - int nNumLights = FLASHLIGHT ? 1 : NUM_LIGHTS; // Flashlight is considered one light, otherwise, use numlights combo - -#if !defined( SHADER_MODEL_PS_2_0 ) - bool bRayCast = RAYTRACESPHERE ? true : false; - bool bRayCastTexKill = SPHERETEXKILLCOMBO ? true : false; -#endif - - float flFlashlightNDotL = i.vTangentViewVector.w; - float4 vFlashlightTexCoord = { 0.0f, 0.0f, 0.0f, 0.0f }; - if ( bFlashlight ) - { - vFlashlightTexCoord.xyzw = i.cVertexLight.xyzw; // This was hidden in this interpolator - i.cVertexLight.rgba = float4( 0.0f, 0.0f, 0.0f, 0.0f ); - } - - // Interpolated vectors - float3 vWorldNormal = i.vWorldNormal.xyz; - float3 vWorldTangent = i.vWorldTangent.xyz; - float3 vWorldBinormal = ( i.vWorldBinormal.xyz * 2.0f ) - 1.0f; // normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); - - float3 vTangentViewVector = i.vTangentViewVector.xyz; - - // World position - float3 vWorldPosition = i.vWorldPosition_ProjPosZ.xyz; - - // World view vector to pixel - float3 vWorldViewVector = normalize( vWorldPosition.xyz - g_vCameraPosition.xyz ); - - //=================// - // TF NPR lighting // - //=================// - if ( bDoDiffuseWarp ) - { - // Replace the interpolated vertex light - if ( bFlashlight == true ) - { - // Deal with this below in the flashlight section - } - else - { - if ( nNumLights > 0 ) - { - float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.z ).rgb; - i.cVertexLight.rgb += i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ) * cWarpedLight.rgb; - } - - if ( nNumLights > 1 ) - { - float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.w ).rgb; - i.cVertexLight.rgb += i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ) * cWarpedLight.rgb; - } - - if ( nNumLights > 2 ) - { - float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.z ).rgb; - i.cVertexLight.rgb += i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ) * cWarpedLight.rgb; - } - - if ( nNumLights > 3 ) - { - float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.w ).rgb; - i.cVertexLight.rgb += i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ) * cWarpedLight.rgb; - } - } - } - - //==========================================================================================================// - // Ray cast against sphere representing eyeball to reduce artifacts from non-spherical morphed eye geometry // - //==========================================================================================================// -#if !defined( SHADER_MODEL_PS_2_0 ) - if ( bRayCast ) - { - float fSphereRayCastDistance = IntersectRaySphere( g_vCameraPosition.xyz, vWorldViewVector.xyz, g_vEyeOrigin.xyz, g_flEyeballRadius ); - vWorldPosition.xyz = g_vCameraPosition.xyz + ( vWorldViewVector.xyz * fSphereRayCastDistance ); - if (fSphereRayCastDistance == 0) - { - if ( bRayCastTexKill ) - clip(-1); // texkill to get a better silhouette - vWorldPosition.xyz = g_vEyeOrigin.xyz + ( vWorldNormal.xyz * g_flEyeballRadius ); - } - } -#endif - - //=================================// - // Generate sphere and cornea uv's // - //=================================// -#if !defined( SHADER_MODEL_PS_2_0 ) - float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture - vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); - vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); - float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; -#else // ps_20 - float2 vCorneaUv = i.vAmbientOcclUv_fallbackCorneaUv.wz; // Note: Cornea texture is a cropped version of the iris texture - float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; -#endif - - //=================================// - // Hacked parallax mapping on iris // - //=================================// - float fIrisOffset = tex2D( g_tCorneaSampler, vCorneaUv.xy ).b; - -#if !defined( SHADER_MODEL_PS_2_0 ) - float2 vParallaxVector = ( ( vTangentViewVector.xy * fIrisOffset * g_flParallaxStrength ) / ( 1.0f - vTangentViewVector.z ) ); // Note: 0.25 is a magic number - vParallaxVector.x = -vParallaxVector.x; //Need to flip x...not sure why. - //vParallaxVector.x *= -1.0; //Need to flip x...not sure why. - //vParallaxVector = 0.0f; //Disable parallax for debugging -#else // Disable parallax effect in 2.0 version - float2 vParallaxVector = { 0.0f, 0.0f }; -#endif - - float2 vIrisUv = vSphereUv.xy - vParallaxVector.xy; - - // Note: We fetch from this texture twice right now with different uv's for the color and alpha - float2 vCorneaNoiseUv = vSphereUv.xy + ( vParallaxVector.xy * 0.5 ); - float fCorneaNoise = tex2D( g_tIrisSampler, vCorneaNoiseUv.xy ).a; - - //===============// - // Cornea normal // - //===============// - // Sample 2D normal from texture - float3 vCorneaTangentNormal = { 0.0, 0.0, 1.0 }; - float4 vCorneaSample = tex2D( g_tCorneaSampler, vCorneaUv.xy ); - vCorneaTangentNormal.xy = vCorneaSample.rg - 0.5f; // Note: This scales the bump to 50% strength - - // Scale strength of normal - vCorneaTangentNormal.xy *= g_flCorneaBumpStrength; - - // Add in surface noise and imperfections (NOTE: This should be baked into the normal map!) - vCorneaTangentNormal.xy += fCorneaNoise * 0.1f; - - // Normalize tangent vector -#if !defined( SHADER_MODEL_PS_2_0 ) - // Since this isn't used later in 2.0, skip the normalize to save shader instructions - vCorneaTangentNormal.xyz = normalize( vCorneaTangentNormal.xyz ); -#endif - - // Transform into world space - float3 vCorneaWorldNormal = Vec3TangentToWorldNormalized( vCorneaTangentNormal.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); - - //============// - // Flashlight // - //============// - float3 vFlashlightVector = { 0.0f, 0.0f, 0.0f }; - float3 cFlashlightColorFalloff = { 0.0f, 0.0f, 0.0f }; - if ( bFlashlight == true ) - { - // Flashlight vector - vFlashlightVector.xyz = normalize( g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz ); - - // Distance attenuation for flashlight and to fade out shadow over distance - float3 vDelta = g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz; - float flDistSquared = dot( vDelta, vDelta ); - float flDist = sqrt( flDistSquared ); - float flFlashlightAttenuation = dot( g_vFlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/flDist, 1.0f/flDistSquared ) ); - - // Flashlight cookie -#if !defined( SHADER_MODEL_PS_2_0 ) - float3 vProjCoords = vFlashlightTexCoord.xyz / vFlashlightTexCoord.w; - float3 cFlashlightCookieColor = tex2D( g_tFlashlightCookieSampler, vProjCoords ); -#else - float3 cFlashlightCookieColor = tex2Dproj( g_tFlashlightCookieSampler, vFlashlightTexCoord.xyzw ); -#endif - - // Shadow depth map -#if FLASHLIGHTSHADOWS && !defined( SHADER_MODEL_PS_2_0 ) - int nShadowLevel = FLASHLIGHTDEPTHFILTERMODE; - float flShadow = DoFlashlightShadow( g_tFlashlightDepthSampler, g_tRandomRotationSampler, vProjCoords, float2(0,0), nShadowLevel, g_vShadowTweaks, false ); - float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = lerp( flAttenuated, flShadow, flFlashlightAttenuation ); // Blend between shadow and above, according to light attenuation - cFlashlightCookieColor *= flShadow; // Apply shadow term to cookie color -#endif - - // Flashlight color intensity (needs to be multiplied by global flashlight color later) - cFlashlightColorFalloff.rgb = flFlashlightAttenuation * cFlashlightCookieColor.rgb; - - // Add this into the interpolated lighting - if ( bDoDiffuseWarp ) - { - //float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, flFlashlightNDotL ).rgb; - //i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * cWarpedLight.rgb; - i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; // No light warp for now - } - else - { - i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; - } - } - - //==============// - // Dilate pupil // - //==============// -#if !defined( SHADER_MODEL_PS_2_0 ) - vIrisUv.xy -= 0.5f; // Center around (0,0) - float fPupilCenterToBorder = saturate( length( vIrisUv.xy ) / 0.2f ); //Note: 0.2 is the uv radius of the iris - float fPupilDilateFactor = g_flDilationFactor; // This value should be between 0-1 - vIrisUv.xy *= lerp (1.0f, fPupilCenterToBorder, saturate( fPupilDilateFactor ) * 2.5f - 1.25f ); - vIrisUv.xy += 0.5f; -#endif - - //============// - // Iris color // - //============// - float4 cIrisColor = tex2D( g_tIrisSampler, vIrisUv.xy ); - - //==========================// - // Iris lighting highlights // - //==========================// - float3 cIrisLighting = float3( 0.0f, 0.0f, 0.0f ); - -#if !defined( SHADER_MODEL_PS_2_0 ) - // Mask off everything but the iris pixels - float fIrisHighlightMask = tex2D( g_tCorneaSampler, vCorneaUv.xy ).a; - - // Generate the normal - float3 vIrisTangentNormal = vCorneaTangentNormal.xyz; - vIrisTangentNormal.xy *= -2.5f; // I'm not normalizing on purpose - - for ( int j=0; j < nNumLights; j++ ) - { - // World light vector - float3 vWorldLightVector; - if ( ( j == 0 ) && ( bFlashlight == true ) ) - vWorldLightVector = vFlashlightVector.xyz; - else - vWorldLightVector = PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, j ); - - // Tangent light vector - float3 vTangentLightVector = Vec3WorldToTangent( vWorldLightVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); - - // Adjust the tangent light vector to generate the iris lighting - float3 tmpv = -vTangentLightVector.xyz; - tmpv.xy *= -0.5f; //Flatten tangent view - tmpv.z = max( tmpv.z, 0.5f ); //Clamp z of tangent view to help maintain highlight - tmpv.xyz = normalize( tmpv.xyz ); - - // Core iris lighting math - float fIrisFacing = pow( abs( dot( vIrisTangentNormal.xyz, tmpv.xyz ) ), 6.0f ) * 0.5f; // Yes, 6.0 and 0.5 are magic numbers - - // Cone of darkness to darken iris highlights when light falls behind eyeball past a certain point - float flConeOfDarkness = pow( 1.0f - saturate( ( -vTangentLightVector.z - 0.25f ) / 0.75f ), 4.0f ); - //float flConeOfDarkness = pow( 1.0f - saturate( ( -dot( vIrisTangentNormal.xyz, vTangentLightVector.xyz ) - 0.15f ) / 0.85f ), 8.0f ); - - // Tint by iris color and cone of darkness - float3 cIrisLightingTmp = fIrisFacing * fIrisHighlightMask * flConeOfDarkness; - - // Attenuate by light color and light falloff - if ( ( j == 0 ) && ( bFlashlight == true ) ) - cIrisLightingTmp.rgb *= cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; - else if ( j == 0 ) - cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); - else if ( j == 1 ) - cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); - else if ( j == 2 ) - cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); - else - cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); - - // Sum into final variable - cIrisLighting.rgb += cIrisLightingTmp.rgb; - } - - // Add slight view dependent iris lighting based on ambient light intensity to enhance situations with no local lights (0.5f is to help keep it subtle) - cIrisLighting.rgb += saturate( dot( vIrisTangentNormal.xyz, -vTangentViewVector.xyz ) ) * g_flAverageAmbient * fIrisHighlightMask * 0.5f; -#else - // Else, intensify light over cornea to simulate the brightening that happens above - cIrisLighting.rgb += i.cVertexLight.rgb * vCorneaSample.a; -#endif - - //===================// - // Ambient occlusion // - //===================// - float3 cAmbientOcclFromTexture = tex2D( g_tEyeAmbientOcclSampler, i.vAmbientOcclUv_fallbackCorneaUv.xy ).rgb; - float3 cAmbientOcclColor = lerp( g_cAmbientOcclColor, 1.0f, cAmbientOcclFromTexture.rgb ); // Color the ambient occlusion - i.cVertexLight.rgb *= cAmbientOcclColor.rgb; - - //==========================// - // Reflection from cube map // - //==========================// - float3 vCorneaReflectionVector = reflect ( vWorldViewVector.xyz, vCorneaWorldNormal.xyz ); - - //float3 cReflection = ENV_MAP_SCALE * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; - float3 cReflection = g_flGlossiness * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; - - // Hack: Only add in half of the env map for the flashlight pass. This looks reasonable. - if ( bFlashlight ) - { - cReflection.rgb *= 0.5f; - } - - //===========================// - // Glint specular highlights // - //===========================// - float3 cSpecularHighlights = 0.0f; - if ( bFlashlight ) - { - cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, vFlashlightVector.xyz ) ), 128.0f ) * cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; - } - else // no flashlight - { - if ( nNumLights > 0 ) - cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 0 ) ) ), 128.0f ) * i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); - - if ( nNumLights > 1 ) - cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 1 ) ) ), 128.0f ) * i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); - - if ( nNumLights > 2 ) - cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 2 ) ) ), 128.0f ) * i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); - - if ( nNumLights > 3 ) - cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 3 ) ) ), 128.0f ) * i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); - } - - //===============// - // Combine terms // - //===============// - float4 result; - - // Unlit iris, pupil, and sclera color - result.rgb = cIrisColor.rgb; - - // Add in slight cornea noise to help define raised cornea layer for close-ups - result.rgb += fCorneaNoise * 0.1f; - - // Diffuse light (Vertex lighting + extra iris caustic lighting) - result.rgb *= i.cVertexLight.rgb + cIrisLighting.rgb; - - // Environment map - result.rgb += cReflection.rgb * i.cVertexLight.rgb; - - // Local light glints - result.rgb += cSpecularHighlights.rgb; - - // Set alpha to 1.0 by default - result.a = 1.0; - -#if !defined( SHADER_MODEL_PS_2_0 ) - float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); - return FinalOutputConst( result, fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR ); -#else - float fogFactor = CalcPixelFogFactor( PIXEL_FOG_TYPE_NONE, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); - return FinalOutput( result, fogFactor, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); -#endif - -} diff --git a/materialsystem/stdshaders/eye_refract_vs20.fxc b/materialsystem/stdshaders/eye_refract_vs20.fxc deleted file mode 100644 index af975f99..00000000 --- a/materialsystem/stdshaders/eye_refract_vs20.fxc +++ /dev/null @@ -1,217 +0,0 @@ -//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============// - -// STATIC: "INTRO" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "LIGHTWARPTEXTURE" "0..1" - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..4" -// DYNAMIC: "MORPHING" "0..1" [vs30] - -#include "vortwarp_vs20_helper.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_iFogType = DOWATERFOG; -static const bool g_bHalfLambert = HALFLAMBERT ? true : false; - -const float3 g_cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); -const float4 g_vIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); -const float4 g_vIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); -const float4 g_vFlashlightPosition : register( SHADER_SPECIFIC_CONST_4 ); - -#if INTRO -const float4 g_vConst4 : register( SHADER_SPECIFIC_CONST_5 ); -#define g_vModelOrigin g_vConst4.xyz -#define g_flTime g_vConst4.w -#endif - -const float4 g_vFlashlightMatrixRow1 : register( SHADER_SPECIFIC_CONST_6 ); -const float4 g_vFlashlightMatrixRow2 : register( SHADER_SPECIFIC_CONST_7 ); -const float4 g_vFlashlightMatrixRow3 : register( SHADER_SPECIFIC_CONST_8 ); -const float4 g_vFlashlightMatrixRow4 : register( SHADER_SPECIFIC_CONST_9 ); - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - float4 vPos : POSITION; // Position - float4 vBoneWeights : BLENDWEIGHT; // Skin weights - float4 vBoneIndices : BLENDINDICES; // Skin indices - float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates - - // Position deltas - float3 vPosFlex : POSITION1; - -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; // Fixed-function fog factor -#endif - float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; // Base texture coordinate - float4 cVertexLight : TEXCOORD1; // Vertex-lit color (Note: w is used for flashlight pass) - float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) - float4 vWorldPosition_ProjPosZ : TEXCOORD3; - float3 vWorldNormal : TEXCOORD4; // World-space normal - float3 vWorldTangent : TEXCOORD5; // World-space tangent - float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights - float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights - - float3 vWorldBinormal : COLOR0; // World-space normal -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT ? true : false; - int nNumLights = NUM_LIGHTS; - - float4 vPosition = v.vPos; - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, vPosition.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz ); -#endif - - // Transform the position - float3 vWorldPosition; - SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPosition ); - - // Note: I'm relying on the iris projection vector math not changing or this will break - float3 vEyeSocketUpVector = normalize( -g_vIrisProjectionV.xyz ); - float3 vEyeSocketLeftVector = normalize( -g_vIrisProjectionU.xyz ); - -#if INTRO - float3 dummy = float3( 0.0f, 0.0f, 0.0f ); - WorldSpaceVertexProcess( g_flTime, g_vModelOrigin, vWorldPosition, dummy, dummy, dummy ); -#endif - - o.vWorldPosition_ProjPosZ.xyz = vWorldPosition.xyz; - - // Transform into projection space - //vWorldPosition -= ( vWorldPosition - g_cEyeOrigin ) * 0.9; //Debug to visualize eye origin - float4 vProjPos = mul( float4( vWorldPosition, 1.0f ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( vWorldPosition, 1.0f ), cViewProjZ ); - - - o.vWorldPosition_ProjPosZ.w = vProjPos.z; - -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( vWorldPosition, vProjPos, g_iFogType ); -#endif - - // Normal = (Pos - Eye origin) - float3 vWorldNormal = normalize( vWorldPosition.xyz - g_cEyeOrigin.xyz ); - o.vWorldNormal.xyz = vWorldNormal.xyz; - - // Tangent & binormal - /* - float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vEyeSocketLeftVector.xyz ) ); - o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; - - float3 vWorldTangent = normalize( cross( vWorldBinormal.xyz, vWorldNormal.xyz ) ); - o.vWorldTangent.xyz = vWorldTangent.xyz; - //*/ - - //* - float3 vWorldTangent = normalize( cross( vEyeSocketUpVector.xyz, vWorldNormal.xyz ) ); - o.vWorldTangent.xyz = vWorldTangent.xyz; - - float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); - o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; - //*/ - - float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz); - o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized (vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz); - - // AV - I think this will effectively make the eyeball less rounded left to right to help vertext lighting quality - // AV - Note: This probably won't look good if put on an exposed eyeball - //float vNormalDotSideVec = -dot( vWorldNormal, g_vEyeballUp ) * 0.5f; - float vNormalDotSideVec = -dot( vWorldNormal, vEyeSocketLeftVector) * 0.5f; - float3 vBentWorldNormal = normalize(vNormalDotSideVec * vEyeSocketLeftVector + vWorldNormal); - - // Compute vertex lighting - o.cVertexLight.a = 0.0f; //Only used for flashlight pass - o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vBentWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, nNumLights ); - - // Only interpolate ambient light for TF NPR lighting - bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; - if ( bDoDiffuseWarp ) - { - if( bDynamicLight ) - { - o.cVertexLight.rgb = AmbientLight( vBentWorldNormal.xyz ); - } - else - { - o.cVertexLight.rgb = float3( 0.0f, 0.0f, 0.0f ); - } - } - -// NOTE: it appears that o.vLightFalloffCosine01 and o.vLightFalloffCosine23 are filled in even if -// we don't have enough lights, meaning we pass garbage to the pixel shader which then throws it away - - // Light falloff for first two local lights - o.vLightFalloffCosine01.x = VertexAttenInternal( vWorldPosition.xyz, 0 ); - o.vLightFalloffCosine01.y = VertexAttenInternal( vWorldPosition.xyz, 1 ); - o.vLightFalloffCosine01.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 0, g_bHalfLambert ); - o.vLightFalloffCosine01.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 1, g_bHalfLambert ); - - // Light falloff for next two local lights - o.vLightFalloffCosine23.x = VertexAttenInternal( vWorldPosition.xyz, 2 ); - o.vLightFalloffCosine23.y = VertexAttenInternal( vWorldPosition.xyz, 3 ); - o.vLightFalloffCosine23.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 2, g_bHalfLambert ); - o.vLightFalloffCosine23.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 3, g_bHalfLambert ); - - // Texture coordinates set by artists for ambient occlusion - o.vAmbientOcclUv_fallbackCorneaUv.xy = v.vTexCoord0.xy; - - // Cornea uv for ps.2.0 fallback - float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture - vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); - vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); - float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; - o.vAmbientOcclUv_fallbackCorneaUv.wz = vCorneaUv.xy; // Note: wz unpacks faster than zw in ps.2.0! - - // Step on the vertex light interpolator for the flashlight tex coords - bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; - o.vTangentViewVector.w = 0.0f; - if ( bFlashlight ) - { - o.cVertexLight.x = dot( g_vFlashlightMatrixRow1.xyzw, float4( vWorldPosition, 1.0f ) ); - o.cVertexLight.y = dot( g_vFlashlightMatrixRow2.xyzw, float4( vWorldPosition, 1.0f ) ); - o.cVertexLight.z = dot( g_vFlashlightMatrixRow3.xyzw, float4( vWorldPosition, 1.0f ) ); - o.cVertexLight.w = dot( g_vFlashlightMatrixRow4.xyzw, float4( vWorldPosition, 1.0f ) ); - - o.vTangentViewVector.w = saturate( dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ) ); // Flashlight N.L with modified normal - - // Half lambert version - //o.cVertexLight.z = dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ); // Flashlight N.L with modified normal - //o.cVertexLight.z = ( o.cVertexLight.z * 0.5f ) + 0.5f; - //o.cVertexLight.z *= o.cVertexLight.z; - } - - return o; -} diff --git a/materialsystem/stdshaders/eyeball.cpp b/materialsystem/stdshaders/eyeball.cpp deleted file mode 100644 index 7113585d..00000000 --- a/materialsystem/stdshaders/eyeball.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Eyeball shader -// -//=============================================================================// - -#include "BaseVSShader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER( Eyeball, "Help for EyeBall" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture", 0 ) - SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - // This should be a dead shader... - return "Wireframe"; - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - } - -END_SHADER diff --git a/materialsystem/stdshaders/eyeglint.cpp b/materialsystem/stdshaders/eyeglint.cpp new file mode 100644 index 00000000..fa52281a --- /dev/null +++ b/materialsystem/stdshaders/eyeglint.cpp @@ -0,0 +1,66 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Run procedural glint generation inner loop in pixel shader +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "shaderlib/cshader.h" + +#include "sdk_eyeglint_vs30.inc" +#include "sdk_eyeglint_ps30.inc" + +BEGIN_VS_SHADER( EyeGlint, "Help for EyeGlint" ) + +BEGIN_SHADER_PARAMS +END_SHADER_PARAMS + +SHADER_INIT +{ +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Additive blending + + int pTexCoords[3] = { 2, 2, 3 }; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, pTexCoords, 0 ); + + pShaderShadow->EnableCulling( false ); + + pShaderShadow->EnableSRGBWrite( false ); // linear texture + + DECLARE_STATIC_VERTEX_SHADER( sdk_eyeglint_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_eyeglint_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_eyeglint_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_eyeglint_ps30 ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_eyeglint_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_eyeglint_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_eyeglint_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_eyeglint_ps30 ); + } + Draw(); +} +END_SHADER diff --git a/materialsystem/stdshaders/eyeglint_dx9.cpp b/materialsystem/stdshaders/eyeglint_dx9.cpp deleted file mode 100644 index d2662e6d..00000000 --- a/materialsystem/stdshaders/eyeglint_dx9.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Run procedural glint generation inner loop in pixel shader -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" -#include "shaderlib/cshader.h" - -#include "eyeglint_vs20.inc" -#include "eyeglint_ps20.inc" -#include "eyeglint_ps20b.inc" - -DEFINE_FALLBACK_SHADER( EyeGlint, EyeGlint_dx9 ) -BEGIN_VS_SHADER( EyeGlint_dx9, "Help for EyeGlint" ) - -BEGIN_SHADER_PARAMS -END_SHADER_PARAMS - -SHADER_INIT -{ -} - -SHADER_FALLBACK -{ - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "Wireframe"; - } - return 0; -} - -SHADER_DRAW -{ - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Additive blending - - int pTexCoords[3] = { 2, 2, 3 }; - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, pTexCoords, 0 ); - - pShaderShadow->EnableCulling( false ); - - pShaderShadow->EnableSRGBWrite( false ); // linear texture - - DECLARE_STATIC_VERTEX_SHADER( eyeglint_vs20 ); - SET_STATIC_VERTEX_SHADER( eyeglint_vs20 ); - - SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); - } - - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); - - SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); - } - Draw(); -} -END_SHADER diff --git a/materialsystem/stdshaders/eyes.cpp b/materialsystem/stdshaders/eyes.cpp index 7aa4738f..034829f7 100644 --- a/materialsystem/stdshaders/eyes.cpp +++ b/materialsystem/stdshaders/eyes.cpp @@ -6,39 +6,28 @@ // $NoKeywords: $ //=============================================================================// -#include "BaseVSShader.h" -#include "eyes_dx8_dx9_helper.h" -#include "cloak_blended_pass_helper.h" +#include "basevsshader.h" +#include "eyes_helper.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -DEFINE_FALLBACK_SHADER( eyes, Eyes_dx8 ) - -BEGIN_VS_SHADER( Eyes_dx8, - "Help for Eyes" ) +BEGIN_VS_SHADER( Eyes, "Help for Eyes" ) BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/eyeball_l", "iris texture", 0 ) - SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture" ) + SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "iris texture" ) SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) - SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "models/humans/male/glint", "glint texture" ) + SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "glint texture" ) SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin for the eyes" ) SHADER_PARAM( EYEUP, SHADER_PARAM_TYPE_VEC3, "[0 0 1]", "up vector for the eyes" ) - SHADER_PARAM( IRISU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "U projection vector for the iris" ) + SHADER_PARAM( IRISU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0 ]", "U projection vector for the iris" ) SHADER_PARAM( IRISV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the iris" ) SHADER_PARAM( GLINTU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "U projection vector for the glint" ) SHADER_PARAM( GLINTV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the glint" ) - SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Iris dilation" ) + SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) - - // Cloak Pass - SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) - SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) END_SHADER_PARAMS void SetupVars( Eyes_DX8_DX9_Vars_t &info ) @@ -60,65 +49,17 @@ BEGIN_VS_SHADER( Eyes_dx8, info.m_nWarpParam = WARPPARAM; } - // Cloak Pass - void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) - { - info.m_nCloakFactor = CLOAKFACTOR; - info.m_nCloakColorTint = CLOAKCOLORTINT; - info.m_nRefractAmount = REFRACTAMOUNT; - } - - bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time - return true; - else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag2 in case the base material still needs it - } - - // Check flag2 if not drawing cloak pass - return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); - } - - bool IsTranslucent( IMaterialVar **params ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag in case the base material still needs it - } - - // Check flag if not drawing cloak pass - return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); - } - SHADER_INIT_PARAMS() { Eyes_DX8_DX9_Vars_t info; SetupVars( info ); InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); - - // Cloak Pass - if ( !params[CLOAKPASSENABLED]->IsDefined() ) - { - params[CLOAKPASSENABLED]->SetIntValue( 0 ); - } - else if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitParamsCloakBlendedPass( this, params, pMaterialName, info ); - } } SHADER_FALLBACK { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) - return "Eyes_dx6"; + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Eyes_dx8"; return 0; } @@ -128,59 +69,14 @@ BEGIN_VS_SHADER( Eyes_dx8, Eyes_DX8_DX9_Vars_t info; SetupVars( info ); InitEyes_DX8_DX9( this, params, info ); - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitCloakBlendedPass( this, params, info ); - } } + SHADER_DRAW { - // Skip the standard rendering if cloak pass is fully opaque - bool bDrawStandardPass = true; - if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - if ( CloakBlendedPassIsFullyOpaque( params, info ) ) - { - // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now - //bDrawStandardPass = false; - } - } - - // Standard rendering pass - if ( bDrawStandardPass ) - { - Eyes_DX8_DX9_Vars_t info; - SetupVars( info ); - DrawEyes_DX8_DX9( false, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else - { - // Skip this pass! - Draw( false ); - } - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + DrawEyes_DX8_DX9( true, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); } END_SHADER + diff --git a/materialsystem/stdshaders/eyes.vsh b/materialsystem/stdshaders/eyes.vsh deleted file mode 100644 index 58ae021d..00000000 --- a/materialsystem/stdshaders/eyes.vsh +++ /dev/null @@ -1,80 +0,0 @@ -vs.1.1 -;------------------------------------------------------------------------------ -; $SHADER_SPECIFIC_CONST_0 = eyeball origin -; $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 -; $SHADER_SPECIFIC_CONST_2 = iris projection U -; $SHADER_SPECIFIC_CONST_3 = iris projection V -; $SHADER_SPECIFIC_CONST_4 = glint projection U -; $SHADER_SPECIFIC_CONST_5 = glint projection V -;------------------------------------------------------------------------------ - -# STATIC: "HALF_LAMBERT" "0..1" -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "LIGHT_COMBO" "0..21" -# DYNAMIC: "SKINNING" "0..1" - -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending (whacks r1-r7, positions in r7) -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -&SkinPosition( $worldPos ); - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ - -&AllocateRegister( \$projPos ); - -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Normal is based on vertex position -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldNormal ); -&AllocateRegister( \$normalDotUp ); - -sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_0 ; Normal = (Pos - Eye origin) -dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_1 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up -mul $normalDotUp, $normalDotUp, $cHalf -mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_1, $worldNormal - -&FreeRegister( \$normalDotUp ); - -; normalize the normal -&Normalize( $worldNormal ); - -;------------------------------------------------------------------------------ -; Lighting -;------------------------------------------------------------------------------ -&DoLighting( $worldPos, $worldNormal ); - -&FreeRegister( \$worldNormal ); - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ - -&CalcFog( $worldPos, $projPos ); - -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Texture coordinates -; Texture 0 is the base texture -; Texture 1 is a planar projection used for the iris -; Texture 2 is a planar projection used for the glint -;------------------------------------------------------------------------------ - -mov oT0, $vTexCoord0 -dp4 oT1.x, $SHADER_SPECIFIC_CONST_2, $worldPos -dp4 oT1.y, $SHADER_SPECIFIC_CONST_3, $worldPos -dp4 oT2.x, $SHADER_SPECIFIC_CONST_4, $worldPos -dp4 oT2.y, $SHADER_SPECIFIC_CONST_5, $worldPos - -&FreeRegister( \$worldPos ); diff --git a/materialsystem/stdshaders/eyes_dx6.cpp b/materialsystem/stdshaders/eyes_dx6.cpp deleted file mode 100644 index f5454595..00000000 --- a/materialsystem/stdshaders/eyes_dx6.cpp +++ /dev/null @@ -1,251 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Teeth renderer -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Eyes, Eyes_dx6 ) - -BEGIN_VS_SHADER( Eyes_dx6, - "Help for Eyes" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "iris texture" ) - SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) - SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "glint texture" ) - SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin for the eyes" ) - SHADER_PARAM( EYEUP, SHADER_PARAM_TYPE_VEC3, "[0 0 1]", "up vector for the eyes" ) - SHADER_PARAM( IRISU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0 ]", "U projection vector for the iris" ) - SHADER_PARAM( IRISV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the iris" ) - SHADER_PARAM( GLINTU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "U projection vector for the glint" ) - SHADER_PARAM( GLINTV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the glint" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - LoadTexture( BASETEXTURE ); - LoadTexture( IRIS ); - } - - void SetTextureTransform( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - MaterialMatrixMode_t textureTransform, int uparam, int vparam ) - { - Vector4D u, v; - params[uparam]->GetVecValue( u.Base(), 4 ); - params[vparam]->GetVecValue( v.Base(), 4 ); - - // Need to transform these puppies into camera space - // they are defined in world space - VMatrix mat, invTrans; - pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); - mat = mat.Transpose(); - - // Compute the inverse transpose of the matrix - // NOTE: I only have to invert it here because VMatrix is transposed - // with respect to what gets returned from GetMatrix. - mat.InverseGeneral( invTrans ); - invTrans = invTrans.Transpose(); - - // Transform the u and v planes into view space - Vector4D uview, vview; - uview.AsVector3D() = invTrans.VMul3x3( u.AsVector3D() ); - vview.AsVector3D() = invTrans.VMul3x3( v.AsVector3D() ); - uview[3] = u[3] - DotProduct( mat.GetTranslation(), uview.AsVector3D() ); - vview[3] = v[3] - DotProduct( mat.GetTranslation(), vview.AsVector3D() ); - - float m[16]; - m[0] = uview[0]; m[1] = vview[0]; m[2] = 0.0f; m[3] = 0.0f; - m[4] = uview[1]; m[5] = vview[1]; m[6] = 0.0f; m[7] = 0.0f; - m[8] = uview[2]; m[9] = vview[2]; m[10] = 1.0f; m[11] = 0.0f; - m[12] = uview[3]; m[13] = vview[3]; m[14] = 0.0f; m[15] = 1.0f; - - pShaderAPI->MatrixMode( textureTransform ); - pShaderAPI->LoadMatrix( m ); - } - - void DrawFlashlight_Iris( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); - - // Alpha blend - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( false ); - - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; - pShaderShadow->DrawFlags( flags ); - FogToBlack(); - - pShaderShadow->EnableLighting( true ); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 2 ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, - SHADER_TEXARG_VERTEXCOLOR ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); - - // alpha stage 0 - // get alpha from constant alpha - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); - - // alpha stage 1 - // get alpha from $basetexture - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // Shove the view position into texcoord 0 before the texture matrix. - pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); - - // iris transform - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, true ); - pShaderShadow->TexGen( SHADER_TEXTURE_STAGE1, SHADER_TEXGENPARAM_EYE_LINEAR ); - - } - DYNAMIC_STATE - { - SetFlashlightFixedFunctionTextureTransform( MATERIAL_TEXTURE0 ); - - // NOTE: This has to come after the loadmatrix since the loadmatrix screws with the - // transform flags!!!!!! - // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. - // NOTE Tried to divide XY by Z, but doesn't work. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 3, true ); - - BindTexture( SHADER_SAMPLER0, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - - BindTexture( SHADER_SAMPLER1, IRIS, IRISFRAME ); - SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE1, IRISU, IRISV ); - } - Draw(); - } - - void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // whites - DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true ); - - // iris - DrawFlashlight_Iris( params, pShaderAPI, pShaderShadow ); - } - - void DrawUsingSoftwareLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // whites - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - - // iris - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR ); - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); - pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, IRIS, IRISFRAME ); - SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE0, IRISU, IRISV ); - } - Draw(); - - // Glint - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); - - pShaderShadow->EnableConstantColor( true ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); - pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); - - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION ); - FogToBlack(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, GLINT ); - SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE0, GLINTU, GLINTV ); - } - Draw( ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - } - bool hasFlashlight = UsingFlashlight( params ); - - if( hasFlashlight ) - { - DrawFlashlight( params, pShaderAPI, pShaderShadow ); - } - else - { - DrawUsingSoftwareLighting( params, pShaderAPI, pShaderShadow ); - } - - } -END_SHADER - diff --git a/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp b/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp deleted file mode 100644 index e1edda0d..00000000 --- a/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp +++ /dev/null @@ -1,550 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//============================================================================= - -#include "BaseVSShader.h" -#include "tier1/convar.h" -#include "mathlib/vmatrix.h" -#include "eyes_dx8_dx9_helper.h" -#include "cpp_shader_constant_register_map.h" -#include "Eyes.inc" -#include "eyes_flashlight_vs11.inc" -#include "eyes_flashlight_ps11.inc" - -#ifdef STDSHADER_DX9_DLL_EXPORT - -#include "eyes_vs20.inc" -#include "eyes_ps20.inc" -#include "eyes_ps20b.inc" -#include "eyes_flashlight_vs20.inc" -#include "eyes_flashlight_ps20.inc" -#include "eyes_flashlight_ps20b.inc" - -#ifndef _X360 -#include "eyes_vs30.inc" -#include "eyes_ps30.inc" -#include "eyes_flashlight_vs30.inc" -#include "eyes_flashlight_ps30.inc" -#endif - -#endif - -ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); - -void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, - Eyes_DX8_DX9_Vars_t &info ) -{ - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - - Assert( info.m_nIntro != -1 ); - if( info.m_nIntro != -1 && !params[info.m_nIntro]->IsDefined() ) - { - params[info.m_nIntro]->SetIntValue( 0 ); - } -} - -void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ) -{ - pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); - pShader->LoadTexture( info.m_nGlint ); - - // Be sure dilation is zeroed if undefined - if( !params[info.m_nDilation]->IsDefined() ) - { - params[info.m_nDilation]->SetFloatValue( 0.0f ); - } -} - -static void SetDepthFlashlightParams( CBaseVSShader *pShader, IShaderDynamicAPI *pShaderAPI, const VMatrix& worldToTexture, const FlashlightState_t& flashlightState ) -{ - float atten[4], pos[4], tweaks[4]; - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); - - // Tweaks associated with a given flashlight - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - - if ( IsX360() ) - { - pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); - } -} - - -static void DrawFlashlight( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) -{ - if( pShaderShadow ) - { - pShaderShadow->EnableDepthWrites( false ); - - pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Spot - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Base - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalizing cubemap - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Iris - - // Set stream format (note that this shader supports compression) - int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - -#ifdef STDSHADER_DX9_DLL_EXPORT - if ( bDX9 ) - { - int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); - SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); - SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); - } - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); - SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); - } -#endif - - // On DX9, get the gamma read and write correct - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Spot - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Base - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Iris - pShaderShadow->EnableSRGBWrite( true ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Shadow noise rotation map - } - } - else -#endif - { - // DX8 uses old asm shaders - eyes_flashlight_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "eyes_flashlight_vs11", vshIndex.GetIndex() ); - - eyes_flashlight_ps11_Static_Index pshIndex; - pShaderShadow->SetPixelShader( "eyes_flashlight_ps11", pshIndex.GetIndex() ); - } - - pShader->FogToBlack(); - } - else - { - // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. - // NOTE Tried to divide XY by Z, but doesn't work. - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - if ( !bDX9 ) - { - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true ); - } - - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - - pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture, info.m_nFrame ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); - pShader->BindTexture( SHADER_SAMPLER3, info.m_nIris, info.m_nIrisFrame ); - -#ifdef STDSHADER_DX9_DLL_EXPORT - if ( bDX9 ) - { - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); - } -#ifndef _X360 - else - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); - } -#endif - -// float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), 0.0f, 0.0f, 0.0f}; -// pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); - - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - SetFlashLightColorFromState( flashlightState, pShaderAPI ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); - SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); - - SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); - } - } -#ifndef _X360 - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); - SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); - - SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); - } -#endif - } - else // older asm shaders for DX8 -#endif - { - eyes_flashlight_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - eyes_flashlight_ps11_Dynamic_Index pshIndex; - pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() ); - } - - // This uses from VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 to VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 - pShader->SetFlashlightVertexShaderConstants( false, -1, false, -1, false ); - - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, info.m_nEyeOrigin ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, info.m_nEyeUp ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, info.m_nIrisU ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, info.m_nIrisV ); - } - pShader->Draw(); -} - -static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) -{ - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Glint - - // Set stream format (note that this shader supports compression) - int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - pShaderShadow->EnableAlphaWrites( true ); //we end up hijacking destination alpha for opaques most of the time. - -#ifdef STDSHADER_DX9_DLL_EXPORT - if ( bDX9 ) - { -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_STATIC_VERTEX_SHADER( eyes_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( eyes_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( eyes_ps20b ); - SET_STATIC_PIXEL_SHADER( eyes_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( eyes_ps20 ); - SET_STATIC_PIXEL_SHADER( eyes_ps20 ); - } - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( eyes_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( eyes_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( eyes_ps30 ); - SET_STATIC_PIXEL_SHADER( eyes_ps30 ); - } -#endif - // On DX9, get the gamma read and write correct - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Base - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // White - pShaderShadow->EnableSRGBWrite( true ); - } - else -#endif - { - eyes_Static_Index vshIndex; - vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - pShaderShadow->SetVertexShader( "Eyes", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "Eyes_Overbright2" ); - } - - pShader->FogToFogColor(); - } - DYNAMIC_STATE - { - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nFrame ); - pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); - pShader->BindTexture( SHADER_SAMPLER2, info.m_nGlint ); - pShader->SetAmbientCubeDynamicStateVertexShader(); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nEyeUp ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nGlintU ); - pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nGlintV ); - -#ifdef STDSHADER_DX9_DLL_EXPORT - if( bDX9 ) - { - LightState_t lightState; - pShaderAPI->GetDX9LightState( &lightState ); - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); - } -#ifndef _X360 - else - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); - } -#endif - - // Get luminance of ambient cube and saturate it - float fGlintDamping = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); - const float fDimGlint = 0.01f; - - // Remap so that glint damping smooth steps to zero for low luminances - if ( fGlintDamping > fDimGlint ) - fGlintDamping = 1.0f; - else - fGlintDamping *= SimpleSplineRemapVal( fGlintDamping, 0.0f, fDimGlint, 0.0f, 1.0f ); - - // Special constant for DX9 eyes: { Dilation, ambient, x, x }; - float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), fGlintDamping, 0.0f, 0.0f}; - pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); - } - } -#ifndef _X360 - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); - } -#endif - - Assert( info.m_nIntro != -1 ); - if( params[info.m_nIntro]->GetIntValue() ) - { - float curTime = params[info.m_nWarpParam]->GetFloatValue(); - float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; - Assert( params[info.m_nEntityOrigin]->IsDefined() ); - params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); - } - } - else -#endif - { - eyes_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - pShader->Draw(); -} - -static void DrawEyes_DX8_DX9_Internal( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, bool bHasFlashlight, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) -{ - if( !bHasFlashlight ) - { - DrawUsingVertexShader( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else - { - DrawFlashlight( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } -} - -extern ConVar r_flashlight_version2; -void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) -{ - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - } - bool bHasFlashlight = pShader->UsingFlashlight( params ); - if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) - { - DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); - if ( pShaderShadow ) - { - pShader->SetInitialShadowState( ); - } - } - DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); -} - - diff --git a/materialsystem/stdshaders/eyes_dx9.cpp b/materialsystem/stdshaders/eyes_dx9.cpp deleted file mode 100644 index b33ec804..00000000 --- a/materialsystem/stdshaders/eyes_dx9.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: eye renderer -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "eyes_dx8_dx9_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( eyes, Eyes_dx9 ) - -BEGIN_VS_SHADER( Eyes_dx9, "Help for Eyes" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "iris texture" ) - SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) - SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "glint texture" ) - SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin for the eyes" ) - SHADER_PARAM( EYEUP, SHADER_PARAM_TYPE_VEC3, "[0 0 1]", "up vector for the eyes" ) - SHADER_PARAM( IRISU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0 ]", "U projection vector for the iris" ) - SHADER_PARAM( IRISV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the iris" ) - SHADER_PARAM( GLINTU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "U projection vector for the glint" ) - SHADER_PARAM( GLINTV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the glint" ) - SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) - SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) - SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) - SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) - END_SHADER_PARAMS - - void SetupVars( Eyes_DX8_DX9_Vars_t &info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nFrame = FRAME; - info.m_nIris = IRIS; - info.m_nIrisFrame = IRISFRAME; - info.m_nGlint = GLINT; - info.m_nEyeOrigin = EYEORIGIN; - info.m_nEyeUp = EYEUP; - info.m_nIrisU = IRISU; - info.m_nIrisV = IRISV; - info.m_nGlintU = GLINTU; - info.m_nGlintV = GLINTV; - info.m_nDilation = DILATION; - info.m_nIntro = INTRO; - info.m_nEntityOrigin = ENTITYORIGIN; - info.m_nWarpParam = WARPPARAM; - } - - SHADER_INIT_PARAMS() - { - Eyes_DX8_DX9_Vars_t info; - SetupVars( info ); - InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "Eyes_dx8"; - - return 0; - } - - SHADER_INIT - { - Eyes_DX8_DX9_Vars_t info; - SetupVars( info ); - InitEyes_DX8_DX9( this, params, info ); - } - - - SHADER_DRAW - { - Eyes_DX8_DX9_Vars_t info; - SetupVars( info ); - DrawEyes_DX8_DX9( true, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } -END_SHADER - diff --git a/materialsystem/stdshaders/eyes_flashlight2_ps11.psh b/materialsystem/stdshaders/eyes_flashlight2_ps11.psh deleted file mode 100644 index 6cc5493e..00000000 --- a/materialsystem/stdshaders/eyes_flashlight2_ps11.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw stuff -;------------------------------------------------------------------------------ - -tex t0 ; Contains spotlight -tex t1 ; Contains base texture -tex t2 ; Normalize world pos to light -tex t3 ; Sample iris - -dp3 r0, t2_bx2, v0_bx2 ; r0 = N dot L -lrp r1.rgb, t3.a, t3, t1 ; r1 = lerp( baseColor, irisSample.xyz, irisSample.a ) -mul r0.rgb, r0_sat, r1 ; Saturate ( N dot L )* lerp -mul r0.rgb, r0, v0.a ; *= attenuation -mul_x2 r0.rgb, r0, t0 + ; *= 2 * spotlight -mov r0.a, t1.a diff --git a/materialsystem/stdshaders/eyes_flashlight_inc.fxc b/materialsystem/stdshaders/eyes_flashlight_inc.fxc deleted file mode 100644 index 7629f72f..00000000 --- a/materialsystem/stdshaders/eyes_flashlight_inc.fxc +++ /dev/null @@ -1,92 +0,0 @@ -//====== Copyright 1996-2006, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" - - -const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); - -sampler SpotSampler : register( s0 ); -sampler BaseTextureSampler : register( s1 ); -sampler IrisSampler : register( s3 ); - -#if FLASHLIGHTSHADOWS && (!SHADER_MODEL_PS_1_1) && (!SHADER_MODEL_PS_1_4) && (!SHADER_MODEL_PS_2_0) -sampler FlashlightDepthSampler : register( s4 ); -sampler RandomRotationSampler : register( s5 ); -#endif - -#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) - -#else - const float4 g_FogParams : register( PSREG_FOG_PARAMS ); - const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); -#endif - -struct PS_INPUT -{ - float4 spotTexCoord : TEXCOORD0; - float2 baseTexCoord : TEXCOORD1; - float2 irisTexCoord : TEXCOORD3; -#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) - float3 vertAtten : COLOR0; -#else - float3 vertAtten : TEXCOORD4; - float3 worldPos : TEXCOORD5; - float3 projPos : TEXCOORD7; -#endif -}; - -float4 main( PS_INPUT i ) : COLOR -{ -#if defined(SHADER_MODEL_PS_2_0) - float3 spotColor = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ) * cFlashlightColor; -#elif ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) - float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; - float3 spotColor = tex2D( SpotSampler, vProjCoords ) * cFlashlightColor; -#else - float3 spotColor = tex2D( SpotSampler, i.spotTexCoord ); -#endif - - float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); - float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); - - float3 outcolor = float3(1,1,1); - -#if !defined( SHADER_MODEL_PS_1_1 ) && !defined( SHADER_MODEL_PS_1_4 ) - if( i.spotTexCoord.w <= 0.0f ) - { - outcolor = float3(0,0,0); - } -#endif - - // Composite the iris and sclera together -#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) - float3 albedo = lerp( baseSample.xyz, irisSample.xyz, irisSample.a ); -#else - float3 albedo = lerp( baseSample.xyz, irisSample.xyz * 0.5f, irisSample.a ); // dim down the iris in HDR -#endif - - // Do shadow depth mapping... -#if FLASHLIGHTSHADOWS && ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) - float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, true ); - float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = lerp( flAttenuated, flShadow, dot(i.vertAtten, float3(0.30f, 0.59f, 0.11f) ) ); // Blend between shadow and above, according to light attenuation - outcolor *= flShadow * spotColor * albedo; -#else - outcolor *= spotColor * albedo; -#endif - - // NOTE!! This has to be last to avoid loss of range. - outcolor *= i.vertAtten; -#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) - return float4( outcolor, baseSample.a ); -#else - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos.z, i.projPos.z ); - return FinalOutput( float4( outcolor, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -#endif - -} diff --git a/materialsystem/stdshaders/eyes_flashlight_ps11.fxc b/materialsystem/stdshaders/eyes_flashlight_ps11.fxc deleted file mode 100644 index 25e0702e..00000000 --- a/materialsystem/stdshaders/eyes_flashlight_ps11.fxc +++ /dev/null @@ -1,9 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#define HDRTYPE HDR_TYPE_NONE - -#include "eyes_flashlight_inc.fxc" diff --git a/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc b/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc deleted file mode 100644 index eb00fc04..00000000 --- a/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc +++ /dev/null @@ -1,15 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] - -#include "eyes_flashlight_inc.fxc" diff --git a/materialsystem/stdshaders/eyes_flashlight_vs11.vsh b/materialsystem/stdshaders/eyes_flashlight_vs11.vsh deleted file mode 100644 index 48c4cd57..00000000 --- a/materialsystem/stdshaders/eyes_flashlight_vs11.vsh +++ /dev/null @@ -1,115 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos ); - -alloc $worldPos -alloc $projPos - - -&SkinPosition( $worldPos ); - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 - -;------------------------------------------------------------------------------ -; Normal is based on vertex position -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldNormal ); -&AllocateRegister( \$normalDotUp ); - -sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_6 ; Normal = (Pos - Eye origin) -dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_7 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up -mul $normalDotUp, $normalDotUp, $cHalf -mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_7, $worldNormal - -&FreeRegister( \$normalDotUp ); - -; normalize the normal -&Normalize( $worldNormal ); - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -; base tex coords -mov oT1.xy, $vTexCoord0 - -; spotlight texcoords -dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 -dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 -dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 -dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 - -local( $worldPosToLightVector, $distFactors ); - -alloc $worldPosToLightVector - -sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0.xyz, $worldPos - -local( $distatten ); -alloc $distatten -; $distatten = [ 1, 1/dist, 1/distsquared ] - -; dist squared -dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector - -; oodist -rsq $distatten.y, $distatten.z - -mov $distatten.x, $cOne - -local( $dist ); -alloc $dist -mul $dist.x, $distatten.z, $distatten.y - -rcp $distatten.z, $distatten.z ; 1/distsquared - -local( $endFalloffFactor ); -alloc $endFalloffFactor - -; ( dist - farZ ) -sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w -; 1 / ( (0.6f * farZ) - farZ) -mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w -max $endFalloffFactor, $endFalloffFactor, $cZero -min $endFalloffFactor, $endFalloffFactor, $cOne - -local( $vertAtten ); -alloc $vertAtten -dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 -mul $vertAtten, $vertAtten, $endFalloffFactor - -; Normalize L -&Normalize( $worldPosToLightVector ); - -; N.L -dp3 $worldNormal, $worldNormal, $worldPosToLightVector - -; Modulate distance attenuation with N.L -mul oD0, $vertAtten, $worldNormal - -; iris -dp4 oT3.x, $SHADER_SPECIFIC_CONST_8, $worldPos -dp4 oT3.y, $SHADER_SPECIFIC_CONST_9, $worldPos - -free $dist -free $endFalloffFactor -free $worldPos -free $worldNormal -free $projPos -free $worldPosToLightVector -free $distatten -free $vertAtten diff --git a/materialsystem/stdshaders/eyes_flashlight_vs20.fxc b/materialsystem/stdshaders/eyes_flashlight_vs20.fxc deleted file mode 100644 index e2e37dc1..00000000 --- a/materialsystem/stdshaders/eyes_flashlight_vs20.fxc +++ /dev/null @@ -1,145 +0,0 @@ -// ------------------------------------------------------------------------------ -// $cLight0Pos = world space light position -// $SHADER_SPECIFIC_CONST_1 = spotlight projection -// $SHADER_SPECIFIC_CONST_2 = spotlight projection -// $SHADER_SPECIFIC_CONST_3 = spotlight projection -// $SHADER_SPECIFIC_CONST_4 = spotlight projection -// $SHADER_SPECIFIC_CONST_5 = far z -// $SHADER_SPECIFIC_CONST_6 = eyeball origin -// $SHADER_SPECIFIC_CONST_7 = eyeball up * 0.5 -// $SHADER_SPECIFIC_CONST_8 = iris projection U -// $SHADER_SPECIFIC_CONST_9 = iris projection V -// ------------------------------------------------------------------------------ - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cLightPosition : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); -const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); -const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); -const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); -const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ -const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_8 ); -const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_9 ); - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - float4 vPos : POSITION; // Position - float4 vBoneWeights : BLENDWEIGHT; // Skin weights - float4 vBoneIndices : BLENDINDICES; // Skin indices - float4 vNormal : NORMAL; - float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; // Fixed-function fog factor -#endif - float4 spotTexCoord : TEXCOORD0; // Spotlight texture coordinates - float2 baseTexCoord : TEXCOORD1; // Base texture coordinates - float2 irisTexCoord : TEXCOORD3; // Iris texture coordinates - float3 vertAtten : TEXCOORD4; // vertex attenuation - float3 worldPos : TEXCOORD5; - float3 projPosXYZ : TEXCOORD7; -}; - - -float RemapValClamped_01( float val, float A, float B ) -{ - float cVal = (val - A) / (B - A); - cVal = saturate( cVal ); - return cVal; -} - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - DecompressVertex_Normal( v.vNormal, vNormal ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); -#endif - - // Perform skinning - float3 worldNormal, worldPos; - SkinPositionAndNormal( - g_bSkinning, - vPosition, vNormal, - v.vBoneWeights, v.vBoneIndices, - worldPos, worldNormal ); - - worldNormal = normalize( worldNormal ); - - // Transform into projection space - float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - o.projPosXYZ = projPos.xyz; - o.worldPos = worldPos.xyz; - -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( worldPos, o.projPos, g_FogType ); -#endif - - // Base texture coordinates - o.baseTexCoord = v.vTexCoord0; - - // Spotlight texture coordinates - o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); - o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); - o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); - o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); - - // Compute vector to light - float3 vWorldPosToLightVector = cLightPosition.xyz - worldPos; - - float3 vDistAtten = float3(1, 1, 1); - vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); // distsquared - vDistAtten.y = rsqrt( vDistAtten.z ); // 1 / dist - - float flDist = vDistAtten.z * vDistAtten.y; // dist - vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared - - float fFarZ = cFlashlighAtten.w; - - float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); - o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); - - o.vertAtten *= dot( normalize( vWorldPosToLightVector ), worldNormal ); - - o.irisTexCoord.x = dot( cIrisProjectionU, float4(worldPos, 1) ); - o.irisTexCoord.y = dot( cIrisProjectionV, float4(worldPos, 1) ); - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/eyes_helper.cpp b/materialsystem/stdshaders/eyes_helper.cpp new file mode 100644 index 00000000..9a7d77f2 --- /dev/null +++ b/materialsystem/stdshaders/eyes_helper.cpp @@ -0,0 +1,324 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "basevsshader.h" +#include "tier1/convar.h" +#include "mathlib/vmatrix.h" +#include "eyes_helper.h" +#include "cpp_shader_constant_register_map.h" +#include "sdk_eyes_vs30.inc" +#include "sdk_eyes_ps30.inc" +#include "sdk_eyes_flashlight_vs30.inc" +#include "sdk_eyes_flashlight_ps30.inc" + +ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); + +void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, + Eyes_DX8_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + Assert( info.m_nIntro != -1 ); + if( info.m_nIntro != -1 && !params[info.m_nIntro]->IsDefined() ) + { + params[info.m_nIntro]->SetIntValue( 0 ); + } +} + +void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ) +{ + pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nGlint ); + + // Be sure dilation is zeroed if undefined + if( !params[info.m_nDilation]->IsDefined() ) + { + params[info.m_nDilation]->SetFloatValue( 0.0f ); + } +} + +static void SetDepthFlashlightParams( CBaseVSShader *pShader, IShaderDynamicAPI *pShaderAPI, const VMatrix& worldToTexture, const FlashlightState_t& flashlightState ) +{ + float atten[4], pos[4], tweaks[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } +} + + +static void DrawFlashlight( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( pShaderShadow ) + { + pShaderShadow->EnableDepthWrites( false ); + + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalizing cubemap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Iris + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_eyes_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_eyes_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_eyes_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( sdk_eyes_flashlight_ps30 ); + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Iris + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Shadow noise rotation map + + pShader->FogToBlack(); + } + else + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture, info.m_nFrame ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nIris, info.m_nIrisFrame ); + + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_eyes_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_eyes_flashlight_vs30 ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_eyes_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( sdk_eyes_flashlight_ps30 ); + + SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); + + // This uses from VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 to VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 + pShader->SetFlashlightVertexShaderConstants( false, -1, false, -1, false ); + + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, info.m_nIrisV ); + } + + pShader->Draw(); +} + +static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Glint + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + pShaderShadow->EnableAlphaWrites( true ); //we end up hijacking destination alpha for opaques most of the time. + + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_eyes_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_eyes_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_eyes_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_eyes_ps30 ); + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // White + pShaderShadow->EnableSRGBWrite( true ); + + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nGlint ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nGlintU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nGlintV ); + + LightState_t lightState; + pShaderAPI->GetDX9LightState( &lightState ); + + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_eyes_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_eyes_vs30 ); + + // Get luminance of ambient cube and saturate it + float fGlintDamping = MAX(0.0f, MIN( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + const float fDimGlint = 0.01f; + + // Remap so that glint damping smooth steps to zero for low luminances + if ( fGlintDamping > fDimGlint ) + fGlintDamping = 1.0f; + else + fGlintDamping *= SimpleSplineRemapVal( fGlintDamping, 0.0f, fDimGlint, 0.0f, 1.0f ); + + // Special constant for DX9 eyes: { Dilation, ambient, x, x }; + float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), fGlintDamping, 0.0f, 0.0f}; + pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_eyes_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_eyes_ps30 ); + + Assert( info.m_nIntro != -1 ); + if( params[info.m_nIntro]->GetIntValue() ) + { + float curTime = params[info.m_nWarpParam]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[info.m_nEntityOrigin]->IsDefined() ); + params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, timeVec, 1 ); + } + } + pShader->Draw(); +} + +static void DrawEyes_DX8_DX9_Internal( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool bHasFlashlight, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( !bHasFlashlight ) + { + DrawUsingVertexShader( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + DrawFlashlight( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +} + +extern ConVar r_flashlight_version2; +void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); +} + + diff --git a/materialsystem/stdshaders/eyes_dx8_dx9_helper.h b/materialsystem/stdshaders/eyes_helper.h similarity index 100% rename from materialsystem/stdshaders/eyes_dx8_dx9_helper.h rename to materialsystem/stdshaders/eyes_helper.h diff --git a/materialsystem/stdshaders/eyes_ps2x.fxc b/materialsystem/stdshaders/eyes_ps2x.fxc deleted file mode 100644 index d71d813f..00000000 --- a/materialsystem/stdshaders/eyes_ps2x.fxc +++ /dev/null @@ -1,68 +0,0 @@ -//====== Copyright 1996-2006, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -sampler BaseTextureSampler : register( s0 ); -sampler IrisSampler : register( s1 ); -sampler GlintSampler : register( s2 ); -const float4 cEyeScalars : register( c0 ); // { Dilation, ambient, x, x } - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float2 irisTexCoord : TEXCOORD1; - float2 glintTexCoord : TEXCOORD2; - float3 vertAtten : TEXCOORD3; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - -#define fDilationFactor cEyeScalars.x -#define fGlintDamping cEyeScalars.y - -float4 main( PS_INPUT i ) : COLOR -{ - float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); - float4 glintSample = tex2D( GlintSampler, i.glintTexCoord ); -/* - // Dilate the pupil/iris texture (1 is max dilation, 0 is none) - float2 biasedCoords = i.irisTexCoord * 2.0f - 1.0f; // -1 to +1 range - float fDilatability = saturate(0.8f - sqrt(dot(biasedCoords, biasedCoords) )); // 1 in the center, fading out to 0 at 0.8 from center, since irises are inset into maps - float2 scaledCoords = biasedCoords * (1 + fDilatability); // Maximal dilation - - // Blend undilated and maximally dilated based upon dilation factor - float2 dilatedCoords = lerp( scaledCoords, biasedCoords, 1.0f-saturate(cDilationFactor.x)); - dilatedCoords = dilatedCoords * 0.5f + 0.5f; // Back to 0..1 range -*/ - - float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); // Sample the iris map using dilated coordinates - - float4 result; - result.rgb = lerp( baseSample.rgb, irisSample.rgb, irisSample.a ); - result.rgb *= i.vertAtten; - result.rgb += glintSample.rgb * fGlintDamping; - result.a = baseSample.a; - - bool bWriteDepthToAlpha = false; - - // ps_2_b and beyond -#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) - bWriteDepthToAlpha = WRITE_DEPTH_TO_DESTALPHA != 0; -#endif - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); -} diff --git a/materialsystem/stdshaders/flashlight_ps2x.fxc b/materialsystem/stdshaders/flashlight_ps2x.fxc deleted file mode 100644 index a4f16198..00000000 --- a/materialsystem/stdshaders/flashlight_ps2x.fxc +++ /dev/null @@ -1,272 +0,0 @@ -//====== Copyright c 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//===========================================================================// - -// vertexshaders that pair with this pixel shader: -// lightmappedgeneric_flashlight_vs20 -// vertexlitgeneric_flashlight_vs20 - -// STATIC: "NORMALMAP" "0..2" -// STATIC: "NORMALMAP2" "0..1" -// STATIC: "WORLDVERTEXTRANSITION" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..1" [ps20] -// STATIC: "DETAIL_BLEND_MODE" "0..1" [ps20b] [ps30] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [ps30] - -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] [ps30] -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -// SKIP: !$WORLDVERTEXTRANSITION && $NORMALMAP2 -// SKIP: !$NORMALMAP && $NORMALMAP2 -// SKIP: !$DETAILTEXTURE && ( $DETAIL_BLEND_MODE != 0 ) - -//#include "common_fog_ps_supportsvertexfog_fxc.h" -#include "shader_constant_register_map.h" -#include "common_flashlight_fxc.h" -#include "common_lightmappedgeneric_fxc.h" - -#include "deferred_shadows.h" - -//const float3 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); -const float4 g_DetailConstants : register( c0 ); -const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float4 g_FlashlightAttenuation : register( PSREG_FLASHLIGHT_ATTENUATION ); -const float3 g_FlashLightPos : register( PSREG_FRESNEL_SPEC_PARAMS ); -// asw -// const float4 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); - -/*#if UBERLIGHT && defined( SHADER_MODEL_PS_3_0 ) - -// add this when you add in uberlight: DYNAMIC: "UBERLIGHT" "0..1" [ps30] - -const float3 g_vSmoothEdge0 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_0 ); -const float3 g_vSmoothEdge1 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_1 ); -const float3 g_vSmoothOneOverWidth : register( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW ); -const float4 g_vShearRound : register( PSREG_UBERLIGHT_SHEAR_ROUND ); -const float4 g_aAbB : register( PSREG_UBERLIGHT_AABB ); -const float4x4 g_FlashlightWorldToLight : register( PSREG_UBERLIGHT_WORLD_TO_LIGHT ); -#endif*/ - -sampler SpotSampler : register( s0 ); -sampler BaseTextureSampler : register( s1 ); -sampler NormalizingCubemapSampler : register( s2 ); - -// use a normalizing cube map here if we aren't normal mapping -sampler BumpMapSampler : register( s3 ); -sampler BaseTextureSampler2 : register( s4 ); - -#ifdef WORLDVERTEXTRANSITION -sampler NormalMap2Sampler : register( s6 ); -#endif - -#if DETAILTEXTURE -sampler DetailSampler : register( s8 ); -#endif - -#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) -sampler RandomRotationSampler : register( s5 ); // Random rotation sampler -sampler FlashlightDepthSampler : register( s7 ); -#endif - -struct PS_INPUT -{ - float4 spotTexCoord : TEXCOORD0; -#if SEAMLESS - float3 SeamlessTexCoord : TEXCOORD1; -#else - float2 baseTexCoord : TEXCOORD1; -#endif -#if NORMALMAP - float3 tangentPosToLightVector : TEXCOORD2; - float2 normalMapTexCoord : TEXCOORD3; -#else - float3 worldPosToLightVector : TEXCOORD2; - float3 normal : TEXCOORD3; -#endif - - float2 detailCoords : TEXCOORD4; - float4 worldPos_worldTransition : TEXCOORD5; -#if HARDWAREFOGBLEND || DOPIXELFOG - float3 projPos_fogFactorW : TEXCOORD6; -#else - float4 projPos_fogFactorW : TEXCOORD6; -#endif - - float4 vNormalSqr : COLOR1; -}; - - - -float4 SampleNormal( sampler s, PS_INPUT i ) -{ -#if SEAMLESS - float4 szy=tex2D( s, i.SeamlessTexCoord.zy ); - float4 sxz=tex2D( s, i.SeamlessTexCoord.xz ); - float4 syx=tex2D( s, i.SeamlessTexCoord.xy ); - //return i.fogFactorW.r*szy + i.fogFactorW.g*sxz + i.fogFactorW.b*syx; - return i.vNormalSqr.r*szy + i.vNormalSqr.g*sxz + i.vNormalSqr.b*syx; -#else -#if NORMALMAP - return tex2D( s, i.normalMapTexCoord.xy); -#else - return float4(0,0,1,1); -#endif -#endif - -} - -float4 main( PS_INPUT i ) : COLOR -{ - bool bBase2 = WORLDVERTEXTRANSITION ? true : false; - bool bBump = (NORMALMAP != 0) ? true : false; - - // Do spot stuff early since we can bail out - float3 spotColor = float3(0,0,0); - float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; - - spotColor = tex2D( SpotSampler, vProjCoords ); - -#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) - spotColor = tex2D( SpotSampler, vProjCoords ); - //spotColor *= i.spotTexCoord.www > float3(0,0,0); // Catch back projection (PC-only at the moment) -#endif - - float4 baseColor = 0.0f; - float4 baseColor2 = 0.0f; - float4 vNormal = float4(0, 0, 1, 1); - float3 baseTexCoords = float3(0,0,0); - //float3 normalTexCoords = float3( 0, 0, 0 ); - -#if SEAMLESS - baseTexCoords = i.SeamlessTexCoord.xyz; - //normalTexCoords = baseTexCoords; -#else - baseTexCoords.xy = i.baseTexCoord.xy; - /*#if ( NORMALMAP != 0 ) - normalTexCoords.xy = i.normalMapTexCoord.xy; - #else - normalTexCoords = baseTexCoords; - #endif*/ -#endif - - //GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpMapSampler, bBase2, bBump, baseTexCoords, i.fogFactorW.xyz, baseColor, baseColor2, vNormal ); - - GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpMapSampler, bBase2, bBump, - baseTexCoords, /*normalTexCoords,*/ i.vNormalSqr.xyz, baseColor, baseColor2, vNormal ); - -#if DETAILTEXTURE - float4 detailColor = float4( g_DetailConstants.xyz, 1.0f ) * tex2D( DetailSampler, i.detailCoords ); -#endif - -#if WORLDVERTEXTRANSITION - float lerpAlpha = 1-i.worldPos_worldTransition.a; -#endif - -#if ( NORMALMAP == 0 ) - vNormal.xyz = normalize( i.normal.xyz ); -#endif - -#if ( NORMALMAP == 1 ) - vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // signed - -# if NORMALMAP2 - float3 normal2 = SampleNormal( NormalMap2Sampler, i ) * 2.0f - 1.0f; - vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha ); -# endif -#endif - -// ssbump -#if ( NORMALMAP == 2 ) - -# if NORMALMAP2 - float3 normal2 = SampleNormal( NormalMap2Sampler, i ); - vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha ); -# endif -#if ( DETAILTEXTURE && ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP ) ) - vNormal.xyz *= 2.0 * detailColor; -#endif - -#else - // Normalize normal after all of the lerps above (including the tri/bilinear texel fetches) - vNormal.xyz = normalize( vNormal.xyz ); -#endif - - spotColor.rgb *= cFlashlightColor.rgb; - - // Compute per-pixel distance attenuation - float3 delta = g_FlashLightPos - i.worldPos_worldTransition.xyz; - float distSquared = dot( delta, delta ); - float dist = sqrt( distSquared ); - float farZ = g_FlashlightAttenuation.w; - float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); - float flAtten = saturate(endFalloffFactor * dot( g_FlashlightAttenuation.xyz, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); - -#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) - float flShadow = tex2DprojBicubic(FlashlightDepthSampler, 512.0f.xx, vProjCoords.xy, vProjCoords.z); - //float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos_fogFactorW.xy / i.projPos_fogFactorW.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, false ); - float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = saturate(lerp( flAttenuated, flShadow, flAtten )); // Blend between shadow and above, according to light attenuation - spotColor *= flShadow; -#endif - -/*#if UBERLIGHT && defined( SHADER_MODEL_PS_3_0 ) - // Transform from world space position to light space position - float3 flashlightSpacePosition = mul( float4( i.worldPos_worldTransition.xyz, 1.0f ), g_FlashlightWorldToLight ).yzx; - spotColor *= uberlight( flashlightSpacePosition, g_vSmoothEdge0, g_vSmoothEdge1, - g_vSmoothOneOverWidth, g_vShearRound.xy, g_aAbB, g_vShearRound.zw ); -#endif*/ - - -#if WORLDVERTEXTRANSITION && !defined( SHADER_MODEL_PS_2_0 ) - baseColor.xyz = lerp( baseColor2.xyz, baseColor.xyz, lerpAlpha ); -#endif - -#if DETAILTEXTURE - float4 vBase = TextureCombine( float4(baseColor.xyz, 1.0f), detailColor, DETAIL_BLEND_MODE, g_DetailConstants.w ); - - //float4 vBase = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailConstants.w ); - baseColor.xyz = vBase.xyz; -#endif - -#if NORMALMAP == 0 - float3 worldPosToLightVector = texCUBE( NormalizingCubemapSampler, i.worldPosToLightVector ) * 2.0f - 1.0f; - float nDotL = dot( worldPosToLightVector, vNormal.xyz ); -#endif - -#if NORMALMAP == 1 - // flashlightfixme: wrap this! - float3 tangentPosToLightVector = texCUBE( NormalizingCubemapSampler, i.tangentPosToLightVector ) * 2.0f - 1.0f; - float nDotL = dot( tangentPosToLightVector, vNormal.xyz ); -#endif - -#if NORMALMAP == 2 - float3 tangentPosToLightVector = normalize( i.tangentPosToLightVector ); - - float nDotL = - vNormal.x*dot( tangentPosToLightVector, bumpBasis[0]) + - vNormal.y*dot( tangentPosToLightVector, bumpBasis[1]) + - vNormal.z*dot( tangentPosToLightVector, bumpBasis[2]); -#endif - - float3 outColor; - //outColor = g_DiffuseModulation * spotColor * baseColor.xyz * saturate( nDotL ); - outColor = spotColor * baseColor.xyz * saturate( nDotL ); - outColor *= flAtten; - - /*float flVertexFogFactor = 0.0f; - #if ( !HARDWAREFOGBLEND && !DOPIXELFOG ) - { - flVertexFogFactor = i.projPos_fogFactorW.w; - } - #endif - float fogFactor = CalcPixelFogFactorSupportsVertexFog( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_worldTransition.xyz, i.projPos_fogFactorW.z, flVertexFogFactor );*/ - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_worldTransition.xyz, i.projPos_fogFactorW.z ); - return FinalOutput( float4(outColor, baseColor.a) , fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -} diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp b/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp deleted file mode 100644 index 9b02330a..00000000 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// - -/* Example how to plug this into an existing shader: - - In the VMT: - // Flesh Interior Pass - "$FleshInteriorEnabled" "1" // Enables effect - "$FleshInteriorTexture" "models/Alyx/alyx_flesh_color" // Mask in alpha - "$FleshNormalTexture" "models/Alyx/alyx_flesh_normal" - "$FleshBorderTexture1D" "models/Alyx/alyx_flesh_border" - "$FleshInteriorNoiseTexture" "Engine/noise-blur-256x256" - "$FleshSubsurfaceTexture" "models/Alyx/alyx_flesh_subsurface" - "$FleshBorderNoiseScale" "1.5" // Flesh Noise UV scalar for border - "$FleshBorderWidth" "0.3" // Width of flesh border - "$FleshBorderSoftness" "0.42" // Border softness must be greater than 0.0 and up tp 0.5 - "$FleshBorderTint" "[1 1 1]" // Tint / brighten the border 1D texture - "$FleshGlossBrightness" "0.66" // Change the brightness of the glossy layer - "$FleshDebugForceFleshOn" "0" // DEBUG: This will force on full flesh for testing - "$FleshScrollSpeed" "1.0" - "Proxies" - { - "FleshInterior" - { - } - } - - #include "flesh_interior_blended_pass_helper.h" - - In BEGIN_SHADER_PARAMS: - // Flesh Interior Pass - SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) - SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) - SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) - SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) - SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) - SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) - SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) - SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) - SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) - SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) - SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) - SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) - SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) - SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) - SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) - - Add this above SHADER_INIT_PARAMS() - // Flesh Interior Pass - void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) - { - info.m_nFleshTexture = FLESHINTERIORTEXTURE; - info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; - info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; - info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; - info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; - info.m_nFleshCubeTexture = FLESHCUBETEXTURE; - - info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; - info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; - info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; - info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; - info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; - info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; - - info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; - info.m_nflBorderWidth = FLESHBORDERWIDTH; - info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; - info.m_ncBorderTint = FLESHBORDERTINT; - info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; - info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; - info.m_nflScrollSpeed = FLESHSCROLLSPEED; - } - - In SHADER_INIT_PARAMS() - // Flesh Interior Pass - if ( !params[FLESHINTERIORENABLED]->IsDefined() ) - { - params[FLESHINTERIORENABLED]->SetIntValue( 0 ); - } - else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); - } - - In SHADER_INIT - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitFleshInteriorBlendedPass( this, params, info ); - } - - At the very end of SHADER_DRAW - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( true ) ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - -==================================================================================================== */ - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" -#include "convar.h" -#include "flesh_interior_blended_pass_helper.h" - -// Auto generated inc files -#include "flesh_interior_blended_pass_dx8_vs11.inc" - -void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) -{ - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFleshCubeTexture, "env_cubemap" ); // Default to in-game env map - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderNoiseScale, kDefaultBorderNoiseScale ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflDebugForceFleshOn, kDefaultDebugForceFleshOn ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius1, kDefaultEffectCenterRadius, 4 ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius2, kDefaultEffectCenterRadius, 4 ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius3, kDefaultEffectCenterRadius, 4 ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius4, kDefaultEffectCenterRadius, 4 ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncSubsurfaceTint, kDefaultSubsurfaceTint, 4 ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderWidth, kDefaultBorderWidth ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderSoftness, kDefaultBorderSoftness ); - SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncBorderTint, kDefaultBorderTint, 4 ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlobalOpacity, kDefaultGlobalOpacity ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlossBrightness, kDefaultGlossBrightness ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflScrollSpeed, kDefaultScrollSpeed ); - SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); -} - -void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ) -{ - // Load textures - pShader->LoadTexture( info.m_nFleshTexture ); - //pShader->LoadTexture( info.m_nFleshNoiseTexture ); - //pShader->LoadTexture( info.m_nFleshBorderTexture1D ); - //pShader->LoadTexture( info.m_nFleshNormalTexture ); - //pShader->LoadTexture( info.m_nFleshSubsurfaceTexture ); - //pShader->LoadCubeMap( info.m_nFleshCubeTexture ); -} - -void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) -{ - SHADOW_STATE - { - // Reset shadow state manually since we're drawing from two materials - pShader->SetInitialShadowState(); - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - // Vertex Shader - flesh_interior_blended_pass_dx8_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "flesh_interior_blended_pass_dx8_vs11", vshIndex.GetIndex() ); - - // Pixel Shader - pShaderShadow->SetPixelShader( "flesh_interior_blended_pass_dx8_ps11", 0 ); - - // Textures - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Blending - pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->EnableAlphaTest( true ); - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); - } - DYNAMIC_STATE - { - // Reset render state manually since we're drawing from two materials - pShaderAPI->SetDefaultState(); - - // Set Vertex Shader Combos - flesh_interior_blended_pass_dx8_vs11_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - // Set Vertex Shader Constants - - // Time % 1000 - float flCurrentTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); - flCurrentTime *= IS_PARAM_DEFINED( info.m_nflScrollSpeed ) ? params[info.m_nflScrollSpeed]->GetFloatValue() : kDefaultScrollSpeed; // This is a dirty hack, but it works well enough - - float vVsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - vVsConst0[0] = flCurrentTime; - vVsConst0[0] -= (float)( (int)( vVsConst0[0] / 1000.0f ) ) * 1000.0f; - - // Flesh effect centers and radii - float vVsConst1[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; - if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius1 ) ) - { - params[info.m_nvEffectCenterRadius1]->GetVecValue( vVsConst1, 4 ); - if ( vVsConst1[3] < 0.001f ) - vVsConst1[3] = 0.001f; - vVsConst1[3] = 1.0f / vVsConst1[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader - } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vVsConst1, 1 ); - - float vVsConst2[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; - if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius2 ) ) - { - params[info.m_nvEffectCenterRadius2]->GetVecValue( vVsConst2, 4 ); - if ( vVsConst2[3] < 0.001f ) - vVsConst2[3] = 0.001f; - vVsConst2[3] = 1.0f / vVsConst2[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader - } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vVsConst2, 2 ); - - float vVsConst3[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; - if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius3 ) ) - { - params[info.m_nvEffectCenterRadius3]->GetVecValue( vVsConst3, 4 ); - if ( vVsConst3[3] < 0.001f ) - vVsConst3[3] = 0.001f; - vVsConst3[3] = 1.0f / vVsConst3[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader - } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vVsConst3, 3 ); - - float vVsConst4[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; - if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius4 ) ) - { - params[info.m_nvEffectCenterRadius4]->GetVecValue( vVsConst4, 4 ); - if ( vVsConst4[3] < 0.001f ) - vVsConst4[3] = 0.001f; - vVsConst4[3] = 1.0f / vVsConst4[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader - } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); - - // Set Pixel Shader Combos - /* None */ - - // Bind textures - pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); - - // Set Pixel Shader Constants - - // Border color tint - pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_ncBorderTint ) ? params[info.m_ncBorderTint]->GetVecValue() : kDefaultBorderTint, 1 ); - - // Global opacity - float vPsConst4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - vPsConst4[0] = IS_PARAM_DEFINED( info.m_nflGlobalOpacity ) ? params[info.m_nflGlobalOpacity]->GetFloatValue() : kDefaultGlobalOpacity; - pShaderAPI->SetPixelShaderConstant( 4, vPsConst4, 1 ); - - float vPsConst5[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - pShaderAPI->SetPixelShaderConstant( 5, vPsConst5, 1 ); - } - pShader->Draw(); -} diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh b/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh deleted file mode 100644 index a9e675d4..00000000 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh +++ /dev/null @@ -1,15 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; c5 1, 1, 1, 1 -;------------------------------------------------------------------------------ - -tex t0 ; Base color - -mul r0, v0, v0 ; // Mask^2 -mul r0, r0, r0 ; // Mask^4 -sub r0, c5, r0 ; // 1.0 - Mask^4 - -mul r0.rgb, r0, t0 ; // * Flesh texture color -mul r0.a, r0.a, t0.a ; // * Flesh X-rated mask -mul r0.a, r0.a, v1.a ; // * Fresnel mask diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh b/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh deleted file mode 100644 index 53b6d87d..00000000 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh +++ /dev/null @@ -1,114 +0,0 @@ -# DYNAMIC: "SKINNING" "0..1" - -vs.1.1 -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; Vertex blending -;------------------------------------------------------------------------------ -&AllocateRegister( \$worldPos ); -&AllocateRegister( \$worldNormal ); -&AllocateRegister( \$projPos ); - -&SkinPositionAndNormal( $worldPos, $worldNormal ); - -if( $SKINNING == 1 ) -{ - &Normalize( $worldNormal ); -} - -;------------------------------------------------------------------------------ -; Transform the position from world to view space -;------------------------------------------------------------------------------ -dp4 $projPos.x, $worldPos, $cViewProj0 -dp4 $projPos.y, $worldPos, $cViewProj1 -dp4 $projPos.z, $worldPos, $cViewProj2 -dp4 $projPos.w, $worldPos, $cViewProj3 - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog - don't bother with water fog for intro effects -;------------------------------------------------------------------------------ -&DepthFog( $projPos, "oFog" ); -&FreeRegister( \$projPos ); - -;------------------------------------------------------------------------------ -; Flesh area -;------------------------------------------------------------------------------ -; // Store the closest effect intensity -; o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance -; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); -; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); -; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); -; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); - -alloc $tmp1 -alloc $flEffect - -mov $flEffect, $cTwo -mad $flEffect, $flEffect, $cTwo, $cTwo - -sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_1 -dp3 $tmp1.w, $tmp1, $tmp1 -rsq $tmp1.w, $tmp1.w -rcp $tmp1.w, $tmp1.w -mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_1.w -min $flEffect, $flEffect, $tmp1.w - -sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_2 -dp3 $tmp1.w, $tmp1, $tmp1 -rsq $tmp1.w, $tmp1.w -rcp $tmp1.w, $tmp1.w -mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_2.w -min $flEffect, $flEffect, $tmp1.w - -sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_3 -dp3 $tmp1.w, $tmp1, $tmp1 -rsq $tmp1.w, $tmp1.w -rcp $tmp1.w, $tmp1.w -mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_3.w -min $flEffect, $flEffect, $tmp1.w - -sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_4 -dp3 $tmp1.w, $tmp1, $tmp1 -rsq $tmp1.w, $tmp1.w -rcp $tmp1.w, $tmp1.w -mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_4.w -min $flEffect, $flEffect, $tmp1.w - -mov oD0, $flEffect - -; float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); -; o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); - -sub $tmp1, $worldPos, $cEyePos -&Normalize( $tmp1 ); -dp3 $tmp1, -$tmp1, $worldNormal -max $tmp1, $tmp1, $cZero -mul $tmp1, $tmp1, $tmp1 -mov oD1, $tmp1 - -free $tmp1 -free $flEffect - -;------------------------------------------------------------------------------ -; Texture coordinates -;------------------------------------------------------------------------------ - -mov oT0.xy, $vTexCoord0 - -alloc $tmp2 - -dp4 $tmp2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 -dp4 $tmp2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - -add oT1.xy, $tmp2, $SHADER_SPECIFIC_CONST_4 - -free $tmp2 - -; YUCK! This is to make texcoords continuous for mat_softwaretl -mov oT2, $cZero - -&FreeRegister( \$worldPos ); -&FreeRegister( \$worldNormal ); diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp b/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp index 885a4cf6..d3862d50 100644 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp +++ b/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp @@ -118,15 +118,12 @@ ==================================================================================================== */ -#include "BaseVSShader.h" +#include "basevsshader.h" #include "mathlib/vmatrix.h" #include "convar.h" #include "flesh_interior_blended_pass_helper.h" - -// Auto generated inc files -#include "flesh_interior_blended_pass_vs20.inc" -#include "flesh_interior_blended_pass_ps20.inc" -#include "flesh_interior_blended_pass_ps20b.inc" +#include "sdk_flesh_interior_blended_pass_vs30.inc" +#include "sdk_flesh_interior_blended_pass_ps30.inc" void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) { @@ -174,25 +171,16 @@ void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params int userDataSize = 0; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + //bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); // Vertex Shader - DECLARE_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_flesh_interior_blended_pass_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_flesh_interior_blended_pass_vs30 ); // Pixel Shader - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); - SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); - SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); - } + DECLARE_STATIC_PIXEL_SHADER( sdk_flesh_interior_blended_pass_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_flesh_interior_blended_pass_ps30 ); // Textures pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); @@ -219,19 +207,17 @@ void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params // Reset render state manually since we're drawing from two materials pShaderAPI->SetDefaultState(); - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + //bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); // Set Vertex Shader Combos LightState_t lightState = { 0, false, false }; pShaderAPI->GetDX9LightState( &lightState ); - DECLARE_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_flesh_interior_blended_pass_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_flesh_interior_blended_pass_vs30 ); // Set Vertex Shader Constants pShader->SetAmbientCubeDynamicStateVertexShader(); @@ -298,16 +284,8 @@ void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); // Set Pixel Shader Combos - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_flesh_interior_blended_pass_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_flesh_interior_blended_pass_ps30 ); // Bind textures pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc b/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc index 3e288e56..9776a28e 100644 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc +++ b/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc @@ -1,8 +1,7 @@ -//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// // Includes ======================================================================================= -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -#include "common_vertexlitgeneric_dx9.h" +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +#include "common_vertexlitgeneric.h" // Texture Samplers =============================================================================== sampler g_tBaseSampler : register( s0 ); diff --git a/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc b/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc index 2a361b01..eabe64f4 100644 --- a/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc +++ b/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc @@ -1,11 +1,10 @@ -//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// // STATIC: "HALFLAMBERT" "0..1" // STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] // DYNAMIC: "COMPRESSED_VERTS" "0..1" // DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" // DYNAMIC: "DYNAMIC_LIGHT" "0..1" // DYNAMIC: "STATIC_LIGHT" "0..1" // DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] @@ -17,7 +16,6 @@ #include "common_vs_fxc.h" // Globals -static const int g_iFogType = DOWATERFOG; static const bool g_bHalfLambert = HALFLAMBERT ? true : false; static const bool g_bSkinning = SKINNING ? true : false; diff --git a/materialsystem/stdshaders/Fxaa3_11.h b/materialsystem/stdshaders/fxaa3_11.h similarity index 100% rename from materialsystem/stdshaders/Fxaa3_11.h rename to materialsystem/stdshaders/fxaa3_11.h diff --git a/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs30.inc b/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs30.inc deleted file mode 100644 index 01dcd1ca..00000000 --- a/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class sdk_screenspaceeffect_vs30_Static_Index -{ -private: - int m_nX360APPCHOOSER; -#ifdef _DEBUG - bool m_bX360APPCHOOSER; -#endif -public: - void SetX360APPCHOOSER( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nX360APPCHOOSER = i; -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif - } - void SetX360APPCHOOSER( bool i ) - { - m_nX360APPCHOOSER = i ? 1 : 0; -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif - } -public: - sdk_screenspaceeffect_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif // _DEBUG - m_nX360APPCHOOSER = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bX360APPCHOOSER; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nX360APPCHOOSER ) + 0; - } -}; -#define shaderStaticTest_sdk_screenspaceeffect_vs30 0 -class sdk_screenspaceeffect_vs30_Dynamic_Index -{ -public: - sdk_screenspaceeffect_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_sdk_screenspaceeffect_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/Vance_Tonemap_ps30.inc b/materialsystem/stdshaders/fxctmp9/Vance_Tonemap_ps30.inc deleted file mode 100644 index b49a8f68..00000000 --- a/materialsystem/stdshaders/fxctmp9/Vance_Tonemap_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_tonemap_ps30_Static_Index -{ -public: - vance_tonemap_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_tonemap_ps30 0 -class vance_tonemap_ps30_Dynamic_Index -{ -private: - int m_nMODE; -#ifdef _DEBUG - bool m_bMODE; -#endif -public: - void SetMODE( int i ) - { - Assert( i >= 0 && i <= 3 ); - m_nMODE = i; -#ifdef _DEBUG - m_bMODE = true; -#endif - } - void SetMODE( bool i ) - { - m_nMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bMODE = true; -#endif - } -public: - vance_tonemap_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bMODE = false; -#endif // _DEBUG - m_nMODE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bMODE; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nMODE ) + 0; - } -}; -#define shaderDynamicTest_vance_tonemap_ps30 psh_forgot_to_set_dynamic_MODE + 0 diff --git a/materialsystem/stdshaders/fxctmp9/VertexLit_and_unlit_Generic_bump_vs30.inc b/materialsystem/stdshaders/fxctmp9/VertexLit_and_unlit_Generic_bump_vs30.inc deleted file mode 100644 index b4231fc2..00000000 --- a/materialsystem/stdshaders/fxctmp9/VertexLit_and_unlit_Generic_bump_vs30.inc +++ /dev/null @@ -1,212 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_bump_vs30_Static_Index -{ -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nUSE_WITH_2B; -#ifdef _DEBUG - bool m_bUSE_WITH_2B; -#endif -public: - void SetUSE_WITH_2B( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nUSE_WITH_2B = i; -#ifdef _DEBUG - m_bUSE_WITH_2B = true; -#endif - } - void SetUSE_WITH_2B( bool i ) - { - m_nUSE_WITH_2B = i ? 1 : 0; -#ifdef _DEBUG - m_bUSE_WITH_2B = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bUSE_WITH_2B = false; -#endif // _DEBUG - m_nUSE_WITH_2B = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bDECAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 16 * m_nHALFLAMBERT ) + ( 32 * m_nUSE_WITH_2B ) + ( 64 * m_nDECAL ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_DECAL + 0 -class vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9/VertexlitPBR_ps30.inc b/materialsystem/stdshaders/fxctmp9/VertexlitPBR_ps30.inc deleted file mode 100644 index ff589ffd..00000000 --- a/materialsystem/stdshaders/fxctmp9/VertexlitPBR_ps30.inc +++ /dev/null @@ -1,387 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlitpbr_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -public: - vertexlitpbr_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2880 * m_nCONVERT_TO_SRGB ) + ( 2880 * m_nFLASHLIGHT ) + ( 5760 * m_nCUBEMAP ) + ( 11520 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 23040 * m_nSMOOTHNESS ) + 0; - } -}; -#define shaderStaticTest_vertexlitpbr_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + 0 -class vertexlitpbr_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nLIGHTMAP; -#ifdef _DEBUG - bool m_bLIGHTMAP; -#endif -public: - void SetLIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTMAP = i; -#ifdef _DEBUG - m_bLIGHTMAP = true; -#endif - } - void SetLIGHTMAP( bool i ) - { - m_nLIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTMAP = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -private: - int m_nLIGHT_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHT_PREVIEW; -#endif -public: - void SetLIGHT_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHT_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } - void SetLIGHT_PREVIEW( bool i ) - { - m_nLIGHT_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } -public: - vertexlitpbr_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bLIGHTMAP = false; -#endif // _DEBUG - m_nLIGHTMAP = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = false; -#endif // _DEBUG - m_nLIGHT_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bLIGHTMAP && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + ( 80 * m_nLIGHTMAP ) + ( 160 * m_nCSM ) + ( 320 * m_nCSM_PERF ) + ( 960 * m_nLIGHT_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_vertexlitpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_LIGHTMAP + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9/chromatic_ps30.inc b/materialsystem/stdshaders/fxctmp9/chromatic_ps30.inc deleted file mode 100644 index 56c0babc..00000000 --- a/materialsystem/stdshaders/fxctmp9/chromatic_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class chromatic_ps30_Static_Index -{ -public: - chromatic_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_chromatic_ps30 0 -class chromatic_ps30_Dynamic_Index -{ -private: - int m_nRADIAL; -#ifdef _DEBUG - bool m_bRADIAL; -#endif -public: - void SetRADIAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nRADIAL = i; -#ifdef _DEBUG - m_bRADIAL = true; -#endif - } - void SetRADIAL( bool i ) - { - m_nRADIAL = i ? 1 : 0; -#ifdef _DEBUG - m_bRADIAL = true; -#endif - } -public: - chromatic_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bRADIAL = false; -#endif // _DEBUG - m_nRADIAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bRADIAL; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nRADIAL ) + 0; - } -}; -#define shaderDynamicTest_chromatic_ps30 psh_forgot_to_set_dynamic_RADIAL + 0 diff --git a/materialsystem/stdshaders/fxctmp9/chromatic_vs30.inc b/materialsystem/stdshaders/fxctmp9/chromatic_vs30.inc deleted file mode 100644 index 99899863..00000000 --- a/materialsystem/stdshaders/fxctmp9/chromatic_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class chromatic_vs30_Static_Index -{ -public: - chromatic_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_chromatic_vs30 0 -class chromatic_vs30_Dynamic_Index -{ -public: - chromatic_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_chromatic_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/depthwrite_ps20.inc b/materialsystem/stdshaders/fxctmp9/depthwrite_ps20.inc deleted file mode 100644 index d9be0712..00000000 --- a/materialsystem/stdshaders/fxctmp9/depthwrite_ps20.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps20_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps20_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps20 psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps20_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps20_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps20 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9/depthwrite_ps20b.inc b/materialsystem/stdshaders/fxctmp9/depthwrite_ps20b.inc deleted file mode 100644 index a3d0bf44..00000000 --- a/materialsystem/stdshaders/fxctmp9/depthwrite_ps20b.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps20b_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps20b_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps20b psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps20b_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps20b_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps20b psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9/depthwrite_ps30.inc b/materialsystem/stdshaders/fxctmp9/depthwrite_ps30.inc deleted file mode 100644 index af6d03c2..00000000 --- a/materialsystem/stdshaders/fxctmp9/depthwrite_ps30.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps30_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps30 psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps30_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps30 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9/depthwrite_vs20.inc b/materialsystem/stdshaders/fxctmp9/depthwrite_vs20.inc deleted file mode 100644 index 7b94dc52..00000000 --- a/materialsystem/stdshaders/fxctmp9/depthwrite_vs20.inc +++ /dev/null @@ -1,137 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_vs20_Static_Index -{ -private: - int m_nONLY_PROJECT_POSITION; -#ifdef _DEBUG - bool m_bONLY_PROJECT_POSITION; -#endif -public: - void SetONLY_PROJECT_POSITION( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nONLY_PROJECT_POSITION = i; -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = true; -#endif - } - void SetONLY_PROJECT_POSITION( bool i ) - { - m_nONLY_PROJECT_POSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = true; -#endif - } -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_vs20_Static_Index( ) - { -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = false; -#endif // _DEBUG - m_nONLY_PROJECT_POSITION = 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nONLY_PROJECT_POSITION ) + ( 4 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_vs20 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_vs20_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -public: - depthwrite_vs20_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshaders/fxctmp9/example_model_ps30.inc b/materialsystem/stdshaders/fxctmp9/example_model_ps30.inc deleted file mode 100644 index 836cb618..00000000 --- a/materialsystem/stdshaders/fxctmp9/example_model_ps30.inc +++ /dev/null @@ -1,162 +0,0 @@ -#include "shaderlib/cshader.h" -class example_model_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -public: - example_model_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 20 * m_nCONVERT_TO_SRGB ) + ( 20 * m_nFLASHLIGHT ) + 0; - } -}; -#define shaderStaticTest_example_model_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + 0 -class example_model_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -public: - example_model_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + 0; - } -}; -#define shaderDynamicTest_example_model_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9/example_model_vs30.inc b/materialsystem/stdshaders/fxctmp9/example_model_vs30.inc deleted file mode 100644 index 88082217..00000000 --- a/materialsystem/stdshaders/fxctmp9/example_model_vs30.inc +++ /dev/null @@ -1,160 +0,0 @@ -#include "shaderlib/cshader.h" -class example_model_vs30_Static_Index -{ -public: - example_model_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_example_model_vs30 0 -class example_model_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -public: - example_model_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0; - } -}; -#define shaderDynamicTest_example_model_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9/flashlight_ps30.inc b/materialsystem/stdshaders/fxctmp9/flashlight_ps30.inc deleted file mode 100644 index 6e292b46..00000000 --- a/materialsystem/stdshaders/fxctmp9/flashlight_ps30.inc +++ /dev/null @@ -1,262 +0,0 @@ -#include "shaderlib/cshader.h" -class flashlight_ps30_Static_Index -{ -private: - int m_nNORMALMAP; -#ifdef _DEBUG - bool m_bNORMALMAP; -#endif -public: - void SetNORMALMAP( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nNORMALMAP = i; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } - void SetNORMALMAP( bool i ) - { - m_nNORMALMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } -private: - int m_nNORMALMAP2; -#ifdef _DEBUG - bool m_bNORMALMAP2; -#endif -public: - void SetNORMALMAP2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAP2 = i; -#ifdef _DEBUG - m_bNORMALMAP2 = true; -#endif - } - void SetNORMALMAP2( bool i ) - { - m_nNORMALMAP2 = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP2 = true; -#endif - } -private: - int m_nWORLDVERTEXTRANSITION; -#ifdef _DEBUG - bool m_bWORLDVERTEXTRANSITION; -#endif -public: - void SetWORLDVERTEXTRANSITION( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWORLDVERTEXTRANSITION = i; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } - void SetWORLDVERTEXTRANSITION( bool i ) - { - m_nWORLDVERTEXTRANSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -public: - flashlight_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bNORMALMAP = false; -#endif // _DEBUG - m_nNORMALMAP = 0; -#ifdef _DEBUG - m_bNORMALMAP2 = false; -#endif // _DEBUG - m_nNORMALMAP2 = 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = false; -#endif // _DEBUG - m_nWORLDVERTEXTRANSITION = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; - } -}; -#define shaderStaticTest_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 -class flashlight_ps30_Dynamic_Index -{ -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -public: - flashlight_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFLASHLIGHTSHADOWS && m_bPIXELFOGTYPE; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFLASHLIGHTSHADOWS ) + ( 2 * m_nPIXELFOGTYPE ) + 0; - } -}; -#define shaderDynamicTest_flashlight_ps30 psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshaders/fxctmp9/fxaa_ps30.inc b/materialsystem/stdshaders/fxctmp9/fxaa_ps30.inc deleted file mode 100644 index 4892cac8..00000000 --- a/materialsystem/stdshaders/fxctmp9/fxaa_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class fxaa_ps30_Static_Index -{ -public: - fxaa_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_fxaa_ps30 0 -class fxaa_ps30_Dynamic_Index -{ -private: - int m_nQUALITY; -#ifdef _DEBUG - bool m_bQUALITY; -#endif -public: - void SetQUALITY( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nQUALITY = i; -#ifdef _DEBUG - m_bQUALITY = true; -#endif - } - void SetQUALITY( bool i ) - { - m_nQUALITY = i ? 1 : 0; -#ifdef _DEBUG - m_bQUALITY = true; -#endif - } -public: - fxaa_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bQUALITY = false; -#endif // _DEBUG - m_nQUALITY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bQUALITY; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nQUALITY ) + 0; - } -}; -#define shaderDynamicTest_fxaa_ps30 psh_forgot_to_set_dynamic_QUALITY + 0 diff --git a/materialsystem/stdshaders/fxctmp9/fxaa_vs30.inc b/materialsystem/stdshaders/fxctmp9/fxaa_vs30.inc deleted file mode 100644 index a2b01587..00000000 --- a/materialsystem/stdshaders/fxctmp9/fxaa_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class fxaa_vs30_Static_Index -{ -public: - fxaa_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_fxaa_vs30 0 -class fxaa_vs30_Dynamic_Index -{ -public: - fxaa_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_fxaa_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_ps30.inc b/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_ps30.inc deleted file mode 100644 index 0bc22fc3..00000000 --- a/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussian_depthaware_ps30_Static_Index -{ -private: - int m_nHORIZONTAL; -#ifdef _DEBUG - bool m_bHORIZONTAL; -#endif -public: - void SetHORIZONTAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHORIZONTAL = i; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } - void SetHORIZONTAL( bool i ) - { - m_nHORIZONTAL = i ? 1 : 0; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } -public: - gaussian_depthaware_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bHORIZONTAL = false; -#endif // _DEBUG - m_nHORIZONTAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHORIZONTAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nHORIZONTAL ) + 0; - } -}; -#define shaderStaticTest_gaussian_depthaware_ps30 psh_forgot_to_set_static_HORIZONTAL + 0 -class gaussian_depthaware_ps30_Dynamic_Index -{ -public: - gaussian_depthaware_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussian_depthaware_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_roughness_ps30.inc b/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_roughness_ps30.inc deleted file mode 100644 index 5b271793..00000000 --- a/materialsystem/stdshaders/fxctmp9/gaussian_depthaware_roughness_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussian_depthaware_roughness_ps30_Static_Index -{ -private: - int m_nHORIZONTAL; -#ifdef _DEBUG - bool m_bHORIZONTAL; -#endif -public: - void SetHORIZONTAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHORIZONTAL = i; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } - void SetHORIZONTAL( bool i ) - { - m_nHORIZONTAL = i ? 1 : 0; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } -public: - gaussian_depthaware_roughness_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bHORIZONTAL = false; -#endif // _DEBUG - m_nHORIZONTAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHORIZONTAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nHORIZONTAL ) + 0; - } -}; -#define shaderStaticTest_gaussian_depthaware_roughness_ps30 psh_forgot_to_set_static_HORIZONTAL + 0 -class gaussian_depthaware_roughness_ps30_Dynamic_Index -{ -public: - gaussian_depthaware_roughness_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussian_depthaware_roughness_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/gaussianx_ps30.inc b/materialsystem/stdshaders/fxctmp9/gaussianx_ps30.inc deleted file mode 100644 index d5580527..00000000 --- a/materialsystem/stdshaders/fxctmp9/gaussianx_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussianx_ps30_Static_Index -{ -public: - gaussianx_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_gaussianx_ps30 0 -class gaussianx_ps30_Dynamic_Index -{ -public: - gaussianx_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussianx_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/gaussiany_ps30.inc b/materialsystem/stdshaders/fxctmp9/gaussiany_ps30.inc deleted file mode 100644 index d643a3d9..00000000 --- a/materialsystem/stdshaders/fxctmp9/gaussiany_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussiany_ps30_Static_Index -{ -public: - gaussiany_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_gaussiany_ps30 0 -class gaussiany_ps30_Dynamic_Index -{ -public: - gaussiany_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussiany_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/light_mesh_ps30.inc b/materialsystem/stdshaders/fxctmp9/light_mesh_ps30.inc deleted file mode 100644 index 276a0a17..00000000 --- a/materialsystem/stdshaders/fxctmp9/light_mesh_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_mesh_ps30_Static_Index -{ -public: - light_mesh_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_mesh_ps30 0 -class light_mesh_ps30_Dynamic_Index -{ -public: - light_mesh_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_mesh_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/light_mesh_vs30.inc b/materialsystem/stdshaders/fxctmp9/light_mesh_vs30.inc deleted file mode 100644 index d6495464..00000000 --- a/materialsystem/stdshaders/fxctmp9/light_mesh_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_mesh_vs30_Static_Index -{ -public: - light_mesh_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_mesh_vs30 0 -class light_mesh_vs30_Dynamic_Index -{ -public: - light_mesh_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_mesh_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/light_volumetrics_ps30.inc b/materialsystem/stdshaders/fxctmp9/light_volumetrics_ps30.inc deleted file mode 100644 index fa567827..00000000 --- a/materialsystem/stdshaders/fxctmp9/light_volumetrics_ps30.inc +++ /dev/null @@ -1,85 +0,0 @@ -#include "shaderlib/cshader.h" -class light_volumetrics_ps30_Static_Index -{ -public: - light_volumetrics_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_volumetrics_ps30 0 -class light_volumetrics_ps30_Dynamic_Index -{ -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nPERF; -#ifdef _DEBUG - bool m_bPERF; -#endif -public: - void SetPERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nPERF = i; -#ifdef _DEBUG - m_bPERF = true; -#endif - } - void SetPERF( bool i ) - { - m_nPERF = i ? 1 : 0; -#ifdef _DEBUG - m_bPERF = true; -#endif - } -public: - light_volumetrics_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bPERF = false; -#endif // _DEBUG - m_nPERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCSM && m_bPERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCSM ) + ( 2 * m_nPERF ) + 0; - } -}; -#define shaderDynamicTest_light_volumetrics_ps30 psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9/light_volumetrics_vs30.inc b/materialsystem/stdshaders/fxctmp9/light_volumetrics_vs30.inc deleted file mode 100644 index 50f1fbbd..00000000 --- a/materialsystem/stdshaders/fxctmp9/light_volumetrics_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_volumetrics_vs30_Static_Index -{ -public: - light_volumetrics_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_volumetrics_vs30 0 -class light_volumetrics_vs30_Dynamic_Index -{ -public: - light_volumetrics_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_volumetrics_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightmappedPBR_ps30.inc b/materialsystem/stdshaders/fxctmp9/lightmappedPBR_ps30.inc deleted file mode 100644 index 3a4de0b8..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightmappedPBR_ps30.inc +++ /dev/null @@ -1,412 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedpbr_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -public: - lightmappedpbr_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS && m_bSEAMLESS && m_bBUMPMAP; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 576 * m_nCONVERT_TO_SRGB ) + ( 576 * m_nFLASHLIGHT ) + ( 1152 * m_nCUBEMAP ) + ( 2304 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 4608 * m_nSMOOTHNESS ) + ( 9216 * m_nSEAMLESS ) + ( 18432 * m_nBUMPMAP ) + 0; - } -}; -#define shaderStaticTest_lightmappedpbr_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMAP + 0 -class lightmappedpbr_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nCUBEMAPCORRECTED; -#ifdef _DEBUG - bool m_bCUBEMAPCORRECTED; -#endif -public: - void SetCUBEMAPCORRECTED( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAPCORRECTED = i; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } - void SetCUBEMAPCORRECTED( bool i ) - { - m_nCUBEMAPCORRECTED = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -private: - int m_nLIGHT_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHT_PREVIEW; -#endif -public: - void SetLIGHT_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHT_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } - void SetLIGHT_PREVIEW( bool i ) - { - m_nLIGHT_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } -public: - lightmappedpbr_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = false; -#endif // _DEBUG - m_nCUBEMAPCORRECTED = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = false; -#endif // _DEBUG - m_nLIGHT_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bCUBEMAPCORRECTED && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + ( 16 * m_nCUBEMAPCORRECTED ) + ( 32 * m_nCSM ) + ( 64 * m_nCSM_PERF ) + ( 192 * m_nLIGHT_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_lightmappedpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_CUBEMAPCORRECTED + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightmappedPBR_vs30.inc b/materialsystem/stdshaders/fxctmp9/lightmappedPBR_vs30.inc deleted file mode 100644 index d4e062ac..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightmappedPBR_vs30.inc +++ /dev/null @@ -1,187 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedpbr_vs30_Static_Index -{ -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -public: - lightmappedpbr_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nBUMPMAP ) + ( 8 * m_nDIFFUSEBUMPMAP ) + ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nVERTEXALPHATEXBLENDFACTOR ) + 0; - } -}; -#define shaderStaticTest_lightmappedpbr_vs30 vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + 0 -class lightmappedpbr_vs30_Dynamic_Index -{ -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -public: - lightmappedpbr_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + 0; - } -}; -#define shaderDynamicTest_lightmappedpbr_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_flashlight_vs30.inc b/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_flashlight_vs30.inc deleted file mode 100644 index e6508779..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_flashlight_vs30.inc +++ /dev/null @@ -1,162 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_flashlight_vs30_Static_Index -{ -private: - int m_nNORMALMAP; -#ifdef _DEBUG - bool m_bNORMALMAP; -#endif -public: - void SetNORMALMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAP = i; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } - void SetNORMALMAP( bool i ) - { - m_nNORMALMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } -private: - int m_nWORLDVERTEXTRANSITION; -#ifdef _DEBUG - bool m_bWORLDVERTEXTRANSITION; -#endif -public: - void SetWORLDVERTEXTRANSITION( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWORLDVERTEXTRANSITION = i; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } - void SetWORLDVERTEXTRANSITION( bool i ) - { - m_nWORLDVERTEXTRANSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDETAIL; -#ifdef _DEBUG - bool m_bDETAIL; -#endif -public: - void SetDETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAIL = i; -#ifdef _DEBUG - m_bDETAIL = true; -#endif - } - void SetDETAIL( bool i ) - { - m_nDETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL = true; -#endif - } -public: - lightmappedgeneric_flashlight_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bNORMALMAP = false; -#endif // _DEBUG - m_nNORMALMAP = 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = false; -#endif // _DEBUG - m_nWORLDVERTEXTRANSITION = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDETAIL = false; -#endif // _DEBUG - m_nDETAIL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + 0 -class lightmappedgeneric_flashlight_vs30_Dynamic_Index -{ -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -public: - lightmappedgeneric_flashlight_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bDOWATERFOG; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nDOWATERFOG ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_ps30.inc b/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_ps30.inc deleted file mode 100644 index 8ed12670..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_ps30.inc +++ /dev/null @@ -1,662 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_ps30_Static_Index -{ -private: - int m_nMASKEDBLENDING; -#ifdef _DEBUG - bool m_bMASKEDBLENDING; -#endif -public: - void SetMASKEDBLENDING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMASKEDBLENDING = i; -#ifdef _DEBUG - m_bMASKEDBLENDING = true; -#endif - } - void SetMASKEDBLENDING( bool i ) - { - m_nMASKEDBLENDING = i ? 1 : 0; -#ifdef _DEBUG - m_bMASKEDBLENDING = true; -#endif - } -private: - int m_nBASETEXTURE2; -#ifdef _DEBUG - bool m_bBASETEXTURE2; -#endif -public: - void SetBASETEXTURE2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2 = i; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } - void SetBASETEXTURE2( bool i ) - { - m_nBASETEXTURE2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nBUMPMAP2; -#ifdef _DEBUG - bool m_bBUMPMAP2; -#endif -public: - void SetBUMPMAP2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP2 = i; -#ifdef _DEBUG - m_bBUMPMAP2 = true; -#endif - } - void SetBUMPMAP2( bool i ) - { - m_nBUMPMAP2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP2 = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nENVMAPMASK; -#ifdef _DEBUG - bool m_bENVMAPMASK; -#endif -public: - void SetENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAPMASK = i; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } - void SetENVMAPMASK( bool i ) - { - m_nENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } -private: - int m_nBASEALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bBASEALPHAENVMAPMASK; -#endif -public: - void SetBASEALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASEALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } - void SetBASEALPHAENVMAPMASK( bool i ) - { - m_nBASEALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nNORMALMAPALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bNORMALMAPALPHAENVMAPMASK; -#endif -public: - void SetNORMALMAPALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAPALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } - void SetNORMALMAPALPHAENVMAPMASK( bool i ) - { - m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nBASETEXTURENOENVMAP; -#ifdef _DEBUG - bool m_bBASETEXTURENOENVMAP; -#endif -public: - void SetBASETEXTURENOENVMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURENOENVMAP = i; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = true; -#endif - } - void SetBASETEXTURENOENVMAP( bool i ) - { - m_nBASETEXTURENOENVMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = true; -#endif - } -private: - int m_nBASETEXTURE2NOENVMAP; -#ifdef _DEBUG - bool m_bBASETEXTURE2NOENVMAP; -#endif -public: - void SetBASETEXTURE2NOENVMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2NOENVMAP = i; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = true; -#endif - } - void SetBASETEXTURE2NOENVMAP( bool i ) - { - m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = true; -#endif - } -private: - int m_nFANCY_BLENDING; -#ifdef _DEBUG - bool m_bFANCY_BLENDING; -#endif -public: - void SetFANCY_BLENDING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFANCY_BLENDING = i; -#ifdef _DEBUG - m_bFANCY_BLENDING = true; -#endif - } - void SetFANCY_BLENDING( bool i ) - { - m_nFANCY_BLENDING = i ? 1 : 0; -#ifdef _DEBUG - m_bFANCY_BLENDING = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMASK; -#ifdef _DEBUG - bool m_bBUMPMASK; -#endif -public: - void SetBUMPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMASK = i; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } - void SetBUMPMASK( bool i ) - { - m_nBUMPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } -public: - lightmappedgeneric_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bMASKEDBLENDING = false; -#endif // _DEBUG - m_nMASKEDBLENDING = 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = false; -#endif // _DEBUG - m_nBASETEXTURE2 = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bBUMPMAP2 = false; -#endif // _DEBUG - m_nBUMPMAP2 = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bENVMAPMASK = false; -#endif // _DEBUG - m_nENVMAPMASK = 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nBASEALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nNORMALMAPALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = false; -#endif // _DEBUG - m_nBASETEXTURENOENVMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = false; -#endif // _DEBUG - m_nBASETEXTURE2NOENVMAP = 0; -#ifdef _DEBUG - m_bFANCY_BLENDING = false; -#endif // _DEBUG - m_nFANCY_BLENDING = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMASK = false; -#endif // _DEBUG - m_nBUMPMASK = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1152 * m_nMASKEDBLENDING ) + ( 2304 * m_nBASETEXTURE2 ) + ( 4608 * m_nDETAILTEXTURE ) + ( 9216 * m_nBUMPMAP ) + ( 18432 * m_nBUMPMAP2 ) + ( 36864 * m_nCUBEMAP ) + ( 73728 * m_nENVMAPMASK ) + ( 147456 * m_nBASEALPHAENVMAPMASK ) + ( 294912 * m_nSELFILLUM ) + ( 589824 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1179648 * m_nDIFFUSEBUMPMAP ) + ( 2359296 * m_nBASETEXTURENOENVMAP ) + ( 4718592 * m_nBASETEXTURE2NOENVMAP ) + ( 9437184 * m_nFANCY_BLENDING ) + ( 18874368 * m_nSEAMLESS ) + ( 37748736 * m_nBUMPMASK ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_ps30 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + 0 -class lightmappedgeneric_ps30_Dynamic_Index -{ -private: - int m_nFASTPATHENVMAPCONTRAST; -#ifdef _DEBUG - bool m_bFASTPATHENVMAPCONTRAST; -#endif -public: - void SetFASTPATHENVMAPCONTRAST( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATHENVMAPCONTRAST = i; -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = true; -#endif - } - void SetFASTPATHENVMAPCONTRAST( bool i ) - { - m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = true; -#endif - } -private: - int m_nCUBEMAPCORRECTED; -#ifdef _DEBUG - bool m_bCUBEMAPCORRECTED; -#endif -public: - void SetCUBEMAPCORRECTED( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAPCORRECTED = i; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } - void SetCUBEMAPCORRECTED( bool i ) - { - m_nCUBEMAPCORRECTED = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -public: - lightmappedgeneric_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = false; -#endif // _DEBUG - m_nFASTPATHENVMAPCONTRAST = 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = false; -#endif // _DEBUG - m_nCUBEMAPCORRECTED = 0; -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bCUBEMAPCORRECTED && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA && m_bCSM && m_bCSM_PERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nCUBEMAPCORRECTED ) + ( 4 * m_nFASTPATH ) + ( 8 * m_nWRITEWATERFOGTODESTALPHA ) + ( 16 * m_nPIXELFOGTYPE ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 96 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 192 * m_nCSM ) + ( 384 * m_nCSM_PERF ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_ps30 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_CUBEMAPCORRECTED + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_vs30.inc b/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_vs30.inc deleted file mode 100644 index 853f8183..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightmappedgeneric_vs30.inc +++ /dev/null @@ -1,312 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_vs30_Static_Index -{ -private: - int m_nENVMAP_MASK; -#ifdef _DEBUG - bool m_bENVMAP_MASK; -#endif -public: - void SetENVMAP_MASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAP_MASK = i; -#ifdef _DEBUG - m_bENVMAP_MASK = true; -#endif - } - void SetENVMAP_MASK( bool i ) - { - m_nENVMAP_MASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAP_MASK = true; -#endif - } -private: - int m_nTANGENTSPACE; -#ifdef _DEBUG - bool m_bTANGENTSPACE; -#endif -public: - void SetTANGENTSPACE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nTANGENTSPACE = i; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } - void SetTANGENTSPACE( bool i ) - { - m_nTANGENTSPACE = i ? 1 : 0; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMASK; -#ifdef _DEBUG - bool m_bBUMPMASK; -#endif -public: - void SetBUMPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMASK = i; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } - void SetBUMPMASK( bool i ) - { - m_nBUMPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } -public: - lightmappedgeneric_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bENVMAP_MASK = false; -#endif // _DEBUG - m_nENVMAP_MASK = 0; -#ifdef _DEBUG - m_bTANGENTSPACE = false; -#endif // _DEBUG - m_nTANGENTSPACE = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMASK = false; -#endif // _DEBUG - m_nBUMPMASK = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS && m_bBUMPMASK; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + 0 -class lightmappedgeneric_vs30_Dynamic_Index -{ -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -public: - lightmappedgeneric_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightpass_ps30.inc b/materialsystem/stdshaders/fxctmp9/lightpass_ps30.inc deleted file mode 100644 index fb620926..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightpass_ps30.inc +++ /dev/null @@ -1,237 +0,0 @@ -#include "shaderlib/cshader.h" -class lightpass_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nBASETEXTURE2; -#ifdef _DEBUG - bool m_bBASETEXTURE2; -#endif -public: - void SetBASETEXTURE2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2 = i; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } - void SetBASETEXTURE2( bool i ) - { - m_nBASETEXTURE2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -private: - int m_nMODEL; -#ifdef _DEBUG - bool m_bMODEL; -#endif -public: - void SetMODEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMODEL = i; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } - void SetMODEL( bool i ) - { - m_nMODEL = i ? 1 : 0; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -public: - lightpass_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = false; -#endif // _DEBUG - m_nBASETEXTURE2 = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; -#ifdef _DEBUG - m_bMODEL = false; -#endif // _DEBUG - m_nMODEL = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP && m_bBASETEXTURE2 && m_bSEAMLESS && m_bDECAL && m_bMODEL && m_bSMOOTHNESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 3 * m_nCONVERT_TO_SRGB ) + ( 3 * m_nBUMPMAP ) + ( 6 * m_nBASETEXTURE2 ) + ( 12 * m_nSEAMLESS ) + ( 24 * m_nDECAL ) + ( 48 * m_nMODEL ) + ( 96 * m_nSMOOTHNESS ) + 0; - } -}; -#define shaderStaticTest_lightpass_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DECAL + psh_forgot_to_set_static_MODEL + psh_forgot_to_set_static_SMOOTHNESS + 0 -class lightpass_ps30_Dynamic_Index -{ -private: - int m_nPERF; -#ifdef _DEBUG - bool m_bPERF; -#endif -public: - void SetPERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nPERF = i; -#ifdef _DEBUG - m_bPERF = true; -#endif - } - void SetPERF( bool i ) - { - m_nPERF = i ? 1 : 0; -#ifdef _DEBUG - m_bPERF = true; -#endif - } -public: - lightpass_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bPERF = false; -#endif // _DEBUG - m_nPERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bPERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nPERF ) + 0; - } -}; -#define shaderDynamicTest_lightpass_ps30 psh_forgot_to_set_dynamic_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lightpass_vs30.inc b/materialsystem/stdshaders/fxctmp9/lightpass_vs30.inc deleted file mode 100644 index 1c427b97..00000000 --- a/materialsystem/stdshaders/fxctmp9/lightpass_vs30.inc +++ /dev/null @@ -1,262 +0,0 @@ -#include "shaderlib/cshader.h" -class lightpass_vs30_Static_Index -{ -private: - int m_nMODEL; -#ifdef _DEBUG - bool m_bMODEL; -#endif -public: - void SetMODEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMODEL = i; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } - void SetMODEL( bool i ) - { - m_nMODEL = i ? 1 : 0; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } -private: - int m_nTANGENTSPACE; -#ifdef _DEBUG - bool m_bTANGENTSPACE; -#endif -public: - void SetTANGENTSPACE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nTANGENTSPACE = i; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } - void SetTANGENTSPACE( bool i ) - { - m_nTANGENTSPACE = i ? 1 : 0; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } -private: - int m_nMORPHING_VTEX; -#ifdef _DEBUG - bool m_bMORPHING_VTEX; -#endif -public: - void SetMORPHING_VTEX( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING_VTEX = i; -#ifdef _DEBUG - m_bMORPHING_VTEX = true; -#endif - } - void SetMORPHING_VTEX( bool i ) - { - m_nMORPHING_VTEX = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING_VTEX = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -public: - lightpass_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bMODEL = false; -#endif // _DEBUG - m_nMODEL = 0; -#ifdef _DEBUG - m_bTANGENTSPACE = false; -#endif // _DEBUG - m_nTANGENTSPACE = 0; -#ifdef _DEBUG - m_bMORPHING_VTEX = false; -#endif // _DEBUG - m_nMORPHING_VTEX = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bMODEL && m_bTANGENTSPACE && m_bMORPHING_VTEX && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 8 * m_nMODEL ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nMORPHING_VTEX ) + ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 256 * m_nSEAMLESS ) + 0; - } -}; -#define shaderStaticTest_lightpass_vs30 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_MORPHING_VTEX + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + 0 -class lightpass_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - lightpass_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_lightpass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9/lpreview1_ps30.inc b/materialsystem/stdshaders/fxctmp9/lpreview1_ps30.inc deleted file mode 100644 index f7f22746..00000000 --- a/materialsystem/stdshaders/fxctmp9/lpreview1_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class lpreview1_ps30_Static_Index -{ -public: - lpreview1_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_lpreview1_ps30 0 -class lpreview1_ps30_Dynamic_Index -{ -public: - lpreview1_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_lpreview1_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/luma_ps30.inc b/materialsystem/stdshaders/fxctmp9/luma_ps30.inc deleted file mode 100644 index 1dc357f7..00000000 --- a/materialsystem/stdshaders/fxctmp9/luma_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class luma_ps30_Static_Index -{ -public: - luma_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_luma_ps30 0 -class luma_ps30_Dynamic_Index -{ -public: - luma_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_luma_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/normalmapreconstruct_ps30.inc b/materialsystem/stdshaders/fxctmp9/normalmapreconstruct_ps30.inc deleted file mode 100644 index fca2ed02..00000000 --- a/materialsystem/stdshaders/fxctmp9/normalmapreconstruct_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class normalmapreconstruct_ps30_Static_Index -{ -public: - normalmapreconstruct_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_normalmapreconstruct_ps30 0 -class normalmapreconstruct_ps30_Dynamic_Index -{ -public: - normalmapreconstruct_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_normalmapreconstruct_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/passthru_vs30.inc b/materialsystem/stdshaders/fxctmp9/passthru_vs30.inc deleted file mode 100644 index e20c5253..00000000 --- a/materialsystem/stdshaders/fxctmp9/passthru_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class passthru_vs30_Static_Index -{ -public: - passthru_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_passthru_vs30 0 -class passthru_vs30_Dynamic_Index -{ -public: - passthru_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_passthru_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/screenspace_simple_vs30.inc b/materialsystem/stdshaders/fxctmp9/screenspace_simple_vs30.inc deleted file mode 100644 index 7da731a6..00000000 --- a/materialsystem/stdshaders/fxctmp9/screenspace_simple_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenspace_simple_vs30_Static_Index -{ -public: - screenspace_simple_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenspace_simple_vs30 0 -class screenspace_simple_vs30_Dynamic_Index -{ -public: - screenspace_simple_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenspace_simple_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/screenwater_ps30.inc b/materialsystem/stdshaders/fxctmp9/screenwater_ps30.inc deleted file mode 100644 index b688b0da..00000000 --- a/materialsystem/stdshaders/fxctmp9/screenwater_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenwater_ps30_Static_Index -{ -public: - screenwater_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenwater_ps30 0 -class screenwater_ps30_Dynamic_Index -{ -public: - screenwater_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenwater_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/screenwater_vs30.inc b/materialsystem/stdshaders/fxctmp9/screenwater_vs30.inc deleted file mode 100644 index ac3891b2..00000000 --- a/materialsystem/stdshaders/fxctmp9/screenwater_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenwater_vs30_Static_Index -{ -public: - screenwater_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenwater_vs30 0 -class screenwater_vs30_Dynamic_Index -{ -public: - screenwater_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenwater_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/skydome_ps30.inc b/materialsystem/stdshaders/fxctmp9/skydome_ps30.inc deleted file mode 100644 index 20619ba2..00000000 --- a/materialsystem/stdshaders/fxctmp9/skydome_ps30.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class skydome_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -public: - skydome_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCONVERT_TO_SRGB ) + 0; - } -}; -#define shaderStaticTest_skydome_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + 0 -class skydome_ps30_Dynamic_Index -{ -private: - int m_nRENDER_SKY; -#ifdef _DEBUG - bool m_bRENDER_SKY; -#endif -public: - void SetRENDER_SKY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nRENDER_SKY = i; -#ifdef _DEBUG - m_bRENDER_SKY = true; -#endif - } - void SetRENDER_SKY( bool i ) - { - m_nRENDER_SKY = i ? 1 : 0; -#ifdef _DEBUG - m_bRENDER_SKY = true; -#endif - } -public: - skydome_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bRENDER_SKY = false; -#endif // _DEBUG - m_nRENDER_SKY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bRENDER_SKY; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nRENDER_SKY ) + 0; - } -}; -#define shaderDynamicTest_skydome_ps30 psh_forgot_to_set_dynamic_RENDER_SKY + 0 diff --git a/materialsystem/stdshaders/fxctmp9/skydome_vs30.inc b/materialsystem/stdshaders/fxctmp9/skydome_vs30.inc deleted file mode 100644 index f9ac5381..00000000 --- a/materialsystem/stdshaders/fxctmp9/skydome_vs30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class skydome_vs30_Static_Index -{ -public: - skydome_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_skydome_vs30 0 -class skydome_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -public: - skydome_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + 0; - } -}; -#define shaderDynamicTest_skydome_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9/ssgi_combine_ps30.inc b/materialsystem/stdshaders/fxctmp9/ssgi_combine_ps30.inc deleted file mode 100644 index 76f1ca76..00000000 --- a/materialsystem/stdshaders/fxctmp9/ssgi_combine_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssgi_combine_ps30_Static_Index -{ -public: - ssgi_combine_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssgi_combine_ps30 0 -class ssgi_combine_ps30_Dynamic_Index -{ -public: - ssgi_combine_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssgi_combine_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/ssgi_ps30.inc b/materialsystem/stdshaders/fxctmp9/ssgi_ps30.inc deleted file mode 100644 index 558e5d4a..00000000 --- a/materialsystem/stdshaders/fxctmp9/ssgi_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssgi_ps30_Static_Index -{ -public: - ssgi_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssgi_ps30 0 -class ssgi_ps30_Dynamic_Index -{ -public: - ssgi_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssgi_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/ssr_ps30.inc b/materialsystem/stdshaders/fxctmp9/ssr_ps30.inc deleted file mode 100644 index 2fe5d76b..00000000 --- a/materialsystem/stdshaders/fxctmp9/ssr_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssr_ps30_Static_Index -{ -public: - ssr_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssr_ps30 0 -class ssr_ps30_Dynamic_Index -{ -public: - ssr_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssr_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/unsharp_blur_ps30.inc b/materialsystem/stdshaders/fxctmp9/unsharp_blur_ps30.inc deleted file mode 100644 index 54032c52..00000000 --- a/materialsystem/stdshaders/fxctmp9/unsharp_blur_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_blur_ps30_Static_Index -{ -public: - unsharp_blur_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_blur_ps30 0 -class unsharp_blur_ps30_Dynamic_Index -{ -public: - unsharp_blur_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_blur_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/unsharp_blur_vs30.inc b/materialsystem/stdshaders/fxctmp9/unsharp_blur_vs30.inc deleted file mode 100644 index 53906a96..00000000 --- a/materialsystem/stdshaders/fxctmp9/unsharp_blur_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_blur_vs30_Static_Index -{ -public: - unsharp_blur_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_blur_vs30 0 -class unsharp_blur_vs30_Dynamic_Index -{ -public: - unsharp_blur_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_blur_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/unsharp_ps30.inc b/materialsystem/stdshaders/fxctmp9/unsharp_ps30.inc deleted file mode 100644 index 03f9fcf9..00000000 --- a/materialsystem/stdshaders/fxctmp9/unsharp_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_ps30_Static_Index -{ -public: - unsharp_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_ps30 0 -class unsharp_ps30_Dynamic_Index -{ -public: - unsharp_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/unsharp_vs30.inc b/materialsystem/stdshaders/fxctmp9/unsharp_vs30.inc deleted file mode 100644 index 9c1b1a84..00000000 --- a/materialsystem/stdshaders/fxctmp9/unsharp_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_vs30_Static_Index -{ -public: - unsharp_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_vs30 0 -class unsharp_vs30_Dynamic_Index -{ -public: - unsharp_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9/vance_bloom_combine_ps30.inc b/materialsystem/stdshaders/fxctmp9/vance_bloom_combine_ps30.inc deleted file mode 100644 index 335e0801..00000000 --- a/materialsystem/stdshaders/fxctmp9/vance_bloom_combine_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_bloom_combine_ps30_Static_Index -{ -public: - vance_bloom_combine_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_bloom_combine_ps30 0 -class vance_bloom_combine_ps30_Dynamic_Index -{ -public: - vance_bloom_combine_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_vance_bloom_combine_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/vance_scope_ps30.inc b/materialsystem/stdshaders/fxctmp9/vance_scope_ps30.inc deleted file mode 100644 index 40087e9a..00000000 --- a/materialsystem/stdshaders/fxctmp9/vance_scope_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_scope_ps30_Static_Index -{ -public: - vance_scope_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_scope_ps30 0 -class vance_scope_ps30_Dynamic_Index -{ -public: - vance_scope_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_vance_scope_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9/vance_scope_vs30.inc b/materialsystem/stdshaders/fxctmp9/vance_scope_vs30.inc deleted file mode 100644 index 978cf31c..00000000 --- a/materialsystem/stdshaders/fxctmp9/vance_scope_vs30.inc +++ /dev/null @@ -1,85 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_scope_vs30_Static_Index -{ -public: - vance_scope_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_scope_vs30 0 -class vance_scope_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -public: - vance_scope_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; - } -}; -#define shaderDynamicTest_vance_scope_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshaders/fxctmp9/vertexLit_and_unlit_Generic_vs30.inc b/materialsystem/stdshaders/fxctmp9/vertexLit_and_unlit_Generic_vs30.inc deleted file mode 100644 index 7473d292..00000000 --- a/materialsystem/stdshaders/fxctmp9/vertexLit_and_unlit_Generic_vs30.inc +++ /dev/null @@ -1,462 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_vs30_Static_Index -{ -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nSEAMLESS_BASE; -#ifdef _DEBUG - bool m_bSEAMLESS_BASE; -#endif -public: - void SetSEAMLESS_BASE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_BASE = i; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } - void SetSEAMLESS_BASE( bool i ) - { - m_nSEAMLESS_BASE = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } -private: - int m_nSEAMLESS_DETAIL; -#ifdef _DEBUG - bool m_bSEAMLESS_DETAIL; -#endif -public: - void SetSEAMLESS_DETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_DETAIL = i; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } - void SetSEAMLESS_DETAIL( bool i ) - { - m_nSEAMLESS_DETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } -private: - int m_nSEPARATE_DETAIL_UVS; -#ifdef _DEBUG - bool m_bSEPARATE_DETAIL_UVS; -#endif -public: - void SetSEPARATE_DETAIL_UVS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEPARATE_DETAIL_UVS = i; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = true; -#endif - } - void SetSEPARATE_DETAIL_UVS( bool i ) - { - m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -private: - int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; -#ifdef _DEBUG - bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; -#endif -public: - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) - { - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } -public: - vertexlit_and_unlit_generic_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = false; -#endif // _DEBUG - m_nSEAMLESS_BASE = 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = false; -#endif // _DEBUG - m_nSEAMLESS_DETAIL = 0; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = false; -#endif // _DEBUG - m_nSEPARATE_DETAIL_UVS = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; -#endif // _DEBUG - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bDECAL && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 256 * m_nVERTEXCOLOR ) + ( 512 * m_nCUBEMAP ) + ( 1024 * m_nHALFLAMBERT ) + ( 2048 * m_nFLASHLIGHT ) + ( 4096 * m_nSEAMLESS_BASE ) + ( 8192 * m_nSEAMLESS_DETAIL ) + ( 16384 * m_nSEPARATE_DETAIL_UVS ) + ( 32768 * m_nDECAL ) + ( 65536 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + 0 -class vertexlit_and_unlit_generic_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDYNAMIC_LIGHT; -#ifdef _DEBUG - bool m_bDYNAMIC_LIGHT; -#endif -public: - void SetDYNAMIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDYNAMIC_LIGHT = i; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } - void SetDYNAMIC_LIGHT( bool i ) - { - m_nDYNAMIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } -private: - int m_nSTATIC_LIGHT_VERTEX; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_VERTEX; -#endif -public: - void SetSTATIC_LIGHT_VERTEX( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_VERTEX = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = true; -#endif - } - void SetSTATIC_LIGHT_VERTEX( bool i ) - { - m_nSTATIC_LIGHT_VERTEX = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = true; -#endif - } -private: - int m_nSTATIC_LIGHT_LIGHTMAP; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_LIGHTMAP; -#endif -public: - void SetSTATIC_LIGHT_LIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_LIGHTMAP = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } - void SetSTATIC_LIGHT_LIGHTMAP( bool i ) - { - m_nSTATIC_LIGHT_LIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - vertexlit_and_unlit_generic_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = false; -#endif // _DEBUG - m_nDYNAMIC_LIGHT = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_VERTEX = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_LIGHTMAP = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT_VERTEX && m_bSTATIC_LIGHT_LIGHTMAP && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT_VERTEX ) + ( 8 * m_nSTATIC_LIGHT_LIGHTMAP ) + ( 16 * m_nDOWATERFOG ) + ( 32 * m_nSKINNING ) + ( 64 * m_nLIGHTING_PREVIEW ) + ( 128 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT_VERTEX + vsh_forgot_to_set_dynamic_STATIC_LIGHT_LIGHTMAP + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9/vertexlitPBR_vs30.inc b/materialsystem/stdshaders/fxctmp9/vertexlitPBR_vs30.inc deleted file mode 100644 index f73364a0..00000000 --- a/materialsystem/stdshaders/fxctmp9/vertexlitPBR_vs30.inc +++ /dev/null @@ -1,287 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlitpbr_vs30_Static_Index -{ -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; -#ifdef _DEBUG - bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; -#endif -public: - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) - { - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } -public: - vertexlitpbr_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; -#endif // _DEBUG - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 320 * m_nVERTEXCOLOR ) + ( 640 * m_nCUBEMAP ) + ( 1280 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + 0; - } -}; -#define shaderStaticTest_vertexlitpbr_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + 0 -class vertexlitpbr_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nDYNAMIC_LIGHT; -#ifdef _DEBUG - bool m_bDYNAMIC_LIGHT; -#endif -public: - void SetDYNAMIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDYNAMIC_LIGHT = i; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } - void SetDYNAMIC_LIGHT( bool i ) - { - m_nDYNAMIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } -private: - int m_nSTATIC_LIGHT; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT; -#endif -public: - void SetSTATIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT = true; -#endif - } - void SetSTATIC_LIGHT( bool i ) - { - m_nSTATIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT = true; -#endif - } -public: - vertexlitpbr_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = false; -#endif // _DEBUG - m_nDYNAMIC_LIGHT = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT = false; -#endif // _DEBUG - m_nSTATIC_LIGHT = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + ( 80 * m_nDYNAMIC_LIGHT ) + ( 160 * m_nSTATIC_LIGHT ) + 0; - } -}; -#define shaderDynamicTest_vertexlitpbr_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + 0 diff --git a/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_bump_ps30.inc b/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_bump_ps30.inc deleted file mode 100644 index 47ee38e9..00000000 --- a/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_bump_ps30.inc +++ /dev/null @@ -1,412 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_bump_ps30_Static_Index -{ -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDIFFUSELIGHTING; -#ifdef _DEBUG - bool m_bDIFFUSELIGHTING; -#endif -public: - void SetDIFFUSELIGHTING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSELIGHTING = i; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } - void SetDIFFUSELIGHTING( bool i ) - { - m_nDIFFUSELIGHTING = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } -private: - int m_nLIGHTWARPTEXTURE; -#ifdef _DEBUG - bool m_bLIGHTWARPTEXTURE; -#endif -public: - void SetLIGHTWARPTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTWARPTEXTURE = i; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = true; -#endif - } - void SetLIGHTWARPTEXTURE( bool i ) - { - m_nLIGHTWARPTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nSELFILLUMFRESNEL; -#ifdef _DEBUG - bool m_bSELFILLUMFRESNEL; -#endif -public: - void SetSELFILLUMFRESNEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUMFRESNEL = i; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = true; -#endif - } - void SetSELFILLUMFRESNEL( bool i ) - { - m_nSELFILLUMFRESNEL = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = true; -#endif - } -private: - int m_nNORMALMAPALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bNORMALMAPALPHAENVMAPMASK; -#endif -public: - void SetNORMALMAPALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAPALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } - void SetNORMALMAPALPHAENVMAPMASK( bool i ) - { - m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 6 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -private: - int m_nBLENDTINTBYBASEALPHA; -#ifdef _DEBUG - bool m_bBLENDTINTBYBASEALPHA; -#endif -public: - void SetBLENDTINTBYBASEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBLENDTINTBYBASEALPHA = i; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } - void SetBLENDTINTBYBASEALPHA( bool i ) - { - m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = false; -#endif // _DEBUG - m_nDIFFUSELIGHTING = 0; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = false; -#endif // _DEBUG - m_nLIGHTWARPTEXTURE = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = false; -#endif // _DEBUG - m_nSELFILLUMFRESNEL = 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nNORMALMAPALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = false; -#endif // _DEBUG - m_nBLENDTINTBYBASEALPHA = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + 0 -class vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index -{ -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nAMBIENT_LIGHT; -#ifdef _DEBUG - bool m_bAMBIENT_LIGHT; -#endif -public: - void SetAMBIENT_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nAMBIENT_LIGHT = i; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = true; -#endif - } - void SetAMBIENT_LIGHT( bool i ) - { - m_nAMBIENT_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = false; -#endif // _DEBUG - m_nAMBIENT_LIGHT = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_ps30.inc b/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_ps30.inc deleted file mode 100644 index ce1c6f91..00000000 --- a/materialsystem/stdshaders/fxctmp9/vertexlit_and_unlit_generic_ps30.inc +++ /dev/null @@ -1,662 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_ps30_Static_Index -{ -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDIFFUSELIGHTING; -#ifdef _DEBUG - bool m_bDIFFUSELIGHTING; -#endif -public: - void SetDIFFUSELIGHTING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSELIGHTING = i; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } - void SetDIFFUSELIGHTING( bool i ) - { - m_nDIFFUSELIGHTING = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } -private: - int m_nENVMAPMASK; -#ifdef _DEBUG - bool m_bENVMAPMASK; -#endif -public: - void SetENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAPMASK = i; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } - void SetENVMAPMASK( bool i ) - { - m_nENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } -private: - int m_nBASEALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bBASEALPHAENVMAPMASK; -#endif -public: - void SetBASEALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASEALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } - void SetBASEALPHAENVMAPMASK( bool i ) - { - m_nBASEALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nSELFILLUM_ENVMAPMASK_ALPHA; -#ifdef _DEBUG - bool m_bSELFILLUM_ENVMAPMASK_ALPHA; -#endif -public: - void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM_ENVMAPMASK_ALPHA = i; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = true; -#endif - } - void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) - { - m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 9 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nSEAMLESS_BASE; -#ifdef _DEBUG - bool m_bSEAMLESS_BASE; -#endif -public: - void SetSEAMLESS_BASE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_BASE = i; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } - void SetSEAMLESS_BASE( bool i ) - { - m_nSEAMLESS_BASE = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } -private: - int m_nSEAMLESS_DETAIL; -#ifdef _DEBUG - bool m_bSEAMLESS_DETAIL; -#endif -public: - void SetSEAMLESS_DETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_DETAIL = i; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } - void SetSEAMLESS_DETAIL( bool i ) - { - m_nSEAMLESS_DETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } -private: - int m_nDISTANCEALPHA; -#ifdef _DEBUG - bool m_bDISTANCEALPHA; -#endif -public: - void SetDISTANCEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDISTANCEALPHA = i; -#ifdef _DEBUG - m_bDISTANCEALPHA = true; -#endif - } - void SetDISTANCEALPHA( bool i ) - { - m_nDISTANCEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bDISTANCEALPHA = true; -#endif - } -private: - int m_nDISTANCEALPHAFROMDETAIL; -#ifdef _DEBUG - bool m_bDISTANCEALPHAFROMDETAIL; -#endif -public: - void SetDISTANCEALPHAFROMDETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDISTANCEALPHAFROMDETAIL = i; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = true; -#endif - } - void SetDISTANCEALPHAFROMDETAIL( bool i ) - { - m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = true; -#endif - } -private: - int m_nSOFT_MASK; -#ifdef _DEBUG - bool m_bSOFT_MASK; -#endif -public: - void SetSOFT_MASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSOFT_MASK = i; -#ifdef _DEBUG - m_bSOFT_MASK = true; -#endif - } - void SetSOFT_MASK( bool i ) - { - m_nSOFT_MASK = i ? 1 : 0; -#ifdef _DEBUG - m_bSOFT_MASK = true; -#endif - } -private: - int m_nOUTLINE; -#ifdef _DEBUG - bool m_bOUTLINE; -#endif -public: - void SetOUTLINE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nOUTLINE = i; -#ifdef _DEBUG - m_bOUTLINE = true; -#endif - } - void SetOUTLINE( bool i ) - { - m_nOUTLINE = i ? 1 : 0; -#ifdef _DEBUG - m_bOUTLINE = true; -#endif - } -private: - int m_nOUTER_GLOW; -#ifdef _DEBUG - bool m_bOUTER_GLOW; -#endif -public: - void SetOUTER_GLOW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nOUTER_GLOW = i; -#ifdef _DEBUG - m_bOUTER_GLOW = true; -#endif - } - void SetOUTER_GLOW( bool i ) - { - m_nOUTER_GLOW = i ? 1 : 0; -#ifdef _DEBUG - m_bOUTER_GLOW = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -private: - int m_nDEPTHBLEND; -#ifdef _DEBUG - bool m_bDEPTHBLEND; -#endif -public: - void SetDEPTHBLEND( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDEPTHBLEND = i; -#ifdef _DEBUG - m_bDEPTHBLEND = true; -#endif - } - void SetDEPTHBLEND( bool i ) - { - m_nDEPTHBLEND = i ? 1 : 0; -#ifdef _DEBUG - m_bDEPTHBLEND = true; -#endif - } -private: - int m_nBLENDTINTBYBASEALPHA; -#ifdef _DEBUG - bool m_bBLENDTINTBYBASEALPHA; -#endif -public: - void SetBLENDTINTBYBASEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBLENDTINTBYBASEALPHA = i; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } - void SetBLENDTINTBYBASEALPHA( bool i ) - { - m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -public: - vertexlit_and_unlit_generic_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = false; -#endif // _DEBUG - m_nDIFFUSELIGHTING = 0; -#ifdef _DEBUG - m_bENVMAPMASK = false; -#endif // _DEBUG - m_nENVMAPMASK = 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nBASEALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = false; -#endif // _DEBUG - m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = false; -#endif // _DEBUG - m_nSEAMLESS_BASE = 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = false; -#endif // _DEBUG - m_nSEAMLESS_DETAIL = 0; -#ifdef _DEBUG - m_bDISTANCEALPHA = false; -#endif // _DEBUG - m_nDISTANCEALPHA = 0; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = false; -#endif // _DEBUG - m_nDISTANCEALPHAFROMDETAIL = 0; -#ifdef _DEBUG - m_bSOFT_MASK = false; -#endif // _DEBUG - m_nSOFT_MASK = 0; -#ifdef _DEBUG - m_bOUTLINE = false; -#endif // _DEBUG - m_nOUTLINE = 0; -#ifdef _DEBUG - m_bOUTER_GLOW = false; -#endif // _DEBUG - m_nOUTER_GLOW = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; -#ifdef _DEBUG - m_bDEPTHBLEND = false; -#endif // _DEBUG - m_nDEPTHBLEND = 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = false; -#endif // _DEBUG - m_nBLENDTINTBYBASEALPHA = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 24 * m_nDETAILTEXTURE ) + ( 48 * m_nCUBEMAP ) + ( 96 * m_nDIFFUSELIGHTING ) + ( 192 * m_nENVMAPMASK ) + ( 384 * m_nBASEALPHAENVMAPMASK ) + ( 768 * m_nSELFILLUM ) + ( 1536 * m_nVERTEXCOLOR ) + ( 3072 * m_nFLASHLIGHT ) + ( 6144 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 12288 * m_nDETAIL_BLEND_MODE ) + ( 122880 * m_nSEAMLESS_BASE ) + ( 245760 * m_nSEAMLESS_DETAIL ) + ( 491520 * m_nDISTANCEALPHA ) + ( 983040 * m_nDISTANCEALPHAFROMDETAIL ) + ( 1966080 * m_nSOFT_MASK ) + ( 3932160 * m_nOUTLINE ) + ( 7864320 * m_nOUTER_GLOW ) + ( 15728640 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 47185920 * m_nDEPTHBLEND ) + ( 94371840 * m_nBLENDTINTBYBASEALPHA ) + ( 188743680 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 -class vertexlit_and_unlit_generic_ps30_Dynamic_Index -{ -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nSTATIC_LIGHT_LIGHTMAP; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_LIGHTMAP; -#endif -public: - void SetSTATIC_LIGHT_LIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_LIGHTMAP = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } - void SetSTATIC_LIGHT_LIGHTMAP( bool i ) - { - m_nSTATIC_LIGHT_LIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } -private: - int m_nDEBUG_LUXELS; -#ifdef _DEBUG - bool m_bDEBUG_LUXELS; -#endif -public: - void SetDEBUG_LUXELS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDEBUG_LUXELS = i; -#ifdef _DEBUG - m_bDEBUG_LUXELS = true; -#endif - } - void SetDEBUG_LUXELS( bool i ) - { - m_nDEBUG_LUXELS = i ? 1 : 0; -#ifdef _DEBUG - m_bDEBUG_LUXELS = true; -#endif - } -public: - vertexlit_and_unlit_generic_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_LIGHTMAP = 0; -#ifdef _DEBUG - m_bDEBUG_LUXELS = false; -#endif // _DEBUG - m_nDEBUG_LUXELS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS && m_bSTATIC_LIGHT_LIGHTMAP && m_bDEBUG_LUXELS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + ( 6 * m_nSTATIC_LIGHT_LIGHTMAP ) + ( 12 * m_nDEBUG_LUXELS ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_STATIC_LIGHT_LIGHTMAP + psh_forgot_to_set_dynamic_DEBUG_LUXELS + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs30.inc deleted file mode 100644 index 01dcd1ca..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class sdk_screenspaceeffect_vs30_Static_Index -{ -private: - int m_nX360APPCHOOSER; -#ifdef _DEBUG - bool m_bX360APPCHOOSER; -#endif -public: - void SetX360APPCHOOSER( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nX360APPCHOOSER = i; -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif - } - void SetX360APPCHOOSER( bool i ) - { - m_nX360APPCHOOSER = i ? 1 : 0; -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif - } -public: - sdk_screenspaceeffect_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bX360APPCHOOSER = true; -#endif // _DEBUG - m_nX360APPCHOOSER = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bX360APPCHOOSER; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nX360APPCHOOSER ) + 0; - } -}; -#define shaderStaticTest_sdk_screenspaceeffect_vs30 0 -class sdk_screenspaceeffect_vs30_Dynamic_Index -{ -public: - sdk_screenspaceeffect_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_sdk_screenspaceeffect_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/Vance_Tonemap_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/Vance_Tonemap_ps30.inc deleted file mode 100644 index b49a8f68..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/Vance_Tonemap_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_tonemap_ps30_Static_Index -{ -public: - vance_tonemap_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_tonemap_ps30 0 -class vance_tonemap_ps30_Dynamic_Index -{ -private: - int m_nMODE; -#ifdef _DEBUG - bool m_bMODE; -#endif -public: - void SetMODE( int i ) - { - Assert( i >= 0 && i <= 3 ); - m_nMODE = i; -#ifdef _DEBUG - m_bMODE = true; -#endif - } - void SetMODE( bool i ) - { - m_nMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bMODE = true; -#endif - } -public: - vance_tonemap_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bMODE = false; -#endif // _DEBUG - m_nMODE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bMODE; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nMODE ) + 0; - } -}; -#define shaderDynamicTest_vance_tonemap_ps30 psh_forgot_to_set_dynamic_MODE + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/VertexLit_and_unlit_Generic_bump_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/VertexLit_and_unlit_Generic_bump_vs30.inc deleted file mode 100644 index b4231fc2..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/VertexLit_and_unlit_Generic_bump_vs30.inc +++ /dev/null @@ -1,212 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_bump_vs30_Static_Index -{ -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nUSE_WITH_2B; -#ifdef _DEBUG - bool m_bUSE_WITH_2B; -#endif -public: - void SetUSE_WITH_2B( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nUSE_WITH_2B = i; -#ifdef _DEBUG - m_bUSE_WITH_2B = true; -#endif - } - void SetUSE_WITH_2B( bool i ) - { - m_nUSE_WITH_2B = i ? 1 : 0; -#ifdef _DEBUG - m_bUSE_WITH_2B = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bUSE_WITH_2B = false; -#endif // _DEBUG - m_nUSE_WITH_2B = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bDECAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 16 * m_nHALFLAMBERT ) + ( 32 * m_nUSE_WITH_2B ) + ( 64 * m_nDECAL ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_DECAL + 0 -class vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/VertexlitPBR_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/VertexlitPBR_ps30.inc deleted file mode 100644 index ff589ffd..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/VertexlitPBR_ps30.inc +++ /dev/null @@ -1,387 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlitpbr_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -public: - vertexlitpbr_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2880 * m_nCONVERT_TO_SRGB ) + ( 2880 * m_nFLASHLIGHT ) + ( 5760 * m_nCUBEMAP ) + ( 11520 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 23040 * m_nSMOOTHNESS ) + 0; - } -}; -#define shaderStaticTest_vertexlitpbr_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + 0 -class vertexlitpbr_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nLIGHTMAP; -#ifdef _DEBUG - bool m_bLIGHTMAP; -#endif -public: - void SetLIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTMAP = i; -#ifdef _DEBUG - m_bLIGHTMAP = true; -#endif - } - void SetLIGHTMAP( bool i ) - { - m_nLIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTMAP = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -private: - int m_nLIGHT_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHT_PREVIEW; -#endif -public: - void SetLIGHT_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHT_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } - void SetLIGHT_PREVIEW( bool i ) - { - m_nLIGHT_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } -public: - vertexlitpbr_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bLIGHTMAP = false; -#endif // _DEBUG - m_nLIGHTMAP = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = false; -#endif // _DEBUG - m_nLIGHT_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bLIGHTMAP && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + ( 80 * m_nLIGHTMAP ) + ( 160 * m_nCSM ) + ( 320 * m_nCSM_PERF ) + ( 960 * m_nLIGHT_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_vertexlitpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_LIGHTMAP + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/chromatic_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/chromatic_ps30.inc deleted file mode 100644 index 56c0babc..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/chromatic_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class chromatic_ps30_Static_Index -{ -public: - chromatic_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_chromatic_ps30 0 -class chromatic_ps30_Dynamic_Index -{ -private: - int m_nRADIAL; -#ifdef _DEBUG - bool m_bRADIAL; -#endif -public: - void SetRADIAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nRADIAL = i; -#ifdef _DEBUG - m_bRADIAL = true; -#endif - } - void SetRADIAL( bool i ) - { - m_nRADIAL = i ? 1 : 0; -#ifdef _DEBUG - m_bRADIAL = true; -#endif - } -public: - chromatic_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bRADIAL = false; -#endif // _DEBUG - m_nRADIAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bRADIAL; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nRADIAL ) + 0; - } -}; -#define shaderDynamicTest_chromatic_ps30 psh_forgot_to_set_dynamic_RADIAL + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/chromatic_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/chromatic_vs30.inc deleted file mode 100644 index 99899863..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/chromatic_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class chromatic_vs30_Static_Index -{ -public: - chromatic_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_chromatic_vs30 0 -class chromatic_vs30_Dynamic_Index -{ -public: - chromatic_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_chromatic_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20.inc b/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20.inc deleted file mode 100644 index d9be0712..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps20_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps20_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps20 psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps20_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps20_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps20 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20b.inc b/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20b.inc deleted file mode 100644 index a3d0bf44..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps20b.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps20b_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps20b_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps20b psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps20b_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps20b_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps20b psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps30.inc deleted file mode 100644 index af6d03c2..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_ps30.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_ps30_Static_Index -{ -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_ps30 psh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_ps30_Dynamic_Index -{ -private: - int m_nALPHACLIP; -#ifdef _DEBUG - bool m_bALPHACLIP; -#endif -public: - void SetALPHACLIP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nALPHACLIP = i; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } - void SetALPHACLIP( bool i ) - { - m_nALPHACLIP = i ? 1 : 0; -#ifdef _DEBUG - m_bALPHACLIP = true; -#endif - } -public: - depthwrite_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bALPHACLIP = false; -#endif // _DEBUG - m_nALPHACLIP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bALPHACLIP; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nALPHACLIP ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_ps30 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_vs20.inc b/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_vs20.inc deleted file mode 100644 index 7b94dc52..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/depthwrite_vs20.inc +++ /dev/null @@ -1,137 +0,0 @@ -#include "shaderlib/cshader.h" -class depthwrite_vs20_Static_Index -{ -private: - int m_nONLY_PROJECT_POSITION; -#ifdef _DEBUG - bool m_bONLY_PROJECT_POSITION; -#endif -public: - void SetONLY_PROJECT_POSITION( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nONLY_PROJECT_POSITION = i; -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = true; -#endif - } - void SetONLY_PROJECT_POSITION( bool i ) - { - m_nONLY_PROJECT_POSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = true; -#endif - } -private: - int m_nCOLOR_DEPTH; -#ifdef _DEBUG - bool m_bCOLOR_DEPTH; -#endif -public: - void SetCOLOR_DEPTH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOLOR_DEPTH = i; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } - void SetCOLOR_DEPTH( bool i ) - { - m_nCOLOR_DEPTH = i ? 1 : 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = true; -#endif - } -public: - depthwrite_vs20_Static_Index( ) - { -#ifdef _DEBUG - m_bONLY_PROJECT_POSITION = false; -#endif // _DEBUG - m_nONLY_PROJECT_POSITION = 0; -#ifdef _DEBUG - m_bCOLOR_DEPTH = false; -#endif // _DEBUG - m_nCOLOR_DEPTH = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nONLY_PROJECT_POSITION ) + ( 4 * m_nCOLOR_DEPTH ) + 0; - } -}; -#define shaderStaticTest_depthwrite_vs20 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + 0 -class depthwrite_vs20_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -public: - depthwrite_vs20_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; - } -}; -#define shaderDynamicTest_depthwrite_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps30.inc deleted file mode 100644 index 836cb618..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps30.inc +++ /dev/null @@ -1,162 +0,0 @@ -#include "shaderlib/cshader.h" -class example_model_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -public: - example_model_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 20 * m_nCONVERT_TO_SRGB ) + ( 20 * m_nFLASHLIGHT ) + 0; - } -}; -#define shaderStaticTest_example_model_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + 0 -class example_model_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -public: - example_model_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + 0; - } -}; -#define shaderDynamicTest_example_model_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs30.inc deleted file mode 100644 index 88082217..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs30.inc +++ /dev/null @@ -1,160 +0,0 @@ -#include "shaderlib/cshader.h" -class example_model_vs30_Static_Index -{ -public: - example_model_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_example_model_vs30 0 -class example_model_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -public: - example_model_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0; - } -}; -#define shaderDynamicTest_example_model_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/flashlight_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/flashlight_ps30.inc deleted file mode 100644 index 6e292b46..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/flashlight_ps30.inc +++ /dev/null @@ -1,262 +0,0 @@ -#include "shaderlib/cshader.h" -class flashlight_ps30_Static_Index -{ -private: - int m_nNORMALMAP; -#ifdef _DEBUG - bool m_bNORMALMAP; -#endif -public: - void SetNORMALMAP( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nNORMALMAP = i; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } - void SetNORMALMAP( bool i ) - { - m_nNORMALMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } -private: - int m_nNORMALMAP2; -#ifdef _DEBUG - bool m_bNORMALMAP2; -#endif -public: - void SetNORMALMAP2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAP2 = i; -#ifdef _DEBUG - m_bNORMALMAP2 = true; -#endif - } - void SetNORMALMAP2( bool i ) - { - m_nNORMALMAP2 = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP2 = true; -#endif - } -private: - int m_nWORLDVERTEXTRANSITION; -#ifdef _DEBUG - bool m_bWORLDVERTEXTRANSITION; -#endif -public: - void SetWORLDVERTEXTRANSITION( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWORLDVERTEXTRANSITION = i; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } - void SetWORLDVERTEXTRANSITION( bool i ) - { - m_nWORLDVERTEXTRANSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -public: - flashlight_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bNORMALMAP = false; -#endif // _DEBUG - m_nNORMALMAP = 0; -#ifdef _DEBUG - m_bNORMALMAP2 = false; -#endif // _DEBUG - m_nNORMALMAP2 = 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = false; -#endif // _DEBUG - m_nWORLDVERTEXTRANSITION = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; - } -}; -#define shaderStaticTest_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 -class flashlight_ps30_Dynamic_Index -{ -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -public: - flashlight_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFLASHLIGHTSHADOWS && m_bPIXELFOGTYPE; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFLASHLIGHTSHADOWS ) + ( 2 * m_nPIXELFOGTYPE ) + 0; - } -}; -#define shaderDynamicTest_flashlight_ps30 psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/fxaa_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/fxaa_ps30.inc deleted file mode 100644 index 4892cac8..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/fxaa_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class fxaa_ps30_Static_Index -{ -public: - fxaa_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_fxaa_ps30 0 -class fxaa_ps30_Dynamic_Index -{ -private: - int m_nQUALITY; -#ifdef _DEBUG - bool m_bQUALITY; -#endif -public: - void SetQUALITY( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nQUALITY = i; -#ifdef _DEBUG - m_bQUALITY = true; -#endif - } - void SetQUALITY( bool i ) - { - m_nQUALITY = i ? 1 : 0; -#ifdef _DEBUG - m_bQUALITY = true; -#endif - } -public: - fxaa_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bQUALITY = false; -#endif // _DEBUG - m_nQUALITY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bQUALITY; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nQUALITY ) + 0; - } -}; -#define shaderDynamicTest_fxaa_ps30 psh_forgot_to_set_dynamic_QUALITY + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/fxaa_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/fxaa_vs30.inc deleted file mode 100644 index a2b01587..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/fxaa_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class fxaa_vs30_Static_Index -{ -public: - fxaa_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_fxaa_vs30 0 -class fxaa_vs30_Dynamic_Index -{ -public: - fxaa_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_fxaa_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_ps30.inc deleted file mode 100644 index 0bc22fc3..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussian_depthaware_ps30_Static_Index -{ -private: - int m_nHORIZONTAL; -#ifdef _DEBUG - bool m_bHORIZONTAL; -#endif -public: - void SetHORIZONTAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHORIZONTAL = i; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } - void SetHORIZONTAL( bool i ) - { - m_nHORIZONTAL = i ? 1 : 0; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } -public: - gaussian_depthaware_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bHORIZONTAL = false; -#endif // _DEBUG - m_nHORIZONTAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHORIZONTAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nHORIZONTAL ) + 0; - } -}; -#define shaderStaticTest_gaussian_depthaware_ps30 psh_forgot_to_set_static_HORIZONTAL + 0 -class gaussian_depthaware_ps30_Dynamic_Index -{ -public: - gaussian_depthaware_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussian_depthaware_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_roughness_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_roughness_ps30.inc deleted file mode 100644 index 5b271793..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/gaussian_depthaware_roughness_ps30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussian_depthaware_roughness_ps30_Static_Index -{ -private: - int m_nHORIZONTAL; -#ifdef _DEBUG - bool m_bHORIZONTAL; -#endif -public: - void SetHORIZONTAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHORIZONTAL = i; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } - void SetHORIZONTAL( bool i ) - { - m_nHORIZONTAL = i ? 1 : 0; -#ifdef _DEBUG - m_bHORIZONTAL = true; -#endif - } -public: - gaussian_depthaware_roughness_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bHORIZONTAL = false; -#endif // _DEBUG - m_nHORIZONTAL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bHORIZONTAL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nHORIZONTAL ) + 0; - } -}; -#define shaderStaticTest_gaussian_depthaware_roughness_ps30 psh_forgot_to_set_static_HORIZONTAL + 0 -class gaussian_depthaware_roughness_ps30_Dynamic_Index -{ -public: - gaussian_depthaware_roughness_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussian_depthaware_roughness_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/gaussianx_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/gaussianx_ps30.inc deleted file mode 100644 index d5580527..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/gaussianx_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussianx_ps30_Static_Index -{ -public: - gaussianx_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_gaussianx_ps30 0 -class gaussianx_ps30_Dynamic_Index -{ -public: - gaussianx_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussianx_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/gaussiany_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/gaussiany_ps30.inc deleted file mode 100644 index d643a3d9..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/gaussiany_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class gaussiany_ps30_Static_Index -{ -public: - gaussiany_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_gaussiany_ps30 0 -class gaussiany_ps30_Dynamic_Index -{ -public: - gaussiany_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_gaussiany_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_ps30.inc deleted file mode 100644 index 276a0a17..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_mesh_ps30_Static_Index -{ -public: - light_mesh_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_mesh_ps30 0 -class light_mesh_ps30_Dynamic_Index -{ -public: - light_mesh_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_mesh_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_vs30.inc deleted file mode 100644 index d6495464..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/light_mesh_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_mesh_vs30_Static_Index -{ -public: - light_mesh_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_mesh_vs30 0 -class light_mesh_vs30_Dynamic_Index -{ -public: - light_mesh_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_mesh_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_ps30.inc deleted file mode 100644 index fa567827..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_ps30.inc +++ /dev/null @@ -1,85 +0,0 @@ -#include "shaderlib/cshader.h" -class light_volumetrics_ps30_Static_Index -{ -public: - light_volumetrics_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_volumetrics_ps30 0 -class light_volumetrics_ps30_Dynamic_Index -{ -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nPERF; -#ifdef _DEBUG - bool m_bPERF; -#endif -public: - void SetPERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nPERF = i; -#ifdef _DEBUG - m_bPERF = true; -#endif - } - void SetPERF( bool i ) - { - m_nPERF = i ? 1 : 0; -#ifdef _DEBUG - m_bPERF = true; -#endif - } -public: - light_volumetrics_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bPERF = false; -#endif // _DEBUG - m_nPERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCSM && m_bPERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCSM ) + ( 2 * m_nPERF ) + 0; - } -}; -#define shaderDynamicTest_light_volumetrics_ps30 psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_vs30.inc deleted file mode 100644 index 50f1fbbd..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/light_volumetrics_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class light_volumetrics_vs30_Static_Index -{ -public: - light_volumetrics_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_light_volumetrics_vs30 0 -class light_volumetrics_vs30_Dynamic_Index -{ -public: - light_volumetrics_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_light_volumetrics_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_ps30.inc deleted file mode 100644 index 3a4de0b8..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_ps30.inc +++ /dev/null @@ -1,412 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedpbr_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -public: - lightmappedpbr_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS && m_bSEAMLESS && m_bBUMPMAP; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 576 * m_nCONVERT_TO_SRGB ) + ( 576 * m_nFLASHLIGHT ) + ( 1152 * m_nCUBEMAP ) + ( 2304 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 4608 * m_nSMOOTHNESS ) + ( 9216 * m_nSEAMLESS ) + ( 18432 * m_nBUMPMAP ) + 0; - } -}; -#define shaderStaticTest_lightmappedpbr_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMAP + 0 -class lightmappedpbr_ps30_Dynamic_Index -{ -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nCUBEMAPCORRECTED; -#ifdef _DEBUG - bool m_bCUBEMAPCORRECTED; -#endif -public: - void SetCUBEMAPCORRECTED( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAPCORRECTED = i; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } - void SetCUBEMAPCORRECTED( bool i ) - { - m_nCUBEMAPCORRECTED = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -private: - int m_nLIGHT_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHT_PREVIEW; -#endif -public: - void SetLIGHT_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHT_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } - void SetLIGHT_PREVIEW( bool i ) - { - m_nLIGHT_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = true; -#endif - } -public: - lightmappedpbr_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = false; -#endif // _DEBUG - m_nCUBEMAPCORRECTED = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; -#ifdef _DEBUG - m_bLIGHT_PREVIEW = false; -#endif // _DEBUG - m_nLIGHT_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bCUBEMAPCORRECTED && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + ( 16 * m_nCUBEMAPCORRECTED ) + ( 32 * m_nCSM ) + ( 64 * m_nCSM_PERF ) + ( 192 * m_nLIGHT_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_lightmappedpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_CUBEMAPCORRECTED + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_vs30.inc deleted file mode 100644 index d4e062ac..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedPBR_vs30.inc +++ /dev/null @@ -1,187 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedpbr_vs30_Static_Index -{ -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -public: - lightmappedpbr_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 4 * m_nBUMPMAP ) + ( 8 * m_nDIFFUSEBUMPMAP ) + ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nVERTEXALPHATEXBLENDFACTOR ) + 0; - } -}; -#define shaderStaticTest_lightmappedpbr_vs30 vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + 0 -class lightmappedpbr_vs30_Dynamic_Index -{ -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -public: - lightmappedpbr_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + 0; - } -}; -#define shaderDynamicTest_lightmappedpbr_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_flashlight_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_flashlight_vs30.inc deleted file mode 100644 index e6508779..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_flashlight_vs30.inc +++ /dev/null @@ -1,162 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_flashlight_vs30_Static_Index -{ -private: - int m_nNORMALMAP; -#ifdef _DEBUG - bool m_bNORMALMAP; -#endif -public: - void SetNORMALMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAP = i; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } - void SetNORMALMAP( bool i ) - { - m_nNORMALMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAP = true; -#endif - } -private: - int m_nWORLDVERTEXTRANSITION; -#ifdef _DEBUG - bool m_bWORLDVERTEXTRANSITION; -#endif -public: - void SetWORLDVERTEXTRANSITION( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWORLDVERTEXTRANSITION = i; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } - void SetWORLDVERTEXTRANSITION( bool i ) - { - m_nWORLDVERTEXTRANSITION = i ? 1 : 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDETAIL; -#ifdef _DEBUG - bool m_bDETAIL; -#endif -public: - void SetDETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAIL = i; -#ifdef _DEBUG - m_bDETAIL = true; -#endif - } - void SetDETAIL( bool i ) - { - m_nDETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL = true; -#endif - } -public: - lightmappedgeneric_flashlight_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bNORMALMAP = false; -#endif // _DEBUG - m_nNORMALMAP = 0; -#ifdef _DEBUG - m_bWORLDVERTEXTRANSITION = false; -#endif // _DEBUG - m_nWORLDVERTEXTRANSITION = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDETAIL = false; -#endif // _DEBUG - m_nDETAIL = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + 0 -class lightmappedgeneric_flashlight_vs30_Dynamic_Index -{ -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -public: - lightmappedgeneric_flashlight_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bDOWATERFOG; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nDOWATERFOG ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_ps30.inc deleted file mode 100644 index 8ed12670..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_ps30.inc +++ /dev/null @@ -1,662 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_ps30_Static_Index -{ -private: - int m_nMASKEDBLENDING; -#ifdef _DEBUG - bool m_bMASKEDBLENDING; -#endif -public: - void SetMASKEDBLENDING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMASKEDBLENDING = i; -#ifdef _DEBUG - m_bMASKEDBLENDING = true; -#endif - } - void SetMASKEDBLENDING( bool i ) - { - m_nMASKEDBLENDING = i ? 1 : 0; -#ifdef _DEBUG - m_bMASKEDBLENDING = true; -#endif - } -private: - int m_nBASETEXTURE2; -#ifdef _DEBUG - bool m_bBASETEXTURE2; -#endif -public: - void SetBASETEXTURE2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2 = i; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } - void SetBASETEXTURE2( bool i ) - { - m_nBASETEXTURE2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nBUMPMAP2; -#ifdef _DEBUG - bool m_bBUMPMAP2; -#endif -public: - void SetBUMPMAP2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP2 = i; -#ifdef _DEBUG - m_bBUMPMAP2 = true; -#endif - } - void SetBUMPMAP2( bool i ) - { - m_nBUMPMAP2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP2 = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nENVMAPMASK; -#ifdef _DEBUG - bool m_bENVMAPMASK; -#endif -public: - void SetENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAPMASK = i; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } - void SetENVMAPMASK( bool i ) - { - m_nENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } -private: - int m_nBASEALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bBASEALPHAENVMAPMASK; -#endif -public: - void SetBASEALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASEALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } - void SetBASEALPHAENVMAPMASK( bool i ) - { - m_nBASEALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nNORMALMAPALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bNORMALMAPALPHAENVMAPMASK; -#endif -public: - void SetNORMALMAPALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAPALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } - void SetNORMALMAPALPHAENVMAPMASK( bool i ) - { - m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nBASETEXTURENOENVMAP; -#ifdef _DEBUG - bool m_bBASETEXTURENOENVMAP; -#endif -public: - void SetBASETEXTURENOENVMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURENOENVMAP = i; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = true; -#endif - } - void SetBASETEXTURENOENVMAP( bool i ) - { - m_nBASETEXTURENOENVMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = true; -#endif - } -private: - int m_nBASETEXTURE2NOENVMAP; -#ifdef _DEBUG - bool m_bBASETEXTURE2NOENVMAP; -#endif -public: - void SetBASETEXTURE2NOENVMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2NOENVMAP = i; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = true; -#endif - } - void SetBASETEXTURE2NOENVMAP( bool i ) - { - m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = true; -#endif - } -private: - int m_nFANCY_BLENDING; -#ifdef _DEBUG - bool m_bFANCY_BLENDING; -#endif -public: - void SetFANCY_BLENDING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFANCY_BLENDING = i; -#ifdef _DEBUG - m_bFANCY_BLENDING = true; -#endif - } - void SetFANCY_BLENDING( bool i ) - { - m_nFANCY_BLENDING = i ? 1 : 0; -#ifdef _DEBUG - m_bFANCY_BLENDING = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMASK; -#ifdef _DEBUG - bool m_bBUMPMASK; -#endif -public: - void SetBUMPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMASK = i; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } - void SetBUMPMASK( bool i ) - { - m_nBUMPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } -public: - lightmappedgeneric_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bMASKEDBLENDING = false; -#endif // _DEBUG - m_nMASKEDBLENDING = 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = false; -#endif // _DEBUG - m_nBASETEXTURE2 = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bBUMPMAP2 = false; -#endif // _DEBUG - m_nBUMPMAP2 = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bENVMAPMASK = false; -#endif // _DEBUG - m_nENVMAPMASK = 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nBASEALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nNORMALMAPALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURENOENVMAP = false; -#endif // _DEBUG - m_nBASETEXTURENOENVMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURE2NOENVMAP = false; -#endif // _DEBUG - m_nBASETEXTURE2NOENVMAP = 0; -#ifdef _DEBUG - m_bFANCY_BLENDING = false; -#endif // _DEBUG - m_nFANCY_BLENDING = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMASK = false; -#endif // _DEBUG - m_nBUMPMASK = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 1152 * m_nMASKEDBLENDING ) + ( 2304 * m_nBASETEXTURE2 ) + ( 4608 * m_nDETAILTEXTURE ) + ( 9216 * m_nBUMPMAP ) + ( 18432 * m_nBUMPMAP2 ) + ( 36864 * m_nCUBEMAP ) + ( 73728 * m_nENVMAPMASK ) + ( 147456 * m_nBASEALPHAENVMAPMASK ) + ( 294912 * m_nSELFILLUM ) + ( 589824 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1179648 * m_nDIFFUSEBUMPMAP ) + ( 2359296 * m_nBASETEXTURENOENVMAP ) + ( 4718592 * m_nBASETEXTURE2NOENVMAP ) + ( 9437184 * m_nFANCY_BLENDING ) + ( 18874368 * m_nSEAMLESS ) + ( 37748736 * m_nBUMPMASK ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_ps30 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + 0 -class lightmappedgeneric_ps30_Dynamic_Index -{ -private: - int m_nFASTPATHENVMAPCONTRAST; -#ifdef _DEBUG - bool m_bFASTPATHENVMAPCONTRAST; -#endif -public: - void SetFASTPATHENVMAPCONTRAST( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATHENVMAPCONTRAST = i; -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = true; -#endif - } - void SetFASTPATHENVMAPCONTRAST( bool i ) - { - m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = true; -#endif - } -private: - int m_nCUBEMAPCORRECTED; -#ifdef _DEBUG - bool m_bCUBEMAPCORRECTED; -#endif -public: - void SetCUBEMAPCORRECTED( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAPCORRECTED = i; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } - void SetCUBEMAPCORRECTED( bool i ) - { - m_nCUBEMAPCORRECTED = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = true; -#endif - } -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nWRITEWATERFOGTODESTALPHA; -#ifdef _DEBUG - bool m_bWRITEWATERFOGTODESTALPHA; -#endif -public: - void SetWRITEWATERFOGTODESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITEWATERFOGTODESTALPHA = i; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } - void SetWRITEWATERFOGTODESTALPHA( bool i ) - { - m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = true; -#endif - } -private: - int m_nPIXELFOGTYPE; -#ifdef _DEBUG - bool m_bPIXELFOGTYPE; -#endif -public: - void SetPIXELFOGTYPE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nPIXELFOGTYPE = i; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } - void SetPIXELFOGTYPE( bool i ) - { - m_nPIXELFOGTYPE = i ? 1 : 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nWRITE_DEPTH_TO_DESTALPHA; -#ifdef _DEBUG - bool m_bWRITE_DEPTH_TO_DESTALPHA; -#endif -public: - void SetWRITE_DEPTH_TO_DESTALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nWRITE_DEPTH_TO_DESTALPHA = i; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } - void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) - { - m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = true; -#endif - } -private: - int m_nCSM; -#ifdef _DEBUG - bool m_bCSM; -#endif -public: - void SetCSM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCSM = i; -#ifdef _DEBUG - m_bCSM = true; -#endif - } - void SetCSM( bool i ) - { - m_nCSM = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM = true; -#endif - } -private: - int m_nCSM_PERF; -#ifdef _DEBUG - bool m_bCSM_PERF; -#endif -public: - void SetCSM_PERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nCSM_PERF = i; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } - void SetCSM_PERF( bool i ) - { - m_nCSM_PERF = i ? 1 : 0; -#ifdef _DEBUG - m_bCSM_PERF = true; -#endif - } -public: - lightmappedgeneric_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATHENVMAPCONTRAST = false; -#endif // _DEBUG - m_nFASTPATHENVMAPCONTRAST = 0; -#ifdef _DEBUG - m_bCUBEMAPCORRECTED = false; -#endif // _DEBUG - m_nCUBEMAPCORRECTED = 0; -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bWRITEWATERFOGTODESTALPHA = false; -#endif // _DEBUG - m_nWRITEWATERFOGTODESTALPHA = 0; -#ifdef _DEBUG - m_bPIXELFOGTYPE = false; -#endif // _DEBUG - m_nPIXELFOGTYPE = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bWRITE_DEPTH_TO_DESTALPHA = false; -#endif // _DEBUG - m_nWRITE_DEPTH_TO_DESTALPHA = 0; -#ifdef _DEBUG - m_bCSM = false; -#endif // _DEBUG - m_nCSM = 0; -#ifdef _DEBUG - m_bCSM_PERF = false; -#endif // _DEBUG - m_nCSM_PERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bCUBEMAPCORRECTED && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA && m_bCSM && m_bCSM_PERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nCUBEMAPCORRECTED ) + ( 4 * m_nFASTPATH ) + ( 8 * m_nWRITEWATERFOGTODESTALPHA ) + ( 16 * m_nPIXELFOGTYPE ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 96 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 192 * m_nCSM ) + ( 384 * m_nCSM_PERF ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_ps30 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_CUBEMAPCORRECTED + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_vs30.inc deleted file mode 100644 index 853f8183..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightmappedgeneric_vs30.inc +++ /dev/null @@ -1,312 +0,0 @@ -#include "shaderlib/cshader.h" -class lightmappedgeneric_vs30_Static_Index -{ -private: - int m_nENVMAP_MASK; -#ifdef _DEBUG - bool m_bENVMAP_MASK; -#endif -public: - void SetENVMAP_MASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAP_MASK = i; -#ifdef _DEBUG - m_bENVMAP_MASK = true; -#endif - } - void SetENVMAP_MASK( bool i ) - { - m_nENVMAP_MASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAP_MASK = true; -#endif - } -private: - int m_nTANGENTSPACE; -#ifdef _DEBUG - bool m_bTANGENTSPACE; -#endif -public: - void SetTANGENTSPACE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nTANGENTSPACE = i; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } - void SetTANGENTSPACE( bool i ) - { - m_nTANGENTSPACE = i ? 1 : 0; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nDIFFUSEBUMPMAP; -#ifdef _DEBUG - bool m_bDIFFUSEBUMPMAP; -#endif -public: - void SetDIFFUSEBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSEBUMPMAP = i; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } - void SetDIFFUSEBUMPMAP( bool i ) - { - m_nDIFFUSEBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nBUMPMASK; -#ifdef _DEBUG - bool m_bBUMPMASK; -#endif -public: - void SetBUMPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMASK = i; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } - void SetBUMPMASK( bool i ) - { - m_nBUMPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMASK = true; -#endif - } -public: - lightmappedgeneric_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bENVMAP_MASK = false; -#endif // _DEBUG - m_nENVMAP_MASK = 0; -#ifdef _DEBUG - m_bTANGENTSPACE = false; -#endif // _DEBUG - m_nTANGENTSPACE = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bDIFFUSEBUMPMAP = false; -#endif // _DEBUG - m_nDIFFUSEBUMPMAP = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bBUMPMASK = false; -#endif // _DEBUG - m_nBUMPMASK = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS && m_bBUMPMASK; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + 0; - } -}; -#define shaderStaticTest_lightmappedgeneric_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + 0 -class lightmappedgeneric_vs30_Dynamic_Index -{ -private: - int m_nFASTPATH; -#ifdef _DEBUG - bool m_bFASTPATH; -#endif -public: - void SetFASTPATH( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFASTPATH = i; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } - void SetFASTPATH( bool i ) - { - m_nFASTPATH = i ? 1 : 0; -#ifdef _DEBUG - m_bFASTPATH = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -public: - lightmappedgeneric_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bFASTPATH = false; -#endif // _DEBUG - m_nFASTPATH = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; - } -}; -#define shaderDynamicTest_lightmappedgeneric_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightpass_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightpass_ps30.inc deleted file mode 100644 index fb620926..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightpass_ps30.inc +++ /dev/null @@ -1,237 +0,0 @@ -#include "shaderlib/cshader.h" -class lightpass_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -private: - int m_nBUMPMAP; -#ifdef _DEBUG - bool m_bBUMPMAP; -#endif -public: - void SetBUMPMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBUMPMAP = i; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } - void SetBUMPMAP( bool i ) - { - m_nBUMPMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bBUMPMAP = true; -#endif - } -private: - int m_nBASETEXTURE2; -#ifdef _DEBUG - bool m_bBASETEXTURE2; -#endif -public: - void SetBASETEXTURE2( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASETEXTURE2 = i; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } - void SetBASETEXTURE2( bool i ) - { - m_nBASETEXTURE2 = i ? 1 : 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -private: - int m_nMODEL; -#ifdef _DEBUG - bool m_bMODEL; -#endif -public: - void SetMODEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMODEL = i; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } - void SetMODEL( bool i ) - { - m_nMODEL = i ? 1 : 0; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } -private: - int m_nSMOOTHNESS; -#ifdef _DEBUG - bool m_bSMOOTHNESS; -#endif -public: - void SetSMOOTHNESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSMOOTHNESS = i; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } - void SetSMOOTHNESS( bool i ) - { - m_nSMOOTHNESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSMOOTHNESS = true; -#endif - } -public: - lightpass_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; -#ifdef _DEBUG - m_bBUMPMAP = false; -#endif // _DEBUG - m_nBUMPMAP = 0; -#ifdef _DEBUG - m_bBASETEXTURE2 = false; -#endif // _DEBUG - m_nBASETEXTURE2 = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; -#ifdef _DEBUG - m_bMODEL = false; -#endif // _DEBUG - m_nMODEL = 0; -#ifdef _DEBUG - m_bSMOOTHNESS = false; -#endif // _DEBUG - m_nSMOOTHNESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP && m_bBASETEXTURE2 && m_bSEAMLESS && m_bDECAL && m_bMODEL && m_bSMOOTHNESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 3 * m_nCONVERT_TO_SRGB ) + ( 3 * m_nBUMPMAP ) + ( 6 * m_nBASETEXTURE2 ) + ( 12 * m_nSEAMLESS ) + ( 24 * m_nDECAL ) + ( 48 * m_nMODEL ) + ( 96 * m_nSMOOTHNESS ) + 0; - } -}; -#define shaderStaticTest_lightpass_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DECAL + psh_forgot_to_set_static_MODEL + psh_forgot_to_set_static_SMOOTHNESS + 0 -class lightpass_ps30_Dynamic_Index -{ -private: - int m_nPERF; -#ifdef _DEBUG - bool m_bPERF; -#endif -public: - void SetPERF( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nPERF = i; -#ifdef _DEBUG - m_bPERF = true; -#endif - } - void SetPERF( bool i ) - { - m_nPERF = i ? 1 : 0; -#ifdef _DEBUG - m_bPERF = true; -#endif - } -public: - lightpass_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bPERF = false; -#endif // _DEBUG - m_nPERF = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bPERF; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nPERF ) + 0; - } -}; -#define shaderDynamicTest_lightpass_ps30 psh_forgot_to_set_dynamic_PERF + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lightpass_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lightpass_vs30.inc deleted file mode 100644 index 1c427b97..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lightpass_vs30.inc +++ /dev/null @@ -1,262 +0,0 @@ -#include "shaderlib/cshader.h" -class lightpass_vs30_Static_Index -{ -private: - int m_nMODEL; -#ifdef _DEBUG - bool m_bMODEL; -#endif -public: - void SetMODEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMODEL = i; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } - void SetMODEL( bool i ) - { - m_nMODEL = i ? 1 : 0; -#ifdef _DEBUG - m_bMODEL = true; -#endif - } -private: - int m_nTANGENTSPACE; -#ifdef _DEBUG - bool m_bTANGENTSPACE; -#endif -public: - void SetTANGENTSPACE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nTANGENTSPACE = i; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } - void SetTANGENTSPACE( bool i ) - { - m_nTANGENTSPACE = i ? 1 : 0; -#ifdef _DEBUG - m_bTANGENTSPACE = true; -#endif - } -private: - int m_nMORPHING_VTEX; -#ifdef _DEBUG - bool m_bMORPHING_VTEX; -#endif -public: - void SetMORPHING_VTEX( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING_VTEX = i; -#ifdef _DEBUG - m_bMORPHING_VTEX = true; -#endif - } - void SetMORPHING_VTEX( bool i ) - { - m_nMORPHING_VTEX = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING_VTEX = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nVERTEXALPHATEXBLENDFACTOR; -#ifdef _DEBUG - bool m_bVERTEXALPHATEXBLENDFACTOR; -#endif -public: - void SetVERTEXALPHATEXBLENDFACTOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXALPHATEXBLENDFACTOR = i; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } - void SetVERTEXALPHATEXBLENDFACTOR( bool i ) - { - m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = true; -#endif - } -private: - int m_nSEAMLESS; -#ifdef _DEBUG - bool m_bSEAMLESS; -#endif -public: - void SetSEAMLESS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS = i; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } - void SetSEAMLESS( bool i ) - { - m_nSEAMLESS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS = true; -#endif - } -public: - lightpass_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bMODEL = false; -#endif // _DEBUG - m_nMODEL = 0; -#ifdef _DEBUG - m_bTANGENTSPACE = false; -#endif // _DEBUG - m_nTANGENTSPACE = 0; -#ifdef _DEBUG - m_bMORPHING_VTEX = false; -#endif // _DEBUG - m_nMORPHING_VTEX = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bVERTEXALPHATEXBLENDFACTOR = false; -#endif // _DEBUG - m_nVERTEXALPHATEXBLENDFACTOR = 0; -#ifdef _DEBUG - m_bSEAMLESS = false; -#endif // _DEBUG - m_nSEAMLESS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bMODEL && m_bTANGENTSPACE && m_bMORPHING_VTEX && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 8 * m_nMODEL ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nMORPHING_VTEX ) + ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 256 * m_nSEAMLESS ) + 0; - } -}; -#define shaderStaticTest_lightpass_vs30 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_MORPHING_VTEX + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + 0 -class lightpass_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - lightpass_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_lightpass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/lpreview1_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/lpreview1_ps30.inc deleted file mode 100644 index f7f22746..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/lpreview1_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class lpreview1_ps30_Static_Index -{ -public: - lpreview1_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_lpreview1_ps30 0 -class lpreview1_ps30_Dynamic_Index -{ -public: - lpreview1_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_lpreview1_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/luma_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/luma_ps30.inc deleted file mode 100644 index 1dc357f7..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/luma_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class luma_ps30_Static_Index -{ -public: - luma_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_luma_ps30 0 -class luma_ps30_Dynamic_Index -{ -public: - luma_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_luma_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/normalmapreconstruct_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/normalmapreconstruct_ps30.inc deleted file mode 100644 index fca2ed02..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/normalmapreconstruct_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class normalmapreconstruct_ps30_Static_Index -{ -public: - normalmapreconstruct_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_normalmapreconstruct_ps30 0 -class normalmapreconstruct_ps30_Dynamic_Index -{ -public: - normalmapreconstruct_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_normalmapreconstruct_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/passthru_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/passthru_vs30.inc deleted file mode 100644 index e20c5253..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/passthru_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class passthru_vs30_Static_Index -{ -public: - passthru_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_passthru_vs30 0 -class passthru_vs30_Dynamic_Index -{ -public: - passthru_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_passthru_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/screenspace_simple_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/screenspace_simple_vs30.inc deleted file mode 100644 index 7da731a6..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/screenspace_simple_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenspace_simple_vs30_Static_Index -{ -public: - screenspace_simple_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenspace_simple_vs30 0 -class screenspace_simple_vs30_Dynamic_Index -{ -public: - screenspace_simple_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenspace_simple_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/screenwater_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/screenwater_ps30.inc deleted file mode 100644 index b688b0da..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/screenwater_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenwater_ps30_Static_Index -{ -public: - screenwater_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenwater_ps30 0 -class screenwater_ps30_Dynamic_Index -{ -public: - screenwater_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenwater_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/screenwater_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/screenwater_vs30.inc deleted file mode 100644 index ac3891b2..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/screenwater_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class screenwater_vs30_Static_Index -{ -public: - screenwater_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_screenwater_vs30 0 -class screenwater_vs30_Dynamic_Index -{ -public: - screenwater_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_screenwater_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/skydome_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/skydome_ps30.inc deleted file mode 100644 index 20619ba2..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/skydome_ps30.inc +++ /dev/null @@ -1,87 +0,0 @@ -#include "shaderlib/cshader.h" -class skydome_ps30_Static_Index -{ -private: - int m_nCONVERT_TO_SRGB; -#ifdef _DEBUG - bool m_bCONVERT_TO_SRGB; -#endif -public: - void SetCONVERT_TO_SRGB( int i ) - { - Assert( i >= 0 && i <= 0 ); - m_nCONVERT_TO_SRGB = i; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } - void SetCONVERT_TO_SRGB( bool i ) - { - m_nCONVERT_TO_SRGB = i ? 1 : 0; -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = true; -#endif - } -public: - skydome_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCONVERT_TO_SRGB = false; -#endif // _DEBUG - m_nCONVERT_TO_SRGB = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 2 * m_nCONVERT_TO_SRGB ) + 0; - } -}; -#define shaderStaticTest_skydome_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + 0 -class skydome_ps30_Dynamic_Index -{ -private: - int m_nRENDER_SKY; -#ifdef _DEBUG - bool m_bRENDER_SKY; -#endif -public: - void SetRENDER_SKY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nRENDER_SKY = i; -#ifdef _DEBUG - m_bRENDER_SKY = true; -#endif - } - void SetRENDER_SKY( bool i ) - { - m_nRENDER_SKY = i ? 1 : 0; -#ifdef _DEBUG - m_bRENDER_SKY = true; -#endif - } -public: - skydome_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bRENDER_SKY = false; -#endif // _DEBUG - m_nRENDER_SKY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bRENDER_SKY; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nRENDER_SKY ) + 0; - } -}; -#define shaderDynamicTest_skydome_ps30 psh_forgot_to_set_dynamic_RENDER_SKY + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/skydome_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/skydome_vs30.inc deleted file mode 100644 index f9ac5381..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/skydome_vs30.inc +++ /dev/null @@ -1,60 +0,0 @@ -#include "shaderlib/cshader.h" -class skydome_vs30_Static_Index -{ -public: - skydome_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_skydome_vs30 0 -class skydome_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -public: - skydome_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + 0; - } -}; -#define shaderDynamicTest_skydome_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/ssgi_combine_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/ssgi_combine_ps30.inc deleted file mode 100644 index 76f1ca76..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/ssgi_combine_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssgi_combine_ps30_Static_Index -{ -public: - ssgi_combine_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssgi_combine_ps30 0 -class ssgi_combine_ps30_Dynamic_Index -{ -public: - ssgi_combine_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssgi_combine_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/ssgi_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/ssgi_ps30.inc deleted file mode 100644 index 558e5d4a..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/ssgi_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssgi_ps30_Static_Index -{ -public: - ssgi_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssgi_ps30 0 -class ssgi_ps30_Dynamic_Index -{ -public: - ssgi_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssgi_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/ssr_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/ssr_ps30.inc deleted file mode 100644 index 2fe5d76b..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/ssr_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class ssr_ps30_Static_Index -{ -public: - ssr_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_ssr_ps30 0 -class ssr_ps30_Dynamic_Index -{ -public: - ssr_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_ssr_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_ps30.inc deleted file mode 100644 index 54032c52..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_blur_ps30_Static_Index -{ -public: - unsharp_blur_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_blur_ps30 0 -class unsharp_blur_ps30_Dynamic_Index -{ -public: - unsharp_blur_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_blur_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_vs30.inc deleted file mode 100644 index 53906a96..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_blur_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_blur_vs30_Static_Index -{ -public: - unsharp_blur_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_blur_vs30 0 -class unsharp_blur_vs30_Dynamic_Index -{ -public: - unsharp_blur_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_blur_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/unsharp_ps30.inc deleted file mode 100644 index 03f9fcf9..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_ps30_Static_Index -{ -public: - unsharp_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_ps30 0 -class unsharp_ps30_Dynamic_Index -{ -public: - unsharp_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/unsharp_vs30.inc deleted file mode 100644 index 9c1b1a84..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/unsharp_vs30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class unsharp_vs30_Static_Index -{ -public: - unsharp_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_unsharp_vs30 0 -class unsharp_vs30_Dynamic_Index -{ -public: - unsharp_vs30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_unsharp_vs30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vance_bloom_combine_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vance_bloom_combine_ps30.inc deleted file mode 100644 index 335e0801..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vance_bloom_combine_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_bloom_combine_ps30_Static_Index -{ -public: - vance_bloom_combine_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_bloom_combine_ps30 0 -class vance_bloom_combine_ps30_Dynamic_Index -{ -public: - vance_bloom_combine_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_vance_bloom_combine_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_ps30.inc deleted file mode 100644 index 40087e9a..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_ps30.inc +++ /dev/null @@ -1,33 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_scope_ps30_Static_Index -{ -public: - vance_scope_ps30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_scope_ps30 0 -class vance_scope_ps30_Dynamic_Index -{ -public: - vance_scope_ps30_Dynamic_Index() - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderDynamicTest_vance_scope_ps30 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_vs30.inc deleted file mode 100644 index 978cf31c..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vance_scope_vs30.inc +++ /dev/null @@ -1,85 +0,0 @@ -#include "shaderlib/cshader.h" -class vance_scope_vs30_Static_Index -{ -public: - vance_scope_vs30_Static_Index( ) - { - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG -#endif // _DEBUG - return 0; - } -}; -#define shaderStaticTest_vance_scope_vs30 0 -class vance_scope_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -public: - vance_scope_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; - } -}; -#define shaderDynamicTest_vance_scope_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vertexLit_and_unlit_Generic_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vertexLit_and_unlit_Generic_vs30.inc deleted file mode 100644 index 7473d292..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vertexLit_and_unlit_Generic_vs30.inc +++ /dev/null @@ -1,462 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_vs30_Static_Index -{ -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nSEAMLESS_BASE; -#ifdef _DEBUG - bool m_bSEAMLESS_BASE; -#endif -public: - void SetSEAMLESS_BASE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_BASE = i; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } - void SetSEAMLESS_BASE( bool i ) - { - m_nSEAMLESS_BASE = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } -private: - int m_nSEAMLESS_DETAIL; -#ifdef _DEBUG - bool m_bSEAMLESS_DETAIL; -#endif -public: - void SetSEAMLESS_DETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_DETAIL = i; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } - void SetSEAMLESS_DETAIL( bool i ) - { - m_nSEAMLESS_DETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } -private: - int m_nSEPARATE_DETAIL_UVS; -#ifdef _DEBUG - bool m_bSEPARATE_DETAIL_UVS; -#endif -public: - void SetSEPARATE_DETAIL_UVS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEPARATE_DETAIL_UVS = i; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = true; -#endif - } - void SetSEPARATE_DETAIL_UVS( bool i ) - { - m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = true; -#endif - } -private: - int m_nDECAL; -#ifdef _DEBUG - bool m_bDECAL; -#endif -public: - void SetDECAL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDECAL = i; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } - void SetDECAL( bool i ) - { - m_nDECAL = i ? 1 : 0; -#ifdef _DEBUG - m_bDECAL = true; -#endif - } -private: - int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; -#ifdef _DEBUG - bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; -#endif -public: - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) - { - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } -public: - vertexlit_and_unlit_generic_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = false; -#endif // _DEBUG - m_nSEAMLESS_BASE = 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = false; -#endif // _DEBUG - m_nSEAMLESS_DETAIL = 0; -#ifdef _DEBUG - m_bSEPARATE_DETAIL_UVS = false; -#endif // _DEBUG - m_nSEPARATE_DETAIL_UVS = 0; -#ifdef _DEBUG - m_bDECAL = false; -#endif // _DEBUG - m_nDECAL = 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; -#endif // _DEBUG - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bDECAL && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 256 * m_nVERTEXCOLOR ) + ( 512 * m_nCUBEMAP ) + ( 1024 * m_nHALFLAMBERT ) + ( 2048 * m_nFLASHLIGHT ) + ( 4096 * m_nSEAMLESS_BASE ) + ( 8192 * m_nSEAMLESS_DETAIL ) + ( 16384 * m_nSEPARATE_DETAIL_UVS ) + ( 32768 * m_nDECAL ) + ( 65536 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + 0 -class vertexlit_and_unlit_generic_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDYNAMIC_LIGHT; -#ifdef _DEBUG - bool m_bDYNAMIC_LIGHT; -#endif -public: - void SetDYNAMIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDYNAMIC_LIGHT = i; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } - void SetDYNAMIC_LIGHT( bool i ) - { - m_nDYNAMIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } -private: - int m_nSTATIC_LIGHT_VERTEX; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_VERTEX; -#endif -public: - void SetSTATIC_LIGHT_VERTEX( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_VERTEX = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = true; -#endif - } - void SetSTATIC_LIGHT_VERTEX( bool i ) - { - m_nSTATIC_LIGHT_VERTEX = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = true; -#endif - } -private: - int m_nSTATIC_LIGHT_LIGHTMAP; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_LIGHTMAP; -#endif -public: - void SetSTATIC_LIGHT_LIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_LIGHTMAP = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } - void SetSTATIC_LIGHT_LIGHTMAP( bool i ) - { - m_nSTATIC_LIGHT_LIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nMORPHING; -#ifdef _DEBUG - bool m_bMORPHING; -#endif -public: - void SetMORPHING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nMORPHING = i; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } - void SetMORPHING( bool i ) - { - m_nMORPHING = i ? 1 : 0; -#ifdef _DEBUG - m_bMORPHING = true; -#endif - } -public: - vertexlit_and_unlit_generic_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = false; -#endif // _DEBUG - m_nDYNAMIC_LIGHT = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_VERTEX = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_VERTEX = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_LIGHTMAP = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bMORPHING = false; -#endif // _DEBUG - m_nMORPHING = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT_VERTEX && m_bSTATIC_LIGHT_LIGHTMAP && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT_VERTEX ) + ( 8 * m_nSTATIC_LIGHT_LIGHTMAP ) + ( 16 * m_nDOWATERFOG ) + ( 32 * m_nSKINNING ) + ( 64 * m_nLIGHTING_PREVIEW ) + ( 128 * m_nMORPHING ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT_VERTEX + vsh_forgot_to_set_dynamic_STATIC_LIGHT_LIGHTMAP + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vertexlitPBR_vs30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vertexlitPBR_vs30.inc deleted file mode 100644 index f73364a0..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vertexlitPBR_vs30.inc +++ /dev/null @@ -1,287 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlitpbr_vs30_Static_Index -{ -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; -#ifdef _DEBUG - bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; -#endif -public: - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } - void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) - { - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; -#endif - } -public: - vertexlitpbr_vs30_Static_Index( ) - { -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; -#endif // _DEBUG - m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 320 * m_nVERTEXCOLOR ) + ( 640 * m_nCUBEMAP ) + ( 1280 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + 0; - } -}; -#define shaderStaticTest_vertexlitpbr_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + 0 -class vertexlitpbr_vs30_Dynamic_Index -{ -private: - int m_nCOMPRESSED_VERTS; -#ifdef _DEBUG - bool m_bCOMPRESSED_VERTS; -#endif -public: - void SetCOMPRESSED_VERTS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCOMPRESSED_VERTS = i; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } - void SetCOMPRESSED_VERTS( bool i ) - { - m_nCOMPRESSED_VERTS = i ? 1 : 0; -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = true; -#endif - } -private: - int m_nDOWATERFOG; -#ifdef _DEBUG - bool m_bDOWATERFOG; -#endif -public: - void SetDOWATERFOG( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDOWATERFOG = i; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } - void SetDOWATERFOG( bool i ) - { - m_nDOWATERFOG = i ? 1 : 0; -#ifdef _DEBUG - m_bDOWATERFOG = true; -#endif - } -private: - int m_nSKINNING; -#ifdef _DEBUG - bool m_bSKINNING; -#endif -public: - void SetSKINNING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSKINNING = i; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } - void SetSKINNING( bool i ) - { - m_nSKINNING = i ? 1 : 0; -#ifdef _DEBUG - m_bSKINNING = true; -#endif - } -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nDYNAMIC_LIGHT; -#ifdef _DEBUG - bool m_bDYNAMIC_LIGHT; -#endif -public: - void SetDYNAMIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDYNAMIC_LIGHT = i; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } - void SetDYNAMIC_LIGHT( bool i ) - { - m_nDYNAMIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = true; -#endif - } -private: - int m_nSTATIC_LIGHT; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT; -#endif -public: - void SetSTATIC_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT = true; -#endif - } - void SetSTATIC_LIGHT( bool i ) - { - m_nSTATIC_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT = true; -#endif - } -public: - vertexlitpbr_vs30_Dynamic_Index() - { -#ifdef _DEBUG - m_bCOMPRESSED_VERTS = false; -#endif // _DEBUG - m_nCOMPRESSED_VERTS = 0; -#ifdef _DEBUG - m_bDOWATERFOG = false; -#endif // _DEBUG - m_nDOWATERFOG = 0; -#ifdef _DEBUG - m_bSKINNING = false; -#endif // _DEBUG - m_nSKINNING = 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bDYNAMIC_LIGHT = false; -#endif // _DEBUG - m_nDYNAMIC_LIGHT = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT = false; -#endif // _DEBUG - m_nSTATIC_LIGHT = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + ( 80 * m_nDYNAMIC_LIGHT ) + ( 160 * m_nSTATIC_LIGHT ) + 0; - } -}; -#define shaderDynamicTest_vertexlitpbr_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_bump_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_bump_ps30.inc deleted file mode 100644 index 47ee38e9..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_bump_ps30.inc +++ /dev/null @@ -1,412 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_bump_ps30_Static_Index -{ -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDIFFUSELIGHTING; -#ifdef _DEBUG - bool m_bDIFFUSELIGHTING; -#endif -public: - void SetDIFFUSELIGHTING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSELIGHTING = i; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } - void SetDIFFUSELIGHTING( bool i ) - { - m_nDIFFUSELIGHTING = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } -private: - int m_nLIGHTWARPTEXTURE; -#ifdef _DEBUG - bool m_bLIGHTWARPTEXTURE; -#endif -public: - void SetLIGHTWARPTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nLIGHTWARPTEXTURE = i; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = true; -#endif - } - void SetLIGHTWARPTEXTURE( bool i ) - { - m_nLIGHTWARPTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nSELFILLUMFRESNEL; -#ifdef _DEBUG - bool m_bSELFILLUMFRESNEL; -#endif -public: - void SetSELFILLUMFRESNEL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUMFRESNEL = i; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = true; -#endif - } - void SetSELFILLUMFRESNEL( bool i ) - { - m_nSELFILLUMFRESNEL = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = true; -#endif - } -private: - int m_nNORMALMAPALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bNORMALMAPALPHAENVMAPMASK; -#endif -public: - void SetNORMALMAPALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nNORMALMAPALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } - void SetNORMALMAPALPHAENVMAPMASK( bool i ) - { - m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = true; -#endif - } -private: - int m_nHALFLAMBERT; -#ifdef _DEBUG - bool m_bHALFLAMBERT; -#endif -public: - void SetHALFLAMBERT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nHALFLAMBERT = i; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } - void SetHALFLAMBERT( bool i ) - { - m_nHALFLAMBERT = i ? 1 : 0; -#ifdef _DEBUG - m_bHALFLAMBERT = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 6 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -private: - int m_nBLENDTINTBYBASEALPHA; -#ifdef _DEBUG - bool m_bBLENDTINTBYBASEALPHA; -#endif -public: - void SetBLENDTINTBYBASEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBLENDTINTBYBASEALPHA = i; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } - void SetBLENDTINTBYBASEALPHA( bool i ) - { - m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = false; -#endif // _DEBUG - m_nDIFFUSELIGHTING = 0; -#ifdef _DEBUG - m_bLIGHTWARPTEXTURE = false; -#endif // _DEBUG - m_nLIGHTWARPTEXTURE = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bSELFILLUMFRESNEL = false; -#endif // _DEBUG - m_nSELFILLUMFRESNEL = 0; -#ifdef _DEBUG - m_bNORMALMAPALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nNORMALMAPALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bHALFLAMBERT = false; -#endif // _DEBUG - m_nHALFLAMBERT = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = false; -#endif // _DEBUG - m_nBLENDTINTBYBASEALPHA = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + 0 -class vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index -{ -private: - int m_nNUM_LIGHTS; -#ifdef _DEBUG - bool m_bNUM_LIGHTS; -#endif -public: - void SetNUM_LIGHTS( int i ) - { - Assert( i >= 0 && i <= 4 ); - m_nNUM_LIGHTS = i; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } - void SetNUM_LIGHTS( bool i ) - { - m_nNUM_LIGHTS = i ? 1 : 0; -#ifdef _DEBUG - m_bNUM_LIGHTS = true; -#endif - } -private: - int m_nAMBIENT_LIGHT; -#ifdef _DEBUG - bool m_bAMBIENT_LIGHT; -#endif -public: - void SetAMBIENT_LIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nAMBIENT_LIGHT = i; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = true; -#endif - } - void SetAMBIENT_LIGHT( bool i ) - { - m_nAMBIENT_LIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -public: - vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bNUM_LIGHTS = false; -#endif // _DEBUG - m_nNUM_LIGHTS = 0; -#ifdef _DEBUG - m_bAMBIENT_LIGHT = false; -#endif // _DEBUG - m_nAMBIENT_LIGHT = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_ps30.inc b/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_ps30.inc deleted file mode 100644 index ce1c6f91..00000000 --- a/materialsystem/stdshaders/fxctmp9_tmp/vertexlit_and_unlit_generic_ps30.inc +++ /dev/null @@ -1,662 +0,0 @@ -#include "shaderlib/cshader.h" -class vertexlit_and_unlit_generic_ps30_Static_Index -{ -private: - int m_nDETAILTEXTURE; -#ifdef _DEBUG - bool m_bDETAILTEXTURE; -#endif -public: - void SetDETAILTEXTURE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDETAILTEXTURE = i; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } - void SetDETAILTEXTURE( bool i ) - { - m_nDETAILTEXTURE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAILTEXTURE = true; -#endif - } -private: - int m_nCUBEMAP; -#ifdef _DEBUG - bool m_bCUBEMAP; -#endif -public: - void SetCUBEMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP = i; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } - void SetCUBEMAP( bool i ) - { - m_nCUBEMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP = true; -#endif - } -private: - int m_nDIFFUSELIGHTING; -#ifdef _DEBUG - bool m_bDIFFUSELIGHTING; -#endif -public: - void SetDIFFUSELIGHTING( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDIFFUSELIGHTING = i; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } - void SetDIFFUSELIGHTING( bool i ) - { - m_nDIFFUSELIGHTING = i ? 1 : 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = true; -#endif - } -private: - int m_nENVMAPMASK; -#ifdef _DEBUG - bool m_bENVMAPMASK; -#endif -public: - void SetENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nENVMAPMASK = i; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } - void SetENVMAPMASK( bool i ) - { - m_nENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bENVMAPMASK = true; -#endif - } -private: - int m_nBASEALPHAENVMAPMASK; -#ifdef _DEBUG - bool m_bBASEALPHAENVMAPMASK; -#endif -public: - void SetBASEALPHAENVMAPMASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBASEALPHAENVMAPMASK = i; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } - void SetBASEALPHAENVMAPMASK( bool i ) - { - m_nBASEALPHAENVMAPMASK = i ? 1 : 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = true; -#endif - } -private: - int m_nSELFILLUM; -#ifdef _DEBUG - bool m_bSELFILLUM; -#endif -public: - void SetSELFILLUM( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM = i; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } - void SetSELFILLUM( bool i ) - { - m_nSELFILLUM = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM = true; -#endif - } -private: - int m_nVERTEXCOLOR; -#ifdef _DEBUG - bool m_bVERTEXCOLOR; -#endif -public: - void SetVERTEXCOLOR( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nVERTEXCOLOR = i; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } - void SetVERTEXCOLOR( bool i ) - { - m_nVERTEXCOLOR = i ? 1 : 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = true; -#endif - } -private: - int m_nFLASHLIGHT; -#ifdef _DEBUG - bool m_bFLASHLIGHT; -#endif -public: - void SetFLASHLIGHT( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHT = i; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } - void SetFLASHLIGHT( bool i ) - { - m_nFLASHLIGHT = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHT = true; -#endif - } -private: - int m_nSELFILLUM_ENVMAPMASK_ALPHA; -#ifdef _DEBUG - bool m_bSELFILLUM_ENVMAPMASK_ALPHA; -#endif -public: - void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSELFILLUM_ENVMAPMASK_ALPHA = i; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = true; -#endif - } - void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) - { - m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = true; -#endif - } -private: - int m_nDETAIL_BLEND_MODE; -#ifdef _DEBUG - bool m_bDETAIL_BLEND_MODE; -#endif -public: - void SetDETAIL_BLEND_MODE( int i ) - { - Assert( i >= 0 && i <= 9 ); - m_nDETAIL_BLEND_MODE = i; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } - void SetDETAIL_BLEND_MODE( bool i ) - { - m_nDETAIL_BLEND_MODE = i ? 1 : 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = true; -#endif - } -private: - int m_nSEAMLESS_BASE; -#ifdef _DEBUG - bool m_bSEAMLESS_BASE; -#endif -public: - void SetSEAMLESS_BASE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_BASE = i; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } - void SetSEAMLESS_BASE( bool i ) - { - m_nSEAMLESS_BASE = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = true; -#endif - } -private: - int m_nSEAMLESS_DETAIL; -#ifdef _DEBUG - bool m_bSEAMLESS_DETAIL; -#endif -public: - void SetSEAMLESS_DETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSEAMLESS_DETAIL = i; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } - void SetSEAMLESS_DETAIL( bool i ) - { - m_nSEAMLESS_DETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = true; -#endif - } -private: - int m_nDISTANCEALPHA; -#ifdef _DEBUG - bool m_bDISTANCEALPHA; -#endif -public: - void SetDISTANCEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDISTANCEALPHA = i; -#ifdef _DEBUG - m_bDISTANCEALPHA = true; -#endif - } - void SetDISTANCEALPHA( bool i ) - { - m_nDISTANCEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bDISTANCEALPHA = true; -#endif - } -private: - int m_nDISTANCEALPHAFROMDETAIL; -#ifdef _DEBUG - bool m_bDISTANCEALPHAFROMDETAIL; -#endif -public: - void SetDISTANCEALPHAFROMDETAIL( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDISTANCEALPHAFROMDETAIL = i; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = true; -#endif - } - void SetDISTANCEALPHAFROMDETAIL( bool i ) - { - m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = true; -#endif - } -private: - int m_nSOFT_MASK; -#ifdef _DEBUG - bool m_bSOFT_MASK; -#endif -public: - void SetSOFT_MASK( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSOFT_MASK = i; -#ifdef _DEBUG - m_bSOFT_MASK = true; -#endif - } - void SetSOFT_MASK( bool i ) - { - m_nSOFT_MASK = i ? 1 : 0; -#ifdef _DEBUG - m_bSOFT_MASK = true; -#endif - } -private: - int m_nOUTLINE; -#ifdef _DEBUG - bool m_bOUTLINE; -#endif -public: - void SetOUTLINE( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nOUTLINE = i; -#ifdef _DEBUG - m_bOUTLINE = true; -#endif - } - void SetOUTLINE( bool i ) - { - m_nOUTLINE = i ? 1 : 0; -#ifdef _DEBUG - m_bOUTLINE = true; -#endif - } -private: - int m_nOUTER_GLOW; -#ifdef _DEBUG - bool m_bOUTER_GLOW; -#endif -public: - void SetOUTER_GLOW( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nOUTER_GLOW = i; -#ifdef _DEBUG - m_bOUTER_GLOW = true; -#endif - } - void SetOUTER_GLOW( bool i ) - { - m_nOUTER_GLOW = i ? 1 : 0; -#ifdef _DEBUG - m_bOUTER_GLOW = true; -#endif - } -private: - int m_nFLASHLIGHTDEPTHFILTERMODE; -#ifdef _DEBUG - bool m_bFLASHLIGHTDEPTHFILTERMODE; -#endif -public: - void SetFLASHLIGHTDEPTHFILTERMODE( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nFLASHLIGHTDEPTHFILTERMODE = i; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } - void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) - { - m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = true; -#endif - } -private: - int m_nDEPTHBLEND; -#ifdef _DEBUG - bool m_bDEPTHBLEND; -#endif -public: - void SetDEPTHBLEND( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDEPTHBLEND = i; -#ifdef _DEBUG - m_bDEPTHBLEND = true; -#endif - } - void SetDEPTHBLEND( bool i ) - { - m_nDEPTHBLEND = i ? 1 : 0; -#ifdef _DEBUG - m_bDEPTHBLEND = true; -#endif - } -private: - int m_nBLENDTINTBYBASEALPHA; -#ifdef _DEBUG - bool m_bBLENDTINTBYBASEALPHA; -#endif -public: - void SetBLENDTINTBYBASEALPHA( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nBLENDTINTBYBASEALPHA = i; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } - void SetBLENDTINTBYBASEALPHA( bool i ) - { - m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = true; -#endif - } -private: - int m_nCUBEMAP_SPHERE_LEGACY; -#ifdef _DEBUG - bool m_bCUBEMAP_SPHERE_LEGACY; -#endif -public: - void SetCUBEMAP_SPHERE_LEGACY( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nCUBEMAP_SPHERE_LEGACY = i; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } - void SetCUBEMAP_SPHERE_LEGACY( bool i ) - { - m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = true; -#endif - } -public: - vertexlit_and_unlit_generic_ps30_Static_Index( ) - { -#ifdef _DEBUG - m_bDETAILTEXTURE = false; -#endif // _DEBUG - m_nDETAILTEXTURE = 0; -#ifdef _DEBUG - m_bCUBEMAP = false; -#endif // _DEBUG - m_nCUBEMAP = 0; -#ifdef _DEBUG - m_bDIFFUSELIGHTING = false; -#endif // _DEBUG - m_nDIFFUSELIGHTING = 0; -#ifdef _DEBUG - m_bENVMAPMASK = false; -#endif // _DEBUG - m_nENVMAPMASK = 0; -#ifdef _DEBUG - m_bBASEALPHAENVMAPMASK = false; -#endif // _DEBUG - m_nBASEALPHAENVMAPMASK = 0; -#ifdef _DEBUG - m_bSELFILLUM = false; -#endif // _DEBUG - m_nSELFILLUM = 0; -#ifdef _DEBUG - m_bVERTEXCOLOR = false; -#endif // _DEBUG - m_nVERTEXCOLOR = 0; -#ifdef _DEBUG - m_bFLASHLIGHT = false; -#endif // _DEBUG - m_nFLASHLIGHT = 0; -#ifdef _DEBUG - m_bSELFILLUM_ENVMAPMASK_ALPHA = false; -#endif // _DEBUG - m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; -#ifdef _DEBUG - m_bDETAIL_BLEND_MODE = false; -#endif // _DEBUG - m_nDETAIL_BLEND_MODE = 0; -#ifdef _DEBUG - m_bSEAMLESS_BASE = false; -#endif // _DEBUG - m_nSEAMLESS_BASE = 0; -#ifdef _DEBUG - m_bSEAMLESS_DETAIL = false; -#endif // _DEBUG - m_nSEAMLESS_DETAIL = 0; -#ifdef _DEBUG - m_bDISTANCEALPHA = false; -#endif // _DEBUG - m_nDISTANCEALPHA = 0; -#ifdef _DEBUG - m_bDISTANCEALPHAFROMDETAIL = false; -#endif // _DEBUG - m_nDISTANCEALPHAFROMDETAIL = 0; -#ifdef _DEBUG - m_bSOFT_MASK = false; -#endif // _DEBUG - m_nSOFT_MASK = 0; -#ifdef _DEBUG - m_bOUTLINE = false; -#endif // _DEBUG - m_nOUTLINE = 0; -#ifdef _DEBUG - m_bOUTER_GLOW = false; -#endif // _DEBUG - m_nOUTER_GLOW = 0; -#ifdef _DEBUG - m_bFLASHLIGHTDEPTHFILTERMODE = false; -#endif // _DEBUG - m_nFLASHLIGHTDEPTHFILTERMODE = 0; -#ifdef _DEBUG - m_bDEPTHBLEND = false; -#endif // _DEBUG - m_nDEPTHBLEND = 0; -#ifdef _DEBUG - m_bBLENDTINTBYBASEALPHA = false; -#endif // _DEBUG - m_nBLENDTINTBYBASEALPHA = 0; -#ifdef _DEBUG - m_bCUBEMAP_SPHERE_LEGACY = false; -#endif // _DEBUG - m_nCUBEMAP_SPHERE_LEGACY = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; - Assert( bAllStaticVarsDefined ); -#endif // _DEBUG - return ( 24 * m_nDETAILTEXTURE ) + ( 48 * m_nCUBEMAP ) + ( 96 * m_nDIFFUSELIGHTING ) + ( 192 * m_nENVMAPMASK ) + ( 384 * m_nBASEALPHAENVMAPMASK ) + ( 768 * m_nSELFILLUM ) + ( 1536 * m_nVERTEXCOLOR ) + ( 3072 * m_nFLASHLIGHT ) + ( 6144 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 12288 * m_nDETAIL_BLEND_MODE ) + ( 122880 * m_nSEAMLESS_BASE ) + ( 245760 * m_nSEAMLESS_DETAIL ) + ( 491520 * m_nDISTANCEALPHA ) + ( 983040 * m_nDISTANCEALPHAFROMDETAIL ) + ( 1966080 * m_nSOFT_MASK ) + ( 3932160 * m_nOUTLINE ) + ( 7864320 * m_nOUTER_GLOW ) + ( 15728640 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 47185920 * m_nDEPTHBLEND ) + ( 94371840 * m_nBLENDTINTBYBASEALPHA ) + ( 188743680 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; - } -}; -#define shaderStaticTest_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 -class vertexlit_and_unlit_generic_ps30_Dynamic_Index -{ -private: - int m_nLIGHTING_PREVIEW; -#ifdef _DEBUG - bool m_bLIGHTING_PREVIEW; -#endif -public: - void SetLIGHTING_PREVIEW( int i ) - { - Assert( i >= 0 && i <= 2 ); - m_nLIGHTING_PREVIEW = i; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } - void SetLIGHTING_PREVIEW( bool i ) - { - m_nLIGHTING_PREVIEW = i ? 1 : 0; -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = true; -#endif - } -private: - int m_nFLASHLIGHTSHADOWS; -#ifdef _DEBUG - bool m_bFLASHLIGHTSHADOWS; -#endif -public: - void SetFLASHLIGHTSHADOWS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nFLASHLIGHTSHADOWS = i; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } - void SetFLASHLIGHTSHADOWS( bool i ) - { - m_nFLASHLIGHTSHADOWS = i ? 1 : 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = true; -#endif - } -private: - int m_nSTATIC_LIGHT_LIGHTMAP; -#ifdef _DEBUG - bool m_bSTATIC_LIGHT_LIGHTMAP; -#endif -public: - void SetSTATIC_LIGHT_LIGHTMAP( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nSTATIC_LIGHT_LIGHTMAP = i; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } - void SetSTATIC_LIGHT_LIGHTMAP( bool i ) - { - m_nSTATIC_LIGHT_LIGHTMAP = i ? 1 : 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = true; -#endif - } -private: - int m_nDEBUG_LUXELS; -#ifdef _DEBUG - bool m_bDEBUG_LUXELS; -#endif -public: - void SetDEBUG_LUXELS( int i ) - { - Assert( i >= 0 && i <= 1 ); - m_nDEBUG_LUXELS = i; -#ifdef _DEBUG - m_bDEBUG_LUXELS = true; -#endif - } - void SetDEBUG_LUXELS( bool i ) - { - m_nDEBUG_LUXELS = i ? 1 : 0; -#ifdef _DEBUG - m_bDEBUG_LUXELS = true; -#endif - } -public: - vertexlit_and_unlit_generic_ps30_Dynamic_Index() - { -#ifdef _DEBUG - m_bLIGHTING_PREVIEW = false; -#endif // _DEBUG - m_nLIGHTING_PREVIEW = 0; -#ifdef _DEBUG - m_bFLASHLIGHTSHADOWS = false; -#endif // _DEBUG - m_nFLASHLIGHTSHADOWS = 0; -#ifdef _DEBUG - m_bSTATIC_LIGHT_LIGHTMAP = false; -#endif // _DEBUG - m_nSTATIC_LIGHT_LIGHTMAP = 0; -#ifdef _DEBUG - m_bDEBUG_LUXELS = false; -#endif // _DEBUG - m_nDEBUG_LUXELS = 0; - } - int GetIndex() - { - // Asserts to make sure that we aren't using any skipped combinations. - // Asserts to make sure that we are setting all of the combination vars. -#ifdef _DEBUG - bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS && m_bSTATIC_LIGHT_LIGHTMAP && m_bDEBUG_LUXELS; - Assert( bAllDynamicVarsDefined ); -#endif // _DEBUG - return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + ( 6 * m_nSTATIC_LIGHT_LIGHTMAP ) + ( 12 * m_nDEBUG_LUXELS ) + 0; - } -}; -#define shaderDynamicTest_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_STATIC_LIGHT_LIGHTMAP + psh_forgot_to_set_dynamic_DEBUG_LUXELS + 0 diff --git a/materialsystem/stdshaders/game_shader_dx9_30.txt b/materialsystem/stdshaders/game_shader_dx9_30.txt new file mode 100644 index 00000000..dc92e05d --- /dev/null +++ b/materialsystem/stdshaders/game_shader_dx9_30.txt @@ -0,0 +1,129 @@ +// +// vs 3.0 ps 3.0 shaders collection +// +// These shaders are forced to compile as shader model 3.0 +// using the new compiler. +// _ps30.vcs +// _vs30.vcs +// + +// Base shaders +depth_of_field_ps30.fxc +depth_of_field_vs30.fxc +sdk_bloom_ps30.fxc +sdk_bloomadd_ps30.fxc +sdk_blurgaussian_3x3_ps30.fxc +sdk_cloak_blended_pass_ps30.fxc +sdk_cloak_blended_pass_vs30.fxc +sdk_core_ps30.fxc +sdk_core_vs30.fxc +sdk_decalmodulate_ps30.fxc +sdk_decalmodulate_vs30.fxc +sdk_depthwrite_ps30.fxc +sdk_depthwrite_vs30.fxc +sdk_emissive_scroll_blended_pass_ps30.fxc +sdk_emissive_scroll_blended_pass_vs30.fxc +sdk_engine_post_ps30.fxc +sdk_eye_refract_ps30.fxc +sdk_eye_refract_vs30.fxc +sdk_eyeglint_ps30.fxc +sdk_eyeglint_vs30.fxc +sdk_eyes_flashlight_ps30.fxc +sdk_eyes_flashlight_vs30.fxc +sdk_eyes_ps30.fxc +sdk_eyes_vs30.fxc +sdk_flesh_interior_blended_pass_ps30.fxc +sdk_flesh_interior_blended_pass_vs30.fxc +sdk_lightmappedgeneric_decal_ps2x.fxc +sdk_lightmappedgeneric_decal_vs20.fxc +sdk_lightmappedgeneric_flashlight_ps2x.fxc +sdk_lightmappedgeneric_flashlight_vs20.fxc +SDK_lightmappedgeneric_ps20b.fxc +sdk_lightmappedgeneric_vs20.fxc +sdk_lightmappedreflective_ps30.fxc +sdk_lightmappedreflective_vs30.fxc +sdk_monitorscreen_ps30.fxc +sdk_refract_ps30.fxc +sdk_refract_vs30.fxc +sdk_screenspaceeffect_vs30.fxc +sdk_shatteredglass_ps30.fxc +sdk_shatteredglass_vs30.fxc +sdk_skin_ps30.fxc +sdk_skin_vs30.fxc +sdk_splinerope_ps30.fxc +sdk_splinerope_vs30.fxc +sdk_sprite_ps30.fxc +sdk_sprite_vs30.fxc +sdk_teeth_bump_ps30.fxc +sdk_teeth_bump_vs30.fxc +sdk_teeth_flashlight_ps30.fxc +sdk_teeth_flashlight_vs30.fxc +sdk_teeth_ps30.fxc +sdk_teeth_vs30.fxc +sdk_unlitgeneric_ps30.fxc +sdk_unlitgeneric_vs30.fxc +sdk_unlittwotexture_ps30.fxc +sdk_unlittwotexture_vs30.fxc +sdk_vertexlit_and_unlit_generic_bump_ps2x.fxc +sdk_vertexlit_and_unlit_generic_bump_ps20b.fxc +sdk_vertexlit_and_unlit_generic_bump_vs20.fxc +sdk_vertexlit_and_unlit_generic_ps2x.fxc +sdk_vertexlit_and_unlit_generic_ps20b.fxc +sdk_vertexlit_and_unlit_generic_vs20.fxc +sdk_water_ps30.fxc +sdk_water_vs30.fxc +sdk_watercheap_ps30.fxc +sdk_watercheap_vs30.fxc +sdk_windowimposter_ps30.fxc +sdk_windowimposter_vs30.fxc +sdk_worldtwotextureblend_ps30.fxc + +// Vance shaders +basicsample_ps30.fxc +bicubicsample_ps30.fxc +bilinearsample_ps30.fxc +chromatic_ps30.fxc +chromatic_vs30.fxc +deferred_composite_ps30.fxc +deferred_composite_vs30.fxc +deferred_csm_ps30.fxc +//deferred_pointlights_ps30.fxc +deferred_sky_ps30.fxc +//deferred_spotlight_ps30.fxc +//deferred_spotlight_shadow_ps30.fxc +deferred_volumetricfog_ps30.fxc +fxaa_ps30.fxc +fxaa_vs30.fxc +gaussian_depthaware_ps30.fxc +gaussian_depthaware_roughness_ps30.fxc +gaussianx_ps30.fxc +gaussiany_ps30.fxc +light_mesh_ps30.fxc +light_mesh_vs30.fxc +light_volumetrics_ps30.fxc +light_volumetrics_vs30.fxc +lightmappedpbr_ps30.fxc +lightmappedpbr_vs30.fxc +lightpass_ps30.fxc +lightpass_vs30.fxc +luma_ps30.fxc +normalmapreconstruct_ps30.fxc +passthru_vs30.fxc +screenwater_ps30.fxc +screenwater_vs30.fxc +skydome_ps30.fxc +skydome_vs30.fxc +ssgi_combine_ps30.fxc +ssgi_ps30.fxc +ssr_ps30.fxc +unsharp_blur_ps30.fxc +unsharp_blur_vs30.fxc +unsharp_ps30.fxc +unsharp_vs30.fxc +vance_bloom_combine_ps30.fxc +vance_scope_ps30.fxc +vance_scope_vs30.fxc +vance_tonemap_ps30.fxc +vertexlitpbr_ps30.fxc +vertexlitpbr_vs30.fxc + diff --git a/materialsystem/stdshaders/game_shader_dx9_base.vpc b/materialsystem/stdshaders/game_shader_dx9_base.vpc index ac909e3b..980c0943 100644 --- a/materialsystem/stdshaders/game_shader_dx9_base.vpc +++ b/materialsystem/stdshaders/game_shader_dx9_base.vpc @@ -31,17 +31,16 @@ $Configuration { $Compiler { - $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX] -// $AdditionalIncludeDirectories "$BASE;..\..\dx9sdk\include" [$WIN32] - $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360] + $AdditionalIncludeDirectories "$BASE;include" $PreprocessorDefinitions "$BASE;STDSHADER_DX9_DLL_EXPORT;FAST_MATERIALVAR_ACCESS;GAME_SHADER_DLL" $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL] + $PreprocessorDefinitions "$BASE;PARALLAX_CORRECTED_CUBEMAPS" } $Linker { $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32] - $SystemLibraries "iconv" [$OSXALL] + $SystemLibraries "iconv" [$OSXALL] } } @@ -49,42 +48,25 @@ $Project { $Folder "Source Files" { - $File "BaseVSShader.cpp" + $File "basevsshader.cpp" - $File "example_model_dx9.cpp" - $File "example_model_dx9_helper.cpp" - - $File "Bloom.cpp" - $File "screenspace_general.cpp" + $Folder "Verify" [$WINDOWS] + { + $File "verification/shader_dll_verify.cpp" [$WINDOWS] + $File "verification/shader_dll_verify.h" [$WINDOWS] + } } $Folder "Header Files" { - $File "BaseVSShader.h" - $File "common_fxc.h" - $File "common_hlsl_cpp_consts.h" - $File "common_ps_fxc.h" - $File "common_vertexlitgeneric_dx9.h" - $File "common_vs_fxc.h" + $File "basevsshader.h" $File "shader_constant_register_map.h" - - $File "example_model_dx9_helper.h" - } - - $Folder "Link Libraries" [$WIN32] - { -// $File "$SRCDIR\dx9sdk\lib\d3dx9.lib" } $Folder "Link Libraries" { $Lib mathlib $Lib shaderlib - } - - $File "_buildallshaders.bat" - $File "_buildshaders.bat" - - $Shaders "_shaderlist_dx9_20b.txt" - $Shaders "_shaderlist_dx9_30.txt" + $Lib tier2 + } } diff --git a/materialsystem/stdshaders/game_shader_dx9_episodic.vpc b/materialsystem/stdshaders/game_shader_dx9_episodic.vpc new file mode 100644 index 00000000..cd6fa1ba --- /dev/null +++ b/materialsystem/stdshaders/game_shader_dx9_episodic.vpc @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// game_shader_dx9.vpc +// +// Project Script for mods to use an an example of how to override shaders +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "mod_episodic" +$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" + +$Project "Shaders (Episodic)" +{ +} \ No newline at end of file diff --git a/materialsystem/stdshaders/game_shader_dx9_hl2.vpc b/materialsystem/stdshaders/game_shader_dx9_hl2.vpc new file mode 100644 index 00000000..740844e4 --- /dev/null +++ b/materialsystem/stdshaders/game_shader_dx9_hl2.vpc @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// game_shader_dx9.vpc +// +// Project Script for mods to use an an example of how to override shaders +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "mod_hl2" +$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" + +$Project "Shaders (HL2)" +{ +} \ No newline at end of file diff --git a/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc b/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc deleted file mode 100644 index dee82199..00000000 --- a/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc +++ /dev/null @@ -1,13 +0,0 @@ -//----------------------------------------------------------------------------- -// game_shader_dx9.vpc -// -// Project Script for mods to use an an example of how to override shaders -//----------------------------------------------------------------------------- - -$Macro SRCDIR "..\.." -$Macro GAMENAME "mod_hl2mp" -$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" - -$Project "Shaders (HL2MP)" -{ -} \ No newline at end of file diff --git a/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc b/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc new file mode 100644 index 00000000..b2d501d9 --- /dev/null +++ b/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// game_shader_dx9_mapbase.vpc +// +// Project Script for Mapbase shader changes +//----------------------------------------------------------------------------- + +$Configuration +{ + $Compiler + { + // https://developer.valvesoftware.com/wiki/Parallax_Corrected_Cubemaps + $PreprocessorDefinitions "$BASE;PARALLAX_CORRECTED_CUBEMAPS" + } +} + +$Project +{ + $Folder "Source Files" + { + $File "bloom.cpp" + $File "screenspace_general.cpp" + $File "cloak_blended_pass_helper.cpp" + $File "common_flashlight_fxc.h" + $File "core.cpp" + $File "decalmodulate.cpp" + $File "depthoffield.cpp" + $File "depthwrite.cpp" + $File "emissive_scroll_blended_pass_helper.cpp" + $File "engine_post.cpp" + $File "eye_refract_helper.cpp" + $File "eye_refract.cpp" + $File "eyeball.cpp" + $File "eyeglint.cpp" + $File "eyes_helper.cpp" + $File "eyes.cpp" + $File "flesh_interior_blended_pass_helper.cpp" + $File "lightmappedgeneric_helper.cpp" + $File "lightmappedgeneric_helper.h" + $File "lightmappedgeneric.cpp" + $File "lightmappedgeneric_ps2_3_x.h" + $File "lightmappedreflective.cpp" + $File "monitorscreen.cpp" + $File "refract_helper.cpp" + $File "refract.cpp" + $File "shatteredglass.cpp" + $File "skin_helper.cpp" + $File "splinerope.cpp" + $File "sprite.cpp" + $File "teeth.cpp" + $File "unlitgeneric.cpp" + $File "unlittwotexture.cpp" + $File "vertexlitgeneric_helper.cpp" + $File "vertexlitgeneric.cpp" + $File "water.cpp" + $File "windowimposter_dx90.cpp" + $File "worldtwotextureblend.cpp" + } + + $Shaders "game_shader_dx9_30.txt" +} diff --git a/materialsystem/stdshaders/game_shader_dx9_vance.vpc b/materialsystem/stdshaders/game_shader_dx9_vance.vpc index f98cae65..d7351141 100644 --- a/materialsystem/stdshaders/game_shader_dx9_vance.vpc +++ b/materialsystem/stdshaders/game_shader_dx9_vance.vpc @@ -5,7 +5,7 @@ //----------------------------------------------------------------------------- $Macro SRCDIR "..\.." -$Macro GAMENAME "VANCE" +$Macro GAMENAME "vance" $Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" $Configuration @@ -21,6 +21,40 @@ $Project "Shaders (VANCE)" { $Folder "Source Files" { + $File "bloom.cpp" + $File "screenspace_general.cpp" + $File "cloak_blended_pass_helper.cpp" + $File "core.cpp" + $File "decalmodulate.cpp" + $File "depthoffield.cpp" + $File "depthwrite.cpp" + $File "emissive_scroll_blended_pass_helper.cpp" + $File "engine_post.cpp" + $File "eye_refract_helper.cpp" + $File "eye_refract.cpp" + $File "eyeglint.cpp" + $File "eyes_helper.cpp" + $File "eyes.cpp" + $File "flesh_interior_blended_pass_helper.cpp" + $File "lightmappedgeneric_helper.cpp" + $File "lightmappedgeneric_helper.h" + $File "lightmappedgeneric.cpp" + $File "lightmappedreflective.cpp" + $File "monitorscreen.cpp" + $File "refract_helper.cpp" + $File "refract.cpp" + $File "shatteredglass.cpp" + $File "skin_helper.cpp" + $File "splinerope.cpp" + $File "sprite.cpp" + $File "teeth.cpp" + $File "unlitgeneric.cpp" + $File "unlittwotexture.cpp" + $File "vertexlitgeneric_helper.cpp" + $File "vertexlitgeneric.cpp" + $File "water.cpp" + $File "windowimposter.cpp" + $File "worldtwotextureblend.cpp" $Folder "Post-processing" { @@ -35,42 +69,28 @@ $Project "Shaders (VANCE)" $File "vance/unsharp_blur.cpp" $File "vance/luma.cpp" $File "vance/tonemap.cpp" - $File "vance/Bloom_combine.cpp" + $File "vance/bloom_combine.cpp" $File "vance/ssao_combine.cpp" - $File "vance/SSGI.cpp" + $File "vance/ssgi.cpp" $File "vance/skydome_atmosphere.cpp" $File "vance/skydome_atmosphere_helper.cpp" $File "vance/skydome_atmosphere_helper.h" } - - $File "lightmappedgeneric_dx9.cpp" - $File "lightmappedgeneric_dx9_helper.cpp" - $File "lightmappedgeneric_dx9_helper.h" - $File "worldvertextransition.cpp" - - $File "vertexlitgeneric_dx9.cpp" - $File "vertexlitgeneric_dx9_helper.cpp" - $File "vertexlitgeneric_dx9_helper.h" - - $File "VertexlitPBR_dx9.cpp" - $File "VertexlitPBR_dx9_helper.cpp" - $File "VertexlitPBR_dx9_helper.h" - - $File "LightmappedPBR_dx9.cpp" - $File "LightmappedPBR_dx9_helper.cpp" - $File "LightmappedPBR_dx9_helper.h" - - $File "lightpass_helper.cpp" - $File "lightpass_helper.h" - $File "light_volumetrics.cpp" - $File "vance_scope_dx9.cpp" - $File "deferred/IDeferredExt.cpp" + $File "vance/vertexlitpbr.cpp" + $File "vance/vertexlitpbr_helper.cpp" + $File "vance/vertexlitpbr_helper.h" + $File "vance/lightmappedpbr.cpp" + $File "vance/lightmappedpbr_helper.cpp" + $File "vance/lightmappedpbr_helper.h" + $File "vance/lightpass_helper.cpp" + $File "vance/lightpass_helper.h" + $File "vance/light_volumetrics.cpp" + $File "vance/vance_scope.cpp" $File "vance/light_mesh.cpp" - - -$File "example_model_dx9.cpp" - -$File "example_model_dx9_helper.cpp" - -$File "Bloom.cpp" + $File "deferred/ideferredext.cpp" } -} \ No newline at end of file + + $Shaders "game_shader_dx9_30.txt" +} diff --git a/materialsystem/stdshaders/gaussianx_ps2x.fxc b/materialsystem/stdshaders/gaussianx_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/gaussianx_ps2x.fxc rename to materialsystem/stdshaders/gaussianx_ps30.fxc diff --git a/materialsystem/stdshaders/gaussiany_ps2x.fxc b/materialsystem/stdshaders/gaussiany_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/gaussiany_ps2x.fxc rename to materialsystem/stdshaders/gaussiany_ps30.fxc diff --git a/materialsystem/stdshaders/gbuffer_vs30.fxc b/materialsystem/stdshaders/gbuffer_vs30.fxc index eb787d00..8871a9a1 100644 --- a/materialsystem/stdshaders/gbuffer_vs30.fxc +++ b/materialsystem/stdshaders/gbuffer_vs30.fxc @@ -6,27 +6,26 @@ // STATIC: "MODEL" "0..1" // STATIC: "TANGENTSPACE" "0..1" -// STATIC: "MORPHING_VTEX" "0..1" // STATIC: "VERTEXCOLOR" "0..1" // STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" -// STATIC: "SEAMLESS" "0..1" +// STATIC: "SEAMLESS" "0..1" // DYNAMIC: "COMPRESSED_VERTS" "0..1" // DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" + +// SKIP: $MORPHING && ( $MODEL == 0 ) #include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" static const bool g_bSkinning = SKINNING ? true : false; static const bool g_bVertexColor = VERTEXCOLOR; static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; -#if MODEL - +#if ( MORPHING ) const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); sampler2D morphSampler : register( s0 ); - #endif #if SEAMLESS @@ -59,7 +58,10 @@ struct VS_INPUT float4 vTexCoord2 : TEXCOORD2; float4 vPosFlex : POSITION1; float4 vNormalFlex : NORMAL1; + +#if ( MORPHING ) float vVertexID : POSITION2; +#endif #else @@ -111,7 +113,10 @@ VS_OUTPUT main( const VS_INPUT In ) DecompressVertex_NormalTangent( In.vNormal, In.vUserData, vNormal, vTangentMixed ); -#if MORPHING +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), + vObjPosition.xyz, vObjNormal, vObjTangent.xyz ); +#else ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal, vTangentMixed.xyz ); #endif @@ -125,7 +130,10 @@ VS_OUTPUT main( const VS_INPUT In ) #else // TANGENTSPACE DecompressVertex_Normal( In.vNormal, vNormal ); -#if MORPHING +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, In.vVertexID, float3( 0, 0, 0 ), + vObjPosition.xyz, vObjNormal ); +#else ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal ); #endif diff --git a/materialsystem/stdshaders/genwaterloop.pl b/materialsystem/stdshaders/genwaterloop.pl deleted file mode 100644 index 64ad0658..00000000 --- a/materialsystem/stdshaders/genwaterloop.pl +++ /dev/null @@ -1,9 +0,0 @@ -for($ix=-2;$ix<=2;$ix++) -{ - for($iy=-2;$iy<=2;$iy++) - { - print "vRefractColor += tex2D( RefractSampler, vRefractTexCoord + $ix * ddx1 + $iy * ddy1 );\n"; - $sumweights+=1; - } -} -print "float sumweights = $sumweights;\n"; diff --git a/materialsystem/stdshaders/include/basicsample_ps30.inc b/materialsystem/stdshaders/include/basicsample_ps30.inc new file mode 100644 index 00000000..c6ab27ff --- /dev/null +++ b/materialsystem/stdshaders/include/basicsample_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class basicsample_ps30_Static_Index +{ +public: + basicsample_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_basicsample_ps30 1 + + +class basicsample_ps30_Dynamic_Index +{ +public: + basicsample_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_basicsample_ps30 1 + diff --git a/materialsystem/stdshaders/include/bicubicsample_ps30.inc b/materialsystem/stdshaders/include/bicubicsample_ps30.inc new file mode 100644 index 00000000..692a5633 --- /dev/null +++ b/materialsystem/stdshaders/include/bicubicsample_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class bicubicsample_ps30_Static_Index +{ +public: + bicubicsample_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_bicubicsample_ps30 1 + + +class bicubicsample_ps30_Dynamic_Index +{ +public: + bicubicsample_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_bicubicsample_ps30 1 + diff --git a/materialsystem/stdshaders/include/bilinearsample_ps30.inc b/materialsystem/stdshaders/include/bilinearsample_ps30.inc new file mode 100644 index 00000000..ed19f3b2 --- /dev/null +++ b/materialsystem/stdshaders/include/bilinearsample_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class bilinearsample_ps30_Static_Index +{ +public: + bilinearsample_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_bilinearsample_ps30 1 + + +class bilinearsample_ps30_Dynamic_Index +{ +public: + bilinearsample_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_bilinearsample_ps30 1 + diff --git a/materialsystem/stdshaders/include/chromatic_ps30.inc b/materialsystem/stdshaders/include/chromatic_ps30.inc new file mode 100644 index 00000000..74d30499 --- /dev/null +++ b/materialsystem/stdshaders/include/chromatic_ps30.inc @@ -0,0 +1,60 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class chromatic_ps30_Static_Index +{ +public: + chromatic_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_chromatic_ps30 1 + + +class chromatic_ps30_Dynamic_Index +{ + unsigned int m_nRADIAL : 2; +#ifdef _DEBUG + bool m_bRADIAL : 1; +#endif // _DEBUG +public: + void SetRADIAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRADIAL = i; +#ifdef _DEBUG + m_bRADIAL = true; +#endif // _DEBUG + } + + chromatic_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nRADIAL = 0; +#ifdef _DEBUG + m_bRADIAL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bRADIAL ); + return ( 1 * m_nRADIAL ) + 0; + } +}; + +#define shaderDynamicTest_chromatic_ps30 psh_forgot_to_set_dynamic_RADIAL + diff --git a/materialsystem/stdshaders/include/chromatic_vs30.inc b/materialsystem/stdshaders/include/chromatic_vs30.inc new file mode 100644 index 00000000..07c5750a --- /dev/null +++ b/materialsystem/stdshaders/include/chromatic_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class chromatic_vs30_Static_Index +{ +public: + chromatic_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_chromatic_vs30 1 + + +class chromatic_vs30_Dynamic_Index +{ +public: + chromatic_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_chromatic_vs30 1 + diff --git a/materialsystem/stdshaders/include/deferred_composite_ps30.inc b/materialsystem/stdshaders/include/deferred_composite_ps30.inc new file mode 100644 index 00000000..9695c41b --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_composite_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_composite_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_composite_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_composite_ps30 1 + + +class deferred_composite_ps30_Dynamic_Index +{ +public: + deferred_composite_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_composite_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_composite_vs30.inc b/materialsystem/stdshaders/include/deferred_composite_vs30.inc new file mode 100644 index 00000000..21ae7193 --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_composite_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class deferred_composite_vs30_Static_Index +{ +public: + deferred_composite_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_deferred_composite_vs30 1 + + +class deferred_composite_vs30_Dynamic_Index +{ +public: + deferred_composite_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_composite_vs30 1 + diff --git a/materialsystem/stdshaders/include/deferred_csm_ps30.inc b/materialsystem/stdshaders/include/deferred_csm_ps30.inc new file mode 100644 index 00000000..f7e97b6f --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_csm_ps30.inc @@ -0,0 +1,57 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_csm_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_csm_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_csm_ps30 1 + + +class deferred_csm_ps30_Dynamic_Index +{ +public: + deferred_csm_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_csm_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_pointlights_ps30.inc b/materialsystem/stdshaders/include/deferred_pointlights_ps30.inc new file mode 100644 index 00000000..ced83baf --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_pointlights_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_pointlights_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_pointlights_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_pointlights_ps30 1 + + +class deferred_pointlights_ps30_Dynamic_Index +{ +public: + deferred_pointlights_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_pointlights_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_sky_ps30.inc b/materialsystem/stdshaders/include/deferred_sky_ps30.inc new file mode 100644 index 00000000..d5915f7e --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_sky_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_sky_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_sky_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_sky_ps30 1 + + +class deferred_sky_ps30_Dynamic_Index +{ +public: + deferred_sky_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_sky_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_spotlight_ps30.inc b/materialsystem/stdshaders/include/deferred_spotlight_ps30.inc new file mode 100644 index 00000000..295233d5 --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_spotlight_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_spotlight_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_spotlight_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_spotlight_ps30 1 + + +class deferred_spotlight_ps30_Dynamic_Index +{ +public: + deferred_spotlight_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_spotlight_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_spotlight_shadow_ps30.inc b/materialsystem/stdshaders/include/deferred_spotlight_shadow_ps30.inc new file mode 100644 index 00000000..20bc8cfc --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_spotlight_shadow_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_spotlight_shadow_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_spotlight_shadow_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_spotlight_shadow_ps30 1 + + +class deferred_spotlight_shadow_ps30_Dynamic_Index +{ +public: + deferred_spotlight_shadow_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_deferred_spotlight_shadow_ps30 1 + diff --git a/materialsystem/stdshaders/include/deferred_volumetricfog_ps30.inc b/materialsystem/stdshaders/include/deferred_volumetricfog_ps30.inc new file mode 100644 index 00000000..d3f0c688 --- /dev/null +++ b/materialsystem/stdshaders/include/deferred_volumetricfog_ps30.inc @@ -0,0 +1,88 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class deferred_volumetricfog_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + deferred_volumetricfog_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_deferred_volumetricfog_ps30 1 + + +class deferred_volumetricfog_ps30_Dynamic_Index +{ + unsigned int m_nFOG : 2; + unsigned int m_nCSM : 2; +#ifdef _DEBUG + bool m_bFOG : 1; + bool m_bCSM : 1; +#endif // _DEBUG +public: + void SetFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFOG = i; +#ifdef _DEBUG + m_bFOG = true; +#endif // _DEBUG + } + + void SetCSM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCSM = i; +#ifdef _DEBUG + m_bCSM = true; +#endif // _DEBUG + } + + deferred_volumetricfog_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nFOG = 0; + m_nCSM = 0; +#ifdef _DEBUG + m_bFOG = false; + m_bCSM = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFOG && m_bCSM ); + return ( 1 * m_nFOG ) + ( 2 * m_nCSM ) + 0; + } +}; + +#define shaderDynamicTest_deferred_volumetricfog_ps30 psh_forgot_to_set_dynamic_FOG + psh_forgot_to_set_dynamic_CSM + diff --git a/materialsystem/stdshaders/include/depth_of_field_ps30.inc b/materialsystem/stdshaders/include/depth_of_field_ps30.inc new file mode 100644 index 00000000..94b8b27b --- /dev/null +++ b/materialsystem/stdshaders/include/depth_of_field_ps30.inc @@ -0,0 +1,60 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class depth_of_field_ps30_Static_Index +{ +public: + depth_of_field_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_depth_of_field_ps30 1 + + +class depth_of_field_ps30_Dynamic_Index +{ + unsigned int m_nQUALITY : 3; +#ifdef _DEBUG + bool m_bQUALITY : 1; +#endif // _DEBUG +public: + void SetQUALITY( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nQUALITY = i; +#ifdef _DEBUG + m_bQUALITY = true; +#endif // _DEBUG + } + + depth_of_field_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nQUALITY = 0; +#ifdef _DEBUG + m_bQUALITY = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bQUALITY ); + return ( 1 * m_nQUALITY ) + 0; + } +}; + +#define shaderDynamicTest_depth_of_field_ps30 psh_forgot_to_set_dynamic_QUALITY + diff --git a/materialsystem/stdshaders/include/depth_of_field_vs30.inc b/materialsystem/stdshaders/include/depth_of_field_vs30.inc new file mode 100644 index 00000000..815f4a2a --- /dev/null +++ b/materialsystem/stdshaders/include/depth_of_field_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class depth_of_field_vs30_Static_Index +{ +public: + depth_of_field_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_depth_of_field_vs30 1 + + +class depth_of_field_vs30_Dynamic_Index +{ +public: + depth_of_field_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_depth_of_field_vs30 1 + diff --git a/materialsystem/stdshaders/include/fxaa_ps30.inc b/materialsystem/stdshaders/include/fxaa_ps30.inc new file mode 100644 index 00000000..334d4348 --- /dev/null +++ b/materialsystem/stdshaders/include/fxaa_ps30.inc @@ -0,0 +1,60 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class fxaa_ps30_Static_Index +{ +public: + fxaa_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_fxaa_ps30 1 + + +class fxaa_ps30_Dynamic_Index +{ + unsigned int m_nQUALITY : 3; +#ifdef _DEBUG + bool m_bQUALITY : 1; +#endif // _DEBUG +public: + void SetQUALITY( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nQUALITY = i; +#ifdef _DEBUG + m_bQUALITY = true; +#endif // _DEBUG + } + + fxaa_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nQUALITY = 0; +#ifdef _DEBUG + m_bQUALITY = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bQUALITY ); + return ( 1 * m_nQUALITY ) + 0; + } +}; + +#define shaderDynamicTest_fxaa_ps30 psh_forgot_to_set_dynamic_QUALITY + diff --git a/materialsystem/stdshaders/include/fxaa_vs30.inc b/materialsystem/stdshaders/include/fxaa_vs30.inc new file mode 100644 index 00000000..51b256c1 --- /dev/null +++ b/materialsystem/stdshaders/include/fxaa_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class fxaa_vs30_Static_Index +{ +public: + fxaa_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_fxaa_vs30 1 + + +class fxaa_vs30_Dynamic_Index +{ +public: + fxaa_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_fxaa_vs30 1 + diff --git a/materialsystem/stdshaders/include/gaussian_depthaware_ps30.inc b/materialsystem/stdshaders/include/gaussian_depthaware_ps30.inc new file mode 100644 index 00000000..ec946cf7 --- /dev/null +++ b/materialsystem/stdshaders/include/gaussian_depthaware_ps30.inc @@ -0,0 +1,60 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class gaussian_depthaware_ps30_Static_Index +{ + unsigned int m_nHORIZONTAL : 2; +#ifdef _DEBUG + bool m_bHORIZONTAL : 1; +#endif // _DEBUG +public: + void SetHORIZONTAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHORIZONTAL = i; +#ifdef _DEBUG + m_bHORIZONTAL = true; +#endif // _DEBUG + } + + gaussian_depthaware_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nHORIZONTAL = 0; +#ifdef _DEBUG + m_bHORIZONTAL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHORIZONTAL ); + return ( 1 * m_nHORIZONTAL ) + 0; + } +}; + +#define shaderStaticTest_gaussian_depthaware_ps30 psh_forgot_to_set_static_HORIZONTAL + + +class gaussian_depthaware_ps30_Dynamic_Index +{ +public: + gaussian_depthaware_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_gaussian_depthaware_ps30 1 + diff --git a/materialsystem/stdshaders/include/gaussian_depthaware_roughness_ps30.inc b/materialsystem/stdshaders/include/gaussian_depthaware_roughness_ps30.inc new file mode 100644 index 00000000..c7622918 --- /dev/null +++ b/materialsystem/stdshaders/include/gaussian_depthaware_roughness_ps30.inc @@ -0,0 +1,60 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class gaussian_depthaware_roughness_ps30_Static_Index +{ + unsigned int m_nHORIZONTAL : 2; +#ifdef _DEBUG + bool m_bHORIZONTAL : 1; +#endif // _DEBUG +public: + void SetHORIZONTAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHORIZONTAL = i; +#ifdef _DEBUG + m_bHORIZONTAL = true; +#endif // _DEBUG + } + + gaussian_depthaware_roughness_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nHORIZONTAL = 0; +#ifdef _DEBUG + m_bHORIZONTAL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHORIZONTAL ); + return ( 1 * m_nHORIZONTAL ) + 0; + } +}; + +#define shaderStaticTest_gaussian_depthaware_roughness_ps30 psh_forgot_to_set_static_HORIZONTAL + + +class gaussian_depthaware_roughness_ps30_Dynamic_Index +{ +public: + gaussian_depthaware_roughness_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_gaussian_depthaware_roughness_ps30 1 + diff --git a/materialsystem/stdshaders/include/gaussianx_ps30.inc b/materialsystem/stdshaders/include/gaussianx_ps30.inc new file mode 100644 index 00000000..23e940e3 --- /dev/null +++ b/materialsystem/stdshaders/include/gaussianx_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class gaussianx_ps30_Static_Index +{ +public: + gaussianx_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_gaussianx_ps30 1 + + +class gaussianx_ps30_Dynamic_Index +{ +public: + gaussianx_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_gaussianx_ps30 1 + diff --git a/materialsystem/stdshaders/include/gaussiany_ps30.inc b/materialsystem/stdshaders/include/gaussiany_ps30.inc new file mode 100644 index 00000000..9d4d3ec1 --- /dev/null +++ b/materialsystem/stdshaders/include/gaussiany_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class gaussiany_ps30_Static_Index +{ +public: + gaussiany_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_gaussiany_ps30 1 + + +class gaussiany_ps30_Dynamic_Index +{ +public: + gaussiany_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_gaussiany_ps30 1 + diff --git a/materialsystem/stdshaders/include/light_mesh_ps30.inc b/materialsystem/stdshaders/include/light_mesh_ps30.inc new file mode 100644 index 00000000..e8a21f5f --- /dev/null +++ b/materialsystem/stdshaders/include/light_mesh_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class light_mesh_ps30_Static_Index +{ +public: + light_mesh_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_light_mesh_ps30 1 + + +class light_mesh_ps30_Dynamic_Index +{ +public: + light_mesh_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_light_mesh_ps30 1 + diff --git a/materialsystem/stdshaders/include/light_mesh_vs30.inc b/materialsystem/stdshaders/include/light_mesh_vs30.inc new file mode 100644 index 00000000..cd5d002f --- /dev/null +++ b/materialsystem/stdshaders/include/light_mesh_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class light_mesh_vs30_Static_Index +{ +public: + light_mesh_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_light_mesh_vs30 1 + + +class light_mesh_vs30_Dynamic_Index +{ +public: + light_mesh_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_light_mesh_vs30 1 + diff --git a/materialsystem/stdshaders/include/light_volumetrics_ps30.inc b/materialsystem/stdshaders/include/light_volumetrics_ps30.inc new file mode 100644 index 00000000..e5db1d73 --- /dev/null +++ b/materialsystem/stdshaders/include/light_volumetrics_ps30.inc @@ -0,0 +1,74 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// (CSM == 0) && PERF +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class light_volumetrics_ps30_Static_Index +{ +public: + light_volumetrics_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_light_volumetrics_ps30 1 + + +class light_volumetrics_ps30_Dynamic_Index +{ + unsigned int m_nCSM : 2; + unsigned int m_nPERF : 2; +#ifdef _DEBUG + bool m_bCSM : 1; + bool m_bPERF : 1; +#endif // _DEBUG +public: + void SetCSM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCSM = i; +#ifdef _DEBUG + m_bCSM = true; +#endif // _DEBUG + } + + void SetPERF( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nPERF = i; +#ifdef _DEBUG + m_bPERF = true; +#endif // _DEBUG + } + + light_volumetrics_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCSM = 0; + m_nPERF = 0; +#ifdef _DEBUG + m_bCSM = false; + m_bPERF = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCSM && m_bPERF ); + return ( 1 * m_nCSM ) + ( 2 * m_nPERF ) + 0; + } +}; + +#define shaderDynamicTest_light_volumetrics_ps30 psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_PERF + diff --git a/materialsystem/stdshaders/include/light_volumetrics_vs30.inc b/materialsystem/stdshaders/include/light_volumetrics_vs30.inc new file mode 100644 index 00000000..6e16fa72 --- /dev/null +++ b/materialsystem/stdshaders/include/light_volumetrics_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class light_volumetrics_vs30_Static_Index +{ +public: + light_volumetrics_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_light_volumetrics_vs30 1 + + +class light_volumetrics_vs30_Dynamic_Index +{ +public: + light_volumetrics_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_light_volumetrics_vs30 1 + diff --git a/materialsystem/stdshaders/include/lightmappedpbr_ps30.inc b/materialsystem/stdshaders/include/lightmappedpbr_ps30.inc new file mode 100644 index 00000000..112ac3f3 --- /dev/null +++ b/materialsystem/stdshaders/include/lightmappedpbr_ps30.inc @@ -0,0 +1,267 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW +// ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $CUBEMAP == 0 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) +// ( $FLASHLIGHT == 1 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) +// ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) +// ( $FLASHLIGHT == 1) && ( $CSM == 1) +// $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class lightmappedpbr_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 1; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nCUBEMAP_SPHERE_LEGACY : 2; + unsigned int m_nSMOOTHNESS : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nBUMPMAP : 2; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB : 1; + bool m_bFLASHLIGHT : 1; + bool m_bCUBEMAP : 1; + bool m_bCUBEMAP_SPHERE_LEGACY : 1; + bool m_bSMOOTHNESS : 1; + bool m_bSEAMLESS : 1; + bool m_bBUMPMAP : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif // _DEBUG + } + + void SetSMOOTHNESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSMOOTHNESS = i; +#ifdef _DEBUG + m_bSMOOTHNESS = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + lightmappedpbr_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = 0; + m_nFLASHLIGHT = 0; + m_nCUBEMAP = 0; + m_nCUBEMAP_SPHERE_LEGACY = 0; + m_nSMOOTHNESS = 0; + m_nSEAMLESS = 0; + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; + m_bFLASHLIGHT = false; + m_bCUBEMAP = false; + m_bCUBEMAP_SPHERE_LEGACY = false; + m_bSMOOTHNESS = false; + m_bSEAMLESS = false; + m_bBUMPMAP = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS && m_bSEAMLESS && m_bBUMPMAP ); + AssertMsg( !( ( m_nCUBEMAP == 1 ) && ( m_nFLASHLIGHT == 1 ) ), "Invalid combo combination ( ( CUBEMAP == 1 ) && ( FLASHLIGHT == 1 ) )" ); + AssertMsg( !( m_nCUBEMAP_SPHERE_LEGACY && ( m_nCUBEMAP == 0 ) ), "Invalid combo combination ( CUBEMAP_SPHERE_LEGACY && ( CUBEMAP == 0 ) )" ); + return ( 576 * m_nCONVERT_TO_SRGB ) + ( 576 * m_nFLASHLIGHT ) + ( 1152 * m_nCUBEMAP ) + ( 2304 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 4608 * m_nSMOOTHNESS ) + ( 9216 * m_nSEAMLESS ) + ( 18432 * m_nBUMPMAP ) + 0; + } +}; + +#define shaderStaticTest_lightmappedpbr_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMAP + + +class lightmappedpbr_ps30_Dynamic_Index +{ + unsigned int m_nWRITEWATERFOGTODESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; + unsigned int m_nCUBEMAPCORRECTED : 2; + unsigned int m_nCSM : 2; + unsigned int m_nCSM_PERF : 2; + unsigned int m_nLIGHT_PREVIEW : 2; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bFLASHLIGHTSHADOWS : 1; + bool m_bCUBEMAPCORRECTED : 1; + bool m_bCSM : 1; + bool m_bCSM_PERF : 1; + bool m_bLIGHT_PREVIEW : 1; +#endif // _DEBUG +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + void SetCUBEMAPCORRECTED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAPCORRECTED = i; +#ifdef _DEBUG + m_bCUBEMAPCORRECTED = true; +#endif // _DEBUG + } + + void SetCSM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCSM = i; +#ifdef _DEBUG + m_bCSM = true; +#endif // _DEBUG + } + + void SetCSM_PERF( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nCSM_PERF = i; +#ifdef _DEBUG + m_bCSM_PERF = true; +#endif // _DEBUG + } + + void SetLIGHT_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHT_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHT_PREVIEW = true; +#endif // _DEBUG + } + + lightmappedpbr_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITEWATERFOGTODESTALPHA = 0; + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nFLASHLIGHTSHADOWS = 0; + m_nCUBEMAPCORRECTED = 0; + m_nCSM = 0; + m_nCSM_PERF = 0; + m_nLIGHT_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bFLASHLIGHTSHADOWS = false; + m_bCUBEMAPCORRECTED = false; + m_bCSM = false; + m_bCSM_PERF = false; + m_bLIGHT_PREVIEW = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bCUBEMAPCORRECTED && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW ); + AssertMsg( !( ( m_nPIXELFOGTYPE == 0 ) && ( m_nWRITEWATERFOGTODESTALPHA != 0 ) ), "Invalid combo combination ( ( PIXELFOGTYPE == 0 ) && ( WRITEWATERFOGTODESTALPHA != 0 ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + ( 16 * m_nCUBEMAPCORRECTED ) + ( 32 * m_nCSM ) + ( 64 * m_nCSM_PERF ) + ( 192 * m_nLIGHT_PREVIEW ) + 0; + } +}; + +#define shaderDynamicTest_lightmappedpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_CUBEMAPCORRECTED + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + diff --git a/materialsystem/stdshaders/include/lightmappedpbr_vs30.inc b/materialsystem/stdshaders/include/lightmappedpbr_vs30.inc new file mode 100644 index 00000000..0e9c2b6a --- /dev/null +++ b/materialsystem/stdshaders/include/lightmappedpbr_vs30.inc @@ -0,0 +1,126 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// !$BUMPMAP && $DIFFUSEBUMPMAP +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class lightmappedpbr_vs30_Static_Index +{ + unsigned int m_nBUMPMAP : 2; + unsigned int m_nDIFFUSEBUMPMAP : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nVERTEXALPHATEXBLENDFACTOR : 2; +#ifdef _DEBUG + bool m_bBUMPMAP : 1; + bool m_bDIFFUSEBUMPMAP : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bVERTEXALPHATEXBLENDFACTOR : 1; +#endif // _DEBUG +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif // _DEBUG + } + + lightmappedpbr_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nBUMPMAP = 0; + m_nDIFFUSEBUMPMAP = 0; + m_nVERTEXCOLOR = 0; + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; + m_bDIFFUSEBUMPMAP = false; + m_bVERTEXCOLOR = false; + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR ); + AssertMsg( !( !m_nBUMPMAP && m_nDIFFUSEBUMPMAP ), "Invalid combo combination ( !BUMPMAP && DIFFUSEBUMPMAP )" ); + return ( 4 * m_nBUMPMAP ) + ( 8 * m_nDIFFUSEBUMPMAP ) + ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nVERTEXALPHATEXBLENDFACTOR ) + 0; + } +}; + +#define shaderStaticTest_lightmappedpbr_vs30 vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + + +class lightmappedpbr_vs30_Dynamic_Index +{ + unsigned int m_nFASTPATH : 2; + unsigned int m_nDOWATERFOG : 2; +#ifdef _DEBUG + bool m_bFASTPATH : 1; + bool m_bDOWATERFOG : 1; +#endif // _DEBUG +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif // _DEBUG + } + + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif // _DEBUG + } + + lightmappedpbr_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nFASTPATH = 0; + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bFASTPATH = false; + m_bDOWATERFOG = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFASTPATH && m_bDOWATERFOG ); + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + 0; + } +}; + +#define shaderDynamicTest_lightmappedpbr_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + diff --git a/materialsystem/stdshaders/include/lightpass_ps30.inc b/materialsystem/stdshaders/include/lightpass_ps30.inc new file mode 100644 index 00000000..14c71ba4 --- /dev/null +++ b/materialsystem/stdshaders/include/lightpass_ps30.inc @@ -0,0 +1,163 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class lightpass_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 1; + unsigned int m_nBUMPMAP : 2; + unsigned int m_nBASETEXTURE2 : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nDECAL : 2; + unsigned int m_nMODEL : 2; + unsigned int m_nSMOOTHNESS : 2; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB : 1; + bool m_bBUMPMAP : 1; + bool m_bBASETEXTURE2 : 1; + bool m_bSEAMLESS : 1; + bool m_bDECAL : 1; + bool m_bMODEL : 1; + bool m_bSMOOTHNESS : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif // _DEBUG + } + + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif // _DEBUG + } + + void SetSMOOTHNESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSMOOTHNESS = i; +#ifdef _DEBUG + m_bSMOOTHNESS = true; +#endif // _DEBUG + } + + lightpass_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = 0; + m_nBUMPMAP = 0; + m_nBASETEXTURE2 = 0; + m_nSEAMLESS = 0; + m_nDECAL = 0; + m_nMODEL = 0; + m_nSMOOTHNESS = 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; + m_bBUMPMAP = false; + m_bBASETEXTURE2 = false; + m_bSEAMLESS = false; + m_bDECAL = false; + m_bMODEL = false; + m_bSMOOTHNESS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCONVERT_TO_SRGB && m_bBUMPMAP && m_bBASETEXTURE2 && m_bSEAMLESS && m_bDECAL && m_bMODEL && m_bSMOOTHNESS ); + return ( 3 * m_nCONVERT_TO_SRGB ) + ( 3 * m_nBUMPMAP ) + ( 6 * m_nBASETEXTURE2 ) + ( 12 * m_nSEAMLESS ) + ( 24 * m_nDECAL ) + ( 48 * m_nMODEL ) + ( 96 * m_nSMOOTHNESS ) + 0; + } +}; + +#define shaderStaticTest_lightpass_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DECAL + psh_forgot_to_set_static_MODEL + psh_forgot_to_set_static_SMOOTHNESS + + +class lightpass_ps30_Dynamic_Index +{ + unsigned int m_nPERF : 2; +#ifdef _DEBUG + bool m_bPERF : 1; +#endif // _DEBUG +public: + void SetPERF( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nPERF = i; +#ifdef _DEBUG + m_bPERF = true; +#endif // _DEBUG + } + + lightpass_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPERF = 0; +#ifdef _DEBUG + m_bPERF = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPERF ); + return ( 1 * m_nPERF ) + 0; + } +}; + +#define shaderDynamicTest_lightpass_ps30 psh_forgot_to_set_dynamic_PERF + diff --git a/materialsystem/stdshaders/include/lightpass_vs30.inc b/materialsystem/stdshaders/include/lightpass_vs30.inc new file mode 100644 index 00000000..40a88f78 --- /dev/null +++ b/materialsystem/stdshaders/include/lightpass_vs30.inc @@ -0,0 +1,149 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $MORPHING && ( $MODEL == 0 ) +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class lightpass_vs30_Static_Index +{ + unsigned int m_nMODEL : 2; + unsigned int m_nTANGENTSPACE : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nVERTEXALPHATEXBLENDFACTOR : 2; + unsigned int m_nSEAMLESS : 2; +#ifdef _DEBUG + bool m_bMODEL : 1; + bool m_bTANGENTSPACE : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bVERTEXALPHATEXBLENDFACTOR : 1; + bool m_bSEAMLESS : 1; +#endif // _DEBUG +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif // _DEBUG + } + + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + lightpass_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nMODEL = 0; + m_nTANGENTSPACE = 0; + m_nVERTEXCOLOR = 0; + m_nVERTEXALPHATEXBLENDFACTOR = 0; + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bMODEL = false; + m_bTANGENTSPACE = false; + m_bVERTEXCOLOR = false; + m_bVERTEXALPHATEXBLENDFACTOR = false; + m_bSEAMLESS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMODEL && m_bTANGENTSPACE && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS ); + return ( 8 * m_nMODEL ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nVERTEXCOLOR ) + ( 64 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 128 * m_nSEAMLESS ) + 0; + } +}; + +#define shaderStaticTest_lightpass_vs30 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + + +class lightpass_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + lightpass_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_lightpass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/luma_ps30.inc b/materialsystem/stdshaders/include/luma_ps30.inc new file mode 100644 index 00000000..6281a125 --- /dev/null +++ b/materialsystem/stdshaders/include/luma_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class luma_ps30_Static_Index +{ +public: + luma_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_luma_ps30 1 + + +class luma_ps30_Dynamic_Index +{ +public: + luma_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_luma_ps30 1 + diff --git a/materialsystem/stdshaders/include/normalmapreconstruct_ps30.inc b/materialsystem/stdshaders/include/normalmapreconstruct_ps30.inc new file mode 100644 index 00000000..aa7b451e --- /dev/null +++ b/materialsystem/stdshaders/include/normalmapreconstruct_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class normalmapreconstruct_ps30_Static_Index +{ +public: + normalmapreconstruct_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_normalmapreconstruct_ps30 1 + + +class normalmapreconstruct_ps30_Dynamic_Index +{ +public: + normalmapreconstruct_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_normalmapreconstruct_ps30 1 + diff --git a/materialsystem/stdshaders/include/passthru_vs30.inc b/materialsystem/stdshaders/include/passthru_vs30.inc new file mode 100644 index 00000000..b24890b8 --- /dev/null +++ b/materialsystem/stdshaders/include/passthru_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class passthru_vs30_Static_Index +{ +public: + passthru_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_passthru_vs30 1 + + +class passthru_vs30_Dynamic_Index +{ +public: + passthru_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_passthru_vs30 1 + diff --git a/materialsystem/stdshaders/include/screenspace_simple_vs30.inc b/materialsystem/stdshaders/include/screenspace_simple_vs30.inc new file mode 100644 index 00000000..1f5e7490 --- /dev/null +++ b/materialsystem/stdshaders/include/screenspace_simple_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class screenspace_simple_vs30_Static_Index +{ +public: + screenspace_simple_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_screenspace_simple_vs30 1 + + +class screenspace_simple_vs30_Dynamic_Index +{ +public: + screenspace_simple_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_screenspace_simple_vs30 1 + diff --git a/materialsystem/stdshaders/include/screenwater_ps30.inc b/materialsystem/stdshaders/include/screenwater_ps30.inc new file mode 100644 index 00000000..ec324322 --- /dev/null +++ b/materialsystem/stdshaders/include/screenwater_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class screenwater_ps30_Static_Index +{ +public: + screenwater_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_screenwater_ps30 1 + + +class screenwater_ps30_Dynamic_Index +{ +public: + screenwater_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_screenwater_ps30 1 + diff --git a/materialsystem/stdshaders/include/screenwater_vs30.inc b/materialsystem/stdshaders/include/screenwater_vs30.inc new file mode 100644 index 00000000..76b012fd --- /dev/null +++ b/materialsystem/stdshaders/include/screenwater_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class screenwater_vs30_Static_Index +{ +public: + screenwater_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_screenwater_vs30 1 + + +class screenwater_vs30_Dynamic_Index +{ +public: + screenwater_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_screenwater_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_bloom_ps30.inc b/materialsystem/stdshaders/include/sdk_bloom_ps30.inc new file mode 100644 index 00000000..22237749 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_bloom_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_bloom_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_bloom_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_bloom_ps30 1 + + +class sdk_bloom_ps30_Dynamic_Index +{ +public: + sdk_bloom_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_bloom_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_bloomadd_ps30.inc b/materialsystem/stdshaders/include/sdk_bloomadd_ps30.inc new file mode 100644 index 00000000..8a7363ac --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_bloomadd_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_bloomadd_ps30_Static_Index +{ +public: + sdk_bloomadd_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_bloomadd_ps30 1 + + +class sdk_bloomadd_ps30_Dynamic_Index +{ +public: + sdk_bloomadd_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_bloomadd_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_blurgaussian_3x3_ps30.inc b/materialsystem/stdshaders/include/sdk_blurgaussian_3x3_ps30.inc new file mode 100644 index 00000000..08b0d7f3 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_blurgaussian_3x3_ps30.inc @@ -0,0 +1,33 @@ +#pragma once +#include "shaderlib/cshader.h" +class sdk_blurgaussian_3x3_ps30_Static_Index +{ +public: + sdk_blurgaussian_3x3_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_blurgaussian_3x3_ps30 1 + + +class sdk_blurgaussian_3x3_ps30_Dynamic_Index +{ +public: + sdk_blurgaussian_3x3_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_blurgaussian_3x3_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_cloak_blended_pass_ps30.inc b/materialsystem/stdshaders/include/sdk_cloak_blended_pass_ps30.inc new file mode 100644 index 00000000..419e3240 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_cloak_blended_pass_ps30.inc @@ -0,0 +1,68 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nBUMPMAP : 2; +#ifdef _DEBUG + bool m_bBUMPMAP : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + sdk_cloak_blended_pass_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBUMPMAP ); + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nBUMPMAP ) + 0; + } +}; + +#define shaderStaticTest_sdk_cloak_blended_pass_ps30 psh_forgot_to_set_static_BUMPMAP + + +class sdk_cloak_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_cloak_blended_pass_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_cloak_blended_pass_vs30.inc b/materialsystem/stdshaders/include/sdk_cloak_blended_pass_vs30.inc new file mode 100644 index 00000000..90f355a0 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_cloak_blended_pass_vs30.inc @@ -0,0 +1,96 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_vs30_Static_Index +{ + unsigned int m_nBUMPMAP : 2; +#ifdef _DEBUG + bool m_bBUMPMAP : 1; +#endif // _DEBUG +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + sdk_cloak_blended_pass_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBUMPMAP ); + return ( 8 * m_nBUMPMAP ) + 0; + } +}; + +#define shaderStaticTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_static_BUMPMAP + + +class sdk_cloak_blended_pass_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_cloak_blended_pass_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_core_ps30.inc b/materialsystem/stdshaders/include/sdk_core_ps30.inc new file mode 100644 index 00000000..90000d5a --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_core_ps30.inc @@ -0,0 +1,127 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ( $REFRACT || $CORECOLORTEXTURE ) && $CUBEMAP +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_core_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nFLOWMAP : 2; + unsigned int m_nCORECOLORTEXTURE : 2; + unsigned int m_nREFRACT : 2; +#ifdef _DEBUG + bool m_bCUBEMAP : 1; + bool m_bFLOWMAP : 1; + bool m_bCORECOLORTEXTURE : 1; + bool m_bREFRACT : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetFLOWMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLOWMAP = i; +#ifdef _DEBUG + m_bFLOWMAP = true; +#endif // _DEBUG + } + + void SetCORECOLORTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCORECOLORTEXTURE = i; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = true; +#endif // _DEBUG + } + + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif // _DEBUG + } + + sdk_core_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nCUBEMAP = 0; + m_nFLOWMAP = 0; + m_nCORECOLORTEXTURE = 0; + m_nREFRACT = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; + m_bFLOWMAP = false; + m_bCORECOLORTEXTURE = false; + m_bREFRACT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT ); + AssertMsg( !( ( m_nREFRACT || m_nCORECOLORTEXTURE ) && m_nCUBEMAP ), "Invalid combo combination ( ( REFRACT || CORECOLORTEXTURE ) && CUBEMAP )" ); + return ( 2 * m_nCONVERT_TO_SRGB ) + ( 4 * m_nCUBEMAP ) + ( 8 * m_nFLOWMAP ) + ( 16 * m_nCORECOLORTEXTURE ) + ( 32 * m_nREFRACT ) + 0; + } +}; + +#define shaderStaticTest_sdk_core_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + + +class sdk_core_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_core_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE ); + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_core_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_core_vs30.inc b/materialsystem/stdshaders/include/sdk_core_vs30.inc new file mode 100644 index 00000000..d761eef6 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_core_vs30.inc @@ -0,0 +1,85 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_core_vs30_Static_Index +{ + unsigned int m_nMODEL : 2; +#ifdef _DEBUG + bool m_bMODEL : 1; +#endif // _DEBUG +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif // _DEBUG + } + + sdk_core_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nMODEL = 0; +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMODEL ); + return ( 4 * m_nMODEL ) + 0; + } +}; + +#define shaderStaticTest_sdk_core_vs30 vsh_forgot_to_set_static_MODEL + + +class sdk_core_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + sdk_core_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_core_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_decalmodulate_ps30.inc b/materialsystem/stdshaders/include/sdk_decalmodulate_ps30.inc new file mode 100644 index 00000000..a487055d --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_decalmodulate_ps30.inc @@ -0,0 +1,134 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps30_Static_Index +{ + unsigned int m_nVERTEXALPHA : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; +#ifdef _DEBUG + bool m_bVERTEXALPHA : 1; + bool m_bFLASHLIGHT : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; +#endif // _DEBUG +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + sdk_decalmodulate_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXALPHA = 0; + m_nFLASHLIGHT = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bVERTEXALPHA = false; + m_bFLASHLIGHT = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXALPHA && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE ); + AssertMsg( !( ( m_nFLASHLIGHT == 0 ) && ( m_nFLASHLIGHTDEPTHFILTERMODE != 0 ) ), "Invalid combo combination ( ( FLASHLIGHT == 0 ) && ( FLASHLIGHTDEPTHFILTERMODE != 0 ) )" ); + return ( 4 * m_nVERTEXALPHA ) + ( 8 * m_nFLASHLIGHT ) + ( 16 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; + +#define shaderStaticTest_sdk_decalmodulate_ps30 psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + + +class sdk_decalmodulate_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_decalmodulate_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_decalmodulate_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_decalmodulate_vs30.inc b/materialsystem/stdshaders/include/sdk_decalmodulate_vs30.inc new file mode 100644 index 00000000..3a8a587f --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_decalmodulate_vs30.inc @@ -0,0 +1,122 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_decalmodulate_vs30_Static_Index +{ + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; + unsigned int m_nFLASHLIGHT : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; + bool m_bLIGHTING_PREVIEW : 1; + bool m_bFLASHLIGHT : 1; +#endif // _DEBUG +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + sdk_decalmodulate_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXCOLOR = 0; + m_nLIGHTING_PREVIEW = 0; + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; + m_bLIGHTING_PREVIEW = false; + m_bFLASHLIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR && m_bLIGHTING_PREVIEW && m_bFLASHLIGHT ); + return ( 8 * m_nVERTEXCOLOR ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 32 * m_nFLASHLIGHT ) + 0; + } +}; + +#define shaderStaticTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_LIGHTING_PREVIEW + vsh_forgot_to_set_static_FLASHLIGHT + + +class sdk_decalmodulate_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_decalmodulate_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_depthwrite_ps30.inc b/materialsystem/stdshaders/include/sdk_depthwrite_ps30.inc new file mode 100644 index 00000000..11b79476 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_depthwrite_ps30.inc @@ -0,0 +1,69 @@ +#pragma once +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps30_Static_Index +{ + unsigned int m_nCOLOR_DEPTH : 2; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH : 1; +#endif // _DEBUG +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif // _DEBUG + } + + sdk_depthwrite_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCOLOR_DEPTH = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOLOR_DEPTH ); + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; + +#define shaderStaticTest_sdk_depthwrite_ps30 psh_forgot_to_set_static_COLOR_DEPTH + + +class sdk_depthwrite_ps30_Dynamic_Index +{ + unsigned int m_nALPHACLIP : 2; +#ifdef _DEBUG + bool m_bALPHACLIP : 1; +#endif // _DEBUG +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif // _DEBUG + } + + sdk_depthwrite_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nALPHACLIP = 0; +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bALPHACLIP ); + return ( 1 * m_nALPHACLIP ) + 0; + } +}; + +#define shaderDynamicTest_sdk_depthwrite_ps30 psh_forgot_to_set_dynamic_ALPHACLIP + diff --git a/materialsystem/stdshaders/include/sdk_depthwrite_vs30.inc b/materialsystem/stdshaders/include/sdk_depthwrite_vs30.inc new file mode 100644 index 00000000..220940d0 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_depthwrite_vs30.inc @@ -0,0 +1,109 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_depthwrite_vs30_Static_Index +{ + unsigned int m_nCOLOR_DEPTH : 2; + unsigned int m_nTREESWAY : 2; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH : 1; + bool m_bTREESWAY : 1; +#endif // _DEBUG +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif // _DEBUG + } + + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif // _DEBUG + } + + sdk_depthwrite_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCOLOR_DEPTH = 0; + m_nTREESWAY = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; + m_bTREESWAY = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOLOR_DEPTH && m_bTREESWAY ); + return ( 8 * m_nCOLOR_DEPTH ) + ( 16 * m_nTREESWAY ) + 0; + } +}; + +#define shaderStaticTest_sdk_depthwrite_vs30 vsh_forgot_to_set_static_COLOR_DEPTH + vsh_forgot_to_set_static_TREESWAY + + +class sdk_depthwrite_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_depthwrite_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_depthwrite_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_ps30.inc b/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_ps30.inc new file mode 100644 index 00000000..64e64ab7 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_emissive_scroll_blended_pass_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps30 1 + + +class sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_vs30.inc b/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_vs30.inc new file mode 100644 index 00000000..cf0b877b --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_emissive_scroll_blended_pass_vs30.inc @@ -0,0 +1,78 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_vs30_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_vs30 1 + + +class sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_engine_post_ps30.inc b/materialsystem/stdshaders/include/sdk_engine_post_ps30.inc new file mode 100644 index 00000000..25ea2af9 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_engine_post_ps30.inc @@ -0,0 +1,202 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ( $CONVERT_FROM_LINEAR == 0 ) && ( $CONVERT_TO_LINEAR == 1 ) +// ( $TOOL_MODE == 0 ) && ( $CONVERT_TO_LINEAR == 1 ) +// ( $LOCAL_CONTRAST_ENABLE == 0 ) && ( $BLURRED_VIGNETTE_ENABLE == 1 ) +// ( $TOOL_MODE == 0 ) && $TV_GAMMA +// ( $TOOL_MODE == 0 ) && $DESATURATEENABLE +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_engine_post_ps30_Static_Index +{ + unsigned int m_nTOOL_MODE : 2; + unsigned int m_nDEPTH_BLUR_ENABLE : 2; +#ifdef _DEBUG + bool m_bTOOL_MODE : 1; + bool m_bDEPTH_BLUR_ENABLE : 1; +#endif // _DEBUG +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif // _DEBUG + } + + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif // _DEBUG + } + + sdk_engine_post_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nTOOL_MODE = 0; + m_nDEPTH_BLUR_ENABLE = 0; +#ifdef _DEBUG + m_bTOOL_MODE = false; + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE ); + return ( 512 * m_nTOOL_MODE ) + ( 1024 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; + +#define shaderStaticTest_sdk_engine_post_ps30 psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + + +class sdk_engine_post_ps30_Dynamic_Index +{ + unsigned int m_nAA_ENABLE : 1; + unsigned int m_nCOL_CORRECT_NUM_LOOKUPS : 3; + unsigned int m_nCONVERT_FROM_LINEAR : 2; + unsigned int m_nCONVERT_TO_LINEAR : 2; + unsigned int m_nNOISE_ENABLE : 2; + unsigned int m_nVIGNETTE_ENABLE : 2; + unsigned int m_nLOCAL_CONTRAST_ENABLE : 2; + unsigned int m_nBLURRED_VIGNETTE_ENABLE : 2; + unsigned int m_nVOMIT_ENABLE : 2; +#ifdef _DEBUG + bool m_bAA_ENABLE : 1; + bool m_bCOL_CORRECT_NUM_LOOKUPS : 1; + bool m_bCONVERT_FROM_LINEAR : 1; + bool m_bCONVERT_TO_LINEAR : 1; + bool m_bNOISE_ENABLE : 1; + bool m_bVIGNETTE_ENABLE : 1; + bool m_bLOCAL_CONTRAST_ENABLE : 1; + bool m_bBLURRED_VIGNETTE_ENABLE : 1; + bool m_bVOMIT_ENABLE : 1; +#endif // _DEBUG +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif // _DEBUG + } + + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif // _DEBUG + } + + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif // _DEBUG + } + + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif // _DEBUG + } + + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif // _DEBUG + } + + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif // _DEBUG + } + + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif // _DEBUG + } + + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif // _DEBUG + } + + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif // _DEBUG + } + + sdk_engine_post_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nAA_ENABLE = 0; + m_nCOL_CORRECT_NUM_LOOKUPS = 0; + m_nCONVERT_FROM_LINEAR = 0; + m_nCONVERT_TO_LINEAR = 0; + m_nNOISE_ENABLE = 0; + m_nVIGNETTE_ENABLE = 0; + m_nLOCAL_CONTRAST_ENABLE = 0; + m_nBLURRED_VIGNETTE_ENABLE = 0; + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bAA_ENABLE = false; + m_bCOL_CORRECT_NUM_LOOKUPS = false; + m_bCONVERT_FROM_LINEAR = false; + m_bCONVERT_TO_LINEAR = false; + m_bNOISE_ENABLE = false; + m_bVIGNETTE_ENABLE = false; + m_bLOCAL_CONTRAST_ENABLE = false; + m_bBLURRED_VIGNETTE_ENABLE = false; + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE ); + AssertMsg( !( ( m_nCONVERT_FROM_LINEAR == 0 ) && ( m_nCONVERT_TO_LINEAR == 1 ) ), "Invalid combo combination ( ( CONVERT_FROM_LINEAR == 0 ) && ( CONVERT_TO_LINEAR == 1 ) )" ); + AssertMsg( !( ( m_nLOCAL_CONTRAST_ENABLE == 0 ) && ( m_nBLURRED_VIGNETTE_ENABLE == 1 ) ), "Invalid combo combination ( ( LOCAL_CONTRAST_ENABLE == 0 ) && ( BLURRED_VIGNETTE_ENABLE == 1 ) )" ); + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_engine_post_ps30 psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + diff --git a/materialsystem/stdshaders/include/sdk_eye_refract_ps30.inc b/materialsystem/stdshaders/include/sdk_eye_refract_ps30.inc new file mode 100644 index 00000000..7c0690c3 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eye_refract_ps30.inc @@ -0,0 +1,154 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps30_Static_Index +{ + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nLIGHTWARPTEXTURE : 2; + unsigned int m_nSPHERETEXKILLCOMBO : 2; + unsigned int m_nRAYTRACESPHERE : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; +#ifdef _DEBUG + bool m_bFLASHLIGHT : 1; + bool m_bLIGHTWARPTEXTURE : 1; + bool m_bSPHERETEXKILLCOMBO : 1; + bool m_bRAYTRACESPHERE : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; +#endif // _DEBUG +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif // _DEBUG + } + + void SetSPHERETEXKILLCOMBO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSPHERETEXKILLCOMBO = i; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif // _DEBUG + } + + void SetRAYTRACESPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRAYTRACESPHERE = i; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + sdk_eye_refract_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nFLASHLIGHT = 0; + m_nLIGHTWARPTEXTURE = 0; + m_nSPHERETEXKILLCOMBO = 0; + m_nRAYTRACESPHERE = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; + m_bLIGHTWARPTEXTURE = false; + m_bSPHERETEXKILLCOMBO = false; + m_bRAYTRACESPHERE = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bSPHERETEXKILLCOMBO && m_bRAYTRACESPHERE && m_bFLASHLIGHTDEPTHFILTERMODE ); + AssertMsg( !( ( m_nRAYTRACESPHERE == 0 ) && ( m_nSPHERETEXKILLCOMBO == 1 ) ), "Invalid combo combination ( ( RAYTRACESPHERE == 0 ) && ( SPHERETEXKILLCOMBO == 1 ) )" ); + return ( 10 * m_nFLASHLIGHT ) + ( 20 * m_nLIGHTWARPTEXTURE ) + ( 40 * m_nSPHERETEXKILLCOMBO ) + ( 80 * m_nRAYTRACESPHERE ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; + +#define shaderStaticTest_sdk_eye_refract_ps30 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SPHERETEXKILLCOMBO + psh_forgot_to_set_static_RAYTRACESPHERE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + + +class sdk_eye_refract_ps30_Dynamic_Index +{ + unsigned int m_nNUM_LIGHTS : 3; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bNUM_LIGHTS : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_eye_refract_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nNUM_LIGHTS = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bNUM_LIGHTS && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eye_refract_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_eye_refract_vs30.inc b/materialsystem/stdshaders/include/sdk_eye_refract_vs30.inc new file mode 100644 index 00000000..337eebdc --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eye_refract_vs30.inc @@ -0,0 +1,174 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eye_refract_vs30_Static_Index +{ + unsigned int m_nINTRO : 2; + unsigned int m_nHALFLAMBERT : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nLIGHTWARPTEXTURE : 2; +#ifdef _DEBUG + bool m_bINTRO : 1; + bool m_bHALFLAMBERT : 1; + bool m_bFLASHLIGHT : 1; + bool m_bLIGHTWARPTEXTURE : 1; +#endif // _DEBUG +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif // _DEBUG + } + + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif // _DEBUG + } + + sdk_eye_refract_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nINTRO = 0; + m_nHALFLAMBERT = 0; + m_nFLASHLIGHT = 0; + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bINTRO = false; + m_bHALFLAMBERT = false; + m_bFLASHLIGHT = false; + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bINTRO && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE ); + return ( 160 * m_nINTRO ) + ( 320 * m_nHALFLAMBERT ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; + +#define shaderStaticTest_sdk_eye_refract_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_LIGHTWARPTEXTURE + + +class sdk_eye_refract_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; + unsigned int m_nNUM_LIGHTS : 3; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; + bool m_bNUM_LIGHTS : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_eye_refract_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; + m_nNUM_LIGHTS = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; + m_bNUM_LIGHTS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nNUM_LIGHTS ) + ( 80 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eye_refract_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + diff --git a/materialsystem/stdshaders/include/sdk_eyeglint_ps30.inc b/materialsystem/stdshaders/include/sdk_eyeglint_ps30.inc new file mode 100644 index 00000000..81c1c75c --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyeglint_ps30.inc @@ -0,0 +1,33 @@ +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyeglint_ps30_Static_Index +{ +public: + sdk_eyeglint_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_eyeglint_ps30 1 + + +class sdk_eyeglint_ps30_Dynamic_Index +{ +public: + sdk_eyeglint_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_eyeglint_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_eyeglint_vs30.inc b/materialsystem/stdshaders/include/sdk_eyeglint_vs30.inc new file mode 100644 index 00000000..073bde02 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyeglint_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyeglint_vs30_Static_Index +{ +public: + sdk_eyeglint_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_eyeglint_vs30 1 + + +class sdk_eyeglint_vs30_Dynamic_Index +{ +public: + sdk_eyeglint_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_eyeglint_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_eyes_flashlight_ps30.inc b/materialsystem/stdshaders/include/sdk_eyes_flashlight_ps30.inc new file mode 100644 index 00000000..16360bc2 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyes_flashlight_ps30.inc @@ -0,0 +1,98 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps30_Static_Index +{ + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; +#endif // _DEBUG +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + sdk_eyes_flashlight_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFLASHLIGHTDEPTHFILTERMODE ); + return ( 4 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; + +#define shaderStaticTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + + +class sdk_eyes_flashlight_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_eyes_flashlight_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_eyes_flashlight_vs30.inc b/materialsystem/stdshaders/include/sdk_eyes_flashlight_vs30.inc new file mode 100644 index 00000000..9196a016 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyes_flashlight_vs30.inc @@ -0,0 +1,78 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_vs30_Static_Index +{ +public: + sdk_eyes_flashlight_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_eyes_flashlight_vs30 1 + + +class sdk_eyes_flashlight_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_eyes_flashlight_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eyes_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_eyes_ps30.inc b/materialsystem/stdshaders/include/sdk_eyes_ps30.inc new file mode 100644 index 00000000..1df23f41 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyes_ps30.inc @@ -0,0 +1,80 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyes_ps30_Static_Index +{ +public: + sdk_eyes_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_eyes_ps30 1 + + +class sdk_eyes_ps30_Dynamic_Index +{ + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_eyes_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE ); + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eyes_ps30 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_eyes_vs30.inc b/materialsystem/stdshaders/include/sdk_eyes_vs30.inc new file mode 100644 index 00000000..e355d6aa --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_eyes_vs30.inc @@ -0,0 +1,135 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_eyes_vs30_Static_Index +{ + unsigned int m_nINTRO : 2; + unsigned int m_nHALFLAMBERT : 2; +#ifdef _DEBUG + bool m_bINTRO : 1; + bool m_bHALFLAMBERT : 1; +#endif // _DEBUG +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif // _DEBUG + } + + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + sdk_eyes_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nINTRO = 0; + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bINTRO = false; + m_bHALFLAMBERT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bINTRO && m_bHALFLAMBERT ); + return ( 32 * m_nINTRO ) + ( 64 * m_nHALFLAMBERT ) + 0; + } +}; + +#define shaderStaticTest_sdk_eyes_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + + +class sdk_eyes_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_eyes_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_eyes_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + diff --git a/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_ps30.inc b/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_ps30.inc new file mode 100644 index 00000000..b18ae900 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_flesh_interior_blended_pass_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_flesh_interior_blended_pass_ps30 1 + + +class sdk_flesh_interior_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_flesh_interior_blended_pass_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_vs30.inc b/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_vs30.inc new file mode 100644 index 00000000..86ab3bf6 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_flesh_interior_blended_pass_vs30.inc @@ -0,0 +1,111 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_vs30_Static_Index +{ + unsigned int m_nHALFLAMBERT : 2; +#ifdef _DEBUG + bool m_bHALFLAMBERT : 1; +#endif // _DEBUG +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + sdk_flesh_interior_blended_pass_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHALFLAMBERT ); + return ( 16 * m_nHALFLAMBERT ) + 0; + } +}; + +#define shaderStaticTest_sdk_flesh_interior_blended_pass_vs30 vsh_forgot_to_set_static_HALFLAMBERT + + +class sdk_flesh_interior_blended_pass_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + sdk_flesh_interior_blended_pass_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + 0; + } +}; + +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_ps30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_ps30.inc new file mode 100644 index 00000000..4b1faf96 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_ps30.inc @@ -0,0 +1,67 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_ps30_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_decal_ps30 1 + + +class sdk_lightmappedgeneric_decal_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_decal_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE ); + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_vs30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_vs30.inc new file mode 100644 index 00000000..d1bc1417 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_decal_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_vs30_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_decal_vs30 1 + + +class sdk_lightmappedgeneric_decal_vs30_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_decal_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_ps30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_ps30.inc new file mode 100644 index 00000000..15a029ef --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_ps30.inc @@ -0,0 +1,242 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// !$WORLDVERTEXTRANSITION && $NORMALMAP2 +// !$NORMALMAP && $NORMALMAP2 +// !$DETAILTEXTURE && ( $DETAIL_BLEND_MODE != 0 ) +// !$PHONG && $PHONGMASK +// $BASETEXTURETRANSFORM2 && !$WORLDVERTEXTRANSITION +// $BASETEXTURETRANSFORM2 && $SEAMLESS +// $BASETEXTURETRANSFORM2 && $PHONG +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps30_Static_Index +{ + unsigned int m_nNORMALMAP : 2; + unsigned int m_nNORMALMAP2 : 2; + unsigned int m_nWORLDVERTEXTRANSITION : 2; + unsigned int m_nFANCY_BLENDING : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nDETAIL_BLEND_MODE : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; + unsigned int m_nPHONG : 2; + unsigned int m_nPHONGMASK : 3; + unsigned int m_nBASETEXTURETRANSFORM2 : 2; +#ifdef _DEBUG + bool m_bNORMALMAP : 1; + bool m_bNORMALMAP2 : 1; + bool m_bWORLDVERTEXTRANSITION : 1; + bool m_bFANCY_BLENDING : 1; + bool m_bSEAMLESS : 1; + bool m_bDETAILTEXTURE : 1; + bool m_bDETAIL_BLEND_MODE : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; + bool m_bPHONG : 1; + bool m_bPHONGMASK : 1; + bool m_bBASETEXTURETRANSFORM2 : 1; +#endif // _DEBUG +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif // _DEBUG + } + + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif // _DEBUG + } + + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif // _DEBUG + } + + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif // _DEBUG + } + + void SetPHONGMASK( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nPHONGMASK = i; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif // _DEBUG + } + + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_flashlight_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nNORMALMAP = 0; + m_nNORMALMAP2 = 0; + m_nWORLDVERTEXTRANSITION = 0; + m_nFANCY_BLENDING = 0; + m_nSEAMLESS = 0; + m_nDETAILTEXTURE = 0; + m_nDETAIL_BLEND_MODE = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + m_nPHONG = 0; + m_nPHONGMASK = 0; + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bNORMALMAP = false; + m_bNORMALMAP2 = false; + m_bWORLDVERTEXTRANSITION = false; + m_bFANCY_BLENDING = false; + m_bSEAMLESS = false; + m_bDETAILTEXTURE = false; + m_bDETAIL_BLEND_MODE = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; + m_bPHONG = false; + m_bPHONGMASK = false; + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bPHONG && m_bPHONGMASK && m_bBASETEXTURETRANSFORM2 ); + AssertMsg( !( !m_nWORLDVERTEXTRANSITION && m_nNORMALMAP2 ), "Invalid combo combination ( !WORLDVERTEXTRANSITION && NORMALMAP2 )" ); + AssertMsg( !( !m_nNORMALMAP && m_nNORMALMAP2 ), "Invalid combo combination ( !NORMALMAP && NORMALMAP2 )" ); + AssertMsg( !( !m_nDETAILTEXTURE && ( m_nDETAIL_BLEND_MODE != 0 ) ), "Invalid combo combination ( !DETAILTEXTURE && ( DETAIL_BLEND_MODE != 0 ) )" ); + AssertMsg( !( !m_nPHONG && m_nPHONGMASK ), "Invalid combo combination ( !PHONG && PHONGMASK )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && !m_nWORLDVERTEXTRANSITION ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && !WORLDVERTEXTRANSITION )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && m_nSEAMLESS ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && SEAMLESS )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && m_nPHONG ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && PHONG )" ); + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nFANCY_BLENDING ) + ( 96 * m_nSEAMLESS ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nDETAIL_BLEND_MODE ) + ( 768 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 2304 * m_nPHONG ) + ( 4608 * m_nPHONGMASK ) + ( 18432 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_PHONG + psh_forgot_to_set_static_PHONGMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + + +class sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_vs30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_vs30.inc new file mode 100644 index 00000000..8fc1c49f --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_flashlight_vs30.inc @@ -0,0 +1,125 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $BASETEXTURETRANSFORM2 && !$WORLDVERTEXTRANSITION +// $BASETEXTURETRANSFORM2 && $SEAMLESS +// $BASETEXTURETRANSFORM2 && $PHONG +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs30_Static_Index +{ + unsigned int m_nNORMALMAP : 2; + unsigned int m_nWORLDVERTEXTRANSITION : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nDETAIL : 2; + unsigned int m_nPHONG : 2; + unsigned int m_nBASETEXTURETRANSFORM2 : 2; +#ifdef _DEBUG + bool m_bNORMALMAP : 1; + bool m_bWORLDVERTEXTRANSITION : 1; + bool m_bSEAMLESS : 1; + bool m_bDETAIL : 1; + bool m_bPHONG : 1; + bool m_bBASETEXTURETRANSFORM2 : 1; +#endif // _DEBUG +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif // _DEBUG + } + + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif // _DEBUG + } + + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif // _DEBUG + } + + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_flashlight_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nNORMALMAP = 0; + m_nWORLDVERTEXTRANSITION = 0; + m_nSEAMLESS = 0; + m_nDETAIL = 0; + m_nPHONG = 0; + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bNORMALMAP = false; + m_bWORLDVERTEXTRANSITION = false; + m_bSEAMLESS = false; + m_bDETAIL = false; + m_bPHONG = false; + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL && m_bPHONG && m_bBASETEXTURETRANSFORM2 ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && !m_nWORLDVERTEXTRANSITION ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && !WORLDVERTEXTRANSITION )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && m_nSEAMLESS ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && SEAMLESS )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && m_nPHONG ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && PHONG )" ); + return ( 1 * m_nNORMALMAP ) + ( 2 * m_nWORLDVERTEXTRANSITION ) + ( 4 * m_nSEAMLESS ) + ( 8 * m_nDETAIL ) + ( 16 * m_nPHONG ) + ( 32 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + vsh_forgot_to_set_static_PHONG + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + + +class sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_ps30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_ps30.inc new file mode 100644 index 00000000..179dcde4 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_ps30.inc @@ -0,0 +1,468 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $BUMPMAP2 && $WARPLIGHTING +// $WARPLIGHTING && $DETAILTEXTURE +// $ENVMAPMASK && $BUMPMAP +// $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK +// $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// $BASEALPHAENVMAPMASK && $ENVMAPMASK +// $BASEALPHAENVMAPMASK && $SELFILLUM +// !$FASTPATH && $FASTPATHENVMAPCONTRAST +// !$FASTPATH && $FASTPATHENVMAPTINT +// !$BUMPMAP && $DIFFUSEBUMPMAP +// !$BUMPMAP && $BUMPMAP2 +// !$BUMPMAP2 && $BUMPMASK +// $ENVMAPMASK && $BUMPMAP2 +// $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// $BASEALPHAENVMAPMASK && $BUMPMAP +// $SEAMLESS && $DETAILTEXTURE +// $SEAMLESS && $MASKEDBLENDING +// $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 ) +// $FANCY_BLENDING && $BUMPMAP && $DETAILTEXTURE +// $BASETEXTURETRANSFORM2 && !$BASETEXTURE2 +// $BASETEXTURETRANSFORM2 && $SEAMLESS +// !$FANCY_BLENDING && $MASKEDBLENDING +// $PARALLAXCORRECT && !$CUBEMAP +// $WARPLIGHTING +// $FASTPATH +// $FASTPATHENVMAPCONTRAST +// $BASETEXTURETRANSFORM2 +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps30_Static_Index +{ + unsigned int m_nMASKEDBLENDING : 2; + unsigned int m_nBASETEXTURE2 : 2; + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nBUMPMAP : 2; + unsigned int m_nBUMPMAP2 : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nENVMAPMASK : 2; + unsigned int m_nBASEALPHAENVMAPMASK : 2; + unsigned int m_nSELFILLUM : 2; + unsigned int m_nNORMALMAPALPHAENVMAPMASK : 2; + unsigned int m_nDIFFUSEBUMPMAP : 2; + unsigned int m_nBASETEXTURENOENVMAP : 2; + unsigned int m_nBASETEXTURE2NOENVMAP : 2; + unsigned int m_nWARPLIGHTING : 2; + unsigned int m_nFANCY_BLENDING : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nBUMPMASK : 2; + unsigned int m_nBASETEXTURETRANSFORM2 : 2; + unsigned int m_nPARALLAXCORRECT : 2; +#ifdef _DEBUG + bool m_bMASKEDBLENDING : 1; + bool m_bBASETEXTURE2 : 1; + bool m_bDETAILTEXTURE : 1; + bool m_bBUMPMAP : 1; + bool m_bBUMPMAP2 : 1; + bool m_bCUBEMAP : 1; + bool m_bENVMAPMASK : 1; + bool m_bBASEALPHAENVMAPMASK : 1; + bool m_bSELFILLUM : 1; + bool m_bNORMALMAPALPHAENVMAPMASK : 1; + bool m_bDIFFUSEBUMPMAP : 1; + bool m_bBASETEXTURENOENVMAP : 1; + bool m_bBASETEXTURE2NOENVMAP : 1; + bool m_bWARPLIGHTING : 1; + bool m_bFANCY_BLENDING : 1; + bool m_bSEAMLESS : 1; + bool m_bBUMPMASK : 1; + bool m_bBASETEXTURETRANSFORM2 : 1; + bool m_bPARALLAXCORRECT : 1; +#endif // _DEBUG +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif // _DEBUG + } + + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif // _DEBUG + } + + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif // _DEBUG + } + + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif // _DEBUG + } + + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif // _DEBUG + } + + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif // _DEBUG + } + + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif // _DEBUG + } + + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif // _DEBUG + } + + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif // _DEBUG + } + + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif // _DEBUG + } + + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif // _DEBUG + } + + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nMASKEDBLENDING = 0; + m_nBASETEXTURE2 = 0; + m_nDETAILTEXTURE = 0; + m_nBUMPMAP = 0; + m_nBUMPMAP2 = 0; + m_nCUBEMAP = 0; + m_nENVMAPMASK = 0; + m_nBASEALPHAENVMAPMASK = 0; + m_nSELFILLUM = 0; + m_nNORMALMAPALPHAENVMAPMASK = 0; + m_nDIFFUSEBUMPMAP = 0; + m_nBASETEXTURENOENVMAP = 0; + m_nBASETEXTURE2NOENVMAP = 0; + m_nWARPLIGHTING = 0; + m_nFANCY_BLENDING = 0; + m_nSEAMLESS = 0; + m_nBUMPMASK = 0; + m_nBASETEXTURETRANSFORM2 = 0; + m_nPARALLAXCORRECT = 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = false; + m_bBASETEXTURE2 = false; + m_bDETAILTEXTURE = false; + m_bBUMPMAP = false; + m_bBUMPMAP2 = false; + m_bCUBEMAP = false; + m_bENVMAPMASK = false; + m_bBASEALPHAENVMAPMASK = false; + m_bSELFILLUM = false; + m_bNORMALMAPALPHAENVMAPMASK = false; + m_bDIFFUSEBUMPMAP = false; + m_bBASETEXTURENOENVMAP = false; + m_bBASETEXTURE2NOENVMAP = false; + m_bWARPLIGHTING = false; + m_bFANCY_BLENDING = false; + m_bSEAMLESS = false; + m_bBUMPMASK = false; + m_bBASETEXTURETRANSFORM2 = false; + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2 && m_bPARALLAXCORRECT ); + AssertMsg( !( m_nBUMPMAP2 && m_nWARPLIGHTING ), "Invalid combo combination ( BUMPMAP2 && WARPLIGHTING )" ); + AssertMsg( !( m_nWARPLIGHTING && m_nDETAILTEXTURE ), "Invalid combo combination ( WARPLIGHTING && DETAILTEXTURE )" ); + AssertMsg( !( m_nENVMAPMASK && m_nBUMPMAP ), "Invalid combo combination ( ENVMAPMASK && BUMPMAP )" ); + AssertMsg( !( m_nNORMALMAPALPHAENVMAPMASK && m_nBASEALPHAENVMAPMASK ), "Invalid combo combination ( NORMALMAPALPHAENVMAPMASK && BASEALPHAENVMAPMASK )" ); + AssertMsg( !( m_nNORMALMAPALPHAENVMAPMASK && m_nENVMAPMASK ), "Invalid combo combination ( NORMALMAPALPHAENVMAPMASK && ENVMAPMASK )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && m_nENVMAPMASK ), "Invalid combo combination ( BASEALPHAENVMAPMASK && ENVMAPMASK )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && m_nSELFILLUM ), "Invalid combo combination ( BASEALPHAENVMAPMASK && SELFILLUM )" ); + AssertMsg( !( !m_nBUMPMAP && m_nDIFFUSEBUMPMAP ), "Invalid combo combination ( !BUMPMAP && DIFFUSEBUMPMAP )" ); + AssertMsg( !( !m_nBUMPMAP && m_nBUMPMAP2 ), "Invalid combo combination ( !BUMPMAP && BUMPMAP2 )" ); + AssertMsg( !( !m_nBUMPMAP2 && m_nBUMPMASK ), "Invalid combo combination ( !BUMPMAP2 && BUMPMASK )" ); + AssertMsg( !( m_nENVMAPMASK && m_nBUMPMAP2 ), "Invalid combo combination ( ENVMAPMASK && BUMPMAP2 )" ); + AssertMsg( !( m_nBASETEXTURENOENVMAP && ( !m_nBASETEXTURE2 || !m_nCUBEMAP ) ), "Invalid combo combination ( BASETEXTURENOENVMAP && ( !BASETEXTURE2 || !CUBEMAP ) )" ); + AssertMsg( !( m_nBASETEXTURE2NOENVMAP && ( !m_nBASETEXTURE2 || !m_nCUBEMAP ) ), "Invalid combo combination ( BASETEXTURE2NOENVMAP && ( !BASETEXTURE2 || !CUBEMAP ) )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && m_nBUMPMAP ), "Invalid combo combination ( BASEALPHAENVMAPMASK && BUMPMAP )" ); + AssertMsg( !( m_nSEAMLESS && m_nDETAILTEXTURE ), "Invalid combo combination ( SEAMLESS && DETAILTEXTURE )" ); + AssertMsg( !( m_nSEAMLESS && m_nMASKEDBLENDING ), "Invalid combo combination ( SEAMLESS && MASKEDBLENDING )" ); + AssertMsg( !( m_nBUMPMASK && ( m_nSEAMLESS || ( m_nDETAILTEXTURE || ( m_nSELFILLUM || ( m_nBASETEXTURENOENVMAP || m_nBASETEXTURE2 ) ) ) ) ), "Invalid combo combination ( BUMPMASK && ( SEAMLESS || ( DETAILTEXTURE || ( SELFILLUM || ( BASETEXTURENOENVMAP || BASETEXTURE2 ) ) ) ) )" ); + AssertMsg( !( m_nFANCY_BLENDING && ( m_nBUMPMAP && m_nDETAILTEXTURE ) ), "Invalid combo combination ( FANCY_BLENDING && ( BUMPMAP && DETAILTEXTURE ) )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && !m_nBASETEXTURE2 ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && !BASETEXTURE2 )" ); + AssertMsg( !( m_nBASETEXTURETRANSFORM2 && m_nSEAMLESS ), "Invalid combo combination ( BASETEXTURETRANSFORM2 && SEAMLESS )" ); + AssertMsg( !( !m_nFANCY_BLENDING && m_nMASKEDBLENDING ), "Invalid combo combination ( !FANCY_BLENDING && MASKEDBLENDING )" ); + AssertMsg( !( m_nPARALLAXCORRECT && !m_nCUBEMAP ), "Invalid combo combination ( PARALLAXCORRECT && !CUBEMAP )" ); + AssertMsg( !m_nWARPLIGHTING, "Invalid combo combination WARPLIGHTING" ); + AssertMsg( !m_nBASETEXTURETRANSFORM2, "Invalid combo combination BASETEXTURETRANSFORM2" ); + return ( 384 * m_nMASKEDBLENDING ) + ( 768 * m_nBASETEXTURE2 ) + ( 1536 * m_nDETAILTEXTURE ) + ( 3072 * m_nBUMPMAP ) + ( 9216 * m_nBUMPMAP2 ) + ( 18432 * m_nCUBEMAP ) + ( 36864 * m_nENVMAPMASK ) + ( 73728 * m_nBASEALPHAENVMAPMASK ) + ( 147456 * m_nSELFILLUM ) + ( 294912 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 589824 * m_nDIFFUSEBUMPMAP ) + ( 1179648 * m_nBASETEXTURENOENVMAP ) + ( 2359296 * m_nBASETEXTURE2NOENVMAP ) + ( 4718592 * m_nWARPLIGHTING ) + ( 9437184 * m_nFANCY_BLENDING ) + ( 18874368 * m_nSEAMLESS ) + ( 37748736 * m_nBUMPMASK ) + ( 75497472 * m_nBASETEXTURETRANSFORM2 ) + ( 150994944 * m_nPARALLAXCORRECT ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + psh_forgot_to_set_static_PARALLAXCORRECT + + +class sdk_lightmappedgeneric_ps30_Dynamic_Index +{ + unsigned int m_nFASTPATHENVMAPCONTRAST : 2; + unsigned int m_nFASTPATH : 2; + unsigned int m_nWRITEWATERFOGTODESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nVANCE_CSM : 2; + unsigned int m_nVANCE_CSM_PERF : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST : 1; + bool m_bFASTPATH : 1; + bool m_bWRITEWATERFOGTODESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bVANCE_CSM : 1; + bool m_bVANCE_CSM_PERF : 1; +#endif // _DEBUG +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif // _DEBUG + } + + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif // _DEBUG + } + + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetVANCE_CSM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVANCE_CSM = i; +#ifdef _DEBUG + m_bVANCE_CSM = true; +#endif // _DEBUG + } + + void SetVANCE_CSM_PERF( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nVANCE_CSM_PERF = i; +#ifdef _DEBUG + m_bVANCE_CSM_PERF = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; + } + + sdk_lightmappedgeneric_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nFASTPATHENVMAPCONTRAST = 0; + m_nFASTPATH = 0; + m_nWRITEWATERFOGTODESTALPHA = 0; + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nVANCE_CSM = 0; + m_nVANCE_CSM_PERF = 0; + m_nLIGHTING_PREVIEW = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) != 0 ; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; + m_bFASTPATH = false; + m_bWRITEWATERFOGTODESTALPHA = false; + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bVANCE_CSM = false; + m_bVANCE_CSM_PERF = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bVANCE_CSM && m_bVANCE_CSM_PERF ); + AssertMsg( !( !m_nFASTPATH && m_nFASTPATHENVMAPCONTRAST ), "Invalid combo combination ( !FASTPATH && FASTPATHENVMAPCONTRAST )" ); + AssertMsg( !m_nFASTPATH, "Invalid combo combination FASTPATH" ); + AssertMsg( !m_nFASTPATHENVMAPCONTRAST, "Invalid combo combination FASTPATHENVMAPCONTRAST" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( m_nLIGHTING_PREVIEW && m_nFASTPATHENVMAPCONTRAST ) ) ), "Invalid combo combination ( 1 && ( 1 && ( LIGHTING_PREVIEW && FASTPATHENVMAPCONTRAST ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( m_nLIGHTING_PREVIEW && m_nFASTPATH ) ) ), "Invalid combo combination ( 1 && ( 1 && ( LIGHTING_PREVIEW && FASTPATH ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( m_nLIGHTING_PREVIEW && m_nFASTPATHENVMAPCONTRAST ) ) ), "Invalid combo combination ( 1 && ( 1 && ( LIGHTING_PREVIEW && FASTPATHENVMAPCONTRAST ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( m_nLIGHTING_PREVIEW && m_nFASTPATH ) ) ), "Invalid combo combination ( 1 && ( 1 && ( LIGHTING_PREVIEW && FASTPATH ) ) )" ); + AssertMsg( !m_nLIGHTING_PREVIEW, "Invalid combo combination LIGHTING_PREVIEW" ); + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 32 * m_nVANCE_CSM ) + ( 64 * m_nVANCE_CSM_PERF ) + ( 192 * m_nLIGHTING_PREVIEW ) + 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_VANCE_CSM + psh_forgot_to_set_dynamic_VANCE_CSM_PERF + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedgeneric_vs30.inc b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_vs30.inc new file mode 100644 index 00000000..463991c5 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedgeneric_vs30.inc @@ -0,0 +1,198 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $SEAMLESS && $BASETEXTURETRANSFORM2 +// !$BUMPMAP && $DIFFUSEBUMPMAP +// $SEAMLESS && $RELIEF_MAPPING +// $BUMPMASK && $RELIEF_MAPPING +// $BUMPMASK && $SEAMLESS +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_vs30_Static_Index +{ + unsigned int m_nENVMAP_MASK : 2; + unsigned int m_nTANGENTSPACE : 2; + unsigned int m_nBUMPMAP : 2; + unsigned int m_nDIFFUSEBUMPMAP : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nVERTEXALPHATEXBLENDFACTOR : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nBUMPMASK : 2; + unsigned int m_nBASETEXTURETRANSFORM2 : 2; +#ifdef _DEBUG + bool m_bENVMAP_MASK : 1; + bool m_bTANGENTSPACE : 1; + bool m_bBUMPMAP : 1; + bool m_bDIFFUSEBUMPMAP : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bVERTEXALPHATEXBLENDFACTOR : 1; + bool m_bSEAMLESS : 1; + bool m_bBUMPMASK : 1; + bool m_bBASETEXTURETRANSFORM2 : 1; +#endif // _DEBUG +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif // _DEBUG + } + + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif // _DEBUG + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif // _DEBUG + } + + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nENVMAP_MASK = 0; + m_nTANGENTSPACE = 0; + m_nBUMPMAP = 0; + m_nDIFFUSEBUMPMAP = 0; + m_nVERTEXCOLOR = 0; + m_nVERTEXALPHATEXBLENDFACTOR = 0; + m_nSEAMLESS = 0; + m_nBUMPMASK = 0; + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bENVMAP_MASK = false; + m_bTANGENTSPACE = false; + m_bBUMPMAP = false; + m_bDIFFUSEBUMPMAP = false; + m_bVERTEXCOLOR = false; + m_bVERTEXALPHATEXBLENDFACTOR = false; + m_bSEAMLESS = false; + m_bBUMPMASK = false; + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2 ); + AssertMsg( !( m_nSEAMLESS && m_nBASETEXTURETRANSFORM2 ), "Invalid combo combination ( SEAMLESS && BASETEXTURETRANSFORM2 )" ); + AssertMsg( !( !m_nBUMPMAP && m_nDIFFUSEBUMPMAP ), "Invalid combo combination ( !BUMPMAP && DIFFUSEBUMPMAP )" ); + AssertMsg( !( m_nBUMPMASK && m_nSEAMLESS ), "Invalid combo combination ( BUMPMASK && SEAMLESS )" ); + return ( 4 * m_nENVMAP_MASK ) + ( 8 * m_nTANGENTSPACE ) + ( 16 * m_nBUMPMAP ) + ( 32 * m_nDIFFUSEBUMPMAP ) + ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 256 * m_nSEAMLESS ) + ( 512 * m_nBUMPMASK ) + ( 1024 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + + +class sdk_lightmappedgeneric_vs30_Dynamic_Index +{ + unsigned int m_nFASTPATH : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; +#ifdef _DEBUG + bool m_bFASTPATH : 1; + bool m_bLIGHTING_PREVIEW : 1; +#endif // _DEBUG +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif // _DEBUG + } + + sdk_lightmappedgeneric_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nFASTPATH = 0; + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFASTPATH = false; + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFASTPATH && m_bLIGHTING_PREVIEW ); + AssertMsg( !( 1 && ( 1 && ( m_nLIGHTING_PREVIEW && m_nFASTPATH ) ) ), "Invalid combo combination ( 1 && ( 1 && ( LIGHTING_PREVIEW && FASTPATH ) ) )" ); + return ( 1 * m_nFASTPATH ) + ( 2 * m_nLIGHTING_PREVIEW ) + 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedreflective_ps30.inc b/materialsystem/stdshaders/include/sdk_lightmappedreflective_ps30.inc new file mode 100644 index 00000000..59b9fc34 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedreflective_ps30.inc @@ -0,0 +1,138 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nBASETEXTURE : 2; + unsigned int m_nREFLECT : 2; + unsigned int m_nREFRACT : 2; + unsigned int m_nENVMAPMASK : 2; +#ifdef _DEBUG + bool m_bBASETEXTURE : 1; + bool m_bREFLECT : 1; + bool m_bREFRACT : 1; + bool m_bENVMAPMASK : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif // _DEBUG + } + + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif // _DEBUG + } + + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + sdk_lightmappedreflective_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nBASETEXTURE = 0; + m_nREFLECT = 0; + m_nREFRACT = 0; + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURE = false; + m_bREFLECT = false; + m_bREFRACT = false; + m_bENVMAPMASK = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBASETEXTURE && m_bREFLECT && m_bREFRACT && m_bENVMAPMASK ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nREFLECT ) + ( 32 * m_nREFRACT ) + ( 64 * m_nENVMAPMASK ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedreflective_ps30 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ENVMAPMASK + + +class sdk_lightmappedreflective_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_lightmappedreflective_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedreflective_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_lightmappedreflective_vs30.inc b/materialsystem/stdshaders/include/sdk_lightmappedreflective_vs30.inc new file mode 100644 index 00000000..68075600 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_lightmappedreflective_vs30.inc @@ -0,0 +1,54 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_vs30_Static_Index +{ + unsigned int m_nBASETEXTURE : 2; +#ifdef _DEBUG + bool m_bBASETEXTURE : 1; +#endif // _DEBUG +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif // _DEBUG + } + + sdk_lightmappedreflective_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBASETEXTURE ); + return ( 1 * m_nBASETEXTURE ) + 0; + } +}; + +#define shaderStaticTest_sdk_lightmappedreflective_vs30 vsh_forgot_to_set_static_BASETEXTURE + + +class sdk_lightmappedreflective_vs30_Dynamic_Index +{ +public: + sdk_lightmappedreflective_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_lightmappedreflective_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_monitorscreen_ps30.inc b/materialsystem/stdshaders/include/sdk_monitorscreen_ps30.inc new file mode 100644 index 00000000..e77aa44e --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_monitorscreen_ps30.inc @@ -0,0 +1,98 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps30_Static_Index +{ + unsigned int m_nTEXTURE2 : 2; +#ifdef _DEBUG + bool m_bTEXTURE2 : 1; +#endif // _DEBUG +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif // _DEBUG + } + + sdk_monitorscreen_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nTEXTURE2 = 0; +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bTEXTURE2 ); + return ( 4 * m_nTEXTURE2 ) + 0; + } +}; + +#define shaderStaticTest_sdk_monitorscreen_ps30 psh_forgot_to_set_static_TEXTURE2 + + +class sdk_monitorscreen_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_monitorscreen_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_monitorscreen_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_refract_ps30.inc b/materialsystem/stdshaders/include/sdk_refract_ps30.inc new file mode 100644 index 00000000..787020e7 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_refract_ps30.inc @@ -0,0 +1,199 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $MASKED && $BLUR +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_refract_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nBLUR : 2; + unsigned int m_nFADEOUTONSILHOUETTE : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nREFRACTTINTTEXTURE : 2; + unsigned int m_nMASKED : 2; + unsigned int m_nCOLORMODULATE : 2; + unsigned int m_nSECONDARY_NORMAL : 2; + unsigned int m_nSHADER_SRGB_READ : 2; +#ifdef _DEBUG + bool m_bBLUR : 1; + bool m_bFADEOUTONSILHOUETTE : 1; + bool m_bCUBEMAP : 1; + bool m_bREFRACTTINTTEXTURE : 1; + bool m_bMASKED : 1; + bool m_bCOLORMODULATE : 1; + bool m_bSECONDARY_NORMAL : 1; + bool m_bSHADER_SRGB_READ : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetBLUR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLUR = i; +#ifdef _DEBUG + m_bBLUR = true; +#endif // _DEBUG + } + + void SetFADEOUTONSILHOUETTE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFADEOUTONSILHOUETTE = i; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetREFRACTTINTTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTTINTTEXTURE = i; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif // _DEBUG + } + + void SetMASKED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKED = i; +#ifdef _DEBUG + m_bMASKED = true; +#endif // _DEBUG + } + + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif // _DEBUG + } + + void SetSECONDARY_NORMAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSECONDARY_NORMAL = i; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif // _DEBUG + } + + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif // _DEBUG + } + + sdk_refract_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nBLUR = 0; + m_nFADEOUTONSILHOUETTE = 0; + m_nCUBEMAP = 0; + m_nREFRACTTINTTEXTURE = 0; + m_nMASKED = 0; + m_nCOLORMODULATE = 0; + m_nSECONDARY_NORMAL = 0; + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bBLUR = false; + m_bFADEOUTONSILHOUETTE = false; + m_bCUBEMAP = false; + m_bREFRACTTINTTEXTURE = false; + m_bMASKED = false; + m_bCOLORMODULATE = false; + m_bSECONDARY_NORMAL = false; + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBLUR && m_bFADEOUTONSILHOUETTE && m_bCUBEMAP && m_bREFRACTTINTTEXTURE && m_bMASKED && m_bCOLORMODULATE && m_bSECONDARY_NORMAL && m_bSHADER_SRGB_READ ); + AssertMsg( !( m_nMASKED && m_nBLUR ), "Invalid combo combination ( MASKED && BLUR )" ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBLUR ) + ( 16 * m_nFADEOUTONSILHOUETTE ) + ( 32 * m_nCUBEMAP ) + ( 64 * m_nREFRACTTINTTEXTURE ) + ( 128 * m_nMASKED ) + ( 256 * m_nCOLORMODULATE ) + ( 512 * m_nSECONDARY_NORMAL ) + ( 1024 * m_nSHADER_SRGB_READ ) + 0; + } +}; + +#define shaderStaticTest_sdk_refract_ps30 psh_forgot_to_set_static_BLUR + psh_forgot_to_set_static_FADEOUTONSILHOUETTE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_REFRACTTINTTEXTURE + psh_forgot_to_set_static_MASKED + psh_forgot_to_set_static_COLORMODULATE + psh_forgot_to_set_static_SECONDARY_NORMAL + psh_forgot_to_set_static_SHADER_SRGB_READ + + +class sdk_refract_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_refract_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_refract_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_refract_vs30.inc b/materialsystem/stdshaders/include/sdk_refract_vs30.inc new file mode 100644 index 00000000..a1fc7a9d --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_refract_vs30.inc @@ -0,0 +1,98 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_refract_vs30_Static_Index +{ + unsigned int m_nMODEL : 2; + unsigned int m_nCOLORMODULATE : 2; +#ifdef _DEBUG + bool m_bMODEL : 1; + bool m_bCOLORMODULATE : 1; +#endif // _DEBUG +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif // _DEBUG + } + + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif // _DEBUG + } + + sdk_refract_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nMODEL = 0; + m_nCOLORMODULATE = 0; +#ifdef _DEBUG + m_bMODEL = false; + m_bCOLORMODULATE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMODEL && m_bCOLORMODULATE ); + return ( 4 * m_nMODEL ) + ( 8 * m_nCOLORMODULATE ) + 0; + } +}; + +#define shaderStaticTest_sdk_refract_vs30 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_COLORMODULATE + + +class sdk_refract_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + sdk_refract_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_refract_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_screenspaceeffect_vs30.inc b/materialsystem/stdshaders/include/sdk_screenspaceeffect_vs30.inc new file mode 100644 index 00000000..c2b5aed5 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_screenspaceeffect_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_screenspaceeffect_vs30_Static_Index +{ +public: + sdk_screenspaceeffect_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_screenspaceeffect_vs30 1 + + +class sdk_screenspaceeffect_vs30_Dynamic_Index +{ +public: + sdk_screenspaceeffect_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_screenspaceeffect_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_shatteredglass_ps30.inc b/materialsystem/stdshaders/include/sdk_shatteredglass_ps30.inc new file mode 100644 index 00000000..f0539ffb --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_shatteredglass_ps30.inc @@ -0,0 +1,152 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $PARALLAXCORRECT && !$CUBEMAP +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_shatteredglass_ps30_Static_Index +{ + unsigned int m_nCUBEMAP : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nENVMAPMASK : 2; + unsigned int m_nBASEALPHAENVMAPMASK : 2; + unsigned int m_nHDRTYPE : 2; + unsigned int m_nPARALLAXCORRECT : 2; +#ifdef _DEBUG + bool m_bCUBEMAP : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bENVMAPMASK : 1; + bool m_bBASEALPHAENVMAPMASK : 1; + bool m_bHDRTYPE : 1; + bool m_bPARALLAXCORRECT : 1; +#endif // _DEBUG +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif // _DEBUG + } + + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif // _DEBUG + } + + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif // _DEBUG + } + + sdk_shatteredglass_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCUBEMAP = 0; + m_nVERTEXCOLOR = 0; + m_nENVMAPMASK = 0; + m_nBASEALPHAENVMAPMASK = 0; + m_nHDRTYPE = 0; + m_nPARALLAXCORRECT = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; + m_bVERTEXCOLOR = false; + m_bENVMAPMASK = false; + m_bBASEALPHAENVMAPMASK = false; + m_bHDRTYPE = false; + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCUBEMAP && m_bVERTEXCOLOR && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bHDRTYPE && m_bPARALLAXCORRECT ); + AssertMsg( !( m_nPARALLAXCORRECT && !m_nCUBEMAP ), "Invalid combo combination ( PARALLAXCORRECT && !CUBEMAP )" ); + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nENVMAPMASK ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nPARALLAXCORRECT ) + 0; + } +}; + +#define shaderStaticTest_sdk_shatteredglass_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_PARALLAXCORRECT + + +class sdk_shatteredglass_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_shatteredglass_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE ); + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_shatteredglass_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_shatteredglass_vs30.inc b/materialsystem/stdshaders/include/sdk_shatteredglass_vs30.inc new file mode 100644 index 00000000..d3e965ac --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_shatteredglass_vs30.inc @@ -0,0 +1,54 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_shatteredglass_vs30_Static_Index +{ + unsigned int m_nENVMAP_MASK : 2; +#ifdef _DEBUG + bool m_bENVMAP_MASK : 1; +#endif // _DEBUG +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif // _DEBUG + } + + sdk_shatteredglass_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bENVMAP_MASK ); + return ( 1 * m_nENVMAP_MASK ) + 0; + } +}; + +#define shaderStaticTest_sdk_shatteredglass_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + + +class sdk_shatteredglass_vs30_Dynamic_Index +{ +public: + sdk_shatteredglass_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_shatteredglass_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_skin_ps30.inc b/materialsystem/stdshaders/include/sdk_skin_ps30.inc new file mode 100644 index 00000000..b598b0b5 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_skin_ps30.inc @@ -0,0 +1,312 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) +// ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) +// ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) +// ( $BLENDTINTBYBASEALPHA ) && ( $SELFILLUM ) +// $ENVMAPMASK && !$CUBEMAP +// $FASTPATH_NOBUMP && ( $RIMLIGHT || $DETAILTEXTURE || $PHONGWARPTEXTURE || $SELFILLUM || $BLENDTINTBYBASEALPHA ) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_skin_ps30_Static_Index +{ + unsigned int m_nCUBEMAP : 2; + unsigned int m_nSELFILLUM : 2; + unsigned int m_nSELFILLUMFRESNEL : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nLIGHTWARPTEXTURE : 2; + unsigned int m_nPHONGWARPTEXTURE : 2; + unsigned int m_nWRINKLEMAP : 2; + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nRIMLIGHT : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; + unsigned int m_nFASTPATH_NOBUMP : 2; + unsigned int m_nBLENDTINTBYBASEALPHA : 2; + unsigned int m_nPHONG_HALFLAMBERT : 2; + unsigned int m_nENVMAPMASK : 2; +#ifdef _DEBUG + bool m_bCUBEMAP : 1; + bool m_bSELFILLUM : 1; + bool m_bSELFILLUMFRESNEL : 1; + bool m_bFLASHLIGHT : 1; + bool m_bLIGHTWARPTEXTURE : 1; + bool m_bPHONGWARPTEXTURE : 1; + bool m_bWRINKLEMAP : 1; + bool m_bDETAILTEXTURE : 1; + bool m_bRIMLIGHT : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; + bool m_bFASTPATH_NOBUMP : 1; + bool m_bBLENDTINTBYBASEALPHA : 1; + bool m_bPHONG_HALFLAMBERT : 1; + bool m_bENVMAPMASK : 1; +#endif // _DEBUG +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif // _DEBUG + } + + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif // _DEBUG + } + + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif // _DEBUG + } + + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif // _DEBUG + } + + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + void SetFASTPATH_NOBUMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH_NOBUMP = i; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif // _DEBUG + } + + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif // _DEBUG + } + + void SetPHONG_HALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG_HALFLAMBERT = i; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + sdk_skin_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCUBEMAP = 0; + m_nSELFILLUM = 0; + m_nSELFILLUMFRESNEL = 0; + m_nFLASHLIGHT = 0; + m_nLIGHTWARPTEXTURE = 0; + m_nPHONGWARPTEXTURE = 0; + m_nWRINKLEMAP = 0; + m_nDETAILTEXTURE = 0; + m_nRIMLIGHT = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + m_nFASTPATH_NOBUMP = 0; + m_nBLENDTINTBYBASEALPHA = 0; + m_nPHONG_HALFLAMBERT = 0; + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; + m_bSELFILLUM = false; + m_bSELFILLUMFRESNEL = false; + m_bFLASHLIGHT = false; + m_bLIGHTWARPTEXTURE = false; + m_bPHONGWARPTEXTURE = false; + m_bWRINKLEMAP = false; + m_bDETAILTEXTURE = false; + m_bRIMLIGHT = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; + m_bFASTPATH_NOBUMP = false; + m_bBLENDTINTBYBASEALPHA = false; + m_bPHONG_HALFLAMBERT = false; + m_bENVMAPMASK = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCUBEMAP && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bPHONGWARPTEXTURE && m_bWRINKLEMAP && m_bDETAILTEXTURE && m_bRIMLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFASTPATH_NOBUMP && m_bBLENDTINTBYBASEALPHA && m_bPHONG_HALFLAMBERT && m_bENVMAPMASK ); + AssertMsg( !( ( m_nFLASHLIGHT == 0 ) && ( m_nFLASHLIGHTDEPTHFILTERMODE != 0 ) ), "Invalid combo combination ( ( FLASHLIGHT == 0 ) && ( FLASHLIGHTDEPTHFILTERMODE != 0 ) )" ); + AssertMsg( !( ( m_nSELFILLUM == 0 ) && ( m_nSELFILLUMFRESNEL == 1 ) ), "Invalid combo combination ( ( SELFILLUM == 0 ) && ( SELFILLUMFRESNEL == 1 ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 1 ) && ( m_nSELFILLUMFRESNEL == 1 ) ), "Invalid combo combination ( ( FLASHLIGHT == 1 ) && ( SELFILLUMFRESNEL == 1 ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 1 ) && ( m_nSELFILLUM == 1 ) ), "Invalid combo combination ( ( FLASHLIGHT == 1 ) && ( SELFILLUM == 1 ) )" ); + AssertMsg( !( m_nBLENDTINTBYBASEALPHA && m_nSELFILLUM ), "Invalid combo combination ( BLENDTINTBYBASEALPHA && SELFILLUM )" ); + AssertMsg( !( m_nENVMAPMASK && !m_nCUBEMAP ), "Invalid combo combination ( ENVMAPMASK && !CUBEMAP )" ); + AssertMsg( !( m_nFASTPATH_NOBUMP && ( m_nRIMLIGHT || ( m_nDETAILTEXTURE || ( m_nPHONGWARPTEXTURE || ( m_nSELFILLUM || m_nBLENDTINTBYBASEALPHA ) ) ) ) ), "Invalid combo combination ( FASTPATH_NOBUMP && ( RIMLIGHT || ( DETAILTEXTURE || ( PHONGWARPTEXTURE || ( SELFILLUM || BLENDTINTBYBASEALPHA ) ) ) ) )" ); + return ( 16 * m_nCUBEMAP ) + ( 32 * m_nSELFILLUM ) + ( 64 * m_nSELFILLUMFRESNEL ) + ( 128 * m_nFLASHLIGHT ) + ( 256 * m_nLIGHTWARPTEXTURE ) + ( 512 * m_nPHONGWARPTEXTURE ) + ( 1024 * m_nWRINKLEMAP ) + ( 2048 * m_nDETAILTEXTURE ) + ( 4096 * m_nRIMLIGHT ) + ( 8192 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 24576 * m_nFASTPATH_NOBUMP ) + ( 49152 * m_nBLENDTINTBYBASEALPHA ) + ( 98304 * m_nPHONG_HALFLAMBERT ) + ( 196608 * m_nENVMAPMASK ) + 0; + } +}; + +#define shaderStaticTest_sdk_skin_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_PHONGWARPTEXTURE + psh_forgot_to_set_static_WRINKLEMAP + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_RIMLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_FASTPATH_NOBUMP + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_PHONG_HALFLAMBERT + psh_forgot_to_set_static_ENVMAPMASK + + +class sdk_skin_ps30_Dynamic_Index +{ + unsigned int m_nWRITEWATERFOGTODESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_skin_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITEWATERFOGTODESTALPHA = 0; + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS ); + AssertMsg( !( ( m_nPIXELFOGTYPE == 0 ) && ( m_nWRITEWATERFOGTODESTALPHA != 0 ) ), "Invalid combo combination ( ( PIXELFOGTYPE == 0 ) && ( WRITEWATERFOGTODESTALPHA != 0 ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_skin_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_skin_vs30.inc b/materialsystem/stdshaders/include/sdk_skin_vs30.inc new file mode 100644 index 00000000..1565e637 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_skin_vs30.inc @@ -0,0 +1,109 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_skin_vs30_Static_Index +{ + unsigned int m_nDECAL : 2; +#ifdef _DEBUG + bool m_bDECAL : 1; +#endif // _DEBUG +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif // _DEBUG + } + + sdk_skin_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nDECAL = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bDECAL ); + return ( 16 * m_nDECAL ) + 0; + } +}; + +#define shaderStaticTest_sdk_skin_vs30 vsh_forgot_to_set_static_DECAL + + +class sdk_skin_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bLIGHTING_PREVIEW : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_skin_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nLIGHTING_PREVIEW = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bLIGHTING_PREVIEW ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nLIGHTING_PREVIEW ) + ( 8 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_skin_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + diff --git a/materialsystem/stdshaders/include/sdk_splinerope_ps30.inc b/materialsystem/stdshaders/include/sdk_splinerope_ps30.inc new file mode 100644 index 00000000..727a7bf4 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_splinerope_ps30.inc @@ -0,0 +1,91 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_splinerope_ps30_Static_Index +{ + unsigned int m_nSHADOWDEPTH : 2; +#ifdef _DEBUG + bool m_bSHADOWDEPTH : 1; +#endif // _DEBUG +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif // _DEBUG + } + + sdk_splinerope_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nSHADOWDEPTH = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bSHADOWDEPTH ); + return ( 4 * m_nSHADOWDEPTH ) + 0; + } +}; + +#define shaderStaticTest_sdk_splinerope_ps30 psh_forgot_to_set_static_SHADOWDEPTH + + +class sdk_splinerope_ps30_Dynamic_Index +{ + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_splinerope_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE ); + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_splinerope_ps30 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_splinerope_vs30.inc b/materialsystem/stdshaders/include/sdk_splinerope_vs30.inc new file mode 100644 index 00000000..73b364fd --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_splinerope_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_splinerope_vs30_Static_Index +{ +public: + sdk_splinerope_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_splinerope_vs30 1 + + +class sdk_splinerope_vs30_Dynamic_Index +{ +public: + sdk_splinerope_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_splinerope_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_sprite_ps30.inc b/materialsystem/stdshaders/include/sdk_sprite_ps30.inc new file mode 100644 index 00000000..a9b67264 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_sprite_ps30.inc @@ -0,0 +1,145 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_sprite_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nCONSTANTCOLOR : 2; + unsigned int m_nHDRTYPE : 2; + unsigned int m_nSRGB : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; + bool m_bCONSTANTCOLOR : 1; + bool m_bHDRTYPE : 1; + bool m_bSRGB : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif // _DEBUG + } + + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif // _DEBUG + } + + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif // _DEBUG + } + + sdk_sprite_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nVERTEXCOLOR = 0; + m_nCONSTANTCOLOR = 0; + m_nHDRTYPE = 0; + m_nSRGB = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; + m_bCONSTANTCOLOR = false; + m_bHDRTYPE = false; + m_bSRGB = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nVERTEXCOLOR ) + ( 16 * m_nCONSTANTCOLOR ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nSRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_sprite_ps30 psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + + +class sdk_sprite_ps30_Dynamic_Index +{ + unsigned int m_nHDRENABLED : 2; + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bHDRENABLED : 1; + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_sprite_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nHDRENABLED = 0; + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bHDRENABLED = false; + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHDRENABLED && m_bPIXELFOGTYPE ); + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_sprite_ps30 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_sprite_vs30.inc b/materialsystem/stdshaders/include/sdk_sprite_vs30.inc new file mode 100644 index 00000000..7f8a2551 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_sprite_vs30.inc @@ -0,0 +1,67 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_sprite_vs30_Static_Index +{ + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nSRGB : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; + bool m_bSRGB : 1; +#endif // _DEBUG +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif // _DEBUG + } + + sdk_sprite_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXCOLOR = 0; + m_nSRGB = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; + m_bSRGB = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR && m_bSRGB ); + return ( 1 * m_nVERTEXCOLOR ) + ( 2 * m_nSRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_sprite_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_SRGB + + +class sdk_sprite_vs30_Dynamic_Index +{ +public: + sdk_sprite_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_sprite_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_teeth_bump_ps30.inc b/materialsystem/stdshaders/include/sdk_teeth_bump_ps30.inc new file mode 100644 index 00000000..bef23198 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_bump_ps30.inc @@ -0,0 +1,107 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_teeth_bump_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 40 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_bump_ps30 1 + + +class sdk_teeth_bump_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nNUM_LIGHTS : 3; + unsigned int m_nAMBIENT_LIGHT : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bNUM_LIGHTS : 1; + bool m_bAMBIENT_LIGHT : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_teeth_bump_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nNUM_LIGHTS = 0; + m_nAMBIENT_LIGHT = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bNUM_LIGHTS = false; + m_bAMBIENT_LIGHT = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 10 * m_nAMBIENT_LIGHT ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_bump_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_teeth_bump_vs30.inc b/materialsystem/stdshaders/include/sdk_teeth_bump_vs30.inc new file mode 100644 index 00000000..e25719d7 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_bump_vs30.inc @@ -0,0 +1,109 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_bump_vs30_Static_Index +{ + unsigned int m_nINTRO : 2; +#ifdef _DEBUG + bool m_bINTRO : 1; +#endif // _DEBUG +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif // _DEBUG + } + + sdk_teeth_bump_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nINTRO = 0; +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bINTRO ); + return ( 16 * m_nINTRO ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_static_INTRO + + +class sdk_teeth_bump_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nSTATIC_LIGHT : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bSTATIC_LIGHT : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_teeth_bump_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nSTATIC_LIGHT = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bSTATIC_LIGHT ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_STATIC_LIGHT + diff --git a/materialsystem/stdshaders/include/sdk_teeth_flashlight_ps30.inc b/materialsystem/stdshaders/include/sdk_teeth_flashlight_ps30.inc new file mode 100644 index 00000000..1ba5cc68 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_flashlight_ps30.inc @@ -0,0 +1,106 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + sdk_teeth_flashlight_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFLASHLIGHTDEPTHFILTERMODE ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + + +class sdk_teeth_flashlight_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_teeth_flashlight_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_teeth_flashlight_vs30.inc b/materialsystem/stdshaders/include/sdk_teeth_flashlight_vs30.inc new file mode 100644 index 00000000..021b199e --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_flashlight_vs30.inc @@ -0,0 +1,96 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_vs30_Static_Index +{ + unsigned int m_nINTRO : 2; +#ifdef _DEBUG + bool m_bINTRO : 1; +#endif // _DEBUG +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif // _DEBUG + } + + sdk_teeth_flashlight_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nINTRO = 0; +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bINTRO ); + return ( 8 * m_nINTRO ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_static_INTRO + + +class sdk_teeth_flashlight_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_teeth_flashlight_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_teeth_ps30.inc b/materialsystem/stdshaders/include/sdk_teeth_ps30.inc new file mode 100644 index 00000000..5e308716 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_ps30.inc @@ -0,0 +1,88 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_teeth_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_ps30 1 + + +class sdk_teeth_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_teeth_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_teeth_vs30.inc b/materialsystem/stdshaders/include/sdk_teeth_vs30.inc new file mode 100644 index 00000000..e90c2634 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_teeth_vs30.inc @@ -0,0 +1,122 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_teeth_vs30_Static_Index +{ + unsigned int m_nINTRO : 2; +#ifdef _DEBUG + bool m_bINTRO : 1; +#endif // _DEBUG +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif // _DEBUG + } + + sdk_teeth_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nINTRO = 0; +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bINTRO ); + return ( 32 * m_nINTRO ) + 0; + } +}; + +#define shaderStaticTest_sdk_teeth_vs30 vsh_forgot_to_set_static_INTRO + + +class sdk_teeth_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_teeth_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDYNAMIC_LIGHT ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_teeth_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + diff --git a/materialsystem/stdshaders/include/sdk_unlitgeneric_ps30.inc b/materialsystem/stdshaders/include/sdk_unlitgeneric_ps30.inc new file mode 100644 index 00000000..c68d43b5 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_unlitgeneric_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + sdk_unlitgeneric_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_sdk_unlitgeneric_ps30 1 + + +class sdk_unlitgeneric_ps30_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_unlitgeneric_ps30 1 + diff --git a/materialsystem/stdshaders/include/sdk_unlitgeneric_vs30.inc b/materialsystem/stdshaders/include/sdk_unlitgeneric_vs30.inc new file mode 100644 index 00000000..1897190b --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_unlitgeneric_vs30.inc @@ -0,0 +1,85 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_vs30_Static_Index +{ + unsigned int m_nVERTEXCOLOR : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; +#endif // _DEBUG +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + sdk_unlitgeneric_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR ); + return ( 4 * m_nVERTEXCOLOR ) + 0; + } +}; + +#define shaderStaticTest_sdk_unlitgeneric_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + + +class sdk_unlitgeneric_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + sdk_unlitgeneric_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_unlitgeneric_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_unlittwotexture_ps30.inc b/materialsystem/stdshaders/include/sdk_unlittwotexture_ps30.inc new file mode 100644 index 00000000..13bfb04e --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_unlittwotexture_ps30.inc @@ -0,0 +1,98 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps30_Static_Index +{ + unsigned int m_nTRANSLUCENT : 2; +#ifdef _DEBUG + bool m_bTRANSLUCENT : 1; +#endif // _DEBUG +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif // _DEBUG + } + + sdk_unlittwotexture_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nTRANSLUCENT = 0; +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bTRANSLUCENT ); + return ( 4 * m_nTRANSLUCENT ) + 0; + } +}; + +#define shaderStaticTest_sdk_unlittwotexture_ps30 psh_forgot_to_set_static_TRANSLUCENT + + +class sdk_unlittwotexture_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_unlittwotexture_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_unlittwotexture_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_unlittwotexture_vs30.inc b/materialsystem/stdshaders/include/sdk_unlittwotexture_vs30.inc new file mode 100644 index 00000000..248fe4d3 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_unlittwotexture_vs30.inc @@ -0,0 +1,67 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_vs30_Static_Index +{ +public: + sdk_unlittwotexture_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_sdk_unlittwotexture_vs30 1 + + +class sdk_unlittwotexture_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + sdk_unlittwotexture_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_unlittwotexture_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_ps30.inc b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_ps30.inc new file mode 100644 index 00000000..3125fc0c --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_ps30.inc @@ -0,0 +1,271 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) +// ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) +// ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) +// ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) +// ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) +// ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) +// ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) +// ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) +// $FLASHLIGHT && $CUBEMAP +// $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP +// $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// $ENVMAPMASK && !$CUBEMAP +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index +{ + unsigned int m_nCUBEMAP : 2; + unsigned int m_nDIFFUSELIGHTING : 2; + unsigned int m_nLIGHTWARPTEXTURE : 2; + unsigned int m_nSELFILLUM : 2; + unsigned int m_nSELFILLUMFRESNEL : 2; + unsigned int m_nNORMALMAPALPHAENVMAPMASK : 2; + unsigned int m_nHALFLAMBERT : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; + unsigned int m_nBLENDTINTBYBASEALPHA : 2; + unsigned int m_nENVMAPMASK : 2; +#ifdef _DEBUG + bool m_bCUBEMAP : 1; + bool m_bDIFFUSELIGHTING : 1; + bool m_bLIGHTWARPTEXTURE : 1; + bool m_bSELFILLUM : 1; + bool m_bSELFILLUMFRESNEL : 1; + bool m_bNORMALMAPALPHAENVMAPMASK : 1; + bool m_bHALFLAMBERT : 1; + bool m_bFLASHLIGHT : 1; + bool m_bDETAILTEXTURE : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; + bool m_bBLENDTINTBYBASEALPHA : 1; + bool m_bENVMAPMASK : 1; +#endif // _DEBUG +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif // _DEBUG + } + + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif // _DEBUG + } + + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif // _DEBUG + } + + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif // _DEBUG + } + + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif // _DEBUG + } + + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCUBEMAP = 0; + m_nDIFFUSELIGHTING = 0; + m_nLIGHTWARPTEXTURE = 0; + m_nSELFILLUM = 0; + m_nSELFILLUMFRESNEL = 0; + m_nNORMALMAPALPHAENVMAPMASK = 0; + m_nHALFLAMBERT = 0; + m_nFLASHLIGHT = 0; + m_nDETAILTEXTURE = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + m_nBLENDTINTBYBASEALPHA = 0; + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; + m_bDIFFUSELIGHTING = false; + m_bLIGHTWARPTEXTURE = false; + m_bSELFILLUM = false; + m_bSELFILLUMFRESNEL = false; + m_bNORMALMAPALPHAENVMAPMASK = false; + m_bHALFLAMBERT = false; + m_bFLASHLIGHT = false; + m_bDETAILTEXTURE = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; + m_bBLENDTINTBYBASEALPHA = false; + m_bENVMAPMASK = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK ); + AssertMsg( !( ( m_nFLASHLIGHT == 0 ) && ( m_nFLASHLIGHTDEPTHFILTERMODE != 0 ) ), "Invalid combo combination ( ( FLASHLIGHT == 0 ) && ( FLASHLIGHTDEPTHFILTERMODE != 0 ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 1 ) && ( m_nLIGHTWARPTEXTURE == 1 ) ), "Invalid combo combination ( ( FLASHLIGHT == 1 ) && ( LIGHTWARPTEXTURE == 1 ) )" ); + AssertMsg( !( ( m_nDIFFUSELIGHTING == 0 ) && ( m_nLIGHTWARPTEXTURE == 1 ) ), "Invalid combo combination ( ( DIFFUSELIGHTING == 0 ) && ( LIGHTWARPTEXTURE == 1 ) )" ); + AssertMsg( !( ( m_nSELFILLUMFRESNEL == 1 ) && ( m_nLIGHTWARPTEXTURE == 1 ) ), "Invalid combo combination ( ( SELFILLUMFRESNEL == 1 ) && ( LIGHTWARPTEXTURE == 1 ) )" ); + AssertMsg( !( ( m_nSELFILLUM == 0 ) && ( m_nSELFILLUMFRESNEL == 1 ) ), "Invalid combo combination ( ( SELFILLUM == 0 ) && ( SELFILLUMFRESNEL == 1 ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 1 ) && ( m_nSELFILLUMFRESNEL == 1 ) ), "Invalid combo combination ( ( FLASHLIGHT == 1 ) && ( SELFILLUMFRESNEL == 1 ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 1 ) && ( m_nSELFILLUM == 1 ) ), "Invalid combo combination ( ( FLASHLIGHT == 1 ) && ( SELFILLUM == 1 ) )" ); + AssertMsg( !( ( m_nSELFILLUMFRESNEL == 1 ) && ( m_nDETAILTEXTURE == 1 ) ), "Invalid combo combination ( ( SELFILLUMFRESNEL == 1 ) && ( DETAILTEXTURE == 1 ) )" ); + AssertMsg( !( ( m_nSELFILLUMFRESNEL == 1 ) && ( m_nNORMALMAPALPHAENVMAPMASK == 1 ) ), "Invalid combo combination ( ( SELFILLUMFRESNEL == 1 ) && ( NORMALMAPALPHAENVMAPMASK == 1 ) )" ); + AssertMsg( !( m_nBLENDTINTBYBASEALPHA && m_nSELFILLUM ), "Invalid combo combination ( BLENDTINTBYBASEALPHA && SELFILLUM )" ); + AssertMsg( !( m_nFLASHLIGHT && m_nCUBEMAP ), "Invalid combo combination ( FLASHLIGHT && CUBEMAP )" ); + AssertMsg( !( m_nNORMALMAPALPHAENVMAPMASK && !m_nCUBEMAP ), "Invalid combo combination ( NORMALMAPALPHAENVMAPMASK && !CUBEMAP )" ); + AssertMsg( !( m_nNORMALMAPALPHAENVMAPMASK && m_nENVMAPMASK ), "Invalid combo combination ( NORMALMAPALPHAENVMAPMASK && ENVMAPMASK )" ); + AssertMsg( !( m_nENVMAPMASK && !m_nCUBEMAP ), "Invalid combo combination ( ENVMAPMASK && !CUBEMAP )" ); + return ( 4 * m_nCUBEMAP ) + ( 8 * m_nDIFFUSELIGHTING ) + ( 16 * m_nLIGHTWARPTEXTURE ) + ( 32 * m_nSELFILLUM ) + ( 64 * m_nSELFILLUMFRESNEL ) + ( 128 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 256 * m_nHALFLAMBERT ) + ( 512 * m_nFLASHLIGHT ) + ( 1024 * m_nDETAILTEXTURE ) + ( 2048 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 6144 * m_nBLENDTINTBYBASEALPHA ) + ( 12288 * m_nENVMAPMASK ) + 0; + } +}; + +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + + +class sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index +{ + unsigned int m_nAMBIENT_LIGHT : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nAMBIENT_LIGHT = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS ); + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_vs30.inc b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_vs30.inc new file mode 100644 index 00000000..5fb6c71a --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_bump_vs30.inc @@ -0,0 +1,109 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index +{ + unsigned int m_nHALFLAMBERT : 2; + unsigned int m_nDECAL : 2; +#ifdef _DEBUG + bool m_bHALFLAMBERT : 1; + bool m_bDECAL : 1; +#endif // _DEBUG +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif // _DEBUG + } + + sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nHALFLAMBERT = 0; + m_nDECAL = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; + m_bDECAL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHALFLAMBERT && m_bDECAL ); + return ( 8 * m_nHALFLAMBERT ) + ( 16 * m_nDECAL ) + 0; + } +}; + +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_DECAL + + +class sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_ps30.inc b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_ps30.inc new file mode 100644 index 00000000..da4cd096 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_ps30.inc @@ -0,0 +1,380 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// $BASEALPHAENVMAPMASK && $ENVMAPMASK +// $BASEALPHAENVMAPMASK && $SELFILLUM +// $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) +// $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) +// ( $CUBEMAP == 0 ) && ( ( $ENVMAPFRESNEL == 1 ) || ( $BASEALPHAENVMAPMASK == 1 ) ) +// ( $CUBEMAP == 0 ) && ( $ENVMAPMASK == 1 ) && ( $SELFILLUM_ENVMAPMASK_ALPHA == 0 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) +// ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA || $ENVMAPFRESNEL) +// ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) +// $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) +// ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) +// $FLASHLIGHT && $CUBEMAP +// $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps30_Static_Index +{ + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nDIFFUSELIGHTING : 2; + unsigned int m_nENVMAPMASK : 2; + unsigned int m_nBASEALPHAENVMAPMASK : 2; + unsigned int m_nSELFILLUM : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nSELFILLUM_ENVMAPMASK_ALPHA : 2; + unsigned int m_nSEAMLESS_BASE : 2; + unsigned int m_nSEAMLESS_DETAIL : 2; + unsigned int m_nDISTANCEALPHA : 2; + unsigned int m_nDISTANCEALPHAFROMDETAIL : 2; + unsigned int m_nSOFT_MASK : 2; + unsigned int m_nOUTLINE : 2; + unsigned int m_nOUTER_GLOW : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; + unsigned int m_nDEPTHBLEND : 2; + unsigned int m_nBLENDTINTBYBASEALPHA : 2; + unsigned int m_nENVMAPFRESNEL : 2; +#ifdef _DEBUG + bool m_bDETAILTEXTURE : 1; + bool m_bCUBEMAP : 1; + bool m_bDIFFUSELIGHTING : 1; + bool m_bENVMAPMASK : 1; + bool m_bBASEALPHAENVMAPMASK : 1; + bool m_bSELFILLUM : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bFLASHLIGHT : 1; + bool m_bSELFILLUM_ENVMAPMASK_ALPHA : 1; + bool m_bSEAMLESS_BASE : 1; + bool m_bSEAMLESS_DETAIL : 1; + bool m_bDISTANCEALPHA : 1; + bool m_bDISTANCEALPHAFROMDETAIL : 1; + bool m_bSOFT_MASK : 1; + bool m_bOUTLINE : 1; + bool m_bOUTER_GLOW : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; + bool m_bDEPTHBLEND : 1; + bool m_bBLENDTINTBYBASEALPHA : 1; + bool m_bENVMAPFRESNEL : 1; +#endif // _DEBUG +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif // _DEBUG + } + + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif // _DEBUG + } + + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif // _DEBUG + } + + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif // _DEBUG + } + + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif // _DEBUG + } + + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif // _DEBUG + } + + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif // _DEBUG + } + + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif // _DEBUG + } + + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif // _DEBUG + } + + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif // _DEBUG + } + + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif // _DEBUG + } + + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif // _DEBUG + } + + void SetENVMAPFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPFRESNEL = i; +#ifdef _DEBUG + m_bENVMAPFRESNEL = true; +#endif // _DEBUG + } + + sdk_vertexlit_and_unlit_generic_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nDETAILTEXTURE = 0; + m_nCUBEMAP = 0; + m_nDIFFUSELIGHTING = 0; + m_nENVMAPMASK = 0; + m_nBASEALPHAENVMAPMASK = 0; + m_nSELFILLUM = 0; + m_nVERTEXCOLOR = 0; + m_nFLASHLIGHT = 0; + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; + m_nSEAMLESS_BASE = 0; + m_nSEAMLESS_DETAIL = 0; + m_nDISTANCEALPHA = 0; + m_nDISTANCEALPHAFROMDETAIL = 0; + m_nSOFT_MASK = 0; + m_nOUTLINE = 0; + m_nOUTER_GLOW = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + m_nDEPTHBLEND = 0; + m_nBLENDTINTBYBASEALPHA = 0; + m_nENVMAPFRESNEL = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; + m_bCUBEMAP = false; + m_bDIFFUSELIGHTING = false; + m_bENVMAPMASK = false; + m_bBASEALPHAENVMAPMASK = false; + m_bSELFILLUM = false; + m_bVERTEXCOLOR = false; + m_bFLASHLIGHT = false; + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; + m_bSEAMLESS_BASE = false; + m_bSEAMLESS_DETAIL = false; + m_bDISTANCEALPHA = false; + m_bDISTANCEALPHAFROMDETAIL = false; + m_bSOFT_MASK = false; + m_bOUTLINE = false; + m_bOUTER_GLOW = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; + m_bDEPTHBLEND = false; + m_bBLENDTINTBYBASEALPHA = false; + m_bENVMAPFRESNEL = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bENVMAPFRESNEL ); + AssertMsg( !( ( m_nDETAILTEXTURE == 0 ) && m_nSEAMLESS_DETAIL ), "Invalid combo combination ( ( DETAILTEXTURE == 0 ) && SEAMLESS_DETAIL )" ); + AssertMsg( !( ( m_nENVMAPMASK || m_nSELFILLUM_ENVMAPMASK_ALPHA ) && ( m_nSEAMLESS_BASE || m_nSEAMLESS_DETAIL ) ), "Invalid combo combination ( ( ENVMAPMASK || SELFILLUM_ENVMAPMASK_ALPHA ) && ( SEAMLESS_BASE || SEAMLESS_DETAIL ) )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && m_nENVMAPMASK ), "Invalid combo combination ( BASEALPHAENVMAPMASK && ENVMAPMASK )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && m_nSELFILLUM ), "Invalid combo combination ( BASEALPHAENVMAPMASK && SELFILLUM )" ); + AssertMsg( !( m_nSELFILLUM && m_nSELFILLUM_ENVMAPMASK_ALPHA ), "Invalid combo combination ( SELFILLUM && SELFILLUM_ENVMAPMASK_ALPHA )" ); + AssertMsg( !( m_nSELFILLUM_ENVMAPMASK_ALPHA && !m_nENVMAPMASK ), "Invalid combo combination ( SELFILLUM_ENVMAPMASK_ALPHA && !ENVMAPMASK )" ); + AssertMsg( !( m_nBASEALPHAENVMAPMASK && ( m_nSEAMLESS_BASE || m_nSEAMLESS_DETAIL ) ), "Invalid combo combination ( BASEALPHAENVMAPMASK && ( SEAMLESS_BASE || SEAMLESS_DETAIL ) )" ); + AssertMsg( !( ( m_nDISTANCEALPHA == 0 ) && ( m_nDISTANCEALPHAFROMDETAIL || ( m_nSOFT_MASK || ( m_nOUTLINE || m_nOUTER_GLOW ) ) ) ), "Invalid combo combination ( ( DISTANCEALPHA == 0 ) && ( DISTANCEALPHAFROMDETAIL || ( SOFT_MASK || ( OUTLINE || OUTER_GLOW ) ) ) )" ); + AssertMsg( !( ( m_nDETAILTEXTURE == 0 ) && m_nDISTANCEALPHAFROMDETAIL ), "Invalid combo combination ( ( DETAILTEXTURE == 0 ) && DISTANCEALPHAFROMDETAIL )" ); + AssertMsg( !( ( m_nCUBEMAP == 0 ) && ( ( m_nENVMAPFRESNEL == 1 ) || ( m_nBASEALPHAENVMAPMASK == 1 ) ) ), "Invalid combo combination ( ( CUBEMAP == 0 ) && ( ( ENVMAPFRESNEL == 1 ) || ( BASEALPHAENVMAPMASK == 1 ) ) )" ); + AssertMsg( !( ( m_nCUBEMAP == 0 ) && ( ( m_nENVMAPMASK == 1 ) && ( m_nSELFILLUM_ENVMAPMASK_ALPHA == 0 ) ) ), "Invalid combo combination ( ( CUBEMAP == 0 ) && ( ( ENVMAPMASK == 1 ) && ( SELFILLUM_ENVMAPMASK_ALPHA == 0 ) ) )" ); + AssertMsg( !( ( m_nFLASHLIGHT == 0 ) && ( m_nFLASHLIGHTDEPTHFILTERMODE != 0 ) ), "Invalid combo combination ( ( FLASHLIGHT == 0 ) && ( FLASHLIGHTDEPTHFILTERMODE != 0 ) )" ); + AssertMsg( !( m_nDISTANCEALPHA && ( m_nENVMAPMASK || ( m_nBASEALPHAENVMAPMASK || ( m_nSELFILLUM || ( m_nSELFILLUM_ENVMAPMASK_ALPHA || m_nENVMAPFRESNEL ) ) ) ) ), "Invalid combo combination ( DISTANCEALPHA && ( ENVMAPMASK || ( BASEALPHAENVMAPMASK || ( SELFILLUM || ( SELFILLUM_ENVMAPMASK_ALPHA || ENVMAPFRESNEL ) ) ) ) )" ); + AssertMsg( !( m_nSEAMLESS_BASE && m_nBLENDTINTBYBASEALPHA ), "Invalid combo combination ( SEAMLESS_BASE && BLENDTINTBYBASEALPHA )" ); + AssertMsg( !( m_nBLENDTINTBYBASEALPHA && ( m_nSELFILLUM || ( ( m_nDISTANCEALPHA && ( m_nDISTANCEALPHAFROMDETAIL == 0 ) ) || m_nBASEALPHAENVMAPMASK ) ) ), "Invalid combo combination ( BLENDTINTBYBASEALPHA && ( SELFILLUM || ( ( DISTANCEALPHA && ( DISTANCEALPHAFROMDETAIL == 0 ) ) || BASEALPHAENVMAPMASK ) ) )" ); + AssertMsg( !( m_nFLASHLIGHT && m_nCUBEMAP ), "Invalid combo combination ( FLASHLIGHT && CUBEMAP )" ); + return ( 4 * m_nDETAILTEXTURE ) + ( 8 * m_nCUBEMAP ) + ( 16 * m_nDIFFUSELIGHTING ) + ( 32 * m_nENVMAPMASK ) + ( 64 * m_nBASEALPHAENVMAPMASK ) + ( 128 * m_nSELFILLUM ) + ( 256 * m_nVERTEXCOLOR ) + ( 512 * m_nFLASHLIGHT ) + ( 1024 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 2048 * m_nSEAMLESS_BASE ) + ( 4096 * m_nSEAMLESS_DETAIL ) + ( 8192 * m_nDISTANCEALPHA ) + ( 16384 * m_nDISTANCEALPHAFROMDETAIL ) + ( 32768 * m_nSOFT_MASK ) + ( 65536 * m_nOUTLINE ) + ( 131072 * m_nOUTER_GLOW ) + ( 262144 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 786432 * m_nDEPTHBLEND ) + ( 1572864 * m_nBLENDTINTBYBASEALPHA ) + ( 3145728 * m_nENVMAPFRESNEL ) + 0; + } +}; + +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPFRESNEL + + +class sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index +{ + unsigned int m_nFLASHLIGHTSHADOWS : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; + } + + sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nFLASHLIGHTSHADOWS = 0; + m_nLIGHTING_PREVIEW = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) != 0 ; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFLASHLIGHTSHADOWS ); + AssertMsg( !m_nLIGHTING_PREVIEW, "Invalid combo combination LIGHTING_PREVIEW" ); + return ( 1 * m_nFLASHLIGHTSHADOWS ) + ( 2 * m_nLIGHTING_PREVIEW ) + 0; + } +}; + +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_vs30.inc b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_vs30.inc new file mode 100644 index 00000000..9cfef612 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_vertexlit_and_unlit_generic_vs30.inc @@ -0,0 +1,258 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) +// ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) +// ( $TREESWAY ) && ( $SEAMLESS_DETAIL || $SEAMLESS_BASE ) +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// $DECAL && $MORPHING == 0 +// $MORPHING + +#pragma once +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_vs30_Static_Index +{ + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nHALFLAMBERT : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nSEAMLESS_BASE : 2; + unsigned int m_nSEAMLESS_DETAIL : 2; + unsigned int m_nSEPARATE_DETAIL_UVS : 2; + unsigned int m_nDECAL : 2; + unsigned int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR : 2; + unsigned int m_nTREESWAY : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; + bool m_bCUBEMAP : 1; + bool m_bHALFLAMBERT : 1; + bool m_bFLASHLIGHT : 1; + bool m_bSEAMLESS_BASE : 1; + bool m_bSEAMLESS_DETAIL : 1; + bool m_bSEPARATE_DETAIL_UVS : 1; + bool m_bDECAL : 1; + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR : 1; + bool m_bTREESWAY : 1; +#endif // _DEBUG +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif // _DEBUG + } + + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif // _DEBUG + } + + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif // _DEBUG + } + + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif // _DEBUG + } + + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif // _DEBUG + } + + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif // _DEBUG + } + + sdk_vertexlit_and_unlit_generic_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXCOLOR = 0; + m_nCUBEMAP = 0; + m_nHALFLAMBERT = 0; + m_nFLASHLIGHT = 0; + m_nSEAMLESS_BASE = 0; + m_nSEAMLESS_DETAIL = 0; + m_nSEPARATE_DETAIL_UVS = 0; + m_nDECAL = 0; + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; + m_nTREESWAY = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; + m_bCUBEMAP = false; + m_bHALFLAMBERT = false; + m_bFLASHLIGHT = false; + m_bSEAMLESS_BASE = false; + m_bSEAMLESS_DETAIL = false; + m_bSEPARATE_DETAIL_UVS = false; + m_bDECAL = false; + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; + m_bTREESWAY = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bDECAL && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR && m_bTREESWAY ); + AssertMsg( !( m_nSEPARATE_DETAIL_UVS && m_nSEAMLESS_DETAIL ), "Invalid combo combination ( SEPARATE_DETAIL_UVS && SEAMLESS_DETAIL )" ); + AssertMsg( !( m_nDONT_GAMMA_CONVERT_VERTEX_COLOR && !m_nVERTEXCOLOR ), "Invalid combo combination ( DONT_GAMMA_CONVERT_VERTEX_COLOR && !VERTEXCOLOR )" ); + AssertMsg( !( m_nTREESWAY && ( m_nSEAMLESS_DETAIL || m_nSEAMLESS_BASE ) ), "Invalid combo combination ( TREESWAY && ( SEAMLESS_DETAIL || SEAMLESS_BASE ) )" ); + return ( 64 * m_nVERTEXCOLOR ) + ( 128 * m_nCUBEMAP ) + ( 256 * m_nHALFLAMBERT ) + ( 512 * m_nFLASHLIGHT ) + ( 1024 * m_nSEAMLESS_BASE ) + ( 2048 * m_nSEAMLESS_DETAIL ) + ( 4096 * m_nSEPARATE_DETAIL_UVS ) + ( 8192 * m_nDECAL ) + ( 16384 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + ( 32768 * m_nTREESWAY ) + 0; + } +}; + +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + vsh_forgot_to_set_static_TREESWAY + + +class sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; + unsigned int m_nMORPHING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; + bool m_bSKINNING : 1; + bool m_bLIGHTING_PREVIEW : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif // _DEBUG + } + + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; + } + + sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; + m_nSKINNING = 0; + m_nLIGHTING_PREVIEW = 0; + m_nMORPHING = pShaderAPI->IsHWMorphingEnabled() ; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; + m_bSKINNING = false; + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bSKINNING && m_bLIGHTING_PREVIEW ); + AssertMsg( !m_nMORPHING, "Invalid combo combination MORPHING" ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nSKINNING ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 32 * m_nMORPHING ) + 0; + } +}; + +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + diff --git a/materialsystem/stdshaders/include/sdk_vertexlit_lighting_only_ps30.inc b/materialsystem/stdshaders/include/sdk_vertexlit_lighting_only_ps30.inc new file mode 100644 index 00000000..049186ae --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_vertexlit_lighting_only_ps30.inc @@ -0,0 +1,112 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_vertexlit_lighting_only_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nDIFFUSELIGHTING : 2; + unsigned int m_nHALFLAMBERT : 2; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING : 1; + bool m_bHALFLAMBERT : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif // _DEBUG + } + + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif // _DEBUG + } + + sdk_vertexlit_lighting_only_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nDIFFUSELIGHTING = 0; + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; + m_bHALFLAMBERT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bDIFFUSELIGHTING && m_bHALFLAMBERT ); + return ( 10 * m_nCONVERT_TO_SRGB ) + ( 20 * m_nDIFFUSELIGHTING ) + ( 40 * m_nHALFLAMBERT ) + 0; + } +}; + +#define shaderStaticTest_sdk_vertexlit_lighting_only_ps30 psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_HALFLAMBERT + + +class sdk_vertexlit_lighting_only_ps30_Dynamic_Index +{ + unsigned int m_nAMBIENT_LIGHT : 2; + unsigned int m_nNUM_LIGHTS : 3; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT : 1; + bool m_bNUM_LIGHTS : 1; +#endif // _DEBUG +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif // _DEBUG + } + + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + sdk_vertexlit_lighting_only_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nAMBIENT_LIGHT = 0; + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; + m_bNUM_LIGHTS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bAMBIENT_LIGHT && m_bNUM_LIGHTS ); + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nNUM_LIGHTS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_vertexlit_lighting_only_ps30 psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + diff --git a/materialsystem/stdshaders/include/sdk_water_ps30.inc b/materialsystem/stdshaders/include/sdk_water_ps30.inc new file mode 100644 index 00000000..ea907f9b --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_water_ps30.inc @@ -0,0 +1,166 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $MULTITEXTURE && $BASETEXTURE +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_water_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nBASETEXTURE : 2; + unsigned int m_nMULTITEXTURE : 2; + unsigned int m_nREFLECT : 2; + unsigned int m_nREFRACT : 2; + unsigned int m_nABOVEWATER : 2; + unsigned int m_nBLURRY_REFRACT : 2; +#ifdef _DEBUG + bool m_bBASETEXTURE : 1; + bool m_bMULTITEXTURE : 1; + bool m_bREFLECT : 1; + bool m_bREFRACT : 1; + bool m_bABOVEWATER : 1; + bool m_bBLURRY_REFRACT : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif // _DEBUG + } + + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif // _DEBUG + } + + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif // _DEBUG + } + + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif // _DEBUG + } + + void SetABOVEWATER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nABOVEWATER = i; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif // _DEBUG + } + + void SetBLURRY_REFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRY_REFRACT = i; +#ifdef _DEBUG + m_bBLURRY_REFRACT = true; +#endif // _DEBUG + } + + sdk_water_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nBASETEXTURE = 0; + m_nMULTITEXTURE = 0; + m_nREFLECT = 0; + m_nREFRACT = 0; + m_nABOVEWATER = 0; + m_nBLURRY_REFRACT = 0; +#ifdef _DEBUG + m_bBASETEXTURE = false; + m_bMULTITEXTURE = false; + m_bREFLECT = false; + m_bREFRACT = false; + m_bABOVEWATER = false; + m_bBLURRY_REFRACT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBASETEXTURE && m_bMULTITEXTURE && m_bREFLECT && m_bREFRACT && m_bABOVEWATER && m_bBLURRY_REFRACT ); + AssertMsg( !( m_nMULTITEXTURE && m_nBASETEXTURE ), "Invalid combo combination ( MULTITEXTURE && BASETEXTURE )" ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nMULTITEXTURE ) + ( 32 * m_nREFLECT ) + ( 64 * m_nREFRACT ) + ( 128 * m_nABOVEWATER ) + ( 256 * m_nBLURRY_REFRACT ) + 0; + } +}; + +#define shaderStaticTest_sdk_water_ps30 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ABOVEWATER + psh_forgot_to_set_static_BLURRY_REFRACT + + +class sdk_water_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + sdk_water_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA ); + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; + +#define shaderDynamicTest_sdk_water_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + diff --git a/materialsystem/stdshaders/include/sdk_water_vs30.inc b/materialsystem/stdshaders/include/sdk_water_vs30.inc new file mode 100644 index 00000000..754f7f50 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_water_vs30.inc @@ -0,0 +1,69 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $MULTITEXTURE && $BASETEXTURE +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_water_vs30_Static_Index +{ + unsigned int m_nBASETEXTURE : 2; + unsigned int m_nMULTITEXTURE : 2; +#ifdef _DEBUG + bool m_bBASETEXTURE : 1; + bool m_bMULTITEXTURE : 1; +#endif // _DEBUG +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif // _DEBUG + } + + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif // _DEBUG + } + + sdk_water_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nBASETEXTURE = 0; + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bBASETEXTURE = false; + m_bMULTITEXTURE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBASETEXTURE && m_bMULTITEXTURE ); + AssertMsg( !( m_nMULTITEXTURE && m_nBASETEXTURE ), "Invalid combo combination ( MULTITEXTURE && BASETEXTURE )" ); + return ( 1 * m_nBASETEXTURE ) + ( 2 * m_nMULTITEXTURE ) + 0; + } +}; + +#define shaderStaticTest_sdk_water_vs30 vsh_forgot_to_set_static_BASETEXTURE + vsh_forgot_to_set_static_MULTITEXTURE + + +class sdk_water_vs30_Dynamic_Index +{ +public: + sdk_water_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_water_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_watercheap_ps30.inc b/materialsystem/stdshaders/include/sdk_watercheap_ps30.inc new file mode 100644 index 00000000..830b73cd --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_watercheap_ps30.inc @@ -0,0 +1,151 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_watercheap_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nMULTITEXTURE : 2; + unsigned int m_nFRESNEL : 2; + unsigned int m_nBLEND : 2; + unsigned int m_nREFRACTALPHA : 2; + unsigned int m_nHDRTYPE : 2; +#ifdef _DEBUG + bool m_bMULTITEXTURE : 1; + bool m_bFRESNEL : 1; + bool m_bBLEND : 1; + bool m_bREFRACTALPHA : 1; + bool m_bHDRTYPE : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif // _DEBUG + } + + void SetFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFRESNEL = i; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif // _DEBUG + } + + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif // _DEBUG + } + + void SetREFRACTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTALPHA = i; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif // _DEBUG + } + + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif // _DEBUG + } + + sdk_watercheap_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nMULTITEXTURE = 0; + m_nFRESNEL = 0; + m_nBLEND = 0; + m_nREFRACTALPHA = 0; + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; + m_bFRESNEL = false; + m_bBLEND = false; + m_bREFRACTALPHA = false; + m_bHDRTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMULTITEXTURE && m_bFRESNEL && m_bBLEND && m_bREFRACTALPHA && m_bHDRTYPE ); + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nMULTITEXTURE ) + ( 16 * m_nFRESNEL ) + ( 32 * m_nBLEND ) + ( 64 * m_nREFRACTALPHA ) + ( 128 * m_nHDRTYPE ) + 0; + } +}; + +#define shaderStaticTest_sdk_watercheap_ps30 psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_FRESNEL + psh_forgot_to_set_static_BLEND + psh_forgot_to_set_static_REFRACTALPHA + psh_forgot_to_set_static_HDRTYPE + + +class sdk_watercheap_ps30_Dynamic_Index +{ + unsigned int m_nHDRENABLED : 2; + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bHDRENABLED : 1; + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_watercheap_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nHDRENABLED = 0; + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bHDRENABLED = false; + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bHDRENABLED && m_bPIXELFOGTYPE ); + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_watercheap_ps30 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_watercheap_vs30.inc b/materialsystem/stdshaders/include/sdk_watercheap_vs30.inc new file mode 100644 index 00000000..9f80e53e --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_watercheap_vs30.inc @@ -0,0 +1,54 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_watercheap_vs30_Static_Index +{ + unsigned int m_nBLEND : 2; +#ifdef _DEBUG + bool m_bBLEND : 1; +#endif // _DEBUG +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif // _DEBUG + } + + sdk_watercheap_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nBLEND = 0; +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bBLEND ); + return ( 1 * m_nBLEND ) + 0; + } +}; + +#define shaderStaticTest_sdk_watercheap_vs30 vsh_forgot_to_set_static_BLEND + + +class sdk_watercheap_vs30_Dynamic_Index +{ +public: + sdk_watercheap_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_watercheap_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_windowimposter_ps30.inc b/materialsystem/stdshaders/include/sdk_windowimposter_ps30.inc new file mode 100644 index 00000000..93a0b482 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_windowimposter_ps30.inc @@ -0,0 +1,85 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_windowimposter_ps30_Static_Index +{ + unsigned int m_nPARALLAXCORRECT : 2; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT : 1; +#endif // _DEBUG +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif // _DEBUG + } + + sdk_windowimposter_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nPARALLAXCORRECT = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPARALLAXCORRECT ); + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; + +#define shaderStaticTest_sdk_windowimposter_ps30 psh_forgot_to_set_static_PARALLAXCORRECT + + +class sdk_windowimposter_ps30_Dynamic_Index +{ + unsigned int m_nPIXELFOGTYPE : 2; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE : 1; +#endif // _DEBUG +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + sdk_windowimposter_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPIXELFOGTYPE ); + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; + +#define shaderDynamicTest_sdk_windowimposter_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + diff --git a/materialsystem/stdshaders/include/sdk_windowimposter_vs30.inc b/materialsystem/stdshaders/include/sdk_windowimposter_vs30.inc new file mode 100644 index 00000000..d3ae39c3 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_windowimposter_vs30.inc @@ -0,0 +1,54 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class sdk_windowimposter_vs30_Static_Index +{ + unsigned int m_nPARALLAXCORRECT : 2; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT : 1; +#endif // _DEBUG +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif // _DEBUG + } + + sdk_windowimposter_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nPARALLAXCORRECT = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bPARALLAXCORRECT ); + return ( 1 * m_nPARALLAXCORRECT ) + 0; + } +}; + +#define shaderStaticTest_sdk_windowimposter_vs30 vsh_forgot_to_set_static_PARALLAXCORRECT + + +class sdk_windowimposter_vs30_Dynamic_Index +{ +public: + sdk_windowimposter_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_sdk_windowimposter_vs30 1 + diff --git a/materialsystem/stdshaders/include/sdk_worldtwotextureblend_ps30.inc b/materialsystem/stdshaders/include/sdk_worldtwotextureblend_ps30.inc new file mode 100644 index 00000000..6632e0b1 --- /dev/null +++ b/materialsystem/stdshaders/include/sdk_worldtwotextureblend_ps30.inc @@ -0,0 +1,248 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// $DETAILTEXTURE && ( $BUMPMAP && !$DETAIL_ALPHA_MASK_BASE_TEXTURE ) +// !$BUMPMAP && $DIFFUSEBUMPMAP +// $VERTEXCOLOR && $BUMPMAP +// FLASHLIGHT && $SELFILLUM +// FLASHLIGHT && $DETAIL_ALPHA_MASK_BASE_TEXTURE +// FLASHLIGHT && ($BUMPMAP || $DIFFUSEBUMPMAP) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class sdk_worldtwotextureblend_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; + unsigned int m_nDETAILTEXTURE : 2; + unsigned int m_nBUMPMAP : 2; + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nSELFILLUM : 2; + unsigned int m_nDIFFUSEBUMPMAP : 2; + unsigned int m_nDETAIL_ALPHA_MASK_BASE_TEXTURE : 2; + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nSEAMLESS : 2; + unsigned int m_nFLASHLIGHTDEPTHFILTERMODE : 2; +#ifdef _DEBUG + bool m_bDETAILTEXTURE : 1; + bool m_bBUMPMAP : 1; + bool m_bVERTEXCOLOR : 1; + bool m_bSELFILLUM : 1; + bool m_bDIFFUSEBUMPMAP : 1; + bool m_bDETAIL_ALPHA_MASK_BASE_TEXTURE : 1; + bool m_bFLASHLIGHT : 1; + bool m_bSEAMLESS : 1; + bool m_bFLASHLIGHTDEPTHFILTERMODE : 1; +#endif // _DEBUG +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif // _DEBUG + } + + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif // _DEBUG + } + + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif // _DEBUG + } + + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif // _DEBUG + } + + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif // _DEBUG + } + + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif // _DEBUG + } + + sdk_worldtwotextureblend_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + m_nDETAILTEXTURE = 0; + m_nBUMPMAP = 0; + m_nVERTEXCOLOR = 0; + m_nSELFILLUM = 0; + m_nDIFFUSEBUMPMAP = 0; + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = 0; + m_nFLASHLIGHT = 0; + m_nSEAMLESS = 0; + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; + m_bBUMPMAP = false; + m_bVERTEXCOLOR = false; + m_bSELFILLUM = false; + m_bDIFFUSEBUMPMAP = false; + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = false; + m_bFLASHLIGHT = false; + m_bSEAMLESS = false; + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bDETAILTEXTURE && m_bBUMPMAP && m_bVERTEXCOLOR && m_bSELFILLUM && m_bDIFFUSEBUMPMAP && m_bDETAIL_ALPHA_MASK_BASE_TEXTURE && m_bFLASHLIGHT && m_bSEAMLESS && m_bFLASHLIGHTDEPTHFILTERMODE ); + AssertMsg( !( m_nDETAILTEXTURE && ( m_nBUMPMAP && !m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) ), "Invalid combo combination ( DETAILTEXTURE && ( BUMPMAP && !DETAIL_ALPHA_MASK_BASE_TEXTURE ) )" ); + AssertMsg( !( !m_nBUMPMAP && m_nDIFFUSEBUMPMAP ), "Invalid combo combination ( !BUMPMAP && DIFFUSEBUMPMAP )" ); + AssertMsg( !( m_nVERTEXCOLOR && m_nBUMPMAP ), "Invalid combo combination ( VERTEXCOLOR && BUMPMAP )" ); + return ( 16 * m_nCONVERT_TO_SRGB ) + ( 32 * m_nDETAILTEXTURE ) + ( 64 * m_nBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nSELFILLUM ) + ( 512 * m_nDIFFUSEBUMPMAP ) + ( 1024 * m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) + ( 2048 * m_nFLASHLIGHT ) + ( 4096 * m_nSEAMLESS ) + ( 8192 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; + +#define shaderStaticTest_sdk_worldtwotextureblend_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_DETAIL_ALPHA_MASK_BASE_TEXTURE + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + + +class sdk_worldtwotextureblend_ps30_Dynamic_Index +{ + unsigned int m_nWRITEWATERFOGTODESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bFLASHLIGHTSHADOWS : 1; +#endif // _DEBUG +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + sdk_worldtwotextureblend_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITEWATERFOGTODESTALPHA = 0; + m_nPIXELFOGTYPE = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nFLASHLIGHTSHADOWS = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; + m_bPIXELFOGTYPE = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; + +#define shaderDynamicTest_sdk_worldtwotextureblend_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + diff --git a/materialsystem/stdshaders/include/skydome_ps30.inc b/materialsystem/stdshaders/include/skydome_ps30.inc new file mode 100644 index 00000000..cc46d586 --- /dev/null +++ b/materialsystem/stdshaders/include/skydome_ps30.inc @@ -0,0 +1,67 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class skydome_ps30_Static_Index +{ +public: + skydome_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_skydome_ps30 1 + + +class skydome_ps30_Dynamic_Index +{ + unsigned int m_nRENDER_SKY : 2; +#ifdef _DEBUG + bool m_bRENDER_SKY : 1; +#endif // _DEBUG +public: + void SetRENDER_SKY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRENDER_SKY = i; +#ifdef _DEBUG + m_bRENDER_SKY = true; +#endif // _DEBUG + } + + skydome_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nRENDER_SKY = 0; +#ifdef _DEBUG + m_bRENDER_SKY = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bRENDER_SKY ); + return ( 1 * m_nRENDER_SKY ) + 0; + } +}; + +#define shaderDynamicTest_skydome_ps30 psh_forgot_to_set_dynamic_RENDER_SKY + diff --git a/materialsystem/stdshaders/include/skydome_vs30.inc b/materialsystem/stdshaders/include/skydome_vs30.inc new file mode 100644 index 00000000..5d1f981a --- /dev/null +++ b/materialsystem/stdshaders/include/skydome_vs30.inc @@ -0,0 +1,54 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class skydome_vs30_Static_Index +{ +public: + skydome_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_skydome_vs30 1 + + +class skydome_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + skydome_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS ); + return ( 1 * m_nCOMPRESSED_VERTS ) + 0; + } +}; + +#define shaderDynamicTest_skydome_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + diff --git a/materialsystem/stdshaders/include/ssgi_combine_ps30.inc b/materialsystem/stdshaders/include/ssgi_combine_ps30.inc new file mode 100644 index 00000000..c06adf90 --- /dev/null +++ b/materialsystem/stdshaders/include/ssgi_combine_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class ssgi_combine_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + ssgi_combine_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_ssgi_combine_ps30 1 + + +class ssgi_combine_ps30_Dynamic_Index +{ +public: + ssgi_combine_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_ssgi_combine_ps30 1 + diff --git a/materialsystem/stdshaders/include/ssgi_ps30.inc b/materialsystem/stdshaders/include/ssgi_ps30.inc new file mode 100644 index 00000000..c55c286e --- /dev/null +++ b/materialsystem/stdshaders/include/ssgi_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class ssgi_ps30_Static_Index +{ +public: + ssgi_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_ssgi_ps30 1 + + +class ssgi_ps30_Dynamic_Index +{ +public: + ssgi_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_ssgi_ps30 1 + diff --git a/materialsystem/stdshaders/include/ssr_ps30.inc b/materialsystem/stdshaders/include/ssr_ps30.inc new file mode 100644 index 00000000..91a4c291 --- /dev/null +++ b/materialsystem/stdshaders/include/ssr_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class ssr_ps30_Static_Index +{ +public: + ssr_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_ssr_ps30 1 + + +class ssr_ps30_Dynamic_Index +{ +public: + ssr_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_ssr_ps30 1 + diff --git a/materialsystem/stdshaders/include/test_ps30.inc b/materialsystem/stdshaders/include/test_ps30.inc new file mode 100644 index 00000000..51222b31 --- /dev/null +++ b/materialsystem/stdshaders/include/test_ps30.inc @@ -0,0 +1,33 @@ +#pragma once +#include "shaderlib/cshader.h" +class test_ps30_Static_Index +{ +public: + test_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_test_ps30 1 + + +class test_ps30_Dynamic_Index +{ +public: + test_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_test_ps30 1 + diff --git a/materialsystem/stdshaders/include/unsharp_blur_ps30.inc b/materialsystem/stdshaders/include/unsharp_blur_ps30.inc new file mode 100644 index 00000000..d0455128 --- /dev/null +++ b/materialsystem/stdshaders/include/unsharp_blur_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class unsharp_blur_ps30_Static_Index +{ +public: + unsharp_blur_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_unsharp_blur_ps30 1 + + +class unsharp_blur_ps30_Dynamic_Index +{ +public: + unsharp_blur_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_unsharp_blur_ps30 1 + diff --git a/materialsystem/stdshaders/include/unsharp_blur_vs30.inc b/materialsystem/stdshaders/include/unsharp_blur_vs30.inc new file mode 100644 index 00000000..87e3d15e --- /dev/null +++ b/materialsystem/stdshaders/include/unsharp_blur_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class unsharp_blur_vs30_Static_Index +{ +public: + unsharp_blur_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_unsharp_blur_vs30 1 + + +class unsharp_blur_vs30_Dynamic_Index +{ +public: + unsharp_blur_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_unsharp_blur_vs30 1 + diff --git a/materialsystem/stdshaders/include/unsharp_ps30.inc b/materialsystem/stdshaders/include/unsharp_ps30.inc new file mode 100644 index 00000000..16cfbef8 --- /dev/null +++ b/materialsystem/stdshaders/include/unsharp_ps30.inc @@ -0,0 +1,42 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class unsharp_ps30_Static_Index +{ +public: + unsharp_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_unsharp_ps30 1 + + +class unsharp_ps30_Dynamic_Index +{ +public: + unsharp_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_unsharp_ps30 1 + diff --git a/materialsystem/stdshaders/include/unsharp_vs30.inc b/materialsystem/stdshaders/include/unsharp_vs30.inc new file mode 100644 index 00000000..dc063465 --- /dev/null +++ b/materialsystem/stdshaders/include/unsharp_vs30.inc @@ -0,0 +1,36 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class unsharp_vs30_Static_Index +{ +public: + unsharp_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_unsharp_vs30 1 + + +class unsharp_vs30_Dynamic_Index +{ +public: + unsharp_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_unsharp_vs30 1 + diff --git a/materialsystem/stdshaders/include/vance_bloom_combine_ps30.inc b/materialsystem/stdshaders/include/vance_bloom_combine_ps30.inc new file mode 100644 index 00000000..86446a16 --- /dev/null +++ b/materialsystem/stdshaders/include/vance_bloom_combine_ps30.inc @@ -0,0 +1,50 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class vance_bloom_combine_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + vance_bloom_combine_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_vance_bloom_combine_ps30 1 + + +class vance_bloom_combine_ps30_Dynamic_Index +{ +public: + vance_bloom_combine_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_vance_bloom_combine_ps30 1 + diff --git a/materialsystem/stdshaders/include/vance_scope_ps30.inc b/materialsystem/stdshaders/include/vance_scope_ps30.inc new file mode 100644 index 00000000..eb292850 --- /dev/null +++ b/materialsystem/stdshaders/include/vance_scope_ps30.inc @@ -0,0 +1,49 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class vance_scope_ps30_Static_Index +{ +public: + vance_scope_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_vance_scope_ps30 1 + + +class vance_scope_ps30_Dynamic_Index +{ +public: + vance_scope_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderDynamicTest_vance_scope_ps30 1 + diff --git a/materialsystem/stdshaders/include/vance_scope_vs30.inc b/materialsystem/stdshaders/include/vance_scope_vs30.inc new file mode 100644 index 00000000..d2655e4e --- /dev/null +++ b/materialsystem/stdshaders/include/vance_scope_vs30.inc @@ -0,0 +1,67 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class vance_scope_vs30_Static_Index +{ +public: + vance_scope_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + } + + int GetIndex() const + { + return 0; + } +}; + +#define shaderStaticTest_vance_scope_vs30 1 + + +class vance_scope_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nSKINNING : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bSKINNING : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + vance_scope_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nSKINNING = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bSKINNING = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bSKINNING ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; + +#define shaderDynamicTest_vance_scope_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + diff --git a/materialsystem/stdshaders/include/vance_tonemap_ps30.inc b/materialsystem/stdshaders/include/vance_tonemap_ps30.inc new file mode 100644 index 00000000..c85cc5a1 --- /dev/null +++ b/materialsystem/stdshaders/include/vance_tonemap_ps30.inc @@ -0,0 +1,68 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class vance_tonemap_ps30_Static_Index +{ + unsigned int m_nCONVERT_TO_SRGB : 2; +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; + } + + vance_tonemap_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + + int GetIndex() const + { + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; + +#define shaderStaticTest_vance_tonemap_ps30 1 + + +class vance_tonemap_ps30_Dynamic_Index +{ + unsigned int m_nMODE : 3; +#ifdef _DEBUG + bool m_bMODE : 1; +#endif // _DEBUG +public: + void SetMODE( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nMODE = i; +#ifdef _DEBUG + m_bMODE = true; +#endif // _DEBUG + } + + vance_tonemap_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nMODE = 0; +#ifdef _DEBUG + m_bMODE = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bMODE ); + return ( 1 * m_nMODE ) + 0; + } +}; + +#define shaderDynamicTest_vance_tonemap_ps30 psh_forgot_to_set_dynamic_MODE + diff --git a/materialsystem/stdshaders/include/vertexlitpbr_ps30.inc b/materialsystem/stdshaders/include/vertexlitpbr_ps30.inc new file mode 100644 index 00000000..87cba73e --- /dev/null +++ b/materialsystem/stdshaders/include/vertexlitpbr_ps30.inc @@ -0,0 +1,227 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW +// ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) +// ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) +// ( $FLASHLIGHT == 1) && ( $CSM == 1) +// $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) +// ($CUBEMAP || FLASHLIGHT ) +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW + +#pragma once +#include "shaderlib/cshader.h" +class vertexlitpbr_ps30_Static_Index +{ + unsigned int m_nFLASHLIGHT : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nCUBEMAP_SPHERE_LEGACY : 2; + unsigned int m_nSMOOTHNESS : 2; +#ifdef _DEBUG + bool m_bFLASHLIGHT : 1; + bool m_bCUBEMAP : 1; + bool m_bCUBEMAP_SPHERE_LEGACY : 1; + bool m_bSMOOTHNESS : 1; +#endif // _DEBUG +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif // _DEBUG + } + + void SetSMOOTHNESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSMOOTHNESS = i; +#ifdef _DEBUG + m_bSMOOTHNESS = true; +#endif // _DEBUG + } + + vertexlitpbr_ps30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nFLASHLIGHT = 0; + m_nCUBEMAP = 0; + m_nCUBEMAP_SPHERE_LEGACY = 0; + m_nSMOOTHNESS = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; + m_bCUBEMAP = false; + m_bCUBEMAP_SPHERE_LEGACY = false; + m_bSMOOTHNESS = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bFLASHLIGHT && m_bCUBEMAP && m_bCUBEMAP_SPHERE_LEGACY && m_bSMOOTHNESS ); + AssertMsg( !( ( m_nCUBEMAP == 1 ) && ( m_nFLASHLIGHT == 1 ) ), "Invalid combo combination ( ( CUBEMAP == 1 ) && ( FLASHLIGHT == 1 ) )" ); + AssertMsg( !( m_nCUBEMAP_SPHERE_LEGACY && ( m_nCUBEMAP == 0 ) ), "Invalid combo combination ( CUBEMAP_SPHERE_LEGACY && ( CUBEMAP == 0 ) )" ); + return ( 1440 * m_nFLASHLIGHT ) + ( 2880 * m_nCUBEMAP ) + ( 5760 * m_nCUBEMAP_SPHERE_LEGACY ) + ( 11520 * m_nSMOOTHNESS ) + 0; + } +}; + +#define shaderStaticTest_vertexlitpbr_ps30 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + psh_forgot_to_set_static_SMOOTHNESS + + +class vertexlitpbr_ps30_Dynamic_Index +{ + unsigned int m_nWRITEWATERFOGTODESTALPHA : 2; + unsigned int m_nPIXELFOGTYPE : 2; + unsigned int m_nNUM_LIGHTS : 3; + unsigned int m_nWRITE_DEPTH_TO_DESTALPHA : 2; + unsigned int m_nFLASHLIGHTSHADOWS : 2; + unsigned int m_nCSM : 2; + unsigned int m_nCSM_PERF : 2; + unsigned int m_nLIGHT_PREVIEW : 2; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA : 1; + bool m_bPIXELFOGTYPE : 1; + bool m_bNUM_LIGHTS : 1; + bool m_bWRITE_DEPTH_TO_DESTALPHA : 1; + bool m_bFLASHLIGHTSHADOWS : 1; + bool m_bCSM : 1; + bool m_bCSM_PERF : 1; + bool m_bLIGHT_PREVIEW : 1; +#endif // _DEBUG +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif // _DEBUG + } + + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif // _DEBUG + } + + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif // _DEBUG + } + + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif // _DEBUG + } + + void SetCSM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCSM = i; +#ifdef _DEBUG + m_bCSM = true; +#endif // _DEBUG + } + + void SetCSM_PERF( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nCSM_PERF = i; +#ifdef _DEBUG + m_bCSM_PERF = true; +#endif // _DEBUG + } + + void SetLIGHT_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHT_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHT_PREVIEW = true; +#endif // _DEBUG + } + + vertexlitpbr_ps30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nWRITEWATERFOGTODESTALPHA = 0; + m_nPIXELFOGTYPE = 0; + m_nNUM_LIGHTS = 0; + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + m_nFLASHLIGHTSHADOWS = 0; + m_nCSM = 0; + m_nCSM_PERF = 0; + m_nLIGHT_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; + m_bPIXELFOGTYPE = false; + m_bNUM_LIGHTS = false; + m_bWRITE_DEPTH_TO_DESTALPHA = false; + m_bFLASHLIGHTSHADOWS = false; + m_bCSM = false; + m_bCSM_PERF = false; + m_bLIGHT_PREVIEW = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS && m_bCSM && m_bCSM_PERF && m_bLIGHT_PREVIEW ); + AssertMsg( !( ( m_nPIXELFOGTYPE == 0 ) && ( m_nWRITEWATERFOGTODESTALPHA != 0 ) ), "Invalid combo combination ( ( PIXELFOGTYPE == 0 ) && ( WRITEWATERFOGTODESTALPHA != 0 ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + AssertMsg( !( 1 && ( 1 && ( ( m_nPIXELFOGTYPE != 1 ) && m_nWRITEWATERFOGTODESTALPHA ) ) ), "Invalid combo combination ( 1 && ( 1 && ( ( PIXELFOGTYPE != 1 ) && WRITEWATERFOGTODESTALPHA ) ) )" ); + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + ( 80 * m_nCSM ) + ( 160 * m_nCSM_PERF ) + ( 480 * m_nLIGHT_PREVIEW ) + 0; + } +}; + +#define shaderDynamicTest_vertexlitpbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + psh_forgot_to_set_dynamic_CSM + psh_forgot_to_set_dynamic_CSM_PERF + psh_forgot_to_set_dynamic_LIGHT_PREVIEW + diff --git a/materialsystem/stdshaders/include/vertexlitpbr_vs30.inc b/materialsystem/stdshaders/include/vertexlitpbr_vs30.inc new file mode 100644 index 00000000..dab82133 --- /dev/null +++ b/materialsystem/stdshaders/include/vertexlitpbr_vs30.inc @@ -0,0 +1,176 @@ +// ALL SKIP STATEMENTS THAT AFFECT THIS SHADER!!! +// defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH + +#pragma once +#include "shaderlib/cshader.h" +class vertexlitpbr_vs30_Static_Index +{ + unsigned int m_nVERTEXCOLOR : 2; + unsigned int m_nCUBEMAP : 2; + unsigned int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR : 2; +#ifdef _DEBUG + bool m_bVERTEXCOLOR : 1; + bool m_bCUBEMAP : 1; + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR : 1; +#endif // _DEBUG +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif // _DEBUG + } + + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif // _DEBUG + } + + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif // _DEBUG + } + + vertexlitpbr_vs30_Static_Index( IShaderShadow* pShaderShadow, IMaterialVar** params ) + { + m_nVERTEXCOLOR = 0; + m_nCUBEMAP = 0; + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; + m_bCUBEMAP = false; + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bVERTEXCOLOR && m_bCUBEMAP && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR ); + return ( 320 * m_nVERTEXCOLOR ) + ( 640 * m_nCUBEMAP ) + ( 1280 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + 0; + } +}; + +#define shaderStaticTest_vertexlitpbr_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + + +class vertexlitpbr_vs30_Dynamic_Index +{ + unsigned int m_nCOMPRESSED_VERTS : 2; + unsigned int m_nDOWATERFOG : 2; + unsigned int m_nSKINNING : 2; + unsigned int m_nLIGHTING_PREVIEW : 2; + unsigned int m_nNUM_LIGHTS : 3; + unsigned int m_nDYNAMIC_LIGHT : 2; + unsigned int m_nSTATIC_LIGHT : 2; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS : 1; + bool m_bDOWATERFOG : 1; + bool m_bSKINNING : 1; + bool m_bLIGHTING_PREVIEW : 1; + bool m_bNUM_LIGHTS : 1; + bool m_bDYNAMIC_LIGHT : 1; + bool m_bSTATIC_LIGHT : 1; +#endif // _DEBUG +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif // _DEBUG + } + + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif // _DEBUG + } + + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif // _DEBUG + } + + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif // _DEBUG + } + + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif // _DEBUG + } + + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif // _DEBUG + } + + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif // _DEBUG + } + + vertexlitpbr_vs30_Dynamic_Index( IShaderDynamicAPI* pShaderAPI ) + { + m_nCOMPRESSED_VERTS = 0; + m_nDOWATERFOG = 0; + m_nSKINNING = 0; + m_nLIGHTING_PREVIEW = 0; + m_nNUM_LIGHTS = 0; + m_nDYNAMIC_LIGHT = 0; + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; + m_bDOWATERFOG = false; + m_bSKINNING = false; + m_bLIGHTING_PREVIEW = false; + m_bNUM_LIGHTS = false; + m_bDYNAMIC_LIGHT = false; + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + } + + int GetIndex() const + { + Assert( m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT ); + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + ( 80 * m_nDYNAMIC_LIGHT ) + ( 160 * m_nSTATIC_LIGHT ) + 0; + } +}; + +#define shaderDynamicTest_vertexlitpbr_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + diff --git a/materialsystem/stdshaders/light_volumetrics_ps20b.fxc b/materialsystem/stdshaders/light_volumetrics_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/light_volumetrics_ps20b.fxc rename to materialsystem/stdshaders/light_volumetrics_ps30.fxc diff --git a/materialsystem/stdshaders/light_volumetrics_vs20.fxc b/materialsystem/stdshaders/light_volumetrics_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/light_volumetrics_vs20.fxc rename to materialsystem/stdshaders/light_volumetrics_vs30.fxc diff --git a/materialsystem/stdshaders/lightmappedPBR_ps30.fxc b/materialsystem/stdshaders/lightmappedPBR_ps30.fxc deleted file mode 100644 index ebb2f64f..00000000 --- a/materialsystem/stdshaders/lightmappedPBR_ps30.fxc +++ /dev/null @@ -1,465 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example pixel shader that can be applied to models -// -//================================================================================================== - -// STATIC: "CONVERT_TO_SRGB" "0..0" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" -// STATIC: "SMOOTHNESS" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "BUMPMAP" "0..1" - -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" -// DYNAMIC: "CUBEMAPCORRECTED" "0..1" -// DYNAMIC: "CSM" "0..1" -// DYNAMIC: "CSM_PERF" "0..2" -// DYNAMIC: "LIGHT_PREVIEW" "0..2" - -// We don't care about those in the editor -// SKIP: ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW - -// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) - -// SKIP: ( $CUBEMAP == 0 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) -// SKIP: ( $FLASHLIGHT == 1 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) -// SKIP: ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) - -// both cant exist at the same time -// SKIP: ( $FLASHLIGHT == 1) && ( $CSM == 1) - -// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" -#include "common_pbr.h" -#include "deferred_shadows.h" -#include "common_lightmappedgeneric_fxc.h" - -#ifdef NV3X - #define PSHADER_VECT_SCALE 20.0 - #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) -#else - #define PSHADER_VECT_SCALE 1.0 - #define VSHADER_VECT_SCALE 1.0 -#endif - -const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); -const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); -const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -#if FLASHLIGHT == 1 -sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler -sampler FlashlightSampler : register( s6 ); // Flashlight cookie - -const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass -const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); -const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); -const float4 g_FlashlightColor : register( PSREG_FLASHLIGHT_COLOR ); -#elif CSM == 1 -sampler ShadowDepthSampler : register( s4 ); // CSM Depth - -const float4x4 g_CSMWorldToTexture : register( c22 ); -const float4 g_CascadeFwd : register( c26 ); -const float4 g_CascadeLight : register( c27 ); -const float4 g_CascadeAmbient : register( c28 ); -const float2 g_CascadeBias : register( c31 ); -const float2 g_CascadeResolution : register( c32 ); -const float4 g_CascadeSize : register( c33 ); -#endif -const float4 g_TintValuesAndLightmapScale : register( c20 ); -const float4 g_EnvmapOrigin_and_Radius : register( c21 ); -#define g_EnvmapOrigin (g_EnvmapOrigin_and_Radius.xyz) -#define g_EnvmapRadius (g_EnvmapOrigin_and_Radius.w) - -#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz - -sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha -sampler RoughnessSampler : register( s1 ); // Roughness -sampler MetallicSampler : register( s2 ); // Metallic -sampler BumpmapSampler : register( s3 ); // Bump map -sampler EnvmapSampler : register( s7 ); // for IBL -sampler BRDFSampler : register( s8 ); // for IBL -sampler AOSampler : register( s9 ); // AO -sampler EmissiveSampler : register( s10 ); // Emissive map -sampler LightmapSampler : register( s11 ); // Lightmap texture from the engine - -// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile -half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV ) -{ - const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; - const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; - half4 r = Roughness * c0 + c1; - half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; - half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw; - return SpecularColor * AB.x + AB.y; -} - -float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness) -{ - return F0 + (max(1.0f.xxx - roughness, F0) - F0) * pow(1.0 - cosTheta, 5.0); -} - -float3 DoIBL(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallness, float roughness, float3 lightmap) -{ - float3 WorldToEye = g_EyePos.xyz - vWorldPos; - float3 V = normalize( WorldToEye ); - float3 N = normalize( vWorldNormal ); - - //precompute dots - float NV = max(0.0, dot(normalize(N), V)); - - float3 metallic = clamp(metallness, 0.0f, 0.9f); -#if CUBEMAP == 1 - -#if CUBEMAPCORRECTED == 0 - float3 reflectVect = CalcReflectionVectorUnnormalized( vWorldNormal, V ); -#else - float3 reflectVect = CalcReflectionVectorUnnormalized( vWorldNormal, WorldToEye); - float3 BoxSize = float3(g_EnvmapRadius,g_EnvmapRadius,g_EnvmapRadius); - float3 BoxMax = BoxSize + g_EnvmapOrigin; - float3 BoxMin = -BoxSize + g_EnvmapOrigin; - float3 firstPlaneIntersect = (BoxMax - vWorldPos) / reflectVect; - float3 secondPlaneIntersect = (BoxMin - vWorldPos) / reflectVect; - float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect); - float planeDist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); - float3 intersectPositionWS = vWorldPos + reflectVect * planeDist; - reflectVect = intersectPositionWS - g_EnvmapOrigin; -#endif - - float4 directionPosX = { 1.0f, 0.01f, 0.01f, 12.0f }; float4 directionNegX = {-1.0f, 0.01f, 0.01f, 12.0f }; - float4 directionPosY = { 0.01f, 1.0f, 0.01f, 12.0f }; float4 directionNegY = { 0.01f,-1.0f, 0.01f, 12.0f }; - float4 directionPosZ = { 0.01f, 0.01f, 1.0f, 12.0f }; float4 directionNegZ = { 0.01f, 0.01f,-1.0f, 12.0f }; - float3 lookupPosX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosX); - float3 lookupNegX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegX); - float3 lookupPosY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosY); - float3 lookupNegY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegY); - float3 lookupPosZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosZ); - float3 lookupNegZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegZ); - float3 envmapCube[6] = { lookupPosX, lookupNegX, lookupPosY, lookupNegY, lookupPosZ, lookupNegZ }; - - float3 irradiance = lightmap; - - float3 f0 = 0.04f.xxx; - f0 = lerp(f0, albedo.rgb, metallic); - float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term - - half3 BRDF = EnvBRDFApprox(f0, roughness, NV); - - float3 kD = 1.0f.xxx - F; - kD *= 1.0 - metallic; - - float3 diffuseIBL = kD * albedo * irradiance; - float3 lookup = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, float4(reflectVect, roughness * 12.0)).rgb; - float3 specularIrradiance = lerp(lookup, PixelShaderAmbientLight( reflectVect, envmapCube ), roughness * roughness ); - float3 specularIBL = BRDF * specularIrradiance; - -#if CUBEMAPCORRECTED == 1 - float fallof = saturate(length(g_EnvmapOrigin - vWorldPos) / g_EnvmapRadius); - fallof = 1.0f - pow(fallof, 5.0f); - specularIBL *= fallof; -#endif - - //mix - return max(0.0, diffuseIBL + specularIBL); -#else - - float3 f0 = 0.04f.xxx; - f0 = lerp(f0, albedo.rgb, metallic); - float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term - - float3 kD = 1.0f.xxx - F; - kD *= 1.0 - metallic; - return kD * albedo * lightmap; -#endif -} - -#if FLASHLIGHT == 1 -float3 DoFlashlight(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallic, float roughness) -{ - float4 flashlightSpacePosition = mul( float4(vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flashlightColor = tex2D( FlashlightSampler, vProjCoords); - float3 shadow = 1.0f; - #if FLASHLIGHTSHADOWS - shadow = tex2DprojBicubic(ShadowDepthSampler, 512.0f.xx, vProjCoords.xy, vProjCoords.z); - #endif - float2 dist = float2(length(g_FlashlightPos_RimBoost.xyz - vWorldPos), dot(g_FlashlightPos_RimBoost.xyz - vWorldPos,g_FlashlightPos_RimBoost.xyz - vWorldPos)); - float fAtten = saturate( dot( g_FlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/dist.x, 1.0f/dist.y ) ) ); - float3 light = DoPBRLight( vWorldPos, vWorldNormal, albedo, g_FlashlightPos_RimBoost.xyz, flashlightColor.rgb * g_FlashlightColor.xyz, g_EyePos.xyz, shadow * fAtten * g_FlashlightColor.w, metallic, roughness); - return light; -} -#elif CSM == 1 -float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) -{ - float2 rtSize = g_CascadeResolution;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; - float fEpsilonX = 1.0f / rtSize.y; - float fEpsilonY = 1.0f / rtSize.x; - -#if CSM_PERF < 1 - float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); - float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); -#endif -#if CSM_PERF < 2 - float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); -#endif - float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); - - float projMask = 1.0f; - if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) - { - projMask = 0.0f; - } - - float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); -#if CSM_PERF < 1 - float shadowProjDiff0 = 1; - float3 shadowMapCenter_objDepth0 = cascade0; - float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; - float objDepth0 = shadowMapCenter_objDepth0.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff0; - float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); - - float shadowProjDiff1 = g_CascadeSize.y; - float3 shadowMapCenter_objDepth1 = cascade1; - float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; - float objDepth1 = shadowMapCenter_objDepth1.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff1; - float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); -#endif - -#if CSM_PERF < 2 - float shadowProjDiff2 = g_CascadeSize.z; - float3 shadowMapCenter_objDepth2 = cascade2; - float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; - float objDepth2 = shadowMapCenter_objDepth2.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff2; - float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); -#endif - - float shadowProjDiff3 = g_CascadeSize.w; - float3 shadowMapCenter_objDepth3 = cascade3; - float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; - float objDepth3 = shadowMapCenter_objDepth3.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff3; - float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); - - /*float shadow0 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); - float shadow1 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow2 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); - float shadow3 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3);*/ - - float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); - -#if CSM_PERF < 2 - float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); -#else - float shadow2 = shadow3; -#endif - -#if CSM_PERF < 1 - float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); -#else - float shadow1 = shadow2; - float shadow0 = shadow2; -#endif - - - /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); - float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); - float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); - float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); - - float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); - float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); - float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); - float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ - - - float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); - float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); - float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); - - float shadow = shadow0123; - - if(projMask == 1.0f) - { - float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); - float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); - return shadowFinal; - } - else - { - return 1.0f; - } - -} - -float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) -{ - float3 Out; - float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); - float4 flashlightSpacePosition = mul(float4(worldPos, 1.0f), g_CSMWorldToTexture); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); - float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); - diffuse = saturate(diffuse); - - Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); - return Out; -} -#endif -struct PS_INPUT -{ - float3 SeamlessTexCoord : TEXCOORD0; // x y z - float2 baseTexCoord : TEXCOORD1; - float4 lightmapTexCoord1And2 : TEXCOORD2; - float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale - float4 worldPos_projPosZ : TEXCOORD4; - - float3x3 TBN : TEXCOORD5; - - float4 vertexColor : COLOR; // in seamless, r g b = blend weights - float4 vertexBlendX_fogFactorW : COLOR1; - -}; - -struct PS_OUTPUT -{ - float4 MainOut : COLOR0; - float4 Normal : COLOR1; - float4 MRAO : COLOR2; - float4 Albedo : COLOR3; -}; - -#if LIGHT_PREVIEW == 2 -LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR -#elif LIGHT_PREVIEW == 1 -HALF4 main(PS_INPUT i) : COLOR -#else -PS_OUTPUT main(PS_INPUT i) : COLOR -#endif -{ - bool bBumpmap = BUMPMAP ? true : false; - bool bCubemap = (CUBEMAP) ? true : false; - float3 UV = 0.0f.xxx; -#if SEAMLESS == 0 - UV.xy = i.baseTexCoord.xy; -#else - UV = i.SeamlessTexCoord; -#endif - float3 worldPos = i.worldPos_projPosZ.xyz; -#if SMOOTHNESS == 0 - float roughnessMap = tex2D( RoughnessSampler, UV.xy ); -#else - float roughnessMap = 1.0f - tex2D( RoughnessSampler, UV.xy ); -#endif - float metallicMap = tex2D( MetallicSampler, UV.xy ); - float AOSample = tex2D( AOSampler, UV.xy ); - float3 EmissiveSample = tex2D( EmissiveSampler, UV.xy ); - float4 baseColor = tex2D( BaseTextureSampler, UV.xy ); - float4 baseColor2 = 0.0f.xxxx; - float4 normalTexel = 0.0f.xxxx; - GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler, BumpmapSampler, false, bBumpmap, - UV, i.vertexColor.rgb, baseColor, baseColor2, normalTexel ); - - float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; - - float3 vWorldNormal = mul( tangentSpaceNormal, i.TBN ); - - PS_OUTPUT output = (PS_OUTPUT)0; - - HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); - if( bBumpmap) - { - HALF2 bumpCoord1; - HALF2 bumpCoord2; - HALF2 bumpCoord3; - ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, - bumpCoord1, bumpCoord2, bumpCoord3 ); - - lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); - lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 ); - lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 ); - } - else - { - HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); - lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); - } - float3 lightmapTexel = 1.0f; - if(bBumpmap) - { - float3 dp; - dp.x = saturate( dot( tangentSpaceNormal, bumpBasis[0] ) ); - dp.y = saturate( dot( tangentSpaceNormal, bumpBasis[1] ) ); - dp.z = saturate( dot( tangentSpaceNormal, bumpBasis[2] ) ); - dp *= dp; - - lightmapTexel = dp.x * lightmapColor1 + - dp.y * lightmapColor2 + - dp.z * lightmapColor3; - float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); - lightmapTexel *= 1.0f / sum; - } - else - { - lightmapTexel = lightmapColor1; - } - - lightmapTexel *= g_TintValuesAndLightmapScale.rgb; - - //HALF2 lightmapCoord = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); - //float3 lightmapTexel = LightMapSample( LightmapSampler, lightmapCoord )* g_TintValuesAndLightmapScale.rgb; - - float3 albedo = g_DiffuseModulation.rgb * baseColor.rgb; - - float3 IBL = DoIBL(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap, lightmapTexel); - float3 Flashlight = 0.0f; -#if FLASHLIGHT - Flashlight = DoFlashlight(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap); - float3 result = (Flashlight); -#elif CSM == 1 - float3 CSMLight = DoPBRCSM(worldPos, vWorldNormal, baseColor.rgb, metallicMap, roughnessMap, length(worldPos - g_EyePos)); - float3 result = (IBL * AOSample) + EmissiveSample + CSMLight; -#else - float3 result = (IBL * AOSample) + EmissiveSample; -#endif - float alpha = baseColor.a * g_DiffuseModulation.a; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, worldPos.z, i.worldPos_projPosZ.w ); - -#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) - alpha = fogFactor; -#endif - -#if LIGHT_PREVIEW == 1 - result = DoPBRLight(worldPos, i.TBN[2].xyz, baseColor, g_EyePos.xyz, 1.0f.xxx, g_EyePos.xyz, 5.0f, metallicMap, roughnessMap); - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - return FinalOutput( float4( result.rgb, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); -#elif LIGHT_PREVIEW == 2 - LPREVIEW_PS_OUT Output; - Output.color = float4( baseColor.xyz,alpha ); - Output.normal = float4( i.TBN[2].xyz,alpha ); - Output.position = float4( worldPos, alpha ); - Output.flags = float4( 1.0f - metallicMap, roughnessMap, 1, alpha ); - return FinalOutput( Output, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -#else - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - output.MainOut = FinalOutput(float4(result.rgb, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w); -#if !FLASHLIGHT - output.Normal = float4(vWorldNormal.xyz, 1.0f); - output.MRAO = float4(metallicMap, roughnessMap, AOSample, 1.0f); - output.Albedo = float4(baseColor.xyz, 1.0f); -#endif - - return output; -#endif -} diff --git a/materialsystem/stdshaders/lightmappedgeneric.cpp b/materialsystem/stdshaders/lightmappedgeneric.cpp new file mode 100644 index 00000000..e5d2916c --- /dev/null +++ b/materialsystem/stdshaders/lightmappedgeneric.cpp @@ -0,0 +1,200 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" +#include "lightmappedgeneric_dx9_helper.h" +#include "SDK_lightmappedgeneric_ps20b.inc" +#include "SDK_lightmappedgeneric_vs20.inc" + +BEGIN_VS_SHADER( SDK_LightmappedGeneric, + "Help for SDK_LightmappedGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( TRANSLUCENT, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( ALPHATEST, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.5", "" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "Blended texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) +#ifdef MAPBASE + // This needs to be a SHADER_PARAM_TYPE_STRING so it isn't considered "defined" by default. + SHADER_PARAM( BASETEXTURETRANSFORM2, SHADER_PARAM_TYPE_STRING, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$basetexture2 texcoord transform" ) +#endif + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha.") + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha.") + + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + SHADER_PARAM( ENVMAPPARALLAX, SHADER_PARAM_TYPE_BOOL, "0", "Enables parallax correction code for env_cubemaps" ) + SHADER_PARAM( ENVMAPPARALLAXOBB1, SHADER_PARAM_TYPE_VEC4, "[1 0 0 0]", "The first line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB2, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "The second line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB3, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "The third line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" ) +#endif +END_SHADER_PARAMS + + void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; +#ifdef MAPBASE + info.m_nBaseTexture2Transform = BASETEXTURETRANSFORM2; +#endif + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + + info.m_nPhong = PHONG; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhongExponent = PHONGEXPONENT; + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + info.m_nEnvmapParallax = ENVMAPPARALLAX; + info.m_nEnvmapParallaxObb1 = ENVMAPPARALLAXOBB1; + info.m_nEnvmapParallaxObb2 = ENVMAPPARALLAXOBB2; + info.m_nEnvmapParallaxObb3 = ENVMAPPARALLAXOBB3; + info.m_nEnvmapOrigin = ENVMAPORIGIN; +#endif + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "LightmappedGeneric_DX8"; + + return 0; + } + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + LightmappedGeneric_DX9_Vars_t info; + SetupVars( info ); + InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, info ); + } + + SHADER_INIT + { + LightmappedGeneric_DX9_Vars_t info; + SetupVars( info ); + InitLightmappedGeneric_DX9( this, params, info ); + } + + SHADER_DRAW + { + LightmappedGeneric_DX9_Vars_t info; + SetupVars( info ); + DrawLightmappedGeneric_DX9( this, params, pShaderAPI, pShaderShadow, info, pContextDataPtr ); + } +END_SHADER \ No newline at end of file diff --git a/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh b/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh deleted file mode 100644 index 80e6db4e..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh +++ /dev/null @@ -1,22 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r1, t2, 1-t3.a ; envmap * envmapmask alpha -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh b/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh deleted file mode 100644 index 9ca0eeb0..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh +++ /dev/null @@ -1,9 +0,0 @@ -ps.1.1 - -tex t0 ; base 1 -tex t1 ; base 2 - -mov r1, t1 -lrp r0, 1-v0.a, t0, r1 -mul r0, r0, c0 - diff --git a/materialsystem/stdshaders/lightmappedgeneric_decal.cpp b/materialsystem/stdshaders/lightmappedgeneric_decal.cpp index 327f02e9..9e74b5cf 100644 --- a/materialsystem/stdshaders/lightmappedgeneric_decal.cpp +++ b/materialsystem/stdshaders/lightmappedgeneric_decal.cpp @@ -7,19 +7,15 @@ //=============================================================================// #include "BaseVSShader.h" -#ifndef VANCE + #include "lightmappedgeneric_decal.inc" -#else -#include "lightmappedgeneric_decal_ps30.inc" -#include "lightmappedgeneric_decal_vs30.inc" -#endif // !VANCE #include "mathlib/bumpvects.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -BEGIN_VS_SHADER(SDK_LightmappedGeneric_Decal, +BEGIN_VS_SHADER( LightmappedGeneric_Decal, "Help for LightmappedGeneric_Decal" ) BEGIN_SHADER_PARAMS @@ -93,7 +89,7 @@ BEGIN_VS_SHADER(SDK_LightmappedGeneric_Decal, int pTexCoords[3] = { 2, 2, 1 }; pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION | VERTEX_COLOR, 3, pTexCoords, 0 ); - lightmappedgeneric_decal_vs30_Static_Index vshIndex; + lightmappedgeneric_decal_Static_Index vshIndex; pShaderShadow->SetVertexShader( "LightmappedGeneric_Decal", vshIndex.GetIndex() ); pShaderShadow->SetPixelShader( "LightmappedGeneric_Decal" ); FogToFogColor(); @@ -117,7 +113,7 @@ BEGIN_VS_SHADER(SDK_LightmappedGeneric_Decal, SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); SetModulationPixelShaderDynamicState( 3 ); - lightmappedgeneric_decal_vs30_Dynamic_Index vshIndex; + lightmappedgeneric_decal_Dynamic_Index vshIndex; vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); } @@ -125,15 +121,13 @@ BEGIN_VS_SHADER(SDK_LightmappedGeneric_Decal, } SHADER_DRAW - { -#ifndef VANCE + { if( UsingFlashlight( params ) ) { DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); } else -#endif { DrawDecal( params, pShaderAPI, pShaderShadow ); } diff --git a/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc b/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc deleted file mode 100644 index fd457be8..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc +++ /dev/null @@ -1,59 +0,0 @@ -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -sampler BaseTextureSampler : register( s0 ); -sampler LightMap0Sampler : register( s1 ); -sampler LightMap1Sampler : register( s2 ); -sampler LightMap2Sampler : register( s3 ); - -const float4 g_LightMap0Color : register( c0 ); -const float4 g_LightMap1Color : register( c1 ); -const float4 g_LightMap2Color : register( c2 ); -const float4 g_ModulationColor : register( c3 ); - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - - -struct PS_INPUT -{ - float4 vProjPos : POSITION; - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - float2 vTexCoord2 : TEXCOORD2; - float2 vTexCoord3 : TEXCOORD3; - float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog - - float4 vColor : COLOR0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 resultColor; - - // output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + - // lightmapColor[1] * ( ( N dot basis[1] )^2 ) + - // lightmapColor[2] * ( ( N dot basis[2] )^2 ) + - resultColor = tex2D( LightMap0Sampler, i.vTexCoord1 ) * g_LightMap0Color; - resultColor = (tex2D( LightMap1Sampler, i.vTexCoord2 ) * g_LightMap1Color) + resultColor; - resultColor = (tex2D( LightMap2Sampler, i.vTexCoord3 ) * g_LightMap2Color) + resultColor; - - // Modulate by decal texture - float4 decalColor = tex2D( BaseTextureSampler, i.vTexCoord0 ); - resultColor.rgb = resultColor * decalColor; - resultColor.a = decalColor.a; - - // Modulate by constant color - resultColor = resultColor * g_ModulationColor; - - // Modulate by per-vertex factor - resultColor = resultColor * i.vColor; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp b/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp deleted file mode 100644 index f55f8883..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp +++ /dev/null @@ -1,288 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Lightmap only shader -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX6 ) - -BEGIN_SHADER( LightmappedGeneric_DX6, - "Help for LightmappedGeneric_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - if( params[BASETEXTURE]->IsDefined() ) - { - if( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) - { - params[ENVMAP]->SetUndefined(); - params[ENVMAPMASK]->SetUndefined(); - } - } - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - - if( !params[ENVMAPTINT]->IsDefined() ) - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[SELFILLUMTINT]->IsDefined() ) - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[DETAILSCALE]->IsDefined() ) - params[DETAILSCALE]->SetFloatValue( 4.0f ); - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - - // Get rid of the envmap if it's optional for this dx level. - if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) - { - params[ENVMAP]->SetUndefined(); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - - SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - { - LoadCubeMap( ENVMAP ); - } - else - { - LoadTexture( ENVMAP ); - } - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if (params[ENVMAPMASK]->IsDefined()) - { - LoadTexture( ENVMAPMASK ); - } - } - } - - SHADER_FALLBACK - { - return 0; - } - - int GetDrawFlagsPass1(IMaterialVar** params) - { - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0; - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - flags |= SHADER_DRAW_COLOR; - if (params[BASETEXTURE]->IsTexture()) - flags |= SHADER_DRAW_TEXCOORD1; - return flags; - } - - void DrawLightmapOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - - SetModulationShadowState(); - SetDefaultBlendingShadowState( ); - pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); - DefaultFog(); - } - DYNAMIC_STATE - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - SetModulationDynamicState(); - } - Draw(); - } - - void DrawBaseTimesLightmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // Base times lightmap - SHADOW_STATE - { - // alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - // Alpha blending - SetDefaultBlendingShadowState( BASETEXTURE, true ); - - // Independenly configure alpha and color - pShaderShadow->EnableAlphaPipe( true ); - - // color channel - - // base - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // lightmap - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); - - pShaderShadow->EnableConstantColor( IsColorModulating() ); - - // alpha channel - pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); - if ((! IsColorModulating()) && ( ! IsAlphaModulating())) - pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); - pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(BASETEXTURE, true) ); - pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, false ); - - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - { - if ( (! IsColorModulating()) && ( ! IsAlphaModulating())) - flags |= SHADER_DRAW_COLOR; - - } - if (params[BASETEXTURE]->IsTexture()) - { - flags |= SHADER_DRAW_TEXCOORD0; - } - - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - } - DYNAMIC_STATE - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - SetModulationDynamicState(); - } - Draw(); - - SHADOW_STATE - { - pShaderShadow->EnableAlphaPipe( false ); - } - } - - void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // Pass 1 : Base * lightmap or just lightmap - if ( params[BASETEXTURE]->IsTexture() ) - { - DrawBaseTimesLightmap( params, pShaderAPI, pShaderShadow ); - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - - // Draw the selfillum pass - if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) - { - FixedFunctionSelfIlluminationPass( - SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); - } - } - else - { - DrawLightmapOnly( params, pShaderAPI, pShaderShadow ); - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - - // Pass 2 : Masked environment map - if (params[ENVMAP]->IsTexture()) - { - FixedFunctionAdditiveMaskedEnvmapPass( - ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - } - - SHADER_DRAW - { - bool hasFlashlight = UsingFlashlight( params ); - - if( hasFlashlight ) - { - DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - } - else - { - // Base * Lightmap + env - DrawMode1( params, pShaderAPI, pShaderShadow ); - } - } -END_SHADER - - -//----------------------------------------------------------------------------- -// This allows us to use a block labelled 'Water_DX60' in the water materials -//----------------------------------------------------------------------------- -BEGIN_INHERITED_SHADER( Water_DX60, LightmappedGeneric_DX6, "Help for Water_DX60" ) -END_INHERITED_SHADER - diff --git a/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp b/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp deleted file mode 100644 index 8464f94f..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp +++ /dev/null @@ -1,802 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Lightmap only shader -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - - -#include "lightmappedgeneric_vs11.inc" -#include "unlitgeneric_vs11.inc" -#include "worldvertextransition_seamless.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); - -DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX8 ) - -BEGIN_VS_SHADER( LightmappedGeneric_DX8, - "Help for LightmappedGeneric_DX8" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "amount of detail texture to apply" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_INTEGER, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) - SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_BOOL, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) - SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) - SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) - END_SHADER_PARAMS - - virtual bool ShouldUseBumpmapping( IMaterialVar **params ) - { - return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); - } - - // Set up anything that is necessary to make decisions in SHADER_FALLBACK. - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. - if( ShouldUseBumpmapping( params ) && params[ALBEDO]->IsDefined() && - params[BASETEXTURE]->IsDefined() && - !( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) ) - { - params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() ); - } - - if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) - { - if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) - { - Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); - params[ENVMAP]->SetUndefined(); - } - } - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - { - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - } - - if( !params[ENVMAPTINT]->IsDefined() ) - { - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( !params[SELFILLUMTINT]->IsDefined() ) - { - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( !params[DETAILSCALE]->IsDefined() ) - { - params[DETAILSCALE]->SetFloatValue( 4.0f ); - } - - if( !params[DETAILBLENDFACTOR]->IsDefined() ) - { - params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); - } - - if( !params[FRESNELREFLECTION]->IsDefined() ) - { - params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); - } - - if( !params[ENVMAPMASKFRAME]->IsDefined() ) - { - params[ENVMAPMASKFRAME]->SetIntValue( 0 ); - } - - if( !params[ENVMAPFRAME]->IsDefined() ) - { - params[ENVMAPFRAME]->SetIntValue( 0 ); - } - - if( !params[BUMPFRAME]->IsDefined() ) - { - params[BUMPFRAME]->SetIntValue( 0 ); - } - - if( !params[ENVMAPCONTRAST]->IsDefined() ) - { - params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); - } - - if( !params[ENVMAPSATURATION]->IsDefined() ) - { - params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); - } - - if( !params[ALPHATESTREFERENCE]->IsDefined() ) - { - params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); - } - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - if( ShouldUseBumpmapping( params ) && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) ) - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); - } - - // Get rid of the envmap if it's optional for this dx level. - if( params[ENVMAPOPTIONAL]->IsDefined() && (params[ENVMAPOPTIONAL]->GetIntValue() > g_pHardwareConfig->GetDXSupportLevel()) ) - { - params[ENVMAP]->SetUndefined(); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - - if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) - { - if( params[BUMPMAP]->IsDefined() ) - { - Warning( "Can't use $bumpmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $bumpmap: %s\n", pMaterialName ); - params[BUMPMAP]->SetUndefined(); - } - if( params[ENVMAP]->IsDefined() ) - { - Warning( "Can't use $envmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $envmap: %s\n", pMaterialName ); - params[ENVMAP]->SetUndefined(); - } - } - - if ( !params[SEAMLESS_SCALE]->IsDefined() ) - { - // zero means don't do seamless mapping. - params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); - } - - // Get rid of envmap if we aren't using bumpmapping - // *and* we have normalmapalphaenvmapmask *and* we don't have envmapmask elsewhere - if ( params[ENVMAP]->IsDefined() && params[BUMPMAP]->IsDefined() && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) && !ShouldUseBumpmapping( params ) ) - { - if ( !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) && !params[ENVMAPMASK]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - } - } - - SHADER_FALLBACK - { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80) - return "LightmappedGeneric_DX6"; - - if ( IsPC() && g_pHardwareConfig->PreferReducedFillrate() ) - return "LightmappedGeneric_NoBump_DX8"; - - return 0; - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - - if( ShouldUseBumpmapping( params ) ) - { - LoadBumpMap( BUMPMAP ); - } - - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - LoadCubeMap( ENVMAP ); - else - LoadTexture( ENVMAP ); - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if (params[ENVMAPMASK]->IsDefined()) - LoadTexture( ENVMAPMASK ); - } - - if( ShouldUseBumpmapping( params ) ) - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - } - } - -#ifndef USE_HLSL_PIXEL_SHADERS - inline const char *GetPixelShaderName( IMaterialVar** params, bool bBumpedEnvMap ) - { - static char const* s_pPixelShaders[] = - { - // Unmasked - "LightmappedGeneric_EnvMapV2", - "LightmappedGeneric_SelfIlluminatedEnvMapV2", - - "LightmappedGeneric_BaseAlphaMaskedEnvMapV2", - "LightmappedGeneric_SelfIlluminatedEnvMapV2", - - // Env map mask - "LightmappedGeneric_MaskedEnvMapV2", - "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", - - "LightmappedGeneric_MaskedEnvMapV2", - "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", - }; - - if (!params[BASETEXTURE]->IsTexture()) - { - if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) - { - if (!params[ENVMAPMASK]->IsDefined() ) - { - return "LightmappedGeneric_EnvmapNoTexture"; - } - else - { - return "LightmappedGeneric_MaskedEnvmapNoTexture"; - } - } - else - { - return "LightmappedGeneric_NoTexture"; - } - } - else - { - if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) - { - int pshIndex = 0; - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) - pshIndex |= 0x1; - if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - pshIndex |= 0x2; - if (params[ENVMAPMASK]->IsTexture()) - pshIndex |= 0x4; - return s_pPixelShaders[pshIndex]; - } - else - { - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) - return "LightmappedGeneric_SelfIlluminated"; - else - return "LightmappedGeneric"; - } - } - } -#endif - - void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) - { - bool hasEnvmap = params[ENVMAP]->IsTexture() && !bBumpedEnvMap; - bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); - bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - bool hasEnvmapCameraSpace = IS_FLAG_SET( MATERIAL_VAR_ENVMAPCAMERASPACE ); - bool hasEnvmapSphere = IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ); - - if ( hasEnvmap || hasBaseTexture || hasVertexColor || !bBumpedEnvMap ) - { - SHADOW_STATE - { - // Alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); - } - - // Base texture on stage 0 - if (params[BASETEXTURE]->IsTexture()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - } - - // Lightmap on stage 1 - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - int fmt = VERTEX_POSITION; - - if ( hasEnvmap ) - { - fmt |= VERTEX_NORMAL; - - // envmap on stage 2 - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // envmapmask on stage 3 - if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - } - } - - if (params[BASETEXTURE]->IsTexture() || bBumpedEnvMap) - { - SetDefaultBlendingShadowState( BASETEXTURE, true ); - } - else - { - SetDefaultBlendingShadowState( ENVMAPMASK, false ); - } - - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - { - fmt |= VERTEX_COLOR; - } - - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - lightmappedgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( false ); - vshIndex.SetENVMAP( hasEnvmap ); - vshIndex.SetENVMAPCAMERASPACE( hasEnvmap && hasEnvmapCameraSpace ); - vshIndex.SetENVMAPSPHERE( hasEnvmap && hasEnvmapSphere ); - vshIndex.SetVERTEXCOLOR( hasVertexColor ); - pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); - - const char *pshName = GetPixelShaderName( params, bBumpedEnvMap ); - pShaderShadow->SetPixelShader( pshName ); - DefaultFog(); - } - DYNAMIC_STATE - { - if (hasBaseTexture) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - } - - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - if ( hasEnvmap ) - { - BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); - - if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - { - if (params[ENVMAPMASK]->IsTexture() ) - BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); - else - BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); - - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); - } - - if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || - IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) - { - LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); - } - SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); - } - - if ( !hasEnvmap || hasBaseTexture || hasVertexColor ) - { - SetModulationVertexShaderDynamicState(); - } - EnablePixelShaderOverbright( 0, true, true ); - SetPixelShaderConstant( 1, SELFILLUMTINT ); - - lightmappedgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - if ( bBumpedEnvMap ) - { - DrawWorldBumpedSpecularLighting( - BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, - ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, - BUMPTRANSFORM, FRESNELREFLECTION, - hasEnvmap || hasBaseTexture || hasVertexColor ); - } - } - - void DrawDetailNoEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doSelfIllum ) - { - SHADOW_STATE - { - // Alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - // Base texture on stage 0 - if (params[BASETEXTURE]->IsTexture()) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Lightmap on stage 1 - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // Detail on stage 2 - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - int fmt = VERTEX_POSITION; - - SetDefaultBlendingShadowState( BASETEXTURE, true ); - - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - fmt |= VERTEX_COLOR; - - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - lightmappedgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( true ); - vshIndex.SetENVMAP( false ); - vshIndex.SetENVMAPCAMERASPACE( false ); - vshIndex.SetENVMAPSPHERE( false ); - vshIndex.SetVERTEXCOLOR( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); - pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); - - if (!params[BASETEXTURE]->IsTexture()) - { - pShaderShadow->SetPixelShader("LightmappedGeneric_DetailNoTexture"); - } - else - { - if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || (!doSelfIllum)) - { - pShaderShadow->SetPixelShader("LightmappedGeneric_Detail"); - } - else - { - pShaderShadow->SetPixelShader("LightmappedGeneric_DetailSelfIlluminated"); - } - } - DefaultFog(); - } - DYNAMIC_STATE - { - if (params[BASETEXTURE]->IsTexture()) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - } - - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - BindTexture( SHADER_SAMPLER2, DETAIL, FRAME ); - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); - - SetModulationVertexShaderDynamicState(); - EnablePixelShaderOverbright( 0, true, true ); - - if (doSelfIllum) - { - SetPixelShaderConstant( 1, SELFILLUMTINT ); - } - float c2[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - c2[0] = c2[1] = c2[2] = c2[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); - pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); - - lightmappedgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - inline const char *GetAdditiveEnvmapPixelShaderName( bool usingMask, - bool usingBaseTexture, bool usingBaseAlphaEnvmapMask ) - { - static char const* s_pPixelShaders[] = - { - "LightmappedGeneric_AddEnvmapNoTexture", - "LightmappedGeneric_AddEnvmapMaskNoTexture", - }; - - if ( !usingMask && usingBaseTexture && usingBaseAlphaEnvmapMask ) - return "LightmappedGeneric_AddBaseAlphaMaskedEnvMap"; - - int pshIndex = 0; - if (usingMask) - pshIndex |= 0x1; - return s_pPixelShaders[pshIndex]; - } - - void DrawAdditiveEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - bool usingBaseTexture = params[BASETEXTURE]->IsTexture(); - bool usingMask = params[ENVMAPMASK]->IsTexture(); - bool usingBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); - SHADOW_STATE - { - // Alpha test - pShaderShadow->EnableAlphaTest( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); - - // envmap on stage 2 - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // envmapmask on stage 3 - if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - } - - if (params[BASETEXTURE]->IsTexture()) - { - SetAdditiveBlendingShadowState( BASETEXTURE, true ); - } - else - { - SetAdditiveBlendingShadowState( ENVMAPMASK, false ); - } - - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Compute the vertex shader index. - lightmappedgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( false ); - vshIndex.SetENVMAP( true ); - vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); - vshIndex.SetENVMAPSPHERE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ); - vshIndex.SetVERTEXCOLOR( false ); - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); - - const char *pshName = GetAdditiveEnvmapPixelShaderName( usingMask, - usingBaseTexture, usingBaseAlphaEnvmapMask ); - pShaderShadow->SetPixelShader( pshName ); - FogToBlack(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); - - if (usingMask || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - { - if (usingMask) - BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); - else - BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); - - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); - } - - SetPixelShaderConstant( 2, ENVMAPTINT ); - - if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) - { - LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); - } - - SetModulationVertexShaderDynamicState(); - - // Compute the vertex shader index. - lightmappedgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - void DrawDetailMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) - { - // Mode 1 : - // Pass 1 : B * L * D + Self Illum - // Pass 2 : Add E * M - - // Draw the detail w/ no envmap - DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, true ); - - if ( !bBumpedEnvMap ) - { - DrawAdditiveEnvmap( params, pShaderAPI, pShaderShadow ); - } - else - { - DrawWorldBumpedSpecularLighting( - BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, - ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, - BUMPTRANSFORM, FRESNELREFLECTION, - true ); - } - } - - void DrawDetailUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) - { - // We don't have enough textures; gotta do this in two passes if there's envmapping - if (!params[ENVMAP]->IsTexture()) - { - DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ); - } - else - { - if (!params[BASETEXTURE]->IsTexture()) - { - // If there's an envmap but no base texture, ignore detail - DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); - } - else - { - DrawDetailMode1( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); - } - } - } - - void DrawUnbumpedSeamlessUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // This is the seamless_scale version, which doesn't use $detail or $bumpmap - SHADOW_STATE - { - // three copies of the base texture for seamless blending - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // lightmap - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - worldvertextransition_seamless_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); - - int pshIndex = 0; - pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - // Texture 0..2 - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); - } - - // Texture 3 = lightmap - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); - - EnablePixelShaderOverbright( 0, true, true ); - - float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); - float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); - - worldvertextransition_seamless_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - SHADER_DRAW - { - bool hasFlashlight = UsingFlashlight( params ); - bool bBump = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && - (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); - bool bSSBump = bBump && ( params[SSBUMP]->GetIntValue() != 0 ); - - if( hasFlashlight ) - { - DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); - } - else if( bBump ) - { - DrawWorldBumpedUsingVertexShader( - BASETEXTURE, BASETEXTURETRANSFORM, - BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, - ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, FRESNELREFLECTION, - false, -1, -1, -1, bSSBump ); - } - else - { - bool bBumpedEnvMap = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && params[ENVMAP]->IsTexture(); - if (!params[DETAIL]->IsTexture()) - { - if( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) - { - DrawUnbumpedSeamlessUsingVertexShader( params, pShaderAPI, pShaderShadow ); - } - else - { - DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); - } - } - else - { - DrawDetailUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); - } - } - } -END_SHADER - - -//----------------------------------------------------------------------------- -// Version that doesn't do bumpmapping -//----------------------------------------------------------------------------- -BEGIN_INHERITED_SHADER( LightmappedGeneric_NoBump_DX8, LightmappedGeneric_DX8, - "Help for LightmappedGeneric_NoBump_DX8" ) - - SHADER_FALLBACK - { - if (g_pHardwareConfig->GetDXSupportLevel() < 80) - return "LightmappedGeneric_DX6"; - - return 0; - } - - virtual bool ShouldUseBumpmapping( IMaterialVar **params ) - { - if ( !g_pConfig->UseBumpmapping() ) - return false; - - if ( !params[BUMPMAP]->IsDefined() ) - return false; - - return ( params[FORCEBUMP]->GetIntValue() != 0 ); - } - -END_INHERITED_SHADER diff --git a/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp b/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp deleted file mode 100644 index 7a683abd..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp +++ /dev/null @@ -1,236 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Lightmap only shader -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "convar.h" -#include "lightmappedgeneric_dx9_helper.h" -#ifdef VANCE -#include "lightpass_helper.h" -#include "vertexlitpbr_dx9_helper.h" -#endif // VANCE - - -static LightmappedGeneric_DX9_Vars_t s_info; - - -#ifdef STDSHADER -BEGIN_VS_SHADER(LightmappedGeneric, - "Help for LightmappedGeneric" ) -#else -BEGIN_VS_SHADER(SDK_LightmappedGeneric, - "Help for LightmappedGeneric" ) -#endif - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - - SHADER_PARAM( ALPHA2, SHADER_PARAM_TYPE_FLOAT, "1", "" ) - - // detail (multi-) texturing - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) - SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) - - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) - SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) - SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) - SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "Blended texture" ) - SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) - SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) - SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) - SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", - "If this is 1, then when detail alpha=0, no base texture is blended and when " - "detail alpha=1, you get detail*base*lightmap" ) - SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) - SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) - SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) - SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) - SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) - SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - - SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") - SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); - SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); - - SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") - SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) - SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") - SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") - SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") - SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") - SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") -#ifdef VANCE - SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") - SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") - SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") - SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") - SHADER_PARAM(USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness") - - SHADER_PARAM(ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "Origin of the env_cubemap (for sphere projected cubemap)") - SHADER_PARAM(ENVMAPRADIUS, SHADER_PARAM_TYPE_INTEGER, "0", "Radius of the env_cubemap (for sphere projected cubemap)") -#endif // VANCE - - END_SHADER_PARAMS - -#ifdef VANCE - void SetupVars(DrawLightPass_Vars_t& info) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nNoise = NOISE; - info.m_nBumpmap = BUMPMAP; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nBumpmap2 = BUMPMAP2; - info.m_nBumpFrame2 = BUMPFRAME2; - info.m_nBumpTransform2 = BUMPTRANSFORM2; - info.m_nBaseTexture2 = BASETEXTURE2; - info.m_nBaseTexture2Frame = FRAME2; - info.m_nSeamlessMappingScale = SEAMLESS_SCALE; - info.bModel = false; - info.m_nUseSmoothness = USESMOOTHNESS; - } - - void SetupVars(VertexLitPBR_DX9_Vars_t& info) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nEnvmap = ENVMAP; - info.m_nBumpmap = BUMPMAP; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nBRDF = BRDF; - info.m_nUseSmoothness = USESMOOTHNESS; - } -#endif // VANCE - - void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlbedo = ALBEDO; - info.m_nSelfIllumTint = SELFILLUMTINT; - - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - - info.m_nAlpha2 = ALPHA2; - - info.m_nDetail = DETAIL; - info.m_nDetailFrame = DETAILFRAME; - info.m_nDetailScale = DETAILSCALE; - info.m_nDetailTextureCombineMode = DETAILBLENDMODE; - info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; - info.m_nDetailTint = DETAILTINT; - - info.m_nEnvmap = ENVMAP; - info.m_nEnvmapFrame = ENVMAPFRAME; - info.m_nEnvmapMask = ENVMAPMASK; - info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; - info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; - info.m_nEnvmapTint = ENVMAPTINT; - info.m_nEnvmapOrigin = ENVMAPORIGIN; - info.m_nEnvmapRadius = ENVMAPRADIUS; - info.m_nBumpmap = BUMPMAP; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - info.m_nEnvmapContrast = ENVMAPCONTRAST; - info.m_nEnvmapSaturation = ENVMAPSATURATION; - info.m_nFresnelReflection = FRESNELREFLECTION; - info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; - info.m_nBumpmap2 = BUMPMAP2; - info.m_nBumpFrame2 = BUMPFRAME2; - info.m_nBumpTransform2 = BUMPTRANSFORM2; - info.m_nBumpMask = BUMPMASK; - info.m_nBaseTexture2 = BASETEXTURE2; - info.m_nBaseTexture2Frame = FRAME2; - info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; - info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; - info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nLightWarpTexture = LIGHTWARPTEXTURE; - info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; - info.m_nMaskedBlending = MASKEDBLENDING; - info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; - info.m_nSelfShadowedBumpFlag = SSBUMP; - info.m_nSeamlessMappingScale = SEAMLESS_SCALE; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - - info.m_nSoftEdges = SOFTEDGES; - info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; - info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; - info.m_nOutline = OUTLINE; - info.m_nOutlineColor = OUTLINECOLOR; - info.m_nOutlineAlpha = OUTLINEALPHA; - info.m_nOutlineStart0 = OUTLINESTART0; - info.m_nOutlineStart1 = OUTLINESTART1; - info.m_nOutlineEnd0 = OUTLINEEND0; - info.m_nOutlineEnd1 = OUTLINEEND1; - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "LightmappedGeneric_DX8"; - - return 0; - } - - // Set up anything that is necessary to make decisions in SHADER_FALLBACK. - SHADER_INIT_PARAMS() - { - SetupVars( s_info ); - InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); - } - - SHADER_INIT - { - SetupVars( s_info ); - InitLightmappedGeneric_DX9( this, params, s_info ); - } - - SHADER_DRAW - { - bool bDrawStandardPass = true; - - if (bDrawStandardPass) - { - DrawLightmappedGeneric_DX9(this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr); - } - else - { - // Skip this pass! - Draw(false); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp deleted file mode 100644 index 207eac2a..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp +++ /dev/null @@ -1,1146 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Lightmap only shader -// -// $Header: $ -// $NoKeywords: $ -//============================================================================= - -#include "lightmappedgeneric_dx9_helper.h" -#include "BaseVSShader.h" -#include "commandbuilder.h" -#include "convar.h" -#ifndef VANCE - -#include "lightmappedgeneric_ps20.inc" -#include "lightmappedgeneric_vs20.inc" -#include "lightmappedgeneric_ps20b.inc" -#else - -#include "IDeferredExt.h" -#include "lightmappedgeneric_ps30.inc" -#include "lightmappedgeneric_vs30.inc" - -#endif // !VANCE - -#include "tier0/memdbgon.h" - -ConVar mat_disable_lightwarp( "mat_disable_lightwarp", "0" ); -ConVar mat_disable_fancy_blending( "mat_disable_fancy_blending", "0" ); -ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); -ConVar my_mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); -ConVar mat_cubemapparallax("mat_cubemapparallax","1"); -extern ConVar r_csm_bias; -extern ConVar r_csm_slopescalebias; -extern ConVar r_csm_performance; -#ifndef VANCE -extern ConVar r_flashlight_version2; -#endif // !VANCE - -class CLightmappedGeneric_DX9_Context : public CBasePerMaterialContextData -{ -public: - uint8 *m_pStaticCmds; - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; - - bool m_bVertexShaderFastPath; - bool m_bPixelShaderFastPath; - bool m_bPixelShaderForceFastPathBecauseOutline; - bool m_bFullyOpaque; - bool m_bFullyOpaqueWithoutAlphaTest; - - void ResetStaticCmds( void ) - { - if ( m_pStaticCmds ) - { - delete[] m_pStaticCmds; - m_pStaticCmds = NULL; - } - } - - CLightmappedGeneric_DX9_Context( void ) - { - m_pStaticCmds = NULL; - } - - ~CLightmappedGeneric_DX9_Context( void ) - { - ResetStaticCmds(); - } - -}; - - -void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ) -{ - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. - if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && - params[info.m_nBaseTexture]->IsDefined() && - !( params[info.m_nNoDiffuseBumpLighting]->IsDefined() && params[info.m_nNoDiffuseBumpLighting]->GetIntValue() ) ) - { - params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); - } - - if( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() ) - { - if( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 ) - { - Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); - params[info.m_nEnvmap]->SetUndefined(); - } - } - - if ( (mat_disable_lightwarp.GetBool() ) && - (info.m_nLightWarpTexture != -1) ) - { - params[info.m_nLightWarpTexture]->SetUndefined(); - } - if ( (mat_disable_fancy_blending.GetBool() ) && - (info.m_nBlendModulateTexture != -1) ) - { - params[info.m_nBlendModulateTexture]->SetUndefined(); - } - - if( !params[info.m_nEnvmapTint]->IsDefined() ) - params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() ) - params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 ); - - if( !params[info.m_nSelfIllumTint]->IsDefined() ) - params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[info.m_nDetailScale]->IsDefined() ) - params[info.m_nDetailScale]->SetFloatValue( 4.0f ); - - if ( !params[info.m_nDetailTint]->IsDefined() ) - params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f ); - - InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); - InitIntParam( info.m_nDetailTextureCombineMode, params, 0 ); - - if( !params[info.m_nFresnelReflection]->IsDefined() ) - params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); - - if( !params[info.m_nEnvmapMaskFrame]->IsDefined() ) - params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 ); - - if( !params[info.m_nEnvmapFrame]->IsDefined() ) - params[info.m_nEnvmapFrame]->SetIntValue( 0 ); - - if (info.m_nEnvmapRadius != -1 && !params[info.m_nEnvmapRadius]->IsDefined()) - params[info.m_nEnvmapRadius]->SetIntValue(-1); - - if( !params[info.m_nBumpFrame]->IsDefined() ) - params[info.m_nBumpFrame]->SetIntValue( 0 ); - - if( !params[info.m_nDetailFrame]->IsDefined() ) - params[info.m_nDetailFrame]->SetIntValue( 0 ); - - if( !params[info.m_nEnvmapContrast]->IsDefined() ) - params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); - - if( !params[info.m_nEnvmapSaturation]->IsDefined() ) - params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); - - InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); - - // No texture means no self-illum or env mask in base alpha - if ( !params[info.m_nBaseTexture]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - if( params[info.m_nBumpmap]->IsDefined() ) - { - params[info.m_nEnvmapMask]->SetUndefined(); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0) ) - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) - { - params[info.m_nEnvmap]->SetUndefined(); - } - - if( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) - { - params[info.m_nBaseTextureNoEnvmap]->SetIntValue( 0 ); - } - if( !params[info.m_nBaseTexture2NoEnvmap]->IsDefined() ) - { - params[info.m_nBaseTexture2NoEnvmap]->SetIntValue( 0 ); - } - - if( ( info.m_nSelfShadowedBumpFlag != -1 ) && - ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() ) - ) - { - params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 ); - } - // handle line art parms - InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); - InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); - InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); -} - -void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ) -{ - if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nBumpmap ); - } - - if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap2]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nBumpmap2 ); - } - - if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpMask]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nBumpMask ); - } - - if (params[info.m_nBaseTexture]->IsDefined()) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if (!params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent()) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[info.m_nBaseTexture2]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture2, TEXTUREFLAGS_SRGB ); - } - - if (params[info.m_nLightWarpTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nLightWarpTexture ); - } - - if ((info.m_nBlendModulateTexture != -1) && - (params[info.m_nBlendModulateTexture]->IsDefined()) ) - { - pShader->LoadTexture( info.m_nBlendModulateTexture ); - } - - if (params[info.m_nDetail]->IsDefined()) - { - int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); - nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; - - pShader->LoadTexture( info.m_nDetail, nDetailBlendMode != 0 ? TEXTUREFLAGS_SRGB : 0 ); - } - - pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - { - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - } - - if (params[info.m_nEnvmap]->IsDefined()) - { - if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - { - int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; - flags |= TEXTUREFLAGS_ALL_MIPS; - pShader->LoadCubeMap(info.m_nEnvmap, flags); - } - else - { - pShader->LoadTexture( info.m_nEnvmap ); - } - - if ( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if ( params[info.m_nEnvmapMask]->IsDefined() ) - { - pShader->LoadTexture( info.m_nEnvmapMask ); - } - } - else - { - params[info.m_nEnvmapMask]->SetUndefined(); - } - - // We always need this because of the flashlight. - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - - if (info.m_nRoughness != -1 && params[info.m_nRoughness]->IsDefined()) - pShader->LoadTexture(info.m_nRoughness); - if (info.m_nMetallic != -1 && params[info.m_nMetallic]->IsDefined()) - pShader->LoadTexture(info.m_nMetallic); -} - -void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar** params, bool hasFlashlight, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - LightmappedGeneric_DX9_Vars_t &info, - CBasePerMaterialContextData **pContextDataPtr - ) -{ - CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *> ( *pContextDataPtr ); - if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged || hasFlashlight ) - { - bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); - int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; - BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360()); //dest alpha is free for special use - bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; - bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow; - - if ( ! pContextData ) // make sure allocated - { - pContextData = new CLightmappedGeneric_DX9_Context; - *pContextDataPtr = pContextData; - } - - bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && ( !g_pHardwareConfig->PreferReducedFillrate() ); - bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); - bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); - bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture(); - bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); - bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); - bool hasBumpMask = hasBump && hasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && - !hasDetailTexture && !hasBaseTexture2 && (params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0); - bool bHasBlendModulateTexture = - (info.m_nBlendModulateTexture != -1) && - (params[info.m_nBlendModulateTexture]->IsTexture() ); - bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - - if ( hasFlashlight && !IsX360() ) - { - // !!speed!! do this in the caller so we don't build struct every time - CBaseVSShader::DrawFlashlight_dx90_Vars_t vars; - vars.m_bBump = hasBump; - vars.m_nBumpmapVar = info.m_nBumpmap; - vars.m_nBumpmapFrame = info.m_nBumpFrame; - vars.m_nBumpTransform = info.m_nBumpTransform; - vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; - vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; - vars.m_bLightmappedGeneric = true; - vars.m_bWorldVertexTransition = hasBaseTexture2; - vars.m_nBaseTexture2Var = info.m_nBaseTexture2; - vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; - vars.m_nBumpmap2Var = info.m_nBumpmap2; - vars.m_nBumpmap2Frame = info.m_nBumpFrame2; - vars.m_nBump2Transform = info.m_nBumpTransform2; - vars.m_nAlphaTestReference = info.m_nAlphaTestReference; - vars.m_bSSBump = hasSSBump; - vars.m_nDetailVar = info.m_nDetail; - vars.m_nDetailScale = info.m_nDetailScale; - vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; - vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; - vars.m_nDetailTint = info.m_nDetailTint; - - vars.m_nRoughness = info.m_nRoughness; - vars.m_nMetallic = info.m_nMetallic; - - vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; - - if ( ( info.m_nSeamlessMappingScale != -1 ) ) - vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); - else - vars.m_fSeamlessScale = 0.0; - pShader->DrawFlashlight_dx90( params, pShaderAPI, pShaderShadow, vars ); - return; - } - - pContextData->m_bFullyOpaque = bFullyOpaque; - pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; - - NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; - if ( hasBump && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - ITexture *pBumpTex = params[info.m_nBumpmap]->GetTextureValue(); - if ( pBumpTex ) - { - nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); - - if ( hasBump2 ) // Check encoding of secondary normal if there is oneg - { - ITexture *pBumpTex2 = params[info.m_nBumpmap]->GetTextureValue(); - if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) - { - DevMsg("LightmappedGeneric: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); - Assert(0); - } - } - } - } - - int nNormalMaskDecodeMode = 0; - if ( hasBumpMask && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - ITexture *pBumpMaskTex = params[info.m_nBumpMask]->GetTextureValue(); - if ( pBumpMaskTex ) - { - nNormalMaskDecodeMode = pBumpMaskTex->GetNormalDecodeMode(); - } - } - - bool bHasOutline = IsBoolSet( info.m_nOutline, params ); - pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; - bool bHasSoftEdges = IsBoolSet( info.m_nSoftEdges, params ); - bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); - - - float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); - - if ( pShaderShadow || bNeedRegenStaticCmds ) - { - bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - bool hasDiffuseBumpmap = hasBump && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0); - - bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); - - bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && - ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); - - if ( bNeedRegenStaticCmds ) - { - pContextData->ResetStaticCmds(); - CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; - - - if( !hasBaseTexture ) - { - if( hasEnvmap ) - { - // if we only have an envmap (no basetexture), then we want the albedo to be black. - staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); - } - else - { - staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - } - } - staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - if ( bSeamlessMapping ) - { - staticCmdsBuf.SetVertexShaderConstant4( - VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, - params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 ); - } - staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 ); - staticCmdsBuf.SetPixelShaderFogParams( 11 ); - staticCmdsBuf.End(); - // now, copy buf - pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; - memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); - } - if ( pShaderShadow ) - { - - // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); - - unsigned int flags = VERTEX_POSITION; - - // base texture - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - if ( bHasBlendModulateTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); - } - - if ( hasBaseTexture2 ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); - } -// if( hasLightmap ) - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - } - else - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); - } - - if( hasEnvmap ) - { - if( hasEnvmap ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); - } - } - flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; - } - - int nDetailBlendMode = 0; - if ( hasDetailTexture ) - { - nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); - } - - if( hasDetailTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); - bool bSRGBState = ( nDetailBlendMode == 1 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, bSRGBState ); - } - - if( hasBump || hasNormalMapAlphaEnvmapMask ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Normal map alpha, in the compressed normal case - } - } - if( hasBump2 ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Secondary normal alpha, in the compressed normal case - } - } - if( hasBumpMask ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); - if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal mask alpha, in the compressed normal case - } - } - if( hasEnvmapMask ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - } - - { - pShaderShadow->EnableTexture(SHADER_SAMPLER13, true); // CSM depth texture (has to be on at all times) - } - - if( hasVertexColor || hasBaseTexture2 || hasBump2 ) - { - flags |= VERTEX_COLOR; - } - - // texcoord0 : base texcoord - // texcoord1 : lightmap texcoord - // texcoord2 : lightmap texcoord offset - int numTexCoords = 2; - if( hasBump ) - { - numTexCoords = 3; - } - - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - - // Pre-cache pixel shaders - bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - - int bumpmap_variant= hasBump; - bool bMaskedBlending=( (info.m_nMaskedBlending != -1) && - (params[info.m_nMaskedBlending]->GetIntValue() != 0) ); -#ifndef VANCE - DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); -#else - DECLARE_STATIC_VERTEX_SHADER(lightmappedgeneric_vs30); -#endif // !VANCE - SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); - SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, 1 ); - SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); - SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); - SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); - - //bool bReliefMapping = false; //( bumpmap_variant == 2 ) && ( ! bSeamlessMapping ); - //SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, false );//bReliefMapping ); - SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); -#ifdef _X360 - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight); -#endif -#ifndef VANCE - SET_STATIC_VERTEX_SHADER(lightmappedgeneric_vs20); -#else - SET_STATIC_VERTEX_SHADER(lightmappedgeneric_vs30); -#endif // !VANCE -#ifndef VANCE - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); - SET_STATIC_PIXEL_SHADER_COMBO( RELIEF_MAPPING, bReliefMapping ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); - SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, (int) nNormalMaskDecodeMode ); -#ifdef _X360 - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight); -#endif - SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); - SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!) - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0 - SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); - } -#else - DECLARE_STATIC_PIXEL_SHADER(lightmappedgeneric_ps30); - SET_STATIC_PIXEL_SHADER_COMBO(BASETEXTURE2, hasBaseTexture2); - SET_STATIC_PIXEL_SHADER_COMBO(DETAILTEXTURE, hasDetailTexture); - SET_STATIC_PIXEL_SHADER_COMBO(BUMPMAP, bumpmap_variant); - SET_STATIC_PIXEL_SHADER_COMBO(BUMPMAP2, hasBump2); - SET_STATIC_PIXEL_SHADER_COMBO(BUMPMASK, hasBumpMask); - SET_STATIC_PIXEL_SHADER_COMBO(DIFFUSEBUMPMAP, hasDiffuseBumpmap); - SET_STATIC_PIXEL_SHADER_COMBO(CUBEMAP, hasEnvmap); - SET_STATIC_PIXEL_SHADER_COMBO(ENVMAPMASK, hasEnvmapMask); - SET_STATIC_PIXEL_SHADER_COMBO(BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask); - SET_STATIC_PIXEL_SHADER_COMBO(SELFILLUM, hasSelfIllum); - SET_STATIC_PIXEL_SHADER_COMBO(NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask); - SET_STATIC_PIXEL_SHADER_COMBO(BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue()); - SET_STATIC_PIXEL_SHADER_COMBO(BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue()); - SET_STATIC_PIXEL_SHADER_COMBO(FANCY_BLENDING, bHasBlendModulateTexture); - SET_STATIC_PIXEL_SHADER_COMBO(MASKEDBLENDING, bMaskedBlending); - SET_STATIC_PIXEL_SHADER_COMBO(SEAMLESS, bSeamlessMapping); - //SET_STATIC_PIXEL_SHADER_COMBO(OUTLINE, bHasOutline); - //SET_STATIC_PIXEL_SHADER_COMBO(SOFTEDGES, bHasSoftEdges); - SET_STATIC_PIXEL_SHADER(lightmappedgeneric_ps30); -#endif // !VANCE - // HACK HACK HACK - enable alpha writes all the time so that we have them for - // underwater stuff and writing depth to dest alpha - // But only do it if we're not using the alpha already for translucency - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - - pShaderShadow->EnableSRGBWrite( true ); - - pShader->DefaultFog(); - - - } // end shadow state - } // end shadow || regen display list - if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) - { - // need to regenerate the semistatic cmds - pContextData->m_SemiStaticCmdsOut.Reset(); - pContextData->m_bMaterialVarsChanged = false; - - bool bHasBlendMaskTransform= ( - (info.m_nBlendMaskTransform != -1) && - (info.m_nMaskedBlending != -1) && - (params[info.m_nMaskedBlending]->GetIntValue() ) && - ( ! (params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); - - // If we don't have a texture transform, we don't have - // to set vertex shader constants or run vertex shader instructions - // for the texture transform. - bool bHasTextureTransform = - !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && - params[info.m_nBumpTransform]->MatrixIsIdentity() && - params[info.m_nBumpTransform2]->MatrixIsIdentity() && - params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); - - bHasTextureTransform |= bHasBlendMaskTransform; - - pContextData->m_bVertexShaderFastPath = !bHasTextureTransform; - - if( params[info.m_nDetail]->IsTexture() ) - { - pContextData->m_bVertexShaderFastPath = false; - } - if (bHasBlendMaskTransform) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( - VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, info.m_nBlendMaskTransform ); - } - - if ( ! pContextData->m_bVertexShaderFastPath ) - { - bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && - ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); - bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); - if (!bSeamlessMapping ) - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - // If we have a detail texture, then the bump texcoords are the same as the base texcoords. - if( hasBump && !hasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); - } - if( hasEnvmapMask ) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); - } - else if ( hasBump2 ) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 ); - } - } - pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint ); - // set up shader modulation color - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - pShader->ComputeModulationColor( color ); - float flLScale = pShaderAPI->GetLightMapScaleFactor(); - color[0] *= flLScale; - color[1] *= flLScale; - color[2] *= flLScale; - - pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); - - color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f; - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); - - if ( hasDetailTexture ) - { - float detailTintAndBlend[4] = {1, 1, 1, 1}; - - if ( info.m_nDetailTint != -1 ) - { - params[info.m_nDetailTint]->GetVecValue( detailTintAndBlend, 3 ); - } - - detailTintAndBlend[3] = fDetailBlendFactor; - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTintAndBlend ); - } - - float envmapTintVal[4]; - float selfIllumTintVal[4]; - params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 ); - params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); - float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); - float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); - float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); - bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); - - pContextData->m_bPixelShaderFastPath = true; - bool bUsingContrast = hasEnvmap && ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) && (envmapSaturation != 1.0f); - bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f); - bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f); - if ( bUsingContrast || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) - { - pContextData->m_bPixelShaderFastPath = false; - } - if( !pContextData->m_bPixelShaderFastPath ) - { - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 ); - pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() ); - pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() ); - float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); - // [ 0, 0, 1-R(0), R(0) ] - pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel ); - - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() ); - } - else - { - if ( bHasOutline ) - { - float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), - GetFloatParam( info.m_nOutlineStart1, params ), - GetFloatParam( info.m_nOutlineEnd0, params ), - GetFloatParam( info.m_nOutlineEnd1, params ), - 0,0,0, - GetFloatParam( info.m_nOutlineAlpha, params ) }; - if ( info.m_nOutlineColor != -1 ) - { - params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); - } - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, flOutlineParms, 2 ); - } - - if ( bHasSoftEdges ) - { - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( - 4, GetFloatParam( info.m_nEdgeSoftnessStart, params ), - GetFloatParam( info.m_nEdgeSoftnessEnd, params ), - 0,0 ); - } - } - // texture binds - if( hasBaseTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - // handle mat_fullbright 2 - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - if( bLightingOnly ) - { - // BASE TEXTURE - if( hasSelfIllum ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - // BASE TEXTURE 2 - if( hasBaseTexture2 ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); - } - - // DETAIL TEXTURE - if( hasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); - } - - // disable color modulation - float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); - - // turn off environment mapping - envmapTintVal[0] = 0.0f; - envmapTintVal[1] = 0.0f; - envmapTintVal[2] = 0.0f; - } - - // always set the transform for detail textures since I'm assuming that you'll - // always have a detailscale. - if( hasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); - } - - if( hasBaseTexture2 ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); - } - if( hasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nDetail, info.m_nDetailFrame ); - } - - if( hasBump || hasNormalMapAlphaEnvmapMask ) - { - if( !g_pConfig->m_bFastNoBump ) - { - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER4, SHADER_SAMPLER9, info.m_nBumpmap, info.m_nBumpFrame ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nBumpmap, info.m_nBumpFrame ); - } - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); - } - } - if( hasBump2 ) - { - if( !g_pConfig->m_bFastNoBump ) - { - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER5, SHADER_SAMPLER10, info.m_nBumpmap2, info.m_nBumpFrame2 ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); - } - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); - } - } - if( hasBumpMask ) - { - if( !g_pConfig->m_bFastNoBump ) - { - if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - Assert(0); - //pContextData->m_SemiStaticCmdsOut.BindTexture( SHADER_SAMPLER8, SHADER_SAMPLER11, info.m_nBumpMask ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBumpMask, -1 ); - } - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, TEXTURE_NORMALMAP_FLAT ); - } - } - - if( hasEnvmapMask ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); - } - - if ( bHasBlendModulateTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 ); - } - - pContextData->m_SemiStaticCmdsOut.End(); - } - } - DYNAMIC_STATE - { - - - ITexture* pCascadedDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_DEPTHTEXTURE); - bool bCSM = pCascadedDepthTexture != NULL; - - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; - DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); - DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); - - bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); - bool isEnvmapCorrected = (info.m_nEnvmapRadius != -1 && info.m_nEnvmapRadius != -1) && (params[info.m_nEnvmapRadius]->IsDefined() && params[info.m_nEnvmapRadius]->GetIntValue() > 0) && params[info.m_nEnvmapOrigin]->IsDefined(); - - if (isEnvmapCorrected) - { - float* origin = (float*)params[info.m_nEnvmapOrigin]->GetVecValue(); - float radius = (float)params[info.m_nEnvmapRadius]->GetIntValue(); - float origin_And_Radius[4] = { origin[0], origin[1], origin[2], radius }; - DynamicCmdsOut.SetPixelShaderConstant(20, origin_And_Radius); - } - - if( hasEnvmap ) - { - DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); - } - int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); - - bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; - - if( nFixedLightingMode != 0 ) - { - if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) - nFixedLightingMode = 0; - else - bVertexShaderFastPath = false; - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); -#ifndef VANCE - DECLARE_DYNAMIC_VERTEX_SHADER(lightmappedgeneric_vs20); -#else - DECLARE_DYNAMIC_VERTEX_SHADER(lightmappedgeneric_vs30); -#endif // !VANCE - - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( - LIGHTING_PREVIEW, - (nFixedLightingMode)?1:0 - ); -#ifndef VANCE - SET_DYNAMIC_VERTEX_SHADER(lightmappedgeneric_vs20); -#else - SET_DYNAMIC_VERTEX_SHADER(lightmappedgeneric_vs30); -#endif // !VANCE - - bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; - if( nFixedLightingMode !=0 ) - { - bPixelShaderFastPath = false; - } - bool bWriteDepthToAlpha; - bool bWriteWaterFogToAlpha; - if( pContextData->m_bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - else - { - //can't write a special value to dest alpha if we're actually using as-intended alpha - bWriteDepthToAlpha = false; - bWriteWaterFogToAlpha = false; - } - - float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); -#ifndef VANCE - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - - DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - - // Don't write fog to alpha if we're using translucency - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); - - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - - // Don't write fog to alpha if we're using translucency - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); - - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20 ); - } -#else - DECLARE_DYNAMIC_PIXEL_SHADER(lightmappedgeneric_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO(FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline); - SET_DYNAMIC_PIXEL_SHADER_COMBO(FASTPATHENVMAPCONTRAST, bPixelShaderFastPath&& envmapContrast == 1.0f); - SET_DYNAMIC_PIXEL_SHADER_COMBO(PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo()); - - // Don't write fog to alpha if we're using translucency - SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha); - SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha); - - SET_DYNAMIC_PIXEL_SHADER_COMBO(CUBEMAPCORRECTED, isEnvmapCorrected && hasEnvmap && mat_cubemapparallax.GetBool()); - SET_DYNAMIC_PIXEL_SHADER_COMBO(LIGHTING_PREVIEW, nFixedLightingMode); - - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM, bCSM && !hasFlashlight ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM_PERF, MAX( 0, MIN( r_csm_performance.GetInt(), 2 ) ) ); // i just dont know anymore - SET_DYNAMIC_PIXEL_SHADER_CMD(DynamicCmdsOut, lightmappedgeneric_ps30); -#endif // !1 - - - if (bCSM) - { - pShader->BindTexture(SHADER_SAMPLER13, pCascadedDepthTexture); - VMatrix* worldToTexture0 = (VMatrix*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0); - pShaderAPI->SetPixelShaderConstant(22, worldToTexture0->Base(), 4); - - lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); - Vector csmFwd = csmData.vecLight; - pShaderAPI->SetPixelShaderConstant(26, csmFwd.Base()); - - Vector csmLight = csmData.light.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(27, csmLight.Base()); - - Vector csmAmbient = csmData.ambient.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(1, csmAmbient.Base()); - - float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; - pShaderAPI->SetPixelShaderConstant(5, biasVar); - - float textureSize[2] = { pCascadedDepthTexture->GetMappingHeight() * 4.0f, pCascadedDepthTexture->GetMappingHeight() }; - pShaderAPI->SetPixelShaderConstant(6, textureSize); - - pShaderAPI->SetPixelShaderConstant(9, GetDeferredExt()->GetLightData_Global().sizes.Base()); - } - - DynamicCmdsOut.End(); - pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); - } - pShader->Draw(); - - if( IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) - { - //Alpha testing makes it so we can't write to dest alpha - //Writing to depth makes it so later polygons can't write to dest alpha either - //This leads to situations with garbage in dest alpha. - - //Fix it now by converting depth to dest alpha for any pixels that just wrote. - pShader->DrawEqualDepthToDestAlpha(); - } -} - -void DrawLightmappedGeneric_DX9(CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - LightmappedGeneric_DX9_Vars_t &info, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool hasFlashlight = pShader->UsingFlashlight(params); -#ifndef VANCE - if ( !IsX360() && !r_flashlight_version2.GetInt() ) - { - DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); - return; - } -#endif // !VANCE - - DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h b/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h deleted file mode 100644 index e029c6a2..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h +++ /dev/null @@ -1,106 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef LIGHTMAPPEDGENERIC_DX9_HELPER_H -#define LIGHTMAPPEDGENERIC_DX9_HELPER_H - -#include -#include "BaseVSShader.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct LightmappedGeneric_DX9_Vars_t -{ - LightmappedGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(LightmappedGeneric_DX9_Vars_t) ); } - - int m_nBaseTexture; - int m_nBaseTextureFrame; - int m_nBaseTextureTransform; - int m_nAlbedo; - int m_nSelfIllumTint; - - int m_nRoughness; - int m_nMetallic; - - int m_nAlpha2; // Hack for DoD srgb blend issues on overlays - - int m_nDetail; - int m_nDetailFrame; - int m_nDetailScale; - int m_nDetailTextureCombineMode; - int m_nDetailTextureBlendFactor; - int m_nDetailTint; - - int m_nEnvmap; - int m_nEnvmapFrame; - int m_nEnvmapMask; - int m_nEnvmapMaskFrame; - int m_nEnvmapMaskTransform; - int m_nEnvmapTint; - int m_nEnvmapContrast; - int m_nEnvmapSaturation; - int m_nEnvmapOrigin; - int m_nEnvmapRadius; - - int m_nBumpmap; - int m_nBumpFrame; - int m_nBumpTransform; - - int m_nFresnelReflection; - int m_nNoDiffuseBumpLighting; - int m_nBumpmap2; - int m_nBumpFrame2; - int m_nBumpTransform2; - int m_nBumpMask; - int m_nBaseTexture2; - int m_nBaseTexture2Frame; - int m_nBaseTextureNoEnvmap; - int m_nBaseTexture2NoEnvmap; - int m_nDetailAlphaMaskBaseTexture; - int m_nFlashlightTexture; - int m_nFlashlightTextureFrame; - int m_nLightWarpTexture; - int m_nBlendModulateTexture; - int m_nMaskedBlending; - int m_nBlendMaskTransform; - int m_nSelfShadowedBumpFlag; - int m_nSeamlessMappingScale; - int m_nAlphaTestReference; - - int m_nSoftEdges; - int m_nEdgeSoftnessStart; - int m_nEdgeSoftnessEnd; - - int m_nOutline; - int m_nOutlineColor; - int m_nOutlineAlpha; - int m_nOutlineStart0; - int m_nOutlineStart1; - int m_nOutlineEnd0; - int m_nOutlineEnd1; - -}; - -void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ); -void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ); -void DrawLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr ); - - -#endif // LIGHTMAPPEDGENERIC_DX9_HELPER_H diff --git a/materialsystem/stdshaders/lightmappedgeneric_envmap.psh b/materialsystem/stdshaders/lightmappedgeneric_envmap.psh deleted file mode 100644 index 49217fee..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_envmap.psh +++ /dev/null @@ -1,20 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) -mul r0.rgb, t1, r0 ; fold in lightmap (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc b/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc deleted file mode 100644 index 3a0d059d..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc +++ /dev/null @@ -1,122 +0,0 @@ -//====== Copyright 1996-2007, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "NORMALMAP" "0..1" -// STATIC: "WORLDVERTEXTRANSITION" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); -const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cNormalMapTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); - -static const int g_FogType = DOWATERFOG; - -struct VS_INPUT -{ - // If this is float4, and the input is float3, the w component default to one. - float4 vPos : POSITION; - float3 vNormal : NORMAL; - float2 vBaseTexCoord : TEXCOORD0; -#if NORMALMAP - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; -#endif - float4 vColor : COLOR0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float4 spotTexCoord : TEXCOORD0; - float2 baseTexCoord : TEXCOORD1; -#if NORMALMAP - float3 tangentPosToLightVector : TEXCOORD2; - float2 normalMapTexCoord : TEXCOORD3; -#else - float3 worldPosToLightVector : TEXCOORD2; - float3 normal : TEXCOORD3; -#endif - float4 vertAtten : COLOR0; -}; - -float RemapValClamped( float val, float A, float B ) -{ - float cVal = (val - A) / (B - A); - cVal = saturate( cVal ); - return cVal; -} - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - float4 projPos; - float3 worldPos; - float3 worldNormal; - float3 eyeVector; - - projPos = mul( v.vPos, cModelViewProj ); - o.projPos = projPos; - - worldPos = mul( v.vPos, cModel[0] ); - worldNormal = mul( v.vNormal, ( float3x3 )cModel[0] ); - -#if NORMALMAP - float3 worldTangentS = mul( v.vTangentS, cModel[0] ); - float3 worldTangentT = mul( v.vTangentT, cModel[0] ); -#endif - -#if !defined( _X360 ) - o.fog = CalcFog( worldPos, projPos, g_FogType ); -#endif - - o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; - o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; - - float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); - o.spotTexCoord = spotTexCoord.xyzw; - - float3 worldPosToLightVector = g_FlashlightPos - worldPos; -#if NORMALMAP - o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[0] ) + cNormalMapTexCoordTransform[0].w; - o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[1] ) + cNormalMapTexCoordTransform[1].w; - - o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); - o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); - o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); -#else - o.worldPosToLightVector = worldPosToLightVector; - o.normal = worldNormal; -#endif - - float3 delta = worldPosToLightVector; - float distSquared = dot( delta, delta ); - float dist = sqrt( distSquared ); - float farZ = g_FlashlightAttenuationFactors.w; - float endFalloffFactor = RemapValClamped( dist, farZ, 0.6 * farZ ); - o.vertAtten.xyz = saturate( endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); - -#if WORLDVERTEXTRANSITION - o.vertAtten.w = 1 - v.vColor.w; -#else -#if VERTEXCOLOR - o.vertAtten.w = v.vColor.w; -#else - o.vertAtten.w = 1.0f; -#endif -#endif - - return o; -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc b/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc deleted file mode 100644 index 1a905733..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc +++ /dev/null @@ -1,184 +0,0 @@ -//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "NORMALMAP" "0..1" -// STATIC: "WORLDVERTEXTRANSITION" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "DETAIL" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); -const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); - -#if SEAMLESS -const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_6 ); -#define SEAMLESS_SCALE (SeamlessScale.x) -#endif -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cNormalMapOrDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); - -static const int g_FogType = DOWATERFOG; - -struct VS_INPUT -{ - float3 vPos : POSITION; //This HAS to match lightmappedgeneric_vs20.fxc's position input. Otherwise depth fighting errors occur on the 360 - float4 vNormal : NORMAL; - float2 vBaseTexCoord : TEXCOORD0; -#if WORLDVERTEXTRANSITION - float2 vLightmapTexCoord : TEXCOORD1; - float4 vColor : COLOR0; -#endif -#if NORMALMAP - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - - float4 spotTexCoord : TEXCOORD0; - -#if SEAMLESS - float3 SeamlessTexCoord : TEXCOORD1; -#else - float2 baseTexCoord : TEXCOORD1; -#endif - -#if NORMALMAP - float3 tangentPosToLightVector : TEXCOORD2; - float2 normalMapTexCoord : TEXCOORD3; -#else - float3 worldPosToLightVector : TEXCOORD2; - float3 normal : TEXCOORD3; -#endif - - float2 detailCoords : TEXCOORD4; - float4 worldPos_worldTransition : TEXCOORD5; - float3 vProjPos : TEXCOORD6; - float4 fogFactorW : TEXCOORD7; -}; - -float RemapValClamped( float val, float A, float B, float C, float D) -{ - float cVal = (val - A) / (B - A); - cVal = saturate( cVal ); - - return C + (D - C) * cVal; -} - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - float4 projPos; - float3 worldPos; - float3 worldNormal; - float3 eyeVector; - - //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360 - projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); - o.projPos = projPos; - o.vProjPos.xyz = projPos.xyw; - - worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); - worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); - - o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f ); - - o.fogFactorW = CalcFog( worldPos, projPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW.w; -#endif - -#if NORMALMAP - float3 worldTangentS = mul( v.vTangentS, cModel[0] ); - float3 worldTangentT = mul( v.vTangentT, cModel[0] ); -#endif -#if SEAMLESS - float3 vNormal=normalize( worldNormal ); - o.fogFactorW.xyz = vNormal * vNormal; // sums to 1. - o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; - - // Generate new tangent and binormal with seamless projection - #if NORMALMAP - // Brute-force for prototype - This must match the projection in the pixel shader! - //float3 vVecX = { 1.0f, 0.0f, 0.0f }; - //float3 vVecY = { 0.0f, 1.0f, 0.0f }; - //float3 vVecZ = { 0.0f, 0.0f, 1.0f }; - //worldTangentS.xyz = normalize( ( o.fogFactorW.x * vVecZ.xyz ) + ( o.fogFactorW.y * vVecX.xyz ) + ( o.fogFactorW.z * vVecX.xyz ) ); - //worldTangentT.xyz = normalize( ( o.fogFactorW.x * vVecY.xyz ) + ( o.fogFactorW.y * vVecZ.xyz ) + ( o.fogFactorW.z * vVecY.xyz ) ); - - // Optimized version - This must match the projection in the pixel shader! - worldTangentS.xyz = normalize( float3( o.fogFactorW.y + o.fogFactorW.z, 0.0f, o.fogFactorW.x ) ); - worldTangentT.xyz = normalize( float3( 0.0f, o.fogFactorW.x + o.fogFactorW.z, o.fogFactorW.y ) ); - #endif -#else -#if (SEAMLESS == 0 ) - o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; - o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; -#endif -#endif - - float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); - o.spotTexCoord = spotTexCoord.xyzw; - - float3 worldPosToLightVector = g_FlashlightPos - worldPos; -#if NORMALMAP - -#if (DETAIL == 0) - o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; - o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; -#else - -#if SEAMLESS - o.normalMapTexCoord = v.vBaseTexCoord; -#else - o.normalMapTexCoord = o.baseTexCoord; -#endif - -#endif - - o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); - o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); - o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); -#else - o.worldPosToLightVector = worldPosToLightVector; - o.normal = worldNormal; -#endif - -#if DETAIL - o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; - o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; -#else - o.detailCoords = float2(0,0); -#endif - - //float3 delta = worldPosToLightVector; - //float distSquared = dot( delta, delta ); - //float dist = sqrt( distSquared ); - //float farZ = g_FlashlightAttenuationFactors.w; - //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); - //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ); - //o.projPos_atten.w = saturate( o.projPos_atten.w ); - -#if WORLDVERTEXTRANSITION - o.worldPos_worldTransition.w = v.vColor.w; -#endif - - return o; -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_helper.cpp b/materialsystem/stdshaders/lightmappedgeneric_helper.cpp new file mode 100644 index 00000000..6f64a15d --- /dev/null +++ b/materialsystem/stdshaders/lightmappedgeneric_helper.cpp @@ -0,0 +1,1787 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//============================================================================= + +#include "lightmappedgeneric_dx9_helper.h" +#include "BaseVSShader.h" +#include "commandbuilder.h" +#include "cpp_shader_constant_register_map.h" +#include "convar.h" +#include "SDK_lightmappedgeneric_ps20b.inc" +#include "SDK_lightmappedgeneric_vs20.inc" +#include "SDK_lightmappedgeneric_ps30.inc" +#include "SDK_lightmappedgeneric_vs30.inc" + +#include "SDK_lightmappedgeneric_flashlight_vs20.inc" +#include "SDK_lightmappedgeneric_flashlight_vs30.inc" +#include "SDK_lightmappedgeneric_flashlight_ps20.inc" +#include "SDK_lightmappedgeneric_flashlight_ps20b.inc" +#include "SDK_lightmappedgeneric_flashlight_ps30.inc" + + +#include "tier0/memdbgon.h" + +ConVar mat_disable_lightwarp( "mat_disable_lightwarp", "0" ); +ConVar mat_disable_fancy_blending( "mat_disable_fancy_blending", "0" ); +ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +ConVar my_mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +ConVar mat_enable_lightmapped_phong( "mat_enable_lightmapped_phong", "1", FCVAR_ARCHIVE, "If 1, allow phong on world brushes. If 0, disallow. mat_force_lightmapped_phong does not work if this value is 0." ); +ConVar mat_force_lightmapped_phong( "mat_force_lightmapped_phong", "0", FCVAR_CHEAT, "Forces the use of phong on all LightmappedAdv textures, regardless of setting in VMT." ); +ConVar mat_force_lightmapped_phong_boost( "mat_force_lightmapped_phong_boost", "5.0", FCVAR_CHEAT ); +ConVar mat_force_lightmapped_phong_exp( "mat_force_lightmapped_phong_exp", "50.0", FCVAR_CHEAT ); + +class CLightmappedGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + bool m_bVertexShaderFastPath; + bool m_bPixelShaderFastPath; + bool m_bPixelShaderForceFastPathBecauseOutline; + bool m_bFullyOpaque; + bool m_bFullyOpaqueWithoutAlphaTest; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CLightmappedGeneric_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CLightmappedGeneric_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() && + !( params[info.m_nNoDiffuseBumpLighting]->IsDefined() && params[info.m_nNoDiffuseBumpLighting]->GetIntValue() ) ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + if( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() ) + { + if( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + if ( (mat_disable_lightwarp.GetBool() ) && + (info.m_nLightWarpTexture != -1) ) + { + params[info.m_nLightWarpTexture]->SetUndefined(); + } + if ( (mat_disable_fancy_blending.GetBool() ) && + (info.m_nBlendModulateTexture != -1) ) + { + params[info.m_nBlendModulateTexture]->SetUndefined(); + } + + if( !params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() ) + params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 ); + + if( !params[info.m_nSelfIllumTint]->IsDefined() ) + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nDetailScale]->IsDefined() ) + params[info.m_nDetailScale]->SetFloatValue( 4.0f ); + + if ( !params[info.m_nDetailTint]->IsDefined() ) + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f ); + + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nDetailTextureCombineMode, params, 0 ); + + if( !params[info.m_nFresnelReflection]->IsDefined() ) + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + + if( !params[info.m_nEnvmapMaskFrame]->IsDefined() ) + params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + + if( !params[info.m_nBumpFrame]->IsDefined() ) + params[info.m_nBumpFrame]->SetIntValue( 0 ); + + if( !params[info.m_nDetailFrame]->IsDefined() ) + params[info.m_nDetailFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if( params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + params[info.m_nEnvmapParallax]->SetUndefined(); +#endif + } + + if( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTextureNoEnvmap]->SetIntValue( 0 ); + } + if( !params[info.m_nBaseTexture2NoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTexture2NoEnvmap]->SetIntValue( 0 ); + } + + if( ( info.m_nSelfShadowedBumpFlag != -1 ) && + ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() ) + ) + { + params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 ); + } + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + if ( !params[info.m_nPhong]->IsDefined() || !mat_enable_lightmapped_phong.GetBool() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + if ( !params[info.m_nPhongBoost]->IsDefined() ) + { + params[info.m_nPhongBoost]->SetFloatValue( 1.0 ); + } + if ( !params[info.m_nPhongFresnelRanges]->IsDefined() ) + { + params[info.m_nPhongFresnelRanges]->SetVecValue( 0.0, 0.5, 1.0 ); + } + if ( !params[info.m_nPhongExponent]->IsDefined() ) + { + params[info.m_nPhongExponent]->SetFloatValue( 5.0 ); + } + + if ( params[info.m_nPhong]->GetIntValue() && mat_enable_lightmapped_phong.GetBool() ) + { + if ( pShader->CanUseEditorMaterials() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + else if ( !params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ) + { + Warning( "Warning! material %s: $envmapmasktransform and $phong are mutually exclusive. Disabling phong..\n", pMaterialName ); + params[info.m_nPhong]->SetIntValue( 0 ); + } + } + else if ( mat_force_lightmapped_phong.GetBool() && mat_enable_lightmapped_phong.GetBool() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ) + { + params[info.m_nPhong]->SetIntValue( 1 ); + params[info.m_nPhongBoost]->SetFloatValue( mat_force_lightmapped_phong_boost.GetFloat() ); + params[info.m_nPhongFresnelRanges]->SetVecValue( 0.0, 0.5, 1.0 ); + params[info.m_nPhongExponent]->SetFloatValue( mat_force_lightmapped_phong_exp.GetFloat() ); + } +} + +#ifdef MAPBASE +// Created for the missing cubemap solution below +void LoadLightmappedGenericEnvmap( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap ); + } +} +#endif + +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap2 ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpMask]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpMask ); + } + + if (params[info.m_nBaseTexture]->IsDefined()) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if (!params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[info.m_nBaseTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2, TEXTUREFLAGS_SRGB ); + } + + if (params[info.m_nLightWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nLightWarpTexture ); + } + + if ((info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsDefined()) ) + { + pShader->LoadTexture( info.m_nBlendModulateTexture ); + } + + if (params[info.m_nDetail]->IsDefined()) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + + pShader->LoadTexture( info.m_nDetail, nDetailBlendMode != 0 ? TEXTUREFLAGS_SRGB : 0 ); + } + + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if (params[info.m_nEnvmap]->IsDefined()) + { +#ifdef MAPBASE + LoadLightmappedGenericEnvmap( pShader, params, info ); + + if (mat_specular_disable_on_missing.GetBool()) + { + // Revert to defaultcubemap when the envmap texture is missing + // (should be equivalent to toolsblack in Mapbase) + if (params[info.m_nEnvmap]->GetTextureValue()->IsError()) + { + params[info.m_nEnvmap]->SetStringValue( "engine/defaultcubemap" ); + LoadLightmappedGenericEnvmap( pShader, params, info ); + } + } +#else + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap ); + } +#endif + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if ( params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + } + else + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); +} + +void DrawLightmappedGenericFlashlight_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, LightmappedGenericFlashlight_DX9_Vars_t &vars ) +{ + Assert( vars.m_bLightmappedGeneric ); + + bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); + bool bSeamless = vars.m_fSeamlessScale != 0.0; + bool bDetail = (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1); + bool bPhong = (vars.m_nPhong != -1) && (params[vars.m_nPhong]->GetIntValue() != 0); +#ifdef MAPBASE + bool hasBaseTextureTransform2 = (vars.m_nBaseTexture2TransformVar != -1) && params[vars.m_nBaseTexture2TransformVar]->IsDefined() && params[vars.m_nBaseTexture2Var]->IsTexture(); + bool bHasBlendModulateTexture = + (vars.m_nBlendModulateTexture != -1) && + (params[vars.m_nBlendModulateTexture]->IsTexture()); +#endif + + int nDetailBlendMode = 0; + if ( bDetail ) + { + nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + } + + PhongMaskVariant_t nPhongMaskVariant = PHONGMASK_NONE; + if ( bPhong ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + nPhongMaskVariant = PHONGMASK_BASEALPHA; + } + else if ( IS_FLAG_SET(MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK) ) + { + nPhongMaskVariant = PHONGMASK_NORMALALPHA; + } + else if ( params[vars.m_nPhongMask]->IsDefined() ) + { + nPhongMaskVariant = PHONGMASK_STANDALONE; + } + } + + if( pShaderShadow ) + { + pShader->SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // Alpha blend + pShader->SetAdditiveBlendingShadowState( BASETEXTURE, true ); + + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); + } + + // Spot sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // Base sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Normalizing cubemap sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // Normalizing cubemap sampler2 or normal map sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + // RandomRotation sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + // Flashlight depth sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + + if( vars.m_bWorldVertexTransition ) + { + // $basetexture2 + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bBump2 ) + { + // Normalmap2 sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + if( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + if( nPhongMaskVariant == PHONGMASK_STANDALONE ) + { + // phong mask sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); + } + +#ifdef MAPBASE + if ( bHasBlendModulateTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, false ); + } +#endif + + pShaderShadow->EnableSRGBWrite( true ); + + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); + SET_STATIC_VERTEX_SHADER_COMBO( NORMALMAP, vars.m_bBump ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_VERTEX_SHADER_COMBO( DETAIL, bDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( PHONG, bPhong ); +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs30 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); + SET_STATIC_VERTEX_SHADER_COMBO( NORMALMAP, vars.m_bBump ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_VERTEX_SHADER_COMBO( DETAIL, bDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( PHONG, bPhong ); +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs20 ); + } + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + if( vars.m_bBump ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + int numTexCoords = 1; + if( vars.m_bWorldVertexTransition ) + { + flags |= VERTEX_COLOR; + numTexCoords = 2; // need lightmap texcoords to get alpha. + } + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + int nBumpMapVariant = 0; + if ( vars.m_bBump ) + { + nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1; + } + + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); +#endif + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, g_pHardwareConfig->GetShadowFilterMode() ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONG, bPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGMASK, nPhongMaskVariant ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps30 ); + } + else if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); +#endif + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, g_pHardwareConfig->GetShadowFilterMode() ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONG, bPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGMASK, nPhongMaskVariant ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); +#endif + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20 ); + } + pShader->FogToBlack(); + } + else + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + if ( pFlashlightDepthTexture == NULL ) + { + const int iFlashlightShadowIndex = ( flashlightState.m_nShadowQuality >> 16 ) - 1; + + if ( iFlashlightShadowIndex >= 0 + && iFlashlightShadowIndex <= ( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST - INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST ) ) + { + pFlashlightDepthTexture = (ITexture*)pShaderAPI->GetIntRenderingParameter( INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + iFlashlightShadowIndex ); + } + } + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + + if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) + { + pShader->BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + if( vars.m_bWorldVertexTransition ) + { + Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); + pShader->BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + if( vars.m_bBump ) + { + pShader->BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if( bDetail ) + { + pShader->BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); + } + + if( bBump2 ) + { + pShader->BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); + } + + if( nPhongMaskVariant == PHONGMASK_STANDALONE ) + { + pShader->BindTexture( SHADER_SAMPLER9, vars.m_nPhongMask, vars.m_nPhongMaskFrame ); + } + +#ifdef MAPBASE + if ( bHasBlendModulateTexture ) + { + pShader->BindTexture( SHADER_SAMPLER10, vars.m_nBlendModulateTexture ); + } +#endif + + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs30 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_flashlight_vs20 ); + } + + if ( bSeamless ) + { + float const0[4]={ vars.m_fSeamlessScale,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); + } + + if ( bDetail ) + { + float vDetailConstants[4] = {1,1,1,1}; + + if ( vars.m_nDetailTint != -1 ) + { + params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); + } + + if ( vars.m_nDetailTextureBlendFactor != -1 ) + { + vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); + } + + if ( bPhong ) + { + float vEyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + vEyePos[3] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, vEyePos ); + } + +#ifdef MAPBASE + else if ( hasBaseTextureTransform2 ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, vars.m_nBaseTexture2TransformVar ); + } +#endif + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = params[vars.m_nPhongExponent]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps30 ); + } + else if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_flashlight_ps20 ); + } + + float atten[4]; // Set the flashlight attenuation factors + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + /*atten[3] = flashlightState.m_FarZAtten;*/ + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + float lightPos[4]; + lightPos[0] = flashlightState.m_vecLightOrigin[0]; + lightPos[1] = flashlightState.m_vecLightOrigin[1]; + lightPos[2] = flashlightState.m_vecLightOrigin[2]; + lightPos[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 1, lightPos, 1 ); + + float specParams[4]; + params[vars.m_nPhongFresnelRanges]->GetVecValue( specParams, 3 ); + specParams[3] = params[vars.m_nPhongBoost]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, specParams, 1 ); + + pShader->SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); + } + pShader->Draw(); +} + +void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar** params, bool hasFlashlight, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr + ) +{ + CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *> ( *pContextDataPtr ); + if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged || hasFlashlight ) + { + bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); + int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360()); //dest alpha is free for special use + bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; + bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow; + + if ( ! pContextData ) // make sure allocated + { + pContextData = new CLightmappedGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + + bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && ( !g_pHardwareConfig->PreferReducedFillrate() ); + bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); + bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); +#ifdef MAPBASE + bool hasBaseTextureTransform2 = (info.m_nBaseTexture2Transform != -1) && params[info.m_nBaseTexture2Transform]->IsDefined() && hasBaseTexture2; +#endif + bool hasLightWarpTexture = params[info.m_nLightWarpTexture]->IsTexture(); + bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture(); + bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool bHasBlendModulateTexture = + (info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsTexture() ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + bool hasParallaxCorrection = params[info.m_nEnvmapParallax]->GetIntValue() > 0; +#endif + + if ( hasFlashlight && !IsX360() ) + { + // !!speed!! do this in the caller so we don't build struct every time + LightmappedGenericFlashlight_DX9_Vars_t vars; + vars.m_bBump = hasBump; + vars.m_nBumpmapVar = info.m_nBumpmap; + vars.m_nBumpmapFrame = info.m_nBumpFrame; + vars.m_nBumpTransform = info.m_nBumpTransform; + vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; + vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; + vars.m_bLightmappedGeneric = true; + vars.m_bWorldVertexTransition = hasBaseTexture2; + vars.m_nBaseTexture2Var = info.m_nBaseTexture2; + vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; +#ifdef MAPBASE + vars.m_nBaseTexture2TransformVar = info.m_nBaseTexture2Transform; +#endif + vars.m_nBumpmap2Var = info.m_nBumpmap2; + vars.m_nBumpmap2Frame = info.m_nBumpFrame2; + vars.m_nBump2Transform = info.m_nBumpTransform2; + vars.m_nAlphaTestReference = info.m_nAlphaTestReference; + vars.m_bSSBump = hasSSBump; + vars.m_nDetailVar = info.m_nDetail; + vars.m_nDetailScale = info.m_nDetailScale; + vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; + vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; + vars.m_nDetailTint = info.m_nDetailTint; + + if ( ( info.m_nSeamlessMappingScale != -1 ) ) + vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + else + vars.m_fSeamlessScale = 0.0; + + vars.m_nPhong = info.m_nPhong; + vars.m_nPhongBoost = info.m_nPhongBoost; + vars.m_nPhongFresnelRanges = info.m_nPhongFresnelRanges; + vars.m_nPhongExponent = info.m_nPhongExponent; + vars.m_nPhongMask = info.m_nEnvmapMask; + vars.m_nPhongMaskFrame = info.m_nEnvmapMaskFrame; + +#ifdef MAPBASE + vars.m_nBlendModulateTexture = info.m_nBlendModulateTexture; +#endif + + DrawLightmappedGenericFlashlight_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, vars ); + return; + } + + pContextData->m_bFullyOpaque = bFullyOpaque; + pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( hasBump && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpTex = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( hasBump2 ) // Check encoding of secondary normal if there is oneg + { + ITexture *pBumpTex2 = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("LightmappedGeneric: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + const bool hasBumpMask = hasBump && hasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && + !hasDetailTexture && !hasBaseTexture2 && (params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0); + + int nNormalMaskDecodeMode = 0; + if ( hasBumpMask && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpMaskTex = params[info.m_nBumpMask]->GetTextureValue(); + if ( pBumpMaskTex ) + { + nNormalMaskDecodeMode = pBumpMaskTex->GetNormalDecodeMode(); + } + } + + const bool bHasOutline = false; //IsBoolSet( info.m_nOutline, params ); + pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; + const bool bHasSoftEdges = false; //IsBoolSet( info.m_nSoftEdges, params ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + + + float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasDiffuseBumpmap = hasBump && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + + if ( bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + + if( !hasBaseTexture ) + { + if( hasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( bSeamlessMapping ) + { + staticCmdsBuf.SetVertexShaderConstant4( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, + params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 ); + } + //staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 ); + staticCmdsBuf.SetPixelShaderFogParams( 11 ); + staticCmdsBuf.End(); + // now, copy buf + pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + if ( pShaderShadow ) + { + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); + + unsigned int flags = VERTEX_POSITION; + + // base texture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( hasLightWarpTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); + } + if ( bHasBlendModulateTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); + } + + if ( hasBaseTexture2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + } +// if( hasLightmap ) + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + else + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + } + + if( hasEnvmap || ( IsX360() && hasFlashlight ) ) + { + if( hasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + } + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + + int nDetailBlendMode = 0; + if ( hasDetailTexture ) + { + nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); + ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue(); + if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP ) + { + if ( hasBump ) + nDetailBlendMode = 10; // ssbump + else + nDetailBlendMode = 11; // ssbump_nobump + } + } + + if( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); + bool bSRGBState = ( nDetailBlendMode == 1 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, bSRGBState ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Normal map alpha, in the compressed normal case + } + } + if( hasBump2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Secondary normal alpha, in the compressed normal case + } + } + if( hasBumpMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal mask alpha, in the compressed normal case + } + } + if( hasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + + if( hasFlashlight && IsX360() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); + } + else if ( !hasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER14, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); + } + + if( hasVertexColor || hasBaseTexture2 || hasBump2 ) + { + flags |= VERTEX_COLOR; + } + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if( hasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + + int bumpmap_variant=(hasSSBump) ? 2 : hasBump; + bool bMaskedBlending=( (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() != 0) ); + + bool bReliefMapping = false; //( bumpmap_variant == 2 ) && ( ! bSeamlessMapping ); + + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, 1 ); // // GSTRINGMIGRATION params[info.m_nEnvmap]->IsTexture() ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, false );//bReliefMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, 1 ); // // GSTRINGMIGRATION params[info.m_nEnvmap]->IsTexture() ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, false );//bReliefMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs20 ); + } + + + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + //SET_STATIC_PIXEL_SHADER_COMBO( RELIEF_MAPPING, bReliefMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + //SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + //SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, (int) nNormalMaskDecodeMode ); +#ifdef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps enabled for 2_0b and onwards + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection ); +#else + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, false ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps30 ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + SET_STATIC_PIXEL_SHADER_COMBO( RELIEF_MAPPING, bReliefMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + //SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + //SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, (int) nNormalMaskDecodeMode ); +#ifdef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURETRANSFORM2, hasBaseTextureTransform2 ); +#endif +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps enabled for 2_0b and onwards + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection ); +#else + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, false ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20b ); + } + //else + //{ + // DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20 ); + // SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + // SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + // SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + // SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + // SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + // SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + // SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + // SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + // SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + // SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + // SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + // SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + // SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + // SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + // SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!) + // SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0 + // SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20 ); + //} + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and writing depth to dest alpha + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + pShaderShadow->EnableSRGBWrite( true ); + + pShader->DefaultFog(); + + + } // end shadow state + } // end shadow || regen display list + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + bool bHasBlendMaskTransform= ( + (info.m_nBlendMaskTransform != -1) && + (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() ) && + ( ! (params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + bool bHasTextureTransform = + !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && +#ifdef MAPBASE + (!hasBaseTextureTransform2 || params[info.m_nBaseTexture2Transform]->MatrixIsIdentity()) && +#endif + params[info.m_nBumpTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform2]->MatrixIsIdentity() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); + + bHasTextureTransform |= bHasBlendMaskTransform; + + pContextData->m_bVertexShaderFastPath = !bHasTextureTransform; + + if( params[info.m_nDetail]->IsTexture() ) + { + pContextData->m_bVertexShaderFastPath = false; + } + if (bHasBlendMaskTransform) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, info.m_nBlendMaskTransform ); + } + + if ( ! pContextData->m_bVertexShaderFastPath ) + { + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + if (!bSeamlessMapping ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + // If we have a detail texture, then the bump texcoords are the same as the base texcoords. + if( hasBump && !hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); + } + else if ( hasBump2 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 ); + } +#ifdef MAPBASE + if ( hasBaseTextureTransform2 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, info.m_nBaseTexture2Transform ); + } +#endif + } + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint ); + // set up shader modulation color + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + pShader->ComputeModulationColor( color ); + float flLScale = pShaderAPI->GetLightMapScaleFactor(); + color[0] *= flLScale; + color[1] *= flLScale; + color[2] *= flLScale; + + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); + + if ( hasDetailTexture ) + { + float detailTintAndBlend[4] = {1, 1, 1, 1}; + + if ( info.m_nDetailTint != -1 ) + { + params[info.m_nDetailTint]->GetVecValue( detailTintAndBlend, 3 ); + } + + detailTintAndBlend[3] = fDetailBlendFactor; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTintAndBlend ); + } + + float envmapTintVal[4]; + float selfIllumTintVal[4]; + params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 ); + params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); + float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + +#ifdef MAPBASE + bool bEditorBlend = (hasBaseTexture2 && pShader->UsingEditor( params )); // Mapbase - For fixing editor blending +#endif + + pContextData->m_bPixelShaderFastPath = true; + bool bUsingContrast = hasEnvmap && ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) && (envmapSaturation != 1.0f); + bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f); + bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f); + if ( bUsingContrast || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) + { + pContextData->m_bPixelShaderFastPath = false; + } + if( !pContextData->m_bPixelShaderFastPath ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() ); + float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); + // [ 0, 0, 1-R(0), R(0) ] + pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel ); + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() ); + } + else + { + if ( bHasOutline ) + { + float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), + GetFloatParam( info.m_nOutlineStart1, params ), + GetFloatParam( info.m_nOutlineEnd0, params ), + GetFloatParam( info.m_nOutlineEnd1, params ), + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ) }; + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, flOutlineParms, 2 ); + } + + if ( bHasSoftEdges ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( + 4, GetFloatParam( info.m_nEdgeSoftnessStart, params ), + GetFloatParam( info.m_nEdgeSoftnessEnd, params ), + 0,0 ); + } + } + // texture binds + if( hasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + // handle mat_fullbright 2 + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + // BASE TEXTURE + if( hasSelfIllum ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // BASE TEXTURE 2 + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); + } + + // DETAIL TEXTURE + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); + } + + // disable color modulation + float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + // turn off environment mapping + envmapTintVal[0] = 0.0f; + envmapTintVal[1] = 0.0f; + envmapTintVal[2] = 0.0f; + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); + } + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nDetail, info.m_nDetailFrame ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER4, SHADER_SAMPLER9, info.m_nBumpmap, info.m_nBumpFrame ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBump2 ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER5, SHADER_SAMPLER10, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBumpMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + Assert(0); + //pContextData->m_SemiStaticCmdsOut.BindTexture( SHADER_SAMPLER8, SHADER_SAMPLER11, info.m_nBumpMask ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBumpMask, -1 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, TEXTURE_NORMALMAP_FLAT ); + } + } + + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( hasLightWarpTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nLightWarpTexture, -1 ); + } + + if ( bHasBlendModulateTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 ); + } + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + if (hasParallaxCorrection) + { + float envMapOrigin[4] = {0,0,0,0}; + params[info.m_nEnvmapOrigin]->GetVecValue( envMapOrigin, 3 ); +#ifdef MAPBASE + envMapOrigin[4] = bEditorBlend ? 1.0f : 0.0f; +#endif + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, envMapOrigin ); + + float* vecs[3]; + vecs[0] = const_cast(params[info.m_nEnvmapParallaxObb1]->GetVecValue()); + vecs[1] = const_cast(params[info.m_nEnvmapParallaxObb2]->GetVecValue()); + vecs[2] = const_cast(params[info.m_nEnvmapParallaxObb3]->GetVecValue()); + float matrix[4][4]; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + matrix[i][j] = vecs[i][j]; + } + } + matrix[3][0] = matrix[3][1] = matrix[3][2] = 0; + matrix[3][3] = 1; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 22, &matrix[0][0], 4 ); + } +#endif + +#ifdef MAPBASE + // Hammer apparently has a bug that causes the vertex blend to get swapped. + // Hammer uses a special internal shader to nullify this, but it doesn't work with custom shaders. + // Downfall got around this by swapping around the base textures in the DLL code when drawn by the editor. + // Doing it here in the shader itself allows us to retain other properties, like FANCY_BLENDING. + else + { + // TODO: This is inefficient use of a constant; Something should be done about this in the future + static const float editorBlend[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + static const float regularBlend[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, (bEditorBlend ? editorBlend : regularBlend), 1 ); + /* + if (bEditorBlend) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 35, 1.0f ); + } + else + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 35, 0.0f ); + } + */ + } +#endif + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + if( hasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); + + bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; + + if( nFixedLightingMode != 0 ) + { + if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) + nFixedLightingMode = 0; + else + bVertexShaderFastPath = false; + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + (nFixedLightingMode)?1:0 + ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, sdk_lightmappedgeneric_vs30 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + (nFixedLightingMode)?1:0 + ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, sdk_lightmappedgeneric_vs20 ); + } + + + bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; + if( nFixedLightingMode !=0 ) + { + bPixelShaderFastPath = false; + } + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( pContextData->m_bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + if ( g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_lightmappedgeneric_ps30 ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_lightmappedgeneric_ps20b ); + } + //else + //{ + // DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20 ); + // SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath ); + // SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + // SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + // + // // Don't write fog to alpha if we're using translucency + // SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + // SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + // + // SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_lightmappedgeneric_ps20 ); + //} + + if( hasFlashlight && IsX360() ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + float atten[4], pos[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + DynamicCmdsOut.SetPixelShaderConstant( 13, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + DynamicCmdsOut.SetPixelShaderConstant( 14, pos, 1 ); + + pShader->BindTexture( SHADER_SAMPLER13, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER14, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER15, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + DynamicCmdsOut.SetPixelShaderConstant( 19, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + DynamicCmdsOut.SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + } + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + eyePos[3] = pShaderAPI->GetFloatRenderingParameter( FLOAT_RENDERPARM_MINIMUMLIGHTING ); + DynamicCmdsOut.SetPixelShaderConstant( 10, eyePos ); + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + + if( IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) + { + //Alpha testing makes it so we can't write to dest alpha + //Writing to depth makes it so later polygons can't write to dest alpha either + //This leads to situations with garbage in dest alpha. + + //Fix it now by converting depth to dest alpha for any pixels that just wrote. + pShader->DrawEqualDepthToDestAlpha(); + } +} + +void DrawLightmappedGeneric_DX9(CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool hasFlashlight = pShader->UsingFlashlight( params ); + + DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); + + //ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" ); + // + //if ( !IsX360() && !r_flashlight_version2.GetInt() ) + //{ + // DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); + // return; + //} + // + //DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); +} diff --git a/materialsystem/stdshaders/lightmappedgeneric_helper.h b/materialsystem/stdshaders/lightmappedgeneric_helper.h new file mode 100644 index 00000000..3e702929 --- /dev/null +++ b/materialsystem/stdshaders/lightmappedgeneric_helper.h @@ -0,0 +1,148 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef LIGHTMAPPEDGENERIC_DX9_HELPER_H +#define LIGHTMAPPEDGENERIC_DX9_HELPER_H + +#include +#include "basevsshader.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct LightmappedGeneric_DX9_Vars_t +{ + LightmappedGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(LightmappedGeneric_DX9_Vars_t) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + + int m_nAlpha2; // Hack for DoD srgb blend issues on overlays + + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nFresnelReflection; + int m_nNoDiffuseBumpLighting; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpTransform2; + int m_nBumpMask; + int m_nBaseTexture2; + int m_nBaseTexture2Frame; +#ifdef MAPBASE + int m_nBaseTexture2Transform; +#endif + int m_nBaseTextureNoEnvmap; + int m_nBaseTexture2NoEnvmap; + int m_nDetailAlphaMaskBaseTexture; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nLightWarpTexture; + int m_nBlendModulateTexture; + int m_nMaskedBlending; + int m_nBlendMaskTransform; + int m_nSelfShadowedBumpFlag; + int m_nSeamlessMappingScale; + int m_nAlphaTestReference; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + + int m_nPhong; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nPhongExponent; + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + int m_nEnvmapParallax; // Needed for editor + int m_nEnvmapParallaxObb1; + int m_nEnvmapParallaxObb2; + int m_nEnvmapParallaxObb3; + int m_nEnvmapOrigin; +#endif +}; + + +enum PhongMaskVariant_t +{ + PHONGMASK_NONE, + PHONGMASK_BASEALPHA, + PHONGMASK_NORMALALPHA, + PHONGMASK_STANDALONE, +}; + +struct LightmappedGenericFlashlight_DX9_Vars_t : public CBaseVSShader::DrawFlashlight_dx90_Vars_t +{ + LightmappedGenericFlashlight_DX9_Vars_t() + : m_nPhong( -1 ) + , m_nPhongBoost( -1 ) + , m_nPhongFresnelRanges( -1 ) + , m_nPhongExponent( -1 ) + , m_nPhongMask( -1 ) + , m_nPhongMaskFrame( -1 ) + { + } + int m_nPhong; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nPhongExponent; + int m_nPhongMask; + int m_nPhongMaskFrame; + +#ifdef MAPBASE + // Fix for displacements not showing $blendmodulatetexture under a flashlight + int m_nBlendModulateTexture; +#endif +}; + + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ); +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ); +void DrawLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr ); + + +#endif // LIGHTMAPPEDGENERIC_DX9_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshaders/lightmappedgeneric_inc.vsh b/materialsystem/stdshaders/lightmappedgeneric_inc.vsh deleted file mode 100644 index a5d12a81..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_inc.vsh +++ /dev/null @@ -1,110 +0,0 @@ -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform -; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform -; $SHADER_SPECIFIC_CONST_4 = Modulation color -;------------------------------------------------------------------------------ - -sub LightmappedGeneric -{ - local( $detail ) = shift; - local( $envmap ) = shift; - local( $envmapcameraspace ) = shift; - local( $envmapsphere ) = shift; - local( $vertexcolor ) = shift; - - local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - - &AllocateRegister( \$projPos ); - - dp4 $projPos.x, $vPos, $cModelViewProj0 - dp4 $projPos.y, $vPos, $cModelViewProj1 - dp4 $projPos.z, $vPos, $cModelViewProj2 - dp4 $projPos.w, $vPos, $cModelViewProj3 - mov oPos, $projPos - - &AllocateRegister( \$worldPos ); - - if( $DOWATERFOG == 1 ) - { - ; Get the worldpos z component only since that's all we need for height fog - dp4 $worldPos.z, $vPos, $cModel2 - } - &CalcFog( $worldPos, $projPos ); - &FreeRegister( \$projPos ); - - ;------------------------------------------------------------------------------ - ; Texture coordinates - ;------------------------------------------------------------------------------ - ; base texcoords - dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 - dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - ; lightmap texcoords - mov oT1, $vTexCoord1 - - if( $envmap ) - { - &AllocateRegister( \$worldNormal ); - - ; Transform the position + normal to world space - dp4 $worldPos.x, $vPos, $cModel0 - dp4 $worldPos.y, $vPos, $cModel1 - if( $DOWATERFOG ne 1 ) - { - dp4 $worldPos.z, $vPos, $cModel2 - } - - dp3 $worldNormal.x, $vNormal, $cModel0 - dp3 $worldNormal.y, $vNormal, $cModel1 - dp3 $worldNormal.z, $vNormal, $cModel2 - - if( $envmapcameraspace ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - ; transform reflection vector into view space - dp3 oT2.x, $reflectionVector, $cViewModel0 - dp3 oT2.y, $reflectionVector, $cViewModel1 - dp3 oT2.z, $reflectionVector, $cViewModel2 - &FreeRegister( \$reflectionVector ); - } - elsif( $envmapsphere ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - &ComputeSphereMapTexCoords( $reflectionVector, "oT2" ); - &FreeRegister( \$reflectionVector ); - } - else - { - &ComputeReflectionVector( $worldPos, $worldNormal, "oT2" ); - } - ; envmap mask - dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 ; FIXME - dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 ; FIXME - -# &FreeRegister( \$worldPos ); - &FreeRegister( \$worldNormal ); - } - - &FreeRegister( \$worldPos ); # garymcthack - - if( $detail ) - { - dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 ; FIXME - dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 ; FIXME - } - - if( $vertexcolor ) - { - ; Modulation color - mul oD0, $vColor, $cModulationColor - } - else - { - ; Modulation color - mov oD0, $cModulationColor - } -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc b/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc deleted file mode 100644 index 1dbb8b2f..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc +++ /dev/null @@ -1,12 +0,0 @@ -sampler TextureSampler : register( s1 ); - -struct PS_INPUT -{ - float4 vColor0 : COLOR0; - float2 vTexCoord1 : TEXCOORD1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - return tex2D( TextureSampler, i.vTexCoord1 ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc b/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc deleted file mode 100644 index afee6c9c..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc +++ /dev/null @@ -1,51 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vTexCoord1 : TEXCOORD1; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - - float4 vDiffuse : COLOR0; - - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - worldPos = mul4x3( v.vPos, cModel[0] ); - - o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - - o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - // YUCK! This is to make texcoords continuous for mat_softwaretl - o.vTexCoord0 = 0.0f; - o.vTexCoord1 = v.vTexCoord1; - - o.vDiffuse = 1.0f; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh b/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh deleted file mode 100644 index 980269a1..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh +++ /dev/null @@ -1,22 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0, t0, v0 ; base times vertex color (with alpha) -mul r1, t2, t3 ; envmap * envmapmask -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh b/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh deleted file mode 100644 index 47902397..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh +++ /dev/null @@ -1,24 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 - -; Blend between grey and lightmap color based on total alpha - -def c0 0.5f 0.5f 0.5f 1.0f - -mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap -+ mul r1.a, t0, v0 ; base times vertex alpha -; GR - workaround for const/lerp issues -mul r0.rgb, c1, t0 ; Self illum * tint -+mul_sat r0.a, c1, t0 -lrp r1.rgb, t0.a, r1, r0 ; Blend between self-illum + lightmap -lrp r0, r1.a, r1, c0 ; interpolate between grey + color diff --git a/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh b/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh deleted file mode 100644 index 8cc6b4cc..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh +++ /dev/null @@ -1,20 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 -tex t1 - -; Blend between grey and lightmap color based on total alpha - -def c2, 0.5f, 0.5f, 0.5f, 1.0f - -mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap -+ mov r1.a, v0 ; vertex alpha -lrp r0, r1.a, r1, c2 ; interpolate between grey + color diff --git a/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc b/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc deleted file mode 100644 index d5be9e5f..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc +++ /dev/null @@ -1,122 +0,0 @@ -// STATIC: "BASETEXTURE" "0..1" -// STATIC: "ENVMAP" "0..1" -// STATIC: "ENVMAPMASK" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "BASEALPHAENVMAPMASK" "0..1" - -// SKIP: !$ENVMAP && ( $BASEALPHAENVMAPMASK || $ENVMAPMASK ) -// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK -// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK -// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK -// SKIP: $SELFILLUM && $BASEALPHAENVMAPMASK -// SKIP: !$BASETEXTURE && $SELFILLUM - -const float3 g_OverbrightFactor : register( c0 ); -const float3 g_SelfIllumTint : register( c1 ); -const float3 g_EnvmapTint : register( c2 ); - -sampler BaseTextureSampler : register( s0 ); -sampler LightmapSampler : register( s1 ); -sampler EnvmapSampler : register( s2 ); -sampler EnvmapMaskSampler : register( s3 ); - -//sampler DetailSampler : register( s3 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float2 lightmapTexCoord : TEXCOORD1; - float3 envmapTexCoord : TEXCOORD2; - float2 envmapMaskTexCoord : TEXCOORD3; - float4 vertexColor : COLOR0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - bool bBaseTexture = BASETEXTURE ? true : false; - bool bEnvmap = ENVMAP ? true : false; - bool bEnvmapMask = ENVMAPMASK ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; - -#if 1 - float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - if( bBaseTexture ) - { - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); - } - - float3 specularFactor = 1.0f; - - if( bEnvmapMask ) - { - specularFactor *= tex2D( EnvmapMaskSampler, i.envmapMaskTexCoord ).xyz; - } - if( bBaseAlphaEnvmapMask ) - { - specularFactor *= 1.0 - baseColor.a; // this blows! - } - - float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); - - float3 albedo = float3( 1.0f, 1.0f, 1.0f ); - float alpha = 1.0f; - if( bBaseTexture ) - { - albedo *= baseColor; - if( !bBaseAlphaEnvmapMask && !bSelfIllum ) - { - alpha *= baseColor.a; - } - } - - // The vertex color contains the modulation color + vertex color combined - albedo *= i.vertexColor; - alpha *= i.vertexColor.a; // not sure about this one - - float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; - - if( bSelfIllum ) - { - float3 selfIllumComponent = g_SelfIllumTint * albedo; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); - } - - float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); - - if( bEnvmap ) - { - specularLighting = tex2D( EnvmapSampler, i.envmapTexCoord ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint; - } - - float3 result = diffuseComponent + specularLighting; - return float4( result, alpha ); -#endif - -#if 0 - float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); - - float3 albedo = float3( 1.0f, 1.0f, 1.0f ); - float alpha = 1.0f; - albedo *= i.vertexColor; - alpha *= i.vertexColor.a; // not sure about this one - - float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; - float3 result = diffuseComponent; - return float4( result, alpha ); -#endif - -#if 0 - float4 result; - - result.rgb = tex2D( LightmapSampler, i.lightmapTexCoord ).rgb * i.vertexColor.rgb; - result.a = i.vertexColor.a; - result.rgb = ( result.rgb * g_OverbrightFactor ) * 2.0f; - return result; -#endif -} - - diff --git a/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h b/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h deleted file mode 100644 index ce01d524..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h +++ /dev/null @@ -1,761 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// SKIP: $BUMPMAP2 && $WARPLIGHTING -// SKIP: $WARPLIGHTING && $DETAILTEXTURE -// SKIP: $ENVMAPMASK && $BUMPMAP -// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK -// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK -// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK -// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM -// SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST -// SKIP: !$FASTPATH && $FASTPATHENVMAPTINT -// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP -// SKIP: !$BUMPMAP && $BUMPMAP2 -// SKIP: $ENVMAPMASK && $BUMPMAP2 -// SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) -// SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) -// SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP -// SKIP: $PARALLAXMAP && $DETAILTEXTURE -// SKIP: $SEAMLESS && $RELIEF_MAPPING -// SKIP: $SEAMLESS && $DETAILTEXTURE -// SKIP: $SEAMLESS && $MASKEDBLENDING -// SKIP: $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 ) -// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 1) -// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 2) -// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 1) -// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 2) -// NOSKIP: $FANCY_BLENDING && (!$FASTPATH) - -// 360 compiler craps out on some combo in this family. Content doesn't use blendmode 10 anyway -// SKIP: $FASTPATH && $PIXELFOGTYPE && $BASETEXTURE2 && $DETAILTEXTURE && $CUBEMAP && ($DETAIL_BLEND_MODE == 10 ) [XBOX] - -// debug crap: -// NOSKIP: $DETAILTEXTURE -// NOSKIP: $CUBEMAP -// NOSKIP: $ENVMAPMASK -// NOSKIP: $BASEALPHAENVMAPMASK -// NOSKIP: $SELFILLUM - -#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp - -#include "common_ps_fxc.h" -#include "common_flashlight_fxc.h" -#include "common_lightmappedgeneric_fxc.h" -#include "deferred_shadows.h" - -#if SEAMLESS -#define USE_FAST_PATH 1 -#else -#define USE_FAST_PATH FASTPATH -#endif - -const HALF4 g_EnvmapTint : register( c0 ); - -#if USE_FAST_PATH == 1 - -# if FASTPATHENVMAPCONTRAST == 0 -static const HALF3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f }; -# else -static const HALF3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f }; -# endif -static const HALF3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f }; -static const HALF g_FresnelReflection = 1.0f; -static const HALF g_OneMinusFresnelReflection = 0.0f; -static const HALF4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f }; -# if OUTLINE -const float4 g_OutlineParams : register( c2 ); -#define OUTLINE_MIN_VALUE0 g_OutlineParams.x -#define OUTLINE_MIN_VALUE1 g_OutlineParams.y -#define OUTLINE_MAX_VALUE0 g_OutlineParams.z -#define OUTLINE_MAX_VALUE1 g_OutlineParams.w - -const float4 g_OutlineColor : register( c3 ); -#define OUTLINE_COLOR g_OutlineColor - -# endif -# if SOFTEDGES -const float4 g_EdgeSoftnessParms : register( c4 ); -#define SOFT_MASK_MIN g_EdgeSoftnessParms.x -#define SOFT_MASK_MAX g_EdgeSoftnessParms.y -# endif -#else - -const HALF3 g_EnvmapContrast : register( c2 ); -const HALF3 g_EnvmapSaturation : register( c3 ); -const HALF4 g_FresnelReflectionReg : register( c4 ); -#define g_FresnelReflection g_FresnelReflectionReg.a -#define g_OneMinusFresnelReflection g_FresnelReflectionReg.b -const HALF4 g_SelfIllumTint : register( c7 ); -#endif - -const float4 g_DetailTint_and_BlendFactor : register( c8 ); -#define g_DetailTint (g_DetailTint_and_BlendFactor.rgb) -#define g_DetailBlendFactor (g_DetailTint_and_BlendFactor.w) - -const float4 g_EnvmapOrigin_and_Radius : register( c20 ); -#define g_EnvmapOrigin (g_EnvmapOrigin_and_Radius.xyz) -#define g_EnvmapRadius (g_EnvmapOrigin_and_Radius.w) -const float g_EnvmapSize : register( c21 ); - -const HALF3 g_EyePos : register( c10 ); -const HALF4 g_FogParams : register( c11 ); -const float4 g_TintValuesAndLightmapScale : register( c12 ); - -#define g_flAlpha2 g_TintValuesAndLightmapScale.w - -const float4 g_FlashlightAttenuationFactors : register( c13 ); -const float3 g_FlashlightPos : register( c14 ); -const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18 -const float4 g_ShadowTweaks : register( c19 ); - - -sampler BaseTextureSampler : register( s0 ); -sampler LightmapSampler : register( s1 ); -sampler EnvmapSampler : register( s2 ); -#if FANCY_BLENDING -sampler BlendModulationSampler : register( s3 ); -#endif - -#if DETAILTEXTURE -sampler DetailSampler : register( s12 ); -#endif - -sampler BumpmapSampler : register( s4 ); -#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA -sampler AlphaMapSampler : register( s9 ); // alpha -#else -#define AlphaMapSampler BumpmapSampler -#endif - -#if BUMPMAP2 == 1 -sampler BumpmapSampler2 : register( s5 ); -#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA -sampler AlphaMapSampler2 : register( s10 ); // alpha -#else -#define AlphaMapSampler2 BumpmapSampler2 -#endif -#else -sampler EnvmapMaskSampler : register( s5 ); -#endif - - -#if WARPLIGHTING -sampler WarpLightingSampler : register( s6 ); -#endif -sampler BaseTextureSampler2 : register( s7 ); - -#if BUMPMASK == 1 -sampler BumpMaskSampler : register( s8 ); -#if NORMALMASK_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA -sampler AlphaMaskSampler : register( s11 ); // alpha -#else -#define AlphaMaskSampler BumpMaskSampler -#endif -#endif - -#if defined( _X360 ) && FLASHLIGHT -sampler FlashlightSampler : register( s13 ); -sampler ShadowDepthSampler : register( s14 ); -sampler RandRotSampler : register( s15 ); -#endif - -#if CSM == 1 -sampler ShadowDepthSampler : register( s13 ); // CSM Depth - -const float4x4 g_CSMWorldToTexture : register( c22 ); -const float4 g_CascadeFwd : register( c26 ); -const float4 g_CascadeLight : register( c27 ); -const float4 g_CascadeAmbient : register( c1 ); -const float2 g_CascadeBias : register( c5 ); -const float2 g_CascadeResolution : register( c6 ); -const float4 g_CascadeSize : register( c9 ); -#endif - -#if CSM == 1 -float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) -{ - float2 rtSize = g_CascadeResolution; //float2(4096.0f * 4.0f, 4096.0f) * 2.0f; - float fEpsilonX = 1.0f / rtSize.y; - float fEpsilonY = 1.0f / rtSize.x; - - #if CSM_PERF < 1 - float3 cascade0 = float3( float2( ( vProjCoords.x / 4 ), vProjCoords.y ), vProjCoords.z ); - float3 cascade1 = float3( - float2( ( vProjCoords.x / 4 ) + ( g_CascadeSize.y - 2 - 1.0f / 8.0f - 0.5 ), vProjCoords.y + ( g_CascadeSize.y - 1 ) / 2 ) / - g_CascadeSize.y, - vProjCoords.z ); - #endif - #if CSM_PERF < 2 - float3 cascade2 = - float3( float2( ( vProjCoords.x / 4 ) + ( g_CascadeSize.z - 3 - 1.0f / 8.0f ), vProjCoords.y + ( g_CascadeSize.z - 1 ) / 2 ) / - g_CascadeSize.z, - vProjCoords.z ); - #endif - float3 cascade3 = - float3( float2( ( vProjCoords.x / 4 ) + ( g_CascadeSize.w - 4 - 1.0f / 8.0f ), vProjCoords.y + ( g_CascadeSize.w - 1 ) / 2 ) / - g_CascadeSize.w, - vProjCoords.z ); - - float projMask = 1.0f; - if ( vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100 ) - { - projMask = 0.0f; - } - - float4 vShadowTweaks = float4( fEpsilonX, fEpsilonY, 0.0f, 0.0f ); - #if CSM_PERF < 1 - float shadowProjDiff0 = 1; - float3 shadowMapCenter_objDepth0 = cascade0; - float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; - float objDepth0 = shadowMapCenter_objDepth0.z + g_CascadeBias.y * ( g_CascadeBias.x * LdN ) * shadowProjDiff0; - float3 vShadowPos0 = float3( shadowMapCenter0, objDepth0 ); - - float shadowProjDiff1 = g_CascadeSize.y; - float3 shadowMapCenter_objDepth1 = cascade1; - float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; - float objDepth1 = shadowMapCenter_objDepth1.z + g_CascadeBias.y * ( g_CascadeBias.x * LdN ) * shadowProjDiff1; - float3 vShadowPos1 = float3( shadowMapCenter1, objDepth1 ); - #endif - - #if CSM_PERF < 2 - float shadowProjDiff2 = g_CascadeSize.z; - float3 shadowMapCenter_objDepth2 = cascade2; - float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; - float objDepth2 = shadowMapCenter_objDepth2.z + g_CascadeBias.y * ( g_CascadeBias.x * LdN ) * shadowProjDiff2; - float3 vShadowPos2 = float3( shadowMapCenter2, objDepth2 ); - #endif - - float shadowProjDiff3 = g_CascadeSize.w; - float3 shadowMapCenter_objDepth3 = cascade3; - float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; - float objDepth3 = shadowMapCenter_objDepth3.z + g_CascadeBias.y * ( g_CascadeBias.x * LdN ) * shadowProjDiff3; - float3 vShadowPos3 = float3( shadowMapCenter3, objDepth3 ); - - /*float shadow0 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); - float shadow1 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow2 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); - float shadow3 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3);*/ - - float shadow3 = PCF( DepthSampler, rtSize, shadowMapCenter3.xy, objDepth3 ); - - #if CSM_PERF < 2 - float shadow2 = PCF( DepthSampler, rtSize, shadowMapCenter2.xy, objDepth2 ); - #else - float shadow2 = shadow3; - #endif - - #if CSM_PERF < 1 - float shadow1 = PCF( DepthSampler, rtSize, shadowMapCenter1.xy, objDepth1 ); - float shadow0 = PCF( DepthSampler, rtSize, shadowMapCenter0.xy, objDepth0 ); - #else - float shadow1 = shadow2; - float shadow0 = shadow2; - #endif - - /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); - float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); - float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); - float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); - - float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); - float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); - float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); - float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ - - float shadow01 = lerp( shadow0, shadow1, pow( saturate( vViewDepth / ( g_CascadeSize.x - 6 ) ), 20.0f ) ); - float shadow012 = lerp( shadow01, shadow2, pow( saturate( vViewDepth / ( g_CascadeSize.y * g_CascadeSize.x - 6 ) ), 20.0f ) ); - float shadow0123 = lerp( shadow012, shadow3, pow( saturate( vViewDepth / ( g_CascadeSize.z * g_CascadeSize.x - 6 ) ), 20.0f ) ); - - float shadow = shadow0123; - - if ( projMask == 1.0f ) - { - float smoothCSMMask = pow( saturate( vViewDepth / ( g_CascadeSize.w * g_CascadeSize.x - 100 ) ), 20.0f ); - float shadowFinal = lerp( shadow, 1.0f, smoothCSMMask ); - return shadowFinal; - } - else - { - return 1.0f; - } -} - -float3 DoCSMLight( in float3 worldPos, in float3 worldNormal, float3 albedo, float ViewZ ) -{ - float3 Out; - float LdN = max( 1.0f - saturate( dot( worldNormal, -g_CascadeFwd.xyz ) ), 0.01 ); - float4 flashlightSpacePosition = mul( float4( worldPos, 1.0f ), g_CSMWorldToTexture ); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flShadow = DoCSM( ShadowDepthSampler, vProjCoords, ViewZ, LdN ); - float diffuse = dot( worldNormal, -g_CascadeFwd.xyz ); - diffuse = saturate( diffuse ); - - Out = albedo * g_CascadeLight.rgb * diffuse * flShadow; - return Out; -} -#endif - - -struct PS_INPUT -{ -#if SEAMLESS - float3 SeamlessTexCoord : TEXCOORD0; // zy xz - float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask -#else - HALF2 baseTexCoord : TEXCOORD0; - // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. -#if ( RELIEF_MAPPING == 0 ) - HALF4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; -#endif -#endif -// CENTROID: TEXCOORD2 - HALF4 lightmapTexCoord1And2 : TEXCOORD2; -// CENTROID: TEXCOORD3 - HALF4 lightmapTexCoord3 : TEXCOORD3; - HALF4 worldPos_projPosZ : TEXCOORD4; - HALF3x3 tangentSpaceTranspose : TEXCOORD5; - // tangentSpaceTranspose : TEXCOORD6 - // tangentSpaceTranspose : TEXCOORD7 - HALF4 vertexColor : COLOR; - float4 vertexBlendX_fogFactorW : COLOR1; - - // Extra iterators on 360, used in flashlight combo -#if defined( _X360 ) && FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD8; - float4 vProjPos : TEXCOORD9; -#endif -}; - -struct PS_OUTPUT -{ - float4 MainOut : COLOR0; - float4 Normal : COLOR1; - float4 MRAO : COLOR2; - float4 Albedo : COLOR3; -}; - -#if LIGHTING_PREVIEW == 2 -LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR -#elif LIGHTING_PREVIEW == 1 -HALF4 main(PS_INPUT i) : COLOR -#else -PS_OUTPUT main( PS_INPUT i ) : COLOR -#endif -{ - bool bBaseTexture2 = BASETEXTURE2 ? true : false; - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bBumpmap = BUMPMAP ? true : false; - bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; - bool bCubemap = CUBEMAP ? true : false; - bool bEnvmapMask = ENVMAPMASK ? true : false; - bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; - bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false; - bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false; - - float4 baseColor = 0.0f; - float4 baseColor2 = 0.0f; - float4 vNormal = float4(0, 0, 1, 1); - float3 baseTexCoords = float3(0,0,0); - -#if SEAMLESS - baseTexCoords = i.SeamlessTexCoord.xyz; -#else - baseTexCoords.xy = i.baseTexCoord.xy; -#endif - - GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpmapSampler, bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask, - baseTexCoords, i.vertexColor.rgb, baseColor, baseColor2, vNormal ); - -#if BUMPMAP == 1 // not ssbump - vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // make signed if we're not ssbump -#endif - - PS_OUTPUT output = (PS_OUTPUT)0; - - HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); -#if LIGHTING_PREVIEW == 0 - if( bBumpmap && bDiffuseBumpmap ) - { - HALF2 bumpCoord1; - HALF2 bumpCoord2; - HALF2 bumpCoord3; - ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, - bumpCoord1, bumpCoord2, bumpCoord3 ); - - lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); - lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 ); - lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 ); - } - else - { - HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); - lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); - } -#endif - -#if RELIEF_MAPPING - // in the parallax case, all texcoords must be the same in order to free - // up an iterator for the tangent space view vector - HALF2 detailTexCoord = i.baseTexCoord.xy; - HALF2 bumpmapTexCoord = i.baseTexCoord.xy; - HALF2 envmapMaskTexCoord = i.baseTexCoord.xy; -#else - - #if ( DETAILTEXTURE == 1 ) - HALF2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; - HALF2 bumpmapTexCoord = i.baseTexCoord.xy; - #elif ( BUMPMASK == 1 ) - HALF2 detailTexCoord = 0.0f; - HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; - HALF2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; - #else - HALF2 detailTexCoord = 0.0f; - HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; - #endif - - HALF2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; -#endif // !RELIEF_MAPPING - - HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); -#if DETAILTEXTURE - -#if SHADER_MODEL_PS_2_0 - detailColor = tex2D( DetailSampler, detailTexCoord ); -#else - detailColor = float4( g_DetailTint, 1.0f ) * tex2D( DetailSampler, detailTexCoord ); -#endif - -#endif - -#if ( OUTLINE || SOFTEDGES ) - float distAlphaMask = baseColor.a; - -# if OUTLINE - if ( ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && - ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) - { - float oFactor=1.0; - if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) - { - oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); - } - else - { - oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); - } - baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); - } -# endif -# if SOFTEDGES - baseColor.a *= smoothstep( SOFT_MASK_MAX, SOFT_MASK_MIN, distAlphaMask ); -# else - baseColor.a *= distAlphaMask >= 0.5; -# endif -#endif - - -#if LIGHTING_PREVIEW == 2 - baseColor.xyz=GammaToLinear(baseColor.xyz); -#endif - - float blendedAlpha = baseColor.a; - -#if MASKEDBLENDING - float blendfactor=0.5; -#else - float blendfactor=i.vertexBlendX_fogFactorW.r; -#endif - - if( bBaseTexture2 ) - { -#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING) - float4 modt=tex2D(BlendModulationSampler,i.lightmapTexCoord3.zw); -#if MASKEDBLENDING - // FXC is unable to optimize this, despite blendfactor=0.5 above - //float minb=modt.g-modt.r; - //float maxb=modt.g+modt.r; - //blendfactor=smoothstep(minb,maxb,blendfactor); - blendfactor=modt.g; -#else - float minb=saturate(modt.g-modt.r); - float maxb=saturate(modt.g+modt.r); - blendfactor=smoothstep(minb,maxb,blendfactor); -#endif -#endif - baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor ); - blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor ); - } - - HALF3 specularFactor = 1.0f; - float4 vNormalMask = float4(0, 0, 1, 1); - if( bBumpmap ) - { - if( bBaseTextureNoEnvmap ) - { - vNormal.a = 0.0f; - } - -#if ( BUMPMAP2 == 1 ) - { - #if ( BUMPMASK == 1 ) - HALF2 b2TexCoord = bumpmap2TexCoord; - #else - HALF2 b2TexCoord = bumpmapTexCoord; - #endif - - HALF4 vNormal2; - if ( BUMPMAP == 2 ) - vNormal2 = tex2D( BumpmapSampler2, b2TexCoord ); - else - vNormal2 = DecompressNormal( BumpmapSampler2, b2TexCoord, NORMAL_DECODE_MODE, AlphaMapSampler2 ); // Bump 2 coords - - if( bBaseTexture2NoEnvmap ) - { - vNormal2.a = 0.0f; - } - - #if ( BUMPMASK == 1 ) - float3 vNormal1 = DecompressNormal( BumpmapSampler, i.detailOrBumpAndEnvmapMaskTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMapSampler ); - - vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz ); - - // Third normal map...same coords as base - vNormalMask = DecompressNormal( BumpMaskSampler, i.baseTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMaskSampler ); - - vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal - specularFactor = vNormalMask.a; - #else // BUMPMASK == 0 - if ( FANCY_BLENDING && bNormalMapAlphaEnvmapMask ) - { - vNormal = lerp( vNormal, vNormal2, blendfactor); - } - else - { - vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor); - } - - #endif - - } - -#endif // BUMPMAP2 == 1 - - if( bNormalMapAlphaEnvmapMask ) - { - specularFactor *= vNormal.a; - } - } - else if ( bNormalMapAlphaEnvmapMask ) - { - specularFactor *= vNormal.a; - } - -#if ( BUMPMAP2 == 0 ) - if( bEnvmapMask ) - { - specularFactor *= tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz; - } -#endif - - if( bBaseAlphaEnvmapMask ) - { - specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows! - } - float4 albedo = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - float alpha = 1.0f; - albedo *= baseColor; - if( !bBaseAlphaEnvmapMask && !bSelfIllum ) - { - alpha *= baseColor.a; - } - - if( bDetailTexture ) - { - albedo = TextureCombine( albedo, detailColor, 0, g_DetailBlendFactor ); - } - - // The vertex color contains the modulation color + vertex color combined -#if ( SEAMLESS == 0 ) - albedo.xyz *= i.vertexColor; -#endif - alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one - - // Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal - float3 vSSBumpVector = vNormal.xyz; - - HALF3 diffuseLighting; - if( bBumpmap && bDiffuseBumpmap ) - { - -// ssbump -#if ( BUMPMAP == 2 ) - diffuseLighting = vNormal.x * lightmapColor1 + - vNormal.y * lightmapColor2 + - vNormal.z * lightmapColor3; - diffuseLighting *= g_TintValuesAndLightmapScale.rgb; - - // now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully - // the compiler will eliminate these calculations - vNormal.xyz = normalize( bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z); -#else - float3 dp; - dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); - dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); - dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); - dp *= dp; - - diffuseLighting = dp.x * lightmapColor1 + - dp.y * lightmapColor2 + - dp.z * lightmapColor3; - float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); - diffuseLighting *= g_TintValuesAndLightmapScale.rgb / sum; -#endif - } - else - { - diffuseLighting = lightmapColor1 * g_TintValuesAndLightmapScale.rgb; - } - -#if WARPLIGHTING && ( SEAMLESS == 0 ) - float len=0.5*length(diffuseLighting); - // FIXME: 8-bit lookup textures like this need a "nice filtering" VTF option, which converts - // them to 16-bit on load or does filtering in the shader (since most hardware - 360 - // included - interpolates 8-bit textures at 8-bit precision, which causes banding) - diffuseLighting *= 2.0*tex2D(WarpLightingSampler,float2(len,0)); -#endif - -//#if CUBEMAP || LIGHTING_PREVIEW || ( defined( _X360 ) && FLASHLIGHT ) - float3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); -//#endif - - float3 diffuseComponent = albedo.xyz * diffuseLighting; - -#if defined( _X360 ) && FLASHLIGHT - - // ssbump doesn't pass a normal to the flashlight...it computes shadowing a different way -#if ( BUMPMAP == 2 ) - bool bHasNormal = false; - - float3 worldPosToLightVector = g_FlashlightPos - i.worldPos_projPosZ.xyz; - - float3 tangentPosToLightVector; - tangentPosToLightVector.x = dot( worldPosToLightVector, i.tangentSpaceTranspose[0] ); - tangentPosToLightVector.y = dot( worldPosToLightVector, i.tangentSpaceTranspose[1] ); - tangentPosToLightVector.z = dot( worldPosToLightVector, i.tangentSpaceTranspose[2] ); - - tangentPosToLightVector = normalize( tangentPosToLightVector ); - - float nDotL = saturate( vSSBumpVector.x*dot( tangentPosToLightVector, bumpBasis[0]) + - vSSBumpVector.y*dot( tangentPosToLightVector, bumpBasis[1]) + - vSSBumpVector.z*dot( tangentPosToLightVector, bumpBasis[2]) ); -#else - bool bHasNormal = true; - float nDotL = 1.0f; -#endif - - float fFlashlight = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, i.flashlightSpacePos, - worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - RandRotSampler, 0, true, false, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bHasNormal ); - - diffuseComponent = albedo.xyz * ( diffuseLighting + ( fFlashlight * nDotL ) ); -#endif - - if( bSelfIllum ) - { - float3 selfIllumComponent = g_SelfIllumTint * albedo.xyz; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); - } - - HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); -#if CUBEMAP - if( bCubemap ) - { - float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; -#if CUBEMAPCORRECTED == 0 - float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); -#else - float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); - float3 BoxSize = float3(g_EnvmapRadius,g_EnvmapRadius,g_EnvmapRadius); - float3 BoxMax = BoxSize + g_EnvmapOrigin; - float3 BoxMin = -BoxSize + g_EnvmapOrigin; - float3 firstPlaneIntersect = (BoxMax - i.worldPos_projPosZ.xyz) / reflectVect; - float3 secondPlaneIntersect = (BoxMin - i.worldPos_projPosZ.xyz) / reflectVect; - float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect); - float planeDist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); - float3 intersectPositionWS = i.worldPos_projPosZ.xyz + reflectVect * planeDist; - reflectVect = intersectPositionWS - g_EnvmapOrigin; - //reflectVect = ((i.worldPos_projPosZ.xyz - g_EnvmapOrigin) * (0.5f) + reflectVect); -#endif - - // Calc Fresnel factor - half3 eyeVect = normalize(worldVertToEyeVector); - HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect ); - fresnel = pow( fresnel, 5.0 ); - fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection; - - specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - - specularLighting *= g_EnvmapTint; -#if FANCY_BLENDING == 0 - HALF3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); - HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); -#endif - specularLighting *= fresnel; - -#if CUBEMAPCORRECTED == 1 - float fallof = saturate(length(g_EnvmapOrigin - i.worldPos_projPosZ.xyz) / g_EnvmapRadius); - fallof = 1.0f - pow(fallof, 5.0f); - specularLighting *= fallof; -#endif - } -#endif - -#if CSM == 1 - diffuseComponent += DoCSMLight( i.worldPos_projPosZ.xyz, worldSpaceNormal.xyz, baseColor.rgb, length(i.worldPos_projPosZ.xyz - g_EyePos)); -#endif - HALF3 result = diffuseComponent + specularLighting; - -#if LIGHTING_PREVIEW - worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); -# if LIGHTING_PREVIEW == 1 - float dotprod = 0.7+0.25 * dot( worldSpaceNormal, normalize( float3( 1, 2, -.5 ) ) ); - return FinalOutput( HALF4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -# else - LPREVIEW_PS_OUT ret; - ret.color = float4( albedo.xyz,alpha ); - ret.normal = float4( worldSpaceNormal,alpha ); - ret.position = float4( i.worldPos_projPosZ.xyz, alpha ); - ret.flags = float4( 1, 1, 1, alpha ); - - return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -# endif -#else // == end LIGHTING_PREVIEW == - - bool bWriteDepthToAlpha = false; - - // ps_2_b and beyond -#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) - bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); -#endif - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - -#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = fogFactor; -#endif - output.MainOut = FinalOutput(float4(result.rgb, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w); - output.Normal = float4(worldSpaceNormal.xyz, 1.0f); - output.MRAO = float4(0.0f, 1.0f, 1.0f, 1.0f); - output.Albedo = float4(baseColor.xyz, 1.0f); - return output; - -#endif -} - diff --git a/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc b/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc deleted file mode 100644 index ae18bf65..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc +++ /dev/null @@ -1,59 +0,0 @@ -// STATIC: "MASKEDBLENDING" "0..1" -// STATIC: "BASETEXTURE2" "0..1" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "BUMPMAP" "0..2" -// STATIC: "BUMPMAP2" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "ENVMAPMASK" "0..1" -// STATIC: "BASEALPHAENVMAPMASK" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -// STATIC: "DIFFUSEBUMPMAP" "0..1" -// STATIC: "BASETEXTURENOENVMAP" "0..1" -// STATIC: "BASETEXTURE2NOENVMAP" "0..1" -// STATIC: "WARPLIGHTING" "0..1" -// STATIC: "FANCY_BLENDING" "0..1" -// STATIC: "RELIEF_MAPPING" "0..0" [ps20b] -// STATIC: "SEAMLESS" "0..1" -// STATIC: "OUTLINE" "0..1" -// STATIC: "SOFTEDGES" "0..1" -// STATIC: "BUMPMASK" "0..1" -// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] -// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] -// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [XBOX] -// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC] -// STATIC: "DETAIL_BLEND_MODE" "0..11" -// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX] - -// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" -// DYNAMIC: "FASTPATH" "0..1" -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] - -// SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] - -// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) - -// SKIP: $SEAMLESS && ( $OUTLINE || $SOFTEDGES) -// SKIP: $BASETEXTURE2 && ( $OUTLINE || $SOFTEDGES) -// SKIP: $BUMPMAP2 && ( $OUTLINE || $SOFTEDGES) -// SKIP: $SELFILLUM && ( $OUTLINE || $SOFTEDGES) -// SKIP: $MASKEDBLENDING && ( $OUTLINE || $SOFTEDGES) -// SKIP: $FANCY_BLENDING && ( $OUTLINE || $SOFTEDGES) -// SKIP: $LIGHTING_PREVIEW && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($FASTPATH == 0) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($DETAILTEXTURE && $BUMPMAP) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($WARPLIGHTING) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($BUMPMAP) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($DETAIL_BLEND_MODE == 2 ) || ($DETAIL_BLEND_MODE == 3 ) || ($DETAIL_BLEND_MODE == 4 ) -// SKIP: ($DETAIL_BLEND_MODE == 5 ) || ($DETAIL_BLEND_MODE == 6 ) || ($DETAIL_BLEND_MODE == 7 ) -// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 ) -// SKIP ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 ) -// SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 ) - -#include "lightmappedgeneric_ps2_3_x.h" - diff --git a/materialsystem/stdshaders/lightmappedgeneric_ps30.fxc b/materialsystem/stdshaders/lightmappedgeneric_ps30.fxc deleted file mode 100644 index 16f97205..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_ps30.fxc +++ /dev/null @@ -1,50 +0,0 @@ -// STATIC: "MASKEDBLENDING" "0..1" -// STATIC: "BASETEXTURE2" "0..1" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "BUMPMAP" "0..1" -// STATIC: "BUMPMAP2" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "ENVMAPMASK" "0..1" -// STATIC: "BASEALPHAENVMAPMASK" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -// STATIC: "DIFFUSEBUMPMAP" "0..1" -// STATIC: "BASETEXTURENOENVMAP" "0..1" -// STATIC: "BASETEXTURE2NOENVMAP" "0..1" -// STATIC: "FANCY_BLENDING" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "BUMPMASK" "0..1" - -// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" -// DYNAMIC: "CUBEMAPCORRECTED" "0..1" -// DYNAMIC: "FASTPATH" "0..1" -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..2" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "CSM" "0..1" -// DYNAMIC: "CSM_PERF" "0..2" - -// SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] - -// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) - - -// SKIP: $SEAMLESS && ( $OUTLINE || $SOFTEDGES) -// SKIP: $BASETEXTURE2 && ( $OUTLINE || $SOFTEDGES) -// SKIP: $BUMPMAP2 && ( $OUTLINE || $SOFTEDGES) -// SKIP: $SELFILLUM && ( $OUTLINE || $SOFTEDGES) -// SKIP: $MASKEDBLENDING && ( $OUTLINE || $SOFTEDGES) -// SKIP: $FANCY_BLENDING && ( $OUTLINE || $SOFTEDGES) -// SKIP: $LIGHTING_PREVIEW && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($FASTPATH == 0) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($DETAILTEXTURE && $BUMPMAP) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($WARPLIGHTING) && ( $OUTLINE || $SOFTEDGES) -// SKIP: ($BUMPMAP) && ( $OUTLINE || $SOFTEDGES) - -#define NORMAL_DECODE_MODE 0 -#define NORMALMASK_DECODE_MODE 0 - -#include "lightmappedgeneric_ps2_3_x.h" - diff --git a/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh b/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh deleted file mode 100644 index 4c80db2f..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 - -mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) - -mul r0.rgb, t1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - diff --git a/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh b/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh deleted file mode 100644 index 78072123..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh +++ /dev/null @@ -1,27 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; c1 - self-illum tint -; c2 - envmap tint -;------------------------------------------------------------------------------ - -tex t0 -tex t1 -tex t2 -tex t3 - -mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) -mov r0.a, v0.a ; Grab alpha from vertex color - -mul r1, t2, t3 ; envmap * envmapmask -mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) - -mul r1, c1, t0.a ; Self illum alpha * tint -mad r1, t0, r1, t1 ; Self illum * tint + lightmap -mul r0.rgb, r1, r0 ; fold in lighting (color only) -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh b/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh deleted file mode 100644 index cc1dd1f8..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh +++ /dev/null @@ -1,20 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# STATIC: "DETAIL" "0..1" -# STATIC: "ENVMAP" "0..1" -# STATIC: "ENVMAPCAMERASPACE" "0..0" -# STATIC: "ENVMAPSPHERE" "0..1" -# STATIC: "VERTEXCOLOR" "0..1" - -# can't have envmapshere or envmapcameraspace without envmap -# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) - -# can't have both envmapsphere and envmapcameraspace -# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE - -#include "LightmappedGeneric_inc.vsh" - -&LightmappedGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, - $VERTEXCOLOR ); - diff --git a/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc b/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc deleted file mode 100644 index 1e091899..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc +++ /dev/null @@ -1,238 +0,0 @@ -// STATIC: "ENVMAP_MASK" "0..1" -// STATIC: "TANGENTSPACE" "0..1" -// STATIC: "BUMPMAP" "0..1" -// STATIC: "DIFFUSEBUMPMAP" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "BUMPMASK" "0..1" - -// DYNAMIC: "FASTPATH" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] - -// This should not be a combo since I'm a moron with the tangent space and the flashlight. -// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP -// SKIP: $SEAMLESS && $RELIEF_MAPPING -// SKIP: $BUMPMASK && $RELIEF_MAPPING -// SKIP: $BUMPMASK && $SEAMLESS - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; -static const bool g_bTangentSpace = TANGENTSPACE; -static const bool g_bBumpmap = BUMPMAP; -static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; -static const bool g_bVertexColor = VERTEXCOLOR; -static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; -static const bool g_BumpMask = BUMPMASK; - -#if SEAMLESS -const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 ); -#define SEAMLESS_SCALE (SeamlessScale.x) -#else -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); -#endif -// This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset. -const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest! - -struct VS_INPUT -{ - float3 vPos : POSITION; - float4 vNormal : NORMAL; - float2 vBaseTexCoord : TEXCOORD0; - float2 vLightmapTexCoord : TEXCOORD1; - float2 vLightmapTexCoordOffset : TEXCOORD2; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; - float4 vColor : COLOR0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - -#if SEAMLESS - float3 SeamlessTexCoord : TEXCOORD0; // x y z - float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask -#else - float2 baseTexCoord : TEXCOORD0; - // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. -#if RELIEF_MAPPING - float3 TangentSpaceViewRay : TEXCOORD1; -#else - float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; -#endif -#endif - float4 lightmapTexCoord1And2 : TEXCOORD2; - float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale - float4 worldPos_projPosZ : TEXCOORD4; - -#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) - float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 -#endif - - float4 vertexColor : COLOR; // in seamless, r g b = blend weights - float4 vertexBlendX_fogFactorW : COLOR1; - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); - - float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); - - float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); - -#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) - float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); - float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); - - #if SEAMLESS && BUMPMAP && defined( _X360 ) - float3 n = normalize( worldNormal ); - float3 n2 = n * n; // sums to 1. - - o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) ); - o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) ); - o.tangentSpaceTranspose[2] = worldNormal; - #else - o.tangentSpaceTranspose[0] = worldTangentS; - o.tangentSpaceTranspose[1] = worldTangentT; - o.tangentSpaceTranspose[2] = worldNormal; - #endif - -#endif - - float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); - -#if SEAMLESS - { - // we need to fill in the texture coordinate projections - o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; - } -#else - { - if (FASTPATH) - { - o.baseTexCoord.xy = v.vBaseTexCoord; - } - else - { - o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; - o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; - } -#if ( RELIEF_MAPPING == 0 ) - { - // calculate detailorbumptexcoord - if ( FASTPATH ) - o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; - else - { - o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w; - o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w; - } - } -#endif - } -#endif - if ( FASTPATH ) - { - o.lightmapTexCoord3.zw = v.vBaseTexCoord; - } - else - { - o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w; - o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w; - } - - // compute lightmap coordinates - if( g_bBumpmap && g_bBumpmapDiffuseLighting ) - { - o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; - - float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; - float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; - - // reversed component order - o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; - o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; - - o.lightmapTexCoord3.xy = lightmapTexCoord3; - } - else - { - o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; - } - -#if ( RELIEF_MAPPING == 0) - if( g_UseSeparateEnvmapMask || g_BumpMask ) - { - // reversed component order -# if FASTPATH - o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; -# else - o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w; - o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w; -# endif - } -#endif - - o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); - - if (!g_bVertexColor) - { - o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a ); - } - else - { -#if FASTPATH - o.vertexColor = v.vColor; -#else - if ( g_bVertexAlphaTexBlendFactor ) - { - o.vertexColor.rgb = v.vColor.rgb; - o.vertexColor.a = cModulationColor.a; - } - else - { - o.vertexColor = v.vColor; - o.vertexColor.a *= cModulationColor.a; - } -#endif - } -#if SEAMLESS - // compute belnd weights in rgb - float3 vNormal=normalize( worldNormal ); - o.vertexColor.xyz = vNormal * vNormal; // sums to 1. -#endif - -// On 360, we have extra iterators and can fold the flashlight into this shader -#if defined( _X360 ) - #if FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); - o.vProjPos = vProjPos; - #endif -#endif - - if ( g_bVertexAlphaTexBlendFactor ) - { - o.vertexBlendX_fogFactorW.r = v.vColor.a; - } - - return o; -} diff --git a/materialsystem/stdshaders/lightmappedgeneric_vs30.fxc b/materialsystem/stdshaders/lightmappedgeneric_vs30.fxc deleted file mode 100644 index 1e091899..00000000 --- a/materialsystem/stdshaders/lightmappedgeneric_vs30.fxc +++ /dev/null @@ -1,238 +0,0 @@ -// STATIC: "ENVMAP_MASK" "0..1" -// STATIC: "TANGENTSPACE" "0..1" -// STATIC: "BUMPMAP" "0..1" -// STATIC: "DIFFUSEBUMPMAP" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "BUMPMASK" "0..1" - -// DYNAMIC: "FASTPATH" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] - -// This should not be a combo since I'm a moron with the tangent space and the flashlight. -// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP -// SKIP: $SEAMLESS && $RELIEF_MAPPING -// SKIP: $BUMPMASK && $RELIEF_MAPPING -// SKIP: $BUMPMASK && $SEAMLESS - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; -static const bool g_bTangentSpace = TANGENTSPACE; -static const bool g_bBumpmap = BUMPMAP; -static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; -static const bool g_bVertexColor = VERTEXCOLOR; -static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; -static const bool g_BumpMask = BUMPMASK; - -#if SEAMLESS -const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 ); -#define SEAMLESS_SCALE (SeamlessScale.x) -#else -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); -#endif -// This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset. -const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest! - -struct VS_INPUT -{ - float3 vPos : POSITION; - float4 vNormal : NORMAL; - float2 vBaseTexCoord : TEXCOORD0; - float2 vLightmapTexCoord : TEXCOORD1; - float2 vLightmapTexCoordOffset : TEXCOORD2; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; - float4 vColor : COLOR0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; - -#if SEAMLESS - float3 SeamlessTexCoord : TEXCOORD0; // x y z - float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask -#else - float2 baseTexCoord : TEXCOORD0; - // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. -#if RELIEF_MAPPING - float3 TangentSpaceViewRay : TEXCOORD1; -#else - float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; -#endif -#endif - float4 lightmapTexCoord1And2 : TEXCOORD2; - float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale - float4 worldPos_projPosZ : TEXCOORD4; - -#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) - float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 -#endif - - float4 vertexColor : COLOR; // in seamless, r g b = blend weights - float4 vertexBlendX_fogFactorW : COLOR1; - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 vObjNormal; - DecompressVertex_Normal( v.vNormal, vObjNormal ); - - float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); - - float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); - - float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); - -#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) - float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); - float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); - - #if SEAMLESS && BUMPMAP && defined( _X360 ) - float3 n = normalize( worldNormal ); - float3 n2 = n * n; // sums to 1. - - o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) ); - o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) ); - o.tangentSpaceTranspose[2] = worldNormal; - #else - o.tangentSpaceTranspose[0] = worldTangentS; - o.tangentSpaceTranspose[1] = worldTangentT; - o.tangentSpaceTranspose[2] = worldNormal; - #endif - -#endif - - float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); - -#if SEAMLESS - { - // we need to fill in the texture coordinate projections - o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; - } -#else - { - if (FASTPATH) - { - o.baseTexCoord.xy = v.vBaseTexCoord; - } - else - { - o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; - o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; - } -#if ( RELIEF_MAPPING == 0 ) - { - // calculate detailorbumptexcoord - if ( FASTPATH ) - o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; - else - { - o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w; - o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w; - } - } -#endif - } -#endif - if ( FASTPATH ) - { - o.lightmapTexCoord3.zw = v.vBaseTexCoord; - } - else - { - o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w; - o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w; - } - - // compute lightmap coordinates - if( g_bBumpmap && g_bBumpmapDiffuseLighting ) - { - o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; - - float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; - float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; - - // reversed component order - o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; - o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; - - o.lightmapTexCoord3.xy = lightmapTexCoord3; - } - else - { - o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; - } - -#if ( RELIEF_MAPPING == 0) - if( g_UseSeparateEnvmapMask || g_BumpMask ) - { - // reversed component order -# if FASTPATH - o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; -# else - o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w; - o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w; -# endif - } -#endif - - o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); - - if (!g_bVertexColor) - { - o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a ); - } - else - { -#if FASTPATH - o.vertexColor = v.vColor; -#else - if ( g_bVertexAlphaTexBlendFactor ) - { - o.vertexColor.rgb = v.vColor.rgb; - o.vertexColor.a = cModulationColor.a; - } - else - { - o.vertexColor = v.vColor; - o.vertexColor.a *= cModulationColor.a; - } -#endif - } -#if SEAMLESS - // compute belnd weights in rgb - float3 vNormal=normalize( worldNormal ); - o.vertexColor.xyz = vNormal * vNormal; // sums to 1. -#endif - -// On 360, we have extra iterators and can fold the flashlight into this shader -#if defined( _X360 ) - #if FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); - o.vProjPos = vProjPos; - #endif -#endif - - if ( g_bVertexAlphaTexBlendFactor ) - { - o.vertexBlendX_fogFactorW.r = v.vColor.a; - } - - return o; -} diff --git a/materialsystem/stdshaders/lightmappedpbr_ps30.fxc b/materialsystem/stdshaders/lightmappedpbr_ps30.fxc new file mode 100644 index 00000000..a401a240 --- /dev/null +++ b/materialsystem/stdshaders/lightmappedpbr_ps30.fxc @@ -0,0 +1,465 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example pixel shader that can be applied to models +// +//================================================================================================== + +// STATIC: "CONVERT_TO_SRGB" "0..0" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" +// STATIC: "SMOOTHNESS" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMAP" "0..1" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "CUBEMAPCORRECTED" "0..1" +// DYNAMIC: "CSM" "0..1" +// DYNAMIC: "CSM_PERF" "0..2" +// DYNAMIC: "LIGHT_PREVIEW" "0..2" + +// We don't care about those in the editor +// SKIP: ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW + +// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// SKIP: ( $CUBEMAP == 0 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $OLDIBL == 0 ) && ( $OLDIBL == 1 ) +// SKIP: ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) + +// both cant exist at the same time +// SKIP: ( $FLASHLIGHT == 1) && ( $CSM == 1) + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" +#include "common_pbr.h" +#include "common_deferredshadows_fxc.h" +#include "common_lightmappedgeneric_fxc.h" + +#ifdef NV3X + #define PSHADER_VECT_SCALE 20.0 + #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) +#else + #define PSHADER_VECT_SCALE 1.0 + #define VSHADER_VECT_SCALE 1.0 +#endif + +const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); +const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); +const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +#if FLASHLIGHT == 1 +sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler +sampler FlashlightSampler : register( s6 ); // Flashlight cookie + +const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass +const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_FlashlightColor : register( PSREG_FLASHLIGHT_COLOR ); +#elif CSM == 1 +sampler ShadowDepthSampler : register( s4 ); // CSM Depth + +const float4x4 g_CSMWorldToTexture : register( c22 ); +const float4 g_CascadeFwd : register( c26 ); +const float4 g_CascadeLight : register( c27 ); +const float4 g_CascadeAmbient : register( c28 ); +const float2 g_CascadeBias : register( c31 ); +const float2 g_CascadeResolution : register( c32 ); +const float4 g_CascadeSize : register( c33 ); +#endif +const float4 g_TintValuesAndLightmapScale : register( c20 ); +const float4 g_EnvmapOrigin_and_Radius : register( c21 ); +#define g_EnvmapOrigin (g_EnvmapOrigin_and_Radius.xyz) +#define g_EnvmapRadius (g_EnvmapOrigin_and_Radius.w) + +#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz + +sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha +sampler RoughnessSampler : register( s1 ); // Roughness +sampler MetallicSampler : register( s2 ); // Metallic +sampler BumpmapSampler : register( s3 ); // Bump map +sampler EnvmapSampler : register( s7 ); // for IBL +sampler BRDFSampler : register( s8 ); // for IBL +sampler AOSampler : register( s9 ); // AO +sampler EmissiveSampler : register( s10 ); // Emissive map +sampler LightmapSampler : register( s11 ); // Lightmap texture from the engine + +// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV ) +{ + const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; + const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; + half4 r = Roughness * c0 + c1; + half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; + half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw; + return SpecularColor * AB.x + AB.y; +} + +float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max(1.0f.xxx - roughness, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 DoIBL(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallness, float roughness, float3 lightmap) +{ + float3 WorldToEye = g_EyePos.xyz - vWorldPos; + float3 V = normalize( WorldToEye ); + float3 N = normalize( vWorldNormal ); + + //precompute dots + float NV = max(0.0, dot(normalize(N), V)); + + float3 metallic = clamp(metallness, 0.0f, 0.9f); +#if CUBEMAP == 1 + +#if CUBEMAPCORRECTED == 0 + float3 reflectVect = CalcReflectionVectorUnnormalized( vWorldNormal, V ); +#else + float3 reflectVect = CalcReflectionVectorUnnormalized( vWorldNormal, WorldToEye); + float3 BoxSize = float3(g_EnvmapRadius,g_EnvmapRadius,g_EnvmapRadius); + float3 BoxMax = BoxSize + g_EnvmapOrigin; + float3 BoxMin = -BoxSize + g_EnvmapOrigin; + float3 firstPlaneIntersect = (BoxMax - vWorldPos) / reflectVect; + float3 secondPlaneIntersect = (BoxMin - vWorldPos) / reflectVect; + float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect); + float planeDist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); + float3 intersectPositionWS = vWorldPos + reflectVect * planeDist; + reflectVect = intersectPositionWS - g_EnvmapOrigin; +#endif + + float4 directionPosX = { 1.0f, 0.01f, 0.01f, 12.0f }; float4 directionNegX = {-1.0f, 0.01f, 0.01f, 12.0f }; + float4 directionPosY = { 0.01f, 1.0f, 0.01f, 12.0f }; float4 directionNegY = { 0.01f,-1.0f, 0.01f, 12.0f }; + float4 directionPosZ = { 0.01f, 0.01f, 1.0f, 12.0f }; float4 directionNegZ = { 0.01f, 0.01f,-1.0f, 12.0f }; + float3 lookupPosX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosX); + float3 lookupNegX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegX); + float3 lookupPosY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosY); + float3 lookupNegY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegY); + float3 lookupPosZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosZ); + float3 lookupNegZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegZ); + float3 envmapCube[6] = { lookupPosX, lookupNegX, lookupPosY, lookupNegY, lookupPosZ, lookupNegZ }; + + float3 irradiance = lightmap; + + float3 f0 = 0.04f.xxx; + f0 = lerp(f0, albedo.rgb, metallic); + float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term + + half3 BRDF = EnvBRDFApprox(f0, roughness, NV); + + float3 kD = 1.0f.xxx - F; + kD *= 1.0 - metallic; + + float3 diffuseIBL = kD * albedo * irradiance; + float3 lookup = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, float4(reflectVect, roughness * 12.0)).rgb; + float3 specularIrradiance = lerp(lookup, PixelShaderAmbientLight( reflectVect, envmapCube ), roughness * roughness ); + float3 specularIBL = BRDF * specularIrradiance; + +#if CUBEMAPCORRECTED == 1 + float fallof = saturate(length(g_EnvmapOrigin - vWorldPos) / g_EnvmapRadius); + fallof = 1.0f - pow(fallof, 5.0f); + specularIBL *= fallof; +#endif + + //mix + return max(0.0, diffuseIBL + specularIBL); +#else + + float3 f0 = 0.04f.xxx; + f0 = lerp(f0, albedo.rgb, metallic); + float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term + + float3 kD = 1.0f.xxx - F; + kD *= 1.0 - metallic; + return kD * albedo * lightmap; +#endif +} + +#if FLASHLIGHT == 1 +float3 DoFlashlight(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallic, float roughness) +{ + float4 flashlightSpacePosition = mul( float4(vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = tex2D( FlashlightSampler, vProjCoords); + float3 shadow = 1.0f; + #if FLASHLIGHTSHADOWS + shadow = tex2DprojBicubic(ShadowDepthSampler, 512.0f.xx, vProjCoords.xy, vProjCoords.z); + #endif + float2 dist = float2(length(g_FlashlightPos_RimBoost.xyz - vWorldPos), dot(g_FlashlightPos_RimBoost.xyz - vWorldPos,g_FlashlightPos_RimBoost.xyz - vWorldPos)); + float fAtten = saturate( dot( g_FlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/dist.x, 1.0f/dist.y ) ) ); + float3 light = DoPBRLight( vWorldPos, vWorldNormal, albedo, g_FlashlightPos_RimBoost.xyz, flashlightColor.rgb * g_FlashlightColor.xyz, g_EyePos.xyz, shadow * fAtten * g_FlashlightColor.w, metallic, roughness); + return light; +} +#elif CSM == 1 +float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) +{ + float2 rtSize = g_CascadeResolution;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; + float fEpsilonX = 1.0f / rtSize.y; + float fEpsilonY = 1.0f / rtSize.x; + +#if CSM_PERF < 1 + float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); + float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); +#endif +#if CSM_PERF < 2 + float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); +#endif + float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); + + float projMask = 1.0f; + if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) + { + projMask = 0.0f; + } + + float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); +#if CSM_PERF < 1 + float shadowProjDiff0 = 1; + float3 shadowMapCenter_objDepth0 = cascade0; + float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; + float objDepth0 = shadowMapCenter_objDepth0.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff0; + float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); + + float shadowProjDiff1 = g_CascadeSize.y; + float3 shadowMapCenter_objDepth1 = cascade1; + float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; + float objDepth1 = shadowMapCenter_objDepth1.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff1; + float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); +#endif + +#if CSM_PERF < 2 + float shadowProjDiff2 = g_CascadeSize.z; + float3 shadowMapCenter_objDepth2 = cascade2; + float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; + float objDepth2 = shadowMapCenter_objDepth2.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff2; + float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); +#endif + + float shadowProjDiff3 = g_CascadeSize.w; + float3 shadowMapCenter_objDepth3 = cascade3; + float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; + float objDepth3 = shadowMapCenter_objDepth3.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff3; + float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); + + /*float shadow0 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); + float shadow1 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); + float shadow2 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); + float shadow3 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3);*/ + + float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); + +#if CSM_PERF < 2 + float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); +#else + float shadow2 = shadow3; +#endif + +#if CSM_PERF < 1 + float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); + float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); +#else + float shadow1 = shadow2; + float shadow0 = shadow2; +#endif + + + /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); + float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); + float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); + float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); + + float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); + float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); + float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); + float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ + + + float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); + float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); + float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); + + float shadow = shadow0123; + + if(projMask == 1.0f) + { + float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); + float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); + return shadowFinal; + } + else + { + return 1.0f; + } + +} + +float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) +{ + float3 Out; + float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); + float4 flashlightSpacePosition = mul(float4(worldPos, 1.0f), g_CSMWorldToTexture); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); + float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); + diffuse = saturate(diffuse); + + Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); + return Out; +} +#endif +struct PS_INPUT +{ + float3 SeamlessTexCoord : TEXCOORD0; // x y z + float2 baseTexCoord : TEXCOORD1; + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale + float4 worldPos_projPosZ : TEXCOORD4; + + float3x3 TBN : TEXCOORD5; + + float4 vertexColor : COLOR; // in seamless, r g b = blend weights + float4 vertexBlendX_fogFactorW : COLOR1; + +}; + +struct PS_OUTPUT +{ + float4 MainOut : COLOR0; + float4 Normal : COLOR1; + float4 MRAO : COLOR2; + float4 Albedo : COLOR3; +}; + +#if LIGHT_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#elif LIGHT_PREVIEW == 1 +HALF4 main(PS_INPUT i) : COLOR +#else +PS_OUTPUT main(PS_INPUT i) : COLOR +#endif +{ + bool bBumpmap = BUMPMAP ? true : false; + bool bCubemap = (CUBEMAP) ? true : false; + float3 UV = 0.0f.xxx; +#if SEAMLESS == 0 + UV.xy = i.baseTexCoord.xy; +#else + UV = i.SeamlessTexCoord; +#endif + float3 worldPos = i.worldPos_projPosZ.xyz; +#if SMOOTHNESS == 0 + float roughnessMap = tex2D( RoughnessSampler, UV.xy ); +#else + float roughnessMap = 1.0f - tex2D( RoughnessSampler, UV.xy ); +#endif + float metallicMap = tex2D( MetallicSampler, UV.xy ); + float AOSample = tex2D( AOSampler, UV.xy ); + float3 EmissiveSample = tex2D( EmissiveSampler, UV.xy ); + float4 baseColor = tex2D( BaseTextureSampler, UV.xy ); + float4 baseColor2 = 0.0f.xxxx; + float4 normalTexel = 0.0f.xxxx; + GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler, BumpmapSampler, false, bBumpmap, + UV, i.vertexColor.rgb, baseColor, baseColor2, normalTexel ); + + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + + float3 vWorldNormal = mul( tangentSpaceNormal, i.TBN ); + + PS_OUTPUT output = (PS_OUTPUT)0; + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); + if( bBumpmap) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 ); + lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 ); + } + else + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + } + float3 lightmapTexel = 1.0f; + if(bBumpmap) + { + float3 dp; + dp.x = saturate( dot( tangentSpaceNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( tangentSpaceNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( tangentSpaceNormal, bumpBasis[2] ) ); + dp *= dp; + + lightmapTexel = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + lightmapTexel *= 1.0f / sum; + } + else + { + lightmapTexel = lightmapColor1; + } + + lightmapTexel *= g_TintValuesAndLightmapScale.rgb; + + //HALF2 lightmapCoord = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + //float3 lightmapTexel = LightMapSample( LightmapSampler, lightmapCoord )* g_TintValuesAndLightmapScale.rgb; + + float3 albedo = g_DiffuseModulation.rgb * baseColor.rgb; + + float3 IBL = DoIBL(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap, lightmapTexel); + float3 Flashlight = 0.0f; +#if FLASHLIGHT + Flashlight = DoFlashlight(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap); + float3 result = (Flashlight); +#elif CSM == 1 + float3 CSMLight = DoPBRCSM(worldPos, vWorldNormal, baseColor.rgb, metallicMap, roughnessMap, length(worldPos - g_EyePos)); + float3 result = (IBL * AOSample) + EmissiveSample + CSMLight; +#else + float3 result = (IBL * AOSample) + EmissiveSample; +#endif + float alpha = baseColor.a * g_DiffuseModulation.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, worldPos.z, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + alpha = fogFactor; +#endif + +#if LIGHT_PREVIEW == 1 + result = DoPBRLight(worldPos, i.TBN[2].xyz, baseColor, g_EyePos.xyz, 1.0f.xxx, g_EyePos.xyz, 5.0f, metallicMap, roughnessMap); + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + return FinalOutput( float4( result.rgb, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); +#elif LIGHT_PREVIEW == 2 + LPREVIEW_PS_OUT Output; + Output.color = float4( baseColor.xyz,alpha ); + Output.normal = float4( i.TBN[2].xyz,alpha ); + Output.position = float4( worldPos, alpha ); + Output.flags = float4( 1.0f - metallicMap, roughnessMap, 1, alpha ); + return FinalOutput( Output, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +#else + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + output.MainOut = FinalOutput(float4(result.rgb, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w); +#if !FLASHLIGHT + output.Normal = float4(vWorldNormal.xyz, 1.0f); + output.MRAO = float4(metallicMap, roughnessMap, AOSample, 1.0f); + output.Albedo = float4(baseColor.xyz, 1.0f); +#endif + + return output; +#endif +} diff --git a/materialsystem/stdshaders/lightmappedPBR_vs30.fxc b/materialsystem/stdshaders/lightmappedpbr_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/lightmappedPBR_vs30.fxc rename to materialsystem/stdshaders/lightmappedpbr_vs30.fxc diff --git a/materialsystem/stdshaders/lightmappedreflective.cpp b/materialsystem/stdshaders/lightmappedreflective.cpp new file mode 100644 index 00000000..2e8899eb --- /dev/null +++ b/materialsystem/stdshaders/lightmappedreflective.cpp @@ -0,0 +1,256 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "mathlib/vmatrix.h" +#include "common_hlsl_cpp_consts.h" // hack hack hack! +#include "sdk_lightmappedreflective_vs30.inc" +#include "sdk_lightmappedreflective_ps30.inc" + +BEGIN_VS_SHADER( LightmappedReflective, "Help for LightmappedReflective" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FRESNELPOWER, SHADER_PARAM_TYPE_FLOAT, "5", "" ) + SHADER_PARAM( MAXREFLECTIVITY, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + SHADER_PARAM( MINREFLECTIVITY, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !params[FRESNELPOWER]->IsDefined() ) + { + params[FRESNELPOWER]->SetFloatValue( 5.0f ); + } + if ( !params[MAXREFLECTIVITY]->IsDefined() ) + { + params[MAXREFLECTIVITY]->SetFloatValue( 1.0f ); + } + + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if ( params[BASETEXTURE]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + } + + SHADER_FALLBACK + { + // FIXME: Create dx8 level fallback if we use this feature out of the SFM + return 0; + } + + SHADER_INIT + { + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE ); + } + if ( params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + if( params[ENVMAPMASK]->IsDefined() ) + { + LoadTexture( ENVMAPMASK ); + } + } + else + { + params[ENVMAPMASK]->SetUndefined(); + } + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + SetInitialShadowState( ); + if( bRefraction ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + } + if( bReflection ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + } + if( params[BASETEXTURE]->IsTexture() ) + { + // BASETEXTURE + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + // LIGHTMAP + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + if ( params[ENVMAPMASK]->IsTexture() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + } + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 1; + if( params[BASETEXTURE]->IsTexture() ) + { + numTexCoords = 3; + } + pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); + + if ( IS_FLAG_SET(MATERIAL_VAR_TRANSLUCENT ) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedreflective_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_VERTEX_SHADER( sdk_lightmappedreflective_vs30 ); + + // "REFLECT" "0..1" + // "REFRACT" "0..1" + + DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, params[ENVMAPMASK]->IsTexture() && params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps30 ); + + FogToFogColor(); + + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + { + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + } + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + if( bRefraction ) + { + // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable + BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 ); + } + if( bReflection ) + { + BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME ); + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTURETRANSFORM ); + + if ( params[ENVMAPMASK]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER6, ENVMAPMASK, ENVMAPMASKFRAME ); + } + } + + // Refraction tint + if( bRefraction ) + { + SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); + } + // Reflection tint + if( bReflection ) + { + SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT ); + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // fresnel constants + float flFresnelFactor = params[MAXREFLECTIVITY]->GetFloatValue() - params[MINREFLECTIVITY]->GetFloatValue(); + float c3[4] = { flFresnelFactor, params[FRESNELPOWER]->GetFloatValue(), params[MINREFLECTIVITY]->GetFloatValue(), 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + pShaderAPI->SetPixelShaderFogParams( 8 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedreflective_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_lightmappedreflective_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps30 ); + } + Draw(); + } + + SHADER_DRAW + { + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); + bool bReflection = params[REFLECTTEXTURE]->IsTexture(); + bool bDrewSomething = false; + if ( bReflection || bRefraction ) + { + bDrewSomething = true; + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + } + + if( !bDrewSomething ) + { + // We are likely here because of the tools. . . draw something so that + // we won't go into wireframe-land. + Draw(); + } + } +END_SHADER diff --git a/materialsystem/stdshaders/lightpass_ps30.fxc b/materialsystem/stdshaders/lightpass_ps30.fxc index 6fe14706..768f3478 100644 --- a/materialsystem/stdshaders/lightpass_ps30.fxc +++ b/materialsystem/stdshaders/lightpass_ps30.fxc @@ -20,7 +20,7 @@ #include "common_lightmappedgeneric_fxc.h" #include "common_pbr.h" -#include "deferred_shadows.h" +#include "common_deferredshadows_fxc.h" sampler BaseTextureSampler : register( s1 ); // Albedo sampler RandDotSampler : register( s2 ); // random noise sampler diff --git a/materialsystem/stdshaders/lightpass_vs30.fxc b/materialsystem/stdshaders/lightpass_vs30.fxc index 2d4d22f9..e2ab6fd0 100644 --- a/materialsystem/stdshaders/lightpass_vs30.fxc +++ b/materialsystem/stdshaders/lightpass_vs30.fxc @@ -6,27 +6,26 @@ // STATIC: "MODEL" "0..1" // STATIC: "TANGENTSPACE" "0..1" -// STATIC: "MORPHING_VTEX" "0..1" // STATIC: "VERTEXCOLOR" "0..1" // STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" -// STATIC: "SEAMLESS" "0..1" +// STATIC: "SEAMLESS" "0..1" // DYNAMIC: "COMPRESSED_VERTS" "0..1" // DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" + +// SKIP: $MORPHING && ( $MODEL == 0 ) #include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" static const bool g_bSkinning = SKINNING ? true : false; static const bool g_bVertexColor = VERTEXCOLOR; static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; -#if MODEL - +#if ( MORPHING ) const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); sampler2D morphSampler : register( s0 ); - #endif #if SEAMLESS @@ -59,7 +58,10 @@ struct VS_INPUT float4 vTexCoord2 : TEXCOORD2; float4 vPosFlex : POSITION1; float4 vNormalFlex : NORMAL1; - float vVertexID : POSITION2; + + #if ( MORPHING ) + float vVertexID : POSITION2; + #endif #else @@ -104,38 +106,42 @@ VS_OUTPUT main( const VS_INPUT In ) float4 vPos = In.vPos; float3 vNormal = 0; -#if TANGENTSPACE - float4 vTangentMixed = 0; - float3 worldTangentS = 0; - float3 worldTangentT = 0; - - DecompressVertex_NormalTangent( In.vNormal, In.vUserData, vNormal, vTangentMixed ); - -#if MORPHING - ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal, vTangentMixed.xyz ); -#endif - - SkinPositionNormalAndTangentSpace( g_bSkinning, vPos, vNormal, vTangentMixed, - In.vBoneWeights, In.vBoneIndices, - worldPos, worldNormal, worldTangentS, worldTangentT ); - - worldTangentS = normalize( worldTangentS ); - worldTangentT = normalize( worldTangentT ); - -#else // TANGENTSPACE - DecompressVertex_Normal( In.vNormal, vNormal ); - -#if MORPHING - ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal ); -#endif + #if TANGENTSPACE + float4 vTangentMixed = 0; + float3 worldTangentS = 0; + float3 worldTangentT = 0; + + DecompressVertex_NormalTangent( In.vNormal, In.vUserData, vNormal, vTangentMixed ); + + #if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), + vObjPosition.xyz, vObjNormal, vObjTangent.xyz ); + #else + ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal, vTangentMixed.xyz ); + #endif + + SkinPositionNormalAndTangentSpace( g_bSkinning, vPos, vNormal, vTangentMixed, + In.vBoneWeights, In.vBoneIndices, + worldPos, worldNormal, worldTangentS, worldTangentT ); + + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + #else // TANGENTSPACE + DecompressVertex_Normal( In.vNormal, vNormal ); + + #if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, In.vVertexID, float3( 0, 0, 0 ), + vObjPosition.xyz, vObjNormal ); + #else + ApplyMorph( In.vPosFlex, In.vNormalFlex, vPos.xyz, vNormal ); + #endif + + SkinPositionAndNormal( g_bSkinning, vPos, vNormal, + In.vBoneWeights, In.vBoneIndices, + worldPos, worldNormal ); + #endif - SkinPositionAndNormal( g_bSkinning, vPos, vNormal, - In.vBoneWeights, In.vBoneIndices, - worldPos, worldNormal ); - -#endif // NOT TANGENTSPACE Out.vertexColor = float4( 0.0f, 0.0f, 0.0f, cModulationColor.a ); - worldNormal = normalize( worldNormal ); #else // MODEL @@ -161,16 +167,16 @@ VS_OUTPUT main( const VS_INPUT In ) worldPos = mul( float4( In.vPos, 1 ), cModel[0] ); worldNormal = mul( In.vNormal, ( float3x3 )cModel[0] ); -#if TANGENTSPACE + #if TANGENTSPACE - float3 worldTangentS = mul( In.vTangentS, ( float3x3 )cModel[0] ); - float3 worldTangentT = mul( In.vTangentT, ( float3x3 )cModel[0] ); + float3 worldTangentS = mul( In.vTangentS, ( float3x3 )cModel[0] ); + float3 worldTangentT = mul( In.vTangentT, ( float3x3 )cModel[0] ); -#endif // NOT TANGENTSPACE + #endif // NOT TANGENTSPACE -#if BUMPMAP2 - Out.vColor_0 = In.vColor_0; -#endif + #if BUMPMAP2 + Out.vColor_0 = In.vColor_0; + #endif #endif // NOT MODEL diff --git a/materialsystem/stdshaders/lpreview1_ps2x.fxc b/materialsystem/stdshaders/lpreview1_ps2x.fxc deleted file mode 100644 index a88cb456..00000000 --- a/materialsystem/stdshaders/lpreview1_ps2x.fxc +++ /dev/null @@ -1,69 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#define HDRTYPE HDR_TYPE_NONE -#define HDRENABLED 0 -#include "common_ps_fxc.h" - -sampler AlbedoSampler : register( s0 ); -sampler NormalSampler : register( s1 ); -sampler PositionSampler : register( s2 ); -sampler AccBuf_In : register( s3 ); - -float4 EyePosition : register (c10); - -float4 Light_origin : register( c0 ); -#define INNER_COS (Light_origin.w) -#define OUTER_COS (Light_dir.w) - -float4 Light_dir : register( c1 ); - -float4 Light_attn : register (c2); -#define QUADRATIC_ATTN (Light_attn.x) -#define LINEAR_ATTN (Light_attn.y) -#define CONSTANT_ATTN (Light_attn.z) -#define SCALE_FACTOR (Light_attn.w) - -float3 Light_color: register(c3); - -struct PS_INPUT -{ - float2 texCoord : TEXCOORD0; -}; - - -float Lerp5(float f1, float f2, float i1, float i2, float x) -{ - return f1+(f2-f1)*(x-i1)/(i2-i1); -} - -float4 main( PS_INPUT i ) : COLOR -{ - float4 normal=tex2D( NormalSampler, i.texCoord ); - float4 albedo=tex2D( AlbedoSampler, i.texCoord ); - float4 pos=tex2D( PositionSampler, i.texCoord ); - float3 old_acc=tex2D( AccBuf_In, i.texCoord ); -// pos.xyz+=EyePosition.xyz; - - float3 ldir=Light_origin.xyz-pos.xyz; - float dist=sqrt(dot(ldir,ldir)); - ldir=normalize(ldir); - float spot_dot=dot(ldir,-Light_dir); - float3 ret=Light_color*0.09*albedo.xyz; // ambient - float dist_falloff=(SCALE_FACTOR/(QUADRATIC_ATTN*dist*dist+LINEAR_ATTN*dist+CONSTANT_ATTN)); - if (spot_dot>OUTER_COS) - { - float falloff=1; - if (spot_dot - add $tmp.z, $tmp.z, $cOne - - ; find 1 / the length of r2 - dp3 $tmp.w, $tmp, $tmp - rsq $tmp.w, $tmp.w - - ; r1 = r2/|r2| + 1 - mad $tmp.xy, $tmp.w, $tmp, $cOne - mul $sphereMapTexCoords.xy, $tmp.xy, $cHalf - - &FreeRegister( \$tmp ); -} - -sub SkinPosition -{ -# print "\$SKINNING = $SKINNING\n"; - local( $worldPos ) = shift; - - if( !defined $SKINNING ) - { - die "using \$SKINNING without defining.\n"; - } - - if( $SKINNING == 0 ) - { - ; - ; 0 bone skinning (4 instructions) - ; - ; Transform position into world space - ; position - dp4 $worldPos.x, $vPos, $cModel0 - dp4 $worldPos.y, $vPos, $cModel1 - dp4 $worldPos.z, $vPos, $cModel2 - mov $worldPos.w, $cOne - } - else - { - ; - ; 3 bone skinning (19 instructions) - ; - local( $boneIndices ); - local( $blendedMatrix0 ); - local( $blendedMatrix1 ); - local( $blendedMatrix2 ); - local( $localPos ); - &AllocateRegister( \$boneIndices ); - &AllocateRegister( \$blendedMatrix0 ); - &AllocateRegister( \$blendedMatrix1 ); - &AllocateRegister( \$blendedMatrix2 ); - - ; Transform position into world space using all bones - ; denormalize d3dcolor to matrix index - mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index - if ( $g_x360 ) - { - mov $boneIndices, $boneIndices.zyxw - } - - ; r11 = boneindices at this point - ; first matrix - mov a0.x, $boneIndices.z - mul $blendedMatrix0, $vBoneWeights.x, c[a0.x] - mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1] - mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2] - ; second matrix - mov a0.x, $boneIndices.y - mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2 - - ; Calculate third weight - ; compute 1-(weight1+weight2) to calculate weight2 - ; Use $boneIndices.w as a temp since we aren't using it for anything. - add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y - sub $boneIndices.w, $cOne, $boneIndices.w - - ; third matrix - mov a0.x, $boneIndices.x - mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2 - - dp4 $worldPos.x, $vPos, $blendedMatrix0 - dp4 $worldPos.y, $vPos, $blendedMatrix1 - dp4 $worldPos.z, $vPos, $blendedMatrix2 - mov $worldPos.w, $cOne - - &FreeRegister( \$boneIndices ); - &FreeRegister( \$blendedMatrix0 ); - &FreeRegister( \$blendedMatrix1 ); - &FreeRegister( \$blendedMatrix2 ); - } -} - - -sub SkinPositionAndNormal -{ -# print "\$SKINNING = $SKINNING\n"; - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - - if( !defined $SKINNING ) - { - die "using \$SKINNING without defining.\n"; - } - - if( $SKINNING == 0 ) - { - ; - ; 0 bone skinning (13 instructions) - ; - ; Transform position + normal + tangentS + tangentT into world space - ; position - dp4 $worldPos.x, $vPos, $cModel0 - dp4 $worldPos.y, $vPos, $cModel1 - dp4 $worldPos.z, $vPos, $cModel2 - mov $worldPos.w, $cOne - ; normal - dp3 $worldNormal.x, $vNormal, $cModel0 - dp3 $worldNormal.y, $vNormal, $cModel1 - dp3 $worldNormal.z, $vNormal, $cModel2 - } - else - { - local( $boneIndices ); - local( $blendedMatrix0 ); - local( $blendedMatrix1 ); - local( $blendedMatrix2 ); - local( $localPos ); - local( $localNormal ); - local( $normalLength ); - local( $ooNormalLength ); - &AllocateRegister( \$boneIndices ); - &AllocateRegister( \$blendedMatrix0 ); - &AllocateRegister( \$blendedMatrix1 ); - &AllocateRegister( \$blendedMatrix2 ); - - ; Transform position into world space using all bones - ; denormalize d3dcolor to matrix index - mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index - if ( $g_x360 ) - { - mov $boneIndices, $boneIndices.zyxw - } - - ; r11 = boneindices at this point - ; first matrix - mov a0.x, $boneIndices.z - mul $blendedMatrix0, $vBoneWeights.x, c[a0.x] - mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1] - mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2] - ; second matrix - mov a0.x, $boneIndices.y - mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2 - - ; Calculate third weight - ; compute 1-(weight1+weight2) to calculate weight2 - ; Use $boneIndices.w as a temp since we aren't using it for anything. - add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y - sub $boneIndices.w, $cOne, $boneIndices.w - - ; third matrix - mov a0.x, $boneIndices.x - mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2 - - dp4 $worldPos.x, $vPos, $blendedMatrix0 - dp4 $worldPos.y, $vPos, $blendedMatrix1 - dp4 $worldPos.z, $vPos, $blendedMatrix2 - mov $worldPos.w, $cOne - - ; normal - dp3 $worldNormal.x, $vNormal, $blendedMatrix0 - dp3 $worldNormal.y, $vNormal, $blendedMatrix1 - dp3 $worldNormal.z, $vNormal, $blendedMatrix2 - - &FreeRegister( \$boneIndices ); - &FreeRegister( \$blendedMatrix0 ); - &FreeRegister( \$blendedMatrix1 ); - &FreeRegister( \$blendedMatrix2 ); - } -} - -sub SkinPositionNormalAndTangentSpace -{ -# print "\$SKINNING = $SKINNING\n"; - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - local( $worldTangentS ) = shift; - local( $worldTangentT ) = shift; - local( $userData ); - local( $localPos ); - local( $localNormal ); - local( $normalLength ); - local( $ooNormalLength ); - - if( !defined $SKINNING ) - { - die "using \$SKINNING without defining.\n"; - } - -# X360TBD: needed for compressed vertex format -# if ( $g_x360 ) -# { -# &AllocateRegister( \$userData ); -# ; remap compressed range [0..1] to [-1..1] -# mad $userData, $vUserData, $cTwo, -$cOne -# } - - if( $SKINNING == 0 ) - { - ; - ; 0 bone skinning (13 instructions) - ; - ; Transform position + normal + tangentS + tangentT into world space - dp4 $worldPos.x, $vPos, $cModel0 - dp4 $worldPos.y, $vPos, $cModel1 - dp4 $worldPos.z, $vPos, $cModel2 - mov $worldPos.w, $cOne - - ; normal - dp3 $worldNormal.x, $vNormal, $cModel0 - dp3 $worldNormal.y, $vNormal, $cModel1 - dp3 $worldNormal.z, $vNormal, $cModel2 - -# X360TBD: needed for compressed vertex format -# if ( $g_x360 ) -# { -# ; tangents -# dp3 $worldTangentS.x, $userData, $cModel0 -# dp3 $worldTangentS.y, $userData, $cModel1 -# dp3 $worldTangentS.z, $userData, $cModel2 -# -# ; calculate tangent t via cross( N, S ) * S[3] -# &Cross( $worldTangentT, $worldNormal, $worldTangentS ); -# mul $worldTangentT.xyz, $userData.w, $worldTangentT.xyz -# } -# else - { - ; tangents - dp3 $worldTangentS.x, $vUserData, $cModel0 - dp3 $worldTangentS.y, $vUserData, $cModel1 - dp3 $worldTangentS.z, $vUserData, $cModel2 - - ; calculate tangent t via cross( N, S ) * S[3] - &Cross( $worldTangentT, $worldNormal, $worldTangentS ); - mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz - } - } - else - { - local( $boneIndices ); - local( $blendedMatrix0 ); - local( $blendedMatrix1 ); - local( $blendedMatrix2 ); - &AllocateRegister( \$boneIndices ); - &AllocateRegister( \$blendedMatrix0 ); - &AllocateRegister( \$blendedMatrix1 ); - &AllocateRegister( \$blendedMatrix2 ); - - ; Transform position into world space using all bones - ; denormalize d3dcolor to matrix index - mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index - if ( $g_x360 ) - { - mov $boneIndices, $boneIndices.zyxw - } - - ; r11 = boneindices at this point - ; first matrix - mov a0.x, $boneIndices.z - mul $blendedMatrix0, $vBoneWeights.x, c[a0.x] - mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1] - mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2] - ; second matrix - mov a0.x, $boneIndices.y - mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2 - - ; Calculate third weight - ; compute 1-(weight1+weight2) to calculate weight2 - ; Use $boneIndices.w as a temp since we aren't using it for anything. - add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y - sub $boneIndices.w, $cOne, $boneIndices.w - - ; third matrix - mov a0.x, $boneIndices.x - mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0 - mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1 - mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2 - - ; position - dp4 $worldPos.x, $vPos, $blendedMatrix0 - dp4 $worldPos.y, $vPos, $blendedMatrix1 - dp4 $worldPos.z, $vPos, $blendedMatrix2 - mov $worldPos.w, $cOne - - ; normal - dp3 $worldNormal.x, $vNormal, $blendedMatrix0 - dp3 $worldNormal.y, $vNormal, $blendedMatrix1 - dp3 $worldNormal.z, $vNormal, $blendedMatrix2 - -# X360TBD: needed for compressed vertex format -# if ( $g_x360 ) -# { -# ; tangents -# dp3 $worldTangentS.x, $userData, $blendedMatrix0 -# dp3 $worldTangentS.y, $userData, $blendedMatrix1 -# dp3 $worldTangentS.z, $userData, $blendedMatrix2 -# -# ; calculate tangent t via cross( N, S ) * S[3] -# &Cross( $worldTangentT, $worldNormal, $worldTangentS ); -# mul $worldTangentT.xyz, $userData.w, $worldTangentT.xyz -# } -# else - { - ; tangents - dp3 $worldTangentS.x, $vUserData, $blendedMatrix0 - dp3 $worldTangentS.y, $vUserData, $blendedMatrix1 - dp3 $worldTangentS.z, $vUserData, $blendedMatrix2 - - ; calculate tangent t via cross( N, S ) * S[3] - &Cross( $worldTangentT, $worldNormal, $worldTangentS ); - mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz - } - - &FreeRegister( \$boneIndices ); - &FreeRegister( \$blendedMatrix0 ); - &FreeRegister( \$blendedMatrix1 ); - &FreeRegister( \$blendedMatrix2 ); - } - -# X360TBD: needed for compressed vertex format -# if ( $g_x360 ) -# { -# &FreeRegister( \$userData ); -# } -} - -sub ColorClamp -{ - ; ColorClamp; stomps $color.w - local( $color ) = shift; - local( $dst ) = shift; - - ; Get the max of RGB and stick it in W - max $color.w, $color.x, $color.y - max $color.w, $color.w, $color.z - - ; get the greater of one and the max color. - max $color.w, $color.w, $cOne - - rcp $color.w, $color.w - mul $dst.xyz, $color.w, $color.xyz -} - -sub AmbientLight -{ - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - local( $add ) = shift; - - ; Ambient lighting - &AllocateRegister( \$nSquared ); - &AllocateRegister( \$isNegative ); - - mul $nSquared.xyz, $worldNormal.xyz, $worldNormal.xyz ; compute n times n - slt $isNegative.xyz, $worldNormal.xyz, $cZero ; Figure out whether each component is >0 - mov a0.x, $isNegative.x - if( $add ) - { - mad $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset], $linearColor ; $linearColor = normal[0]*normal[0] * box color of appropriate x side - } - else - { - mul $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset] ; $linearColor = normal[0]*normal[0] * box color of appropriate x side - } - mov a0.x, $isNegative.y - mad $linearColor.xyz, $nSquared.y, c[a0.x + $cAmbientColorPosYOffset], $linearColor - mov a0.x, $isNegative.z - mad $linearColor.xyz, $nSquared.z, c[a0.x + $cAmbientColorPosZOffset], $linearColor - - &FreeRegister( \$isNegative ); - &FreeRegister( \$nSquared ); -} - -sub DirectionalLight -{ - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - local( $add ) = shift; - - &AllocateRegister( \$nDotL ); # FIXME: This only needs to be a scalar - - ; NOTE: Gotta use -l here, since light direction = -l - ; DIRECTIONAL LIGHT - ; compute n dot l - dp3 $nDotL.x, -c[a0.x + 1], $worldNormal - - if ( $HALF_LAMBERT == 0 ) - { - ; lambert - max $nDotL.x, $nDotL.x, c0.x ; Clamp to zero - } - elsif ( $HALF_LAMBERT == 1 ) - { - ; half-lambert - mad $nDotL.x, $nDotL.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5)^2 - mul $nDotL.x, $nDotL.x, $nDotL.x - } - else - { - die "\$HALF_LAMBERT is hosed\n"; - } - - if( $add ) - { - mad $linearColor.xyz, c[a0.x], $nDotL.x, $linearColor - } - else - { - mul $linearColor.xyz, c[a0.x], $nDotL.x - } - - &FreeRegister( \$nDotL ); -} - -sub PointLight -{ - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - local( $add ) = shift; - - local( $lightDir ); - &AllocateRegister( \$lightDir ); - - ; POINT LIGHT - ; compute light direction - sub $lightDir, c[a0.x+2], $worldPos - - local( $lightDistSquared ); - local( $ooLightDist ); - &AllocateRegister( \$lightDistSquared ); - &AllocateRegister( \$ooLightDist ); - - ; normalize light direction, maintain temporaries for attenuation - dp3 $lightDistSquared, $lightDir, $lightDir - rsq $ooLightDist, $lightDistSquared.x - mul $lightDir, $lightDir, $ooLightDist.x - - local( $attenuationFactors ); - &AllocateRegister( \$attenuationFactors ); - - ; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d') - dst $attenuationFactors, $lightDistSquared, $ooLightDist ; r4 = ( 1, d, d*d, 1/d ) - &FreeRegister( \$lightDistSquared ); - &FreeRegister( \$ooLightDist ); - local( $attenuation ); - &AllocateRegister( \$attenuation ); - dp3 $attenuation, $attenuationFactors, c[a0.x+4] ; r3 = atten0 + d * atten1 + d*d * atten2 - - rcp $lightDir.w, $attenuation ; $lightDir.w = 1 / (atten0 + d * atten1 + d*d * atten2) - - &FreeRegister( \$attenuationFactors ); - &FreeRegister( \$attenuation ); - - local( $tmp ); - &AllocateRegister( \$tmp ); # FIXME : really only needs to be a scalar - - ; compute n dot l, fold in distance attenutation - dp3 $tmp.x, $lightDir, $worldNormal - - if ( $HALF_LAMBERT == 0 ) - { - ; lambert - max $tmp.x, $tmp.x, c0.x ; Clamp to zero - } - elsif ( $HALF_LAMBERT == 1 ) - { - ; half-lambert - mad $tmp.x, $tmp.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5)^2 - mul $tmp.x, $tmp.x, $tmp.x - } - else - { - die "\$HALF_LAMBERT is hosed\n"; - } - - mul $tmp.x, $tmp.x, $lightDir.w - if( $add ) - { - mad $linearColor.xyz, c[a0.x], $tmp.x, $linearColor - } - else - { - mul $linearColor.xyz, c[a0.x], $tmp.x - } - - &FreeRegister( \$lightDir ); - &FreeRegister( \$tmp ); # FIXME : really only needs to be a scalar -} - -sub SpotLight -{ - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - local( $add ) = shift; - - local( $lightDir ); - &AllocateRegister( \$lightDir ); - - ; SPOTLIGHT - ; compute light direction - sub $lightDir, c[a0.x+2], $worldPos - - local( $lightDistSquared ); - local( $ooLightDist ); - &AllocateRegister( \$lightDistSquared ); - &AllocateRegister( \$ooLightDist ); - - ; normalize light direction, maintain temporaries for attenuation - dp3 $lightDistSquared, $lightDir, $lightDir - rsq $ooLightDist, $lightDistSquared.x - mul $lightDir, $lightDir, $ooLightDist.x - - local( $attenuationFactors ); - &AllocateRegister( \$attenuationFactors ); - - ; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d') - dst $attenuationFactors, $lightDistSquared, $ooLightDist ; r4 = ( 1, d, d*d, 1/d ) - - &FreeRegister( \$lightDistSquared ); - &FreeRegister( \$ooLightDist ); - local( $attenuation ); &AllocateRegister( \$attenuation ); - - dp3 $attenuation, $attenuationFactors, c[a0.x+4] ; r3 = atten0 + d * atten1 + d*d * atten2 - rcp $lightDir.w, $attenuation ; r1.w = 1 / (atten0 + d * atten1 + d*d * atten2) - - &FreeRegister( \$attenuationFactors ); - &FreeRegister( \$attenuation ); - - local( $litSrc ); &AllocateRegister( \$litSrc ); - local( $tmp ); &AllocateRegister( \$tmp ); # FIXME - only needs to be scalar - - ; compute n dot l - dp3 $litSrc.x, $worldNormal, $lightDir - - if ( $HALF_LAMBERT == 0 ) - { - ; lambert - max $litSrc.x, $litSrc.x, c0.x ; Clamp to zero - } - elsif ( $HALF_LAMBERT == 1 ) - { - ; half-lambert - mad $litSrc.x, $litSrc.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5) ^ 2 - mul $litSrc.x, $litSrc.x, $litSrc.x - } - else - { - die "\$HALF_LAMBERT is hosed\n"; - } - - ; compute angular attenuation - dp3 $tmp.x, c[a0.x+1], -$lightDir ; dot = -delta * spot direction - sub $litSrc.y, $tmp.x, c[a0.x+3].z ; r2.y = dot - stopdot2 - &FreeRegister( \$tmp ); - mul $litSrc.y, $litSrc.y, c[a0.x+3].w ; r2.y = (dot - stopdot2) / (stopdot - stopdot2) - mov $litSrc.w, c[a0.x+3].x ; r2.w = exponent - local( $litDst ); &AllocateRegister( \$litDst ); - lit $litDst, $litSrc ; r3.y = N dot L or 0, whichever is bigger - &FreeRegister( \$litSrc ); - ; r3.z = pow((dot - stopdot2) / (stopdot - stopdot2), exponent) - min $litDst.z, $litDst.z, $cOne ; clamp pow() to 1 - - local( $tmp1 ); &AllocateRegister( \$tmp1 ); - local( $tmp2 ); &AllocateRegister( \$tmp2 ); # FIXME - could be scalar - - ; fold in distance attenutation with other factors - mul $tmp1, c[a0.x], $lightDir.w - mul $tmp2.x, $litDst.y, $litDst.z - if( $add ) - { - mad $linearColor.xyz, $tmp1, $tmp2.x, $linearColor - } - else - { - mul $linearColor.xyz, $tmp1, $tmp2.x - } - - &FreeRegister( \$lightDir ); - &FreeRegister( \$litDst ); - &FreeRegister( \$tmp1 ); - &FreeRegister( \$tmp2 ); -} - -sub DoLight -{ - local( $lightType ) = shift; - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - local( $add ) = shift; - - if( $lightType eq "spot" ) - { - &SpotLight( $worldPos, $worldNormal, $linearColor, $add ); - } - elsif( $lightType eq "point" ) - { - &PointLight( $worldPos, $worldNormal, $linearColor, $add ); - } - elsif( $lightType eq "directional" ) - { - &DirectionalLight( $worldNormal, $linearColor, $add ); - } - else - { - die "don't know about light type \"$lightType\"\n"; - } -} - -sub DoLighting -{ - if( !defined $LIGHT_COMBO ) - { - die "DoLighting called without using \$LIGHT_COMBO\n"; - } - if ( !defined $HALF_LAMBERT ) - { - die "DoLighting called without using \$HALF_LAMBERT\n"; - } - - my $staticLightType = $g_staticLightTypeArray[$LIGHT_COMBO]; - my $ambientLightType = $g_ambientLightTypeArray[$LIGHT_COMBO]; - my $localLightType1 = $g_localLightType1Array[$LIGHT_COMBO]; - my $localLightType2 = $g_localLightType2Array[$LIGHT_COMBO]; - -# print "\$staticLightType = $staticLightType\n"; -# print "\$ambientLightType = $ambientLightType\n"; -# print "\$localLightType1 = $localLightType1\n"; -# print "\$localLightType2 = $localLightType2\n"; - - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - - ; special case for no lighting - if( $staticLightType eq "none" && $ambientLightType eq "none" && - $localLightType1 eq "none" && $localLightType2 eq "none" ) - { - ; Have to write something here since debug d3d runtime will barf otherwise. - mov oD0, $cOne - return; - } - - ; special case for static lighting only - ; Don't need to bother converting to linear space in this case. - if( $staticLightType eq "static" && $ambientLightType eq "none" && - $localLightType1 eq "none" && $localLightType2 eq "none" ) - { - mov oD0, $vSpecular - return; - } - - alloc $linearColor - alloc $gammaColor - - local( $add ) = 0; - if( $staticLightType eq "static" ) - { - ; The static lighting comes in in gamma space and has also been premultiplied by $cOverbrightFactor - ; need to get it into - ; linear space so that we can do adds. - rcp $gammaColor.w, $cOverbrightFactor - mul $gammaColor.xyz, $vSpecular, $gammaColor.w - &GammaToLinear( $gammaColor, $linearColor ); - $add = 1; - } - - if( $ambientLightType eq "ambient" ) - { - &AmbientLight( $worldNormal, $linearColor, $add ); - $add = 1; - } - - if( $localLightType1 ne "none" ) - { - mov a0.x, $cLight0Offset - &DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add ); - $add = 1; - } - - if( $localLightType2 ne "none" ) - { - mov a0.x, $cLight1Offset - &DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add ); - $add = 1; - } - - ;------------------------------------------------------------------------------ - ; Output color (gamma correction) - ;------------------------------------------------------------------------------ - - &LinearToGamma( $linearColor, $gammaColor ); - if( 0 ) - { - mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor - } - else - { - mul $gammaColor.xyz, $gammaColor.xyz, $cOverbrightFactor - &ColorClamp( $gammaColor, "oD0" ); - } - -; mov oD0.xyz, $linearColor - mov oD0.w, $cOne ; make sure all components are defined - - free $linearColor - free $gammaColor -} - -sub DoDynamicLightingToLinear -{ - local( $worldPos ) = shift; - local( $worldNormal ) = shift; - local( $linearColor ) = shift; - - if( !defined $LIGHT_COMBO ) - { - die "DoLighting called without using \$LIGHT_COMBO\n"; - } - if ( !defined $HALF_LAMBERT ) - { - die "DoLighting called without using \$HALF_LAMBERT\n"; - } - - my $staticLightType = $g_staticLightTypeArray[$LIGHT_COMBO]; - my $ambientLightType = $g_ambientLightTypeArray[$LIGHT_COMBO]; - my $localLightType1 = $g_localLightType1Array[$LIGHT_COMBO]; - my $localLightType2 = $g_localLightType2Array[$LIGHT_COMBO]; - - # No lights at all. . note that we don't even consider static lighting here. - if( $ambientLightType eq "none" && - $localLightType1 eq "none" && $localLightType2 eq "none" ) - { - mov $linearColor, $cZero - return; - } - - local( $add ) = 0; - if( $ambientLightType eq "ambient" ) - { - &AmbientLight( $worldNormal, $linearColor, $add ); - $add = 1; - } - - if( $localLightType1 ne "none" ) - { - mov a0.x, $cLight0Offset - &DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add ); - $add = 1; - } - - if( $localLightType2 ne "none" ) - { - mov a0.x, $cLight1Offset - &DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add ); - $add = 1; - } -} - -sub NotImplementedYet -{ - &AllocateRegister( \$projPos ); - dp4 $projPos.x, $worldPos, $cViewProj0 - dp4 $projPos.y, $worldPos, $cViewProj1 - dp4 $projPos.z, $worldPos, $cViewProj2 - dp4 $projPos.w, $worldPos, $cViewProj3 - mov oPos, $projPos - &FreeRegister( \$projPos ); - exit; -} diff --git a/materialsystem/stdshaders/makefile._shaderlist_dx9_20b.copy b/materialsystem/stdshaders/makefile._shaderlist_dx9_20b.copy deleted file mode 100644 index d4106cc9..00000000 --- a/materialsystem/stdshaders/makefile._shaderlist_dx9_20b.copy +++ /dev/null @@ -1,3 +0,0 @@ -depthwrite_ps2x.fxc-----depthwrite_ps20 -depthwrite_ps2x.fxc-----depthwrite_ps20b -depthwrite_vs20.fxc-----depthwrite_vs20 diff --git a/materialsystem/stdshaders/makefile._shaderlist_dx9_30.copy b/materialsystem/stdshaders/makefile._shaderlist_dx9_30.copy deleted file mode 100644 index 2f4b447e..00000000 --- a/materialsystem/stdshaders/makefile._shaderlist_dx9_30.copy +++ /dev/null @@ -1,47 +0,0 @@ -unsharp_blur_ps2x.fxc-----unsharp_blur_ps30 -unsharp_blur_vs20.fxc-----unsharp_blur_vs30 -unsharp_ps2x.fxc-----unsharp_ps30 -unsharp_vs20.fxc-----unsharp_vs30 -fxaa_ps30.fxc-----fxaa_ps30 -fxaa_vs30.fxc-----fxaa_vs30 -luma_ps30.fxc-----luma_ps30 -lightmappedgeneric_ps30.fxc-----lightmappedgeneric_ps30 -lightmappedgeneric_vs30.fxc-----lightmappedgeneric_vs30 -flashlight_ps2x.fxc-----flashlight_ps30 -lightmappedgeneric_flashlight_vs20.fxc-----lightmappedgeneric_flashlight_vs30 -screenspace_simple_vs30.fxc-----screenspace_simple_vs30 -SDK_screenspaceeffect_vs20.fxc-----SDK_screenspaceeffect_vs30 -gaussianx_ps2x.fxc-----gaussianx_ps30 -gaussiany_ps2x.fxc-----gaussiany_ps30 -gaussian_depthaware_ps30.fxc-----gaussian_depthaware_ps30 -gaussian_depthaware_roughness_ps30.fxc-----gaussian_depthaware_roughness_ps30 -vance_bloom_combine_ps30.fxc-----vance_bloom_combine_ps30 -Vance_Tonemap_ps30.fxc-----Vance_Tonemap_ps30 -chromatic_ps2x.fxc-----chromatic_ps30 -chromatic_vs20.fxc-----chromatic_vs30 -screenwater_ps2x.fxc-----screenwater_ps30 -screenwater_vs20.fxc-----screenwater_vs30 -skydome_ps30.fxc-----skydome_ps30 -skydome_vs30.fxc-----skydome_vs30 -ssgi_ps30.fxc-----ssgi_ps30 -ssgi_combine_ps30.fxc-----ssgi_combine_ps30 -ssr_ps30.fxc-----ssr_ps30 -vertexlit_and_unlit_generic_ps30.fxc-----vertexlit_and_unlit_generic_ps30 -vertexLit_and_unlit_Generic_vs30.fxc-----vertexLit_and_unlit_Generic_vs30 -vertexlit_and_unlit_generic_bump_ps30.fxc-----vertexlit_and_unlit_generic_bump_ps30 -VertexlitPBR_ps30.fxc-----VertexlitPBR_ps30 -vertexlitPBR_vs30.fxc-----vertexlitPBR_vs30 -lightmappedPBR_ps30.fxc-----lightmappedPBR_ps30 -lightmappedPBR_vs30.fxc-----lightmappedPBR_vs30 -lightpass_ps30.fxc-----lightpass_ps30 -lightpass_vs30.fxc-----lightpass_vs30 -normalmapreconstruct_ps30.fxc-----normalmapreconstruct_ps30 -light_volumetrics_ps20b.fxc-----light_volumetrics_ps30 -light_volumetrics_vs20.fxc-----light_volumetrics_vs30 -vance_scope_ps30.fxc-----vance_scope_ps30 -vance_scope_vs30.fxc-----vance_scope_vs30 -lpreview1_ps2x.fxc-----lpreview1_ps30 -depthwrite_ps2x.fxc-----depthwrite_ps30 -passthru_vs20.fxc-----passthru_vs30 -light_mesh_ps30.fxc-----light_mesh_ps30 -light_mesh_vs30.fxc-----light_mesh_vs30 diff --git a/materialsystem/stdshaders/monitorscreen.cpp b/materialsystem/stdshaders/monitorscreen.cpp new file mode 100644 index 00000000..d596fd38 --- /dev/null +++ b/materialsystem/stdshaders/monitorscreen.cpp @@ -0,0 +1,159 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "basevsshader.h" +#include "sdk_unlittwotexture_vs30.inc" +#include "sdk_monitorscreen_ps30.inc" +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( MonitorScreen, "This is a shader that does a contrast/saturation version of base times lightmap." ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( CONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( SATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( TINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "monitor tint" ) + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "second texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" ) + SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" ) + END_SHADER_PARAMS + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + if( !params[CONTRAST]->IsDefined() ) + { + params[CONTRAST]->SetFloatValue( 0.0f ); + } + if( !params[SATURATION]->IsDefined() ) + { + params[SATURATION]->SetFloatValue( 1.0f ); + } + if( !params[TINT]->IsDefined() ) + { + params[TINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if (!IS_FLAG_DEFINED( MATERIAL_VAR_MODEL )) + { + CLEAR_FLAGS( MATERIAL_VAR_MODEL ); + } + } + + SHADER_FALLBACK + { + if( params && !params[BASETEXTURE]->IsDefined() ) + return "SDK_LightmappedGeneric"; + + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + if (params[TEXTURE2]->IsDefined()) + { + LoadTexture( TEXTURE2 ); + } + } + + SHADER_DRAW + { + bool bHasTexture2 = params[TEXTURE2]->IsTexture(); + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + if ( bHasTexture2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a texture alpha on either texture + isTranslucent = isTranslucent || TextureIsTranslucent( BASETEXTURE, true ) || + TextureIsTranslucent( TEXTURE2, true ); + + if ( isTranslucent ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + else + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + else + DisableAlphaBlending( ); + } + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE2, (bHasTexture2)?(1):(0) ); + SET_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps30 ); + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + if( bHasTexture2 ) + { + BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, TEXTURE2TRANSFORM ); + } + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetPixelShaderConstant( 1, CONTRAST ); + SetPixelShaderConstant( 2, SATURATION ); + SetPixelShaderConstant( 3, TINT ); + SetModulationVertexShaderDynamicState(); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps30 ); + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/passthru_vs20.fxc b/materialsystem/stdshaders/passthru_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/passthru_vs20.fxc rename to materialsystem/stdshaders/passthru_vs30.fxc diff --git a/materialsystem/stdshaders/refract.cpp b/materialsystem/stdshaders/refract.cpp index 852e93a5..ccadb7b2 100644 --- a/materialsystem/stdshaders/refract.cpp +++ b/materialsystem/stdshaders/refract.cpp @@ -5,13 +5,11 @@ // $NoKeywords: $ //=============================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" -#include "refract_dx9_helper.h" +#include "refract_helper.h" -DEFINE_FALLBACK_SHADER( Refract, Refract_DX90 ) - -BEGIN_VS_SHADER( Refract_DX90, "Help for Refract" ) +BEGIN_VS_SHADER( Refract, "Help for Refract" ) BEGIN_SHADER_PARAMS SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) diff --git a/materialsystem/stdshaders/refract_dx60.cpp b/materialsystem/stdshaders/refract_dx60.cpp deleted file mode 100644 index 2ca7a83c..00000000 --- a/materialsystem/stdshaders/refract_dx60.cpp +++ /dev/null @@ -1,16 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// FIXME: This is a placeholder. . need to do something for real here. -DEFINE_FALLBACK_SHADER( Refract, Refract_DX60 ) -DEFINE_FALLBACK_SHADER( Refract_DX60, UnlitGeneric ) - - diff --git a/materialsystem/stdshaders/refract_dx80.cpp b/materialsystem/stdshaders/refract_dx80.cpp deleted file mode 100644 index b6e6e5a0..00000000 --- a/materialsystem/stdshaders/refract_dx80.cpp +++ /dev/null @@ -1,317 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - - -#include "BaseVSShader.h" - -#include "refract_model_vs11.inc" -#include "refract_world_vs11.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define MAXBLUR 1 - -DEFINE_FALLBACK_SHADER( Refract, Refract_DX80 ) - -BEGIN_VS_SHADER( Refract_DX80, - "Help for Refract_DX80" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) - SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) - SHADER_PARAM( DUDVMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_dudv", "dudv bump map" ) - SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( DUDVFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $dudvmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) - SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_INTEGER, "1", "0, 1, or 2 for how much blur you want" ) - SHADER_PARAM( FADEOUTONSILHOUETTE, SHADER_PARAM_TYPE_BOOL, "1", "0 for no fade out on silhouette, 1 for fade out on sillhouette" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" ) - SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) - SHADER_PARAM( FALLBACK, SHADER_PARAM_TYPE_STRING, "", "Name of the fallback shader" ) - SHADER_PARAM( FORCEREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Forces refraction on boards that have poor performance" ) - SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" ) - SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); - if( !params[ENVMAPTINT]->IsDefined() ) - { - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - if( !params[ENVMAPCONTRAST]->IsDefined() ) - { - params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); - } - if( !params[ENVMAPSATURATION]->IsDefined() ) - { - params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); - } - if( !params[ENVMAPFRAME]->IsDefined() ) - { - params[ENVMAPFRAME]->SetIntValue( 0 ); - } - if( !params[FRESNELREFLECTION]->IsDefined() ) - { - params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); - } - if( !params[MASKED]->IsDefined() ) - { - params[MASKED]->SetIntValue( 0 ); - } - if( !params[BLURAMOUNT]->IsDefined() ) - { - params[BLURAMOUNT]->SetIntValue( 0 ); - } - if( !params[FADEOUTONSILHOUETTE]->IsDefined() ) - { - params[FADEOUTONSILHOUETTE]->SetIntValue( 0 ); - } - SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); - } - - SHADER_FALLBACK - { - if ( IsPC() ) - { - const char *pFallback = (params && params[FALLBACK]->IsDefined()) ? params[FALLBACK]->GetStringValue() : ""; - if (!pFallback[0]) - { - pFallback = "Refract_DX60"; - } - - if( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) - return pFallback; - - if ( g_pHardwareConfig->PreferReducedFillrate() && (params && (params[FORCEREFRACT]->GetIntValue() == 0)) ) - return pFallback; - } - - return 0; - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - if (params[DUDVMAP]->IsDefined() ) - { - LoadTexture( DUDVMAP ); - } - if (params[NORMALMAP]->IsDefined() ) - { - LoadBumpMap( NORMALMAP ); - } - if( params[ENVMAP]->IsDefined() ) - { - LoadCubeMap( ENVMAP ); - } - if( params[REFRACTTINTTEXTURE]->IsDefined() ) - { - LoadTexture( REFRACTTINTTEXTURE ); - } - } - - inline int ComputePixelShaderIndex( bool bRefractTintTexture, bool bNormalMapAlpha ) - { - // "REFRACTTINTTEXTURE" "0..1" - // "NORMALMAPALPHA" "0..1" - int pshIndex = 0; - if( bRefractTintTexture ) pshIndex |= 0x1; - if( bNormalMapAlpha ) pshIndex |= 0x2; - return pshIndex; - } - - SHADER_DRAW - { - bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); - bool bHasEnvmap = params[ENVMAP]->IsTexture(); - int blurAmount = params[BLURAMOUNT]->GetIntValue(); - bool bRefractTintTexture = params[REFRACTTINTTEXTURE]->IsTexture(); - if( blurAmount < 0 ) - { - blurAmount = 0; - } - else if( blurAmount > MAXBLUR ) - { - blurAmount = MAXBLUR; - } - bool bMasked = (params[MASKED]->GetIntValue() != 0); - - SHADOW_STATE - { - if ( params[NOWRITEZ]->GetIntValue() != 0 ) - { - pShaderShadow->EnableDepthWrites( false ); - } - - // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - // If envmap is not specified, the alpha channel is the translucency - // (If envmap *is* specified, alpha channel is the reflection amount) - bool bNormalMapAlpha = false; - if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap ) - { - SetDefaultBlendingShadowState( NORMALMAP, false ); - if ( !bMasked && TextureIsTranslucent( NORMALMAP, false ) ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - bNormalMapAlpha = true; - } - } - - // dudv map - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // renderable texture for refraction - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - if( bRefractTintTexture ) - { - // refract tint texture - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - } - - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - int userDataSize = 0; - if( bIsModel ) - { - userDataSize = 4; - } - else - { - fmt |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; - } - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, userDataSize ); - - if( bIsModel ) - { - refract_model_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Refract_model_vs11", vshIndex.GetIndex() ); - } - else - { - refract_world_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Refract_world_vs11", vshIndex.GetIndex() ); - } - - int pshIndex; - pshIndex = ComputePixelShaderIndex( bRefractTintTexture, bNormalMapAlpha ); - pShaderShadow->SetPixelShader( "Refract_ps11", pshIndex ); - - if( bMasked ) - { - EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - } - DefaultFog(); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); - - if ( params[DUDVFRAME]->GetIntValue() == 0 ) - { - BindTexture( SHADER_SAMPLER0, DUDVMAP, BUMPFRAME ); - } - else - { - BindTexture( SHADER_SAMPLER0, DUDVMAP, DUDVFRAME ); - } - - if ( params[BASETEXTURE]->IsTexture() ) - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); - } - - if( bRefractTintTexture ) - { - BindTexture( SHADER_SAMPLER2, REFRACTTINTTEXTURE, REFRACTTINTTEXTUREFRAME ); - } - - if ( params[NORMALMAP]->IsTexture() ) - { - BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); - } - - float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); - pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - - // used to invert y - // xboxfixme - move this into defined constants - float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); - - SetPixelShaderConstant( 0, REFRACTTINT ); - if( bIsModel ) - { - refract_model_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - refract_world_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - - Draw(); - - if( bHasEnvmap ) - { - bool bNoWriteZ = (params[NOWRITEZ]->GetIntValue() != 0); - const bool bBlendSpecular = true; - if( bIsModel ) - { - DrawModelBumpedSpecularLighting( NORMALMAP, BUMPFRAME, - ENVMAP, ENVMAPFRAME, - ENVMAPTINT, ALPHA, - ENVMAPCONTRAST, ENVMAPSATURATION, - BUMPTRANSFORM, - bBlendSpecular, bNoWriteZ ); - } - else - { - DrawWorldBumpedSpecularLighting( NORMALMAP, ENVMAP, - BUMPFRAME, ENVMAPFRAME, - ENVMAPTINT, ALPHA, - ENVMAPCONTRAST, ENVMAPSATURATION, - BUMPTRANSFORM, FRESNELREFLECTION, - bBlendSpecular, bNoWriteZ ); - } - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/refract_dx9_helper.cpp b/materialsystem/stdshaders/refract_dx9_helper.cpp deleted file mode 100644 index f436e62a..00000000 --- a/materialsystem/stdshaders/refract_dx9_helper.cpp +++ /dev/null @@ -1,342 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "refract_dx9_helper.h" -#include "convar.h" -#include "Refract_vs20.inc" -#include "Refract_ps20.inc" -#include "Refract_ps20b.inc" -#include "cpp_shader_constant_register_map.h" - -#define MAXBLUR 1 - -// FIXME: doesn't support fresnel! -void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Refract_DX9_Vars_t &info ) -{ - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); - if( !params[info.m_nEnvmapTint]->IsDefined() ) - { - params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - if( !params[info.m_nEnvmapContrast]->IsDefined() ) - { - params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); - } - if( !params[info.m_nEnvmapSaturation]->IsDefined() ) - { - params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); - } - if( !params[info.m_nEnvmapFrame]->IsDefined() ) - { - params[info.m_nEnvmapFrame]->SetIntValue( 0 ); - } - if( !params[info.m_nFresnelReflection]->IsDefined() ) - { - params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); - } - if( !params[info.m_nMasked]->IsDefined() ) - { - params[info.m_nMasked]->SetIntValue( 0 ); - } - if( !params[info.m_nBlurAmount]->IsDefined() ) - { - params[info.m_nBlurAmount]->SetIntValue( 0 ); - } - if( !params[info.m_nFadeOutOnSilhouette]->IsDefined() ) - { - params[info.m_nFadeOutOnSilhouette]->SetIntValue( 0 ); - } - if( !params[info.m_nForceAlphaWrite]->IsDefined() ) - { - params[info.m_nForceAlphaWrite]->SetIntValue( 0 ); - } - SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); -} - -void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ) -{ - if (params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - } - if (params[info.m_nNormalMap]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nNormalMap ); - } - if (params[info.m_nNormalMap2]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nNormalMap2 ); - } - if( params[info.m_nEnvmap]->IsDefined() ) - { - pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); - } - if( params[info.m_nRefractTintTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nRefractTintTexture, TEXTUREFLAGS_SRGB ); - } -} - -void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) -{ - bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); - bool bHasEnvmap = params[info.m_nEnvmap]->IsTexture(); - bool bRefractTintTexture = params[info.m_nRefractTintTexture]->IsTexture(); - bool bFadeOutOnSilhouette = params[info.m_nFadeOutOnSilhouette]->GetIntValue() != 0; - int blurAmount = params[info.m_nBlurAmount]->GetIntValue(); - bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0); - bool bSecondaryNormal = ( ( info.m_nNormalMap2 != -1 ) && ( params[info.m_nNormalMap2]->IsTexture() ) ); - bool bColorModulate = ( ( info.m_nVertexColorModulate != -1 ) && ( params[info.m_nVertexColorModulate]->GetIntValue() ) ); - bool bWriteZ = params[info.m_nNoWriteZ]->GetIntValue() == 0; - - if( blurAmount < 0 ) - { - blurAmount = 0; - } - else if( blurAmount > MAXBLUR ) - { - blurAmount = MAXBLUR; - } - - BlendType_t nBlendType = pShader->EvaluateBlendRequirements( BASETEXTURE, true ); - bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use - bFullyOpaque &= !bMasked; - - bool bTranslucentNormal = pShader->TextureIsTranslucent( info.m_nNormalMap, false ); - bFullyOpaque &= (! bTranslucentNormal ); - - NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; - if ( g_pHardwareConfig->SupportsNormalMapCompression() ) - { - ITexture *pBumpTex = params[info.m_nNormalMap]->GetTextureValue(); - if ( pBumpTex ) - { - nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); - - if ( bSecondaryNormal ) // Check encoding of secondary normal if there is one - { - ITexture *pBumpTex2 = params[info.m_nNormalMap2]->GetTextureValue(); - if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) - { - DevMsg("Refract: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); - Assert(0); - } - } - } - } - - SHADOW_STATE - { - pShader->SetInitialShadowState( ); - - pShaderShadow->EnableDepthWrites( bWriteZ ); - - // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - // If envmap is not specified, the alpha channel is the translucency - // (If envmap *is* specified, alpha channel is the reflection amount) - if ( params[info.m_nNormalMap]->IsTexture() && !bHasEnvmap ) - { - pShader->SetDefaultBlendingShadowState( info.m_nNormalMap, false ); - } - - // source render target that contains the image that we are warping. - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); - - // normal map - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Normal map alpha, in the compressed normal case - } - - if ( bSecondaryNormal ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Secondary normal map alpha, in the compressed normal case - } - } - - if( bHasEnvmap ) - { - // envmap - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); - } - if( bRefractTintTexture ) - { - // refract tint texture - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); - } - - pShaderShadow->EnableSRGBWrite( true ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int userDataSize = 0; - int nTexCoordCount = 1; - if( bIsModel ) - { - userDataSize = 4; - } - else - { - flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; - } - - if ( bColorModulate ) - { - flags |= VERTEX_COLOR; - } - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( refract_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); - SET_STATIC_VERTEX_SHADER_COMBO( COLORMODULATE, bColorModulate ); - SET_STATIC_VERTEX_SHADER( refract_vs20 ); - - // We have to do this in the shader on R500 or Leopard - bool bShaderSRGBConvert = IsOSX() && ( g_pHardwareConfig->FakeSRGBWrite() || !g_pHardwareConfig->CanDoSRGBReadFromRTs() ); - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send OpenGL down the ps2b path - { - DECLARE_STATIC_PIXEL_SHADER( refract_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); - SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); - SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); - SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSRGBConvert ); - SET_STATIC_PIXEL_SHADER( refract_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( refract_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); - SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); - SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); - SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER( refract_ps20 ); - } - pShader->DefaultFog(); - if( bMasked ) - { - pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - } - - bool bAlphaWrites = bFullyOpaque || ( params[ info.m_nForceAlphaWrite ]->GetIntValue() != 0 ); - pShaderShadow->EnableAlphaWrites( bAlphaWrites ); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - - if ( params[info.m_nBaseTexture]->IsTexture() ) - { - pShader->BindTexture( SHADER_SAMPLER2, info.m_nBaseTexture, info.m_nFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); - } - - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShader->BindTexture( SHADER_SAMPLER3, SHADER_SAMPLER6, info.m_nNormalMap, info.m_nBumpFrame ); - } - else - { - pShader->BindTexture( SHADER_SAMPLER3, info.m_nNormalMap, info.m_nBumpFrame ); - } - - if ( bSecondaryNormal ) - { - if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) - { - pShader->BindTexture( SHADER_SAMPLER1, SHADER_SAMPLER7, info.m_nNormalMap2, info.m_nBumpFrame2 ); - } - else - { - pShader->BindTexture( SHADER_SAMPLER1, info.m_nNormalMap2, info.m_nBumpFrame2 ); - } - } - - if( bHasEnvmap ) - { - pShader->BindTexture( SHADER_SAMPLER4, info.m_nEnvmap, info.m_nEnvmapFrame ); - } - - if( bRefractTintTexture ) - { - pShader->BindTexture( SHADER_SAMPLER5, info.m_nRefractTintTexture, info.m_nRefractTintTextureFrame ); - } - - DECLARE_DYNAMIC_VERTEX_SHADER( refract_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( refract_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send Posix down the ps2b path - { - DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( refract_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( refract_ps20 ); - } - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform ); // 1 & 2 - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBumpTransform2 ); // 3 & 4 - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - pShader->SetPixelShaderConstantGammaToLinear( 0, info.m_nEnvmapTint ); - pShader->SetPixelShaderConstantGammaToLinear( 1, info.m_nRefractTint ); - pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); - pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation ); - float c5[4] = { params[info.m_nRefractAmount]->GetFloatValue(), - params[info.m_nRefractAmount]->GetFloatValue(), 0.0f, 0.0f }; - - // Time % 1000 - c5[3] = pShaderAPI->CurrentTime(); - c5[3] -= (float)( (int)( c5[3] / 1000.0f ) ) * 1000.0f; - pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); - - float cVs3[4] = { c5[3], 0.0f, 0.0f, 0.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, cVs3, 1 ); - } - pShader->Draw(); -} - diff --git a/materialsystem/stdshaders/refract_helper.cpp b/materialsystem/stdshaders/refract_helper.cpp new file mode 100644 index 00000000..b5a1b891 --- /dev/null +++ b/materialsystem/stdshaders/refract_helper.cpp @@ -0,0 +1,327 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "basevsshader.h" +#include "refract_helper.h" +#include "convar.h" +#include "sdk_refract_vs30.inc" +#include "sdk_refract_ps30.inc" +#include "cpp_shader_constant_register_map.h" + +#define MAXBLUR 1 + +// FIXME: doesn't support fresnel! +void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Refract_DX9_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + { + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + } + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + { + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + { + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + } + if( !params[info.m_nFresnelReflection]->IsDefined() ) + { + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nMasked]->IsDefined() ) + { + params[info.m_nMasked]->SetIntValue( 0 ); + } + if( !params[info.m_nBlurAmount]->IsDefined() ) + { + params[info.m_nBlurAmount]->SetIntValue( 0 ); + } + if( !params[info.m_nFadeOutOnSilhouette]->IsDefined() ) + { + params[info.m_nFadeOutOnSilhouette]->SetIntValue( 0 ); + } + if( !params[info.m_nForceAlphaWrite]->IsDefined() ) + { + params[info.m_nForceAlphaWrite]->SetIntValue( 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); +} + +void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ) +{ + if (params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + } + if (params[info.m_nNormalMap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap ); + } + if (params[info.m_nNormalMap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap2 ); + } + if( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); + +#ifdef MAPBASE + if (mat_specular_disable_on_missing.GetBool()) + { + // Revert to defaultcubemap when the envmap texture is missing + // (should be equivalent to toolsblack in Mapbase) + if (!IS_FLAG_SET( MATERIAL_VAR_MODEL ) && params[info.m_nEnvmap]->GetTextureValue()->IsError()) + { + params[info.m_nEnvmap]->SetStringValue( "engine/defaultcubemap" ); + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); + } + } +#endif + } + if( params[info.m_nRefractTintTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nRefractTintTexture, TEXTUREFLAGS_SRGB ); + } +} + +void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[info.m_nEnvmap]->IsTexture(); + bool bRefractTintTexture = params[info.m_nRefractTintTexture]->IsTexture(); + bool bFadeOutOnSilhouette = params[info.m_nFadeOutOnSilhouette]->GetIntValue() != 0; + int blurAmount = params[info.m_nBlurAmount]->GetIntValue(); + bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0); + bool bSecondaryNormal = ( ( info.m_nNormalMap2 != -1 ) && ( params[info.m_nNormalMap2]->IsTexture() ) ); + bool bColorModulate = ( ( info.m_nVertexColorModulate != -1 ) && ( params[info.m_nVertexColorModulate]->GetIntValue() ) ); + bool bWriteZ = params[info.m_nNoWriteZ]->GetIntValue() == 0; + + if( blurAmount < 0 ) + { + blurAmount = 0; + } + else if( blurAmount > MAXBLUR ) + { + blurAmount = MAXBLUR; + } + + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + bFullyOpaque &= !bMasked; + + bool bTranslucentNormal = pShader->TextureIsTranslucent( info.m_nNormalMap, false ); + bFullyOpaque &= (! bTranslucentNormal ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pBumpTex = params[info.m_nNormalMap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( bSecondaryNormal ) // Check encoding of secondary normal if there is one + { + ITexture *pBumpTex2 = params[info.m_nNormalMap2]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("Refract: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + + SHADOW_STATE + { + pShader->SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( bWriteZ ); + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + if ( params[info.m_nNormalMap]->IsTexture() && !bHasEnvmap ) + { + pShader->SetDefaultBlendingShadowState( info.m_nNormalMap, false ); + } + + // source render target that contains the image that we are warping. + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Normal map alpha, in the compressed normal case + } + + if ( bSecondaryNormal ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Secondary normal map alpha, in the compressed normal case + } + } + + if( bHasEnvmap ) + { + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bRefractTintTexture ) + { + // refract tint texture + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + int nTexCoordCount = 1; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + + if ( bColorModulate ) + { + flags |= VERTEX_COLOR; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_refract_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); + SET_STATIC_VERTEX_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_VERTEX_SHADER( sdk_refract_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_refract_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); + SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); + SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, 0 ); + SET_STATIC_PIXEL_SHADER( sdk_refract_ps30 ); + + pShader->DefaultFog(); + if( bMasked ) + { + pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + } + + bool bAlphaWrites = bFullyOpaque || ( params[ info.m_nForceAlphaWrite ]->GetIntValue() != 0 ); + pShaderShadow->EnableAlphaWrites( bAlphaWrites ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + if ( params[info.m_nBaseTexture]->IsTexture() ) + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nBaseTexture, info.m_nFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER3, SHADER_SAMPLER6, info.m_nNormalMap, info.m_nBumpFrame ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER3, info.m_nNormalMap, info.m_nBumpFrame ); + } + + if ( bSecondaryNormal ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER1, SHADER_SAMPLER7, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + } + + if( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER4, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + if( bRefractTintTexture ) + { + pShader->BindTexture( SHADER_SAMPLER5, info.m_nRefractTintTexture, info.m_nRefractTintTextureFrame ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_refract_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_refract_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_refract_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_refract_ps30 ); + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform ); // 1 & 2 + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBumpTransform2 ); // 3 & 4 + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + pShader->SetPixelShaderConstantGammaToLinear( 0, info.m_nEnvmapTint ); + pShader->SetPixelShaderConstantGammaToLinear( 1, info.m_nRefractTint ); + pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation ); + float c5[4] = { params[info.m_nRefractAmount]->GetFloatValue(), + params[info.m_nRefractAmount]->GetFloatValue(), 0.0f, 0.0f }; + + // Time % 1000 + c5[3] = pShaderAPI->CurrentTime(); + c5[3] -= (float)( (int)( c5[3] / 1000.0f ) ) * 1000.0f; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + float cVs3[4] = { c5[3], 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, cVs3, 1 ); + } + pShader->Draw(); +} + diff --git a/materialsystem/stdshaders/refract_dx9_helper.h b/materialsystem/stdshaders/refract_helper.h similarity index 100% rename from materialsystem/stdshaders/refract_dx9_helper.h rename to materialsystem/stdshaders/refract_helper.h diff --git a/materialsystem/stdshaders/refract_ps2x.fxc b/materialsystem/stdshaders/refract_ps2x.fxc deleted file mode 100644 index 2f974230..00000000 --- a/materialsystem/stdshaders/refract_ps2x.fxc +++ /dev/null @@ -1,250 +0,0 @@ -//====== Copyright 1996-2007, Valve Corporation, All rights reserved. ======= -// -//============================================================================= - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "BLUR" "0..1" -// STATIC: "FADEOUTONSILHOUETTE" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "REFRACTTINTTEXTURE" "0..1" -// STATIC: "MASKED" "0..1" -// STATIC: "COLORMODULATE" "0..1" -// STATIC: "SECONDARY_NORMAL" "0..1" -// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] -// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] -// STATIC: "SHADER_SRGB_READ" "0..1" [ps20b] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] - -// SKIP: $MASKED && $BLUR - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -sampler NormalSampler2 : register( s1 ); -sampler RefractSampler : register( s2 ); -sampler NormalSampler : register( s3 ); -#if CUBEMAP -sampler EnvmapSampler : register( s4 ); -#endif -#if REFRACTTINTTEXTURE -sampler RefractTintSampler : register( s5 ); -#endif - -#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA -sampler AlphaMapSampler : register( s6 ); // alpha -sampler AlphaMapSampler2 : register( s7 ); -#else -#define AlphaMapSampler2 NormalSampler -#define AlphaMapSampler NormalSampler2 -#endif - -const float3 g_EnvmapTint : register( c0 ); -const float3 g_RefractTint : register( c1 ); -const float3 g_EnvmapContrast : register( c2 ); -const float3 g_EnvmapSaturation : register( c3 ); -const float4 g_c5 : register( c5 ); -#define g_RefractScale g_c5.x -#define g_flTime g_c5.w - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - -static const int g_BlurCount = BLUR; -static const float g_BlurFraction = 1.0f / 512.0f; -static const float g_HalfBlurFraction = 0.5 * g_BlurFraction; -static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction, - -g_BlurFraction,-g_HalfBlurFraction ); - -struct PS_INPUT -{ - float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz - float3 vTangentVertToEyeVector : TEXCOORD1; - float3 vWorldNormal : TEXCOORD2; - float3 vWorldTangent : TEXCOORD3; - float3 vWorldBinormal : TEXCOORD4; - float3 vRefractXYW : TEXCOORD5; - float3 vWorldViewVector : TEXCOORD6; -#if COLORMODULATE - float4 ColorModulate : COLOR0; -#endif - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog - float4 fogFactorW : COLOR1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float3 result; - - float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - -#if FADEOUTONSILHOUETTE - //float blend = -i.projNormal.z; - float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) ); - blend = blend * blend * blend; -#else - float blend = 1.0f; -#endif - - // Decompress normal - float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORMAL_DECODE_MODE, AlphaMapSampler ); - -#if SECONDARY_NORMAL - float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORMAL_DECODE_MODE, AlphaMapSampler2 ); - vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz ); -#endif - -#if REFRACTTINTTEXTURE - float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy ); -#else - float3 refractTintColor = g_RefractTint; -#endif - -#if COLORMODULATE - refractTintColor *= i.ColorModulate.rgb; -#endif - - // Perform division by W only once - float ooW = 1.0f / i.vRefractXYW.z; - - // Compute coordinates for sampling refraction - float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; - float2 vRefractTexCoord = vNormal.xy; - float scale = vNormal.a * g_RefractScale; -#if COLORMODULATE - scale *= i.ColorModulate.a; -#endif - vRefractTexCoord *= scale; - vRefractTexCoord += vRefractTexCoordNoWarp; - -#if (BLUR==1) // use polyphase magic to convert 9 lookups into 4 - - // basic principle behind this transformation: - // [ A B C ] - // [ D E F ] - // [ G H I ] - // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]). - // scale the upper 2x2 by 4/9 (total area of kernel occupied) - // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F]) - // scale right 1x2 by 2/9 - // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H]) - // scale bottom 2x1 by 2/9 - // fetch last sample (I) and scale by 1/9. - - float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction); - float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction); - float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction); - float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction); - result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444; - result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222; - result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222; - result += tex2D(RefractSampler, singleton_loc) * 0.1111111; - - #if ( SHADER_SRGB_READ == 1 ) - { - // Just do this once rather than after every blur step, which is wrong, but much more efficient - result = GammaToLinear( result ); - } - #endif - - float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy); - #if ( SHADER_SRGB_READ == 1 ) - { - unblurredColor = GammaToLinear( unblurredColor ); - } - #endif - - result = lerp(unblurredColor, result * refractTintColor, blend); - -#elif (BLUR>0) // iteratively step through render target - int x, y; - - result = float3( 0.0f, 0.0f, 0.0f ); - for( x = -g_BlurCount; x <= g_BlurCount; x++ ) - { - for( y = -g_BlurCount; y <= g_BlurCount; y++ ) - { - result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) ); - } - } - - int width = g_BlurCount * 2 + 1; - result *= 1.0f / ( width * width ); - - #if ( SHADER_SRGB_READ == 1 ) - { - // Just do this once rather than after every blur step, which is wrong, but much more efficient - result = GammaToLinear( result ); - } - #endif - - // result is the blurred one now. . .now lerp. - float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); - #if ( SHADER_SRGB_READ == 1 ) - { - unblurredColor = GammaToLinear( unblurredColor ); - } - #endif - - result = lerp( unblurredColor, result * refractTintColor, blend ); -#else -# if MASKED - float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy ); - #if ( SHADER_SRGB_READ == 1 ) - { - fMaskedResult = GammaToLinear( fMaskedResult ); - } - #endif - - return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); -# else - float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); - #if ( SHADER_SRGB_READ == 1 ) - { - colorWarp = GammaToLinear( colorWarp ); - } - #endif - float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); - #if ( SHADER_SRGB_READ == 1 ) - { - colorNoWarp = GammaToLinear( colorNoWarp ); - } - #endif - - colorWarp *= refractTintColor; - result = lerp( colorNoWarp, colorWarp, blend ); -# endif -#endif - -#if CUBEMAP - float specularFactor = vNormal.a; - - float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal ); - - float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector ); - float3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint; - float3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); - float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); - result += specularLighting; -#endif - -#if COLORMODULATE - float resultAlpha = i.ColorModulate.a * vNormal.a; -#else - float resultAlpha = vNormal.a; -#endif - - return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); -} diff --git a/materialsystem/stdshaders/screenspace_general.cpp b/materialsystem/stdshaders/screenspace_general.cpp index 8dfe4aa8..e4aa966f 100644 --- a/materialsystem/stdshaders/screenspace_general.cpp +++ b/materialsystem/stdshaders/screenspace_general.cpp @@ -1,16 +1,14 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// -#include "BaseVSShader.h" -#include "IDeferredExt.h" -#include "SDK_screenspaceeffect_vs30.inc" +#include "basevsshader.h" +#include "sdk_screenspaceeffect_vs30.inc" -DEFINE_FALLBACK_SHADER( SDK_screenspace_general, SDK_screenspace_general_dx9 ) -BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_general", SHADER_NOT_EDITABLE ) +BEGIN_VS_SHADER_FLAGS( Screenspace_General, "Help for Screenspace_General", SHADER_NOT_EDITABLE ) BEGIN_SHADER_PARAMS SHADER_PARAM( C0_X,SHADER_PARAM_TYPE_FLOAT,"0","") SHADER_PARAM( C0_Y,SHADER_PARAM_TYPE_FLOAT,"0","") @@ -39,7 +37,6 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera SHADER_PARAM( LINEARREAD_TEXTURE2, SHADER_PARAM_TYPE_INTEGER, "0", "" ) SHADER_PARAM( LINEARREAD_TEXTURE3, SHADER_PARAM_TYPE_INTEGER, "0", "" ) SHADER_PARAM( LINEARWRITE,SHADER_PARAM_TYPE_INTEGER,"0","") - SHADER_PARAM( USES_VIEWPROJ, SHADER_PARAM_TYPE_INTEGER, "0", "") SHADER_PARAM( X360APPCHOOSER, SHADER_PARAM_TYPE_INTEGER, "0", "Needed for movies in 360 launcher" ) END_SHADER_PARAMS @@ -85,7 +82,7 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); ImageFormat fmt=txtr->GetImageFormat(); if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); else pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0, !params[LINEARREAD_BASETEXTURE]->IsDefined() || !params[LINEARREAD_BASETEXTURE]->GetIntValue() ); } @@ -95,7 +92,7 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera ITexture *txtr=params[TEXTURE1]->GetTextureValue(); ImageFormat fmt=txtr->GetImageFormat(); if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1, true); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); else pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1, !params[LINEARREAD_TEXTURE1]->IsDefined() || !params[LINEARREAD_TEXTURE1]->GetIntValue() ); } @@ -105,7 +102,7 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera ITexture *txtr=params[TEXTURE2]->GetTextureValue(); ImageFormat fmt=txtr->GetImageFormat(); if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2, true); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); else pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2, !params[LINEARREAD_TEXTURE2]->IsDefined() || !params[LINEARREAD_TEXTURE2]->GetIntValue() ); } @@ -115,7 +112,7 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera ITexture *txtr=params[TEXTURE3]->GetTextureValue(); ImageFormat fmt=txtr->GetImageFormat(); if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3, true); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3,false); else pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3, !params[LINEARREAD_TEXTURE3]->IsDefined() || !params[LINEARREAD_TEXTURE3]->GetIntValue() ); } @@ -136,9 +133,7 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera // Pre-cache shaders DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( X360APPCHOOSER, IS_PARAM_DEFINED( X360APPCHOOSER ) ? params[X360APPCHOOSER]->GetIntValue() : 0 ); - vsh_forgot_to_set_static_X360APPCHOOSER = 0; // This is a dirty workaround to the shortcut [= 0] in the fxc - SET_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); if (params[DISABLE_COLOR_WRITES]->GetIntValue()) { @@ -218,34 +213,15 @@ BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_genera pShaderAPI->SetPixelShaderConstant( 0, c0, ARRAYSIZE(c0)/4 ); - if (params[BASETEXTURE]->IsDefined()) - { - float flResolution[2] = { - params[BASETEXTURE]->GetTextureValue()->GetActualWidth(), - params[BASETEXTURE]->GetTextureValue()->GetActualHeight() - }; - - pShaderAPI->SetPixelShaderConstant(4, flResolution); - } - - if (USES_VIEWPROJ != -1 && params[USES_VIEWPROJ]->GetIntValue() != 0) - { - pShaderAPI->SetPixelShaderConstant(6, GetDeferredExt()->GetOriginBase()); - - pShaderAPI->SetPixelShaderConstant(8, GetDeferredExt()->m_matViewInv.Base(), 4); - pShaderAPI->SetPixelShaderConstant(12, GetDeferredExt()->m_matProjInv.Base(), 4); - pShaderAPI->SetPixelShaderConstant(16, GetDeferredExt()->m_matView.Base(), 4); - pShaderAPI->SetPixelShaderConstant(20, GetDeferredExt()->m_matProj.Base(), 4); - - float zPlanes[2] = { GetDeferredExt()->GetZDistNear(), GetDeferredExt()->GetZDistFar() }; - pShaderAPI->SetPixelShaderConstant(24, zPlanes); - } + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); pShaderAPI->SetVertexShaderIndex( 0 ); pShaderAPI->SetPixelShaderIndex( 0 ); - DECLARE_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); } Draw(); } diff --git a/materialsystem/stdshaders/screenspace_simple_vs20.fxc b/materialsystem/stdshaders/screenspace_simple_vs20.fxc deleted file mode 100644 index 124f49f6..00000000 --- a/materialsystem/stdshaders/screenspace_simple_vs20.fxc +++ /dev/null @@ -1,19 +0,0 @@ -// Includes -#include "common_vs_fxc.h" - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord0 : TEXCOORD0; -}; - -// Main -VS_OUTPUT main(float4 Position : POSITION, - float2 TexCoord : TEXCOORD0) -{ - VS_OUTPUT OUT; - OUT.Position = Position; - OUT.TexCoord0 = TexCoord; - return OUT; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/screenspace_simple_vs30.fxc b/materialsystem/stdshaders/screenspace_simple_vs30.fxc deleted file mode 100644 index 124f49f6..00000000 --- a/materialsystem/stdshaders/screenspace_simple_vs30.fxc +++ /dev/null @@ -1,19 +0,0 @@ -// Includes -#include "common_vs_fxc.h" - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord0 : TEXCOORD0; -}; - -// Main -VS_OUTPUT main(float4 Position : POSITION, - float2 TexCoord : TEXCOORD0) -{ - VS_OUTPUT OUT; - OUT.Position = Position; - OUT.TexCoord0 = TexCoord; - return OUT; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/screenwater_ps2x.fxc b/materialsystem/stdshaders/screenwater_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/screenwater_ps2x.fxc rename to materialsystem/stdshaders/screenwater_ps30.fxc diff --git a/materialsystem/stdshaders/screenwater_vs20.fxc b/materialsystem/stdshaders/screenwater_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/screenwater_vs20.fxc rename to materialsystem/stdshaders/screenwater_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_bloom_ps30.fxc b/materialsystem/stdshaders/sdk_bloom_ps30.fxc new file mode 100644 index 00000000..f3d6d055 --- /dev/null +++ b/materialsystem/stdshaders/sdk_bloom_ps30.fxc @@ -0,0 +1,20 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler FBSampler : register( s0 ); +sampler BlurSampler : register( s1 ); + +struct PS_INPUT +{ + float2 texCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 fbSample = tex2D( FBSampler, i.texCoord ); + float4 blurSample = tex2D( BlurSampler, i.texCoord ); + + return FinalOutput( float4( fbSample + blurSample.rgb * blurSample.a * MAX_HDR_OVERBRIGHT, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/materialsystem/stdshaders/SDK_bloomadd_ps2x.fxc b/materialsystem/stdshaders/sdk_bloomadd_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/SDK_bloomadd_ps2x.fxc rename to materialsystem/stdshaders/sdk_bloomadd_ps30.fxc diff --git a/materialsystem/stdshaders/sdk_blurfilter_ps30.fxc b/materialsystem/stdshaders/sdk_blurfilter_ps30.fxc new file mode 100644 index 00000000..bbf6a4fa --- /dev/null +++ b/materialsystem/stdshaders/sdk_blurfilter_ps30.fxc @@ -0,0 +1,89 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "APPROX_SRGB_ADAPTER" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; + float2 coordTap1Neg : TEXCOORD4; + float2 coordTap2Neg : TEXCOORD5; + float2 coordTap3Neg : TEXCOORD6; +}; + +float2 psTapOffs[3] : register( c0 ); +float3 scale_factor : register( c3 ); + +float4 SampleTexture( sampler texSampler, float2 uv ) +{ + float4 cSample = tex2D( texSampler, uv ); + + #if ( APPROX_SRGB_ADAPTER ) + { + cSample.rgb = max( cSample.rgb, float3( 0.00001f, 0.00001f, 0.00001f ) ); // rsqrt doesn't like inputs of zero + + float3 ooSQRT; // + ooSQRT.r = rsqrt( cSample.r ); // + ooSQRT.g = rsqrt( cSample.g ); // Approximate linear-to-sRGB conversion + ooSQRT.b = rsqrt( cSample.b ); // + cSample.rgb *= ooSQRT.rgb; // + } + #endif + + return cSample; +} + +float4 main( PS_INPUT i ) : COLOR +{ + float4 s0, s1, s2, s3, s4, s5, s6, color; + + // Sample taps with coordinates from VS + s0 = SampleTexture( TexSampler, i.coordTap0 ); + s1 = SampleTexture( TexSampler, i.coordTap1 ); + s2 = SampleTexture( TexSampler, i.coordTap2 ); + s3 = SampleTexture( TexSampler, i.coordTap3 ); + s4 = SampleTexture( TexSampler, i.coordTap1Neg ); + s5 = SampleTexture( TexSampler, i.coordTap2Neg ); + s6 = SampleTexture( TexSampler, i.coordTap3Neg ); + + color = s0 * 0.2013f; + color += ( s1 + s4 ) * 0.2185f; + color += ( s2 + s5 ) * 0.0821f; + color += ( s3 + s6 ) * 0.0461f; + + // Compute tex coords for other taps + float2 coordTap4 = i.coordTap0 + psTapOffs[0]; + float2 coordTap5 = i.coordTap0 + psTapOffs[1]; + float2 coordTap6 = i.coordTap0 + psTapOffs[2]; + float2 coordTap4Neg = i.coordTap0 - psTapOffs[0]; + float2 coordTap5Neg = i.coordTap0 - psTapOffs[1]; + float2 coordTap6Neg = i.coordTap0 - psTapOffs[2]; + + // Sample the taps + s1 = SampleTexture( TexSampler, coordTap4 ); + s2 = SampleTexture( TexSampler, coordTap5 ); + s3 = SampleTexture( TexSampler, coordTap6 ); + s4 = SampleTexture( TexSampler, coordTap4Neg ); + s5 = SampleTexture( TexSampler, coordTap5Neg ); + s6 = SampleTexture( TexSampler, coordTap6Neg ); + + color += ( s1 + s4 ) * 0.0262f; + color += ( s2 + s5 ) * 0.0162f; + color += ( s3 + s6 ) * 0.0102f; + color.xyz*=scale_factor.xyz; + + #if ( APPROX_SRGB_ADAPTER ) + { + color.xyz *= color.xyz; // Approximate sRGB-to-linear conversion + } + #endif + + return color; +} + diff --git a/materialsystem/stdshaders/sdk_blurgaussian_3x3_ps30.fxc b/materialsystem/stdshaders/sdk_blurgaussian_3x3_ps30.fxc new file mode 100644 index 00000000..5dbf655e --- /dev/null +++ b/materialsystem/stdshaders/sdk_blurgaussian_3x3_ps30.fxc @@ -0,0 +1,22 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +sampler g_texSampler : register( s0 ); + +struct PS_INPUT +{ + float2 uv : TEXCOORD0; +}; + +float2 g_vPsTapOffsets[2] : register( c0 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float4 cOut; + + cOut = 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[0] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[0] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[1] ); + cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[1] ); + + return cOut; +} diff --git a/materialsystem/stdshaders/sdk_cloak_blended_pass_ps30.fxc b/materialsystem/stdshaders/sdk_cloak_blended_pass_ps30.fxc new file mode 100644 index 00000000..ff0f5cc2 --- /dev/null +++ b/materialsystem/stdshaders/sdk_cloak_blended_pass_ps30.fxc @@ -0,0 +1,104 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "BUMPMAP" "0..1" + +// Includes ======================================================================================= +#include "common_vertexlitgeneric.h" + +// Texture Samplers =============================================================================== +sampler g_tRefractionSampler : register( s0 ); +#if BUMPMAP + sampler g_tBumpSampler : register( s1 ); +#endif + +// Shaders Constants and Globals ================================================================== +const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix +const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix + +const float4 g_vCameraPosition : register( c5 ); +const float4 g_vPackedConst6 : register( c6 ); +#define g_flCloakFactor g_vPackedConst6.x // Default = 1.0f +#define g_flRefractAmount g_vPackedConst6.y // Default = 1.0f + +const float4 g_cCloakColorTint : register( c7 ); + +// 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw) +static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ), + float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ), + float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ), + float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) }; + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float3 vWorldNormal : TEXCOORD0; // World-space normal + float3 vProjPosForRefract : TEXCOORD1; + float3 vWorldViewVector : TEXCOORD2; + #if BUMPMAP + float3x3 mTangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float2 vTexCoord0 : TEXCOORD6; + #endif +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + float3 vWorldNormal = normalize( i.vWorldNormal.xyz ); + + #if BUMPMAP + float4 vBumpTexel = tex2D( g_tBumpSampler, i.vTexCoord0.xy ); + float3 vTangentNormal = ( 2.0f * vBumpTexel ) - 1.0f; + vWorldNormal.xyz = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz ); + #endif + + // Transform world space normal into clip space and project + float3 vProjNormal; + vProjNormal.x = dot( vWorldNormal.xyz, g_mViewProj0.xyz ); // 1st row + vProjNormal.y = dot( vWorldNormal.xyz, g_mViewProj1.xyz ); // 2nd row + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vProjPosForRefract.xy / i.vProjPosForRefract.z; + float2 vRefractTexCoord = vProjNormal.xy; + float scale = lerp( g_flRefractAmount, 0.0f, saturate( g_flCloakFactor ) ); + vRefractTexCoord.xy *= scale; + vRefractTexCoord.xy += vRefractTexCoordNoWarp.xy; + + // Blur by scalable Poisson filter + float flBlurAmount = lerp( 0.05f, 0.0f, saturate( g_flCloakFactor ) ); + float3 cRefract = tex2D( g_tRefractionSampler, vRefractTexCoord.xy ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].xy * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].wz * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].xy * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].wz * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].xy * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].wz * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].xy * flBlurAmount ) ); + cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].wz * flBlurAmount ) ); + cRefract /= 9.0f; + + // 1-(N.V) for Fresnel term (NOTE: If this math changes, you need to update the C code that mimics this on the CPU) + float flFresnel = 1.0f - saturate( dot( i.vWorldNormal.xyz, normalize( -i.vWorldViewVector.xyz ) ) ); + float flCloakLerpFactor = saturate( lerp( 1.0f, flFresnel - 1.35f, saturate( g_flCloakFactor ) ) ); + flCloakLerpFactor = 1.0f - smoothstep( 0.4f, 0.425f, flCloakLerpFactor ); + + // Slightly dim the facing pixels and brighten the silhouette pixels + cRefract.rgb *= lerp( flFresnel * 0.4 + 0.8, 1.0f, saturate( g_flCloakFactor ) * saturate( g_flCloakFactor ) ); // This gives a scalar in the range [0.8 1.2] + + // Refract color tint + float fColorTintStrength = saturate( ( saturate( g_flCloakFactor ) - 0.75f ) * 4.0f ); + cRefract.rgb *= lerp( g_cCloakColorTint, 1.0f, fColorTintStrength ); + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = cRefract.rgb; + + // Set alpha to cloak mask + result.a = flCloakLerpFactor; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/materialsystem/stdshaders/sdk_cloak_blended_pass_vs30.fxc b/materialsystem/stdshaders/sdk_cloak_blended_pass_vs30.fxc new file mode 100644 index 00000000..743c3071 --- /dev/null +++ b/materialsystem/stdshaders/sdk_cloak_blended_pass_vs30.fxc @@ -0,0 +1,132 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "BUMPMAP" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +// Globals +static const bool g_bSkinning = SKINNING ? true : false; +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + + #if BUMPMAP + float4 vTangent : TANGENT; + #endif + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; + + #if ( MORPHING ) + float vVertexID : POSITION2; + #endif +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float3 vWorldNormal : TEXCOORD0; // World-space normal + float3 vProjPosForRefract : TEXCOORD1; + float3 vWorldViewVector : TEXCOORD2; + + #if BUMPMAP + float3x3 mTangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float2 vTexCoord0 : TEXCOORD6; + #endif +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Flexes coming in from a separate stream (contribution masked by cFlexScale.x) + float4 vObjPosition = i.vPos; + float3 vObjNormal; + + #if BUMPMAP + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent ); + + #if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), vObjPosition.xyz, vObjNormal, vObjTangent.xyz ); + #else + ApplyMorph( i.vPosFlex, i.vNormalFlex, vObjPosition.xyz, vObjNormal, vObjTangent.xyz ); + #endif + #else // !BUMPMAP + DecompressVertex_Normal( i.vNormal, vObjNormal ); + + #if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), + vObjPosition.xyz, vObjNormal ); + #else + ApplyMorph( i.vPosFlex, i.vNormalFlex, vObjPosition.xyz, vObjNormal ); + #endif + #endif + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + #if BUMPMAP + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal.xyz, vObjTangent.xyzw, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + #else + SkinPositionAndNormal( g_bSkinning, vObjPosition, vObjNormal.xyz, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal ); + #endif + o.vWorldNormal.xyz = normalize( vWorldNormal.xyz ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPosition.x; + vRefractPos.y = -vProjPosition.y; // Invert Y + vRefractPos = (vRefractPos + vProjPosition.w) * 0.5f; + o.vProjPosForRefract.xyz = float3(vRefractPos.x, vRefractPos.y, vProjPosition.w); + + // View vector + float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz); + o.vWorldViewVector.xyz = vWorldViewVector.xyz; + + // Tangent space transform + #if BUMPMAP + o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x ); + o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y ); + o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z ); + #endif + + // Texture coordinates + #if BUMPMAP + o.vTexCoord0.x = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[0] ); + o.vTexCoord0.y = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[1] ); + #endif + + return o; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/cloud_ps20.fxc b/materialsystem/stdshaders/sdk_cloud_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/cloud_ps20.fxc rename to materialsystem/stdshaders/sdk_cloud_ps30.fxc diff --git a/materialsystem/stdshaders/cloud_vs20.fxc b/materialsystem/stdshaders/sdk_cloud_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/cloud_vs20.fxc rename to materialsystem/stdshaders/sdk_cloud_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_core_ps30.fxc b/materialsystem/stdshaders/sdk_core_ps30.fxc new file mode 100644 index 00000000..7cd6528d --- /dev/null +++ b/materialsystem/stdshaders/sdk_core_ps30.fxc @@ -0,0 +1,221 @@ +//====== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "CUBEMAP" "0..1" +// STATIC: "FLOWMAP" "0..1" +// STATIC: "CORECOLORTEXTURE" "0..1" +// STATIC: "REFRACT" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +// SKIP: ( $REFRACT || $CORECOLORTEXTURE ) && $CUBEMAP + +#include "common_ps_fxc.h" + +sampler RefractSampler : register( s2 ); +sampler NormalSampler : register( s3 ); +#if CUBEMAP +sampler EnvmapSampler : register( s4 ); +#endif +#if FLOWMAP +sampler FlowmapSampler : register( s6 ); +#endif + +#if CORECOLORTEXTURE +sampler CoreColorSampler : register( s7 ); +#endif + +const HALF3 g_EnvmapTint : register( c0 ); +const HALF3 g_RefractTint : register( c1 ); +const HALF3 g_EnvmapContrast : register( c2 ); +const HALF3 g_EnvmapSaturation : register( c3 ); +const HALF2 g_RefractScale : register( c5 ); +#if FLOWMAP +const float g_Time : register( c6 ); +const float2 g_FlowScrollRate : register( c7 ); +const float g_CoreColorTexCoordOffset : register( c9 ); +#endif + +const float3 g_EyePos : register( c8 ); +const float4 g_FogParams : register( c11 ); + + +const float3 g_SphereCenter : register( c12 ); +const float3 g_SphereRadius : register( c15 ); + +float LengthThroughSphere( float3 vecRayOrigin, float3 vecRayDelta, + float3 vecSphereCenter, float flRadius, out float alpha ) +{ + // Solve using the ray equation + the sphere equation + // P = o + dt + // (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2 + // (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2 + // (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 + + // (oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 + + // (oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2 + // (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t + + // (ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0 + // or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a + // a = DotProduct( vecRayDelta, vecRayDelta ); + // b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta ) + // c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius; + + float3 vecSphereToRay; + vecSphereToRay = vecRayOrigin - vecSphereCenter; + + float a = dot( vecRayDelta, vecRayDelta ); + + // This would occur in the case of a zero-length ray + // if ( a == 0.0f ) + // { + // *pT1 = *pT2 = 0.0f; + // return vecSphereToRay.LengthSqr() <= flRadius * flRadius; + // } + + float b = 2 * dot( vecSphereToRay, vecRayDelta ); + float c = dot( vecSphereToRay, vecSphereToRay ) - flRadius * flRadius; + float flDiscrim = b * b - 4 * a * c; + // if ( flDiscrim < 0.0f ) + // return 0.0f; + + float hack = flDiscrim; + flDiscrim = sqrt( flDiscrim ); + float oo2a = 0.5f / a; + + + //if( hack < 0.0f ) + //{ + // alpha = 0.0f; + // return 0.0f; + //} + //else + //{ + // alpha = 1.0f; + // return abs( flDiscrim ) * 2 * oo2a; + //} + + //replacing the if's above because if's in hlsl are bad..... + float fHackGreaterThanZero = step( 0.0f, hack ); + alpha = fHackGreaterThanZero; + return (fHackGreaterThanZero * (abs( flDiscrim ) * 2 * oo2a)); + + + // *pT1 = ( - b - flDiscrim ) * oo2a; + // *pT2 = ( - b + flDiscrim ) * oo2a; + // return true; +} + + +struct PS_INPUT +{ + float2 vBumpTexCoord : TEXCOORD0; // dudvMapAndNormalMapTexCoord + HALF3 vWorldVertToEyeVector : TEXCOORD1; + HALF3x3 tangentSpaceTranspose : TEXCOORD2; + float3 vRefractXYW : TEXCOORD5; + float3 projNormal : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF3 result = 0.0f; + + HALF blend = 1.0f; + +#if FLOWMAP + // Mapbase tries to un-hack some of this code + //float3 g_SphereCenter = { 2688.0f, 12139.0f, 5170.0f }; + //float g_SphereDiameter = 430.0f; + //float g_SphereRadius = g_SphereDiameter * 0.5f; + + float g_SphereDiameter = g_SphereRadius * 2.0f; + + float3 tmp = i.worldPos_projPosZ.xyz - g_SphereCenter; + float hackRadius = 1.05f * sqrt( dot( tmp, tmp ) ); + + float sphereAlpha; + float lengthThroughSphere = LengthThroughSphere( g_EyePos, normalize( i.worldPos_projPosZ.xyz - g_EyePos ), + g_SphereCenter, /*g_SphereRadius*/ hackRadius, sphereAlpha ); + + float normalizedLengthThroughSphere = lengthThroughSphere / g_SphereDiameter; + + + float3 hackWorldSpaceNormal = normalize( i.worldPos_projPosZ.xyz - g_SphereCenter ); + float3 realFuckingNormal = abs( hackWorldSpaceNormal ); + hackWorldSpaceNormal = 0.5f * ( hackWorldSpaceNormal + 1.0f ); + + // hackWorldSpaceNormal = abs( hackWorldSpaceNormal ); + + // return float4( hackWorldSpaceNormal.x, 0.0f, 0.0f, 1.0f ); + + i.vBumpTexCoord.xy = 0.0f; + i.vBumpTexCoord.xy = realFuckingNormal.z * tex2D( FlowmapSampler, hackWorldSpaceNormal.xy ); + i.vBumpTexCoord.xy += realFuckingNormal.y * tex2D( FlowmapSampler, hackWorldSpaceNormal.xz ); + i.vBumpTexCoord.xy += realFuckingNormal.x * tex2D( FlowmapSampler, hackWorldSpaceNormal.yz ); + i.vBumpTexCoord.xy += g_Time * g_FlowScrollRate; + // return float4( i.vBumpTexCoord.xy, 0.0f, 0.0f ); +#endif + + // Load normal and expand range + HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoord ); + // return vNormalSample; + HALF3 tangentSpaceNormal = vNormalSample * 2.0 - 1.0; + + HALF3 refractTintColor = g_RefractTint; + + // Perform division by W only once + float ooW = 1.0f / i.vRefractXYW.z; + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; + float2 vRefractTexCoord = tangentSpaceNormal.xy; + HALF scale = vNormalSample.a * g_RefractScale.x; +#if FLOWMAP + scale *= normalizedLengthThroughSphere; +#endif + vRefractTexCoord *= scale; +#if FLOWMAP + float2 hackOffset = vRefractTexCoord; +#endif + vRefractTexCoord += vRefractTexCoordNoWarp; + + float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); + float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + + colorWarp *= refractTintColor; +#if REFRACT + result = lerp( colorNoWarp, colorWarp, blend ); + // return float4( 1.0f, 0.0f, 0.0f, 1.0f ); +#endif + +#if CUBEMAP + HALF specularFactor = vNormalSample.a; + + HALF3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal ); + + HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vWorldVertToEyeVector ); + HALF3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + result += specularLighting; +#endif + +#if CORECOLORTEXTURE && FLOWMAP + float4 coreColorTexel = tex2D( CoreColorSampler, hackOffset + float2( normalizedLengthThroughSphere, g_CoreColorTexCoordOffset ) ); + HALF4 rgba = HALF4( lerp( result, coreColorTexel, coreColorTexel.a /*normalizedLengthThroughSphere*/ ), sphereAlpha ); +#else + HALF4 rgba = HALF4( result, vNormalSample.a ); +#endif + + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +} + diff --git a/materialsystem/stdshaders/sdk_core_vs30.fxc b/materialsystem/stdshaders/sdk_core_vs30.fxc new file mode 100644 index 00000000..9b7c9652 --- /dev/null +++ b/materialsystem/stdshaders/sdk_core_vs30.fxc @@ -0,0 +1,103 @@ +// STATIC: "MODEL" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bModel = MODEL ? true : false; + +const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; +#if !MODEL + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +#else + float4 vUserData : TANGENT; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; + float vFog : FOG; + float2 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + float3 vRefractXYW : TEXCOORD5; + float4 projNormal_screenCoordW : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + + float3 vObjNormal; +#if MODEL + float4 vObjTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent ); + + SkinPositionNormalAndTangentSpace( + g_bSkinning, + v.vPos, vObjNormal, vObjTangent, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal, worldTangentS, worldTangentT ); +#else + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + worldPos = mul( v.vPos, cModel[0] ); + worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); +#endif + + + // Projected position + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos_POSITION = vProjPos; + o.projNormal_screenCoordW.xyz = mul( worldNormal, cViewProj ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Refraction transform + o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = o.vFog = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); + + // Eye vector + float3 vWorldEyeVect = cEyePos - vWorldPos; + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + + return o; +} diff --git a/materialsystem/stdshaders/sdk_decalmodulate_ps30.fxc b/materialsystem/stdshaders/sdk_decalmodulate_ps30.fxc new file mode 100644 index 00000000..f69b835d --- /dev/null +++ b/materialsystem/stdshaders/sdk_decalmodulate_ps30.fxc @@ -0,0 +1,97 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// +// paired with "vertexlit_and_unlit_generic_vs##" + +// STATIC: "VERTEXALPHA" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) + +#include "common_ps_fxc.h" +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +sampler TexSampler : register( s0 ); + +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogTweakParams : register( c0 ); +#define g_fFogExponentTweak g_FogTweakParams.x +#define g_fFogScaleTweak g_FogTweakParams.y + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const float3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + + float4 worldPos_projPosZ : TEXCOORD1; // Necessary for pixel fog + + float4 color : COLOR1; + +#if FLASHLIGHT + float4 vProjPos : TEXCOORD2; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result = tex2D( TexSampler, i.baseTexCoord ); + + // Blend towards grey based on alpha + float flFactor = 1.0; +#if VERTEXALPHA + flFactor *= i.color.w; +#endif + +#if FLASHLIGHT + //if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + float2 vProjPos = float2(0, 0); +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = FLASHLIGHTSHADOWS; + vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise +#endif + + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + float3( 0.0f, 0.0f, 1.0f ), g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), false ); + + flFactor *= (flashlightColor.x + flashlightColor.y + flashlightColor.z); + + //result.xyz *= flashlightColor.xyz; + + //result.a *= (flashlightColor.x * flashlightColor.y * flashlightColor.z); + } +#endif + + result.xyz = lerp( float3( 0.5, 0.5, 0.5 ), result.xyz, flFactor ); + + // Since we're blending with a mod2x, we need to compensate with this hack + // NOTE: If the fog color (not fog density) is extremely dark, this can makes some decals seem + // a little transparent, but it's better than not doing this + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + fogFactor = pow( saturate( g_fFogScaleTweak * fogFactor ), g_fFogExponentTweak ); + + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +} diff --git a/materialsystem/stdshaders/sdk_decalmodulate_vs30.fxc b/materialsystem/stdshaders/sdk_decalmodulate_vs30.fxc new file mode 100644 index 00000000..8a0d9744 --- /dev/null +++ b/materialsystem/stdshaders/sdk_decalmodulate_vs30.fxc @@ -0,0 +1,136 @@ +// based on vertexlit_and_unlit_generic_vs20.fxc +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "LIGHTING_PREVIEW" "0..1" +// STATIC: "FLASHLIGHT" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); + +#if ( MORPHING ) +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 worldPos_ProjPosZ : TEXCOORD1; + float4 color : COLOR1; // Vertex color (from lighting or unlit) + +#if FLASHLIGHT + float4 vProjPos : TEXCOORD2; +#endif +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal = 0; + +#if ( LIGHTING_PREVIEW || MORPHING ) + // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) + DecompressVertex_Normal( v.vNormal, vNormal ); +#endif + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + if ( !g_bVertexColor ) + { + worldNormal = normalize( worldNormal ); + } + +#if ( MORPHING ) + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + +#if FLASHLIGHT + // Transform into projection space + projPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.vProjPos = projPos; +#endif + + o.worldPos_ProjPosZ.xyz = worldPos.xyz; + o.worldPos_ProjPosZ.w = projPos.z; + + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. + o.color.rgb = GammaToLinear( v.vColor.rgb ); + o.color.a = v.vColor.a; + } + else + { + o.color = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + } + + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + +#if LIGHTING_PREVIEW + float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); + o.color.xyz=float3(dot,dot,dot); +#endif + + return o; +} + + diff --git a/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc b/materialsystem/stdshaders/sdk_depthtodestalpha_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/depthtodestalpha_ps20b.fxc rename to materialsystem/stdshaders/sdk_depthtodestalpha_ps30.fxc diff --git a/materialsystem/stdshaders/depthtodestalpha_vs20.fxc b/materialsystem/stdshaders/sdk_depthtodestalpha_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/depthtodestalpha_vs20.fxc rename to materialsystem/stdshaders/sdk_depthtodestalpha_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_depthwrite_ps30.fxc b/materialsystem/stdshaders/sdk_depthwrite_ps30.fxc new file mode 100644 index 00000000..1baabcf3 --- /dev/null +++ b/materialsystem/stdshaders/sdk_depthwrite_ps30.fxc @@ -0,0 +1,44 @@ +// STATIC: "COLOR_DEPTH" "0..1" + +// DYNAMIC: "ALPHACLIP" "0..1" + +const float g_AlphaThreshold : register( c0 ); + +const float2 g_vNearFarPlanes : register( c1 ); + #define g_flNearPlane g_vNearFarPlanes.x + #define g_flFarPlane g_vNearFarPlanes.y + +struct PS_INPUT +{ +#if ALPHACLIP + float2 texCoord0 : TEXCOORD0; +#endif + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float4 color = float4( 1, 0, 0, 1 ); // opaque alpha....the color doesn't matter for this shader + +#if ALPHACLIP + color = tex2D( BaseTextureSampler, i.texCoord0 ); + + clip( color.a - g_AlphaThreshold ); + +#endif + +#if ( COLOR_DEPTH == 1 ) + + return float4( i.vWorldPos_projPosZ.w / g_flFarPlane, 0.0, 0.0, 1.0 ); + +#else + + return color; + +#endif +} diff --git a/materialsystem/stdshaders/sdk_depthwrite_vs30.fxc b/materialsystem/stdshaders/sdk_depthwrite_vs30.fxc new file mode 100644 index 00000000..3768b219 --- /dev/null +++ b/materialsystem/stdshaders/sdk_depthwrite_vs30.fxc @@ -0,0 +1,115 @@ +// STATIC: "COLOR_DEPTH" "0..1" +// STATIC: "TREESWAY" "0..2" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +#if ( TREESWAY ) + const float4 g_vTreeSwayParams0 : register( SHADER_SPECIFIC_CONST_2 ); + const float4 g_vTreeSwayParams1 : register( SHADER_SPECIFIC_CONST_3 ); + const float4 g_vTreeSwayParams2 : register( SHADER_SPECIFIC_CONST_4 ); + const float4 g_vTreeSwayParams3 : register( SHADER_SPECIFIC_CONST_5 ); + const float4 g_vTreeSwayParams4 : register( SHADER_SPECIFIC_CONST_9 ); + + #define g_flTime g_vTreeSwayParams0.x + #define g_vWindDir g_vTreeSwayParams0.yz + + #define g_flScrumbleFalloffCurve g_vTreeSwayParams1.x + #define g_flSwayFalloffCurve g_vTreeSwayParams1.y + #define g_flScrumbleSpeed g_vTreeSwayParams1.z + #define g_flFastSwaySpeedScale g_vTreeSwayParams1.w + + + #define g_flHeight g_vTreeSwayParams2.x + #define g_flStartHeight g_vTreeSwayParams2.y + #define g_flRadius g_vTreeSwayParams2.z + #define g_flStartRadius g_vTreeSwayParams2.w + + #define g_flSwaySpeed g_vTreeSwayParams3.x + #define g_flSwayIntensity g_vTreeSwayParams3.y + #define g_flScrumbleWaveCount g_vTreeSwayParams3.z + #define g_flScrumbleIntensity g_vTreeSwayParams3.w + + #define g_flWindSpeedLerpStart g_vTreeSwayParams4.x + #define g_flWindSpeedLerpEnd g_vTreeSwayParams4.y + + #include "tree_sway.h" +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord : TEXCOORD0; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + + // Position delta stream + float3 vPosFlex : POSITION1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float2 texCoord : TEXCOORD0; + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + float3 vWorldPos; + float4 vPosition = v.vPos; + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, float3(0, 0, 0), vPosition.xyz ); +#else + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#endif + + #if ( TREESWAY ) + { + vPosition.xyz = ComputeTreeSway( vPosition.xyz, g_flTime ); + } + #endif + + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPos ); + + float4 vProjPos = mul( float4( vWorldPos, 1.0f ), cViewProj ); + + o.vProjPos = vProjPos; + + o.texCoord = v.vTexCoord; + +#if ( COLOR_DEPTH ) + o.vWorldPos_projPosZ.z = vProjPos.z; + o.vWorldPos_projPosZ.w = vProjPos.w; +#endif + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_ps30.fxc b/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_ps30.fxc new file mode 100644 index 00000000..83e26dbf --- /dev/null +++ b/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_ps30.fxc @@ -0,0 +1,49 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +// Includes ======================================================================================= +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +#include "common_vertexlitgeneric.h" + +// Texture Samplers =============================================================================== +sampler g_tBaseSampler : register( s0 ); +sampler g_tFlowSampler : register( s1 ); +sampler g_tSelfIllumSampler : register( s2 ); + +// Shaders Constants and Globals ================================================================== +const float4 g_vPackedConst0 : register( c0 ); +#define g_flBlendStrength g_vPackedConst0.x +#define g_flTime g_vPackedConst0.y + +const float2 g_vEmissiveScrollVector : register( c1 ); +const float3 g_cSelfIllumTint : register( c2 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; +}; + +// Main =========================================================================================== +//float4 main( PS_INPUT i ) : COLOR // Non-HDR for debugging +float4 main( PS_INPUT i ) : COLOR +{ + // Color texture + float4 cBaseColor = tex2D( g_tBaseSampler, i.vTexCoord0.xy ); + + // Fetch from dudv map and then fetch from emissive texture with new uv's & scroll + float4 vFlowValue = tex2D( g_tFlowSampler, i.vTexCoord0.xy ); + float2 vEmissiveTexCoord = vFlowValue.xy + ( g_vEmissiveScrollVector.xy * g_flTime ); + float4 cEmissiveColor = tex2D( g_tSelfIllumSampler, vEmissiveTexCoord.xy ); + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = cBaseColor.rgb * cEmissiveColor.rgb * g_cSelfIllumTint.rgb; + result.rgb *= g_flBlendStrength; + + // Set alpha to 0.0f so it doesn't change dest alpha (I should probably disable dest alpha writes) + result.a = 0.0f; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} \ No newline at end of file diff --git a/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_vs30.fxc b/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_vs30.fxc new file mode 100644 index 00000000..c0e68407 --- /dev/null +++ b/materialsystem/stdshaders/sdk_emissive_scroll_blended_pass_vs30.fxc @@ -0,0 +1,68 @@ +//========= Copyright ? 1996-2006, Valve Corporation, All rights reserved. ============// + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +// Globals +static const bool g_bSkinning = SKINNING ? true : false; + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + + float3 vPosFlex : POSITION1; // Delta positions for flexing + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float2 vTexCoord0 : TEXCOORD0; +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + float4 vObjPosition = i.vPos; + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), vObjPosition.xyz ); +#else + ApplyMorph( i.vPosFlex, vObjPosition.xyz ); +#endif + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + SkinPosition( g_bSkinning, vObjPosition, i.vBoneWeights, i.vBoneIndices, vWorldPosition ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // Pass through tex coords + o.vTexCoord0.xy = i.vTexCoord0.xy; + + return o; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/sdk_engine_post_ps30.fxc b/materialsystem/stdshaders/sdk_engine_post_ps30.fxc new file mode 100644 index 00000000..e7d53ba0 --- /dev/null +++ b/materialsystem/stdshaders/sdk_engine_post_ps30.fxc @@ -0,0 +1,394 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// FIXMEL4DTOMAINMERGE +// Need to re-enable bloom and disable other L4D-only features in here and the cpp file. + +// STATIC: "TOOL_MODE" "0..1" +// STATIC: "DEPTH_BLUR_ENABLE" "0..1" + +// DYNAMIC: "AA_ENABLE" "0..0" [PC] +// DYNAMIC: "AA_ENABLE" "0..1" [XBOX] + +// DYNAMIC: "COL_CORRECT_NUM_LOOKUPS" "0..3" + +// DYNAMIC: "CONVERT_FROM_LINEAR" "0..1" [ps20b] [ps30] [PC] +// DYNAMIC: "CONVERT_TO_LINEAR" "0..1" [ps20b] [ps30] [PC] +// DYNAMIC: "CONVERT_FROM_LINEAR" "0..0" [ps20b] [XBOX] +// DYNAMIC: "CONVERT_TO_LINEAR" "0..0" [ps20b] [XBOX] +// SKIP: ( $CONVERT_FROM_LINEAR == 0 ) && ( $CONVERT_TO_LINEAR == 1 ) +// SKIP: ( $TOOL_MODE == 0 ) && ( $CONVERT_TO_LINEAR == 1 ) + +// DYNAMIC: "NOISE_ENABLE" "0..1" [ps20b] [ps30] +// DYNAMIC: "VIGNETTE_ENABLE" "0..1" [ps20b] [ps30] +// DYNAMIC: "LOCAL_CONTRAST_ENABLE" "0..1" [ps20b] [ps30] +// DYNAMIC: "BLURRED_VIGNETTE_ENABLE" "0..1" [ps20b] [ps30] +// DYNAMIC: "VOMIT_ENABLE" "0..1" +// SKIP: ( $LOCAL_CONTRAST_ENABLE == 0 ) && ( $BLURRED_VIGNETTE_ENABLE == 1 ) + +// DYNAMIC: "TV_GAMMA" "0..1" [ps20b] [PC] +// DYNAMIC: "DESATURATEENABLE" "0..1" [ps20b] [PC] +// SKIP: ( $TOOL_MODE == 0 ) && $TV_GAMMA +// SKIP: ( $TOOL_MODE == 0 ) && $DESATURATEENABLE + +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler FBTextureSampler : register( s1 ); +sampler ColorCorrectionVolumeTexture0 : register( s2 ); +sampler ColorCorrectionVolumeTexture1 : register( s3 ); +sampler ColorCorrectionVolumeTexture2 : register( s4 ); +sampler ColorCorrectionVolumeTexture3 : register( s5 ); +sampler NoiseSampler : register( s6 ); +sampler VignetteSampler : register( s7 ); +sampler ScreenEffectSampler : register( s8 ); // used for vomit/paint screen particle effects + +float4 psTapOffs_Packed : register( c0 ); // psTapOffs_packed contains 1-pixel offsets: ( +dX, 0, +dY, -dX ) +float4 tweakables : register( c1 ); // (x - AA strength/unused) (y - reduction of 1-pixel-line blur) + // (z - edge threshold multipler) (w - tap offset multiplier) +float4 uvTransform : register( c2 ); // Transform BaseTexture UVs for use with the FBTexture + +float ColorCorrectionDefaultWeight : register( c3 ); +float4 ColorCorrectionVolumeWeights : register( c4 ); + +// Bloom & Depth Blur parameters +// x: bloom amount; multiply bloom downscale buffer by this value and add to base color +// y: bloom lerp amount; lerp between base color and blurred bloom buffer with this factor (allows for color bleeding in dark areas) +// z: depth blur focal plane distance. Value is in dest alpha space [0,1], not world units. +// w: depth blur scale value; scale distance from focal plane by this amount +float4 BloomParameters : register( c5 ); +#define g_flBloomAmount ( BloomParameters.x ) +#define g_flBloomLerpFactor ( BloomParameters.y ) +#define g_flDepthBlurFocalDistance ( BloomParameters.z ) +#define g_flDepthBlurScale ( BloomParameters.w ) + +float g_flNoiseScalar : register( c6 ); +float g_flTime : register( c7 ); +float4 g_vLocalContrastParams : register( c8 ); +#define g_flLocalContrastStrength g_vLocalContrastParams.x +#define g_flLocalContrastMidToneMask g_vLocalContrastParams.y +#define g_flBlurredVignetteStrength g_vLocalContrastParams.z + +float4 g_vLocalContrastVignetteParams : register( c9 ); +#define g_flLocalContrastVignetteStart g_vLocalContrastVignetteParams.x +#define g_flLocalContrastVignetteEnd g_vLocalContrastVignetteParams.y +#define g_flLocalContrastEdgeStrength g_vLocalContrastVignetteParams.z + +float g_flFadeToBlackStrength : register( c10 ); + +float4 g_vVomitColor[2] : register( c11 ); +#define g_flVomitRefractStrength g_vVomitColor[0].a + +float4 g_vViewportTransform : register( c13 ); +float4 g_vInvViewportTransform : register( c14 ); + +float4 g_vViewFadeColor : register( c15 ); + +float2 g_c16 : register( c16 ); +#define g_flDesaturation g_c16.x +#define g_flFadeMode2 g_c16.y + +float Luminance( float3 cColor ) +{ + float3 tmpv = { 0.2125, 0.7154, 0.0721 }; + float flLuminance = dot( cColor.rgb, tmpv.rgb ); + return flLuminance; +} + +float4 GetBloomColor( float2 bloomUV ) +{ + return tex2D( BaseTextureSampler, bloomUV ); +} + +float4 PerformColorCorrection( float4 outColor ) +{ + if (COL_CORRECT_NUM_LOOKUPS > 0) + { + // NOTE: This code requires the color correction texture to be 32 units to be correct. + // This code will cause (0,0,0) to be read from 0.5f/32 + // and (1,1,1) to be read from 31.5f/32 + float4 offsetOutColor = outColor*(31.0f/32.0f) + (0.5f/32.0f); + + outColor.rgb = outColor.rgb * ColorCorrectionDefaultWeight; + outColor.rgb += tex3D( ColorCorrectionVolumeTexture0, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.x; + if (COL_CORRECT_NUM_LOOKUPS > 1) + { + outColor.rgb += tex3D( ColorCorrectionVolumeTexture1, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.y; + if (COL_CORRECT_NUM_LOOKUPS > 2) + { + outColor.rgb += tex3D( ColorCorrectionVolumeTexture2, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.z; + if (COL_CORRECT_NUM_LOOKUPS > 3) + { + outColor.rgb += tex3D( ColorCorrectionVolumeTexture3, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.w; + } + } + } + } + + return outColor; +} + +float3 PerformVomitBlend( float3 vRefractParams, float3 vFullResColor, float3 vBlurredColor ) +{ + float3 vVomitColor = lerp( g_vVomitColor[0].rgb, g_vVomitColor[1].rgb, vRefractParams.z ); // vomit tint + + vFullResColor.rgb *= lerp( float3( 1, 1, 1 ), vVomitColor, vRefractParams.z ); // vomit tint full-res buffer + vFullResColor.rgb = lerp ( vFullResColor.rgb, vVomitColor.rgb * vBlurredColor.rgb, vRefractParams.z ); + return vFullResColor.rgb; +} + +float2 PerformUVTransform( float2 bloomUVs ) +{ + // NOTE: 'wz' is used since 'zw' is not a valid swizzle for ps20 shaders + return bloomUVs*uvTransform.wz + uvTransform.xy; +} + +// Apply TV Gamma for movie layoff specific to 360 TV movie playback path +float3 SrgbGammaToTvGamma( float3 cInput ) +{ + float3 cLinear = SrgbGammaToLinear( cInput ); + return pow( cLinear, 1.0f / 2.5f ); +} + + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 fbTexCoord = 0; + #if !defined( SHADER_MODEL_PS_2_0 ) + { + fbTexCoord.xy = PerformUVTransform( i.baseTexCoord ); + fbTexCoord.zw = i.baseTexCoord; + } + #else + { + fbTexCoord.xy = PerformUVTransform( i.baseTexCoord ); + } + #endif + + float4 cBloomBlurredLum = GetBloomColor( i.baseTexCoord ); // bloom color and blurred luminance in alpha + float4 vVomitRefractParams; + #if ( VOMIT_ENABLE == 1 ) + { + // perturb texture coordinate + vVomitRefractParams = tex2D( ScreenEffectSampler, i.baseTexCoord ); + fbTexCoord = fbTexCoord + g_flVomitRefractStrength * ( vVomitRefractParams.xyxy - 0.5 ); + + #if !defined( SHADER_MODEL_PS_2_0 ) + { + // screen coords -> viewport coords + float4 vNormalizedTexCoord = g_vViewportTransform.xyxy * fbTexCoord + g_vViewportTransform.zwzw; + // mirrored repeat texcoord math doesn't fit into 2.0 + vNormalizedTexCoord = min( 2.0 - vNormalizedTexCoord, abs( vNormalizedTexCoord ) ); + // viewport coords -> screen coords + fbTexCoord = g_vInvViewportTransform.xyxy * vNormalizedTexCoord + g_vInvViewportTransform.zwzw; + + cBloomBlurredLum = GetBloomColor( fbTexCoord.zw ); // fetch again with perturbed texcoords + } + #else + { + cBloomBlurredLum = GetBloomColor( fbTexCoord.xy ); // fetch again with perturbed texcoords + } + #endif + } + #endif + + float4 rawColor = tex2D( FBTextureSampler, fbTexCoord.xy ).rgba; + float3 baseColor = rawColor.rgb; + float depthValue = rawColor.a; + + #if ( CONVERT_FROM_LINEAR == 1 ) + { + baseColor.rgb = SrgbLinearToGamma( baseColor.rgb ); + } + #endif + + float4 outColor = float4( baseColor, 1 ); + + #if ( AA_ENABLE == 1 ) + { + float3 up; + float3 dn; + float3 lf; + float3 rt; + float3 uplf; + float3 uprt; + float3 dnlf; + float3 dnrt; + + // psTapOffs_packed contains 1-pixel offsets: ( +dX, 0, +dY, -dX ) + float4 texelDelta = psTapOffs_Packed.xyzw; + dn = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.yz ).rgb; // ( 0,+1) + rt = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.xy ).rgb; // (+1, 0) + up = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.yz ).rgb; // ( 0,-1) + lf = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.xy ).rgb; // (-1, 0) + dnlf = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.wz ).rgb; // (-1,+1) + uprt = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.wz ).rgb; // (+1,-1) + texelDelta.y = texelDelta.z; // Can't quite get all 8 sample offsets from a single float4 with the allowed swizzles! + uplf = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.xy ).rgb; // (+1,+1) + dnrt = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.xy ).rgb; // (-1,-1) + + // Generate the edge mask + float flBaseLum = Luminance( baseColor.rgb ); + float flEdge = saturate( abs( Luminance( dn.rgb ) - flBaseLum ) - 0.1 ); + flEdge += saturate( abs( Luminance( up.rgb ) - flBaseLum ) - 0.1 ); + flEdge += saturate( abs( Luminance( lf.rgb ) - flBaseLum ) - 0.1 ); + flEdge += saturate( abs( Luminance( rt.rgb ) - flBaseLum ) - 0.1 ); + flEdge *= 5.0; + + // Average full 3x3 neighborhood of pixels giving more weight to the center sample + float3 vBlurColor = ( baseColor.rgb * 4.0f ) + up.rgb + dn.rgb + lf.rgb + rt.rgb + dnrt.rgb + uprt.rgb + dnlf.rgb + uplf.rgb; + vBlurColor.rgb *= 0.0833333; // 1.0 / 12.0 + + // Lerp between crisp and blurry pixel based on edge mask + outColor.rgb = lerp( baseColor.rgb, vBlurColor.rgb, saturate( flEdge ) ); + } + #endif + + #if ( VOMIT_ENABLE == 1 ) + { + outColor.rgb = PerformVomitBlend( vVomitRefractParams.xyz, outColor.rgb, cBloomBlurredLum.aaa ); + } + #endif + + #if ( LOCAL_CONTRAST_ENABLE == 1 ) + { + float fMask = 1.0; + + // Extract midtones and limit contrast enhancement there + // TODO: This can probably go away for perf. + //float fBrightness = dot( outColor.rgb, float3( 0.3, 0.59, 0.11 ) ); + // bell-shaped mask + //fMask = smoothstep( 0.5 - g_flLocalContrastMidToneMask, 0.5, fBrightness ); + //fMask *= smoothstep( 0.5 + g_flLocalContrastMidToneMask, 0.5, fBrightness ); + + //fMask = smoothstep( 1.0, 0.5, fBrightness ); + + /* + // unsharp mask on luminance only + // This is the technically correct way, going to YUV, applying contrast to Y, and converting back to RGB + float3 outColorYUV; + outColorYUV.x = dot( outColor.rgb, float3( 0.299, 0.587, 0.114 ) ); + outColorYUV.y = dot( outColor.rgb, float3( -0.14713, -0.28886, 0.436 ) ); + outColorYUV.z = dot( outColor.rgb, float3( 0.615, -0.51499, -0.10001 ) ); + outColorYUV.x = outColorYUV.x + g_flLocalContrastStrength * fMask * ( outColorYUV.x - cBloomBlurredLum.aaa ); + outColor.r = dot( outColorYUV.xyz, float3( 1.0, 0.0, 1.13983 ) ); + outColor.g = dot( outColorYUV.xyz, float3( 1.0, -0.39465, -0.58060 ) ); + outColor.b = dot( outColorYUV.xyz, float3( 1.0, 2.03211, 0.0 ) ); + */ + + // This applies the delta contrast derived from the luminance to all color channels. The difference to the + // correct way is imperceptible. + float fLuminance = dot( outColor.rgb, float3( 0.299, 0.587, 0.114 ) ); + float fContrastLum = fLuminance + g_flLocalContrastStrength * ( fLuminance - cBloomBlurredLum.a ); + + // Mask off pixels that got very bright, to control super-contrast + //fMask = 1.0 - smoothstep( 0.3, 1.0, fContrastLum ); + + float2 vCenterDir = ( 2.0 * i.baseTexCoord.xy ) - 1.0; + float fMyVignette = smoothstep( g_flLocalContrastVignetteStart, g_flLocalContrastVignetteEnd, length( vCenterDir ) ); + float fMyVignette2 = fMyVignette; + fMyVignette = lerp( g_flLocalContrastStrength, g_flLocalContrastEdgeStrength, fMyVignette ); + + fMask = fMyVignette; + + // If the mask is positive, only brighten pixels. If the mask is negative, don't let it get less than -1.0. + //outColor.rgb += fMask * ( fLuminance - cBloomBlurredLum.aaa ); + outColor.rgb += max( fMask * ( fLuminance - cBloomBlurredLum.aaa ), -1.0 + step( 0.0, fMask ) ); // Selective clamp to positive adds 4 instructions + + #if ( BLURRED_VIGNETTE_ENABLE == 1 ) + outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.aaa, fMyVignette2 * g_flBlurredVignetteStrength ); + #endif + } + #endif + + // Composite bloom and full-screen + depth blur effects + #if ( DEPTH_BLUR_ENABLE ) + { + float blurFactor = g_flBloomLerpFactor + abs( depthValue - g_flDepthBlurFocalDistance ) * g_flDepthBlurScale; + blurFactor = clamp( blurFactor, 0, 1 ); + outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.rgb, blurFactor ); + outColor.rgb += g_flBloomAmount * cBloomBlurredLum.rgb; + } + #else + { + outColor.rgb += g_flBloomAmount * cBloomBlurredLum.rgb; + } + #endif + + // Used to be FADE_TYPE 0..2 combo + float3 vFadeDestColor = lerp( g_vViewFadeColor.rgb, g_vViewFadeColor.rgb * outColor.rgb, g_flFadeMode2 ); + outColor.rgb = lerp( outColor.rgb, vFadeDestColor.rgb, g_vViewFadeColor.a ); + + #if ( DESATURATEENABLE ) + { + float flLum = saturate( dot( outColor.rgb, float3( 0.3f, 0.59f, 0.11f) ) ); + outColor.rgb = lerp( saturate( outColor.rgb ), flLum.xxx, saturate( g_flDesaturation ) ); + } + #else + { + outColor = PerformColorCorrection( outColor ); // Color correction + } + #endif + + // Vignette + #if ( VIGNETTE_ENABLE == 1 ) + { + // Vignette + float2 vUv = i.baseTexCoord.xy; + //float2 vTmp = ( vUv.xy * 2.0 ) - 1.0; + float flVignette; + + //flVignette = 1.0 - pow( abs( vTmp.x ), 6.0f ); + //flVignette *= 1.0 - pow( abs( vTmp.y ), 6.0f ); + //flVignette = 1.0 - ( 1.0 - flVignette ) * ( ( saturate( ( 1.0 - vUv.y ) - 0.3 ) / 0.7 ) ); + + // This tex2D solves the 3 lines of math above + flVignette = tex2D( VignetteSampler, vUv.xy ).r; // Red is for the PC + flVignette = saturate( flVignette * 0.55 + 0.46 ); + + outColor.rgb *= flVignette; + } + #endif + + // Noise + #if ( NOISE_ENABLE == 1 ) + { + // Additive Noise + float2 vUv0 = i.baseTexCoord.xy * 10.0 + g_flTime; + float2 vUv1 = i.baseTexCoord.yx * 20.0 - g_flTime; + float2 vNoiseTexelUv; + vNoiseTexelUv.x = tex2D( NoiseSampler, vUv0.xy ).g; + vNoiseTexelUv.y = tex2D( NoiseSampler, vUv1.xy ).g; + float flNoiseTexel = tex2D( NoiseSampler, vNoiseTexelUv.xy ).g; + + float3 vTmp = { 0.2125f, 0.7154f, 0.0721f }; + float flLuminance = saturate( dot( outColor.rgb, vTmp.rgb ) ); + + float flNoiseScalar = 0.2f + 0.8f * ( saturate( pow( 1.0 - flLuminance, 12.0 ) ) ); + outColor.rgb += ( ( flNoiseTexel * 0.3f ) - 0.15f ) * g_flNoiseScalar * flNoiseScalar; + } + #endif + + // Fade to black + outColor.rgb = lerp( outColor.rgb, 0.0, g_flFadeToBlackStrength ); + + #if TV_GAMMA + { + // Used for SFM to record movies in native TV gamma space + outColor.rgb = SrgbGammaToTvGamma( outColor.rgb ); + } + #endif + + #if ( CONVERT_TO_LINEAR == 1 ) + { + // If we have a float back buffer, we want to remain in linear space after this shader + outColor.rgb = SrgbGammaToLinear( outColor.rgb ); + } + #endif + + return FinalOutput( outColor, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/materialsystem/stdshaders/sdk_eye_refract_ps30.fxc b/materialsystem/stdshaders/sdk_eye_refract_ps30.fxc new file mode 100644 index 00000000..1bf23f00 --- /dev/null +++ b/materialsystem/stdshaders/sdk_eye_refract_ps30.fxc @@ -0,0 +1,401 @@ +//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =========================== + +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "SPHERETEXKILLCOMBO" "0..1" +// STATIC: "RAYTRACESPHERE" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" + +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" + +// We don't use other lights when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) +// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) + +// Includes ======================================================================================= +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +// Texture Samplers =============================================================================== +sampler g_tCorneaSampler : register( s0 ); +sampler g_tIrisSampler : register( s1 ); +sampler g_tEyeReflectionCubemapSampler : register( s2 ); +sampler g_tEyeAmbientOcclSampler : register( s3 ); +sampler g_tLightwarpSampler : register( s4 ); // 1D texture for TF NPR lighting + +sampler g_tFlashlightCookieSampler : register( s5 ); +sampler g_tFlashlightDepthSampler : register( s6 ); +sampler g_tRandomRotationSampler : register( s7 ); + +// Shaders Constants and Globals ================================================================== +const float4 g_vPackedConst0 : register( c0 ); +#define g_flDilationFactor g_vPackedConst0.x +#define g_flGlossiness g_vPackedConst0.y +#define g_flAverageAmbient g_vPackedConst0.z +#define g_flCorneaBumpStrength g_vPackedConst0.w + +const float3 g_vEyeOrigin : register( c1 ); +const float4 g_vIrisProjectionU : register( c2 ); +const float4 g_vIrisProjectionV : register( c3 ); +const float4 g_vCameraPosition : register( c4 ); +const float3 g_cAmbientOcclColor : register( c5 ); + +const float4 g_vPackedConst6 : register( c6 ); +#define g_flEyeballRadius g_vPackedConst6.y //0.51f +#define g_flParallaxStrength g_vPackedConst6.w //0.25f + +// Flashlight constants +const float4 g_vFlashlightAttenuationFactors : register( c7 ); // FarZ in w +const float3 g_vFlashlightPos : register( c8 ); +const float4 g_vShadowTweaks : register( c9 ); +const float4 g_ShaderControls : register( c10 ); +#define g_fPixelFogType g_ShaderControls.x + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + +PixelShaderLightInfo g_sLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; + float4 cVertexLight : TEXCOORD1; // w is used for the flashlight pass + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +// Ray sphere intersect returns distance along ray to intersection ================================ +float IntersectRaySphere ( float3 cameraPos, float3 ray, float3 sphereCenter, float sphereRadius) +{ + float3 dst = cameraPos.xyz - sphereCenter.xyz; + float B = dot(dst, ray); + float C = dot(dst, dst) - (sphereRadius * sphereRadius); + float D = B*B - C; + return (D > 0) ? (-B - sqrt(D)) : 0; +} + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Set bools to compile out code + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + int nNumLights = FLASHLIGHT ? 1 : NUM_LIGHTS; // Flashlight is considered one light, otherwise, use numlights combo + bool bRayCast = RAYTRACESPHERE ? true : false; + bool bRayCastTexKill = SPHERETEXKILLCOMBO ? true : false; + + float flFlashlightNDotL = i.vTangentViewVector.w; + float4 vFlashlightTexCoord = { 0.0f, 0.0f, 0.0f, 0.0f }; + if ( bFlashlight ) + { + vFlashlightTexCoord.xyzw = i.cVertexLight.xyzw; // This was hidden in this interpolator + i.cVertexLight.rgba = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + + // Interpolated vectors + float3 vWorldNormal = i.vWorldNormal.xyz; + float3 vWorldTangent = i.vWorldTangent.xyz; + float3 vWorldBinormal = ( i.vWorldBinormal.xyz * 2.0f ) - 1.0f; // normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + + float3 vTangentViewVector = i.vTangentViewVector.xyz; + + // World position + float3 vWorldPosition = i.vWorldPosition_ProjPosZ.xyz; + + // World view vector to pixel + float3 vWorldViewVector = normalize( vWorldPosition.xyz - g_vCameraPosition.xyz ); + + //=================// + // TF NPR lighting // + //=================// + if ( bDoDiffuseWarp ) + { + // Replace the interpolated vertex light + if ( bFlashlight == true ) + { + // Deal with this below in the flashlight section + } + else + { + if ( nNumLights > 0 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 1 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 2 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 3 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ) * cWarpedLight.rgb; + } + } + } + + //==========================================================================================================// + // Ray cast against sphere representing eyeball to reduce artifacts from non-spherical morphed eye geometry // + //==========================================================================================================// + if ( bRayCast ) + { + float fSphereRayCastDistance = IntersectRaySphere( g_vCameraPosition.xyz, vWorldViewVector.xyz, g_vEyeOrigin.xyz, g_flEyeballRadius ); + vWorldPosition.xyz = g_vCameraPosition.xyz + ( vWorldViewVector.xyz * fSphereRayCastDistance ); + if (fSphereRayCastDistance == 0) + { + if ( bRayCastTexKill ) + clip(-1); // texkill to get a better silhouette + vWorldPosition.xyz = g_vEyeOrigin.xyz + ( vWorldNormal.xyz * g_flEyeballRadius ); + } + } + + //=================================// + // Generate sphere and cornea uv's // + //=================================// + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; + + //=================================// + // Hacked parallax mapping on iris // + //=================================// + float fIrisOffset = tex2D( g_tCorneaSampler, vCorneaUv.xy ).b; + + float2 vParallaxVector = ( ( vTangentViewVector.xy * fIrisOffset * g_flParallaxStrength ) / ( 1.0f - vTangentViewVector.z ) ); // Note: 0.25 is a magic number + vParallaxVector.x = -vParallaxVector.x; //Need to flip x...not sure why. + + float2 vIrisUv = vSphereUv.xy - vParallaxVector.xy; + + // Note: We fetch from this texture twice right now with different uv's for the color and alpha + float2 vCorneaNoiseUv = vSphereUv.xy + ( vParallaxVector.xy * 0.5 ); + float fCorneaNoise = tex2D( g_tIrisSampler, vCorneaNoiseUv.xy ).a; + + //===============// + // Cornea normal // + //===============// + // Sample 2D normal from texture + float3 vCorneaTangentNormal = { 0.0, 0.0, 1.0 }; + float4 vCorneaSample = tex2D( g_tCorneaSampler, vCorneaUv.xy ); + vCorneaTangentNormal.xy = vCorneaSample.rg - 0.5f; // Note: This scales the bump to 50% strength + + // Scale strength of normal + vCorneaTangentNormal.xy *= g_flCorneaBumpStrength; + + // Add in surface noise and imperfections (NOTE: This should be baked into the normal map!) + vCorneaTangentNormal.xy += fCorneaNoise * 0.1f; + + // Normalize tangent vector + // Since this isn't used later in 2.0, skip the normalize to save shader instructions + vCorneaTangentNormal.xyz = normalize( vCorneaTangentNormal.xyz ); + + // Transform into world space + float3 vCorneaWorldNormal = Vec3TangentToWorldNormalized( vCorneaTangentNormal.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + //============// + // Flashlight // + //============// + float3 vFlashlightVector = { 0.0f, 0.0f, 0.0f }; + float3 cFlashlightColorFalloff = { 0.0f, 0.0f, 0.0f }; + if ( bFlashlight == true ) + { + // Flashlight vector + vFlashlightVector.xyz = normalize( g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz ); + + // Distance attenuation for flashlight and to fade out shadow over distance + float3 vDelta = g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz; + float flDistSquared = dot( vDelta, vDelta ); + float flDist = sqrt( flDistSquared ); + float flFlashlightAttenuation = dot( g_vFlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/flDist, 1.0f/flDistSquared ) ); + + // Flashlight cookie + float3 vProjCoords = vFlashlightTexCoord.xyz / vFlashlightTexCoord.w; + float3 cFlashlightCookieColor = tex2D( g_tFlashlightCookieSampler, vProjCoords ); + + // Shadow depth map +#if FLASHLIGHTSHADOWS + int nShadowLevel = FLASHLIGHTDEPTHFILTERMODE; + float flShadow = DoFlashlightShadow( g_tFlashlightDepthSampler, g_tRandomRotationSampler, vProjCoords, float2(0,0), nShadowLevel, g_vShadowTweaks, false ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, flFlashlightAttenuation ); // Blend between shadow and above, according to light attenuation + cFlashlightCookieColor *= flShadow; // Apply shadow term to cookie color +#endif + + // Flashlight color intensity (needs to be multiplied by global flashlight color later) + cFlashlightColorFalloff.rgb = flFlashlightAttenuation * cFlashlightCookieColor.rgb; + + // Add this into the interpolated lighting + if ( bDoDiffuseWarp ) + { + //float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, flFlashlightNDotL ).rgb; + //i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * cWarpedLight.rgb; + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; // No light warp for now + } + else + { + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; + } + } + + //==============// + // Dilate pupil // + //==============// + vIrisUv.xy -= 0.5f; // Center around (0,0) + float fPupilCenterToBorder = saturate( length( vIrisUv.xy ) / 0.2f ); //Note: 0.2 is the uv radius of the iris + float fPupilDilateFactor = g_flDilationFactor; // This value should be between 0-1 + vIrisUv.xy *= lerp (1.0f, fPupilCenterToBorder, saturate( fPupilDilateFactor ) * 2.5f - 1.25f ); + vIrisUv.xy += 0.5f; + + //============// + // Iris color // + //============// + float4 cIrisColor = tex2D( g_tIrisSampler, vIrisUv.xy ); + + //==========================// + // Iris lighting highlights // + //==========================// + float3 cIrisLighting = float3( 0.0f, 0.0f, 0.0f ); + + // Mask off everything but the iris pixels + float fIrisHighlightMask = tex2D( g_tCorneaSampler, vCorneaUv.xy ).a; + + // Generate the normal + float3 vIrisTangentNormal = vCorneaTangentNormal.xyz; + vIrisTangentNormal.xy *= -2.5f; // I'm not normalizing on purpose + + for ( int j=0; j < nNumLights; j++ ) + { + // World light vector + float3 vWorldLightVector; + if ( ( j == 0 ) && ( bFlashlight == true ) ) + vWorldLightVector = vFlashlightVector.xyz; + else + vWorldLightVector = PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, j ); + + // Tangent light vector + float3 vTangentLightVector = Vec3WorldToTangent( vWorldLightVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Adjust the tangent light vector to generate the iris lighting + float3 tmpv = -vTangentLightVector.xyz; + tmpv.xy *= -0.5f; //Flatten tangent view + tmpv.z = max( tmpv.z, 0.5f ); //Clamp z of tangent view to help maintain highlight + tmpv.xyz = normalize( tmpv.xyz ); + + // Core iris lighting math + float fIrisFacing = pow( abs( dot( vIrisTangentNormal.xyz, tmpv.xyz ) ), 6.0f ) * 0.5f; // Yes, 6.0 and 0.5 are magic numbers + + // Cone of darkness to darken iris highlights when light falls behind eyeball past a certain point + float flConeOfDarkness = pow( 1.0f - saturate( ( -vTangentLightVector.z - 0.25f ) / 0.75f ), 4.0f ); + //float flConeOfDarkness = pow( 1.0f - saturate( ( -dot( vIrisTangentNormal.xyz, vTangentLightVector.xyz ) - 0.15f ) / 0.85f ), 8.0f ); + + // Tint by iris color and cone of darkness + float3 cIrisLightingTmp = fIrisFacing * fIrisHighlightMask * flConeOfDarkness; + + // Attenuate by light color and light falloff + if ( ( j == 0 ) && ( bFlashlight == true ) ) + cIrisLightingTmp.rgb *= cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + else if ( j == 0 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + else if ( j == 1 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + else if ( j == 2 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + else + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + + // Sum into final variable + cIrisLighting.rgb += cIrisLightingTmp.rgb; + } + + // Add slight view dependent iris lighting based on ambient light intensity to enhance situations with no local lights (0.5f is to help keep it subtle) + cIrisLighting.rgb += saturate( dot( vIrisTangentNormal.xyz, -vTangentViewVector.xyz ) ) * g_flAverageAmbient * fIrisHighlightMask * 0.5f; + + //===================// + // Ambient occlusion // + //===================// + float3 cAmbientOcclFromTexture = tex2D( g_tEyeAmbientOcclSampler, i.vAmbientOcclUv_fallbackCorneaUv.xy ).rgb; + float3 cAmbientOcclColor = lerp( g_cAmbientOcclColor, 1.0f, cAmbientOcclFromTexture.rgb ); // Color the ambient occlusion + i.cVertexLight.rgb *= cAmbientOcclColor.rgb; + + //==========================// + // Reflection from cube map // + //==========================// + float3 vCorneaReflectionVector = reflect ( vWorldViewVector.xyz, vCorneaWorldNormal.xyz ); + + //float3 cReflection = ENV_MAP_SCALE * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + float3 cReflection = g_flGlossiness * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + + // Hack: Only add in half of the env map for the flashlight pass. This looks reasonable. + if ( bFlashlight ) + { + cReflection.rgb *= 0.5f; + } + + //===========================// + // Glint specular highlights // + //===========================// + float3 cSpecularHighlights = 0.0f; + if ( bFlashlight ) + { + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, vFlashlightVector.xyz ) ), 128.0f ) * cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + } + else // no flashlight + { + if ( nNumLights > 0 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 0 ) ) ), 128.0f ) * i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + + if ( nNumLights > 1 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 1 ) ) ), 128.0f ) * i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + + if ( nNumLights > 2 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 2 ) ) ), 128.0f ) * i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + + if ( nNumLights > 3 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 3 ) ) ), 128.0f ) * i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + } + + //===============// + // Combine terms // + //===============// + float4 result; + + // Unlit iris, pupil, and sclera color + result.rgb = cIrisColor.rgb; + + // Add in slight cornea noise to help define raised cornea layer for close-ups + result.rgb += fCorneaNoise * 0.1f; + + // Diffuse light (Vertex lighting + extra iris caustic lighting) + result.rgb *= i.cVertexLight.rgb + cIrisLighting.rgb; + + // Environment map + result.rgb += cReflection.rgb * i.cVertexLight.rgb; + + // Local light glints + result.rgb += cSpecularHighlights.rgb; + + // Set alpha to 1.0 by default + result.a = 1.0; + + float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_vCameraPosition, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); + return FinalOutput( result, fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR ); +} diff --git a/materialsystem/stdshaders/sdk_eye_refract_vs30.fxc b/materialsystem/stdshaders/sdk_eye_refract_vs30.fxc new file mode 100644 index 00000000..35df0733 --- /dev/null +++ b/materialsystem/stdshaders/sdk_eye_refract_vs30.fxc @@ -0,0 +1,206 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" + +#include "common_vortwarp_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 g_cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_vIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 g_vIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 g_vFlashlightPosition : register( SHADER_SPECIFIC_CONST_4 ); + +#if INTRO +const float4 g_vConst4 : register( SHADER_SPECIFIC_CONST_5 ); +#define g_vModelOrigin g_vConst4.xyz +#define g_flTime g_vConst4.w +#endif + +const float4 g_vFlashlightMatrixRow1 : register( SHADER_SPECIFIC_CONST_6 ); +const float4 g_vFlashlightMatrixRow2 : register( SHADER_SPECIFIC_CONST_7 ); +const float4 g_vFlashlightMatrixRow3 : register( SHADER_SPECIFIC_CONST_8 ); +const float4 g_vFlashlightMatrixRow4 : register( SHADER_SPECIFIC_CONST_9 ); + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position deltas + float3 vPosFlex : POSITION1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; // Base texture coordinate + float4 cVertexLight : TEXCOORD1; // Vertex-lit color (Note: w is used for flashlight pass) + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vPosition = v.vPos; + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz ); +#else + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#endif + + // Transform the position + float3 vWorldPosition; + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPosition ); + + // Note: I'm relying on the iris projection vector math not changing or this will break + float3 vEyeSocketUpVector = normalize( -g_vIrisProjectionV.xyz ); + float3 vEyeSocketLeftVector = normalize( -g_vIrisProjectionU.xyz ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_flTime, g_vModelOrigin, vWorldPosition, dummy, dummy, dummy ); +#endif + + o.vWorldPosition_ProjPosZ.xyz = vWorldPosition.xyz; + + // Transform into projection space + //vWorldPosition -= ( vWorldPosition - g_cEyeOrigin ) * 0.9; //Debug to visualize eye origin + float4 vProjPos = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( vWorldPosition, 1.0f ), cViewProjZ ); + + o.vWorldPosition_ProjPosZ.w = vProjPos.z; + + // Normal = (Pos - Eye origin) + float3 vWorldNormal = normalize( vWorldPosition.xyz - g_cEyeOrigin.xyz ); + o.vWorldNormal.xyz = vWorldNormal.xyz; + + // Tangent & binormal + /* + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vEyeSocketLeftVector.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + + float3 vWorldTangent = normalize( cross( vWorldBinormal.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + //*/ + + //* + float3 vWorldTangent = normalize( cross( vEyeSocketUpVector.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + //*/ + + float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz); + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized (vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz); + + // AV - I think this will effectively make the eyeball less rounded left to right to help vertext lighting quality + // AV - Note: This probably won't look good if put on an exposed eyeball + //float vNormalDotSideVec = -dot( vWorldNormal, g_vEyeballUp ) * 0.5f; + float vNormalDotSideVec = -dot( vWorldNormal, vEyeSocketLeftVector) * 0.5f; + float3 vBentWorldNormal = normalize(vNormalDotSideVec * vEyeSocketLeftVector + vWorldNormal); + + // Compute vertex lighting + o.cVertexLight.a = 0.0f; //Only used for flashlight pass + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vBentWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, nNumLights ); + + // Only interpolate ambient light for TF NPR lighting + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + if ( bDoDiffuseWarp ) + { + if( bDynamicLight ) + { + o.cVertexLight.rgb = AmbientLight( vBentWorldNormal.xyz ); + } + else + { + o.cVertexLight.rgb = float3( 0.0f, 0.0f, 0.0f ); + } + } + +// NOTE: it appears that o.vLightFalloffCosine01 and o.vLightFalloffCosine23 are filled in even if +// we don't have enough lights, meaning we pass garbage to the pixel shader which then throws it away + + // Light falloff for first two local lights + o.vLightFalloffCosine01.x = VertexAttenInternal( vWorldPosition.xyz, 0 ); + o.vLightFalloffCosine01.y = VertexAttenInternal( vWorldPosition.xyz, 1 ); + o.vLightFalloffCosine01.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 0, g_bHalfLambert ); + o.vLightFalloffCosine01.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 1, g_bHalfLambert ); + + // Light falloff for next two local lights + o.vLightFalloffCosine23.x = VertexAttenInternal( vWorldPosition.xyz, 2 ); + o.vLightFalloffCosine23.y = VertexAttenInternal( vWorldPosition.xyz, 3 ); + o.vLightFalloffCosine23.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 2, g_bHalfLambert ); + o.vLightFalloffCosine23.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 3, g_bHalfLambert ); + + // Texture coordinates set by artists for ambient occlusion + o.vAmbientOcclUv_fallbackCorneaUv.xy = v.vTexCoord0.xy; + + // Cornea uv for ps.2.0 fallback + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; + o.vAmbientOcclUv_fallbackCorneaUv.wz = vCorneaUv.xy; // Note: wz unpacks faster than zw in ps.2.0! + + // Step on the vertex light interpolator for the flashlight tex coords + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + o.vTangentViewVector.w = 0.0f; + if ( bFlashlight ) + { + o.cVertexLight.x = dot( g_vFlashlightMatrixRow1.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.y = dot( g_vFlashlightMatrixRow2.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.z = dot( g_vFlashlightMatrixRow3.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.w = dot( g_vFlashlightMatrixRow4.xyzw, float4( vWorldPosition, 1.0f ) ); + + o.vTangentViewVector.w = saturate( dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ) ); // Flashlight N.L with modified normal + + // Half lambert version + //o.cVertexLight.z = dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ); // Flashlight N.L with modified normal + //o.cVertexLight.z = ( o.cVertexLight.z * 0.5f ) + 0.5f; + //o.cVertexLight.z *= o.cVertexLight.z; + } + + return o; +} diff --git a/materialsystem/stdshaders/eyeglint_ps2x.fxc b/materialsystem/stdshaders/sdk_eyeglint_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/eyeglint_ps2x.fxc rename to materialsystem/stdshaders/sdk_eyeglint_ps30.fxc diff --git a/materialsystem/stdshaders/eyeglint_vs20.fxc b/materialsystem/stdshaders/sdk_eyeglint_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/eyeglint_vs20.fxc rename to materialsystem/stdshaders/sdk_eyeglint_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_eyes_flashlight_ps30.fxc b/materialsystem/stdshaders/sdk_eyes_flashlight_ps30.fxc new file mode 100644 index 00000000..ea34ddc5 --- /dev/null +++ b/materialsystem/stdshaders/sdk_eyes_flashlight_ps30.fxc @@ -0,0 +1,99 @@ +//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +sampler SpotSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); +sampler IrisSampler : register( s3 ); + +#if FLASHLIGHTSHADOWS && (!SHADER_MODEL_PS_1_1) && (!SHADER_MODEL_PS_1_4) && (!SHADER_MODEL_PS_2_0) +sampler FlashlightDepthSampler : register( s4 ); +sampler RandomRotationSampler : register( s5 ); +#endif + +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + +#else + const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +#endif + +struct PS_INPUT +{ + float4 spotTexCoord : TEXCOORD0; + float2 baseTexCoord : TEXCOORD1; + float2 irisTexCoord : TEXCOORD3; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 vertAtten : COLOR0; +#else + float3 vertAtten : TEXCOORD4; + float3 worldPos : TEXCOORD5; + float3 projPos : TEXCOORD7; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if defined(SHADER_MODEL_PS_2_0) + float3 spotColor = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ) * cFlashlightColor; +#elif ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 spotColor = tex2D( SpotSampler, vProjCoords ) * cFlashlightColor; +#else + float3 spotColor = tex2D( SpotSampler, i.spotTexCoord ); +#endif + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); + + float3 outcolor = float3(1,1,1); + +#if !defined( SHADER_MODEL_PS_1_1 ) && !defined( SHADER_MODEL_PS_1_4 ) + if( i.spotTexCoord.w <= 0.0f ) + { + outcolor = float3(0,0,0); + } +#endif + + // Composite the iris and sclera together +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 albedo = lerp( baseSample.xyz, irisSample.xyz, irisSample.a ); +#else + float3 albedo = lerp( baseSample.xyz, irisSample.xyz * 0.5f, irisSample.a ); // dim down the iris in HDR +#endif + + // Do shadow depth mapping... +#if FLASHLIGHTSHADOWS && ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, true ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, dot(i.vertAtten, float3(0.30f, 0.59f, 0.11f) ) ); // Blend between shadow and above, according to light attenuation + outcolor *= flShadow * spotColor * albedo; +#else + outcolor *= spotColor * albedo; +#endif + + // NOTE!! This has to be last to avoid loss of range. + outcolor *= i.vertAtten; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + return float4( outcolor, baseSample.a ); +#else + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos.z, i.projPos.z ); + return FinalOutput( float4( outcolor, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#endif + +} diff --git a/materialsystem/stdshaders/sdk_eyes_flashlight_vs30.fxc b/materialsystem/stdshaders/sdk_eyes_flashlight_vs30.fxc new file mode 100644 index 00000000..0479e2d5 --- /dev/null +++ b/materialsystem/stdshaders/sdk_eyes_flashlight_vs30.fxc @@ -0,0 +1,135 @@ +// ------------------------------------------------------------------------------ +// $cLight0Pos = world space light position +// $SHADER_SPECIFIC_CONST_1 = spotlight projection +// $SHADER_SPECIFIC_CONST_2 = spotlight projection +// $SHADER_SPECIFIC_CONST_3 = spotlight projection +// $SHADER_SPECIFIC_CONST_4 = spotlight projection +// $SHADER_SPECIFIC_CONST_5 = far z +// $SHADER_SPECIFIC_CONST_6 = eyeball origin +// $SHADER_SPECIFIC_CONST_7 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_8 = iris projection U +// $SHADER_SPECIFIC_CONST_9 = iris projection V +// ------------------------------------------------------------------------------ + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cLightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_8 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_9 ); + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vNormal : NORMAL; + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float4 spotTexCoord : TEXCOORD0; // Spotlight texture coordinates + float2 baseTexCoord : TEXCOORD1; // Base texture coordinates + float2 irisTexCoord : TEXCOORD3; // Iris texture coordinates + float3 vertAtten : TEXCOORD4; // vertex attenuation + float3 worldPos : TEXCOORD5; + float3 projPosXYZ : TEXCOORD7; +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + worldNormal = normalize( worldNormal ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.projPosXYZ = projPos.xyz; + o.worldPos = worldPos.xyz; + + // Base texture coordinates + o.baseTexCoord = v.vTexCoord0; + + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cLightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); // distsquared + vDistAtten.y = rsqrt( vDistAtten.z ); // 1 / dist + + float flDist = vDistAtten.z * vDistAtten.y; // dist + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + o.vertAtten *= dot( normalize( vWorldPosToLightVector ), worldNormal ); + + o.irisTexCoord.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTexCoord.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + + return o; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/sdk_eyes_ps30.fxc b/materialsystem/stdshaders/sdk_eyes_ps30.fxc new file mode 100644 index 00000000..aad7afce --- /dev/null +++ b/materialsystem/stdshaders/sdk_eyes_ps30.fxc @@ -0,0 +1,68 @@ +//====== Copyright 1996-2006, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler IrisSampler : register( s1 ); +sampler GlintSampler : register( s2 ); +const float4 cEyeScalars : register( c0 ); // { Dilation, ambient, x, x } + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float2 irisTexCoord : TEXCOORD1; + float2 glintTexCoord : TEXCOORD2; + float3 vertAtten : TEXCOORD3; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +#define fDilationFactor cEyeScalars.x +#define fGlintDamping cEyeScalars.y + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 glintSample = tex2D( GlintSampler, i.glintTexCoord ); +/* + // Dilate the pupil/iris texture (1 is max dilation, 0 is none) + float2 biasedCoords = i.irisTexCoord * 2.0f - 1.0f; // -1 to +1 range + float fDilatability = saturate(0.8f - sqrt(dot(biasedCoords, biasedCoords) )); // 1 in the center, fading out to 0 at 0.8 from center, since irises are inset into maps + float2 scaledCoords = biasedCoords * (1 + fDilatability); // Maximal dilation + + // Blend undilated and maximally dilated based upon dilation factor + float2 dilatedCoords = lerp( scaledCoords, biasedCoords, 1.0f-saturate(cDilationFactor.x)); + dilatedCoords = dilatedCoords * 0.5f + 0.5f; // Back to 0..1 range +*/ + + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); // Sample the iris map using dilated coordinates + + float4 result; + result.rgb = lerp( baseSample.rgb, irisSample.rgb, irisSample.a ); + result.rgb *= i.vertAtten; + result.rgb += glintSample.rgb * fGlintDamping; + result.a = baseSample.a; + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = WRITE_DEPTH_TO_DESTALPHA != 0; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshaders/sdk_eyes_vs30.fxc b/materialsystem/stdshaders/sdk_eyes_vs30.fxc new file mode 100644 index 00000000..984a16d2 --- /dev/null +++ b/materialsystem/stdshaders/sdk_eyes_vs30.fxc @@ -0,0 +1,126 @@ +//======= Copyright � 1996-2006, Valve Corporation, All rights reserved. ====== +// $SHADER_SPECIFIC_CONST_0 = eyeball origin +// $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_2 = iris projection U +// $SHADER_SPECIFIC_CONST_3 = iris projection V +// $SHADER_SPECIFIC_CONST_4 = glint projection U +// $SHADER_SPECIFIC_CONST_5 = glint projection V +//============================================================================= + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" + +#include "common_vortwarp_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const int g_bSkinning = SKINNING ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float3 cHalfEyeballUp : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cGlintProjectionU : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cGlintProjectionV : register( SHADER_SPECIFIC_CONST_5 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_6 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_7 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_8 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + float3 vPosFlex : POSITION1; // Delta positions for flexing +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float2 baseTC : TEXCOORD0; // Base texture coordinate + float2 irisTC : TEXCOORD1; // Iris texture coordinates + float2 glintTC : TEXCOORD2; // Glint texture coordinates + float3 vColor : TEXCOORD3; // Vertex-lit color + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 dummy = v.vPos.xyz; // dummy values that can't be optimized out + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, dummy, vPosition.xyz ); +#else + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#endif + + // Transform the position and dummy normal (not doing the dummy normal causes invariance issues with the flashlight!) + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, dummy, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, dummy, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + // Normal = (Pos - Eye origin) - just step on dummy normal created above + worldNormal = worldPos - cEyeOrigin; + + // Normal -= 0.5f * (Normal dot Eye Up) * Eye Up + float normalDotUp = -dot( worldNormal, cHalfEyeballUp) * 0.5f; + worldNormal = normalize(normalDotUp * cHalfEyeballUp + worldNormal); + + // Vertex lighting + o.vColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); + + // Texture 0 is the base texture + // Texture 1 is a planar projection used for the iris + // Texture 2 is a planar projection used for the glint + o.baseTC = v.vTexCoord0; + o.irisTC.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTC.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + o.glintTC.x = dot( cGlintProjectionU, float4(worldPos, 1) ); + o.glintTC.y = dot( cGlintProjectionV, float4(worldPos, 1) ); + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_ps30.fxc b/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_ps30.fxc new file mode 100644 index 00000000..9776a28e --- /dev/null +++ b/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_ps30.fxc @@ -0,0 +1,126 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// +// Includes ======================================================================================= +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +#include "common_vertexlitgeneric.h" + +// Texture Samplers =============================================================================== +sampler g_tBaseSampler : register( s0 ); +sampler g_tNoiseSampler : register( s1 ); +sampler g_tBorder1DSampler : register( s2 ); +sampler g_tNormalSampler : register( s3 ); +sampler g_tSubsurfaceSampler: register( s4 ); +sampler g_tCubeSampler : register( s5 ); + +// Shaders Constants and Globals ================================================================== +const float3 g_cSubsurfaceTint : register( c0 ); +const float2 g_flBorderWidth : register( c1 ); //{ 1.0f / g_flBorderWidthFromVmt, ( 1.0f / g_flBorderWidthFromVmt ) - 1.0f }; +const float g_flBorderSoftness : register( c2 ); +const float3 g_cBorderTint : register( c3 ); +const float g_flGlobalOpacity : register( c4 ); +const float g_flGlossBrightness : register( c5 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Color texture + float4 cBaseColor = tex2D( g_tBaseSampler, i.vTexCoord0.xy ); + float flFleshMaskFromTexture = cBaseColor.a; + + // Subsurface colors + float4 cSubsurfaceColor = tex2D( g_tSubsurfaceSampler, i.vTexCoord0.xy ); + cBaseColor.rgb += cBaseColor.rgb * cSubsurfaceColor.rgb * g_cSubsurfaceTint.rgb; + + // Scroll noise textures to ripple border of opening + float flNoise0 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.xy ).g; // Use green so we can DXT1 if we want + float flNoise1 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.wz ).g; // Use green so we can DXT1 if we want + float flNoise = ( flNoise0 + flNoise1 ) * 0.5f; + + // Generate 0-1 mask from distance computed in the VS + float flClampedInputMask = 0.0f; + flClampedInputMask = 1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x ); + flClampedInputMask *= i.flDistanceToEffectCenter_flFresnelEffect.y; + flClampedInputMask *= flFleshMaskFromTexture; + + // Noise mask - Only apply noise around border of sphere + float flBorderMask = saturate( ( 1.0f - flClampedInputMask ) * g_flBorderWidth.x - g_flBorderWidth.y ); + float flNoiseMask = 1.0f - abs( ( flBorderMask * 2.0f ) - 1.0f ); + + // This is used to lerp in the 1D border texture over the flesh color + float flBorderMaskWithNoise = ( 1.0f - smoothstep( flNoiseMask - g_flBorderSoftness, flNoiseMask + g_flBorderSoftness, flNoise.r ) ) * flNoiseMask; + + // Border color + float vBorderUv = ( sign( flBorderMask - 0.5 ) * (1.0f - pow( flBorderMaskWithNoise, 4.0f )) * 0.5f ) + 0.5f; + float4 cBorderColor = 2.0f * tex2D( g_tBorder1DSampler, vBorderUv ); + cBorderColor.rgb *= g_cBorderTint; + cBorderColor.rgb *= flNoise; + + // Normal map + float4 vNormalMapValue = tex2D( g_tNormalSampler, i.vTexCoord0.xy ); + float3 vTangentNormal = ( vNormalMapValue.xyz * 2.0f ) - 1.0f; + vTangentNormal.xy += ( flNoise * 1.5f ) - 0.75f; // NOTE: This will denormalize the normal. + //float3 vWorldNormal = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz ); + + // Specular gloss layer + float3 vTangentReflectionVector = reflect( i.vTangentViewVector.xyz, vTangentNormal.xyz ); + //vTangentReflectionVector.xy += ( flNoise * 1.5f ) - 0.75f; + float3 vWorldReflectionVector = mul( i.mTangentSpaceTranspose, vTangentReflectionVector.xyz ); + float3 cGlossLayer = ENV_MAP_SCALE * texCUBE( g_tCubeSampler, vWorldReflectionVector.xyz ).rgb; + cGlossLayer.rgb *= g_flGlossBrightness; + + // Gloss mask is just hard-coded fresnel for now + float flGlossMask = pow( saturate( dot( vTangentNormal.xyz, -i.vTangentViewVector.xyz ) ), 8.0f ); + + // Opacity + float flOpacity = 1.0f; + flOpacity = max( flBorderMaskWithNoise, step( flBorderMask, 0.5f ) ); + + // Apply global opacity + flOpacity *= g_flGlobalOpacity; + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = cBaseColor.rgb * i.cVertexLight.rgb; + result.rgb += cGlossLayer.rgb * flGlossMask; + result.rgb *= pow( 1.0f - flBorderMaskWithNoise, 2.0f ); // Darken near border + result.rgb = lerp( result.rgb, cBorderColor.rgb, saturate( vBorderUv * 2.0f ) ); // bring in transition 1D texture + + //result.rgb = flClampedInputMask; + //result.rgb = flBorderMask; + //result.rgb = saturate( flClampedInputMask * 2.0f ); + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.x;// * i.flDistanceToEffectCenter_flFresnelEffect.y; + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.y * g_flBorderWidth.x - g_flBorderWidth.y; + //result.rgb = flNoiseMask; + //result.rgb = flBorderMaskWithNoise; + //result.rgb = flOpacity; + //result.rgb = flBorderUv; + //result.rgb = cBorderColor; + //result.rgb = -i.vTangentViewVector.z; + //result.rgb = vNormalMapValue.xyz; + //result.rgb = vTangentNormal.xyz; + //result.rgb = flGlossLayer; + //result.rgb = i.cVertexLight.rgb; + //result.rgb = texCUBE( g_tCubeSampler, vTangentNormal.xyz ).rgb; + //result.rgb = i.vTangentViewVector.x; + //result.rgb = cGlossLayer.rgb; + + // Set alpha for blending + result.a = flOpacity; + //result.a = 1.0f; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} diff --git a/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_vs30.fxc b/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_vs30.fxc new file mode 100644 index 00000000..557873d7 --- /dev/null +++ b/materialsystem/stdshaders/sdk_flesh_interior_blended_pass_vs30.fxc @@ -0,0 +1,148 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "HALFLAMBERT" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" + +// Includes +#include "common_vs_fxc.h" + +// Globals +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 g_vConst0 : register( SHADER_SPECIFIC_CONST_0 ); +#define g_flTime g_vConst0.x +#define g_flNoiseUvScroll g_vConst0.y +#define g_flBorderNoiseScale g_vConst0.z +#define g_flDebugForceFleshOn g_vConst0.w + +const float4 g_vEffectCenterOoRadius1 : register( SHADER_SPECIFIC_CONST_1 ); //= { -295.0f, -5.0f, 40.0f, 1.0f/20.0f }; +const float4 g_vEffectCenterOoRadius2 : register( SHADER_SPECIFIC_CONST_2 ); //= { -295.0f, 15.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius3 : register( SHADER_SPECIFIC_CONST_3 ); //= { -295.0f, 35.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius4 : register( SHADER_SPECIFIC_CONST_4 ); //= { -295.0f, 55.0f, 40.0f, 1.0f/10.0f }; + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + float3 vPosFlex : POSITION1; // Delta positions for flexing + float4 vTangent : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; + +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Flexes coming in from a separate stream (contribution masked by cFlexScale.x) + float4 vObjPosition = i.vPos; + vObjPosition.xyz += i.vPosFlex.xyz * cFlexScale.x; + + float3 vObjNormal; + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent ); + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal, vObjTangent, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // Pass through tex coords + o.vTexCoord0.xy = i.vTexCoord0.xy; + + // Store the closest effect intensity + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); + + /* + // Test values for development in Alyx_interior map + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + float3 vTestPosition = { -295.0f, -5.0f, 40.0f }; + float flMinY = -5.0f; + float flMaxY = 66.0f; + vTestPosition.y = lerp( flMinY, flMaxY, ( abs( frac( g_flTime / 20.0f ) * 2.0 - 1.0 ) ) ); + //vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + + //1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x * 4.0f - 3.0f ) + + //o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + + const float g_flInteriorRadius = 20.0f; + if ( g_flInteriorRadius ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius ); + } + + const float g_flInteriorRadius2 = 14.0f; + if ( g_flInteriorRadius2 ) + { + vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + //vTestPosition.z = lerp( 37, 45, ( abs( frac( g_flTime / 4.0f ) * 2.0 - 1.0 ) ) ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius2 ); + } + //*/ + + if ( g_flDebugForceFleshOn ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = 0.0f; + } + + // Fresnel mask + float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); + o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); + + // Noise UV + o.vNoiseTexCoord.xy = o.vTexCoord0.xy * g_flBorderNoiseScale + g_flNoiseUvScroll; + o.vNoiseTexCoord.zw = o.vTexCoord0.xy * g_flBorderNoiseScale - g_flNoiseUvScroll; // Will fetch as wz to avoid matching layers + + // Tangent view vector + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Compute vertex lighting + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + +#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) + o.cVertexLight.rgb = DoLighting( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); +#else + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); +#endif + + // Tangent space transform + o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x ); + o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y ); + o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z ); + + return o; +} diff --git a/materialsystem/stdshaders/sdk_lightmappedreflective_ps30.fxc b/materialsystem/stdshaders/sdk_lightmappedreflective_ps30.fxc new file mode 100644 index 00000000..4e3e2005 --- /dev/null +++ b/materialsystem/stdshaders/sdk_lightmappedreflective_ps30.fxc @@ -0,0 +1,182 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "REFLECT" "0..1" +// STATIC: "REFRACT" "0..1" +// STATIC: "ENVMAPMASK" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "common_ps_fxc.h" + +sampler RefractSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); +sampler ReflectSampler : register( s2 ); +#if BASETEXTURE +sampler LightmapSampler : register( s3 ); +#endif +#if ENVMAPMASK +sampler EnvMapMaskSampler : register( s6 ); +#endif +sampler NormalSampler : register( s4 ); + +const HALF4 vRefractTint : register( c1 ); +const float4 g_FresnelConstants : register( c3 ); +const HALF4 vReflectTint : register( c4 ); +const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale + +const float4 g_PixelFogParams : register( c8 ); +const float3 g_EyePos : register( c9 ); + + +static const bool g_bReflect = REFLECT ? true : false; +static const bool g_bRefract = REFRACT ? true : false; + +struct PS_INPUT +{ + float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0; + half3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float4 vWorldPos_vProjPosW : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if BASETEXTURE +// CENTROID: TEXCOORD6 + HALF4 lightmapTexCoord1And2 : TEXCOORD6; +// CENTROID: TEXCOORD7 + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ + // Load normal and expand range + HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoordXY_vTexCoordXY.xy ); + HALF3 vNormal = normalize( vNormalSample * 2.0 - 1.0 ); + + // Perform division by W only once + float ooW = 1.0f / i.vWorldPos_vProjPosW.w; + + float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; + + float4 reflectRefractScale = g_ReflectRefractScale; + + // Compute coordinates for sampling Reflection + float2 vReflectTexCoord; + float2 vRefractTexCoord; + + // vectorize the dependent UV calculations (reflect = .xy, refract = .wz) +#ifdef NV3X + float4 vDependentTexCoords = vNormal.xyxy * vNormalSample.a * reflectRefractScale; +#else + float4 vN; + vN.xy = vNormal.xy; + vN.w = vNormal.x; + vN.z = vNormal.y; + float4 vDependentTexCoords = vN * vNormalSample.a * reflectRefractScale; +#endif + + vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); + vReflectTexCoord = vDependentTexCoords.xy; + vRefractTexCoord = vDependentTexCoords.wz; + + // Sample reflection and refraction + HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); + HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); + vReflectColor *= vReflectTint; + vRefractColor *= vRefractTint; + + half3 vEyeVect; + vEyeVect = normalize( i.vTangentEyeVect ); + + // Fresnel term + HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); + HALF fFresnelScalar = g_FresnelConstants.x * pow( 1.0 - fNdotV, g_FresnelConstants.y ) + g_FresnelConstants.z; + HALF4 fFresnel = HALF4( fFresnelScalar, fFresnelScalar, fFresnelScalar, fFresnelScalar ); + +#if BASETEXTURE + float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ); + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + HALF3 lightmapColor1 = lightmapSample1.rgb; + HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + + float3 diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= LIGHT_MAP_SCALE / sum; + HALF3 diffuseComponent = baseSample.rgb * diffuseLighting; +#endif + + float4 flMask; +#if ENVMAPMASK + flMask = tex2D( EnvMapMaskSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ); +#else + flMask = float4( 1.0f, 1.0f, 1.0f, 1.0f ); +#endif + + // NOTE: the BASETEXTURE path hasn't been tested (or really written for that matter, just copied from water) + // What I think should happen is that the alpha of base texture should be its 'translucency' + // which should indicate how much refraction to use. + // We should add an envmapmask to deal with how much reflection to use + // along with all the focus, etc. features + float4 result; + float flAlpha = 1.0f; + if( g_bReflect && g_bRefract ) + { + result = lerp( vRefractColor, vReflectColor, fFresnel ) * flMask; +#if BASETEXTURE + result += float4( diffuseComponent, 1.0f ); + flAlpha = baseSample.a; +#endif + } + else if( g_bReflect ) + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ) + vReflectColor * flMask; + flAlpha = baseSample.a; +#else + result = vReflectColor; +#endif + } + else if( g_bRefract ) + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ) + vRefractColor * flMask; + flAlpha = baseSample.a; +#else + result = vRefractColor; +#endif + } + else + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ); + flAlpha = baseSample.a; +#else + result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); +#endif + } + + float fogFactor = 0.0f; + #if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) + { + fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_PixelFogParams, g_EyePos.xyz, i.vWorldPos_vProjPosW.xyz, i.vProjPos.z ); + } + #endif + + return FinalOutput( float4( result.rgb, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); +} diff --git a/materialsystem/stdshaders/sdk_lightmappedreflective_vs30.fxc b/materialsystem/stdshaders/sdk_lightmappedreflective_vs30.fxc new file mode 100644 index 00000000..4877d1a1 --- /dev/null +++ b/materialsystem/stdshaders/sdk_lightmappedreflective_vs30.fxc @@ -0,0 +1,105 @@ +// STATIC: "BASETEXTURE" "0..1" + +#include "common_vs_fxc.h" + +const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cBaseTextureTransform[2] : register( SHADER_SPECIFIC_CONST_3 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; + float vFog : FOG; + float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float4 vWorldPos_vProjPosW : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if BASETEXTURE + HALF4 lightmapTexCoord1And2 : TEXCOORD6; + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + // Projected position + float4 vProjPos = mul( v.vPos, cModelViewProj ); + o.vProjPos = o.vProjPos_POSITION = vProjPos; + + // Project tangent basis + float2 vProjTangentS = mul( v.vTangentS, cViewProj ); + float2 vProjTangentT = mul( v.vTangentT, cViewProj ); + + // Map projected position to the reflection texture + float2 vReflectPos; + vReflectPos.x = -vProjPos.x; + vReflectPos.y = -vProjPos.y; // invert Y + vReflectPos = (vReflectPos + vProjPos.w) * 0.5f; + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Reflection transform + o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x ); + + o.screenCoord = vProjPos.x; + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + + o.vWorldPos_vProjPosW.xyz = vWorldPos; + o.vWorldPos_vProjPosW.w = vProjPos.w; + + // Eye vector + float3 vWorldEyeVect = cEyePos - vWorldPos; + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, v.vTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, v.vTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, vObjNormal ); + + // Tranform bump coordinates + o.vBumpTexCoordXY_vTexCoordXY.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoordXY_vTexCoordXY.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + +#if BASETEXTURE + o.vBumpTexCoordXY_vTexCoordXY.z = dot( v.vBaseTexCoord, cBaseTextureTransform[0] ); + o.vBumpTexCoordXY_vTexCoordXY.w = dot( v.vBaseTexCoord, cBaseTextureTransform[1] ); + + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; +#else + o.vBumpTexCoordXY_vTexCoordXY.z = 0.0f; + o.vBumpTexCoordXY_vTexCoordXY.w = 0.0f; +#endif + + return o; +} + diff --git a/materialsystem/stdshaders/sdk_monitorscreen_ps30.fxc b/materialsystem/stdshaders/sdk_monitorscreen_ps30.fxc new file mode 100644 index 00000000..19d2d1d3 --- /dev/null +++ b/materialsystem/stdshaders/sdk_monitorscreen_ps30.fxc @@ -0,0 +1,49 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// +//paired with unlittwotexture_vs20 + +// STATIC: "TEXTURE2" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler SecondaryTextureSampler : register( s1 ); + + +const float4 g_Contrast : register( c1 ); +const float4 g_Saturation : register( c2 ); +const float4 g_Tint : register( c3 ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +#define g_Grey float4( 0.33333f, 0.33333f, 0.33333f, 0.33333f ) + +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 vColor : COLOR0; + + float4 worldPos_projPosZ : TEXCOORD7; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 resultColor = tex2D( BaseTextureSampler, i.vTexCoord0 ) * i.vColor; // base texture modulated with vertex color + +#if (TEXTURE2 == 1) + resultColor = tex2D( SecondaryTextureSampler, i.vTexCoord1 ) * resultColor; // modulate base color by another texture +#endif + + float3 tempColor = resultColor.rgb * resultColor.rgb; //base * base + resultColor.rgb = lerp( resultColor.rgb, tempColor.rgb, g_Contrast.rgb ); // blend between color and color * color + tempColor = dot( resultColor.rgb, g_Grey ); // color greyscaled + resultColor.rgb = lerp( tempColor.rgb, resultColor.rgb, g_Saturation.rgb ); // blend between color and greyscale + resultColor.rgb = resultColor.rgb * g_Tint.rgb; // tint + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshaders/sdk_refract_ps30.fxc b/materialsystem/stdshaders/sdk_refract_ps30.fxc new file mode 100644 index 00000000..d654346f --- /dev/null +++ b/materialsystem/stdshaders/sdk_refract_ps30.fxc @@ -0,0 +1,237 @@ +//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. ======= +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "BLUR" "0..1" +// STATIC: "FADEOUTONSILHOUETTE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "REFRACTTINTTEXTURE" "0..1" +// STATIC: "MASKED" "0..1" +// STATIC: "COLORMODULATE" "0..1" +// STATIC: "SECONDARY_NORMAL" "0..1" +// STATIC: "SHADER_SRGB_READ" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +// SKIP: $MASKED && $BLUR + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler2 : register( s1 ); +sampler RefractSampler : register( s2 ); +sampler NormalSampler : register( s3 ); +#if CUBEMAP +sampler EnvmapSampler : register( s4 ); +#endif +#if REFRACTTINTTEXTURE +sampler RefractTintSampler : register( s5 ); +#endif + +#define AlphaMapSampler2 NormalSampler +#define AlphaMapSampler NormalSampler2 + +const float3 g_EnvmapTint : register( c0 ); +const float3 g_RefractTint : register( c1 ); +const float3 g_EnvmapContrast : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_c5 : register( c5 ); +#define g_RefractScale g_c5.x +#define g_flTime g_c5.w + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +static const int g_BlurCount = BLUR; +static const float g_BlurFraction = 1.0f / 512.0f; +static const float g_HalfBlurFraction = 0.5 * g_BlurFraction; +static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction, + -g_BlurFraction,-g_HalfBlurFraction ); + +struct PS_INPUT +{ + float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz + float3 vTangentVertToEyeVector : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 ColorModulate : COLOR0; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + + float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + +#if FADEOUTONSILHOUETTE + //float blend = -i.projNormal.z; + float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) ); + blend = blend * blend * blend; +#else + float blend = 1.0f; +#endif + + // Decompress normal + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORM_DECODE_NONE, AlphaMapSampler ); + +#if SECONDARY_NORMAL + float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORM_DECODE_NONE, AlphaMapSampler2 ); + vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz ); +#endif + +#if REFRACTTINTTEXTURE + float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy ); +#else + float3 refractTintColor = g_RefractTint; +#endif + +#if COLORMODULATE + refractTintColor *= i.ColorModulate.rgb; +#endif + + // Perform division by W only once + float ooW = 1.0f / i.vRefractXYW.z; + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; + float2 vRefractTexCoord = vNormal.xy; + float scale = vNormal.a * g_RefractScale; +#if COLORMODULATE + scale *= i.ColorModulate.a; +#endif + vRefractTexCoord *= scale; + vRefractTexCoord += vRefractTexCoordNoWarp; + +#if (BLUR==1) // use polyphase magic to convert 9 lookups into 4 + + // basic principle behind this transformation: + // [ A B C ] + // [ D E F ] + // [ G H I ] + // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]). + // scale the upper 2x2 by 4/9 (total area of kernel occupied) + // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F]) + // scale right 1x2 by 2/9 + // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H]) + // scale bottom 2x1 by 2/9 + // fetch last sample (I) and scale by 1/9. + + float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction); + float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction); + float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction); + float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction); + result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444; + result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222; + result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222; + result += tex2D(RefractSampler, singleton_loc) * 0.1111111; + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp(unblurredColor, result * refractTintColor, blend); + +#elif (BLUR>0) // iteratively step through render target + int x, y; + + result = float3( 0.0f, 0.0f, 0.0f ); + for( x = -g_BlurCount; x <= g_BlurCount; x++ ) + { + for( y = -g_BlurCount; y <= g_BlurCount; y++ ) + { + result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) ); + } + } + + int width = g_BlurCount * 2 + 1; + result *= 1.0f / ( width * width ); + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + // result is the blurred one now. . .now lerp. + float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp( unblurredColor, result * refractTintColor, blend ); +#else +# if MASKED + float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + fMaskedResult = GammaToLinear( fMaskedResult ); + } + #endif + + return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +# else + float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorWarp = GammaToLinear( colorWarp ); + } + #endif + float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorNoWarp = GammaToLinear( colorNoWarp ); + } + #endif + + colorWarp *= refractTintColor; + result = lerp( colorNoWarp, colorWarp, blend ); +# endif +#endif + +#if CUBEMAP + float specularFactor = vNormal.a; + + float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal ); + + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector ); + float3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + result += specularLighting; +#endif + +#if COLORMODULATE + float resultAlpha = i.ColorModulate.a * vNormal.a; +#else + float resultAlpha = vNormal.a; +#endif + + return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshaders/sdk_refract_vs30.fxc b/materialsystem/stdshaders/sdk_refract_vs30.fxc new file mode 100644 index 00000000..8271f19d --- /dev/null +++ b/materialsystem/stdshaders/sdk_refract_vs30.fxc @@ -0,0 +1,134 @@ +//====== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "MODEL" "0..1" +// STATIC: "COLORMODULATE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bModel = MODEL ? true : false; + +const float4 cBumpTexCoordTransform[4] : register( SHADER_SPECIFIC_CONST_1 ); + +const float g_flTime : register( SHADER_SPECIFIC_CONST_5 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; +#if !MODEL + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +#else + float4 vUserData : TANGENT; +#endif +#if COLORMODULATE + float4 vColor : COLOR0; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; + float4 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 vColor : COLOR0; +#endif + float4 fogFactorW : COLOR1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + +#if COLORMODULATE + o.vColor = v.vColor; +#endif + + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + + float3 vObjNormal; +#if MODEL + float4 vObjTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent ); + + SkinPositionNormalAndTangentSpace( + g_bSkinning, + v.vPos, vObjNormal, vObjTangent, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal, worldTangentS, worldTangentT ); +#else + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + worldPos = mul( v.vPos, cModel[0] ); + worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); +#endif + + // World normal + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + + // Projected position + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos_POSITION = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + //o.projNormal.xyz = mul( worldNormal, cViewProj ); + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Refraction transform + o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); + + // Eye vector + float3 vWorldEyeVect = normalize( cEyePos - vWorldPos ); + o.vWorldViewVector.xyz = -vWorldEyeVect.xyz; + + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + + // Tranform bump coordinates (note wz, not zw) + o.vBumpTexCoord.w = dot( v.vBaseTexCoord, cBumpTexCoordTransform[2] ); + o.vBumpTexCoord.z = dot( v.vBaseTexCoord, cBumpTexCoordTransform[3] ); + + + // Tangent space transform + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + o.vWorldTangent.xyz = worldTangentS.xyz; + o.vWorldBinormal.xyz = worldTangentT.xyz; + + return o; +} diff --git a/materialsystem/stdshaders/sdk_screenspaceeffect_vs30.fxc b/materialsystem/stdshaders/sdk_screenspaceeffect_vs30.fxc new file mode 100644 index 00000000..2946858f --- /dev/null +++ b/materialsystem/stdshaders/sdk_screenspaceeffect_vs30.fxc @@ -0,0 +1,32 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; + float2 ZeroTexCoord : TEXCOORD1; + float2 bloomTexCoord : TEXCOORD2; +}; + +float4 Texel_Sizes : register (SHADER_SPECIFIC_CONST_0); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = float4( v.vPos, 1.0f ); + o.baseTexCoord = v.vBaseTexCoord; + o.ZeroTexCoord=float2(0,0); + o.bloomTexCoord.x=v.vBaseTexCoord.x+Texel_Sizes.z; + o.bloomTexCoord.y=v.vBaseTexCoord.y+Texel_Sizes.w; + + return o; +} diff --git a/materialsystem/stdshaders/shadowmodel_ps20.fxc b/materialsystem/stdshaders/sdk_shadowmodel_ps30.fxc similarity index 100% rename from materialsystem/stdshaders/shadowmodel_ps20.fxc rename to materialsystem/stdshaders/sdk_shadowmodel_ps30.fxc diff --git a/materialsystem/stdshaders/sdk_shadowmodel_vs30.fxc b/materialsystem/stdshaders/sdk_shadowmodel_vs30.fxc new file mode 100644 index 00000000..0b5a3a79 --- /dev/null +++ b/materialsystem/stdshaders/sdk_shadowmodel_vs30.fxc @@ -0,0 +1,75 @@ +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cShadowTextureMatrix[3] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cTexOrigin : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cTexScale : register( SHADER_SPECIFIC_CONST_4 ); + +// { Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 } +const float3 cShadowConstants : register( SHADER_SPECIFIC_CONST_5 ); +#define flShadowFalloffOffset cShadowConstants.x +#define flOneOverShadowDist cShadowConstants.y +#define flShadowScale cShadowConstants.z + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float3 vNormal : NORMAL; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float3 T0 : TEXCOORD0; // PS wants this to be 4D but VS doesn't? (see original asm sources) + float3 T1 : TEXCOORD1; + float3 T2 : TEXCOORD2; + float T3 : TEXCOORD3; + float4 vColor : COLOR0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + + // Transform position into texture space (from 0 to 1) + float3 vTexturePos; + vTexturePos.x = dot( worldPos.xyz, cShadowTextureMatrix[0].xyz ); + vTexturePos.y = dot( worldPos.xyz, cShadowTextureMatrix[1].xyz ); + vTexturePos.z = dot( worldPos.xyz, cShadowTextureMatrix[2].xyz ); + + // Figure out the shadow fade amount + float flShadowFade = ( vTexturePos.z - flShadowFalloffOffset ) * flOneOverShadowDist; + + // Offset it into the texture + o.T0 = vTexturePos * cTexScale + cTexOrigin; + + // We're doing clipping by using texkill + o.T1.xyz = vTexturePos.xyz; // Also clips when shadow z < 0 ! + o.T2.xyz = float3( 1.0f, 1.0f, 1.0f ) - vTexturePos.xyz; + o.T2.z = 1.0f - flShadowFade; // Clips when shadow z > shadow distance + + // We're doing backface culling by using texkill also (wow yucky) + // -------------------------------------------------------------- + // Transform z component of normal in texture space + // If it's negative, then don't draw the pixel + o.T3 = dot( worldNormal, -cShadowTextureMatrix[2] ); + + // Shadow color, falloff + o.vColor.xyz = cModulationColor.xyz; + o.vColor.w = flShadowFade * flShadowScale; + + return o; +} diff --git a/materialsystem/stdshaders/sdk_shatteredglass_ps30.fxc b/materialsystem/stdshaders/sdk_shatteredglass_ps30.fxc new file mode 100644 index 00000000..e0a53770 --- /dev/null +++ b/materialsystem/stdshaders/sdk_shatteredglass_ps30.fxc @@ -0,0 +1,156 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// STATIC: "CUBEMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "PARALLAXCORRECT" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +// SKIP: $PARALLAXCORRECT && !$CUBEMAP + +#include "common_ps_fxc.h" + +// HDRFIXME: Need to make this work. + +#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp + +#include "common_ps_fxc.h" +#include "common_lightmappedgeneric_fxc.h" + +const HALF4 g_EnvmapTint : register( c0 ); +const HALF3 g_DiffuseModulation : register( c1 ); +const HALF3 g_EnvmapContrast : register( c2 ); +const HALF3 g_EnvmapSaturation : register( c3 ); +const HALF4 g_FresnelReflection : register( c4 ); +const HALF3 g_EyePos : register( c5 ); +const HALF3 g_OverbrightFactor : register( c6 ); + +const HALF4 g_FogParams : register( c12 ); + +// Parallax cubemaps +#if (PARALLAXCORRECT) +const float3 cubemapPos : register(c7); +const float4x4 obbMatrix : register(c8); //through c11 +#endif + +// CENTROID: TEXCOORD2 + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler EnvmapSampler : register( s2 ); +sampler DetailSampler : register( s3 ); +sampler EnvmapMaskSampler : register( s5 ); + +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; + HALF2 detailTexCoord : TEXCOORD1; + HALF2 lightmapTexCoord : TEXCOORD2; + HALF2 envmapMaskTexCoord : TEXCOORD3; + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3 worldSpaceNormal : TEXCOORD5; + HALF4 vertexColor : COLOR; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bCubemap = CUBEMAP ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + + HALF4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + HALF4 detailColor = tex2D( DetailSampler, i.detailTexCoord ); + + HALF2 lightmapCoordinates = i.lightmapTexCoord; + HALF3 lightmapColor = LightMapSample( LightmapSampler, lightmapCoordinates ); + + HALF3 specularFactor = 1.0f; + if( bEnvmapMask ) + { + specularFactor = tex2D( EnvmapMaskSampler, i.detailTexCoord ).xyz; + } + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + HALF3 diffuseLighting = lightmapColor; + diffuseLighting *= g_DiffuseModulation; + diffuseLighting *= LIGHT_MAP_SCALE; + + HALF3 albedo = baseColor; + HALF alpha = 1.0f; + + if( !bBaseAlphaEnvmapMask ) + { + alpha *= baseColor.a; + } + + albedo *= detailColor; + alpha *= detailColor.a; + + // FIXME: seperate vertexcolor and vertexalpha? + // vertex alpha is ignored if vertexcolor isn't set. . need to check other version. + if( bVertexColor ) + { + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + if( bCubemap ) + { + float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; + worldVertToEyeVector = NormalizeWithCubemap( NormalizeSampler, worldVertToEyeVector ); + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, worldVertToEyeVector ); + + // Calc Fresnel factor + HALF3 worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceNormal ); + HALF fresnel = 1.0 - dot( worldSpaceNormal, worldVertToEyeVector ); + fresnel = pow( fresnel, 5.0 ); + fresnel = fresnel * g_FresnelReflection.b + g_FresnelReflection.a; + + //Parallax correction (2_0b and beyond) + //Adapted from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +#if (PARALLAXCORRECT) + float3 worldPos = i.worldPos_projPosZ.xyz; + float3 positionLS = mul(float4(worldPos, 1), obbMatrix); + float3 rayLS = mul(reflectVect, (float3x3) obbMatrix); + + float3 firstPlaneIntersect = (float3(1.0f, 1.0f, 1.0f) - positionLS) / rayLS; + float3 secondPlaneIntersect = (-positionLS) / rayLS; + float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect); + float distance = min(furthestPlane.x, min(furthestPlane.y, furthestPlane.z)); + + // Use distance in WS directly to recover intersection + float3 intersectPositionWS = worldPos + reflectVect * distance; + reflectVect = intersectPositionWS - cubemapPos; +#endif + + specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + + specularLighting *= g_EnvmapTint; +#if HDRTYPE == HDR_TYPE_NONE + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + specularLighting *= fresnel; + } + + // Do it somewhat unlit + HALF3 result = albedo*(g_OverbrightFactor.z*diffuseLighting + g_OverbrightFactor.y) + specularLighting; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( HALF4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/materialsystem/stdshaders/sdk_shatteredglass_vs30.fxc b/materialsystem/stdshaders/sdk_shatteredglass_vs30.fxc new file mode 100644 index 00000000..baddbd2d --- /dev/null +++ b/materialsystem/stdshaders/sdk_shatteredglass_vs30.fxc @@ -0,0 +1,58 @@ +// STATIC: "ENVMAP_MASK" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); + +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vDetailTexCoord : TEXCOORD2; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; + float2 detailTexCoord : TEXCOORD1; + float2 lightmapTexCoord : TEXCOORD2; + float2 envmapMaskTexCoord : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD4; + float3 worldNormal : TEXCOORD5; + float4 vertexColor : COLOR; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + + o.worldPos_projPosZ.w = projPos.z; + o.worldPos_projPosZ.xyz = mul( float4( v.vPos, 1 ), cModel[0] ); + o.worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; + o.detailTexCoord.x = dot( v.vDetailTexCoord, cDetailTexCoordTransform[0] ) + cDetailTexCoordTransform[0].w; + o.detailTexCoord.y = dot( v.vDetailTexCoord, cDetailTexCoordTransform[1] ) + cDetailTexCoordTransform[1].w; + o.envmapMaskTexCoord.x = dot( v.vDetailTexCoord, cDetailTexCoordTransform[0] ) + cDetailTexCoordTransform[0].w; + o.envmapMaskTexCoord.y = dot( v.vDetailTexCoord, cDetailTexCoordTransform[1] ) + cDetailTexCoordTransform[1].w; + o.lightmapTexCoord = v.vLightmapTexCoord; + + o.vertexColor = cModulationColor; + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_skin_ps30.fxc b/materialsystem/stdshaders/sdk_skin_ps30.fxc new file mode 100644 index 00000000..17fc4c3d --- /dev/null +++ b/materialsystem/stdshaders/sdk_skin_ps30.fxc @@ -0,0 +1,412 @@ +//======= Copyright � 1996-2007, Valve Corporation, All rights reserved. ====== +// STATIC: "CUBEMAP" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "PHONGWARPTEXTURE" "0..1" +// STATIC: "WRINKLEMAP" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "RIMLIGHT" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// STATIC: "FASTPATH_NOBUMP" "0..1" +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "PHONG_HALFLAMBERT" "0..1" +// STATIC: "ENVMAPMASK" "0..1" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" + + +// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) + +// BlendTintByBaseAlpha and self illum and are opposing meanings for alpha channel +// SKIP: ( $BLENDTINTBYBASEALPHA ) && ( $SELFILLUM ) + +// SKIP: $ENVMAPMASK && !$CUBEMAP + +// fastpath means: +// no bumpmap +// basealphaenvmapmask (not inverted) +// no spec expmap +// no spectint +// no specwarp +// no rimlight +// no selfillum +// no detail +// no BlendTintByBaseAlpha + +// SKIP: $FASTPATH_NOBUMP && ( $RIMLIGHT || $DETAILTEXTURE || $PHONGWARPTEXTURE || $SELFILLUM || $BLENDTINTBYBASEALPHA ) + + + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +const float4 g_SelfIllumTint_and_DetailBlendFactor : register( PSREG_SELFILLUMTINT ); +#if ( SELFILLUMFRESNEL == 1 ) +const float4 g_SelfIllumScaleBiasExpBrightness : register( PSREG_SELFILLUM_SCALE_BIAS_EXP ); +#endif +const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); +const float4 g_EnvmapTint_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); // w controls spec mask +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_EnvMapFresnel : register( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK ); // x is envmap fresnel ... w is selfillummask control +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_FlashlightAttenuationFactors_RimMask : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass, x has rim mask control +const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); // xyz are fresnel, w is specular boost +const float4 g_SpecularRimParams : register( PSREG_SPEC_RIM_PARAMS ); // xyz are specular tint color, w is rim power +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) +const float4 g_ShaderControls : register( PSREG_CONSTANT_27 ); // x is basemap alpgha phong mask, y is 1 - blendtintbybasealpha, z is tint overlay amount, w controls "INVERTPHONGMASK" +const float4 g_DetailBlendMode_NumLights : register( c32 ); + +#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz +#define g_fRimBoost g_FlashlightPos_RimBoost.w +#define g_FresnelRanges g_FresnelSpecParams.xyz +#define g_SpecularBoost g_FresnelSpecParams.w +#define g_SpecularTint g_SpecularRimParams.xyz +#define g_RimExponent g_SpecularRimParams.w +#define g_FlashlightAttenuationFactors g_FlashlightAttenuationFactors_RimMask +#define g_RimMaskControl g_FlashlightAttenuationFactors_RimMask.x +#define g_SelfIllumMaskControl g_EnvMapFresnel.w +#define g_fBaseMapAlphaPhongMask g_ShaderControls.x +#define g_fMinLighting g_ShaderControls.y +#define g_fTintReplacementControl g_ShaderControls.z +#define g_fInvertPhongMask g_ShaderControls.w +#define g_DetailBlendMode g_DetailBlendMode_NumLights.x +#define g_NumLights g_DetailBlendMode_NumLights.y + +sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha +sampler SpecularWarpSampler : register( s1 ); // Specular warp sampler (for iridescence etc) +sampler DiffuseWarpSampler : register( s2 ); // Lighting warp sampler (1D texture for diffuse lighting modification) +sampler NormalMapSampler : register( s3 ); // Normal map, specular mask in alpha +sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler +sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers +sampler FlashlightSampler : register( s6 ); // Flashlight cookie +sampler SpecExponentSampler : register( s7 ); // Specular exponent map +sampler EnvmapSampler : register( s8 ); // Cubic environment map + +#if WRINKLEMAP +sampler WrinkleSampler : register( s9 ); // Compression base +sampler StretchSampler : register( s10 ); // Expansion base +sampler NormalWrinkleSampler : register( s11 ); // Compression base +sampler NormalStretchSampler : register( s12 ); // Expansion base +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s13 ); // detail texture +#endif + +sampler SelfIllumMaskSampler : register( s14 ); // selfillummask + +#if ENVMAPMASK +sampler EnvmapMaskSampler : register( s15 ); +#endif + + +struct PS_INPUT +{ + float4 baseTexCoordDetailTexCoord : TEXCOORD0; // xy=base zw=detail + float3 lightAtten : TEXCOORD1; // Scalar light attenuation factors for FOUR lights + float3 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bWrinkleMap = WRINKLEMAP ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false; + bool bDoAmbientOcclusion = false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDoRimLighting = RIMLIGHT ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + int nNumLights = g_NumLights; + + // Unpacking for convenience + float fWrinkleWeight = i.projPos_fWrinkleWeight.w; + float3 vProjPos = i.projPos_fWrinkleWeight.xyz; + float3 vWorldPos = i.worldPos_atten3.xyz; + float atten3 = i.worldPos_atten3.w; + + float4 vLightAtten = float4( i.lightAtten, atten3 ); + +#if WRINKLEMAP + float flWrinkleAmount = saturate( -fWrinkleWeight ); // One of these two is zero + float flStretchAmount = saturate( fWrinkleWeight ); // while the other is in the 0..1 range + + float flTextureAmount = 1.0f - flWrinkleAmount - flStretchAmount; // These should sum to one +#endif + + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoordDetailTexCoord.xy ); +#if WRINKLEMAP + float4 wrinkleColor = tex2D( WrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchColor = tex2D( StretchSampler, i.baseTexCoordDetailTexCoord.xy ); + + // Apply wrinkle blend to only RGB. Alpha comes from the base texture + baseColor.rgb = flTextureAmount * baseColor.rgb + flWrinkleAmount * wrinkleColor.rgb + flStretchAmount * stretchColor.rgb; +#endif + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.baseTexCoordDetailTexCoord.zw ); + baseColor = TextureCombine( baseColor, detailColor, g_DetailBlendMode, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, vWorldPos.xyz, vProjPos.z ); + + float3 vEyeDir = normalize(i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz); + float3 vRimAmbientCubeColor = PixelShaderAmbientLight(vEyeDir, cAmbientCube); + + float3 worldSpaceNormal, tangentSpaceNormal; + +#if ENVMAPMASK + float3 fSpecMask = float3( 1.0f, 1.0f, 1.0f ); +#else + float fSpecMask = 1.0f; +#endif + +#if !DETAILTEXTURE + // Blixibon - $bumpmap transform support + float4 normalTexel = tex2D( NormalMapSampler, i.baseTexCoordDetailTexCoord.zw ); +#else + float4 normalTexel = tex2D( NormalMapSampler, i.baseTexCoordDetailTexCoord.xy ); +#endif + +#if WRINKLEMAP + float4 wrinkleNormal = tex2D( NormalWrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchNormal = tex2D( NormalStretchSampler, i.baseTexCoordDetailTexCoord.xy ); + normalTexel = flTextureAmount * normalTexel + flWrinkleAmount * wrinkleNormal + flStretchAmount * stretchNormal; +#endif + +#if (FASTPATH_NOBUMP == 0) + tangentSpaceNormal = lerp( 2.0f * normalTexel.xyz - 1.0f, float3(0, 0, 1), g_fBaseMapAlphaPhongMask ); +#else + tangentSpaceNormal = float3(0, 0, 1); +#endif + + #if ENVMAPMASK + { + float4 envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoordDetailTexCoord.xy ); + fSpecMask = lerp( envmapMaskTexel.xyz, baseColor.aaa, g_fBaseMapAlphaPhongMask ); + } + #else + { +#if (FASTPATH_NOBUMP == 0 ) + fSpecMask = lerp( normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask ); +#else + fSpecMask = baseColor.a; +#endif + } + #endif + + // We need a normal if we're doing any lighting + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + float fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges ); + float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir ); + + // Break down reflect so that we can share dot(worldSpaceNormal,vEyeDir) with fresnel terms + float3 vReflect = 2 * worldSpaceNormal * dot(worldSpaceNormal, vEyeDir) - vEyeDir; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + float3 envMapColor = float3( 0.0f, 0.0f, 0.0f ); + if( !bFlashlight ) + { + // Summation of diffuse illumination from all local lights + diffuseLighting = PixelShaderDoLighting( vWorldPos, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, true, vLightAtten, + cAmbientCube, NormalizeRandRotSampler, nNumLights, cLightInfo, PHONG_HALFLAMBERT, + + // These parameters aren't passed by generic shaders: + false, 1.0f, + bDoDiffuseWarp, DiffuseWarpSampler ); + + if( bCubemap ) + { + if ( bEnvmapMask ) + { + float3 fEnvMapMask = lerp( baseColor.aaa, fSpecMask, g_EnvmapTint_ShadowTweaks.w ); + envMapColor = (ENV_MAP_SCALE * + lerp(1, fFresnelRanges, g_EnvMapFresnel.x) * + lerp(fEnvMapMask, float3(1,1,1)-fEnvMapMask, g_fInvertPhongMask)) * + texCUBE( EnvmapSampler, vReflect ).xyz * + g_EnvmapTint_ShadowTweaks.xyz; + } + else + { + // Mask is either normal map alpha or base map alpha +#if ( SELFILLUMFRESNEL == 1 ) // This is to match the 2.0 version of vertexlitgeneric + float fEnvMapMask = lerp( baseColor.a, g_fInvertPhongMask, g_EnvmapTint_ShadowTweaks.w ); +#else + float fEnvMapMask = lerp( baseColor.a, fSpecMask, g_EnvmapTint_ShadowTweaks.w ); +#endif + + envMapColor = (ENV_MAP_SCALE * + lerp(1, fFresnelRanges, g_EnvMapFresnel.x) * + lerp(fEnvMapMask, 1-fEnvMapMask, g_fInvertPhongMask)) * + texCUBE( EnvmapSampler, vReflect ).xyz * + g_EnvmapTint_ShadowTweaks.xyz; + } + } + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 rimLighting = float3( 0.0f, 0.0f, 0.0f ); + + float3 vSpecularTint = 1; + float fRimMask = 0; + float fSpecExp = 1; + +#if ( FASTPATH_NOBUMP == 0 ) + float4 vSpecExpMap = tex2D( SpecExponentSampler, i.baseTexCoordDetailTexCoord.xy ); + + if ( !bFlashlight ) + { + fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); // Select rim mask + } + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent +#if defined( _X360 ) + [flatten] +#endif + + fSpecExp = (g_EyePos_SpecExponent.w >= 0.0) ? g_EyePos_SpecExponent.w : (1.0f + 149.0f * vSpecExpMap.r); + + // If constant tint is negative, tint with albedo, based upon scalar tint map +#if defined( _X360 ) + [flatten] +#endif + vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g ); + vSpecularTint = (g_SpecularTint.r >= 0.0) ? g_SpecularTint.rgb : vSpecularTint; + +#else + fSpecExp = max(g_EyePos_SpecExponent.w, 0); +#endif + + float3 albedo = baseColor.rgb; + + if ( !bFlashlight ) + { + // Summation of specular from all local lights besides the flashlight + PixelShaderDoSpecularLighting( vWorldPos, worldSpaceNormal, + fSpecExp, vEyeDir, vLightAtten, + nNumLights, cLightInfo, false, 1.0f, bDoSpecularWarp, + SpecularWarpSampler, fFresnelRanges, bDoRimLighting, g_RimExponent, + + // Outputs + specularLighting, rimLighting ); + } + else + { + float4 flashlightSpacePosition = mul( float4( vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); + + DoSpecularFlashlight( g_FlashlightPos, vWorldPos, flashlightSpacePosition, worldSpaceNormal, + g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, + FlashlightSampler, ShadowDepthSampler, NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, vProjPos.xy / vProjPos.z, + fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpSampler, fFresnelRanges, g_EnvmapTint_ShadowTweaks, + + // These two values are output + diffuseLighting, specularLighting ); + } + + // If we didn't already apply Fresnel to specular warp, modulate the specular + if ( !bDoSpecularWarp ) + fSpecMask *= fFresnelRanges; + + // Modulate with spec mask, boost and tint + specularLighting *= fSpecMask * g_SpecularBoost; + + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_fTintReplacementControl); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + +#if FOGTYPE == 2 || FLASHLIGHT != 0 + float3 diffuseComponent = albedo * diffuseLighting; +#else + float flFresnelMinlight = saturate( dot( worldSpaceNormal, vEyeDir ) ); + float3 diffuseComponent = albedo * lerp( diffuseLighting, 1, g_fMinLighting * flFresnelMinlight ); +#endif + + if ( bSelfIllum && !bFlashlight ) + { +#if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a Fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + float3 vVertexNormal = normalize( float3( i.tangentSpaceTranspose[0].z, i.tangentSpaceTranspose[1].z, i.tangentSpaceTranspose[2].z ) ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, vEyeDir.xyz ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo * g_SelfIllumScaleBiasExpBrightness.w, baseColor.a * saturate( flSelfIllumFresnel ) ); +#else + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy ).xyz; + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo, vSelfIllumMask ); +#endif + + diffuseComponent = max( 0.0f, diffuseComponent ); + } + +#if DETAILTEXTURE + diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, + g_DetailBlendMode, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + if ( bDoRimLighting && !bFlashlight ) + { + float fRimMultiply = fRimMask * fRimFresnel; // both unit range: [0, 1] + + // Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges) + rimLighting *= fRimMultiply; + + // Fold rim lighting into specular term by using the max so that we don't really add light twice... + specularLighting = max( specularLighting, rimLighting ); + + // Add in view-ray lookup from ambient cube + specularLighting += (vRimAmbientCubeColor * g_fRimBoost) * saturate(fRimMultiply * worldSpaceNormal.z); + } + + float3 result = specularLighting*vSpecularTint + envMapColor + diffuseComponent; + +#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + float alpha = fogFactor; +#else + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha = lerp( baseColor.a * alpha, alpha, g_fBaseMapAlphaPhongMask ); + } +#endif + + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, vProjPos.z ); +} diff --git a/materialsystem/stdshaders/sdk_skin_vs30.fxc b/materialsystem/stdshaders/sdk_skin_vs30.fxc new file mode 100644 index 00000000..ae5f0c97 --- /dev/null +++ b/materialsystem/stdshaders/sdk_skin_vs30.fxc @@ -0,0 +1,138 @@ +//======= Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "DECAL" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" + +#include "common_vs_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#if ( MORPHING ) +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float4 vPosFlex : POSITION1; + float4 vNormalFlex : NORMAL1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; + // Stuff that is seen by the pixel shader + float4 baseTexCoord : TEXCOORD0; // includes detail tex coord + float3 lightAtten : TEXCOORD1; + float3 worldVertToEyeVector : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, v.vTexCoord2, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if ( USE_MORPHING && DECAL ) + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.projPos_fWrinkleWeight.xyz = vProjPos.xyz; + + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_atten3.xyz = worldPos; + + // Needed for specular + o.worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + + // Compute bumped lighting + // FIXME: We shouldn't have to compute this for unlit materials + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, true ); + + // Base texture coordinate transform + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + o.baseTexCoord.z = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.baseTexCoord.w = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} diff --git a/materialsystem/stdshaders/sdk_sky_hdr_compressed_ps30.fxc b/materialsystem/stdshaders/sdk_sky_hdr_compressed_ps30.fxc new file mode 100644 index 00000000..6668a119 --- /dev/null +++ b/materialsystem/stdshaders/sdk_sky_hdr_compressed_ps30.fxc @@ -0,0 +1,27 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler ExposureTextureSampler0 : register( s0 ); +sampler ExposureTextureSampler1 : register( s1 ); +sampler ExposureTextureSampler2 : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF3 color0 = 0.25*tex2D( ExposureTextureSampler0, i.baseTexCoord ); + HALF3 color1 = 2.0*tex2D( ExposureTextureSampler1, i.baseTexCoord ); + HALF3 color2 = 16.0*tex2D( ExposureTextureSampler2, i.baseTexCoord ); + + // This is never fogged. +// return FinalOutput( float4( max(max(color0,color1),color2), 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate + return FinalOutput( float4(1,0,0,1 ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshaders/sdk_sky_hdr_compressed_rgbs_ps30.fxc b/materialsystem/stdshaders/sdk_sky_hdr_compressed_rgbs_ps30.fxc new file mode 100644 index 00000000..24007a7a --- /dev/null +++ b/materialsystem/stdshaders/sdk_sky_hdr_compressed_rgbs_ps30.fxc @@ -0,0 +1,48 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler RGBSTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +float2 texWidthHeight : register( c1 ); + +float4 texOffsets : register( c2 ); + +struct PS_INPUT +{ + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + float4 s00 = tex2D(RGBSTextureSampler, i.baseTexCoord00); + float4 s10 = tex2D(RGBSTextureSampler, i.baseTexCoord10); + float4 s01 = tex2D(RGBSTextureSampler, i.baseTexCoord01); + float4 s11 = tex2D(RGBSTextureSampler, i.baseTexCoord11); + + float2 fracCoord = frac(i.baseTexCoord_In_Pixels); + + s00.rgb*=s00.a; + s10.rgb*=s10.a; + + s00.xyz = lerp(s00, s10, fracCoord.x); + + s01.rgb*=s01.a; + s11.rgb*=s11.a; + s01.xyz = lerp(s01, s11, fracCoord.x); + + result = lerp(s00, s01, fracCoord.y); + + // This is never fogged. + return FinalOutput( float4( InputScale*result, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshaders/sdk_sky_ps30.fxc b/materialsystem/stdshaders/sdk_sky_ps30.fxc new file mode 100644 index 00000000..a1618d42 --- /dev/null +++ b/materialsystem/stdshaders/sdk_sky_ps30.fxc @@ -0,0 +1,25 @@ +// HDRFIXME: Make this work with nonHDR +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler BaseTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF4 color = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + color.rgb *= InputScale.rgb; + + // This is never fogged. + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/materialsystem/stdshaders/sky_vs20.fxc b/materialsystem/stdshaders/sdk_sky_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/sky_vs20.fxc rename to materialsystem/stdshaders/sdk_sky_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_splinerope_ps30.fxc b/materialsystem/stdshaders/sdk_splinerope_ps30.fxc new file mode 100644 index 00000000..af5deb23 --- /dev/null +++ b/materialsystem/stdshaders/sdk_splinerope_ps30.fxc @@ -0,0 +1,48 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// STATIC: "SHADOWDEPTH" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" + +float4 g_FogParams : register( c0 ); +float3 g_EyePos : register( c1 ); + +// VS_OUTPUT in a common file. +#define PIXELSHADER +#include "common_splinerope_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler NormalSampler : register( s1 ); + +float4 main( PS_INPUT i ) : COLOR +{ + #if ( SHADOWDEPTH == 0 ) + { + float3 vNormalMapDir = tex2D( NormalSampler, i.texCoord.xy ); // Get the 3-vector from the normal map + float4 textureColor = tex2D( BaseTextureSampler, i.texCoord.xy ); + + //Expand compacted vectors + vNormalMapDir = ( vNormalMapDir - 0.5 ) * 2.0; + float3 vLightDir = float3( 0.0f, 0.0f, 1.0f ); + + float lightDirDotNormalMap = dot( vNormalMapDir, vLightDir ); //normalMap dot dirLightDir + + // do half-lambert on the dot + lightDirDotNormalMap = lightDirDotNormalMap * 0.5 + 0.5; + lightDirDotNormalMap = lightDirDotNormalMap * lightDirDotNormalMap; + + float4 resultColor; + resultColor.xyz = lightDirDotNormalMap * ( textureColor.rgb * i.argbcolor.rgb ); + resultColor.a = textureColor.a * i.argbcolor.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); + } + #else + { + return float4( 0.0f, 0.0f, 0.0f, 1.0f ); + } + #endif +} diff --git a/materialsystem/stdshaders/sdk_splinerope_vs30.fxc b/materialsystem/stdshaders/sdk_splinerope_vs30.fxc new file mode 100644 index 00000000..3d0a236f --- /dev/null +++ b/materialsystem/stdshaders/sdk_splinerope_vs30.fxc @@ -0,0 +1,71 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +#include "common_vs_fxc.h" +#include "spline_fxc.h" + +const float4x3 cModelView : register(SHADER_SPECIFIC_CONST_0); +const float4x4 cProj : register(SHADER_SPECIFIC_CONST_3); +const float g_MinPixelSize : register(SHADER_SPECIFIC_CONST_7); + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vTint : COLOR; + float4 vParms : POSITION; // T V side_id + float4 vSplinePt0 : TEXCOORD0; // x y z rad + float4 vSplinePt1 : TEXCOORD1; // x y z rad + float4 vSplinePt2 : TEXCOORD2; // x y z rad + float4 vSplinePt3 : TEXCOORD3; // x y z rad +}; + +// VS_OUTPUT in a common file. +#include "common_splinerope_fxc.h" + +#define P0 (v.vSplinePt0) +#define P1 (v.vSplinePt1) +#define P2 (v.vSplinePt2) +#define P3 (v.vSplinePt3) + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + // posrad.xyz is worldspace position and posrad.w is worldspace diameter. + float4 posrad = CatmullRomSpline( P0, P1, P2, P3, v.vParms.x ); + + // calculate projected position here so that we can figure out how much to bloat the diameter to avoid aliasing of the sort where you skip pixels in a segment. + { + // PERF FIXME!! This could be simplified quite a bit if this ever becomes a bottleneck. I feel dirty. + // Get the view-space position for two points that are posrad.w units away from each other horizontally. + float3 viewPos1 = mul4x3( float4( posrad.xyz, 1.0f ), cModelView ); + float3 viewPos2 = viewPos1 + float3( posrad.w, 0.0f, 0.0f ); + + // Project both points. + float4 projPos1 = mul( float4( viewPos1, 1.0f ), cProj ); + float4 projPos2 = mul( float4( viewPos2, 1.0f ), cProj ); + + // Get the distance of the two points from each other in normalized screen space. + float projectedDiameterInPixels = abs( ( projPos1.x / projPos1.w ) - ( projPos2.x / projPos2.w ) ); + + // Compare the distance between the two points to the minimum allowed to keep from skipping pixels and causing aliasing. + if ( projectedDiameterInPixels < g_MinPixelSize ) + { + // Scale the radius in world space so that it is bigger than the required pixel size in screen space. + posrad.w *= ( g_MinPixelSize / projectedDiameterInPixels ); + } + } + + float3 v2p = float3( 0, 0, 1 ); + v2p = posrad.xyz - cEyePos; // screen aligned + + float3 tangent = DCatmullRomSpline3( P0, P1, P2, P3, v.vParms.x ); + float3 ofs = normalize( cross( v2p, normalize( tangent ) ) ); + posrad.xyz += ofs * ( posrad.w * ( v.vParms.z - .5 ) ); + o.projPos = mul( float4(posrad.xyz, 1.0f), cViewProj ); + o.worldPos_projPosZ.xyz = posrad.xyz; + o.worldPos_projPosZ.w = o.projPos.z; + o.texCoord.xy = float2( 1.0f - v.vParms.z, v.vParms.y ); + o.argbcolor = float4( v.vTint.rgb, v.vTint.a ); + + return o; +} diff --git a/materialsystem/stdshaders/sdk_sprite_ps30.fxc b/materialsystem/stdshaders/sdk_sprite_ps30.fxc new file mode 100644 index 00000000..9f5bf5e0 --- /dev/null +++ b/materialsystem/stdshaders/sdk_sprite_ps30.fxc @@ -0,0 +1,54 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CONSTANTCOLOR" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "SRGB" "0..1" + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +const HALF4 g_Color : register( c0 ); +const float g_HDRColorScale : register( c1 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result, sample = tex2D( TexSampler, i.baseTexCoord ); + +#if VERTEXCOLOR + sample *= i.color; +#endif + +#if CONSTANTCOLOR + sample *= g_Color; +#endif + +#if HDRTYPE && HDRENABLED + sample.xyz *= g_HDRColorScale; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); +#if SRGB + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#else + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_GAMMA ); +#endif + + return result; +} + diff --git a/materialsystem/stdshaders/sdk_sprite_vs30.fxc b/materialsystem/stdshaders/sdk_sprite_vs30.fxc new file mode 100644 index 00000000..b37f237d --- /dev/null +++ b/materialsystem/stdshaders/sdk_sprite_vs30.fxc @@ -0,0 +1,56 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SRGB" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + projPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. +#if SRGB + o.color.rgba = GammaToLinear( v.vColor.rgba ); +#else + o.color.rgba = v.vColor.rgba; +#endif + } + + // Base texture coordinates + o.baseTexCoord.xy = v.vTexCoord0.xy; + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_spritecard_ps30.fxc b/materialsystem/stdshaders/sdk_spritecard_ps30.fxc new file mode 100644 index 00000000..36095fb6 --- /dev/null +++ b/materialsystem/stdshaders/sdk_spritecard_ps30.fxc @@ -0,0 +1,193 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "DUALSEQUENCE" "0..1" +// STATIC: "SEQUENCE_BLEND_MODE" "0..2" +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "MAXLUMFRAMEBLEND1" "0..1" +// STATIC: "MAXLUMFRAMEBLEND2" "0..1" +// STATIC: "EXTRACTGREENALPHA" "0..1" +// STATIC: "COLORRAMP" "0..1" +// STATIC: "ANIMBLEND" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "DEPTHBLEND" "0..1" + +#define COMBINE_MODE_AVERAGE 0 +#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1 +#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +const float4 g_Parameters : register( c0 ); +const float4 g_DepthFeatheringConstants : register( c2 ); + +#define fAdditiveBlendWeight g_Parameters.x +#define fOverbrightFactor g_Parameters.y +#define fAdditiveSelfBlendWeight g_Parameters.z + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif +#if EXTRACTGREENALPHA + float4 blendfactor1 : TEXCOORD4; +#endif + +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vScreenPos_ReverseZ : TEXCOORD7; +#else + float4 vScreenPos : TEXCOORD7; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); +sampler ColorRampSampler : register( s1 ); +sampler DepthSampler : register( s2 ); + +float4 main( PS_INPUT i ) : COLOR +{ + bool bMaxLumFrameBlend1 = MAXLUMFRAMEBLEND1 ? true : false; + bool bMaxLumFrameBlend2 = MAXLUMFRAMEBLEND2 ? true : false; + bool bExtractGreenAlpha = EXTRACTGREENALPHA ? true : false; + bool bAddBaseTexture2 = ADDBASETEXTURE2 ? true : false; + bool bDualSequence = DUALSEQUENCE ? true : false; + bool bColorRamp = COLORRAMP ? true : false; +#ifdef DEPTHBLEND + bool bDepthBlend = DEPTHBLEND ? true : false; +#endif + int nSequenceBlendMode = SEQUENCE_BLEND_MODE; + + // Sample frames from texture 0 + float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); + + float4 baseTex1 = tex2D( BaseTextureSampler, i.texCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha) +#if ANIMBLEND + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = baseTex0; +#endif + + if ( bMaxLumFrameBlend1 ) + { + // Blend between animation frames based upon max luminance + float lum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float lum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( lum0 > lum1 ) + blended_rgb = baseTex0; + else + blended_rgb = baseTex1; + } + else if( bExtractGreenAlpha ) + { +#if EXTRACTGREENALPHA + // Weight Green/Alphas from the two frames for a scalar result + blended_rgb = dot( baseTex0, i.blendfactor0 ) + dot( baseTex1, i.blendfactor1 ); +#endif + } + +#if DUALSEQUENCE + if ( bDualSequence ) + { + baseTex0 = tex2D( BaseTextureSampler, i.vSeq2TexCoord0 ); + baseTex1 = tex2D( BaseTextureSampler, i.vSeq2TexCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend2) + float4 rgb2 = lerp( baseTex0, baseTex1, i.blendfactor0.z ); + + if ( bMaxLumFrameBlend2 ) + { + // blend between animation frames based upon max luminance + float tlum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float tlum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( tlum0 > tlum1 ) + rgb2 = baseTex0; + else + rgb2 = baseTex1; + } + + if ( nSequenceBlendMode == COMBINE_MODE_AVERAGE ) + { + blended_rgb = 0.5 * ( blended_rgb + rgb2 ); + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND ) + { + blended_rgb.rgb = rgb2.rgb; + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_OVER_SECOND ) + { + blended_rgb.rgb = lerp( blended_rgb.rgb, rgb2.rgb, rgb2.a ); + } + } // bDualSequence +#endif + + // Optional color ramp + if ( bColorRamp ) + { + blended_rgb.rgb = tex2D( ColorRampSampler, float2( blended_rgb.r, blended_rgb.g ) ); + } + + // Overbright + blended_rgb.rgb *= fOverbrightFactor; + + //Soft Particles FTW +# if (DEPTHBLEND == 1) +# if defined( _X360 ) + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos_ReverseZ.xy / i.vScreenPos_ReverseZ.w, i.vScreenPos_ReverseZ.z, i.vScreenPos_ReverseZ.w, g_DepthFeatheringConstants ); +# else + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos.xy / i.vScreenPos.w, i.vScreenPos.z, i.vScreenPos.w, g_DepthFeatheringConstants ); +# endif + i.argbcolor.a *= fDepthBlend; +# endif + + // Premultiply the alpha for a ONE:INVALPHA blend +#if ADDBASETEXTURE2 + if ( bAddBaseTexture2 ) + { + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + if ( !bColorRamp ) + { + blended_rgb.rgb *= blended_rgb.a; + } + + if ( bExtractGreenAlpha ) + { + blended_rgb.rgb += fAdditiveBlendWeight * i.argbcolor.a * blended_rgb.rgb; + } + else + { + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * tex2D( BaseTextureSampler, i.texCoord2 ); + } + + blended_rgb.rgb *= i.argbcolor.rgb; + } + else +#endif + { +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveSelfBlendWeight * i.argbcolor.a * blended_rgb; + blended_rgb.rgb *= i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif + } + + return FinalOutput( blended_rgb, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/materialsystem/stdshaders/spritecard_vsxx.fxc b/materialsystem/stdshaders/sdk_spritecard_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/spritecard_vsxx.fxc rename to materialsystem/stdshaders/sdk_spritecard_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_teeth_bump_ps30.fxc b/materialsystem/stdshaders/sdk_teeth_bump_ps30.fxc new file mode 100644 index 00000000..53359190 --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_bump_ps30.fxc @@ -0,0 +1,76 @@ +//====== Copyright � 1996-2006, Valve Corporation, All rights reserved. ======= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#include "shader_constant_register_map.h" + +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +sampler BaseTextureSampler : register( s0 ); +sampler BumpTextureSampler : register( s1 ); +sampler NormalizeSampler : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +#define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz +#define fDarkening i.worldVertToEyeVector_Darkening.w + +float4 main( PS_INPUT i ) : COLOR +{ + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1); + float fSpecExp = g_EyePos_SpecExponent.w; + + float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord ); + tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f; + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent + if ( fSpecExp == 0 ) + fSpecExp = 1.0f * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w; + + // Summation of diffuse illumination from all local lights + float3 diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, + bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true, + false, 0, false, NormalizeSampler ); + + float3 vDummy, specularLighting; + + // Summation of specular from all local lights + PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector), + vLightAtten, nNumLights, cLightInfo, + false, 1.0f, false, NormalizeSampler, 1.0f, false, 1.0f, + + // Outputs + specularLighting, vDummy ); + + // Specular plus diffuse, all darkened as a function of mouth openness + float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshaders/sdk_teeth_bump_vs30.fxc b/materialsystem/stdshaders/sdk_teeth_bump_vs30.fxc new file mode 100644 index 00000000..87b5fe66 --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_bump_vs30.fxc @@ -0,0 +1,120 @@ +//======= Copyright � 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" + +#include "common_vortwarp_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#if ( MORPHING ) +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + float4 vUserData : TANGENT; // Sign for cross product in w + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), + vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, worldTangentS, worldTangentT ); +#endif + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + // Needed for specular + o.worldVertToEyeVector_Darkening.xyz = cEyePos - worldPos; + + // Special darkening of lights for mouth open/close + o.worldVertToEyeVector_Darkening.w = cTeethLighting.w * saturate( dot( worldNormal, cTeethLighting.xyz ) );; + + // Scalar light attenuation (mouth darkening applied in pixel shader) + o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, true ); + o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, true ); + + o.baseTexCoord = v.vTexCoord0; + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_teeth_flashlight_ps30.fxc b/materialsystem/stdshaders/sdk_teeth_flashlight_ps30.fxc new file mode 100644 index 00000000..e4fce0c9 --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_flashlight_ps30.fxc @@ -0,0 +1,53 @@ +//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler SpotSampler : register( s1 ); +sampler FlashlightDepthSampler : register( s2 ); +sampler RandomRotationSampler : register( s3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float3 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float3 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4 g_FlashlightAtten : register( PSREG_FLASHLIGHT_ATTENUATION ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 projPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 result = tex2D( SpotSampler, vProjCoords ); + + result *= cFlashlightColor.rgb; + result *= DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true ); + result *= 0.35f; // Without this, unshadowed teeth always seem to glow + result *= i.vertAtten; // Distance atten, NdotL and forward vector + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + result *= baseSample.rgb; // Multiply by base map and diffuse + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos.xyz, i.projPos.z ); + return FinalOutput( float4( result, baseSample.a ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/materialsystem/stdshaders/sdk_teeth_flashlight_vs30.fxc b/materialsystem/stdshaders/sdk_teeth_flashlight_vs30.fxc new file mode 100644 index 00000000..14309aca --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_flashlight_vs30.fxc @@ -0,0 +1,138 @@ +//======= Copyright � 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vortwarp_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cFlashlightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_8 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_9 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#if ( MORPHING ) +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 vProjPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.worldPos = worldPos.xyz; + o.vProjPos = o.projPos; + + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cFlashlightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); + vDistAtten.y = rsqrt( vDistAtten.z ); + + float flDist = vDistAtten.z * vDistAtten.y; // Distance to light + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float NdotL = saturate( dot( worldNormal, normalize( vWorldPosToLightVector ) ) ); + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + // Final attenuation from flashlight only... + float linearAtten = NdotL * dot( vDistAtten, cFlashlighAtten.xyz ) * endFalloffFactor; + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Modulate flashlight by mouth darkening + o.vertAtten = linearAtten * fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_teeth_ps30.fxc b/materialsystem/stdshaders/sdk_teeth_ps30.fxc new file mode 100644 index 00000000..7f72b3e8 --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_ps30.fxc @@ -0,0 +1,37 @@ +//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float4 result; + result.xyz = baseSample.xyz * i.vertAtten; + result.a = baseSample.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/materialsystem/stdshaders/sdk_teeth_vs30.fxc b/materialsystem/stdshaders/sdk_teeth_vs30.fxc new file mode 100644 index 00000000..0a0d5b05 --- /dev/null +++ b/materialsystem/stdshaders/sdk_teeth_vs30.fxc @@ -0,0 +1,109 @@ +//======= Copyright � 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" + +#include "common_vortwarp_fxc.h" +#include "common_morphing_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#if ( MORPHING ) +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; + +#if ( MORPHING ) + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if ( MORPHING ) + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#else + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + // Compute lighting + float3 linearColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false ); + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Darken by forward dot normal and illumination factor + linearColor *= fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.vertAtten = linearColor; + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_unlitgeneric_ps30.fxc b/materialsystem/stdshaders/sdk_unlitgeneric_ps30.fxc new file mode 100644 index 00000000..2c7296a6 --- /dev/null +++ b/materialsystem/stdshaders/sdk_unlitgeneric_ps30.fxc @@ -0,0 +1,18 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +#include "common_ps_fxc.h" + +sampler TextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result = i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/materialsystem/stdshaders/sdk_unlitgeneric_vs30.fxc b/materialsystem/stdshaders/sdk_unlitgeneric_vs30.fxc new file mode 100644 index 00000000..ca504d22 --- /dev/null +++ b/materialsystem/stdshaders/sdk_unlitgeneric_vs30.fxc @@ -0,0 +1,76 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTextureTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cMaskTextureTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cDetailTextureTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4 g_vVertexColor : register( SHADER_SPECIFIC_CONST_6 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + +#if VERTEXCOLOR + float4 vColor : COLOR0; +#endif + + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + + float4 vColor : COLOR0; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + float3 worldNormal; + + //------------------------------------------------------------------------------ + // Vertex blending + //------------------------------------------------------------------------------ + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + //------------------------------------------------------------------------------ + // Texture coord transforms + //------------------------------------------------------------------------------ + o.vTexCoord0 = mul( v.vTexCoord0, (float2x4)cBaseTextureTransform ); + o.vTexCoord3 = mul( v.vTexCoord0, (float2x4)cDetailTextureTransform ); + + o.vColor = cModulationColor; + +#if VERTEXCOLOR + // 0 or 1 for g_vVertexColor.x, eliminating a bool + o.vColor = lerp( o.vColor, o.vColor * v.vColor, g_vVertexColor.x ); +#endif + + return o; +} + + + diff --git a/materialsystem/stdshaders/sdk_unlittwotexture_ps30.fxc b/materialsystem/stdshaders/sdk_unlittwotexture_ps30.fxc new file mode 100644 index 00000000..8e6a84e7 --- /dev/null +++ b/materialsystem/stdshaders/sdk_unlittwotexture_ps30.fxc @@ -0,0 +1,54 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// STATIC: "TRANSLUCENT" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +#if defined( SHADER_MODEL_PS_2_0 ) + #define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +const HALF4 g_DiffuseModulation : register( c1 ); +#if !FLASHLIGHT + // we don't use these with HDR. + const HALF3 g_EnvmapContrast : register( c2 ); + const HALF3 g_EnvmapSaturation : register( c3 ); +#endif + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler BaseTextureSampler2 : register( s1 ); + +struct PS_INPUT +{ + float4 projPos : POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + float4 baseColor2 = tex2D( BaseTextureSampler2, i.baseTexCoord2.xy ); + float4 result = baseColor * baseColor2 * g_DiffuseModulation; + + // This material can only get a non-opaque alpha if the material is marked as translucent +# if ( TRANSLUCENT == 0 ) + result.a = 1.0f; +# endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/materialsystem/stdshaders/sdk_unlittwotexture_vs30.fxc b/materialsystem/stdshaders/sdk_unlittwotexture_vs30.fxc new file mode 100644 index 00000000..cb799727 --- /dev/null +++ b/materialsystem/stdshaders/sdk_unlittwotexture_vs30.fxc @@ -0,0 +1,57 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 ); // 2 & 3 + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha + + float4 vColor : COLOR0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, worldPos ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + + // Needed for water fog alpha; + o.worldPos_projPosZ = float4( worldPos.xyz, o.projPos.z ); // FIXME: we shouldn't have to compute this all thie time. + + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); // Base texture coordinates + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + o.baseTexCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); // Secondary texture coordinates + o.baseTexCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); + + o.vColor = cModulationColor; + + return o; +} diff --git a/materialsystem/stdshaders/sdk_volume_clouds_ps30.fxc b/materialsystem/stdshaders/sdk_volume_clouds_ps30.fxc new file mode 100644 index 00000000..d507ab46 --- /dev/null +++ b/materialsystem/stdshaders/sdk_volume_clouds_ps30.fxc @@ -0,0 +1,65 @@ +//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +// Includes ======================================================================================= +#include "common_vertexlitgeneric.h" + +// Texture Samplers =============================================================================== +sampler g_tInnerSampler : register( s0 ); +sampler g_tMiddleSampler : register( s1 ); +sampler g_tOuterSampler : register( s2 ); + +// Shaders Constants and Globals ================================================================== +//const float4 g_vPackedConst6 : register( c6 ); +//#define g_flTime g_vPackedConst6.w + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 v2DTangentViewVector01 : TEXCOORD0; + float4 vUv01 : TEXCOORD1; + float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + float4 vFinalColor = float4( 0.0f, 0.0f, 0.0f, 1.0f ); + +#if defined(SHADER_MODEL_PS_2_0) + float flNumLayers = 2.0f; +#else + float flNumLayers = 10.0f; +#endif + + //float flColorDim = 1.0f; + for ( float j=flNumLayers-1.0f; j>=0.0f; j-=1.0f ) // From hightest to lowest layer + { + float4 vInnerTexel = tex2D( g_tInnerSampler, saturate( i.vUv01.xy + i.v2DTangentViewVector01.xy * 0.005 * j ) ); + float4 vMiddleTexel = tex2D( g_tMiddleSampler, saturate( i.vUv01.wz + i.v2DTangentViewVector01.wz * 0.005 * j ) ); + float4 vOuterTexel = tex2D( g_tOuterSampler, saturate( i.v2DTangentViewVector2_vUv2.wz + i.v2DTangentViewVector2_vUv2.xy * 0.005 * j ) ); + + float4 vThisTexel; + vThisTexel.rgb = ( vInnerTexel.rgb * vInnerTexel.a ) + ( vMiddleTexel.rgb * vMiddleTexel.a ) + ( vOuterTexel.rgb * vOuterTexel.a ); + vThisTexel.a = 1.0f - ( ( 1.0f - vOuterTexel.a ) * ( 1.0f - vMiddleTexel.a ) * ( 1.0f - vInnerTexel.a ) ); + + //vThisTexel.rgb *= flColorDim; + //flColorDim *= 0.95f; + + // 5.0 and 0.8625 are magic numbers that look good with the current textures + float flBlendValue = saturate( pow( vThisTexel.a, lerp( 5.0f, 0.8625f, saturate( j/(flNumLayers-1.0f) ) ) ) ); + + vFinalColor.rgb = vThisTexel.rgb + ( vFinalColor.rgb * ( 1.0f - flBlendValue ) ); + vFinalColor.a *= 1.0f - flBlendValue; // Dest alpha scalar + } + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = vFinalColor.rgb; + result.a = 1.0f - vFinalColor.a; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit. +} diff --git a/materialsystem/stdshaders/volume_clouds_vs20.fxc b/materialsystem/stdshaders/sdk_volume_clouds_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/volume_clouds_vs20.fxc rename to materialsystem/stdshaders/sdk_volume_clouds_vs30.fxc diff --git a/materialsystem/stdshaders/sdk_water_ps30.fxc b/materialsystem/stdshaders/sdk_water_ps30.fxc new file mode 100644 index 00000000..d4146eef --- /dev/null +++ b/materialsystem/stdshaders/sdk_water_ps30.fxc @@ -0,0 +1,334 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "REFLECT" "0..1" +// STATIC: "REFRACT" "0..1" +// STATIC: "ABOVEWATER" "0..1" +// STATIC: "BLURRY_REFRACT" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#include "common_ps_fxc.h" + +sampler RefractSampler : register( s0 ); +#if BASETEXTURE +sampler BaseTextureSampler : register( s1 ); +#endif +sampler ReflectSampler : register( s2 ); +#if BASETEXTURE +sampler LightmapSampler : register( s3 ); +#endif +sampler NormalSampler : register( s4 ); + +const HALF4 vRefractTint : register( c1 ); +const HALF4 vReflectTint : register( c4 ); +const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale +const HALF4 g_WaterFogColor : register( c6 ); +const HALF4 g_WaterFogParams : register( c7 ); + +const float4 g_PixelFogParams : register( c8 ); + +const float3 g_EyePos : register( c9 ); + +#define g_WaterFogStart g_WaterFogParams.x +#define g_WaterFogEndMinusStart g_WaterFogParams.y +#define g_Reflect_OverBright g_WaterFogParams.z + +struct PS_INPUT +{ + float2 vBumpTexCoord : TEXCOORD0; + half3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float4 vWorldPos_projPosW : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE +// CENTROID: TEXCOORD6 + HALF4 lightmapTexCoord1And2 : TEXCOORD6; +// CENTROID: TEXCOORD7 + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + + float4 fogFactorW : COLOR1; +}; + +struct DrawWater_params_t +{ + float2 vBumpTexCoord; +#if MULTITEXTURE + float4 vExtraBumpTexCoord; +#endif + float4 vReflectXY_vRefractYX; + float w; + float4 vReflectRefractScale; + float fReflectOverbright; + float4 vReflectTint; + float4 vRefractTint; + half3 vTangentEyeVect; + float4 waterFogColor; +#if BASETEXTURE + HALF4 lightmapTexCoord1And2; + HALF4 lightmapTexCoord3; +#endif + float4 vProjPos; + float4 pixelFogParams; + float fWaterFogStart; + float fWaterFogEndMinusStart; + float3 vEyePos; + float3 vWorldPos; +}; + +void DrawWater( in DrawWater_params_t i, +#if BASETEXTURE + in sampler BaseTextureSampler, + in sampler LightmapSampler, +#endif + in sampler NormalSampler, + in sampler RefractSampler, + in sampler ReflectSampler, + out float4 result, out float fogFactor ) +{ + bool bReflect = REFLECT ? true : false; + bool bRefract = REFRACT ? true : false; + +#if MULTITEXTURE + float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord ); + float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy ); + float4 vNormal2 = tex2D( NormalSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + + vNormal.xyz = 2.0 * vNormal.xyz - 1.0; + +#else + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORM_DECODE_NONE ); +#endif + + // Perform division by W only once + float ooW = 1.0f / i.w; + + float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; + +#if ABOVEWATER + float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; +#else + // We don't actually have valid depth values in alpha when we are underwater looking out, so + // just set to farthest value. + float waterFogDepthValue = 1.0f; +#endif + float4 reflectRefractScale = i.vReflectRefractScale; +#if !BASETEXTURE +#if ( BLURRY_REFRACT == 0 ) + reflectRefractScale *= waterFogDepthValue; +#endif +#endif + + // Compute coordinates for sampling Reflection + float2 vReflectTexCoord; + float2 vRefractTexCoord; + + // vectorize the dependent UV calculations (reflect = .xy, refract = .wz) + float4 vN; + vN.xy = vNormal.xy; + vN.w = vNormal.x; + vN.z = vNormal.y; + float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale; + + vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); + vReflectTexCoord = vDependentTexCoords.xy; + vRefractTexCoord = vDependentTexCoords.wz; + + HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); +#if BLURRY_REFRACT + // Sample reflection and refraction + float2 ddx1=float2(0.005,0); + float2 ddy1=float2(0,0.005); + float4 vRefractColor=float4(0,0,0,0); + +#if 0 + float sumweights=0; + for(int ix=-2;ix<=2;ix++) + { + for(int iy=-2;iy<=2;iy++) + { + float weight=1; ///(1+abs(ix)+abs(iy)); + vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1); + sumweights+=weight; + } + } +#else + // NOTE: Generated by genwaterloop.pl in the stdshaders directory. + // Need to unroll for 360 to avoid shader compilation problems. + // Modified genwaterloop.pl and regenerate if you need different params + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 ); + float sumweights = 25; + // NOTE: end of generated code. +#endif + + vRefractColor *= (1.0/sumweights); + vReflectColor *= i.fReflectOverbright; + vReflectColor *= i.vReflectTint; + vRefractColor *= i.vRefractTint; +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + // get the blurred depth value to be used for fog. + waterFogDepthValue = vRefractColor.a; +# endif +#else + vReflectColor *= i.vReflectTint; + HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); + // get the depth value from the refracted sample to be used for fog. +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a; +# endif +#endif + + half3 vEyeVect; + vEyeVect = normalize( i.vTangentEyeVect ); + + // Fresnel term + HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); + HALF fFresnel = pow( 1.0 - fNdotV, 5 ); + +#if !BASETEXTURE + // fFresnel == 1.0f means full reflection + fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f ); +#endif + + + // blend between refraction and fog color. +#if ABOVEWATER + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) ); +#else + float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart ); + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor ); +#endif + +#if BASETEXTURE + float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy ); + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + HALF3 lightmapColor1 = lightmapSample1.rgb; + HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + + float3 diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= LIGHT_MAP_SCALE / sum; + HALF3 diffuseComponent = baseSample.rgb * diffuseLighting; +#endif + + if( bReflect && bRefract ) + { + result = lerp( vRefractColor, vReflectColor, fFresnel ); + } + else if( bReflect ) + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a; +#else + result = vReflectColor; +#endif + } + else if( bRefract ) + { + result = vRefractColor; + } + else + { + result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + fogFactor = CalcRangeFogFactorNonFixedFunction( i.vWorldPos, i.vEyePos, i.pixelFogParams.z, i.pixelFogParams.x, i.pixelFogParams.w ); +#else + fogFactor = 0; +#endif +} + +float4 main( PS_INPUT i ) : COLOR +{ + DrawWater_params_t params; + + params.vBumpTexCoord = i.vBumpTexCoord; +#if MULTITEXTURE + params.vExtraBumpTexCoord = i.vExtraBumpTexCoord; +#endif + params.vReflectXY_vRefractYX = i.vReflectXY_vRefractYX; + params.w = i.vWorldPos_projPosW.w; + params.vReflectRefractScale = g_ReflectRefractScale; + params.fReflectOverbright = g_Reflect_OverBright; + params.vReflectTint = vReflectTint; + params.vRefractTint = vRefractTint; + params.vTangentEyeVect = i.vTangentEyeVect; + params.waterFogColor = g_WaterFogColor; +#if BASETEXTURE + params.lightmapTexCoord1And2 = i.lightmapTexCoord1And2; + params.lightmapTexCoord3 = i.lightmapTexCoord3; +#endif + params.vProjPos = i.vProjPos; + params.pixelFogParams = g_PixelFogParams; + params.fWaterFogStart = g_WaterFogStart; + params.fWaterFogEndMinusStart = g_WaterFogEndMinusStart; + params.vEyePos = g_EyePos; + params.vWorldPos = i.vWorldPos_projPosW.xyz; + + float4 result; + float fogFactor; + DrawWater( params, + // yay. . can't put sampler in a struct. +#if BASETEXTURE + BaseTextureSampler, + LightmapSampler, +#endif + NormalSampler, RefractSampler, ReflectSampler, + result, fogFactor ); + + return FinalOutput( float4( result.rgb, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); +} + diff --git a/materialsystem/stdshaders/sdk_water_vs30.fxc b/materialsystem/stdshaders/sdk_water_vs30.fxc new file mode 100644 index 00000000..bee4aa50 --- /dev/null +++ b/materialsystem/stdshaders/sdk_water_vs30.fxc @@ -0,0 +1,118 @@ +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#include "common_vs_fxc.h" + +const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; +#if !defined( _X360 ) + float vFog : FOG; +#endif + float2 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float4 vWorldPos_projPosW : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE + HALF4 lightmapTexCoord1And2 : TEXCOORD6; + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + // Projected position + float4 vProjPos = mul( v.vPos, cModelViewProj ); + o.vProjPos = o.vProjPos_POSITION = vProjPos; + + // Project tangent basis + float2 vProjTangentS = mul( v.vTangentS, cViewProj ); + float2 vProjTangentT = mul( v.vTangentT, cViewProj ); + + // Map projected position to the reflection texture + float2 vReflectPos; + vReflectPos = (vProjPos.xy + vProjPos.w) * 0.5f; + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Reflection transform + o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x ); + o.vWorldPos_projPosW.w = vProjPos.w; + + o.screenCoord = vProjPos.x; + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.vFog = o.fogFactorW; +#endif + o.vWorldPos_projPosW.xyz = vWorldPos; + + // Eye vector + float3 vWorldEyeVect = cEyePos - vWorldPos; + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, v.vTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, v.vTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, vObjNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + float f45x=v.vBaseTexCoord.x+v.vBaseTexCoord.y; + float f45y=v.vBaseTexCoord.y-v.vBaseTexCoord.x; +#if MULTITEXTURE + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vBaseTexCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vBaseTexCoord.x*0.45+TexOffsets.w; +#endif + +#if BASETEXTURE + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; +#endif + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_watercheap_ps30.fxc b/materialsystem/stdshaders/sdk_watercheap_ps30.fxc new file mode 100644 index 00000000..71253b11 --- /dev/null +++ b/materialsystem/stdshaders/sdk_watercheap_ps30.fxc @@ -0,0 +1,143 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "FRESNEL" "0..1" +// STATIC: "BLEND" "0..1" +// STATIC: "REFRACTALPHA" "0..1" +// STATIC: "HDRTYPE" "0..2" + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" + +const HALF3 g_WaterFogColor : register( c0 ); +const HALF4 g_CheapWaterParams : register( c1 ); +const HALF4 g_ReflectTint : register( c2 ); +const float4 g_PixelFogParams : register( c3 ); +const float3 g_EyePos : register( c4 ); + +#define g_CheapWaterStart g_CheapWaterParams.x +#define g_CheapWaterEnd g_CheapWaterParams.y +#define g_CheapWaterDeltaRecip g_CheapWaterParams.z +#define g_CheapWaterStartDivDelta g_CheapWaterParams.w + +sampler EnvmapSampler : register( s0 ); +sampler NormalMapSampler : register( s1 ); +#if REFRACTALPHA +sampler RefractSampler : register( s2 ); +#endif +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + float2 normalMapTexCoord : TEXCOORD0; + HALF3 worldSpaceEyeVect : TEXCOORD1; + HALF3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif + float3 vWorldPos : TEXCOORD7; + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBlend = BLEND ? true : false; + +#if MULTITEXTURE + float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord ); + float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy ); + float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + + vNormal = 2.0 * vNormal - 1.0; + +#else + float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORM_DECODE_NONE ); +#endif + + HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); + HALF3 worldSpaceEye; + + HALF flWorldSpaceDist = 1.0f; + +#ifdef NV3X + // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes. + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye ); + HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr ); + worldSpaceEye *= rcpWorldSpaceDist; + flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#else // !NV3X + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + flWorldSpaceDist = length( worldSpaceEye ); + worldSpaceEye /= flWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#endif + + HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye ); + HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= g_ReflectTint; + +#if FRESNEL + // FIXME: It's unclear that we want to do this for cheap water + // but the code did this previously and I didn't want to change it + HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal ); + flDotResult = 1.0f - max( 0.0f, flDotResult ); + + HALF flFresnelFactor = flDotResult * flDotResult; + flFresnelFactor *= flFresnelFactor; + flFresnelFactor *= flDotResult; +#else + HALF flFresnelFactor = g_ReflectTint.a; +#endif + + HALF flAlpha; + if (bBlend) + { + HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta ); + flAlpha = saturate( flFresnelFactor + flReflectAmount ); + +#if REFRACTALPHA + // Perform division by W only once + float ooW = 1.0f / i.vRefract_W_ProjZ.z; + float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW; + float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; + // Fade on the border between the water and land. + flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f ); +#endif + } + else + { + flAlpha = 1.0f; +#if HDRTYPE == 0 || HDRENABLED == 0 + specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor ); +#else + specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor ); +#endif + } + + // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders. +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + float fogFactor = CalcRangeFogFactorNonFixedFunction( i.vWorldPos, g_EyePos, g_PixelFogParams.z, g_PixelFogParams.x, g_PixelFogParams.w ); +#else + float fogFactor = 0; +#endif + + return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/materialsystem/stdshaders/sdk_watercheap_vs30.fxc b/materialsystem/stdshaders/sdk_watercheap_vs30.fxc new file mode 100644 index 00000000..4b9086b3 --- /dev/null +++ b/materialsystem/stdshaders/sdk_watercheap_vs30.fxc @@ -0,0 +1,87 @@ +// STATIC: "BLEND" "0..1" +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vNormalMapCoord : TEXCOORD0; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 normalMapTexCoord : TEXCOORD0; + float3 worldVertToEyeVector : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + float4 vExtraBumpTexCoord : TEXCOORD6; + float3 vWorldPos : TEXCOORD7; + float4 fogFactorW : COLOR1; +}; + +const float4 cNormalMapTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + + projPos = mul( v.vPos, cModelViewProj ); + o.projPos = projPos; + +#if BLEND + // Map projected position to the reflection texture + o.vRefract_W_ProjZ.x = projPos.x; + o.vRefract_W_ProjZ.y = -projPos.y; // invert Y + o.vRefract_W_ProjZ.xy = (o.vRefract_W_ProjZ + projPos.w) * 0.5f; + o.vRefract_W_ProjZ.z = projPos.w; +#endif + + o.vRefract_W_ProjZ.w = projPos.z; + + worldPos = mul( v.vPos, cModel[0] ); + + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVector = worldVertToEyeVector; + + // FIXME: need to add a normalMapTransform to all of the water shaders. + //o.normalMapTexCoord.x = dot( v.vNormalMapCoord, cNormalMapTransform[0] ) + cNormalMapTransform[0].w; + //o.normalMapTexCoord.y = dot( v.vNormalMapCoord, cNormalMapTransform[1] ) + cNormalMapTransform[1].w; + o.normalMapTexCoord = v.vNormalMapCoord; + + float f45x=v.vNormalMapCoord.x+v.vNormalMapCoord.y; + float f45y=v.vNormalMapCoord.y-v.vNormalMapCoord.x; + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vNormalMapCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vNormalMapCoord.x*0.45+TexOffsets.w; + + o.fogFactorW = CalcFog( worldPos, projPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + o.vWorldPos = worldPos; + + return o; +} + + diff --git a/materialsystem/stdshaders/sdk_windowimposter_ps30.fxc b/materialsystem/stdshaders/sdk_windowimposter_ps30.fxc new file mode 100644 index 00000000..c8d60268 --- /dev/null +++ b/materialsystem/stdshaders/sdk_windowimposter_ps30.fxc @@ -0,0 +1,61 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// +// STATIC: "PARALLAXCORRECT" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler EnvmapSampler : register( s0 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +#if PARALLAXCORRECT +// Parallax cubemaps +const float3 cubemapPos : register(c0); +const float4x4 obbMatrix : register(c1); //through c4 +#endif + +struct PS_INPUT +{ + float3 eyeToVertVector : TEXCOORD0; + float4 vertexColor : COLOR; + + float4 worldPos_projPosZ : TEXCOORD1; // Necessary for pixel fog + +#if PARALLAXCORRECT + float3 worldSpaceNormal : TEXCOORD2; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if PARALLAXCORRECT + float3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, g_EyePos_SpecExponent.xyz - i.worldPos_projPosZ.xyz ); //i.eyeToVertVector; //CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.eyeToVertVector ); + + //Parallax correction (2_0b and beyond) + //Adapted from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ + float3 worldPos = i.worldPos_projPosZ.xyz; + float3 positionLS = mul(float4(worldPos, 1), obbMatrix); + float3 rayLS = mul(reflectVect, (float3x3) obbMatrix); + + float3 firstPlaneIntersect = (float3(1.0f, 1.0f, 1.0f) - positionLS) / rayLS; + float3 secondPlaneIntersect = (-positionLS) / rayLS; + float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect); + float distance = min(furthestPlane.x, min(furthestPlane.y, furthestPlane.z)); + + // Use distance in WS directly to recover intersection + float3 intersectPositionWS = worldPos + reflectVect * distance; + reflectVect = intersectPositionWS - cubemapPos; +#else + float3 reflectVect = i.eyeToVertVector; +#endif + + HALF4 color; + color.xyz = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + color.a = 1.0f; + color *= i.vertexColor; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( color, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/materialsystem/stdshaders/sdk_windowimposter_vs30.fxc b/materialsystem/stdshaders/sdk_windowimposter_vs30.fxc new file mode 100644 index 00000000..607cea8a --- /dev/null +++ b/materialsystem/stdshaders/sdk_windowimposter_vs30.fxc @@ -0,0 +1,50 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// +// +// Purpose: +// +//=========================================================================== +// STATIC: "PARALLAXCORRECT" "0..1" + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; +#if PARALLAXCORRECT + float4 vNormal : NORMAL; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float3 eyeToVertVector : TEXCOORD0; + float4 vertexColor : COLOR; + + float4 worldPos_projPosZ : TEXCOORD1; // Necessary for pixel fog + +#if PARALLAXCORRECT + float3 worldNormal : TEXCOORD2; +#endif +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + + float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + o.worldPos_projPosZ = float4( worldPos.xyz, o.projPos.z ); + o.eyeToVertVector = worldPos - cEyePos; + +#if PARALLAXCORRECT + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + o.worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); +#endif + + o.vertexColor = cModulationColor; + return o; +} + diff --git a/materialsystem/stdshaders/sdk_worldtwotextureblend_ps30.fxc b/materialsystem/stdshaders/sdk_worldtwotextureblend_ps30.fxc new file mode 100644 index 00000000..7499fef6 --- /dev/null +++ b/materialsystem/stdshaders/sdk_worldtwotextureblend_ps30.fxc @@ -0,0 +1,214 @@ +//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "DETAIL_ALPHA_MASK_BASE_TEXTURE" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" + +// SKIP: $DETAILTEXTURE && ( $BUMPMAP && !$DETAIL_ALPHA_MASK_BASE_TEXTURE ) +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $VERTEXCOLOR && $BUMPMAP +// SKIP: FLASHLIGHT && $SELFILLUM +// SKIP: FLASHLIGHT && $DETAIL_ALPHA_MASK_BASE_TEXTURE +// SKIP: FLASHLIGHT && ($BUMPMAP || $DIFFUSEBUMPMAP) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + + +#define HDRTYPE HDR_TYPE_NONE +#include "common_flashlight_fxc.h" +#include "common_ps_fxc.h" + +const HALF4 g_SelfIllumTint : register( c7 ); +static const HALF g_OverbrightFactor = 2.0f; + +const HALF3 g_EyePos : register( c10 ); +const HALF4 g_FogParams : register( c11 ); + +const HALF3 g_FlashlightPos : register( c15 ); +// flashlightfixme: Move this math into the vertex shader. +const float4x4 g_FlashlightWorldToTexture : register( c16 ); + +const float4 g_FlashlightAttenuationFactors : register( c20 ); + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler FlashlightSampler : register( s2 ); +sampler DetailSampler : register( s3 ); +sampler BumpmapSampler : register( s4 ); +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; + HALF4 detailOrBumpTexCoord : TEXCOORD1; + HALF4 lightmapTexCoord1And2 : TEXCOORD2; // CENTROID: TEXCOORD2 + HALF2 lightmapTexCoord3 : TEXCOORD3; // CENTROID: TEXCOORD3 + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6; + // tangentSpaceTranspose : TEXCOORD7; + HALF4 vertexColor : COLOR; +}; + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); + if( bBumpmap && bDiffuseBumpmap ) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + } + else + { + if( !bFlashlight ) + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + } + } + + HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + if( bDetailTexture ) + { + detailColor = tex2D( DetailSampler, i.detailOrBumpTexCoord.xy ); + } + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + if ( bDetailAlphaMaskBaseTexture ) + { + // This is what WorldTwoTextureBlend_DX6 does. + baseColor.rgb = saturate( saturate( baseColor * 2 ) * detailColor.a + (1 - detailColor.a) ); + baseColor.rgb *= detailColor; + } + else + { + baseColor.rgb = lerp( baseColor, detailColor, detailColor.a ); + } + + HALF3 normal = HALF3( 0.0f, 0.0f, 1.0f ); + if( bBumpmap ) + { + HALF3 normalTexel; + normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord.xy ); + normal = 2.0 * normalTexel - 1.0; + } + + HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f ); + HALF alpha = 1.0f; + albedo *= baseColor; + if( !bSelfIllum ) + { + alpha *= baseColor.a; + } + + // The vertex color contains the modulation color + vertex color combined + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + HALF3 diffuseLighting; + if( bFlashlight ) + { + float3 worldSpaceNormal; + // Make the unbumped version not so fucking stupid and not need tangentSpaceTranspose you knob. + worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); + + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); + + diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, FlashlightSampler, NormalizeSampler, + nShadowSampleLevel, bDoShadows, false, float2(0, 0), false ); + } + else + { + if( bBumpmap && bDiffuseBumpmap ) + { + float dot1 = saturate( dot( normal, bumpBasis[0] ) ); + float dot2 = saturate( dot( normal, bumpBasis[1] ) ); + float dot3 = saturate( dot( normal, bumpBasis[2] ) ); + + float sum = dot1 + dot2 + dot3; + diffuseLighting = dot1 * lightmapColor1 + + dot2 * lightmapColor2 + + dot3 * lightmapColor3; + diffuseLighting *= 1.0f / sum; + } + else + { + diffuseLighting = lightmapColor1; + } + + // Only scale here since the flashlight will already be scaled properly + diffuseLighting *= g_OverbrightFactor; + } + + HALF3 diffuseComponent = albedo * diffuseLighting; + + if( bSelfIllum ) + { + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + HALF3 result = diffuseComponent + specularLighting; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/materialsystem/stdshaders/shader_constant_register_map.h b/materialsystem/stdshaders/shader_constant_register_map.h index ef1d9df7..9e8702de 100644 --- a/materialsystem/stdshaders/shader_constant_register_map.h +++ b/materialsystem/stdshaders/shader_constant_register_map.h @@ -6,7 +6,7 @@ //============================================================================= #ifndef C_CODE_HACK -#include "common_vertexlitgeneric_dx9.h" +#include "common_vertexlitgeneric.h" #endif #define PSREG_SELFILLUMTINT PSREG_CONSTANT_00 diff --git a/materialsystem/stdshaders/shadow.cpp b/materialsystem/stdshaders/shadow.cpp deleted file mode 100644 index 2c8b380e..00000000 --- a/materialsystem/stdshaders/shadow.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "shadow_ps20.inc" -#include "shadow_ps20b.inc" -#include "shadow_vs20.inc" - -BEGIN_VS_SHADER_FLAGS( Shadow, "Help for Shadow", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - /* - The alpha blending state either must be: - - Src Color * Dst Color + Dst Color * 0 - (src color = C*A + 1-A) - - or - - // Can't be this, doesn't work with fog - Src Color * Dst Color + Dst Color * (1-Src Alpha) - (src color = C * A, Src Alpha = A) - */ - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "Shadow_DX8"; - } - return 0; - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - - // NOTE: This is deliberately this way round (instead of "DST_COLOR, ZERO"), - // since these two permutations produce *different* values on 360!! - // This was causing undue darkening of the framebuffer by these - // shadows, which was highly noticeable in very dark areas: - EnableAlphaBlending( SHADER_BLEND_ZERO, SHADER_BLEND_SRC_COLOR ); - - - unsigned int flags = VERTEX_POSITION | VERTEX_COLOR; - int numTexCoords = 1; - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( shadow_vs20 ); - SET_STATIC_VERTEX_SHADER( shadow_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( shadow_ps20b ); - SET_STATIC_PIXEL_SHADER( shadow_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( shadow_ps20 ); - SET_STATIC_PIXEL_SHADER( shadow_ps20 ); - } - - pShaderShadow->EnableSRGBWrite( true ); - - // We need to fog to *white* regardless of overbrighting... - FogToWhite(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - SetPixelShaderConstantGammaToLinear( 1, COLOR ); - - // Get texture dimensions... - int nWidth = 16; - int nHeight = 16; - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - if (pTexture) - { - nWidth = pTexture->GetActualWidth(); - nHeight = pTexture->GetActualHeight(); - } - - Vector4D vecJitter( 1.0 / nWidth, 1.0 / nHeight, 0.0, 0.0 ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vecJitter.Base() ); - - vecJitter.y *= -1.0f; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vecJitter.Base() ); - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - - DECLARE_DYNAMIC_VERTEX_SHADER( shadow_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER( shadow_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( shadow_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( shadow_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( shadow_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( shadow_ps20 ); - } - - float eyePos[4]; - pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); - pShaderAPI->SetPixelShaderConstant( 2, eyePos, 1 ); - pShaderAPI->SetPixelShaderFogParams( 3 ); - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/shadow_ps2x.fxc b/materialsystem/stdshaders/shadow_ps2x.fxc deleted file mode 100644 index d1eaa939..00000000 --- a/materialsystem/stdshaders/shadow_ps2x.fxc +++ /dev/null @@ -1,62 +0,0 @@ -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -const HALF4 g_ShadowColor : register( c1 ); -const HALF3 g_EyePos : register( c2 ); -const HALF4 g_FogParams : register( c3 ); - -sampler ShadowSampler : register( s0 ); - -// CENTROID: TEXCOORD0 -// CENTROID: TEXCOORD1 -// CENTROID: TEXCOORD2 -// CENTROID: TEXCOORD3 -// CENTROID: TEXCOORD4 -struct PS_INPUT -{ - float2 texCoord0 : TEXCOORD0; - float2 texCoord1 : TEXCOORD1; - float2 texCoord2 : TEXCOORD2; - float2 texCoord3 : TEXCOORD3; - float2 texCoord4 : TEXCOORD4; - HALF4 worldPos_projPosZ : TEXCOORD5; - HALF4 shadowColor : COLOR0; - HALF4 fogFactorW : COLOR1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - HALF4 samples[5]; - samples[0] = tex2D( ShadowSampler, i.texCoord0 ); - samples[1] = tex2D( ShadowSampler, i.texCoord1 ); - samples[2] = tex2D( ShadowSampler, i.texCoord2 ); - samples[3] = tex2D( ShadowSampler, i.texCoord3 ); - samples[4] = tex2D( ShadowSampler, i.texCoord4 ); - - // Interpolate between a bunch of jittered shadow samples. - HALF shadowCoverage = (samples[0].a + samples[1].a + samples[2].a + samples[3].a + samples[4].a) * 0.2; - - // To accomplish shadow fading, subtract vertex alpha from texture alpha - shadowCoverage = saturate( shadowCoverage - i.shadowColor.a ); - - // Blend between white and the constant color... - // return lerp( 1.0-shadowCoverage, 1.0, g_ShadowColor ); - - // this is equivalent, and saves an instruction - HALF4 result = shadowCoverage*g_ShadowColor - shadowCoverage; - result = 1.0 + result; - - float alpha = 1.0f; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - - // Apply fog here to compensate for our srcColor*dstColor alpha blend into already fogged pixels - result.rgb = 1.0f - ( ( 1.0f - result.rgb ) * pow( ( 1.0f - fogFactor ), 4.0f ) ); - - // Call FinalOutput without fog! - return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/shadow_vs20.fxc b/materialsystem/stdshaders/shadow_vs20.fxc deleted file mode 100644 index 29b94769..00000000 --- a/materialsystem/stdshaders/shadow_vs20.fxc +++ /dev/null @@ -1,65 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cTextureJitter[2] : register( SHADER_SPECIFIC_CONST_2 ); - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vColor : COLOR0; - float4 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 texCoord0 : TEXCOORD0; - float2 texCoord1 : TEXCOORD1; - float2 texCoord2 : TEXCOORD2; - float2 texCoord3 : TEXCOORD3; - float2 texCoord4 : TEXCOORD4; - HALF4 worldPos_projPosZ : TEXCOORD5; - float4 shadowColor : COLOR0; - float4 fogFactorW : COLOR1; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldNormal, worldPos; - float2 texCoord; - worldPos = mul( v.vPos, cModel[0] ); - float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - - // NOTE: CalcFog returns 1 for non-water fog, so it's ok to use fog - // It returns the real fog for range fog, since we do vertex fog - o.fogFactorW = CalcFog( worldPos, projPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - o.shadowColor = v.vColor; - o.worldPos_projPosZ = float4( worldPos, projPos.z ); - - texCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - texCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - - o.texCoord0.xy = texCoord; - o.texCoord1.xy = texCoord + cTextureJitter[0]; - o.texCoord2.xy = texCoord - cTextureJitter[0]; - o.texCoord3.xy = texCoord + cTextureJitter[1]; - o.texCoord4.xy = texCoord - cTextureJitter[1]; - - return o; -} - - diff --git a/materialsystem/stdshaders/shadowbuild_dx9.cpp b/materialsystem/stdshaders/shadowbuild_dx9.cpp deleted file mode 100644 index d6df17e4..00000000 --- a/materialsystem/stdshaders/shadowbuild_dx9.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: A shader that builds the shadow using render-to-texture -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "mathlib/VMatrix.h" - -#include "unlitgeneric_vs20.inc" -#include "shadowbuildtexture_ps20.inc" -#include "shadowbuildtexture_ps20b.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( ShadowBuild, ShadowBuild_DX9 ) - -BEGIN_VS_SHADER_FLAGS( ShadowBuild_DX9, "Help for ShadowBuild", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( TRANSLUCENT_MATERIAL, SHADER_PARAM_TYPE_MATERIAL, "", "Points to a material to grab translucency from" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SHADER_FALLBACK - { - if ( !g_pHardwareConfig->SupportsVertexAndPixelShaders() ) - return "ShadowBuild_DX6"; - - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "ShadowBuild_DX8"; - - return 0; - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture(BASETEXTURE); - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - // Add the alphas into the frame buffer - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - - // base texture. We just use this for alpha, but enable SRGB read to make everything consistent. - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - pShaderShadow->EnableSRGBWrite( true ); - - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS ); - - // Specify vertex format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - unsigned int nTexCoordCount = 1; - unsigned int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( shadowbuildtexture_ps20b ); - SET_STATIC_PIXEL_SHADER( shadowbuildtexture_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( shadowbuildtexture_ps20 ); - SET_STATIC_PIXEL_SHADER( shadowbuildtexture_ps20 ); - } - } - DYNAMIC_STATE - { - SetModulationVertexShaderDynamicState(); - - // Snack important parameters from the original material - // FIXME: What about alpha modulation? Need a solution for that - ITexture *pTexture = NULL; - IMaterialVar **ppTranslucentParams = NULL; - if (params[TRANSLUCENT_MATERIAL]->IsDefined()) - { - IMaterial *pMaterial = params[TRANSLUCENT_MATERIAL]->GetMaterialValue(); - if (pMaterial) - { - ppTranslucentParams = pMaterial->GetShaderParams(); - if ( ppTranslucentParams[BASETEXTURE]->IsTexture() ) - { - pTexture = ppTranslucentParams[BASETEXTURE]->GetTextureValue(); - } - } - } - - if (pTexture) - { - BindTexture( SHADER_SAMPLER0, pTexture, ppTranslucentParams[FRAME]->GetIntValue() ); - - Vector4D transformation[2]; - const VMatrix &mat = ppTranslucentParams[BASETEXTURETRANSFORM]->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP_FULLBRIGHT ); - } - - BOOL bShaderConstants[1] = { false }; - pShaderAPI->SetBooleanVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0, bShaderConstants, 1 ); - - // Compute the vertex shader index. - DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( shadowbuildtexture_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( shadowbuildtexture_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( shadowbuildtexture_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( shadowbuildtexture_ps20 ); - } - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/shadowbuildtexture_ps2x.fxc b/materialsystem/stdshaders/shadowbuildtexture_ps2x.fxc deleted file mode 100644 index f29036f5..00000000 --- a/materialsystem/stdshaders/shadowbuildtexture_ps2x.fxc +++ /dev/null @@ -1,27 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#include "common_ps_fxc.h" - -sampler BaseTextureSampler : register( s0 ); - -struct PS_INPUT -{ - float2 vTexCoord0 : TEXCOORD0; - float4 vColor : COLOR0; - -#if defined( _X360 ) //matching pixel shader inputs to vertex shader outputs to avoid shader patches - float2 vTexCoord1 : TEXCOORD1; - float2 vTexCoord2 : TEXCOORD2; - float2 vTexCoord3 : TEXCOORD3; - float4 fogFactorW : COLOR1; - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -#endif -}; - -HALF4 main( PS_INPUT i ) : COLOR -{ - //relevant data is in the alpha channel, modulate vertex alpha by texture alpha - float returnAlpha = tex2D( BaseTextureSampler, i.vTexCoord0 ).a * i.vColor.a; - - return FinalOutput( float4( 1.0f, 1.0f, 1.0f, returnAlpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/shadowmodel.cpp b/materialsystem/stdshaders/shadowmodel.cpp new file mode 100644 index 00000000..f738fbcc --- /dev/null +++ b/materialsystem/stdshaders/shadowmodel.cpp @@ -0,0 +1,151 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +//Note: Not upgraded to vs/ps 2.0 fxc's because this shader is unused and there are no test cases to verify against. +#include "basevsshader.h" + +#if !defined( _X360 ) +#include "shadowmodel_ps20.inc" +#include "shadowmodel_vs20.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if !defined( _X360 ) //not used for anything at time of 360 ship, and we want to avoid storing/loading assembly shaders + +//PC version +BEGIN_VS_SHADER_FLAGS( ShadowModel, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ + if (!params[BASETEXTURESCALE]->IsDefined()) + { + Vector2D scale(1, 1); + params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); + } + + if (!params[FALLOFFDISTANCE]->IsDefined()) + params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); + + if (!params[FALLOFFAMOUNT]->IsDefined()) + params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "ShadowModel_DX8"; + + return 0; +} + +SHADER_INIT +{ + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } +} + +SHADER_DRAW +{ + SHADOW_STATE + { + // Base texture on stage 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Multiplicative blending state... + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + + // We need to fog to *white* regardless of overbrighting... + FogToWhite(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); + + Vector4D shadow; + shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); + shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; + if (shadow[1] != 0.0f) + shadow[1] = 1.0f / shadow[1]; + shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); + + // The constant color is the shadow color... + SetModulationVertexShaderDynamicState(); + + DECLARE_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + } + Draw( ); +} +END_SHADER + + +#else + +//360 version + +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT +{ +} + +SHADER_DRAW +{ + Draw( false ); +} +END_SHADER + +#endif \ No newline at end of file diff --git a/materialsystem/stdshaders/shadowmodel_dx8.cpp b/materialsystem/stdshaders/shadowmodel_dx8.cpp deleted file mode 100644 index e7d7228a..00000000 --- a/materialsystem/stdshaders/shadowmodel_dx8.cpp +++ /dev/null @@ -1,97 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "shadowmodel.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX8 ) - -BEGIN_VS_SHADER_FLAGS( ShadowModel_DX8, "Help for ShadowModel", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) - SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) - SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) - SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) - SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - if (!params[BASETEXTURESCALE]->IsDefined()) - { - Vector2D scale(1, 1); - params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); - } - - if (!params[FALLOFFDISTANCE]->IsDefined()) - params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); - - if (!params[FALLOFFAMOUNT]->IsDefined()) - params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - // Base texture on stage 0 - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Multiplicative blending state... - EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); - - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - shadowmodel_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "ShadowModel", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "ShadowModel" ); - - // We need to fog to *white* regardless of overbrighting... - FogToWhite(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); - - Vector4D shadow; - shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); - shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; - if (shadow[1] != 0.0f) - shadow[1] = 1.0f / shadow[1]; - shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); - - // The constant color is the shadow color... - SetModulationVertexShaderDynamicState(); - - shadowmodel_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/shadowmodel_dx9.cpp b/materialsystem/stdshaders/shadowmodel_dx9.cpp deleted file mode 100644 index 0198e86f..00000000 --- a/materialsystem/stdshaders/shadowmodel_dx9.cpp +++ /dev/null @@ -1,154 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -//Note: Not upgraded to vs/ps 2.0 fxc's because this shader is unused and there are no test cases to verify against. -#include "BaseVSShader.h" - -#if !defined( _X360 ) -#include "shadowmodel_ps20.inc" -#include "shadowmodel_vs20.inc" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX9 ) - - -#if !defined( _X360 ) //not used for anything at time of 360 ship, and we want to avoid storing/loading assembly shaders - -//PC version -BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) - -BEGIN_SHADER_PARAMS -SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) -SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) -SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) -SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) -SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) -END_SHADER_PARAMS - -SHADER_INIT_PARAMS() -{ - if (!params[BASETEXTURESCALE]->IsDefined()) - { - Vector2D scale(1, 1); - params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); - } - - if (!params[FALLOFFDISTANCE]->IsDefined()) - params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); - - if (!params[FALLOFFAMOUNT]->IsDefined()) - params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); -} - -SHADER_FALLBACK -{ - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "ShadowModel_DX8"; - - return 0; -} - -SHADER_INIT -{ - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - } -} - -SHADER_DRAW -{ - SHADOW_STATE - { - // Base texture on stage 0 - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - - // Multiplicative blending state... - EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); - - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); - SET_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); - - DECLARE_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); - SET_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); - - // We need to fog to *white* regardless of overbrighting... - FogToWhite(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); - - Vector4D shadow; - shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); - shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; - if (shadow[1] != 0.0f) - shadow[1] = 1.0f / shadow[1]; - shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); - - // The constant color is the shadow color... - SetModulationVertexShaderDynamicState(); - - DECLARE_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); - } - Draw( ); -} -END_SHADER - - -#else - -//360 version - -BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) - -BEGIN_SHADER_PARAMS -SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) -SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) -SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) -SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) -SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) -END_SHADER_PARAMS - -SHADER_INIT_PARAMS() -{ -} - -SHADER_FALLBACK -{ - return 0; -} - -SHADER_INIT -{ -} - -SHADER_DRAW -{ - Draw( false ); -} -END_SHADER - -#endif \ No newline at end of file diff --git a/materialsystem/stdshaders/shadowmodel_vs20.fxc b/materialsystem/stdshaders/shadowmodel_vs20.fxc deleted file mode 100644 index 9d1ff02c..00000000 --- a/materialsystem/stdshaders/shadowmodel_vs20.fxc +++ /dev/null @@ -1,81 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cShadowTextureMatrix[3] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cTexOrigin : register( SHADER_SPECIFIC_CONST_3 ); -const float4 cTexScale : register( SHADER_SPECIFIC_CONST_4 ); - -// { Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 } -const float3 cShadowConstants : register( SHADER_SPECIFIC_CONST_5 ); -#define flShadowFalloffOffset cShadowConstants.x -#define flOneOverShadowDist cShadowConstants.y -#define flShadowScale cShadowConstants.z - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float3 vNormal : NORMAL; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position - float3 T0 : TEXCOORD0; // PS wants this to be 4D but VS doesn't? (see original asm sources) - float3 T1 : TEXCOORD1; - float3 T2 : TEXCOORD2; - float T3 : TEXCOORD3; - float4 vColor : COLOR0; - float fog : FOG; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - // Perform skinning - float3 worldNormal, worldPos; - SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - - // Transform into projection space - o.projPos = mul( float4( worldPos, 1 ), cViewProj ); - - // Compute fog - o.fog = CalcFog( worldPos, o.projPos, g_FogType ); - - // Transform position into texture space (from 0 to 1) - float3 vTexturePos; - vTexturePos.x = dot( worldPos.xyz, cShadowTextureMatrix[0].xyz ); - vTexturePos.y = dot( worldPos.xyz, cShadowTextureMatrix[1].xyz ); - vTexturePos.z = dot( worldPos.xyz, cShadowTextureMatrix[2].xyz ); - - // Figure out the shadow fade amount - float flShadowFade = ( vTexturePos.z - flShadowFalloffOffset ) * flOneOverShadowDist; - - // Offset it into the texture - o.T0 = vTexturePos * cTexScale + cTexOrigin; - - // We're doing clipping by using texkill - o.T1.xyz = vTexturePos.xyz; // Also clips when shadow z < 0 ! - o.T2.xyz = float3( 1.0f, 1.0f, 1.0f ) - vTexturePos.xyz; - o.T2.z = 1.0f - flShadowFade; // Clips when shadow z > shadow distance - - // We're doing backface culling by using texkill also (wow yucky) - // -------------------------------------------------------------- - // Transform z component of normal in texture space - // If it's negative, then don't draw the pixel - o.T3 = dot( worldNormal, -cShadowTextureMatrix[2] ); - - // Shadow color, falloff - o.vColor.xyz = cModulationColor.xyz; - o.vColor.w = flShadowFade * flShadowScale; - - return o; -} diff --git a/materialsystem/stdshaders/shatteredglass.cpp b/materialsystem/stdshaders/shatteredglass.cpp new file mode 100644 index 00000000..7ec737cb --- /dev/null +++ b/materialsystem/stdshaders/shatteredglass.cpp @@ -0,0 +1,319 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "basevsshader.h" +#include "sdk_shatteredglass_ps30.inc" +#include "sdk_shatteredglass_vs30.inc" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +BEGIN_VS_SHADER( ShatteredGlass, "Help for ShatteredGlass" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "Glass/glasswindowbreak070b", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "Glass/glasswindowbreak070b", "detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "detail scale" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "glass/glasswindowbreak070b_mask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( UNLITFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.7", "0.0 == multiply by lightmap, 1.0 == multiply by 1" ) +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + SHADER_PARAM( ENVMAPPARALLAX, SHADER_PARAM_TYPE_BOOL, "0", "Enables parallax correction code for env_cubemaps" ) + SHADER_PARAM( ENVMAPPARALLAXOBB1, SHADER_PARAM_TYPE_VEC4, "[1 0 0 0]", "The first line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB2, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "The second line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB3, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "The third line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" ) +#endif + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + + if( !params[ENVMAPSATURATION]->IsDefined() ) + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + + if( !params[UNLITFACTOR]->IsDefined() ) + params[UNLITFACTOR]->SetFloatValue( 0.3f ); + + if( !params[FRESNELREFLECTION]->IsDefined() ) + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + + if( !params[ENVMAPFRAME]->IsDefined() ) + params[ENVMAPFRAME]->SetIntValue( 0 ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if ( !params[BASETEXTURE]->GetTextureValue()->IsTranslucent() ) + { + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if ( params[DETAIL]->IsDefined() ) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + LoadCubeMap( ENVMAP ); +#ifdef MAPBASE + if (mat_specular_disable_on_missing.GetBool()) + { + // Revert to defaultcubemap when the envmap texture is missing + // (should be equivalent to toolsblack in Mapbase) + if (params[ENVMAP]->GetTextureValue()->IsError()) + { + params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); + LoadCubeMap( ENVMAP ); + } + } +#endif + + if ( params[ENVMAPMASK]->IsDefined() ) + { + LoadTexture( ENVMAPMASK ); + } + } + } + + SHADER_DRAW + { + bool bHasEnvmapMask = false; + bool bHasEnvmap = false; +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + bool hasParallaxCorrection = false; +#endif + if ( params[ENVMAP]->IsTexture() ) + { + bHasEnvmap = true; +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + hasParallaxCorrection = params[ENVMAPPARALLAX]->GetIntValue() > 0; +#endif + if ( params[ENVMAPMASK]->IsTexture() ) + { + bHasEnvmapMask = true; + } + } + bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool bHasBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); + + // Base + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Alpha blending, enable alpha blending if the detail texture is translucent + bool detailIsTranslucent = TextureIsTranslucent( DETAIL, false ); + if ( detailIsTranslucent ) + { + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + else + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + // Base texture + unsigned int flags = VERTEX_POSITION; + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // Lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + else + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + } + + // Detail texture + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); + + // Envmap + if ( bHasEnvmap ) + { + flags |= VERTEX_NORMAL; + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + + if( bHasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + } + + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + + if ( bHasVertexColor ) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->VertexShaderVertexFormat( flags, 3, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_shatteredglass_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, bHasEnvmapMask ); + SET_STATIC_VERTEX_SHADER( sdk_shatteredglass_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_shatteredglass_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, bHasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps enabled for 2_0b and onwards + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection ); +#else + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, false ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_shatteredglass_ps30 ); + + DefaultFog(); + } + DYNAMIC_STATE + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, DETAILSCALE ); + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + BindTexture( SHADER_SAMPLER3, DETAIL ); + + if( bHasEnvmap ) + { + BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); + if( bHasEnvmapMask ) + { + BindTexture( SHADER_SAMPLER5, ENVMAPMASK, ENVMAPMASKFRAME ); + } + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_shatteredglass_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_shatteredglass_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_shatteredglass_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_shatteredglass_ps30 ); + + SetEnvMapTintPixelShaderDynamicState( 0, ENVMAPTINT, -1 ); + SetModulationPixelShaderDynamicState( 1 ); + SetPixelShaderConstant( 2, ENVMAPCONTRAST ); + SetPixelShaderConstant( 3, ENVMAPSATURATION ); + + // [ 0, 0 ,0, R(0) ] + float fresnel[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + fresnel[3] = params[FRESNELREFLECTION]->GetFloatValue(); + fresnel[0] = fresnel[1] = fresnel[2] = 1.0f - fresnel[3]; + pShaderAPI->SetPixelShaderConstant( 4, fresnel ); + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + pShaderAPI->SetPixelShaderConstant( 5, eyePos, 1 ); + + pShaderAPI->SetPixelShaderFogParams( 12 ); + + float overbright[4]; + overbright[0] = OVERBRIGHT; + overbright[1] = params[UNLITFACTOR]->GetFloatValue(); + overbright[2] = overbright[3] = 1.0f - params[UNLITFACTOR]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 6, overbright ); + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + if (hasParallaxCorrection) + { + pShaderAPI->SetPixelShaderConstant( 7, params[ENVMAPORIGIN]->GetVecValue() ); + + float* vecs[3]; + vecs[0] = const_cast(params[ENVMAPPARALLAXOBB1]->GetVecValue()); + vecs[1] = const_cast(params[ENVMAPPARALLAXOBB2]->GetVecValue()); + vecs[2] = const_cast(params[ENVMAPPARALLAXOBB3]->GetVecValue()); + float matrix[4][4]; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + matrix[i][j] = vecs[i][j]; + } + } + matrix[3][0] = matrix[3][1] = matrix[3][2] = 0; + matrix[3][3] = 1; + pShaderAPI->SetPixelShaderConstant( 8, &matrix[0][0], 4 ); + } +#endif + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/skin_dx9_helper.cpp b/materialsystem/stdshaders/skin_dx9_helper.cpp deleted file mode 100644 index cc999788..00000000 --- a/materialsystem/stdshaders/skin_dx9_helper.cpp +++ /dev/null @@ -1,990 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "skin_dx9_helper.h" -#include "convar.h" -#include "cpp_shader_constant_register_map.h" -#include "skin_vs20.inc" -#include "skin_ps20b.inc" -#include "commandbuilder.h" - -#ifndef _X360 -#include "skin_vs30.inc" -#include "skin_ps30.inc" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); -static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); -static ConVar r_rimlight( "r_rimlight", "1", FCVAR_NONE ); - -// Textures may be bound to the following samplers: -// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha -// SHADER_SAMPLER1 Specular warp (including iridescence) -// SHADER_SAMPLER2 Diffuse Lighting warp texture -// SHADER_SAMPLER3 Normal Map -// SHADER_SAMPLER4 Flashlight Shadow Depth Map -// SHADER_SAMPLER5 Normalization cube map -// SHADER_SAMPLER6 Flashlight Cookie -// SHADER_SAMPLER7 Specular exponent -// SHADER_SAMPLER8 Cubic environment map -// SHADER_SAMPLER9 Compressed wrinklemap -// SHADER_SAMPLER10 Stretched wrinklemap -// SHADER_SAMPLER11 Compressed wrinkle normal map -// SHADER_SAMPLER12 Stretched wrinkle normal map -// SHADER_SAMPLER13 Detail texture - - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ) -{ - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - Assert( info.m_nFlashlightTexture >= 0 ); - - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. - if( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && - params[info.m_nBaseTexture]->IsDefined() ) - { - params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); - } - - // This shader can be used with hw skinning - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - - // No texture means no env mask in base alpha - if ( !params[info.m_nBaseTexture]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - // Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map - bool bBump = (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined(); - bool bEnvMap = (info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsDefined(); - bool bDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined(); - bool bPhong = (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined(); - if( bBump || bEnvMap || bDiffuseWarp || bPhong ) - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - } - else - { - CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - } - - if ( ( info.m_nSelfIllumFresnel != -1 ) && ( !params[info.m_nSelfIllumFresnel]->IsDefined() ) ) - { - params[info.m_nSelfIllumFresnel]->SetIntValue( 0 ); - } - - if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) ) - { - params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f ); - } - - if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) ) - { - params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 ); - } - - if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) ) - { - params[info.m_nEnvmapFresnel]->SetFloatValue( 0 ); - } -} - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- -void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitGeneric_DX9_Vars_t &info ) -{ - Assert( info.m_nFlashlightTexture >= 0 ); - pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); - - bool bIsBaseTextureTranslucent = false; - if ( params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - - if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) && - params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() ) - { - pShader->LoadTexture( info.m_nWrinkle, TEXTUREFLAGS_SRGB ); - pShader->LoadTexture( info.m_nStretch, TEXTUREFLAGS_SRGB ); - } - } - - bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); - - // No alpha channel in any of the textures? No self illum or envmapmask - if ( !bIsBaseTextureTranslucent ) - { - bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); - - // Can still be self illum with no base alpha if using one of these alternate modes - if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - } - - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - if ( (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsDefined() && - (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) - { - pShader->LoadTexture( info.m_nPhongExponentTexture ); - } - - if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() && - (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) - { - pShader->LoadTexture( info.m_nDiffuseWarpTexture ); - } - - if ( (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsDefined() && - (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) - { - pShader->LoadTexture( info.m_nPhongWarpTexture ); - } - - if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) - { - int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); - if ( nDetailBlendMode == 0 ) // Mod2X - pShader->LoadTexture( info.m_nDetail ); - else - pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); - } - - if ( g_pConfig->UseBumpmapping() ) - { - if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nBumpmap ); - SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); - - if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) && - params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() ) - { - pShader->LoadTexture( info.m_nNormalWrinkle ); - pShader->LoadTexture( info.m_nNormalStretch ); - } - } - } - - if ( params[info.m_nEnvmap]->IsDefined() ) - { - pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); - } - - if ( bHasSelfIllumMask ) - { - pShader->LoadTexture( info.m_nSelfIllumMask ); - } -} - -class CSkin_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - bool m_bFastPath; - -}; - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawSkin_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bHasFlashlight, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); - bool bHasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture(); - - bool bHasBaseTextureWrinkle = bHasBaseTexture && - (info.m_nWrinkle != -1) && params[info.m_nWrinkle]->IsTexture() && - (info.m_nStretch != -1) && params[info.m_nStretch]->IsTexture(); - - bool bHasBumpWrinkle = bHasBump && - (info.m_nNormalWrinkle != -1) && params[info.m_nNormalWrinkle]->IsTexture() && - (info.m_nNormalStretch != -1) && params[info.m_nNormalStretch]->IsTexture(); - - bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) != 0; - bool bHasSelfIllumFresnel = ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); - bool bHasSelfIllumMask = ( bHasSelfIllum ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsTexture(); - - // Tie these to specular - bool bHasPhong = (info.m_nPhong != -1) && ( params[info.m_nPhong]->GetIntValue() != 0 ); - bool bHasSpecularExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture(); - bool bHasPhongTintMap = bHasSpecularExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 ); - bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); - bool bHasPhongWarp = (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsTexture(); - bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - -#if !defined( _X360 ) - bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); -#endif - - // Rimlight must be set to non-zero to trigger rim light combo (also requires Phong) - bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 ); - bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 ); - - float fBlendFactor=( info.m_nDetailTextureBlendFactor == -1 )? 1 : params[info.m_nDetailTextureBlendFactor]->GetFloatValue(); - bool hasDetailTexture = ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsTexture(); - int nDetailBlendMode = ( hasDetailTexture && info.m_nDetailTextureCombineMode != -1 ) ? params[info.m_nDetailTextureCombineMode]->GetIntValue() : 0; - - bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) && !bHasSelfIllum; // Pixel shader can't do both BLENDTINTBYBASEALPHA and SELFILLUM, so let selfillum win - - float flTintReplacementAmount = GetFloatParam( info.m_nTintReplacesBaseColor, params ); - - float flPhongExponentFactor = ( info.m_nPhongExponentFactor != -1 ) ? GetFloatParam( info.m_nPhongExponentFactor, params ) : 0.0f; - const bool bHasPhongExponentFactor = flPhongExponentFactor != 0.0f; - - BlendType_t nBlendType= pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true ); - - bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && !bHasFlashlight; //dest alpha is free for special use - - CSkin_DX9_Context *pContextData = reinterpret_cast< CSkin_DX9_Context *> ( *pContextDataPtr ); - if ( ! pContextData ) - { - pContextData = new CSkin_DX9_Context; - *pContextDataPtr = pContextData; - } - - if( pShader->IsSnapshotting() ) - { - // look at color and alphamod stuff. - // Unlit generic never uses the flashlight - bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); - bool bHasNormal = params[info.m_nBumpmap]->IsTexture(); - bool bCanUseBaseAlphaPhongMaskFastPath = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); - - if ( ! ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) ) - bCanUseBaseAlphaPhongMaskFastPath = true; - - pContextData->m_bFastPath = - (! bHasBump ) && - (! bHasSpecularExponentTexture ) && - (! bHasPhongTintMap ) && - (! bHasPhongWarp ) && - (! bHasRimLight ) && - (! hasDetailTexture ) && - bCanUseBaseAlphaPhongMaskFastPath && - (! bHasSelfIllum ) && - (! bBlendTintByBaseAlpha ); - - // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if( bHasFlashlight ) - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - - if( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - else // not flashlight pass - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); - } - - if ( bHasEnvmap ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Cubic environment map - if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); - } - } - } - - unsigned int flags = VERTEX_POSITION; - if( bHasNormal ) - { - flags |= VERTEX_NORMAL; - } - - int userDataSize = 0; - - // Always enable...will bind white if nothing specified... - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Base (albedo) compression map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Base (albedo) expansion map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true ); - } - - if( bHasDiffuseWarp ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Diffuse warp texture - } - - if( bHasPhongWarp ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Specular warp texture - } - - // Specular exponent map or dummy - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Specular exponent map - - if( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); - userDataSize = 4; // tangent S - } - - // Always enable, since flat normal will be bound - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map - userDataSize = 4; // tangent S - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map - - if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal compression map - pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Normal expansion map - } - - if ( hasDetailTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); - if ( nDetailBlendMode != 0 ) //Not Mod2X - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true ); - } - - if ( bHasSelfIllum ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); - } - - if( bHasVertexColor || bHasVertexAlpha ) - { - flags |= VERTEX_COLOR; - } - - pShaderShadow->EnableSRGBWrite( true ); - - // texcoord0 : base texcoord, texcoord2 : decal hw morph delta - int pTexCoordDim[3] = { 2, 0, 3 }; - int nTexCoordCount = 1; - -#ifndef _X360 - // Special morphed decal information - if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) - { - nTexCoordCount = 3; - } -#endif - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); - - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_STATIC_VERTEX_SHADER( skin_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( skin_vs20 ); - - // Assume we're only going to get in here if we support 2b - DECLARE_STATIC_PIXEL_SHADER( skin_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); - SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); - SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( skin_ps20b ); - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( skin_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); - SET_STATIC_VERTEX_SHADER( skin_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( skin_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); - SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); - SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( skin_ps30 ); - } -#endif - - if( bHasFlashlight ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - else // not snapshotting -- begin dynamic state - { - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); - - if( bHasBaseTexture ) - { - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - } - - if ( bHasBaseTextureWrinkle ) - { - pShader->BindTexture( SHADER_SAMPLER9, info.m_nWrinkle, info.m_nBaseTextureFrame ); - pShader->BindTexture( SHADER_SAMPLER10, info.m_nStretch, info.m_nBaseTextureFrame ); - } - else if ( bHasBumpWrinkle ) - { - pShader->BindTexture( SHADER_SAMPLER9, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - pShader->BindTexture( SHADER_SAMPLER10, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - - if( bHasDiffuseWarp && bHasPhong ) - { - if ( r_lightwarpidentity.GetBool() ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_IDENTITY_LIGHTWARP ); - } - else - { - pShader->BindTexture( SHADER_SAMPLER2, info.m_nDiffuseWarpTexture ); - } - } - - if( bHasPhongWarp ) - { - pShader->BindTexture( SHADER_SAMPLER1, info.m_nPhongWarpTexture ); - } - - if( bHasSpecularExponentTexture && bHasPhong ) - { - pShader->BindTexture( SHADER_SAMPLER7, info.m_nPhongExponentTexture ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_WHITE ); - } - - if( !g_pConfig->m_bFastNoBump ) - { - if( bHasBump ) - pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); - else - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); - - if ( bHasBumpWrinkle ) - { - pShader->BindTexture( SHADER_SAMPLER11, info.m_nNormalWrinkle, info.m_nBumpFrame ); - pShader->BindTexture( SHADER_SAMPLER12, info.m_nNormalStretch, info.m_nBumpFrame ); - } - else if ( bHasBaseTextureWrinkle ) - { - pShader->BindTexture( SHADER_SAMPLER11, info.m_nBumpmap, info.m_nBumpFrame ); - pShader->BindTexture( SHADER_SAMPLER12, info.m_nBumpmap, info.m_nBumpFrame ); - } - } - else - { - if( bHasBump ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); - } - if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER11, TEXTURE_NORMALMAP_FLAT ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER12, TEXTURE_NORMALMAP_FLAT ); - } - } - - if ( hasDetailTexture ) - { - pShader->BindTexture( SHADER_SAMPLER13, info.m_nDetail, info.m_nDetailFrame ); - } - - if ( bHasSelfIllum ) - { - if ( bHasSelfIllumMask ) // Separate texture for self illum? - { - pShader->BindTexture( SHADER_SAMPLER14, info.m_nSelfIllumMask ); // Bind it - } - else // else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER14, TEXTURE_BLACK ); // Bind dummy - } - } - - LightState_t lightState = { 0, false, false }; - bool bFlashlightShadows = false; - if( bHasFlashlight ) - { - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); - - SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - } - else // no flashlight - { - if ( bHasEnvmap ) - { - pShader->BindTexture( SHADER_SAMPLER8, info.m_nEnvmap, info.m_nEnvmapFrame ); - } - - pShaderAPI->GetDX9LightState( &lightState ); - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - int numBones = pShaderAPI->GetCurrentNumBones(); - - // don't have an easy way to get this through to GLM, so just print it old school - //printf("\n-D- DrawSkin_DX9_Internal numBones is %d", numBones ); - - bool bWriteDepthToAlpha = false; - bool bWriteWaterFogToAlpha = false; - if( bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER( skin_vs20 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PHONG_USE_EXPONENT_FACTOR, bHasPhongExponentFactor ); - SET_DYNAMIC_PIXEL_SHADER( skin_ps20b ); - } -#ifndef _X360 - else - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( skin_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PHONG_USE_EXPONENT_FACTOR, bHasPhongExponentFactor ); - SET_DYNAMIC_PIXEL_SHADER( skin_ps30 ); - - bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; - pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); - } -#endif - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - - if( bHasBump ) - { - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); - } - - if ( hasDetailTexture ) - { - if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) - pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, - info.m_nDetailTextureTransform, - info.m_nDetailScale ); - else - pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, - info.m_nBaseTextureTransform, - info.m_nDetailScale ); - } - - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - pShader->SetPixelShaderConstant_W( PSREG_SELFILLUMTINT, info.m_nSelfIllumTint, fBlendFactor ); - bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 ); - float fInvertPhongMask = bInvertPhongMask ? 1 : 0; - - bool bHasBaseAlphaPhongMask = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); - float fHasBaseAlphaPhongMask = bHasBaseAlphaPhongMask ? 1 : 0; - // Controls for lerp-style paths through shader code - float vShaderControls[4] = { fHasBaseAlphaPhongMask, 0.0f/*unused*/, flTintReplacementAmount, fInvertPhongMask }; - pShaderAPI->SetPixelShaderConstant( PSREG_CONSTANT_27, vShaderControls, 1 ); - - if ( hasDetailTexture ) - { -#if 0 // needs constant change - if ( info.m_nDetailTint != -1 ) - pShader->SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); - else - { - float boring_tint[4]={1,1,1,1}; - pShaderAPI->SetPixelShaderConstant( 10, boring_tint, 1 ); - } -#endif - } - - if ( bHasSelfIllumFresnel && !bHasFlashlight ) - { - float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; - float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; - float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; - float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; - - vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias - vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale - vConstScaleBiasExp[2] = flExp; // Exp - vConstScaleBiasExp[3] = flMax; // Brightness - - pShaderAPI->SetPixelShaderConstant( PSREG_SELFILLUM_SCALE_BIAS_EXP, vConstScaleBiasExp, 1 ); - } - - pShader->SetAmbientCubeDynamicStateVertexShader(); - - if( !bHasFlashlight ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); - - // Setting .x to 1 means to apply Fresnel to env map. Setting w to 1 means use separate selfillummask - float vEnvMapFresnel_SelfIllumMask[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - vEnvMapFresnel_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; - - if( bHasEnvmap ) - { - float vEnvMapTint_MaskControl[4] = {1.0f, 1.0f, 1.0f, 0.0f}; - - // If we have a tint, grab it - if ( (info.m_nEnvmapTint != -1) && params[info.m_nEnvmapTint]->IsDefined() ) - params[info.m_nEnvmapTint]->GetVecValue(vEnvMapTint_MaskControl, 3); - - // Set control for source of env map mask (normal alpha or base alpha) - vEnvMapTint_MaskControl[3] = bHasNormalMapAlphaEnvmapMask ? 1.0f : 0.0f; - - if ( (info.m_nEnvmapFresnel != -1) && params[info.m_nEnvmapFresnel]->IsDefined() ) - vEnvMapFresnel_SelfIllumMask[0] = params[info.m_nEnvmapFresnel]->GetFloatValue(); - - // Handle mat_fullbright 2 (diffuse lighting only with 50% gamma space basetexture) - if( bLightingOnly ) - { - vEnvMapTint_MaskControl[0] = vEnvMapTint_MaskControl[1] = vEnvMapTint_MaskControl[2] = 0.0f; - } - - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, vEnvMapTint_MaskControl, 1 ); - } - - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK, vEnvMapFresnel_SelfIllumMask, 1 ); - } - - pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight - pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); - - // Pack Phong exponent in with the eye position - float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {1, 0.5, 1, 1}, vRimBoost[4] = {1, 1, 1, 1}; - float vSpecularTint[4] = {1, 1, 1, 4}; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - - // If we have a phong exponent factor, then use that as a multiplier against the texture. - if ( bHasPhongExponentFactor ) - { - vEyePos_SpecExponent[3] = flPhongExponentFactor; - } - else - { - // Use the alpha channel of the normal map for the exponent by default - vEyePos_SpecExponent[3] = -1.f; - if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() ) - { - float fValue = params[info.m_nPhongExponent]->GetFloatValue(); - if ( fValue > 0.f ) - { - // Nonzero value in material overrides map channel - vEyePos_SpecExponent[3] = fValue; - } - } - } - - // Get the tint parameter - if ( (info.m_nPhongTint != -1) && params[info.m_nPhongTint]->IsDefined() ) - { - params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 3); - } - - // Get the rim light power (goes in w of Phong tint) - if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() ) - { - vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue(); - vSpecularTint[3] = max(vSpecularTint[3], 1.0f); // Make sure this is at least 1 - } - - // Get the rim boost (goes in w of flashlight position) - if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() ) - { - vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue(); - } - - if ( !bHasFlashlight ) - { - float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code - vRimMaskControl[0] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f; - - // Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 ); - } - - // If it's all zeros, there was no constant tint in the vmt - if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) ) - { - if ( bHasPhongTintMap ) // If we have a map to use, tell the shader - { - vSpecularTint[0] = -1; - } - else // Otherwise, just tint with white - { - vSpecularTint[0] = 1.0f; - vSpecularTint[1] = 1.0f; - vSpecularTint[2] = 1.0f; - } - } - - // handle mat_fullbright 2 (diffuse lighting only) - if( bLightingOnly ) - { - // BASETEXTURE - if( bHasSelfIllum && !bHasFlashlight ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - // DETAILTEXTURE - if ( hasDetailTexture ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER13, TEXTURE_GREY ); - } - - // turn off specularity - vSpecularTint[0] = vSpecularTint[1] = vSpecularTint[2] = 0.0f; - } - - if ( (info.m_nPhongFresnelRanges != -1) && params[info.m_nPhongFresnelRanges]->IsDefined() ) - { - params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters - // Change fresnel range encoding from (min, mid, max) to ((mid-min)*2, mid, (max-mid)*2) - vFresnelRanges_SpecBoost[0] = (vFresnelRanges_SpecBoost[1] - vFresnelRanges_SpecBoost[0]) * 2; - vFresnelRanges_SpecBoost[2] = (vFresnelRanges_SpecBoost[2] - vFresnelRanges_SpecBoost[1]) * 2; - } - - if ( (info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined()) // Grab optional Phong boost param - vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue(); - else - vFresnelRanges_SpecBoost[3] = 1.0f; - - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 ); - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass - - pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 ); - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - // flashlightfixme: put this in common code. - if( bHasFlashlight ) - { - VMatrix worldToTexture; - float atten[4], pos[4], tweaks[4]; - - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost - - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); - - // Tweaks associated with a given flashlight - tweaks[0] = ShadowFilterFromState( flashlightState ); - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - - if ( IsX360() ) - { - pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); - } - } - } - pShader->Draw(); -} - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -extern ConVar r_flashlight_version2; -void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) - -{ - bool bHasFlashlight = pShader->UsingFlashlight( params ); - if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) - { - DrawSkin_DX9_Internal( pShader, params, pShaderAPI, - pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); - if ( pShaderShadow ) - { - pShader->SetInitialShadowState( ); - } - } - DrawSkin_DX9_Internal( pShader, params, pShaderAPI, - pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/skin_dx9_helper.h b/materialsystem/stdshaders/skin_dx9_helper.h deleted file mode 100644 index 414e8dd2..00000000 --- a/materialsystem/stdshaders/skin_dx9_helper.h +++ /dev/null @@ -1,35 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef SKIN_DX9_HELPER_H -#define SKIN_DX9_HELPER_H - -#include - -#include "vertexlitgeneric_dx9_helper.h" - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - -void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, - const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ); -void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, - VertexLitGeneric_DX9_Vars_t &info ); - -void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, - VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ); - - - -#endif // SKIN_DX9_HELPER_H diff --git a/materialsystem/stdshaders/skin_helper.cpp b/materialsystem/stdshaders/skin_helper.cpp new file mode 100644 index 00000000..e0fc5c7c --- /dev/null +++ b/materialsystem/stdshaders/skin_helper.cpp @@ -0,0 +1,977 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "basevsshader.h" +#include "skin_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "commandbuilder.h" +#include "sdk_skin_vs30.inc" +#include "sdk_skin_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +// Textures may be bound to the following samplers: +// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha +// SHADER_SAMPLER1 Specular warp (including iridescence) +// SHADER_SAMPLER2 Diffuse Lighting warp texture +// SHADER_SAMPLER3 Normal Map +// SHADER_SAMPLER4 Flashlight Shadow Depth Map +// SHADER_SAMPLER5 Normalization cube map +// SHADER_SAMPLER6 Flashlight Cookie +// SHADER_SAMPLER7 Specular exponent +// SHADER_SAMPLER8 Cubic environment map +// SHADER_SAMPLER9 Compressed wrinklemap +// SHADER_SAMPLER10 Stretched wrinklemap +// SHADER_SAMPLER11 Compressed wrinkle normal map +// SHADER_SAMPLER12 Stretched wrinkle normal map +// SHADER_SAMPLER13 Detail texture + + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // No texture means no env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map + bool bBump = (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined(); + bool bEnvMap = (info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsDefined(); + bool bDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined(); + bool bPhong = (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined(); + if( bBump || bEnvMap || bDiffuseWarp || bPhong ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + if ( ( info.m_nSelfIllumFresnel != -1 ) && ( !params[info.m_nSelfIllumFresnel]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnel]->SetIntValue( 0 ); + } + + if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f ); + } + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) ) + { + params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 ); + } + + if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) ) + { + params[info.m_nEnvmapFresnel]->SetFloatValue( 0 ); + } + +#ifdef MAPBASE + InitIntParam( info.m_nPhongDisableHalfLambert, params, 0 ); +#endif +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitGeneric_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + + if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) && + params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nWrinkle, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nStretch, TEXTUREFLAGS_SRGB ); + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongExponentTexture ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongWarpTexture ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) // Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + + if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) && + params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nNormalWrinkle ); + pShader->LoadTexture( info.m_nNormalStretch ); + } + } + } + + if ( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + +#ifdef MAPBASE + // This is crashing for currently unknown reasons. + // As a result, $envmapmask support is not yet functional. + /* + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + */ +#endif + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CSkin_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawSkin_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bHasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture(); + + bool bHasBaseTextureWrinkle = bHasBaseTexture && + (info.m_nWrinkle != -1) && params[info.m_nWrinkle]->IsTexture() && + (info.m_nStretch != -1) && params[info.m_nStretch]->IsTexture(); + + bool bHasBumpWrinkle = bHasBump && + (info.m_nNormalWrinkle != -1) && params[info.m_nNormalWrinkle]->IsTexture() && + (info.m_nNormalStretch != -1) && params[info.m_nNormalStretch]->IsTexture(); + + bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) != 0; + bool bHasSelfIllumFresnel = ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + bool bHasSelfIllumMask = ( bHasSelfIllum ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsTexture(); + + // Tie these to specular + bool bHasPhong = (info.m_nPhong != -1) && ( params[info.m_nPhong]->GetIntValue() != 0 ); + bool bHasSpecularExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture(); + bool bHasPhongTintMap = bHasSpecularExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 ); + bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + bool bHasPhongWarp = (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsTexture(); + bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + +#ifdef MAPBASE + bool bHasEnvmapMask = (!bHasFlashlight || IsX360()) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); +#endif + +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + // Rimlight must be set to non-zero to trigger rim light combo (also requires Phong) + bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 ); + bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 ); + + float fBlendFactor=( info.m_nDetailTextureBlendFactor == -1 )? 1 : params[info.m_nDetailTextureBlendFactor]->GetFloatValue(); + bool hasDetailTexture = ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsTexture(); + int nDetailBlendMode = ( hasDetailTexture && info.m_nDetailTextureCombineMode != -1 ) ? params[info.m_nDetailTextureCombineMode]->GetIntValue() : 0; + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) && !bHasSelfIllum; // Pixel shader can't do both BLENDTINTBYBASEALPHA and SELFILLUM, so let selfillum win + + float flTintReplacementAmount = GetFloatParam( info.m_nTintReplacesBaseColor, params ); + +#ifdef MAPBASE + // This option was ported from Alien Swarm for Source 2013's "skin shader" implementation. + // Original comment from Alien Swarm SDK: + // "This is to allow phong materials to disable half lambert. Half lambert has always been forced on in phong, + // so the only safe way to allow artists to disable half lambert is to create this param that disables the + // default behavior of forcing half lambert on." + bool bPhongHalfLambert = IS_PARAM_DEFINED( info.m_nPhongDisableHalfLambert ) ? (params[info.m_nPhongDisableHalfLambert]->GetIntValue() == 0) : true; +#endif + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true ); + + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && !bHasFlashlight; //dest alpha is free for special use + + CSkin_DX9_Context *pContextData = reinterpret_cast< CSkin_DX9_Context *> ( *pContextDataPtr ); + if ( ! pContextData ) + { + pContextData = new CSkin_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + bool bHasNormal = params[info.m_nBumpmap]->IsTexture(); + bool bCanUseBaseAlphaPhongMaskFastPath = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + + if ( ! ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) ) + bCanUseBaseAlphaPhongMaskFastPath = true; + + pContextData->m_bFastPath = + (! bHasBump ) && + (! bHasSpecularExponentTexture ) && + (! bHasPhongTintMap ) && + (! bHasPhongWarp ) && + (! bHasRimLight ) && + (! hasDetailTexture ) && + bCanUseBaseAlphaPhongMaskFastPath && + (! bHasSelfIllum ) && + (! bBlendTintByBaseAlpha ); + + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Cubic environment map + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + } + } + + unsigned int flags = VERTEX_POSITION; + if( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } + + int userDataSize = 0; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Base (albedo) compression map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Base (albedo) expansion map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true ); + } + + if( bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Diffuse warp texture + } + + if( bHasPhongWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Specular warp texture + } + + // Specular exponent map or dummy + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Specular exponent map + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + userDataSize = 4; // tangent S + } + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + userDataSize = 4; // tangent S + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal compression map + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Normal expansion map + } + + if ( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true ); + } + + if ( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + } + +#ifdef MAPBASE + if ( bHasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); + } +#endif + + if( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord, texcoord2 : decal hw morph delta + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + // The vertex shader uses the vertex id stream + if ( bFastVertexTextures ) + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_skin_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal && bFastVertexTextures ); + SET_STATIC_VERTEX_SHADER( sdk_skin_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_skin_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( PHONG_HALFLAMBERT, bPhongHalfLambert ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_skin_ps30 ); + // SETDETAILBLENDMODE + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + else // not snapshotting -- begin dynamic state + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + + if( bHasBaseTexture ) + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nWrinkle, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nStretch, info.m_nBaseTextureFrame ); + } + else if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + + if( bHasDiffuseWarp && bHasPhong ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nDiffuseWarpTexture ); + } + } + + if( bHasPhongWarp ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nPhongWarpTexture ); + } + + if( bHasSpecularExponentTexture && bHasPhong ) + { + pShader->BindTexture( SHADER_SAMPLER7, info.m_nPhongExponentTexture ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_WHITE ); + } + + if( !g_pConfig->m_bFastNoBump ) + { + if( bHasBump ) + pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + else + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + + if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nNormalWrinkle, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nNormalStretch, info.m_nBumpFrame ); + } + else if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nBumpmap, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + if( bHasBump ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER11, TEXTURE_NORMALMAP_FLAT ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER12, TEXTURE_NORMALMAP_FLAT ); + } + } + +#ifdef MAPBASE + if ( bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } +#endif + + if ( hasDetailTexture ) + { + pShader->BindTexture( SHADER_SAMPLER13, info.m_nDetail, info.m_nDetailFrame ); + } + + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pShader->BindTexture( SHADER_SAMPLER14, info.m_nSelfIllumMask ); // Bind it + } + else // else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER14, TEXTURE_BLACK ); // Bind dummy + } + } + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + if ( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER8, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + //int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + // don't have an easy way to get this through to GLM, so just print it old school + //printf("\n-D- DrawSkin_DX9_Internal numBones is %d", numBones ); + + bool bWriteDepthToAlpha = false; + bool bWriteWaterFogToAlpha = false; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + if ( bFastVertexTextures ) + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_skin_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_skin_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_skin_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_skin_ps30 ); + + // SETNUMLIGHTS + + if ( bFastVertexTextures ) + { + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + +#ifdef MAPBASE + // The original code makes it seem like we have the opportunity to support both $bumptransform and $detail at the same time, + // and that may or may not have been Valve's intention, but we'd need to add another texcoord for this and it's already + // a limitation with the non-skin shader anyway. + if ( bHasBump ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform ); + } + else +#else + if( bHasBump ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } +#endif + + if ( hasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nDetailTextureTransform, + info.m_nDetailScale ); + else + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nBaseTextureTransform, + info.m_nDetailScale ); + } + + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetPixelShaderConstant_W( PSREG_SELFILLUMTINT, info.m_nSelfIllumTint, fBlendFactor ); + bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 ); + float fInvertPhongMask = bInvertPhongMask ? 1 : 0; + + bool bHasBaseAlphaPhongMask = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + float fHasBaseAlphaPhongMask = bHasBaseAlphaPhongMask ? 1 : 0; + // Controls for lerp-style paths through shader code + + const float flMinLighting = pShaderAPI->GetFloatRenderingParameter( FLOAT_RENDERPARM_MINIMUMLIGHTING ); + + float vShaderControls[4] = { fHasBaseAlphaPhongMask, flMinLighting, flTintReplacementAmount, fInvertPhongMask }; + pShaderAPI->SetPixelShaderConstant( PSREG_CONSTANT_27, vShaderControls, 1 ); + + float vDetailBlendMode_NumLights[4]; + if ( hasDetailTexture ) + { + vDetailBlendMode_NumLights[0] = nDetailBlendMode; + } + + vDetailBlendMode_NumLights[1] = lightState.m_nNumLights; + pShaderAPI->SetPixelShaderConstant( 32, vDetailBlendMode_NumLights, 1 ); + + if ( bHasSelfIllumFresnel && !bHasFlashlight ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pShaderAPI->SetPixelShaderConstant( PSREG_SELFILLUM_SCALE_BIAS_EXP, vConstScaleBiasExp, 1 ); + } + + pShader->SetAmbientCubeDynamicStateVertexShader(); + + if( !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Setting .x to 1 means to apply Fresnel to env map. Setting w to 1 means use separate selfillummask + float vEnvMapFresnel_SelfIllumMask[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + vEnvMapFresnel_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + + if( bHasEnvmap ) + { + float vEnvMapTint_MaskControl[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + + // If we have a tint, grab it + if ( (info.m_nEnvmapTint != -1) && params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->GetVecValue(vEnvMapTint_MaskControl, 3); + + // Set control for source of env map mask (normal alpha or base alpha) + vEnvMapTint_MaskControl[3] = bHasNormalMapAlphaEnvmapMask ? 1.0f : 0.0f; + + if ( (info.m_nEnvmapFresnel != -1) && params[info.m_nEnvmapFresnel]->IsDefined() ) + vEnvMapFresnel_SelfIllumMask[0] = params[info.m_nEnvmapFresnel]->GetFloatValue(); + + // Handle mat_fullbright 2 (diffuse lighting only with 50% gamma space basetexture) + if( bLightingOnly ) + { + vEnvMapTint_MaskControl[0] = vEnvMapTint_MaskControl[1] = vEnvMapTint_MaskControl[2] = 0.0f; + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, vEnvMapTint_MaskControl, 1 ); + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK, vEnvMapFresnel_SelfIllumMask, 1 ); + } + + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + // Pack Phong exponent in with the eye position + float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {1, 0.5, 1, 1}, vRimBoost[4] = {1, 1, 1, 1}; + float vSpecularTint[4] = {1, 1, 1, 4}; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + + // Use the alpha channel of the normal map for the exponent by default + vEyePos_SpecExponent[3] = -1.f; + if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() ) + { + float fValue = params[info.m_nPhongExponent]->GetFloatValue(); + if ( fValue > 0.f ) + { + // Nonzero value in material overrides map channel + vEyePos_SpecExponent[3] = fValue; + } + } + + // Get the tint parameter + if ( (info.m_nPhongTint != -1) && params[info.m_nPhongTint]->IsDefined() ) + { + params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 3); + } + + // Get the rim light power (goes in w of Phong tint) + if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() ) + { + vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue(); + vSpecularTint[3] = MAX(vSpecularTint[3], 1.0f); // Make sure this is at least 1 + } + + // Get the rim boost (goes in w of flashlight position) + if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() ) + { + vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue(); + } + + if ( !bHasFlashlight ) + { + float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code + vRimMaskControl[0] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f; + + // Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 ); + } + + // If it's all zeros, there was no constant tint in the vmt + if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) ) + { + if ( bHasPhongTintMap ) // If we have a map to use, tell the shader + { + vSpecularTint[0] = -1; + } + else // Otherwise, just tint with white + { + vSpecularTint[0] = 1.0f; + vSpecularTint[1] = 1.0f; + vSpecularTint[2] = 1.0f; + } + } + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + // BASETEXTURE + if( bHasSelfIllum && !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // DETAILTEXTURE + if ( hasDetailTexture ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER13, TEXTURE_GREY ); + } + + // turn off specularity + vSpecularTint[0] = vSpecularTint[1] = vSpecularTint[2] = 0.0f; + } + + if ( (info.m_nPhongFresnelRanges != -1) && params[info.m_nPhongFresnelRanges]->IsDefined() ) + { + params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters + // Change fresnel range encoding from (min, mid, max) to ((mid-min)*2, mid, (max-mid)*2) + vFresnelRanges_SpecBoost[0] = (vFresnelRanges_SpecBoost[1] - vFresnelRanges_SpecBoost[0]) * 2; + vFresnelRanges_SpecBoost[2] = (vFresnelRanges_SpecBoost[2] - vFresnelRanges_SpecBoost[1]) * 2; + } + + if ( (info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined()) // Grab optional Phong boost param + vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue(); + else + vFresnelRanges_SpecBoost[3] = 1.0f; + + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass + + pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 ); + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + // flashlightfixme: put this in common code. + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + //ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" ); + + bool bHasFlashlight = pShader->UsingFlashlight( params ); + //if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetBool() ) ) + //{ + // DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + // pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); + // if ( pShaderShadow ) + // { + // pShader->SetInitialShadowState( ); + // } + //} + DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/materialsystem/stdshaders/skin_helper.h b/materialsystem/stdshaders/skin_helper.h new file mode 100644 index 00000000..d90e61ab --- /dev/null +++ b/materialsystem/stdshaders/skin_helper.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef SKIN_DX9_HELPER_H +#define SKIN_DX9_HELPER_H + +#include + +#include "vertexlitgeneric_helper.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ); +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + VertexLitGeneric_DX9_Vars_t &info ); + +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ); + + + +#endif // SKIN_DX9_HELPER_H diff --git a/materialsystem/stdshaders/skin_ps20b.fxc b/materialsystem/stdshaders/skin_ps20b.fxc deleted file mode 100644 index 8d2e3204..00000000 --- a/materialsystem/stdshaders/skin_ps20b.fxc +++ /dev/null @@ -1,381 +0,0 @@ -//======= Copyright 1996-2007, Valve Corporation, All rights reserved. ====== -// STATIC: "CONVERT_TO_SRGB" "0..0" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "SELFILLUMFRESNEL" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "LIGHTWARPTEXTURE" "0..1" -// STATIC: "PHONGWARPTEXTURE" "0..1" -// STATIC: "WRINKLEMAP" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..6" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "RIMLIGHT" "0..1" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] -// STATIC: "FASTPATH_NOBUMP" "0..1" -// STATIC: "BLENDTINTBYBASEALPHA" "0..1" - -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..4" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] -// DYNAMIC: "PHONG_USE_EXPONENT_FACTOR" "0..0" [ps20] -// DYNAMIC: "PHONG_USE_EXPONENT_FACTOR" "0..1" [ps20b] [ps30] [PC] - - -// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) - -// blend mode doesn't matter if we only have one texture -// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] - -// Only need self illum fresnel when self illum enabled -// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) - -// BlendTintByBaseAlpha and self illum and are opposing meanings for alpha channel -// SKIP: ( $BLENDTINTBYBASEALPHA ) && ( $SELFILLUM ) - -// fastpath means: -// no bumpmap -// basealphaenvmapmask (not inverted) -// no spec expmap -// no spectint -// no specwarp -// no rimlight -// no selfillum -// no detail -// no BlendTintByBaseAlpha - -// SKIP: $FASTPATH_NOBUMP && ( $RIMLIGHT || $DETAILTEXTURE || $PHONGWARPTEXTURE || $SELFILLUM || $BLENDTINTBYBASEALPHA ) - - - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" - -const float4 g_SelfIllumTint_and_DetailBlendFactor : register( PSREG_SELFILLUMTINT ); -#if ( SELFILLUMFRESNEL == 1 ) -const float4 g_SelfIllumScaleBiasExpBrightness : register( PSREG_SELFILLUM_SCALE_BIAS_EXP ); -#endif -const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); -const float4 g_EnvmapTint_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); // w controls spec mask -const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); -const float4 g_EnvMapFresnel : register( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK ); // x is envmap fresnel ... w is selfillummask control -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_FlashlightAttenuationFactors_RimMask : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass, x has rim mask control -const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); -#if FLASHLIGHT - const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); -#endif -const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); // xyz are fresnel, w is specular boost -const float4 g_SpecularRimParams : register( PSREG_SPEC_RIM_PARAMS ); // xyz are specular tint color, w is rim power -PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) - -// TODO: give this a better name. For now, I don't want to touch shader_constant_register_map.h since I don't want to trigger a recompile of everything... -const float4 g_ShaderControls : register( PSREG_CONSTANT_27 ); // x is basemap alpgha phong mask, y is 1 - blendtintbybasealpha, z is tint overlay amount, w controls "INVERTPHONGMASK" -#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz -#define g_fRimBoost g_FlashlightPos_RimBoost.w -#define g_FresnelRanges g_FresnelSpecParams.xyz -#define g_SpecularBoost g_FresnelSpecParams.w -#define g_SpecularTint g_SpecularRimParams.xyz -#define g_RimExponent g_SpecularRimParams.w -#define g_FlashlightAttenuationFactors g_FlashlightAttenuationFactors_RimMask -#define g_RimMaskControl g_FlashlightAttenuationFactors_RimMask.x -#define g_SelfIllumMaskControl g_EnvMapFresnel.w -#define g_fBaseMapAlphaPhongMask g_ShaderControls.x -#define g_fTintReplacementControl g_ShaderControls.z -#define g_fInvertPhongMask g_ShaderControls.w - - -sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha -sampler SpecularWarpSampler : register( s1 ); // Specular warp sampler (for iridescence etc) -sampler DiffuseWarpSampler : register( s2 ); // Lighting warp sampler (1D texture for diffuse lighting modification) -sampler NormalMapSampler : register( s3 ); // Normal map, specular mask in alpha -sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler -sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers -sampler FlashlightSampler : register( s6 ); // Flashlight cookie -sampler SpecExponentSampler : register( s7 ); // Specular exponent map -sampler EnvmapSampler : register( s8 ); // Cubic environment map - -#if WRINKLEMAP -sampler WrinkleSampler : register( s9 ); // Compression base -sampler StretchSampler : register( s10 ); // Expansion base -sampler NormalWrinkleSampler : register( s11 ); // Compression base -sampler NormalStretchSampler : register( s12 ); // Expansion base -#endif - -#if DETAILTEXTURE -sampler DetailSampler : register( s13 ); // detail texture -#endif - -sampler SelfIllumMaskSampler : register( s14 ); // selfillummask - -struct PS_INPUT -{ - float4 baseTexCoordDetailTexCoord : TEXCOORD0; // xy=base zw=detail - float3 lightAtten : TEXCOORD1; // Scalar light attenuation factors for FOUR lights - float3 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; - float3x3 tangentSpaceTranspose : TEXCOORD3; - // second row : TEXCOORD4; - // third row : TEXCOORD5; - float4 worldPos_atten3 : TEXCOORD6; - float4 projPos_fWrinkleWeight : TEXCOORD7; -}; - - - -float4 main( PS_INPUT i ) : COLOR -{ - bool bWrinkleMap = WRINKLEMAP ? true : false; - bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; - bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false; - bool bDoAmbientOcclusion = false; - bool bFlashlight = (FLASHLIGHT!=0) ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bDoRimLighting = RIMLIGHT ? true : false; - bool bCubemap = CUBEMAP ? true : false; - bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; - int nNumLights = NUM_LIGHTS; - - // Unpacking for convenience - float fWrinkleWeight = i.projPos_fWrinkleWeight.w; - float3 vProjPos = i.projPos_fWrinkleWeight.xyz; - float3 vWorldPos = i.worldPos_atten3.xyz; - float atten3 = i.worldPos_atten3.w; - - float4 vLightAtten = float4( i.lightAtten, atten3 ); - -#if WRINKLEMAP - float flWrinkleAmount = saturate( -fWrinkleWeight ); // One of these two is zero - float flStretchAmount = saturate( fWrinkleWeight ); // while the other is in the 0..1 range - - float flTextureAmount = 1.0f - flWrinkleAmount - flStretchAmount; // These should sum to one -#endif - - float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoordDetailTexCoord.xy ); -#if WRINKLEMAP - float4 wrinkleColor = tex2D( WrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); - float4 stretchColor = tex2D( StretchSampler, i.baseTexCoordDetailTexCoord.xy ); - - // Apply wrinkle blend to only RGB. Alpha comes from the base texture - baseColor.rgb = flTextureAmount * baseColor + flWrinkleAmount * wrinkleColor + flStretchAmount * stretchColor; -#endif - -#if DETAILTEXTURE - float4 detailColor = tex2D( DetailSampler, i.baseTexCoordDetailTexCoord.zw ); - baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); -#endif - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, vWorldPos.z, vProjPos.z ); - - float3 vEyeDir = normalize(i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz); - float3 vRimAmbientCubeColor = PixelShaderAmbientLight(vEyeDir, cAmbientCube); - - float3 worldSpaceNormal, tangentSpaceNormal; - float fSpecMask = 1.0f; - float4 normalTexel = tex2D( NormalMapSampler, i.baseTexCoordDetailTexCoord.xy ); - -#if WRINKLEMAP - float4 wrinkleNormal = tex2D( NormalWrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); - float4 stretchNormal = tex2D( NormalStretchSampler, i.baseTexCoordDetailTexCoord.xy ); - normalTexel = flTextureAmount * normalTexel + flWrinkleAmount * wrinkleNormal + flStretchAmount * stretchNormal; -#endif - -#if (FASTPATH_NOBUMP == 0 ) - tangentSpaceNormal = lerp( 2.0f * normalTexel.xyz - 1.0f, float3(0, 0, 1), g_fBaseMapAlphaPhongMask ); - fSpecMask = lerp( normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask ); -#else - tangentSpaceNormal = float3(0, 0, 1); - fSpecMask = baseColor.a; -#endif - - // We need a normal if we're doing any lighting - worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); - - float fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges ); - float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir ); - - // Break down reflect so that we can share dot(worldSpaceNormal,vEyeDir) with fresnel terms - float3 vReflect = 2 * worldSpaceNormal * dot(worldSpaceNormal, vEyeDir) - vEyeDir; - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - float3 envMapColor = float3( 0.0f, 0.0f, 0.0f ); - if( !bFlashlight ) - { - // Summation of diffuse illumination from all local lights - diffuseLighting = PixelShaderDoLighting( vWorldPos, worldSpaceNormal, - float3( 0.0f, 0.0f, 0.0f ), false, true, vLightAtten, - cAmbientCube, NormalizeRandRotSampler, nNumLights, cLightInfo, true, - - // These parameters aren't passed by generic shaders: - false, 1.0f, - bDoDiffuseWarp, DiffuseWarpSampler ); - - if( bCubemap ) - { - // Mask is either normal map alpha or base map alpha -#if ( SELFILLUMFRESNEL == 1 ) // This is to match the 2.0 version of vertexlitgeneric - float fEnvMapMask = lerp( baseColor.a, g_fInvertPhongMask, g_EnvmapTint_ShadowTweaks.w ); -#else - float fEnvMapMask = lerp( baseColor.a, fSpecMask, g_EnvmapTint_ShadowTweaks.w ); -#endif - - envMapColor = (ENV_MAP_SCALE * - lerp(1, fFresnelRanges, g_EnvMapFresnel.x) * - lerp(fEnvMapMask, 1-fEnvMapMask, g_fInvertPhongMask)) * - texCUBE( EnvmapSampler, vReflect ) * - g_EnvmapTint_ShadowTweaks.xyz; - } - } - - float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); - float3 rimLighting = float3( 0.0f, 0.0f, 0.0f ); - - float3 vSpecularTint = 1; - float fRimMask = 0; - float fSpecExp = 1; - -#if ( FASTPATH_NOBUMP == 0 ) - float4 vSpecExpMap = tex2D( SpecExponentSampler, i.baseTexCoordDetailTexCoord.xy ); - - if ( !bFlashlight ) - { - fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); // Select rim mask - } - - // If the exponent passed in as a constant is zero, use the value from the map as the exponent -#if defined( _X360 ) - [flatten] -#endif - -#if ( PHONG_USE_EXPONENT_FACTOR ) - fSpecExp = ( 1.0f + g_EyePos_SpecExponent.w * vSpecExpMap.r ); -#else - fSpecExp = (g_EyePos_SpecExponent.w >= 0.0) ? g_EyePos_SpecExponent.w : (1.0f + 149.0f * vSpecExpMap.r); -#endif - - // If constant tint is negative, tint with albedo, based upon scalar tint map -#if defined( _X360 ) - [flatten] -#endif - vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g ); - vSpecularTint = (g_SpecularTint.r >= 0.0) ? g_SpecularTint.rgb : vSpecularTint; - -#else - fSpecExp = max(g_EyePos_SpecExponent.w, 0); -#endif - - float3 albedo = baseColor.rgb; - - if ( !bFlashlight ) - { - // Summation of specular from all local lights besides the flashlight - PixelShaderDoSpecularLighting( vWorldPos, worldSpaceNormal, - fSpecExp, vEyeDir, vLightAtten, - nNumLights, cLightInfo, false, 1.0f, bDoSpecularWarp, - SpecularWarpSampler, fFresnelRanges, bDoRimLighting, g_RimExponent, - - // Outputs - specularLighting, rimLighting ); - } - else - { - #if FLASHLIGHT - float4 flashlightSpacePosition = mul( float4( vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); - - DoSpecularFlashlight( g_FlashlightPos, vWorldPos, flashlightSpacePosition, worldSpaceNormal, - g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, - FlashlightSampler, ShadowDepthSampler, NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, vProjPos.xy / vProjPos.z, - fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpSampler, fFresnelRanges, g_EnvmapTint_ShadowTweaks, - - // These two values are output - diffuseLighting, specularLighting ); - #endif - } - - // If we didn't already apply Fresnel to specular warp, modulate the specular - if ( !bDoSpecularWarp ) - fSpecMask *= fFresnelRanges; - - // Modulate with spec mask, boost and tint - specularLighting *= fSpecMask * g_SpecularBoost; - - if (bBlendTintByBaseAlpha) - { - float3 tintedColor = albedo * g_DiffuseModulation.rgb; - tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_fTintReplacementControl); - albedo = lerp(albedo, tintedColor, baseColor.a); - } - else - { - albedo = albedo * g_DiffuseModulation.rgb; - } - - - float3 diffuseComponent = albedo * diffuseLighting; - if ( bSelfIllum && !bFlashlight ) - { -#if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file - // This will apply a Fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look - float3 vVertexNormal = normalize( float3( i.tangentSpaceTranspose[0].z, i.tangentSpaceTranspose[1].z, i.tangentSpaceTranspose[2].z ) ); - float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, vEyeDir.xyz ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; - diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo * g_SelfIllumScaleBiasExpBrightness.w, baseColor.a * saturate( flSelfIllumFresnel ) ); -#else - float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy ); - vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); - diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo, vSelfIllumMask ); -#endif - - diffuseComponent = max( 0.0f, diffuseComponent ); - } - -#if DETAILTEXTURE - diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, - DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); -#endif - - if ( bDoRimLighting && !bFlashlight ) - { - float fRimMultiply = fRimMask * fRimFresnel; // both unit range: [0, 1] - - // Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges) - rimLighting *= fRimMultiply; - - // Fold rim lighting into specular term by using the max so that we don't really add light twice... - specularLighting = max( specularLighting, rimLighting ); - - // Add in view-ray lookup from ambient cube - specularLighting += (vRimAmbientCubeColor * g_fRimBoost) * saturate(fRimMultiply * worldSpaceNormal.z); - } - - float3 result = specularLighting*vSpecularTint + envMapColor + diffuseComponent; - -#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) - float alpha = fogFactor; -#else - float alpha = g_DiffuseModulation.a; - if ( !bSelfIllum && !bBlendTintByBaseAlpha ) - { - alpha = lerp( baseColor.a * alpha, alpha, g_fBaseMapAlphaPhongMask ); - } -#endif - - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - - //FIXME: need to take dowaterfog into consideration - return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, vProjPos.z ); -} diff --git a/materialsystem/stdshaders/skin_vs20.fxc b/materialsystem/stdshaders/skin_vs20.fxc deleted file mode 100644 index 9b04b7aa..00000000 --- a/materialsystem/stdshaders/skin_vs20.fxc +++ /dev/null @@ -1,173 +0,0 @@ -//======= Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ====== - -// STATIC: "DECAL" "0..1" [vs30] -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - - -//----------------------------------------------------------------------------- -// Input vertex format -//----------------------------------------------------------------------------- -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vColor : COLOR0; - float3 vSpecular : COLOR1; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; - float4 vTexCoord2 : TEXCOORD2; - float4 vTexCoord3 : TEXCOORD3; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; - float4 vUserData : TANGENT; - - // Position and normal/tangent deltas - float4 vPosFlex : POSITION1; - float4 vNormalFlex : NORMAL1; - -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - // Stuff that isn't seen by the pixel shader - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - // Stuff that is seen by the pixel shader - float4 baseTexCoord : TEXCOORD0; // includes detail tex coord - float3 lightAtten : TEXCOORD1; - float3 worldVertToEyeVector : TEXCOORD2; - float3x3 tangentSpaceTranspose : TEXCOORD3; - // second row : TEXCOORD4; - // third row : TEXCOORD5; - float4 worldPos_atten3 : TEXCOORD6; - float4 projPos_fWrinkleWeight : TEXCOORD7; -}; - -//----------------------------------------------------------------------------- -// Main shader entry point -//----------------------------------------------------------------------------- -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - float4 vTangent; - DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, - vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, v.vTexCoord2, - vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); -#endif - - // Perform skinning - float3 worldNormal, worldPos, worldTangentS, worldTangentT; - SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, - v.vBoneWeights, v.vBoneIndices, worldPos, - worldNormal, worldTangentS, worldTangentT ); - - // Always normalize since flex path is controlled by runtime - // constant not a shader combo and will always generate the normalization - worldNormal = normalize( worldNormal ); - worldTangentS = normalize( worldTangentS ); - worldTangentT = normalize( worldTangentT ); - -#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL - // Avoid z precision errors - worldPos += worldNormal * 0.05f * v.vTexCoord2.z; -#endif - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.projPos_fWrinkleWeight.xyz = vProjPos.xyz; - -#if !defined( _X360 ) - o.fog = CalcFog( worldPos, vProjPos.xyz, g_FogType ); -#endif - // Needed for water fog alpha and diffuse lighting - // FIXME: we shouldn't have to compute this all the time. - o.worldPos_atten3.xyz = worldPos; - - // Needed for specular - o.worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); - - // Compute bumped lighting - // FIXME: We shouldn't have to compute this for unlit materials -#if defined ( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) - o.lightAtten.xyz = float3(0,0,0); - o.worldPos_atten3.w = 0.0f; - #if ( NUM_LIGHTS > 0 ) - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); - #endif - #if ( NUM_LIGHTS > 1 ) - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); - #endif - #if ( NUM_LIGHTS > 2 ) - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); - #endif - #if ( NUM_LIGHTS > 3 ) - o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, false ); - #endif -#else - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); - o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, true ); -#endif - - // Base texture coordinate transform - o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - o.baseTexCoord.z = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); - o.baseTexCoord.w = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); - - // Tangent space transform - o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); - o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); - o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); - - return o; -} diff --git a/materialsystem/stdshaders/sky.cpp b/materialsystem/stdshaders/sky.cpp new file mode 100644 index 00000000..94435917 --- /dev/null +++ b/materialsystem/stdshaders/sky.cpp @@ -0,0 +1,126 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "basevsshader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" + +#include "convar.h" + +BEGIN_VS_SHADER( Sky_DX9, "Help for Sky_DX9 shader" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "sky_dx6"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + ImageFormat fmt = params[BASETEXTURE]->GetTextureValue()->GetImageFormat(); + LoadTexture( BASETEXTURE, (fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616) ? 0 : TEXTUREFLAGS_SRGB ); + } + } + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + pShaderAPI->SetPixelShaderConstant(0,c0,1); + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + Draw( ); + } + +END_SHADER + diff --git a/materialsystem/stdshaders/sky_dx6.cpp b/materialsystem/stdshaders/sky_dx6.cpp deleted file mode 100644 index 15bdc553..00000000 --- a/materialsystem/stdshaders/sky_dx6.cpp +++ /dev/null @@ -1,15 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Teeth renderer -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Sky, UnlitGeneric ) -DEFINE_FALLBACK_SHADER( Sky_dx6, UnlitGeneric ) - diff --git a/materialsystem/stdshaders/sky_dx9.cpp b/materialsystem/stdshaders/sky_dx9.cpp deleted file mode 100644 index 93eb6115..00000000 --- a/materialsystem/stdshaders/sky_dx9.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// -#include "BaseVSShader.h" -#include "sky_vs20.inc" -#include "sky_ps20.inc" -#include "sky_ps20b.inc" - -#include "convar.h" - -BEGIN_VS_SHADER( Sky_DX9, "Help for Sky_DX9 shader" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) - SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "sky_dx6"; - } - return 0; - } - - SHADER_INIT_PARAMS() - { - SET_FLAGS( MATERIAL_VAR_NOFOG ); - SET_FLAGS( MATERIAL_VAR_IGNOREZ ); - } - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - { - ImageFormat fmt = params[BASETEXTURE]->GetTextureValue()->GetImageFormat(); - LoadTexture( BASETEXTURE, (fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616) ? 0 : TEXTUREFLAGS_SRGB ); - } - } - SHADER_DRAW - { - SHADOW_STATE - { - SetInitialShadowState(); - -// pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); - SET_STATIC_VERTEX_SHADER( sky_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); - SET_STATIC_PIXEL_SHADER( sky_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); - SET_STATIC_PIXEL_SHADER( sky_ps20 ); - } - // we are writing linear values from this shader. - pShaderShadow->EnableSRGBWrite( true ); - - pShaderShadow->EnableAlphaWrites( true ); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - float c1[4]={0,0,0,0}; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); - - float c0[4]={1,1,1,1}; - if (params[COLOR]->IsDefined()) - { - memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); - } - ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ( - (fmt==IMAGE_FORMAT_RGBA16161616) || - ( (fmt==IMAGE_FORMAT_RGBA16161616F) && - (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) - ) - { - c0[0]*=16.0; - c0[1]*=16.0; - c0[2]*=16.0; - } - pShaderAPI->SetPixelShaderConstant(0,c0,1); - DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); - - // Texture coord transform - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); - } - } - Draw( ); - } - -END_SHADER - diff --git a/materialsystem/stdshaders/sky_hdr.cpp b/materialsystem/stdshaders/sky_hdr.cpp new file mode 100644 index 00000000..4a3462b9 --- /dev/null +++ b/materialsystem/stdshaders/sky_hdr.cpp @@ -0,0 +1,297 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "basevsshader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" +#include "sky_hdr_compressed_ps20.inc" +#include "sky_hdr_compressed_ps20b.inc" +#include "sky_hdr_compressed_rgbs_ps20.inc" +#include "sky_hdr_compressed_rgbs_ps20b.inc" + +#include "convar.h" + +static ConVar mat_use_compressed_hdr_textures( "mat_use_compressed_hdr_textures", "1" ); + +DEFINE_FALLBACK_SHADER( Sky, Sky_HDR_DX9 ) + +BEGIN_VS_SHADER( Sky_HDR_DX9, "Help for Sky_HDR_DX9 shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( HDRBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture when running with HDR enabled" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture (compressed) for hdr compression method A" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture0 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture1 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture2 for hdr compression method B" ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "Sky_DX9"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + // First figure out if sampler zero wants to be sRGB + int nSamplerZeroFlags = 0; + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && mat_use_compressed_hdr_textures.GetBool() ) + { + nSamplerZeroFlags = 0; + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + nSamplerZeroFlags = 0; + } + else + { + nSamplerZeroFlags = TEXTUREFLAGS_SRGB; + + if ( params[HDRBASETEXTURE]->IsDefined() && params[HDRBASETEXTURE]->IsTexture() ) + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( ( fmt == IMAGE_FORMAT_RGBA16161616F ) || ( fmt == IMAGE_FORMAT_RGBA16161616 ) ) + { + nSamplerZeroFlags = 0; + } + } + } + } + + // Next, figure out which texture will be on sampler zero + int nSampler0 = HDRCOMPRESSEDTEXTURE; + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && mat_use_compressed_hdr_textures.GetBool() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE; + } + else + { + if ( params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE0; + } + else + { + nSampler0 = HDRBASETEXTURE; + } + } + + // Load the appropriate textures, making sure that the texture set on sampler 0 is sRGB if necessary + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && (mat_use_compressed_hdr_textures.GetBool() ) ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE, HDRCOMPRESSEDTEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE0, HDRCOMPRESSEDTEXTURE0 == nSampler0 ? nSamplerZeroFlags : 0 ); + if ( params[HDRCOMPRESSEDTEXTURE1]->IsDefined() ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE1, HDRCOMPRESSEDTEXTURE1 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + if ( params[HDRCOMPRESSEDTEXTURE2]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE2, HDRCOMPRESSEDTEXTURE2 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + else + { + if ( params[HDRBASETEXTURE]->IsDefined() ) + { + LoadTexture( HDRBASETEXTURE, HDRBASETEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && + mat_use_compressed_hdr_textures.GetBool() ) + { + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + } + else + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + if ( + params[HDRCOMPRESSEDTEXTURE]->IsDefined() && + mat_use_compressed_hdr_textures.GetBool() + ) + { + // set up data needs for pixel shader interpolation + ITexture *txtr=params[HDRCOMPRESSEDTEXTURE]->GetTextureValue(); + float w=txtr->GetActualWidth(); + float h=txtr->GetActualHeight(); + float FUDGE=0.01/MAX(w,h); // per ATI + float c1[4]={0.5/w-FUDGE, 0.5/h-FUDGE, w, h }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); + c0[0]*=8.0; + c0[1]*=8.0; + c0[2]*=8.0; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE0, FRAME ); + BindTexture( SHADER_SAMPLER1, HDRCOMPRESSEDTEXTURE1, FRAME ); + BindTexture( SHADER_SAMPLER2, HDRCOMPRESSEDTEXTURE2, FRAME ); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + + } + else + { + BindTexture( SHADER_SAMPLER0, HDRBASETEXTURE, FRAME ); + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + } + Draw( ); + } +END_SHADER diff --git a/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc b/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc deleted file mode 100644 index 8e54d21f..00000000 --- a/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc +++ /dev/null @@ -1,29 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -#include "common_ps_fxc.h" - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -sampler ExposureTextureSampler0 : register( s0 ); -sampler ExposureTextureSampler1 : register( s1 ); -sampler ExposureTextureSampler2 : register( s2 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - HALF3 color0 = 0.25*tex2D( ExposureTextureSampler0, i.baseTexCoord ); - HALF3 color1 = 2.0*tex2D( ExposureTextureSampler1, i.baseTexCoord ); - HALF3 color2 = 16.0*tex2D( ExposureTextureSampler2, i.baseTexCoord ); - - // This is never fogged. -// return FinalOutput( float4( max(max(color0,color1),color2), 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate - return FinalOutput( float4(1,0,0,1 ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate -} diff --git a/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc b/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc deleted file mode 100644 index 4871da56..00000000 --- a/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc +++ /dev/null @@ -1,81 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -#include "common_ps_fxc.h" - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -sampler RGBSTextureSampler : register( s0 ); -HALF4 InputScale : register( c0 ); - -float2 texWidthHeight : register( c1 ); - -float4 texOffsets : register( c2 ); - -struct PS_INPUT -{ -//#if defined( _X360 ) -// float2 baseTexCoord : TEXCOORD0; -//#else - float2 baseTexCoord00 : TEXCOORD0; - float2 baseTexCoord01 : TEXCOORD1; - float2 baseTexCoord10 : TEXCOORD2; - float2 baseTexCoord11 : TEXCOORD3; - float2 baseTexCoord_In_Pixels: TEXCOORD4; -//#endif -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float3 result; - -//#if defined( _X360 ) //360 has a cheaper way to handle RGBscale -// float4 Weights; -// float4 samples_0; //no arrays allowed in inline assembly -// float4 samples_1; -// float4 samples_2; -// float4 samples_3; -// float2 vTexCoord = i.baseTexCoord; -// -// asm { -// tfetch2D samples_0, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false -// tfetch2D samples_1, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false -// tfetch2D samples_2, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false -// tfetch2D samples_3, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false -// -// getWeights2D Weights, vTexCoord.xy, RGBSTextureSampler -// }; -// -// Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); -// -// result.rgb = samples_0.rgb * (samples_0.a * Weights.x); -// result.rgb += samples_1.rgb * (samples_1.a * Weights.y); -// result.rgb += samples_2.rgb * (samples_2.a * Weights.z); -// result.rgb += samples_3.rgb * (samples_3.a * Weights.w); -// -//#else - float4 s00 = tex2D(RGBSTextureSampler, i.baseTexCoord00); - float4 s10 = tex2D(RGBSTextureSampler, i.baseTexCoord10); - float4 s01 = tex2D(RGBSTextureSampler, i.baseTexCoord01); - float4 s11 = tex2D(RGBSTextureSampler, i.baseTexCoord11); - - float2 fracCoord = frac(i.baseTexCoord_In_Pixels); - - s00.rgb*=s00.a; - s10.rgb*=s10.a; - - s00.xyz = lerp(s00, s10, fracCoord.x); - - s01.rgb*=s01.a; - s11.rgb*=s11.a; - s01.xyz = lerp(s01, s11, fracCoord.x); - - result = lerp(s00, s01, fracCoord.y); -//#endif - - // This is never fogged. - return FinalOutput( float4( InputScale*result, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate -} diff --git a/materialsystem/stdshaders/sky_hdr_dx9.cpp b/materialsystem/stdshaders/sky_hdr_dx9.cpp deleted file mode 100644 index 008f37e3..00000000 --- a/materialsystem/stdshaders/sky_hdr_dx9.cpp +++ /dev/null @@ -1,297 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// -#include "BaseVSShader.h" -#include "sky_vs20.inc" -#include "sky_ps20.inc" -#include "sky_ps20b.inc" -#include "sky_hdr_compressed_ps20.inc" -#include "sky_hdr_compressed_ps20b.inc" -#include "sky_hdr_compressed_rgbs_ps20.inc" -#include "sky_hdr_compressed_rgbs_ps20b.inc" - -#include "convar.h" - -static ConVar mat_use_compressed_hdr_textures( "mat_use_compressed_hdr_textures", "1" ); - -DEFINE_FALLBACK_SHADER( Sky, Sky_HDR_DX9 ) - -BEGIN_VS_SHADER( Sky_HDR_DX9, "Help for Sky_HDR_DX9 shader" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( HDRBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture when running with HDR enabled" ) - SHADER_PARAM( HDRCOMPRESSEDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture (compressed) for hdr compression method A" ) - SHADER_PARAM( HDRCOMPRESSEDTEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture0 for hdr compression method B" ) - SHADER_PARAM( HDRCOMPRESSEDTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture1 for hdr compression method B" ) - SHADER_PARAM( HDRCOMPRESSEDTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture2 for hdr compression method B" ) - SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - return "Sky_DX9"; - } - return 0; - } - - SHADER_INIT_PARAMS() - { - SET_FLAGS( MATERIAL_VAR_NOFOG ); - SET_FLAGS( MATERIAL_VAR_IGNOREZ ); - } - SHADER_INIT - { - // First figure out if sampler zero wants to be sRGB - int nSamplerZeroFlags = 0; - if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && mat_use_compressed_hdr_textures.GetBool() ) - { - nSamplerZeroFlags = 0; - } - else - { - if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) - { - nSamplerZeroFlags = 0; - } - else - { - nSamplerZeroFlags = TEXTUREFLAGS_SRGB; - - if ( params[HDRBASETEXTURE]->IsDefined() && params[HDRBASETEXTURE]->IsTexture() ) - { - ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ( ( fmt == IMAGE_FORMAT_RGBA16161616F ) || ( fmt == IMAGE_FORMAT_RGBA16161616 ) ) - { - nSamplerZeroFlags = 0; - } - } - } - } - - // Next, figure out which texture will be on sampler zero - int nSampler0 = HDRCOMPRESSEDTEXTURE; - if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && mat_use_compressed_hdr_textures.GetBool() ) - { - nSampler0 = HDRCOMPRESSEDTEXTURE; - } - else - { - if ( params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) - { - nSampler0 = HDRCOMPRESSEDTEXTURE0; - } - else - { - nSampler0 = HDRBASETEXTURE; - } - } - - // Load the appropriate textures, making sure that the texture set on sampler 0 is sRGB if necessary - if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && (mat_use_compressed_hdr_textures.GetBool() ) ) - { - LoadTexture( HDRCOMPRESSEDTEXTURE, HDRCOMPRESSEDTEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); - } - else - { - if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) - { - LoadTexture( HDRCOMPRESSEDTEXTURE0, HDRCOMPRESSEDTEXTURE0 == nSampler0 ? nSamplerZeroFlags : 0 ); - if ( params[HDRCOMPRESSEDTEXTURE1]->IsDefined() ) - { - LoadTexture( HDRCOMPRESSEDTEXTURE1, HDRCOMPRESSEDTEXTURE1 == nSampler0 ? nSamplerZeroFlags : 0 ); - } - if ( params[HDRCOMPRESSEDTEXTURE2]->IsDefined()) - { - LoadTexture( HDRCOMPRESSEDTEXTURE2, HDRCOMPRESSEDTEXTURE2 == nSampler0 ? nSamplerZeroFlags : 0 ); - } - } - else - { - if ( params[HDRBASETEXTURE]->IsDefined() ) - { - LoadTexture( HDRBASETEXTURE, HDRBASETEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); - } - } - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - SetInitialShadowState(); - -// pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); - SET_STATIC_VERTEX_SHADER( sky_vs20 ); - - if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && - mat_use_compressed_hdr_textures.GetBool() ) - { - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); - SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); - SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); - } - } - else - { - if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); - SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); - SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); - } - } - else - { - ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); - SET_STATIC_PIXEL_SHADER( sky_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); - SET_STATIC_PIXEL_SHADER( sky_ps20 ); - } - } - } - // we are writing linear values from this shader. - pShaderShadow->EnableSRGBWrite( true ); - - pShaderShadow->EnableAlphaWrites( true ); - } - - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); - - // Texture coord transform - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); - - float c0[4]={1,1,1,1}; - if (params[COLOR]->IsDefined()) - { - memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); - } - if ( - params[HDRCOMPRESSEDTEXTURE]->IsDefined() && - mat_use_compressed_hdr_textures.GetBool() - ) - { - // set up data needs for pixel shader interpolation - ITexture *txtr=params[HDRCOMPRESSEDTEXTURE]->GetTextureValue(); - float w=txtr->GetActualWidth(); - float h=txtr->GetActualHeight(); - float FUDGE=0.01/max(w,h); // per ATI - float c1[4]={(float)(0.5/w-FUDGE), (float)(0.5/h-FUDGE), w, h }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); - - BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); - c0[0]*=8.0; - c0[1]*=8.0; - c0[2]*=8.0; - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); - } - } - else - { - float c1[4]={0,0,0,0}; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); - - if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) - { - BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE0, FRAME ); - BindTexture( SHADER_SAMPLER1, HDRCOMPRESSEDTEXTURE1, FRAME ); - BindTexture( SHADER_SAMPLER2, HDRCOMPRESSEDTEXTURE2, FRAME ); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); - } - - } - else - { - BindTexture( SHADER_SAMPLER0, HDRBASETEXTURE, FRAME ); - ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ( - (fmt==IMAGE_FORMAT_RGBA16161616) || - ( (fmt==IMAGE_FORMAT_RGBA16161616F) && - (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) - ) - { - c0[0]*=16.0; - c0[1]*=16.0; - c0[2]*=16.0; - } - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); - } - } - } - pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); - } - Draw( ); - } -END_SHADER diff --git a/materialsystem/stdshaders/sky_ps2x.fxc b/materialsystem/stdshaders/sky_ps2x.fxc deleted file mode 100644 index 563fddbb..00000000 --- a/materialsystem/stdshaders/sky_ps2x.fxc +++ /dev/null @@ -1,27 +0,0 @@ -// HDRFIXME: Make this work with nonHDR -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -#include "common_ps_fxc.h" - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -sampler BaseTextureSampler : register( s0 ); -HALF4 InputScale : register( c0 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - HALF4 color = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); - color.rgb *= InputScale.rgb; - - // This is never fogged. - return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate -} diff --git a/materialsystem/stdshaders/skydome_ps30.fxc b/materialsystem/stdshaders/skydome_ps30.fxc index a141e682..70388ebe 100644 --- a/materialsystem/stdshaders/skydome_ps30.fxc +++ b/materialsystem/stdshaders/skydome_ps30.fxc @@ -5,7 +5,6 @@ //================================================================================================== // DYNAMIC: "RENDER_SKY" "0..1" -// STATIC: "CONVERT_TO_SRGB" "0..0" #include "common_flashlight_fxc.h" #include "shader_constant_register_map.h" diff --git a/materialsystem/stdshaders/spline_fxc.h b/materialsystem/stdshaders/spline_fxc.h new file mode 100644 index 00000000..bc9fb428 --- /dev/null +++ b/materialsystem/stdshaders/spline_fxc.h @@ -0,0 +1,19 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// derivative of catmull rom spline courtesy of calc +float4 DCatmullRomSpline ( float4 a, float4 b, float4 c, float4 d, float t ) +{ + return 0.5 *( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * (3 * b - a - 3 * c + d ) ) + + t * ( 2 * a - 5 * b + 4 * c - d + 2 * ( t * ( 3 * b - a - 3 * c + d ) ) ) ); +} + +float3 DCatmullRomSpline3 ( float3 a, float3 b, float3 c, float3 d, float t ) +{ + return 0.5 *( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * (3 * b - a - 3 * c + d ) ) + + t * ( 2 * a - 5 * b + 4 * c - d + 2 * ( t * ( 3 * b - a - 3 * c + d ) ) ) ); +} + +float4 CatmullRomSpline( float4 a, float4 b, float4 c, float4 d, float t ) +{ + return b + 0.5 * t * ( c - a + t * ( 2 * a - 5 * b + 4 * c - d + t * ( -a + 3 * b -3 * c + d ) ) ); +} diff --git a/materialsystem/stdshaders/splinerope.cpp b/materialsystem/stdshaders/splinerope.cpp new file mode 100644 index 00000000..db00ca6b --- /dev/null +++ b/materialsystem/stdshaders/splinerope.cpp @@ -0,0 +1,139 @@ +//===== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======// + +#include "basevsshader.h" +#include "convar.h" +#include "sdk_splinerope_ps30.inc" +#include "sdk_splinerope_vs30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar rope_min_pixel_diameter( "rope_min_pixel_diameter", "2.0", FCVAR_CHEAT ); + +BEGIN_VS_SHADER( Cable, "Help for SplineRope" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SHADERSRGBREAD360, SHADER_PARAM_TYPE_BOOL, "0", "Simulate srgb read in shader code") + SHADER_PARAM( SHADOWDEPTH, SHADER_PARAM_TYPE_INTEGER, "0", "writing to a shadow depth buffer" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "normal map" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // srgb read 360 + InitIntParam( SHADERSRGBREAD360, params, 0 ); + InitIntParam( SHADOWDEPTH, params, 0 ); + if ( !params[BUMPMAP]->IsDefined() ) + { + params[BUMPMAP]->SetStringValue( "cable/cablenormalmap" ); + } + SET_FLAGS2( MATERIAL_VAR2_IS_SPRITECARD ); // What's this for? + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + LoadTexture( BASETEXTURE ); + LoadBumpMap( BUMPMAP ); + } + + SHADER_DRAW + { + bool bShadowDepth = ( params[SHADOWDEPTH]->GetIntValue() != 0 ); + SHADOW_STATE + { + // draw back-facing because of yaw spin + pShaderShadow->EnableCulling( false ); + + if ( bShadowDepth ) + { + // don't write color and alpha since we only interested in depth for shadow maps. + pShaderShadow->EnableColorWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // polyoffset for shadow maps. + pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_SHADOW_BIAS ); + } + else + { + // We need to write to dest alpha for depth feathering. + pShaderShadow->EnableAlphaWrites( true ); + + // base texture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + } + + static int s_TexCoordSize[]={ 4, // (worldspace xyz) (radius (diameter?) of spline at this point) for first control point + 4, // (worldspace xyz) (radius of spline at this point) for second control point + 4, // (worldspace xyz) (radius of spline at this point) for third control point + 4, // (worldspace xyz) (radius of spline at this point) for fourth control point + }; + + unsigned int flags = VERTEX_POSITION | VERTEX_COLOR; + + int numTexCoords = 4; + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, s_TexCoordSize, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_splinerope_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_splinerope_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_splinerope_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SHADOWDEPTH, bShadowDepth ); + SET_STATIC_PIXEL_SHADER( sdk_splinerope_ps30 ); + } + DYNAMIC_STATE + { + // We need these only when screen-orienting, which we are always in this shader. + LoadModelViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 ); + LoadProjectionMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); + + // Get viewport and render target dimensions and set shader constant to do a 2D mad + ShaderViewport_t viewport; + pShaderAPI->GetViewports( &viewport, 1 ); + + float c7[4]={ 0.0f, 0.0f, 0.0f, 0.0f }; + if ( !g_pHardwareConfig->IsAAEnabled() ) + { + float flMinPixelDiameter = rope_min_pixel_diameter.GetFloat() / ( float )viewport.m_nWidth; + c7[0]= c7[1] = c7[2] = c7[3] = flMinPixelDiameter; + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, c7, 1 ); + + // bind base texture + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // normal map + BindTexture( SHADER_SAMPLER1, BUMPMAP ); + + if ( !bShadowDepth ) + { + pShaderAPI->SetPixelShaderFogParams( 0 ); + + float vEyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + vEyePos[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, vEyePos, 1 ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_splinerope_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_splinerope_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_splinerope_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_splinerope_ps30 ); + } + Draw( ); + } +END_SHADER diff --git a/materialsystem/stdshaders/sprite.cpp b/materialsystem/stdshaders/sprite.cpp index 77934f57..443c6b98 100644 --- a/materialsystem/stdshaders/sprite.cpp +++ b/materialsystem/stdshaders/sprite.cpp @@ -4,17 +4,20 @@ // // $NoKeywords: $ // -// Implementation of the sprite shader //=============================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include #include "const.h" -#include "sprite_vs11.inc" + +#include "cpp_shader_constant_register_map.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#include "sdk_sprite_vs30.inc" +#include "sdk_sprite_ps30.inc" + // WARNING! Change these in engine/SpriteGn.h if you change them here! #define SPR_VP_PARALLEL_UPRIGHT 0 #define SPR_FACING_UPRIGHT 1 @@ -22,36 +25,41 @@ #define SPR_ORIENTED 3 #define SPR_VP_PARALLEL_ORIENTED 4 - -DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX8 ) - -BEGIN_VS_SHADER( Sprite_DX8, - "Help for Sprite_DX8" ) +BEGIN_VS_SHADER( Sprite, "Help for Sprite" ) BEGIN_SHADER_PARAMS SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + SHADER_PARAM( NOSRGB, SHADER_PARAM_TYPE_BOOL, "0", "do not operate in srgb space" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) END_SHADER_PARAMS SHADER_FALLBACK { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) - return "Sprite_DX6"; + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "Sprite_DX8"; return 0; } - SHADER_INIT_PARAMS() { // FIXME: This can share code with sprite.cpp - // FIXME: Not sure if this is the best solution, but it's a very] - // easy one. When graphics aren't enabled, we oftentimes need to get - // at the parameters of a shader. Therefore, we must set the default - // values in a separate phase from when we load resources. - if (!params[ALPHA]->IsDefined()) - params[ ALPHA ]->SetFloatValue( 1.0f ); + { + params[ALPHA]->SetFloatValue( 1.0f ); + } + + if (!params[HDRCOLORSCALE]->IsDefined()) + { + params[HDRCOLORSCALE]->SetFloatValue( 1.0f ); + } + + if ( !params[NOSRGB]->IsDefined() ) + { + // Disable sRGB reads and writes by default + params[NOSRGB]->SetIntValue( 1 ); + } SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); @@ -96,7 +104,8 @@ BEGIN_VS_SHADER( Sprite_DX8, SHADER_INIT { - LoadTexture( BASETEXTURE ); + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + LoadTexture( BASETEXTURE, bSRGB ? TEXTUREFLAGS_SRGB : 0 ); } #define SHADER_USE_VERTEX_COLOR 1 @@ -104,58 +113,80 @@ BEGIN_VS_SHADER( Sprite_DX8, void SetSpriteCommonShadowState( unsigned int shaderFlags ) { + IShaderShadow *pShaderShadow = s_pShaderShadow; + IMaterialVar **params = s_ppParams; + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bSRGB ); unsigned int flags = VERTEX_POSITION; if( shaderFlags & SHADER_USE_VERTEX_COLOR ) { flags |= VERTEX_COLOR; } - s_pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 ); - - sprite_vs11_Static_Index vshIndex; - bool vertexColor = ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false; - vshIndex.SetVERTEXCOLOR( vertexColor ); - s_pShaderShadow->SetVertexShader( "sprite_vs11", vshIndex.GetIndex() ); - - // "VERTEXCOLOR" "0..1" - // "CONSTANTCOLOR" "0..1" - int pshIndex = 0; - if ( shaderFlags & SHADER_USE_VERTEX_COLOR ) pshIndex |= 0x1; - if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) pshIndex |= 0x2; - s_pShaderShadow->SetPixelShader( "sprite_ps11", pshIndex ); + int numTexCoords = 1; + s_pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_sprite_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_VERTEX_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_VERTEX_SHADER( sdk_sprite_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_sprite_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER( sdk_sprite_ps30 ); + + // OSX always has to sRGB write (don't do this on Linux/Win GL - it causes glow sprites to be way too dark) + s_pShaderShadow->EnableSRGBWrite( bSRGB || ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) ); } void SetSpriteCommonDynamicState( unsigned int shaderFlags ) { + IShaderDynamicAPI *pShaderAPI = s_pShaderAPI; + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - sprite_vs11_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( 0 ); - vshIndex.SetDOWATERFOG( fogIndex ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); - s_pShaderAPI->SetPixelShaderIndex( 0 ); - if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if( shaderFlags & SHADER_USE_CONSTANT_COLOR ) { - SetPixelShaderConstant( 0, COLOR, ALPHA ); + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 0, COLOR, ALPHA ); + else + SetPixelShaderConstant( 0, COLOR, ALPHA ); } - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); - - // identity base texture transorm - float ident[2][4] = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f } - }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } } SHADER_DRAW { + bool bSRGB = params[NOSRGB]->GetIntValue() == 0; + SHADOW_STATE { pShaderShadow->EnableCulling( false ); @@ -167,6 +198,7 @@ BEGIN_VS_SHADER( Sprite_DX8, SHADOW_STATE { FogToFogColor(); + SetSpriteCommonShadowState( 0 ); } DYNAMIC_STATE @@ -182,6 +214,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); @@ -197,9 +230,10 @@ BEGIN_VS_SHADER( Sprite_DX8, SHADOW_STATE { pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS ); + pShaderShadow->EnableDepthTest( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); @@ -217,6 +251,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); @@ -233,6 +268,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); @@ -249,6 +285,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); @@ -272,6 +309,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); SetSpriteCommonShadowState( flags ); @@ -297,6 +335,7 @@ BEGIN_VS_SHADER( Sprite_DX8, pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); SetSpriteCommonShadowState( flags ); @@ -307,29 +346,35 @@ BEGIN_VS_SHADER( Sprite_DX8, ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - sprite_vs11_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( 0 ); - vshIndex.SetDOWATERFOG( fogIndex ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - s_pShaderAPI->SetPixelShaderIndex( 0 ); - - color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; color[3] = 1.0f; s_pShaderAPI->SetPixelShaderConstant( 0, color ); - - - // identity base texture transorm - float ident[2][4] = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f } - }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } } Draw(); SHADOW_STATE @@ -345,34 +390,41 @@ BEGIN_VS_SHADER( Sprite_DX8, int numAnimationFrames = pTexture->GetNumAnimationFrames(); BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - sprite_vs11_Dynamic_Index vshIndex; - vshIndex.SetSKINNING( 0 ); - vshIndex.SetDOWATERFOG( fogIndex ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_sprite_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_sprite_ps30 ); - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - s_pShaderAPI->SetPixelShaderIndex( 0 ); + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; color[3] = 1.0f; s_pShaderAPI->SetPixelShaderConstant( 0, color ); - - // identity base texture transorm - float ident[2][4] = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f } - }; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } } Draw(); } + break; default: - ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); break; } } diff --git a/materialsystem/stdshaders/sprite_dx6.cpp b/materialsystem/stdshaders/sprite_dx6.cpp deleted file mode 100644 index 15ba22a6..00000000 --- a/materialsystem/stdshaders/sprite_dx6.cpp +++ /dev/null @@ -1,289 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -// Implementation of the sprite shader -//=============================================================================// - -#include "shaderlib/cshader.h" -#include -#include "const.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// WARNING! Change these in engine/SpriteGn.h if you change them here! -#define SPR_VP_PARALLEL_UPRIGHT 0 -#define SPR_FACING_UPRIGHT 1 -#define SPR_VP_PARALLEL 2 -#define SPR_ORIENTED 3 -#define SPR_VP_PARALLEL_ORIENTED 4 - - -DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX6 ) - -BEGIN_SHADER( Sprite_DX6, - "Help for Sprite_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) - SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) - SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) - SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FIXME: This can share code with sprite.cpp - // FIXME: Not sure if this is the best solution, but it's a very] - // easy one. When graphics aren't enabled, we oftentimes need to get - // at the parameters of a shader. Therefore, we must set the default - // values in a separate phase from when we load resources. - - if (!params[ALPHA]->IsDefined()) - params[ ALPHA ]->SetFloatValue( 1.0f ); - - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); - SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); - - // translate from a string orientation to an enumeration - if (params[SPRITEORIENTATION]->IsDefined()) - { - const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); - if( stricmp( orientationString, "parallel_upright" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - else if( stricmp( orientationString, "facing_upright" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); - } - else if( stricmp( orientationString, "vp_parallel" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); - } - else if( stricmp( orientationString, "oriented" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); - } - else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); - } - else - { - Warning( "error with $spriteOrientation\n" ); - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - } - else - { - // default case - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableCulling( false ); - } - - switch( params[SPRITERENDERMODE]->GetIntValue() ) - { - case kRenderNormal: - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderTransColor: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderTransTexture: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderGlow: - case kRenderWorldGlow: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToBlack(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderTransAlpha: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderTransAlphaAdd: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - FogToBlack(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - - case kRenderTransAdd: - SHADOW_STATE - { - if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) - { - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - } - else - { - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - } - pShaderShadow->EnableConstantColor( true ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - FogToBlack(); - } - DYNAMIC_STATE - { - SetColorState( COLOR, ALPHA ); - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - break; - case kRenderTransAddFrameBlend: - { - float flFrame = params[FRAME]->GetFloatValue(); - float flFade = params[ALPHA]->GetFloatValue(); - SHADOW_STATE - { - if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) - { - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - } - else - { - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); - } - pShaderShadow->EnableConstantColor( true ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - FogToBlack(); - } - DYNAMIC_STATE - { - float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); - pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); - } - Draw(); - SHADOW_STATE - { - FogToBlack(); - } - DYNAMIC_STATE - { - float frameBlendAlpha = ( flFrame - ( int )flFrame ); - pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - int numAnimationFrames = pTexture->GetNumAnimationFrames(); - BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); - } - Draw(); - } - - break; - default: - ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); - break; - } - } -END_SHADER diff --git a/materialsystem/stdshaders/sprite_dx9.cpp b/materialsystem/stdshaders/sprite_dx9.cpp deleted file mode 100644 index 0a0bb9f4..00000000 --- a/materialsystem/stdshaders/sprite_dx9.cpp +++ /dev/null @@ -1,490 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#include "BaseVSShader.h" -#include -#include "const.h" - -#include "cpp_shader_constant_register_map.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#include "sprite_vs20.inc" -#include "sprite_ps20.inc" -#include "sprite_ps20b.inc" - -// WARNING! Change these in engine/SpriteGn.h if you change them here! -#define SPR_VP_PARALLEL_UPRIGHT 0 -#define SPR_FACING_UPRIGHT 1 -#define SPR_VP_PARALLEL 2 -#define SPR_ORIENTED 3 -#define SPR_VP_PARALLEL_ORIENTED 4 - - -DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX9 ) - -BEGIN_VS_SHADER( Sprite_DX9, - "Help for Sprite_DX9" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) - SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) - SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) - SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) - SHADER_PARAM( NOSRGB, SHADER_PARAM_TYPE_BOOL, "0", "do not operate in srgb space" ) - SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if (g_pHardwareConfig->GetDXSupportLevel() < 90) - return "Sprite_DX8"; - return 0; - } - SHADER_INIT_PARAMS() - { - // FIXME: This can share code with sprite.cpp - if (!params[ALPHA]->IsDefined()) - { - params[ALPHA]->SetFloatValue( 1.0f ); - } - - if (!params[HDRCOLORSCALE]->IsDefined()) - { - params[HDRCOLORSCALE]->SetFloatValue( 1.0f ); - } - - if ( !params[NOSRGB]->IsDefined() ) - { - // Disable sRGB reads and writes by default - params[NOSRGB]->SetIntValue( 1 ); - } - - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); - SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); - - // translate from a string orientation to an enumeration - if (params[SPRITEORIENTATION]->IsDefined()) - { - const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); - if( stricmp( orientationString, "parallel_upright" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - else if( stricmp( orientationString, "facing_upright" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); - } - else if( stricmp( orientationString, "vp_parallel" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); - } - else if( stricmp( orientationString, "oriented" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); - } - else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) - { - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); - } - else - { - Warning( "error with $spriteOrientation\n" ); - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - } - else - { - // default case - params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); - } - } - - SHADER_INIT - { - bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; - LoadTexture( BASETEXTURE, bSRGB ? TEXTUREFLAGS_SRGB : 0 ); - } - -#define SHADER_USE_VERTEX_COLOR 1 -#define SHADER_USE_CONSTANT_COLOR 2 - - void SetSpriteCommonShadowState( unsigned int shaderFlags ) - { - IShaderShadow *pShaderShadow = s_pShaderShadow; - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bSRGB ); - - // Only enabling this on OSX() - it causes GL mode's light glow sprites to be much darker vs. D3D9 under Linux/Win GL. - bool bSRGBOutputAdapter = ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) && !bSRGB; - - unsigned int flags = VERTEX_POSITION; - if( shaderFlags & SHADER_USE_VERTEX_COLOR ) - { - flags |= VERTEX_COLOR; - } - int numTexCoords = 1; - s_pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - - DECLARE_STATIC_VERTEX_SHADER( sprite_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); - SET_STATIC_VERTEX_SHADER_COMBO( SRGB, bSRGB ); - SET_STATIC_VERTEX_SHADER( sprite_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path - { - DECLARE_STATIC_PIXEL_SHADER( sprite_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); - SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); - SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); - SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); - SET_STATIC_PIXEL_SHADER_COMBO( SRGB_OUTPUT_ADAPTER, bSRGBOutputAdapter ); - SET_STATIC_PIXEL_SHADER( sprite_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sprite_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); - SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); - SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); - SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); - SET_STATIC_PIXEL_SHADER( sprite_ps20 ); - } - - // OSX always has to sRGB write (don't do this on Linux/Win GL - it causes glow sprites to be way too dark) - s_pShaderShadow->EnableSRGBWrite( bSRGB || ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) ); - } - - void SetSpriteCommonDynamicState( unsigned int shaderFlags ) - { - IShaderDynamicAPI *pShaderAPI = s_pShaderAPI; - bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; - - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - if( shaderFlags & SHADER_USE_CONSTANT_COLOR ) - { - if ( bSRGB ) - SetPixelShaderConstantGammaToLinear( 0, COLOR, ALPHA ); - else - SetPixelShaderConstant( 0, COLOR, ALPHA ); - } - - if( IsHDREnabled() ) - { - if ( bSRGB ) - SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); - else - SetPixelShaderConstant( 1, HDRCOLORSCALE ); - } - } - - SHADER_DRAW - { - bool bSRGB = params[NOSRGB]->GetIntValue() == 0; - - SHADOW_STATE - { - pShaderShadow->EnableCulling( false ); - } - - switch( params[SPRITERENDERMODE]->GetIntValue() ) - { - case kRenderNormal: - SHADOW_STATE - { - FogToFogColor(); - - SetSpriteCommonShadowState( 0 ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( 0 ); - } - Draw(); - break; - case kRenderTransColor: - case kRenderTransTexture: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - FogToFogColor(); - - SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); - } - Draw(); - break; - case kRenderGlow: - case kRenderWorldGlow: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - - FogToBlack(); - - SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); - } - Draw(); - break; - case kRenderTransAlpha: - // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - FogToFogColor(); - - SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); - } - Draw(); - break; - case kRenderTransAlphaAdd: - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - FogToFogColor(); - - SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); - } - Draw(); - - SHADOW_STATE - { - SetInitialShadowState(); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); - - FogToBlack(); - - SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); - } - Draw(); - break; - - case kRenderTransAdd: - { - unsigned int flags = SHADER_USE_CONSTANT_COLOR; - if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) - { - flags |= SHADER_USE_VERTEX_COLOR; - } - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - - FogToBlack(); - - SetSpriteCommonShadowState( flags ); - } - DYNAMIC_STATE - { - SetSpriteCommonDynamicState( flags ); - } - } - Draw(); - break; - case kRenderTransAddFrameBlend: - { - float flFrame = params[FRAME]->GetFloatValue(); - float flFade = params[ALPHA]->GetFloatValue(); - unsigned int flags = SHADER_USE_CONSTANT_COLOR; - if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) - { - flags |= SHADER_USE_VERTEX_COLOR; - } - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - - FogToBlack(); - - SetSpriteCommonShadowState( flags ); - } - DYNAMIC_STATE - { - float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); - - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - float color[4]; - if ( bSRGB ) - color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); - else - color[0] = color[1] = color[2] = flFade * frameBlendAlpha; - color[3] = 1.0f; - s_pShaderAPI->SetPixelShaderConstant( 0, color ); - if( IsHDREnabled() ) - { - if ( bSRGB ) - SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); - else - SetPixelShaderConstant( 1, HDRCOLORSCALE ); - } - } - Draw(); - SHADOW_STATE - { - FogToBlack(); - - SetSpriteCommonShadowState( flags ); - } - DYNAMIC_STATE - { - float frameBlendAlpha = ( flFrame - ( int )flFrame ); - ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); - int numAnimationFrames = pTexture->GetNumAnimationFrames(); - BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); - - MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - float color[4]; - if ( bSRGB ) - color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); - else - color[0] = color[1] = color[2] = flFade * frameBlendAlpha; - color[3] = 1.0f; - s_pShaderAPI->SetPixelShaderConstant( 0, color ); - if( IsHDREnabled() ) - { - if ( bSRGB ) - SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); - else - SetPixelShaderConstant( 1, HDRCOLORSCALE ); - } - } - Draw(); - } - - break; - default: - ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); - break; - } - } -END_SHADER diff --git a/materialsystem/stdshaders/sprite_ps11.psh b/materialsystem/stdshaders/sprite_ps11.psh deleted file mode 100644 index 021246d1..00000000 --- a/materialsystem/stdshaders/sprite_ps11.psh +++ /dev/null @@ -1,15 +0,0 @@ -; STATIC: "VERTEXCOLOR" "0..1" -; STATIC: "CONSTANTCOLOR" "0..1" - -ps.1.1 - -tex t0 -mov r0, t0 - -#if VERTEXCOLOR -mul r0, r0, v0 -#endif - -#if CONSTANTCOLOR -mul r0, r0, c0 -#endif \ No newline at end of file diff --git a/materialsystem/stdshaders/sprite_ps2x.fxc b/materialsystem/stdshaders/sprite_ps2x.fxc deleted file mode 100644 index 83a7ab08..00000000 --- a/materialsystem/stdshaders/sprite_ps2x.fxc +++ /dev/null @@ -1,61 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "CONSTANTCOLOR" "0..1" -// STATIC: "HDRTYPE" "0..2" -// STATIC: "SRGB" "0..1" -// STATIC: "SRGB_OUTPUT_ADAPTER" "0..1" [ps20b] - -// DYNAMIC: "HDRENABLED" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -const HALF4 g_Color : register( c0 ); -const float g_HDRColorScale : register( c1 ); - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - -sampler TexSampler : register( s0 ); - -struct PS_INPUT -{ - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 result, sample = tex2D( TexSampler, i.baseTexCoord ); - -#if VERTEXCOLOR - sample *= i.color; -#endif - -#if CONSTANTCOLOR - sample *= g_Color; -#endif - -#if HDRTYPE && HDRENABLED - sample.xyz *= g_HDRColorScale; -#endif - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); -#if SRGB - result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -#else - result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_GAMMA ); -#endif - - // On Posix, we're being forced through a linear-to-gamma curve but don't want it, so we do the opposite here first -#if SRGB_OUTPUT_ADAPTER - result = GammaToLinear( result ); -#endif - - return result; -} - diff --git a/materialsystem/stdshaders/sprite_vs11.vsh b/materialsystem/stdshaders/sprite_vs11.vsh deleted file mode 100644 index 5ffa45f1..00000000 --- a/materialsystem/stdshaders/sprite_vs11.vsh +++ /dev/null @@ -1,9 +0,0 @@ -vs.1.1 - -# STATIC: "VERTEXCOLOR" "0..1" -# DYNAMIC: "SKINNING" "0..0" -# DYNAMIC: "DOWATERFOG" "0..1" - -#include "UnlitGeneric_inc.vsh" - -&UnlitGeneric( 0, 0, 0, 0, $VERTEXCOLOR ); diff --git a/materialsystem/stdshaders/sprite_vs20.fxc b/materialsystem/stdshaders/sprite_vs20.fxc deleted file mode 100644 index 5e427c19..00000000 --- a/materialsystem/stdshaders/sprite_vs20.fxc +++ /dev/null @@ -1,65 +0,0 @@ -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "SRGB" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bVertexColor = VERTEXCOLOR ? true : false; - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vColor : COLOR0; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; -#endif - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - worldPos = mul4x3( v.vPos, cModel[0] ); - - // Transform into projection space - float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = projPos; - projPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); - -#if !defined( _X360 ) - o.fog = CalcFog( worldPos, projPos, g_FogType ); -#endif - if ( g_bVertexColor ) - { - // Assume that this is unlitgeneric if you are using vertex color. -#if SRGB - o.color.rgba = GammaToLinear( v.vColor.rgba ); -#else - o.color.rgba = v.vColor.rgba; -#endif - } - - // Base texture coordinates - o.baseTexCoord.xy = v.vTexCoord0.xy; - - return o; -} - - diff --git a/materialsystem/stdshaders/spritecard.cpp b/materialsystem/stdshaders/spritecard.cpp index 2eb65b64..4eb38acc 100644 --- a/materialsystem/stdshaders/spritecard.cpp +++ b/materialsystem/stdshaders/spritecard.cpp @@ -6,7 +6,7 @@ // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" // STDSHADER_DX9_DLL_EXPORT @@ -29,10 +29,6 @@ #define DEFAULT_PARTICLE_FEATHERING_ENABLED 1 -#ifdef STDSHADER_DX8_DLL_EXPORT -DEFINE_FALLBACK_SHADER( Spritecard, Spritecard_DX8 ) -#endif - int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go against the default soft-particle value { static int iRetVal = -1; @@ -67,11 +63,7 @@ int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go agains } -#ifdef STDSHADER_DX9_DLL_EXPORT BEGIN_VS_SHADER_FLAGS( Spritecard, "Help for Spritecard", SHADER_NOT_EDITABLE ) -#else -BEGIN_VS_SHADER_FLAGS( Spritecard_DX8, "Help for Spritecard_DX8", SHADER_NOT_EDITABLE ) -#endif BEGIN_SHADER_PARAMS SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) @@ -299,7 +291,7 @@ SHADER_DRAW numTexCoords = 8; } pShaderShadow->VertexShaderVertexFormat( flags, - numTexCoords, + numTexCoords, nSplineType? s_TexCoordSizeSpline : s_TexCoordSize, 0 ); if ( bDX8 ) @@ -417,18 +409,18 @@ SHADER_DRAW if ( bZoomSeq2 ) { float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue()); - float C0[4]={ (float)(0.5*(1.0+flZScale)), flZScale, 0, 0 }; + float C0[4]={ 0.5*(1.0+flZScale), flZScale, 0, 0 }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, C0, ARRAYSIZE(C0)/4 ); } // set fade constants in vsconsts 8 and 9 float flMaxDistance = params[MAXDISTANCE]->GetFloatValue(); - float flStartFade = max( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() ); + float flStartFade = MAX( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() ); float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(), params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(), - flStartFade, (float)(1.0/(flMaxDistance-flStartFade)), + flStartFade, 1.0/(flMaxDistance-flStartFade), 0,0 }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, VC0, ARRAYSIZE(VC0)/4 ); diff --git a/materialsystem/stdshaders/spritecard_ps11.fxc b/materialsystem/stdshaders/spritecard_ps11.fxc deleted file mode 100644 index 624362cb..00000000 --- a/materialsystem/stdshaders/spritecard_ps11.fxc +++ /dev/null @@ -1,72 +0,0 @@ -// STATIC: "ADDBASETEXTURE2" "0..1" -// STATIC: "ADDSELF" "0..1" -// STATIC: "USEALPHAASRGB" "0..1" -// SKIP: $USEALPHAASRGB && $ADDSELF -// SKIP: $USEALPHAASRGB && $ADDBASETEXTURE2 - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float2 texCoord0 : TEXCOORD0; - float2 texCoord1 : TEXCOORD1; - float4 argbcolor : COLOR; - float4 blendfactor0 : TEXCOORD2; -#if ADDBASETEXTURE2 - float2 texCoord2 : TEXCOORD3; -#endif - float4 vScreenPos : TEXCOORD7; -}; - -sampler BaseTextureSampler : register( s0 ); - -#if ADDBASETEXTURE2 -sampler BaseTextureSampler2 : register( s3 ); -#endif - -sampler BaseTextureSampler1 : register( s1 ); -const float4 g_Parameters : register( c0 ); -const float4 g_ColorPowers : register( c1 ); - -#define fAdditiveBlendWeight g_Parameters.x -#define fOverbrightFactor g_Parameters.y -#define fAdditiveSelfBlendWeight g_Parameters.z -#define fSoftParticleBlendScale g_Parameters.w - -#pragma warning( disable : 4707 4704 ) -float4 main( PS_INPUT i ) : COLOR -{ - // Sample frames from texture 0 -#if ( ! ADDSELF ) && ( ! ADDBASETEXTURE2 ) - float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); - float4 baseTex1 = tex2D( BaseTextureSampler1, i.texCoord1 ); - float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); -#else - float4 blended_rgb = tex2D( BaseTextureSampler, i.texCoord0 ); -#endif -#if USEALPHAASRGB - blended_rgb.rgb = blended_rgb.a; -#endif - -#if ADDBASETEXTURE2 - blended_rgb.a *= i.argbcolor.a; - - // In this case, we don't really want to pre-multiply by alpha - float4 color2 = tex2D( BaseTextureSampler2, i.texCoord2 ); - blended_rgb.rgb *= blended_rgb.a; - blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * color2; - blended_rgb.rgb *= 2 * i.argbcolor.rgb; -#else -#if ADDSELF - blended_rgb.a *= i.argbcolor.a; - blended_rgb.rgb *= blended_rgb.a; - blended_rgb.rgb += fOverbrightFactor * 8 * fAdditiveSelfBlendWeight * blended_rgb; - blended_rgb.rgb *= 2 * i.argbcolor.rgb; -#else - blended_rgb *= i.argbcolor; -#endif -#endif - return blended_rgb; -} - diff --git a/materialsystem/stdshaders/spritecard_ps2x.fxc b/materialsystem/stdshaders/spritecard_ps2x.fxc deleted file mode 100644 index 1281d33a..00000000 --- a/materialsystem/stdshaders/spritecard_ps2x.fxc +++ /dev/null @@ -1,194 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "DUALSEQUENCE" "0..1" -// STATIC: "SEQUENCE_BLEND_MODE" "0..2" -// STATIC: "ADDBASETEXTURE2" "0..1" -// STATIC: "MAXLUMFRAMEBLEND1" "0..1" -// STATIC: "MAXLUMFRAMEBLEND2" "0..1" -// STATIC: "EXTRACTGREENALPHA" "0..1" -// STATIC: "COLORRAMP" "0..1" -// STATIC: "ANIMBLEND" "0..1" -// STATIC: "ADDSELF" "0..1" -// STATIC: "DEPTHBLEND" "0..1" [ps20b] - -#define COMBINE_MODE_AVERAGE 0 -#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1 -#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2 - -#define HDRTYPE HDR_TYPE_NONE -#include "common_ps_fxc.h" - -const float4 g_Parameters : register( c0 ); -const float4 g_DepthFeatheringConstants : register( c2 ); - -#define fAdditiveBlendWeight g_Parameters.x -#define fOverbrightFactor g_Parameters.y -#define fAdditiveSelfBlendWeight g_Parameters.z - -struct PS_INPUT -{ - float2 texCoord0 : TEXCOORD0; - float2 texCoord1 : TEXCOORD1; - float4 argbcolor : COLOR; - float4 blendfactor0 : TEXCOORD2; -#if ADDBASETEXTURE2 - float2 texCoord2 : TEXCOORD3; -#endif -#if EXTRACTGREENALPHA - float4 blendfactor1 : TEXCOORD4; -#endif - -#if DUALSEQUENCE - float2 vSeq2TexCoord0 : TEXCOORD5; - float2 vSeq2TexCoord1 : TEXCOORD6; -#endif - -#if defined( REVERSE_DEPTH_ON_X360 ) - float4 vScreenPos_ReverseZ : TEXCOORD7; -#else - float4 vScreenPos : TEXCOORD7; -#endif -}; - -sampler BaseTextureSampler : register( s0 ); -sampler ColorRampSampler : register( s1 ); -sampler DepthSampler : register( s2 ); - -float4 main( PS_INPUT i ) : COLOR -{ - bool bMaxLumFrameBlend1 = MAXLUMFRAMEBLEND1 ? true : false; - bool bMaxLumFrameBlend2 = MAXLUMFRAMEBLEND2 ? true : false; - bool bExtractGreenAlpha = EXTRACTGREENALPHA ? true : false; - bool bAddBaseTexture2 = ADDBASETEXTURE2 ? true : false; - bool bDualSequence = DUALSEQUENCE ? true : false; - bool bColorRamp = COLORRAMP ? true : false; -#ifdef DEPTHBLEND - bool bDepthBlend = DEPTHBLEND ? true : false; -#endif - int nSequenceBlendMode = SEQUENCE_BLEND_MODE; - - // Sample frames from texture 0 - float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); - - float4 baseTex1 = tex2D( BaseTextureSampler, i.texCoord1 ); - - // Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha) -#if ANIMBLEND - float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); -#else - float4 blended_rgb = baseTex0; -#endif - - if ( bMaxLumFrameBlend1 ) - { - // Blend between animation frames based upon max luminance - float lum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); - float lum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); - - if ( lum0 > lum1 ) - blended_rgb = baseTex0; - else - blended_rgb = baseTex1; - } - else if( bExtractGreenAlpha ) - { -#if EXTRACTGREENALPHA - // Weight Green/Alphas from the two frames for a scalar result - blended_rgb = dot( baseTex0, i.blendfactor0 ) + dot( baseTex1, i.blendfactor1 ); -#endif - } - -#if DUALSEQUENCE - if ( bDualSequence ) - { - baseTex0 = tex2D( BaseTextureSampler, i.vSeq2TexCoord0 ); - baseTex1 = tex2D( BaseTextureSampler, i.vSeq2TexCoord1 ); - - // Blend by default (may override with bMaxLumFrameBlend2) - float4 rgb2 = lerp( baseTex0, baseTex1, i.blendfactor0.z ); - - if ( bMaxLumFrameBlend2 ) - { - // blend between animation frames based upon max luminance - float tlum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); - float tlum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); - - if ( tlum0 > tlum1 ) - rgb2 = baseTex0; - else - rgb2 = baseTex1; - } - - if ( nSequenceBlendMode == COMBINE_MODE_AVERAGE ) - { - blended_rgb = 0.5 * ( blended_rgb + rgb2 ); - } - else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND ) - { - blended_rgb.rgb = rgb2.rgb; - } - else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_OVER_SECOND ) - { - blended_rgb.rgb = lerp( blended_rgb.rgb, rgb2.rgb, rgb2.a ); - } - } // bDualSequence -#endif - - // Optional color ramp - if ( bColorRamp ) - { - blended_rgb.rgb = tex2D( ColorRampSampler, float2( blended_rgb.r, blended_rgb.g ) ); - } - - // Overbright - blended_rgb.rgb *= fOverbrightFactor; - - //Soft Particles FTW -# if (DEPTHBLEND == 1) -# if defined( _X360 ) - float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos_ReverseZ.xy / i.vScreenPos_ReverseZ.w, i.vScreenPos_ReverseZ.z, i.vScreenPos_ReverseZ.w, g_DepthFeatheringConstants ); -# else - float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos.xy / i.vScreenPos.w, i.vScreenPos.z, i.vScreenPos.w, g_DepthFeatheringConstants ); -# endif - i.argbcolor.a *= fDepthBlend; -# endif - - // Premultiply the alpha for a ONE:INVALPHA blend -#if ADDBASETEXTURE2 - if ( bAddBaseTexture2 ) - { - blended_rgb.a *= i.argbcolor.a; - - // In this case, we don't really want to pre-multiply by alpha - if ( !bColorRamp ) - { - blended_rgb.rgb *= blended_rgb.a; - } - - if ( bExtractGreenAlpha ) - { - blended_rgb.rgb += fAdditiveBlendWeight * i.argbcolor.a * blended_rgb.rgb; - } - else - { - blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * tex2D( BaseTextureSampler, i.texCoord2 ); - } - - blended_rgb.rgb *= i.argbcolor.rgb; - } - else -#endif - { -#if ADDSELF - blended_rgb.a *= i.argbcolor.a; - blended_rgb.rgb *= blended_rgb.a; - blended_rgb.rgb += fOverbrightFactor * fAdditiveSelfBlendWeight * i.argbcolor.a * blended_rgb; - blended_rgb.rgb *= i.argbcolor.rgb; -#else - blended_rgb *= i.argbcolor; -#endif - } - - return FinalOutput( blended_rgb, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); -} - diff --git a/materialsystem/stdshaders/ssgi_combine_ps30.fxc b/materialsystem/stdshaders/ssgi_combine_ps30.fxc index 93ba3f26..fe3cb0fd 100644 --- a/materialsystem/stdshaders/ssgi_combine_ps30.fxc +++ b/materialsystem/stdshaders/ssgi_combine_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" diff --git a/materialsystem/stdshaders/stdshader_dx9.vpc b/materialsystem/stdshaders/stdshader_dx9.vpc deleted file mode 100644 index b83cc154..00000000 --- a/materialsystem/stdshaders/stdshader_dx9.vpc +++ /dev/null @@ -1,127 +0,0 @@ -//----------------------------------------------------------------------------- -// STDSHADER_DX9.vpc -// -// Project Script for mods to use an an example of how to override shaders -//----------------------------------------------------------------------------- - -$Macro SRCDIR "..\.." -$Macro OUTBINDIR "$SRCDIR\..\game\bin" - -$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" - -$Configuration "Debug" -{ - $General - { - $OutputDirectory "Debug_dx9" [$WIN32] - $IntermediateDirectory "Debug_dx9" [$WIN32] - } -} - -$Configuration "Release" -{ - $General - { - $OutputDirectory "Release_dx9" [$WIN32] - $IntermediateDirectory "Release_dx9" [$WIN32] - } -} - -// Common Configuration -$Configuration -{ - $Compiler - { - $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX] - $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360] - $AdditionalIncludeDirectories "$BASE;.\;.\vance;.\deferred" - $PreprocessorDefinitions "$BASE;STDSHADER;FAST_MATERIALVAR_ACCESS" - $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL] - $PreprocessorDefinitions "$BASE;VANCE" - } - - $Linker - { - $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32] - $SystemLibraries "iconv" [$OSXALL] - } -} - -$Project "stdshader_dx9" -{ - $Folder "Source Files" - { - - $Folder "Post-processing" - { - $File "vance/chromatic.cpp" - $File "vance/fxaa.cpp" - $File "vance/gaussian_depthaware.cpp" - $File "vance/gaussianx.cpp" - $File "vance/gaussiany.cpp" - $File "vance/screenwater.cpp" - $File "vance/unsharp.cpp" - $File "vance/unsharp_blur.cpp" - $File "vance/luma.cpp" - $File "vance/tonemap.cpp" - $File "vance/Bloom_combine.cpp" - $File "vance/ssao_combine.cpp" - $File "vance/SSGI.cpp" - $File "vance/skydome_atmosphere.cpp" - $File "vance/skydome_atmosphere_helper.cpp" - $File "vance/skydome_atmosphere_helper.h" - } - $File "BaseVSShader.cpp" - $File "screenspace_general.cpp" - - $File "lightmappedgeneric_dx9.cpp" - $File "lightmappedgeneric_dx9_helper.cpp" - $File "lightmappedgeneric_dx9_helper.h" - $File "worldvertextransition.cpp" - - $File "vertexlitgeneric_dx9.cpp" - $File "vertexlitgeneric_dx9_helper.cpp" - $File "vertexlitgeneric_dx9_helper.h" - - $File "VertexlitPBR_dx9.cpp" - $File "VertexlitPBR_dx9_helper.cpp" - $File "VertexlitPBR_dx9_helper.h" - - $File "LightmappedPBR_dx9.cpp" - $File "LightmappedPBR_dx9_helper.cpp" - $File "LightmappedPBR_dx9_helper.h" - - $File "lightpass_helper.cpp" - $File "lightpass_helper.h" - - - $Folder "Engine" - { - $File "AccumBuff4Sample.cpp" - $File "accumbuff5sample.cpp" - $File "BufferClearObeyStencil_dx9.cpp" - $File "depthwrite.cpp" - $File "writez_dx9.cpp" - $File "writestencil_dx9.cpp" - $File "wireframe_dx9.cpp" - $File "shadow.cpp" - $File "shadowbuild_dx9.cpp" - } - - $File "deferred/IDeferredExt.cpp" - - $Folder "Remove me when VAC2 is out" [$WIN32] - { - $File "$SRCDIR\tier1\checksum_crc.cpp" - $File "$SRCDIR\tier1\checksum_md5.cpp" - $File "..\shader_dll_verify.cpp" - $File "..\shader_dll_verify.h" - } - } - - $Folder "Link Libraries" - { - $Lib mathlib - $Lib shaderlib - } -} \ No newline at end of file diff --git a/materialsystem/stdshaders/teeth.cpp b/materialsystem/stdshaders/teeth.cpp index b3dc9ff9..46c98619 100644 --- a/materialsystem/stdshaders/teeth.cpp +++ b/materialsystem/stdshaders/teeth.cpp @@ -4,35 +4,20 @@ // //=============================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "cpp_shader_constant_register_map.h" - -#include "teeth_vs20.inc" -#include "teeth_flashlight_vs20.inc" -#include "teeth_bump_vs20.inc" -#include "teeth_ps20.inc" -#include "teeth_ps20b.inc" -#include "teeth_flashlight_ps20.inc" -#include "teeth_flashlight_ps20b.inc" -#include "teeth_bump_ps20.inc" -#include "teeth_bump_ps20b.inc" - -#ifndef _X360 -#include "teeth_vs30.inc" -#include "teeth_ps30.inc" -#include "teeth_bump_vs30.inc" -#include "teeth_bump_ps30.inc" -#include "teeth_flashlight_vs30.inc" -#include "teeth_flashlight_ps30.inc" -#endif +#include "sdk_teeth_vs30.inc" +#include "sdk_teeth_ps30.inc" +#include "sdk_teeth_bump_vs30.inc" +#include "sdk_teeth_bump_ps30.inc" +#include "sdk_teeth_flashlight_vs30.inc" +#include "sdk_teeth_flashlight_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX9 ) - extern ConVar r_flashlight_version2; -BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) +BEGIN_VS_SHADER( Teeth, "Help for Teeth" ) BEGIN_SHADER_PARAMS SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) @@ -113,82 +98,27 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) if ( hasBump ) { -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); - - // ps_2_b version which does phong - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); - SET_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); - SET_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); - } - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); - SET_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); - } -#endif + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_teeth_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_teeth_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_teeth_bump_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_teeth_bump_ps30 ); } else { -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_STATIC_VERTEX_SHADER( teeth_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( teeth_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( teeth_ps20b ); - SET_STATIC_PIXEL_SHADER( teeth_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( teeth_ps20 ); - SET_STATIC_PIXEL_SHADER( teeth_ps20 ); - } - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER( teeth_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( teeth_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( teeth_ps30 ); - SET_STATIC_PIXEL_SHADER( teeth_ps30 ); - } -#endif + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_teeth_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_teeth_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_teeth_ps30 ); + SET_STATIC_PIXEL_SHADER( sdk_teeth_ps30 ); } // On DX9, do sRGB @@ -222,129 +152,47 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) float vEyePos_SpecExponent[4]; pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; + if (g_pHardwareConfig->HasFastVertexTextures() || g_pHardwareConfig->SupportsPixelShaders_2_b()) + vEyePos_SpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); + else + vEyePos_SpecExponent[3] = 0.0f; pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); if ( hasBump ) { -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); - - // ps_2_b version which does Phong - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - Vector4D vSpecExponent; - vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); - - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); - } - } -#ifndef _X360 - else - { - SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); - - Vector4D vSpecExponent; - vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); - } -#endif + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_teeth_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_teeth_bump_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_teeth_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_teeth_bump_ps30 ); } else { // For non-bumped case, ambient cube is computed in the vertex shader SetAmbientCubeDynamicStateVertexShader(); -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); - } - } -#ifndef _X360 - else - { - SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); - } -#endif + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_teeth_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_teeth_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_teeth_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_teeth_ps30 ); } if( params[INTRO]->GetIntValue() ) @@ -392,41 +240,17 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats } -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); - SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); - } - } -#ifndef _X360 - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); - SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_teeth_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_teeth_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_teeth_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( sdk_teeth_flashlight_ps30 ); - DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); - } -#endif // On DX9, do sRGB pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); pShaderShadow->EnableSRGBWrite( true ); @@ -495,53 +319,17 @@ BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) pShaderAPI->GetWorldSpaceCameraPosition( vFlashlightPos ); pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vFlashlightPos, 1 ); - if ( IsX360() ) - { - pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); - } + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); - } - } -#ifndef _X360 - else - { - SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_teeth_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_teeth_flashlight_vs30 ); - DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); - } -#endif + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_teeth_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_teeth_flashlight_ps30 ); if( params[INTRO]->GetIntValue() ) { diff --git a/materialsystem/stdshaders/teeth_bump_ps2x.fxc b/materialsystem/stdshaders/teeth_bump_ps2x.fxc deleted file mode 100644 index 72e43a10..00000000 --- a/materialsystem/stdshaders/teeth_bump_ps2x.fxc +++ /dev/null @@ -1,101 +0,0 @@ -//====== Copyright 1996-2006, Valve Corporation, All rights reserved. ======= - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] -// DYNAMIC: "AMBIENT_LIGHT" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -#include "shader_constant_register_map.h" - -const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); -PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total - -sampler BaseTextureSampler : register( s0 ); -sampler BumpTextureSampler : register( s1 ); -sampler NormalizeSampler : register( s2 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float4 worldVertToEyeVector_Darkening : TEXCOORD1; - float3x3 tangentSpaceTranspose : TEXCOORD2; - // second row : TEXCOORD3; - // third row : TEXCOORD4; - float4 worldPos_projPosZ : TEXCOORD5; - float2 lightAtten01 : TEXCOORD6; - float2 lightAtten23 : TEXCOORD7; -}; - - - -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - -#define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz -#define fDarkening i.worldVertToEyeVector_Darkening.w - -#endif - - - -float4 main( PS_INPUT i ) : COLOR -{ - bool bAmbientLight = AMBIENT_LIGHT ? true : false; - int nNumLights = NUM_LIGHTS; - - float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); - float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); - - float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1); - float fSpecExp = g_EyePos_SpecExponent.w; - - float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord ); - tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f; - worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); - - // If the exponent passed in as a constant is zero, use the value from the map as the exponent - if ( fSpecExp == 0 ) - fSpecExp = 1.0f * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w; - - // Summation of diffuse illumination from all local lights - float3 diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, - float3( 0.0f, 0.0f, 0.0f ), false, - bAmbientLight, vLightAtten, - cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true, - false, 0, false, NormalizeSampler ); - -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - - float3 vDummy, specularLighting; - - // Summation of specular from all local lights - PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector), - vLightAtten, nNumLights, cLightInfo, - false, 1.0f, false, NormalizeSampler, 1.0f, false, 1.0f, - - // Outputs - specularLighting, vDummy ); - - // Specular plus diffuse, all darkened as a function of mouth openness - float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening; - -#else - float3 result = baseSample.rgb * diffuseLighting * i.worldVertToEyeVector_Darkening.w; -#endif - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); -} diff --git a/materialsystem/stdshaders/teeth_bump_vs20.fxc b/materialsystem/stdshaders/teeth_bump_vs20.fxc deleted file mode 100644 index 1dd834b5..00000000 --- a/materialsystem/stdshaders/teeth_bump_vs20.fxc +++ /dev/null @@ -1,152 +0,0 @@ -//======= Copyright 1996-2006, Valve Corporation, All rights reserved. ====== - -// STATIC: "INTRO" "0..1" -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "STATIC_LIGHT" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "vortwarp_vs20_helper.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - -const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); -#if INTRO -const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); -#define g_Time const4.w -#define modelOrigin const4.xyz -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float2 vTexCoord0 : TEXCOORD0; - float4 vUserData : TANGENT; // Sign for cross product in w - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 baseTexCoord : TEXCOORD0; - float4 worldVertToEyeVector_Darkening : TEXCOORD1; - float3x3 tangentSpaceTranspose : TEXCOORD2; - // second row : TEXCOORD3; - // third row : TEXCOORD4; - float4 worldPos_projPosZ : TEXCOORD5; - float2 lightAtten01 : TEXCOORD6; - float2 lightAtten23 : TEXCOORD7; -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - float4 vTangent; - DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), - vPosition.xyz, vNormal, vTangent.xyz ); -#endif - - // Perform skinning - float3 worldNormal, worldPos, worldTangentS, worldTangentT; - SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, - v.vBoneWeights, v.vBoneIndices, worldPos, - worldNormal, worldTangentS, worldTangentT ); - -#if INTRO - WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, worldTangentS, worldTangentT ); -#endif - - // Always normalize since flex path is controlled by runtime - // constant not a shader combo and will always generate the normalization - worldNormal = normalize( worldNormal ); - worldTangentS = normalize( worldTangentS ); - worldTangentT = normalize( worldTangentT ); - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( worldPos, vProjPos, g_FogType ); -#endif - // Needed for specular - o.worldVertToEyeVector_Darkening.xyz = cEyePos - worldPos; - - // Special darkening of lights for mouth open/close - o.worldVertToEyeVector_Darkening.w = cTeethLighting.w * saturate( dot( worldNormal, cTeethLighting.xyz ) );; - - // Scalar light attenuation (mouth darkening applied in pixel shader) -#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) - o.lightAtten01.xy = float2(0,0); - o.lightAtten23.xy = float2(0,0); - #if ( NUM_LIGHTS > 0 ) - o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, false ); - #endif - #if ( NUM_LIGHTS > 1 ) - o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, false ); - #endif - #if ( NUM_LIGHTS > 2 ) - o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, false ); - #endif - #if ( NUM_LIGHTS > 3 ) - o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, false ); - #endif -#else - o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, true ); - o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, true ); - o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, true ); - o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, true ); -#endif - - o.baseTexCoord = v.vTexCoord0; - - // Tangent space transform - o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); - o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); - o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); - - return o; -} - - diff --git a/materialsystem/stdshaders/teeth_dx6.cpp b/materialsystem/stdshaders/teeth_dx6.cpp deleted file mode 100644 index 8c097f6a..00000000 --- a/materialsystem/stdshaders/teeth_dx6.cpp +++ /dev/null @@ -1,69 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "BaseVSShader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX6 ) - -BEGIN_VS_SHADER( Teeth_DX6, - "Help for Teeth_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) - SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - LoadTexture( BASETEXTURE ); - } - - void DrawUsingSoftwareLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - } - - SHADER_DRAW - { - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - } - bool hasFlashlight = UsingFlashlight( params ); - - if( hasFlashlight ) - { - DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - } - else - { - DrawUsingSoftwareLighting( params, pShaderAPI, pShaderShadow ); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/teeth_dx8.cpp b/materialsystem/stdshaders/teeth_dx8.cpp deleted file mode 100644 index d91626d8..00000000 --- a/materialsystem/stdshaders/teeth_dx8.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "BaseVSShader.h" - -#include "teeth.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX8 ) - -BEGIN_VS_SHADER( Teeth_DX8, "Help for Teeth_DX8" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) - SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) - SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" ) - SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) - SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if( !params[INTRO]->IsDefined() ) - { - params[INTRO]->SetIntValue( 0 ); - } - } - - SHADER_FALLBACK - { - if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || g_pConfig->bSoftwareLighting ) ) - { - return "Teeth_dx6"; - } - return 0; - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - LoadTexture( BASETEXTURE ); - } - - void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 0 ); - teeth_Static_Index vshIndex; - vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - vshIndex.SetINTRO( params[INTRO]->GetIntValue() != 0 ); - pShaderShadow->SetVertexShader( "Teeth", vshIndex.GetIndex() ); - pShaderShadow->SetPixelShader( "VertexLitTexture_Overbright2" ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetAmbientCubeDynamicStateVertexShader(); - - Vector4D lighting; - params[FORWARD]->GetVecValue( lighting.Base(), 3 ); - lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); - - teeth_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if( params[INTRO]->GetIntValue() ) - { - float curTime = params[WARPPARAM]->GetFloatValue(); - float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; - Assert( params[ENTITYORIGIN]->IsDefined() ); - params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 ); - } - } - Draw(); - } - - SHADER_DRAW - { - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - } - bool hasFlashlight = UsingFlashlight( params ); - if( hasFlashlight ) - { - DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1, - // Optional parameters, specific to teeth: - true, FORWARD, ILLUMFACTOR ); - } - else - { - DrawUsingVertexShader( params, pShaderAPI, pShaderShadow ); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc b/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc deleted file mode 100644 index 7ef61872..00000000 --- a/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc +++ /dev/null @@ -1,66 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" - -sampler BaseTextureSampler : register( s0 ); -sampler SpotSampler : register( s1 ); -sampler FlashlightDepthSampler : register( s2 ); -sampler RandomRotationSampler : register( s3 ); - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float3 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float3 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); -const float4 g_FlashlightAtten : register( PSREG_FLASHLIGHT_ATTENUATION ); -const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); -const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; // Base texture coordinates - float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates - float3 vertAtten : TEXCOORD2; // Distance/spot attenuation - float4 projPos : TEXCOORD3; // Projective space position - float3 worldPos : TEXCOORD4; // Necessary for pixel fog -}; - -float4 main( PS_INPUT i ) : COLOR -{ -#if defined( SHADER_MODEL_PS_2_0 ) - float3 result = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ); -#else - float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; - float3 result = tex2D( SpotSampler, vProjCoords ); -#endif - - result *= cFlashlightColor.rgb; - -#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) - result *= DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true ); -#endif - result *= 0.35f; // Without this, unshadowed teeth always seem to glow - - result *= i.vertAtten; // Distance atten, NdotL and forward vector - - float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); - result *= baseSample.rgb; // Multiply by base map and diffuse - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); - return FinalOutput( float4( result, baseSample.a ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); -} - diff --git a/materialsystem/stdshaders/teeth_flashlight_vs20.fxc b/materialsystem/stdshaders/teeth_flashlight_vs20.fxc deleted file mode 100644 index 8c5ce4c5..00000000 --- a/materialsystem/stdshaders/teeth_flashlight_vs20.fxc +++ /dev/null @@ -1,149 +0,0 @@ -//======= Copyright 1996-2007, Valve Corporation, All rights reserved. ====== - -// STATIC: "INTRO" "0..1" - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] - -#include "vortwarp_vs20_helper.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - -const float4 cFlashlightPosition : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); -const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); -const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); -const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); -const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ - -const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_8 ); -#if INTRO -const float4 const4 : register( SHADER_SPECIFIC_CONST_9 ); -#define g_Time const4.w -#define modelOrigin const4.xyz -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float2 vTexCoord0 : TEXCOORD0; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 baseTexCoord : TEXCOORD0; // Base texture coordinates - float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates - float3 vertAtten : TEXCOORD2; // Distance/spot attenuation - float4 vProjPos : TEXCOORD3; // Projective space position - float3 worldPos : TEXCOORD4; // Necessary for pixel fog -}; - - -float RemapValClamped_01( float val, float A, float B ) -{ - float cVal = (val - A) / (B - A); - cVal = saturate( cVal ); - return cVal; -} - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - DecompressVertex_Normal( v.vNormal, vNormal ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); -#endif - - // Normalize the flexed normal - vNormal.xyz = normalize( vNormal.xyz ); - - // Transform the position - float3 worldPos, worldNormal; - SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - -#if INTRO - float3 dummy = float3( 0.0f, 0.0f, 0.0f ); - WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); -#endif - - // Transform into projection space - o.projPos = mul( float4( worldPos, 1 ), cViewProj ); - o.worldPos = worldPos.xyz; - o.vProjPos = o.projPos; -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( worldPos, o.projPos, g_FogType ); -#endif - // Spotlight texture coordinates - o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); - o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); - o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); - o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); - - // Compute vector to light - float3 vWorldPosToLightVector = cFlashlightPosition.xyz - worldPos; - - float3 vDistAtten = float3(1, 1, 1); - vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); - vDistAtten.y = rsqrt( vDistAtten.z ); - - float flDist = vDistAtten.z * vDistAtten.y; // Distance to light - vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared - - float fFarZ = cFlashlighAtten.w; - - float NdotL = saturate( dot( worldNormal, normalize( vWorldPosToLightVector ) ) ); - - float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); - o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); - - // Final attenuation from flashlight only... - float linearAtten = NdotL * dot( vDistAtten, cFlashlighAtten.xyz ) * endFalloffFactor; - - // Forward vector - float3 vForward = cTeethLighting.xyz; - float fIllumFactor = cTeethLighting.w; - - // Modulate flashlight by mouth darkening - o.vertAtten = linearAtten * fIllumFactor * saturate( dot( worldNormal, vForward ) ); - - o.baseTexCoord = v.vTexCoord0; - - return o; -} - - diff --git a/materialsystem/stdshaders/teeth_ps2x.fxc b/materialsystem/stdshaders/teeth_ps2x.fxc deleted file mode 100644 index 4893f9aa..00000000 --- a/materialsystem/stdshaders/teeth_ps2x.fxc +++ /dev/null @@ -1,48 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] - - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -#include "common_ps_fxc.h" -#include "shader_constant_register_map.h" - -sampler BaseTextureSampler : register( s0 ); - -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float3 vertAtten : TEXCOORD1; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); - - float4 result; - result.xyz = baseSample.xyz * i.vertAtten; - result.a = baseSample.a; - - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); -} diff --git a/materialsystem/stdshaders/teeth_vs20.fxc b/materialsystem/stdshaders/teeth_vs20.fxc deleted file mode 100644 index 9a9ab045..00000000 --- a/materialsystem/stdshaders/teeth_vs20.fxc +++ /dev/null @@ -1,127 +0,0 @@ -//======= Copyright 1996-2006, Valve Corporation, All rights reserved. ====== - -// STATIC: "INTRO" "0..1" -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "vortwarp_vs20_helper.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - -const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); -#if INTRO -const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); -#define g_Time const4.w -#define modelOrigin const4.xyz -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float2 vTexCoord0 : TEXCOORD0; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - -struct VS_OUTPUT -{ - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - float2 baseTexCoord : TEXCOORD0; - float3 vertAtten : TEXCOORD1; - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT ? true : false; - - float4 vPosition = v.vPos; - float3 vNormal; - DecompressVertex_Normal( v.vNormal, vNormal ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); -#endif - - // Normalize the flexed normal - vNormal.xyz = normalize( vNormal.xyz ); - - // Transform the position - float3 worldPos, worldNormal; - SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); - -#if INTRO - float3 dummy = float3( 0.0f, 0.0f, 0.0f ); - WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); -#endif - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); -#if !defined( _X360 ) - // Set fixed-function fog factor - o.fog = CalcFog( worldPos, vProjPos, g_FogType ); -#endif - - // Compute lighting -#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) - float3 linearColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false ); -#else - float3 linearColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false, NUM_LIGHTS ); -#endif - - // Forward vector - float3 vForward = cTeethLighting.xyz; - float fIllumFactor = cTeethLighting.w; - - // Darken by forward dot normal and illumination factor - linearColor *= fIllumFactor * saturate( dot( worldNormal, vForward ) ); - - o.vertAtten = linearColor; - o.baseTexCoord = v.vTexCoord0; - - return o; -} - - diff --git a/materialsystem/stdshaders/test_ps30.fxc b/materialsystem/stdshaders/test_ps30.fxc new file mode 100644 index 00000000..c0321e02 --- /dev/null +++ b/materialsystem/stdshaders/test_ps30.fxc @@ -0,0 +1,17 @@ + +struct C_INPUT +{ + float4 value; +}; + +C_INPUT g_cInput : register( c0 ); + +struct PS_INPUT +{ + float2 vUv0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return float4( 1.0f, 1.0f, 1.0f, 1.0f ); +} diff --git a/materialsystem/stdshaders/tree_sway.h b/materialsystem/stdshaders/tree_sway.h new file mode 100644 index 00000000..2bc998ad --- /dev/null +++ b/materialsystem/stdshaders/tree_sway.h @@ -0,0 +1,89 @@ +//============ Copyright (c) Valve Corporation, All rights reserved. ============ + +#ifndef _TREE_SWAY_H +#define _TREE_SWAY_H + +// Tree sway vertex animation function. Requires a number of global variables to be defined. See vertexlit_and_unlit_generic_vs20.fxc or depthwrite_vs20.fxc for details. + +// Tree sway mode 2: +// Hacks to use tree sway code on rectangular sheets of plastic/tarp attached at the four corners. +// Inverts the sway scale radius to be 1 at (0,0,0) in model space and fall off radially towards the edges of the model. +// The model is expected to be build lying in the xy plane in model space, with its center at the origin. +// Treeswaystrength should be 0 in the vmt. + +#if ( TREESWAY ) + float3 ComputeTreeSway( float3 vPositionOS, float flTime ) + { + static const float g_flWindOffsetScale = 19; + + float flWindIntensity = length( g_vWindDir ); + + // Model root position is the translation component of the model to world matrix + float3 vModelRoot = float3( cModel[0][3].x, cModel[0][3].y, cModel[0][3].z ); + + // Transform the wind direction into model space + float3 vWindDirAndIntensityOS = mul( ( float3x3 )cModel[0], float3( g_vWindDir, 0 ) ); + + float flSwayScaleHeight = saturate( ( vPositionOS.z - g_flHeight * g_flStartHeight ) / + ( ( 1.0 - g_flStartHeight ) * g_flHeight ) ); + + float flSwayScaleRadius = saturate( length( ( vPositionOS.xy ) - g_flRadius * g_flStartRadius ) / + ( ( 1.0 - g_flStartRadius ) * g_flRadius ) ); + + // Used to turn off branch sway and scrumble below the minimum sway height + float flHeightThreshold = step( 0, vPositionOS.z - g_flHeight * g_flStartHeight ); + + #if ( TREESWAY == 2 ) + { + // Works better for hanging vines + flHeightThreshold = step( vPositionOS.z - g_flHeight * g_flStartHeight, 0 ); + } + #endif + + // Scale branch motion based on how orthogonal they are + // This is what I want to compute: + // float flOrthoBranchScale = 1.0 - abs( dot( normalize( vWindDirAndIntensityOS.xyz ), float3( normalize( vPositionOS.xy ), 0 ) ) ); + // Some NV hardware (7800) will do bad things when normalizing a 0 length vector. Instead, I'm doing the dot product unnormalized + // and divide by the length of the vectors, making sure to avoid divide by 0. + float flOrthoBranchScale = abs( dot( vWindDirAndIntensityOS.xyz, float3( vPositionOS.xy, 0 ) ) ); + flOrthoBranchScale = 1.0 - saturate( flOrthoBranchScale / ( max( length( vWindDirAndIntensityOS.xyz ), 0.0001 ) * max( length( vPositionOS.xy ), 0.0001 ) ) ); + + float flSwayScaleTrunk = g_flSwayIntensity * pow( flSwayScaleHeight, g_flSwayFalloffCurve ); + float flSwayScaleBranches = g_flSwayIntensity * flOrthoBranchScale * flSwayScaleRadius * flHeightThreshold; + #if ( TREESWAY == 2 ) + { + // Looks stupid on vines + flSwayScaleBranches = 0.0; + } + #endif + float flWindTimeOffset = dot( vModelRoot.xyz, float3( 1, 1, 1 ) ) * g_flWindOffsetScale; + float flSlowSwayTime = ( flTime + flWindTimeOffset ) * g_flSwaySpeed; + + float3 vSwayPosOS = normalize( vPositionOS.xyz ); + float3 vScrumblePosOS = vSwayPosOS * g_flScrumbleWaveCount; + float flScrumbleScale = pow( flSwayScaleRadius, g_flScrumbleFalloffCurve ) * g_flScrumbleIntensity * flHeightThreshold; + + float3 vPositionOffset = float3( 0, 0, 0 ); + + // lerp between slow and fast sines based on wind speed + float flSpeedLerp = smoothstep( g_flWindSpeedLerpStart, g_flWindSpeedLerpEnd, flWindIntensity ); + float4 vABunchOfSines = sin( float4( 1.0, 2.31, g_flFastSwaySpeedScale, 2.14 * g_flFastSwaySpeedScale ) * flSlowSwayTime.xxxx ); + vABunchOfSines.xy = lerp( vABunchOfSines.xy, vABunchOfSines.zw, flSpeedLerp ); + + vPositionOffset.xyz = vWindDirAndIntensityOS * flSwayScaleTrunk * ( vABunchOfSines.x + 0.1 ); + vPositionOffset.xyz += vWindDirAndIntensityOS * flSwayScaleBranches * ( vABunchOfSines.y + 0.4 ); + + float3 vScrumbleScale = flScrumbleScale.xxx; + #if ( TREESWAY == 2 ) + { + vScrumbleScale *= float3( 0.5, 0.5, 1.0 ); + } + #endif + + vPositionOffset.xyz += flWindIntensity * ( vScrumbleScale.xyz * sin( g_flScrumbleSpeed * flTime.xxx + vScrumblePosOS.yzx + flWindTimeOffset.xxx ) ); + + return vPositionOS.xyz + vPositionOffset.xyz; + } +#endif + +#endif // _TREE_SWAY_H \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric.cpp b/materialsystem/stdshaders/unlitgeneric.cpp new file mode 100644 index 00000000..23854678 --- /dev/null +++ b/materialsystem/stdshaders/unlitgeneric.cpp @@ -0,0 +1,253 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" + +extern ConVar r_flashlight_version2; + +BEGIN_VS_SHADER( SDK_UnlitGeneric, "Help for SDK_UnlitGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( VERTEXALPHATEST, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "2D map for warping specular" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.") + SHADER_PARAM( DISTANCEALPHAFROMDETAIL, SHADER_PARAM_TYPE_BOOL, "0", "Take the distance-coded alpha mask from the detail texture.") + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( SCALEEDGESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft edges based upon resolution. 1024x768 = nominal.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( GLOW, SHADER_PARAM_TYPE_BOOL, "0", "Enable glow/shadow for distance coded textures.") + SHADER_PARAM( GLOWCOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outter glow for distance coded line art." ) + SHADER_PARAM( GLOWALPHA, SHADER_PARAM_TYPE_FLOAT, "1", "Base glow alpha amount for glows/shadows with distance alpha." ) + SHADER_PARAM( GLOWSTART, SHADER_PARAM_TYPE_FLOAT, "0.7", "start value for glow/shadow") + SHADER_PARAM( GLOWEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "end value for glow/shadow") + SHADER_PARAM( GLOWX, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset x for glow mask.") + SHADER_PARAM( GLOWY, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset y for glow mask.") + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SCALEOUTLINESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft part of the outline based upon resolution. 1024x768 = nominal.") + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + + SHADER_PARAM( GAMMACOLORREAD, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of color texture read." ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + SHADER_PARAM( RECEIVEFLASHLIGHT, SHADER_PARAM_TYPE_INTEGER, "0", "Forces this material to receive flashlights." ) + +#ifdef MAPBASE + SHADER_PARAM( ALLOWDIFFUSEMODULATION, SHADER_PARAM_TYPE_BOOL, "1", "Allow per-instance color modulation" ) + + SHADER_PARAM( ENVMAPFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC3, "[0.0 1.0 2.0]", "Min/max fresnel range and exponent for vertexlitgeneric" ) + SHADER_PARAM( BASEALPHAENVMAPMASKMINMAXEXP, SHADER_PARAM_TYPE_VEC3, "[1.0 0.0 1.0]", "" ) +#endif + + // vertexlitgeneric tree sway animation control (on unlitgeneric) + SHADER_PARAM( TREESWAY, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( TREESWAYHEIGHT, SHADER_PARAM_TYPE_FLOAT, "1000", "" ) + SHADER_PARAM( TREESWAYSTARTHEIGHT, SHADER_PARAM_TYPE_FLOAT, "0.2", "" ) + SHADER_PARAM( TREESWAYRADIUS, SHADER_PARAM_TYPE_FLOAT, "300", "" ) + SHADER_PARAM( TREESWAYSTARTRADIUS, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSPEED, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + SHADER_PARAM( TREESWAYSPEEDHIGHWINDMULTIPLIER, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( TREESWAYSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "10", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESPEED, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFREQUENCY, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.5", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPSTART, SHADER_PARAM_TYPE_FLOAT, "3", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPEND, SHADER_PARAM_TYPE_FLOAT, "6", "" ) + SHADER_PARAM( TREESWAYSTATIC, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( TREESWAYSTATICVALUES, SHADER_PARAM_TYPE_VEC2, "[0.5 0.5]", "" ) + + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = -1; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = -1; + info.m_nBumpFrame = -1; + info.m_nBumpTransform = -1; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nVertexAlphaTest = VERTEXALPHATEST; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nHDRColorScale = HDRCOLORSCALE; + info.m_nPhongExponent = -1; + info.m_nPhongExponentTexture = -1; + info.m_nDiffuseWarpTexture = -1; + info.m_nPhongWarpTexture = -1; + info.m_nPhongBoost = -1; + info.m_nPhongFresnelRanges = -1; + info.m_nPhong = -1; + info.m_nPhongTint = -1; + info.m_nPhongAlbedoTint = -1; + info.m_nSelfIllumEnvMapMask_Alpha = -1; + info.m_nAmbientOnly = -1; + info.m_nBaseMapAlphaPhongMask = -1; + info.m_nEnvmapFresnel = -1; + info.m_nSelfIllumMask = -1; + + info.m_nDistanceAlpha = DISTANCEALPHA; + info.m_nDistanceAlphaFromDetail = DISTANCEALPHAFROMDETAIL; + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nScaleEdgeSoftnessBasedOnScreenRes = SCALEEDGESOFTNESSBASEDONSCREENRES; + + info.m_nGlow = GLOW; + info.m_nGlowColor = GLOWCOLOR; + info.m_nGlowAlpha = GLOWALPHA; + info.m_nGlowStart = GLOWSTART; + info.m_nGlowEnd = GLOWEND; + info.m_nGlowX = GLOWX; + info.m_nGlowY = GLOWY; + + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + info.m_nScaleOutlineSoftnessBasedOnScreenRes = SCALEOUTLINESOFTNESSBASEDONSCREENRES; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nGammaColorRead = GAMMACOLORREAD; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + info.m_nReceiveFlashlight = RECEIVEFLASHLIGHT; + +#ifdef MAPBASE + info.m_nAllowDiffuseModulation = ALLOWDIFFUSEMODULATION; + + info.m_nEnvMapFresnelMinMaxExp = ENVMAPFRESNELMINMAXEXP; + info.m_nBaseAlphaEnvMapMaskMinMaxExp = BASEALPHAENVMAPMASKMINMAXEXP; +#endif + + info.m_nTreeSway = TREESWAY; + info.m_nTreeSwayHeight = TREESWAYHEIGHT; + info.m_nTreeSwayStartHeight = TREESWAYSTARTHEIGHT; + info.m_nTreeSwayRadius = TREESWAYRADIUS; + info.m_nTreeSwayStartRadius = TREESWAYSTARTRADIUS; + info.m_nTreeSwaySpeed = TREESWAYSPEED; + info.m_nTreeSwaySpeedHighWindMultiplier = TREESWAYSPEEDHIGHWINDMULTIPLIER; + info.m_nTreeSwayStrength = TREESWAYSTRENGTH; + info.m_nTreeSwayScrumbleSpeed = TREESWAYSCRUMBLESPEED; + info.m_nTreeSwayScrumbleStrength = TREESWAYSCRUMBLESTRENGTH; + info.m_nTreeSwayScrumbleFrequency = TREESWAYSCRUMBLEFREQUENCY; + info.m_nTreeSwayFalloffExp = TREESWAYFALLOFFEXP; + info.m_nTreeSwayScrumbleFalloffExp = TREESWAYSCRUMBLEFALLOFFEXP; + info.m_nTreeSwaySpeedLerpStart = TREESWAYSPEEDLERPSTART; + info.m_nTreeSwaySpeedLerpEnd = TREESWAYSPEEDLERPEND; + info.m_nTreeSwayStatic = TREESWAYSTATIC; + info.m_nTreeSwayStaticValues = TREESWAYSTATICVALUES; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, false, vars ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "UnlitGeneric_DX8"; + } + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, false, vars ); + } + + SHADER_DRAW + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + + //ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" ); + + //bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 ); + if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && /*!bNewFlashlightPath &&*/ pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass + { + Draw( false ); + } + else + { + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, false, vars, vertexCompression, pContextDataPtr ); + } + } +END_SHADER diff --git a/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh b/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh deleted file mode 100644 index 563845de..00000000 --- a/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh +++ /dev/null @@ -1,24 +0,0 @@ -ps.1.1 -def c0,0,0,0,.1 -def c1,0,0,0,.1 -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -; tc3 - detail texcoords -; -; c3 = outline color -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t3 ; detail mask - -mul r1,t0,t3 ; multiply - -mov r0.rgb, c3 ; color = outline color -;add r0.a, r1.a, c0.a -;cnd r0.rgb, r0.a, r0, r1 ; if ( alpha+c0 > 0.5 ) color = outline, else color = base -sub r0.a, r1.a, c1.a -cnd r0.rgb, r0.a, r1, r0 ; if ( alpha -c1 > 0.5) color=base diff --git a/materialsystem/stdshaders/unlitgeneric_dx6.cpp b/materialsystem/stdshaders/unlitgeneric_dx6.cpp deleted file mode 100644 index fc8bdf47..00000000 --- a/materialsystem/stdshaders/unlitgeneric_dx6.cpp +++ /dev/null @@ -1,310 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX6 ) -DEFINE_FALLBACK_SHADER( MonitorScreen, UnlitGeneric_DX6 ) -DEFINE_FALLBACK_SHADER( ParticleSphere, UnlitGeneric_DX6 ) -DEFINE_FALLBACK_SHADER( Predator, Predator_DX60 ) -DEFINE_FALLBACK_SHADER( Predator_DX60, UnlitGeneric_DX6 ) -DEFINE_FALLBACK_SHADER( WindowImposter, WindowImposter_DX60 ) -DEFINE_FALLBACK_SHADER( WindowImposter_DX60, UnlitGeneric_DX6 ) - -BEGIN_SHADER( UnlitGeneric_DX6, - "Help for UnlitGeneric_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - if( !params[ENVMAPTINT]->IsDefined() ) - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - if( !params[DETAILSCALE]->IsDefined() ) - params[DETAILSCALE]->SetFloatValue( 4.0f ); - - // No texture means no env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - // Get rid of the envmap if it's optional for this dx level. - if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) - { - params[ENVMAP]->SetUndefined(); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - // the second texture (if there is one) - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - LoadCubeMap( ENVMAP ); - else - LoadTexture( ENVMAP ); - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); - - if (params[ENVMAPMASK]->IsDefined()) - { - LoadTexture( ENVMAPMASK ); - } - } - } - - int GetDrawFlagsPass1(IMaterialVar** params, bool doDetail) - { - int flags = SHADER_DRAW_POSITION; - if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) - flags |= SHADER_DRAW_COLOR; - if (params[BASETEXTURE]->IsTexture()) - flags |= SHADER_DRAW_TEXCOORD0; - if (doDetail) - flags |= SHADER_DRAW_TEXCOORD1; - return flags; - } - - void SetDetailShadowState(IShaderShadow* pShaderShadow) - { - // Specifically choose overbright2, will cause mod2x here - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); - } - - void SetDetailDymamicState(IShaderShadow* pShaderShadow) - { - BindTexture( SHADER_SAMPLER1, DETAIL, FRAME ); - SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM, DETAILSCALE ); - } - - void DrawAdditiveNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) - { - SHADOW_STATE - { - SetModulationShadowState(); - SetAdditiveBlendingShadowState( ); - if (doDetail) - SetDetailShadowState(pShaderShadow); - pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); - FogToBlack(); - } - DYNAMIC_STATE - { - SetModulationDynamicState(); - if (doDetail) - SetDetailDymamicState(pShaderShadow); - } - Draw( ); - } - - void DrawAdditiveTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - SetModulationShadowState(); - SetAdditiveBlendingShadowState( BASETEXTURE, true ); - if (doDetail) - SetDetailShadowState(pShaderShadow); - pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); - FogToBlack(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - if (doDetail) - SetDetailDymamicState(pShaderShadow); - SetModulationDynamicState(); - } - Draw( ); - } - - void DrawNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) - { - SHADOW_STATE - { - SetModulationShadowState(); - SetNormalBlendingShadowState( ); - if (doDetail) - SetDetailShadowState(pShaderShadow); - pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); - FogToFogColor(); - } - DYNAMIC_STATE - { - SetModulationDynamicState(); - if (doDetail) - SetDetailDymamicState(pShaderShadow); - } - Draw( ); - } - - void DrawTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - SetModulationShadowState(); - SetNormalBlendingShadowState( BASETEXTURE, true ); - if (doDetail) - SetDetailShadowState(pShaderShadow); - pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - if (doDetail) - SetDetailDymamicState(pShaderShadow); - SetModulationDynamicState(); - } - Draw( ); - } - - SHADER_DRAW - { - bool isTextureDefined = params[BASETEXTURE]->IsTexture(); - bool hasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); - bool doFirstPass = isTextureDefined || hasVertexColor || (!params[ENVMAP]->IsTexture()); - - if (doFirstPass) - { - SHADOW_STATE - { - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - if( params[ALPHATESTREFERENCE]->IsDefined() && params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); - } - } - - if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) - { - if (!isTextureDefined) - { - bool hasDetailTexture = params[DETAIL]->IsTexture(); - DrawAdditiveNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); - } - else - { - // We can't do detail in a single pass if we're also - // colormodulating and have vertex color - bool hasDetailTexture = params[DETAIL]->IsTexture(); - bool isModulating = IsColorModulating() || IsAlphaModulating(); - bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); - DrawAdditiveTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); - if (hasDetailTexture && !onePassDetail) - { - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - } - } - else - { - if (!isTextureDefined) - { - bool hasDetailTexture = params[DETAIL]->IsTexture(); - DrawNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); - } - else - { - // We can't do detail in a single pass if we're also - // colormodulating and have vertex color - bool hasDetailTexture = params[DETAIL]->IsTexture(); - bool isModulating = IsColorModulating() || IsAlphaModulating(); - bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); - DrawTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); - if (hasDetailTexture && !onePassDetail) - { - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - } - } - } - - SHADOW_STATE - { - // Disable mod2x used by detail - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); - } - - // Second pass... - if (params[ENVMAP]->IsTexture() && - (!doFirstPass || IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) - { - if (doFirstPass || IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) - { - FixedFunctionAdditiveMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - else - { - FixedFunctionMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - } - } -END_SHADER diff --git a/materialsystem/stdshaders/unlitgeneric_dx8.cpp b/materialsystem/stdshaders/unlitgeneric_dx8.cpp deleted file mode 100644 index 19d0e169..00000000 --- a/materialsystem/stdshaders/unlitgeneric_dx8.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX8 ) - -BEGIN_VS_SHADER( UnlitGeneric_DX8, - "Help for UnlitGeneric_DX8" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) - SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") - SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) - SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") - SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") - SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") - SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") - SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) - { - return "UnlitGeneric_DX6"; - } - return 0; - } - - SHADER_INIT_PARAMS() - { - InitParamsUnlitGeneric_DX8( - BASETEXTURE, DETAILSCALE, ENVMAPOPTIONAL, - ENVMAP, ENVMAPTINT, ENVMAPMASKSCALE, - DETAILBLENDMODE ); - } - - SHADER_INIT - { - InitUnlitGeneric_DX8( BASETEXTURE, DETAIL, ENVMAP, ENVMAPMASK ); - } - - SHADER_DRAW - { - VertexShaderUnlitGenericPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, - DETAIL, DETAILSCALE, true, ENVMAP, ENVMAPFRAME, ENVMAPMASK, - ENVMAPMASKFRAME, ENVMAPMASKSCALE, ENVMAPTINT, ALPHATESTREFERENCE, - DETAILBLENDMODE, - OUTLINE, OUTLINECOLOR, OUTLINESTART0, OUTLINEEND1, SEPARATEDETAILUVS ); - } -END_SHADER - diff --git a/materialsystem/stdshaders/unlitgeneric_dx9.cpp b/materialsystem/stdshaders/unlitgeneric_dx9.cpp deleted file mode 100644 index b57474a8..00000000 --- a/materialsystem/stdshaders/unlitgeneric_dx9.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" -#include "vertexlitgeneric_dx9_helper.h" - -extern ConVar r_flashlight_version2; - -BEGIN_VS_SHADER( UnlitGeneric, "Help for UnlitGeneric" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "envmap frame number" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) - SHADER_PARAM( VERTEXALPHATEST, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) - SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) - SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) - SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) - SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) - SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "2D map for warping specular" ) - SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) - SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) - SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) - SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) - SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) - - SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) - - SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.") - SHADER_PARAM( DISTANCEALPHAFROMDETAIL, SHADER_PARAM_TYPE_BOOL, "0", "Take the distance-coded alpha mask from the detail texture.") - - SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") - SHADER_PARAM( SCALEEDGESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft edges based upon resolution. 1024x768 = nominal.") - SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); - SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); - - SHADER_PARAM( GLOW, SHADER_PARAM_TYPE_BOOL, "0", "Enable glow/shadow for distance coded textures.") - SHADER_PARAM( GLOWCOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outter glow for distance coded line art." ) - SHADER_PARAM( GLOWALPHA, SHADER_PARAM_TYPE_FLOAT, "1", "Base glow alpha amount for glows/shadows with distance alpha." ) - SHADER_PARAM( GLOWSTART, SHADER_PARAM_TYPE_FLOAT, "0.7", "start value for glow/shadow") - SHADER_PARAM( GLOWEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "end value for glow/shadow") - SHADER_PARAM( GLOWX, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset x for glow mask.") - SHADER_PARAM( GLOWY, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset y for glow mask.") - - SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") - SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) - SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") - SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") - SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") - SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") - SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") - SHADER_PARAM( SCALEOUTLINESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft part of the outline based upon resolution. 1024x768 = nominal.") - - SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) - - SHADER_PARAM( GAMMACOLORREAD, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of color texture read." ) - SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) - - SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) - SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) - SHADER_PARAM( RECEIVEFLASHLIGHT, SHADER_PARAM_TYPE_INTEGER, "0", "Forces this material to receive flashlights." ) - - END_SHADER_PARAMS - - void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlbedo = ALBEDO; - info.m_nSelfIllumTint = -1; - info.m_nDetail = DETAIL; - info.m_nDetailFrame = DETAILFRAME; - info.m_nDetailScale = DETAILSCALE; - info.m_nDetailTextureCombineMode = DETAILBLENDMODE; - info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; - info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; - - info.m_nEnvmap = ENVMAP; - info.m_nEnvmapFrame = ENVMAPFRAME; - info.m_nEnvmapMask = ENVMAPMASK; - info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; - info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; - info.m_nEnvmapTint = ENVMAPTINT; - info.m_nBumpmap = -1; - info.m_nBumpFrame = -1; - info.m_nBumpTransform = -1; - info.m_nEnvmapContrast = ENVMAPCONTRAST; - info.m_nEnvmapSaturation = ENVMAPSATURATION; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nVertexAlphaTest = VERTEXALPHATEST; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nHDRColorScale = HDRCOLORSCALE; - info.m_nPhongExponent = -1; - info.m_nPhongExponentTexture = -1; - info.m_nDiffuseWarpTexture = -1; - info.m_nPhongWarpTexture = -1; - info.m_nPhongBoost = -1; - info.m_nPhongFresnelRanges = -1; - info.m_nPhong = -1; - info.m_nPhongTint = -1; - info.m_nPhongAlbedoTint = -1; - info.m_nSelfIllumEnvMapMask_Alpha = -1; - info.m_nAmbientOnly = -1; - info.m_nBaseMapAlphaPhongMask = -1; - info.m_nEnvmapFresnel = -1; - info.m_nSelfIllumMask = -1; - - info.m_nDistanceAlpha = DISTANCEALPHA; - info.m_nDistanceAlphaFromDetail = DISTANCEALPHAFROMDETAIL; - info.m_nSoftEdges = SOFTEDGES; - info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; - info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; - info.m_nScaleEdgeSoftnessBasedOnScreenRes = SCALEEDGESOFTNESSBASEDONSCREENRES; - - info.m_nGlow = GLOW; - info.m_nGlowColor = GLOWCOLOR; - info.m_nGlowAlpha = GLOWALPHA; - info.m_nGlowStart = GLOWSTART; - info.m_nGlowEnd = GLOWEND; - info.m_nGlowX = GLOWX; - info.m_nGlowY = GLOWY; - - info.m_nOutline = OUTLINE; - info.m_nOutlineColor = OUTLINECOLOR; - info.m_nOutlineAlpha = OUTLINEALPHA; - info.m_nOutlineStart0 = OUTLINESTART0; - info.m_nOutlineStart1 = OUTLINESTART1; - info.m_nOutlineEnd0 = OUTLINEEND0; - info.m_nOutlineEnd1 = OUTLINEEND1; - info.m_nScaleOutlineSoftnessBasedOnScreenRes = SCALEOUTLINESOFTNESSBASEDONSCREENRES; - - info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; - - info.m_nLinearWrite = LINEARWRITE; - info.m_nGammaColorRead = GAMMACOLORREAD; - - info.m_nDepthBlend = DEPTHBLEND; - info.m_nDepthBlendScale = DEPTHBLENDSCALE; - info.m_nReceiveFlashlight = RECEIVEFLASHLIGHT; - } - - SHADER_INIT_PARAMS() - { - VertexLitGeneric_DX9_Vars_t vars; - SetupVars( vars ); - InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, false, vars ); - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "UnlitGeneric_DX8"; - } - return 0; - } - - SHADER_INIT - { - VertexLitGeneric_DX9_Vars_t vars; - SetupVars( vars ); - InitVertexLitGeneric_DX9( this, params, false, vars ); - } - - SHADER_DRAW - { - VertexLitGeneric_DX9_Vars_t vars; - SetupVars( vars ); - - bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 ); - if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && !bNewFlashlightPath && pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass - { - Draw( false ); - } - else - { - DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, false, vars, vertexCompression, pContextDataPtr ); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/unlitgeneric_inc.vsh b/materialsystem/stdshaders/unlitgeneric_inc.vsh deleted file mode 100644 index ac2abb7e..00000000 --- a/materialsystem/stdshaders/unlitgeneric_inc.vsh +++ /dev/null @@ -1,142 +0,0 @@ -#include "macros.vsh" - -;------------------------------------------------------------------------------ -; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform -; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform -; $SHADER_SPECIFIC_CONST_4-$SHADER_SPECIFIC_CONST_5 = Detail texture transform -;------------------------------------------------------------------------------ - -sub UnlitGeneric -{ - local( $detail ) = shift; - local( $envmap ) = shift; - local( $envmapcameraspace ) = shift; - local( $envmapsphere ) = shift; - local( $vertexcolor ) = shift; - local( $separatedetailuvs ) = shift; - - local( $worldPos, $worldNormal, $projPos, $reflectionVector ); - - ;------------------------------------------------------------------------------ - ; Vertex blending - ;------------------------------------------------------------------------------ - &AllocateRegister( \$worldPos ); - if( $envmap ) - { - &AllocateRegister( \$worldNormal ); - &SkinPositionAndNormal( $worldPos, $worldNormal ); - } - else - { - &SkinPosition( $worldPos ); - } - - ;------------------------------------------------------------------------------ - ; Transform the position from world to proj space - ;------------------------------------------------------------------------------ - - &AllocateRegister( \$projPos ); - - dp4 $projPos.x, $worldPos, $cViewProj0 - dp4 $projPos.y, $worldPos, $cViewProj1 - dp4 $projPos.z, $worldPos, $cViewProj2 - dp4 $projPos.w, $worldPos, $cViewProj3 - mov oPos, $projPos - - ;------------------------------------------------------------------------------ - ; Fog - ;------------------------------------------------------------------------------ - &CalcFog( $worldPos, $projPos ); - &FreeRegister( \$projPos ); - - if( !$envmap ) - { - &FreeRegister( \$worldPos ); - } - - ;------------------------------------------------------------------------------ - ; Texture coordinates (use world-space normal for envmap, tex transform for mask) - ;------------------------------------------------------------------------------ - dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 - dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - if ( $g_x360 ) - { - ; must write xyzw to match read in pixelshader - mov oT0.zw, $cZero - } - - if( $envmap ) - { - if( $envmapcameraspace ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - - ; transform reflection vector into view space - dp3 oT1.x, $reflectionVector, $cViewModel0 - dp3 oT1.y, $reflectionVector, $cViewModel1 - dp3 oT1.z, $reflectionVector, $cViewModel2 - if ( $g_x360 ) - { - ; must write xyzw to match read in pixelshader - mov oT1.w, $cZero - } - - &FreeRegister( \$reflectionVector ); - } - elsif( $envmapsphere ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); - - &FreeRegister( \$reflectionVector ); - } - else - { - &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); - } - - ; envmap mask - dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - if ( $g_x360 ) - { - ; must write xyzw to match read in pixelshader - mov oT2.zw, $cZero - } - - &FreeRegister( \$worldPos ); - &FreeRegister( \$worldNormal ); - } - - if( $detail ) - { - if ( $separatedetailuvs ) - { - mov oT3, $vTexCoord1 - } - else - { - dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 - dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - } - - if ( $g_x360 ) - { - ; must write xyzw to match read in pixelshader - mov oT3.zw, $cZero - } - } - - if( $vertexcolor ) - { - ; Modulation color - mul oD0, $vColor, $cModulationColor - } - else - { - ; Modulation color - mov oD0, $cModulationColor - } -} diff --git a/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc b/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc deleted file mode 100644 index dcbd43a2..00000000 --- a/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc +++ /dev/null @@ -1,47 +0,0 @@ -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - - float4 vDiffuse : COLOR0; - - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); - - o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - - o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - o.vDiffuse = 1.0f; - - return o; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc b/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc deleted file mode 100644 index e3970e87..00000000 --- a/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc +++ /dev/null @@ -1,9 +0,0 @@ -struct PS_INPUT -{ - float4 vColor0 : COLOR0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - return i.vColor0; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc b/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc deleted file mode 100644 index e4fffb83..00000000 --- a/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc +++ /dev/null @@ -1,14 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#include "common_ps_fxc.h" - -struct PS_INPUT -{ - float4 vColor0 : COLOR0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - return FinalOutput( i.vColor0, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric_ps11.fxc b/materialsystem/stdshaders/unlitgeneric_ps11.fxc deleted file mode 100644 index 071d666c..00000000 --- a/materialsystem/stdshaders/unlitgeneric_ps11.fxc +++ /dev/null @@ -1,12 +0,0 @@ -sampler TextureSampler : register( s0 ); - -struct PS_INPUT -{ - float4 vColor0 : COLOR0; - float2 vTexCoord0 : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - return i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric_ps2x.fxc b/materialsystem/stdshaders/unlitgeneric_ps2x.fxc deleted file mode 100644 index 1620638f..00000000 --- a/materialsystem/stdshaders/unlitgeneric_ps2x.fxc +++ /dev/null @@ -1,19 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -#include "common_ps_fxc.h" - -sampler TextureSampler : register( s0 ); - -struct PS_INPUT -{ - float4 vColor0 : COLOR0; - float2 vTexCoord0 : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float4 result = i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); - - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unlitgeneric_vs11.vsh b/materialsystem/stdshaders/unlitgeneric_vs11.vsh deleted file mode 100644 index b165fa7a..00000000 --- a/materialsystem/stdshaders/unlitgeneric_vs11.vsh +++ /dev/null @@ -1,23 +0,0 @@ -vs.1.1 - -# STATIC: "DETAIL" "0..1" -# STATIC: "ENVMAP" "0..1" -# STATIC: "ENVMAPCAMERASPACE" "0..0" -# STATIC: "ENVMAPSPHERE" "0..1" -# STATIC: "VERTEXCOLOR" "0..1" -# STATIC: "SEPARATEDETAILUVS" "0..1" -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" - -# can't have envmapshere or envmapcameraspace without envmap -# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) - -# can't have both envmapsphere and envmapcameraspace -# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE - -# SKIP: !$DETAIL && $SEPARATEDETAILUVS - - -#include "UnlitGeneric_inc.vsh" - -&UnlitGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, $VERTEXCOLOR, $SEPARATEDETAILUVS ); diff --git a/materialsystem/stdshaders/unlitgeneric_vs20.fxc b/materialsystem/stdshaders/unlitgeneric_vs20.fxc deleted file mode 100644 index 37249305..00000000 --- a/materialsystem/stdshaders/unlitgeneric_vs20.fxc +++ /dev/null @@ -1,91 +0,0 @@ -// STATIC: "VERTEXCOLOR" "0..1" -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" - -#include "common_vs_fxc.h" - -static const int g_FogType = DOWATERFOG; -static const bool g_bSkinning = SKINNING ? true : false; - -const float4 cBaseTextureTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -const float4 cMaskTextureTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); -const float4 cDetailTextureTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); -const float4 g_vVertexColor : register( SHADER_SPECIFIC_CONST_6 ); - -struct VS_INPUT -{ - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - -#if VERTEXCOLOR - float4 vColor : COLOR0; -#endif - - float4 vTexCoord0 : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vTexCoord0 : TEXCOORD0; - float2 vTexCoord1 : TEXCOORD1; - float2 vTexCoord2 : TEXCOORD2; - float2 vTexCoord3 : TEXCOORD3; - - float4 vColor : COLOR0; - float4 fogFactorW : COLOR1; - -#if !defined( _X360 ) - float fog : FOG; -#endif - - float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float3 worldPos; - float3 worldNormal; - - //------------------------------------------------------------------------------ - // Vertex blending - //------------------------------------------------------------------------------ - SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); - - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.vProjPos = vProjPos; - vProjPos = dot( float4( worldPos, 1 ), cViewProjZ ); - o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); - - //------------------------------------------------------------------------------ - // Fog - //------------------------------------------------------------------------------ - o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - //------------------------------------------------------------------------------ - // Texture coord transforms - //------------------------------------------------------------------------------ - o.vTexCoord0 = mul( v.vTexCoord0, (float2x4)cBaseTextureTransform ); - o.vTexCoord3 = mul( v.vTexCoord0, (float2x4)cDetailTextureTransform ); - - o.vColor = cModulationColor; - -#if VERTEXCOLOR - // 0 or 1 for g_vVertexColor.x, eliminating a bool - o.vColor = lerp( o.vColor, o.vColor * v.vColor, g_vVertexColor.x ); -#endif - - return o; -} - - - diff --git a/materialsystem/stdshaders/unlittwotexture.cpp b/materialsystem/stdshaders/unlittwotexture.cpp new file mode 100644 index 00000000..91d32f88 --- /dev/null +++ b/materialsystem/stdshaders/unlittwotexture.cpp @@ -0,0 +1,243 @@ +//===== Copyright � 1996-2007, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "cloak_blended_pass_helper.h" +#include "cpp_shader_constant_register_map.h" +#include "sdk_unlittwotexture_vs30.inc" +#include "sdk_unlittwotexture_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( UnlitTwoTexture, "Help for UnlitTwoTexture" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "second texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" ) + SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + return 0; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + LoadTexture( BASETEXTURE ); + if (params[TEXTURE2]->IsDefined()) + LoadTexture( TEXTURE2 ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Skip flashlight pass for unlit stuff + bool bNewFlashlightPath = IsX360(); + if ( bDrawStandardPass && ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && + !bNewFlashlightPath && ( pShaderAPI->InFlashlightMode() ) ) // not snapshotting && flashlight pass) + { + bDrawStandardPass = false; + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + s_pShaderShadow->EnableSRGBWrite( true ); + + // Either we've got a constant modulation or we've got a texture alpha on either texture + if ( IsAlphaModulating() || IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) || TextureIsTranslucent( BASETEXTURE, true ) || TextureIsTranslucent( TEXTURE2, true ) ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + DisableAlphaBlending( ); + } + } + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + if (IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR )) + { + flags |= VERTEX_COLOR; + } + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // If this is set, blend with the alpha channels of the textures and modulation color + bool bTranslucent = IsAlphaModulating() || IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) || TextureIsTranslucent( BASETEXTURE, true ) || TextureIsTranslucent( TEXTURE2, true ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, bTranslucent ); + SET_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps30 ); + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, TEXTURE2TRANSFORM ); + SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + int numBones = pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps30 ); + } + Draw(); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/materialsystem/stdshaders/unsharp_blur_ps2x.fxc b/materialsystem/stdshaders/unsharp_blur_ps2x.fxc deleted file mode 100644 index d3d993da..00000000 --- a/materialsystem/stdshaders/unsharp_blur_ps2x.fxc +++ /dev/null @@ -1,23 +0,0 @@ -#include "./common_ps_fxc.h" - -sampler sceneSampler : register( s0 ); - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord[4]: TEXCOORD0; -}; - -half4 main(VS_OUTPUT IN) : COLOR -{ - half4 c; - - // box filter - c = tex2D(sceneSampler, IN.TexCoord[0]) * 0.25; //0.25 = weighting over 4 samples - c += tex2D(sceneSampler, IN.TexCoord[1]) * 0.25; - c += tex2D(sceneSampler, IN.TexCoord[2]) * 0.25; - c += tex2D(sceneSampler, IN.TexCoord[3]) * 0.25; - c.a=1; - return c; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_blur_ps30.fxc b/materialsystem/stdshaders/unsharp_blur_ps30.fxc new file mode 100644 index 00000000..971ebf6a --- /dev/null +++ b/materialsystem/stdshaders/unsharp_blur_ps30.fxc @@ -0,0 +1,23 @@ +#include "common_ps_fxc.h" + +sampler sceneSampler : register( s0 ); + +// Structs +struct VS_OUTPUT +{ + float4 Position : POSITION; + float2 TexCoord[4]: TEXCOORD0; +}; + +half4 main(VS_OUTPUT IN) : COLOR +{ + half4 c; + + // box filter + c = tex2D(sceneSampler, IN.TexCoord[0]) * 0.25; //0.25 = weighting over 4 samples + c += tex2D(sceneSampler, IN.TexCoord[1]) * 0.25; + c += tex2D(sceneSampler, IN.TexCoord[2]) * 0.25; + c += tex2D(sceneSampler, IN.TexCoord[3]) * 0.25; + c.a=1; + return c; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_blur_vs20.fxc b/materialsystem/stdshaders/unsharp_blur_vs20.fxc deleted file mode 100644 index 188d54e9..00000000 --- a/materialsystem/stdshaders/unsharp_blur_vs20.fxc +++ /dev/null @@ -1,27 +0,0 @@ -// Includes -#include "./common_vs_fxc.h" - -const float WindowSize : register(SHADER_SPECIFIC_CONST_0); -const float BlurSize : register(SHADER_SPECIFIC_CONST_1); - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord[4]: TEXCOORD0; -}; - -// Main -VS_OUTPUT main(float4 Position : POSITION, - float2 TexCoord : TEXCOORD0) -{ - VS_OUTPUT OUT; - float2 texelSize = BlurSize / WindowSize; //make sure blurring is relative to screen reslution - float2 s = TexCoord; - OUT.Position = Position; - OUT.TexCoord[0] = s; - OUT.TexCoord[1] = s + float2(2, 0)*texelSize; //apply blur relativity factor - OUT.TexCoord[2] = s + float2(2, 2)*texelSize; - OUT.TexCoord[3] = s + float2(0, 2)*texelSize; - return OUT; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_blur_vs30.fxc b/materialsystem/stdshaders/unsharp_blur_vs30.fxc new file mode 100644 index 00000000..3d550c64 --- /dev/null +++ b/materialsystem/stdshaders/unsharp_blur_vs30.fxc @@ -0,0 +1,27 @@ +// Includes +#include "common_vs_fxc.h" + +const float WindowSize : register(SHADER_SPECIFIC_CONST_0); +const float BlurSize : register(SHADER_SPECIFIC_CONST_1); + +// Structs +struct VS_OUTPUT +{ + float4 Position : POSITION; + float2 TexCoord[4]: TEXCOORD0; +}; + +// Main +VS_OUTPUT main(float4 Position : POSITION, + float2 TexCoord : TEXCOORD0) +{ + VS_OUTPUT OUT; + float2 texelSize = BlurSize / WindowSize; //make sure blurring is relative to screen reslution + float2 s = TexCoord; + OUT.Position = Position; + OUT.TexCoord[0] = s; + OUT.TexCoord[1] = s + float2(2, 0)*texelSize; //apply blur relativity factor + OUT.TexCoord[2] = s + float2(2, 2)*texelSize; + OUT.TexCoord[3] = s + float2(0, 2)*texelSize; + return OUT; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_ps2x.fxc b/materialsystem/stdshaders/unsharp_ps2x.fxc deleted file mode 100644 index cb933651..00000000 --- a/materialsystem/stdshaders/unsharp_ps2x.fxc +++ /dev/null @@ -1,26 +0,0 @@ -// Includes -#include "./common_ps_fxc.h" - -sampler sceneSampler : register( s0 ); -sampler BlurredSampler : register( s1 ); - -const float UnsharpStrength : register( c0 ); - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord0 : TEXCOORD0; - float2 TexCoord1 : TEXCOORD1; -}; - -// Main -half4 main(VS_OUTPUT IN) : COLOR -{ - half4 orig = tex2D(sceneSampler, IN.TexCoord1); - half4 blur = tex2D(BlurredSampler, IN.TexCoord1); - half4 mask = orig - blur; - half4 result = orig + UnsharpStrength*mask; - result.a = orig.a; - return result; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_ps30.fxc b/materialsystem/stdshaders/unsharp_ps30.fxc new file mode 100644 index 00000000..1df83d44 --- /dev/null +++ b/materialsystem/stdshaders/unsharp_ps30.fxc @@ -0,0 +1,26 @@ +// Includes +#include "common_ps_fxc.h" + +sampler sceneSampler : register( s0 ); +sampler BlurredSampler : register( s1 ); + +const float UnsharpStrength : register( c0 ); + +// Structs +struct VS_OUTPUT +{ + float4 Position : POSITION; + float2 TexCoord0 : TEXCOORD0; + float2 TexCoord1 : TEXCOORD1; +}; + +// Main +half4 main(VS_OUTPUT IN) : COLOR +{ + half4 orig = tex2D(sceneSampler, IN.TexCoord1); + half4 blur = tex2D(BlurredSampler, IN.TexCoord1); + half4 mask = orig - blur; + half4 result = orig + UnsharpStrength*mask; + result.a = orig.a; + return result; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_vs20.fxc b/materialsystem/stdshaders/unsharp_vs20.fxc deleted file mode 100644 index b897eb21..00000000 --- a/materialsystem/stdshaders/unsharp_vs20.fxc +++ /dev/null @@ -1,25 +0,0 @@ -// Includes -#include "./common_vs_fxc.h" - -const float WindowSize : register(SHADER_SPECIFIC_CONST_0); -const float BlurSize : register(SHADER_SPECIFIC_CONST_1); - -// Structs -struct VS_OUTPUT -{ - float4 Position : POSITION; - float2 TexCoord0 : TEXCOORD0; - float2 TexCoord1 : TEXCOORD1; -}; - -// Main -VS_OUTPUT main(float4 Position : POSITION, - float2 TexCoord : TEXCOORD0) -{ - VS_OUTPUT OUT; - float2 texelSize = 1.0 / WindowSize; - OUT.Position = Position; - OUT.TexCoord0 = TexCoord + texelSize*0.5; - OUT.TexCoord1 = TexCoord + texelSize*0.5/BlurSize; - return OUT; -} \ No newline at end of file diff --git a/materialsystem/stdshaders/unsharp_vs30.fxc b/materialsystem/stdshaders/unsharp_vs30.fxc new file mode 100644 index 00000000..db8c441b --- /dev/null +++ b/materialsystem/stdshaders/unsharp_vs30.fxc @@ -0,0 +1,25 @@ +// Includes +#include "common_vs_fxc.h" + +const float WindowSize : register(SHADER_SPECIFIC_CONST_0); +const float BlurSize : register(SHADER_SPECIFIC_CONST_1); + +// Structs +struct VS_OUTPUT +{ + float4 Position : POSITION; + float2 TexCoord0 : TEXCOORD0; + float2 TexCoord1 : TEXCOORD1; +}; + +// Main +VS_OUTPUT main(float4 Position : POSITION, + float2 TexCoord : TEXCOORD0) +{ + VS_OUTPUT OUT; + float2 texelSize = 1.0 / WindowSize; + OUT.Position = Position; + OUT.TexCoord0 = TexCoord + texelSize*0.5; + OUT.TexCoord1 = TexCoord + texelSize*0.5/BlurSize; + return OUT; +} \ No newline at end of file diff --git a/materialsystem/stdshaders/vance/Bloom.cpp b/materialsystem/stdshaders/vance/Bloom.cpp deleted file mode 100644 index c2635fbe..00000000 --- a/materialsystem/stdshaders/vance/Bloom.cpp +++ /dev/null @@ -1,90 +0,0 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "SDK_screenspaceeffect_vs20.inc" -#include "SDK_Bloom_ps20.inc" -#include "SDK_Bloom_ps20b.inc" - -BEGIN_VS_SHADER_FLAGS( SDK_Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) - SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[FBTEXTURE]->IsDefined() ) - { - LoadTexture( FBTEXTURE ); - } - if( params[BLURTEXTURE]->IsDefined() ) - { - LoadTexture( BLURTEXTURE ); - } - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); - SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); - SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); - DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/vance/Bloom_combine.cpp b/materialsystem/stdshaders/vance/Bloom_combine.cpp deleted file mode 100644 index da1c24d4..00000000 --- a/materialsystem/stdshaders/vance/Bloom_combine.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "../BaseVSShader.h" - -#include "SDK_screenspaceeffect_vs30.inc" -#include "vance_bloom_combine_ps30.inc" - -BEGIN_VS_SHADER_FLAGS( Bloom_Combine, "Help for Bloom", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) - SHADER_PARAM( BLOOMTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS0", "") - SHADER_PARAM( BLOOMTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS1", "") - SHADER_PARAM( BLOOMTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS2", "") - SHADER_PARAM( BLOOMTEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS3", "") - SHADER_PARAM( AMOUNT, SHADER_PARAM_TYPE_FLOAT, "1", "") - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[FBTEXTURE]->IsDefined() ) - { - LoadTexture( FBTEXTURE ); - } - if (params[BLOOMTEXTURE]->IsDefined()) - { - LoadTexture(BLOOMTEXTURE); - } - if (params[BLOOMTEXTURE1]->IsDefined()) - { - LoadTexture(BLOOMTEXTURE1); - } - if (params[BLOOMTEXTURE2]->IsDefined()) - { - LoadTexture(BLOOMTEXTURE2); - } - if (params[BLOOMTEXTURE3]->IsDefined()) - { - LoadTexture(BLOOMTEXTURE3); - } - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true); - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - SET_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER(vance_bloom_combine_ps30); - SET_STATIC_PIXEL_SHADER(vance_bloom_combine_ps30); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BLOOMTEXTURE, -1); - BindTexture( SHADER_SAMPLER2, BLOOMTEXTURE1, -1); - BindTexture( SHADER_SAMPLER3, BLOOMTEXTURE2, -1); - BindTexture( SHADER_SAMPLER4, BLOOMTEXTURE3, -1); - - float fBlurSize[4]; - fBlurSize[0] = params[AMOUNT]->GetFloatValue(); - fBlurSize[1] = fBlurSize[2] = fBlurSize[3] = fBlurSize[0]; - pShaderAPI->SetPixelShaderConstant(0, fBlurSize); - - DECLARE_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER(vance_bloom_combine_ps30); - SET_DYNAMIC_PIXEL_SHADER(vance_bloom_combine_ps30); - } - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/vance/SSGI.cpp b/materialsystem/stdshaders/vance/SSGI.cpp deleted file mode 100644 index aaa243f7..00000000 --- a/materialsystem/stdshaders/vance/SSGI.cpp +++ /dev/null @@ -1,160 +0,0 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" -#include "IDeferredExt.h" - -#include "passthru_vs30.inc" -#include "ssgi_ps30.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar r_post_ssgi_bias("r_post_ssao_bias", "0.001"); -static ConVar r_post_ssgi_radius("r_post_ssao_radius", "5"); -static ConVar r_post_ssgi_fallof("r_post_ssao_fallof", "0.0"); -static ConVar r_post_ssgi_area("r_post_ssao_area", "0.005"); -static ConVar r_post_ssgi_strength("r_post_ssao_strength", "0.175"); -static ConVar r_post_ssgi_samples("r_post_ssao_samples", "16"); - -extern ConVar csm_enabled; - -BEGIN_VS_SHADER_FLAGS(SSGI, "Help for SSGI", SHADER_NOT_EDITABLE) -BEGIN_SHADER_PARAMS -SHADER_PARAM(DEPTHBUFFER, SHADER_PARAM_TYPE_TEXTURE, "_rt_DepthBuffer", "") -SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") -SHADER_PARAM(FRAMEBUFFER, SHADER_PARAM_TYPE_TEXTURE, "_rt_VanceHDR", "") -SHADER_PARAM(CSM, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPassCSM", "") -SHADER_PARAM(NORMAL, SHADER_PARAM_TYPE_TEXTURE, "_rt_defNormal", "") -SHADER_PARAM(POSITION, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPosition", "") -END_SHADER_PARAMS -SHADER_INIT_PARAMS() -{ - params[NOISE]->SetStringValue("shaders/bluenoise"); - params[CSM]->SetStringValue("_rt_defPassCSM"); - params[NORMAL]->SetStringValue("_rt_Normals"); - params[POSITION]->SetStringValue("_rt_defPosition"); - params[DEPTHBUFFER]->SetStringValue("_rt_DepthBuffer"); - params[FRAMEBUFFER]->SetStringValue("_rt_VanceHDR"); -} - -SHADER_INIT -{ - if (params[DEPTHBUFFER]->IsDefined()) - { - LoadTexture(DEPTHBUFFER); - } - if (params[FRAMEBUFFER]->IsDefined()) - { - LoadTexture(FRAMEBUFFER); - } - if (params[NOISE]->IsDefined()) - { - LoadTexture(NOISE); - } - if (params[CSM]->IsDefined()) - { - LoadTexture(CSM); - } - if (params[NORMAL]->IsDefined()) - { - LoadTexture(NORMAL); - } - if (params[POSITION]->IsDefined()) - { - LoadTexture(POSITION); - } -} - -SHADER_FALLBACK -{ - // Requires DX9 + above - // But for some reason some GPUs dont support the SM3 but they clearly do, probably a bug - /*if ( g_pHardwareConfig->GetDXSupportLevel() < 90 || !g_pHardwareConfig->SupportsShaderModel_3_0() ) - { - Assert( 0 ); - return "Wireframe"; - }*/ - return 0; -} - -SHADER_DRAW -{ - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites(false); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); - - pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER3, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER4, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER5, true); - - DECLARE_STATIC_VERTEX_SHADER(passthru_vs30); - SET_STATIC_VERTEX_SHADER(passthru_vs30); - - DECLARE_STATIC_PIXEL_SHADER(ssgi_ps30); - SET_STATIC_PIXEL_SHADER(ssgi_ps30); - } - - DYNAMIC_STATE - { - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions(nWidth, nHeight); - float fResolution[4]; - fResolution[0] = float(1.0 / nWidth); - fResolution[1] = float(1.0 / nHeight); - pShaderAPI->SetPixelShaderConstant(1, fResolution); - - float fTime[4]; - fTime[0] = pShaderAPI->CurrentTime(); - fTime[2] = fTime[1] = fTime[0]; - pShaderAPI->SetPixelShaderConstant(2, fTime); - - float flParams[4]; - flParams[0] = r_post_ssgi_radius.GetFloat(); - flParams[1] = 1.0f; - flParams[2] = r_post_ssgi_fallof.GetFloat(); - flParams[3] = r_post_ssgi_strength.GetFloat(); - pShaderAPI->SetPixelShaderConstant(4, flParams); - - float flParams2[4]; - flParams2[0] = r_post_ssgi_bias.GetFloat(); - flParams2[1] = r_post_ssgi_area.GetFloat(); - flParams2[2] = r_post_ssgi_samples.GetFloat(); - flParams2[3] = 0; - pShaderAPI->SetPixelShaderConstant(5, flParams2); - - float zPlanes[2] = { GetDeferredExt()->GetZDistNear(), GetDeferredExt()->GetZDistFar() }; - pShaderAPI->SetPixelShaderConstant(6, zPlanes); - - pShaderAPI->SetPixelShaderConstant(7, GetDeferredExt()->GetOriginBase()); - - pShaderAPI->SetPixelShaderConstant(8, GetDeferredExt()->m_matViewInv.Base(), 4); - pShaderAPI->SetPixelShaderConstant(12, GetDeferredExt()->m_matProjInv.Base(), 4); - pShaderAPI->SetPixelShaderConstant(16, GetDeferredExt()->m_matView.Base(), 4); - pShaderAPI->SetPixelShaderConstant(20, GetDeferredExt()->m_matProj.Base(), 4); - - BindTexture(SHADER_SAMPLER0, DEPTHBUFFER); - BindTexture(SHADER_SAMPLER1, FRAMEBUFFER); - BindTexture(SHADER_SAMPLER2, NOISE); - BindTexture(SHADER_SAMPLER3, CSM); - BindTexture(SHADER_SAMPLER4, NORMAL); - BindTexture(SHADER_SAMPLER5, POSITION); - - DECLARE_DYNAMIC_VERTEX_SHADER(passthru_vs30); - SET_DYNAMIC_VERTEX_SHADER(passthru_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(ssgi_ps30); - SET_DYNAMIC_PIXEL_SHADER(ssgi_ps30); - } - Draw(); -} -END_SHADER \ No newline at end of file diff --git a/materialsystem/stdshaders/vance/bloom.cpp b/materialsystem/stdshaders/vance/bloom.cpp new file mode 100644 index 00000000..1a0d414c --- /dev/null +++ b/materialsystem/stdshaders/vance/bloom.cpp @@ -0,0 +1,90 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" + +#include "sdk_screenspaceeffect_vs20.inc" +#include "sdk_Bloom_ps20.inc" +#include "sdk_Bloom_ps20b.inc" + +BEGIN_VS_SHADER_FLAGS( Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) + SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + if( params[BLURTEXTURE]->IsDefined() ) + { + LoadTexture( BLURTEXTURE ); + } + } + + SHADER_FALLBACK + { + // Requires DX9 + above + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); + SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); + SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); + } + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/vance/bloom_combine.cpp b/materialsystem/stdshaders/vance/bloom_combine.cpp new file mode 100644 index 00000000..4e7636a2 --- /dev/null +++ b/materialsystem/stdshaders/vance/bloom_combine.cpp @@ -0,0 +1,101 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" + +#include "sdk_screenspaceeffect_vs30.inc" +#include "vance_bloom_combine_ps30.inc" + +BEGIN_VS_SHADER_FLAGS( Bloom_Combine, "Help for Bloom", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) + SHADER_PARAM( BLOOMTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS0", "") + SHADER_PARAM( BLOOMTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS1", "") + SHADER_PARAM( BLOOMTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS2", "") + SHADER_PARAM( BLOOMTEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "_rt_BloomDS3", "") + SHADER_PARAM( AMOUNT, SHADER_PARAM_TYPE_FLOAT, "1", "") + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + if (params[BLOOMTEXTURE]->IsDefined()) + { + LoadTexture(BLOOMTEXTURE); + } + if (params[BLOOMTEXTURE1]->IsDefined()) + { + LoadTexture(BLOOMTEXTURE1); + } + if (params[BLOOMTEXTURE2]->IsDefined()) + { + LoadTexture(BLOOMTEXTURE2); + } + if (params[BLOOMTEXTURE3]->IsDefined()) + { + LoadTexture(BLOOMTEXTURE3); + } + } + + SHADER_FALLBACK + { + // Requires DX9 + above + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true); + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vance_bloom_combine_ps30 ); + SET_STATIC_PIXEL_SHADER( vance_bloom_combine_ps30 ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BLOOMTEXTURE, -1); + BindTexture( SHADER_SAMPLER2, BLOOMTEXTURE1, -1); + BindTexture( SHADER_SAMPLER3, BLOOMTEXTURE2, -1); + BindTexture( SHADER_SAMPLER4, BLOOMTEXTURE3, -1); + + float fBlurSize[4]; + fBlurSize[0] = params[AMOUNT]->GetFloatValue(); + fBlurSize[1] = fBlurSize[2] = fBlurSize[3] = fBlurSize[0]; + pShaderAPI->SetPixelShaderConstant(0, fBlurSize); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vance_bloom_combine_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( vance_bloom_combine_ps30 ); + } + Draw(); + } +END_SHADER diff --git a/materialsystem/stdshaders/vance/chromatic.cpp b/materialsystem/stdshaders/vance/chromatic.cpp index 9a060410..c951eec9 100644 --- a/materialsystem/stdshaders/vance/chromatic.cpp +++ b/materialsystem/stdshaders/vance/chromatic.cpp @@ -1,13 +1,13 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "chromatic_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -50,14 +50,11 @@ BEGIN_VS_SHADER( Chromatic_Dispersion, "Help for Chromatic Dispersion" ) pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( chromatic_ps30 ); - SET_STATIC_PIXEL_SHADER( chromatic_ps30 ); - } + DECLARE_STATIC_PIXEL_SHADER( chromatic_ps30 ); + SET_STATIC_PIXEL_SHADER( chromatic_ps30 ); } DYNAMIC_STATE @@ -66,15 +63,12 @@ BEGIN_VS_SHADER( Chromatic_Dispersion, "Help for Chromatic Dispersion" ) pShaderAPI->SetPixelShaderConstant( 0, g_const0 ); BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( chromatic_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( RADIAL, params[RADIAL]->GetIntValue() ); - SET_DYNAMIC_PIXEL_SHADER( chromatic_ps30 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( chromatic_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( RADIAL, params[RADIAL]->GetIntValue() ); + SET_DYNAMIC_PIXEL_SHADER( chromatic_ps30 ); } Draw(); } diff --git a/materialsystem/stdshaders/vance/fxaa.cpp b/materialsystem/stdshaders/vance/fxaa.cpp index 88dadaca..aa8dbd50 100644 --- a/materialsystem/stdshaders/vance/fxaa.cpp +++ b/materialsystem/stdshaders/vance/fxaa.cpp @@ -1,13 +1,13 @@ -//===== Copyright 2011, GearDev Software, All rights reserved. ======// +//===== Copyright � 2011, GearDev Software, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //=====================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "fxaa_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -59,8 +59,8 @@ BEGIN_VS_SHADER_FLAGS( FXAA, "Help for FXAA", SHADER_NOT_EDITABLE ) pShaderShadow->EnableColorWrites( true ); pShaderShadow->EnableAlphaWrites( true ); - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_STATIC_PIXEL_SHADER( fxaa_ps30 ); SET_STATIC_PIXEL_SHADER( fxaa_ps30 ); @@ -76,8 +76,8 @@ BEGIN_VS_SHADER_FLAGS( FXAA, "Help for FXAA", SHADER_NOT_EDITABLE ) BindTexture( SHADER_SAMPLER0, FRAMEBUFFER ); - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_DYNAMIC_PIXEL_SHADER( fxaa_ps30 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( QUALITY, params[QUALITY]->GetIntValue() ); diff --git a/materialsystem/stdshaders/vance/gaussian_depthaware.cpp b/materialsystem/stdshaders/vance/gaussian_depthaware.cpp index 433c57d8..f5bca605 100644 --- a/materialsystem/stdshaders/vance/gaussian_depthaware.cpp +++ b/materialsystem/stdshaders/vance/gaussian_depthaware.cpp @@ -1,14 +1,14 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "IDeferredExt.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "gaussian_depthaware_ps30.inc" ConVar r_post_ssao_blursize("r_post_ssao_blursize", "4.0", FCVAR_CHEAT); @@ -75,8 +75,8 @@ BEGIN_VS_SHADER( Gaussian_DepthAware, "Depth aware gaussian blur" ) pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_STATIC_PIXEL_SHADER(gaussian_depthaware_ps30); SET_STATIC_PIXEL_SHADER_COMBO(HORIZONTAL, params[HORIZONTAL]->GetIntValue()); @@ -105,8 +105,8 @@ BEGIN_VS_SHADER( Gaussian_DepthAware, "Depth aware gaussian blur" ) BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); BindTexture( SHADER_SAMPLER1, DEPTHBUFFER, -1); BindTexture( SHADER_SAMPLER2, NORMALS, -1); - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); pShaderAPI->SetPixelShaderConstant(2, GetDeferredExt()->m_matProjInv.Base(), 4); diff --git a/materialsystem/stdshaders/vance/gaussian_depthaware_roughness.cpp b/materialsystem/stdshaders/vance/gaussian_depthaware_roughness.cpp index 7586f784..b75024ce 100644 --- a/materialsystem/stdshaders/vance/gaussian_depthaware_roughness.cpp +++ b/materialsystem/stdshaders/vance/gaussian_depthaware_roughness.cpp @@ -1,14 +1,14 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "IDeferredExt.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "gaussian_depthaware_roughness_ps30.inc" ConVar r_post_ssr_blursize("r_post_ssr_blursize", "5.0", FCVAR_CHEAT); @@ -81,8 +81,8 @@ BEGIN_VS_SHADER( Gaussian_DepthAware_Roughness, "Depth aware gaussian blur that pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_STATIC_PIXEL_SHADER(gaussian_depthaware_roughness_ps30); SET_STATIC_PIXEL_SHADER_COMBO(HORIZONTAL, params[HORIZONTAL]->GetIntValue()); @@ -112,8 +112,8 @@ BEGIN_VS_SHADER( Gaussian_DepthAware_Roughness, "Depth aware gaussian blur that BindTexture( SHADER_SAMPLER1, DEPTHBUFFER, -1); BindTexture( SHADER_SAMPLER2, NORMALS, -1); BindTexture( SHADER_SAMPLER3, MRAO, -1); - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); pShaderAPI->SetPixelShaderConstant(2, GetDeferredExt()->m_matProjInv.Base(), 4); diff --git a/materialsystem/stdshaders/vance/gaussianx.cpp b/materialsystem/stdshaders/vance/gaussianx.cpp index e730ec30..9c2f063d 100644 --- a/materialsystem/stdshaders/vance/gaussianx.cpp +++ b/materialsystem/stdshaders/vance/gaussianx.cpp @@ -1,13 +1,13 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "gaussianx_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -50,8 +50,8 @@ BEGIN_VS_SHADER( GaussianX, "Help for Gaussian X" ) pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { @@ -85,8 +85,8 @@ BEGIN_VS_SHADER( GaussianX, "Help for Gaussian X" ) { BindTexture(SHADER_SAMPLER0, pShaderAPI->GetRenderTargetEx(0)); } - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { diff --git a/materialsystem/stdshaders/vance/gaussiany.cpp b/materialsystem/stdshaders/vance/gaussiany.cpp index b30d071b..523a897e 100644 --- a/materialsystem/stdshaders/vance/gaussiany.cpp +++ b/materialsystem/stdshaders/vance/gaussiany.cpp @@ -1,13 +1,13 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "gaussiany_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -50,14 +50,11 @@ BEGIN_VS_SHADER( GaussianY, "Help for Gaussian Y" ) pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( gaussiany_ps30 ); - SET_STATIC_PIXEL_SHADER( gaussiany_ps30 ); - } + DECLARE_STATIC_PIXEL_SHADER( gaussiany_ps30 ); + SET_STATIC_PIXEL_SHADER( gaussiany_ps30 ); } DYNAMIC_STATE @@ -85,14 +82,12 @@ BEGIN_VS_SHADER( GaussianY, "Help for Gaussian Y" ) { BindTexture(SHADER_SAMPLER0, pShaderAPI->GetRenderTargetEx(0)); } - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( gaussiany_ps30 ); - SET_DYNAMIC_PIXEL_SHADER( gaussiany_ps30 ); - } + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( gaussiany_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( gaussiany_ps30 ); } Draw(); } diff --git a/materialsystem/stdshaders/vance/light_mesh.cpp b/materialsystem/stdshaders/vance/light_mesh.cpp index 411bbb0a..32a4a1ab 100644 --- a/materialsystem/stdshaders/vance/light_mesh.cpp +++ b/materialsystem/stdshaders/vance/light_mesh.cpp @@ -4,7 +4,7 @@ // //================================================================================================== -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" #include "skydome_atmosphere_helper.h" #include "commandbuilder.h" diff --git a/materialsystem/stdshaders/light_volumetrics.cpp b/materialsystem/stdshaders/vance/light_volumetrics.cpp similarity index 99% rename from materialsystem/stdshaders/light_volumetrics.cpp rename to materialsystem/stdshaders/vance/light_volumetrics.cpp index 2bbbc8dc..03eb0e99 100644 --- a/materialsystem/stdshaders/light_volumetrics.cpp +++ b/materialsystem/stdshaders/vance/light_volumetrics.cpp @@ -1,5 +1,5 @@ -#include "BaseVSShader.h" +#include "basevsshader.h" #include "mathlib/vmatrix.h" #include "convar.h" #include "IDeferredExt.h" diff --git a/materialsystem/stdshaders/vance/lightmappedpbr.cpp b/materialsystem/stdshaders/vance/lightmappedpbr.cpp new file mode 100644 index 00000000..63ab0e99 --- /dev/null +++ b/materialsystem/stdshaders/vance/lightmappedpbr.cpp @@ -0,0 +1,116 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example shader that can be applied to models +// +//================================================================================================== + +#include "basevsshader.h" +#include "convar.h" +#include "lightmappedpbr_helper.h" +#include "lightpass_helper.h" + +#ifdef STDSHADER +BEGIN_VS_SHADER(LightmappedPBR, + "Help for LightmappedPBR") +#else +BEGIN_VS_SHADER(LightmappedPBR, + "Help for LightmappedPBR") +#endif + +BEGIN_SHADER_PARAMS +SHADER_PARAM(ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "") +SHADER_PARAM(ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap") +SHADER_PARAM(BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map") +SHADER_PARAM(SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping") + +SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") +SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") +SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") +SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") +SHADER_PARAM(AO, SHADER_PARAM_TYPE_TEXTURE, "", "") +SHADER_PARAM(EMISSIVE, SHADER_PARAM_TYPE_TEXTURE, "", "") +SHADER_PARAM(USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness") + +SHADER_PARAM(ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "Origin of the env_cubemap (for sphere projected cubemap)") +SHADER_PARAM(ENVMAPRADIUS, SHADER_PARAM_TYPE_INTEGER, "0", "Radius of the env_cubemap (for sphere projected cubemap)") +END_SHADER_PARAMS + +void SetupVars(LightmappedPBR_DX9_Vars_t& info) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nRoughness = ROUGHNESS; + info.m_nMetallic = METALLIC; + info.m_nAO = AO; + info.m_nEmissive = EMISSIVE; + info.m_nEnvmap = ENVMAP; + info.m_nBumpmap = BUMPMAP; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nBRDF = BRDF; + info.m_nUseSmoothness = USESMOOTHNESS; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nEnvmapOrigin = ENVMAPORIGIN; + info.m_nEnvmapRadius = ENVMAPRADIUS; +} + +void SetupVars(DrawLightPass_Vars_t& info) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nNoise = NOISE; + info.m_nBumpmap = BUMPMAP; + info.m_nRoughness = ROUGHNESS; + info.m_nMetallic = METALLIC; + info.m_nBumpmap2 = -1; + info.m_nBumpFrame2 = -1; + info.m_nBumpTransform2 = -1; + info.m_nBaseTexture2 = -1; + info.m_nBaseTexture2Frame = -1; + info.m_nSeamlessMappingScale = -1; + info.bModel = false; + info.m_nUseSmoothness = USESMOOTHNESS; +} + +SHADER_INIT_PARAMS() +{ + LightmappedPBR_DX9_Vars_t info; + SetupVars(info); + InitParamsLightmappedPBR_DX9(this, params, pMaterialName, info); +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT +{ + LightmappedPBR_DX9_Vars_t info; + SetupVars(info); + InitLightmappedPBR_DX9(this, params, info); +} + +SHADER_DRAW +{ + bool hasFlashlight = UsingFlashlight(params); + bool bDrawStandardPass = true; + + if (bDrawStandardPass) + { + LightmappedPBR_DX9_Vars_t info; + SetupVars(info); + DrawLightmappedPBR_DX9(this, params, pShaderAPI, pShaderShadow, hasFlashlight, info, vertexCompression, pContextDataPtr); + } + else + { + // Skip this pass! + Draw(false); + } + +} + +END_SHADER + diff --git a/materialsystem/stdshaders/vance/lightmappedpbr_helper.cpp b/materialsystem/stdshaders/vance/lightmappedpbr_helper.cpp new file mode 100644 index 00000000..e944bd4a --- /dev/null +++ b/materialsystem/stdshaders/vance/lightmappedpbr_helper.cpp @@ -0,0 +1,513 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "basevsshader.h" +#include "lightmappedpbr_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "lightmappedpbr_vs30.inc" +#include "lightmappedpbr_ps30.inc" +#include "commandbuilder.h" + +#include "IDeferredExt.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); + + +extern ConVar r_csm_bias; +extern ConVar r_csm_slopescalebias; +extern ConVar r_csm_performance; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedPBR_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + params[info.m_nBRDF]->SetStringValue("models/PBRTest/BRDF"); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + if (((info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined()) && g_pConfig->UseBumpmapping()) + // we don't need a tangent space if we have envmap without bumpmap + // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + ) + { + SET_FLAGS2(MATERIAL_VAR2_NEEDS_TANGENT_SPACES); + } + + SET_FLAGS2(MATERIAL_VAR2_LIGHTING_LIGHTMAP); + if (g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined()) + { + SET_FLAGS2(MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP); + } + + + if (info.m_nEnvmapRadius != -1 && !params[info.m_nEnvmapRadius]->IsDefined()) + params[info.m_nEnvmapRadius]->SetIntValue(-1); +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedPBR_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture(info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } + + if (info.m_nRoughness != -1 && params[info.m_nRoughness]->IsDefined()) + { + pShader->LoadTexture(info.m_nRoughness); + } + if (info.m_nMetallic != -1 && params[info.m_nMetallic]->IsDefined()) + { + pShader->LoadTexture(info.m_nMetallic); + } + if (info.m_nAO != -1 && params[info.m_nAO]->IsDefined()) + { + pShader->LoadTexture(info.m_nAO); + } + if (info.m_nEmissive != -1 && params[info.m_nEmissive]->IsDefined()) + { + pShader->LoadTexture(info.m_nEmissive); + } + if (info.m_nBRDF != -1 && params[info.m_nBRDF]->IsDefined()) + { + pShader->LoadTexture(info.m_nBRDF); + } + + if (info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined()) + { + if (!IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE)) + { + int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; + flags |= TEXTUREFLAGS_ALL_MIPS; + pShader->LoadCubeMap(info.m_nEnvmap, flags); + } + else + { + pShader->LoadTexture(info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0); + } + + if (!g_pHardwareConfig->SupportsCubeMaps()) + { + SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); + } + } + + if (g_pConfig->UseBumpmapping()) + { + if ((info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined()) + { + pShader->LoadBumpMap(info.m_nBumpmap); + SET_FLAGS2(MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL); + } + } +} + +class CLightmappedPBR_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawLightmappedPBR_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, LightmappedPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bHasRoughness = (info.m_nRoughness != -1) && params[info.m_nRoughness]->IsTexture(); + bool bHasMetallic = (info.m_nMetallic != -1) && params[info.m_nMetallic]->IsTexture(); + bool bHasAO = (info.m_nAO != -1) && params[info.m_nAO]->IsTexture(); + bool bHasEmissive = (info.m_nEmissive != -1) && params[info.m_nEmissive]->IsTexture(); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasEnvmap =(info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsTexture(); + bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); + bool bHasBump = IsTextureSet(info.m_nBumpmap, params); + bool bUseSmoothness = info.m_nUseSmoothness != -1 && params[info.m_nUseSmoothness]->GetIntValue() == 1; + bool bSeamlessMapping = ((info.m_nSeamlessMappingScale != -1) && (params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0)); + + bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool bHasVertexAlpha = IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA); + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); + bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; + + CLightmappedPBR_DX9_Context *pContextData = reinterpret_cast< CLightmappedPBR_DX9_Context *> ( *pContextDataPtr ); + if ( !pContextData ) + { + pContextData = new CLightmappedPBR_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_SPACE; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Roughness map + pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); // Metallic map + + if (bHasEnvmap) + { + pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); + if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE) + { + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER7, true); + } + } + + + if (bHasVertexColor || bHasVertexAlpha) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + } + + pShaderShadow->EnableTexture(SHADER_SAMPLER8, true); // BRDF for IBL + + pShaderShadow->EnableTexture(SHADER_SAMPLER9, true); // Ambient Occlusion + pShaderShadow->EnableTexture(SHADER_SAMPLER10, true); // Emissive map + pShaderShadow->EnableTexture(SHADER_SAMPLER11, true); // Lightmap + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 3; + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedpbr_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bHasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, bHasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); + SET_STATIC_VERTEX_SHADER( lightmappedpbr_vs30 ); + + // Assume we're only going to get in here if we support 2b + DECLARE_STATIC_PIXEL_SHADER( lightmappedpbr_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( SMOOTHNESS, bUseSmoothness ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, false ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bHasBump ); + SET_STATIC_PIXEL_SHADER( lightmappedpbr_ps30 ); + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + else // not snapshotting -- begin dynamic state + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool isEnvmapCorrected = (info.m_nEnvmapRadius != -1 && info.m_nEnvmapOrigin != -1) && (params[info.m_nEnvmapRadius]->IsDefined() && params[info.m_nEnvmapRadius]->GetIntValue() > 0) && params[info.m_nEnvmapOrigin]->IsDefined(); + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + pShader->ComputeModulationColor(color); + float flLScale = pShaderAPI->GetLightMapScaleFactor(); + color[0] *= flLScale; + color[1] *= flLScale; + color[2] *= flLScale; + pShaderAPI->SetPixelShaderConstant(20, color, 1); + + if (isEnvmapCorrected) + { + float* origin = (float*)params[info.m_nEnvmapOrigin]->GetVecValue(); + float radius = (float)params[info.m_nEnvmapRadius]->GetIntValue(); + float origin_And_Radius[4] = { origin[0], origin[1], origin[2], radius }; + pShaderAPI->SetPixelShaderConstant(21, origin_And_Radius); + } + + if( bHasBaseTexture ) + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + else + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + + if (bHasRoughness) + pShader->BindTexture(SHADER_SAMPLER1, info.m_nRoughness); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER1, TEXTURE_WHITE); + + if (bHasMetallic) + pShader->BindTexture(SHADER_SAMPLER2, info.m_nMetallic); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER2, TEXTURE_BLACK); + + if (bHasEnvmap) + pShader->BindTexture(SHADER_SAMPLER7, info.m_nEnvmap); + + if (bHasAO) + pShader->BindTexture(SHADER_SAMPLER9, info.m_nAO); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER9, TEXTURE_WHITE); + + if (bHasEmissive) + pShader->BindTexture(SHADER_SAMPLER10, info.m_nEmissive); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER10, TEXTURE_BLACK); + + pShaderAPI->BindStandardTexture(SHADER_SAMPLER11, TEXTURE_LIGHTMAP); + + ITexture *pCascadedDepthTexture = (ITexture *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_DEPTHTEXTURE ); + bool bUseCSM = pCascadedDepthTexture != NULL; + + if (!g_pConfig->m_bFastNoBump) + { + if (bHasBump) + { + pShader->BindTexture(SHADER_SAMPLER3, info.m_nBumpmap); + } + else + { + pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); + } + } + else + { + if (bHasBump) + { + pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); + } + } + + pShader->BindTexture(SHADER_SAMPLER8, info.m_nBRDF); + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + + bool bWriteDepthToAlpha = false; + bool bWriteWaterFogToAlpha = false; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedpbr_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, true); + SET_DYNAMIC_VERTEX_SHADER( lightmappedpbr_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedpbr_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CUBEMAPCORRECTED, isEnvmapCorrected ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHT_PREVIEW, pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM, bUseCSM && !bHasFlashlight ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM_PERF, MAX( 0, MIN( r_csm_performance.GetInt(), 2 ) ) ); // i just dont know anymore + SET_DYNAMIC_PIXEL_SHADER( lightmappedpbr_ps30 ); + + if (bSeamlessMapping) + { + float scale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant(VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &scale); + } + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform ); + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1); + + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + + float const* pFlashlightColor = flashlightState.m_Color; + float vPsConst[4] = { pFlashlightColor[0], pFlashlightColor[1], pFlashlightColor[2], 4.5f }; + pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_COLOR, vPsConst, 1); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + } + else + { + if ( bUseCSM ) + { + const lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); + const VMatrix worldToTexture0 = *reinterpret_cast( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0 ) ); + const Vector2D biasVar = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; + const Vector2D textureSize = { static_cast( pCascadedDepthTexture->GetMappingHeight() * 4 ), static_cast( pCascadedDepthTexture->GetMappingHeight() ) }; + + pShader->BindTexture( SHADER_SAMPLER4, pCascadedDepthTexture ); + pShaderAPI->SetPixelShaderConstant( 22, worldToTexture0.Base(), 4 ); + pShaderAPI->SetPixelShaderConstant( 26, csmData.vecLight.Base() ); + pShaderAPI->SetPixelShaderConstant( 27, csmData.light.Base() ); + pShaderAPI->SetPixelShaderConstant( 28, csmData.ambient.Base() ); + pShaderAPI->SetPixelShaderConstant( 31, biasVar.Base() ); + pShaderAPI->SetPixelShaderConstant( 32, textureSize.Base() ); + pShaderAPI->SetPixelShaderConstant( 33, csmData.sizes.Base() ); + } + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawLightmappedPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bHasFlashlight, + LightmappedPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) + +{ + DrawLightmappedPBR_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/materialsystem/stdshaders/LightmappedPBR_dx9_helper.h b/materialsystem/stdshaders/vance/lightmappedpbr_helper.h similarity index 100% rename from materialsystem/stdshaders/LightmappedPBR_dx9_helper.h rename to materialsystem/stdshaders/vance/lightmappedpbr_helper.h diff --git a/materialsystem/stdshaders/lightpass_helper.cpp b/materialsystem/stdshaders/vance/lightpass_helper.cpp similarity index 90% rename from materialsystem/stdshaders/lightpass_helper.cpp rename to materialsystem/stdshaders/vance/lightpass_helper.cpp index 29e8aac9..d24a2c25 100644 --- a/materialsystem/stdshaders/lightpass_helper.cpp +++ b/materialsystem/stdshaders/vance/lightpass_helper.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ // //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" #include "cpp_shader_constant_register_map.h" #include "lightpass_vs30.inc" @@ -219,7 +219,6 @@ void DrawLightPass(CBaseVSShader * pShader, IMaterialVar * *params, IShaderDynam // Vertex Shader DECLARE_STATIC_VERTEX_SHADER(lightpass_vs30); SET_STATIC_VERTEX_SHADER_COMBO(MODEL, bModel); - SET_STATIC_VERTEX_SHADER_COMBO(MORPHING_VTEX, bModel && bFastVTex); SET_STATIC_VERTEX_SHADER_COMBO(TANGENTSPACE, bHasBump); SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)); SET_STATIC_VERTEX_SHADER_COMBO(VERTEXALPHATEXBLENDFACTOR, bHasBaseTexture2 || bHasBump2); @@ -259,7 +258,6 @@ void DrawLightPass(CBaseVSShader * pShader, IMaterialVar * *params, IShaderDynam DECLARE_DYNAMIC_VERTEX_SHADER(lightpass_vs30); SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (bModel && (int)vertexCompression) ? 1 : 0); SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, (bModel&& pShaderAPI->GetCurrentNumBones() > 0) ? 1 : 0); - SET_DYNAMIC_VERTEX_SHADER_COMBO(MORPHING, (bModel&& pShaderAPI->IsHWMorphingEnabled()) ? 1 : 0); SET_DYNAMIC_VERTEX_SHADER(lightpass_vs30); // Set Pixel Shader Combos @@ -342,30 +340,23 @@ void DrawLightPass(CBaseVSShader * pShader, IMaterialVar * *params, IShaderDynam pShaderAPI->GetWorldSpaceCameraPosition(flEye); pShaderAPI->SetPixelShaderConstant(5, flEye); + const lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); + const VMatrix worldToTexture0 = *reinterpret_cast( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0 ) ); + const Vector2D biasVar = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; + const Vector2D textureSize = { static_cast( pCascadedDepthTexture->GetMappingHeight() * 4), static_cast( pCascadedDepthTexture->GetMappingHeight() ) }; + if (pCascadedDepthTexture) { - pShader->BindTexture(SHADER_SAMPLER8, pCascadedDepthTexture, -1); - VMatrix * worldToTexture0 = (VMatrix*)pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0); - pShaderAPI->SetPixelShaderConstant(6, worldToTexture0->Base(), 4); + pShader->BindTexture( SHADER_SAMPLER8, pCascadedDepthTexture ); + pShaderAPI->SetPixelShaderConstant( 6, worldToTexture0.Base(), 4 ); } - lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); - Vector csmFwd = csmData.vecLight; - pShaderAPI->SetPixelShaderConstant(10, csmFwd.Base()); - - Vector csmLight = csmData.light.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(11, csmLight.Base()); - - Vector csmAmbient = csmData.ambient.AsVector3D(); - pShaderAPI->SetPixelShaderConstant(12, csmAmbient.Base()); - - float biasVar[2] = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; - pShaderAPI->SetPixelShaderConstant(13, biasVar); - - float textureSize[2] = { pCascadedDepthTexture->GetActualWidth(), pCascadedDepthTexture->GetActualHeight() }; - pShaderAPI->SetPixelShaderConstant(14, textureSize); - - pShaderAPI->SetPixelShaderConstant(15, GetDeferredExt()->GetLightData_Global().sizes.Base()); + pShaderAPI->SetPixelShaderConstant( 11, csmData.vecLight.Base() ); + pShaderAPI->SetPixelShaderConstant( 12, csmData.light.Base() ); + pShaderAPI->SetPixelShaderConstant( 13, csmData.ambient.Base() ); + pShaderAPI->SetPixelShaderConstant( 14, biasVar.Base() ); + pShaderAPI->SetPixelShaderConstant( 15, textureSize.Base() ); + pShaderAPI->SetPixelShaderConstant( 16, csmData.sizes.Base() ); } pShader->Draw(); } diff --git a/materialsystem/stdshaders/lightpass_helper.h b/materialsystem/stdshaders/vance/lightpass_helper.h similarity index 100% rename from materialsystem/stdshaders/lightpass_helper.h rename to materialsystem/stdshaders/vance/lightpass_helper.h diff --git a/materialsystem/stdshaders/vance/luma.cpp b/materialsystem/stdshaders/vance/luma.cpp index 1dd8fd6d..3899a19c 100644 --- a/materialsystem/stdshaders/vance/luma.cpp +++ b/materialsystem/stdshaders/vance/luma.cpp @@ -1,13 +1,13 @@ -//===== Copyright 2011, GearDev Software, All rights reserved. ======// +//===== Copyright � 2011, GearDev Software, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //=====================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "screenspace_simple_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "luma_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! @@ -54,8 +54,8 @@ BEGIN_VS_SHADER_FLAGS( LUMA, "Help for luma", SHADER_NOT_EDITABLE ) pShaderShadow->EnableColorWrites( false ); pShaderShadow->EnableAlphaWrites( true ); - DECLARE_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_STATIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_STATIC_PIXEL_SHADER( luma_ps30 ); SET_STATIC_PIXEL_SHADER( luma_ps30 ); @@ -65,8 +65,8 @@ BEGIN_VS_SHADER_FLAGS( LUMA, "Help for luma", SHADER_NOT_EDITABLE ) { BindTexture( SHADER_SAMPLER0, FRAMEBUFFER ); - DECLARE_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( screenspace_simple_vs30 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); DECLARE_DYNAMIC_PIXEL_SHADER( luma_ps30 ); SET_DYNAMIC_PIXEL_SHADER( luma_ps30 ); diff --git a/materialsystem/stdshaders/vance/screenwater.cpp b/materialsystem/stdshaders/vance/screenwater.cpp index dad1484a..7727147d 100644 --- a/materialsystem/stdshaders/vance/screenwater.cpp +++ b/materialsystem/stdshaders/vance/screenwater.cpp @@ -1,11 +1,11 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "screenwater_vs30.inc" #include "screenwater_ps30.inc" diff --git a/materialsystem/stdshaders/vance/skydome_atmosphere.cpp b/materialsystem/stdshaders/vance/skydome_atmosphere.cpp index 2bd229b3..94dd7792 100644 --- a/materialsystem/stdshaders/vance/skydome_atmosphere.cpp +++ b/materialsystem/stdshaders/vance/skydome_atmosphere.cpp @@ -4,7 +4,7 @@ // //================================================================================================== -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" #include "skydome_atmosphere_helper.h" #include "commandbuilder.h" @@ -197,7 +197,6 @@ SHADER_DRAW // Assume we're only going to get in here if we support 2b DECLARE_STATIC_PIXEL_SHADER(skydome_ps30); - SET_STATIC_PIXEL_SHADER_COMBO(CONVERT_TO_SRGB, 0); SET_STATIC_PIXEL_SHADER(skydome_ps30); // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff diff --git a/materialsystem/stdshaders/vance/skydome_atmosphere_helper.cpp b/materialsystem/stdshaders/vance/skydome_atmosphere_helper.cpp index 5ba82966..7f36348a 100644 --- a/materialsystem/stdshaders/vance/skydome_atmosphere_helper.cpp +++ b/materialsystem/stdshaders/vance/skydome_atmosphere_helper.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ // //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "skydome_atmosphere_helper.h" #include "convar.h" #include "cpp_shader_constant_register_map.h" diff --git a/materialsystem/stdshaders/vance/ssao_combine.cpp b/materialsystem/stdshaders/vance/ssao_combine.cpp index f4a3aa4f..61721018 100644 --- a/materialsystem/stdshaders/vance/ssao_combine.cpp +++ b/materialsystem/stdshaders/vance/ssao_combine.cpp @@ -1,13 +1,13 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "SDK_screenspaceeffect_vs30.inc" +#include "sdk_screenspaceeffect_vs30.inc" #include "ssgi_combine_ps30.inc" @@ -64,14 +64,11 @@ SHADER_DRAW pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER(ssgi_combine_ps30); - SET_STATIC_PIXEL_SHADER(ssgi_combine_ps30); - } + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( ssgi_combine_ps30 ); + SET_STATIC_PIXEL_SHADER( ssgi_combine_ps30 ); } DYNAMIC_STATE @@ -92,14 +89,11 @@ SHADER_DRAW fResolution[1] = float(1.0 / nHeight); pShaderAPI->SetPixelShaderConstant(1, fResolution); - DECLARE_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER(ssgi_combine_ps30); - SET_DYNAMIC_PIXEL_SHADER(ssgi_combine_ps30); - } + DECLARE_DYNAMIC_PIXEL_SHADER( ssgi_combine_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( ssgi_combine_ps30 ); } Draw(); } diff --git a/materialsystem/stdshaders/vance/ssgi.cpp b/materialsystem/stdshaders/vance/ssgi.cpp new file mode 100644 index 00000000..aa5c0eb3 --- /dev/null +++ b/materialsystem/stdshaders/vance/ssgi.cpp @@ -0,0 +1,160 @@ +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "basevsshader.h" +#include "IDeferredExt.h" + +#include "passthru_vs30.inc" +#include "ssgi_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar r_post_ssgi_bias("r_post_ssao_bias", "0.001"); +static ConVar r_post_ssgi_radius("r_post_ssao_radius", "5"); +static ConVar r_post_ssgi_fallof("r_post_ssao_fallof", "0.0"); +static ConVar r_post_ssgi_area("r_post_ssao_area", "0.005"); +static ConVar r_post_ssgi_strength("r_post_ssao_strength", "0.175"); +static ConVar r_post_ssgi_samples("r_post_ssao_samples", "16"); + +extern ConVar csm_enabled; + +BEGIN_VS_SHADER_FLAGS(SSGI, "Help for SSGI", SHADER_NOT_EDITABLE) +BEGIN_SHADER_PARAMS +SHADER_PARAM(DEPTHBUFFER, SHADER_PARAM_TYPE_TEXTURE, "_rt_DepthBuffer", "") +SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") +SHADER_PARAM(FRAMEBUFFER, SHADER_PARAM_TYPE_TEXTURE, "_rt_VanceHDR", "") +SHADER_PARAM(CSM, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPassCSM", "") +SHADER_PARAM(NORMAL, SHADER_PARAM_TYPE_TEXTURE, "_rt_defNormal", "") +SHADER_PARAM(POSITION, SHADER_PARAM_TYPE_TEXTURE, "_rt_defPosition", "") +END_SHADER_PARAMS +SHADER_INIT_PARAMS() +{ + params[NOISE]->SetStringValue("shaders/bluenoise"); + params[CSM]->SetStringValue("_rt_defPassCSM"); + params[NORMAL]->SetStringValue("_rt_Normals"); + params[POSITION]->SetStringValue("_rt_defPosition"); + params[DEPTHBUFFER]->SetStringValue("_rt_DepthBuffer"); + params[FRAMEBUFFER]->SetStringValue("_rt_VanceHDR"); +} + +SHADER_INIT +{ + if (params[DEPTHBUFFER]->IsDefined()) + { + LoadTexture(DEPTHBUFFER); + } + if (params[FRAMEBUFFER]->IsDefined()) + { + LoadTexture(FRAMEBUFFER); + } + if (params[NOISE]->IsDefined()) + { + LoadTexture(NOISE); + } + if (params[CSM]->IsDefined()) + { + LoadTexture(CSM); + } + if (params[NORMAL]->IsDefined()) + { + LoadTexture(NORMAL); + } + if (params[POSITION]->IsDefined()) + { + LoadTexture(POSITION); + } +} + +SHADER_FALLBACK +{ + // Requires DX9 + above + // But for some reason some GPUs dont support the SM3 but they clearly do, probably a bug + /*if ( g_pHardwareConfig->GetDXSupportLevel() < 90 || !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + Assert( 0 ); + return "Wireframe"; + }*/ + return 0; +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites(false); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); + + pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER3, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER4, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER5, true); + + DECLARE_STATIC_VERTEX_SHADER(passthru_vs30); + SET_STATIC_VERTEX_SHADER(passthru_vs30); + + DECLARE_STATIC_PIXEL_SHADER(ssgi_ps30); + SET_STATIC_PIXEL_SHADER(ssgi_ps30); + } + + DYNAMIC_STATE + { + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions(nWidth, nHeight); + float fResolution[4]; + fResolution[0] = float(1.0 / nWidth); + fResolution[1] = float(1.0 / nHeight); + pShaderAPI->SetPixelShaderConstant(1, fResolution); + + float fTime[4]; + fTime[0] = pShaderAPI->CurrentTime(); + fTime[2] = fTime[1] = fTime[0]; + pShaderAPI->SetPixelShaderConstant(2, fTime); + + float flParams[4]; + flParams[0] = r_post_ssgi_radius.GetFloat(); + flParams[1] = 1.0f; + flParams[2] = r_post_ssgi_fallof.GetFloat(); + flParams[3] = r_post_ssgi_strength.GetFloat(); + pShaderAPI->SetPixelShaderConstant(4, flParams); + + float flParams2[4]; + flParams2[0] = r_post_ssgi_bias.GetFloat(); + flParams2[1] = r_post_ssgi_area.GetFloat(); + flParams2[2] = r_post_ssgi_samples.GetFloat(); + flParams2[3] = 0; + pShaderAPI->SetPixelShaderConstant(5, flParams2); + + float zPlanes[2] = { GetDeferredExt()->GetZDistNear(), GetDeferredExt()->GetZDistFar() }; + pShaderAPI->SetPixelShaderConstant(6, zPlanes); + + pShaderAPI->SetPixelShaderConstant(7, GetDeferredExt()->GetOriginBase()); + + pShaderAPI->SetPixelShaderConstant(8, GetDeferredExt()->m_matViewInv.Base(), 4); + pShaderAPI->SetPixelShaderConstant(12, GetDeferredExt()->m_matProjInv.Base(), 4); + pShaderAPI->SetPixelShaderConstant(16, GetDeferredExt()->m_matView.Base(), 4); + pShaderAPI->SetPixelShaderConstant(20, GetDeferredExt()->m_matProj.Base(), 4); + + BindTexture(SHADER_SAMPLER0, DEPTHBUFFER); + BindTexture(SHADER_SAMPLER1, FRAMEBUFFER); + BindTexture(SHADER_SAMPLER2, NOISE); + BindTexture(SHADER_SAMPLER3, CSM); + BindTexture(SHADER_SAMPLER4, NORMAL); + BindTexture(SHADER_SAMPLER5, POSITION); + + DECLARE_DYNAMIC_VERTEX_SHADER(passthru_vs30); + SET_DYNAMIC_VERTEX_SHADER(passthru_vs30); + + DECLARE_DYNAMIC_PIXEL_SHADER(ssgi_ps30); + SET_DYNAMIC_PIXEL_SHADER(ssgi_ps30); + } + Draw(); +} +END_SHADER \ No newline at end of file diff --git a/materialsystem/stdshaders/vance/tonemap.cpp b/materialsystem/stdshaders/vance/tonemap.cpp index 72762985..24155a37 100644 --- a/materialsystem/stdshaders/vance/tonemap.cpp +++ b/materialsystem/stdshaders/vance/tonemap.cpp @@ -1,14 +1,14 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" -#include "SDK_screenspaceeffect_vs30.inc" -#include "Vance_Tonemap_ps30.inc" +#include "sdk_screenspaceeffect_vs30.inc" +#include "vance_tonemap_ps30.inc" ConVar r_post_tonemap_underexposure("r_post_tonemap_underexposure", "1"); ConVar r_post_tonemap_overexposure("r_post_tonemap_overexposure", "1"); @@ -51,44 +51,38 @@ SHADER_DRAW pShaderShadow->VertexShaderVertexFormat(fmt, 1, 0, 0); // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_STATIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER(vance_tonemap_ps30); - SET_STATIC_PIXEL_SHADER(vance_tonemap_ps30); - } + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vance_tonemap_ps30 ); + SET_STATIC_PIXEL_SHADER( vance_tonemap_ps30 ); } DYNAMIC_STATE { BindTexture(SHADER_SAMPLER0, FBTEXTURE, -1); - float fOverExposure[4]; - fOverExposure[0] = r_post_tonemap_overexposure.GetFloat(); - fOverExposure[1] = fOverExposure[2] = fOverExposure[3] = fOverExposure[0]; - pShaderAPI->SetPixelShaderConstant(0, fOverExposure); - - float fUnderExposure[4]; - fUnderExposure[0] = r_post_tonemap_underexposure.GetFloat(); - fUnderExposure[1] = fUnderExposure[2] = fUnderExposure[3] = fUnderExposure[0]; - pShaderAPI->SetPixelShaderConstant(1, fUnderExposure); - - float fExposure[4]; - fExposure[0] = r_post_tonemap_exposure.GetFloat(); - fExposure[1] = fExposure[2] = fExposure[3] = fExposure[0]; - pShaderAPI->SetPixelShaderConstant(2, fExposure); - - DECLARE_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - SET_DYNAMIC_VERTEX_SHADER(sdk_screenspaceeffect_vs30); - - //if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER(vance_tonemap_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO(MODE, clamp(r_post_tonemap_mode.GetInt(), 0, 3)); - SET_DYNAMIC_PIXEL_SHADER(vance_tonemap_ps30); - } + float fOverExposure[4]; + fOverExposure[0] = r_post_tonemap_overexposure.GetFloat(); + fOverExposure[1] = fOverExposure[2] = fOverExposure[3] = fOverExposure[0]; + pShaderAPI->SetPixelShaderConstant(0, fOverExposure); + + float fUnderExposure[4]; + fUnderExposure[0] = r_post_tonemap_underexposure.GetFloat(); + fUnderExposure[1] = fUnderExposure[2] = fUnderExposure[3] = fUnderExposure[0]; + pShaderAPI->SetPixelShaderConstant(1, fUnderExposure); + + float fExposure[4]; + fExposure[0] = r_post_tonemap_exposure.GetFloat(); + fExposure[1] = fExposure[2] = fExposure[3] = fExposure[0]; + pShaderAPI->SetPixelShaderConstant(2, fExposure); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vance_tonemap_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( MODE, clamp( r_post_tonemap_mode.GetInt(), 0, 3 ) ); + SET_DYNAMIC_PIXEL_SHADER( vance_tonemap_ps30 ); } Draw(); } diff --git a/materialsystem/stdshaders/vance/unsharp.cpp b/materialsystem/stdshaders/vance/unsharp.cpp index 1917c2d5..a44def02 100644 --- a/materialsystem/stdshaders/vance/unsharp.cpp +++ b/materialsystem/stdshaders/vance/unsharp.cpp @@ -1,11 +1,11 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "unsharp_vs30.inc" #include "unsharp_ps30.inc" diff --git a/materialsystem/stdshaders/vance/unsharp_blur.cpp b/materialsystem/stdshaders/vance/unsharp_blur.cpp index a915f557..1871dbae 100644 --- a/materialsystem/stdshaders/vance/unsharp_blur.cpp +++ b/materialsystem/stdshaders/vance/unsharp_blur.cpp @@ -1,11 +1,11 @@ -//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "unsharp_blur_vs30.inc" #include "unsharp_blur_ps30.inc" diff --git a/materialsystem/stdshaders/vance/vance_scope.cpp b/materialsystem/stdshaders/vance/vance_scope.cpp new file mode 100644 index 00000000..7faa10ff --- /dev/null +++ b/materialsystem/stdshaders/vance/vance_scope.cpp @@ -0,0 +1,99 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example shader that can be applied to models +// +//================================================================================================== + +#include "basevsshader.h" +#include "convar.h" + +#include "vance_scope_ps30.inc" +#include "vance_scope_vs30.inc" + +ConVar vance_sniper_scope_dist("vance_sniper_scope_dist", "5.0"); +ConVar vance_sniper_scope_scale("vance_sniper_scope_scale", "5.0"); + +BEGIN_VS_SHADER( Scope, "VANCE Scope shader, like in insurgency or something" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( OVERLAY, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture(BASETEXTURE); + } + if (params[OVERLAY]->IsDefined()) + { + LoadTexture(OVERLAY); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableSRGBWrite(true); + pShaderShadow->EnableDepthWrites(false); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + // We need three texcoords, all in the default float2 size + pShaderShadow->VertexShaderVertexFormat(flags, 1, 0, 0); + + pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); // Base (albedo) map + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0, true); + pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Overlay + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER(vance_scope_vs30); + SET_STATIC_VERTEX_SHADER(vance_scope_vs30); + + DECLARE_STATIC_PIXEL_SHADER(vance_scope_ps30); + SET_STATIC_PIXEL_SHADER(vance_scope_ps30); + } + DYNAMIC_STATE + { + BindTexture(SHADER_SAMPLER0, BASETEXTURE, FRAME); + BindTexture(SHADER_SAMPLER1, OVERLAY); + + int numBones = pShaderAPI->GetCurrentNumBones(); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant(0, vEyePos_SpecExponent, 1); + + float settings[2] = { vance_sniper_scope_dist.GetFloat(), vance_sniper_scope_scale.GetFloat()}; + pShaderAPI->SetPixelShaderConstant(1, settings, 1); + + int width, height; + pShaderAPI->GetBackBufferDimensions(width, height); + float resolution[2] = {width, height}; + pShaderAPI->SetPixelShaderConstant(2, resolution, 1); + + // Set Vertex Shader Combos + DECLARE_DYNAMIC_VERTEX_SHADER(vance_scope_vs30); + SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, numBones > 0); + SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (int)vertexCompression); + SET_DYNAMIC_VERTEX_SHADER(vance_scope_vs30); + + DECLARE_DYNAMIC_PIXEL_SHADER(vance_scope_ps30); + SET_DYNAMIC_PIXEL_SHADER(vance_scope_ps30); + } + + Draw(); + } + +END_SHADER + diff --git a/materialsystem/stdshaders/vance/vertexlitpbr.cpp b/materialsystem/stdshaders/vance/vertexlitpbr.cpp new file mode 100644 index 00000000..8f2c0767 --- /dev/null +++ b/materialsystem/stdshaders/vance/vertexlitpbr.cpp @@ -0,0 +1,112 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example shader that can be applied to models +// +//================================================================================================== + +#include "basevsshader.h" +#include "convar.h" +#include "vertexlitpbr_helper.h" +#include "lightpass_helper.h" + +#ifdef STDSHADER +BEGIN_VS_SHADER(VertexLitPBR, + "Help for LightmappedPBR") +#else +BEGIN_VS_SHADER(VertexLitPBR, + "Help for LightmappedPBR") +#endif + +BEGIN_SHADER_PARAMS + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + + SHADER_PARAM( BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "" ) + SHADER_PARAM( NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "" ) + SHADER_PARAM( ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( AO, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( EMISSIVE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( LIGHTMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "lightmap texture--will be bound by the engine" ) + + SHADER_PARAM( USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness" ) +END_SHADER_PARAMS + +void SetupVars(VertexLitPBR_DX9_Vars_t& info) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nRoughness = ROUGHNESS; + info.m_nMetallic = METALLIC; + info.m_nAO = AO; + info.m_nEmissive = EMISSIVE; + info.m_nEnvmap = ENVMAP; + info.m_nBumpmap = BUMPMAP; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nBRDF = BRDF; + info.m_nUseSmoothness = USESMOOTHNESS; + info.m_nLightmap = LIGHTMAP; +} + +void SetupVars(DrawLightPass_Vars_t& info) +{ + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nNoise = NOISE; + info.m_nBumpmap = BUMPMAP; + info.m_nRoughness = ROUGHNESS; + info.m_nMetallic = METALLIC; + info.m_nBumpmap2 = -1; + info.m_nBumpFrame2 = -1; + info.m_nBumpTransform2 = -1; + info.m_nBaseTexture2 = -1; + info.m_nBaseTexture2Frame = -1; + info.m_nSeamlessMappingScale = -1; + info.bModel = true; + info.m_nUseSmoothness = USESMOOTHNESS; +} + +SHADER_INIT_PARAMS() +{ + VertexLitPBR_DX9_Vars_t info; + SetupVars(info); + InitParamsVertexLitPBR_DX9(this, params, pMaterialName, info); +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT +{ + VertexLitPBR_DX9_Vars_t info; + SetupVars(info); + InitVertexLitPBR_DX9(this, params, info); +} + +SHADER_DRAW +{ + bool bDrawStandardPass = true; + bool hasFlashlight = UsingFlashlight(params); + + if (bDrawStandardPass) + { + VertexLitPBR_DX9_Vars_t info; + SetupVars(info); + DrawVertexLitPBR_DX9(this, params, pShaderAPI, pShaderShadow, hasFlashlight, info, vertexCompression, pContextDataPtr); + } + else + { + // Skip this pass! + Draw(false); + } + +} + +END_SHADER + diff --git a/materialsystem/stdshaders/vance/vertexlitpbr_helper.cpp b/materialsystem/stdshaders/vance/vertexlitpbr_helper.cpp new file mode 100644 index 00000000..5abc4065 --- /dev/null +++ b/materialsystem/stdshaders/vance/vertexlitpbr_helper.cpp @@ -0,0 +1,505 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "basevsshader.h" +#include "vertexlitpbr_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "vertexlitpbr_vs30.inc" +#include "vertexlitpbr_ps30.inc" +#include "commandbuilder.h" + +#include "IDeferredExt.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +extern ConVar r_csm_bias; +extern ConVar r_csm_slopescalebias; +extern ConVar r_csm_performance; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitPBR_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + params[info.m_nBRDF]->SetStringValue("models/PBRTest/BRDF"); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + if (((info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined()) + // we don't need a tangent space if we have envmap without bumpmap + // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + ) + { + SET_FLAGS2(MATERIAL_VAR2_NEEDS_TANGENT_SPACES); + } + + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitPBR_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture(info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } + + if (info.m_nRoughness != -1 && params[info.m_nRoughness]->IsDefined()) + { + pShader->LoadTexture(info.m_nRoughness); + } + if (info.m_nMetallic != -1 && params[info.m_nMetallic]->IsDefined()) + { + pShader->LoadTexture(info.m_nMetallic); + } + if (info.m_nAO != -1 && params[info.m_nAO]->IsDefined()) + { + pShader->LoadTexture(info.m_nAO); + } + if (info.m_nEmissive != -1 && params[info.m_nEmissive]->IsDefined()) + { + pShader->LoadTexture(info.m_nEmissive); + } + if (info.m_nBRDF != -1 && params[info.m_nBRDF]->IsDefined()) + { + pShader->LoadTexture(info.m_nBRDF); + } + if (info.m_nLightmap != -1 && params[info.m_nLightmap]->IsDefined()) + { + pShader->LoadTexture(info.m_nLightmap); + } + + if (info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined()) + { + if (!IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE)) + { + int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; + flags |= TEXTUREFLAGS_ALL_MIPS; + pShader->LoadCubeMap(info.m_nEnvmap, flags); + } + else + { + pShader->LoadTexture(info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0); + } + + if (!g_pHardwareConfig->SupportsCubeMaps()) + { + SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); + } + } + + if (g_pConfig->UseBumpmapping()) + { + if ((info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined()) + { + pShader->LoadBumpMap(info.m_nBumpmap); + SET_FLAGS2(MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL); + } + } +} + +class CVertexLitPBR_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawVertexLitPBR_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, VertexLitPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bHasRoughness = (info.m_nRoughness != -1) && params[info.m_nRoughness]->IsTexture(); + bool bHasMetallic = (info.m_nMetallic != -1) && params[info.m_nMetallic]->IsTexture(); + bool bHasAO = (info.m_nAO != -1) && params[info.m_nAO]->IsTexture(); + bool bHasEmissive = (info.m_nEmissive != -1) && params[info.m_nEmissive]->IsTexture(); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasEnvmap =(info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsTexture(); + bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); + bool bHasBump = IsTextureSet(info.m_nBumpmap, params); + bool bUseSmoothness = info.m_nUseSmoothness != -1 && params[info.m_nUseSmoothness]->GetIntValue() == 1; + bool bHasLightmap = (info.m_nLightmap != -1) && params[info.m_nLightmap]->IsTexture(); + + bool bHasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool bHasVertexAlpha = IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA); + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); + bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; + + CVertexLitPBR_DX9_Context *pContextData = reinterpret_cast< CVertexLitPBR_DX9_Context *> ( *pContextDataPtr ); + if ( !pContextData ) + { + pContextData = new CVertexLitPBR_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Roughness map + pShaderShadow->EnableTexture(SHADER_SAMPLER2, true); // Metallic map + + if (bHasEnvmap) + { + pShaderShadow->EnableTexture(SHADER_SAMPLER7, true); + if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE) + { + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER7, true); + } + } + + + if (bHasVertexColor || bHasVertexAlpha) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + } + + pShaderShadow->EnableTexture(SHADER_SAMPLER8, true); // BRDF for IBL + + pShaderShadow->EnableTexture(SHADER_SAMPLER9, true); // Ambient Occlusion + pShaderShadow->EnableTexture(SHADER_SAMPLER10, true); // Emissive map + pShaderShadow->EnableTexture(SHADER_SAMPLER11, true); // Lightmap + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + userDataSize = 4; // tangent S + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord + int pTexCoordDim[3] = { 2, 2, 3 }; + int nTexCoordCount = 1; + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlitpbr_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha); + SET_STATIC_VERTEX_SHADER_COMBO(CUBEMAP, bHasEnvmap); + SET_STATIC_VERTEX_SHADER_COMBO(DONT_GAMMA_CONVERT_VERTEX_COLOR, bHasVertexColor); + SET_STATIC_VERTEX_SHADER( vertexlitpbr_vs30 ); + + // Assume we're only going to get in here if we support 2b + DECLARE_STATIC_PIXEL_SHADER( vertexlitpbr_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && !bHasFlashlight); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO(SMOOTHNESS, bUseSmoothness); + SET_STATIC_PIXEL_SHADER( vertexlitpbr_ps30 ); + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + else // not snapshotting -- begin dynamic state + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + + if( bHasBaseTexture ) + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + else + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + + if (bHasRoughness) + pShader->BindTexture(SHADER_SAMPLER1, info.m_nRoughness); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER1, TEXTURE_WHITE); + + if (bHasMetallic) + pShader->BindTexture(SHADER_SAMPLER2, info.m_nMetallic); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER2, TEXTURE_BLACK); + + if (bHasEnvmap) + pShader->BindTexture(SHADER_SAMPLER7, info.m_nEnvmap); + + if (bHasAO) + pShader->BindTexture(SHADER_SAMPLER9, info.m_nAO); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER9, TEXTURE_WHITE); + + if (bHasEmissive) + pShader->BindTexture(SHADER_SAMPLER10, info.m_nEmissive); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER10, TEXTURE_BLACK); + + if (bHasLightmap) + pShader->BindTexture(SHADER_SAMPLER11, info.m_nLightmap); + else + pShaderAPI->BindStandardTexture(SHADER_SAMPLER11, TEXTURE_WHITE); + + if (!g_pConfig->m_bFastNoBump) + { + if (bHasBump) + { + pShader->BindTexture(SHADER_SAMPLER3, info.m_nBumpmap); + } + else + { + pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); + } + } + else + { + if (bHasBump) + { + pShaderAPI->BindStandardTexture(SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT); + } + } + + pShader->BindTexture(SHADER_SAMPLER8, info.m_nBRDF); + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + bool bWriteDepthToAlpha = false; + bool bWriteWaterFogToAlpha = false; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + + ITexture *pCascadedDepthTexture = (ITexture *)pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_DEPTHTEXTURE ); + bool bUseCSM = pCascadedDepthTexture != NULL; + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlitpbr_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight()); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0); + SET_DYNAMIC_VERTEX_SHADER( vertexlitpbr_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlitpbr_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO(LIGHT_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM, bUseCSM && !bHasFlashlight ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CSM_PERF, MAX( 0, MIN( r_csm_performance.GetInt(), 2 ) ) ); // i just dont know anymore + SET_DYNAMIC_PIXEL_SHADER( vertexlitpbr_ps30 ); + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + if (!bHasFlashlight) + { + pShaderAPI->BindStandardTexture(SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED); + pShaderAPI->CommitPixelShaderLighting(PSREG_LIGHT_INFO_ARRAY); + pShaderAPI->SetPixelShaderStateAmbientLightCube(PSREG_AMBIENT_CUBE); // Force to black if not bAmbientLight + } + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1); + + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + + float const* pFlashlightColor = flashlightState.m_Color; + float vPsConst[4] = { pFlashlightColor[0], pFlashlightColor[1], pFlashlightColor[2], 4.5f }; + pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_COLOR, vPsConst, 1); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + } + else + { + if ( bUseCSM ) + { + const lightData_Global_t csmData = GetDeferredExt()->GetLightData_Global(); + const VMatrix worldToTexture0 = *reinterpret_cast( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0 ) ); + const Vector2D biasVar = { r_csm_slopescalebias.GetFloat(), r_csm_bias.GetFloat() }; + const Vector2D textureSize = { static_cast( pCascadedDepthTexture->GetMappingHeight() * 4 ), static_cast( pCascadedDepthTexture->GetMappingHeight() ) }; + + pShader->BindTexture( SHADER_SAMPLER4, pCascadedDepthTexture ); + pShaderAPI->SetPixelShaderConstant( 32, worldToTexture0.Base(), 4 ); + pShaderAPI->SetPixelShaderConstant( 36, csmData.vecLight.Base() ); + pShaderAPI->SetPixelShaderConstant( 37, csmData.light.Base() ); + pShaderAPI->SetPixelShaderConstant( 38, csmData.ambient.Base() ); + pShaderAPI->SetPixelShaderConstant( 39, biasVar.Base() ); + pShaderAPI->SetPixelShaderConstant( 40, textureSize.Base() ); + pShaderAPI->SetPixelShaderConstant( 41, csmData.sizes.Base() ); + } + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawVertexLitPBR_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bHasFlashlight, + VertexLitPBR_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) + +{ + DrawVertexLitPBR_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/materialsystem/stdshaders/VertexlitPBR_dx9_helper.h b/materialsystem/stdshaders/vance/vertexlitpbr_helper.h similarity index 100% rename from materialsystem/stdshaders/VertexlitPBR_dx9_helper.h rename to materialsystem/stdshaders/vance/vertexlitpbr_helper.h diff --git a/materialsystem/stdshaders/vance_bloom_combine_ps30.fxc b/materialsystem/stdshaders/vance_bloom_combine_ps30.fxc index 63a5b20b..842b68ac 100644 --- a/materialsystem/stdshaders/vance_bloom_combine_ps30.fxc +++ b/materialsystem/stdshaders/vance_bloom_combine_ps30.fxc @@ -1,5 +1,4 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] #define HDRTYPE HDR_TYPE_NONE #include "common_ps_fxc.h" diff --git a/materialsystem/stdshaders/vance_scope_dx9.cpp b/materialsystem/stdshaders/vance_scope_dx9.cpp deleted file mode 100644 index 193bcfab..00000000 --- a/materialsystem/stdshaders/vance_scope_dx9.cpp +++ /dev/null @@ -1,99 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#include "BaseVSShader.h" -#include "convar.h" - -#include "vance_scope_ps30.inc" -#include "vance_scope_vs30.inc" - -ConVar vance_sniper_scope_dist("vance_sniper_scope_dist", "5.0"); -ConVar vance_sniper_scope_scale("vance_sniper_scope_scale", "5.0"); - -BEGIN_VS_SHADER( Scope, "VANCE Scope shader, like in insurgency or something" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( OVERLAY, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture(BASETEXTURE); - } - if (params[OVERLAY]->IsDefined()) - { - LoadTexture(OVERLAY); - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableSRGBWrite(true); - pShaderShadow->EnableDepthWrites(false); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; - // We need three texcoords, all in the default float2 size - pShaderShadow->VertexShaderVertexFormat(flags, 1, 0, 0); - - pShaderShadow->EnableTexture(SHADER_SAMPLER0, true); // Base (albedo) map - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0, true); - pShaderShadow->EnableTexture(SHADER_SAMPLER1, true); // Overlay - - // Vertex Shader - DECLARE_STATIC_VERTEX_SHADER(vance_scope_vs30); - SET_STATIC_VERTEX_SHADER(vance_scope_vs30); - - DECLARE_STATIC_PIXEL_SHADER(vance_scope_ps30); - SET_STATIC_PIXEL_SHADER(vance_scope_ps30); - } - DYNAMIC_STATE - { - BindTexture(SHADER_SAMPLER0, BASETEXTURE, FRAME); - BindTexture(SHADER_SAMPLER1, OVERLAY); - - int numBones = pShaderAPI->GetCurrentNumBones(); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant(0, vEyePos_SpecExponent, 1); - - float settings[2] = { vance_sniper_scope_dist.GetFloat(), vance_sniper_scope_scale.GetFloat()}; - pShaderAPI->SetPixelShaderConstant(1, settings, 1); - - int width, height; - pShaderAPI->GetBackBufferDimensions(width, height); - float resolution[2] = {width, height}; - pShaderAPI->SetPixelShaderConstant(2, resolution, 1); - - // Set Vertex Shader Combos - DECLARE_DYNAMIC_VERTEX_SHADER(vance_scope_vs30); - SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, numBones > 0); - SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (int)vertexCompression); - SET_DYNAMIC_VERTEX_SHADER(vance_scope_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(vance_scope_ps30); - SET_DYNAMIC_PIXEL_SHADER(vance_scope_ps30); - } - - Draw(); - } - -END_SHADER - diff --git a/materialsystem/stdshaders/vance_tonemap_ps30.fxc b/materialsystem/stdshaders/vance_tonemap_ps30.fxc new file mode 100644 index 00000000..18a72667 --- /dev/null +++ b/materialsystem/stdshaders/vance_tonemap_ps30.fxc @@ -0,0 +1,81 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [= g_pHardwareConfig->NeedsShaderSRGBConversion()] + +// DYNAMIC: "MODE" "0..3" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler FBSampler : register( s0 ); + +float m_flOverExposure : register(c0); +float m_flUnderExposure : register(c1); +float m_flExposure : register(c2); + +struct PS_INPUT +{ + float2 texCoord : TEXCOORD0; +}; + +float3 toHDR(float3 color) +{ + float3 underExposure = color / m_flUnderExposure; + float3 overExposure = color * m_flOverExposure; + + float3 hdrImage = lerp(underExposure, overExposure, color); + return hdrImage; +} + +float3 sRGBCorrect(float3 color) +{ + return pow(color, 1.0f / 2.2f); +} + +float3 getExposure(float3 color) +{ + float3 retColor = color * m_flExposure; + return retColor; +} + +float3 Burgess(float3 input) +{ + float3 x = max(0,input-0.004); + float3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06); + + return retColor; +} + +float3 Reinhard(float3 x) +{ + float3 retColor = x / (x + 1); + + return pow(retColor, 1/2.2f); +} + +float3 ACES(float3 x) +{ + float a = 2.51f; + float b = 0.03f; + float c = 2.43f; + float d = 0.59f; + float e = 0.14f; + float3 retColor = saturate((x*(a*x+b))/(x*(c*x+d)+e)); + return sRGBCorrect(retColor); +} + +float4 main( PS_INPUT i ) : COLOR +{ + float3 fbSample = tex2D( FBSampler, i.texCoord ).rgb; + + float3 retColor = getExposure(fbSample); + retColor = toHDR(retColor); +#if MODE == 1 + retColor = ACES(retColor); +#elif MODE == 2 + retColor = Reinhard(retColor); +#elif MODE == 3 + retColor = Burgess(retColor); +#else + retColor = sRGBCorrect(retColor); +#endif + return FinalOutput( float4( retColor, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/materialsystem/shader_dll_verify.cpp b/materialsystem/stdshaders/verification/shader_dll_verify.cpp similarity index 100% rename from materialsystem/shader_dll_verify.cpp rename to materialsystem/stdshaders/verification/shader_dll_verify.cpp diff --git a/materialsystem/shader_dll_verify.h b/materialsystem/stdshaders/verification/shader_dll_verify.h similarity index 100% rename from materialsystem/shader_dll_verify.h rename to materialsystem/stdshaders/verification/shader_dll_verify.h diff --git a/materialsystem/stdshaders/vertexlitPBR_ps30.fxc b/materialsystem/stdshaders/vertexlitPBR_ps30.fxc deleted file mode 100644 index ac6cca4b..00000000 --- a/materialsystem/stdshaders/vertexlitPBR_ps30.fxc +++ /dev/null @@ -1,484 +0,0 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example pixel shader that can be applied to models -// -//================================================================================================== - -// STATIC: "CONVERT_TO_SRGB" "0..0" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" -// STATIC: "SMOOTHNESS" "0..1" - -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..4" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" -// DYNAMIC: "LIGHTMAP" "0..1" -// DYNAMIC: "CSM" "0..1" -// DYNAMIC: "CSM_PERF" "0..2" -// DYNAMIC: "LIGHT_PREVIEW" "0..2" - -// We don't care about those in the editor -// SKIP: ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW - -// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) - -// SKIP: ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) - -// both cant exist at the same time -// SKIP: ( $FLASHLIGHT == 1) && ( $CSM == 1) - -// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) - -// SKIP: ($CUBEMAP || FLASHLIGHT ) - -#include "common_flashlight_fxc.h" -#include "shader_constant_register_map.h" -#include "common_pbr.h" -#include "deferred_shadows.h" - -#ifdef NV3X - #define PSHADER_VECT_SCALE 20.0 - #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) -#else - #define PSHADER_VECT_SCALE 1.0 - #define VSHADER_VECT_SCALE 1.0 -#endif - -const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); -const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); -const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); -const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); -const float4 g_FogParams : register( PSREG_FOG_PARAMS ); -#if FLASHLIGHT == 1 -sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler -sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers -sampler FlashlightSampler : register( s6 ); // Flashlight cookie - -const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass -const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); -const float4 g_FlashlightColor : register( PSREG_FLASHLIGHT_COLOR ); -const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); -#elif CSM == 1 -sampler ShadowDepthSampler : register( s4 ); // CSM Depth - -const float4x4 g_CSMWorldToTexture : register( c32 ); -const float4 g_CascadeFwd : register( c36 ); -const float4 g_CascadeLight : register( c37 ); -const float4 g_CascadeAmbient : register( c38 ); -const float2 g_CascadeBias : register( c39 ); -const float2 g_CascadeResolution : register( c40 ); -const float4 g_CascadeSize : register( c41 ); -#endif -PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) - -#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz - -sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha -sampler RoughnessSampler : register( s1 ); // Roughness -sampler MetallicSampler : register( s2 ); // Metallic -sampler BumpmapSampler : register( s3 ); // Bump map - - - -sampler EnvmapSampler : register( s7 ); // for IBL -sampler BRDFSampler : register( s8 ); // for IBL -sampler AOSampler : register( s9 ); // AO -sampler EmissiveSampler : register( s10 ); // Emissive map -sampler LightmapSampler : register( s11 ); // Lightmap texture from the engine - -//DoPBRLight(float3 vWorldPos, float3 vWorldNormal, float3 albedo, float3 vPosition, float3 vColor, float3 vEye, float atten_radius, float3 metallic, float3 roughness) -float3 DoPBRLights(float3 vEye, float3 vWorldNormal, float3 vWorldPos, float4 albedo, float4 atten, float3 lightmap, float metallic, float roughness) -{ - float3 linearColor = 0.0; - -#if LIGHTMAP ==0 - if ( NUM_LIGHTS > 0 ) - { - linearColor += DoPBRLight(vWorldPos, vWorldNormal, albedo, cLightInfo[0].pos, cLightInfo[0].color.rgb, vEye, atten.x, metallic, roughness); - if ( NUM_LIGHTS > 1 ) - { - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[1].pos, cLightInfo[1].color.rgb, vEye, atten.x, metallic, roughness); - if ( NUM_LIGHTS > 2 ) - { - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[2].pos, cLightInfo[2].color.rgb, vEye, atten.x, metallic, roughness); - if ( NUM_LIGHTS > 3 ) - { - // Unpack the 4th light's data from tight constant packing - float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, vLight3Pos, vLight3Color, vEye, atten.x, metallic, roughness); - } - } - } - } - #else - if ( NUM_LIGHTS > 0 ) - { - float lightmap_atten = dot(lightmap, cLightInfo[0].color.rgb); - lightmap_atten = lightmap_atten * lightmap_atten * 2.0f; - linearColor += DoPBRLight(vWorldPos, vWorldNormal, albedo, cLightInfo[0].pos, cLightInfo[0].color.rgb, vEye, lightmap_atten, metallic, roughness); - if ( NUM_LIGHTS > 1 ) - { - lightmap_atten = dot(lightmap, cLightInfo[1].color.rgb); - lightmap_atten = lightmap_atten * lightmap_atten * 2.0f; - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[1].pos, cLightInfo[1].color.rgb, vEye, lightmap_atten, metallic, roughness); - if ( NUM_LIGHTS > 2 ) - { - lightmap_atten = dot(lightmap, cLightInfo[2].color.rgb); - lightmap_atten = lightmap_atten * lightmap_atten * 2.0f; - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[2].pos, cLightInfo[2].color.rgb, vEye,lightmap_atten, metallic, roughness); - if ( NUM_LIGHTS > 3 ) - { - // Unpack the 4th light's data from tight constant packing - float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - lightmap_atten = dot(lightmap, vLight3Color); - lightmap_atten = lightmap_atten * lightmap_atten * 2.0f; - linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, vLight3Pos, vLight3Color, vEye, lightmap_atten, metallic, roughness); - } - } - } - } - #endif - - return linearColor; -} - -// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile -half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV ) -{ - const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; - const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; - half4 r = Roughness * c0 + c1; - half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; - half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw; - return SpecularColor * AB.x + AB.y; -} - -float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness) -{ - return F0 + (max(1.0f.xxx - roughness, F0) - F0) * pow(1.0 - cosTheta, 5.0); -} - -float3 DoIBL(float3 vEye, float3 vWorldNormal, float3 vWorldPos, float2 screenUV, float3 albedo, float metallness, float roughness, float3 lightmap) -{ - float3 metallic = clamp(metallness, 0.0f, 0.9f); -#if CUBEMAP == 1 - float3 V = normalize( vEye - vWorldPos ); - float3 N = normalize( vWorldNormal ); - - //precompute dots - float NV = max(0.0,dot(N, V)); - - HALF3 reflectVect = 2.0 * NV * N - V; - float4 directionPosX = { 1.0f, 0.01f, 0.01f, 12.0f }; float4 directionNegX = {-1.0f, 0.01f, 0.01f, 12.0f }; - float4 directionPosY = { 0.01f, 1.0f, 0.01f, 12.0f }; float4 directionNegY = { 0.01f,-1.0f, 0.01f, 12.0f }; - float4 directionPosZ = { 0.01f, 0.01f, 1.0f, 12.0f }; float4 directionNegZ = { 0.01f, 0.01f,-1.0f, 12.0f }; - float3 lookupPosX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosX); - float3 lookupNegX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegX); - float3 lookupPosY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosY); - float3 lookupNegY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegY); - float3 lookupPosZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosZ); - float3 lookupNegZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegZ); - float3 envmapCube[6] = { lookupPosX, lookupNegX, lookupPosY, lookupNegY, lookupPosZ, lookupNegZ }; - -#if LIGHTMAP == 0 - float3 irradiance = PixelShaderAmbientLight( N, cAmbientCube ); -#else - float3 irradiance = lightmap; -#endif - - float3 f0 = 0.04f.xxx; - f0 = lerp(f0, albedo.rgb, metallic); - float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term - - half3 BRDF = EnvBRDFApprox(f0, roughness, NV); - - float3 kD = 1.0f.xxx - F; - kD *= 1.0 - metallic; - - float3 diffuseIBL = kD * albedo * irradiance; - float3 lookup = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, float4(reflectVect, roughness * 12.0)).rgb; - float3 specularIrradiance = lerp(lookup, PixelShaderAmbientLight( reflectVect, envmapCube ), roughness * roughness ); - float3 specularIBL = BRDF * specularIrradiance; - //mix - return max(0.0, diffuseIBL + specularIBL); -#else - - float3 V = normalize( vEye - vWorldPos ); - float3 N = normalize( vWorldNormal ); - - //precompute dots - float NV = max(0.0,dot(N, V)); - -#if LIGHTMAP == 0 - float3 irradiance = PixelShaderAmbientLight( N, cAmbientCube ); -#else - float3 irradiance = lightmap; -#endif - - float3 f0 = 0.04f.xxx; - f0 = lerp(f0, albedo.rgb, metallic); - float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term - - float3 kD = 1.0f.xxx - F; - kD *= 1.0 - metallic; - - float3 diffuseIBL = kD * albedo * irradiance; - - return max(0.0, diffuseIBL); -#endif -} - -#if FLASHLIGHT == 1 -float3 DoFlashlight(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallic, float roughness) -{ - float4 flashlightSpacePosition = mul( float4(vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flashlightColor = tex2D( FlashlightSampler, vProjCoords); - float3 shadow = 1.0f; - #if FLASHLIGHTSHADOWS - shadow = tex2DprojBicubic(ShadowDepthSampler, 512.0f.xx, vProjCoords.xy, vProjCoords.z); - #endif - float2 dist = float2(length(g_FlashlightPos_RimBoost.xyz - vWorldPos), dot(g_FlashlightPos_RimBoost.xyz - vWorldPos,g_FlashlightPos_RimBoost.xyz - vWorldPos)); - float fAtten = saturate( dot( g_FlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/dist.x, 1.0f/dist.y ) ) ); - float3 light = DoPBRLight( vWorldPos, vWorldNormal, albedo, g_FlashlightPos_RimBoost.xyz, flashlightColor.rgb * g_FlashlightColor.xyz, g_EyePos.xyz, shadow * fAtten * g_FlashlightColor.w, metallic, roughness); - return light; -} -#elif CSM == 1 -float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) -{ - float2 rtSize = g_CascadeResolution;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; - float fEpsilonX = 1.0f / rtSize.y; - float fEpsilonY = 1.0f / rtSize.x; - -#if CSM_PERF < 1 - float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); - float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); -#endif -#if CSM_PERF < 2 - float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); -#endif - float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); - - float projMask = 1.0f; - if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) - { - projMask = 0.0f; - } - - float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); -#if CSM_PERF < 1 - float shadowProjDiff0 = 1; - float3 shadowMapCenter_objDepth0 = cascade0; - float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; - float objDepth0 = shadowMapCenter_objDepth0.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff0; - float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); - - float shadowProjDiff1 = g_CascadeSize.y; - float3 shadowMapCenter_objDepth1 = cascade1; - float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; - float objDepth1 = shadowMapCenter_objDepth1.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff1; - float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); -#endif - -#if CSM_PERF < 2 - float shadowProjDiff2 = g_CascadeSize.z; - float3 shadowMapCenter_objDepth2 = cascade2; - float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; - float objDepth2 = shadowMapCenter_objDepth2.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff2; - float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); -#endif - - float shadowProjDiff3 = g_CascadeSize.w; - float3 shadowMapCenter_objDepth3 = cascade3; - float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; - float objDepth3 = shadowMapCenter_objDepth3.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff3; - float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); - - /*float shadow0 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); - float shadow1 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow2 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); - float shadow3 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3);*/ - - float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); - -#if CSM_PERF < 2 - float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); -#else - float shadow2 = shadow3; -#endif - -#if CSM_PERF < 1 - float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); - float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); -#else - float shadow1 = shadow2; - float shadow0 = shadow2; -#endif - - - /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); - float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); - float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); - float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); - - float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); - float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); - float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); - float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ - - - float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); - float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); - float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); - - float shadow = shadow0123; - - if(projMask == 1.0f) - { - float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); - float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); - return shadowFinal; - } - else - { - return 1.0f; - } - -} - -float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) -{ - float3 Out; - float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); - float4 flashlightSpacePosition = mul(float4(worldPos, 1.0f), g_CSMWorldToTexture); - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); - float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); - diffuse = saturate(diffuse); - - Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); - return Out; -} -#endif - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - float4 lightAtten : TEXCOORD1; - float3 worldNormal : TEXCOORD2; - float3 worldPos : TEXCOORD3; - float4 projPos : TEXCOORD4; - float4 color : TEXCOORD5; - float3 localPos : TEXCOORD6; // for Irradiance calculations - float4 vWorldTangent: TEXCOORD7; - float3 vWorldBinormal: TEXCOORD8; -}; - -struct PS_OUTPUT -{ - float4 MainOut : COLOR0; - float4 Normal : COLOR1; - float4 MRAO : COLOR2; - float4 Albedo : COLOR3; -}; - -#if LIGHT_PREVIEW == 2 -LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR -#elif LIGHT_PREVIEW == 1 -HALF4 main(PS_INPUT i) : COLOR -#else -PS_OUTPUT main(PS_INPUT i) : COLOR -#endif -{ - float2 UV = i.baseTexCoord; - float2 screenUV = i.projPos.xy / i.projPos.w; - screenUV = screenUV * 0.5f + 0.5f; - float4 baseColor = tex2D( BaseTextureSampler, UV ); - -#if SMOOTHNESS == 0 - float roughnessMap = tex2D( RoughnessSampler, UV ); -#else - float roughnessMap = 1.0f - tex2D( RoughnessSampler, UV ); -#endif - - float metallicMap = tex2D( MetallicSampler, UV ); - float AOSample = tex2D( AOSampler, UV ); - float3 EmissiveSample = tex2D( EmissiveSampler, UV ); - float4 normalTexel = tex2D( BumpmapSampler, UV); - float3 lightmapTexel = GammaToLinear( 2.0f * tex2D( LightmapSampler, UV ).rgb ); - - float3 worldPos = i.worldPos; - float3 worldNormal = i.worldNormal; - float3 eyeToWorld = (g_EyePos - worldPos); - float3 albedo = g_DiffuseModulation.rgb * baseColor.rgb; - bool bCubemap = (CUBEMAP) ? true : false; - - float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; - float3 vWorldBinormal = i.vWorldBinormal; - - float3 vWorldNormal = Vec3TangentToWorld( tangentSpaceNormal, worldNormal, i.vWorldTangent, vWorldBinormal ); - vWorldNormal = normalize( vWorldNormal ); - - float3 projPos = i.projPos.xyz; - float3 Lighting = float(0.0).xxx; - -#if LIGHMAP == 0 - // Summation of diffuse illumination from all local lights - Lighting = DoPBRLights(g_EyePos.xyz, vWorldNormal, worldPos, baseColor, i.lightAtten, lightmapTexel, metallicMap, roughnessMap); -#endif - float3 IBL = DoIBL(g_EyePos.xyz, vWorldNormal, worldPos, screenUV, baseColor.rgb, metallicMap, roughnessMap, lightmapTexel); -#if FLASHLIGHT - float3 Flashlight = DoFlashlight(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap); -#elif CSM == 1 - float3 CSMLight = DoPBRCSM(worldPos, vWorldNormal, baseColor.rgb, metallicMap, roughnessMap, length(worldPos - g_EyePos)); -#endif - - float3 result = ( -#if FLASHLIGHT - Flashlight); -#elif CSM == 1 - CSMLight + Lighting + IBL * AOSample) + EmissiveSample; -#else - Lighting + IBL * AOSample) + EmissiveSample; -#endif - float alpha = baseColor.a * g_DiffuseModulation.a; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); - -#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) - alpha = fogFactor; -#endif - -#if LIGHT_PREVIEW == 1 - result = DoPBRLight(worldPos, vWorldNormal, baseColor, g_EyePos.xyz, 1.0f.xxx, g_EyePos.xyz, 5.0f, metallicMap, roughnessMap); - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - return FinalOutput( float4( result, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z ); -#elif LIGHT_PREVIEW == 2 - LPREVIEW_PS_OUT Output; - Output.color = float4( baseColor.xyz,alpha ); - Output.normal = float4( vWorldNormal,alpha ); - Output.position = float4( worldPos, alpha ); - Output.flags = float4( 1.0f - metallicMap, roughnessMap, 1, alpha ); - return FinalOutput( Output, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -#else - - PS_OUTPUT output = (PS_OUTPUT) 0; - - bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); - output.MainOut = FinalOutput(float4(result, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z); -#if !FLASHLIGHT - output.Normal = float4(vWorldNormal.xyz, 1.0f); - output.MRAO = float4(metallicMap, roughnessMap, AOSample, 0.0f); - output.Albedo = float4(baseColor.xyz, 1.0f); -#endif - return output; -#endif -} diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc deleted file mode 100644 index 4a3db793..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc +++ /dev/null @@ -1,350 +0,0 @@ -//======= Copyright � 1996-2008, Valve Corporation, All rights reserved. ====== - -// STATIC: "CUBEMAP" "0..1" -// STATIC: "DIFFUSELIGHTING" "0..1" -// STATIC: "LIGHTWARPTEXTURE" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "SELFILLUMFRESNEL" "0..1" -// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..6" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] -// STATIC: "BLENDTINTBYBASEALPHA" "0..1" - -// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] -// DYNAMIC: "AMBIENT_LIGHT" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] - -// We don't use light combos when doing the flashlight -// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] - -// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) - -// Don't do diffuse warp on flashlight -// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] - -// Only warp diffuse if we have it at all -// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) - -// Skip this since it blows ps20 instruction limits -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) - -// Only need self illum fresnel when self illum enabled -// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) - -// BlendTintByBaseAlpha is incompatible with other interpretations of alpha -// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) - -// Only _XBOX allows flashlight and cubemap in the current implementation -// SKIP: $FLASHLIGHT && $CUBEMAP [PC] - -// Meaningless combinations -// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP - -#include "common_flashlight_fxc.h" -#include "common_vertexlitgeneric_dx9.h" - -const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); -const float4 g_DiffuseModulation : register( c1 ); -const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); -const float3 g_EnvmapSaturation : register( c3 ); -const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); -#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) -#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) - -const float3 cAmbientCube[6] : register( c5 ); - -// 11, 12 not used? -#if ( SELFILLUMFRESNEL == 1 ) - const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); -#endif - -const float4 g_ShaderControls : register( c12 ); -#define g_fPixelFogType g_ShaderControls.x -#define g_fWriteDepthToAlpha g_ShaderControls.y -#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z - - -// 2 registers each - 6 registers total -PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 - -const float3 g_EyePos : register( c20 ); -const float4 g_FogParams : register( c21 ); - -const float4 g_FlashlightAttenuationFactors : register( c22 ); -const float3 g_FlashlightPos : register( c23 ); -const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 - -sampler BaseTextureSampler : register( s0 ); -sampler EnvmapSampler : register( s1 ); -sampler DetailSampler : register( s2 ); -sampler BumpmapSampler : register( s3 ); -sampler EnvmapMaskSampler : register( s4 ); -sampler NormalizeSampler : register( s5 ); -sampler RandRotSampler : register( s6 ); // RandomRotation sampler -sampler FlashlightSampler : register( s7 ); -sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler -sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) - -struct PS_INPUT -{ - float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; - float3 lightAtten : TEXCOORD1; - float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; - float3 vWorldNormal : TEXCOORD3; // World-space normal - float4 vWorldTangent : TEXCOORD4; -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float4 vProjPos : TEXCOORD5; -#else - float3 vWorldBinormal : TEXCOORD5; -#endif - float4 worldPos_projPosZ : TEXCOORD6; - float3 detailTexCoord_atten3 : TEXCOORD7; - float4 fogFactorW : COLOR1; - -#if defined( _X360 ) -#if FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD8; -#endif -#endif -}; - -// Calculate both types of Fog and lerp to get result -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); - return lerp( fRangeFog, fHeightFog, fPixelFogType ); -} - -// Blend both types of Fog and lerp to get result -float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) -{ - pixelFogFactor = saturate( pixelFogFactor ); - float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog - float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - return lerp( fRangeResult, fHeightResult, fPixelFogType ); -} - -float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) -{ - float4 result = vShaderColor; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb *= LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb *= GAMMA_LIGHT_SCALE; - } - - result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); - - result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion - - return result; -} - -float4 main( PS_INPUT i ) : COLOR -{ - bool bCubemap = CUBEMAP ? true : false; - bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; - bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; - bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; - bool bHalfLambert = HALFLAMBERT ? true : false; - bool bFlashlight = (FLASHLIGHT!=0) ? true : false; - bool bAmbientLight = AMBIENT_LIGHT ? true : false; - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; - int nNumLights = NUM_LIGHTS; - -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; -#else - float3 vWorldBinormal = i.vWorldBinormal; -#endif - - // Unpack four light attenuations - float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); - - float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); - -#if DETAILTEXTURE - float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); - baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - - float specularFactor = 1.0f; - float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); - float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; - - if ( bNormalMapAlphaEnvmapMask ) - specularFactor = normalTexel.a; - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - - float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); - if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) - { - worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); -#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) - worldSpaceNormal = normalize( worldSpaceNormal ); -#else - worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); -#endif - } - - if ( bDiffuseLighting ) - { - diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, - float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, - cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, - false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); - } - - float3 albedo = baseColor; - if (bBlendTintByBaseAlpha) - { - float3 tintedColor = albedo * g_DiffuseModulation.rgb; - tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); - albedo = lerp(albedo, tintedColor, baseColor.a); - } - else - { - albedo = albedo * g_DiffuseModulation.rgb; - } - - float alpha = g_DiffuseModulation.a; - if ( !bSelfIllum && !bBlendTintByBaseAlpha ) - { - alpha *= baseColor.a; - } - - -#if FLASHLIGHT - if( bFlashlight ) - { - int nShadowSampleLevel = 0; - bool bDoShadows = false; - float2 vProjPos = float2(0, 0); -// On ps_2_b, we can do shadow mapping -#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) - nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; - bDoShadows = FLASHLIGHTSHADOWS; - vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise -#endif - -#if defined ( _X360 ) - float4 flashlightSpacePosition = i.flashlightSpacePos; -#else - float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, - worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); - -#if defined ( _X360 ) - diffuseLighting += flashlightColor; -#else - diffuseLighting = flashlightColor; -#endif - - } -#endif - - - float3 diffuseComponent = albedo * diffuseLighting; - - -#if !FLASHLIGHT || defined ( _X360 ) - if ( bSelfIllum ) - { - #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file - // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look - #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); - float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; - - float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); - #else - float3 vVertexNormal = i.vWorldNormal.xyz; - float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; - - float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); - #endif - #else - float3 selfIllumComponent = g_SelfIllumTint * albedo; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); - #endif - } -#endif - - float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); -#if !FLASHLIGHT || defined ( _X360 ) - if( bCubemap ) - { - float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); - - specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; - float3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); - float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); - } -#endif - - float3 result = diffuseComponent + specularLighting; - -#if defined(SHADER_MODEL_PS_2_0) - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); -#else - float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); -#endif - -#if defined( SHADER_MODEL_PS_2_0 ) - #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = fogFactor; - #endif -#else // 2b or higher - alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog -#endif - -#if defined( SHADER_MODEL_PS_2_0 ) - return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); -#else - return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); -#endif - -} - diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps30.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps30.fxc deleted file mode 100644 index fd6735e8..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps30.fxc +++ /dev/null @@ -1,360 +0,0 @@ -//======= Copyright � 1996-2008, Valve Corporation, All rights reserved. ====== - -// STATIC: "CUBEMAP" "0..1" -// STATIC: "DIFFUSELIGHTING" "0..1" -// STATIC: "LIGHTWARPTEXTURE" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "SELFILLUMFRESNEL" "0..1" -// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..6" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] -// STATIC: "BLENDTINTBYBASEALPHA" "0..1" - -// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] -// DYNAMIC: "AMBIENT_LIGHT" "0..1" -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] - -// We don't use light combos when doing the flashlight -// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] - -// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) - -// Don't do diffuse warp on flashlight -// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] - -// Only warp diffuse if we have it at all -// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) - -// Skip this since it blows ps20 instruction limits -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) - -// Only need self illum fresnel when self illum enabled -// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] -// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) -// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) - -// BlendTintByBaseAlpha is incompatible with other interpretations of alpha -// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) - -// Only _XBOX allows flashlight and cubemap in the current implementation -// SKIP: $FLASHLIGHT && $CUBEMAP [PC] - -// Meaningless combinations -// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP - -#include "common_flashlight_fxc.h" -#include "common_vertexlitgeneric_dx9.h" - -const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); -const float4 g_DiffuseModulation : register( c1 ); -const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); -const float3 g_EnvmapSaturation : register( c3 ); -const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); -#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) -#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) - -const float3 cAmbientCube[6] : register( c5 ); - -// 11, 12 not used? -#if ( SELFILLUMFRESNEL == 1 ) - const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); -#endif - -const float4 g_ShaderControls : register( c12 ); -#define g_fPixelFogType g_ShaderControls.x -#define g_fWriteDepthToAlpha g_ShaderControls.y -#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z - - -// 2 registers each - 6 registers total -PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 - -const float3 g_EyePos : register( c20 ); -const float4 g_FogParams : register( c21 ); - -const float4 g_FlashlightAttenuationFactors : register( c22 ); -const float3 g_FlashlightPos : register( c23 ); -const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 - -sampler BaseTextureSampler : register( s0 ); -sampler EnvmapSampler : register( s1 ); -sampler DetailSampler : register( s2 ); -sampler BumpmapSampler : register( s3 ); -sampler EnvmapMaskSampler : register( s4 ); -sampler NormalizeSampler : register( s5 ); -sampler RandRotSampler : register( s6 ); // RandomRotation sampler -sampler FlashlightSampler : register( s7 ); -sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler -sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) - -struct PS_INPUT -{ - float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; - float3 lightAtten : TEXCOORD1; - float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; - float3 vWorldNormal : TEXCOORD3; // World-space normal - float4 vWorldTangent : TEXCOORD4; -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float4 vProjPos : TEXCOORD5; -#else - float3 vWorldBinormal : TEXCOORD5; -#endif - float4 worldPos_projPosZ : TEXCOORD6; - float3 detailTexCoord_atten3 : TEXCOORD7; - float4 fogFactorW : COLOR1; - -#if defined( _X360 ) -#if FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD8; -#endif -#endif -}; - -// Calculate both types of Fog and lerp to get result -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); - return lerp( fRangeFog, fHeightFog, fPixelFogType ); -} - -// Blend both types of Fog and lerp to get result -float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) -{ - pixelFogFactor = saturate( pixelFogFactor ); - float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog - float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - return lerp( fRangeResult, fHeightResult, fPixelFogType ); -} - -float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) -{ - float4 result = vShaderColor; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb *= LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb *= GAMMA_LIGHT_SCALE; - } - - result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); - - result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion - - return result; -} - -struct PS_OUTPUT -{ - float4 MainOut : COLOR0; - float4 Normal : COLOR1; - float4 MRAO : COLOR2; - float4 Albedo : COLOR3; -}; - -PS_OUTPUT main(PS_INPUT i) : COLOR -{ - bool bCubemap = CUBEMAP ? true : false; - bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; - bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; - bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; - bool bHalfLambert = HALFLAMBERT ? true : false; - bool bFlashlight = (FLASHLIGHT!=0) ? true : false; - bool bAmbientLight = AMBIENT_LIGHT ? true : false; - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; - int nNumLights = NUM_LIGHTS; - -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; -#else - float3 vWorldBinormal = i.vWorldBinormal; -#endif - - // Unpack four light attenuations - float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); - - float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); - -#if DETAILTEXTURE - float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); - baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - - float specularFactor = 1.0f; - float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); - float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; - - if ( bNormalMapAlphaEnvmapMask ) - specularFactor = normalTexel.a; - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - - float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); - if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) - { - worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); -#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) - worldSpaceNormal = normalize( worldSpaceNormal ); -#else - worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); -#endif - } - - if ( bDiffuseLighting ) - { - diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, - float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, - cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, - false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); - } - - float3 albedo = baseColor; - if (bBlendTintByBaseAlpha) - { - float3 tintedColor = albedo * g_DiffuseModulation.rgb; - tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); - albedo = lerp(albedo, tintedColor, baseColor.a); - } - else - { - albedo = albedo * g_DiffuseModulation.rgb; - } - - float alpha = g_DiffuseModulation.a; - if ( !bSelfIllum && !bBlendTintByBaseAlpha ) - { - alpha *= baseColor.a; - } - - -#if FLASHLIGHT - if( bFlashlight ) - { - int nShadowSampleLevel = 0; - bool bDoShadows = false; - float2 vProjPos = float2(0, 0); -// On ps_2_b, we can do shadow mapping -#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) - nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; - bDoShadows = FLASHLIGHTSHADOWS; - vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise -#endif - -#if defined ( _X360 ) - float4 flashlightSpacePosition = i.flashlightSpacePos; -#else - float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, - worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); - -#if defined ( _X360 ) - diffuseLighting += flashlightColor; -#else - diffuseLighting = flashlightColor; -#endif - - } -#endif - - - float3 diffuseComponent = albedo * diffuseLighting; - - -#if !FLASHLIGHT || defined ( _X360 ) - if ( bSelfIllum ) - { - #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file - // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look - #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) - float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); - float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; - - float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); - #else - float3 vVertexNormal = i.vWorldNormal.xyz; - float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; - - float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); - #endif - #else - float3 selfIllumComponent = g_SelfIllumTint * albedo; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); - #endif - } -#endif - - float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); -#if !FLASHLIGHT || defined ( _X360 ) - if( bCubemap ) - { - float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); - - specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; - float3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); - float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); - } -#endif - - float3 result = diffuseComponent + specularLighting; - -#if defined(SHADER_MODEL_PS_2_0) - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); -#else - float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); -#endif - -#if defined( SHADER_MODEL_PS_2_0 ) - #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = fogFactor; - #endif -#else // 2b or higher - alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog -#endif - - PS_OUTPUT output = (PS_OUTPUT) 0; - output.MainOut = FinalOutputConst(float4(result.rgb, alpha), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w); -#if !FLASHLIGHT - output.Normal = float4(worldSpaceNormal.xyz, 1.0f); - output.MRAO = float4(0.0f, 1.0f, 1.0f, 0.0f); - output.Albedo = float4(albedo.xyz, 1.0f); -#endif - return output; -} - diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc deleted file mode 100644 index 06afd956..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc +++ /dev/null @@ -1,198 +0,0 @@ -//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====== -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "USE_WITH_2B" "0..1" -// STATIC: "DECAL" "0..1" [vs30] -// STATIC: "FLASHLIGHT" "0..1" [XBOX] -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 -const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); // 4 & 5 -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - - -//----------------------------------------------------------------------------- -// Input vertex format -//----------------------------------------------------------------------------- -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vColor : COLOR0; - float3 vSpecular : COLOR1; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; - float4 vTexCoord2 : TEXCOORD2; - float4 vTexCoord3 : TEXCOORD3; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; - float4 vUserData : TANGENT; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - - -//----------------------------------------------------------------------------- -// Output vertex format -//----------------------------------------------------------------------------- -struct VS_OUTPUT -{ - // Stuff that isn't seen by the pixel shader - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - // Stuff that is seen by the pixel shader - - float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; - float3 lightAtten : TEXCOORD1; - float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; - float3 vWorldNormal : TEXCOORD3; // World-space normal - float4 vWorldTangent : TEXCOORD4; -#if USE_WITH_2B - float4 vProjPos : TEXCOORD5; -#else - float3 vWorldBinormal : TEXCOORD5; -#endif - float4 worldPos_projPosZ : TEXCOORD6; - float3 detailTexCoord_atten3 : TEXCOORD7; - float4 fogFactorW : COLOR1; - -#if defined( _X360 ) && FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD8; -#endif -}; - - -//----------------------------------------------------------------------------- -// Main shader entry point -//----------------------------------------------------------------------------- -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - float4 vTangent; - DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, - v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); -#endif - - // Perform skinning - float3 worldNormal, worldPos, worldTangentS, worldTangentT; - SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, - v.vBoneWeights, v.vBoneIndices, worldPos, - worldNormal, worldTangentS, worldTangentT ); - - // Always normalize since flex path is controlled by runtime - // constant not a shader combo and will always generate the normalization - worldNormal = normalize( worldNormal ); - worldTangentS = normalize( worldTangentS ); - worldTangentT = normalize( worldTangentT ); - -#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL - // Avoid z precision errors - worldPos += worldNormal * 0.05f * v.vTexCoord2.z; -#endif - - o.vWorldNormal.xyz = worldNormal.xyz; - o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - -#if USE_WITH_2B - o.vProjPos = vProjPos; -#else - o.vWorldBinormal.xyz = worldTangentT.xyz; -#endif - - o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - // Needed for water fog alpha and diffuse lighting - // FIXME: we shouldn't have to compute this all the time. - o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); - - // Needed for cubemapping + parallax mapping - // FIXME: We shouldn't have to compute this all the time. - //o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); - o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = normalize( cEyePos.xyz - worldPos.xyz ); - -#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) - o.lightAtten.xyz = float3(0,0,0); - o.detailTexCoord_atten3.z = 0.0f; - #if ( NUM_LIGHTS > 0 ) - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); - #endif - #if ( NUM_LIGHTS > 1 ) - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); - #endif - #if ( NUM_LIGHTS > 2 ) - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); - #endif - #if ( NUM_LIGHTS > 3 ) - o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, false ); - #endif -#else - // Scalar light attenuation - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); - o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, true ); -#endif - - // Base texture coordinate transform - o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - - // Detail texture coordinate transform - o.detailTexCoord_atten3.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); - o.detailTexCoord_atten3.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); - -#if defined( _X360 ) && FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - return o; -} diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs30.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs30.fxc deleted file mode 100644 index 06afd956..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs30.fxc +++ /dev/null @@ -1,198 +0,0 @@ -//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====== -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "USE_WITH_2B" "0..1" -// STATIC: "DECAL" "0..1" [vs30] -// STATIC: "FLASHLIGHT" "0..1" [XBOX] -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] - -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] - -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 -const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); // 4 & 5 -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); - -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - - -//----------------------------------------------------------------------------- -// Input vertex format -//----------------------------------------------------------------------------- -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vColor : COLOR0; - float3 vSpecular : COLOR1; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; - float4 vTexCoord2 : TEXCOORD2; - float4 vTexCoord3 : TEXCOORD3; - float3 vTangentS : TANGENT; - float3 vTangentT : BINORMAL; - float4 vUserData : TANGENT; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - - -//----------------------------------------------------------------------------- -// Output vertex format -//----------------------------------------------------------------------------- -struct VS_OUTPUT -{ - // Stuff that isn't seen by the pixel shader - float4 projPos : POSITION; -#if !defined( _X360 ) - float fog : FOG; -#endif - // Stuff that is seen by the pixel shader - - float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; - float3 lightAtten : TEXCOORD1; - float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; - float3 vWorldNormal : TEXCOORD3; // World-space normal - float4 vWorldTangent : TEXCOORD4; -#if USE_WITH_2B - float4 vProjPos : TEXCOORD5; -#else - float3 vWorldBinormal : TEXCOORD5; -#endif - float4 worldPos_projPosZ : TEXCOORD6; - float3 detailTexCoord_atten3 : TEXCOORD7; - float4 fogFactorW : COLOR1; - -#if defined( _X360 ) && FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD8; -#endif -}; - - -//----------------------------------------------------------------------------- -// Main shader entry point -//----------------------------------------------------------------------------- -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - float4 vPosition = v.vPos; - float3 vNormal; - float4 vTangent; - DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, - v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); -#endif - - // Perform skinning - float3 worldNormal, worldPos, worldTangentS, worldTangentT; - SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, - v.vBoneWeights, v.vBoneIndices, worldPos, - worldNormal, worldTangentS, worldTangentT ); - - // Always normalize since flex path is controlled by runtime - // constant not a shader combo and will always generate the normalization - worldNormal = normalize( worldNormal ); - worldTangentS = normalize( worldTangentS ); - worldTangentT = normalize( worldTangentT ); - -#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL - // Avoid z precision errors - worldPos += worldNormal * 0.05f * v.vTexCoord2.z; -#endif - - o.vWorldNormal.xyz = worldNormal.xyz; - o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - -#if USE_WITH_2B - o.vProjPos = vProjPos; -#else - o.vWorldBinormal.xyz = worldTangentT.xyz; -#endif - - o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW; -#endif - - // Needed for water fog alpha and diffuse lighting - // FIXME: we shouldn't have to compute this all the time. - o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); - - // Needed for cubemapping + parallax mapping - // FIXME: We shouldn't have to compute this all the time. - //o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); - o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = normalize( cEyePos.xyz - worldPos.xyz ); - -#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) - o.lightAtten.xyz = float3(0,0,0); - o.detailTexCoord_atten3.z = 0.0f; - #if ( NUM_LIGHTS > 0 ) - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); - #endif - #if ( NUM_LIGHTS > 1 ) - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); - #endif - #if ( NUM_LIGHTS > 2 ) - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); - #endif - #if ( NUM_LIGHTS > 3 ) - o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, false ); - #endif -#else - // Scalar light attenuation - o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); - o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); - o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); - o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, true ); -#endif - - // Base texture coordinate transform - o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); - - // Detail texture coordinate transform - o.detailTexCoord_atten3.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); - o.detailTexCoord_atten3.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); - -#if defined( _X360 ) && FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - return o; -} diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc deleted file mode 100644 index 0220b3b6..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc +++ /dev/null @@ -1,507 +0,0 @@ -//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =======// -// -//=============================================================================// -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "DIFFUSELIGHTING" "0..1" -// STATIC: "ENVMAPMASK" "0..1" -// STATIC: "BASEALPHAENVMAPMASK" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..9" -// STATIC: "SEAMLESS_BASE" "0..1" -// STATIC: "SEAMLESS_DETAIL" "0..1" -// STATIC: "DISTANCEALPHA" "0..1" -// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" -// STATIC: "SOFT_MASK" "0..1" -// STATIC: "OUTLINE" "0..1" -// STATIC: "OUTER_GLOW" "0..1" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] -// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] -// STATIC: "BLENDTINTBYBASEALPHA" "0..1" -// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] -// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" - -// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] -// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" [ps20b] [ps30] -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..0" [ps20] -// DYNAMIC: "DEBUG_LUXELS" "0..1" [ps20b] [ps30] - -// detail blend mode 6 = ps20b only -// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] - -// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) -// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) -// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) -// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK -// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM -// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA -// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) -// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] -// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) -// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) -// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] - -// DISTANCEALPHA-related skips -// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) -// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) -// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) - -// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER -// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) - -// BlendTintByBaseAlpha is incompatible with other interpretations of alpha -// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) - -// Only _XBOX allows flashlight and cubemap in the current implementation -// SKIP: $FLASHLIGHT && $CUBEMAP [PC] - -// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) - -// Debugging luxels only makes sense if we have lightmaps on this geometry. -// SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1) - -#include "common_flashlight_fxc.h" -#include "common_vertexlitgeneric_dx9.h" - -const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); -const float4 g_DiffuseModulation : register( c1 ); -const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); -const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); -const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); - -const float4 g_ShaderControls : register( c12 ); -const float4 g_DepthFeatheringConstants : register( c13 ); - -const float4 g_EyePos : register( c20 ); -const float4 g_FogParams : register( c21 ); - -#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz -#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w -#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz -#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w - -const float4 g_FlashlightAttenuationFactors : register( c22 ); -const HALF3 g_FlashlightPos : register( c23 ); -const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 - - -sampler BaseTextureSampler : register( s0 ); -sampler EnvmapSampler : register( s1 ); -sampler DetailSampler : register( s2 ); -sampler EnvmapMaskSampler : register( s4 ); -sampler RandRotSampler : register( s6 ); // RandomRotation sampler -sampler FlashlightSampler : register( s7 ); -sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler -sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending -sampler SelfIllumMaskSampler : register( s11 ); // selfillummask -sampler LightMapSampler : register( s12 ); - -struct PS_INPUT -{ -#if SEAMLESS_BASE - HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate -#else - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate -#endif -#if SEAMLESS_DETAIL - HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate -#else - HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate -#endif - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection - float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight - -#if defined ( _X360 ) -#if FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD5; -#endif -#endif - - float4 projPos : TEXCOORD6; - float4 worldPos_projPosZ : TEXCOORD7; - float4 fogFactorW : COLOR1; -#if SEAMLESS_BASE || SEAMLESS_DETAIL - float3 SeamlessWeights : COLOR0; // x y z projection weights -#endif -}; - -const float4 g_GlowParameters : register( c5 ); -const float4 g_GlowColor : register( c6 ); -#define GLOW_UV_OFFSET g_GlowParameters.xy -#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z -#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w -#define OUTER_GLOW_COLOR g_GlowColor - -#define g_fPixelFogType g_ShaderControls.x -#define g_fWriteDepthToAlpha g_ShaderControls.y -#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z -#define g_fVertexAlpha g_ShaderControls.w - - -const float4 g_DistanceAlphaParams : register( c7 ); -#define SOFT_MASK_MAX g_DistanceAlphaParams.x -#define SOFT_MASK_MIN g_DistanceAlphaParams.y - -const float4 g_OutlineColor : register( c8 ); -#define OUTLINE_COLOR g_OutlineColor - -const float4 g_OutlineParams : register( c9 ); -// these are ordered this way for optimal ps20 swizzling -#define OUTLINE_MIN_VALUE0 g_OutlineParams.x -#define OUTLINE_MAX_VALUE1 g_OutlineParams.y -#define OUTLINE_MAX_VALUE0 g_OutlineParams.z -#define OUTLINE_MIN_VALUE1 g_OutlineParams.w - -#if DETAILTEXTURE -const float3 g_DetailTint : register( c10 ); -#endif - -#if DEBUG_LUXELS -const float4 g_LuxelScale : register( c11 ); -#endif - - -// Calculate unified fog -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive - float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive - // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 - float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); - return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); -} - -// Blend both types of Fog and lerp to get result -float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) -{ - //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog - //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - //return lerp( fRangeResult, fHeightResult, fPixelFogType ); - pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); - return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); -} - - -float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) -{ - float4 result = vShaderColor; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb *= LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb *= GAMMA_LIGHT_SCALE; - } - - result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); - - result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion - - return result; -} - - -#if LIGHTING_PREVIEW == 2 -LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR -#else -float4 main( PS_INPUT i ) : COLOR -#endif -{ - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bCubemap = CUBEMAP ? true : false; - bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; - bool bHasNormal = bCubemap || bDiffuseLighting; - bool bEnvmapMask = ENVMAPMASK ? true : false; - bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bVertexColor = VERTEXCOLOR ? true : false; - bool bFlashlight = FLASHLIGHT ? true : false; - bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; - - HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); -#if SEAMLESS_BASE - baseColor = - i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ - i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ - i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); -#else - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); - -#if SRGB_INPUT_ADAPTER - baseColor.rgb = GammaToLinear( baseColor.rgb ); -#endif - -#endif // !SEAMLESS_BASE - - -#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) - float distAlphaMask = baseColor.a; -#endif - - -#if DETAILTEXTURE -#if SEAMLESS_DETAIL - float4 detailColor = - i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ - i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ - i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); -#else - float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); -#endif - detailColor.rgb *= g_DetailTint; - -#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) - float distAlphaMask = detailColor.a; - detailColor.a = 1.0; // make tcombine treat as 1.0 -#endif - baseColor = - TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - -#if DISTANCEALPHA - // now, do all distance alpha effects - //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) - //{ - // float oFactor=1.0; - // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) - // { - // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); - // } - // else - // { - // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); - // } - // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); - //} - if ( OUTLINE ) - { - float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); - baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); - } - - float mskUsed; - if ( SOFT_MASK ) - { - mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); - baseColor.a *= mskUsed; - } - else - { - mskUsed = distAlphaMask >= 0.5; - if (DETAILTEXTURE ) - baseColor.a *= mskUsed; - else - baseColor.a = mskUsed; - } - - - if ( OUTER_GLOW ) - { -#if DISTANCEALPHAFROMDETAIL - float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); -#else - float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); -#endif - float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); - baseColor = lerp( glowc, baseColor, mskUsed ); - } - -#endif // DISTANCEALPHA - - float3 specularFactor = 1.0f; - float4 envmapMaskTexel; - if( bEnvmapMask ) - { - envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); - specularFactor *= envmapMaskTexel.xyz; - } - - if( bBaseAlphaEnvmapMask ) - { - specularFactor *= 1.0 - baseColor.a; // this blows! - } - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - if( bDiffuseLighting || bVertexColor ) - { - diffuseLighting = i.color.rgb; - } - -#if STATIC_LIGHT_LIGHTMAP - // This matches the behavior of vertex lighting, which multiplies by cOverbright (which is not accessible here) - // And converts from Gamma space to Linear space before being used. - float2 lightmapTexCoords = i.baseTexCoord.xy; - #if DEBUG_LUXELS - lightmapTexCoords.xy *= g_LuxelScale.xy; - #endif - float3 f3LightmapColor = GammaToLinear( 2.0f * tex2D( LightMapSampler, lightmapTexCoords ).rgb ); - diffuseLighting = f3LightmapColor; -#endif - - float3 albedo = baseColor; - - if (bBlendTintByBaseAlpha) - { - float3 tintedColor = albedo * g_DiffuseModulation.rgb; - tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); - albedo = lerp(albedo, tintedColor, baseColor.a); - } - else - { - albedo = albedo * g_DiffuseModulation.rgb; - } - - float alpha = g_DiffuseModulation.a; - if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) - { - alpha *= baseColor.a; - } - - - if( bFlashlight ) - { - int nShadowSampleLevel = 0; - bool bDoShadows = false; -// On ps_2_b, we can do shadow mapping -#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) - nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; - bDoShadows = true; -#endif - -#if defined ( _X360 ) - float4 flashlightSpacePosition = i.flashlightSpacePos; -#else - float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 - bool bUseWorldNormal = true; -#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) - bUseWorldNormal = false; -#endif - float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, - i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); - -#if defined ( _X360 ) - diffuseLighting += flashlightColor; -#else - diffuseLighting = flashlightColor; -#endif - } - - if( bVertexColor && bDiffuseLighting ) - { - albedo *= i.color.rgb; - } - - alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); - - float3 diffuseComponent = albedo * diffuseLighting; - -#if DETAILTEXTURE - diffuseComponent = - TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - - HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); - -#if !FLASHLIGHT || defined ( _X360 ) - #if SELFILLUM_ENVMAPMASK_ALPHA - // range of alpha: - // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) - // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) - HALF3 selfIllumComponent = g_SelfIllumTint * albedo; - half Adj_Alpha=8*envmapMaskTexel.a; - diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; - #else - if ( bSelfIllum ) - { - float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); - vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); - diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); - } - #endif - - if( bCubemap ) - { -#if CUBEMAP_SPHERE_LEGACY - HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); - - specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; -#else - HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); - - specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; - HALF3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); - HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); -#endif - } -#endif - - HALF3 result = diffuseComponent + specularLighting; - -#if LIGHTING_PREVIEW -# if LIGHTING_PREVIEW == 1 - float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); - return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); -# else - LPREVIEW_PS_OUT ret; - ret.flags=float4(1,1,1,1); - ret.color=float4( albedo.xyz, alpha ); - ret.normal=float4(i.worldSpaceNormal,alpha); - ret.position=float4(i.worldPos_projPosZ.xyz, alpha); - return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -# endif -#else - -# if (DEPTHBLEND == 1) - { - float2 vScreenPos; - vScreenPos.x = i.projPos.x; - vScreenPos.y = -i.projPos.y; - vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; - alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); - } -# endif - -#if defined( SHADER_MODEL_PS_2_0 ) - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); - #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); - #endif - return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); -#else // 2b or higher - float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); - alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog - return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); -#endif - -#endif -} - diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps30.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps30.fxc deleted file mode 100644 index b81c3a00..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps30.fxc +++ /dev/null @@ -1,525 +0,0 @@ -//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =======// -// -//=============================================================================// -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "DIFFUSELIGHTING" "0..1" -// STATIC: "ENVMAPMASK" "0..1" -// STATIC: "BASEALPHAENVMAPMASK" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" -// STATIC: "DETAIL_BLEND_MODE" "0..9" -// STATIC: "SEAMLESS_BASE" "0..1" -// STATIC: "SEAMLESS_DETAIL" "0..1" -// STATIC: "DISTANCEALPHA" "0..1" -// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" -// STATIC: "SOFT_MASK" "0..1" -// STATIC: "OUTLINE" "0..1" -// STATIC: "OUTER_GLOW" "0..1" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] -// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] -// STATIC: "BLENDTINTBYBASEALPHA" "0..1" -// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] -// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" - -// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] -// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" [ps20b] [ps30] -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..0" [ps20] -// DYNAMIC: "DEBUG_LUXELS" "0..1" [ps20b] [ps30] - -// detail blend mode 6 = ps20b only -// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] - -// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) -// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) -// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) -// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK -// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM -// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA -// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) -// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] -// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) -// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) -// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] - -// Flashlight shadow filter mode is irrelevant if there is no flashlight -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] - -// DISTANCEALPHA-related skips -// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) -// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) -// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) - -// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER -// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) - -// BlendTintByBaseAlpha is incompatible with other interpretations of alpha -// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) - -// Only _XBOX allows flashlight and cubemap in the current implementation -// SKIP: $FLASHLIGHT && $CUBEMAP [PC] - -// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) - -// Debugging luxels only makes sense if we have lightmaps on this geometry. -// SKIP: ($STATIC_LIGHT_LIGHTMAP == 0) && ($DEBUG_LUXELS == 1) - -#include "common_flashlight_fxc.h" -#include "common_vertexlitgeneric_dx9.h" - -const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); -const float4 g_DiffuseModulation : register( c1 ); -const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); -const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); -const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); - -const float4 g_ShaderControls : register( c12 ); -const float4 g_DepthFeatheringConstants : register( c13 ); - -const float4 g_EyePos : register( c20 ); -const float4 g_FogParams : register( c21 ); - -#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz -#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w -#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz -#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w - -const float4 g_FlashlightAttenuationFactors : register( c22 ); -const HALF3 g_FlashlightPos : register( c23 ); -const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 - - -sampler BaseTextureSampler : register( s0 ); -sampler EnvmapSampler : register( s1 ); -sampler DetailSampler : register( s2 ); -sampler EnvmapMaskSampler : register( s4 ); -sampler RandRotSampler : register( s6 ); // RandomRotation sampler -sampler FlashlightSampler : register( s7 ); -sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler -sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending -sampler SelfIllumMaskSampler : register( s11 ); // selfillummask -sampler LightMapSampler : register( s12 ); - -struct PS_INPUT -{ -#if SEAMLESS_BASE - HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate -#else - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate -#endif -#if SEAMLESS_DETAIL - HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate -#else - HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate -#endif - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection - float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight - -#if defined ( _X360 ) -#if FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD5; -#endif -#endif - - float4 projPos : TEXCOORD6; - float4 worldPos_projPosZ : TEXCOORD7; - float4 fogFactorW : COLOR1; -#if SEAMLESS_BASE || SEAMLESS_DETAIL - float3 SeamlessWeights : COLOR0; // x y z projection weights -#endif -}; - -const float4 g_GlowParameters : register( c5 ); -const float4 g_GlowColor : register( c6 ); -#define GLOW_UV_OFFSET g_GlowParameters.xy -#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z -#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w -#define OUTER_GLOW_COLOR g_GlowColor - -#define g_fPixelFogType g_ShaderControls.x -#define g_fWriteDepthToAlpha g_ShaderControls.y -#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z -#define g_fVertexAlpha g_ShaderControls.w - - -const float4 g_DistanceAlphaParams : register( c7 ); -#define SOFT_MASK_MAX g_DistanceAlphaParams.x -#define SOFT_MASK_MIN g_DistanceAlphaParams.y - -const float4 g_OutlineColor : register( c8 ); -#define OUTLINE_COLOR g_OutlineColor - -const float4 g_OutlineParams : register( c9 ); -// these are ordered this way for optimal ps20 swizzling -#define OUTLINE_MIN_VALUE0 g_OutlineParams.x -#define OUTLINE_MAX_VALUE1 g_OutlineParams.y -#define OUTLINE_MAX_VALUE0 g_OutlineParams.z -#define OUTLINE_MIN_VALUE1 g_OutlineParams.w - -#if DETAILTEXTURE -const float3 g_DetailTint : register( c10 ); -#endif - -#if DEBUG_LUXELS -const float4 g_LuxelScale : register( c11 ); -#endif - - -// Calculate unified fog -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive - float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive - // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 - float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); - return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); -} - -// Blend both types of Fog and lerp to get result -float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) -{ - //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog - //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - //return lerp( fRangeResult, fHeightResult, fPixelFogType ); - pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); - return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); -} - - -float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) -{ - float4 result = vShaderColor; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb *= LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb *= GAMMA_LIGHT_SCALE; - } - - result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); - - result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion - - return result; -} - -struct PS_OUTPUT -{ - float4 MainOut : COLOR0; - float4 Normal : COLOR1; - float4 MRAO : COLOR2; - float4 Albedo : COLOR3; -}; - -#if LIGHTING_PREVIEW == 2 -LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR -#elif LIGHTING_PREVIEW == 1 -HALF4 main(PS_INPUT i) : COLOR -#else -PS_OUTPUT main(PS_INPUT i) : COLOR -#endif -{ - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bCubemap = CUBEMAP ? true : false; - bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; - bool bHasNormal = bCubemap || bDiffuseLighting; - bool bEnvmapMask = ENVMAPMASK ? true : false; - bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bVertexColor = VERTEXCOLOR ? true : false; - bool bFlashlight = FLASHLIGHT ? true : false; - bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; - - HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); -#if SEAMLESS_BASE - baseColor = - i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ - i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ - i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); -#else - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); - -#if SRGB_INPUT_ADAPTER - baseColor.rgb = GammaToLinear( baseColor.rgb ); -#endif - -#endif // !SEAMLESS_BASE - - -#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) - float distAlphaMask = baseColor.a; -#endif - - -#if DETAILTEXTURE -#if SEAMLESS_DETAIL - float4 detailColor = - i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ - i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ - i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); -#else - float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); -#endif - detailColor.rgb *= g_DetailTint; - -#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) - float distAlphaMask = detailColor.a; - detailColor.a = 1.0; // make tcombine treat as 1.0 -#endif - baseColor = - TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - -#if DISTANCEALPHA - // now, do all distance alpha effects - //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) - //{ - // float oFactor=1.0; - // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) - // { - // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); - // } - // else - // { - // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); - // } - // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); - //} - if ( OUTLINE ) - { - float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); - baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); - } - - float mskUsed; - if ( SOFT_MASK ) - { - mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); - baseColor.a *= mskUsed; - } - else - { - mskUsed = distAlphaMask >= 0.5; - if (DETAILTEXTURE ) - baseColor.a *= mskUsed; - else - baseColor.a = mskUsed; - } - - - if ( OUTER_GLOW ) - { -#if DISTANCEALPHAFROMDETAIL - float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); -#else - float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); -#endif - float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); - baseColor = lerp( glowc, baseColor, mskUsed ); - } - -#endif // DISTANCEALPHA - - float3 specularFactor = 1.0f; - float4 envmapMaskTexel; - if( bEnvmapMask ) - { - envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); - specularFactor *= envmapMaskTexel.xyz; - } - - if( bBaseAlphaEnvmapMask ) - { - specularFactor *= 1.0 - baseColor.a; // this blows! - } - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - if( bDiffuseLighting || bVertexColor ) - { - diffuseLighting = i.color.rgb; - } - -#if STATIC_LIGHT_LIGHTMAP - // This matches the behavior of vertex lighting, which multiplies by cOverbright (which is not accessible here) - // And converts from Gamma space to Linear space before being used. - float2 lightmapTexCoords = i.baseTexCoord.xy; - #if DEBUG_LUXELS - lightmapTexCoords.xy *= g_LuxelScale.xy; - #endif - float3 f3LightmapColor = GammaToLinear( 2.0f * tex2D( LightMapSampler, lightmapTexCoords ).rgb ); - diffuseLighting = f3LightmapColor; -#endif - - float3 albedo = baseColor; - - if (bBlendTintByBaseAlpha) - { - float3 tintedColor = albedo * g_DiffuseModulation.rgb; - tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); - albedo = lerp(albedo, tintedColor, baseColor.a); - } - else - { - albedo = albedo * g_DiffuseModulation.rgb; - } - - float alpha = g_DiffuseModulation.a; - if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) - { - alpha *= baseColor.a; - } - - - if( bFlashlight ) - { - int nShadowSampleLevel = 0; - bool bDoShadows = false; -// On ps_2_b, we can do shadow mapping -#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) - nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; - bDoShadows = true; -#endif - -#if defined ( _X360 ) - float4 flashlightSpacePosition = i.flashlightSpacePos; -#else - float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 - bool bUseWorldNormal = true; -#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) - bUseWorldNormal = false; -#endif - float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, - i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, - RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); - -#if defined ( _X360 ) - diffuseLighting += flashlightColor; -#else - diffuseLighting = flashlightColor; -#endif - } - - if( bVertexColor && bDiffuseLighting ) - { - albedo *= i.color.rgb; - } - - alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); - - float3 diffuseComponent = albedo * diffuseLighting; - -#if DETAILTEXTURE - diffuseComponent = - TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); -#endif - - HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); - -#if !FLASHLIGHT || defined ( _X360 ) - #if SELFILLUM_ENVMAPMASK_ALPHA - // range of alpha: - // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) - // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) - HALF3 selfIllumComponent = g_SelfIllumTint * albedo; - half Adj_Alpha=8*envmapMaskTexel.a; - diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; - #else - if ( bSelfIllum ) - { - float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); - vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); - diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); - } - #endif - - if( bCubemap ) - { -#if CUBEMAP_SPHERE_LEGACY - HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); - - specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; -#else - HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); - - specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); - specularLighting *= specularFactor; - specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; - HALF3 specularLightingSquared = specularLighting * specularLighting; - specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); - HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); - specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); -#endif - } -#endif - - HALF3 result = diffuseComponent + specularLighting; - -#if LIGHTING_PREVIEW -# if LIGHTING_PREVIEW == 1 - float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); - return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); -# else - LPREVIEW_PS_OUT ret; - ret.flags=float4(1,1,1,1); - ret.color=float4( albedo.xyz, alpha ); - ret.normal=float4(i.worldSpaceNormal,alpha); - ret.position=float4(i.worldPos_projPosZ.xyz, alpha); - return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -# endif -#else - -# if (DEPTHBLEND == 1) - { - float2 vScreenPos; - vScreenPos.x = i.projPos.x; - vScreenPos.y = -i.projPos.y; - vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; - alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); - } -# endif - - PS_OUTPUT output = (PS_OUTPUT) 0; - if (!bFlashlight) - { - output.Normal = float4(i.worldSpaceNormal.xyz, 1.0f); - output.MRAO = float4(0.0f, 1.0f, 1.0f, 0.0f); - output.Albedo = float4(albedo.xyz, 0.0f); - } -#if defined( SHADER_MODEL_PS_2_0 ) - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); - #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); - #endif - output.MainOut = FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); - return output; -#else // 2b or higher - float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); - alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog - output.MainOut = FinalOutputConst(float4(result.rgb, alpha), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z); - return output; -#endif - -#endif -} - diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc deleted file mode 100644 index 4ba11f13..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc +++ /dev/null @@ -1,250 +0,0 @@ -//======= Copyright � 1996-2007, Valve Corporation, All rights reserved. ====== - -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "SEAMLESS_BASE" "0..1" -// STATIC: "SEAMLESS_DETAIL" "0..1" -// STATIC: "SEPARATE_DETAIL_UVS" "0..1" -// STATIC: "DECAL" "0..1" [vs30] -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] -// STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT_VERTEX" "0..1" -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] -// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) -// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; -static const bool g_bVertexColor = VERTEXCOLOR ? true : false; -static const bool g_bCubemap = CUBEMAP ? true : false; -static const bool g_bFlashlight = FLASHLIGHT ? true : false; -static const bool g_bHalfLambert = HALFLAMBERT ? true : false; -#if (defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL) -static const bool g_bDecalOffset = true; -#else -static const bool g_bDecalOffset = false; -#endif - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -#if SEAMLESS_DETAIL || SEAMLESS_BASE -const float cSeamlessScale : register( SHADER_SPECIFIC_CONST_2); -#define SEAMLESS_SCALE cSeamlessScale.x -#endif - -const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); - -#if defined ( _X360 ) -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); -sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); -#endif - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vColor : COLOR0; - float3 vSpecular : COLOR1; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; - float4 vTexCoord2 : TEXCOORD2; - float4 vTexCoord3 : TEXCOORD3; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; -#endif - -#if SEAMLESS_BASE - HALF3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) -#else - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate -#endif -#if SEAMLESS_DETAIL - HALF3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate -#else - HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate -#endif - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - -#if CUBEMAP || _X360 - float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps -#endif - - float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight - -#if defined ( _X360 ) && FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD5; -#endif - - float4 vProjPos : TEXCOORD6; - float4 worldPos_ProjPosZ : TEXCOORD7; - float4 fogFactorW : COLOR1; -#if SEAMLESS_DETAIL || SEAMLESS_BASE - float3 SeamlessWeights : COLOR0; // x y z projection weights -#endif - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT_VERTEX ? true : false; - bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); - - float4 vPosition = v.vPos; - float3 vNormal = 0; - if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) - { - // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) - DecompressVertex_Normal( v.vNormal, vNormal ); - } - -#if SEAMLESS_BASE || SEAMLESS_DETAIL - // compute blend weights in rgb - float3 NNormal=normalize( vNormal ); - o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. -#endif - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, - v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); -#endif - - // Perform skinning - float3 worldNormal, worldPos; - SkinPositionAndNormal( - g_bSkinning, - vPosition, vNormal, - v.vBoneWeights, v.vBoneIndices, - worldPos, worldNormal ); - - if ( !g_bVertexColor ) - { - worldNormal = normalize( worldNormal ); - } - -#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL - // Avoid z precision errors - worldPos += worldNormal * 0.05f * v.vTexCoord2.z; -#endif - - o.worldSpaceNormal = worldNormal; - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.vProjPos = vProjPos; - o.fogFactorW.w = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW.w; -#endif - o.worldPos_ProjPosZ.xyz = worldPos.xyz; - o.worldPos_ProjPosZ.w = vProjPos.z; - - // Needed for cubemaps -#if CUBEMAP - o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); -#endif - -#if !defined (_X360) && FLASHLIGHT - o.color = float4( 0.0f, 0.0f, 0.0f, 0.0f ); -#else - if ( g_bVertexColor ) - { - // Assume that this is unlitgeneric if you are using vertex color. - o.color.rgb = ( DONT_GAMMA_CONVERT_VERTEX_COLOR ) ? v.vColor.rgb : GammaToLinear( v.vColor.rgb ); - o.color.a = v.vColor.a; - } - else - { - #if ( ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) ) - { - o.color.xyz = DoLighting( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert ); - } - #else - { - o.color.xyz = DoLightingUnrolled( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); - } - #endif - } -#endif - - -#if SEAMLESS_BASE - o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; -#else - // Base texture coordinates - o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); -#endif - -#if SEAMLESS_DETAIL - // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so - // that scale works. More smartness could allow 3d xform. - o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*cDetailTexCoordTransform[0].x) * v.vPos.xyz; -#else - // Detail texture coordinates - // FIXME: This shouldn't have to be computed all the time. - o.detailTexCoord.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); - o.detailTexCoord.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); -#endif - -#if SEPARATE_DETAIL_UVS - o.detailTexCoord.xy = v.vTexCoord1.xy; -#endif - -#if LIGHTING_PREVIEW - float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); - o.color.xyz=float3(dot,dot,dot); -#endif - -#if defined ( _X360 ) && FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - return o; -} - - diff --git a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs30.fxc b/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs30.fxc deleted file mode 100644 index bd6b7dd5..00000000 --- a/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs30.fxc +++ /dev/null @@ -1,250 +0,0 @@ -//======= Copyright � 1996-2007, Valve Corporation, All rights reserved. ====== - -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "CUBEMAP" "0..1" -// STATIC: "HALFLAMBERT" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "SEAMLESS_BASE" "0..1" -// STATIC: "SEAMLESS_DETAIL" "0..1" -// STATIC: "SEPARATE_DETAIL_UVS" "0..1" -// STATIC: "DECAL" "0..1" [vs30] -// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] -// STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DYNAMIC_LIGHT" "0..1" -// DYNAMIC: "STATIC_LIGHT_VERTEX" "0..1" -// DYNAMIC: "STATIC_LIGHT_LIGHTMAP" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" -// DYNAMIC: "SKINNING" "0..1" -// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] -// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] -// DYNAMIC: "MORPHING" "0..1" [vs30] -// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] - -// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo -// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] -// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) -// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) -#include "common_vs_fxc.h" - -static const bool g_bSkinning = SKINNING ? true : false; -static const int g_FogType = DOWATERFOG; -static const bool g_bVertexColor = VERTEXCOLOR ? true : false; -static const bool g_bCubemap = CUBEMAP ? true : false; -static const bool g_bFlashlight = FLASHLIGHT ? true : false; -static const bool g_bHalfLambert = HALFLAMBERT ? true : false; -#if (defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL) -static const bool g_bDecalOffset = true; -#else -static const bool g_bDecalOffset = false; -#endif - -const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); -#if SEAMLESS_DETAIL || SEAMLESS_BASE -const float cSeamlessScale : register( SHADER_SPECIFIC_CONST_2); -#define SEAMLESS_SCALE cSeamlessScale.x -#endif - -const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); - -#if defined ( _X360 ) -const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 -#endif - -#ifdef SHADER_MODEL_VS_3_0 -// NOTE: cMorphTargetTextureDim.xy = target dimensions, -// cMorphTargetTextureDim.z = 4tuples/morph -const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); -const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); -sampler2D morphSampler : register( s0 ); -#endif - -struct VS_INPUT -{ - // This is all of the stuff that we ever use. - float4 vPos : POSITION; - float4 vBoneWeights : BLENDWEIGHT; - float4 vBoneIndices : BLENDINDICES; - float4 vNormal : NORMAL; - float4 vColor : COLOR0; - float3 vSpecular : COLOR1; - // make these float2's and stick the [n n 0 1] in the dot math. - float4 vTexCoord0 : TEXCOORD0; - float4 vTexCoord1 : TEXCOORD1; - float4 vTexCoord2 : TEXCOORD2; - float4 vTexCoord3 : TEXCOORD3; - - // Position and normal/tangent deltas - float3 vPosFlex : POSITION1; - float3 vNormalFlex : NORMAL1; -#ifdef SHADER_MODEL_VS_3_0 - float vVertexID : POSITION2; -#endif -}; - - -struct VS_OUTPUT -{ - float4 projPos : POSITION; // Projection-space position -#if !defined( _X360 ) - float fog : FOG; -#endif - -#if SEAMLESS_BASE - HALF3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) -#else - HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate -#endif -#if SEAMLESS_DETAIL - HALF3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate -#else - HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate -#endif - float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) - -#if CUBEMAP || _X360 - float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps -#endif - - float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight - -#if defined ( _X360 ) && FLASHLIGHT - float4 flashlightSpacePos : TEXCOORD5; -#endif - - float4 vProjPos : TEXCOORD6; - float4 worldPos_ProjPosZ : TEXCOORD7; - float4 fogFactorW : COLOR1; -#if SEAMLESS_DETAIL || SEAMLESS_BASE - float3 SeamlessWeights : COLOR0; // x y z projection weights -#endif - -}; - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - bool bDynamicLight = DYNAMIC_LIGHT ? true : false; - bool bStaticLight = STATIC_LIGHT_VERTEX ? true : false; - bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); - - float4 vPosition = v.vPos; - float3 vNormal = 0; - if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) - { - // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) - DecompressVertex_Normal( v.vNormal, vNormal ); - } - -#if SEAMLESS_BASE || SEAMLESS_DETAIL - // compute blend weights in rgb - float3 NNormal=normalize( vNormal ); - o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. -#endif - -#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING - ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); -#else - ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, - v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); -#endif - - // Perform skinning - float3 worldNormal, worldPos; - SkinPositionAndNormal( - g_bSkinning, - vPosition, vNormal, - v.vBoneWeights, v.vBoneIndices, - worldPos, worldNormal ); - - if ( !g_bVertexColor ) - { - worldNormal = normalize( worldNormal ); - } - -#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL - // Avoid z precision errors - worldPos += worldNormal * 0.05f * v.vTexCoord2.z; -#endif - - o.worldSpaceNormal = worldNormal; - - // Transform into projection space - float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); - o.projPos = vProjPos; - vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); - - o.vProjPos = vProjPos; - o.fogFactorW.w = CalcFog( worldPos, vProjPos, g_FogType ); -#if !defined( _X360 ) - o.fog = o.fogFactorW.w; -#endif - o.worldPos_ProjPosZ.xyz = worldPos.xyz; - o.worldPos_ProjPosZ.w = vProjPos.z; - - // Needed for cubemaps -#if CUBEMAP - o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); -#endif - -#if !defined (_X360) && FLASHLIGHT - o.color = float4( 0.0f, 0.0f, 0.0f, 0.0f ); -#else - if ( g_bVertexColor ) - { - // Assume that this is unlitgeneric if you are using vertex color. - o.color.rgb = ( DONT_GAMMA_CONVERT_VERTEX_COLOR ) ? v.vColor.rgb : GammaToLinear( v.vColor.rgb ); - o.color.a = v.vColor.a; - } - else - { - #if ( ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) ) - { - o.color.xyz = DoLighting( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert ); - } - #else - { - o.color.xyz = DoLightingUnrolled( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); - } - #endif - } -#endif - - -#if SEAMLESS_BASE - o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; -#else - // Base texture coordinates - o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); - o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); -#endif - -#if SEAMLESS_DETAIL - // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so - // that scale works. More smartness could allow 3d xform. - o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*cDetailTexCoordTransform[0].x) * v.vPos.xyz; -#else - // Detail texture coordinates - // FIXME: This shouldn't have to be computed all the time. - o.detailTexCoord.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); - o.detailTexCoord.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); -#endif - -#if SEPARATE_DETAIL_UVS - o.detailTexCoord.xy = v.vTexCoord1.xy; -#endif - -#if LIGHTING_PREVIEW - float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); - o.color.xyz=float3(dot,dot,dot); -#endif - -#if defined ( _X360 ) && FLASHLIGHT - o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); -#endif - - return o; -} - - diff --git a/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc b/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc deleted file mode 100644 index 52812637..00000000 --- a/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc +++ /dev/null @@ -1,68 +0,0 @@ -//======= Copyright 1996-2006, Valve Corporation, All rights reserved. ====== - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "DIFFUSELIGHTING" "0..1" -// STATIC: "HALFLAMBERT" "0..1" - -// DYNAMIC: "AMBIENT_LIGHT" "0..1" -// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] -// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] - -#define HDRTYPE HDR_TYPE_NONE -#include "common_vertexlitgeneric_dx9.h" - -const float4 g_OverbrightFactor : register( c4 ); -const float3 cAmbientCube[6] : register( c6 ); - -PixelShaderLightInfo cLightInfo[3] : register(c13); - -sampler BumpmapSampler : register( s0 ); -sampler NormalizeSampler : register( s1 ); - -struct PS_INPUT -{ - float2 baseTexCoord : TEXCOORD0; - // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. - float2 detailOrBumpTexCoord : TEXCOORD1; - // bump mapping and a separate envmap mask texture are mutually exclusive. - float2 envmapMaskTexCoord : TEXCOORD2; - float3 worldVertToEyeVector : TEXCOORD3; - float3x3 tangentSpaceTranspose : TEXCOORD4; - float4 worldPos_projPosZ : TEXCOORD5; - float2 lightAtten01 : TEXCOORD6; - float2 lightAtten23 : TEXCOORD7; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; - bool bHalfLambert = HALFLAMBERT ? true : false; - bool bAmbientLight = AMBIENT_LIGHT ? true : false; - int nNumLights = NUM_LIGHTS; - - float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); - - float3 tangentSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); - float4 normalTexel = 1.0f; - float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); - - normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord ); - tangentSpaceNormal = 2.0f * normalTexel - 1.0f; - - float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); - if( bDiffuseLighting ) - { - float3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal ); - float3 staticLightingColor = float3( 0.0f, 0.0f, 0.0f ); - diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, - float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, - vLightAtten, cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, - false, 0, false, NormalizeSampler ); - // multiply by .5 since we want a 50% (in gamma space) reflective surface) - diffuseLighting *= pow( 0.5f, 2.2f ); - } - - return FinalOutput( float4( diffuseLighting, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} - diff --git a/materialsystem/stdshaders/vertexlit_notexture.psh b/materialsystem/stdshaders/vertexlit_notexture.psh deleted file mode 100644 index 5241abd7..00000000 --- a/materialsystem/stdshaders/vertexlit_notexture.psh +++ /dev/null @@ -1,13 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -mov r0, v0 -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - diff --git a/materialsystem/stdshaders/vertexlitgeneric.cpp b/materialsystem/stdshaders/vertexlitgeneric.cpp new file mode 100644 index 00000000..378c39be --- /dev/null +++ b/materialsystem/stdshaders/vertexlitgeneric.cpp @@ -0,0 +1,591 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=====================================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "emissive_scroll_blended_pass_helper.h" +#include "cloak_blended_pass_helper.h" +#include "flesh_interior_blended_pass_helper.h" + +#ifdef GAME_SHADER_DLL +#include "weapon_sheen_pass_helper.h" +#endif + + +BEGIN_VS_SHADER( SDK_VertexLitGeneric, "Help for SDK_VertexLitGeneric" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( COMPRESS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "compression wrinklemap" ) + SHADER_PARAM( STRETCH, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "expansion wrinklemap" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPCOMPRESS, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "compression bump map" ) + SHADER_PARAM( BUMPSTRETCH, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "expansion bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( SELFILLUM_ENVMAPMASK_ALPHA, SHADER_PARAM_TYPE_FLOAT,"0.0","defines that self illum value comes from env map mask alpha" ) + SHADER_PARAM( SELFILLUMFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "Self illum fresnel" ) + SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) + + // Debugging term for visualizing ambient data on its own + SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) + + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "warp the specular term" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( BASEMAPALPHAPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "indicates that there is no normal map and that the phong mask is in base alpha" ) + SHADER_PARAM( INVERTPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "invert the phong mask (0=full phong, 1=no phong)" ) + SHADER_PARAM( ENVMAPFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "Degree to which Fresnel should be applied to env map" ) + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + // Rim lighting terms + SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" ) + SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" ) + SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" ) + SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" ) + + // Seamless mapping scale + SHADER_PARAM( SEAMLESS_BASE, SHADER_PARAM_TYPE_BOOL, "0", "whether to apply seamless mapping to the base texture. requires a smooth model." ) + SHADER_PARAM( SEAMLESS_DETAIL, SHADER_PARAM_TYPE_BOOL, "0", "where to apply seamless mapping to the detail texture." ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "the scale for the seamless mapping. # of repetions of texture per inch." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + +#ifdef GAME_SHADER_DLL + // Weapon Sheen Pass + SHADER_PARAM( SHEENPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables weapon sheen render in a second pass" ) + SHADER_PARAM( SHEENMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "sheenmap" ) + SHADER_PARAM( SHEENMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "sheenmap mask" ) + SHADER_PARAM( SHEENMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( SHEENMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "sheenmap tint" ) + SHADER_PARAM( SHEENMAPMASKSCALEX, SHADER_PARAM_TYPE_FLOAT, "1", "X Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKSCALEY, SHADER_PARAM_TYPE_FLOAT, "1", "Y Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETX, SHADER_PARAM_TYPE_FLOAT, "0", "X Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETY, SHADER_PARAM_TYPE_FLOAT, "0", "Y Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKDIRECTION, SHADER_PARAM_TYPE_INTEGER, "0", "The direction the sheen should move (length direction of weapon) XYZ, 0,1,2" ) + SHADER_PARAM( SHEENINDEX, SHADER_PARAM_TYPE_INTEGER, "0", "Index of the Effect Type (Color Additive, Override etc...)" ) +#endif + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries. Only supported without bumpmaps" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + +#ifdef MAPBASE + SHADER_PARAM( ALLOWDIFFUSEMODULATION, SHADER_PARAM_TYPE_BOOL, "1", "Allow per-instance color modulation" ) + + SHADER_PARAM( ENVMAPFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC3, "[0.0 1.0 2.0]", "Min/max fresnel range and exponent for vertexlitgeneric" ) + SHADER_PARAM( BASEALPHAENVMAPMASKMINMAXEXP, SHADER_PARAM_TYPE_VEC3, "[1.0 0.0 1.0]", "" ) + + SHADER_PARAM( PHONGDISABLEHALFLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Disable half lambert for phong" ) +#endif + + // vertexlitgeneric tree sway animation control + SHADER_PARAM( TREESWAY, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( TREESWAYHEIGHT, SHADER_PARAM_TYPE_FLOAT, "1000", "" ) + SHADER_PARAM( TREESWAYSTARTHEIGHT, SHADER_PARAM_TYPE_FLOAT, "0.2", "" ) + SHADER_PARAM( TREESWAYRADIUS, SHADER_PARAM_TYPE_FLOAT, "300", "" ) + SHADER_PARAM( TREESWAYSTARTRADIUS, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSPEED, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + SHADER_PARAM( TREESWAYSPEEDHIGHWINDMULTIPLIER, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( TREESWAYSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "10", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESPEED, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLESTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFREQUENCY, SHADER_PARAM_TYPE_FLOAT, "0.1", "" ) + SHADER_PARAM( TREESWAYFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.5", "" ) + SHADER_PARAM( TREESWAYSCRUMBLEFALLOFFEXP, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPSTART, SHADER_PARAM_TYPE_FLOAT, "3", "" ) + SHADER_PARAM( TREESWAYSPEEDLERPEND, SHADER_PARAM_TYPE_FLOAT, "6", "" ) + SHADER_PARAM( TREESWAYSTATIC, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( TREESWAYSTATICVALUES, SHADER_PARAM_TYPE_VEC2, "[0.5 0.5]", "" ) + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nWrinkle = COMPRESS; + info.m_nStretch = STRETCH; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nNormalWrinkle = BUMPCOMPRESS; + info.m_nNormalStretch = BUMPSTRETCH; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; + + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nSelfIllumEnvMapMask_Alpha = SELFILLUM_ENVMAPMASK_ALPHA; + info.m_nSelfIllumFresnel = SELFILLUMFRESNEL; + info.m_nSelfIllumFresnelMinMaxExp = SELFILLUMFRESNELMINMAXEXP; + + info.m_nAmbientOnly = AMBIENTONLY; + info.m_nPhongExponent = PHONGEXPONENT; + info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE; + info.m_nPhongTint = PHONGTINT; + info.m_nPhongAlbedoTint = PHONGALBEDOTINT; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + info.m_nPhongWarpTexture = PHONGWARPTEXTURE; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhong = PHONG; + info.m_nBaseMapAlphaPhongMask = BASEMAPALPHAPHONGMASK; + info.m_nEnvmapFresnel = ENVMAPFRESNEL; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + // Rim lighting parameters + info.m_nRimLight = RIMLIGHT; + info.m_nRimLightPower = RIMLIGHTEXPONENT; + info.m_nRimLightBoost = RIMLIGHTBOOST; + info.m_nRimMask = RIMMASK; + + // seamless + info.m_nSeamlessScale = SEAMLESS_SCALE; + info.m_nSeamlessDetail = SEAMLESS_DETAIL; + info.m_nSeamlessBase = SEAMLESS_BASE; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nDetailTint = DETAILTINT; + info.m_nInvertPhongMask = INVERTPHONGMASK; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + + info.m_nSelfIllumMask = SELFILLUMMASK; + info.m_nBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA; + info.m_nTintReplacesBaseColor = BLENDTINTCOLOROVERBASE; + +#ifdef MAPBASE + info.m_nAllowDiffuseModulation = ALLOWDIFFUSEMODULATION; + + info.m_nEnvMapFresnelMinMaxExp = ENVMAPFRESNELMINMAXEXP; + info.m_nBaseAlphaEnvMapMaskMinMaxExp = BASEALPHAENVMAPMASKMINMAXEXP; + + info.m_nPhongDisableHalfLambert = PHONGDISABLEHALFLAMBERT; +#endif + + info.m_nTreeSway = TREESWAY; + info.m_nTreeSwayHeight = TREESWAYHEIGHT; + info.m_nTreeSwayStartHeight = TREESWAYSTARTHEIGHT; + info.m_nTreeSwayRadius = TREESWAYRADIUS; + info.m_nTreeSwayStartRadius = TREESWAYSTARTRADIUS; + info.m_nTreeSwaySpeed = TREESWAYSPEED; + info.m_nTreeSwaySpeedHighWindMultiplier = TREESWAYSPEEDHIGHWINDMULTIPLIER; + info.m_nTreeSwayStrength = TREESWAYSTRENGTH; + info.m_nTreeSwayScrumbleSpeed = TREESWAYSCRUMBLESPEED; + info.m_nTreeSwayScrumbleStrength = TREESWAYSCRUMBLESTRENGTH; + info.m_nTreeSwayScrumbleFrequency = TREESWAYSCRUMBLEFREQUENCY; + info.m_nTreeSwayFalloffExp = TREESWAYFALLOFFEXP; + info.m_nTreeSwayScrumbleFalloffExp = TREESWAYSCRUMBLEFALLOFFEXP; + info.m_nTreeSwaySpeedLerpStart = TREESWAYSPEEDLERPSTART; + info.m_nTreeSwaySpeedLerpEnd = TREESWAYSPEEDLERPEND; + info.m_nTreeSwayStatic = TREESWAYSTATIC; + info.m_nTreeSwayStaticValues = TREESWAYSTATICVALUES; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + +#ifdef GAME_SHADER_DLL + // Weapon Sheen Pass + void SetupVarsWeaponSheenPass( WeaponSheenPassVars_t &info ) + { + info.m_nSheenMap = SHEENMAP; + info.m_nSheenMapMask = SHEENMAPMASK; + info.m_nSheenMapMaskFrame = SHEENMAPMASKFRAME; + info.m_nSheenMapTint = SHEENMAPTINT; + info.m_nSheenMapMaskScaleX = SHEENMAPMASKSCALEX; + info.m_nSheenMapMaskScaleY = SHEENMAPMASKSCALEY; + info.m_nSheenMapMaskOffsetX = SHEENMAPMASKOFFSETX; + info.m_nSheenMapMaskOffsetY = SHEENMAPMASKOFFSETY; + info.m_nSheenMapMaskDirection = SHEENMAPMASKDIRECTION; + info.m_nSheenIndex = SHEENINDEX; + + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } +#endif + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + +#ifdef GAME_SHADER_DLL + if ( params[SHEENPASSENABLED]->GetIntValue() ) // If material supports weapon sheen + return true; +#endif + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; + } + + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, true, vars ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + +#ifdef GAME_SHADER_DLL + // Sheen Pass + if ( !params[SHEENPASSENABLED]->IsDefined() ) + { + params[SHEENPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitParamsWeaponSheenPass( this, params, pMaterialName, info ); + } +#endif + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 80) + return "VertexLitGeneric_DX7"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "VertexLitGeneric_DX8"; + + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, true, vars ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + +#ifdef GAME_SHADER_DLL + // TODO : Only do this if we're in range of the camera + // Weapon Sheen + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitWeaponSheenPass( this, params, info ); + } +#endif + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, true, vars, vertexCompression, pContextDataPtr ); + } + else + { + // Skip this pass! + Draw( false ); + } + +#ifdef GAME_SHADER_DLL + // Weapon sheen pass + // only if doing standard as well (don't do it if cloaked) + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + if ( ( pShaderShadow != NULL ) || ( bDrawStandardPass && ShouldDrawMaterialSheen( params, info ) ) ) + { + DrawWeaponSheenPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + } +#endif + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh deleted file mode 100644 index db80aefd..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask (in alpha channel) - -mul r0, t0, c3 ; base times modulation -mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) -mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh deleted file mode 100644 index 82989f4e..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask (in alpha channel) -tex t3 ; detail texture - -mul r0, t0, c3 ; base times modulation -mul_x2 r0.rgb, r0, t3 ; detail texture -mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) -mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh deleted file mode 100644 index e95d932b..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t3 ; detail texture - -mul r0, t0, c3 ; base times modulation -mul_x2 r0.rgb, r0, t3 ; detail texture -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh deleted file mode 100644 index ace4a68f..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh +++ /dev/null @@ -1,21 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask -tex t3 ; detail texture - -mul r0, t0, c3 ; Base times modulation -mul_x2 r0.rgb, r0, t3 ; detail texture -mul r1, t1, t2 ; Envmap * mask -mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh deleted file mode 100644 index 9cc71776..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh +++ /dev/null @@ -1,28 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 -tex t1 -tex t3 - -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) - -mul_x2 r0.rgb, r0, t3 ; detail texture - -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - diff --git a/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh deleted file mode 100644 index 24396a07..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh +++ /dev/null @@ -1,29 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 ; base -tex t1 ; env map -tex t2 ; mask -tex t3 ; Detail - -mul r0.rgb, t0, c3 + ; base times modulation -mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha - -mul_x2 r0.rgb, r0, t3 ; detail texture - -mul r1, t2, t1 ; envmapmask * envmap -mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp deleted file mode 100644 index 8ecd111f..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp +++ /dev/null @@ -1,421 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX6 ) - -BEGIN_SHADER( VertexLitGeneric_DX6, - "Help for VertexLitGeneric_DX6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - - if( !params[ENVMAPTINT]->IsDefined() ) - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[SELFILLUMTINT]->IsDefined() ) - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[DETAILSCALE]->IsDefined() ) - params[DETAILSCALE]->SetFloatValue( 4.0f ); - - // No envmap uses mode 0, it's one less pass - // Also, if multipass = 0, then go to mode 0 also - if ( ( !params[ENVMAP]->IsDefined() ) || - ( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) ) - { - CLEAR_FLAGS( MATERIAL_VAR_ENVMAPMODE ); - } - - // Vertex color requires mode 1 - if ( IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPMODE ); - } - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if ( IS_FLAG_SET(MATERIAL_VAR_DECAL) ) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - SET_FLAGS2( MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING ); - - // Get rid of the envmap if it's optional for this dx level. - if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) - { - params[ENVMAP]->SetUndefined(); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - LoadCubeMap( ENVMAP ); - else - LoadTexture( ENVMAP ); - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if (params[ENVMAPMASK]->IsDefined()) - LoadTexture( ENVMAPMASK ); - } - } - - int GetDrawFlagsPass1(IMaterialVar** params) - { - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_COLOR; - if (params[BASETEXTURE]->IsTexture()) - flags |= SHADER_DRAW_TEXCOORD0; - return flags; - } - - void DrawVertexLightingOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); - - SetModulationShadowState(); - SetDefaultBlendingShadowState( ); - pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); - DefaultFog(); - } - DYNAMIC_STATE - { - SetModulationDynamicState(); - } - Draw(); - } - - void MultiplyByVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - // FIXME: How to deal with texture alpha?? - - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); - - // NOTE: We're not doing lightmapping here, but we want to use the - // same blend mode as we used for lightmapping - pShaderShadow->EnableBlending( true ); - SingleTextureLightmapBlendMode(); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 1 ); - - // This here will perform color = vertex light * (cc alpha) + 1 * (1 - cc alpha) - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_CONSTANTALPHA, - SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); - - // Alpha isn't used, it doesn't matter what we set it to. - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); - - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR ); - FogToOOOverbright(); - } - DYNAMIC_STATE - { - // Put the alpha in the color channel to modulate the color down.... - float alpha = GetAlpha(); - pShaderAPI->Color4f( OO_OVERBRIGHT, OO_OVERBRIGHT, OO_OVERBRIGHT, alpha ); - } - Draw(); - - SHADOW_STATE - { - pShaderShadow->EnableCustomPixelPipe( false ); - } - } - - - //----------------------------------------------------------------------------- - // Used by mode 1 - //----------------------------------------------------------------------------- - - void DrawBaseTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // Base times vertex lighting, no vertex color - SHADOW_STATE - { - // alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - // base - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - - // Independenly configure alpha and color - - // Color = Color mod * Vertex Light * Tex (x2) - // Alpha = Constant Alpha * Tex Alpha (no tex alpha if self illum == 1) - // Can't have color modulation here - pShaderShadow->EnableConstantColor( IsColorModulating() ); - - // Independenly configure alpha and color - pShaderShadow->EnableAlphaPipe( true ); - pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); - pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); - - if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, true ); - - SetDefaultBlendingShadowState( BASETEXTURE, true ); - pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); - DefaultFog(); - } - DYNAMIC_STATE - { - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetModulationDynamicState(); - } - Draw(); - - SHADOW_STATE - { - pShaderShadow->EnableAlphaPipe( false ); - } - } - - //----------------------------------------------------------------------------- - // Envmap times vertex lighting, no vertex color - //----------------------------------------------------------------------------- - - void DrawEnvmapTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - int materialVarFlags = params[FLAGS]->GetIntValue(); - - // alpha test - pShaderShadow->EnableAlphaTest( false ); - - int flags = SetShadowEnvMappingState( ENVMAPMASK ) | SHADER_DRAW_COLOR; - bool hasEnvMapMask = params[ENVMAPMASK]->IsTexture(); - - pShaderShadow->OverbrightValue( hasEnvMapMask ? - SHADER_TEXTURE_STAGE1 : SHADER_TEXTURE_STAGE0, OVERBRIGHT ); - - // Independenly configure alpha and color - - // Color = Env map * Vertex Light * Envmapmask (x2) - // Alpha = Constant Alpha * Vertex light alpha * Env Map mask Alpha - pShaderShadow->EnableConstantColor( IsColorModulating() ); - - pShaderShadow->EnableAlphaPipe( true ); - pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); - pShaderShadow->EnableVertexAlpha( (materialVarFlags & MATERIAL_VAR_VERTEXALPHA) != 0 ); - if (hasEnvMapMask) - pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, true ); - - SetDefaultBlendingShadowState( BASETEXTURE, true ); - - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - } - DYNAMIC_STATE - { - SetDynamicEnvMappingState( ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); - } - Draw(); - - SHADOW_STATE - { - pShaderShadow->EnableCustomPixelPipe( false ); - pShaderShadow->EnableAlphaPipe( false ); - } - } - - void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - bool texDefined = params[BASETEXTURE]->IsTexture(); - bool envDefined = params[ENVMAP]->IsTexture(); -// bool maskDefined = params[ENVMAPMASK]->IsTexture(); - - // Pass 1 : Base + env - - // FIXME: Could make it 1 pass for base + env, if it wasn't - // for the envmap tint. So this is 3 passes for now.... - - // If it's base + mask * env, gotta do that in 2 passes - // Gotta do funky stuff to fade out self-illuminated stuff - bool hasEnvMapTint = !IsWhite(ENVMAPTINT); - - // Special case, can do in one pass - if (!hasEnvMapTint && !texDefined && !IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) && - !IsColorModulating() ) - { - DrawEnvmapTimesVertexLighting( params, pShaderAPI, pShaderShadow ); - return; - } - - if (texDefined) - { - FixedFunctionBaseTimesDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - else - { - FixedFunctionMaskedEnvmapPass( - ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - - // We can get here if multipass isn't set if we specify a vertex color - if ( IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) - { - if ( texDefined && envDefined ) - { - FixedFunctionAdditiveMaskedEnvmapPass( - ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - } - - // Pass 2 : * vertex lighting - MultiplyByVertexLighting( params, pShaderAPI, pShaderShadow ); - - // FIXME: We could add it to the lightmap - // Draw the selfillum pass (blows away envmap at self-illum points) - if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) - { - FixedFunctionSelfIlluminationPass( - SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); - } - } - - void DrawMode0( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - // Pass 1 : Base * lightmap or just lightmap - if ( params[BASETEXTURE]->IsTexture() ) - { - DrawBaseTimesVertexLighting( params, pShaderAPI, pShaderShadow ); - - // Detail map - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - - // Draw the selfillum pass - if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) - { - FixedFunctionSelfIlluminationPass( - SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); - } - } - else - { - DrawVertexLightingOnly( params, pShaderAPI, pShaderShadow ); - - // Detail map - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - - // Pass 2 : Masked environment map - if ( params[ENVMAP]->IsTexture() && - (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) - { - FixedFunctionAdditiveMaskedEnvmapPass( - ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - } - - SHADER_DRAW - { - bool useMode1 = IS_FLAG_SET(MATERIAL_VAR_ENVMAPMODE); - if (!useMode1) - { - // Base * Vertex Lighting + env - DrawMode0( params, pShaderAPI, pShaderShadow ); - } - else - { - // ( Base + env ) * Vertex Lighting - DrawMode1( params, pShaderAPI, pShaderShadow ); - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp deleted file mode 100644 index 7a114a56..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp +++ /dev/null @@ -1,413 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX7 ) -DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX7 ) - -BEGIN_SHADER( VertexLitGeneric_DX7, - "Help for VertexLitGeneric_DX7" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - - if( !params[ENVMAPTINT]->IsDefined() ) - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[SELFILLUMTINT]->IsDefined() ) - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[DETAILSCALE]->IsDefined() ) - params[DETAILSCALE]->SetFloatValue( 4.0f ); - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - SET_FLAGS2( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ); - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - } - - SHADER_FALLBACK - { - if (g_pHardwareConfig->GetDXSupportLevel() < 70) - return "VertexLitGeneric_DX6"; - - return 0; - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - LoadCubeMap( ENVMAP ); - else - LoadTexture( ENVMAP ); - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if (params[ENVMAPMASK]->IsDefined()) - LoadTexture( ENVMAPMASK ); - } - } - - void DrawBaseTimesVertexColor( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - // alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - pShaderShadow->EnableCustomPixelPipe( true ); - - pShaderShadow->CustomTextureStages( 1 ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_VERTEXCOLOR ); - - // Get alpha from the texture so that alpha blend and alpha test work properly. - bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); - if ( bTextureIsTranslucent ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); - } - else - { - if ( IsAlphaModulating() ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); - } - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL | SHADER_DRAW_TEXCOORD0; - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - - if ( IsAlphaModulating() || IsColorModulating() ) - { - pShaderShadow->CustomTextureStages( 2 ); - - if ( IsColorModulating() ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); - } - - // Get alpha from the texture so that alpha blend and alpha test work properly. - if ( IsAlphaModulating() && bTextureIsTranslucent ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); - } - } - - SetDefaultBlendingShadowState( BASETEXTURE, true ); - } - DYNAMIC_STATE - { - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetModulationDynamicState(); - } - Draw(); - } - - void DrawVertexColorNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - pShaderShadow->EnableCustomPixelPipe( true ); - - pShaderShadow->CustomTextureStages( 1 ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_ONE, SHADER_TEXARG_VERTEXCOLOR ); - - int flags = SHADER_DRAW_POSITION; - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - } - DYNAMIC_STATE - { -// SetModulationDynamicState(); - } - Draw(); - } - - void DrawBaseTimesBakedVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - // alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); - - // base - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - int flags = SHADER_DRAW_POSITION; - if (params[BASETEXTURE]->IsTexture()) - { - flags |= SHADER_DRAW_TEXCOORD1; - } - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 1 ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_TEXTURE ); - - // Get alpha from the texture so that alpha blend and alpha test work properly. - bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); - if ( bTextureIsTranslucent ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); - } - else - { - if ( IsAlphaModulating() ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); - } - } - - if ( IsAlphaModulating() || IsColorModulating() ) - { - pShaderShadow->CustomTextureStages( 2 ); - - if ( IsColorModulating()) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); - } - - // Get alpha from the texture so that alpha blend and alpha test work properly. - if ( IsAlphaModulating() && bTextureIsTranslucent ) - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); - } - else - { - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); - } - } - - SetDefaultBlendingShadowState( BASETEXTURE, true ); - } - DYNAMIC_STATE - { - SetFixedFunctionTextureTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM ); - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetModulationDynamicState(); - } - Draw(); - } - - void DrawBakedVertexLightingNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) - { - SHADOW_STATE - { - int flags = SHADER_DRAW_POSITION; - pShaderShadow->DrawFlags( flags ); - DefaultFog(); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 1 ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_NONE ); - - // Alpha isn't used, it doesn't matter what we set it to. - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); - } - DYNAMIC_STATE - { - } - Draw(); - } - - SHADER_DRAW - { - bool bBakedLighting = IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ); - bool hasFlashlight = UsingFlashlight( params ); - - if( hasFlashlight ) - { - DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - return; - } - // Pass 1 : Base * lightmap or just lightmap - if ( params[BASETEXTURE]->IsTexture() ) - { - // Draw base times lighting. - // Lighting is either sent down per vertex from the app, or it's in the second - // stream as color values. - if( bBakedLighting ) - { - DrawBaseTimesBakedVertexLighting( params, pShaderAPI, pShaderShadow ); - } - else - { - DrawBaseTimesVertexColor( params, pShaderAPI, pShaderShadow ); - } - - // Detail map - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - - // Draw the selfillum pass - if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) - { - FixedFunctionSelfIlluminationPass( - SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); - } - } - else - { - if( bBakedLighting ) - { - DrawBakedVertexLightingNoBase( params, pShaderAPI, pShaderShadow ); - } - else - { - DrawVertexColorNoBase( params, pShaderAPI, pShaderShadow ); - } - - FixedFunctionMultiplyByDetailPass( - BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); - } - - - // Pass 2 : Masked environment map - if ( params[ENVMAP]->IsTexture() && (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) - { - FixedFunctionAdditiveMaskedEnvmapPass( - ENVMAP, ENVMAPMASK, BASETEXTURE, - ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, - BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); - } - - } -END_SHADER diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp deleted file mode 100644 index 31addf42..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp +++ /dev/null @@ -1,807 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "vertexlitgeneric_vs11.inc" -#include "vertexlitgeneric_selfillumonly.inc" -#include "emissive_scroll_blended_pass_helper.h" -#include "flesh_interior_blended_pass_helper.h" -#include "cloak_blended_pass_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX8 ) -DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX8 ) - -BEGIN_VS_SHADER( VertexLitGeneric_DX8, - "Help for VertexLitGeneric" ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) - SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) - - // Emissive Scroll Pass - SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) - SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) - SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) - SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) - SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) - SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) - - // Cloak Pass - SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) - SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) - - // Flesh Interior Pass - SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) - SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) - SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) - SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) - SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) - SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) - SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) - SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) - SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) - SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) - SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) - SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) - SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) - SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) - SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) - - // Color Replacement Pass - SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") - SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) - - END_SHADER_PARAMS - - // Cloak Pass - void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) - { - info.m_nCloakFactor = CLOAKFACTOR; - info.m_nCloakColorTint = CLOAKCOLORTINT; - info.m_nRefractAmount = REFRACTAMOUNT; - - // Delete these lines if not bump mapping! - info.m_nBumpmap = BUMPMAP; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - } - - bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time - return true; - else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag2 in case the base material still needs it - } - - // Check flag2 if not drawing cloak pass - return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); - } - - bool IsTranslucent( IMaterialVar **params ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag in case the base material still needs it - } - - // Check flag if not drawing cloak pass - return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); - } - - // Emissive Scroll Pass - void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) - { - info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; - info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; - info.m_nFlowTexture = -1; // Not used in DX8 - info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; - info.m_nEmissiveTint = EMISSIVEBLENDTINT; - info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; - info.m_nTime = TIME; - } - - // Flesh Interior Pass - void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) - { - info.m_nFleshTexture = FLESHINTERIORTEXTURE; - info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; - info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; - info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; - info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; - info.m_nFleshCubeTexture = FLESHCUBETEXTURE; - - info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; - info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; - info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; - info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; - info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; - info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; - - info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; - info.m_nflBorderWidth = FLESHBORDERWIDTH; - info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; - info.m_ncBorderTint = FLESHBORDERTINT; - info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; - info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; - info.m_nflScrollSpeed = FLESHSCROLLSPEED; - - info.m_nTime = TIME; - } - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - // We don't want no stinking bump mapping on models in dx8. - // Wait a minute! We want specular bump. .need to make that work by itself. -// params[BUMPMAP]->SetUndefined(); -// if( IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) ) -// { -// CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); -// params[ENVMAP]->SetUndefined(); -// } - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if( !params[ENVMAPMASKSCALE]->IsDefined() ) - params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); - - if( !params[ENVMAPMASKFRAME]->IsDefined() ) - params[ENVMAPMASKFRAME]->SetIntValue( 0 ); - - if( !params[ENVMAPTINT]->IsDefined() ) - params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[SELFILLUMTINT]->IsDefined() ) - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - - if( !params[DETAILSCALE]->IsDefined() ) - params[DETAILSCALE]->SetFloatValue( 4.0f ); - - if( !params[DETAILBLENDFACTOR]->IsDefined() ) - params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); - - if( !params[DETAILBLENDMODE]->IsDefined() ) - params[DETAILBLENDMODE]->SetFloatValue( 0 ); - - if( !params[ENVMAPCONTRAST]->IsDefined() ) - params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); - - if( !params[ENVMAPSATURATION]->IsDefined() ) - params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); - - if( !params[ENVMAPFRAME]->IsDefined() ) - params[ENVMAPFRAME]->SetIntValue( 0 ); - - if( !params[BUMPFRAME]->IsDefined() ) - params[BUMPFRAME]->SetIntValue( 0 ); - - if( !params[ALPHATESTREFERENCE]->IsDefined() ) - params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); - - // No texture means no self-illum or env mask in base alpha - if ( !params[BASETEXTURE]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - - // Get rid of the envmap if it's optional for this dx level. - if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) - { - params[ENVMAP]->SetUndefined(); - } - - // If mat_specular 0, then get rid of envmap - if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) - { - params[ENVMAP]->SetUndefined(); - } - - // If a bumpmap is defined but an envmap isn't, then ignore the bumpmap. - // It was meant to be used with diffuse - if ( !params[ENVMAP]->IsDefined() ) - { - params[BUMPMAP]->SetUndefined(); - } - - // Cloak Pass - if ( !params[CLOAKPASSENABLED]->IsDefined() ) - { - params[CLOAKPASSENABLED]->SetIntValue( 0 ); - } - else if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitParamsCloakBlendedPass( this, params, pMaterialName, info ); - } - - // Emissive Scroll Pass - if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) - { - params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); - } - else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); - } - - // Flesh Interior Pass - if ( !params[FLESHINTERIORENABLED]->IsDefined() ) - { - params[FLESHINTERIORENABLED]->SetIntValue( 0 ); - } - else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); - } - - // Color Replacement Pass - if ( !params[BLENDTINTBYBASEALPHA]->IsDefined() ) - { - params[BLENDTINTBYBASEALPHA]->SetIntValue(0); - } - - if ( !params[BLENDTINTCOLOROVERBASE]->IsDefined() ) - { - params[BLENDTINTCOLOROVERBASE]->SetFloatValue(0); - } - } - - SHADER_FALLBACK - { - if ( IsPC() ) - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 70) - return "VertexLitGeneric_DX6"; - - if ( g_pHardwareConfig->GetDXSupportLevel() < 80) - return "VertexLitGeneric_DX7"; - - if ( g_pHardwareConfig->PreferReducedFillrate() ) - return "VertexLitGeneric_NoBump_DX8"; - } - return 0; - } - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - - if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - - if (g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined()) - { - LoadBumpMap( BUMPMAP ); - } - - // Don't alpha test if the alpha channel is used for other purposes - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - { - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - } - - if (params[ENVMAP]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - { - LoadCubeMap( ENVMAP ); - } - else - { - LoadTexture( ENVMAP ); - } - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - - if (params[ENVMAPMASK]->IsDefined()) - { - LoadTexture( ENVMAPMASK ); - } - } - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitCloakBlendedPass( this, params, info ); - } - - // Emissive Scroll Pass - if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - InitEmissiveScrollBlendedPass( this, params, info ); - } - - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitFleshInteriorBlendedPass( this, params, info ); - } - } - - inline const char *GetUnbumpedPixelShaderName( IMaterialVar** params, bool bSkipEnvmap ) - { - static char const* s_pPixelShaders[] = - { - "VertexLitGeneric_EnvmapV2", - "VertexLitGeneric_SelfIlluminatedEnvmapV2", - - "VertexLitGeneric_BaseAlphaMaskedEnvmapV2", - "VertexLitGeneric_SelfIlluminatedEnvmapV2", - - // Env map mask - "VertexLitGeneric_MaskedEnvmapV2", - "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", - - "VertexLitGeneric_MaskedEnvmapV2", - "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", - - // Detail - "VertexLitGeneric_DetailEnvmapV2", - "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", - - "VertexLitGeneric_DetailBaseAlphaMaskedEnvmapV2", - "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", - - // Env map mask - "VertexLitGeneric_DetailMaskedEnvmapV2", - "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", - - "VertexLitGeneric_DetailMaskedEnvmapV2", - "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", - }; - - if ( !params[BASETEXTURE]->IsTexture() ) - { - if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) - { - if (!params[ENVMAPMASK]->IsTexture()) - { - return "VertexLitGeneric_EnvmapNoTexture"; - } - else - { - return "VertexLitGeneric_MaskedEnvmapNoTexture"; - } - } - else - { - if ( params[DETAIL]->IsTexture() ) - { - return "VertexLitGeneric_DetailNoTexture"; - } - else - { - return "VertexLitGeneric_NoTexture"; - } - } - } - else - { - if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) - { - return "VertexLitGeneric_BlendTint"; - } - else if ( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) - { - int pshIndex = 0; - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) - pshIndex |= 0x1; - if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - pshIndex |= 0x2; - if (params[ENVMAPMASK]->IsTexture()) - pshIndex |= 0x4; - if (params[DETAIL]->IsTexture()) - pshIndex |= 0x8; - return s_pPixelShaders[pshIndex]; - } - else - { - if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) - { - if ( params[DETAIL]->IsTexture() ) - return "VertexLitGeneric_DetailSelfIlluminated"; - else - return "VertexLitGeneric_SelfIlluminated"; - } - else if ( params[DETAIL]->IsTexture() ) - { - switch( params[DETAILBLENDMODE]->GetIntValue() ) - { - case 0: - return "VertexLitGeneric_Detail"; - - case 1: // additive modes - return "VertexLitGeneric_Detail_Additive"; - - case 5: - case 6: - return "VertexLitGeneric_Detail_Additive_selfillum"; - break; - - default: - return "VertexLitGeneric_Detail_LerpBase"; - } - } - else - { - return "VertexLitGeneric"; - } - } - } - } - - void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bSkipEnvmap ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); - } - - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - - // FIXME: We could enable this, but we'd never get it working on dx7 or lower - // FIXME: This isn't going to work until we make more vertex shaders that - // pass the vertex color and alpha values through. -#if 0 - if ( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ) ) - fmt |= VERTEX_COLOR; -#endif - - if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) - { - // envmap on stage 1 - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // envmapmask on stage 2 - if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - } - } - - if (params[BASETEXTURE]->IsTexture()) - { - SetDefaultBlendingShadowState( BASETEXTURE, true ); - } - else - { - SetDefaultBlendingShadowState( ENVMAPMASK, false ); - } - - if ( params[DETAIL]->IsTexture()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - } - - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Set up the vertex shader index. - vertexlitgeneric_vs11_Static_Index vshIndex; - vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); - //vshIndex.SetDETAIL( params[DETAIL]->IsTexture() ); - if( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) - { - vshIndex.SetENVMAP( true ); - vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); - if( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ) - { - vshIndex.SetENVMAPSPHERE( false ); - } - else - { - vshIndex.SetENVMAPSPHERE( IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ); - } - } - else - { - vshIndex.SetENVMAP( false ); - vshIndex.SetENVMAPCAMERASPACE( false ); - vshIndex.SetENVMAPSPHERE( false ); - } - pShaderShadow->SetVertexShader( "vertexlitgeneric_vs11", vshIndex.GetIndex() ); - - const char *pshName = GetUnbumpedPixelShaderName( params, bSkipEnvmap ); - pShaderShadow->SetPixelShader( pshName ); - DefaultFog(); - pShaderShadow->EnableAlphaWrites( true ); - } - DYNAMIC_STATE - { - if (params[BASETEXTURE]->IsTexture()) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - } - -// if (params[ENVMAP]->IsTexture()) - if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) - { - BindTexture( SHADER_SAMPLER1, ENVMAP, ENVMAPFRAME ); - - if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - { - if (params[ENVMAPMASK]->IsTexture() ) - BindTexture( SHADER_SAMPLER2, ENVMAPMASK, ENVMAPMASKFRAME ); - else - BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); - - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); - } - - if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || - IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) - { - LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); - } - SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); - } - - if ( params[DETAIL]->IsTexture()) - { - BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); - } - - SetAmbientCubeDynamicStateVertexShader(); - SetModulationPixelShaderDynamicState( 3 ); - EnablePixelShaderOverbright( 0, true, true ); - SetPixelShaderConstant( 1, SELFILLUMTINT ); - - if ( params[DETAIL]->IsTexture() && ( ! IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ) ) - { - float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - c1[0] = c1[1] = c1[2] = c1[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); - pShaderAPI->SetPixelShaderConstant( 1, c1, 1 ); - } - - if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) - { - float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - c1[0] = c1[1] = c1[2] = c1[3] = params[BLENDTINTCOLOROVERBASE]->GetFloatValue(); - pShaderAPI->SetPixelShaderConstant( 1, c1 ); - } - - vertexlitgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - if( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA ) ) - { - pShaderAPI->SetPixelShaderIndex( 0 ); - } - else - { - // write 255 to alpha if we aren't told to write depth to dest alpha (We don't ever actually write depth to dest alpha in dx8) - pShaderAPI->SetPixelShaderIndex( 1 ); - float c4[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - pShaderAPI->SetPixelShaderConstant( 4, c4, 1 ); - } - } - Draw(); - } - - SHADER_DRAW - { - // Skip the standard rendering if cloak pass is fully opaque - bool bDrawStandardPass = true; - if ( false/*disabled! no effect*/ && params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - if ( CloakBlendedPassIsFullyOpaque( params, info ) ) - { - // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now - //bDrawStandardPass = false; - } - } - - // Standard rendering pass - if ( bDrawStandardPass ) - { - // FLASHLIGHTFIXME: need to make these the same. - bool hasFlashlight = UsingFlashlight( params ); - bool bBump = g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsTexture(); - - if( hasFlashlight ) - { - DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1 ); - } - else if( bBump ) - { - bool bSkipEnvmap = true; - DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); - - // specular pass - bool bBlendSpecular = true; - if( params[ENVMAP]->IsTexture() ) - { - DrawModelBumpedSpecularLighting( BUMPMAP, BUMPFRAME, ENVMAP, ENVMAPFRAME, - ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, BUMPTRANSFORM, bBlendSpecular ); - } - } - else - { - bool bSkipEnvmap = false; - DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); - } - } - else - { - // Skip this pass! - Draw( false ); - } - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - - // Emissive Scroll Pass - if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( true ) ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - } -END_SHADER - - -//----------------------------------------------------------------------------- -// Version that doesn't do bumpmapping -//----------------------------------------------------------------------------- -BEGIN_INHERITED_SHADER( VertexLitGeneric_NoBump_DX8, VertexLitGeneric_DX8, - "Help for VertexLitGeneric_NoBump_DX8" ) - - SHADER_FALLBACK - { - if (g_pConfig->bSoftwareLighting) - return "VertexLitGeneric_DX6"; - - if (!g_pHardwareConfig->SupportsVertexAndPixelShaders()) - return "VertexLitGeneric_DX7"; - - return 0; - } - - virtual bool ShouldUseBumpmapping( IMaterialVar **params ) - { - if ( !g_pConfig->UseBumpmapping() ) - return false; - - if ( !params[BUMPMAP]->IsDefined() ) - return false; - - return ( params[FORCEBUMP]->GetIntValue() != 0 ); - } - -END_INHERITED_SHADER - diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp deleted file mode 100644 index 894f00ed..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp +++ /dev/null @@ -1,622 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=====================================================================================// - -#include "BaseVSShader.h" -#include "vertexlitgeneric_dx9_helper.h" -#ifndef VANCE // not even using this smh. im not gonna waste my time on compiling this -#include "emissive_scroll_blended_pass_helper.h" -#include "cloak_blended_pass_helper.h" -#include "flesh_interior_blended_pass_helper.h" -#include "weapon_sheen_pass_helper.h" -#else -#include "vertexlitpbr_dx9_helper.h" -#include "lightpass_helper.h" -#endif // !VANCE - -#ifdef STDSHADER -BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) -#else -BEGIN_VS_SHADER(SDK_VertexLitGeneric, "Help for VertexLitGeneric") -#endif - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) - SHADER_PARAM( COMPRESS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "compression wrinklemap" ) - SHADER_PARAM( STRETCH, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "expansion wrinklemap" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BUMPCOMPRESS, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "compression bump map" ) - SHADER_PARAM( BUMPSTRETCH, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "expansion bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( SELFILLUM_ENVMAPMASK_ALPHA, SHADER_PARAM_TYPE_FLOAT,"0.0","defines that self illum value comes from env map mask alpha" ) - SHADER_PARAM( SELFILLUMFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "Self illum fresnel" ) - SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) - SHADER_PARAM( LIGHTMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "lightmap texture--will be bound by the engine") - - // Debugging term for visualizing ambient data on its own - SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) - - SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) - SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) - SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) - SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) - SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "warp the specular term" ) - SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) - SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) - SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) - SHADER_PARAM( PHONGEXPONENTFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "When using a phong exponent texture, this will be multiplied by the 0..1 that comes out of the texture." ) - SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) - SHADER_PARAM( BASEMAPALPHAPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "indicates that there is no normal map and that the phong mask is in base alpha" ) - SHADER_PARAM( INVERTPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "invert the phong mask (0=full phong, 1=no phong)" ) - SHADER_PARAM( ENVMAPFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "Degree to which Fresnel should be applied to env map" ) - SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) - - // detail (multi-) texturing - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) - SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) - SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) - - // Rim lighting terms - SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" ) - SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" ) - SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" ) - SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" ) - - // Seamless mapping scale - SHADER_PARAM( SEAMLESS_BASE, SHADER_PARAM_TYPE_BOOL, "0", "whether to apply seamless mapping to the base texture. requires a smooth model." ) - SHADER_PARAM( SEAMLESS_DETAIL, SHADER_PARAM_TYPE_BOOL, "0", "where to apply seamless mapping to the detail texture." ) - SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "the scale for the seamless mapping. # of repetions of texture per inch." ) - - // Emissive Scroll Pass - SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) - SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) - SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) - SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) - SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) - SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) - SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) - - // Cloak Pass - SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) - SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) - - // Weapon Sheen Pass - SHADER_PARAM( SHEENPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables weapon sheen render in a second pass" ) - SHADER_PARAM( SHEENMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "sheenmap" ) - SHADER_PARAM( SHEENMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "sheenmap mask" ) - SHADER_PARAM( SHEENMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( SHEENMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "sheenmap tint" ) - SHADER_PARAM( SHEENMAPMASKSCALEX, SHADER_PARAM_TYPE_FLOAT, "1", "X Scale the size of the map mask to the size of the target" ) - SHADER_PARAM( SHEENMAPMASKSCALEY, SHADER_PARAM_TYPE_FLOAT, "1", "Y Scale the size of the map mask to the size of the target" ) - SHADER_PARAM( SHEENMAPMASKOFFSETX, SHADER_PARAM_TYPE_FLOAT, "0", "X Offset of the mask relative to model space coords of target" ) - SHADER_PARAM( SHEENMAPMASKOFFSETY, SHADER_PARAM_TYPE_FLOAT, "0", "Y Offset of the mask relative to model space coords of target" ) - SHADER_PARAM( SHEENMAPMASKDIRECTION, SHADER_PARAM_TYPE_INTEGER, "0", "The direction the sheen should move (length direction of weapon) XYZ, 0,1,2" ) - SHADER_PARAM( SHEENINDEX, SHADER_PARAM_TYPE_INTEGER, "0", "Index of the Effect Type (Color Additive, Override etc...)" ) - - // Flesh Interior Pass - SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) - SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) - SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) - SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) - SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) - SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) - SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) - SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) - SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) - SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) - SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) - SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) - SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) - SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) - SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) - SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) - - SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) - SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) - SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries. Only supported without bumpmaps" ) - SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) - - SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") - SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) -#ifdef VANCE - SHADER_PARAM(PBR, SHADER_PARAM_TYPE_BOOL, "0", "Swap Vertexlitgeneric to VertexlitPBR") - SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") - SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") - SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") - SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") - SHADER_PARAM(USESMOOTHNESS, SHADER_PARAM_TYPE_BOOL, "0", "Invert roughness") -#endif // VANCE - - END_SHADER_PARAMS - -#ifdef VANCE - void SetupVars(DrawLightPass_Vars_t& info) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nNoise = NOISE; - info.m_nBumpmap = BUMPMAP; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nBumpmap2 = -1; - info.m_nBumpFrame2 = -1; - info.m_nBumpTransform2 = -1; - info.m_nBaseTexture2 = -1; - info.m_nBaseTexture2Frame = -1; - info.m_nSeamlessMappingScale = -1; - info.bModel = true; - info.m_nUseSmoothness = USESMOOTHNESS; - } - - void SetupVars(VertexLitPBR_DX9_Vars_t& info) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nEnvmap = ENVMAP; - info.m_nBumpmap = BUMPMAP; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nBRDF = BRDF; - } -#endif // VANCE - - void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nWrinkle = COMPRESS; - info.m_nStretch = STRETCH; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlbedo = ALBEDO; - info.m_nSelfIllumTint = SELFILLUMTINT; - info.m_nDetail = DETAIL; - info.m_nDetailFrame = DETAILFRAME; - info.m_nDetailScale = DETAILSCALE; - info.m_nEnvmap = ENVMAP; - info.m_nEnvmapFrame = ENVMAPFRAME; - info.m_nEnvmapMask = ENVMAPMASK; - info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; - info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; - info.m_nEnvmapTint = ENVMAPTINT; - info.m_nBumpmap = BUMPMAP; - info.m_nNormalWrinkle = BUMPCOMPRESS; - info.m_nNormalStretch = BUMPSTRETCH; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - info.m_nEnvmapContrast = ENVMAPCONTRAST; - info.m_nEnvmapSaturation = ENVMAPSATURATION; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; - info.m_nLightmap = LIGHTMAP; - - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nSelfIllumEnvMapMask_Alpha = SELFILLUM_ENVMAPMASK_ALPHA; - info.m_nSelfIllumFresnel = SELFILLUMFRESNEL; - info.m_nSelfIllumFresnelMinMaxExp = SELFILLUMFRESNELMINMAXEXP; - - info.m_nAmbientOnly = AMBIENTONLY; - info.m_nPhongExponent = PHONGEXPONENT; - info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE; - info.m_nPhongTint = PHONGTINT; - info.m_nPhongAlbedoTint = PHONGALBEDOTINT; - info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; - info.m_nPhongWarpTexture = PHONGWARPTEXTURE; - info.m_nPhongBoost = PHONGBOOST; - info.m_nPhongExponentFactor = PHONGEXPONENTFACTOR; - info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; - info.m_nPhong = PHONG; - info.m_nBaseMapAlphaPhongMask = BASEMAPALPHAPHONGMASK; - info.m_nEnvmapFresnel = ENVMAPFRESNEL; - info.m_nDetailTextureCombineMode = DETAILBLENDMODE; - info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; - info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; - - // Rim lighting parameters - info.m_nRimLight = RIMLIGHT; - info.m_nRimLightPower = RIMLIGHTEXPONENT; - info.m_nRimLightBoost = RIMLIGHTBOOST; - info.m_nRimMask = RIMMASK; - - // seamless - info.m_nSeamlessScale = SEAMLESS_SCALE; - info.m_nSeamlessDetail = SEAMLESS_DETAIL; - info.m_nSeamlessBase = SEAMLESS_BASE; - - info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; - - info.m_nLinearWrite = LINEARWRITE; - info.m_nDetailTint = DETAILTINT; - info.m_nInvertPhongMask = INVERTPHONGMASK; - - info.m_nDepthBlend = DEPTHBLEND; - info.m_nDepthBlendScale = DEPTHBLENDSCALE; - - info.m_nSelfIllumMask = SELFILLUMMASK; - info.m_nBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA; - info.m_nTintReplacesBaseColor = BLENDTINTCOLOROVERBASE; - } - -#ifndef VANCE - - // Cloak Pass - void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) - { - info.m_nCloakFactor = CLOAKFACTOR; - info.m_nCloakColorTint = CLOAKCOLORTINT; - info.m_nRefractAmount = REFRACTAMOUNT; - - // Delete these lines if not bump mapping! - info.m_nBumpmap = BUMPMAP; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - } - - // Weapon Sheen Pass - void SetupVarsWeaponSheenPass( WeaponSheenPassVars_t &info ) - { - info.m_nSheenMap = SHEENMAP; - info.m_nSheenMapMask = SHEENMAPMASK; - info.m_nSheenMapMaskFrame = SHEENMAPMASKFRAME; - info.m_nSheenMapTint = SHEENMAPTINT; - info.m_nSheenMapMaskScaleX = SHEENMAPMASKSCALEX; - info.m_nSheenMapMaskScaleY = SHEENMAPMASKSCALEY; - info.m_nSheenMapMaskOffsetX = SHEENMAPMASKOFFSETX; - info.m_nSheenMapMaskOffsetY = SHEENMAPMASKOFFSETY; - info.m_nSheenMapMaskDirection = SHEENMAPMASKDIRECTION; - info.m_nSheenIndex = SHEENINDEX; - - info.m_nBumpmap = BUMPMAP; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - } - - bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time - return true; - else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag2 in case the base material still needs it - } - if ( params[SHEENPASSENABLED]->GetIntValue() ) // If material supports weapon sheen - return true; - - // Check flag2 if not drawing cloak pass - return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); - } - - bool IsTranslucent( IMaterialVar **params ) const - { - if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking - { - if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check - return true; - // else, not cloaking this frame, so check flag in case the base material still needs it - } - - // Check flag if not drawing cloak pass - return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); - } - - // Emissive Scroll Pass - void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) - { - info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; - info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; - info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; - info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; - info.m_nEmissiveTint = EMISSIVEBLENDTINT; - info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; - info.m_nTime = TIME; - } - - // Flesh Interior Pass - void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) - { - info.m_nFleshTexture = FLESHINTERIORTEXTURE; - info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; - info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; - info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; - info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; - info.m_nFleshCubeTexture = FLESHCUBETEXTURE; - - info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; - info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; - info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; - info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; - info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; - info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; - - info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; - info.m_nflBorderWidth = FLESHBORDERWIDTH; - info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; - info.m_ncBorderTint = FLESHBORDERTINT; - info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; - info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; - info.m_nflScrollSpeed = FLESHSCROLLSPEED; - - info.m_nTime = TIME; - } - -#endif // !VANCE - - SHADER_INIT_PARAMS() - { - - VertexLitGeneric_DX9_Vars_t vars; - SetupVars( vars ); - InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, true, vars ); -#ifndef VANCE - - // Cloak Pass - if ( !params[CLOAKPASSENABLED]->IsDefined() ) - { - params[CLOAKPASSENABLED]->SetIntValue( 0 ); - } - else if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitParamsCloakBlendedPass( this, params, pMaterialName, info ); - } - - // Sheen Pass - if ( !params[SHEENPASSENABLED]->IsDefined() ) - { - params[SHEENPASSENABLED]->SetIntValue( 0 ); - } - else if ( params[SHEENPASSENABLED]->GetIntValue() ) - { - WeaponSheenPassVars_t info; - SetupVarsWeaponSheenPass( info ); - InitParamsWeaponSheenPass( this, params, pMaterialName, info ); - } - - // Emissive Scroll Pass - if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) - { - params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); - } - else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); - } - - // Flesh Interior Pass - if ( !params[FLESHINTERIORENABLED]->IsDefined() ) - { - params[FLESHINTERIORENABLED]->SetIntValue( 0 ); - } - else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); - } -#else - params[CLOAKPASSENABLED]->SetIntValue(0); - params[BRDF]->SetStringValue("models/PBRTest/BRDF"); -#endif // !VANCE - } - - SHADER_FALLBACK - { - if (g_pHardwareConfig->GetDXSupportLevel() < 70) - return "VertexLitGeneric_DX6"; - - if (g_pHardwareConfig->GetDXSupportLevel() < 80) - return "VertexLitGeneric_DX7"; - - if (g_pHardwareConfig->GetDXSupportLevel() < 90) - return "VertexLitGeneric_DX8"; - - return 0; - } - - SHADER_INIT - { -#ifndef VANCE - VertexLitGeneric_DX9_Vars_t vars; - SetupVars(vars); - InitVertexLitGeneric_DX9(this, params, true, vars); - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - InitCloakBlendedPass( this, params, info ); - } - - // TODO : Only do this if we're in range of the camera - // Weapon Sheen - if ( params[SHEENPASSENABLED]->GetIntValue() ) - { - WeaponSheenPassVars_t info; - SetupVarsWeaponSheenPass( info ); - InitWeaponSheenPass( this, params, info ); - } - - // Emissive Scroll Pass - if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - InitEmissiveScrollBlendedPass( this, params, info ); - } - - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - InitFleshInteriorBlendedPass( this, params, info ); - } -#else - if (params[PBR]->GetIntValue() == 0) - { - VertexLitGeneric_DX9_Vars_t vars; - SetupVars(vars); - InitVertexLitGeneric_DX9(this, params, true, vars); - } - else - { - VertexLitPBR_DX9_Vars_t info; - SetupVars(info); - InitVertexLitPBR_DX9(this, params, info); - } -#endif - } - - SHADER_DRAW - { - bool bDrawStandardPass = true; - bool hasFlashlight = UsingFlashlight(params); - -#ifndef VANCE - if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - if ( CloakBlendedPassIsFullyOpaque( params, info ) ) - { - bDrawStandardPass = false; - } - } - -#endif // !VANCE - // Standard rendering pass - if ( bDrawStandardPass ) - { - if (params[PBR]->GetIntValue() == 0) - { - VertexLitGeneric_DX9_Vars_t info; - SetupVars(info); - DrawVertexLitGeneric_DX9(this, params, pShaderAPI, pShaderShadow, true, info, vertexCompression, pContextDataPtr); - } - else - { - VertexLitPBR_DX9_Vars_t info; - SetupVars(info); - DrawVertexLitPBR_DX9(this, params, pShaderAPI, pShaderShadow, hasFlashlight, info, vertexCompression, pContextDataPtr); - } - } - else - { - // Skip this pass! - Draw( false ); - } - - if (!hasFlashlight) - { - DrawLightPass_Vars_t vars; - SetupVars(vars); - DrawLightPass(this, params, pShaderAPI, pShaderShadow, vertexCompression, pContextDataPtr, vars); - } - -#ifndef VANCE - // Weapon sheen pass - // only if doing standard as well (don't do it if cloaked) - if ( params[SHEENPASSENABLED]->GetIntValue() ) - { - WeaponSheenPassVars_t info; - SetupVarsWeaponSheenPass( info ); - if ( ( pShaderShadow != NULL ) || ( bDrawStandardPass && ShouldDrawMaterialSheen( params, info ) ) ) - { - DrawWeaponSheenPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else - { - // Skip this pass! - Draw( false ); - } - } - - // Cloak Pass - if ( params[CLOAKPASSENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) - { - CloakBlendedPassVars_t info; - SetupVarsCloakBlendedPass( info ); - DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - - // Emissive Scroll Pass - if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) - { - EmissiveScrollBlendedPassVars_t info; - SetupVarsEmissiveScrollBlendedPass( info ); - DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } - - // Flesh Interior Pass - if ( params[FLESHINTERIORENABLED]->GetIntValue() ) - { - // If ( snapshotting ) or ( we need to draw this frame ) - if ( ( pShaderShadow != NULL ) || ( true ) ) - { - FleshInteriorBlendedPassVars_t info; - SetupVarsFleshInteriorBlendedPass( info ); - DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); - } - else // We're not snapshotting and we don't need to draw this frame - { - // Skip this pass! - Draw( false ); - } - } -#endif // !VANCE - } -END_SHADER diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h b/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h deleted file mode 100644 index 3736bfe8..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h +++ /dev/null @@ -1,71 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VERTEXLITGENERIC_DX95_HELPER_H -#define VERTEXLITGENERIC_DX95_HELPER_H - -#include - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct VertexLitGeneric_DX95_Vars_t -{ - VertexLitGeneric_DX95_Vars_t() { memset( this, 0xFF, sizeof(VertexLitGeneric_DX95_Vars_t) ); } - - int m_nBaseTexture; - int m_nBaseTextureFrame; - int m_nBaseTexture2; - int m_nBaseTextureFrame2; - int m_nBaseTexture3; - int m_nBaseTextureFrame3; - int m_nBaseTextureTransform; - int m_nAlbedo; - int m_nSelfIllumTint; - int m_nDetail; - int m_nDetailFrame; - int m_nDetailScale; - int m_nEnvmap; - int m_nEnvmapFrame; - int m_nEnvmapMask; - int m_nEnvmapMaskFrame; - int m_nEnvmapMaskTransform; - int m_nEnvmapTint; - int m_nBumpmap; - int m_nBumpFrame; - int m_nBumpmap2; - int m_nBumpFrame2; - int m_nBumpMask; - int m_nBumpmap3; - int m_nBumpFrame3; - int m_nBumpTransform; - int m_nEnvmapContrast; - int m_nEnvmapSaturation; - int m_nAlphaTestReference; - int m_nFlashlightTexture; - int m_nFlashlightTextureFrame; - int m_nSelfIllumEnvMapMask_Alpha; - -}; - -void InitParamsVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); -void InitVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); -void DrawVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); - - -#endif // VERTEXLITGENERIC_DX95_HELPER_H diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp deleted file mode 100644 index 6770542f..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp +++ /dev/null @@ -1,1548 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "vertexlitgeneric_dx9_helper.h" -#include "skin_dx9_helper.h" - -#ifndef VANCE -#include "VertexLit_and_unlit_Generic_vs20.inc" -#include "VertexLit_and_unlit_Generic_bump_vs20.inc" - -#include "vertexlit_and_unlit_generic_ps20.inc" -#include "vertexlit_and_unlit_generic_ps20b.inc" -#include "vertexlit_and_unlit_generic_bump_ps20.inc" -#include "vertexlit_and_unlit_generic_bump_ps20b.inc" -#endif // !VANCE - -#ifndef _X360 -#include "vertexlit_and_unlit_generic_vs30.inc" -#include "vertexlit_and_unlit_generic_ps30.inc" -#include "vertexlit_and_unlit_generic_bump_vs30.inc" -#include "vertexlit_and_unlit_generic_bump_ps30.inc" -#endif - -#include "commandbuilder.h" -#include "convar.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); -static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); -static ConVar mat_luxels( "mat_luxels", "0", FCVAR_CHEAT ); - - -static inline bool WantsSkinShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info ) -{ - if ( info.m_nPhong == -1) // Don't use skin without Phong - return false; - - if ( params[info.m_nPhong]->GetIntValue() == 0 ) // Don't use skin without Phong turned on - return false; - - if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture() ) // If there's Phong and diffuse warp do skin - return true; - - if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 1 ) - { - if ( info.m_nBumpmap == -1 ) // Don't use without a bump map - return false; - - if ( !params[info.m_nBumpmap]->IsTexture() ) // Don't use if the texture isn't specified - return false; - } - - return true; -} - -int g_nSnapShots; - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) -{ - InitIntParam( info.m_nPhong, params, 0 ); - - InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); - InitIntParam( info.m_nVertexAlphaTest, params, 0 ); - - InitIntParam( info.m_nFlashlightNoLambert, params, 0 ); - - if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() ) - { - params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() ) - { - params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - InitIntParam( info.m_nEnvmapFrame, params, 0 ); - InitIntParam( info.m_nBumpFrame, params, 0 ); - InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); - InitIntParam( info.m_nReceiveFlashlight, params, 0 ); - - InitFloatParam( info.m_nDetailScale, params, 4.0f ); - - if ( (info.m_nBlendTintByBaseAlpha != -1) && (!params[info.m_nBlendTintByBaseAlpha]->IsDefined()) ) - { - params[info.m_nBlendTintByBaseAlpha]->SetIntValue( 0 ); - } - - InitFloatParam( info.m_nTintReplacesBaseColor, params, 0 ); - - if ( (info.m_nSelfIllumTint != -1) && (!params[info.m_nSelfIllumTint]->IsDefined()) ) - { - params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - -#ifndef VANCE - if ( WantsSkinShader( params, info ) ) - { - if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() || !g_pConfig->UsePhong() ) - { - params[info.m_nPhong]->SetIntValue( 0 ); - } - else - { - InitParamsSkin_DX9( pShader, params, pMaterialName, info ); - return; - } - } -#endif // !VANCE - - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - if ( info.m_nFlashlightTexture != -1 ) - { - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - } - - // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. - if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && - params[info.m_nBaseTexture]->IsDefined() ) - { - params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); - } - - // This shader can be used with hw skinning - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if ( bVertexLitGeneric ) - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); - } - else - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - } - - InitIntParam( info.m_nEnvmapMaskFrame, params, 0 ); - InitFloatParam( info.m_nEnvmapContrast, params, 0.0 ); - InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f ); - InitFloatParam( info.m_nSeamlessScale, params, 0.0 ); - - // handle line art parms - InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); - InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); - InitFloatParam( info.m_nGlowAlpha, params, 1.0 ); - InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); - - // No texture means no self-illum or env mask in base alpha - if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - if( ( (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) - // we don't need a tangent space if we have envmap without bumpmap - // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) - ) - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - } - else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) // diffuse warp goes down bump path... - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - } - else // no tangent space needed - { - CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - } - - bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - if ( hasNormalMapAlphaEnvmapMask ) - { - params[info.m_nEnvmapMask]->SetUndefined(); - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 && - params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask ) - { - Warning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName ); - params[info.m_nEnvmap]->SetUndefined(); - } - - if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() ) - { - params[info.m_nEnvmapMask]->SetUndefined(); - if ( !hasNormalMapAlphaEnvmapMask ) - { - Warning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName ); - params[info.m_nEnvmap]->SetUndefined(); - } - } - - // If mat_specular 0, then get rid of envmap - if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) - { - params[info.m_nEnvmap]->SetUndefined(); - } - - InitFloatParam( info.m_nHDRColorScale, params, 1.0f ); - - InitIntParam( info.m_nLinearWrite, params, 0 ); - InitIntParam( info.m_nGammaColorRead, params, 0 ); - - InitIntParam( info.m_nDepthBlend, params, 0 ); - InitFloatParam( info.m_nDepthBlendScale, params, 50.0f ); -} - - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- - -void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) -{ - - //bool bHasBump = ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsTexture(); - //if ( bHasBump ) - //{ - // if ( ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsDefined() ) - // bNeedsSkinBecauseOfDetail = true; - //} -#ifndef VANCE - // both detailed and bumped = needs skin shader (for now) - bool bNeedsSkinBecauseOfDetail = false; - if ( bNeedsSkinBecauseOfDetail || - ( info.m_nPhong != -1 && - params[info.m_nPhong]->GetIntValue() && - g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) - { - InitSkin_DX9( pShader, params, info ); - return; - } - -#endif // !VANCE - - if ( info.m_nFlashlightTexture != -1 ) - { - pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); - } - - bool bIsBaseTextureTranslucent = false; - if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ? 0 : TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - } - - bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); - - // No alpha channel in any of the textures? No self illum or envmapmask - if ( !bIsBaseTextureTranslucent ) - { - bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); - - // Can still be self illum with no base alpha if using one of these alternate modes - if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) - { - CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); - } - - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) - { - int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); - if ( nDetailBlendMode == 0 ) //Mod2X - pShader->LoadTexture( info.m_nDetail ); - else - pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); - } - - if ( g_pConfig->UseBumpmapping() ) - { - if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) - { - pShader->LoadBumpMap( info.m_nBumpmap ); - SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); - } - else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) - { - SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); - } - } - - // Don't alpha test if the alpha channel is used for other purposes - if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - { - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - } - - if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) - { - if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - { - int flags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0; - flags |= TEXTUREFLAGS_ALL_MIPS; - pShader->LoadCubeMap( info.m_nEnvmap, flags); - } - else - { - pShader->LoadTexture( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); - } - - if ( !g_pHardwareConfig->SupportsCubeMaps() ) - { - SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); - } - } - if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) - { - pShader->LoadTexture( info.m_nEnvmapMask ); - } - - if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nDiffuseWarpTexture ); - } - - if ( bHasSelfIllumMask ) - { - pShader->LoadTexture( info.m_nSelfIllumMask ); - } -} - -class CVertexLitGeneric_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - -}; - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, - bool bVertexLitGeneric, bool bHasFlashlight, - VertexLitGeneric_DX9_Vars_t &info, - VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) - -{ - CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr ); - -/*^*/ // printf("\t\t>DrawVertexLitGeneric_DX9_Internal\n"); - - bool bHasBump = IsTextureSet( info.m_nBumpmap, params ); -#if !defined( _X360 ) - bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); -#endif - - bool hasDiffuseLighting = bVertexLitGeneric; -/*^*/ // printf("\t\t[%d] bVertexLitGeneric\n",(int)bVertexLitGeneric); - - if ( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - { - bHasFlashlight = false; - } - - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - bool bHasDiffuseWarp = (!bHasFlashlight || IsX360() ) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); - bool bHasLightmapTexture = IsTextureSet( info.m_nLightmap, params ); - bool bHasMatLuxel = bHasLightmapTexture && mat_luxels.GetBool(); - - //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); - bool bFlashlightNoLambert = false; - if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() ) - { - bFlashlightNoLambert = true; - } - - bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params ); - - float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); - bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params ); - int nDetailBlendMode = bHasDetailTexture ? GetIntParam( info.m_nDetailTextureCombineMode, params ) : 0; - int nDetailTranslucencyTexture = -1; - - if ( bHasDetailTexture ) - { - if ( ( nDetailBlendMode == 6 ) && ( ! (g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) ) - { - nDetailBlendMode = 5; // skip fancy threshold blending if ps2.0 - } - if ( ( nDetailBlendMode == 3 ) || ( nDetailBlendMode == 8 ) || ( nDetailBlendMode == 9 ) ) - nDetailTranslucencyTexture = info.m_nDetail; - } - - bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ); - float fTintReplaceFactor = GetFloatParam( info.m_nTintReplacesBaseColor, params, 0.0 ); - - BlendType_t nBlendType; - bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params ); - if ( bHasBaseTexture ) - { - // if base alpha is used for tinting, ignore the base texture for computing translucency - nBlendType = pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true, nDetailTranslucencyTexture ); - } - else - { - nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); - } - bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && (!bHasFlashlight || IsX360() ); //dest alpha is free for special use - - bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture(); - - - bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); -/*^*/ // printf("\t\t[%d] bHasVertexColor\n",(int)bHasVertexColor); -/*^*/ // printf("\t\t[%d] bHasVertexAlpha\n",(int)bHasVertexAlpha); - - if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) - { -/*^*/ // printf("\t\t[1] snapshotting=%d pContextData=%08x pContextData->m_bMaterialVarsChanged=%d \n",(int)pShader->IsSnapshotting(), (int)pContextData, pContextData ? (int)pContextData->m_bMaterialVarsChanged : -1 ); - bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ); - bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ); - bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params ); - bool bHasSelfIllum = (!bHasFlashlight || IsX360() ) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); - bool bHasEnvmapMask = (!bHasFlashlight || IsX360() ) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); - bool bHasSelfIllumFresnel = ( !IsTextureSet( info.m_nDetail, params ) ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); - - bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params ); - bool hasSelfIllumInEnvMapMask = - ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && - ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ; - - if ( pShader->IsSnapshotting() ) - { -/*^*/ // printf("\t\t[2] snapshotting...\n"); - - bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - - - if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 ) - { - bHasVertexAlpha = true; - } - - // look at color and alphamod stuff. - // Unlit generic never uses the flashlight - if ( bHasSelfIllumFresnel ) - { - CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - hasNormalMapAlphaEnvmapMask = false; - } - - bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsTexture(); - bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); - bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail; - if ( IsPC() ) - { - // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models) - bHasNormal = true; - } - - bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); - // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if ( bHasFlashlight ) - { - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - - if ( !IsX360() ) - { - if (bHasBaseTexture && params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - else - { - pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); - } - - if ( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - } - else - { - pShader->SetBlendingShadowState( nBlendType ); - } - } - else - { - pShader->SetBlendingShadowState( nBlendType ); - } - - unsigned int flags = VERTEX_POSITION; - if ( bHasNormal ) - { - flags |= VERTEX_NORMAL; - } -/*^*/ // printf("\t\t[%1d] VERTEX_NORMAL\n",(flags&VERTEX_NORMAL)!=0); - - int userDataSize = 0; - bool bSRGBInputAdapter = false; - - // basetexture - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - if ( bHasBaseTexture ) - { - if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ) - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); - else - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - // If we're on OSX GL on a crappy OS which can't do sRGB from render targets, check to see if we're reading from one... - if ( IsOSX() && !g_pHardwareConfig->CanDoSRGBReadFromRTs() ) - { - ITexture *pBaseTexture = bHasBaseTexture ? params[info.m_nBaseTexture]->GetTextureValue() : NULL; - if ( pBaseTexture && pBaseTexture->IsRenderTarget() ) - { - bSRGBInputAdapter = true; - } - } - } - - if ( bHasEnvmap ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - } - } - if ( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 ); - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); - userDataSize = 4; // tangent S - } - - if ( bHasDetailTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - if ( nDetailBlendMode != 0 ) //Not Mod2X - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); - } - - if ( bHasBump || bHasDiffuseWarp ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - userDataSize = 4; // tangent S - // Normalizing cube map - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - } - if ( bHasEnvmapMask ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - } - - if ( bHasVertexColor || bHasVertexAlpha ) - { - flags |= VERTEX_COLOR; - } -/*^*/ // printf("\t\t[%1d] VERTEX_COLOR\n",(flags&VERTEX_COLOR)!=0); -/*^*/ // printf("\t\t[%1d] VERTEX_COLOR_STREAM_1\n",(flags&VERTEX_COLOR_STREAM_1)!=0); - - - if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Diffuse warp texture - } - - if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) - { - if( bHasBump ) - Warning( "DEPTHBLEND not supported by bump mapped variations of vertexlitgeneric to avoid shader bloat. Either remove the bump map or convince a graphics programmer that it's worth it.\n" ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); - } - - if( bHasSelfIllum ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask - } - - - // Always enable this sampler, used for lightmaps depending on the dynamic combo. - // Lightmaps are generated in gamma space, but not sRGB, so leave that disabled. Conversion is done in the shader. - pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); - - bool bSRGBWrite = true; - if( (info.m_nLinearWrite != -1) && (params[info.m_nLinearWrite]->GetIntValue() == 1) ) - { - bSRGBWrite = false; - } - - pShaderShadow->EnableSRGBWrite( bSRGBWrite ); - - // texcoord0 : base texcoord - int pTexCoordDim[3] = { 2, 2, 3 }; - int nTexCoordCount = 1; - - if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) ) - { - ++nTexCoordCount; - } - else - { - pTexCoordDim[1] = 0; - } - -#ifndef _X360 - // Special morphed decal information - if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) - { - nTexCoordCount = 3; - } -#endif - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; -/*^*/ // printf("\t\t[%1d] VERTEX_FORMAT_COMPRESSED\n",(flags&VERTEX_FORMAT_COMPRESSED)!=0); - -/*^*/ // printf("\t\t -> CShaderShadowDX8::VertexShaderVertexFormat( flags=%08x, texcount=%d )\n",flags,nTexCoordCount); - - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); - - if ( bHasBump || bHasDiffuseWarp ) - { -#ifndef VANCE -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); - SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, g_pHardwareConfig->SupportsPixelShaders_2_b() ); -#ifdef _X360 - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); -#endif - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way - { - DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); - } - else // ps_2_0 - { - DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); - } - } - else - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); - SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, true ); - SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); - SET_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30 ); - } -#else - DECLARE_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30); - SET_STATIC_VERTEX_SHADER_COMBO(HALFLAMBERT, bHalfLambert); - SET_STATIC_VERTEX_SHADER_COMBO(USE_WITH_2B, g_pHardwareConfig->SupportsPixelShaders_2_b()); - SET_STATIC_VERTEX_SHADER_COMBO(DECAL, bIsDecal); - SET_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30); - - DECLARE_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30); - SET_STATIC_PIXEL_SHADER_COMBO(CUBEMAP, bHasEnvmap); - SET_STATIC_PIXEL_SHADER_COMBO(DIFFUSELIGHTING, hasDiffuseLighting); - SET_STATIC_PIXEL_SHADER_COMBO(LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel); - SET_STATIC_PIXEL_SHADER_COMBO(SELFILLUM, bHasSelfIllum); - SET_STATIC_PIXEL_SHADER_COMBO(SELFILLUMFRESNEL, bHasSelfIllumFresnel); - SET_STATIC_PIXEL_SHADER_COMBO(NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask&& bHasEnvmap); - SET_STATIC_PIXEL_SHADER_COMBO(HALFLAMBERT, bHalfLambert); - SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHT, bHasFlashlight); - SET_STATIC_PIXEL_SHADER_COMBO(DETAILTEXTURE, bHasDetailTexture); - SET_STATIC_PIXEL_SHADER_COMBO(DETAIL_BLEND_MODE, nDetailBlendMode); - SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode); - SET_STATIC_PIXEL_SHADER_COMBO(BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha); - SET_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30); -#endif - } - else // !(bHasBump || bHasDiffuseWarp) - { - bool bDistanceAlphaFromDetail = false; - bool bSoftMask = false; - bool bGlow = false; - bool bOutline = false; - - bool bDoDepthBlend = IsBoolSet( info.m_nDepthBlend, params ); - - if ( bDistanceAlpha ) - { - bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params ); - bSoftMask = IsBoolSet( info.m_nSoftEdges, params ); - bGlow = IsBoolSet( info.m_nGlow, params ); - bOutline = IsBoolSet( info.m_nOutline, params ); - } -#ifndef VANCE -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); - SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); - SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); - SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); - SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); - SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, (! bSRGBWrite ) && bHasVertexColor ); - SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send Gl this way - { - DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); - SET_STATIC_PIXEL_SHADER_COMBO( SRGB_INPUT_ADAPTER, bSRGBInputAdapter ? 1 : 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); - } - else // ps_2_0 - { - DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); - } - } - else -#ifndef _X360 - { - // The vertex shader uses the vertex id stream - SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); - - DECLARE_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_vs30 ); - SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); - SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); - SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); - SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); - SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); - SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); - SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, bSRGBWrite ? 0 : 1 ); - SET_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_ps30 ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); - SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); - SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); - SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); - SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); - SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); - SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); - SET_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_ps30 ); - } - -#endif -#else - - DECLARE_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_vs30); - SET_STATIC_VERTEX_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha); - SET_STATIC_VERTEX_SHADER_COMBO(CUBEMAP, bHasEnvmap); - SET_STATIC_VERTEX_SHADER_COMBO(HALFLAMBERT, bHalfLambert); - SET_STATIC_VERTEX_SHADER_COMBO(FLASHLIGHT, bHasFlashlight); - SET_STATIC_VERTEX_SHADER_COMBO(SEAMLESS_BASE, bSeamlessBase); - SET_STATIC_VERTEX_SHADER_COMBO(SEAMLESS_DETAIL, bSeamlessDetail); - SET_STATIC_VERTEX_SHADER_COMBO(SEPARATE_DETAIL_UVS, IsBoolSet(info.m_nSeparateDetailUVs, params)); - SET_STATIC_VERTEX_SHADER_COMBO(DONT_GAMMA_CONVERT_VERTEX_COLOR, (!bSRGBWrite) && bHasVertexColor); - SET_STATIC_VERTEX_SHADER_COMBO(DECAL, bIsDecal); - SET_STATIC_VERTEX_SHADER(vertexlit_and_unlit_generic_vs30); - - DECLARE_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_ps30); - SET_STATIC_PIXEL_SHADER_COMBO(SELFILLUM_ENVMAPMASK_ALPHA, (hasSelfIllumInEnvMapMask && (bHasEnvmapMask))); - SET_STATIC_PIXEL_SHADER_COMBO(CUBEMAP, bHasEnvmap); - SET_STATIC_PIXEL_SHADER_COMBO(CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap); - SET_STATIC_PIXEL_SHADER_COMBO(DIFFUSELIGHTING, hasDiffuseLighting); - SET_STATIC_PIXEL_SHADER_COMBO(ENVMAPMASK, bHasEnvmapMask); - SET_STATIC_PIXEL_SHADER_COMBO(BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask); - SET_STATIC_PIXEL_SHADER_COMBO(SELFILLUM, bHasSelfIllum); - SET_STATIC_PIXEL_SHADER_COMBO(VERTEXCOLOR, bHasVertexColor); - SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHT, bHasFlashlight); - SET_STATIC_PIXEL_SHADER_COMBO(DETAILTEXTURE, bHasDetailTexture); - SET_STATIC_PIXEL_SHADER_COMBO(DETAIL_BLEND_MODE, nDetailBlendMode); - SET_STATIC_PIXEL_SHADER_COMBO(SEAMLESS_BASE, bSeamlessBase); - SET_STATIC_PIXEL_SHADER_COMBO(SEAMLESS_DETAIL, bSeamlessDetail); - SET_STATIC_PIXEL_SHADER_COMBO(DISTANCEALPHA, bDistanceAlpha); - SET_STATIC_PIXEL_SHADER_COMBO(DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail); - SET_STATIC_PIXEL_SHADER_COMBO(SOFT_MASK, bSoftMask); - SET_STATIC_PIXEL_SHADER_COMBO(OUTLINE, bOutline); - SET_STATIC_PIXEL_SHADER_COMBO(OUTER_GLOW, bGlow); - SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode); - SET_STATIC_PIXEL_SHADER_COMBO(DEPTHBLEND, bDoDepthBlend); - SET_STATIC_PIXEL_SHADER_COMBO(BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha); - SET_STATIC_PIXEL_SHADER(vertexlit_and_unlit_generic_ps30); -#endif - } - - if ( bHasFlashlight && !IsX360() ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // HACK HACK HACK - enable alpha writes all the time so that we have them for - // underwater stuff and the loadout and character select screens. - pShaderShadow->EnableAlphaWrites( bFullyOpaque ); - } - - if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) ) - { -/*^*/ // printf("\t\t[3] pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) TRUE \n"); - if ( ! pContextData ) // make sure allocated - { - ++g_nSnapShots; - pContextData = new CVertexLitGeneric_DX9_Context; - *pContextDataPtr = pContextData; - } - pContextData->m_SemiStaticCmdsOut.Reset(); - pContextData->m_SemiStaticCmdsOut.SetPixelShaderFogParams( 21 ); - if ( bHasBaseTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - else - { - if( bHasEnvmap ) - { - // if we only have an envmap (no basetexture), then we want the albedo to be black. - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - } - } - if ( bHasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); - } - if ( bHasSelfIllum ) - { - if ( bHasSelfIllumMask ) // Separate texture for self illum? - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, info.m_nSelfIllumMask, -1 ); // Bind it - } - else // else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, TEXTURE_BLACK ); // Bind dummy - } - } - - if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER10, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); - } - if ( bSeamlessDetail || bSeamlessBase ) - { - float flSeamlessData[4]={ params[info.m_nSeamlessScale]->GetFloatValue(), - 0,0,0}; - pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flSeamlessData ); - } - - if ( info.m_nBaseTextureTransform != -1 ) - { - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - } - - - if ( bHasDetailTexture ) - { - if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nDetailTextureTransform, info.m_nDetailScale ); - else - pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBaseTextureTransform, info.m_nDetailScale ); - //Assert( !bHasBump ); - if ( info.m_nDetailTint != -1 ) - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); - else - { - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 10, 1, 1, 1, 1 ); - } - } - if ( bDistanceAlpha ) - { - float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params ); - float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params ); - // set all line art shader parms - bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params ); - bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params ); - - float flResScale = 1.0; - - float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params ); - float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params ); - float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params ); - float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params ); - - if ( bScaleEdges || bScaleOutline ) - { - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - flResScale=max( 0.5, max( 1024.0/nWidth, 768/nHeight ) ); - - if ( bScaleEdges ) - { - float flMid = 0.5 * ( flSoftStart + flSoftEnd ); - flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 ); - flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 ); - } - - - if ( bScaleOutline ) - { - // shrink the soft part of the outline, enlarging hard part - float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 ); - flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 ); - float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 ); - flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 ); - } - - } - - float flConsts[]={ - // c5 - glow values - GetFloatParam( info.m_nGlowX, params ), - GetFloatParam( info.m_nGlowY, params ), - GetFloatParam( info.m_nGlowStart, params ), - GetFloatParam( info.m_nGlowEnd, params ), - // c6 - glow color - 0,0,0, // will be filled in - GetFloatParam( info.m_nGlowAlpha, params ), - // c7 - mask range parms - flSoftStart, - flSoftEnd, - 0,0, - // c8 - outline color - 0,0,0, - GetFloatParam( info.m_nOutlineAlpha, params ), - // c9 - outline parms. ordered for optimal ps20 .wzyx swizzling - flOutlineStart0, - flOutlineEnd1, - flOutlineEnd0, - flOutlineStart1, - }; - - if ( info.m_nGlowColor != -1 ) - { - params[info.m_nGlowColor]->GetVecValue( flConsts+4, 3 ); - } - if ( info.m_nOutlineColor != -1 ) - { - params[info.m_nOutlineColor]->GetVecValue( flConsts+12, 3 ); - } - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, flConsts, 5 ); - - } - if ( !g_pConfig->m_bFastNoBump ) - { - if ( bHasBump ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); - } - else if ( bHasDiffuseWarp ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); - } - } - else - { - if ( bHasBump ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); - } - } - // Setting w to 1 means use separate selfillummask - float vEnvMapSaturation_SelfIllumMask[4] = {1.0f, 1.0f, 1.0f, 0.0f}; - if ( info.m_nEnvmapSaturation != -1 ) - params[info.m_nEnvmapSaturation]->GetVecValue( vEnvMapSaturation_SelfIllumMask, 3 ); - - vEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, vEnvMapSaturation_SelfIllumMask, 1 ); - if ( bHasEnvmap ) - { - pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, info.m_nEnvmapTint, fTintReplaceFactor ); - } - else - { - pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, -1, fTintReplaceFactor); - } - - if ( bHasEnvmapMask ) - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); - } - - if ( bHasSelfIllumFresnel && (!bHasFlashlight || IsX360() ) ) - { - float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; - float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; - float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; - float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; - - vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias - vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale - vConstScaleBiasExp[2] = flExp; // Exp - vConstScaleBiasExp[3] = flMax; // Brightness - - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vConstScaleBiasExp ); - } - - if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) - { - if ( r_lightwarpidentity.GetBool() ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_IDENTITY_LIGHTWARP ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nDiffuseWarpTexture, -1 ); - } - } - - if ( bHasFlashlight ) - { - // Tweaks associated with a given flashlight - VMatrix worldToTexture; - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - float tweaks[4]; - tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; - tweaks[1] = ShadowAttenFromState( flashlightState ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( 2, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( 31, vScreenScale, 1 ); - } - - if ( ( !bHasFlashlight || IsX360() ) && ( info.m_nEnvmapContrast != -1 ) ) - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); - - // mat_fullbright 2 handling - bool bLightingOnly = bVertexLitGeneric && mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - if( bLightingOnly ) - { - if ( bHasBaseTexture ) - { - if( ( bHasSelfIllum && !hasSelfIllumInEnvMapMask ) ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); - } - else - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - } - if ( bHasDetailTexture ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); - } - } - - if ( bHasBump || bHasDiffuseWarp ) - { - pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); - pContextData->m_SemiStaticCmdsOut.SetPixelShaderStateAmbientLightCube( 5 ); - pContextData->m_SemiStaticCmdsOut.CommitPixelShaderLighting( 13 ); - } - pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nSelfIllumTint, fBlendFactor ); - pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); - pContextData->m_SemiStaticCmdsOut.End(); - } - } - if ( pShaderAPI ) - { - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; - DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); - - if ( bHasEnvmap ) - { - DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, info.m_nEnvmap, info.m_nEnvmapFrame ); - } - - bool bFlashlightShadows = false; - if ( bHasFlashlight ) - { - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) - { - pShader->BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); - DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); - } - - SetFlashLightColorFromState( state, pShaderAPI, 28, bFlashlightNoLambert ); - - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); - } - - - // Set up light combo state - LightState_t lightState = { 0, false, false, false }; - if ( bVertexLitGeneric && (!bHasFlashlight || IsX360() ) ) - { - pShaderAPI->GetDX9LightState( &lightState ); - } - - // Override the lighting desired if we have a lightmap set! - if ( bHasLightmapTexture ) - { - lightState.m_bStaticLightVertex = false; - lightState.m_bStaticLightTexel = true; - - // Usual case, not debugging. - if (!bHasMatLuxel) - { - pShader->BindTexture(SHADER_SAMPLER12, info.m_nLightmap); - } - else - { - float dimensions[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_DEBUG_LUXELS ); - pShader->GetTextureDimensions( &dimensions[0], &dimensions[1], info.m_nLightmap ); - DynamicCmdsOut.SetPixelShaderConstant( 11, dimensions, 1 ); - } - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - int numBones = pShaderAPI->GetCurrentNumBones(); - - bool bWriteDepthToAlpha; - bool bWriteWaterFogToAlpha; - if( bFullyOpaque ) - { - bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); - bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); - AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); - } - else - { - //can't write a special value to dest alpha if we're actually using as-intended alpha - bWriteDepthToAlpha = false; - bWriteWaterFogToAlpha = false; - } - - if ( bHasBump || bHasDiffuseWarp ) - { -#ifndef VANCE - -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_vs20 ); - - // Bind ps_2_b shader so we can get shadow mapping... - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way - { - DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); -// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20 ); - } - } - - else -#ifndef _X360 - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); -// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps30 ); - - bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; - pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); - } -#endif -#endif // !VANCE - pShader->SetHWMorphVertexShaderState(VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0); - - DECLARE_DYNAMIC_VERTEX_SHADER(vertexlit_and_unlit_generic_bump_vs30); - SET_DYNAMIC_VERTEX_SHADER_COMBO(DOWATERFOG, fogIndex); - SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, numBones > 0); - SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (int)vertexCompression); - SET_DYNAMIC_VERTEX_SHADER_COMBO(MORPHING, pShaderAPI->IsHWMorphingEnabled()); - SET_DYNAMIC_VERTEX_SHADER_CMD(DynamicCmdsOut, vertexlit_and_unlit_generic_bump_vs30); - - DECLARE_DYNAMIC_PIXEL_SHADER(vertexlit_and_unlit_generic_bump_ps30); - SET_DYNAMIC_PIXEL_SHADER_COMBO(NUM_LIGHTS, lightState.m_nNumLights); - SET_DYNAMIC_PIXEL_SHADER_COMBO(AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0); - SET_DYNAMIC_PIXEL_SHADER_COMBO(FLASHLIGHTSHADOWS, bFlashlightShadows); - SET_DYNAMIC_PIXEL_SHADER_CMD(DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps30); - } - else // !( bHasBump || bHasDiffuseWarp ) - { - if ( bAmbientOnly ) // Override selected light combo to be ambient only - { - lightState.m_bAmbientLight = true; - lightState.m_bStaticLightVertex = false; - lightState.m_nNumLights = 0; - } -#ifndef VANCE -#ifndef _X360 - if ( !g_pHardwareConfig->HasFastVertexTextures() ) -#endif - { - bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); - - DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_VERTEX, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( - LIGHTING_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); - SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs20 ); - - // Bind ps_2_b shader so we can get shadow mapping - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way - { - DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); - -// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( DEBUG_LUXELS, bHasMatLuxel ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( - LIGHTING_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( - LIGHTING_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20 ); - } - } - else -#endif -#ifndef _X360 - { - pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER(vertexlit_and_unlit_generic_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_VERTEX, lightState.m_bStaticLightVertex ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER(vertexlit_and_unlit_generic_ps30 ); -// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( STATIC_LIGHT_LIGHTMAP, lightState.m_bStaticLightTexel ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( DEBUG_LUXELS, bHasMatLuxel ? 1 : 0 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, - pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); - SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps30 ); - - bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; - pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); - } -#endif - } - - if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) - { - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() ); - } - else - { - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - } - - float eyePos[4]; - pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); - DynamicCmdsOut.SetPixelShaderConstant( 20, eyePos ); - - // Non-bump case does its own depth feathering work - if ( !bHasBump && !bHasDiffuseWarp ) - { - DynamicCmdsOut.SetDepthFeatheringPixelShaderConstant( 13, GetFloatParam( info.m_nDepthBlendScale, params, 50.0f ) ); - } - - float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; - float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; - float fWriteWaterFogToDestAlpha = (pShaderAPI->GetPixelFogCombo() == 1 && bWriteWaterFogToAlpha) ? 1 : 0; - float fVertexAlpha = bHasVertexAlpha ? 1 : 0; - - // Controls for lerp-style paths through shader code (bump and non-bump have use different register) - float vShaderControls[4] = { fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha }; - DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 ); - - // flashlightfixme: put this in common code. - if ( bHasFlashlight ) - { - VMatrix worldToTexture; - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - SetFlashLightColorFromState( flashlightState, pShaderAPI, 28, bFlashlightNoLambert ); - - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); - - pShader->BindTexture( SHADER_SAMPLER7, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - float atten_pos[8]; - atten_pos[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten_pos[1] = flashlightState.m_fLinearAtten; - atten_pos[2] = flashlightState.m_fQuadraticAtten; - atten_pos[3] = flashlightState.m_FarZ; - atten_pos[4] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - atten_pos[5] = flashlightState.m_vecLightOrigin[1]; - atten_pos[6] = flashlightState.m_vecLightOrigin[2]; - atten_pos[7] = 1.0f; - DynamicCmdsOut.SetPixelShaderConstant( 22, atten_pos, 2 ); - - DynamicCmdsOut.SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); - } - DynamicCmdsOut.End(); - pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); - } - pShader->Draw(); - -/*^*/ // printf("\t\tSupportsPixelShaders_2_b() && g_pConfig->UseBumpmapping() && g_pConfig->UsePhong() ) - { - DrawSkin_DX9( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); - return; - } -#endif - - bool bHasFlashlight = pShader->UsingFlashlight(params); - - DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI, - pShaderShadow, bVertexLitGeneric, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} diff --git a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h b/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h deleted file mode 100644 index 5820dbeb..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h +++ /dev/null @@ -1,145 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VERTEXLITGENERIC_DX9_HELPER_H -#define VERTEXLITGENERIC_DX9_HELPER_H - -#include - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct VertexLitGeneric_DX9_Vars_t -{ - VertexLitGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } - - int m_nBaseTexture; - int m_nWrinkle; - int m_nStretch; - int m_nBaseTextureFrame; - int m_nBaseTextureTransform; - int m_nAlbedo; - int m_nDetail; - int m_nDetailFrame; - int m_nDetailScale; - int m_nEnvmap; - int m_nEnvmapFrame; - int m_nEnvmapMask; - int m_nEnvmapMaskFrame; - int m_nEnvmapMaskTransform; - int m_nEnvmapTint; - int m_nBumpmap; - int m_nNormalWrinkle; - int m_nNormalStretch; - int m_nBumpFrame; - int m_nBumpTransform; - int m_nEnvmapContrast; - int m_nEnvmapSaturation; - int m_nAlphaTestReference; - int m_nVertexAlphaTest; - int m_nFlashlightNoLambert; - int m_nFlashlightTexture; - int m_nFlashlightTextureFrame; - int m_nLightmap; - - int m_nSelfIllumTint; - int m_nSelfIllumFresnel; - int m_nSelfIllumFresnelMinMaxExp; - - int m_nPhongExponent; - int m_nPhongTint; - int m_nPhongAlbedoTint; - int m_nPhongExponentTexture; - int m_nDiffuseWarpTexture; - int m_nPhongWarpTexture; - int m_nPhongBoost; - int m_nPhongFresnelRanges; - int m_nPhongExponentFactor; - int m_nSelfIllumEnvMapMask_Alpha; - int m_nAmbientOnly; - int m_nHDRColorScale; - int m_nPhong; - int m_nBaseMapAlphaPhongMask; - int m_nEnvmapFresnel; - - int m_nDetailTextureCombineMode; - int m_nDetailTextureBlendFactor; - - // Rim lighting parameters - int m_nRimLight; - int m_nRimLightPower; - int m_nRimLightBoost; - int m_nRimMask; - - int m_nSeamlessScale; - int m_nSeamlessBase; - int m_nSeamlessDetail; - - // distance coded line art parameters - int m_nDistanceAlpha; - int m_nDistanceAlphaFromDetail; - - int m_nSoftEdges; - int m_nEdgeSoftnessStart; - int m_nEdgeSoftnessEnd; - int m_nScaleEdgeSoftnessBasedOnScreenRes; - - int m_nGlow; - int m_nGlowColor; - int m_nGlowAlpha; - int m_nGlowStart; - int m_nGlowEnd; - int m_nGlowX; - int m_nGlowY; - int m_nOutline; - int m_nOutlineColor; - int m_nOutlineAlpha; - int m_nOutlineStart0; - int m_nOutlineStart1; - int m_nOutlineEnd0; - int m_nOutlineEnd1; - int m_nScaleOutlineSoftnessBasedOnScreenRes; - - int m_nSeparateDetailUVs; - int m_nDetailTextureTransform; - - int m_nLinearWrite; - int m_nGammaColorRead; - - int m_nDetailTint; - int m_nInvertPhongMask; - - int m_nDepthBlend; - int m_nDepthBlendScale; - - int m_nSelfIllumMask; - int m_nReceiveFlashlight; - - int m_nBlendTintByBaseAlpha; - - int m_nTintReplacesBaseColor; -}; - -void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); -void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); -void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr - ); - - -#endif // VERTEXLITGENERIC_DX9_HELPER_H diff --git a/materialsystem/stdshaders/vertexlitgeneric_envmap.psh b/materialsystem/stdshaders/vertexlitgeneric_envmap.psh deleted file mode 100644 index 019f8c0a..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_envmap.psh +++ /dev/null @@ -1,17 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map - -mul r0, t0, c3 ; base times modulation -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh b/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh deleted file mode 100644 index a5810b5e..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh +++ /dev/null @@ -1,137 +0,0 @@ -vs.1.1 - -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "SKINNING" "0..1" -# STATIC: "TEETH" "0..1" - -#include "macros.vsh" - -local( $worldPos, $worldNormal, $projPos ); - -alloc $worldPos -alloc $worldNormal -alloc $projPos - -if( 0 ) -{ - ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos - ; Special case for static prop lighting. We can go directly from - ; world to proj space for position, with the exception of z, which - ; is needed for fogging *if* height fog is enabled. - - ; NOTE: We don't use this path if $envmap is defined since we need - ; worldpos for envmapping. - dp4 $projPos.x, $vPos, $cModelViewProj0 - dp4 $projPos.y, $vPos, $cModelViewProj1 - dp4 $projPos.z, $vPos, $cModelViewProj2 - dp4 $projPos.w, $vPos, $cModelViewProj3 - ; normal - dp3 $worldNormal.x, $vNormal, $cModel0 - dp3 $worldNormal.y, $vNormal, $cModel1 - dp3 $worldNormal.z, $vNormal, $cModel2 - - ; Need this for height fog if it's enabled and for height clipping - dp4 $worldPos.z, $vPos, $cModel2 -} -else -{ - &SkinPositionAndNormal( $worldPos, $worldNormal ); - - if( $SKINNING == 1 ) - { - &Normalize( $worldNormal ); - } - - ;------------------------------------------------------------------------------ - ; Transform the position from world to view space - ;------------------------------------------------------------------------------ - dp4 $projPos.x, $worldPos, $cViewProj0 - dp4 $projPos.y, $worldPos, $cViewProj1 - dp4 $projPos.z, $worldPos, $cViewProj2 - dp4 $projPos.w, $worldPos, $cViewProj3 -} - -mov oPos, $projPos - -;------------------------------------------------------------------------------ -; Fog -;------------------------------------------------------------------------------ -&CalcFog( $worldPos, $projPos ); - -; base tex coords -dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 -dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 - -; normal map coords -;dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_8 -;dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_9 - -; spotlight texcoords -dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 -dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 -dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 -dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 - -local( $worldPosToLightVector, $distFactors ); - -alloc $worldPosToLightVector - -sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0, $worldPos -mov oT2, $worldPosToLightVector - -local( $distatten ); -alloc $distatten -; $distatten = [ 1, 1/dist, 1/distsquared ] - -; dist squared -dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector - -; oodist -rsq $distatten.y, $distatten.z - -mov $distatten.x, $cOne - -local( $dist ); -alloc $dist -mul $dist.x, $distatten.z, $distatten.y - -rcp $distatten.z, $distatten.z ; 1/distsquared - -local( $endFalloffFactor ); -alloc $endFalloffFactor - -; ( dist - farZ ) -sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w -; 1 / ( (0.6f * farZ) - farZ) -mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w -max $endFalloffFactor, $endFalloffFactor, $cZero -min $endFalloffFactor, $endFalloffFactor, $cOne - -local( $vertAtten ); -alloc $vertAtten -dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 -mul $vertAtten, $vertAtten, $endFalloffFactor - -if( $TEETH ) -{ - alloc $mouthAtten - dp3 $mouthAtten, $worldNormal.xyz, $SHADER_SPECIFIC_CONST_10.xyz - max $mouthAtten, $cZero, $mouthAtten - mul $mouthAtten, $mouthAtten, $SHADER_SPECIFIC_CONST_10.w - mul $vertAtten, $vertAtten, $mouthAtten - free $mouthAtten -} - -mov oD0, $vertAtten - -mov oT3.xyz, $worldNormal.xyz - - -free $dist -free $endFalloffFactor -free $worldPos -free $worldNormal -free $projPos -free $worldPosToLightVector -free $distatten -free $vertAtten diff --git a/materialsystem/stdshaders/vertexlitgeneric_helper.cpp b/materialsystem/stdshaders/vertexlitgeneric_helper.cpp new file mode 100644 index 00000000..14890a22 --- /dev/null +++ b/materialsystem/stdshaders/vertexlitgeneric_helper.cpp @@ -0,0 +1,1634 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "skin_dx9_helper.h" + +#include "SDK_vertexlit_and_unlit_generic_vs20.inc" +#include "SDK_vertexlit_and_unlit_generic_bump_vs20.inc" + +//#include "SDK_vertexlit_and_unlit_generic_ps20.inc" +#include "SDK_vertexlit_and_unlit_generic_ps20b.inc" +//#include "SDK_vertexlit_and_unlit_generic_bump_ps20.inc" +#include "SDK_vertexlit_and_unlit_generic_bump_ps20b.inc" + +#ifndef _X360 +#include "SDK_vertexlit_and_unlit_generic_vs30.inc" +#include "SDK_vertexlit_and_unlit_generic_ps30.inc" +#include "SDK_vertexlit_and_unlit_generic_bump_vs30.inc" +#include "SDK_vertexlit_and_unlit_generic_bump_ps30.inc" +#endif + +#include "commandbuilder.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); + + +static inline bool WantsSkinShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info ) +{ + if ( info.m_nPhong == -1) // Don't use skin without Phong + return false; + + if ( params[info.m_nPhong]->GetIntValue() == 0 ) // Don't use skin without Phong turned on + return false; + + if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture() ) // If there's Phong and diffuse warp do skin + return true; + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 1 ) + { + if ( info.m_nBumpmap == -1 ) // Don't use without a bump map + return false; + + if ( !params[info.m_nBumpmap]->IsTexture() ) // Don't use if the texture isn't specified + return false; + } + + return true; +} + +int g_nSnapShots; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + InitIntParam( info.m_nPhong, params, 0 ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + InitIntParam( info.m_nVertexAlphaTest, params, 0 ); + + InitIntParam( info.m_nFlashlightNoLambert, params, 0 ); + + if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() ) + { + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + InitIntParam( info.m_nEnvmapFrame, params, 0 ); + InitIntParam( info.m_nBumpFrame, params, 0 ); + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nReceiveFlashlight, params, 0 ); + + InitFloatParam( info.m_nDetailScale, params, 4.0f ); + + if ( (info.m_nBlendTintByBaseAlpha != -1) && (!params[info.m_nBlendTintByBaseAlpha]->IsDefined()) ) + { + params[info.m_nBlendTintByBaseAlpha]->SetIntValue( 0 ); + } + + InitFloatParam( info.m_nTintReplacesBaseColor, params, 0 ); + + if ( (info.m_nSelfIllumTint != -1) && (!params[info.m_nSelfIllumTint]->IsDefined()) ) + { + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + + if ( WantsSkinShader( params, info ) ) + { + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() || !g_pConfig->UsePhong() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + else + { + InitParamsSkin_DX9( pShader, params, pMaterialName, info ); + return; + } + } + + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + if ( info.m_nFlashlightTexture != -1 ) + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if ( bVertexLitGeneric ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + InitIntParam( info.m_nEnvmapMaskFrame, params, 0 ); + InitFloatParam( info.m_nEnvmapContrast, params, 0.0 ); + InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f ); + InitFloatParam( info.m_nSeamlessScale, params, 0.0 ); + + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nGlowAlpha, params, 1.0 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + // No texture means no self-illum or env mask in base alpha + if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + if( ( (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + // we don't need a tangent space if we have envmap without bumpmap + // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) // diffuse warp goes down bump path... + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else // no tangent space needed + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + if ( hasNormalMapAlphaEnvmapMask ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + +#ifndef MAPBASE + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 && + params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + if ( !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } +#endif + + // If mat_specular 0, then get rid of envmap + if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + InitFloatParam( info.m_nHDRColorScale, params, 1.0f ); + + InitIntParam( info.m_nLinearWrite, params, 0 ); + InitIntParam( info.m_nGammaColorRead, params, 0 ); + + InitIntParam( info.m_nDepthBlend, params, 0 ); + InitFloatParam( info.m_nDepthBlendScale, params, 50.0f ); + +#ifdef MAPBASE + InitIntParam( info.m_nAllowDiffuseModulation, params, 1 ); + + if ( ( info.m_nEnvMapFresnelMinMaxExp != -1 ) && !params[info.m_nEnvMapFresnelMinMaxExp]->IsDefined() ) + { + params[info.m_nEnvMapFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 2.0f, 0.0f ); + } + if ( ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) && !params[info.m_nBaseAlphaEnvMapMaskMinMaxExp]->IsDefined() ) + { + // Default to min: 1 max: 0 exp: 1 so that we default to the legacy behavior for basealphaenvmapmask, which is 1-baseColor.a + // These default values translate to a scale of -1, bias of 1 and exponent 1 in the shader. + params[info.m_nBaseAlphaEnvMapMaskMinMaxExp]->SetVecValue( 1.0f, 0.0f, 1.0f, 0.0f ); + } +#endif + + InitIntParam( info.m_nTreeSway, params, 0 ); + InitFloatParam( info.m_nTreeSwayHeight, params, 1000.0f ); + InitFloatParam( info.m_nTreeSwayStartHeight, params, 0.1f ); + InitFloatParam( info.m_nTreeSwayRadius, params, 300.0f ); + InitFloatParam( info.m_nTreeSwayStartRadius, params, 0.2f ); + InitFloatParam( info.m_nTreeSwaySpeed, params, 1.0f ); + InitFloatParam( info.m_nTreeSwaySpeedHighWindMultiplier, params, 2.0f ); + InitFloatParam( info.m_nTreeSwayStrength, params, 10.0f ); + InitFloatParam( info.m_nTreeSwayScrumbleSpeed, params, 5.0f ); + InitFloatParam( info.m_nTreeSwayScrumbleStrength, params, 10.0f ); + InitFloatParam( info.m_nTreeSwayScrumbleFrequency, params, 12.0f ); + InitFloatParam( info.m_nTreeSwayFalloffExp, params, 1.5f ); + InitFloatParam( info.m_nTreeSwayScrumbleFalloffExp, params, 1.0f ); + InitFloatParam( info.m_nTreeSwaySpeedLerpStart, params, 3.0f ); + InitFloatParam( info.m_nTreeSwaySpeedLerpEnd, params, 6.0f ); +} + + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- + +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + // both detailed and bumped = needs skin shader (for now) + bool bNeedsSkinBecauseOfDetail = false; + + //bool bHasBump = ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsTexture(); + //if ( bHasBump ) + //{ + // if ( ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsDefined() ) + // bNeedsSkinBecauseOfDetail = true; + //} + + if ( bNeedsSkinBecauseOfDetail || + ( info.m_nPhong != -1 && + params[info.m_nPhong]->GetIntValue() && + g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) + { + InitSkin_DX9( pShader, params, info ); + return; + } + + if ( info.m_nFlashlightTexture != -1 ) + { + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + } + + bool bIsBaseTextureTranslucent = false; + if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ? 0 : TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) //Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + } + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CVertexLitGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + +}; + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, bool bHasFlashlight, + VertexLitGeneric_DX9_Vars_t &info, + VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr ); + +/*^*/ // printf("\t\t>DrawVertexLitGeneric_DX9_Internal\n"); + + bool bHasBump = IsTextureSet( info.m_nBumpmap, params ); +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + bool hasDiffuseLighting = bVertexLitGeneric; +/*^*/ // printf("\t\t[%d] bVertexLitGeneric\n",(int)bVertexLitGeneric); + + if ( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + bHasFlashlight = false; + } + + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasDiffuseWarp = (!bHasFlashlight || IsX360() ) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + + + //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); + bool bFlashlightNoLambert = false; + if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() ) + { + bFlashlightNoLambert = true; + } + + int nTreeSwayMode = clamp( GetIntParam( info.m_nTreeSway, params, 0 ), 0, 2 ); + bool bTreeSway = nTreeSwayMode != 0; + bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params ); + + float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params ); + int nDetailBlendMode = bHasDetailTexture ? GetIntParam( info.m_nDetailTextureCombineMode, params ) : 0; + int nDetailTranslucencyTexture = -1; + + if ( bHasDetailTexture ) + { + if ( ( nDetailBlendMode == 6 ) && ( ! (g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) ) + { + nDetailBlendMode = 5; // skip fancy threshold blending if ps2.0 + } + if ( ( nDetailBlendMode == 3 ) || ( nDetailBlendMode == 8 ) || ( nDetailBlendMode == 9 ) ) + nDetailTranslucencyTexture = info.m_nDetail; + } + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ); + float fTintReplaceFactor = GetFloatParam( info.m_nTintReplacesBaseColor, params, 0.0 ); + + BlendType_t nBlendType; + bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params ); + if ( bHasBaseTexture ) + { + // if base alpha is used for tinting, ignore the base texture for computing translucency + nBlendType = pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true, nDetailTranslucencyTexture ); + } + else + { + nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); + } + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && (!bHasFlashlight || IsX360() ); //dest alpha is free for special use + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture(); + + + bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + + if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) + { + bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ) && !bTreeSway; + bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ) && !bTreeSway; + bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params ); + bool bHasSelfIllum = (!bHasFlashlight || IsX360() ) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool bHasEnvmapMask = (!bHasFlashlight || IsX360() ) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); + bool bHasSelfIllumFresnel = ( !IsTextureSet( info.m_nDetail, params ) ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); +#ifdef MAPBASE + bool bHasEnvMapFresnel = bHasEnvmap && IsBoolSet( info.m_nEnvmapFresnel, params ); +#endif + + bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params ); + bool hasSelfIllumInEnvMapMask = + ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && + ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ; + +#ifdef MAPBASE + if (!bHasEnvmap) + { + bHasEnvmapMask = hasSelfIllumInEnvMapMask; + } +#endif + + if ( pShader->IsSnapshotting() ) + { +/*^*/ // printf("\t\t[2] snapshotting...\n"); + +#ifdef MAPBASE + bool hasBaseAlphaEnvmapMask = bHasEnvmap && IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + bool hasNormalMapAlphaEnvmapMask = bHasEnvmap && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); +#else + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); +#endif + + + if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 ) + { + bHasVertexAlpha = true; + } + + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + if ( bHasSelfIllumFresnel ) + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + hasNormalMapAlphaEnvmapMask = false; + } + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsTexture(); +#ifndef MAPBASE + bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); +#endif + bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail; + if ( IsPC() ) + { + // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models) + bHasNormal = true; + } + + bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if ( bHasFlashlight ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + if ( !IsX360() ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + else + { + pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); + } + + if ( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + + unsigned int flags = VERTEX_POSITION; + if ( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } +/*^*/ // printf("\t\t[%1d] VERTEX_NORMAL\n",(flags&VERTEX_NORMAL)!=0); + + int userDataSize = 0; + bool bSRGBInputAdapter = false; + + // basetexture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + if ( bHasBaseTexture ) + { + if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ) + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + else + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // If we're on OSX GL on a crappy OS which can't do sRGB from render targets, check to see if we're reading from one... + if ( IsOSX() && !g_pHardwareConfig->CanDoSRGBReadFromRTs() ) + { + ITexture *pBaseTexture = params[info.m_nBaseTexture]->GetTextureValue(); + if ( pBaseTexture && pBaseTexture->IsRenderTarget() ) + { + bSRGBInputAdapter = true; + } + } + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + } + if ( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + userDataSize = 4; // tangent S + } + + if ( bHasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + userDataSize = 4; // tangent S + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + if ( bHasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + + if ( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR\n",(flags&VERTEX_COLOR)!=0); +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR_STREAM_1\n",(flags&VERTEX_COLOR_STREAM_1)!=0); + + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Diffuse warp texture + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + if( bHasBump ) + Warning( "DEPTHBLEND not supported by bump mapped variations of vertexlitgeneric to avoid shader bloat. Either remove the bump map or convince a graphics programmer that it's worth it.\n" ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); + } + + if( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask + } + + bool bSRGBWrite = true; + if( (info.m_nLinearWrite != -1) && (params[info.m_nLinearWrite]->GetIntValue() == 1) ) + { + bSRGBWrite = false; + } + + pShaderShadow->EnableSRGBWrite( bSRGBWrite ); + + // texcoord0 : base texcoord + int pTexCoordDim[3] = { 2, 2, 3 }; + int nTexCoordCount = 1; + + if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) ) + { + ++nTexCoordCount; + } + else + { + pTexCoordDim[1] = 0; + } + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; +/*^*/ // printf("\t\t[%1d] VERTEX_FORMAT_COMPRESSED\n",(flags&VERTEX_FORMAT_COMPRESSED)!=0); + +/*^*/ // printf("\t\t -> CShaderShadowDX8::VertexShaderVertexFormat( flags=%08x, texcount=%d )\n",flags,nTexCoordCount); + + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, 1 ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs20 ); + + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + //{ + DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20b ); + //} + //else // ps_2_0 + //{ + // DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20 ); + // SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + // SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + // SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + // SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + // SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + // SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + // SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + // SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + // SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + // SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20 ); + //} + } +#ifndef _X360 + else + { + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + // The vertex shader uses the vertex id stream + if ( bFastVertexTextures ) + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, true ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER_COMBO( SM30_VERTEXID, bFastVertexTextures ); + SET_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps30 ); + } +#endif + } + else // !(bHasBump || bHasDiffuseWarp) + { + bool bDistanceAlphaFromDetail = false; + bool bSoftMask = false; + bool bGlow = false; + bool bOutline = false; + + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + bool bDoDepthBlend = IsBoolSet( info.m_nDepthBlend, params ) && !mat_reduceparticles.GetBool(); + + if ( bDistanceAlpha ) + { + bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params ); + bSoftMask = IsBoolSet( info.m_nSoftEdges, params ); + bGlow = IsBoolSet( info.m_nGlow, params ); + bOutline = IsBoolSet( info.m_nOutline, params ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, (! bSRGBWrite ) && bHasVertexColor ); + SET_STATIC_VERTEX_SHADER_COMBO( TREESWAY, bTreeSway ? nTreeSwayMode : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs20 ); + + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send Gl this way + //{ + DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); +#ifndef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); +#endif + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB_INPUT_ADAPTER, bSRGBInputAdapter ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20b ); + //} + //else // ps_2_0 + //{ + // DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20 ); + // SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + // SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + // SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + // SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + // SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + // SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + // SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + // SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + // SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + // SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + // SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + // SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + // SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + // SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + // SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + // SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + // SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20 ); + //} + } +#ifndef _X360 + else + { + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + // The vertex shader uses the vertex id stream + if ( bFastVertexTextures ) + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER_COMBO( SM30_VERTEXID, bFastVertexTextures ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, bSRGBWrite ? 0 : 1 ); + SET_STATIC_VERTEX_SHADER_COMBO( TREESWAY, bTreeSway ? nTreeSwayMode : 0 ); + SET_STATIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); +#ifndef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); +#endif + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); +#ifdef MAPBASE + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPFRESNEL, bHasEnvMapFresnel ); +#endif + SET_STATIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps30 ); + } +#endif + } + + if ( bHasFlashlight && !IsX360() ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and the loadout and character select screens. + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + + if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) ) + { +/*^*/ // printf("\t\t[3] pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) TRUE \n"); + if ( ! pContextData ) // make sure allocated + { + ++g_nSnapShots; + pContextData = new CVertexLitGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderFogParams( 21 ); + if ( bHasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + if( bHasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); + } + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, info.m_nSelfIllumMask, -1 ); // Bind it + } + else // else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, TEXTURE_BLACK ); // Bind dummy + } + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER10, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + if ( bSeamlessDetail || bSeamlessBase ) + { + float flSeamlessData[4]={ params[info.m_nSeamlessScale]->GetFloatValue(), + 0,0,0}; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flSeamlessData ); + } + + if ( info.m_nBaseTextureTransform != -1 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + } + + + if ( bHasDetailTexture ) + { + if ( !bTreeSway ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nDetailTextureTransform, info.m_nDetailScale ); + else + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + //Assert( !bHasBump ); + if ( info.m_nDetailTint != -1 ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); + else + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 10, 1, 1, 1, 1 ); + } + } +#ifdef MAPBASE + else if ( bHasEnvmapMask && info.m_nEnvmapMaskTransform != -1 ) + { + // Use $envmapmasktransform when there is no detail texture taking up this space + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); + } + else if ( bHasBump && info.m_nBumpTransform != -1 ) + { + // Use $bumptransform when there is no detail texture taking up this space + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform ); + } +#endif + if ( bDistanceAlpha ) + { + float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params ); + float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params ); + // set all line art shader parms + bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params ); + bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params ); + + float flResScale = 1.0; + + float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params ); + float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params ); + float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params ); + float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params ); + + if ( bScaleEdges || bScaleOutline ) + { + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + flResScale=max( 0.5, max( 1024.0/nWidth, 768/nHeight ) ); + + if ( bScaleEdges ) + { + float flMid = 0.5 * ( flSoftStart + flSoftEnd ); + flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 ); + flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 ); + } + + + if ( bScaleOutline ) + { + // shrink the soft part of the outline, enlarging hard part + float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 ); + flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 ); + float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 ); + flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 ); + } + + } + + float flConsts[]={ + // c5 - glow values + GetFloatParam( info.m_nGlowX, params ), + GetFloatParam( info.m_nGlowY, params ), + GetFloatParam( info.m_nGlowStart, params ), + GetFloatParam( info.m_nGlowEnd, params ), + // c6 - glow color + 0,0,0, // will be filled in + GetFloatParam( info.m_nGlowAlpha, params ), + // c7 - mask range parms + flSoftStart, + flSoftEnd, + 0,0, + // c8 - outline color + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ), + // c9 - outline parms. ordered for optimal ps20 .wzyx swizzling + flOutlineStart0, + flOutlineEnd1, + flOutlineEnd0, + flOutlineStart1, + }; + + if ( info.m_nGlowColor != -1 ) + { + params[info.m_nGlowColor]->GetVecValue( flConsts+4, 3 ); + } + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flConsts+12, 3 ); + } +#ifdef MAPBASE + if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) + { + flConsts[10] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[0]; + flConsts[11] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[1] - flConsts[10]; + } +#endif + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, flConsts, 5 ); + + } +#ifdef MAPBASE + else if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) + { + float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + flConsts[2] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[0]; + flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[1] - flConsts[2]; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, flConsts, 1 ); + } +#endif + if ( !g_pConfig->m_bFastNoBump ) + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + } + else if ( bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + else + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + // Setting w to 1 means use separate selfillummask + float vEnvMapSaturation_SelfIllumMask[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + if ( info.m_nEnvmapSaturation != -1 ) + params[info.m_nEnvmapSaturation]->GetVecValue( vEnvMapSaturation_SelfIllumMask, 3 ); + + vEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, vEnvMapSaturation_SelfIllumMask, 1 ); + if ( bHasEnvmap ) + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, info.m_nEnvmapTint, fTintReplaceFactor ); + } + else + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, -1, fTintReplaceFactor); + } + + if ( bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + +#ifdef MAPBASE + if ( bHasEnvMapFresnel ) + { + float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + params[ info.m_nEnvMapFresnelMinMaxExp ]->GetVecValue( flConsts, 3 ); + flConsts[1] -= flConsts[0]; // convert max fresnel into scale factor + + if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) + { + flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[2]; // basealphaenvmapmask exponent in w + } + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 14, flConsts, 1 ); + } + else if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) + { + // still need to set exponent for basealphaenvmapmask + float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[2]; // basealphaenvmapmask exponent in w + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 14, flConsts, 1 ); + } +#endif + + if ( bHasSelfIllumFresnel && (!bHasFlashlight || IsX360() ) ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vConstScaleBiasExp ); + } + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nDiffuseWarpTexture, -1 ); + } + } + + if ( bHasFlashlight ) + { + // Tweaks associated with a given flashlight + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + float tweaks[4]; + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( 2, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + + if ( ( !bHasFlashlight || IsX360() ) && ( info.m_nEnvmapContrast != -1 ) ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + + // mat_fullbright 2 handling + bool bLightingOnly = bVertexLitGeneric && mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + if ( bHasBaseTexture ) + { + if( ( bHasSelfIllum && !hasSelfIllumInEnvMapMask ) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderStateAmbientLightCube( 5 ); + pContextData->m_SemiStaticCmdsOut.CommitPixelShaderLighting( 13 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nSelfIllumTint, fBlendFactor ); + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + + if ( bTreeSway ) + { + float flParams[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + flParams[0] = GetFloatParam( info.m_nTreeSwaySpeedHighWindMultiplier, params, 2.0f ); + flParams[1] = GetFloatParam( info.m_nTreeSwayScrumbleFalloffExp, params, 1.0f ); + flParams[2] = GetFloatParam( info.m_nTreeSwayFalloffExp, params, 1.0f ); + flParams[3] = GetFloatParam( info.m_nTreeSwayScrumbleSpeed, params, 3.0f ); + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, flParams ); + + flParams[0] = GetFloatParam( info.m_nTreeSwaySpeedLerpStart, params, 3.0f ); + flParams[1] = GetFloatParam( info.m_nTreeSwaySpeedLerpEnd, params, 6.0f ); + flParams[2] = 0; + flParams[3] = 0; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flParams ); + + flParams[0] = GetFloatParam( info.m_nTreeSwayHeight, params, 1000.0f ); + flParams[1] = GetFloatParam( info.m_nTreeSwayStartHeight, params, 0.1f ); + flParams[2] = GetFloatParam( info.m_nTreeSwayRadius, params, 300.0f ); + flParams[3] = GetFloatParam( info.m_nTreeSwayStartRadius, params, 0.2f ); + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, flParams ); + + flParams[0] = GetFloatParam( info.m_nTreeSwaySpeed, params, 1.0f ); + flParams[1] = GetFloatParam( info.m_nTreeSwayStrength, params, 10.0f ); + flParams[2] = GetFloatParam( info.m_nTreeSwayScrumbleFrequency, params, 12.0f ); + flParams[3] = GetFloatParam( info.m_nTreeSwayScrumbleStrength, params, 10.0f ); + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, flParams ); + } + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + if ( pShaderAPI ) + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + if ( bHasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + bool bFlashlightShadows = false; + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); + } + + SetFlashLightColorFromState( state, pShaderAPI, 28, bFlashlightNoLambert ); + + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + } + + + // Set up light combo state + LightState_t lightState = {0, false, false}; + if ( bVertexLitGeneric && (!bHasFlashlight || IsX360() ) ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_bump_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping... + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + //{ + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_bump_ps20b ); + //} + /*else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_bump_ps20 ); + }*/ + } +#ifndef _X360 + else + { + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + if ( bFastVertexTextures ) + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() && bFastVertexTextures ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_bump_ps30 ); + + if ( bFastVertexTextures ) + { + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + } +#endif + } + else // !( bHasBump || bHasDiffuseWarp ) + { + if ( bAmbientOnly ) // Override selected light combo to be ambient only + { + lightState.m_bAmbientLight = true; + lightState.m_bStaticLight = false; + lightState.m_nNumLights = 0; + } + +#ifndef _X360 + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping + //if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + //{ + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20b ); + +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_ps20b ); + //} + /*else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_ps20 ); + }*/ + } +#ifndef _X360 + else + { + const bool bFastVertexTextures = g_pHardwareConfig->HasFastVertexTextures(); + + if ( bFastVertexTextures ) + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_vertexlit_and_unlit_generic_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() && bFastVertexTextures ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_vertexlit_and_unlit_generic_ps30 ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, sdk_vertexlit_and_unlit_generic_ps30 ); + + if ( bFastVertexTextures ) + { + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } + } +#endif + } + +#ifdef MAPBASE + // material can choose to support per-instance modulation via $allowdiffusemodulation + bool bAllowDiffuseModulation = (info.m_nAllowDiffuseModulation == -1) ? true : (params[info.m_nAllowDiffuseModulation]->GetIntValue() != 0); + + if (bAllowDiffuseModulation) +#endif + { + if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() ); + } + else + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + } + } +#ifdef MAPBASE + else + { + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + pShaderAPI->SetPixelShaderConstant( 1, color ); + } +#endif + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + eyePos[3] = pShaderAPI->GetFloatRenderingParameter( FLOAT_RENDERPARM_MINIMUMLIGHTING ); + DynamicCmdsOut.SetPixelShaderConstant( 20, eyePos ); + + // Non-bump case does its own depth feathering work + if ( !bHasBump && !bHasDiffuseWarp ) + { + DynamicCmdsOut.SetDepthFeatheringPixelShaderConstant( 13, GetFloatParam( info.m_nDepthBlendScale, params, 50.0f ) ); + } + + float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; + float fWriteWaterFogToDestAlpha = (pShaderAPI->GetPixelFogCombo() == 1 && bWriteWaterFogToAlpha) ? 1 : 0; + float fVertexAlpha = bHasVertexAlpha ? 1 : 0; + + // Controls for lerp-style paths through shader code (bump and non-bump have use different register) + float vShaderControls[4] = { fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha }; + DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 ); + + // flashlightfixme: put this in common code. + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, 28, bFlashlightNoLambert ); + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + pShader->BindTexture( SHADER_SAMPLER7, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + float atten_pos[8]; + atten_pos[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten_pos[1] = flashlightState.m_fLinearAtten; + atten_pos[2] = flashlightState.m_fQuadraticAtten; + atten_pos[3] = flashlightState.m_FarZ; + atten_pos[4] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + atten_pos[5] = flashlightState.m_vecLightOrigin[1]; + atten_pos[6] = flashlightState.m_vecLightOrigin[2]; + atten_pos[7] = 1.0f; + DynamicCmdsOut.SetPixelShaderConstant( 22, atten_pos, 2 ); + + DynamicCmdsOut.SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); + } + + if ( bTreeSway ) + { + float fTempConst[4]; + fTempConst[1] = pShaderAPI->CurrentTime(); + if ( params[info.m_nTreeSwayStatic]->GetIntValue() == 0 ) + { + const Vector& windDir = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_WIND_DIRECTION ); + fTempConst[2] = windDir.x; + fTempConst[3] = windDir.y; + } + else + { + // Use a static value instead of the env_wind value. + params[info.m_nTreeSwayStaticValues]->GetVecValue( fTempConst+2, 2 ); + } + DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, fTempConst ); + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + +/*^*/ // printf("\t\tSupportsPixelShaders_2_b()*/ && g_pConfig->UseBumpmapping() && g_pConfig->UsePhong() ) + { + DrawSkin_DX9( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); + return; + } + + bool bReceiveFlashlight = bVertexLitGeneric; + bool bNewFlashlight = IsX360(); + if ( bNewFlashlight ) + { + bReceiveFlashlight = bReceiveFlashlight || ( GetIntParam( info.m_nReceiveFlashlight, params ) != 0 ); + } + bool bHasFlashlight = bReceiveFlashlight && pShader->UsingFlashlight( params ); + + DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bVertexLitGeneric, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/materialsystem/stdshaders/vertexlitgeneric_helper.h b/materialsystem/stdshaders/vertexlitgeneric_helper.h new file mode 100644 index 00000000..5df1ab93 --- /dev/null +++ b/materialsystem/stdshaders/vertexlitgeneric_helper.h @@ -0,0 +1,175 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX9_HELPER_H +#define VERTEXLITGENERIC_DX9_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX9_Vars_t +{ + VertexLitGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } + + int m_nBaseTexture; + int m_nWrinkle; + int m_nStretch; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nNormalWrinkle; + int m_nNormalStretch; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nVertexAlphaTest; + int m_nFlashlightNoLambert; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + + int m_nSelfIllumTint; + int m_nSelfIllumFresnel; + int m_nSelfIllumFresnelMinMaxExp; + + int m_nPhongExponent; + int m_nPhongTint; + int m_nPhongAlbedoTint; + int m_nPhongExponentTexture; + int m_nDiffuseWarpTexture; + int m_nPhongWarpTexture; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nSelfIllumEnvMapMask_Alpha; + int m_nAmbientOnly; + int m_nHDRColorScale; + int m_nPhong; + int m_nBaseMapAlphaPhongMask; + int m_nEnvmapFresnel; + + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + + // Rim lighting parameters + int m_nRimLight; + int m_nRimLightPower; + int m_nRimLightBoost; + int m_nRimMask; + + int m_nSeamlessScale; + int m_nSeamlessBase; + int m_nSeamlessDetail; + + // distance coded line art parameters + int m_nDistanceAlpha; + int m_nDistanceAlphaFromDetail; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + int m_nScaleEdgeSoftnessBasedOnScreenRes; + + int m_nGlow; + int m_nGlowColor; + int m_nGlowAlpha; + int m_nGlowStart; + int m_nGlowEnd; + int m_nGlowX; + int m_nGlowY; + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + int m_nScaleOutlineSoftnessBasedOnScreenRes; + + int m_nSeparateDetailUVs; + int m_nDetailTextureTransform; + + int m_nLinearWrite; + int m_nGammaColorRead; + + int m_nDetailTint; + int m_nInvertPhongMask; + + int m_nDepthBlend; + int m_nDepthBlendScale; + + int m_nSelfIllumMask; + int m_nReceiveFlashlight; + + int m_nBlendTintByBaseAlpha; + + int m_nTintReplacesBaseColor; + +#ifdef MAPBASE + // Parameters ported from Alien Swarm SDK shaders. + + // Utility param for disabling tinting on certain materials. + int m_nAllowDiffuseModulation; + + // $envmapfresnel on non-phong materials. + int m_nEnvMapFresnelMinMaxExp; + int m_nBaseAlphaEnvMapMaskMinMaxExp; + + // Disables $halflambert on phong materials. See bPhongHalfLambert in DrawSkin_DX9_Internal() for more info. + int m_nPhongDisableHalfLambert; +#endif + + int m_nTreeSway; + int m_nTreeSwayHeight; + int m_nTreeSwayStartHeight; + int m_nTreeSwayRadius; + int m_nTreeSwayStartRadius; + int m_nTreeSwaySpeed; + int m_nTreeSwaySpeedHighWindMultiplier; + int m_nTreeSwayStrength; + int m_nTreeSwayScrumbleSpeed; + int m_nTreeSwayScrumbleStrength; + int m_nTreeSwayScrumbleFrequency; + int m_nTreeSwayFalloffExp; + int m_nTreeSwayScrumbleFalloffExp; + int m_nTreeSwaySpeedLerpStart; + int m_nTreeSwaySpeedLerpEnd; + int m_nTreeSwayStatic; + int m_nTreeSwayStaticValues; +}; + +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr + ); + + +#endif // VERTEXLITGENERIC_DX9_HELPER_H diff --git a/materialsystem/stdshaders/vertexlitgeneric_inc.vsh b/materialsystem/stdshaders/vertexlitgeneric_inc.vsh deleted file mode 100644 index da6b6bf9..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_inc.vsh +++ /dev/null @@ -1,145 +0,0 @@ -#include "macros.vsh" - -sub VertexLitGeneric -{ - local( $detail ) = shift; - local( $envmap ) = shift; - local( $envmapcameraspace ) = shift; - local( $envmapsphere ) = shift; - local( $decal ) = shift; - - local( $worldPos, $worldNormal, $projPos ); - local( $reflectionVector ); - - ;------------------------------------------------------------------------------ - ; Vertex blending - ;------------------------------------------------------------------------------ - &AllocateRegister( \$worldPos ); - &AllocateRegister( \$worldNormal ); - &AllocateRegister( \$projPos ); -; if( $g_staticLightType eq "static" && $g_ambientLightType eq "none" && -; $g_localLightType1 eq "none" && $g_localLightType2 eq "none" && !$envmap ) - if( 0 ) - { - ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos - ; of the flashlight shaders - ; Special case for static prop lighting. We can go directly from - ; world to proj space for position, with the exception of z, which - ; is needed for fogging *if* height fog is enabled. - - ; NOTE: We don't use this path if $envmap is defined since we need - ; worldpos for envmapping. - dp4 $projPos.x, $vPos, $cModelViewProj0 - dp4 $projPos.y, $vPos, $cModelViewProj1 - dp4 $projPos.z, $vPos, $cModelViewProj2 - dp4 $projPos.w, $vPos, $cModelViewProj3 - ; normal - dp3 $worldNormal.x, $vNormal, $cModel0 - dp3 $worldNormal.y, $vNormal, $cModel1 - dp3 $worldNormal.z, $vNormal, $cModel2 - - ; Need this for height fog if it's enabled and for height clipping - dp4 $worldPos.z, $vPos, $cModel2 - } - else - { - &SkinPositionAndNormal( $worldPos, $worldNormal ); - - if( $SKINNING == 1 ) - { - &Normalize( $worldNormal ); - } - - ;------------------------------------------------------------------------------ - ; Transform the position from world to view space - ;------------------------------------------------------------------------------ - dp4 $projPos.x, $worldPos, $cViewProj0 - dp4 $projPos.y, $worldPos, $cViewProj1 - dp4 $projPos.z, $worldPos, $cViewProj2 - dp4 $projPos.w, $worldPos, $cViewProj3 - } - - mov oPos, $projPos - - ;------------------------------------------------------------------------------ - ; Fog - ;------------------------------------------------------------------------------ - &CalcFog( $worldPos, $projPos ); - &FreeRegister( \$projPos ); - - ;------------------------------------------------------------------------------ - ; Lighting - ;------------------------------------------------------------------------------ - &DoLighting( $worldPos, $worldNormal ); - - if( !$envmap ) - { - &FreeRegister( \$worldNormal ); - } - - ;------------------------------------------------------------------------------ - ; Texture coordinates - ;------------------------------------------------------------------------------ - - dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 - dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 - - if( $envmap ) - { - if( $envmapcameraspace ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - - ; transform reflection vector into view space - dp3 oT1.x, $reflectionVector, $cViewModel0 - dp3 oT1.y, $reflectionVector, $cViewModel1 - dp3 oT1.z, $reflectionVector, $cViewModel2 - - &FreeRegister( \$reflectionVector ); - } - elsif( $envmapsphere ) - { - &AllocateRegister( \$reflectionVector ); - &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); - &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); - - &FreeRegister( \$reflectionVector ); - } - else - { - &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); - } - - ; envmap mask - dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 - dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 - - &FreeRegister( \$worldNormal ); - } - else - { - if ( $decal ) - { - &AllocateRegister( \$temp ); - mov $temp, $vTexCoord0 - sub oT1.xyz, $temp.xyz, $vTexCoord1.xyz - sub oT2.xyz, $vTexCoord2.xyz, $temp.xyz - &FreeRegister( \$temp ); - } - else - { - ; YUCK! This is to make texcoords continuous for mat_softwaretl - mov oT1, $cZero - mov oT2, $cZero - } - } - - if( $detail ) - { - dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 - dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 - } - &FreeRegister( \$worldPos ); -} - diff --git a/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh b/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh deleted file mode 100644 index 722e1418..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh +++ /dev/null @@ -1,5 +0,0 @@ -ps.1.1 - -mov r0, v0 - - diff --git a/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc b/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc deleted file mode 100644 index 70ad7094..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc +++ /dev/null @@ -1,9 +0,0 @@ -struct PS_INPUT -{ - float3 vColor0 : COLOR0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - return float4( i.vColor0, 1.0 ); -} diff --git a/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh deleted file mode 100644 index afee48ad..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh +++ /dev/null @@ -1,19 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -tex t0 ; base color -tex t1 ; cube map -tex t2 ; envmap mask - -mul r0, t0, c3 ; Base times modulation -mul r1, t1, t2 ; Envmap * mask -mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint -mul r0.rgb, v0, r0 ; apply vertex lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh deleted file mode 100644 index 4b479199..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh +++ /dev/null @@ -1,25 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 -tex t1 - -mul r0.rgb, t0, c3 + ; base times modulation -mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) - -mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting - diff --git a/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh b/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh deleted file mode 100644 index 38c80e4f..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh +++ /dev/null @@ -1,26 +0,0 @@ -ps.1.1 - -;------------------------------------------------------------------------------ -; Draw a texture . . woo hoo! -; t0 - texture -; -; The texture coordinates need to be defined as follows: -; tc0 - texcoords -;------------------------------------------------------------------------------ - -; Get the color from the texture -tex t0 ; base -tex t1 ; env map -tex t2 ; mask - -mul r0.rgb, t0, c3 + ; base times modulation -mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha - -mul r1, t2, t1 ; envmapmask * envmap -mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) - -mul r0.rgb, v0, r0 ; Apply lighting -mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) - -mul r1, t0, c1 ; Self illum * tint -lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh b/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh deleted file mode 100644 index c0ab2765..00000000 --- a/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh +++ /dev/null @@ -1,22 +0,0 @@ -vs.1.1 - -# STATIC: "HALF_LAMBERT" "0..1" -# STATIC: "ENVMAP" "0..1" -# STATIC: "ENVMAPCAMERASPACE" "0..0" -# STATIC: "ENVMAPSPHERE" "0..1" -# DYNAMIC: "DOWATERFOG" "0..1" -# DYNAMIC: "LIGHT_COMBO" "0..21" -# DYNAMIC: "SKINNING" "0..1" - -# can't have envmapshere or envmapcameraspace without envmap -# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) - -# can't have both envmapsphere and envmapcameraspace -# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE - -# decal is by itself -# SKIP: $DECAL && ( $DETAIL || $ENVMAP || $ENVMAPCAMERASPACE || $ENVMAPSPHERE ) - -#include "VertexLitGeneric_inc.vsh" - -&VertexLitGeneric( 1, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, 0 ); diff --git a/materialsystem/stdshaders/vertexlitpbr_ps30.fxc b/materialsystem/stdshaders/vertexlitpbr_ps30.fxc new file mode 100644 index 00000000..c5f8e881 --- /dev/null +++ b/materialsystem/stdshaders/vertexlitpbr_ps30.fxc @@ -0,0 +1,438 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example pixel shader that can be applied to models +// +//================================================================================================== + +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" +// STATIC: "SMOOTHNESS" "0..1" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "CSM" "0..1" +// DYNAMIC: "CSM_PERF" "0..2" +// DYNAMIC: "LIGHT_PREVIEW" "0..2" + +// We don't care about those in the editor +// SKIP: ($CUBEMAP || FLASHLIGHT ) && $LIGHT_PREVIEW + +// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// SKIP: ( $CUBEMAP == 1 ) && ( $FLASHLIGHT == 1 ) + +// both cant exist at the same time +// SKIP: ( $FLASHLIGHT == 1) && ( $CSM == 1) + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +// SKIP: ($CUBEMAP || FLASHLIGHT ) + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" +#include "common_pbr.h" +#include "common_deferredshadows_fxc.h" + +#ifdef NV3X + #define PSHADER_VECT_SCALE 20.0 + #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) +#else + #define PSHADER_VECT_SCALE 1.0 + #define VSHADER_VECT_SCALE 1.0 +#endif + +const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); +const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +#if FLASHLIGHT == 1 +sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler +sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers +sampler FlashlightSampler : register( s6 ); // Flashlight cookie + +const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass +const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4 g_FlashlightColor : register( PSREG_FLASHLIGHT_COLOR ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +#elif CSM == 1 +sampler ShadowDepthSampler : register( s4 ); // CSM Depth + +const float4x4 g_CSMWorldToTexture : register( c32 ); +const float4 g_CascadeFwd : register( c36 ); +const float4 g_CascadeLight : register( c37 ); +const float4 g_CascadeAmbient : register( c38 ); +const float2 g_CascadeBias : register( c39 ); +const float2 g_CascadeResolution : register( c40 ); +const float4 g_CascadeSize : register( c41 ); +#endif +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) + +#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz + +sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha +sampler RoughnessSampler : register( s1 ); // Roughness +sampler MetallicSampler : register( s2 ); // Metallic +sampler BumpmapSampler : register( s3 ); // Bump map +sampler EnvmapSampler : register( s7 ); // for IBL +sampler BRDFSampler : register( s8 ); // for IBL +sampler AOSampler : register( s9 ); // AO +sampler EmissiveSampler : register( s10 ); // Emissive map + +//DoPBRLight(float3 vWorldPos, float3 vWorldNormal, float3 albedo, float3 vPosition, float3 vColor, float3 vEye, float atten_radius, float3 metallic, float3 roughness) +float3 DoPBRLights(float3 vEye, float3 vWorldNormal, float3 vWorldPos, float4 albedo, float4 atten, float metallic, float roughness) +{ + float3 linearColor = 0.0; + int nNumLights = NUM_LIGHTS; + + if ( NUM_LIGHTS > 0 ) + { + linearColor += DoPBRLight(vWorldPos, vWorldNormal, albedo, cLightInfo[0].pos, cLightInfo[0].color.rgb, vEye, atten.x, metallic, roughness); + if ( NUM_LIGHTS > 1 ) + { + linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[1].pos, cLightInfo[1].color.rgb, vEye, atten.x, metallic, roughness); + if ( NUM_LIGHTS > 2 ) + { + linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, cLightInfo[2].pos, cLightInfo[2].color.rgb, vEye, atten.x, metallic, roughness); + if ( NUM_LIGHTS > 3 ) + { + // Unpack the 4th light's data from tight constant packing + float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + linearColor += DoPBRLight( vWorldPos, vWorldNormal, albedo, vLight3Pos, vLight3Color, vEye, atten.x, metallic, roughness); + } + } + } + } + + return linearColor; +} + +// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile +half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV ) +{ + const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; + const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; + half4 r = Roughness * c0 + c1; + half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; + half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw; + return SpecularColor * AB.x + AB.y; +} + +float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max(1.0f.xxx - roughness, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 DoIBL(float3 vEye, float3 vWorldNormal, float3 vWorldPos, float2 screenUV, float3 albedo, float metallness, float roughness) +{ + float3 metallic = clamp(metallness, 0.0f, 0.9f); +#if CUBEMAP == 1 + float3 V = normalize( vEye - vWorldPos ); + float3 N = normalize( vWorldNormal ); + + //precompute dots + float NV = max(0.0,dot(N, V)); + + HALF3 reflectVect = 2.0 * NV * N - V; + float4 directionPosX = { 1.0f, 0.01f, 0.01f, 12.0f }; float4 directionNegX = {-1.0f, 0.01f, 0.01f, 12.0f }; + float4 directionPosY = { 0.01f, 1.0f, 0.01f, 12.0f }; float4 directionNegY = { 0.01f,-1.0f, 0.01f, 12.0f }; + float4 directionPosZ = { 0.01f, 0.01f, 1.0f, 12.0f }; float4 directionNegZ = { 0.01f, 0.01f,-1.0f, 12.0f }; + float3 lookupPosX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosX); + float3 lookupNegX = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegX); + float3 lookupPosY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosY); + float3 lookupNegY = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegY); + float3 lookupPosZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosZ); + float3 lookupNegZ = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegZ); + float3 envmapCube[6] = { lookupPosX, lookupNegX, lookupPosY, lookupNegY, lookupPosZ, lookupNegZ }; + + float3 irradiance = PixelShaderAmbientLight( N, cAmbientCube ); + + float3 f0 = 0.04f.xxx; + f0 = lerp(f0, albedo.rgb, metallic); + float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term + + half3 BRDF = EnvBRDFApprox(f0, roughness, NV); + + float3 kD = 1.0f.xxx - F; + kD *= 1.0 - metallic; + + float3 diffuseIBL = kD * albedo * irradiance; + float3 lookup = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, float4(reflectVect, roughness * 12.0)).rgb; + float3 specularIrradiance = lerp(lookup, PixelShaderAmbientLight( reflectVect, envmapCube ), roughness * roughness ); + float3 specularIBL = BRDF * specularIrradiance; + //mix + return max(0.0, diffuseIBL + specularIBL); +#else + + float3 V = normalize( vEye - vWorldPos ); + float3 N = normalize( vWorldNormal ); + + //precompute dots + float NV = max(0.0,dot(N, V)); + + float3 irradiance = PixelShaderAmbientLight( N, cAmbientCube ); + + float3 f0 = 0.04f.xxx; + f0 = lerp(f0, albedo.rgb, metallic); + float3 F = fresnelSchlickRoughness(NV, f0, roughness); // ambient Lighting Fresnel Term + + float3 kD = 1.0f.xxx - F; + kD *= 1.0 - metallic; + + float3 diffuseIBL = kD * albedo * irradiance; + + return max(0.0, diffuseIBL); +#endif +} + +#if FLASHLIGHT == 1 +float3 DoFlashlight(float3 vWorldNormal, float3 vWorldPos, float3 albedo, float metallic, float roughness) +{ + float4 flashlightSpacePosition = mul( float4(vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = tex2D( FlashlightSampler, vProjCoords); + float3 shadow = 1.0f; + #if FLASHLIGHTSHADOWS + shadow = tex2DprojBicubic(ShadowDepthSampler, 512.0f.xx, vProjCoords.xy, vProjCoords.z); + #endif + float2 dist = float2(length(g_FlashlightPos_RimBoost.xyz - vWorldPos), dot(g_FlashlightPos_RimBoost.xyz - vWorldPos,g_FlashlightPos_RimBoost.xyz - vWorldPos)); + float fAtten = saturate( dot( g_FlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/dist.x, 1.0f/dist.y ) ) ); + float3 light = DoPBRLight( vWorldPos, vWorldNormal, albedo, g_FlashlightPos_RimBoost.xyz, flashlightColor.rgb * g_FlashlightColor.xyz, g_EyePos.xyz, shadow * fAtten * g_FlashlightColor.w, metallic, roughness); + return light; +} +#elif CSM == 1 +float DoCSM( sampler DepthSampler, const float3 vProjCoords, float vViewDepth, float LdN ) +{ + float2 rtSize = g_CascadeResolution;//float2(4096.0f * 4.0f, 4096.0f) * 2.0f; + float fEpsilonX = 1.0f / rtSize.y; + float fEpsilonY = 1.0f / rtSize.x; + +#if CSM_PERF < 1 + float3 cascade0 = float3( float2((vProjCoords.x / 4), vProjCoords.y), vProjCoords.z); + float3 cascade1 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.y - 2 - 1.0f/8.0f - 0.5), vProjCoords.y + (g_CascadeSize.y - 1) / 2) / g_CascadeSize.y, vProjCoords.z); +#endif +#if CSM_PERF < 2 + float3 cascade2 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.z - 3 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.z - 1) / 2) / g_CascadeSize.z, vProjCoords.z); +#endif + float3 cascade3 = float3( float2((vProjCoords.x / 4) + (g_CascadeSize.w - 4 - 1.0f/8.0f), vProjCoords.y + (g_CascadeSize.w - 1) / 2) / g_CascadeSize.w, vProjCoords.z); + + float projMask = 1.0f; + if(vViewDepth >= g_CascadeSize.w * g_CascadeSize.x - 100) + { + projMask = 0.0f; + } + + float4 vShadowTweaks = float4(fEpsilonX, fEpsilonY, 0.0f, 0.0f); +#if CSM_PERF < 1 + float shadowProjDiff0 = 1; + float3 shadowMapCenter_objDepth0 = cascade0; + float2 shadowMapCenter0 = shadowMapCenter_objDepth0.xy; + float objDepth0 = shadowMapCenter_objDepth0.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff0; + float3 vShadowPos0 = float3(shadowMapCenter0, objDepth0); + + float shadowProjDiff1 = g_CascadeSize.y; + float3 shadowMapCenter_objDepth1 = cascade1; + float2 shadowMapCenter1 = shadowMapCenter_objDepth1.xy; + float objDepth1 = shadowMapCenter_objDepth1.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff1; + float3 vShadowPos1 = float3(shadowMapCenter1, objDepth1); +#endif + +#if CSM_PERF < 2 + float shadowProjDiff2 = g_CascadeSize.z; + float3 shadowMapCenter_objDepth2 = cascade2; + float2 shadowMapCenter2 = shadowMapCenter_objDepth2.xy; + float objDepth2 = shadowMapCenter_objDepth2.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff2; + float3 vShadowPos2 = float3(shadowMapCenter2, objDepth2); +#endif + + float shadowProjDiff3 = g_CascadeSize.w; + float3 shadowMapCenter_objDepth3 = cascade3; + float2 shadowMapCenter3 = shadowMapCenter_objDepth3.xy; + float objDepth3 = shadowMapCenter_objDepth3.z + g_CascadeBias.y * (g_CascadeBias.x * LdN) * shadowProjDiff3; + float3 vShadowPos3 = float3(shadowMapCenter3, objDepth3); + + /*float shadow0 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); + float shadow1 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); + float shadow2 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); + float shadow3 = tex2DprojBilinear(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3);*/ + + float shadow3 = PCF(DepthSampler,rtSize, shadowMapCenter3.xy, objDepth3); + +#if CSM_PERF < 2 + float shadow2 = PCF(DepthSampler,rtSize, shadowMapCenter2.xy, objDepth2); +#else + float shadow2 = shadow3; +#endif + +#if CSM_PERF < 1 + float shadow1 = PCF(DepthSampler,rtSize, shadowMapCenter1.xy, objDepth1); + float shadow0 = PCF(DepthSampler,rtSize, shadowMapCenter0.xy, objDepth0); +#else + float shadow1 = shadow2; + float shadow0 = shadow2; +#endif + + + /*float shadow0 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos0, vShadowTweaks); + float shadow1 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos1, vShadowTweaks); + float shadow2 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos2, vShadowTweaks); + float shadow3 = DoShadowNvidiaPCF5x5GaussianEx(DepthSampler, vShadowPos3, vShadowTweaks); + + float shadow0 = DoShadowRAWZ(DepthSampler, float4(vShadowPos0, 1.0f)); + float shadow1 = DoShadowRAWZ(DepthSampler, float4(vShadowPos1, 1.0f)); + float shadow2 = DoShadowRAWZ(DepthSampler, float4(vShadowPos2, 1.0f)); + float shadow3 = DoShadowRAWZ(DepthSampler, float4(vShadowPos3, 1.0f));*/ + + + float shadow01 = lerp(shadow0,shadow1,pow(saturate(vViewDepth / (g_CascadeSize.x - 6)), 20.0f)); + float shadow012 = lerp(shadow01,shadow2,pow(saturate(vViewDepth / (g_CascadeSize.y * g_CascadeSize.x - 6)), 20.0f)); + float shadow0123 = lerp(shadow012,shadow3,pow(saturate(vViewDepth / (g_CascadeSize.z * g_CascadeSize.x - 6)), 20.0f)); + + float shadow = shadow0123; + + if(projMask == 1.0f) + { + float smoothCSMMask = pow(saturate(vViewDepth / (g_CascadeSize.w * g_CascadeSize.x - 100)), 20.0f); + float shadowFinal = lerp(shadow, 1.0f, smoothCSMMask); + return shadowFinal; + } + else + { + return 1.0f; + } + +} + +float3 DoPBRCSM(in float3 worldPos, in float3 worldNormal, float3 albedo, float metallic, float roughness, float ViewZ) +{ + float3 Out; + float LdN = max(1.0f - saturate(dot(worldNormal, -g_CascadeFwd.xyz)), 0.01); + float4 flashlightSpacePosition = mul(float4(worldPos, 1.0f), g_CSMWorldToTexture); + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flShadow = DoCSM(ShadowDepthSampler, vProjCoords, ViewZ, LdN); + float diffuse = dot(worldNormal, -g_CascadeFwd.xyz); + diffuse = saturate(diffuse); + + Out = DoPBRLight(worldPos, worldNormal, albedo, (-g_CascadeFwd.xyz * 4096) + g_EyePos, g_CascadeLight, g_EyePos, flShadow, metallic, roughness); + return Out; +} +#endif + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float4 lightAtten : TEXCOORD1; + float3 worldNormal : TEXCOORD2; + float3 worldPos : TEXCOORD3; + float4 projPos : TEXCOORD4; + float4 color : TEXCOORD5; + float3 localPos : TEXCOORD6; // for Irradiance calculations + float4 vWorldTangent: TEXCOORD7; + float3 vWorldBinormal: TEXCOORD8; +}; + +struct PS_OUTPUT +{ + float4 MainOut : COLOR0; + float4 Normal : COLOR1; + float4 MRAO : COLOR2; + float4 Albedo : COLOR3; +}; + +#if LIGHT_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#elif LIGHT_PREVIEW == 1 +HALF4 main(PS_INPUT i) : COLOR +#else +PS_OUTPUT main(PS_INPUT i) : COLOR +#endif +{ + float2 UV = i.baseTexCoord; + float2 screenUV = i.projPos.xy / i.projPos.w; + screenUV = screenUV * 0.5f + 0.5f; + float4 baseColor = tex2D( BaseTextureSampler, UV ); + +#if SMOOTHNESS == 0 + float roughnessMap = tex2D( RoughnessSampler, UV ); +#else + float roughnessMap = 1.0f - tex2D( RoughnessSampler, UV ); +#endif + + float metallicMap = tex2D( MetallicSampler, UV ); + float AOSample = tex2D( AOSampler, UV ); + float3 EmissiveSample = tex2D( EmissiveSampler, UV ); + float4 normalTexel = tex2D( BumpmapSampler, UV); + + float3 worldPos = i.worldPos; + float3 worldNormal = i.worldNormal; + float3 eyeToWorld = (g_EyePos - worldPos); + float3 albedo = g_DiffuseModulation.rgb * baseColor.rgb; + bool bCubemap = (CUBEMAP) ? true : false; + + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + float3 vWorldBinormal = i.vWorldBinormal; + + float3 vWorldNormal = Vec3TangentToWorld( tangentSpaceNormal, worldNormal, i.vWorldTangent, vWorldBinormal ); + vWorldNormal = normalize( vWorldNormal ); + + float3 projPos = i.projPos.xyz; + float3 Lighting = float(0.0).xxx; + + // Summation of diffuse illumination from all local lights + Lighting = DoPBRLights(g_EyePos.xyz, vWorldNormal, worldPos, baseColor, i.lightAtten, metallicMap, roughnessMap); + float3 IBL = DoIBL(g_EyePos.xyz, vWorldNormal, worldPos, screenUV, baseColor.rgb, metallicMap, roughnessMap); +#if FLASHLIGHT + float3 Flashlight = DoFlashlight(vWorldNormal, worldPos, baseColor.rgb, metallicMap, roughnessMap); +#elif CSM == 1 + float3 CSMLight = DoPBRCSM(worldPos, vWorldNormal, baseColor.rgb, metallicMap, roughnessMap, length(worldPos - g_EyePos)); +#endif + + float3 result = ( +#if FLASHLIGHT + Flashlight); +#elif CSM == 1 + CSMLight + Lighting + IBL * AOSample) + EmissiveSample; +#else + Lighting + IBL * AOSample) + EmissiveSample; +#endif + float alpha = baseColor.a * g_DiffuseModulation.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); + +#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + alpha = fogFactor; +#endif + +#if LIGHT_PREVIEW == 1 + result = DoPBRLight(worldPos, vWorldNormal, baseColor, g_EyePos.xyz, 1.0f.xxx, g_EyePos.xyz, 5.0f, metallicMap, roughnessMap); + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + return FinalOutput( float4( result, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z ); +#elif LIGHT_PREVIEW == 2 + LPREVIEW_PS_OUT Output; + Output.color = float4( baseColor.xyz,alpha ); + Output.normal = float4( vWorldNormal,alpha ); + Output.position = float4( worldPos, alpha ); + Output.flags = float4( 1.0f - metallicMap, roughnessMap, 1, alpha ); + return FinalOutput( Output, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +#else + + PS_OUTPUT output = (PS_OUTPUT) 0; + + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + output.MainOut = FinalOutput(float4(result, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z); +#if !FLASHLIGHT + output.Normal = float4(vWorldNormal.xyz, 1.0f); + output.MRAO = float4(metallicMap, roughnessMap, AOSample, 0.0f); + output.Albedo = float4(baseColor.xyz, 1.0f); +#endif + return output; +#endif +} diff --git a/materialsystem/stdshaders/vertexlitPBR_vs30.fxc b/materialsystem/stdshaders/vertexlitpbr_vs30.fxc similarity index 100% rename from materialsystem/stdshaders/vertexlitPBR_vs30.fxc rename to materialsystem/stdshaders/vertexlitpbr_vs30.fxc diff --git a/materialsystem/stdshaders/volume_clouds.cpp b/materialsystem/stdshaders/volume_clouds.cpp index 1421dbb4..1f7a3ce7 100644 --- a/materialsystem/stdshaders/volume_clouds.cpp +++ b/materialsystem/stdshaders/volume_clouds.cpp @@ -1,13 +1,12 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "volume_clouds_helper.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -DEFINE_FALLBACK_SHADER( VolumeClouds, VolumeClouds_dx9 ) -BEGIN_VS_SHADER( VolumeClouds_dx9, "VolumeClouds" ) +BEGIN_VS_SHADER( VolumeClouds, "VolumeClouds" ) BEGIN_SHADER_PARAMS SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 1" ) diff --git a/materialsystem/stdshaders/volume_clouds_helper.cpp b/materialsystem/stdshaders/volume_clouds_helper.cpp index cd2e889e..86831c89 100644 --- a/materialsystem/stdshaders/volume_clouds_helper.cpp +++ b/materialsystem/stdshaders/volume_clouds_helper.cpp @@ -1,13 +1,12 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "mathlib/vmatrix.h" #include "volume_clouds_helper.h" #include "convar.h" // Auto generated inc files #include "volume_clouds_vs20.inc" -#include "volume_clouds_ps20.inc" #include "volume_clouds_ps20b.inc" @@ -58,16 +57,8 @@ void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDyn SET_STATIC_VERTEX_SHADER( volume_clouds_vs20 ); // Pixel Shader - if( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) - { - DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); - SET_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); - SET_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); - } + DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); // Textures pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); @@ -108,16 +99,8 @@ void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDyn pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vPackedVsConst1, 1 ); // Set Pixel Shader Combos - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) - { - DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); // Bind textures pShader->BindTexture( SHADER_SAMPLER0, info.m_nTexture1 ); diff --git a/materialsystem/stdshaders/volume_clouds_ps2x.fxc b/materialsystem/stdshaders/volume_clouds_ps2x.fxc deleted file mode 100644 index 7435f305..00000000 --- a/materialsystem/stdshaders/volume_clouds_ps2x.fxc +++ /dev/null @@ -1,66 +0,0 @@ -//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============// - -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] - -// Includes ======================================================================================= -#include "common_vertexlitgeneric_dx9.h" - -// Texture Samplers =============================================================================== -sampler g_tInnerSampler : register( s0 ); -sampler g_tMiddleSampler : register( s1 ); -sampler g_tOuterSampler : register( s2 ); - -// Shaders Constants and Globals ================================================================== -//const float4 g_vPackedConst6 : register( c6 ); -//#define g_flTime g_vPackedConst6.w - -// Interpolated values ============================================================================ -struct PS_INPUT -{ - float4 v2DTangentViewVector01 : TEXCOORD0; - float4 vUv01 : TEXCOORD1; - float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; -}; - -// Main =========================================================================================== -float4 main( PS_INPUT i ) : COLOR -{ - float4 vFinalColor = float4( 0.0f, 0.0f, 0.0f, 1.0f ); - -#if defined(SHADER_MODEL_PS_2_0) - float flNumLayers = 2.0f; -#else - float flNumLayers = 10.0f; -#endif - - //float flColorDim = 1.0f; - for ( float j=flNumLayers-1.0f; j>=0.0f; j-=1.0f ) // From hightest to lowest layer - { - float4 vInnerTexel = tex2D( g_tInnerSampler, saturate( i.vUv01.xy + i.v2DTangentViewVector01.xy * 0.005 * j ) ); - float4 vMiddleTexel = tex2D( g_tMiddleSampler, saturate( i.vUv01.wz + i.v2DTangentViewVector01.wz * 0.005 * j ) ); - float4 vOuterTexel = tex2D( g_tOuterSampler, saturate( i.v2DTangentViewVector2_vUv2.wz + i.v2DTangentViewVector2_vUv2.xy * 0.005 * j ) ); - - float4 vThisTexel; - vThisTexel.rgb = ( vInnerTexel.rgb * vInnerTexel.a ) + ( vMiddleTexel.rgb * vMiddleTexel.a ) + ( vOuterTexel.rgb * vOuterTexel.a ); - vThisTexel.a = 1.0f - ( ( 1.0f - vOuterTexel.a ) * ( 1.0f - vMiddleTexel.a ) * ( 1.0f - vInnerTexel.a ) ); - - //vThisTexel.rgb *= flColorDim; - //flColorDim *= 0.95f; - - // 5.0 and 0.8625 are magic numbers that look good with the current textures - float flBlendValue = saturate( pow( vThisTexel.a, lerp( 5.0f, 0.8625f, saturate( j/(flNumLayers-1.0f) ) ) ) ); - - vFinalColor.rgb = vThisTexel.rgb + ( vFinalColor.rgb * ( 1.0f - flBlendValue ) ); - vFinalColor.a *= 1.0f - flBlendValue; // Dest alpha scalar - } - - //===============// - // Combine terms // - //===============// - float4 result; - result.rgb = vFinalColor.rgb; - result.a = 1.0f - vFinalColor.a; - - return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit. -} diff --git a/materialsystem/stdshaders/vr_distort_hud.cpp b/materialsystem/stdshaders/vr_distort_hud.cpp deleted file mode 100644 index b78a3e51..00000000 --- a/materialsystem/stdshaders/vr_distort_hud.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "BaseVSShader.h" -#include "commandbuilder.h" - -#include "vr_distort_hud_ps20.inc" -#include "vr_distort_hud_ps20b.inc" -#include "vr_distort_hud_vs20.inc" -#include "vr_distort_hud_ps30.inc" -#include "vr_distort_hud_vs30.inc" - -#include "../materialsystem_global.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData -{ -public: - uint8 *m_pStaticCmds; - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; - - void ResetStaticCmds( void ) - { - if ( m_pStaticCmds ) - { - delete[] m_pStaticCmds; - m_pStaticCmds = NULL; - } - } - - CVRDistortTexture_DX9_Context( void ) - { - m_pStaticCmds = NULL; - } - - ~CVRDistortTexture_DX9_Context( void ) - { - ResetStaticCmds(); - } - -}; - - -BEGIN_VS_SHADER( vr_distort_hud, "Help for hud warp" ) - BEGIN_SHADER_PARAMS - - SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_gui", "" ) - SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map_left", "" ) - SHADER_PARAM( DISTORTBOUNDS, SHADER_PARAM_TYPE_VEC4, "[ 0 0 1 1 ]", "" ) - SHADER_PARAM( HUDTRANSLUCENT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( HUDUNDISTORT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); - LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | TEXTUREFLAGS_SINGLECOPY | - TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); - } - - SHADER_DRAW - { - CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); - bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; - - if ( !pContextData ) // make sure allocated - { - pContextData = new CVRDistortTexture_DX9_Context; - *pContextDataPtr = pContextData; - } - - if ( pShaderShadow || bNeedRegenStaticCmds ) - { - pContextData->ResetStaticCmds(); - CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; - - staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); - staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); - - staticCmdsBuf.End(); - - // now, copy buf - pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; - memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); - } - - if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) - { - // need to regenerate the semistatic cmds - pContextData->m_SemiStaticCmdsOut.Reset(); - pContextData->m_bMaterialVarsChanged = false; - - pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); - pContextData->m_SemiStaticCmdsOut.End(); - } - - SHADOW_STATE - { - SetInitialShadowState( ); - - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - pShaderShadow->EnableSRGBWrite( true ); - pShaderShadow->EnableAlphaWrites( false ); - - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); - - if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) - { - pShaderShadow->EnableAlphaTest( true ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - else - { - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->EnableBlending( false ); - pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ZERO ); - } - - DefaultFog(); - - int nFormat = 0; - nFormat |= VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); - - if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) - { - DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); - SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); - SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); - SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); - } - } - else - { - DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); - SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); - SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); - } - } - - DYNAMIC_STATE - { - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; - DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); - DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); - - pShaderAPI->SetDefaultState(); - - SetPixelShaderConstant( 0, DISTORTBOUNDS ); - SetPixelShaderConstant( 1, HUDTRANSLUCENT ); - - int hudUndistortEnabled = ( params[ HUDUNDISTORT ]->GetIntValue() == 0 ) ? 0 : 1; - - if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) - { - DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); - } - } - else - { - DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); - } - - DynamicCmdsOut.End(); - pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); - } - - Draw(); - - } -END_SHADER diff --git a/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc b/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc deleted file mode 100644 index 331c1897..00000000 --- a/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc +++ /dev/null @@ -1,78 +0,0 @@ -// DYNAMIC: "CMBO_HUDUNDISTORT" "0..1" - -#include "shader_constant_register_map.h" -#include "common_ps_fxc.h" - -sampler BaseTextureSampler : register( s0 ); -sampler DistortMapTextureSampler : register( s1 ); - -const float4 DistortBounds : register( c0 ); -const int bHudTranslucent : register( c1 ); - -struct PS_INPUT -{ - float2 vBaseTexCoord : TEXCOORD0; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - float2 vOriginal = i.vBaseTexCoord.xy; - - - // The full uv 0->1 range of the base texture here is shifted/scaled so that it maps - // to the region that would be minUV->maxUV of the base texture in the regular undistort - // code. This lets us overlay a higher-resolution inset rectangle directly onto the - // render target with undistort, which results in a much higher-quality HUD. - - float2 minUV = DistortBounds.xy; - float2 maxUV = DistortBounds.zw; - float2 scaleUV = 1.0 / ( maxUV - minUV ); - - - float2 vGreen; - float4 vFinal; - - #if ( CMBO_HUDUNDISTORT ) - { - float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); - - float2 vRed = vRead.xy; - float2 vBlue = vRead.zw; - - vGreen = ( vRed + vBlue ) / 2.0; - - vRed = ( vRed - minUV ) * scaleUV; - vGreen = ( vGreen - minUV ) * scaleUV; - vBlue = ( vBlue - minUV ) * scaleUV; - - vFinal.r = tex2D( BaseTextureSampler, vRed ).r; - vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; - vFinal.b = tex2D( BaseTextureSampler, vBlue ).b; - } - #else - { - vGreen = ( vOriginal - minUV ) * scaleUV; - vFinal = tex2D( BaseTextureSampler, vGreen ); - } - #endif - - - // When the HUD isn't supposed to be rendered as translucent, some of its elements do occasionally have non-unit alpha. - // We always have blending and alphatest enabled here, so if the hud itself is not supposed to be translucent we need - // to fix up the alphas. - vFinal.a = lerp( 1, vFinal.a, bHudTranslucent ); - - - // Smooth off the edges of the quad. This also gives (0,0,0,0) in the outer areas, for alpha test and for blackout. - - const float edgeRampFrac = 0.005; - float2 uvEdgeRamp = smoothstep( float2(-edgeRampFrac,-edgeRampFrac), float2(edgeRampFrac,edgeRampFrac), vGreen ) * - ( 1 - smoothstep( float2(1-edgeRampFrac,1-edgeRampFrac), float2(1+edgeRampFrac,1+edgeRampFrac), vGreen ) ); - - float edgeRamp = uvEdgeRamp.x * uvEdgeRamp.y; - - vFinal *= edgeRamp; - - - return vFinal; -} diff --git a/materialsystem/stdshaders/vr_distort_hud_vs20.fxc b/materialsystem/stdshaders/vr_distort_hud_vs20.fxc deleted file mode 100644 index b82bfa13..00000000 --- a/materialsystem/stdshaders/vr_distort_hud_vs20.fxc +++ /dev/null @@ -1,26 +0,0 @@ -#include "common_vs_fxc.h" - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - o.vProjPos = v.vPos; - o.vBaseTexCoord = v.vBaseTexCoord; - - return o; -} diff --git a/materialsystem/stdshaders/vr_distort_texture.cpp b/materialsystem/stdshaders/vr_distort_texture.cpp deleted file mode 100644 index 1e87d72a..00000000 --- a/materialsystem/stdshaders/vr_distort_texture.cpp +++ /dev/null @@ -1,213 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "BaseVSShader.h" -#include "commandbuilder.h" - -#include "vr_distort_texture_ps20.inc" -#include "vr_distort_texture_ps20b.inc" -#include "vr_distort_texture_vs20.inc" -#include "vr_distort_texture_ps30.inc" -#include "vr_distort_texture_vs30.inc" - -#include "../materialsystem_global.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - - - - - - -class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData -{ -public: - uint8 *m_pStaticCmds; - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; - - void ResetStaticCmds( void ) - { - if ( m_pStaticCmds ) - { - delete[] m_pStaticCmds; - m_pStaticCmds = NULL; - } - } - - CVRDistortTexture_DX9_Context( void ) - { - m_pStaticCmds = NULL; - } - - ~CVRDistortTexture_DX9_Context( void ) - { - ResetStaticCmds(); - } - -}; - - -static const float kAllZeros[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - -BEGIN_VS_SHADER( vr_distort_texture, "Help for warp" ) - BEGIN_SHADER_PARAMS - - SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map", "" ) - SHADER_PARAM( USERENDERTARGET, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); - LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | - TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); - } - - SHADER_DRAW - { - CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); - bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; - - if ( !pContextData ) // make sure allocated - { - pContextData = new CVRDistortTexture_DX9_Context; - *pContextDataPtr = pContextData; - } - - if ( pShaderShadow || bNeedRegenStaticCmds ) - { - pContextData->ResetStaticCmds(); - CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; - - staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); - staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); - - staticCmdsBuf.End(); - - // now, copy buf - pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; - memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); - } - - if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) - { - // need to regenerate the semistatic cmds - pContextData->m_SemiStaticCmdsOut.Reset(); - pContextData->m_bMaterialVarsChanged = false; - - pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); - pContextData->m_SemiStaticCmdsOut.End(); - } - - SHADOW_STATE - { - SetInitialShadowState( ); - - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableDepthTest( false ); - - pShaderShadow->EnableBlending( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - pShaderShadow->EnableSRGBWrite( true ); - pShaderShadow->EnableAlphaWrites( false ); - pShaderShadow->EnableAlphaTest( false ); - - DefaultFog(); - - int nFormat = 0; - nFormat |= VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); - - if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) - { - DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); - SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); - SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); - SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); - } - } - else - { - DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); - SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); - - DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); - SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); - } - } - - DYNAMIC_STATE - { - CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; - DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); - DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); - - pShaderAPI->SetDefaultState(); - - int useRenderTarget = ( params[ USERENDERTARGET ]->GetIntValue() == 0 ) ? 0 : 1; - - if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) - { - DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); - } - } - else - { - DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); - SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); - SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); - } - - DynamicCmdsOut.End(); - pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); - } - Draw(); - } -END_SHADER diff --git a/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc b/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc deleted file mode 100644 index 23ff3f5f..00000000 --- a/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc +++ /dev/null @@ -1,49 +0,0 @@ -// DYNAMIC: "CMBO_USERENDERTARGET" "0..1" - -#include "shader_constant_register_map.h" -#include "common_ps_fxc.h" - -sampler BaseTextureSampler : register( s0 ); -sampler DistortMapTextureSampler : register( s1 ); - - -struct PS_INPUT -{ - float2 vBaseTexCoord : TEXCOORD0; -}; - - -float4 main( PS_INPUT i ) : COLOR -{ - float2 vOriginal = i.vBaseTexCoord.xy; - - float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); - - float2 vGreen; - vGreen.r = ( vRead.x + vRead.z ) / 2.0; - vGreen.g = ( vRead.y + vRead.w ) / 2.0; - - float4 vFinal; - vFinal.r = tex2D( BaseTextureSampler, vRead.xy ).r; - vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; - vFinal.b = tex2D( BaseTextureSampler, vRead.zw ).b; - - float fBoundsCheck; - #if ( CMBO_USERENDERTARGET ) - { - fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.01,0.01)), float2(1,1)) + dot( (vGreen.xy > float2(0.99,0.99)), float2(1,1)) ); - } - #else - { - fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.005,0.005)), float2(1,1)) + dot( (vGreen.xy > float2(0.995,0.995)), float2(1,1)) - + (vGreen.x > 0.495 && vGreen.x < 0.505 ) ); - } - #endif - - vFinal.xyz = lerp( vFinal.xyz, float3(0,0,0), fBoundsCheck ); - - return vFinal; -} - - - diff --git a/materialsystem/stdshaders/vr_distort_texture_vs20.fxc b/materialsystem/stdshaders/vr_distort_texture_vs20.fxc deleted file mode 100644 index b82bfa13..00000000 --- a/materialsystem/stdshaders/vr_distort_texture_vs20.fxc +++ /dev/null @@ -1,26 +0,0 @@ -#include "common_vs_fxc.h" - - -struct VS_INPUT -{ - float4 vPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; - float2 vBaseTexCoord : TEXCOORD0; -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o; - - o.vProjPos = v.vPos; - o.vBaseTexCoord = v.vBaseTexCoord; - - return o; -} diff --git a/materialsystem/stdshaders/water.cpp b/materialsystem/stdshaders/water.cpp index 11353577..63236487 100644 --- a/materialsystem/stdshaders/water.cpp +++ b/materialsystem/stdshaders/water.cpp @@ -5,17 +5,14 @@ // $NoKeywords: $ //=============================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "mathlib/vmatrix.h" #include "common_hlsl_cpp_consts.h" // hack hack hack! #include "convar.h" - -#include "WaterCheap_vs20.inc" -#include "WaterCheap_ps20.inc" -#include "WaterCheap_ps20b.inc" -#include "Water_vs20.inc" -#include "Water_ps20.inc" -#include "water_ps20b.inc" +#include "sdk_watercheap_vs30.inc" +#include "sdk_watercheap_ps30.inc" +#include "sdk_water_vs30.inc" +#include "sdk_water_ps30.inc" #ifndef _X360 static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE ); @@ -23,8 +20,7 @@ static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR ) -BEGIN_VS_SHADER( Water_DX90, - "Help for Water" ) +BEGIN_VS_SHADER( Water_LDR, "Help for Water" ) BEGIN_SHADER_PARAMS SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" ) @@ -103,11 +99,7 @@ BEGIN_VS_SHADER( Water_DX90, // By default, we're force expensive on dx9. NO WE DON'T!!!! if( !params[FORCEEXPENSIVE]->IsDefined() ) { -#ifdef _X360 - params[FORCEEXPENSIVE]->SetIntValue( 0 ); -#else params[FORCEEXPENSIVE]->SetIntValue( 1 ); -#endif } if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) { @@ -129,10 +121,6 @@ BEGIN_VS_SHADER( Water_DX90, SHADER_FALLBACK { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "Water_DX81"; - } return 0; } @@ -151,6 +139,19 @@ BEGIN_VS_SHADER( Water_DX90, if ( params[ENVMAP]->IsDefined() ) { LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB ); + +#ifdef MAPBASE + if (mat_specular_disable_on_missing.GetBool()) + { + // Revert to defaultcubemap when the envmap texture is missing + // (should be equivalent to toolsblack in Mapbase) + if (params[ENVMAP]->GetTextureValue()->IsError()) + { + params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); + LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB ); + } + } +#endif } if ( params[NORMALMAP]->IsDefined() ) { @@ -236,37 +237,19 @@ BEGIN_VS_SHADER( Water_DX90, } } - DECLARE_STATIC_VERTEX_SHADER( water_vs20 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_water_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); - SET_STATIC_VERTEX_SHADER( water_vs20 ); - - // "REFLECT" "0..1" - // "REFRACT" "0..1" + SET_STATIC_VERTEX_SHADER( sdk_water_vs30 ); - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( water_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); - SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); - SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER( water_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( water_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); - SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); - SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); - SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER( water_ps20 ); - } + DECLARE_STATIC_PIXEL_SHADER( sdk_water_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER( sdk_water_ps30 ); FogToFogColor(); @@ -368,22 +351,18 @@ BEGIN_VS_SHADER( Water_DX90, pShaderAPI->SetPixelShaderFogParams( 8 ); - DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( water_vs20 ); + float vEyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + vEyePos[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 9, vEyePos ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_water_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_water_vs30 ); - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); - SET_DYNAMIC_PIXEL_SHADER( water_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( water_ps20 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_water_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_water_ps30 ); } Draw(); } @@ -430,36 +409,19 @@ BEGIN_VS_SHADER( Water_DX90, } } - DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_watercheap_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction ); - SET_STATIC_VERTEX_SHADER( watercheap_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_watercheap_vs30 ); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); - SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); - Vector4D Scroll1; - params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); - SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER( watercheap_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); - SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); - SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); - SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); - Vector4D Scroll1; - params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); - SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); - SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); - SET_STATIC_PIXEL_SHADER( watercheap_ps20 ); - } + DECLARE_STATIC_PIXEL_SHADER( sdk_watercheap_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER( sdk_watercheap_ps30 ); // HDRFIXME: test cheap water! if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) @@ -488,13 +450,18 @@ BEGIN_VS_SHADER( Water_DX90, float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); float cheapWaterParams[4] = { - (float)(cheapWaterStartDistance * VSHADER_VECT_SCALE), - (float)(cheapWaterEndDistance * VSHADER_VECT_SCALE), - (float)(PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance )), + cheapWaterStartDistance * VSHADER_VECT_SCALE, + cheapWaterEndDistance * VSHADER_VECT_SCALE, + PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ), cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ), }; pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams ); + float vEyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + vEyePos[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 4, vEyePos ); + if( g_pConfig->bShowSpecular ) { SetPixelShaderConstant( 2, REFLECTTINT, REFLECTBLENDFACTOR ); @@ -521,36 +488,20 @@ BEGIN_VS_SHADER( Water_DX90, pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); } - DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_watercheap_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_watercheap_vs30 ); - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); - } + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_watercheap_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_watercheap_ps30 ); } Draw(); } SHADER_DRAW { - // TODO: fit the cheap water stuff into the water shader so that we don't have to do - // 2 passes. -#ifdef _X360 - bool bForceExpensive = false; -#else bool bForceExpensive = r_waterforceexpensive.GetBool(); -#endif bool bForceCheap = (params[FORCECHEAP]->GetIntValue() != 0) || UsingEditor( params ); if ( bForceCheap ) { @@ -563,11 +514,7 @@ BEGIN_VS_SHADER( Water_DX90, Assert( !( bForceCheap && bForceExpensive ) ); bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); -#ifdef _X360 - bool bReflection = params[REFLECTTEXTURE]->IsTexture(); -#else bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); -#endif bool bDrewSomething = false; if ( !bForceCheap && ( bReflection || bRefraction ) ) { @@ -575,13 +522,7 @@ BEGIN_VS_SHADER( Water_DX90, DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); } - // Use $decal to see if we are a decal or not. . if we are, then don't bother - // drawing the cheap version for now since we don't have access to env_cubemap -#ifdef _X360 - if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bForceExpensive ) -#else if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) -#endif { bDrewSomething = true; DrawCheapWater( params, pShaderShadow, pShaderAPI, !bForceCheap, bRefraction ); @@ -599,14 +540,13 @@ END_SHADER //----------------------------------------------------------------------------- // This allows us to use a block labelled 'Water_DX9_HDR' in the water materials //----------------------------------------------------------------------------- -BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90, - "Help for Water_DX9_HDR" ) +BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water, "Help for Water_DX9_HDR" ) SHADER_FALLBACK { - if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + if ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) { - return "WATER_DX90"; + return "Water_LDR"; } return 0; } diff --git a/materialsystem/stdshaders/water_dudv.cpp b/materialsystem/stdshaders/water_dudv.cpp deleted file mode 100644 index cf29c183..00000000 --- a/materialsystem/stdshaders/water_dudv.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - - -#include "BaseVSShader.h" - -#include "waterdudv_vs11.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER( Water_DuDv, "Help for Water_DuDv" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) - SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - if ( params[BUMPMAP]->IsDefined() ) - { - LoadTexture( BUMPMAP ); - } - if( !params[REFRACTTINT]->IsDefined() ) - { - params[REFRACTTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableColorWrites( true ); - pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); - int fmt = VERTEX_POSITION | VERTEX_NORMAL; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0, 0 ); - - pShaderShadow->SetVertexShader( "WaterDuDv_vs11", 0 ); - pShaderShadow->SetPixelShader( "WaterDuDv_ps11", 0 ); - DisableFog(); - } - DYNAMIC_STATE - { - waterdudv_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetDOFOG( pShaderAPI->GetSceneFogMode() != MATERIAL_FOG_NONE ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - - Vector4D vec; - const float *pTint = params[REFRACTTINT]->GetVecValue(); - float flAverage = ( pTint[0] + pTint[1] + pTint[2] ) / 3.0f; - vec.Init( flAverage, flAverage, flAverage, 1.0f ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vec.Base() ); - - // Amount to refract - SetPixelShaderConstant( 0, REFRACTAMOUNT ); - - // Used to renormalize - vec.Init( 1.0f, 1.0f, 1.0f, 1.0f ); - pShaderAPI->SetPixelShaderConstant( 1, vec.Base() ); - - // Used to deal with the red channel - vec.Init( 0.0f, 1.0f, 1.0f, 1.0f ); - pShaderAPI->SetPixelShaderConstant( 2, vec.Base() ); - - vec.Init( 1.0f, 0.0f, 0.0f, 0.0f ); - pShaderAPI->SetPixelShaderConstant( 3, vec.Base() ); - - BindTexture( SHADER_TEXTURE_STAGE0, BUMPMAP, BUMPFRAME ); - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/water_dx60.cpp b/materialsystem/stdshaders/water_dx60.cpp deleted file mode 100644 index b6c952b3..00000000 --- a/materialsystem/stdshaders/water_dx60.cpp +++ /dev/null @@ -1,15 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// NOTE: Water DX60 is located in LightmappedGeneric_DX6 so it can inherit -DEFINE_FALLBACK_SHADER( Water, Water_DX60 ) - diff --git a/materialsystem/stdshaders/water_dx80.cpp b/materialsystem/stdshaders/water_dx80.cpp deleted file mode 100644 index 2f31bb5b..00000000 --- a/materialsystem/stdshaders/water_dx80.cpp +++ /dev/null @@ -1,419 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" - -#include "water_vs11.inc" -#include "watercheappervertexfresnel_vs11.inc" -#include "watercheap_vs11.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_VS_SHADER( Water_DX80, - "Help for Water_DX80" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) - SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) - SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) - SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) - SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) - SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) - SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) - SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) - SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) - SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) - SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) - SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) - SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) - { - params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); - } - if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) - { - params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); - } - if( !params[SCALE]->IsDefined() ) - { - params[SCALE]->SetVecValue( 1.0f, 1.0f ); - } - if( !params[FOGCOLOR]->IsDefined() ) - { - params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); - Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); - } - if( !params[REFLECTENTITIES]->IsDefined() ) - { - params[REFLECTENTITIES]->SetIntValue( 0 ); - } - if( !params[FORCEEXPENSIVE]->IsDefined() ) - { - params[FORCEEXPENSIVE]->SetIntValue( 0 ); - } - if( !params[REFLECTBLENDFACTOR]->IsDefined() ) - { - params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); - } - if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) - { - params[FORCEEXPENSIVE]->SetIntValue( 0 ); - } - } - - SHADER_FALLBACK - { - if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) ) - { - return "Water_DX60"; - } - return 0; - } - - SHADER_INIT - { - Assert( params[WATERDEPTH]->IsDefined() ); - if( params[REFRACTTEXTURE]->IsDefined() ) - { - LoadTexture( REFRACTTEXTURE ); - } - if( params[REFLECTTEXTURE]->IsDefined() ) - { - LoadTexture( REFLECTTEXTURE ); - } - if (params[BUMPMAP]->IsDefined() ) - { - LoadTexture( BUMPMAP ); - } - if (params[ENVMAP]->IsDefined() ) - { - LoadCubeMap( ENVMAP ); - } - if (params[NORMALMAP]->IsDefined() ) - { - LoadBumpMap( NORMALMAP ); - } - } - - inline void SetCheapWaterFactors( IMaterialVar **params, IShaderDynamicAPI* pShaderAPI, int nConstantReg ) - { - float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); - float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); - float flCheapWaterConstants[4] = - { - flCheapWaterStartDistance, - 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ), - 0.0f, - 0.0f - }; - pShaderAPI->SetVertexShaderConstant( nConstantReg, flCheapWaterConstants ); - } - - inline void DrawReflection( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI, bool bBlendReflection ) - { - SHADOW_STATE - { - SetInitialShadowState( ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - if( bBlendReflection ) - { - EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - - water_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WaterReflect_ps11", 0 ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); - - float fReflectionAmount = params[REFLECTAMOUNT]->GetFloatValue(); - pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fReflectionAmount, 0.0f, 0.0f, fReflectionAmount ); - - BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); - BindTexture( SHADER_SAMPLER1, REFLECTTEXTURE, -1 ); - BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); - pShaderAPI->SetVertexShaderIndex( 0 ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - - // used to invert y - float c[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); - - SetPixelShaderConstant( 0, REFLECTTINT ); - - water_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - inline void DrawRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - water_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WaterRefract_ps11", 0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); - float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); - pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); - BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); - BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - - // used to invert y - float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); - - SetPixelShaderConstant( 0, REFRACTTINT ); - - water_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - inline void DrawRefractionForFresnel( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI ) - { - SHADOW_STATE - { - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - water_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WaterRefractFresnel_ps11", 0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); - float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); - pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); - BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); - BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); - BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); - - // used to invert y - float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); - - SetPixelShaderConstant( 0, REFRACTTINT ); - - water_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bBlendFresnel, bool bNoPerVertexFresnel ) - { - SHADOW_STATE - { - SetInitialShadowState( ); - - // In edit mode, use nocull - if ( UsingEditor( params ) ) - { - s_pShaderShadow->EnableCulling( false ); - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if( bBlend ) - { - if ( bBlendFresnel ) - { - EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE_MINUS_DST_ALPHA ); - } - else - { - EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - } - - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | - VERTEX_TANGENT_T, 1, 0, 0 ); - - if( bNoPerVertexFresnel ) - { - watercheap_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WaterCheap_vs11", vshIndex.GetIndex() ); - } - else - { - watercheappervertexfresnel_vs11_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WaterCheapPerVertexFresnel_vs11", vshIndex.GetIndex() ); - } - - static const char *s_pPixelShaderName[] = - { - "WaterCheapOpaque_ps11", - "WaterCheap_ps11", - "WaterCheapNoFresnelOpaque_ps11", - "WaterCheapNoFresnel_ps11", - }; - - int nPshIndex = 0; - if ( bBlend ) nPshIndex |= 0x1; - if ( bNoPerVertexFresnel ) nPshIndex |= 0x2; - pShaderShadow->SetPixelShader( s_pPixelShaderName[nPshIndex] ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); - BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); - - if( bBlend && !bBlendFresnel ) - { - SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 ); - } - else - { - float flCheapWaterConstants[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flCheapWaterConstants ); - } - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); - - SetPixelShaderConstant( 0, FOGCOLOR ); - SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); - - if( bNoPerVertexFresnel ) - { - watercheap_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - watercheappervertexfresnel_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - Draw(); - } - - SHADER_DRAW - { - // NOTE: Here's what all this means. - // 1) ForceCheap means use env_cubemap only - // 2) ForceExpensive means do real reflection instead of env_cubemap. - // By default, it will do refraction and use env_cubemap for the reflection. - // If dest alpha is available, it will also use dest alpha for a fresnel term. - // otherwise there will be no fresnel term as it looks bizzare. - - bool bBlendReflection = false; - bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); - bool bForceExpensive = !bForceCheap && (params[FORCEEXPENSIVE]->GetIntValue() != 0); - bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); - bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); - bool bReflectionUseFresnel = false; - - // Can't do fresnel when forcing cheap or if there's no refraction - if( !bForceCheap ) - { - if( bRefraction ) - { - // NOTE: Expensive reflection does the fresnel correctly per-pixel - if ( g_pHardwareConfig->HasDestAlphaBuffer() && !bReflection && !params[NOFRESNEL]->GetIntValue() ) - { - DrawRefractionForFresnel( params, pShaderShadow, pShaderAPI ); - bReflectionUseFresnel = true; - } - else - { - DrawRefraction( params, pShaderShadow, pShaderAPI ); - } - bBlendReflection = true; - } - if( bReflection ) - { - DrawReflection( params, pShaderShadow, pShaderAPI, bBlendReflection ); - } - } - - // Use $decal to see if we are a decal or not. . if we are, then don't bother - // drawing the cheap version for now since we don't have access to env_cubemap - if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) - { - bool bNoPerVertexFresnel = ( params[NOFRESNEL]->GetIntValue() || bReflectionUseFresnel || bForceCheap || !bRefraction ); - DrawCheapWater( params, pShaderShadow, pShaderAPI, bBlendReflection, bReflectionUseFresnel, bNoPerVertexFresnel ); - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/water_dx81.cpp b/materialsystem/stdshaders/water_dx81.cpp deleted file mode 100644 index 764ffe9e..00000000 --- a/materialsystem/stdshaders/water_dx81.cpp +++ /dev/null @@ -1,311 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" - -#include "water_ps14.inc" -#include "watercheap_vs14.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Water, Water_DX81 ) - -BEGIN_VS_SHADER( Water_DX81, - "Help for Water_DX81" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) - SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) - SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) - SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) - SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) - SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) - SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) - SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) - SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) - SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) - SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) - SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) - SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) - SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); - if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) - { - params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); - } - if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) - { - params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); - } - if( !params[SCALE]->IsDefined() ) - { - params[SCALE]->SetVecValue( 1.0f, 1.0f ); - } - if( !params[FOGCOLOR]->IsDefined() ) - { - params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); - Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); - } - if( !params[REFLECTENTITIES]->IsDefined() ) - { - params[REFLECTENTITIES]->SetIntValue( 0 ); - } - if( !params[FORCEEXPENSIVE]->IsDefined() ) - { - params[FORCEEXPENSIVE]->SetIntValue( 0 ); - } - if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) - { - params[FORCEEXPENSIVE]->SetIntValue( 0 ); - } - if( !params[REFLECTBLENDFACTOR]->IsDefined() ) - { - params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); - } - if( !params[FORCEEXPENSIVE]->GetIntValue() && !params[ENVMAP]->IsDefined() ) - { - params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); - } - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 81 ) - { - return "Water_DX80"; - } - return 0; - } - - SHADER_INIT - { - Assert( params[WATERDEPTH]->IsDefined() ); - if( params[REFRACTTEXTURE]->IsDefined() ) - { - LoadTexture( REFRACTTEXTURE ); - } - if( params[REFLECTTEXTURE]->IsDefined() ) - { - LoadTexture( REFLECTTEXTURE ); - } - if (params[ENVMAP]->IsDefined() ) - { - LoadTexture( ENVMAP ); - } - if (params[NORMALMAP]->IsDefined() ) - { - LoadBumpMap( NORMALMAP ); - } - } - - inline int GetReflectionRefractionPixelShaderIndex( bool bReflection, bool bRefraction ) - { - // "REFLECT" "0..1" - // "REFRACT" "0..1" - int pshIndex = ( bReflection ? 1 : 0 ) | ( bRefraction ? 2 : 0 ); - return pshIndex; - } - - inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) - { - SHADOW_STATE - { - SetInitialShadowState( ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if( bRefraction ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - } - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if( bReflection ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - } - int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - water_ps14_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "Water_ps14", vshIndex.GetIndex() ); - - int pshIndex = GetReflectionRefractionPixelShaderIndex( bReflection, bRefraction ); - pShaderShadow->SetPixelShader ( "Water_ps14", pshIndex ); - FogToFogColor(); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_NORMALIZATION_CUBEMAP ); - if( bRefraction ) - { - BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); - } - BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); - if( bReflection ) - { - BindTexture( SHADER_SAMPLER4, REFLECTTEXTURE, -1 ); - } - - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, REFLECTAMOUNT ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); - SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, REFRACTAMOUNT ); - - float c0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); - - SetPixelShaderConstant( 1, REFRACTTINT ); - SetPixelShaderConstant( 4, REFLECTTINT ); - - float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; - pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); - - // ERASE ME! - float c3[4] = { 5.0f, 0.0f, 0.0f, 0.0f }; - pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); - - // reflection/refraction scale - float reflectionRefractionScale[4] = { params[REFLECTAMOUNT]->GetFloatValue(), - params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f }; - pShaderAPI->SetPixelShaderConstant( 5, reflectionRefractionScale, 1 ); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, reflectionRefractionScale, 1 ); - - water_ps14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - enum DrawCheapType_t - { - DRAW_CHEAP_OPAQUE = 0, - DRAW_CHEAP_FRESNEL_OPAQUE, - DRAW_CHEAP_LOD_ONLY, - DRAW_CHEAP_FRESNEL_AND_LOD, - }; - - inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, - IShaderDynamicAPI* pShaderAPI, DrawCheapType_t type ) - { - SHADOW_STATE - { - SetInitialShadowState( ); - - // In edit mode, use nocull - if ( UsingEditor( params ) ) - { - s_pShaderShadow->EnableCulling( false ); - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) - { - EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | - VERTEX_TANGENT_T, 1, 0, 0 ); - - watercheap_vs14_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WaterCheap_vs14", vshIndex.GetIndex() ); - - static const char *s_pPixelShader[] = - { - "WaterCheapOpaque_ps14", - "WaterCheapFresnelOpaque_ps14", - "WaterCheap_ps14", - "WaterCheapFresnel_ps14", - }; - - pShaderShadow->SetPixelShader( s_pPixelShader[type] ); - FogToFogColor(); - } - DYNAMIC_STATE - { - pShaderAPI->SetDefaultState(); - BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); - BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); - - float pCheapWaterConstants[4] = { 0, 0, 0, 0 }; - if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) - { - float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); - float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); - pCheapWaterConstants[0] = flCheapWaterStartDistance; - pCheapWaterConstants[1] = 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ); - } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, pCheapWaterConstants ); - - SetPixelShaderConstant( 0, FOGCOLOR ); - SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); - - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); - - watercheap_vs14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); - } - - SHADER_DRAW - { - // NOTE: Here's what all this means. - // 1) ForceCheap means use env_cubemap only - // 2) ForceExpensive means do real reflection instead of env_cubemap. - // By default, it will do refraction and use env_cubemap for the reflection. - - // Also, it will fade to cheap water at a particular distance, - // based on CheapWaterStartDistance and CheapWaterEndDistance - // * In the ForceCheap case, no fading is required - // * In the default case, it will fade based on these parameters in a single pass - // * In the expensive case, it will have to perform the fade in a separate pass. - - bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); - bool bForceExpensive = params[FORCEEXPENSIVE]->GetIntValue() != 0; - bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); - bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); - DrawCheapType_t type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_OPAQUE : DRAW_CHEAP_FRESNEL_OPAQUE; - if( !bForceCheap && (bRefraction || bReflection) ) - { - DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); - if ( !bReflection ) - { - type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_LOD_ONLY : DRAW_CHEAP_FRESNEL_AND_LOD; - } - else - { - type = DRAW_CHEAP_LOD_ONLY; - } - } - - // Use $decal to see if we are a decal or not. . if we are, then don't bother - // drawing the cheap version for now since we don't have access to env_cubemap - if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bReflection ) - { - DrawCheapWater( params, pShaderShadow, pShaderAPI, type ); - } - } -END_SHADER - diff --git a/materialsystem/stdshaders/water_ps2x.fxc b/materialsystem/stdshaders/water_ps2x.fxc deleted file mode 100644 index a80a8a15..00000000 --- a/materialsystem/stdshaders/water_ps2x.fxc +++ /dev/null @@ -1,110 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b] [= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "BASETEXTURE" "0..1" -// STATIC: "MULTITEXTURE" "0..1" -// STATIC: "REFLECT" "0..1" -// STATIC: "REFRACT" "0..1" -// STATIC: "ABOVEWATER" "0..1" -// STATIC: "BLURRY_REFRACT" "0..1" [ps20b] - -// When we turn NORMAL_DECODE_MODE on, this shader only needs 0..1, not 0..2 -// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] -// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] - -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] - -// SKIP: $MULTITEXTURE && $BASETEXTURE - -#if defined(SHADER_MODEL_PS_2_0) -# define BLURRY_REFRACT 0 -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - -#include "water_ps2x_helper.h" - - -sampler RefractSampler : register( s0 ); -#if BASETEXTURE -sampler BaseTextureSampler : register( s1 ); -#endif -sampler ReflectSampler : register( s2 ); -#if BASETEXTURE -sampler LightmapSampler : register( s3 ); -#endif -sampler NormalSampler : register( s4 ); - -const HALF4 vRefractTint : register( c1 ); -const HALF4 vReflectTint : register( c4 ); -const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale -const HALF4 g_WaterFogColor : register( c6 ); -const HALF4 g_WaterFogParams : register( c7 ); - -const float4 g_PixelFogParams : register( c8 ); - - -#define g_WaterFogStart g_WaterFogParams.x -#define g_WaterFogEndMinusStart g_WaterFogParams.y -#define g_Reflect_OverBright g_WaterFogParams.z - -struct PS_INPUT -{ - float2 vBumpTexCoord : TEXCOORD0; - half3 vTangentEyeVect : TEXCOORD1; - float4 vReflectXY_vRefractYX : TEXCOORD2; - float W : TEXCOORD3; - float4 vProjPos : TEXCOORD4; - float screenCoord : TEXCOORD5; -#if MULTITEXTURE - float4 vExtraBumpTexCoord : TEXCOORD6; -#endif -#if BASETEXTURE -// CENTROID: TEXCOORD6 - HALF4 lightmapTexCoord1And2 : TEXCOORD6; -// CENTROID: TEXCOORD7 - HALF4 lightmapTexCoord3 : TEXCOORD7; -#endif - - float4 fogFactorW : COLOR1; -}; - -float4 main( PS_INPUT i ) : COLOR -{ - DrawWater_params_t params; - - params.vBumpTexCoord = i.vBumpTexCoord; -#if MULTITEXTURE - params.vExtraBumpTexCoord = i.vExtraBumpTexCoord; -#endif - params.vReflectXY_vRefractYX = i.vReflectXY_vRefractYX; - params.w = i.W; - params.vReflectRefractScale = g_ReflectRefractScale; - params.fReflectOverbright = g_Reflect_OverBright; - params.vReflectTint = vReflectTint; - params.vRefractTint = vRefractTint; - params.vTangentEyeVect = i.vTangentEyeVect; - params.waterFogColor = g_WaterFogColor; -#if BASETEXTURE - params.lightmapTexCoord1And2 = i.lightmapTexCoord1And2; - params.lightmapTexCoord3 = i.lightmapTexCoord3; -#endif - params.vProjPos = i.vProjPos; - params.pixelFogParams = g_PixelFogParams; - params.fWaterFogStart = g_WaterFogStart; - params.fWaterFogEndMinusStart = g_WaterFogEndMinusStart; - - float4 result; - float fogFactor; - DrawWater( params, - // yay. . can't put sampler in a struct. -#if BASETEXTURE - BaseTextureSampler, - LightmapSampler, -#endif - NormalSampler, RefractSampler, ReflectSampler, - result, fogFactor ); - - return FinalOutput( float4( result.rgb, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); -} - diff --git a/materialsystem/stdshaders/water_ps2x_helper.h b/materialsystem/stdshaders/water_ps2x_helper.h deleted file mode 100644 index b15b9986..00000000 --- a/materialsystem/stdshaders/water_ps2x_helper.h +++ /dev/null @@ -1,239 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -#include "common_ps_fxc.h" - -struct DrawWater_params_t -{ - float2 vBumpTexCoord; -#if MULTITEXTURE - float4 vExtraBumpTexCoord; -#endif - float4 vReflectXY_vRefractYX; - float w; - float4 vReflectRefractScale; - float fReflectOverbright; - float4 vReflectTint; - float4 vRefractTint; - half3 vTangentEyeVect; - float4 waterFogColor; -#if BASETEXTURE - HALF4 lightmapTexCoord1And2; - HALF4 lightmapTexCoord3; -#endif - float4 vProjPos; - float4 pixelFogParams; - float fWaterFogStart; - float fWaterFogEndMinusStart; -}; - -void DrawWater( in DrawWater_params_t i, -#if BASETEXTURE - in sampler BaseTextureSampler, - in sampler LightmapSampler, -#endif - in sampler NormalSampler, - in sampler RefractSampler, - in sampler ReflectSampler, - out float4 result, out float fogFactor ) -{ - bool bReflect = REFLECT ? true : false; - bool bRefract = REFRACT ? true : false; - -#if MULTITEXTURE - float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord ); - float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy ); - float4 vNormal2 = tex2D( NormalSampler, i.vExtraBumpTexCoord.zw ); - vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); - -#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) - vNormal.xy = vNormal.xy * 2.0f - 1.0f; - vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); - vNormal.a = 1.0f; -#else - vNormal.xyz = 2.0 * vNormal.xyz - 1.0; -#endif - -#else - float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORMAL_DECODE_MODE ); -#endif - - // Perform division by W only once - float ooW = 1.0f / i.w; - - float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; - -#if ABOVEWATER - float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; -#else - // We don't actually have valid depth values in alpha when we are underwater looking out, so - // just set to farthest value. - float waterFogDepthValue = 1.0f; -#endif - float4 reflectRefractScale = i.vReflectRefractScale; -#if !BASETEXTURE -#if ( BLURRY_REFRACT == 0 ) - reflectRefractScale *= waterFogDepthValue; -#endif -#endif - - // Compute coordinates for sampling Reflection - float2 vReflectTexCoord; - float2 vRefractTexCoord; - - // vectorize the dependent UV calculations (reflect = .xy, refract = .wz) - float4 vN; - vN.xy = vNormal.xy; - vN.w = vNormal.x; - vN.z = vNormal.y; - float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale; - - vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); - vReflectTexCoord = vDependentTexCoords.xy; - vRefractTexCoord = vDependentTexCoords.wz; - - HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); -#if BLURRY_REFRACT - // Sample reflection and refraction - float2 ddx1=float2(0.005,0); - float2 ddy1=float2(0,0.005); - float4 vRefractColor=float4(0,0,0,0); - -#if 0 - float sumweights=0; - for(int ix=-2;ix<=2;ix++) - { - for(int iy=-2;iy<=2;iy++) - { - float weight=1; ///(1+abs(ix)+abs(iy)); - vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1); - sumweights+=weight; - } - } -#else - // NOTE: Generated by genwaterloop.pl in the stdshaders directory. - // Need to unroll for 360 to avoid shader compilation problems. - // Modified genwaterloop.pl and regenerate if you need different params - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 ); - vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 ); - float sumweights = 25; - // NOTE: end of generated code. -#endif - - vRefractColor *= (1.0/sumweights); - vReflectColor *= i.fReflectOverbright; - vReflectColor *= i.vReflectTint; - vRefractColor *= i.vRefractTint; -# if ABOVEWATER - // Don't mess with this in the underwater case since we don't really have - // depth values there. - // get the blurred depth value to be used for fog. - waterFogDepthValue = vRefractColor.a; -# endif -#else - vReflectColor *= i.vReflectTint; - HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); - // get the depth value from the refracted sample to be used for fog. -# if ABOVEWATER - // Don't mess with this in the underwater case since we don't really have - // depth values there. - waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a; -# endif -#endif - - half3 vEyeVect; - vEyeVect = normalize( i.vTangentEyeVect ); - - // Fresnel term - HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); - HALF fFresnel = pow( 1.0 - fNdotV, 5 ); - -#if !BASETEXTURE - // fFresnel == 1.0f means full reflection - fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f ); -#endif - - - // blend between refraction and fog color. -#if ABOVEWATER - vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) ); -#else - float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart ); - vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor ); -#endif - -#if BASETEXTURE - float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy ); - HALF2 bumpCoord1; - HALF2 bumpCoord2; - HALF2 bumpCoord3; - ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, - bumpCoord1, bumpCoord2, bumpCoord3 ); - - HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); - HALF3 lightmapColor1 = lightmapSample1.rgb; - HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); - HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); - - float3 dp; - dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); - dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); - dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); - dp *= dp; - - float3 diffuseLighting = dp.x * lightmapColor1 + - dp.y * lightmapColor2 + - dp.z * lightmapColor3; - float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); - diffuseLighting *= LIGHT_MAP_SCALE / sum; - HALF3 diffuseComponent = baseSample.rgb * diffuseLighting; -#endif - - if( bReflect && bRefract ) - { - result = lerp( vRefractColor, vReflectColor, fFresnel ); - } - else if( bReflect ) - { -#if BASETEXTURE - result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a; -#else - result = vReflectColor; -#endif - } - else if( bRefract ) - { - result = vRefractColor; - } - else - { - result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); - } - -#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) - fogFactor = CalcRangeFog( i.vProjPos.z, i.pixelFogParams.x, i.pixelFogParams.z, i.pixelFogParams.w ); -#else - fogFactor = 0; -#endif -} diff --git a/materialsystem/stdshaders/waterreflect_ps14.psh b/materialsystem/stdshaders/waterreflect_ps14.psh deleted file mode 100644 index 4d277b1e..00000000 --- a/materialsystem/stdshaders/waterreflect_ps14.psh +++ /dev/null @@ -1,8 +0,0 @@ -ps.1.4 - -texld r0, t0_dw.xyw ; sample dudv map - -phase - -texld r0, t0 - diff --git a/materialsystem/stdshaders/waterrefract_ps14.psh b/materialsystem/stdshaders/waterrefract_ps14.psh deleted file mode 100644 index 8d63934d..00000000 --- a/materialsystem/stdshaders/waterrefract_ps14.psh +++ /dev/null @@ -1,23 +0,0 @@ -ps.1.4 - -; non-fresnel version -; t0: -; texture: dudv map -; texcoords: coords for normal map -; t1: -; texcoords: uvw for first dp3 -; t2: -; texture: renderable texture that we are going to perturb -; texcoords: uvw for second dp3 -;tex t0 ; sample dudv map -;texm3x2pad t1, t0 ; -;texm3x2tex t2, t0 ; sample renderabletexture - -;mul r0, t2, c1 - - -texld r0, t0 ; sample dudv map - -phase - -texld r0, t2_dw.xyw diff --git a/materialsystem/stdshaders/white_ps2x.fxc b/materialsystem/stdshaders/white_ps2x.fxc deleted file mode 100644 index 0c971ef1..00000000 --- a/materialsystem/stdshaders/white_ps2x.fxc +++ /dev/null @@ -1,12 +0,0 @@ -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] - -#include "common_ps_fxc.h" - -struct PS_INPUT -{ -}; - -HALF4 main( PS_INPUT i ) : COLOR -{ - return FinalOutput( float4( 1.0f, 1.0f, 1.0f, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); -} diff --git a/materialsystem/stdshaders/windowimposter.cpp b/materialsystem/stdshaders/windowimposter.cpp new file mode 100644 index 00000000..3db30da6 --- /dev/null +++ b/materialsystem/stdshaders/windowimposter.cpp @@ -0,0 +1,156 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "basevsshader.h" +#include "cpp_shader_constant_register_map.h" +#include "sdk_windowimposter_vs30.inc" +#include "sdk_windowimposter_ps30.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +BEGIN_VS_SHADER( WindowImposter, "Help for WindowImposter" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + +#ifdef MAPBASE + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) +#endif + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + SHADER_PARAM( ENVMAPPARALLAX, SHADER_PARAM_TYPE_BOOL, "0", "Enables parallax correction code for env_cubemaps" ) + SHADER_PARAM( ENVMAPPARALLAXOBB1, SHADER_PARAM_TYPE_VEC4, "[1 0 0 0]", "The first line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB2, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "The second line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPPARALLAXOBB3, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "The third line of the parallax correction OBB matrix" ) + SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" ) +#endif + END_SHADER_PARAMS + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { +#ifdef MAPBASE + if( !params[ENVMAPFRAME]->IsDefined() ) + params[ENVMAPFRAME]->SetIntValue( 0 ); +#endif + } + + SHADER_FALLBACK + { + return NULL; + } + + SHADER_INIT + { + LoadCubeMap( ENVMAP ); +#ifdef MAPBASE + if (mat_specular_disable_on_missing.GetBool()) + { + // Revert to defaultcubemap when the envmap texture is missing + // (should be equivalent to toolsblack in Mapbase) + if (params[ENVMAP]->GetTextureValue()->IsError()) + { + params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); + LoadCubeMap( ENVMAP ); + } + } +#endif + } + + SHADER_DRAW + { +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + bool hasParallaxCorrection = params[ENVMAPPARALLAX]->GetIntValue() > 0; +#else + bool hasParallaxCorrection = false; +#endif + + SHADOW_STATE + { + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_windowimposter_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection ); // Parallax cubemaps enabled for 2_0b and onwards + SET_STATIC_VERTEX_SHADER( sdk_windowimposter_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_windowimposter_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection ); // Parallax cubemaps enabled for 2_0b and onwards + SET_STATIC_PIXEL_SHADER( sdk_windowimposter_ps30 ); + + unsigned int flags = VERTEX_POSITION; + int nTexCoordCount = 2; + + if (hasParallaxCorrection) + { + flags |= VERTEX_NORMAL; + nTexCoordCount++; + } + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, 0, 0 ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableDepthWrites( false ); + FogToFogColor(); + } + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_windowimposter_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_windowimposter_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_windowimposter_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_windowimposter_ps30 ); + + SetModulationVertexShaderDynamicState(); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemaps + if (hasParallaxCorrection) + { + pShaderAPI->SetPixelShaderConstant( 0, params[ENVMAPORIGIN]->GetVecValue() ); + + float* vecs[3]; + vecs[0] = const_cast(params[ENVMAPPARALLAXOBB1]->GetVecValue()); + vecs[1] = const_cast(params[ENVMAPPARALLAXOBB2]->GetVecValue()); + vecs[2] = const_cast(params[ENVMAPPARALLAXOBB3]->GetVecValue()); + float matrix[4][4]; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + matrix[i][j] = vecs[i][j]; + } + } + matrix[3][0] = matrix[3][1] = matrix[3][2] = 0; + matrix[3][3] = 1; + pShaderAPI->SetPixelShaderConstant( 1, &matrix[0][0], 4 ); + } +#endif + +#ifdef MAPBASE + BindTexture( SHADER_SAMPLER0, ENVMAP, ENVMAPFRAME ); +#else + BindTexture( SHADER_SAMPLER0, ENVMAP, -1 ); +#endif + } + Draw(); + } + +END_SHADER diff --git a/materialsystem/stdshaders/wireframe_dx9.cpp b/materialsystem/stdshaders/wireframe_dx9.cpp deleted file mode 100644 index d55c5c34..00000000 --- a/materialsystem/stdshaders/wireframe_dx9.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=====================================================================================// - -#include "BaseVSShader.h" -#include "vertexlitgeneric_dx9_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( Wireframe, Wireframe_DX9 ) - -BEGIN_VS_SHADER( Wireframe_DX9, - "Help for Wireframe_DX9" ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "Wireframe_DX8"; - } - return 0; - } - - SHADER_INIT_PARAMS() - { - VertexLitGeneric_DX9_Vars_t vars; - InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, false, vars ); - - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - SET_FLAGS( MATERIAL_VAR_NOFOG ); - SET_FLAGS( MATERIAL_VAR_WIREFRAME ); - } - - SHADER_INIT - { - VertexLitGeneric_DX9_Vars_t vars; - InitVertexLitGeneric_DX9( this, params, false, vars ); - } - - SHADER_DRAW - { - VertexLitGeneric_DX9_Vars_t vars; - DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, false, vars, vertexCompression, pContextDataPtr ); - } -END_SHADER - diff --git a/materialsystem/stdshaders/worldtwotextureblend.cpp b/materialsystem/stdshaders/worldtwotextureblend.cpp index 542013e0..b2f1f1ef 100644 --- a/materialsystem/stdshaders/worldtwotextureblend.cpp +++ b/materialsystem/stdshaders/worldtwotextureblend.cpp @@ -6,13 +6,12 @@ // $NoKeywords: $ //===========================================================================// -#include "BaseVSShader.h" +#include "basevsshader.h" #include "convar.h" -#include "lightmappedgeneric_vs20.inc" -#include "WorldTwoTextureBlend_ps20.inc" -#include "WorldTwoTextureBlend_ps20b.inc" +#include "sdk_lightmappedgeneric_vs30.inc" +#include "sdk_worldtwotextureblend_ps30.inc" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -20,8 +19,7 @@ extern ConVar r_flashlight_version2; // FIXME: Need to make a dx9 version so that "CENTROID" works. -BEGIN_VS_SHADER( WorldTwoTextureBlend, - "Help for WorldTwoTextureBlend" ) +BEGIN_VS_SHADER( WorldTwoTextureBlend, "Help for WorldTwoTextureBlend" ) BEGIN_SHADER_PARAMS SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) @@ -246,7 +244,7 @@ END_SHADER_PARAMS pShaderShadow->EnableSRGBWrite( true ); - DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, hasFlashlight ); @@ -254,40 +252,26 @@ END_SHADER_PARAMS SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); - SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, 0 ); //( bumpmap_variant == 2 )?1:0); SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); //( bumpmap_variant == 2 )?1:0); #ifdef _X360 SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); #endif - SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); - SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); - SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); - SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); - SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); - SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); - SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); - } +#ifdef MAPBASE + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURETRANSFORM2, false ); +#endif + SET_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( sdk_worldtwotextureblend_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( sdk_worldtwotextureblend_ps30 ); // HACK HACK HACK - enable alpha writes all the time so that we have them for // underwater stuff. @@ -387,12 +371,10 @@ END_SHADER_PARAMS } MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( - LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); - SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs30 ); bool bWriteDepthToAlpha; bool bWriteWaterFogToAlpha; @@ -409,29 +391,14 @@ END_SHADER_PARAMS bWriteWaterFogToAlpha = false; } + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_worldtwotextureblend_ps30 ); - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); - - // Don't write fog to alpha if we're using translucency - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); - SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); - - // Don't write fog to alpha if we're using translucency - SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) && - (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); - } - + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( sdk_worldtwotextureblend_ps30 ); // always set the transform for detail textures since I'm assuming that you'll // always have a detailscale. @@ -484,8 +451,10 @@ END_SHADER_PARAMS SHADER_DRAW { + //ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" ); + bool bHasFlashlight = UsingFlashlight( params ); - if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + if ( bHasFlashlight /*&& ( IsX360() || r_flashlight_version2.GetInt() )*/ ) { DrawPass( params, pShaderAPI, pShaderShadow, false, vertexCompression ); SHADOW_STATE diff --git a/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp b/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp deleted file mode 100644 index 3ae6383a..00000000 --- a/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX6 ) - - -BEGIN_SHADER( WorldTwoTextureBlend_DX6, - "Help for WorldTwoTextureBlend" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) - SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", - "If this is 1, then when detail alpha=0, no base texture is blended and when " - "detail alpha=1, you get detail*base*lightmap" ) - END_SHADER_PARAMS - - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - LoadTexture( BASETEXTURE ); - LoadTexture( DETAIL ); - } - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) - params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - } - - SHADER_DRAW - { - float detailScale = params[DETAILSCALE]->GetFloatValue(); - - bool hasFlashlight = UsingFlashlight( params ); - - if( hasFlashlight ) - { - DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - return; - } - - // DX6 fallback mode. - if ( params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) - { - DetailAlphaMaskPass1( pShaderShadow, pShaderAPI, params, detailScale ); - DetailAlphaMaskPass2( pShaderShadow, pShaderAPI, detailScale ); - } - else - { - // FIXME: add multitexture support! - NormalModePass1( pShaderShadow, pShaderAPI ); - NormalModePass2( pShaderShadow, pShaderAPI, params, detailScale ); - NormalModePass3( pShaderShadow, pShaderAPI, params, detailScale ); - } - } - - - // ------------------------------------------------------------------------------ // - // "Normal" mode - doesn't use the detail texture's alpha mask. - // ------------------------------------------------------------------------------ // - - void NormalModePass1( - IShaderShadow *pShaderShadow, - IShaderDynamicAPI *pShaderAPI ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - } - Draw(); - } - - void NormalModePass2( - IShaderShadow *pShaderShadow, - IShaderDynamicAPI *pShaderAPI, - IMaterialVar **params, - float detailScale ) - { - SHADOW_STATE - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableBlending( true ); - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); - FogToFogColor(); - } - - DYNAMIC_STATE - { - if ( detailScale != 1.0f ) - { - pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); - pShaderAPI->LoadIdentity(); - pShaderAPI->ScaleXY( detailScale, detailScale ); - } - BindTexture( SHADER_SAMPLER0, DETAIL ); - } - Draw(); - } - - void NormalModePass3( - IShaderShadow *pShaderShadow, - IShaderDynamicAPI *pShaderAPI, - IMaterialVar **params, - float detailScale ) - { - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - SingleTextureLightmapBlendMode(); - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - FogToOOOverbright(); - } - DYNAMIC_STATE - { - if ( detailScale != 1.0f ) - pShaderAPI->LoadIdentity( ); - - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - } - Draw(); - } - - - // ------------------------------------------------------------------------------ // - // "Detail alpha mask mode". - // ------------------------------------------------------------------------------ // - - void DetailAlphaMaskPass1( - IShaderShadow *pShaderShadow, - IShaderDynamicAPI *pShaderAPI, - IMaterialVar **params, - float detailScale ) - { - // The equation is [B*Da + (1-Da)] * [D * L] - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 2 ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // Stage 0 - // Color = B*2 - // Note the 2x here.. we do 4x total in this shader and - // the first 2x is here. The second is in SingleTextureLightmapBlendMode in the 2nd pass. - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); - - // Stage 1 [where P = prev stage] - // Color = B*Da + (1-Da) - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATEINVCOLOR_ADDALPHA, - SHADER_TEXARG_INVTEXTUREALPHA, SHADER_TEXARG_PREVIOUSSTAGE ); - - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); - FogToFogColor(); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - BindTexture( SHADER_SAMPLER1, DETAIL ); - - pShaderAPI->Color4f( 1, 1, 1, 1 ); - - if ( detailScale != 1.0f ) - { - pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); - pShaderAPI->LoadIdentity(); - pShaderAPI->ScaleXY( detailScale, detailScale ); - } - - } - Draw(); - } - - void DetailAlphaMaskPass2( IShaderShadow *pShaderShadow, IShaderDynamicAPI *pShaderAPI, float detailScale ) - { - SHADOW_STATE - { - s_pShaderShadow->EnableCustomPixelPipe( true ); - s_pShaderShadow->CustomTextureStages( 2 ); - - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true); - - // Make sure the texgen transform is applied to the texture coordinates and not to an auto-generated reflection vector or whatever. - s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_OBJECT_LINEAR ); - - // This turns on blending and does overbrighting if it's enabled. - SingleTextureLightmapBlendMode(); - - // Stage 0, color = D - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); - - // Stage 1, color = D*L - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, - SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_TEXTURE ); - - // Use the lightmap coordinates in both stages. - pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_LIGHTMAP_TEXCOORD1 ); - FogToFogColor(); - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, DETAIL); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - if ( detailScale != 1.0f ) - { - pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); - pShaderAPI->LoadIdentity(); - - pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); - pShaderAPI->LoadIdentity(); - pShaderAPI->ScaleXY( detailScale, detailScale ); - } - } - - Draw(); - } - -END_SHADER - diff --git a/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp b/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp deleted file mode 100644 index a58d9dfb..00000000 --- a/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "lightmappedgeneric_vs11.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX8 ) - -BEGIN_VS_SHADER( WorldTwoTextureBlend_DX8, - "Help for WorldTwoTextureBlend_DX8" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) - SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", - "If this is 1, then when detail alpha=0, no base texture is blended and when " - "detail alpha=1, you get detail*base*lightmap" ) - END_SHADER_PARAMS - - SHADER_FALLBACK - { - if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) - return "WorldTwoTextureBlend_DX6"; - - return 0; - } - SHADER_INIT - { - LoadTexture( FLASHLIGHTTEXTURE ); - if (params[BASETEXTURE]->IsDefined()) - { - LoadTexture( BASETEXTURE ); - } - - if (params[DETAIL]->IsDefined()) - { - LoadTexture( DETAIL ); - } - } - - SHADER_INIT_PARAMS() - { - // FLASHLIGHTFIXME - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - - if( !params[SELFILLUMTINT]->IsDefined() ) - { - params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) - { - params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); - } - - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - } - - const char *GetPixelShaderName( IMaterialVar** params, bool bHasBaseTexture, bool bHasDetailTexture ) - { - bool bSelfIllum = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM); - if ( !bHasBaseTexture ) - { - if ( !bHasDetailTexture ) - return "LightmappedGeneric_NoTexture"; - - return "LightmappedGeneric_DetailNoTexture"; - } - - if ( !bHasDetailTexture ) - { - if ( bSelfIllum ) - return "LightmappedGeneric_SelfIlluminated"; - - return "LightmappedGeneric"; - } - - if ( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) - { - if ( bSelfIllum ) - return "WorldTwoTextureBlend_SelfIlluminated"; - - return "WorldTwoTextureBlend"; - } - - return "WorldTwoTextureBlend_DetailAlpha"; - } - - - SHADER_DRAW - { - bool hasFlashlight = UsingFlashlight( params ); - if( hasFlashlight ) - { - DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, - FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); - return; - } - - bool bHasBaseTexture = params[BASETEXTURE]->IsTexture(); - bool bHasDetailTexture = params[DETAIL]->IsTexture(); - bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - - SHADOW_STATE - { - if ( bHasBaseTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - } - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - if ( bHasDetailTexture ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - } - pShaderShadow->EnableBlending( false ); - - pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); - - // Let the shaders do the fun stuff. - lightmappedgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( bHasDetailTexture ); - vshIndex.SetENVMAP( false ); - vshIndex.SetENVMAPCAMERASPACE( false ); - vshIndex.SetENVMAPSPHERE( false ); - vshIndex.SetVERTEXCOLOR( bHasVertexColor ); - pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); - - const char *pPixelShaderName = GetPixelShaderName( params, bHasBaseTexture, bHasDetailTexture ); - pShaderShadow->SetPixelShader( pPixelShaderName ); - - FogToFogColor(); - } - DYNAMIC_STATE - { - if ( bHasBaseTexture ) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); - } - - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - if ( bHasDetailTexture ) - { - BindTexture( SHADER_SAMPLER2, DETAIL ); - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); - } - - SetModulationVertexShaderDynamicState(); - - // Dynamic vertex shader index. - lightmappedgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - EnablePixelShaderOverbright( 0, true, true ); - SetPixelShaderConstant( 1, SELFILLUMTINT ); - } - Draw(); - } - -END_SHADER - diff --git a/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc b/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc deleted file mode 100644 index b81fa7bd..00000000 --- a/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc +++ /dev/null @@ -1,217 +0,0 @@ -//====== Copyright 1996-2007, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] -// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] -// STATIC: "DETAILTEXTURE" "0..1" -// STATIC: "BUMPMAP" "0..1" -// STATIC: "VERTEXCOLOR" "0..1" -// STATIC: "SELFILLUM" "0..1" -// STATIC: "DIFFUSEBUMPMAP" "0..1" -// STATIC: "DETAIL_ALPHA_MASK_BASE_TEXTURE" "0..1" -// STATIC: "FLASHLIGHT" "0..1" -// STATIC: "SEAMLESS" "0..1" -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] -// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] - -// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" -// DYNAMIC: "PIXELFOGTYPE" "0..1" -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] -// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] -// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] - -// SKIP: $DETAILTEXTURE && ( $BUMPMAP && !$DETAIL_ALPHA_MASK_BASE_TEXTURE ) -// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP -// SKIP: $VERTEXCOLOR && $BUMPMAP -// SKIP: FLASHLIGHT && $SELFILLUM -// SKIP: FLASHLIGHT && $DETAIL_ALPHA_MASK_BASE_TEXTURE -// SKIP: FLASHLIGHT && ($BUMPMAP || $DIFFUSEBUMPMAP) - -// We don't care about flashlight depth unless the flashlight is on -// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] - -#if defined( SHADER_MODEL_PS_2_0 ) -# define WRITE_DEPTH_TO_DESTALPHA 0 -#endif - - -#define HDRTYPE HDR_TYPE_NONE -#include "common_flashlight_fxc.h" -#include "common_ps_fxc.h" - -const HALF4 g_SelfIllumTint : register( c7 ); -static const HALF g_OverbrightFactor = 2.0f; - -const HALF3 g_EyePos : register( c10 ); -const HALF4 g_FogParams : register( c11 ); - -const HALF3 g_FlashlightPos : register( c15 ); -// flashlightfixme: Move this math into the vertex shader. -const float4x4 g_FlashlightWorldToTexture : register( c16 ); - -const float4 g_FlashlightAttenuationFactors : register( c20 ); - -sampler BaseTextureSampler : register( s0 ); -sampler LightmapSampler : register( s1 ); -sampler FlashlightSampler : register( s2 ); -sampler DetailSampler : register( s3 ); -sampler BumpmapSampler : register( s4 ); -sampler NormalizeSampler : register( s6 ); - -struct PS_INPUT -{ - HALF2 baseTexCoord : TEXCOORD0; - HALF4 detailOrBumpTexCoord : TEXCOORD1; - HALF4 lightmapTexCoord1And2 : TEXCOORD2; // CENTROID: TEXCOORD2 - HALF2 lightmapTexCoord3 : TEXCOORD3; // CENTROID: TEXCOORD3 - HALF4 worldPos_projPosZ : TEXCOORD4; - HALF3x3 tangentSpaceTranspose : TEXCOORD5; - // tangentSpaceTranspose : TEXCOORD6; - // tangentSpaceTranspose : TEXCOORD7; - HALF4 vertexColor : COLOR; -}; - - -float4 main( PS_INPUT i ) : COLOR -{ - bool bDetailTexture = DETAILTEXTURE ? true : false; - bool bBumpmap = BUMPMAP ? true : false; - bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; - bool bVertexColor = VERTEXCOLOR ? true : false; - bool bSelfIllum = SELFILLUM ? true : false; - bool bDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE ? true : false; - bool bFlashlight = FLASHLIGHT ? true : false; - - HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); - HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); - if( bBumpmap && bDiffuseBumpmap ) - { - HALF2 bumpCoord1; - HALF2 bumpCoord2; - HALF2 bumpCoord3; - ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, - bumpCoord1, bumpCoord2, bumpCoord3 ); - - HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); - lightmapColor1 = lightmapSample1.rgb; - lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); - lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); - } - else - { - if( !bFlashlight ) - { - HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); - HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); - lightmapColor1 = lightmapSample1.rgb; - } - } - - HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); - if( bDetailTexture ) - { - detailColor = tex2D( DetailSampler, i.detailOrBumpTexCoord.xy ); - } - - HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); - baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); - if ( bDetailAlphaMaskBaseTexture ) - { - // This is what WorldTwoTextureBlend_DX6 does. - baseColor.rgb = saturate( saturate( baseColor * 2 ) * detailColor.a + (1 - detailColor.a) ); - baseColor.rgb *= detailColor; - } - else - { - baseColor.rgb = lerp( baseColor, detailColor, detailColor.a ); - } - - HALF3 normal = HALF3( 0.0f, 0.0f, 1.0f ); - if( bBumpmap ) - { - HALF3 normalTexel; - normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord.xy ); - normal = 2.0 * normalTexel - 1.0; - } - - HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f ); - HALF alpha = 1.0f; - albedo *= baseColor; - if( !bSelfIllum ) - { - alpha *= baseColor.a; - } - - // The vertex color contains the modulation color + vertex color combined - albedo *= i.vertexColor; - alpha *= i.vertexColor.a; // not sure about this one - - HALF3 diffuseLighting; - if( bFlashlight ) - { - float3 worldSpaceNormal; - // Make the unbumped version not so fucking stupid and not need tangentSpaceTranspose you knob. - worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); - - int nShadowSampleLevel = 0; - bool bDoShadows = false; -// On ps_2_b, we can do shadow mapping -#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) - nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; - bDoShadows = true; -#endif - float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); - - diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, - worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, - g_FlashlightAttenuationFactors.w, FlashlightSampler, FlashlightSampler, NormalizeSampler, - nShadowSampleLevel, bDoShadows, false, float2(0, 0), false ); - } - else - { - if( bBumpmap && bDiffuseBumpmap ) - { - float dot1 = saturate( dot( normal, bumpBasis[0] ) ); - float dot2 = saturate( dot( normal, bumpBasis[1] ) ); - float dot3 = saturate( dot( normal, bumpBasis[2] ) ); - - float sum = dot1 + dot2 + dot3; - diffuseLighting = dot1 * lightmapColor1 + - dot2 * lightmapColor2 + - dot3 * lightmapColor3; - diffuseLighting *= 1.0f / sum; - } - else - { - diffuseLighting = lightmapColor1; - } - - // Only scale here since the flashlight will already be scaled properly - diffuseLighting *= g_OverbrightFactor; - } - - HALF3 diffuseComponent = albedo * diffuseLighting; - - if( bSelfIllum ) - { - HALF3 selfIllumComponent = g_SelfIllumTint * albedo; - diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); - } - - HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); - HALF3 result = diffuseComponent + specularLighting; - - float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); - -#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) - alpha = fogFactor; -#endif - - return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); -} - diff --git a/materialsystem/stdshaders/worldvertexalpha.cpp b/materialsystem/stdshaders/worldvertexalpha.cpp deleted file mode 100644 index 85bad1c1..00000000 --- a/materialsystem/stdshaders/worldvertexalpha.cpp +++ /dev/null @@ -1,259 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "WorldVertexAlpha.inc" -#include "worldvertexalpha_ps20.inc" -#include "worldvertexalpha_ps20b.inc" - -BEGIN_VS_SHADER( WorldVertexAlpha, - "Help for WorldVertexAlpha" ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - SET_FLAGS2( MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA ); - } - SHADER_INIT - { - // Load the base texture here! - LoadTexture( BASETEXTURE ); - } - - SHADER_FALLBACK - { -// if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) - { - return "WorldVertexAlpha_DX8"; - } - return 0; - } - - SHADER_DRAW - { - if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - // NOTE: This is the DX8, Non-Hammer version. - - SHADOW_STATE - { - // Base time lightmap (Need two texture stages) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - - worldvertexalpha_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); - FogToFogColor(); - } - - DYNAMIC_STATE - { - // Bind the base texture (Stage0) and lightmap (Stage1) - BindTexture( SHADER_SAMPLER0, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - EnablePixelShaderOverbright( 0, true, true ); - - worldvertexalpha_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - - Draw(); - } - else - { - // DX 9 version with HDR support - - // Pass 1 - SHADOW_STATE - { - SetInitialShadowState(); - - pShaderShadow->EnableAlphaWrites( true ); - - // Base time lightmap (Need two texture stages) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - pShaderShadow->EnableBlendingSeparateAlpha( true ); - pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ZERO, SHADER_BLEND_SRC_ALPHA ); - - worldvertexalpha_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); - SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); - SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - } - - - FogToFogColor(); - } - - DYNAMIC_STATE - { - // Bind the base texture (Stage0) and lightmap (Stage1) - BindTexture( SHADER_SAMPLER0, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - worldvertexalpha_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - } - } - Draw(); - - // Pass 2 - SHADOW_STATE - { - SetInitialShadowState(); - - pShaderShadow->EnableAlphaWrites( true ); - pShaderShadow->EnableColorWrites( false ); - - // Base time lightmap (Need two texture stages) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - pShaderShadow->EnableBlendingSeparateAlpha( true ); - pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - - worldvertexalpha_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); - SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); - SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - } - - FogToFogColor(); - } - - DYNAMIC_STATE - { - // Bind the base texture (Stage0) and lightmap (Stage1) - BindTexture( SHADER_SAMPLER0, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - - worldvertexalpha_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); - } - } - Draw(); - } - } - else - { - // NOTE: This is the DX7, Hammer version. - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); -// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - - // Use vertex color for Hammer because it puts the blending alpha in the vertices. - unsigned int colorFlag = 0; - if( UsingEditor( params ) ) - { - colorFlag |= SHADER_DRAW_COLOR; - } - - pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | - SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - } - - Draw(); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/worldvertexalpha_dx8.cpp b/materialsystem/stdshaders/worldvertexalpha_dx8.cpp deleted file mode 100644 index 0ea139ee..00000000 --- a/materialsystem/stdshaders/worldvertexalpha_dx8.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "worldvertexalpha.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( WorldVertexAlpha, WorldVertexAlpha_DX8 ) - -BEGIN_VS_SHADER( WorldVertexAlpha_DX8, - "Help for WorldVertexAlpha_DX8" ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - } - SHADER_INIT - { - // Load the base texture here! - LoadTexture( BASETEXTURE ); - } - - SHADER_DRAW - { - if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) - { - // NOTE: This is the DX8, Non-Hammer version. - - SHADOW_STATE - { - // Base time lightmap (Need two texture stages) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - - worldvertexalpha_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); - - pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); - FogToFogColor(); - } - - DYNAMIC_STATE - { - // Bind the base texture (Stage0) and lightmap (Stage1) - BindTexture( SHADER_SAMPLER0, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); - EnablePixelShaderOverbright( 0, true, true ); - - worldvertexalpha_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - - Draw(); - } - else - { - // NOTE: This is the DX7, Hammer version. - // FIXME: Gary - you need to write a proper non-fixed function shader for this. - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); - - pShaderShadow->EnableBlending( true ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); -// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); - - // Use vertex color for Hammer because it puts the blending alpha in the vertices. - unsigned int colorFlag = 0; - if( UsingEditor( params ) ) - { - colorFlag |= SHADER_DRAW_COLOR; - } - - pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | - SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - } - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - } - - Draw(); - } - } -END_SHADER diff --git a/materialsystem/stdshaders/worldvertextransition.cpp b/materialsystem/stdshaders/worldvertextransition.cpp deleted file mode 100644 index c6459d80..00000000 --- a/materialsystem/stdshaders/worldvertextransition.cpp +++ /dev/null @@ -1,212 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" -#include "convar.h" - -#include "worldvertextransition_dx8_helper.h" -#include "lightmappedgeneric_dx9_helper.h" -#ifdef VANCE -#include "lightpass_helper.h" -#endif // VANCE - -static LightmappedGeneric_DX9_Vars_t s_info; - -#ifdef STDSHADER -BEGIN_VS_SHADER(WorldVertexTransition, "Help for WorldVertexTransition" ) -#else -BEGIN_VS_SHADER(SDK_WorldVertexTransition, "Help for WorldVertexTransition") -#endif - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) - SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) - SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) - SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) - - // detail (multi-) texturing - SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) - SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) - SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) - - SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) - SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) - SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) - SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) - SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) - SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) - SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) - SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) - SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) - SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) - SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) - SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) - SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) - SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) - SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) - SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) - SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) - SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", - "If this is 1, then when detail alpha=0, no base texture is blended and when " - "detail alpha=1, you get detail*base*lightmap" ) - SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) - SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) - SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) - SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) - SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) - SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) -#ifdef VANCE - SHADER_PARAM(BRDF, SHADER_PARAM_TYPE_TEXTURE, "models/PBRTest/BRDF", "") - SHADER_PARAM(NOISE, SHADER_PARAM_TYPE_TEXTURE, "shaders/bluenoise", "") - SHADER_PARAM(ROUGHNESS, SHADER_PARAM_TYPE_TEXTURE, "", "") - SHADER_PARAM(METALLIC, SHADER_PARAM_TYPE_TEXTURE, "", "") -#endif // VANCE - - END_SHADER_PARAMS - -#ifdef VANCE - void SetupVars(DrawLightPass_Vars_t& info) -{ - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nNoise = NOISE; - info.m_nBumpmap = BUMPMAP; - info.m_nRoughness = ROUGHNESS; - info.m_nMetallic = METALLIC; - info.m_nBumpmap2 = BUMPMAP2; - info.m_nBumpFrame2 = BUMPFRAME2; - info.m_nBumpTransform2 = BUMPTRANSFORM2; - info.m_nBaseTexture2 = BASETEXTURE2; - info.m_nBaseTexture2Frame = FRAME2; - info.m_nSeamlessMappingScale = SEAMLESS_SCALE; - info.bModel = false; - info.m_nUseSmoothness = -1; -} -#endif // VANCE - - void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) - { - info.m_nBaseTextureVar = BASETEXTURE; - info.m_nBaseTextureFrameVar = FRAME; - info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; - info.m_nBaseTexture2Var = BASETEXTURE2; - info.m_nBaseTexture2FrameVar = FRAME2; - info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM; // FIXME!!!! - } - - void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlbedo = ALBEDO; - info.m_nSelfIllumTint = SELFILLUMTINT; - - info.m_nDetail = DETAIL; - info.m_nDetailFrame = DETAILFRAME; - info.m_nDetailScale = DETAILSCALE; - info.m_nDetailTextureCombineMode = DETAILBLENDMODE; - info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; - info.m_nDetailTint = DETAILTINT; - - info.m_nEnvmap = ENVMAP; - info.m_nEnvmapFrame = ENVMAPFRAME; - info.m_nEnvmapMask = ENVMAPMASK; - info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; - info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; - info.m_nEnvmapTint = ENVMAPTINT; - info.m_nBumpmap = BUMPMAP; - info.m_nBumpFrame = BUMPFRAME; - info.m_nBumpTransform = BUMPTRANSFORM; - info.m_nEnvmapContrast = ENVMAPCONTRAST; - info.m_nEnvmapSaturation = ENVMAPSATURATION; - info.m_nFresnelReflection = FRESNELREFLECTION; - info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; - info.m_nBumpmap2 = BUMPMAP2; - info.m_nBumpFrame2 = BUMPFRAME2; - info.m_nBaseTexture2 = BASETEXTURE2; - info.m_nBaseTexture2Frame = FRAME2; - info.m_nBumpTransform2 = BUMPTRANSFORM2; - info.m_nBumpMask = BUMPMASK; - info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; - info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; - info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - info.m_nLightWarpTexture = LIGHTWARPTEXTURE; - info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; - info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; - info.m_nMaskedBlending = MASKEDBLENDING; - info.m_nSelfShadowedBumpFlag = SSBUMP; - info.m_nSeamlessMappingScale = SEAMLESS_SCALE; - info.m_nAlphaTestReference = -1; - } - - SHADER_FALLBACK - { - if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "WorldVertexTransition_DX8"; - - return 0; - } - - SHADER_INIT_PARAMS() - { - SetupVars( s_info ); - InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); - } - - SHADER_INIT - { - SetupVars( s_info ); - InitLightmappedGeneric_DX9( this, params, s_info ); - -#ifdef VANCE - DrawLightPass_Vars_t vars; - SetupVars(vars); - InitLightPass(this, params, vars); -#endif // VANCE - } - - SHADER_DRAW - { -#ifndef VANCE - - if ( UsingEditor( params ) ) - { - WorldVertexTransitionEditor_DX8_Vars_t info; - SetupVars( info ); - DrawWorldVertexTransitionEditor_DX8( this, params, pShaderAPI, pShaderShadow, info ); - return; - } - -#endif // !VANCE - - // Skip the standard rendering if cloak pass is fully opaque - bool bDrawStandardPass = true; - - if (bDrawStandardPass) - { - DrawLightmappedGeneric_DX9(this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr); - } - else - { - // Skip this pass! - Draw(false); - } - - DrawLightPass_Vars_t vars; - SetupVars(vars); - DrawLightPass(this, params, pShaderAPI, pShaderShadow, vertexCompression, pContextDataPtr, vars); - } -END_SHADER - diff --git a/materialsystem/stdshaders/worldvertextransition_dx6.cpp b/materialsystem/stdshaders/worldvertextransition_dx6.cpp deleted file mode 100644 index 163291e3..00000000 --- a/materialsystem/stdshaders/worldvertextransition_dx6.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "shaderlib/cshader.h" - -#include "worldvertextransition_dx6_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX6 ) - -BEGIN_SHADER( WorldVertexTransition_DX6, - "Help for WorldVertexTransition_dx6" ) - - BEGIN_SHADER_PARAMS - SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) - END_SHADER_PARAMS - - void SetupVars( WorldVertexTransition_DX6_Vars_t& info ) - { - info.m_nBaseTextureVar = BASETEXTURE; - info.m_nBaseTextureFrameVar = FRAME; - info.m_nBaseTexture2Var = BASETEXTURE2; - info.m_nFlashlightTextureVar = FLASHLIGHTTEXTURE; - } - - SHADER_INIT_PARAMS() - { - WorldVertexTransition_DX6_Vars_t info; - SetupVars( info ); - InitParamsWorldVertexTransition_DX6( params, info ); - } - - SHADER_INIT - { - WorldVertexTransition_DX6_Vars_t info; - SetupVars( info ); - InitWorldVertexTransition_DX6( this, params, info ); - } - - SHADER_DRAW - { - WorldVertexTransition_DX6_Vars_t info; - SetupVars( info ); - DrawWorldVertexTransition_DX6( this, params, pShaderAPI, pShaderShadow, info ); - } -END_SHADER diff --git a/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp b/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp deleted file mode 100644 index 7539ff29..00000000 --- a/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp +++ /dev/null @@ -1,206 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "shaderlib/cshader.h" -#include "worldvertextransition_dx6_helper.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) -{ - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - // FLASHLIGHTFIXME - params[info.m_nFlashlightTextureVar]->SetStringValue( "effects/flashlight001" ); -} - -void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) -{ - // FLASHLIGHTFIXME - if ( params[info.m_nFlashlightTextureVar]->IsDefined() ) - { - pShader->LoadTexture( info.m_nFlashlightTextureVar ); - } - - if ( params[info.m_nBaseTextureVar]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTextureVar ); - } - - if ( params[info.m_nBaseTexture2Var]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture2Var ); - } -} - -static void DrawFlashlightPass( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int nPass, WorldVertexTransition_DX6_Vars_t &info ) -{ - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( false ); - - pShaderShadow->SetDiffuseMaterialSource( SHADER_MATERIALSOURCE_COLOR1 ); - if( nPass == 0 ) - { - pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - } - else - { - pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); - } - - int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; - pShaderShadow->DrawFlags( flags ); - pShader->FogToBlack(); - - pShaderShadow->EnableLighting( true ); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 2 ); - - // color stage 0 - // projected texture * vertex color (lighting) - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, - SHADER_TEXARG_VERTEXCOLOR ); - - // color stage 1 - // * base texture - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); - - // alpha stage 0 - // get alpha from constant alpha * vertex color - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_VERTEXCOLOR ); - - // alpha stage 1 - // get alpha from $basetexture - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // Shove the view position into texcoord 0 before the texture matrix. - pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); - pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); - } - DYNAMIC_STATE - { - pShader->SetFlashlightFixedFunctionTextureTransform( MATERIAL_TEXTURE0 ); - - // NOTE: This has to come after the loadmatrix since the loadmatrix screws with the - // transform flags!!!!!! - // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. - // NOTE Tried to divide XY by Z, but doesn't work. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 3, true ); - - pShader->BindTexture( SHADER_SAMPLER0, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); - if( nPass == 0 ) - { - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, -1 ); - } - else - { - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); - } - } - pShader->Draw(); -} - - -void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ) -{ - bool bHasFlashlight = pShader->UsingFlashlight( params ); - if( bHasFlashlight ) - { - DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 0, info ); - DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 1, info ); - return; - } - - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); - - pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - pShader->FogToFogColor(); - } - DYNAMIC_STATE - { - //pShaderAPI->TexMinFilter( SHADER_TEXFILTERMODE_NEAREST ); - //pShaderAPI->TexMagFilter( SHADER_TEXFILTERMODE_NEAREST ); - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - } - pShader->Draw(); - - SHADOW_STATE - { - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableBlending( true ); - - pShaderShadow->EnableCustomPixelPipe( true ); - pShaderShadow->CustomTextureStages( 2 ); - - // alpha and color stage 0 - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_TEXTURE, - SHADER_TEXARG_TEXTURE ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_SELECTARG1, - SHADER_TEXARG_TEXTURE, - SHADER_TEXARG_TEXTURE ); - - // alpha and color stage 1 - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_ALPHA, - SHADER_TEXOP_MODULATE, - SHADER_TEXARG_TEXTURE, - SHADER_TEXARG_VERTEXCOLOR ); - - pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, - SHADER_TEXCHANNEL_COLOR, - SHADER_TEXOP_MODULATE2X, - SHADER_TEXARG_PREVIOUSSTAGE, - SHADER_TEXARG_TEXTURE ); - - // Looks backwards, but this is done so that lightmap alpha = 1 when only - // using 1 texture (needed for translucent displacements). - pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - - pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); - pShader->FogToFogColor(); - } - DYNAMIC_STATE - { - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); - } - pShader->Draw(); -} diff --git a/materialsystem/stdshaders/worldvertextransition_dx6_helper.h b/materialsystem/stdshaders/worldvertextransition_dx6_helper.h deleted file mode 100644 index 16e0bfd5..00000000 --- a/materialsystem/stdshaders/worldvertextransition_dx6_helper.h +++ /dev/null @@ -1,39 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef WORLDVERTEXTRANSITION_DX6_HELPER_H -#define WORLDVERTEXTRANSITION_DX6_HELPER_H - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct WorldVertexTransition_DX6_Vars_t -{ - WorldVertexTransition_DX6_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransition_DX6_Vars_t) ); } - - int m_nBaseTextureVar; - int m_nBaseTextureFrameVar; - int m_nBaseTexture2Var; - int m_nFlashlightTextureVar; -}; - -void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); -void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); -void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ); - - -#endif // WORLDVERTEXTRANSITION_DX6_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp b/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp deleted file mode 100644 index 6a49fd71..00000000 --- a/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp +++ /dev/null @@ -1,81 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "worldvertextransition_dx8_helper.h" -#include "BaseVSShader.h" - -#include "WorldVertexTransition.inc" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) -{ - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); -} - -void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) -{ - if ( params[info.m_nBaseTextureVar]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTextureVar ); - } - - if ( params[info.m_nBaseTexture2Var]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture2Var ); - } -} - -void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ) -{ - SHADOW_STATE - { - // This is the dx8 worldcraft version (non-bumped always.. too bad) - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - int fmt = VERTEX_POSITION | VERTEX_COLOR; - pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); - - worldvertextransition_Static_Index vshIndex; - pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); - pShaderShadow->SetPixelShader( "WorldVertexTransition_Editor" ); - - pShader->FogToFogColor(); - } - DYNAMIC_STATE - { - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); - pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, info.m_nBaseTexture2FrameVar ); - - // Texture 3 = lightmap - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); - - pShader->EnablePixelShaderOverbright( 0, true, true ); - - // JasonM - Gnarly hack since we're calling this legacy shader from DX9 - int nTextureTransformConst = VERTEX_SHADER_SHADER_SPECIFIC_CONST_0; - int nTextureTransformConst2 = VERTEX_SHADER_SHADER_SPECIFIC_CONST_2; - if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) - { - nTextureTransformConst -= 10; - nTextureTransformConst2 -= 10; - } - - pShader->SetVertexShaderTextureTransform( nTextureTransformConst, info.m_nBaseTextureTransformVar ); - pShader->SetVertexShaderTextureTransform( nTextureTransformConst2, info.m_nBaseTexture2TransformVar ); - - worldvertextransition_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - pShader->Draw(); -} diff --git a/materialsystem/stdshaders/worldvertextransition_dx8_helper.h b/materialsystem/stdshaders/worldvertextransition_dx8_helper.h deleted file mode 100644 index d17d532e..00000000 --- a/materialsystem/stdshaders/worldvertextransition_dx8_helper.h +++ /dev/null @@ -1,44 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef WORLDVERTEXTRANSITION_DX8_HELPER_H -#define WORLDVERTEXTRANSITION_DX8_HELPER_H - -#include - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct WorldVertexTransitionEditor_DX8_Vars_t -{ - WorldVertexTransitionEditor_DX8_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransitionEditor_DX8_Vars_t) ); } - - int m_nBaseTextureVar; - int m_nBaseTextureFrameVar; - int m_nBaseTextureTransformVar; - int m_nBaseTexture2Var; - int m_nBaseTexture2FrameVar; - int m_nBaseTexture2TransformVar; -}; - -void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); -void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); -void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ); - - -#endif // WORLDVERTEXTRANSITION_DX8_HELPER_H \ No newline at end of file diff --git a/materialsystem/stdshaders/writestencil_dx9.cpp b/materialsystem/stdshaders/writestencil_dx9.cpp deleted file mode 100644 index 825d4ea9..00000000 --- a/materialsystem/stdshaders/writestencil_dx9.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "writez_vs30.inc" -#include "white_ps30.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( WriteStencil, WriteStencil_DX9 ) - -BEGIN_VS_SHADER_FLAGS( WriteStencil_DX9, "Help for WriteStencil", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "WriteStencil_DX8"; - - return 0; - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableColorWrites( false ); // - pShaderShadow->EnableAlphaWrites( false ); // Write ONLY to stencil - pShaderShadow->EnableDepthWrites( false ); // - - DECLARE_STATIC_VERTEX_SHADER( writez_vs30 ); - SET_STATIC_VERTEX_SHADER( writez_vs30 ); - - //No pixel shader, doubles fill rate. - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - } - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( writez_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( writez_vs30 ); - - //No pixel shader, doubles fill rate. - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/writez_dx9.cpp b/materialsystem/stdshaders/writez_dx9.cpp deleted file mode 100644 index 0679bd32..00000000 --- a/materialsystem/stdshaders/writez_dx9.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - - -#include "writez_vs30.inc" -#include "white_ps30.inc" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -DEFINE_FALLBACK_SHADER( WriteZ, WriteZ_DX9 ) - -BEGIN_VS_SHADER_FLAGS( WriteZ_DX9, "Help for WriteZ", SHADER_NOT_EDITABLE ) - - BEGIN_SHADER_PARAMS - END_SHADER_PARAMS - - SHADER_INIT_PARAMS() - { - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - return "WriteZ_DX8"; - - return 0; - } - - SHADER_INIT - { - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableColorWrites( false ); - pShaderShadow->EnableAlphaWrites( false ); - - DECLARE_STATIC_VERTEX_SHADER( writez_vs30 ); - SET_STATIC_VERTEX_SHADER( writez_vs30 ); - - //No pixel shader, doubles fill rate. - - // Set stream format (note that this shader supports compression) - unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; - int nTexCoordCount = 1; - int userDataSize = 0; - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); - } - DYNAMIC_STATE - { - DECLARE_DYNAMIC_VERTEX_SHADER( writez_vs30 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); - SET_DYNAMIC_VERTEX_SHADER( writez_vs30 ); - - //No pixel shader, doubles fill rate. - } - Draw(); - } -END_SHADER - diff --git a/materialsystem/stdshaders/writez_vs20.fxc b/materialsystem/stdshaders/writez_vs20.fxc deleted file mode 100644 index 3f31f3fb..00000000 --- a/materialsystem/stdshaders/writez_vs20.fxc +++ /dev/null @@ -1,24 +0,0 @@ -// DYNAMIC: "COMPRESSED_VERTS" "0..1" -// DYNAMIC: "DOWATERFOG" "0..1" - -#include "common_vs_fxc.h" - -struct VS_INPUT -{ - float4 vPos : POSITION; -}; - -struct VS_OUTPUT -{ - float4 vProjPos : POSITION; -}; - - -VS_OUTPUT main( const VS_INPUT v ) -{ - VS_OUTPUT o = ( VS_OUTPUT )0; - - o.vProjPos = mul( v.vPos, cModelViewProj ); - - return o; -} \ No newline at end of file diff --git a/mathlib/IceKey.cpp b/mathlib/IceKey.cpp index c03c72fe..e739ce6f 100644 --- a/mathlib/IceKey.cpp +++ b/mathlib/IceKey.cpp @@ -60,11 +60,11 @@ static const int ice_keyrot[16] = { static unsigned int gf_mult ( - unsigned int a, - unsigned int b, - unsigned int m + register unsigned int a, + register unsigned int b, + register unsigned int m ) { - unsigned int res = 0; + register unsigned int res = 0; while (b) { if (b & 1) @@ -88,10 +88,10 @@ gf_mult ( static unsigned long gf_exp7 ( - unsigned int b, + register unsigned int b, unsigned int m ) { - unsigned int x; + register unsigned int x; if (b == 0) return (0); @@ -109,10 +109,10 @@ gf_exp7 ( static unsigned long ice_perm32 ( - unsigned long x + register unsigned long x ) { - unsigned long res = 0; - const unsigned long *pbox = ice_pbox; + register unsigned long res = 0; + register const unsigned long *pbox = ice_pbox; while (x) { if (x & 1) @@ -133,7 +133,7 @@ ice_perm32 ( static void ice_sboxes_init (void) { - int i; + register int i; for (i=0; i<1024; i++) { int col = (i >> 1) & 0xff; @@ -202,7 +202,7 @@ IceKey::~IceKey () static unsigned long ice_f ( - unsigned long p, + register unsigned long p, const IceSubkey *sk ) { unsigned long tl, tr; /* Expanded 40-bit values */ @@ -240,8 +240,8 @@ IceKey::encrypt ( unsigned char *ctext ) const { - int i; - unsigned long l, r; + register int i; + register unsigned long l, r; l = (((unsigned long) ptext[0]) << 24) | (((unsigned long) ptext[1]) << 16) @@ -275,8 +275,8 @@ IceKey::decrypt ( unsigned char *ptext ) const { - int i; - unsigned long l, r; + register int i; + register unsigned long l, r; l = (((unsigned long) ctext[0]) << 24) | (((unsigned long) ctext[1]) << 16) @@ -313,20 +313,20 @@ IceKey::scheduleBuild ( int i; for (i=0; i<8; i++) { - int j; - int kr = keyrot[i]; + register int j; + register int kr = keyrot[i]; IceSubkey *isk = &_keysched[n + i]; for (j=0; j<3; j++) isk->val[j] = 0; for (j=0; j<15; j++) { - int k; + register int k; unsigned long *curr_sk = &isk->val[j % 3]; for (k=0; k<4; k++) { unsigned short *curr_kb = &kb[(kr + k) & 3]; - int bit = *curr_kb & 1; + register int bit = *curr_kb & 1; *curr_sk = (*curr_sk << 1) | bit; *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15); diff --git a/mathlib/color_conversion.cpp b/mathlib/color_conversion.cpp index c3dbaf25..c3125258 100644 --- a/mathlib/color_conversion.cpp +++ b/mathlib/color_conversion.cpp @@ -609,10 +609,10 @@ void VectorToColorRGBExp32( const Vector& vin, ColorRGBExp32 &c ) scalar = *reinterpret_cast(&fbits); } - // We can totally wind up above 255 and that's okay--but above 256 would be right out. - Assert(vin.x * scalar < 256.0f && - vin.y * scalar < 256.0f && - vin.z * scalar < 256.0f); + // we should never need to clamp: + Assert(vin.x * scalar <= 255.0f && + vin.y * scalar <= 255.0f && + vin.z * scalar <= 255.0f); // This awful construction is necessary to prevent VC2005 from using the // fldcw/fnstcw control words around every float-to-unsigned-char operation. diff --git a/mathlib/imagequant.cpp b/mathlib/imagequant.cpp index 47ba4f4c..daa7b394 100644 --- a/mathlib/imagequant.cpp +++ b/mathlib/imagequant.cpp @@ -46,7 +46,7 @@ void ColorQuantize(uint8 const *Image, val1+=PIXEL(x,y,c)*ExtraValueXForms[i*3+c]; val1>>=8; NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=(uint8) - (min(255,max(0,val1))); + (MIN(255,MAX(0,val1))); } } struct QuantizedValue *q=Quantize(s,Width*Height,N_DIMENSIONS, @@ -76,7 +76,7 @@ void ColorQuantize(uint8 const *Image, tryc+=Error[x][c][ErrorUse]; Error[x][c][ErrorUse]=0; } - samp[c]=(uint8) min(255,max(0,tryc)); + samp[c]=(uint8) MIN(255,MAX(0,tryc)); } struct QuantizedValue *f=FindMatch(samp,3,Weights,q); out_pixels[Width*y+x]=(uint8) (f->value); diff --git a/mathlib/mathlib_base.cpp b/mathlib/mathlib_base.cpp index 64069a7b..d7df6667 100644 --- a/mathlib/mathlib_base.cpp +++ b/mathlib/mathlib_base.cpp @@ -1461,9 +1461,7 @@ float Bias( float x, float biasAmt ) { lastExponent = log( biasAmt ) * -1.4427f; // (-1.4427 = 1 / log(0.5)) } - float fRet = pow( x, lastExponent ); - Assert ( !IS_NAN( fRet ) ); - return fRet; + return pow( x, lastExponent ); } @@ -1479,9 +1477,7 @@ float Gain( float x, float biasAmt ) float SmoothCurve( float x ) { - // Actual smooth curve. Visualization: - // http://www.wolframalpha.com/input/?i=plot%5B+0.5+*+%281+-+cos%5B2+*+pi+*+x%5D%29+for+x+%3D+%280%2C+1%29+%5D - return 0.5f * (1 - cos( 2.0f * M_PI * x ) ); + return (1 - cos( x * M_PI )) * 0.5f; } @@ -1775,7 +1771,7 @@ void QuaternionScale( const Quaternion &p, float t, Quaternion &q ) // FIXME: nick, this isn't overly sensitive to accuracy, and it may be faster to // use the cos part (w) of the quaternion (sin(omega)*N,cos(omega)) to figure the new scale. float sinom = sqrt( DotProduct( &p.x, &p.x ) ); - sinom = min( sinom, 1.f ); + sinom = MIN( sinom, 1.f ); float sinsom = sin( asin( sinom ) * t ); @@ -1860,10 +1856,7 @@ void QuaternionMult( const Quaternion &p, const Quaternion &q, Quaternion &qt ) void QuaternionMatrix( const Quaternion &q, const Vector &pos, matrix3x4_t& matrix ) { - if ( !HushAsserts() ) - { - Assert( pos.IsValid() ); - } + Assert( pos.IsValid() ); QuaternionMatrix( q, matrix ); @@ -1875,10 +1868,7 @@ void QuaternionMatrix( const Quaternion &q, const Vector &pos, matrix3x4_t& matr void QuaternionMatrix( const Quaternion &q, matrix3x4_t& matrix ) { Assert( s_bMathlibInitialized ); - if ( !HushAsserts() ) - { - Assert( q.IsValid() ); - } + Assert( q.IsValid() ); #ifdef _VPROF_MATHLIB VPROF_BUDGET( "QuaternionMatrix", "Mathlib" ); @@ -3398,7 +3388,7 @@ void MathLib_Init( float gamma, float texGamma, float brightness, int overbright { s_bSSE2Enabled = false; } -#endif // !_X360 +#endif s_bMathlibInitialized = true; @@ -4049,10 +4039,10 @@ void CalcTriangleTangentSpace( const Vector &p0, const Vector &p1, const Vector //----------------------------------------------------------------------------- void RGBtoHSV( const Vector &rgb, Vector &hsv ) { - float flMax = max( rgb.x, rgb.y ); - flMax = max( flMax, rgb.z ); - float flMin = min( rgb.x, rgb.y ); - flMin = min( flMin, rgb.z ); + float flMax = MAX( rgb.x, rgb.y ); + flMax = MAX( flMax, rgb.z ); + float flMin = MIN( rgb.x, rgb.y ); + flMin = MIN( flMin, rgb.z ); // hsv.z is the value hsv.z = flMax; diff --git a/mathlib/quantize.cpp b/mathlib/quantize.cpp index e829d2d2..adb2be51 100644 --- a/mathlib/quantize.cpp +++ b/mathlib/quantize.cpp @@ -411,8 +411,8 @@ static void Label(struct QuantizedValue *q, int updatecolor) else for(int i=0;iMins[i]=min(q->Children[0]->Mins[i],q->Children[1]->Mins[i]); - q->Maxs[i]=max(q->Children[0]->Maxs[i],q->Children[1]->Maxs[i]); + q->Mins[i]=MIN(q->Children[0]->Mins[i],q->Children[1]->Mins[i]); + q->Maxs[i]=MAX(q->Children[0]->Maxs[i],q->Children[1]->Maxs[i]); } } } diff --git a/mathlib/simdvectormatrix.cpp b/mathlib/simdvectormatrix.cpp index 9cac37c4..8edb9ef0 100644 --- a/mathlib/simdvectormatrix.cpp +++ b/mathlib/simdvectormatrix.cpp @@ -48,7 +48,7 @@ void CSIMDVectorMatrix::CreateFromRGBA_FloatImageData(int srcwidth, int srcheigh { for(int cp=0;cp<4; cp++) { - int real_cp=min( cp, ntrailing_pixels_per_source_line-1 ); + int real_cp=MIN( cp, ntrailing_pixels_per_source_line-1 ); data_out[4*c+cp]= data_in[c+4*real_cp]; } } diff --git a/mathlib/sparse_convolution_noise.cpp b/mathlib/sparse_convolution_noise.cpp index dbf19b60..2bfb48ff 100644 --- a/mathlib/sparse_convolution_noise.cpp +++ b/mathlib/sparse_convolution_noise.cpp @@ -130,8 +130,8 @@ float SparseConvolutionNoise(Vector const &pnt, float (*pNoiseShapeFunction)(flo pNoiseShapeFunction ); } #ifdef MEASURE_RANGE - fmin1=min(sum_out,fmin1); - fmax1=max(sum_out,fmax1); + fmin1=MIN(sum_out,fmin1); + fmax1=MAX(sum_out,fmax1); #endif return RemapValClamped( sum_out, .544487, 9.219176, 0.0, 1.0 ); } diff --git a/mathlib/sse.cpp b/mathlib/sse.cpp index 7240e5ed..6f05a522 100644 --- a/mathlib/sse.cpp +++ b/mathlib/sse.cpp @@ -62,10 +62,10 @@ _PS_EXTERN_CONST(am_pi_o_2, (float)(M_PI / 2.0)); _PS_EXTERN_CONST(am_2_o_pi, (float)(2.0 / M_PI)); _PS_EXTERN_CONST(am_pi_o_4, (float)(M_PI / 4.0)); _PS_EXTERN_CONST(am_4_o_pi, (float)(4.0 / M_PI)); -_PS_EXTERN_CONST_TYPE(am_sign_mask, int32, 0x80000000); +_PS_EXTERN_CONST_TYPE(am_sign_mask, uint32, 0x80000000); _PS_EXTERN_CONST_TYPE(am_inv_sign_mask, int32, ~0x80000000); -_PS_EXTERN_CONST_TYPE(am_min_norm_pos,int32, 0x00800000); -_PS_EXTERN_CONST_TYPE(am_mant_mask, int32, 0x7f800000); +_PS_EXTERN_CONST_TYPE(am_min_norm_pos,uint32, 0x00800000); +_PS_EXTERN_CONST_TYPE(am_mant_mask, uint32, 0x7f800000); _PS_EXTERN_CONST_TYPE(am_inv_mant_mask, int32, ~0x7f800000); _EPI32_CONST(1, 1); @@ -204,9 +204,7 @@ float FASTCALL _SSE_VectorNormalize (Vector& vec) #endif float *v = &vec[0]; -#ifdef _WIN32 float *r = &result[0]; -#endif float radius = 0.f; // Blah, get rid of these comparisons ... in reality, if you have all 3 as zero, it shouldn't @@ -303,8 +301,8 @@ float _SSE_InvRSquared(const float* v) shufps xmm2, xmm2, 1 // x2 = vy * vy, X, X, X addss xmm1, xmm2 // x1 = (vx * vx) + (vy * vy), X, X, X addss xmm1, xmm3 // x1 = (vx * vx) + (vy * vy) + (vz * vz), X, X, X - maxss xmm1, xmm5 // x1 = max( 1.0, x1 ) - rcpss xmm0, xmm1 // x0 = 1 / max( 1.0, x1 ) + maxss xmm1, xmm5 // x1 = MAX( 1.0, x1 ) + rcpss xmm0, xmm1 // x0 = 1 / MAX( 1.0, x1 ) movss inv_r2, xmm0 // inv_r2 = x0 } #elif POSIX @@ -341,8 +339,8 @@ float _SSE_InvRSquared(const float* v) // #define _PS_CONST(Name, Val) static const ALIGN16 float _ps_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } #define _PS_CONST_TYPE(Name, Type, Val) static const ALIGN16 Type _ps_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } -_PS_CONST_TYPE(sign_mask, int, 0x80000000); -_PS_CONST_TYPE(inv_sign_mask, int, ~0x80000000); +_PS_CONST_TYPE(sign_mask, uint32, 0x80000000); +_PS_CONST_TYPE(inv_sign_mask, uint32, ~0x80000000); #define _PI32_CONST(Name, Val) static const ALIGN16 int _pi32_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } @@ -742,7 +740,6 @@ float _SSE_cos( float x ) //----------------------------------------------------------------------------- // SSE2 implementations of optimized routines: //----------------------------------------------------------------------------- -#ifdef PLATFORM_WINDOWS_PC32 void _SSE2_SinCos(float x, float* s, float* c) // any x { #ifdef _WIN32 @@ -828,9 +825,7 @@ void _SSE2_SinCos(float x, float* s, float* c) // any x #error "Not Implemented" #endif } -#endif // PLATFORM_WINDOWS_PC32 -#ifdef PLATFORM_WINDOWS_PC32 float _SSE2_cos(float x) { #ifdef _WIN32 @@ -888,9 +883,7 @@ float _SSE2_cos(float x) return x; } -#endif // PLATFORM_WINDOWS_PC32 -#if 0 // SSE Version of VectorTransform void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1) { @@ -948,9 +941,7 @@ void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1) #error "Not Implemented" #endif } -#endif -#if 0 void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ) { Assert( s_bMathlibInitialized ); @@ -1004,7 +995,6 @@ void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ) #error "Not Implemented" #endif } -#endif #ifdef _WIN32 void _declspec(naked) _SSE_VectorMA( const float *start, float scale, const float *direction, float *dest ) diff --git a/mathlib/sse.h b/mathlib/sse.h index 1b49c50c..72de1d3b 100644 --- a/mathlib/sse.h +++ b/mathlib/sse.h @@ -15,13 +15,9 @@ void FASTCALL _SSE_VectorNormalizeFast(Vector& vec); float _SSE_InvRSquared(const float* v); void _SSE_SinCos(float x, float* s, float* c); float _SSE_cos( float x); -#ifdef PLATFORM_WINDOWS_PC32 void _SSE2_SinCos(float x, float* s, float* c); float _SSE2_cos(float x); -#endif -#if 0 void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1); void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ); -#endif #endif // _SSE_H diff --git a/mathlib/sseconst.cpp b/mathlib/sseconst.cpp index 2f923193..d68588fd 100644 --- a/mathlib/sseconst.cpp +++ b/mathlib/sseconst.cpp @@ -38,19 +38,19 @@ const fltx4 g_QuatMultRowSign[4] = { -1.0f, -1.0f, -1.0f, 1.0f } }; -const int32 ALIGN16 g_SIMD_clear_signmask[4] ALIGN16_POST = {0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; -const int32 ALIGN16 g_SIMD_signmask[4] ALIGN16_POST = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; -const int32 ALIGN16 g_SIMD_lsbmask[4] ALIGN16_POST = { 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe }; -const int32 ALIGN16 g_SIMD_clear_wmask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0 }; -const int32 ALIGN16 g_SIMD_AllOnesMask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; // ~0,~0,~0,~0 -const int32 ALIGN16 g_SIMD_Low16BitsMask[4] ALIGN16_POST = { 0xffff, 0xffff, 0xffff, 0xffff }; // 0xffff x 4 - -const int32 ALIGN16 g_SIMD_ComponentMask[4][4] ALIGN16_POST = +const uint32 ALIGN16 g_SIMD_clear_signmask[4] ALIGN16_POST = {0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; +const uint32 ALIGN16 g_SIMD_signmask[4] ALIGN16_POST = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; +const uint32 ALIGN16 g_SIMD_lsbmask[4] ALIGN16_POST = { 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe }; +const uint32 ALIGN16 g_SIMD_clear_wmask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0 }; +const uint32 ALIGN16 g_SIMD_AllOnesMask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; // ~0,~0,~0,~0 +const uint32 ALIGN16 g_SIMD_Low16BitsMask[4] ALIGN16_POST = { 0xffff, 0xffff, 0xffff, 0xffff }; // 0xffff x 4 + +const uint32 ALIGN16 g_SIMD_ComponentMask[4][4] ALIGN16_POST = { { 0xFFFFFFFF, 0, 0, 0 }, { 0, 0xFFFFFFFF, 0, 0 }, { 0, 0, 0xFFFFFFFF, 0 }, { 0, 0, 0, 0xFFFFFFFF } }; -const int32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST = +const uint32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST = { { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, { 0xffffffff, 0x00000000, 0x00000000, 0x00000000 }, diff --git a/mathlib/ssenoise.cpp b/mathlib/ssenoise.cpp index 6ead1c8d..244a1e59 100644 --- a/mathlib/ssenoise.cpp +++ b/mathlib/ssenoise.cpp @@ -30,10 +30,6 @@ static ALIGN16 int32 idx_mask[4]= {0xffff, 0xffff, 0xffff, 0xffff}; // returns 0..1 static inline float GetLatticePointValue( int idx_x, int idx_y, int idx_z ) { - NOTE_UNUSED(perm_d); - NOTE_UNUSED(impulse_ycoords); - NOTE_UNUSED(impulse_zcoords); - int ret_idx = perm_a[idx_x & 0xff]; ret_idx = perm_b[( idx_y + ret_idx ) & 0xff]; ret_idx = perm_c[( idx_z + ret_idx ) & 0xff]; diff --git a/mathlib/vmatrix.cpp b/mathlib/vmatrix.cpp index 01a987b4..e99fae2a 100644 --- a/mathlib/vmatrix.cpp +++ b/mathlib/vmatrix.cpp @@ -955,7 +955,7 @@ void MatrixBuildTranslation( VMatrix& dst, const Vector &translation ) //----------------------------------------------------------------------------- void MatrixBuildRotationAboutAxis( VMatrix &dst, const Vector &vAxisOfRot, float angleDegrees ) { - MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, const_cast< matrix3x4_t &> ( dst.As3x4() ) ); + MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, dst.As3x4() ); dst[3][0] = 0; dst[3][1] = 0; dst[3][2] = 0; diff --git a/public/IDeferredExt.h b/public/IDeferredExt.h index ea8ca48a..fb44f00d 100644 --- a/public/IDeferredExt.h +++ b/public/IDeferredExt.h @@ -7,8 +7,9 @@ #include "tier1/interface.h" #endif -#include "../../public/mathlib/vector4d.h" -#include "../../public/mathlib/vmatrix.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/vmatrix.h" #include "materialsystem/itexture.h" struct lightData_Global_t @@ -17,17 +18,18 @@ struct lightData_Global_t { bEnabled = false; bShadow = false; - vecLight.Init(0, 0, 1); - + vecLight.Init( 0, 0, 1 ); light.Init(); ambient.Init(); sizes.Init(); }; - Vector4D light, ambient, sizes; - bool bEnabled; - bool bShadow; - Vector vecLight; + Vector4D light; + Vector4D ambient; + Vector4D sizes; + Vector4D vecLight; + bool bEnabled : 1; + bool bShadow : 1; }; #include "tier0/memdbgoff.h" @@ -138,4 +140,4 @@ FORCEINLINE CDeferredExtension *GetDeferredExt() } #endif -#endif \ No newline at end of file +#endif diff --git a/public/ScratchPadUtils.cpp b/public/ScratchPadUtils.cpp index dfb93b0d..6e020aaf 100644 --- a/public/ScratchPadUtils.cpp +++ b/public/ScratchPadUtils.cpp @@ -141,11 +141,11 @@ void CScratchPadGraph::UpdateTicksAndStuff( float flTime, float flValue ) // Extend the lines attached to the time labels. for ( int i=0; i < m_nTimeLabelsDrawn; i++ ) { - float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; + float flTimeLocl = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; m_pPad->DrawLine( - CSPVert((const Vector&) GetSamplePosition( flTime, m_flHighestValue )), - CSPVert((const Vector&) GetSamplePosition( flTime, flValue ) ) + CSPVert((const Vector&) GetSamplePosition( flTimeLocl, m_flHighestValue )), + CSPVert((const Vector&) GetSamplePosition( flTimeLocl, flValue ) ) ); } @@ -158,21 +158,21 @@ void CScratchPadGraph::UpdateTicksAndStuff( float flTime, float flValue ) { CTextParams params; - float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; + float flTimeLocl = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; params.m_bSolidBackground = true; - params.m_vPos = GetSamplePosition( flTime, m_flValueOrigin-5 ); + params.m_vPos = GetSamplePosition( flTimeLocl, m_flValueOrigin-5 ); params.m_bTwoSided = true; char str[512]; - Q_snprintf( str, sizeof( str ), "time: %.2f", flTime ); + Q_snprintf( str, sizeof( str ), "time: %.2f", flTimeLocl ); m_pPad->DrawText( str, params ); // Now draw the vertical line for the value.. m_pPad->DrawLine( - CSPVert( (const Vector&)GetSamplePosition( flTime, m_flValueOrigin ) ), - CSPVert( (const Vector&)GetSamplePosition( flTime, m_flHighestValue ) ) + CSPVert( (const Vector&)GetSamplePosition( flTimeLocl, m_flValueOrigin ) ), + CSPVert( (const Vector&)GetSamplePosition( flTimeLocl, m_flHighestValue ) ) ); diff --git a/public/SoundEmitterSystem/isoundemittersystembase.h b/public/SoundEmitterSystem/isoundemittersystembase.h index 77fbf0da..9cb6ee6a 100644 --- a/public/SoundEmitterSystem/isoundemittersystembase.h +++ b/public/SoundEmitterSystem/isoundemittersystembase.h @@ -264,9 +264,6 @@ abstract_class ISoundEmitterSystemBase : public IAppSystem virtual soundlevel_t LookupSoundLevelByHandle( char const *soundname, HSOUNDSCRIPTHANDLE& handle ) = 0; virtual void ReloadSoundEntriesInList( IFileList *pFilesToReload ) = 0; - - // Called by either client or server to force ModShutdown and ModInit - virtual void Flush() = 0; }; #endif // ISOUNDEMITTERSYSTEMBASE_H diff --git a/public/UtlCachedFileData.h b/public/UtlCachedFileData.h index 4420c21b..d7b0bc46 100644 --- a/public/UtlCachedFileData.h +++ b/public/UtlCachedFileData.h @@ -461,7 +461,7 @@ void CUtlCachedFileData::InitSmallBuffer( FileHandle_t& fh, int fileSize, boo // Read the element name char elementFileName[ 512 ]; - buf.GetString( elementFileName ); + buf.GetString( elementFileName, sizeof( elementFileName ) ); // Now read the element int slot = GetIndex( elementFileName ); @@ -561,7 +561,7 @@ void CUtlCachedFileData::InitLargeBuffer( FileHandle_t& fh, bool& deleteFile // Read the element name char elementFileName[ 512 ]; - buf.GetString( elementFileName ); + buf.GetString( elementFileName, sizeof( elementFileName ) ); // Now read the element int slot = GetIndex( elementFileName ); @@ -682,7 +682,7 @@ void CUtlCachedFileData::Save() fh = g_pFullFileSystem->Open( m_sRepositoryFileName, "wb" ); if ( FILESYSTEM_INVALID_HANDLE == fh ) { - ExecuteNTimes( 25, Warning( "Unable to persist cache '%s', check file permissions\n", m_sRepositoryFileName.String() ) ); + Warning( "Unable to persist cache '%s', check file permissions\n", m_sRepositoryFileName.String() ); } else { diff --git a/public/VGuiMatSurface/IMatSystemSurface.h b/public/VGuiMatSurface/IMatSystemSurface.h index 8d76b805..7e9d90fe 100644 --- a/public/VGuiMatSurface/IMatSystemSurface.h +++ b/public/VGuiMatSurface/IMatSystemSurface.h @@ -108,13 +108,6 @@ class IMatSystemSurface : public vgui::ISurface virtual void GetFullscreenViewportAndRenderTarget( int & x, int & y, int & w, int & h, ITexture **ppRenderTarget ) = 0; virtual void SetFullscreenViewportAndRenderTarget( int x, int y, int w, int h, ITexture *pRenderTarget ) = 0; - - // get texture id for a texture - virtual int DrawGetTextureId( ITexture *pTexture ) = 0; - - // begin and end skin composition painting - virtual void BeginSkinCompositionPainting() = 0; - virtual void EndSkinCompositionPainting() = 0; }; diff --git a/public/XUnzip.cpp b/public/XUnzip.cpp index e58f55b2..fbeb595e 100644 --- a/public/XUnzip.cpp +++ b/public/XUnzip.cpp @@ -1810,16 +1810,16 @@ uInt *v) // working area: values in order of bit length uInt f; // i repeats in table every f entries int g; // maximum code length int h; // table level - uInt i; // counter, current code - uInt j; // counter - int k; // number of bits in current code + register uInt i; // counter, current code + register uInt j; // counter + register int k; // number of bits in current code int l; // bits per table (returned in m) uInt mask; // (1 << w) - 1, to avoid cc -O bug on HP - uInt *p; // pointer into c[], b[], or v[] + register uInt *p; // pointer into c[], b[], or v[] inflate_huft *q; // points to current table struct inflate_huft_s r; // table entry for structure assignment inflate_huft *u[BMAX]; // table stack - int w; // bits before this table == (l * h) + register int w; // bits before this table == (l * h) uInt x[BMAX+1]; // bit offsets, then code stack uInt *xp; // pointer into x int y; // number of dummy codes added diff --git a/public/XZip.cpp b/public/XZip.cpp index 2aab2135..2b187a85 100644 --- a/public/XZip.cpp +++ b/public/XZip.cpp @@ -1470,7 +1470,7 @@ void send_bits(TState &state,int value, int length) */ unsigned bi_reverse(unsigned code, int len) { - unsigned res = 0; + register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; @@ -1571,7 +1571,7 @@ int longest_match (TState &state,IPos cur_match); */ void lm_init (TState &state, int pack_level, ush *flags) { - unsigned j; + register unsigned j; Assert(state,pack_level>=1 && pack_level<=8,"bad pack level"); @@ -1642,9 +1642,9 @@ void lm_init (TState &state, int pack_level, ush *flags) int longest_match(TState &state,IPos cur_match) { unsigned chain_length = state.ds.max_chain_length; /* max hash chain length */ - uch far *scan = state.ds.window + state.ds.strstart; /* current string */ - uch far *match; /* matched string */ - int len; /* length of current match */ + register uch far *scan = state.ds.window + state.ds.strstart; /* current string */ + register uch far *match; /* matched string */ + register int len; /* length of current match */ int best_len = state.ds.prev_length; /* best match length so far */ IPos limit = state.ds.strstart > (IPos)MAX_DIST ? state.ds.strstart - (IPos)MAX_DIST : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, @@ -1657,9 +1657,9 @@ int longest_match(TState &state,IPos cur_match) - uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; - uch scan_end1 = scan[best_len-1]; - uch scan_end = scan[best_len]; + register uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; + register uch scan_end1 = scan[best_len-1]; + register uch scan_end = scan[best_len]; /* Do not waste too much time if we already have a good match: */ if (state.ds.prev_length >= state.ds.good_match) { @@ -1747,7 +1747,7 @@ int longest_match(TState &state,IPos cur_match) */ void fill_window(TState &state) { - unsigned n, m; + register unsigned n, m; unsigned more; /* Amount of free space at the end of the window. */ do { @@ -1916,7 +1916,7 @@ ulg deflate(TState &state) IPos prev_match; /* previous match */ int flush; /* set if current block must be flushed */ int match_available = 0; /* set if previous match exists */ - unsigned match_length = MIN_MATCH-1; /* length of best match */ + register unsigned match_length = MIN_MATCH-1; /* length of best match */ if (state.level <= 3) return deflate_fast(state); /* optimized for speed */ diff --git a/public/appframework/ilaunchermgr.h b/public/appframework/ilaunchermgr.h index 4b433ad8..2498ab36 100644 --- a/public/appframework/ilaunchermgr.h +++ b/public/appframework/ilaunchermgr.h @@ -16,8 +16,13 @@ #include "appframework/IAppSystem.h" #if defined( DX_TO_GL_ABSTRACTION ) -#include "togl/linuxwin/glmgrbasics.h" -#include "togl/linuxwin/glmdisplay.h" + #if defined( LINUX ) || defined( _WIN32 ) + #include "togl/linuxwin/glmgrbasics.h" + #include "togl/linuxwin/glmdisplay.h" + #elif defined( OSX ) + #include "togl/osx/glmgrbasics.h" + #include "togl/osx/glmdisplay.h" + #endif class GLMDisplayDB; class CShowPixelsParams; diff --git a/public/bitmap/float_bm.h b/public/bitmap/float_bm.h index b4dfb160..73f090c5 100644 --- a/public/bitmap/float_bm.h +++ b/public/bitmap/float_bm.h @@ -46,10 +46,10 @@ inline PixRGBAF PixRGBA8_to_F( PixRGBA8 const &x ) inline PixRGBA8 PixRGBAF_to_8( PixRGBAF const &f ) { PixRGBA8 x; - x.Red = max( 0, min( 255.0,255.0*f.Red ) ); - x.Green = max( 0, min( 255.0,255.0*f.Green ) ); - x.Blue = max( 0, min( 255.0,255.0*f.Blue ) ); - x.Alpha = max( 0, min( 255.0,255.0*f.Alpha ) ); + x.Red = MAX( 0, MIN( 255.0,255.0*f.Red ) ); + x.Green = MAX( 0, MIN( 255.0,255.0*f.Green ) ); + x.Blue = MAX( 0, MIN( 255.0,255.0*f.Blue ) ); + x.Alpha = MAX( 0, MIN( 255.0,255.0*f.Alpha ) ); return x; } @@ -296,7 +296,7 @@ class FloatCubeMap_t if (face_maps[f].RGBAData) { nfaces++; - ret=max(ret,face_maps[f].BrightestColor()); + ret=MAX(ret,face_maps[f].BrightestColor()); } return ret; } diff --git a/public/bitmap/imageformat.h b/public/bitmap/imageformat.h index 3e8f7b13..4a6a8ce0 100644 --- a/public/bitmap/imageformat.h +++ b/public/bitmap/imageformat.h @@ -21,7 +21,7 @@ enum NormalDecodeMode_t }; // Forward declaration -#ifdef _WIN32 +#if defined(_WIN32) && _MSC_VER < 1900 typedef enum _D3DFORMAT D3DFORMAT; #endif @@ -100,13 +100,10 @@ enum ImageFormat IMAGE_FORMAT_LE_BGRA8888, #endif - IMAGE_FORMAT_DXT1_RUNTIME, - IMAGE_FORMAT_DXT5_RUNTIME, - NUM_IMAGE_FORMATS }; -#if defined( POSIX ) || defined( DX_TO_GL_ABSTRACTION ) +#if defined( POSIX ) || defined( DX_TO_GL_ABSTRACTION ) || _MSC_VER >= 1900 typedef enum _D3DFORMAT { D3DFMT_INDEX16, @@ -451,9 +448,6 @@ namespace ImageLoader int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma, int numLevels = 0 ); - // Low quality mipmap generation, but way faster. - void GenerateMipmapLevelsLQ( unsigned char* pSrc, unsigned char* pDst, int width, int height, - ImageFormat imageFormat, int numLevels ); //----------------------------------------------------------------------------- // operations on square images (src and dst can be the same) @@ -517,10 +511,6 @@ namespace ImageLoader return ( info.m_NumRedBits > 8 || info.m_NumGreeBits > 8 || info.m_NumBlueBits > 8 || info.m_NumAlphaBits > 8 ); } - inline bool IsRuntimeCompressed( ImageFormat fmt ) - { - return ( fmt == IMAGE_FORMAT_DXT1_RUNTIME ) || ( fmt == IMAGE_FORMAT_DXT5_RUNTIME ); - } } // end namespace ImageLoader diff --git a/public/bone_setup.cpp b/public/bone_setup.cpp index 4630c730..3cd59dbb 100644 --- a/public/bone_setup.cpp +++ b/public/bone_setup.cpp @@ -832,9 +832,9 @@ static void CalcZeroframeData( const CStudioHdr *pStudioHdr, const studiohdr_t * { s1 = clamp( (fFrame - index * animdesc.zeroframespan) / animdesc.zeroframespan, 0.0f, 1.0f ); } - int i0 = max( index - 1, 0 ); + int i0 = MAX( index - 1, 0 ); int i1 = index; - int i2 = min( index + 1, animdesc.zeroframecount - 1 ); + int i2 = MIN( index + 1, animdesc.zeroframecount - 1 ); for (j = 0; j < pAnimStudioHdr->numbones; j++) { if (pAnimGroup) @@ -2625,14 +2625,14 @@ class CIKSolver X[i] = P[i]; normalize(X); -// Its y axis is perpendicular to P, so Y = unit( E - X(EX) ). +// Its y axis is perpendicular to P, so Y = unit( E - X(E�X) ). float dDOTx = dot(D,X); for (i = 0 ; i < 3 ; i++) Y[i] = D[i] - dDOTx * X[i]; normalize(Y); -// Its z axis is perpendicular to both X and Y, so Z = XY. +// Its z axis is perpendicular to both X and Y, so Z = X�Y. cross(X,Y,Z); @@ -2798,8 +2798,8 @@ bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vecto // exaggerate knee targets for legs that are nearly straight // FIXME: should be configurable, and the ikKnee should be from the original animation, not modifed - float d = (targetFoot-worldThigh).Length() - min( l1, l2 ); - d = max( l1 + l2, d ); + float d = (targetFoot-worldThigh).Length() - MIN( l1, l2 ); + d = MAX( l1 + l2, d ); // FIXME: too short knee directions cause trouble d = d * 100; @@ -2819,7 +2819,7 @@ bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vecto // too close? // limit distance to about an 80 degree knee bend - float minDist = max( fabs(l1 - l2) * 1.15, min( l1, l2 ) * 0.15 ); + float minDist = MAX( fabs(l1 - l2) * 1.15, MIN( l1, l2 ) * 0.15 ); if (ikFoot.Length() < minDist) { // too close to get an accurate vector, just use original vector @@ -3283,7 +3283,7 @@ void CIKContext::AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, floa } else { - flCycle = max( 0.0, min( flCycle, 0.9999 ) ); + flCycle = MAX( 0.0, MIN( flCycle, 0.9999 ) ); } } @@ -3777,7 +3777,7 @@ void CIKContext::UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneTo pTarget->est.floor = Lerp( pRule->flRuleWeight, pTarget->est.floor, pRule->floor ); pTarget->est.radius = Lerp( pRule->flRuleWeight, pTarget->est.radius, pRule->radius ); //pTarget->est.latched = Lerp( pRule->flRuleWeight, pTarget->est.latched, pRule->latched ); - pTarget->est.latched = min( pTarget->est.latched, pRule->latched ); + pTarget->est.latched = MIN( pTarget->est.latched, pRule->latched ); pTarget->est.release = Lerp( pRule->flRuleWeight, pTarget->est.release, pRule->release ); pTarget->est.flWeight = Lerp( pRule->flRuleWeight, pTarget->est.flWeight, pRule->flWeight ); } @@ -3795,7 +3795,7 @@ void CIKContext::UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneTo if (pRule->latched > 0.0) pTarget->est.latched = 0.0; else - pTarget->est.latched = min( pTarget->est.latched, 1.0f - pRule->flWeight ); + pTarget->est.latched = MIN( pTarget->est.latched, 1.0f - pRule->flWeight ); } break; case IK_RELEASE: @@ -3804,7 +3804,7 @@ void CIKContext::UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneTo if (pRule->latched > 0.0) pTarget->est.latched = 0.0; else - pTarget->est.latched = min( pTarget->est.latched, 1.0f - pRule->flWeight ); + pTarget->est.latched = MIN( pTarget->est.latched, 1.0f - pRule->flWeight ); pTarget->est.flWeight = (pTarget->est.flWeight) * (1 - pRule->flWeight * pRule->flRuleWeight); } @@ -3970,11 +3970,11 @@ void CIKContext::AutoIKRelease( void ) float ft = m_flTime - pTarget->error.flErrorTime; if (dt < 0.25) { - pTarget->error.ramp = min( pTarget->error.ramp + ft * 4.0, 1.0 ); + pTarget->error.ramp = MIN( pTarget->error.ramp + ft * 4.0, 1.0 ); } else { - pTarget->error.ramp = max( pTarget->error.ramp - ft * 4.0, 0.0 ); + pTarget->error.ramp = MAX( pTarget->error.ramp - ft * 4.0, 0.0 ); } if (pTarget->error.ramp > 0.0) { @@ -4732,7 +4732,7 @@ void DoQuatInterpBone( // FIXME: a fast acos should be acceptable dot = clamp( dot, -1.f, 1.f ); weight[i] = 1 - (2 * acos( dot ) * pProc->pTrigger( i )->inv_tolerance ); - weight[i] = max( 0, weight[i] ); + weight[i] = MAX( 0, weight[i] ); scale += weight[i]; } @@ -5894,32 +5894,28 @@ int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAtta int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName ) { - if ( pStudioHdr ) + // binary search for the bone matching pName + int start = 0, end = pStudioHdr->numbones()-1; + const byte *pBoneTable = pStudioHdr->GetBoneTableSortedByName(); + mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); + while (start <= end) { - // binary search for the bone matching pName - int start = 0, end = pStudioHdr->numbones()-1; - const byte *pBoneTable = pStudioHdr->GetBoneTableSortedByName(); - mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); - while (start <= end) - { - int mid = (start + end) >> 1; - int cmp = Q_stricmp( pbones[pBoneTable[mid]].pszName(), pName ); + int mid = (start + end) >> 1; + int cmp = Q_stricmp( pbones[pBoneTable[mid]].pszName(), pName ); - if ( cmp < 0 ) - { - start = mid + 1; - } - else if ( cmp > 0 ) - { - end = mid - 1; - } - else - { - return pBoneTable[mid]; - } + if ( cmp < 0 ) + { + start = mid + 1; + } + else if ( cmp > 0 ) + { + end = mid - 1; + } + else + { + return pBoneTable[mid]; } } - return -1; } diff --git a/public/bspfile.h b/public/bspfile.h index 794b1e69..bff7b20a 100644 --- a/public/bspfile.h +++ b/public/bspfile.h @@ -32,8 +32,8 @@ #define MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER 35 // We can have larger lightmaps on displacements -#define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER 509 -#define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 512 +#define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER 125 +#define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 128 // This is the actual max.. (change if you change the brush lightmap dim or disp lightmap dim @@ -59,7 +59,11 @@ // 16 bit short limits #define MAX_MAP_MODELS 1024 #define MAX_MAP_BRUSHES 8192 +#ifdef MAPBASE +#define MAX_MAP_ENTITIES 65536 // According to ficool2, this limit is bogus/not enforced by the engine and can be "safely" raised. +#else #define MAX_MAP_ENTITIES 8192 +#endif #define MAX_MAP_TEXINFO 12288 #define MAX_MAP_TEXDATA 2048 #define MAX_MAP_DISPINFO 2048 @@ -90,9 +94,17 @@ #define MAX_MAP_LIGHTING 0x1000000 #define MAX_MAP_VISIBILITY 0x1000000 // increased BSPVERSION 7 #define MAX_MAP_TEXTURES 1024 +#ifdef MAPBASE +#define MAX_MAP_WORLDLIGHTS 65536 // According to ficool2, this limit is bogus/not enforced by the engine and can be "safely" raised. +#else #define MAX_MAP_WORLDLIGHTS 8192 +#endif #define MAX_MAP_CUBEMAPSAMPLES 1024 +#ifdef MAPBASE +#define MAX_MAP_OVERLAYS 8192 // According to ficool2, this limit is bogus/not enforced by the engine and can be "safely" raised. +#else #define MAX_MAP_OVERLAYS 512 +#endif #define MAX_MAP_WATEROVERLAYS 16384 #define MAX_MAP_TEXDATA_STRING_DATA 256000 #define MAX_MAP_TEXDATA_STRING_TABLE 65536 @@ -376,9 +388,7 @@ struct lump_t DECLARE_BYTESWAP_DATADESC(); int fileofs, filelen; int version; // default to zero - // this field was char fourCC[4] previously, but was unused, favoring the LUMP IDs above instead. It has been - // repurposed for compression. 0 implies the lump is not compressed. - int uncompressedSize; // default to zero + char fourCC[4]; // default to ( char )0, ( char )0, ( char )0, ( char )0 }; @@ -386,7 +396,7 @@ struct dheader_t { DECLARE_BYTESWAP_DATADESC(); int ident; - int version; + int version; lump_t lumps[HEADER_LUMPS]; int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6) }; @@ -421,7 +431,7 @@ struct dgamelumpheader_t // This is expected to be a four-CC code ('lump') typedef int GameLumpId_t; -// game lump is compressed, filelen reflects original size +// 360 only: game lump is compressed, filelen reflects original size // use next entry fileofs to determine actual disk lump compressed size // compression stage ensures a terminal null dictionary entry #define GAMELUMPFLAG_COMPRESSED 0x0001 diff --git a/public/bspflags.h b/public/bspflags.h index d4df43d1..74547c98 100644 --- a/public/bspflags.h +++ b/public/bspflags.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $Workfile: $ // $Date: $ @@ -36,14 +36,14 @@ #define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) #define CONTENTS_TESTFOGVOLUME 0x100 -#define CONTENTS_UNUSED 0x200 +#define CONTENTS_UNUSED 0x200 -// unused +// unused // NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS // if not visible, then grab from the bottom. #define CONTENTS_UNUSED6 0x400 -#define CONTENTS_TEAM1 0x800 // per team contents used to differentiate collisions +#define CONTENTS_TEAM1 0x800 // per team contents used to differentiate collisions #define CONTENTS_TEAM2 0x1000 // between players and objects on different teams // ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW @@ -93,7 +93,7 @@ #define SURF_BUMPLIGHT 0x0800 // calculate three lightmaps for the surface for bumpmapping #define SURF_NOSHADOWS 0x1000 // Don't receive shadows #define SURF_NODECALS 0x2000 // Don't receive decals -#define SURF_NOCHOP 0x4000 // Don't subdivide patches on this surface +#define SURF_NOCHOP 0x4000 // Don't subdivide patches on this surface #define SURF_HITBOX 0x8000 // surface is part of a hitbox @@ -147,6 +147,6 @@ #define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE) // Things projectile bullets should collide with -#define MASK_BULLETSCANTOUCH (MASK_ALL - CONTENTS_GRATE) +#define MASK_BULLETSCANTOUCH (MASK_ALL & ~CONTENTS_GRATE) #endif // BSPFLAGS_H diff --git a/public/cdll_int.h b/public/cdll_int.h index 3a1d763e..dd3e1e90 100644 --- a/public/cdll_int.h +++ b/public/cdll_int.h @@ -548,9 +548,6 @@ abstract_class IVEngineClient013 // returns the string name of the key to which this string is bound. Returns NULL if no such binding exists // Unlike Key_LookupBinding, leading '+' characters are not stripped from bindings. virtual const char *Key_LookupBindingExact( const char *pBinding ) = 0; - - virtual void AddPhonemeFile( const char *pszPhonemeFile ) = 0; - }; abstract_class IVEngineClient : public IVEngineClient013 diff --git a/public/collisionutils.cpp b/public/collisionutils.cpp index 2549a569..d26db4ab 100644 --- a/public/collisionutils.cpp +++ b/public/collisionutils.cpp @@ -228,7 +228,7 @@ int IntersectTriangleWithPlaneBarycentric( const Vector& org, const Vector& edge { pIntersection[ptIdx].x = - ( orgDotNormal - plane.w + edgeVDotNormal) / ( edgeUDotNormal - edgeVDotNormal); - pIntersection[ptIdx].y = 1.0f - pIntersection[ptIdx].x; + pIntersection[ptIdx].y = 1.0f - pIntersection[ptIdx].x;; if ((pIntersection[ptIdx].x >= 0.0f) && (pIntersection[ptIdx].x <= 1.0f) && (pIntersection[ptIdx].y >= 0.0f) && (pIntersection[ptIdx].y <= 1.0f)) ++ptIdx; diff --git a/public/const.h b/public/const.h index 0ed97e9e..105c0ef9 100644 --- a/public/const.h +++ b/public/const.h @@ -46,15 +46,7 @@ #define MAX_PLAYERS_PER_CLIENT 1 // One player per PC #endif -// Max decorated map name, with things like workshop/cp_foo.ugc123456 -#define MAX_MAP_NAME 96 - -// Max name used in save files. Needs to be left at 32 for SourceSDK compatibility. -#define MAX_MAP_NAME_SAVE 32 - -// Max non-decorated map name for e.g. server browser (just cp_foo) -#define MAX_DISPLAY_MAP_NAME 32 - +#define MAX_MAP_NAME 32 #define MAX_NETWORKID_LENGTH 64 // num chars for a network (i.e steam) ID // BUGBUG: Reconcile with or derive this from the engine's internal definition! @@ -258,7 +250,12 @@ enum SolidFlags_t FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects - FSOLID_MAX_BITS = 10 +#ifdef MAPBASE + // From https://developer.valvesoftware.com/wiki/Owner + FSOLID_COLLIDE_WITH_OWNER = 0X0400, +#endif + + FSOLID_MAX_BITS = 11 }; //----------------------------------------------------------------------------- @@ -443,5 +440,17 @@ class CThreadNullMutex; typedef CThreadNullMutex CSourceMutex; #endif +//Tony; added for IPlayerInfo V3. +//Putting all standard possible stances, but GetStance in CBasePlayer will only return standing or ducking by default - +//up to the mod to specify the others, or override what GetStance returns. +enum player_Stance +{ + PINFO_STANCE_STANDING = 0, + PINFO_STANCE_DUCKING, + + PINFO_STANCE_SPRINTING, + PINFO_STANCE_PRONE, +}; + #endif diff --git a/public/datamap.h b/public/datamap.h index 34a1caf8..b25bb172 100644 --- a/public/datamap.h +++ b/public/datamap.h @@ -313,6 +313,12 @@ struct datamap_t static datamap_t *GetBaseMap(); \ template friend void DataMapAccess(T *, datamap_t **p); \ template friend datamap_t *DataMapInit(T *); + +#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \ + static datamap_t m_DataMap; \ + static datamap_t *GetBaseMap(); \ + template friend void ::DataMapAccess(T *, datamap_t **p); \ + template friend datamap_t *::DataMapInit(T *); #define DECLARE_DATADESC() \ DECLARE_SIMPLE_DATADESC() \ @@ -414,6 +420,8 @@ inline void DataMapAccess(T *ignored, datamap_t **p) *p = &T::m_DataMap; } +template datamap_t* DataMapInit(T*); + //----------------------------------------------------------------------------- class CDatadescGeneratedNameHolder diff --git a/public/datamodel/dmattribute.h b/public/datamodel/dmattribute.h index e383eabf..e4441ff9 100644 --- a/public/datamodel/dmattribute.h +++ b/public/datamodel/dmattribute.h @@ -357,7 +357,7 @@ inline void CDmAttribute::SetValue( char *pValue ) inline void CDmAttribute::SetValue( const void *pValue, size_t nSize ) { - CUtlBinaryBlock buf( pValue, (int)nSize ); + CUtlBinaryBlock buf( pValue, nSize ); return SetValue( buf ); } @@ -599,7 +599,7 @@ inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, char *pVa inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const void *pValue, size_t nSize ) { - CUtlBinaryBlock buf( pValue, (int)nSize ); + CUtlBinaryBlock buf( pValue, nSize ); return SetValue( pAttributeName, buf ); } diff --git a/public/datamodel/dmattributetypes.h b/public/datamodel/dmattributetypes.h index 3a29caa5..fbff3ef7 100644 --- a/public/datamodel/dmattributetypes.h +++ b/public/datamodel/dmattributetypes.h @@ -11,7 +11,6 @@ #endif #include "tier1/utlvector.h" -#include "tier1/utlbinaryblock.h" #include "tier1/utlstring.h" #include "tier1/uniqueid.h" #include "Color.h" diff --git a/public/dt_utlvector_send.cpp b/public/dt_utlvector_send.cpp index b10170de..06f78c64 100644 --- a/public/dt_utlvector_send.cpp +++ b/public/dt_utlvector_send.cpp @@ -134,7 +134,7 @@ void* SendProxy_LengthTable( const SendProp *pProp, const void *pStructBase, con // Note: you have to be DILIGENT about calling NetworkStateChanged whenever an element in your CUtlVector changes // since CUtlVector doesn't do this automatically. SendProp SendPropUtlVector( - char *pVarName, // Use SENDINFO_UTLVECTOR to generate these 4. + const char *pVarName, // Use SENDINFO_UTLVECTOR to generate these 4. int offset, // Used to generate pData in the function specified in varProxy. int sizeofVar, // The size of each element in the utlvector. EnsureCapacityFn ensureFn, // This is the value returned for elements out of the array's current range. diff --git a/public/dt_utlvector_send.h b/public/dt_utlvector_send.h index f2ba68c3..3684d5b5 100644 --- a/public/dt_utlvector_send.h +++ b/public/dt_utlvector_send.h @@ -43,7 +43,7 @@ // ) // SendProp SendPropUtlVector( - char *pVarName, // Use SENDINFO_UTLVECTOR to generate these first 4 parameters. + const char *pVarName, // Use SENDINFO_UTLVECTOR to generate these first 4 parameters. int offset, int sizeofVar, EnsureCapacityFn ensureFn, diff --git a/public/edict.h b/public/edict.h index 37c701b4..67c558cd 100644 --- a/public/edict.h +++ b/public/edict.h @@ -343,8 +343,6 @@ inline void CBaseEdict::SetFree() m_fStateFlags |= FL_EDICT_FREE; } -// WARNING: Make sure you don't really want to call ED_ClearFreeFlag which will also -// remove this edict from the g_FreeEdicts bitset. inline void CBaseEdict::ClearFree() { m_fStateFlags &= ~FL_EDICT_FREE; diff --git a/public/eiface.h b/public/eiface.h index c7ca17c6..2dc83a22 100644 --- a/public/eiface.h +++ b/public/eiface.h @@ -59,7 +59,6 @@ class CGamestatsData; class CSteamID; class IReplayFactory; class IReplaySystem; -class IServer; typedef struct player_info_s player_info_t; @@ -73,10 +72,7 @@ typedef struct player_info_s player_info_t; #define DLLEXPORT /* */ #endif -#define INTERFACEVERSION_VENGINESERVER_VERSION_21 "VEngineServer021" -#define INTERFACEVERSION_VENGINESERVER_VERSION_22 "VEngineServer022" -#define INTERFACEVERSION_VENGINESERVER "VEngineServer023" -#define INTERFACEVERSION_VENGINESERVER_INT 23 +#define INTERFACEVERSION_VENGINESERVER "VEngineServer021" struct bbox_t { @@ -92,16 +88,16 @@ abstract_class IVEngineServer public: // Tell engine to change level ( "changelevel s1\n" or "changelevel2 s1 s2\n" ) virtual void ChangeLevel( const char *s1, const char *s2 ) = 0; - + // Ask engine whether the specified map is a valid map file (exists and has valid version number). virtual int IsMapValid( const char *filename ) = 0; - + // Is this a dedicated server? virtual bool IsDedicatedServer( void ) = 0; - + // Is in Hammer editing mode? virtual int IsInEditMode( void ) = 0; - + // Add to the server/client lookup/precache table, the specified string is given a unique index // NOTE: The indices for PrecacheModel are 1 based // a 0 returned from those methods indicates the model or sound was not correctly precached @@ -414,46 +410,12 @@ abstract_class IVEngineServer // Get sv.GetTime() virtual float GetServerTime() const = 0; - - // Exposed for server plugin authors - virtual IServer *GetIServer() = 0; - - virtual bool IsPlayerNameLocked( const edict_t *pEdict ) = 0; - virtual bool CanPlayerChangeName( const edict_t *pEdict ) = 0; - - // Find the canonical name of a map, given a partial or non-canonical map name. - // Except in the case of an exact match, pMapName is updated to the canonical name of the match. - // NOTE That this is subject to the same limitation as ServerGameDLL::CanProvideLevel -- This is non-blocking, so it - // is possible that blocking ServerGameDLL::PrepareLevelResources call may be able to pull a better match than - // is immediately available to this call (e.g. blocking lookups of cloud maps) - enum eFindMapResult { - // A direct match for this name was found - eFindMap_Found, - // No match for this map name could be found. - eFindMap_NotFound, - // A fuzzy match for this mapname was found and pMapName was updated to the full name. - // Ex: cp_dust -> cp_dustbowl - eFindMap_FuzzyMatch, - // A match for this map name was found, and the map name was updated to the canonical version of the - // name. - // Ex: workshop/1234 -> workshop/cp_qualified_name.ugc1234 - eFindMap_NonCanonical, - // No currently available match for this map name could be found, but it may be possible to load ( see caveat - // about PrepareLevelResources above ) - eFindMap_PossiblyAvailable - }; - virtual eFindMapResult FindMap( /* in/out */ char *pMapName, int nMapNameMax ) = 0; }; -// These only differ in new items added to the end -typedef IVEngineServer IVEngineServer021; -typedef IVEngineServer IVEngineServer022; - #define INTERFACEVERSION_SERVERGAMEDLL_VERSION_8 "ServerGameDLL008" -#define INTERFACEVERSION_SERVERGAMEDLL_VERSION_9 "ServerGameDLL009" -#define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL010" -#define INTERFACEVERSION_SERVERGAMEDLL_INT 10 +#define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL009" +#define INTERFACEVERSION_SERVERGAMEDLL_INT 9 class IServerGCLobby; @@ -581,54 +543,6 @@ abstract_class IServerGameDLL // Get gamedata string to send to the master serer updater. virtual const char *GetServerBrowserGameData() = 0; - - // Called to add output to the status command - virtual void Status( void (*print) (const char *fmt, ...) ) = 0; - - // Informs the game we would like to load this level, giving it a chance to prepare dynamic resources. - // - // - pszMapName is the name of the map we're looking for, and may be overridden to e.g. the canonical name of the - // map. - // - // - pszMapFile is the file we intend to use for this map ( e.g. maps/.bsp ), and may be overridden to the - // file representing this map name. ( e.g. /path/to/steamapps/workshop/cp_mymap.ugc12345.bsp ) - // - // This call is blocking, and may block for extended periods. See AsyncPrepareLevelResources below. - virtual void PrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize ) = 0; - - // Asynchronous version of PrepareLevelResources. Returns preparation status of map when called. - // If passed, flProgress is filled with the current progress percentage [ 0.f to 1.f ] for the InProgress - // result - enum ePrepareLevelResourcesResult - { - // Good to go - ePrepareLevelResources_Prepared, - // Game DLL is async preparing (e.g. streaming resources). flProgress will be filled if passed. - ePrepareLevelResources_InProgress - }; - virtual ePrepareLevelResourcesResult AsyncPrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize, - /* in/out */ char *pszMapFile, size_t nMapFileSize, - float *flProgress = NULL ) = 0; - - // Ask the game DLL to evaluate what it would do with this map name were it passed to PrepareLevelResources. - // NOTE That this is this is syncronous and non-blocking, so it is possible that async PrepareLevelResources call - // may be able to pull a better match than is immediately available to this call (e.g. blocking lookups of - // cloud maps) - enum eCanProvideLevelResult { - // Have no knowledge of this level name, it will be up to the engine to provide. (e.g. as maps/levelname.bsp) - eCanProvideLevel_CannotProvide, - // Can provide resources for this level, and pMapName has been updated to the canonical name we would provide it - // under (as with PrepareLevelResources) - eCanProvideLevel_CanProvide, - // We recognize this level name as something we might be able to prepare, but without a blocking/async call to - // PrepareLevelResources, it is not possible to say whether it is available. - eCanProvideLevel_Possibly - }; - virtual eCanProvideLevelResult CanProvideLevel( /* in/out */ char *pMapName, int nMapNameMax ) = 0; - - // Called to see if the game server is okay with a manual changelevel or map command - virtual bool IsManualMapChangeOkay( const char **pszReason ) = 0; }; typedef IServerGameDLL IServerGameDLL008; diff --git a/public/engine/IEngineSound.h b/public/engine/IEngineSound.h index ce8ac15b..f4f83a9c 100644 --- a/public/engine/IEngineSound.h +++ b/public/engine/IEngineSound.h @@ -43,7 +43,7 @@ class Vector; #define SNDLEVEL_FROM_COMPATIBILITY_MODE( x ) ((soundlevel_t)(int)( (x) - 256 )) // Tells if the given sndlevel is marked as compatibility mode. -#define SNDLEVEL_IS_COMPATIBILITY_MODE( x ) ( (x) >= soundlevel_t(256) ) +#define SNDLEVEL_IS_COMPATIBILITY_MODE( x ) ( (x) >= 256 ) diff --git a/public/engine/ishadowmgr.h b/public/engine/ishadowmgr.h index babac919..5165a8ab 100644 --- a/public/engine/ishadowmgr.h +++ b/public/engine/ishadowmgr.h @@ -40,6 +40,7 @@ enum ShadowFlags_t { SHADOW_FLAGS_FLASHLIGHT = (1 << 0), SHADOW_FLAGS_SHADOW = (1 << 1), + // Update this if you add flags SHADOW_FLAGS_LAST_FLAG = SHADOW_FLAGS_SHADOW }; diff --git a/public/fgdlib/gamedata.h b/public/fgdlib/gamedata.h index cf8b5be1..5d55db2f 100644 --- a/public/fgdlib/gamedata.h +++ b/public/fgdlib/gamedata.h @@ -88,6 +88,11 @@ class GameData bool RemapNameField( const char *pszInValue, char *pszOutValue, TNameFixup NameFixup ); bool LoadFGDMaterialExclusions( TokenReader &tr ); bool LoadFGDAutoVisGroups( TokenReader &tr ); + +#ifdef MAPBASE + // Sets up for additional instance remap fixes from Mapbase + void SetupInstanceRemapParams( int iStartNodes, int iStartBrushSide, bool bRemapVecLines ); +#endif CUtlVector< FGDMatExlcusions_s > m_FGDMaterialExclusions; @@ -109,6 +114,11 @@ class GameData matrix3x4_t m_InstanceMat; // matrix of the origin and rotation of rendering char m_InstancePrefix[ 128 ]; // the prefix used for the instance name remapping GDclass *m_InstanceClass; // the entity class that is being remapped +#ifdef MAPBASE + int m_InstanceStartAINodes; // the number of AI nodes in the level (for AI node remapping) + int m_InstanceStartSide; // the number of brush sides in the level (for brush side remapping) + bool m_bRemapVecLines; // allows ivVecLine to be remapped +#endif }; diff --git a/public/fgdlib/gdvar.h b/public/fgdlib/gdvar.h index 197ff30d..e6eb37fe 100644 --- a/public/fgdlib/gdvar.h +++ b/public/fgdlib/gdvar.h @@ -92,6 +92,14 @@ class GDinputvariable inline GDIV_TYPE GetType() { return m_eType; } const char *GetTypeText(void); + +#ifdef MAPBASE + // The FGD library normally enforces that variable types should always stay the same. + // The new AI node remapping code needs to change the "nodeid" keyvalue on AI nodes so + // it's properly recognized as a node ID which needs to be remapped. + // That's what this hack is for. + inline void ForceSetType( GDIV_TYPE newType ) { m_eType = newType; } +#endif inline void GetDefault(int *pnStore) { diff --git a/public/filesystem.h b/public/filesystem.h index 8571eb59..9ae55bcb 100644 --- a/public/filesystem.h +++ b/public/filesystem.h @@ -5,10 +5,6 @@ // $NoKeywords: $ //===========================================================================// -#ifndef FILESYSTEM_H -#define FILESYSTEM_H -#pragma once - #include #include "tier0/threadtools.h" @@ -21,6 +17,9 @@ #include "tier1/checksum_md5.h" #include "tier1/refcount.h" +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + #ifdef _WIN32 #pragma once #endif @@ -582,20 +581,10 @@ abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) = 0; // converts a partial path into a full path - // Prefer using the RelativePathToFullPath_safe template wrapper to calling this directly - virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; - template const char *RelativePathToFullPath_safe( const char *pFileName, const char *pPathID, OUT_Z_ARRAY char (&pDest)[maxLenInChars], PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) - { - return RelativePathToFullPath( pFileName, pPathID, pDest, (int)maxLenInChars, pathFilter, pPathType ); - } + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; // Returns the search path, each path is separated by ;s. Returns the length of the string returned - // Prefer using the GetSearchPath_safe template wrapper to calling this directly - virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; - template int GetSearchPath_safe( const char *pathID, bool bGetPackFiles, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) - { - return GetSearchPath( pathID, bGetPackFiles, pDest, (int)maxLenInChars ); - } + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) = 0; // interface for custom pack files > 4Gb virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0; @@ -662,21 +651,11 @@ abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem // FIXME: This method is obsolete! Use RelativePathToFullPath instead! // converts a partial path into a full path - // Prefer using the GetLocalPath_safe template wrapper to calling this directly - virtual const char *GetLocalPath( const char *pFileName, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; - template const char *GetLocalPath_safe( const char *pFileName, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) - { - return GetLocalPath( pFileName, pDest, (int)maxLenInChars ); - } + virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0; // Returns true on success ( based on current list of search paths, otherwise false if // it can't be resolved ) - // Prefer using the FullPathToRelativePath_safe template wrapper to calling this directly - virtual bool FullPathToRelativePath( const char *pFullpath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; - template bool FullPathToRelativePath_safe( const char *pFullpath, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) - { - return FullPathToRelativePath( pFullpath, pDest, (int)maxLenInChars ); - } + virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) = 0; // Gets the current working directory virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0; @@ -836,12 +815,7 @@ abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem virtual void EndMapAccess() = 0; // Returns true on success, otherwise false if it can't be resolved - // Prefer using the FullPathToRelativePathEx_safe template wrapper to calling this directly - virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) = 0; - template bool FullPathToRelativePathEx_safe( const char *pFullpath, OUT_Z_ARRAY char (&pDest)[maxLenInChars] ) - { - return FullPathToRelativePathEx( pFullpath, pDest, (int)maxLenInChars ); - } + virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0; virtual int GetPathIndex( const FileNameHandle_t &handle ) = 0; virtual long GetPathTime( const char *pPath, const char *pPathID ) = 0; @@ -918,14 +892,6 @@ abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem // Called when we unload a file, to remove that file's info for pure server purposes. virtual void NotifyFileUnloaded( const char *pszFilename, const char *pPathId ) = 0; - - // Returns true on successfully retrieve case-sensitive full path, otherwise false - // Prefer using the GetCaseCorrectFullPath template wrapper to calling this directly - virtual bool GetCaseCorrectFullPath_Ptr( const char *pFullPath, OUT_Z_CAP( maxLenInChars ) char *pDest, int maxLenInChars ) = 0; - template bool GetCaseCorrectFullPath( const char *pFullPath, OUT_Z_ARRAY char( &pDest )[maxLenInChars] ) - { - return GetCaseCorrectFullPath_Ptr( pFullPath, pDest, (int)maxLenInChars ); - } }; //----------------------------------------------------------------------------- diff --git a/public/filesystem_init.cpp b/public/filesystem_init.cpp index c1bcf3e1..36b484f5 100644 --- a/public/filesystem_init.cpp +++ b/public/filesystem_init.cpp @@ -86,7 +86,7 @@ class CTempEnvVar if ( pValue ) { m_bExisted = true; - m_OriginalValue.SetSize( Q_strlen( pValue ) + 1 ); + m_OriginalValue.SetSize( strlen( pValue ) + 1 ); memcpy( m_OriginalValue.Base(), pValue, m_OriginalValue.Count() ); } else @@ -982,6 +982,77 @@ bool DoesPathExistAlready( const char *pPathEnvVar, const char *pTestPath ) } } +FSReturnCode_t SetSteamInstallPath( char *steamInstallPath, int steamInstallPathLen, CSteamEnvVars &steamEnvVars, bool bErrorsAsWarnings ) +{ + if ( IsConsole() ) + { + // consoles don't use steam + return FS_MISSING_STEAM_DLL; + } + + if ( IsPosix() ) + return FS_OK; // under posix the content does not live with steam.dll up the path, rely on the environment already being set by steam + + // Start at our bin directory and move up until we find a directory with steam.dll in it. + char executablePath[MAX_PATH]; + if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) ) + { + if ( bErrorsAsWarnings ) + { + Warning( "SetSteamInstallPath: FileSystem_GetExecutableDir failed.\n" ); + return FS_INVALID_PARAMETERS; + } + else + { + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." ); + } + } + + Q_strncpy( steamInstallPath, executablePath, steamInstallPathLen ); +#ifdef WIN32 + const char *pchSteamDLL = "steam" DLL_EXT_STRING; +#elif defined(POSIX) + // under osx the bin lives in the bin/ folder, so step back one + Q_StripLastDir( steamInstallPath, steamInstallPathLen ); + const char *pchSteamDLL = "libsteam" DLL_EXT_STRING; +#else + #error +#endif + while ( 1 ) + { + // Ignore steamapp.cfg here in case they're debugging. We still need to know the real steam path so we can find their username. + // find + if ( DoesFileExistIn( steamInstallPath, pchSteamDLL ) && !DoesFileExistIn( steamInstallPath, "steamapp.cfg" ) ) + break; + + if ( !Q_StripLastDir( steamInstallPath, steamInstallPathLen ) ) + { + if ( bErrorsAsWarnings ) + { + Warning( "Can't find %s relative to executable path: %s.\n", pchSteamDLL, executablePath ); + return FS_MISSING_STEAM_DLL; + } + else + { + return SetupFileSystemError( false, FS_MISSING_STEAM_DLL, "Can't find %s relative to executable path: %s.", pchSteamDLL, executablePath ); + } + } + } + + // Also, add the install path to their PATH environment variable, so filesystem_steam.dll can get to steam.dll. + char szPath[ 8192 ]; + steamEnvVars.m_Path.GetValue( szPath, sizeof( szPath ) ); + if ( !DoesPathExistAlready( szPath, steamInstallPath ) ) + { +#ifdef WIN32 +#define PATH_SEP ";" +#else +#define PATH_SEP ":" +#endif + steamEnvVars.m_Path.SetValue( "%s%s%s", szPath, PATH_SEP, steamInstallPath ); + } + return FS_OK; +} FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen ) { @@ -1061,6 +1132,29 @@ void SetSteamUserPassphrase( KeyValues *pSteamInfo, CSteamEnvVars &steamEnvVars } } +FSReturnCode_t SetupSteamStartupEnvironment( KeyValues *pFileSystemInfo, const char *pGameInfoDirectory, CSteamEnvVars &steamEnvVars ) +{ + // Ok, we're going to run Steam. See if they have SteamInfo.txt. If not, we'll try to deduce what we can. + char steamInfoFile[MAX_PATH]; + Q_strncpy( steamInfoFile, pGameInfoDirectory, sizeof( steamInfoFile ) ); + Q_AppendSlash( steamInfoFile, sizeof( steamInfoFile ) ); + Q_strncat( steamInfoFile, "steaminfo.txt", sizeof( steamInfoFile ), COPY_ALL_CHARACTERS ); + KeyValues *pSteamInfo = ReadKeyValuesFile( steamInfoFile ); + + char steamInstallPath[MAX_PATH]; + FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, false ); + if ( ret != FS_OK ) + return ret; + + SetSteamAppUser( pSteamInfo, steamInstallPath, steamEnvVars ); + SetSteamUserPassphrase( pSteamInfo, steamEnvVars ); + + if ( pSteamInfo ) + pSteamInfo->deleteThis(); + + return FS_OK; +} + FSReturnCode_t FileSystem_SetBasePaths( IFileSystem *pFileSystem ) { pFileSystem->RemoveSearchPaths( "EXECUTABLE_PATH" ); @@ -1116,6 +1210,18 @@ FSReturnCode_t FileSystem_GetFileSystemDLLName( char *pFileSystemDLL, int nMaxLe return FS_OK; } +//----------------------------------------------------------------------------- +// Sets up the steam.dll install path in our PATH env var (so you can then just +// LoadLibrary() on filesystem_steam.dll without having to copy steam.dll anywhere special ) +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_SetupSteamInstallPath() +{ + CSteamEnvVars steamEnvVars; + char steamInstallPath[MAX_PATH]; + FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true ); + steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + return ret; +} //----------------------------------------------------------------------------- // Sets up the steam environment + gets back the gameinfo.txt path @@ -1135,6 +1241,42 @@ FSReturnCode_t FileSystem_SetupSteamEnvironment( CFSSteamSetupInfo &fsInfo ) #else setenv( GAMEDIR_TOKEN, fsInfo.m_GameInfoPath, 1 ); #endif + + CSteamEnvVars steamEnvVars; + if ( fsInfo.m_bSteam ) + { + if ( fsInfo.m_bToolsMode ) + { + // Now, load gameinfo.txt (to make sure it's there) + KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths; + ret = LoadGameInfoFile( fsInfo.m_GameInfoPath, pMainFile, pFileSystemInfo, pSearchPaths ); + if ( ret != FS_OK ) + return ret; + + // If filesystem_stdio.dll is missing or -steam is specified, then load filesystem_steam.dll. + // There are two command line parameters for Steam: + // 1) -steam (runs Steam in remote filesystem mode; requires Steam backend) + // 2) -steamlocal (runs Steam in local filesystem mode (all content off HDD) + + // Setup all the environment variables related to Steam so filesystem_steam.dll knows how to initialize Steam. + ret = SetupSteamStartupEnvironment( pFileSystemInfo, fsInfo.m_GameInfoPath, steamEnvVars ); + if ( ret != FS_OK ) + return ret; + + steamEnvVars.m_SteamAppId.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + + // We're done with main file + pMainFile->deleteThis(); + } + else if ( fsInfo.m_bSetSteamDLLPath ) + { + // This is used by the engine to automatically set the path to their steam.dll when running the engine, + // so they can debug it without having to copy steam.dll up into their hl2.exe folder. + char steamInstallPath[MAX_PATH]; + ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true ); + steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + } + } return FS_OK; } diff --git a/public/filesystem_init.h b/public/filesystem_init.h index 9274a5cb..d95e7c3a 100644 --- a/public/filesystem_init.h +++ b/public/filesystem_init.h @@ -209,6 +209,11 @@ void FileSystem_ClearSteamEnvVars(); // Find the steam.cfg above you for optional stuff FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen ); +// Setup the Steam.dll path without needing all the extra gameinfo stuff first +// used by the CSteamApplication::Create() code to LoadModule() on the filesystem +// before the underlying apps know specific details about the environment to load +FSReturnCode_t FileSystem_SetupSteamInstallPath(); + // Returns the last error. const char *FileSystem_GetLastErrorString(); diff --git a/public/filesystem_passthru.h b/public/filesystem_passthru.h index f4478b8d..b6f1d2c7 100644 --- a/public/filesystem_passthru.h +++ b/public/filesystem_passthru.h @@ -120,9 +120,8 @@ class CFileSystemPassThru : public CInternalFileSystemPassThru virtual const char *FindNext( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindNext( handle ); } virtual bool FindIsDirectory( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindIsDirectory( handle ); } virtual void FindClose( FileFindHandle_t handle ) { m_pFileSystemPassThru->FindClose( handle ); } - virtual const char *GetLocalPath( const char *pFileName, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pDest, maxLenInChars ); } - virtual bool FullPathToRelativePath( const char *pFullpath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pDest, maxLenInChars ); } - virtual bool GetCaseCorrectFullPath_Ptr( const char *pFullPath, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetCaseCorrectFullPath_Ptr( pFullPath, pDest, maxLenInChars ); } + virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pLocalPath, localPathBufferSize ); } + virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pRelative, maxlen ); } virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) { return m_pFileSystemPassThru->GetCurrentDirectory( pDirectory, maxlen ); } virtual void PrintOpenedFiles( void ) { m_pFileSystemPassThru->PrintOpenedFiles(); } virtual void PrintSearchPaths( void ) { m_pFileSystemPassThru->PrintSearchPaths(); } @@ -175,8 +174,8 @@ class CFileSystemPassThru : public CInternalFileSystemPassThru virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) { return m_pFileSystemPassThru->AsyncSetPriority(hControl, newPriority); } virtual bool AsyncSuspend() { return m_pFileSystemPassThru->AsyncSuspend(); } virtual bool AsyncResume() { return m_pFileSystemPassThru->AsyncResume(); } - virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pDest, maxLenInChars, pathFilter, pPathType ); } - virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pDest, maxLenInChars ); } + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pLocalPath, localPathBufferSize, pathFilter, pPathType ); } + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pPath, nMaxLen ); } virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) { return m_pFileSystemPassThru->OpenEx( pFileName, pOptions, flags, pathID, ppszResolvedFilename );} virtual int ReadEx( void* pOutput, int destSize, int size, FileHandle_t file ) { return m_pFileSystemPassThru->ReadEx( pOutput, destSize, size, file ); } @@ -209,7 +208,7 @@ class CFileSystemPassThru : public CInternalFileSystemPassThru virtual void EndMapAccess() { m_pFileSystemPassThru->EndMapAccess(); } virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadToBuffer( hFile, buf, nMaxBytes, pfnAlloc ); } - virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pDest, maxLenInChars ); } + virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, char *pRelative, int nMaxLen ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pRelative, nMaxLen ); } virtual int GetPathIndex( const FileNameHandle_t &handle ) { return m_pFileSystemPassThru->GetPathIndex( handle ); } virtual long GetPathTime( const char *pPath, const char *pPathID ) { return m_pFileSystemPassThru->GetPathTime( pPath, pPathID ); } diff --git a/public/gamebspfile.h b/public/gamebspfile.h index d9b1d2ac..f8029bae 100644 --- a/public/gamebspfile.h +++ b/public/gamebspfile.h @@ -36,7 +36,7 @@ enum { GAMELUMP_DETAIL_PROPS_VERSION = 4, GAMELUMP_DETAIL_PROP_LIGHTING_VERSION = 0, - GAMELUMP_STATIC_PROPS_VERSION = 10, + GAMELUMP_STATIC_PROPS_VERSION = 6, GAMELUMP_STATIC_PROP_LIGHTING_VERSION = 0, GAMELUMP_DETAIL_PROP_LIGHTING_HDR_VERSION = 0, }; @@ -139,9 +139,7 @@ enum STATIC_PROP_NO_SELF_SHADOWING = 0x80, // disable self shadowing in vrad - STATIC_PROP_NO_PER_TEXEL_LIGHTING = 0x100, // whether we should do per-texel lightmaps in vrad. - - STATIC_PROP_WC_MASK = 0x1d8, // all flags settable in hammer (?) + STATIC_PROP_WC_MASK = 0xd8, // all flags settable in hammer (?) }; struct StaticPropDictLump_t @@ -185,26 +183,6 @@ struct StaticPropLumpV5_t // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump }; -struct StaticPropLumpV6_t -{ - DECLARE_BYTESWAP_DATADESC(); - Vector m_Origin; - QAngle m_Angles; - unsigned short m_PropType; - unsigned short m_FirstLeaf; - unsigned short m_LeafCount; - unsigned char m_Solid; - unsigned char m_Flags; - int m_Skin; - float m_FadeMinDist; - float m_FadeMaxDist; - Vector m_LightingOrigin; - float m_flForcedFadeScale; - unsigned short m_nMinDXLevel; - unsigned short m_nMaxDXLevel; - // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump -}; - struct StaticPropLump_t { DECLARE_BYTESWAP_DATADESC(); @@ -214,6 +192,7 @@ struct StaticPropLump_t unsigned short m_FirstLeaf; unsigned short m_LeafCount; unsigned char m_Solid; + unsigned char m_Flags; int m_Skin; float m_FadeMinDist; float m_FadeMaxDist; @@ -222,59 +201,8 @@ struct StaticPropLump_t unsigned short m_nMinDXLevel; unsigned short m_nMaxDXLevel; // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump - unsigned int m_Flags; - unsigned short m_nLightmapResolutionX; - unsigned short m_nLightmapResolutionY; - - - StaticPropLump_t& operator=(const StaticPropLumpV4_t& _rhs) - { - m_Origin = _rhs.m_Origin; - m_Angles = _rhs.m_Angles; - m_PropType = _rhs.m_PropType; - m_FirstLeaf = _rhs.m_FirstLeaf; - m_LeafCount = _rhs.m_LeafCount; - m_Solid = _rhs.m_Solid; - m_Flags = _rhs.m_Flags; - m_Skin = _rhs.m_Skin; - m_FadeMinDist = _rhs.m_FadeMinDist; - m_FadeMaxDist = _rhs.m_FadeMaxDist; - m_LightingOrigin = _rhs.m_LightingOrigin; - - // These get potentially set twice--once here and once in the caller. - // Value judgement: This makes the code easier to work with, so unless it's a perf issue... - m_flForcedFadeScale = 1.0f; - m_nMinDXLevel = 0; - m_nMaxDXLevel = 0; - m_nLightmapResolutionX = 0; - m_nLightmapResolutionY = 0; - - // Older versions don't want this. - m_Flags |= STATIC_PROP_NO_PER_TEXEL_LIGHTING; - return *this; - } - - StaticPropLump_t& operator=(const StaticPropLumpV5_t& _rhs) - { - (*this) = reinterpret_cast(_rhs); - - m_flForcedFadeScale = _rhs.m_flForcedFadeScale; - return *this; - } - - StaticPropLump_t& operator=(const StaticPropLumpV6_t& _rhs) - { - (*this) = reinterpret_cast(_rhs); - - m_nMinDXLevel = _rhs.m_nMinDXLevel; - m_nMaxDXLevel = _rhs.m_nMaxDXLevel; - return *this; - } }; - - - struct StaticPropLeafLump_t { DECLARE_BYTESWAP_DATADESC(); diff --git a/public/haptics/haptic_utils.cpp b/public/haptics/haptic_utils.cpp index b9c72b2f..e6d3288a 100644 --- a/public/haptics/haptic_utils.cpp +++ b/public/haptics/haptic_utils.cpp @@ -138,6 +138,12 @@ void ConnectHaptics(CreateInterfaceFn appFactory) HookHapticMessages(); } +#if _MSC_VER >= 1925 +// deleting haptics results in a warning about deleting something with a non-virtual destructor +// big yikes but we can't do anything about it as it's accessed via interface +#pragma warning (disable: 5205) +#endif + void DisconnectHaptics() { haptics->ShutdownHaptics(); diff --git a/public/html/htmlmessages.h b/public/html/htmlmessages.h new file mode 100644 index 00000000..bfdc3475 --- /dev/null +++ b/public/html/htmlmessages.h @@ -0,0 +1,116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTMLMESSAGES_H +#define HTMLMESSAGES_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Commands we IPC across to the html thread and get responses for +//----------------------------------------------------------------------------- +enum EHTMLCommands +{ + // input events + eHTMLCommands_KeyUp, + eHTMLCommands_KeyDown, + eHTMLCommands_KeyChar, + eHTMLCommands_MouseDown, + eHTMLCommands_MouseUp, + eHTMLCommands_MouseDblClick, + eHTMLCommands_MouseWheel, + eHTMLCommands_MouseMove, + eHTMLCommands_MouseLeave, + + // command events + eHTMLCommands_BrowserCreate, + eHTMLCommands_BrowserRemove, + eHTMLCommands_BrowserErrorStrings, + eHTMLCommands_BrowserSize, + eHTMLCommands_BrowserPosition, + eHTMLCommands_PostURL, + eHTMLCommands_StopLoad, + eHTMLCommands_Reload, + eHTMLCommands_GoForward, + eHTMLCommands_GoBack, + eHTMLCommands_Copy, + eHTMLCommands_Paste, + eHTMLCommands_ExecuteJavaScript, + eHTMLCommands_SetFocus, + eHTMLCommands_HorizontalScrollBarSize, + eHTMLCommands_VerticalScrollBarSize, + eHTMLCommands_Find, + eHTMLCommands_StopFind, + eHTMLCommands_SetHorizontalScroll, + eHTMLCommands_SetVerticalScroll, + eHTMLCommands_SetZoomLevel, + eHTMLCommands_ViewSource, + eHTMLCommands_NeedsPaintResponse, + eHTMLCommands_AddHeader, + eHTMLCommands_GetZoom, + eHTMLCommands_FileLoadDialogResponse, + eHTMLCommands_LinkAtPosition, + eHTMLCommands_ZoomToElementAtPosition, + eHTMLCommands_SavePageToJPEG, + eHTMLCommands_JSAlert, + eHTMLCommands_JSConfirm, + eHTMLCommands_CanGoBackandForward, + eHTMLCommands_OpenSteamURL, + eHTMLCommands_SizePopup, + eHTMLCommands_SetCookie, + eHTMLCommands_SetTargetFrameRate, + eHTMLCommands_FullRepaint, + eHTMLCommands_SetPageScale, + eHTMLCommands_RequestFullScreen, + eHTMLCommands_ExitFullScreen, + eHTMLCommands_GetCookiesForURL, + eHTMLCommands_ZoomToCurrentlyFocusedNode, + eHTMLCommands_CloseFullScreenFlashIfOpen, + eHTMLCommands_PauseFullScreenFlashMovieIfOpen, + eHTMLCommands_GetFocusedNodeValue, + + // output back to the main thread + eHTMLCommands_BrowserCreateResponse, + eHTMLCommands_BrowserReady, + eHTMLCommands_URLChanged, + eHTMLCommands_FinishedRequest, + eHTMLCommands_StartRequest, + eHTMLCommands_ShowPopup, + eHTMLCommands_HidePopup, + eHTMLCommands_OpenNewTab, + eHTMLCommands_PopupHTMLWindow, + eHTMLCommands_PopupHTMLWindowResponse, + eHTMLCommands_SetHTMLTitle, + eHTMLCommands_LoadingResource, + eHTMLCommands_StatusText, + eHTMLCommands_SetCursor, + eHTMLCommands_FileLoadDialog, + eHTMLCommands_ShowToolTip, + eHTMLCommands_UpdateToolTip, + eHTMLCommands_HideToolTip, + eHTMLCommands_SearchResults, + eHTMLCommands_Close, + eHTMLCommands_VerticalScrollBarSizeResponse, + eHTMLCommands_HorizontalScrollBarSizeResponse, + eHTMLCommands_GetZoomResponse, + eHTMLCommands_StartRequestResponse, + eHTMLCommands_NeedsPaint, + eHTMLCommands_LinkAtPositionResponse, + eHTMLCommands_ZoomToElementAtPositionResponse, + eHTMLCommands_JSDialogResponse, + eHTMLCommands_ScaleToValueResponse, + eHTMLCommands_RequestFullScreenResponse, + eHTMLCommands_GetCookiesForURLResponse, + eHTMLCommands_NodeGotFocus, + eHTMLCommands_SavePageToJPEGResponse, + eHTMLCommands_GetFocusedNodeValueResponse, + + eHTMLCommands_None, + +}; + +#endif // HTMLMESSAGES_H \ No newline at end of file diff --git a/public/html/htmlprotobuf.cpp b/public/html/htmlprotobuf.cpp new file mode 100644 index 00000000..19822273 --- /dev/null +++ b/public/html/htmlprotobuf.cpp @@ -0,0 +1,70 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + + +#include "html/htmlprotobuf.h" +#include "tier0/vprof.h" +#include "tier0/valve_minmax_off.h" + + +#ifdef _WIN64 +// disable 64-bit warnings for the google headers +#pragma warning(push) +#pragma warning(disable:4244) // warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data +#pragma warning(disable:4267) // warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data +#endif + +#include "tier0/memdbgoff.h" +#include "protobuf-2.3.0/src/google/protobuf/message_lite.h" +#include "tier0/memdbgon.h" + +#ifdef _WIN64 +#pragma warning(pop) +#endif + +//----------------------------------------------------------------------------- +// Purpose: serialize a protobuf into a utlbuffer +//----------------------------------------------------------------------------- +void CHTMLBaseProtoBufMsg::SerializeCrossProc( CUtlBuffer *pBuffer ) const +{ + VPROF_BUDGET( "CUIProtoBufMsg::SerializeCrossProc", VPROF_BUDGETGROUP_OTHER_VGUI ); + uint32 unSize = ((google::protobuf::MessageLite *)m_pMsg)->ByteSize(); + + // Ensure enough for type, size, and serialized data + pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) * 3 + unSize ); // bugbug cboyd - drop to * 2 whenpassthrough is removed below + + pBuffer->PutUnsignedInt( unSize ); + + if ( unSize == 0 ) + return; + + uint8 *pBody = (uint8*)pBuffer->Base()+pBuffer->TellPut(); + ((google::protobuf::MessageLite *)m_pMsg)->SerializeWithCachedSizesToArray( pBody ); + pBuffer->SeekPut( CUtlBuffer::SEEK_CURRENT, unSize ); +} + + +//----------------------------------------------------------------------------- +// Purpose: grab a previously serialized protobuf +//----------------------------------------------------------------------------- +bool CHTMLBaseProtoBufMsg::BDeserializeCrossProc( CUtlBuffer *pBuffer ) +{ + VPROF_BUDGET( "CUIProtoBufMsg::BDeserialize", VPROF_BUDGETGROUP_OTHER_VGUI ); + if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint32) ) + return false; + uint32 unSize = pBuffer->GetUnsignedInt(); + + if ( unSize == 0 ) + return true; + + if ( pBuffer->GetBytesRemaining() < (int)unSize ) + return false; + + bool bSucccess = ((google::protobuf::MessageLite *)m_pMsg)->ParseFromArray( (uint8*)pBuffer->Base()+pBuffer->TellGet(), unSize ); + pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, unSize ); + + return bSucccess; +} + diff --git a/public/html/htmlprotobuf.h b/public/html/htmlprotobuf.h new file mode 100644 index 00000000..35d1d1d9 --- /dev/null +++ b/public/html/htmlprotobuf.h @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTML_PROTOBUF +#define HTML_PROTOBUF + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlbuffer.h" +#include "html/htmlmessages.h" + +namespace google +{ + namespace protobuf + { + class MessageLite; + } +} + +class CHTMLBaseProtoBufMsg +{ +public: + void SerializeCrossProc( CUtlBuffer *pBuffer ) const; + bool BDeserializeCrossProc( CUtlBuffer *pBuffer ); + +protected: + void *m_pMsg; + bool m_bIsValid; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Base class for protobuf objects +//----------------------------------------------------------------------------- +template< typename PB_OBJECT_TYPE > +class CHTMLProtoBufMsg : public CHTMLBaseProtoBufMsg +{ +public: + CHTMLProtoBufMsg( EHTMLCommands eMsg ) + { + m_pMsg = new PB_OBJECT_TYPE; + m_bIsValid = true; + } + + // Construct and deserialize in one + CHTMLProtoBufMsg( CUtlBuffer *pBuffer ) + { + m_pMsg = NULL; + m_bIsValid = BDeserializeCrossProc( pBuffer ); + } + + // Destructor + virtual ~CHTMLProtoBufMsg() + { + delete (PB_OBJECT_TYPE *)m_pMsg; + } + + bool BIsValid() { return m_bIsValid; } + + // Accessors + PB_OBJECT_TYPE &Body() { return *((PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } + const PB_OBJECT_TYPE &BodyConst() const { return *((const PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } + +}; + + +#endif // HTML_PROTOBUF diff --git a/public/html/ichromehtmlwrapper.h b/public/html/ichromehtmlwrapper.h new file mode 100644 index 00000000..d606ba05 --- /dev/null +++ b/public/html/ichromehtmlwrapper.h @@ -0,0 +1,63 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICHROMEHTMLWRAPPER_H +#define ICHROMEHTMLWRAPPER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include + +class CUtlString; +class IHTMLResponses; +struct HTMLCommandBuffer_t; + + +//------------------------------------------------------------- ---------------- +// Purpose: wrapper for HTML functionality +//----------------------------------------------------------------------------- +class IHTMLChromeController +{ +public: + virtual ~IHTMLChromeController() {} + + virtual bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) = 0; + virtual void Shutdown() = 0; + virtual bool RunFrame() = 0; + + + // set a cookie in the CEF instance. pchPath is typically "/". If nExpires is 0 then it is a session only cookie, other wise it is saved. + virtual void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires = 0 ) = 0; + virtual void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) = 0; + + virtual void SetClientBuildID( uint64 ulBuildID ) = 0; + + virtual bool BHasPendingMessages() = 0; + + virtual void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) = 0; + virtual void RemoveBrowser( IHTMLResponses *pBrowser ) = 0; + + virtual void WakeThread() = 0; + virtual HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) = 0; + virtual void PushCommand( HTMLCommandBuffer_t * ) = 0; + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ) = 0; + + virtual bool ChromePrepareForValidate() = 0; + virtual bool ChromeResumeFromValidate() = 0; +#endif + + virtual void SetCefThreadTargetFrameRate( uint32 nFPS ) = 0; +}; + +#define CHROMEHTML_CONTROLLER_INTERFACE_VERSION "ChromeHTML_Controller_001" + + +#endif // ICHROMEHTMLWRAPPER_H \ No newline at end of file diff --git a/public/html/ihtmlchrome.h b/public/html/ihtmlchrome.h new file mode 100644 index 00000000..b4b74355 --- /dev/null +++ b/public/html/ihtmlchrome.h @@ -0,0 +1,120 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef IHTMLCHROME_H +#define IHTMLCHROME_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "htmlmessages.h" +#include "tier1/utlbuffer.h" + +// prototypes for all the protobuf messages, so we don't need to include all of protobuf +class CMsgBrowserReady; +class CMsgNeedsPaint; +class CMsgStartRequest; +class CMsgURLChanged; +class CMsgFinishedRequest; +class CMsgShowPopup; +class CMsgHidePopup; +class CMsgOpenNewTab; +class CMsgPopupHTMLWindow; +class CMsgSetHTMLTitle; +class CMsgLoadingResource; +class CMsgStatusText; +class CMsgSetCursor; +class CMsgFileLoadDialog; +class CMsgShowToolTip; +class CMsgUpdateToolTip; +class CMsgHideToolTip; +class CMsgSearchResults; +class CMsgClose; +class CMsgHorizontalScrollBarSizeResponse; +class CMsgVerticalScrollBarSizeResponse; +class CMsgGetZoomResponse; +class CMsgLinkAtPositionResponse; +class CMsgZoomToElementAtPositionResponse; +class CMsgJSAlert; +class CMsgJSConfirm; +class CMsgCanGoBackAndForward; +class CMsgOpenSteamURL; +class CMsgSizePopup; +class CMsgScalePageToValueResponse; +class CMsgRequestFullScreen; +class CMsgExitFullScreen; +class CMsgGetCookiesForURLResponse; +class CMsgNodeHasFocus; +class CMsgSavePageToJPEGResponse; +class CMsgFocusedNodeTextResponse; + +//----------------------------------------------------------------------------- +// Purpose: a single IPC packet for the html thread (in and out) +//----------------------------------------------------------------------------- +struct HTMLCommandBuffer_t +{ + EHTMLCommands m_eCmd; + int m_iBrowser; + CUtlBuffer m_Buffer; +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const tchar *pchName ) + { + VALIDATE_SCOPE(); + ValidateObj( m_Buffer ); + } +#endif +}; + + +//----------------------------------------------------------------------------- +// Purpose: callback interfaces for messages from the html thread +//----------------------------------------------------------------------------- +class IHTMLResponses +{ +public: + virtual ~IHTMLResponses() {} + + virtual void BrowserSetIndex( int idx ) = 0; + virtual int BrowserGetIndex() = 0; + virtual void BrowserReady( const CMsgBrowserReady *pCmd ) = 0; + virtual void BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) = 0; + virtual void BrowserStartRequest( const CMsgStartRequest *pCmd ) = 0; + virtual void BrowserURLChanged( const CMsgURLChanged *pCmd ) = 0; + virtual void BrowserFinishedRequest( const CMsgFinishedRequest *pCmd ) = 0; + virtual void BrowserShowPopup( const CMsgShowPopup *pCmd ) = 0; + virtual void BrowserHidePopup( const CMsgHidePopup *pCmd ) = 0; + virtual void BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ) = 0; + virtual void BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ) = 0; + virtual void BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd ) = 0; + virtual void BrowserLoadingResource( const CMsgLoadingResource *pCmd ) = 0; + virtual void BrowserStatusText( const CMsgStatusText *pCmd ) = 0; + virtual void BrowserSetCursor( const CMsgSetCursor *pCmd ) = 0; + virtual void BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd ) = 0; + virtual void BrowserShowToolTip( const CMsgShowToolTip *pCmd ) = 0; + virtual void BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ) = 0; + virtual void BrowserHideToolTip( const CMsgHideToolTip *pCmd ) = 0; + virtual void BrowserSearchResults( const CMsgSearchResults *pCmd ) = 0; + virtual void BrowserClose( const CMsgClose *pCmd ) = 0; + virtual void BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd ) = 0; + virtual void BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd ) = 0; + virtual void BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ) = 0; + virtual void BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd ) = 0; + virtual void BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd ) = 0; + virtual void BrowserJSAlert( const CMsgJSAlert *pCmd ) = 0; + virtual void BrowserJSConfirm( const CMsgJSConfirm *pCmd ) = 0; + virtual void BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd ) = 0; + virtual void BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd ) = 0; + virtual void BrowserSizePopup( const CMsgSizePopup *pCmd ) = 0; + virtual void BrowserScalePageToValueResponse( const CMsgScalePageToValueResponse *pCmd ) = 0; + virtual void BrowserRequestFullScreen( const CMsgRequestFullScreen *pCmd ) = 0; + virtual void BrowserExitFullScreen( const CMsgExitFullScreen *pCmd ) = 0; + virtual void BrowserGetCookiesForURLResponse( const CMsgGetCookiesForURLResponse *pCmd ) = 0; + virtual void BrowserNodeGotFocus( const CMsgNodeHasFocus *pCmd ) = 0; + virtual void BrowserSavePageToJPEGResponse( const CMsgSavePageToJPEGResponse *pCmd ) = 0; + virtual void BrowserFocusedNodeValueResponse( const CMsgFocusedNodeTextResponse *pCmd ) = 0; +}; + +#endif // IHTMLCHROME_H diff --git a/public/html/ipainthtml.h b/public/html/ipainthtml.h new file mode 100644 index 00000000..9e47e23f --- /dev/null +++ b/public/html/ipainthtml.h @@ -0,0 +1,54 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef IPAINTHTML_H +#define IPAINTHTML_H + +class IPaintHTML +{ +public: + enum EPaintTarget + { + ePaintBrowser, + ePaintPopup, + ePaintMAX + }; + // returns the texture id used, pass in -1 to create a new texture + virtual int DrawSubTextureRGBA( EPaintTarget eTarget, int textureID, int x, int y, const unsigned char *pRGBA, int updateWide, int updateTall, int fullTextureWide, int fullTextureTall ) = 0; + virtual void DeleteTexture( EPaintTarget eTarget, int textureID ) = 0; +}; + +class IInputEventHTML +{ +public: + enum EMouseButton + { + eButtonLeft, + eButtonMiddle, + eButtonRight + }; + + virtual bool ChromeHandleMouseClick( EMouseButton eButton, bool bUp, int nClickCount ) = 0; + virtual bool ChromeHandleMouseMove( int x, int y ) = 0; + virtual bool ChromeHandleMouseWheel( int delta ) = 0; + + enum EKeyType + { + KeyDown, + KeyUp, + Char + }; + enum EKeyModifier + { + AltDown = 1, + CrtlDown = 2, + ShiftDown = 4, + }; + + virtual bool ChromeHandleKeyEvent( EKeyType type, int key, int modifiers, bool bKeyUp ) = 0; +}; + +#endif // IPAINTHTML_H \ No newline at end of file diff --git a/public/ibsppack.h b/public/ibsppack.h index 3f115d78..7ecaa780 100644 --- a/public/ibsppack.h +++ b/public/ibsppack.h @@ -28,13 +28,6 @@ abstract_class IBSPPack virtual void SetHDRMode( bool bHDR ) = 0; virtual bool SwapBSPFile( IFileSystem *pFileSystem, const char *filename, const char *swapFilename, bool bSwapOnLoad, VTFConvertFunc_t pVTFConvertFunc, VHVFixupFunc_t pVHVFixupFunc, CompressFunc_t pCompressFunc ) = 0; - enum eRepackBSPFlags - { - eRepackBSP_CompressLumps = 1 << 0, - eRepackBSP_CompressPackfile = 1 << 1 - }; - virtual bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, eRepackBSPFlags repackFlags ) = 0; - // used to get/set the pak file from a BSP virtual bool GetPakFileLump( IFileSystem *pFileSystem, const char *pBSPFilename, void **pPakData, int *pPakSize ) = 0; virtual bool SetPakFileLump( IFileSystem *pFileSystem, const char *pBSPFilename, const char *pNewFilename, void *pPakData, int pakSize ) = 0; @@ -43,6 +36,6 @@ abstract_class IBSPPack virtual bool GetBSPDependants( IFileSystem *pFileSystem, const char *pBSPFilename, CUtlVector< CUtlString > *pList ) = 0; }; -#define IBSPPACK_VERSION_STRING "IBSPPACK004" +#define IBSPPACK_VERSION_STRING "IBSPPACK003" #endif // IBSPPACK_H diff --git a/public/iclientnetworkable.h b/public/iclientnetworkable.h index 6ecb362b..434a276b 100644 --- a/public/iclientnetworkable.h +++ b/public/iclientnetworkable.h @@ -99,8 +99,6 @@ abstract_class IClientNetworkable // Tells the entity that it's about to be destroyed due to the client receiving // an uncompressed update that's caused it to destroy all entities & recreate them. virtual void SetDestroyedOnRecreateEntities( void ) = 0; - - virtual void OnDataUnchangedInPVS() = 0; }; diff --git a/public/icvar.h b/public/icvar.h index 8eaa48a5..369adc58 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -87,9 +87,9 @@ abstract_class ICvar : public IAppSystem // Install a console printer virtual void InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; virtual void RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; - virtual void ConsoleColorPrintf( const Color& clr, PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 3, 4 ) = 0; - virtual void ConsolePrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 2, 3 ) = 0; - virtual void ConsoleDPrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const FMTFUNCTION( 2, 3 ) = 0; + virtual void ConsoleColorPrintf( const Color& clr, PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + virtual void ConsolePrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + virtual void ConsoleDPrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; // Reverts cvars which contain a specific flag virtual void RevertFlaggedConVars( int nFlag ) = 0; diff --git a/public/ispatialpartition.h b/public/ispatialpartition.h index ff9bd7da..6b6678f7 100644 --- a/public/ispatialpartition.h +++ b/public/ispatialpartition.h @@ -83,9 +83,6 @@ class IPartitionEnumerator { public: virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ) = 0; - // XXX(johns): This should have a virtual destructor, but would be ABI breaking (non-versioned interface implemented - // by the game) - // virtual ~IPartitionEnumerator(){} }; diff --git a/public/istudiorender.h b/public/istudiorender.h index 6be93c90..f0af6115 100644 --- a/public/istudiorender.h +++ b/public/istudiorender.h @@ -178,16 +178,6 @@ struct DrawModelResults_t CUtlVectorFixed m_Materials; }; -struct ColorTexelsInfo_t -{ - int m_nWidth; - int m_nHeight; - int m_nMipmapCount; - ImageFormat m_ImageFormat; - int m_nByteCount; - byte* m_pTexelData; -}; - struct ColorMeshInfo_t { // A given color mesh can own a unique Mesh, or it can use a shared Mesh @@ -196,8 +186,6 @@ struct ColorMeshInfo_t IPooledVBAllocator * m_pPooledVBAllocator; int m_nVertOffsetInBytes; int m_nNumVerts; - ITexture * m_pLightmap; - ColorTexelsInfo_t * m_pLightmapData; }; struct DrawModelInfo_t diff --git a/public/jigglebones.cpp b/public/jigglebones.cpp index 29b8647d..10038e58 100644 --- a/public/jigglebones.cpp +++ b/public/jigglebones.cpp @@ -23,7 +23,7 @@ ConVar cl_jiggle_bone_debug_yaw_constraints( "cl_jiggle_bone_debug_yaw_constrain ConVar cl_jiggle_bone_debug_pitch_constraints( "cl_jiggle_bone_debug_pitch_constraints", "0", FCVAR_CHEAT, "Display physics-based 'jiggle bone' debugging information" ); #endif // CLIENT_DLL -ConVar cl_jiggle_bone_framerate_cutoff( "cl_jiggle_bone_framerate_cutoff", "20", 0, "Skip jiggle bone simulation if framerate drops below this value (frames/second)" ); +ConVar cl_jiggle_bone_framerate_cutoff( "cl_jiggle_bone_framerate_cutoff", "45", 0, "Skip jiggle bone simulation if framerate drops below this value (frames/second)" ); //----------------------------------------------------------------------------- @@ -40,10 +40,6 @@ JiggleData * CJiggleBones::GetJiggleData( int bone, float currenttime, const Vec JiggleData data; data.Init( bone, currenttime, initBasePos, initTipPos ); - // Start out using jiggle bones for at least 16 frames. - data.useGoalMatrixCount = 0; - data.useJiggleBoneCount = 16; - int idx = m_jiggleBoneState.AddToHead( data ); if ( idx == m_jiggleBoneState.InvalidIndex() ) return NULL; @@ -100,40 +96,11 @@ void CJiggleBones::BuildJiggleTransformations( int boneIndex, float currenttime, float deltaT = currenttime - data->lastUpdate; const float thousandHZ = 0.001f; - bool bMaxDeltaT = deltaT < thousandHZ; - bool bUseGoalMatrix = cl_jiggle_bone_framerate_cutoff.GetFloat() <= 0.0f || deltaT > ( 1.0f / cl_jiggle_bone_framerate_cutoff.GetFloat() ); - - if ( bUseGoalMatrix ) - { - // We hit the jiggle bone framerate cutoff. Reset the useGoalMatrixCount so we - // use the goal matrix at least 32 frames and don't flash back and forth. - data->useGoalMatrixCount = 32; - } - else if ( data->useGoalMatrixCount > 0 ) - { - // Below the cutoff, but still need to use the goal matrix a few more times. - bUseGoalMatrix = true; - data->useGoalMatrixCount--; - } - else - { - // Use real jiggle bones. Woot! - data->useJiggleBoneCount = 32; - } - - if ( data->useJiggleBoneCount > 0 ) - { - // Make sure we draw at least runs of 32 frames with real jiggle bones. - data->useJiggleBoneCount--; - data->useGoalMatrixCount = 0; - bUseGoalMatrix = false; - } - - if ( bMaxDeltaT ) + if ( deltaT < thousandHZ ) { deltaT = thousandHZ; } - else if ( bUseGoalMatrix ) + else if ( cl_jiggle_bone_framerate_cutoff.GetFloat() <= 0.0f || deltaT > ( 1.0f / cl_jiggle_bone_framerate_cutoff.GetFloat() ) ) { // disable jigglebone - just use goal matrix boneMX = goalMX; diff --git a/public/jigglebones.h b/public/jigglebones.h index 037a4866..57afdaa7 100644 --- a/public/jigglebones.h +++ b/public/jigglebones.h @@ -65,9 +65,6 @@ struct JiggleData Vector boingVelDir; // current estimation of jiggle bone unit velocity vector for boing effect float boingSpeed; // current estimation of jiggle bone speed for boing effect float boingTime; - - int useGoalMatrixCount; // Count of times we need to fast draw using goal matrix. - int useJiggleBoneCount; // Count of times we need to draw using real jiggly bones. }; class CJiggleBones diff --git a/public/keyframe/keyframe.cpp b/public/keyframe/keyframe.cpp index 1e08b0a3..425a172e 100644 --- a/public/keyframe/keyframe.cpp +++ b/public/keyframe/keyframe.cpp @@ -154,7 +154,7 @@ class CPositionInterpolator_Linear : public IPositionInterpolator { public: virtual void Release(); - virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ); virtual void SetKeyPosition( int keyNum, Vector const &vPos ); virtual void InterpolatePosition( float time, Vector &vOut ); virtual bool ProcessKey( char const *pName, char const *pValue ) { return false; } @@ -171,7 +171,7 @@ void CPositionInterpolator_Linear::Release() { } -void CPositionInterpolator_Linear::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +void CPositionInterpolator_Linear::GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ) { *outName = "Linear"; *outMinKeyReq = 0; @@ -201,7 +201,7 @@ class CPositionInterpolator_CatmullRom : public IPositionInterpolator { public: virtual void Release(); - virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ); virtual void SetKeyPosition( int keyNum, Vector const &vPos ); virtual void InterpolatePosition( float time, Vector &vOut ); virtual bool ProcessKey( char const *pName, char const *pValue ) { return false; } @@ -218,7 +218,7 @@ void CPositionInterpolator_CatmullRom::Release() { } -void CPositionInterpolator_CatmullRom::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +void CPositionInterpolator_CatmullRom::GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ) { *outName = "Catmull-Rom Spline"; *outMinKeyReq = -1; @@ -282,7 +282,7 @@ class CPositionInterpolator_Rope : public IPositionInterpolator CPositionInterpolator_Rope(); virtual void Release(); - virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ); virtual void SetKeyPosition( int keyNum, Vector const &vPos ); virtual void InterpolatePosition( float time, Vector &vOut ); virtual bool ProcessKey( char const *pName, char const *pValue ); @@ -319,7 +319,7 @@ void CPositionInterpolator_Rope::Release() delete this; } -void CPositionInterpolator_Rope::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +void CPositionInterpolator_Rope::GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ) { *outName = "Rope"; *outMinKeyReq = 0; @@ -433,7 +433,7 @@ typedef void (*RotationInterpolatorFunc_t)(float time, Quaternion &outRot); typedef struct { - char *szName; + const char *szName; RotationInterpolatorFunc_t pFunc; // defines the range of keys this interpolator needs to function @@ -458,7 +458,7 @@ int Motion_GetNumberOfRotationInterpolators( void ) return ARRAYSIZE(g_RotationInterpolators); } -bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, const char **outName, int *outMinKeyReq, int *outMaxKeyReq ) { if ( rotInterpNum < 0 || rotInterpNum >= Motion_GetNumberOfRotationInterpolators() ) { diff --git a/public/keyframe/keyframe.h b/public/keyframe/keyframe.h index b2cfd27c..4ee04824 100644 --- a/public/keyframe/keyframe.h +++ b/public/keyframe/keyframe.h @@ -14,7 +14,7 @@ class IPositionInterpolator public: virtual void Release() = 0; - virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) = 0; + virtual void GetDetails( const char **outName, int *outMinKeyReq, int *outMaxKeyReq ) = 0; virtual void SetKeyPosition( int keyNum, Vector const &vPos ) = 0; virtual void InterpolatePosition( float time, Vector &vOut ) = 0; @@ -34,7 +34,7 @@ IPositionInterpolator* Motion_GetPositionInterpolator( int interpNum ); // Rotation interpolators. int Motion_GetNumberOfRotationInterpolators( void ); -bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, char **outName, int *outMinKeyReq, int *outMaxKeyReq ); +bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, const char **outName, int *outMinKeyReq, int *outMaxKeyReq ); bool Motion_InterpolateRotation( float time, int interpFuncNum, Quaternion &outQuatRotation ); bool Motion_SetKeyAngles( int keyNum, Quaternion &quatAngles ); diff --git a/public/loadcmdline.cpp b/public/loadcmdline.cpp index 30c616f3..1df30efb 100644 --- a/public/loadcmdline.cpp +++ b/public/loadcmdline.cpp @@ -22,7 +22,8 @@ static void AddArguments( int &argc, char **&argv, const char *str ) char *argList = 0; int argCt = argc; - argList = V_strdup( str ); + argList = new char[ Q_strlen( str ) + 1 ]; + Q_strcpy( argList, str ); // Parse the arguments out of the string char *token = strtok( argList, " " ); @@ -44,7 +45,8 @@ static void AddArguments( int &argc, char **&argv, const char *str ) int i; for( i = 0; i < argc - 1; ++i ) { - args[ i ] = V_strdup( argv[ i ] ); + args[ i ] = new char[ Q_strlen( argv[ i ] ) + 1 ]; + Q_strcpy( args[ i ], argv[ i ] ); } // copy new arguments @@ -52,12 +54,14 @@ static void AddArguments( int &argc, char **&argv, const char *str ) token = strtok( argList, " " ); for( ; i < argCt - 1; ++i ) { - args[ i ] = V_strdup( token ); + args[ i ] = new char[ Q_strlen( token ) + 1 ]; + Q_strcpy( args[ i ], token ); token = strtok( NULL, " " ); } // Copy the last original argument - args[ i ] = V_strdup( argv[ argc - 1 ] ); + args[ i ] = new char[ Q_strlen( argv[ argc - 1 ] ) + 1 ]; + Q_strcpy( args[ i ], argv[ argc - 1 ] ); argc = argCt; argv = args; @@ -116,4 +120,4 @@ void DeleteCmdLine( int argc, char **argv ) delete [] argv[i]; } delete [] argv; -} +} \ No newline at end of file diff --git a/public/materialsystem/IShader.h b/public/materialsystem/IShader.h index 7815e8aa..27bf91e3 100644 --- a/public/materialsystem/IShader.h +++ b/public/materialsystem/IShader.h @@ -21,9 +21,8 @@ // it's not 256, because you can't use all 256 slots in 10.5.x. // use this constant everywhere you might normally use "256" in reference to a parameter array size. // The highest shader constant is c218, plus we allocate c219 and c220 for two clip planes -#define DXABSTRACT_VS_PARAM_SLOTS 228 +#define DXABSTRACT_VS_PARAM_SLOTS 219 #define DXABSTRACT_VS_FIRST_BONE_SLOT VERTEX_SHADER_MODEL -#define DXABSTRACT_VS_LAST_BONE_SLOT (VERTEX_SHADER_SHADER_SPECIFIC_CONST_13-1) // user clip plane 0 goes in DXABSTRACT_VS_CLIP_PLANE_BASE... plane 1 goes in the slot after that // dxabstract uses these constants to check plane index limit and to deliver planes to shader for DP4 -> oCLP[n] @@ -34,8 +33,6 @@ #include "materialsystem/imaterialsystem.h" #include "materialsystem/ishaderapi.h" -#include "materialsystem/ishadersystem_declarations.h" - //----------------------------------------------------------------------------- // forward declarations @@ -46,6 +43,24 @@ class IShaderDynamicAPI; class IShaderInit; class CBasePerMaterialContextData; +//----------------------------------------------------------------------------- +// Shader flags +//----------------------------------------------------------------------------- +enum ShaderFlags_t +{ + SHADER_NOT_EDITABLE = 0x1 +}; + + +//----------------------------------------------------------------------------- +// Shader parameter flags +//----------------------------------------------------------------------------- +enum ShaderParamFlags_t +{ + SHADER_PARAM_NOT_EDITABLE = 0x1 +}; + + //----------------------------------------------------------------------------- // Information about each shader parameter //----------------------------------------------------------------------------- @@ -59,10 +74,72 @@ struct ShaderParamInfo_t }; +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_MATH_CONSTANTS0 = 0, + VERTEX_SHADER_MATH_CONSTANTS1 = 1, + VERTEX_SHADER_CAMERA_POS = 2, + VERTEX_SHADER_FLEXSCALE = 3, // used by DX9 only! + VERTEX_SHADER_LIGHT_INDEX = 3, // used by DX8 only! + VERTEX_SHADER_MODELVIEWPROJ = 4, + VERTEX_SHADER_VIEWPROJ = 8, + VERTEX_SHADER_MODELVIEWPROJ_THIRD_ROW = 12, + VERTEX_SHADER_VIEWPROJ_THIRD_ROW = 13, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 = 14, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_11 = 15, + VERTEX_SHADER_FOG_PARAMS = 16, + VERTEX_SHADER_VIEWMODEL = 17, + VERTEX_SHADER_AMBIENT_LIGHT = 21, + VERTEX_SHADER_LIGHTS = 27, + VERTEX_SHADER_LIGHT0_POSITION = 29, + VERTEX_SHADER_MODULATION_COLOR = 47, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 = 48, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_1 = 49, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 = 50, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 = 51, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 = 52, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 = 53, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 = 54, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_7 = 55, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_8 = 56, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_9 = 57, + VERTEX_SHADER_MODEL = 58, + + // + // We reserve up through 216 for the 53 bones + // + + // 219 ClipPlane0 |------ OpenGL will jam clip planes into these two + // 220 ClipPlane1 | + + VERTEX_SHADER_FLEX_WEIGHTS = 1024, + VERTEX_SHADER_MAX_FLEX_WEIGHT_COUNT = 512, +}; #define VERTEX_SHADER_BONE_TRANSFORM( k ) ( VERTEX_SHADER_MODEL + 3 * (k) ) - +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST = 0, + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST_COUNT = 4, + + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0 = 4, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_1 = 5, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_2 = 6, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_3 = 7, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_4 = 8, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_5 = 9, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_6 = 10, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_7 = 11, +}; // The public methods exposed by each shader //----------------------------------------------------------------------------- abstract_class IShader @@ -102,4 +179,27 @@ abstract_class IShader // virtual const ShaderParamInfo_t& GetParamInfo( int paramIndex ) const = 0; }; + +//----------------------------------------------------------------------------- +// Shader dictionaries defined in DLLs +//----------------------------------------------------------------------------- +enum PrecompiledShaderType_t +{ + PRECOMPILED_VERTEX_SHADER = 0, + PRECOMPILED_PIXEL_SHADER, + + PRECOMPILED_SHADER_TYPE_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Flags field of PrecompiledShader_t +//----------------------------------------------------------------------------- +enum +{ + // runtime flags + SHADER_DYNAMIC_COMPILE_IS_HLSL = 0x1, + SHADER_FAILED_LOAD = 0x2, +}; + #endif // ISHADER_H diff --git a/public/materialsystem/MaterialSystemUtil.h b/public/materialsystem/MaterialSystemUtil.h index 3f22e918..ddabcd22 100644 --- a/public/materialsystem/MaterialSystemUtil.h +++ b/public/materialsystem/MaterialSystemUtil.h @@ -72,6 +72,10 @@ class CTextureReference void Init( char const* pTexture, const char *pTextureGroupName, bool bComplain = true ); void InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ); void InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL ); + void InitRenderTarget(int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, const char* pStrOptionalName = NULL) + { + InitRenderTarget(w, h, sizeMode, fmt, depth, bHDR, const_cast(pStrOptionalName)); + } #if defined( _X360 ) // used when RT coupling is disparate (texture is DDR based, surface is EDRAM based) void InitRenderTargetTexture( int width, int height, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL ); diff --git a/public/materialsystem/combineoperations.h b/public/materialsystem/combineoperations.h deleted file mode 100644 index 195f19f4..00000000 --- a/public/materialsystem/combineoperations.h +++ /dev/null @@ -1,29 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef COMBINEOPERATIONS_H -#define COMBINEOPERATIONS_H -#pragma once - -// New combines can be written in the middle (and generally should be written before Error). -// Keep these in sync with cCombineMaterialName in ctexturecompositor.cpp -enum ECombineOperation -{ - ECO_Multiply = 0, - ECO_Add, - ECO_Lerp, - - ECO_Select, - - ECO_Legacy_Lerp_FirstPass, - ECO_Legacy_Lerp_SecondPass, - - ECO_Error, - ECO_COUNT -}; - -#endif /* COMBINEOPERATIONS_H */ diff --git a/public/materialsystem/hardwaretexels.h b/public/materialsystem/hardwaretexels.h deleted file mode 100644 index 0821b41b..00000000 --- a/public/materialsystem/hardwaretexels.h +++ /dev/null @@ -1,87 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Hardware Texels -// -// Contains texture data that was encoded with the map. The initial use case -// is for per-texel lightmaps to allow static props to match the lighting -// of the surrounding BSP geometry. -// -//=============================================================================// - -#ifndef HARDWARETEXELS_H -#define HARDWARETEXELS_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "bitmap/imageformat.h" -#include "datamap.h" - -// valve hardware texels -#define VHT_VERSION 0 - -namespace HardwareTexels -{ -#pragma pack(1) - -// ------------------------------------------------------------------------------------------------ -struct MeshHeader_t -{ - DECLARE_BYTESWAP_DATADESC(); - - // this mesh is part of this lod - unsigned int m_nLod; - - // starting at this offset - unsigned int m_nOffset; - - // this mesh consumes this many bytes - unsigned int m_nBytes; - - // with this width and height - unsigned int m_nWidth; - unsigned int m_nHeight; - - unsigned int m_nUnused[3]; -}; - -// ------------------------------------------------------------------------------------------------ -struct FileHeader_t -{ - DECLARE_BYTESWAP_DATADESC(); - - // file version as defined by VHV_VERSION - int m_nVersion; - - // must match checkSum in the .mdl header - unsigned int m_nChecksum; - - // all texels are encoded in the same format - // This is a value from ImageFormat. - unsigned int m_nTexelFormat; - - // Number of meshes - int m_nMeshes; - - inline MeshHeader_t *pMesh( int nMesh ) const - { - Assert(nMesh < m_nMeshes); - - return (MeshHeader_t *)(((byte *)this) + sizeof(FileHeader_t)) + nMesh; - }; - - inline void *pTexelBase( int nMesh ) const - { - return (void *)((byte *)this + pMesh( nMesh )->m_nOffset); - }; - - unsigned int m_nUnused[4]; -}; - -#pragma pack() - -}; // end namespace - -#endif // HARDWARETEXELS_H - diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index bf896579..27af7725 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -43,7 +43,6 @@ struct MaterialSystem_Config_t; class VMatrix; struct matrix3x4_t; class ITexture; -class ITextureCompositor; struct MaterialSystemHardwareIdentifier_t; class KeyValues; class IShader; @@ -74,9 +73,9 @@ typedef uint64 VertexFormat_t; #define ABSOLUTE_MINIMUM_DXLEVEL 80 #endif -enum ShaderParamType_t -{ - SHADER_PARAM_TYPE_TEXTURE, +enum ShaderParamType_t +{ + SHADER_PARAM_TYPE_TEXTURE, SHADER_PARAM_TYPE_INTEGER, SHADER_PARAM_TYPE_COLOR, SHADER_PARAM_TYPE_VEC2, @@ -89,7 +88,6 @@ enum ShaderParamType_t SHADER_PARAM_TYPE_MATRIX, SHADER_PARAM_TYPE_MATERIAL, SHADER_PARAM_TYPE_STRING, - SHADER_PARAM_TYPE_MATRIX4X2 }; enum MaterialMatrixMode_t @@ -120,8 +118,8 @@ enum MaterialMatrixMode_t const int NUM_MODEL_TRANSFORMS = 53; const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS; -enum MaterialPrimitiveType_t -{ +enum MaterialPrimitiveType_t +{ MATERIAL_POINTS = 0x0, MATERIAL_LINES, MATERIAL_TRIANGLES, @@ -257,7 +255,7 @@ enum LightType_OptimizationFlags_t }; -struct LightDesc_t +struct LightDesc_t { LightType_t m_Type; Vector m_Color; @@ -291,10 +289,11 @@ struct LightDesc_t #define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 // inhibit allocation in 360 EDRAM #define CREATERENDERTARGETFLAGS_TEMP 0x00000010 // only allocates memory upon first resolve, destroyed at level end + //----------------------------------------------------------------------------- // allowed stencil operations. These match the d3d operations //----------------------------------------------------------------------------- -enum StencilOperation_t +enum StencilOperation_t { #if !defined( _X360 ) STENCILOPERATION_KEEP = 1, @@ -318,7 +317,7 @@ enum StencilOperation_t STENCILOPERATION_FORCE_DWORD = 0x7fffffff }; -enum StencilComparisonFunction_t +enum StencilComparisonFunction_t { #if !defined( _X360 ) STENCILCOMPARISONFUNCTION_NEVER = 1, @@ -410,7 +409,7 @@ struct MaterialAdapterInfo_t //----------------------------------------------------------------------------- struct MaterialVideoMode_t { - int m_Width; // if width and height are 0 and you select + int m_Width; // if width and height are 0 and you select int m_Height; // windowed mode, it'll use the window size ImageFormat m_Format; // use ImageFormats (ignored for windowed mode) int m_RefreshRate; // 0 == default (ignored for windowed mode) @@ -429,12 +428,22 @@ struct FlashlightState_t m_flShadowDepthBias = 0.0005f; m_flShadowJitterSeed = 0.0f; m_flShadowAtten = 0.0f; - m_bScissor = false; + m_bScissor = false; m_nLeft = -1; m_nTop = -1; m_nRight = -1; m_nBottom = -1; m_nShadowQuality = 0; +#ifdef ASW_PROJECTED_TEXTURES + m_bOrtho = false; + m_fOrthoLeft = -1.0f; + m_fOrthoRight = 1.0f; + m_fOrthoTop = -1.0f; + m_fOrthoBottom = 1.0f; + + m_fBrightnessScale = 1.0f; + m_pSpotlightTexture = NULL; +#endif } Vector m_vecLightOrigin; @@ -461,6 +470,22 @@ struct FlashlightState_t float m_flShadowAtten; int m_nShadowQuality; +#ifdef ASW_PROJECTED_TEXTURES + bool m_bOrtho; + float m_fOrthoLeft; + float m_fOrthoRight; + float m_fOrthoTop; + float m_fOrthoBottom; + + float m_FarZAtten; + float m_fBrightnessScale; + bool m_bGlobalLight; +#endif + +#ifdef MAPBASE + bool m_bAlwaysDraw; +#endif + // Getters for scissor members bool DoScissor() { return m_bScissor; } int GetLeft() { return m_nLeft; } @@ -472,28 +497,13 @@ struct FlashlightState_t friend class CShadowMgr; - bool m_bScissor; + bool m_bScissor; int m_nLeft; int m_nTop; int m_nRight; int m_nBottom; }; -// Passed as the callback object to Async functions in the material system -// so that callers don't have to worry about memory going out of scope before the -// results return. -abstract_class IAsyncTextureOperationReceiver : public IRefCounted -{ -public: - virtual void OnAsyncCreateComplete( ITexture* pTex, void* pExtraArgs ) = 0; - virtual void OnAsyncFindComplete( ITexture* pTex, void* pExtraArgs ) = 0; - virtual void OnAsyncMapComplete( ITexture* pTex, void* pExtraArgs, void* pMemory, int nPitch ) = 0; - virtual void OnAsyncReadbackBegin( ITexture* pDst, ITexture* pSrc, void* pExtraArgs ) = 0; - - virtual int GetRefCount() const = 0; -}; - - //----------------------------------------------------------------------------- // Flags to be used with the Init call //----------------------------------------------------------------------------- @@ -541,9 +551,16 @@ enum RenderTargetSizeMode_t RT_SIZE_OFFSCREEN=5, // Target of specified size, don't mess with dimensions RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP=6, // Same size as the frame buffer, rounded up if necessary for systems that can't do non-power of two textures. RT_SIZE_REPLAY_SCREENSHOT = 7, // Rounded down to power of 2, essentially... - RT_SIZE_LITERAL = 8, // Use the size passed in. Don't clamp it to the frame buffer size. Really. - RT_SIZE_LITERAL_PICMIP = 9 // Use the size passed in, don't clamp to the frame buffer size, but do apply picmip restrictions. + RT_SIZE_LITERAL = 8 // Use the size passed in. Don't clamp it to the frame buffer size. Really. +}; +enum RenderBackend_t +{ + RENDER_BACKEND_UNKNOWN, + RENDER_BACKEND_D3D9, + RENDER_BACKEND_TOGL, + RENDER_BACKEND_VULKAN, + RENDER_BACKEND_NULL, }; typedef void (*MaterialBufferReleaseFunc_t)( ); @@ -564,7 +581,7 @@ class CShadowMgr; DECLARE_POINTER_HANDLE( MaterialLock_t ); //----------------------------------------------------------------------------- -// +// //----------------------------------------------------------------------------- abstract_class IMaterialSystem : public IAppSystem @@ -584,12 +601,12 @@ abstract_class IMaterialSystem : public IAppSystem // Call this to initialize the material system // returns a method to create interfaces in the shader dll - virtual CreateInterfaceFn Init( char const* pShaderAPIDLL, + virtual CreateInterfaceFn Init( char const* pShaderAPIDLL, IMaterialProxyFactory *pMaterialProxyFactory, CreateInterfaceFn fileSystemFactory, CreateInterfaceFn cvarFactory=NULL ) = 0; - // Call this to set an explicit shader version to use + // Call this to set an explicit shader version to use // Must be called before Init(). virtual void SetShaderAPI( char const *pShaderAPIDLL ) = 0; @@ -629,8 +646,8 @@ abstract_class IMaterialSystem : public IAppSystem // Get the current config for this video card (as last set by UpdateConfig) virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const = 0; - // Gets *recommended* configuration information associated with the display card, - // given a particular dx level to run under. + // Gets *recommended* configuration information associated with the display card, + // given a particular dx level to run under. // Use dxlevel 0 to use the recommended dx level. // The function returns false if an invalid dxlevel was specified @@ -672,7 +689,7 @@ abstract_class IMaterialSystem : public IAppSystem // FIXME: REMOVE! Get video card identitier virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const = 0; - // Use this to spew information about the 3D layer + // Use this to spew information about the 3D layer virtual void SpewDriverInfo() const = 0; virtual void GetDXLevelDefaults(uint &max_dxlevel,uint &recommended_dxlevel) = 0; @@ -823,15 +840,15 @@ abstract_class IMaterialSystem : public IAppSystem virtual IMaterial * CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) = 0; // Find a material by name. - // The name of a material is a full path to + // The name of a material is a full path to // the vmt file starting from "hl2/materials" (or equivalent) without // a file extension. // eg. "dev/dev_bumptest" refers to somethign similar to: // "d:/hl2/hl2/materials/dev/dev_bumptest.vmt" // // Most of the texture groups for pTextureGroupName are listed in texture_group_names.h. - // - // Note: if the material can't be found, this returns a checkerboard material. You can + // + // Note: if the material can't be found, this returns a checkerboard material. You can // find out if you have that material by calling IMaterial::IsErrorMaterial(). // (Or use the global IsErrorMaterial function, which checks if it's null too). virtual IMaterial * FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) = 0; @@ -842,7 +859,7 @@ abstract_class IMaterialSystem : public IAppSystem //--------------------------------- // This is the interface for knowing what materials are available // is to use the following functions to get a list of materials. The - // material names will have the full path to the material, and that is the + // material names will have the full path to the material, and that is the // only way that the directory structure of the materials will be seen through this // interface. // NOTE: This is mostly for worldcraft to get a list of materials to put @@ -850,7 +867,7 @@ abstract_class IMaterialSystem : public IAppSystem virtual MaterialHandle_t FirstMaterial() const = 0; // returns InvalidMaterial if there isn't another material. - // WARNING: you must call GetNextMaterial until it returns NULL, + // WARNING: you must call GetNextMaterial until it returns NULL, // otherwise there will be a memory leak. virtual MaterialHandle_t NextMaterial( MaterialHandle_t h ) const = 0; @@ -874,11 +891,11 @@ abstract_class IMaterialSystem : public IAppSystem virtual bool IsTextureLoaded( char const* pTextureName ) const = 0; // Creates a procedural texture - virtual ITexture * CreateProceduralTexture( const char *pTextureName, - const char *pTextureGroupName, - int w, - int h, - ImageFormat fmt, + virtual ITexture * CreateProceduralTexture( const char *pTextureName, + const char *pTextureGroupName, + int w, + int h, + ImageFormat fmt, int nFlags ) = 0; // @@ -891,37 +908,37 @@ abstract_class IMaterialSystem : public IAppSystem // If depth == true, a depth buffer is also allocated. If not, then // the screen's depth buffer is used. // Creates a texture for use as a render target - virtual ITexture * CreateRenderTargetTexture( int w, - int h, + virtual ITexture * CreateRenderTargetTexture( int w, + int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, + ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED ) = 0; virtual ITexture * CreateNamedRenderTargetTextureEx( const char *pRTName, // Pass in NULL here for an unnamed render target. - int w, - int h, + int w, + int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ) = 0; - virtual ITexture * CreateNamedRenderTargetTexture( const char *pRTName, - int w, - int h, + virtual ITexture * CreateNamedRenderTargetTexture( const char *pRTName, + int w, + int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, - bool bClampTexCoords = true, + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + bool bClampTexCoords = true, bool bAutoMipMap = false ) = 0; // Must be called between the above Begin-End calls! virtual ITexture * CreateNamedRenderTargetTextureEx2( const char *pRTName, // Pass in NULL here for an unnamed render target. - int w, - int h, + int w, + int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). - ImageFormat format, - MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ) = 0; @@ -932,13 +949,13 @@ abstract_class IMaterialSystem : public IAppSystem // To allocate lightmaps, sort the whole world by material twice. // The first time through, call AllocateLightmap for every surface. // that has a lightmap. - // The second time through, call AllocateWhiteLightmap for every + // The second time through, call AllocateWhiteLightmap for every // surface that expects to use shaders that expect lightmaps. virtual void BeginLightmapAllocation( ) = 0; virtual void EndLightmapAllocation( ) = 0; // returns the sorting id for this surface - virtual int AllocateLightmap( int width, int height, + virtual int AllocateLightmap( int width, int height, int offsetIntoLightmapPage[2], IMaterial *pMaterial ) = 0; // returns the sorting id for this surface @@ -950,7 +967,7 @@ abstract_class IMaterialSystem : public IAppSystem // You should never call UpdateLightmap for a lightmap allocated through // AllocateWhiteLightmap. virtual void UpdateLightmap( int lightmapPageID, int lightmapSize[2], - int offsetIntoLightmapPage[2], + int offsetIntoLightmapPage[2], float *pFloatImage, float *pFloatImageBump1, float *pFloatImageBump2, float *pFloatImageBump3 ) = 0; @@ -1046,7 +1063,7 @@ abstract_class IMaterialSystem : public IAppSystem #ifdef DX_TO_GL_ABSTRACTION virtual void DoStartupShaderPreloading( void ) = 0; -#endif +#endif // Sets the override sizes for all render target size tests. These replace the frame buffer size. // Set them when you are rendering primarily to something larger than the frame buffer (as in VR mode). @@ -1058,31 +1075,12 @@ abstract_class IMaterialSystem : public IAppSystem // returns the display device name that matches the adapter index we were started with virtual char *GetDisplayDeviceName() const = 0; - // creates a texture suitable for use with materials from a raw stream of bits. - // The bits will be retained by the material system and can be freed upon return. - virtual ITexture* CreateTextureFromBits(int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits) = 0; - - // Lie to the material system to pretend to be in render target allocation mode at the beginning of time. - // This was a thing that mattered a lot to old hardware, but doesn't matter at all to new hardware, - // where new is defined to be "anything from the last decade." However, we want to preserve legacy behavior - // for the old games because it's easier than testing them. - virtual void OverrideRenderTargetAllocation( bool rtAlloc ) = 0; - - // creates a texture compositor that will attempt to composite a new textuer from the steps of the specified KeyValues. - virtual ITextureCompositor* NewTextureCompositor( int w, int h, const char* pCompositeName, int nTeamNum, uint64 randomSeed, KeyValues* stageDesc, uint32 texCompositeCreateFlags = 0 ) = 0; - - // Loads the texture with the specified name, calls pRecipient->OnAsyncFindComplete with the result from the main thread. - // once the texture load is complete. If the texture cannot be found, the returned texture will return true for IsError(). - virtual void AsyncFindTexture( const char* pFilename, const char *pTextureGroupName, IAsyncTextureOperationReceiver* pRecipient, void* pExtraArgs, bool bComplain = true, int nAdditionalCreationFlags = 0 ) = 0; - - // creates a texture suitable for use with materials from a raw stream of bits. - // The bits will be retained by the material system and can be freed upon return. - virtual ITexture* CreateNamedTextureFromBitsEx( const char* pName, const char *pTextureGroupName, int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits, int nFlags ) = 0; + virtual RenderBackend_t GetRenderBackend() const = 0; }; //----------------------------------------------------------------------------- -// +// //----------------------------------------------------------------------------- abstract_class IMatRenderContext : public IRefCounted { @@ -1103,7 +1101,7 @@ abstract_class IMatRenderContext : public IRefCounted // Bind a material is current for rendering. virtual void Bind( IMaterial *material, void *proxyData = 0 ) = 0; - // Bind a lightmap page current for rendering. You only have to + // Bind a lightmap page current for rendering. You only have to // do this for materials that require lightmaps. virtual void BindLightmapPage( int lightmapPageID ) = 0; @@ -1190,8 +1188,8 @@ abstract_class IMatRenderContext : public IRefCounted virtual void DestroyStaticMesh( IMesh* mesh ) = 0; // Gets the dynamic mesh associated with the currently bound material - // note that you've got to render the mesh before calling this function - // a second time. Clients should *not* call DestroyStaticMesh on the mesh + // note that you've got to render the mesh before calling this function + // a second time. Clients should *not* call DestroyStaticMesh on the mesh // returned by this call. // Use buffered = false if you want to not have the mesh be buffered, // but use it instead in the following pattern: @@ -1209,10 +1207,10 @@ abstract_class IMatRenderContext : public IRefCounted // If you pass in a material in pAutoBind, it will automatically bind the // material. This can be helpful since you must bind the material you're // going to use BEFORE calling GetDynamicMesh. - virtual IMesh* GetDynamicMesh( - bool buffered = true, - IMesh* pVertexOverride = 0, - IMesh* pIndexOverride = 0, + virtual IMesh* GetDynamicMesh( + bool buffered = true, + IMesh* pVertexOverride = 0, + IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 ) = 0; // ------------ New Vertex/Index Buffer interface ---------------------------- @@ -1282,7 +1280,7 @@ abstract_class IMatRenderContext : public IRefCounted // Gets the current height clip mode virtual MaterialHeightClipMode_t GetHeightClipMode( ) = 0; - // This returns the diameter of the sphere in pixels based on + // This returns the diameter of the sphere in pixels based on // the current model, view, + projection matrices and viewport. virtual float ComputePixelDiameterOfSphere( const Vector& vecAbsOrigin, float flRadius ) = 0; @@ -1328,7 +1326,7 @@ abstract_class IMatRenderContext : public IRefCounted // all the necessary pixel/texel coordinate fix ups. fractional values can be used for the // src_texture coordinates to get linear sampling - integer values should produce 1:1 mappings // for non-scaled operations. - virtual void DrawScreenSpaceRectangle( + virtual void DrawScreenSpaceRectangle( IMaterial *pMaterial, int destx, int desty, int width, int height, @@ -1383,7 +1381,7 @@ abstract_class IMatRenderContext : public IRefCounted virtual void SetStencilReferenceValue(int ref) = 0; virtual void SetStencilTestMask(uint32 msk) = 0; virtual void SetStencilWriteMask(uint32 msk) = 0; - virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax,int value) =0; + virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax,int value) =0; virtual void SetRenderTargetEx( int nRenderTargetID, ITexture *pTexture ) = 0; @@ -1394,8 +1392,8 @@ abstract_class IMatRenderContext : public IRefCounted // Returns the number of vertices + indices we can render using the dynamic mesh // Passing true in the second parameter will return the max # of vertices + indices - // we can use before a flush is provoked and may return different values - // if called multiple times in succession. + // we can use before a flush is provoked and may return different values + // if called multiple times in succession. // Passing false into the second parameter will return // the maximum possible vertices + indices that can be rendered in a single batch virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) = 0; @@ -1478,7 +1476,7 @@ abstract_class IMatRenderContext : public IRefCounted virtual bool GetMorphAccumulatorTexCoord( Vector2D *pTexCoord, IMorph *pMorph, int nVertex ) = 0; // Version of get dynamic mesh that specifies a specific vertex format - virtual IMesh* GetDynamicMeshEx( VertexFormat_t vertexFormat, bool bBuffered = true, + virtual IMesh* GetDynamicMeshEx( VertexFormat_t vertexFormat, bool bBuffered = true, IMesh* pVertexOverride = 0, IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 ) = 0; virtual void FogMaxDensity( float flMaxDensity ) = 0; @@ -1526,7 +1524,7 @@ abstract_class IMatRenderContext : public IRefCounted // Temp render data gets immediately freed after it's all unlocked in single core. // This prevents it from being freed - virtual void AddRefRenderData() = 0; + virtual void AddRefRenderData() = 0; virtual void ReleaseRenderData() = 0; // Returns whether a pointer is render data. NOTE: passing NULL returns true @@ -1539,11 +1537,6 @@ abstract_class IMatRenderContext : public IRefCounted virtual void OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable ) = 0; virtual void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) = 0; - - // Create a texture from the specified src render target, then call pRecipient->OnAsyncCreateComplete from the main thread. - // The texture will be created using the destination format, and will optionally have mipmaps generated. - // In case of error, the provided callback function will be called with the error texture. - virtual void AsyncCreateTextureFromRenderTarget( ITexture* pSrcRt, const char* pDstName, ImageFormat dstFmt, bool bGenMips, int nAdditionalCreationFlags, IAsyncTextureOperationReceiver* pRecipient, void* pExtraArgs ) = 0; }; template< class E > inline E* IMatRenderContext::LockRenderDataTyped( int nCount, const E* pSrcData ) @@ -1613,14 +1606,14 @@ inline void CMatRenderDataReference::Release() //----------------------------------------------------------------------------- // Utility class for locking/unlocking render data //----------------------------------------------------------------------------- -template< typename E > +template< typename E > class CMatRenderData { public: CMatRenderData( IMatRenderContext* pRenderContext ); CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E *pSrcData = NULL ); ~CMatRenderData(); - E* Lock( int nCount, const E* pSrcData = NULL ); + E* Lock( int nCount, const E* pSrcData = NULL ); void Release(); bool IsValid() const; const E* Base() const; @@ -1672,7 +1665,7 @@ inline E* CMatRenderData::Lock( int nCount, const E* pSrcData ) m_nCount = nCount; if ( pSrcData && m_pRenderContext->IsRenderData( pSrcData ) ) { - // Yes, we're const-casting away, but that should be ok since + // Yes, we're const-casting away, but that should be ok since // the src data is render data m_pRenderData = const_cast( pSrcData ); m_pRenderContext->AddRefRenderData(); @@ -1756,7 +1749,7 @@ class CMatRenderContextPtr : public CRefPtr }; //----------------------------------------------------------------------------- -// Helper class for begin/end of pix event via constructor/destructor +// Helper class for begin/end of pix event via constructor/destructor //----------------------------------------------------------------------------- #define PIX_VALVE_ORANGE 0xFFF5940F @@ -1785,7 +1778,7 @@ class PIXEvent #if PIX_ENABLE # define PIXEVENT PIXEvent _pixEvent #else -# define PIXEVENT +# define PIXEVENT #endif //----------------------------------------------------------------------------- @@ -1796,7 +1789,7 @@ class PIXEvent static void DoMatSysQueueMark( IMaterialSystem *pMaterialSystem, const char *psz ) { CMatRenderContextPtr pRenderContext( pMaterialSystem ); - if ( pRenderContext->GetCallQueue() ) + if ( pRenderContext->GetCallQueue() ) pRenderContext->GetCallQueue()->QueueCall( Plat_DebugString, CUtlEnvelope( psz ) ); } @@ -1810,4 +1803,16 @@ static void DoMatSysQueueMark( IMaterialSystem *pMaterialSystem, const char *psz extern IMaterialSystem *materials; extern IMaterialSystem *g_pMaterialSystem; +FORCEINLINE bool IsEmulatingGL() +{ + static bool bIsEmulatingGL = ( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-r_emulate_gl" ) != NULL ) : false; + return bIsEmulatingGL; +} + +FORCEINLINE bool IsOpenGL() +{ + static bool bIsOpenGL = materials->GetRenderBackend() == RENDER_BACKEND_TOGL || IsEmulatingGL(); + return bIsOpenGL; +} + #endif // IMATERIALSYSTEM_H diff --git a/public/materialsystem/imaterialsystemhardwareconfig.h b/public/materialsystem/imaterialsystemhardwareconfig.h index 699b9bdf..9c6de3f0 100644 --- a/public/materialsystem/imaterialsystemhardwareconfig.h +++ b/public/materialsystem/imaterialsystemhardwareconfig.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $Header: $ // $NoKeywords: $ @@ -19,16 +19,8 @@ //----------------------------------------------------------------------------- // GL helpers //----------------------------------------------------------------------------- -FORCEINLINE bool IsEmulatingGL() -{ - static bool bIsEmulatingGL = ( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-r_emulate_gl" ) != NULL ) : false; - return bIsEmulatingGL; -} - -FORCEINLINE bool IsOpenGL( void ) -{ - return IsPlatformOpenGL() || IsEmulatingGL(); -} +FORCEINLINE bool IsEmulatingGL(); +FORCEINLINE bool IsOpenGL(); //----------------------------------------------------------------------------- // Material system interface version @@ -148,7 +140,7 @@ class IMaterialSystemHardwareConfig virtual bool SupportsColorOnSecondStream() const = 0; virtual bool SupportsStaticPlusDynamicLighting() const = 0; - // Does our card have a hard time with fillrate + // Does our card have a hard time with fillrate // relative to other cards w/ the same dx level? virtual bool PreferReducedFillrate() const = 0; diff --git a/public/materialsystem/imesh.h b/public/materialsystem/imesh.h index 3da443b4..51744095 100644 --- a/public/materialsystem/imesh.h +++ b/public/materialsystem/imesh.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //===========================================================================// @@ -16,14 +16,10 @@ #include #include #include "tier0/dbg.h" +#include "tier0/icommandline.h" #include "tier2/meshutils.h" #include "mathlib/mathlib.h" -#if defined( DX_TO_GL_ABSTRACTION ) -// Swap these so that we do color swapping on 10.6.2, which doesn't have EXT_vertex_array_bgra -#define OPENGL_SWAP_COLORS -#endif - //----------------------------------------------------------------------------- // forward declarations //----------------------------------------------------------------------------- @@ -60,7 +56,7 @@ enum DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL = 384 * 1024, // Only allocate this much during map transitions }; -// Vertex fields must be written in well-defined order to achieve write combining, +// Vertex fields must be written in well-defined order to achieve write combining, // which is a perf booster enum WriteCombineOrdering_t { @@ -137,7 +133,7 @@ struct VertexDesc_t // The first vertex index (used for buffered vertex buffers, or cards that don't support stream offset) int m_nFirstVertex; - // The offset in bytes of the memory we're writing into + // The offset in bytes of the memory we're writing into // from the start of the D3D buffer (will be 0 for static meshes) unsigned int m_nOffset; @@ -152,7 +148,7 @@ struct IndexDesc_t // Pointers to the index data unsigned short *m_pIndices; - // The offset in bytes of the memory we're writing into + // The offset in bytes of the memory we're writing into // from the start of the D3D buffer (will be 0 for static meshes) unsigned int m_nOffset; @@ -199,14 +195,14 @@ struct ModelVertexDX8_t : public ModelVertexDX7_t inline float *OffsetFloatPointer( float *pBufferPointer, int nVertexCount, int vertexSize ) { return reinterpret_cast( - reinterpret_cast(pBufferPointer) + + reinterpret_cast(pBufferPointer) + nVertexCount * vertexSize); } inline const float *OffsetFloatPointer( const float *pBufferPointer, int nVertexCount, int vertexSize ) { return reinterpret_cast( - reinterpret_cast(pBufferPointer) + + reinterpret_cast(pBufferPointer) + nVertexCount * vertexSize); } @@ -337,11 +333,11 @@ abstract_class IMesh : public IVertexBuffer, public IIndexBuffer virtual void Draw( CPrimList *pLists, int nLists ) = 0; // Copy verts and/or indices to a mesh builder. This only works for temp meshes! - virtual void CopyToMeshBuilder( + virtual void CopyToMeshBuilder( int iStartVert, // Which vertices to copy. - int nVerts, + int nVerts, int iStartIndex, // Which indices to copy. - int nIndices, + int nIndices, int indexOffset, // This is added to each index. CMeshBuilder &builder ) = 0; @@ -447,7 +443,7 @@ class CVertexBuilder : private VertexDesc_t // Returns the base vertex memory pointer void* BaseVertexData(); - // Selects the nth Vertex and Index + // Selects the nth Vertex and Index void SelectVertex( int idx ); // Advances the current vertex and index by one @@ -531,7 +527,7 @@ class CVertexBuilder : private VertexDesc_t void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); - // tangent space + // tangent space void TangentS3f( float sx, float sy, float sz ); void TangentS3fv( const float* s ); @@ -554,14 +550,14 @@ class CVertexBuilder : private VertexDesc_t // Generic per-vertex data (templatized for code which needs to support compressed vertices) template void CompressedUserData( const float* pData ); - // Fast Vertex! No need to call advance vertex, and no random access allowed. + // Fast Vertex! No need to call advance vertex, and no random access allowed. // WARNING - these are low level functions that are intended only for use // in the software vertex skinner. void FastVertex( const ModelVertexDX7_t &vertex ); void FastVertexSSE( const ModelVertexDX7_t &vertex ); // store 4 dx7 vertices fast. for special sse dx7 pipeline - void Fast4VerticesSSE( + void Fast4VerticesSSE( ModelVertexDX7_t const *vtx_a, ModelVertexDX7_t const *vtx_b, ModelVertexDX7_t const *vtx_c, @@ -571,7 +567,7 @@ class CVertexBuilder : private VertexDesc_t void FastVertexSSE( const ModelVertexDX8_t &vertex ); // Add number of verts and current vert since FastVertex routines do not update. - void FastAdvanceNVertices( int n ); + void FastAdvanceNVertices( int n ); #if defined( _X360 ) void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); @@ -1025,7 +1021,7 @@ inline int CVertexBuilder::TotalVertexCount() const inline void* CVertexBuilder::BaseVertexData() { // FIXME: If there's no position specified, we need to find - // the base address + // the base address Assert( m_pPosition ); return m_pPosition; } @@ -1036,7 +1032,7 @@ inline void* CVertexBuilder::BaseVertexData() //----------------------------------------------------------------------------- inline void CVertexBuilder::SelectVertex( int nIndex ) { - // NOTE: This index is expected to be relative + // NOTE: This index is expected to be relative Assert( (nIndex >= 0) && (nIndex < m_nMaxVertexCount) ); m_nCurrentVertex = nIndex; @@ -1258,7 +1254,7 @@ inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) #endif } -inline void CVertexBuilder::Fast4VerticesSSE( +inline void CVertexBuilder::Fast4VerticesSSE( ModelVertexDX7_t const *vtx_a, ModelVertexDX7_t const *vtx_b, ModelVertexDX7_t const *vtx_c, @@ -1422,7 +1418,7 @@ inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex ) "movntps %%xmm0, (%1)\n" "movntps %%xmm1, 16(%1)\n" "movntps %%xmm2, 32(%1)\n" - "movntps %%xmm3, 48(%1)\n" + "movntps %%xmm3, 48(%1)\n" :: "r" (pRead), "r" (pCurrPos) : "memory"); #else Error( "Implement CMeshBuilder::FastVertexSSE((dx8)" ); @@ -1783,11 +1779,12 @@ inline void CVertexBuilder::Color3f( float r, float g, float b ) Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; -#else - int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; + else + col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; + *(int*)m_pCurrColor = col; } @@ -1799,11 +1796,12 @@ inline void CVertexBuilder::Color3fv( const float *rgb ) Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) ); Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; -#else - int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; + else + col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; + *(int*)m_pCurrColor = col; } @@ -1814,11 +1812,12 @@ inline void CVertexBuilder::Color4f( float r, float g, float b, float a ) Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) ); Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0) ); -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); -#else - int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); + else + col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); + *(int*)m_pCurrColor = col; } @@ -1830,11 +1829,12 @@ inline void CVertexBuilder::Color4fv( const float *rgba ) Assert( (rgba[0] >= 0.0) && (rgba[1] >= 0.0) && (rgba[2] >= 0.0) && (rgba[3] >= 0.0) ); Assert( (rgba[0] <= 1.0) && (rgba[1] <= 1.0) && (rgba[2] <= 1.0) && (rgba[3] <= 1.0) ); -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(rgba[0])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[2]) << 16) | (FastFToC(rgba[3]) << 24); -#else - int col = (FastFToC(rgba[2])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[0]) << 16) | (FastFToC(rgba[3]) << 24); -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(rgba[0])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[2]) << 16) | (FastFToC(rgba[3]) << 24); + else + col = (FastFToC(rgba[2])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[0]) << 16) | (FastFToC(rgba[3]) << 24); + *(int*)m_pCurrColor = col; } @@ -1848,12 +1848,12 @@ inline void CVertexBuilder::Color4fv( const float *rgba ) inline void CVertexBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b ) { Assert( m_pColor && m_pCurrColor ); - #ifdef OPENGL_SWAP_COLORS - int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory - #else - int col = b | (g << 8) | (r << 16) | 0xFF000000; - #endif - + int col = 0; + if ( IsOpenGL() ) + col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + else + col = b | (g << 8) | (r << 16) | 0xFF000000; + *(int*)m_pCurrColor = col; } @@ -1861,11 +1861,11 @@ inline void CVertexBuilder::Color3ubv( unsigned char const* rgb ) { Assert(rgb); Assert( m_pColor && m_pCurrColor ); - #ifdef OPENGL_SWAP_COLORS - int col = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16) | 0xFF000000; // r, g, b, a in memory - #else - int col = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16) | 0xFF000000; - #endif + int col = 0; + if ( IsOpenGL() ) + col = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16) | 0xFF000000; // r, g, b, a in memory + else + col = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16) | 0xFF000000; *(int*)m_pCurrColor = col; } @@ -1873,11 +1873,11 @@ inline void CVertexBuilder::Color3ubv( unsigned char const* rgb ) inline void CVertexBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) { Assert( m_pColor && m_pCurrColor ); - #ifdef OPENGL_SWAP_COLORS - int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory - #else - int col = b | (g << 8) | (r << 16) | (a << 24); - #endif + int col = 0; + if ( IsOpenGL() ) + col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + else + col = b | (g << 8) | (r << 16) | (a << 24); *(int*)m_pCurrColor = col; } @@ -1886,12 +1886,13 @@ inline void CVertexBuilder::Color4ubv( unsigned char const* rgba ) { Assert( rgba ); Assert( m_pColor && m_pCurrColor ); - #ifdef OPENGL_SWAP_COLORS - int col = rgba[0] | (rgba[1] << 8) | (rgba[2] << 16) | (rgba[3] << 24); // r, g, b, a in memory - #else - int col = rgba[2] | (rgba[1] << 8) | (rgba[0] << 16) | (rgba[3] << 24); - #endif - *(int*)m_pCurrColor = col; + int col = 0; + if ( IsOpenGL() ) + col = rgba[0] | (rgba[1] << 8) | (rgba[2] << 16) | (rgba[3] << 24); // r, g, b, a in memory + else + col = rgba[2] | (rgba[1] << 8) | (rgba[0] << 16) | (rgba[3] << 24); + + *(int*)m_pCurrColor = col; } inline void CVertexBuilder::Specular3f( float r, float g, float b ) @@ -1902,11 +1903,12 @@ inline void CVertexBuilder::Specular3f( float r, float g, float b ) Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; -#else - int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; + else + col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; + *(int*)pSpecular = col; } @@ -1919,11 +1921,12 @@ inline void CVertexBuilder::Specular3fv( const float *rgb ) Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; -#else - int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; + else + col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; + *(int*)pSpecular = col; } @@ -1935,11 +1938,12 @@ inline void CVertexBuilder::Specular4f( float r, float g, float b, float a ) Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0f) ); unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); -#else - int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); + else + col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); + *(int*)pSpecular = col; } @@ -1952,11 +1956,12 @@ inline void CVertexBuilder::Specular4fv( const float *rgb ) Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) && (rgb[3] <= 1.0) ); unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; -#ifdef OPENGL_SWAP_COLORS - int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | (FastFToC(rgb[3]) << 24); -#else - int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | (FastFToC(rgb[3]) << 24); -#endif + int col = 0; + if ( IsOpenGL() ) + col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | (FastFToC(rgb[3]) << 24); + else + col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | (FastFToC(rgb[3]) << 24); + *(int*)pSpecular = col; } @@ -1965,12 +1970,12 @@ inline void CVertexBuilder::Specular3ub( unsigned char r, unsigned char g, unsig Assert( m_pSpecular ); unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; - #ifdef OPENGL_SWAP_COLORS - int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory - #else - int col = b | (g << 8) | (r << 16) | 0xFF000000; - #endif - + int col = 0; + if ( IsOpenGL() ) + col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + else + col = b | (g << 8) | (r << 16) | 0xFF000000; + *(int*)pSpecular = col; } @@ -1979,12 +1984,12 @@ inline void CVertexBuilder::Specular3ubv( unsigned char const *c ) Assert( m_pSpecular ); unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; - #ifdef OPENGL_SWAP_COLORS - int col = c[0] | (c[1] << 8) | (c[2] << 16) | 0xFF000000; // r, g, b, a in memory - #else - int col = c[2] | (c[1] << 8) | (c[0] << 16) | 0xFF000000; - #endif - + int col = 0; + if ( IsOpenGL() ) + col = c[0] | (c[1] << 8) | (c[2] << 16) | 0xFF000000; // r, g, b, a in memory + else + col = c[2] | (c[1] << 8) | (c[0] << 16) | 0xFF000000; + *(int*)pSpecular = col; } @@ -1993,11 +1998,11 @@ inline void CVertexBuilder::Specular4ub( unsigned char r, unsigned char g, unsig Assert( m_pSpecular ); unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; - #ifdef OPENGL_SWAP_COLORS - int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory - #else - int col = b | (g << 8) | (r << 16) | (a << 24); - #endif + int col = 0; + if ( IsOpenGL() ) + col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + else + col = b | (g << 8) | (r << 16) | (a << 24); *(int*)pSpecular = col; } @@ -2007,12 +2012,12 @@ inline void CVertexBuilder::Specular4ubv( unsigned char const *c ) Assert( m_pSpecular ); unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; - #ifdef OPENGL_SWAP_COLORS - int col = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); - #else - int col = c[2] | (c[1] << 8) | (c[0] << 16) | (c[3] << 24); - #endif - + int col = 0; + if ( IsOpenGL() ) + col = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + else + col = c[2] | (c[1] << 8) | (c[0] << 16) | (c[3] << 24); + *(int*)pSpecular = col; } @@ -2218,10 +2223,9 @@ inline void CVertexBuilder::BoneMatrix( int idx, int matrixIdx ) } Assert( (matrixIdx >= 0) && (matrixIdx < 53) ); -#ifdef OPENGL_SWAP_COLORS - idx = sg_IndexSwap[idx]; -#endif - + if ( IsOpenGL() ) + idx = sg_IndexSwap[idx]; + #ifndef NEW_SKINNING unsigned char* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex]; if ( IsX360() ) @@ -2341,7 +2345,7 @@ template inline void CVertexBuilder::CompressedUserD #if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); PackNormal_SHORT2( pData, (unsigned int *)pUserData, binormalSign ); -#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) // FIXME: add a combined CompressedNormalAndTangent() accessor, to avoid reading back from write-combined memory here // The normal should have already been written into the lower 16 // bits - here, we OR in the tangent into the upper 16 bits @@ -2418,7 +2422,7 @@ class CIndexBuilder : private IndexDesc_t // Resets the mesh builder so it points to the start of everything again void Reset(); - // Selects the nth Index + // Selects the nth Index void SelectIndex( int nBufferIndex ); // Advances the current index by one @@ -2492,7 +2496,7 @@ class CIndexBuilder : private IndexDesc_t //----------------------------------------------------------------------------- // Constructor //----------------------------------------------------------------------------- -inline CIndexBuilder::CIndexBuilder() : m_pIndexBuffer(0), m_nIndexCount(0), +inline CIndexBuilder::CIndexBuilder() : m_pIndexBuffer(0), m_nIndexCount(0), m_nCurrentIndex(0), m_nMaxIndexCount(0) { m_nTotalIndexCount = 0; @@ -2806,7 +2810,7 @@ inline void CIndexBuilder::AdvanceIndex() m_nCurrentIndex += m_nIndexSize; if ( m_nCurrentIndex > m_nIndexCount ) { - m_nIndexCount = m_nCurrentIndex; + m_nIndexCount = m_nCurrentIndex; } } @@ -2815,7 +2819,7 @@ inline void CIndexBuilder::AdvanceIndices( int nIndices ) m_nCurrentIndex += nIndices * m_nIndexSize; if ( m_nCurrentIndex > m_nIndexCount ) { - m_nIndexCount = m_nCurrentIndex; + m_nIndexCount = m_nCurrentIndex; } } @@ -2858,7 +2862,7 @@ inline void CIndexBuilder::FastIndex( unsigned short nIndex ) Assert( m_nCurrentIndex < m_nMaxIndexCount ); m_pIndices[m_nCurrentIndex] = (unsigned short)( m_nIndexOffset + nIndex ); m_nCurrentIndex += m_nIndexSize; - m_nIndexCount = m_nCurrentIndex; + m_nIndexCount = m_nCurrentIndex; } inline void CIndexBuilder::FastTriangle( int startVert ) @@ -2970,7 +2974,7 @@ inline void CIndexBuilder::FastIndex2( unsigned short nIndex1, unsigned short nI *(int*)( &m_pIndices[m_nCurrentIndex] ) = nIndices; m_nCurrentIndex += m_nIndexSize + m_nIndexSize; - m_nIndexCount = m_nCurrentIndex; + m_nIndexCount = m_nCurrentIndex; } @@ -3063,7 +3067,7 @@ class CMeshBuilder : public MeshDesc_t void EndModify( bool bSpewData = false ); // A helper method since this seems to be done a whole bunch. - void DrawQuad( IMesh* pMesh, const float *v1, const float *v2, + void DrawQuad( IMesh* pMesh, const float *v1, const float *v2, const float *v3, const float *v4, unsigned char const *pColor, bool wireframe = false ); // returns the number of indices and vertices @@ -3082,7 +3086,7 @@ class CMeshBuilder : public MeshDesc_t // Returns the base vertex memory pointer void* BaseVertexData(); - // Selects the nth Vertex and Index + // Selects the nth Vertex and Index void SelectVertex( int idx ); void SelectIndex( int idx ); @@ -3122,7 +3126,7 @@ class CMeshBuilder : public MeshDesc_t #else float *BoneMatrix() const; #endif - unsigned short const *Index() const; + unsigned short const *Index() const; // position setting void Position3f( float x, float y, float z ); @@ -3174,7 +3178,7 @@ class CMeshBuilder : public MeshDesc_t void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); - // tangent space + // tangent space void TangentS3f( float sx, float sy, float sz ); void TangentS3fv( const float *s ); @@ -3207,14 +3211,14 @@ class CMeshBuilder : public MeshDesc_t // Fast Index! No need to call advance index, and no random access allowed void FastIndex( unsigned short index ); - // Fast Vertex! No need to call advance vertex, and no random access allowed. + // Fast Vertex! No need to call advance vertex, and no random access allowed. // WARNING - these are low level functions that are intended only for use // in the software vertex skinner. void FastVertex( const ModelVertexDX7_t &vertex ); void FastVertexSSE( const ModelVertexDX7_t &vertex ); // store 4 dx7 vertices fast. for special sse dx7 pipeline - void Fast4VerticesSSE( + void Fast4VerticesSSE( ModelVertexDX7_t const *vtx_a, ModelVertexDX7_t const *vtx_b, ModelVertexDX7_t const *vtx_c, @@ -3224,17 +3228,17 @@ class CMeshBuilder : public MeshDesc_t void FastVertexSSE( const ModelVertexDX8_t &vertex ); // Add number of verts and current vert since FastVertexxx routines do not update. - void FastAdvanceNVertices(int n); + void FastAdvanceNVertices(int n); #if defined( _X360 ) void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); #endif private: - // Computes number of verts and indices - void ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, + // Computes number of verts and indices + void ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, MaterialPrimitiveType_t type, int nPrimitiveCount ); - int IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ); + int IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ); // The mesh we're modifying IMesh *m_pMesh; @@ -3282,7 +3286,7 @@ inline CMeshBuilder::CMeshBuilder() : m_pMesh(0), m_bGenerateIndices(false) //----------------------------------------------------------------------------- // Computes the number of verts and indices based on primitive type and count //----------------------------------------------------------------------------- -inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, +inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, MaterialPrimitiveType_t type, int nPrimitiveCount ) { switch(type) @@ -3434,7 +3438,7 @@ inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int Assert( pMesh && (!m_pMesh) ); // NOTE: We can't specify the indices when we use quads, polygons, or - // linestrips; they aren't actually directly supported by + // linestrips; they aren't actually directly supported by // the material system Assert( (type != MATERIAL_QUADS) && (type != MATERIAL_INSTANCED_QUADS) && (type != MATERIAL_POLYGON) && (type != MATERIAL_LINE_STRIP) && (type != MATERIAL_LINE_LOOP)); @@ -3561,7 +3565,7 @@ inline void CMeshBuilder::Reset() //----------------------------------------------------------------------------- -// Selects the current Vertex and Index +// Selects the current Vertex and Index //----------------------------------------------------------------------------- FORCEINLINE void CMeshBuilder::SelectVertex( int nIndex ) { @@ -3570,7 +3574,7 @@ FORCEINLINE void CMeshBuilder::SelectVertex( int nIndex ) inline void CMeshBuilder::SelectVertexFromIndex( int idx ) { - // NOTE: This index is expected to be relative + // NOTE: This index is expected to be relative int vertIdx = idx - m_nFirstVertex; SelectVertex( vertIdx ); } @@ -3622,7 +3626,7 @@ FORCEINLINE int CMeshBuilder::GetCurrentIndex() //----------------------------------------------------------------------------- // A helper method since this seems to be done a whole bunch. //----------------------------------------------------------------------------- -inline void CMeshBuilder::DrawQuad( IMesh* pMesh, const float* v1, const float* v2, +inline void CMeshBuilder::DrawQuad( IMesh* pMesh, const float* v1, const float* v2, const float* v3, const float* v4, unsigned char const* pColor, bool wireframe ) { if (!wireframe) @@ -3797,7 +3801,7 @@ FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) m_VertexBuilder.FastVertexSSE( vertex ); } -FORCEINLINE void CMeshBuilder::Fast4VerticesSSE( +FORCEINLINE void CMeshBuilder::Fast4VerticesSSE( const ModelVertexDX7_t *vtx_a, const ModelVertexDX7_t *vtx_b, const ModelVertexDX7_t *vtx_c, const ModelVertexDX7_t *vtx_d ) { diff --git a/public/materialsystem/ishadersystem_declarations.h b/public/materialsystem/ishadersystem_declarations.h deleted file mode 100644 index 3c54edca..00000000 --- a/public/materialsystem/ishadersystem_declarations.h +++ /dev/null @@ -1,131 +0,0 @@ -//===== Copyright Valve Corporation, All rights reserved. ======// -#ifndef ISHADER_DECLARATIONS_HDR -#define ISHADER_DECLARATIONS_HDR - -//----------------------------------------------------------------------------- -// Standard vertex shader constants -//----------------------------------------------------------------------------- -enum -{ - // Standard vertex shader constants - VERTEX_SHADER_MATH_CONSTANTS0 = 0, - VERTEX_SHADER_MATH_CONSTANTS1 = 1, - VERTEX_SHADER_CAMERA_POS = 2, - VERTEX_SHADER_FLEXSCALE = 3, // DX9 only - VERTEX_SHADER_LIGHT_INDEX = 3, // DX8 only - VERTEX_SHADER_MODELVIEWPROJ = 4, - VERTEX_SHADER_VIEWPROJ = 8, - VERTEX_SHADER_MODELVIEWPROJ_THIRD_ROW = 12, - VERTEX_SHADER_VIEWPROJ_THIRD_ROW = 13, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 = 14, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_11 = 15, - VERTEX_SHADER_FOG_PARAMS = 16, - VERTEX_SHADER_VIEWMODEL = 17, - VERTEX_SHADER_AMBIENT_LIGHT = 21, - VERTEX_SHADER_LIGHTS = 27, - VERTEX_SHADER_LIGHT0_POSITION = 29, - VERTEX_SHADER_MODULATION_COLOR = 47, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 = 48, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_1 = 49, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 = 50, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 = 51, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 = 52, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 = 53, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 = 54, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_7 = 55, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_8 = 56, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_9 = 57, - VERTEX_SHADER_MODEL = 58, - // - // We reserve up through 216 for the 53 bones supported on DX9 - // - VERTEX_SHADER_SHADER_SPECIFIC_CONST_13 = 217, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_14 = 218, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_15 = 219, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_16 = 220, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_17 = 221, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_18 = 222, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_19 = 223, - VERTEX_SHADER_SHADER_SPECIFIC_CONST_12 = 224, - - // 226 ClipPlane0 |------ OpenGL will jam clip planes into these two - // 227 ClipPlane1 | - - - VERTEX_SHADER_FLEX_WEIGHTS = 1024, - VERTEX_SHADER_MAX_FLEX_WEIGHT_COUNT = 512, -}; - -//----------------------------------------------------------------------------- -// forward declarations -//----------------------------------------------------------------------------- -class IMaterialVar; -class IShaderShadow; -class IShaderDynamicAPI; -class IShaderInit; -class CBasePerMaterialContextData; - - -//----------------------------------------------------------------------------- -// Shader flags -//----------------------------------------------------------------------------- -enum ShaderFlags_t -{ - SHADER_NOT_EDITABLE = 0x1 -}; - - -//----------------------------------------------------------------------------- -// Shader parameter flags -//----------------------------------------------------------------------------- -enum ShaderParamFlags_t -{ - SHADER_PARAM_NOT_EDITABLE = 0x1 -}; - - - -//----------------------------------------------------------------------------- -// Standard vertex shader constants -//----------------------------------------------------------------------------- -enum -{ - // Standard vertex shader constants - VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST = 0, - VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST_COUNT = 4, - - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0 = 4, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_1 = 5, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_2 = 6, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_3 = 7, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_4 = 8, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_5 = 9, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_6 = 10, - VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_7 = 11, -}; - - -//----------------------------------------------------------------------------- -// Shader dictionaries defined in DLLs -//----------------------------------------------------------------------------- -enum PrecompiledShaderType_t -{ - PRECOMPILED_VERTEX_SHADER = 0, - PRECOMPILED_PIXEL_SHADER, - - PRECOMPILED_SHADER_TYPE_COUNT, -}; - - -//----------------------------------------------------------------------------- -// Flags field of PrecompiledShader_t -//----------------------------------------------------------------------------- -enum -{ - // runtime flags - SHADER_IS_ASM = 0x1, - SHADER_FAILED_LOAD = 0x2, -}; - - -#endif \ No newline at end of file diff --git a/public/materialsystem/itexture.h b/public/materialsystem/itexture.h index 0e315447..a5aa20fd 100644 --- a/public/materialsystem/itexture.h +++ b/public/materialsystem/itexture.h @@ -39,10 +39,6 @@ abstract_class ITextureRegenerator // This will be called when the regenerator needs to be deleted // which will happen when the texture is destroyed virtual void Release() = 0; - - // (erics): This should have a virtual destructor, but would be ABI breaking (non-versioned interface implemented - // by the game) -// virtual ~ITextureRegenerator(){} }; abstract_class ITexture @@ -124,13 +120,6 @@ abstract_class ITexture // Save texture to a file. virtual bool SaveToFile( const char *fileName ) = 0; - - // Copy this texture, which must be a render target or a renderable texture, to the destination texture, - // which must have been created with the STAGING bit. - virtual void CopyToStagingTexture( ITexture* pDstTex ) = 0; - - // Set that this texture should return true for the call "IsError" - virtual void SetErrorTexture( bool bIsErrorTexture ) = 0; }; diff --git a/public/materialsystem/itexturecompositor.h b/public/materialsystem/itexturecompositor.h deleted file mode 100644 index a158d36c..00000000 --- a/public/materialsystem/itexturecompositor.h +++ /dev/null @@ -1,50 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ================================== // -// -// Purpose: Defines a texture compositor infterface which uses simple operations and shaders to -// create complex procedural textures. -// -//============================================================================================== // - -#ifndef ITEXTURECOMPOSITOR_H -#define ITEXTURECOMPOSITOR_H -#pragma once - -#include "interface.h" -#include "itexture.h" - -#define ITEXTURE_COMPOSITOR_INTERFACE_VERSION "_ITextureCompositor000" - -enum ECompositeResolveStatus -{ - ECRS_Idle, - ECRS_Scheduled, - ECRS_PendingTextureLoads, - ECRS_PendingComposites, - ECRS_Error, - ECRS_Complete -}; - -enum TextureCompositeCreateFlags_t -{ - TEX_COMPOSITE_CREATE_FLAGS_FORCE = 0x00000001, - TEX_COMPOSITE_CREATE_FLAGS_NO_COMPRESSION = 0x00000002, - TEX_COMPOSITE_CREATE_FLAGS_NO_MIPMAPS = 0x00000004, -}; - -abstract_class ITextureCompositor -{ -public: - virtual int AddRef() = 0; - virtual int Release() = 0; - virtual int GetRefCount() const = 0; - - virtual void Update() = 0; - virtual ITexture* GetResultTexture() const = 0; - virtual ECompositeResolveStatus GetResolveStatus() const = 0; - virtual void ScheduleResolve() = 0; -protected: - virtual ~ITextureCompositor() {} -}; - - -#endif /* ITEXTURECOMPOSITOR_H */ diff --git a/public/mathlib/mathlib.h b/public/mathlib/mathlib.h index 05df16d5..30ad3536 100644 --- a/public/mathlib/mathlib.h +++ b/public/mathlib/mathlib.h @@ -350,12 +350,12 @@ FORCEINLINE void VectorClear(vec_t *a) FORCEINLINE float VectorMaximum(const vec_t *v) { - return max( v[0], max( v[1], v[2] ) ); + return MAX( v[0], MAX( v[1], v[2] ) ); } FORCEINLINE float VectorMaximum(const Vector& v) { - return max( v.x, max( v.y, v.z ) ); + return MAX( v.x, MAX( v.y, v.z ) ); } FORCEINLINE void VectorScale (const float* in, vec_t scale, float* out) @@ -380,7 +380,7 @@ inline void VectorNegate(vec_t *a) } -//#define VectorMaximum(a) ( max( (a)[0], max( (a)[1], (a)[2] ) ) ) +//#define VectorMaximum(a) ( MAX( (a)[0], MAX( (a)[1], (a)[2] ) ) ) #define Vector2Clear(x) {(x)[0]=(x)[1]=0;} #define Vector2Negate(x) {(x)[0]=-((x)[0]);(x)[1]=-((x)[1]);} #define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];} @@ -457,7 +457,7 @@ void inline SinCos( float radians, float *sine, float *cosine ) *sine = sin( radians ); *cosine = cos( radians ); #elif defined( POSIX ) - double __cosr, __sinr; + register double __cosr, __sinr; __asm ("fsincos" : "=t" (__cosr), "=u" (__sinr) : "0" (radians)); *sine = __sinr; @@ -1203,7 +1203,7 @@ inline float SimpleSplineRemapValClamped( float val, float A, float B, float C, FORCEINLINE int RoundFloatToInt(float f) { -#if defined(__i386__) || defined(_M_IX86) || defined( PLATFORM_WINDOWS_PC64 ) || defined(__x86_64__) +#if defined(__i386__) || defined(_M_IX86) || defined( PLATFORM_WINDOWS_PC64 ) return _mm_cvtss_si32(_mm_load_ss(&f)); #elif defined( _X360 ) #ifdef Assert @@ -1491,7 +1491,7 @@ FORCEINLINE unsigned char LinearToLightmap( float f ) FORCEINLINE void ColorClamp( Vector& color ) { - float maxc = max( color.x, max( color.y, color.z ) ); + float maxc = MAX( color.x, MAX( color.y, color.z ) ); if ( maxc > 1.0f ) { float ooMax = 1.0f / maxc; @@ -1987,10 +1987,10 @@ FORCEINLINE unsigned int * PackNormal_SHORT2( float nx, float ny, float nz, unsi ny *= 16384.0f; // '0' and '32768' values are invalid encodings - nx = max( nx, 1.0f ); // Make sure there are no zero values - ny = max( ny, 1.0f ); - nx = min( nx, 32767.0f ); // Make sure there are no 32768 values - ny = min( ny, 32767.0f ); + nx = MAX( nx, 1.0f ); // Make sure there are no zero values + ny = MAX( ny, 1.0f ); + nx = MIN( nx, 32767.0f ); // Make sure there are no 32768 values + ny = MIN( ny, 32767.0f ); if ( nz < 0.0f ) nx = -nx; // Set the sign bit for z @@ -2168,7 +2168,7 @@ inline bool CloseEnough( const Vector &a, const Vector &b, float epsilon = EQUAL // Fast compare // maxUlps is the maximum error in terms of Units in the Last Place. This // specifies how big an error we are willing to accept in terms of the value -// of the least significant digit of the floating point numbers +// of the least significant digit of the floating point number�s // representation. maxUlps can also be interpreted in terms of how many // representable floats we are willing to accept between A and B. // This function will allow maxUlps-1 floats between A and B. diff --git a/public/mathlib/ssemath.h b/public/mathlib/ssemath.h index 9ab08db5..510b1fcd 100644 --- a/public/mathlib/ssemath.h +++ b/public/mathlib/ssemath.h @@ -170,17 +170,17 @@ extern const fltx4 Four_Negative_FLT_MAX; // -FLT_MAX, -FLT_MAX, -FLT_MAX, extern const fltx4 g_SIMD_0123; // 0 1 2 3 as float // external aligned integer constants -extern const ALIGN16 int32 g_SIMD_clear_signmask[] ALIGN16_POST; // 0x7fffffff x 4 -extern const ALIGN16 int32 g_SIMD_signmask[] ALIGN16_POST; // 0x80000000 x 4 -extern const ALIGN16 int32 g_SIMD_lsbmask[] ALIGN16_POST; // 0xfffffffe x 4 -extern const ALIGN16 int32 g_SIMD_clear_wmask[] ALIGN16_POST; // -1 -1 -1 0 -extern const ALIGN16 int32 g_SIMD_ComponentMask[4][4] ALIGN16_POST; // [0xFFFFFFFF 0 0 0], [0 0xFFFFFFFF 0 0], [0 0 0xFFFFFFFF 0], [0 0 0 0xFFFFFFFF] -extern const ALIGN16 int32 g_SIMD_AllOnesMask[] ALIGN16_POST; // ~0,~0,~0,~0 -extern const ALIGN16 int32 g_SIMD_Low16BitsMask[] ALIGN16_POST; // 0xffff x 4 +extern const ALIGN16 uint32 g_SIMD_clear_signmask[] ALIGN16_POST; // 0x7fffffff x 4 +extern const ALIGN16 uint32 g_SIMD_signmask[] ALIGN16_POST; // 0x80000000 x 4 +extern const ALIGN16 uint32 g_SIMD_lsbmask[] ALIGN16_POST; // 0xfffffffe x 4 +extern const ALIGN16 uint32 g_SIMD_clear_wmask[] ALIGN16_POST; // -1 -1 -1 0 +extern const ALIGN16 uint32 g_SIMD_ComponentMask[4][4] ALIGN16_POST; // [0xFFFFFFFF 0 0 0], [0 0xFFFFFFFF 0 0], [0 0 0xFFFFFFFF 0], [0 0 0 0xFFFFFFFF] +extern const ALIGN16 uint32 g_SIMD_AllOnesMask[] ALIGN16_POST; // ~0,~0,~0,~0 +extern const ALIGN16 uint32 g_SIMD_Low16BitsMask[] ALIGN16_POST; // 0xffff x 4 // this mask is used for skipping the tail of things. If you have N elements in an array, and wish // to mask out the tail, g_SIMD_SkipTailMask[N & 3] what you want to use for the last iteration. -extern const int32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST; +extern const uint32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST; // Define prefetch macros. // The characteristics of cache and prefetch are completely @@ -436,23 +436,23 @@ FORCEINLINE fltx4 ArcTan2SIMD( const fltx4 &a, const fltx4 &b ) return result; } -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) +FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // MAX(a,b) { fltx4 retVal; - SubFloat( retVal, 0 ) = max( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( retVal, 1 ) = max( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( retVal, 2 ) = max( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( retVal, 3 ) = max( SubFloat( a, 3 ), SubFloat( b, 3 ) ); + SubFloat( retVal, 0 ) = MAX( SubFloat( a, 0 ), SubFloat( b, 0 ) ); + SubFloat( retVal, 1 ) = MAX( SubFloat( a, 1 ), SubFloat( b, 1 ) ); + SubFloat( retVal, 2 ) = MAX( SubFloat( a, 2 ), SubFloat( b, 2 ) ); + SubFloat( retVal, 3 ) = MAX( SubFloat( a, 3 ), SubFloat( b, 3 ) ); return retVal; } -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) +FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // MIN(a,b) { fltx4 retVal; - SubFloat( retVal, 0 ) = min( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( retVal, 1 ) = min( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( retVal, 2 ) = min( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( retVal, 3 ) = min( SubFloat( a, 3 ), SubFloat( b, 3 ) ); + SubFloat( retVal, 0 ) = MIN( SubFloat( a, 0 ), SubFloat( b, 0 ) ); + SubFloat( retVal, 1 ) = MIN( SubFloat( a, 1 ), SubFloat( b, 1 ) ); + SubFloat( retVal, 2 ) = MIN( SubFloat( a, 2 ), SubFloat( b, 2 ) ); + SubFloat( retVal, 3 ) = MIN( SubFloat( a, 3 ), SubFloat( b, 3 ) ); return retVal; } @@ -858,7 +858,7 @@ FORCEINLINE void TransposeSIMD( fltx4 & x, fltx4 & y, fltx4 & z, fltx4 & w ) // and replicate it to the whole return value. FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 & a ) { - float lowest = min( min( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); + float lowest = MIN( MIN( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); return ReplicateX4(lowest); } @@ -866,7 +866,7 @@ FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 & a ) // and replicate it to the whole return value. FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 & a ) { - float highest = max( max( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); + float highest = MAX( MAX( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); return ReplicateX4(highest); } @@ -1067,12 +1067,12 @@ FORCEINLINE fltx4 ArcTan2SIMD( const fltx4 &a, const fltx4 &b ) // DivSIMD defined further down, since it uses ReciprocalSIMD -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) +FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // MAX(a,b) { return __vmaxfp( a, b ); } -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) +FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // MIN(a,b) { return __vminfp( a, b ); } @@ -1520,11 +1520,11 @@ FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 & a ) compareOne = __vrlimi( compareOne, a, 8 | 4 , 1 ); // compareOne is [y,z,G,G] fltx4 retval = MinSIMD( a, compareOne ); - // retVal is [min(x,y), min(y,z), G, G] + // retVal is [MIN(x,y), MIN(y,z), G, G] compareOne = __vrlimi( compareOne, a, 8 , 2); // compareOne is [z, G, G, G] retval = MinSIMD( retval, compareOne ); - // retVal = [ min(min(x,y),z), G, G, G ] + // retVal = [ MIN(MIN(x,y),z), G, G, G ] // splat the x component out to the whole vector and return return SplatXSIMD( retval ); @@ -1544,11 +1544,11 @@ FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 & a ) compareOne = __vrlimi( compareOne, a, 8 | 4 , 1 ); // compareOne is [y,z,G,G] fltx4 retval = MaxSIMD( a, compareOne ); - // retVal is [max(x,y), max(y,z), G, G] + // retVal is [MAX(x,y), MAX(y,z), G, G] compareOne = __vrlimi( compareOne, a, 8 , 2); // compareOne is [z, G, G, G] retval = MaxSIMD( retval, compareOne ); - // retVal = [ max(max(x,y),z), G, G, G ] + // retVal = [ MAX(MAX(x,y),z), G, G, G ] // splat the x component out to the whole vector and return return SplatXSIMD( retval ); @@ -2120,12 +2120,12 @@ FORCEINLINE fltx4 CmpInBoundsSIMD( const fltx4 & a, const fltx4 & b ) // (a <= return AndSIMD( CmpLeSIMD(a,b), CmpGeSIMD(a, NegSIMD(b)) ); } -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) +FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // MIN(a,b) { return _mm_min_ps( a, b ); } -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) +FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // MAX(a,b) { return _mm_max_ps( a, b ); } @@ -2271,11 +2271,11 @@ FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 &a ) fltx4 compareOne = RotateLeft( a ); // compareOne is [y,z,G,x] fltx4 retval = MinSIMD( a, compareOne ); - // retVal is [min(x,y), ... ] + // retVal is [MIN(x,y), ... ] compareOne = RotateLeft2( a ); // compareOne is [z, G, x, y] retval = MinSIMD( retval, compareOne ); - // retVal = [ min(min(x,y),z)..] + // retVal = [ MIN(MIN(x,y),z)..] // splat the x component out to the whole vector and return return SplatXSIMD( retval ); @@ -2288,11 +2288,11 @@ FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 &a ) fltx4 compareOne = RotateLeft( a ); // compareOne is [y,z,G,x] fltx4 retval = MaxSIMD( a, compareOne ); - // retVal is [max(x,y), ... ] + // retVal is [MAX(x,y), ... ] compareOne = RotateLeft2( a ); // compareOne is [z, G, x, y] retval = MaxSIMD( retval, compareOne ); - // retVal = [ max(max(x,y),z)..] + // retVal = [ MAX(MAX(x,y),z)..] // splat the x component out to the whole vector and return return SplatXSIMD( retval ); @@ -3095,6 +3095,7 @@ FORCEINLINE int BoxOnPlaneSideSIMD( const fltx4& emins, const fltx4& emaxs, cons return sides[0]; } + FORCEINLINE float Dot4SIMD2(FLTX4 a, FLTX4 b) { fltx4 x = MulSIMD(a, b); diff --git a/public/mathlib/ssequaternion.h b/public/mathlib/ssequaternion.h index 825a9e45..42f127cc 100644 --- a/public/mathlib/ssequaternion.h +++ b/public/mathlib/ssequaternion.h @@ -233,7 +233,7 @@ FORCEINLINE fltx4 QuaternionScaleSIMD( const fltx4 &p, float t ) // FIXME: nick, this isn't overly sensitive to accuracy, and it may be faster to // use the cos part (w) of the quaternion (sin(omega)*N,cos(omega)) to figure the new scale. float sinom = sqrt( SubFloat( p, 0 ) * SubFloat( p, 0 ) + SubFloat( p, 1 ) * SubFloat( p, 1 ) + SubFloat( p, 2 ) * SubFloat( p, 2 ) ); - sinom = min( sinom, 1.f ); + sinom = MIN( sinom, 1.f ); float sinsom = sin( asin( sinom ) * t ); diff --git a/public/mathlib/vector.h b/public/mathlib/vector.h index a797da25..64e14802 100644 --- a/public/mathlib/vector.h +++ b/public/mathlib/vector.h @@ -1557,6 +1557,11 @@ class Quaternion // same data-layout as engine's vec4_t, inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f) { x = ix; y = iy; z = iz; w = iw; } +#ifdef MAPBASE_VSCRIPT + // Needed to get around vec_t recognition and inlining + void ScriptInit( float ix, float iy, float iz, float iw ) { Init( ix, iy, iz, iw ); } +#endif + bool IsValid() const; void Invalidate(); diff --git a/public/mathlib/vector4d.h b/public/mathlib/vector4d.h index 2b20c882..c5d0699f 100644 --- a/public/mathlib/vector4d.h +++ b/public/mathlib/vector4d.h @@ -41,9 +41,15 @@ class Vector4D Vector4D(void); Vector4D(vec_t X, vec_t Y, vec_t Z, vec_t W); Vector4D(const float *pFloat); +#ifdef MAPBASE + Vector4D(const Vector& vec, vec_t W); +#endif // Initialization void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f); +#ifdef MAPBASE + void Init( const Vector& vec, vec_t W ); +#endif // Got any nasty NAN's? bool IsValid() const; @@ -222,6 +228,14 @@ inline Vector4D::Vector4D(const float *pFloat) Assert( IsValid() ); } +#ifdef MAPBASE +inline Vector4D::Vector4D(const Vector& vec, vec_t W ) +{ + x = vec.x; y = vec.y; z = vec.z; w = W; + Assert( IsValid() ); +} +#endif + //----------------------------------------------------------------------------- // copy constructor @@ -243,6 +257,14 @@ inline void Vector4D::Init( vec_t ix, vec_t iy, vec_t iz, vec_t iw ) Assert( IsValid() ); } +#ifdef MAPBASE +inline void Vector4D::Init( const Vector& vec, vec_t iw ) +{ + x = vec.x; y = vec.y; z = vec.z; w = iw; + Assert( IsValid() ); +} +#endif + inline void Vector4D::Random( vec_t minVal, vec_t maxVal ) { x = minVal + ((vec_t)rand() / VALVE_RAND_MAX) * (maxVal - minVal); diff --git a/public/mathlib/vmatrix.h b/public/mathlib/vmatrix.h index e49a888d..c18e4822 100644 --- a/public/mathlib/vmatrix.h +++ b/public/mathlib/vmatrix.h @@ -107,6 +107,7 @@ class VMatrix void PreTranslate(const Vector &vTrans); void PostTranslate(const Vector &vTrans); + matrix3x4_t& As3x4(); const matrix3x4_t& As3x4() const; void CopyFrom3x4( const matrix3x4_t &m3x4 ); void Set3x4( matrix3x4_t& matrix3x4 ) const; @@ -629,6 +630,11 @@ inline const matrix3x4_t& VMatrix::As3x4() const return *((const matrix3x4_t*)this); } +inline matrix3x4_t& VMatrix::As3x4() +{ + return *((matrix3x4_t*)this); +} + inline void VMatrix::CopyFrom3x4( const matrix3x4_t &m3x4 ) { memcpy( m, m3x4.Base(), sizeof( matrix3x4_t ) ); diff --git a/public/matsys_controls/QCGenerator.h b/public/matsys_controls/QCGenerator.h index d6b69d21..d9978f88 100644 --- a/public/matsys_controls/QCGenerator.h +++ b/public/matsys_controls/QCGenerator.h @@ -79,9 +79,9 @@ struct QCInfo { pQCGenerator = pPanel; - V_strcpy_safe( pszSMDPath, "" ); - V_strcpy_safe( pszCollisionPath, "" ); - V_strcpy_safe( pszSurfaceProperty, "default" ); + Q_strcpy( pszSMDPath, "" ); + Q_strcpy( pszCollisionPath, "" ); + Q_strcpy( pszSurfaceProperty, "default" ); bStaticProp = false; bMostlyOpaque = false; bDisableCollision = false; diff --git a/public/matsys_controls/manipulator.h b/public/matsys_controls/manipulator.h index f030509a..a08426ef 100644 --- a/public/matsys_controls/manipulator.h +++ b/public/matsys_controls/manipulator.h @@ -19,7 +19,6 @@ class IManipulator { public: - virtual ~IManipulator(){} virtual void OnBeginManipulation( void ) = 0; virtual void OnAcceptManipulation( void ) = 0; virtual void OnCancelManipulation( void ) = 0; diff --git a/public/matsys_controls/mdlpanel.h b/public/matsys_controls/mdlpanel.h index 60068567..070fb973 100644 --- a/public/matsys_controls/mdlpanel.h +++ b/public/matsys_controls/mdlpanel.h @@ -64,7 +64,7 @@ class CMDLPanel : public CPotteryWheelPanel void SetLOD( int nLOD ); // Sets the current sequence - void SetSequence( int nSequence, bool bResetSequence = false ); + void SetSequence( int nSequence ); // Set the pose parameters void SetPoseParameters( const float *pPoseParameters, int nCount ); @@ -113,7 +113,6 @@ class CMDLPanel : public CPotteryWheelPanel CMDL m_MDL; matrix3x4_t m_MDLToWorld; bool m_bDisabled; - float m_flCycleStartTime; }; MDLData_t m_RootMDL; diff --git a/public/matsys_controls/potterywheelpanel.h b/public/matsys_controls/potterywheelpanel.h index 5da55e48..47125a3f 100644 --- a/public/matsys_controls/potterywheelpanel.h +++ b/public/matsys_controls/potterywheelpanel.h @@ -45,7 +45,6 @@ class CPotteryWheelPanel : public vgui::EditablePanel virtual ~CPotteryWheelPanel(); // Overriden methods of vgui::Panel - virtual void ApplySettings( KeyValues *inResourceData ); virtual void Init( int x, int y, int wide, int tall ); virtual void Paint(); @@ -118,7 +117,6 @@ class CPotteryWheelPanel : public vgui::EditablePanel bool WarpMouse( int &x, int &y ); IManipulator *m_pCurrentManip; int m_nManipStartX, m_nManipStartY; - int m_nClickStartX, m_nClickStartY; // Re-apply the manipulators on a new model void ApplyManipulation(); @@ -138,7 +136,6 @@ class CPotteryWheelPanel : public vgui::EditablePanel private: void CreateDefaultLights(); void DestroyLights(); - void ParseLightsFromKV( KeyValues *pLightsKV ); CMaterialReference m_LightProbeBackground; CMaterialReference m_LightProbeHDRBackground; diff --git a/public/minmax.h b/public/minmax.h index 7597957c..8860f5e9 100644 --- a/public/minmax.h +++ b/public/minmax.h @@ -8,11 +8,13 @@ #ifndef MINMAX_H #define MINMAX_H +#if !defined(POSIX) #ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) + #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) + #define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif #endif #endif // MINMAX_H diff --git a/public/networkvar.h b/public/networkvar.h index 142b35e9..46a92de0 100644 --- a/public/networkvar.h +++ b/public/networkvar.h @@ -744,9 +744,9 @@ class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > const type* Base() const { return m_Value; } \ int Count() const { return count; } \ protected: \ - inline void NetworkStateChanged( int index ) \ + inline void NetworkStateChanged( int _index ) \ { \ - CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[_index] ); \ } \ type m_Value[count]; \ }; \ diff --git a/public/p4lib/ip4.h b/public/p4lib/ip4.h index d37ab396..37a9bab7 100644 --- a/public/p4lib/ip4.h +++ b/public/p4lib/ip4.h @@ -39,7 +39,6 @@ struct P4File_t CUtlSymbol m_sDepotFile; // the name in the depot CUtlSymbol m_sClientFile; // the name on the client in Perforce syntax CUtlSymbol m_sLocalFile; // the name on the client in local syntax - CUtlSymbol m_sFileType; // the type according to the server, see p4 help filetypes int m_iHeadRevision; // head revision number int m_iHaveRevision; // the revision the clientspec has synced locally bool m_bDir; // directory @@ -79,7 +78,9 @@ struct P4Client_t //----------------------------------------------------------------------------- // Purpose: Interface to accessing P4 commands //----------------------------------------------------------------------------- -#define P4_INTERFACE_VERSION "VP4002" +#define P4_INTERFACE_VERSION "VP4001" +// Vitaliy - 09-Feb-'07: if anybody ups the version of this interface, please +// move the method "SetOpenFileChangeList" into the appropriate section. abstract_class IP4 : public IAppSystem { @@ -115,9 +116,6 @@ abstract_class IP4 : public IAppSystem // changes the clientspec to remove the specified path (cloaking) virtual void RemovePathFromActiveClientspec( const char *path ) = 0; - // sets the name of the changelist to open files under, NULL for "Default" changelist - virtual void SetOpenFileChangeList(const char *pChangeListName) = 0; - // file manipulation virtual bool OpenFileForAdd( const char *pFullPath ) = 0; virtual bool OpenFileForEdit( const char *pFullPath ) = 0; @@ -175,17 +173,15 @@ abstract_class IP4 : public IAppSystem // Returns file information for a single file virtual bool GetFileInfo( const char *pFullPath, P4File_t *pFileInfo ) = 0; - // Reopens a file for edit or add with the specified filetype. To see the valid strings for - // filetypes, see p4 help fileinfo. Perforce has to know about files before the filetype can - // be changed (so for new files, they must be added first, then the filetype modified). - virtual bool SetFileType( const char *pFullPath, const char *pFileType ) = 0; - // retreives the list of files in a path, using a known client spec virtual CUtlVector &GetFileListUsingClientSpec( const char *pPath, const char *pClientSpec ) = 0; // retrieves the last error from the last op (which is likely to span multiple lines) // this is only valid after OpenFile[s]For{Add,Edit,Delete} or {Submit,Revert}File[s] virtual const char *GetLastError() = 0; + + // sets the name of the changelist to open files under, NULL for "Default" changelist + virtual void SetOpenFileChangeList( const char *pChangeListName ) = 0; }; diff --git a/public/particles/particles.h b/public/particles/particles.h index 4066d85e..f75d96d2 100644 --- a/public/particles/particles.h +++ b/public/particles/particles.h @@ -154,7 +154,6 @@ enum ParticleFunctionType_t struct CParticleVisibilityInputs { - float m_flCameraBias; float m_flInputMin; float m_flInputMax; float m_flAlphaScaleMin; @@ -669,7 +668,7 @@ class CParticleOperatorInstance } // should the constraint be run only once after all other constraints? - virtual bool IsFinalConstraint( void ) const + virtual bool IsFinalConstaint( void ) const { return false; } @@ -721,12 +720,6 @@ class CParticleOperatorInstance return false; } - // Does this operator require that particles remain in the order they were emitted? - virtual bool RequiresOrderInvariance( void ) const - { - return false; - } - // Called when the SFM wants to skip forward in time virtual void SkipToTime( float flTime, CParticleCollection *pParticles, void *pContext ) const {} @@ -888,9 +881,7 @@ class CParticleOperatorDefinition : public IParticleOperatorDefinition DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale minimum","0", float, VisibilityInputs.m_flAlphaScaleMin ) \ DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale maximum","1", float, VisibilityInputs.m_flAlphaScaleMax ) \ DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale minimum","1", float, VisibilityInputs.m_flRadiusScaleMin ) \ - DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale maximum","1", float, VisibilityInputs.m_flRadiusScaleMax ) \ - DMXELEMENT_UNPACK_FIELD( "Visibility Camera Depth Bias", "0", float, VisibilityInputs.m_flCameraBias ) - + DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale maximum","1", float, VisibilityInputs.m_flRadiusScaleMax ) // DMXELEMENT_UNPACK_FIELD( "Visibility Use Bounding Box for Proxy", "0", bool, VisibilityInputs.m_bUseBBox ) // DMXELEMENT_UNPACK_FIELD( "Visibility Bounding Box Scale", "1.0", float, VisibilityInputs.m_flBBoxScale ) @@ -970,7 +961,6 @@ struct CParticleVisibilityData { float m_flAlphaVisibility; float m_flRadiusVisibility; - float m_flCameraBias; bool m_bUseVisibility; }; @@ -1072,7 +1062,7 @@ class CParticleCollection float *GetInitialFloatAttributePtrForWrite( int nAttribute, int nParticleNumber ); fltx4 *GetInitialM128AttributePtrForWrite( int nAttribute, size_t *pStrideOut ); - void Simulate( float dt, bool updateBboxOnly ); + void Simulate( float dt ); void SkipToTime( float t ); // the camera objetc may be compared for equality against control point objects @@ -1104,17 +1094,14 @@ class CParticleCollection // Used to retrieve the position of a control point // somewhere between m_fCurTime and m_fCurTime - m_fPreviousDT - void GetControlPointAtTime( int nControlPoint, float flTime, Vector *pControlPoint ) const; - void GetControlPointAtPrevTime( int nControlPoint, Vector *pControlPoint ) const; + void GetControlPointAtTime( int nControlPoint, float flTime, Vector *pControlPoint ); + void GetControlPointAtPrevTime( int nControlPoint, Vector *pControlPoint ); void GetControlPointOrientationAtTime( int nControlPoint, float flTime, Vector *pForward, Vector *pRight, Vector *pUp ); void GetControlPointTransformAtTime( int nControlPoint, float flTime, matrix3x4_t *pMat ); void GetControlPointTransformAtTime( int nControlPoint, float flTime, VMatrix *pMat ); void GetControlPointTransformAtTime( int nControlPoint, float flTime, CParticleSIMDTransformation *pXForm ); int GetHighestControlPoint( void ) const; - // Has this particle moved recently (since the last simulation?) - bool HasMoved() const; - // Control point accessed: // NOTE: Unlike the definition's version of these methods, // these OR-in the masks of their children. @@ -1213,7 +1200,8 @@ class CParticleCollection void BloatBoundsUsingControlPoint(); private: - void GenerateSortedIndexList( Vector vecCameraPos, CParticleVisibilityData *pVisibilityData, bool bSorted ); + int GenerateCulledSortedIndexList( ParticleRenderData_t *pOut, Vector vecCamera, Vector vecFwd, CParticleVisibilityData *pVisibilityData, bool bSorted ); + int GenerateSortedIndexList( ParticleRenderData_t *pOut, Vector vecCameraPos, CParticleVisibilityData *pVisibilityData, bool bSorted ); void Init( CParticleSystemDefinition *pDef, float flDelay, int nRandomSeed ); void InitStorage( CParticleSystemDefinition *pDef ); @@ -1262,7 +1250,6 @@ class CParticleCollection bool ComputeIsTranslucent(); bool ComputeIsTwoPass(); bool ComputeIsBatchable(); - bool ComputeRequiresOrderInvariance(); void LabelTextureUsage( void ); @@ -1284,7 +1271,6 @@ class CParticleCollection int m_nMaxAllowedParticles; bool m_bDormant; bool m_bEmissionStopped; - bool m_bRequiresOrderInvariance; int m_LocalLightingCP; Color m_LocalLighting; @@ -1352,7 +1338,6 @@ class CParticleCollection // How many frames have we drawn? int m_nDrawnFrames; - int m_nSimulatedFrames; Vector m_Center; // average of particle centers @@ -1821,12 +1806,9 @@ inline fltx4 *CParticleCollection::GetM128AttributePtrForWrite( int nAttribute, { // NOTE: If you hit this assertion, it means your particle operator isn't returning // the appropriate fields in the RequiredAttributesMask call - if ( !HushAsserts() ) - { - Assert( !m_bIsRunningInitializers || ( m_nPerParticleInitializedAttributeMask & (1 << nAttribute) ) ); - Assert( !m_bIsRunningOperators || ( m_nPerParticleUpdatedAttributeMask & (1 << nAttribute) ) ); - Assert( m_nParticleFloatStrides[nAttribute] != 0 ); - } + Assert( !m_bIsRunningInitializers || ( m_nPerParticleInitializedAttributeMask & (1 << nAttribute) ) ); + Assert( !m_bIsRunningOperators || ( m_nPerParticleUpdatedAttributeMask & (1 << nAttribute) ) ); + Assert( m_nParticleFloatStrides[nAttribute] != 0 ); *(pStrideOut) = m_nParticleFloatStrides[ nAttribute ]/4; return reinterpret_cast( m_pParticleAttributes[ nAttribute ] ); @@ -2257,7 +2239,7 @@ FORCEINLINE int CParticleCollection::GetControlPointParent( int nControlPoint ) FORCEINLINE bool CParticleCollection::IsValid( void ) const { - return ( m_pDef != NULL && m_pDef->GetMaterial() ); + return ( m_pDef != nullptr && m_pDef->GetMaterial() ); } diff --git a/public/pixelwriter.h b/public/pixelwriter.h index 5c510553..c2d31d67 100644 --- a/public/pixelwriter.h +++ b/public/pixelwriter.h @@ -331,14 +331,6 @@ FORCEINLINE_PIXEL void CPixelWriter::SetPixelMemory( ImageFormat format, void* p format_error_printed[format] = true; } m_Size = 0; // set to zero so that we don't stomp memory for formats that we don't understand. - m_RShift = 0; - m_GShift = 0; - m_BShift = 0; - m_AShift = 0; - m_RMask = 0x00; - m_GMask = 0x00; - m_BMask = 0x00; - m_AMask = 0x00; } break; } diff --git a/public/renderparm.h b/public/renderparm.h index 39b58eda..77df07a3 100644 --- a/public/renderparm.h +++ b/public/renderparm.h @@ -27,8 +27,8 @@ enum RenderParamVector_t VECTOR_RENDERPARM_HMDWARP_GROW_ABOVEBELOW, VECTOR_RENDERPARM_HMDWARP_ASPECT, INT_RENDERPARM_DISTORTION_TYPE, - - VECTOR_RENDERPARM_CASCADED_FORWARD, + + VECTOR_RENDERPARM_WIND_DIRECTION, MAX_VECTOR_RENDER_PARMS = 20 }; @@ -57,24 +57,16 @@ enum RenderParamInt_t INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST, INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST = INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + 4, +#ifdef VANCE // DeferredRendering INT_RENDERPARM_DEFERRED_RENDER_STAGE, INT_RENDERPARM_CASCADED_DEPTHTEXTURE, INT_RENDERPARM_CASCADED_MATRIX_ADDRESS_0, +#endif - MAX_INT_RENDER_PARMS = 20 }; -#ifdef VANCE -enum DeferredRenderStage_t -{ - DEFERRED_RENDER_STAGE_INVALID = 0, - DEFERRED_RENDER_STAGE_GBUFFER, - DEFERRED_RENDER_STAGE_POSTLIGHT, -}; -#endif - // for INT_RENDERPARM_BACK_BUFFER_INDEX #define BACK_BUFFER_INDEX_DEFAULT 0 #define BACK_BUFFER_INDEX_HDR 1 @@ -92,4 +84,9 @@ enum RenderParamTexture_t #define ENABLE_FIXED_LIGHTING_OUTPUTMRTS_FOR_DEFERRED_LIGHTING 2 #define ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH 3 +enum RenderParamFloat_t +{ + FLOAT_RENDERPARM_MINIMUMLIGHTING = 0, +}; + #endif // RENDERPARM_H diff --git a/public/responserules/response_host_interface.h b/public/responserules/response_host_interface.h new file mode 100644 index 00000000..fa39bd88 --- /dev/null +++ b/public/responserules/response_host_interface.h @@ -0,0 +1,66 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_HOST_INTERFACE_H +#define RESPONSE_HOST_INTERFACE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "filesystem.h" +class IUniformRandomStream; +class ICommandLine; + +namespace ResponseRules +{ + // FUNCTIONS YOU MUST IMPLEMENT IN THE HOST EXECUTABLE: + // These are functions that are mentioned in the header, but need their bodies implemented + // in the .dll that links against this lib. + // This is to wrap functions that previously came from the engine interface + // back when the response rules were inside the server.dll . Now that the rules + // are included into a standalone editor, we don't necessarily have an engine around, + // so there needs to be some other implementation. + abstract_class IEngineEmulator + { + public: + /// Given an input text buffer data pointer, parses a single token into the variable token and returns the new + /// reading position + virtual const char *ParseFile( const char *data, char *token, int maxlen ) = 0; + +#ifdef MAPBASE + /// (Optional) Same as ParseFile, but with casing preserved and escaped quotes supported + virtual const char *ParseFilePreserve( const char *data, char *token, int maxlen ) { return ParseFile( data, token, maxlen ); } +#endif + + /// Return a pointer to an IFileSystem we can use to read and process scripts. + virtual IFileSystem *GetFilesystem() = 0; + + /// Return a pointer to an instance of an IUniformRandomStream + virtual IUniformRandomStream *GetRandomStream() = 0 ; + + /// Return a pointer to a tier0 ICommandLine + virtual ICommandLine *GetCommandLine() = 0; + + /// Emulates the server's UTIL_LoadFileForMe + virtual byte *LoadFileForMe( const char *filename, int *pLength ) = 0; + + /// Emulates the server's UTIL_FreeFile + virtual void FreeFile( byte *buffer ) = 0; + + + /// Somewhere in the host executable you should define this symbol and + /// point it at a singleton instance. + static IEngineEmulator *s_pSingleton; + + // this is just a function that returns the pointer above -- just in + // case we need to define it differently. And I get asserts this way. + static IEngineEmulator *Get(); + }; +}; + + +#endif \ No newline at end of file diff --git a/public/responserules/response_types.h b/public/responserules/response_types.h new file mode 100644 index 00000000..2e80cc5a --- /dev/null +++ b/public/responserules/response_types.h @@ -0,0 +1,480 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_TYPES_H +#define RESPONSE_TYPES_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/interval.h" +#include "mathlib/compressed_vector.h" +#include "datamap.h" +#include "soundflags.h" +#include "tier1/utlsymbol.h" + +namespace ResponseRules +{ + /// Custom symbol table for the response rules. + extern CUtlSymbolTable g_RS; +}; + +#ifdef _MANAGED +// forward declare some editor types just so we can friend them. +namespace ResponseRulesCLI +{ + ref class ResponseQueryResult; +} +#endif + +namespace ResponseRules +{ + using ::DataMapAccess; + // using ::DataMapInit; + class CResponseSystem; + +#pragma pack(push,1) + template + struct response_interval_t + { + T start; + T range; + + interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; } + void FromInterval( const interval_t &from ) { start = from.start; range = from.range; } + float Random() const { interval_t temp = { start, range }; return RandomInterval( temp ); } + }; + + typedef response_interval_t responseparams_interval_t; +#pragma pack(pop) + +#pragma pack(push,1) + struct AI_ResponseFollowup + { + + + // TODO: make less wasteful of memory, by using a symbol table. + const char *followup_concept; // 12 -- next response + const char *followup_contexts; // 16 + float followup_delay; // 20 + const char *followup_target; // 24 -- to whom is this despatched? + // AIConceptHandle_t hConcept; + const char *followup_entityiotarget; //< if this rule involves firing entity io + const char *followup_entityioinput; //< if this rule involves firing entity io + float followup_entityiodelay; + bool bFired; + + inline bool IsValid( void ) const { return (followup_concept && followup_contexts); } + inline void Invalidate() { followup_concept = NULL; followup_contexts = NULL; } + inline void SetFired( bool fired ) { bFired = fired; } + inline bool HasBeenFired() { return bFired; } + + AI_ResponseFollowup( void ) : followup_concept(NULL), followup_contexts(NULL), followup_delay(0), followup_target(NULL), followup_entityiotarget(NULL), followup_entityioinput(NULL), followup_entityiodelay(0), bFired(false) + {}; + AI_ResponseFollowup( char *_followup_concept, char *_followup_contexts, float _followup_delay, char *_followup_target, + char *_followup_entityiotarget, char *_followup_entityioinput, float _followup_entityiodelay ) : + followup_concept(_followup_concept), followup_contexts(_followup_contexts), followup_delay(_followup_delay), followup_target(_followup_target), + followup_entityiotarget(_followup_entityiotarget), followup_entityioinput(_followup_entityioinput), followup_entityiodelay(_followup_entityiodelay), + bFired(false) + {}; + }; +#pragma pack(pop) + + + enum ResponseType_t + { + RESPONSE_NONE = 0, + RESPONSE_SPEAK, + RESPONSE_SENTENCE, + RESPONSE_SCENE, + RESPONSE_RESPONSE, // A reference to another response by name + RESPONSE_PRINT, + RESPONSE_ENTITYIO, // poke an input on an entity +#ifdef MAPBASE + RESPONSE_VSCRIPT, // Run VScript code + RESPONSE_VSCRIPT_FILE, // Run a VScript file (bypasses ugliness and character limits when just using IncludeScript() with RESPONSE_VSCRIPT) +#endif + + NUM_RESPONSES, + }; + +#ifdef MAPBASE + // The "apply to world" context option has been replaced with a flag-based integer which can apply contexts to more things. + // + // New ones should be implemented in: + // CResponseSystem::BuildDispatchTables() - AI_ResponseSystem.cpp (with their own funcs for m_RuleDispatch) + // CRR_Response::Describe() - rr_response.cpp + // CAI_Expresser::SpeakDispatchResponse() - ai_speech.cpp + // + // Also mind that this is 8-bit + enum : uint8 + { + APPLYCONTEXT_SELF = (1 << 0), // Included for contexts that apply to both self and something else + APPLYCONTEXT_WORLD = (1 << 1), // Apply to world + + APPLYCONTEXT_SQUAD = (1 << 2), // Apply to squad + APPLYCONTEXT_ENEMY = (1 << 3), // Apply to enemy + }; +#endif + + +#pragma pack(push,1) + struct ResponseParams + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + enum + { + RG_DELAYAFTERSPEAK = (1<<0), + RG_SPEAKONCE = (1<<1), + RG_ODDS = (1<<2), + RG_RESPEAKDELAY = (1<<3), + RG_SOUNDLEVEL = (1<<4), + RG_DONT_USE_SCENE = (1<<5), + RG_STOP_ON_NONIDLE = (1<<6), + RG_WEAPONDELAY = (1<<7), + RG_DELAYBEFORESPEAK = (1<<8), + }; + + ResponseParams() + { + flags = 0; + odds = 100; + delay.start = 0; + delay.range = 0; + respeakdelay.start = 0; + respeakdelay.range = 0; + weapondelay.start = 0; + weapondelay.range = 0; + soundlevel = 0; + predelay.start = 0; + predelay.range = 0; + } + responseparams_interval_t delay; //4 + responseparams_interval_t respeakdelay; //8 + responseparams_interval_t weapondelay; //12 + + short odds; //14 + + short flags; //16 + byte soundlevel; //17 + + responseparams_interval_t predelay; //21 + + ALIGN32 AI_ResponseFollowup *m_pFollowup; + + }; +#pragma pack(pop) + + class CriteriaSet + { + public: + typedef CUtlSymbol CritSymbol_t; ///< just to make it clear that some symbols come out of our special static table + public: + CriteriaSet(); + CriteriaSet( const CriteriaSet& src ); + CriteriaSet( const char *criteria, const char *value ) ; // construct initialized with a key/value pair (convenience) + ~CriteriaSet(); + + static CritSymbol_t ComputeCriteriaSymbol( const char *criteria ); + void AppendCriteria( CritSymbol_t criteria, const char *value = "", float weight = 1.0f ); + void AppendCriteria( const char *criteria, const char *value = "", float weight = 1.0f ); + void AppendCriteria( const char *criteria, float value, float weight = 1.0f ); + void RemoveCriteria( const char *criteria ); + + void Describe() const; + + int GetCount() const; + int FindCriterionIndex( CritSymbol_t criteria ) const; + int FindCriterionIndex( const char *name ) const; + inline bool IsValidIndex( int index ) const; + + CritSymbol_t GetNameSymbol( int nIndex ) const; + inline static const char *SymbolToStr( const CritSymbol_t &symbol ); + const char *GetName( int index ) const; + const char *GetValue( int index ) const; + float GetWeight( int index ) const; + + /// Merge another CriteriaSet into this one. + void Merge( const CriteriaSet *otherCriteria ); + void Merge( const char *modifiers ); // add criteria parsed from a text string + + /// add all of the contexts herein onto an entity. all durations are infinite. + void WriteToEntity( CBaseEntity *pEntity ); + + // Accessors to things that need only be done under unusual circumstances. + inline void EnsureCapacity( int num ); + void Reset(); // clear out this criteria (should not be necessary) + + /// When this is true, calls to AppendCriteria on a criteria that already exists + /// will override the existing value. (This is the default behavior). Can be temporarily + /// set false to prevent such overrides. + inline void OverrideOnAppend( bool bOverride ) { m_bOverrideOnAppend = bOverride; } + + // For iteration from beginning to end (also should not be necessary except in + // save/load) + inline int Head() const; + inline int Next( int i ) const; // use with IsValidIndex above + + const static char kAPPLYTOWORLDPREFIX = '$'; + + /// A last minute l4d2 change: deferred contexts prefixed with a '$' + /// character are actually applied to the world. This matches the + /// related hack in CBaseEntity::AppplyContext. + /// This function works IN-PLACE on the "from" parameter. + /// any $-prefixed criteria in pFrom become prefixed by "world", + /// and are also written into pSetOnWorld. + /// *IF* a response matches using the modified criteria, then and only + /// then should you write back the criteria in pSetOnWorld to the world + /// entity, subsequent to the match but BEFORE the dispatch. + /// Returns the number of contexts modified. If it returns 0, then + /// pSetOnWorld is empty. + static int InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, + CriteriaSet * RESTRICT pSetOnWorld ); + + private: + void RemoveCriteria( int idx, bool bTestForPrefix ); + + struct CritEntry_t + { + CritEntry_t() : + criterianame( UTL_INVAL_SYMBOL ), + weight( 0.0f ) + { + value[ 0 ] = 0; + } + + CritEntry_t( const CritEntry_t& src ) + { + criterianame = src.criterianame; + value[ 0 ] = 0; + weight = src.weight; + SetValue( src.value ); + } + + CritEntry_t& operator=( const CritEntry_t& src ) + { + if ( this == &src ) + return *this; + + criterianame = src.criterianame; + weight = src.weight; + SetValue( src.value ); + + return *this; + } + + static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs ) + { + return lhs.criterianame < rhs.criterianame; + } + + void SetValue( char const *str ) + { + if ( !str ) + { + value[ 0 ] = 0; + } + else + { + Q_strncpy( value, str, sizeof( value ) ); + } + } + + CritSymbol_t criterianame; + char value[ 64 ]; + float weight; + }; + + static CUtlSymbolTable sm_CriteriaSymbols; + typedef CUtlRBTree< CritEntry_t, short > Dict_t; + Dict_t m_Lookup; + int m_nNumPrefixedContexts; // number of contexts prefixed with kAPPLYTOWORLDPREFIX + bool m_bOverrideOnAppend; + }; + + inline void CriteriaSet::EnsureCapacity( int num ) + { + m_Lookup.EnsureCapacity(num); + } + + //----------------------------------------------------------------------------- + // Purpose: Generic container for a response to a match to a criteria set + // This is what searching for a response returns + //----------------------------------------------------------------------------- + + class CRR_Response + { + public: + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + CRR_Response(); + CRR_Response( const CRR_Response &from ); + CRR_Response &operator=( const CRR_Response &from ); + ~CRR_Response(); + private: + void operator delete(void* p); // please do not new or delete CRR_Responses. + public: + + // void Release(); // we no longer encourage new and delete on these things + + void GetName( char *buf, size_t buflen ) const; + void GetResponse( char *buf, size_t buflen ) const; +#ifdef MAPBASE + void GetRule( char *buf, size_t buflen ) const; +#endif + const char* GetNamePtr() const; + const char* GetResponsePtr() const; + const ResponseParams *GetParams() const { return &m_Params; } + ResponseType_t GetType() const { return (ResponseType_t)m_Type; } + soundlevel_t GetSoundLevel() const; + float GetRespeakDelay() const; + float GetWeaponDelay() const; + bool GetSpeakOnce() const; + bool ShouldntUseScene( ) const; + bool ShouldBreakOnNonIdle( void ) const; + int GetOdds() const; + float GetDelay() const; + float GetPreDelay() const; + + inline bool IsEmpty() const; // true iff my response name is empty + void Invalidate() ; // wipe out my contents, mark me invalid + + // Get/set the contexts we apply to character and world after execution + void SetContext( const char *context ); + const char * GetContext( void ) const { return m_szContext; } + + // Get/set the score I matched with (under certain circumstances) + inline float GetMatchScore( void ) { return m_fMatchScore; } + inline void SetMatchScore( float f ) { m_fMatchScore = f; } + +#ifdef MAPBASE + int GetContextFlags() { return m_iContextFlags; } + bool IsApplyContextToWorld( void ) { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } + + inline short *GetInternalIndices() { return m_InternalIndices; } + inline void SetInternalIndices( short iGroup, short iWithinGroup ) { m_InternalIndices[0] = iGroup; m_InternalIndices[1] = iWithinGroup; } +#else + bool IsApplyContextToWorld( void ) { return m_bApplyContextToWorld; } +#endif + + void Describe( const CriteriaSet *pDebugCriteria = NULL ); + + void Init( ResponseType_t type, + const char *responseName, + const ResponseParams& responseparams, + const char *matchingRule, + const char *applyContext, + bool bApplyContextToWorld ); + +#ifdef MAPBASE + void Init( ResponseType_t type, + const char *responseName, + const ResponseParams& responseparams, + const char *matchingRule, + const char *applyContext, + int iContextFlags ); +#endif + + static const char *DescribeResponse( ResponseType_t type ); + + enum + { + MAX_RESPONSE_NAME = 64, + MAX_RULE_NAME = 64 + }; + + + private: + byte m_Type; + char m_szResponseName[ MAX_RESPONSE_NAME ]; + char m_szMatchingRule[ MAX_RULE_NAME ]; + + ResponseParams m_Params; + float m_fMatchScore; // when instantiated dynamically in SpeakFindResponse, the score of the rule that matched it. + + char * m_szContext; // context data we apply to character after running +#ifdef MAPBASE + int m_iContextFlags; + + // The response's original indices in the system. [0] is the group's index, [1] is the index within the group. + // For now, this is only set in prospecctive mode. It's used to call back to the ParserResponse and mark a prospectively chosen response as used. + short m_InternalIndices[2]; +#else + bool m_bApplyContextToWorld; +#endif + +#ifdef _MANAGED + friend ref class ResponseRulesCLI::ResponseQueryResult; +#endif + }; + + + + abstract_class IResponseFilter + { + public: + virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ) = 0; + }; + + abstract_class IResponseSystem + { + public: + virtual ~IResponseSystem() {} + + virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL ) = 0; + virtual void GetAllResponses( CUtlVector *pResponses ) = 0; + virtual void PrecacheResponses( bool bEnable ) = 0; + +#ifdef MAPBASE + // (Optional) Call this before and after using FindBestResponse() for a prospective lookup, e.g. a response that might not actually be used + // and should not trigger displayfirst, etc. + virtual void SetProspective( bool bToggle ) {}; + + // (Optional) Marks a prospective response as used + virtual void MarkResponseAsUsed( short iGroup, short iWithinGroup ) {}; +#endif + }; + + + + // INLINE FUNCTIONS + + // Used as a failsafe in finding responses. + bool CRR_Response::IsEmpty() const + { + return m_szResponseName[0] == 0; + } + + inline bool CriteriaSet::IsValidIndex( int index ) const + { + return ( index >= 0 && index < ((int)(m_Lookup.Count())) ); + } + + inline int CriteriaSet::Head() const + { + return m_Lookup.FirstInorder(); + } + + inline int CriteriaSet::Next( int i ) const + { + return m_Lookup.NextInorder(i); + } + + inline const char *CriteriaSet::SymbolToStr( const CritSymbol_t &symbol ) + { + return sm_CriteriaSymbols.String(symbol); + } + +} + +#include "rr_speechconcept.h" +#include "response_host_interface.h" + +#endif diff --git a/public/responserules/rr_speechconcept.h b/public/responserules/rr_speechconcept.h new file mode 100644 index 00000000..65b1bb6e --- /dev/null +++ b/public/responserules/rr_speechconcept.h @@ -0,0 +1,57 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Class data for an AI Concept, an atom of response-driven dialog. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RR_SPEECHCONCEPT_H +#define RR_SPEECHCONCEPT_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "utlsymbol.h" + +#define RR_CONCEPTS_ARE_STRINGS 0 + + +typedef CUtlSymbolTable CRR_ConceptSymbolTable; + +namespace ResponseRules +{ +class CRR_Concept +{ +public: // local typedefs + typedef CUtlSymbol tGenericId; // an int-like type that can be used to refer to all concepts of this type + tGenericId m_iConcept; + +public: + CRR_Concept() {}; + // construct concept from a string. + CRR_Concept(const char *fromString); + + // Return as a string + const char *GetStringConcept() const; + static const char *GetStringForGenericId(tGenericId genericId); + + operator tGenericId() const { return m_iConcept; } + operator const char *() const { return GetStringConcept(); } + inline bool operator==(const CRR_Concept &other) // default is compare by concept ids + { + return m_iConcept == other.m_iConcept; + } + bool operator==(const char *pszConcept); + +protected: + +private: + // dupe a concept + // CRR_Concept& operator=(CRR_Concept &other); + CRR_Concept& operator=(const char *fromString); +}; +}; + + +#endif diff --git a/public/rope_physics.cpp b/public/rope_physics.cpp index 9fe3ff52..5b8bfd89 100644 --- a/public/rope_physics.cpp +++ b/public/rope_physics.cpp @@ -60,7 +60,7 @@ void CBaseRopePhysics::Restart() void CBaseRopePhysics::ResetSpringLength( float flSpringDist ) { - m_flSpringDist = max( flSpringDist, 0 ); + m_flSpringDist = MAX( flSpringDist, 0 ); m_flSpringDistSqr = m_flSpringDist * m_flSpringDist; for( int i=0; i < NumSprings(); i++ ) diff --git a/public/rope_shared.h b/public/rope_shared.h index 54c28829..fe79b6e6 100644 --- a/public/rope_shared.h +++ b/public/rope_shared.h @@ -28,7 +28,11 @@ #define ROPE_COLLIDE (1<<2) // Collide with the world? #define ROPE_SIMULATE (1<<3) // Is the rope valid? #define ROPE_BREAKABLE (1<<4) // Can the endpoints detach? +#ifdef MAPBASE +#define ROPE_USE_WIND (1<<5) // Wind simulation on this rope. +#else #define ROPE_NO_WIND (1<<5) // No wind simulation on this rope. +#endif #define ROPE_INITIAL_HANG (1<<6) // By default, ropes will simulate for a bit internally when they // are created so they sag, but dynamically created ropes for things // like harpoons don't want this. diff --git a/public/saverestoretypes.h b/public/saverestoretypes.h index 7868e2fb..96e5cf5d 100644 --- a/public/saverestoretypes.h +++ b/public/saverestoretypes.h @@ -93,7 +93,7 @@ struct levellist_t { DECLARE_SIMPLE_DATADESC(); - char mapName[ MAX_MAP_NAME_SAVE ]; + char mapName[ MAX_MAP_NAME ]; char landmarkName[ 32 ]; edict_t *pentLandmark; Vector vecLandmarkOrigin; @@ -171,7 +171,7 @@ struct saverestorelevelinfo_t char szLandmarkName[20]; // landmark we'll spawn near in next level Vector vecLandmarkOffset; // for landmark transitions float time; - char szCurrentMapName[MAX_MAP_NAME_SAVE]; // To check global entities + char szCurrentMapName[MAX_MAP_NAME]; // To check global entities int mapVersion; }; @@ -181,7 +181,7 @@ class CGameSaveRestoreInfo { public: CGameSaveRestoreInfo() - : tableCount( 0 ), pTable( 0 ), m_pCurrentEntity( 0 ), m_EntityToIndex( 1024 ) + : m_iTableCount( 0 ), m_pTable( 0 ), m_pCurrentEntity( 0 ), m_EntityToIndex( 1024 ) { memset( &levelInfo, 0, sizeof( levelInfo ) ); modelSpaceOffset.Init( 0, 0, 0 ); @@ -189,8 +189,8 @@ class CGameSaveRestoreInfo void InitEntityTable( entitytable_t *pNewTable = NULL, int size = 0 ) { - pTable = pNewTable; - tableCount = size; + m_pTable = pNewTable; + m_iTableCount = size; for ( int i = 0; i < NumEntities(); i++ ) { @@ -200,17 +200,17 @@ class CGameSaveRestoreInfo entitytable_t *DetachEntityTable() { - entitytable_t *pReturn = pTable; - pTable = NULL; - tableCount = 0; + entitytable_t *pReturn = m_pTable; + m_pTable = NULL; + m_iTableCount = 0; return pReturn; } CBaseEntity *GetCurrentEntityContext() { return m_pCurrentEntity; } void SetCurrentEntityContext(CBaseEntity *pEntity) { m_pCurrentEntity = pEntity; } - int NumEntities() { return tableCount; } - entitytable_t *GetEntityInfo( int i ) { return (pTable + i); } + int NumEntities() { return m_iTableCount; } + entitytable_t *GetEntityInfo( int i ) { return (m_pTable + i); } float GetBaseTime() const { return levelInfo.time; } Vector GetLandmark() const { return ( levelInfo.fUseLandmark ) ? levelInfo.vecLandmarkOffset : vec3_origin; } @@ -218,13 +218,13 @@ class CGameSaveRestoreInfo { #ifdef GAME_DLL int i; - entitytable_t *pTable; + entitytable_t *m_pTable; int nEntities = NumEntities(); for ( i = 0; i < nEntities; i++ ) { - pTable = GetEntityInfo( i ); - m_EntityToIndex.Insert( CHashElement( pTable->hEnt.Get(), i ) ); + m_pTable = GetEntityInfo( i ); + m_EntityToIndex.Insert( CHashElement( m_pTable->hEnt.Get(), i ) ); } #endif } @@ -269,8 +269,8 @@ class CGameSaveRestoreInfo Vector modelSpaceOffset; // used only for globaly entity brushes modelled in different coordinate systems. private: - int tableCount; // Number of elements in the entity table - entitytable_t *pTable; // Array of entitytable_t elements (1 for each entity) + int m_iTableCount; // Number of elements in the entity table + entitytable_t *m_pTable; // Array of entitytable_t elements (1 for each entity) CBaseEntity *m_pCurrentEntity; // only valid during the save functions of this entity, NULL otherwise @@ -514,8 +514,8 @@ inline const char *CSaveRestoreSegment::StringFromSymbol( int token ) #ifndef _WIN32 inline unsigned CSaveRestoreSegment::_rotr ( unsigned val, int shift) { - unsigned lobit; /* non-zero means lo bit set */ - unsigned num = val; /* number to rotate */ + register unsigned lobit; /* non-zero means lo bit set */ + register unsigned num = val; /* number to rotate */ shift &= 0x1f; /* modulo 32 -- this will also make negative shifts work */ diff --git a/public/scratchpad3d.h b/public/scratchpad3d.h index 7e9aad66..30b2455c 100644 --- a/public/scratchpad3d.h +++ b/public/scratchpad3d.h @@ -51,7 +51,7 @@ class CScratchPad3D : public IScratchPad3D m_pCachedRenderData = NULL; } - ~CBaseCommand() + virtual ~CBaseCommand() { ReleaseCachedRenderData(); } diff --git a/public/sentence.cpp b/public/sentence.cpp index bb7ade5e..abdcca77 100644 --- a/public/sentence.cpp +++ b/public/sentence.cpp @@ -671,10 +671,6 @@ void CSentence::ParseDataVersionOnePointZero( CUtlBuffer& buf ) buf.GetString( token ); if ( strlen( token ) <= 0 ) break; - - // end of block, return - if ( !V_strcmp( token, "}" ) ) - break; char section[ 256 ]; Q_strncpy( section, token, sizeof( section ) ); @@ -1100,7 +1096,7 @@ void CSentence::ResetToBase( void ) void CSentence::MarkNewPhraseBase( void ) { #if PHONEME_EDITOR - m_nResetWordBase = max( m_Words.Size(), 0 ); + m_nResetWordBase = MAX( m_Words.Size(), 0 ); #endif } @@ -1495,10 +1491,10 @@ float CSentence::GetIntensity( float time, float endtime ) int end = i + 1; int next = i + 2; - prev = max( -1, prev ); - start = max( -1, start ); - end = min( end, GetNumSamples() ); - next = min( next, GetNumSamples() ); + prev = MAX( -1, prev ); + start = MAX( -1, start ); + end = MIN( end, GetNumSamples() ); + next = MIN( next, GetNumSamples() ); CEmphasisSample *esPre = GetBoundedSample( prev, endtime ); CEmphasisSample *esStart = GetBoundedSample( start, endtime ); @@ -1682,7 +1678,7 @@ bool CSentence::ShouldSplitWord( char in ) if ( in <= 32 ) return true; - if ( (unsigned char)in > SCHAR_MAX ) + if ( in >= 128 ) return true; if ( ispunct( in ) ) diff --git a/public/shaderapi/ishaderapi.h b/public/shaderapi/ishaderapi.h index 1a90caee..367cd0e9 100644 --- a/public/shaderapi/ishaderapi.h +++ b/public/shaderapi/ishaderapi.h @@ -82,7 +82,7 @@ enum CreateTextureFlags_t TEXTURE_CREATE_VERTEXTEXTURE = 0x0040, // for internal use only TEXTURE_CREATE_FALLBACK = 0x0080, // 360 only TEXTURE_CREATE_NOD3DMEMORY = 0x0100, // 360 only - TEXTURE_CREATE_SYSMEM = 0x0200, // This texture should be alloc'd in the sysmem pool + TEXTURE_CREATE_UNUSED3 = 0x0200, // Dead TEXTURE_CREATE_UNUSED4 = 0x0400, // Dead TEXTURE_CREATE_UNUSED5 = 0x0800, // Dead TEXTURE_CREATE_UNFILTERABLE_OK = 0x1000, @@ -611,13 +611,6 @@ abstract_class IShaderAPI : public IShaderDynamicAPI //extended clear buffers function with alpha independent from color virtual void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) = 0; - - // Allows copying a render target to another texture by specifying them both. - virtual void CopyRenderTargetToScratchTexture( ShaderAPITextureHandle_t srcRt, ShaderAPITextureHandle_t dstTex, Rect_t *pSrcRect = NULL, Rect_t *pDstRect = NULL ) = 0; - - // Allows locking and unlocking of very specific surface types. - virtual void LockRect( void** pOutBits, int* pOutPitch, ShaderAPITextureHandle_t texHandle, int mipmap, int x, int y, int w, int h, bool bWrite, bool bRead ) = 0; - virtual void UnlockRect( ShaderAPITextureHandle_t texHandle, int mipmap ) = 0; }; diff --git a/public/shaderapi/ishaderdynamic.h b/public/shaderapi/ishaderdynamic.h index b78942d2..4d1d2d2d 100644 --- a/public/shaderapi/ishaderdynamic.h +++ b/public/shaderapi/ishaderdynamic.h @@ -36,8 +36,7 @@ struct LightState_t { int m_nNumLights; bool m_bAmbientLight; - bool m_bStaticLightVertex; - bool m_bStaticLightTexel; + bool m_bStaticLight; inline int HasDynamicLight() { return (m_bAmbientLight || (m_nNumLights > 0)) ? 1 : 0; } }; @@ -107,9 +106,6 @@ enum StandardTextureId_t // A snapshot of the frame buffer's depth. Currently only valid on the 360 TEXTURE_IDENTITY_LIGHTWARP, - // Equivalent to the debug material for mat_luxels, in convenient texture form. - TEXTURE_DEBUG_LUXELS, - TEXTURE_MAX_STD_TEXTURES = 32 }; diff --git a/public/shaderlib/BaseShader.h b/public/shaderlib/BaseShader.h index 6119183d..93a38c4f 100644 --- a/public/shaderlib/BaseShader.h +++ b/public/shaderlib/BaseShader.h @@ -168,8 +168,6 @@ class CBaseShader : public IShader void BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame = 0 ); void BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame = 0 ); - void GetTextureDimensions( float* pOutWidth, float* pOutHeight, int nTextureVar ); - // Is the texture translucent? bool TextureIsTranslucent( int textureVar, bool isBaseTexture ); diff --git a/public/shaderlib/cshader.h b/public/shaderlib/cshader.h index 9c693638..dcaee307 100644 --- a/public/shaderlib/cshader.h +++ b/public/shaderlib/cshader.h @@ -12,9 +12,6 @@ #pragma once #endif -// uncomment this if you want to build for nv3x -//#define NV3X 1 - // This is what all shaders include. // CBaseShader will become CShader in this file. #include "materialsystem/ishaderapi.h" @@ -32,7 +29,9 @@ #include "shaderlib/ShaderDLL.h" // make "local variable is initialized but not referenced" warnings errors for combo checking macros +#ifdef _MSC_VER #pragma warning ( error : 4189 ) +#endif //----------------------------------------------------------------------------- // Global interfaces @@ -41,33 +40,21 @@ extern IMaterialSystemHardwareConfig *g_pHardwareConfig; extern const MaterialSystem_Config_t *g_pConfig; extern bool g_shaderConfigDumpEnable; -// Helper method -bool IsUsingGraphics(); - -#define SOFTWARE_VERTEX_SHADER(name) \ - static void SoftwareVertexShader_ ## name( CMeshBuilder &meshBuilder, IMaterialVar **params, IShaderDynamicAPI* pShaderAPI ) - -#define FORWARD_DECLARE_SOFTWARE_VERTEX_SHADER(name)\ - static void SoftwareVertexShader_ ## name( CMeshBuilder &meshBuilder, IMaterialVar **params, IShaderDynamicAPI* pShaderAPI ); - -#define USE_SOFTWARE_VERTEX_SHADER(name) \ - m_SoftwareVertexShader = SoftwareVertexShader_ ## name - #define SHADER_INIT_PARAMS() \ - virtual void OnInitShaderParams( IMaterialVar **params, const char *pMaterialName ) + void OnInitShaderParams( IMaterialVar **params, const char *pMaterialName ) override #define SHADER_FALLBACK \ - virtual char const* GetFallbackShader( IMaterialVar** params ) const + const char *GetFallbackShader( IMaterialVar** params ) const override // Typesafe flag setting -inline void CShader_SetFlags( IMaterialVar **params, MaterialVarFlags_t _flag ) +inline void CShader_SetFlags( IMaterialVar **params, MaterialVarFlags_t flag ) { - params[FLAGS]->SetIntValue( params[FLAGS]->GetIntValue() | (_flag) ); + params[FLAGS]->SetIntValue( params[FLAGS]->GetIntValue() | flag ); } -inline bool CShader_IsFlagSet( IMaterialVar **params, MaterialVarFlags_t _flag ) +inline bool CShader_IsFlagSet( IMaterialVar **params, MaterialVarFlags_t flag ) { - return ((params[FLAGS]->GetIntValue() & (_flag) ) != 0); + return (params[FLAGS]->GetIntValue() & flag ) != 0; } #define SET_FLAGS( _flag ) CShader_SetFlags( params, _flag ) @@ -215,19 +202,19 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag #define SHADER_INIT \ - char const* GetName() const \ + char const* GetName() const override \ { \ return s_Name; \ } \ - int GetFlags() const \ + int GetFlags() const override \ { \ return s_nFlags; \ } \ - int GetNumParams() const \ + int GetNumParams() const override \ {\ return CBaseClass::GetNumParams() + s_ShaderParams.Count();\ }\ - char const* GetParamName( int param ) const \ + char const* GetParamName( int param ) const override \ {\ int nBaseClassParamCount = CBaseClass::GetNumParams(); \ if (param < nBaseClassParamCount) \ @@ -235,7 +222,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag else \ return s_ShaderParams[param - nBaseClassParamCount]->GetName(); \ }\ - char const* GetParamHelp( int param ) const \ + char const* GetParamHelp( int param ) const override \ {\ int nBaseClassParamCount = CBaseClass::GetNumParams(); \ if (param < nBaseClassParamCount) \ @@ -248,7 +235,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag else \ return s_ShaderParams[param - nBaseClassParamCount]->GetHelp(); \ }\ - ShaderParamType_t GetParamType( int param ) const \ + ShaderParamType_t GetParamType( int param ) const override \ {\ int nBaseClassParamCount = CBaseClass::GetNumParams(); \ if (param < nBaseClassParamCount) \ @@ -256,7 +243,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag else \ return s_ShaderParams[param - nBaseClassParamCount]->GetType(); \ }\ - char const* GetParamDefault( int param ) const \ + char const* GetParamDefault( int param ) const override \ {\ int nBaseClassParamCount = CBaseClass::GetNumParams(); \ if (param < nBaseClassParamCount) \ @@ -269,7 +256,7 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag else \ return s_ShaderParams[param - nBaseClassParamCount]->GetDefault(); \ }\ - int GetParamFlags( int param ) const \ + int GetParamFlags( int param ) const override \ {\ int nBaseClassParamCount = CBaseClass::GetNumParams(); \ if (param < nBaseClassParamCount) \ @@ -282,15 +269,14 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag else \ return s_ShaderParams[param - nBaseClassParamCount]->GetFlags(); \ }\ - void OnInitShaderInstance( IMaterialVar **params, IShaderInit *pShaderInit, const char *pMaterialName ) + void OnInitShaderInstance( IMaterialVar **params, IShaderInit *pShaderInit, const char *pMaterialName ) override #define SHADER_DRAW \ - void OnDrawElements( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) + void OnDrawElements( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) override #define SHADOW_STATE if (pShaderShadow) #define DYNAMIC_STATE if (pShaderAPI) -#define ShaderWarning if (pShaderShadow) Warning //----------------------------------------------------------------------------- // Used to easily define a shader which *always* falls back @@ -353,70 +339,68 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // psh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_PIXEL_SHADER #define DECLARE_DYNAMIC_PIXEL_SHADER( shader ) \ - int declaredynpixshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( declaredynpixshader_ ## shader ## _missingcurlybraces ); \ - shader ## _Dynamic_Index _pshIndex; \ - int psh ## shader = 0 + shader ## _Dynamic_Index _pshIndex( pShaderAPI ); \ + constexpr int psh ## shader = 1 // vsh ## shader is used here to generate a warning if you don't ever call SET_DYNAMIC_VERTEX_SHADER #define DECLARE_DYNAMIC_VERTEX_SHADER( shader ) \ - int declaredynvertshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( declaredynvertshader_ ## shader ## _missingcurlybraces ); \ - shader ## _Dynamic_Index _vshIndex; \ - int vsh ## shader = 0 + shader ## _Dynamic_Index _vshIndex( pShaderAPI ); \ + constexpr int vsh ## shader = 1 // psh ## shader is used here to generate a warning if you don't ever call SET_STATIC_PIXEL_SHADER #define DECLARE_STATIC_PIXEL_SHADER( shader ) \ - int declarestaticpixshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( declarestaticpixshader_ ## shader ## _missingcurlybraces ); \ - shader ## _Static_Index _pshIndex; \ - int psh ## shader = 0 + shader ## _Static_Index _pshIndex( pShaderShadow, params ); \ + constexpr int psh ## shader = 1 // vsh ## shader is used here to generate a warning if you don't ever call SET_STATIC_VERTEX_SHADER #define DECLARE_STATIC_VERTEX_SHADER( shader ) \ - int declarestaticvertshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( declarestaticvertshader_ ## shader ## _missingcurlybraces ); \ - shader ## _Static_Index _vshIndex; \ - int vsh ## shader = 0 + shader ## _Static_Index _vshIndex( pShaderShadow, params ); \ + constexpr int vsh ## shader = 1 // psh_forgot_to_set_dynamic_ ## var is used to make sure that you set all // all combos. If you don't, you will get an undefined variable used error // in the SET_DYNAMIC_PIXEL_SHADER block. #define SET_DYNAMIC_PIXEL_SHADER_COMBO( var, val ) \ - int dynpixshadercombo_ ## var ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynpixshadercombo_ ## var ## _missingcurlybraces ); \ - _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ - int psh_forgot_to_set_dynamic_ ## var = 0 + _pshIndex.Set ## var( ( val ) ); \ + constexpr int psh_forgot_to_set_dynamic_ ## var = 1 + +#define SET_DYNAMIC_PIXEL_SHADER_COMBO_OVERRIDE_DEFAULT( var, val ) \ + _pshIndex.Set ## var( ( val ) ); + // vsh_forgot_to_set_dynamic_ ## var is used to make sure that you set all // all combos. If you don't, you will get an undefined variable used error // in the SET_DYNAMIC_VERTEX_SHADER block. #define SET_DYNAMIC_VERTEX_SHADER_COMBO( var, val ) \ - int dynvertshadercombo_ ## var ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynvertshadercombo_ ## var ## _missingcurlybraces ); \ - _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS dyn var %s = %d (%s)", #var, (int) val, #val );}; \ - int vsh_forgot_to_set_dynamic_ ## var = 0 + _vshIndex.Set ## var( ( val ) ); \ + constexpr int vsh_forgot_to_set_dynamic_ ## var = 1 + +#define SET_DYNAMIC_VERTEX_SHADER_COMBO_OVERRIDE_DEFAULT( var, val ) \ + _vshIndex.Set ## var( ( val ) ); // psh_forgot_to_set_static_ ## var is used to make sure that you set all // all combos. If you don't, you will get an undefined variable used error // in the SET_STATIC_PIXEL_SHADER block. #define SET_STATIC_PIXEL_SHADER_COMBO( var, val ) \ - int staticpixshadercombo_ ## var ## _missingcurlybraces = 0; \ - NOTE_UNUSED( staticpixshadercombo_ ## var ## _missingcurlybraces ); \ - _pshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n PS stat var %s = %d (%s)", #var, (int) val, #val );}; \ - int psh_forgot_to_set_static_ ## var = 0 + _pshIndex.Set ## var( ( val ) ); \ + constexpr int psh_forgot_to_set_static_ ## var = 1 + +#define SET_STATIC_PIXEL_SHADER_COMBO_OVERRIDE_DEFAULT( var, val ) \ + _pshIndex.Set ## var( ( val ) ); + // vsh_forgot_to_set_static_ ## var is used to make sure that you set all // all combos. If you don't, you will get an undefined variable used error // in the SET_STATIC_VERTEX_SHADER block. #define SET_STATIC_VERTEX_SHADER_COMBO( var, val ) \ - int staticvertshadercombo_ ## var ## _missingcurlybraces = 0; \ - NOTE_UNUSED( staticvertshadercombo_ ## var ## _missingcurlybraces ); \ - _vshIndex.Set ## var( ( val ) ); if(g_shaderConfigDumpEnable){printf("\n VS stat var %s = %d (%s)", #var, (int) val, #val );}; \ - int vsh_forgot_to_set_static_ ## var = 0 + _vshIndex.Set ## var( ( val ) ); \ + constexpr int vsh_forgot_to_set_static_ ## var = 1 + +#define SET_STATIC_VERTEX_SHADER_COMBO_OVERRIDE_DEFAULT( var, val ) \ + _vshIndex.Set ## var( ( val ) ); // psh_testAllCombos adds up all of the psh_forgot_to_set_dynamic_ ## var's from @@ -425,19 +409,13 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // psh ## shader being set to itself ensures that DECLARE_DYNAMIC_PIXEL_SHADER // was called for this particular shader. #define SET_DYNAMIC_PIXEL_SHADER( shader ) \ - int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ - int psh_testAllCombos = shaderDynamicTest_ ## shader; \ - NOTE_UNUSED( psh_testAllCombos ); \ - NOTE_UNUSED( psh ## shader ); \ + static_assert( ( shaderDynamicTest_ ## shader ) != 0, "Missing combo!" ); \ + static_assert( psh ## shader != 0, "Not pixel shader!" ); \ pShaderAPI->SetPixelShaderIndex( _pshIndex.GetIndex() ) #define SET_DYNAMIC_PIXEL_SHADER_CMD( cmdstream, shader ) \ - int dynamicpixshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynamicpixshader_ ## shader ## _missingcurlybraces ); \ - int psh_testAllCombos = shaderDynamicTest_ ## shader; \ - NOTE_UNUSED( psh_testAllCombos ); \ - NOTE_UNUSED( psh ## shader ); \ + static_assert( ( shaderDynamicTest_ ## shader ) != 0, "Missing combo!" ); \ + static_assert( psh ## shader != 0, "Not pixel shader!" ); \ cmdstream.SetPixelShaderIndex( _pshIndex.GetIndex() ) @@ -447,19 +425,13 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // vsh ## shader being set to itself ensures that DECLARE_DYNAMIC_VERTEX_SHADER // was called for this particular shader. #define SET_DYNAMIC_VERTEX_SHADER( shader ) \ - int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ - int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ - NOTE_UNUSED( vsh_testAllCombos ); \ - NOTE_UNUSED( vsh ## shader ); \ + static_assert( ( shaderDynamicTest_ ## shader ) != 0, "Missing combo!" ); \ + static_assert( vsh ## shader != 0, "Not vertex shader!" ); \ pShaderAPI->SetVertexShaderIndex( _vshIndex.GetIndex() ) #define SET_DYNAMIC_VERTEX_SHADER_CMD( cmdstream, shader ) \ - int dynamicvertshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( dynamicvertshader_ ## shader ## _missingcurlybraces ); \ - int vsh_testAllCombos = shaderDynamicTest_ ## shader; \ - NOTE_UNUSED( vsh_testAllCombos ); \ - NOTE_UNUSED( vsh ## shader ); \ + static_assert( shaderDynamicTest_ ## shader != 0, "Missing combo!" ); \ + static_assert( vsh ## shader != 0, "Not vertex shader!" ); \ cmdstream.SetVertexShaderIndex( _vshIndex.GetIndex() ) @@ -469,11 +441,8 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // psh ## shader being set to itself ensures that DECLARE_STATIC_PIXEL_SHADER // was called for this particular shader. #define SET_STATIC_PIXEL_SHADER( shader ) \ - int staticpixshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( staticpixshader_ ## shader ## _missingcurlybraces ); \ - int psh_testAllCombos = shaderStaticTest_ ## shader; \ - NOTE_UNUSED( psh_testAllCombos ); \ - NOTE_UNUSED( psh ## shader ); \ + static_assert( ( shaderStaticTest_ ## shader ) != 0, "Missing combo!" ); \ + static_assert( psh ## shader != 0, "Not pixel shader!" ); \ pShaderShadow->SetPixelShader( #shader, _pshIndex.GetIndex() ) // vsh_testAllCombos adds up all of the vsh_forgot_to_set_static_ ## var's from @@ -482,11 +451,8 @@ inline bool CShader_IsFlag2Set( IMaterialVar **params, MaterialVarFlags2_t _flag // vsh ## shader being set to itself ensures that DECLARE_STATIC_VERTEX_SHADER // was called for this particular shader. #define SET_STATIC_VERTEX_SHADER( shader ) \ - int staticvertshader_ ## shader ## _missingcurlybraces = 0; \ - NOTE_UNUSED( staticvertshader_ ## shader ## _missingcurlybraces ); \ - int vsh_testAllCombos = shaderStaticTest_ ## shader; \ - NOTE_UNUSED( vsh_testAllCombos ); \ - NOTE_UNUSED( vsh ## shader ); \ + static_assert( shaderStaticTest_ ## shader != 0, "Missing combo!" ); \ + static_assert( vsh ## shader != 0, "Not vertex shader!" ); \ pShaderShadow->SetVertexShader( #shader, _vshIndex.GetIndex() ) #endif // CSHADER_H diff --git a/public/smooth_average.h b/public/smooth_average.h index 25f694b9..c8b529fe 100644 --- a/public/smooth_average.h +++ b/public/smooth_average.h @@ -123,12 +123,12 @@ inline CTimingInfo< T > CalcSmoothAverage_Struct( const T &value, int nTimes, co { if ( i != newValueIndex ) { - info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); - info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + info.m_HighAverage = MAX( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = MIN( pInfo->m_Values[i].m_Average, info.m_LowAverage ); } - info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); - info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + info.m_HighValue = MAX( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = MIN( pInfo->m_Values[i].m_Value, info.m_LowValue ); info.m_AverageValue += pInfo->m_Values[i].m_Value; } @@ -194,12 +194,12 @@ inline CTimingInfo< T > SumOverTimeInterval_Struct( const T &value, float nSecon { if ( i != newValueIndex ) { - info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); - info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + info.m_HighAverage = MAX( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = MIN( pInfo->m_Values[i].m_Average, info.m_LowAverage ); } - info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); - info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + info.m_HighValue = MAX( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = MIN( pInfo->m_Values[i].m_Value, info.m_LowValue ); info.m_AverageValue += pInfo->m_Values[i].m_Value; } diff --git a/public/soundcombiner.cpp b/public/soundcombiner.cpp index 3445b46a..62705a5a 100644 --- a/public/soundcombiner.cpp +++ b/public/soundcombiner.cpp @@ -612,8 +612,8 @@ bool CSoundCombiner::AppendSilence( int ¤tsample, float duration ) while ( --numSamples >= 0 ) { currentValue += random->RandomInt( -MOTION_MAXSTEP, MOTION_MAXSTEP ); - currentValue = min( maxValue, currentValue ); - currentValue = max( minValue, currentValue ); + currentValue = MIN( maxValue, currentValue ); + currentValue = MAX( minValue, currentValue ); // Downsample to 0 65556 range short s = (float)currentValue / 32768.0f; diff --git a/public/stdstring.h b/public/stdstring.h index c72320f7..50ed1c29 100644 --- a/public/stdstring.h +++ b/public/stdstring.h @@ -70,6 +70,15 @@ class CStdStringSaveRestoreOps : public CDefSaveRestoreOps std::string *pString = (std::string *)fieldInfo.pField; return pString->empty(); } + +#ifdef MAPBASE + virtual bool Parse( const SaveRestoreFieldInfo_t &fieldInfo, char const* szValue ) + { + std::string *pString = (std::string *)fieldInfo.pField; + pString->assign(szValue); + return true; + } +#endif }; //------------------------------------- @@ -85,4 +94,9 @@ inline ISaveRestoreOps *GetStdStringDataOps() #define DEFINE_STDSTRING(name) \ { FIELD_CUSTOM, #name, { offsetof(classNameTypedef,name), 0 }, 1, FTYPEDESC_SAVE, NULL, GetStdStringDataOps(), NULL } +#ifdef MAPBASE +#define DEFINE_KEYSTDSTRING(name,mapname) \ + { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, GetStdStringDataOps(), NULL } +#endif + #endif // STDSTRING_H diff --git a/public/steam/isteamapplist.h b/public/steam/isteamapplist.h index e6726c1a..91de8324 100644 --- a/public/steam/isteamapplist.h +++ b/public/steam/isteamapplist.h @@ -10,8 +10,7 @@ #pragma once #endif -#include "isteamclient.h" -#include "steamtypes.h" +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: This is a restricted interface that can only be used by previously approved apps, @@ -25,7 +24,7 @@ class ISteamAppList virtual uint32 GetNumInstalledApps() = 0; virtual uint32 GetInstalledApps( AppId_t *pvecAppID, uint32 unMaxAppIDs ) = 0; - virtual int GetAppName( AppId_t nAppID, char *pchName, int cchNameMax ) = 0; // returns -1 if no name was found + virtual int GetAppName( AppId_t nAppID, STEAM_OUT_STRING() char *pchName, int cchNameMax ) = 0; // returns -1 if no name was found virtual int GetAppInstallDir( AppId_t nAppID, char *pchDirectory, int cchNameMax ) = 0; // returns -1 if no dir was found virtual int GetAppBuildId( AppId_t nAppID ) = 0; // return the buildid of this app, may change at any time based on backend updates to the game @@ -33,30 +32,36 @@ class ISteamAppList #define STEAMAPPLIST_INTERFACE_VERSION "STEAMAPPLIST_INTERFACE_VERSION001" +// Global interface accessor +inline ISteamAppList *SteamAppList(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamAppList *, SteamAppList, STEAMAPPLIST_INTERFACE_VERSION ); + // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //--------------------------------------------------------------------------------- // Purpose: Sent when a new app is installed //--------------------------------------------------------------------------------- -DEFINE_CALLBACK( SteamAppInstalled_t, k_iSteamAppListCallbacks + 1 ); - CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( SteamAppInstalled_t, k_iSteamAppListCallbacks + 1 ) +STEAM_CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs +STEAM_CALLBACK_MEMBER( 1, int, m_iInstallFolderIndex ) // library folder the app is installed +STEAM_CALLBACK_END( 2 ) //--------------------------------------------------------------------------------- // Purpose: Sent when an app is uninstalled //--------------------------------------------------------------------------------- -DEFINE_CALLBACK( SteamAppUninstalled_t, k_iSteamAppListCallbacks + 2 ); - CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( SteamAppUninstalled_t, k_iSteamAppListCallbacks + 2 ) +STEAM_CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs +STEAM_CALLBACK_MEMBER( 1, int, m_iInstallFolderIndex ) // library folder the app was installed +STEAM_CALLBACK_END(2) #pragma pack( pop ) diff --git a/public/steam/isteamapps.h b/public/steam/isteamapps.h index 07005836..fd6b3340 100644 --- a/public/steam/isteamapps.h +++ b/public/steam/isteamapps.h @@ -10,7 +10,9 @@ #pragma once #endif -const int k_cubAppProofOfPurchaseKeyMax = 64; // max bytes of a legacy cd key we support +#include "steam_api_common.h" + +const int k_cubAppProofOfPurchaseKeyMax = 240; // max supported length of a legacy cd key //----------------------------------------------------------------------------- @@ -50,7 +52,7 @@ class ISteamApps virtual void InstallDLC( AppId_t nAppID ) = 0; virtual void UninstallDLC( AppId_t nAppID ) = 0; - // Request cd-key for yourself or owned DLC. If you are interested in this + // Request legacy cd-key for yourself or owned DLC. If you are interested in this // data then make sure you provide us with a list of valid keys to be distributed // to users when they purchase the game, before the game ships. // You'll receive an AppProofOfPurchaseKeyResponse_t callback when @@ -65,26 +67,57 @@ class ISteamApps virtual uint32 GetAppInstallDir( AppId_t appID, char *pchFolder, uint32 cchFolderBufferSize ) = 0; virtual bool BIsAppInstalled( AppId_t appID ) = 0; // returns true if that app is installed (not necessarily owned) - virtual CSteamID GetAppOwner() = 0; // returns the SteamID of the original owner. If different from current user, it's borrowed + // returns the SteamID of the original owner. If this CSteamID is different from ISteamUser::GetSteamID(), + // the user has a temporary license borrowed via Family Sharing + virtual CSteamID GetAppOwner() = 0; - // Returns the associated launch param if the game is run via steam://run///?param1=value1;param2=value2;param3=value3 etc. + // Returns the associated launch param if the game is run via steam://run///?param1=value1¶m2=value2¶m3=value3 etc. // Parameter names starting with the character '@' are reserved for internal use and will always return and empty string. // Parameter names starting with an underscore '_' are reserved for steam features -- they can be queried by the game, // but it is advised that you not param names beginning with an underscore for your own features. - virtual const char *GetLaunchQueryParam( const char *pchKey ) = 0; + // Check for new launch parameters on callback NewUrlLaunchParameters_t + virtual const char *GetLaunchQueryParam( const char *pchKey ) = 0; // get download progress for optional DLC virtual bool GetDlcDownloadProgress( AppId_t nAppID, uint64 *punBytesDownloaded, uint64 *punBytesTotal ) = 0; // return the buildid of this app, may change at any time based on backend updates to the game virtual int GetAppBuildId() = 0; -#ifdef _PS3 - // Result returned in a RegisterActivationCodeResponse_t callresult - virtual SteamAPICall_t RegisterActivationCode( const char *pchActivationCode ) = 0; -#endif + + // Request all proof of purchase keys for the calling appid and asociated DLC. + // A series of AppProofOfPurchaseKeyResponse_t callbacks will be sent with + // appropriate appid values, ending with a final callback where the m_nAppId + // member is k_uAppIdInvalid (zero). + virtual void RequestAllProofOfPurchaseKeys() = 0; + + STEAM_CALL_RESULT( FileDetailsResult_t ) + virtual SteamAPICall_t GetFileDetails( const char* pszFileName ) = 0; + + // Get command line if game was launched via Steam URL, e.g. steam://run////. + // This method of passing a connect string (used when joining via rich presence, accepting an + // invite, etc) is preferable to passing the connect string on the operating system command + // line, which is a security risk. In order for rich presence joins to go through this + // path and not be placed on the OS command line, you must set a value in your app's + // configuration on Steam. Ask Valve for help with this. + // + // If game was already running and launched again, the NewUrlLaunchParameters_t will be fired. + virtual int GetLaunchCommandLine( char *pszCommandLine, int cubCommandLine ) = 0; + + // Check if user borrowed this game via Family Sharing, If true, call GetAppOwner() to get the lender SteamID + virtual bool BIsSubscribedFromFamilySharing() = 0; + + // check if game is a timed trial with limited playtime + virtual bool BIsTimedTrial( uint32* punSecondsAllowed, uint32* punSecondsPlayed ) = 0; + + // set current DLC AppID being played (or 0 if none). Allows Steam to track usage of major DLC extensions + virtual bool SetDlcContext( AppId_t nAppID ) = 0; }; -#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION007" +#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION008" + +// Global interface accessor +inline ISteamApps *SteamApps(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamApps *, SteamApps, STEAMAPPS_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -92,7 +125,7 @@ class ISteamApps #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- // Purpose: posted after the user gains ownership of DLC & that DLC is installed @@ -127,28 +160,57 @@ struct RegisterActivationCodeResponse_t uint32 m_unPackageRegistered; // package that was registered. Only set on success }; + +//--------------------------------------------------------------------------------- +// Purpose: posted after the user gains executes a Steam URL with command line or query parameters +// such as steam://run///-commandline/?param1=value1¶m2=value2¶m3=value3 etc +// while the game is already running. The new params can be queried +// with GetLaunchQueryParam and GetLaunchCommandLine +//--------------------------------------------------------------------------------- +struct NewUrlLaunchParameters_t +{ + enum { k_iCallback = k_iSteamAppsCallbacks + 14 }; +}; + + //----------------------------------------------------------------------------- -// Purpose: response to RegisterActivationCode() +// Purpose: response to RequestAppProofOfPurchaseKey/RequestAllProofOfPurchaseKeys +// for supporting third-party CD keys, or other proof-of-purchase systems. //----------------------------------------------------------------------------- struct AppProofOfPurchaseKeyResponse_t { - enum { k_iCallback = k_iSteamAppsCallbacks + 13 }; + enum { k_iCallback = k_iSteamAppsCallbacks + 21 }; EResult m_eResult; uint32 m_nAppID; - char m_rgchKey[ k_cubAppProofOfPurchaseKeyMax ]; + uint32 m_cchKeyLength; + char m_rgchKey[k_cubAppProofOfPurchaseKeyMax]; }; -//--------------------------------------------------------------------------------- -// Purpose: posted after the user gains executes a steam url with query parameters -// such as steam://run///?param1=value1;param2=value2;param3=value3; etc -// while the game is already running. The new params can be queried -// with GetLaunchQueryParam. -//--------------------------------------------------------------------------------- -struct NewLaunchQueryParameters_t + +//----------------------------------------------------------------------------- +// Purpose: response to GetFileDetails +//----------------------------------------------------------------------------- +struct FileDetailsResult_t { - enum { k_iCallback = k_iSteamAppsCallbacks + 14 }; + enum { k_iCallback = k_iSteamAppsCallbacks + 23 }; + EResult m_eResult; + uint64 m_ulFileSize; // original file size in bytes + uint8 m_FileSHA[20]; // original file SHA1 hash + uint32 m_unFlags; // }; +//----------------------------------------------------------------------------- +// Purpose: called for games in Timed Trial mode +//----------------------------------------------------------------------------- +struct TimedTrialStatus_t +{ + enum { k_iCallback = k_iSteamAppsCallbacks + 30 }; + AppId_t m_unAppID; // appID + bool m_bIsOffline; // if true, time allowed / played refers to offline time, not total time + uint32 m_unSecondsAllowed; // how many seconds the app can be played in total + uint32 m_unSecondsPlayed; // how many seconds the app was already played +}; + #pragma pack( pop ) #endif // ISTEAMAPPS_H diff --git a/public/steam/isteamappticket.h b/public/steam/isteamappticket.h new file mode 100644 index 00000000..21fb9e13 --- /dev/null +++ b/public/steam/isteamappticket.h @@ -0,0 +1,28 @@ +//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: a private, but well versioned, interface to get at critical bits +// of a steam3 appticket - consumed by the simple drm wrapper to let it +// ask about ownership with greater confidence. +// +//============================================================================= + +#ifndef ISTEAMAPPTICKET_H +#define ISTEAMAPPTICKET_H +#pragma once + +//----------------------------------------------------------------------------- +// Purpose: hand out a reasonable "future proof" view of an app ownership ticket +// the raw (signed) buffer, and indices into that buffer where the appid and +// steamid are located. the sizes of the appid and steamid are implicit in +// (each version of) the interface - currently uin32 appid and uint64 steamid +//----------------------------------------------------------------------------- +class ISteamAppTicket +{ +public: + virtual uint32 GetAppOwnershipTicketData( uint32 nAppID, void *pvBuffer, uint32 cbBufferLength, uint32 *piAppId, uint32 *piSteamId, uint32 *piSignature, uint32 *pcbSignature ) = 0; +}; + +#define STEAMAPPTICKET_INTERFACE_VERSION "STEAMAPPTICKET_INTERFACE_VERSION001" + + +#endif // ISTEAMAPPTICKET_H diff --git a/public/steam/isteamclient.h b/public/steam/isteamclient.h index 796d72d6..8cd45891 100644 --- a/public/steam/isteamclient.h +++ b/public/steam/isteamclient.h @@ -1,8 +1,9 @@ -//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======= +//====== Copyright Valve Corporation, All rights reserved. ==================== // -// Purpose: Main interface for loading and accessing Steamworks API's from the -// Steam client. -// For most uses, this code is wrapped inside of SteamAPI_Init() +// Internal low-level access to Steamworks interfaces. +// +// Most users of the Steamworks SDK do not need to include this file. +// You should only include this if you are doing something special. //============================================================================= #ifndef ISTEAMCLIENT_H @@ -11,95 +12,7 @@ #pragma once #endif -#include "steamtypes.h" -#include "steamclientpublic.h" - -// Define compile time assert macros to let us validate the structure sizes. -#define VALVE_COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1]; - -#ifndef REFERENCE -#define REFERENCE(arg) ((void)arg) -#endif - -#if defined(__linux__) || defined(__APPLE__) -// The 32-bit version of gcc has the alignment requirement for uint64 and double set to -// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. -// The 64-bit version of gcc has the alignment requirement for these types set to -// 8 meaning that unless we use #pragma pack(4) our structures will get bigger. -// The 64-bit structure packing has to match the 32-bit structure packing for each platform. -#define VALVE_CALLBACK_PACK_SMALL -#else -#define VALVE_CALLBACK_PACK_LARGE -#endif - -#if defined( VALVE_CALLBACK_PACK_SMALL ) -#pragma pack( push, 4 ) -#elif defined( VALVE_CALLBACK_PACK_LARGE ) -#pragma pack( push, 8 ) -#else -#error ??? -#endif - -typedef struct ValvePackingSentinel_t -{ - uint32 m_u32; - uint64 m_u64; - uint16 m_u16; - double m_d; -} ValvePackingSentinel_t; - -#pragma pack( pop ) - - -#if defined(VALVE_CALLBACK_PACK_SMALL) -VALVE_COMPILE_TIME_ASSERT( sizeof(ValvePackingSentinel_t) == 24 ) -#elif defined(VALVE_CALLBACK_PACK_LARGE) -VALVE_COMPILE_TIME_ASSERT( sizeof(ValvePackingSentinel_t) == 32 ) -#else -#error ??? -#endif - - -// handle to a communication pipe to the Steam client -typedef int32 HSteamPipe; -// handle to single instance of a steam user -typedef int32 HSteamUser; -// function prototype -#if defined( POSIX ) -#define __cdecl -#endif -extern "C" typedef void (__cdecl *SteamAPIWarningMessageHook_t)(int, const char *); -extern "C" typedef void( *SteamAPI_PostAPIResultInProcess_t )(SteamAPICall_t callHandle, void *, uint32 unCallbackSize, int iCallbackNum); -extern "C" typedef uint32 ( *SteamAPI_CheckCallbackRegistered_t )( int iCallbackNum ); -#if defined( __SNC__ ) - #pragma diag_suppress=1700 // warning 1700: class "%s" has virtual functions but non-virtual destructor -#endif - -// interface predec -class ISteamUser; -class ISteamGameServer; -class ISteamFriends; -class ISteamUtils; -class ISteamMatchmaking; -class ISteamContentServer; -class ISteamMatchmakingServers; -class ISteamUserStats; -class ISteamApps; -class ISteamNetworking; -class ISteamRemoteStorage; -class ISteamScreenshots; -class ISteamMusic; -class ISteamMusicRemote; -class ISteamGameServerStats; -class ISteamPS3OverlayRender; -class ISteamHTTP; -class ISteamUnifiedMessages; -class ISteamController; -class ISteamUGC; -class ISteamAppList; -class ISteamHTMLSurface; -class ISteamInventory; -class ISteamVideo; +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: Interface to creating a new steam instance, or to @@ -107,26 +20,32 @@ class ISteamVideo; // different process or is local. // // For most scenarios this is all handled automatically via SteamAPI_Init(). -// You'll only need to use these interfaces if you have a more complex versioning scheme, -// where you want to get different versions of the same interface in different dll's in your project. +// You'll only need these APIs if you have a more complex versioning scheme, +// or if you want to implement a multiplexed gameserver where a single process +// is handling multiple games at once with independent gameserver SteamIDs. //----------------------------------------------------------------------------- class ISteamClient { public: - // Creates a communication pipe to the Steam client + // Creates a communication pipe to the Steam client. + // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling virtual HSteamPipe CreateSteamPipe() = 0; // Releases a previously created communications pipe + // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling virtual bool BReleaseSteamPipe( HSteamPipe hSteamPipe ) = 0; // connects to an existing global user, failing if none exists // used by the game to coordinate with the steamUI + // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling virtual HSteamUser ConnectToGlobalUser( HSteamPipe hSteamPipe ) = 0; // used by game servers, create a steam user that won't be shared with anyone else + // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling virtual HSteamUser CreateLocalUser( HSteamPipe *phSteamPipe, EAccountType eAccountType ) = 0; // removes an allocated user + // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling virtual void ReleaseUser( HSteamPipe hSteamPipe, HSteamUser hUser ) = 0; // retrieves the ISteamUser interface associated with the handle @@ -137,7 +56,7 @@ class ISteamClient // set the local IP and Port to bind to // this must be set before CreateLocalUser() - virtual void SetLocalIPBinding( uint32 unIP, uint16 usPort ) = 0; + virtual void SetLocalIPBinding( const SteamIPAddress_t &unIP, uint16 usPort ) = 0; // returns the ISteamFriends interface virtual ISteamFriends *GetISteamFriends( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; @@ -172,9 +91,11 @@ class ISteamClient // user screenshots virtual ISteamScreenshots *GetISteamScreenshots( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; - // this needs to be called every frame to process matchmaking results - // redundant if you're already calling SteamAPI_RunCallbacks() - virtual void RunFrame() = 0; + // game search + virtual ISteamGameSearch *GetISteamGameSearch( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + + // Deprecated. Applications should use SteamAPI_RunCallbacks() or SteamGameServer_RunCallbacks() instead. + STEAM_PRIVATE_API( virtual void RunFrame() = 0; ) // returns the number of IPC calls made since the last time this function was called // Used for perf debugging so you can understand how many IPC calls your game makes per frame @@ -185,23 +106,19 @@ class ISteamClient // API warning handling // 'int' is the severity; 0 for msg, 1 for warning // 'const char *' is the text of the message - // callbacks will occur directly after the API function is called that generated the warning or message + // callbacks will occur directly after the API function is called that generated the warning or message. virtual void SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction ) = 0; // Trigger global shutdown for the DLL virtual bool BShutdownIfAllPipesClosed() = 0; -#ifdef _PS3 - virtual ISteamPS3OverlayRender *GetISteamPS3OverlayRender() = 0; -#endif - // Expose HTTP interface virtual ISteamHTTP *GetISteamHTTP( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; - // Exposes the ISteamUnifiedMessages interface - virtual ISteamUnifiedMessages *GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + // Deprecated - the ISteamUnifiedMessages interface is no longer intended for public consumption. + STEAM_PRIVATE_API( virtual void *DEPRECATED_GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0 ; ) - // Exposes the ISteamController interface + // Exposes the ISteamController interface - deprecated in favor of Steam Input virtual ISteamController *GetISteamController( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; // Exposes the ISteamUGC interface @@ -220,284 +137,43 @@ class ISteamClient virtual ISteamHTMLSurface *GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) = 0; // Helper functions for internal Steam usage - virtual void Set_SteamAPI_CPostAPIResultInProcess( SteamAPI_PostAPIResultInProcess_t func ) = 0; - virtual void Remove_SteamAPI_CPostAPIResultInProcess( SteamAPI_PostAPIResultInProcess_t func ) = 0; - virtual void Set_SteamAPI_CCheckCallbackRegisteredInProcess( SteamAPI_CheckCallbackRegistered_t func ) = 0; + STEAM_PRIVATE_API( virtual void DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess( void (*)() ) = 0; ) + STEAM_PRIVATE_API( virtual void DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess( void (*)() ) = 0; ) + STEAM_PRIVATE_API( virtual void Set_SteamAPI_CCheckCallbackRegisteredInProcess( SteamAPI_CheckCallbackRegistered_t func ) = 0; ) // inventory virtual ISteamInventory *GetISteamInventory( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; // Video virtual ISteamVideo *GetISteamVideo( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; -}; - - -#define STEAMCLIENT_INTERFACE_VERSION "SteamClient017" - -//----------------------------------------------------------------------------- -// Purpose: Base values for callback identifiers, each callback must -// have a unique ID. -//----------------------------------------------------------------------------- -enum { k_iSteamUserCallbacks = 100 }; -enum { k_iSteamGameServerCallbacks = 200 }; -enum { k_iSteamFriendsCallbacks = 300 }; -enum { k_iSteamBillingCallbacks = 400 }; -enum { k_iSteamMatchmakingCallbacks = 500 }; -enum { k_iSteamContentServerCallbacks = 600 }; -enum { k_iSteamUtilsCallbacks = 700 }; -enum { k_iClientFriendsCallbacks = 800 }; -enum { k_iClientUserCallbacks = 900 }; -enum { k_iSteamAppsCallbacks = 1000 }; -enum { k_iSteamUserStatsCallbacks = 1100 }; -enum { k_iSteamNetworkingCallbacks = 1200 }; -enum { k_iClientRemoteStorageCallbacks = 1300 }; -enum { k_iClientDepotBuilderCallbacks = 1400 }; -enum { k_iSteamGameServerItemsCallbacks = 1500 }; -enum { k_iClientUtilsCallbacks = 1600 }; -enum { k_iSteamGameCoordinatorCallbacks = 1700 }; -enum { k_iSteamGameServerStatsCallbacks = 1800 }; -enum { k_iSteam2AsyncCallbacks = 1900 }; -enum { k_iSteamGameStatsCallbacks = 2000 }; -enum { k_iClientHTTPCallbacks = 2100 }; -enum { k_iClientScreenshotsCallbacks = 2200 }; -enum { k_iSteamScreenshotsCallbacks = 2300 }; -enum { k_iClientAudioCallbacks = 2400 }; -enum { k_iClientUnifiedMessagesCallbacks = 2500 }; -enum { k_iSteamStreamLauncherCallbacks = 2600 }; -enum { k_iClientControllerCallbacks = 2700 }; -enum { k_iSteamControllerCallbacks = 2800 }; -enum { k_iClientParentalSettingsCallbacks = 2900 }; -enum { k_iClientDeviceAuthCallbacks = 3000 }; -enum { k_iClientNetworkDeviceManagerCallbacks = 3100 }; -enum { k_iClientMusicCallbacks = 3200 }; -enum { k_iClientRemoteClientManagerCallbacks = 3300 }; -enum { k_iClientUGCCallbacks = 3400 }; -enum { k_iSteamStreamClientCallbacks = 3500 }; -enum { k_IClientProductBuilderCallbacks = 3600 }; -enum { k_iClientShortcutsCallbacks = 3700 }; -enum { k_iClientRemoteControlManagerCallbacks = 3800 }; -enum { k_iSteamAppListCallbacks = 3900 }; -enum { k_iSteamMusicCallbacks = 4000 }; -enum { k_iSteamMusicRemoteCallbacks = 4100 }; -enum { k_iClientVRCallbacks = 4200 }; -enum { k_iClientReservedCallbacks = 4300 }; -enum { k_iSteamReservedCallbacks = 4400 }; -enum { k_iSteamHTMLSurfaceCallbacks = 4500 }; -enum { k_iClientVideoCallbacks = 4600 }; -enum { k_iClientInventoryCallbacks = 4700 }; - -//----------------------------------------------------------------------------- -// The CALLBACK macros are for client side callback logging enabled with -// log_callback -// Do not change any of these. -//----------------------------------------------------------------------------- -struct SteamCallback_t -{ -public: - SteamCallback_t() {} -}; + // Parental controls + virtual ISteamParentalSettings *GetISteamParentalSettings( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; -#define DEFINE_CALLBACK( callbackname, callbackid ) \ -struct callbackname : SteamCallback_t { \ - enum { k_iCallback = callbackid }; \ - static callbackname *GetNullPointer() { return 0; } \ - static const char *GetCallbackName() { return #callbackname; } \ - static uint32 GetCallbackID() { return callbackname::k_iCallback; } + // Exposes the Steam Input interface for controller support + virtual ISteamInput *GetISteamInput( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; -#define CALLBACK_MEMBER( varidx, vartype, varname ) \ - public: vartype varname ; \ - static void GetMemberVar_##varidx( unsigned int &varOffset, unsigned int &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { \ - varOffset = (unsigned int)(size_t)&GetNullPointer()->varname; \ - varSize = sizeof( vartype ); \ - varCount = 1; \ - *pszName = #varname; *pszType = #vartype; } + // Steam Parties interface + virtual ISteamParties *GetISteamParties( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; -#define CALLBACK_ARRAY( varidx, vartype, varname, varcount ) \ - public: vartype varname [ varcount ]; \ - static void GetMemberVar_##varidx( unsigned int &varOffset, unsigned int &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { \ - varOffset = (unsigned int)(size_t)&GetNullPointer()->varname[0]; \ - varSize = sizeof( vartype ); \ - varCount = varcount; \ - *pszName = #varname; *pszType = #vartype; } + // Steam Remote Play interface + virtual ISteamRemotePlay *GetISteamRemotePlay( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0; + STEAM_PRIVATE_API( virtual void DestroyAllInterfaces() = 0; ) -#define END_CALLBACK_INTERNAL_BEGIN( numvars ) \ - static uint32 GetNumMemberVariables() { return numvars; } \ - static bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { \ - switch ( index ) { default : return false; - +}; +#define STEAMCLIENT_INTERFACE_VERSION "SteamClient020" -#define END_CALLBACK_INTERNAL_SWITCH( varidx ) case varidx : GetMemberVar_##varidx( varOffset, varSize, varCount, pszName, pszType ); return true; +#ifndef STEAM_API_EXPORTS -#define END_CALLBACK_INTERNAL_END() }; } }; +// Global ISteamClient interface accessor +inline ISteamClient *SteamClient(); +STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamClient *, SteamClient, SteamInternal_CreateInterface( STEAMCLIENT_INTERFACE_VERSION ), "global", STEAMCLIENT_INTERFACE_VERSION ); -#define END_DEFINE_CALLBACK_0() \ - static uint32 GetNumMemberVariables() { return 0; } \ - static bool GetMemberVariable( uint32 index, uint32 &varOffset, uint32 &varSize, uint32 &varCount, const char **pszName, const char **pszType ) { REFERENCE( pszType ); REFERENCE( pszName ); REFERENCE( varCount ); REFERENCE( varSize ); REFERENCE( varOffset ); REFERENCE( index ); return false; } \ - }; - +// The internal ISteamClient used for the gameserver interface. +// (This is actually the same thing. You really shouldn't need to access any of this stuff directly.) +inline ISteamClient *SteamGameServerClient() { return SteamClient(); } -#define END_DEFINE_CALLBACK_1() \ - END_CALLBACK_INTERNAL_BEGIN( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_2() \ - END_CALLBACK_INTERNAL_BEGIN( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_3() \ - END_CALLBACK_INTERNAL_BEGIN( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_4() \ - END_CALLBACK_INTERNAL_BEGIN( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_5() \ - END_CALLBACK_INTERNAL_BEGIN( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_END() - - -#define END_DEFINE_CALLBACK_6() \ - END_CALLBACK_INTERNAL_BEGIN( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_7() \ - END_CALLBACK_INTERNAL_BEGIN( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_8() \ - END_CALLBACK_INTERNAL_BEGIN( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_9() \ - END_CALLBACK_INTERNAL_BEGIN( 9 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_10() \ - END_CALLBACK_INTERNAL_BEGIN( 10 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 9 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_11() \ - END_CALLBACK_INTERNAL_BEGIN( 11 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 9 ) \ - END_CALLBACK_INTERNAL_SWITCH( 10 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_12() \ - END_CALLBACK_INTERNAL_BEGIN( 12 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 9 ) \ - END_CALLBACK_INTERNAL_SWITCH( 10 ) \ - END_CALLBACK_INTERNAL_SWITCH( 11 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_13() \ - END_CALLBACK_INTERNAL_BEGIN( 13 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 9 ) \ - END_CALLBACK_INTERNAL_SWITCH( 10 ) \ - END_CALLBACK_INTERNAL_SWITCH( 11 ) \ - END_CALLBACK_INTERNAL_SWITCH( 12 ) \ - END_CALLBACK_INTERNAL_END() - -#define END_DEFINE_CALLBACK_14() \ - END_CALLBACK_INTERNAL_BEGIN( 14 ) \ - END_CALLBACK_INTERNAL_SWITCH( 0 ) \ - END_CALLBACK_INTERNAL_SWITCH( 1 ) \ - END_CALLBACK_INTERNAL_SWITCH( 2 ) \ - END_CALLBACK_INTERNAL_SWITCH( 3 ) \ - END_CALLBACK_INTERNAL_SWITCH( 4 ) \ - END_CALLBACK_INTERNAL_SWITCH( 5 ) \ - END_CALLBACK_INTERNAL_SWITCH( 6 ) \ - END_CALLBACK_INTERNAL_SWITCH( 7 ) \ - END_CALLBACK_INTERNAL_SWITCH( 8 ) \ - END_CALLBACK_INTERNAL_SWITCH( 9 ) \ - END_CALLBACK_INTERNAL_SWITCH( 10 ) \ - END_CALLBACK_INTERNAL_SWITCH( 11 ) \ - END_CALLBACK_INTERNAL_SWITCH( 12 ) \ - END_CALLBACK_INTERNAL_SWITCH( 13 ) \ - END_CALLBACK_INTERNAL_END() +#endif #endif // ISTEAMCLIENT_H diff --git a/public/steam/isteamcontroller.h b/public/steam/isteamcontroller.h index 5c3d01ab..53a49e6e 100644 --- a/public/steam/isteamcontroller.h +++ b/public/steam/isteamcontroller.h @@ -1,6 +1,12 @@ -//====== Copyright 1996-2013, Valve Corporation, All rights reserved. ======= +//====== Copyright 1996-2018, Valve Corporation, All rights reserved. ======= +// Note: The older ISteamController interface has been deprecated in favor of ISteamInput - this interface +// was updated in this SDK but will be removed from future SDK's. The Steam Client will retain +// compatibility with the older interfaces so your any existing integrations should be unaffected. // -// Purpose: interface to valve controller +// Purpose: Steam Input is a flexible input API that supports over three hundred devices including all +// common variants of Xbox, Playstation, Nintendo Switch Pro, and Steam Controllers. +// For more info including a getting started guide for developers +// please visit: https://partner.steamgames.com/doc/features/steam_controller // //============================================================================= @@ -10,129 +16,701 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" +#include "isteaminput.h" -// callbacks -#if defined( VALVE_CALLBACK_PACK_SMALL ) -#pragma pack( push, 4 ) -#elif defined( VALVE_CALLBACK_PACK_LARGE ) -#pragma pack( push, 8 ) -#else -#error isteamclient.h must be included -#endif +#define STEAM_CONTROLLER_MAX_COUNT 16 -#define MAX_STEAM_CONTROLLERS 16 +#define STEAM_CONTROLLER_MAX_ANALOG_ACTIONS 16 -#pragma pack( pop ) +#define STEAM_CONTROLLER_MAX_DIGITAL_ACTIONS 128 -#define STEAM_RIGHT_TRIGGER_MASK 0x0000001 -#define STEAM_LEFT_TRIGGER_MASK 0x0000002 -#define STEAM_RIGHT_BUMPER_MASK 0x0000004 -#define STEAM_LEFT_BUMPER_MASK 0x0000008 -#define STEAM_BUTTON_0_MASK 0x0000010 -#define STEAM_BUTTON_1_MASK 0x0000020 -#define STEAM_BUTTON_2_MASK 0x0000040 -#define STEAM_BUTTON_3_MASK 0x0000080 -#define STEAM_TOUCH_0_MASK 0x0000100 -#define STEAM_TOUCH_1_MASK 0x0000200 -#define STEAM_TOUCH_2_MASK 0x0000400 -#define STEAM_TOUCH_3_MASK 0x0000800 -#define STEAM_BUTTON_MENU_MASK 0x0001000 -#define STEAM_BUTTON_STEAM_MASK 0x0002000 -#define STEAM_BUTTON_ESCAPE_MASK 0x0004000 -#define STEAM_BUTTON_BACK_LEFT_MASK 0x0008000 -#define STEAM_BUTTON_BACK_RIGHT_MASK 0x0010000 -#define STEAM_BUTTON_LEFTPAD_CLICKED_MASK 0x0020000 -#define STEAM_BUTTON_RIGHTPAD_CLICKED_MASK 0x0040000 -#define STEAM_LEFTPAD_FINGERDOWN_MASK 0x0080000 -#define STEAM_RIGHTPAD_FINGERDOWN_MASK 0x0100000 -#define STEAM_JOYSTICK_BUTTON_MASK 0x0400000 +#define STEAM_CONTROLLER_MAX_ORIGINS 8 +#define STEAM_CONTROLLER_MAX_ACTIVE_LAYERS 16 -#pragma pack( push, 1 ) +// When sending an option to a specific controller handle, you can send to all controllers via this command +#define STEAM_CONTROLLER_HANDLE_ALL_CONTROLLERS UINT64_MAX -struct SteamControllerState001_t +#define STEAM_CONTROLLER_MIN_ANALOG_ACTION_DATA -1.0f +#define STEAM_CONTROLLER_MAX_ANALOG_ACTION_DATA 1.0f + +#ifndef ISTEAMINPUT_H +enum ESteamControllerPad { - // If packet num matches that on your prior call, then the controller state hasn't been changed since - // your last call and there is no need to process it - uint32 unPacketNum; - - // bit flags for each of the buttons - uint64 ulButtons; + k_ESteamControllerPad_Left, + k_ESteamControllerPad_Right +}; +#endif + +// Note: Please do not use action origins as a way to identify controller types. There is no +// guarantee that they will be added in a contiguous manner - use GetInputTypeForHandle instead +// Versions of Steam that add new controller types in the future will extend this enum if you're +// using a lookup table please check the bounds of any origins returned by Steam. +enum EControllerActionOrigin +{ + // Steam Controller + k_EControllerActionOrigin_None, + k_EControllerActionOrigin_A, + k_EControllerActionOrigin_B, + k_EControllerActionOrigin_X, + k_EControllerActionOrigin_Y, + k_EControllerActionOrigin_LeftBumper, + k_EControllerActionOrigin_RightBumper, + k_EControllerActionOrigin_LeftGrip, + k_EControllerActionOrigin_RightGrip, + k_EControllerActionOrigin_Start, + k_EControllerActionOrigin_Back, + k_EControllerActionOrigin_LeftPad_Touch, + k_EControllerActionOrigin_LeftPad_Swipe, + k_EControllerActionOrigin_LeftPad_Click, + k_EControllerActionOrigin_LeftPad_DPadNorth, + k_EControllerActionOrigin_LeftPad_DPadSouth, + k_EControllerActionOrigin_LeftPad_DPadWest, + k_EControllerActionOrigin_LeftPad_DPadEast, + k_EControllerActionOrigin_RightPad_Touch, + k_EControllerActionOrigin_RightPad_Swipe, + k_EControllerActionOrigin_RightPad_Click, + k_EControllerActionOrigin_RightPad_DPadNorth, + k_EControllerActionOrigin_RightPad_DPadSouth, + k_EControllerActionOrigin_RightPad_DPadWest, + k_EControllerActionOrigin_RightPad_DPadEast, + k_EControllerActionOrigin_LeftTrigger_Pull, + k_EControllerActionOrigin_LeftTrigger_Click, + k_EControllerActionOrigin_RightTrigger_Pull, + k_EControllerActionOrigin_RightTrigger_Click, + k_EControllerActionOrigin_LeftStick_Move, + k_EControllerActionOrigin_LeftStick_Click, + k_EControllerActionOrigin_LeftStick_DPadNorth, + k_EControllerActionOrigin_LeftStick_DPadSouth, + k_EControllerActionOrigin_LeftStick_DPadWest, + k_EControllerActionOrigin_LeftStick_DPadEast, + k_EControllerActionOrigin_Gyro_Move, + k_EControllerActionOrigin_Gyro_Pitch, + k_EControllerActionOrigin_Gyro_Yaw, + k_EControllerActionOrigin_Gyro_Roll, - // Left pad coordinates - short sLeftPadX; - short sLeftPadY; + // PS4 Dual Shock + k_EControllerActionOrigin_PS4_X, + k_EControllerActionOrigin_PS4_Circle, + k_EControllerActionOrigin_PS4_Triangle, + k_EControllerActionOrigin_PS4_Square, + k_EControllerActionOrigin_PS4_LeftBumper, + k_EControllerActionOrigin_PS4_RightBumper, + k_EControllerActionOrigin_PS4_Options, //Start + k_EControllerActionOrigin_PS4_Share, //Back + k_EControllerActionOrigin_PS4_LeftPad_Touch, + k_EControllerActionOrigin_PS4_LeftPad_Swipe, + k_EControllerActionOrigin_PS4_LeftPad_Click, + k_EControllerActionOrigin_PS4_LeftPad_DPadNorth, + k_EControllerActionOrigin_PS4_LeftPad_DPadSouth, + k_EControllerActionOrigin_PS4_LeftPad_DPadWest, + k_EControllerActionOrigin_PS4_LeftPad_DPadEast, + k_EControllerActionOrigin_PS4_RightPad_Touch, + k_EControllerActionOrigin_PS4_RightPad_Swipe, + k_EControllerActionOrigin_PS4_RightPad_Click, + k_EControllerActionOrigin_PS4_RightPad_DPadNorth, + k_EControllerActionOrigin_PS4_RightPad_DPadSouth, + k_EControllerActionOrigin_PS4_RightPad_DPadWest, + k_EControllerActionOrigin_PS4_RightPad_DPadEast, + k_EControllerActionOrigin_PS4_CenterPad_Touch, + k_EControllerActionOrigin_PS4_CenterPad_Swipe, + k_EControllerActionOrigin_PS4_CenterPad_Click, + k_EControllerActionOrigin_PS4_CenterPad_DPadNorth, + k_EControllerActionOrigin_PS4_CenterPad_DPadSouth, + k_EControllerActionOrigin_PS4_CenterPad_DPadWest, + k_EControllerActionOrigin_PS4_CenterPad_DPadEast, + k_EControllerActionOrigin_PS4_LeftTrigger_Pull, + k_EControllerActionOrigin_PS4_LeftTrigger_Click, + k_EControllerActionOrigin_PS4_RightTrigger_Pull, + k_EControllerActionOrigin_PS4_RightTrigger_Click, + k_EControllerActionOrigin_PS4_LeftStick_Move, + k_EControllerActionOrigin_PS4_LeftStick_Click, + k_EControllerActionOrigin_PS4_LeftStick_DPadNorth, + k_EControllerActionOrigin_PS4_LeftStick_DPadSouth, + k_EControllerActionOrigin_PS4_LeftStick_DPadWest, + k_EControllerActionOrigin_PS4_LeftStick_DPadEast, + k_EControllerActionOrigin_PS4_RightStick_Move, + k_EControllerActionOrigin_PS4_RightStick_Click, + k_EControllerActionOrigin_PS4_RightStick_DPadNorth, + k_EControllerActionOrigin_PS4_RightStick_DPadSouth, + k_EControllerActionOrigin_PS4_RightStick_DPadWest, + k_EControllerActionOrigin_PS4_RightStick_DPadEast, + k_EControllerActionOrigin_PS4_DPad_North, + k_EControllerActionOrigin_PS4_DPad_South, + k_EControllerActionOrigin_PS4_DPad_West, + k_EControllerActionOrigin_PS4_DPad_East, + k_EControllerActionOrigin_PS4_Gyro_Move, + k_EControllerActionOrigin_PS4_Gyro_Pitch, + k_EControllerActionOrigin_PS4_Gyro_Yaw, + k_EControllerActionOrigin_PS4_Gyro_Roll, + + // XBox One + k_EControllerActionOrigin_XBoxOne_A, + k_EControllerActionOrigin_XBoxOne_B, + k_EControllerActionOrigin_XBoxOne_X, + k_EControllerActionOrigin_XBoxOne_Y, + k_EControllerActionOrigin_XBoxOne_LeftBumper, + k_EControllerActionOrigin_XBoxOne_RightBumper, + k_EControllerActionOrigin_XBoxOne_Menu, //Start + k_EControllerActionOrigin_XBoxOne_View, //Back + k_EControllerActionOrigin_XBoxOne_LeftTrigger_Pull, + k_EControllerActionOrigin_XBoxOne_LeftTrigger_Click, + k_EControllerActionOrigin_XBoxOne_RightTrigger_Pull, + k_EControllerActionOrigin_XBoxOne_RightTrigger_Click, + k_EControllerActionOrigin_XBoxOne_LeftStick_Move, + k_EControllerActionOrigin_XBoxOne_LeftStick_Click, + k_EControllerActionOrigin_XBoxOne_LeftStick_DPadNorth, + k_EControllerActionOrigin_XBoxOne_LeftStick_DPadSouth, + k_EControllerActionOrigin_XBoxOne_LeftStick_DPadWest, + k_EControllerActionOrigin_XBoxOne_LeftStick_DPadEast, + k_EControllerActionOrigin_XBoxOne_RightStick_Move, + k_EControllerActionOrigin_XBoxOne_RightStick_Click, + k_EControllerActionOrigin_XBoxOne_RightStick_DPadNorth, + k_EControllerActionOrigin_XBoxOne_RightStick_DPadSouth, + k_EControllerActionOrigin_XBoxOne_RightStick_DPadWest, + k_EControllerActionOrigin_XBoxOne_RightStick_DPadEast, + k_EControllerActionOrigin_XBoxOne_DPad_North, + k_EControllerActionOrigin_XBoxOne_DPad_South, + k_EControllerActionOrigin_XBoxOne_DPad_West, + k_EControllerActionOrigin_XBoxOne_DPad_East, + + // XBox 360 + k_EControllerActionOrigin_XBox360_A, + k_EControllerActionOrigin_XBox360_B, + k_EControllerActionOrigin_XBox360_X, + k_EControllerActionOrigin_XBox360_Y, + k_EControllerActionOrigin_XBox360_LeftBumper, + k_EControllerActionOrigin_XBox360_RightBumper, + k_EControllerActionOrigin_XBox360_Start, //Start + k_EControllerActionOrigin_XBox360_Back, //Back + k_EControllerActionOrigin_XBox360_LeftTrigger_Pull, + k_EControllerActionOrigin_XBox360_LeftTrigger_Click, + k_EControllerActionOrigin_XBox360_RightTrigger_Pull, + k_EControllerActionOrigin_XBox360_RightTrigger_Click, + k_EControllerActionOrigin_XBox360_LeftStick_Move, + k_EControllerActionOrigin_XBox360_LeftStick_Click, + k_EControllerActionOrigin_XBox360_LeftStick_DPadNorth, + k_EControllerActionOrigin_XBox360_LeftStick_DPadSouth, + k_EControllerActionOrigin_XBox360_LeftStick_DPadWest, + k_EControllerActionOrigin_XBox360_LeftStick_DPadEast, + k_EControllerActionOrigin_XBox360_RightStick_Move, + k_EControllerActionOrigin_XBox360_RightStick_Click, + k_EControllerActionOrigin_XBox360_RightStick_DPadNorth, + k_EControllerActionOrigin_XBox360_RightStick_DPadSouth, + k_EControllerActionOrigin_XBox360_RightStick_DPadWest, + k_EControllerActionOrigin_XBox360_RightStick_DPadEast, + k_EControllerActionOrigin_XBox360_DPad_North, + k_EControllerActionOrigin_XBox360_DPad_South, + k_EControllerActionOrigin_XBox360_DPad_West, + k_EControllerActionOrigin_XBox360_DPad_East, + + // SteamController V2 + k_EControllerActionOrigin_SteamV2_A, + k_EControllerActionOrigin_SteamV2_B, + k_EControllerActionOrigin_SteamV2_X, + k_EControllerActionOrigin_SteamV2_Y, + k_EControllerActionOrigin_SteamV2_LeftBumper, + k_EControllerActionOrigin_SteamV2_RightBumper, + k_EControllerActionOrigin_SteamV2_LeftGrip_Lower, + k_EControllerActionOrigin_SteamV2_LeftGrip_Upper, + k_EControllerActionOrigin_SteamV2_RightGrip_Lower, + k_EControllerActionOrigin_SteamV2_RightGrip_Upper, + k_EControllerActionOrigin_SteamV2_LeftBumper_Pressure, + k_EControllerActionOrigin_SteamV2_RightBumper_Pressure, + k_EControllerActionOrigin_SteamV2_LeftGrip_Pressure, + k_EControllerActionOrigin_SteamV2_RightGrip_Pressure, + k_EControllerActionOrigin_SteamV2_LeftGrip_Upper_Pressure, + k_EControllerActionOrigin_SteamV2_RightGrip_Upper_Pressure, + k_EControllerActionOrigin_SteamV2_Start, + k_EControllerActionOrigin_SteamV2_Back, + k_EControllerActionOrigin_SteamV2_LeftPad_Touch, + k_EControllerActionOrigin_SteamV2_LeftPad_Swipe, + k_EControllerActionOrigin_SteamV2_LeftPad_Click, + k_EControllerActionOrigin_SteamV2_LeftPad_Pressure, + k_EControllerActionOrigin_SteamV2_LeftPad_DPadNorth, + k_EControllerActionOrigin_SteamV2_LeftPad_DPadSouth, + k_EControllerActionOrigin_SteamV2_LeftPad_DPadWest, + k_EControllerActionOrigin_SteamV2_LeftPad_DPadEast, + k_EControllerActionOrigin_SteamV2_RightPad_Touch, + k_EControllerActionOrigin_SteamV2_RightPad_Swipe, + k_EControllerActionOrigin_SteamV2_RightPad_Click, + k_EControllerActionOrigin_SteamV2_RightPad_Pressure, + k_EControllerActionOrigin_SteamV2_RightPad_DPadNorth, + k_EControllerActionOrigin_SteamV2_RightPad_DPadSouth, + k_EControllerActionOrigin_SteamV2_RightPad_DPadWest, + k_EControllerActionOrigin_SteamV2_RightPad_DPadEast, + k_EControllerActionOrigin_SteamV2_LeftTrigger_Pull, + k_EControllerActionOrigin_SteamV2_LeftTrigger_Click, + k_EControllerActionOrigin_SteamV2_RightTrigger_Pull, + k_EControllerActionOrigin_SteamV2_RightTrigger_Click, + k_EControllerActionOrigin_SteamV2_LeftStick_Move, + k_EControllerActionOrigin_SteamV2_LeftStick_Click, + k_EControllerActionOrigin_SteamV2_LeftStick_DPadNorth, + k_EControllerActionOrigin_SteamV2_LeftStick_DPadSouth, + k_EControllerActionOrigin_SteamV2_LeftStick_DPadWest, + k_EControllerActionOrigin_SteamV2_LeftStick_DPadEast, + k_EControllerActionOrigin_SteamV2_Gyro_Move, + k_EControllerActionOrigin_SteamV2_Gyro_Pitch, + k_EControllerActionOrigin_SteamV2_Gyro_Yaw, + k_EControllerActionOrigin_SteamV2_Gyro_Roll, + + // Switch - Pro or Joycons used as a single input device. + // This does not apply to a single joycon + k_EControllerActionOrigin_Switch_A, + k_EControllerActionOrigin_Switch_B, + k_EControllerActionOrigin_Switch_X, + k_EControllerActionOrigin_Switch_Y, + k_EControllerActionOrigin_Switch_LeftBumper, + k_EControllerActionOrigin_Switch_RightBumper, + k_EControllerActionOrigin_Switch_Plus, //Start + k_EControllerActionOrigin_Switch_Minus, //Back + k_EControllerActionOrigin_Switch_Capture, + k_EControllerActionOrigin_Switch_LeftTrigger_Pull, + k_EControllerActionOrigin_Switch_LeftTrigger_Click, + k_EControllerActionOrigin_Switch_RightTrigger_Pull, + k_EControllerActionOrigin_Switch_RightTrigger_Click, + k_EControllerActionOrigin_Switch_LeftStick_Move, + k_EControllerActionOrigin_Switch_LeftStick_Click, + k_EControllerActionOrigin_Switch_LeftStick_DPadNorth, + k_EControllerActionOrigin_Switch_LeftStick_DPadSouth, + k_EControllerActionOrigin_Switch_LeftStick_DPadWest, + k_EControllerActionOrigin_Switch_LeftStick_DPadEast, + k_EControllerActionOrigin_Switch_RightStick_Move, + k_EControllerActionOrigin_Switch_RightStick_Click, + k_EControllerActionOrigin_Switch_RightStick_DPadNorth, + k_EControllerActionOrigin_Switch_RightStick_DPadSouth, + k_EControllerActionOrigin_Switch_RightStick_DPadWest, + k_EControllerActionOrigin_Switch_RightStick_DPadEast, + k_EControllerActionOrigin_Switch_DPad_North, + k_EControllerActionOrigin_Switch_DPad_South, + k_EControllerActionOrigin_Switch_DPad_West, + k_EControllerActionOrigin_Switch_DPad_East, + k_EControllerActionOrigin_Switch_ProGyro_Move, // Primary Gyro in Pro Controller, or Right JoyCon + k_EControllerActionOrigin_Switch_ProGyro_Pitch, // Primary Gyro in Pro Controller, or Right JoyCon + k_EControllerActionOrigin_Switch_ProGyro_Yaw, // Primary Gyro in Pro Controller, or Right JoyCon + k_EControllerActionOrigin_Switch_ProGyro_Roll, // Primary Gyro in Pro Controller, or Right JoyCon + // Switch JoyCon Specific + k_EControllerActionOrigin_Switch_RightGyro_Move, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EControllerActionOrigin_Switch_RightGyro_Pitch, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EControllerActionOrigin_Switch_RightGyro_Yaw, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EControllerActionOrigin_Switch_RightGyro_Roll, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EControllerActionOrigin_Switch_LeftGyro_Move, + k_EControllerActionOrigin_Switch_LeftGyro_Pitch, + k_EControllerActionOrigin_Switch_LeftGyro_Yaw, + k_EControllerActionOrigin_Switch_LeftGyro_Roll, + k_EControllerActionOrigin_Switch_LeftGrip_Lower, // Left JoyCon SR Button + k_EControllerActionOrigin_Switch_LeftGrip_Upper, // Left JoyCon SL Button + k_EControllerActionOrigin_Switch_RightGrip_Lower, // Right JoyCon SL Button + k_EControllerActionOrigin_Switch_RightGrip_Upper, // Right JoyCon SR Button + + // Added in SDK 1.45 + k_EControllerActionOrigin_PS4_DPad_Move, + k_EControllerActionOrigin_XBoxOne_DPad_Move, + k_EControllerActionOrigin_XBox360_DPad_Move, + k_EControllerActionOrigin_Switch_DPad_Move, + + // Added in SDK 1.51 + k_EControllerActionOrigin_PS5_X, + k_EControllerActionOrigin_PS5_Circle, + k_EControllerActionOrigin_PS5_Triangle, + k_EControllerActionOrigin_PS5_Square, + k_EControllerActionOrigin_PS5_LeftBumper, + k_EControllerActionOrigin_PS5_RightBumper, + k_EControllerActionOrigin_PS5_Option, //Start + k_EControllerActionOrigin_PS5_Create, //Back + k_EControllerActionOrigin_PS5_Mute, + k_EControllerActionOrigin_PS5_LeftPad_Touch, + k_EControllerActionOrigin_PS5_LeftPad_Swipe, + k_EControllerActionOrigin_PS5_LeftPad_Click, + k_EControllerActionOrigin_PS5_LeftPad_DPadNorth, + k_EControllerActionOrigin_PS5_LeftPad_DPadSouth, + k_EControllerActionOrigin_PS5_LeftPad_DPadWest, + k_EControllerActionOrigin_PS5_LeftPad_DPadEast, + k_EControllerActionOrigin_PS5_RightPad_Touch, + k_EControllerActionOrigin_PS5_RightPad_Swipe, + k_EControllerActionOrigin_PS5_RightPad_Click, + k_EControllerActionOrigin_PS5_RightPad_DPadNorth, + k_EControllerActionOrigin_PS5_RightPad_DPadSouth, + k_EControllerActionOrigin_PS5_RightPad_DPadWest, + k_EControllerActionOrigin_PS5_RightPad_DPadEast, + k_EControllerActionOrigin_PS5_CenterPad_Touch, + k_EControllerActionOrigin_PS5_CenterPad_Swipe, + k_EControllerActionOrigin_PS5_CenterPad_Click, + k_EControllerActionOrigin_PS5_CenterPad_DPadNorth, + k_EControllerActionOrigin_PS5_CenterPad_DPadSouth, + k_EControllerActionOrigin_PS5_CenterPad_DPadWest, + k_EControllerActionOrigin_PS5_CenterPad_DPadEast, + k_EControllerActionOrigin_PS5_LeftTrigger_Pull, + k_EControllerActionOrigin_PS5_LeftTrigger_Click, + k_EControllerActionOrigin_PS5_RightTrigger_Pull, + k_EControllerActionOrigin_PS5_RightTrigger_Click, + k_EControllerActionOrigin_PS5_LeftStick_Move, + k_EControllerActionOrigin_PS5_LeftStick_Click, + k_EControllerActionOrigin_PS5_LeftStick_DPadNorth, + k_EControllerActionOrigin_PS5_LeftStick_DPadSouth, + k_EControllerActionOrigin_PS5_LeftStick_DPadWest, + k_EControllerActionOrigin_PS5_LeftStick_DPadEast, + k_EControllerActionOrigin_PS5_RightStick_Move, + k_EControllerActionOrigin_PS5_RightStick_Click, + k_EControllerActionOrigin_PS5_RightStick_DPadNorth, + k_EControllerActionOrigin_PS5_RightStick_DPadSouth, + k_EControllerActionOrigin_PS5_RightStick_DPadWest, + k_EControllerActionOrigin_PS5_RightStick_DPadEast, + k_EControllerActionOrigin_PS5_DPad_Move, + k_EControllerActionOrigin_PS5_DPad_North, + k_EControllerActionOrigin_PS5_DPad_South, + k_EControllerActionOrigin_PS5_DPad_West, + k_EControllerActionOrigin_PS5_DPad_East, + k_EControllerActionOrigin_PS5_Gyro_Move, + k_EControllerActionOrigin_PS5_Gyro_Pitch, + k_EControllerActionOrigin_PS5_Gyro_Yaw, + k_EControllerActionOrigin_PS5_Gyro_Roll, + + k_EControllerActionOrigin_XBoxOne_LeftGrip_Lower, + k_EControllerActionOrigin_XBoxOne_LeftGrip_Upper, + k_EControllerActionOrigin_XBoxOne_RightGrip_Lower, + k_EControllerActionOrigin_XBoxOne_RightGrip_Upper, + k_EControllerActionOrigin_XBoxOne_Share, + + // Added in SDK 1.53 + k_EControllerActionOrigin_SteamDeck_A, + k_EControllerActionOrigin_SteamDeck_B, + k_EControllerActionOrigin_SteamDeck_X, + k_EControllerActionOrigin_SteamDeck_Y, + k_EControllerActionOrigin_SteamDeck_L1, + k_EControllerActionOrigin_SteamDeck_R1, + k_EControllerActionOrigin_SteamDeck_Menu, + k_EControllerActionOrigin_SteamDeck_View, + k_EControllerActionOrigin_SteamDeck_LeftPad_Touch, + k_EControllerActionOrigin_SteamDeck_LeftPad_Swipe, + k_EControllerActionOrigin_SteamDeck_LeftPad_Click, + k_EControllerActionOrigin_SteamDeck_LeftPad_DPadNorth, + k_EControllerActionOrigin_SteamDeck_LeftPad_DPadSouth, + k_EControllerActionOrigin_SteamDeck_LeftPad_DPadWest, + k_EControllerActionOrigin_SteamDeck_LeftPad_DPadEast, + k_EControllerActionOrigin_SteamDeck_RightPad_Touch, + k_EControllerActionOrigin_SteamDeck_RightPad_Swipe, + k_EControllerActionOrigin_SteamDeck_RightPad_Click, + k_EControllerActionOrigin_SteamDeck_RightPad_DPadNorth, + k_EControllerActionOrigin_SteamDeck_RightPad_DPadSouth, + k_EControllerActionOrigin_SteamDeck_RightPad_DPadWest, + k_EControllerActionOrigin_SteamDeck_RightPad_DPadEast, + k_EControllerActionOrigin_SteamDeck_L2_SoftPull, + k_EControllerActionOrigin_SteamDeck_L2, + k_EControllerActionOrigin_SteamDeck_R2_SoftPull, + k_EControllerActionOrigin_SteamDeck_R2, + k_EControllerActionOrigin_SteamDeck_LeftStick_Move, + k_EControllerActionOrigin_SteamDeck_L3, + k_EControllerActionOrigin_SteamDeck_LeftStick_DPadNorth, + k_EControllerActionOrigin_SteamDeck_LeftStick_DPadSouth, + k_EControllerActionOrigin_SteamDeck_LeftStick_DPadWest, + k_EControllerActionOrigin_SteamDeck_LeftStick_DPadEast, + k_EControllerActionOrigin_SteamDeck_LeftStick_Touch, + k_EControllerActionOrigin_SteamDeck_RightStick_Move, + k_EControllerActionOrigin_SteamDeck_R3, + k_EControllerActionOrigin_SteamDeck_RightStick_DPadNorth, + k_EControllerActionOrigin_SteamDeck_RightStick_DPadSouth, + k_EControllerActionOrigin_SteamDeck_RightStick_DPadWest, + k_EControllerActionOrigin_SteamDeck_RightStick_DPadEast, + k_EControllerActionOrigin_SteamDeck_RightStick_Touch, + k_EControllerActionOrigin_SteamDeck_L4, + k_EControllerActionOrigin_SteamDeck_R4, + k_EControllerActionOrigin_SteamDeck_L5, + k_EControllerActionOrigin_SteamDeck_R5, + k_EControllerActionOrigin_SteamDeck_DPad_Move, + k_EControllerActionOrigin_SteamDeck_DPad_North, + k_EControllerActionOrigin_SteamDeck_DPad_South, + k_EControllerActionOrigin_SteamDeck_DPad_West, + k_EControllerActionOrigin_SteamDeck_DPad_East, + k_EControllerActionOrigin_SteamDeck_Gyro_Move, + k_EControllerActionOrigin_SteamDeck_Gyro_Pitch, + k_EControllerActionOrigin_SteamDeck_Gyro_Yaw, + k_EControllerActionOrigin_SteamDeck_Gyro_Roll, + k_EControllerActionOrigin_SteamDeck_Reserved1, + k_EControllerActionOrigin_SteamDeck_Reserved2, + k_EControllerActionOrigin_SteamDeck_Reserved3, + k_EControllerActionOrigin_SteamDeck_Reserved4, + k_EControllerActionOrigin_SteamDeck_Reserved5, + k_EControllerActionOrigin_SteamDeck_Reserved6, + k_EControllerActionOrigin_SteamDeck_Reserved7, + k_EControllerActionOrigin_SteamDeck_Reserved8, + k_EControllerActionOrigin_SteamDeck_Reserved9, + k_EControllerActionOrigin_SteamDeck_Reserved10, + k_EControllerActionOrigin_SteamDeck_Reserved11, + k_EControllerActionOrigin_SteamDeck_Reserved12, + k_EControllerActionOrigin_SteamDeck_Reserved13, + k_EControllerActionOrigin_SteamDeck_Reserved14, + k_EControllerActionOrigin_SteamDeck_Reserved15, + k_EControllerActionOrigin_SteamDeck_Reserved16, + k_EControllerActionOrigin_SteamDeck_Reserved17, + k_EControllerActionOrigin_SteamDeck_Reserved18, + k_EControllerActionOrigin_SteamDeck_Reserved19, + k_EControllerActionOrigin_SteamDeck_Reserved20, + + k_EControllerActionOrigin_Count, // If Steam has added support for new controllers origins will go here. + k_EControllerActionOrigin_MaximumPossibleValue = 32767, // Origins are currently a maximum of 16 bits. +}; + +#ifndef ISTEAMINPUT_H +enum EXboxOrigin +{ + k_EXboxOrigin_A, + k_EXboxOrigin_B, + k_EXboxOrigin_X, + k_EXboxOrigin_Y, + k_EXboxOrigin_LeftBumper, + k_EXboxOrigin_RightBumper, + k_EXboxOrigin_Menu, //Start + k_EXboxOrigin_View, //Back + k_EXboxOrigin_LeftTrigger_Pull, + k_EXboxOrigin_LeftTrigger_Click, + k_EXboxOrigin_RightTrigger_Pull, + k_EXboxOrigin_RightTrigger_Click, + k_EXboxOrigin_LeftStick_Move, + k_EXboxOrigin_LeftStick_Click, + k_EXboxOrigin_LeftStick_DPadNorth, + k_EXboxOrigin_LeftStick_DPadSouth, + k_EXboxOrigin_LeftStick_DPadWest, + k_EXboxOrigin_LeftStick_DPadEast, + k_EXboxOrigin_RightStick_Move, + k_EXboxOrigin_RightStick_Click, + k_EXboxOrigin_RightStick_DPadNorth, + k_EXboxOrigin_RightStick_DPadSouth, + k_EXboxOrigin_RightStick_DPadWest, + k_EXboxOrigin_RightStick_DPadEast, + k_EXboxOrigin_DPad_North, + k_EXboxOrigin_DPad_South, + k_EXboxOrigin_DPad_West, + k_EXboxOrigin_DPad_East, +}; + +enum ESteamInputType +{ + k_ESteamInputType_Unknown, + k_ESteamInputType_SteamController, + k_ESteamInputType_XBox360Controller, + k_ESteamInputType_XBoxOneController, + k_ESteamInputType_GenericGamepad, // DirectInput controllers + k_ESteamInputType_PS4Controller, + k_ESteamInputType_AppleMFiController, // Unused + k_ESteamInputType_AndroidController, // Unused + k_ESteamInputType_SwitchJoyConPair, // Unused + k_ESteamInputType_SwitchJoyConSingle, // Unused + k_ESteamInputType_SwitchProController, + k_ESteamInputType_MobileTouch, // Steam Link App On-screen Virtual Controller + k_ESteamInputType_PS3Controller, // Currently uses PS4 Origins + k_ESteamInputType_PS5Controller, // Added in SDK 151 + k_ESteamInputType_Count, + k_ESteamInputType_MaximumPossibleValue = 255, +}; +#endif + +enum ESteamControllerLEDFlag +{ + k_ESteamControllerLEDFlag_SetColor, + k_ESteamControllerLEDFlag_RestoreUserDefault +}; + +// ControllerHandle_t is used to refer to a specific controller. +// This handle will consistently identify a controller, even if it is disconnected and re-connected +typedef uint64 ControllerHandle_t; + + +// These handles are used to refer to a specific in-game action or action set +// All action handles should be queried during initialization for performance reasons +typedef uint64 ControllerActionSetHandle_t; +typedef uint64 ControllerDigitalActionHandle_t; +typedef uint64 ControllerAnalogActionHandle_t; + +#pragma pack( push, 1 ) + +#ifdef ISTEAMINPUT_H +#define ControllerAnalogActionData_t InputAnalogActionData_t +#define ControllerDigitalActionData_t InputDigitalActionData_t +#define ControllerMotionData_t InputMotionData_t +#else +struct ControllerAnalogActionData_t +{ + // Type of data coming from this action, this will match what got specified in the action set + EControllerSourceMode eMode; - // Right pad coordinates - short sRightPadX; - short sRightPadY; + // The current state of this action; will be delta updates for mouse actions + float x, y; + // Whether or not this action is currently available to be bound in the active action set + bool bActive; }; -#pragma pack( pop ) - -#define SteamControllerState_t SteamControllerState001_t +struct ControllerDigitalActionData_t +{ + // The current state of this action; will be true if currently pressed + bool bState; + + // Whether or not this action is currently available to be bound in the active action set + bool bActive; +}; -enum ESteamControllerPad +struct ControllerMotionData_t { - k_ESteamControllerPad_Left, - k_ESteamControllerPad_Right + // Sensor-fused absolute rotation; will drift in heading + float rotQuatX; + float rotQuatY; + float rotQuatZ; + float rotQuatW; + + // Positional acceleration + float posAccelX; + float posAccelY; + float posAccelZ; + + // Angular velocity + float rotVelX; + float rotVelY; + float rotVelZ; }; +#endif +#pragma pack( pop ) + //----------------------------------------------------------------------------- -// Purpose: Native Steam controller support API +// Purpose: Steam Input API //----------------------------------------------------------------------------- class ISteamController { public: + + // Init and Shutdown must be called when starting/ending use of this interface + virtual bool Init() = 0; + virtual bool Shutdown() = 0; + + // Synchronize API state with the latest Steam Controller inputs available. This + // is performed automatically by SteamAPI_RunCallbacks, but for the absolute lowest + // possible latency, you call this directly before reading controller state. This must + // be called from somewhere before GetConnectedControllers will return any handles + virtual void RunFrame() = 0; - // - // Native controller support API - // + // Enumerate currently connected controllers + // handlesOut should point to a STEAM_CONTROLLER_MAX_COUNT sized array of ControllerHandle_t handles + // Returns the number of handles written to handlesOut + virtual int GetConnectedControllers( STEAM_OUT_ARRAY_COUNT( STEAM_CONTROLLER_MAX_COUNT, Receives list of connected controllers ) ControllerHandle_t *handlesOut ) = 0; + + //----------------------------------------------------------------------------- + // ACTION SETS + //----------------------------------------------------------------------------- - // Must call init and shutdown when starting/ending use of the interface - virtual bool Init( const char *pchAbsolutePathToControllerConfigVDF ) = 0; - virtual bool Shutdown() = 0; + // Lookup the handle for an Action Set. Best to do this once on startup, and store the handles for all future API calls. + virtual ControllerActionSetHandle_t GetActionSetHandle( const char *pszActionSetName ) = 0; + + // Reconfigure the controller to use the specified action set (ie 'Menu', 'Walk' or 'Drive') + // This is cheap, and can be safely called repeatedly. It's often easier to repeatedly call it in + // your state loops, instead of trying to place it in all of your state transitions. + virtual void ActivateActionSet( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle ) = 0; + virtual ControllerActionSetHandle_t GetCurrentActionSet( ControllerHandle_t controllerHandle ) = 0; - // Pump callback/callresult events, SteamAPI_RunCallbacks will do this for you, - // normally never need to call directly. - virtual void RunFrame() = 0; + // ACTION SET LAYERS + virtual void ActivateActionSetLayer( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ) = 0; + virtual void DeactivateActionSetLayer( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ) = 0; + virtual void DeactivateAllActionSetLayers( ControllerHandle_t controllerHandle ) = 0; + // Enumerate currently active layers + // handlesOut should point to a STEAM_CONTROLLER_MAX_ACTIVE_LAYERS sized array of ControllerActionSetHandle_t handles. + // Returns the number of handles written to handlesOut + virtual int GetActiveActionSetLayers( ControllerHandle_t controllerHandle, STEAM_OUT_ARRAY_COUNT( STEAM_CONTROLLER_MAX_ACTIVE_LAYERS, Receives list of active layers ) ControllerActionSetHandle_t *handlesOut ) = 0; - // Get the state of the specified controller, returns false if that controller is not connected - virtual bool GetControllerState( uint32 unControllerIndex, SteamControllerState_t *pState ) = 0; + //----------------------------------------------------------------------------- + // ACTIONS + //----------------------------------------------------------------------------- - // Trigger a haptic pulse on the controller - virtual void TriggerHapticPulse( uint32 unControllerIndex, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) = 0; + // Lookup the handle for a digital action. Best to do this once on startup, and store the handles for all future API calls. + virtual ControllerDigitalActionHandle_t GetDigitalActionHandle( const char *pszActionName ) = 0; + + // Returns the current state of the supplied digital game action + virtual ControllerDigitalActionData_t GetDigitalActionData( ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle ) = 0; + + // Get the origin(s) for a digital action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. + // originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles. The EControllerActionOrigin enum will get extended as support for new controller controllers gets added to + // the Steam client and will exceed the values from this header, please check bounds if you are using a look up table. + virtual int GetDigitalActionOrigins( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerDigitalActionHandle_t digitalActionHandle, STEAM_OUT_ARRAY_COUNT( STEAM_CONTROLLER_MAX_ORIGINS, Receives list of aciton origins ) EControllerActionOrigin *originsOut ) = 0; + + // Lookup the handle for an analog action. Best to do this once on startup, and store the handles for all future API calls. + virtual ControllerAnalogActionHandle_t GetAnalogActionHandle( const char *pszActionName ) = 0; + + // Returns the current state of these supplied analog game action + virtual ControllerAnalogActionData_t GetAnalogActionData( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle ) = 0; - // Set the override mode which is used to choose to use different base/legacy bindings from your config file - virtual void SetOverrideMode( const char *pchMode ) = 0; -}; + // Get the origin(s) for an analog action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. + // originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles. The EControllerActionOrigin enum will get extended as support for new controller controllers gets added to + // the Steam client and will exceed the values from this header, please check bounds if you are using a look up table. + virtual int GetAnalogActionOrigins( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerAnalogActionHandle_t analogActionHandle, STEAM_OUT_ARRAY_COUNT( STEAM_CONTROLLER_MAX_ORIGINS, Receives list of action origins ) EControllerActionOrigin *originsOut ) = 0; + + // Get a local path to art for on-screen glyph for a particular origin - this call is cheap + virtual const char *GetGlyphForActionOrigin( EControllerActionOrigin eOrigin ) = 0; + + // Returns a localized string (from Steam's language setting) for the specified origin - this call is serialized + virtual const char *GetStringForActionOrigin( EControllerActionOrigin eOrigin ) = 0; -#define STEAMCONTROLLER_INTERFACE_VERSION "STEAMCONTROLLER_INTERFACE_VERSION" + virtual void StopAnalogActionMomentum( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction ) = 0; -// callbacks -#if defined( VALVE_CALLBACK_PACK_SMALL ) -#pragma pack( push, 4 ) -#elif defined( VALVE_CALLBACK_PACK_LARGE ) -#pragma pack( push, 8 ) -#else -#error isteamclient.h must be included -#endif + // Returns raw motion data from the specified controller + virtual ControllerMotionData_t GetMotionData( ControllerHandle_t controllerHandle ) = 0; -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -/* -struct ControllerCallback_t -{ - enum { k_iCallback = k_iSteamControllerCallbacks + 1 }; + //----------------------------------------------------------------------------- + // OUTPUTS + //----------------------------------------------------------------------------- + + // Trigger a haptic pulse on a controller + virtual void TriggerHapticPulse( ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) = 0; + + // Trigger a pulse with a duty cycle of usDurationMicroSec / usOffMicroSec, unRepeat times. + // nFlags is currently unused and reserved for future use. + virtual void TriggerRepeatedHapticPulse( ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec, unsigned short usOffMicroSec, unsigned short unRepeat, unsigned int nFlags ) = 0; -}; -*/ + // Trigger a vibration event on supported controllers. + virtual void TriggerVibration( ControllerHandle_t controllerHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed ) = 0; + // Set the controller LED color on supported controllers. + virtual void SetLEDColor( ControllerHandle_t controllerHandle, uint8 nColorR, uint8 nColorG, uint8 nColorB, unsigned int nFlags ) = 0; -#pragma pack( pop ) + //----------------------------------------------------------------------------- + // Utility functions available without using the rest of Steam Input API + //----------------------------------------------------------------------------- + + // Invokes the Steam overlay and brings up the binding screen if the user is using Big Picture Mode + // If the user is not in Big Picture Mode it will open up the binding in a new window + virtual bool ShowBindingPanel( ControllerHandle_t controllerHandle ) = 0; + + // Returns the input type for a particular handle - unlike EControllerActionOrigin which update with Steam and may return unrecognized values + // ESteamInputType will remain static and only return valid values from your SDK version + virtual ESteamInputType GetInputTypeForHandle( ControllerHandle_t controllerHandle ) = 0; + + // Returns the associated controller handle for the specified emulated gamepad - can be used with the above 2 functions + // to identify controllers presented to your game over Xinput. Returns 0 if the Xinput index isn't associated with Steam Input + virtual ControllerHandle_t GetControllerForGamepadIndex( int nIndex ) = 0; + + // Returns the associated gamepad index for the specified controller, if emulating a gamepad or -1 if not associated with an Xinput index + virtual int GetGamepadIndexForController( ControllerHandle_t ulControllerHandle ) = 0; + + // Returns a localized string (from Steam's language setting) for the specified Xbox controller origin. + virtual const char *GetStringForXboxOrigin( EXboxOrigin eOrigin ) = 0; + + // Get a local path to art for on-screen glyph for a particular Xbox controller origin. + virtual const char *GetGlyphForXboxOrigin( EXboxOrigin eOrigin ) = 0; + + // Get the equivalent ActionOrigin for a given Xbox controller origin this can be chained with GetGlyphForActionOrigin to provide future proof glyphs for + // non-Steam Input API action games. Note - this only translates the buttons directly and doesn't take into account any remapping a user has made in their configuration + virtual EControllerActionOrigin GetActionOriginFromXboxOrigin( ControllerHandle_t controllerHandle, EXboxOrigin eOrigin ) = 0; + + // Convert an origin to another controller type - for inputs not present on the other controller type this will return k_EControllerActionOrigin_None + virtual EControllerActionOrigin TranslateActionOrigin( ESteamInputType eDestinationInputType, EControllerActionOrigin eSourceOrigin ) = 0; + + // Get the binding revision for a given device. Returns false if the handle was not valid or if a mapping is not yet loaded for the device + virtual bool GetControllerBindingRevision( ControllerHandle_t controllerHandle, int *pMajor, int *pMinor ) = 0; +}; + +#define STEAMCONTROLLER_INTERFACE_VERSION "SteamController008" +// Global interface accessor +inline ISteamController *SteamController(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamController *, SteamController, STEAMCONTROLLER_INTERFACE_VERSION ); #endif // ISTEAMCONTROLLER_H diff --git a/public/steam/isteamdualsense.h b/public/steam/isteamdualsense.h new file mode 100644 index 00000000..5acc8574 --- /dev/null +++ b/public/steam/isteamdualsense.h @@ -0,0 +1,169 @@ +/* SIE CONFIDENTIAL + * $PSLibId$ + * Copyright (C) 2019 Sony Interactive Entertainment Inc. + * All Rights Reserved. + */ + + +#ifndef _SCE_PAD_TRIGGER_EFFECT_H +#define _SCE_PAD_TRIGGER_EFFECT_H + + +#define SCE_PAD_TRIGGER_EFFECT_TRIGGER_MASK_L2 0x01 +#define SCE_PAD_TRIGGER_EFFECT_TRIGGER_MASK_R2 0x02 + +#define SCE_PAD_TRIGGER_EFFECT_PARAM_INDEX_FOR_L2 0 +#define SCE_PAD_TRIGGER_EFFECT_PARAM_INDEX_FOR_R2 1 + +#define SCE_PAD_TRIGGER_EFFECT_TRIGGER_NUM 2 + +/* Definition of control point num */ +#define SCE_PAD_TRIGGER_EFFECT_CONTROL_POINT_NUM 10 + +typedef enum ScePadTriggerEffectMode{ + SCE_PAD_TRIGGER_EFFECT_MODE_OFF, + SCE_PAD_TRIGGER_EFFECT_MODE_FEEDBACK, + SCE_PAD_TRIGGER_EFFECT_MODE_WEAPON, + SCE_PAD_TRIGGER_EFFECT_MODE_VIBRATION, + SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_FEEDBACK, + SCE_PAD_TRIGGER_EFFECT_MODE_SLOPE_FEEDBACK, + SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_VIBRATION, +} ScePadTriggerEffectMode; + +/** + *E + * @brief parameter for setting the trigger effect to off mode. + * Off Mode: Stop trigger effect. + **/ +typedef struct ScePadTriggerEffectOffParam{ + uint8_t padding[48]; +} ScePadTriggerEffectOffParam; + +/** + *E + * @brief parameter for setting the trigger effect to Feedback mode. + * Feedback Mode: The motor arm pushes back trigger. + * Trigger obtains stiffness at specified position. + **/ +typedef struct ScePadTriggerEffectFeedbackParam{ + uint8_t position; /*E position where the strength of target trigger start changing(0~9). */ + uint8_t strength; /*E strength that the motor arm pushes back target trigger(0~8 (0: Same as Off mode)). */ + uint8_t padding[46]; +} ScePadTriggerEffectFeedbackParam; + +/** + *E + * @brief parameter for setting the trigger effect to Weapon mode. + * Weapon Mode: Emulate weapon like gun trigger. + **/ +typedef struct ScePadTriggerEffectWeaponParam{ + uint8_t startPosition; /*E position where the stiffness of trigger start changing(2~7). */ + uint8_t endPosition; /*E position where the stiffness of trigger finish changing(startPosition+1~8). */ + uint8_t strength; /*E strength of gun trigger(0~8 (0: Same as Off mode)). */ + uint8_t padding[45]; +} ScePadTriggerEffectWeaponParam; + +/** + *E + * @brief parameter for setting the trigger effect to Vibration mode. + * Vibration Mode: Vibrates motor arm around specified position. + **/ +typedef struct ScePadTriggerEffectVibrationParam{ + uint8_t position; /*E position where the motor arm start vibrating(0~9). */ + uint8_t amplitude; /*E vibration amplitude(0~8 (0: Same as Off mode)). */ + uint8_t frequency; /*E vibration frequency(0~255[Hz] (0: Same as Off mode)). */ + uint8_t padding[45]; +} ScePadTriggerEffectVibrationParam; + +/** + *E + * @brief parameter for setting the trigger effect to ScePadTriggerEffectMultiplePositionFeedbackParam mode. + * Multi Position Feedback Mode: The motor arm pushes back trigger. + * Trigger obtains specified stiffness at each control point. + **/ +typedef struct ScePadTriggerEffectMultiplePositionFeedbackParam{ + uint8_t strength[SCE_PAD_TRIGGER_EFFECT_CONTROL_POINT_NUM]; /*E strength that the motor arm pushes back target trigger at position(0~8 (0: Same as Off mode)). + * strength[0] means strength of motor arm at position0. + * strength[1] means strength of motor arm at position1. + * ... + * */ + uint8_t padding[38]; +} ScePadTriggerEffectMultiplePositionFeedbackParam; + +/** + *E + * @brief parameter for setting the trigger effect to Feedback3 mode. + * Slope Feedback Mode: The motor arm pushes back trigger between two spedified control points. + * Stiffness of the trigger is changing depending on the set place. + **/ +typedef struct ScePadTriggerEffectSlopeFeedbackParam{ + + uint8_t startPosition; /*E position where the strength of target trigger start changing(0~endPosition). */ + uint8_t endPosition; /*E position where the strength of target trigger finish changing(startPosition+1~9). */ + uint8_t startStrength; /*E strength when trigger's position is startPosition(1~8) */ + uint8_t endStrength; /*E strength when trigger's position is endPosition(1~8) */ + uint8_t padding[44]; +} ScePadTriggerEffectSlopeFeedbackParam; + +/** + *E + * @brief parameter for setting the trigger effect to Vibration2 mode. + * Multi Position Vibration Mode: Vibrates motor arm around specified control point. + * Trigger vibrates specified amplitude at each control point. + **/ +typedef struct ScePadTriggerEffectMultiplePositionVibrationParam{ + uint8_t frequency; /*E vibration frequency(0~255 (0: Same as Off mode)) */ + uint8_t amplitude[SCE_PAD_TRIGGER_EFFECT_CONTROL_POINT_NUM]; /*E vibration amplitude at position(0~8 (0: Same as Off mode)). + * amplitude[0] means amplitude of vibration at position0. + * amplitude[1] means amplitude of vibration at position1. + * ... + * */ + uint8_t padding[37]; +} ScePadTriggerEffectMultiplePositionVibrationParam; + +/** + *E + * @brief parameter for setting the trigger effect mode. + **/ +typedef union ScePadTriggerEffectCommandData{ + ScePadTriggerEffectOffParam offParam; + ScePadTriggerEffectFeedbackParam feedbackParam; + ScePadTriggerEffectWeaponParam weaponParam; + ScePadTriggerEffectVibrationParam vibrationParam; + ScePadTriggerEffectMultiplePositionFeedbackParam multiplePositionFeedbackParam; + ScePadTriggerEffectSlopeFeedbackParam slopeFeedbackParam; + ScePadTriggerEffectMultiplePositionVibrationParam multiplePositionVibrationParam; +} ScePadTriggerEffectCommandData; + +/** + *E + * @brief parameter for setting the trigger effect. + **/ +typedef struct ScePadTriggerEffectCommand{ + ScePadTriggerEffectMode mode; + uint8_t padding[4]; + ScePadTriggerEffectCommandData commandData; +} ScePadTriggerEffectCommand; + +/** + *E + * @brief parameter for the scePadSetTriggerEffect function. + **/ +typedef struct ScePadTriggerEffectParam{ + + uint8_t triggerMask; /*E Set trigger mask to activate trigger effect commands. + * SCE_PAD_TRIGGER_EFFECT_TRIGGER_MASK_L2 : 0x01 + * SCE_PAD_TRIGGER_EFFECT_TRIGGER_MASK_R2 : 0x02 + * */ + uint8_t padding[7]; + + ScePadTriggerEffectCommand command[SCE_PAD_TRIGGER_EFFECT_TRIGGER_NUM]; /*E command[SCE_PAD_TRIGGER_EFFECT_PARAM_INDEX_FOR_L2] is for L2 trigger setting + * and param[SCE_PAD_TRIGGER_EFFECT_PARAM_INDEX_FOR_R2] is for R2 trgger setting. + * */ +} ScePadTriggerEffectParam; + +#if defined(__cplusplus) && __cplusplus >= 201103L +static_assert( sizeof( ScePadTriggerEffectParam ) == 120, "ScePadTriggerEffectParam has incorrect size" ); +#endif + +#endif /* _SCE_PAD_TRIGGER_EFFECT_H */ diff --git a/public/steam/isteamfriends.h b/public/steam/isteamfriends.h index 60526edd..4ac4293c 100644 --- a/public/steam/isteamfriends.h +++ b/public/steam/isteamfriends.h @@ -1,4 +1,4 @@ -//====== Copyright (C) 1996-2008, Valve Corporation, All rights reserved. ===== +//====== Copyright Valve Corporation, All rights reserved. ==================== // // Purpose: interface to both friends list data and general information about users // @@ -10,9 +10,7 @@ #pragma once #endif -#include "isteamclient.h" -#include "steamclientpublic.h" - +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: set of relationships to other users @@ -26,7 +24,7 @@ enum EFriendRelationship k_EFriendRelationshipRequestInitiator = 4, k_EFriendRelationshipIgnored = 5, // this is stored; the user has explicit blocked this other user from comments/chat/etc k_EFriendRelationshipIgnoredFriend = 6, - k_EFriendRelationshipSuggested = 7, + k_EFriendRelationshipSuggested_DEPRECATED = 7, // was used by the original implementation of the facebook linking feature, but now unused. // keep this updated k_EFriendRelationshipMax = 8, @@ -59,6 +57,7 @@ enum EPersonaState k_EPersonaStateSnooze = 4, // auto-away for a long time k_EPersonaStateLookingToTrade = 5, // Online, trading k_EPersonaStateLookingToPlay = 6, // Online, wanting to play + k_EPersonaStateInvisible = 7, // Online, but appears offline to friends. This status is never published to clients. k_EPersonaStateMax, }; @@ -80,7 +79,8 @@ enum EFriendFlags k_EFriendFlagRequestingInfo = 0x100, k_EFriendFlagIgnored = 0x200, k_EFriendFlagIgnoredFriend = 0x400, - k_EFriendFlagSuggested = 0x800, + // k_EFriendFlagSuggested = 0x800, // not used + k_EFriendFlagChatMember = 0x1000, k_EFriendFlagAll = 0xFFFF, }; @@ -91,7 +91,7 @@ enum EFriendFlags #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif struct FriendGameInfo_t { @@ -127,22 +127,11 @@ enum EUserRestriction k_nUserRestrictionTrading = 64, // user cannot participate in trading (console, mobile) }; -//----------------------------------------------------------------------------- -// Purpose: information about user sessions -//----------------------------------------------------------------------------- -struct FriendSessionStateInfo_t -{ - uint32 m_uiOnlineSessionInstances; - uint8 m_uiPublishedToFriendsSessionInstance; -}; - - - // size limit on chat room or member metadata const uint32 k_cubChatMetadataMax = 8192; // size limits on Rich Presence data -enum { k_cchMaxRichPresenceKeys = 20 }; +enum { k_cchMaxRichPresenceKeys = 30 }; enum { k_cchMaxRichPresenceKeyLength = 64 }; enum { k_cchMaxRichPresenceValueLength = 256 }; @@ -154,6 +143,47 @@ enum EOverlayToStoreFlag k_EOverlayToStoreFlag_AddToCartAndShow = 2, }; + +//----------------------------------------------------------------------------- +// Purpose: Tells Steam where to place the browser window inside the overlay +//----------------------------------------------------------------------------- +enum EActivateGameOverlayToWebPageMode +{ + k_EActivateGameOverlayToWebPageMode_Default = 0, // Browser will open next to all other windows that the user has open in the overlay. + // The window will remain open, even if the user closes then re-opens the overlay. + + k_EActivateGameOverlayToWebPageMode_Modal = 1 // Browser will be opened in a special overlay configuration which hides all other windows + // that the user has open in the overlay. When the user closes the overlay, the browser window + // will also close. When the user closes the browser window, the overlay will automatically close. +}; + +//----------------------------------------------------------------------------- +// Purpose: See GetProfileItemPropertyString and GetProfileItemPropertyUint +//----------------------------------------------------------------------------- +enum ECommunityProfileItemType +{ + k_ECommunityProfileItemType_AnimatedAvatar = 0, + k_ECommunityProfileItemType_AvatarFrame = 1, + k_ECommunityProfileItemType_ProfileModifier = 2, + k_ECommunityProfileItemType_ProfileBackground = 3, + k_ECommunityProfileItemType_MiniProfileBackground = 4, +}; +enum ECommunityProfileItemProperty +{ + k_ECommunityProfileItemProperty_ImageSmall = 0, // string + k_ECommunityProfileItemProperty_ImageLarge = 1, // string + k_ECommunityProfileItemProperty_InternalName = 2, // string + k_ECommunityProfileItemProperty_Title = 3, // string + k_ECommunityProfileItemProperty_Description = 4, // string + k_ECommunityProfileItemProperty_AppID = 5, // uint32 + k_ECommunityProfileItemProperty_TypeID = 6, // uint32 + k_ECommunityProfileItemProperty_Class = 7, // uint32 + k_ECommunityProfileItemProperty_MovieWebM = 8, // string + k_ECommunityProfileItemProperty_MovieMP4 = 9, // string + k_ECommunityProfileItemProperty_MovieWebMSmall = 10, // string + k_ECommunityProfileItemProperty_MovieMP4Small = 11, // string +}; + //----------------------------------------------------------------------------- // Purpose: interface to accessing information about individual users, // that can be a friend, in a group, on a game server or in a lobby with the local user @@ -175,6 +205,7 @@ class ISteamFriends // // If the name change fails to happen on the server, then an additional global PersonaStateChange_t will be posted // to change the name back, in addition to the SetPersonaNameResponse_t callback. + STEAM_CALL_RESULT( SetPersonaNameResponse_t ) virtual SteamAPICall_t SetPersonaName( const char *pchPersonaName ) = 0; // gets the status of the current user @@ -205,13 +236,14 @@ class ISteamFriends virtual const char *GetFriendPersonaName( CSteamID steamIDFriend ) = 0; // returns true if the friend is actually in a game, and fills in pFriendGameInfo with an extra details - virtual bool GetFriendGamePlayed( CSteamID steamIDFriend, OUT_STRUCT() FriendGameInfo_t *pFriendGameInfo ) = 0; + virtual bool GetFriendGamePlayed( CSteamID steamIDFriend, STEAM_OUT_STRUCT() FriendGameInfo_t *pFriendGameInfo ) = 0; // accesses old friends names - returns an empty string when their are no more items in the history virtual const char *GetFriendPersonaNameHistory( CSteamID steamIDFriend, int iPersonaName ) = 0; // friends steam level virtual int GetFriendSteamLevel( CSteamID steamIDFriend ) = 0; // Returns nickname the current user has set for the specified player. Returns NULL if the no nickname has been set for that player. + // DEPRECATED: GetPersonaName follows the Steam nickname preferences, so apps shouldn't need to care about nicknames explicitly. virtual const char *GetPlayerNickname( CSteamID steamIDPlayer ) = 0; // friend grouping (tag) apis @@ -224,7 +256,7 @@ class ISteamFriends // returns the number of members in a given friends group virtual int GetFriendsGroupMembersCount( FriendsGroupID_t friendsGroupID ) = 0; // gets up to nMembersCount members of the given friends group, if fewer exist than requested those positions' SteamIDs will be invalid - virtual void GetFriendsGroupMembersList( FriendsGroupID_t friendsGroupID, OUT_ARRAY_CALL(nMembersCount, GetFriendsGroupMembersCount, friendsGroupID ) CSteamID *pOutSteamIDMembers, int nMembersCount ) = 0; + virtual void GetFriendsGroupMembersList( FriendsGroupID_t friendsGroupID, STEAM_OUT_ARRAY_CALL(nMembersCount, GetFriendsGroupMembersCount, friendsGroupID ) CSteamID *pOutSteamIDMembers, int nMembersCount ) = 0; // returns true if the specified user meets any of the criteria specified in iFriendFlags // iFriendFlags can be the union (binary or, |) of one or more k_EFriendFlags values @@ -237,8 +269,10 @@ class ISteamFriends virtual const char *GetClanTag( CSteamID steamIDClan ) = 0; // returns the most recent information we have about what's happening in a clan virtual bool GetClanActivityCounts( CSteamID steamIDClan, int *pnOnline, int *pnInGame, int *pnChatting ) = 0; + // for clans a user is a member of, they will have reasonably up-to-date information, but for others you'll have to download the info to have the latest - virtual SteamAPICall_t DownloadClanActivityCounts( ARRAY_COUNT(cClansToRequest) CSteamID *psteamIDClans, int cClansToRequest ) = 0; + STEAM_CALL_RESULT( DownloadClanActivityCountsResult_t ) + virtual SteamAPICall_t DownloadClanActivityCounts( STEAM_ARRAY_COUNT(cClansToRequest) CSteamID *psteamIDClans, int cClansToRequest ) = 0; // iterators for getting users in a chat room, lobby, game server or clan // note that large clans that cannot be iterated by the local user @@ -254,7 +288,8 @@ class ISteamFriends virtual void SetInGameVoiceSpeaking( CSteamID steamIDUser, bool bSpeaking ) = 0; // activates the game overlay, with an optional dialog to open - // valid options are "Friends", "Community", "Players", "Settings", "OfficialGameGroup", "Stats", "Achievements" + // valid options include "Friends", "Community", "Players", "Settings", "OfficialGameGroup", "Stats", "Achievements", + // "chatroomgroup/nnnn" virtual void ActivateGameOverlay( const char *pchDialog ) = 0; // activates game overlay to a specific place @@ -272,7 +307,7 @@ class ISteamFriends // activates game overlay web browser directly to the specified URL // full address with protocol type is required, e.g. http://www.steamgames.com/ - virtual void ActivateGameOverlayToWebPage( const char *pchURL ) = 0; + virtual void ActivateGameOverlayToWebPage( const char *pchURL, EActivateGameOverlayToWebPageMode eMode = k_EActivateGameOverlayToWebPageMode_Default ) = 0; // activates game overlay to store page for app virtual void ActivateGameOverlayToStore( AppId_t nAppID, EOverlayToStoreFlag eFlag ) = 0; @@ -307,6 +342,7 @@ class ISteamFriends // you can only ask about clans that a user is a member of // note that this won't download avatars automatically; if you get an officer, // and no avatar image is available, call RequestUserInformation( steamID, false ) to download the avatar + STEAM_CALL_RESULT( ClanOfficerListResponse_t ) virtual SteamAPICall_t RequestClanOfficerList( CSteamID steamIDClan ) = 0; // iteration of clan officers - can only be done when a RequestClanOfficerList() call has completed @@ -324,10 +360,16 @@ class ISteamFriends // Rich Presence data is automatically shared between friends who are in the same game // Each user has a set of Key/Value pairs - // Up to 20 different keys can be set - // There are two magic keys: + // Note the following limits: k_cchMaxRichPresenceKeys, k_cchMaxRichPresenceKeyLength, k_cchMaxRichPresenceValueLength + // There are five magic keys: // "status" - a UTF-8 string that will show up in the 'view game info' dialog in the Steam friends list // "connect" - a UTF-8 string that contains the command-line for how a friend can connect to a game + // "steam_display" - Names a rich presence localization token that will be displayed in the viewing user's selected language + // in the Steam client UI. For more info: https://partner.steamgames.com/doc/api/ISteamFriends#richpresencelocalization + // "steam_player_group" - When set, indicates to the Steam client that the player is a member of a particular group. Players in the same group + // may be organized together in various places in the Steam UI. + // "steam_player_group_size" - When set, indicates the total number of players in the steam_player_group. The Steam client may use this number to + // display additional information about a group when all of the members are not part of a user's friends list. // GetFriendRichPresence() returns an empty string "" if no value is set // SetRichPresence() to a NULL or an empty string deletes the key // You can iterate the current set of keys for a friend with GetFriendRichPresenceKeyCount() @@ -340,10 +382,9 @@ class ISteamFriends // Requests rich presence for a specific user. virtual void RequestFriendRichPresence( CSteamID steamIDFriend ) = 0; - // rich invite support - // if the target accepts the invite, the pchConnectString gets added to the command-line for launching the game - // if the game is already running, a GameRichPresenceJoinRequested_t callback is posted containing the connect string - // invites can only be sent to friends + // Rich invite support. + // If the target accepts the invite, a GameRichPresenceJoinRequested_t callback is posted containing the connect string. + // (Or you can configure your game so that it is passed on the command line instead. This is a deprecated path; ask us if you really need this.) virtual bool InviteUserToGame( CSteamID steamIDFriend, const char *pchConnectString ) = 0; // recently-played-with friends iteration @@ -358,12 +399,13 @@ class ISteamFriends // this allows in-game access to group (clan) chats from in the game // the behavior is somewhat sophisticated, because the user may or may not be already in the group chat from outside the game or in the overlay // use ActivateGameOverlayToUser( "chat", steamIDClan ) to open the in-game overlay version of the chat + STEAM_CALL_RESULT( JoinClanChatRoomCompletionResult_t ) virtual SteamAPICall_t JoinClanChatRoom( CSteamID steamIDClan ) = 0; virtual bool LeaveClanChatRoom( CSteamID steamIDClan ) = 0; virtual int GetClanChatMemberCount( CSteamID steamIDClan ) = 0; virtual CSteamID GetChatMemberByIndex( CSteamID steamIDClan, int iUser ) = 0; virtual bool SendClanChatMessage( CSteamID steamIDClanChat, const char *pchText ) = 0; - virtual int GetClanChatMessage( CSteamID steamIDClanChat, int iMessage, void *prgchText, int cchTextMax, EChatEntryType *peChatEntryType, OUT_STRUCT() CSteamID *psteamidChatter ) = 0; + virtual int GetClanChatMessage( CSteamID steamIDClanChat, int iMessage, void *prgchText, int cchTextMax, EChatEntryType *peChatEntryType, STEAM_OUT_STRUCT() CSteamID *psteamidChatter ) = 0; virtual bool IsClanChatAdmin( CSteamID steamIDClanChat, CSteamID steamIDUser ) = 0; // interact with the Steam (game overlay / desktop) @@ -378,12 +420,49 @@ class ISteamFriends virtual int GetFriendMessage( CSteamID steamIDFriend, int iMessageID, void *pvData, int cubData, EChatEntryType *peChatEntryType ) = 0; // following apis + STEAM_CALL_RESULT( FriendsGetFollowerCount_t ) virtual SteamAPICall_t GetFollowerCount( CSteamID steamID ) = 0; + STEAM_CALL_RESULT( FriendsIsFollowing_t ) virtual SteamAPICall_t IsFollowing( CSteamID steamID ) = 0; + STEAM_CALL_RESULT( FriendsEnumerateFollowingList_t ) virtual SteamAPICall_t EnumerateFollowingList( uint32 unStartIndex ) = 0; + + virtual bool IsClanPublic( CSteamID steamIDClan ) = 0; + virtual bool IsClanOfficialGameGroup( CSteamID steamIDClan ) = 0; + + /// Return the number of chats (friends or chat rooms) with unread messages. + /// A "priority" message is one that would generate some sort of toast or + /// notification, and depends on user settings. + /// + /// You can register for UnreadChatMessagesChanged_t callbacks to know when this + /// has potentially changed. + virtual int GetNumChatsWithUnreadPriorityMessages() = 0; + + // activates game overlay to open the remote play together invite dialog. Invitations will be sent for remote play together + virtual void ActivateGameOverlayRemotePlayTogetherInviteDialog( CSteamID steamIDLobby ) = 0; + + // Call this before calling ActivateGameOverlayToWebPage() to have the Steam Overlay Browser block navigations + // to your specified protocol (scheme) uris and instead dispatch a OverlayBrowserProtocolNavigation_t callback to your game. + // ActivateGameOverlayToWebPage() must have been called with k_EActivateGameOverlayToWebPageMode_Modal + virtual bool RegisterProtocolInOverlayBrowser( const char *pchProtocol ) = 0; + + // Activates the game overlay to open an invite dialog that will send the provided Rich Presence connect string to selected friends + virtual void ActivateGameOverlayInviteDialogConnectString( const char *pchConnectString ) = 0; + + // Steam Community items equipped by a user on their profile + // You can register for EquippedProfileItemsChanged_t to know when a friend has changed their equipped profile items + STEAM_CALL_RESULT( EquippedProfileItems_t ) + virtual SteamAPICall_t RequestEquippedProfileItems( CSteamID steamID ) = 0; + virtual bool BHasEquippedProfileItem( CSteamID steamID, ECommunityProfileItemType itemType ) = 0; + virtual const char *GetProfileItemPropertyString( CSteamID steamID, ECommunityProfileItemType itemType, ECommunityProfileItemProperty prop ) = 0; + virtual uint32 GetProfileItemPropertyUint( CSteamID steamID, ECommunityProfileItemType itemType, ECommunityProfileItemProperty prop ) = 0; }; -#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends015" +#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends017" + +// Global interface accessor +inline ISteamFriends *SteamFriends(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamFriends *, SteamFriends, STEAMFRIENDS_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -391,7 +470,7 @@ class ISteamFriends #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- @@ -421,9 +500,10 @@ enum EPersonaChange k_EPersonaChangeLeftSource = 0x0100, k_EPersonaChangeRelationshipChanged = 0x0200, k_EPersonaChangeNameFirstSet = 0x0400, - k_EPersonaChangeFacebookInfo = 0x0800, + k_EPersonaChangeBroadcast = 0x0800, k_EPersonaChangeNickname = 0x1000, k_EPersonaChangeSteamLevel = 0x2000, + k_EPersonaChangeRichPresence = 0x4000, }; @@ -623,6 +703,47 @@ struct SetPersonaNameResponse_t EResult m_result; // detailed result code }; +//----------------------------------------------------------------------------- +// Purpose: Invoked when the status of unread messages changes +//----------------------------------------------------------------------------- +struct UnreadChatMessagesChanged_t +{ + enum { k_iCallback = k_iSteamFriendsCallbacks + 48 }; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Dispatched when an overlay browser instance is navigated to a protocol/scheme registered by RegisterProtocolInOverlayBrowser() +//----------------------------------------------------------------------------- +struct OverlayBrowserProtocolNavigation_t +{ + enum { k_iCallback = k_iSteamFriendsCallbacks + 49 }; + char rgchURI[ 1024 ]; +}; + +//----------------------------------------------------------------------------- +// Purpose: A user's equipped profile items have changed +//----------------------------------------------------------------------------- +struct EquippedProfileItemsChanged_t +{ + enum { k_iCallback = k_iSteamFriendsCallbacks + 50 }; + CSteamID m_steamID; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +struct EquippedProfileItems_t +{ + enum { k_iCallback = k_iSteamFriendsCallbacks + 51 }; + EResult m_eResult; + CSteamID m_steamID; + bool m_bHasAnimatedAvatar; + bool m_bHasAvatarFrame; + bool m_bHasProfileModifier; + bool m_bHasProfileBackground; + bool m_bHasMiniProfileBackground; +}; #pragma pack( pop ) diff --git a/public/steam/isteamgamecoordinator.h b/public/steam/isteamgamecoordinator.h new file mode 100644 index 00000000..89b740d7 --- /dev/null +++ b/public/steam/isteamgamecoordinator.h @@ -0,0 +1,74 @@ +//====== Copyright , Valve Corporation, All rights reserved. ======= +// +// Purpose: interface to the game coordinator for this application +// +//============================================================================= + +#ifndef ISTEAMGAMECOORDINATOR +#define ISTEAMGAMECOORDINATOR +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + + +// list of possible return values from the ISteamGameCoordinator API +enum EGCResults +{ + k_EGCResultOK = 0, + k_EGCResultNoMessage = 1, // There is no message in the queue + k_EGCResultBufferTooSmall = 2, // The buffer is too small for the requested message + k_EGCResultNotLoggedOn = 3, // The client is not logged onto Steam + k_EGCResultInvalidMessage = 4, // Something was wrong with the message being sent with SendMessage +}; + + +//----------------------------------------------------------------------------- +// Purpose: Functions for sending and receiving messages from the Game Coordinator +// for this application +//----------------------------------------------------------------------------- +class ISteamGameCoordinator +{ +public: + + // sends a message to the Game Coordinator + virtual EGCResults SendMessage( uint32 unMsgType, const void *pubData, uint32 cubData ) = 0; + + // returns true if there is a message waiting from the game coordinator + virtual bool IsMessageAvailable( uint32 *pcubMsgSize ) = 0; + + // fills the provided buffer with the first message in the queue and returns k_EGCResultOK or + // returns k_EGCResultNoMessage if there is no message waiting. pcubMsgSize is filled with the message size. + // If the provided buffer is not large enough to fit the entire message, k_EGCResultBufferTooSmall is returned + // and the message remains at the head of the queue. + virtual EGCResults RetrieveMessage( uint32 *punMsgType, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize ) = 0; + +}; +#define STEAMGAMECOORDINATOR_INTERFACE_VERSION "SteamGameCoordinator001" + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + +// callback notification - A new message is available for reading from the message queue +struct GCMessageAvailable_t +{ + enum { k_iCallback = k_iSteamGameCoordinatorCallbacks + 1 }; + uint32 m_nMessageSize; +}; + +// callback notification - A message failed to make it to the GC. It may be down temporarily +struct GCMessageFailed_t +{ + enum { k_iCallback = k_iSteamGameCoordinatorCallbacks + 2 }; +}; + +#pragma pack( pop ) + +#endif // ISTEAMGAMECOORDINATOR diff --git a/public/steam/isteamgameserver.h b/public/steam/isteamgameserver.h index cc109985..386e7fa4 100644 --- a/public/steam/isteamgameserver.h +++ b/public/steam/isteamgameserver.h @@ -10,9 +10,7 @@ #pragma once #endif -#include "isteamclient.h" - -#define MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE ((uint16)-1) +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: Functions for authenticating users via Steam to play on a game server @@ -27,7 +25,7 @@ class ISteamGameServer // /// This is called by SteamGameServer_Init, and you will usually not need to call it directly - virtual bool InitGameServer( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, uint32 unFlags, AppId_t nGameAppId, const char *pchVersionString ) = 0; + STEAM_PRIVATE_API( virtual bool InitGameServer( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, uint32 unFlags, AppId_t nGameAppId, const char *pchVersionString ) = 0; ) /// Game product identifier. This is currently used by the master server for version checking purposes. /// It's a required field, but will eventually will go away, and the AppID will be used for this purpose. @@ -93,14 +91,23 @@ class ISteamGameServer /// Set name of map to report in the server browser /// - /// @see k_cbMaxGameServerName + /// @see k_cbMaxGameServerMapName virtual void SetMapName( const char *pszMapName ) = 0; /// Let people know if your server will require a password virtual void SetPasswordProtected( bool bPasswordProtected ) = 0; - /// Spectator server. The default value is zero, meaning the service - /// is not used. + /// Spectator server port to advertise. The default value is zero, meaning the + /// service is not used. If your server receives any info requests on the LAN, + /// this is the value that will be placed into the reply for such local queries. + /// + /// This is also the value that will be advertised by the master server. + /// The only exception is if your server is using a FakeIP. Then then the second + /// fake port number (index 1) assigned to your server will be listed on the master + /// server as the spectator port, if you set this value to any nonzero value. + /// + /// This function merely controls the values that are advertised -- it's up to you to + /// configure the server to actually listen on this port and handle any spectator traffic virtual void SetSpectatorPort( uint16 unSpectatorPort ) = 0; /// Name of the spectator server. (Only used if spectator port is nonzero.) @@ -122,8 +129,6 @@ class ISteamGameServer /// Sets a string defining the "gamedata" for this server, this is optional, but if it is set /// it allows users to filter in the matchmaking/server-browser interfaces based on the value - /// don't set this unless it actually changes, its only uploaded to the master once (when - /// acknowledged) /// /// @see k_cbMaxGameServerGameData virtual void SetGameData( const char *pchGameData ) = 0; @@ -131,42 +136,20 @@ class ISteamGameServer /// Region identifier. This is an optional field, the default value is empty, meaning the "world" region virtual void SetRegion( const char *pszRegion ) = 0; + /// Indicate whether you wish to be listed on the master server list + /// and/or respond to server browser / LAN discovery packets. + /// The server starts with this value set to false. You should set all + /// relevant server parameters before enabling advertisement on the server. + /// + /// (This function used to be named EnableHeartbeats, so if you are wondering + /// where that function went, it's right here. It does the same thing as before, + /// the old name was just confusing.) + virtual void SetAdvertiseServerActive( bool bActive ) = 0; + // -// Player list management / authentication +// Player list management / authentication. // - // Handles receiving a new connection from a Steam user. This call will ask the Steam - // servers to validate the users identity, app ownership, and VAC status. If the Steam servers - // are off-line, then it will validate the cached ticket itself which will validate app ownership - // and identity. The AuthBlob here should be acquired on the game client using SteamUser()->InitiateGameConnection() - // and must then be sent up to the game server for authentication. - // - // Return Value: returns true if the users ticket passes basic checks. pSteamIDUser will contain the Steam ID of this user. pSteamIDUser must NOT be NULL - // If the call succeeds then you should expect a GSClientApprove_t or GSClientDeny_t callback which will tell you whether authentication - // for the user has succeeded or failed (the steamid in the callback will match the one returned by this call) - virtual bool SendUserConnectAndAuthenticate( uint32 unIPClient, const void *pvAuthBlob, uint32 cubAuthBlobSize, CSteamID *pSteamIDUser ) = 0; - - // Creates a fake user (ie, a bot) which will be listed as playing on the server, but skips validation. - // - // Return Value: Returns a SteamID for the user to be tracked with, you should call HandleUserDisconnect() - // when this user leaves the server just like you would for a real user. - virtual CSteamID CreateUnauthenticatedUserConnection() = 0; - - // Should be called whenever a user leaves our game server, this lets Steam internally - // track which users are currently on which servers for the purposes of preventing a single - // account being logged into multiple servers, showing who is currently on a server, etc. - virtual void SendUserDisconnect( CSteamID steamIDUser ) = 0; - - // Update the data to be displayed in the server browser and matchmaking interfaces for a user - // currently connected to the server. For regular users you must call this after you receive a - // GSUserValidationSuccess callback. - // - // Return Value: true if successful, false if failure (ie, steamIDUser wasn't for an active player) - virtual bool BUpdateUserData( CSteamID steamIDUser, const char *pchPlayerName, uint32 uScore ) = 0; - - // New auth system APIs - do not mix with the old auth system APIs. - // ---------------------------------------------------------------- - // Retrieve ticket to be sent to the entity who wishes to authenticate you ( using BeginAuthSession API ). // pcbTicket retrieves the length of the actual ticket. virtual HAuthTicket GetAuthSessionTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0; @@ -193,20 +176,18 @@ class ISteamGameServer // these two functions s are deprecated, and will not return results // they will be removed in a future version of the SDK virtual void GetGameplayStats( ) = 0; - virtual SteamAPICall_t GetServerReputation( ) = 0; + STEAM_CALL_RESULT( GSReputation_t ) + virtual SteamAPICall_t GetServerReputation() = 0; // Returns the public IP of the server according to Steam, useful when the server is // behind NAT and you want to advertise its IP in a lobby for other clients to directly // connect to - virtual uint32 GetPublicIP() = 0; + virtual SteamIPAddress_t GetPublicIP() = 0; + +// Server browser related query packet processing for shared socket mode. These are used +// when you pass STEAMGAMESERVER_QUERY_PORT_SHARED as the query port to SteamGameServer_Init. +// IP address and port are in host order, i.e 127.0.0.1 == 0x7f000001 -// These are in GameSocketShare mode, where instead of ISteamGameServer creating its own -// socket to talk to the master server on, it lets the game use its socket to forward messages -// back and forth. This prevents us from requiring server ops to open up yet another port -// in their firewalls. -// -// the IP address and port should be in host order, i.e 127.0.0.1 == 0x7f000001 - // These are used when you've elected to multiplex the game server's UDP socket // rather than having the master server updater use its own sockets. // @@ -224,43 +205,70 @@ class ISteamGameServer virtual int GetNextOutgoingPacket( void *pOut, int cbMaxOut, uint32 *pNetAdr, uint16 *pPort ) = 0; // -// Control heartbeats / advertisement with master server +// Server clan association // - // Call this as often as you like to tell the master server updater whether or not - // you want it to be active (default: off). - virtual void EnableHeartbeats( bool bActive ) = 0; - - // You usually don't need to modify this. - // Pass -1 to use the default value for iHeartbeatInterval. - // Some mods change this. - virtual void SetHeartbeatInterval( int iHeartbeatInterval ) = 0; - - // Force a heartbeat to steam at the next opportunity - virtual void ForceHeartbeat() = 0; - // associate this game server with this clan for the purposes of computing player compat + STEAM_CALL_RESULT( AssociateWithClanResult_t ) virtual SteamAPICall_t AssociateWithClan( CSteamID steamIDClan ) = 0; // ask if any of the current players dont want to play with this new player - or vice versa + STEAM_CALL_RESULT( ComputeNewPlayerCompatibilityResult_t ) virtual SteamAPICall_t ComputeNewPlayerCompatibility( CSteamID steamIDNewPlayer ) = 0; -}; -#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer012" -// game server flags -const uint32 k_unServerFlagNone = 0x00; -const uint32 k_unServerFlagActive = 0x01; // server has users playing -const uint32 k_unServerFlagSecure = 0x02; // server wants to be secure -const uint32 k_unServerFlagDedicated = 0x04; // server is dedicated -const uint32 k_unServerFlagLinux = 0x08; // linux build -const uint32 k_unServerFlagPassworded = 0x10; // password protected -const uint32 k_unServerFlagPrivate = 0x20; // server shouldn't list on master server and - // won't enforce authentication of users that connect to the server. - // Useful when you run a server where the clients may not - // be connected to the internet but you want them to play (i.e LANs) + // Handles receiving a new connection from a Steam user. This call will ask the Steam + // servers to validate the users identity, app ownership, and VAC status. If the Steam servers + // are off-line, then it will validate the cached ticket itself which will validate app ownership + // and identity. The AuthBlob here should be acquired on the game client using SteamUser()->InitiateGameConnection() + // and must then be sent up to the game server for authentication. + // + // Return Value: returns true if the users ticket passes basic checks. pSteamIDUser will contain the Steam ID of this user. pSteamIDUser must NOT be NULL + // If the call succeeds then you should expect a GSClientApprove_t or GSClientDeny_t callback which will tell you whether authentication + // for the user has succeeded or failed (the steamid in the callback will match the one returned by this call) + // + // DEPRECATED! This function will be removed from the SDK in an upcoming version. + // Please migrate to BeginAuthSession and related functions. + virtual bool SendUserConnectAndAuthenticate_DEPRECATED( uint32 unIPClient, const void *pvAuthBlob, uint32 cubAuthBlobSize, CSteamID *pSteamIDUser ) = 0; + + // Creates a fake user (ie, a bot) which will be listed as playing on the server, but skips validation. + // + // Return Value: Returns a SteamID for the user to be tracked with, you should call EndAuthSession() + // when this user leaves the server just like you would for a real user. + virtual CSteamID CreateUnauthenticatedUserConnection() = 0; + + // Should be called whenever a user leaves our game server, this lets Steam internally + // track which users are currently on which servers for the purposes of preventing a single + // account being logged into multiple servers, showing who is currently on a server, etc. + // + // DEPRECATED! This function will be removed from the SDK in an upcoming version. + // Please migrate to BeginAuthSession and related functions. + virtual void SendUserDisconnect_DEPRECATED( CSteamID steamIDUser ) = 0; + + // Update the data to be displayed in the server browser and matchmaking interfaces for a user + // currently connected to the server. For regular users you must call this after you receive a + // GSUserValidationSuccess callback. + // + // Return Value: true if successful, false if failure (ie, steamIDUser wasn't for an active player) + virtual bool BUpdateUserData( CSteamID steamIDUser, const char *pchPlayerName, uint32 uScore ) = 0; + +// Deprecated functions. These will be removed in a future version of the SDK. +// If you really need these, please contact us and help us understand what you are +// using them for. + + STEAM_PRIVATE_API( + virtual void SetMasterServerHeartbeatInterval_DEPRECATED( int iHeartbeatInterval ) = 0; + virtual void ForceMasterServerHeartbeat_DEPRECATED() = 0; + ) +}; + +#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer014" + +// Global accessor +inline ISteamGameServer *SteamGameServer(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamGameServer *, SteamGameServer, STEAMGAMESERVER_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -268,7 +276,7 @@ const uint32 k_unServerFlagPrivate = 0x20; // server shouldn't list on master #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif diff --git a/public/steam/isteamgameserverstats.h b/public/steam/isteamgameserverstats.h index 8d53186e..50192794 100644 --- a/public/steam/isteamgameserverstats.h +++ b/public/steam/isteamgameserverstats.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright Valve Corporation, All rights reserved. ======= // // Purpose: interface for game servers to steam stats and achievements // @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: Functions for authenticating users via Steam to play on a game server @@ -23,19 +23,29 @@ class ISteamGameServerStats // if the user has no stats, GSStatsReceived_t.m_eResult will be set to k_EResultFail // these stats will only be auto-updated for clients playing on the server. For other // users you'll need to call RequestUserStats() again to refresh any data + STEAM_CALL_RESULT( GSStatsReceived_t ) virtual SteamAPICall_t RequestUserStats( CSteamID steamIDUser ) = 0; // requests stat information for a user, usable after a successful call to RequestUserStats() + STEAM_FLAT_NAME( GetUserStatInt32 ) virtual bool GetUserStat( CSteamID steamIDUser, const char *pchName, int32 *pData ) = 0; + + STEAM_FLAT_NAME( GetUserStatFloat ) virtual bool GetUserStat( CSteamID steamIDUser, const char *pchName, float *pData ) = 0; + virtual bool GetUserAchievement( CSteamID steamIDUser, const char *pchName, bool *pbAchieved ) = 0; // Set / update stats and achievements. // Note: These updates will work only on stats game servers are allowed to edit and only for // game servers that have been declared as officially controlled by the game creators. // Set the IP range of your official servers on the Steamworks page + + STEAM_FLAT_NAME( SetUserStatInt32 ) virtual bool SetUserStat( CSteamID steamIDUser, const char *pchName, int32 nData ) = 0; + + STEAM_FLAT_NAME( SetUserStatFloat ) virtual bool SetUserStat( CSteamID steamIDUser, const char *pchName, float fData ) = 0; + virtual bool UpdateUserAvgRateStat( CSteamID steamIDUser, const char *pchName, float flCountThisSession, double dSessionLength ) = 0; virtual bool SetUserAchievement( CSteamID steamIDUser, const char *pchName ) = 0; @@ -47,18 +57,23 @@ class ISteamGameServerStats // uploaded has been rejected, either because they broke constraints // or were out of date. In this case the server sends back updated values. // The stats should be re-iterated to keep in sync. + STEAM_CALL_RESULT( GSStatsStored_t ) virtual SteamAPICall_t StoreUserStats( CSteamID steamIDUser ) = 0; }; - #define STEAMGAMESERVERSTATS_INTERFACE_VERSION "SteamGameServerStats001" +// Global accessor +inline ISteamGameServerStats *SteamGameServerStats(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamGameServerStats *, SteamGameServerStats, STEAMGAMESERVERSTATS_INTERFACE_VERSION ); + + // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- diff --git a/public/steam/isteamhtmlsurface.h b/public/steam/isteamhtmlsurface.h index c257164a..dd30fe24 100644 --- a/public/steam/isteamhtmlsurface.h +++ b/public/steam/isteamhtmlsurface.h @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" typedef uint32 HHTMLBrowser; const uint32 INVALID_HTMLBROWSER = 0; @@ -33,6 +33,14 @@ class ISteamHTMLSurface // identify your client on web servers. // The userCSS string lets you apply a CSS style sheet to every displayed page, leave null if // you do not require this functionality. + // + // YOU MUST HAVE IMPLEMENTED HANDLERS FOR HTML_BrowserReady_t, HTML_StartRequest_t, + // HTML_JSAlert_t, HTML_JSConfirm_t, and HTML_FileOpenDialog_t! See the CALLBACKS + // section of this interface (AllowStartRequest, etc) for more details. If you do + // not implement these callback handlers, the browser may appear to hang instead of + // navigating to new pages or triggering javascript popups. + // + STEAM_CALL_RESULT( HTML_BrowserReady_t ) virtual SteamAPICall_t CreateBrowser( const char *pchUserAgent, const char *pchUserCSS ) = 0; // Call this when you are done with a html surface, this lets us free the resources being used by it @@ -129,8 +137,9 @@ class ISteamHTMLSurface k_eHTMLKeyModifier_ShiftDown = 1 << 2, }; - // keyboard interactions, native keycode is the virtual key code value from your OS - virtual void KeyDown( HHTMLBrowser unBrowserHandle, uint32 nNativeKeyCode, EHTMLKeyModifiers eHTMLKeyModifiers ) = 0; + // keyboard interactions, native keycode is the virtual key code value from your OS, system key flags the key to not + // be sent as a typed character as well as a key down + virtual void KeyDown( HHTMLBrowser unBrowserHandle, uint32 nNativeKeyCode, EHTMLKeyModifiers eHTMLKeyModifiers, bool bIsSystemKey = false ) = 0; virtual void KeyUp( HHTMLBrowser unBrowserHandle, uint32 nNativeKeyCode, EHTMLKeyModifiers eHTMLKeyModifiers ) = 0; // cUnicodeChar is the unicode character point for this keypress (and potentially multiple chars per press) virtual void KeyChar( HHTMLBrowser unBrowserHandle, uint32 cUnicodeChar, EHTMLKeyModifiers eHTMLKeyModifiers ) = 0; @@ -169,6 +178,13 @@ class ISteamHTMLSurface // When background mode is disabled, any video or audio objects with that property will resume with ".play()". virtual void SetBackgroundMode( HHTMLBrowser unBrowserHandle, bool bBackgroundMode ) = 0; + // Scale the output display space by this factor, this is useful when displaying content on high dpi devices. + // Specifies the ratio between physical and logical pixels. + virtual void SetDPIScalingFactor( HHTMLBrowser unBrowserHandle, float flDPIScaling ) = 0; + + // Open HTML/JS developer tools + virtual void OpenDeveloperTools( HHTMLBrowser unBrowserHandle ) = 0; + // CALLBACKS // // These set of functions are used as responses to callback requests @@ -188,7 +204,11 @@ class ISteamHTMLSurface virtual void FileLoadDialogResponse( HHTMLBrowser unBrowserHandle, const char **pchSelectedFiles ) = 0; }; -#define STEAMHTMLSURFACE_INTERFACE_VERSION "STEAMHTMLSURFACE_INTERFACE_VERSION_003" +#define STEAMHTMLSURFACE_INTERFACE_VERSION "STEAMHTMLSURFACE_INTERFACE_VERSION_005" + +// Global interface accessor +inline ISteamHTMLSurface *SteamHTMLSurface(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamHTMLSurface *, SteamHTMLSurface, STEAMHTMLSURFACE_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -196,156 +216,156 @@ class ISteamHTMLSurface #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- // Purpose: The browser is ready for use //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_BrowserReady_t, k_iSteamHTMLSurfaceCallbacks + 1 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // this browser is now fully created and ready to navigate to pages -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( HTML_BrowserReady_t, k_iSteamHTMLSurfaceCallbacks + 1 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // this browser is now fully created and ready to navigate to pages +STEAM_CALLBACK_END(1) //----------------------------------------------------------------------------- // Purpose: the browser has a pending paint //----------------------------------------------------------------------------- -DEFINE_CALLBACK(HTML_NeedsPaint_t, k_iSteamHTMLSurfaceCallbacks + 2) -CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the browser that needs the paint -CALLBACK_MEMBER(1, const char *, pBGRA ) // a pointer to the B8G8R8A8 data for this surface, valid until SteamAPI_RunCallbacks is next called -CALLBACK_MEMBER(2, uint32, unWide) // the total width of the pBGRA texture -CALLBACK_MEMBER(3, uint32, unTall) // the total height of the pBGRA texture -CALLBACK_MEMBER(4, uint32, unUpdateX) // the offset in X for the damage rect for this update -CALLBACK_MEMBER(5, uint32, unUpdateY) // the offset in Y for the damage rect for this update -CALLBACK_MEMBER(6, uint32, unUpdateWide) // the width of the damage rect for this update -CALLBACK_MEMBER(7, uint32, unUpdateTall) // the height of the damage rect for this update -CALLBACK_MEMBER(8, uint32, unScrollX) // the page scroll the browser was at when this texture was rendered -CALLBACK_MEMBER(9, uint32, unScrollY) // the page scroll the browser was at when this texture was rendered -CALLBACK_MEMBER(10, float, flPageScale) // the page scale factor on this page when rendered -CALLBACK_MEMBER(11, uint32, unPageSerial) // incremented on each new page load, you can use this to reject draws while navigating to new pages -END_DEFINE_CALLBACK_12() +STEAM_CALLBACK_BEGIN(HTML_NeedsPaint_t, k_iSteamHTMLSurfaceCallbacks + 2) +STEAM_CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the browser that needs the paint +STEAM_CALLBACK_MEMBER(1, const char *, pBGRA ) // a pointer to the B8G8R8A8 data for this surface, valid until SteamAPI_RunCallbacks is next called +STEAM_CALLBACK_MEMBER(2, uint32, unWide) // the total width of the pBGRA texture +STEAM_CALLBACK_MEMBER(3, uint32, unTall) // the total height of the pBGRA texture +STEAM_CALLBACK_MEMBER(4, uint32, unUpdateX) // the offset in X for the damage rect for this update +STEAM_CALLBACK_MEMBER(5, uint32, unUpdateY) // the offset in Y for the damage rect for this update +STEAM_CALLBACK_MEMBER(6, uint32, unUpdateWide) // the width of the damage rect for this update +STEAM_CALLBACK_MEMBER(7, uint32, unUpdateTall) // the height of the damage rect for this update +STEAM_CALLBACK_MEMBER(8, uint32, unScrollX) // the page scroll the browser was at when this texture was rendered +STEAM_CALLBACK_MEMBER(9, uint32, unScrollY) // the page scroll the browser was at when this texture was rendered +STEAM_CALLBACK_MEMBER(10, float, flPageScale) // the page scale factor on this page when rendered +STEAM_CALLBACK_MEMBER(11, uint32, unPageSerial) // incremented on each new page load, you can use this to reject draws while navigating to new pages +STEAM_CALLBACK_END(12) //----------------------------------------------------------------------------- // Purpose: The browser wanted to navigate to a new page // NOTE - you MUST call AllowStartRequest in response to this callback //----------------------------------------------------------------------------- -DEFINE_CALLBACK(HTML_StartRequest_t, k_iSteamHTMLSurfaceCallbacks + 3) -CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the handle of the surface navigating -CALLBACK_MEMBER(1, const char *, pchURL) // the url they wish to navigate to -CALLBACK_MEMBER(2, const char *, pchTarget) // the html link target type (i.e _blank, _self, _parent, _top ) -CALLBACK_MEMBER(3, const char *, pchPostData ) // any posted data for the request -CALLBACK_MEMBER(4, bool, bIsRedirect) // true if this was a http/html redirect from the last load request -END_DEFINE_CALLBACK_5() +STEAM_CALLBACK_BEGIN(HTML_StartRequest_t, k_iSteamHTMLSurfaceCallbacks + 3) +STEAM_CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the handle of the surface navigating +STEAM_CALLBACK_MEMBER(1, const char *, pchURL) // the url they wish to navigate to +STEAM_CALLBACK_MEMBER(2, const char *, pchTarget) // the html link target type (i.e _blank, _self, _parent, _top ) +STEAM_CALLBACK_MEMBER(3, const char *, pchPostData ) // any posted data for the request +STEAM_CALLBACK_MEMBER(4, bool, bIsRedirect) // true if this was a http/html redirect from the last load request +STEAM_CALLBACK_END(5) //----------------------------------------------------------------------------- // Purpose: The browser has been requested to close due to user interaction (usually from a javascript window.close() call) //----------------------------------------------------------------------------- -DEFINE_CALLBACK(HTML_CloseBrowser_t, k_iSteamHTMLSurfaceCallbacks + 4) -CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the handle of the surface -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN(HTML_CloseBrowser_t, k_iSteamHTMLSurfaceCallbacks + 4) +STEAM_CALLBACK_MEMBER(0, HHTMLBrowser, unBrowserHandle) // the handle of the surface +STEAM_CALLBACK_END(1) //----------------------------------------------------------------------------- // Purpose: the browser is navigating to a new url //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_URLChanged_t, k_iSteamHTMLSurfaceCallbacks + 5 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface navigating -CALLBACK_MEMBER( 1, const char *, pchURL ) // the url they wish to navigate to -CALLBACK_MEMBER( 2, const char *, pchPostData ) // any posted data for the request -CALLBACK_MEMBER( 3, bool, bIsRedirect ) // true if this was a http/html redirect from the last load request -CALLBACK_MEMBER( 4, const char *, pchPageTitle ) // the title of the page -CALLBACK_MEMBER( 5, bool, bNewNavigation ) // true if this was from a fresh tab and not a click on an existing page -END_DEFINE_CALLBACK_6() +STEAM_CALLBACK_BEGIN( HTML_URLChanged_t, k_iSteamHTMLSurfaceCallbacks + 5 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface navigating +STEAM_CALLBACK_MEMBER( 1, const char *, pchURL ) // the url they wish to navigate to +STEAM_CALLBACK_MEMBER( 2, const char *, pchPostData ) // any posted data for the request +STEAM_CALLBACK_MEMBER( 3, bool, bIsRedirect ) // true if this was a http/html redirect from the last load request +STEAM_CALLBACK_MEMBER( 4, const char *, pchPageTitle ) // the title of the page +STEAM_CALLBACK_MEMBER( 5, bool, bNewNavigation ) // true if this was from a fresh tab and not a click on an existing page +STEAM_CALLBACK_END(6) //----------------------------------------------------------------------------- // Purpose: A page is finished loading //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_FinishedRequest_t, k_iSteamHTMLSurfaceCallbacks + 6 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchURL ) // -CALLBACK_MEMBER( 2, const char *, pchPageTitle ) // -END_DEFINE_CALLBACK_3() +STEAM_CALLBACK_BEGIN( HTML_FinishedRequest_t, k_iSteamHTMLSurfaceCallbacks + 6 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchURL ) // +STEAM_CALLBACK_MEMBER( 2, const char *, pchPageTitle ) // +STEAM_CALLBACK_END(3) //----------------------------------------------------------------------------- // Purpose: a request to load this url in a new tab //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_OpenLinkInNewTab_t, k_iSteamHTMLSurfaceCallbacks + 7 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchURL ) // -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_OpenLinkInNewTab_t, k_iSteamHTMLSurfaceCallbacks + 7 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchURL ) // +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: the page has a new title now //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_ChangedTitle_t, k_iSteamHTMLSurfaceCallbacks + 8 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchTitle ) // -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_ChangedTitle_t, k_iSteamHTMLSurfaceCallbacks + 8 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchTitle ) // +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: results from a search //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_SearchResults_t, k_iSteamHTMLSurfaceCallbacks + 9 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, uint32, unResults ) // -CALLBACK_MEMBER( 2, uint32, unCurrentMatch ) // -END_DEFINE_CALLBACK_3() +STEAM_CALLBACK_BEGIN( HTML_SearchResults_t, k_iSteamHTMLSurfaceCallbacks + 9 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, uint32, unResults ) // +STEAM_CALLBACK_MEMBER( 2, uint32, unCurrentMatch ) // +STEAM_CALLBACK_END(3) //----------------------------------------------------------------------------- // Purpose: page history status changed on the ability to go backwards and forward //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_CanGoBackAndForward_t, k_iSteamHTMLSurfaceCallbacks + 10 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, bool, bCanGoBack ) // -CALLBACK_MEMBER( 2, bool, bCanGoForward ) // -END_DEFINE_CALLBACK_3() +STEAM_CALLBACK_BEGIN( HTML_CanGoBackAndForward_t, k_iSteamHTMLSurfaceCallbacks + 10 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, bool, bCanGoBack ) // +STEAM_CALLBACK_MEMBER( 2, bool, bCanGoForward ) // +STEAM_CALLBACK_END(3) //----------------------------------------------------------------------------- // Purpose: details on the visibility and size of the horizontal scrollbar //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_HorizontalScroll_t, k_iSteamHTMLSurfaceCallbacks + 11 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, uint32, unScrollMax ) // -CALLBACK_MEMBER( 2, uint32, unScrollCurrent ) // -CALLBACK_MEMBER( 3, float, flPageScale ) // -CALLBACK_MEMBER( 4, bool , bVisible ) // -CALLBACK_MEMBER( 5, uint32, unPageSize ) // -END_DEFINE_CALLBACK_6() +STEAM_CALLBACK_BEGIN( HTML_HorizontalScroll_t, k_iSteamHTMLSurfaceCallbacks + 11 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, uint32, unScrollMax ) // +STEAM_CALLBACK_MEMBER( 2, uint32, unScrollCurrent ) // +STEAM_CALLBACK_MEMBER( 3, float, flPageScale ) // +STEAM_CALLBACK_MEMBER( 4, bool , bVisible ) // +STEAM_CALLBACK_MEMBER( 5, uint32, unPageSize ) // +STEAM_CALLBACK_END(6) //----------------------------------------------------------------------------- // Purpose: details on the visibility and size of the vertical scrollbar //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_VerticalScroll_t, k_iSteamHTMLSurfaceCallbacks + 12 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, uint32, unScrollMax ) // -CALLBACK_MEMBER( 2, uint32, unScrollCurrent ) // -CALLBACK_MEMBER( 3, float, flPageScale ) // -CALLBACK_MEMBER( 4, bool, bVisible ) // -CALLBACK_MEMBER( 5, uint32, unPageSize ) // -END_DEFINE_CALLBACK_6() +STEAM_CALLBACK_BEGIN( HTML_VerticalScroll_t, k_iSteamHTMLSurfaceCallbacks + 12 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, uint32, unScrollMax ) // +STEAM_CALLBACK_MEMBER( 2, uint32, unScrollCurrent ) // +STEAM_CALLBACK_MEMBER( 3, float, flPageScale ) // +STEAM_CALLBACK_MEMBER( 4, bool, bVisible ) // +STEAM_CALLBACK_MEMBER( 5, uint32, unPageSize ) // +STEAM_CALLBACK_END(6) //----------------------------------------------------------------------------- // Purpose: response to GetLinkAtPosition call //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_LinkAtPosition_t, k_iSteamHTMLSurfaceCallbacks + 13 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, uint32, x ) // NOTE - Not currently set -CALLBACK_MEMBER( 2, uint32, y ) // NOTE - Not currently set -CALLBACK_MEMBER( 3, const char *, pchURL ) // -CALLBACK_MEMBER( 4, bool, bInput ) // -CALLBACK_MEMBER( 5, bool, bLiveLink ) // -END_DEFINE_CALLBACK_6() +STEAM_CALLBACK_BEGIN( HTML_LinkAtPosition_t, k_iSteamHTMLSurfaceCallbacks + 13 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, uint32, x ) // NOTE - Not currently set +STEAM_CALLBACK_MEMBER( 2, uint32, y ) // NOTE - Not currently set +STEAM_CALLBACK_MEMBER( 3, const char *, pchURL ) // +STEAM_CALLBACK_MEMBER( 4, bool, bInput ) // +STEAM_CALLBACK_MEMBER( 5, bool, bLiveLink ) // +STEAM_CALLBACK_END(6) @@ -353,89 +373,104 @@ END_DEFINE_CALLBACK_6() // Purpose: show a Javascript alert dialog, call JSDialogResponse // when the user dismisses this dialog (or right away to ignore it) //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_JSAlert_t, k_iSteamHTMLSurfaceCallbacks + 14 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchMessage ) // -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_JSAlert_t, k_iSteamHTMLSurfaceCallbacks + 14 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchMessage ) // +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: show a Javascript confirmation dialog, call JSDialogResponse // when the user dismisses this dialog (or right away to ignore it) //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_JSConfirm_t, k_iSteamHTMLSurfaceCallbacks + 15 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchMessage ) // -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_JSConfirm_t, k_iSteamHTMLSurfaceCallbacks + 15 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchMessage ) // +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: when received show a file open dialog // then call FileLoadDialogResponse with the file(s) the user selected. //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_FileOpenDialog_t, k_iSteamHTMLSurfaceCallbacks + 16 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchTitle ) // -CALLBACK_MEMBER( 2, const char *, pchInitialFile ) // -END_DEFINE_CALLBACK_3() +STEAM_CALLBACK_BEGIN( HTML_FileOpenDialog_t, k_iSteamHTMLSurfaceCallbacks + 16 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchTitle ) // +STEAM_CALLBACK_MEMBER( 2, const char *, pchInitialFile ) // +STEAM_CALLBACK_END(3) //----------------------------------------------------------------------------- -// Purpose: a new html window has been created +// Purpose: a new html window is being created. +// +// IMPORTANT NOTE: at this time, the API does not allow you to acknowledge or +// render the contents of this new window, so the new window is always destroyed +// immediately. The URL and other parameters of the new window are passed here +// to give your application the opportunity to call CreateBrowser and set up +// a new browser in response to the attempted popup, if you wish to do so. //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_NewWindow_t, k_iSteamHTMLSurfaceCallbacks + 21 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the current surface -CALLBACK_MEMBER( 1, const char *, pchURL ) // the page to load -CALLBACK_MEMBER( 2, uint32, unX ) // the x pos into the page to display the popup -CALLBACK_MEMBER( 3, uint32, unY ) // the y pos into the page to display the popup -CALLBACK_MEMBER( 4, uint32, unWide ) // the total width of the pBGRA texture -CALLBACK_MEMBER( 5, uint32, unTall ) // the total height of the pBGRA texture -CALLBACK_MEMBER( 6, HHTMLBrowser, unNewWindow_BrowserHandle ) // the handle of the new window surface -END_DEFINE_CALLBACK_7() +STEAM_CALLBACK_BEGIN( HTML_NewWindow_t, k_iSteamHTMLSurfaceCallbacks + 21 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the current surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchURL ) // the page to load +STEAM_CALLBACK_MEMBER( 2, uint32, unX ) // the x pos into the page to display the popup +STEAM_CALLBACK_MEMBER( 3, uint32, unY ) // the y pos into the page to display the popup +STEAM_CALLBACK_MEMBER( 4, uint32, unWide ) // the total width of the pBGRA texture +STEAM_CALLBACK_MEMBER( 5, uint32, unTall ) // the total height of the pBGRA texture +STEAM_CALLBACK_MEMBER( 6, HHTMLBrowser, unNewWindow_BrowserHandle_IGNORE ) +STEAM_CALLBACK_END(7) //----------------------------------------------------------------------------- // Purpose: change the cursor to display //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_SetCursor_t, k_iSteamHTMLSurfaceCallbacks + 22 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, uint32, eMouseCursor ) // the EMouseCursor to display -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_SetCursor_t, k_iSteamHTMLSurfaceCallbacks + 22 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, uint32, eMouseCursor ) // the EMouseCursor to display +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: informational message from the browser //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_StatusText_t, k_iSteamHTMLSurfaceCallbacks + 23 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_StatusText_t, k_iSteamHTMLSurfaceCallbacks + 23 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: show a tooltip //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_ShowToolTip_t, k_iSteamHTMLSurfaceCallbacks + 24 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_ShowToolTip_t, k_iSteamHTMLSurfaceCallbacks + 24 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: update the text of an existing tooltip //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_UpdateToolTip_t, k_iSteamHTMLSurfaceCallbacks + 25 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display -END_DEFINE_CALLBACK_2() +STEAM_CALLBACK_BEGIN( HTML_UpdateToolTip_t, k_iSteamHTMLSurfaceCallbacks + 25 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_MEMBER( 1, const char *, pchMsg ) // the EMouseCursor to display +STEAM_CALLBACK_END(2) //----------------------------------------------------------------------------- // Purpose: hide the tooltip you are showing //----------------------------------------------------------------------------- -DEFINE_CALLBACK( HTML_HideToolTip_t, k_iSteamHTMLSurfaceCallbacks + 26 ) -CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( HTML_HideToolTip_t, k_iSteamHTMLSurfaceCallbacks + 26 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // the handle of the surface +STEAM_CALLBACK_END(1) + + +//----------------------------------------------------------------------------- +// Purpose: The browser has restarted due to an internal failure, use this new handle value +//----------------------------------------------------------------------------- +STEAM_CALLBACK_BEGIN( HTML_BrowserRestarted_t, k_iSteamHTMLSurfaceCallbacks + 27 ) +STEAM_CALLBACK_MEMBER( 0, HHTMLBrowser, unBrowserHandle ) // this is the new browser handle after the restart +STEAM_CALLBACK_MEMBER( 1, HHTMLBrowser, unOldBrowserHandle ) // the handle for the browser before the restart, if your handle was this then switch to using unBrowserHandle for API calls +STEAM_CALLBACK_END(2) #pragma pack( pop ) diff --git a/public/steam/isteamhttp.h b/public/steam/isteamhttp.h index 8fab537d..fb034ca1 100644 --- a/public/steam/isteamhttp.h +++ b/public/steam/isteamhttp.h @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" #include "steamhttpenums.h" // Handle to a HTTP Request handle @@ -128,7 +128,8 @@ class ISteamHTTP // Set the extra user agent info for a request, this doesn't clobber the normal user agent, it just adds the extra info on the end virtual bool SetHTTPRequestUserAgentInfo( HTTPRequestHandle hRequest, const char *pchUserAgentInfo ) = 0; - // Set that https request should require verified SSL certificate via machines certificate trust store + // Disable or re-enable verification of SSL/TLS certificates. + // By default, certificates are checked for all HTTPS requests. virtual bool SetHTTPRequestRequiresVerifiedCertificate( HTTPRequestHandle hRequest, bool bRequireVerifiedCertificate ) = 0; // Set an absolute timeout on the HTTP request, this is just a total time timeout different than the network activity timeout @@ -139,7 +140,15 @@ class ISteamHTTP virtual bool GetHTTPRequestWasTimedOut( HTTPRequestHandle hRequest, bool *pbWasTimedOut ) = 0; }; -#define STEAMHTTP_INTERFACE_VERSION "STEAMHTTP_INTERFACE_VERSION002" +#define STEAMHTTP_INTERFACE_VERSION "STEAMHTTP_INTERFACE_VERSION003" + +// Global interface accessor +inline ISteamHTTP *SteamHTTP(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamHTTP *, SteamHTTP, STEAMHTTP_INTERFACE_VERSION ); + +// Global accessor for the gameserver client +inline ISteamHTTP *SteamGameServerHTTP(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamHTTP *, SteamGameServerHTTP, STEAMHTTP_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -147,12 +156,12 @@ class ISteamHTTP #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif struct HTTPRequestCompleted_t { - enum { k_iCallback = k_iClientHTTPCallbacks + 1 }; + enum { k_iCallback = k_iSteamHTTPCallbacks + 1 }; // Handle value for the request that has completed. HTTPRequestHandle m_hRequest; @@ -175,7 +184,7 @@ struct HTTPRequestCompleted_t struct HTTPRequestHeadersReceived_t { - enum { k_iCallback = k_iClientHTTPCallbacks + 2 }; + enum { k_iCallback = k_iSteamHTTPCallbacks + 2 }; // Handle value for the request that has received headers. HTTPRequestHandle m_hRequest; @@ -187,7 +196,7 @@ struct HTTPRequestHeadersReceived_t struct HTTPRequestDataReceived_t { - enum { k_iCallback = k_iClientHTTPCallbacks + 3 }; + enum { k_iCallback = k_iSteamHTTPCallbacks + 3 }; // Handle value for the request that has received data. HTTPRequestHandle m_hRequest; diff --git a/public/steam/isteaminput.h b/public/steam/isteaminput.h new file mode 100644 index 00000000..e28f274d --- /dev/null +++ b/public/steam/isteaminput.h @@ -0,0 +1,962 @@ +//====== Copyright 1996-2018, Valve Corporation, All rights reserved. ======= +// +// Purpose: Steam Input is a flexible input API that supports over three hundred devices including all +// common variants of Xbox, Playstation, Nintendo Switch Pro, and Steam Controllers. +// For more info including a getting started guide for developers +// please visit: https://partner.steamgames.com/doc/features/steam_controller +// +//============================================================================= + +#ifndef ISTEAMINPUT_H +#define ISTEAMINPUT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + +#define STEAM_INPUT_MAX_COUNT 16 + +#define STEAM_INPUT_MAX_ANALOG_ACTIONS 16 + +#define STEAM_INPUT_MAX_DIGITAL_ACTIONS 128 + +#define STEAM_INPUT_MAX_ORIGINS 8 + +#define STEAM_INPUT_MAX_ACTIVE_LAYERS 16 + +// When sending an option to a specific controller handle, you can send to all devices via this command +#define STEAM_INPUT_HANDLE_ALL_CONTROLLERS UINT64_MAX + +#define STEAM_INPUT_MIN_ANALOG_ACTION_DATA -1.0f +#define STEAM_INPUT_MAX_ANALOG_ACTION_DATA 1.0f + +enum EInputSourceMode +{ + k_EInputSourceMode_None, + k_EInputSourceMode_Dpad, + k_EInputSourceMode_Buttons, + k_EInputSourceMode_FourButtons, + k_EInputSourceMode_AbsoluteMouse, + k_EInputSourceMode_RelativeMouse, + k_EInputSourceMode_JoystickMove, + k_EInputSourceMode_JoystickMouse, + k_EInputSourceMode_JoystickCamera, + k_EInputSourceMode_ScrollWheel, + k_EInputSourceMode_Trigger, + k_EInputSourceMode_TouchMenu, + k_EInputSourceMode_MouseJoystick, + k_EInputSourceMode_MouseRegion, + k_EInputSourceMode_RadialMenu, + k_EInputSourceMode_SingleButton, + k_EInputSourceMode_Switches +}; + +// Note: Please do not use action origins as a way to identify controller types. There is no +// guarantee that they will be added in a contiguous manner - use GetInputTypeForHandle instead. +// Versions of Steam that add new controller types in the future will extend this enum so if you're +// using a lookup table please check the bounds of any origins returned by Steam. +enum EInputActionOrigin +{ + // Steam Controller + k_EInputActionOrigin_None, + k_EInputActionOrigin_SteamController_A, + k_EInputActionOrigin_SteamController_B, + k_EInputActionOrigin_SteamController_X, + k_EInputActionOrigin_SteamController_Y, + k_EInputActionOrigin_SteamController_LeftBumper, + k_EInputActionOrigin_SteamController_RightBumper, + k_EInputActionOrigin_SteamController_LeftGrip, + k_EInputActionOrigin_SteamController_RightGrip, + k_EInputActionOrigin_SteamController_Start, + k_EInputActionOrigin_SteamController_Back, + k_EInputActionOrigin_SteamController_LeftPad_Touch, + k_EInputActionOrigin_SteamController_LeftPad_Swipe, + k_EInputActionOrigin_SteamController_LeftPad_Click, + k_EInputActionOrigin_SteamController_LeftPad_DPadNorth, + k_EInputActionOrigin_SteamController_LeftPad_DPadSouth, + k_EInputActionOrigin_SteamController_LeftPad_DPadWest, + k_EInputActionOrigin_SteamController_LeftPad_DPadEast, + k_EInputActionOrigin_SteamController_RightPad_Touch, + k_EInputActionOrigin_SteamController_RightPad_Swipe, + k_EInputActionOrigin_SteamController_RightPad_Click, + k_EInputActionOrigin_SteamController_RightPad_DPadNorth, + k_EInputActionOrigin_SteamController_RightPad_DPadSouth, + k_EInputActionOrigin_SteamController_RightPad_DPadWest, + k_EInputActionOrigin_SteamController_RightPad_DPadEast, + k_EInputActionOrigin_SteamController_LeftTrigger_Pull, + k_EInputActionOrigin_SteamController_LeftTrigger_Click, + k_EInputActionOrigin_SteamController_RightTrigger_Pull, + k_EInputActionOrigin_SteamController_RightTrigger_Click, + k_EInputActionOrigin_SteamController_LeftStick_Move, + k_EInputActionOrigin_SteamController_LeftStick_Click, + k_EInputActionOrigin_SteamController_LeftStick_DPadNorth, + k_EInputActionOrigin_SteamController_LeftStick_DPadSouth, + k_EInputActionOrigin_SteamController_LeftStick_DPadWest, + k_EInputActionOrigin_SteamController_LeftStick_DPadEast, + k_EInputActionOrigin_SteamController_Gyro_Move, + k_EInputActionOrigin_SteamController_Gyro_Pitch, + k_EInputActionOrigin_SteamController_Gyro_Yaw, + k_EInputActionOrigin_SteamController_Gyro_Roll, + k_EInputActionOrigin_SteamController_Reserved0, + k_EInputActionOrigin_SteamController_Reserved1, + k_EInputActionOrigin_SteamController_Reserved2, + k_EInputActionOrigin_SteamController_Reserved3, + k_EInputActionOrigin_SteamController_Reserved4, + k_EInputActionOrigin_SteamController_Reserved5, + k_EInputActionOrigin_SteamController_Reserved6, + k_EInputActionOrigin_SteamController_Reserved7, + k_EInputActionOrigin_SteamController_Reserved8, + k_EInputActionOrigin_SteamController_Reserved9, + k_EInputActionOrigin_SteamController_Reserved10, + + // PS4 Dual Shock + k_EInputActionOrigin_PS4_X, + k_EInputActionOrigin_PS4_Circle, + k_EInputActionOrigin_PS4_Triangle, + k_EInputActionOrigin_PS4_Square, + k_EInputActionOrigin_PS4_LeftBumper, + k_EInputActionOrigin_PS4_RightBumper, + k_EInputActionOrigin_PS4_Options, //Start + k_EInputActionOrigin_PS4_Share, //Back + k_EInputActionOrigin_PS4_LeftPad_Touch, + k_EInputActionOrigin_PS4_LeftPad_Swipe, + k_EInputActionOrigin_PS4_LeftPad_Click, + k_EInputActionOrigin_PS4_LeftPad_DPadNorth, + k_EInputActionOrigin_PS4_LeftPad_DPadSouth, + k_EInputActionOrigin_PS4_LeftPad_DPadWest, + k_EInputActionOrigin_PS4_LeftPad_DPadEast, + k_EInputActionOrigin_PS4_RightPad_Touch, + k_EInputActionOrigin_PS4_RightPad_Swipe, + k_EInputActionOrigin_PS4_RightPad_Click, + k_EInputActionOrigin_PS4_RightPad_DPadNorth, + k_EInputActionOrigin_PS4_RightPad_DPadSouth, + k_EInputActionOrigin_PS4_RightPad_DPadWest, + k_EInputActionOrigin_PS4_RightPad_DPadEast, + k_EInputActionOrigin_PS4_CenterPad_Touch, + k_EInputActionOrigin_PS4_CenterPad_Swipe, + k_EInputActionOrigin_PS4_CenterPad_Click, + k_EInputActionOrigin_PS4_CenterPad_DPadNorth, + k_EInputActionOrigin_PS4_CenterPad_DPadSouth, + k_EInputActionOrigin_PS4_CenterPad_DPadWest, + k_EInputActionOrigin_PS4_CenterPad_DPadEast, + k_EInputActionOrigin_PS4_LeftTrigger_Pull, + k_EInputActionOrigin_PS4_LeftTrigger_Click, + k_EInputActionOrigin_PS4_RightTrigger_Pull, + k_EInputActionOrigin_PS4_RightTrigger_Click, + k_EInputActionOrigin_PS4_LeftStick_Move, + k_EInputActionOrigin_PS4_LeftStick_Click, + k_EInputActionOrigin_PS4_LeftStick_DPadNorth, + k_EInputActionOrigin_PS4_LeftStick_DPadSouth, + k_EInputActionOrigin_PS4_LeftStick_DPadWest, + k_EInputActionOrigin_PS4_LeftStick_DPadEast, + k_EInputActionOrigin_PS4_RightStick_Move, + k_EInputActionOrigin_PS4_RightStick_Click, + k_EInputActionOrigin_PS4_RightStick_DPadNorth, + k_EInputActionOrigin_PS4_RightStick_DPadSouth, + k_EInputActionOrigin_PS4_RightStick_DPadWest, + k_EInputActionOrigin_PS4_RightStick_DPadEast, + k_EInputActionOrigin_PS4_DPad_North, + k_EInputActionOrigin_PS4_DPad_South, + k_EInputActionOrigin_PS4_DPad_West, + k_EInputActionOrigin_PS4_DPad_East, + k_EInputActionOrigin_PS4_Gyro_Move, + k_EInputActionOrigin_PS4_Gyro_Pitch, + k_EInputActionOrigin_PS4_Gyro_Yaw, + k_EInputActionOrigin_PS4_Gyro_Roll, + k_EInputActionOrigin_PS4_DPad_Move, + k_EInputActionOrigin_PS4_Reserved1, + k_EInputActionOrigin_PS4_Reserved2, + k_EInputActionOrigin_PS4_Reserved3, + k_EInputActionOrigin_PS4_Reserved4, + k_EInputActionOrigin_PS4_Reserved5, + k_EInputActionOrigin_PS4_Reserved6, + k_EInputActionOrigin_PS4_Reserved7, + k_EInputActionOrigin_PS4_Reserved8, + k_EInputActionOrigin_PS4_Reserved9, + k_EInputActionOrigin_PS4_Reserved10, + + // XBox One + k_EInputActionOrigin_XBoxOne_A, + k_EInputActionOrigin_XBoxOne_B, + k_EInputActionOrigin_XBoxOne_X, + k_EInputActionOrigin_XBoxOne_Y, + k_EInputActionOrigin_XBoxOne_LeftBumper, + k_EInputActionOrigin_XBoxOne_RightBumper, + k_EInputActionOrigin_XBoxOne_Menu, //Start + k_EInputActionOrigin_XBoxOne_View, //Back + k_EInputActionOrigin_XBoxOne_LeftTrigger_Pull, + k_EInputActionOrigin_XBoxOne_LeftTrigger_Click, + k_EInputActionOrigin_XBoxOne_RightTrigger_Pull, + k_EInputActionOrigin_XBoxOne_RightTrigger_Click, + k_EInputActionOrigin_XBoxOne_LeftStick_Move, + k_EInputActionOrigin_XBoxOne_LeftStick_Click, + k_EInputActionOrigin_XBoxOne_LeftStick_DPadNorth, + k_EInputActionOrigin_XBoxOne_LeftStick_DPadSouth, + k_EInputActionOrigin_XBoxOne_LeftStick_DPadWest, + k_EInputActionOrigin_XBoxOne_LeftStick_DPadEast, + k_EInputActionOrigin_XBoxOne_RightStick_Move, + k_EInputActionOrigin_XBoxOne_RightStick_Click, + k_EInputActionOrigin_XBoxOne_RightStick_DPadNorth, + k_EInputActionOrigin_XBoxOne_RightStick_DPadSouth, + k_EInputActionOrigin_XBoxOne_RightStick_DPadWest, + k_EInputActionOrigin_XBoxOne_RightStick_DPadEast, + k_EInputActionOrigin_XBoxOne_DPad_North, + k_EInputActionOrigin_XBoxOne_DPad_South, + k_EInputActionOrigin_XBoxOne_DPad_West, + k_EInputActionOrigin_XBoxOne_DPad_East, + k_EInputActionOrigin_XBoxOne_DPad_Move, + k_EInputActionOrigin_XBoxOne_LeftGrip_Lower, + k_EInputActionOrigin_XBoxOne_LeftGrip_Upper, + k_EInputActionOrigin_XBoxOne_RightGrip_Lower, + k_EInputActionOrigin_XBoxOne_RightGrip_Upper, + k_EInputActionOrigin_XBoxOne_Share, // Xbox Series X controllers only + k_EInputActionOrigin_XBoxOne_Reserved6, + k_EInputActionOrigin_XBoxOne_Reserved7, + k_EInputActionOrigin_XBoxOne_Reserved8, + k_EInputActionOrigin_XBoxOne_Reserved9, + k_EInputActionOrigin_XBoxOne_Reserved10, + + // XBox 360 + k_EInputActionOrigin_XBox360_A, + k_EInputActionOrigin_XBox360_B, + k_EInputActionOrigin_XBox360_X, + k_EInputActionOrigin_XBox360_Y, + k_EInputActionOrigin_XBox360_LeftBumper, + k_EInputActionOrigin_XBox360_RightBumper, + k_EInputActionOrigin_XBox360_Start, //Start + k_EInputActionOrigin_XBox360_Back, //Back + k_EInputActionOrigin_XBox360_LeftTrigger_Pull, + k_EInputActionOrigin_XBox360_LeftTrigger_Click, + k_EInputActionOrigin_XBox360_RightTrigger_Pull, + k_EInputActionOrigin_XBox360_RightTrigger_Click, + k_EInputActionOrigin_XBox360_LeftStick_Move, + k_EInputActionOrigin_XBox360_LeftStick_Click, + k_EInputActionOrigin_XBox360_LeftStick_DPadNorth, + k_EInputActionOrigin_XBox360_LeftStick_DPadSouth, + k_EInputActionOrigin_XBox360_LeftStick_DPadWest, + k_EInputActionOrigin_XBox360_LeftStick_DPadEast, + k_EInputActionOrigin_XBox360_RightStick_Move, + k_EInputActionOrigin_XBox360_RightStick_Click, + k_EInputActionOrigin_XBox360_RightStick_DPadNorth, + k_EInputActionOrigin_XBox360_RightStick_DPadSouth, + k_EInputActionOrigin_XBox360_RightStick_DPadWest, + k_EInputActionOrigin_XBox360_RightStick_DPadEast, + k_EInputActionOrigin_XBox360_DPad_North, + k_EInputActionOrigin_XBox360_DPad_South, + k_EInputActionOrigin_XBox360_DPad_West, + k_EInputActionOrigin_XBox360_DPad_East, + k_EInputActionOrigin_XBox360_DPad_Move, + k_EInputActionOrigin_XBox360_Reserved1, + k_EInputActionOrigin_XBox360_Reserved2, + k_EInputActionOrigin_XBox360_Reserved3, + k_EInputActionOrigin_XBox360_Reserved4, + k_EInputActionOrigin_XBox360_Reserved5, + k_EInputActionOrigin_XBox360_Reserved6, + k_EInputActionOrigin_XBox360_Reserved7, + k_EInputActionOrigin_XBox360_Reserved8, + k_EInputActionOrigin_XBox360_Reserved9, + k_EInputActionOrigin_XBox360_Reserved10, + + + // Switch - Pro or Joycons used as a single input device. + // This does not apply to a single joycon + k_EInputActionOrigin_Switch_A, + k_EInputActionOrigin_Switch_B, + k_EInputActionOrigin_Switch_X, + k_EInputActionOrigin_Switch_Y, + k_EInputActionOrigin_Switch_LeftBumper, + k_EInputActionOrigin_Switch_RightBumper, + k_EInputActionOrigin_Switch_Plus, //Start + k_EInputActionOrigin_Switch_Minus, //Back + k_EInputActionOrigin_Switch_Capture, + k_EInputActionOrigin_Switch_LeftTrigger_Pull, + k_EInputActionOrigin_Switch_LeftTrigger_Click, + k_EInputActionOrigin_Switch_RightTrigger_Pull, + k_EInputActionOrigin_Switch_RightTrigger_Click, + k_EInputActionOrigin_Switch_LeftStick_Move, + k_EInputActionOrigin_Switch_LeftStick_Click, + k_EInputActionOrigin_Switch_LeftStick_DPadNorth, + k_EInputActionOrigin_Switch_LeftStick_DPadSouth, + k_EInputActionOrigin_Switch_LeftStick_DPadWest, + k_EInputActionOrigin_Switch_LeftStick_DPadEast, + k_EInputActionOrigin_Switch_RightStick_Move, + k_EInputActionOrigin_Switch_RightStick_Click, + k_EInputActionOrigin_Switch_RightStick_DPadNorth, + k_EInputActionOrigin_Switch_RightStick_DPadSouth, + k_EInputActionOrigin_Switch_RightStick_DPadWest, + k_EInputActionOrigin_Switch_RightStick_DPadEast, + k_EInputActionOrigin_Switch_DPad_North, + k_EInputActionOrigin_Switch_DPad_South, + k_EInputActionOrigin_Switch_DPad_West, + k_EInputActionOrigin_Switch_DPad_East, + k_EInputActionOrigin_Switch_ProGyro_Move, // Primary Gyro in Pro Controller, or Right JoyCon + k_EInputActionOrigin_Switch_ProGyro_Pitch, // Primary Gyro in Pro Controller, or Right JoyCon + k_EInputActionOrigin_Switch_ProGyro_Yaw, // Primary Gyro in Pro Controller, or Right JoyCon + k_EInputActionOrigin_Switch_ProGyro_Roll, // Primary Gyro in Pro Controller, or Right JoyCon + k_EInputActionOrigin_Switch_DPad_Move, + k_EInputActionOrigin_Switch_Reserved1, + k_EInputActionOrigin_Switch_Reserved2, + k_EInputActionOrigin_Switch_Reserved3, + k_EInputActionOrigin_Switch_Reserved4, + k_EInputActionOrigin_Switch_Reserved5, + k_EInputActionOrigin_Switch_Reserved6, + k_EInputActionOrigin_Switch_Reserved7, + k_EInputActionOrigin_Switch_Reserved8, + k_EInputActionOrigin_Switch_Reserved9, + k_EInputActionOrigin_Switch_Reserved10, + + // Switch JoyCon Specific + k_EInputActionOrigin_Switch_RightGyro_Move, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EInputActionOrigin_Switch_RightGyro_Pitch, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EInputActionOrigin_Switch_RightGyro_Yaw, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EInputActionOrigin_Switch_RightGyro_Roll, // Right JoyCon Gyro generally should correspond to Pro's single gyro + k_EInputActionOrigin_Switch_LeftGyro_Move, + k_EInputActionOrigin_Switch_LeftGyro_Pitch, + k_EInputActionOrigin_Switch_LeftGyro_Yaw, + k_EInputActionOrigin_Switch_LeftGyro_Roll, + k_EInputActionOrigin_Switch_LeftGrip_Lower, // Left JoyCon SR Button + k_EInputActionOrigin_Switch_LeftGrip_Upper, // Left JoyCon SL Button + k_EInputActionOrigin_Switch_RightGrip_Lower, // Right JoyCon SL Button + k_EInputActionOrigin_Switch_RightGrip_Upper, // Right JoyCon SR Button + k_EInputActionOrigin_Switch_Reserved11, + k_EInputActionOrigin_Switch_Reserved12, + k_EInputActionOrigin_Switch_Reserved13, + k_EInputActionOrigin_Switch_Reserved14, + k_EInputActionOrigin_Switch_Reserved15, + k_EInputActionOrigin_Switch_Reserved16, + k_EInputActionOrigin_Switch_Reserved17, + k_EInputActionOrigin_Switch_Reserved18, + k_EInputActionOrigin_Switch_Reserved19, + k_EInputActionOrigin_Switch_Reserved20, + + // Added in SDK 1.51 + k_EInputActionOrigin_PS5_X, + k_EInputActionOrigin_PS5_Circle, + k_EInputActionOrigin_PS5_Triangle, + k_EInputActionOrigin_PS5_Square, + k_EInputActionOrigin_PS5_LeftBumper, + k_EInputActionOrigin_PS5_RightBumper, + k_EInputActionOrigin_PS5_Option, //Start + k_EInputActionOrigin_PS5_Create, //Back + k_EInputActionOrigin_PS5_Mute, + k_EInputActionOrigin_PS5_LeftPad_Touch, + k_EInputActionOrigin_PS5_LeftPad_Swipe, + k_EInputActionOrigin_PS5_LeftPad_Click, + k_EInputActionOrigin_PS5_LeftPad_DPadNorth, + k_EInputActionOrigin_PS5_LeftPad_DPadSouth, + k_EInputActionOrigin_PS5_LeftPad_DPadWest, + k_EInputActionOrigin_PS5_LeftPad_DPadEast, + k_EInputActionOrigin_PS5_RightPad_Touch, + k_EInputActionOrigin_PS5_RightPad_Swipe, + k_EInputActionOrigin_PS5_RightPad_Click, + k_EInputActionOrigin_PS5_RightPad_DPadNorth, + k_EInputActionOrigin_PS5_RightPad_DPadSouth, + k_EInputActionOrigin_PS5_RightPad_DPadWest, + k_EInputActionOrigin_PS5_RightPad_DPadEast, + k_EInputActionOrigin_PS5_CenterPad_Touch, + k_EInputActionOrigin_PS5_CenterPad_Swipe, + k_EInputActionOrigin_PS5_CenterPad_Click, + k_EInputActionOrigin_PS5_CenterPad_DPadNorth, + k_EInputActionOrigin_PS5_CenterPad_DPadSouth, + k_EInputActionOrigin_PS5_CenterPad_DPadWest, + k_EInputActionOrigin_PS5_CenterPad_DPadEast, + k_EInputActionOrigin_PS5_LeftTrigger_Pull, + k_EInputActionOrigin_PS5_LeftTrigger_Click, + k_EInputActionOrigin_PS5_RightTrigger_Pull, + k_EInputActionOrigin_PS5_RightTrigger_Click, + k_EInputActionOrigin_PS5_LeftStick_Move, + k_EInputActionOrigin_PS5_LeftStick_Click, + k_EInputActionOrigin_PS5_LeftStick_DPadNorth, + k_EInputActionOrigin_PS5_LeftStick_DPadSouth, + k_EInputActionOrigin_PS5_LeftStick_DPadWest, + k_EInputActionOrigin_PS5_LeftStick_DPadEast, + k_EInputActionOrigin_PS5_RightStick_Move, + k_EInputActionOrigin_PS5_RightStick_Click, + k_EInputActionOrigin_PS5_RightStick_DPadNorth, + k_EInputActionOrigin_PS5_RightStick_DPadSouth, + k_EInputActionOrigin_PS5_RightStick_DPadWest, + k_EInputActionOrigin_PS5_RightStick_DPadEast, + k_EInputActionOrigin_PS5_DPad_North, + k_EInputActionOrigin_PS5_DPad_South, + k_EInputActionOrigin_PS5_DPad_West, + k_EInputActionOrigin_PS5_DPad_East, + k_EInputActionOrigin_PS5_Gyro_Move, + k_EInputActionOrigin_PS5_Gyro_Pitch, + k_EInputActionOrigin_PS5_Gyro_Yaw, + k_EInputActionOrigin_PS5_Gyro_Roll, + k_EInputActionOrigin_PS5_DPad_Move, + k_EInputActionOrigin_PS5_Reserved1, + k_EInputActionOrigin_PS5_Reserved2, + k_EInputActionOrigin_PS5_Reserved3, + k_EInputActionOrigin_PS5_Reserved4, + k_EInputActionOrigin_PS5_Reserved5, + k_EInputActionOrigin_PS5_Reserved6, + k_EInputActionOrigin_PS5_Reserved7, + k_EInputActionOrigin_PS5_Reserved8, + k_EInputActionOrigin_PS5_Reserved9, + k_EInputActionOrigin_PS5_Reserved10, + k_EInputActionOrigin_PS5_Reserved11, + k_EInputActionOrigin_PS5_Reserved12, + k_EInputActionOrigin_PS5_Reserved13, + k_EInputActionOrigin_PS5_Reserved14, + k_EInputActionOrigin_PS5_Reserved15, + k_EInputActionOrigin_PS5_Reserved16, + k_EInputActionOrigin_PS5_Reserved17, + k_EInputActionOrigin_PS5_Reserved18, + k_EInputActionOrigin_PS5_Reserved19, + k_EInputActionOrigin_PS5_Reserved20, + + // Added in SDK 1.53 + k_EInputActionOrigin_SteamDeck_A, + k_EInputActionOrigin_SteamDeck_B, + k_EInputActionOrigin_SteamDeck_X, + k_EInputActionOrigin_SteamDeck_Y, + k_EInputActionOrigin_SteamDeck_L1, + k_EInputActionOrigin_SteamDeck_R1, + k_EInputActionOrigin_SteamDeck_Menu, + k_EInputActionOrigin_SteamDeck_View, + k_EInputActionOrigin_SteamDeck_LeftPad_Touch, + k_EInputActionOrigin_SteamDeck_LeftPad_Swipe, + k_EInputActionOrigin_SteamDeck_LeftPad_Click, + k_EInputActionOrigin_SteamDeck_LeftPad_DPadNorth, + k_EInputActionOrigin_SteamDeck_LeftPad_DPadSouth, + k_EInputActionOrigin_SteamDeck_LeftPad_DPadWest, + k_EInputActionOrigin_SteamDeck_LeftPad_DPadEast, + k_EInputActionOrigin_SteamDeck_RightPad_Touch, + k_EInputActionOrigin_SteamDeck_RightPad_Swipe, + k_EInputActionOrigin_SteamDeck_RightPad_Click, + k_EInputActionOrigin_SteamDeck_RightPad_DPadNorth, + k_EInputActionOrigin_SteamDeck_RightPad_DPadSouth, + k_EInputActionOrigin_SteamDeck_RightPad_DPadWest, + k_EInputActionOrigin_SteamDeck_RightPad_DPadEast, + k_EInputActionOrigin_SteamDeck_L2_SoftPull, + k_EInputActionOrigin_SteamDeck_L2, + k_EInputActionOrigin_SteamDeck_R2_SoftPull, + k_EInputActionOrigin_SteamDeck_R2, + k_EInputActionOrigin_SteamDeck_LeftStick_Move, + k_EInputActionOrigin_SteamDeck_L3, + k_EInputActionOrigin_SteamDeck_LeftStick_DPadNorth, + k_EInputActionOrigin_SteamDeck_LeftStick_DPadSouth, + k_EInputActionOrigin_SteamDeck_LeftStick_DPadWest, + k_EInputActionOrigin_SteamDeck_LeftStick_DPadEast, + k_EInputActionOrigin_SteamDeck_LeftStick_Touch, + k_EInputActionOrigin_SteamDeck_RightStick_Move, + k_EInputActionOrigin_SteamDeck_R3, + k_EInputActionOrigin_SteamDeck_RightStick_DPadNorth, + k_EInputActionOrigin_SteamDeck_RightStick_DPadSouth, + k_EInputActionOrigin_SteamDeck_RightStick_DPadWest, + k_EInputActionOrigin_SteamDeck_RightStick_DPadEast, + k_EInputActionOrigin_SteamDeck_RightStick_Touch, + k_EInputActionOrigin_SteamDeck_L4, + k_EInputActionOrigin_SteamDeck_R4, + k_EInputActionOrigin_SteamDeck_L5, + k_EInputActionOrigin_SteamDeck_R5, + k_EInputActionOrigin_SteamDeck_DPad_Move, + k_EInputActionOrigin_SteamDeck_DPad_North, + k_EInputActionOrigin_SteamDeck_DPad_South, + k_EInputActionOrigin_SteamDeck_DPad_West, + k_EInputActionOrigin_SteamDeck_DPad_East, + k_EInputActionOrigin_SteamDeck_Gyro_Move, + k_EInputActionOrigin_SteamDeck_Gyro_Pitch, + k_EInputActionOrigin_SteamDeck_Gyro_Yaw, + k_EInputActionOrigin_SteamDeck_Gyro_Roll, + k_EInputActionOrigin_SteamDeck_Reserved1, + k_EInputActionOrigin_SteamDeck_Reserved2, + k_EInputActionOrigin_SteamDeck_Reserved3, + k_EInputActionOrigin_SteamDeck_Reserved4, + k_EInputActionOrigin_SteamDeck_Reserved5, + k_EInputActionOrigin_SteamDeck_Reserved6, + k_EInputActionOrigin_SteamDeck_Reserved7, + k_EInputActionOrigin_SteamDeck_Reserved8, + k_EInputActionOrigin_SteamDeck_Reserved9, + k_EInputActionOrigin_SteamDeck_Reserved10, + k_EInputActionOrigin_SteamDeck_Reserved11, + k_EInputActionOrigin_SteamDeck_Reserved12, + k_EInputActionOrigin_SteamDeck_Reserved13, + k_EInputActionOrigin_SteamDeck_Reserved14, + k_EInputActionOrigin_SteamDeck_Reserved15, + k_EInputActionOrigin_SteamDeck_Reserved16, + k_EInputActionOrigin_SteamDeck_Reserved17, + k_EInputActionOrigin_SteamDeck_Reserved18, + k_EInputActionOrigin_SteamDeck_Reserved19, + k_EInputActionOrigin_SteamDeck_Reserved20, + + k_EInputActionOrigin_Count, // If Steam has added support for new controllers origins will go here. + k_EInputActionOrigin_MaximumPossibleValue = 32767, // Origins are currently a maximum of 16 bits. +}; + +enum EXboxOrigin +{ + k_EXboxOrigin_A, + k_EXboxOrigin_B, + k_EXboxOrigin_X, + k_EXboxOrigin_Y, + k_EXboxOrigin_LeftBumper, + k_EXboxOrigin_RightBumper, + k_EXboxOrigin_Menu, //Start + k_EXboxOrigin_View, //Back + k_EXboxOrigin_LeftTrigger_Pull, + k_EXboxOrigin_LeftTrigger_Click, + k_EXboxOrigin_RightTrigger_Pull, + k_EXboxOrigin_RightTrigger_Click, + k_EXboxOrigin_LeftStick_Move, + k_EXboxOrigin_LeftStick_Click, + k_EXboxOrigin_LeftStick_DPadNorth, + k_EXboxOrigin_LeftStick_DPadSouth, + k_EXboxOrigin_LeftStick_DPadWest, + k_EXboxOrigin_LeftStick_DPadEast, + k_EXboxOrigin_RightStick_Move, + k_EXboxOrigin_RightStick_Click, + k_EXboxOrigin_RightStick_DPadNorth, + k_EXboxOrigin_RightStick_DPadSouth, + k_EXboxOrigin_RightStick_DPadWest, + k_EXboxOrigin_RightStick_DPadEast, + k_EXboxOrigin_DPad_North, + k_EXboxOrigin_DPad_South, + k_EXboxOrigin_DPad_West, + k_EXboxOrigin_DPad_East, + k_EXboxOrigin_Count, +}; + +enum ESteamControllerPad +{ + k_ESteamControllerPad_Left, + k_ESteamControllerPad_Right +}; + +enum EControllerHapticLocation +{ + k_EControllerHapticLocation_Left = ( 1 << k_ESteamControllerPad_Left ), + k_EControllerHapticLocation_Right = ( 1 << k_ESteamControllerPad_Right ), + k_EControllerHapticLocation_Both = ( 1 << k_ESteamControllerPad_Left | 1 << k_ESteamControllerPad_Right ), +}; + +enum EControllerHapticType +{ + k_EControllerHapticType_Off, + k_EControllerHapticType_Tick, + k_EControllerHapticType_Click, +}; + +enum ESteamInputType +{ + k_ESteamInputType_Unknown, + k_ESteamInputType_SteamController, + k_ESteamInputType_XBox360Controller, + k_ESteamInputType_XBoxOneController, + k_ESteamInputType_GenericGamepad, // DirectInput controllers + k_ESteamInputType_PS4Controller, + k_ESteamInputType_AppleMFiController, // Unused + k_ESteamInputType_AndroidController, // Unused + k_ESteamInputType_SwitchJoyConPair, // Unused + k_ESteamInputType_SwitchJoyConSingle, // Unused + k_ESteamInputType_SwitchProController, + k_ESteamInputType_MobileTouch, // Steam Link App On-screen Virtual Controller + k_ESteamInputType_PS3Controller, // Currently uses PS4 Origins + k_ESteamInputType_PS5Controller, // Added in SDK 151 + k_ESteamInputType_SteamDeckController, // Added in SDK 153 + k_ESteamInputType_Count, + k_ESteamInputType_MaximumPossibleValue = 255, +}; + +// Individual values are used by the GetSessionInputConfigurationSettings bitmask +enum ESteamInputConfigurationEnableType +{ + k_ESteamInputConfigurationEnableType_None = 0x0000, + k_ESteamInputConfigurationEnableType_Playstation = 0x0001, + k_ESteamInputConfigurationEnableType_Xbox = 0x0002, + k_ESteamInputConfigurationEnableType_Generic = 0x0004, + k_ESteamInputConfigurationEnableType_Switch = 0x0008, +}; + +// These values are passed into SetLEDColor +enum ESteamInputLEDFlag +{ + k_ESteamInputLEDFlag_SetColor, + // Restore the LED color to the user's preference setting as set in the controller personalization menu. + // This also happens automatically on exit of your game. + k_ESteamInputLEDFlag_RestoreUserDefault +}; + +// These values are passed into GetGlyphPNGForActionOrigin +enum ESteamInputGlyphSize +{ + k_ESteamInputGlyphSize_Small, // 32x32 pixels + k_ESteamInputGlyphSize_Medium, // 128x128 pixels + k_ESteamInputGlyphSize_Large, // 256x256 pixels + k_ESteamInputGlyphSize_Count, +}; + +enum ESteamInputGlyphStyle +{ + // Base-styles - cannot mix + ESteamInputGlyphStyle_Knockout = 0x0, // Face buttons will have colored labels/outlines on a knocked out background + // Rest of inputs will have white detail/borders on a knocked out background + ESteamInputGlyphStyle_Light = 0x1, // Black detail/borders on a white background + ESteamInputGlyphStyle_Dark = 0x2, // White detail/borders on a black background + + // Modifiers + // Default ABXY/PS equivalent glyphs have a solid fill w/ color matching the physical buttons on the device + ESteamInputGlyphStyle_NeutralColorABXY = 0x10, // ABXY Buttons will match the base style color instead of their normal associated color + ESteamInputGlyphStyle_SolidABXY = 0x20, // ABXY Buttons will have a solid fill +}; + +enum ESteamInputActionEventType +{ + ESteamInputActionEventType_DigitalAction, + ESteamInputActionEventType_AnalogAction, +}; + +// InputHandle_t is used to refer to a specific controller. +// This handle will consistently identify a controller, even if it is disconnected and re-connected +typedef uint64 InputHandle_t; + +// These handles are used to refer to a specific in-game action or action set +// All action handles should be queried during initialization for performance reasons +typedef uint64 InputActionSetHandle_t; +typedef uint64 InputDigitalActionHandle_t; +typedef uint64 InputAnalogActionHandle_t; + +#pragma pack( push, 1 ) + +struct InputAnalogActionData_t +{ + // Type of data coming from this action, this will match what got specified in the action set + EInputSourceMode eMode; + + // The current state of this action; will be delta updates for mouse actions + float x, y; + + // Whether or not this action is currently available to be bound in the active action set + bool bActive; +}; + +struct InputDigitalActionData_t +{ + // The current state of this action; will be true if currently pressed + bool bState; + + // Whether or not this action is currently available to be bound in the active action set + bool bActive; +}; + +struct InputMotionData_t +{ + // Sensor-fused absolute rotation; will drift in heading + float rotQuatX; + float rotQuatY; + float rotQuatZ; + float rotQuatW; + + // Positional acceleration + float posAccelX; + float posAccelY; + float posAccelZ; + + // Angular velocity + float rotVelX; + float rotVelY; + float rotVelZ; +}; + +//----------------------------------------------------------------------------- +// Purpose: when callbacks are enabled this fires each time a controller action +// state changes +//----------------------------------------------------------------------------- +struct SteamInputActionEvent_t +{ + InputHandle_t controllerHandle; + ESteamInputActionEventType eEventType; + struct AnalogAction_t { + InputAnalogActionHandle_t actionHandle; + InputAnalogActionData_t analogActionData; + }; + struct DigitalAction_t { + InputDigitalActionHandle_t actionHandle; + InputDigitalActionData_t digitalActionData; + }; + union { + AnalogAction_t analogAction; + DigitalAction_t digitalAction; + }; +}; + +//----------------------------------------------------------------------------- +// Forward declaration for ScePadTriggerEffectParam, defined in isteamdualsense.h +//----------------------------------------------------------------------------- +struct ScePadTriggerEffectParam; + +#pragma pack( pop ) + +typedef void ( *SteamInputActionEventCallbackPointer )( SteamInputActionEvent_t * ); + +//----------------------------------------------------------------------------- +// Purpose: Steam Input API +//----------------------------------------------------------------------------- +class ISteamInput +{ +public: + + // Init and Shutdown must be called when starting/ending use of this interface. + // if bExplicitlyCallRunFrame is called then you will need to manually call RunFrame + // each frame, otherwise Steam Input will updated when SteamAPI_RunCallbacks() is called + virtual bool Init( bool bExplicitlyCallRunFrame ) = 0; + virtual bool Shutdown() = 0; + + // Set the absolute path to the Input Action Manifest file containing the in-game actions + // and file paths to the official configurations. Used in games that bundle Steam Input + // configurations inside of the game depot instead of using the Steam Workshop + virtual bool SetInputActionManifestFilePath( const char *pchInputActionManifestAbsolutePath ) = 0; + + // Synchronize API state with the latest Steam Input action data available. This + // is performed automatically by SteamAPI_RunCallbacks, but for the absolute lowest + // possible latency, you call this directly before reading controller state. + // Note: This must be called from somewhere before GetConnectedControllers will + // return any handles + virtual void RunFrame( bool bReservedValue = true ) = 0; + + // Waits on an IPC event from Steam sent when there is new data to be fetched from + // the data drop. Returns true when data was recievied before the timeout expires. + // Useful for games with a dedicated input thread + virtual bool BWaitForData( bool bWaitForever, uint32 unTimeout ) = 0; + + // Returns true if new data has been received since the last time action data was accessed + // via GetDigitalActionData or GetAnalogActionData. The game will still need to call + // SteamInput()->RunFrame() or SteamAPI_RunCallbacks() before this to update the data stream + virtual bool BNewDataAvailable() = 0; + + // Enumerate currently connected Steam Input enabled devices - developers can opt in controller by type (ex: Xbox/Playstation/etc) via + // the Steam Input settings in the Steamworks site or users can opt-in in their controller settings in Steam. + // handlesOut should point to a STEAM_INPUT_MAX_COUNT sized array of InputHandle_t handles + // Returns the number of handles written to handlesOut + virtual int GetConnectedControllers( STEAM_OUT_ARRAY_COUNT( STEAM_INPUT_MAX_COUNT, Receives list of connected controllers ) InputHandle_t *handlesOut ) = 0; + + //----------------------------------------------------------------------------- + // CALLBACKS + //----------------------------------------------------------------------------- + + // Controller configuration loaded - these callbacks will always fire if you have + // a handler. Note: this is called within either SteamInput()->RunFrame or by SteamAPI_RunCallbacks + STEAM_CALL_BACK( SteamInputConfigurationLoaded_t ) + + // Enable SteamInputDeviceConnected_t and SteamInputDeviceDisconnected_t callbacks. + // Each controller that is already connected will generate a device connected + // callback when you enable them + virtual void EnableDeviceCallbacks() = 0; + + // Controller Connected - provides info about a single newly connected controller + // Note: this is called within either SteamInput()->RunFrame or by SteamAPI_RunCallbacks + STEAM_CALL_BACK( SteamInputDeviceConnected_t ) + + // Controller Disconnected - provides info about a single disconnected controller + // Note: this is called within either SteamInput()->RunFrame or by SteamAPI_RunCallbacks + STEAM_CALL_BACK( SteamInputDeviceDisconnected_t ) + + // Enable SteamInputActionEvent_t callbacks. Directly calls your callback function + // for lower latency than standard Steam callbacks. Supports one callback at a time. + // Note: this is called within either SteamInput()->RunFrame or by SteamAPI_RunCallbacks + virtual void EnableActionEventCallbacks( SteamInputActionEventCallbackPointer pCallback ) = 0; + + //----------------------------------------------------------------------------- + // ACTION SETS + //----------------------------------------------------------------------------- + + // Lookup the handle for an Action Set. Best to do this once on startup, and store the handles for all future API calls. + virtual InputActionSetHandle_t GetActionSetHandle( const char *pszActionSetName ) = 0; + + // Reconfigure the controller to use the specified action set (ie 'Menu', 'Walk' or 'Drive') + // This is cheap, and can be safely called repeatedly. It's often easier to repeatedly call it in + // your state loops, instead of trying to place it in all of your state transitions. + virtual void ActivateActionSet( InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle ) = 0; + virtual InputActionSetHandle_t GetCurrentActionSet( InputHandle_t inputHandle ) = 0; + + // ACTION SET LAYERS + virtual void ActivateActionSetLayer( InputHandle_t inputHandle, InputActionSetHandle_t actionSetLayerHandle ) = 0; + virtual void DeactivateActionSetLayer( InputHandle_t inputHandle, InputActionSetHandle_t actionSetLayerHandle ) = 0; + virtual void DeactivateAllActionSetLayers( InputHandle_t inputHandle ) = 0; + + // Enumerate currently active layers. + // handlesOut should point to a STEAM_INPUT_MAX_ACTIVE_LAYERS sized array of InputActionSetHandle_t handles + // Returns the number of handles written to handlesOut + virtual int GetActiveActionSetLayers( InputHandle_t inputHandle, STEAM_OUT_ARRAY_COUNT( STEAM_INPUT_MAX_ACTIVE_LAYERS, Receives list of active layers ) InputActionSetHandle_t *handlesOut ) = 0; + + //----------------------------------------------------------------------------- + // ACTIONS + //----------------------------------------------------------------------------- + + // Lookup the handle for a digital action. Best to do this once on startup, and store the handles for all future API calls. + virtual InputDigitalActionHandle_t GetDigitalActionHandle( const char *pszActionName ) = 0; + + // Returns the current state of the supplied digital game action + virtual InputDigitalActionData_t GetDigitalActionData( InputHandle_t inputHandle, InputDigitalActionHandle_t digitalActionHandle ) = 0; + + // Get the origin(s) for a digital action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. + // originsOut should point to a STEAM_INPUT_MAX_ORIGINS sized array of EInputActionOrigin handles. The EInputActionOrigin enum will get extended as support for new controller controllers gets added to + // the Steam client and will exceed the values from this header, please check bounds if you are using a look up table. + virtual int GetDigitalActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputDigitalActionHandle_t digitalActionHandle, STEAM_OUT_ARRAY_COUNT( STEAM_INPUT_MAX_ORIGINS, Receives list of action origins ) EInputActionOrigin *originsOut ) = 0; + + // Returns a localized string (from Steam's language setting) for the user-facing action name corresponding to the specified handle + virtual const char *GetStringForDigitalActionName( InputDigitalActionHandle_t eActionHandle ) = 0; + + // Lookup the handle for an analog action. Best to do this once on startup, and store the handles for all future API calls. + virtual InputAnalogActionHandle_t GetAnalogActionHandle( const char *pszActionName ) = 0; + + // Returns the current state of these supplied analog game action + virtual InputAnalogActionData_t GetAnalogActionData( InputHandle_t inputHandle, InputAnalogActionHandle_t analogActionHandle ) = 0; + + // Get the origin(s) for an analog action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. + // originsOut should point to a STEAM_INPUT_MAX_ORIGINS sized array of EInputActionOrigin handles. The EInputActionOrigin enum will get extended as support for new controller controllers gets added to + // the Steam client and will exceed the values from this header, please check bounds if you are using a look up table. + virtual int GetAnalogActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputAnalogActionHandle_t analogActionHandle, STEAM_OUT_ARRAY_COUNT( STEAM_INPUT_MAX_ORIGINS, Receives list of action origins ) EInputActionOrigin *originsOut ) = 0; + + // Get a local path to a PNG file for the provided origin's glyph. + virtual const char *GetGlyphPNGForActionOrigin( EInputActionOrigin eOrigin, ESteamInputGlyphSize eSize, uint32 unFlags ) = 0; + + // Get a local path to a SVG file for the provided origin's glyph. + virtual const char *GetGlyphSVGForActionOrigin( EInputActionOrigin eOrigin, uint32 unFlags ) = 0; + + // Get a local path to an older, Big Picture Mode-style PNG file for a particular origin + virtual const char *GetGlyphForActionOrigin_Legacy( EInputActionOrigin eOrigin ) = 0; + + // Returns a localized string (from Steam's language setting) for the specified origin. + virtual const char *GetStringForActionOrigin( EInputActionOrigin eOrigin ) = 0; + + // Returns a localized string (from Steam's language setting) for the user-facing action name corresponding to the specified handle + virtual const char *GetStringForAnalogActionName( InputAnalogActionHandle_t eActionHandle ) = 0; + + // Stop analog momentum for the action if it is a mouse action in trackball mode + virtual void StopAnalogActionMomentum( InputHandle_t inputHandle, InputAnalogActionHandle_t eAction ) = 0; + + // Returns raw motion data from the specified device + virtual InputMotionData_t GetMotionData( InputHandle_t inputHandle ) = 0; + + //----------------------------------------------------------------------------- + // OUTPUTS + //----------------------------------------------------------------------------- + + // Trigger a vibration event on supported controllers - Steam will translate these commands into haptic pulses for Steam Controllers + virtual void TriggerVibration( InputHandle_t inputHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed ) = 0; + + // Trigger a vibration event on supported controllers including Xbox trigger impulse rumble - Steam will translate these commands into haptic pulses for Steam Controllers + virtual void TriggerVibrationExtended( InputHandle_t inputHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed, unsigned short usLeftTriggerSpeed, unsigned short usRightTriggerSpeed ) = 0; + + // Send a haptic pulse, works on Steam Deck and Steam Controller devices + virtual void TriggerSimpleHapticEvent( InputHandle_t inputHandle, EControllerHapticLocation eHapticLocation, uint8 nIntensity, char nGainDB, uint8 nOtherIntensity, char nOtherGainDB ) = 0; + + // Set the controller LED color on supported controllers. nFlags is a bitmask of values from ESteamInputLEDFlag - 0 will default to setting a color. Steam will handle + // the behavior on exit of your program so you don't need to try restore the default as you are shutting down + virtual void SetLEDColor( InputHandle_t inputHandle, uint8 nColorR, uint8 nColorG, uint8 nColorB, unsigned int nFlags ) = 0; + + // Trigger a haptic pulse on a Steam Controller - if you are approximating rumble you may want to use TriggerVibration instead. + // Good uses for Haptic pulses include chimes, noises, or directional gameplay feedback (taking damage, footstep locations, etc). + virtual void Legacy_TriggerHapticPulse( InputHandle_t inputHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) = 0; + + // Trigger a haptic pulse with a duty cycle of usDurationMicroSec / usOffMicroSec, unRepeat times. If you are approximating rumble you may want to use TriggerVibration instead. + // nFlags is currently unused and reserved for future use. + virtual void Legacy_TriggerRepeatedHapticPulse( InputHandle_t inputHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec, unsigned short usOffMicroSec, unsigned short unRepeat, unsigned int nFlags ) = 0; + + //----------------------------------------------------------------------------- + // Utility functions available without using the rest of Steam Input API + //----------------------------------------------------------------------------- + + // Invokes the Steam overlay and brings up the binding screen if the user is using Big Picture Mode + // If the user is not in Big Picture Mode it will open up the binding in a new window + virtual bool ShowBindingPanel( InputHandle_t inputHandle ) = 0; + + // Returns the input type for a particular handle - unlike EInputActionOrigin which update with Steam and may return unrecognized values + // ESteamInputType will remain static and only return valid values from your SDK version + virtual ESteamInputType GetInputTypeForHandle( InputHandle_t inputHandle ) = 0; + + // Returns the associated controller handle for the specified emulated gamepad - can be used with the above 2 functions + // to identify controllers presented to your game over Xinput. Returns 0 if the Xinput index isn't associated with Steam Input + virtual InputHandle_t GetControllerForGamepadIndex( int nIndex ) = 0; + + // Returns the associated gamepad index for the specified controller, if emulating a gamepad or -1 if not associated with an Xinput index + virtual int GetGamepadIndexForController( InputHandle_t ulinputHandle ) = 0; + + // Returns a localized string (from Steam's language setting) for the specified Xbox controller origin. + virtual const char *GetStringForXboxOrigin( EXboxOrigin eOrigin ) = 0; + + // Get a local path to art for on-screen glyph for a particular Xbox controller origin + virtual const char *GetGlyphForXboxOrigin( EXboxOrigin eOrigin ) = 0; + + // Get the equivalent ActionOrigin for a given Xbox controller origin this can be chained with GetGlyphForActionOrigin to provide future proof glyphs for + // non-Steam Input API action games. Note - this only translates the buttons directly and doesn't take into account any remapping a user has made in their configuration + virtual EInputActionOrigin GetActionOriginFromXboxOrigin( InputHandle_t inputHandle, EXboxOrigin eOrigin ) = 0; + + // Convert an origin to another controller type - for inputs not present on the other controller type this will return k_EInputActionOrigin_None + // When a new input type is added you will be able to pass in k_ESteamInputType_Unknown and the closest origin that your version of the SDK recognized will be returned + // ex: if a Playstation 5 controller was released this function would return Playstation 4 origins. + virtual EInputActionOrigin TranslateActionOrigin( ESteamInputType eDestinationInputType, EInputActionOrigin eSourceOrigin ) = 0; + + // Get the binding revision for a given device. Returns false if the handle was not valid or if a mapping is not yet loaded for the device + virtual bool GetDeviceBindingRevision( InputHandle_t inputHandle, int *pMajor, int *pMinor ) = 0; + + // Get the Steam Remote Play session ID associated with a device, or 0 if there is no session associated with it + // See isteamremoteplay.h for more information on Steam Remote Play sessions + virtual uint32 GetRemotePlaySessionID( InputHandle_t inputHandle ) = 0; + + // Get a bitmask of the Steam Input Configuration types opted in for the current session. Returns ESteamInputConfigurationEnableType values.? + // Note: user can override the settings from the Steamworks Partner site so the returned values may not exactly match your default configuration + virtual uint16 GetSessionInputConfigurationSettings() = 0; + + // Set the trigger effect for a DualSense controller + virtual void SetDualSenseTriggerEffect( InputHandle_t inputHandle, const ScePadTriggerEffectParam *pParam ) = 0; +}; + +#define STEAMINPUT_INTERFACE_VERSION "SteamInput006" + +// Global interface accessor +inline ISteamInput *SteamInput(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamInput *, SteamInput, STEAMINPUT_INTERFACE_VERSION ); + +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + +//----------------------------------------------------------------------------- +// Purpose: called when a new controller has been connected, will fire once +// per controller if multiple new controllers connect in the same frame +//----------------------------------------------------------------------------- +struct SteamInputDeviceConnected_t +{ + enum { k_iCallback = k_iSteamControllerCallbacks + 1 }; + InputHandle_t m_ulConnectedDeviceHandle; // Handle for device +}; + +//----------------------------------------------------------------------------- +// Purpose: called when a new controller has been connected, will fire once +// per controller if multiple new controllers connect in the same frame +//----------------------------------------------------------------------------- +struct SteamInputDeviceDisconnected_t +{ + enum { k_iCallback = k_iSteamControllerCallbacks + 2 }; + InputHandle_t m_ulDisconnectedDeviceHandle; // Handle for device +}; + +//----------------------------------------------------------------------------- +// Purpose: called when a controller configuration has been loaded, will fire once +// per controller per focus change for Steam Input enabled controllers +//----------------------------------------------------------------------------- +struct SteamInputConfigurationLoaded_t +{ + enum { k_iCallback = k_iSteamControllerCallbacks + 3 }; + AppId_t m_unAppID; + InputHandle_t m_ulDeviceHandle; // Handle for device + CSteamID m_ulMappingCreator; // May differ from local user when using + // an unmodified community or official config + uint32 m_unMajorRevision; // Binding revision from In-game Action File. + // Same value as queried by GetDeviceBindingRevision + uint32 m_unMinorRevision; + bool m_bUsesSteamInputAPI; // Does the configuration contain any Analog/Digital actions? + bool m_bUsesGamepadAPI; // Does the configuration contain any Xinput bindings? +}; + +#pragma pack( pop ) + +#endif // ISTEAMINPUT_H \ No newline at end of file diff --git a/public/steam/isteaminventory.h b/public/steam/isteaminventory.h new file mode 100644 index 00000000..70665920 --- /dev/null +++ b/public/steam/isteaminventory.h @@ -0,0 +1,435 @@ +//====== Copyright 1996-2014 Valve Corporation, All rights reserved. ======= +// +// Purpose: interface to Steam Inventory +// +//============================================================================= + +#ifndef ISTEAMINVENTORY_H +#define ISTEAMINVENTORY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + + +// Every individual instance of an item has a globally-unique ItemInstanceID. +// This ID is unique to the combination of (player, specific item instance) +// and will not be transferred to another player or re-used for another item. +typedef uint64 SteamItemInstanceID_t; + +static const SteamItemInstanceID_t k_SteamItemInstanceIDInvalid = (SteamItemInstanceID_t)~0; + +// Types of items in your game are identified by a 32-bit "item definition number". +// Valid definition numbers are between 1 and 999999999; numbers less than or equal to +// zero are invalid, and numbers greater than or equal to one billion (1x10^9) are +// reserved for internal Steam use. +typedef int32 SteamItemDef_t; + + +enum ESteamItemFlags +{ + // Item status flags - these flags are permanently attached to specific item instances + k_ESteamItemNoTrade = 1 << 0, // This item is account-locked and cannot be traded or given away. + + // Action confirmation flags - these flags are set one time only, as part of a result set + k_ESteamItemRemoved = 1 << 8, // The item has been destroyed, traded away, expired, or otherwise invalidated + k_ESteamItemConsumed = 1 << 9, // The item quantity has been decreased by 1 via ConsumeItem API. + + // All other flag bits are currently reserved for internal Steam use at this time. + // Do not assume anything about the state of other flags which are not defined here. +}; + +struct SteamItemDetails_t +{ + SteamItemInstanceID_t m_itemId; + SteamItemDef_t m_iDefinition; + uint16 m_unQuantity; + uint16 m_unFlags; // see ESteamItemFlags +}; + +typedef int32 SteamInventoryResult_t; + +static const SteamInventoryResult_t k_SteamInventoryResultInvalid = -1; + +typedef uint64 SteamInventoryUpdateHandle_t; +const SteamInventoryUpdateHandle_t k_SteamInventoryUpdateHandleInvalid = 0xffffffffffffffffull; + +//----------------------------------------------------------------------------- +// Purpose: Steam Inventory query and manipulation API +//----------------------------------------------------------------------------- +class ISteamInventory +{ +public: + + // INVENTORY ASYNC RESULT MANAGEMENT + // + // Asynchronous inventory queries always output a result handle which can be used with + // GetResultStatus, GetResultItems, etc. A SteamInventoryResultReady_t callback will + // be triggered when the asynchronous result becomes ready (or fails). + // + + // Find out the status of an asynchronous inventory result handle. Possible values: + // k_EResultPending - still in progress + // k_EResultOK - done, result ready + // k_EResultExpired - done, result ready, maybe out of date (see DeserializeResult) + // k_EResultInvalidParam - ERROR: invalid API call parameters + // k_EResultServiceUnavailable - ERROR: service temporarily down, you may retry later + // k_EResultLimitExceeded - ERROR: operation would exceed per-user inventory limits + // k_EResultFail - ERROR: unknown / generic error + virtual EResult GetResultStatus( SteamInventoryResult_t resultHandle ) = 0; + + // Copies the contents of a result set into a flat array. The specific + // contents of the result set depend on which query which was used. + virtual bool GetResultItems( SteamInventoryResult_t resultHandle, + STEAM_OUT_ARRAY_COUNT( punOutItemsArraySize,Output array) SteamItemDetails_t *pOutItemsArray, + uint32 *punOutItemsArraySize ) = 0; + + // In combination with GetResultItems, you can use GetResultItemProperty to retrieve + // dynamic string properties for a given item returned in the result set. + // + // Property names are always composed of ASCII letters, numbers, and/or underscores. + // + // Pass a NULL pointer for pchPropertyName to get a comma - separated list of available + // property names. + // + // If pchValueBuffer is NULL, *punValueBufferSize will contain the + // suggested buffer size. Otherwise it will be the number of bytes actually copied + // to pchValueBuffer. If the results do not fit in the given buffer, partial + // results may be copied. + virtual bool GetResultItemProperty( SteamInventoryResult_t resultHandle, + uint32 unItemIndex, + const char *pchPropertyName, + STEAM_OUT_STRING_COUNT( punValueBufferSizeOut ) char *pchValueBuffer, uint32 *punValueBufferSizeOut ) = 0; + + // Returns the server time at which the result was generated. Compare against + // the value of IClientUtils::GetServerRealTime() to determine age. + virtual uint32 GetResultTimestamp( SteamInventoryResult_t resultHandle ) = 0; + + // Returns true if the result belongs to the target steam ID, false if the + // result does not. This is important when using DeserializeResult, to verify + // that a remote player is not pretending to have a different user's inventory. + virtual bool CheckResultSteamID( SteamInventoryResult_t resultHandle, CSteamID steamIDExpected ) = 0; + + // Destroys a result handle and frees all associated memory. + virtual void DestroyResult( SteamInventoryResult_t resultHandle ) = 0; + + + // INVENTORY ASYNC QUERY + // + + // Captures the entire state of the current user's Steam inventory. + // You must call DestroyResult on this handle when you are done with it. + // Returns false and sets *pResultHandle to zero if inventory is unavailable. + // Note: calls to this function are subject to rate limits and may return + // cached results if called too frequently. It is suggested that you call + // this function only when you are about to display the user's full inventory, + // or if you expect that the inventory may have changed. + virtual bool GetAllItems( SteamInventoryResult_t *pResultHandle ) = 0; + + + // Captures the state of a subset of the current user's Steam inventory, + // identified by an array of item instance IDs. The results from this call + // can be serialized and passed to other players to "prove" that the current + // user owns specific items, without exposing the user's entire inventory. + // For example, you could call GetItemsByID with the IDs of the user's + // currently equipped cosmetic items and serialize this to a buffer, and + // then transmit this buffer to other players upon joining a game. + virtual bool GetItemsByID( SteamInventoryResult_t *pResultHandle, STEAM_ARRAY_COUNT( unCountInstanceIDs ) const SteamItemInstanceID_t *pInstanceIDs, uint32 unCountInstanceIDs ) = 0; + + + // RESULT SERIALIZATION AND AUTHENTICATION + // + // Serialized result sets contain a short signature which can't be forged + // or replayed across different game sessions. A result set can be serialized + // on the local client, transmitted to other players via your game networking, + // and deserialized by the remote players. This is a secure way of preventing + // hackers from lying about posessing rare/high-value items. + + // Serializes a result set with signature bytes to an output buffer. Pass + // NULL as an output buffer to get the required size via punOutBufferSize. + // The size of a serialized result depends on the number items which are being + // serialized. When securely transmitting items to other players, it is + // recommended to use "GetItemsByID" first to create a minimal result set. + // Results have a built-in timestamp which will be considered "expired" after + // an hour has elapsed. See DeserializeResult for expiration handling. + virtual bool SerializeResult( SteamInventoryResult_t resultHandle, STEAM_OUT_BUFFER_COUNT(punOutBufferSize) void *pOutBuffer, uint32 *punOutBufferSize ) = 0; + + // Deserializes a result set and verifies the signature bytes. Returns false + // if bRequireFullOnlineVerify is set but Steam is running in Offline mode. + // Otherwise returns true and then delivers error codes via GetResultStatus. + // + // The bRESERVED_MUST_BE_FALSE flag is reserved for future use and should not + // be set to true by your game at this time. + // + // DeserializeResult has a potential soft-failure mode where the handle status + // is set to k_EResultExpired. GetResultItems() still succeeds in this mode. + // The "expired" result could indicate that the data may be out of date - not + // just due to timed expiration (one hour), but also because one of the items + // in the result set may have been traded or consumed since the result set was + // generated. You could compare the timestamp from GetResultTimestamp() to + // ISteamUtils::GetServerRealTime() to determine how old the data is. You could + // simply ignore the "expired" result code and continue as normal, or you + // could challenge the player with expired data to send an updated result set. + virtual bool DeserializeResult( SteamInventoryResult_t *pOutResultHandle, STEAM_BUFFER_COUNT(punOutBufferSize) const void *pBuffer, uint32 unBufferSize, bool bRESERVED_MUST_BE_FALSE = false ) = 0; + + + // INVENTORY ASYNC MODIFICATION + // + + // GenerateItems() creates one or more items and then generates a SteamInventoryCallback_t + // notification with a matching nCallbackContext parameter. This API is only intended + // for prototyping - it is only usable by Steam accounts that belong to the publisher group + // for your game. + // If punArrayQuantity is not NULL, it should be the same length as pArrayItems and should + // describe the quantity of each item to generate. + virtual bool GenerateItems( SteamInventoryResult_t *pResultHandle, STEAM_ARRAY_COUNT(unArrayLength) const SteamItemDef_t *pArrayItemDefs, STEAM_ARRAY_COUNT(unArrayLength) const uint32 *punArrayQuantity, uint32 unArrayLength ) = 0; + + // GrantPromoItems() checks the list of promotional items for which the user may be eligible + // and grants the items (one time only). On success, the result set will include items which + // were granted, if any. If no items were granted because the user isn't eligible for any + // promotions, this is still considered a success. + virtual bool GrantPromoItems( SteamInventoryResult_t *pResultHandle ) = 0; + + // AddPromoItem() / AddPromoItems() are restricted versions of GrantPromoItems(). Instead of + // scanning for all eligible promotional items, the check is restricted to a single item + // definition or set of item definitions. This can be useful if your game has custom UI for + // showing a specific promo item to the user. + virtual bool AddPromoItem( SteamInventoryResult_t *pResultHandle, SteamItemDef_t itemDef ) = 0; + virtual bool AddPromoItems( SteamInventoryResult_t *pResultHandle, STEAM_ARRAY_COUNT(unArrayLength) const SteamItemDef_t *pArrayItemDefs, uint32 unArrayLength ) = 0; + + // ConsumeItem() removes items from the inventory, permanently. They cannot be recovered. + // Not for the faint of heart - if your game implements item removal at all, a high-friction + // UI confirmation process is highly recommended. + virtual bool ConsumeItem( SteamInventoryResult_t *pResultHandle, SteamItemInstanceID_t itemConsume, uint32 unQuantity ) = 0; + + // ExchangeItems() is an atomic combination of item generation and consumption. + // It can be used to implement crafting recipes or transmutations, or items which unpack + // themselves into other items (e.g., a chest). + // Exchange recipes are defined in the ItemDef, and explicitly list the required item + // types and resulting generated type. + // Exchange recipes are evaluated atomically by the Inventory Service; if the supplied + // components do not match the recipe, or do not contain sufficient quantity, the + // exchange will fail. + virtual bool ExchangeItems( SteamInventoryResult_t *pResultHandle, + STEAM_ARRAY_COUNT(unArrayGenerateLength) const SteamItemDef_t *pArrayGenerate, STEAM_ARRAY_COUNT(unArrayGenerateLength) const uint32 *punArrayGenerateQuantity, uint32 unArrayGenerateLength, + STEAM_ARRAY_COUNT(unArrayDestroyLength) const SteamItemInstanceID_t *pArrayDestroy, STEAM_ARRAY_COUNT(unArrayDestroyLength) const uint32 *punArrayDestroyQuantity, uint32 unArrayDestroyLength ) = 0; + + + // TransferItemQuantity() is intended for use with items which are "stackable" (can have + // quantity greater than one). It can be used to split a stack into two, or to transfer + // quantity from one stack into another stack of identical items. To split one stack into + // two, pass k_SteamItemInstanceIDInvalid for itemIdDest and a new item will be generated. + virtual bool TransferItemQuantity( SteamInventoryResult_t *pResultHandle, SteamItemInstanceID_t itemIdSource, uint32 unQuantity, SteamItemInstanceID_t itemIdDest ) = 0; + + + // TIMED DROPS AND PLAYTIME CREDIT + // + + // Deprecated. Calling this method is not required for proper playtime accounting. + virtual void SendItemDropHeartbeat() = 0; + + // Playtime credit must be consumed and turned into item drops by your game. Only item + // definitions which are marked as "playtime item generators" can be spawned. The call + // will return an empty result set if there is not enough playtime credit for a drop. + // Your game should call TriggerItemDrop at an appropriate time for the user to receive + // new items, such as between rounds or while the player is dead. Note that players who + // hack their clients could modify the value of "dropListDefinition", so do not use it + // to directly control rarity. + // See your Steamworks configuration to set playtime drop rates for individual itemdefs. + // The client library will suppress too-frequent calls to this method. + virtual bool TriggerItemDrop( SteamInventoryResult_t *pResultHandle, SteamItemDef_t dropListDefinition ) = 0; + + + // Deprecated. This method is not supported. + virtual bool TradeItems( SteamInventoryResult_t *pResultHandle, CSteamID steamIDTradePartner, + STEAM_ARRAY_COUNT(nArrayGiveLength) const SteamItemInstanceID_t *pArrayGive, STEAM_ARRAY_COUNT(nArrayGiveLength) const uint32 *pArrayGiveQuantity, uint32 nArrayGiveLength, + STEAM_ARRAY_COUNT(nArrayGetLength) const SteamItemInstanceID_t *pArrayGet, STEAM_ARRAY_COUNT(nArrayGetLength) const uint32 *pArrayGetQuantity, uint32 nArrayGetLength ) = 0; + + + // ITEM DEFINITIONS + // + // Item definitions are a mapping of "definition IDs" (integers between 1 and 1000000) + // to a set of string properties. Some of these properties are required to display items + // on the Steam community web site. Other properties can be defined by applications. + // Use of these functions is optional; there is no reason to call LoadItemDefinitions + // if your game hardcodes the numeric definition IDs (eg, purple face mask = 20, blue + // weapon mod = 55) and does not allow for adding new item types without a client patch. + // + + // LoadItemDefinitions triggers the automatic load and refresh of item definitions. + // Every time new item definitions are available (eg, from the dynamic addition of new + // item types while players are still in-game), a SteamInventoryDefinitionUpdate_t + // callback will be fired. + virtual bool LoadItemDefinitions() = 0; + + // GetItemDefinitionIDs returns the set of all defined item definition IDs (which are + // defined via Steamworks configuration, and not necessarily contiguous integers). + // If pItemDefIDs is null, the call will return true and *punItemDefIDsArraySize will + // contain the total size necessary for a subsequent call. Otherwise, the call will + // return false if and only if there is not enough space in the output array. + virtual bool GetItemDefinitionIDs( + STEAM_OUT_ARRAY_COUNT(punItemDefIDsArraySize,List of item definition IDs) SteamItemDef_t *pItemDefIDs, + STEAM_DESC(Size of array is passed in and actual size used is returned in this param) uint32 *punItemDefIDsArraySize ) = 0; + + // GetItemDefinitionProperty returns a string property from a given item definition. + // Note that some properties (for example, "name") may be localized and will depend + // on the current Steam language settings (see ISteamApps::GetCurrentGameLanguage). + // Property names are always composed of ASCII letters, numbers, and/or underscores. + // Pass a NULL pointer for pchPropertyName to get a comma - separated list of available + // property names. If pchValueBuffer is NULL, *punValueBufferSize will contain the + // suggested buffer size. Otherwise it will be the number of bytes actually copied + // to pchValueBuffer. If the results do not fit in the given buffer, partial + // results may be copied. + virtual bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPropertyName, + STEAM_OUT_STRING_COUNT(punValueBufferSizeOut) char *pchValueBuffer, uint32 *punValueBufferSizeOut ) = 0; + + // Request the list of "eligible" promo items that can be manually granted to the given + // user. These are promo items of type "manual" that won't be granted automatically. + // An example usage of this is an item that becomes available every week. + STEAM_CALL_RESULT( SteamInventoryEligiblePromoItemDefIDs_t ) + virtual SteamAPICall_t RequestEligiblePromoItemDefinitionsIDs( CSteamID steamID ) = 0; + + // After handling a SteamInventoryEligiblePromoItemDefIDs_t call result, use this + // function to pull out the list of item definition ids that the user can be + // manually granted via the AddPromoItems() call. + virtual bool GetEligiblePromoItemDefinitionIDs( + CSteamID steamID, + STEAM_OUT_ARRAY_COUNT(punItemDefIDsArraySize,List of item definition IDs) SteamItemDef_t *pItemDefIDs, + STEAM_DESC(Size of array is passed in and actual size used is returned in this param) uint32 *punItemDefIDsArraySize ) = 0; + + // Starts the purchase process for the given item definitions. The callback SteamInventoryStartPurchaseResult_t + // will be posted if Steam was able to initialize the transaction. + // + // Once the purchase has been authorized and completed by the user, the callback SteamInventoryResultReady_t + // will be posted. + STEAM_CALL_RESULT( SteamInventoryStartPurchaseResult_t ) + virtual SteamAPICall_t StartPurchase( STEAM_ARRAY_COUNT(unArrayLength) const SteamItemDef_t *pArrayItemDefs, STEAM_ARRAY_COUNT(unArrayLength) const uint32 *punArrayQuantity, uint32 unArrayLength ) = 0; + + // Request current prices for all applicable item definitions + STEAM_CALL_RESULT( SteamInventoryRequestPricesResult_t ) + virtual SteamAPICall_t RequestPrices() = 0; + + // Returns the number of items with prices. Need to call RequestPrices() first. + virtual uint32 GetNumItemsWithPrices() = 0; + + // Returns item definition ids and their prices in the user's local currency. + // Need to call RequestPrices() first. + virtual bool GetItemsWithPrices( STEAM_ARRAY_COUNT(unArrayLength) STEAM_OUT_ARRAY_COUNT(pArrayItemDefs, Items with prices) SteamItemDef_t *pArrayItemDefs, + STEAM_ARRAY_COUNT(unArrayLength) STEAM_OUT_ARRAY_COUNT(pPrices, List of prices for the given item defs) uint64 *pCurrentPrices, + STEAM_ARRAY_COUNT(unArrayLength) STEAM_OUT_ARRAY_COUNT(pPrices, List of prices for the given item defs) uint64 *pBasePrices, + uint32 unArrayLength ) = 0; + + // Retrieves the price for the item definition id + // Returns false if there is no price stored for the item definition. + virtual bool GetItemPrice( SteamItemDef_t iDefinition, uint64 *pCurrentPrice, uint64 *pBasePrice ) = 0; + + // Create a request to update properties on items + virtual SteamInventoryUpdateHandle_t StartUpdateProperties() = 0; + // Remove the property on the item + virtual bool RemoveProperty( SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char *pchPropertyName ) = 0; + // Accessor methods to set properties on items + + STEAM_FLAT_NAME( SetPropertyString ) + virtual bool SetProperty( SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char *pchPropertyName, const char *pchPropertyValue ) = 0; + + STEAM_FLAT_NAME( SetPropertyBool ) + virtual bool SetProperty( SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char *pchPropertyName, bool bValue ) = 0; + + STEAM_FLAT_NAME( SetPropertyInt64 ) + virtual bool SetProperty( SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char *pchPropertyName, int64 nValue ) = 0; + + STEAM_FLAT_NAME( SetPropertyFloat ) + virtual bool SetProperty( SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char *pchPropertyName, float flValue ) = 0; + + // Submit the update request by handle + virtual bool SubmitUpdateProperties( SteamInventoryUpdateHandle_t handle, SteamInventoryResult_t * pResultHandle ) = 0; + + virtual bool InspectItem( SteamInventoryResult_t *pResultHandle, const char *pchItemToken ) = 0; +}; + +#define STEAMINVENTORY_INTERFACE_VERSION "STEAMINVENTORY_INTERFACE_V003" + +// Global interface accessor +inline ISteamInventory *SteamInventory(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamInventory *, SteamInventory, STEAMINVENTORY_INTERFACE_VERSION ); + +// Global accessor for the gameserver client +inline ISteamInventory *SteamGameServerInventory(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamInventory *, SteamGameServerInventory, STEAMINVENTORY_INTERFACE_VERSION ); + +// SteamInventoryResultReady_t callbacks are fired whenever asynchronous +// results transition from "Pending" to "OK" or an error state. There will +// always be exactly one callback per handle. +struct SteamInventoryResultReady_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 0 }; + SteamInventoryResult_t m_handle; + EResult m_result; +}; + + +// SteamInventoryFullUpdate_t callbacks are triggered when GetAllItems +// successfully returns a result which is newer / fresher than the last +// known result. (It will not trigger if the inventory hasn't changed, +// or if results from two overlapping calls are reversed in flight and +// the earlier result is already known to be stale/out-of-date.) +// The normal ResultReady callback will still be triggered immediately +// afterwards; this is an additional notification for your convenience. +struct SteamInventoryFullUpdate_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 1 }; + SteamInventoryResult_t m_handle; +}; + + +// A SteamInventoryDefinitionUpdate_t callback is triggered whenever +// item definitions have been updated, which could be in response to +// LoadItemDefinitions() or any other async request which required +// a definition update in order to process results from the server. +struct SteamInventoryDefinitionUpdate_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 2 }; +}; + +// Returned +struct SteamInventoryEligiblePromoItemDefIDs_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 3 }; + EResult m_result; + CSteamID m_steamID; + int m_numEligiblePromoItemDefs; + bool m_bCachedData; // indicates that the data was retrieved from the cache and not the server +}; + +// Triggered from StartPurchase call +struct SteamInventoryStartPurchaseResult_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 4 }; + EResult m_result; + uint64 m_ulOrderID; + uint64 m_ulTransID; +}; + + +// Triggered from RequestPrices +struct SteamInventoryRequestPricesResult_t +{ + enum { k_iCallback = k_iSteamInventoryCallbacks + 5 }; + EResult m_result; + char m_rgchCurrency[4]; +}; + +#pragma pack( pop ) + + +#endif // ISTEAMCONTROLLER_H diff --git a/public/steam/isteammatchmaking.h b/public/steam/isteammatchmaking.h index e3be340d..12189c72 100644 --- a/public/steam/isteammatchmaking.h +++ b/public/steam/isteammatchmaking.h @@ -10,10 +10,8 @@ #pragma once #endif -#include "steamtypes.h" -#include "steamclientpublic.h" +#include "steam_api_common.h" #include "matchmakingtypes.h" -#include "isteamclient.h" #include "isteamfriends.h" // lobby type description @@ -25,6 +23,8 @@ enum ELobbyType k_ELobbyTypeInvisible = 3, // returned by search, but not visible to other friends // useful if you want a user in two lobbies, for example matching groups together // a user can be in only one regular lobby, and up to two invisible lobbies + k_ELobbyTypePrivateUnique = 4, // private, unique and does not delete when empty - only one of these may exist per unique keypair set + // can only create from webapi }; // lobby search filter tools @@ -103,6 +103,7 @@ class ISteamMatchmaking } */ // + STEAM_CALL_RESULT( LobbyMatchList_t ) virtual SteamAPICall_t RequestLobbyList() = 0; // filters for lobbies // this needs to be called before RequestLobbyList() to take effect @@ -133,12 +134,14 @@ class ISteamMatchmaking // this is an asynchronous request // results will be returned by LobbyCreated_t callback and call result; lobby is joined & ready to use at this point // a LobbyEnter_t callback will also be received (since the local user is joining their own lobby) + STEAM_CALL_RESULT( LobbyCreated_t ) virtual SteamAPICall_t CreateLobby( ELobbyType eLobbyType, int cMaxMembers ) = 0; // Joins an existing lobby // this is an asynchronous request // results will be returned by LobbyEnter_t callback & call result, check m_EChatRoomEnterResponse to see if was successful // lobby metadata is available to use immediately on this call completing + STEAM_CALL_RESULT( LobbyEnter_t ) virtual SteamAPICall_t JoinLobby( CSteamID steamIDLobby ) = 0; // Leave a lobby; this will take effect immediately on the client side @@ -201,7 +204,7 @@ class ISteamMatchmaking // *pSteamIDUser is filled in with the CSteamID of the member // *pvData is filled in with the message itself // return value is the number of bytes written into the buffer - virtual int GetLobbyChatEntry( CSteamID steamIDLobby, int iChatID, OUT_STRUCT() CSteamID *pSteamIDUser, void *pvData, int cubData, EChatEntryType *peChatEntryType ) = 0; + virtual int GetLobbyChatEntry( CSteamID steamIDLobby, int iChatID, STEAM_OUT_STRUCT() CSteamID *pSteamIDUser, void *pvData, int cubData, EChatEntryType *peChatEntryType ) = 0; // Refreshes metadata for a lobby you're not necessarily in right now // you never do this for lobbies you're a member of, only if your @@ -217,7 +220,7 @@ class ISteamMatchmaking // either the IP/Port or the steamID of the game server has to be valid, depending on how you want the clients to be able to connect virtual void SetLobbyGameServer( CSteamID steamIDLobby, uint32 unGameServerIP, uint16 unGameServerPort, CSteamID steamIDGameServer ) = 0; // returns the details of a game server set in a lobby - returns false if there is no game server set, or that lobby doesn't exist - virtual bool GetLobbyGameServer( CSteamID steamIDLobby, uint32 *punGameServerIP, uint16 *punGameServerPort, OUT_STRUCT() CSteamID *psteamIDGameServer ) = 0; + virtual bool GetLobbyGameServer( CSteamID steamIDLobby, uint32 *punGameServerIP, uint16 *punGameServerPort, STEAM_OUT_STRUCT() CSteamID *psteamIDGameServer ) = 0; // set the limit on the # of users who can join the lobby virtual bool SetLobbyMemberLimit( CSteamID steamIDLobby, int cMaxMembers ) = 0; @@ -256,6 +259,9 @@ class ISteamMatchmaking }; #define STEAMMATCHMAKING_INTERFACE_VERSION "SteamMatchMaking009" +// Global interface accessor +inline ISteamMatchmaking *SteamMatchmaking(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamMatchmaking *, SteamMatchmaking, STEAMMATCHMAKING_INTERFACE_VERSION ); //----------------------------------------------------------------------------- // Callback interfaces for server list functions (see ISteamMatchmakingServers below) @@ -387,12 +393,12 @@ class ISteamMatchmakingServers // Request a new list of servers of a particular type. These calls each correspond to one of the EMatchMakingType values. // Each call allocates a new asynchronous request object. // Request object must be released by calling ReleaseRequest( hServerListRequest ) - virtual HServerListRequest RequestInternetServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; + virtual HServerListRequest RequestInternetServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; virtual HServerListRequest RequestLANServerList( AppId_t iApp, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; - virtual HServerListRequest RequestFriendsServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; - virtual HServerListRequest RequestFavoritesServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; - virtual HServerListRequest RequestHistoryServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; - virtual HServerListRequest RequestSpectatorServerList( AppId_t iApp, ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; + virtual HServerListRequest RequestFriendsServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; + virtual HServerListRequest RequestFavoritesServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; + virtual HServerListRequest RequestHistoryServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; + virtual HServerListRequest RequestSpectatorServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0; // Releases the asynchronous request object and cancels any pending query on it if there's a pending query in progress. // RefreshComplete callback is not posted when request is released. @@ -518,6 +524,10 @@ class ISteamMatchmakingServers }; #define STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION "SteamMatchMakingServers002" +// Global interface accessor +inline ISteamMatchmakingServers *SteamMatchmakingServers(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamMatchmakingServers *, SteamMatchmakingServers, STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION ); + // game server flags const uint32 k_unFavoriteFlagNone = 0x00; const uint32 k_unFavoriteFlagFavorite = 0x01; // this game favorite entry is for the favorites list @@ -541,16 +551,181 @@ enum EChatMemberStateChange #define BChatMemberStateChangeRemoved( rgfChatMemberStateChangeFlags ) ( rgfChatMemberStateChangeFlags & ( k_EChatMemberStateChangeDisconnected | k_EChatMemberStateChangeLeft | k_EChatMemberStateChangeKicked | k_EChatMemberStateChangeBanned ) ) + //----------------------------------------------------------------------------- -// Callbacks for ISteamMatchmaking (which go through the regular Steam callback registration system) +// Purpose: Functions for match making services for clients to get to favorites +// and to operate on game lobbies. +//----------------------------------------------------------------------------- +class ISteamGameSearch +{ +public: + // ============================================================================================= + // Game Player APIs + + // a keyname and a list of comma separated values: one of which is must be found in order for the match to qualify + // fails if a search is currently in progress + virtual EGameSearchErrorCode_t AddGameSearchParams( const char *pchKeyToFind, const char *pchValuesToFind ) = 0; + + // all players in lobby enter the queue and await a SearchForGameNotificationCallback_t callback. fails if another search is currently in progress + // if not the owner of the lobby or search already in progress this call fails + // periodic callbacks will be sent as queue time estimates change + virtual EGameSearchErrorCode_t SearchForGameWithLobby( CSteamID steamIDLobby, int nPlayerMin, int nPlayerMax ) = 0; + + // user enter the queue and await a SearchForGameNotificationCallback_t callback. fails if another search is currently in progress + // periodic callbacks will be sent as queue time estimates change + virtual EGameSearchErrorCode_t SearchForGameSolo( int nPlayerMin, int nPlayerMax ) = 0; + + // after receiving SearchForGameResultCallback_t, accept or decline the game + // multiple SearchForGameResultCallback_t will follow as players accept game until the host starts or cancels the game + virtual EGameSearchErrorCode_t AcceptGame() = 0; + virtual EGameSearchErrorCode_t DeclineGame() = 0; + + // after receiving GameStartedByHostCallback_t get connection details to server + virtual EGameSearchErrorCode_t RetrieveConnectionDetails( CSteamID steamIDHost, char *pchConnectionDetails, int cubConnectionDetails ) = 0; + + // leaves queue if still waiting + virtual EGameSearchErrorCode_t EndGameSearch() = 0; + + // ============================================================================================= + // Game Host APIs + + // a keyname and a list of comma separated values: all the values you allow + virtual EGameSearchErrorCode_t SetGameHostParams( const char *pchKey, const char *pchValue ) = 0; + + // set connection details for players once game is found so they can connect to this server + virtual EGameSearchErrorCode_t SetConnectionDetails( const char *pchConnectionDetails, int cubConnectionDetails ) = 0; + + // mark server as available for more players with nPlayerMin,nPlayerMax desired + // accept no lobbies with playercount greater than nMaxTeamSize + // the set of lobbies returned must be partitionable into teams of no more than nMaxTeamSize + // RequestPlayersForGameNotificationCallback_t callback will be sent when the search has started + // multple RequestPlayersForGameResultCallback_t callbacks will follow when players are found + virtual EGameSearchErrorCode_t RequestPlayersForGame( int nPlayerMin, int nPlayerMax, int nMaxTeamSize ) = 0; + + // accept the player list and release connection details to players + // players will only be given connection details and host steamid when this is called + // ( allows host to accept after all players confirm, some confirm, or none confirm. decision is entirely up to the host ) + virtual EGameSearchErrorCode_t HostConfirmGameStart( uint64 ullUniqueGameID ) = 0; + + // cancel request and leave the pool of game hosts looking for players + // if a set of players has already been sent to host, all players will receive SearchForGameHostFailedToConfirm_t + virtual EGameSearchErrorCode_t CancelRequestPlayersForGame() = 0; + + // submit a result for one player. does not end the game. ullUniqueGameID continues to describe this game + virtual EGameSearchErrorCode_t SubmitPlayerResult( uint64 ullUniqueGameID, CSteamID steamIDPlayer, EPlayerResult_t EPlayerResult ) = 0; + + // ends the game. no further SubmitPlayerResults for ullUniqueGameID will be accepted + // any future requests will provide a new ullUniqueGameID + virtual EGameSearchErrorCode_t EndGame( uint64 ullUniqueGameID ) = 0; + +}; +#define STEAMGAMESEARCH_INTERFACE_VERSION "SteamMatchGameSearch001" + +// Global interface accessor +inline ISteamGameSearch *SteamGameSearch(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamGameSearch *, SteamGameSearch, STEAMGAMESEARCH_INTERFACE_VERSION ); + + +//----------------------------------------------------------------------------- +// Purpose: Functions for quickly creating a Party with friends or acquaintances, +// EG from chat rooms. +//----------------------------------------------------------------------------- +enum ESteamPartyBeaconLocationType +{ + k_ESteamPartyBeaconLocationType_Invalid = 0, + k_ESteamPartyBeaconLocationType_ChatGroup = 1, + + k_ESteamPartyBeaconLocationType_Max, +}; + + #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif + +struct SteamPartyBeaconLocation_t +{ + ESteamPartyBeaconLocationType m_eType; + uint64 m_ulLocationID; +}; + +enum ESteamPartyBeaconLocationData +{ + k_ESteamPartyBeaconLocationDataInvalid = 0, + k_ESteamPartyBeaconLocationDataName = 1, + k_ESteamPartyBeaconLocationDataIconURLSmall = 2, + k_ESteamPartyBeaconLocationDataIconURLMedium = 3, + k_ESteamPartyBeaconLocationDataIconURLLarge = 4, +}; + +class ISteamParties +{ +public: + + // ============================================================================================= + // Party Client APIs + + // Enumerate any active beacons for parties you may wish to join + virtual uint32 GetNumActiveBeacons() = 0; + virtual PartyBeaconID_t GetBeaconByIndex( uint32 unIndex ) = 0; + virtual bool GetBeaconDetails( PartyBeaconID_t ulBeaconID, CSteamID *pSteamIDBeaconOwner, STEAM_OUT_STRUCT() SteamPartyBeaconLocation_t *pLocation, STEAM_OUT_STRING_COUNT(cchMetadata) char *pchMetadata, int cchMetadata ) = 0; + + // Join an open party. Steam will reserve one beacon slot for your SteamID, + // and return the necessary JoinGame string for you to use to connect + STEAM_CALL_RESULT( JoinPartyCallback_t ) + virtual SteamAPICall_t JoinParty( PartyBeaconID_t ulBeaconID ) = 0; + + // ============================================================================================= + // Party Host APIs + + // Get a list of possible beacon locations + virtual bool GetNumAvailableBeaconLocations( uint32 *puNumLocations ) = 0; + virtual bool GetAvailableBeaconLocations( SteamPartyBeaconLocation_t *pLocationList, uint32 uMaxNumLocations ) = 0; + + // Create a new party beacon and activate it in the selected location. + // unOpenSlots is the maximum number of users that Steam will send to you. + // When people begin responding to your beacon, Steam will send you + // PartyReservationCallback_t callbacks to let you know who is on the way. + STEAM_CALL_RESULT( CreateBeaconCallback_t ) + virtual SteamAPICall_t CreateBeacon( uint32 unOpenSlots, SteamPartyBeaconLocation_t *pBeaconLocation, const char *pchConnectString, const char *pchMetadata ) = 0; + + // Call this function when a user that had a reservation (see callback below) + // has successfully joined your party. + // Steam will manage the remaining open slots automatically. + virtual void OnReservationCompleted( PartyBeaconID_t ulBeacon, CSteamID steamIDUser ) = 0; + + // To cancel a reservation (due to timeout or user input), call this. + // Steam will open a new reservation slot. + // Note: The user may already be in-flight to your game, so it's possible they will still connect and try to join your party. + virtual void CancelReservation( PartyBeaconID_t ulBeacon, CSteamID steamIDUser ) = 0; + + // Change the number of open beacon reservation slots. + // Call this if, for example, someone without a reservation joins your party (eg a friend, or via your own matchmaking system). + STEAM_CALL_RESULT( ChangeNumOpenSlotsCallback_t ) + virtual SteamAPICall_t ChangeNumOpenSlots( PartyBeaconID_t ulBeacon, uint32 unOpenSlots ) = 0; + + // Turn off the beacon. + virtual bool DestroyBeacon( PartyBeaconID_t ulBeacon ) = 0; + + // Utils + virtual bool GetBeaconLocationData( SteamPartyBeaconLocation_t BeaconLocation, ESteamPartyBeaconLocationData eData, STEAM_OUT_STRING_COUNT(cchDataStringOut) char *pchDataStringOut, int cchDataStringOut ) = 0; + +}; +#define STEAMPARTIES_INTERFACE_VERSION "SteamParties002" + +// Global interface accessor +inline ISteamParties *SteamParties(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamParties *, SteamParties, STEAMPARTIES_INTERFACE_VERSION ); + + +//----------------------------------------------------------------------------- +// Callbacks for ISteamMatchmaking (which go through the regular Steam callback registration system) + //----------------------------------------------------------------------------- // Purpose: a server was added/removed from the favorites list, you should refresh now //----------------------------------------------------------------------------- @@ -741,6 +916,171 @@ struct FavoritesListAccountsUpdated_t EResult m_eResult; }; + + +//----------------------------------------------------------------------------- +// Callbacks for ISteamGameSearch (which go through the regular Steam callback registration system) + +struct SearchForGameProgressCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 1 }; + + uint64 m_ullSearchID; // all future callbacks referencing this search will include this Search ID + + EResult m_eResult; // if search has started this result will be k_EResultOK, any other value indicates search has failed to start or has terminated + CSteamID m_lobbyID; // lobby ID if lobby search, invalid steamID otherwise + CSteamID m_steamIDEndedSearch; // if search was terminated, steamID that terminated search + + int32 m_nSecondsRemainingEstimate; + int32 m_cPlayersSearching; +}; + +// notification to all players searching that a game has been found +struct SearchForGameResultCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 2 }; + + uint64 m_ullSearchID; + + EResult m_eResult; // if game/host was lost this will be an error value + + // if m_bGameFound is true the following are non-zero + int32 m_nCountPlayersInGame; + int32 m_nCountAcceptedGame; + // if m_steamIDHost is valid the host has started the game + CSteamID m_steamIDHost; + bool m_bFinalCallback; +}; + + +//----------------------------------------------------------------------------- +// ISteamGameSearch : Game Host API callbacks + +// callback from RequestPlayersForGame when the matchmaking service has started or ended search +// callback will also follow a call from CancelRequestPlayersForGame - m_bSearchInProgress will be false +struct RequestPlayersForGameProgressCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 11 }; + + EResult m_eResult; // m_ullSearchID will be non-zero if this is k_EResultOK + uint64 m_ullSearchID; // all future callbacks referencing this search will include this Search ID +}; + +// callback from RequestPlayersForGame +// one of these will be sent per player +// followed by additional callbacks when players accept or decline the game +struct RequestPlayersForGameResultCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 12 }; + + EResult m_eResult; // m_ullSearchID will be non-zero if this is k_EResultOK + uint64 m_ullSearchID; + + CSteamID m_SteamIDPlayerFound; // player steamID + CSteamID m_SteamIDLobby; // if the player is in a lobby, the lobby ID + enum PlayerAcceptState_t + { + k_EStateUnknown = 0, + k_EStatePlayerAccepted = 1, + k_EStatePlayerDeclined = 2, + }; + PlayerAcceptState_t m_ePlayerAcceptState; + int32 m_nPlayerIndex; + int32 m_nTotalPlayersFound; // expect this many callbacks at minimum + int32 m_nTotalPlayersAcceptedGame; + int32 m_nSuggestedTeamIndex; + uint64 m_ullUniqueGameID; +}; + + +struct RequestPlayersForGameFinalResultCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 13 }; + + EResult m_eResult; + uint64 m_ullSearchID; + uint64 m_ullUniqueGameID; +}; + + + +// this callback confirms that results were received by the matchmaking service for this player +struct SubmitPlayerResultResultCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 14 }; + + EResult m_eResult; + uint64 ullUniqueGameID; + CSteamID steamIDPlayer; +}; + + +// this callback confirms that the game is recorded as complete on the matchmaking service +// the next call to RequestPlayersForGame will generate a new unique game ID +struct EndGameResultCallback_t +{ + enum { k_iCallback = k_iSteamGameSearchCallbacks + 15 }; + + EResult m_eResult; + uint64 ullUniqueGameID; +}; + + +// Steam has responded to the user request to join a party via the given Beacon ID. +// If successful, the connect string contains game-specific instructions to connect +// to the game with that party. +struct JoinPartyCallback_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 1 }; + + EResult m_eResult; + PartyBeaconID_t m_ulBeaconID; + CSteamID m_SteamIDBeaconOwner; + char m_rgchConnectString[256]; +}; + +// Response to CreateBeacon request. If successful, the beacon ID is provided. +struct CreateBeaconCallback_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 2 }; + + EResult m_eResult; + PartyBeaconID_t m_ulBeaconID; +}; + +// Someone has used the beacon to join your party - they are in-flight now +// and we've reserved one of the open slots for them. +// You should confirm when they join your party by calling OnReservationCompleted(). +// Otherwise, Steam may timeout their reservation eventually. +struct ReservationNotificationCallback_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 3 }; + + PartyBeaconID_t m_ulBeaconID; + CSteamID m_steamIDJoiner; +}; + +// Response to ChangeNumOpenSlots call +struct ChangeNumOpenSlotsCallback_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 4 }; + + EResult m_eResult; +}; + +// The list of possible Party beacon locations has changed +struct AvailableBeaconLocationsUpdated_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 5 }; +}; + +// The list of active beacons may have changed +struct ActiveBeaconsUpdated_t +{ + enum { k_iCallback = k_iSteamPartiesCallbacks + 6 }; +}; + + #pragma pack( pop ) diff --git a/public/steam/isteammusic.h b/public/steam/isteammusic.h index 779a4c2e..ffa49a08 100644 --- a/public/steam/isteammusic.h +++ b/public/steam/isteammusic.h @@ -6,7 +6,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: @@ -44,22 +44,26 @@ class ISteamMusic #define STEAMMUSIC_INTERFACE_VERSION "STEAMMUSIC_INTERFACE_VERSION001" +// Global interface accessor +inline ISteamMusic *SteamMusic(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamMusic *, SteamMusic, STEAMMUSIC_INTERFACE_VERSION ); + // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif -DEFINE_CALLBACK( PlaybackStatusHasChanged_t, k_iSteamMusicCallbacks + 1 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( PlaybackStatusHasChanged_t, k_iSteamMusicCallbacks + 1 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( VolumeHasChanged_t, k_iSteamMusicCallbacks + 2 ) - CALLBACK_MEMBER( 0, float, m_flNewVolume ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( VolumeHasChanged_t, k_iSteamMusicCallbacks + 2 ) + STEAM_CALLBACK_MEMBER( 0, float, m_flNewVolume ) +STEAM_CALLBACK_END(1) #pragma pack( pop ) diff --git a/public/steam/isteammusicremote.h b/public/steam/isteammusicremote.h index ea29a7de..a36f4f87 100644 --- a/public/steam/isteammusicremote.h +++ b/public/steam/isteammusicremote.h @@ -6,7 +6,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" #include "isteammusic.h" #define k_SteamMusicNameMaxLength 255 @@ -64,63 +64,67 @@ class ISteamMusicRemote #define STEAMMUSICREMOTE_INTERFACE_VERSION "STEAMMUSICREMOTE_INTERFACE_VERSION001" +// Global interface accessor +inline ISteamMusicRemote *SteamMusicRemote(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamMusicRemote *, SteamMusicRemote, STEAMMUSICREMOTE_INTERFACE_VERSION ); + // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif -DEFINE_CALLBACK( MusicPlayerRemoteWillActivate_t, k_iSteamMusicRemoteCallbacks + 1) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerRemoteWillActivate_t, k_iSteamMusicRemoteCallbacks + 1) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerRemoteWillDeactivate_t, k_iSteamMusicRemoteCallbacks + 2 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerRemoteWillDeactivate_t, k_iSteamMusicRemoteCallbacks + 2 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerRemoteToFront_t, k_iSteamMusicRemoteCallbacks + 3 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerRemoteToFront_t, k_iSteamMusicRemoteCallbacks + 3 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWillQuit_t, k_iSteamMusicRemoteCallbacks + 4 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerWillQuit_t, k_iSteamMusicRemoteCallbacks + 4 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWantsPlay_t, k_iSteamMusicRemoteCallbacks + 5 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsPlay_t, k_iSteamMusicRemoteCallbacks + 5 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWantsPause_t, k_iSteamMusicRemoteCallbacks + 6 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsPause_t, k_iSteamMusicRemoteCallbacks + 6 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWantsPlayPrevious_t, k_iSteamMusicRemoteCallbacks + 7 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsPlayPrevious_t, k_iSteamMusicRemoteCallbacks + 7 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWantsPlayNext_t, k_iSteamMusicRemoteCallbacks + 8 ) -END_DEFINE_CALLBACK_0() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsPlayNext_t, k_iSteamMusicRemoteCallbacks + 8 ) +STEAM_CALLBACK_END(0) -DEFINE_CALLBACK( MusicPlayerWantsShuffled_t, k_iSteamMusicRemoteCallbacks + 9 ) - CALLBACK_MEMBER( 0, bool, m_bShuffled ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsShuffled_t, k_iSteamMusicRemoteCallbacks + 9 ) + STEAM_CALLBACK_MEMBER( 0, bool, m_bShuffled ) +STEAM_CALLBACK_END(1) -DEFINE_CALLBACK( MusicPlayerWantsLooped_t, k_iSteamMusicRemoteCallbacks + 10 ) - CALLBACK_MEMBER(0, bool, m_bLooped ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsLooped_t, k_iSteamMusicRemoteCallbacks + 10 ) + STEAM_CALLBACK_MEMBER(0, bool, m_bLooped ) +STEAM_CALLBACK_END(1) -DEFINE_CALLBACK( MusicPlayerWantsVolume_t, k_iSteamMusicCallbacks + 11 ) - CALLBACK_MEMBER(0, float, m_flNewVolume) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsVolume_t, k_iSteamMusicCallbacks + 11 ) + STEAM_CALLBACK_MEMBER(0, float, m_flNewVolume) +STEAM_CALLBACK_END(1) -DEFINE_CALLBACK( MusicPlayerSelectsQueueEntry_t, k_iSteamMusicCallbacks + 12 ) - CALLBACK_MEMBER(0, int, nID ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerSelectsQueueEntry_t, k_iSteamMusicCallbacks + 12 ) + STEAM_CALLBACK_MEMBER(0, int, nID ) +STEAM_CALLBACK_END(1) -DEFINE_CALLBACK( MusicPlayerSelectsPlaylistEntry_t, k_iSteamMusicCallbacks + 13 ) - CALLBACK_MEMBER(0, int, nID ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerSelectsPlaylistEntry_t, k_iSteamMusicCallbacks + 13 ) + STEAM_CALLBACK_MEMBER(0, int, nID ) +STEAM_CALLBACK_END(1) -DEFINE_CALLBACK( MusicPlayerWantsPlayingRepeatStatus_t, k_iSteamMusicRemoteCallbacks + 14 ) - CALLBACK_MEMBER(0, int, m_nPlayingRepeatStatus ) -END_DEFINE_CALLBACK_1() +STEAM_CALLBACK_BEGIN( MusicPlayerWantsPlayingRepeatStatus_t, k_iSteamMusicRemoteCallbacks + 14 ) + STEAM_CALLBACK_MEMBER(0, int, m_nPlayingRepeatStatus ) +STEAM_CALLBACK_END(1) #pragma pack( pop ) diff --git a/public/steam/isteamnetworking.h b/public/steam/isteamnetworking.h index c77f7bf7..b7e077a3 100644 --- a/public/steam/isteamnetworking.h +++ b/public/steam/isteamnetworking.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: interface to steam managing network connections between game clients & servers // @@ -10,21 +10,23 @@ #pragma once #endif -#include "steamtypes.h" -#include "steamclientpublic.h" - +#include "steam_api_common.h" // list of possible errors returned by SendP2PPacket() API // these will be posted in the P2PSessionConnectFail_t callback enum EP2PSessionError { k_EP2PSessionErrorNone = 0, - k_EP2PSessionErrorNotRunningApp = 1, // target is not running the same game k_EP2PSessionErrorNoRightsToApp = 2, // local user doesn't own the app that is running - k_EP2PSessionErrorDestinationNotLoggedIn = 3, // target user isn't connected to Steam k_EP2PSessionErrorTimeout = 4, // target isn't responding, perhaps not calling AcceptP2PSessionWithUser() // corporate firewalls can also block this (NAT traversal is not firewall traversal) // make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction + + // The following error codes were removed and will never be sent. + // For privacy reasons, there is no reply if the user is offline or playing another game. + k_EP2PSessionErrorNotRunningApp_DELETED = 1, + k_EP2PSessionErrorDestinationNotLoggedIn_DELETED = 3, + k_EP2PSessionErrorMax = 5 }; @@ -63,7 +65,7 @@ enum EP2PSend #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif struct P2PSessionState_t { @@ -122,13 +124,26 @@ enum ESNetSocketConnectionType //----------------------------------------------------------------------------- // Purpose: Functions for making connections and sending data between clients, // traversing NAT's where possible +// +// NOTE: This interface is deprecated and may be removed in a future release of +/// the Steamworks SDK. Please see ISteamNetworkingSockets and +/// ISteamNetworkingMessages //----------------------------------------------------------------------------- class ISteamNetworking { public: //////////////////////////////////////////////////////////////////////////////////////////// - // Session-less connection functions - // automatically establishes NAT-traversing or Relay server connections + // + // UDP-style (connectionless) networking interface. These functions send messages using + // an API organized around the destination. Reliable and unreliable messages are supported. + // + // For a more TCP-style interface (meaning you have a connection handle), see the functions below. + // Both interface styles can send both reliable and unreliable messages. + // + // Automatically establishes NAT-traversing or Relay server connections + // + // These APIs are deprecated, and may be removed in a future version of the Steamworks + // SDK. See ISteamNetworkingMessages. // Sends a P2P packet to the specified user // UDP-like, unreliable and a max packet size of 1200 bytes @@ -177,15 +192,29 @@ class ISteamNetworking // or to existing connections that need to automatically reconnect after this value is set. // // P2P packet relay is allowed by default + // + // NOTE: This function is deprecated and may be removed in a future version of the SDK. For + // security purposes, we may decide to relay the traffic to certain peers, even if you pass false + // to this function, to prevent revealing the client's IP address top another peer. virtual bool AllowP2PPacketRelay( bool bAllow ) = 0; //////////////////////////////////////////////////////////////////////////////////////////// - // LISTEN / CONNECT style interface functions // - // This is an older set of functions designed around the Berkeley TCP sockets model - // it's preferential that you use the above P2P functions, they're more robust - // and these older functions will be removed eventually + // LISTEN / CONNECT connection-oriented interface functions + // + // These functions are more like a client-server TCP API. One side is the "server" + // and "listens" for incoming connections, which then must be "accepted." The "client" + // initiates a connection by "connecting." Sending and receiving is done through a + // connection handle. + // + // For a more UDP-style interface, where you do not track connection handles but + // simply send messages to a SteamID, use the UDP-style functions above. + // + // Both methods can send both reliable and unreliable methods. + // + // These APIs are deprecated, and may be removed in a future version of the Steamworks + // SDK. See ISteamNetworkingSockets. // //////////////////////////////////////////////////////////////////////////////////////////// @@ -198,14 +227,14 @@ class ISteamNetworking // pass in 0 if you just want the default local IP // unPort is the port to use // pass in 0 if you don't want users to be able to connect via IP/Port, but expect to be always peer-to-peer connections only - virtual SNetListenSocket_t CreateListenSocket( int nVirtualP2PPort, uint32 nIP, uint16 nPort, bool bAllowUseOfPacketRelay ) = 0; + virtual SNetListenSocket_t CreateListenSocket( int nVirtualP2PPort, SteamIPAddress_t nIP, uint16 nPort, bool bAllowUseOfPacketRelay ) = 0; // creates a socket and begin connection to a remote destination // can connect via a known steamID (client or game server), or directly to an IP // on success will trigger a SocketStatusCallback_t callback // on failure or timeout will trigger a SocketStatusCallback_t callback with a failure code in m_eSNetSocketState virtual SNetSocket_t CreateP2PConnectionSocket( CSteamID steamIDTarget, int nVirtualPort, int nTimeoutSec, bool bAllowUseOfPacketRelay ) = 0; - virtual SNetSocket_t CreateConnectionSocket( uint32 nIP, uint16 nPort, int nTimeoutSec ) = 0; + virtual SNetSocket_t CreateConnectionSocket( SteamIPAddress_t nIP, uint16 nPort, int nTimeoutSec ) = 0; // disconnects the connection to the socket, if any, and invalidates the handle // any unread data on the socket will be thrown away @@ -247,11 +276,11 @@ class ISteamNetworking virtual bool RetrieveData( SNetListenSocket_t hListenSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize, SNetSocket_t *phSocket ) = 0; // returns information about the specified socket, filling out the contents of the pointers - virtual bool GetSocketInfo( SNetSocket_t hSocket, CSteamID *pSteamIDRemote, int *peSocketStatus, uint32 *punIPRemote, uint16 *punPortRemote ) = 0; + virtual bool GetSocketInfo( SNetSocket_t hSocket, CSteamID *pSteamIDRemote, int *peSocketStatus, SteamIPAddress_t *punIPRemote, uint16 *punPortRemote ) = 0; // returns which local port the listen socket is bound to // *pnIP and *pnPort will be 0 if the socket is set to listen for P2P connections only - virtual bool GetListenSocketInfo( SNetListenSocket_t hListenSocket, uint32 *pnIP, uint16 *pnPort ) = 0; + virtual bool GetListenSocketInfo( SNetListenSocket_t hListenSocket, SteamIPAddress_t *pnIP, uint16 *pnPort ) = 0; // returns true to describe how the socket ended up connecting virtual ESNetSocketConnectionType GetSocketConnectionType( SNetSocket_t hSocket ) = 0; @@ -259,7 +288,15 @@ class ISteamNetworking // max packet size, in bytes virtual int GetMaxPacketSize( SNetSocket_t hSocket ) = 0; }; -#define STEAMNETWORKING_INTERFACE_VERSION "SteamNetworking005" +#define STEAMNETWORKING_INTERFACE_VERSION "SteamNetworking006" + +// Global interface accessor +inline ISteamNetworking *SteamNetworking(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworking *, SteamNetworking, STEAMNETWORKING_INTERFACE_VERSION ); + +// Global accessor for the gameserver client +inline ISteamNetworking *SteamGameServerNetworking(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworking *, SteamGameServerNetworking, STEAMNETWORKING_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -267,7 +304,7 @@ class ISteamNetworking #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif // callback notification - a user wants to talk to us over the P2P channel via the SendP2PPacket() API diff --git a/public/steam/isteamnetworkingmessages.h b/public/steam/isteamnetworkingmessages.h new file mode 100644 index 00000000..b7a2cd0e --- /dev/null +++ b/public/steam/isteamnetworkingmessages.h @@ -0,0 +1,198 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== + +#ifndef ISTEAMNETWORKINGMESSAGES +#define ISTEAMNETWORKINGMESSAGES +#pragma once + +#include "steamnetworkingtypes.h" +#include "steam_api_common.h" + +//----------------------------------------------------------------------------- +/// The non-connection-oriented interface to send and receive messages +/// (whether they be "clients" or "servers"). +/// +/// ISteamNetworkingSockets is connection-oriented (like TCP), meaning you +/// need to listen and connect, and then you send messages using a connection +/// handle. ISteamNetworkingMessages is more like UDP, in that you can just send +/// messages to arbitrary peers at any time. The underlying connections are +/// established implicitly. +/// +/// Under the hood ISteamNetworkingMessages works on top of the ISteamNetworkingSockets +/// code, so you get the same routing and messaging efficiency. The difference is +/// mainly in your responsibility to explicitly establish a connection and +/// the type of feedback you get about the state of the connection. Both +/// interfaces can do "P2P" communications, and both support both unreliable +/// and reliable messages, fragmentation and reassembly. +/// +/// The primary purpose of this interface is to be "like UDP", so that UDP-based code +/// can be ported easily to take advantage of relayed connections. If you find +/// yourself needing more low level information or control, or to be able to better +/// handle failure, then you probably need to use ISteamNetworkingSockets directly. +/// Also, note that if your main goal is to obtain a connection between two peers +/// without concerning yourself with assigning roles of "client" and "server", +/// you may find the symmetric connection mode of ISteamNetworkingSockets useful. +/// (See k_ESteamNetworkingConfig_SymmetricConnect.) +/// +class ISteamNetworkingMessages +{ +public: + /// Sends a message to the specified host. If we don't already have a session with that user, + /// a session is implicitly created. There might be some handshaking that needs to happen + /// before we can actually begin sending message data. If this handshaking fails and we can't + /// get through, an error will be posted via the callback SteamNetworkingMessagesSessionFailed_t. + /// There is no notification when the operation succeeds. (You should have the peer send a reply + /// for this purpose.) + /// + /// Sending a message to a host will also implicitly accept any incoming connection from that host. + /// + /// nSendFlags is a bitmask of k_nSteamNetworkingSend_xxx options + /// + /// nRemoteChannel is a routing number you can use to help route message to different systems. + /// You'll have to call ReceiveMessagesOnChannel() with the same channel number in order to retrieve + /// the data on the other end. + /// + /// Using different channels to talk to the same user will still use the same underlying + /// connection, saving on resources. If you don't need this feature, use 0. + /// Otherwise, small integers are the most efficient. + /// + /// It is guaranteed that reliable messages to the same host on the same channel + /// will be be received by the remote host (if they are received at all) exactly once, + /// and in the same order that they were sent. + /// + /// NO other order guarantees exist! In particular, unreliable messages may be dropped, + /// received out of order with respect to each other and with respect to reliable data, + /// or may be received multiple times. Messages on different channels are *not* guaranteed + /// to be received in the order they were sent. + /// + /// A note for those familiar with TCP/IP ports, or converting an existing codebase that + /// opened multiple sockets: You might notice that there is only one channel, and with + /// TCP/IP each endpoint has a port number. You can think of the channel number as the + /// *destination* port. If you need each message to also include a "source port" (so the + /// recipient can route the reply), then just put that in your message. That is essentially + /// how UDP works! + /// + /// Returns: + /// - k_EREsultOK on success. + /// - k_EResultNoConnection, if the session has failed or was closed by the peer and + /// k_nSteamNetworkingSend_AutoRestartBrokenSession was not specified. (You can + /// use GetSessionConnectionInfo to get the details.) In order to acknowledge the + /// broken session and start a new one, you must call CloseSessionWithUser, or you may + /// repeat the call with k_nSteamNetworkingSend_AutoRestartBrokenSession. See + /// k_nSteamNetworkingSend_AutoRestartBrokenSession for more details. + /// - See ISteamNetworkingSockets::SendMessageToConnection for more possible return values + virtual EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const void *pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ) = 0; + + /// Reads the next message that has been sent from another user via SendMessageToUser() on the given channel. + /// Returns number of messages returned into your list. (0 if no message are available on that channel.) + /// + /// When you're done with the message object(s), make sure and call SteamNetworkingMessage_t::Release()! + virtual int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + /// Call this in response to a SteamNetworkingMessagesSessionRequest_t callback. + /// SteamNetworkingMessagesSessionRequest_t are posted when a user tries to send you a message, + /// and you haven't tried to talk to them first. If you don't want to talk to them, just ignore + /// the request. If the user continues to send you messages, SteamNetworkingMessagesSessionRequest_t + /// callbacks will continue to be posted periodically. + /// + /// Returns false if there is no session with the user pending or otherwise. If there is an + /// existing active session, this function will return true, even if it is not pending. + /// + /// Calling SendMessageToUser() will implicitly accepts any pending session request to that user. + virtual bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0; + + /// Call this when you're done talking to a user to immediately free up resources under-the-hood. + /// If the remote user tries to send data to you again, another SteamNetworkingMessagesSessionRequest_t + /// callback will be posted. + /// + /// Note that sessions that go unused for a few minutes are automatically timed out. + virtual bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0; + + /// Call this when you're done talking to a user on a specific channel. Once all + /// open channels to a user have been closed, the open session to the user will be + /// closed, and any new data from this user will trigger a + /// SteamSteamNetworkingMessagesSessionRequest_t callback + virtual bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nLocalChannel ) = 0; + + /// Returns information about the latest state of a connection, if any, with the given peer. + /// Primarily intended for debugging purposes, but can also be used to get more detailed + /// failure information. (See SendMessageToUser and k_nSteamNetworkingSend_AutoRestartBrokenSession.) + /// + /// Returns the value of SteamNetConnectionInfo_t::m_eState, or k_ESteamNetworkingConnectionState_None + /// if no connection exists with specified peer. You may pass nullptr for either parameter if + /// you do not need the corresponding details. Note that sessions time out after a while, + /// so if a connection fails, or SendMessageToUser returns k_EResultNoConnection, you cannot wait + /// indefinitely to obtain the reason for failure. + virtual ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingIdentity &identityRemote, SteamNetConnectionInfo_t *pConnectionInfo, SteamNetConnectionRealTimeStatus_t *pQuickStatus ) = 0; +}; +#define STEAMNETWORKINGMESSAGES_INTERFACE_VERSION "SteamNetworkingMessages002" + +// +// Callbacks +// + +#pragma pack( push, 1 ) + +/// Posted when a remote host is sending us a message, and we do not already have a session with them +struct SteamNetworkingMessagesSessionRequest_t +{ + enum { k_iCallback = k_iSteamNetworkingMessagesCallbacks + 1 }; + SteamNetworkingIdentity m_identityRemote; // user who wants to talk to us +}; + +/// Posted when we fail to establish a connection, or we detect that communications +/// have been disrupted it an unusual way. There is no notification when a peer proactively +/// closes the session. ("Closed by peer" is not a concept of UDP-style communications, and +/// SteamNetworkingMessages is primarily intended to make porting UDP code easy.) +/// +/// Remember: callbacks are asynchronous. See notes on SendMessageToUser, +/// and k_nSteamNetworkingSend_AutoRestartBrokenSession in particular. +/// +/// Also, if a session times out due to inactivity, no callbacks will be posted. The only +/// way to detect that this is happening is that querying the session state may return +/// none, connecting, and findingroute again. +struct SteamNetworkingMessagesSessionFailed_t +{ + enum { k_iCallback = k_iSteamNetworkingMessagesCallbacks + 2 }; + + /// Detailed info about the session that failed. + /// SteamNetConnectionInfo_t::m_identityRemote indicates who this session + /// was with. + SteamNetConnectionInfo_t m_info; +}; + +#pragma pack(pop) + +// Global accessors + +// Using standalone lib +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB + + static_assert( STEAMNETWORKINGMESSAGES_INTERFACE_VERSION[25] == '2', "Version mismatch" ); + + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages_LibV2(); + inline ISteamNetworkingMessages *SteamNetworkingMessages_Lib() { return SteamNetworkingMessages_LibV2(); } + + // If running in context of steam, we also define a gameserver instance. + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamGameServerNetworkingMessages_LibV2(); + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages_Lib() { return SteamGameServerNetworkingMessages_LibV2(); } + + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_LibV2(); } + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_LibV2(); } + #endif +#endif + +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI + + // Steamworks SDK + STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamNetworkingMessages_SteamAPI, STEAMNETWORKINGMESSAGES_INTERFACE_VERSION ); + STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamGameServerNetworkingMessages_SteamAPI, STEAMNETWORKINGMESSAGES_INTERFACE_VERSION ); + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_SteamAPI(); } + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_SteamAPI(); } + #endif +#endif + +#endif // ISTEAMNETWORKINGMESSAGES diff --git a/public/steam/isteamnetworkingsockets.h b/public/steam/isteamnetworkingsockets.h new file mode 100644 index 00000000..b4e9ec33 --- /dev/null +++ b/public/steam/isteamnetworkingsockets.h @@ -0,0 +1,1031 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== + +#ifndef ISTEAMNETWORKINGSOCKETS +#define ISTEAMNETWORKINGSOCKETS +#pragma once + +#include "steamnetworkingtypes.h" +#include "steam_api_common.h" + +struct SteamNetAuthenticationStatus_t; +struct SteamNetworkingFakeIPResult_t; +class ISteamNetworkingConnectionSignaling; +class ISteamNetworkingSignalingRecvContext; +class ISteamNetworkingFakeUDPPort; + +//----------------------------------------------------------------------------- +/// Lower level networking API. +/// +/// - Connection-oriented API (like TCP, not UDP). When sending and receiving +/// messages, a connection handle is used. (For a UDP-style interface, where +/// the peer is identified by their address with each send/recv call, see +/// ISteamNetworkingMessages.) The typical pattern is for a "server" to "listen" +/// on a "listen socket." A "client" will "connect" to the server, and the +/// server will "accept" the connection. If you have a symmetric situation +/// where either peer may initiate the connection and server/client roles are +/// not clearly defined, check out k_ESteamNetworkingConfig_SymmetricConnect. +/// - But unlike TCP, it's message-oriented, not stream-oriented. +/// - Mix of reliable and unreliable messages +/// - Fragmentation and reassembly +/// - Supports connectivity over plain UDP +/// - Also supports SDR ("Steam Datagram Relay") connections, which are +/// addressed by the identity of the peer. There is a "P2P" use case and +/// a "hosted dedicated server" use case. +/// +/// Note that neither of the terms "connection" nor "socket" necessarily correspond +/// one-to-one with an underlying UDP socket. An attempt has been made to +/// keep the semantics as similar to the standard socket model when appropriate, +/// but some deviations do exist. +/// +/// See also: ISteamNetworkingMessages, the UDP-style interface. This API might be +/// easier to use, especially when porting existing UDP code. +class ISteamNetworkingSockets +{ +public: + + /// Creates a "server" socket that listens for clients to connect to by + /// calling ConnectByIPAddress, over ordinary UDP (IPv4 or IPv6) + /// + /// You must select a specific local port to listen on and set it + /// the port field of the local address. + /// + /// Usually you will set the IP portion of the address to zero (SteamNetworkingIPAddr::Clear()). + /// This means that you will not bind to any particular local interface (i.e. the same + /// as INADDR_ANY in plain socket code). Furthermore, if possible the socket will be bound + /// in "dual stack" mode, which means that it can accept both IPv4 and IPv6 client connections. + /// If you really do wish to bind a particular interface, then set the local address to the + /// appropriate IPv4 or IPv6 IP. + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + /// + /// When a client attempts to connect, a SteamNetConnectionStatusChangedCallback_t + /// will be posted. The connection will be in the connecting state. + virtual HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddress, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Creates a connection and begins talking to a "server" over UDP at the + /// given IPv4 or IPv6 address. The remote host must be listening with a + /// matching call to CreateListenSocketIP on the specified port. + /// + /// A SteamNetConnectionStatusChangedCallback_t callback will be triggered when we start + /// connecting, and then another one on either timeout or successful connection. + /// + /// If the server does not have any identity configured, then their network address + /// will be the only identity in use. Or, the network host may provide a platform-specific + /// identity with or without a valid certificate to authenticate that identity. (These + /// details will be contained in the SteamNetConnectionStatusChangedCallback_t.) It's + /// up to your application to decide whether to allow the connection. + /// + /// By default, all connections will get basic encryption sufficient to prevent + /// casual eavesdropping. But note that without certificates (or a shared secret + /// distributed through some other out-of-band mechanism), you don't have any + /// way of knowing who is actually on the other end, and thus are vulnerable to + /// man-in-the-middle attacks. + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Like CreateListenSocketIP, but clients will connect using ConnectP2P. + /// + /// nLocalVirtualPort specifies how clients can connect to this socket using + /// ConnectP2P. It's very common for applications to only have one listening socket; + /// in that case, use zero. If you need to open multiple listen sockets and have clients + /// be able to connect to one or the other, then nLocalVirtualPort should be a small + /// integer (<1000) unique to each listen socket you create. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes. + /// + /// If you are listening on a dedicated servers in known data center, + /// then you can listen using this function instead of CreateHostedDedicatedServerListenSocket, + /// to allow clients to connect without a ticket. Any user that owns + /// the app and is signed into Steam will be able to attempt to connect to + /// your server. Also, a connection attempt may require the client to + /// be connected to Steam, which is one more moving part that may fail. When + /// tickets are used, then once a ticket is obtained, a client can connect to + /// your server even if they got disconnected from Steam or Steam is offline. + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + virtual HSteamListenSocket CreateListenSocketP2P( int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Begin connecting to a peer that is identified using a platform-specific identifier. + /// This uses the default rendezvous service, which depends on the platform and library + /// configuration. (E.g. on Steam, it goes through the steam backend.) + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + /// + /// To use your own signaling service, see: + /// - ConnectP2PCustomSignaling + /// - k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling + virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Accept an incoming connection that has been received on a listen socket. + /// + /// When a connection attempt is received (perhaps after a few basic handshake + /// packets have been exchanged to prevent trivial spoofing), a connection interface + /// object is created in the k_ESteamNetworkingConnectionState_Connecting state + /// and a SteamNetConnectionStatusChangedCallback_t is posted. At this point, your + /// application MUST either accept or close the connection. (It may not ignore it.) + /// Accepting the connection will transition it either into the connected state, + /// or the finding route state, depending on the connection type. + /// + /// You should take action within a second or two, because accepting the connection is + /// what actually sends the reply notifying the client that they are connected. If you + /// delay taking action, from the client's perspective it is the same as the network + /// being unresponsive, and the client may timeout the connection attempt. In other + /// words, the client cannot distinguish between a delay caused by network problems + /// and a delay caused by the application. + /// + /// This means that if your application goes for more than a few seconds without + /// processing callbacks (for example, while loading a map), then there is a chance + /// that a client may attempt to connect in that interval and fail due to timeout. + /// + /// If the application does not respond to the connection attempt in a timely manner, + /// and we stop receiving communication from the client, the connection attempt will + /// be timed out locally, transitioning the connection to the + /// k_ESteamNetworkingConnectionState_ProblemDetectedLocally state. The client may also + /// close the connection before it is accepted, and a transition to the + /// k_ESteamNetworkingConnectionState_ClosedByPeer is also possible depending the exact + /// sequence of events. + /// + /// Returns k_EResultInvalidParam if the handle is invalid. + /// Returns k_EResultInvalidState if the connection is not in the appropriate state. + /// (Remember that the connection state could change in between the time that the + /// notification being posted to the queue and when it is received by the application.) + /// + /// A note about connection configuration options. If you need to set any configuration + /// options that are common to all connections accepted through a particular listen + /// socket, consider setting the options on the listen socket, since such options are + /// inherited automatically. If you really do need to set options that are connection + /// specific, it is safe to set them on the connection before accepting the connection. + virtual EResult AcceptConnection( HSteamNetConnection hConn ) = 0; + + /// Disconnects from the remote host and invalidates the connection handle. + /// Any unread data on the connection is discarded. + /// + /// nReason is an application defined code that will be received on the other + /// end and recorded (when possible) in backend analytics. The value should + /// come from a restricted range. (See ESteamNetConnectionEnd.) If you don't need + /// to communicate any information to the remote host, and do not want analytics to + /// be able to distinguish "normal" connection terminations from "exceptional" ones, + /// You may pass zero, in which case the generic value of + /// k_ESteamNetConnectionEnd_App_Generic will be used. + /// + /// pszDebug is an optional human-readable diagnostic string that will be received + /// by the remote host and recorded (when possible) in backend analytics. + /// + /// If you wish to put the socket into a "linger" state, where an attempt is made to + /// flush any remaining sent data, use bEnableLinger=true. Otherwise reliable data + /// is not flushed. + /// + /// If the connection has already ended and you are just freeing up the + /// connection interface, the reason code, debug string, and linger flag are + /// ignored. + virtual bool CloseConnection( HSteamNetConnection hPeer, int nReason, const char *pszDebug, bool bEnableLinger ) = 0; + + /// Destroy a listen socket. All the connections that were accepting on the listen + /// socket are closed ungracefully. + virtual bool CloseListenSocket( HSteamListenSocket hSocket ) = 0; + + /// Set connection user data. the data is returned in the following places + /// - You can query it using GetConnectionUserData. + /// - The SteamNetworkingmessage_t structure. + /// - The SteamNetConnectionInfo_t structure. + /// (Which is a member of SteamNetConnectionStatusChangedCallback_t -- but see WARNINGS below!!!!) + /// + /// Do you need to set this atomically when the connection is created? + /// See k_ESteamNetworkingConfig_ConnectionUserData. + /// + /// WARNING: Be *very careful* when using the value provided in callbacks structs. + /// Callbacks are queued, and the value that you will receive in your + /// callback is the userdata that was effective at the time the callback + /// was queued. There are subtle race conditions that can hapen if you + /// don't understand this! + /// + /// If any incoming messages for this connection are queued, the userdata + /// field is updated, so that when when you receive messages (e.g. with + /// ReceiveMessagesOnConnection), they will always have the very latest + /// userdata. So the tricky race conditions that can happen with callbacks + /// do not apply to retrieving messages. + /// + /// Returns false if the handle is invalid. + virtual bool SetConnectionUserData( HSteamNetConnection hPeer, int64 nUserData ) = 0; + + /// Fetch connection user data. Returns -1 if handle is invalid + /// or if you haven't set any userdata on the connection. + virtual int64 GetConnectionUserData( HSteamNetConnection hPeer ) = 0; + + /// Set a name for the connection, used mostly for debugging + virtual void SetConnectionName( HSteamNetConnection hPeer, const char *pszName ) = 0; + + /// Fetch connection name. Returns false if handle is invalid + virtual bool GetConnectionName( HSteamNetConnection hPeer, char *pszName, int nMaxLen ) = 0; + + /// Send a message to the remote host on the specified connection. + /// + /// nSendFlags determines the delivery guarantees that will be provided, + /// when data should be buffered, etc. E.g. k_nSteamNetworkingSend_Unreliable + /// + /// Note that the semantics we use for messages are not precisely + /// the same as the semantics of a standard "stream" socket. + /// (SOCK_STREAM) For an ordinary stream socket, the boundaries + /// between chunks are not considered relevant, and the sizes of + /// the chunks of data written will not necessarily match up to + /// the sizes of the chunks that are returned by the reads on + /// the other end. The remote host might read a partial chunk, + /// or chunks might be coalesced. For the message semantics + /// used here, however, the sizes WILL match. Each send call + /// will match a successful read call on the remote host + /// one-for-one. If you are porting existing stream-oriented + /// code to the semantics of reliable messages, your code should + /// work the same, since reliable message semantics are more + /// strict than stream semantics. The only caveat is related to + /// performance: there is per-message overhead to retain the + /// message sizes, and so if your code sends many small chunks + /// of data, performance will suffer. Any code based on stream + /// sockets that does not write excessively small chunks will + /// work without any changes. + /// + /// The pOutMessageNumber is an optional pointer to receive the + /// message number assigned to the message, if sending was successful. + /// + /// Returns: + /// - k_EResultInvalidParam: invalid connection handle, or the individual message is too big. + /// (See k_cbMaxSteamNetworkingSocketsMessageSizeSend) + /// - k_EResultInvalidState: connection is in an invalid state + /// - k_EResultNoConnection: connection has ended + /// - k_EResultIgnored: You used k_nSteamNetworkingSend_NoDelay, and the message was dropped because + /// we were not ready to send it. + /// - k_EResultLimitExceeded: there was already too much data queued to be sent. + /// (See k_ESteamNetworkingConfig_SendBufferSize) + virtual EResult SendMessageToConnection( HSteamNetConnection hConn, const void *pData, uint32 cbData, int nSendFlags, int64 *pOutMessageNumber ) = 0; + + /// Send one or more messages without copying the message payload. + /// This is the most efficient way to send messages. To use this + /// function, you must first allocate a message object using + /// ISteamNetworkingUtils::AllocateMessage. (Do not declare one + /// on the stack or allocate your own.) + /// + /// You should fill in the message payload. You can either let + /// it allocate the buffer for you and then fill in the payload, + /// or if you already have a buffer allocated, you can just point + /// m_pData at your buffer and set the callback to the appropriate function + /// to free it. Note that if you use your own buffer, it MUST remain valid + /// until the callback is executed. And also note that your callback can be + /// invoked at any time from any thread (perhaps even before SendMessages + /// returns!), so it MUST be fast and threadsafe. + /// + /// You MUST also fill in: + /// - m_conn - the handle of the connection to send the message to + /// - m_nFlags - bitmask of k_nSteamNetworkingSend_xxx flags. + /// + /// All other fields are currently reserved and should not be modified. + /// + /// The library will take ownership of the message structures. They may + /// be modified or become invalid at any time, so you must not read them + /// after passing them to this function. + /// + /// pOutMessageNumberOrResult is an optional array that will receive, + /// for each message, the message number that was assigned to the message + /// if sending was successful. If sending failed, then a negative EResult + /// value is placed into the array. For example, the array will hold + /// -k_EResultInvalidState if the connection was in an invalid state. + /// See ISteamNetworkingSockets::SendMessageToConnection for possible + /// failure codes. + virtual void SendMessages( int nMessages, SteamNetworkingMessage_t *const *pMessages, int64 *pOutMessageNumberOrResult ) = 0; + + /// Flush any messages waiting on the Nagle timer and send them + /// at the next transmission opportunity (often that means right now). + /// + /// If Nagle is enabled (it's on by default) then when calling + /// SendMessageToConnection the message will be buffered, up to the Nagle time + /// before being sent, to merge small messages into the same packet. + /// (See k_ESteamNetworkingConfig_NagleTime) + /// + /// Returns: + /// k_EResultInvalidParam: invalid connection handle + /// k_EResultInvalidState: connection is in an invalid state + /// k_EResultNoConnection: connection has ended + /// k_EResultIgnored: We weren't (yet) connected, so this operation has no effect. + virtual EResult FlushMessagesOnConnection( HSteamNetConnection hConn ) = 0; + + /// Fetch the next available message(s) from the connection, if any. + /// Returns the number of messages returned into your array, up to nMaxMessages. + /// If the connection handle is invalid, -1 is returned. + /// + /// The order of the messages returned in the array is relevant. + /// Reliable messages will be received in the order they were sent (and with the + /// same sizes --- see SendMessageToConnection for on this subtle difference from a stream socket). + /// + /// Unreliable messages may be dropped, or delivered out of order with respect to + /// each other or with respect to reliable messages. The same unreliable message + /// may be received multiple times. + /// + /// If any messages are returned, you MUST call SteamNetworkingMessage_t::Release() on each + /// of them free up resources after you are done. It is safe to keep the object alive for + /// a little while (put it into some queue, etc), and you may call Release() from any thread. + virtual int ReceiveMessagesOnConnection( HSteamNetConnection hConn, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + /// Returns basic information about the high-level state of the connection. + virtual bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) = 0; + + /// Returns a small set of information about the real-time state of the connection + /// and the queue status of each lane. + /// + /// - pStatus may be NULL if the information is not desired. (E.g. you are only interested + /// in the lane information.) + /// - On entry, nLanes specifies the length of the pLanes array. This may be 0 + /// if you do not wish to receive any lane data. It's OK for this to be smaller than + /// the total number of configured lanes. + /// - pLanes points to an array that will receive lane-specific info. It can be NULL + /// if this is not needed. + /// + /// Return value: + /// - k_EResultNoConnection - connection handle is invalid or connection has been closed. + /// - k_EResultInvalidParam - nLanes is bad + virtual EResult GetConnectionRealTimeStatus( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus, + int nLanes, SteamNetConnectionRealTimeLaneStatus_t *pLanes ) = 0; + + /// Returns detailed connection stats in text format. Useful + /// for dumping to a log, etc. + /// + /// Returns: + /// -1 failure (bad connection handle) + /// 0 OK, your buffer was filled in and '\0'-terminated + /// >0 Your buffer was either nullptr, or it was too small and the text got truncated. + /// Try again with a buffer of at least N bytes. + virtual int GetDetailedConnectionStatus( HSteamNetConnection hConn, char *pszBuf, int cbBuf ) = 0; + + /// Returns local IP and port that a listen socket created using CreateListenSocketIP is bound to. + /// + /// An IPv6 address of ::0 means "any IPv4 or IPv6" + /// An IPv6 address of ::ffff:0000:0000 means "any IPv4" + virtual bool GetListenSocketAddress( HSteamListenSocket hSocket, SteamNetworkingIPAddr *address ) = 0; + + /// Create a pair of connections that are talking to each other, e.g. a loopback connection. + /// This is very useful for testing, or so that your client/server code can work the same + /// even when you are running a local "server". + /// + /// The two connections will immediately be placed into the connected state, and no callbacks + /// will be posted immediately. After this, if you close either connection, the other connection + /// will receive a callback, exactly as if they were communicating over the network. You must + /// close *both* sides in order to fully clean up the resources! + /// + /// By default, internal buffers are used, completely bypassing the network, the chopping up of + /// messages into packets, encryption, copying the payload, etc. This means that loopback + /// packets, by default, will not simulate lag or loss. Passing true for bUseNetworkLoopback will + /// cause the socket pair to send packets through the local network loopback device (127.0.0.1) + /// on ephemeral ports. Fake lag and loss are supported in this case, and CPU time is expended + /// to encrypt and decrypt. + /// + /// If you wish to assign a specific identity to either connection, you may pass a particular + /// identity. Otherwise, if you pass nullptr, the respective connection will assume a generic + /// "localhost" identity. If you use real network loopback, this might be translated to the + /// actual bound loopback port. Otherwise, the port will be zero. + virtual bool CreateSocketPair( HSteamNetConnection *pOutConnection1, HSteamNetConnection *pOutConnection2, bool bUseNetworkLoopback, const SteamNetworkingIdentity *pIdentity1, const SteamNetworkingIdentity *pIdentity2 ) = 0; + + /// Configure multiple outbound messages streams ("lanes") on a connection, and + /// control head-of-line blocking between them. Messages within a given lane + /// are always sent in the order they are queued, but messages from different + /// lanes may be sent out of order. Each lane has its own message number + /// sequence. The first message sent on each lane will be assigned the number 1. + /// + /// Each lane has a "priority". Lower priority lanes will only be processed + /// when all higher-priority lanes are empty. The magnitudes of the priority + /// values are not relevant, only their sort order. Higher numeric values + /// take priority over lower numeric values. + /// + /// Each lane also is assigned a weight, which controls the approximate proportion + /// of the bandwidth that will be consumed by the lane, relative to other lanes + /// of the same priority. (This is assuming the lane stays busy. An idle lane + /// does not build up "credits" to be be spent once a message is queued.) + /// This value is only meaningful as a proportion, relative to other lanes with + /// the same priority. For lanes with different priorities, the strict priority + /// order will prevail, and their weights relative to each other are not relevant. + /// Thus, if a lane has a unique priority value, the weight value for that lane is + /// not relevant. + /// + /// Example: 3 lanes, with priorities [ 0, 10, 10 ] and weights [ (NA), 20, 5 ]. + /// Messages sent on the first will always be sent first, before messages in the + /// other two lanes. Its weight value is irrelevant, since there are no other + /// lanes with priority=0. The other two lanes will share bandwidth, with the second + /// and third lanes sharing bandwidth using a ratio of approximately 4:1. + /// (The weights [ NA, 4, 1 ] would be equivalent.) + /// + /// Notes: + /// - At the time of this writing, some code has performance cost that is linear + /// in the number of lanes, so keep the number of lanes to an absolute minimum. + /// 3 or so is fine; >8 is a lot. The max number of lanes on Steam is 255, + /// which is a very large number and not recommended! If you are compiling this + /// library from source, see STEAMNETWORKINGSOCKETS_MAX_LANES.) + /// - Lane priority values may be any int. Their absolute value is not relevant, + /// only the order matters. + /// - Weights must be positive, and due to implementation details, they are restricted + /// to 16-bit values. The absolute magnitudes don't matter, just the proportions. + /// - Messages sent on a lane index other than 0 have a small overhead on the wire, + /// so for maximum wire efficiency, lane 0 should be the "most common" lane, regardless + /// of priorities or weights. + /// - A connection has a single lane by default. Calling this function with + /// nNumLanes=1 is legal, but pointless, since the priority and weight values are + /// irrelevant in that case. + /// - You may reconfigure connection lanes at any time, however reducing the number of + /// lanes is not allowed. + /// - Reconfiguring lanes might restart any bandwidth sharing balancing. Usually you + /// will call this function once, near the start of the connection, perhaps after + /// exchanging a few messages. + /// - To assign all lanes the same priority, you may use pLanePriorities=NULL. + /// - If you wish all lanes with the same priority to share bandwidth equally (or + /// if no two lanes have the same priority value, and thus priority values are + /// irrelevant), you may use pLaneWeights=NULL + /// - Priorities and weights determine the order that messages are SENT on the wire. + /// There are NO GUARANTEES on the order that messages are RECEIVED! Due to packet + /// loss, out-of-order delivery, and subtle details of packet serialization, messages + /// might still be received slightly out-of-order! The *only* strong guarantee is that + /// *reliable* messages on the *same lane* will be delivered in the order they are sent. + /// - Each host configures the lanes for the packets they send; the lanes for the flow + /// in one direction are completely unrelated to the lanes in the opposite direction. + /// + /// Return value: + /// - k_EResultNoConnection - bad hConn + /// - k_EResultInvalidParam - Invalid number of lanes, bad weights, or you tried to reduce the number of lanes + /// - k_EResultInvalidState - Connection is already dead, etc + /// + /// See also: + /// SteamNetworkingMessage_t::m_idxLane + virtual EResult ConfigureConnectionLanes( HSteamNetConnection hConn, int nNumLanes, const int *pLanePriorities, const uint16 *pLaneWeights ) = 0; + + // + // Identity and authentication + // + + /// Get the identity assigned to this interface. + /// E.g. on Steam, this is the user's SteamID, or for the gameserver interface, the SteamID assigned + /// to the gameserver. Returns false and sets the result to an invalid identity if we don't know + /// our identity yet. (E.g. GameServer has not logged in. On Steam, the user will know their SteamID + /// even if they are not signed into Steam.) + virtual bool GetIdentity( SteamNetworkingIdentity *pIdentity ) = 0; + + /// Indicate our desire to be ready participate in authenticated communications. + /// If we are currently not ready, then steps will be taken to obtain the necessary + /// certificates. (This includes a certificate for us, as well as any CA certificates + /// needed to authenticate peers.) + /// + /// You can call this at program init time if you know that you are going to + /// be making authenticated connections, so that we will be ready immediately when + /// those connections are attempted. (Note that essentially all connections require + /// authentication, with the exception of ordinary UDP connections with authentication + /// disabled using k_ESteamNetworkingConfig_IP_AllowWithoutAuth.) If you don't call + /// this function, we will wait until a feature is utilized that that necessitates + /// these resources. + /// + /// You can also call this function to force a retry, if failure has occurred. + /// Once we make an attempt and fail, we will not automatically retry. + /// In this respect, the behavior of the system after trying and failing is the same + /// as before the first attempt: attempting authenticated communication or calling + /// this function will call the system to attempt to acquire the necessary resources. + /// + /// You can use GetAuthenticationStatus or listen for SteamNetAuthenticationStatus_t + /// to monitor the status. + /// + /// Returns the current value that would be returned from GetAuthenticationStatus. + virtual ESteamNetworkingAvailability InitAuthentication() = 0; + + /// Query our readiness to participate in authenticated communications. A + /// SteamNetAuthenticationStatus_t callback is posted any time this status changes, + /// but you can use this function to query it at any time. + /// + /// The value of SteamNetAuthenticationStatus_t::m_eAvail is returned. If you only + /// want this high level status, you can pass NULL for pDetails. If you want further + /// details, pass non-NULL to receive them. + virtual ESteamNetworkingAvailability GetAuthenticationStatus( SteamNetAuthenticationStatus_t *pDetails ) = 0; + + // + // Poll groups. A poll group is a set of connections that can be polled efficiently. + // (In our API, to "poll" a connection means to retrieve all pending messages. We + // actually don't have an API to "poll" the connection *state*, like BSD sockets.) + // + + /// Create a new poll group. + /// + /// You should destroy the poll group when you are done using DestroyPollGroup + virtual HSteamNetPollGroup CreatePollGroup() = 0; + + /// Destroy a poll group created with CreatePollGroup(). + /// + /// If there are any connections in the poll group, they are removed from the group, + /// and left in a state where they are not part of any poll group. + /// Returns false if passed an invalid poll group handle. + virtual bool DestroyPollGroup( HSteamNetPollGroup hPollGroup ) = 0; + + /// Assign a connection to a poll group. Note that a connection may only belong to a + /// single poll group. Adding a connection to a poll group implicitly removes it from + /// any other poll group it is in. + /// + /// You can pass k_HSteamNetPollGroup_Invalid to remove a connection from its current + /// poll group without adding it to a new poll group. + /// + /// If there are received messages currently pending on the connection, an attempt + /// is made to add them to the queue of messages for the poll group in approximately + /// the order that would have applied if the connection was already part of the poll + /// group at the time that the messages were received. + /// + /// Returns false if the connection handle is invalid, or if the poll group handle + /// is invalid (and not k_HSteamNetPollGroup_Invalid). + virtual bool SetConnectionPollGroup( HSteamNetConnection hConn, HSteamNetPollGroup hPollGroup ) = 0; + + /// Same as ReceiveMessagesOnConnection, but will return the next messages available + /// on any connection in the poll group. Examine SteamNetworkingMessage_t::m_conn + /// to know which connection. (SteamNetworkingMessage_t::m_nConnUserData might also + /// be useful.) + /// + /// Delivery order of messages among different connections will usually match the + /// order that the last packet was received which completed the message. But this + /// is not a strong guarantee, especially for packets received right as a connection + /// is being assigned to poll group. + /// + /// Delivery order of messages on the same connection is well defined and the + /// same guarantees are present as mentioned in ReceiveMessagesOnConnection. + /// (But the messages are not grouped by connection, so they will not necessarily + /// appear consecutively in the list; they may be interleaved with messages for + /// other connections.) + virtual int ReceiveMessagesOnPollGroup( HSteamNetPollGroup hPollGroup, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + // + // Clients connecting to dedicated servers hosted in a data center, + // using tickets issued by your game coordinator. If you are not + // issuing your own tickets to restrict who can attempt to connect + // to your server, then you won't use these functions. + // + + /// Call this when you receive a ticket from your backend / matchmaking system. Puts the + /// ticket into a persistent cache, and optionally returns the parsed ticket. + /// + /// See stamdatagram_ticketgen.h for more details. + virtual bool ReceivedRelayAuthTicket( const void *pvTicket, int cbTicket, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0; + + /// Search cache for a ticket to talk to the server on the specified virtual port. + /// If found, returns the number of seconds until the ticket expires, and optionally + /// the complete cracked ticket. Returns 0 if we don't have a ticket. + /// + /// Typically this is useful just to confirm that you have a ticket, before you + /// call ConnectToHostedDedicatedServer to connect to the server. + virtual int FindRelayAuthTicketForServer( const SteamNetworkingIdentity &identityGameServer, int nRemoteVirtualPort, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0; + + /// Client call to connect to a server hosted in a Valve data center, on the specified virtual + /// port. You must have placed a ticket for this server into the cache, or else this connect + /// attempt will fail! If you are not issuing your own tickets, then to connect to a dedicated + /// server via SDR in auto-ticket mode, use ConnectP2P. (The server must be configured to allow + /// this type of connection by listening using CreateListenSocketP2P.) + /// + /// You may wonder why tickets are stored in a cache, instead of simply being passed as an argument + /// here. The reason is to make reconnection to a gameserver robust, even if the client computer loses + /// connection to Steam or the central backend, or the app is restarted or crashes, etc. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + virtual HSteamNetConnection ConnectToHostedDedicatedServer( const SteamNetworkingIdentity &identityTarget, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + // + // Servers hosted in data centers known to the Valve relay network + // + + /// Returns the value of the SDR_LISTEN_PORT environment variable. This + /// is the UDP server your server will be listening on. This will + /// configured automatically for you in production environments. + /// + /// In development, you'll need to set it yourself. See + /// https://partner.steamgames.com/doc/api/ISteamNetworkingSockets + /// for more information on how to configure dev environments. + virtual uint16 GetHostedDedicatedServerPort() = 0; + + /// Returns 0 if SDR_LISTEN_PORT is not set. Otherwise, returns the data center the server + /// is running in. This will be k_SteamDatagramPOPID_dev in non-production environment. + virtual SteamNetworkingPOPID GetHostedDedicatedServerPOPID() = 0; + + /// Return info about the hosted server. This contains the PoPID of the server, + /// and opaque routing information that can be used by the relays to send traffic + /// to your server. + /// + /// You will need to send this information to your backend, and put it in tickets, + /// so that the relays will know how to forward traffic from + /// clients to your server. See SteamDatagramRelayAuthTicket for more info. + /// + /// Also, note that the routing information is contained in SteamDatagramGameCoordinatorServerLogin, + /// so if possible, it's preferred to use GetGameCoordinatorServerLogin to send this info + /// to your game coordinator service, and also login securely at the same time. + /// + /// On a successful exit, k_EResultOK is returned + /// + /// Unsuccessful exit: + /// - Something other than k_EResultOK is returned. + /// - k_EResultInvalidState: We are not configured to listen for SDR (SDR_LISTEN_SOCKET + /// is not set.) + /// - k_EResultPending: we do not (yet) have the authentication information needed. + /// (See GetAuthenticationStatus.) If you use environment variables to pre-fetch + /// the network config, this data should always be available immediately. + /// - A non-localized diagnostic debug message will be placed in m_data that describes + /// the cause of the failure. + /// + /// NOTE: The returned blob is not encrypted. Send it to your backend, but don't + /// directly share it with clients. + virtual EResult GetHostedDedicatedServerAddress( SteamDatagramHostedAddress *pRouting ) = 0; + + /// Create a listen socket on the specified virtual port. The physical UDP port to use + /// will be determined by the SDR_LISTEN_PORT environment variable. If a UDP port is not + /// configured, this call will fail. + /// + /// This call MUST be made through the SteamGameServerNetworkingSockets() interface. + /// + /// This function should be used when you are using the ticket generator library + /// to issue your own tickets. Clients connecting to the server on this virtual + /// port will need a ticket, and they must connect using ConnectToHostedDedicatedServer. + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + virtual HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Generate an authentication blob that can be used to securely login with + /// your backend, using SteamDatagram_ParseHostedServerLogin. (See + /// steamdatagram_gamecoordinator.h) + /// + /// Before calling the function: + /// - Populate the app data in pLoginInfo (m_cbAppData and m_appData). You can leave + /// all other fields uninitialized. + /// - *pcbSignedBlob contains the size of the buffer at pBlob. (It should be + /// at least k_cbMaxSteamDatagramGameCoordinatorServerLoginSerialized.) + /// + /// On a successful exit: + /// - k_EResultOK is returned + /// - All of the remaining fields of pLoginInfo will be filled out. + /// - *pcbSignedBlob contains the size of the serialized blob that has been + /// placed into pBlob. + /// + /// Unsuccessful exit: + /// - Something other than k_EResultOK is returned. + /// - k_EResultNotLoggedOn: you are not logged in (yet) + /// - See GetHostedDedicatedServerAddress for more potential failure return values. + /// - A non-localized diagnostic debug message will be placed in pBlob that describes + /// the cause of the failure. + /// + /// This works by signing the contents of the SteamDatagramGameCoordinatorServerLogin + /// with the cert that is issued to this server. In dev environments, it's OK if you do + /// not have a cert. (You will need to enable insecure dev login in SteamDatagram_ParseHostedServerLogin.) + /// Otherwise, you will need a signed cert. + /// + /// NOTE: The routing blob returned here is not encrypted. Send it to your backend + /// and don't share it directly with clients. + virtual EResult GetGameCoordinatorServerLogin( SteamDatagramGameCoordinatorServerLogin *pLoginInfo, int *pcbSignedBlob, void *pBlob ) = 0; + + + // + // Relayed connections using custom signaling protocol + // + // This is used if you have your own method of sending out-of-band + // signaling / rendezvous messages through a mutually trusted channel. + // + + /// Create a P2P "client" connection that does signaling over a custom + /// rendezvous/signaling channel. + /// + /// pSignaling points to a new object that you create just for this connection. + /// It must stay valid until Release() is called. Once you pass the + /// object to this function, it assumes ownership. Release() will be called + /// from within the function call if the call fails. Furthermore, until Release() + /// is called, you should be prepared for methods to be invoked on your + /// object from any thread! You need to make sure your object is threadsafe! + /// Furthermore, you should make sure that dispatching the methods is done + /// as quickly as possible. + /// + /// This function will immediately construct a connection in the "connecting" + /// state. Soon after (perhaps before this function returns, perhaps in another thread), + /// the connection will begin sending signaling messages by calling + /// ISteamNetworkingConnectionSignaling::SendSignal. + /// + /// When the remote peer accepts the connection (See + /// ISteamNetworkingSignalingRecvContext::OnConnectRequest), + /// it will begin sending signaling messages. When these messages are received, + /// you can pass them to the connection using ReceivedP2PCustomSignal. + /// + /// If you know the identity of the peer that you expect to be on the other end, + /// you can pass their identity to improve debug output or just detect bugs. + /// If you don't know their identity yet, you can pass NULL, and their + /// identity will be established in the connection handshake. + /// + /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() + /// when your app initializes + /// + /// If you need to set any initial config options, pass them here. See + /// SteamNetworkingConfigValue_t for more about why this is preferable to + /// setting the options "immediately" after creation. + virtual HSteamNetConnection ConnectP2PCustomSignaling( ISteamNetworkingConnectionSignaling *pSignaling, const SteamNetworkingIdentity *pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// Called when custom signaling has received a message. When your + /// signaling channel receives a message, it should save off whatever + /// routing information was in the envelope into the context object, + /// and then pass the payload to this function. + /// + /// A few different things can happen next, depending on the message: + /// + /// - If the signal is associated with existing connection, it is dealt + /// with immediately. If any replies need to be sent, they will be + /// dispatched using the ISteamNetworkingConnectionSignaling + /// associated with the connection. + /// - If the message represents a connection request (and the request + /// is not redundant for an existing connection), a new connection + /// will be created, and ReceivedConnectRequest will be called on your + /// context object to determine how to proceed. + /// - Otherwise, the message is for a connection that does not + /// exist (anymore). In this case, we *may* call SendRejectionReply + /// on your context object. + /// + /// In any case, we will not save off pContext or access it after this + /// function returns. + /// + /// Returns true if the message was parsed and dispatched without anything + /// unusual or suspicious happening. Returns false if there was some problem + /// with the message that prevented ordinary handling. (Debug output will + /// usually have more information.) + /// + /// If you expect to be using relayed connections, then you probably want + /// to call ISteamNetworkingUtils::InitRelayNetworkAccess() when your app initializes + virtual bool ReceivedP2PCustomSignal( const void *pMsg, int cbMsg, ISteamNetworkingSignalingRecvContext *pContext ) = 0; + + // + // Certificate provision by the application. On Steam, we normally handle all this automatically + // and you will not need to use these advanced functions. + // + + /// Get blob that describes a certificate request. You can send this to your game coordinator. + /// Upon entry, *pcbBlob should contain the size of the buffer. On successful exit, it will + /// return the number of bytes that were populated. You can pass pBlob=NULL to query for the required + /// size. (512 bytes is a conservative estimate.) + /// + /// Pass this blob to your game coordinator and call SteamDatagram_CreateCert. + virtual bool GetCertificateRequest( int *pcbBlob, void *pBlob, SteamNetworkingErrMsg &errMsg ) = 0; + + /// Set the certificate. The certificate blob should be the output of + /// SteamDatagram_CreateCert. + virtual bool SetCertificate( const void *pCertificate, int cbCertificate, SteamNetworkingErrMsg &errMsg ) = 0; + + /// Reset the identity associated with this instance. + /// Any open connections are closed. Any previous certificates, etc are discarded. + /// You can pass a specific identity that you want to use, or you can pass NULL, + /// in which case the identity will be invalid until you set it using SetCertificate + /// + /// NOTE: This function is not actually supported on Steam! It is included + /// for use on other platforms where the active user can sign out and + /// a new user can sign in. + virtual void ResetIdentity( const SteamNetworkingIdentity *pIdentity ) = 0; + + // + // Misc + // + + /// Invoke all callback functions queued for this interface. + /// See k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, etc + /// + /// You don't need to call this if you are using Steam's callback dispatch + /// mechanism (SteamAPI_RunCallbacks and SteamGameserver_RunCallbacks). + virtual void RunCallbacks() = 0; + + // + // "FakeIP" system. + // + // A FakeIP is essentially a temporary, arbitrary identifier that + // happens to be a valid IPv4 address. The purpose of this system is to make it + // easy to integrate with existing code that identifies hosts using IPv4 addresses. + // The FakeIP address will never actually be used to send or receive any packets + // on the Internet, it is strictly an identifier. + // + // FakeIP addresses are designed to (hopefully) pass through existing code as + // transparently as possible, while conflicting with "real" addresses that might + // be in use on networks (both the Internet and LANs) in the same code as little + // as possible. At the time this comment is being written, they come from the + // 169.254.0.0/16 range, and the port number will always be >1024. HOWEVER, + // this is subject to change! Do not make assumptions about these addresses, + // or your code might break in the future. In particular, you should use + // functions such as ISteamNetworkingUtils::IsFakeIP to determine if an IP + // address is a "fake" one used by this system. + // + + /// Begin asynchronous process of allocating a fake IPv4 address that other + /// peers can use to contact us via P2P. IP addresses returned by this + /// function are globally unique for a given appid. + /// + /// nNumPorts is the numbers of ports you wish to reserve. This is useful + /// for the same reason that listening on multiple UDP ports is useful for + /// different types of traffic. Because these allocations come from a global + /// namespace, there is a relatively strict limit on the maximum number of + /// ports you may request. (At the time of this writing, the limit is 4.) + /// The Port assignments are *not* guaranteed to have any particular order + /// or relationship! Do *not* assume they are contiguous, even though that + /// may often occur in practice. + /// + /// Returns false if a request was already in progress, true if a new request + /// was started. A SteamNetworkingFakeIPResult_t will be posted when the request + /// completes. + /// + /// For gameservers, you *must* call this after initializing the SDK but before + /// beginning login. Steam needs to know in advance that FakeIP will be used. + /// Everywhere your public IP would normally appear (such as the server browser) will be + /// replaced by the FakeIP, and the fake port at index 0. The request is actually queued + /// until the logon completes, so you must not wait until the allocation completes + /// before logging in. Except for trivial failures that can be detected locally + /// (e.g. invalid parameter), a SteamNetworkingFakeIPResult_t callback (whether success or + /// failure) will not be posted until after we have logged in. Furthermore, it is assumed + /// that FakeIP allocation is essential for your application to function, and so failure + /// will not be reported until *several* retries have been attempted. This process may + /// last several minutes. It is *highly* recommended to treat failure as fatal. + /// + /// To communicate using a connection-oriented (TCP-style) API: + /// - Server creates a listen socket using CreateListenSocketP2PFakeIP + /// - Client connects using ConnectByIPAddress, passing in the FakeIP address. + /// - The connection will behave mostly like a P2P connection. The identities + /// that appear in SteamNetConnectionInfo_t will be the FakeIP identity until + /// we know the real identity. Then it will be the real identity. If the + /// SteamNetConnectionInfo_t::m_addrRemote is valid, it will be a real IPv4 + /// address of a NAT-punched connection. Otherwise, it will not be valid. + /// + /// To communicate using an ad-hoc sendto/recv from (UDP-style) API, + /// use CreateFakeUDPPort. + virtual bool BeginAsyncRequestFakeIP( int nNumPorts ) = 0; + + /// Return info about the FakeIP and port(s) that we have been assigned, + /// if any. idxFirstPort is currently reserved and must be zero. + /// Make sure and check SteamNetworkingFakeIPResult_t::m_eResult + virtual void GetFakeIP( int idxFirstPort, SteamNetworkingFakeIPResult_t *pInfo ) = 0; + + /// Create a listen socket that will listen for P2P connections sent + /// to our FakeIP. A peer can initiate connections to this listen + /// socket by calling ConnectByIPAddress. + /// + /// idxFakePort refers to the *index* of the fake port requested, + /// not the actual port number. For example, pass 0 to refer to the + /// first port in the reservation. You must call this only after calling + /// BeginAsyncRequestFakeIP. However, you do not need to wait for the + /// request to complete before creating the listen socket. + virtual HSteamListenSocket CreateListenSocketP2PFakeIP( int idxFakePort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + + /// If the connection was initiated using the "FakeIP" system, then we + /// we can get an IP address for the remote host. If the remote host had + /// a global FakeIP at the time the connection was established, this + /// function will return that global IP. Otherwise, a FakeIP that is + /// unique locally will be allocated from the local FakeIP address space, + /// and that will be returned. + /// + /// The allocation of local FakeIPs attempts to assign addresses in + /// a consistent manner. If multiple connections are made to the + /// same remote host, they *probably* will return the same FakeIP. + /// However, since the namespace is limited, this cannot be guaranteed. + /// + /// On failure, returns: + /// - k_EResultInvalidParam: invalid connection handle + /// - k_EResultIPNotFound: This connection wasn't made using FakeIP system + virtual EResult GetRemoteFakeIPForConnection( HSteamNetConnection hConn, SteamNetworkingIPAddr *pOutAddr ) = 0; + + /// Get an interface that can be used like a UDP port to send/receive + /// datagrams to a FakeIP address. This is intended to make it easy + /// to port existing UDP-based code to take advantage of SDR. + /// + /// idxFakeServerPort refers to the *index* of the port allocated using + /// BeginAsyncRequestFakeIP and is used to create "server" ports. You may + /// call this before the allocation has completed. However, any attempts + /// to send packets will fail until the allocation has succeeded. When + /// the peer receives packets sent from this interface, the from address + /// of the packet will be the globally-unique FakeIP. If you call this + /// function multiple times and pass the same (nonnegative) fake port index, + /// the same object will be returned, and this object is not reference counted. + /// + /// To create a "client" port (e.g. the equivalent of an ephemeral UDP port) + /// pass -1. In this case, a distinct object will be returned for each call. + /// When the peer receives packets sent from this interface, the peer will + /// assign a FakeIP from its own locally-controlled namespace. + virtual ISteamNetworkingFakeUDPPort *CreateFakeUDPPort( int idxFakeServerPort ) = 0; + +protected: + ~ISteamNetworkingSockets(); // Silence some warnings +}; +#define STEAMNETWORKINGSOCKETS_INTERFACE_VERSION "SteamNetworkingSockets012" + +// Global accessors + +// Using standalone lib +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB + + static_assert( STEAMNETWORKINGSOCKETS_INTERFACE_VERSION[24] == '2', "Version mismatch" ); + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamNetworkingSockets_LibV12(); + inline ISteamNetworkingSockets *SteamNetworkingSockets_Lib() { return SteamNetworkingSockets_LibV12(); } + + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamGameServerNetworkingSockets_LibV12(); + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets_Lib() { return SteamGameServerNetworkingSockets_LibV12(); } + + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingSockets *SteamNetworkingSockets() { return SteamNetworkingSockets_LibV12(); } + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets() { return SteamGameServerNetworkingSockets_LibV12(); } + #endif +#endif + +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI + STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamNetworkingSockets_SteamAPI, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); + STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamGameServerNetworkingSockets_SteamAPI, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingSockets *SteamNetworkingSockets() { return SteamNetworkingSockets_SteamAPI(); } + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets() { return SteamGameServerNetworkingSockets_SteamAPI(); } + #endif +#endif + +/// Callback struct used to notify when a connection has changed state +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error "Must define VALVE_CALLBACK_PACK_SMALL or VALVE_CALLBACK_PACK_LARGE" +#endif + +/// This callback is posted whenever a connection is created, destroyed, or changes state. +/// The m_info field will contain a complete description of the connection at the time the +/// change occurred and the callback was posted. In particular, m_eState will have the +/// new connection state. +/// +/// You will usually need to listen for this callback to know when: +/// - A new connection arrives on a listen socket. +/// m_info.m_hListenSocket will be set, m_eOldState = k_ESteamNetworkingConnectionState_None, +/// and m_info.m_eState = k_ESteamNetworkingConnectionState_Connecting. +/// See ISteamNetworkigSockets::AcceptConnection. +/// - A connection you initiated has been accepted by the remote host. +/// m_eOldState = k_ESteamNetworkingConnectionState_Connecting, and +/// m_info.m_eState = k_ESteamNetworkingConnectionState_Connected. +/// Some connections might transition to k_ESteamNetworkingConnectionState_FindingRoute first. +/// - A connection has been actively rejected or closed by the remote host. +/// m_eOldState = k_ESteamNetworkingConnectionState_Connecting or k_ESteamNetworkingConnectionState_Connected, +/// and m_info.m_eState = k_ESteamNetworkingConnectionState_ClosedByPeer. m_info.m_eEndReason +/// and m_info.m_szEndDebug will have for more details. +/// NOTE: upon receiving this callback, you must still destroy the connection using +/// ISteamNetworkingSockets::CloseConnection to free up local resources. (The details +/// passed to the function are not used in this case, since the connection is already closed.) +/// - A problem was detected with the connection, and it has been closed by the local host. +/// The most common failure is timeout, but other configuration or authentication failures +/// can cause this. m_eOldState = k_ESteamNetworkingConnectionState_Connecting or +/// k_ESteamNetworkingConnectionState_Connected, and m_info.m_eState = k_ESteamNetworkingConnectionState_ProblemDetectedLocally. +/// m_info.m_eEndReason and m_info.m_szEndDebug will have for more details. +/// NOTE: upon receiving this callback, you must still destroy the connection using +/// ISteamNetworkingSockets::CloseConnection to free up local resources. (The details +/// passed to the function are not used in this case, since the connection is already closed.) +/// +/// Remember that callbacks are posted to a queue, and networking connections can +/// change at any time. It is possible that the connection has already changed +/// state by the time you process this callback. +/// +/// Also note that callbacks will be posted when connections are created and destroyed by your own API calls. +struct SteamNetConnectionStatusChangedCallback_t +{ + enum { k_iCallback = k_iSteamNetworkingSocketsCallbacks + 1 }; + + /// Connection handle + HSteamNetConnection m_hConn; + + /// Full connection info + SteamNetConnectionInfo_t m_info; + + /// Previous state. (Current state is in m_info.m_eState) + ESteamNetworkingConnectionState m_eOldState; +}; + +/// A struct used to describe our readiness to participate in authenticated, +/// encrypted communication. In order to do this we need: +/// +/// - The list of trusted CA certificates that might be relevant for this +/// app. +/// - A valid certificate issued by a CA. +/// +/// This callback is posted whenever the state of our readiness changes. +struct SteamNetAuthenticationStatus_t +{ + enum { k_iCallback = k_iSteamNetworkingSocketsCallbacks + 2 }; + + /// Status + ESteamNetworkingAvailability m_eAvail; + + /// Non-localized English language status. For diagnostic/debugging + /// purposes only. + char m_debugMsg[ 256 ]; +}; + +#pragma pack( pop ) + +#endif // ISTEAMNETWORKINGSOCKETS diff --git a/public/steam/isteamnetworkingutils.h b/public/steam/isteamnetworkingutils.h new file mode 100644 index 00000000..626efedf --- /dev/null +++ b/public/steam/isteamnetworkingutils.h @@ -0,0 +1,500 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== +// +// Purpose: misc networking utilities +// +//============================================================================= + +#ifndef ISTEAMNETWORKINGUTILS +#define ISTEAMNETWORKINGUTILS +#pragma once + +#include "steamnetworkingtypes.h" +#include "steam_api_common.h" + +struct SteamDatagramRelayAuthTicket; +struct SteamRelayNetworkStatus_t; + +//----------------------------------------------------------------------------- +/// Misc networking utilities for checking the local networking environment +/// and estimating pings. +class ISteamNetworkingUtils +{ +public: + // + // Efficient message sending + // + + /// Allocate and initialize a message object. Usually the reason + /// you call this is to pass it to ISteamNetworkingSockets::SendMessages. + /// The returned object will have all of the relevant fields cleared to zero. + /// + /// Optionally you can also request that this system allocate space to + /// hold the payload itself. If cbAllocateBuffer is nonzero, the system + /// will allocate memory to hold a payload of at least cbAllocateBuffer bytes. + /// m_pData will point to the allocated buffer, m_cbSize will be set to the + /// size, and m_pfnFreeData will be set to the proper function to free up + /// the buffer. + /// + /// If cbAllocateBuffer=0, then no buffer is allocated. m_pData will be NULL, + /// m_cbSize will be zero, and m_pfnFreeData will be NULL. You will need to + /// set each of these. + virtual SteamNetworkingMessage_t *AllocateMessage( int cbAllocateBuffer ) = 0; + + // + // Access to Steam Datagram Relay (SDR) network + // + + // + // Initialization and status check + // + + /// If you know that you are going to be using the relay network (for example, + /// because you anticipate making P2P connections), call this to initialize the + /// relay network. If you do not call this, the initialization will + /// be delayed until the first time you use a feature that requires access + /// to the relay network, which will delay that first access. + /// + /// You can also call this to force a retry if the previous attempt has failed. + /// Performing any action that requires access to the relay network will also + /// trigger a retry, and so calling this function is never strictly necessary, + /// but it can be useful to call it a program launch time, if access to the + /// relay network is anticipated. + /// + /// Use GetRelayNetworkStatus or listen for SteamRelayNetworkStatus_t + /// callbacks to know when initialization has completed. + /// Typically initialization completes in a few seconds. + /// + /// Note: dedicated servers hosted in known data centers do *not* need + /// to call this, since they do not make routing decisions. However, if + /// the dedicated server will be using P2P functionality, it will act as + /// a "client" and this should be called. + inline void InitRelayNetworkAccess(); + + /// Fetch current status of the relay network. + /// + /// SteamRelayNetworkStatus_t is also a callback. It will be triggered on + /// both the user and gameserver interfaces any time the status changes, or + /// ping measurement starts or stops. + /// + /// SteamRelayNetworkStatus_t::m_eAvail is returned. If you want + /// more details, you can pass a non-NULL value. + virtual ESteamNetworkingAvailability GetRelayNetworkStatus( SteamRelayNetworkStatus_t *pDetails ) = 0; + + // + // "Ping location" functions + // + // We use the ping times to the valve relays deployed worldwide to + // generate a "marker" that describes the location of an Internet host. + // Given two such markers, we can estimate the network latency between + // two hosts, without sending any packets. The estimate is based on the + // optimal route that is found through the Valve network. If you are + // using the Valve network to carry the traffic, then this is precisely + // the ping you want. If you are not, then the ping time will probably + // still be a reasonable estimate. + // + // This is extremely useful to select peers for matchmaking! + // + // The markers can also be converted to a string, so they can be transmitted. + // We have a separate library you can use on your app's matchmaking/coordinating + // server to manipulate these objects. (See steamdatagram_gamecoordinator.h) + + /// Return location info for the current host. Returns the approximate + /// age of the data, in seconds, or -1 if no data is available. + /// + /// It takes a few seconds to initialize access to the relay network. If + /// you call this very soon after calling InitRelayNetworkAccess, + /// the data may not be available yet. + /// + /// This always return the most up-to-date information we have available + /// right now, even if we are in the middle of re-calculating ping times. + virtual float GetLocalPingLocation( SteamNetworkPingLocation_t &result ) = 0; + + /// Estimate the round-trip latency between two arbitrary locations, in + /// milliseconds. This is a conservative estimate, based on routing through + /// the relay network. For most basic relayed connections, this ping time + /// will be pretty accurate, since it will be based on the route likely to + /// be actually used. + /// + /// If a direct IP route is used (perhaps via NAT traversal), then the route + /// will be different, and the ping time might be better. Or it might actually + /// be a bit worse! Standard IP routing is frequently suboptimal! + /// + /// But even in this case, the estimate obtained using this method is a + /// reasonable upper bound on the ping time. (Also it has the advantage + /// of returning immediately and not sending any packets.) + /// + /// In a few cases we might not able to estimate the route. In this case + /// a negative value is returned. k_nSteamNetworkingPing_Failed means + /// the reason was because of some networking difficulty. (Failure to + /// ping, etc) k_nSteamNetworkingPing_Unknown is returned if we cannot + /// currently answer the question for some other reason. + /// + /// Do you need to be able to do this from a backend/matchmaking server? + /// You are looking for the "game coordinator" library. + virtual int EstimatePingTimeBetweenTwoLocations( const SteamNetworkPingLocation_t &location1, const SteamNetworkPingLocation_t &location2 ) = 0; + + /// Same as EstimatePingTime, but assumes that one location is the local host. + /// This is a bit faster, especially if you need to calculate a bunch of + /// these in a loop to find the fastest one. + /// + /// In rare cases this might return a slightly different estimate than combining + /// GetLocalPingLocation with EstimatePingTimeBetweenTwoLocations. That's because + /// this function uses a slightly more complete set of information about what + /// route would be taken. + virtual int EstimatePingTimeFromLocalHost( const SteamNetworkPingLocation_t &remoteLocation ) = 0; + + /// Convert a ping location into a text format suitable for sending over the wire. + /// The format is a compact and human readable. However, it is subject to change + /// so please do not parse it yourself. Your buffer must be at least + /// k_cchMaxSteamNetworkingPingLocationString bytes. + virtual void ConvertPingLocationToString( const SteamNetworkPingLocation_t &location, char *pszBuf, int cchBufSize ) = 0; + + /// Parse back SteamNetworkPingLocation_t string. Returns false if we couldn't understand + /// the string. + virtual bool ParsePingLocationString( const char *pszString, SteamNetworkPingLocation_t &result ) = 0; + + /// Check if the ping data of sufficient recency is available, and if + /// it's too old, start refreshing it. + /// + /// Please only call this function when you *really* do need to force an + /// immediate refresh of the data. (For example, in response to a specific + /// user input to refresh this information.) Don't call it "just in case", + /// before every connection, etc. That will cause extra traffic to be sent + /// for no benefit. The library will automatically refresh the information + /// as needed. + /// + /// Returns true if sufficiently recent data is already available. + /// + /// Returns false if sufficiently recent data is not available. In this + /// case, ping measurement is initiated, if it is not already active. + /// (You cannot restart a measurement already in progress.) + /// + /// You can use GetRelayNetworkStatus or listen for SteamRelayNetworkStatus_t + /// to know when ping measurement completes. + virtual bool CheckPingDataUpToDate( float flMaxAgeSeconds ) = 0; + + // + // List of Valve data centers, and ping times to them. This might + // be useful to you if you are use our hosting, or just need to measure + // latency to a cloud data center where we are running relays. + // + + /// Fetch ping time of best available relayed route from this host to + /// the specified data center. + virtual int GetPingToDataCenter( SteamNetworkingPOPID popID, SteamNetworkingPOPID *pViaRelayPoP ) = 0; + + /// Get *direct* ping time to the relays at the data center. + virtual int GetDirectPingToPOP( SteamNetworkingPOPID popID ) = 0; + + /// Get number of network points of presence in the config + virtual int GetPOPCount() = 0; + + /// Get list of all POP IDs. Returns the number of entries that were filled into + /// your list. + virtual int GetPOPList( SteamNetworkingPOPID *list, int nListSz ) = 0; + + // + // Misc + // + + /// Fetch current timestamp. This timer has the following properties: + /// + /// - Monotonicity is guaranteed. + /// - The initial value will be at least 24*3600*30*1e6, i.e. about + /// 30 days worth of microseconds. In this way, the timestamp value of + /// 0 will always be at least "30 days ago". Also, negative numbers + /// will never be returned. + /// - Wraparound / overflow is not a practical concern. + /// + /// If you are running under the debugger and stop the process, the clock + /// might not advance the full wall clock time that has elapsed between + /// calls. If the process is not blocked from normal operation, the + /// timestamp values will track wall clock time, even if you don't call + /// the function frequently. + /// + /// The value is only meaningful for this run of the process. Don't compare + /// it to values obtained on another computer, or other runs of the same process. + virtual SteamNetworkingMicroseconds GetLocalTimestamp() = 0; + + /// Set a function to receive network-related information that is useful for debugging. + /// This can be very useful during development, but it can also be useful for troubleshooting + /// problems with tech savvy end users. If you have a console or other log that customers + /// can examine, these log messages can often be helpful to troubleshoot network issues. + /// (Especially any warning/error messages.) + /// + /// The detail level indicates what message to invoke your callback on. Lower numeric + /// value means more important, and the value you pass is the lowest priority (highest + /// numeric value) you wish to receive callbacks for. + /// + /// The value here controls the detail level for most messages. You can control the + /// detail level for various subsystems (perhaps only for certain connections) by + /// adjusting the configuration values k_ESteamNetworkingConfig_LogLevel_Xxxxx. + /// + /// Except when debugging, you should only use k_ESteamNetworkingSocketsDebugOutputType_Msg + /// or k_ESteamNetworkingSocketsDebugOutputType_Warning. For best performance, do NOT + /// request a high detail level and then filter out messages in your callback. This incurs + /// all of the expense of formatting the messages, which are then discarded. Setting a high + /// priority value (low numeric value) here allows the library to avoid doing this work. + /// + /// IMPORTANT: This may be called from a service thread, while we own a mutex, etc. + /// Your output function must be threadsafe and fast! Do not make any other + /// Steamworks calls from within the handler. + virtual void SetDebugOutputFunction( ESteamNetworkingSocketsDebugOutputType eDetailLevel, FSteamNetworkingSocketsDebugOutput pfnFunc ) = 0; + + // + // Fake IP + // + // Useful for interfacing with code that assumes peers are identified using an IPv4 address + // + + /// Return true if an IPv4 address is one that might be used as a "fake" one. + /// This function is fast; it just does some logical tests on the IP and does + /// not need to do any lookup operations. + inline bool IsFakeIPv4( uint32 nIPv4 ) { return GetIPv4FakeIPType( nIPv4 ) > k_ESteamNetworkingFakeIPType_NotFake; } + virtual ESteamNetworkingFakeIPType GetIPv4FakeIPType( uint32 nIPv4 ) = 0; + + /// Get the real identity associated with a given FakeIP. + /// + /// On failure, returns: + /// - k_EResultInvalidParam: the IP is not a FakeIP. + /// - k_EResultNoMatch: we don't recognize that FakeIP and don't know the corresponding identity. + /// + /// FakeIP's used by active connections, or the FakeIPs assigned to local identities, + /// will always work. FakeIPs for recently destroyed connections will continue to + /// return results for a little while, but not forever. At some point, we will forget + /// FakeIPs to save space. It's reasonably safe to assume that you can read back the + /// real identity of a connection very soon after it is destroyed. But do not wait + /// indefinitely. + virtual EResult GetRealIdentityForFakeIP( const SteamNetworkingIPAddr &fakeIP, SteamNetworkingIdentity *pOutRealIdentity ) = 0; + + // + // Set and get configuration values, see ESteamNetworkingConfigValue for individual descriptions. + // + + // Shortcuts for common cases. (Implemented as inline functions below) + bool SetGlobalConfigValueInt32( ESteamNetworkingConfigValue eValue, int32 val ); + bool SetGlobalConfigValueFloat( ESteamNetworkingConfigValue eValue, float val ); + bool SetGlobalConfigValueString( ESteamNetworkingConfigValue eValue, const char *val ); + bool SetGlobalConfigValuePtr( ESteamNetworkingConfigValue eValue, void *val ); + bool SetConnectionConfigValueInt32( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, int32 val ); + bool SetConnectionConfigValueFloat( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, float val ); + bool SetConnectionConfigValueString( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, const char *val ); + + // + // Set global callbacks. If you do not want to use Steam's callback dispatch mechanism and you + // want to use the same callback on all (or most) listen sockets and connections, then + // simply install these callbacks first thing, and you are good to go. + // See ISteamNetworkingSockets::RunCallbacks + // + bool SetGlobalCallback_SteamNetConnectionStatusChanged( FnSteamNetConnectionStatusChanged fnCallback ); + bool SetGlobalCallback_SteamNetAuthenticationStatusChanged( FnSteamNetAuthenticationStatusChanged fnCallback ); + bool SetGlobalCallback_SteamRelayNetworkStatusChanged( FnSteamRelayNetworkStatusChanged fnCallback ); + bool SetGlobalCallback_FakeIPResult( FnSteamNetworkingFakeIPResult fnCallback ); + bool SetGlobalCallback_MessagesSessionRequest( FnSteamNetworkingMessagesSessionRequest fnCallback ); + bool SetGlobalCallback_MessagesSessionFailed( FnSteamNetworkingMessagesSessionFailed fnCallback ); + + /// Set a configuration value. + /// - eValue: which value is being set + /// - eScope: Onto what type of object are you applying the setting? + /// - scopeArg: Which object you want to change? (Ignored for global scope). E.g. connection handle, listen socket handle, interface pointer, etc. + /// - eDataType: What type of data is in the buffer at pValue? This must match the type of the variable exactly! + /// - pArg: Value to set it to. You can pass NULL to remove a non-global setting at this scope, + /// causing the value for that object to use global defaults. Or at global scope, passing NULL + /// will reset any custom value and restore it to the system default. + /// NOTE: When setting pointers (e.g. callback functions), do not pass the function pointer directly. + /// Your argument should be a pointer to a function pointer. + virtual bool SetConfigValue( ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj, + ESteamNetworkingConfigDataType eDataType, const void *pArg ) = 0; + + /// Set a configuration value, using a struct to pass the value. + /// (This is just a convenience shortcut; see below for the implementation and + /// a little insight into how SteamNetworkingConfigValue_t is used when + /// setting config options during listen socket and connection creation.) + bool SetConfigValueStruct( const SteamNetworkingConfigValue_t &opt, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj ); + + /// Get a configuration value. + /// - eValue: which value to fetch + /// - eScopeType: query setting on what type of object + /// - eScopeArg: the object to query the setting for + /// - pOutDataType: If non-NULL, the data type of the value is returned. + /// - pResult: Where to put the result. Pass NULL to query the required buffer size. (k_ESteamNetworkingGetConfigValue_BufferTooSmall will be returned.) + /// - cbResult: IN: the size of your buffer. OUT: the number of bytes filled in or required. + virtual ESteamNetworkingGetConfigValueResult GetConfigValue( ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj, + ESteamNetworkingConfigDataType *pOutDataType, void *pResult, size_t *cbResult ) = 0; + + /// Get info about a configuration value. Returns the name of the value, + /// or NULL if the value doesn't exist. Other output parameters can be NULL + /// if you do not need them. + virtual const char *GetConfigValueInfo( ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigDataType *pOutDataType, + ESteamNetworkingConfigScope *pOutScope ) = 0; + + /// Iterate the list of all configuration values in the current environment that it might + /// be possible to display or edit using a generic UI. To get the first iterable value, + /// pass k_ESteamNetworkingConfig_Invalid. Returns k_ESteamNetworkingConfig_Invalid + /// to signal end of list. + /// + /// The bEnumerateDevVars argument can be used to include "dev" vars. These are vars that + /// are recommended to only be editable in "debug" or "dev" mode and typically should not be + /// shown in a retail environment where a malicious local user might use this to cheat. + virtual ESteamNetworkingConfigValue IterateGenericEditableConfigValues( ESteamNetworkingConfigValue eCurrent, bool bEnumerateDevVars ) = 0; + + // + // String conversions. You'll usually access these using the respective + // inline methods. + // + virtual void SteamNetworkingIPAddr_ToString( const SteamNetworkingIPAddr &addr, char *buf, size_t cbBuf, bool bWithPort ) = 0; + virtual bool SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr *pAddr, const char *pszStr ) = 0; + virtual ESteamNetworkingFakeIPType SteamNetworkingIPAddr_GetFakeIPType( const SteamNetworkingIPAddr &addr ) = 0; + virtual void SteamNetworkingIdentity_ToString( const SteamNetworkingIdentity &identity, char *buf, size_t cbBuf ) = 0; + virtual bool SteamNetworkingIdentity_ParseString( SteamNetworkingIdentity *pIdentity, const char *pszStr ) = 0; + +protected: + ~ISteamNetworkingUtils(); // Silence some warnings +}; +#define STEAMNETWORKINGUTILS_INTERFACE_VERSION "SteamNetworkingUtils004" + +// Global accessors +// Using standalone lib +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB + + // Standalone lib + static_assert( STEAMNETWORKINGUTILS_INTERFACE_VERSION[22] == '4', "Version mismatch" ); + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingUtils *SteamNetworkingUtils_LibV4(); + inline ISteamNetworkingUtils *SteamNetworkingUtils_Lib() { return SteamNetworkingUtils_LibV4(); } + + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingUtils *SteamNetworkingUtils() { return SteamNetworkingUtils_LibV4(); } + #endif +#endif + +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI + STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamNetworkingUtils *, SteamNetworkingUtils_SteamAPI, + /* Prefer user version of the interface. But if it isn't found, then use + gameserver one. Yes, this is a completely terrible hack */ + SteamInternal_FindOrCreateUserInterface( 0, STEAMNETWORKINGUTILS_INTERFACE_VERSION ) ? + SteamInternal_FindOrCreateUserInterface( 0, STEAMNETWORKINGUTILS_INTERFACE_VERSION ) : + SteamInternal_FindOrCreateGameServerInterface( 0, STEAMNETWORKINGUTILS_INTERFACE_VERSION ), + "global", + STEAMNETWORKINGUTILS_INTERFACE_VERSION + ) + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingUtils *SteamNetworkingUtils() { return SteamNetworkingUtils_SteamAPI(); } + #endif +#endif + +/// A struct used to describe our readiness to use the relay network. +/// To do this we first need to fetch the network configuration, +/// which describes what POPs are available. +struct SteamRelayNetworkStatus_t +{ + enum { k_iCallback = k_iSteamNetworkingUtilsCallbacks + 1 }; + + /// Summary status. When this is "current", initialization has + /// completed. Anything else means you are not ready yet, or + /// there is a significant problem. + ESteamNetworkingAvailability m_eAvail; + + /// Nonzero if latency measurement is in progress (or pending, + /// awaiting a prerequisite). + int m_bPingMeasurementInProgress; + + /// Status obtaining the network config. This is a prerequisite + /// for relay network access. + /// + /// Failure to obtain the network config almost always indicates + /// a problem with the local internet connection. + ESteamNetworkingAvailability m_eAvailNetworkConfig; + + /// Current ability to communicate with ANY relay. Note that + /// the complete failure to communicate with any relays almost + /// always indicates a problem with the local Internet connection. + /// (However, just because you can reach a single relay doesn't + /// mean that the local connection is in perfect health.) + ESteamNetworkingAvailability m_eAvailAnyRelay; + + /// Non-localized English language status. For diagnostic/debugging + /// purposes only. + char m_debugMsg[ 256 ]; +}; + +#ifndef API_GEN + +/// Utility class for printing a SteamNetworkingIdentity. +/// E.g. printf( "Identity is '%s'\n", SteamNetworkingIdentityRender( identity ).c_str() ); +struct SteamNetworkingIdentityRender +{ + SteamNetworkingIdentityRender( const SteamNetworkingIdentity &x ) { x.ToString( buf, sizeof(buf) ); } + inline const char *c_str() const { return buf; } +private: + char buf[ SteamNetworkingIdentity::k_cchMaxString ]; +}; + +/// Utility class for printing a SteamNetworkingIPAddrRender. +struct SteamNetworkingIPAddrRender +{ + SteamNetworkingIPAddrRender( const SteamNetworkingIPAddr &x, bool bWithPort = true ) { x.ToString( buf, sizeof(buf), bWithPort ); } + inline const char *c_str() const { return buf; } +private: + char buf[ SteamNetworkingIPAddr::k_cchMaxString ]; +}; + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Internal stuff + +inline void ISteamNetworkingUtils::InitRelayNetworkAccess() { CheckPingDataUpToDate( 1e10f ); } +inline bool ISteamNetworkingUtils::SetGlobalConfigValueInt32( ESteamNetworkingConfigValue eValue, int32 val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_Int32, &val ); } +inline bool ISteamNetworkingUtils::SetGlobalConfigValueFloat( ESteamNetworkingConfigValue eValue, float val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_Float, &val ); } +inline bool ISteamNetworkingUtils::SetGlobalConfigValueString( ESteamNetworkingConfigValue eValue, const char *val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_String, val ); } +inline bool ISteamNetworkingUtils::SetGlobalConfigValuePtr( ESteamNetworkingConfigValue eValue, void *val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_Ptr, &val ); } // Note: passing pointer to pointer. +inline bool ISteamNetworkingUtils::SetConnectionConfigValueInt32( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, int32 val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Connection, hConn, k_ESteamNetworkingConfig_Int32, &val ); } +inline bool ISteamNetworkingUtils::SetConnectionConfigValueFloat( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, float val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Connection, hConn, k_ESteamNetworkingConfig_Float, &val ); } +inline bool ISteamNetworkingUtils::SetConnectionConfigValueString( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, const char *val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Connection, hConn, k_ESteamNetworkingConfig_String, val ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_SteamNetConnectionStatusChanged( FnSteamNetConnectionStatusChanged fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, (void*)fnCallback ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_SteamNetAuthenticationStatusChanged( FnSteamNetAuthenticationStatusChanged fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_AuthStatusChanged, (void*)fnCallback ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_SteamRelayNetworkStatusChanged( FnSteamRelayNetworkStatusChanged fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged, (void*)fnCallback ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_FakeIPResult( FnSteamNetworkingFakeIPResult fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_FakeIPResult, (void*)fnCallback ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionRequest( FnSteamNetworkingMessagesSessionRequest fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_MessagesSessionRequest, (void*)fnCallback ); } +inline bool ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionFailed( FnSteamNetworkingMessagesSessionFailed fnCallback ) { return SetGlobalConfigValuePtr( k_ESteamNetworkingConfig_Callback_MessagesSessionFailed, (void*)fnCallback ); } + +inline bool ISteamNetworkingUtils::SetConfigValueStruct( const SteamNetworkingConfigValue_t &opt, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj ) +{ + // Locate the argument. Strings are a special case, since the + // "value" (the whole string buffer) doesn't fit in the struct + // NOTE: for pointer values, we pass a pointer to the pointer, + // we do not pass the pointer directly. + const void *pVal = ( opt.m_eDataType == k_ESteamNetworkingConfig_String ) ? (const void *)opt.m_val.m_string : (const void *)&opt.m_val; + return SetConfigValue( opt.m_eValue, eScopeType, scopeObj, opt.m_eDataType, pVal ); +} + +// How to get helper functions. +#if defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) || defined(STEAMNETWORKINGSOCKETS_FOREXPORT) || defined( STEAMNETWORKINGSOCKETS_STANDALONELIB ) + + // Call direct to static functions + STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIPAddr_ToString( const SteamNetworkingIPAddr *pAddr, char *buf, size_t cbBuf, bool bWithPort ); + STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr *pAddr, const char *pszStr ); + STEAMNETWORKINGSOCKETS_INTERFACE ESteamNetworkingFakeIPType SteamNetworkingIPAddr_GetFakeIPType( const SteamNetworkingIPAddr *pAddr ); + STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIdentity_ToString( const SteamNetworkingIdentity *pIdentity, char *buf, size_t cbBuf ); + STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIdentity_ParseString( SteamNetworkingIdentity *pIdentity, size_t sizeofIdentity, const char *pszStr ); + inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingIPAddr_ToString( this, buf, cbBuf, bWithPort ); } + inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingIPAddr_ParseString( this, pszStr ); } + inline ESteamNetworkingFakeIPType SteamNetworkingIPAddr::GetFakeIPType() const { return SteamNetworkingIPAddr_GetFakeIPType( this ); } + inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingIdentity_ToString( this, buf, cbBuf ); } + inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingIdentity_ParseString( this, sizeof(*this), pszStr ); } + +#elif defined( STEAMNETWORKINGSOCKETS_STEAMAPI ) + // Using steamworks SDK - go through SteamNetworkingUtils() + inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingUtils()->SteamNetworkingIPAddr_ToString( *this, buf, cbBuf, bWithPort ); } + inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIPAddr_ParseString( this, pszStr ); } + inline ESteamNetworkingFakeIPType SteamNetworkingIPAddr::GetFakeIPType() const { return SteamNetworkingUtils()->SteamNetworkingIPAddr_GetFakeIPType( *this ); } + inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingUtils()->SteamNetworkingIdentity_ToString( *this, buf, cbBuf ); } + inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIdentity_ParseString( this, pszStr ); } +#else + #error "Invalid config" +#endif + +#endif // ISTEAMNETWORKINGUTILS diff --git a/public/steam/isteamparentalsettings.h b/public/steam/isteamparentalsettings.h new file mode 100644 index 00000000..2a22b01a --- /dev/null +++ b/public/steam/isteamparentalsettings.h @@ -0,0 +1,63 @@ +//====== Copyright � 2013-, Valve Corporation, All rights reserved. ======= +// +// Purpose: Interface to Steam parental settings (Family View) +// +//============================================================================= + +#ifndef ISTEAMPARENTALSETTINGS_H +#define ISTEAMPARENTALSETTINGS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + +// Feature types for parental settings +enum EParentalFeature +{ + k_EFeatureInvalid = 0, + k_EFeatureStore = 1, + k_EFeatureCommunity = 2, + k_EFeatureProfile = 3, + k_EFeatureFriends = 4, + k_EFeatureNews = 5, + k_EFeatureTrading = 6, + k_EFeatureSettings = 7, + k_EFeatureConsole = 8, + k_EFeatureBrowser = 9, + k_EFeatureParentalSetup = 10, + k_EFeatureLibrary = 11, + k_EFeatureTest = 12, + k_EFeatureSiteLicense = 13, + k_EFeatureMax +}; + +class ISteamParentalSettings +{ +public: + virtual bool BIsParentalLockEnabled() = 0; + virtual bool BIsParentalLockLocked() = 0; + + virtual bool BIsAppBlocked( AppId_t nAppID ) = 0; + virtual bool BIsAppInBlockList( AppId_t nAppID ) = 0; + + virtual bool BIsFeatureBlocked( EParentalFeature eFeature ) = 0; + virtual bool BIsFeatureInBlockList( EParentalFeature eFeature ) = 0; +}; + +#define STEAMPARENTALSETTINGS_INTERFACE_VERSION "STEAMPARENTALSETTINGS_INTERFACE_VERSION001" + +// Global interface accessor +inline ISteamParentalSettings *SteamParentalSettings(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamParentalSettings *, SteamParentalSettings, STEAMPARENTALSETTINGS_INTERFACE_VERSION ); + +//----------------------------------------------------------------------------- +// Purpose: Callback for querying UGC +//----------------------------------------------------------------------------- +struct SteamParentalSettingsChanged_t +{ + enum { k_iCallback = k_ISteamParentalSettingsCallbacks + 1 }; +}; + + +#endif // ISTEAMPARENTALSETTINGS_H diff --git a/public/steam/isteamps3overlayrenderer.h b/public/steam/isteamps3overlayrenderer.h new file mode 100644 index 00000000..4e07d4a1 --- /dev/null +++ b/public/steam/isteamps3overlayrenderer.h @@ -0,0 +1,91 @@ +//====== Copyright 1996-2010, Valve Corporation, All rights reserved. ======= +// +// Purpose: interface the game must provide Steam with on PS3 in order for the +// Steam overlay to render. +// +//============================================================================= + +#ifndef ISTEAMPS3OVERLAYRENDERER_H +#define ISTEAMPS3OVERLAYRENDERER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "cell/pad.h" + +//----------------------------------------------------------------------------- +// Purpose: Enum for supported gradient directions +//----------------------------------------------------------------------------- +enum EOverlayGradientDirection +{ + k_EOverlayGradientHorizontal = 1, + k_EOverlayGradientVertical = 2, + k_EOverlayGradientNone = 3, +}; + +// Helpers for fetching individual color components from ARGB packed DWORD colors Steam PS3 overlay renderer uses. +#define STEAM_COLOR_RED( color ) \ + (int)(((color)>>16)&0xff) + +#define STEAM_COLOR_GREEN( color ) \ + (int)(((color)>>8)&0xff) + +#define STEAM_COLOR_BLUE( color ) \ + (int)((color)&0xff) + +#define STEAM_COLOR_ALPHA( color ) \ + (int)(((color)>>24)&0xff) + + +//----------------------------------------------------------------------------- +// Purpose: Interface the game must expose to Steam for rendering +//----------------------------------------------------------------------------- +class ISteamPS3OverlayRenderHost +{ +public: + + // Interface for game engine to implement which Steam requires to render. + + // Draw a textured rect. This may use only part of the texture and will pass texture coords, it will also possibly request a gradient and will specify colors for vertexes. + virtual void DrawTexturedRect( int x0, int y0, int x1, int y1, float u0, float v0, float u1, float v1, int32 iTextureID, DWORD colorStart, DWORD colorEnd, EOverlayGradientDirection eDirection ) = 0; + + // Load a RGBA texture for Steam, or update a previously loaded one. Updates may be partial. You must not evict or remove this texture once Steam has uploaded it. + virtual void LoadOrUpdateTexture( int32 iTextureID, bool bIsFullTexture, int x0, int y0, uint32 uWidth, uint32 uHeight, int32 iBytes, char *pData ) = 0; + + // Delete a texture Steam previously uploaded + virtual void DeleteTexture( int32 iTextureID ) = 0; + + // Delete all previously uploaded textures + virtual void DeleteAllTextures() = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Interface Steam exposes for the game to tell it when to render, etc. +//----------------------------------------------------------------------------- +class ISteamPS3OverlayRender +{ +public: + + // Call once at startup to initialize the Steam overlay and pass it your host interface ptr + virtual bool BHostInitialize( uint32 unScreenWidth, uint32 unScreenHeight, uint32 unRefreshRate, ISteamPS3OverlayRenderHost *pRenderHost, void *CellFontLib ) = 0; + + // Call this once a frame when you are ready for the Steam overlay to render (ie, right before flipping buffers, after all your rendering) + virtual void Render() = 0; + + // Call this everytime you read input on PS3. + // + // If this returns true, then the overlay is active and has consumed the input, your game + // should then ignore all the input until BHandleCellPadData once again returns false, which + // will mean the overlay is deactivated. + virtual bool BHandleCellPadData( const CellPadData &padData ) = 0; + + // Call this if you detect no controllers connected or that the XMB is intercepting input + // + // This is important to clear input state for the overlay, so keys left down during XMB activation + // are not continued to be processed. + virtual bool BResetInputState() = 0; +}; + + +#endif // ISTEAMPS3OVERLAYRENDERER_H \ No newline at end of file diff --git a/public/steam/isteamremoteplay.h b/public/steam/isteamremoteplay.h new file mode 100644 index 00000000..9c2dafb3 --- /dev/null +++ b/public/steam/isteamremoteplay.h @@ -0,0 +1,88 @@ +//============ Copyright (c) Valve Corporation, All rights reserved. ============ + +#ifndef ISTEAMREMOTEPLAY_H +#define ISTEAMREMOTEPLAY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + + +//----------------------------------------------------------------------------- +// Purpose: The form factor of a device +//----------------------------------------------------------------------------- +enum ESteamDeviceFormFactor +{ + k_ESteamDeviceFormFactorUnknown = 0, + k_ESteamDeviceFormFactorPhone = 1, + k_ESteamDeviceFormFactorTablet = 2, + k_ESteamDeviceFormFactorComputer = 3, + k_ESteamDeviceFormFactorTV = 4, +}; + +// Steam Remote Play session ID +typedef uint32 RemotePlaySessionID_t; + + +//----------------------------------------------------------------------------- +// Purpose: Functions to provide information about Steam Remote Play sessions +//----------------------------------------------------------------------------- +class ISteamRemotePlay +{ +public: + // Get the number of currently connected Steam Remote Play sessions + virtual uint32 GetSessionCount() = 0; + + // Get the currently connected Steam Remote Play session ID at the specified index. Returns zero if index is out of bounds. + virtual RemotePlaySessionID_t GetSessionID( int iSessionIndex ) = 0; + + // Get the SteamID of the connected user + virtual CSteamID GetSessionSteamID( RemotePlaySessionID_t unSessionID ) = 0; + + // Get the name of the session client device + // This returns NULL if the sessionID is not valid + virtual const char *GetSessionClientName( RemotePlaySessionID_t unSessionID ) = 0; + + // Get the form factor of the session client device + virtual ESteamDeviceFormFactor GetSessionClientFormFactor( RemotePlaySessionID_t unSessionID ) = 0; + + // Get the resolution, in pixels, of the session client device + // This is set to 0x0 if the resolution is not available + virtual bool BGetSessionClientResolution( RemotePlaySessionID_t unSessionID, int *pnResolutionX, int *pnResolutionY ) = 0; + + // Invite a friend to Remote Play Together + // This returns false if the invite can't be sent + virtual bool BSendRemotePlayTogetherInvite( CSteamID steamIDFriend ) = 0; +}; + +#define STEAMREMOTEPLAY_INTERFACE_VERSION "STEAMREMOTEPLAY_INTERFACE_VERSION001" + +// Global interface accessor +inline ISteamRemotePlay *SteamRemotePlay(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamRemotePlay *, SteamRemotePlay, STEAMREMOTEPLAY_INTERFACE_VERSION ); + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + + +STEAM_CALLBACK_BEGIN( SteamRemotePlaySessionConnected_t, k_iSteamRemotePlayCallbacks + 1 ) + STEAM_CALLBACK_MEMBER( 0, RemotePlaySessionID_t, m_unSessionID ) +STEAM_CALLBACK_END( 0 ) + + +STEAM_CALLBACK_BEGIN( SteamRemotePlaySessionDisconnected_t, k_iSteamRemotePlayCallbacks + 2 ) + STEAM_CALLBACK_MEMBER( 0, RemotePlaySessionID_t, m_unSessionID ) +STEAM_CALLBACK_END( 0 ) + + +#pragma pack( pop ) + + +#endif // #define ISTEAMREMOTEPLAY_H diff --git a/public/steam/isteamremotestorage.h b/public/steam/isteamremotestorage.h index 6853cd6f..01b8dae3 100644 --- a/public/steam/isteamremotestorage.h +++ b/public/steam/isteamremotestorage.h @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" //----------------------------------------------------------------------------- @@ -28,7 +28,7 @@ const uint32 k_unMaxCloudFileChunkSize = 100 * 1024 * 1024; #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif struct SteamParamStringArray_t { @@ -57,12 +57,6 @@ const uint32 k_cchTagListMax = 1024 + 1; const uint32 k_cchFilenameMax = 260; const uint32 k_cchPublishedFileURLMax = 256; -// Ways to handle a synchronization conflict -enum EResolveConflict -{ - k_EResolveConflictKeepClient = 1, // The local version of each file will be used to overwrite the server version - k_EResolveConflictKeepServer = 2, // The server version of each file will be used to overwrite the local version -}; enum ERemoteStoragePlatform { @@ -71,7 +65,10 @@ enum ERemoteStoragePlatform k_ERemoteStoragePlatformOSX = (1 << 1), k_ERemoteStoragePlatformPS3 = (1 << 2), k_ERemoteStoragePlatformLinux = (1 << 3), - k_ERemoteStoragePlatformReserved2 = (1 << 4), + k_ERemoteStoragePlatformSwitch = (1 << 4), + k_ERemoteStoragePlatformAndroid = (1 << 5), + k_ERemoteStoragePlatformIOS = (1 << 6), + // NB we get one more before we need to widen some things k_ERemoteStoragePlatformAll = 0xffffffff }; @@ -81,6 +78,7 @@ enum ERemoteStoragePublishedFileVisibility k_ERemoteStoragePublishedFileVisibilityPublic = 0, k_ERemoteStoragePublishedFileVisibilityFriendsOnly = 1, k_ERemoteStoragePublishedFileVisibilityPrivate = 2, + k_ERemoteStoragePublishedFileVisibilityUnlisted = 3, }; @@ -158,6 +156,28 @@ enum EUGCReadAction k_EUGCRead_Close = 2, }; +enum ERemoteStorageLocalFileChange +{ + k_ERemoteStorageLocalFileChange_Invalid = 0, + + // The file was updated from another device + k_ERemoteStorageLocalFileChange_FileUpdated = 1, + + // The file was deleted by another device + k_ERemoteStorageLocalFileChange_FileDeleted = 2, +}; + +enum ERemoteStorageFilePathType +{ + k_ERemoteStorageFilePathType_Invalid = 0, + + // The file is directly accessed by the game and this is the full path + k_ERemoteStorageFilePathType_Absolute = 1, + + // The file is accessed via the ISteamRemoteStorage API and this is the filename + k_ERemoteStorageFilePathType_APIFilename = 2, +}; + //----------------------------------------------------------------------------- // Purpose: Functions for accessing, reading and writing files stored remotely @@ -176,8 +196,17 @@ class ISteamRemoteStorage // file operations virtual bool FileWrite( const char *pchFile, const void *pvData, int32 cubData ) = 0; virtual int32 FileRead( const char *pchFile, void *pvData, int32 cubDataToRead ) = 0; + + STEAM_CALL_RESULT( RemoteStorageFileWriteAsyncComplete_t ) + virtual SteamAPICall_t FileWriteAsync( const char *pchFile, const void *pvData, uint32 cubData ) = 0; + + STEAM_CALL_RESULT( RemoteStorageFileReadAsyncComplete_t ) + virtual SteamAPICall_t FileReadAsync( const char *pchFile, uint32 nOffset, uint32 cubToRead ) = 0; + virtual bool FileReadAsyncComplete( SteamAPICall_t hReadCall, void *pvBuffer, uint32 cubToRead ) = 0; + virtual bool FileForget( const char *pchFile ) = 0; virtual bool FileDelete( const char *pchFile ) = 0; + STEAM_CALL_RESULT( RemoteStorageFileShareResult_t ) virtual SteamAPICall_t FileShare( const char *pchFile ) = 0; virtual bool SetSyncPlatforms( const char *pchFile, ERemoteStoragePlatform eRemoteStoragePlatform ) = 0; @@ -199,7 +228,7 @@ class ISteamRemoteStorage virtual const char *GetFileNameAndSize( int iFile, int32 *pnFileSizeInBytes ) = 0; // configuration management - virtual bool GetQuota( int32 *pnTotalBytes, int32 *puAvailableBytes ) = 0; + virtual bool GetQuota( uint64 *pnTotalBytes, uint64 *puAvailableBytes ) = 0; virtual bool IsCloudEnabledForAccount() = 0; virtual bool IsCloudEnabledForApp() = 0; virtual void SetCloudEnabledForApp( bool bEnabled ) = 0; @@ -209,6 +238,7 @@ class ISteamRemoteStorage // Downloads a UGC file. A priority value of 0 will download the file immediately, // otherwise it will wait to download the file until all downloads with a lower priority // value are completed. Downloads with equal priority will occur simultaneously. + STEAM_CALL_RESULT( RemoteStorageDownloadUGCResult_t ) virtual SteamAPICall_t UGCDownload( UGCHandle_t hContent, uint32 unPriority ) = 0; // Gets the amount of data downloaded so far for a piece of content. pnBytesExpected can be 0 if function returns false @@ -216,7 +246,7 @@ class ISteamRemoteStorage virtual bool GetUGCDownloadProgress( UGCHandle_t hContent, int32 *pnBytesDownloaded, int32 *pnBytesExpected ) = 0; // Gets metadata for a file after it has been downloaded. This is the same metadata given in the RemoteStorageDownloadUGCResult_t call result - virtual bool GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, char **ppchName, int32 *pnFileSizeInBytes, OUT_STRUCT() CSteamID *pSteamIDOwner ) = 0; + virtual bool GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, STEAM_OUT_STRING() char **ppchName, int32 *pnFileSizeInBytes, STEAM_OUT_STRUCT() CSteamID *pSteamIDOwner ) = 0; // After download, gets the content of the file. // Small files can be read all at once by calling this function with an offset of 0 and cubDataToRead equal to the size of the file. @@ -230,25 +260,8 @@ class ISteamRemoteStorage virtual int32 GetCachedUGCCount() = 0; virtual UGCHandle_t GetCachedUGCHandle( int32 iCachedContent ) = 0; - // The following functions are only necessary on the Playstation 3. On PC & Mac, the Steam client will handle these operations for you - // On Playstation 3, the game controls which files are stored in the cloud, via FilePersist, FileFetch, and FileForget. - -#if defined(_PS3) || defined(_SERVER) - // Connect to Steam and get a list of files in the Cloud - results in a RemoteStorageAppSyncStatusCheck_t callback - virtual void GetFileListFromServer() = 0; - // Indicate this file should be downloaded in the next sync - virtual bool FileFetch( const char *pchFile ) = 0; - // Indicate this file should be persisted in the next sync - virtual bool FilePersist( const char *pchFile ) = 0; - // Pull any requested files down from the Cloud - results in a RemoteStorageAppSyncedClient_t callback - virtual bool SynchronizeToClient() = 0; - // Upload any requested files to the Cloud - results in a RemoteStorageAppSyncedServer_t callback - virtual bool SynchronizeToServer() = 0; - // Reset any fetch/persist/etc requests - virtual bool ResetFileRequestState() = 0; -#endif - // publishing UGC + STEAM_CALL_RESULT( RemoteStoragePublishFileProgress_t ) virtual SteamAPICall_t PublishWorkshopFile( const char *pchFile, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags, EWorkshopFileType eWorkshopFileType ) = 0; virtual PublishedFileUpdateHandle_t CreatePublishedFileUpdateRequest( PublishedFileId_t unPublishedFileId ) = 0; virtual bool UpdatePublishedFileFile( PublishedFileUpdateHandle_t updateHandle, const char *pchFile ) = 0; @@ -257,33 +270,61 @@ class ISteamRemoteStorage virtual bool UpdatePublishedFileDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchDescription ) = 0; virtual bool UpdatePublishedFileVisibility( PublishedFileUpdateHandle_t updateHandle, ERemoteStoragePublishedFileVisibility eVisibility ) = 0; virtual bool UpdatePublishedFileTags( PublishedFileUpdateHandle_t updateHandle, SteamParamStringArray_t *pTags ) = 0; + STEAM_CALL_RESULT( RemoteStorageUpdatePublishedFileResult_t ) virtual SteamAPICall_t CommitPublishedFileUpdate( PublishedFileUpdateHandle_t updateHandle ) = 0; // Gets published file details for the given publishedfileid. If unMaxSecondsOld is greater than 0, // cached data may be returned, depending on how long ago it was cached. A value of 0 will force a refresh. // A value of k_WorkshopForceLoadPublishedFileDetailsFromCache will use cached data if it exists, no matter how old it is. + STEAM_CALL_RESULT( RemoteStorageGetPublishedFileDetailsResult_t ) virtual SteamAPICall_t GetPublishedFileDetails( PublishedFileId_t unPublishedFileId, uint32 unMaxSecondsOld ) = 0; + STEAM_CALL_RESULT( RemoteStorageDeletePublishedFileResult_t ) virtual SteamAPICall_t DeletePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; // enumerate the files that the current user published with this app + STEAM_CALL_RESULT( RemoteStorageEnumerateUserPublishedFilesResult_t ) virtual SteamAPICall_t EnumerateUserPublishedFiles( uint32 unStartIndex ) = 0; + STEAM_CALL_RESULT( RemoteStorageSubscribePublishedFileResult_t ) virtual SteamAPICall_t SubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; + STEAM_CALL_RESULT( RemoteStorageEnumerateUserSubscribedFilesResult_t ) virtual SteamAPICall_t EnumerateUserSubscribedFiles( uint32 unStartIndex ) = 0; + STEAM_CALL_RESULT( RemoteStorageUnsubscribePublishedFileResult_t ) virtual SteamAPICall_t UnsubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; virtual bool UpdatePublishedFileSetChangeDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchChangeDescription ) = 0; + STEAM_CALL_RESULT( RemoteStorageGetPublishedItemVoteDetailsResult_t ) virtual SteamAPICall_t GetPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; + STEAM_CALL_RESULT( RemoteStorageUpdateUserPublishedItemVoteResult_t ) virtual SteamAPICall_t UpdateUserPublishedItemVote( PublishedFileId_t unPublishedFileId, bool bVoteUp ) = 0; + STEAM_CALL_RESULT( RemoteStorageGetPublishedItemVoteDetailsResult_t ) virtual SteamAPICall_t GetUserPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; + STEAM_CALL_RESULT( RemoteStorageEnumerateUserPublishedFilesResult_t ) virtual SteamAPICall_t EnumerateUserSharedWorkshopFiles( CSteamID steamId, uint32 unStartIndex, SteamParamStringArray_t *pRequiredTags, SteamParamStringArray_t *pExcludedTags ) = 0; + STEAM_CALL_RESULT( RemoteStoragePublishFileProgress_t ) virtual SteamAPICall_t PublishVideo( EWorkshopVideoProvider eVideoProvider, const char *pchVideoAccount, const char *pchVideoIdentifier, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags ) = 0; + STEAM_CALL_RESULT( RemoteStorageSetUserPublishedFileActionResult_t ) virtual SteamAPICall_t SetUserPublishedFileAction( PublishedFileId_t unPublishedFileId, EWorkshopFileAction eAction ) = 0; + STEAM_CALL_RESULT( RemoteStorageEnumeratePublishedFilesByUserActionResult_t ) virtual SteamAPICall_t EnumeratePublishedFilesByUserAction( EWorkshopFileAction eAction, uint32 unStartIndex ) = 0; // this method enumerates the public view of workshop files + STEAM_CALL_RESULT( RemoteStorageEnumerateWorkshopFilesResult_t ) virtual SteamAPICall_t EnumeratePublishedWorkshopFiles( EWorkshopEnumerationType eEnumerationType, uint32 unStartIndex, uint32 unCount, uint32 unDays, SteamParamStringArray_t *pTags, SteamParamStringArray_t *pUserTags ) = 0; + STEAM_CALL_RESULT( RemoteStorageDownloadUGCResult_t ) virtual SteamAPICall_t UGCDownloadToLocation( UGCHandle_t hContent, const char *pchLocation, uint32 unPriority ) = 0; + + // Cloud dynamic state change notification + virtual int32 GetLocalFileChangeCount() = 0; + virtual const char *GetLocalFileChange( int iFile, ERemoteStorageLocalFileChange *pEChangeType, ERemoteStorageFilePathType *pEFilePathType ) = 0; + + // Indicate to Steam the beginning / end of a set of local file + // operations - for example, writing a game save that requires updating two files. + virtual bool BeginFileWriteBatch() = 0; + virtual bool EndFileWriteBatch() = 0; }; -#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION012" +#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION016" +// Global interface accessor +inline ISteamRemoteStorage *SteamRemoteStorage(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamRemoteStorage *, SteamRemoteStorage, STEAMREMOTESTORAGE_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -291,86 +332,25 @@ class ISteamRemoteStorage #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif -//----------------------------------------------------------------------------- -// Purpose: sent when the local file cache is fully synced with the server for an app -// That means that an application can be started and has all latest files -//----------------------------------------------------------------------------- -struct RemoteStorageAppSyncedClient_t -{ - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 1 }; - AppId_t m_nAppID; - EResult m_eResult; - int m_unNumDownloads; -}; - -//----------------------------------------------------------------------------- -// Purpose: sent when the server is fully synced with the local file cache for an app -// That means that we can shutdown Steam and our data is stored on the server -//----------------------------------------------------------------------------- -struct RemoteStorageAppSyncedServer_t -{ - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 2 }; - AppId_t m_nAppID; - EResult m_eResult; - int m_unNumUploads; -}; - -//----------------------------------------------------------------------------- -// Purpose: Status of up and downloads during a sync session -// -//----------------------------------------------------------------------------- -struct RemoteStorageAppSyncProgress_t -{ - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 3 }; - char m_rgchCurrentFile[k_cchFilenameMax]; // Current file being transferred - AppId_t m_nAppID; // App this info relates to - uint32 m_uBytesTransferredThisChunk; // Bytes transferred this chunk - double m_dAppPercentComplete; // Percent complete that this app's transfers are - bool m_bUploading; // if false, downloading -}; -// -// IMPORTANT! k_iClientRemoteStorageCallbacks + 4 is used, see iclientremotestorage.h -// -//----------------------------------------------------------------------------- -// Purpose: Sent after we've determined the list of files that are out of sync -// with the server. -//----------------------------------------------------------------------------- -struct RemoteStorageAppSyncStatusCheck_t -{ - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 5 }; - AppId_t m_nAppID; - EResult m_eResult; -}; - -//----------------------------------------------------------------------------- -// Purpose: Sent after a conflict resolution attempt. -//----------------------------------------------------------------------------- -struct RemoteStorageConflictResolution_t -{ - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 6 }; - AppId_t m_nAppID; - EResult m_eResult; -}; - //----------------------------------------------------------------------------- // Purpose: The result of a call to FileShare() //----------------------------------------------------------------------------- struct RemoteStorageFileShareResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 7 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 7 }; EResult m_eResult; // The result of the operation UGCHandle_t m_hFile; // The handle that can be shared with users and features char m_rgchFilename[k_cchFilenameMax]; // The name of the file that was shared }; -// k_iClientRemoteStorageCallbacks + 8 is deprecated! Do not reuse +// k_iSteamRemoteStorageCallbacks + 8 is deprecated! Do not reuse //----------------------------------------------------------------------------- @@ -378,19 +358,22 @@ struct RemoteStorageFileShareResult_t //----------------------------------------------------------------------------- struct RemoteStoragePublishFileResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 9 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 9 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; bool m_bUserNeedsToAcceptWorkshopLegalAgreement; }; +// k_iSteamRemoteStorageCallbacks + 10 is deprecated! Do not reuse + + //----------------------------------------------------------------------------- // Purpose: The result of a call to DeletePublishedFile() //----------------------------------------------------------------------------- struct RemoteStorageDeletePublishedFileResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 11 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 11 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; }; @@ -401,7 +384,7 @@ struct RemoteStorageDeletePublishedFileResult_t //----------------------------------------------------------------------------- struct RemoteStorageEnumerateUserPublishedFilesResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 12 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 12 }; EResult m_eResult; // The result of the operation. int32 m_nResultsReturned; int32 m_nTotalResultCount; @@ -414,7 +397,7 @@ struct RemoteStorageEnumerateUserPublishedFilesResult_t //----------------------------------------------------------------------------- struct RemoteStorageSubscribePublishedFileResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 13 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 13 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; }; @@ -425,7 +408,7 @@ struct RemoteStorageSubscribePublishedFileResult_t //----------------------------------------------------------------------------- struct RemoteStorageEnumerateUserSubscribedFilesResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 14 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 14 }; EResult m_eResult; // The result of the operation. int32 m_nResultsReturned; int32 m_nTotalResultCount; @@ -438,7 +421,7 @@ struct RemoteStorageEnumerateUserSubscribedFilesResult_t #elif defined(VALVE_CALLBACK_PACK_LARGE) VALVE_COMPILE_TIME_ASSERT( sizeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) == (1 + 1 + 1 + 50 + 100) * 4 + 4 ); #else -#warning You must first include isteamclient.h +#warning You must first include steam_api_common.h #endif //----------------------------------------------------------------------------- @@ -446,7 +429,7 @@ struct RemoteStorageEnumerateUserSubscribedFilesResult_t //----------------------------------------------------------------------------- struct RemoteStorageUnsubscribePublishedFileResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 15 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 15 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; }; @@ -457,7 +440,7 @@ struct RemoteStorageUnsubscribePublishedFileResult_t //----------------------------------------------------------------------------- struct RemoteStorageUpdatePublishedFileResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 16 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 16 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; bool m_bUserNeedsToAcceptWorkshopLegalAgreement; @@ -469,7 +452,7 @@ struct RemoteStorageUpdatePublishedFileResult_t //----------------------------------------------------------------------------- struct RemoteStorageDownloadUGCResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 17 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 17 }; EResult m_eResult; // The result of the operation. UGCHandle_t m_hFile; // The handle to the file that was attempted to be downloaded. AppId_t m_nAppID; // ID of the app that created this file. @@ -484,7 +467,7 @@ struct RemoteStorageDownloadUGCResult_t //----------------------------------------------------------------------------- struct RemoteStorageGetPublishedFileDetailsResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 18 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 18 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; AppId_t m_nCreatorAppID; // ID of the app that created this file. @@ -511,7 +494,7 @@ struct RemoteStorageGetPublishedFileDetailsResult_t struct RemoteStorageEnumerateWorkshopFilesResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 19 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 19 }; EResult m_eResult; int32 m_nResultsReturned; int32 m_nTotalResultCount; @@ -527,7 +510,7 @@ struct RemoteStorageEnumerateWorkshopFilesResult_t //----------------------------------------------------------------------------- struct RemoteStorageGetPublishedItemVoteDetailsResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 20 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 20 }; EResult m_eResult; PublishedFileId_t m_unPublishedFileId; int32 m_nVotesFor; @@ -542,7 +525,7 @@ struct RemoteStorageGetPublishedItemVoteDetailsResult_t //----------------------------------------------------------------------------- struct RemoteStoragePublishedFileSubscribed_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 21 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 21 }; PublishedFileId_t m_nPublishedFileId; // The published file id AppId_t m_nAppID; // ID of the app that will consume this file. }; @@ -552,7 +535,7 @@ struct RemoteStoragePublishedFileSubscribed_t //----------------------------------------------------------------------------- struct RemoteStoragePublishedFileUnsubscribed_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 22 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 22 }; PublishedFileId_t m_nPublishedFileId; // The published file id AppId_t m_nAppID; // ID of the app that will consume this file. }; @@ -563,7 +546,7 @@ struct RemoteStoragePublishedFileUnsubscribed_t //----------------------------------------------------------------------------- struct RemoteStoragePublishedFileDeleted_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 23 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 23 }; PublishedFileId_t m_nPublishedFileId; // The published file id AppId_t m_nAppID; // ID of the app that will consume this file. }; @@ -574,7 +557,7 @@ struct RemoteStoragePublishedFileDeleted_t //----------------------------------------------------------------------------- struct RemoteStorageUpdateUserPublishedItemVoteResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 24 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 24 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; // The published file id }; @@ -585,7 +568,7 @@ struct RemoteStorageUpdateUserPublishedItemVoteResult_t //----------------------------------------------------------------------------- struct RemoteStorageUserVoteDetails_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 25 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 25 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; // The published file id EWorkshopVote m_eVote; // what the user voted @@ -593,7 +576,7 @@ struct RemoteStorageUserVoteDetails_t struct RemoteStorageEnumerateUserSharedWorkshopFilesResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 26 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 26 }; EResult m_eResult; // The result of the operation. int32 m_nResultsReturned; int32 m_nTotalResultCount; @@ -602,7 +585,7 @@ struct RemoteStorageEnumerateUserSharedWorkshopFilesResult_t struct RemoteStorageSetUserPublishedFileActionResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 27 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 27 }; EResult m_eResult; // The result of the operation. PublishedFileId_t m_nPublishedFileId; // The published file id EWorkshopFileAction m_eAction; // the action that was attempted @@ -610,7 +593,7 @@ struct RemoteStorageSetUserPublishedFileActionResult_t struct RemoteStorageEnumeratePublishedFilesByUserActionResult_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 28 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 28 }; EResult m_eResult; // The result of the operation. EWorkshopFileAction m_eAction; // the action that was filtered on int32 m_nResultsReturned; @@ -625,7 +608,7 @@ struct RemoteStorageEnumeratePublishedFilesByUserActionResult_t //----------------------------------------------------------------------------- struct RemoteStoragePublishFileProgress_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 29 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 29 }; double m_dPercentFile; bool m_bPreview; }; @@ -636,13 +619,40 @@ struct RemoteStoragePublishFileProgress_t //----------------------------------------------------------------------------- struct RemoteStoragePublishedFileUpdated_t { - enum { k_iCallback = k_iClientRemoteStorageCallbacks + 30 }; + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 30 }; PublishedFileId_t m_nPublishedFileId; // The published file id AppId_t m_nAppID; // ID of the app that will consume this file. - UGCHandle_t m_hFile; // The new content + uint64 m_ulUnused; // not used anymore }; +//----------------------------------------------------------------------------- +// Purpose: Called when a FileWriteAsync completes +//----------------------------------------------------------------------------- +struct RemoteStorageFileWriteAsyncComplete_t +{ + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 31 }; + EResult m_eResult; // result +}; +//----------------------------------------------------------------------------- +// Purpose: Called when a FileReadAsync completes +//----------------------------------------------------------------------------- +struct RemoteStorageFileReadAsyncComplete_t +{ + enum { k_iCallback = k_iSteamRemoteStorageCallbacks + 32 }; + SteamAPICall_t m_hFileReadAsync; // call handle of the async read which was made + EResult m_eResult; // result + uint32 m_nOffset; // offset in the file this read was at + uint32 m_cubRead; // amount read - will the <= the amount requested +}; + +//----------------------------------------------------------------------------- +// Purpose: one or more files for this app have changed locally after syncing +// to remote session changes +// Note: only posted if this happens DURING the local app session +//----------------------------------------------------------------------------- +STEAM_CALLBACK_BEGIN( RemoteStorageLocalFileChange_t, k_iSteamRemoteStorageCallbacks + 33 ) +STEAM_CALLBACK_END( 0 ) #pragma pack( pop ) diff --git a/public/steam/isteamscreenshots.h b/public/steam/isteamscreenshots.h index 1636c160..18242682 100644 --- a/public/steam/isteamscreenshots.h +++ b/public/steam/isteamscreenshots.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======= // // Purpose: public interface to user remote file storage in Steam // @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" const uint32 k_nScreenshotMaxTaggedUsers = 32; const uint32 k_nScreenshotMaxTaggedPublishedFiles = 32; @@ -25,6 +25,16 @@ const int k_ScreenshotThumbWidth = 200; typedef uint32 ScreenshotHandle; #define INVALID_SCREENSHOT_HANDLE 0 +enum EVRScreenshotType +{ + k_EVRScreenshotType_None = 0, + k_EVRScreenshotType_Mono = 1, + k_EVRScreenshotType_Stereo = 2, + k_EVRScreenshotType_MonoCubemap = 3, + k_EVRScreenshotType_MonoPanorama = 4, + k_EVRScreenshotType_StereoPanorama = 5 +}; + //----------------------------------------------------------------------------- // Purpose: Functions for adding screenshots to the user's screenshot library //----------------------------------------------------------------------------- @@ -57,9 +67,23 @@ class ISteamScreenshots // Tags a published file as being visible in the screenshot virtual bool TagPublishedFile( ScreenshotHandle hScreenshot, PublishedFileId_t unPublishedFileID ) = 0; + + // Returns true if the app has hooked the screenshot + virtual bool IsScreenshotsHooked() = 0; + + // Adds a VR screenshot to the user's screenshot library from disk in the supported type. + // pchFilename should be the normal 2D image used in the library view + // pchVRFilename should contain the image that matches the correct type + // The return value is a handle that is valid for the duration of the game process and can be used to apply tags. + // JPEG, TGA, and PNG formats are supported. + virtual ScreenshotHandle AddVRScreenshotToLibrary( EVRScreenshotType eType, const char *pchFilename, const char *pchVRFilename ) = 0; }; -#define STEAMSCREENSHOTS_INTERFACE_VERSION "STEAMSCREENSHOTS_INTERFACE_VERSION002" +#define STEAMSCREENSHOTS_INTERFACE_VERSION "STEAMSCREENSHOTS_INTERFACE_VERSION003" + +// Global interface accessor +inline ISteamScreenshots *SteamScreenshots(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamScreenshots *, SteamScreenshots, STEAMSCREENSHOTS_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -67,7 +91,7 @@ class ISteamScreenshots #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- // Purpose: Screenshot successfully written or otherwise added to the library @@ -92,5 +116,5 @@ struct ScreenshotRequested_t #pragma pack( pop ) - #endif // ISTEAMSCREENSHOTS_H + diff --git a/public/steam/isteamugc.h b/public/steam/isteamugc.h index 6ac2a555..f6e43a8d 100644 --- a/public/steam/isteamugc.h +++ b/public/steam/isteamugc.h @@ -10,7 +10,8 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" +#include "isteamremotestorage.h" // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -18,7 +19,7 @@ #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif @@ -46,6 +47,7 @@ enum EUGCMatchingUGCType k_EUGCMatchingUGCType_UsableInGame = 10, // ready-to-use items and integrated guides k_EUGCMatchingUGCType_ControllerBindings = 11, k_EUGCMatchingUGCType_GameManagedItems = 12, // game managed items (not managed by users) + k_EUGCMatchingUGCType_All = ~0, // @note: will only be valid for CreateQueryUserUGCRequest requests }; // Different lists of published UGC for a user. @@ -91,6 +93,13 @@ enum EUGCQuery k_EUGCQuery_RankedByVotesUp = 10, k_EUGCQuery_RankedByTextSearch = 11, k_EUGCQuery_RankedByTotalUniqueSubscriptions = 12, + k_EUGCQuery_RankedByPlaytimeTrend = 13, + k_EUGCQuery_RankedByTotalPlaytime = 14, + k_EUGCQuery_RankedByAveragePlaytimeTrend = 15, + k_EUGCQuery_RankedByLifetimeAveragePlaytime = 16, + k_EUGCQuery_RankedByPlaytimeSessionsTrend = 17, + k_EUGCQuery_RankedByLifetimePlaytimeSessions = 18, + k_EUGCQuery_RankedByLastUpdatedDate = 19, }; enum EItemUpdateStatus @@ -116,14 +125,36 @@ enum EItemState enum EItemStatistic { - k_EItemStatistic_NumSubscriptions = 0, - k_EItemStatistic_NumFavorites = 1, - k_EItemStatistic_NumFollowers = 2, - k_EItemStatistic_NumUniqueSubscriptions = 3, - k_EItemStatistic_NumUniqueFavorites = 4, - k_EItemStatistic_NumUniqueFollowers = 5, - k_EItemStatistic_NumUniqueWebsiteViews = 6, - k_EItemStatistic_ReportScore = 7, + k_EItemStatistic_NumSubscriptions = 0, + k_EItemStatistic_NumFavorites = 1, + k_EItemStatistic_NumFollowers = 2, + k_EItemStatistic_NumUniqueSubscriptions = 3, + k_EItemStatistic_NumUniqueFavorites = 4, + k_EItemStatistic_NumUniqueFollowers = 5, + k_EItemStatistic_NumUniqueWebsiteViews = 6, + k_EItemStatistic_ReportScore = 7, + k_EItemStatistic_NumSecondsPlayed = 8, + k_EItemStatistic_NumPlaytimeSessions = 9, + k_EItemStatistic_NumComments = 10, + k_EItemStatistic_NumSecondsPlayedDuringTimePeriod = 11, + k_EItemStatistic_NumPlaytimeSessionsDuringTimePeriod = 12, +}; + +enum EItemPreviewType +{ + k_EItemPreviewType_Image = 0, // standard image file expected (e.g. jpg, png, gif, etc.) + k_EItemPreviewType_YouTubeVideo = 1, // video id is stored + k_EItemPreviewType_Sketchfab = 2, // model id is stored + k_EItemPreviewType_EnvironmentMap_HorizontalCross = 3, // standard image file expected - cube map in the layout + // +---+---+-------+ + // | |Up | | + // +---+---+---+---+ + // | L | F | R | B | + // +---+---+---+---+ + // | |Dn | | + // +---+---+---+---+ + k_EItemPreviewType_EnvironmentMap_LatLong = 4, // standard image file expected + k_EItemPreviewType_ReservedMax = 255, // you can specify your own types above this value }; const uint32 kNumUGCResultsPerPage = 50; @@ -174,37 +205,53 @@ class ISteamUGC virtual UGCQueryHandle_t CreateQueryUserUGCRequest( AccountID_t unAccountID, EUserUGCList eListType, EUGCMatchingUGCType eMatchingUGCType, EUserUGCListSortOrder eSortOrder, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ) = 0; // Query for all matching UGC. Creator app id or consumer app id must be valid and be set to the current running app. unPage should start at 1. + STEAM_FLAT_NAME( CreateQueryAllUGCRequestPage ) virtual UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ) = 0; + // Query for all matching UGC using the new deep paging interface. Creator app id or consumer app id must be valid and be set to the current running app. pchCursor should be set to NULL or "*" to get the first result set. + STEAM_FLAT_NAME( CreateQueryAllUGCRequestCursor ) + virtual UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, const char *pchCursor = NULL ) = 0; + // Query for the details of the given published file ids (the RequestUGCDetails call is deprecated and replaced with this) virtual UGCQueryHandle_t CreateQueryUGCDetailsRequest( PublishedFileId_t *pvecPublishedFileID, uint32 unNumPublishedFileIDs ) = 0; // Send the query to Steam + STEAM_CALL_RESULT( SteamUGCQueryCompleted_t ) virtual SteamAPICall_t SendQueryUGCRequest( UGCQueryHandle_t handle ) = 0; // Retrieve an individual result after receiving the callback for querying UGC virtual bool GetQueryUGCResult( UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t *pDetails ) = 0; - virtual bool GetQueryUGCPreviewURL( UGCQueryHandle_t handle, uint32 index, char *pchURL, uint32 cchURLSize ) = 0; - virtual bool GetQueryUGCMetadata( UGCQueryHandle_t handle, uint32 index, char *pchMetadata, uint32 cchMetadatasize ) = 0; + virtual uint32 GetQueryUGCNumTags( UGCQueryHandle_t handle, uint32 index ) = 0; + virtual bool GetQueryUGCTag( UGCQueryHandle_t handle, uint32 index, uint32 indexTag, STEAM_OUT_STRING_COUNT( cchValueSize ) char* pchValue, uint32 cchValueSize ) = 0; + virtual bool GetQueryUGCTagDisplayName( UGCQueryHandle_t handle, uint32 index, uint32 indexTag, STEAM_OUT_STRING_COUNT( cchValueSize ) char* pchValue, uint32 cchValueSize ) = 0; + virtual bool GetQueryUGCPreviewURL( UGCQueryHandle_t handle, uint32 index, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchURL, uint32 cchURLSize ) = 0; + virtual bool GetQueryUGCMetadata( UGCQueryHandle_t handle, uint32 index, STEAM_OUT_STRING_COUNT(cchMetadatasize) char *pchMetadata, uint32 cchMetadatasize ) = 0; virtual bool GetQueryUGCChildren( UGCQueryHandle_t handle, uint32 index, PublishedFileId_t* pvecPublishedFileID, uint32 cMaxEntries ) = 0; - virtual bool GetQueryUGCStatistic( UGCQueryHandle_t handle, uint32 index, EItemStatistic eStatType, uint32 *pStatValue ) = 0; + virtual bool GetQueryUGCStatistic( UGCQueryHandle_t handle, uint32 index, EItemStatistic eStatType, uint64 *pStatValue ) = 0; virtual uint32 GetQueryUGCNumAdditionalPreviews( UGCQueryHandle_t handle, uint32 index ) = 0; - virtual bool GetQueryUGCAdditionalPreview( UGCQueryHandle_t handle, uint32 index, uint32 previewIndex, char *pchURLOrVideoID, uint32 cchURLSize, bool *pbIsImage ) = 0; + virtual bool GetQueryUGCAdditionalPreview( UGCQueryHandle_t handle, uint32 index, uint32 previewIndex, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchURLOrVideoID, uint32 cchURLSize, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchOriginalFileName, uint32 cchOriginalFileNameSize, EItemPreviewType *pPreviewType ) = 0; virtual uint32 GetQueryUGCNumKeyValueTags( UGCQueryHandle_t handle, uint32 index ) = 0; - virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, uint32 keyValueTagIndex, char *pchKey, uint32 cchKeySize, char *pchValue, uint32 cchValueSize ) = 0; + virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, uint32 keyValueTagIndex, STEAM_OUT_STRING_COUNT(cchKeySize) char *pchKey, uint32 cchKeySize, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ) = 0; + + // Return the first value matching the pchKey. Note that a key may map to multiple values. Returns false if there was an error or no matching value was found. + STEAM_FLAT_NAME( GetQueryFirstUGCKeyValueTag ) + virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, const char *pchKey, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ) = 0; // Release the request to free up memory, after retrieving results virtual bool ReleaseQueryUGCRequest( UGCQueryHandle_t handle ) = 0; // Options to set for querying UGC virtual bool AddRequiredTag( UGCQueryHandle_t handle, const char *pTagName ) = 0; + virtual bool AddRequiredTagGroup( UGCQueryHandle_t handle, const SteamParamStringArray_t *pTagGroups ) = 0; // match any of the tags in this group virtual bool AddExcludedTag( UGCQueryHandle_t handle, const char *pTagName ) = 0; + virtual bool SetReturnOnlyIDs( UGCQueryHandle_t handle, bool bReturnOnlyIDs ) = 0; virtual bool SetReturnKeyValueTags( UGCQueryHandle_t handle, bool bReturnKeyValueTags ) = 0; virtual bool SetReturnLongDescription( UGCQueryHandle_t handle, bool bReturnLongDescription ) = 0; virtual bool SetReturnMetadata( UGCQueryHandle_t handle, bool bReturnMetadata ) = 0; virtual bool SetReturnChildren( UGCQueryHandle_t handle, bool bReturnChildren ) = 0; virtual bool SetReturnAdditionalPreviews( UGCQueryHandle_t handle, bool bReturnAdditionalPreviews ) = 0; virtual bool SetReturnTotalOnly( UGCQueryHandle_t handle, bool bReturnTotalOnly ) = 0; + virtual bool SetReturnPlaytimeStats( UGCQueryHandle_t handle, uint32 unDays ) = 0; virtual bool SetLanguage( UGCQueryHandle_t handle, const char *pchLanguage ) = 0; virtual bool SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAgeSeconds ) = 0; @@ -215,12 +262,16 @@ class ISteamUGC virtual bool SetMatchAnyTag( UGCQueryHandle_t handle, bool bMatchAnyTag ) = 0; virtual bool SetSearchText( UGCQueryHandle_t handle, const char *pSearchText ) = 0; virtual bool SetRankedByTrendDays( UGCQueryHandle_t handle, uint32 unDays ) = 0; + virtual bool SetTimeCreatedDateRange( UGCQueryHandle_t handle, RTime32 rtStart, RTime32 rtEnd ) = 0; + virtual bool SetTimeUpdatedDateRange( UGCQueryHandle_t handle, RTime32 rtStart, RTime32 rtEnd ) = 0; virtual bool AddRequiredKeyValueTag( UGCQueryHandle_t handle, const char *pKey, const char *pValue ) = 0; // DEPRECATED - Use CreateQueryUGCDetailsRequest call above instead! + STEAM_CALL_RESULT( SteamUGCRequestUGCDetailsResult_t ) virtual SteamAPICall_t RequestUGCDetails( PublishedFileId_t nPublishedFileID, uint32 unMaxAgeSeconds ) = 0; // Steam Workshop Creator API + STEAM_CALL_RESULT( CreateItemResult_t ) virtual SteamAPICall_t CreateItem( AppId_t nConsumerAppId, EWorkshopFileType eFileType ) = 0; // create new item for this app with no content attached yet virtual UGCUpdateHandle_t StartItemUpdate( AppId_t nConsumerAppId, PublishedFileId_t nPublishedFileID ) = 0; // start an UGC item update. Set changed properties before commiting update with CommitItemUpdate() @@ -233,18 +284,32 @@ class ISteamUGC virtual bool SetItemTags( UGCUpdateHandle_t updateHandle, const SteamParamStringArray_t *pTags ) = 0; // change the tags of an UGC item virtual bool SetItemContent( UGCUpdateHandle_t handle, const char *pszContentFolder ) = 0; // update item content from this local folder virtual bool SetItemPreview( UGCUpdateHandle_t handle, const char *pszPreviewFile ) = 0; // change preview image file for this item. pszPreviewFile points to local image file, which must be under 1MB in size + virtual bool SetAllowLegacyUpload( UGCUpdateHandle_t handle, bool bAllowLegacyUpload ) = 0; // use legacy upload for a single small file. The parameter to SetItemContent() should either be a directory with one file or the full path to the file. The file must also be less than 10MB in size. + virtual bool RemoveAllItemKeyValueTags( UGCUpdateHandle_t handle ) = 0; // remove all existing key-value tags (you can add new ones via the AddItemKeyValueTag function) virtual bool RemoveItemKeyValueTags( UGCUpdateHandle_t handle, const char *pchKey ) = 0; // remove any existing key-value tags with the specified key virtual bool AddItemKeyValueTag( UGCUpdateHandle_t handle, const char *pchKey, const char *pchValue ) = 0; // add new key-value tags for the item. Note that there can be multiple values for a tag. + virtual bool AddItemPreviewFile( UGCUpdateHandle_t handle, const char *pszPreviewFile, EItemPreviewType type ) = 0; // add preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size + virtual bool AddItemPreviewVideo( UGCUpdateHandle_t handle, const char *pszVideoID ) = 0; // add preview video for this item + virtual bool UpdateItemPreviewFile( UGCUpdateHandle_t handle, uint32 index, const char *pszPreviewFile ) = 0; // updates an existing preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size + virtual bool UpdateItemPreviewVideo( UGCUpdateHandle_t handle, uint32 index, const char *pszVideoID ) = 0; // updates an existing preview video for this item + virtual bool RemoveItemPreview( UGCUpdateHandle_t handle, uint32 index ) = 0; // remove a preview by index starting at 0 (previews are sorted) + STEAM_CALL_RESULT( SubmitItemUpdateResult_t ) virtual SteamAPICall_t SubmitItemUpdate( UGCUpdateHandle_t handle, const char *pchChangeNote ) = 0; // commit update process started with StartItemUpdate() virtual EItemUpdateStatus GetItemUpdateProgress( UGCUpdateHandle_t handle, uint64 *punBytesProcessed, uint64* punBytesTotal ) = 0; // Steam Workshop Consumer API + STEAM_CALL_RESULT( SetUserItemVoteResult_t ) virtual SteamAPICall_t SetUserItemVote( PublishedFileId_t nPublishedFileID, bool bVoteUp ) = 0; + STEAM_CALL_RESULT( GetUserItemVoteResult_t ) virtual SteamAPICall_t GetUserItemVote( PublishedFileId_t nPublishedFileID ) = 0; + STEAM_CALL_RESULT( UserFavoriteItemsListChanged_t ) virtual SteamAPICall_t AddItemToFavorites( AppId_t nAppId, PublishedFileId_t nPublishedFileID ) = 0; + STEAM_CALL_RESULT( UserFavoriteItemsListChanged_t ) virtual SteamAPICall_t RemoveItemFromFavorites( AppId_t nAppId, PublishedFileId_t nPublishedFileID ) = 0; + STEAM_CALL_RESULT( RemoteStorageSubscribePublishedFileResult_t ) virtual SteamAPICall_t SubscribeItem( PublishedFileId_t nPublishedFileID ) = 0; // subscribe to this item, will be installed ASAP + STEAM_CALL_RESULT( RemoteStorageUnsubscribePublishedFileResult_t ) virtual SteamAPICall_t UnsubscribeItem( PublishedFileId_t nPublishedFileID ) = 0; // unsubscribe from this item, will be uninstalled after game quits virtual uint32 GetNumSubscribedItems() = 0; // number of subscribed items virtual uint32 GetSubscribedItems( PublishedFileId_t* pvecPublishedFileID, uint32 cMaxEntries ) = 0; // all subscribed item PublishFileIDs @@ -254,7 +319,7 @@ class ISteamUGC // get info about currently installed content on disc for items that have k_EItemStateInstalled set // if k_EItemStateLegacyItem is set, pchFolder contains the path to the legacy file itself (not a folder) - virtual bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID, uint64 *punSizeOnDisk, char *pchFolder, uint32 cchFolderSize, uint32 *punTimeStamp ) = 0; + virtual bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID, uint64 *punSizeOnDisk, STEAM_OUT_STRING_COUNT( cchFolderSize ) char *pchFolder, uint32 cchFolderSize, uint32 *punTimeStamp ) = 0; // get info about pending update for items that have k_EItemStateNeedsUpdate set. punBytesTotal will be valid after download started once virtual bool GetItemDownloadInfo( PublishedFileId_t nPublishedFileID, uint64 *punBytesDownloaded, uint64 *punBytesTotal ) = 0; @@ -267,21 +332,67 @@ class ISteamUGC // game servers can set a specific workshop folder before issuing any UGC commands. // This is helpful if you want to support multiple game servers running out of the same install folder virtual bool BInitWorkshopForGameServer( DepotId_t unWorkshopDepotID, const char *pszFolder ) = 0; + + // SuspendDownloads( true ) will suspend all workshop downloads until SuspendDownloads( false ) is called or the game ends + virtual void SuspendDownloads( bool bSuspend ) = 0; + + // usage tracking + STEAM_CALL_RESULT( StartPlaytimeTrackingResult_t ) + virtual SteamAPICall_t StartPlaytimeTracking( PublishedFileId_t *pvecPublishedFileID, uint32 unNumPublishedFileIDs ) = 0; + STEAM_CALL_RESULT( StopPlaytimeTrackingResult_t ) + virtual SteamAPICall_t StopPlaytimeTracking( PublishedFileId_t *pvecPublishedFileID, uint32 unNumPublishedFileIDs ) = 0; + STEAM_CALL_RESULT( StopPlaytimeTrackingResult_t ) + virtual SteamAPICall_t StopPlaytimeTrackingForAllItems() = 0; + + // parent-child relationship or dependency management + STEAM_CALL_RESULT( AddUGCDependencyResult_t ) + virtual SteamAPICall_t AddDependency( PublishedFileId_t nParentPublishedFileID, PublishedFileId_t nChildPublishedFileID ) = 0; + STEAM_CALL_RESULT( RemoveUGCDependencyResult_t ) + virtual SteamAPICall_t RemoveDependency( PublishedFileId_t nParentPublishedFileID, PublishedFileId_t nChildPublishedFileID ) = 0; + + // add/remove app dependence/requirements (usually DLC) + STEAM_CALL_RESULT( AddAppDependencyResult_t ) + virtual SteamAPICall_t AddAppDependency( PublishedFileId_t nPublishedFileID, AppId_t nAppID ) = 0; + STEAM_CALL_RESULT( RemoveAppDependencyResult_t ) + virtual SteamAPICall_t RemoveAppDependency( PublishedFileId_t nPublishedFileID, AppId_t nAppID ) = 0; + // request app dependencies. note that whatever callback you register for GetAppDependenciesResult_t may be called multiple times + // until all app dependencies have been returned + STEAM_CALL_RESULT( GetAppDependenciesResult_t ) + virtual SteamAPICall_t GetAppDependencies( PublishedFileId_t nPublishedFileID ) = 0; + + // delete the item without prompting the user + STEAM_CALL_RESULT( DeleteItemResult_t ) + virtual SteamAPICall_t DeleteItem( PublishedFileId_t nPublishedFileID ) = 0; + + // Show the app's latest Workshop EULA to the user in an overlay window, where they can accept it or not + virtual bool ShowWorkshopEULA() = 0; + // Retrieve information related to the user's acceptance or not of the app's specific Workshop EULA + STEAM_CALL_RESULT( WorkshopEULAStatus_t ) + virtual SteamAPICall_t GetWorkshopEULAStatus() = 0; }; -#define STEAMUGC_INTERFACE_VERSION "STEAMUGC_INTERFACE_VERSION007" +#define STEAMUGC_INTERFACE_VERSION "STEAMUGC_INTERFACE_VERSION016" + +// Global interface accessor +inline ISteamUGC *SteamUGC(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamUGC *, SteamUGC, STEAMUGC_INTERFACE_VERSION ); + +// Global accessor for the gameserver client +inline ISteamUGC *SteamGameServerUGC(); +STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamUGC *, SteamGameServerUGC, STEAMUGC_INTERFACE_VERSION ); //----------------------------------------------------------------------------- // Purpose: Callback for querying UGC //----------------------------------------------------------------------------- struct SteamUGCQueryCompleted_t { - enum { k_iCallback = k_iClientUGCCallbacks + 1 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 1 }; UGCQueryHandle_t m_handle; EResult m_eResult; uint32 m_unNumResultsReturned; uint32 m_unTotalMatchingResults; bool m_bCachedData; // indicates whether this data was retrieved from the local on-disk cache + char m_rgchNextCursor[k_cchPublishedFileURLMax]; // If a paging cursor was used, then this will be the next cursor to get the next result set. }; @@ -290,7 +401,7 @@ struct SteamUGCQueryCompleted_t //----------------------------------------------------------------------------- struct SteamUGCRequestUGCDetailsResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 2 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 2 }; SteamUGCDetails_t m_details; bool m_bCachedData; // indicates whether this data was retrieved from the local on-disk cache }; @@ -301,7 +412,7 @@ struct SteamUGCRequestUGCDetailsResult_t //----------------------------------------------------------------------------- struct CreateItemResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 3 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 3 }; EResult m_eResult; PublishedFileId_t m_nPublishedFileId; // new item got this UGC PublishFileID bool m_bUserNeedsToAcceptWorkshopLegalAgreement; @@ -313,9 +424,10 @@ struct CreateItemResult_t //----------------------------------------------------------------------------- struct SubmitItemUpdateResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 4 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 4 }; EResult m_eResult; bool m_bUserNeedsToAcceptWorkshopLegalAgreement; + PublishedFileId_t m_nPublishedFileId; }; @@ -324,7 +436,7 @@ struct SubmitItemUpdateResult_t //----------------------------------------------------------------------------- struct ItemInstalled_t { - enum { k_iCallback = k_iClientUGCCallbacks + 5 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 5 }; AppId_t m_unAppID; PublishedFileId_t m_nPublishedFileId; }; @@ -335,7 +447,7 @@ struct ItemInstalled_t //----------------------------------------------------------------------------- struct DownloadItemResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 6 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 6 }; AppId_t m_unAppID; PublishedFileId_t m_nPublishedFileId; EResult m_eResult; @@ -346,7 +458,7 @@ struct DownloadItemResult_t //----------------------------------------------------------------------------- struct UserFavoriteItemsListChanged_t { - enum { k_iCallback = k_iClientUGCCallbacks + 7 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 7 }; PublishedFileId_t m_nPublishedFileId; EResult m_eResult; bool m_bWasAddRequest; @@ -357,7 +469,7 @@ struct UserFavoriteItemsListChanged_t //----------------------------------------------------------------------------- struct SetUserItemVoteResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 8 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 8 }; PublishedFileId_t m_nPublishedFileId; EResult m_eResult; bool m_bVoteUp; @@ -368,7 +480,7 @@ struct SetUserItemVoteResult_t //----------------------------------------------------------------------------- struct GetUserItemVoteResult_t { - enum { k_iCallback = k_iClientUGCCallbacks + 9 }; + enum { k_iCallback = k_iSteamUGCCallbacks + 9 }; PublishedFileId_t m_nPublishedFileId; EResult m_eResult; bool m_bVotedUp; @@ -376,6 +488,118 @@ struct GetUserItemVoteResult_t bool m_bVoteSkipped; }; +//----------------------------------------------------------------------------- +// Purpose: The result of a call to StartPlaytimeTracking() +//----------------------------------------------------------------------------- +struct StartPlaytimeTrackingResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 10 }; + EResult m_eResult; +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to StopPlaytimeTracking() +//----------------------------------------------------------------------------- +struct StopPlaytimeTrackingResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 11 }; + EResult m_eResult; +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to AddDependency +//----------------------------------------------------------------------------- +struct AddUGCDependencyResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 12 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + PublishedFileId_t m_nChildPublishedFileId; +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to RemoveDependency +//----------------------------------------------------------------------------- +struct RemoveUGCDependencyResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 13 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + PublishedFileId_t m_nChildPublishedFileId; +}; + + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to AddAppDependency +//----------------------------------------------------------------------------- +struct AddAppDependencyResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 14 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + AppId_t m_nAppID; +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to RemoveAppDependency +//----------------------------------------------------------------------------- +struct RemoveAppDependencyResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 15 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + AppId_t m_nAppID; +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to GetAppDependencies. Callback may be called +// multiple times until all app dependencies have been returned. +//----------------------------------------------------------------------------- +struct GetAppDependenciesResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 16 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + AppId_t m_rgAppIDs[32]; + uint32 m_nNumAppDependencies; // number returned in this struct + uint32 m_nTotalNumAppDependencies; // total found +}; + +//----------------------------------------------------------------------------- +// Purpose: The result of a call to DeleteItem +//----------------------------------------------------------------------------- +struct DeleteItemResult_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 17 }; + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; +}; + + +//----------------------------------------------------------------------------- +// Purpose: signal that the list of subscribed items changed +//----------------------------------------------------------------------------- +struct UserSubscribedItemsListChanged_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 18 }; + AppId_t m_nAppID; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Status of the user's acceptable/rejection of the app's specific Workshop EULA +//----------------------------------------------------------------------------- +struct WorkshopEULAStatus_t +{ + enum { k_iCallback = k_iSteamUGCCallbacks + 20 }; + EResult m_eResult; + AppId_t m_nAppID; + uint32 m_unVersion; + RTime32 m_rtAction; + bool m_bAccepted; + bool m_bNeedsAction; +}; + #pragma pack( pop ) #endif // ISTEAMUGC_H diff --git a/public/steam/isteamuser.h b/public/steam/isteamuser.h index 989b88e7..82625dac 100644 --- a/public/steam/isteamuser.h +++ b/public/steam/isteamuser.h @@ -10,28 +10,7 @@ #pragma once #endif -#include "isteamclient.h" - -// structure that contains client callback data -// see callbacks documentation for more details -#if defined( VALVE_CALLBACK_PACK_SMALL ) -#pragma pack( push, 4 ) -#elif defined( VALVE_CALLBACK_PACK_LARGE ) -#pragma pack( push, 8 ) -#else -#error isteamclient.h must be included -#endif -struct CallbackMsg_t -{ - HSteamUser m_hSteamUser; - int m_iCallback; - uint8 *m_pubParam; - int m_cubParam; -}; -#pragma pack( pop ) - -// reference to a steam call, to filter results by -typedef int32 HSteamCall; +#include "steam_api_common.h" //----------------------------------------------------------------------------- // Purpose: Functions for accessing and manipulating a steam account @@ -68,11 +47,17 @@ class ISteamUser // // return value - returns the number of bytes written to pBlob. If the return is 0, then the buffer passed in was too small, and the call has failed // The contents of pBlob should then be sent to the game server, for it to use to complete the authentication process. - virtual int InitiateGameConnection( void *pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPortServer, bool bSecure ) = 0; + // + // DEPRECATED! This function will be removed from the SDK in an upcoming version. + // Please migrate to BeginAuthSession and related functions. + virtual int InitiateGameConnection_DEPRECATED( void *pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPortServer, bool bSecure ) = 0; // notify of disconnect // needs to occur when the game client leaves the specified game server, needs to match with the InitiateGameConnection() call - virtual void TerminateGameConnection( uint32 unIPServer, uint16 usPortServer ) = 0; + // + // DEPRECATED! This function will be removed from the SDK in an upcoming version. + // Please migrate to BeginAuthSession and related functions. + virtual void TerminateGameConnection_DEPRECATED( uint32 unIPServer, uint16 usPortServer ) = 0; // Legacy functions @@ -91,36 +76,50 @@ class ISteamUser // k_eVoiceResultNotRecording virtual void StopVoiceRecording( ) = 0; - // Determine the amount of captured audio data that is available in bytes. - // This provides both the compressed and uncompressed data. Please note that the uncompressed - // data is not the raw feed from the microphone: data may only be available if audible - // levels of speech are detected. - // nUncompressedVoiceDesiredSampleRate is necessary to know the number of bytes to return in pcbUncompressed - can be set to 0 if you don't need uncompressed (the usual case) - // If you're upgrading from an older Steamworks API, you'll want to pass in 11025 to nUncompressedVoiceDesiredSampleRate - virtual EVoiceResult GetAvailableVoice( uint32 *pcbCompressed, uint32 *pcbUncompressed, uint32 nUncompressedVoiceDesiredSampleRate ) = 0; - - // Gets the latest voice data from the microphone. Compressed data is an arbitrary format, and is meant to be handed back to - // DecompressVoice() for playback later as a binary blob. Uncompressed data is 16-bit, signed integer, 11025Hz PCM format. - // Please note that the uncompressed data is not the raw feed from the microphone: data may only be available if audible - // levels of speech are detected, and may have passed through denoising filters, etc. - // This function should be called as often as possible once recording has started; once per frame at least. - // nBytesWritten is set to the number of bytes written to pDestBuffer. - // nUncompressedBytesWritten is set to the number of bytes written to pUncompressedDestBuffer. - // You must grab both compressed and uncompressed here at the same time, if you want both. - // Matching data that is not read during this call will be thrown away. - // GetAvailableVoice() can be used to determine how much data is actually available. - // If you're upgrading from an older Steamworks API, you'll want to pass in 11025 to nUncompressedVoiceDesiredSampleRate - virtual EVoiceResult GetVoice( bool bWantCompressed, void *pDestBuffer, uint32 cbDestBufferSize, uint32 *nBytesWritten, bool bWantUncompressed, void *pUncompressedDestBuffer, uint32 cbUncompressedDestBufferSize, uint32 *nUncompressBytesWritten, uint32 nUncompressedVoiceDesiredSampleRate ) = 0; - - // Decompresses a chunk of compressed data produced by GetVoice(). - // nBytesWritten is set to the number of bytes written to pDestBuffer unless the return value is k_EVoiceResultBufferTooSmall. - // In that case, nBytesWritten is set to the size of the buffer required to decompress the given - // data. The suggested buffer size for the destination buffer is 22 kilobytes. - // The output format of the data is 16-bit signed at the requested samples per second. - // If you're upgrading from an older Steamworks API, you'll want to pass in 11025 to nDesiredSampleRate + // Determine the size of captured audio data that is available from GetVoice. + // Most applications will only use compressed data and should ignore the other + // parameters, which exist primarily for backwards compatibility. See comments + // below for further explanation of "uncompressed" data. + virtual EVoiceResult GetAvailableVoice( uint32 *pcbCompressed, uint32 *pcbUncompressed_Deprecated = 0, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated = 0 ) = 0; + + // --------------------------------------------------------------------------- + // NOTE: "uncompressed" audio is a deprecated feature and should not be used + // by most applications. It is raw single-channel 16-bit PCM wave data which + // may have been run through preprocessing filters and/or had silence removed, + // so the uncompressed audio could have a shorter duration than you expect. + // There may be no data at all during long periods of silence. Also, fetching + // uncompressed audio will cause GetVoice to discard any leftover compressed + // audio, so you must fetch both types at once. Finally, GetAvailableVoice is + // not precisely accurate when the uncompressed size is requested. So if you + // really need to use uncompressed audio, you should call GetVoice frequently + // with two very large (20kb+) output buffers instead of trying to allocate + // perfectly-sized buffers. But most applications should ignore all of these + // details and simply leave the "uncompressed" parameters as NULL/zero. + // --------------------------------------------------------------------------- + + // Read captured audio data from the microphone buffer. This should be called + // at least once per frame, and preferably every few milliseconds, to keep the + // microphone input delay as low as possible. Most applications will only use + // compressed data and should pass NULL/zero for the "uncompressed" parameters. + // Compressed data can be transmitted by your application and decoded into raw + // using the DecompressVoice function below. + virtual EVoiceResult GetVoice( bool bWantCompressed, void *pDestBuffer, uint32 cbDestBufferSize, uint32 *nBytesWritten, bool bWantUncompressed_Deprecated = false, void *pUncompressedDestBuffer_Deprecated = 0, uint32 cbUncompressedDestBufferSize_Deprecated = 0, uint32 *nUncompressBytesWritten_Deprecated = 0, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated = 0 ) = 0; + + // Decodes the compressed voice data returned by GetVoice. The output data is + // raw single-channel 16-bit PCM audio. The decoder supports any sample rate + // from 11025 to 48000; see GetVoiceOptimalSampleRate() below for details. + // If the output buffer is not large enough, then *nBytesWritten will be set + // to the required buffer size, and k_EVoiceResultBufferTooSmall is returned. + // It is suggested to start with a 20kb buffer and reallocate as necessary. virtual EVoiceResult DecompressVoice( const void *pCompressed, uint32 cbCompressed, void *pDestBuffer, uint32 cbDestBufferSize, uint32 *nBytesWritten, uint32 nDesiredSampleRate ) = 0; - // This returns the frequency of the voice data as it's stored internally; calling DecompressVoice() with this size will yield the best results + // This returns the native sample rate of the Steam voice decompressor; using + // this sample rate for DecompressVoice will perform the least CPU processing. + // However, the final audio quality will depend on how well the audio device + // (and/or your application's audio output SDK) deals with lower sample rates. + // You may find that you get the best audio output quality when you ignore + // this function and use the native sample rate of your audio output device, + // which is usually 48000 or 44100. virtual uint32 GetVoiceOptimalSampleRate() = 0; // Retrieve ticket to be sent to the entity who wishes to authenticate you. @@ -153,9 +152,15 @@ class ISteamUser // Requests a ticket encrypted with an app specific shared key // pDataToInclude, cbDataToInclude will be encrypted into the ticket // ( This is asynchronous, you must wait for the ticket to be completed by the server ) + STEAM_CALL_RESULT( EncryptedAppTicketResponse_t ) virtual SteamAPICall_t RequestEncryptedAppTicket( void *pDataToInclude, int cbDataToInclude ) = 0; - // retrieve a finished ticket + // Retrieves a finished ticket. + // If no ticket is available, or your buffer is too small, returns false. + // Upon exit, *pcbTicket will be either the size of the ticket copied into your buffer + // (if true was returned), or the size needed (if false was returned). To determine the + // proper size of the ticket, you can pass pTicket=NULL and cbMaxTicket=0; if a ticket + // is available, *pcbTicket will contain the size needed, otherwise it will be zero. virtual bool GetEncryptedAppTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0; // Trading Card badges data access @@ -176,49 +181,40 @@ class ISteamUser // or else immediately navigate to the result URL using a hidden browser window. // NOTE 2: The resulting authorization cookie has an expiration time of one day, // so it would be a good idea to request and visit a new auth URL every 12 hours. + STEAM_CALL_RESULT( StoreAuthURLResponse_t ) virtual SteamAPICall_t RequestStoreAuthURL( const char *pchRedirectURL ) = 0; -#ifdef _PS3 - // Initiates PS3 Logon request using just PSN ticket. - // - // PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to - // prompt the user for network setup/PSN logon before initiating the Steam side of the logon. - // - // Listen for SteamServersConnected_t or SteamServerConnectFailure_t for status. SteamServerConnectFailure_t - // may return with EResult k_EResultExternalAccountUnlinked if the PSN account is unknown to Steam. You should - // then call LogOnAndLinkSteamAccountToPSN() after prompting the user for credentials to establish a link. - // Future calls to LogOn() after the one time link call should succeed as long as the user is connected to PSN. - virtual void LogOn( bool bInteractive ) = 0; - - // Initiates a request to logon with a specific steam username/password and create a PSN account link at - // the same time. Should call this only if LogOn() has failed and indicated the PSN account is unlinked. - // - // PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to - // prompt the user for network setup/PSN logon before initiating the Steam side of the logon. pchUserName - // should be the users Steam username, and pchPassword should be the users Steam password. - // - // Listen for SteamServersConnected_t or SteamServerConnectFailure_t for status. SteamServerConnectFailure_t - // may return with EResult k_EResultOtherAccountAlreadyLinked if already linked to another account. - virtual void LogOnAndLinkSteamAccountToPSN( bool bInteractive, const char *pchUserName, const char *pchPassword ) = 0; - - // Final logon option for PS3, this logs into an existing account if already linked, but if not already linked - // creates a new account using the info in the PSN ticket to generate a unique account name. The new account is - // then linked to the PSN ticket. This is the faster option for new users who don't have an existing Steam account - // to get into multiplayer. - // - // PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to - // prompt the user for network setup/PSN logon before initiating the Steam side of the logon. - virtual void LogOnAndCreateNewSteamAccountIfNeeded( bool bInteractive ) = 0; + // gets whether the users phone number is verified + virtual bool BIsPhoneVerified() = 0; - // Returns a special SteamID that represents the user's PSN information. Can be used to query the user's PSN avatar, - // online name, etc. through the standard Steamworks interfaces. - virtual CSteamID GetConsoleSteamID() = 0; -#endif + // gets whether the user has two factor enabled on their account + virtual bool BIsTwoFactorEnabled() = 0; + + // gets whether the users phone number is identifying + virtual bool BIsPhoneIdentifying() = 0; + + // gets whether the users phone number is awaiting (re)verification + virtual bool BIsPhoneRequiringVerification() = 0; + + STEAM_CALL_RESULT( MarketEligibilityResponse_t ) + virtual SteamAPICall_t GetMarketEligibility() = 0; + + // Retrieves anti indulgence / duration control for current user + STEAM_CALL_RESULT( DurationControl_t ) + virtual SteamAPICall_t GetDurationControl() = 0; + + // Advise steam china duration control system about the online state of the game. + // This will prevent offline gameplay time from counting against a user's + // playtime limits. + virtual bool BSetDurationControlOnlineState( EDurationControlOnlineState eNewState ) = 0; }; -#define STEAMUSER_INTERFACE_VERSION "SteamUser018" +#define STEAMUSER_INTERFACE_VERSION "SteamUser021" +// Global interface accessor +inline ISteamUser *SteamUser(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamUser *, SteamUser, STEAMUSER_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -226,7 +222,7 @@ class ISteamUser #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- @@ -250,6 +246,7 @@ struct SteamServerConnectFailure_t { enum { k_iCallback = k_iSteamUserCallbacks + 2 }; EResult m_eResult; + bool m_bStillRetrying; }; @@ -373,6 +370,46 @@ struct StoreAuthURLResponse_t }; +//----------------------------------------------------------------------------- +// Purpose: sent in response to ISteamUser::GetMarketEligibility +//----------------------------------------------------------------------------- +struct MarketEligibilityResponse_t +{ + enum { k_iCallback = k_iSteamUserCallbacks + 66 }; + bool m_bAllowed; + EMarketNotAllowedReasonFlags m_eNotAllowedReason; + RTime32 m_rtAllowedAtTime; + + int m_cdaySteamGuardRequiredDays; // The number of days any user is required to have had Steam Guard before they can use the market + int m_cdayNewDeviceCooldown; // The number of days after initial device authorization a user must wait before using the market on that device +}; + + +//----------------------------------------------------------------------------- +// Purpose: sent for games with enabled anti indulgence / duration control, for +// enabled users. Lets the game know whether the user can keep playing or +// whether the game should exit, and returns info about remaining gameplay time. +// +// This callback is fired asynchronously in response to timers triggering. +// It is also fired in response to calls to GetDurationControl(). +//----------------------------------------------------------------------------- +struct DurationControl_t +{ + enum { k_iCallback = k_iSteamUserCallbacks + 67 }; + + EResult m_eResult; // result of call (always k_EResultOK for asynchronous timer-based notifications) + AppId_t m_appid; // appid generating playtime + + bool m_bApplicable; // is duration control applicable to user + game combination + int32 m_csecsLast5h; // playtime since most recent 5 hour gap in playtime, only counting up to regulatory limit of playtime, in seconds + + EDurationControlProgress m_progress; // recommended progress (either everything is fine, or please exit game) + EDurationControlNotification m_notification; // notification to show, if any (always k_EDurationControlNotification_None for API calls) + + int32 m_csecsToday; // playtime on current calendar day + int32 m_csecsRemaining; // playtime remaining until the user hits a regulatory limit +}; + #pragma pack( pop ) diff --git a/public/steam/isteamuserstats.h b/public/steam/isteamuserstats.h index 3a65691c..8bb0c90f 100644 --- a/public/steam/isteamuserstats.h +++ b/public/steam/isteamuserstats.h @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" #include "isteamremotestorage.h" // size limit on stat or achievement name (UTF-8 encoded) @@ -67,7 +67,7 @@ enum ELeaderboardUploadScoreMethod #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif struct LeaderboardEntry_t @@ -89,15 +89,23 @@ class ISteamUserStats { public: // Ask the server to send down this user's data and achievements for this game + STEAM_CALL_BACK( UserStatsReceived_t ) virtual bool RequestCurrentStats() = 0; // Data accessors + STEAM_FLAT_NAME( GetStatInt32 ) virtual bool GetStat( const char *pchName, int32 *pData ) = 0; + + STEAM_FLAT_NAME( GetStatFloat ) virtual bool GetStat( const char *pchName, float *pData ) = 0; // Set / update data + STEAM_FLAT_NAME( SetStatInt32 ) virtual bool SetStat( const char *pchName, int32 nData ) = 0; + + STEAM_FLAT_NAME( SetStatFloat ) virtual bool SetStat( const char *pchName, float fData ) = 0; + virtual bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dSessionLength ) = 0; // Achievement flag accessors @@ -148,11 +156,16 @@ class ISteamUserStats // returns a UserStatsReceived_t received when completed // if the other user has no stats, UserStatsReceived_t.m_eResult will be set to k_EResultFail // these stats won't be auto-updated; you'll need to call RequestUserStats() again to refresh any data + STEAM_CALL_RESULT( UserStatsReceived_t ) virtual SteamAPICall_t RequestUserStats( CSteamID steamIDUser ) = 0; // requests stat information for a user, usable after a successful call to RequestUserStats() + STEAM_FLAT_NAME( GetUserStatInt32 ) virtual bool GetUserStat( CSteamID steamIDUser, const char *pchName, int32 *pData ) = 0; + + STEAM_FLAT_NAME( GetUserStatFloat ) virtual bool GetUserStat( CSteamID steamIDUser, const char *pchName, float *pData ) = 0; + virtual bool GetUserAchievement( CSteamID steamIDUser, const char *pchName, bool *pbAchieved ) = 0; // See notes for GetAchievementAndUnlockTime above virtual bool GetUserAchievementAndUnlockTime( CSteamID steamIDUser, const char *pchName, bool *pbAchieved, uint32 *punUnlockTime ) = 0; @@ -164,10 +177,12 @@ class ISteamUserStats // asks the Steam back-end for a leaderboard by name, and will create it if it's not yet // This call is asynchronous, with the result returned in LeaderboardFindResult_t + STEAM_CALL_RESULT(LeaderboardFindResult_t) virtual SteamAPICall_t FindOrCreateLeaderboard( const char *pchLeaderboardName, ELeaderboardSortMethod eLeaderboardSortMethod, ELeaderboardDisplayType eLeaderboardDisplayType ) = 0; // as above, but won't create the leaderboard if it's not found // This call is asynchronous, with the result returned in LeaderboardFindResult_t + STEAM_CALL_RESULT( LeaderboardFindResult_t ) virtual SteamAPICall_t FindLeaderboard( const char *pchLeaderboardName ) = 0; // returns the name of a leaderboard @@ -190,13 +205,14 @@ class ISteamUserStats // k_ELeaderboardDataRequestGlobalAroundUser requests rows around the current user, nRangeStart being negate // e.g. DownloadLeaderboardEntries( hLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -3, 3 ) will return 7 rows, 3 before the user, 3 after // k_ELeaderboardDataRequestFriends requests all the rows for friends of the current user + STEAM_CALL_RESULT( LeaderboardScoresDownloaded_t ) virtual SteamAPICall_t DownloadLeaderboardEntries( SteamLeaderboard_t hSteamLeaderboard, ELeaderboardDataRequest eLeaderboardDataRequest, int nRangeStart, int nRangeEnd ) = 0; // as above, but downloads leaderboard entries for an arbitrary set of users - ELeaderboardDataRequest is k_ELeaderboardDataRequestUsers // if a user doesn't have a leaderboard entry, they won't be included in the result // a max of 100 users can be downloaded at a time, with only one outstanding call at a time - METHOD_DESC(Downloads leaderboard entries for an arbitrary set of users - ELeaderboardDataRequest is k_ELeaderboardDataRequestUsers) + STEAM_CALL_RESULT( LeaderboardScoresDownloaded_t ) virtual SteamAPICall_t DownloadLeaderboardEntriesForUsers( SteamLeaderboard_t hSteamLeaderboard, - ARRAY_COUNT_D(cUsers, Array of users to retrieve) CSteamID *prgUsers, int cUsers ) = 0; + STEAM_ARRAY_COUNT_D(cUsers, Array of users to retrieve) CSteamID *prgUsers, int cUsers ) = 0; // Returns data about a single leaderboard entry // use a for loop from 0 to LeaderboardScoresDownloaded_t::m_cEntryCount to get all the downloaded entries @@ -218,20 +234,24 @@ class ISteamUserStats // This call is asynchronous, with the result returned in LeaderboardScoreUploaded_t // Details are extra game-defined information regarding how the user got that score // pScoreDetails points to an array of int32's, cScoreDetailsCount is the number of int32's in the list + STEAM_CALL_RESULT( LeaderboardScoreUploaded_t ) virtual SteamAPICall_t UploadLeaderboardScore( SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, int32 nScore, const int32 *pScoreDetails, int cScoreDetailsCount ) = 0; // Attaches a piece of user generated content the user's entry on a leaderboard. // hContent is a handle to a piece of user generated content that was shared using ISteamUserRemoteStorage::FileShare(). // This call is asynchronous, with the result returned in LeaderboardUGCSet_t. + STEAM_CALL_RESULT( LeaderboardUGCSet_t ) virtual SteamAPICall_t AttachLeaderboardUGC( SteamLeaderboard_t hSteamLeaderboard, UGCHandle_t hUGC ) = 0; // Retrieves the number of players currently playing your game (online + offline) // This call is asynchronous, with the result returned in NumberOfCurrentPlayers_t + STEAM_CALL_RESULT( NumberOfCurrentPlayers_t ) virtual SteamAPICall_t GetNumberOfCurrentPlayers() = 0; // Requests that Steam fetch data on the percentage of players who have received each achievement // for the game globally. // This call is asynchronous, with the result returned in GlobalAchievementPercentagesReady_t. + STEAM_CALL_RESULT( GlobalAchievementPercentagesReady_t ) virtual SteamAPICall_t RequestGlobalAchievementPercentages() = 0; // Get the info on the most achieved achievement for the game, returns an iterator index you can use to fetch @@ -251,41 +271,43 @@ class ISteamUserStats // This call is asynchronous, with the results returned in GlobalStatsReceived_t. // nHistoryDays specifies how many days of day-by-day history to retrieve in addition // to the overall totals. The limit is 60. + STEAM_CALL_RESULT( GlobalStatsReceived_t ) virtual SteamAPICall_t RequestGlobalStats( int nHistoryDays ) = 0; // Gets the lifetime totals for an aggregated stat + STEAM_FLAT_NAME( GetGlobalStatInt64 ) virtual bool GetGlobalStat( const char *pchStatName, int64 *pData ) = 0; + + STEAM_FLAT_NAME( GetGlobalStatDouble ) virtual bool GetGlobalStat( const char *pchStatName, double *pData ) = 0; // Gets history for an aggregated stat. pData will be filled with daily values, starting with today. // So when called, pData[0] will be today, pData[1] will be yesterday, and pData[2] will be two days ago, // etc. cubData is the size in bytes of the pubData buffer. Returns the number of // elements actually set. - virtual int32 GetGlobalStatHistory( const char *pchStatName, ARRAY_COUNT(cubData) int64 *pData, uint32 cubData ) = 0; - virtual int32 GetGlobalStatHistory( const char *pchStatName, ARRAY_COUNT(cubData) double *pData, uint32 cubData ) = 0; - -#ifdef _PS3 - // Call to kick off installation of the PS3 trophies. This call is asynchronous, and the results will be returned in a PS3TrophiesInstalled_t - // callback. - virtual bool InstallPS3Trophies() = 0; - - // Returns the amount of space required at boot to install trophies. This value can be used when comparing the amount of space needed - // by the game to the available space value passed to the game at boot. The value is set during InstallPS3Trophies(). - virtual uint64 GetTrophySpaceRequiredBeforeInstall() = 0; - - // On PS3, user stats & achievement progress through Steam must be stored with the user's saved game data. - // At startup, before calling RequestCurrentStats(), you must pass the user's stats data to Steam via this method. - // If you do not have any user data, call this function with pvData = NULL and cubData = 0 - virtual bool SetUserStatsData( const void *pvData, uint32 cubData ) = 0; - - // Call to get the user's current stats data. You should retrieve this data after receiving successful UserStatsReceived_t & UserStatsStored_t - // callbacks, and store the data with the user's save game data. You can call this method with pvData = NULL and cubData = 0 to get the required - // buffer size. - virtual bool GetUserStatsData( void *pvData, uint32 cubData, uint32 *pcubWritten ) = 0; -#endif + + STEAM_FLAT_NAME( GetGlobalStatHistoryInt64 ) + virtual int32 GetGlobalStatHistory( const char *pchStatName, STEAM_ARRAY_COUNT(cubData) int64 *pData, uint32 cubData ) = 0; + + STEAM_FLAT_NAME( GetGlobalStatHistoryDouble ) + virtual int32 GetGlobalStatHistory( const char *pchStatName, STEAM_ARRAY_COUNT(cubData) double *pData, uint32 cubData ) = 0; + + // For achievements that have related Progress stats, use this to query what the bounds of that progress are. + // You may want this info to selectively call IndicateAchievementProgress when appropriate milestones of progress + // have been made, to show a progress notification to the user. + STEAM_FLAT_NAME( GetAchievementProgressLimitsInt32 ) + virtual bool GetAchievementProgressLimits( const char *pchName, int32 *pnMinProgress, int32 *pnMaxProgress ) = 0; + + STEAM_FLAT_NAME( GetAchievementProgressLimitsFloat ) + virtual bool GetAchievementProgressLimits( const char *pchName, float *pfMinProgress, float *pfMaxProgress ) = 0; + }; -#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION011" +#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION012" + +// Global interface accessor +inline ISteamUserStats *SteamUserStats(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamUserStats *, SteamUserStats, STEAMUSERSTATS_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -293,7 +315,7 @@ class ISteamUserStats #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- diff --git a/public/steam/isteamutils.h b/public/steam/isteamutils.h index 54777d33..5f56d8d8 100644 --- a/public/steam/isteamutils.h +++ b/public/steam/isteamutils.h @@ -10,7 +10,7 @@ #pragma once #endif -#include "isteamclient.h" +#include "steam_api_common.h" // Steam API call failure results @@ -41,6 +41,24 @@ enum EGamepadTextInputLineMode k_EGamepadTextInputLineModeMultipleLines = 1 }; +enum EFloatingGamepadTextInputMode +{ + k_EFloatingGamepadTextInputModeModeSingleLine = 0, // Enter dismisses the keyboard + k_EFloatingGamepadTextInputModeModeMultipleLines = 1, // User needs to explictly close the keyboard + k_EFloatingGamepadTextInputModeModeEmail = 2, // Keyboard layout is email, enter dismisses the keyboard + k_EFloatingGamepadTextInputModeModeNumeric = 3, // Keyboard layout is numeric, enter dismisses the keyboard + +}; + +// The context where text filtering is being done +enum ETextFilteringContext +{ + k_ETextFilteringContextUnknown = 0, // Unknown context + k_ETextFilteringContextGameContent = 1, // Game content, only legally required filtering is performed + k_ETextFilteringContextChat = 2, // Chat from another player + k_ETextFilteringContextName = 3, // Character or item name +}; + // function prototype for warning message hook #if defined( POSIX ) @@ -61,7 +79,7 @@ class ISteamUtils // the universe this client is connecting to virtual EUniverse GetConnectedUniverse() = 0; - // Steam server time - in PST, number of seconds since January 1, 1970 (i.e unix time) + // Steam server time. Number of seconds since January 1, 1970, GMT (i.e unix time) virtual uint32 GetServerRealTime() = 0; // returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database) @@ -76,8 +94,8 @@ class ISteamUtils // the destination buffer size should be 4 * height * width * sizeof(char) virtual bool GetImageRGBA( int iImage, uint8 *pubDest, int nDestBufferSize ) = 0; - // returns the IP of the reporting server for valve - currently only used in Source engine games - virtual bool GetCSERIPPort( uint32 *unIP, uint16 *usPort ) = 0; + // Deprecated. Do not call this. + STEAM_PRIVATE_API( virtual bool GetCSERIPPort( uint32 *unIP, uint16 *usPort ) = 0; ) // return the amount of battery power left in the current system in % [0..100], 255 for being on AC power virtual uint8 GetCurrentBatteryPower() = 0; @@ -95,9 +113,8 @@ class ISteamUtils virtual ESteamAPICallFailure GetAPICallFailureReason( SteamAPICall_t hSteamAPICall ) = 0; virtual bool GetAPICallResult( SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ) = 0; - // this needs to be called every frame to process matchmaking results - // redundant if you're already calling SteamAPI_RunCallbacks() - virtual void RunFrame() = 0; + // Deprecated. Applications should use SteamAPI_RunCallbacks() instead. Game servers do not need to call this function. + STEAM_PRIVATE_API( virtual void RunFrame() = 0; ) // returns the number of IPC calls made since the last time this function was called // Used for perf debugging so you can understand how many IPC calls your game makes per frame @@ -126,7 +143,6 @@ class ISteamUtils // refresh the screen with Present or SwapBuffers to allow the overlay to do it's work. virtual bool BOverlayNeedsPresent() = 0; -#ifndef _PS3 // Asynchronous call to check if an executable file has been signed using the public key set on the signing tab // of the partner site, for example to refuse to load modified executable files. // The result is returned in CheckFileSignature_t. @@ -135,20 +151,10 @@ class ISteamUtils // k_ECheckFileSignatureFileNotFound - The file does not exist on disk. // k_ECheckFileSignatureInvalidSignature - The file exists, and the signing tab has been set for this file, but the file is either not signed or the signature does not match. // k_ECheckFileSignatureValidSignature - The file is signed and the signature is valid. + STEAM_CALL_RESULT( CheckFileSignature_t ) virtual SteamAPICall_t CheckFileSignature( const char *szFileName ) = 0; -#endif - -#ifdef _PS3 - virtual void PostPS3SysutilCallback( uint64_t status, uint64_t param, void* userdata ) = 0; - virtual bool BIsReadyToShutdown() = 0; - virtual bool BIsPSNOnline() = 0; - - // Call this with localized strings for the language the game is running in, otherwise default english - // strings will be used by Steam. - virtual void SetPSNGameBootInviteStrings( const char *pchSubject, const char *pchBody ) = 0; -#endif - // Activates the Big Picture text input dialog which only supports gamepad input + // Activates the full-screen text input dialog which takes a initial text string and returns the text the user has typed virtual bool ShowGamepadTextInput( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32 unCharMax, const char *pchExistingText ) = 0; // Returns previously entered text & length @@ -163,10 +169,72 @@ class ISteamUtils // Sets the inset of the overlay notification from the corner specified by SetOverlayNotificationPosition. virtual void SetOverlayNotificationInset( int nHorizontalInset, int nVerticalInset ) = 0; + + // returns true if Steam & the Steam Overlay are running in Big Picture mode + // Games much be launched through the Steam client to enable the Big Picture overlay. During development, + // a game can be added as a non-steam game to the developers library to test this feature + virtual bool IsSteamInBigPictureMode() = 0; + + // ask SteamUI to create and render its OpenVR dashboard + virtual void StartVRDashboard() = 0; + + // Returns true if the HMD content will be streamed via Steam Remote Play + virtual bool IsVRHeadsetStreamingEnabled() = 0; + + // Set whether the HMD content will be streamed via Steam Remote Play + // If this is set to true, then the scene in the HMD headset will be streamed, and remote input will not be allowed. + // If this is set to false, then the application window will be streamed instead, and remote input will be allowed. + // The default is true unless "VRHeadsetStreaming" "0" is in the extended appinfo for a game. + // (this is useful for games that have asymmetric multiplayer gameplay) + virtual void SetVRHeadsetStreamingEnabled( bool bEnabled ) = 0; + + // Returns whether this steam client is a Steam China specific client, vs the global client. + virtual bool IsSteamChinaLauncher() = 0; + + // Initializes text filtering, loading dictionaries for the language the game is running in. + // unFilterOptions are reserved for future use and should be set to 0 + // Returns false if filtering is unavailable for the game's language, in which case FilterText() will act as a passthrough. + // + // Users can customize the text filter behavior in their Steam Account preferences: + // https://store.steampowered.com/account/preferences#CommunityContentPreferences + virtual bool InitFilterText( uint32 unFilterOptions = 0 ) = 0; + + // Filters the provided input message and places the filtered result into pchOutFilteredText, using legally required filtering and additional filtering based on the context and user settings + // eContext is the type of content in the input string + // sourceSteamID is the Steam ID that is the source of the input string (e.g. the player with the name, or who said the chat text) + // pchInputText is the input string that should be filtered, which can be ASCII or UTF-8 + // pchOutFilteredText is where the output will be placed, even if no filtering is performed + // nByteSizeOutFilteredText is the size (in bytes) of pchOutFilteredText, should be at least strlen(pchInputText)+1 + // Returns the number of characters (not bytes) filtered + virtual int FilterText( ETextFilteringContext eContext, CSteamID sourceSteamID, const char *pchInputMessage, char *pchOutFilteredText, uint32 nByteSizeOutFilteredText ) = 0; + + // Return what we believe your current ipv6 connectivity to "the internet" is on the specified protocol. + // This does NOT tell you if the Steam client is currently connected to Steam via ipv6. + virtual ESteamIPv6ConnectivityState GetIPv6ConnectivityState( ESteamIPv6ConnectivityProtocol eProtocol ) = 0; + + // returns true if currently running on the Steam Deck device + virtual bool IsSteamRunningOnSteamDeck() = 0; + + // Opens a floating keyboard over the game content and sends OS keyboard keys directly to the game. + // The text field position is specified in pixels relative the origin of the game window and is used to position the floating keyboard in a way that doesn't cover the text field + virtual bool ShowFloatingGamepadTextInput( EFloatingGamepadTextInputMode eKeyboardMode, int nTextFieldXPosition, int nTextFieldYPosition, int nTextFieldWidth, int nTextFieldHeight ) = 0; + + // In game launchers that don't have controller support you can call this to have Steam Input translate the controller input into mouse/kb to navigate the launcher + virtual void SetGameLauncherMode( bool bLauncherMode ) = 0; + + // Dismisses the floating keyboard. + virtual bool DismissFloatingGamepadTextInput() = 0; }; -#define STEAMUTILS_INTERFACE_VERSION "SteamUtils007" +#define STEAMUTILS_INTERFACE_VERSION "SteamUtils010" +// Global interface accessor +inline ISteamUtils *SteamUtils(); +STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamUtils *, SteamUtils, SteamInternal_FindOrCreateUserInterface( 0, STEAMUTILS_INTERFACE_VERSION ), "user", STEAMUTILS_INTERFACE_VERSION ); + +// Global accessor for the gameserver client +inline ISteamUtils *SteamGameServerUtils(); +STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamUtils *, SteamGameServerUtils, SteamInternal_FindOrCreateGameServerInterface( 0, STEAMUTILS_INTERFACE_VERSION ), "gameserver", STEAMUTILS_INTERFACE_VERSION ); // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) @@ -174,7 +242,7 @@ class ISteamUtils #elif defined( VALVE_CALLBACK_PACK_LARGE ) #pragma pack( push, 8 ) #else -#error isteamclient.h must be included +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx #endif //----------------------------------------------------------------------------- @@ -203,6 +271,8 @@ struct SteamAPICallCompleted_t { enum { k_iCallback = k_iSteamUtilsCallbacks + 3 }; SteamAPICall_t m_hAsyncCall; + int m_iCallback; + uint32 m_cubParam; }; @@ -235,76 +305,35 @@ struct CheckFileSignature_t ECheckFileSignature m_eCheckFileSignature; }; -#ifdef _PS3 -//----------------------------------------------------------------------------- -// callback for NetCtlNetStartDialog finishing on PS3 -//----------------------------------------------------------------------------- -struct NetStartDialogFinished_t -{ - enum { k_iCallback = k_iSteamUtilsCallbacks + 6 }; -}; - -//----------------------------------------------------------------------------- -// callback for NetCtlNetStartDialog unloaded on PS3 -//----------------------------------------------------------------------------- -struct NetStartDialogUnloaded_t -{ - enum { k_iCallback = k_iSteamUtilsCallbacks + 7 }; -}; - -//----------------------------------------------------------------------------- -// callback for system menu closing on PS3 - should trigger resyncronizing friends list, etc. -//----------------------------------------------------------------------------- -struct PS3SystemMenuClosed_t -{ - enum { k_iCallback = k_iSteamUtilsCallbacks + 8 }; -}; - -//----------------------------------------------------------------------------- -// callback for NP message being selected by user on PS3 - should trigger handling of message if it's a lobby invite, etc. -//----------------------------------------------------------------------------- -struct PS3NPMessageSelected_t -{ - enum { k_iCallback = k_iSteamUtilsCallbacks + 9 }; - uint32 dataid; -}; -//----------------------------------------------------------------------------- -// callback for when the PS3 keyboard dialog closes -//----------------------------------------------------------------------------- -struct PS3KeyboardDialogFinished_t -{ - enum { k_iCallback = k_iSteamUtilsCallbacks + 10 }; -}; +// k_iSteamUtilsCallbacks + 13 is taken -// k_iSteamUtilsCallbacks + 11 is taken //----------------------------------------------------------------------------- -// callback for PSN status changing on PS3 +// Full Screen gamepad text input has been closed //----------------------------------------------------------------------------- -struct PS3PSNStatusChange_t +struct GamepadTextInputDismissed_t { - enum { k_iCallback = k_iSteamUtilsCallbacks + 12 }; - bool m_bPSNOnline; + enum { k_iCallback = k_iSteamUtilsCallbacks + 14 }; + bool m_bSubmitted; // true if user entered & accepted text (Call ISteamUtils::GetEnteredGamepadTextInput() for text), false if canceled input + uint32 m_unSubmittedText; }; -#endif +// k_iSteamUtilsCallbacks + 15 through 35 are taken -// k_iSteamUtilsCallbacks + 13 is taken +STEAM_CALLBACK_BEGIN( AppResumingFromSuspend_t, k_iSteamUtilsCallbacks + 36 ) +STEAM_CALLBACK_END(0) +// k_iSteamUtilsCallbacks + 37 is taken //----------------------------------------------------------------------------- -// Big Picture gamepad text input has been closed +// The floating on-screen keyboard has been closed //----------------------------------------------------------------------------- -struct GamepadTextInputDismissed_t +struct FloatingGamepadTextInputDismissed_t { - enum { k_iCallback = k_iSteamUtilsCallbacks + 14 }; - bool m_bSubmitted; // true if user entered & accepted text (Call ISteamUtils::GetEnteredGamepadTextInput() for text), false if canceled input - uint32 m_unSubmittedText; + enum { k_iCallback = k_iSteamUtilsCallbacks + 38 }; }; -// k_iSteamUtilsCallbacks + 15 is taken - #pragma pack( pop ) #endif // ISTEAMUTILS_H diff --git a/public/steam/isteamvideo.h b/public/steam/isteamvideo.h new file mode 100644 index 00000000..4832d7b6 --- /dev/null +++ b/public/steam/isteamvideo.h @@ -0,0 +1,68 @@ +//====== Copyright 1996-2014 Valve Corporation, All rights reserved. ======= +// +// Purpose: interface to Steam Video +// +//============================================================================= + +#ifndef ISTEAMVIDEO_H +#define ISTEAMVIDEO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steam_api_common.h" + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + + + + +//----------------------------------------------------------------------------- +// Purpose: Steam Video API +//----------------------------------------------------------------------------- +class ISteamVideo +{ +public: + + // Get a URL suitable for streaming the given Video app ID's video + virtual void GetVideoURL( AppId_t unVideoAppID ) = 0; + + // returns true if user is uploading a live broadcast + virtual bool IsBroadcasting( int *pnNumViewers ) = 0; + + // Get the OPF Details for 360 Video Playback + STEAM_CALL_BACK( GetOPFSettingsResult_t ) + virtual void GetOPFSettings( AppId_t unVideoAppID ) = 0; + virtual bool GetOPFStringForApp( AppId_t unVideoAppID, char *pchBuffer, int32 *pnBufferSize ) = 0; +}; + +#define STEAMVIDEO_INTERFACE_VERSION "STEAMVIDEO_INTERFACE_V002" + +// Global interface accessor +inline ISteamVideo *SteamVideo(); +STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamVideo *, SteamVideo, STEAMVIDEO_INTERFACE_VERSION ); + +STEAM_CALLBACK_BEGIN( GetVideoURLResult_t, k_iSteamVideoCallbacks + 11 ) + STEAM_CALLBACK_MEMBER( 0, EResult, m_eResult ) + STEAM_CALLBACK_MEMBER( 1, AppId_t, m_unVideoAppID ) + STEAM_CALLBACK_MEMBER( 2, char, m_rgchURL[256] ) +STEAM_CALLBACK_END(3) + + +STEAM_CALLBACK_BEGIN( GetOPFSettingsResult_t, k_iSteamVideoCallbacks + 24 ) + STEAM_CALLBACK_MEMBER( 0, EResult, m_eResult ) + STEAM_CALLBACK_MEMBER( 1, AppId_t, m_unVideoAppID ) +STEAM_CALLBACK_END(2) + + +#pragma pack( pop ) + + +#endif // ISTEAMVIDEO_H diff --git a/public/steam/matchmakingtypes.h b/public/steam/matchmakingtypes.h index 08d5a966..0ae70c7c 100644 --- a/public/steam/matchmakingtypes.h +++ b/public/steam/matchmakingtypes.h @@ -82,7 +82,7 @@ class servernetadr_t // Access the IP uint32 GetIP() const; - void SetIP( uint32 ); + void SetIP( uint32 unIP ); // This gets the 'a.b.c.d:port' string with the connection port (instead of the query port). const char *GetConnectionAddressString() const; @@ -156,9 +156,9 @@ inline const char *servernetadr_t::ToString( uint32 unIP, uint16 usPort ) const static int nBuf = 0; unsigned char *ipByte = (unsigned char *)&unIP; #ifdef VALVE_BIG_ENDIAN - V_snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[0]), (int)(ipByte[1]), (int)(ipByte[2]), (int)(ipByte[3]), usPort ); + _snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[0]), (int)(ipByte[1]), (int)(ipByte[2]), (int)(ipByte[3]), usPort ); #else - V_snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[3]), (int)(ipByte[2]), (int)(ipByte[1]), (int)(ipByte[0]), usPort ); + _snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[3]), (int)(ipByte[2]), (int)(ipByte[1]), (int)(ipByte[0]), usPort ); #endif const char *pchRet = s[nBuf]; ++nBuf; diff --git a/public/steam/steam_api.h b/public/steam/steam_api.h index b6ab4edf..494f1dd1 100644 --- a/public/steam/steam_api.h +++ b/public/steam/steam_api.h @@ -1,6 +1,13 @@ -//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= +//====== Copyright Valve Corporation, All rights reserved. ==================== // -// Purpose: +// This header includes *all* of the interfaces and callback structures +// in the Steamworks SDK, and some high level functions to control the SDK +// (init, shutdown, etc) that you probably only need in one or two files. +// +// To save your compile times, we recommend that you not include this file +// in header files. Instead, include the specific headers for the interfaces +// and callback structures you need. The one file you might consider including +// in your precompiled header (e.g. stdafx.h) is steam_api_common.h // //============================================================================= @@ -10,6 +17,10 @@ #pragma once #endif +// Basic stuff +#include "steam_api_common.h" + +// All of the interfaces #include "isteamclient.h" #include "isteamuser.h" #include "isteamfriends.h" @@ -23,38 +34,19 @@ #include "isteammusic.h" #include "isteammusicremote.h" #include "isteamhttp.h" -#include "isteamunifiedmessages.h" #include "isteamcontroller.h" #include "isteamugc.h" #include "isteamapplist.h" #include "isteamhtmlsurface.h" +#include "isteaminventory.h" +#include "isteamvideo.h" +#include "isteamparentalsettings.h" +#include "isteaminput.h" +#include "isteamremoteplay.h" +#include "isteamnetworkingmessages.h" +#include "isteamnetworkingsockets.h" +#include "isteamnetworkingutils.h" -#if defined( _PS3 ) -#include "steamps3params.h" -#endif - -// Steam API export macro -#if defined( _WIN32 ) && !defined( _X360 ) - #if defined( STEAM_API_EXPORTS ) - #define S_API extern "C" __declspec( dllexport ) - #elif defined( STEAM_API_NODLL ) - #define S_API extern "C" - #else - #define S_API extern "C" __declspec( dllimport ) - #endif // STEAM_API_EXPORTS -#elif defined( GNUC ) - #if defined( STEAM_API_EXPORTS ) - #define S_API extern "C" __attribute__ ((visibility("default"))) - #else - #define S_API extern "C" - #endif // STEAM_API_EXPORTS -#else // !WIN32 - #if defined( STEAM_API_EXPORTS ) - #define S_API extern "C" - #else - #define S_API extern "C" - #endif // STEAM_API_EXPORTS -#endif //----------------------------------------------------------------------------------------------------------------------------------------------------------// // Steam API setup & shutdown @@ -63,567 +55,243 @@ // //----------------------------------------------------------------------------------------------------------------------------------------------------------// -// S_API void SteamAPI_Init(); (see below) -S_API void S_CALLTYPE SteamAPI_Shutdown(); -// checks if a local Steam client is running -S_API bool S_CALLTYPE SteamAPI_IsSteamRunning(); +// SteamAPI_Init must be called before using any other API functions. If it fails, an +// error message will be output to the debugger (or stderr) with further information. +S_API bool S_CALLTYPE SteamAPI_Init(); + +// SteamAPI_Shutdown should be called during process shutdown if possible. +S_API void S_CALLTYPE SteamAPI_Shutdown(); -// Detects if your executable was launched through the Steam client, and restarts your game through -// the client if necessary. The Steam client will be started if it is not running. +// SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam. // -// Returns: true if your executable was NOT launched through the Steam client. This function will -// then start your application through the client. Your current process should exit. +// Returns true if the current process should terminate. Steam is now re-launching your application. // -// false if your executable was started through the Steam client or a steam_appid.txt file -// is present in your game's directory (for development). Your current process should continue. +// Returns false if no action needs to be taken. This means that your executable was started through +// the Steam client, or a steam_appid.txt file is present in your game's directory (for development). +// Your current process should continue if false is returned. // -// NOTE: This function should be used only if you are using CEG or not using Steam's DRM. Once applied -// to your executable, Steam's DRM will handle restarting through Steam if necessary. +// NOTE: If you use the Steam DRM wrapper on your primary executable file, this check is unnecessary +// since the DRM wrapper will ensure that your application was launched properly through Steam. S_API bool S_CALLTYPE SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ); +// Many Steam API functions allocate a small amount of thread-local memory for parameter storage. +// SteamAPI_ReleaseCurrentThreadMemory() will free API memory associated with the calling thread. +// This function is also called automatically by SteamAPI_RunCallbacks(), so a single-threaded +// program never needs to explicitly call this function. +S_API void S_CALLTYPE SteamAPI_ReleaseCurrentThreadMemory(); + + // crash dump recording functions S_API void S_CALLTYPE SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID ); S_API void S_CALLTYPE SteamAPI_SetMiniDumpComment( const char *pchMsg ); -// interface pointers, configured by SteamAPI_Init() -S_API ISteamClient *S_CALLTYPE SteamClient(); +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +// steamclient.dll private wrapper functions +// +// The following functions are part of abstracting API access to the steamclient.dll, but should only be used in very specific cases +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +// SteamAPI_IsSteamRunning() returns true if Steam is currently running +S_API bool S_CALLTYPE SteamAPI_IsSteamRunning(); -// -// VERSION_SAFE_STEAM_API_INTERFACES is usually not necessary, but it provides safety against releasing -// new steam_api.dll's without recompiling/rereleasing modules that use it. -// -// If you use VERSION_SAFE_STEAM_API_INTERFACES, then you should call SteamAPI_InitSafe(). Also, to get the -// Steam interfaces, you must create and Init() a CSteamAPIContext (below) and use the interfaces in there. -// -// If you don't use VERSION_SAFE_STEAM_API_INTERFACES, then you can use SteamAPI_Init() and the SteamXXXX() -// functions below to get at the Steam interfaces. -// -#ifdef VERSION_SAFE_STEAM_API_INTERFACES -S_API bool S_CALLTYPE SteamAPI_InitSafe(); -#else +// returns the filename path of the current running Steam process, used if you need to load an explicit steam dll by name. +// DEPRECATED - implementation is Windows only, and the path returned is a UTF-8 string which must be converted to UTF-16 for use with Win32 APIs +S_API const char *SteamAPI_GetSteamInstallPath(); -#if defined(_PS3) -S_API bool S_CALLTYPE SteamAPI_Init( SteamPS3Params_t *pParams ); -#else -S_API bool S_CALLTYPE SteamAPI_Init(); -#endif +// sets whether or not Steam_RunCallbacks() should do a try {} catch (...) {} around calls to issuing callbacks +// This is ignored if you are using the manual callback dispatch method +S_API void SteamAPI_SetTryCatchCallbacks( bool bTryCatchCallbacks ); -S_API ISteamUser *S_CALLTYPE SteamUser(); -S_API ISteamFriends *S_CALLTYPE SteamFriends(); -S_API ISteamUtils *S_CALLTYPE SteamUtils(); -S_API ISteamMatchmaking *S_CALLTYPE SteamMatchmaking(); -S_API ISteamUserStats *S_CALLTYPE SteamUserStats(); -S_API ISteamApps *S_CALLTYPE SteamApps(); -S_API ISteamNetworking *S_CALLTYPE SteamNetworking(); -S_API ISteamMatchmakingServers *S_CALLTYPE SteamMatchmakingServers(); -S_API ISteamRemoteStorage *S_CALLTYPE SteamRemoteStorage(); -S_API ISteamScreenshots *S_CALLTYPE SteamScreenshots(); -S_API ISteamHTTP *S_CALLTYPE SteamHTTP(); -S_API ISteamUnifiedMessages *S_CALLTYPE SteamUnifiedMessages(); -S_API ISteamController *S_CALLTYPE SteamController(); -S_API ISteamUGC *S_CALLTYPE SteamUGC(); -S_API ISteamAppList *S_CALLTYPE SteamAppList(); -S_API ISteamMusic *S_CALLTYPE SteamMusic(); -S_API ISteamMusicRemote *S_CALLTYPE SteamMusicRemote(); -S_API ISteamHTMLSurface *S_CALLTYPE SteamHTMLSurface(); -#ifdef _PS3 -S_API ISteamPS3OverlayRender *S_CALLTYPE SteamPS3OverlayRender(); +#if defined( VERSION_SAFE_STEAM_API_INTERFACES ) +// exists only for backwards compat with code written against older SDKs +S_API bool S_CALLTYPE SteamAPI_InitSafe(); #endif -#endif // VERSION_SAFE_STEAM_API_INTERFACES +#if defined(USE_BREAKPAD_HANDLER) || defined(STEAM_API_EXPORTS) +// this should be called before the game initialized the steam APIs +// pchDate should be of the format "Mmm dd yyyy" (such as from the __ DATE __ macro ) +// pchTime should be of the format "hh:mm:ss" (such as from the __ TIME __ macro ) +// bFullMemoryDumps (Win32 only) -- writes out a uuid-full.dmp in the client/dumps folder +// pvContext-- can be NULL, will be the void * context passed into m_pfnPreMinidumpCallback +// PFNPreMinidumpCallback m_pfnPreMinidumpCallback -- optional callback which occurs just before a .dmp file is written during a crash. Applications can hook this to allow adding additional information into the .dmp comment stream. +S_API void S_CALLTYPE SteamAPI_UseBreakpadCrashHandler( char const *pchVersion, char const *pchDate, char const *pchTime, bool bFullMemoryDumps, void *pvContext, PFNPreMinidumpCallback m_pfnPreMinidumpCallback ); +S_API void S_CALLTYPE SteamAPI_SetBreakpadAppID( uint32 unAppID ); +#endif //----------------------------------------------------------------------------------------------------------------------------------------------------------// -// steam callback and call-result helpers // -// The following macros and classes are used to register your application for -// callbacks and call-results, which are delivered in a predictable manner. +// Manual callback loop // -// STEAM_CALLBACK macros are meant for use inside of a C++ class definition. -// They map a Steam notification callback directly to a class member function -// which is automatically prototyped as "void func( callback_type *pParam )". +// An alternative method for dispatching callbacks. Similar to a windows message loop. // -// CCallResult is used with specific Steam APIs that return "result handles". -// The handle can be passed to a CCallResult object's Set function, along with -// an object pointer and member-function pointer. The member function will -// be executed once the results of the Steam API call are available. +// If you use the manual callback dispatch, you must NOT use: // -// CCallback and CCallbackManual classes can be used instead of STEAM_CALLBACK -// macros if you require finer control over registration and unregistration. +// - SteamAPI_RunCallbacks or SteamGameServer_RunCallbacks +// - STEAM_CALLBACK, CCallResult, CCallback, or CCallbackManual // -// Callbacks and call-results are queued automatically and are only -// delivered/executed when your application calls SteamAPI_RunCallbacks(). -//----------------------------------------------------------------------------------------------------------------------------------------------------------// - -S_API void S_CALLTYPE SteamAPI_RunCallbacks(); +// Here is the basic template for replacing SteamAPI_RunCallbacks() with manual dispatch +/* - - -// Declares a callback member function plus a helper member variable which -// registers the callback on object creation and unregisters on destruction. -// The optional fourth 'var' param exists only for backwards-compatibility -// and can be ignored. -#define STEAM_CALLBACK( thisclass, func, .../*callback_type, [deprecated] var*/ ) \ - _STEAM_CALLBACK_SELECT( ( __VA_ARGS__, 4, 3 ), ( /**/, thisclass, func, __VA_ARGS__ ) ) - -// Declares a callback function and a named CCallbackManual variable which -// has Register and Unregister functions instead of automatic registration. -#define STEAM_CALLBACK_MANUAL( thisclass, func, callback_type, var ) \ - CCallbackManual< thisclass, callback_type > var; void func( callback_type *pParam ) - - -// Internal functions used by the utility CCallback objects to receive callbacks -S_API void S_CALLTYPE SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback ); -S_API void S_CALLTYPE SteamAPI_UnregisterCallback( class CCallbackBase *pCallback ); -// Internal functions used by the utility CCallResult objects to receive async call results -S_API void S_CALLTYPE SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); -S_API void S_CALLTYPE SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); - - -//----------------------------------------------------------------------------- -// Purpose: base for callbacks and call results - internal implementation detail -//----------------------------------------------------------------------------- -class CCallbackBase -{ -public: - CCallbackBase() { m_nCallbackFlags = 0; m_iCallback = 0; } - // don't add a virtual destructor because we export this binary interface across dll's - virtual void Run( void *pvParam ) = 0; - virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) = 0; - int GetICallback() { return m_iCallback; } - virtual int GetCallbackSizeBytes() = 0; - -protected: - enum { k_ECallbackFlagsRegistered = 0x01, k_ECallbackFlagsGameServer = 0x02 }; - uint8 m_nCallbackFlags; - int m_iCallback; - friend class CCallbackMgr; - -private: - CCallbackBase( const CCallbackBase& ); - CCallbackBase& operator=( const CCallbackBase& ); -}; - -//----------------------------------------------------------------------------- -// Purpose: templated base for callbacks - internal implementation detail -//----------------------------------------------------------------------------- -template< int sizeof_P > -class CCallbackImpl : protected CCallbackBase -{ -public: - ~CCallbackImpl() { if ( m_nCallbackFlags & k_ECallbackFlagsRegistered ) SteamAPI_UnregisterCallback( this ); } - void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; } - -protected: - virtual void Run( void *pvParam ) = 0; - virtual void Run( void *pvParam, bool /*bIOFailure*/, SteamAPICall_t /*hSteamAPICall*/ ) { Run( pvParam ); } - virtual int GetCallbackSizeBytes() { return sizeof_P; } -}; - - -//----------------------------------------------------------------------------- -// Purpose: maps a steam async call result to a class member function -// template params: T = local class, P = parameter struct -//----------------------------------------------------------------------------- -template< class T, class P > -class CCallResult : private CCallbackBase -{ -public: - typedef void (T::*func_t)( P*, bool ); - - CCallResult() - { - m_hAPICall = k_uAPICallInvalid; - m_pObj = NULL; - m_Func = NULL; - m_iCallback = P::k_iCallback; - } - - void Set( SteamAPICall_t hAPICall, T *p, func_t func ) - { - if ( m_hAPICall ) - SteamAPI_UnregisterCallResult( this, m_hAPICall ); - - m_hAPICall = hAPICall; - m_pObj = p; - m_Func = func; - - if ( hAPICall ) - SteamAPI_RegisterCallResult( this, hAPICall ); - } - - bool IsActive() const + HSteamPipe hSteamPipe = SteamAPI_GetHSteamPipe(); // See also SteamGameServer_GetHSteamPipe() + SteamAPI_ManualDispatch_RunFrame( hSteamPipe ) + CallbackMsg_t callback; + while ( SteamAPI_ManualDispatch_GetNextCallback( hSteamPipe, &callback ) ) { - return ( m_hAPICall != k_uAPICallInvalid ); - } - - void Cancel() - { - if ( m_hAPICall != k_uAPICallInvalid ) + // Check for dispatching API call results + if ( callback.m_iCallback == SteamAPICallCompleted_t::k_iCallback ) { - SteamAPI_UnregisterCallResult( this, m_hAPICall ); - m_hAPICall = k_uAPICallInvalid; + SteamAPICallCompleted_t *pCallCompleted = (SteamAPICallCompleted_t *)callback. + void *pTmpCallResult = malloc( pCallback->m_cubParam ); + bool bFailed; + if ( SteamAPI_ManualDispatch_GetAPICallResult( hSteamPipe, pCallCompleted->m_hAsyncCall, pTmpCallResult, pCallback->m_cubParam, pCallback->m_iCallback, &bFailed ) ) + { + // Dispatch the call result to the registered handler(s) for the + // call identified by pCallCompleted->m_hAsyncCall + } + free( pTmpCallResult ); } - - } - - ~CCallResult() - { - Cancel(); - } - - void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; } -private: - virtual void Run( void *pvParam ) - { - m_hAPICall = k_uAPICallInvalid; // caller unregisters for us - (m_pObj->*m_Func)( (P *)pvParam, false ); - } - virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) - { - if ( hSteamAPICall == m_hAPICall ) + else { - m_hAPICall = k_uAPICallInvalid; // caller unregisters for us - (m_pObj->*m_Func)( (P *)pvParam, bIOFailure ); + // Look at callback.m_iCallback to see what kind of callback it is, + // and dispatch to appropriate handler(s) } + SteamAPI_ManualDispatch_FreeLastCallback( hSteamPipe ); } - virtual int GetCallbackSizeBytes() - { - return sizeof( P ); - } - - SteamAPICall_t m_hAPICall; - T *m_pObj; - func_t m_Func; -}; - - - -//----------------------------------------------------------------------------- -// Purpose: maps a steam callback to a class member function -// template params: T = local class, P = parameter struct, -// bGameserver = listen for gameserver callbacks instead of client callbacks -//----------------------------------------------------------------------------- -template< class T, class P, bool bGameserver = false > -class CCallback : public CCallbackImpl< sizeof( P ) > -{ -public: - typedef void (T::*func_t)(P*); - - // NOTE: If you can't provide the correct parameters at construction time, you should - // use the CCallbackManual callback object (STEAM_CALLBACK_MANUAL macro) instead. - CCallback( T *pObj, func_t func ) : m_pObj( NULL ), m_Func( NULL ) - { - if ( bGameserver ) - { - this->SetGameserverFlag(); - } - Register( pObj, func ); - } - - // manual registration of the callback - void Register( T *pObj, func_t func ) - { - if ( !pObj || !func ) - return; - - if ( this->m_nCallbackFlags & CCallbackBase::k_ECallbackFlagsRegistered ) - Unregister(); - - m_pObj = pObj; - m_Func = func; - // SteamAPI_RegisterCallback sets k_ECallbackFlagsRegistered - SteamAPI_RegisterCallback( this, P::k_iCallback ); - } - - void Unregister() - { - // SteamAPI_UnregisterCallback removes k_ECallbackFlagsRegistered - SteamAPI_UnregisterCallback( this ); - } - -protected: - virtual void Run( void *pvParam ) - { - (m_pObj->*m_Func)( (P *)pvParam ); - } - - T *m_pObj; - func_t m_Func; -}; - - -//----------------------------------------------------------------------------- -// Purpose: subclass of CCallback which allows default-construction in -// an unregistered state; you must call Register manually -//----------------------------------------------------------------------------- -template< class T, class P, bool bGameServer = false > -class CCallbackManual : public CCallback< T, P, bGameServer > -{ -public: - CCallbackManual() : CCallback< T, P, bGameServer >( NULL, NULL ) {} - - // Inherits public Register and Unregister functions from base class -}; - - - -//----------------------------------------------------------------------------- -// The following macros are implementation details, not intended for public use -//----------------------------------------------------------------------------- -#define _STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) -#define _STEAM_CALLBACK_HELPER( _1, _2, SELECTED, ... ) _STEAM_CALLBACK_##SELECTED -#define _STEAM_CALLBACK_SELECT( X, Y ) _STEAM_CALLBACK_HELPER X Y -#define _STEAM_CALLBACK_3( extra_code, thisclass, func, param ) \ - struct CCallbackInternal_ ## func : private CCallbackImpl< sizeof( param ) > { \ - CCallbackInternal_ ## func () { extra_code SteamAPI_RegisterCallback( this, param::k_iCallback ); } \ - CCallbackInternal_ ## func ( const CCallbackInternal_ ## func & ) { extra_code SteamAPI_RegisterCallback( this, param::k_iCallback ); } \ - CCallbackInternal_ ## func & operator=( const CCallbackInternal_ ## func & ) { return *this; } \ - private: virtual void Run( void *pvParam ) { _STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) \ - thisclass *pOuter = reinterpret_cast( reinterpret_cast(this) - offsetof( thisclass, m_steamcallback_ ## func ) ); \ - pOuter->func( reinterpret_cast( pvParam ) ); \ - } \ - } m_steamcallback_ ## func ; void func( param *pParam ) -#define _STEAM_CALLBACK_4( _, thisclass, func, param, var ) \ - CCallback< thisclass, param > var; void func( param *pParam ) - - -#ifdef _WIN32 -// disable this warning; this pattern need for steam callback registration -#pragma warning( disable: 4355 ) // 'this' : used in base member initializer list -#endif - -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -// steamclient.dll private wrapper functions -// -// The following functions are part of abstracting API access to the steamclient.dll, but should only be used in very specific cases +*/ //----------------------------------------------------------------------------------------------------------------------------------------------------------// -// pumps out all the steam messages, calling the register callback -S_API void Steam_RunCallbacks( HSteamPipe hSteamPipe, bool bGameServerCallbacks ); +/// Inform the API that you wish to use manual event dispatch. This must be called after SteamAPI_Init, but before +/// you use any of the other manual dispatch functions below. +S_API void S_CALLTYPE SteamAPI_ManualDispatch_Init(); -// register the callback funcs to use to interact with the steam dll -S_API void Steam_RegisterInterfaceFuncs( void *hModule ); +/// Perform certain periodic actions that need to be performed. +S_API void S_CALLTYPE SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe ); -// returns the HSteamUser of the last user to dispatch a callback -S_API HSteamUser Steam_GetHSteamUserCurrent(); +/// Fetch the next pending callback on the given pipe, if any. If a callback is available, true is returned +/// and the structure is populated. In this case, you MUST call SteamAPI_ManualDispatch_FreeLastCallback +/// (after dispatching the callback) before calling SteamAPI_ManualDispatch_GetNextCallback again. +S_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ); -// returns the filename path of the current running Steam process, used if you need to load an explicit steam dll by name -S_API const char *SteamAPI_GetSteamInstallPath(); +/// You must call this after dispatching the callback, if SteamAPI_ManualDispatch_GetNextCallback returns true. +S_API void S_CALLTYPE SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe ); -// returns the pipe we are communicating to Steam with -S_API HSteamPipe SteamAPI_GetHSteamPipe(); +/// Return the call result for the specified call on the specified pipe. You really should +/// only call this in a handler for SteamAPICallCompleted_t callback. +S_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ); -// sets whether or not Steam_RunCallbacks() should do a try {} catch (...) {} around calls to issuing callbacks -S_API void SteamAPI_SetTryCatchCallbacks( bool bTryCatchCallbacks ); - -// backwards compat export, passes through to SteamAPI_ variants -S_API HSteamPipe GetHSteamPipe(); -S_API HSteamUser GetHSteamUser(); - -#ifdef VERSION_SAFE_STEAM_API_INTERFACES //----------------------------------------------------------------------------------------------------------------------------------------------------------// -// VERSION_SAFE_STEAM_API_INTERFACES uses CSteamAPIContext to provide interfaces to each module in a way that -// lets them each specify the interface versions they are compiled with. // -// It's important that these stay inlined in the header so the calling module specifies the interface versions -// for whatever Steam API version it has. +// CSteamAPIContext +// +// Deprecated! This is not necessary any more. Please use the global accessors directly +// //----------------------------------------------------------------------------------------------------------------------------------------------------------// -S_API HSteamUser SteamAPI_GetHSteamUser(); - -class CSteamAPIContext -{ -public: - CSteamAPIContext(); - void Clear(); - - bool Init(); - - ISteamUser* SteamUser() { return m_pSteamUser; } - ISteamFriends* SteamFriends() { return m_pSteamFriends; } - ISteamUtils* SteamUtils() { return m_pSteamUtils; } - ISteamMatchmaking* SteamMatchmaking() { return m_pSteamMatchmaking; } - ISteamUserStats* SteamUserStats() { return m_pSteamUserStats; } - ISteamApps* SteamApps() { return m_pSteamApps; } - ISteamMatchmakingServers* SteamMatchmakingServers() { return m_pSteamMatchmakingServers; } - ISteamNetworking* SteamNetworking() { return m_pSteamNetworking; } - ISteamRemoteStorage* SteamRemoteStorage() { return m_pSteamRemoteStorage; } - ISteamScreenshots* SteamScreenshots() { return m_pSteamScreenshots; } - ISteamHTTP* SteamHTTP() { return m_pSteamHTTP; } - ISteamUnifiedMessages* SteamUnifiedMessages() { return m_pSteamUnifiedMessages; } - ISteamController* SteamController() { return m_pController; } - ISteamUGC* SteamUGC() { return m_pSteamUGC; } - ISteamAppList* SteamAppList() { return m_pSteamAppList; } - ISteamMusic* SteamMusic() { return m_pSteamMusic; } - ISteamMusicRemote* SteamMusicRemote() { return m_pSteamMusicRemote; } - ISteamHTMLSurface* SteamHTMLSurface() { return m_pSteamHTMLSurface; } -#ifdef _PS3 - ISteamPS3OverlayRender* SteamPS3OverlayRender() { return m_pSteamPS3OverlayRender; } -#endif - -private: - ISteamUser *m_pSteamUser; - ISteamFriends *m_pSteamFriends; - ISteamUtils *m_pSteamUtils; - ISteamMatchmaking *m_pSteamMatchmaking; - ISteamUserStats *m_pSteamUserStats; - ISteamApps *m_pSteamApps; - ISteamMatchmakingServers *m_pSteamMatchmakingServers; - ISteamNetworking *m_pSteamNetworking; - ISteamRemoteStorage *m_pSteamRemoteStorage; - ISteamScreenshots *m_pSteamScreenshots; - ISteamHTTP *m_pSteamHTTP; - ISteamUnifiedMessages*m_pSteamUnifiedMessages; - ISteamController *m_pController; - ISteamUGC *m_pSteamUGC; - ISteamAppList *m_pSteamAppList; - ISteamMusic *m_pSteamMusic; - ISteamMusicRemote *m_pSteamMusicRemote; - ISteamHTMLSurface *m_pSteamHTMLSurface; -#ifdef _PS3 - ISteamPS3OverlayRender *m_pSteamPS3OverlayRender; -#endif -}; - -inline CSteamAPIContext::CSteamAPIContext() -{ - Clear(); -} - -inline void CSteamAPIContext::Clear() -{ - m_pSteamUser = NULL; - m_pSteamFriends = NULL; - m_pSteamUtils = NULL; - m_pSteamMatchmaking = NULL; - m_pSteamUserStats = NULL; - m_pSteamApps = NULL; - m_pSteamMatchmakingServers = NULL; - m_pSteamNetworking = NULL; - m_pSteamRemoteStorage = NULL; - m_pSteamHTTP = NULL; - m_pSteamScreenshots = NULL; - m_pSteamMusic = NULL; - m_pSteamUnifiedMessages = NULL; - m_pController = NULL; - m_pSteamUGC = NULL; - m_pSteamAppList = NULL; - m_pSteamMusic = NULL; - m_pSteamMusicRemote= NULL; - m_pSteamHTMLSurface = NULL; -#ifdef _PS3 - m_pSteamPS3OverlayRender = NULL; -#endif -} +#ifndef STEAM_API_EXPORTS -// This function must be inlined so the module using steam_api.dll gets the version names they want. inline bool CSteamAPIContext::Init() { - if ( !SteamClient() ) + m_pSteamClient = ::SteamClient(); + if ( !m_pSteamClient ) return false; - HSteamUser hSteamUser = SteamAPI_GetHSteamUser(); - HSteamPipe hSteamPipe = SteamAPI_GetHSteamPipe(); - - m_pSteamUser = SteamClient()->GetISteamUser( hSteamUser, hSteamPipe, STEAMUSER_INTERFACE_VERSION ); + m_pSteamUser = ::SteamUser(); if ( !m_pSteamUser ) return false; - m_pSteamFriends = SteamClient()->GetISteamFriends( hSteamUser, hSteamPipe, STEAMFRIENDS_INTERFACE_VERSION ); + m_pSteamFriends = ::SteamFriends(); if ( !m_pSteamFriends ) return false; - m_pSteamUtils = SteamClient()->GetISteamUtils( hSteamPipe, STEAMUTILS_INTERFACE_VERSION ); + m_pSteamUtils = ::SteamUtils(); if ( !m_pSteamUtils ) return false; - m_pSteamMatchmaking = SteamClient()->GetISteamMatchmaking( hSteamUser, hSteamPipe, STEAMMATCHMAKING_INTERFACE_VERSION ); + m_pSteamMatchmaking = ::SteamMatchmaking(); if ( !m_pSteamMatchmaking ) return false; - m_pSteamMatchmakingServers = SteamClient()->GetISteamMatchmakingServers( hSteamUser, hSteamPipe, STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION ); + m_pSteamGameSearch = ::SteamGameSearch(); + if ( !m_pSteamGameSearch ) + return false; + +#if !defined( IOSALL) // Not yet supported on iOS. + m_pSteamMatchmakingServers = ::SteamMatchmakingServers(); if ( !m_pSteamMatchmakingServers ) return false; +#endif - m_pSteamUserStats = SteamClient()->GetISteamUserStats( hSteamUser, hSteamPipe, STEAMUSERSTATS_INTERFACE_VERSION ); + m_pSteamUserStats = ::SteamUserStats(); if ( !m_pSteamUserStats ) return false; - - m_pSteamApps = SteamClient()->GetISteamApps( hSteamUser, hSteamPipe, STEAMAPPS_INTERFACE_VERSION ); + + m_pSteamApps = ::SteamApps(); if ( !m_pSteamApps ) return false; - m_pSteamNetworking = SteamClient()->GetISteamNetworking( hSteamUser, hSteamPipe, STEAMNETWORKING_INTERFACE_VERSION ); + m_pSteamNetworking = ::SteamNetworking(); if ( !m_pSteamNetworking ) return false; - m_pSteamRemoteStorage = SteamClient()->GetISteamRemoteStorage( hSteamUser, hSteamPipe, STEAMREMOTESTORAGE_INTERFACE_VERSION ); + m_pSteamRemoteStorage = ::SteamRemoteStorage(); if ( !m_pSteamRemoteStorage ) return false; - m_pSteamScreenshots = SteamClient()->GetISteamScreenshots( hSteamUser, hSteamPipe, STEAMSCREENSHOTS_INTERFACE_VERSION ); + m_pSteamScreenshots = ::SteamScreenshots(); if ( !m_pSteamScreenshots ) return false; - m_pSteamHTTP = SteamClient()->GetISteamHTTP( hSteamUser, hSteamPipe, STEAMHTTP_INTERFACE_VERSION ); + m_pSteamHTTP = ::SteamHTTP(); if ( !m_pSteamHTTP ) return false; - m_pSteamUnifiedMessages = SteamClient()->GetISteamUnifiedMessages( hSteamUser, hSteamPipe, STEAMUNIFIEDMESSAGES_INTERFACE_VERSION ); - if ( !m_pSteamUnifiedMessages ) - return false; - - m_pController = SteamClient()->GetISteamController( hSteamUser, hSteamPipe, STEAMCONTROLLER_INTERFACE_VERSION ); + m_pController = ::SteamController(); if ( !m_pController ) return false; - m_pSteamUGC = SteamClient()->GetISteamUGC( hSteamUser, hSteamPipe, STEAMUGC_INTERFACE_VERSION ); + m_pSteamUGC = ::SteamUGC(); if ( !m_pSteamUGC ) return false; - m_pSteamAppList = SteamClient()->GetISteamAppList( hSteamUser, hSteamPipe, STEAMAPPLIST_INTERFACE_VERSION ); + m_pSteamAppList = ::SteamAppList(); if ( !m_pSteamAppList ) return false; - m_pSteamMusic = SteamClient()->GetISteamMusic( hSteamUser, hSteamPipe, STEAMMUSIC_INTERFACE_VERSION ); + m_pSteamMusic = ::SteamMusic(); if ( !m_pSteamMusic ) - { return false; - } - m_pSteamMusicRemote = SteamClient()->GetISteamMusicRemote( hSteamUser, hSteamPipe, STEAMMUSICREMOTE_INTERFACE_VERSION ); + m_pSteamMusicRemote = ::SteamMusicRemote(); if ( !m_pSteamMusicRemote ) - { return false; - } - m_pSteamHTMLSurface = SteamClient()->GetISteamHTMLSurface( hSteamUser, hSteamPipe, STEAMHTMLSURFACE_INTERFACE_VERSION ); +#if !defined( ANDROID ) && !defined( IOSALL) // Not yet supported on Android or ios. + m_pSteamHTMLSurface = ::SteamHTMLSurface(); if ( !m_pSteamHTMLSurface ) - { + return false; +#endif + + m_pSteamInventory = ::SteamInventory(); + if ( !m_pSteamInventory ) return false; - } -#ifdef _PS3 - m_pSteamPS3OverlayRender = SteamClient()->GetISteamPS3OverlayRender(); -#endif + m_pSteamVideo = ::SteamVideo(); + if ( !m_pSteamVideo ) + return false; + + m_pSteamParentalSettings = ::SteamParentalSettings(); + if ( !m_pSteamParentalSettings ) + return false; + + m_pSteamInput = ::SteamInput(); + if ( !m_pSteamInput ) + return false; return true; } -#endif // VERSION_SAFE_STEAM_API_INTERFACES - -#if defined(USE_BREAKPAD_HANDLER) || defined(STEAM_API_EXPORTS) -// this should be called before the game initialized the steam APIs -// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE__ macro ) -// pchTime should be of the format "hh:mm:ss" (such as from the __TIME__ macro ) -// bFullMemoryDumps (Win32 only) -- writes out a uuid-full.dmp in the client/dumps folder -// pvContext-- can be NULL, will be the void * context passed into m_pfnPreMinidumpCallback -// PFNPreMinidumpCallback m_pfnPreMinidumpCallback -- optional callback which occurs just before a .dmp file is written during a crash. Applications can hook this to allow adding additional information into the .dmp comment stream. -S_API void S_CALLTYPE SteamAPI_UseBreakpadCrashHandler( char const *pchVersion, char const *pchDate, char const *pchTime, bool bFullMemoryDumps, void *pvContext, PFNPreMinidumpCallback m_pfnPreMinidumpCallback ); -S_API void S_CALLTYPE SteamAPI_SetBreakpadAppID( uint32 unAppID ); #endif #endif // STEAM_API_H diff --git a/public/steam/steam_api.json b/public/steam/steam_api.json new file mode 100644 index 00000000..aa99da9f --- /dev/null +++ b/public/steam/steam_api.json @@ -0,0 +1,14043 @@ +{ + "callback_structs": [ + { + "callback_id": 101, + "fields": [], + "struct": "SteamServersConnected_t" + }, + { + "callback_id": 102, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_bStillRetrying", "fieldtype":"bool" } + ], + "struct": "SteamServerConnectFailure_t" + }, + { + "callback_id": 103, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "SteamServersDisconnected_t" + }, + { + "callback_id": 113, + "fields": [ + { "fieldname":"m_uAppID", "fieldtype":"uint32" }, + { "fieldname":"m_unGameServerIP", "fieldtype":"uint32" }, + { "fieldname":"m_usGameServerPort", "fieldtype":"uint16" }, + { "fieldname":"m_bSecure", "fieldtype":"uint16" }, + { "fieldname":"m_uReason", "fieldtype":"uint32" } + ], + "struct": "ClientGameServerDeny_t" + }, + { + "callback_id": 117, + "enums": [ + { + "enumname": "EFailureType", + "fqname": "IPCFailure_t::EFailureType", + "values": [ + { "name":"k_EFailureFlushedCallbackQueue", "value":"0" }, + { "name":"k_EFailurePipeFail", "value":"1" } + ] + } + ], + "fields": [ + { "fieldname":"m_eFailureType", "fieldtype":"uint8" } + ], + "struct": "IPCFailure_t" + }, + { + "callback_id": 125, + "fields": [], + "struct": "LicensesUpdated_t" + }, + { + "callback_id": 143, + "fields": [ + { "fieldname":"m_SteamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_eAuthSessionResponse", "fieldtype":"EAuthSessionResponse" }, + { "fieldname":"m_OwnerSteamID", "fieldtype":"CSteamID" } + ], + "struct": "ValidateAuthTicketResponse_t" + }, + { + "callback_id": 152, + "fields": [ + { "fieldname":"m_unAppID", "fieldtype":"uint32" }, + { "fieldname":"m_ulOrderID", "fieldtype":"uint64" }, + { "fieldname":"m_bAuthorized", "fieldtype":"uint8" } + ], + "struct": "MicroTxnAuthorizationResponse_t" + }, + { + "callback_id": 154, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "EncryptedAppTicketResponse_t" + }, + { + "callback_id": 163, + "fields": [ + { "fieldname":"m_hAuthTicket", "fieldtype":"HAuthTicket" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "GetAuthSessionTicketResponse_t" + }, + { + "callback_id": 164, + "fields": [ + { "fieldname":"m_szURL", "fieldtype":"char [256]" } + ], + "struct": "GameWebCallback_t" + }, + { + "callback_id": 165, + "fields": [ + { "fieldname":"m_szURL", "fieldtype":"char [512]" } + ], + "struct": "StoreAuthURLResponse_t" + }, + { + "callback_id": 166, + "fields": [ + { "fieldname":"m_bAllowed", "fieldtype":"bool" }, + { "fieldname":"m_eNotAllowedReason", "fieldtype":"EMarketNotAllowedReasonFlags" }, + { "fieldname":"m_rtAllowedAtTime", "fieldtype":"RTime32" }, + { "fieldname":"m_cdaySteamGuardRequiredDays", "fieldtype":"int" }, + { "fieldname":"m_cdayNewDeviceCooldown", "fieldtype":"int" } + ], + "struct": "MarketEligibilityResponse_t" + }, + { + "callback_id": 167, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_appid", "fieldtype":"AppId_t" }, + { "fieldname":"m_bApplicable", "fieldtype":"bool" }, + { "fieldname":"m_csecsLast5h", "fieldtype":"int32" }, + { "fieldname":"m_progress", "fieldtype":"EDurationControlProgress" }, + { "fieldname":"m_notification", "fieldtype":"EDurationControlNotification" }, + { "fieldname":"m_csecsToday", "fieldtype":"int32" }, + { "fieldname":"m_csecsRemaining", "fieldtype":"int32" } + ], + "struct": "DurationControl_t" + }, + { + "callback_id": 304, + "fields": [ + { "fieldname":"m_ulSteamID", "fieldtype":"uint64" }, + { "fieldname":"m_nChangeFlags", "fieldtype":"int" } + ], + "struct": "PersonaStateChange_t" + }, + { + "callback_id": 331, + "fields": [ + { "fieldname":"m_bActive", "fieldtype":"uint8" } + ], + "struct": "GameOverlayActivated_t" + }, + { + "callback_id": 332, + "fields": [ + { "fieldname":"m_rgchServer", "fieldtype":"char [64]" }, + { "fieldname":"m_rgchPassword", "fieldtype":"char [64]" } + ], + "struct": "GameServerChangeRequested_t" + }, + { + "callback_id": 333, + "fields": [ + { "fieldname":"m_steamIDLobby", "fieldtype":"CSteamID" }, + { "fieldname":"m_steamIDFriend", "fieldtype":"CSteamID" } + ], + "struct": "GameLobbyJoinRequested_t" + }, + { + "callback_id": 334, + "fields": [ + { "fieldname":"m_steamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_iImage", "fieldtype":"int" }, + { "fieldname":"m_iWide", "fieldtype":"int" }, + { "fieldname":"m_iTall", "fieldtype":"int" } + ], + "struct": "AvatarImageLoaded_t" + }, + { + "callback_id": 335, + "fields": [ + { "fieldname":"m_steamIDClan", "fieldtype":"CSteamID" }, + { "fieldname":"m_cOfficers", "fieldtype":"int" }, + { "fieldname":"m_bSuccess", "fieldtype":"uint8" } + ], + "struct": "ClanOfficerListResponse_t" + }, + { + "callback_id": 336, + "fields": [ + { "fieldname":"m_steamIDFriend", "fieldtype":"CSteamID" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "FriendRichPresenceUpdate_t" + }, + { + "callback_id": 337, + "fields": [ + { "fieldname":"m_steamIDFriend", "fieldtype":"CSteamID" }, + { "fieldname":"m_rgchConnect", "fieldtype":"char [256]" } + ], + "struct": "GameRichPresenceJoinRequested_t" + }, + { + "callback_id": 338, + "fields": [ + { "fieldname":"m_steamIDClanChat", "fieldtype":"CSteamID" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" }, + { "fieldname":"m_iMessageID", "fieldtype":"int" } + ], + "struct": "GameConnectedClanChatMsg_t" + }, + { + "callback_id": 339, + "fields": [ + { "fieldname":"m_steamIDClanChat", "fieldtype":"CSteamID" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "GameConnectedChatJoin_t" + }, + { + "callback_id": 340, + "fields": [ + { "fieldname":"m_steamIDClanChat", "fieldtype":"CSteamID" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" }, + { "fieldname":"m_bKicked", "fieldtype":"bool" }, + { "fieldname":"m_bDropped", "fieldtype":"bool" } + ], + "struct": "GameConnectedChatLeave_t" + }, + { + "callback_id": 341, + "fields": [ + { "fieldname":"m_bSuccess", "fieldtype":"bool" } + ], + "struct": "DownloadClanActivityCountsResult_t" + }, + { + "callback_id": 342, + "fields": [ + { "fieldname":"m_steamIDClanChat", "fieldtype":"CSteamID" }, + { "fieldname":"m_eChatRoomEnterResponse", "fieldtype":"EChatRoomEnterResponse" } + ], + "struct": "JoinClanChatRoomCompletionResult_t" + }, + { + "callback_id": 343, + "fields": [ + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" }, + { "fieldname":"m_iMessageID", "fieldtype":"int" } + ], + "struct": "GameConnectedFriendChatMsg_t" + }, + { + "callback_id": 344, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_nCount", "fieldtype":"int" } + ], + "struct": "FriendsGetFollowerCount_t" + }, + { + "callback_id": 345, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_bIsFollowing", "fieldtype":"bool" } + ], + "struct": "FriendsIsFollowing_t" + }, + { + "callback_id": 346, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_rgSteamID", "fieldtype":"CSteamID [50]" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" } + ], + "struct": "FriendsEnumerateFollowingList_t" + }, + { + "callback_id": 347, + "fields": [ + { "fieldname":"m_bSuccess", "fieldtype":"bool" }, + { "fieldname":"m_bLocalSuccess", "fieldtype":"bool" }, + { "fieldname":"m_result", "fieldtype":"EResult" } + ], + "struct": "SetPersonaNameResponse_t" + }, + { + "callback_id": 348, + "fields": [], + "struct": "UnreadChatMessagesChanged_t" + }, + { + "callback_id": 349, + "fields": [ + { "fieldname":"rgchURI", "fieldtype":"char [1024]" } + ], + "struct": "OverlayBrowserProtocolNavigation_t" + }, + { + "callback_id": 350, + "fields": [ + { "fieldname":"m_steamID", "fieldtype":"CSteamID" } + ], + "struct": "EquippedProfileItemsChanged_t" + }, + { + "callback_id": 351, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_bHasAnimatedAvatar", "fieldtype":"bool" }, + { "fieldname":"m_bHasAvatarFrame", "fieldtype":"bool" }, + { "fieldname":"m_bHasProfileModifier", "fieldtype":"bool" }, + { "fieldname":"m_bHasProfileBackground", "fieldtype":"bool" }, + { "fieldname":"m_bHasMiniProfileBackground", "fieldtype":"bool" } + ], + "struct": "EquippedProfileItems_t" + }, + { + "callback_id": 701, + "fields": [], + "struct": "IPCountry_t" + }, + { + "callback_id": 702, + "fields": [ + { "fieldname":"m_nMinutesBatteryLeft", "fieldtype":"uint8" } + ], + "struct": "LowBatteryPower_t" + }, + { + "callback_id": 703, + "fields": [ + { "fieldname":"m_hAsyncCall", "fieldtype":"SteamAPICall_t" }, + { "fieldname":"m_iCallback", "fieldtype":"int" }, + { "fieldname":"m_cubParam", "fieldtype":"uint32" } + ], + "struct": "SteamAPICallCompleted_t" + }, + { + "callback_id": 704, + "fields": [], + "struct": "SteamShutdown_t" + }, + { + "callback_id": 705, + "fields": [ + { "fieldname":"m_eCheckFileSignature", "fieldtype":"ECheckFileSignature" } + ], + "struct": "CheckFileSignature_t" + }, + { + "callback_id": 714, + "fields": [ + { "fieldname":"m_bSubmitted", "fieldtype":"bool" }, + { "fieldname":"m_unSubmittedText", "fieldtype":"uint32" } + ], + "struct": "GamepadTextInputDismissed_t" + }, + { + "callback_id": 736, + "fields": [], + "struct": "AppResumingFromSuspend_t" + }, + { + "callback_id": 738, + "fields": [], + "struct": "FloatingGamepadTextInputDismissed_t" + }, + { + "callback_id": 502, + "fields": [ + { "fieldname":"m_nIP", "fieldtype":"uint32" }, + { "fieldname":"m_nQueryPort", "fieldtype":"uint32" }, + { "fieldname":"m_nConnPort", "fieldtype":"uint32" }, + { "fieldname":"m_nAppID", "fieldtype":"uint32" }, + { "fieldname":"m_nFlags", "fieldtype":"uint32" }, + { "fieldname":"m_bAdd", "fieldtype":"bool" }, + { "fieldname":"m_unAccountId", "fieldtype":"AccountID_t" } + ], + "struct": "FavoritesListChanged_t" + }, + { + "callback_id": 503, + "fields": [ + { "fieldname":"m_ulSteamIDUser", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulGameID", "fieldtype":"uint64" } + ], + "struct": "LobbyInvite_t" + }, + { + "callback_id": 504, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_rgfChatPermissions", "fieldtype":"uint32" }, + { "fieldname":"m_bLocked", "fieldtype":"bool" }, + { "fieldname":"m_EChatRoomEnterResponse", "fieldtype":"uint32" } + ], + "struct": "LobbyEnter_t" + }, + { + "callback_id": 505, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDMember", "fieldtype":"uint64" }, + { "fieldname":"m_bSuccess", "fieldtype":"uint8" } + ], + "struct": "LobbyDataUpdate_t" + }, + { + "callback_id": 506, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDUserChanged", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDMakingChange", "fieldtype":"uint64" }, + { "fieldname":"m_rgfChatMemberStateChange", "fieldtype":"uint32" } + ], + "struct": "LobbyChatUpdate_t" + }, + { + "callback_id": 507, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDUser", "fieldtype":"uint64" }, + { "fieldname":"m_eChatEntryType", "fieldtype":"uint8" }, + { "fieldname":"m_iChatID", "fieldtype":"uint32" } + ], + "struct": "LobbyChatMsg_t" + }, + { + "callback_id": 509, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDGameServer", "fieldtype":"uint64" }, + { "fieldname":"m_unIP", "fieldtype":"uint32" }, + { "fieldname":"m_usPort", "fieldtype":"uint16" } + ], + "struct": "LobbyGameCreated_t" + }, + { + "callback_id": 510, + "fields": [ + { "fieldname":"m_nLobbiesMatching", "fieldtype":"uint32" } + ], + "struct": "LobbyMatchList_t" + }, + { + "callback_id": 512, + "fields": [ + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" }, + { "fieldname":"m_ulSteamIDAdmin", "fieldtype":"uint64" }, + { "fieldname":"m_bKickedDueToDisconnect", "fieldtype":"uint8" } + ], + "struct": "LobbyKicked_t" + }, + { + "callback_id": 513, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ulSteamIDLobby", "fieldtype":"uint64" } + ], + "struct": "LobbyCreated_t" + }, + { + "callback_id": 515, + "fields": [ + { "fieldname":"m_bGameBootInviteExists", "fieldtype":"bool" }, + { "fieldname":"m_steamIDLobby", "fieldtype":"CSteamID" } + ], + "struct": "PSNGameBootInviteResult_t" + }, + { + "callback_id": 516, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "FavoritesListAccountsUpdated_t" + }, + { + "callback_id": 5201, + "fields": [ + { "fieldname":"m_ullSearchID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_lobbyID", "fieldtype":"CSteamID" }, + { "fieldname":"m_steamIDEndedSearch", "fieldtype":"CSteamID" }, + { "fieldname":"m_nSecondsRemainingEstimate", "fieldtype":"int32" }, + { "fieldname":"m_cPlayersSearching", "fieldtype":"int32" } + ], + "struct": "SearchForGameProgressCallback_t" + }, + { + "callback_id": 5202, + "fields": [ + { "fieldname":"m_ullSearchID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nCountPlayersInGame", "fieldtype":"int32" }, + { "fieldname":"m_nCountAcceptedGame", "fieldtype":"int32" }, + { "fieldname":"m_steamIDHost", "fieldtype":"CSteamID" }, + { "fieldname":"m_bFinalCallback", "fieldtype":"bool" } + ], + "struct": "SearchForGameResultCallback_t" + }, + { + "callback_id": 5211, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ullSearchID", "fieldtype":"uint64" } + ], + "struct": "RequestPlayersForGameProgressCallback_t" + }, + { + "callback_id": 5212, + "enums": [ + { + "enumname": "PlayerAcceptState_t", + "fqname": "RequestPlayersForGameResultCallback_t::PlayerAcceptState_t", + "values": [ + { "name":"k_EStateUnknown", "value":"0" }, + { "name":"k_EStatePlayerAccepted", "value":"1" }, + { "name":"k_EStatePlayerDeclined", "value":"2" } + ] + } + ], + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ullSearchID", "fieldtype":"uint64" }, + { "fieldname":"m_SteamIDPlayerFound", "fieldtype":"CSteamID" }, + { "fieldname":"m_SteamIDLobby", "fieldtype":"CSteamID" }, + { "fieldname":"m_ePlayerAcceptState", "fieldtype":"RequestPlayersForGameResultCallback_t::PlayerAcceptState_t" }, + { "fieldname":"m_nPlayerIndex", "fieldtype":"int32" }, + { "fieldname":"m_nTotalPlayersFound", "fieldtype":"int32" }, + { "fieldname":"m_nTotalPlayersAcceptedGame", "fieldtype":"int32" }, + { "fieldname":"m_nSuggestedTeamIndex", "fieldtype":"int32" }, + { "fieldname":"m_ullUniqueGameID", "fieldtype":"uint64" } + ], + "struct": "RequestPlayersForGameResultCallback_t" + }, + { + "callback_id": 5213, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ullSearchID", "fieldtype":"uint64" }, + { "fieldname":"m_ullUniqueGameID", "fieldtype":"uint64" } + ], + "struct": "RequestPlayersForGameFinalResultCallback_t" + }, + { + "callback_id": 5214, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"ullUniqueGameID", "fieldtype":"uint64" }, + { "fieldname":"steamIDPlayer", "fieldtype":"CSteamID" } + ], + "struct": "SubmitPlayerResultResultCallback_t" + }, + { + "callback_id": 5215, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"ullUniqueGameID", "fieldtype":"uint64" } + ], + "struct": "EndGameResultCallback_t" + }, + { + "callback_id": 5301, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ulBeaconID", "fieldtype":"PartyBeaconID_t" }, + { "fieldname":"m_SteamIDBeaconOwner", "fieldtype":"CSteamID" }, + { "fieldname":"m_rgchConnectString", "fieldtype":"char [256]" } + ], + "struct": "JoinPartyCallback_t" + }, + { + "callback_id": 5302, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ulBeaconID", "fieldtype":"PartyBeaconID_t" } + ], + "struct": "CreateBeaconCallback_t" + }, + { + "callback_id": 5303, + "fields": [ + { "fieldname":"m_ulBeaconID", "fieldtype":"PartyBeaconID_t" }, + { "fieldname":"m_steamIDJoiner", "fieldtype":"CSteamID" } + ], + "struct": "ReservationNotificationCallback_t" + }, + { + "callback_id": 5304, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "ChangeNumOpenSlotsCallback_t" + }, + { + "callback_id": 5305, + "fields": [], + "struct": "AvailableBeaconLocationsUpdated_t" + }, + { + "callback_id": 5306, + "fields": [], + "struct": "ActiveBeaconsUpdated_t" + }, + { + "callback_id": 1307, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_hFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_rgchFilename", "fieldtype":"char [260]" } + ], + "struct": "RemoteStorageFileShareResult_t" + }, + { + "callback_id": 1309, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_bUserNeedsToAcceptWorkshopLegalAgreement", "fieldtype":"bool" } + ], + "struct": "RemoteStoragePublishFileResult_t" + }, + { + "callback_id": 1311, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "RemoteStorageDeletePublishedFileResult_t" + }, + { + "callback_id": 1312, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" }, + { "fieldname":"m_rgPublishedFileId", "fieldtype":"PublishedFileId_t [50]" } + ], + "struct": "RemoteStorageEnumerateUserPublishedFilesResult_t" + }, + { + "callback_id": 1313, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "RemoteStorageSubscribePublishedFileResult_t" + }, + { + "callback_id": 1314, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" }, + { "fieldname":"m_rgPublishedFileId", "fieldtype":"PublishedFileId_t [50]" }, + { "fieldname":"m_rgRTimeSubscribed", "fieldtype":"uint32 [50]" } + ], + "struct": "RemoteStorageEnumerateUserSubscribedFilesResult_t" + }, + { + "callback_id": 1315, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "RemoteStorageUnsubscribePublishedFileResult_t" + }, + { + "callback_id": 1316, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_bUserNeedsToAcceptWorkshopLegalAgreement", "fieldtype":"bool" } + ], + "struct": "RemoteStorageUpdatePublishedFileResult_t" + }, + { + "callback_id": 1317, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_hFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_nSizeInBytes", "fieldtype":"int32" }, + { "fieldname":"m_pchFileName", "fieldtype":"char [260]" }, + { "fieldname":"m_ulSteamIDOwner", "fieldtype":"uint64" } + ], + "struct": "RemoteStorageDownloadUGCResult_t" + }, + { + "callback_id": 1318, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nCreatorAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_nConsumerAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_rgchTitle", "fieldtype":"char [129]" }, + { "fieldname":"m_rgchDescription", "fieldtype":"char [8000]" }, + { "fieldname":"m_hFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_hPreviewFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_ulSteamIDOwner", "fieldtype":"uint64" }, + { "fieldname":"m_rtimeCreated", "fieldtype":"uint32" }, + { "fieldname":"m_rtimeUpdated", "fieldtype":"uint32" }, + { "fieldname":"m_eVisibility", "fieldtype":"ERemoteStoragePublishedFileVisibility" }, + { "fieldname":"m_bBanned", "fieldtype":"bool" }, + { "fieldname":"m_rgchTags", "fieldtype":"char [1025]" }, + { "fieldname":"m_bTagsTruncated", "fieldtype":"bool" }, + { "fieldname":"m_pchFileName", "fieldtype":"char [260]" }, + { "fieldname":"m_nFileSize", "fieldtype":"int32" }, + { "fieldname":"m_nPreviewFileSize", "fieldtype":"int32" }, + { "fieldname":"m_rgchURL", "fieldtype":"char [256]" }, + { "fieldname":"m_eFileType", "fieldtype":"EWorkshopFileType" }, + { "fieldname":"m_bAcceptedForUse", "fieldtype":"bool" } + ], + "struct": "RemoteStorageGetPublishedFileDetailsResult_t" + }, + { + "callback_id": 1319, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" }, + { "fieldname":"m_rgPublishedFileId", "fieldtype":"PublishedFileId_t [50]" }, + { "fieldname":"m_rgScore", "fieldtype":"float [50]" }, + { "fieldname":"m_nAppId", "fieldtype":"AppId_t" }, + { "fieldname":"m_unStartIndex", "fieldtype":"uint32" } + ], + "struct": "RemoteStorageEnumerateWorkshopFilesResult_t" + }, + { + "callback_id": 1320, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_unPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nVotesFor", "fieldtype":"int32" }, + { "fieldname":"m_nVotesAgainst", "fieldtype":"int32" }, + { "fieldname":"m_nReports", "fieldtype":"int32" }, + { "fieldname":"m_fScore", "fieldtype":"float" } + ], + "struct": "RemoteStorageGetPublishedItemVoteDetailsResult_t" + }, + { + "callback_id": 1321, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "RemoteStoragePublishedFileSubscribed_t" + }, + { + "callback_id": 1322, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "RemoteStoragePublishedFileUnsubscribed_t" + }, + { + "callback_id": 1323, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "RemoteStoragePublishedFileDeleted_t" + }, + { + "callback_id": 1324, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "RemoteStorageUpdateUserPublishedItemVoteResult_t" + }, + { + "callback_id": 1325, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eVote", "fieldtype":"EWorkshopVote" } + ], + "struct": "RemoteStorageUserVoteDetails_t" + }, + { + "callback_id": 1326, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" }, + { "fieldname":"m_rgPublishedFileId", "fieldtype":"PublishedFileId_t [50]" } + ], + "struct": "RemoteStorageEnumerateUserSharedWorkshopFilesResult_t" + }, + { + "callback_id": 1327, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eAction", "fieldtype":"EWorkshopFileAction" } + ], + "struct": "RemoteStorageSetUserPublishedFileActionResult_t" + }, + { + "callback_id": 1328, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_eAction", "fieldtype":"EWorkshopFileAction" }, + { "fieldname":"m_nResultsReturned", "fieldtype":"int32" }, + { "fieldname":"m_nTotalResultCount", "fieldtype":"int32" }, + { "fieldname":"m_rgPublishedFileId", "fieldtype":"PublishedFileId_t [50]" }, + { "fieldname":"m_rgRTimeUpdated", "fieldtype":"uint32 [50]" } + ], + "struct": "RemoteStorageEnumeratePublishedFilesByUserActionResult_t" + }, + { + "callback_id": 1329, + "fields": [ + { "fieldname":"m_dPercentFile", "fieldtype":"double" }, + { "fieldname":"m_bPreview", "fieldtype":"bool" } + ], + "struct": "RemoteStoragePublishFileProgress_t" + }, + { + "callback_id": 1330, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_ulUnused", "fieldtype":"uint64" } + ], + "struct": "RemoteStoragePublishedFileUpdated_t" + }, + { + "callback_id": 1331, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "RemoteStorageFileWriteAsyncComplete_t" + }, + { + "callback_id": 1332, + "fields": [ + { "fieldname":"m_hFileReadAsync", "fieldtype":"SteamAPICall_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nOffset", "fieldtype":"uint32" }, + { "fieldname":"m_cubRead", "fieldtype":"uint32" } + ], + "struct": "RemoteStorageFileReadAsyncComplete_t" + }, + { + "callback_id": 1333, + "fields": [], + "struct": "RemoteStorageLocalFileChange_t" + }, + { + "callback_id": 1101, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "UserStatsReceived_t" + }, + { + "callback_id": 1102, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "UserStatsStored_t" + }, + { + "callback_id": 1103, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_bGroupAchievement", "fieldtype":"bool" }, + { "fieldname":"m_rgchAchievementName", "fieldtype":"char [128]" }, + { "fieldname":"m_nCurProgress", "fieldtype":"uint32" }, + { "fieldname":"m_nMaxProgress", "fieldtype":"uint32" } + ], + "struct": "UserAchievementStored_t" + }, + { + "callback_id": 1104, + "fields": [ + { "fieldname":"m_hSteamLeaderboard", "fieldtype":"SteamLeaderboard_t" }, + { "fieldname":"m_bLeaderboardFound", "fieldtype":"uint8" } + ], + "struct": "LeaderboardFindResult_t" + }, + { + "callback_id": 1105, + "fields": [ + { "fieldname":"m_hSteamLeaderboard", "fieldtype":"SteamLeaderboard_t" }, + { "fieldname":"m_hSteamLeaderboardEntries", "fieldtype":"SteamLeaderboardEntries_t" }, + { "fieldname":"m_cEntryCount", "fieldtype":"int" } + ], + "struct": "LeaderboardScoresDownloaded_t" + }, + { + "callback_id": 1106, + "fields": [ + { "fieldname":"m_bSuccess", "fieldtype":"uint8" }, + { "fieldname":"m_hSteamLeaderboard", "fieldtype":"SteamLeaderboard_t" }, + { "fieldname":"m_nScore", "fieldtype":"int32" }, + { "fieldname":"m_bScoreChanged", "fieldtype":"uint8" }, + { "fieldname":"m_nGlobalRankNew", "fieldtype":"int" }, + { "fieldname":"m_nGlobalRankPrevious", "fieldtype":"int" } + ], + "struct": "LeaderboardScoreUploaded_t" + }, + { + "callback_id": 1107, + "fields": [ + { "fieldname":"m_bSuccess", "fieldtype":"uint8" }, + { "fieldname":"m_cPlayers", "fieldtype":"int32" } + ], + "struct": "NumberOfCurrentPlayers_t" + }, + { + "callback_id": 1108, + "fields": [ + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "UserStatsUnloaded_t" + }, + { + "callback_id": 1109, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"CGameID" }, + { "fieldname":"m_rgchAchievementName", "fieldtype":"char [128]" }, + { "fieldname":"m_bAchieved", "fieldtype":"bool" }, + { "fieldname":"m_nIconHandle", "fieldtype":"int" } + ], + "struct": "UserAchievementIconFetched_t" + }, + { + "callback_id": 1110, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "GlobalAchievementPercentagesReady_t" + }, + { + "callback_id": 1111, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_hSteamLeaderboard", "fieldtype":"SteamLeaderboard_t" } + ], + "struct": "LeaderboardUGCSet_t" + }, + { + "callback_id": 1112, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ulRequiredDiskSpace", "fieldtype":"uint64" } + ], + "struct": "PS3TrophiesInstalled_t" + }, + { + "callback_id": 1112, + "fields": [ + { "fieldname":"m_nGameID", "fieldtype":"uint64" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "GlobalStatsReceived_t" + }, + { + "callback_id": 1005, + "fields": [ + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "DlcInstalled_t" + }, + { + "callback_id": 1008, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"ERegisterActivationCodeResult" }, + { "fieldname":"m_unPackageRegistered", "fieldtype":"uint32" } + ], + "struct": "RegisterActivationCodeResponse_t" + }, + { + "callback_id": 1014, + "fields": [], + "struct": "NewUrlLaunchParameters_t" + }, + { + "callback_id": 1021, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nAppID", "fieldtype":"uint32" }, + { "fieldname":"m_cchKeyLength", "fieldtype":"uint32" }, + { "fieldname":"m_rgchKey", "fieldtype":"char [240]" } + ], + "struct": "AppProofOfPurchaseKeyResponse_t" + }, + { + "callback_id": 1023, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_ulFileSize", "fieldtype":"uint64" }, + { "fieldname":"m_FileSHA", "fieldtype":"uint8 [20]" }, + { "fieldname":"m_unFlags", "fieldtype":"uint32" } + ], + "struct": "FileDetailsResult_t" + }, + { + "callback_id": 1030, + "fields": [ + { "fieldname":"m_unAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_bIsOffline", "fieldtype":"bool" }, + { "fieldname":"m_unSecondsAllowed", "fieldtype":"uint32" }, + { "fieldname":"m_unSecondsPlayed", "fieldtype":"uint32" } + ], + "struct": "TimedTrialStatus_t" + }, + { + "callback_id": 1202, + "fields": [ + { "fieldname":"m_steamIDRemote", "fieldtype":"CSteamID" } + ], + "struct": "P2PSessionRequest_t" + }, + { + "callback_id": 1203, + "fields": [ + { "fieldname":"m_steamIDRemote", "fieldtype":"CSteamID" }, + { "fieldname":"m_eP2PSessionError", "fieldtype":"uint8" } + ], + "struct": "P2PSessionConnectFail_t" + }, + { + "callback_id": 1201, + "fields": [ + { "fieldname":"m_hSocket", "fieldtype":"SNetSocket_t" }, + { "fieldname":"m_hListenSocket", "fieldtype":"SNetListenSocket_t" }, + { "fieldname":"m_steamIDRemote", "fieldtype":"CSteamID" }, + { "fieldname":"m_eSNetSocketState", "fieldtype":"int" } + ], + "struct": "SocketStatusCallback_t" + }, + { + "callback_id": 2301, + "fields": [ + { "fieldname":"m_hLocal", "fieldtype":"ScreenshotHandle" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "ScreenshotReady_t" + }, + { + "callback_id": 2302, + "fields": [], + "struct": "ScreenshotRequested_t" + }, + { + "callback_id": 4001, + "fields": [], + "struct": "PlaybackStatusHasChanged_t" + }, + { + "callback_id": 4002, + "fields": [ + { "fieldname":"m_flNewVolume", "fieldtype":"float" } + ], + "struct": "VolumeHasChanged_t" + }, + { + "callback_id": 4101, + "fields": [], + "struct": "MusicPlayerRemoteWillActivate_t" + }, + { + "callback_id": 4102, + "fields": [], + "struct": "MusicPlayerRemoteWillDeactivate_t" + }, + { + "callback_id": 4103, + "fields": [], + "struct": "MusicPlayerRemoteToFront_t" + }, + { + "callback_id": 4104, + "fields": [], + "struct": "MusicPlayerWillQuit_t" + }, + { + "callback_id": 4105, + "fields": [], + "struct": "MusicPlayerWantsPlay_t" + }, + { + "callback_id": 4106, + "fields": [], + "struct": "MusicPlayerWantsPause_t" + }, + { + "callback_id": 4107, + "fields": [], + "struct": "MusicPlayerWantsPlayPrevious_t" + }, + { + "callback_id": 4108, + "fields": [], + "struct": "MusicPlayerWantsPlayNext_t" + }, + { + "callback_id": 4109, + "fields": [ + { "fieldname":"m_bShuffled", "fieldtype":"bool" } + ], + "struct": "MusicPlayerWantsShuffled_t" + }, + { + "callback_id": 4110, + "fields": [ + { "fieldname":"m_bLooped", "fieldtype":"bool" } + ], + "struct": "MusicPlayerWantsLooped_t" + }, + { + "callback_id": 4011, + "fields": [ + { "fieldname":"m_flNewVolume", "fieldtype":"float" } + ], + "struct": "MusicPlayerWantsVolume_t" + }, + { + "callback_id": 4012, + "fields": [ + { "fieldname":"nID", "fieldtype":"int" } + ], + "struct": "MusicPlayerSelectsQueueEntry_t" + }, + { + "callback_id": 4013, + "fields": [ + { "fieldname":"nID", "fieldtype":"int" } + ], + "struct": "MusicPlayerSelectsPlaylistEntry_t" + }, + { + "callback_id": 4114, + "fields": [ + { "fieldname":"m_nPlayingRepeatStatus", "fieldtype":"int" } + ], + "struct": "MusicPlayerWantsPlayingRepeatStatus_t" + }, + { + "callback_id": 2101, + "fields": [ + { "fieldname":"m_hRequest", "fieldtype":"HTTPRequestHandle" }, + { "fieldname":"m_ulContextValue", "fieldtype":"uint64" }, + { "fieldname":"m_bRequestSuccessful", "fieldtype":"bool" }, + { "fieldname":"m_eStatusCode", "fieldtype":"EHTTPStatusCode" }, + { "fieldname":"m_unBodySize", "fieldtype":"uint32" } + ], + "struct": "HTTPRequestCompleted_t" + }, + { + "callback_id": 2102, + "fields": [ + { "fieldname":"m_hRequest", "fieldtype":"HTTPRequestHandle" }, + { "fieldname":"m_ulContextValue", "fieldtype":"uint64" } + ], + "struct": "HTTPRequestHeadersReceived_t" + }, + { + "callback_id": 2103, + "fields": [ + { "fieldname":"m_hRequest", "fieldtype":"HTTPRequestHandle" }, + { "fieldname":"m_ulContextValue", "fieldtype":"uint64" }, + { "fieldname":"m_cOffset", "fieldtype":"uint32" }, + { "fieldname":"m_cBytesReceived", "fieldtype":"uint32" } + ], + "struct": "HTTPRequestDataReceived_t" + }, + { + "callback_id": 2801, + "fields": [ + { "fieldname":"m_ulConnectedDeviceHandle", "fieldtype":"InputHandle_t" } + ], + "struct": "SteamInputDeviceConnected_t" + }, + { + "callback_id": 2802, + "fields": [ + { "fieldname":"m_ulDisconnectedDeviceHandle", "fieldtype":"InputHandle_t" } + ], + "struct": "SteamInputDeviceDisconnected_t" + }, + { + "callback_id": 2803, + "fields": [ + { "fieldname":"m_unAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_ulDeviceHandle", "fieldtype":"InputHandle_t" }, + { "fieldname":"m_ulMappingCreator", "fieldtype":"CSteamID" }, + { "fieldname":"m_unMajorRevision", "fieldtype":"uint32" }, + { "fieldname":"m_unMinorRevision", "fieldtype":"uint32" }, + { "fieldname":"m_bUsesSteamInputAPI", "fieldtype":"bool" }, + { "fieldname":"m_bUsesGamepadAPI", "fieldtype":"bool" } + ], + "struct": "SteamInputConfigurationLoaded_t" + }, + { + "callback_id": 3401, + "fields": [ + { "fieldname":"m_handle", "fieldtype":"UGCQueryHandle_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_unNumResultsReturned", "fieldtype":"uint32" }, + { "fieldname":"m_unTotalMatchingResults", "fieldtype":"uint32" }, + { "fieldname":"m_bCachedData", "fieldtype":"bool" }, + { "fieldname":"m_rgchNextCursor", "fieldtype":"char [256]" } + ], + "struct": "SteamUGCQueryCompleted_t" + }, + { + "callback_id": 3402, + "fields": [ + { "fieldname":"m_details", "fieldtype":"SteamUGCDetails_t" }, + { "fieldname":"m_bCachedData", "fieldtype":"bool" } + ], + "struct": "SteamUGCRequestUGCDetailsResult_t" + }, + { + "callback_id": 3403, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_bUserNeedsToAcceptWorkshopLegalAgreement", "fieldtype":"bool" } + ], + "struct": "CreateItemResult_t" + }, + { + "callback_id": 3404, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_bUserNeedsToAcceptWorkshopLegalAgreement", "fieldtype":"bool" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "SubmitItemUpdateResult_t" + }, + { + "callback_id": 3405, + "fields": [ + { "fieldname":"m_unAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "ItemInstalled_t" + }, + { + "callback_id": 3406, + "fields": [ + { "fieldname":"m_unAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "DownloadItemResult_t" + }, + { + "callback_id": 3407, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_bWasAddRequest", "fieldtype":"bool" } + ], + "struct": "UserFavoriteItemsListChanged_t" + }, + { + "callback_id": 3408, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_bVoteUp", "fieldtype":"bool" } + ], + "struct": "SetUserItemVoteResult_t" + }, + { + "callback_id": 3409, + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_bVotedUp", "fieldtype":"bool" }, + { "fieldname":"m_bVotedDown", "fieldtype":"bool" }, + { "fieldname":"m_bVoteSkipped", "fieldtype":"bool" } + ], + "struct": "GetUserItemVoteResult_t" + }, + { + "callback_id": 3410, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "StartPlaytimeTrackingResult_t" + }, + { + "callback_id": 3411, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "StopPlaytimeTrackingResult_t" + }, + { + "callback_id": 3412, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nChildPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "AddUGCDependencyResult_t" + }, + { + "callback_id": 3413, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nChildPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "RemoveUGCDependencyResult_t" + }, + { + "callback_id": 3414, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "AddAppDependencyResult_t" + }, + { + "callback_id": 3415, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "RemoveAppDependencyResult_t" + }, + { + "callback_id": 3416, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_rgAppIDs", "fieldtype":"AppId_t [32]" }, + { "fieldname":"m_nNumAppDependencies", "fieldtype":"uint32" }, + { "fieldname":"m_nTotalNumAppDependencies", "fieldtype":"uint32" } + ], + "struct": "GetAppDependenciesResult_t" + }, + { + "callback_id": 3417, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" } + ], + "struct": "DeleteItemResult_t" + }, + { + "callback_id": 3418, + "fields": [ + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" } + ], + "struct": "UserSubscribedItemsListChanged_t" + }, + { + "callback_id": 3420, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_unVersion", "fieldtype":"uint32" }, + { "fieldname":"m_rtAction", "fieldtype":"RTime32" }, + { "fieldname":"m_bAccepted", "fieldtype":"bool" }, + { "fieldname":"m_bNeedsAction", "fieldtype":"bool" } + ], + "struct": "WorkshopEULAStatus_t" + }, + { + "callback_id": 3901, + "fields": [ + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_iInstallFolderIndex", "fieldtype":"int" } + ], + "struct": "SteamAppInstalled_t" + }, + { + "callback_id": 3902, + "fields": [ + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_iInstallFolderIndex", "fieldtype":"int" } + ], + "struct": "SteamAppUninstalled_t" + }, + { + "callback_id": 4501, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" } + ], + "struct": "HTML_BrowserReady_t" + }, + { + "callback_id": 4502, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pBGRA", "fieldtype":"const char *" }, + { "fieldname":"unWide", "fieldtype":"uint32" }, + { "fieldname":"unTall", "fieldtype":"uint32" }, + { "fieldname":"unUpdateX", "fieldtype":"uint32" }, + { "fieldname":"unUpdateY", "fieldtype":"uint32" }, + { "fieldname":"unUpdateWide", "fieldtype":"uint32" }, + { "fieldname":"unUpdateTall", "fieldtype":"uint32" }, + { "fieldname":"unScrollX", "fieldtype":"uint32" }, + { "fieldname":"unScrollY", "fieldtype":"uint32" }, + { "fieldname":"flPageScale", "fieldtype":"float" }, + { "fieldname":"unPageSerial", "fieldtype":"uint32" } + ], + "struct": "HTML_NeedsPaint_t" + }, + { + "callback_id": 4503, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchURL", "fieldtype":"const char *" }, + { "fieldname":"pchTarget", "fieldtype":"const char *" }, + { "fieldname":"pchPostData", "fieldtype":"const char *" }, + { "fieldname":"bIsRedirect", "fieldtype":"bool" } + ], + "struct": "HTML_StartRequest_t" + }, + { + "callback_id": 4504, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" } + ], + "struct": "HTML_CloseBrowser_t" + }, + { + "callback_id": 4505, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchURL", "fieldtype":"const char *" }, + { "fieldname":"pchPostData", "fieldtype":"const char *" }, + { "fieldname":"bIsRedirect", "fieldtype":"bool" }, + { "fieldname":"pchPageTitle", "fieldtype":"const char *" }, + { "fieldname":"bNewNavigation", "fieldtype":"bool" } + ], + "struct": "HTML_URLChanged_t" + }, + { + "callback_id": 4506, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchURL", "fieldtype":"const char *" }, + { "fieldname":"pchPageTitle", "fieldtype":"const char *" } + ], + "struct": "HTML_FinishedRequest_t" + }, + { + "callback_id": 4507, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchURL", "fieldtype":"const char *" } + ], + "struct": "HTML_OpenLinkInNewTab_t" + }, + { + "callback_id": 4508, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchTitle", "fieldtype":"const char *" } + ], + "struct": "HTML_ChangedTitle_t" + }, + { + "callback_id": 4509, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"unResults", "fieldtype":"uint32" }, + { "fieldname":"unCurrentMatch", "fieldtype":"uint32" } + ], + "struct": "HTML_SearchResults_t" + }, + { + "callback_id": 4510, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"bCanGoBack", "fieldtype":"bool" }, + { "fieldname":"bCanGoForward", "fieldtype":"bool" } + ], + "struct": "HTML_CanGoBackAndForward_t" + }, + { + "callback_id": 4511, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"unScrollMax", "fieldtype":"uint32" }, + { "fieldname":"unScrollCurrent", "fieldtype":"uint32" }, + { "fieldname":"flPageScale", "fieldtype":"float" }, + { "fieldname":"bVisible", "fieldtype":"bool" }, + { "fieldname":"unPageSize", "fieldtype":"uint32" } + ], + "struct": "HTML_HorizontalScroll_t" + }, + { + "callback_id": 4512, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"unScrollMax", "fieldtype":"uint32" }, + { "fieldname":"unScrollCurrent", "fieldtype":"uint32" }, + { "fieldname":"flPageScale", "fieldtype":"float" }, + { "fieldname":"bVisible", "fieldtype":"bool" }, + { "fieldname":"unPageSize", "fieldtype":"uint32" } + ], + "struct": "HTML_VerticalScroll_t" + }, + { + "callback_id": 4513, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"x", "fieldtype":"uint32" }, + { "fieldname":"y", "fieldtype":"uint32" }, + { "fieldname":"pchURL", "fieldtype":"const char *" }, + { "fieldname":"bInput", "fieldtype":"bool" }, + { "fieldname":"bLiveLink", "fieldtype":"bool" } + ], + "struct": "HTML_LinkAtPosition_t" + }, + { + "callback_id": 4514, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchMessage", "fieldtype":"const char *" } + ], + "struct": "HTML_JSAlert_t" + }, + { + "callback_id": 4515, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchMessage", "fieldtype":"const char *" } + ], + "struct": "HTML_JSConfirm_t" + }, + { + "callback_id": 4516, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchTitle", "fieldtype":"const char *" }, + { "fieldname":"pchInitialFile", "fieldtype":"const char *" } + ], + "struct": "HTML_FileOpenDialog_t" + }, + { + "callback_id": 4521, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchURL", "fieldtype":"const char *" }, + { "fieldname":"unX", "fieldtype":"uint32" }, + { "fieldname":"unY", "fieldtype":"uint32" }, + { "fieldname":"unWide", "fieldtype":"uint32" }, + { "fieldname":"unTall", "fieldtype":"uint32" }, + { "fieldname":"unNewWindow_BrowserHandle_IGNORE", "fieldtype":"HHTMLBrowser" } + ], + "struct": "HTML_NewWindow_t" + }, + { + "callback_id": 4522, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"eMouseCursor", "fieldtype":"uint32" } + ], + "struct": "HTML_SetCursor_t" + }, + { + "callback_id": 4523, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchMsg", "fieldtype":"const char *" } + ], + "struct": "HTML_StatusText_t" + }, + { + "callback_id": 4524, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchMsg", "fieldtype":"const char *" } + ], + "struct": "HTML_ShowToolTip_t" + }, + { + "callback_id": 4525, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"pchMsg", "fieldtype":"const char *" } + ], + "struct": "HTML_UpdateToolTip_t" + }, + { + "callback_id": 4526, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" } + ], + "struct": "HTML_HideToolTip_t" + }, + { + "callback_id": 4527, + "fields": [ + { "fieldname":"unBrowserHandle", "fieldtype":"HHTMLBrowser" }, + { "fieldname":"unOldBrowserHandle", "fieldtype":"HHTMLBrowser" } + ], + "struct": "HTML_BrowserRestarted_t" + }, + { + "callback_id": 4700, + "fields": [ + { "fieldname":"m_handle", "fieldtype":"SteamInventoryResult_t" }, + { "fieldname":"m_result", "fieldtype":"EResult" } + ], + "struct": "SteamInventoryResultReady_t" + }, + { + "callback_id": 4701, + "fields": [ + { "fieldname":"m_handle", "fieldtype":"SteamInventoryResult_t" } + ], + "struct": "SteamInventoryFullUpdate_t" + }, + { + "callback_id": 4702, + "fields": [], + "struct": "SteamInventoryDefinitionUpdate_t" + }, + { + "callback_id": 4703, + "fields": [ + { "fieldname":"m_result", "fieldtype":"EResult" }, + { "fieldname":"m_steamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_numEligiblePromoItemDefs", "fieldtype":"int" }, + { "fieldname":"m_bCachedData", "fieldtype":"bool" } + ], + "struct": "SteamInventoryEligiblePromoItemDefIDs_t" + }, + { + "callback_id": 4704, + "fields": [ + { "fieldname":"m_result", "fieldtype":"EResult" }, + { "fieldname":"m_ulOrderID", "fieldtype":"uint64" }, + { "fieldname":"m_ulTransID", "fieldtype":"uint64" } + ], + "struct": "SteamInventoryStartPurchaseResult_t" + }, + { + "callback_id": 4705, + "fields": [ + { "fieldname":"m_result", "fieldtype":"EResult" }, + { "fieldname":"m_rgchCurrency", "fieldtype":"char [4]" } + ], + "struct": "SteamInventoryRequestPricesResult_t" + }, + { + "callback_id": 4611, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_unVideoAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_rgchURL", "fieldtype":"char [256]" } + ], + "struct": "GetVideoURLResult_t" + }, + { + "callback_id": 4624, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_unVideoAppID", "fieldtype":"AppId_t" } + ], + "struct": "GetOPFSettingsResult_t" + }, + { + "callback_id": 5001, + "fields": [], + "struct": "SteamParentalSettingsChanged_t" + }, + { + "callback_id": 5701, + "fields": [ + { "fieldname":"m_unSessionID", "fieldtype":"RemotePlaySessionID_t" } + ], + "struct": "SteamRemotePlaySessionConnected_t" + }, + { + "callback_id": 5702, + "fields": [ + { "fieldname":"m_unSessionID", "fieldtype":"RemotePlaySessionID_t" } + ], + "struct": "SteamRemotePlaySessionDisconnected_t" + }, + { + "callback_id": 1251, + "fields": [ + { "fieldname":"m_identityRemote", "fieldtype":"SteamNetworkingIdentity" } + ], + "struct": "SteamNetworkingMessagesSessionRequest_t" + }, + { + "callback_id": 1252, + "fields": [ + { "fieldname":"m_info", "fieldtype":"SteamNetConnectionInfo_t" } + ], + "struct": "SteamNetworkingMessagesSessionFailed_t" + }, + { + "callback_id": 1221, + "fields": [ + { "fieldname":"m_hConn", "fieldtype":"HSteamNetConnection" }, + { "fieldname":"m_info", "fieldtype":"SteamNetConnectionInfo_t" }, + { "fieldname":"m_eOldState", "fieldtype":"ESteamNetworkingConnectionState" } + ], + "struct": "SteamNetConnectionStatusChangedCallback_t" + }, + { + "callback_id": 1222, + "fields": [ + { "fieldname":"m_eAvail", "fieldtype":"ESteamNetworkingAvailability" }, + { "fieldname":"m_debugMsg", "fieldtype":"char [256]" } + ], + "struct": "SteamNetAuthenticationStatus_t" + }, + { + "callback_id": 1281, + "fields": [ + { "fieldname":"m_eAvail", "fieldtype":"ESteamNetworkingAvailability" }, + { "fieldname":"m_bPingMeasurementInProgress", "fieldtype":"int" }, + { "fieldname":"m_eAvailNetworkConfig", "fieldtype":"ESteamNetworkingAvailability" }, + { "fieldname":"m_eAvailAnyRelay", "fieldtype":"ESteamNetworkingAvailability" }, + { "fieldname":"m_debugMsg", "fieldtype":"char [256]" } + ], + "struct": "SteamRelayNetworkStatus_t" + }, + { + "callback_id": 201, + "fields": [ + { "fieldname":"m_SteamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_OwnerSteamID", "fieldtype":"CSteamID" } + ], + "struct": "GSClientApprove_t" + }, + { + "callback_id": 202, + "fields": [ + { "fieldname":"m_SteamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_eDenyReason", "fieldtype":"EDenyReason" }, + { "fieldname":"m_rgchOptionalText", "fieldtype":"char [128]" } + ], + "struct": "GSClientDeny_t" + }, + { + "callback_id": 203, + "fields": [ + { "fieldname":"m_SteamID", "fieldtype":"CSteamID" }, + { "fieldname":"m_eDenyReason", "fieldtype":"EDenyReason" } + ], + "struct": "GSClientKick_t" + }, + { + "callback_id": 206, + "fields": [ + { "fieldname":"m_SteamID", "fieldtype":"uint64" }, + { "fieldname":"m_pchAchievement", "fieldtype":"char [128]" }, + { "fieldname":"m_bUnlocked", "fieldtype":"bool" } + ], + "struct": "GSClientAchievementStatus_t" + }, + { + "callback_id": 115, + "fields": [ + { "fieldname":"m_bSecure", "fieldtype":"uint8" } + ], + "struct": "GSPolicyResponse_t" + }, + { + "callback_id": 207, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_nRank", "fieldtype":"int32" }, + { "fieldname":"m_unTotalConnects", "fieldtype":"uint32" }, + { "fieldname":"m_unTotalMinutesPlayed", "fieldtype":"uint32" } + ], + "struct": "GSGameplayStats_t" + }, + { + "callback_id": 208, + "fields": [ + { "fieldname":"m_SteamIDUser", "fieldtype":"CSteamID" }, + { "fieldname":"m_SteamIDGroup", "fieldtype":"CSteamID" }, + { "fieldname":"m_bMember", "fieldtype":"bool" }, + { "fieldname":"m_bOfficer", "fieldtype":"bool" } + ], + "struct": "GSClientGroupStatus_t" + }, + { + "callback_id": 209, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_unReputationScore", "fieldtype":"uint32" }, + { "fieldname":"m_bBanned", "fieldtype":"bool" }, + { "fieldname":"m_unBannedIP", "fieldtype":"uint32" }, + { "fieldname":"m_usBannedPort", "fieldtype":"uint16" }, + { "fieldname":"m_ulBannedGameID", "fieldtype":"uint64" }, + { "fieldname":"m_unBanExpires", "fieldtype":"uint32" } + ], + "struct": "GSReputation_t" + }, + { + "callback_id": 210, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" } + ], + "struct": "AssociateWithClanResult_t" + }, + { + "callback_id": 211, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_cPlayersThatDontLikeCandidate", "fieldtype":"int" }, + { "fieldname":"m_cPlayersThatCandidateDoesntLike", "fieldtype":"int" }, + { "fieldname":"m_cClanPlayersThatDontLikeCandidate", "fieldtype":"int" }, + { "fieldname":"m_SteamIDCandidate", "fieldtype":"CSteamID" } + ], + "struct": "ComputeNewPlayerCompatibilityResult_t" + }, + { + "callback_id": 1800, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "GSStatsReceived_t" + }, + { + "callback_id": 1801, + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "GSStatsStored_t" + }, + { + "callback_id": 1108, + "fields": [ + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" } + ], + "struct": "GSStatsUnloaded_t" + }, + { + "callback_id": 1223, + "consts": [ + { "constname":"k_nMaxReturnPorts", "consttype":"int", "constval":"8" } + ], + "fields": [ + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_identity", "fieldtype":"SteamNetworkingIdentity" }, + { "fieldname":"m_unIP", "fieldtype":"uint32" }, + { "fieldname":"m_unPorts", "fieldtype":"uint16 [8]" } + ], + "struct": "SteamNetworkingFakeIPResult_t" + } + ], + "consts": [ + { "constname":"k_uAppIdInvalid", "consttype":"AppId_t", "constval":"0x0" }, + { "constname":"k_uDepotIdInvalid", "consttype":"DepotId_t", "constval":"0x0" }, + { "constname":"k_uAPICallInvalid", "consttype":"SteamAPICall_t", "constval":"0x0" }, + { "constname":"k_ulPartyBeaconIdInvalid", "consttype":"PartyBeaconID_t", "constval":"0" }, + { "constname":"k_HAuthTicketInvalid", "consttype":"HAuthTicket", "constval":"0" }, + { "constname":"k_unSteamAccountIDMask", "consttype":"unsigned int", "constval":"0xFFFFFFFF" }, + { "constname":"k_unSteamAccountInstanceMask", "consttype":"unsigned int", "constval":"0x000FFFFF" }, + { "constname":"k_unSteamUserDefaultInstance", "consttype":"unsigned int", "constval":"1" }, + { "constname":"k_cchGameExtraInfoMax", "consttype":"int", "constval":"64" }, + { "constname":"k_cchMaxFriendsGroupName", "consttype":"int", "constval":"64" }, + { "constname":"k_cFriendsGroupLimit", "consttype":"int", "constval":"100" }, + { "constname":"k_FriendsGroupID_Invalid", "consttype":"FriendsGroupID_t", "constval":"- 1" }, + { "constname":"k_cEnumerateFollowersMax", "consttype":"int", "constval":"50" }, + { "constname":"k_cubChatMetadataMax", "consttype":"uint32", "constval":"8192" }, + { "constname":"k_cbMaxGameServerGameDir", "consttype":"int", "constval":"32" }, + { "constname":"k_cbMaxGameServerMapName", "consttype":"int", "constval":"32" }, + { "constname":"k_cbMaxGameServerGameDescription", "consttype":"int", "constval":"64" }, + { "constname":"k_cbMaxGameServerName", "consttype":"int", "constval":"64" }, + { "constname":"k_cbMaxGameServerTags", "consttype":"int", "constval":"128" }, + { "constname":"k_cbMaxGameServerGameData", "consttype":"int", "constval":"2048" }, + { "constname":"HSERVERQUERY_INVALID", "consttype":"int", "constval":"0xffffffff" }, + { "constname":"k_unFavoriteFlagNone", "consttype":"uint32", "constval":"0x00" }, + { "constname":"k_unFavoriteFlagFavorite", "consttype":"uint32", "constval":"0x01" }, + { "constname":"k_unFavoriteFlagHistory", "consttype":"uint32", "constval":"0x02" }, + { "constname":"k_unMaxCloudFileChunkSize", "consttype":"uint32", "constval":"100 * 1024 * 1024" }, + { "constname":"k_PublishedFileIdInvalid", "consttype":"PublishedFileId_t", "constval":"0" }, + { "constname":"k_UGCHandleInvalid", "consttype":"UGCHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"k_PublishedFileUpdateHandleInvalid", "consttype":"PublishedFileUpdateHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"k_UGCFileStreamHandleInvalid", "consttype":"UGCFileWriteStreamHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"k_cchPublishedDocumentTitleMax", "consttype":"uint32", "constval":"128 + 1" }, + { "constname":"k_cchPublishedDocumentDescriptionMax", "consttype":"uint32", "constval":"8000" }, + { "constname":"k_cchPublishedDocumentChangeDescriptionMax", "consttype":"uint32", "constval":"8000" }, + { "constname":"k_unEnumeratePublishedFilesMaxResults", "consttype":"uint32", "constval":"50" }, + { "constname":"k_cchTagListMax", "consttype":"uint32", "constval":"1024 + 1" }, + { "constname":"k_cchFilenameMax", "consttype":"uint32", "constval":"260" }, + { "constname":"k_cchPublishedFileURLMax", "consttype":"uint32", "constval":"256" }, + { "constname":"k_cubAppProofOfPurchaseKeyMax", "consttype":"int", "constval":"240" }, + { "constname":"k_nScreenshotMaxTaggedUsers", "consttype":"uint32", "constval":"32" }, + { "constname":"k_nScreenshotMaxTaggedPublishedFiles", "consttype":"uint32", "constval":"32" }, + { "constname":"k_cubUFSTagTypeMax", "consttype":"int", "constval":"255" }, + { "constname":"k_cubUFSTagValueMax", "consttype":"int", "constval":"255" }, + { "constname":"k_ScreenshotThumbWidth", "consttype":"int", "constval":"200" }, + { "constname":"k_UGCQueryHandleInvalid", "consttype":"UGCQueryHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"k_UGCUpdateHandleInvalid", "consttype":"UGCUpdateHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"kNumUGCResultsPerPage", "consttype":"uint32", "constval":"50" }, + { "constname":"k_cchDeveloperMetadataMax", "consttype":"uint32", "constval":"5000" }, + { "constname":"INVALID_HTMLBROWSER", "consttype":"uint32", "constval":"0" }, + { "constname":"k_SteamItemInstanceIDInvalid", "consttype":"SteamItemInstanceID_t", "constval":"( SteamItemInstanceID_t ) ~ 0" }, + { "constname":"k_SteamInventoryResultInvalid", "consttype":"SteamInventoryResult_t", "constval":"- 1" }, + { "constname":"k_SteamInventoryUpdateHandleInvalid", "consttype":"SteamInventoryUpdateHandle_t", "constval":"0xffffffffffffffffull" }, + { "constname":"k_HSteamNetConnection_Invalid", "consttype":"HSteamNetConnection", "constval":"0" }, + { "constname":"k_HSteamListenSocket_Invalid", "consttype":"HSteamListenSocket", "constval":"0" }, + { "constname":"k_HSteamNetPollGroup_Invalid", "consttype":"HSteamNetPollGroup", "constval":"0" }, + { "constname":"k_cchMaxSteamNetworkingErrMsg", "consttype":"int", "constval":"1024" }, + { "constname":"k_cchSteamNetworkingMaxConnectionCloseReason", "consttype":"int", "constval":"128" }, + { "constname":"k_cchSteamNetworkingMaxConnectionDescription", "consttype":"int", "constval":"128" }, + { "constname":"k_cchSteamNetworkingMaxConnectionAppName", "consttype":"int", "constval":"32" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_Unauthenticated", "consttype":"int", "constval":"1" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_Unencrypted", "consttype":"int", "constval":"2" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_LoopbackBuffers", "consttype":"int", "constval":"4" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_Fast", "consttype":"int", "constval":"8" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_Relayed", "consttype":"int", "constval":"16" }, + { "constname":"k_nSteamNetworkConnectionInfoFlags_DualWifi", "consttype":"int", "constval":"32" }, + { "constname":"k_cbMaxSteamNetworkingSocketsMessageSizeSend", "consttype":"int", "constval":"512 * 1024" }, + { "constname":"k_nSteamNetworkingSend_Unreliable", "consttype":"int", "constval":"0" }, + { "constname":"k_nSteamNetworkingSend_NoNagle", "consttype":"int", "constval":"1" }, + { "constname":"k_nSteamNetworkingSend_UnreliableNoNagle", "consttype":"int", "constval":"k_nSteamNetworkingSend_Unreliable | k_nSteamNetworkingSend_NoNagle" }, + { "constname":"k_nSteamNetworkingSend_NoDelay", "consttype":"int", "constval":"4" }, + { "constname":"k_nSteamNetworkingSend_UnreliableNoDelay", "consttype":"int", "constval":"k_nSteamNetworkingSend_Unreliable | k_nSteamNetworkingSend_NoDelay | k_nSteamNetworkingSend_NoNagle" }, + { "constname":"k_nSteamNetworkingSend_Reliable", "consttype":"int", "constval":"8" }, + { "constname":"k_nSteamNetworkingSend_ReliableNoNagle", "consttype":"int", "constval":"k_nSteamNetworkingSend_Reliable | k_nSteamNetworkingSend_NoNagle" }, + { "constname":"k_nSteamNetworkingSend_UseCurrentThread", "consttype":"int", "constval":"16" }, + { "constname":"k_nSteamNetworkingSend_AutoRestartBrokenSession", "consttype":"int", "constval":"32" }, + { "constname":"k_cchMaxSteamNetworkingPingLocationString", "consttype":"int", "constval":"1024" }, + { "constname":"k_nSteamNetworkingPing_Failed", "consttype":"int", "constval":"- 1" }, + { "constname":"k_nSteamNetworkingPing_Unknown", "consttype":"int", "constval":"- 2" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Default", "consttype":"int", "constval":"- 1" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Disable", "consttype":"int", "constval":"0" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Relay", "consttype":"int", "constval":"1" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Private", "consttype":"int", "constval":"2" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Public", "consttype":"int", "constval":"4" }, + { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_All", "consttype":"int", "constval":"0x7fffffff" }, + { "constname":"k_SteamDatagramPOPID_dev", "consttype":"SteamNetworkingPOPID", "constval":"( ( uint32 ) 'd' << 16U ) | ( ( uint32 ) 'e' << 8U ) | ( uint32 ) 'v'" }, + { "constname":"STEAMGAMESERVER_QUERY_PORT_SHARED", "consttype":"uint16", "constval":"0xffff" }, + { "constname":"MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE", "consttype":"uint16", "constval":"STEAMGAMESERVER_QUERY_PORT_SHARED" }, + { "constname":"k_cbSteamDatagramMaxSerializedTicket", "consttype":"uint32", "constval":"512" }, + { "constname":"k_cbMaxSteamDatagramGameCoordinatorServerLoginAppData", "consttype":"uint32", "constval":"2048" }, + { "constname":"k_cbMaxSteamDatagramGameCoordinatorServerLoginSerialized", "consttype":"uint32", "constval":"4096" }, + { "constname":"k_cbSteamNetworkingSocketsFakeUDPPortRecommendedMTU", "consttype":"int", "constval":"1200" }, + { "constname":"k_cbSteamNetworkingSocketsFakeUDPPortMaxMessageSize", "consttype":"int", "constval":"4096" } + ], + "enums": [ + { + "enumname": "ESteamIPType", + "values": [ + { "name":"k_ESteamIPTypeIPv4", "value":"0" }, + { "name":"k_ESteamIPTypeIPv6", "value":"1" } + ] + }, + { + "enumname": "EUniverse", + "values": [ + { "name":"k_EUniverseInvalid", "value":"0" }, + { "name":"k_EUniversePublic", "value":"1" }, + { "name":"k_EUniverseBeta", "value":"2" }, + { "name":"k_EUniverseInternal", "value":"3" }, + { "name":"k_EUniverseDev", "value":"4" }, + { "name":"k_EUniverseMax", "value":"5" } + ] + }, + { + "enumname": "EResult", + "values": [ + { "name":"k_EResultNone", "value":"0" }, + { "name":"k_EResultOK", "value":"1" }, + { "name":"k_EResultFail", "value":"2" }, + { "name":"k_EResultNoConnection", "value":"3" }, + { "name":"k_EResultInvalidPassword", "value":"5" }, + { "name":"k_EResultLoggedInElsewhere", "value":"6" }, + { "name":"k_EResultInvalidProtocolVer", "value":"7" }, + { "name":"k_EResultInvalidParam", "value":"8" }, + { "name":"k_EResultFileNotFound", "value":"9" }, + { "name":"k_EResultBusy", "value":"10" }, + { "name":"k_EResultInvalidState", "value":"11" }, + { "name":"k_EResultInvalidName", "value":"12" }, + { "name":"k_EResultInvalidEmail", "value":"13" }, + { "name":"k_EResultDuplicateName", "value":"14" }, + { "name":"k_EResultAccessDenied", "value":"15" }, + { "name":"k_EResultTimeout", "value":"16" }, + { "name":"k_EResultBanned", "value":"17" }, + { "name":"k_EResultAccountNotFound", "value":"18" }, + { "name":"k_EResultInvalidSteamID", "value":"19" }, + { "name":"k_EResultServiceUnavailable", "value":"20" }, + { "name":"k_EResultNotLoggedOn", "value":"21" }, + { "name":"k_EResultPending", "value":"22" }, + { "name":"k_EResultEncryptionFailure", "value":"23" }, + { "name":"k_EResultInsufficientPrivilege", "value":"24" }, + { "name":"k_EResultLimitExceeded", "value":"25" }, + { "name":"k_EResultRevoked", "value":"26" }, + { "name":"k_EResultExpired", "value":"27" }, + { "name":"k_EResultAlreadyRedeemed", "value":"28" }, + { "name":"k_EResultDuplicateRequest", "value":"29" }, + { "name":"k_EResultAlreadyOwned", "value":"30" }, + { "name":"k_EResultIPNotFound", "value":"31" }, + { "name":"k_EResultPersistFailed", "value":"32" }, + { "name":"k_EResultLockingFailed", "value":"33" }, + { "name":"k_EResultLogonSessionReplaced", "value":"34" }, + { "name":"k_EResultConnectFailed", "value":"35" }, + { "name":"k_EResultHandshakeFailed", "value":"36" }, + { "name":"k_EResultIOFailure", "value":"37" }, + { "name":"k_EResultRemoteDisconnect", "value":"38" }, + { "name":"k_EResultShoppingCartNotFound", "value":"39" }, + { "name":"k_EResultBlocked", "value":"40" }, + { "name":"k_EResultIgnored", "value":"41" }, + { "name":"k_EResultNoMatch", "value":"42" }, + { "name":"k_EResultAccountDisabled", "value":"43" }, + { "name":"k_EResultServiceReadOnly", "value":"44" }, + { "name":"k_EResultAccountNotFeatured", "value":"45" }, + { "name":"k_EResultAdministratorOK", "value":"46" }, + { "name":"k_EResultContentVersion", "value":"47" }, + { "name":"k_EResultTryAnotherCM", "value":"48" }, + { "name":"k_EResultPasswordRequiredToKickSession", "value":"49" }, + { "name":"k_EResultAlreadyLoggedInElsewhere", "value":"50" }, + { "name":"k_EResultSuspended", "value":"51" }, + { "name":"k_EResultCancelled", "value":"52" }, + { "name":"k_EResultDataCorruption", "value":"53" }, + { "name":"k_EResultDiskFull", "value":"54" }, + { "name":"k_EResultRemoteCallFailed", "value":"55" }, + { "name":"k_EResultPasswordUnset", "value":"56" }, + { "name":"k_EResultExternalAccountUnlinked", "value":"57" }, + { "name":"k_EResultPSNTicketInvalid", "value":"58" }, + { "name":"k_EResultExternalAccountAlreadyLinked", "value":"59" }, + { "name":"k_EResultRemoteFileConflict", "value":"60" }, + { "name":"k_EResultIllegalPassword", "value":"61" }, + { "name":"k_EResultSameAsPreviousValue", "value":"62" }, + { "name":"k_EResultAccountLogonDenied", "value":"63" }, + { "name":"k_EResultCannotUseOldPassword", "value":"64" }, + { "name":"k_EResultInvalidLoginAuthCode", "value":"65" }, + { "name":"k_EResultAccountLogonDeniedNoMail", "value":"66" }, + { "name":"k_EResultHardwareNotCapableOfIPT", "value":"67" }, + { "name":"k_EResultIPTInitError", "value":"68" }, + { "name":"k_EResultParentalControlRestricted", "value":"69" }, + { "name":"k_EResultFacebookQueryError", "value":"70" }, + { "name":"k_EResultExpiredLoginAuthCode", "value":"71" }, + { "name":"k_EResultIPLoginRestrictionFailed", "value":"72" }, + { "name":"k_EResultAccountLockedDown", "value":"73" }, + { "name":"k_EResultAccountLogonDeniedVerifiedEmailRequired", "value":"74" }, + { "name":"k_EResultNoMatchingURL", "value":"75" }, + { "name":"k_EResultBadResponse", "value":"76" }, + { "name":"k_EResultRequirePasswordReEntry", "value":"77" }, + { "name":"k_EResultValueOutOfRange", "value":"78" }, + { "name":"k_EResultUnexpectedError", "value":"79" }, + { "name":"k_EResultDisabled", "value":"80" }, + { "name":"k_EResultInvalidCEGSubmission", "value":"81" }, + { "name":"k_EResultRestrictedDevice", "value":"82" }, + { "name":"k_EResultRegionLocked", "value":"83" }, + { "name":"k_EResultRateLimitExceeded", "value":"84" }, + { "name":"k_EResultAccountLoginDeniedNeedTwoFactor", "value":"85" }, + { "name":"k_EResultItemDeleted", "value":"86" }, + { "name":"k_EResultAccountLoginDeniedThrottle", "value":"87" }, + { "name":"k_EResultTwoFactorCodeMismatch", "value":"88" }, + { "name":"k_EResultTwoFactorActivationCodeMismatch", "value":"89" }, + { "name":"k_EResultAccountAssociatedToMultiplePartners", "value":"90" }, + { "name":"k_EResultNotModified", "value":"91" }, + { "name":"k_EResultNoMobileDevice", "value":"92" }, + { "name":"k_EResultTimeNotSynced", "value":"93" }, + { "name":"k_EResultSmsCodeFailed", "value":"94" }, + { "name":"k_EResultAccountLimitExceeded", "value":"95" }, + { "name":"k_EResultAccountActivityLimitExceeded", "value":"96" }, + { "name":"k_EResultPhoneActivityLimitExceeded", "value":"97" }, + { "name":"k_EResultRefundToWallet", "value":"98" }, + { "name":"k_EResultEmailSendFailure", "value":"99" }, + { "name":"k_EResultNotSettled", "value":"100" }, + { "name":"k_EResultNeedCaptcha", "value":"101" }, + { "name":"k_EResultGSLTDenied", "value":"102" }, + { "name":"k_EResultGSOwnerDenied", "value":"103" }, + { "name":"k_EResultInvalidItemType", "value":"104" }, + { "name":"k_EResultIPBanned", "value":"105" }, + { "name":"k_EResultGSLTExpired", "value":"106" }, + { "name":"k_EResultInsufficientFunds", "value":"107" }, + { "name":"k_EResultTooManyPending", "value":"108" }, + { "name":"k_EResultNoSiteLicensesFound", "value":"109" }, + { "name":"k_EResultWGNetworkSendExceeded", "value":"110" }, + { "name":"k_EResultAccountNotFriends", "value":"111" }, + { "name":"k_EResultLimitedUserAccount", "value":"112" }, + { "name":"k_EResultCantRemoveItem", "value":"113" }, + { "name":"k_EResultAccountDeleted", "value":"114" }, + { "name":"k_EResultExistingUserCancelledLicense", "value":"115" }, + { "name":"k_EResultCommunityCooldown", "value":"116" }, + { "name":"k_EResultNoLauncherSpecified", "value":"117" }, + { "name":"k_EResultMustAgreeToSSA", "value":"118" }, + { "name":"k_EResultLauncherMigrated", "value":"119" }, + { "name":"k_EResultSteamRealmMismatch", "value":"120" }, + { "name":"k_EResultInvalidSignature", "value":"121" }, + { "name":"k_EResultParseFailure", "value":"122" }, + { "name":"k_EResultNoVerifiedPhone", "value":"123" }, + { "name":"k_EResultInsufficientBattery", "value":"124" }, + { "name":"k_EResultChargerRequired", "value":"125" }, + { "name":"k_EResultCachedCredentialInvalid", "value":"126" }, + { "name":"K_EResultPhoneNumberIsVOIP", "value":"127" } + ] + }, + { + "enumname": "EVoiceResult", + "values": [ + { "name":"k_EVoiceResultOK", "value":"0" }, + { "name":"k_EVoiceResultNotInitialized", "value":"1" }, + { "name":"k_EVoiceResultNotRecording", "value":"2" }, + { "name":"k_EVoiceResultNoData", "value":"3" }, + { "name":"k_EVoiceResultBufferTooSmall", "value":"4" }, + { "name":"k_EVoiceResultDataCorrupted", "value":"5" }, + { "name":"k_EVoiceResultRestricted", "value":"6" }, + { "name":"k_EVoiceResultUnsupportedCodec", "value":"7" }, + { "name":"k_EVoiceResultReceiverOutOfDate", "value":"8" }, + { "name":"k_EVoiceResultReceiverDidNotAnswer", "value":"9" } + ] + }, + { + "enumname": "EDenyReason", + "values": [ + { "name":"k_EDenyInvalid", "value":"0" }, + { "name":"k_EDenyInvalidVersion", "value":"1" }, + { "name":"k_EDenyGeneric", "value":"2" }, + { "name":"k_EDenyNotLoggedOn", "value":"3" }, + { "name":"k_EDenyNoLicense", "value":"4" }, + { "name":"k_EDenyCheater", "value":"5" }, + { "name":"k_EDenyLoggedInElseWhere", "value":"6" }, + { "name":"k_EDenyUnknownText", "value":"7" }, + { "name":"k_EDenyIncompatibleAnticheat", "value":"8" }, + { "name":"k_EDenyMemoryCorruption", "value":"9" }, + { "name":"k_EDenyIncompatibleSoftware", "value":"10" }, + { "name":"k_EDenySteamConnectionLost", "value":"11" }, + { "name":"k_EDenySteamConnectionError", "value":"12" }, + { "name":"k_EDenySteamResponseTimedOut", "value":"13" }, + { "name":"k_EDenySteamValidationStalled", "value":"14" }, + { "name":"k_EDenySteamOwnerLeftGuestUser", "value":"15" } + ] + }, + { + "enumname": "EBeginAuthSessionResult", + "values": [ + { "name":"k_EBeginAuthSessionResultOK", "value":"0" }, + { "name":"k_EBeginAuthSessionResultInvalidTicket", "value":"1" }, + { "name":"k_EBeginAuthSessionResultDuplicateRequest", "value":"2" }, + { "name":"k_EBeginAuthSessionResultInvalidVersion", "value":"3" }, + { "name":"k_EBeginAuthSessionResultGameMismatch", "value":"4" }, + { "name":"k_EBeginAuthSessionResultExpiredTicket", "value":"5" } + ] + }, + { + "enumname": "EAuthSessionResponse", + "values": [ + { "name":"k_EAuthSessionResponseOK", "value":"0" }, + { "name":"k_EAuthSessionResponseUserNotConnectedToSteam", "value":"1" }, + { "name":"k_EAuthSessionResponseNoLicenseOrExpired", "value":"2" }, + { "name":"k_EAuthSessionResponseVACBanned", "value":"3" }, + { "name":"k_EAuthSessionResponseLoggedInElseWhere", "value":"4" }, + { "name":"k_EAuthSessionResponseVACCheckTimedOut", "value":"5" }, + { "name":"k_EAuthSessionResponseAuthTicketCanceled", "value":"6" }, + { "name":"k_EAuthSessionResponseAuthTicketInvalidAlreadyUsed", "value":"7" }, + { "name":"k_EAuthSessionResponseAuthTicketInvalid", "value":"8" }, + { "name":"k_EAuthSessionResponsePublisherIssuedBan", "value":"9" } + ] + }, + { + "enumname": "EUserHasLicenseForAppResult", + "values": [ + { "name":"k_EUserHasLicenseResultHasLicense", "value":"0" }, + { "name":"k_EUserHasLicenseResultDoesNotHaveLicense", "value":"1" }, + { "name":"k_EUserHasLicenseResultNoAuth", "value":"2" } + ] + }, + { + "enumname": "EAccountType", + "values": [ + { "name":"k_EAccountTypeInvalid", "value":"0" }, + { "name":"k_EAccountTypeIndividual", "value":"1" }, + { "name":"k_EAccountTypeMultiseat", "value":"2" }, + { "name":"k_EAccountTypeGameServer", "value":"3" }, + { "name":"k_EAccountTypeAnonGameServer", "value":"4" }, + { "name":"k_EAccountTypePending", "value":"5" }, + { "name":"k_EAccountTypeContentServer", "value":"6" }, + { "name":"k_EAccountTypeClan", "value":"7" }, + { "name":"k_EAccountTypeChat", "value":"8" }, + { "name":"k_EAccountTypeConsoleUser", "value":"9" }, + { "name":"k_EAccountTypeAnonUser", "value":"10" }, + { "name":"k_EAccountTypeMax", "value":"11" } + ] + }, + { + "enumname": "EChatEntryType", + "values": [ + { "name":"k_EChatEntryTypeInvalid", "value":"0" }, + { "name":"k_EChatEntryTypeChatMsg", "value":"1" }, + { "name":"k_EChatEntryTypeTyping", "value":"2" }, + { "name":"k_EChatEntryTypeInviteGame", "value":"3" }, + { "name":"k_EChatEntryTypeEmote", "value":"4" }, + { "name":"k_EChatEntryTypeLeftConversation", "value":"6" }, + { "name":"k_EChatEntryTypeEntered", "value":"7" }, + { "name":"k_EChatEntryTypeWasKicked", "value":"8" }, + { "name":"k_EChatEntryTypeWasBanned", "value":"9" }, + { "name":"k_EChatEntryTypeDisconnected", "value":"10" }, + { "name":"k_EChatEntryTypeHistoricalChat", "value":"11" }, + { "name":"k_EChatEntryTypeLinkBlocked", "value":"14" } + ] + }, + { + "enumname": "EChatRoomEnterResponse", + "values": [ + { "name":"k_EChatRoomEnterResponseSuccess", "value":"1" }, + { "name":"k_EChatRoomEnterResponseDoesntExist", "value":"2" }, + { "name":"k_EChatRoomEnterResponseNotAllowed", "value":"3" }, + { "name":"k_EChatRoomEnterResponseFull", "value":"4" }, + { "name":"k_EChatRoomEnterResponseError", "value":"5" }, + { "name":"k_EChatRoomEnterResponseBanned", "value":"6" }, + { "name":"k_EChatRoomEnterResponseLimited", "value":"7" }, + { "name":"k_EChatRoomEnterResponseClanDisabled", "value":"8" }, + { "name":"k_EChatRoomEnterResponseCommunityBan", "value":"9" }, + { "name":"k_EChatRoomEnterResponseMemberBlockedYou", "value":"10" }, + { "name":"k_EChatRoomEnterResponseYouBlockedMember", "value":"11" }, + { "name":"k_EChatRoomEnterResponseRatelimitExceeded", "value":"15" } + ] + }, + { + "enumname": "EChatSteamIDInstanceFlags", + "values": [ + { "name":"k_EChatAccountInstanceMask", "value":"4095" }, + { "name":"k_EChatInstanceFlagClan", "value":"524288" }, + { "name":"k_EChatInstanceFlagLobby", "value":"262144" }, + { "name":"k_EChatInstanceFlagMMSLobby", "value":"131072" } + ] + }, + { + "enumname": "ENotificationPosition", + "values": [ + { "name":"k_EPositionTopLeft", "value":"0" }, + { "name":"k_EPositionTopRight", "value":"1" }, + { "name":"k_EPositionBottomLeft", "value":"2" }, + { "name":"k_EPositionBottomRight", "value":"3" } + ] + }, + { + "enumname": "EBroadcastUploadResult", + "values": [ + { "name":"k_EBroadcastUploadResultNone", "value":"0" }, + { "name":"k_EBroadcastUploadResultOK", "value":"1" }, + { "name":"k_EBroadcastUploadResultInitFailed", "value":"2" }, + { "name":"k_EBroadcastUploadResultFrameFailed", "value":"3" }, + { "name":"k_EBroadcastUploadResultTimeout", "value":"4" }, + { "name":"k_EBroadcastUploadResultBandwidthExceeded", "value":"5" }, + { "name":"k_EBroadcastUploadResultLowFPS", "value":"6" }, + { "name":"k_EBroadcastUploadResultMissingKeyFrames", "value":"7" }, + { "name":"k_EBroadcastUploadResultNoConnection", "value":"8" }, + { "name":"k_EBroadcastUploadResultRelayFailed", "value":"9" }, + { "name":"k_EBroadcastUploadResultSettingsChanged", "value":"10" }, + { "name":"k_EBroadcastUploadResultMissingAudio", "value":"11" }, + { "name":"k_EBroadcastUploadResultTooFarBehind", "value":"12" }, + { "name":"k_EBroadcastUploadResultTranscodeBehind", "value":"13" }, + { "name":"k_EBroadcastUploadResultNotAllowedToPlay", "value":"14" }, + { "name":"k_EBroadcastUploadResultBusy", "value":"15" }, + { "name":"k_EBroadcastUploadResultBanned", "value":"16" }, + { "name":"k_EBroadcastUploadResultAlreadyActive", "value":"17" }, + { "name":"k_EBroadcastUploadResultForcedOff", "value":"18" }, + { "name":"k_EBroadcastUploadResultAudioBehind", "value":"19" }, + { "name":"k_EBroadcastUploadResultShutdown", "value":"20" }, + { "name":"k_EBroadcastUploadResultDisconnect", "value":"21" }, + { "name":"k_EBroadcastUploadResultVideoInitFailed", "value":"22" }, + { "name":"k_EBroadcastUploadResultAudioInitFailed", "value":"23" } + ] + }, + { + "enumname": "EMarketNotAllowedReasonFlags", + "values": [ + { "name":"k_EMarketNotAllowedReason_None", "value":"0" }, + { "name":"k_EMarketNotAllowedReason_TemporaryFailure", "value":"1" }, + { "name":"k_EMarketNotAllowedReason_AccountDisabled", "value":"2" }, + { "name":"k_EMarketNotAllowedReason_AccountLockedDown", "value":"4" }, + { "name":"k_EMarketNotAllowedReason_AccountLimited", "value":"8" }, + { "name":"k_EMarketNotAllowedReason_TradeBanned", "value":"16" }, + { "name":"k_EMarketNotAllowedReason_AccountNotTrusted", "value":"32" }, + { "name":"k_EMarketNotAllowedReason_SteamGuardNotEnabled", "value":"64" }, + { "name":"k_EMarketNotAllowedReason_SteamGuardOnlyRecentlyEnabled", "value":"128" }, + { "name":"k_EMarketNotAllowedReason_RecentPasswordReset", "value":"256" }, + { "name":"k_EMarketNotAllowedReason_NewPaymentMethod", "value":"512" }, + { "name":"k_EMarketNotAllowedReason_InvalidCookie", "value":"1024" }, + { "name":"k_EMarketNotAllowedReason_UsingNewDevice", "value":"2048" }, + { "name":"k_EMarketNotAllowedReason_RecentSelfRefund", "value":"4096" }, + { "name":"k_EMarketNotAllowedReason_NewPaymentMethodCannotBeVerified", "value":"8192" }, + { "name":"k_EMarketNotAllowedReason_NoRecentPurchases", "value":"16384" }, + { "name":"k_EMarketNotAllowedReason_AcceptedWalletGift", "value":"32768" } + ] + }, + { + "enumname": "EDurationControlProgress", + "values": [ + { "name":"k_EDurationControlProgress_Full", "value":"0" }, + { "name":"k_EDurationControlProgress_Half", "value":"1" }, + { "name":"k_EDurationControlProgress_None", "value":"2" }, + { "name":"k_EDurationControl_ExitSoon_3h", "value":"3" }, + { "name":"k_EDurationControl_ExitSoon_5h", "value":"4" }, + { "name":"k_EDurationControl_ExitSoon_Night", "value":"5" } + ] + }, + { + "enumname": "EDurationControlNotification", + "values": [ + { "name":"k_EDurationControlNotification_None", "value":"0" }, + { "name":"k_EDurationControlNotification_1Hour", "value":"1" }, + { "name":"k_EDurationControlNotification_3Hours", "value":"2" }, + { "name":"k_EDurationControlNotification_HalfProgress", "value":"3" }, + { "name":"k_EDurationControlNotification_NoProgress", "value":"4" }, + { "name":"k_EDurationControlNotification_ExitSoon_3h", "value":"5" }, + { "name":"k_EDurationControlNotification_ExitSoon_5h", "value":"6" }, + { "name":"k_EDurationControlNotification_ExitSoon_Night", "value":"7" } + ] + }, + { + "enumname": "EDurationControlOnlineState", + "values": [ + { "name":"k_EDurationControlOnlineState_Invalid", "value":"0" }, + { "name":"k_EDurationControlOnlineState_Offline", "value":"1" }, + { "name":"k_EDurationControlOnlineState_Online", "value":"2" }, + { "name":"k_EDurationControlOnlineState_OnlineHighPri", "value":"3" } + ] + }, + { + "enumname": "EGameSearchErrorCode_t", + "values": [ + { "name":"k_EGameSearchErrorCode_OK", "value":"1" }, + { "name":"k_EGameSearchErrorCode_Failed_Search_Already_In_Progress", "value":"2" }, + { "name":"k_EGameSearchErrorCode_Failed_No_Search_In_Progress", "value":"3" }, + { "name":"k_EGameSearchErrorCode_Failed_Not_Lobby_Leader", "value":"4" }, + { "name":"k_EGameSearchErrorCode_Failed_No_Host_Available", "value":"5" }, + { "name":"k_EGameSearchErrorCode_Failed_Search_Params_Invalid", "value":"6" }, + { "name":"k_EGameSearchErrorCode_Failed_Offline", "value":"7" }, + { "name":"k_EGameSearchErrorCode_Failed_NotAuthorized", "value":"8" }, + { "name":"k_EGameSearchErrorCode_Failed_Unknown_Error", "value":"9" } + ] + }, + { + "enumname": "EPlayerResult_t", + "values": [ + { "name":"k_EPlayerResultFailedToConnect", "value":"1" }, + { "name":"k_EPlayerResultAbandoned", "value":"2" }, + { "name":"k_EPlayerResultKicked", "value":"3" }, + { "name":"k_EPlayerResultIncomplete", "value":"4" }, + { "name":"k_EPlayerResultCompleted", "value":"5" } + ] + }, + { + "enumname": "ESteamIPv6ConnectivityProtocol", + "values": [ + { "name":"k_ESteamIPv6ConnectivityProtocol_Invalid", "value":"0" }, + { "name":"k_ESteamIPv6ConnectivityProtocol_HTTP", "value":"1" }, + { "name":"k_ESteamIPv6ConnectivityProtocol_UDP", "value":"2" } + ] + }, + { + "enumname": "ESteamIPv6ConnectivityState", + "values": [ + { "name":"k_ESteamIPv6ConnectivityState_Unknown", "value":"0" }, + { "name":"k_ESteamIPv6ConnectivityState_Good", "value":"1" }, + { "name":"k_ESteamIPv6ConnectivityState_Bad", "value":"2" } + ] + }, + { + "enumname": "EFriendRelationship", + "values": [ + { "name":"k_EFriendRelationshipNone", "value":"0" }, + { "name":"k_EFriendRelationshipBlocked", "value":"1" }, + { "name":"k_EFriendRelationshipRequestRecipient", "value":"2" }, + { "name":"k_EFriendRelationshipFriend", "value":"3" }, + { "name":"k_EFriendRelationshipRequestInitiator", "value":"4" }, + { "name":"k_EFriendRelationshipIgnored", "value":"5" }, + { "name":"k_EFriendRelationshipIgnoredFriend", "value":"6" }, + { "name":"k_EFriendRelationshipSuggested_DEPRECATED", "value":"7" }, + { "name":"k_EFriendRelationshipMax", "value":"8" } + ] + }, + { + "enumname": "EPersonaState", + "values": [ + { "name":"k_EPersonaStateOffline", "value":"0" }, + { "name":"k_EPersonaStateOnline", "value":"1" }, + { "name":"k_EPersonaStateBusy", "value":"2" }, + { "name":"k_EPersonaStateAway", "value":"3" }, + { "name":"k_EPersonaStateSnooze", "value":"4" }, + { "name":"k_EPersonaStateLookingToTrade", "value":"5" }, + { "name":"k_EPersonaStateLookingToPlay", "value":"6" }, + { "name":"k_EPersonaStateInvisible", "value":"7" }, + { "name":"k_EPersonaStateMax", "value":"8" } + ] + }, + { + "enumname": "EFriendFlags", + "values": [ + { "name":"k_EFriendFlagNone", "value":"0" }, + { "name":"k_EFriendFlagBlocked", "value":"1" }, + { "name":"k_EFriendFlagFriendshipRequested", "value":"2" }, + { "name":"k_EFriendFlagImmediate", "value":"4" }, + { "name":"k_EFriendFlagClanMember", "value":"8" }, + { "name":"k_EFriendFlagOnGameServer", "value":"16" }, + { "name":"k_EFriendFlagRequestingFriendship", "value":"128" }, + { "name":"k_EFriendFlagRequestingInfo", "value":"256" }, + { "name":"k_EFriendFlagIgnored", "value":"512" }, + { "name":"k_EFriendFlagIgnoredFriend", "value":"1024" }, + { "name":"k_EFriendFlagChatMember", "value":"4096" }, + { "name":"k_EFriendFlagAll", "value":"65535" } + ] + }, + { + "enumname": "EUserRestriction", + "values": [ + { "name":"k_nUserRestrictionNone", "value":"0" }, + { "name":"k_nUserRestrictionUnknown", "value":"1" }, + { "name":"k_nUserRestrictionAnyChat", "value":"2" }, + { "name":"k_nUserRestrictionVoiceChat", "value":"4" }, + { "name":"k_nUserRestrictionGroupChat", "value":"8" }, + { "name":"k_nUserRestrictionRating", "value":"16" }, + { "name":"k_nUserRestrictionGameInvites", "value":"32" }, + { "name":"k_nUserRestrictionTrading", "value":"64" } + ] + }, + { + "enumname": "EOverlayToStoreFlag", + "values": [ + { "name":"k_EOverlayToStoreFlag_None", "value":"0" }, + { "name":"k_EOverlayToStoreFlag_AddToCart", "value":"1" }, + { "name":"k_EOverlayToStoreFlag_AddToCartAndShow", "value":"2" } + ] + }, + { + "enumname": "EActivateGameOverlayToWebPageMode", + "values": [ + { "name":"k_EActivateGameOverlayToWebPageMode_Default", "value":"0" }, + { "name":"k_EActivateGameOverlayToWebPageMode_Modal", "value":"1" } + ] + }, + { + "enumname": "ECommunityProfileItemType", + "values": [ + { "name":"k_ECommunityProfileItemType_AnimatedAvatar", "value":"0" }, + { "name":"k_ECommunityProfileItemType_AvatarFrame", "value":"1" }, + { "name":"k_ECommunityProfileItemType_ProfileModifier", "value":"2" }, + { "name":"k_ECommunityProfileItemType_ProfileBackground", "value":"3" }, + { "name":"k_ECommunityProfileItemType_MiniProfileBackground", "value":"4" } + ] + }, + { + "enumname": "ECommunityProfileItemProperty", + "values": [ + { "name":"k_ECommunityProfileItemProperty_ImageSmall", "value":"0" }, + { "name":"k_ECommunityProfileItemProperty_ImageLarge", "value":"1" }, + { "name":"k_ECommunityProfileItemProperty_InternalName", "value":"2" }, + { "name":"k_ECommunityProfileItemProperty_Title", "value":"3" }, + { "name":"k_ECommunityProfileItemProperty_Description", "value":"4" }, + { "name":"k_ECommunityProfileItemProperty_AppID", "value":"5" }, + { "name":"k_ECommunityProfileItemProperty_TypeID", "value":"6" }, + { "name":"k_ECommunityProfileItemProperty_Class", "value":"7" }, + { "name":"k_ECommunityProfileItemProperty_MovieWebM", "value":"8" }, + { "name":"k_ECommunityProfileItemProperty_MovieMP4", "value":"9" }, + { "name":"k_ECommunityProfileItemProperty_MovieWebMSmall", "value":"10" }, + { "name":"k_ECommunityProfileItemProperty_MovieMP4Small", "value":"11" } + ] + }, + { + "enumname": "EPersonaChange", + "values": [ + { "name":"k_EPersonaChangeName", "value":"1" }, + { "name":"k_EPersonaChangeStatus", "value":"2" }, + { "name":"k_EPersonaChangeComeOnline", "value":"4" }, + { "name":"k_EPersonaChangeGoneOffline", "value":"8" }, + { "name":"k_EPersonaChangeGamePlayed", "value":"16" }, + { "name":"k_EPersonaChangeGameServer", "value":"32" }, + { "name":"k_EPersonaChangeAvatar", "value":"64" }, + { "name":"k_EPersonaChangeJoinedSource", "value":"128" }, + { "name":"k_EPersonaChangeLeftSource", "value":"256" }, + { "name":"k_EPersonaChangeRelationshipChanged", "value":"512" }, + { "name":"k_EPersonaChangeNameFirstSet", "value":"1024" }, + { "name":"k_EPersonaChangeBroadcast", "value":"2048" }, + { "name":"k_EPersonaChangeNickname", "value":"4096" }, + { "name":"k_EPersonaChangeSteamLevel", "value":"8192" }, + { "name":"k_EPersonaChangeRichPresence", "value":"16384" } + ] + }, + { + "enumname": "ESteamAPICallFailure", + "values": [ + { "name":"k_ESteamAPICallFailureNone", "value":"-1" }, + { "name":"k_ESteamAPICallFailureSteamGone", "value":"0" }, + { "name":"k_ESteamAPICallFailureNetworkFailure", "value":"1" }, + { "name":"k_ESteamAPICallFailureInvalidHandle", "value":"2" }, + { "name":"k_ESteamAPICallFailureMismatchedCallback", "value":"3" } + ] + }, + { + "enumname": "EGamepadTextInputMode", + "values": [ + { "name":"k_EGamepadTextInputModeNormal", "value":"0" }, + { "name":"k_EGamepadTextInputModePassword", "value":"1" } + ] + }, + { + "enumname": "EGamepadTextInputLineMode", + "values": [ + { "name":"k_EGamepadTextInputLineModeSingleLine", "value":"0" }, + { "name":"k_EGamepadTextInputLineModeMultipleLines", "value":"1" } + ] + }, + { + "enumname": "EFloatingGamepadTextInputMode", + "values": [ + { "name":"k_EFloatingGamepadTextInputModeModeSingleLine", "value":"0" }, + { "name":"k_EFloatingGamepadTextInputModeModeMultipleLines", "value":"1" }, + { "name":"k_EFloatingGamepadTextInputModeModeEmail", "value":"2" }, + { "name":"k_EFloatingGamepadTextInputModeModeNumeric", "value":"3" } + ] + }, + { + "enumname": "ETextFilteringContext", + "values": [ + { "name":"k_ETextFilteringContextUnknown", "value":"0" }, + { "name":"k_ETextFilteringContextGameContent", "value":"1" }, + { "name":"k_ETextFilteringContextChat", "value":"2" }, + { "name":"k_ETextFilteringContextName", "value":"3" } + ] + }, + { + "enumname": "ECheckFileSignature", + "values": [ + { "name":"k_ECheckFileSignatureInvalidSignature", "value":"0" }, + { "name":"k_ECheckFileSignatureValidSignature", "value":"1" }, + { "name":"k_ECheckFileSignatureFileNotFound", "value":"2" }, + { "name":"k_ECheckFileSignatureNoSignaturesFoundForThisApp", "value":"3" }, + { "name":"k_ECheckFileSignatureNoSignaturesFoundForThisFile", "value":"4" } + ] + }, + { + "enumname": "EMatchMakingServerResponse", + "values": [ + { "name":"eServerResponded", "value":"0" }, + { "name":"eServerFailedToRespond", "value":"1" }, + { "name":"eNoServersListedOnMasterServer", "value":"2" } + ] + }, + { + "enumname": "ELobbyType", + "values": [ + { "name":"k_ELobbyTypePrivate", "value":"0" }, + { "name":"k_ELobbyTypeFriendsOnly", "value":"1" }, + { "name":"k_ELobbyTypePublic", "value":"2" }, + { "name":"k_ELobbyTypeInvisible", "value":"3" }, + { "name":"k_ELobbyTypePrivateUnique", "value":"4" } + ] + }, + { + "enumname": "ELobbyComparison", + "values": [ + { "name":"k_ELobbyComparisonEqualToOrLessThan", "value":"-2" }, + { "name":"k_ELobbyComparisonLessThan", "value":"-1" }, + { "name":"k_ELobbyComparisonEqual", "value":"0" }, + { "name":"k_ELobbyComparisonGreaterThan", "value":"1" }, + { "name":"k_ELobbyComparisonEqualToOrGreaterThan", "value":"2" }, + { "name":"k_ELobbyComparisonNotEqual", "value":"3" } + ] + }, + { + "enumname": "ELobbyDistanceFilter", + "values": [ + { "name":"k_ELobbyDistanceFilterClose", "value":"0" }, + { "name":"k_ELobbyDistanceFilterDefault", "value":"1" }, + { "name":"k_ELobbyDistanceFilterFar", "value":"2" }, + { "name":"k_ELobbyDistanceFilterWorldwide", "value":"3" } + ] + }, + { + "enumname": "EChatMemberStateChange", + "values": [ + { "name":"k_EChatMemberStateChangeEntered", "value":"1" }, + { "name":"k_EChatMemberStateChangeLeft", "value":"2" }, + { "name":"k_EChatMemberStateChangeDisconnected", "value":"4" }, + { "name":"k_EChatMemberStateChangeKicked", "value":"8" }, + { "name":"k_EChatMemberStateChangeBanned", "value":"16" } + ] + }, + { + "enumname": "ESteamPartyBeaconLocationType", + "values": [ + { "name":"k_ESteamPartyBeaconLocationType_Invalid", "value":"0" }, + { "name":"k_ESteamPartyBeaconLocationType_ChatGroup", "value":"1" }, + { "name":"k_ESteamPartyBeaconLocationType_Max", "value":"2" } + ] + }, + { + "enumname": "ESteamPartyBeaconLocationData", + "values": [ + { "name":"k_ESteamPartyBeaconLocationDataInvalid", "value":"0" }, + { "name":"k_ESteamPartyBeaconLocationDataName", "value":"1" }, + { "name":"k_ESteamPartyBeaconLocationDataIconURLSmall", "value":"2" }, + { "name":"k_ESteamPartyBeaconLocationDataIconURLMedium", "value":"3" }, + { "name":"k_ESteamPartyBeaconLocationDataIconURLLarge", "value":"4" } + ] + }, + { + "enumname": "ERemoteStoragePlatform", + "values": [ + { "name":"k_ERemoteStoragePlatformNone", "value":"0" }, + { "name":"k_ERemoteStoragePlatformWindows", "value":"1" }, + { "name":"k_ERemoteStoragePlatformOSX", "value":"2" }, + { "name":"k_ERemoteStoragePlatformPS3", "value":"4" }, + { "name":"k_ERemoteStoragePlatformLinux", "value":"8" }, + { "name":"k_ERemoteStoragePlatformSwitch", "value":"16" }, + { "name":"k_ERemoteStoragePlatformAndroid", "value":"32" }, + { "name":"k_ERemoteStoragePlatformIOS", "value":"64" }, + { "name":"k_ERemoteStoragePlatformAll", "value":"-1" } + ] + }, + { + "enumname": "ERemoteStoragePublishedFileVisibility", + "values": [ + { "name":"k_ERemoteStoragePublishedFileVisibilityPublic", "value":"0" }, + { "name":"k_ERemoteStoragePublishedFileVisibilityFriendsOnly", "value":"1" }, + { "name":"k_ERemoteStoragePublishedFileVisibilityPrivate", "value":"2" }, + { "name":"k_ERemoteStoragePublishedFileVisibilityUnlisted", "value":"3" } + ] + }, + { + "enumname": "EWorkshopFileType", + "values": [ + { "name":"k_EWorkshopFileTypeFirst", "value":"0" }, + { "name":"k_EWorkshopFileTypeCommunity", "value":"0" }, + { "name":"k_EWorkshopFileTypeMicrotransaction", "value":"1" }, + { "name":"k_EWorkshopFileTypeCollection", "value":"2" }, + { "name":"k_EWorkshopFileTypeArt", "value":"3" }, + { "name":"k_EWorkshopFileTypeVideo", "value":"4" }, + { "name":"k_EWorkshopFileTypeScreenshot", "value":"5" }, + { "name":"k_EWorkshopFileTypeGame", "value":"6" }, + { "name":"k_EWorkshopFileTypeSoftware", "value":"7" }, + { "name":"k_EWorkshopFileTypeConcept", "value":"8" }, + { "name":"k_EWorkshopFileTypeWebGuide", "value":"9" }, + { "name":"k_EWorkshopFileTypeIntegratedGuide", "value":"10" }, + { "name":"k_EWorkshopFileTypeMerch", "value":"11" }, + { "name":"k_EWorkshopFileTypeControllerBinding", "value":"12" }, + { "name":"k_EWorkshopFileTypeSteamworksAccessInvite", "value":"13" }, + { "name":"k_EWorkshopFileTypeSteamVideo", "value":"14" }, + { "name":"k_EWorkshopFileTypeGameManagedItem", "value":"15" }, + { "name":"k_EWorkshopFileTypeMax", "value":"16" } + ] + }, + { + "enumname": "EWorkshopVote", + "values": [ + { "name":"k_EWorkshopVoteUnvoted", "value":"0" }, + { "name":"k_EWorkshopVoteFor", "value":"1" }, + { "name":"k_EWorkshopVoteAgainst", "value":"2" }, + { "name":"k_EWorkshopVoteLater", "value":"3" } + ] + }, + { + "enumname": "EWorkshopFileAction", + "values": [ + { "name":"k_EWorkshopFileActionPlayed", "value":"0" }, + { "name":"k_EWorkshopFileActionCompleted", "value":"1" } + ] + }, + { + "enumname": "EWorkshopEnumerationType", + "values": [ + { "name":"k_EWorkshopEnumerationTypeRankedByVote", "value":"0" }, + { "name":"k_EWorkshopEnumerationTypeRecent", "value":"1" }, + { "name":"k_EWorkshopEnumerationTypeTrending", "value":"2" }, + { "name":"k_EWorkshopEnumerationTypeFavoritesOfFriends", "value":"3" }, + { "name":"k_EWorkshopEnumerationTypeVotedByFriends", "value":"4" }, + { "name":"k_EWorkshopEnumerationTypeContentByFriends", "value":"5" }, + { "name":"k_EWorkshopEnumerationTypeRecentFromFollowedUsers", "value":"6" } + ] + }, + { + "enumname": "EWorkshopVideoProvider", + "values": [ + { "name":"k_EWorkshopVideoProviderNone", "value":"0" }, + { "name":"k_EWorkshopVideoProviderYoutube", "value":"1" } + ] + }, + { + "enumname": "EUGCReadAction", + "values": [ + { "name":"k_EUGCRead_ContinueReadingUntilFinished", "value":"0" }, + { "name":"k_EUGCRead_ContinueReading", "value":"1" }, + { "name":"k_EUGCRead_Close", "value":"2" } + ] + }, + { + "enumname": "ERemoteStorageLocalFileChange", + "values": [ + { "name":"k_ERemoteStorageLocalFileChange_Invalid", "value":"0" }, + { "name":"k_ERemoteStorageLocalFileChange_FileUpdated", "value":"1" }, + { "name":"k_ERemoteStorageLocalFileChange_FileDeleted", "value":"2" } + ] + }, + { + "enumname": "ERemoteStorageFilePathType", + "values": [ + { "name":"k_ERemoteStorageFilePathType_Invalid", "value":"0" }, + { "name":"k_ERemoteStorageFilePathType_Absolute", "value":"1" }, + { "name":"k_ERemoteStorageFilePathType_APIFilename", "value":"2" } + ] + }, + { + "enumname": "ELeaderboardDataRequest", + "values": [ + { "name":"k_ELeaderboardDataRequestGlobal", "value":"0" }, + { "name":"k_ELeaderboardDataRequestGlobalAroundUser", "value":"1" }, + { "name":"k_ELeaderboardDataRequestFriends", "value":"2" }, + { "name":"k_ELeaderboardDataRequestUsers", "value":"3" } + ] + }, + { + "enumname": "ELeaderboardSortMethod", + "values": [ + { "name":"k_ELeaderboardSortMethodNone", "value":"0" }, + { "name":"k_ELeaderboardSortMethodAscending", "value":"1" }, + { "name":"k_ELeaderboardSortMethodDescending", "value":"2" } + ] + }, + { + "enumname": "ELeaderboardDisplayType", + "values": [ + { "name":"k_ELeaderboardDisplayTypeNone", "value":"0" }, + { "name":"k_ELeaderboardDisplayTypeNumeric", "value":"1" }, + { "name":"k_ELeaderboardDisplayTypeTimeSeconds", "value":"2" }, + { "name":"k_ELeaderboardDisplayTypeTimeMilliSeconds", "value":"3" } + ] + }, + { + "enumname": "ELeaderboardUploadScoreMethod", + "values": [ + { "name":"k_ELeaderboardUploadScoreMethodNone", "value":"0" }, + { "name":"k_ELeaderboardUploadScoreMethodKeepBest", "value":"1" }, + { "name":"k_ELeaderboardUploadScoreMethodForceUpdate", "value":"2" } + ] + }, + { + "enumname": "ERegisterActivationCodeResult", + "values": [ + { "name":"k_ERegisterActivationCodeResultOK", "value":"0" }, + { "name":"k_ERegisterActivationCodeResultFail", "value":"1" }, + { "name":"k_ERegisterActivationCodeResultAlreadyRegistered", "value":"2" }, + { "name":"k_ERegisterActivationCodeResultTimeout", "value":"3" }, + { "name":"k_ERegisterActivationCodeAlreadyOwned", "value":"4" } + ] + }, + { + "enumname": "EP2PSessionError", + "values": [ + { "name":"k_EP2PSessionErrorNone", "value":"0" }, + { "name":"k_EP2PSessionErrorNoRightsToApp", "value":"2" }, + { "name":"k_EP2PSessionErrorTimeout", "value":"4" }, + { "name":"k_EP2PSessionErrorNotRunningApp_DELETED", "value":"1" }, + { "name":"k_EP2PSessionErrorDestinationNotLoggedIn_DELETED", "value":"3" }, + { "name":"k_EP2PSessionErrorMax", "value":"5" } + ] + }, + { + "enumname": "EP2PSend", + "values": [ + { "name":"k_EP2PSendUnreliable", "value":"0" }, + { "name":"k_EP2PSendUnreliableNoDelay", "value":"1" }, + { "name":"k_EP2PSendReliable", "value":"2" }, + { "name":"k_EP2PSendReliableWithBuffering", "value":"3" } + ] + }, + { + "enumname": "ESNetSocketState", + "values": [ + { "name":"k_ESNetSocketStateInvalid", "value":"0" }, + { "name":"k_ESNetSocketStateConnected", "value":"1" }, + { "name":"k_ESNetSocketStateInitiated", "value":"10" }, + { "name":"k_ESNetSocketStateLocalCandidatesFound", "value":"11" }, + { "name":"k_ESNetSocketStateReceivedRemoteCandidates", "value":"12" }, + { "name":"k_ESNetSocketStateChallengeHandshake", "value":"15" }, + { "name":"k_ESNetSocketStateDisconnecting", "value":"21" }, + { "name":"k_ESNetSocketStateLocalDisconnect", "value":"22" }, + { "name":"k_ESNetSocketStateTimeoutDuringConnect", "value":"23" }, + { "name":"k_ESNetSocketStateRemoteEndDisconnected", "value":"24" }, + { "name":"k_ESNetSocketStateConnectionBroken", "value":"25" } + ] + }, + { + "enumname": "ESNetSocketConnectionType", + "values": [ + { "name":"k_ESNetSocketConnectionTypeNotConnected", "value":"0" }, + { "name":"k_ESNetSocketConnectionTypeUDP", "value":"1" }, + { "name":"k_ESNetSocketConnectionTypeUDPRelay", "value":"2" } + ] + }, + { + "enumname": "EVRScreenshotType", + "values": [ + { "name":"k_EVRScreenshotType_None", "value":"0" }, + { "name":"k_EVRScreenshotType_Mono", "value":"1" }, + { "name":"k_EVRScreenshotType_Stereo", "value":"2" }, + { "name":"k_EVRScreenshotType_MonoCubemap", "value":"3" }, + { "name":"k_EVRScreenshotType_MonoPanorama", "value":"4" }, + { "name":"k_EVRScreenshotType_StereoPanorama", "value":"5" } + ] + }, + { + "enumname": "AudioPlayback_Status", + "values": [ + { "name":"AudioPlayback_Undefined", "value":"0" }, + { "name":"AudioPlayback_Playing", "value":"1" }, + { "name":"AudioPlayback_Paused", "value":"2" }, + { "name":"AudioPlayback_Idle", "value":"3" } + ] + }, + { + "enumname": "EHTTPMethod", + "values": [ + { "name":"k_EHTTPMethodInvalid", "value":"0" }, + { "name":"k_EHTTPMethodGET", "value":"1" }, + { "name":"k_EHTTPMethodHEAD", "value":"2" }, + { "name":"k_EHTTPMethodPOST", "value":"3" }, + { "name":"k_EHTTPMethodPUT", "value":"4" }, + { "name":"k_EHTTPMethodDELETE", "value":"5" }, + { "name":"k_EHTTPMethodOPTIONS", "value":"6" }, + { "name":"k_EHTTPMethodPATCH", "value":"7" } + ] + }, + { + "enumname": "EHTTPStatusCode", + "values": [ + { "name":"k_EHTTPStatusCodeInvalid", "value":"0" }, + { "name":"k_EHTTPStatusCode100Continue", "value":"100" }, + { "name":"k_EHTTPStatusCode101SwitchingProtocols", "value":"101" }, + { "name":"k_EHTTPStatusCode200OK", "value":"200" }, + { "name":"k_EHTTPStatusCode201Created", "value":"201" }, + { "name":"k_EHTTPStatusCode202Accepted", "value":"202" }, + { "name":"k_EHTTPStatusCode203NonAuthoritative", "value":"203" }, + { "name":"k_EHTTPStatusCode204NoContent", "value":"204" }, + { "name":"k_EHTTPStatusCode205ResetContent", "value":"205" }, + { "name":"k_EHTTPStatusCode206PartialContent", "value":"206" }, + { "name":"k_EHTTPStatusCode300MultipleChoices", "value":"300" }, + { "name":"k_EHTTPStatusCode301MovedPermanently", "value":"301" }, + { "name":"k_EHTTPStatusCode302Found", "value":"302" }, + { "name":"k_EHTTPStatusCode303SeeOther", "value":"303" }, + { "name":"k_EHTTPStatusCode304NotModified", "value":"304" }, + { "name":"k_EHTTPStatusCode305UseProxy", "value":"305" }, + { "name":"k_EHTTPStatusCode307TemporaryRedirect", "value":"307" }, + { "name":"k_EHTTPStatusCode400BadRequest", "value":"400" }, + { "name":"k_EHTTPStatusCode401Unauthorized", "value":"401" }, + { "name":"k_EHTTPStatusCode402PaymentRequired", "value":"402" }, + { "name":"k_EHTTPStatusCode403Forbidden", "value":"403" }, + { "name":"k_EHTTPStatusCode404NotFound", "value":"404" }, + { "name":"k_EHTTPStatusCode405MethodNotAllowed", "value":"405" }, + { "name":"k_EHTTPStatusCode406NotAcceptable", "value":"406" }, + { "name":"k_EHTTPStatusCode407ProxyAuthRequired", "value":"407" }, + { "name":"k_EHTTPStatusCode408RequestTimeout", "value":"408" }, + { "name":"k_EHTTPStatusCode409Conflict", "value":"409" }, + { "name":"k_EHTTPStatusCode410Gone", "value":"410" }, + { "name":"k_EHTTPStatusCode411LengthRequired", "value":"411" }, + { "name":"k_EHTTPStatusCode412PreconditionFailed", "value":"412" }, + { "name":"k_EHTTPStatusCode413RequestEntityTooLarge", "value":"413" }, + { "name":"k_EHTTPStatusCode414RequestURITooLong", "value":"414" }, + { "name":"k_EHTTPStatusCode415UnsupportedMediaType", "value":"415" }, + { "name":"k_EHTTPStatusCode416RequestedRangeNotSatisfiable", "value":"416" }, + { "name":"k_EHTTPStatusCode417ExpectationFailed", "value":"417" }, + { "name":"k_EHTTPStatusCode4xxUnknown", "value":"418" }, + { "name":"k_EHTTPStatusCode429TooManyRequests", "value":"429" }, + { "name":"k_EHTTPStatusCode444ConnectionClosed", "value":"444" }, + { "name":"k_EHTTPStatusCode500InternalServerError", "value":"500" }, + { "name":"k_EHTTPStatusCode501NotImplemented", "value":"501" }, + { "name":"k_EHTTPStatusCode502BadGateway", "value":"502" }, + { "name":"k_EHTTPStatusCode503ServiceUnavailable", "value":"503" }, + { "name":"k_EHTTPStatusCode504GatewayTimeout", "value":"504" }, + { "name":"k_EHTTPStatusCode505HTTPVersionNotSupported", "value":"505" }, + { "name":"k_EHTTPStatusCode5xxUnknown", "value":"599" } + ] + }, + { + "enumname": "EInputSourceMode", + "values": [ + { "name":"k_EInputSourceMode_None", "value":"0" }, + { "name":"k_EInputSourceMode_Dpad", "value":"1" }, + { "name":"k_EInputSourceMode_Buttons", "value":"2" }, + { "name":"k_EInputSourceMode_FourButtons", "value":"3" }, + { "name":"k_EInputSourceMode_AbsoluteMouse", "value":"4" }, + { "name":"k_EInputSourceMode_RelativeMouse", "value":"5" }, + { "name":"k_EInputSourceMode_JoystickMove", "value":"6" }, + { "name":"k_EInputSourceMode_JoystickMouse", "value":"7" }, + { "name":"k_EInputSourceMode_JoystickCamera", "value":"8" }, + { "name":"k_EInputSourceMode_ScrollWheel", "value":"9" }, + { "name":"k_EInputSourceMode_Trigger", "value":"10" }, + { "name":"k_EInputSourceMode_TouchMenu", "value":"11" }, + { "name":"k_EInputSourceMode_MouseJoystick", "value":"12" }, + { "name":"k_EInputSourceMode_MouseRegion", "value":"13" }, + { "name":"k_EInputSourceMode_RadialMenu", "value":"14" }, + { "name":"k_EInputSourceMode_SingleButton", "value":"15" }, + { "name":"k_EInputSourceMode_Switches", "value":"16" } + ] + }, + { + "enumname": "EInputActionOrigin", + "values": [ + { "name":"k_EInputActionOrigin_None", "value":"0" }, + { "name":"k_EInputActionOrigin_SteamController_A", "value":"1" }, + { "name":"k_EInputActionOrigin_SteamController_B", "value":"2" }, + { "name":"k_EInputActionOrigin_SteamController_X", "value":"3" }, + { "name":"k_EInputActionOrigin_SteamController_Y", "value":"4" }, + { "name":"k_EInputActionOrigin_SteamController_LeftBumper", "value":"5" }, + { "name":"k_EInputActionOrigin_SteamController_RightBumper", "value":"6" }, + { "name":"k_EInputActionOrigin_SteamController_LeftGrip", "value":"7" }, + { "name":"k_EInputActionOrigin_SteamController_RightGrip", "value":"8" }, + { "name":"k_EInputActionOrigin_SteamController_Start", "value":"9" }, + { "name":"k_EInputActionOrigin_SteamController_Back", "value":"10" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_Touch", "value":"11" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_Swipe", "value":"12" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_Click", "value":"13" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_DPadNorth", "value":"14" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_DPadSouth", "value":"15" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_DPadWest", "value":"16" }, + { "name":"k_EInputActionOrigin_SteamController_LeftPad_DPadEast", "value":"17" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_Touch", "value":"18" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_Swipe", "value":"19" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_Click", "value":"20" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_DPadNorth", "value":"21" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_DPadSouth", "value":"22" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_DPadWest", "value":"23" }, + { "name":"k_EInputActionOrigin_SteamController_RightPad_DPadEast", "value":"24" }, + { "name":"k_EInputActionOrigin_SteamController_LeftTrigger_Pull", "value":"25" }, + { "name":"k_EInputActionOrigin_SteamController_LeftTrigger_Click", "value":"26" }, + { "name":"k_EInputActionOrigin_SteamController_RightTrigger_Pull", "value":"27" }, + { "name":"k_EInputActionOrigin_SteamController_RightTrigger_Click", "value":"28" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_Move", "value":"29" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_Click", "value":"30" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_DPadNorth", "value":"31" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_DPadSouth", "value":"32" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_DPadWest", "value":"33" }, + { "name":"k_EInputActionOrigin_SteamController_LeftStick_DPadEast", "value":"34" }, + { "name":"k_EInputActionOrigin_SteamController_Gyro_Move", "value":"35" }, + { "name":"k_EInputActionOrigin_SteamController_Gyro_Pitch", "value":"36" }, + { "name":"k_EInputActionOrigin_SteamController_Gyro_Yaw", "value":"37" }, + { "name":"k_EInputActionOrigin_SteamController_Gyro_Roll", "value":"38" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved0", "value":"39" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved1", "value":"40" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved2", "value":"41" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved3", "value":"42" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved4", "value":"43" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved5", "value":"44" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved6", "value":"45" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved7", "value":"46" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved8", "value":"47" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved9", "value":"48" }, + { "name":"k_EInputActionOrigin_SteamController_Reserved10", "value":"49" }, + { "name":"k_EInputActionOrigin_PS4_X", "value":"50" }, + { "name":"k_EInputActionOrigin_PS4_Circle", "value":"51" }, + { "name":"k_EInputActionOrigin_PS4_Triangle", "value":"52" }, + { "name":"k_EInputActionOrigin_PS4_Square", "value":"53" }, + { "name":"k_EInputActionOrigin_PS4_LeftBumper", "value":"54" }, + { "name":"k_EInputActionOrigin_PS4_RightBumper", "value":"55" }, + { "name":"k_EInputActionOrigin_PS4_Options", "value":"56" }, + { "name":"k_EInputActionOrigin_PS4_Share", "value":"57" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_Touch", "value":"58" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_Swipe", "value":"59" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_Click", "value":"60" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_DPadNorth", "value":"61" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_DPadSouth", "value":"62" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_DPadWest", "value":"63" }, + { "name":"k_EInputActionOrigin_PS4_LeftPad_DPadEast", "value":"64" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_Touch", "value":"65" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_Swipe", "value":"66" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_Click", "value":"67" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_DPadNorth", "value":"68" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_DPadSouth", "value":"69" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_DPadWest", "value":"70" }, + { "name":"k_EInputActionOrigin_PS4_RightPad_DPadEast", "value":"71" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_Touch", "value":"72" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_Swipe", "value":"73" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_Click", "value":"74" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_DPadNorth", "value":"75" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_DPadSouth", "value":"76" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_DPadWest", "value":"77" }, + { "name":"k_EInputActionOrigin_PS4_CenterPad_DPadEast", "value":"78" }, + { "name":"k_EInputActionOrigin_PS4_LeftTrigger_Pull", "value":"79" }, + { "name":"k_EInputActionOrigin_PS4_LeftTrigger_Click", "value":"80" }, + { "name":"k_EInputActionOrigin_PS4_RightTrigger_Pull", "value":"81" }, + { "name":"k_EInputActionOrigin_PS4_RightTrigger_Click", "value":"82" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_Move", "value":"83" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_Click", "value":"84" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_DPadNorth", "value":"85" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_DPadSouth", "value":"86" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_DPadWest", "value":"87" }, + { "name":"k_EInputActionOrigin_PS4_LeftStick_DPadEast", "value":"88" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_Move", "value":"89" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_Click", "value":"90" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_DPadNorth", "value":"91" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_DPadSouth", "value":"92" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_DPadWest", "value":"93" }, + { "name":"k_EInputActionOrigin_PS4_RightStick_DPadEast", "value":"94" }, + { "name":"k_EInputActionOrigin_PS4_DPad_North", "value":"95" }, + { "name":"k_EInputActionOrigin_PS4_DPad_South", "value":"96" }, + { "name":"k_EInputActionOrigin_PS4_DPad_West", "value":"97" }, + { "name":"k_EInputActionOrigin_PS4_DPad_East", "value":"98" }, + { "name":"k_EInputActionOrigin_PS4_Gyro_Move", "value":"99" }, + { "name":"k_EInputActionOrigin_PS4_Gyro_Pitch", "value":"100" }, + { "name":"k_EInputActionOrigin_PS4_Gyro_Yaw", "value":"101" }, + { "name":"k_EInputActionOrigin_PS4_Gyro_Roll", "value":"102" }, + { "name":"k_EInputActionOrigin_PS4_DPad_Move", "value":"103" }, + { "name":"k_EInputActionOrigin_PS4_Reserved1", "value":"104" }, + { "name":"k_EInputActionOrigin_PS4_Reserved2", "value":"105" }, + { "name":"k_EInputActionOrigin_PS4_Reserved3", "value":"106" }, + { "name":"k_EInputActionOrigin_PS4_Reserved4", "value":"107" }, + { "name":"k_EInputActionOrigin_PS4_Reserved5", "value":"108" }, + { "name":"k_EInputActionOrigin_PS4_Reserved6", "value":"109" }, + { "name":"k_EInputActionOrigin_PS4_Reserved7", "value":"110" }, + { "name":"k_EInputActionOrigin_PS4_Reserved8", "value":"111" }, + { "name":"k_EInputActionOrigin_PS4_Reserved9", "value":"112" }, + { "name":"k_EInputActionOrigin_PS4_Reserved10", "value":"113" }, + { "name":"k_EInputActionOrigin_XBoxOne_A", "value":"114" }, + { "name":"k_EInputActionOrigin_XBoxOne_B", "value":"115" }, + { "name":"k_EInputActionOrigin_XBoxOne_X", "value":"116" }, + { "name":"k_EInputActionOrigin_XBoxOne_Y", "value":"117" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftBumper", "value":"118" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightBumper", "value":"119" }, + { "name":"k_EInputActionOrigin_XBoxOne_Menu", "value":"120" }, + { "name":"k_EInputActionOrigin_XBoxOne_View", "value":"121" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftTrigger_Pull", "value":"122" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftTrigger_Click", "value":"123" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightTrigger_Pull", "value":"124" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightTrigger_Click", "value":"125" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_Move", "value":"126" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_Click", "value":"127" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_DPadNorth", "value":"128" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_DPadSouth", "value":"129" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_DPadWest", "value":"130" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftStick_DPadEast", "value":"131" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_Move", "value":"132" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_Click", "value":"133" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_DPadNorth", "value":"134" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_DPadSouth", "value":"135" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_DPadWest", "value":"136" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightStick_DPadEast", "value":"137" }, + { "name":"k_EInputActionOrigin_XBoxOne_DPad_North", "value":"138" }, + { "name":"k_EInputActionOrigin_XBoxOne_DPad_South", "value":"139" }, + { "name":"k_EInputActionOrigin_XBoxOne_DPad_West", "value":"140" }, + { "name":"k_EInputActionOrigin_XBoxOne_DPad_East", "value":"141" }, + { "name":"k_EInputActionOrigin_XBoxOne_DPad_Move", "value":"142" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftGrip_Lower", "value":"143" }, + { "name":"k_EInputActionOrigin_XBoxOne_LeftGrip_Upper", "value":"144" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightGrip_Lower", "value":"145" }, + { "name":"k_EInputActionOrigin_XBoxOne_RightGrip_Upper", "value":"146" }, + { "name":"k_EInputActionOrigin_XBoxOne_Share", "value":"147" }, + { "name":"k_EInputActionOrigin_XBoxOne_Reserved6", "value":"148" }, + { "name":"k_EInputActionOrigin_XBoxOne_Reserved7", "value":"149" }, + { "name":"k_EInputActionOrigin_XBoxOne_Reserved8", "value":"150" }, + { "name":"k_EInputActionOrigin_XBoxOne_Reserved9", "value":"151" }, + { "name":"k_EInputActionOrigin_XBoxOne_Reserved10", "value":"152" }, + { "name":"k_EInputActionOrigin_XBox360_A", "value":"153" }, + { "name":"k_EInputActionOrigin_XBox360_B", "value":"154" }, + { "name":"k_EInputActionOrigin_XBox360_X", "value":"155" }, + { "name":"k_EInputActionOrigin_XBox360_Y", "value":"156" }, + { "name":"k_EInputActionOrigin_XBox360_LeftBumper", "value":"157" }, + { "name":"k_EInputActionOrigin_XBox360_RightBumper", "value":"158" }, + { "name":"k_EInputActionOrigin_XBox360_Start", "value":"159" }, + { "name":"k_EInputActionOrigin_XBox360_Back", "value":"160" }, + { "name":"k_EInputActionOrigin_XBox360_LeftTrigger_Pull", "value":"161" }, + { "name":"k_EInputActionOrigin_XBox360_LeftTrigger_Click", "value":"162" }, + { "name":"k_EInputActionOrigin_XBox360_RightTrigger_Pull", "value":"163" }, + { "name":"k_EInputActionOrigin_XBox360_RightTrigger_Click", "value":"164" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_Move", "value":"165" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_Click", "value":"166" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_DPadNorth", "value":"167" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_DPadSouth", "value":"168" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_DPadWest", "value":"169" }, + { "name":"k_EInputActionOrigin_XBox360_LeftStick_DPadEast", "value":"170" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_Move", "value":"171" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_Click", "value":"172" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_DPadNorth", "value":"173" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_DPadSouth", "value":"174" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_DPadWest", "value":"175" }, + { "name":"k_EInputActionOrigin_XBox360_RightStick_DPadEast", "value":"176" }, + { "name":"k_EInputActionOrigin_XBox360_DPad_North", "value":"177" }, + { "name":"k_EInputActionOrigin_XBox360_DPad_South", "value":"178" }, + { "name":"k_EInputActionOrigin_XBox360_DPad_West", "value":"179" }, + { "name":"k_EInputActionOrigin_XBox360_DPad_East", "value":"180" }, + { "name":"k_EInputActionOrigin_XBox360_DPad_Move", "value":"181" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved1", "value":"182" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved2", "value":"183" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved3", "value":"184" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved4", "value":"185" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved5", "value":"186" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved6", "value":"187" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved7", "value":"188" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved8", "value":"189" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved9", "value":"190" }, + { "name":"k_EInputActionOrigin_XBox360_Reserved10", "value":"191" }, + { "name":"k_EInputActionOrigin_Switch_A", "value":"192" }, + { "name":"k_EInputActionOrigin_Switch_B", "value":"193" }, + { "name":"k_EInputActionOrigin_Switch_X", "value":"194" }, + { "name":"k_EInputActionOrigin_Switch_Y", "value":"195" }, + { "name":"k_EInputActionOrigin_Switch_LeftBumper", "value":"196" }, + { "name":"k_EInputActionOrigin_Switch_RightBumper", "value":"197" }, + { "name":"k_EInputActionOrigin_Switch_Plus", "value":"198" }, + { "name":"k_EInputActionOrigin_Switch_Minus", "value":"199" }, + { "name":"k_EInputActionOrigin_Switch_Capture", "value":"200" }, + { "name":"k_EInputActionOrigin_Switch_LeftTrigger_Pull", "value":"201" }, + { "name":"k_EInputActionOrigin_Switch_LeftTrigger_Click", "value":"202" }, + { "name":"k_EInputActionOrigin_Switch_RightTrigger_Pull", "value":"203" }, + { "name":"k_EInputActionOrigin_Switch_RightTrigger_Click", "value":"204" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_Move", "value":"205" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_Click", "value":"206" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_DPadNorth", "value":"207" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_DPadSouth", "value":"208" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_DPadWest", "value":"209" }, + { "name":"k_EInputActionOrigin_Switch_LeftStick_DPadEast", "value":"210" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_Move", "value":"211" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_Click", "value":"212" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_DPadNorth", "value":"213" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_DPadSouth", "value":"214" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_DPadWest", "value":"215" }, + { "name":"k_EInputActionOrigin_Switch_RightStick_DPadEast", "value":"216" }, + { "name":"k_EInputActionOrigin_Switch_DPad_North", "value":"217" }, + { "name":"k_EInputActionOrigin_Switch_DPad_South", "value":"218" }, + { "name":"k_EInputActionOrigin_Switch_DPad_West", "value":"219" }, + { "name":"k_EInputActionOrigin_Switch_DPad_East", "value":"220" }, + { "name":"k_EInputActionOrigin_Switch_ProGyro_Move", "value":"221" }, + { "name":"k_EInputActionOrigin_Switch_ProGyro_Pitch", "value":"222" }, + { "name":"k_EInputActionOrigin_Switch_ProGyro_Yaw", "value":"223" }, + { "name":"k_EInputActionOrigin_Switch_ProGyro_Roll", "value":"224" }, + { "name":"k_EInputActionOrigin_Switch_DPad_Move", "value":"225" }, + { "name":"k_EInputActionOrigin_Switch_Reserved1", "value":"226" }, + { "name":"k_EInputActionOrigin_Switch_Reserved2", "value":"227" }, + { "name":"k_EInputActionOrigin_Switch_Reserved3", "value":"228" }, + { "name":"k_EInputActionOrigin_Switch_Reserved4", "value":"229" }, + { "name":"k_EInputActionOrigin_Switch_Reserved5", "value":"230" }, + { "name":"k_EInputActionOrigin_Switch_Reserved6", "value":"231" }, + { "name":"k_EInputActionOrigin_Switch_Reserved7", "value":"232" }, + { "name":"k_EInputActionOrigin_Switch_Reserved8", "value":"233" }, + { "name":"k_EInputActionOrigin_Switch_Reserved9", "value":"234" }, + { "name":"k_EInputActionOrigin_Switch_Reserved10", "value":"235" }, + { "name":"k_EInputActionOrigin_Switch_RightGyro_Move", "value":"236" }, + { "name":"k_EInputActionOrigin_Switch_RightGyro_Pitch", "value":"237" }, + { "name":"k_EInputActionOrigin_Switch_RightGyro_Yaw", "value":"238" }, + { "name":"k_EInputActionOrigin_Switch_RightGyro_Roll", "value":"239" }, + { "name":"k_EInputActionOrigin_Switch_LeftGyro_Move", "value":"240" }, + { "name":"k_EInputActionOrigin_Switch_LeftGyro_Pitch", "value":"241" }, + { "name":"k_EInputActionOrigin_Switch_LeftGyro_Yaw", "value":"242" }, + { "name":"k_EInputActionOrigin_Switch_LeftGyro_Roll", "value":"243" }, + { "name":"k_EInputActionOrigin_Switch_LeftGrip_Lower", "value":"244" }, + { "name":"k_EInputActionOrigin_Switch_LeftGrip_Upper", "value":"245" }, + { "name":"k_EInputActionOrigin_Switch_RightGrip_Lower", "value":"246" }, + { "name":"k_EInputActionOrigin_Switch_RightGrip_Upper", "value":"247" }, + { "name":"k_EInputActionOrigin_Switch_Reserved11", "value":"248" }, + { "name":"k_EInputActionOrigin_Switch_Reserved12", "value":"249" }, + { "name":"k_EInputActionOrigin_Switch_Reserved13", "value":"250" }, + { "name":"k_EInputActionOrigin_Switch_Reserved14", "value":"251" }, + { "name":"k_EInputActionOrigin_Switch_Reserved15", "value":"252" }, + { "name":"k_EInputActionOrigin_Switch_Reserved16", "value":"253" }, + { "name":"k_EInputActionOrigin_Switch_Reserved17", "value":"254" }, + { "name":"k_EInputActionOrigin_Switch_Reserved18", "value":"255" }, + { "name":"k_EInputActionOrigin_Switch_Reserved19", "value":"256" }, + { "name":"k_EInputActionOrigin_Switch_Reserved20", "value":"257" }, + { "name":"k_EInputActionOrigin_PS5_X", "value":"258" }, + { "name":"k_EInputActionOrigin_PS5_Circle", "value":"259" }, + { "name":"k_EInputActionOrigin_PS5_Triangle", "value":"260" }, + { "name":"k_EInputActionOrigin_PS5_Square", "value":"261" }, + { "name":"k_EInputActionOrigin_PS5_LeftBumper", "value":"262" }, + { "name":"k_EInputActionOrigin_PS5_RightBumper", "value":"263" }, + { "name":"k_EInputActionOrigin_PS5_Option", "value":"264" }, + { "name":"k_EInputActionOrigin_PS5_Create", "value":"265" }, + { "name":"k_EInputActionOrigin_PS5_Mute", "value":"266" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Touch", "value":"267" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Swipe", "value":"268" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Click", "value":"269" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadNorth", "value":"270" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadSouth", "value":"271" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadWest", "value":"272" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadEast", "value":"273" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Touch", "value":"274" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Swipe", "value":"275" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Click", "value":"276" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadNorth", "value":"277" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadSouth", "value":"278" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadWest", "value":"279" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadEast", "value":"280" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Touch", "value":"281" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Swipe", "value":"282" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Click", "value":"283" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadNorth", "value":"284" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadSouth", "value":"285" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadWest", "value":"286" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadEast", "value":"287" }, + { "name":"k_EInputActionOrigin_PS5_LeftTrigger_Pull", "value":"288" }, + { "name":"k_EInputActionOrigin_PS5_LeftTrigger_Click", "value":"289" }, + { "name":"k_EInputActionOrigin_PS5_RightTrigger_Pull", "value":"290" }, + { "name":"k_EInputActionOrigin_PS5_RightTrigger_Click", "value":"291" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_Move", "value":"292" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_Click", "value":"293" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadNorth", "value":"294" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadSouth", "value":"295" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadWest", "value":"296" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadEast", "value":"297" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_Move", "value":"298" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_Click", "value":"299" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadNorth", "value":"300" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadSouth", "value":"301" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadWest", "value":"302" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadEast", "value":"303" }, + { "name":"k_EInputActionOrigin_PS5_DPad_North", "value":"304" }, + { "name":"k_EInputActionOrigin_PS5_DPad_South", "value":"305" }, + { "name":"k_EInputActionOrigin_PS5_DPad_West", "value":"306" }, + { "name":"k_EInputActionOrigin_PS5_DPad_East", "value":"307" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Move", "value":"308" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Pitch", "value":"309" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Yaw", "value":"310" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Roll", "value":"311" }, + { "name":"k_EInputActionOrigin_PS5_DPad_Move", "value":"312" }, + { "name":"k_EInputActionOrigin_PS5_Reserved1", "value":"313" }, + { "name":"k_EInputActionOrigin_PS5_Reserved2", "value":"314" }, + { "name":"k_EInputActionOrigin_PS5_Reserved3", "value":"315" }, + { "name":"k_EInputActionOrigin_PS5_Reserved4", "value":"316" }, + { "name":"k_EInputActionOrigin_PS5_Reserved5", "value":"317" }, + { "name":"k_EInputActionOrigin_PS5_Reserved6", "value":"318" }, + { "name":"k_EInputActionOrigin_PS5_Reserved7", "value":"319" }, + { "name":"k_EInputActionOrigin_PS5_Reserved8", "value":"320" }, + { "name":"k_EInputActionOrigin_PS5_Reserved9", "value":"321" }, + { "name":"k_EInputActionOrigin_PS5_Reserved10", "value":"322" }, + { "name":"k_EInputActionOrigin_PS5_Reserved11", "value":"323" }, + { "name":"k_EInputActionOrigin_PS5_Reserved12", "value":"324" }, + { "name":"k_EInputActionOrigin_PS5_Reserved13", "value":"325" }, + { "name":"k_EInputActionOrigin_PS5_Reserved14", "value":"326" }, + { "name":"k_EInputActionOrigin_PS5_Reserved15", "value":"327" }, + { "name":"k_EInputActionOrigin_PS5_Reserved16", "value":"328" }, + { "name":"k_EInputActionOrigin_PS5_Reserved17", "value":"329" }, + { "name":"k_EInputActionOrigin_PS5_Reserved18", "value":"330" }, + { "name":"k_EInputActionOrigin_PS5_Reserved19", "value":"331" }, + { "name":"k_EInputActionOrigin_PS5_Reserved20", "value":"332" }, + { "name":"k_EInputActionOrigin_SteamDeck_A", "value":"333" }, + { "name":"k_EInputActionOrigin_SteamDeck_B", "value":"334" }, + { "name":"k_EInputActionOrigin_SteamDeck_X", "value":"335" }, + { "name":"k_EInputActionOrigin_SteamDeck_Y", "value":"336" }, + { "name":"k_EInputActionOrigin_SteamDeck_L1", "value":"337" }, + { "name":"k_EInputActionOrigin_SteamDeck_R1", "value":"338" }, + { "name":"k_EInputActionOrigin_SteamDeck_Menu", "value":"339" }, + { "name":"k_EInputActionOrigin_SteamDeck_View", "value":"340" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_Touch", "value":"341" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_Swipe", "value":"342" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_Click", "value":"343" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_DPadNorth", "value":"344" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_DPadSouth", "value":"345" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_DPadWest", "value":"346" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftPad_DPadEast", "value":"347" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_Touch", "value":"348" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_Swipe", "value":"349" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_Click", "value":"350" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_DPadNorth", "value":"351" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_DPadSouth", "value":"352" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_DPadWest", "value":"353" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightPad_DPadEast", "value":"354" }, + { "name":"k_EInputActionOrigin_SteamDeck_L2_SoftPull", "value":"355" }, + { "name":"k_EInputActionOrigin_SteamDeck_L2", "value":"356" }, + { "name":"k_EInputActionOrigin_SteamDeck_R2_SoftPull", "value":"357" }, + { "name":"k_EInputActionOrigin_SteamDeck_R2", "value":"358" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_Move", "value":"359" }, + { "name":"k_EInputActionOrigin_SteamDeck_L3", "value":"360" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_DPadNorth", "value":"361" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_DPadSouth", "value":"362" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_DPadWest", "value":"363" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_DPadEast", "value":"364" }, + { "name":"k_EInputActionOrigin_SteamDeck_LeftStick_Touch", "value":"365" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_Move", "value":"366" }, + { "name":"k_EInputActionOrigin_SteamDeck_R3", "value":"367" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_DPadNorth", "value":"368" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_DPadSouth", "value":"369" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_DPadWest", "value":"370" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_DPadEast", "value":"371" }, + { "name":"k_EInputActionOrigin_SteamDeck_RightStick_Touch", "value":"372" }, + { "name":"k_EInputActionOrigin_SteamDeck_L4", "value":"373" }, + { "name":"k_EInputActionOrigin_SteamDeck_R4", "value":"374" }, + { "name":"k_EInputActionOrigin_SteamDeck_L5", "value":"375" }, + { "name":"k_EInputActionOrigin_SteamDeck_R5", "value":"376" }, + { "name":"k_EInputActionOrigin_SteamDeck_DPad_Move", "value":"377" }, + { "name":"k_EInputActionOrigin_SteamDeck_DPad_North", "value":"378" }, + { "name":"k_EInputActionOrigin_SteamDeck_DPad_South", "value":"379" }, + { "name":"k_EInputActionOrigin_SteamDeck_DPad_West", "value":"380" }, + { "name":"k_EInputActionOrigin_SteamDeck_DPad_East", "value":"381" }, + { "name":"k_EInputActionOrigin_SteamDeck_Gyro_Move", "value":"382" }, + { "name":"k_EInputActionOrigin_SteamDeck_Gyro_Pitch", "value":"383" }, + { "name":"k_EInputActionOrigin_SteamDeck_Gyro_Yaw", "value":"384" }, + { "name":"k_EInputActionOrigin_SteamDeck_Gyro_Roll", "value":"385" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved1", "value":"386" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved2", "value":"387" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved3", "value":"388" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved4", "value":"389" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved5", "value":"390" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved6", "value":"391" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved7", "value":"392" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved8", "value":"393" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved9", "value":"394" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved10", "value":"395" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved11", "value":"396" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved12", "value":"397" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved13", "value":"398" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved14", "value":"399" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved15", "value":"400" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved16", "value":"401" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved17", "value":"402" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved18", "value":"403" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved19", "value":"404" }, + { "name":"k_EInputActionOrigin_SteamDeck_Reserved20", "value":"405" }, + { "name":"k_EInputActionOrigin_Count", "value":"406" }, + { "name":"k_EInputActionOrigin_MaximumPossibleValue", "value":"32767" } + ] + }, + { + "enumname": "EXboxOrigin", + "values": [ + { "name":"k_EXboxOrigin_A", "value":"0" }, + { "name":"k_EXboxOrigin_B", "value":"1" }, + { "name":"k_EXboxOrigin_X", "value":"2" }, + { "name":"k_EXboxOrigin_Y", "value":"3" }, + { "name":"k_EXboxOrigin_LeftBumper", "value":"4" }, + { "name":"k_EXboxOrigin_RightBumper", "value":"5" }, + { "name":"k_EXboxOrigin_Menu", "value":"6" }, + { "name":"k_EXboxOrigin_View", "value":"7" }, + { "name":"k_EXboxOrigin_LeftTrigger_Pull", "value":"8" }, + { "name":"k_EXboxOrigin_LeftTrigger_Click", "value":"9" }, + { "name":"k_EXboxOrigin_RightTrigger_Pull", "value":"10" }, + { "name":"k_EXboxOrigin_RightTrigger_Click", "value":"11" }, + { "name":"k_EXboxOrigin_LeftStick_Move", "value":"12" }, + { "name":"k_EXboxOrigin_LeftStick_Click", "value":"13" }, + { "name":"k_EXboxOrigin_LeftStick_DPadNorth", "value":"14" }, + { "name":"k_EXboxOrigin_LeftStick_DPadSouth", "value":"15" }, + { "name":"k_EXboxOrigin_LeftStick_DPadWest", "value":"16" }, + { "name":"k_EXboxOrigin_LeftStick_DPadEast", "value":"17" }, + { "name":"k_EXboxOrigin_RightStick_Move", "value":"18" }, + { "name":"k_EXboxOrigin_RightStick_Click", "value":"19" }, + { "name":"k_EXboxOrigin_RightStick_DPadNorth", "value":"20" }, + { "name":"k_EXboxOrigin_RightStick_DPadSouth", "value":"21" }, + { "name":"k_EXboxOrigin_RightStick_DPadWest", "value":"22" }, + { "name":"k_EXboxOrigin_RightStick_DPadEast", "value":"23" }, + { "name":"k_EXboxOrigin_DPad_North", "value":"24" }, + { "name":"k_EXboxOrigin_DPad_South", "value":"25" }, + { "name":"k_EXboxOrigin_DPad_West", "value":"26" }, + { "name":"k_EXboxOrigin_DPad_East", "value":"27" }, + { "name":"k_EXboxOrigin_Count", "value":"28" } + ] + }, + { + "enumname": "ESteamControllerPad", + "values": [ + { "name":"k_ESteamControllerPad_Left", "value":"0" }, + { "name":"k_ESteamControllerPad_Right", "value":"1" } + ] + }, + { + "enumname": "EControllerHapticLocation", + "values": [ + { "name":"k_EControllerHapticLocation_Left", "value":"1" }, + { "name":"k_EControllerHapticLocation_Right", "value":"2" }, + { "name":"k_EControllerHapticLocation_Both", "value":"3" } + ] + }, + { + "enumname": "EControllerHapticType", + "values": [ + { "name":"k_EControllerHapticType_Off", "value":"0" }, + { "name":"k_EControllerHapticType_Tick", "value":"1" }, + { "name":"k_EControllerHapticType_Click", "value":"2" } + ] + }, + { + "enumname": "ESteamInputType", + "values": [ + { "name":"k_ESteamInputType_Unknown", "value":"0" }, + { "name":"k_ESteamInputType_SteamController", "value":"1" }, + { "name":"k_ESteamInputType_XBox360Controller", "value":"2" }, + { "name":"k_ESteamInputType_XBoxOneController", "value":"3" }, + { "name":"k_ESteamInputType_GenericGamepad", "value":"4" }, + { "name":"k_ESteamInputType_PS4Controller", "value":"5" }, + { "name":"k_ESteamInputType_AppleMFiController", "value":"6" }, + { "name":"k_ESteamInputType_AndroidController", "value":"7" }, + { "name":"k_ESteamInputType_SwitchJoyConPair", "value":"8" }, + { "name":"k_ESteamInputType_SwitchJoyConSingle", "value":"9" }, + { "name":"k_ESteamInputType_SwitchProController", "value":"10" }, + { "name":"k_ESteamInputType_MobileTouch", "value":"11" }, + { "name":"k_ESteamInputType_PS3Controller", "value":"12" }, + { "name":"k_ESteamInputType_PS5Controller", "value":"13" }, + { "name":"k_ESteamInputType_SteamDeckController", "value":"14" }, + { "name":"k_ESteamInputType_Count", "value":"15" }, + { "name":"k_ESteamInputType_MaximumPossibleValue", "value":"255" } + ] + }, + { + "enumname": "ESteamInputConfigurationEnableType", + "values": [ + { "name":"k_ESteamInputConfigurationEnableType_None", "value":"0" }, + { "name":"k_ESteamInputConfigurationEnableType_Playstation", "value":"1" }, + { "name":"k_ESteamInputConfigurationEnableType_Xbox", "value":"2" }, + { "name":"k_ESteamInputConfigurationEnableType_Generic", "value":"4" }, + { "name":"k_ESteamInputConfigurationEnableType_Switch", "value":"8" } + ] + }, + { + "enumname": "ESteamInputLEDFlag", + "values": [ + { "name":"k_ESteamInputLEDFlag_SetColor", "value":"0" }, + { "name":"k_ESteamInputLEDFlag_RestoreUserDefault", "value":"1" } + ] + }, + { + "enumname": "ESteamInputGlyphSize", + "values": [ + { "name":"k_ESteamInputGlyphSize_Small", "value":"0" }, + { "name":"k_ESteamInputGlyphSize_Medium", "value":"1" }, + { "name":"k_ESteamInputGlyphSize_Large", "value":"2" }, + { "name":"k_ESteamInputGlyphSize_Count", "value":"3" } + ] + }, + { + "enumname": "ESteamInputGlyphStyle", + "values": [ + { "name":"ESteamInputGlyphStyle_Knockout", "value":"0" }, + { "name":"ESteamInputGlyphStyle_Light", "value":"1" }, + { "name":"ESteamInputGlyphStyle_Dark", "value":"2" }, + { "name":"ESteamInputGlyphStyle_NeutralColorABXY", "value":"16" }, + { "name":"ESteamInputGlyphStyle_SolidABXY", "value":"32" } + ] + }, + { + "enumname": "ESteamInputActionEventType", + "values": [ + { "name":"ESteamInputActionEventType_DigitalAction", "value":"0" }, + { "name":"ESteamInputActionEventType_AnalogAction", "value":"1" } + ] + }, + { + "enumname": "EControllerActionOrigin", + "values": [ + { "name":"k_EControllerActionOrigin_None", "value":"0" }, + { "name":"k_EControllerActionOrigin_A", "value":"1" }, + { "name":"k_EControllerActionOrigin_B", "value":"2" }, + { "name":"k_EControllerActionOrigin_X", "value":"3" }, + { "name":"k_EControllerActionOrigin_Y", "value":"4" }, + { "name":"k_EControllerActionOrigin_LeftBumper", "value":"5" }, + { "name":"k_EControllerActionOrigin_RightBumper", "value":"6" }, + { "name":"k_EControllerActionOrigin_LeftGrip", "value":"7" }, + { "name":"k_EControllerActionOrigin_RightGrip", "value":"8" }, + { "name":"k_EControllerActionOrigin_Start", "value":"9" }, + { "name":"k_EControllerActionOrigin_Back", "value":"10" }, + { "name":"k_EControllerActionOrigin_LeftPad_Touch", "value":"11" }, + { "name":"k_EControllerActionOrigin_LeftPad_Swipe", "value":"12" }, + { "name":"k_EControllerActionOrigin_LeftPad_Click", "value":"13" }, + { "name":"k_EControllerActionOrigin_LeftPad_DPadNorth", "value":"14" }, + { "name":"k_EControllerActionOrigin_LeftPad_DPadSouth", "value":"15" }, + { "name":"k_EControllerActionOrigin_LeftPad_DPadWest", "value":"16" }, + { "name":"k_EControllerActionOrigin_LeftPad_DPadEast", "value":"17" }, + { "name":"k_EControllerActionOrigin_RightPad_Touch", "value":"18" }, + { "name":"k_EControllerActionOrigin_RightPad_Swipe", "value":"19" }, + { "name":"k_EControllerActionOrigin_RightPad_Click", "value":"20" }, + { "name":"k_EControllerActionOrigin_RightPad_DPadNorth", "value":"21" }, + { "name":"k_EControllerActionOrigin_RightPad_DPadSouth", "value":"22" }, + { "name":"k_EControllerActionOrigin_RightPad_DPadWest", "value":"23" }, + { "name":"k_EControllerActionOrigin_RightPad_DPadEast", "value":"24" }, + { "name":"k_EControllerActionOrigin_LeftTrigger_Pull", "value":"25" }, + { "name":"k_EControllerActionOrigin_LeftTrigger_Click", "value":"26" }, + { "name":"k_EControllerActionOrigin_RightTrigger_Pull", "value":"27" }, + { "name":"k_EControllerActionOrigin_RightTrigger_Click", "value":"28" }, + { "name":"k_EControllerActionOrigin_LeftStick_Move", "value":"29" }, + { "name":"k_EControllerActionOrigin_LeftStick_Click", "value":"30" }, + { "name":"k_EControllerActionOrigin_LeftStick_DPadNorth", "value":"31" }, + { "name":"k_EControllerActionOrigin_LeftStick_DPadSouth", "value":"32" }, + { "name":"k_EControllerActionOrigin_LeftStick_DPadWest", "value":"33" }, + { "name":"k_EControllerActionOrigin_LeftStick_DPadEast", "value":"34" }, + { "name":"k_EControllerActionOrigin_Gyro_Move", "value":"35" }, + { "name":"k_EControllerActionOrigin_Gyro_Pitch", "value":"36" }, + { "name":"k_EControllerActionOrigin_Gyro_Yaw", "value":"37" }, + { "name":"k_EControllerActionOrigin_Gyro_Roll", "value":"38" }, + { "name":"k_EControllerActionOrigin_PS4_X", "value":"39" }, + { "name":"k_EControllerActionOrigin_PS4_Circle", "value":"40" }, + { "name":"k_EControllerActionOrigin_PS4_Triangle", "value":"41" }, + { "name":"k_EControllerActionOrigin_PS4_Square", "value":"42" }, + { "name":"k_EControllerActionOrigin_PS4_LeftBumper", "value":"43" }, + { "name":"k_EControllerActionOrigin_PS4_RightBumper", "value":"44" }, + { "name":"k_EControllerActionOrigin_PS4_Options", "value":"45" }, + { "name":"k_EControllerActionOrigin_PS4_Share", "value":"46" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_Touch", "value":"47" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_Swipe", "value":"48" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_Click", "value":"49" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_DPadNorth", "value":"50" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_DPadSouth", "value":"51" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_DPadWest", "value":"52" }, + { "name":"k_EControllerActionOrigin_PS4_LeftPad_DPadEast", "value":"53" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_Touch", "value":"54" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_Swipe", "value":"55" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_Click", "value":"56" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_DPadNorth", "value":"57" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_DPadSouth", "value":"58" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_DPadWest", "value":"59" }, + { "name":"k_EControllerActionOrigin_PS4_RightPad_DPadEast", "value":"60" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_Touch", "value":"61" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_Swipe", "value":"62" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_Click", "value":"63" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_DPadNorth", "value":"64" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_DPadSouth", "value":"65" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_DPadWest", "value":"66" }, + { "name":"k_EControllerActionOrigin_PS4_CenterPad_DPadEast", "value":"67" }, + { "name":"k_EControllerActionOrigin_PS4_LeftTrigger_Pull", "value":"68" }, + { "name":"k_EControllerActionOrigin_PS4_LeftTrigger_Click", "value":"69" }, + { "name":"k_EControllerActionOrigin_PS4_RightTrigger_Pull", "value":"70" }, + { "name":"k_EControllerActionOrigin_PS4_RightTrigger_Click", "value":"71" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_Move", "value":"72" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_Click", "value":"73" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_DPadNorth", "value":"74" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_DPadSouth", "value":"75" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_DPadWest", "value":"76" }, + { "name":"k_EControllerActionOrigin_PS4_LeftStick_DPadEast", "value":"77" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_Move", "value":"78" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_Click", "value":"79" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_DPadNorth", "value":"80" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_DPadSouth", "value":"81" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_DPadWest", "value":"82" }, + { "name":"k_EControllerActionOrigin_PS4_RightStick_DPadEast", "value":"83" }, + { "name":"k_EControllerActionOrigin_PS4_DPad_North", "value":"84" }, + { "name":"k_EControllerActionOrigin_PS4_DPad_South", "value":"85" }, + { "name":"k_EControllerActionOrigin_PS4_DPad_West", "value":"86" }, + { "name":"k_EControllerActionOrigin_PS4_DPad_East", "value":"87" }, + { "name":"k_EControllerActionOrigin_PS4_Gyro_Move", "value":"88" }, + { "name":"k_EControllerActionOrigin_PS4_Gyro_Pitch", "value":"89" }, + { "name":"k_EControllerActionOrigin_PS4_Gyro_Yaw", "value":"90" }, + { "name":"k_EControllerActionOrigin_PS4_Gyro_Roll", "value":"91" }, + { "name":"k_EControllerActionOrigin_XBoxOne_A", "value":"92" }, + { "name":"k_EControllerActionOrigin_XBoxOne_B", "value":"93" }, + { "name":"k_EControllerActionOrigin_XBoxOne_X", "value":"94" }, + { "name":"k_EControllerActionOrigin_XBoxOne_Y", "value":"95" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftBumper", "value":"96" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightBumper", "value":"97" }, + { "name":"k_EControllerActionOrigin_XBoxOne_Menu", "value":"98" }, + { "name":"k_EControllerActionOrigin_XBoxOne_View", "value":"99" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftTrigger_Pull", "value":"100" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftTrigger_Click", "value":"101" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightTrigger_Pull", "value":"102" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightTrigger_Click", "value":"103" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_Move", "value":"104" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_Click", "value":"105" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_DPadNorth", "value":"106" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_DPadSouth", "value":"107" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_DPadWest", "value":"108" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftStick_DPadEast", "value":"109" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_Move", "value":"110" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_Click", "value":"111" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_DPadNorth", "value":"112" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_DPadSouth", "value":"113" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_DPadWest", "value":"114" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightStick_DPadEast", "value":"115" }, + { "name":"k_EControllerActionOrigin_XBoxOne_DPad_North", "value":"116" }, + { "name":"k_EControllerActionOrigin_XBoxOne_DPad_South", "value":"117" }, + { "name":"k_EControllerActionOrigin_XBoxOne_DPad_West", "value":"118" }, + { "name":"k_EControllerActionOrigin_XBoxOne_DPad_East", "value":"119" }, + { "name":"k_EControllerActionOrigin_XBox360_A", "value":"120" }, + { "name":"k_EControllerActionOrigin_XBox360_B", "value":"121" }, + { "name":"k_EControllerActionOrigin_XBox360_X", "value":"122" }, + { "name":"k_EControllerActionOrigin_XBox360_Y", "value":"123" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftBumper", "value":"124" }, + { "name":"k_EControllerActionOrigin_XBox360_RightBumper", "value":"125" }, + { "name":"k_EControllerActionOrigin_XBox360_Start", "value":"126" }, + { "name":"k_EControllerActionOrigin_XBox360_Back", "value":"127" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftTrigger_Pull", "value":"128" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftTrigger_Click", "value":"129" }, + { "name":"k_EControllerActionOrigin_XBox360_RightTrigger_Pull", "value":"130" }, + { "name":"k_EControllerActionOrigin_XBox360_RightTrigger_Click", "value":"131" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_Move", "value":"132" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_Click", "value":"133" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_DPadNorth", "value":"134" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_DPadSouth", "value":"135" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_DPadWest", "value":"136" }, + { "name":"k_EControllerActionOrigin_XBox360_LeftStick_DPadEast", "value":"137" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_Move", "value":"138" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_Click", "value":"139" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_DPadNorth", "value":"140" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_DPadSouth", "value":"141" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_DPadWest", "value":"142" }, + { "name":"k_EControllerActionOrigin_XBox360_RightStick_DPadEast", "value":"143" }, + { "name":"k_EControllerActionOrigin_XBox360_DPad_North", "value":"144" }, + { "name":"k_EControllerActionOrigin_XBox360_DPad_South", "value":"145" }, + { "name":"k_EControllerActionOrigin_XBox360_DPad_West", "value":"146" }, + { "name":"k_EControllerActionOrigin_XBox360_DPad_East", "value":"147" }, + { "name":"k_EControllerActionOrigin_SteamV2_A", "value":"148" }, + { "name":"k_EControllerActionOrigin_SteamV2_B", "value":"149" }, + { "name":"k_EControllerActionOrigin_SteamV2_X", "value":"150" }, + { "name":"k_EControllerActionOrigin_SteamV2_Y", "value":"151" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftBumper", "value":"152" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightBumper", "value":"153" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftGrip_Lower", "value":"154" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftGrip_Upper", "value":"155" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightGrip_Lower", "value":"156" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightGrip_Upper", "value":"157" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftBumper_Pressure", "value":"158" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightBumper_Pressure", "value":"159" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftGrip_Pressure", "value":"160" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightGrip_Pressure", "value":"161" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftGrip_Upper_Pressure", "value":"162" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightGrip_Upper_Pressure", "value":"163" }, + { "name":"k_EControllerActionOrigin_SteamV2_Start", "value":"164" }, + { "name":"k_EControllerActionOrigin_SteamV2_Back", "value":"165" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_Touch", "value":"166" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_Swipe", "value":"167" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_Click", "value":"168" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_Pressure", "value":"169" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_DPadNorth", "value":"170" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_DPadSouth", "value":"171" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_DPadWest", "value":"172" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftPad_DPadEast", "value":"173" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_Touch", "value":"174" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_Swipe", "value":"175" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_Click", "value":"176" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_Pressure", "value":"177" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_DPadNorth", "value":"178" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_DPadSouth", "value":"179" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_DPadWest", "value":"180" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightPad_DPadEast", "value":"181" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftTrigger_Pull", "value":"182" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftTrigger_Click", "value":"183" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightTrigger_Pull", "value":"184" }, + { "name":"k_EControllerActionOrigin_SteamV2_RightTrigger_Click", "value":"185" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_Move", "value":"186" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_Click", "value":"187" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_DPadNorth", "value":"188" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_DPadSouth", "value":"189" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_DPadWest", "value":"190" }, + { "name":"k_EControllerActionOrigin_SteamV2_LeftStick_DPadEast", "value":"191" }, + { "name":"k_EControllerActionOrigin_SteamV2_Gyro_Move", "value":"192" }, + { "name":"k_EControllerActionOrigin_SteamV2_Gyro_Pitch", "value":"193" }, + { "name":"k_EControllerActionOrigin_SteamV2_Gyro_Yaw", "value":"194" }, + { "name":"k_EControllerActionOrigin_SteamV2_Gyro_Roll", "value":"195" }, + { "name":"k_EControllerActionOrigin_Switch_A", "value":"196" }, + { "name":"k_EControllerActionOrigin_Switch_B", "value":"197" }, + { "name":"k_EControllerActionOrigin_Switch_X", "value":"198" }, + { "name":"k_EControllerActionOrigin_Switch_Y", "value":"199" }, + { "name":"k_EControllerActionOrigin_Switch_LeftBumper", "value":"200" }, + { "name":"k_EControllerActionOrigin_Switch_RightBumper", "value":"201" }, + { "name":"k_EControllerActionOrigin_Switch_Plus", "value":"202" }, + { "name":"k_EControllerActionOrigin_Switch_Minus", "value":"203" }, + { "name":"k_EControllerActionOrigin_Switch_Capture", "value":"204" }, + { "name":"k_EControllerActionOrigin_Switch_LeftTrigger_Pull", "value":"205" }, + { "name":"k_EControllerActionOrigin_Switch_LeftTrigger_Click", "value":"206" }, + { "name":"k_EControllerActionOrigin_Switch_RightTrigger_Pull", "value":"207" }, + { "name":"k_EControllerActionOrigin_Switch_RightTrigger_Click", "value":"208" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_Move", "value":"209" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_Click", "value":"210" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_DPadNorth", "value":"211" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_DPadSouth", "value":"212" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_DPadWest", "value":"213" }, + { "name":"k_EControllerActionOrigin_Switch_LeftStick_DPadEast", "value":"214" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_Move", "value":"215" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_Click", "value":"216" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_DPadNorth", "value":"217" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_DPadSouth", "value":"218" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_DPadWest", "value":"219" }, + { "name":"k_EControllerActionOrigin_Switch_RightStick_DPadEast", "value":"220" }, + { "name":"k_EControllerActionOrigin_Switch_DPad_North", "value":"221" }, + { "name":"k_EControllerActionOrigin_Switch_DPad_South", "value":"222" }, + { "name":"k_EControllerActionOrigin_Switch_DPad_West", "value":"223" }, + { "name":"k_EControllerActionOrigin_Switch_DPad_East", "value":"224" }, + { "name":"k_EControllerActionOrigin_Switch_ProGyro_Move", "value":"225" }, + { "name":"k_EControllerActionOrigin_Switch_ProGyro_Pitch", "value":"226" }, + { "name":"k_EControllerActionOrigin_Switch_ProGyro_Yaw", "value":"227" }, + { "name":"k_EControllerActionOrigin_Switch_ProGyro_Roll", "value":"228" }, + { "name":"k_EControllerActionOrigin_Switch_RightGyro_Move", "value":"229" }, + { "name":"k_EControllerActionOrigin_Switch_RightGyro_Pitch", "value":"230" }, + { "name":"k_EControllerActionOrigin_Switch_RightGyro_Yaw", "value":"231" }, + { "name":"k_EControllerActionOrigin_Switch_RightGyro_Roll", "value":"232" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGyro_Move", "value":"233" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGyro_Pitch", "value":"234" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGyro_Yaw", "value":"235" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGyro_Roll", "value":"236" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGrip_Lower", "value":"237" }, + { "name":"k_EControllerActionOrigin_Switch_LeftGrip_Upper", "value":"238" }, + { "name":"k_EControllerActionOrigin_Switch_RightGrip_Lower", "value":"239" }, + { "name":"k_EControllerActionOrigin_Switch_RightGrip_Upper", "value":"240" }, + { "name":"k_EControllerActionOrigin_PS4_DPad_Move", "value":"241" }, + { "name":"k_EControllerActionOrigin_XBoxOne_DPad_Move", "value":"242" }, + { "name":"k_EControllerActionOrigin_XBox360_DPad_Move", "value":"243" }, + { "name":"k_EControllerActionOrigin_Switch_DPad_Move", "value":"244" }, + { "name":"k_EControllerActionOrigin_PS5_X", "value":"245" }, + { "name":"k_EControllerActionOrigin_PS5_Circle", "value":"246" }, + { "name":"k_EControllerActionOrigin_PS5_Triangle", "value":"247" }, + { "name":"k_EControllerActionOrigin_PS5_Square", "value":"248" }, + { "name":"k_EControllerActionOrigin_PS5_LeftBumper", "value":"249" }, + { "name":"k_EControllerActionOrigin_PS5_RightBumper", "value":"250" }, + { "name":"k_EControllerActionOrigin_PS5_Option", "value":"251" }, + { "name":"k_EControllerActionOrigin_PS5_Create", "value":"252" }, + { "name":"k_EControllerActionOrigin_PS5_Mute", "value":"253" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Touch", "value":"254" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Swipe", "value":"255" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Click", "value":"256" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadNorth", "value":"257" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadSouth", "value":"258" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadWest", "value":"259" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadEast", "value":"260" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Touch", "value":"261" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Swipe", "value":"262" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Click", "value":"263" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadNorth", "value":"264" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadSouth", "value":"265" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadWest", "value":"266" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadEast", "value":"267" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Touch", "value":"268" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Swipe", "value":"269" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Click", "value":"270" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadNorth", "value":"271" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadSouth", "value":"272" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadWest", "value":"273" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadEast", "value":"274" }, + { "name":"k_EControllerActionOrigin_PS5_LeftTrigger_Pull", "value":"275" }, + { "name":"k_EControllerActionOrigin_PS5_LeftTrigger_Click", "value":"276" }, + { "name":"k_EControllerActionOrigin_PS5_RightTrigger_Pull", "value":"277" }, + { "name":"k_EControllerActionOrigin_PS5_RightTrigger_Click", "value":"278" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_Move", "value":"279" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_Click", "value":"280" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadNorth", "value":"281" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadSouth", "value":"282" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadWest", "value":"283" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadEast", "value":"284" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_Move", "value":"285" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_Click", "value":"286" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadNorth", "value":"287" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadSouth", "value":"288" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadWest", "value":"289" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadEast", "value":"290" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_Move", "value":"291" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_North", "value":"292" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_South", "value":"293" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_West", "value":"294" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_East", "value":"295" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Move", "value":"296" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Pitch", "value":"297" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Yaw", "value":"298" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Roll", "value":"299" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftGrip_Lower", "value":"300" }, + { "name":"k_EControllerActionOrigin_XBoxOne_LeftGrip_Upper", "value":"301" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightGrip_Lower", "value":"302" }, + { "name":"k_EControllerActionOrigin_XBoxOne_RightGrip_Upper", "value":"303" }, + { "name":"k_EControllerActionOrigin_XBoxOne_Share", "value":"304" }, + { "name":"k_EControllerActionOrigin_SteamDeck_A", "value":"305" }, + { "name":"k_EControllerActionOrigin_SteamDeck_B", "value":"306" }, + { "name":"k_EControllerActionOrigin_SteamDeck_X", "value":"307" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Y", "value":"308" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L1", "value":"309" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R1", "value":"310" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Menu", "value":"311" }, + { "name":"k_EControllerActionOrigin_SteamDeck_View", "value":"312" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_Touch", "value":"313" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_Swipe", "value":"314" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_Click", "value":"315" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_DPadNorth", "value":"316" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_DPadSouth", "value":"317" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_DPadWest", "value":"318" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftPad_DPadEast", "value":"319" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_Touch", "value":"320" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_Swipe", "value":"321" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_Click", "value":"322" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_DPadNorth", "value":"323" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_DPadSouth", "value":"324" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_DPadWest", "value":"325" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightPad_DPadEast", "value":"326" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L2_SoftPull", "value":"327" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L2", "value":"328" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R2_SoftPull", "value":"329" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R2", "value":"330" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_Move", "value":"331" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L3", "value":"332" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_DPadNorth", "value":"333" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_DPadSouth", "value":"334" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_DPadWest", "value":"335" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_DPadEast", "value":"336" }, + { "name":"k_EControllerActionOrigin_SteamDeck_LeftStick_Touch", "value":"337" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_Move", "value":"338" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R3", "value":"339" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_DPadNorth", "value":"340" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_DPadSouth", "value":"341" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_DPadWest", "value":"342" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_DPadEast", "value":"343" }, + { "name":"k_EControllerActionOrigin_SteamDeck_RightStick_Touch", "value":"344" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L4", "value":"345" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R4", "value":"346" }, + { "name":"k_EControllerActionOrigin_SteamDeck_L5", "value":"347" }, + { "name":"k_EControllerActionOrigin_SteamDeck_R5", "value":"348" }, + { "name":"k_EControllerActionOrigin_SteamDeck_DPad_Move", "value":"349" }, + { "name":"k_EControllerActionOrigin_SteamDeck_DPad_North", "value":"350" }, + { "name":"k_EControllerActionOrigin_SteamDeck_DPad_South", "value":"351" }, + { "name":"k_EControllerActionOrigin_SteamDeck_DPad_West", "value":"352" }, + { "name":"k_EControllerActionOrigin_SteamDeck_DPad_East", "value":"353" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Gyro_Move", "value":"354" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Gyro_Pitch", "value":"355" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Gyro_Yaw", "value":"356" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Gyro_Roll", "value":"357" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved1", "value":"358" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved2", "value":"359" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved3", "value":"360" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved4", "value":"361" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved5", "value":"362" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved6", "value":"363" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved7", "value":"364" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved8", "value":"365" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved9", "value":"366" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved10", "value":"367" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved11", "value":"368" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved12", "value":"369" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved13", "value":"370" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved14", "value":"371" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved15", "value":"372" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved16", "value":"373" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved17", "value":"374" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved18", "value":"375" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved19", "value":"376" }, + { "name":"k_EControllerActionOrigin_SteamDeck_Reserved20", "value":"377" }, + { "name":"k_EControllerActionOrigin_Count", "value":"378" }, + { "name":"k_EControllerActionOrigin_MaximumPossibleValue", "value":"32767" } + ] + }, + { + "enumname": "ESteamControllerLEDFlag", + "values": [ + { "name":"k_ESteamControllerLEDFlag_SetColor", "value":"0" }, + { "name":"k_ESteamControllerLEDFlag_RestoreUserDefault", "value":"1" } + ] + }, + { + "enumname": "EUGCMatchingUGCType", + "values": [ + { "name":"k_EUGCMatchingUGCType_Items", "value":"0" }, + { "name":"k_EUGCMatchingUGCType_Items_Mtx", "value":"1" }, + { "name":"k_EUGCMatchingUGCType_Items_ReadyToUse", "value":"2" }, + { "name":"k_EUGCMatchingUGCType_Collections", "value":"3" }, + { "name":"k_EUGCMatchingUGCType_Artwork", "value":"4" }, + { "name":"k_EUGCMatchingUGCType_Videos", "value":"5" }, + { "name":"k_EUGCMatchingUGCType_Screenshots", "value":"6" }, + { "name":"k_EUGCMatchingUGCType_AllGuides", "value":"7" }, + { "name":"k_EUGCMatchingUGCType_WebGuides", "value":"8" }, + { "name":"k_EUGCMatchingUGCType_IntegratedGuides", "value":"9" }, + { "name":"k_EUGCMatchingUGCType_UsableInGame", "value":"10" }, + { "name":"k_EUGCMatchingUGCType_ControllerBindings", "value":"11" }, + { "name":"k_EUGCMatchingUGCType_GameManagedItems", "value":"12" }, + { "name":"k_EUGCMatchingUGCType_All", "value":"-1" } + ] + }, + { + "enumname": "EUserUGCList", + "values": [ + { "name":"k_EUserUGCList_Published", "value":"0" }, + { "name":"k_EUserUGCList_VotedOn", "value":"1" }, + { "name":"k_EUserUGCList_VotedUp", "value":"2" }, + { "name":"k_EUserUGCList_VotedDown", "value":"3" }, + { "name":"k_EUserUGCList_WillVoteLater", "value":"4" }, + { "name":"k_EUserUGCList_Favorited", "value":"5" }, + { "name":"k_EUserUGCList_Subscribed", "value":"6" }, + { "name":"k_EUserUGCList_UsedOrPlayed", "value":"7" }, + { "name":"k_EUserUGCList_Followed", "value":"8" } + ] + }, + { + "enumname": "EUserUGCListSortOrder", + "values": [ + { "name":"k_EUserUGCListSortOrder_CreationOrderDesc", "value":"0" }, + { "name":"k_EUserUGCListSortOrder_CreationOrderAsc", "value":"1" }, + { "name":"k_EUserUGCListSortOrder_TitleAsc", "value":"2" }, + { "name":"k_EUserUGCListSortOrder_LastUpdatedDesc", "value":"3" }, + { "name":"k_EUserUGCListSortOrder_SubscriptionDateDesc", "value":"4" }, + { "name":"k_EUserUGCListSortOrder_VoteScoreDesc", "value":"5" }, + { "name":"k_EUserUGCListSortOrder_ForModeration", "value":"6" } + ] + }, + { + "enumname": "EUGCQuery", + "values": [ + { "name":"k_EUGCQuery_RankedByVote", "value":"0" }, + { "name":"k_EUGCQuery_RankedByPublicationDate", "value":"1" }, + { "name":"k_EUGCQuery_AcceptedForGameRankedByAcceptanceDate", "value":"2" }, + { "name":"k_EUGCQuery_RankedByTrend", "value":"3" }, + { "name":"k_EUGCQuery_FavoritedByFriendsRankedByPublicationDate", "value":"4" }, + { "name":"k_EUGCQuery_CreatedByFriendsRankedByPublicationDate", "value":"5" }, + { "name":"k_EUGCQuery_RankedByNumTimesReported", "value":"6" }, + { "name":"k_EUGCQuery_CreatedByFollowedUsersRankedByPublicationDate", "value":"7" }, + { "name":"k_EUGCQuery_NotYetRated", "value":"8" }, + { "name":"k_EUGCQuery_RankedByTotalVotesAsc", "value":"9" }, + { "name":"k_EUGCQuery_RankedByVotesUp", "value":"10" }, + { "name":"k_EUGCQuery_RankedByTextSearch", "value":"11" }, + { "name":"k_EUGCQuery_RankedByTotalUniqueSubscriptions", "value":"12" }, + { "name":"k_EUGCQuery_RankedByPlaytimeTrend", "value":"13" }, + { "name":"k_EUGCQuery_RankedByTotalPlaytime", "value":"14" }, + { "name":"k_EUGCQuery_RankedByAveragePlaytimeTrend", "value":"15" }, + { "name":"k_EUGCQuery_RankedByLifetimeAveragePlaytime", "value":"16" }, + { "name":"k_EUGCQuery_RankedByPlaytimeSessionsTrend", "value":"17" }, + { "name":"k_EUGCQuery_RankedByLifetimePlaytimeSessions", "value":"18" }, + { "name":"k_EUGCQuery_RankedByLastUpdatedDate", "value":"19" } + ] + }, + { + "enumname": "EItemUpdateStatus", + "values": [ + { "name":"k_EItemUpdateStatusInvalid", "value":"0" }, + { "name":"k_EItemUpdateStatusPreparingConfig", "value":"1" }, + { "name":"k_EItemUpdateStatusPreparingContent", "value":"2" }, + { "name":"k_EItemUpdateStatusUploadingContent", "value":"3" }, + { "name":"k_EItemUpdateStatusUploadingPreviewFile", "value":"4" }, + { "name":"k_EItemUpdateStatusCommittingChanges", "value":"5" } + ] + }, + { + "enumname": "EItemState", + "values": [ + { "name":"k_EItemStateNone", "value":"0" }, + { "name":"k_EItemStateSubscribed", "value":"1" }, + { "name":"k_EItemStateLegacyItem", "value":"2" }, + { "name":"k_EItemStateInstalled", "value":"4" }, + { "name":"k_EItemStateNeedsUpdate", "value":"8" }, + { "name":"k_EItemStateDownloading", "value":"16" }, + { "name":"k_EItemStateDownloadPending", "value":"32" } + ] + }, + { + "enumname": "EItemStatistic", + "values": [ + { "name":"k_EItemStatistic_NumSubscriptions", "value":"0" }, + { "name":"k_EItemStatistic_NumFavorites", "value":"1" }, + { "name":"k_EItemStatistic_NumFollowers", "value":"2" }, + { "name":"k_EItemStatistic_NumUniqueSubscriptions", "value":"3" }, + { "name":"k_EItemStatistic_NumUniqueFavorites", "value":"4" }, + { "name":"k_EItemStatistic_NumUniqueFollowers", "value":"5" }, + { "name":"k_EItemStatistic_NumUniqueWebsiteViews", "value":"6" }, + { "name":"k_EItemStatistic_ReportScore", "value":"7" }, + { "name":"k_EItemStatistic_NumSecondsPlayed", "value":"8" }, + { "name":"k_EItemStatistic_NumPlaytimeSessions", "value":"9" }, + { "name":"k_EItemStatistic_NumComments", "value":"10" }, + { "name":"k_EItemStatistic_NumSecondsPlayedDuringTimePeriod", "value":"11" }, + { "name":"k_EItemStatistic_NumPlaytimeSessionsDuringTimePeriod", "value":"12" } + ] + }, + { + "enumname": "EItemPreviewType", + "values": [ + { "name":"k_EItemPreviewType_Image", "value":"0" }, + { "name":"k_EItemPreviewType_YouTubeVideo", "value":"1" }, + { "name":"k_EItemPreviewType_Sketchfab", "value":"2" }, + { "name":"k_EItemPreviewType_EnvironmentMap_HorizontalCross", "value":"3" }, + { "name":"k_EItemPreviewType_EnvironmentMap_LatLong", "value":"4" }, + { "name":"k_EItemPreviewType_ReservedMax", "value":"255" } + ] + }, + { + "enumname": "ESteamItemFlags", + "values": [ + { "name":"k_ESteamItemNoTrade", "value":"1" }, + { "name":"k_ESteamItemRemoved", "value":"256" }, + { "name":"k_ESteamItemConsumed", "value":"512" } + ] + }, + { + "enumname": "EParentalFeature", + "values": [ + { "name":"k_EFeatureInvalid", "value":"0" }, + { "name":"k_EFeatureStore", "value":"1" }, + { "name":"k_EFeatureCommunity", "value":"2" }, + { "name":"k_EFeatureProfile", "value":"3" }, + { "name":"k_EFeatureFriends", "value":"4" }, + { "name":"k_EFeatureNews", "value":"5" }, + { "name":"k_EFeatureTrading", "value":"6" }, + { "name":"k_EFeatureSettings", "value":"7" }, + { "name":"k_EFeatureConsole", "value":"8" }, + { "name":"k_EFeatureBrowser", "value":"9" }, + { "name":"k_EFeatureParentalSetup", "value":"10" }, + { "name":"k_EFeatureLibrary", "value":"11" }, + { "name":"k_EFeatureTest", "value":"12" }, + { "name":"k_EFeatureSiteLicense", "value":"13" }, + { "name":"k_EFeatureMax", "value":"14" } + ] + }, + { + "enumname": "ESteamDeviceFormFactor", + "values": [ + { "name":"k_ESteamDeviceFormFactorUnknown", "value":"0" }, + { "name":"k_ESteamDeviceFormFactorPhone", "value":"1" }, + { "name":"k_ESteamDeviceFormFactorTablet", "value":"2" }, + { "name":"k_ESteamDeviceFormFactorComputer", "value":"3" }, + { "name":"k_ESteamDeviceFormFactorTV", "value":"4" } + ] + }, + { + "enumname": "ESteamNetworkingAvailability", + "values": [ + { "name":"k_ESteamNetworkingAvailability_CannotTry", "value":"-102" }, + { "name":"k_ESteamNetworkingAvailability_Failed", "value":"-101" }, + { "name":"k_ESteamNetworkingAvailability_Previously", "value":"-100" }, + { "name":"k_ESteamNetworkingAvailability_Retrying", "value":"-10" }, + { "name":"k_ESteamNetworkingAvailability_NeverTried", "value":"1" }, + { "name":"k_ESteamNetworkingAvailability_Waiting", "value":"2" }, + { "name":"k_ESteamNetworkingAvailability_Attempting", "value":"3" }, + { "name":"k_ESteamNetworkingAvailability_Current", "value":"100" }, + { "name":"k_ESteamNetworkingAvailability_Unknown", "value":"0" }, + { "name":"k_ESteamNetworkingAvailability__Force32bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingIdentityType", + "values": [ + { "name":"k_ESteamNetworkingIdentityType_Invalid", "value":"0" }, + { "name":"k_ESteamNetworkingIdentityType_SteamID", "value":"16" }, + { "name":"k_ESteamNetworkingIdentityType_XboxPairwiseID", "value":"17" }, + { "name":"k_ESteamNetworkingIdentityType_SonyPSN", "value":"18" }, + { "name":"k_ESteamNetworkingIdentityType_GoogleStadia", "value":"19" }, + { "name":"k_ESteamNetworkingIdentityType_IPAddress", "value":"1" }, + { "name":"k_ESteamNetworkingIdentityType_GenericString", "value":"2" }, + { "name":"k_ESteamNetworkingIdentityType_GenericBytes", "value":"3" }, + { "name":"k_ESteamNetworkingIdentityType_UnknownType", "value":"4" }, + { "name":"k_ESteamNetworkingIdentityType__Force32bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingFakeIPType", + "values": [ + { "name":"k_ESteamNetworkingFakeIPType_Invalid", "value":"0" }, + { "name":"k_ESteamNetworkingFakeIPType_NotFake", "value":"1" }, + { "name":"k_ESteamNetworkingFakeIPType_GlobalIPv4", "value":"2" }, + { "name":"k_ESteamNetworkingFakeIPType_LocalIPv4", "value":"3" }, + { "name":"k_ESteamNetworkingFakeIPType__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingConnectionState", + "values": [ + { "name":"k_ESteamNetworkingConnectionState_None", "value":"0" }, + { "name":"k_ESteamNetworkingConnectionState_Connecting", "value":"1" }, + { "name":"k_ESteamNetworkingConnectionState_FindingRoute", "value":"2" }, + { "name":"k_ESteamNetworkingConnectionState_Connected", "value":"3" }, + { "name":"k_ESteamNetworkingConnectionState_ClosedByPeer", "value":"4" }, + { "name":"k_ESteamNetworkingConnectionState_ProblemDetectedLocally", "value":"5" }, + { "name":"k_ESteamNetworkingConnectionState_FinWait", "value":"-1" }, + { "name":"k_ESteamNetworkingConnectionState_Linger", "value":"-2" }, + { "name":"k_ESteamNetworkingConnectionState_Dead", "value":"-3" }, + { "name":"k_ESteamNetworkingConnectionState__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetConnectionEnd", + "values": [ + { "name":"k_ESteamNetConnectionEnd_Invalid", "value":"0" }, + { "name":"k_ESteamNetConnectionEnd_App_Min", "value":"1000" }, + { "name":"k_ESteamNetConnectionEnd_App_Generic", "value":"1000" }, + { "name":"k_ESteamNetConnectionEnd_App_Max", "value":"1999" }, + { "name":"k_ESteamNetConnectionEnd_AppException_Min", "value":"2000" }, + { "name":"k_ESteamNetConnectionEnd_AppException_Generic", "value":"2000" }, + { "name":"k_ESteamNetConnectionEnd_AppException_Max", "value":"2999" }, + { "name":"k_ESteamNetConnectionEnd_Local_Min", "value":"3000" }, + { "name":"k_ESteamNetConnectionEnd_Local_OfflineMode", "value":"3001" }, + { "name":"k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity", "value":"3002" }, + { "name":"k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay", "value":"3003" }, + { "name":"k_ESteamNetConnectionEnd_Local_NetworkConfig", "value":"3004" }, + { "name":"k_ESteamNetConnectionEnd_Local_Rights", "value":"3005" }, + { "name":"k_ESteamNetConnectionEnd_Local_P2P_ICE_NoPublicAddresses", "value":"3006" }, + { "name":"k_ESteamNetConnectionEnd_Local_Max", "value":"3999" }, + { "name":"k_ESteamNetConnectionEnd_Remote_Min", "value":"4000" }, + { "name":"k_ESteamNetConnectionEnd_Remote_Timeout", "value":"4001" }, + { "name":"k_ESteamNetConnectionEnd_Remote_BadCrypt", "value":"4002" }, + { "name":"k_ESteamNetConnectionEnd_Remote_BadCert", "value":"4003" }, + { "name":"k_ESteamNetConnectionEnd_Remote_BadProtocolVersion", "value":"4006" }, + { "name":"k_ESteamNetConnectionEnd_Remote_P2P_ICE_NoPublicAddresses", "value":"4007" }, + { "name":"k_ESteamNetConnectionEnd_Remote_Max", "value":"4999" }, + { "name":"k_ESteamNetConnectionEnd_Misc_Min", "value":"5000" }, + { "name":"k_ESteamNetConnectionEnd_Misc_Generic", "value":"5001" }, + { "name":"k_ESteamNetConnectionEnd_Misc_InternalError", "value":"5002" }, + { "name":"k_ESteamNetConnectionEnd_Misc_Timeout", "value":"5003" }, + { "name":"k_ESteamNetConnectionEnd_Misc_SteamConnectivity", "value":"5005" }, + { "name":"k_ESteamNetConnectionEnd_Misc_NoRelaySessionsToClient", "value":"5006" }, + { "name":"k_ESteamNetConnectionEnd_Misc_P2P_Rendezvous", "value":"5008" }, + { "name":"k_ESteamNetConnectionEnd_Misc_P2P_NAT_Firewall", "value":"5009" }, + { "name":"k_ESteamNetConnectionEnd_Misc_PeerSentNoConnection", "value":"5010" }, + { "name":"k_ESteamNetConnectionEnd_Misc_Max", "value":"5999" }, + { "name":"k_ESteamNetConnectionEnd__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingConfigScope", + "values": [ + { "name":"k_ESteamNetworkingConfig_Global", "value":"1" }, + { "name":"k_ESteamNetworkingConfig_SocketsInterface", "value":"2" }, + { "name":"k_ESteamNetworkingConfig_ListenSocket", "value":"3" }, + { "name":"k_ESteamNetworkingConfig_Connection", "value":"4" }, + { "name":"k_ESteamNetworkingConfigScope__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingConfigDataType", + "values": [ + { "name":"k_ESteamNetworkingConfig_Int32", "value":"1" }, + { "name":"k_ESteamNetworkingConfig_Int64", "value":"2" }, + { "name":"k_ESteamNetworkingConfig_Float", "value":"3" }, + { "name":"k_ESteamNetworkingConfig_String", "value":"4" }, + { "name":"k_ESteamNetworkingConfig_Ptr", "value":"5" }, + { "name":"k_ESteamNetworkingConfigDataType__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingConfigValue", + "values": [ + { "name":"k_ESteamNetworkingConfig_Invalid", "value":"0" }, + { "name":"k_ESteamNetworkingConfig_TimeoutInitial", "value":"24" }, + { "name":"k_ESteamNetworkingConfig_TimeoutConnected", "value":"25" }, + { "name":"k_ESteamNetworkingConfig_SendBufferSize", "value":"9" }, + { "name":"k_ESteamNetworkingConfig_ConnectionUserData", "value":"40" }, + { "name":"k_ESteamNetworkingConfig_SendRateMin", "value":"10" }, + { "name":"k_ESteamNetworkingConfig_SendRateMax", "value":"11" }, + { "name":"k_ESteamNetworkingConfig_NagleTime", "value":"12" }, + { "name":"k_ESteamNetworkingConfig_IP_AllowWithoutAuth", "value":"23" }, + { "name":"k_ESteamNetworkingConfig_MTU_PacketSize", "value":"32" }, + { "name":"k_ESteamNetworkingConfig_MTU_DataSize", "value":"33" }, + { "name":"k_ESteamNetworkingConfig_Unencrypted", "value":"34" }, + { "name":"k_ESteamNetworkingConfig_SymmetricConnect", "value":"37" }, + { "name":"k_ESteamNetworkingConfig_LocalVirtualPort", "value":"38" }, + { "name":"k_ESteamNetworkingConfig_DualWifi_Enable", "value":"39" }, + { "name":"k_ESteamNetworkingConfig_EnableDiagnosticsUI", "value":"46" }, + { "name":"k_ESteamNetworkingConfig_FakePacketLoss_Send", "value":"2" }, + { "name":"k_ESteamNetworkingConfig_FakePacketLoss_Recv", "value":"3" }, + { "name":"k_ESteamNetworkingConfig_FakePacketLag_Send", "value":"4" }, + { "name":"k_ESteamNetworkingConfig_FakePacketLag_Recv", "value":"5" }, + { "name":"k_ESteamNetworkingConfig_FakePacketReorder_Send", "value":"6" }, + { "name":"k_ESteamNetworkingConfig_FakePacketReorder_Recv", "value":"7" }, + { "name":"k_ESteamNetworkingConfig_FakePacketReorder_Time", "value":"8" }, + { "name":"k_ESteamNetworkingConfig_FakePacketDup_Send", "value":"26" }, + { "name":"k_ESteamNetworkingConfig_FakePacketDup_Recv", "value":"27" }, + { "name":"k_ESteamNetworkingConfig_FakePacketDup_TimeMax", "value":"28" }, + { "name":"k_ESteamNetworkingConfig_PacketTraceMaxBytes", "value":"41" }, + { "name":"k_ESteamNetworkingConfig_FakeRateLimit_Send_Rate", "value":"42" }, + { "name":"k_ESteamNetworkingConfig_FakeRateLimit_Send_Burst", "value":"43" }, + { "name":"k_ESteamNetworkingConfig_FakeRateLimit_Recv_Rate", "value":"44" }, + { "name":"k_ESteamNetworkingConfig_FakeRateLimit_Recv_Burst", "value":"45" }, + { "name":"k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged", "value":"201" }, + { "name":"k_ESteamNetworkingConfig_Callback_AuthStatusChanged", "value":"202" }, + { "name":"k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged", "value":"203" }, + { "name":"k_ESteamNetworkingConfig_Callback_MessagesSessionRequest", "value":"204" }, + { "name":"k_ESteamNetworkingConfig_Callback_MessagesSessionFailed", "value":"205" }, + { "name":"k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling", "value":"206" }, + { "name":"k_ESteamNetworkingConfig_Callback_FakeIPResult", "value":"207" }, + { "name":"k_ESteamNetworkingConfig_P2P_STUN_ServerList", "value":"103" }, + { "name":"k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable", "value":"104" }, + { "name":"k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty", "value":"105" }, + { "name":"k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty", "value":"106" }, + { "name":"k_ESteamNetworkingConfig_P2P_TURN_ServerList", "value":"107" }, + { "name":"k_ESteamNetworkingConfig_P2P_TURN_UserList", "value":"108" }, + { "name":"k_ESteamNetworkingConfig_P2P_TURN_PassList", "value":"109" }, + { "name":"k_ESteamNetworkingConfig_P2P_Transport_ICE_Implementation", "value":"110" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFailInitial", "value":"19" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFail", "value":"20" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_MinPingsBeforePingAccurate", "value":"21" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_SingleSocket", "value":"22" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_ForceRelayCluster", "value":"29" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_DebugTicketAddress", "value":"30" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_ForceProxyAddr", "value":"31" }, + { "name":"k_ESteamNetworkingConfig_SDRClient_FakeClusterPing", "value":"36" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_AckRTT", "value":"13" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_PacketDecode", "value":"14" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_Message", "value":"15" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_PacketGaps", "value":"16" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_P2PRendezvous", "value":"17" }, + { "name":"k_ESteamNetworkingConfig_LogLevel_SDRRelayPings", "value":"18" }, + { "name":"k_ESteamNetworkingConfig_DELETED_EnumerateDevVars", "value":"35" }, + { "name":"k_ESteamNetworkingConfigValue__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingGetConfigValueResult", + "values": [ + { "name":"k_ESteamNetworkingGetConfigValue_BadValue", "value":"-1" }, + { "name":"k_ESteamNetworkingGetConfigValue_BadScopeObj", "value":"-2" }, + { "name":"k_ESteamNetworkingGetConfigValue_BufferTooSmall", "value":"-3" }, + { "name":"k_ESteamNetworkingGetConfigValue_OK", "value":"1" }, + { "name":"k_ESteamNetworkingGetConfigValue_OKInherited", "value":"2" }, + { "name":"k_ESteamNetworkingGetConfigValueResult__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "ESteamNetworkingSocketsDebugOutputType", + "values": [ + { "name":"k_ESteamNetworkingSocketsDebugOutputType_None", "value":"0" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Bug", "value":"1" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Error", "value":"2" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Important", "value":"3" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Warning", "value":"4" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Msg", "value":"5" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Verbose", "value":"6" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Debug", "value":"7" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType_Everything", "value":"8" }, + { "name":"k_ESteamNetworkingSocketsDebugOutputType__Force32Bit", "value":"2147483647" } + ] + }, + { + "enumname": "EServerMode", + "values": [ + { "name":"eServerModeInvalid", "value":"0" }, + { "name":"eServerModeNoAuthentication", "value":"1" }, + { "name":"eServerModeAuthentication", "value":"2" }, + { "name":"eServerModeAuthenticationAndSecure", "value":"3" } + ] + } + ], + "interfaces": [ + { + "classname": "ISteamClient", + "fields": [], + "methods": [ + { + "methodname": "CreateSteamPipe", + "methodname_flat": "SteamAPI_ISteamClient_CreateSteamPipe", + "params": [], + "returntype": "HSteamPipe" + }, + { + "methodname": "BReleaseSteamPipe", + "methodname_flat": "SteamAPI_ISteamClient_BReleaseSteamPipe", + "params": [ + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" } + ], + "returntype": "bool" + }, + { + "methodname": "ConnectToGlobalUser", + "methodname_flat": "SteamAPI_ISteamClient_ConnectToGlobalUser", + "params": [ + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" } + ], + "returntype": "HSteamUser" + }, + { + "methodname": "CreateLocalUser", + "methodname_flat": "SteamAPI_ISteamClient_CreateLocalUser", + "params": [ + { "paramname":"phSteamPipe", "paramtype":"HSteamPipe *" }, + { "paramname":"eAccountType", "paramtype":"EAccountType" } + ], + "returntype": "HSteamUser" + }, + { + "methodname": "ReleaseUser", + "methodname_flat": "SteamAPI_ISteamClient_ReleaseUser", + "params": [ + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"hUser", "paramtype":"HSteamUser" } + ], + "returntype": "void" + }, + { + "methodname": "GetISteamUser", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamUser", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamUser *" + }, + { + "methodname": "GetISteamGameServer", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamGameServer", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamGameServer *" + }, + { + "methodname": "SetLocalIPBinding", + "methodname_flat": "SteamAPI_ISteamClient_SetLocalIPBinding", + "params": [ + { "paramname":"unIP", "paramtype":"const SteamIPAddress_t &" }, + { "paramname":"usPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "GetISteamFriends", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamFriends", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamFriends *" + }, + { + "methodname": "GetISteamUtils", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamUtils", + "params": [ + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamUtils *" + }, + { + "methodname": "GetISteamMatchmaking", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamMatchmaking", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamMatchmaking *" + }, + { + "methodname": "GetISteamMatchmakingServers", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamMatchmakingServers", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamMatchmakingServers *" + }, + { + "methodname": "GetISteamGenericInterface", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamGenericInterface", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "void *" + }, + { + "methodname": "GetISteamUserStats", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamUserStats", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamUserStats *" + }, + { + "methodname": "GetISteamGameServerStats", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamGameServerStats", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamGameServerStats *" + }, + { + "methodname": "GetISteamApps", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamApps", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamApps *" + }, + { + "methodname": "GetISteamNetworking", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamNetworking", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamNetworking *" + }, + { + "methodname": "GetISteamRemoteStorage", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamRemoteStorage", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamRemoteStorage *" + }, + { + "methodname": "GetISteamScreenshots", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamScreenshots", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamScreenshots *" + }, + { + "methodname": "GetISteamGameSearch", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamGameSearch", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamGameSearch *" + }, + { + "methodname": "GetIPCCallCount", + "methodname_flat": "SteamAPI_ISteamClient_GetIPCCallCount", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetWarningMessageHook", + "methodname_flat": "SteamAPI_ISteamClient_SetWarningMessageHook", + "params": [ + { "paramname":"pFunction", "paramtype":"SteamAPIWarningMessageHook_t" } + ], + "returntype": "void" + }, + { + "methodname": "BShutdownIfAllPipesClosed", + "methodname_flat": "SteamAPI_ISteamClient_BShutdownIfAllPipesClosed", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetISteamHTTP", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamHTTP", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamHTTP *" + }, + { + "methodname": "GetISteamController", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamController", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamController *" + }, + { + "methodname": "GetISteamUGC", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamUGC", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamUGC *" + }, + { + "methodname": "GetISteamAppList", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamAppList", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamAppList *" + }, + { + "methodname": "GetISteamMusic", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamMusic", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamMusic *" + }, + { + "methodname": "GetISteamMusicRemote", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamMusicRemote", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamMusicRemote *" + }, + { + "methodname": "GetISteamHTMLSurface", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamHTMLSurface", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamHTMLSurface *" + }, + { + "methodname": "GetISteamInventory", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamInventory", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamInventory *" + }, + { + "methodname": "GetISteamVideo", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamVideo", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamVideo *" + }, + { + "methodname": "GetISteamParentalSettings", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamParentalSettings", + "params": [ + { "paramname":"hSteamuser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamParentalSettings *" + }, + { + "methodname": "GetISteamInput", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamInput", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamInput *" + }, + { + "methodname": "GetISteamParties", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamParties", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamParties *" + }, + { + "methodname": "GetISteamRemotePlay", + "methodname_flat": "SteamAPI_ISteamClient_GetISteamRemotePlay", + "params": [ + { "paramname":"hSteamUser", "paramtype":"HSteamUser" }, + { "paramname":"hSteamPipe", "paramtype":"HSteamPipe" }, + { "paramname":"pchVersion", "paramtype":"const char *" } + ], + "returntype": "ISteamRemotePlay *" + } + ] + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamUser", + "name_flat": "SteamAPI_SteamUser_v021" + } + ], + "classname": "ISteamUser", + "fields": [], + "methods": [ + { + "methodname": "GetHSteamUser", + "methodname_flat": "SteamAPI_ISteamUser_GetHSteamUser", + "params": [], + "returntype": "HSteamUser" + }, + { + "methodname": "BLoggedOn", + "methodname_flat": "SteamAPI_ISteamUser_BLoggedOn", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetSteamID", + "methodname_flat": "SteamAPI_ISteamUser_GetSteamID", + "params": [], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "InitiateGameConnection_DEPRECATED", + "methodname_flat": "SteamAPI_ISteamUser_InitiateGameConnection_DEPRECATED", + "params": [ + { "paramname":"pAuthBlob", "paramtype":"void *" }, + { "paramname":"cbMaxAuthBlob", "paramtype":"int" }, + { "paramname":"steamIDGameServer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"unIPServer", "paramtype":"uint32" }, + { "paramname":"usPortServer", "paramtype":"uint16" }, + { "paramname":"bSecure", "paramtype":"bool" } + ], + "returntype": "int" + }, + { + "methodname": "TerminateGameConnection_DEPRECATED", + "methodname_flat": "SteamAPI_ISteamUser_TerminateGameConnection_DEPRECATED", + "params": [ + { "paramname":"unIPServer", "paramtype":"uint32" }, + { "paramname":"usPortServer", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "TrackAppUsageEvent", + "methodname_flat": "SteamAPI_ISteamUser_TrackAppUsageEvent", + "params": [ + { "paramname":"gameID", "paramtype":"CGameID", "paramtype_flat":"uint64_gameid" }, + { "paramname":"eAppUsageEvent", "paramtype":"int" }, + { "paramname":"pchExtraInfo", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "GetUserDataFolder", + "methodname_flat": "SteamAPI_ISteamUser_GetUserDataFolder", + "params": [ + { "paramname":"pchBuffer", "paramtype":"char *" }, + { "paramname":"cubBuffer", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "StartVoiceRecording", + "methodname_flat": "SteamAPI_ISteamUser_StartVoiceRecording", + "params": [], + "returntype": "void" + }, + { + "methodname": "StopVoiceRecording", + "methodname_flat": "SteamAPI_ISteamUser_StopVoiceRecording", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetAvailableVoice", + "methodname_flat": "SteamAPI_ISteamUser_GetAvailableVoice", + "params": [ + { "paramname":"pcbCompressed", "paramtype":"uint32 *" }, + { "paramname":"pcbUncompressed_Deprecated", "paramtype":"uint32 *" }, + { "paramname":"nUncompressedVoiceDesiredSampleRate_Deprecated", "paramtype":"uint32" } + ], + "returntype": "EVoiceResult" + }, + { + "methodname": "GetVoice", + "methodname_flat": "SteamAPI_ISteamUser_GetVoice", + "params": [ + { "paramname":"bWantCompressed", "paramtype":"bool" }, + { "paramname":"pDestBuffer", "paramtype":"void *" }, + { "paramname":"cbDestBufferSize", "paramtype":"uint32" }, + { "paramname":"nBytesWritten", "paramtype":"uint32 *" }, + { "paramname":"bWantUncompressed_Deprecated", "paramtype":"bool" }, + { "paramname":"pUncompressedDestBuffer_Deprecated", "paramtype":"void *" }, + { "paramname":"cbUncompressedDestBufferSize_Deprecated", "paramtype":"uint32" }, + { "paramname":"nUncompressBytesWritten_Deprecated", "paramtype":"uint32 *" }, + { "paramname":"nUncompressedVoiceDesiredSampleRate_Deprecated", "paramtype":"uint32" } + ], + "returntype": "EVoiceResult" + }, + { + "methodname": "DecompressVoice", + "methodname_flat": "SteamAPI_ISteamUser_DecompressVoice", + "params": [ + { "paramname":"pCompressed", "paramtype":"const void *" }, + { "paramname":"cbCompressed", "paramtype":"uint32" }, + { "paramname":"pDestBuffer", "paramtype":"void *" }, + { "paramname":"cbDestBufferSize", "paramtype":"uint32" }, + { "paramname":"nBytesWritten", "paramtype":"uint32 *" }, + { "paramname":"nDesiredSampleRate", "paramtype":"uint32" } + ], + "returntype": "EVoiceResult" + }, + { + "methodname": "GetVoiceOptimalSampleRate", + "methodname_flat": "SteamAPI_ISteamUser_GetVoiceOptimalSampleRate", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetAuthSessionTicket", + "methodname_flat": "SteamAPI_ISteamUser_GetAuthSessionTicket", + "params": [ + { "paramname":"pTicket", "paramtype":"void *" }, + { "paramname":"cbMaxTicket", "paramtype":"int" }, + { "paramname":"pcbTicket", "paramtype":"uint32 *" } + ], + "returntype": "HAuthTicket" + }, + { + "methodname": "BeginAuthSession", + "methodname_flat": "SteamAPI_ISteamUser_BeginAuthSession", + "params": [ + { "paramname":"pAuthTicket", "paramtype":"const void *" }, + { "paramname":"cbAuthTicket", "paramtype":"int" }, + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "EBeginAuthSessionResult" + }, + { + "methodname": "EndAuthSession", + "methodname_flat": "SteamAPI_ISteamUser_EndAuthSession", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "CancelAuthTicket", + "methodname_flat": "SteamAPI_ISteamUser_CancelAuthTicket", + "params": [ + { "paramname":"hAuthTicket", "paramtype":"HAuthTicket" } + ], + "returntype": "void" + }, + { + "methodname": "UserHasLicenseForApp", + "methodname_flat": "SteamAPI_ISteamUser_UserHasLicenseForApp", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"appID", "paramtype":"AppId_t" } + ], + "returntype": "EUserHasLicenseForAppResult" + }, + { + "methodname": "BIsBehindNAT", + "methodname_flat": "SteamAPI_ISteamUser_BIsBehindNAT", + "params": [], + "returntype": "bool" + }, + { + "methodname": "AdvertiseGame", + "methodname_flat": "SteamAPI_ISteamUser_AdvertiseGame", + "params": [ + { "paramname":"steamIDGameServer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"unIPServer", "paramtype":"uint32" }, + { "paramname":"usPortServer", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "callresult": "EncryptedAppTicketResponse_t", + "methodname": "RequestEncryptedAppTicket", + "methodname_flat": "SteamAPI_ISteamUser_RequestEncryptedAppTicket", + "params": [ + { "paramname":"pDataToInclude", "paramtype":"void *" }, + { "paramname":"cbDataToInclude", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetEncryptedAppTicket", + "methodname_flat": "SteamAPI_ISteamUser_GetEncryptedAppTicket", + "params": [ + { "paramname":"pTicket", "paramtype":"void *" }, + { "paramname":"cbMaxTicket", "paramtype":"int" }, + { "paramname":"pcbTicket", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGameBadgeLevel", + "methodname_flat": "SteamAPI_ISteamUser_GetGameBadgeLevel", + "params": [ + { "paramname":"nSeries", "paramtype":"int" }, + { "paramname":"bFoil", "paramtype":"bool" } + ], + "returntype": "int" + }, + { + "methodname": "GetPlayerSteamLevel", + "methodname_flat": "SteamAPI_ISteamUser_GetPlayerSteamLevel", + "params": [], + "returntype": "int" + }, + { + "callresult": "StoreAuthURLResponse_t", + "methodname": "RequestStoreAuthURL", + "methodname_flat": "SteamAPI_ISteamUser_RequestStoreAuthURL", + "params": [ + { "paramname":"pchRedirectURL", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "BIsPhoneVerified", + "methodname_flat": "SteamAPI_ISteamUser_BIsPhoneVerified", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsTwoFactorEnabled", + "methodname_flat": "SteamAPI_ISteamUser_BIsTwoFactorEnabled", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsPhoneIdentifying", + "methodname_flat": "SteamAPI_ISteamUser_BIsPhoneIdentifying", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsPhoneRequiringVerification", + "methodname_flat": "SteamAPI_ISteamUser_BIsPhoneRequiringVerification", + "params": [], + "returntype": "bool" + }, + { + "callresult": "MarketEligibilityResponse_t", + "methodname": "GetMarketEligibility", + "methodname_flat": "SteamAPI_ISteamUser_GetMarketEligibility", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "DurationControl_t", + "methodname": "GetDurationControl", + "methodname_flat": "SteamAPI_ISteamUser_GetDurationControl", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "BSetDurationControlOnlineState", + "methodname_flat": "SteamAPI_ISteamUser_BSetDurationControlOnlineState", + "params": [ + { "paramname":"eNewState", "paramtype":"EDurationControlOnlineState" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamUser021" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamFriends", + "name_flat": "SteamAPI_SteamFriends_v017" + } + ], + "classname": "ISteamFriends", + "fields": [], + "methods": [ + { + "methodname": "GetPersonaName", + "methodname_flat": "SteamAPI_ISteamFriends_GetPersonaName", + "params": [], + "returntype": "const char *" + }, + { + "callresult": "SetPersonaNameResponse_t", + "methodname": "SetPersonaName", + "methodname_flat": "SteamAPI_ISteamFriends_SetPersonaName", + "params": [ + { "paramname":"pchPersonaName", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetPersonaState", + "methodname_flat": "SteamAPI_ISteamFriends_GetPersonaState", + "params": [], + "returntype": "EPersonaState" + }, + { + "methodname": "GetFriendCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendCount", + "params": [ + { "paramname":"iFriendFlags", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetFriendByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendByIndex", + "params": [ + { "paramname":"iFriend", "paramtype":"int" }, + { "paramname":"iFriendFlags", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetFriendRelationship", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendRelationship", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "EFriendRelationship" + }, + { + "methodname": "GetFriendPersonaState", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendPersonaState", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "EPersonaState" + }, + { + "methodname": "GetFriendPersonaName", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendPersonaName", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetFriendGamePlayed", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendGamePlayed", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { + "out_struct": "", + "paramname": "pFriendGameInfo", + "paramtype": "FriendGameInfo_t *" + } + ], + "returntype": "bool" + }, + { + "methodname": "GetFriendPersonaNameHistory", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendPersonaNameHistory", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iPersonaName", "paramtype":"int" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetFriendSteamLevel", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendSteamLevel", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetPlayerNickname", + "methodname_flat": "SteamAPI_ISteamFriends_GetPlayerNickname", + "params": [ + { "paramname":"steamIDPlayer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetFriendsGroupCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendsGroupCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "GetFriendsGroupIDByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendsGroupIDByIndex", + "params": [ + { "paramname":"iFG", "paramtype":"int" } + ], + "returntype": "FriendsGroupID_t" + }, + { + "methodname": "GetFriendsGroupName", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendsGroupName", + "params": [ + { "paramname":"friendsGroupID", "paramtype":"FriendsGroupID_t" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetFriendsGroupMembersCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendsGroupMembersCount", + "params": [ + { "paramname":"friendsGroupID", "paramtype":"FriendsGroupID_t" } + ], + "returntype": "int" + }, + { + "methodname": "GetFriendsGroupMembersList", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendsGroupMembersList", + "params": [ + { "paramname":"friendsGroupID", "paramtype":"FriendsGroupID_t" }, + { + "out_array_call": "nMembersCount,GetFriendsGroupMembersCount,friendsGroupID", + "paramname": "pOutSteamIDMembers", + "paramtype": "CSteamID *" + }, + { "paramname":"nMembersCount", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "HasFriend", + "methodname_flat": "SteamAPI_ISteamFriends_HasFriend", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iFriendFlags", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetClanCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "GetClanByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanByIndex", + "params": [ + { "paramname":"iClan", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetClanName", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanName", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetClanTag", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanTag", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetClanActivityCounts", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanActivityCounts", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pnOnline", "paramtype":"int *" }, + { "paramname":"pnInGame", "paramtype":"int *" }, + { "paramname":"pnChatting", "paramtype":"int *" } + ], + "returntype": "bool" + }, + { + "callresult": "DownloadClanActivityCountsResult_t", + "methodname": "DownloadClanActivityCounts", + "methodname_flat": "SteamAPI_ISteamFriends_DownloadClanActivityCounts", + "params": [ + { + "array_count": "cClansToRequest", + "paramname": "psteamIDClans", + "paramtype": "CSteamID *" + }, + { "paramname":"cClansToRequest", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetFriendCountFromSource", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendCountFromSource", + "params": [ + { "paramname":"steamIDSource", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetFriendFromSourceByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendFromSourceByIndex", + "params": [ + { "paramname":"steamIDSource", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iFriend", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "IsUserInSource", + "methodname_flat": "SteamAPI_ISteamFriends_IsUserInSource", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDSource", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "SetInGameVoiceSpeaking", + "methodname_flat": "SteamAPI_ISteamFriends_SetInGameVoiceSpeaking", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"bSpeaking", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "ActivateGameOverlay", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlay", + "params": [ + { "paramname":"pchDialog", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "ActivateGameOverlayToUser", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayToUser", + "params": [ + { "paramname":"pchDialog", "paramtype":"const char *" }, + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "ActivateGameOverlayToWebPage", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage", + "params": [ + { "paramname":"pchURL", "paramtype":"const char *" }, + { "paramname":"eMode", "paramtype":"EActivateGameOverlayToWebPageMode" } + ], + "returntype": "void" + }, + { + "methodname": "ActivateGameOverlayToStore", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayToStore", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { "paramname":"eFlag", "paramtype":"EOverlayToStoreFlag" } + ], + "returntype": "void" + }, + { + "methodname": "SetPlayedWith", + "methodname_flat": "SteamAPI_ISteamFriends_SetPlayedWith", + "params": [ + { "paramname":"steamIDUserPlayedWith", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "ActivateGameOverlayInviteDialog", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialog", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "GetSmallFriendAvatar", + "methodname_flat": "SteamAPI_ISteamFriends_GetSmallFriendAvatar", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetMediumFriendAvatar", + "methodname_flat": "SteamAPI_ISteamFriends_GetMediumFriendAvatar", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetLargeFriendAvatar", + "methodname_flat": "SteamAPI_ISteamFriends_GetLargeFriendAvatar", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "RequestUserInformation", + "methodname_flat": "SteamAPI_ISteamFriends_RequestUserInformation", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"bRequireNameOnly", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "callresult": "ClanOfficerListResponse_t", + "methodname": "RequestClanOfficerList", + "methodname_flat": "SteamAPI_ISteamFriends_RequestClanOfficerList", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetClanOwner", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanOwner", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetClanOfficerCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanOfficerCount", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetClanOfficerByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanOfficerByIndex", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iOfficer", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetUserRestrictions", + "methodname_flat": "SteamAPI_ISteamFriends_GetUserRestrictions", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetRichPresence", + "methodname_flat": "SteamAPI_ISteamFriends_SetRichPresence", + "params": [ + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "ClearRichPresence", + "methodname_flat": "SteamAPI_ISteamFriends_ClearRichPresence", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetFriendRichPresence", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendRichPresence", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetFriendRichPresenceKeyCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendRichPresenceKeyCount", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetFriendRichPresenceKeyByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendRichPresenceKeyByIndex", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iKey", "paramtype":"int" } + ], + "returntype": "const char *" + }, + { + "methodname": "RequestFriendRichPresence", + "methodname_flat": "SteamAPI_ISteamFriends_RequestFriendRichPresence", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "InviteUserToGame", + "methodname_flat": "SteamAPI_ISteamFriends_InviteUserToGame", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchConnectString", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetCoplayFriendCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetCoplayFriendCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "GetCoplayFriend", + "methodname_flat": "SteamAPI_ISteamFriends_GetCoplayFriend", + "params": [ + { "paramname":"iCoplayFriend", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetFriendCoplayTime", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendCoplayTime", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetFriendCoplayGame", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendCoplayGame", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "AppId_t" + }, + { + "callresult": "JoinClanChatRoomCompletionResult_t", + "methodname": "JoinClanChatRoom", + "methodname_flat": "SteamAPI_ISteamFriends_JoinClanChatRoom", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "LeaveClanChatRoom", + "methodname_flat": "SteamAPI_ISteamFriends_LeaveClanChatRoom", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "GetClanChatMemberCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanChatMemberCount", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetChatMemberByIndex", + "methodname_flat": "SteamAPI_ISteamFriends_GetChatMemberByIndex", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iUser", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "SendClanChatMessage", + "methodname_flat": "SteamAPI_ISteamFriends_SendClanChatMessage", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetClanChatMessage", + "methodname_flat": "SteamAPI_ISteamFriends_GetClanChatMessage", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iMessage", "paramtype":"int" }, + { "paramname":"prgchText", "paramtype":"void *" }, + { "paramname":"cchTextMax", "paramtype":"int" }, + { "paramname":"peChatEntryType", "paramtype":"EChatEntryType *" }, + { + "out_struct": "", + "paramname": "psteamidChatter", + "paramtype": "CSteamID *" + } + ], + "returntype": "int" + }, + { + "methodname": "IsClanChatAdmin", + "methodname_flat": "SteamAPI_ISteamFriends_IsClanChatAdmin", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "IsClanChatWindowOpenInSteam", + "methodname_flat": "SteamAPI_ISteamFriends_IsClanChatWindowOpenInSteam", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "OpenClanChatWindowInSteam", + "methodname_flat": "SteamAPI_ISteamFriends_OpenClanChatWindowInSteam", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseClanChatWindowInSteam", + "methodname_flat": "SteamAPI_ISteamFriends_CloseClanChatWindowInSteam", + "params": [ + { "paramname":"steamIDClanChat", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "SetListenForFriendsMessages", + "methodname_flat": "SteamAPI_ISteamFriends_SetListenForFriendsMessages", + "params": [ + { "paramname":"bInterceptEnabled", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "ReplyToFriendMessage", + "methodname_flat": "SteamAPI_ISteamFriends_ReplyToFriendMessage", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchMsgToSend", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetFriendMessage", + "methodname_flat": "SteamAPI_ISteamFriends_GetFriendMessage", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iMessageID", "paramtype":"int" }, + { "paramname":"pvData", "paramtype":"void *" }, + { "paramname":"cubData", "paramtype":"int" }, + { "paramname":"peChatEntryType", "paramtype":"EChatEntryType *" } + ], + "returntype": "int" + }, + { + "callresult": "FriendsGetFollowerCount_t", + "methodname": "GetFollowerCount", + "methodname_flat": "SteamAPI_ISteamFriends_GetFollowerCount", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "FriendsIsFollowing_t", + "methodname": "IsFollowing", + "methodname_flat": "SteamAPI_ISteamFriends_IsFollowing", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "FriendsEnumerateFollowingList_t", + "methodname": "EnumerateFollowingList", + "methodname_flat": "SteamAPI_ISteamFriends_EnumerateFollowingList", + "params": [ + { "paramname":"unStartIndex", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "IsClanPublic", + "methodname_flat": "SteamAPI_ISteamFriends_IsClanPublic", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "IsClanOfficialGameGroup", + "methodname_flat": "SteamAPI_ISteamFriends_IsClanOfficialGameGroup", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "GetNumChatsWithUnreadPriorityMessages", + "methodname_flat": "SteamAPI_ISteamFriends_GetNumChatsWithUnreadPriorityMessages", + "params": [], + "returntype": "int" + }, + { + "methodname": "ActivateGameOverlayRemotePlayTogetherInviteDialog", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayRemotePlayTogetherInviteDialog", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "RegisterProtocolInOverlayBrowser", + "methodname_flat": "SteamAPI_ISteamFriends_RegisterProtocolInOverlayBrowser", + "params": [ + { "paramname":"pchProtocol", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "ActivateGameOverlayInviteDialogConnectString", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialogConnectString", + "params": [ + { "paramname":"pchConnectString", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "callresult": "EquippedProfileItems_t", + "methodname": "RequestEquippedProfileItems", + "methodname_flat": "SteamAPI_ISteamFriends_RequestEquippedProfileItems", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "BHasEquippedProfileItem", + "methodname_flat": "SteamAPI_ISteamFriends_BHasEquippedProfileItem", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"itemType", "paramtype":"ECommunityProfileItemType" } + ], + "returntype": "bool" + }, + { + "methodname": "GetProfileItemPropertyString", + "methodname_flat": "SteamAPI_ISteamFriends_GetProfileItemPropertyString", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"itemType", "paramtype":"ECommunityProfileItemType" }, + { "paramname":"prop", "paramtype":"ECommunityProfileItemProperty" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetProfileItemPropertyUint", + "methodname_flat": "SteamAPI_ISteamFriends_GetProfileItemPropertyUint", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"itemType", "paramtype":"ECommunityProfileItemType" }, + { "paramname":"prop", "paramtype":"ECommunityProfileItemProperty" } + ], + "returntype": "uint32" + } + ], + "version_string": "SteamFriends017" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamUtils", + "name_flat": "SteamAPI_SteamUtils_v010" + }, + { + "kind": "gameserver", + "name": "SteamGameServerUtils", + "name_flat": "SteamAPI_SteamGameServerUtils_v010" + } + ], + "classname": "ISteamUtils", + "fields": [], + "methods": [ + { + "methodname": "GetSecondsSinceAppActive", + "methodname_flat": "SteamAPI_ISteamUtils_GetSecondsSinceAppActive", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetSecondsSinceComputerActive", + "methodname_flat": "SteamAPI_ISteamUtils_GetSecondsSinceComputerActive", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetConnectedUniverse", + "methodname_flat": "SteamAPI_ISteamUtils_GetConnectedUniverse", + "params": [], + "returntype": "EUniverse" + }, + { + "methodname": "GetServerRealTime", + "methodname_flat": "SteamAPI_ISteamUtils_GetServerRealTime", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetIPCountry", + "methodname_flat": "SteamAPI_ISteamUtils_GetIPCountry", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "GetImageSize", + "methodname_flat": "SteamAPI_ISteamUtils_GetImageSize", + "params": [ + { "paramname":"iImage", "paramtype":"int" }, + { "paramname":"pnWidth", "paramtype":"uint32 *" }, + { "paramname":"pnHeight", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetImageRGBA", + "methodname_flat": "SteamAPI_ISteamUtils_GetImageRGBA", + "params": [ + { "paramname":"iImage", "paramtype":"int" }, + { "paramname":"pubDest", "paramtype":"uint8 *" }, + { "paramname":"nDestBufferSize", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetCurrentBatteryPower", + "methodname_flat": "SteamAPI_ISteamUtils_GetCurrentBatteryPower", + "params": [], + "returntype": "uint8" + }, + { + "methodname": "GetAppID", + "methodname_flat": "SteamAPI_ISteamUtils_GetAppID", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetOverlayNotificationPosition", + "methodname_flat": "SteamAPI_ISteamUtils_SetOverlayNotificationPosition", + "params": [ + { "paramname":"eNotificationPosition", "paramtype":"ENotificationPosition" } + ], + "returntype": "void" + }, + { + "methodname": "IsAPICallCompleted", + "methodname_flat": "SteamAPI_ISteamUtils_IsAPICallCompleted", + "params": [ + { "paramname":"hSteamAPICall", "paramtype":"SteamAPICall_t" }, + { "paramname":"pbFailed", "paramtype":"bool *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAPICallFailureReason", + "methodname_flat": "SteamAPI_ISteamUtils_GetAPICallFailureReason", + "params": [ + { "paramname":"hSteamAPICall", "paramtype":"SteamAPICall_t" } + ], + "returntype": "ESteamAPICallFailure" + }, + { + "methodname": "GetAPICallResult", + "methodname_flat": "SteamAPI_ISteamUtils_GetAPICallResult", + "params": [ + { "paramname":"hSteamAPICall", "paramtype":"SteamAPICall_t" }, + { "paramname":"pCallback", "paramtype":"void *" }, + { "paramname":"cubCallback", "paramtype":"int" }, + { "paramname":"iCallbackExpected", "paramtype":"int" }, + { "paramname":"pbFailed", "paramtype":"bool *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetIPCCallCount", + "methodname_flat": "SteamAPI_ISteamUtils_GetIPCCallCount", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetWarningMessageHook", + "methodname_flat": "SteamAPI_ISteamUtils_SetWarningMessageHook", + "params": [ + { "paramname":"pFunction", "paramtype":"SteamAPIWarningMessageHook_t" } + ], + "returntype": "void" + }, + { + "methodname": "IsOverlayEnabled", + "methodname_flat": "SteamAPI_ISteamUtils_IsOverlayEnabled", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BOverlayNeedsPresent", + "methodname_flat": "SteamAPI_ISteamUtils_BOverlayNeedsPresent", + "params": [], + "returntype": "bool" + }, + { + "callresult": "CheckFileSignature_t", + "methodname": "CheckFileSignature", + "methodname_flat": "SteamAPI_ISteamUtils_CheckFileSignature", + "params": [ + { "paramname":"szFileName", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "ShowGamepadTextInput", + "methodname_flat": "SteamAPI_ISteamUtils_ShowGamepadTextInput", + "params": [ + { "paramname":"eInputMode", "paramtype":"EGamepadTextInputMode" }, + { "paramname":"eLineInputMode", "paramtype":"EGamepadTextInputLineMode" }, + { "paramname":"pchDescription", "paramtype":"const char *" }, + { "paramname":"unCharMax", "paramtype":"uint32" }, + { "paramname":"pchExistingText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetEnteredGamepadTextLength", + "methodname_flat": "SteamAPI_ISteamUtils_GetEnteredGamepadTextLength", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetEnteredGamepadTextInput", + "methodname_flat": "SteamAPI_ISteamUtils_GetEnteredGamepadTextInput", + "params": [ + { "paramname":"pchText", "paramtype":"char *" }, + { "paramname":"cchText", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetSteamUILanguage", + "methodname_flat": "SteamAPI_ISteamUtils_GetSteamUILanguage", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "IsSteamRunningInVR", + "methodname_flat": "SteamAPI_ISteamUtils_IsSteamRunningInVR", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetOverlayNotificationInset", + "methodname_flat": "SteamAPI_ISteamUtils_SetOverlayNotificationInset", + "params": [ + { "paramname":"nHorizontalInset", "paramtype":"int" }, + { "paramname":"nVerticalInset", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "IsSteamInBigPictureMode", + "methodname_flat": "SteamAPI_ISteamUtils_IsSteamInBigPictureMode", + "params": [], + "returntype": "bool" + }, + { + "methodname": "StartVRDashboard", + "methodname_flat": "SteamAPI_ISteamUtils_StartVRDashboard", + "params": [], + "returntype": "void" + }, + { + "methodname": "IsVRHeadsetStreamingEnabled", + "methodname_flat": "SteamAPI_ISteamUtils_IsVRHeadsetStreamingEnabled", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetVRHeadsetStreamingEnabled", + "methodname_flat": "SteamAPI_ISteamUtils_SetVRHeadsetStreamingEnabled", + "params": [ + { "paramname":"bEnabled", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "IsSteamChinaLauncher", + "methodname_flat": "SteamAPI_ISteamUtils_IsSteamChinaLauncher", + "params": [], + "returntype": "bool" + }, + { + "methodname": "InitFilterText", + "methodname_flat": "SteamAPI_ISteamUtils_InitFilterText", + "params": [ + { "paramname":"unFilterOptions", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "FilterText", + "methodname_flat": "SteamAPI_ISteamUtils_FilterText", + "params": [ + { "paramname":"eContext", "paramtype":"ETextFilteringContext" }, + { "paramname":"sourceSteamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchInputMessage", "paramtype":"const char *" }, + { "paramname":"pchOutFilteredText", "paramtype":"char *" }, + { "paramname":"nByteSizeOutFilteredText", "paramtype":"uint32" } + ], + "returntype": "int" + }, + { + "methodname": "GetIPv6ConnectivityState", + "methodname_flat": "SteamAPI_ISteamUtils_GetIPv6ConnectivityState", + "params": [ + { "paramname":"eProtocol", "paramtype":"ESteamIPv6ConnectivityProtocol" } + ], + "returntype": "ESteamIPv6ConnectivityState" + }, + { + "methodname": "IsSteamRunningOnSteamDeck", + "methodname_flat": "SteamAPI_ISteamUtils_IsSteamRunningOnSteamDeck", + "params": [], + "returntype": "bool" + }, + { + "methodname": "ShowFloatingGamepadTextInput", + "methodname_flat": "SteamAPI_ISteamUtils_ShowFloatingGamepadTextInput", + "params": [ + { "paramname":"eKeyboardMode", "paramtype":"EFloatingGamepadTextInputMode" }, + { "paramname":"nTextFieldXPosition", "paramtype":"int" }, + { "paramname":"nTextFieldYPosition", "paramtype":"int" }, + { "paramname":"nTextFieldWidth", "paramtype":"int" }, + { "paramname":"nTextFieldHeight", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGameLauncherMode", + "methodname_flat": "SteamAPI_ISteamUtils_SetGameLauncherMode", + "params": [ + { "paramname":"bLauncherMode", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "DismissFloatingGamepadTextInput", + "methodname_flat": "SteamAPI_ISteamUtils_DismissFloatingGamepadTextInput", + "params": [], + "returntype": "bool" + } + ], + "version_string": "SteamUtils010" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamMatchmaking", + "name_flat": "SteamAPI_SteamMatchmaking_v009" + } + ], + "classname": "ISteamMatchmaking", + "fields": [], + "methods": [ + { + "methodname": "GetFavoriteGameCount", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetFavoriteGameCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "GetFavoriteGame", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetFavoriteGame", + "params": [ + { "paramname":"iGame", "paramtype":"int" }, + { "paramname":"pnAppID", "paramtype":"AppId_t *" }, + { "paramname":"pnIP", "paramtype":"uint32 *" }, + { "paramname":"pnConnPort", "paramtype":"uint16 *" }, + { "paramname":"pnQueryPort", "paramtype":"uint16 *" }, + { "paramname":"punFlags", "paramtype":"uint32 *" }, + { "paramname":"pRTime32LastPlayedOnServer", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddFavoriteGame", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddFavoriteGame", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { "paramname":"nIP", "paramtype":"uint32" }, + { "paramname":"nConnPort", "paramtype":"uint16" }, + { "paramname":"nQueryPort", "paramtype":"uint16" }, + { "paramname":"unFlags", "paramtype":"uint32" }, + { "paramname":"rTime32LastPlayedOnServer", "paramtype":"uint32" } + ], + "returntype": "int" + }, + { + "methodname": "RemoveFavoriteGame", + "methodname_flat": "SteamAPI_ISteamMatchmaking_RemoveFavoriteGame", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { "paramname":"nIP", "paramtype":"uint32" }, + { "paramname":"nConnPort", "paramtype":"uint16" }, + { "paramname":"nQueryPort", "paramtype":"uint16" }, + { "paramname":"unFlags", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "callresult": "LobbyMatchList_t", + "methodname": "RequestLobbyList", + "methodname_flat": "SteamAPI_ISteamMatchmaking_RequestLobbyList", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "AddRequestLobbyListStringFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListStringFilter", + "params": [ + { "paramname":"pchKeyToMatch", "paramtype":"const char *" }, + { "paramname":"pchValueToMatch", "paramtype":"const char *" }, + { "paramname":"eComparisonType", "paramtype":"ELobbyComparison" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListNumericalFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListNumericalFilter", + "params": [ + { "paramname":"pchKeyToMatch", "paramtype":"const char *" }, + { "paramname":"nValueToMatch", "paramtype":"int" }, + { "paramname":"eComparisonType", "paramtype":"ELobbyComparison" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListNearValueFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListNearValueFilter", + "params": [ + { "paramname":"pchKeyToMatch", "paramtype":"const char *" }, + { "paramname":"nValueToBeCloseTo", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListFilterSlotsAvailable", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListFilterSlotsAvailable", + "params": [ + { "paramname":"nSlotsAvailable", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListDistanceFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListDistanceFilter", + "params": [ + { "paramname":"eLobbyDistanceFilter", "paramtype":"ELobbyDistanceFilter" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListResultCountFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListResultCountFilter", + "params": [ + { "paramname":"cMaxResults", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "AddRequestLobbyListCompatibleMembersFilter", + "methodname_flat": "SteamAPI_ISteamMatchmaking_AddRequestLobbyListCompatibleMembersFilter", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "GetLobbyByIndex", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyByIndex", + "params": [ + { "paramname":"iLobby", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "callresult": "LobbyCreated_t", + "methodname": "CreateLobby", + "methodname_flat": "SteamAPI_ISteamMatchmaking_CreateLobby", + "params": [ + { "paramname":"eLobbyType", "paramtype":"ELobbyType" }, + { "paramname":"cMaxMembers", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "LobbyEnter_t", + "methodname": "JoinLobby", + "methodname_flat": "SteamAPI_ISteamMatchmaking_JoinLobby", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "LeaveLobby", + "methodname_flat": "SteamAPI_ISteamMatchmaking_LeaveLobby", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "InviteUserToLobby", + "methodname_flat": "SteamAPI_ISteamMatchmaking_InviteUserToLobby", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDInvitee", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "GetNumLobbyMembers", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetNumLobbyMembers", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetLobbyMemberByIndex", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyMemberByIndex", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iMember", "paramtype":"int" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetLobbyData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "const char *" + }, + { + "methodname": "SetLobbyData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetLobbyDataCount", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyDataCount", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "GetLobbyDataByIndex", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyDataByIndex", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iLobbyData", "paramtype":"int" }, + { "paramname":"pchKey", "paramtype":"char *" }, + { "paramname":"cchKeyBufferSize", "paramtype":"int" }, + { "paramname":"pchValue", "paramtype":"char *" }, + { "paramname":"cchValueBufferSize", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "DeleteLobbyData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_DeleteLobbyData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetLobbyMemberData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyMemberData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "const char *" + }, + { + "methodname": "SetLobbyMemberData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyMemberData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SendLobbyChatMsg", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SendLobbyChatMsg", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pvMsgBody", "paramtype":"const void *" }, + { "paramname":"cubMsgBody", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetLobbyChatEntry", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyChatEntry", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"iChatID", "paramtype":"int" }, + { + "out_struct": "", + "paramname": "pSteamIDUser", + "paramtype": "CSteamID *" + }, + { "paramname":"pvData", "paramtype":"void *" }, + { "paramname":"cubData", "paramtype":"int" }, + { "paramname":"peChatEntryType", "paramtype":"EChatEntryType *" } + ], + "returntype": "int" + }, + { + "methodname": "RequestLobbyData", + "methodname_flat": "SteamAPI_ISteamMatchmaking_RequestLobbyData", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "SetLobbyGameServer", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyGameServer", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"unGameServerIP", "paramtype":"uint32" }, + { "paramname":"unGameServerPort", "paramtype":"uint16" }, + { "paramname":"steamIDGameServer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "GetLobbyGameServer", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyGameServer", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"punGameServerIP", "paramtype":"uint32 *" }, + { "paramname":"punGameServerPort", "paramtype":"uint16 *" }, + { + "out_struct": "", + "paramname": "psteamIDGameServer", + "paramtype": "CSteamID *" + } + ], + "returntype": "bool" + }, + { + "methodname": "SetLobbyMemberLimit", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyMemberLimit", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"cMaxMembers", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetLobbyMemberLimit", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyMemberLimit", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "int" + }, + { + "methodname": "SetLobbyType", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyType", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"eLobbyType", "paramtype":"ELobbyType" } + ], + "returntype": "bool" + }, + { + "methodname": "SetLobbyJoinable", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyJoinable", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"bLobbyJoinable", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "GetLobbyOwner", + "methodname_flat": "SteamAPI_ISteamMatchmaking_GetLobbyOwner", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "SetLobbyOwner", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLobbyOwner", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDNewOwner", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "SetLinkedLobby", + "methodname_flat": "SteamAPI_ISteamMatchmaking_SetLinkedLobby", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDLobbyDependent", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamMatchMaking009" + }, + { + "classname": "ISteamMatchmakingServerListResponse", + "fields": [], + "methods": [ + { + "methodname": "ServerResponded", + "methodname_flat": "SteamAPI_ISteamMatchmakingServerListResponse_ServerResponded", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" }, + { "paramname":"iServer", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "ServerFailedToRespond", + "methodname_flat": "SteamAPI_ISteamMatchmakingServerListResponse_ServerFailedToRespond", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" }, + { "paramname":"iServer", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "RefreshComplete", + "methodname_flat": "SteamAPI_ISteamMatchmakingServerListResponse_RefreshComplete", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" }, + { "paramname":"response", "paramtype":"EMatchMakingServerResponse" } + ], + "returntype": "void" + } + ] + }, + { + "classname": "ISteamMatchmakingPingResponse", + "fields": [], + "methods": [ + { + "methodname": "ServerResponded", + "methodname_flat": "SteamAPI_ISteamMatchmakingPingResponse_ServerResponded", + "params": [ + { "paramname":"server", "paramtype":"gameserveritem_t &" } + ], + "returntype": "void" + }, + { + "methodname": "ServerFailedToRespond", + "methodname_flat": "SteamAPI_ISteamMatchmakingPingResponse_ServerFailedToRespond", + "params": [], + "returntype": "void" + } + ] + }, + { + "classname": "ISteamMatchmakingPlayersResponse", + "fields": [], + "methods": [ + { + "methodname": "AddPlayerToList", + "methodname_flat": "SteamAPI_ISteamMatchmakingPlayersResponse_AddPlayerToList", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"nScore", "paramtype":"int" }, + { "paramname":"flTimePlayed", "paramtype":"float" } + ], + "returntype": "void" + }, + { + "methodname": "PlayersFailedToRespond", + "methodname_flat": "SteamAPI_ISteamMatchmakingPlayersResponse_PlayersFailedToRespond", + "params": [], + "returntype": "void" + }, + { + "methodname": "PlayersRefreshComplete", + "methodname_flat": "SteamAPI_ISteamMatchmakingPlayersResponse_PlayersRefreshComplete", + "params": [], + "returntype": "void" + } + ] + }, + { + "classname": "ISteamMatchmakingRulesResponse", + "fields": [], + "methods": [ + { + "methodname": "RulesResponded", + "methodname_flat": "SteamAPI_ISteamMatchmakingRulesResponse_RulesResponded", + "params": [ + { "paramname":"pchRule", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "RulesFailedToRespond", + "methodname_flat": "SteamAPI_ISteamMatchmakingRulesResponse_RulesFailedToRespond", + "params": [], + "returntype": "void" + }, + { + "methodname": "RulesRefreshComplete", + "methodname_flat": "SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete", + "params": [], + "returntype": "void" + } + ] + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamMatchmakingServers", + "name_flat": "SteamAPI_SteamMatchmakingServers_v002" + } + ], + "classname": "ISteamMatchmakingServers", + "fields": [], + "methods": [ + { + "methodname": "RequestInternetServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestInternetServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { + "array_count": "nFilters", + "paramname": "ppchFilters", + "paramtype": "MatchMakingKeyValuePair_t **" + }, + { "paramname":"nFilters", "paramtype":"uint32" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "RequestLANServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestLANServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "RequestFriendsServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestFriendsServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { + "array_count": "nFilters", + "paramname": "ppchFilters", + "paramtype": "MatchMakingKeyValuePair_t **" + }, + { "paramname":"nFilters", "paramtype":"uint32" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "RequestFavoritesServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestFavoritesServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { + "array_count": "nFilters", + "paramname": "ppchFilters", + "paramtype": "MatchMakingKeyValuePair_t **" + }, + { "paramname":"nFilters", "paramtype":"uint32" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "RequestHistoryServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestHistoryServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { + "array_count": "nFilters", + "paramname": "ppchFilters", + "paramtype": "MatchMakingKeyValuePair_t **" + }, + { "paramname":"nFilters", "paramtype":"uint32" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "RequestSpectatorServerList", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RequestSpectatorServerList", + "params": [ + { "paramname":"iApp", "paramtype":"AppId_t" }, + { + "array_count": "nFilters", + "paramname": "ppchFilters", + "paramtype": "MatchMakingKeyValuePair_t **" + }, + { "paramname":"nFilters", "paramtype":"uint32" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingServerListResponse *" } + ], + "returntype": "HServerListRequest" + }, + { + "methodname": "ReleaseRequest", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_ReleaseRequest", + "params": [ + { "paramname":"hServerListRequest", "paramtype":"HServerListRequest" } + ], + "returntype": "void" + }, + { + "methodname": "GetServerDetails", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_GetServerDetails", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" }, + { "paramname":"iServer", "paramtype":"int" } + ], + "returntype": "gameserveritem_t *" + }, + { + "methodname": "CancelQuery", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_CancelQuery", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" } + ], + "returntype": "void" + }, + { + "methodname": "RefreshQuery", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RefreshQuery", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" } + ], + "returntype": "void" + }, + { + "methodname": "IsRefreshing", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_IsRefreshing", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" } + ], + "returntype": "bool" + }, + { + "methodname": "GetServerCount", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_GetServerCount", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" } + ], + "returntype": "int" + }, + { + "methodname": "RefreshServer", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_RefreshServer", + "params": [ + { "paramname":"hRequest", "paramtype":"HServerListRequest" }, + { "paramname":"iServer", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "PingServer", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_PingServer", + "params": [ + { "paramname":"unIP", "paramtype":"uint32" }, + { "paramname":"usPort", "paramtype":"uint16" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingPingResponse *" } + ], + "returntype": "HServerQuery" + }, + { + "methodname": "PlayerDetails", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_PlayerDetails", + "params": [ + { "paramname":"unIP", "paramtype":"uint32" }, + { "paramname":"usPort", "paramtype":"uint16" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingPlayersResponse *" } + ], + "returntype": "HServerQuery" + }, + { + "methodname": "ServerRules", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_ServerRules", + "params": [ + { "paramname":"unIP", "paramtype":"uint32" }, + { "paramname":"usPort", "paramtype":"uint16" }, + { "paramname":"pRequestServersResponse", "paramtype":"ISteamMatchmakingRulesResponse *" } + ], + "returntype": "HServerQuery" + }, + { + "methodname": "CancelServerQuery", + "methodname_flat": "SteamAPI_ISteamMatchmakingServers_CancelServerQuery", + "params": [ + { "paramname":"hServerQuery", "paramtype":"HServerQuery" } + ], + "returntype": "void" + } + ], + "version_string": "SteamMatchMakingServers002" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamGameSearch", + "name_flat": "SteamAPI_SteamGameSearch_v001" + } + ], + "classname": "ISteamGameSearch", + "fields": [], + "methods": [ + { + "methodname": "AddGameSearchParams", + "methodname_flat": "SteamAPI_ISteamGameSearch_AddGameSearchParams", + "params": [ + { "paramname":"pchKeyToFind", "paramtype":"const char *" }, + { "paramname":"pchValuesToFind", "paramtype":"const char *" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "SearchForGameWithLobby", + "methodname_flat": "SteamAPI_ISteamGameSearch_SearchForGameWithLobby", + "params": [ + { "paramname":"steamIDLobby", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"nPlayerMin", "paramtype":"int" }, + { "paramname":"nPlayerMax", "paramtype":"int" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "SearchForGameSolo", + "methodname_flat": "SteamAPI_ISteamGameSearch_SearchForGameSolo", + "params": [ + { "paramname":"nPlayerMin", "paramtype":"int" }, + { "paramname":"nPlayerMax", "paramtype":"int" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "AcceptGame", + "methodname_flat": "SteamAPI_ISteamGameSearch_AcceptGame", + "params": [], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "DeclineGame", + "methodname_flat": "SteamAPI_ISteamGameSearch_DeclineGame", + "params": [], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "RetrieveConnectionDetails", + "methodname_flat": "SteamAPI_ISteamGameSearch_RetrieveConnectionDetails", + "params": [ + { "paramname":"steamIDHost", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchConnectionDetails", "paramtype":"char *" }, + { "paramname":"cubConnectionDetails", "paramtype":"int" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "EndGameSearch", + "methodname_flat": "SteamAPI_ISteamGameSearch_EndGameSearch", + "params": [], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "SetGameHostParams", + "methodname_flat": "SteamAPI_ISteamGameSearch_SetGameHostParams", + "params": [ + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "SetConnectionDetails", + "methodname_flat": "SteamAPI_ISteamGameSearch_SetConnectionDetails", + "params": [ + { "paramname":"pchConnectionDetails", "paramtype":"const char *" }, + { "paramname":"cubConnectionDetails", "paramtype":"int" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "RequestPlayersForGame", + "methodname_flat": "SteamAPI_ISteamGameSearch_RequestPlayersForGame", + "params": [ + { "paramname":"nPlayerMin", "paramtype":"int" }, + { "paramname":"nPlayerMax", "paramtype":"int" }, + { "paramname":"nMaxTeamSize", "paramtype":"int" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "HostConfirmGameStart", + "methodname_flat": "SteamAPI_ISteamGameSearch_HostConfirmGameStart", + "params": [ + { "paramname":"ullUniqueGameID", "paramtype":"uint64" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "CancelRequestPlayersForGame", + "methodname_flat": "SteamAPI_ISteamGameSearch_CancelRequestPlayersForGame", + "params": [], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "SubmitPlayerResult", + "methodname_flat": "SteamAPI_ISteamGameSearch_SubmitPlayerResult", + "params": [ + { "paramname":"ullUniqueGameID", "paramtype":"uint64" }, + { "paramname":"steamIDPlayer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"EPlayerResult", "paramtype":"EPlayerResult_t" } + ], + "returntype": "EGameSearchErrorCode_t" + }, + { + "methodname": "EndGame", + "methodname_flat": "SteamAPI_ISteamGameSearch_EndGame", + "params": [ + { "paramname":"ullUniqueGameID", "paramtype":"uint64" } + ], + "returntype": "EGameSearchErrorCode_t" + } + ], + "version_string": "SteamMatchGameSearch001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamParties", + "name_flat": "SteamAPI_SteamParties_v002" + } + ], + "classname": "ISteamParties", + "fields": [], + "methods": [ + { + "methodname": "GetNumActiveBeacons", + "methodname_flat": "SteamAPI_ISteamParties_GetNumActiveBeacons", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetBeaconByIndex", + "methodname_flat": "SteamAPI_ISteamParties_GetBeaconByIndex", + "params": [ + { "paramname":"unIndex", "paramtype":"uint32" } + ], + "returntype": "PartyBeaconID_t" + }, + { + "methodname": "GetBeaconDetails", + "methodname_flat": "SteamAPI_ISteamParties_GetBeaconDetails", + "params": [ + { "paramname":"ulBeaconID", "paramtype":"PartyBeaconID_t" }, + { "paramname":"pSteamIDBeaconOwner", "paramtype":"CSteamID *" }, + { + "out_struct": "", + "paramname": "pLocation", + "paramtype": "SteamPartyBeaconLocation_t *" + }, + { + "out_string_count": "cchMetadata", + "paramname": "pchMetadata", + "paramtype": "char *" + }, + { "paramname":"cchMetadata", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "callresult": "JoinPartyCallback_t", + "methodname": "JoinParty", + "methodname_flat": "SteamAPI_ISteamParties_JoinParty", + "params": [ + { "paramname":"ulBeaconID", "paramtype":"PartyBeaconID_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetNumAvailableBeaconLocations", + "methodname_flat": "SteamAPI_ISteamParties_GetNumAvailableBeaconLocations", + "params": [ + { "paramname":"puNumLocations", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAvailableBeaconLocations", + "methodname_flat": "SteamAPI_ISteamParties_GetAvailableBeaconLocations", + "params": [ + { "paramname":"pLocationList", "paramtype":"SteamPartyBeaconLocation_t *" }, + { "paramname":"uMaxNumLocations", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "callresult": "CreateBeaconCallback_t", + "methodname": "CreateBeacon", + "methodname_flat": "SteamAPI_ISteamParties_CreateBeacon", + "params": [ + { "paramname":"unOpenSlots", "paramtype":"uint32" }, + { "paramname":"pBeaconLocation", "paramtype":"SteamPartyBeaconLocation_t *" }, + { "paramname":"pchConnectString", "paramtype":"const char *" }, + { "paramname":"pchMetadata", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "OnReservationCompleted", + "methodname_flat": "SteamAPI_ISteamParties_OnReservationCompleted", + "params": [ + { "paramname":"ulBeacon", "paramtype":"PartyBeaconID_t" }, + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "CancelReservation", + "methodname_flat": "SteamAPI_ISteamParties_CancelReservation", + "params": [ + { "paramname":"ulBeacon", "paramtype":"PartyBeaconID_t" }, + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "callresult": "ChangeNumOpenSlotsCallback_t", + "methodname": "ChangeNumOpenSlots", + "methodname_flat": "SteamAPI_ISteamParties_ChangeNumOpenSlots", + "params": [ + { "paramname":"ulBeacon", "paramtype":"PartyBeaconID_t" }, + { "paramname":"unOpenSlots", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "DestroyBeacon", + "methodname_flat": "SteamAPI_ISteamParties_DestroyBeacon", + "params": [ + { "paramname":"ulBeacon", "paramtype":"PartyBeaconID_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetBeaconLocationData", + "methodname_flat": "SteamAPI_ISteamParties_GetBeaconLocationData", + "params": [ + { "paramname":"BeaconLocation", "paramtype":"SteamPartyBeaconLocation_t" }, + { "paramname":"eData", "paramtype":"ESteamPartyBeaconLocationData" }, + { + "out_string_count": "cchDataStringOut", + "paramname": "pchDataStringOut", + "paramtype": "char *" + }, + { "paramname":"cchDataStringOut", "paramtype":"int" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamParties002" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamRemoteStorage", + "name_flat": "SteamAPI_SteamRemoteStorage_v016" + } + ], + "classname": "ISteamRemoteStorage", + "fields": [], + "methods": [ + { + "methodname": "FileWrite", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWrite", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"pvData", "paramtype":"const void *" }, + { "paramname":"cubData", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "FileRead", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileRead", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"pvData", "paramtype":"void *" }, + { "paramname":"cubDataToRead", "paramtype":"int32" } + ], + "returntype": "int32" + }, + { + "callresult": "RemoteStorageFileWriteAsyncComplete_t", + "methodname": "FileWriteAsync", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWriteAsync", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"pvData", "paramtype":"const void *" }, + { "paramname":"cubData", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageFileReadAsyncComplete_t", + "methodname": "FileReadAsync", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileReadAsync", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"nOffset", "paramtype":"uint32" }, + { "paramname":"cubToRead", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "FileReadAsyncComplete", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileReadAsyncComplete", + "params": [ + { "paramname":"hReadCall", "paramtype":"SteamAPICall_t" }, + { "paramname":"pvBuffer", "paramtype":"void *" }, + { "paramname":"cubToRead", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "FileForget", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileForget", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "FileDelete", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileDelete", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "callresult": "RemoteStorageFileShareResult_t", + "methodname": "FileShare", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileShare", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "SetSyncPlatforms", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_SetSyncPlatforms", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"eRemoteStoragePlatform", "paramtype":"ERemoteStoragePlatform" } + ], + "returntype": "bool" + }, + { + "methodname": "FileWriteStreamOpen", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWriteStreamOpen", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "UGCFileWriteStreamHandle_t" + }, + { + "methodname": "FileWriteStreamWriteChunk", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWriteStreamWriteChunk", + "params": [ + { "paramname":"writeHandle", "paramtype":"UGCFileWriteStreamHandle_t" }, + { "paramname":"pvData", "paramtype":"const void *" }, + { "paramname":"cubData", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "FileWriteStreamClose", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWriteStreamClose", + "params": [ + { "paramname":"writeHandle", "paramtype":"UGCFileWriteStreamHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "FileWriteStreamCancel", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileWriteStreamCancel", + "params": [ + { "paramname":"writeHandle", "paramtype":"UGCFileWriteStreamHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "FileExists", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FileExists", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "FilePersisted", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_FilePersisted", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetFileSize", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetFileSize", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "int32" + }, + { + "methodname": "GetFileTimestamp", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetFileTimestamp", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "int64" + }, + { + "methodname": "GetSyncPlatforms", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetSyncPlatforms", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "ERemoteStoragePlatform" + }, + { + "methodname": "GetFileCount", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetFileCount", + "params": [], + "returntype": "int32" + }, + { + "methodname": "GetFileNameAndSize", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetFileNameAndSize", + "params": [ + { "paramname":"iFile", "paramtype":"int" }, + { "paramname":"pnFileSizeInBytes", "paramtype":"int32 *" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetQuota", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetQuota", + "params": [ + { "paramname":"pnTotalBytes", "paramtype":"uint64 *" }, + { "paramname":"puAvailableBytes", "paramtype":"uint64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "IsCloudEnabledForAccount", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_IsCloudEnabledForAccount", + "params": [], + "returntype": "bool" + }, + { + "methodname": "IsCloudEnabledForApp", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetCloudEnabledForApp", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_SetCloudEnabledForApp", + "params": [ + { "paramname":"bEnabled", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "callresult": "RemoteStorageDownloadUGCResult_t", + "methodname": "UGCDownload", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UGCDownload", + "params": [ + { "paramname":"hContent", "paramtype":"UGCHandle_t" }, + { "paramname":"unPriority", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetUGCDownloadProgress", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetUGCDownloadProgress", + "params": [ + { "paramname":"hContent", "paramtype":"UGCHandle_t" }, + { "paramname":"pnBytesDownloaded", "paramtype":"int32 *" }, + { "paramname":"pnBytesExpected", "paramtype":"int32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUGCDetails", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetUGCDetails", + "params": [ + { "paramname":"hContent", "paramtype":"UGCHandle_t" }, + { "paramname":"pnAppID", "paramtype":"AppId_t *" }, + { + "out_string": "", + "paramname": "ppchName", + "paramtype": "char **" + }, + { "paramname":"pnFileSizeInBytes", "paramtype":"int32 *" }, + { + "out_struct": "", + "paramname": "pSteamIDOwner", + "paramtype": "CSteamID *" + } + ], + "returntype": "bool" + }, + { + "methodname": "UGCRead", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UGCRead", + "params": [ + { "paramname":"hContent", "paramtype":"UGCHandle_t" }, + { "paramname":"pvData", "paramtype":"void *" }, + { "paramname":"cubDataToRead", "paramtype":"int32" }, + { "paramname":"cOffset", "paramtype":"uint32" }, + { "paramname":"eAction", "paramtype":"EUGCReadAction" } + ], + "returntype": "int32" + }, + { + "methodname": "GetCachedUGCCount", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetCachedUGCCount", + "params": [], + "returntype": "int32" + }, + { + "methodname": "GetCachedUGCHandle", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetCachedUGCHandle", + "params": [ + { "paramname":"iCachedContent", "paramtype":"int32" } + ], + "returntype": "UGCHandle_t" + }, + { + "callresult": "RemoteStoragePublishFileProgress_t", + "methodname": "PublishWorkshopFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_PublishWorkshopFile", + "params": [ + { "paramname":"pchFile", "paramtype":"const char *" }, + { "paramname":"pchPreviewFile", "paramtype":"const char *" }, + { "paramname":"nConsumerAppId", "paramtype":"AppId_t" }, + { "paramname":"pchTitle", "paramtype":"const char *" }, + { "paramname":"pchDescription", "paramtype":"const char *" }, + { "paramname":"eVisibility", "paramtype":"ERemoteStoragePublishedFileVisibility" }, + { "paramname":"pTags", "paramtype":"SteamParamStringArray_t *" }, + { "paramname":"eWorkshopFileType", "paramtype":"EWorkshopFileType" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "CreatePublishedFileUpdateRequest", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_CreatePublishedFileUpdateRequest", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "PublishedFileUpdateHandle_t" + }, + { + "methodname": "UpdatePublishedFileFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileFile", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pchFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePublishedFilePreviewFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFilePreviewFile", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pchPreviewFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePublishedFileTitle", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileTitle", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pchTitle", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePublishedFileDescription", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileDescription", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pchDescription", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePublishedFileVisibility", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileVisibility", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"eVisibility", "paramtype":"ERemoteStoragePublishedFileVisibility" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePublishedFileTags", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileTags", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pTags", "paramtype":"SteamParamStringArray_t *" } + ], + "returntype": "bool" + }, + { + "callresult": "RemoteStorageUpdatePublishedFileResult_t", + "methodname": "CommitPublishedFileUpdate", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_CommitPublishedFileUpdate", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageGetPublishedFileDetailsResult_t", + "methodname": "GetPublishedFileDetails", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetPublishedFileDetails", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" }, + { "paramname":"unMaxSecondsOld", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageDeletePublishedFileResult_t", + "methodname": "DeletePublishedFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_DeletePublishedFile", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageEnumerateUserPublishedFilesResult_t", + "methodname": "EnumerateUserPublishedFiles", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EnumerateUserPublishedFiles", + "params": [ + { "paramname":"unStartIndex", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageSubscribePublishedFileResult_t", + "methodname": "SubscribePublishedFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_SubscribePublishedFile", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageEnumerateUserSubscribedFilesResult_t", + "methodname": "EnumerateUserSubscribedFiles", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EnumerateUserSubscribedFiles", + "params": [ + { "paramname":"unStartIndex", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageUnsubscribePublishedFileResult_t", + "methodname": "UnsubscribePublishedFile", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UnsubscribePublishedFile", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "UpdatePublishedFileSetChangeDescription", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdatePublishedFileSetChangeDescription", + "params": [ + { "paramname":"updateHandle", "paramtype":"PublishedFileUpdateHandle_t" }, + { "paramname":"pchChangeDescription", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "callresult": "RemoteStorageGetPublishedItemVoteDetailsResult_t", + "methodname": "GetPublishedItemVoteDetails", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetPublishedItemVoteDetails", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageUpdateUserPublishedItemVoteResult_t", + "methodname": "UpdateUserPublishedItemVote", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UpdateUserPublishedItemVote", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" }, + { "paramname":"bVoteUp", "paramtype":"bool" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageGetPublishedItemVoteDetailsResult_t", + "methodname": "GetUserPublishedItemVoteDetails", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetUserPublishedItemVoteDetails", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageEnumerateUserPublishedFilesResult_t", + "methodname": "EnumerateUserSharedWorkshopFiles", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EnumerateUserSharedWorkshopFiles", + "params": [ + { "paramname":"steamId", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"unStartIndex", "paramtype":"uint32" }, + { "paramname":"pRequiredTags", "paramtype":"SteamParamStringArray_t *" }, + { "paramname":"pExcludedTags", "paramtype":"SteamParamStringArray_t *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStoragePublishFileProgress_t", + "methodname": "PublishVideo", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_PublishVideo", + "params": [ + { "paramname":"eVideoProvider", "paramtype":"EWorkshopVideoProvider" }, + { "paramname":"pchVideoAccount", "paramtype":"const char *" }, + { "paramname":"pchVideoIdentifier", "paramtype":"const char *" }, + { "paramname":"pchPreviewFile", "paramtype":"const char *" }, + { "paramname":"nConsumerAppId", "paramtype":"AppId_t" }, + { "paramname":"pchTitle", "paramtype":"const char *" }, + { "paramname":"pchDescription", "paramtype":"const char *" }, + { "paramname":"eVisibility", "paramtype":"ERemoteStoragePublishedFileVisibility" }, + { "paramname":"pTags", "paramtype":"SteamParamStringArray_t *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageSetUserPublishedFileActionResult_t", + "methodname": "SetUserPublishedFileAction", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_SetUserPublishedFileAction", + "params": [ + { "paramname":"unPublishedFileId", "paramtype":"PublishedFileId_t" }, + { "paramname":"eAction", "paramtype":"EWorkshopFileAction" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageEnumeratePublishedFilesByUserActionResult_t", + "methodname": "EnumeratePublishedFilesByUserAction", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EnumeratePublishedFilesByUserAction", + "params": [ + { "paramname":"eAction", "paramtype":"EWorkshopFileAction" }, + { "paramname":"unStartIndex", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageEnumerateWorkshopFilesResult_t", + "methodname": "EnumeratePublishedWorkshopFiles", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EnumeratePublishedWorkshopFiles", + "params": [ + { "paramname":"eEnumerationType", "paramtype":"EWorkshopEnumerationType" }, + { "paramname":"unStartIndex", "paramtype":"uint32" }, + { "paramname":"unCount", "paramtype":"uint32" }, + { "paramname":"unDays", "paramtype":"uint32" }, + { "paramname":"pTags", "paramtype":"SteamParamStringArray_t *" }, + { "paramname":"pUserTags", "paramtype":"SteamParamStringArray_t *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageDownloadUGCResult_t", + "methodname": "UGCDownloadToLocation", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_UGCDownloadToLocation", + "params": [ + { "paramname":"hContent", "paramtype":"UGCHandle_t" }, + { "paramname":"pchLocation", "paramtype":"const char *" }, + { "paramname":"unPriority", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetLocalFileChangeCount", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetLocalFileChangeCount", + "params": [], + "returntype": "int32" + }, + { + "methodname": "GetLocalFileChange", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_GetLocalFileChange", + "params": [ + { "paramname":"iFile", "paramtype":"int" }, + { "paramname":"pEChangeType", "paramtype":"ERemoteStorageLocalFileChange *" }, + { "paramname":"pEFilePathType", "paramtype":"ERemoteStorageFilePathType *" } + ], + "returntype": "const char *" + }, + { + "methodname": "BeginFileWriteBatch", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch", + "params": [], + "returntype": "bool" + }, + { + "methodname": "EndFileWriteBatch", + "methodname_flat": "SteamAPI_ISteamRemoteStorage_EndFileWriteBatch", + "params": [], + "returntype": "bool" + } + ], + "version_string": "STEAMREMOTESTORAGE_INTERFACE_VERSION016" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamUserStats", + "name_flat": "SteamAPI_SteamUserStats_v012" + } + ], + "classname": "ISteamUserStats", + "fields": [], + "methods": [ + { + "callback": "UserStatsReceived_t", + "methodname": "RequestCurrentStats", + "methodname_flat": "SteamAPI_ISteamUserStats_RequestCurrentStats", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetStatInt32", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"int32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetStatFloat", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"float *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetStat", + "methodname_flat": "SteamAPI_ISteamUserStats_SetStatInt32", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"nData", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetStat", + "methodname_flat": "SteamAPI_ISteamUserStats_SetStatFloat", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"fData", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateAvgRateStat", + "methodname_flat": "SteamAPI_ISteamUserStats_UpdateAvgRateStat", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"flCountThisSession", "paramtype":"float" }, + { "paramname":"dSessionLength", "paramtype":"double" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAchievement", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievement", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetAchievement", + "methodname_flat": "SteamAPI_ISteamUserStats_SetAchievement", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "ClearAchievement", + "methodname_flat": "SteamAPI_ISteamUserStats_ClearAchievement", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAchievementAndUnlockTime", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementAndUnlockTime", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" }, + { "paramname":"punUnlockTime", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "StoreStats", + "methodname_flat": "SteamAPI_ISteamUserStats_StoreStats", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetAchievementIcon", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementIcon", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "int" + }, + { + "methodname": "GetAchievementDisplayAttribute", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementDisplayAttribute", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "const char *" + }, + { + "methodname": "IndicateAchievementProgress", + "methodname_flat": "SteamAPI_ISteamUserStats_IndicateAchievementProgress", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"nCurProgress", "paramtype":"uint32" }, + { "paramname":"nMaxProgress", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetNumAchievements", + "methodname_flat": "SteamAPI_ISteamUserStats_GetNumAchievements", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetAchievementName", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementName", + "params": [ + { "paramname":"iAchievement", "paramtype":"uint32" } + ], + "returntype": "const char *" + }, + { + "callresult": "UserStatsReceived_t", + "methodname": "RequestUserStats", + "methodname_flat": "SteamAPI_ISteamUserStats_RequestUserStats", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetUserStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetUserStatInt32", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"int32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUserStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetUserStatFloat", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"float *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUserAchievement", + "methodname_flat": "SteamAPI_ISteamUserStats_GetUserAchievement", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUserAchievementAndUnlockTime", + "methodname_flat": "SteamAPI_ISteamUserStats_GetUserAchievementAndUnlockTime", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" }, + { "paramname":"punUnlockTime", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "ResetAllStats", + "methodname_flat": "SteamAPI_ISteamUserStats_ResetAllStats", + "params": [ + { "paramname":"bAchievementsToo", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "callresult": "LeaderboardFindResult_t", + "methodname": "FindOrCreateLeaderboard", + "methodname_flat": "SteamAPI_ISteamUserStats_FindOrCreateLeaderboard", + "params": [ + { "paramname":"pchLeaderboardName", "paramtype":"const char *" }, + { "paramname":"eLeaderboardSortMethod", "paramtype":"ELeaderboardSortMethod" }, + { "paramname":"eLeaderboardDisplayType", "paramtype":"ELeaderboardDisplayType" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "LeaderboardFindResult_t", + "methodname": "FindLeaderboard", + "methodname_flat": "SteamAPI_ISteamUserStats_FindLeaderboard", + "params": [ + { "paramname":"pchLeaderboardName", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetLeaderboardName", + "methodname_flat": "SteamAPI_ISteamUserStats_GetLeaderboardName", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetLeaderboardEntryCount", + "methodname_flat": "SteamAPI_ISteamUserStats_GetLeaderboardEntryCount", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" } + ], + "returntype": "int" + }, + { + "methodname": "GetLeaderboardSortMethod", + "methodname_flat": "SteamAPI_ISteamUserStats_GetLeaderboardSortMethod", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" } + ], + "returntype": "ELeaderboardSortMethod" + }, + { + "methodname": "GetLeaderboardDisplayType", + "methodname_flat": "SteamAPI_ISteamUserStats_GetLeaderboardDisplayType", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" } + ], + "returntype": "ELeaderboardDisplayType" + }, + { + "callresult": "LeaderboardScoresDownloaded_t", + "methodname": "DownloadLeaderboardEntries", + "methodname_flat": "SteamAPI_ISteamUserStats_DownloadLeaderboardEntries", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" }, + { "paramname":"eLeaderboardDataRequest", "paramtype":"ELeaderboardDataRequest" }, + { "paramname":"nRangeStart", "paramtype":"int" }, + { "paramname":"nRangeEnd", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "LeaderboardScoresDownloaded_t", + "methodname": "DownloadLeaderboardEntriesForUsers", + "methodname_flat": "SteamAPI_ISteamUserStats_DownloadLeaderboardEntriesForUsers", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" }, + { + "array_count": "cUsers", + "desc": "Array of users to retrieve", + "paramname": "prgUsers", + "paramtype": "CSteamID *" + }, + { "paramname":"cUsers", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetDownloadedLeaderboardEntry", + "methodname_flat": "SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry", + "params": [ + { "paramname":"hSteamLeaderboardEntries", "paramtype":"SteamLeaderboardEntries_t" }, + { "paramname":"index", "paramtype":"int" }, + { "paramname":"pLeaderboardEntry", "paramtype":"LeaderboardEntry_t *" }, + { "paramname":"pDetails", "paramtype":"int32 *" }, + { "paramname":"cDetailsMax", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "callresult": "LeaderboardScoreUploaded_t", + "methodname": "UploadLeaderboardScore", + "methodname_flat": "SteamAPI_ISteamUserStats_UploadLeaderboardScore", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" }, + { "paramname":"eLeaderboardUploadScoreMethod", "paramtype":"ELeaderboardUploadScoreMethod" }, + { "paramname":"nScore", "paramtype":"int32" }, + { "paramname":"pScoreDetails", "paramtype":"const int32 *" }, + { "paramname":"cScoreDetailsCount", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "LeaderboardUGCSet_t", + "methodname": "AttachLeaderboardUGC", + "methodname_flat": "SteamAPI_ISteamUserStats_AttachLeaderboardUGC", + "params": [ + { "paramname":"hSteamLeaderboard", "paramtype":"SteamLeaderboard_t" }, + { "paramname":"hUGC", "paramtype":"UGCHandle_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "NumberOfCurrentPlayers_t", + "methodname": "GetNumberOfCurrentPlayers", + "methodname_flat": "SteamAPI_ISteamUserStats_GetNumberOfCurrentPlayers", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "GlobalAchievementPercentagesReady_t", + "methodname": "RequestGlobalAchievementPercentages", + "methodname_flat": "SteamAPI_ISteamUserStats_RequestGlobalAchievementPercentages", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetMostAchievedAchievementInfo", + "methodname_flat": "SteamAPI_ISteamUserStats_GetMostAchievedAchievementInfo", + "params": [ + { "paramname":"pchName", "paramtype":"char *" }, + { "paramname":"unNameBufLen", "paramtype":"uint32" }, + { "paramname":"pflPercent", "paramtype":"float *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" } + ], + "returntype": "int" + }, + { + "methodname": "GetNextMostAchievedAchievementInfo", + "methodname_flat": "SteamAPI_ISteamUserStats_GetNextMostAchievedAchievementInfo", + "params": [ + { "paramname":"iIteratorPrevious", "paramtype":"int" }, + { "paramname":"pchName", "paramtype":"char *" }, + { "paramname":"unNameBufLen", "paramtype":"uint32" }, + { "paramname":"pflPercent", "paramtype":"float *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" } + ], + "returntype": "int" + }, + { + "methodname": "GetAchievementAchievedPercent", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementAchievedPercent", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pflPercent", "paramtype":"float *" } + ], + "returntype": "bool" + }, + { + "callresult": "GlobalStatsReceived_t", + "methodname": "RequestGlobalStats", + "methodname_flat": "SteamAPI_ISteamUserStats_RequestGlobalStats", + "params": [ + { "paramname":"nHistoryDays", "paramtype":"int" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetGlobalStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetGlobalStatInt64", + "params": [ + { "paramname":"pchStatName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"int64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGlobalStat", + "methodname_flat": "SteamAPI_ISteamUserStats_GetGlobalStatDouble", + "params": [ + { "paramname":"pchStatName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"double *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGlobalStatHistory", + "methodname_flat": "SteamAPI_ISteamUserStats_GetGlobalStatHistoryInt64", + "params": [ + { "paramname":"pchStatName", "paramtype":"const char *" }, + { + "array_count": "cubData", + "paramname": "pData", + "paramtype": "int64 *" + }, + { "paramname":"cubData", "paramtype":"uint32" } + ], + "returntype": "int32" + }, + { + "methodname": "GetGlobalStatHistory", + "methodname_flat": "SteamAPI_ISteamUserStats_GetGlobalStatHistoryDouble", + "params": [ + { "paramname":"pchStatName", "paramtype":"const char *" }, + { + "array_count": "cubData", + "paramname": "pData", + "paramtype": "double *" + }, + { "paramname":"cubData", "paramtype":"uint32" } + ], + "returntype": "int32" + }, + { + "methodname": "GetAchievementProgressLimits", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementProgressLimitsInt32", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pnMinProgress", "paramtype":"int32 *" }, + { "paramname":"pnMaxProgress", "paramtype":"int32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAchievementProgressLimits", + "methodname_flat": "SteamAPI_ISteamUserStats_GetAchievementProgressLimitsFloat", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pfMinProgress", "paramtype":"float *" }, + { "paramname":"pfMaxProgress", "paramtype":"float *" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMUSERSTATS_INTERFACE_VERSION012" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamApps", + "name_flat": "SteamAPI_SteamApps_v008" + } + ], + "classname": "ISteamApps", + "fields": [], + "methods": [ + { + "methodname": "BIsSubscribed", + "methodname_flat": "SteamAPI_ISteamApps_BIsSubscribed", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsLowViolence", + "methodname_flat": "SteamAPI_ISteamApps_BIsLowViolence", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsCybercafe", + "methodname_flat": "SteamAPI_ISteamApps_BIsCybercafe", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsVACBanned", + "methodname_flat": "SteamAPI_ISteamApps_BIsVACBanned", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetCurrentGameLanguage", + "methodname_flat": "SteamAPI_ISteamApps_GetCurrentGameLanguage", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "GetAvailableGameLanguages", + "methodname_flat": "SteamAPI_ISteamApps_GetAvailableGameLanguages", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "BIsSubscribedApp", + "methodname_flat": "SteamAPI_ISteamApps_BIsSubscribedApp", + "params": [ + { "paramname":"appID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "BIsDlcInstalled", + "methodname_flat": "SteamAPI_ISteamApps_BIsDlcInstalled", + "params": [ + { "paramname":"appID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetEarliestPurchaseUnixTime", + "methodname_flat": "SteamAPI_ISteamApps_GetEarliestPurchaseUnixTime", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "uint32" + }, + { + "methodname": "BIsSubscribedFromFreeWeekend", + "methodname_flat": "SteamAPI_ISteamApps_BIsSubscribedFromFreeWeekend", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetDLCCount", + "methodname_flat": "SteamAPI_ISteamApps_GetDLCCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "BGetDLCDataByIndex", + "methodname_flat": "SteamAPI_ISteamApps_BGetDLCDataByIndex", + "params": [ + { "paramname":"iDLC", "paramtype":"int" }, + { "paramname":"pAppID", "paramtype":"AppId_t *" }, + { "paramname":"pbAvailable", "paramtype":"bool *" }, + { "paramname":"pchName", "paramtype":"char *" }, + { "paramname":"cchNameBufferSize", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "InstallDLC", + "methodname_flat": "SteamAPI_ISteamApps_InstallDLC", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "void" + }, + { + "methodname": "UninstallDLC", + "methodname_flat": "SteamAPI_ISteamApps_UninstallDLC", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "void" + }, + { + "methodname": "RequestAppProofOfPurchaseKey", + "methodname_flat": "SteamAPI_ISteamApps_RequestAppProofOfPurchaseKey", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetCurrentBetaName", + "methodname_flat": "SteamAPI_ISteamApps_GetCurrentBetaName", + "params": [ + { "paramname":"pchName", "paramtype":"char *" }, + { "paramname":"cchNameBufferSize", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "MarkContentCorrupt", + "methodname_flat": "SteamAPI_ISteamApps_MarkContentCorrupt", + "params": [ + { "paramname":"bMissingFilesOnly", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "GetInstalledDepots", + "methodname_flat": "SteamAPI_ISteamApps_GetInstalledDepots", + "params": [ + { "paramname":"appID", "paramtype":"AppId_t" }, + { "paramname":"pvecDepots", "paramtype":"DepotId_t *" }, + { "paramname":"cMaxDepots", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetAppInstallDir", + "methodname_flat": "SteamAPI_ISteamApps_GetAppInstallDir", + "params": [ + { "paramname":"appID", "paramtype":"AppId_t" }, + { "paramname":"pchFolder", "paramtype":"char *" }, + { "paramname":"cchFolderBufferSize", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "BIsAppInstalled", + "methodname_flat": "SteamAPI_ISteamApps_BIsAppInstalled", + "params": [ + { "paramname":"appID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAppOwner", + "methodname_flat": "SteamAPI_ISteamApps_GetAppOwner", + "params": [], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetLaunchQueryParam", + "methodname_flat": "SteamAPI_ISteamApps_GetLaunchQueryParam", + "params": [ + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetDlcDownloadProgress", + "methodname_flat": "SteamAPI_ISteamApps_GetDlcDownloadProgress", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { "paramname":"punBytesDownloaded", "paramtype":"uint64 *" }, + { "paramname":"punBytesTotal", "paramtype":"uint64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetAppBuildId", + "methodname_flat": "SteamAPI_ISteamApps_GetAppBuildId", + "params": [], + "returntype": "int" + }, + { + "methodname": "RequestAllProofOfPurchaseKeys", + "methodname_flat": "SteamAPI_ISteamApps_RequestAllProofOfPurchaseKeys", + "params": [], + "returntype": "void" + }, + { + "callresult": "FileDetailsResult_t", + "methodname": "GetFileDetails", + "methodname_flat": "SteamAPI_ISteamApps_GetFileDetails", + "params": [ + { "paramname":"pszFileName", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetLaunchCommandLine", + "methodname_flat": "SteamAPI_ISteamApps_GetLaunchCommandLine", + "params": [ + { "paramname":"pszCommandLine", "paramtype":"char *" }, + { "paramname":"cubCommandLine", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "BIsSubscribedFromFamilySharing", + "methodname_flat": "SteamAPI_ISteamApps_BIsSubscribedFromFamilySharing", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsTimedTrial", + "methodname_flat": "SteamAPI_ISteamApps_BIsTimedTrial", + "params": [ + { "paramname":"punSecondsAllowed", "paramtype":"uint32 *" }, + { "paramname":"punSecondsPlayed", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetDlcContext", + "methodname_flat": "SteamAPI_ISteamApps_SetDlcContext", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMAPPS_INTERFACE_VERSION008" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamNetworking", + "name_flat": "SteamAPI_SteamNetworking_v006" + }, + { + "kind": "gameserver", + "name": "SteamGameServerNetworking", + "name_flat": "SteamAPI_SteamGameServerNetworking_v006" + } + ], + "classname": "ISteamNetworking", + "fields": [], + "methods": [ + { + "methodname": "SendP2PPacket", + "methodname_flat": "SteamAPI_ISteamNetworking_SendP2PPacket", + "params": [ + { "paramname":"steamIDRemote", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pubData", "paramtype":"const void *" }, + { "paramname":"cubData", "paramtype":"uint32" }, + { "paramname":"eP2PSendType", "paramtype":"EP2PSend" }, + { "paramname":"nChannel", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "IsP2PPacketAvailable", + "methodname_flat": "SteamAPI_ISteamNetworking_IsP2PPacketAvailable", + "params": [ + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" }, + { "paramname":"nChannel", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "ReadP2PPacket", + "methodname_flat": "SteamAPI_ISteamNetworking_ReadP2PPacket", + "params": [ + { "paramname":"pubDest", "paramtype":"void *" }, + { "paramname":"cubDest", "paramtype":"uint32" }, + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" }, + { "paramname":"psteamIDRemote", "paramtype":"CSteamID *" }, + { "paramname":"nChannel", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "AcceptP2PSessionWithUser", + "methodname_flat": "SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser", + "params": [ + { "paramname":"steamIDRemote", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseP2PSessionWithUser", + "methodname_flat": "SteamAPI_ISteamNetworking_CloseP2PSessionWithUser", + "params": [ + { "paramname":"steamIDRemote", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseP2PChannelWithUser", + "methodname_flat": "SteamAPI_ISteamNetworking_CloseP2PChannelWithUser", + "params": [ + { "paramname":"steamIDRemote", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"nChannel", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetP2PSessionState", + "methodname_flat": "SteamAPI_ISteamNetworking_GetP2PSessionState", + "params": [ + { "paramname":"steamIDRemote", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pConnectionState", "paramtype":"P2PSessionState_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "AllowP2PPacketRelay", + "methodname_flat": "SteamAPI_ISteamNetworking_AllowP2PPacketRelay", + "params": [ + { "paramname":"bAllow", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "CreateListenSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_CreateListenSocket", + "params": [ + { "paramname":"nVirtualP2PPort", "paramtype":"int" }, + { "paramname":"nIP", "paramtype":"SteamIPAddress_t" }, + { "paramname":"nPort", "paramtype":"uint16" }, + { "paramname":"bAllowUseOfPacketRelay", "paramtype":"bool" } + ], + "returntype": "SNetListenSocket_t" + }, + { + "methodname": "CreateP2PConnectionSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_CreateP2PConnectionSocket", + "params": [ + { "paramname":"steamIDTarget", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"nVirtualPort", "paramtype":"int" }, + { "paramname":"nTimeoutSec", "paramtype":"int" }, + { "paramname":"bAllowUseOfPacketRelay", "paramtype":"bool" } + ], + "returntype": "SNetSocket_t" + }, + { + "methodname": "CreateConnectionSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_CreateConnectionSocket", + "params": [ + { "paramname":"nIP", "paramtype":"SteamIPAddress_t" }, + { "paramname":"nPort", "paramtype":"uint16" }, + { "paramname":"nTimeoutSec", "paramtype":"int" } + ], + "returntype": "SNetSocket_t" + }, + { + "methodname": "DestroySocket", + "methodname_flat": "SteamAPI_ISteamNetworking_DestroySocket", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" }, + { "paramname":"bNotifyRemoteEnd", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "DestroyListenSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_DestroyListenSocket", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetListenSocket_t" }, + { "paramname":"bNotifyRemoteEnd", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SendDataOnSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_SendDataOnSocket", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" }, + { "paramname":"pubData", "paramtype":"void *" }, + { "paramname":"cubData", "paramtype":"uint32" }, + { "paramname":"bReliable", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "IsDataAvailableOnSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_IsDataAvailableOnSocket", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" }, + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "RetrieveDataFromSocket", + "methodname_flat": "SteamAPI_ISteamNetworking_RetrieveDataFromSocket", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" }, + { "paramname":"pubDest", "paramtype":"void *" }, + { "paramname":"cubDest", "paramtype":"uint32" }, + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "IsDataAvailable", + "methodname_flat": "SteamAPI_ISteamNetworking_IsDataAvailable", + "params": [ + { "paramname":"hListenSocket", "paramtype":"SNetListenSocket_t" }, + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" }, + { "paramname":"phSocket", "paramtype":"SNetSocket_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "RetrieveData", + "methodname_flat": "SteamAPI_ISteamNetworking_RetrieveData", + "params": [ + { "paramname":"hListenSocket", "paramtype":"SNetListenSocket_t" }, + { "paramname":"pubDest", "paramtype":"void *" }, + { "paramname":"cubDest", "paramtype":"uint32" }, + { "paramname":"pcubMsgSize", "paramtype":"uint32 *" }, + { "paramname":"phSocket", "paramtype":"SNetSocket_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetSocketInfo", + "methodname_flat": "SteamAPI_ISteamNetworking_GetSocketInfo", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" }, + { "paramname":"pSteamIDRemote", "paramtype":"CSteamID *" }, + { "paramname":"peSocketStatus", "paramtype":"int *" }, + { "paramname":"punIPRemote", "paramtype":"SteamIPAddress_t *" }, + { "paramname":"punPortRemote", "paramtype":"uint16 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetListenSocketInfo", + "methodname_flat": "SteamAPI_ISteamNetworking_GetListenSocketInfo", + "params": [ + { "paramname":"hListenSocket", "paramtype":"SNetListenSocket_t" }, + { "paramname":"pnIP", "paramtype":"SteamIPAddress_t *" }, + { "paramname":"pnPort", "paramtype":"uint16 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetSocketConnectionType", + "methodname_flat": "SteamAPI_ISteamNetworking_GetSocketConnectionType", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" } + ], + "returntype": "ESNetSocketConnectionType" + }, + { + "methodname": "GetMaxPacketSize", + "methodname_flat": "SteamAPI_ISteamNetworking_GetMaxPacketSize", + "params": [ + { "paramname":"hSocket", "paramtype":"SNetSocket_t" } + ], + "returntype": "int" + } + ], + "version_string": "SteamNetworking006" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamScreenshots", + "name_flat": "SteamAPI_SteamScreenshots_v003" + } + ], + "classname": "ISteamScreenshots", + "fields": [], + "methods": [ + { + "methodname": "WriteScreenshot", + "methodname_flat": "SteamAPI_ISteamScreenshots_WriteScreenshot", + "params": [ + { "paramname":"pubRGB", "paramtype":"void *" }, + { "paramname":"cubRGB", "paramtype":"uint32" }, + { "paramname":"nWidth", "paramtype":"int" }, + { "paramname":"nHeight", "paramtype":"int" } + ], + "returntype": "ScreenshotHandle" + }, + { + "methodname": "AddScreenshotToLibrary", + "methodname_flat": "SteamAPI_ISteamScreenshots_AddScreenshotToLibrary", + "params": [ + { "paramname":"pchFilename", "paramtype":"const char *" }, + { "paramname":"pchThumbnailFilename", "paramtype":"const char *" }, + { "paramname":"nWidth", "paramtype":"int" }, + { "paramname":"nHeight", "paramtype":"int" } + ], + "returntype": "ScreenshotHandle" + }, + { + "methodname": "TriggerScreenshot", + "methodname_flat": "SteamAPI_ISteamScreenshots_TriggerScreenshot", + "params": [], + "returntype": "void" + }, + { + "methodname": "HookScreenshots", + "methodname_flat": "SteamAPI_ISteamScreenshots_HookScreenshots", + "params": [ + { "paramname":"bHook", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "SetLocation", + "methodname_flat": "SteamAPI_ISteamScreenshots_SetLocation", + "params": [ + { "paramname":"hScreenshot", "paramtype":"ScreenshotHandle" }, + { "paramname":"pchLocation", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "TagUser", + "methodname_flat": "SteamAPI_ISteamScreenshots_TagUser", + "params": [ + { "paramname":"hScreenshot", "paramtype":"ScreenshotHandle" }, + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "TagPublishedFile", + "methodname_flat": "SteamAPI_ISteamScreenshots_TagPublishedFile", + "params": [ + { "paramname":"hScreenshot", "paramtype":"ScreenshotHandle" }, + { "paramname":"unPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "IsScreenshotsHooked", + "methodname_flat": "SteamAPI_ISteamScreenshots_IsScreenshotsHooked", + "params": [], + "returntype": "bool" + }, + { + "methodname": "AddVRScreenshotToLibrary", + "methodname_flat": "SteamAPI_ISteamScreenshots_AddVRScreenshotToLibrary", + "params": [ + { "paramname":"eType", "paramtype":"EVRScreenshotType" }, + { "paramname":"pchFilename", "paramtype":"const char *" }, + { "paramname":"pchVRFilename", "paramtype":"const char *" } + ], + "returntype": "ScreenshotHandle" + } + ], + "version_string": "STEAMSCREENSHOTS_INTERFACE_VERSION003" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamMusic", + "name_flat": "SteamAPI_SteamMusic_v001" + } + ], + "classname": "ISteamMusic", + "fields": [], + "methods": [ + { + "methodname": "BIsEnabled", + "methodname_flat": "SteamAPI_ISteamMusic_BIsEnabled", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsPlaying", + "methodname_flat": "SteamAPI_ISteamMusic_BIsPlaying", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetPlaybackStatus", + "methodname_flat": "SteamAPI_ISteamMusic_GetPlaybackStatus", + "params": [], + "returntype": "AudioPlayback_Status" + }, + { + "methodname": "Play", + "methodname_flat": "SteamAPI_ISteamMusic_Play", + "params": [], + "returntype": "void" + }, + { + "methodname": "Pause", + "methodname_flat": "SteamAPI_ISteamMusic_Pause", + "params": [], + "returntype": "void" + }, + { + "methodname": "PlayPrevious", + "methodname_flat": "SteamAPI_ISteamMusic_PlayPrevious", + "params": [], + "returntype": "void" + }, + { + "methodname": "PlayNext", + "methodname_flat": "SteamAPI_ISteamMusic_PlayNext", + "params": [], + "returntype": "void" + }, + { + "methodname": "SetVolume", + "methodname_flat": "SteamAPI_ISteamMusic_SetVolume", + "params": [ + { "paramname":"flVolume", "paramtype":"float" } + ], + "returntype": "void" + }, + { + "methodname": "GetVolume", + "methodname_flat": "SteamAPI_ISteamMusic_GetVolume", + "params": [], + "returntype": "float" + } + ], + "version_string": "STEAMMUSIC_INTERFACE_VERSION001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamMusicRemote", + "name_flat": "SteamAPI_SteamMusicRemote_v001" + } + ], + "classname": "ISteamMusicRemote", + "fields": [], + "methods": [ + { + "methodname": "RegisterSteamMusicRemote", + "methodname_flat": "SteamAPI_ISteamMusicRemote_RegisterSteamMusicRemote", + "params": [ + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "DeregisterSteamMusicRemote", + "methodname_flat": "SteamAPI_ISteamMusicRemote_DeregisterSteamMusicRemote", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsCurrentMusicRemote", + "methodname_flat": "SteamAPI_ISteamMusicRemote_BIsCurrentMusicRemote", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BActivationSuccess", + "methodname_flat": "SteamAPI_ISteamMusicRemote_BActivationSuccess", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetDisplayName", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetDisplayName", + "params": [ + { "paramname":"pchDisplayName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetPNGIcon_64x64", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetPNGIcon_64x64", + "params": [ + { "paramname":"pvBuffer", "paramtype":"void *" }, + { "paramname":"cbBufferLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "EnablePlayPrevious", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnablePlayPrevious", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "EnablePlayNext", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnablePlayNext", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "EnableShuffled", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnableShuffled", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "EnableLooped", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnableLooped", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "EnableQueue", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnableQueue", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "EnablePlaylists", + "methodname_flat": "SteamAPI_ISteamMusicRemote_EnablePlaylists", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdatePlaybackStatus", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdatePlaybackStatus", + "params": [ + { "paramname":"nStatus", "paramtype":"AudioPlayback_Status" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateShuffled", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateShuffled", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateLooped", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateLooped", + "params": [ + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateVolume", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateVolume", + "params": [ + { "paramname":"flValue", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "CurrentEntryWillChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_CurrentEntryWillChange", + "params": [], + "returntype": "bool" + }, + { + "methodname": "CurrentEntryIsAvailable", + "methodname_flat": "SteamAPI_ISteamMusicRemote_CurrentEntryIsAvailable", + "params": [ + { "paramname":"bAvailable", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateCurrentEntryText", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateCurrentEntryText", + "params": [ + { "paramname":"pchText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateCurrentEntryElapsedSeconds", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateCurrentEntryElapsedSeconds", + "params": [ + { "paramname":"nValue", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateCurrentEntryCoverArt", + "methodname_flat": "SteamAPI_ISteamMusicRemote_UpdateCurrentEntryCoverArt", + "params": [ + { "paramname":"pvBuffer", "paramtype":"void *" }, + { "paramname":"cbBufferLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "CurrentEntryDidChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_CurrentEntryDidChange", + "params": [], + "returntype": "bool" + }, + { + "methodname": "QueueWillChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_QueueWillChange", + "params": [], + "returntype": "bool" + }, + { + "methodname": "ResetQueueEntries", + "methodname_flat": "SteamAPI_ISteamMusicRemote_ResetQueueEntries", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetQueueEntry", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetQueueEntry", + "params": [ + { "paramname":"nID", "paramtype":"int" }, + { "paramname":"nPosition", "paramtype":"int" }, + { "paramname":"pchEntryText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetCurrentQueueEntry", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetCurrentQueueEntry", + "params": [ + { "paramname":"nID", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "QueueDidChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_QueueDidChange", + "params": [], + "returntype": "bool" + }, + { + "methodname": "PlaylistWillChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_PlaylistWillChange", + "params": [], + "returntype": "bool" + }, + { + "methodname": "ResetPlaylistEntries", + "methodname_flat": "SteamAPI_ISteamMusicRemote_ResetPlaylistEntries", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetPlaylistEntry", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetPlaylistEntry", + "params": [ + { "paramname":"nID", "paramtype":"int" }, + { "paramname":"nPosition", "paramtype":"int" }, + { "paramname":"pchEntryText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetCurrentPlaylistEntry", + "methodname_flat": "SteamAPI_ISteamMusicRemote_SetCurrentPlaylistEntry", + "params": [ + { "paramname":"nID", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "PlaylistDidChange", + "methodname_flat": "SteamAPI_ISteamMusicRemote_PlaylistDidChange", + "params": [], + "returntype": "bool" + } + ], + "version_string": "STEAMMUSICREMOTE_INTERFACE_VERSION001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamHTTP", + "name_flat": "SteamAPI_SteamHTTP_v003" + }, + { + "kind": "gameserver", + "name": "SteamGameServerHTTP", + "name_flat": "SteamAPI_SteamGameServerHTTP_v003" + } + ], + "classname": "ISteamHTTP", + "fields": [], + "methods": [ + { + "methodname": "CreateHTTPRequest", + "methodname_flat": "SteamAPI_ISteamHTTP_CreateHTTPRequest", + "params": [ + { "paramname":"eHTTPRequestMethod", "paramtype":"EHTTPMethod" }, + { "paramname":"pchAbsoluteURL", "paramtype":"const char *" } + ], + "returntype": "HTTPRequestHandle" + }, + { + "methodname": "SetHTTPRequestContextValue", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestContextValue", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"ulContextValue", "paramtype":"uint64" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestNetworkActivityTimeout", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestNetworkActivityTimeout", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"unTimeoutSeconds", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestHeaderValue", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestHeaderValue", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchHeaderName", "paramtype":"const char *" }, + { "paramname":"pchHeaderValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestGetOrPostParameter", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestGetOrPostParameter", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchParamName", "paramtype":"const char *" }, + { "paramname":"pchParamValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SendHTTPRequest", + "methodname_flat": "SteamAPI_ISteamHTTP_SendHTTPRequest", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pCallHandle", "paramtype":"SteamAPICall_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "SendHTTPRequestAndStreamResponse", + "methodname_flat": "SteamAPI_ISteamHTTP_SendHTTPRequestAndStreamResponse", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pCallHandle", "paramtype":"SteamAPICall_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "DeferHTTPRequest", + "methodname_flat": "SteamAPI_ISteamHTTP_DeferHTTPRequest", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" } + ], + "returntype": "bool" + }, + { + "methodname": "PrioritizeHTTPRequest", + "methodname_flat": "SteamAPI_ISteamHTTP_PrioritizeHTTPRequest", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPResponseHeaderSize", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPResponseHeaderSize", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchHeaderName", "paramtype":"const char *" }, + { "paramname":"unResponseHeaderSize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPResponseHeaderValue", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPResponseHeaderValue", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchHeaderName", "paramtype":"const char *" }, + { "paramname":"pHeaderValueBuffer", "paramtype":"uint8 *" }, + { "paramname":"unBufferSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPResponseBodySize", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPResponseBodySize", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"unBodySize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPResponseBodyData", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPResponseBodyData", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pBodyDataBuffer", "paramtype":"uint8 *" }, + { "paramname":"unBufferSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPStreamingResponseBodyData", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPStreamingResponseBodyData", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"cOffset", "paramtype":"uint32" }, + { "paramname":"pBodyDataBuffer", "paramtype":"uint8 *" }, + { "paramname":"unBufferSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "ReleaseHTTPRequest", + "methodname_flat": "SteamAPI_ISteamHTTP_ReleaseHTTPRequest", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPDownloadProgressPct", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPDownloadProgressPct", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pflPercentOut", "paramtype":"float *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestRawPostBody", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestRawPostBody", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchContentType", "paramtype":"const char *" }, + { "paramname":"pubBody", "paramtype":"uint8 *" }, + { "paramname":"unBodyLen", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "CreateCookieContainer", + "methodname_flat": "SteamAPI_ISteamHTTP_CreateCookieContainer", + "params": [ + { "paramname":"bAllowResponsesToModify", "paramtype":"bool" } + ], + "returntype": "HTTPCookieContainerHandle" + }, + { + "methodname": "ReleaseCookieContainer", + "methodname_flat": "SteamAPI_ISteamHTTP_ReleaseCookieContainer", + "params": [ + { "paramname":"hCookieContainer", "paramtype":"HTTPCookieContainerHandle" } + ], + "returntype": "bool" + }, + { + "methodname": "SetCookie", + "methodname_flat": "SteamAPI_ISteamHTTP_SetCookie", + "params": [ + { "paramname":"hCookieContainer", "paramtype":"HTTPCookieContainerHandle" }, + { "paramname":"pchHost", "paramtype":"const char *" }, + { "paramname":"pchUrl", "paramtype":"const char *" }, + { "paramname":"pchCookie", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestCookieContainer", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestCookieContainer", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"hCookieContainer", "paramtype":"HTTPCookieContainerHandle" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestUserAgentInfo", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestUserAgentInfo", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pchUserAgentInfo", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestRequiresVerifiedCertificate", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestRequiresVerifiedCertificate", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"bRequireVerifiedCertificate", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetHTTPRequestAbsoluteTimeoutMS", + "methodname_flat": "SteamAPI_ISteamHTTP_SetHTTPRequestAbsoluteTimeoutMS", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"unMilliseconds", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetHTTPRequestWasTimedOut", + "methodname_flat": "SteamAPI_ISteamHTTP_GetHTTPRequestWasTimedOut", + "params": [ + { "paramname":"hRequest", "paramtype":"HTTPRequestHandle" }, + { "paramname":"pbWasTimedOut", "paramtype":"bool *" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMHTTP_INTERFACE_VERSION003" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamInput", + "name_flat": "SteamAPI_SteamInput_v006" + } + ], + "classname": "ISteamInput", + "fields": [], + "methods": [ + { + "methodname": "Init", + "methodname_flat": "SteamAPI_ISteamInput_Init", + "params": [ + { "paramname":"bExplicitlyCallRunFrame", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "Shutdown", + "methodname_flat": "SteamAPI_ISteamInput_Shutdown", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetInputActionManifestFilePath", + "methodname_flat": "SteamAPI_ISteamInput_SetInputActionManifestFilePath", + "params": [ + { "paramname":"pchInputActionManifestAbsolutePath", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "RunFrame", + "methodname_flat": "SteamAPI_ISteamInput_RunFrame", + "params": [ + { "paramname":"bReservedValue", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "BWaitForData", + "methodname_flat": "SteamAPI_ISteamInput_BWaitForData", + "params": [ + { "paramname":"bWaitForever", "paramtype":"bool" }, + { "paramname":"unTimeout", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "BNewDataAvailable", + "methodname_flat": "SteamAPI_ISteamInput_BNewDataAvailable", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetConnectedControllers", + "methodname_flat": "SteamAPI_ISteamInput_GetConnectedControllers", + "params": [ + { + "desc": "Receives list of connected controllers", + "out_array_count": "STEAM_INPUT_MAX_COUNT", + "paramname": "handlesOut", + "paramtype": "InputHandle_t *" + } + ], + "returntype": "int" + }, + { + "callback": "SteamInputConfigurationLoaded_t", + "methodname": "EnableDeviceCallbacks", + "methodname_flat": "SteamAPI_ISteamInput_EnableDeviceCallbacks", + "params": [], + "returntype": "void" + }, + { + "callback": "SteamInputDeviceDisconnected_t", + "methodname": "EnableActionEventCallbacks", + "methodname_flat": "SteamAPI_ISteamInput_EnableActionEventCallbacks", + "params": [ + { "paramname":"pCallback", "paramtype":"SteamInputActionEventCallbackPointer" } + ], + "returntype": "void" + }, + { + "methodname": "GetActionSetHandle", + "methodname_flat": "SteamAPI_ISteamInput_GetActionSetHandle", + "params": [ + { "paramname":"pszActionSetName", "paramtype":"const char *" } + ], + "returntype": "InputActionSetHandle_t" + }, + { + "methodname": "ActivateActionSet", + "methodname_flat": "SteamAPI_ISteamInput_ActivateActionSet", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"InputActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetCurrentActionSet", + "methodname_flat": "SteamAPI_ISteamInput_GetCurrentActionSet", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "InputActionSetHandle_t" + }, + { + "methodname": "ActivateActionSetLayer", + "methodname_flat": "SteamAPI_ISteamInput_ActivateActionSetLayer", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"actionSetLayerHandle", "paramtype":"InputActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "DeactivateActionSetLayer", + "methodname_flat": "SteamAPI_ISteamInput_DeactivateActionSetLayer", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"actionSetLayerHandle", "paramtype":"InputActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "DeactivateAllActionSetLayers", + "methodname_flat": "SteamAPI_ISteamInput_DeactivateAllActionSetLayers", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetActiveActionSetLayers", + "methodname_flat": "SteamAPI_ISteamInput_GetActiveActionSetLayers", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { + "desc": "Receives list of active layers", + "out_array_count": "STEAM_INPUT_MAX_ACTIVE_LAYERS", + "paramname": "handlesOut", + "paramtype": "InputActionSetHandle_t *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetDigitalActionHandle", + "methodname_flat": "SteamAPI_ISteamInput_GetDigitalActionHandle", + "params": [ + { "paramname":"pszActionName", "paramtype":"const char *" } + ], + "returntype": "InputDigitalActionHandle_t" + }, + { + "methodname": "GetDigitalActionData", + "methodname_flat": "SteamAPI_ISteamInput_GetDigitalActionData", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"digitalActionHandle", "paramtype":"InputDigitalActionHandle_t" } + ], + "returntype": "InputDigitalActionData_t" + }, + { + "methodname": "GetDigitalActionOrigins", + "methodname_flat": "SteamAPI_ISteamInput_GetDigitalActionOrigins", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"InputActionSetHandle_t" }, + { "paramname":"digitalActionHandle", "paramtype":"InputDigitalActionHandle_t" }, + { + "desc": "Receives list of action origins", + "out_array_count": "STEAM_INPUT_MAX_ORIGINS", + "paramname": "originsOut", + "paramtype": "EInputActionOrigin *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetStringForDigitalActionName", + "methodname_flat": "SteamAPI_ISteamInput_GetStringForDigitalActionName", + "params": [ + { "paramname":"eActionHandle", "paramtype":"InputDigitalActionHandle_t" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetAnalogActionHandle", + "methodname_flat": "SteamAPI_ISteamInput_GetAnalogActionHandle", + "params": [ + { "paramname":"pszActionName", "paramtype":"const char *" } + ], + "returntype": "InputAnalogActionHandle_t" + }, + { + "methodname": "GetAnalogActionData", + "methodname_flat": "SteamAPI_ISteamInput_GetAnalogActionData", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"analogActionHandle", "paramtype":"InputAnalogActionHandle_t" } + ], + "returntype": "InputAnalogActionData_t" + }, + { + "methodname": "GetAnalogActionOrigins", + "methodname_flat": "SteamAPI_ISteamInput_GetAnalogActionOrigins", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"InputActionSetHandle_t" }, + { "paramname":"analogActionHandle", "paramtype":"InputAnalogActionHandle_t" }, + { + "desc": "Receives list of action origins", + "out_array_count": "STEAM_INPUT_MAX_ORIGINS", + "paramname": "originsOut", + "paramtype": "EInputActionOrigin *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetGlyphPNGForActionOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetGlyphPNGForActionOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EInputActionOrigin" }, + { "paramname":"eSize", "paramtype":"ESteamInputGlyphSize" }, + { "paramname":"unFlags", "paramtype":"uint32" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetGlyphSVGForActionOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetGlyphSVGForActionOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EInputActionOrigin" }, + { "paramname":"unFlags", "paramtype":"uint32" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetGlyphForActionOrigin_Legacy", + "methodname_flat": "SteamAPI_ISteamInput_GetGlyphForActionOrigin_Legacy", + "params": [ + { "paramname":"eOrigin", "paramtype":"EInputActionOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetStringForActionOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetStringForActionOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EInputActionOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetStringForAnalogActionName", + "methodname_flat": "SteamAPI_ISteamInput_GetStringForAnalogActionName", + "params": [ + { "paramname":"eActionHandle", "paramtype":"InputAnalogActionHandle_t" } + ], + "returntype": "const char *" + }, + { + "methodname": "StopAnalogActionMomentum", + "methodname_flat": "SteamAPI_ISteamInput_StopAnalogActionMomentum", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"eAction", "paramtype":"InputAnalogActionHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetMotionData", + "methodname_flat": "SteamAPI_ISteamInput_GetMotionData", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "InputMotionData_t" + }, + { + "methodname": "TriggerVibration", + "methodname_flat": "SteamAPI_ISteamInput_TriggerVibration", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"usLeftSpeed", "paramtype":"unsigned short" }, + { "paramname":"usRightSpeed", "paramtype":"unsigned short" } + ], + "returntype": "void" + }, + { + "methodname": "TriggerVibrationExtended", + "methodname_flat": "SteamAPI_ISteamInput_TriggerVibrationExtended", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"usLeftSpeed", "paramtype":"unsigned short" }, + { "paramname":"usRightSpeed", "paramtype":"unsigned short" }, + { "paramname":"usLeftTriggerSpeed", "paramtype":"unsigned short" }, + { "paramname":"usRightTriggerSpeed", "paramtype":"unsigned short" } + ], + "returntype": "void" + }, + { + "methodname": "TriggerSimpleHapticEvent", + "methodname_flat": "SteamAPI_ISteamInput_TriggerSimpleHapticEvent", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"eHapticLocation", "paramtype":"EControllerHapticLocation" }, + { "paramname":"nIntensity", "paramtype":"uint8" }, + { "paramname":"nGainDB", "paramtype":"char" }, + { "paramname":"nOtherIntensity", "paramtype":"uint8" }, + { "paramname":"nOtherGainDB", "paramtype":"char" } + ], + "returntype": "void" + }, + { + "methodname": "SetLEDColor", + "methodname_flat": "SteamAPI_ISteamInput_SetLEDColor", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"nColorR", "paramtype":"uint8" }, + { "paramname":"nColorG", "paramtype":"uint8" }, + { "paramname":"nColorB", "paramtype":"uint8" }, + { "paramname":"nFlags", "paramtype":"unsigned int" } + ], + "returntype": "void" + }, + { + "methodname": "Legacy_TriggerHapticPulse", + "methodname_flat": "SteamAPI_ISteamInput_Legacy_TriggerHapticPulse", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"eTargetPad", "paramtype":"ESteamControllerPad" }, + { "paramname":"usDurationMicroSec", "paramtype":"unsigned short" } + ], + "returntype": "void" + }, + { + "methodname": "Legacy_TriggerRepeatedHapticPulse", + "methodname_flat": "SteamAPI_ISteamInput_Legacy_TriggerRepeatedHapticPulse", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"eTargetPad", "paramtype":"ESteamControllerPad" }, + { "paramname":"usDurationMicroSec", "paramtype":"unsigned short" }, + { "paramname":"usOffMicroSec", "paramtype":"unsigned short" }, + { "paramname":"unRepeat", "paramtype":"unsigned short" }, + { "paramname":"nFlags", "paramtype":"unsigned int" } + ], + "returntype": "void" + }, + { + "methodname": "ShowBindingPanel", + "methodname_flat": "SteamAPI_ISteamInput_ShowBindingPanel", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetInputTypeForHandle", + "methodname_flat": "SteamAPI_ISteamInput_GetInputTypeForHandle", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "ESteamInputType" + }, + { + "methodname": "GetControllerForGamepadIndex", + "methodname_flat": "SteamAPI_ISteamInput_GetControllerForGamepadIndex", + "params": [ + { "paramname":"nIndex", "paramtype":"int" } + ], + "returntype": "InputHandle_t" + }, + { + "methodname": "GetGamepadIndexForController", + "methodname_flat": "SteamAPI_ISteamInput_GetGamepadIndexForController", + "params": [ + { "paramname":"ulinputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "int" + }, + { + "methodname": "GetStringForXboxOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetStringForXboxOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetGlyphForXboxOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetGlyphForXboxOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetActionOriginFromXboxOrigin", + "methodname_flat": "SteamAPI_ISteamInput_GetActionOriginFromXboxOrigin", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "EInputActionOrigin" + }, + { + "methodname": "TranslateActionOrigin", + "methodname_flat": "SteamAPI_ISteamInput_TranslateActionOrigin", + "params": [ + { "paramname":"eDestinationInputType", "paramtype":"ESteamInputType" }, + { "paramname":"eSourceOrigin", "paramtype":"EInputActionOrigin" } + ], + "returntype": "EInputActionOrigin" + }, + { + "methodname": "GetDeviceBindingRevision", + "methodname_flat": "SteamAPI_ISteamInput_GetDeviceBindingRevision", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"pMajor", "paramtype":"int *" }, + { "paramname":"pMinor", "paramtype":"int *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetRemotePlaySessionID", + "methodname_flat": "SteamAPI_ISteamInput_GetRemotePlaySessionID", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetSessionInputConfigurationSettings", + "methodname_flat": "SteamAPI_ISteamInput_GetSessionInputConfigurationSettings", + "params": [], + "returntype": "uint16" + }, + { + "methodname": "SetDualSenseTriggerEffect", + "methodname_flat": "SteamAPI_ISteamInput_SetDualSenseTriggerEffect", + "params": [ + { "paramname":"inputHandle", "paramtype":"InputHandle_t" }, + { "paramname":"pParam", "paramtype":"const ScePadTriggerEffectParam *" } + ], + "returntype": "void" + } + ], + "version_string": "SteamInput006" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamController", + "name_flat": "SteamAPI_SteamController_v008" + } + ], + "classname": "ISteamController", + "fields": [], + "methods": [ + { + "methodname": "Init", + "methodname_flat": "SteamAPI_ISteamController_Init", + "params": [], + "returntype": "bool" + }, + { + "methodname": "Shutdown", + "methodname_flat": "SteamAPI_ISteamController_Shutdown", + "params": [], + "returntype": "bool" + }, + { + "methodname": "RunFrame", + "methodname_flat": "SteamAPI_ISteamController_RunFrame", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetConnectedControllers", + "methodname_flat": "SteamAPI_ISteamController_GetConnectedControllers", + "params": [ + { + "desc": "Receives list of connected controllers", + "out_array_count": "STEAM_CONTROLLER_MAX_COUNT", + "paramname": "handlesOut", + "paramtype": "ControllerHandle_t *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetActionSetHandle", + "methodname_flat": "SteamAPI_ISteamController_GetActionSetHandle", + "params": [ + { "paramname":"pszActionSetName", "paramtype":"const char *" } + ], + "returntype": "ControllerActionSetHandle_t" + }, + { + "methodname": "ActivateActionSet", + "methodname_flat": "SteamAPI_ISteamController_ActivateActionSet", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"ControllerActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetCurrentActionSet", + "methodname_flat": "SteamAPI_ISteamController_GetCurrentActionSet", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "ControllerActionSetHandle_t" + }, + { + "methodname": "ActivateActionSetLayer", + "methodname_flat": "SteamAPI_ISteamController_ActivateActionSetLayer", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"actionSetLayerHandle", "paramtype":"ControllerActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "DeactivateActionSetLayer", + "methodname_flat": "SteamAPI_ISteamController_DeactivateActionSetLayer", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"actionSetLayerHandle", "paramtype":"ControllerActionSetHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "DeactivateAllActionSetLayers", + "methodname_flat": "SteamAPI_ISteamController_DeactivateAllActionSetLayers", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetActiveActionSetLayers", + "methodname_flat": "SteamAPI_ISteamController_GetActiveActionSetLayers", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { + "desc": "Receives list of active layers", + "out_array_count": "STEAM_CONTROLLER_MAX_ACTIVE_LAYERS", + "paramname": "handlesOut", + "paramtype": "ControllerActionSetHandle_t *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetDigitalActionHandle", + "methodname_flat": "SteamAPI_ISteamController_GetDigitalActionHandle", + "params": [ + { "paramname":"pszActionName", "paramtype":"const char *" } + ], + "returntype": "ControllerDigitalActionHandle_t" + }, + { + "methodname": "GetDigitalActionData", + "methodname_flat": "SteamAPI_ISteamController_GetDigitalActionData", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"digitalActionHandle", "paramtype":"ControllerDigitalActionHandle_t" } + ], + "returntype": "InputDigitalActionData_t" + }, + { + "methodname": "GetDigitalActionOrigins", + "methodname_flat": "SteamAPI_ISteamController_GetDigitalActionOrigins", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"ControllerActionSetHandle_t" }, + { "paramname":"digitalActionHandle", "paramtype":"ControllerDigitalActionHandle_t" }, + { + "desc": "Receives list of aciton origins", + "out_array_count": "STEAM_CONTROLLER_MAX_ORIGINS", + "paramname": "originsOut", + "paramtype": "EControllerActionOrigin *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetAnalogActionHandle", + "methodname_flat": "SteamAPI_ISteamController_GetAnalogActionHandle", + "params": [ + { "paramname":"pszActionName", "paramtype":"const char *" } + ], + "returntype": "ControllerAnalogActionHandle_t" + }, + { + "methodname": "GetAnalogActionData", + "methodname_flat": "SteamAPI_ISteamController_GetAnalogActionData", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"analogActionHandle", "paramtype":"ControllerAnalogActionHandle_t" } + ], + "returntype": "InputAnalogActionData_t" + }, + { + "methodname": "GetAnalogActionOrigins", + "methodname_flat": "SteamAPI_ISteamController_GetAnalogActionOrigins", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"actionSetHandle", "paramtype":"ControllerActionSetHandle_t" }, + { "paramname":"analogActionHandle", "paramtype":"ControllerAnalogActionHandle_t" }, + { + "desc": "Receives list of action origins", + "out_array_count": "STEAM_CONTROLLER_MAX_ORIGINS", + "paramname": "originsOut", + "paramtype": "EControllerActionOrigin *" + } + ], + "returntype": "int" + }, + { + "methodname": "GetGlyphForActionOrigin", + "methodname_flat": "SteamAPI_ISteamController_GetGlyphForActionOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EControllerActionOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetStringForActionOrigin", + "methodname_flat": "SteamAPI_ISteamController_GetStringForActionOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EControllerActionOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "StopAnalogActionMomentum", + "methodname_flat": "SteamAPI_ISteamController_StopAnalogActionMomentum", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"eAction", "paramtype":"ControllerAnalogActionHandle_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetMotionData", + "methodname_flat": "SteamAPI_ISteamController_GetMotionData", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "InputMotionData_t" + }, + { + "methodname": "TriggerHapticPulse", + "methodname_flat": "SteamAPI_ISteamController_TriggerHapticPulse", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"eTargetPad", "paramtype":"ESteamControllerPad" }, + { "paramname":"usDurationMicroSec", "paramtype":"unsigned short" } + ], + "returntype": "void" + }, + { + "methodname": "TriggerRepeatedHapticPulse", + "methodname_flat": "SteamAPI_ISteamController_TriggerRepeatedHapticPulse", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"eTargetPad", "paramtype":"ESteamControllerPad" }, + { "paramname":"usDurationMicroSec", "paramtype":"unsigned short" }, + { "paramname":"usOffMicroSec", "paramtype":"unsigned short" }, + { "paramname":"unRepeat", "paramtype":"unsigned short" }, + { "paramname":"nFlags", "paramtype":"unsigned int" } + ], + "returntype": "void" + }, + { + "methodname": "TriggerVibration", + "methodname_flat": "SteamAPI_ISteamController_TriggerVibration", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"usLeftSpeed", "paramtype":"unsigned short" }, + { "paramname":"usRightSpeed", "paramtype":"unsigned short" } + ], + "returntype": "void" + }, + { + "methodname": "SetLEDColor", + "methodname_flat": "SteamAPI_ISteamController_SetLEDColor", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"nColorR", "paramtype":"uint8" }, + { "paramname":"nColorG", "paramtype":"uint8" }, + { "paramname":"nColorB", "paramtype":"uint8" }, + { "paramname":"nFlags", "paramtype":"unsigned int" } + ], + "returntype": "void" + }, + { + "methodname": "ShowBindingPanel", + "methodname_flat": "SteamAPI_ISteamController_ShowBindingPanel", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetInputTypeForHandle", + "methodname_flat": "SteamAPI_ISteamController_GetInputTypeForHandle", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "ESteamInputType" + }, + { + "methodname": "GetControllerForGamepadIndex", + "methodname_flat": "SteamAPI_ISteamController_GetControllerForGamepadIndex", + "params": [ + { "paramname":"nIndex", "paramtype":"int" } + ], + "returntype": "ControllerHandle_t" + }, + { + "methodname": "GetGamepadIndexForController", + "methodname_flat": "SteamAPI_ISteamController_GetGamepadIndexForController", + "params": [ + { "paramname":"ulControllerHandle", "paramtype":"ControllerHandle_t" } + ], + "returntype": "int" + }, + { + "methodname": "GetStringForXboxOrigin", + "methodname_flat": "SteamAPI_ISteamController_GetStringForXboxOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetGlyphForXboxOrigin", + "methodname_flat": "SteamAPI_ISteamController_GetGlyphForXboxOrigin", + "params": [ + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetActionOriginFromXboxOrigin", + "methodname_flat": "SteamAPI_ISteamController_GetActionOriginFromXboxOrigin", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"eOrigin", "paramtype":"EXboxOrigin" } + ], + "returntype": "EControllerActionOrigin" + }, + { + "methodname": "TranslateActionOrigin", + "methodname_flat": "SteamAPI_ISteamController_TranslateActionOrigin", + "params": [ + { "paramname":"eDestinationInputType", "paramtype":"ESteamInputType" }, + { "paramname":"eSourceOrigin", "paramtype":"EControllerActionOrigin" } + ], + "returntype": "EControllerActionOrigin" + }, + { + "methodname": "GetControllerBindingRevision", + "methodname_flat": "SteamAPI_ISteamController_GetControllerBindingRevision", + "params": [ + { "paramname":"controllerHandle", "paramtype":"ControllerHandle_t" }, + { "paramname":"pMajor", "paramtype":"int *" }, + { "paramname":"pMinor", "paramtype":"int *" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamController008" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamUGC", + "name_flat": "SteamAPI_SteamUGC_v016" + }, + { + "kind": "gameserver", + "name": "SteamGameServerUGC", + "name_flat": "SteamAPI_SteamGameServerUGC_v016" + } + ], + "classname": "ISteamUGC", + "fields": [], + "methods": [ + { + "methodname": "CreateQueryUserUGCRequest", + "methodname_flat": "SteamAPI_ISteamUGC_CreateQueryUserUGCRequest", + "params": [ + { "paramname":"unAccountID", "paramtype":"AccountID_t" }, + { "paramname":"eListType", "paramtype":"EUserUGCList" }, + { "paramname":"eMatchingUGCType", "paramtype":"EUGCMatchingUGCType" }, + { "paramname":"eSortOrder", "paramtype":"EUserUGCListSortOrder" }, + { "paramname":"nCreatorAppID", "paramtype":"AppId_t" }, + { "paramname":"nConsumerAppID", "paramtype":"AppId_t" }, + { "paramname":"unPage", "paramtype":"uint32" } + ], + "returntype": "UGCQueryHandle_t" + }, + { + "methodname": "CreateQueryAllUGCRequest", + "methodname_flat": "SteamAPI_ISteamUGC_CreateQueryAllUGCRequestPage", + "params": [ + { "paramname":"eQueryType", "paramtype":"EUGCQuery" }, + { "paramname":"eMatchingeMatchingUGCTypeFileType", "paramtype":"EUGCMatchingUGCType" }, + { "paramname":"nCreatorAppID", "paramtype":"AppId_t" }, + { "paramname":"nConsumerAppID", "paramtype":"AppId_t" }, + { "paramname":"unPage", "paramtype":"uint32" } + ], + "returntype": "UGCQueryHandle_t" + }, + { + "methodname": "CreateQueryAllUGCRequest", + "methodname_flat": "SteamAPI_ISteamUGC_CreateQueryAllUGCRequestCursor", + "params": [ + { "paramname":"eQueryType", "paramtype":"EUGCQuery" }, + { "paramname":"eMatchingeMatchingUGCTypeFileType", "paramtype":"EUGCMatchingUGCType" }, + { "paramname":"nCreatorAppID", "paramtype":"AppId_t" }, + { "paramname":"nConsumerAppID", "paramtype":"AppId_t" }, + { "paramname":"pchCursor", "paramtype":"const char *" } + ], + "returntype": "UGCQueryHandle_t" + }, + { + "methodname": "CreateQueryUGCDetailsRequest", + "methodname_flat": "SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest", + "params": [ + { "paramname":"pvecPublishedFileID", "paramtype":"PublishedFileId_t *" }, + { "paramname":"unNumPublishedFileIDs", "paramtype":"uint32" } + ], + "returntype": "UGCQueryHandle_t" + }, + { + "callresult": "SteamUGCQueryCompleted_t", + "methodname": "SendQueryUGCRequest", + "methodname_flat": "SteamAPI_ISteamUGC_SendQueryUGCRequest", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetQueryUGCResult", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCResult", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"pDetails", "paramtype":"SteamUGCDetails_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCNumTags", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCNumTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetQueryUGCTag", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"indexTag", "paramtype":"uint32" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCTagDisplayName", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCTagDisplayName", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"indexTag", "paramtype":"uint32" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCPreviewURL", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCPreviewURL", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { + "out_string_count": "cchURLSize", + "paramname": "pchURL", + "paramtype": "char *" + }, + { "paramname":"cchURLSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCMetadata", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCMetadata", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { + "out_string_count": "cchMetadatasize", + "paramname": "pchMetadata", + "paramtype": "char *" + }, + { "paramname":"cchMetadatasize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCChildren", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCChildren", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"pvecPublishedFileID", "paramtype":"PublishedFileId_t *" }, + { "paramname":"cMaxEntries", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCStatistic", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCStatistic", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"eStatType", "paramtype":"EItemStatistic" }, + { "paramname":"pStatValue", "paramtype":"uint64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCNumAdditionalPreviews", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetQueryUGCAdditionalPreview", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"previewIndex", "paramtype":"uint32" }, + { + "out_string_count": "cchURLSize", + "paramname": "pchURLOrVideoID", + "paramtype": "char *" + }, + { "paramname":"cchURLSize", "paramtype":"uint32" }, + { + "out_string_count": "cchURLSize", + "paramname": "pchOriginalFileName", + "paramtype": "char *" + }, + { "paramname":"cchOriginalFileNameSize", "paramtype":"uint32" }, + { "paramname":"pPreviewType", "paramtype":"EItemPreviewType *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCNumKeyValueTags", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetQueryUGCKeyValueTag", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"keyValueTagIndex", "paramtype":"uint32" }, + { + "out_string_count": "cchKeySize", + "paramname": "pchKey", + "paramtype": "char *" + }, + { "paramname":"cchKeySize", "paramtype":"uint32" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCKeyValueTag", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryFirstUGCKeyValueTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "ReleaseQueryUGCRequest", + "methodname_flat": "SteamAPI_ISteamUGC_ReleaseQueryUGCRequest", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "AddRequiredTag", + "methodname_flat": "SteamAPI_ISteamUGC_AddRequiredTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pTagName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddRequiredTagGroup", + "methodname_flat": "SteamAPI_ISteamUGC_AddRequiredTagGroup", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pTagGroups", "paramtype":"const SteamParamStringArray_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddExcludedTag", + "methodname_flat": "SteamAPI_ISteamUGC_AddExcludedTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pTagName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnOnlyIDs", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnOnlyIDs", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnOnlyIDs", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnKeyValueTags", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnKeyValueTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnKeyValueTags", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnLongDescription", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnLongDescription", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnLongDescription", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnMetadata", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnMetadata", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnMetadata", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnChildren", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnChildren", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnChildren", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnAdditionalPreviews", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnAdditionalPreviews", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnAdditionalPreviews", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnTotalOnly", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnTotalOnly", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bReturnTotalOnly", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetReturnPlaytimeStats", + "methodname_flat": "SteamAPI_ISteamUGC_SetReturnPlaytimeStats", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"unDays", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetLanguage", + "methodname_flat": "SteamAPI_ISteamUGC_SetLanguage", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pchLanguage", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetAllowCachedResponse", + "methodname_flat": "SteamAPI_ISteamUGC_SetAllowCachedResponse", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"unMaxAgeSeconds", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetCloudFileNameFilter", + "methodname_flat": "SteamAPI_ISteamUGC_SetCloudFileNameFilter", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pMatchCloudFileName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetMatchAnyTag", + "methodname_flat": "SteamAPI_ISteamUGC_SetMatchAnyTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"bMatchAnyTag", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetSearchText", + "methodname_flat": "SteamAPI_ISteamUGC_SetSearchText", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pSearchText", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetRankedByTrendDays", + "methodname_flat": "SteamAPI_ISteamUGC_SetRankedByTrendDays", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"unDays", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetTimeCreatedDateRange", + "methodname_flat": "SteamAPI_ISteamUGC_SetTimeCreatedDateRange", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"rtStart", "paramtype":"RTime32" }, + { "paramname":"rtEnd", "paramtype":"RTime32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetTimeUpdatedDateRange", + "methodname_flat": "SteamAPI_ISteamUGC_SetTimeUpdatedDateRange", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"rtStart", "paramtype":"RTime32" }, + { "paramname":"rtEnd", "paramtype":"RTime32" } + ], + "returntype": "bool" + }, + { + "methodname": "AddRequiredKeyValueTag", + "methodname_flat": "SteamAPI_ISteamUGC_AddRequiredKeyValueTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"pKey", "paramtype":"const char *" }, + { "paramname":"pValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "callresult": "SteamUGCRequestUGCDetailsResult_t", + "methodname": "RequestUGCDetails", + "methodname_flat": "SteamAPI_ISteamUGC_RequestUGCDetails", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"unMaxAgeSeconds", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "CreateItemResult_t", + "methodname": "CreateItem", + "methodname_flat": "SteamAPI_ISteamUGC_CreateItem", + "params": [ + { "paramname":"nConsumerAppId", "paramtype":"AppId_t" }, + { "paramname":"eFileType", "paramtype":"EWorkshopFileType" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "StartItemUpdate", + "methodname_flat": "SteamAPI_ISteamUGC_StartItemUpdate", + "params": [ + { "paramname":"nConsumerAppId", "paramtype":"AppId_t" }, + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "UGCUpdateHandle_t" + }, + { + "methodname": "SetItemTitle", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemTitle", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchTitle", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemDescription", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemDescription", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchDescription", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemUpdateLanguage", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemUpdateLanguage", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchLanguage", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemMetadata", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemMetadata", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchMetaData", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemVisibility", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemVisibility", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"eVisibility", "paramtype":"ERemoteStoragePublishedFileVisibility" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemTags", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemTags", + "params": [ + { "paramname":"updateHandle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pTags", "paramtype":"const SteamParamStringArray_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemContent", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemContent", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pszContentFolder", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetItemPreview", + "methodname_flat": "SteamAPI_ISteamUGC_SetItemPreview", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pszPreviewFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetAllowLegacyUpload", + "methodname_flat": "SteamAPI_ISteamUGC_SetAllowLegacyUpload", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"bAllowLegacyUpload", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "RemoveAllItemKeyValueTags", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveAllItemKeyValueTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" } + ], + "returntype": "bool" + }, + { + "methodname": "RemoveItemKeyValueTags", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveItemKeyValueTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchKey", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddItemKeyValueTag", + "methodname_flat": "SteamAPI_ISteamUGC_AddItemKeyValueTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddItemPreviewFile", + "methodname_flat": "SteamAPI_ISteamUGC_AddItemPreviewFile", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pszPreviewFile", "paramtype":"const char *" }, + { "paramname":"type", "paramtype":"EItemPreviewType" } + ], + "returntype": "bool" + }, + { + "methodname": "AddItemPreviewVideo", + "methodname_flat": "SteamAPI_ISteamUGC_AddItemPreviewVideo", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pszVideoID", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateItemPreviewFile", + "methodname_flat": "SteamAPI_ISteamUGC_UpdateItemPreviewFile", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"pszPreviewFile", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateItemPreviewVideo", + "methodname_flat": "SteamAPI_ISteamUGC_UpdateItemPreviewVideo", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"pszVideoID", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "RemoveItemPreview", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveItemPreview", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"index", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "callresult": "SubmitItemUpdateResult_t", + "methodname": "SubmitItemUpdate", + "methodname_flat": "SteamAPI_ISteamUGC_SubmitItemUpdate", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"pchChangeNote", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetItemUpdateProgress", + "methodname_flat": "SteamAPI_ISteamUGC_GetItemUpdateProgress", + "params": [ + { "paramname":"handle", "paramtype":"UGCUpdateHandle_t" }, + { "paramname":"punBytesProcessed", "paramtype":"uint64 *" }, + { "paramname":"punBytesTotal", "paramtype":"uint64 *" } + ], + "returntype": "EItemUpdateStatus" + }, + { + "callresult": "SetUserItemVoteResult_t", + "methodname": "SetUserItemVote", + "methodname_flat": "SteamAPI_ISteamUGC_SetUserItemVote", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"bVoteUp", "paramtype":"bool" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "GetUserItemVoteResult_t", + "methodname": "GetUserItemVote", + "methodname_flat": "SteamAPI_ISteamUGC_GetUserItemVote", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "UserFavoriteItemsListChanged_t", + "methodname": "AddItemToFavorites", + "methodname_flat": "SteamAPI_ISteamUGC_AddItemToFavorites", + "params": [ + { "paramname":"nAppId", "paramtype":"AppId_t" }, + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "UserFavoriteItemsListChanged_t", + "methodname": "RemoveItemFromFavorites", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveItemFromFavorites", + "params": [ + { "paramname":"nAppId", "paramtype":"AppId_t" }, + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageSubscribePublishedFileResult_t", + "methodname": "SubscribeItem", + "methodname_flat": "SteamAPI_ISteamUGC_SubscribeItem", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoteStorageUnsubscribePublishedFileResult_t", + "methodname": "UnsubscribeItem", + "methodname_flat": "SteamAPI_ISteamUGC_UnsubscribeItem", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetNumSubscribedItems", + "methodname_flat": "SteamAPI_ISteamUGC_GetNumSubscribedItems", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetSubscribedItems", + "methodname_flat": "SteamAPI_ISteamUGC_GetSubscribedItems", + "params": [ + { "paramname":"pvecPublishedFileID", "paramtype":"PublishedFileId_t *" }, + { "paramname":"cMaxEntries", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetItemState", + "methodname_flat": "SteamAPI_ISteamUGC_GetItemState", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetItemInstallInfo", + "methodname_flat": "SteamAPI_ISteamUGC_GetItemInstallInfo", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"punSizeOnDisk", "paramtype":"uint64 *" }, + { + "out_string_count": "cchFolderSize", + "paramname": "pchFolder", + "paramtype": "char *" + }, + { "paramname":"cchFolderSize", "paramtype":"uint32" }, + { "paramname":"punTimeStamp", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetItemDownloadInfo", + "methodname_flat": "SteamAPI_ISteamUGC_GetItemDownloadInfo", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"punBytesDownloaded", "paramtype":"uint64 *" }, + { "paramname":"punBytesTotal", "paramtype":"uint64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "DownloadItem", + "methodname_flat": "SteamAPI_ISteamUGC_DownloadItem", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"bHighPriority", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "BInitWorkshopForGameServer", + "methodname_flat": "SteamAPI_ISteamUGC_BInitWorkshopForGameServer", + "params": [ + { "paramname":"unWorkshopDepotID", "paramtype":"DepotId_t" }, + { "paramname":"pszFolder", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SuspendDownloads", + "methodname_flat": "SteamAPI_ISteamUGC_SuspendDownloads", + "params": [ + { "paramname":"bSuspend", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "callresult": "StartPlaytimeTrackingResult_t", + "methodname": "StartPlaytimeTracking", + "methodname_flat": "SteamAPI_ISteamUGC_StartPlaytimeTracking", + "params": [ + { "paramname":"pvecPublishedFileID", "paramtype":"PublishedFileId_t *" }, + { "paramname":"unNumPublishedFileIDs", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "StopPlaytimeTrackingResult_t", + "methodname": "StopPlaytimeTracking", + "methodname_flat": "SteamAPI_ISteamUGC_StopPlaytimeTracking", + "params": [ + { "paramname":"pvecPublishedFileID", "paramtype":"PublishedFileId_t *" }, + { "paramname":"unNumPublishedFileIDs", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "StopPlaytimeTrackingResult_t", + "methodname": "StopPlaytimeTrackingForAllItems", + "methodname_flat": "SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "AddUGCDependencyResult_t", + "methodname": "AddDependency", + "methodname_flat": "SteamAPI_ISteamUGC_AddDependency", + "params": [ + { "paramname":"nParentPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"nChildPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoveUGCDependencyResult_t", + "methodname": "RemoveDependency", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveDependency", + "params": [ + { "paramname":"nParentPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"nChildPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "AddAppDependencyResult_t", + "methodname": "AddAppDependency", + "methodname_flat": "SteamAPI_ISteamUGC_AddAppDependency", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "RemoveAppDependencyResult_t", + "methodname": "RemoveAppDependency", + "methodname_flat": "SteamAPI_ISteamUGC_RemoveAppDependency", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" }, + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "GetAppDependenciesResult_t", + "methodname": "GetAppDependencies", + "methodname_flat": "SteamAPI_ISteamUGC_GetAppDependencies", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "DeleteItemResult_t", + "methodname": "DeleteItem", + "methodname_flat": "SteamAPI_ISteamUGC_DeleteItem", + "params": [ + { "paramname":"nPublishedFileID", "paramtype":"PublishedFileId_t" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "ShowWorkshopEULA", + "methodname_flat": "SteamAPI_ISteamUGC_ShowWorkshopEULA", + "params": [], + "returntype": "bool" + }, + { + "callresult": "WorkshopEULAStatus_t", + "methodname": "GetWorkshopEULAStatus", + "methodname_flat": "SteamAPI_ISteamUGC_GetWorkshopEULAStatus", + "params": [], + "returntype": "SteamAPICall_t" + } + ], + "version_string": "STEAMUGC_INTERFACE_VERSION016" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamAppList", + "name_flat": "SteamAPI_SteamAppList_v001" + } + ], + "classname": "ISteamAppList", + "fields": [], + "methods": [ + { + "methodname": "GetNumInstalledApps", + "methodname_flat": "SteamAPI_ISteamAppList_GetNumInstalledApps", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetInstalledApps", + "methodname_flat": "SteamAPI_ISteamAppList_GetInstalledApps", + "params": [ + { "paramname":"pvecAppID", "paramtype":"AppId_t *" }, + { "paramname":"unMaxAppIDs", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetAppName", + "methodname_flat": "SteamAPI_ISteamAppList_GetAppName", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { + "out_string": "", + "paramname": "pchName", + "paramtype": "char *" + }, + { "paramname":"cchNameMax", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetAppInstallDir", + "methodname_flat": "SteamAPI_ISteamAppList_GetAppInstallDir", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" }, + { "paramname":"pchDirectory", "paramtype":"char *" }, + { "paramname":"cchNameMax", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetAppBuildId", + "methodname_flat": "SteamAPI_ISteamAppList_GetAppBuildId", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "int" + } + ], + "version_string": "STEAMAPPLIST_INTERFACE_VERSION001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamHTMLSurface", + "name_flat": "SteamAPI_SteamHTMLSurface_v005" + } + ], + "classname": "ISteamHTMLSurface", + "enums": [ + { + "enumname": "EHTMLMouseButton", + "fqname": "ISteamHTMLSurface::EHTMLMouseButton", + "values": [ + { "name":"eHTMLMouseButton_Left", "value":"0" }, + { "name":"eHTMLMouseButton_Right", "value":"1" }, + { "name":"eHTMLMouseButton_Middle", "value":"2" } + ] + }, + { + "enumname": "EMouseCursor", + "fqname": "ISteamHTMLSurface::EMouseCursor", + "values": [ + { "name":"dc_user", "value":"0" }, + { "name":"dc_none", "value":"1" }, + { "name":"dc_arrow", "value":"2" }, + { "name":"dc_ibeam", "value":"3" }, + { "name":"dc_hourglass", "value":"4" }, + { "name":"dc_waitarrow", "value":"5" }, + { "name":"dc_crosshair", "value":"6" }, + { "name":"dc_up", "value":"7" }, + { "name":"dc_sizenw", "value":"8" }, + { "name":"dc_sizese", "value":"9" }, + { "name":"dc_sizene", "value":"10" }, + { "name":"dc_sizesw", "value":"11" }, + { "name":"dc_sizew", "value":"12" }, + { "name":"dc_sizee", "value":"13" }, + { "name":"dc_sizen", "value":"14" }, + { "name":"dc_sizes", "value":"15" }, + { "name":"dc_sizewe", "value":"16" }, + { "name":"dc_sizens", "value":"17" }, + { "name":"dc_sizeall", "value":"18" }, + { "name":"dc_no", "value":"19" }, + { "name":"dc_hand", "value":"20" }, + { "name":"dc_blank", "value":"21" }, + { "name":"dc_middle_pan", "value":"22" }, + { "name":"dc_north_pan", "value":"23" }, + { "name":"dc_north_east_pan", "value":"24" }, + { "name":"dc_east_pan", "value":"25" }, + { "name":"dc_south_east_pan", "value":"26" }, + { "name":"dc_south_pan", "value":"27" }, + { "name":"dc_south_west_pan", "value":"28" }, + { "name":"dc_west_pan", "value":"29" }, + { "name":"dc_north_west_pan", "value":"30" }, + { "name":"dc_alias", "value":"31" }, + { "name":"dc_cell", "value":"32" }, + { "name":"dc_colresize", "value":"33" }, + { "name":"dc_copycur", "value":"34" }, + { "name":"dc_verticaltext", "value":"35" }, + { "name":"dc_rowresize", "value":"36" }, + { "name":"dc_zoomin", "value":"37" }, + { "name":"dc_zoomout", "value":"38" }, + { "name":"dc_help", "value":"39" }, + { "name":"dc_custom", "value":"40" }, + { "name":"dc_last", "value":"41" } + ] + }, + { + "enumname": "EHTMLKeyModifiers", + "fqname": "ISteamHTMLSurface::EHTMLKeyModifiers", + "values": [ + { "name":"k_eHTMLKeyModifier_None", "value":"0" }, + { "name":"k_eHTMLKeyModifier_AltDown", "value":"1" }, + { "name":"k_eHTMLKeyModifier_CtrlDown", "value":"2" }, + { "name":"k_eHTMLKeyModifier_ShiftDown", "value":"4" } + ] + } + ], + "fields": [], + "methods": [ + { + "methodname": "Init", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_Init", + "params": [], + "returntype": "bool" + }, + { + "methodname": "Shutdown", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_Shutdown", + "params": [], + "returntype": "bool" + }, + { + "callresult": "HTML_BrowserReady_t", + "methodname": "CreateBrowser", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_CreateBrowser", + "params": [ + { "paramname":"pchUserAgent", "paramtype":"const char *" }, + { "paramname":"pchUserCSS", "paramtype":"const char *" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "RemoveBrowser", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_RemoveBrowser", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "LoadURL", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_LoadURL", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"pchURL", "paramtype":"const char *" }, + { "paramname":"pchPostData", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetSize", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetSize", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"unWidth", "paramtype":"uint32" }, + { "paramname":"unHeight", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "StopLoad", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_StopLoad", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "Reload", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_Reload", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "GoBack", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_GoBack", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "GoForward", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_GoForward", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "AddHeader", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_AddHeader", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "ExecuteJavascript", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_ExecuteJavascript", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"pchScript", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "MouseUp", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_MouseUp", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"eMouseButton", "paramtype":"ISteamHTMLSurface::EHTMLMouseButton" } + ], + "returntype": "void" + }, + { + "methodname": "MouseDown", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_MouseDown", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"eMouseButton", "paramtype":"ISteamHTMLSurface::EHTMLMouseButton" } + ], + "returntype": "void" + }, + { + "methodname": "MouseDoubleClick", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_MouseDoubleClick", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"eMouseButton", "paramtype":"ISteamHTMLSurface::EHTMLMouseButton" } + ], + "returntype": "void" + }, + { + "methodname": "MouseMove", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_MouseMove", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"x", "paramtype":"int" }, + { "paramname":"y", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "MouseWheel", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_MouseWheel", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"nDelta", "paramtype":"int32" } + ], + "returntype": "void" + }, + { + "methodname": "KeyDown", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_KeyDown", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"nNativeKeyCode", "paramtype":"uint32" }, + { "paramname":"eHTMLKeyModifiers", "paramtype":"ISteamHTMLSurface::EHTMLKeyModifiers" }, + { "paramname":"bIsSystemKey", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "KeyUp", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_KeyUp", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"nNativeKeyCode", "paramtype":"uint32" }, + { "paramname":"eHTMLKeyModifiers", "paramtype":"ISteamHTMLSurface::EHTMLKeyModifiers" } + ], + "returntype": "void" + }, + { + "methodname": "KeyChar", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_KeyChar", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"cUnicodeChar", "paramtype":"uint32" }, + { "paramname":"eHTMLKeyModifiers", "paramtype":"ISteamHTMLSurface::EHTMLKeyModifiers" } + ], + "returntype": "void" + }, + { + "methodname": "SetHorizontalScroll", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetHorizontalScroll", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"nAbsolutePixelScroll", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "SetVerticalScroll", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetVerticalScroll", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"nAbsolutePixelScroll", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "SetKeyFocus", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetKeyFocus", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"bHasKeyFocus", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "ViewSource", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_ViewSource", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "CopyToClipboard", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_CopyToClipboard", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "PasteFromClipboard", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_PasteFromClipboard", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "Find", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_Find", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"pchSearchStr", "paramtype":"const char *" }, + { "paramname":"bCurrentlyInFind", "paramtype":"bool" }, + { "paramname":"bReverse", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "StopFind", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_StopFind", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "GetLinkAtPosition", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_GetLinkAtPosition", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"x", "paramtype":"int" }, + { "paramname":"y", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "SetCookie", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetCookie", + "params": [ + { "paramname":"pchHostname", "paramtype":"const char *" }, + { "paramname":"pchKey", "paramtype":"const char *" }, + { "paramname":"pchValue", "paramtype":"const char *" }, + { "paramname":"pchPath", "paramtype":"const char *" }, + { "paramname":"nExpires", "paramtype":"RTime32" }, + { "paramname":"bSecure", "paramtype":"bool" }, + { "paramname":"bHTTPOnly", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "SetPageScaleFactor", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetPageScaleFactor", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"flZoom", "paramtype":"float" }, + { "paramname":"nPointX", "paramtype":"int" }, + { "paramname":"nPointY", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "SetBackgroundMode", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetBackgroundMode", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"bBackgroundMode", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "SetDPIScalingFactor", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_SetDPIScalingFactor", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"flDPIScaling", "paramtype":"float" } + ], + "returntype": "void" + }, + { + "methodname": "OpenDeveloperTools", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_OpenDeveloperTools", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" } + ], + "returntype": "void" + }, + { + "methodname": "AllowStartRequest", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_AllowStartRequest", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"bAllowed", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "JSDialogResponse", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_JSDialogResponse", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"bResult", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "FileLoadDialogResponse", + "methodname_flat": "SteamAPI_ISteamHTMLSurface_FileLoadDialogResponse", + "params": [ + { "paramname":"unBrowserHandle", "paramtype":"HHTMLBrowser" }, + { "paramname":"pchSelectedFiles", "paramtype":"const char **" } + ], + "returntype": "void" + } + ], + "version_string": "STEAMHTMLSURFACE_INTERFACE_VERSION_005" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamInventory", + "name_flat": "SteamAPI_SteamInventory_v003" + }, + { + "kind": "gameserver", + "name": "SteamGameServerInventory", + "name_flat": "SteamAPI_SteamGameServerInventory_v003" + } + ], + "classname": "ISteamInventory", + "fields": [], + "methods": [ + { + "methodname": "GetResultStatus", + "methodname_flat": "SteamAPI_ISteamInventory_GetResultStatus", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" } + ], + "returntype": "EResult" + }, + { + "methodname": "GetResultItems", + "methodname_flat": "SteamAPI_ISteamInventory_GetResultItems", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" }, + { + "desc": "Output array", + "out_array_count": "punOutItemsArraySize", + "paramname": "pOutItemsArray", + "paramtype": "SteamItemDetails_t *" + }, + { "paramname":"punOutItemsArraySize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetResultItemProperty", + "methodname_flat": "SteamAPI_ISteamInventory_GetResultItemProperty", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" }, + { "paramname":"unItemIndex", "paramtype":"uint32" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { + "out_string_count": "punValueBufferSizeOut", + "paramname": "pchValueBuffer", + "paramtype": "char *" + }, + { "paramname":"punValueBufferSizeOut", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetResultTimestamp", + "methodname_flat": "SteamAPI_ISteamInventory_GetResultTimestamp", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" } + ], + "returntype": "uint32" + }, + { + "methodname": "CheckResultSteamID", + "methodname_flat": "SteamAPI_ISteamInventory_CheckResultSteamID", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" }, + { "paramname":"steamIDExpected", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "DestroyResult", + "methodname_flat": "SteamAPI_ISteamInventory_DestroyResult", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetAllItems", + "methodname_flat": "SteamAPI_ISteamInventory_GetAllItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetItemsByID", + "methodname_flat": "SteamAPI_ISteamInventory_GetItemsByID", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { + "array_count": "unCountInstanceIDs", + "paramname": "pInstanceIDs", + "paramtype": "const SteamItemInstanceID_t *" + }, + { "paramname":"unCountInstanceIDs", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "SerializeResult", + "methodname_flat": "SteamAPI_ISteamInventory_SerializeResult", + "params": [ + { "paramname":"resultHandle", "paramtype":"SteamInventoryResult_t" }, + { + "out_buffer_count": "punOutBufferSize", + "paramname": "pOutBuffer", + "paramtype": "void *" + }, + { "paramname":"punOutBufferSize", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "DeserializeResult", + "methodname_flat": "SteamAPI_ISteamInventory_DeserializeResult", + "params": [ + { "paramname":"pOutResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { + "buffer_count": "punOutBufferSize", + "paramname": "pBuffer", + "paramtype": "const void *" + }, + { "paramname":"unBufferSize", "paramtype":"uint32" }, + { "paramname":"bRESERVED_MUST_BE_FALSE", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "GenerateItems", + "methodname_flat": "SteamAPI_ISteamInventory_GenerateItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { + "array_count": "unArrayLength", + "paramname": "pArrayItemDefs", + "paramtype": "const SteamItemDef_t *" + }, + { + "array_count": "unArrayLength", + "paramname": "punArrayQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"unArrayLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GrantPromoItems", + "methodname_flat": "SteamAPI_ISteamInventory_GrantPromoItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "AddPromoItem", + "methodname_flat": "SteamAPI_ISteamInventory_AddPromoItem", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"itemDef", "paramtype":"SteamItemDef_t" } + ], + "returntype": "bool" + }, + { + "methodname": "AddPromoItems", + "methodname_flat": "SteamAPI_ISteamInventory_AddPromoItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { + "array_count": "unArrayLength", + "paramname": "pArrayItemDefs", + "paramtype": "const SteamItemDef_t *" + }, + { "paramname":"unArrayLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "ConsumeItem", + "methodname_flat": "SteamAPI_ISteamInventory_ConsumeItem", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"itemConsume", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"unQuantity", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "ExchangeItems", + "methodname_flat": "SteamAPI_ISteamInventory_ExchangeItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { + "array_count": "unArrayGenerateLength", + "paramname": "pArrayGenerate", + "paramtype": "const SteamItemDef_t *" + }, + { + "array_count": "unArrayGenerateLength", + "paramname": "punArrayGenerateQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"unArrayGenerateLength", "paramtype":"uint32" }, + { + "array_count": "unArrayDestroyLength", + "paramname": "pArrayDestroy", + "paramtype": "const SteamItemInstanceID_t *" + }, + { + "array_count": "unArrayDestroyLength", + "paramname": "punArrayDestroyQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"unArrayDestroyLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "TransferItemQuantity", + "methodname_flat": "SteamAPI_ISteamInventory_TransferItemQuantity", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"itemIdSource", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"unQuantity", "paramtype":"uint32" }, + { "paramname":"itemIdDest", "paramtype":"SteamItemInstanceID_t" } + ], + "returntype": "bool" + }, + { + "methodname": "SendItemDropHeartbeat", + "methodname_flat": "SteamAPI_ISteamInventory_SendItemDropHeartbeat", + "params": [], + "returntype": "void" + }, + { + "methodname": "TriggerItemDrop", + "methodname_flat": "SteamAPI_ISteamInventory_TriggerItemDrop", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"dropListDefinition", "paramtype":"SteamItemDef_t" } + ], + "returntype": "bool" + }, + { + "methodname": "TradeItems", + "methodname_flat": "SteamAPI_ISteamInventory_TradeItems", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"steamIDTradePartner", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { + "array_count": "nArrayGiveLength", + "paramname": "pArrayGive", + "paramtype": "const SteamItemInstanceID_t *" + }, + { + "array_count": "nArrayGiveLength", + "paramname": "pArrayGiveQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"nArrayGiveLength", "paramtype":"uint32" }, + { + "array_count": "nArrayGetLength", + "paramname": "pArrayGet", + "paramtype": "const SteamItemInstanceID_t *" + }, + { + "array_count": "nArrayGetLength", + "paramname": "pArrayGetQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"nArrayGetLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "LoadItemDefinitions", + "methodname_flat": "SteamAPI_ISteamInventory_LoadItemDefinitions", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetItemDefinitionIDs", + "methodname_flat": "SteamAPI_ISteamInventory_GetItemDefinitionIDs", + "params": [ + { + "desc": "List of item definition IDs", + "out_array_count": "punItemDefIDsArraySize", + "paramname": "pItemDefIDs", + "paramtype": "SteamItemDef_t *" + }, + { + "desc": "Size of array is passed in and actual size used is returned in this param", + "paramname": "punItemDefIDsArraySize", + "paramtype": "uint32 *" + } + ], + "returntype": "bool" + }, + { + "methodname": "GetItemDefinitionProperty", + "methodname_flat": "SteamAPI_ISteamInventory_GetItemDefinitionProperty", + "params": [ + { "paramname":"iDefinition", "paramtype":"SteamItemDef_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { + "out_string_count": "punValueBufferSizeOut", + "paramname": "pchValueBuffer", + "paramtype": "char *" + }, + { "paramname":"punValueBufferSizeOut", "paramtype":"uint32 *" } + ], + "returntype": "bool" + }, + { + "callresult": "SteamInventoryEligiblePromoItemDefIDs_t", + "methodname": "RequestEligiblePromoItemDefinitionsIDs", + "methodname_flat": "SteamAPI_ISteamInventory_RequestEligiblePromoItemDefinitionsIDs", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetEligiblePromoItemDefinitionIDs", + "methodname_flat": "SteamAPI_ISteamInventory_GetEligiblePromoItemDefinitionIDs", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { + "desc": "List of item definition IDs", + "out_array_count": "punItemDefIDsArraySize", + "paramname": "pItemDefIDs", + "paramtype": "SteamItemDef_t *" + }, + { + "desc": "Size of array is passed in and actual size used is returned in this param", + "paramname": "punItemDefIDsArraySize", + "paramtype": "uint32 *" + } + ], + "returntype": "bool" + }, + { + "callresult": "SteamInventoryStartPurchaseResult_t", + "methodname": "StartPurchase", + "methodname_flat": "SteamAPI_ISteamInventory_StartPurchase", + "params": [ + { + "array_count": "unArrayLength", + "paramname": "pArrayItemDefs", + "paramtype": "const SteamItemDef_t *" + }, + { + "array_count": "unArrayLength", + "paramname": "punArrayQuantity", + "paramtype": "const uint32 *" + }, + { "paramname":"unArrayLength", "paramtype":"uint32" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "SteamInventoryRequestPricesResult_t", + "methodname": "RequestPrices", + "methodname_flat": "SteamAPI_ISteamInventory_RequestPrices", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetNumItemsWithPrices", + "methodname_flat": "SteamAPI_ISteamInventory_GetNumItemsWithPrices", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetItemsWithPrices", + "methodname_flat": "SteamAPI_ISteamInventory_GetItemsWithPrices", + "params": [ + { + "array_count": "unArrayLength", + "desc": "Items with prices", + "out_array_count": "pArrayItemDefs", + "paramname": "pArrayItemDefs", + "paramtype": "SteamItemDef_t *" + }, + { + "array_count": "unArrayLength", + "desc": "List of prices for the given item defs", + "out_array_count": "pPrices", + "paramname": "pCurrentPrices", + "paramtype": "uint64 *" + }, + { + "array_count": "unArrayLength", + "desc": "List of prices for the given item defs", + "out_array_count": "pPrices", + "paramname": "pBasePrices", + "paramtype": "uint64 *" + }, + { "paramname":"unArrayLength", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetItemPrice", + "methodname_flat": "SteamAPI_ISteamInventory_GetItemPrice", + "params": [ + { "paramname":"iDefinition", "paramtype":"SteamItemDef_t" }, + { "paramname":"pCurrentPrice", "paramtype":"uint64 *" }, + { "paramname":"pBasePrice", "paramtype":"uint64 *" } + ], + "returntype": "bool" + }, + { + "methodname": "StartUpdateProperties", + "methodname_flat": "SteamAPI_ISteamInventory_StartUpdateProperties", + "params": [], + "returntype": "SteamInventoryUpdateHandle_t" + }, + { + "methodname": "RemoveProperty", + "methodname_flat": "SteamAPI_ISteamInventory_RemoveProperty", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"nItemID", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetProperty", + "methodname_flat": "SteamAPI_ISteamInventory_SetPropertyString", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"nItemID", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { "paramname":"pchPropertyValue", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetProperty", + "methodname_flat": "SteamAPI_ISteamInventory_SetPropertyBool", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"nItemID", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { "paramname":"bValue", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "SetProperty", + "methodname_flat": "SteamAPI_ISteamInventory_SetPropertyInt64", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"nItemID", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { "paramname":"nValue", "paramtype":"int64" } + ], + "returntype": "bool" + }, + { + "methodname": "SetProperty", + "methodname_flat": "SteamAPI_ISteamInventory_SetPropertyFloat", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"nItemID", "paramtype":"SteamItemInstanceID_t" }, + { "paramname":"pchPropertyName", "paramtype":"const char *" }, + { "paramname":"flValue", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "SubmitUpdateProperties", + "methodname_flat": "SteamAPI_ISteamInventory_SubmitUpdateProperties", + "params": [ + { "paramname":"handle", "paramtype":"SteamInventoryUpdateHandle_t" }, + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "InspectItem", + "methodname_flat": "SteamAPI_ISteamInventory_InspectItem", + "params": [ + { "paramname":"pResultHandle", "paramtype":"SteamInventoryResult_t *" }, + { "paramname":"pchItemToken", "paramtype":"const char *" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMINVENTORY_INTERFACE_V003" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamVideo", + "name_flat": "SteamAPI_SteamVideo_v002" + } + ], + "classname": "ISteamVideo", + "fields": [], + "methods": [ + { + "methodname": "GetVideoURL", + "methodname_flat": "SteamAPI_ISteamVideo_GetVideoURL", + "params": [ + { "paramname":"unVideoAppID", "paramtype":"AppId_t" } + ], + "returntype": "void" + }, + { + "methodname": "IsBroadcasting", + "methodname_flat": "SteamAPI_ISteamVideo_IsBroadcasting", + "params": [ + { "paramname":"pnNumViewers", "paramtype":"int *" } + ], + "returntype": "bool" + }, + { + "callback": "GetOPFSettingsResult_t", + "methodname": "GetOPFSettings", + "methodname_flat": "SteamAPI_ISteamVideo_GetOPFSettings", + "params": [ + { "paramname":"unVideoAppID", "paramtype":"AppId_t" } + ], + "returntype": "void" + }, + { + "methodname": "GetOPFStringForApp", + "methodname_flat": "SteamAPI_ISteamVideo_GetOPFStringForApp", + "params": [ + { "paramname":"unVideoAppID", "paramtype":"AppId_t" }, + { "paramname":"pchBuffer", "paramtype":"char *" }, + { "paramname":"pnBufferSize", "paramtype":"int32 *" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMVIDEO_INTERFACE_V002" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamParentalSettings", + "name_flat": "SteamAPI_SteamParentalSettings_v001" + } + ], + "classname": "ISteamParentalSettings", + "fields": [], + "methods": [ + { + "methodname": "BIsParentalLockEnabled", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsParentalLockEnabled", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsParentalLockLocked", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsParentalLockLocked", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BIsAppBlocked", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsAppBlocked", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "BIsAppInBlockList", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsAppInBlockList", + "params": [ + { "paramname":"nAppID", "paramtype":"AppId_t" } + ], + "returntype": "bool" + }, + { + "methodname": "BIsFeatureBlocked", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsFeatureBlocked", + "params": [ + { "paramname":"eFeature", "paramtype":"EParentalFeature" } + ], + "returntype": "bool" + }, + { + "methodname": "BIsFeatureInBlockList", + "methodname_flat": "SteamAPI_ISteamParentalSettings_BIsFeatureInBlockList", + "params": [ + { "paramname":"eFeature", "paramtype":"EParentalFeature" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMPARENTALSETTINGS_INTERFACE_VERSION001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamRemotePlay", + "name_flat": "SteamAPI_SteamRemotePlay_v001" + } + ], + "classname": "ISteamRemotePlay", + "fields": [], + "methods": [ + { + "methodname": "GetSessionCount", + "methodname_flat": "SteamAPI_ISteamRemotePlay_GetSessionCount", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetSessionID", + "methodname_flat": "SteamAPI_ISteamRemotePlay_GetSessionID", + "params": [ + { "paramname":"iSessionIndex", "paramtype":"int" } + ], + "returntype": "RemotePlaySessionID_t" + }, + { + "methodname": "GetSessionSteamID", + "methodname_flat": "SteamAPI_ISteamRemotePlay_GetSessionSteamID", + "params": [ + { "paramname":"unSessionID", "paramtype":"RemotePlaySessionID_t" } + ], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "GetSessionClientName", + "methodname_flat": "SteamAPI_ISteamRemotePlay_GetSessionClientName", + "params": [ + { "paramname":"unSessionID", "paramtype":"RemotePlaySessionID_t" } + ], + "returntype": "const char *" + }, + { + "methodname": "GetSessionClientFormFactor", + "methodname_flat": "SteamAPI_ISteamRemotePlay_GetSessionClientFormFactor", + "params": [ + { "paramname":"unSessionID", "paramtype":"RemotePlaySessionID_t" } + ], + "returntype": "ESteamDeviceFormFactor" + }, + { + "methodname": "BGetSessionClientResolution", + "methodname_flat": "SteamAPI_ISteamRemotePlay_BGetSessionClientResolution", + "params": [ + { "paramname":"unSessionID", "paramtype":"RemotePlaySessionID_t" }, + { "paramname":"pnResolutionX", "paramtype":"int *" }, + { "paramname":"pnResolutionY", "paramtype":"int *" } + ], + "returntype": "bool" + }, + { + "methodname": "BSendRemotePlayTogetherInvite", + "methodname_flat": "SteamAPI_ISteamRemotePlay_BSendRemotePlayTogetherInvite", + "params": [ + { "paramname":"steamIDFriend", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + } + ], + "version_string": "STEAMREMOTEPLAY_INTERFACE_VERSION001" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamNetworkingMessages_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingMessages_SteamAPI_v002" + }, + { + "kind": "gameserver", + "name": "SteamGameServerNetworkingMessages_SteamAPI", + "name_flat": "SteamAPI_SteamGameServerNetworkingMessages_SteamAPI_v002" + } + ], + "classname": "ISteamNetworkingMessages", + "fields": [], + "methods": [ + { + "methodname": "SendMessageToUser", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_SendMessageToUser", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"pubData", "paramtype":"const void *" }, + { "paramname":"cubData", "paramtype":"uint32" }, + { "paramname":"nSendFlags", "paramtype":"int" }, + { "paramname":"nRemoteChannel", "paramtype":"int" } + ], + "returntype": "EResult" + }, + { + "methodname": "ReceiveMessagesOnChannel", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_ReceiveMessagesOnChannel", + "params": [ + { "paramname":"nLocalChannel", "paramtype":"int" }, + { "paramname":"ppOutMessages", "paramtype":"SteamNetworkingMessage_t **" }, + { "paramname":"nMaxMessages", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "AcceptSessionWithUser", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_AcceptSessionWithUser", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseSessionWithUser", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_CloseSessionWithUser", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseChannelWithUser", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_CloseChannelWithUser", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"nLocalChannel", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetSessionConnectionInfo", + "methodname_flat": "SteamAPI_ISteamNetworkingMessages_GetSessionConnectionInfo", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"pConnectionInfo", "paramtype":"SteamNetConnectionInfo_t *" }, + { "paramname":"pQuickStatus", "paramtype":"SteamNetConnectionRealTimeStatus_t *" } + ], + "returntype": "ESteamNetworkingConnectionState" + } + ], + "version_string": "SteamNetworkingMessages002" + }, + { + "accessors": [ + { + "kind": "user", + "name": "SteamNetworkingSockets_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingSockets_SteamAPI_v012" + }, + { + "kind": "gameserver", + "name": "SteamGameServerNetworkingSockets_SteamAPI", + "name_flat": "SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012" + } + ], + "classname": "ISteamNetworkingSockets", + "fields": [], + "methods": [ + { + "methodname": "CreateListenSocketIP", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP", + "params": [ + { "paramname":"localAddress", "paramtype":"const SteamNetworkingIPAddr &" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamListenSocket" + }, + { + "methodname": "ConnectByIPAddress", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress", + "params": [ + { "paramname":"address", "paramtype":"const SteamNetworkingIPAddr &" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamNetConnection" + }, + { + "methodname": "CreateListenSocketP2P", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateListenSocketP2P", + "params": [ + { "paramname":"nLocalVirtualPort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamListenSocket" + }, + { + "methodname": "ConnectP2P", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConnectP2P", + "params": [ + { "paramname":"identityRemote", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"nRemoteVirtualPort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamNetConnection" + }, + { + "methodname": "AcceptConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_AcceptConnection", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" } + ], + "returntype": "EResult" + }, + { + "methodname": "CloseConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CloseConnection", + "params": [ + { "paramname":"hPeer", "paramtype":"HSteamNetConnection" }, + { "paramname":"nReason", "paramtype":"int" }, + { "paramname":"pszDebug", "paramtype":"const char *" }, + { "paramname":"bEnableLinger", "paramtype":"bool" } + ], + "returntype": "bool" + }, + { + "methodname": "CloseListenSocket", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CloseListenSocket", + "params": [ + { "paramname":"hSocket", "paramtype":"HSteamListenSocket" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConnectionUserData", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SetConnectionUserData", + "params": [ + { "paramname":"hPeer", "paramtype":"HSteamNetConnection" }, + { "paramname":"nUserData", "paramtype":"int64" } + ], + "returntype": "bool" + }, + { + "methodname": "GetConnectionUserData", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetConnectionUserData", + "params": [ + { "paramname":"hPeer", "paramtype":"HSteamNetConnection" } + ], + "returntype": "int64" + }, + { + "methodname": "SetConnectionName", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SetConnectionName", + "params": [ + { "paramname":"hPeer", "paramtype":"HSteamNetConnection" }, + { "paramname":"pszName", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "GetConnectionName", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetConnectionName", + "params": [ + { "paramname":"hPeer", "paramtype":"HSteamNetConnection" }, + { "paramname":"pszName", "paramtype":"char *" }, + { "paramname":"nMaxLen", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "SendMessageToConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SendMessageToConnection", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"pData", "paramtype":"const void *" }, + { "paramname":"cbData", "paramtype":"uint32" }, + { "paramname":"nSendFlags", "paramtype":"int" }, + { "paramname":"pOutMessageNumber", "paramtype":"int64 *" } + ], + "returntype": "EResult" + }, + { + "methodname": "SendMessages", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SendMessages", + "params": [ + { "paramname":"nMessages", "paramtype":"int" }, + { "paramname":"pMessages", "paramtype":"SteamNetworkingMessage_t *const *" }, + { "paramname":"pOutMessageNumberOrResult", "paramtype":"int64 *" } + ], + "returntype": "void" + }, + { + "methodname": "FlushMessagesOnConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_FlushMessagesOnConnection", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" } + ], + "returntype": "EResult" + }, + { + "methodname": "ReceiveMessagesOnConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"ppOutMessages", "paramtype":"SteamNetworkingMessage_t **" }, + { "paramname":"nMaxMessages", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetConnectionInfo", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetConnectionInfo", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"pInfo", "paramtype":"SteamNetConnectionInfo_t *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetConnectionRealTimeStatus", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetConnectionRealTimeStatus", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"pStatus", "paramtype":"SteamNetConnectionRealTimeStatus_t *" }, + { "paramname":"nLanes", "paramtype":"int" }, + { "paramname":"pLanes", "paramtype":"SteamNetConnectionRealTimeLaneStatus_t *" } + ], + "returntype": "EResult" + }, + { + "methodname": "GetDetailedConnectionStatus", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetDetailedConnectionStatus", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"pszBuf", "paramtype":"char *" }, + { "paramname":"cbBuf", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetListenSocketAddress", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetListenSocketAddress", + "params": [ + { "paramname":"hSocket", "paramtype":"HSteamListenSocket" }, + { "paramname":"address", "paramtype":"SteamNetworkingIPAddr *" } + ], + "returntype": "bool" + }, + { + "methodname": "CreateSocketPair", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateSocketPair", + "params": [ + { "paramname":"pOutConnection1", "paramtype":"HSteamNetConnection *" }, + { "paramname":"pOutConnection2", "paramtype":"HSteamNetConnection *" }, + { "paramname":"bUseNetworkLoopback", "paramtype":"bool" }, + { "paramname":"pIdentity1", "paramtype":"const SteamNetworkingIdentity *" }, + { "paramname":"pIdentity2", "paramtype":"const SteamNetworkingIdentity *" } + ], + "returntype": "bool" + }, + { + "methodname": "ConfigureConnectionLanes", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConfigureConnectionLanes", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"nNumLanes", "paramtype":"int" }, + { "paramname":"pLanePriorities", "paramtype":"const int *" }, + { "paramname":"pLaneWeights", "paramtype":"const uint16 *" } + ], + "returntype": "EResult" + }, + { + "methodname": "GetIdentity", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetIdentity", + "params": [ + { "paramname":"pIdentity", "paramtype":"SteamNetworkingIdentity *" } + ], + "returntype": "bool" + }, + { + "methodname": "InitAuthentication", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_InitAuthentication", + "params": [], + "returntype": "ESteamNetworkingAvailability" + }, + { + "methodname": "GetAuthenticationStatus", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetAuthenticationStatus", + "params": [ + { "paramname":"pDetails", "paramtype":"SteamNetAuthenticationStatus_t *" } + ], + "returntype": "ESteamNetworkingAvailability" + }, + { + "methodname": "CreatePollGroup", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreatePollGroup", + "params": [], + "returntype": "HSteamNetPollGroup" + }, + { + "methodname": "DestroyPollGroup", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_DestroyPollGroup", + "params": [ + { "paramname":"hPollGroup", "paramtype":"HSteamNetPollGroup" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConnectionPollGroup", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"hPollGroup", "paramtype":"HSteamNetPollGroup" } + ], + "returntype": "bool" + }, + { + "methodname": "ReceiveMessagesOnPollGroup", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup", + "params": [ + { "paramname":"hPollGroup", "paramtype":"HSteamNetPollGroup" }, + { "paramname":"ppOutMessages", "paramtype":"SteamNetworkingMessage_t **" }, + { "paramname":"nMaxMessages", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "ReceivedRelayAuthTicket", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ReceivedRelayAuthTicket", + "params": [ + { "paramname":"pvTicket", "paramtype":"const void *" }, + { "paramname":"cbTicket", "paramtype":"int" }, + { "paramname":"pOutParsedTicket", "paramtype":"SteamDatagramRelayAuthTicket *" } + ], + "returntype": "bool" + }, + { + "methodname": "FindRelayAuthTicketForServer", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_FindRelayAuthTicketForServer", + "params": [ + { "paramname":"identityGameServer", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"nRemoteVirtualPort", "paramtype":"int" }, + { "paramname":"pOutParsedTicket", "paramtype":"SteamDatagramRelayAuthTicket *" } + ], + "returntype": "int" + }, + { + "methodname": "ConnectToHostedDedicatedServer", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConnectToHostedDedicatedServer", + "params": [ + { "paramname":"identityTarget", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"nRemoteVirtualPort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamNetConnection" + }, + { + "methodname": "GetHostedDedicatedServerPort", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerPort", + "params": [], + "returntype": "uint16" + }, + { + "methodname": "GetHostedDedicatedServerPOPID", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerPOPID", + "params": [], + "returntype": "SteamNetworkingPOPID" + }, + { + "methodname": "GetHostedDedicatedServerAddress", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerAddress", + "params": [ + { "paramname":"pRouting", "paramtype":"SteamDatagramHostedAddress *" } + ], + "returntype": "EResult" + }, + { + "methodname": "CreateHostedDedicatedServerListenSocket", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateHostedDedicatedServerListenSocket", + "params": [ + { "paramname":"nLocalVirtualPort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamListenSocket" + }, + { + "methodname": "GetGameCoordinatorServerLogin", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetGameCoordinatorServerLogin", + "params": [ + { "paramname":"pLoginInfo", "paramtype":"SteamDatagramGameCoordinatorServerLogin *" }, + { "paramname":"pcbSignedBlob", "paramtype":"int *" }, + { "paramname":"pBlob", "paramtype":"void *" } + ], + "returntype": "EResult" + }, + { + "methodname": "ConnectP2PCustomSignaling", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConnectP2PCustomSignaling", + "params": [ + { "paramname":"pSignaling", "paramtype":"ISteamNetworkingConnectionSignaling *" }, + { "paramname":"pPeerIdentity", "paramtype":"const SteamNetworkingIdentity *" }, + { "paramname":"nRemoteVirtualPort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamNetConnection" + }, + { + "methodname": "ReceivedP2PCustomSignal", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ReceivedP2PCustomSignal", + "params": [ + { "paramname":"pMsg", "paramtype":"const void *" }, + { "paramname":"cbMsg", "paramtype":"int" }, + { "paramname":"pContext", "paramtype":"ISteamNetworkingSignalingRecvContext *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetCertificateRequest", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetCertificateRequest", + "params": [ + { "paramname":"pcbBlob", "paramtype":"int *" }, + { "paramname":"pBlob", "paramtype":"void *" }, + { "paramname":"errMsg", "paramtype":"SteamNetworkingErrMsg &" } + ], + "returntype": "bool" + }, + { + "methodname": "SetCertificate", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_SetCertificate", + "params": [ + { "paramname":"pCertificate", "paramtype":"const void *" }, + { "paramname":"cbCertificate", "paramtype":"int" }, + { "paramname":"errMsg", "paramtype":"SteamNetworkingErrMsg &" } + ], + "returntype": "bool" + }, + { + "methodname": "ResetIdentity", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ResetIdentity", + "params": [ + { "paramname":"pIdentity", "paramtype":"const SteamNetworkingIdentity *" } + ], + "returntype": "void" + }, + { + "methodname": "RunCallbacks", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_RunCallbacks", + "params": [], + "returntype": "void" + }, + { + "methodname": "BeginAsyncRequestFakeIP", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_BeginAsyncRequestFakeIP", + "params": [ + { "paramname":"nNumPorts", "paramtype":"int" } + ], + "returntype": "bool" + }, + { + "methodname": "GetFakeIP", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetFakeIP", + "params": [ + { "paramname":"idxFirstPort", "paramtype":"int" }, + { "paramname":"pInfo", "paramtype":"SteamNetworkingFakeIPResult_t *" } + ], + "returntype": "void" + }, + { + "methodname": "CreateListenSocketP2PFakeIP", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateListenSocketP2PFakeIP", + "params": [ + { "paramname":"idxFakePort", "paramtype":"int" }, + { "paramname":"nOptions", "paramtype":"int" }, + { "paramname":"pOptions", "paramtype":"const SteamNetworkingConfigValue_t *" } + ], + "returntype": "HSteamListenSocket" + }, + { + "methodname": "GetRemoteFakeIPForConnection", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_GetRemoteFakeIPForConnection", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"pOutAddr", "paramtype":"SteamNetworkingIPAddr *" } + ], + "returntype": "EResult" + }, + { + "methodname": "CreateFakeUDPPort", + "methodname_flat": "SteamAPI_ISteamNetworkingSockets_CreateFakeUDPPort", + "params": [ + { "paramname":"idxFakeServerPort", "paramtype":"int" } + ], + "returntype": "ISteamNetworkingFakeUDPPort *" + } + ], + "version_string": "SteamNetworkingSockets012" + }, + { + "accessors": [ + { + "kind": "global", + "name": "SteamNetworkingUtils_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingUtils_SteamAPI_v004" + } + ], + "classname": "ISteamNetworkingUtils", + "fields": [], + "methods": [ + { + "methodname": "AllocateMessage", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_AllocateMessage", + "params": [ + { "paramname":"cbAllocateBuffer", "paramtype":"int" } + ], + "returntype": "SteamNetworkingMessage_t *" + }, + { + "methodname": "InitRelayNetworkAccess", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_InitRelayNetworkAccess", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetRelayNetworkStatus", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetRelayNetworkStatus", + "params": [ + { "paramname":"pDetails", "paramtype":"SteamRelayNetworkStatus_t *" } + ], + "returntype": "ESteamNetworkingAvailability" + }, + { + "methodname": "GetLocalPingLocation", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetLocalPingLocation", + "params": [ + { "paramname":"result", "paramtype":"SteamNetworkPingLocation_t &" } + ], + "returntype": "float" + }, + { + "methodname": "EstimatePingTimeBetweenTwoLocations", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_EstimatePingTimeBetweenTwoLocations", + "params": [ + { "paramname":"location1", "paramtype":"const SteamNetworkPingLocation_t &" }, + { "paramname":"location2", "paramtype":"const SteamNetworkPingLocation_t &" } + ], + "returntype": "int" + }, + { + "methodname": "EstimatePingTimeFromLocalHost", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_EstimatePingTimeFromLocalHost", + "params": [ + { "paramname":"remoteLocation", "paramtype":"const SteamNetworkPingLocation_t &" } + ], + "returntype": "int" + }, + { + "methodname": "ConvertPingLocationToString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_ConvertPingLocationToString", + "params": [ + { "paramname":"location", "paramtype":"const SteamNetworkPingLocation_t &" }, + { "paramname":"pszBuf", "paramtype":"char *" }, + { "paramname":"cchBufSize", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "ParsePingLocationString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_ParsePingLocationString", + "params": [ + { "paramname":"pszString", "paramtype":"const char *" }, + { "paramname":"result", "paramtype":"SteamNetworkPingLocation_t &" } + ], + "returntype": "bool" + }, + { + "methodname": "CheckPingDataUpToDate", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_CheckPingDataUpToDate", + "params": [ + { "paramname":"flMaxAgeSeconds", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "GetPingToDataCenter", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetPingToDataCenter", + "params": [ + { "paramname":"popID", "paramtype":"SteamNetworkingPOPID" }, + { "paramname":"pViaRelayPoP", "paramtype":"SteamNetworkingPOPID *" } + ], + "returntype": "int" + }, + { + "methodname": "GetDirectPingToPOP", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetDirectPingToPOP", + "params": [ + { "paramname":"popID", "paramtype":"SteamNetworkingPOPID" } + ], + "returntype": "int" + }, + { + "methodname": "GetPOPCount", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetPOPCount", + "params": [], + "returntype": "int" + }, + { + "methodname": "GetPOPList", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetPOPList", + "params": [ + { "paramname":"list", "paramtype":"SteamNetworkingPOPID *" }, + { "paramname":"nListSz", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "GetLocalTimestamp", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetLocalTimestamp", + "params": [], + "returntype": "SteamNetworkingMicroseconds" + }, + { + "methodname": "SetDebugOutputFunction", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetDebugOutputFunction", + "params": [ + { "paramname":"eDetailLevel", "paramtype":"ESteamNetworkingSocketsDebugOutputType" }, + { "paramname":"pfnFunc", "paramtype":"FSteamNetworkingSocketsDebugOutput" } + ], + "returntype": "void" + }, + { + "methodname": "IsFakeIPv4", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_IsFakeIPv4", + "params": [ + { "paramname":"nIPv4", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetIPv4FakeIPType", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetIPv4FakeIPType", + "params": [ + { "paramname":"nIPv4", "paramtype":"uint32" } + ], + "returntype": "ESteamNetworkingFakeIPType" + }, + { + "methodname": "GetRealIdentityForFakeIP", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetRealIdentityForFakeIP", + "params": [ + { "paramname":"fakeIP", "paramtype":"const SteamNetworkingIPAddr &" }, + { "paramname":"pOutRealIdentity", "paramtype":"SteamNetworkingIdentity *" } + ], + "returntype": "EResult" + }, + { + "methodname": "SetGlobalConfigValueInt32", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueInt32", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalConfigValueFloat", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueFloat", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalConfigValueString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueString", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalConfigValuePtr", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValuePtr", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"void *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConnectionConfigValueInt32", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueInt32", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConnectionConfigValueFloat", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueFloat", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConnectionConfigValueString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueString", + "params": [ + { "paramname":"hConn", "paramtype":"HSteamNetConnection" }, + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"val", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_SteamNetConnectionStatusChanged", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetConnectionStatusChanged", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamNetConnectionStatusChanged" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_SteamNetAuthenticationStatusChanged", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetAuthenticationStatusChanged", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamNetAuthenticationStatusChanged" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_SteamRelayNetworkStatusChanged", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamRelayNetworkStatusChanged", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamRelayNetworkStatusChanged" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_FakeIPResult", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_FakeIPResult", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamNetworkingFakeIPResult" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_MessagesSessionRequest", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_MessagesSessionRequest", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamNetworkingMessagesSessionRequest" } + ], + "returntype": "bool" + }, + { + "methodname": "SetGlobalCallback_MessagesSessionFailed", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_MessagesSessionFailed", + "params": [ + { "paramname":"fnCallback", "paramtype":"FnSteamNetworkingMessagesSessionFailed" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConfigValue", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetConfigValue", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"eScopeType", "paramtype":"ESteamNetworkingConfigScope" }, + { "paramname":"scopeObj", "paramtype":"intptr_t" }, + { "paramname":"eDataType", "paramtype":"ESteamNetworkingConfigDataType" }, + { "paramname":"pArg", "paramtype":"const void *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetConfigValueStruct", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SetConfigValueStruct", + "params": [ + { "paramname":"opt", "paramtype":"const SteamNetworkingConfigValue_t &" }, + { "paramname":"eScopeType", "paramtype":"ESteamNetworkingConfigScope" }, + { "paramname":"scopeObj", "paramtype":"intptr_t" } + ], + "returntype": "bool" + }, + { + "methodname": "GetConfigValue", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetConfigValue", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"eScopeType", "paramtype":"ESteamNetworkingConfigScope" }, + { "paramname":"scopeObj", "paramtype":"intptr_t" }, + { "paramname":"pOutDataType", "paramtype":"ESteamNetworkingConfigDataType *" }, + { "paramname":"pResult", "paramtype":"void *" }, + { "paramname":"cbResult", "paramtype":"size_t *" } + ], + "returntype": "ESteamNetworkingGetConfigValueResult" + }, + { + "methodname": "GetConfigValueInfo", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_GetConfigValueInfo", + "params": [ + { "paramname":"eValue", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"pOutDataType", "paramtype":"ESteamNetworkingConfigDataType *" }, + { "paramname":"pOutScope", "paramtype":"ESteamNetworkingConfigScope *" } + ], + "returntype": "const char *" + }, + { + "methodname": "IterateGenericEditableConfigValues", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_IterateGenericEditableConfigValues", + "params": [ + { "paramname":"eCurrent", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"bEnumerateDevVars", "paramtype":"bool" } + ], + "returntype": "ESteamNetworkingConfigValue" + }, + { + "methodname": "SteamNetworkingIPAddr_ToString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_ToString", + "params": [ + { "paramname":"addr", "paramtype":"const SteamNetworkingIPAddr &" }, + { "paramname":"buf", "paramtype":"char *" }, + { "paramname":"cbBuf", "paramtype":"uint32" }, + { "paramname":"bWithPort", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "SteamNetworkingIPAddr_ParseString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_ParseString", + "params": [ + { "paramname":"pAddr", "paramtype":"SteamNetworkingIPAddr *" }, + { "paramname":"pszStr", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "SteamNetworkingIPAddr_GetFakeIPType", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_GetFakeIPType", + "params": [ + { "paramname":"addr", "paramtype":"const SteamNetworkingIPAddr &" } + ], + "returntype": "ESteamNetworkingFakeIPType" + }, + { + "methodname": "SteamNetworkingIdentity_ToString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SteamNetworkingIdentity_ToString", + "params": [ + { "paramname":"identity", "paramtype":"const SteamNetworkingIdentity &" }, + { "paramname":"buf", "paramtype":"char *" }, + { "paramname":"cbBuf", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "SteamNetworkingIdentity_ParseString", + "methodname_flat": "SteamAPI_ISteamNetworkingUtils_SteamNetworkingIdentity_ParseString", + "params": [ + { "paramname":"pIdentity", "paramtype":"SteamNetworkingIdentity *" }, + { "paramname":"pszStr", "paramtype":"const char *" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamNetworkingUtils004" + }, + { + "accessors": [ + { + "kind": "gameserver", + "name": "SteamGameServer", + "name_flat": "SteamAPI_SteamGameServer_v014" + } + ], + "classname": "ISteamGameServer", + "fields": [], + "methods": [ + { + "methodname": "SetProduct", + "methodname_flat": "SteamAPI_ISteamGameServer_SetProduct", + "params": [ + { "paramname":"pszProduct", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetGameDescription", + "methodname_flat": "SteamAPI_ISteamGameServer_SetGameDescription", + "params": [ + { "paramname":"pszGameDescription", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetModDir", + "methodname_flat": "SteamAPI_ISteamGameServer_SetModDir", + "params": [ + { "paramname":"pszModDir", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetDedicatedServer", + "methodname_flat": "SteamAPI_ISteamGameServer_SetDedicatedServer", + "params": [ + { "paramname":"bDedicated", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "LogOn", + "methodname_flat": "SteamAPI_ISteamGameServer_LogOn", + "params": [ + { "paramname":"pszToken", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "LogOnAnonymous", + "methodname_flat": "SteamAPI_ISteamGameServer_LogOnAnonymous", + "params": [], + "returntype": "void" + }, + { + "methodname": "LogOff", + "methodname_flat": "SteamAPI_ISteamGameServer_LogOff", + "params": [], + "returntype": "void" + }, + { + "methodname": "BLoggedOn", + "methodname_flat": "SteamAPI_ISteamGameServer_BLoggedOn", + "params": [], + "returntype": "bool" + }, + { + "methodname": "BSecure", + "methodname_flat": "SteamAPI_ISteamGameServer_BSecure", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetSteamID", + "methodname_flat": "SteamAPI_ISteamGameServer_GetSteamID", + "params": [], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "WasRestartRequested", + "methodname_flat": "SteamAPI_ISteamGameServer_WasRestartRequested", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetMaxPlayerCount", + "methodname_flat": "SteamAPI_ISteamGameServer_SetMaxPlayerCount", + "params": [ + { "paramname":"cPlayersMax", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "SetBotPlayerCount", + "methodname_flat": "SteamAPI_ISteamGameServer_SetBotPlayerCount", + "params": [ + { "paramname":"cBotplayers", "paramtype":"int" } + ], + "returntype": "void" + }, + { + "methodname": "SetServerName", + "methodname_flat": "SteamAPI_ISteamGameServer_SetServerName", + "params": [ + { "paramname":"pszServerName", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetMapName", + "methodname_flat": "SteamAPI_ISteamGameServer_SetMapName", + "params": [ + { "paramname":"pszMapName", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetPasswordProtected", + "methodname_flat": "SteamAPI_ISteamGameServer_SetPasswordProtected", + "params": [ + { "paramname":"bPasswordProtected", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "SetSpectatorPort", + "methodname_flat": "SteamAPI_ISteamGameServer_SetSpectatorPort", + "params": [ + { "paramname":"unSpectatorPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "SetSpectatorServerName", + "methodname_flat": "SteamAPI_ISteamGameServer_SetSpectatorServerName", + "params": [ + { "paramname":"pszSpectatorServerName", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "ClearAllKeyValues", + "methodname_flat": "SteamAPI_ISteamGameServer_ClearAllKeyValues", + "params": [], + "returntype": "void" + }, + { + "methodname": "SetKeyValue", + "methodname_flat": "SteamAPI_ISteamGameServer_SetKeyValue", + "params": [ + { "paramname":"pKey", "paramtype":"const char *" }, + { "paramname":"pValue", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetGameTags", + "methodname_flat": "SteamAPI_ISteamGameServer_SetGameTags", + "params": [ + { "paramname":"pchGameTags", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetGameData", + "methodname_flat": "SteamAPI_ISteamGameServer_SetGameData", + "params": [ + { "paramname":"pchGameData", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetRegion", + "methodname_flat": "SteamAPI_ISteamGameServer_SetRegion", + "params": [ + { "paramname":"pszRegion", "paramtype":"const char *" } + ], + "returntype": "void" + }, + { + "methodname": "SetAdvertiseServerActive", + "methodname_flat": "SteamAPI_ISteamGameServer_SetAdvertiseServerActive", + "params": [ + { "paramname":"bActive", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "GetAuthSessionTicket", + "methodname_flat": "SteamAPI_ISteamGameServer_GetAuthSessionTicket", + "params": [ + { "paramname":"pTicket", "paramtype":"void *" }, + { "paramname":"cbMaxTicket", "paramtype":"int" }, + { "paramname":"pcbTicket", "paramtype":"uint32 *" } + ], + "returntype": "HAuthTicket" + }, + { + "methodname": "BeginAuthSession", + "methodname_flat": "SteamAPI_ISteamGameServer_BeginAuthSession", + "params": [ + { "paramname":"pAuthTicket", "paramtype":"const void *" }, + { "paramname":"cbAuthTicket", "paramtype":"int" }, + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "EBeginAuthSessionResult" + }, + { + "methodname": "EndAuthSession", + "methodname_flat": "SteamAPI_ISteamGameServer_EndAuthSession", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "CancelAuthTicket", + "methodname_flat": "SteamAPI_ISteamGameServer_CancelAuthTicket", + "params": [ + { "paramname":"hAuthTicket", "paramtype":"HAuthTicket" } + ], + "returntype": "void" + }, + { + "methodname": "UserHasLicenseForApp", + "methodname_flat": "SteamAPI_ISteamGameServer_UserHasLicenseForApp", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"appID", "paramtype":"AppId_t" } + ], + "returntype": "EUserHasLicenseForAppResult" + }, + { + "methodname": "RequestUserGroupStatus", + "methodname_flat": "SteamAPI_ISteamGameServer_RequestUserGroupStatus", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"steamIDGroup", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGameplayStats", + "methodname_flat": "SteamAPI_ISteamGameServer_GetGameplayStats", + "params": [], + "returntype": "void" + }, + { + "callresult": "GSReputation_t", + "methodname": "GetServerReputation", + "methodname_flat": "SteamAPI_ISteamGameServer_GetServerReputation", + "params": [], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetPublicIP", + "methodname_flat": "SteamAPI_ISteamGameServer_GetPublicIP", + "params": [], + "returntype": "SteamIPAddress_t" + }, + { + "methodname": "HandleIncomingPacket", + "methodname_flat": "SteamAPI_ISteamGameServer_HandleIncomingPacket", + "params": [ + { "paramname":"pData", "paramtype":"const void *" }, + { "paramname":"cbData", "paramtype":"int" }, + { "paramname":"srcIP", "paramtype":"uint32" }, + { "paramname":"srcPort", "paramtype":"uint16" } + ], + "returntype": "bool" + }, + { + "methodname": "GetNextOutgoingPacket", + "methodname_flat": "SteamAPI_ISteamGameServer_GetNextOutgoingPacket", + "params": [ + { "paramname":"pOut", "paramtype":"void *" }, + { "paramname":"cbMaxOut", "paramtype":"int" }, + { "paramname":"pNetAdr", "paramtype":"uint32 *" }, + { "paramname":"pPort", "paramtype":"uint16 *" } + ], + "returntype": "int" + }, + { + "callresult": "AssociateWithClanResult_t", + "methodname": "AssociateWithClan", + "methodname_flat": "SteamAPI_ISteamGameServer_AssociateWithClan", + "params": [ + { "paramname":"steamIDClan", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "callresult": "ComputeNewPlayerCompatibilityResult_t", + "methodname": "ComputeNewPlayerCompatibility", + "methodname_flat": "SteamAPI_ISteamGameServer_ComputeNewPlayerCompatibility", + "params": [ + { "paramname":"steamIDNewPlayer", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "SendUserConnectAndAuthenticate_DEPRECATED", + "methodname_flat": "SteamAPI_ISteamGameServer_SendUserConnectAndAuthenticate_DEPRECATED", + "params": [ + { "paramname":"unIPClient", "paramtype":"uint32" }, + { "paramname":"pvAuthBlob", "paramtype":"const void *" }, + { "paramname":"cubAuthBlobSize", "paramtype":"uint32" }, + { "paramname":"pSteamIDUser", "paramtype":"CSteamID *" } + ], + "returntype": "bool" + }, + { + "methodname": "CreateUnauthenticatedUserConnection", + "methodname_flat": "SteamAPI_ISteamGameServer_CreateUnauthenticatedUserConnection", + "params": [], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "SendUserDisconnect_DEPRECATED", + "methodname_flat": "SteamAPI_ISteamGameServer_SendUserDisconnect_DEPRECATED", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "BUpdateUserData", + "methodname_flat": "SteamAPI_ISteamGameServer_BUpdateUserData", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchPlayerName", "paramtype":"const char *" }, + { "paramname":"uScore", "paramtype":"uint32" } + ], + "returntype": "bool" + } + ], + "version_string": "SteamGameServer014" + }, + { + "accessors": [ + { + "kind": "gameserver", + "name": "SteamGameServerStats", + "name_flat": "SteamAPI_SteamGameServerStats_v001" + } + ], + "classname": "ISteamGameServerStats", + "fields": [], + "methods": [ + { + "callresult": "GSStatsReceived_t", + "methodname": "RequestUserStats", + "methodname_flat": "SteamAPI_ISteamGameServerStats_RequestUserStats", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + }, + { + "methodname": "GetUserStat", + "methodname_flat": "SteamAPI_ISteamGameServerStats_GetUserStatInt32", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"int32 *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUserStat", + "methodname_flat": "SteamAPI_ISteamGameServerStats_GetUserStatFloat", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pData", "paramtype":"float *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetUserAchievement", + "methodname_flat": "SteamAPI_ISteamGameServerStats_GetUserAchievement", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"pbAchieved", "paramtype":"bool *" } + ], + "returntype": "bool" + }, + { + "methodname": "SetUserStat", + "methodname_flat": "SteamAPI_ISteamGameServerStats_SetUserStatInt32", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"nData", "paramtype":"int32" } + ], + "returntype": "bool" + }, + { + "methodname": "SetUserStat", + "methodname_flat": "SteamAPI_ISteamGameServerStats_SetUserStatFloat", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"fData", "paramtype":"float" } + ], + "returntype": "bool" + }, + { + "methodname": "UpdateUserAvgRateStat", + "methodname_flat": "SteamAPI_ISteamGameServerStats_UpdateUserAvgRateStat", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" }, + { "paramname":"flCountThisSession", "paramtype":"float" }, + { "paramname":"dSessionLength", "paramtype":"double" } + ], + "returntype": "bool" + }, + { + "methodname": "SetUserAchievement", + "methodname_flat": "SteamAPI_ISteamGameServerStats_SetUserAchievement", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "ClearUserAchievement", + "methodname_flat": "SteamAPI_ISteamGameServerStats_ClearUserAchievement", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" }, + { "paramname":"pchName", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "callresult": "GSStatsStored_t", + "methodname": "StoreUserStats", + "methodname_flat": "SteamAPI_ISteamGameServerStats_StoreUserStats", + "params": [ + { "paramname":"steamIDUser", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "SteamAPICall_t" + } + ], + "version_string": "SteamGameServerStats001" + }, + { + "classname": "ISteamNetworkingFakeUDPPort", + "fields": [], + "methods": [ + { + "methodname": "DestroyFakeUDPPort", + "methodname_flat": "SteamAPI_ISteamNetworkingFakeUDPPort_DestroyFakeUDPPort", + "params": [], + "returntype": "void" + }, + { + "methodname": "SendMessageToFakeIP", + "methodname_flat": "SteamAPI_ISteamNetworkingFakeUDPPort_SendMessageToFakeIP", + "params": [ + { "paramname":"remoteAddress", "paramtype":"const SteamNetworkingIPAddr &" }, + { "paramname":"pData", "paramtype":"const void *" }, + { "paramname":"cbData", "paramtype":"uint32" }, + { "paramname":"nSendFlags", "paramtype":"int" } + ], + "returntype": "EResult" + }, + { + "methodname": "ReceiveMessages", + "methodname_flat": "SteamAPI_ISteamNetworkingFakeUDPPort_ReceiveMessages", + "params": [ + { "paramname":"ppOutMessages", "paramtype":"SteamNetworkingMessage_t **" }, + { "paramname":"nMaxMessages", "paramtype":"int" } + ], + "returntype": "int" + }, + { + "methodname": "ScheduleCleanup", + "methodname_flat": "SteamAPI_ISteamNetworkingFakeUDPPort_ScheduleCleanup", + "params": [ + { "paramname":"remoteAddress", "paramtype":"const SteamNetworkingIPAddr &" } + ], + "returntype": "void" + } + ] + } + ], + "structs": [ + { + "fields": [ + { "fieldname":"m_rgubIPv6", "fieldtype":"uint8 [16]" }, + { "fieldname":"m_eType", "fieldtype":"ESteamIPType" } + ], + "methods": [ + { + "methodname": "IsSet", + "methodname_flat": "SteamAPI_SteamIPAddress_t_IsSet", + "params": [], + "returntype": "bool" + } + ], + "struct": "SteamIPAddress_t" + }, + { + "fields": [ + { "fieldname":"m_gameID", "fieldtype":"CGameID" }, + { "fieldname":"m_unGameIP", "fieldtype":"uint32" }, + { "fieldname":"m_usGamePort", "fieldtype":"uint16" }, + { "fieldname":"m_usQueryPort", "fieldtype":"uint16" }, + { "fieldname":"m_steamIDLobby", "fieldtype":"CSteamID" } + ], + "struct": "FriendGameInfo_t" + }, + { + "fields": [ + { "fieldname":"m_szKey", "fieldtype":"char [256]" }, + { "fieldname":"m_szValue", "fieldtype":"char [256]" } + ], + "methods": [ + { + "methodname": "Construct", + "methodname_flat": "SteamAPI_MatchMakingKeyValuePair_t_Construct", + "params": [], + "returntype": "void" + } + ], + "struct": "MatchMakingKeyValuePair_t" + }, + { + "fields": [ + { + "fieldname": "m_usConnectionPort", + "fieldtype": "uint16", + "private": true + }, + { + "fieldname": "m_usQueryPort", + "fieldtype": "uint16", + "private": true + }, + { + "fieldname": "m_unIP", + "fieldtype": "uint32", + "private": true + } + ], + "methods": [ + { + "methodname": "Construct", + "methodname_flat": "SteamAPI_servernetadr_t_Construct", + "params": [], + "returntype": "void" + }, + { + "methodname": "Init", + "methodname_flat": "SteamAPI_servernetadr_t_Init", + "params": [ + { "paramname":"ip", "paramtype":"unsigned int" }, + { "paramname":"usQueryPort", "paramtype":"uint16" }, + { "paramname":"usConnectionPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "GetQueryPort", + "methodname_flat": "SteamAPI_servernetadr_t_GetQueryPort", + "params": [], + "returntype": "uint16" + }, + { + "methodname": "SetQueryPort", + "methodname_flat": "SteamAPI_servernetadr_t_SetQueryPort", + "params": [ + { "paramname":"usPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "GetConnectionPort", + "methodname_flat": "SteamAPI_servernetadr_t_GetConnectionPort", + "params": [], + "returntype": "uint16" + }, + { + "methodname": "SetConnectionPort", + "methodname_flat": "SteamAPI_servernetadr_t_SetConnectionPort", + "params": [ + { "paramname":"usPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "GetIP", + "methodname_flat": "SteamAPI_servernetadr_t_GetIP", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetIP", + "methodname_flat": "SteamAPI_servernetadr_t_SetIP", + "params": [ + { "paramname":"unIP", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "GetConnectionAddressString", + "methodname_flat": "SteamAPI_servernetadr_t_GetConnectionAddressString", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "GetQueryAddressString", + "methodname_flat": "SteamAPI_servernetadr_t_GetQueryAddressString", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "operator<", + "methodname_flat": "SteamAPI_servernetadr_t_IsLessThan", + "params": [ + { "paramname":"netadr", "paramtype":"const servernetadr_t &" } + ], + "returntype": "bool" + }, + { + "methodname": "operator=", + "methodname_flat": "SteamAPI_servernetadr_t_Assign", + "params": [ + { "paramname":"that", "paramtype":"const servernetadr_t &" } + ], + "returntype": "void" + } + ], + "struct": "servernetadr_t" + }, + { + "fields": [ + { "fieldname":"m_NetAdr", "fieldtype":"servernetadr_t" }, + { "fieldname":"m_nPing", "fieldtype":"int" }, + { "fieldname":"m_bHadSuccessfulResponse", "fieldtype":"bool" }, + { "fieldname":"m_bDoNotRefresh", "fieldtype":"bool" }, + { "fieldname":"m_szGameDir", "fieldtype":"char [32]" }, + { "fieldname":"m_szMap", "fieldtype":"char [32]" }, + { "fieldname":"m_szGameDescription", "fieldtype":"char [64]" }, + { "fieldname":"m_nAppID", "fieldtype":"uint32" }, + { "fieldname":"m_nPlayers", "fieldtype":"int" }, + { "fieldname":"m_nMaxPlayers", "fieldtype":"int" }, + { "fieldname":"m_nBotPlayers", "fieldtype":"int" }, + { "fieldname":"m_bPassword", "fieldtype":"bool" }, + { "fieldname":"m_bSecure", "fieldtype":"bool" }, + { "fieldname":"m_ulTimeLastPlayed", "fieldtype":"uint32" }, + { "fieldname":"m_nServerVersion", "fieldtype":"int" }, + { + "fieldname": "m_szServerName", + "fieldtype": "char [64]", + "private": true + }, + { "fieldname":"m_szGameTags", "fieldtype":"char [128]" }, + { "fieldname":"m_steamID", "fieldtype":"CSteamID" } + ], + "methods": [ + { + "methodname": "Construct", + "methodname_flat": "SteamAPI_gameserveritem_t_Construct", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetName", + "methodname_flat": "SteamAPI_gameserveritem_t_GetName", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "SetName", + "methodname_flat": "SteamAPI_gameserveritem_t_SetName", + "params": [ + { "paramname":"pName", "paramtype":"const char *" } + ], + "returntype": "void" + } + ], + "struct": "gameserveritem_t" + }, + { + "fields": [ + { "fieldname":"m_eType", "fieldtype":"ESteamPartyBeaconLocationType" }, + { "fieldname":"m_ulLocationID", "fieldtype":"uint64" } + ], + "struct": "SteamPartyBeaconLocation_t" + }, + { + "fields": [ + { "fieldname":"m_ppStrings", "fieldtype":"const char **" }, + { "fieldname":"m_nNumStrings", "fieldtype":"int32" } + ], + "struct": "SteamParamStringArray_t" + }, + { + "fields": [ + { "fieldname":"m_steamIDUser", "fieldtype":"CSteamID" }, + { "fieldname":"m_nGlobalRank", "fieldtype":"int32" }, + { "fieldname":"m_nScore", "fieldtype":"int32" }, + { "fieldname":"m_cDetails", "fieldtype":"int32" }, + { "fieldname":"m_hUGC", "fieldtype":"UGCHandle_t" } + ], + "struct": "LeaderboardEntry_t" + }, + { + "fields": [ + { "fieldname":"m_bConnectionActive", "fieldtype":"uint8" }, + { "fieldname":"m_bConnecting", "fieldtype":"uint8" }, + { "fieldname":"m_eP2PSessionError", "fieldtype":"uint8" }, + { "fieldname":"m_bUsingRelay", "fieldtype":"uint8" }, + { "fieldname":"m_nBytesQueuedForSend", "fieldtype":"int32" }, + { "fieldname":"m_nPacketsQueuedForSend", "fieldtype":"int32" }, + { "fieldname":"m_nRemoteIP", "fieldtype":"uint32" }, + { "fieldname":"m_nRemotePort", "fieldtype":"uint16" } + ], + "struct": "P2PSessionState_t" + }, + { + "fields": [ + { "fieldname":"eMode", "fieldtype":"EInputSourceMode" }, + { "fieldname":"x", "fieldtype":"float" }, + { "fieldname":"y", "fieldtype":"float" }, + { "fieldname":"bActive", "fieldtype":"bool" } + ], + "struct": "InputAnalogActionData_t" + }, + { + "fields": [ + { "fieldname":"bState", "fieldtype":"bool" }, + { "fieldname":"bActive", "fieldtype":"bool" } + ], + "struct": "InputDigitalActionData_t" + }, + { + "fields": [ + { "fieldname":"rotQuatX", "fieldtype":"float" }, + { "fieldname":"rotQuatY", "fieldtype":"float" }, + { "fieldname":"rotQuatZ", "fieldtype":"float" }, + { "fieldname":"rotQuatW", "fieldtype":"float" }, + { "fieldname":"posAccelX", "fieldtype":"float" }, + { "fieldname":"posAccelY", "fieldtype":"float" }, + { "fieldname":"posAccelZ", "fieldtype":"float" }, + { "fieldname":"rotVelX", "fieldtype":"float" }, + { "fieldname":"rotVelY", "fieldtype":"float" }, + { "fieldname":"rotVelZ", "fieldtype":"float" } + ], + "struct": "InputMotionData_t" + }, + { + "fields": [ + { "fieldname":"controllerHandle", "fieldtype":"InputHandle_t" }, + { "fieldname":"eEventType", "fieldtype":"ESteamInputActionEventType" }, + { "fieldname":"analogAction", "fieldtype":"SteamInputActionEvent_t::AnalogAction_t" } + ], + "struct": "SteamInputActionEvent_t" + }, + { + "fields": [ + { "fieldname":"m_nPublishedFileId", "fieldtype":"PublishedFileId_t" }, + { "fieldname":"m_eResult", "fieldtype":"EResult" }, + { "fieldname":"m_eFileType", "fieldtype":"EWorkshopFileType" }, + { "fieldname":"m_nCreatorAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_nConsumerAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_rgchTitle", "fieldtype":"char [129]" }, + { "fieldname":"m_rgchDescription", "fieldtype":"char [8000]" }, + { "fieldname":"m_ulSteamIDOwner", "fieldtype":"uint64" }, + { "fieldname":"m_rtimeCreated", "fieldtype":"uint32" }, + { "fieldname":"m_rtimeUpdated", "fieldtype":"uint32" }, + { "fieldname":"m_rtimeAddedToUserList", "fieldtype":"uint32" }, + { "fieldname":"m_eVisibility", "fieldtype":"ERemoteStoragePublishedFileVisibility" }, + { "fieldname":"m_bBanned", "fieldtype":"bool" }, + { "fieldname":"m_bAcceptedForUse", "fieldtype":"bool" }, + { "fieldname":"m_bTagsTruncated", "fieldtype":"bool" }, + { "fieldname":"m_rgchTags", "fieldtype":"char [1025]" }, + { "fieldname":"m_hFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_hPreviewFile", "fieldtype":"UGCHandle_t" }, + { "fieldname":"m_pchFileName", "fieldtype":"char [260]" }, + { "fieldname":"m_nFileSize", "fieldtype":"int32" }, + { "fieldname":"m_nPreviewFileSize", "fieldtype":"int32" }, + { "fieldname":"m_rgchURL", "fieldtype":"char [256]" }, + { "fieldname":"m_unVotesUp", "fieldtype":"uint32" }, + { "fieldname":"m_unVotesDown", "fieldtype":"uint32" }, + { "fieldname":"m_flScore", "fieldtype":"float" }, + { "fieldname":"m_unNumChildren", "fieldtype":"uint32" } + ], + "struct": "SteamUGCDetails_t" + }, + { + "fields": [ + { "fieldname":"m_itemId", "fieldtype":"SteamItemInstanceID_t" }, + { "fieldname":"m_iDefinition", "fieldtype":"SteamItemDef_t" }, + { "fieldname":"m_unQuantity", "fieldtype":"uint16" }, + { "fieldname":"m_unFlags", "fieldtype":"uint16" } + ], + "struct": "SteamItemDetails_t" + }, + { + "consts": [ + { "constname":"k_cchMaxString", "consttype":"int", "constval":"48" } + ], + "fields": [ + { "fieldname":"m_ipv6", "fieldtype":"uint8 [16]" }, + { "fieldname":"m_port", "fieldtype":"uint16" } + ], + "methods": [ + { + "methodname": "Clear", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_Clear", + "params": [], + "returntype": "void" + }, + { + "methodname": "IsIPv6AllZeros", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_IsIPv6AllZeros", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetIPv6", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_SetIPv6", + "params": [ + { "paramname":"ipv6", "paramtype":"const uint8 *" }, + { "paramname":"nPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "SetIPv4", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_SetIPv4", + "params": [ + { "paramname":"nIP", "paramtype":"uint32" }, + { "paramname":"nPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "IsIPv4", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_IsIPv4", + "params": [], + "returntype": "bool" + }, + { + "methodname": "GetIPv4", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_GetIPv4", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "SetIPv6LocalHost", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost", + "params": [ + { "paramname":"nPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "IsLocalHost", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_IsLocalHost", + "params": [], + "returntype": "bool" + }, + { + "methodname": "ToString", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_ToString", + "params": [ + { "paramname":"buf", "paramtype":"char *" }, + { "paramname":"cbBuf", "paramtype":"uint32" }, + { "paramname":"bWithPort", "paramtype":"bool" } + ], + "returntype": "void" + }, + { + "methodname": "ParseString", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_ParseString", + "params": [ + { "paramname":"pszStr", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "operator==", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_IsEqualTo", + "params": [ + { "paramname":"x", "paramtype":"const SteamNetworkingIPAddr &" } + ], + "returntype": "bool" + }, + { + "methodname": "GetFakeIPType", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_GetFakeIPType", + "params": [], + "returntype": "ESteamNetworkingFakeIPType" + }, + { + "methodname": "IsFakeIP", + "methodname_flat": "SteamAPI_SteamNetworkingIPAddr_IsFakeIP", + "params": [], + "returntype": "bool" + } + ], + "struct": "SteamNetworkingIPAddr" + }, + { + "consts": [ + { "constname":"k_cchMaxString", "consttype":"int", "constval":"128" }, + { "constname":"k_cchMaxGenericString", "consttype":"int", "constval":"32" }, + { "constname":"k_cchMaxXboxPairwiseID", "consttype":"int", "constval":"33" }, + { "constname":"k_cbMaxGenericBytes", "consttype":"int", "constval":"32" } + ], + "fields": [ + { "fieldname":"m_eType", "fieldtype":"ESteamNetworkingIdentityType" }, + { "fieldname":"m_cbSize", "fieldtype":"int" }, + { "fieldname":"m_szUnknownRawString", "fieldtype":"char [128]" } + ], + "methods": [ + { + "methodname": "Clear", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_Clear", + "params": [], + "returntype": "void" + }, + { + "methodname": "IsInvalid", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_IsInvalid", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetSteamID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetSteamID", + "params": [ + { "paramname":"steamID", "paramtype":"CSteamID", "paramtype_flat":"uint64_steamid" } + ], + "returntype": "void" + }, + { + "methodname": "GetSteamID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetSteamID", + "params": [], + "returntype": "CSteamID", + "returntype_flat": "uint64_steamid" + }, + { + "methodname": "SetSteamID64", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetSteamID64", + "params": [ + { "paramname":"steamID", "paramtype":"uint64" } + ], + "returntype": "void" + }, + { + "methodname": "GetSteamID64", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetSteamID64", + "params": [], + "returntype": "uint64" + }, + { + "methodname": "SetXboxPairwiseID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetXboxPairwiseID", + "params": [ + { "paramname":"pszString", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetXboxPairwiseID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetXboxPairwiseID", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "SetPSNID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetPSNID", + "params": [ + { "paramname":"id", "paramtype":"uint64" } + ], + "returntype": "void" + }, + { + "methodname": "GetPSNID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetPSNID", + "params": [], + "returntype": "uint64" + }, + { + "methodname": "SetStadiaID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetStadiaID", + "params": [ + { "paramname":"id", "paramtype":"uint64" } + ], + "returntype": "void" + }, + { + "methodname": "GetStadiaID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetStadiaID", + "params": [], + "returntype": "uint64" + }, + { + "methodname": "SetIPAddr", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetIPAddr", + "params": [ + { "paramname":"addr", "paramtype":"const SteamNetworkingIPAddr &" } + ], + "returntype": "void" + }, + { + "methodname": "GetIPAddr", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetIPAddr", + "params": [], + "returntype": "const SteamNetworkingIPAddr *" + }, + { + "methodname": "SetIPv4Addr", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetIPv4Addr", + "params": [ + { "paramname":"nIPv4", "paramtype":"uint32" }, + { "paramname":"nPort", "paramtype":"uint16" } + ], + "returntype": "void" + }, + { + "methodname": "GetIPv4", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetIPv4", + "params": [], + "returntype": "uint32" + }, + { + "methodname": "GetFakeIPType", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetFakeIPType", + "params": [], + "returntype": "ESteamNetworkingFakeIPType" + }, + { + "methodname": "IsFakeIP", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_IsFakeIP", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetLocalHost", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetLocalHost", + "params": [], + "returntype": "void" + }, + { + "methodname": "IsLocalHost", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_IsLocalHost", + "params": [], + "returntype": "bool" + }, + { + "methodname": "SetGenericString", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetGenericString", + "params": [ + { "paramname":"pszString", "paramtype":"const char *" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGenericString", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetGenericString", + "params": [], + "returntype": "const char *" + }, + { + "methodname": "SetGenericBytes", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetGenericBytes", + "params": [ + { "paramname":"data", "paramtype":"const void *" }, + { "paramname":"cbLen", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetGenericBytes", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetGenericBytes", + "params": [ + { "paramname":"cbLen", "paramtype":"int &" } + ], + "returntype": "const uint8 *" + }, + { + "methodname": "operator==", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_IsEqualTo", + "params": [ + { "paramname":"x", "paramtype":"const SteamNetworkingIdentity &" } + ], + "returntype": "bool" + }, + { + "methodname": "ToString", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_ToString", + "params": [ + { "paramname":"buf", "paramtype":"char *" }, + { "paramname":"cbBuf", "paramtype":"uint32" } + ], + "returntype": "void" + }, + { + "methodname": "ParseString", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_ParseString", + "params": [ + { "paramname":"pszStr", "paramtype":"const char *" } + ], + "returntype": "bool" + } + ], + "struct": "SteamNetworkingIdentity" + }, + { + "fields": [ + { "fieldname":"m_identityRemote", "fieldtype":"SteamNetworkingIdentity" }, + { "fieldname":"m_nUserData", "fieldtype":"int64" }, + { "fieldname":"m_hListenSocket", "fieldtype":"HSteamListenSocket" }, + { "fieldname":"m_addrRemote", "fieldtype":"SteamNetworkingIPAddr" }, + { "fieldname":"m__pad1", "fieldtype":"uint16" }, + { "fieldname":"m_idPOPRemote", "fieldtype":"SteamNetworkingPOPID" }, + { "fieldname":"m_idPOPRelay", "fieldtype":"SteamNetworkingPOPID" }, + { "fieldname":"m_eState", "fieldtype":"ESteamNetworkingConnectionState" }, + { "fieldname":"m_eEndReason", "fieldtype":"int" }, + { "fieldname":"m_szEndDebug", "fieldtype":"char [128]" }, + { "fieldname":"m_szConnectionDescription", "fieldtype":"char [128]" }, + { "fieldname":"m_nFlags", "fieldtype":"int" }, + { "fieldname":"reserved", "fieldtype":"uint32 [63]" } + ], + "struct": "SteamNetConnectionInfo_t" + }, + { + "fields": [ + { "fieldname":"m_eState", "fieldtype":"ESteamNetworkingConnectionState" }, + { "fieldname":"m_nPing", "fieldtype":"int" }, + { "fieldname":"m_flConnectionQualityLocal", "fieldtype":"float" }, + { "fieldname":"m_flConnectionQualityRemote", "fieldtype":"float" }, + { "fieldname":"m_flOutPacketsPerSec", "fieldtype":"float" }, + { "fieldname":"m_flOutBytesPerSec", "fieldtype":"float" }, + { "fieldname":"m_flInPacketsPerSec", "fieldtype":"float" }, + { "fieldname":"m_flInBytesPerSec", "fieldtype":"float" }, + { "fieldname":"m_nSendRateBytesPerSecond", "fieldtype":"int" }, + { "fieldname":"m_cbPendingUnreliable", "fieldtype":"int" }, + { "fieldname":"m_cbPendingReliable", "fieldtype":"int" }, + { "fieldname":"m_cbSentUnackedReliable", "fieldtype":"int" }, + { "fieldname":"m_usecQueueTime", "fieldtype":"SteamNetworkingMicroseconds" }, + { "fieldname":"reserved", "fieldtype":"uint32 [16]" } + ], + "struct": "SteamNetConnectionRealTimeStatus_t" + }, + { + "fields": [ + { "fieldname":"m_cbPendingUnreliable", "fieldtype":"int" }, + { "fieldname":"m_cbPendingReliable", "fieldtype":"int" }, + { "fieldname":"m_cbSentUnackedReliable", "fieldtype":"int" }, + { "fieldname":"_reservePad1", "fieldtype":"int" }, + { "fieldname":"m_usecQueueTime", "fieldtype":"SteamNetworkingMicroseconds" }, + { "fieldname":"reserved", "fieldtype":"uint32 [10]" } + ], + "struct": "SteamNetConnectionRealTimeLaneStatus_t" + }, + { + "fields": [ + { "fieldname":"m_pData", "fieldtype":"void *" }, + { "fieldname":"m_cbSize", "fieldtype":"int" }, + { "fieldname":"m_conn", "fieldtype":"HSteamNetConnection" }, + { "fieldname":"m_identityPeer", "fieldtype":"SteamNetworkingIdentity" }, + { "fieldname":"m_nConnUserData", "fieldtype":"int64" }, + { "fieldname":"m_usecTimeReceived", "fieldtype":"SteamNetworkingMicroseconds" }, + { "fieldname":"m_nMessageNumber", "fieldtype":"int64" }, + { "fieldname":"m_pfnFreeData", "fieldtype":"void (*)(SteamNetworkingMessage_t *)" }, + { "fieldname":"m_pfnRelease", "fieldtype":"void (*)(SteamNetworkingMessage_t *)" }, + { "fieldname":"m_nChannel", "fieldtype":"int" }, + { "fieldname":"m_nFlags", "fieldtype":"int" }, + { "fieldname":"m_nUserData", "fieldtype":"int64" }, + { "fieldname":"m_idxLane", "fieldtype":"uint16" }, + { "fieldname":"_pad1__", "fieldtype":"uint16" } + ], + "methods": [ + { + "methodname": "Release", + "methodname_flat": "SteamAPI_SteamNetworkingMessage_t_Release", + "params": [], + "returntype": "void" + } + ], + "struct": "SteamNetworkingMessage_t" + }, + { + "fields": [ + { "fieldname":"m_data", "fieldtype":"uint8 [512]" } + ], + "struct": "SteamNetworkPingLocation_t" + }, + { + "fields": [ + { "fieldname":"m_eValue", "fieldtype":"ESteamNetworkingConfigValue" }, + { "fieldname":"m_eDataType", "fieldtype":"ESteamNetworkingConfigDataType" }, + { "fieldname":"m_int64", "fieldtype":"int64_t" } + ], + "methods": [ + { + "methodname": "SetInt32", + "methodname_flat": "SteamAPI_SteamNetworkingConfigValue_t_SetInt32", + "params": [ + { "paramname":"eVal", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"data", "paramtype":"int32_t" } + ], + "returntype": "void" + }, + { + "methodname": "SetInt64", + "methodname_flat": "SteamAPI_SteamNetworkingConfigValue_t_SetInt64", + "params": [ + { "paramname":"eVal", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"data", "paramtype":"int64_t" } + ], + "returntype": "void" + }, + { + "methodname": "SetFloat", + "methodname_flat": "SteamAPI_SteamNetworkingConfigValue_t_SetFloat", + "params": [ + { "paramname":"eVal", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"data", "paramtype":"float" } + ], + "returntype": "void" + }, + { + "methodname": "SetPtr", + "methodname_flat": "SteamAPI_SteamNetworkingConfigValue_t_SetPtr", + "params": [ + { "paramname":"eVal", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"data", "paramtype":"void *" } + ], + "returntype": "void" + }, + { + "methodname": "SetString", + "methodname_flat": "SteamAPI_SteamNetworkingConfigValue_t_SetString", + "params": [ + { "paramname":"eVal", "paramtype":"ESteamNetworkingConfigValue" }, + { "paramname":"data", "paramtype":"const char *" } + ], + "returntype": "void" + } + ], + "struct": "SteamNetworkingConfigValue_t" + }, + { + "fields": [ + { "fieldname":"m_cbSize", "fieldtype":"int" }, + { "fieldname":"m_data", "fieldtype":"char [128]" } + ], + "methods": [ + { + "methodname": "Clear", + "methodname_flat": "SteamAPI_SteamDatagramHostedAddress_Clear", + "params": [], + "returntype": "void" + }, + { + "methodname": "GetPopID", + "methodname_flat": "SteamAPI_SteamDatagramHostedAddress_GetPopID", + "params": [], + "returntype": "SteamNetworkingPOPID" + }, + { + "methodname": "SetDevAddress", + "methodname_flat": "SteamAPI_SteamDatagramHostedAddress_SetDevAddress", + "params": [ + { "paramname":"nIP", "paramtype":"uint32" }, + { "paramname":"nPort", "paramtype":"uint16" }, + { "paramname":"popid", "paramtype":"SteamNetworkingPOPID" } + ], + "returntype": "void" + } + ], + "struct": "SteamDatagramHostedAddress" + }, + { + "fields": [ + { "fieldname":"m_identity", "fieldtype":"SteamNetworkingIdentity" }, + { "fieldname":"m_routing", "fieldtype":"SteamDatagramHostedAddress" }, + { "fieldname":"m_nAppID", "fieldtype":"AppId_t" }, + { "fieldname":"m_rtime", "fieldtype":"RTime32" }, + { "fieldname":"m_cbAppData", "fieldtype":"int" }, + { "fieldname":"m_appData", "fieldtype":"char [2048]" } + ], + "struct": "SteamDatagramGameCoordinatorServerLogin" + } + ], + "typedefs": [ + { "typedef":"uint8", "type":"unsigned char" }, + { "typedef":"int8", "type":"signed char" }, + { "typedef":"int16", "type":"short" }, + { "typedef":"uint16", "type":"unsigned short" }, + { "typedef":"int32", "type":"int" }, + { "typedef":"uint32", "type":"unsigned int" }, + { "typedef":"int64", "type":"long long" }, + { "typedef":"uint64", "type":"unsigned long long" }, + { "typedef":"lint64", "type":"long long" }, + { "typedef":"ulint64", "type":"unsigned long long" }, + { "typedef":"intp", "type":"long long" }, + { "typedef":"uintp", "type":"unsigned long long" }, + { "typedef":"AppId_t", "type":"unsigned int" }, + { "typedef":"DepotId_t", "type":"unsigned int" }, + { "typedef":"RTime32", "type":"unsigned int" }, + { "typedef":"SteamAPICall_t", "type":"unsigned long long" }, + { "typedef":"AccountID_t", "type":"unsigned int" }, + { "typedef":"PartyBeaconID_t", "type":"unsigned long long" }, + { "typedef":"HAuthTicket", "type":"unsigned int" }, + { "typedef":"PFNPreMinidumpCallback", "type":"void (*)(void *)" }, + { "typedef":"HSteamPipe", "type":"int" }, + { "typedef":"HSteamUser", "type":"int" }, + { "typedef":"FriendsGroupID_t", "type":"short" }, + { "typedef":"HServerListRequest", "type":"void *" }, + { "typedef":"HServerQuery", "type":"int" }, + { "typedef":"UGCHandle_t", "type":"unsigned long long" }, + { "typedef":"PublishedFileUpdateHandle_t", "type":"unsigned long long" }, + { "typedef":"PublishedFileId_t", "type":"unsigned long long" }, + { "typedef":"UGCFileWriteStreamHandle_t", "type":"unsigned long long" }, + { "typedef":"SteamLeaderboard_t", "type":"unsigned long long" }, + { "typedef":"SteamLeaderboardEntries_t", "type":"unsigned long long" }, + { "typedef":"SNetSocket_t", "type":"unsigned int" }, + { "typedef":"SNetListenSocket_t", "type":"unsigned int" }, + { "typedef":"ScreenshotHandle", "type":"unsigned int" }, + { "typedef":"HTTPRequestHandle", "type":"unsigned int" }, + { "typedef":"HTTPCookieContainerHandle", "type":"unsigned int" }, + { "typedef":"InputHandle_t", "type":"unsigned long long" }, + { "typedef":"InputActionSetHandle_t", "type":"unsigned long long" }, + { "typedef":"InputDigitalActionHandle_t", "type":"unsigned long long" }, + { "typedef":"InputAnalogActionHandle_t", "type":"unsigned long long" }, + { "typedef":"SteamInputActionEventCallbackPointer", "type":"void (*)(SteamInputActionEvent_t *)" }, + { "typedef":"ControllerHandle_t", "type":"unsigned long long" }, + { "typedef":"ControllerActionSetHandle_t", "type":"unsigned long long" }, + { "typedef":"ControllerDigitalActionHandle_t", "type":"unsigned long long" }, + { "typedef":"ControllerAnalogActionHandle_t", "type":"unsigned long long" }, + { "typedef":"UGCQueryHandle_t", "type":"unsigned long long" }, + { "typedef":"UGCUpdateHandle_t", "type":"unsigned long long" }, + { "typedef":"HHTMLBrowser", "type":"unsigned int" }, + { "typedef":"SteamItemInstanceID_t", "type":"unsigned long long" }, + { "typedef":"SteamItemDef_t", "type":"int" }, + { "typedef":"SteamInventoryResult_t", "type":"int" }, + { "typedef":"SteamInventoryUpdateHandle_t", "type":"unsigned long long" }, + { "typedef":"RemotePlaySessionID_t", "type":"unsigned int" }, + { "typedef":"FnSteamNetConnectionStatusChanged", "type":"void (*)(SteamNetConnectionStatusChangedCallback_t *)" }, + { "typedef":"FnSteamNetAuthenticationStatusChanged", "type":"void (*)(SteamNetAuthenticationStatus_t *)" }, + { "typedef":"FnSteamRelayNetworkStatusChanged", "type":"void (*)(SteamRelayNetworkStatus_t *)" }, + { "typedef":"FnSteamNetworkingMessagesSessionRequest", "type":"void (*)(SteamNetworkingMessagesSessionRequest_t *)" }, + { "typedef":"FnSteamNetworkingMessagesSessionFailed", "type":"void (*)(SteamNetworkingMessagesSessionFailed_t *)" }, + { "typedef":"FnSteamNetworkingFakeIPResult", "type":"void (*)(SteamNetworkingFakeIPResult_t *)" }, + { "typedef":"HSteamNetConnection", "type":"unsigned int" }, + { "typedef":"HSteamListenSocket", "type":"unsigned int" }, + { "typedef":"HSteamNetPollGroup", "type":"unsigned int" }, + { "typedef":"SteamNetworkingErrMsg", "type":"char [1024]" }, + { "typedef":"SteamNetworkingPOPID", "type":"unsigned int" }, + { "typedef":"SteamNetworkingMicroseconds", "type":"long long" }, + { "typedef":"FSteamNetworkingSocketsDebugOutput", "type":"void (*)(ESteamNetworkingSocketsDebugOutputType, const char *)" } + ] +} diff --git a/public/steam/steam_api_common.h b/public/steam/steam_api_common.h new file mode 100644 index 00000000..005fb117 --- /dev/null +++ b/public/steam/steam_api_common.h @@ -0,0 +1,235 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== +// +// Steamworks SDK minimal include +// +// Defines the minimal set of things we need to use any single interface +// or register for any callback. +// +//============================================================================= + +#ifndef STEAM_API_COMMON_H +#define STEAM_API_COMMON_H +#ifdef _WIN32 +#pragma once +#endif + +#include "steamtypes.h" +#include "steamclientpublic.h" + +// S_API defines the linkage and calling conventions for steam_api.dll exports +#if defined( _WIN32 ) && !defined( _X360 ) + #if defined( STEAM_API_EXPORTS ) + #define S_API extern "C" __declspec( dllexport ) + #elif defined( STEAM_API_NODLL ) + #define S_API extern "C" + #else + #define S_API extern "C" __declspec( dllimport ) + #endif // STEAM_API_EXPORTS +#elif defined( GNUC ) + #if defined( STEAM_API_EXPORTS ) + #define S_API extern "C" __attribute__ ((visibility("default"))) + #else + #define S_API extern "C" + #endif // STEAM_API_EXPORTS +#else // !WIN32 + #if defined( STEAM_API_EXPORTS ) + #define S_API extern "C" + #else + #define S_API extern "C" + #endif // STEAM_API_EXPORTS +#endif + +#if ( defined(STEAM_API_EXPORTS) || defined(STEAM_API_NODLL) ) && !defined(API_GEN) +#define STEAM_PRIVATE_API( ... ) __VA_ARGS__ +#elif defined(STEAM_API_EXPORTS) && defined(API_GEN) +#define STEAM_PRIVATE_API( ... ) +#else +#define STEAM_PRIVATE_API( ... ) protected: __VA_ARGS__ public: +#endif + +// handle to a communication pipe to the Steam client +typedef int32 HSteamPipe; +// handle to single instance of a steam user +typedef int32 HSteamUser; +// function prototype +#if defined( POSIX ) +#define __cdecl +#endif +extern "C" typedef void (__cdecl *SteamAPIWarningMessageHook_t)(int, const char *); +extern "C" typedef uint32 ( *SteamAPI_CheckCallbackRegistered_t )( int iCallbackNum ); +#if defined( __SNC__ ) + #pragma diag_suppress=1700 // warning 1700: class "%s" has virtual functions but non-virtual destructor +#endif + +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +// steam callback and call-result helpers +// +// The following macros and classes are used to register your application for +// callbacks and call-results, which are delivered in a predictable manner. +// +// STEAM_CALLBACK macros are meant for use inside of a C++ class definition. +// They map a Steam notification callback directly to a class member function +// which is automatically prototyped as "void func( callback_type *pParam )". +// +// CCallResult is used with specific Steam APIs that return "result handles". +// The handle can be passed to a CCallResult object's Set function, along with +// an object pointer and member-function pointer. The member function will +// be executed once the results of the Steam API call are available. +// +// CCallback and CCallbackManual classes can be used instead of STEAM_CALLBACK +// macros if you require finer control over registration and unregistration. +// +// Callbacks and call-results are queued automatically and are only +// delivered/executed when your application calls SteamAPI_RunCallbacks(). +// +// Note that there is an alternative, lower level callback dispatch mechanism. +// See SteamAPI_ManualDispatch_Init +//----------------------------------------------------------------------------------------------------------------------------------------------------------// + +// Dispatch all queued Steamworks callbacks. +// +// This is safe to call from multiple threads simultaneously, +// but if you choose to do this, callback code could be executed on any thread. +// One alternative is to call SteamAPI_RunCallbacks from the main thread only, +// and call SteamAPI_ReleaseCurrentThreadMemory regularly on other threads. +S_API void S_CALLTYPE SteamAPI_RunCallbacks(); + +// Declares a callback member function plus a helper member variable which +// registers the callback on object creation and unregisters on destruction. +// The optional fourth 'var' param exists only for backwards-compatibility +// and can be ignored. +#define STEAM_CALLBACK( thisclass, func, .../*callback_type, [deprecated] var*/ ) \ + _STEAM_CALLBACK_SELECT( ( __VA_ARGS__, 4, 3 ), ( /**/, thisclass, func, __VA_ARGS__ ) ) + +// Declares a callback function and a named CCallbackManual variable which +// has Register and Unregister functions instead of automatic registration. +#define STEAM_CALLBACK_MANUAL( thisclass, func, callback_type, var ) \ + CCallbackManual< thisclass, callback_type > var; void func( callback_type *pParam ) + +// Dispatch callbacks relevant to the gameserver client and interfaces. +// To register for these, you need to use STEAM_GAMESERVER_CALLBACK. +// (Or call SetGameserverFlag on your CCallbackBase object.) +S_API void S_CALLTYPE SteamGameServer_RunCallbacks(); + +// Same as STEAM_CALLBACK, but for callbacks on the gameserver interface. +// These will be dispatched during SteamGameServer_RunCallbacks +#define STEAM_GAMESERVER_CALLBACK( thisclass, func, /*callback_type, [deprecated] var*/... ) \ + _STEAM_CALLBACK_SELECT( ( __VA_ARGS__, GS, 3 ), ( this->SetGameserverFlag();, thisclass, func, __VA_ARGS__ ) ) +#define STEAM_GAMESERVER_CALLBACK_MANUAL( thisclass, func, callback_type, var ) \ + CCallbackManual< thisclass, callback_type, true > var; void func( callback_type *pParam ) + +//----------------------------------------------------------------------------- +// Purpose: base for callbacks and call results - internal implementation detail +//----------------------------------------------------------------------------- +class CCallbackBase +{ +public: + CCallbackBase() { m_nCallbackFlags = 0; m_iCallback = 0; } + // don't add a virtual destructor because we export this binary interface across dll's + virtual void Run( void *pvParam ) = 0; + virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) = 0; + int GetICallback() { return m_iCallback; } + virtual int GetCallbackSizeBytes() = 0; + +protected: + enum { k_ECallbackFlagsRegistered = 0x01, k_ECallbackFlagsGameServer = 0x02 }; + uint8 m_nCallbackFlags; + int m_iCallback; + friend class CCallbackMgr; + +private: + CCallbackBase( const CCallbackBase& ); + CCallbackBase& operator=( const CCallbackBase& ); +}; + +//----------------------------------------------------------------------------- +// Purpose: templated base for callbacks - internal implementation detail +//----------------------------------------------------------------------------- +template< int sizeof_P > +class CCallbackImpl : protected CCallbackBase +{ +public: + virtual ~CCallbackImpl() { if ( m_nCallbackFlags & k_ECallbackFlagsRegistered ) SteamAPI_UnregisterCallback( this ); } + void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; } + +protected: + friend class CCallbackMgr; + virtual void Run( void *pvParam ) = 0; + virtual void Run( void *pvParam, bool /*bIOFailure*/, SteamAPICall_t /*hSteamAPICall*/ ) { Run( pvParam ); } + virtual int GetCallbackSizeBytes() { return sizeof_P; } +}; + + +//----------------------------------------------------------------------------- +// Purpose: maps a steam async call result to a class member function +// template params: T = local class, P = parameter struct +//----------------------------------------------------------------------------- +template< class T, class P > +class CCallResult : private CCallbackBase +{ +public: + typedef void (T::*func_t)( P*, bool ); + + CCallResult(); + ~CCallResult(); + + void Set( SteamAPICall_t hAPICall, T *p, func_t func ); + bool IsActive() const; + void Cancel(); + + void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; } +private: + virtual void Run( void *pvParam ); + virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ); + virtual int GetCallbackSizeBytes() { return sizeof( P ); } + + SteamAPICall_t m_hAPICall; + T *m_pObj; + func_t m_Func; +}; + + + +//----------------------------------------------------------------------------- +// Purpose: maps a steam callback to a class member function +// template params: T = local class, P = parameter struct, +// bGameserver = listen for gameserver callbacks instead of client callbacks +//----------------------------------------------------------------------------- +template< class T, class P, bool bGameserver = false > +class CCallback : public CCallbackImpl< sizeof( P ) > +{ +public: + typedef void (T::*func_t)(P*); + + // NOTE: If you can't provide the correct parameters at construction time, you should + // use the CCallbackManual callback object (STEAM_CALLBACK_MANUAL macro) instead. + CCallback( T *pObj, func_t func ); + + void Register( T *pObj, func_t func ); + void Unregister(); + +protected: + virtual void Run( void *pvParam ); + + T *m_pObj; + func_t m_Func; +}; + + +//----------------------------------------------------------------------------- +// Purpose: subclass of CCallback which allows default-construction in +// an unregistered state; you must call Register manually +//----------------------------------------------------------------------------- +template< class T, class P, bool bGameServer = false > +class CCallbackManual : public CCallback< T, P, bGameServer > +{ +public: + CCallbackManual() : CCallback< T, P, bGameServer >( nullptr, nullptr ) {} + + // Inherits public Register and Unregister functions from base class +}; + +// Internal implementation details for all of the above +#include "steam_api_internal.h" + +#endif // STEAM_API_COMMON_H diff --git a/public/steam/steam_api_flat.h b/public/steam/steam_api_flat.h new file mode 100644 index 00000000..d0e3c48a --- /dev/null +++ b/public/steam/steam_api_flat.h @@ -0,0 +1,1274 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== +// +// Purpose: Header for "flat" SteamAPI. Use this for binding to other languages. +// This file is auto-generated, do not edit it. +// +//============================================================================= + +#ifndef STEAMAPIFLAT_H +#define STEAMAPIFLAT_H + +#include "steam/steam_api.h" +#include "steam/isteamgameserver.h" +#include "steam/isteamgameserverstats.h" + +typedef uint64 uint64_steamid; // Used when passing or returning CSteamID +typedef uint64 uint64_gameid; // Used when passing or return CGameID + + + +// ISteamClient +S_API HSteamPipe SteamAPI_ISteamClient_CreateSteamPipe( ISteamClient* self ); +S_API bool SteamAPI_ISteamClient_BReleaseSteamPipe( ISteamClient* self, HSteamPipe hSteamPipe ); +S_API HSteamUser SteamAPI_ISteamClient_ConnectToGlobalUser( ISteamClient* self, HSteamPipe hSteamPipe ); +S_API HSteamUser SteamAPI_ISteamClient_CreateLocalUser( ISteamClient* self, HSteamPipe * phSteamPipe, EAccountType eAccountType ); +S_API void SteamAPI_ISteamClient_ReleaseUser( ISteamClient* self, HSteamPipe hSteamPipe, HSteamUser hUser ); +S_API ISteamUser * SteamAPI_ISteamClient_GetISteamUser( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamGameServer * SteamAPI_ISteamClient_GetISteamGameServer( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API void SteamAPI_ISteamClient_SetLocalIPBinding( ISteamClient* self, const SteamIPAddress_t & unIP, uint16 usPort ); +S_API ISteamFriends * SteamAPI_ISteamClient_GetISteamFriends( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamUtils * SteamAPI_ISteamClient_GetISteamUtils( ISteamClient* self, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamMatchmaking * SteamAPI_ISteamClient_GetISteamMatchmaking( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamMatchmakingServers * SteamAPI_ISteamClient_GetISteamMatchmakingServers( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API void * SteamAPI_ISteamClient_GetISteamGenericInterface( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamUserStats * SteamAPI_ISteamClient_GetISteamUserStats( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamGameServerStats * SteamAPI_ISteamClient_GetISteamGameServerStats( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamApps * SteamAPI_ISteamClient_GetISteamApps( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamNetworking * SteamAPI_ISteamClient_GetISteamNetworking( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamRemoteStorage * SteamAPI_ISteamClient_GetISteamRemoteStorage( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamScreenshots * SteamAPI_ISteamClient_GetISteamScreenshots( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamGameSearch * SteamAPI_ISteamClient_GetISteamGameSearch( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API uint32 SteamAPI_ISteamClient_GetIPCCallCount( ISteamClient* self ); +S_API void SteamAPI_ISteamClient_SetWarningMessageHook( ISteamClient* self, SteamAPIWarningMessageHook_t pFunction ); +S_API bool SteamAPI_ISteamClient_BShutdownIfAllPipesClosed( ISteamClient* self ); +S_API ISteamHTTP * SteamAPI_ISteamClient_GetISteamHTTP( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamController * SteamAPI_ISteamClient_GetISteamController( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamUGC * SteamAPI_ISteamClient_GetISteamUGC( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamAppList * SteamAPI_ISteamClient_GetISteamAppList( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamMusic * SteamAPI_ISteamClient_GetISteamMusic( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamMusicRemote * SteamAPI_ISteamClient_GetISteamMusicRemote( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamHTMLSurface * SteamAPI_ISteamClient_GetISteamHTMLSurface( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamInventory * SteamAPI_ISteamClient_GetISteamInventory( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamVideo * SteamAPI_ISteamClient_GetISteamVideo( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamParentalSettings * SteamAPI_ISteamClient_GetISteamParentalSettings( ISteamClient* self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamInput * SteamAPI_ISteamClient_GetISteamInput( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamParties * SteamAPI_ISteamClient_GetISteamParties( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); +S_API ISteamRemotePlay * SteamAPI_ISteamClient_GetISteamRemotePlay( ISteamClient* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char * pchVersion ); + +// ISteamUser + +// A versioned accessor is exported by the library +S_API ISteamUser *SteamAPI_SteamUser_v021(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamUser(), but using this ensures that you are using a matching library. +inline ISteamUser *SteamAPI_SteamUser() { return SteamAPI_SteamUser_v021(); } +S_API HSteamUser SteamAPI_ISteamUser_GetHSteamUser( ISteamUser* self ); +S_API bool SteamAPI_ISteamUser_BLoggedOn( ISteamUser* self ); +S_API uint64_steamid SteamAPI_ISteamUser_GetSteamID( ISteamUser* self ); +S_API int SteamAPI_ISteamUser_InitiateGameConnection_DEPRECATED( ISteamUser* self, void * pAuthBlob, int cbMaxAuthBlob, uint64_steamid steamIDGameServer, uint32 unIPServer, uint16 usPortServer, bool bSecure ); +S_API void SteamAPI_ISteamUser_TerminateGameConnection_DEPRECATED( ISteamUser* self, uint32 unIPServer, uint16 usPortServer ); +S_API void SteamAPI_ISteamUser_TrackAppUsageEvent( ISteamUser* self, uint64_gameid gameID, int eAppUsageEvent, const char * pchExtraInfo ); +S_API bool SteamAPI_ISteamUser_GetUserDataFolder( ISteamUser* self, char * pchBuffer, int cubBuffer ); +S_API void SteamAPI_ISteamUser_StartVoiceRecording( ISteamUser* self ); +S_API void SteamAPI_ISteamUser_StopVoiceRecording( ISteamUser* self ); +S_API EVoiceResult SteamAPI_ISteamUser_GetAvailableVoice( ISteamUser* self, uint32 * pcbCompressed, uint32 * pcbUncompressed_Deprecated, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated ); +S_API EVoiceResult SteamAPI_ISteamUser_GetVoice( ISteamUser* self, bool bWantCompressed, void * pDestBuffer, uint32 cbDestBufferSize, uint32 * nBytesWritten, bool bWantUncompressed_Deprecated, void * pUncompressedDestBuffer_Deprecated, uint32 cbUncompressedDestBufferSize_Deprecated, uint32 * nUncompressBytesWritten_Deprecated, uint32 nUncompressedVoiceDesiredSampleRate_Deprecated ); +S_API EVoiceResult SteamAPI_ISteamUser_DecompressVoice( ISteamUser* self, const void * pCompressed, uint32 cbCompressed, void * pDestBuffer, uint32 cbDestBufferSize, uint32 * nBytesWritten, uint32 nDesiredSampleRate ); +S_API uint32 SteamAPI_ISteamUser_GetVoiceOptimalSampleRate( ISteamUser* self ); +S_API HAuthTicket SteamAPI_ISteamUser_GetAuthSessionTicket( ISteamUser* self, void * pTicket, int cbMaxTicket, uint32 * pcbTicket ); +S_API EBeginAuthSessionResult SteamAPI_ISteamUser_BeginAuthSession( ISteamUser* self, const void * pAuthTicket, int cbAuthTicket, uint64_steamid steamID ); +S_API void SteamAPI_ISteamUser_EndAuthSession( ISteamUser* self, uint64_steamid steamID ); +S_API void SteamAPI_ISteamUser_CancelAuthTicket( ISteamUser* self, HAuthTicket hAuthTicket ); +S_API EUserHasLicenseForAppResult SteamAPI_ISteamUser_UserHasLicenseForApp( ISteamUser* self, uint64_steamid steamID, AppId_t appID ); +S_API bool SteamAPI_ISteamUser_BIsBehindNAT( ISteamUser* self ); +S_API void SteamAPI_ISteamUser_AdvertiseGame( ISteamUser* self, uint64_steamid steamIDGameServer, uint32 unIPServer, uint16 usPortServer ); +S_API SteamAPICall_t SteamAPI_ISteamUser_RequestEncryptedAppTicket( ISteamUser* self, void * pDataToInclude, int cbDataToInclude ); +S_API bool SteamAPI_ISteamUser_GetEncryptedAppTicket( ISteamUser* self, void * pTicket, int cbMaxTicket, uint32 * pcbTicket ); +S_API int SteamAPI_ISteamUser_GetGameBadgeLevel( ISteamUser* self, int nSeries, bool bFoil ); +S_API int SteamAPI_ISteamUser_GetPlayerSteamLevel( ISteamUser* self ); +S_API SteamAPICall_t SteamAPI_ISteamUser_RequestStoreAuthURL( ISteamUser* self, const char * pchRedirectURL ); +S_API bool SteamAPI_ISteamUser_BIsPhoneVerified( ISteamUser* self ); +S_API bool SteamAPI_ISteamUser_BIsTwoFactorEnabled( ISteamUser* self ); +S_API bool SteamAPI_ISteamUser_BIsPhoneIdentifying( ISteamUser* self ); +S_API bool SteamAPI_ISteamUser_BIsPhoneRequiringVerification( ISteamUser* self ); +S_API SteamAPICall_t SteamAPI_ISteamUser_GetMarketEligibility( ISteamUser* self ); +S_API SteamAPICall_t SteamAPI_ISteamUser_GetDurationControl( ISteamUser* self ); +S_API bool SteamAPI_ISteamUser_BSetDurationControlOnlineState( ISteamUser* self, EDurationControlOnlineState eNewState ); + +// ISteamFriends + +// A versioned accessor is exported by the library +S_API ISteamFriends *SteamAPI_SteamFriends_v017(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamFriends(), but using this ensures that you are using a matching library. +inline ISteamFriends *SteamAPI_SteamFriends() { return SteamAPI_SteamFriends_v017(); } +S_API const char * SteamAPI_ISteamFriends_GetPersonaName( ISteamFriends* self ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_SetPersonaName( ISteamFriends* self, const char * pchPersonaName ); +S_API EPersonaState SteamAPI_ISteamFriends_GetPersonaState( ISteamFriends* self ); +S_API int SteamAPI_ISteamFriends_GetFriendCount( ISteamFriends* self, int iFriendFlags ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetFriendByIndex( ISteamFriends* self, int iFriend, int iFriendFlags ); +S_API EFriendRelationship SteamAPI_ISteamFriends_GetFriendRelationship( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API EPersonaState SteamAPI_ISteamFriends_GetFriendPersonaState( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API const char * SteamAPI_ISteamFriends_GetFriendPersonaName( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API bool SteamAPI_ISteamFriends_GetFriendGamePlayed( ISteamFriends* self, uint64_steamid steamIDFriend, FriendGameInfo_t * pFriendGameInfo ); +S_API const char * SteamAPI_ISteamFriends_GetFriendPersonaNameHistory( ISteamFriends* self, uint64_steamid steamIDFriend, int iPersonaName ); +S_API int SteamAPI_ISteamFriends_GetFriendSteamLevel( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API const char * SteamAPI_ISteamFriends_GetPlayerNickname( ISteamFriends* self, uint64_steamid steamIDPlayer ); +S_API int SteamAPI_ISteamFriends_GetFriendsGroupCount( ISteamFriends* self ); +S_API FriendsGroupID_t SteamAPI_ISteamFriends_GetFriendsGroupIDByIndex( ISteamFriends* self, int iFG ); +S_API const char * SteamAPI_ISteamFriends_GetFriendsGroupName( ISteamFriends* self, FriendsGroupID_t friendsGroupID ); +S_API int SteamAPI_ISteamFriends_GetFriendsGroupMembersCount( ISteamFriends* self, FriendsGroupID_t friendsGroupID ); +S_API void SteamAPI_ISteamFriends_GetFriendsGroupMembersList( ISteamFriends* self, FriendsGroupID_t friendsGroupID, CSteamID * pOutSteamIDMembers, int nMembersCount ); +S_API bool SteamAPI_ISteamFriends_HasFriend( ISteamFriends* self, uint64_steamid steamIDFriend, int iFriendFlags ); +S_API int SteamAPI_ISteamFriends_GetClanCount( ISteamFriends* self ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetClanByIndex( ISteamFriends* self, int iClan ); +S_API const char * SteamAPI_ISteamFriends_GetClanName( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API const char * SteamAPI_ISteamFriends_GetClanTag( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API bool SteamAPI_ISteamFriends_GetClanActivityCounts( ISteamFriends* self, uint64_steamid steamIDClan, int * pnOnline, int * pnInGame, int * pnChatting ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_DownloadClanActivityCounts( ISteamFriends* self, CSteamID * psteamIDClans, int cClansToRequest ); +S_API int SteamAPI_ISteamFriends_GetFriendCountFromSource( ISteamFriends* self, uint64_steamid steamIDSource ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetFriendFromSourceByIndex( ISteamFriends* self, uint64_steamid steamIDSource, int iFriend ); +S_API bool SteamAPI_ISteamFriends_IsUserInSource( ISteamFriends* self, uint64_steamid steamIDUser, uint64_steamid steamIDSource ); +S_API void SteamAPI_ISteamFriends_SetInGameVoiceSpeaking( ISteamFriends* self, uint64_steamid steamIDUser, bool bSpeaking ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlay( ISteamFriends* self, const char * pchDialog ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayToUser( ISteamFriends* self, const char * pchDialog, uint64_steamid steamID ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage( ISteamFriends* self, const char * pchURL, EActivateGameOverlayToWebPageMode eMode ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayToStore( ISteamFriends* self, AppId_t nAppID, EOverlayToStoreFlag eFlag ); +S_API void SteamAPI_ISteamFriends_SetPlayedWith( ISteamFriends* self, uint64_steamid steamIDUserPlayedWith ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialog( ISteamFriends* self, uint64_steamid steamIDLobby ); +S_API int SteamAPI_ISteamFriends_GetSmallFriendAvatar( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API int SteamAPI_ISteamFriends_GetMediumFriendAvatar( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API int SteamAPI_ISteamFriends_GetLargeFriendAvatar( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API bool SteamAPI_ISteamFriends_RequestUserInformation( ISteamFriends* self, uint64_steamid steamIDUser, bool bRequireNameOnly ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_RequestClanOfficerList( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetClanOwner( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API int SteamAPI_ISteamFriends_GetClanOfficerCount( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetClanOfficerByIndex( ISteamFriends* self, uint64_steamid steamIDClan, int iOfficer ); +S_API uint32 SteamAPI_ISteamFriends_GetUserRestrictions( ISteamFriends* self ); +S_API bool SteamAPI_ISteamFriends_SetRichPresence( ISteamFriends* self, const char * pchKey, const char * pchValue ); +S_API void SteamAPI_ISteamFriends_ClearRichPresence( ISteamFriends* self ); +S_API const char * SteamAPI_ISteamFriends_GetFriendRichPresence( ISteamFriends* self, uint64_steamid steamIDFriend, const char * pchKey ); +S_API int SteamAPI_ISteamFriends_GetFriendRichPresenceKeyCount( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API const char * SteamAPI_ISteamFriends_GetFriendRichPresenceKeyByIndex( ISteamFriends* self, uint64_steamid steamIDFriend, int iKey ); +S_API void SteamAPI_ISteamFriends_RequestFriendRichPresence( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API bool SteamAPI_ISteamFriends_InviteUserToGame( ISteamFriends* self, uint64_steamid steamIDFriend, const char * pchConnectString ); +S_API int SteamAPI_ISteamFriends_GetCoplayFriendCount( ISteamFriends* self ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetCoplayFriend( ISteamFriends* self, int iCoplayFriend ); +S_API int SteamAPI_ISteamFriends_GetFriendCoplayTime( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API AppId_t SteamAPI_ISteamFriends_GetFriendCoplayGame( ISteamFriends* self, uint64_steamid steamIDFriend ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_JoinClanChatRoom( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API bool SteamAPI_ISteamFriends_LeaveClanChatRoom( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API int SteamAPI_ISteamFriends_GetClanChatMemberCount( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API uint64_steamid SteamAPI_ISteamFriends_GetChatMemberByIndex( ISteamFriends* self, uint64_steamid steamIDClan, int iUser ); +S_API bool SteamAPI_ISteamFriends_SendClanChatMessage( ISteamFriends* self, uint64_steamid steamIDClanChat, const char * pchText ); +S_API int SteamAPI_ISteamFriends_GetClanChatMessage( ISteamFriends* self, uint64_steamid steamIDClanChat, int iMessage, void * prgchText, int cchTextMax, EChatEntryType * peChatEntryType, CSteamID * psteamidChatter ); +S_API bool SteamAPI_ISteamFriends_IsClanChatAdmin( ISteamFriends* self, uint64_steamid steamIDClanChat, uint64_steamid steamIDUser ); +S_API bool SteamAPI_ISteamFriends_IsClanChatWindowOpenInSteam( ISteamFriends* self, uint64_steamid steamIDClanChat ); +S_API bool SteamAPI_ISteamFriends_OpenClanChatWindowInSteam( ISteamFriends* self, uint64_steamid steamIDClanChat ); +S_API bool SteamAPI_ISteamFriends_CloseClanChatWindowInSteam( ISteamFriends* self, uint64_steamid steamIDClanChat ); +S_API bool SteamAPI_ISteamFriends_SetListenForFriendsMessages( ISteamFriends* self, bool bInterceptEnabled ); +S_API bool SteamAPI_ISteamFriends_ReplyToFriendMessage( ISteamFriends* self, uint64_steamid steamIDFriend, const char * pchMsgToSend ); +S_API int SteamAPI_ISteamFriends_GetFriendMessage( ISteamFriends* self, uint64_steamid steamIDFriend, int iMessageID, void * pvData, int cubData, EChatEntryType * peChatEntryType ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_GetFollowerCount( ISteamFriends* self, uint64_steamid steamID ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_IsFollowing( ISteamFriends* self, uint64_steamid steamID ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_EnumerateFollowingList( ISteamFriends* self, uint32 unStartIndex ); +S_API bool SteamAPI_ISteamFriends_IsClanPublic( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API bool SteamAPI_ISteamFriends_IsClanOfficialGameGroup( ISteamFriends* self, uint64_steamid steamIDClan ); +S_API int SteamAPI_ISteamFriends_GetNumChatsWithUnreadPriorityMessages( ISteamFriends* self ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayRemotePlayTogetherInviteDialog( ISteamFriends* self, uint64_steamid steamIDLobby ); +S_API bool SteamAPI_ISteamFriends_RegisterProtocolInOverlayBrowser( ISteamFriends* self, const char * pchProtocol ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialogConnectString( ISteamFriends* self, const char * pchConnectString ); +S_API SteamAPICall_t SteamAPI_ISteamFriends_RequestEquippedProfileItems( ISteamFriends* self, uint64_steamid steamID ); +S_API bool SteamAPI_ISteamFriends_BHasEquippedProfileItem( ISteamFriends* self, uint64_steamid steamID, ECommunityProfileItemType itemType ); +S_API const char * SteamAPI_ISteamFriends_GetProfileItemPropertyString( ISteamFriends* self, uint64_steamid steamID, ECommunityProfileItemType itemType, ECommunityProfileItemProperty prop ); +S_API uint32 SteamAPI_ISteamFriends_GetProfileItemPropertyUint( ISteamFriends* self, uint64_steamid steamID, ECommunityProfileItemType itemType, ECommunityProfileItemProperty prop ); + +// ISteamUtils + +// A versioned accessor is exported by the library +S_API ISteamUtils *SteamAPI_SteamUtils_v010(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamUtils(), but using this ensures that you are using a matching library. +inline ISteamUtils *SteamAPI_SteamUtils() { return SteamAPI_SteamUtils_v010(); } + +// A versioned accessor is exported by the library +S_API ISteamUtils *SteamAPI_SteamGameServerUtils_v010(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerUtils(), but using this ensures that you are using a matching library. +inline ISteamUtils *SteamAPI_SteamGameServerUtils() { return SteamAPI_SteamGameServerUtils_v010(); } +S_API uint32 SteamAPI_ISteamUtils_GetSecondsSinceAppActive( ISteamUtils* self ); +S_API uint32 SteamAPI_ISteamUtils_GetSecondsSinceComputerActive( ISteamUtils* self ); +S_API EUniverse SteamAPI_ISteamUtils_GetConnectedUniverse( ISteamUtils* self ); +S_API uint32 SteamAPI_ISteamUtils_GetServerRealTime( ISteamUtils* self ); +S_API const char * SteamAPI_ISteamUtils_GetIPCountry( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_GetImageSize( ISteamUtils* self, int iImage, uint32 * pnWidth, uint32 * pnHeight ); +S_API bool SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils* self, int iImage, uint8 * pubDest, int nDestBufferSize ); +S_API uint8 SteamAPI_ISteamUtils_GetCurrentBatteryPower( ISteamUtils* self ); +S_API uint32 SteamAPI_ISteamUtils_GetAppID( ISteamUtils* self ); +S_API void SteamAPI_ISteamUtils_SetOverlayNotificationPosition( ISteamUtils* self, ENotificationPosition eNotificationPosition ); +S_API bool SteamAPI_ISteamUtils_IsAPICallCompleted( ISteamUtils* self, SteamAPICall_t hSteamAPICall, bool * pbFailed ); +S_API ESteamAPICallFailure SteamAPI_ISteamUtils_GetAPICallFailureReason( ISteamUtils* self, SteamAPICall_t hSteamAPICall ); +S_API bool SteamAPI_ISteamUtils_GetAPICallResult( ISteamUtils* self, SteamAPICall_t hSteamAPICall, void * pCallback, int cubCallback, int iCallbackExpected, bool * pbFailed ); +S_API uint32 SteamAPI_ISteamUtils_GetIPCCallCount( ISteamUtils* self ); +S_API void SteamAPI_ISteamUtils_SetWarningMessageHook( ISteamUtils* self, SteamAPIWarningMessageHook_t pFunction ); +S_API bool SteamAPI_ISteamUtils_IsOverlayEnabled( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_BOverlayNeedsPresent( ISteamUtils* self ); +S_API SteamAPICall_t SteamAPI_ISteamUtils_CheckFileSignature( ISteamUtils* self, const char * szFileName ); +S_API bool SteamAPI_ISteamUtils_ShowGamepadTextInput( ISteamUtils* self, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char * pchDescription, uint32 unCharMax, const char * pchExistingText ); +S_API uint32 SteamAPI_ISteamUtils_GetEnteredGamepadTextLength( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_GetEnteredGamepadTextInput( ISteamUtils* self, char * pchText, uint32 cchText ); +S_API const char * SteamAPI_ISteamUtils_GetSteamUILanguage( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_IsSteamRunningInVR( ISteamUtils* self ); +S_API void SteamAPI_ISteamUtils_SetOverlayNotificationInset( ISteamUtils* self, int nHorizontalInset, int nVerticalInset ); +S_API bool SteamAPI_ISteamUtils_IsSteamInBigPictureMode( ISteamUtils* self ); +S_API void SteamAPI_ISteamUtils_StartVRDashboard( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_IsVRHeadsetStreamingEnabled( ISteamUtils* self ); +S_API void SteamAPI_ISteamUtils_SetVRHeadsetStreamingEnabled( ISteamUtils* self, bool bEnabled ); +S_API bool SteamAPI_ISteamUtils_IsSteamChinaLauncher( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_InitFilterText( ISteamUtils* self, uint32 unFilterOptions ); +S_API int SteamAPI_ISteamUtils_FilterText( ISteamUtils* self, ETextFilteringContext eContext, uint64_steamid sourceSteamID, const char * pchInputMessage, char * pchOutFilteredText, uint32 nByteSizeOutFilteredText ); +S_API ESteamIPv6ConnectivityState SteamAPI_ISteamUtils_GetIPv6ConnectivityState( ISteamUtils* self, ESteamIPv6ConnectivityProtocol eProtocol ); +S_API bool SteamAPI_ISteamUtils_IsSteamRunningOnSteamDeck( ISteamUtils* self ); +S_API bool SteamAPI_ISteamUtils_ShowFloatingGamepadTextInput( ISteamUtils* self, EFloatingGamepadTextInputMode eKeyboardMode, int nTextFieldXPosition, int nTextFieldYPosition, int nTextFieldWidth, int nTextFieldHeight ); +S_API void SteamAPI_ISteamUtils_SetGameLauncherMode( ISteamUtils* self, bool bLauncherMode ); +S_API bool SteamAPI_ISteamUtils_DismissFloatingGamepadTextInput( ISteamUtils* self ); + +// ISteamMatchmaking + +// A versioned accessor is exported by the library +S_API ISteamMatchmaking *SteamAPI_SteamMatchmaking_v009(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamMatchmaking(), but using this ensures that you are using a matching library. +inline ISteamMatchmaking *SteamAPI_SteamMatchmaking() { return SteamAPI_SteamMatchmaking_v009(); } +S_API int SteamAPI_ISteamMatchmaking_GetFavoriteGameCount( ISteamMatchmaking* self ); +S_API bool SteamAPI_ISteamMatchmaking_GetFavoriteGame( ISteamMatchmaking* self, int iGame, AppId_t * pnAppID, uint32 * pnIP, uint16 * pnConnPort, uint16 * pnQueryPort, uint32 * punFlags, uint32 * pRTime32LastPlayedOnServer ); +S_API int SteamAPI_ISteamMatchmaking_AddFavoriteGame( ISteamMatchmaking* self, AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags, uint32 rTime32LastPlayedOnServer ); +S_API bool SteamAPI_ISteamMatchmaking_RemoveFavoriteGame( ISteamMatchmaking* self, AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags ); +S_API SteamAPICall_t SteamAPI_ISteamMatchmaking_RequestLobbyList( ISteamMatchmaking* self ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListStringFilter( ISteamMatchmaking* self, const char * pchKeyToMatch, const char * pchValueToMatch, ELobbyComparison eComparisonType ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListNumericalFilter( ISteamMatchmaking* self, const char * pchKeyToMatch, int nValueToMatch, ELobbyComparison eComparisonType ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListNearValueFilter( ISteamMatchmaking* self, const char * pchKeyToMatch, int nValueToBeCloseTo ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListFilterSlotsAvailable( ISteamMatchmaking* self, int nSlotsAvailable ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListDistanceFilter( ISteamMatchmaking* self, ELobbyDistanceFilter eLobbyDistanceFilter ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListResultCountFilter( ISteamMatchmaking* self, int cMaxResults ); +S_API void SteamAPI_ISteamMatchmaking_AddRequestLobbyListCompatibleMembersFilter( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API uint64_steamid SteamAPI_ISteamMatchmaking_GetLobbyByIndex( ISteamMatchmaking* self, int iLobby ); +S_API SteamAPICall_t SteamAPI_ISteamMatchmaking_CreateLobby( ISteamMatchmaking* self, ELobbyType eLobbyType, int cMaxMembers ); +S_API SteamAPICall_t SteamAPI_ISteamMatchmaking_JoinLobby( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API void SteamAPI_ISteamMatchmaking_LeaveLobby( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API bool SteamAPI_ISteamMatchmaking_InviteUserToLobby( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint64_steamid steamIDInvitee ); +S_API int SteamAPI_ISteamMatchmaking_GetNumLobbyMembers( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API uint64_steamid SteamAPI_ISteamMatchmaking_GetLobbyMemberByIndex( ISteamMatchmaking* self, uint64_steamid steamIDLobby, int iMember ); +S_API const char * SteamAPI_ISteamMatchmaking_GetLobbyData( ISteamMatchmaking* self, uint64_steamid steamIDLobby, const char * pchKey ); +S_API bool SteamAPI_ISteamMatchmaking_SetLobbyData( ISteamMatchmaking* self, uint64_steamid steamIDLobby, const char * pchKey, const char * pchValue ); +S_API int SteamAPI_ISteamMatchmaking_GetLobbyDataCount( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API bool SteamAPI_ISteamMatchmaking_GetLobbyDataByIndex( ISteamMatchmaking* self, uint64_steamid steamIDLobby, int iLobbyData, char * pchKey, int cchKeyBufferSize, char * pchValue, int cchValueBufferSize ); +S_API bool SteamAPI_ISteamMatchmaking_DeleteLobbyData( ISteamMatchmaking* self, uint64_steamid steamIDLobby, const char * pchKey ); +S_API const char * SteamAPI_ISteamMatchmaking_GetLobbyMemberData( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint64_steamid steamIDUser, const char * pchKey ); +S_API void SteamAPI_ISteamMatchmaking_SetLobbyMemberData( ISteamMatchmaking* self, uint64_steamid steamIDLobby, const char * pchKey, const char * pchValue ); +S_API bool SteamAPI_ISteamMatchmaking_SendLobbyChatMsg( ISteamMatchmaking* self, uint64_steamid steamIDLobby, const void * pvMsgBody, int cubMsgBody ); +S_API int SteamAPI_ISteamMatchmaking_GetLobbyChatEntry( ISteamMatchmaking* self, uint64_steamid steamIDLobby, int iChatID, CSteamID * pSteamIDUser, void * pvData, int cubData, EChatEntryType * peChatEntryType ); +S_API bool SteamAPI_ISteamMatchmaking_RequestLobbyData( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API void SteamAPI_ISteamMatchmaking_SetLobbyGameServer( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint32 unGameServerIP, uint16 unGameServerPort, uint64_steamid steamIDGameServer ); +S_API bool SteamAPI_ISteamMatchmaking_GetLobbyGameServer( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint32 * punGameServerIP, uint16 * punGameServerPort, CSteamID * psteamIDGameServer ); +S_API bool SteamAPI_ISteamMatchmaking_SetLobbyMemberLimit( ISteamMatchmaking* self, uint64_steamid steamIDLobby, int cMaxMembers ); +S_API int SteamAPI_ISteamMatchmaking_GetLobbyMemberLimit( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API bool SteamAPI_ISteamMatchmaking_SetLobbyType( ISteamMatchmaking* self, uint64_steamid steamIDLobby, ELobbyType eLobbyType ); +S_API bool SteamAPI_ISteamMatchmaking_SetLobbyJoinable( ISteamMatchmaking* self, uint64_steamid steamIDLobby, bool bLobbyJoinable ); +S_API uint64_steamid SteamAPI_ISteamMatchmaking_GetLobbyOwner( ISteamMatchmaking* self, uint64_steamid steamIDLobby ); +S_API bool SteamAPI_ISteamMatchmaking_SetLobbyOwner( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint64_steamid steamIDNewOwner ); +S_API bool SteamAPI_ISteamMatchmaking_SetLinkedLobby( ISteamMatchmaking* self, uint64_steamid steamIDLobby, uint64_steamid steamIDLobbyDependent ); + +// ISteamMatchmakingServerListResponse +S_API void SteamAPI_ISteamMatchmakingServerListResponse_ServerResponded( ISteamMatchmakingServerListResponse* self, HServerListRequest hRequest, int iServer ); +S_API void SteamAPI_ISteamMatchmakingServerListResponse_ServerFailedToRespond( ISteamMatchmakingServerListResponse* self, HServerListRequest hRequest, int iServer ); +S_API void SteamAPI_ISteamMatchmakingServerListResponse_RefreshComplete( ISteamMatchmakingServerListResponse* self, HServerListRequest hRequest, EMatchMakingServerResponse response ); + +// ISteamMatchmakingPingResponse +S_API void SteamAPI_ISteamMatchmakingPingResponse_ServerResponded( ISteamMatchmakingPingResponse* self, gameserveritem_t & server ); +S_API void SteamAPI_ISteamMatchmakingPingResponse_ServerFailedToRespond( ISteamMatchmakingPingResponse* self ); + +// ISteamMatchmakingPlayersResponse +S_API void SteamAPI_ISteamMatchmakingPlayersResponse_AddPlayerToList( ISteamMatchmakingPlayersResponse* self, const char * pchName, int nScore, float flTimePlayed ); +S_API void SteamAPI_ISteamMatchmakingPlayersResponse_PlayersFailedToRespond( ISteamMatchmakingPlayersResponse* self ); +S_API void SteamAPI_ISteamMatchmakingPlayersResponse_PlayersRefreshComplete( ISteamMatchmakingPlayersResponse* self ); + +// ISteamMatchmakingRulesResponse +S_API void SteamAPI_ISteamMatchmakingRulesResponse_RulesResponded( ISteamMatchmakingRulesResponse* self, const char * pchRule, const char * pchValue ); +S_API void SteamAPI_ISteamMatchmakingRulesResponse_RulesFailedToRespond( ISteamMatchmakingRulesResponse* self ); +S_API void SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete( ISteamMatchmakingRulesResponse* self ); + +// ISteamMatchmakingServers + +// A versioned accessor is exported by the library +S_API ISteamMatchmakingServers *SteamAPI_SteamMatchmakingServers_v002(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamMatchmakingServers(), but using this ensures that you are using a matching library. +inline ISteamMatchmakingServers *SteamAPI_SteamMatchmakingServers() { return SteamAPI_SteamMatchmakingServers_v002(); } +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestInternetServerList( ISteamMatchmakingServers* self, AppId_t iApp, MatchMakingKeyValuePair_t ** ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestLANServerList( ISteamMatchmakingServers* self, AppId_t iApp, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestFriendsServerList( ISteamMatchmakingServers* self, AppId_t iApp, MatchMakingKeyValuePair_t ** ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestFavoritesServerList( ISteamMatchmakingServers* self, AppId_t iApp, MatchMakingKeyValuePair_t ** ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestHistoryServerList( ISteamMatchmakingServers* self, AppId_t iApp, MatchMakingKeyValuePair_t ** ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API HServerListRequest SteamAPI_ISteamMatchmakingServers_RequestSpectatorServerList( ISteamMatchmakingServers* self, AppId_t iApp, MatchMakingKeyValuePair_t ** ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse * pRequestServersResponse ); +S_API void SteamAPI_ISteamMatchmakingServers_ReleaseRequest( ISteamMatchmakingServers* self, HServerListRequest hServerListRequest ); +S_API gameserveritem_t * SteamAPI_ISteamMatchmakingServers_GetServerDetails( ISteamMatchmakingServers* self, HServerListRequest hRequest, int iServer ); +S_API void SteamAPI_ISteamMatchmakingServers_CancelQuery( ISteamMatchmakingServers* self, HServerListRequest hRequest ); +S_API void SteamAPI_ISteamMatchmakingServers_RefreshQuery( ISteamMatchmakingServers* self, HServerListRequest hRequest ); +S_API bool SteamAPI_ISteamMatchmakingServers_IsRefreshing( ISteamMatchmakingServers* self, HServerListRequest hRequest ); +S_API int SteamAPI_ISteamMatchmakingServers_GetServerCount( ISteamMatchmakingServers* self, HServerListRequest hRequest ); +S_API void SteamAPI_ISteamMatchmakingServers_RefreshServer( ISteamMatchmakingServers* self, HServerListRequest hRequest, int iServer ); +S_API HServerQuery SteamAPI_ISteamMatchmakingServers_PingServer( ISteamMatchmakingServers* self, uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse * pRequestServersResponse ); +S_API HServerQuery SteamAPI_ISteamMatchmakingServers_PlayerDetails( ISteamMatchmakingServers* self, uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse * pRequestServersResponse ); +S_API HServerQuery SteamAPI_ISteamMatchmakingServers_ServerRules( ISteamMatchmakingServers* self, uint32 unIP, uint16 usPort, ISteamMatchmakingRulesResponse * pRequestServersResponse ); +S_API void SteamAPI_ISteamMatchmakingServers_CancelServerQuery( ISteamMatchmakingServers* self, HServerQuery hServerQuery ); + +// ISteamGameSearch + +// A versioned accessor is exported by the library +S_API ISteamGameSearch *SteamAPI_SteamGameSearch_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameSearch(), but using this ensures that you are using a matching library. +inline ISteamGameSearch *SteamAPI_SteamGameSearch() { return SteamAPI_SteamGameSearch_v001(); } +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_AddGameSearchParams( ISteamGameSearch* self, const char * pchKeyToFind, const char * pchValuesToFind ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_SearchForGameWithLobby( ISteamGameSearch* self, uint64_steamid steamIDLobby, int nPlayerMin, int nPlayerMax ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_SearchForGameSolo( ISteamGameSearch* self, int nPlayerMin, int nPlayerMax ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_AcceptGame( ISteamGameSearch* self ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_DeclineGame( ISteamGameSearch* self ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_RetrieveConnectionDetails( ISteamGameSearch* self, uint64_steamid steamIDHost, char * pchConnectionDetails, int cubConnectionDetails ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_EndGameSearch( ISteamGameSearch* self ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_SetGameHostParams( ISteamGameSearch* self, const char * pchKey, const char * pchValue ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_SetConnectionDetails( ISteamGameSearch* self, const char * pchConnectionDetails, int cubConnectionDetails ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_RequestPlayersForGame( ISteamGameSearch* self, int nPlayerMin, int nPlayerMax, int nMaxTeamSize ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_HostConfirmGameStart( ISteamGameSearch* self, uint64 ullUniqueGameID ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_CancelRequestPlayersForGame( ISteamGameSearch* self ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_SubmitPlayerResult( ISteamGameSearch* self, uint64 ullUniqueGameID, uint64_steamid steamIDPlayer, EPlayerResult_t EPlayerResult ); +S_API EGameSearchErrorCode_t SteamAPI_ISteamGameSearch_EndGame( ISteamGameSearch* self, uint64 ullUniqueGameID ); + +// ISteamParties + +// A versioned accessor is exported by the library +S_API ISteamParties *SteamAPI_SteamParties_v002(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamParties(), but using this ensures that you are using a matching library. +inline ISteamParties *SteamAPI_SteamParties() { return SteamAPI_SteamParties_v002(); } +S_API uint32 SteamAPI_ISteamParties_GetNumActiveBeacons( ISteamParties* self ); +S_API PartyBeaconID_t SteamAPI_ISteamParties_GetBeaconByIndex( ISteamParties* self, uint32 unIndex ); +S_API bool SteamAPI_ISteamParties_GetBeaconDetails( ISteamParties* self, PartyBeaconID_t ulBeaconID, CSteamID * pSteamIDBeaconOwner, SteamPartyBeaconLocation_t * pLocation, char * pchMetadata, int cchMetadata ); +S_API SteamAPICall_t SteamAPI_ISteamParties_JoinParty( ISteamParties* self, PartyBeaconID_t ulBeaconID ); +S_API bool SteamAPI_ISteamParties_GetNumAvailableBeaconLocations( ISteamParties* self, uint32 * puNumLocations ); +S_API bool SteamAPI_ISteamParties_GetAvailableBeaconLocations( ISteamParties* self, SteamPartyBeaconLocation_t * pLocationList, uint32 uMaxNumLocations ); +S_API SteamAPICall_t SteamAPI_ISteamParties_CreateBeacon( ISteamParties* self, uint32 unOpenSlots, SteamPartyBeaconLocation_t * pBeaconLocation, const char * pchConnectString, const char * pchMetadata ); +S_API void SteamAPI_ISteamParties_OnReservationCompleted( ISteamParties* self, PartyBeaconID_t ulBeacon, uint64_steamid steamIDUser ); +S_API void SteamAPI_ISteamParties_CancelReservation( ISteamParties* self, PartyBeaconID_t ulBeacon, uint64_steamid steamIDUser ); +S_API SteamAPICall_t SteamAPI_ISteamParties_ChangeNumOpenSlots( ISteamParties* self, PartyBeaconID_t ulBeacon, uint32 unOpenSlots ); +S_API bool SteamAPI_ISteamParties_DestroyBeacon( ISteamParties* self, PartyBeaconID_t ulBeacon ); +S_API bool SteamAPI_ISteamParties_GetBeaconLocationData( ISteamParties* self, SteamPartyBeaconLocation_t BeaconLocation, ESteamPartyBeaconLocationData eData, char * pchDataStringOut, int cchDataStringOut ); + +// ISteamRemoteStorage + +// A versioned accessor is exported by the library +S_API ISteamRemoteStorage *SteamAPI_SteamRemoteStorage_v016(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamRemoteStorage(), but using this ensures that you are using a matching library. +inline ISteamRemoteStorage *SteamAPI_SteamRemoteStorage() { return SteamAPI_SteamRemoteStorage_v016(); } +S_API bool SteamAPI_ISteamRemoteStorage_FileWrite( ISteamRemoteStorage* self, const char * pchFile, const void * pvData, int32 cubData ); +S_API int32 SteamAPI_ISteamRemoteStorage_FileRead( ISteamRemoteStorage* self, const char * pchFile, void * pvData, int32 cubDataToRead ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_FileWriteAsync( ISteamRemoteStorage* self, const char * pchFile, const void * pvData, uint32 cubData ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_FileReadAsync( ISteamRemoteStorage* self, const char * pchFile, uint32 nOffset, uint32 cubToRead ); +S_API bool SteamAPI_ISteamRemoteStorage_FileReadAsyncComplete( ISteamRemoteStorage* self, SteamAPICall_t hReadCall, void * pvBuffer, uint32 cubToRead ); +S_API bool SteamAPI_ISteamRemoteStorage_FileForget( ISteamRemoteStorage* self, const char * pchFile ); +S_API bool SteamAPI_ISteamRemoteStorage_FileDelete( ISteamRemoteStorage* self, const char * pchFile ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_FileShare( ISteamRemoteStorage* self, const char * pchFile ); +S_API bool SteamAPI_ISteamRemoteStorage_SetSyncPlatforms( ISteamRemoteStorage* self, const char * pchFile, ERemoteStoragePlatform eRemoteStoragePlatform ); +S_API UGCFileWriteStreamHandle_t SteamAPI_ISteamRemoteStorage_FileWriteStreamOpen( ISteamRemoteStorage* self, const char * pchFile ); +S_API bool SteamAPI_ISteamRemoteStorage_FileWriteStreamWriteChunk( ISteamRemoteStorage* self, UGCFileWriteStreamHandle_t writeHandle, const void * pvData, int32 cubData ); +S_API bool SteamAPI_ISteamRemoteStorage_FileWriteStreamClose( ISteamRemoteStorage* self, UGCFileWriteStreamHandle_t writeHandle ); +S_API bool SteamAPI_ISteamRemoteStorage_FileWriteStreamCancel( ISteamRemoteStorage* self, UGCFileWriteStreamHandle_t writeHandle ); +S_API bool SteamAPI_ISteamRemoteStorage_FileExists( ISteamRemoteStorage* self, const char * pchFile ); +S_API bool SteamAPI_ISteamRemoteStorage_FilePersisted( ISteamRemoteStorage* self, const char * pchFile ); +S_API int32 SteamAPI_ISteamRemoteStorage_GetFileSize( ISteamRemoteStorage* self, const char * pchFile ); +S_API int64 SteamAPI_ISteamRemoteStorage_GetFileTimestamp( ISteamRemoteStorage* self, const char * pchFile ); +S_API ERemoteStoragePlatform SteamAPI_ISteamRemoteStorage_GetSyncPlatforms( ISteamRemoteStorage* self, const char * pchFile ); +S_API int32 SteamAPI_ISteamRemoteStorage_GetFileCount( ISteamRemoteStorage* self ); +S_API const char * SteamAPI_ISteamRemoteStorage_GetFileNameAndSize( ISteamRemoteStorage* self, int iFile, int32 * pnFileSizeInBytes ); +S_API bool SteamAPI_ISteamRemoteStorage_GetQuota( ISteamRemoteStorage* self, uint64 * pnTotalBytes, uint64 * puAvailableBytes ); +S_API bool SteamAPI_ISteamRemoteStorage_IsCloudEnabledForAccount( ISteamRemoteStorage* self ); +S_API bool SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp( ISteamRemoteStorage* self ); +S_API void SteamAPI_ISteamRemoteStorage_SetCloudEnabledForApp( ISteamRemoteStorage* self, bool bEnabled ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_UGCDownload( ISteamRemoteStorage* self, UGCHandle_t hContent, uint32 unPriority ); +S_API bool SteamAPI_ISteamRemoteStorage_GetUGCDownloadProgress( ISteamRemoteStorage* self, UGCHandle_t hContent, int32 * pnBytesDownloaded, int32 * pnBytesExpected ); +S_API bool SteamAPI_ISteamRemoteStorage_GetUGCDetails( ISteamRemoteStorage* self, UGCHandle_t hContent, AppId_t * pnAppID, char ** ppchName, int32 * pnFileSizeInBytes, CSteamID * pSteamIDOwner ); +S_API int32 SteamAPI_ISteamRemoteStorage_UGCRead( ISteamRemoteStorage* self, UGCHandle_t hContent, void * pvData, int32 cubDataToRead, uint32 cOffset, EUGCReadAction eAction ); +S_API int32 SteamAPI_ISteamRemoteStorage_GetCachedUGCCount( ISteamRemoteStorage* self ); +S_API UGCHandle_t SteamAPI_ISteamRemoteStorage_GetCachedUGCHandle( ISteamRemoteStorage* self, int32 iCachedContent ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_PublishWorkshopFile( ISteamRemoteStorage* self, const char * pchFile, const char * pchPreviewFile, AppId_t nConsumerAppId, const char * pchTitle, const char * pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t * pTags, EWorkshopFileType eWorkshopFileType ); +S_API PublishedFileUpdateHandle_t SteamAPI_ISteamRemoteStorage_CreatePublishedFileUpdateRequest( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileFile( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, const char * pchFile ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFilePreviewFile( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, const char * pchPreviewFile ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileTitle( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, const char * pchTitle ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileDescription( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, const char * pchDescription ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileVisibility( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, ERemoteStoragePublishedFileVisibility eVisibility ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileTags( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, SteamParamStringArray_t * pTags ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_CommitPublishedFileUpdate( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_GetPublishedFileDetails( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId, uint32 unMaxSecondsOld ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_DeletePublishedFile( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_EnumerateUserPublishedFiles( ISteamRemoteStorage* self, uint32 unStartIndex ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_SubscribePublishedFile( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_EnumerateUserSubscribedFiles( ISteamRemoteStorage* self, uint32 unStartIndex ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_UnsubscribePublishedFile( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API bool SteamAPI_ISteamRemoteStorage_UpdatePublishedFileSetChangeDescription( ISteamRemoteStorage* self, PublishedFileUpdateHandle_t updateHandle, const char * pchChangeDescription ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_GetPublishedItemVoteDetails( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_UpdateUserPublishedItemVote( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId, bool bVoteUp ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_GetUserPublishedItemVoteDetails( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_EnumerateUserSharedWorkshopFiles( ISteamRemoteStorage* self, uint64_steamid steamId, uint32 unStartIndex, SteamParamStringArray_t * pRequiredTags, SteamParamStringArray_t * pExcludedTags ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_PublishVideo( ISteamRemoteStorage* self, EWorkshopVideoProvider eVideoProvider, const char * pchVideoAccount, const char * pchVideoIdentifier, const char * pchPreviewFile, AppId_t nConsumerAppId, const char * pchTitle, const char * pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t * pTags ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_SetUserPublishedFileAction( ISteamRemoteStorage* self, PublishedFileId_t unPublishedFileId, EWorkshopFileAction eAction ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_EnumeratePublishedFilesByUserAction( ISteamRemoteStorage* self, EWorkshopFileAction eAction, uint32 unStartIndex ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_EnumeratePublishedWorkshopFiles( ISteamRemoteStorage* self, EWorkshopEnumerationType eEnumerationType, uint32 unStartIndex, uint32 unCount, uint32 unDays, SteamParamStringArray_t * pTags, SteamParamStringArray_t * pUserTags ); +S_API SteamAPICall_t SteamAPI_ISteamRemoteStorage_UGCDownloadToLocation( ISteamRemoteStorage* self, UGCHandle_t hContent, const char * pchLocation, uint32 unPriority ); +S_API int32 SteamAPI_ISteamRemoteStorage_GetLocalFileChangeCount( ISteamRemoteStorage* self ); +S_API const char * SteamAPI_ISteamRemoteStorage_GetLocalFileChange( ISteamRemoteStorage* self, int iFile, ERemoteStorageLocalFileChange * pEChangeType, ERemoteStorageFilePathType * pEFilePathType ); +S_API bool SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch( ISteamRemoteStorage* self ); +S_API bool SteamAPI_ISteamRemoteStorage_EndFileWriteBatch( ISteamRemoteStorage* self ); + +// ISteamUserStats + +// A versioned accessor is exported by the library +S_API ISteamUserStats *SteamAPI_SteamUserStats_v012(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamUserStats(), but using this ensures that you are using a matching library. +inline ISteamUserStats *SteamAPI_SteamUserStats() { return SteamAPI_SteamUserStats_v012(); } +S_API bool SteamAPI_ISteamUserStats_RequestCurrentStats( ISteamUserStats* self ); +S_API bool SteamAPI_ISteamUserStats_GetStatInt32( ISteamUserStats* self, const char * pchName, int32 * pData ); +S_API bool SteamAPI_ISteamUserStats_GetStatFloat( ISteamUserStats* self, const char * pchName, float * pData ); +S_API bool SteamAPI_ISteamUserStats_SetStatInt32( ISteamUserStats* self, const char * pchName, int32 nData ); +S_API bool SteamAPI_ISteamUserStats_SetStatFloat( ISteamUserStats* self, const char * pchName, float fData ); +S_API bool SteamAPI_ISteamUserStats_UpdateAvgRateStat( ISteamUserStats* self, const char * pchName, float flCountThisSession, double dSessionLength ); +S_API bool SteamAPI_ISteamUserStats_GetAchievement( ISteamUserStats* self, const char * pchName, bool * pbAchieved ); +S_API bool SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats* self, const char * pchName ); +S_API bool SteamAPI_ISteamUserStats_ClearAchievement( ISteamUserStats* self, const char * pchName ); +S_API bool SteamAPI_ISteamUserStats_GetAchievementAndUnlockTime( ISteamUserStats* self, const char * pchName, bool * pbAchieved, uint32 * punUnlockTime ); +S_API bool SteamAPI_ISteamUserStats_StoreStats( ISteamUserStats* self ); +S_API int SteamAPI_ISteamUserStats_GetAchievementIcon( ISteamUserStats* self, const char * pchName ); +S_API const char * SteamAPI_ISteamUserStats_GetAchievementDisplayAttribute( ISteamUserStats* self, const char * pchName, const char * pchKey ); +S_API bool SteamAPI_ISteamUserStats_IndicateAchievementProgress( ISteamUserStats* self, const char * pchName, uint32 nCurProgress, uint32 nMaxProgress ); +S_API uint32 SteamAPI_ISteamUserStats_GetNumAchievements( ISteamUserStats* self ); +S_API const char * SteamAPI_ISteamUserStats_GetAchievementName( ISteamUserStats* self, uint32 iAchievement ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_RequestUserStats( ISteamUserStats* self, uint64_steamid steamIDUser ); +S_API bool SteamAPI_ISteamUserStats_GetUserStatInt32( ISteamUserStats* self, uint64_steamid steamIDUser, const char * pchName, int32 * pData ); +S_API bool SteamAPI_ISteamUserStats_GetUserStatFloat( ISteamUserStats* self, uint64_steamid steamIDUser, const char * pchName, float * pData ); +S_API bool SteamAPI_ISteamUserStats_GetUserAchievement( ISteamUserStats* self, uint64_steamid steamIDUser, const char * pchName, bool * pbAchieved ); +S_API bool SteamAPI_ISteamUserStats_GetUserAchievementAndUnlockTime( ISteamUserStats* self, uint64_steamid steamIDUser, const char * pchName, bool * pbAchieved, uint32 * punUnlockTime ); +S_API bool SteamAPI_ISteamUserStats_ResetAllStats( ISteamUserStats* self, bool bAchievementsToo ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_FindOrCreateLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName, ELeaderboardSortMethod eLeaderboardSortMethod, ELeaderboardDisplayType eLeaderboardDisplayType ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_FindLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName ); +S_API const char * SteamAPI_ISteamUserStats_GetLeaderboardName( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard ); +S_API int SteamAPI_ISteamUserStats_GetLeaderboardEntryCount( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard ); +S_API ELeaderboardSortMethod SteamAPI_ISteamUserStats_GetLeaderboardSortMethod( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard ); +S_API ELeaderboardDisplayType SteamAPI_ISteamUserStats_GetLeaderboardDisplayType( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_DownloadLeaderboardEntries( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardDataRequest eLeaderboardDataRequest, int nRangeStart, int nRangeEnd ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_DownloadLeaderboardEntriesForUsers( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, CSteamID * prgUsers, int cUsers ); +S_API bool SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( ISteamUserStats* self, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, LeaderboardEntry_t * pLeaderboardEntry, int32 * pDetails, int cDetailsMax ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_UploadLeaderboardScore( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, int32 nScore, const int32 * pScoreDetails, int cScoreDetailsCount ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_AttachLeaderboardUGC( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, UGCHandle_t hUGC ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_GetNumberOfCurrentPlayers( ISteamUserStats* self ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_RequestGlobalAchievementPercentages( ISteamUserStats* self ); +S_API int SteamAPI_ISteamUserStats_GetMostAchievedAchievementInfo( ISteamUserStats* self, char * pchName, uint32 unNameBufLen, float * pflPercent, bool * pbAchieved ); +S_API int SteamAPI_ISteamUserStats_GetNextMostAchievedAchievementInfo( ISteamUserStats* self, int iIteratorPrevious, char * pchName, uint32 unNameBufLen, float * pflPercent, bool * pbAchieved ); +S_API bool SteamAPI_ISteamUserStats_GetAchievementAchievedPercent( ISteamUserStats* self, const char * pchName, float * pflPercent ); +S_API SteamAPICall_t SteamAPI_ISteamUserStats_RequestGlobalStats( ISteamUserStats* self, int nHistoryDays ); +S_API bool SteamAPI_ISteamUserStats_GetGlobalStatInt64( ISteamUserStats* self, const char * pchStatName, int64 * pData ); +S_API bool SteamAPI_ISteamUserStats_GetGlobalStatDouble( ISteamUserStats* self, const char * pchStatName, double * pData ); +S_API int32 SteamAPI_ISteamUserStats_GetGlobalStatHistoryInt64( ISteamUserStats* self, const char * pchStatName, int64 * pData, uint32 cubData ); +S_API int32 SteamAPI_ISteamUserStats_GetGlobalStatHistoryDouble( ISteamUserStats* self, const char * pchStatName, double * pData, uint32 cubData ); +S_API bool SteamAPI_ISteamUserStats_GetAchievementProgressLimitsInt32( ISteamUserStats* self, const char * pchName, int32 * pnMinProgress, int32 * pnMaxProgress ); +S_API bool SteamAPI_ISteamUserStats_GetAchievementProgressLimitsFloat( ISteamUserStats* self, const char * pchName, float * pfMinProgress, float * pfMaxProgress ); + +// ISteamApps + +// A versioned accessor is exported by the library +S_API ISteamApps *SteamAPI_SteamApps_v008(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamApps(), but using this ensures that you are using a matching library. +inline ISteamApps *SteamAPI_SteamApps() { return SteamAPI_SteamApps_v008(); } +S_API bool SteamAPI_ISteamApps_BIsSubscribed( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BIsLowViolence( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BIsCybercafe( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BIsVACBanned( ISteamApps* self ); +S_API const char * SteamAPI_ISteamApps_GetCurrentGameLanguage( ISteamApps* self ); +S_API const char * SteamAPI_ISteamApps_GetAvailableGameLanguages( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BIsSubscribedApp( ISteamApps* self, AppId_t appID ); +S_API bool SteamAPI_ISteamApps_BIsDlcInstalled( ISteamApps* self, AppId_t appID ); +S_API uint32 SteamAPI_ISteamApps_GetEarliestPurchaseUnixTime( ISteamApps* self, AppId_t nAppID ); +S_API bool SteamAPI_ISteamApps_BIsSubscribedFromFreeWeekend( ISteamApps* self ); +S_API int SteamAPI_ISteamApps_GetDLCCount( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BGetDLCDataByIndex( ISteamApps* self, int iDLC, AppId_t * pAppID, bool * pbAvailable, char * pchName, int cchNameBufferSize ); +S_API void SteamAPI_ISteamApps_InstallDLC( ISteamApps* self, AppId_t nAppID ); +S_API void SteamAPI_ISteamApps_UninstallDLC( ISteamApps* self, AppId_t nAppID ); +S_API void SteamAPI_ISteamApps_RequestAppProofOfPurchaseKey( ISteamApps* self, AppId_t nAppID ); +S_API bool SteamAPI_ISteamApps_GetCurrentBetaName( ISteamApps* self, char * pchName, int cchNameBufferSize ); +S_API bool SteamAPI_ISteamApps_MarkContentCorrupt( ISteamApps* self, bool bMissingFilesOnly ); +S_API uint32 SteamAPI_ISteamApps_GetInstalledDepots( ISteamApps* self, AppId_t appID, DepotId_t * pvecDepots, uint32 cMaxDepots ); +S_API uint32 SteamAPI_ISteamApps_GetAppInstallDir( ISteamApps* self, AppId_t appID, char * pchFolder, uint32 cchFolderBufferSize ); +S_API bool SteamAPI_ISteamApps_BIsAppInstalled( ISteamApps* self, AppId_t appID ); +S_API uint64_steamid SteamAPI_ISteamApps_GetAppOwner( ISteamApps* self ); +S_API const char * SteamAPI_ISteamApps_GetLaunchQueryParam( ISteamApps* self, const char * pchKey ); +S_API bool SteamAPI_ISteamApps_GetDlcDownloadProgress( ISteamApps* self, AppId_t nAppID, uint64 * punBytesDownloaded, uint64 * punBytesTotal ); +S_API int SteamAPI_ISteamApps_GetAppBuildId( ISteamApps* self ); +S_API void SteamAPI_ISteamApps_RequestAllProofOfPurchaseKeys( ISteamApps* self ); +S_API SteamAPICall_t SteamAPI_ISteamApps_GetFileDetails( ISteamApps* self, const char * pszFileName ); +S_API int SteamAPI_ISteamApps_GetLaunchCommandLine( ISteamApps* self, char * pszCommandLine, int cubCommandLine ); +S_API bool SteamAPI_ISteamApps_BIsSubscribedFromFamilySharing( ISteamApps* self ); +S_API bool SteamAPI_ISteamApps_BIsTimedTrial( ISteamApps* self, uint32 * punSecondsAllowed, uint32 * punSecondsPlayed ); +S_API bool SteamAPI_ISteamApps_SetDlcContext( ISteamApps* self, AppId_t nAppID ); + +// ISteamNetworking + +// A versioned accessor is exported by the library +S_API ISteamNetworking *SteamAPI_SteamNetworking_v006(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamNetworking(), but using this ensures that you are using a matching library. +inline ISteamNetworking *SteamAPI_SteamNetworking() { return SteamAPI_SteamNetworking_v006(); } + +// A versioned accessor is exported by the library +S_API ISteamNetworking *SteamAPI_SteamGameServerNetworking_v006(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerNetworking(), but using this ensures that you are using a matching library. +inline ISteamNetworking *SteamAPI_SteamGameServerNetworking() { return SteamAPI_SteamGameServerNetworking_v006(); } +S_API bool SteamAPI_ISteamNetworking_SendP2PPacket( ISteamNetworking* self, uint64_steamid steamIDRemote, const void * pubData, uint32 cubData, EP2PSend eP2PSendType, int nChannel ); +S_API bool SteamAPI_ISteamNetworking_IsP2PPacketAvailable( ISteamNetworking* self, uint32 * pcubMsgSize, int nChannel ); +S_API bool SteamAPI_ISteamNetworking_ReadP2PPacket( ISteamNetworking* self, void * pubDest, uint32 cubDest, uint32 * pcubMsgSize, CSteamID * psteamIDRemote, int nChannel ); +S_API bool SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser( ISteamNetworking* self, uint64_steamid steamIDRemote ); +S_API bool SteamAPI_ISteamNetworking_CloseP2PSessionWithUser( ISteamNetworking* self, uint64_steamid steamIDRemote ); +S_API bool SteamAPI_ISteamNetworking_CloseP2PChannelWithUser( ISteamNetworking* self, uint64_steamid steamIDRemote, int nChannel ); +S_API bool SteamAPI_ISteamNetworking_GetP2PSessionState( ISteamNetworking* self, uint64_steamid steamIDRemote, P2PSessionState_t * pConnectionState ); +S_API bool SteamAPI_ISteamNetworking_AllowP2PPacketRelay( ISteamNetworking* self, bool bAllow ); +S_API SNetListenSocket_t SteamAPI_ISteamNetworking_CreateListenSocket( ISteamNetworking* self, int nVirtualP2PPort, SteamIPAddress_t nIP, uint16 nPort, bool bAllowUseOfPacketRelay ); +S_API SNetSocket_t SteamAPI_ISteamNetworking_CreateP2PConnectionSocket( ISteamNetworking* self, uint64_steamid steamIDTarget, int nVirtualPort, int nTimeoutSec, bool bAllowUseOfPacketRelay ); +S_API SNetSocket_t SteamAPI_ISteamNetworking_CreateConnectionSocket( ISteamNetworking* self, SteamIPAddress_t nIP, uint16 nPort, int nTimeoutSec ); +S_API bool SteamAPI_ISteamNetworking_DestroySocket( ISteamNetworking* self, SNetSocket_t hSocket, bool bNotifyRemoteEnd ); +S_API bool SteamAPI_ISteamNetworking_DestroyListenSocket( ISteamNetworking* self, SNetListenSocket_t hSocket, bool bNotifyRemoteEnd ); +S_API bool SteamAPI_ISteamNetworking_SendDataOnSocket( ISteamNetworking* self, SNetSocket_t hSocket, void * pubData, uint32 cubData, bool bReliable ); +S_API bool SteamAPI_ISteamNetworking_IsDataAvailableOnSocket( ISteamNetworking* self, SNetSocket_t hSocket, uint32 * pcubMsgSize ); +S_API bool SteamAPI_ISteamNetworking_RetrieveDataFromSocket( ISteamNetworking* self, SNetSocket_t hSocket, void * pubDest, uint32 cubDest, uint32 * pcubMsgSize ); +S_API bool SteamAPI_ISteamNetworking_IsDataAvailable( ISteamNetworking* self, SNetListenSocket_t hListenSocket, uint32 * pcubMsgSize, SNetSocket_t * phSocket ); +S_API bool SteamAPI_ISteamNetworking_RetrieveData( ISteamNetworking* self, SNetListenSocket_t hListenSocket, void * pubDest, uint32 cubDest, uint32 * pcubMsgSize, SNetSocket_t * phSocket ); +S_API bool SteamAPI_ISteamNetworking_GetSocketInfo( ISteamNetworking* self, SNetSocket_t hSocket, CSteamID * pSteamIDRemote, int * peSocketStatus, SteamIPAddress_t * punIPRemote, uint16 * punPortRemote ); +S_API bool SteamAPI_ISteamNetworking_GetListenSocketInfo( ISteamNetworking* self, SNetListenSocket_t hListenSocket, SteamIPAddress_t * pnIP, uint16 * pnPort ); +S_API ESNetSocketConnectionType SteamAPI_ISteamNetworking_GetSocketConnectionType( ISteamNetworking* self, SNetSocket_t hSocket ); +S_API int SteamAPI_ISteamNetworking_GetMaxPacketSize( ISteamNetworking* self, SNetSocket_t hSocket ); + +// ISteamScreenshots + +// A versioned accessor is exported by the library +S_API ISteamScreenshots *SteamAPI_SteamScreenshots_v003(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamScreenshots(), but using this ensures that you are using a matching library. +inline ISteamScreenshots *SteamAPI_SteamScreenshots() { return SteamAPI_SteamScreenshots_v003(); } +S_API ScreenshotHandle SteamAPI_ISteamScreenshots_WriteScreenshot( ISteamScreenshots* self, void * pubRGB, uint32 cubRGB, int nWidth, int nHeight ); +S_API ScreenshotHandle SteamAPI_ISteamScreenshots_AddScreenshotToLibrary( ISteamScreenshots* self, const char * pchFilename, const char * pchThumbnailFilename, int nWidth, int nHeight ); +S_API void SteamAPI_ISteamScreenshots_TriggerScreenshot( ISteamScreenshots* self ); +S_API void SteamAPI_ISteamScreenshots_HookScreenshots( ISteamScreenshots* self, bool bHook ); +S_API bool SteamAPI_ISteamScreenshots_SetLocation( ISteamScreenshots* self, ScreenshotHandle hScreenshot, const char * pchLocation ); +S_API bool SteamAPI_ISteamScreenshots_TagUser( ISteamScreenshots* self, ScreenshotHandle hScreenshot, uint64_steamid steamID ); +S_API bool SteamAPI_ISteamScreenshots_TagPublishedFile( ISteamScreenshots* self, ScreenshotHandle hScreenshot, PublishedFileId_t unPublishedFileID ); +S_API bool SteamAPI_ISteamScreenshots_IsScreenshotsHooked( ISteamScreenshots* self ); +S_API ScreenshotHandle SteamAPI_ISteamScreenshots_AddVRScreenshotToLibrary( ISteamScreenshots* self, EVRScreenshotType eType, const char * pchFilename, const char * pchVRFilename ); + +// ISteamMusic + +// A versioned accessor is exported by the library +S_API ISteamMusic *SteamAPI_SteamMusic_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamMusic(), but using this ensures that you are using a matching library. +inline ISteamMusic *SteamAPI_SteamMusic() { return SteamAPI_SteamMusic_v001(); } +S_API bool SteamAPI_ISteamMusic_BIsEnabled( ISteamMusic* self ); +S_API bool SteamAPI_ISteamMusic_BIsPlaying( ISteamMusic* self ); +S_API AudioPlayback_Status SteamAPI_ISteamMusic_GetPlaybackStatus( ISteamMusic* self ); +S_API void SteamAPI_ISteamMusic_Play( ISteamMusic* self ); +S_API void SteamAPI_ISteamMusic_Pause( ISteamMusic* self ); +S_API void SteamAPI_ISteamMusic_PlayPrevious( ISteamMusic* self ); +S_API void SteamAPI_ISteamMusic_PlayNext( ISteamMusic* self ); +S_API void SteamAPI_ISteamMusic_SetVolume( ISteamMusic* self, float flVolume ); +S_API float SteamAPI_ISteamMusic_GetVolume( ISteamMusic* self ); + +// ISteamMusicRemote + +// A versioned accessor is exported by the library +S_API ISteamMusicRemote *SteamAPI_SteamMusicRemote_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamMusicRemote(), but using this ensures that you are using a matching library. +inline ISteamMusicRemote *SteamAPI_SteamMusicRemote() { return SteamAPI_SteamMusicRemote_v001(); } +S_API bool SteamAPI_ISteamMusicRemote_RegisterSteamMusicRemote( ISteamMusicRemote* self, const char * pchName ); +S_API bool SteamAPI_ISteamMusicRemote_DeregisterSteamMusicRemote( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_BIsCurrentMusicRemote( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_BActivationSuccess( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_SetDisplayName( ISteamMusicRemote* self, const char * pchDisplayName ); +S_API bool SteamAPI_ISteamMusicRemote_SetPNGIcon_64x64( ISteamMusicRemote* self, void * pvBuffer, uint32 cbBufferLength ); +S_API bool SteamAPI_ISteamMusicRemote_EnablePlayPrevious( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_EnablePlayNext( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_EnableShuffled( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_EnableLooped( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_EnableQueue( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_EnablePlaylists( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_UpdatePlaybackStatus( ISteamMusicRemote* self, AudioPlayback_Status nStatus ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateShuffled( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateLooped( ISteamMusicRemote* self, bool bValue ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateVolume( ISteamMusicRemote* self, float flValue ); +S_API bool SteamAPI_ISteamMusicRemote_CurrentEntryWillChange( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_CurrentEntryIsAvailable( ISteamMusicRemote* self, bool bAvailable ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateCurrentEntryText( ISteamMusicRemote* self, const char * pchText ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateCurrentEntryElapsedSeconds( ISteamMusicRemote* self, int nValue ); +S_API bool SteamAPI_ISteamMusicRemote_UpdateCurrentEntryCoverArt( ISteamMusicRemote* self, void * pvBuffer, uint32 cbBufferLength ); +S_API bool SteamAPI_ISteamMusicRemote_CurrentEntryDidChange( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_QueueWillChange( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_ResetQueueEntries( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_SetQueueEntry( ISteamMusicRemote* self, int nID, int nPosition, const char * pchEntryText ); +S_API bool SteamAPI_ISteamMusicRemote_SetCurrentQueueEntry( ISteamMusicRemote* self, int nID ); +S_API bool SteamAPI_ISteamMusicRemote_QueueDidChange( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_PlaylistWillChange( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_ResetPlaylistEntries( ISteamMusicRemote* self ); +S_API bool SteamAPI_ISteamMusicRemote_SetPlaylistEntry( ISteamMusicRemote* self, int nID, int nPosition, const char * pchEntryText ); +S_API bool SteamAPI_ISteamMusicRemote_SetCurrentPlaylistEntry( ISteamMusicRemote* self, int nID ); +S_API bool SteamAPI_ISteamMusicRemote_PlaylistDidChange( ISteamMusicRemote* self ); + +// ISteamHTTP + +// A versioned accessor is exported by the library +S_API ISteamHTTP *SteamAPI_SteamHTTP_v003(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamHTTP(), but using this ensures that you are using a matching library. +inline ISteamHTTP *SteamAPI_SteamHTTP() { return SteamAPI_SteamHTTP_v003(); } + +// A versioned accessor is exported by the library +S_API ISteamHTTP *SteamAPI_SteamGameServerHTTP_v003(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerHTTP(), but using this ensures that you are using a matching library. +inline ISteamHTTP *SteamAPI_SteamGameServerHTTP() { return SteamAPI_SteamGameServerHTTP_v003(); } +S_API HTTPRequestHandle SteamAPI_ISteamHTTP_CreateHTTPRequest( ISteamHTTP* self, EHTTPMethod eHTTPRequestMethod, const char * pchAbsoluteURL ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestContextValue( ISteamHTTP* self, HTTPRequestHandle hRequest, uint64 ulContextValue ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestNetworkActivityTimeout( ISteamHTTP* self, HTTPRequestHandle hRequest, uint32 unTimeoutSeconds ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestHeaderValue( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchHeaderName, const char * pchHeaderValue ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestGetOrPostParameter( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchParamName, const char * pchParamValue ); +S_API bool SteamAPI_ISteamHTTP_SendHTTPRequest( ISteamHTTP* self, HTTPRequestHandle hRequest, SteamAPICall_t * pCallHandle ); +S_API bool SteamAPI_ISteamHTTP_SendHTTPRequestAndStreamResponse( ISteamHTTP* self, HTTPRequestHandle hRequest, SteamAPICall_t * pCallHandle ); +S_API bool SteamAPI_ISteamHTTP_DeferHTTPRequest( ISteamHTTP* self, HTTPRequestHandle hRequest ); +S_API bool SteamAPI_ISteamHTTP_PrioritizeHTTPRequest( ISteamHTTP* self, HTTPRequestHandle hRequest ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPResponseHeaderSize( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchHeaderName, uint32 * unResponseHeaderSize ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPResponseHeaderValue( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchHeaderName, uint8 * pHeaderValueBuffer, uint32 unBufferSize ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPResponseBodySize( ISteamHTTP* self, HTTPRequestHandle hRequest, uint32 * unBodySize ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPResponseBodyData( ISteamHTTP* self, HTTPRequestHandle hRequest, uint8 * pBodyDataBuffer, uint32 unBufferSize ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPStreamingResponseBodyData( ISteamHTTP* self, HTTPRequestHandle hRequest, uint32 cOffset, uint8 * pBodyDataBuffer, uint32 unBufferSize ); +S_API bool SteamAPI_ISteamHTTP_ReleaseHTTPRequest( ISteamHTTP* self, HTTPRequestHandle hRequest ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPDownloadProgressPct( ISteamHTTP* self, HTTPRequestHandle hRequest, float * pflPercentOut ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestRawPostBody( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchContentType, uint8 * pubBody, uint32 unBodyLen ); +S_API HTTPCookieContainerHandle SteamAPI_ISteamHTTP_CreateCookieContainer( ISteamHTTP* self, bool bAllowResponsesToModify ); +S_API bool SteamAPI_ISteamHTTP_ReleaseCookieContainer( ISteamHTTP* self, HTTPCookieContainerHandle hCookieContainer ); +S_API bool SteamAPI_ISteamHTTP_SetCookie( ISteamHTTP* self, HTTPCookieContainerHandle hCookieContainer, const char * pchHost, const char * pchUrl, const char * pchCookie ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestCookieContainer( ISteamHTTP* self, HTTPRequestHandle hRequest, HTTPCookieContainerHandle hCookieContainer ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestUserAgentInfo( ISteamHTTP* self, HTTPRequestHandle hRequest, const char * pchUserAgentInfo ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestRequiresVerifiedCertificate( ISteamHTTP* self, HTTPRequestHandle hRequest, bool bRequireVerifiedCertificate ); +S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestAbsoluteTimeoutMS( ISteamHTTP* self, HTTPRequestHandle hRequest, uint32 unMilliseconds ); +S_API bool SteamAPI_ISteamHTTP_GetHTTPRequestWasTimedOut( ISteamHTTP* self, HTTPRequestHandle hRequest, bool * pbWasTimedOut ); + +// ISteamInput + +// A versioned accessor is exported by the library +S_API ISteamInput *SteamAPI_SteamInput_v006(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamInput(), but using this ensures that you are using a matching library. +inline ISteamInput *SteamAPI_SteamInput() { return SteamAPI_SteamInput_v006(); } +S_API bool SteamAPI_ISteamInput_Init( ISteamInput* self, bool bExplicitlyCallRunFrame ); +S_API bool SteamAPI_ISteamInput_Shutdown( ISteamInput* self ); +S_API bool SteamAPI_ISteamInput_SetInputActionManifestFilePath( ISteamInput* self, const char * pchInputActionManifestAbsolutePath ); +S_API void SteamAPI_ISteamInput_RunFrame( ISteamInput* self, bool bReservedValue ); +S_API bool SteamAPI_ISteamInput_BWaitForData( ISteamInput* self, bool bWaitForever, uint32 unTimeout ); +S_API bool SteamAPI_ISteamInput_BNewDataAvailable( ISteamInput* self ); +S_API int SteamAPI_ISteamInput_GetConnectedControllers( ISteamInput* self, InputHandle_t * handlesOut ); +S_API void SteamAPI_ISteamInput_EnableDeviceCallbacks( ISteamInput* self ); +S_API void SteamAPI_ISteamInput_EnableActionEventCallbacks( ISteamInput* self, SteamInputActionEventCallbackPointer pCallback ); +S_API InputActionSetHandle_t SteamAPI_ISteamInput_GetActionSetHandle( ISteamInput* self, const char * pszActionSetName ); +S_API void SteamAPI_ISteamInput_ActivateActionSet( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle ); +S_API InputActionSetHandle_t SteamAPI_ISteamInput_GetCurrentActionSet( ISteamInput* self, InputHandle_t inputHandle ); +S_API void SteamAPI_ISteamInput_ActivateActionSetLayer( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t actionSetLayerHandle ); +S_API void SteamAPI_ISteamInput_DeactivateActionSetLayer( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t actionSetLayerHandle ); +S_API void SteamAPI_ISteamInput_DeactivateAllActionSetLayers( ISteamInput* self, InputHandle_t inputHandle ); +S_API int SteamAPI_ISteamInput_GetActiveActionSetLayers( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t * handlesOut ); +S_API InputDigitalActionHandle_t SteamAPI_ISteamInput_GetDigitalActionHandle( ISteamInput* self, const char * pszActionName ); +S_API InputDigitalActionData_t SteamAPI_ISteamInput_GetDigitalActionData( ISteamInput* self, InputHandle_t inputHandle, InputDigitalActionHandle_t digitalActionHandle ); +S_API int SteamAPI_ISteamInput_GetDigitalActionOrigins( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputDigitalActionHandle_t digitalActionHandle, EInputActionOrigin * originsOut ); +S_API const char * SteamAPI_ISteamInput_GetStringForDigitalActionName( ISteamInput* self, InputDigitalActionHandle_t eActionHandle ); +S_API InputAnalogActionHandle_t SteamAPI_ISteamInput_GetAnalogActionHandle( ISteamInput* self, const char * pszActionName ); +S_API InputAnalogActionData_t SteamAPI_ISteamInput_GetAnalogActionData( ISteamInput* self, InputHandle_t inputHandle, InputAnalogActionHandle_t analogActionHandle ); +S_API int SteamAPI_ISteamInput_GetAnalogActionOrigins( ISteamInput* self, InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputAnalogActionHandle_t analogActionHandle, EInputActionOrigin * originsOut ); +S_API const char * SteamAPI_ISteamInput_GetGlyphPNGForActionOrigin( ISteamInput* self, EInputActionOrigin eOrigin, ESteamInputGlyphSize eSize, uint32 unFlags ); +S_API const char * SteamAPI_ISteamInput_GetGlyphSVGForActionOrigin( ISteamInput* self, EInputActionOrigin eOrigin, uint32 unFlags ); +S_API const char * SteamAPI_ISteamInput_GetGlyphForActionOrigin_Legacy( ISteamInput* self, EInputActionOrigin eOrigin ); +S_API const char * SteamAPI_ISteamInput_GetStringForActionOrigin( ISteamInput* self, EInputActionOrigin eOrigin ); +S_API const char * SteamAPI_ISteamInput_GetStringForAnalogActionName( ISteamInput* self, InputAnalogActionHandle_t eActionHandle ); +S_API void SteamAPI_ISteamInput_StopAnalogActionMomentum( ISteamInput* self, InputHandle_t inputHandle, InputAnalogActionHandle_t eAction ); +S_API InputMotionData_t SteamAPI_ISteamInput_GetMotionData( ISteamInput* self, InputHandle_t inputHandle ); +S_API void SteamAPI_ISteamInput_TriggerVibration( ISteamInput* self, InputHandle_t inputHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed ); +S_API void SteamAPI_ISteamInput_TriggerVibrationExtended( ISteamInput* self, InputHandle_t inputHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed, unsigned short usLeftTriggerSpeed, unsigned short usRightTriggerSpeed ); +S_API void SteamAPI_ISteamInput_TriggerSimpleHapticEvent( ISteamInput* self, InputHandle_t inputHandle, EControllerHapticLocation eHapticLocation, uint8 nIntensity, char nGainDB, uint8 nOtherIntensity, char nOtherGainDB ); +S_API void SteamAPI_ISteamInput_SetLEDColor( ISteamInput* self, InputHandle_t inputHandle, uint8 nColorR, uint8 nColorG, uint8 nColorB, unsigned int nFlags ); +S_API void SteamAPI_ISteamInput_Legacy_TriggerHapticPulse( ISteamInput* self, InputHandle_t inputHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ); +S_API void SteamAPI_ISteamInput_Legacy_TriggerRepeatedHapticPulse( ISteamInput* self, InputHandle_t inputHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec, unsigned short usOffMicroSec, unsigned short unRepeat, unsigned int nFlags ); +S_API bool SteamAPI_ISteamInput_ShowBindingPanel( ISteamInput* self, InputHandle_t inputHandle ); +S_API ESteamInputType SteamAPI_ISteamInput_GetInputTypeForHandle( ISteamInput* self, InputHandle_t inputHandle ); +S_API InputHandle_t SteamAPI_ISteamInput_GetControllerForGamepadIndex( ISteamInput* self, int nIndex ); +S_API int SteamAPI_ISteamInput_GetGamepadIndexForController( ISteamInput* self, InputHandle_t ulinputHandle ); +S_API const char * SteamAPI_ISteamInput_GetStringForXboxOrigin( ISteamInput* self, EXboxOrigin eOrigin ); +S_API const char * SteamAPI_ISteamInput_GetGlyphForXboxOrigin( ISteamInput* self, EXboxOrigin eOrigin ); +S_API EInputActionOrigin SteamAPI_ISteamInput_GetActionOriginFromXboxOrigin( ISteamInput* self, InputHandle_t inputHandle, EXboxOrigin eOrigin ); +S_API EInputActionOrigin SteamAPI_ISteamInput_TranslateActionOrigin( ISteamInput* self, ESteamInputType eDestinationInputType, EInputActionOrigin eSourceOrigin ); +S_API bool SteamAPI_ISteamInput_GetDeviceBindingRevision( ISteamInput* self, InputHandle_t inputHandle, int * pMajor, int * pMinor ); +S_API uint32 SteamAPI_ISteamInput_GetRemotePlaySessionID( ISteamInput* self, InputHandle_t inputHandle ); +S_API uint16 SteamAPI_ISteamInput_GetSessionInputConfigurationSettings( ISteamInput* self ); +S_API void SteamAPI_ISteamInput_SetDualSenseTriggerEffect( ISteamInput* self, InputHandle_t inputHandle, const ScePadTriggerEffectParam * pParam ); + +// ISteamController + +// A versioned accessor is exported by the library +S_API ISteamController *SteamAPI_SteamController_v008(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamController(), but using this ensures that you are using a matching library. +inline ISteamController *SteamAPI_SteamController() { return SteamAPI_SteamController_v008(); } +S_API bool SteamAPI_ISteamController_Init( ISteamController* self ); +S_API bool SteamAPI_ISteamController_Shutdown( ISteamController* self ); +S_API void SteamAPI_ISteamController_RunFrame( ISteamController* self ); +S_API int SteamAPI_ISteamController_GetConnectedControllers( ISteamController* self, ControllerHandle_t * handlesOut ); +S_API ControllerActionSetHandle_t SteamAPI_ISteamController_GetActionSetHandle( ISteamController* self, const char * pszActionSetName ); +S_API void SteamAPI_ISteamController_ActivateActionSet( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle ); +S_API ControllerActionSetHandle_t SteamAPI_ISteamController_GetCurrentActionSet( ISteamController* self, ControllerHandle_t controllerHandle ); +S_API void SteamAPI_ISteamController_ActivateActionSetLayer( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ); +S_API void SteamAPI_ISteamController_DeactivateActionSetLayer( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ); +S_API void SteamAPI_ISteamController_DeactivateAllActionSetLayers( ISteamController* self, ControllerHandle_t controllerHandle ); +S_API int SteamAPI_ISteamController_GetActiveActionSetLayers( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t * handlesOut ); +S_API ControllerDigitalActionHandle_t SteamAPI_ISteamController_GetDigitalActionHandle( ISteamController* self, const char * pszActionName ); +S_API InputDigitalActionData_t SteamAPI_ISteamController_GetDigitalActionData( ISteamController* self, ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle ); +S_API int SteamAPI_ISteamController_GetDigitalActionOrigins( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerDigitalActionHandle_t digitalActionHandle, EControllerActionOrigin * originsOut ); +S_API ControllerAnalogActionHandle_t SteamAPI_ISteamController_GetAnalogActionHandle( ISteamController* self, const char * pszActionName ); +S_API InputAnalogActionData_t SteamAPI_ISteamController_GetAnalogActionData( ISteamController* self, ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle ); +S_API int SteamAPI_ISteamController_GetAnalogActionOrigins( ISteamController* self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerAnalogActionHandle_t analogActionHandle, EControllerActionOrigin * originsOut ); +S_API const char * SteamAPI_ISteamController_GetGlyphForActionOrigin( ISteamController* self, EControllerActionOrigin eOrigin ); +S_API const char * SteamAPI_ISteamController_GetStringForActionOrigin( ISteamController* self, EControllerActionOrigin eOrigin ); +S_API void SteamAPI_ISteamController_StopAnalogActionMomentum( ISteamController* self, ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction ); +S_API InputMotionData_t SteamAPI_ISteamController_GetMotionData( ISteamController* self, ControllerHandle_t controllerHandle ); +S_API void SteamAPI_ISteamController_TriggerHapticPulse( ISteamController* self, ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ); +S_API void SteamAPI_ISteamController_TriggerRepeatedHapticPulse( ISteamController* self, ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec, unsigned short usOffMicroSec, unsigned short unRepeat, unsigned int nFlags ); +S_API void SteamAPI_ISteamController_TriggerVibration( ISteamController* self, ControllerHandle_t controllerHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed ); +S_API void SteamAPI_ISteamController_SetLEDColor( ISteamController* self, ControllerHandle_t controllerHandle, uint8 nColorR, uint8 nColorG, uint8 nColorB, unsigned int nFlags ); +S_API bool SteamAPI_ISteamController_ShowBindingPanel( ISteamController* self, ControllerHandle_t controllerHandle ); +S_API ESteamInputType SteamAPI_ISteamController_GetInputTypeForHandle( ISteamController* self, ControllerHandle_t controllerHandle ); +S_API ControllerHandle_t SteamAPI_ISteamController_GetControllerForGamepadIndex( ISteamController* self, int nIndex ); +S_API int SteamAPI_ISteamController_GetGamepadIndexForController( ISteamController* self, ControllerHandle_t ulControllerHandle ); +S_API const char * SteamAPI_ISteamController_GetStringForXboxOrigin( ISteamController* self, EXboxOrigin eOrigin ); +S_API const char * SteamAPI_ISteamController_GetGlyphForXboxOrigin( ISteamController* self, EXboxOrigin eOrigin ); +S_API EControllerActionOrigin SteamAPI_ISteamController_GetActionOriginFromXboxOrigin( ISteamController* self, ControllerHandle_t controllerHandle, EXboxOrigin eOrigin ); +S_API EControllerActionOrigin SteamAPI_ISteamController_TranslateActionOrigin( ISteamController* self, ESteamInputType eDestinationInputType, EControllerActionOrigin eSourceOrigin ); +S_API bool SteamAPI_ISteamController_GetControllerBindingRevision( ISteamController* self, ControllerHandle_t controllerHandle, int * pMajor, int * pMinor ); + +// ISteamUGC + +// A versioned accessor is exported by the library +S_API ISteamUGC *SteamAPI_SteamUGC_v016(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamUGC(), but using this ensures that you are using a matching library. +inline ISteamUGC *SteamAPI_SteamUGC() { return SteamAPI_SteamUGC_v016(); } + +// A versioned accessor is exported by the library +S_API ISteamUGC *SteamAPI_SteamGameServerUGC_v016(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerUGC(), but using this ensures that you are using a matching library. +inline ISteamUGC *SteamAPI_SteamGameServerUGC() { return SteamAPI_SteamGameServerUGC_v016(); } +S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryUserUGCRequest( ISteamUGC* self, AccountID_t unAccountID, EUserUGCList eListType, EUGCMatchingUGCType eMatchingUGCType, EUserUGCListSortOrder eSortOrder, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ); +S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryAllUGCRequestPage( ISteamUGC* self, EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ); +S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryAllUGCRequestCursor( ISteamUGC* self, EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, const char * pchCursor ); +S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest( ISteamUGC* self, PublishedFileId_t * pvecPublishedFileID, uint32 unNumPublishedFileIDs ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_SendQueryUGCRequest( ISteamUGC* self, UGCQueryHandle_t handle ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCResult( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t * pDetails ); +S_API uint32 SteamAPI_ISteamUGC_GetQueryUGCNumTags( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCTag( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 indexTag, char * pchValue, uint32 cchValueSize ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCTagDisplayName( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 indexTag, char * pchValue, uint32 cchValueSize ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCPreviewURL( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, char * pchURL, uint32 cchURLSize ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCMetadata( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, char * pchMetadata, uint32 cchMetadatasize ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCChildren( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, PublishedFileId_t * pvecPublishedFileID, uint32 cMaxEntries ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCStatistic( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, EItemStatistic eStatType, uint64 * pStatValue ); +S_API uint32 SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 previewIndex, char * pchURLOrVideoID, uint32 cchURLSize, char * pchOriginalFileName, uint32 cchOriginalFileNameSize, EItemPreviewType * pPreviewType ); +S_API uint32 SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 keyValueTagIndex, char * pchKey, uint32 cchKeySize, char * pchValue, uint32 cchValueSize ); +S_API bool SteamAPI_ISteamUGC_GetQueryFirstUGCKeyValueTag( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, const char * pchKey, char * pchValue, uint32 cchValueSize ); +S_API bool SteamAPI_ISteamUGC_ReleaseQueryUGCRequest( ISteamUGC* self, UGCQueryHandle_t handle ); +S_API bool SteamAPI_ISteamUGC_AddRequiredTag( ISteamUGC* self, UGCQueryHandle_t handle, const char * pTagName ); +S_API bool SteamAPI_ISteamUGC_AddRequiredTagGroup( ISteamUGC* self, UGCQueryHandle_t handle, const SteamParamStringArray_t * pTagGroups ); +S_API bool SteamAPI_ISteamUGC_AddExcludedTag( ISteamUGC* self, UGCQueryHandle_t handle, const char * pTagName ); +S_API bool SteamAPI_ISteamUGC_SetReturnOnlyIDs( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnOnlyIDs ); +S_API bool SteamAPI_ISteamUGC_SetReturnKeyValueTags( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnKeyValueTags ); +S_API bool SteamAPI_ISteamUGC_SetReturnLongDescription( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnLongDescription ); +S_API bool SteamAPI_ISteamUGC_SetReturnMetadata( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnMetadata ); +S_API bool SteamAPI_ISteamUGC_SetReturnChildren( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnChildren ); +S_API bool SteamAPI_ISteamUGC_SetReturnAdditionalPreviews( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnAdditionalPreviews ); +S_API bool SteamAPI_ISteamUGC_SetReturnTotalOnly( ISteamUGC* self, UGCQueryHandle_t handle, bool bReturnTotalOnly ); +S_API bool SteamAPI_ISteamUGC_SetReturnPlaytimeStats( ISteamUGC* self, UGCQueryHandle_t handle, uint32 unDays ); +S_API bool SteamAPI_ISteamUGC_SetLanguage( ISteamUGC* self, UGCQueryHandle_t handle, const char * pchLanguage ); +S_API bool SteamAPI_ISteamUGC_SetAllowCachedResponse( ISteamUGC* self, UGCQueryHandle_t handle, uint32 unMaxAgeSeconds ); +S_API bool SteamAPI_ISteamUGC_SetCloudFileNameFilter( ISteamUGC* self, UGCQueryHandle_t handle, const char * pMatchCloudFileName ); +S_API bool SteamAPI_ISteamUGC_SetMatchAnyTag( ISteamUGC* self, UGCQueryHandle_t handle, bool bMatchAnyTag ); +S_API bool SteamAPI_ISteamUGC_SetSearchText( ISteamUGC* self, UGCQueryHandle_t handle, const char * pSearchText ); +S_API bool SteamAPI_ISteamUGC_SetRankedByTrendDays( ISteamUGC* self, UGCQueryHandle_t handle, uint32 unDays ); +S_API bool SteamAPI_ISteamUGC_SetTimeCreatedDateRange( ISteamUGC* self, UGCQueryHandle_t handle, RTime32 rtStart, RTime32 rtEnd ); +S_API bool SteamAPI_ISteamUGC_SetTimeUpdatedDateRange( ISteamUGC* self, UGCQueryHandle_t handle, RTime32 rtStart, RTime32 rtEnd ); +S_API bool SteamAPI_ISteamUGC_AddRequiredKeyValueTag( ISteamUGC* self, UGCQueryHandle_t handle, const char * pKey, const char * pValue ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_RequestUGCDetails( ISteamUGC* self, PublishedFileId_t nPublishedFileID, uint32 unMaxAgeSeconds ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_CreateItem( ISteamUGC* self, AppId_t nConsumerAppId, EWorkshopFileType eFileType ); +S_API UGCUpdateHandle_t SteamAPI_ISteamUGC_StartItemUpdate( ISteamUGC* self, AppId_t nConsumerAppId, PublishedFileId_t nPublishedFileID ); +S_API bool SteamAPI_ISteamUGC_SetItemTitle( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchTitle ); +S_API bool SteamAPI_ISteamUGC_SetItemDescription( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchDescription ); +S_API bool SteamAPI_ISteamUGC_SetItemUpdateLanguage( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchLanguage ); +S_API bool SteamAPI_ISteamUGC_SetItemMetadata( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchMetaData ); +S_API bool SteamAPI_ISteamUGC_SetItemVisibility( ISteamUGC* self, UGCUpdateHandle_t handle, ERemoteStoragePublishedFileVisibility eVisibility ); +S_API bool SteamAPI_ISteamUGC_SetItemTags( ISteamUGC* self, UGCUpdateHandle_t updateHandle, const SteamParamStringArray_t * pTags ); +S_API bool SteamAPI_ISteamUGC_SetItemContent( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pszContentFolder ); +S_API bool SteamAPI_ISteamUGC_SetItemPreview( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pszPreviewFile ); +S_API bool SteamAPI_ISteamUGC_SetAllowLegacyUpload( ISteamUGC* self, UGCUpdateHandle_t handle, bool bAllowLegacyUpload ); +S_API bool SteamAPI_ISteamUGC_RemoveAllItemKeyValueTags( ISteamUGC* self, UGCUpdateHandle_t handle ); +S_API bool SteamAPI_ISteamUGC_RemoveItemKeyValueTags( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchKey ); +S_API bool SteamAPI_ISteamUGC_AddItemKeyValueTag( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchKey, const char * pchValue ); +S_API bool SteamAPI_ISteamUGC_AddItemPreviewFile( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pszPreviewFile, EItemPreviewType type ); +S_API bool SteamAPI_ISteamUGC_AddItemPreviewVideo( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pszVideoID ); +S_API bool SteamAPI_ISteamUGC_UpdateItemPreviewFile( ISteamUGC* self, UGCUpdateHandle_t handle, uint32 index, const char * pszPreviewFile ); +S_API bool SteamAPI_ISteamUGC_UpdateItemPreviewVideo( ISteamUGC* self, UGCUpdateHandle_t handle, uint32 index, const char * pszVideoID ); +S_API bool SteamAPI_ISteamUGC_RemoveItemPreview( ISteamUGC* self, UGCUpdateHandle_t handle, uint32 index ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_SubmitItemUpdate( ISteamUGC* self, UGCUpdateHandle_t handle, const char * pchChangeNote ); +S_API EItemUpdateStatus SteamAPI_ISteamUGC_GetItemUpdateProgress( ISteamUGC* self, UGCUpdateHandle_t handle, uint64 * punBytesProcessed, uint64 * punBytesTotal ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_SetUserItemVote( ISteamUGC* self, PublishedFileId_t nPublishedFileID, bool bVoteUp ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_GetUserItemVote( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_AddItemToFavorites( ISteamUGC* self, AppId_t nAppId, PublishedFileId_t nPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_RemoveItemFromFavorites( ISteamUGC* self, AppId_t nAppId, PublishedFileId_t nPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_SubscribeItem( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_UnsubscribeItem( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API uint32 SteamAPI_ISteamUGC_GetNumSubscribedItems( ISteamUGC* self ); +S_API uint32 SteamAPI_ISteamUGC_GetSubscribedItems( ISteamUGC* self, PublishedFileId_t * pvecPublishedFileID, uint32 cMaxEntries ); +S_API uint32 SteamAPI_ISteamUGC_GetItemState( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API bool SteamAPI_ISteamUGC_GetItemInstallInfo( ISteamUGC* self, PublishedFileId_t nPublishedFileID, uint64 * punSizeOnDisk, char * pchFolder, uint32 cchFolderSize, uint32 * punTimeStamp ); +S_API bool SteamAPI_ISteamUGC_GetItemDownloadInfo( ISteamUGC* self, PublishedFileId_t nPublishedFileID, uint64 * punBytesDownloaded, uint64 * punBytesTotal ); +S_API bool SteamAPI_ISteamUGC_DownloadItem( ISteamUGC* self, PublishedFileId_t nPublishedFileID, bool bHighPriority ); +S_API bool SteamAPI_ISteamUGC_BInitWorkshopForGameServer( ISteamUGC* self, DepotId_t unWorkshopDepotID, const char * pszFolder ); +S_API void SteamAPI_ISteamUGC_SuspendDownloads( ISteamUGC* self, bool bSuspend ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_StartPlaytimeTracking( ISteamUGC* self, PublishedFileId_t * pvecPublishedFileID, uint32 unNumPublishedFileIDs ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_StopPlaytimeTracking( ISteamUGC* self, PublishedFileId_t * pvecPublishedFileID, uint32 unNumPublishedFileIDs ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems( ISteamUGC* self ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_AddDependency( ISteamUGC* self, PublishedFileId_t nParentPublishedFileID, PublishedFileId_t nChildPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_RemoveDependency( ISteamUGC* self, PublishedFileId_t nParentPublishedFileID, PublishedFileId_t nChildPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_AddAppDependency( ISteamUGC* self, PublishedFileId_t nPublishedFileID, AppId_t nAppID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_RemoveAppDependency( ISteamUGC* self, PublishedFileId_t nPublishedFileID, AppId_t nAppID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_GetAppDependencies( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_DeleteItem( ISteamUGC* self, PublishedFileId_t nPublishedFileID ); +S_API bool SteamAPI_ISteamUGC_ShowWorkshopEULA( ISteamUGC* self ); +S_API SteamAPICall_t SteamAPI_ISteamUGC_GetWorkshopEULAStatus( ISteamUGC* self ); + +// ISteamAppList + +// A versioned accessor is exported by the library +S_API ISteamAppList *SteamAPI_SteamAppList_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamAppList(), but using this ensures that you are using a matching library. +inline ISteamAppList *SteamAPI_SteamAppList() { return SteamAPI_SteamAppList_v001(); } +S_API uint32 SteamAPI_ISteamAppList_GetNumInstalledApps( ISteamAppList* self ); +S_API uint32 SteamAPI_ISteamAppList_GetInstalledApps( ISteamAppList* self, AppId_t * pvecAppID, uint32 unMaxAppIDs ); +S_API int SteamAPI_ISteamAppList_GetAppName( ISteamAppList* self, AppId_t nAppID, char * pchName, int cchNameMax ); +S_API int SteamAPI_ISteamAppList_GetAppInstallDir( ISteamAppList* self, AppId_t nAppID, char * pchDirectory, int cchNameMax ); +S_API int SteamAPI_ISteamAppList_GetAppBuildId( ISteamAppList* self, AppId_t nAppID ); + +// ISteamHTMLSurface + +// A versioned accessor is exported by the library +S_API ISteamHTMLSurface *SteamAPI_SteamHTMLSurface_v005(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamHTMLSurface(), but using this ensures that you are using a matching library. +inline ISteamHTMLSurface *SteamAPI_SteamHTMLSurface() { return SteamAPI_SteamHTMLSurface_v005(); } +S_API bool SteamAPI_ISteamHTMLSurface_Init( ISteamHTMLSurface* self ); +S_API bool SteamAPI_ISteamHTMLSurface_Shutdown( ISteamHTMLSurface* self ); +S_API SteamAPICall_t SteamAPI_ISteamHTMLSurface_CreateBrowser( ISteamHTMLSurface* self, const char * pchUserAgent, const char * pchUserCSS ); +S_API void SteamAPI_ISteamHTMLSurface_RemoveBrowser( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_LoadURL( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, const char * pchURL, const char * pchPostData ); +S_API void SteamAPI_ISteamHTMLSurface_SetSize( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 unWidth, uint32 unHeight ); +S_API void SteamAPI_ISteamHTMLSurface_StopLoad( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_Reload( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_GoBack( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_GoForward( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_AddHeader( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, const char * pchKey, const char * pchValue ); +S_API void SteamAPI_ISteamHTMLSurface_ExecuteJavascript( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, const char * pchScript ); +S_API void SteamAPI_ISteamHTMLSurface_MouseUp( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, ISteamHTMLSurface::EHTMLMouseButton eMouseButton ); +S_API void SteamAPI_ISteamHTMLSurface_MouseDown( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, ISteamHTMLSurface::EHTMLMouseButton eMouseButton ); +S_API void SteamAPI_ISteamHTMLSurface_MouseDoubleClick( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, ISteamHTMLSurface::EHTMLMouseButton eMouseButton ); +S_API void SteamAPI_ISteamHTMLSurface_MouseMove( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, int x, int y ); +S_API void SteamAPI_ISteamHTMLSurface_MouseWheel( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, int32 nDelta ); +S_API void SteamAPI_ISteamHTMLSurface_KeyDown( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 nNativeKeyCode, ISteamHTMLSurface::EHTMLKeyModifiers eHTMLKeyModifiers, bool bIsSystemKey ); +S_API void SteamAPI_ISteamHTMLSurface_KeyUp( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 nNativeKeyCode, ISteamHTMLSurface::EHTMLKeyModifiers eHTMLKeyModifiers ); +S_API void SteamAPI_ISteamHTMLSurface_KeyChar( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 cUnicodeChar, ISteamHTMLSurface::EHTMLKeyModifiers eHTMLKeyModifiers ); +S_API void SteamAPI_ISteamHTMLSurface_SetHorizontalScroll( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 nAbsolutePixelScroll ); +S_API void SteamAPI_ISteamHTMLSurface_SetVerticalScroll( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, uint32 nAbsolutePixelScroll ); +S_API void SteamAPI_ISteamHTMLSurface_SetKeyFocus( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, bool bHasKeyFocus ); +S_API void SteamAPI_ISteamHTMLSurface_ViewSource( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_CopyToClipboard( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_PasteFromClipboard( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_Find( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, const char * pchSearchStr, bool bCurrentlyInFind, bool bReverse ); +S_API void SteamAPI_ISteamHTMLSurface_StopFind( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_GetLinkAtPosition( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, int x, int y ); +S_API void SteamAPI_ISteamHTMLSurface_SetCookie( ISteamHTMLSurface* self, const char * pchHostname, const char * pchKey, const char * pchValue, const char * pchPath, RTime32 nExpires, bool bSecure, bool bHTTPOnly ); +S_API void SteamAPI_ISteamHTMLSurface_SetPageScaleFactor( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, float flZoom, int nPointX, int nPointY ); +S_API void SteamAPI_ISteamHTMLSurface_SetBackgroundMode( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, bool bBackgroundMode ); +S_API void SteamAPI_ISteamHTMLSurface_SetDPIScalingFactor( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, float flDPIScaling ); +S_API void SteamAPI_ISteamHTMLSurface_OpenDeveloperTools( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle ); +S_API void SteamAPI_ISteamHTMLSurface_AllowStartRequest( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, bool bAllowed ); +S_API void SteamAPI_ISteamHTMLSurface_JSDialogResponse( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, bool bResult ); +S_API void SteamAPI_ISteamHTMLSurface_FileLoadDialogResponse( ISteamHTMLSurface* self, HHTMLBrowser unBrowserHandle, const char ** pchSelectedFiles ); + +// ISteamInventory + +// A versioned accessor is exported by the library +S_API ISteamInventory *SteamAPI_SteamInventory_v003(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamInventory(), but using this ensures that you are using a matching library. +inline ISteamInventory *SteamAPI_SteamInventory() { return SteamAPI_SteamInventory_v003(); } + +// A versioned accessor is exported by the library +S_API ISteamInventory *SteamAPI_SteamGameServerInventory_v003(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerInventory(), but using this ensures that you are using a matching library. +inline ISteamInventory *SteamAPI_SteamGameServerInventory() { return SteamAPI_SteamGameServerInventory_v003(); } +S_API EResult SteamAPI_ISteamInventory_GetResultStatus( ISteamInventory* self, SteamInventoryResult_t resultHandle ); +S_API bool SteamAPI_ISteamInventory_GetResultItems( ISteamInventory* self, SteamInventoryResult_t resultHandle, SteamItemDetails_t * pOutItemsArray, uint32 * punOutItemsArraySize ); +S_API bool SteamAPI_ISteamInventory_GetResultItemProperty( ISteamInventory* self, SteamInventoryResult_t resultHandle, uint32 unItemIndex, const char * pchPropertyName, char * pchValueBuffer, uint32 * punValueBufferSizeOut ); +S_API uint32 SteamAPI_ISteamInventory_GetResultTimestamp( ISteamInventory* self, SteamInventoryResult_t resultHandle ); +S_API bool SteamAPI_ISteamInventory_CheckResultSteamID( ISteamInventory* self, SteamInventoryResult_t resultHandle, uint64_steamid steamIDExpected ); +S_API void SteamAPI_ISteamInventory_DestroyResult( ISteamInventory* self, SteamInventoryResult_t resultHandle ); +S_API bool SteamAPI_ISteamInventory_GetAllItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle ); +S_API bool SteamAPI_ISteamInventory_GetItemsByID( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, const SteamItemInstanceID_t * pInstanceIDs, uint32 unCountInstanceIDs ); +S_API bool SteamAPI_ISteamInventory_SerializeResult( ISteamInventory* self, SteamInventoryResult_t resultHandle, void * pOutBuffer, uint32 * punOutBufferSize ); +S_API bool SteamAPI_ISteamInventory_DeserializeResult( ISteamInventory* self, SteamInventoryResult_t * pOutResultHandle, const void * pBuffer, uint32 unBufferSize, bool bRESERVED_MUST_BE_FALSE ); +S_API bool SteamAPI_ISteamInventory_GenerateItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, const SteamItemDef_t * pArrayItemDefs, const uint32 * punArrayQuantity, uint32 unArrayLength ); +S_API bool SteamAPI_ISteamInventory_GrantPromoItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle ); +S_API bool SteamAPI_ISteamInventory_AddPromoItem( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, SteamItemDef_t itemDef ); +S_API bool SteamAPI_ISteamInventory_AddPromoItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, const SteamItemDef_t * pArrayItemDefs, uint32 unArrayLength ); +S_API bool SteamAPI_ISteamInventory_ConsumeItem( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, SteamItemInstanceID_t itemConsume, uint32 unQuantity ); +S_API bool SteamAPI_ISteamInventory_ExchangeItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, const SteamItemDef_t * pArrayGenerate, const uint32 * punArrayGenerateQuantity, uint32 unArrayGenerateLength, const SteamItemInstanceID_t * pArrayDestroy, const uint32 * punArrayDestroyQuantity, uint32 unArrayDestroyLength ); +S_API bool SteamAPI_ISteamInventory_TransferItemQuantity( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, SteamItemInstanceID_t itemIdSource, uint32 unQuantity, SteamItemInstanceID_t itemIdDest ); +S_API void SteamAPI_ISteamInventory_SendItemDropHeartbeat( ISteamInventory* self ); +S_API bool SteamAPI_ISteamInventory_TriggerItemDrop( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, SteamItemDef_t dropListDefinition ); +S_API bool SteamAPI_ISteamInventory_TradeItems( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, uint64_steamid steamIDTradePartner, const SteamItemInstanceID_t * pArrayGive, const uint32 * pArrayGiveQuantity, uint32 nArrayGiveLength, const SteamItemInstanceID_t * pArrayGet, const uint32 * pArrayGetQuantity, uint32 nArrayGetLength ); +S_API bool SteamAPI_ISteamInventory_LoadItemDefinitions( ISteamInventory* self ); +S_API bool SteamAPI_ISteamInventory_GetItemDefinitionIDs( ISteamInventory* self, SteamItemDef_t * pItemDefIDs, uint32 * punItemDefIDsArraySize ); +S_API bool SteamAPI_ISteamInventory_GetItemDefinitionProperty( ISteamInventory* self, SteamItemDef_t iDefinition, const char * pchPropertyName, char * pchValueBuffer, uint32 * punValueBufferSizeOut ); +S_API SteamAPICall_t SteamAPI_ISteamInventory_RequestEligiblePromoItemDefinitionsIDs( ISteamInventory* self, uint64_steamid steamID ); +S_API bool SteamAPI_ISteamInventory_GetEligiblePromoItemDefinitionIDs( ISteamInventory* self, uint64_steamid steamID, SteamItemDef_t * pItemDefIDs, uint32 * punItemDefIDsArraySize ); +S_API SteamAPICall_t SteamAPI_ISteamInventory_StartPurchase( ISteamInventory* self, const SteamItemDef_t * pArrayItemDefs, const uint32 * punArrayQuantity, uint32 unArrayLength ); +S_API SteamAPICall_t SteamAPI_ISteamInventory_RequestPrices( ISteamInventory* self ); +S_API uint32 SteamAPI_ISteamInventory_GetNumItemsWithPrices( ISteamInventory* self ); +S_API bool SteamAPI_ISteamInventory_GetItemsWithPrices( ISteamInventory* self, SteamItemDef_t * pArrayItemDefs, uint64 * pCurrentPrices, uint64 * pBasePrices, uint32 unArrayLength ); +S_API bool SteamAPI_ISteamInventory_GetItemPrice( ISteamInventory* self, SteamItemDef_t iDefinition, uint64 * pCurrentPrice, uint64 * pBasePrice ); +S_API SteamInventoryUpdateHandle_t SteamAPI_ISteamInventory_StartUpdateProperties( ISteamInventory* self ); +S_API bool SteamAPI_ISteamInventory_RemoveProperty( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char * pchPropertyName ); +S_API bool SteamAPI_ISteamInventory_SetPropertyString( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char * pchPropertyName, const char * pchPropertyValue ); +S_API bool SteamAPI_ISteamInventory_SetPropertyBool( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char * pchPropertyName, bool bValue ); +S_API bool SteamAPI_ISteamInventory_SetPropertyInt64( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char * pchPropertyName, int64 nValue ); +S_API bool SteamAPI_ISteamInventory_SetPropertyFloat( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamItemInstanceID_t nItemID, const char * pchPropertyName, float flValue ); +S_API bool SteamAPI_ISteamInventory_SubmitUpdateProperties( ISteamInventory* self, SteamInventoryUpdateHandle_t handle, SteamInventoryResult_t * pResultHandle ); +S_API bool SteamAPI_ISteamInventory_InspectItem( ISteamInventory* self, SteamInventoryResult_t * pResultHandle, const char * pchItemToken ); + +// ISteamVideo + +// A versioned accessor is exported by the library +S_API ISteamVideo *SteamAPI_SteamVideo_v002(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamVideo(), but using this ensures that you are using a matching library. +inline ISteamVideo *SteamAPI_SteamVideo() { return SteamAPI_SteamVideo_v002(); } +S_API void SteamAPI_ISteamVideo_GetVideoURL( ISteamVideo* self, AppId_t unVideoAppID ); +S_API bool SteamAPI_ISteamVideo_IsBroadcasting( ISteamVideo* self, int * pnNumViewers ); +S_API void SteamAPI_ISteamVideo_GetOPFSettings( ISteamVideo* self, AppId_t unVideoAppID ); +S_API bool SteamAPI_ISteamVideo_GetOPFStringForApp( ISteamVideo* self, AppId_t unVideoAppID, char * pchBuffer, int32 * pnBufferSize ); + +// ISteamParentalSettings + +// A versioned accessor is exported by the library +S_API ISteamParentalSettings *SteamAPI_SteamParentalSettings_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamParentalSettings(), but using this ensures that you are using a matching library. +inline ISteamParentalSettings *SteamAPI_SteamParentalSettings() { return SteamAPI_SteamParentalSettings_v001(); } +S_API bool SteamAPI_ISteamParentalSettings_BIsParentalLockEnabled( ISteamParentalSettings* self ); +S_API bool SteamAPI_ISteamParentalSettings_BIsParentalLockLocked( ISteamParentalSettings* self ); +S_API bool SteamAPI_ISteamParentalSettings_BIsAppBlocked( ISteamParentalSettings* self, AppId_t nAppID ); +S_API bool SteamAPI_ISteamParentalSettings_BIsAppInBlockList( ISteamParentalSettings* self, AppId_t nAppID ); +S_API bool SteamAPI_ISteamParentalSettings_BIsFeatureBlocked( ISteamParentalSettings* self, EParentalFeature eFeature ); +S_API bool SteamAPI_ISteamParentalSettings_BIsFeatureInBlockList( ISteamParentalSettings* self, EParentalFeature eFeature ); + +// ISteamRemotePlay + +// A versioned accessor is exported by the library +S_API ISteamRemotePlay *SteamAPI_SteamRemotePlay_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamRemotePlay(), but using this ensures that you are using a matching library. +inline ISteamRemotePlay *SteamAPI_SteamRemotePlay() { return SteamAPI_SteamRemotePlay_v001(); } +S_API uint32 SteamAPI_ISteamRemotePlay_GetSessionCount( ISteamRemotePlay* self ); +S_API RemotePlaySessionID_t SteamAPI_ISteamRemotePlay_GetSessionID( ISteamRemotePlay* self, int iSessionIndex ); +S_API uint64_steamid SteamAPI_ISteamRemotePlay_GetSessionSteamID( ISteamRemotePlay* self, RemotePlaySessionID_t unSessionID ); +S_API const char * SteamAPI_ISteamRemotePlay_GetSessionClientName( ISteamRemotePlay* self, RemotePlaySessionID_t unSessionID ); +S_API ESteamDeviceFormFactor SteamAPI_ISteamRemotePlay_GetSessionClientFormFactor( ISteamRemotePlay* self, RemotePlaySessionID_t unSessionID ); +S_API bool SteamAPI_ISteamRemotePlay_BGetSessionClientResolution( ISteamRemotePlay* self, RemotePlaySessionID_t unSessionID, int * pnResolutionX, int * pnResolutionY ); +S_API bool SteamAPI_ISteamRemotePlay_BSendRemotePlayTogetherInvite( ISteamRemotePlay* self, uint64_steamid steamIDFriend ); + +// ISteamNetworkingMessages + +// A versioned accessor is exported by the library +S_API ISteamNetworkingMessages *SteamAPI_SteamNetworkingMessages_SteamAPI_v002(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamNetworkingMessages_SteamAPI(), but using this ensures that you are using a matching library. +inline ISteamNetworkingMessages *SteamAPI_SteamNetworkingMessages_SteamAPI() { return SteamAPI_SteamNetworkingMessages_SteamAPI_v002(); } + +// A versioned accessor is exported by the library +S_API ISteamNetworkingMessages *SteamAPI_SteamGameServerNetworkingMessages_SteamAPI_v002(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerNetworkingMessages_SteamAPI(), but using this ensures that you are using a matching library. +inline ISteamNetworkingMessages *SteamAPI_SteamGameServerNetworkingMessages_SteamAPI() { return SteamAPI_SteamGameServerNetworkingMessages_SteamAPI_v002(); } +S_API EResult SteamAPI_ISteamNetworkingMessages_SendMessageToUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote, const void * pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ); +S_API int SteamAPI_ISteamNetworkingMessages_ReceiveMessagesOnChannel( ISteamNetworkingMessages* self, int nLocalChannel, SteamNetworkingMessage_t ** ppOutMessages, int nMaxMessages ); +S_API bool SteamAPI_ISteamNetworkingMessages_AcceptSessionWithUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote ); +S_API bool SteamAPI_ISteamNetworkingMessages_CloseSessionWithUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote ); +S_API bool SteamAPI_ISteamNetworkingMessages_CloseChannelWithUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote, int nLocalChannel ); +S_API ESteamNetworkingConnectionState SteamAPI_ISteamNetworkingMessages_GetSessionConnectionInfo( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote, SteamNetConnectionInfo_t * pConnectionInfo, SteamNetConnectionRealTimeStatus_t * pQuickStatus ); + +// ISteamNetworkingSockets + +// A versioned accessor is exported by the library +S_API ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI_v012(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamNetworkingSockets_SteamAPI(), but using this ensures that you are using a matching library. +inline ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI() { return SteamAPI_SteamNetworkingSockets_SteamAPI_v012(); } + +// A versioned accessor is exported by the library +S_API ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerNetworkingSockets_SteamAPI(), but using this ensures that you are using a matching library. +inline ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI() { return SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(); } +S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP( ISteamNetworkingSockets* self, const SteamNetworkingIPAddr & localAddress, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress( ISteamNetworkingSockets* self, const SteamNetworkingIPAddr & address, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketP2P( ISteamNetworkingSockets* self, int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectP2P( ISteamNetworkingSockets* self, const SteamNetworkingIdentity & identityRemote, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API EResult SteamAPI_ISteamNetworkingSockets_AcceptConnection( ISteamNetworkingSockets* self, HSteamNetConnection hConn ); +S_API bool SteamAPI_ISteamNetworkingSockets_CloseConnection( ISteamNetworkingSockets* self, HSteamNetConnection hPeer, int nReason, const char * pszDebug, bool bEnableLinger ); +S_API bool SteamAPI_ISteamNetworkingSockets_CloseListenSocket( ISteamNetworkingSockets* self, HSteamListenSocket hSocket ); +S_API bool SteamAPI_ISteamNetworkingSockets_SetConnectionUserData( ISteamNetworkingSockets* self, HSteamNetConnection hPeer, int64 nUserData ); +S_API int64 SteamAPI_ISteamNetworkingSockets_GetConnectionUserData( ISteamNetworkingSockets* self, HSteamNetConnection hPeer ); +S_API void SteamAPI_ISteamNetworkingSockets_SetConnectionName( ISteamNetworkingSockets* self, HSteamNetConnection hPeer, const char * pszName ); +S_API bool SteamAPI_ISteamNetworkingSockets_GetConnectionName( ISteamNetworkingSockets* self, HSteamNetConnection hPeer, char * pszName, int nMaxLen ); +S_API EResult SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( ISteamNetworkingSockets* self, HSteamNetConnection hConn, const void * pData, uint32 cbData, int nSendFlags, int64 * pOutMessageNumber ); +S_API void SteamAPI_ISteamNetworkingSockets_SendMessages( ISteamNetworkingSockets* self, int nMessages, SteamNetworkingMessage_t *const * pMessages, int64 * pOutMessageNumberOrResult ); +S_API EResult SteamAPI_ISteamNetworkingSockets_FlushMessagesOnConnection( ISteamNetworkingSockets* self, HSteamNetConnection hConn ); +S_API int SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection( ISteamNetworkingSockets* self, HSteamNetConnection hConn, SteamNetworkingMessage_t ** ppOutMessages, int nMaxMessages ); +S_API bool SteamAPI_ISteamNetworkingSockets_GetConnectionInfo( ISteamNetworkingSockets* self, HSteamNetConnection hConn, SteamNetConnectionInfo_t * pInfo ); +S_API EResult SteamAPI_ISteamNetworkingSockets_GetConnectionRealTimeStatus( ISteamNetworkingSockets* self, HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t * pStatus, int nLanes, SteamNetConnectionRealTimeLaneStatus_t * pLanes ); +S_API int SteamAPI_ISteamNetworkingSockets_GetDetailedConnectionStatus( ISteamNetworkingSockets* self, HSteamNetConnection hConn, char * pszBuf, int cbBuf ); +S_API bool SteamAPI_ISteamNetworkingSockets_GetListenSocketAddress( ISteamNetworkingSockets* self, HSteamListenSocket hSocket, SteamNetworkingIPAddr * address ); +S_API bool SteamAPI_ISteamNetworkingSockets_CreateSocketPair( ISteamNetworkingSockets* self, HSteamNetConnection * pOutConnection1, HSteamNetConnection * pOutConnection2, bool bUseNetworkLoopback, const SteamNetworkingIdentity * pIdentity1, const SteamNetworkingIdentity * pIdentity2 ); +S_API EResult SteamAPI_ISteamNetworkingSockets_ConfigureConnectionLanes( ISteamNetworkingSockets* self, HSteamNetConnection hConn, int nNumLanes, const int * pLanePriorities, const uint16 * pLaneWeights ); +S_API bool SteamAPI_ISteamNetworkingSockets_GetIdentity( ISteamNetworkingSockets* self, SteamNetworkingIdentity * pIdentity ); +S_API ESteamNetworkingAvailability SteamAPI_ISteamNetworkingSockets_InitAuthentication( ISteamNetworkingSockets* self ); +S_API ESteamNetworkingAvailability SteamAPI_ISteamNetworkingSockets_GetAuthenticationStatus( ISteamNetworkingSockets* self, SteamNetAuthenticationStatus_t * pDetails ); +S_API HSteamNetPollGroup SteamAPI_ISteamNetworkingSockets_CreatePollGroup( ISteamNetworkingSockets* self ); +S_API bool SteamAPI_ISteamNetworkingSockets_DestroyPollGroup( ISteamNetworkingSockets* self, HSteamNetPollGroup hPollGroup ); +S_API bool SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup( ISteamNetworkingSockets* self, HSteamNetConnection hConn, HSteamNetPollGroup hPollGroup ); +S_API int SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup( ISteamNetworkingSockets* self, HSteamNetPollGroup hPollGroup, SteamNetworkingMessage_t ** ppOutMessages, int nMaxMessages ); +S_API bool SteamAPI_ISteamNetworkingSockets_ReceivedRelayAuthTicket( ISteamNetworkingSockets* self, const void * pvTicket, int cbTicket, SteamDatagramRelayAuthTicket * pOutParsedTicket ); +S_API int SteamAPI_ISteamNetworkingSockets_FindRelayAuthTicketForServer( ISteamNetworkingSockets* self, const SteamNetworkingIdentity & identityGameServer, int nRemoteVirtualPort, SteamDatagramRelayAuthTicket * pOutParsedTicket ); +S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectToHostedDedicatedServer( ISteamNetworkingSockets* self, const SteamNetworkingIdentity & identityTarget, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API uint16 SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerPort( ISteamNetworkingSockets* self ); +S_API SteamNetworkingPOPID SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerPOPID( ISteamNetworkingSockets* self ); +S_API EResult SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerAddress( ISteamNetworkingSockets* self, SteamDatagramHostedAddress * pRouting ); +S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateHostedDedicatedServerListenSocket( ISteamNetworkingSockets* self, int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API EResult SteamAPI_ISteamNetworkingSockets_GetGameCoordinatorServerLogin( ISteamNetworkingSockets* self, SteamDatagramGameCoordinatorServerLogin * pLoginInfo, int * pcbSignedBlob, void * pBlob ); +S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectP2PCustomSignaling( ISteamNetworkingSockets* self, ISteamNetworkingConnectionSignaling * pSignaling, const SteamNetworkingIdentity * pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API bool SteamAPI_ISteamNetworkingSockets_ReceivedP2PCustomSignal( ISteamNetworkingSockets* self, const void * pMsg, int cbMsg, ISteamNetworkingSignalingRecvContext * pContext ); +S_API bool SteamAPI_ISteamNetworkingSockets_GetCertificateRequest( ISteamNetworkingSockets* self, int * pcbBlob, void * pBlob, SteamNetworkingErrMsg & errMsg ); +S_API bool SteamAPI_ISteamNetworkingSockets_SetCertificate( ISteamNetworkingSockets* self, const void * pCertificate, int cbCertificate, SteamNetworkingErrMsg & errMsg ); +S_API void SteamAPI_ISteamNetworkingSockets_ResetIdentity( ISteamNetworkingSockets* self, const SteamNetworkingIdentity * pIdentity ); +S_API void SteamAPI_ISteamNetworkingSockets_RunCallbacks( ISteamNetworkingSockets* self ); +S_API bool SteamAPI_ISteamNetworkingSockets_BeginAsyncRequestFakeIP( ISteamNetworkingSockets* self, int nNumPorts ); +S_API void SteamAPI_ISteamNetworkingSockets_GetFakeIP( ISteamNetworkingSockets* self, int idxFirstPort, SteamNetworkingFakeIPResult_t * pInfo ); +S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketP2PFakeIP( ISteamNetworkingSockets* self, int idxFakePort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API EResult SteamAPI_ISteamNetworkingSockets_GetRemoteFakeIPForConnection( ISteamNetworkingSockets* self, HSteamNetConnection hConn, SteamNetworkingIPAddr * pOutAddr ); +S_API ISteamNetworkingFakeUDPPort * SteamAPI_ISteamNetworkingSockets_CreateFakeUDPPort( ISteamNetworkingSockets* self, int idxFakeServerPort ); + +// ISteamNetworkingUtils + +// A versioned accessor is exported by the library +S_API ISteamNetworkingUtils *SteamAPI_SteamNetworkingUtils_SteamAPI_v004(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamNetworkingUtils_SteamAPI(), but using this ensures that you are using a matching library. +inline ISteamNetworkingUtils *SteamAPI_SteamNetworkingUtils_SteamAPI() { return SteamAPI_SteamNetworkingUtils_SteamAPI_v004(); } +S_API SteamNetworkingMessage_t * SteamAPI_ISteamNetworkingUtils_AllocateMessage( ISteamNetworkingUtils* self, int cbAllocateBuffer ); +S_API void SteamAPI_ISteamNetworkingUtils_InitRelayNetworkAccess( ISteamNetworkingUtils* self ); +S_API ESteamNetworkingAvailability SteamAPI_ISteamNetworkingUtils_GetRelayNetworkStatus( ISteamNetworkingUtils* self, SteamRelayNetworkStatus_t * pDetails ); +S_API float SteamAPI_ISteamNetworkingUtils_GetLocalPingLocation( ISteamNetworkingUtils* self, SteamNetworkPingLocation_t & result ); +S_API int SteamAPI_ISteamNetworkingUtils_EstimatePingTimeBetweenTwoLocations( ISteamNetworkingUtils* self, const SteamNetworkPingLocation_t & location1, const SteamNetworkPingLocation_t & location2 ); +S_API int SteamAPI_ISteamNetworkingUtils_EstimatePingTimeFromLocalHost( ISteamNetworkingUtils* self, const SteamNetworkPingLocation_t & remoteLocation ); +S_API void SteamAPI_ISteamNetworkingUtils_ConvertPingLocationToString( ISteamNetworkingUtils* self, const SteamNetworkPingLocation_t & location, char * pszBuf, int cchBufSize ); +S_API bool SteamAPI_ISteamNetworkingUtils_ParsePingLocationString( ISteamNetworkingUtils* self, const char * pszString, SteamNetworkPingLocation_t & result ); +S_API bool SteamAPI_ISteamNetworkingUtils_CheckPingDataUpToDate( ISteamNetworkingUtils* self, float flMaxAgeSeconds ); +S_API int SteamAPI_ISteamNetworkingUtils_GetPingToDataCenter( ISteamNetworkingUtils* self, SteamNetworkingPOPID popID, SteamNetworkingPOPID * pViaRelayPoP ); +S_API int SteamAPI_ISteamNetworkingUtils_GetDirectPingToPOP( ISteamNetworkingUtils* self, SteamNetworkingPOPID popID ); +S_API int SteamAPI_ISteamNetworkingUtils_GetPOPCount( ISteamNetworkingUtils* self ); +S_API int SteamAPI_ISteamNetworkingUtils_GetPOPList( ISteamNetworkingUtils* self, SteamNetworkingPOPID * list, int nListSz ); +S_API SteamNetworkingMicroseconds SteamAPI_ISteamNetworkingUtils_GetLocalTimestamp( ISteamNetworkingUtils* self ); +S_API void SteamAPI_ISteamNetworkingUtils_SetDebugOutputFunction( ISteamNetworkingUtils* self, ESteamNetworkingSocketsDebugOutputType eDetailLevel, FSteamNetworkingSocketsDebugOutput pfnFunc ); +S_API bool SteamAPI_ISteamNetworkingUtils_IsFakeIPv4( ISteamNetworkingUtils* self, uint32 nIPv4 ); +S_API ESteamNetworkingFakeIPType SteamAPI_ISteamNetworkingUtils_GetIPv4FakeIPType( ISteamNetworkingUtils* self, uint32 nIPv4 ); +S_API EResult SteamAPI_ISteamNetworkingUtils_GetRealIdentityForFakeIP( ISteamNetworkingUtils* self, const SteamNetworkingIPAddr & fakeIP, SteamNetworkingIdentity * pOutRealIdentity ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueInt32( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, int32 val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueFloat( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, float val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueString( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, const char * val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValuePtr( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, void * val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueInt32( ISteamNetworkingUtils* self, HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, int32 val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueFloat( ISteamNetworkingUtils* self, HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, float val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueString( ISteamNetworkingUtils* self, HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, const char * val ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetConnectionStatusChanged( ISteamNetworkingUtils* self, FnSteamNetConnectionStatusChanged fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetAuthenticationStatusChanged( ISteamNetworkingUtils* self, FnSteamNetAuthenticationStatusChanged fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamRelayNetworkStatusChanged( ISteamNetworkingUtils* self, FnSteamRelayNetworkStatusChanged fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_FakeIPResult( ISteamNetworkingUtils* self, FnSteamNetworkingFakeIPResult fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_MessagesSessionRequest( ISteamNetworkingUtils* self, FnSteamNetworkingMessagesSessionRequest fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_MessagesSessionFailed( ISteamNetworkingUtils* self, FnSteamNetworkingMessagesSessionFailed fnCallback ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetConfigValue( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj, ESteamNetworkingConfigDataType eDataType, const void * pArg ); +S_API bool SteamAPI_ISteamNetworkingUtils_SetConfigValueStruct( ISteamNetworkingUtils* self, const SteamNetworkingConfigValue_t & opt, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj ); +S_API ESteamNetworkingGetConfigValueResult SteamAPI_ISteamNetworkingUtils_GetConfigValue( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj, ESteamNetworkingConfigDataType * pOutDataType, void * pResult, size_t * cbResult ); +S_API const char * SteamAPI_ISteamNetworkingUtils_GetConfigValueInfo( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigDataType * pOutDataType, ESteamNetworkingConfigScope * pOutScope ); +S_API ESteamNetworkingConfigValue SteamAPI_ISteamNetworkingUtils_IterateGenericEditableConfigValues( ISteamNetworkingUtils* self, ESteamNetworkingConfigValue eCurrent, bool bEnumerateDevVars ); +S_API void SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_ToString( ISteamNetworkingUtils* self, const SteamNetworkingIPAddr & addr, char * buf, uint32 cbBuf, bool bWithPort ); +S_API bool SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_ParseString( ISteamNetworkingUtils* self, SteamNetworkingIPAddr * pAddr, const char * pszStr ); +S_API ESteamNetworkingFakeIPType SteamAPI_ISteamNetworkingUtils_SteamNetworkingIPAddr_GetFakeIPType( ISteamNetworkingUtils* self, const SteamNetworkingIPAddr & addr ); +S_API void SteamAPI_ISteamNetworkingUtils_SteamNetworkingIdentity_ToString( ISteamNetworkingUtils* self, const SteamNetworkingIdentity & identity, char * buf, uint32 cbBuf ); +S_API bool SteamAPI_ISteamNetworkingUtils_SteamNetworkingIdentity_ParseString( ISteamNetworkingUtils* self, SteamNetworkingIdentity * pIdentity, const char * pszStr ); + +// ISteamGameServer + +// A versioned accessor is exported by the library +S_API ISteamGameServer *SteamAPI_SteamGameServer_v014(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServer(), but using this ensures that you are using a matching library. +inline ISteamGameServer *SteamAPI_SteamGameServer() { return SteamAPI_SteamGameServer_v014(); } +S_API void SteamAPI_ISteamGameServer_SetProduct( ISteamGameServer* self, const char * pszProduct ); +S_API void SteamAPI_ISteamGameServer_SetGameDescription( ISteamGameServer* self, const char * pszGameDescription ); +S_API void SteamAPI_ISteamGameServer_SetModDir( ISteamGameServer* self, const char * pszModDir ); +S_API void SteamAPI_ISteamGameServer_SetDedicatedServer( ISteamGameServer* self, bool bDedicated ); +S_API void SteamAPI_ISteamGameServer_LogOn( ISteamGameServer* self, const char * pszToken ); +S_API void SteamAPI_ISteamGameServer_LogOnAnonymous( ISteamGameServer* self ); +S_API void SteamAPI_ISteamGameServer_LogOff( ISteamGameServer* self ); +S_API bool SteamAPI_ISteamGameServer_BLoggedOn( ISteamGameServer* self ); +S_API bool SteamAPI_ISteamGameServer_BSecure( ISteamGameServer* self ); +S_API uint64_steamid SteamAPI_ISteamGameServer_GetSteamID( ISteamGameServer* self ); +S_API bool SteamAPI_ISteamGameServer_WasRestartRequested( ISteamGameServer* self ); +S_API void SteamAPI_ISteamGameServer_SetMaxPlayerCount( ISteamGameServer* self, int cPlayersMax ); +S_API void SteamAPI_ISteamGameServer_SetBotPlayerCount( ISteamGameServer* self, int cBotplayers ); +S_API void SteamAPI_ISteamGameServer_SetServerName( ISteamGameServer* self, const char * pszServerName ); +S_API void SteamAPI_ISteamGameServer_SetMapName( ISteamGameServer* self, const char * pszMapName ); +S_API void SteamAPI_ISteamGameServer_SetPasswordProtected( ISteamGameServer* self, bool bPasswordProtected ); +S_API void SteamAPI_ISteamGameServer_SetSpectatorPort( ISteamGameServer* self, uint16 unSpectatorPort ); +S_API void SteamAPI_ISteamGameServer_SetSpectatorServerName( ISteamGameServer* self, const char * pszSpectatorServerName ); +S_API void SteamAPI_ISteamGameServer_ClearAllKeyValues( ISteamGameServer* self ); +S_API void SteamAPI_ISteamGameServer_SetKeyValue( ISteamGameServer* self, const char * pKey, const char * pValue ); +S_API void SteamAPI_ISteamGameServer_SetGameTags( ISteamGameServer* self, const char * pchGameTags ); +S_API void SteamAPI_ISteamGameServer_SetGameData( ISteamGameServer* self, const char * pchGameData ); +S_API void SteamAPI_ISteamGameServer_SetRegion( ISteamGameServer* self, const char * pszRegion ); +S_API void SteamAPI_ISteamGameServer_SetAdvertiseServerActive( ISteamGameServer* self, bool bActive ); +S_API HAuthTicket SteamAPI_ISteamGameServer_GetAuthSessionTicket( ISteamGameServer* self, void * pTicket, int cbMaxTicket, uint32 * pcbTicket ); +S_API EBeginAuthSessionResult SteamAPI_ISteamGameServer_BeginAuthSession( ISteamGameServer* self, const void * pAuthTicket, int cbAuthTicket, uint64_steamid steamID ); +S_API void SteamAPI_ISteamGameServer_EndAuthSession( ISteamGameServer* self, uint64_steamid steamID ); +S_API void SteamAPI_ISteamGameServer_CancelAuthTicket( ISteamGameServer* self, HAuthTicket hAuthTicket ); +S_API EUserHasLicenseForAppResult SteamAPI_ISteamGameServer_UserHasLicenseForApp( ISteamGameServer* self, uint64_steamid steamID, AppId_t appID ); +S_API bool SteamAPI_ISteamGameServer_RequestUserGroupStatus( ISteamGameServer* self, uint64_steamid steamIDUser, uint64_steamid steamIDGroup ); +S_API void SteamAPI_ISteamGameServer_GetGameplayStats( ISteamGameServer* self ); +S_API SteamAPICall_t SteamAPI_ISteamGameServer_GetServerReputation( ISteamGameServer* self ); +S_API SteamIPAddress_t SteamAPI_ISteamGameServer_GetPublicIP( ISteamGameServer* self ); +S_API bool SteamAPI_ISteamGameServer_HandleIncomingPacket( ISteamGameServer* self, const void * pData, int cbData, uint32 srcIP, uint16 srcPort ); +S_API int SteamAPI_ISteamGameServer_GetNextOutgoingPacket( ISteamGameServer* self, void * pOut, int cbMaxOut, uint32 * pNetAdr, uint16 * pPort ); +S_API SteamAPICall_t SteamAPI_ISteamGameServer_AssociateWithClan( ISteamGameServer* self, uint64_steamid steamIDClan ); +S_API SteamAPICall_t SteamAPI_ISteamGameServer_ComputeNewPlayerCompatibility( ISteamGameServer* self, uint64_steamid steamIDNewPlayer ); +S_API bool SteamAPI_ISteamGameServer_SendUserConnectAndAuthenticate_DEPRECATED( ISteamGameServer* self, uint32 unIPClient, const void * pvAuthBlob, uint32 cubAuthBlobSize, CSteamID * pSteamIDUser ); +S_API uint64_steamid SteamAPI_ISteamGameServer_CreateUnauthenticatedUserConnection( ISteamGameServer* self ); +S_API void SteamAPI_ISteamGameServer_SendUserDisconnect_DEPRECATED( ISteamGameServer* self, uint64_steamid steamIDUser ); +S_API bool SteamAPI_ISteamGameServer_BUpdateUserData( ISteamGameServer* self, uint64_steamid steamIDUser, const char * pchPlayerName, uint32 uScore ); + +// ISteamGameServerStats + +// A versioned accessor is exported by the library +S_API ISteamGameServerStats *SteamAPI_SteamGameServerStats_v001(); +// Inline, unversioned accessor to get the current version. Essentially the same as SteamGameServerStats(), but using this ensures that you are using a matching library. +inline ISteamGameServerStats *SteamAPI_SteamGameServerStats() { return SteamAPI_SteamGameServerStats_v001(); } +S_API SteamAPICall_t SteamAPI_ISteamGameServerStats_RequestUserStats( ISteamGameServerStats* self, uint64_steamid steamIDUser ); +S_API bool SteamAPI_ISteamGameServerStats_GetUserStatInt32( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, int32 * pData ); +S_API bool SteamAPI_ISteamGameServerStats_GetUserStatFloat( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, float * pData ); +S_API bool SteamAPI_ISteamGameServerStats_GetUserAchievement( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, bool * pbAchieved ); +S_API bool SteamAPI_ISteamGameServerStats_SetUserStatInt32( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, int32 nData ); +S_API bool SteamAPI_ISteamGameServerStats_SetUserStatFloat( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, float fData ); +S_API bool SteamAPI_ISteamGameServerStats_UpdateUserAvgRateStat( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName, float flCountThisSession, double dSessionLength ); +S_API bool SteamAPI_ISteamGameServerStats_SetUserAchievement( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName ); +S_API bool SteamAPI_ISteamGameServerStats_ClearUserAchievement( ISteamGameServerStats* self, uint64_steamid steamIDUser, const char * pchName ); +S_API SteamAPICall_t SteamAPI_ISteamGameServerStats_StoreUserStats( ISteamGameServerStats* self, uint64_steamid steamIDUser ); + +// ISteamNetworkingFakeUDPPort +S_API void SteamAPI_ISteamNetworkingFakeUDPPort_DestroyFakeUDPPort( ISteamNetworkingFakeUDPPort* self ); +S_API EResult SteamAPI_ISteamNetworkingFakeUDPPort_SendMessageToFakeIP( ISteamNetworkingFakeUDPPort* self, const SteamNetworkingIPAddr & remoteAddress, const void * pData, uint32 cbData, int nSendFlags ); +S_API int SteamAPI_ISteamNetworkingFakeUDPPort_ReceiveMessages( ISteamNetworkingFakeUDPPort* self, SteamNetworkingMessage_t ** ppOutMessages, int nMaxMessages ); +S_API void SteamAPI_ISteamNetworkingFakeUDPPort_ScheduleCleanup( ISteamNetworkingFakeUDPPort* self, const SteamNetworkingIPAddr & remoteAddress ); + +// SteamIPAddress_t +S_API bool SteamAPI_SteamIPAddress_t_IsSet( SteamIPAddress_t* self ); + +// MatchMakingKeyValuePair_t +S_API void SteamAPI_MatchMakingKeyValuePair_t_Construct( MatchMakingKeyValuePair_t* self ); + +// servernetadr_t +S_API void SteamAPI_servernetadr_t_Construct( servernetadr_t* self ); +S_API void SteamAPI_servernetadr_t_Init( servernetadr_t* self, unsigned int ip, uint16 usQueryPort, uint16 usConnectionPort ); +S_API uint16 SteamAPI_servernetadr_t_GetQueryPort( servernetadr_t* self ); +S_API void SteamAPI_servernetadr_t_SetQueryPort( servernetadr_t* self, uint16 usPort ); +S_API uint16 SteamAPI_servernetadr_t_GetConnectionPort( servernetadr_t* self ); +S_API void SteamAPI_servernetadr_t_SetConnectionPort( servernetadr_t* self, uint16 usPort ); +S_API uint32 SteamAPI_servernetadr_t_GetIP( servernetadr_t* self ); +S_API void SteamAPI_servernetadr_t_SetIP( servernetadr_t* self, uint32 unIP ); +S_API const char * SteamAPI_servernetadr_t_GetConnectionAddressString( servernetadr_t* self ); +S_API const char * SteamAPI_servernetadr_t_GetQueryAddressString( servernetadr_t* self ); +S_API bool SteamAPI_servernetadr_t_IsLessThan( servernetadr_t* self, const servernetadr_t & netadr ); +S_API void SteamAPI_servernetadr_t_Assign( servernetadr_t* self, const servernetadr_t & that ); + +// gameserveritem_t +S_API void SteamAPI_gameserveritem_t_Construct( gameserveritem_t* self ); +S_API const char * SteamAPI_gameserveritem_t_GetName( gameserveritem_t* self ); +S_API void SteamAPI_gameserveritem_t_SetName( gameserveritem_t* self, const char * pName ); + +// SteamNetworkingIPAddr +S_API void SteamAPI_SteamNetworkingIPAddr_Clear( SteamNetworkingIPAddr* self ); +S_API bool SteamAPI_SteamNetworkingIPAddr_IsIPv6AllZeros( SteamNetworkingIPAddr* self ); +S_API void SteamAPI_SteamNetworkingIPAddr_SetIPv6( SteamNetworkingIPAddr* self, const uint8 * ipv6, uint16 nPort ); +S_API void SteamAPI_SteamNetworkingIPAddr_SetIPv4( SteamNetworkingIPAddr* self, uint32 nIP, uint16 nPort ); +S_API bool SteamAPI_SteamNetworkingIPAddr_IsIPv4( SteamNetworkingIPAddr* self ); +S_API uint32 SteamAPI_SteamNetworkingIPAddr_GetIPv4( SteamNetworkingIPAddr* self ); +S_API void SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost( SteamNetworkingIPAddr* self, uint16 nPort ); +S_API bool SteamAPI_SteamNetworkingIPAddr_IsLocalHost( SteamNetworkingIPAddr* self ); +S_API void SteamAPI_SteamNetworkingIPAddr_ToString( SteamNetworkingIPAddr* self, char * buf, uint32 cbBuf, bool bWithPort ); +S_API bool SteamAPI_SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr* self, const char * pszStr ); +S_API bool SteamAPI_SteamNetworkingIPAddr_IsEqualTo( SteamNetworkingIPAddr* self, const SteamNetworkingIPAddr & x ); +S_API ESteamNetworkingFakeIPType SteamAPI_SteamNetworkingIPAddr_GetFakeIPType( SteamNetworkingIPAddr* self ); +S_API bool SteamAPI_SteamNetworkingIPAddr_IsFakeIP( SteamNetworkingIPAddr* self ); + +// SteamNetworkingIdentity +S_API void SteamAPI_SteamNetworkingIdentity_Clear( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_IsInvalid( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetSteamID( SteamNetworkingIdentity* self, uint64_steamid steamID ); +S_API uint64_steamid SteamAPI_SteamNetworkingIdentity_GetSteamID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetSteamID64( SteamNetworkingIdentity* self, uint64 steamID ); +S_API uint64 SteamAPI_SteamNetworkingIdentity_GetSteamID64( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_SetXboxPairwiseID( SteamNetworkingIdentity* self, const char * pszString ); +S_API const char * SteamAPI_SteamNetworkingIdentity_GetXboxPairwiseID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetPSNID( SteamNetworkingIdentity* self, uint64 id ); +S_API uint64 SteamAPI_SteamNetworkingIdentity_GetPSNID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetStadiaID( SteamNetworkingIdentity* self, uint64 id ); +S_API uint64 SteamAPI_SteamNetworkingIdentity_GetStadiaID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetIPAddr( SteamNetworkingIdentity* self, const SteamNetworkingIPAddr & addr ); +S_API const SteamNetworkingIPAddr * SteamAPI_SteamNetworkingIdentity_GetIPAddr( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetIPv4Addr( SteamNetworkingIdentity* self, uint32 nIPv4, uint16 nPort ); +S_API uint32 SteamAPI_SteamNetworkingIdentity_GetIPv4( SteamNetworkingIdentity* self ); +S_API ESteamNetworkingFakeIPType SteamAPI_SteamNetworkingIdentity_GetFakeIPType( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_IsFakeIP( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetLocalHost( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_IsLocalHost( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_SetGenericString( SteamNetworkingIdentity* self, const char * pszString ); +S_API const char * SteamAPI_SteamNetworkingIdentity_GetGenericString( SteamNetworkingIdentity* self ); +S_API bool SteamAPI_SteamNetworkingIdentity_SetGenericBytes( SteamNetworkingIdentity* self, const void * data, uint32 cbLen ); +S_API const uint8 * SteamAPI_SteamNetworkingIdentity_GetGenericBytes( SteamNetworkingIdentity* self, int & cbLen ); +S_API bool SteamAPI_SteamNetworkingIdentity_IsEqualTo( SteamNetworkingIdentity* self, const SteamNetworkingIdentity & x ); +S_API void SteamAPI_SteamNetworkingIdentity_ToString( SteamNetworkingIdentity* self, char * buf, uint32 cbBuf ); +S_API bool SteamAPI_SteamNetworkingIdentity_ParseString( SteamNetworkingIdentity* self, const char * pszStr ); + +// SteamNetworkingMessage_t +S_API void SteamAPI_SteamNetworkingMessage_t_Release( SteamNetworkingMessage_t* self ); + +// SteamNetworkingConfigValue_t +S_API void SteamAPI_SteamNetworkingConfigValue_t_SetInt32( SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, int32_t data ); +S_API void SteamAPI_SteamNetworkingConfigValue_t_SetInt64( SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, int64_t data ); +S_API void SteamAPI_SteamNetworkingConfigValue_t_SetFloat( SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, float data ); +S_API void SteamAPI_SteamNetworkingConfigValue_t_SetPtr( SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, void * data ); +S_API void SteamAPI_SteamNetworkingConfigValue_t_SetString( SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, const char * data ); + +// SteamDatagramHostedAddress +S_API void SteamAPI_SteamDatagramHostedAddress_Clear( SteamDatagramHostedAddress* self ); +S_API SteamNetworkingPOPID SteamAPI_SteamDatagramHostedAddress_GetPopID( SteamDatagramHostedAddress* self ); +S_API void SteamAPI_SteamDatagramHostedAddress_SetDevAddress( SteamDatagramHostedAddress* self, uint32 nIP, uint16 nPort, SteamNetworkingPOPID popid ); +#endif // STEAMAPIFLAT_H diff --git a/public/steam/steam_api_internal.h b/public/steam/steam_api_internal.h new file mode 100644 index 00000000..fcebd7b7 --- /dev/null +++ b/public/steam/steam_api_internal.h @@ -0,0 +1,406 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== +// +// Internal implementation details of the steamworks SDK. +// +// You should be able to figure out how to use the SDK by reading +// steam_api_common.h, and should not need to understand anything in here. +// +//----------------------------------------------------------------------------- + +#ifdef STEAM_CALLBACK_BEGIN +#error "This file should only be included from steam_api_common.h" +#endif + +#include + +// Internal functions used to locate/create interfaces +S_API HSteamPipe S_CALLTYPE SteamAPI_GetHSteamPipe(); +S_API HSteamUser S_CALLTYPE SteamAPI_GetHSteamUser(); +S_API HSteamPipe S_CALLTYPE SteamGameServer_GetHSteamPipe(); +S_API HSteamUser S_CALLTYPE SteamGameServer_GetHSteamUser(); +S_API void *S_CALLTYPE SteamInternal_ContextInit( void *pContextInitData ); +S_API void *S_CALLTYPE SteamInternal_CreateInterface( const char *ver ); +S_API void *S_CALLTYPE SteamInternal_FindOrCreateUserInterface( HSteamUser hSteamUser, const char *pszVersion ); +S_API void *S_CALLTYPE SteamInternal_FindOrCreateGameServerInterface( HSteamUser hSteamUser, const char *pszVersion ); + +// Macro used to define a type-safe accessor that will always return the version +// of the interface of the *header file* you are compiling with! We also bounce +// through a safety function that checks for interfaces being created or destroyed. +// +// SteamInternal_ContextInit takes a base pointer for the equivalent of +// struct { void (*pFn)(void* pCtx); uintptr_t counter; void *ptr; } +// Do not change layout or add non-pointer aligned data! +#define STEAM_DEFINE_INTERFACE_ACCESSOR( type, name, expr, kind, version ) \ + inline void S_CALLTYPE SteamInternal_Init_ ## name( type *p ) { *p = (type)( expr ); } \ + STEAM_CLANG_ATTR( "interface_accessor_kind:" kind ";interface_accessor_version:" version ";" ) \ + inline type name() { \ + static void* s_CallbackCounterAndContext[ 3 ] = { (void*)&SteamInternal_Init_ ## name, 0, 0 }; \ + return *(type*)SteamInternal_ContextInit( s_CallbackCounterAndContext ); \ + } + +#define STEAM_DEFINE_USER_INTERFACE_ACCESSOR( type, name, version ) \ + STEAM_DEFINE_INTERFACE_ACCESSOR( type, name, SteamInternal_FindOrCreateUserInterface( SteamAPI_GetHSteamUser(), version ), "user", version ) +#define STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( type, name, version ) \ + STEAM_DEFINE_INTERFACE_ACCESSOR( type, name, SteamInternal_FindOrCreateGameServerInterface( SteamGameServer_GetHSteamUser(), version ), "gameserver", version ) + +// +// Internal stuff used for the standard, higher-level callback mechanism +// + +// Internal functions used by the utility CCallback objects to receive callbacks +S_API void S_CALLTYPE SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback ); +S_API void S_CALLTYPE SteamAPI_UnregisterCallback( class CCallbackBase *pCallback ); +// Internal functions used by the utility CCallResult objects to receive async call results +S_API void S_CALLTYPE SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); +S_API void S_CALLTYPE SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall ); + +// disable this warning; this pattern need for steam callback registration +#ifdef _MSVC_VER +#pragma warning( push ) +#pragma warning( disable: 4355 ) // 'this' : used in base member initializer list +#endif + +#define _STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) +#define _STEAM_CALLBACK_HELPER( _1, _2, SELECTED, ... ) _STEAM_CALLBACK_##SELECTED +#define _STEAM_CALLBACK_SELECT( X, Y ) _STEAM_CALLBACK_HELPER X Y +#define _STEAM_CALLBACK_3( extra_code, thisclass, func, param ) \ + struct CCallbackInternal_ ## func : private CCallbackImpl< sizeof( param ) > { \ + CCallbackInternal_ ## func () { extra_code SteamAPI_RegisterCallback( this, param::k_iCallback ); } \ + CCallbackInternal_ ## func ( const CCallbackInternal_ ## func & ) { extra_code SteamAPI_RegisterCallback( this, param::k_iCallback ); } \ + CCallbackInternal_ ## func & operator=( const CCallbackInternal_ ## func & ) { return *this; } \ + private: virtual void Run( void *pvParam ) { _STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) \ + thisclass *pOuter = reinterpret_cast( reinterpret_cast(this) - offsetof( thisclass, m_steamcallback_ ## func ) ); \ + pOuter->func( reinterpret_cast( pvParam ) ); \ + } \ + } m_steamcallback_ ## func ; void func( param *pParam ) +#define _STEAM_CALLBACK_4( _, thisclass, func, param, var ) \ + CCallback< thisclass, param > var; void func( param *pParam ) +#define _STEAM_CALLBACK_GS( _, thisclass, func, param, var ) \ + CCallback< thisclass, param, true > var; void func( param *pParam ) + +#ifndef API_GEN + +template< class T, class P > +inline CCallResult::CCallResult() +{ + m_hAPICall = k_uAPICallInvalid; + m_pObj = nullptr; + m_Func = nullptr; + m_iCallback = P::k_iCallback; +} + +template< class T, class P > +inline void CCallResult::Set( SteamAPICall_t hAPICall, T *p, func_t func ) +{ + if ( m_hAPICall ) + SteamAPI_UnregisterCallResult( this, m_hAPICall ); + + m_hAPICall = hAPICall; + m_pObj = p; + m_Func = func; + + if ( hAPICall ) + SteamAPI_RegisterCallResult( this, hAPICall ); +} + +template< class T, class P > +inline bool CCallResult::IsActive() const +{ + return (m_hAPICall != k_uAPICallInvalid); +} + +template< class T, class P > +inline void CCallResult::Cancel() +{ + if ( m_hAPICall != k_uAPICallInvalid ) + { + SteamAPI_UnregisterCallResult( this, m_hAPICall ); + m_hAPICall = k_uAPICallInvalid; + } +} + +template< class T, class P > +inline CCallResult::~CCallResult() +{ + Cancel(); +} + +template< class T, class P > +inline void CCallResult::Run( void *pvParam ) +{ + m_hAPICall = k_uAPICallInvalid; // caller unregisters for us + (m_pObj->*m_Func)((P *)pvParam, false); +} + +template< class T, class P > +inline void CCallResult::Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) +{ + if ( hSteamAPICall == m_hAPICall ) + { + m_hAPICall = k_uAPICallInvalid; // caller unregisters for us + (m_pObj->*m_Func)((P *)pvParam, bIOFailure); + } +} + +template< class T, class P, bool bGameserver > +inline CCallback< T, P, bGameserver >::CCallback( T *pObj, func_t func ) + : m_pObj( nullptr ), m_Func( nullptr ) +{ + if ( bGameserver ) + { + this->SetGameserverFlag(); + } + Register( pObj, func ); +} + +template< class T, class P, bool bGameserver > +inline void CCallback< T, P, bGameserver >::Register( T *pObj, func_t func ) +{ + if ( !pObj || !func ) + return; + + if ( this->m_nCallbackFlags & CCallbackBase::k_ECallbackFlagsRegistered ) + Unregister(); + + m_pObj = pObj; + m_Func = func; + // SteamAPI_RegisterCallback sets k_ECallbackFlagsRegistered + SteamAPI_RegisterCallback( this, P::k_iCallback ); +} + +template< class T, class P, bool bGameserver > +inline void CCallback< T, P, bGameserver >::Unregister() +{ + // SteamAPI_UnregisterCallback removes k_ECallbackFlagsRegistered + SteamAPI_UnregisterCallback( this ); +} + +template< class T, class P, bool bGameserver > +inline void CCallback< T, P, bGameserver >::Run( void *pvParam ) +{ + (m_pObj->*m_Func)((P *)pvParam); +} + +#endif // #ifndef API_GEN + +// structure that contains client callback data +// see callbacks documentation for more details +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx +#endif + +/// Internal structure used in manual callback dispatch +struct CallbackMsg_t +{ + HSteamUser m_hSteamUser; // Specific user to whom this callback applies. + int m_iCallback; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.) + uint8 *m_pubParam; // Points to the callback structure + int m_cubParam; // Size of the data pointed to by m_pubParam +}; +#pragma pack( pop ) + +// Macros to define steam callback structures. Used internally for debugging +#ifdef STEAM_CALLBACK_INSPECTION_ENABLED + #include "../../clientdll/steam_api_callback_inspection.h" +#else + #define STEAM_CALLBACK_BEGIN( callbackname, callbackid ) struct callbackname { enum { k_iCallback = callbackid }; + #define STEAM_CALLBACK_MEMBER( varidx, vartype, varname ) vartype varname ; + #define STEAM_CALLBACK_MEMBER_ARRAY( varidx, vartype, varname, varcount ) vartype varname [ varcount ]; + #define STEAM_CALLBACK_END(nArgs) }; +#endif + +// Forward declare all of the Steam interfaces. (Do we really need to do this?) +class ISteamClient; +class ISteamUser; +class ISteamGameServer; +class ISteamFriends; +class ISteamUtils; +class ISteamMatchmaking; +class ISteamContentServer; +class ISteamMatchmakingServers; +class ISteamUserStats; +class ISteamApps; +class ISteamNetworking; +class ISteamRemoteStorage; +class ISteamScreenshots; +class ISteamMusic; +class ISteamMusicRemote; +class ISteamGameServerStats; +class ISteamPS3OverlayRender; +class ISteamHTTP; +class ISteamController; +class ISteamUGC; +class ISteamAppList; +class ISteamHTMLSurface; +class ISteamInventory; +class ISteamVideo; +class ISteamParentalSettings; +class ISteamGameSearch; +class ISteamInput; +class ISteamParties; +class ISteamRemotePlay; + +//----------------------------------------------------------------------------- +// Purpose: Base values for callback identifiers, each callback must +// have a unique ID. +//----------------------------------------------------------------------------- +enum { k_iSteamUserCallbacks = 100 }; +enum { k_iSteamGameServerCallbacks = 200 }; +enum { k_iSteamFriendsCallbacks = 300 }; +enum { k_iSteamBillingCallbacks = 400 }; +enum { k_iSteamMatchmakingCallbacks = 500 }; +enum { k_iSteamContentServerCallbacks = 600 }; +enum { k_iSteamUtilsCallbacks = 700 }; +enum { k_iSteamAppsCallbacks = 1000 }; +enum { k_iSteamUserStatsCallbacks = 1100 }; +enum { k_iSteamNetworkingCallbacks = 1200 }; +enum { k_iSteamNetworkingSocketsCallbacks = 1220 }; +enum { k_iSteamNetworkingMessagesCallbacks = 1250 }; +enum { k_iSteamNetworkingUtilsCallbacks = 1280 }; +enum { k_iSteamRemoteStorageCallbacks = 1300 }; +enum { k_iSteamGameServerItemsCallbacks = 1500 }; +enum { k_iSteamGameCoordinatorCallbacks = 1700 }; +enum { k_iSteamGameServerStatsCallbacks = 1800 }; +enum { k_iSteam2AsyncCallbacks = 1900 }; +enum { k_iSteamGameStatsCallbacks = 2000 }; +enum { k_iSteamHTTPCallbacks = 2100 }; +enum { k_iSteamScreenshotsCallbacks = 2300 }; +// NOTE: 2500-2599 are reserved +enum { k_iSteamStreamLauncherCallbacks = 2600 }; +enum { k_iSteamControllerCallbacks = 2800 }; +enum { k_iSteamUGCCallbacks = 3400 }; +enum { k_iSteamStreamClientCallbacks = 3500 }; +enum { k_iSteamAppListCallbacks = 3900 }; +enum { k_iSteamMusicCallbacks = 4000 }; +enum { k_iSteamMusicRemoteCallbacks = 4100 }; +enum { k_iSteamGameNotificationCallbacks = 4400 }; +enum { k_iSteamHTMLSurfaceCallbacks = 4500 }; +enum { k_iSteamVideoCallbacks = 4600 }; +enum { k_iSteamInventoryCallbacks = 4700 }; +enum { k_ISteamParentalSettingsCallbacks = 5000 }; +enum { k_iSteamGameSearchCallbacks = 5200 }; +enum { k_iSteamPartiesCallbacks = 5300 }; +enum { k_iSteamSTARCallbacks = 5500 }; +enum { k_iSteamRemotePlayCallbacks = 5700 }; +enum { k_iSteamChatCallbacks = 5900 }; +// NOTE: Internal "IClientXxx" callback IDs go in clientenums.h + +#ifdef _MSVC_VER +#pragma warning( pop ) +#endif + +// Macros used to annotate various Steamworks interfaces to generate the +// flat API +#ifdef API_GEN +# define STEAM_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#else +# define STEAM_CLANG_ATTR(ATTR) +#endif + +#define STEAM_OUT_STRUCT() STEAM_CLANG_ATTR( "out_struct: ;" ) +#define STEAM_OUT_STRING() STEAM_CLANG_ATTR( "out_string: ;" ) +#define STEAM_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) STEAM_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) +#define STEAM_OUT_ARRAY_COUNT(COUNTER, DESC) STEAM_CLANG_ATTR( "out_array_count:" #COUNTER ";desc:" #DESC ) +#define STEAM_ARRAY_COUNT(COUNTER) STEAM_CLANG_ATTR( "array_count:" #COUNTER ";" ) +#define STEAM_ARRAY_COUNT_D(COUNTER, DESC) STEAM_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) +#define STEAM_BUFFER_COUNT(COUNTER) STEAM_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) +#define STEAM_OUT_BUFFER_COUNT(COUNTER) STEAM_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) +#define STEAM_OUT_STRING_COUNT(COUNTER) STEAM_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define STEAM_DESC(DESC) STEAM_CLANG_ATTR("desc:" #DESC ";") +#define STEAM_CALL_RESULT(RESULT_TYPE) STEAM_CLANG_ATTR("callresult:" #RESULT_TYPE ";") +#define STEAM_CALL_BACK(RESULT_TYPE) STEAM_CLANG_ATTR("callback:" #RESULT_TYPE ";") +#define STEAM_FLAT_NAME(NAME) STEAM_CLANG_ATTR("flat_name:" #NAME ";") + +// CSteamAPIContext encapsulates the Steamworks API global accessors into +// a single object. +// +// DEPRECATED: Used the global interface accessors instead! +// +// This will be removed in a future iteration of the SDK +class CSteamAPIContext +{ +public: + CSteamAPIContext() { Clear(); } + inline void Clear() { memset( this, 0, sizeof(*this) ); } + inline bool Init(); // NOTE: This is defined in steam_api.h, to avoid this file having to include everything + ISteamClient* SteamClient() const { return m_pSteamClient; } + ISteamUser* SteamUser() const { return m_pSteamUser; } + ISteamFriends* SteamFriends() const { return m_pSteamFriends; } + ISteamUtils* SteamUtils() const { return m_pSteamUtils; } + ISteamMatchmaking* SteamMatchmaking() const { return m_pSteamMatchmaking; } + ISteamGameSearch* SteamGameSearch() const { return m_pSteamGameSearch; } + ISteamUserStats* SteamUserStats() const { return m_pSteamUserStats; } + ISteamApps* SteamApps() const { return m_pSteamApps; } + ISteamMatchmakingServers* SteamMatchmakingServers() const { return m_pSteamMatchmakingServers; } + ISteamNetworking* SteamNetworking() const { return m_pSteamNetworking; } + ISteamRemoteStorage* SteamRemoteStorage() const { return m_pSteamRemoteStorage; } + ISteamScreenshots* SteamScreenshots() const { return m_pSteamScreenshots; } + ISteamHTTP* SteamHTTP() const { return m_pSteamHTTP; } + ISteamController* SteamController() const { return m_pController; } + ISteamUGC* SteamUGC() const { return m_pSteamUGC; } + ISteamAppList* SteamAppList() const { return m_pSteamAppList; } + ISteamMusic* SteamMusic() const { return m_pSteamMusic; } + ISteamMusicRemote* SteamMusicRemote() const { return m_pSteamMusicRemote; } + ISteamHTMLSurface* SteamHTMLSurface() const { return m_pSteamHTMLSurface; } + ISteamInventory* SteamInventory() const { return m_pSteamInventory; } + ISteamVideo* SteamVideo() const { return m_pSteamVideo; } + ISteamParentalSettings* SteamParentalSettings() const { return m_pSteamParentalSettings; } + ISteamInput* SteamInput() const { return m_pSteamInput; } +private: + ISteamClient *m_pSteamClient; + ISteamUser *m_pSteamUser; + ISteamFriends *m_pSteamFriends; + ISteamUtils *m_pSteamUtils; + ISteamMatchmaking *m_pSteamMatchmaking; + ISteamGameSearch *m_pSteamGameSearch; + ISteamUserStats *m_pSteamUserStats; + ISteamApps *m_pSteamApps; + ISteamMatchmakingServers *m_pSteamMatchmakingServers; + ISteamNetworking *m_pSteamNetworking; + ISteamRemoteStorage *m_pSteamRemoteStorage; + ISteamScreenshots *m_pSteamScreenshots; + ISteamHTTP *m_pSteamHTTP; + ISteamController *m_pController; + ISteamUGC *m_pSteamUGC; + ISteamAppList *m_pSteamAppList; + ISteamMusic *m_pSteamMusic; + ISteamMusicRemote *m_pSteamMusicRemote; + ISteamHTMLSurface *m_pSteamHTMLSurface; + ISteamInventory *m_pSteamInventory; + ISteamVideo *m_pSteamVideo; + ISteamParentalSettings *m_pSteamParentalSettings; + ISteamInput *m_pSteamInput; +}; + +class CSteamGameServerAPIContext +{ +public: + CSteamGameServerAPIContext() { Clear(); } + inline void Clear() { memset( this, 0, sizeof(*this) ); } + inline bool Init(); // NOTE: This is defined in steam_gameserver.h, to avoid this file having to include everything + + ISteamClient *SteamClient() const { return m_pSteamClient; } + ISteamGameServer *SteamGameServer() const { return m_pSteamGameServer; } + ISteamUtils *SteamGameServerUtils() const { return m_pSteamGameServerUtils; } + ISteamNetworking *SteamGameServerNetworking() const { return m_pSteamGameServerNetworking; } + ISteamGameServerStats *SteamGameServerStats() const { return m_pSteamGameServerStats; } + ISteamHTTP *SteamHTTP() const { return m_pSteamHTTP; } + ISteamInventory *SteamInventory() const { return m_pSteamInventory; } + ISteamUGC *SteamUGC() const { return m_pSteamUGC; } + +private: + ISteamClient *m_pSteamClient; + ISteamGameServer *m_pSteamGameServer; + ISteamUtils *m_pSteamGameServerUtils; + ISteamNetworking *m_pSteamGameServerNetworking; + ISteamGameServerStats *m_pSteamGameServerStats; + ISteamHTTP *m_pSteamHTTP; + ISteamInventory *m_pSteamInventory; + ISteamUGC *m_pSteamUGC; +}; + + diff --git a/public/steam/steam_gameserver.h b/public/steam/steam_gameserver.h index 6b67da1d..28a436f5 100644 --- a/public/steam/steam_gameserver.h +++ b/public/steam/steam_gameserver.h @@ -22,162 +22,96 @@ enum EServerMode eServerModeAuthenticationAndSecure = 3, // Authenticate users, list on the server list and VAC protect clients }; -// Initialize ISteamGameServer interface object, and set server properties which may not be changed. +/// Pass to SteamGameServer_Init to indicate that the same UDP port will be used for game traffic +/// UDP queries for server browser pings and LAN discovery. In this case, Steam will not open up a +/// socket to handle server browser queries, and you must use ISteamGameServer::HandleIncomingPacket +/// and ISteamGameServer::GetNextOutgoingPacket to handle packets related to server discovery on your socket. +const uint16 STEAMGAMESERVER_QUERY_PORT_SHARED = 0xffff; + +// DEPRECATED: This old name was really confusing. +const uint16 MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE = STEAMGAMESERVER_QUERY_PORT_SHARED; + +// Initialize SteamGameServer client and interface objects, and set server properties which may not be changed. // // After calling this function, you should set any additional server parameters, and then // call ISteamGameServer::LogOnAnonymous() or ISteamGameServer::LogOn() // -// - usSteamPort is the local port used to communicate with the steam servers. -// - usGamePort is the port that clients will connect to for gameplay. +// - unIP will usually be zero. If you are on a machine with multiple IP addresses, you can pass a non-zero +// value here and the relevant sockets will be bound to that IP. This can be used to ensure that +// the IP you desire is the one used in the server browser. +// - usGamePort is the port that clients will connect to for gameplay. You will usually open up your +// own socket bound to this port. // - usQueryPort is the port that will manage server browser related duties and info -// pings from clients. If you pass MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE for usQueryPort, then it +// pings from clients. If you pass STEAMGAMESERVER_QUERY_PORT_SHARED for usQueryPort, then it // will use "GameSocketShare" mode, which means that the game is responsible for sending and receiving -// UDP packets for the master server updater. See references to GameSocketShare in isteamgameserver.h. -// - The version string is usually in the form x.x.x.x, and is used by the master server to detect when the +// UDP packets for the master server updater. (See ISteamGameServer::HandleIncomingPacket and +// ISteamGameServer::GetNextOutgoingPacket.) +// - The version string should be in the form x.x.x.x, and is used by the master server to detect when the // server is out of date. (Only servers with the latest version will be listed.) -#ifndef _PS3 - -#ifdef VERSION_SAFE_STEAM_API_INTERFACES -S_API bool SteamGameServer_InitSafe( uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); -#else -S_API bool SteamGameServer_Init( uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); -#endif - -#else - -#ifdef VERSION_SAFE_STEAM_API_INTERFACES -S_API bool SteamGameServer_InitSafe( const SteamPS3Params_t *ps3Params, uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); -#else -S_API bool SteamGameServer_Init( const SteamPS3Params_t *ps3Params, uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); -#endif - -#endif - -#ifndef VERSION_SAFE_STEAM_API_INTERFACES -S_API ISteamGameServer *SteamGameServer(); -S_API ISteamUtils *SteamGameServerUtils(); -S_API ISteamNetworking *SteamGameServerNetworking(); -S_API ISteamGameServerStats *SteamGameServerStats(); -S_API ISteamHTTP *SteamGameServerHTTP(); -S_API ISteamUGC *SteamGameServerUGC(); -#endif +inline bool SteamGameServer_Init( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); +// Shutdown SteamGameSeverXxx interfaces, log out, and free resources. S_API void SteamGameServer_Shutdown(); -S_API void SteamGameServer_RunCallbacks(); + +// Most Steam API functions allocate some amount of thread-local memory for +// parameter storage. Calling SteamGameServer_ReleaseCurrentThreadMemory() +// will free all API-related memory associated with the calling thread. +// This memory is released automatically by SteamGameServer_RunCallbacks(), +// so single-threaded servers do not need to explicitly call this function. +inline void SteamGameServer_ReleaseCurrentThreadMemory(); S_API bool SteamGameServer_BSecure(); S_API uint64 SteamGameServer_GetSteamID(); +// Older SDKs exported this global pointer, but it is no longer supported. +// You should use SteamGameServerClient() or CSteamGameServerAPIContext to +// safely access the ISteamClient APIs from your game server application. +//S_API ISteamClient *g_pSteamClientGameServer; -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -// These macros are similar to the STEAM_CALLBACK_* macros in steam_api.h, but only trigger for gameserver callbacks -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -#define STEAM_GAMESERVER_CALLBACK( thisclass, func, /*callback_type, [deprecated] var*/... ) \ - _STEAM_CALLBACK_SELECT( ( __VA_ARGS__, GS, 3 ), ( this->SetGameserverFlag();, thisclass, func, __VA_ARGS__ ) ) - -#define STEAM_GAMESERVER_CALLBACK_MANUAL( thisclass, func, callback_type, var ) \ - CCallbackManual< thisclass, callback_type, true > var; void func( callback_type *pParam ) - - - -#define _STEAM_CALLBACK_GS( _, thisclass, func, param, var ) \ - CCallback< thisclass, param, true > var; void func( param *pParam ) +// SteamGameServer_InitSafe has been replaced with SteamGameServer_Init and +// is no longer supported. Use SteamGameServer_Init instead. +//S_API void S_CALLTYPE SteamGameServer_InitSafe(); -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -// steamclient.dll private wrapper functions +//============================================================================= // -// The following functions are part of abstracting API access to the steamclient.dll, but should only be used in very specific cases -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -S_API HSteamPipe SteamGameServer_GetHSteamPipe(); - -#ifdef VERSION_SAFE_STEAM_API_INTERFACES -//----------------------------------------------------------------------------------------------------------------------------------------------------------// -// VERSION_SAFE_STEAM_API_INTERFACES uses CSteamAPIContext to provide interfaces to each module in a way that -// lets them each specify the interface versions they are compiled with. +// Internal implementation details below // -// It's important that these stay inlined in the header so the calling module specifies the interface versions -// for whatever Steam API version it has. -//----------------------------------------------------------------------------------------------------------------------------------------------------------// - -S_API HSteamUser SteamGameServer_GetHSteamUser(); - -class CSteamGameServerAPIContext -{ -public: - CSteamGameServerAPIContext(); - void Clear(); - - bool Init(); - - ISteamGameServer *SteamGameServer() { return m_pSteamGameServer; } - ISteamUtils *SteamGameServerUtils() { return m_pSteamGameServerUtils; } - ISteamNetworking *SteamGameServerNetworking() { return m_pSteamGameServerNetworking; } - ISteamGameServerStats *SteamGameServerStats() { return m_pSteamGameServerStats; } - ISteamHTTP *SteamHTTP() { return m_pSteamHTTP; } - ISteamUGC *SteamUGC() { return m_pSteamUGC; } - -private: - ISteamGameServer *m_pSteamGameServer; - ISteamUtils *m_pSteamGameServerUtils; - ISteamNetworking *m_pSteamGameServerNetworking; - ISteamGameServerStats *m_pSteamGameServerStats; - ISteamHTTP *m_pSteamHTTP; - ISteamUGC *m_pSteamUGC; -}; - -inline CSteamGameServerAPIContext::CSteamGameServerAPIContext() -{ - Clear(); -} - -inline void CSteamGameServerAPIContext::Clear() -{ - m_pSteamGameServer = NULL; - m_pSteamGameServerUtils = NULL; - m_pSteamGameServerNetworking = NULL; - m_pSteamGameServerStats = NULL; - m_pSteamHTTP = NULL; - m_pSteamUGC = NULL; -} +//============================================================================= -S_API ISteamClient *g_pSteamClientGameServer; -// This function must be inlined so the module using steam_api.dll gets the version names they want. +#ifndef STEAM_API_EXPORTS +// This function must be declared inline in the header so the module using steam_api.dll gets the version names they want. inline bool CSteamGameServerAPIContext::Init() { - if ( !g_pSteamClientGameServer ) + m_pSteamClient = ::SteamGameServerClient(); + if ( !m_pSteamClient ) return false; - HSteamUser hSteamUser = SteamGameServer_GetHSteamUser(); - HSteamPipe hSteamPipe = SteamGameServer_GetHSteamPipe(); - - m_pSteamGameServer = g_pSteamClientGameServer->GetISteamGameServer( hSteamUser, hSteamPipe, STEAMGAMESERVER_INTERFACE_VERSION ); - if ( !m_pSteamGameServer ) + m_pSteamGameServer = ::SteamGameServer(); + m_pSteamGameServerUtils = ::SteamGameServerUtils(); + m_pSteamGameServerNetworking = ::SteamGameServerNetworking(); + m_pSteamGameServerStats = ::SteamGameServerStats(); + m_pSteamHTTP = ::SteamGameServerHTTP(); + m_pSteamInventory = ::SteamGameServerInventory(); + m_pSteamUGC = ::SteamGameServerUGC(); + if ( !m_pSteamGameServer || !m_pSteamGameServerUtils || !m_pSteamGameServerNetworking || !m_pSteamGameServerStats + || !m_pSteamHTTP || !m_pSteamInventory || !m_pSteamUGC ) return false; - m_pSteamGameServerUtils = g_pSteamClientGameServer->GetISteamUtils( hSteamPipe, STEAMUTILS_INTERFACE_VERSION ); - if ( !m_pSteamGameServerUtils ) - return false; - - m_pSteamGameServerNetworking = g_pSteamClientGameServer->GetISteamNetworking( hSteamUser, hSteamPipe, STEAMNETWORKING_INTERFACE_VERSION ); - if ( !m_pSteamGameServerNetworking ) - return false; - - m_pSteamGameServerStats = g_pSteamClientGameServer->GetISteamGameServerStats( hSteamUser, hSteamPipe, STEAMGAMESERVERSTATS_INTERFACE_VERSION ); - if ( !m_pSteamGameServerStats ) - return false; - - m_pSteamHTTP = g_pSteamClientGameServer->GetISteamHTTP( hSteamUser, hSteamPipe, STEAMHTTP_INTERFACE_VERSION ); - if ( !m_pSteamHTTP ) - return false; + return true; +} +#endif - m_pSteamUGC = g_pSteamClientGameServer->GetISteamUGC( hSteamUser, hSteamPipe, STEAMUGC_INTERFACE_VERSION ); - if ( !m_pSteamUGC ) +S_API bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usLegacySteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); +inline bool SteamGameServer_Init( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ) +{ + if ( !SteamInternal_GameServer_Init( unIP, 0, usGamePort, usQueryPort, eServerMode, pchVersionString ) ) return false; return true; } - -#endif // VERSION_SAFE_STEAM_API_INTERFACES - +inline void SteamGameServer_ReleaseCurrentThreadMemory() +{ + SteamAPI_ReleaseCurrentThreadMemory(); +} #endif // STEAM_GAMESERVER_H diff --git a/public/steam/steamclientpublic.h b/public/steam/steamclientpublic.h index 4e952dc7..1521e333 100644 --- a/public/steam/steamclientpublic.h +++ b/public/steam/steamclientpublic.h @@ -1,23 +1,11 @@ //========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============ // -// Purpose: +// Declare common types used by the Steamworks SDK. // //============================================================================= #ifndef STEAMCLIENTPUBLIC_H #define STEAMCLIENTPUBLIC_H -#ifdef _WIN32 -#pragma once -#endif -//lint -save -e1931 -e1927 -e1924 -e613 -e726 - -// This header file defines the interface between the calling application and the code that -// knows how to communicate with the connection manager (CM) from the Steam service - -// This header file is intended to be portable; ideally this 1 header file plus a lib or dll -// is all you need to integrate the client library into some other tree. So please avoid -// including or requiring other header files if possible. This header should only describe the -// interface layer, no need to include anything about the implementation. #include "steamtypes.h" #include "steamuniverse.h" @@ -25,6 +13,7 @@ // General result codes enum EResult { + k_EResultNone = 0, // no result k_EResultOK = 1, // success k_EResultFail = 2, // generic failure k_EResultNoConnection = 3, // no/failed network connection @@ -125,6 +114,33 @@ enum EResult k_EResultRefundToWallet = 98, // Cannot refund to payment method, must use wallet k_EResultEmailSendFailure = 99, // Cannot send an email k_EResultNotSettled = 100, // Can't perform operation till payment has settled + k_EResultNeedCaptcha = 101, // Needs to provide a valid captcha + k_EResultGSLTDenied = 102, // a game server login token owned by this token's owner has been banned + k_EResultGSOwnerDenied = 103, // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone) + k_EResultInvalidItemType = 104, // the type of thing we were requested to act on is invalid + k_EResultIPBanned = 105, // the ip address has been banned from taking this action + k_EResultGSLTExpired = 106, // this token has expired from disuse; can be reset for use + k_EResultInsufficientFunds = 107, // user doesn't have enough wallet funds to complete the action + k_EResultTooManyPending = 108, // There are too many of this thing pending already + k_EResultNoSiteLicensesFound = 109, // No site licenses found + k_EResultWGNetworkSendExceeded = 110, // the WG couldn't send a response because we exceeded max network send size + k_EResultAccountNotFriends = 111, // the user is not mutually friends + k_EResultLimitedUserAccount = 112, // the user is limited + k_EResultCantRemoveItem = 113, // item can't be removed + k_EResultAccountDeleted = 114, // account has been deleted + k_EResultExistingUserCancelledLicense = 115, // A license for this already exists, but cancelled + k_EResultCommunityCooldown = 116, // access is denied because of a community cooldown (probably from support profile data resets) + k_EResultNoLauncherSpecified = 117, // No launcher was specified, but a launcher was needed to choose correct realm for operation. + k_EResultMustAgreeToSSA = 118, // User must agree to china SSA or global SSA before login + k_EResultLauncherMigrated = 119, // The specified launcher type is no longer supported; the user should be directed elsewhere + k_EResultSteamRealmMismatch = 120, // The user's realm does not match the realm of the requested resource + k_EResultInvalidSignature = 121, // signature check did not match + k_EResultParseFailure = 122, // Failed to parse input + k_EResultNoVerifiedPhone = 123, // account does not have a verified phone number + k_EResultInsufficientBattery = 124, // user device doesn't have enough battery charge currently to complete the action + k_EResultChargerRequired = 125, // The operation requires a charger to be plugged in, which wasn't present + k_EResultCachedCredentialInvalid = 126, // Cached credential was invalid - user must reauthenticate + K_EResultPhoneNumberIsVOIP = 127, // The phone number provided is a Voice Over IP number }; // Error codes for use with the voice functions @@ -224,89 +240,6 @@ enum EAccountType -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -enum EAppReleaseState -{ - k_EAppReleaseState_Unknown = 0, // unknown, required appinfo or license info is missing - k_EAppReleaseState_Unavailable = 1, // even if user 'just' owns it, can see game at all - k_EAppReleaseState_Prerelease = 2, // can be purchased and is visible in games list, nothing else. Common appInfo section released - k_EAppReleaseState_PreloadOnly = 3, // owners can preload app, not play it. AppInfo fully released. - k_EAppReleaseState_Released = 4, // owners can download and play app. -}; - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -enum EAppOwnershipFlags -{ - k_EAppOwnershipFlags_None = 0x0000, // unknown - k_EAppOwnershipFlags_OwnsLicense = 0x0001, // owns license for this game - k_EAppOwnershipFlags_FreeLicense = 0x0002, // not paid for game - k_EAppOwnershipFlags_RegionRestricted = 0x0004, // owns app, but not allowed to play in current region - k_EAppOwnershipFlags_LowViolence = 0x0008, // only low violence version - k_EAppOwnershipFlags_InvalidPlatform = 0x0010, // app not supported on current platform - k_EAppOwnershipFlags_SharedLicense = 0x0020, // license was granted by authorized local device - k_EAppOwnershipFlags_FreeWeekend = 0x0040, // owned by a free weekend licenses - k_EAppOwnershipFlags_RetailLicense = 0x0080, // has a retail license for game, (CD-Key etc) - k_EAppOwnershipFlags_LicenseLocked = 0x0100, // shared license is locked (in use) by other user - k_EAppOwnershipFlags_LicensePending = 0x0200, // owns app, but transaction is still pending. Can't install or play - k_EAppOwnershipFlags_LicenseExpired = 0x0400, // doesn't own app anymore since license expired - k_EAppOwnershipFlags_LicensePermanent = 0x0800, // permanent license, not borrowed, or guest or freeweekend etc - k_EAppOwnershipFlags_LicenseRecurring = 0x1000, // Recurring license, user is charged periodically - k_EAppOwnershipFlags_LicenseCanceled = 0x2000, // Mark as canceled, but might be still active if recurring - k_EAppOwnershipFlags_AutoGrant = 0x4000, // Ownership is based on any kind of autogrant license -}; - - -//----------------------------------------------------------------------------- -// Purpose: designed as flags to allow filters masks -//----------------------------------------------------------------------------- -enum EAppType -{ - k_EAppType_Invalid = 0x000, // unknown / invalid - k_EAppType_Game = 0x001, // playable game, default type - k_EAppType_Application = 0x002, // software application - k_EAppType_Tool = 0x004, // SDKs, editors & dedicated servers - k_EAppType_Demo = 0x008, // game demo - k_EAppType_Media_DEPRECATED = 0x010, // legacy - was used for game trailers, which are now just videos on the web - k_EAppType_DLC = 0x020, // down loadable content - k_EAppType_Guide = 0x040, // game guide, PDF etc - k_EAppType_Driver = 0x080, // hardware driver updater (ATI, Razor etc) - k_EAppType_Config = 0x100, // hidden app used to config Steam features (backpack, sales, etc) - k_EAppType_Hardware = 0x200, // a hardware device (Steam Machine, Steam Controller, Steam Link, etc.) - // 0x400 is up for grabs here - k_EAppType_Video = 0x800, // A video component of either a Film or TVSeries (may be the feature, an episode, preview, making-of, etc) - k_EAppType_Plugin = 0x1000, // Plug-in types for other Apps - k_EAppType_Music = 0x2000, // Music files - - k_EAppType_Shortcut = 0x40000000, // just a shortcut, client side only - k_EAppType_DepotOnly = 0x80000000, // placeholder since depots and apps share the same namespace -}; - - - -//----------------------------------------------------------------------------- -// types of user game stats fields -// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN DATABASE -//----------------------------------------------------------------------------- -enum ESteamUserStatType -{ - k_ESteamUserStatTypeINVALID = 0, - k_ESteamUserStatTypeINT = 1, - k_ESteamUserStatTypeFLOAT = 2, - // Read as FLOAT, set with count / session length - k_ESteamUserStatTypeAVGRATE = 3, - k_ESteamUserStatTypeACHIEVEMENTS = 4, - k_ESteamUserStatTypeGROUPACHIEVEMENTS = 5, - - // max, for sanity checks - k_ESteamUserStatTypeMAX -}; - - //----------------------------------------------------------------------------- // Purpose: Chat Entry Types (previously was only friend-to-friend message types) //----------------------------------------------------------------------------- @@ -325,8 +258,8 @@ enum EChatEntryType k_EChatEntryTypeWasBanned = 9, // user was banned (data: 64-bit steamid of actor performing the ban) k_EChatEntryTypeDisconnected = 10, // user disconnected k_EChatEntryTypeHistoricalChat = 11, // a chat message from user's chat history or offilne message - k_EChatEntryTypeReserved1 = 12, - k_EChatEntryTypeReserved2 = 13, + //k_EChatEntryTypeReserved1 = 12, // No longer used + //k_EChatEntryTypeReserved2 = 13, // No longer used k_EChatEntryTypeLinkBlocked = 14, // a link was removed by the chat filter. }; @@ -350,18 +283,13 @@ enum EChatRoomEnterResponse // k_EChatRoomEnterResponseNoRankingDataLobby = 12, // No longer used // k_EChatRoomEnterResponseNoRankingDataUser = 13, // No longer used // k_EChatRoomEnterResponseRankOutOfRange = 14, // No longer used + k_EChatRoomEnterResponseRatelimitExceeded = 15, // Join failed - to many join attempts in a very short period of time }; -typedef void (*PFNLegacyKeyRegistration)( const char *pchCDKey, const char *pchInstallPath ); -typedef bool (*PFNLegacyKeyInstalled)(); - const unsigned int k_unSteamAccountIDMask = 0xFFFFFFFF; const unsigned int k_unSteamAccountInstanceMask = 0x000FFFFF; -// we allow 3 simultaneous user account instances right now, 1= desktop, 2 = console, 4 = web, 0 = all -const unsigned int k_unSteamUserDesktopInstance = 1; -const unsigned int k_unSteamUserConsoleInstance = 2; -const unsigned int k_unSteamUserWebInstance = 4; +const unsigned int k_unSteamUserDefaultInstance = 1; // fixed instance for all individual users // Special flags for Chat accounts - they go in the top 8 bits // of the steam ID's "instance", leaving 12 for the actual instances @@ -377,26 +305,6 @@ enum EChatSteamIDInstanceFlags }; -//----------------------------------------------------------------------------- -// Purpose: Marketing message flags that change how a client should handle them -//----------------------------------------------------------------------------- -enum EMarketingMessageFlags -{ - k_EMarketingMessageFlagsNone = 0, - k_EMarketingMessageFlagsHighPriority = 1 << 0, - k_EMarketingMessageFlagsPlatformWindows = 1 << 1, - k_EMarketingMessageFlagsPlatformMac = 1 << 2, - k_EMarketingMessageFlagsPlatformLinux = 1 << 3, - - //aggregate flags - k_EMarketingMessageFlagsPlatformRestrictions = - k_EMarketingMessageFlagsPlatformWindows | - k_EMarketingMessageFlagsPlatformMac | - k_EMarketingMessageFlagsPlatformLinux, -}; - - - //----------------------------------------------------------------------------- // Purpose: Possible positions to tell the overlay to show notifications in //----------------------------------------------------------------------------- @@ -427,10 +335,129 @@ enum EBroadcastUploadResult k_EBroadcastUploadResultSettingsChanged = 10, // the client changed broadcast settings k_EBroadcastUploadResultMissingAudio = 11, // client failed to send audio data k_EBroadcastUploadResultTooFarBehind = 12, // clients was too slow uploading + k_EBroadcastUploadResultTranscodeBehind = 13, // server failed to keep up with transcode + k_EBroadcastUploadResultNotAllowedToPlay = 14, // Broadcast does not have permissions to play game + k_EBroadcastUploadResultBusy = 15, // RTMP host to busy to take new broadcast stream, choose another + k_EBroadcastUploadResultBanned = 16, // Account banned from community broadcast + k_EBroadcastUploadResultAlreadyActive = 17, // We already already have an stream running. + k_EBroadcastUploadResultForcedOff = 18, // We explicitly shutting down a broadcast + k_EBroadcastUploadResultAudioBehind = 19, // Audio stream was too far behind video + k_EBroadcastUploadResultShutdown = 20, // Broadcast Server was shut down + k_EBroadcastUploadResultDisconnect = 21, // broadcast uploader TCP disconnected + k_EBroadcastUploadResultVideoInitFailed = 22, // invalid video settings + k_EBroadcastUploadResultAudioInitFailed = 23, // invalid audio settings +}; + + +//----------------------------------------------------------------------------- +// Purpose: Reasons a user may not use the Community Market. +// Used in MarketEligibilityResponse_t. +//----------------------------------------------------------------------------- +enum EMarketNotAllowedReasonFlags +{ + k_EMarketNotAllowedReason_None = 0, + + // A back-end call failed or something that might work again on retry + k_EMarketNotAllowedReason_TemporaryFailure = (1 << 0), + + // Disabled account + k_EMarketNotAllowedReason_AccountDisabled = (1 << 1), + + // Locked account + k_EMarketNotAllowedReason_AccountLockedDown = (1 << 2), + + // Limited account (no purchases) + k_EMarketNotAllowedReason_AccountLimited = (1 << 3), + + // The account is banned from trading items + k_EMarketNotAllowedReason_TradeBanned = (1 << 4), + + // Wallet funds aren't tradable because the user has had no purchase + // activity in the last year or has had no purchases prior to last month + k_EMarketNotAllowedReason_AccountNotTrusted = (1 << 5), + + // The user doesn't have Steam Guard enabled + k_EMarketNotAllowedReason_SteamGuardNotEnabled = (1 << 6), + + // The user has Steam Guard, but it hasn't been enabled for the required + // number of days + k_EMarketNotAllowedReason_SteamGuardOnlyRecentlyEnabled = (1 << 7), + + // The user has recently forgotten their password and reset it + k_EMarketNotAllowedReason_RecentPasswordReset = (1 << 8), + + // The user has recently funded his or her wallet with a new payment method + k_EMarketNotAllowedReason_NewPaymentMethod = (1 << 9), + + // An invalid cookie was sent by the user + k_EMarketNotAllowedReason_InvalidCookie = (1 << 10), + + // The user has Steam Guard, but is using a new computer or web browser + k_EMarketNotAllowedReason_UsingNewDevice = (1 << 11), + + // The user has recently refunded a store purchase by his or herself + k_EMarketNotAllowedReason_RecentSelfRefund = (1 << 12), + + // The user has recently funded his or her wallet with a new payment method that cannot be verified + k_EMarketNotAllowedReason_NewPaymentMethodCannotBeVerified = (1 << 13), + + // Not only is the account not trusted, but they have no recent purchases at all + k_EMarketNotAllowedReason_NoRecentPurchases = (1 << 14), + + // User accepted a wallet gift that was recently purchased + k_EMarketNotAllowedReason_AcceptedWalletGift = (1 << 15), +}; + + +// +// describes XP / progress restrictions to apply for games with duration control / +// anti-indulgence enabled for minor Steam China users. +// +// WARNING: DO NOT RENUMBER +enum EDurationControlProgress +{ + k_EDurationControlProgress_Full = 0, // Full progress + k_EDurationControlProgress_Half = 1, // deprecated - XP or persistent rewards should be halved + k_EDurationControlProgress_None = 2, // deprecated - XP or persistent rewards should be stopped + + k_EDurationControl_ExitSoon_3h = 3, // allowed 3h time since 5h gap/break has elapsed, game should exit - steam will terminate the game soon + k_EDurationControl_ExitSoon_5h = 4, // allowed 5h time in calendar day has elapsed, game should exit - steam will terminate the game soon + k_EDurationControl_ExitSoon_Night = 5, // game running after day period, game should exit - steam will terminate the game soon }; -#pragma pack( push, 1 ) +// +// describes which notification timer has expired, for steam china duration control feature +// +// WARNING: DO NOT RENUMBER +enum EDurationControlNotification +{ + k_EDurationControlNotification_None = 0, // just informing you about progress, no notification to show + k_EDurationControlNotification_1Hour = 1, // "you've been playing for N hours" + + k_EDurationControlNotification_3Hours = 2, // deprecated - "you've been playing for 3 hours; take a break" + k_EDurationControlNotification_HalfProgress = 3,// deprecated - "your XP / progress is half normal" + k_EDurationControlNotification_NoProgress = 4, // deprecated - "your XP / progress is zero" + + k_EDurationControlNotification_ExitSoon_3h = 5, // allowed 3h time since 5h gap/break has elapsed, game should exit - steam will terminate the game soon + k_EDurationControlNotification_ExitSoon_5h = 6, // allowed 5h time in calendar day has elapsed, game should exit - steam will terminate the game soon + k_EDurationControlNotification_ExitSoon_Night = 7,// game running after day period, game should exit - steam will terminate the game soon +}; + + +// +// Specifies a game's online state in relation to duration control +// +enum EDurationControlOnlineState +{ + k_EDurationControlOnlineState_Invalid = 0, // nil value + k_EDurationControlOnlineState_Offline = 1, // currently in offline play - single-player, offline co-op, etc. + k_EDurationControlOnlineState_Online = 2, // currently in online play + k_EDurationControlOnlineState_OnlineHighPri = 3, // currently in online play and requests not to be interrupted +}; + + +#pragma pack( push, 1 ) #define CSTEAMID_DEFINED @@ -473,7 +500,7 @@ class CSteamID CSteamID( uint32 unAccountID, unsigned int unAccountInstance, EUniverse eUniverse, EAccountType eAccountType ) { #if defined(_SERVER) && defined(Assert) - Assert( ! ( ( k_EAccountTypeIndividual == eAccountType ) && ( unAccountInstance > k_unSteamUserWebInstance ) ) ); // enforce that for individual accounts, instance is always 1 + Assert( ( k_EAccountTypeIndividual != eAccountType ) || ( unAccountInstance == k_unSteamUserDefaultInstance ) ); // enforce that for individual accounts, instance is always 1 #endif // _SERVER InstancedSet( unAccountID, unAccountInstance, eUniverse, eAccountType ); } @@ -515,8 +542,7 @@ class CSteamID } else { - // by default we pick the desktop instance - m_steamid.m_comp.m_unAccountInstance = k_unSteamUserDesktopInstance; + m_steamid.m_comp.m_unAccountInstance = k_unSteamUserDefaultInstance; } } @@ -570,37 +596,6 @@ class CSteamID m_steamid.m_comp.m_unAccountInstance = 0; } - -#if defined( INCLUDED_STEAM2_USERID_STRUCTS ) - //----------------------------------------------------------------------------- - // Purpose: Initializes a steam ID from a Steam2 ID structure - // Input: pTSteamGlobalUserID - Steam2 ID to convert - // eUniverse - universe this ID belongs to - //----------------------------------------------------------------------------- - void SetFromSteam2( TSteamGlobalUserID *pTSteamGlobalUserID, EUniverse eUniverse ) - { - m_steamid.m_comp.m_unAccountID = pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits * 2 + - pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits; - m_steamid.m_comp.m_EUniverse = eUniverse; // set the universe - m_steamid.m_comp.m_EAccountType = k_EAccountTypeIndividual; // Steam 2 accounts always map to account type of individual - m_steamid.m_comp.m_unAccountInstance = k_unSteamUserDesktopInstance; // Steam2 only knew desktop instances - } - - //----------------------------------------------------------------------------- - // Purpose: Fills out a Steam2 ID structure - // Input: pTSteamGlobalUserID - Steam2 ID to write to - //----------------------------------------------------------------------------- - void ConvertToSteam2( TSteamGlobalUserID *pTSteamGlobalUserID ) const - { - // only individual accounts have any meaning in Steam 2, only they can be mapped - // Assert( m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual ); - - pTSteamGlobalUserID->m_SteamInstanceID = 0; - pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits = m_steamid.m_comp.m_unAccountID % 2; - pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits = m_steamid.m_comp.m_unAccountID / 2; - } -#endif // defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H ) - //----------------------------------------------------------------------------- // Purpose: Converts steam ID to its 64-bit representation // Output : 64-bit representation of a Steam ID @@ -752,8 +747,7 @@ class CSteamID // simple accessors void SetAccountID( uint32 unAccountID ) { m_steamid.m_comp.m_unAccountID = unAccountID; } void SetAccountInstance( uint32 unInstance ){ m_steamid.m_comp.m_unAccountInstance = unInstance; } - void ClearIndividualInstance() { if ( BIndividualAccount() ) m_steamid.m_comp.m_unAccountInstance = 0; } - bool HasNoIndividualInstance() const { return BIndividualAccount() && (m_steamid.m_comp.m_unAccountInstance==0); } + AccountID_t GetAccountID() const { return m_steamid.m_comp.m_unAccountID; } uint32 GetUnAccountInstance() const { return m_steamid.m_comp.m_unAccountInstance; } EAccountType GetEAccountType() const { return ( EAccountType ) m_steamid.m_comp.m_EAccountType; } @@ -773,7 +767,6 @@ class CSteamID // and is preferred when the caller knows it's safe to be strict. // Returns whether the string parsed correctly. bool SetFromStringStrict( const char *pchSteamID, EUniverse eDefaultUniverse ); - bool SetFromSteam2String( const char *pchSteam2ID, EUniverse eUniverse ); inline bool operator==( const CSteamID &val ) const { return m_steamid.m_unAll64Bits == val.m_steamid.m_unAll64Bits; } inline bool operator!=( const CSteamID &val ) const { return !operator==( val ); } @@ -823,7 +816,7 @@ inline bool CSteamID::IsValid() const if ( m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual ) { - if ( m_steamid.m_comp.m_unAccountID == 0 || m_steamid.m_comp.m_unAccountInstance > k_unSteamUserWebInstance ) + if ( m_steamid.m_comp.m_unAccountID == 0 || m_steamid.m_comp.m_unAccountInstance != k_unSteamUserDefaultInstance ) return false; } @@ -842,6 +835,41 @@ inline bool CSteamID::IsValid() const return true; } +#if defined( INCLUDED_STEAM2_USERID_STRUCTS ) + +//----------------------------------------------------------------------------- +// Purpose: Initializes a steam ID from a Steam2 ID structure +// Input: pTSteamGlobalUserID - Steam2 ID to convert +// eUniverse - universe this ID belongs to +//----------------------------------------------------------------------------- +inline CSteamID SteamIDFromSteam2UserID( TSteamGlobalUserID *pTSteamGlobalUserID, EUniverse eUniverse ) +{ + uint32 unAccountID = pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits * 2 + + pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits; + + return CSteamID( unAccountID, k_unSteamUserDefaultInstance, eUniverse, k_EAccountTypeIndividual ); +} + +bool SteamIDFromSteam2String( const char *pchSteam2ID, EUniverse eUniverse, CSteamID *pSteamIDOut ); + +//----------------------------------------------------------------------------- +// Purpose: Fills out a Steam2 ID structure +// Input: pTSteamGlobalUserID - Steam2 ID to write to +//----------------------------------------------------------------------------- +inline TSteamGlobalUserID SteamIDToSteam2UserID( CSteamID steamID ) +{ + TSteamGlobalUserID steamGlobalUserID; + + steamGlobalUserID.m_SteamInstanceID = 0; + steamGlobalUserID.m_SteamLocalUserID.Split.High32bits = steamID.GetAccountID() % 2; + steamGlobalUserID.m_SteamLocalUserID.Split.Low32bits = steamID.GetAccountID() / 2; + + return steamGlobalUserID; +} + + +#endif + // generic invalid CSteamID #define k_steamIDNil CSteamID() @@ -918,74 +946,21 @@ class CGameID m_gameID.m_nType = k_EGameIDTypeGameMod; } - // Hidden functions used only by Steam - explicit CGameID( const char *pchGameID ); - const char *Render() const; // render this Game ID to string - static const char *Render( uint64 ulGameID ); // static method to render a uint64 representation of a Game ID to a string - - // must include checksum_crc.h first to get this functionality -#if defined( CHECKSUM_CRC_H ) - CGameID( uint32 nAppID, const char *pchModPath ) - { - m_ulGameID = 0; - m_gameID.m_nAppID = nAppID; - m_gameID.m_nType = k_EGameIDTypeGameMod; - - char rgchModDir[MAX_PATH]; - V_FileBase( pchModPath, rgchModDir, sizeof( rgchModDir ) ); - CRC32_t crc32; - CRC32_Init( &crc32 ); - CRC32_ProcessBuffer( &crc32, rgchModDir, V_strlen( rgchModDir ) ); - CRC32_Final( &crc32 ); - - // set the high-bit on the mod-id - // reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique - // replacement for appID's - m_gameID.m_nModID = crc32 | (0x80000000); - } - - CGameID( const char *pchExePath, const char *pchAppName ) + CGameID( const CGameID &that ) { - m_ulGameID = 0; - m_gameID.m_nAppID = k_uAppIdInvalid; - m_gameID.m_nType = k_EGameIDTypeShortcut; - - CRC32_t crc32; - CRC32_Init( &crc32 ); - CRC32_ProcessBuffer( &crc32, pchExePath, V_strlen( pchExePath ) ); - CRC32_ProcessBuffer( &crc32, pchAppName, V_strlen( pchAppName ) ); - CRC32_Final( &crc32 ); - - // set the high-bit on the mod-id - // reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique - // replacement for appID's - m_gameID.m_nModID = crc32 | (0x80000000); + m_ulGameID = that.m_ulGameID; } -#if defined( VSTFILEID_H ) - - CGameID( VstFileID vstFileID ) + CGameID& operator=( const CGameID & that ) { - m_ulGameID = 0; - m_gameID.m_nAppID = k_uAppIdInvalid; - m_gameID.m_nType = k_EGameIDTypeP2P; - - CRC32_t crc32; - CRC32_Init( &crc32 ); - const char *pchFileId = vstFileID.Render(); - CRC32_ProcessBuffer( &crc32, pchFileId, V_strlen( pchFileId ) ); - CRC32_Final( &crc32 ); - - // set the high-bit on the mod-id - // reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique - // replacement for appID's - m_gameID.m_nModID = crc32 | (0x80000000); + m_ulGameID = that.m_ulGameID; + return *this; } -#endif /* VSTFILEID_H */ - -#endif /* CHECKSUM_CRC_H */ - + // Hidden functions used only by Steam + explicit CGameID( const char *pchGameID ); + const char *Render() const; // render this Game ID to string + static const char *Render( uint64 ulGameID ); // static method to render a uint64 representation of a Game ID to a string uint64 ToUint64() const { @@ -1065,9 +1040,6 @@ class CGameID return m_gameID.m_nAppID == k_uAppIdInvalid && m_gameID.m_nModID & 0x80000000; default: -#if defined(Assert) - Assert(false); -#endif return false; } @@ -1078,9 +1050,9 @@ class CGameID m_ulGameID = 0; } - - -private: +// +// Internal stuff. Use the accessors above if possible +// enum EGameIDType { @@ -1115,24 +1087,90 @@ class CGameID const int k_cchGameExtraInfoMax = 64; -//----------------------------------------------------------------------------- -// Constants used for query ports. -//----------------------------------------------------------------------------- - -#define QUERY_PORT_NOT_INITIALIZED 0xFFFF // We haven't asked the GS for this query port's actual value yet. -#define QUERY_PORT_ERROR 0xFFFE // We were unable to get the query port for this server. - - //----------------------------------------------------------------------------- // Purpose: Passed as argument to SteamAPI_UseBreakpadCrashHandler to enable optional callback // just before minidump file is captured after a crash has occurred. (Allows app to append additional comment data to the dump, etc.) //----------------------------------------------------------------------------- typedef void (*PFNPreMinidumpCallback)(void *context); -//----------------------------------------------------------------------------- -// Purpose: Used by ICrashHandler interfaces to reference particular installed crash handlers -//----------------------------------------------------------------------------- -typedef void *BREAKPAD_HANDLE; -#define BREAKPAD_INVALID_HANDLE (BREAKPAD_HANDLE)0 +enum EGameSearchErrorCode_t +{ + k_EGameSearchErrorCode_OK = 1, + k_EGameSearchErrorCode_Failed_Search_Already_In_Progress = 2, + k_EGameSearchErrorCode_Failed_No_Search_In_Progress = 3, + k_EGameSearchErrorCode_Failed_Not_Lobby_Leader = 4, // if not the lobby leader can not call SearchForGameWithLobby + k_EGameSearchErrorCode_Failed_No_Host_Available = 5, // no host is available that matches those search params + k_EGameSearchErrorCode_Failed_Search_Params_Invalid = 6, // search params are invalid + k_EGameSearchErrorCode_Failed_Offline = 7, // offline, could not communicate with server + k_EGameSearchErrorCode_Failed_NotAuthorized = 8, // either the user or the application does not have priveledges to do this + k_EGameSearchErrorCode_Failed_Unknown_Error = 9, // unknown error +}; + +enum EPlayerResult_t +{ + k_EPlayerResultFailedToConnect = 1, // failed to connect after confirming + k_EPlayerResultAbandoned = 2, // quit game without completing it + k_EPlayerResultKicked = 3, // kicked by other players/moderator/server rules + k_EPlayerResultIncomplete = 4, // player stayed to end but game did not conclude successfully ( nofault to player ) + k_EPlayerResultCompleted = 5, // player completed game +}; + + +enum ESteamIPv6ConnectivityProtocol +{ + k_ESteamIPv6ConnectivityProtocol_Invalid = 0, + k_ESteamIPv6ConnectivityProtocol_HTTP = 1, // because a proxy may make this different than other protocols + k_ESteamIPv6ConnectivityProtocol_UDP = 2, // test UDP connectivity. Uses a port that is commonly needed for other Steam stuff. If UDP works, TCP probably works. +}; + +// For the above transport protocol, what do we think the local machine's connectivity to the internet over ipv6 is like +enum ESteamIPv6ConnectivityState +{ + k_ESteamIPv6ConnectivityState_Unknown = 0, // We haven't run a test yet + k_ESteamIPv6ConnectivityState_Good = 1, // We have recently been able to make a request on ipv6 for the given protocol + k_ESteamIPv6ConnectivityState_Bad = 2, // We failed to make a request, either because this machine has no ipv6 address assigned, or it has no upstream connectivity +}; + + +// Define compile time assert macros to let us validate the structure sizes. +#define VALVE_COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1]; + +#if defined(__linux__) || defined(__APPLE__) +// The 32-bit version of gcc has the alignment requirement for uint64 and double set to +// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. +// The 64-bit version of gcc has the alignment requirement for these types set to +// 8 meaning that unless we use #pragma pack(4) our structures will get bigger. +// The 64-bit structure packing has to match the 32-bit structure packing for each platform. +#define VALVE_CALLBACK_PACK_SMALL +#else +#define VALVE_CALLBACK_PACK_LARGE +#endif + +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error ??? +#endif + +typedef struct ValvePackingSentinel_t +{ + uint32 m_u32; + uint64 m_u64; + uint16 m_u16; + double m_d; +} ValvePackingSentinel_t; + +#pragma pack( pop ) + + +#if defined(VALVE_CALLBACK_PACK_SMALL) +VALVE_COMPILE_TIME_ASSERT( sizeof(ValvePackingSentinel_t) == 24 ) +#elif defined(VALVE_CALLBACK_PACK_LARGE) +VALVE_COMPILE_TIME_ASSERT( sizeof(ValvePackingSentinel_t) == 32 ) +#else +#error ??? +#endif #endif // STEAMCLIENTPUBLIC_H diff --git a/public/steam/steamcontrollerpublic.h b/public/steam/steamcontrollerpublic.h new file mode 100644 index 00000000..327ea46a --- /dev/null +++ b/public/steam/steamcontrollerpublic.h @@ -0,0 +1,79 @@ +//========= Copyright 1996-2013, Valve LLC, All rights reserved. ============ +// +// Purpose: Controller related public types/constants +// +//============================================================================= + +#ifndef STEAMCONTROLLERPUBLIC_H +#define STEAMCONTROLLERPUBLIC_H +#ifdef _WIN32 +#pragma once +#endif + + +#if defined( STEAM ) || defined( ISTEAMCONTROLLER_H ) +// This file should only be included by the Steam build or directly from +// isteamcontroller.h. +#include "steamtypes.h" +#else +#include +typedef uint32_t uint32; +#ifdef __C51__ +typedef uint8_t uint64[8]; +#else +typedef uint64_t uint64; +#endif +#endif + +#pragma pack(1) + +// Safe to add new bitfields at the end of this list for new buttons/actions, +// but never re-use or re-number an existing flag as old client code will be +// confused. +#define STEAM_RIGHT_TRIGGER_MASK 0x0000000000000001l +#define STEAM_LEFT_TRIGGER_MASK 0x0000000000000002l +#define STEAM_RIGHT_BUMPER_MASK 0x0000000000000004l +#define STEAM_LEFT_BUMPER_MASK 0x0000000000000008l +#define STEAM_BUTTON_0_MASK 0x0000000000000010l +#define STEAM_BUTTON_1_MASK 0x0000000000000020l +#define STEAM_BUTTON_2_MASK 0x0000000000000040l +#define STEAM_BUTTON_3_MASK 0x0000000000000080l +#define STEAM_TOUCH_0_MASK 0x0000000000000100l +#define STEAM_TOUCH_1_MASK 0x0000000000000200l +#define STEAM_TOUCH_2_MASK 0x0000000000000400l +#define STEAM_TOUCH_3_MASK 0x0000000000000800l +#define STEAM_BUTTON_MENU_MASK 0x0000000000001000l +#define STEAM_BUTTON_STEAM_MASK 0x0000000000002000l +#define STEAM_BUTTON_ESCAPE_MASK 0x0000000000004000l +#define STEAM_BUTTON_BACK_LEFT_MASK 0x0000000000008000l +#define STEAM_BUTTON_BACK_RIGHT_MASK 0x0000000000010000l +#define STEAM_BUTTON_LEFTPAD_CLICKED_MASK 0x0000000000020000l +#define STEAM_BUTTON_RIGHTPAD_CLICKED_MASK 0x0000000000040000l +#define STEAM_LEFTPAD_FINGERDOWN_MASK 0x0000000000080000l +#define STEAM_RIGHTPAD_FINGERDOWN_MASK 0x0000000000100000l + +// Only add fields to the end of this struct, or if you need to change it in a larger +// way add a new message id and new struct completely so as to not break old clients. +typedef struct +{ + // If packet num matches that on your prior call, then the controller state hasn't been changed since + // your last call and there is no need to process it + uint32 unPacketNum; + + // bit flags for each of the buttons + uint64 ulButtons; + + // Left pad coordinates + short sLeftPadX; + short sLeftPadY; + + // Right pad coordinates + short sRightPadX; + short sRightPadY; + +} SteamControllerState_t; + +#pragma pack() + +#endif // STEAMCONTROLLERPUBLIC_H + diff --git a/public/steam/steamencryptedappticket.h b/public/steam/steamencryptedappticket.h new file mode 100644 index 00000000..4419a0be --- /dev/null +++ b/public/steam/steamencryptedappticket.h @@ -0,0 +1,40 @@ +//========= Copyright 1996-2010, Valve LLC, All rights reserved. ============ +// +// Purpose: utilities to decode/decrypt a ticket from the +// ISteamUser::RequestEncryptedAppTicket, ISteamUser::GetEncryptedAppTicket API +// +// To use: declare CSteamEncryptedAppTicket, then call BDecryptTicket +// if BDecryptTicket returns true, other accessors are valid +// +//============================================================================= + +#include "steam_api.h" + +static const int k_nSteamEncryptedAppTicketSymmetricKeyLen = 32; + + +S_API bool SteamEncryptedAppTicket_BDecryptTicket( const uint8 *rgubTicketEncrypted, uint32 cubTicketEncrypted, + uint8 *rgubTicketDecrypted, uint32 *pcubTicketDecrypted, + const uint8 rgubKey[k_nSteamEncryptedAppTicketSymmetricKeyLen], int cubKey ); + +S_API bool SteamEncryptedAppTicket_BIsTicketForApp( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, AppId_t nAppID ); + +S_API RTime32 SteamEncryptedAppTicket_GetTicketIssueTime( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted ); + +S_API void SteamEncryptedAppTicket_GetTicketSteamID( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, CSteamID *psteamID ); + +S_API AppId_t SteamEncryptedAppTicket_GetTicketAppID( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted ); + +S_API bool SteamEncryptedAppTicket_BUserOwnsAppInTicket( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, AppId_t nAppID ); + +S_API bool SteamEncryptedAppTicket_BUserIsVacBanned( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted ); + +S_API bool SteamEncryptedAppTicket_BGetAppDefinedValue( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, uint32 *pValue ); + +S_API const uint8 *SteamEncryptedAppTicket_GetUserVariableData( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, uint32 *pcubUserData ); + +S_API bool SteamEncryptedAppTicket_BIsTicketSigned( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted, const uint8 *pubRSAKey, uint32 cubRSAKey ); + +S_API bool SteamEncryptedAppTicket_BIsLicenseBorrowed( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted ); + +S_API bool SteamEncryptedAppTicket_BIsLicenseTemporary( uint8 *rgubTicketDecrypted, uint32 cubTicketDecrypted ); diff --git a/public/steam/steamhttpenums.h b/public/steam/steamhttpenums.h index e15171f4..056b0e5f 100644 --- a/public/steam/steamhttpenums.h +++ b/public/steam/steamhttpenums.h @@ -23,6 +23,7 @@ enum EHTTPMethod k_EHTTPMethodPUT, k_EHTTPMethodDELETE, k_EHTTPMethodOPTIONS, + k_EHTTPMethodPATCH, // The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for // a compliant general purpose server. We'll likely add more as we find uses for them. @@ -83,6 +84,7 @@ enum EHTTPStatusCode k_EHTTPStatusCode417ExpectationFailed = 417, k_EHTTPStatusCode4xxUnknown = 418, // 418 is reserved, so we'll use it to mean unknown k_EHTTPStatusCode429TooManyRequests = 429, + k_EHTTPStatusCode444ConnectionClosed = 444, // nginx only? // Server error codes k_EHTTPStatusCode500InternalServerError = 500, diff --git a/public/steam/steamnetworkingfakeip.h b/public/steam/steamnetworkingfakeip.h new file mode 100644 index 00000000..89ebd101 --- /dev/null +++ b/public/steam/steamnetworkingfakeip.h @@ -0,0 +1,135 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== + +#ifndef STEAMNETWORKINGFAKEIP_H +#define STEAMNETWORKINGFAKEIP_H +#pragma once + +#include "steamnetworkingtypes.h" +#include "steam_api_common.h" + +// It is HIGHLY recommended to limit messages sent via Fake UDP port to this +// value. The purpose of a Fake UDP port is to make porting ordinary ad-hoc UDP +// code easier. Although the real MTU might be higher than this, this particular +// conservative value is chosen so that fragmentation won't be occurring and +// hiding performance problems from you. +constexpr int k_cbSteamNetworkingSocketsFakeUDPPortRecommendedMTU = 1200; + +// Messages larger than this size are not allowed and cannot be sent +// via Fake UDP port. +constexpr int k_cbSteamNetworkingSocketsFakeUDPPortMaxMessageSize = 4096; + +//----------------------------------------------------------------------------- +/// ISteamNetworkingFakeUDPPort +/// +/// Acts like a UDP port, sending and receiving datagrams addressed using +/// FakeIP addresses. +/// +/// See: ISteamNetworkingSockets::CreateFakeUDPPort + +class ISteamNetworkingFakeUDPPort +{ +public: + /// Destroy the object and cleanup any internal connections. + /// Note that this function call is not threadsafe with respect + /// to any other method of this interface. (However, in general + /// all other operations are threadsafe with respect to each other.) + virtual void DestroyFakeUDPPort() = 0; + + /// Send a datagram to the specified FakeIP. + /// + /// See ISteamNetworkingSockets::SendMessageToConnection for the meaning of + /// nSendFlags and possible return codes. + /// + /// Notes: + /// - datagrams larger than the underlying MTU are supported, but + /// reliable messages (k_nSteamNetworkingSend_Reliable) are not supported. + /// - You will usually want to use k_nSteamNetworkingSend_NoNagle + /// - k_EResultBusy is returned if this is a "server" port and the global + /// allocation has not yet completed. + /// - k_EResultIPNotFound will be returned if the address is a local/ephemeral + /// address and no existing connection can be found. This can happen if + /// the remote host contacted us without having a global address, and we + /// assigned them a random local address, and then the session with + /// that host timed out. + /// - When initiating communications, the first messages may be sent + /// via backend signaling, or otherwise delayed, while a route is found. + /// Expect the ping time to fluctuate during this period, and it's possible + /// that messages will be delivered out of order (which is also possible with + /// ordinary UDP). + virtual EResult SendMessageToFakeIP( const SteamNetworkingIPAddr &remoteAddress, const void *pData, uint32 cbData, int nSendFlags ) = 0; + + /// Receive messages on the port. + /// + /// Returns the number of messages returned into your array, up to nMaxMessages. + /// + /// SteamNetworkingMessage_t::m_identity in the returned message(s) will always contain + /// a FakeIP. See ISteamNetworkingUtils::GetRealIdentityForFakeIP. + virtual int ReceiveMessages( SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; + + /// Schedule the internal connection for a given peer to be cleaned up in a few seconds. + /// + /// Idle connections automatically time out, and so this is not strictly *necessary*, + /// but if you have reason to believe that you are done talking to a given peer for + /// a while, you can call this to speed up the timeout. If any remaining packets are + /// sent or received from the peer, the cleanup is canceled and the usual timeout + /// value is restored. Thus you will usually call this immediately after sending + /// or receiving application-layer "close connection" packets. + virtual void ScheduleCleanup( const SteamNetworkingIPAddr &remoteAddress ) = 0; +}; + +/// Callback struct used to notify when a connection has changed state +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error "Must define VALVE_CALLBACK_PACK_SMALL or VALVE_CALLBACK_PACK_LARGE" +#endif + +/// A struct used to describe a "fake IP" we have been assigned to +/// use as an identifier. This callback is posted when +/// ISteamNetworkingSoockets::BeginAsyncRequestFakeIP completes. +/// See also ISteamNetworkingSockets::GetFakeIP +struct SteamNetworkingFakeIPResult_t +{ + enum { k_iCallback = k_iSteamNetworkingSocketsCallbacks + 3 }; + + /// Status/result of the allocation request. Possible failure values are: + /// - k_EResultBusy - you called GetFakeIP but the request has not completed. + /// - k_EResultInvalidParam - you called GetFakeIP with an invalid port index + /// - k_EResultLimitExceeded - You asked for too many ports, or made an + /// additional request after one had already succeeded + /// - k_EResultNoMatch - GetFakeIP was called, but no request has been made + /// + /// Note that, with the exception of k_EResultBusy (if you are polling), + /// it is highly recommended to treat all failures as fatal. + EResult m_eResult; + + /// Local identity of the ISteamNetworkingSockets object that made + /// this request and is assigned the IP. This is needed in the callback + /// in the case where there are multiple ISteamNetworkingSockets objects. + /// (E.g. one for the user, and another for the local gameserver). + SteamNetworkingIdentity m_identity; + + /// Fake IPv4 IP address that we have been assigned. NOTE: this + /// IP address is not exclusively ours! Steam tries to avoid sharing + /// IP addresses, but this may not always be possible. The IP address + /// may be currently in use by another host, but with different port(s). + /// The exact same IP:port address may have been used previously. + /// Steam tries to avoid reusing ports until they have not been in use for + /// some time, but this may not always be possible. + uint32 m_unIP; + + /// Port number(s) assigned to us. Only the first entries will contain + /// nonzero values. Entries corresponding to ports beyond what was + /// allocated for you will be zero. + /// + /// (NOTE: At the time of this writing, the maximum number of ports you may + /// request is 4.) + enum { k_nMaxReturnPorts = 8 }; + uint16 m_unPorts[k_nMaxReturnPorts]; +}; + +#pragma pack( pop ) + +#endif // _H diff --git a/public/steam/steamnetworkingtypes.h b/public/steam/steamnetworkingtypes.h new file mode 100644 index 00000000..6f93c04a --- /dev/null +++ b/public/steam/steamnetworkingtypes.h @@ -0,0 +1,1796 @@ +//====== Copyright Valve Corporation, All rights reserved. ==================== +// +// Purpose: misc networking utilities +// +//============================================================================= + +#ifndef STEAMNETWORKINGTYPES +#define STEAMNETWORKINGTYPES +#pragma once + +#include +#include +#include "steamtypes.h" +#include "steamclientpublic.h" + +//----------------------------------------------------------------------------- +// SteamNetworkingSockets config. +#if !defined(STEAMNETWORKINGSOCKETS_STANDALONELIB) && !defined(STEAMNETWORKINGSOCKETS_STEAMAPI) + #define STEAMNETWORKINGSOCKETS_STEAMAPI +#endif +//----------------------------------------------------------------------------- + +#ifdef NN_NINTENDO_SDK // We always static link on Nintendo + #define STEAMNETWORKINGSOCKETS_STATIC_LINK +#endif +#if defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" +#elif defined( STEAMNETWORKINGSOCKETS_FOREXPORT ) + #ifdef _WIN32 + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __declspec( dllexport ) + #else + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __attribute__((visibility("default"))) + #endif +#else + #ifdef _WIN32 + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __declspec( dllimport ) + #else + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" + #endif +#endif + +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error "Must define VALVE_CALLBACK_PACK_SMALL or VALVE_CALLBACK_PACK_LARGE" +#endif + +struct SteamDatagramRelayAuthTicket; +struct SteamDatagramHostedAddress; +struct SteamDatagramGameCoordinatorServerLogin; +struct SteamNetConnectionStatusChangedCallback_t; +struct SteamNetAuthenticationStatus_t; +struct SteamRelayNetworkStatus_t; +struct SteamNetworkingMessagesSessionRequest_t; +struct SteamNetworkingMessagesSessionFailed_t; +struct SteamNetworkingFakeIPResult_t; + +typedef void (*FnSteamNetConnectionStatusChanged)( SteamNetConnectionStatusChangedCallback_t * ); +typedef void (*FnSteamNetAuthenticationStatusChanged)( SteamNetAuthenticationStatus_t * ); +typedef void (*FnSteamRelayNetworkStatusChanged)(SteamRelayNetworkStatus_t *); +typedef void (*FnSteamNetworkingMessagesSessionRequest)(SteamNetworkingMessagesSessionRequest_t *); +typedef void (*FnSteamNetworkingMessagesSessionFailed)(SteamNetworkingMessagesSessionFailed_t *); +typedef void (*FnSteamNetworkingFakeIPResult)(SteamNetworkingFakeIPResult_t *); + +/// Handle used to identify a connection to a remote host. +typedef uint32 HSteamNetConnection; +const HSteamNetConnection k_HSteamNetConnection_Invalid = 0; + +/// Handle used to identify a "listen socket". Unlike traditional +/// Berkeley sockets, a listen socket and a connection are two +/// different abstractions. +typedef uint32 HSteamListenSocket; +const HSteamListenSocket k_HSteamListenSocket_Invalid = 0; + +/// Handle used to identify a poll group, used to query many +/// connections at once efficiently. +typedef uint32 HSteamNetPollGroup; +const HSteamNetPollGroup k_HSteamNetPollGroup_Invalid = 0; + +/// Max length of diagnostic error message +const int k_cchMaxSteamNetworkingErrMsg = 1024; + +/// Used to return English-language diagnostic error messages to caller. +/// (For debugging or spewing to a console, etc. Not intended for UI.) +typedef char SteamNetworkingErrMsg[ k_cchMaxSteamNetworkingErrMsg ]; + +/// Identifier used for a network location point of presence. (E.g. a Valve data center.) +/// Typically you won't need to directly manipulate these. +typedef uint32 SteamNetworkingPOPID; + +/// A local timestamp. You can subtract two timestamps to get the number of elapsed +/// microseconds. This is guaranteed to increase over time during the lifetime +/// of a process, but not globally across runs. You don't need to worry about +/// the value wrapping around. Note that the underlying clock might not actually have +/// microsecond resolution. +typedef int64 SteamNetworkingMicroseconds; + +/// Describe the status of a particular network resource +enum ESteamNetworkingAvailability +{ + // Negative values indicate a problem. + // + // In general, we will not automatically retry unless you take some action that + // depends on of requests this resource, such as querying the status, attempting + // to initiate a connection, receive a connection, etc. If you do not take any + // action at all, we do not automatically retry in the background. + k_ESteamNetworkingAvailability_CannotTry = -102, // A dependent resource is missing, so this service is unavailable. (E.g. we cannot talk to routers because Internet is down or we don't have the network config.) + k_ESteamNetworkingAvailability_Failed = -101, // We have tried for enough time that we would expect to have been successful by now. We have never been successful + k_ESteamNetworkingAvailability_Previously = -100, // We tried and were successful at one time, but now it looks like we have a problem + + k_ESteamNetworkingAvailability_Retrying = -10, // We previously failed and are currently retrying + + // Not a problem, but not ready either + k_ESteamNetworkingAvailability_NeverTried = 1, // We don't know because we haven't ever checked/tried + k_ESteamNetworkingAvailability_Waiting = 2, // We're waiting on a dependent resource to be acquired. (E.g. we cannot obtain a cert until we are logged into Steam. We cannot measure latency to relays until we have the network config.) + k_ESteamNetworkingAvailability_Attempting = 3, // We're actively trying now, but are not yet successful. + + k_ESteamNetworkingAvailability_Current = 100, // Resource is online/available + + + k_ESteamNetworkingAvailability_Unknown = 0, // Internal dummy/sentinel, or value is not applicable in this context + k_ESteamNetworkingAvailability__Force32bit = 0x7fffffff, +}; + +// +// Describing network hosts +// + +/// Different methods of describing the identity of a network host +enum ESteamNetworkingIdentityType +{ + // Dummy/empty/invalid. + // Please note that if we parse a string that we don't recognize + // but that appears reasonable, we will NOT use this type. Instead + // we'll use k_ESteamNetworkingIdentityType_UnknownType. + k_ESteamNetworkingIdentityType_Invalid = 0, + + // + // Basic platform-specific identifiers. + // + k_ESteamNetworkingIdentityType_SteamID = 16, // 64-bit CSteamID + k_ESteamNetworkingIdentityType_XboxPairwiseID = 17, // Publisher-specific user identity, as string + k_ESteamNetworkingIdentityType_SonyPSN = 18, // 64-bit ID + k_ESteamNetworkingIdentityType_GoogleStadia = 19, // 64-bit ID + //k_ESteamNetworkingIdentityType_NintendoNetworkServiceAccount, + //k_ESteamNetworkingIdentityType_EpicGameStore + //k_ESteamNetworkingIdentityType_WeGame + + // + // Special identifiers. + // + + // Use their IP address (and port) as their "identity". + // These types of identities are always unauthenticated. + // They are useful for porting plain sockets code, and other + // situations where you don't care about authentication. In this + // case, the local identity will be "localhost", + // and the remote address will be their network address. + // + // We use the same type for either IPv4 or IPv6, and + // the address is always store as IPv6. We use IPv4 + // mapped addresses to handle IPv4. + k_ESteamNetworkingIdentityType_IPAddress = 1, + + // Generic string/binary blobs. It's up to your app to interpret this. + // This library can tell you if the remote host presented a certificate + // signed by somebody you have chosen to trust, with this identity on it. + // It's up to you to ultimately decide what this identity means. + k_ESteamNetworkingIdentityType_GenericString = 2, + k_ESteamNetworkingIdentityType_GenericBytes = 3, + + // This identity type is used when we parse a string that looks like is a + // valid identity, just of a kind that we don't recognize. In this case, we + // can often still communicate with the peer! Allowing such identities + // for types we do not recognize useful is very useful for forward + // compatibility. + k_ESteamNetworkingIdentityType_UnknownType = 4, + + // Make sure this enum is stored in an int. + k_ESteamNetworkingIdentityType__Force32bit = 0x7fffffff, +}; + +/// "Fake IPs" are assigned to hosts, to make it easier to interface with +/// older code that assumed all hosts will have an IPv4 address +enum ESteamNetworkingFakeIPType +{ + k_ESteamNetworkingFakeIPType_Invalid, // Error, argument was not even an IP address, etc. + k_ESteamNetworkingFakeIPType_NotFake, // Argument was a valid IP, but was not from the reserved "fake" range + k_ESteamNetworkingFakeIPType_GlobalIPv4, // Globally unique (for a given app) IPv4 address. Address space managed by Steam + k_ESteamNetworkingFakeIPType_LocalIPv4, // Locally unique IPv4 address. Address space managed by the local process. For internal use only; should not be shared! + + k_ESteamNetworkingFakeIPType__Force32Bit = 0x7fffffff +}; + +#pragma pack(push,1) + +/// Store an IP and port. IPv6 is always used; IPv4 is represented using +/// "IPv4-mapped" addresses: IPv4 aa.bb.cc.dd => IPv6 ::ffff:aabb:ccdd +/// (RFC 4291 section 2.5.5.2.) +struct SteamNetworkingIPAddr +{ + void Clear(); // Set everything to zero. E.g. [::]:0 + bool IsIPv6AllZeros() const; // Return true if the IP is ::0. (Doesn't check port.) + void SetIPv6( const uint8 *ipv6, uint16 nPort ); // Set IPv6 address. IP is interpreted as bytes, so there are no endian issues. (Same as inaddr_in6.) The IP can be a mapped IPv4 address + void SetIPv4( uint32 nIP, uint16 nPort ); // Sets to IPv4 mapped address. IP and port are in host byte order. + bool IsIPv4() const; // Return true if IP is mapped IPv4 + uint32 GetIPv4() const; // Returns IP in host byte order (e.g. aa.bb.cc.dd as 0xaabbccdd). Returns 0 if IP is not mapped IPv4. + void SetIPv6LocalHost( uint16 nPort = 0); // Set to the IPv6 localhost address ::1, and the specified port. + bool IsLocalHost() const; // Return true if this identity is localhost. (Either IPv6 ::1, or IPv4 127.0.0.1) + + // Max length of the buffer needed to hold IP formatted using ToString, including '\0' + // ([0123:4567:89ab:cdef:0123:4567:89ab:cdef]:12345) + enum { k_cchMaxString = 48 }; + + /// Print to a string, with or without the port. Mapped IPv4 addresses are printed + /// as dotted decimal (12.34.56.78), otherwise this will print the canonical + /// form according to RFC5952. If you include the port, IPv6 will be surrounded by + /// brackets, e.g. [::1:2]:80. Your buffer should be at least k_cchMaxString bytes + /// to avoid truncation + /// + /// See also SteamNetworkingIdentityRender + inline void ToString( char *buf, size_t cbBuf, bool bWithPort ) const; + + /// Parse an IP address and optional port. If a port is not present, it is set to 0. + /// (This means that you cannot tell if a zero port was explicitly specified.) + inline bool ParseString( const char *pszStr ); + + /// RFC4038, section 4.2 + struct IPv4MappedAddress { + uint64 m_8zeros; + uint16 m_0000; + uint16 m_ffff; + uint8 m_ip[ 4 ]; // NOTE: As bytes, i.e. network byte order + }; + + union + { + uint8 m_ipv6[ 16 ]; + IPv4MappedAddress m_ipv4; + }; + uint16 m_port; // Host byte order + + /// See if two addresses are identical + bool operator==(const SteamNetworkingIPAddr &x ) const; + + /// Classify address as FakeIP. This function never returns + /// k_ESteamNetworkingFakeIPType_Invalid. + ESteamNetworkingFakeIPType GetFakeIPType() const; + + /// Return true if we are a FakeIP + bool IsFakeIP() const { return GetFakeIPType() > k_ESteamNetworkingFakeIPType_NotFake; } +}; + +/// An abstract way to represent the identity of a network host. All identities can +/// be represented as simple string. Furthermore, this string representation is actually +/// used on the wire in several places, even though it is less efficient, in order to +/// facilitate forward compatibility. (Old client code can handle an identity type that +/// it doesn't understand.) +struct SteamNetworkingIdentity +{ + /// Type of identity. + ESteamNetworkingIdentityType m_eType; + + // + // Get/Set in various formats. + // + + void Clear(); + bool IsInvalid() const; // Return true if we are the invalid type. Does not make any other validity checks (e.g. is SteamID actually valid) + + void SetSteamID( CSteamID steamID ); + CSteamID GetSteamID() const; // Return black CSteamID (!IsValid()) if identity is not a SteamID + void SetSteamID64( uint64 steamID ); // Takes SteamID as raw 64-bit number + uint64 GetSteamID64() const; // Returns 0 if identity is not SteamID + + bool SetXboxPairwiseID( const char *pszString ); // Returns false if invalid length + const char *GetXboxPairwiseID() const; // Returns nullptr if not Xbox ID + + void SetPSNID( uint64 id ); + uint64 GetPSNID() const; // Returns 0 if not PSN + + void SetStadiaID( uint64 id ); + uint64 GetStadiaID() const; // Returns 0 if not Stadia + + void SetIPAddr( const SteamNetworkingIPAddr &addr ); // Set to specified IP:port + const SteamNetworkingIPAddr *GetIPAddr() const; // returns null if we are not an IP address. + void SetIPv4Addr( uint32 nIPv4, uint16 nPort ); // Set to specified IPv4:port + uint32 GetIPv4() const; // returns 0 if we are not an IPv4 address. + + ESteamNetworkingFakeIPType GetFakeIPType() const; + bool IsFakeIP() const { return GetFakeIPType() > k_ESteamNetworkingFakeIPType_NotFake; } + + // "localhost" is equivalent for many purposes to "anonymous." Our remote + // will identify us by the network address we use. + void SetLocalHost(); // Set to localhost. (We always use IPv6 ::1 for this, not 127.0.0.1) + bool IsLocalHost() const; // Return true if this identity is localhost. + + bool SetGenericString( const char *pszString ); // Returns false if invalid length + const char *GetGenericString() const; // Returns nullptr if not generic string type + + bool SetGenericBytes( const void *data, size_t cbLen ); // Returns false if invalid size. + const uint8 *GetGenericBytes( int &cbLen ) const; // Returns null if not generic bytes type + + /// See if two identities are identical + bool operator==(const SteamNetworkingIdentity &x ) const; + + /// Print to a human-readable string. This is suitable for debug messages + /// or any other time you need to encode the identity as a string. It has a + /// URL-like format (type:). Your buffer should be at least + /// k_cchMaxString bytes big to avoid truncation. + /// + /// See also SteamNetworkingIPAddrRender + void ToString( char *buf, size_t cbBuf ) const; + + /// Parse back a string that was generated using ToString. If we don't understand the + /// string, but it looks "reasonable" (it matches the pattern type: and doesn't + /// have any funky characters, etc), then we will return true, and the type is set to + /// k_ESteamNetworkingIdentityType_UnknownType. false will only be returned if the string + /// looks invalid. + bool ParseString( const char *pszStr ); + + // Max sizes + enum { + k_cchMaxString = 128, // Max length of the buffer needed to hold any identity, formatted in string format by ToString + k_cchMaxGenericString = 32, // Max length of the string for generic string identities. Including terminating '\0' + k_cchMaxXboxPairwiseID = 33, // Including terminating '\0' + k_cbMaxGenericBytes = 32, + }; + + // + // Internal representation. Don't access this directly, use the accessors! + // + // Number of bytes that are relevant below. This MUST ALWAYS be + // set. (Use the accessors!) This is important to enable old code to work + // with new identity types. + int m_cbSize; + union { + uint64 m_steamID64; + uint64 m_PSNID; + uint64 m_stadiaID; + char m_szGenericString[ k_cchMaxGenericString ]; + char m_szXboxPairwiseID[ k_cchMaxXboxPairwiseID ]; + uint8 m_genericBytes[ k_cbMaxGenericBytes ]; + char m_szUnknownRawString[ k_cchMaxString ]; + SteamNetworkingIPAddr m_ip; + uint32 m_reserved[ 32 ]; // Pad structure to leave easy room for future expansion + }; +}; +#pragma pack(pop) + +// +// Connection status +// + +/// High level connection status +enum ESteamNetworkingConnectionState +{ + + /// Dummy value used to indicate an error condition in the API. + /// Specified connection doesn't exist or has already been closed. + k_ESteamNetworkingConnectionState_None = 0, + + /// We are trying to establish whether peers can talk to each other, + /// whether they WANT to talk to each other, perform basic auth, + /// and exchange crypt keys. + /// + /// - For connections on the "client" side (initiated locally): + /// We're in the process of trying to establish a connection. + /// Depending on the connection type, we might not know who they are. + /// Note that it is not possible to tell if we are waiting on the + /// network to complete handshake packets, or for the application layer + /// to accept the connection. + /// + /// - For connections on the "server" side (accepted through listen socket): + /// We have completed some basic handshake and the client has presented + /// some proof of identity. The connection is ready to be accepted + /// using AcceptConnection(). + /// + /// In either case, any unreliable packets sent now are almost certain + /// to be dropped. Attempts to receive packets are guaranteed to fail. + /// You may send messages if the send mode allows for them to be queued. + /// but if you close the connection before the connection is actually + /// established, any queued messages will be discarded immediately. + /// (We will not attempt to flush the queue and confirm delivery to the + /// remote host, which ordinarily happens when a connection is closed.) + k_ESteamNetworkingConnectionState_Connecting = 1, + + /// Some connection types use a back channel or trusted 3rd party + /// for earliest communication. If the server accepts the connection, + /// then these connections switch into the rendezvous state. During this + /// state, we still have not yet established an end-to-end route (through + /// the relay network), and so if you send any messages unreliable, they + /// are going to be discarded. + k_ESteamNetworkingConnectionState_FindingRoute = 2, + + /// We've received communications from our peer (and we know + /// who they are) and are all good. If you close the connection now, + /// we will make our best effort to flush out any reliable sent data that + /// has not been acknowledged by the peer. (But note that this happens + /// from within the application process, so unlike a TCP connection, you are + /// not totally handing it off to the operating system to deal with it.) + k_ESteamNetworkingConnectionState_Connected = 3, + + /// Connection has been closed by our peer, but not closed locally. + /// The connection still exists from an API perspective. You must close the + /// handle to free up resources. If there are any messages in the inbound queue, + /// you may retrieve them. Otherwise, nothing may be done with the connection + /// except to close it. + /// + /// This stats is similar to CLOSE_WAIT in the TCP state machine. + k_ESteamNetworkingConnectionState_ClosedByPeer = 4, + + /// A disruption in the connection has been detected locally. (E.g. timeout, + /// local internet connection disrupted, etc.) + /// + /// The connection still exists from an API perspective. You must close the + /// handle to free up resources. + /// + /// Attempts to send further messages will fail. Any remaining received messages + /// in the queue are available. + k_ESteamNetworkingConnectionState_ProblemDetectedLocally = 5, + +// +// The following values are used internally and will not be returned by any API. +// We document them here to provide a little insight into the state machine that is used +// under the hood. +// + + /// We've disconnected on our side, and from an API perspective the connection is closed. + /// No more data may be sent or received. All reliable data has been flushed, or else + /// we've given up and discarded it. We do not yet know for sure that the peer knows + /// the connection has been closed, however, so we're just hanging around so that if we do + /// get a packet from them, we can send them the appropriate packets so that they can + /// know why the connection was closed (and not have to rely on a timeout, which makes + /// it appear as if something is wrong). + k_ESteamNetworkingConnectionState_FinWait = -1, + + /// We've disconnected on our side, and from an API perspective the connection is closed. + /// No more data may be sent or received. From a network perspective, however, on the wire, + /// we have not yet given any indication to the peer that the connection is closed. + /// We are in the process of flushing out the last bit of reliable data. Once that is done, + /// we will inform the peer that the connection has been closed, and transition to the + /// FinWait state. + /// + /// Note that no indication is given to the remote host that we have closed the connection, + /// until the data has been flushed. If the remote host attempts to send us data, we will + /// do whatever is necessary to keep the connection alive until it can be closed properly. + /// But in fact the data will be discarded, since there is no way for the application to + /// read it back. Typically this is not a problem, as application protocols that utilize + /// the lingering functionality are designed for the remote host to wait for the response + /// before sending any more data. + k_ESteamNetworkingConnectionState_Linger = -2, + + /// Connection is completely inactive and ready to be destroyed + k_ESteamNetworkingConnectionState_Dead = -3, + + k_ESteamNetworkingConnectionState__Force32Bit = 0x7fffffff +}; + +/// Enumerate various causes of connection termination. These are designed to work similar +/// to HTTP error codes: the numeric range gives you a rough classification as to the source +/// of the problem. +enum ESteamNetConnectionEnd +{ + // Invalid/sentinel value + k_ESteamNetConnectionEnd_Invalid = 0, + + // + // Application codes. These are the values you will pass to + // ISteamNetworkingSockets::CloseConnection. You can use these codes if + // you want to plumb through application-specific reason codes. If you don't + // need this facility, feel free to always pass + // k_ESteamNetConnectionEnd_App_Generic. + // + // The distinction between "normal" and "exceptional" termination is + // one you may use if you find useful, but it's not necessary for you + // to do so. The only place where we distinguish between normal and + // exceptional is in connection analytics. If a significant + // proportion of connections terminates in an exceptional manner, + // this can trigger an alert. + // + + // 1xxx: Application ended the connection in a "usual" manner. + // E.g.: user intentionally disconnected from the server, + // gameplay ended normally, etc + k_ESteamNetConnectionEnd_App_Min = 1000, + k_ESteamNetConnectionEnd_App_Generic = k_ESteamNetConnectionEnd_App_Min, + // Use codes in this range for "normal" disconnection + k_ESteamNetConnectionEnd_App_Max = 1999, + + // 2xxx: Application ended the connection in some sort of exceptional + // or unusual manner that might indicate a bug or configuration + // issue. + // + k_ESteamNetConnectionEnd_AppException_Min = 2000, + k_ESteamNetConnectionEnd_AppException_Generic = k_ESteamNetConnectionEnd_AppException_Min, + // Use codes in this range for "unusual" disconnection + k_ESteamNetConnectionEnd_AppException_Max = 2999, + + // + // System codes. These will be returned by the system when + // the connection state is k_ESteamNetworkingConnectionState_ClosedByPeer + // or k_ESteamNetworkingConnectionState_ProblemDetectedLocally. It is + // illegal to pass a code in this range to ISteamNetworkingSockets::CloseConnection + // + + // 3xxx: Connection failed or ended because of problem with the + // local host or their connection to the Internet. + k_ESteamNetConnectionEnd_Local_Min = 3000, + + // You cannot do what you want to do because you're running in offline mode. + k_ESteamNetConnectionEnd_Local_OfflineMode = 3001, + + // We're having trouble contacting many (perhaps all) relays. + // Since it's unlikely that they all went offline at once, the best + // explanation is that we have a problem on our end. Note that we don't + // bother distinguishing between "many" and "all", because in practice, + // it takes time to detect a connection problem, and by the time + // the connection has timed out, we might not have been able to + // actively probe all of the relay clusters, even if we were able to + // contact them at one time. So this code just means that: + // + // * We don't have any recent successful communication with any relay. + // * We have evidence of recent failures to communicate with multiple relays. + k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity = 3002, + + // A hosted server is having trouble talking to the relay + // that the client was using, so the problem is most likely + // on our end + k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay = 3003, + + // We're not able to get the SDR network config. This is + // *almost* always a local issue, since the network config + // comes from the CDN, which is pretty darn reliable. + k_ESteamNetConnectionEnd_Local_NetworkConfig = 3004, + + // Steam rejected our request because we don't have rights + // to do this. + k_ESteamNetConnectionEnd_Local_Rights = 3005, + + // ICE P2P rendezvous failed because we were not able to + // determine our "public" address (e.g. reflexive address via STUN) + // + // If relay fallback is available (it always is on Steam), then + // this is only used internally and will not be returned as a high + // level failure. + k_ESteamNetConnectionEnd_Local_P2P_ICE_NoPublicAddresses = 3006, + + k_ESteamNetConnectionEnd_Local_Max = 3999, + + // 4xxx: Connection failed or ended, and it appears that the + // cause does NOT have to do with the local host or their + // connection to the Internet. It could be caused by the + // remote host, or it could be somewhere in between. + k_ESteamNetConnectionEnd_Remote_Min = 4000, + + // The connection was lost, and as far as we can tell our connection + // to relevant services (relays) has not been disrupted. This doesn't + // mean that the problem is "their fault", it just means that it doesn't + // appear that we are having network issues on our end. + k_ESteamNetConnectionEnd_Remote_Timeout = 4001, + + // Something was invalid with the cert or crypt handshake + // info you gave me, I don't understand or like your key types, + // etc. + k_ESteamNetConnectionEnd_Remote_BadCrypt = 4002, + + // You presented me with a cert that was I was able to parse + // and *technically* we could use encrypted communication. + // But there was a problem that prevents me from checking your identity + // or ensuring that somebody int he middle can't observe our communication. + // E.g.: - the CA key was missing (and I don't accept unsigned certs) + // - The CA key isn't one that I trust, + // - The cert doesn't was appropriately restricted by app, user, time, data center, etc. + // - The cert wasn't issued to you. + // - etc + k_ESteamNetConnectionEnd_Remote_BadCert = 4003, + + // These will never be returned + //k_ESteamNetConnectionEnd_Remote_NotLoggedIn_DEPRECATED = 4004, + //k_ESteamNetConnectionEnd_Remote_NotRunningApp_DEPRECATED = 4005, + + // Something wrong with the protocol version you are using. + // (Probably the code you are running is too old.) + k_ESteamNetConnectionEnd_Remote_BadProtocolVersion = 4006, + + // NAT punch failed failed because we never received any public + // addresses from the remote host. (But we did receive some + // signals form them.) + // + // If relay fallback is available (it always is on Steam), then + // this is only used internally and will not be returned as a high + // level failure. + k_ESteamNetConnectionEnd_Remote_P2P_ICE_NoPublicAddresses = 4007, + + k_ESteamNetConnectionEnd_Remote_Max = 4999, + + // 5xxx: Connection failed for some other reason. + k_ESteamNetConnectionEnd_Misc_Min = 5000, + + // A failure that isn't necessarily the result of a software bug, + // but that should happen rarely enough that it isn't worth specifically + // writing UI or making a localized message for. + // The debug string should contain further details. + k_ESteamNetConnectionEnd_Misc_Generic = 5001, + + // Generic failure that is most likely a software bug. + k_ESteamNetConnectionEnd_Misc_InternalError = 5002, + + // The connection to the remote host timed out, but we + // don't know if the problem is on our end, in the middle, + // or on their end. + k_ESteamNetConnectionEnd_Misc_Timeout = 5003, + + //k_ESteamNetConnectionEnd_Misc_RelayConnectivity_DEPRECATED = 5004, + + // There's some trouble talking to Steam. + k_ESteamNetConnectionEnd_Misc_SteamConnectivity = 5005, + + // A server in a dedicated hosting situation has no relay sessions + // active with which to talk back to a client. (It's the client's + // job to open and maintain those sessions.) + k_ESteamNetConnectionEnd_Misc_NoRelaySessionsToClient = 5006, + + // While trying to initiate a connection, we never received + // *any* communication from the peer. + //k_ESteamNetConnectionEnd_Misc_ServerNeverReplied = 5007, + + // P2P rendezvous failed in a way that we don't have more specific + // information + k_ESteamNetConnectionEnd_Misc_P2P_Rendezvous = 5008, + + // NAT punch failed, probably due to NAT/firewall configuration. + // + // If relay fallback is available (it always is on Steam), then + // this is only used internally and will not be returned as a high + // level failure. + k_ESteamNetConnectionEnd_Misc_P2P_NAT_Firewall = 5009, + + // Our peer replied that it has no record of the connection. + // This should not happen ordinarily, but can happen in a few + // exception cases: + // + // - This is an old connection, and the peer has already cleaned + // up and forgotten about it. (Perhaps it timed out and they + // closed it and were not able to communicate this to us.) + // - A bug or internal protocol error has caused us to try to + // talk to the peer about the connection before we received + // confirmation that the peer has accepted the connection. + // - The peer thinks that we have closed the connection for some + // reason (perhaps a bug), and believes that is it is + // acknowledging our closure. + k_ESteamNetConnectionEnd_Misc_PeerSentNoConnection = 5010, + + k_ESteamNetConnectionEnd_Misc_Max = 5999, + + k_ESteamNetConnectionEnd__Force32Bit = 0x7fffffff +}; + +/// Max length, in bytes (including null terminator) of the reason string +/// when a connection is closed. +const int k_cchSteamNetworkingMaxConnectionCloseReason = 128; + +/// Max length, in bytes (include null terminator) of debug description +/// of a connection. +const int k_cchSteamNetworkingMaxConnectionDescription = 128; + +/// Max length of the app's part of the description +const int k_cchSteamNetworkingMaxConnectionAppName = 32; + +const int k_nSteamNetworkConnectionInfoFlags_Unauthenticated = 1; // We don't have a certificate for the remote host. +const int k_nSteamNetworkConnectionInfoFlags_Unencrypted = 2; // Information is being sent out over a wire unencrypted (by this library) +const int k_nSteamNetworkConnectionInfoFlags_LoopbackBuffers = 4; // Internal loopback buffers. Won't be true for localhost. (You can check the address to determine that.) This implies k_nSteamNetworkConnectionInfoFlags_FastLAN +const int k_nSteamNetworkConnectionInfoFlags_Fast = 8; // The connection is "fast" and "reliable". Either internal/localhost (check the address to find out), or the peer is on the same LAN. (Probably. It's based on the address and the ping time, this is actually hard to determine unambiguously). +const int k_nSteamNetworkConnectionInfoFlags_Relayed = 16; // The connection is relayed somehow (SDR or TURN). +const int k_nSteamNetworkConnectionInfoFlags_DualWifi = 32; // We're taking advantage of dual-wifi multi-path + +/// Describe the state of a connection. +struct SteamNetConnectionInfo_t +{ + + /// Who is on the other end? Depending on the connection type and phase of the connection, we might not know + SteamNetworkingIdentity m_identityRemote; + + /// Arbitrary user data set by the local application code + int64 m_nUserData; + + /// Handle to listen socket this was connected on, or k_HSteamListenSocket_Invalid if we initiated the connection + HSteamListenSocket m_hListenSocket; + + /// Remote address. Might be all 0's if we don't know it, or if this is N/A. + /// (E.g. Basically everything except direct UDP connection.) + SteamNetworkingIPAddr m_addrRemote; + uint16 m__pad1; + + /// What data center is the remote host in? (0 if we don't know.) + SteamNetworkingPOPID m_idPOPRemote; + + /// What relay are we using to communicate with the remote host? + /// (0 if not applicable.) + SteamNetworkingPOPID m_idPOPRelay; + + /// High level state of the connection + ESteamNetworkingConnectionState m_eState; + + /// Basic cause of the connection termination or problem. + /// See ESteamNetConnectionEnd for the values used + int m_eEndReason; + + /// Human-readable, but non-localized explanation for connection + /// termination or problem. This is intended for debugging / + /// diagnostic purposes only, not to display to users. It might + /// have some details specific to the issue. + char m_szEndDebug[ k_cchSteamNetworkingMaxConnectionCloseReason ]; + + /// Debug description. This includes the internal connection ID, + /// connection type (and peer information), and any name + /// given to the connection by the app. This string is used in various + /// internal logging messages. + /// + /// Note that the connection ID *usually* matches the HSteamNetConnection + /// handle, but in certain cases with symmetric connections it might not. + char m_szConnectionDescription[ k_cchSteamNetworkingMaxConnectionDescription ]; + + /// Misc flags. Bitmask of k_nSteamNetworkConnectionInfoFlags_Xxxx + int m_nFlags; + + /// Internal stuff, room to change API easily + uint32 reserved[63]; +}; + +/// Quick connection state, pared down to something you could call +/// more frequently without it being too big of a perf hit. +struct SteamNetConnectionRealTimeStatus_t +{ + + /// High level state of the connection + ESteamNetworkingConnectionState m_eState; + + /// Current ping (ms) + int m_nPing; + + /// Connection quality measured locally, 0...1. (Percentage of packets delivered + /// end-to-end in order). + float m_flConnectionQualityLocal; + + /// Packet delivery success rate as observed from remote host + float m_flConnectionQualityRemote; + + /// Current data rates from recent history. + float m_flOutPacketsPerSec; + float m_flOutBytesPerSec; + float m_flInPacketsPerSec; + float m_flInBytesPerSec; + + /// Estimate rate that we believe that we can send data to our peer. + /// Note that this could be significantly higher than m_flOutBytesPerSec, + /// meaning the capacity of the channel is higher than you are sending data. + /// (That's OK!) + int m_nSendRateBytesPerSecond; + + /// Number of bytes pending to be sent. This is data that you have recently + /// requested to be sent but has not yet actually been put on the wire. The + /// reliable number ALSO includes data that was previously placed on the wire, + /// but has now been scheduled for re-transmission. Thus, it's possible to + /// observe m_cbPendingReliable increasing between two checks, even if no + /// calls were made to send reliable data between the checks. Data that is + /// awaiting the Nagle delay will appear in these numbers. + int m_cbPendingUnreliable; + int m_cbPendingReliable; + + /// Number of bytes of reliable data that has been placed the wire, but + /// for which we have not yet received an acknowledgment, and thus we may + /// have to re-transmit. + int m_cbSentUnackedReliable; + + /// If you queued a message right now, approximately how long would that message + /// wait in the queue before we actually started putting its data on the wire in + /// a packet? + /// + /// In general, data that is sent by the application is limited by the bandwidth + /// of the channel. If you send data faster than this, it must be queued and + /// put on the wire at a metered rate. Even sending a small amount of data (e.g. + /// a few MTU, say ~3k) will require some of the data to be delayed a bit. + /// + /// Ignoring multiple lanes, the estimated delay will be approximately equal to + /// + /// ( m_cbPendingUnreliable+m_cbPendingReliable ) / m_nSendRateBytesPerSecond + /// + /// plus or minus one MTU. It depends on how much time has elapsed since the last + /// packet was put on the wire. For example, the queue might have *just* been emptied, + /// and the last packet placed on the wire, and we are exactly up against the send + /// rate limit. In that case we might need to wait for one packet's worth of time to + /// elapse before we can send again. On the other extreme, the queue might have data + /// in it waiting for Nagle. (This will always be less than one packet, because as + /// soon as we have a complete packet we would send it.) In that case, we might be + /// ready to send data now, and this value will be 0. + /// + /// This value is only valid if multiple lanes are not used. If multiple lanes are + /// in use, then the queue time will be different for each lane, and you must use + /// the value in SteamNetConnectionRealTimeLaneStatus_t. + /// + /// Nagle delay is ignored for the purposes of this calculation. + SteamNetworkingMicroseconds m_usecQueueTime; + + // Internal stuff, room to change API easily + uint32 reserved[16]; +}; + +/// Quick status of a particular lane +struct SteamNetConnectionRealTimeLaneStatus_t +{ + // Counters for this particular lane. See the corresponding variables + // in SteamNetConnectionRealTimeStatus_t + int m_cbPendingUnreliable; + int m_cbPendingReliable; + int m_cbSentUnackedReliable; + int _reservePad1; // Reserved for future use + + /// Lane-specific queue time. This value takes into consideration lane priorities + /// and weights, and how much data is queued in each lane, and attempts to predict + /// how any data currently queued will be sent out. + SteamNetworkingMicroseconds m_usecQueueTime; + + // Internal stuff, room to change API easily + uint32 reserved[10]; +}; + +#pragma pack( pop ) + +// +// Network messages +// + +/// Max size of a single message that we can SEND. +/// Note: We might be wiling to receive larger messages, +/// and our peer might, too. +const int k_cbMaxSteamNetworkingSocketsMessageSizeSend = 512 * 1024; + +/// A message that has been received. +struct SteamNetworkingMessage_t +{ + + /// Message payload + void *m_pData; + + /// Size of the payload. + int m_cbSize; + + /// For messages received on connections: what connection did this come from? + /// For outgoing messages: what connection to send it to? + /// Not used when using the ISteamNetworkingMessages interface + HSteamNetConnection m_conn; + + /// For inbound messages: Who sent this to us? + /// For outbound messages on connections: not used. + /// For outbound messages on the ad-hoc ISteamNetworkingMessages interface: who should we send this to? + SteamNetworkingIdentity m_identityPeer; + + /// For messages received on connections, this is the user data + /// associated with the connection. + /// + /// This is *usually* the same as calling GetConnection() and then + /// fetching the user data associated with that connection, but for + /// the following subtle differences: + /// + /// - This user data will match the connection's user data at the time + /// is captured at the time the message is returned by the API. + /// If you subsequently change the userdata on the connection, + /// this won't be updated. + /// - This is an inline call, so it's *much* faster. + /// - You might have closed the connection, so fetching the user data + /// would not be possible. + /// + /// Not used when sending messages. + int64 m_nConnUserData; + + /// Local timestamp when the message was received + /// Not used for outbound messages. + SteamNetworkingMicroseconds m_usecTimeReceived; + + /// Message number assigned by the sender. This is not used for outbound + /// messages. Note that if multiple lanes are used, each lane has its own + /// message numbers, which are assigned sequentially, so messages from + /// different lanes will share the same numbers. + int64 m_nMessageNumber; + + /// Function used to free up m_pData. This mechanism exists so that + /// apps can create messages with buffers allocated from their own + /// heap, and pass them into the library. This function will + /// usually be something like: + /// + /// free( pMsg->m_pData ); + void (*m_pfnFreeData)( SteamNetworkingMessage_t *pMsg ); + + /// Function to used to decrement the internal reference count and, if + /// it's zero, release the message. You should not set this function pointer, + /// or need to access this directly! Use the Release() function instead! + void (*m_pfnRelease)( SteamNetworkingMessage_t *pMsg ); + + /// When using ISteamNetworkingMessages, the channel number the message was received on + /// (Not used for messages sent or received on "connections") + int m_nChannel; + + /// Bitmask of k_nSteamNetworkingSend_xxx flags. + /// For received messages, only the k_nSteamNetworkingSend_Reliable bit is valid. + /// For outbound messages, all bits are relevant + int m_nFlags; + + /// Arbitrary user data that you can use when sending messages using + /// ISteamNetworkingUtils::AllocateMessage and ISteamNetworkingSockets::SendMessage. + /// (The callback you set in m_pfnFreeData might use this field.) + /// + /// Not used for received messages. + int64 m_nUserData; + + /// For outbound messages, which lane to use? See ISteamNetworkingSockets::ConfigureConnectionLanes. + /// For inbound messages, what lane was the message received on? + uint16 m_idxLane; + uint16 _pad1__; + + /// You MUST call this when you're done with the object, + /// to free up memory, etc. + inline void Release(); + + // For code compatibility, some accessors +#ifndef API_GEN + inline uint32 GetSize() const { return m_cbSize; } + inline const void *GetData() const { return m_pData; } + inline int GetChannel() const { return m_nChannel; } + inline HSteamNetConnection GetConnection() const { return m_conn; } + inline int64 GetConnectionUserData() const { return m_nConnUserData; } + inline SteamNetworkingMicroseconds GetTimeReceived() const { return m_usecTimeReceived; } + inline int64 GetMessageNumber() const { return m_nMessageNumber; } +#endif +protected: + // Declare destructor protected. You should never need to declare a message + // object on the stack or create one yourself. + // - You will receive a pointer to a message object when you receive messages (e.g. ISteamNetworkingSockets::ReceiveMessagesOnConnection) + // - You can allocate a message object for efficient sending using ISteamNetworkingUtils::AllocateMessage + // - Call Release() to free the object + inline ~SteamNetworkingMessage_t() {} +}; + +// +// Flags used to set options for message sending +// + +// Send the message unreliably. Can be lost. Messages *can* be larger than a +// single MTU (UDP packet), but there is no retransmission, so if any piece +// of the message is lost, the entire message will be dropped. +// +// The sending API does have some knowledge of the underlying connection, so +// if there is no NAT-traversal accomplished or there is a recognized adjustment +// happening on the connection, the packet will be batched until the connection +// is open again. +// +// Migration note: This is not exactly the same as k_EP2PSendUnreliable! You +// probably want k_ESteamNetworkingSendType_UnreliableNoNagle +const int k_nSteamNetworkingSend_Unreliable = 0; + +// Disable Nagle's algorithm. +// By default, Nagle's algorithm is applied to all outbound messages. This means +// that the message will NOT be sent immediately, in case further messages are +// sent soon after you send this, which can be grouped together. Any time there +// is enough buffered data to fill a packet, the packets will be pushed out immediately, +// but partially-full packets not be sent until the Nagle timer expires. See +// ISteamNetworkingSockets::FlushMessagesOnConnection, ISteamNetworkingMessages::FlushMessagesToUser +// +// NOTE: Don't just send every message without Nagle because you want packets to get there +// quicker. Make sure you understand the problem that Nagle is solving before disabling it. +// If you are sending small messages, often many at the same time, then it is very likely that +// it will be more efficient to leave Nagle enabled. A typical proper use of this flag is +// when you are sending what you know will be the last message sent for a while (e.g. the last +// in the server simulation tick to a particular client), and you use this flag to flush all +// messages. +const int k_nSteamNetworkingSend_NoNagle = 1; + +// Send a message unreliably, bypassing Nagle's algorithm for this message and any messages +// currently pending on the Nagle timer. This is equivalent to using k_ESteamNetworkingSend_Unreliable +// and then immediately flushing the messages using ISteamNetworkingSockets::FlushMessagesOnConnection +// or ISteamNetworkingMessages::FlushMessagesToUser. (But using this flag is more efficient since you +// only make one API call.) +const int k_nSteamNetworkingSend_UnreliableNoNagle = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoNagle; + +// If the message cannot be sent very soon (because the connection is still doing some initial +// handshaking, route negotiations, etc), then just drop it. This is only applicable for unreliable +// messages. Using this flag on reliable messages is invalid. +const int k_nSteamNetworkingSend_NoDelay = 4; + +// Send an unreliable message, but if it cannot be sent relatively quickly, just drop it instead of queuing it. +// This is useful for messages that are not useful if they are excessively delayed, such as voice data. +// NOTE: The Nagle algorithm is not used, and if the message is not dropped, any messages waiting on the +// Nagle timer are immediately flushed. +// +// A message will be dropped under the following circumstances: +// - the connection is not fully connected. (E.g. the "Connecting" or "FindingRoute" states) +// - there is a sufficiently large number of messages queued up already such that the current message +// will not be placed on the wire in the next ~200ms or so. +// +// If a message is dropped for these reasons, k_EResultIgnored will be returned. +const int k_nSteamNetworkingSend_UnreliableNoDelay = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoDelay|k_nSteamNetworkingSend_NoNagle; + +// Reliable message send. Can send up to k_cbMaxSteamNetworkingSocketsMessageSizeSend bytes in a single message. +// Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for +// efficient sends of large chunks of data. +// +// The Nagle algorithm is used. See notes on k_ESteamNetworkingSendType_Unreliable for more details. +// See k_ESteamNetworkingSendType_ReliableNoNagle, ISteamNetworkingSockets::FlushMessagesOnConnection, +// ISteamNetworkingMessages::FlushMessagesToUser +// +// Migration note: This is NOT the same as k_EP2PSendReliable, it's more like k_EP2PSendReliableWithBuffering +const int k_nSteamNetworkingSend_Reliable = 8; + +// Send a message reliably, but bypass Nagle's algorithm. +// +// Migration note: This is equivalent to k_EP2PSendReliable +const int k_nSteamNetworkingSend_ReliableNoNagle = k_nSteamNetworkingSend_Reliable|k_nSteamNetworkingSend_NoNagle; + +// By default, message sending is queued, and the work of encryption and talking to +// the operating system sockets, etc is done on a service thread. This is usually a +// a performance win when messages are sent from the "main thread". However, if this +// flag is set, and data is ready to be sent immediately (either from this message +// or earlier queued data), then that work will be done in the current thread, before +// the current call returns. If data is not ready to be sent (due to rate limiting +// or Nagle), then this flag has no effect. +// +// This is an advanced flag used to control performance at a very low level. For +// most applications running on modern hardware with more than one CPU core, doing +// the work of sending on a service thread will yield the best performance. Only +// use this flag if you have a really good reason and understand what you are doing. +// Otherwise you will probably just make performance worse. +const int k_nSteamNetworkingSend_UseCurrentThread = 16; + +// When sending a message using ISteamNetworkingMessages, automatically re-establish +// a broken session, without returning k_EResultNoConnection. Without this flag, +// if you attempt to send a message, and the session was proactively closed by the +// peer, or an error occurred that disrupted communications, then you must close the +// session using ISteamNetworkingMessages::CloseSessionWithUser before attempting to +// send another message. (Or you can simply add this flag and retry.) In this way, +// the disruption cannot go unnoticed, and a more clear order of events can be +// ascertained. This is especially important when reliable messages are used, since +// if the connection is disrupted, some of those messages will not have been delivered, +// and it is in general not possible to know which. Although a +// SteamNetworkingMessagesSessionFailed_t callback will be posted when an error occurs +// to notify you that a failure has happened, callbacks are asynchronous, so it is not +// possible to tell exactly when it happened. And because the primary purpose of +// ISteamNetworkingMessages is to be like UDP, there is no notification when a peer closes +// the session. +// +// If you are not using any reliable messages (e.g. you are using ISteamNetworkingMessages +// exactly as a transport replacement for UDP-style datagrams only), you may not need to +// know when an underlying connection fails, and so you may not need this notification. +const int k_nSteamNetworkingSend_AutoRestartBrokenSession = 32; + +// +// Ping location / measurement +// + +/// Object that describes a "location" on the Internet with sufficient +/// detail that we can reasonably estimate an upper bound on the ping between +/// the two hosts, even if a direct route between the hosts is not possible, +/// and the connection must be routed through the Steam Datagram Relay network. +/// This does not contain any information that identifies the host. Indeed, +/// if two hosts are in the same building or otherwise have nearly identical +/// networking characteristics, then it's valid to use the same location +/// object for both of them. +/// +/// NOTE: This object should only be used in the same process! Do not serialize it, +/// send it over the wire, or persist it in a file or database! If you need +/// to do that, convert it to a string representation using the methods in +/// ISteamNetworkingUtils(). +struct SteamNetworkPingLocation_t +{ + uint8 m_data[ 512 ]; +}; + +/// Max possible length of a ping location, in string format. This is +/// an extremely conservative worst case value which leaves room for future +/// syntax enhancements. Most strings in practice are a lot shorter. +/// If you are storing many of these, you will very likely benefit from +/// using dynamic memory. +const int k_cchMaxSteamNetworkingPingLocationString = 1024; + +/// Special values that are returned by some functions that return a ping. +const int k_nSteamNetworkingPing_Failed = -1; +const int k_nSteamNetworkingPing_Unknown = -2; + +// +// Configuration values +// + +/// Configuration values can be applied to different types of objects. +enum ESteamNetworkingConfigScope +{ + + /// Get/set global option, or defaults. Even options that apply to more specific scopes + /// have global scope, and you may be able to just change the global defaults. If you + /// need different settings per connection (for example), then you will need to set those + /// options at the more specific scope. + k_ESteamNetworkingConfig_Global = 1, + + /// Some options are specific to a particular interface. Note that all connection + /// and listen socket settings can also be set at the interface level, and they will + /// apply to objects created through those interfaces. + k_ESteamNetworkingConfig_SocketsInterface = 2, + + /// Options for a listen socket. Listen socket options can be set at the interface layer, + /// if you have multiple listen sockets and they all use the same options. + /// You can also set connection options on a listen socket, and they set the defaults + /// for all connections accepted through this listen socket. (They will be used if you don't + /// set a connection option.) + k_ESteamNetworkingConfig_ListenSocket = 3, + + /// Options for a specific connection. + k_ESteamNetworkingConfig_Connection = 4, + + k_ESteamNetworkingConfigScope__Force32Bit = 0x7fffffff +}; + +// Different configuration values have different data types +enum ESteamNetworkingConfigDataType +{ + k_ESteamNetworkingConfig_Int32 = 1, + k_ESteamNetworkingConfig_Int64 = 2, + k_ESteamNetworkingConfig_Float = 3, + k_ESteamNetworkingConfig_String = 4, + k_ESteamNetworkingConfig_Ptr = 5, + + k_ESteamNetworkingConfigDataType__Force32Bit = 0x7fffffff +}; + +/// Configuration options +enum ESteamNetworkingConfigValue +{ + k_ESteamNetworkingConfig_Invalid = 0, + +// +// Connection options +// + + /// [connection int32] Timeout value (in ms) to use when first connecting + k_ESteamNetworkingConfig_TimeoutInitial = 24, + + /// [connection int32] Timeout value (in ms) to use after connection is established + k_ESteamNetworkingConfig_TimeoutConnected = 25, + + /// [connection int32] Upper limit of buffered pending bytes to be sent, + /// if this is reached SendMessage will return k_EResultLimitExceeded + /// Default is 512k (524288 bytes) + k_ESteamNetworkingConfig_SendBufferSize = 9, + + /// [connection int64] Get/set userdata as a configuration option. + /// The default value is -1. You may want to set the user data as + /// a config value, instead of using ISteamNetworkingSockets::SetConnectionUserData + /// in two specific instances: + /// + /// - You wish to set the userdata atomically when creating + /// an outbound connection, so that the userdata is filled in properly + /// for any callbacks that happen. However, note that this trick + /// only works for connections initiated locally! For incoming + /// connections, multiple state transitions may happen and + /// callbacks be queued, before you are able to service the first + /// callback! Be careful! + /// + /// - You can set the default userdata for all newly created connections + /// by setting this value at a higher level (e.g. on the listen + /// socket or at the global level.) Then this default + /// value will be inherited when the connection is created. + /// This is useful in case -1 is a valid userdata value, and you + /// wish to use something else as the default value so you can + /// tell if it has been set or not. + /// + /// HOWEVER: once a connection is created, the effective value is + /// then bound to the connection. Unlike other connection options, + /// if you change it again at a higher level, the new value will not + /// be inherited by connections. + /// + /// Using the userdata field in callback structs is not advised because + /// of tricky race conditions. Instead, you might try one of these methods: + /// + /// - Use a separate map with the HSteamNetConnection as the key. + /// - Fetch the userdata from the connection in your callback + /// using ISteamNetworkingSockets::GetConnectionUserData, to + // ensure you have the current value. + k_ESteamNetworkingConfig_ConnectionUserData = 40, + + /// [connection int32] Minimum/maximum send rate clamp, 0 is no limit. + /// This value will control the min/max allowed sending rate that + /// bandwidth estimation is allowed to reach. Default is 0 (no-limit) + k_ESteamNetworkingConfig_SendRateMin = 10, + k_ESteamNetworkingConfig_SendRateMax = 11, + + /// [connection int32] Nagle time, in microseconds. When SendMessage is called, if + /// the outgoing message is less than the size of the MTU, it will be + /// queued for a delay equal to the Nagle timer value. This is to ensure + /// that if the application sends several small messages rapidly, they are + /// coalesced into a single packet. + /// See historical RFC 896. Value is in microseconds. + /// Default is 5000us (5ms). + k_ESteamNetworkingConfig_NagleTime = 12, + + /// [connection int32] Don't automatically fail IP connections that don't have + /// strong auth. On clients, this means we will attempt the connection even if + /// we don't know our identity or can't get a cert. On the server, it means that + /// we won't automatically reject a connection due to a failure to authenticate. + /// (You can examine the incoming connection and decide whether to accept it.) + /// + /// This is a dev configuration value, and you should not let users modify it in + /// production. + k_ESteamNetworkingConfig_IP_AllowWithoutAuth = 23, + + /// [connection int32] Do not send UDP packets with a payload of + /// larger than N bytes. If you set this, k_ESteamNetworkingConfig_MTU_DataSize + /// is automatically adjusted + k_ESteamNetworkingConfig_MTU_PacketSize = 32, + + /// [connection int32] (read only) Maximum message size you can send that + /// will not fragment, based on k_ESteamNetworkingConfig_MTU_PacketSize + k_ESteamNetworkingConfig_MTU_DataSize = 33, + + /// [connection int32] Allow unencrypted (and unauthenticated) communication. + /// 0: Not allowed (the default) + /// 1: Allowed, but prefer encrypted + /// 2: Allowed, and preferred + /// 3: Required. (Fail the connection if the peer requires encryption.) + /// + /// This is a dev configuration value, since its purpose is to disable encryption. + /// You should not let users modify it in production. (But note that it requires + /// the peer to also modify their value in order for encryption to be disabled.) + k_ESteamNetworkingConfig_Unencrypted = 34, + + /// [connection int32] Set this to 1 on outbound connections and listen sockets, + /// to enable "symmetric connect mode", which is useful in the following + /// common peer-to-peer use case: + /// + /// - The two peers are "equal" to each other. (Neither is clearly the "client" + /// or "server".) + /// - Either peer may initiate the connection, and indeed they may do this + /// at the same time + /// - The peers only desire a single connection to each other, and if both + /// peers initiate connections simultaneously, a protocol is needed for them + /// to resolve the conflict, so that we end up with a single connection. + /// + /// This use case is both common, and involves subtle race conditions and tricky + /// pitfalls, which is why the API has support for dealing with it. + /// + /// If an incoming connection arrives on a listen socket or via custom signaling, + /// and the application has not attempted to make a matching outbound connection + /// in symmetric mode, then the incoming connection can be accepted as usual. + /// A "matching" connection means that the relevant endpoint information matches. + /// (At the time this comment is being written, this is only supported for P2P + /// connections, which means that the peer identities must match, and the virtual + /// port must match. At a later time, symmetric mode may be supported for other + /// connection types.) + /// + /// If connections are initiated by both peers simultaneously, race conditions + /// can arise, but fortunately, most of them are handled internally and do not + /// require any special awareness from the application. However, there + /// is one important case that application code must be aware of: + /// If application code attempts an outbound connection using a ConnectXxx + /// function in symmetric mode, and a matching incoming connection is already + /// waiting on a listen socket, then instead of forming a new connection, + /// the ConnectXxx call will accept the existing incoming connection, and return + /// a connection handle to this accepted connection. + /// IMPORTANT: in this case, a SteamNetConnectionStatusChangedCallback_t + /// has probably *already* been posted to the queue for the incoming connection! + /// (Once callbacks are posted to the queue, they are not modified.) It doesn't + /// matter if the callback has not been consumed by the app. Thus, application + /// code that makes use of symmetric connections must be aware that, when processing a + /// SteamNetConnectionStatusChangedCallback_t for an incoming connection, the + /// m_hConn may refer to a new connection that the app has has not + /// seen before (the usual case), but it may also refer to a connection that + /// has already been accepted implicitly through a call to Connect()! In this + /// case, AcceptConnection() will return k_EResultDuplicateRequest. + /// + /// Only one symmetric connection to a given peer (on a given virtual port) + /// may exist at any given time. If client code attempts to create a connection, + /// and a (live) connection already exists on the local host, then either the + /// existing connection will be accepted as described above, or the attempt + /// to create a new connection will fail. Furthermore, linger mode functionality + /// is not supported on symmetric connections. + /// + /// A more complicated race condition can arise if both peers initiate a connection + /// at roughly the same time. In this situation, each peer will receive an incoming + /// connection from the other peer, when the application code has already initiated + /// an outgoing connection to that peer. The peers must resolve this conflict and + /// decide who is going to act as the "server" and who will act as the "client". + /// Typically the application does not need to be aware of this case as it is handled + /// internally. On both sides, the will observe their outbound connection being + /// "accepted", although one of them one have been converted internally to act + /// as the "server". + /// + /// In general, symmetric mode should be all-or-nothing: do not mix symmetric + /// connections with a non-symmetric connection that it might possible "match" + /// with. If you use symmetric mode on any connections, then both peers should + /// use it on all connections, and the corresponding listen socket, if any. The + /// behaviour when symmetric and ordinary connections are mixed is not defined by + /// this API, and you should not rely on it. (This advice only applies when connections + /// might possibly "match". For example, it's OK to use all symmetric mode + /// connections on one virtual port, and all ordinary, non-symmetric connections + /// on a different virtual port, as there is no potential for ambiguity.) + /// + /// When using the feature, you should set it in the following situations on + /// applicable objects: + /// + /// - When creating an outbound connection using ConnectXxx function + /// - When creating a listen socket. (Note that this will automatically cause + /// any accepted connections to inherit the flag.) + /// - When using custom signaling, before accepting an incoming connection. + /// + /// Setting the flag on listen socket and accepted connections will enable the + /// API to automatically deal with duplicate incoming connections, even if the + /// local host has not made any outbound requests. (In general, such duplicate + /// requests from a peer are ignored internally and will not be visible to the + /// application code. The previous connection must be closed or resolved first.) + k_ESteamNetworkingConfig_SymmetricConnect = 37, + + /// [connection int32] For connection types that use "virtual ports", this can be used + /// to assign a local virtual port. For incoming connections, this will always be the + /// virtual port of the listen socket (or the port requested by the remote host if custom + /// signaling is used and the connection is accepted), and cannot be changed. For + /// connections initiated locally, the local virtual port will default to the same as the + /// requested remote virtual port, if you do not specify a different option when creating + /// the connection. The local port is only relevant for symmetric connections, when + /// determining if two connections "match." In this case, if you need the local and remote + /// port to differ, you can set this value. + /// + /// You can also read back this value on listen sockets. + /// + /// This value should not be read or written in any other context. + k_ESteamNetworkingConfig_LocalVirtualPort = 38, + + /// [connection int32] Enable Dual wifi band support for this connection + /// 0 = no, 1 = yes, 2 = simulate it for debugging, even if dual wifi not available + k_ESteamNetworkingConfig_DualWifi_Enable = 39, + + /// [connection int32] True to enable diagnostics reporting through + /// generic platform UI. (Only available on Steam.) + k_ESteamNetworkingConfig_EnableDiagnosticsUI = 46, + +// +// Simulating network conditions +// +// These are global (not per-connection) because they apply at +// a relatively low UDP layer. +// + + /// [global float, 0--100] Randomly discard N pct of packets instead of sending/recv + /// This is a global option only, since it is applied at a low level + /// where we don't have much context + k_ESteamNetworkingConfig_FakePacketLoss_Send = 2, + k_ESteamNetworkingConfig_FakePacketLoss_Recv = 3, + + /// [global int32]. Delay all outbound/inbound packets by N ms + k_ESteamNetworkingConfig_FakePacketLag_Send = 4, + k_ESteamNetworkingConfig_FakePacketLag_Recv = 5, + + /// [global float] 0-100 Percentage of packets we will add additional delay + /// to (causing them to be reordered) + k_ESteamNetworkingConfig_FakePacketReorder_Send = 6, + k_ESteamNetworkingConfig_FakePacketReorder_Recv = 7, + + /// [global int32] Extra delay, in ms, to apply to reordered packets. + k_ESteamNetworkingConfig_FakePacketReorder_Time = 8, + + /// [global float 0--100] Globally duplicate some percentage of packets we send + k_ESteamNetworkingConfig_FakePacketDup_Send = 26, + k_ESteamNetworkingConfig_FakePacketDup_Recv = 27, + + /// [global int32] Amount of delay, in ms, to delay duplicated packets. + /// (We chose a random delay between 0 and this value) + k_ESteamNetworkingConfig_FakePacketDup_TimeMax = 28, + + /// [global int32] Trace every UDP packet, similar to Wireshark or tcpdump. + /// Value is max number of bytes to dump. -1 disables tracing. + // 0 only traces the info but no actual data bytes + k_ESteamNetworkingConfig_PacketTraceMaxBytes = 41, + + + // [global int32] Global UDP token bucket rate limits. + // "Rate" refers to the steady state rate. (Bytes/sec, the + // rate that tokens are put into the bucket.) "Burst" + // refers to the max amount that could be sent in a single + // burst. (In bytes, the max capacity of the bucket.) + // Rate=0 disables the limiter entirely, which is the default. + // Burst=0 disables burst. (This is not realistic. A + // burst of at least 4K is recommended; the default is higher.) + k_ESteamNetworkingConfig_FakeRateLimit_Send_Rate = 42, + k_ESteamNetworkingConfig_FakeRateLimit_Send_Burst = 43, + k_ESteamNetworkingConfig_FakeRateLimit_Recv_Rate = 44, + k_ESteamNetworkingConfig_FakeRateLimit_Recv_Burst = 45, + +// +// Callbacks +// + + // On Steam, you may use the default Steam callback dispatch mechanism. If you prefer + // to not use this dispatch mechanism (or you are not running with Steam), or you want + // to associate specific functions with specific listen sockets or connections, you can + // register them as configuration values. + // + // Note also that ISteamNetworkingUtils has some helpers to set these globally. + + /// [connection FnSteamNetConnectionStatusChanged] Callback that will be invoked + /// when the state of a connection changes. + /// + /// IMPORTANT: callbacks are dispatched to the handler that is in effect at the time + /// the event occurs, which might be in another thread. For example, immediately after + /// creating a listen socket, you may receive an incoming connection. And then immediately + /// after this, the remote host may close the connection. All of this could happen + /// before the function to create the listen socket has returned. For this reason, + /// callbacks usually must be in effect at the time of object creation. This means + /// you should set them when you are creating the listen socket or connection, or have + /// them in effect so they will be inherited at the time of object creation. + /// + /// For example: + /// + /// exterm void MyStatusChangedFunc( SteamNetConnectionStatusChangedCallback_t *info ); + /// SteamNetworkingConfigValue_t opt; opt.SetPtr( k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, MyStatusChangedFunc ); + /// SteamNetworkingIPAddr localAddress; localAddress.Clear(); + /// HSteamListenSocket hListenSock = SteamNetworkingSockets()->CreateListenSocketIP( localAddress, 1, &opt ); + /// + /// When accepting an incoming connection, there is no atomic way to switch the + /// callback. However, if the connection is DOA, AcceptConnection() will fail, and + /// you can fetch the state of the connection at that time. + /// + /// If all connections and listen sockets can use the same callback, the simplest + /// method is to set it globally before you create any listen sockets or connections. + k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged = 201, + + /// [global FnSteamNetAuthenticationStatusChanged] Callback that will be invoked + /// when our auth state changes. If you use this, install the callback before creating + /// any connections or listen sockets, and don't change it. + /// See: ISteamNetworkingUtils::SetGlobalCallback_SteamNetAuthenticationStatusChanged + k_ESteamNetworkingConfig_Callback_AuthStatusChanged = 202, + + /// [global FnSteamRelayNetworkStatusChanged] Callback that will be invoked + /// when our auth state changes. If you use this, install the callback before creating + /// any connections or listen sockets, and don't change it. + /// See: ISteamNetworkingUtils::SetGlobalCallback_SteamRelayNetworkStatusChanged + k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged = 203, + + /// [global FnSteamNetworkingMessagesSessionRequest] Callback that will be invoked + /// when a peer wants to initiate a SteamNetworkingMessagesSessionRequest. + /// See: ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionRequest + k_ESteamNetworkingConfig_Callback_MessagesSessionRequest = 204, + + /// [global FnSteamNetworkingMessagesSessionFailed] Callback that will be invoked + /// when a session you have initiated, or accepted either fails to connect, or loses + /// connection in some unexpected way. + /// See: ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionFailed + k_ESteamNetworkingConfig_Callback_MessagesSessionFailed = 205, + + /// [global FnSteamNetworkingSocketsCreateConnectionSignaling] Callback that will + /// be invoked when we need to create a signaling object for a connection + /// initiated locally. See: ISteamNetworkingSockets::ConnectP2P, + /// ISteamNetworkingMessages. + k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling = 206, + + /// [global FnSteamNetworkingFakeIPResult] Callback that's invoked when + /// a FakeIP allocation finishes. See: ISteamNetworkingSockets::BeginAsyncRequestFakeIP, + /// ISteamNetworkingUtils::SetGlobalCallback_FakeIPResult + k_ESteamNetworkingConfig_Callback_FakeIPResult = 207, + +// +// P2P connection settings +// + +// /// [listen socket int32] When you create a P2P listen socket, we will automatically +// /// open up a UDP port to listen for LAN connections. LAN connections can be made +// /// without any signaling: both sides can be disconnected from the Internet. +// /// +// /// This value can be set to zero to disable the feature. +// k_ESteamNetworkingConfig_P2P_Discovery_Server_LocalPort = 101, +// +// /// [connection int32] P2P connections can perform broadcasts looking for the peer +// /// on the LAN. +// k_ESteamNetworkingConfig_P2P_Discovery_Client_RemotePort = 102, + + /// [connection string] Comma-separated list of STUN servers that can be used + /// for NAT piercing. If you set this to an empty string, NAT piercing will + /// not be attempted. Also if "public" candidates are not allowed for + /// P2P_Transport_ICE_Enable, then this is ignored. + k_ESteamNetworkingConfig_P2P_STUN_ServerList = 103, + + /// [connection int32] What types of ICE candidates to share with the peer. + /// See k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_xxx values + k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable = 104, + + /// [connection int32] When selecting P2P transport, add various + /// penalties to the scores for selected transports. (Route selection + /// scores are on a scale of milliseconds. The score begins with the + /// route ping time and is then adjusted.) + k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty = 105, + k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty = 106, + k_ESteamNetworkingConfig_P2P_TURN_ServerList = 107, + k_ESteamNetworkingConfig_P2P_TURN_UserList = 108, + k_ESteamNetworkingConfig_P2P_TURN_PassList = 109, + //k_ESteamNetworkingConfig_P2P_Transport_LANBeacon_Penalty = 107, + k_ESteamNetworkingConfig_P2P_Transport_ICE_Implementation = 110, + +// +// Settings for SDR relayed connections +// + + /// [int32 global] If the first N pings to a port all fail, mark that port as unavailable for + /// a while, and try a different one. Some ISPs and routers may drop the first + /// packet, so setting this to 1 may greatly disrupt communications. + k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFailInitial = 19, + + /// [int32 global] If N consecutive pings to a port fail, after having received successful + /// communication, mark that port as unavailable for a while, and try a + /// different one. + k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFail = 20, + + /// [int32 global] Minimum number of lifetime pings we need to send, before we think our estimate + /// is solid. The first ping to each cluster is very often delayed because of NAT, + /// routers not having the best route, etc. Until we've sent a sufficient number + /// of pings, our estimate is often inaccurate. Keep pinging until we get this + /// many pings. + k_ESteamNetworkingConfig_SDRClient_MinPingsBeforePingAccurate = 21, + + /// [int32 global] Set all steam datagram traffic to originate from the same + /// local port. By default, we open up a new UDP socket (on a different local + /// port) for each relay. This is slightly less optimal, but it works around + /// some routers that don't implement NAT properly. If you have intermittent + /// problems talking to relays that might be NAT related, try toggling + /// this flag + k_ESteamNetworkingConfig_SDRClient_SingleSocket = 22, + + /// [global string] Code of relay cluster to force use. If not empty, we will + /// only use relays in that cluster. E.g. 'iad' + k_ESteamNetworkingConfig_SDRClient_ForceRelayCluster = 29, + + /// [connection string] For debugging, generate our own (unsigned) ticket, using + /// the specified gameserver address. Router must be configured to accept unsigned + /// tickets. + k_ESteamNetworkingConfig_SDRClient_DebugTicketAddress = 30, + + /// [global string] For debugging. Override list of relays from the config with + /// this set (maybe just one). Comma-separated list. + k_ESteamNetworkingConfig_SDRClient_ForceProxyAddr = 31, + + /// [global string] For debugging. Force ping times to clusters to be the specified + /// values. A comma separated list of = values. E.g. "sto=32,iad=100" + /// + /// This is a dev configuration value, you probably should not let users modify it + /// in production. + k_ESteamNetworkingConfig_SDRClient_FakeClusterPing = 36, + +// +// Log levels for debugging information of various subsystems. +// Higher numeric values will cause more stuff to be printed. +// See ISteamNetworkingUtils::SetDebugOutputFunction for more +// information +// +// The default for all values is k_ESteamNetworkingSocketsDebugOutputType_Warning. +// + k_ESteamNetworkingConfig_LogLevel_AckRTT = 13, // [connection int32] RTT calculations for inline pings and replies + k_ESteamNetworkingConfig_LogLevel_PacketDecode = 14, // [connection int32] log SNP packets send/recv + k_ESteamNetworkingConfig_LogLevel_Message = 15, // [connection int32] log each message send/recv + k_ESteamNetworkingConfig_LogLevel_PacketGaps = 16, // [connection int32] dropped packets + k_ESteamNetworkingConfig_LogLevel_P2PRendezvous = 17, // [connection int32] P2P rendezvous messages + k_ESteamNetworkingConfig_LogLevel_SDRRelayPings = 18, // [global int32] Ping relays + + + // Deleted, do not use + k_ESteamNetworkingConfig_DELETED_EnumerateDevVars = 35, + + k_ESteamNetworkingConfigValue__Force32Bit = 0x7fffffff +}; + +// Bitmask of types to share +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Default = -1; // Special value - use user defaults +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Disable = 0; // Do not do any ICE work at all or share any IP addresses with peer +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Relay = 1; // Relayed connection via TURN server. +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Private = 2; // host addresses that appear to be link-local or RFC1918 addresses +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Public = 4; // STUN reflexive addresses, or host address that isn't a "private" address +const int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_All = 0x7fffffff; + +/// In a few places we need to set configuration options on listen sockets and connections, and +/// have them take effect *before* the listen socket or connection really starts doing anything. +/// Creating the object and then setting the options "immediately" after creation doesn't work +/// completely, because network packets could be received between the time the object is created and +/// when the options are applied. To set options at creation time in a reliable way, they must be +/// passed to the creation function. This structure is used to pass those options. +/// +/// For the meaning of these fields, see ISteamNetworkingUtils::SetConfigValue. Basically +/// when the object is created, we just iterate over the list of options and call +/// ISteamNetworkingUtils::SetConfigValueStruct, where the scope arguments are supplied by the +/// object being created. +struct SteamNetworkingConfigValue_t +{ + /// Which option is being set + ESteamNetworkingConfigValue m_eValue; + + /// Which field below did you fill in? + ESteamNetworkingConfigDataType m_eDataType; + + /// Option value + union + { + int32_t m_int32; + int64_t m_int64; + float m_float; + const char *m_string; // Points to your '\0'-terminated buffer + void *m_ptr; + } m_val; + + // + // Shortcut helpers to set the type and value in a single call + // + inline void SetInt32( ESteamNetworkingConfigValue eVal, int32_t data ) + { + m_eValue = eVal; + m_eDataType = k_ESteamNetworkingConfig_Int32; + m_val.m_int32 = data; + } + inline void SetInt64( ESteamNetworkingConfigValue eVal, int64_t data ) + { + m_eValue = eVal; + m_eDataType = k_ESteamNetworkingConfig_Int64; + m_val.m_int64 = data; + } + inline void SetFloat( ESteamNetworkingConfigValue eVal, float data ) + { + m_eValue = eVal; + m_eDataType = k_ESteamNetworkingConfig_Float; + m_val.m_float = data; + } + inline void SetPtr( ESteamNetworkingConfigValue eVal, void *data ) + { + m_eValue = eVal; + m_eDataType = k_ESteamNetworkingConfig_Ptr; + m_val.m_ptr = data; + } + inline void SetString( ESteamNetworkingConfigValue eVal, const char *data ) // WARNING - Just saves your pointer. Does NOT make a copy of the string + { + m_eValue = eVal; + m_eDataType = k_ESteamNetworkingConfig_Ptr; + m_val.m_string = data; + } +}; + +/// Return value of ISteamNetworkintgUtils::GetConfigValue +enum ESteamNetworkingGetConfigValueResult +{ + k_ESteamNetworkingGetConfigValue_BadValue = -1, // No such configuration value + k_ESteamNetworkingGetConfigValue_BadScopeObj = -2, // Bad connection handle, etc + k_ESteamNetworkingGetConfigValue_BufferTooSmall = -3, // Couldn't fit the result in your buffer + k_ESteamNetworkingGetConfigValue_OK = 1, + k_ESteamNetworkingGetConfigValue_OKInherited = 2, // A value was not set at this level, but the effective (inherited) value was returned. + + k_ESteamNetworkingGetConfigValueResult__Force32Bit = 0x7fffffff +}; + +// +// Debug output +// + +/// Detail level for diagnostic output callback. +/// See ISteamNetworkingUtils::SetDebugOutputFunction +enum ESteamNetworkingSocketsDebugOutputType +{ + k_ESteamNetworkingSocketsDebugOutputType_None = 0, + k_ESteamNetworkingSocketsDebugOutputType_Bug = 1, // You used the API incorrectly, or an internal error happened + k_ESteamNetworkingSocketsDebugOutputType_Error = 2, // Run-time error condition that isn't the result of a bug. (E.g. we are offline, cannot bind a port, etc) + k_ESteamNetworkingSocketsDebugOutputType_Important = 3, // Nothing is wrong, but this is an important notification + k_ESteamNetworkingSocketsDebugOutputType_Warning = 4, + k_ESteamNetworkingSocketsDebugOutputType_Msg = 5, // Recommended amount + k_ESteamNetworkingSocketsDebugOutputType_Verbose = 6, // Quite a bit + k_ESteamNetworkingSocketsDebugOutputType_Debug = 7, // Practically everything + k_ESteamNetworkingSocketsDebugOutputType_Everything = 8, // Wall of text, detailed packet contents breakdown, etc + + k_ESteamNetworkingSocketsDebugOutputType__Force32Bit = 0x7fffffff +}; + +/// Setup callback for debug output, and the desired verbosity you want. +typedef void (*FSteamNetworkingSocketsDebugOutput)( ESteamNetworkingSocketsDebugOutputType nType, const char *pszMsg ); + +// +// Valve data centers +// + +/// Convert 3- or 4-character ID to 32-bit int. +inline SteamNetworkingPOPID CalculateSteamNetworkingPOPIDFromString( const char *pszCode ) +{ + // OK we made a bad decision when we decided how to pack 3-character codes into a uint32. We'd like to support + // 4-character codes, but we don't want to break compatibility. The migration path has some subtleties that make + // this nontrivial, and there are already some IDs stored in SQL. Ug, so the 4 character code "abcd" will + // be encoded with the digits like "0xddaabbcc". + // + // Also: we don't currently use 1- or 2-character codes, but if ever do in the future, let's make sure don't read + // past the end of the string and access uninitialized memory. (And if the string is empty, we always want + // to return 0 and not read bytes past the '\0'.) + // + // There is also extra paranoia to make sure the bytes are not treated as signed. + SteamNetworkingPOPID result = (uint32)(uint8)pszCode[0] << 16U; + if ( pszCode[1] ) + { + result |= ( (uint32)(uint8)pszCode[1] << 8U ); + if ( pszCode[2] ) + { + result |= (uint32)(uint8)pszCode[2] | ( (uint32)(uint8)pszCode[3] << 24U ); + } + } + return result; +} + +/// Unpack integer to string representation, including terminating '\0' +/// +/// See also SteamNetworkingPOPIDRender +template +inline void GetSteamNetworkingLocationPOPStringFromID( SteamNetworkingPOPID id, char (&szCode)[N] ) +{ +#if !defined( __GNUC__ ) || __GNUC__ >= 5 + static_assert( N >= 5, "Fixed-size buffer not big enough to hold SDR POP ID" ); +#endif + szCode[0] = char( id >> 16U ); + szCode[1] = char( id >> 8U ); + szCode[2] = char( id ); + szCode[3] = char( id >> 24U ); // See comment above about deep regret and sadness + szCode[4] = 0; +} + +/// The POPID "dev" is used in non-production environments for testing. +const SteamNetworkingPOPID k_SteamDatagramPOPID_dev = ( (uint32)'d' << 16U ) | ( (uint32)'e' << 8U ) | (uint32)'v'; + +#ifndef API_GEN + +/// Utility class for printing a SteamNetworkingPOPID. +struct SteamNetworkingPOPIDRender +{ + SteamNetworkingPOPIDRender( SteamNetworkingPOPID x ) { GetSteamNetworkingLocationPOPStringFromID( x, buf ); } + inline const char *c_str() const { return buf; } +private: + char buf[ 8 ]; +}; + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Internal stuff +#ifndef API_GEN + +// For code compatibility +typedef SteamNetworkingMessage_t ISteamNetworkingMessage; +typedef SteamNetworkingErrMsg SteamDatagramErrMsg; + +inline void SteamNetworkingIPAddr::Clear() { memset( this, 0, sizeof(*this) ); } +inline bool SteamNetworkingIPAddr::IsIPv6AllZeros() const { const uint64 *q = (const uint64 *)m_ipv6; return q[0] == 0 && q[1] == 0; } +inline void SteamNetworkingIPAddr::SetIPv6( const uint8 *ipv6, uint16 nPort ) { memcpy( m_ipv6, ipv6, 16 ); m_port = nPort; } +inline void SteamNetworkingIPAddr::SetIPv4( uint32 nIP, uint16 nPort ) { m_ipv4.m_8zeros = 0; m_ipv4.m_0000 = 0; m_ipv4.m_ffff = 0xffff; m_ipv4.m_ip[0] = uint8(nIP>>24); m_ipv4.m_ip[1] = uint8(nIP>>16); m_ipv4.m_ip[2] = uint8(nIP>>8); m_ipv4.m_ip[3] = uint8(nIP); m_port = nPort; } +inline bool SteamNetworkingIPAddr::IsIPv4() const { return m_ipv4.m_8zeros == 0 && m_ipv4.m_0000 == 0 && m_ipv4.m_ffff == 0xffff; } +inline uint32 SteamNetworkingIPAddr::GetIPv4() const { return IsIPv4() ? ( (uint32(m_ipv4.m_ip[0])<<24) | (uint32(m_ipv4.m_ip[1])<<16) | (uint32(m_ipv4.m_ip[2])<<8) | uint32(m_ipv4.m_ip[3]) ) : 0; } +inline void SteamNetworkingIPAddr::SetIPv6LocalHost( uint16 nPort ) { m_ipv4.m_8zeros = 0; m_ipv4.m_0000 = 0; m_ipv4.m_ffff = 0; m_ipv6[12] = 0; m_ipv6[13] = 0; m_ipv6[14] = 0; m_ipv6[15] = 1; m_port = nPort; } +inline bool SteamNetworkingIPAddr::IsLocalHost() const { return ( m_ipv4.m_8zeros == 0 && m_ipv4.m_0000 == 0 && m_ipv4.m_ffff == 0 && m_ipv6[12] == 0 && m_ipv6[13] == 0 && m_ipv6[14] == 0 && m_ipv6[15] == 1 ) || ( GetIPv4() == 0x7f000001 ); } +inline bool SteamNetworkingIPAddr::operator==(const SteamNetworkingIPAddr &x ) const { return memcmp( this, &x, sizeof(SteamNetworkingIPAddr) ) == 0; } + +inline void SteamNetworkingIdentity::Clear() { memset( this, 0, sizeof(*this) ); } +inline bool SteamNetworkingIdentity::IsInvalid() const { return m_eType == k_ESteamNetworkingIdentityType_Invalid; } +inline void SteamNetworkingIdentity::SetSteamID( CSteamID steamID ) { SetSteamID64( steamID.ConvertToUint64() ); } +inline CSteamID SteamNetworkingIdentity::GetSteamID() const { return CSteamID( GetSteamID64() ); } +inline void SteamNetworkingIdentity::SetSteamID64( uint64 steamID ) { m_eType = k_ESteamNetworkingIdentityType_SteamID; m_cbSize = sizeof( m_steamID64 ); m_steamID64 = steamID; } +inline uint64 SteamNetworkingIdentity::GetSteamID64() const { return m_eType == k_ESteamNetworkingIdentityType_SteamID ? m_steamID64 : 0; } +inline bool SteamNetworkingIdentity::SetXboxPairwiseID( const char *pszString ) { size_t l = strlen( pszString ); if ( l < 1 || l >= sizeof(m_szXboxPairwiseID) ) return false; + m_eType = k_ESteamNetworkingIdentityType_XboxPairwiseID; m_cbSize = int(l+1); memcpy( m_szXboxPairwiseID, pszString, m_cbSize ); return true; } +inline const char *SteamNetworkingIdentity::GetXboxPairwiseID() const { return m_eType == k_ESteamNetworkingIdentityType_XboxPairwiseID ? m_szXboxPairwiseID : NULL; } +inline void SteamNetworkingIdentity::SetPSNID( uint64 id ) { m_eType = k_ESteamNetworkingIdentityType_SonyPSN; m_cbSize = sizeof( m_PSNID ); m_PSNID = id; } +inline uint64 SteamNetworkingIdentity::GetPSNID() const { return m_eType == k_ESteamNetworkingIdentityType_SonyPSN ? m_PSNID : 0; } +inline void SteamNetworkingIdentity::SetStadiaID( uint64 id ) { m_eType = k_ESteamNetworkingIdentityType_GoogleStadia; m_cbSize = sizeof( m_stadiaID ); m_stadiaID = id; } +inline uint64 SteamNetworkingIdentity::GetStadiaID() const { return m_eType == k_ESteamNetworkingIdentityType_GoogleStadia ? m_stadiaID : 0; } +inline void SteamNetworkingIdentity::SetIPAddr( const SteamNetworkingIPAddr &addr ) { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip = addr; } +inline const SteamNetworkingIPAddr *SteamNetworkingIdentity::GetIPAddr() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? &m_ip : NULL; } +inline void SteamNetworkingIdentity::SetIPv4Addr( uint32 nIPv4, uint16 nPort ) { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip.SetIPv4( nIPv4, nPort ); } +inline uint32 SteamNetworkingIdentity::GetIPv4() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? m_ip.GetIPv4() : 0; } +inline ESteamNetworkingFakeIPType SteamNetworkingIdentity::GetFakeIPType() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? m_ip.GetFakeIPType() : k_ESteamNetworkingFakeIPType_Invalid; } +inline void SteamNetworkingIdentity::SetLocalHost() { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip.SetIPv6LocalHost(); } +inline bool SteamNetworkingIdentity::IsLocalHost() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress && m_ip.IsLocalHost(); } +inline bool SteamNetworkingIdentity::SetGenericString( const char *pszString ) { size_t l = strlen( pszString ); if ( l >= sizeof(m_szGenericString) ) return false; + m_eType = k_ESteamNetworkingIdentityType_GenericString; m_cbSize = int(l+1); memcpy( m_szGenericString, pszString, m_cbSize ); return true; } +inline const char *SteamNetworkingIdentity::GetGenericString() const { return m_eType == k_ESteamNetworkingIdentityType_GenericString ? m_szGenericString : NULL; } +inline bool SteamNetworkingIdentity::SetGenericBytes( const void *data, size_t cbLen ) { if ( cbLen > sizeof(m_genericBytes) ) return false; + m_eType = k_ESteamNetworkingIdentityType_GenericBytes; m_cbSize = int(cbLen); memcpy( m_genericBytes, data, m_cbSize ); return true; } +inline const uint8 *SteamNetworkingIdentity::GetGenericBytes( int &cbLen ) const { if ( m_eType != k_ESteamNetworkingIdentityType_GenericBytes ) return NULL; + cbLen = m_cbSize; return m_genericBytes; } +inline bool SteamNetworkingIdentity::operator==(const SteamNetworkingIdentity &x ) const { return m_eType == x.m_eType && m_cbSize == x.m_cbSize && memcmp( m_genericBytes, x.m_genericBytes, m_cbSize ) == 0; } +inline void SteamNetworkingMessage_t::Release() { (*m_pfnRelease)( this ); } + +#endif // #ifndef API_GEN + +#endif // #ifndef STEAMNETWORKINGTYPES diff --git a/public/steam/steamps3params.h b/public/steam/steamps3params.h new file mode 100644 index 00000000..c0741b4b --- /dev/null +++ b/public/steam/steamps3params.h @@ -0,0 +1,112 @@ +//====== Copyright 1996-2008, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#ifndef STEAMPS3PARAMS_H +#define STEAMPS3PARAMS_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +// PlayStation 3 initialization parameters +// +// The following structure must be passed to when loading steam_api_ps3.prx +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +#define STEAM_PS3_PATH_MAX 1055 +#define STEAM_PS3_SERVICE_ID_MAX 32 +#define STEAM_PS3_COMMUNICATION_ID_MAX 10 +#define STEAM_PS3_COMMUNICATION_SIG_MAX 160 +#define STEAM_PS3_LANGUAGE_MAX 64 +#define STEAM_PS3_REGION_CODE_MAX 16 +#define STEAM_PS3_CURRENT_PARAMS_VER 2 +struct SteamPS3Params_t +{ + uint32 m_unVersion; // set to STEAM_PS3_CURRENT_PARAMS_VER + + void *pReserved; + uint32 m_nAppId; // set to your game's appid + + char m_rgchInstallationPath[ STEAM_PS3_PATH_MAX ]; // directory containing latest steam prx's and sdata. Can be read only (BDVD) + char m_rgchSystemCache[ STEAM_PS3_PATH_MAX ]; // temp working cache, not persistent + char m_rgchGameData[ STEAM_PS3_PATH_MAX ]; // persistent game data path for storing user data + char m_rgchNpServiceID[ STEAM_PS3_SERVICE_ID_MAX ]; + char m_rgchNpCommunicationID[ STEAM_PS3_COMMUNICATION_ID_MAX ]; + char m_rgchNpCommunicationSig[ STEAM_PS3_COMMUNICATION_SIG_MAX ]; + + // Language should be one of the following. must be zero terminated + // danish + // dutch + // english + // finnish + // french + // german + // italian + // korean + // norwegian + // polish + // portuguese + // russian + // schinese + // spanish + // swedish + // tchinese + char m_rgchSteamLanguage[ STEAM_PS3_LANGUAGE_MAX ]; + + // region codes are "SCEA", "SCEE", "SCEJ". must be zero terminated + char m_rgchRegionCode[ STEAM_PS3_REGION_CODE_MAX ]; + + // Should be SYS_TTYP3 through SYS_TTYP10, if it's 0 then Steam won't spawn a + // thread to read console input at all. Using this let's you use Steam console commands + // like: profile_on, profile_off, profile_dump, mem_stats, mem_validate. + unsigned int m_cSteamInputTTY; + + struct Ps3netInit_t + { + bool m_bNeedInit; + void *m_pMemory; + int m_nMemorySize; + int m_flags; + } m_sysNetInitInfo; + + struct Ps3jpgInit_t + { + bool m_bNeedInit; + } m_sysJpgInitInfo; + + struct Ps3pngInit_t + { + bool m_bNeedInit; + } m_sysPngInitInfo; + + struct Ps3sysutilUserInfo_t + { + bool m_bNeedInit; + } m_sysSysUtilUserInfo; + + bool m_bIncludeNewsPage; +}; + + +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +// PlayStation 3 memory structure +//----------------------------------------------------------------------------------------------------------------------------------------------------------// +#define STEAMPS3_MALLOC_INUSE 0x53D04A51 +#define STEAMPS3_MALLOC_SYSTEM 0x0D102C48 +#define STEAMPS3_MALLOC_OK 0xFFD04A51 +struct SteamPS3Memory_t +{ + bool m_bSingleAllocation; // If true, Steam will request one 6MB allocation and use the returned memory for all future allocations + // If false, Steam will make call malloc for each allocation + + // required function pointers + void* (*m_pfMalloc)(size_t); + void* (*m_pfRealloc)(void *, size_t); + void (*m_pfFree)(void *); + size_t (*m_pUsable_size)(void*); +}; + + +#endif // STEAMPS3PARAMS_H diff --git a/public/steam/steamtypes.h b/public/steam/steamtypes.h index 22ce3e61..7b604345 100644 --- a/public/steam/steamtypes.h +++ b/public/steam/steamtypes.h @@ -17,26 +17,31 @@ typedef unsigned char uint8; #endif -#if defined( __GNUC__ ) && !defined(POSIX) +#if defined( __GNUC__ ) && !defined(_WIN32) && !defined(POSIX) #if __GNUC__ < 4 #error "Steamworks requires GCC 4.X (4.2 or 4.4 have been tested)" #endif #define POSIX 1 #endif -#if defined(__x86_64__) || defined(_WIN64) +#if defined(__LP64__) || defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) || defined(__s390x__) #define X64BITS #endif +#if !defined(VALVE_BIG_ENDIAN) +#if defined(_PS3) // Make sure VALVE_BIG_ENDIAN gets set on PS3, may already be set previously in Valve internal code. -#if !defined(VALVE_BIG_ENDIAN) && defined(_PS3) -#define VALVE_BIG_ENDIAN +#define VALVE_BIG_ENDIAN 1 +#endif +#if defined( __GNUC__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define VALVE_BIG_ENDIAN 1 +#endif #endif typedef unsigned char uint8; typedef signed char int8; -#if defined( _WIN32 ) +#if defined( _WIN32 ) && !defined( __GNUC__ ) typedef __int16 int16; typedef unsigned __int16 uint16; @@ -84,96 +89,100 @@ typedef unsigned int uintp; #endif // else _WIN32 -#ifdef __clang__ -# define CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) -#else -# define CLANG_ATTR(ATTR) -#endif - -#define METHOD_DESC(DESC) CLANG_ATTR( "desc:" #DESC ";" ) -#define IGNOREATTR() CLANG_ATTR( "ignore" ) -#define OUT_STRUCT() CLANG_ATTR( "out_struct: ;" ) -#define OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define OUT_ARRAY_COUNT(COUNTER, DESC) CLANG_ATTR( "out_array_count:" #COUNTER ";desc:" #DESC ) -#define ARRAY_COUNT(COUNTER) CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define ARRAY_COUNT_D(COUNTER, DESC) CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define BUFFER_COUNT(COUNTER) CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define OUT_BUFFER_COUNT(COUNTER) CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define OUT_STRING_COUNT(COUNTER) CLANG_ATTR( "out_string_count:" #COUNTER ";" ) -#define DESC(DESC) CLANG_ATTR("desc:" #DESC ";") - - -const int k_cubSaltSize = 8; -typedef uint8 Salt_t[ k_cubSaltSize ]; - -//----------------------------------------------------------------------------- -// GID (GlobalID) stuff -// This is a globally unique identifier. It's guaranteed to be unique across all -// racks and servers for as long as a given universe persists. -//----------------------------------------------------------------------------- -// NOTE: for GID parsing/rendering and other utils, see gid.h -typedef uint64 GID_t; - -const GID_t k_GIDNil = 0xffffffffffffffffull; - -// For convenience, we define a number of types that are just new names for GIDs -typedef uint64 JobID_t; // Each Job has a unique ID -typedef GID_t TxnID_t; // Each financial transaction has a unique ID - -const GID_t k_TxnIDNil = k_GIDNil; -const GID_t k_TxnIDUnknown = 0; - -const JobID_t k_JobIDNil = 0xffffffffffffffffull; - -// this is baked into client messages and interfaces as an int, -// make sure we never break this. -typedef uint32 PackageId_t; -const PackageId_t k_uPackageIdFreeSub = 0x0; -const PackageId_t k_uPackageIdInvalid = 0xFFFFFFFF; - -typedef uint32 BundleId_t; -const BundleId_t k_uBundleIdInvalid = 0; - -// this is baked into client messages and interfaces as an int, -// make sure we never break this. typedef uint32 AppId_t; const AppId_t k_uAppIdInvalid = 0x0; -typedef uint64 AssetClassId_t; -const AssetClassId_t k_ulAssetClassIdInvalid = 0x0; - -typedef uint32 PhysicalItemId_t; -const PhysicalItemId_t k_uPhysicalItemIdInvalid = 0x0; - - -// this is baked into client messages and interfaces as an int, -// make sure we never break this. AppIds and DepotIDs also presently -// share the same namespace, but since we'd like to change that in the future -// I've defined it seperately here. +// AppIds and DepotIDs also presently share the same namespace typedef uint32 DepotId_t; const DepotId_t k_uDepotIdInvalid = 0x0; -// RTime32 -// We use this 32 bit time representing real world time. -// It offers 1 second resolution beginning on January 1, 1970 (Unix time) +// RTime32. Seconds elapsed since Jan 1 1970, i.e. unix timestamp. +// It's the same as time_t, but it is always 32-bit and unsigned. typedef uint32 RTime32; -typedef uint32 CellID_t; -const CellID_t k_uCellIDInvalid = 0xFFFFFFFF; - // handle to a Steam API call typedef uint64 SteamAPICall_t; const SteamAPICall_t k_uAPICallInvalid = 0x0; typedef uint32 AccountID_t; -typedef uint32 PartnerId_t; -const PartnerId_t k_uPartnerIdInvalid = 0; - -// ID for a depot content manifest -typedef uint64 ManifestId_t; -const ManifestId_t k_uManifestIdInvalid = 0; - - +// Party Beacon ID +typedef uint64 PartyBeaconID_t; +const PartyBeaconID_t k_ulPartyBeaconIdInvalid = 0; + +enum ESteamIPType +{ + k_ESteamIPTypeIPv4 = 0, + k_ESteamIPTypeIPv6 = 1, +}; + +#pragma pack( push, 1 ) + +struct SteamIPAddress_t +{ + union { + + uint32 m_unIPv4; // Host order + uint8 m_rgubIPv6[16]; // Network order! Same as inaddr_in6. (0011:2233:4455:6677:8899:aabb:ccdd:eeff) + + // Internal use only + uint64 m_ipv6Qword[2]; // big endian + }; + + ESteamIPType m_eType; + + bool IsSet() const + { + if ( k_ESteamIPTypeIPv4 == m_eType ) + { + return m_unIPv4 != 0; + } + else + { + return m_ipv6Qword[0] !=0 || m_ipv6Qword[1] != 0; + } + } + + static SteamIPAddress_t IPv4Any() + { + SteamIPAddress_t ipOut; + ipOut.m_eType = k_ESteamIPTypeIPv4; + ipOut.m_unIPv4 = 0; + + return ipOut; + } + + static SteamIPAddress_t IPv6Any() + { + SteamIPAddress_t ipOut; + ipOut.m_eType = k_ESteamIPTypeIPv6; + ipOut.m_ipv6Qword[0] = 0; + ipOut.m_ipv6Qword[1] = 0; + + return ipOut; + } + + static SteamIPAddress_t IPv4Loopback() + { + SteamIPAddress_t ipOut; + ipOut.m_eType = k_ESteamIPTypeIPv4; + ipOut.m_unIPv4 = 0x7f000001; + + return ipOut; + } + + static SteamIPAddress_t IPv6Loopback() + { + SteamIPAddress_t ipOut; + ipOut.m_eType = k_ESteamIPTypeIPv6; + ipOut.m_ipv6Qword[0] = 0; + ipOut.m_ipv6Qword[1] = 0; + ipOut.m_rgubIPv6[15] = 1; + + return ipOut; + } +}; + +#pragma pack( pop ) #endif // STEAMTYPES_H diff --git a/public/steam/steamvr.h b/public/steam/steamvr.h new file mode 100644 index 00000000..be62fc86 --- /dev/null +++ b/public/steam/steamvr.h @@ -0,0 +1,261 @@ +#pragma once + +#include + +namespace vr +{ + +#if defined(__linux__) || defined(__APPLE__) + // The 32-bit version of gcc has the alignment requirement for uint64 and double set to + // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. + // The 64-bit version of gcc has the alignment requirement for these types set to + // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. + // The 64-bit structure packing has to match the 32-bit structure packing for each platform. +#pragma pack( push, 4 ) +#else +#pragma pack( push, 8 ) +#endif + + +// right-handed system +// +y is up +// +x is to the right +// -z is going away from you +// Distance unit is meters +struct HmdMatrix34_t +{ + float m[3][4]; +}; + +struct HmdMatrix44_t +{ + float m[4][4]; +}; + + +/** Used to return the post-distortion UVs for each color channel. +* UVs range from 0 to 1 with 0,0 in the upper left corner of the +* source render target. The 0,0 to 1,1 range covers a single eye. */ +struct DistortionCoordinates_t +{ + float rfRed[2]; + float rfGreen[2]; + float rfBlue[2]; +}; + + +enum Hmd_Eye +{ + Eye_Left = 0, + Eye_Right = 1 +}; + +enum GraphicsAPIConvention +{ + API_DirectX = 0, // Normalized Z goes from 0 at the viewer to 1 at the far clip plane + API_OpenGL = 1, // Normalized Z goes from 1 at the viewer to -1 at the far clip plane +}; + +enum HmdTrackingResult +{ + TrackingResult_Uninitialized = 1, + + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, + + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, +}; + +class IHmd +{ +public: + + + // ------------------------------------ + // Display Methods + // ------------------------------------ + + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + + /** Suggested size for the intermediate render target that the distortion pulls from. */ + virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport( Hmd_Eye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + + /** The projection matrix for the specified eye */ + virtual HmdMatrix44_t GetProjectionMatrix( Hmd_Eye eEye, float fNearZ, float fFarZ, GraphicsAPIConvention eProjType ) = 0; + + /** The components necessary to build your own projection matrix in case your + * application is doing something fancy like infinite Z */ + virtual void GetProjectionRaw( Hmd_Eye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + + /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in + * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */ + virtual DistortionCoordinates_t ComputeDistortion( Hmd_Eye eEye, float fU, float fV ) = 0; + + /** Returns the transform from eye space to the head space. Eye space is the per-eye flavor of head + * space that provides stereo disparity. Instead of Model * View * Projection the sequence is Model * View * Eye^-1 * Projection. + * Normally View and Eye^-1 will be multiplied together and treated as View in your application. + */ + virtual HmdMatrix34_t GetHeadFromEyePose( Hmd_Eye eEye ) = 0; + + /** For use in simple VR apps, this method returns the concatenation of the + * tracking pose and the eye matrix to get a full view matrix for each eye. + * This is ( GetEyeMatrix() ) * (GetWorldFromHeadPose() ^ -1 ) */ + virtual bool GetViewMatrix( float fSecondsFromNow, HmdMatrix44_t *pMatLeftView, HmdMatrix44_t *pMatRightView, HmdTrackingResult *peResult ) = 0; + + /** [D3D9 Only] + * Returns the adapter index that the user should pass into CreateDevice to set up D3D9 in such + * a way that it can go full screen exclusive on the HMD. Returns -1 if there was an error. + */ + virtual int32_t GetD3D9AdapterIndex() = 0; + + /** [D3D10/11 Only] + * Returns the adapter index and output index that the user should pass into EnumAdapters adn EnumOutputs + * to create the device and swap chain in DX10 and DX11. If an error occurs both indices will be set to -1. + */ + virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex ) = 0; + + /** [Windows Only] + * Notifies the system that the VR output will appear in a particular window. + */ + virtual void AttachToWindow( void *hWnd ) = 0; + + // ------------------------------------ + // Tracking Methods + // ------------------------------------ + + /** The pose that the tracker thinks that the HMD will be in at the specified + * number of seconds into the future. Pass 0 to get the current state. + * + * This is roughly analogous to the inverse of the view matrix in most applications, though + * many games will need to do some additional rotation or translation on top of the rotation + * and translation provided by the head pose. + * + * If this function returns true the pose has been populated with a pose that can be used by the application. + * Check peResult for details about the pose, including messages that should be displayed to the user. + */ + virtual bool GetTrackerFromHeadPose( float fPredictedSecondsFromNow, HmdMatrix34_t *pmPose, HmdTrackingResult *peResult ) = 0; + + /** Passes back the pose matrix from the last successful call to GetWorldFromHeadPose(). Returns true if that matrix is + * valid (because there has been a previous successful pose.) */ + virtual bool GetLastTrackerFromHeadPose( HmdMatrix34_t *pmPose ) = 0; + + /** Returns true if the tracker for this HMD will drift the Yaw component of its pose over time regardless of + * actual head motion. This is true for gyro-based trackers with no ground truth. */ + virtual bool WillDriftInYaw() = 0; + + /** Sets the zero pose for the tracker coordinate system. After this call all WorldFromHead poses will be relative + * to the pose whenever this was called. The new zero coordinate system will not change the fact that the Y axis is + * up in the real world, so the next pose returned from GetWorldFromHeadPose after a call to ZeroTracker may not be + * exactly an identity matrix. */ + virtual void ZeroTracker() = 0; + + /** Returns the zero pose for the tracker coordinate system. If the tracker has never had a valid pose, this + * will be an identity matrix. */ + virtual HmdMatrix34_t GetTrackerZeroPose() = 0; + + // ------------------------------------ + // Administrative methods + // ------------------------------------ + + /** The ID of the driver this HMD uses as a UTF-8 string. Returns the length of the ID in bytes. If + * the buffer is not large enough to fit the ID an empty string will be returned. In general, 128 bytes + * will be enough to fit any ID. */ + virtual uint32_t GetDriverId( char *pchBuffer, uint32_t unBufferLen ) = 0; + + /** The ID of this display within its driver this HMD uses as a UTF-8 string. Returns the length of the ID in bytes. If + * the buffer is not large enough to fit the ID an empty string will be returned. In general, 128 bytes + * will be enough to fit any ID. */ + virtual uint32_t GetDisplayId( char *pchBuffer, uint32_t unBufferLen ) = 0; +}; + +static const char * const IHmd_Version = "IHmd_005"; + +/** error codes returned by Vr_Init */ +enum HmdError +{ + HmdError_None = 0, + + HmdError_Init_InstallationNotFound = 100, + HmdError_Init_InstallationCorrupt = 101, + HmdError_Init_VRClientDLLNotFound = 102, + HmdError_Init_FileNotFound = 103, + HmdError_Init_FactoryNotFound = 104, + HmdError_Init_InterfaceNotFound = 105, + HmdError_Init_InvalidInterface = 106, + HmdError_Init_UserConfigDirectoryInvalid = 107, + HmdError_Init_HmdNotFound = 108, + HmdError_Init_NotInitialized = 109, + + HmdError_Driver_Failed = 200, + HmdError_Driver_Unknown = 201, + HmdError_Driver_HmdUnknown = 202, + HmdError_Driver_NotLoaded = 203, + + HmdError_IPC_ServerInitFailed = 300, + HmdError_IPC_ConnectFailed = 301, + HmdError_IPC_SharedStateInitFailed = 302, + + HmdError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + +}; + + +// figure out how to import from the VR API dll +#if defined(_WIN32) + +#ifdef VR_API_EXPORT +#define VR_INTERFACE extern "C" __declspec( dllexport ) +#else +#define VR_INTERFACE extern "C" __declspec( dllimport ) +#endif + +#elif defined(GNUC) || defined(COMPILER_GCC) + +#ifdef VR_API_EXPORT +#define VR_INTERFACE extern "C" __attribute__((visibility("default"))) +#else +#define VR_INTERFACE extern "C" +#endif + +#else +#error "Unsupported Platform." +#endif + + + + +/** Finds the active installation of the VR API and initializes it. The priority for figuring +* out where to load vrclient from are: +* 1. The convar "VR_OVERRIDE", which should contain an absolute path to the root of +* an vr API directory. +* 2. The pchVROverride argument. This should be an absolute path or a path relative to +* the current executable. +* 3. The path "./vr" relative to the current executable's path. +* +* Each of these paths are to the "root" of the VR API install. That's the directory with +* the "drivers" directory and a platform (i.e. "win32") directory in it, not the directory with the DLL itself. +*/ +VR_INTERFACE IHmd *VR_Init( HmdError *peError ); + +/** unloads vrclient.dll. Any interface pointers from the interface are +* invalid after this point */ +VR_INTERFACE void VR_Shutdown( ); + +/** Returns true if there is an HMD attached. This check is as lightweight as possible and +* can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants +* to know if initializing VR is a possibility but isn't ready to take that step yet. +*/ +VR_INTERFACE bool VR_IsHmdPresent(); + +/** Returns the string version of an HMD error. This function may be called outside of VR_Init()/VR_Shutdown(). */ +VR_INTERFACE const char *VR_GetStringForHmdError( HmdError error ); + +#pragma pack( pop ) + + +} \ No newline at end of file diff --git a/public/studio.cpp b/public/studio.cpp index bf6fdb7d..eade3ef9 100644 --- a/public/studio.cpp +++ b/public/studio.cpp @@ -575,7 +575,7 @@ int studiohdr_t::GetActivityListVersion( void ) Assert( pStudioHdr ); - version = min( version, pStudioHdr->activitylistversion ); + version = MIN( version, pStudioHdr->activitylistversion ); } return version; @@ -920,16 +920,6 @@ mstudioseqdesc_t &CStudioHdr::pSeqdesc( int i ) Assert( ( i >= 0 && i < GetNumSeq() ) || ( i == 1 && GetNumSeq() <= 1 ) ); if ( i < 0 || i >= GetNumSeq() ) { - if ( GetNumSeq() <= 0 ) - { - // Return a zero'd out struct reference if we've got nothing. - // C_BaseObject::StopAnimGeneratedSounds was crashing due to this function - // returning a reference to garbage. It should now see numevents is 0, - // and bail. - static mstudioseqdesc_t s_nil_seq; - return s_nil_seq; - } - // Avoid reading random memory. i = 0; } @@ -1036,10 +1026,9 @@ int CStudioHdr::GetSharedPoseParameter( int iSequence, int iLocalPose ) const Assert( m_pVModel ); - int group = m_pVModel->m_seq[iSequence].group; - virtualgroup_t *pGroup = m_pVModel->m_group.IsValidIndex( group ) ? &m_pVModel->m_group[ group ] : NULL; + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[iSequence].group ]; - return pGroup ? pGroup->masterPose[iLocalPose] : iLocalPose; + return pGroup->masterPose[iLocalPose]; } @@ -1218,7 +1207,7 @@ int CStudioHdr::GetActivityListVersion( void ) { const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); Assert( pStudioHdr ); - version = min( version, pStudioHdr->activitylistversion ); + version = MIN( version, pStudioHdr->activitylistversion ); } return version; @@ -1261,7 +1250,7 @@ int CStudioHdr::GetEventListVersion( void ) { const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); Assert( pStudioHdr ); - version = min( version, pStudioHdr->eventsindexed ); + version = MIN( version, pStudioHdr->eventsindexed ); } return version; @@ -1426,8 +1415,8 @@ void CStudioHdr::RunFlexRules( const float *src, float *dest ) k--; break; case STUDIO_NEG: stack[k-1] = -stack[k-1]; break; - case STUDIO_MAX: stack[k-2] = max( stack[k-2], stack[k-1] ); k--; break; - case STUDIO_MIN: stack[k-2] = min( stack[k-2], stack[k-1] ); k--; break; + case STUDIO_MAX: stack[k-2] = MAX( stack[k-2], stack[k-1] ); k--; break; + case STUDIO_MIN: stack[k-2] = MIN( stack[k-2], stack[k-1] ); k--; break; case STUDIO_CONST: stack[k] = pops->d.value; k++; break; case STUDIO_FETCH1: { @@ -1614,7 +1603,6 @@ void CStudioHdr::RunFlexRules( const float *src, float *dest ) //----------------------------------------------------------------------------- #define iabs(i) (( (i) >= 0 ) ? (i) : -(i) ) -CUtlSymbolTable g_ActivityModifiersTable; extern void SetActivityForSequence( CStudioHdr *pstudiohdr, int i ); void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict pstudiohdr ) @@ -1640,7 +1628,7 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict // Some studio headers have no activities at all. In those // cases we can avoid a lot of this effort. - bool bFoundOne = false; + bool bFoundOne = false; // for each sequence in the header... const int NumSeq = pstudiohdr->GetNumSeq(); @@ -1669,10 +1657,7 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict HashValueType * __restrict toUpdate = &m_ActToSeqHash.Element(handle); toUpdate->count += 1; toUpdate->totalWeight += iabs(seqdesc.actweight); - if ( !HushAsserts() ) - { - AssertMsg( toUpdate->totalWeight > 0, "toUpdate->totalWeight: %d", toUpdate->totalWeight ); - } + Assert( toUpdate->totalWeight > 0 ); } else { @@ -1688,7 +1673,7 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict // Now, create starting indices for each activity. For an activity n, // the starting index is of course the sum of counts [0..n-1]. - int sequenceCount = 0; + register int sequenceCount = 0; int topActivity = 0; // this will store the highest seen activity number (used later to make an ad hoc map on the stack) for ( UtlHashHandle_t handle = m_ActToSeqHash.GetFirstHandle() ; m_ActToSeqHash.IsValidHandle(handle) ; @@ -1697,7 +1682,7 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict HashValueType &element = m_ActToSeqHash[handle]; element.startingIdx = sequenceCount; sequenceCount += element.count; - topActivity = max(topActivity, element.activityIdx); + topActivity = MAX(topActivity, element.activityIdx); } @@ -1716,7 +1701,6 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict // This stack may potentially grow very large; so if you have problems with it, // go to a utlmap or similar structure. unsigned int allocsize = (topActivity + 1) * sizeof(int); -#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression allocsize = ALIGN_VALUE(allocsize,16); int * __restrict seqsPerAct = static_cast(stackalloc(allocsize)); memset(seqsPerAct, 0, allocsize); @@ -1735,23 +1719,6 @@ void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict int tupleOffset = seqsPerAct[seqdesc.activity]; Assert( tupleOffset < element.count ); - if ( seqdesc.numactivitymodifiers > 0 ) - { - // add entries for this model's activity modifiers - (tupleList + element.startingIdx + tupleOffset)->pActivityModifiers = new CUtlSymbol[ seqdesc.numactivitymodifiers ]; - (tupleList + element.startingIdx + tupleOffset)->iNumActivityModifiers = seqdesc.numactivitymodifiers; - - for ( int k = 0; k < seqdesc.numactivitymodifiers; k++ ) - { - (tupleList + element.startingIdx + tupleOffset)->pActivityModifiers[ k ] = g_ActivityModifiersTable.AddString( seqdesc.pActivityModifier( k )->pszName() ); - } - } - else - { - (tupleList + element.startingIdx + tupleOffset)->pActivityModifiers = NULL; - (tupleList + element.startingIdx + tupleOffset)->iNumActivityModifiers = 0; - } - // You might be tempted to collapse this pointer math into a single pointer -- // don't! the tuple list is marked __restrict above. (tupleList + element.startingIdx + tupleOffset)->seqnum = i; // store sequence number diff --git a/public/studio.h b/public/studio.h index bc70313b..7d2dcf2d 100644 --- a/public/studio.h +++ b/public/studio.h @@ -26,7 +26,7 @@ #include "datamap.h" #include "generichash.h" #include "localflexcontroller.h" -#include "utlsymbol.h" + #define STUDIO_ENABLE_PERF_COUNTERS @@ -755,14 +755,6 @@ struct mstudioautolayer_t float end; // end of all influence }; -struct mstudioactivitymodifier_t -{ - DECLARE_BYTESWAP_DATADESC(); - - int sznameindex; - inline char *pszName() { return (sznameindex) ? (char *)(((byte *)this) + sznameindex ) : NULL; } -}; - // sequence descriptions struct mstudioseqdesc_t { @@ -859,11 +851,7 @@ struct mstudioseqdesc_t int cycleposeindex; // index of pose parameter to use as cycle index - int activitymodifierindex; - int numactivitymodifiers; - inline mstudioactivitymodifier_t *pActivityModifier( int i ) const { Assert( i >= 0 && i < numactivitymodifiers); return activitymodifierindex != 0 ? (mstudioactivitymodifier_t *)(((byte *)this) + activitymodifierindex) + i : NULL; }; - - int unused[5]; // remove/add as appropriate (grow back to 8 ints on version change!) + int unused[7]; // remove/add as appropriate (grow back to 8 ints on version change!) mstudioseqdesc_t(){} private: @@ -1771,7 +1759,7 @@ struct thinModelVertices_t { Assert( ( m_numBoneInfluences >= 1 ) && ( m_numBoneInfluences <= 3 ) ); Assert( ( boneWeights.numbones >= 1 ) && ( boneWeights.numbones <= m_numBoneInfluences ) ); - int numStoredWeights = max( 0, ( m_numBoneInfluences - 1 ) ); + int numStoredWeights = MAX( 0, ( m_numBoneInfluences - 1 ) ); float *pBaseWeight = m_boneWeights + vertIndex*numStoredWeights; char *pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences; for ( int i = 0; i < m_numBoneInfluences; i++ ) @@ -1841,7 +1829,7 @@ struct thinModelVertices_t Assert( pBoneWeights ); Assert( ( m_numBoneInfluences <= 1 ) || ( m_boneWeights != NULL ) ); Assert( ( m_numBoneInfluences <= 0 ) || ( m_boneIndices != NULL ) ); - int numStoredWeights = max( 0, ( m_numBoneInfluences - 1 ) ); + int numStoredWeights = MAX( 0, ( m_numBoneInfluences - 1 ) ); float *pBaseWeight = m_boneWeights + vertIndex*numStoredWeights; char *pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences; float sum = 0.0f; @@ -1959,75 +1947,75 @@ struct vertexFileFixup_t }; // This flag is set if no hitbox information was specified -#define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX 0x00000001 +#define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX ( 1 << 0 ) // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild // models when we change materials. -#define STUDIOHDR_FLAGS_USES_ENV_CUBEMAP 0x00000002 +#define STUDIOHDR_FLAGS_USES_ENV_CUBEMAP ( 1 << 1 ) // Use this when there are translucent parts to the model but we're not going to sort it -#define STUDIOHDR_FLAGS_FORCE_OPAQUE 0x00000004 +#define STUDIOHDR_FLAGS_FORCE_OPAQUE ( 1 << 2 ) // Use this when we want to render the opaque parts during the opaque pass // and the translucent parts during the translucent pass -#define STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS 0x00000008 +#define STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS ( 1 << 3 ) // This is set any time the .qc files has $staticprop in it // Means there's no bones and no transforms -#define STUDIOHDR_FLAGS_STATIC_PROP 0x00000010 +#define STUDIOHDR_FLAGS_STATIC_PROP ( 1 << 4 ) // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild // models when we change materials. -#define STUDIOHDR_FLAGS_USES_FB_TEXTURE 0x00000020 +#define STUDIOHDR_FLAGS_USES_FB_TEXTURE ( 1 << 5 ) // This flag is set by studiomdl.exe if a separate "$shadowlod" entry was present // for the .mdl (the shadow lod is the last entry in the lod list if present) -#define STUDIOHDR_FLAGS_HASSHADOWLOD 0x00000040 +#define STUDIOHDR_FLAGS_HASSHADOWLOD ( 1 << 6 ) // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild // models when we change materials. -#define STUDIOHDR_FLAGS_USES_BUMPMAPPING 0x00000080 +#define STUDIOHDR_FLAGS_USES_BUMPMAPPING ( 1 << 7 ) // NOTE: This flag is set when we should use the actual materials on the shadow LOD // instead of overriding them with the default one (necessary for translucent shadows) -#define STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS 0x00000100 +#define STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS ( 1 << 8 ) // NOTE: This flag is set when we should use the actual materials on the shadow LOD // instead of overriding them with the default one (necessary for translucent shadows) -#define STUDIOHDR_FLAGS_OBSOLETE 0x00000200 +#define STUDIOHDR_FLAGS_OBSOLETE ( 1 << 9 ) -#define STUDIOHDR_FLAGS_UNUSED 0x00000400 +#define STUDIOHDR_FLAGS_UNUSED ( 1 << 10 ) // NOTE: This flag is set at mdl build time -#define STUDIOHDR_FLAGS_NO_FORCED_FADE 0x00000800 +#define STUDIOHDR_FLAGS_NO_FORCED_FADE ( 1 << 11 ) // NOTE: The npc will lengthen the viseme check to always include two phonemes -#define STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE 0x00001000 +#define STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE ( 1 << 12 ) // This flag is set when the .qc has $constantdirectionallight in it // If set, we use constantdirectionallightdot to calculate light intensity // rather than the normal directional dot product // only valid if STUDIOHDR_FLAGS_STATIC_PROP is also set -#define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT 0x00002000 +#define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT ( 1 << 13 ) // Flag to mark delta flexes as already converted from disk format to memory format -#define STUDIOHDR_FLAGS_FLEXES_CONVERTED 0x00004000 +#define STUDIOHDR_FLAGS_FLEXES_CONVERTED ( 1 << 14 ) // Indicates the studiomdl was built in preview mode -#define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE 0x00008000 +#define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE ( 1 << 15 ) // Ambient boost (runtime flag) -#define STUDIOHDR_FLAGS_AMBIENT_BOOST 0x00010000 +#define STUDIOHDR_FLAGS_AMBIENT_BOOST ( 1 << 16 ) // Don't cast shadows from this model (useful on first-person models) -#define STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS 0x00020000 +#define STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS ( 1 << 17 ) // alpha textures should cast shadows in vrad on this model (ONLY prop_static!) -#define STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS 0x00040000 +#define STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS ( 1 << 18 ) // flagged on load to indicate no animation events on this model -#define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE 0x00200000 +#define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ( 1 << 21 ) // NOTE! Next time we up the .mdl file format, remove studiohdr2_t // and insert all fields in this structure into studiohdr_t. @@ -2505,7 +2493,6 @@ class CStudioHdr CUtlVector< int > m_boneParent; public: - // This class maps an activity to sequences allowed for that activity, accelerating the resolution // of SelectWeightedSequence(), especially on PowerPC. Iterating through every sequence // attached to a model turned out to be a very destructive cache access pattern on 360. @@ -2521,10 +2508,8 @@ class CStudioHdr // A tuple of a sequence and its corresponding weight. Lists of these correspond to activities. struct SequenceTuple { - short seqnum; - short weight; // the absolute value of the weight from the sequence header - CUtlSymbol *pActivityModifiers; // list of activity modifier symbols - int iNumActivityModifiers; + short seqnum; + short weight; // the absolute value of the weight from the sequence header }; // The type of the hash's stored data, a composite of both key and value @@ -2594,13 +2579,9 @@ class CStudioHdr // dtor -- not virtual because this class has no inheritors ~CActivityToSequenceMapping() - { + { if ( m_pSequenceTuples != NULL ) { - if ( m_pSequenceTuples->pActivityModifiers != NULL ) - { - delete[] m_pSequenceTuples->pActivityModifiers; - } delete[] m_pSequenceTuples; } } @@ -2631,9 +2612,6 @@ class CStudioHdr /// A more efficient version of the old SelectWeightedSequence() function in animation.cpp. int SelectWeightedSequence( CStudioHdr *pstudiohdr, int activity, int curSequence ); - // selects the sequence with the most matching modifiers - int SelectWeightedSequenceFromModifiers( CStudioHdr *pstudiohdr, int activity, CUtlSymbol *pActivityModifiers, int iModifierCount ); - // Actually a big array, into which the hash values index. SequenceTuple *m_pSequenceTuples; unsigned int m_iSequenceTuplesCount; // (size of the whole array) @@ -2678,19 +2656,6 @@ class CStudioHdr return m_ActivityToSequence.SelectWeightedSequence( this, activity, curSequence ); } - inline int SelectWeightedSequenceFromModifiers( int activity, CUtlSymbol *pActivityModifiers, int iModifierCount ) - { -#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE - // We lazy-initialize the header on demand here, because CStudioHdr::Init() is - // called from the constructor, at which time the this pointer is illegitimate. - if ( !m_ActivityToSequence.IsInitialized() ) - { - m_ActivityToSequence.Initialize( this ); - } -#endif - return m_ActivityToSequence.SelectWeightedSequenceFromModifiers( this, activity, pActivityModifiers, iModifierCount ); - } - /// True iff there is at least one sequence for the given activity. inline bool HaveSequenceForActivity( int activity ) { diff --git a/public/studio_virtualmodel.cpp b/public/studio_virtualmodel.cpp index 0a658df6..d8d2ce42 100644 --- a/public/studio_virtualmodel.cpp +++ b/public/studio_virtualmodel.cpp @@ -474,8 +474,8 @@ void virtualmodel_t::AppendPoseParameters( int group, const studiohdr_t *pStudio // duplicate, reset start and end to fit full dynamic range mstudioposeparamdesc_t *pPose1 = pStudioHdr->pLocalPoseParameter( j ); mstudioposeparamdesc_t *pPose2 = m_group[ pose[k].group ].GetStudioHdr()->pLocalPoseParameter( pose[k].index ); - float start = min( pPose2->end, min( pPose1->end, min( pPose2->start, pPose1->start ) ) ); - float end = max( pPose2->end, max( pPose1->end, max( pPose2->start, pPose1->start ) ) ); + float start = MIN( pPose2->end, MIN( pPose1->end, MIN( pPose2->start, pPose1->start ) ) ); + float end = MAX( pPose2->end, MAX( pPose1->end, MAX( pPose2->start, pPose1->start ) ) ); pPose2->start = start; pPose2->end = end; } diff --git a/public/texture_group_names.h b/public/texture_group_names.h index 92b31279..b30ed35a 100644 --- a/public/texture_group_names.h +++ b/public/texture_group_names.h @@ -23,7 +23,6 @@ #define TEXTURE_GROUP_PRECACHED "Precached" // TODO: assign texture groups to the precached materials #define TEXTURE_GROUP_CUBE_MAP "CubeMap textures" #define TEXTURE_GROUP_RENDER_TARGET "RenderTargets" -#define TEXTURE_GROUP_RUNTIME_COMPOSITE "Runtime Composite" #define TEXTURE_GROUP_UNACCOUNTED "Unaccounted textures" // Textures that weren't assigned a texture group. //#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER "Static Vertex" #define TEXTURE_GROUP_STATIC_INDEX_BUFFER "Static Indices" diff --git a/public/tier0/annotations.h b/public/tier0/annotations.h index 7e0f4698..25537821 100644 --- a/public/tier0/annotations.h +++ b/public/tier0/annotations.h @@ -48,8 +48,6 @@ #define OUT_Z_ARRAY _Deref_post_z_ #define INOUT_Z_ARRAY _Deref_prepost_z_ #endif // _MSC_VER >= 1700 -// Used for annotating functions to describe their return types. -#define MUST_CHECK_RETURN _Check_return_ // Use the macros above to annotate string functions that fill buffers as shown here, // in order to give VS's /analyze more opportunities to find bugs. // void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes ); @@ -78,7 +76,6 @@ #define INOUT_Z_BYTECAP(x) #define OUT_Z_ARRAY #define INOUT_Z_ARRAY -#define MUST_CHECK_RETURN #endif #endif // ANALYSIS_ANNOTATIONS_H diff --git a/public/tier0/basetypes.h b/public/tier0/basetypes.h index 22ce51bc..9bcaf90e 100644 --- a/public/tier0/basetypes.h +++ b/public/tier0/basetypes.h @@ -131,6 +131,70 @@ T Max( T const &val1, T const &val2 ) #define TRUE (!FALSE) #endif +//----------------------------------------------------------------------------- +// fsel +//----------------------------------------------------------------------------- +#ifndef _X360 + +#define fsel(c,x,y) ( (c) >= 0 ? (x) : (y) ) + +// integer conditional move +// if a >= 0, return x, else y +#define isel(a,x,y) ( ((a) >= 0) ? (x) : (y) ) + +// if x = y, return a, else b +#define ieqsel(x,y,a,b) (( (x) == (y) ) ? (a) : (b)) + +// if the nth bit of a is set (counting with 0 = LSB), +// return x, else y +// this is fast if nbit is a compile-time immediate +#define ibitsel(a, nbit, x, y) ( ( ((a) & (1 << (nbit))) != 0 ) ? (x) : (y) ) + +#else + +// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT +// this is much faster than if ( aFloat > 0 ) { x = .. } +// the XDK defines two intrinsics, one for floats and one for doubles -- it's the same +// opcode, but the __fself version tells the compiler not to do a wasteful unnecessary +// rounding op after each sel. +// #define fsel __fsel +FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) { return __fsel( fComparand, fValGE, fLT ); } +FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) { return __fself( fComparand, fValGE, fLT ); } + +// if a >= 0, return x, else y +FORCEINLINE int isel( int a, int x, int y ) +{ + int mask = a >> 31; // arithmetic shift right, splat out the sign bit + return x + ((y - x) & mask); +}; + +// if a >= 0, return x, else y +FORCEINLINE unsigned isel( int a, unsigned x, unsigned y ) +{ + int mask = a >> 31; // arithmetic shift right, splat out the sign bit + return x + ((y - x) & mask); +}; + +// ( x == y ) ? a : b +FORCEINLINE unsigned ieqsel( unsigned x, unsigned y, unsigned a, unsigned b ) +{ + unsigned mask = (x == y) ? 0 : -1; + return a + ((b - a) & mask); +}; + +// ( x == y ) ? a : b +FORCEINLINE int ieqsel( int x, int y, int a, int b ) +{ + int mask = (x == y) ? 0 : -1; + return a + ((b - a) & mask); +}; + +// if the nth bit of a is set (counting with 0 = LSB), +// return x, else y +// this is fast if nbit is a compile-time immediate +#define ibitsel(a, nbit, x, y) ( (x) + (((y) - (x)) & (((a) & (1 << (nbit))) ? 0 : -1)) ) + +#endif #ifndef DONT_DEFINE_BOOL // Needed for Cocoa stuff to compile. typedef int BOOL; @@ -147,6 +211,10 @@ typedef wchar_t ucs2; // under windows wchar_t is ucs2 typedef unsigned short ucs2; #endif +#ifdef MAPBASE +#define TO_THREESTATE(num) static_cast(num) +#endif + enum ThreeState_t { TRS_FALSE, diff --git a/public/tier0/cpumonitoring.h b/public/tier0/cpumonitoring.h deleted file mode 100644 index e6d1c9cd..00000000 --- a/public/tier0/cpumonitoring.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CPU_MONITORING_H -#define CPU_MONITORING_H - -/* -This header defines functions and structures for controlling the measurement of CPU frequency -in order to detect thermal throttling. For details see the associated source file. -*/ - -struct CPUFrequencyResults -{ - double m_timeStamp; // Time (from Plat_FloatTime) when the measurements were made. - float m_GHz; - float m_percentage; - float m_lowestPercentage; -}; - -// Call this to get results. -// When CPU monitoring is 'disabled' it may still be running at a low frequency, -// for OGS purposes or for proactively warning users of problems. If fGetDisabledResults -// is true then results will be returned when disabled (if available). -PLATFORM_INTERFACE CPUFrequencyResults GetCPUFrequencyResults( bool fGetDisabledResults = false ); - -// Call this to set the monitoring frequency. Intervals of 2-5 seconds (2,000 to 5,000 ms) -// are recommended. An interval of zero will disable CPU monitoring. Short delays (below -// about 300 ms) will be rounded up. -PLATFORM_INTERFACE void SetCPUMonitoringInterval( unsigned nDelayMilliseconds ); - -// Warn with increasing strident colors when CPU percentages go below these levels. -// They are const int instead of float because const float in C++ is stupid. -const int kCPUMonitoringWarning1 = 80; -const int kCPUMonitoringWarning2 = 50; - -#endif diff --git a/public/tier0/dbg.h b/public/tier0/dbg.h index 5fa68adf..fab71650 100644 --- a/public/tier0/dbg.h +++ b/public/tier0/dbg.h @@ -15,7 +15,9 @@ #include "basetypes.h" #include "dbgflag.h" #include "platform.h" +#if _MSC_VER < 1900 #include +#endif #include #include @@ -221,9 +223,6 @@ typedef void (*AssertFailedNotifyFunc_t)( const char *pchFile, int nLine, const DBG_INTERFACE void SetAssertFailedNotifyFunc( AssertFailedNotifyFunc_t func ); DBG_INTERFACE void CallAssertFailedNotifyFunc( const char *pchFile, int nLine, const char *pchMessage ); -/* True if -hushasserts was passed on command line. */ -DBG_INTERFACE bool HushAsserts(); - #if defined( USE_SDL ) DBG_INTERFACE void SetAssertDialogParent( struct SDL_Window *window ); DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); @@ -250,10 +249,10 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); if (!(_exp)) \ { \ _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \ - SpewRetval_t ret = _SpewMessage("%s", static_cast( _msg )); \ + SpewRetval_t _ret = _SpewMessage("%s", static_cast( _msg )); \ CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \ _executeExp; \ - if ( ret == SPEW_DEBUGGER) \ + if ( _ret == SPEW_DEBUGGER) \ { \ if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \ { \ @@ -394,36 +393,18 @@ DBG_INTERFACE struct SDL_Window * GetAssertDialogParent(); #define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false ) #define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false ) -// Stringify a number -#define V_STRINGIFY_INTERNAL(x) #x -// Extra level of indirection needed when passing in a macro to avoid getting the macro name instead of value -#define V_STRINGIFY(x) V_STRINGIFY_INTERNAL(x) - -// Macros to help decorate warnings or errors with the location in code -#define FILE_LINE_FUNCTION_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):" __FUNCTION__ ":" -#define FILE_LINE_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):" -#define FUNCTION_LINE_STRING __FUNCTION__ "(" V_STRINGIFY(__LINE__) "): " - -// Handy define for inserting clickable messages into the build output. -// Use like this: -// #pragma MESSAGE("Some message") -#define MESSAGE(msg) message(__FILE__ "(" V_STRINGIFY(__LINE__) "): " msg) - #if !defined( _X360 ) || !defined( _RETAIL ) /* These are always compiled in */ DBG_INTERFACE void Msg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 ); DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 ); -DBG_INTERFACE void MsgV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ); DBG_INTERFACE void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 ); DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 ); -DBG_INTERFACE void WarningV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ); DBG_INTERFACE void Log( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 ); DBG_INTERFACE void DLog( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 ); -DBG_INTERFACE void LogV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ); #ifdef Error // p4.cpp does a #define Error Warning and in that case the Error prototype needs to @@ -431,23 +412,17 @@ DBG_INTERFACE void LogV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist DBG_INTERFACE void Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 ); #else DBG_INTERFACE void NORETURN Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 ); -DBG_INTERFACE void NORETURN ErrorV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ); - #endif #else inline void Msg( ... ) {} inline void DMsg( ... ) {} -inline void MsgV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {} inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {} -inline void WarningV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {} inline void DWarning( ... ) {} inline void Log( ... ) {} inline void DLog( ... ) {} -inline void LogV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {} inline void Error( ... ) {} -inline void ErrorV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {} #endif diff --git a/public/tier0/fasttimer.h b/public/tier0/fasttimer.h index e9e634f3..79496a9e 100644 --- a/public/tier0/fasttimer.h +++ b/public/tier0/fasttimer.h @@ -222,6 +222,8 @@ class CAverageCycleCounter unsigned m_nIters; CCycleCount m_Total; CCycleCount m_Peak; + bool m_fReport; + const tchar *m_pszName; }; // -------------------------------------------------------------------------- // diff --git a/public/tier0/icommandline.h b/public/tier0/icommandline.h index 9107d697..cbe9cb59 100644 --- a/public/tier0/icommandline.h +++ b/public/tier0/icommandline.h @@ -40,8 +40,6 @@ abstract_class ICommandLine // copies the string passwed virtual void SetParm( int nIndex, char const *pNewParm ) =0; - - virtual const char *ParmValueByIndex( int nIndex, const char *pDefaultVal = 0 ) const = 0; }; //----------------------------------------------------------------------------- diff --git a/public/tier0/memalloc.h b/public/tier0/memalloc.h index e0f9c16a..34e1ccb9 100644 --- a/public/tier0/memalloc.h +++ b/public/tier0/memalloc.h @@ -382,7 +382,12 @@ class CMemAllocAttributeAlloction #pragma warning(disable:4290) #pragma warning(push) + +#if _MSC_VER < 1900 #include +#else + #include +#endif // MEM_DEBUG_CLASSNAME is opt-in. // Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads diff --git a/public/tier0/memdbgon.h b/public/tier0/memdbgon.h index 7fd6e9ca..4e46839f 100644 --- a/public/tier0/memdbgon.h +++ b/public/tier0/memdbgon.h @@ -37,7 +37,7 @@ #include "commonmacros.h" #include "memalloc.h" -#if defined(USE_MEM_DEBUG) +#if USE_MEM_DEBUG #if defined( POSIX ) #define _NORMAL_BLOCK 1 @@ -91,7 +91,7 @@ inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nEle } #endif -#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s) +#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc((c)*(s)), (c), (s)) #define free(p) g_pMemAlloc->Free( p ) #define _msize(p) g_pMemAlloc->GetSize( p ) #define _expand(p, s) _expand_NoLongerSupported(p, s) @@ -99,7 +99,7 @@ inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nEle // -------------------------------------------------------- // Debug path -#if defined(USE_MEM_DEBUG) +#if USE_MEM_DEBUG #define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__) #define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ ) @@ -231,7 +231,7 @@ inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString) #else -#if defined(USE_MEM_DEBUG) +#if USE_MEM_DEBUG #ifndef _STATIC_LINKED #pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build") #else diff --git a/public/tier0/memoverride.cpp b/public/tier0/memoverride.cpp index bec06c0e..5ff4dbb4 100644 --- a/public/tier0/memoverride.cpp +++ b/public/tier0/memoverride.cpp @@ -40,9 +40,17 @@ #define __cdecl #endif +#undef _malloc_dbg +#undef _calloc_dbg +#undef _free_dbg +#undef _CrtSetCheckCount +#undef _CrtGetCheckCount +#undef _CrtSetDebugFillThreshold + #if defined( _WIN32 ) && !defined( _X360 ) const char *MakeModuleFileName() { +#if _MSC_VER < 1900 if ( g_pMemAlloc->IsDebugHeap() ) { char *pszModuleName = (char *)HeapAlloc( GetProcessHeap(), 0, MAX_PATH ); // small leak, debug only @@ -65,27 +73,36 @@ const char *MakeModuleFileName() return pszModuleName; } +#endif return NULL; } static void *AllocUnattributed( size_t nSize ) { +#if _MSC_VER < 1900 static const char *pszOwner = MakeModuleFileName(); if ( !pszOwner ) return g_pMemAlloc->Alloc(nSize); else return g_pMemAlloc->Alloc(nSize, pszOwner, 0); +#else + return g_pMemAlloc->Alloc(nSize); +#endif } static void *ReallocUnattributed( void *pMem, size_t nSize ) { +#if _MSC_VER < 1900 static const char *pszOwner = MakeModuleFileName(); if ( !pszOwner ) return g_pMemAlloc->Realloc(pMem, nSize); else return g_pMemAlloc->Realloc(pMem, nSize, pszOwner, 0); +#else + return g_pMemAlloc->Realloc(pMem, nSize); +#endif } #else @@ -108,6 +125,9 @@ inline void *ReallocUnattributed( void *pMem, size_t nSize ) // this magic only works under win32 // under linux this malloc() overrides the libc malloc() and so we // end up in a recursion (as g_pMemAlloc->Alloc() calls malloc) +#if _MSC_VER >= 1900 && !defined(_CRTNOALIAS) +#define _CRTNOALIAS +#endif #if _MSC_VER >= 1400 #define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT #define FREE_CALL _CRTNOALIAS @@ -155,6 +175,11 @@ void* __cdecl _malloc_base( size_t nSize ) { return AllocUnattributed( nSize ); } +#elif _MSC_VER >= 1900 + __declspec(restrict) void* _malloc_base(size_t nSize) + { + return AllocUnattributed(nSize); + } #else void *_malloc_base( size_t nSize ) { @@ -162,24 +187,47 @@ void *_malloc_base( size_t nSize ) } #endif +#if _MSC_VER >= 1900 +__declspec(restrict) void* _calloc_base(size_t count, size_t nSize) +{ + void* pMem = AllocUnattributed(count * nSize); + memset(pMem, 0, count * nSize); + return pMem; +} +#else void *_calloc_base( size_t nSize ) { void *pMem = AllocUnattributed( nSize ); memset(pMem, 0, nSize); return pMem; } +#endif +#if _MSC_VER >= 1900 +__declspec(restrict) void* _realloc_base(void* pMem, size_t nSize) +{ + return ReallocUnattributed(pMem, nSize); +} +#else void *_realloc_base( void *pMem, size_t nSize ) { return ReallocUnattributed( pMem, nSize ); } +#endif +#if _MSC_VER >= 1900 +__declspec(restrict) void* _recalloc_base(void* pMem, size_t count, size_t nSize) +{ + return _recalloc(pMem, count, nSize); +} +#else void *_recalloc_base( void *pMem, size_t nSize ) { void *pMemOut = ReallocUnattributed( pMem, nSize ); memset(pMemOut, 0, nSize); return pMemOut; } +#endif void _free_base( void *pMem ) { @@ -200,7 +248,11 @@ void * __cdecl _malloc_crt(size_t size) void * __cdecl _calloc_crt(size_t count, size_t size) { +#if _MSC_VER >= 1900 + return _calloc_base(count, size); +#else return _calloc_base( count * size ); +#endif } void * __cdecl _realloc_crt(void *ptr, size_t size) @@ -210,17 +262,29 @@ void * __cdecl _realloc_crt(void *ptr, size_t size) void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size) { +#if _MSC_VER >= 1900 + return _recalloc_base(ptr, count, size); +#else return _recalloc_base( ptr, size * count ); +#endif } ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size ) { - void *pMem = ReallocUnattributed( memblock, size * count ); - memset( pMem, 0, size * count ); - return pMem; + const size_t oldSize = _msize(memblock); + const size_t newSize = count * size; + void* pMemOut = ReallocUnattributed(memblock, newSize); + + if (newSize > oldSize) + memset(((char*)pMemOut) + oldSize, 0, newSize - oldSize); + + return pMemOut; } size_t _msize_base( void *pMem ) +#if _MSC_VER >= 1925 //VS2019+ + throw() +#endif { return g_pMemAlloc->GetSize(pMem); } @@ -485,6 +549,7 @@ void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse, return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine ); } +#ifdef DEBUG void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse, const char *pFileName, int nLine ) { @@ -498,6 +563,7 @@ void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse, Assert( 0 ); return NULL; } +#endif void __cdecl _free_dbg( void *pMem, int nBlockUse ) { @@ -505,6 +571,7 @@ void __cdecl _free_dbg( void *pMem, int nBlockUse ) g_pMemAlloc->Free(pMem); } +#ifdef DEBUG size_t __cdecl _msize_dbg( void *pMem, int nBlockUse ) { #ifdef _WIN32 @@ -514,6 +581,7 @@ size_t __cdecl _msize_dbg( void *pMem, int nBlockUse ) return 0; #endif } +#endif #ifdef _WIN32 @@ -614,6 +682,7 @@ ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t coun extern "C" { +#ifdef DEBUG int _CrtDumpMemoryLeaks(void) { return 0; @@ -628,11 +697,25 @@ int _CrtSetDbgFlag( int nNewFlag ) { return g_pMemAlloc->CrtSetDbgFlag( nNewFlag ); } +#endif // 64-bit port. #define AFNAME(var) __p_ ## var #define AFRET(var) &var +#if _MSC_VER >= 1900 +int* __cdecl __p__crtDbgFlag(void) +{ + static int dummy = _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; + return &dummy; +} + +long* __cdecl __p__crtBreakAlloc(void) +{ + static long dummy = 0; + return &dummy; +} +#else int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF; int* AFNAME(_crtDbgFlag)(void) { @@ -644,12 +727,14 @@ long* AFNAME(_crtBreakAlloc) (void) { return AFRET(_crtBreakAlloc); } +#endif void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse ) { DebuggerBreak(); } +#ifdef DEBUG _CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook ) { DebuggerBreak(); @@ -710,13 +795,14 @@ void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pCon { DebuggerBreak(); } - +#endif //----------------------------------------------------------------------------- // Methods in dbgrpt.cpp //----------------------------------------------------------------------------- long _crtAssertBusy = -1; +#ifdef DEBUG int __cdecl _CrtSetReportMode( int nReportType, int nReportMode ) { return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode ); @@ -731,6 +817,7 @@ _CRT_REPORT_HOOK __cdecl _CrtSetReportHook( _CRT_REPORT_HOOK pfnNewHook ) { return (_CRT_REPORT_HOOK)g_pMemAlloc->CrtSetReportHook( pfnNewHook ); } +#endif int __cdecl _CrtDbgReport( int nRptType, const char * szFile, int nLine, const char * szModule, const char * szFormat, ... ) @@ -863,7 +950,7 @@ ErrorHandlerRegistrar::ErrorHandlerRegistrar() _set_invalid_parameter_handler( VInvalidParameterHandler ); } -#if defined( _DEBUG ) +#if 0 // defined( _DEBUG ) // wrapper which passes no debug info; not available in debug #ifndef SUPPRESS_INVALID_PARAMETER_NO_INFO @@ -887,21 +974,41 @@ int __cdecl __crtMessageWindowW( int nRptType, const wchar_t * szFile, const wch int __cdecl _CrtDbgReportV( int nRptType, const wchar_t *szFile, int nLine, const wchar_t *szModule, const wchar_t *szFormat, va_list arglist ) { - Assert(0); + wchar_t buffer[256]; + vswprintf(buffer, 256, szFormat, arglist); + DevWarning("%ls", buffer); return 0; } int __cdecl _CrtDbgReportW( int nRptType, const wchar_t *szFile, int nLine, const wchar_t *szModule, const wchar_t *szFormat, ...) { - Assert(0); + wchar_t buffer[256]; + va_list args; + va_start(args, szFormat); + vswprintf(buffer, 256, szFormat, args); + va_end(args); + DevWarning("%ls", buffer); return 0; } +#if _MSC_VER >= 1900 +int __cdecl _VCrtDbgReportA(int nRptType, void* returnAddress, const char* szFile, int nLine, + const char* szModule, const char* szFormat, va_list arglist) +#else int __cdecl _VCrtDbgReportA( int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, va_list arglist ) +#endif { - Assert(0); +#if _MSC_VER >= 1900 + char buffer[256]; + vsnprintf(buffer, 256, szFormat, arglist); + DevWarning("%s", buffer); +#else + wchar_t buffer[256]; + vswprintf(buffer, 256, szFormat, arglist); + DevWarning("%ls", buffer); +#endif // _MSC_VER >= 1900 return 0; } @@ -927,13 +1034,12 @@ extern "C" int __cdecl _CrtGetCheckCount( void ) return __crtDebugCheckCount; } +#ifdef DEBUG // aligned offset debug extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n ) { Assert( IsPC() || 0 ); - void *pMem = ReallocUnattributed( memblock, size * count ); - memset( pMem, 0, size * count ); - return pMem; + return ReallocUnattributed(memblock, size * count); } extern "C" void * __cdecl _aligned_recalloc_dbg( void *memblock, size_t count, size_t size, size_t align, const char * f_name, int line_n ) @@ -950,12 +1056,16 @@ _CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void ) { return NULL; } +#endif // DEBUG #endif + +#ifdef DEBUG int __cdecl _CrtReportBlockType(const void * pUserData) { return 0; } +#endif } // end extern "C" @@ -995,14 +1105,14 @@ void * __cdecl _heap_alloc_dbg( size_t nSize, int nBlockUse, const char * szFile static void * __cdecl realloc_help( void * pUserData, size_t * pnNewSize, int nBlockUse,const char * szFileName, int nLine, int fRealloc ) { - assert(0); // Shouldn't be needed + Assert(0); // Shouldn't be needed return NULL; } #else static void * __cdecl realloc_help( void * pUserData, size_t nNewSize, int nBlockUse, const char * szFileName, int nLine, int fRealloc) { - assert(0); // Shouldn't be needed + Assert(0); // Shouldn't be needed return NULL; } #endif @@ -1018,11 +1128,13 @@ void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse) _free_dbg(pUserData, 0); } +#ifdef DEBUG _CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void) { - assert(0); + Assert(0); return NULL; } +#endif static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize) { @@ -1030,12 +1142,13 @@ static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t return bOkay; } - +#ifdef DEBUG _CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void) { - assert(0); + Assert(0); return NULL; } +#endif #if _MSC_VER >= 1400 static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead) @@ -1046,6 +1159,8 @@ static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, { } #endif + +#if defined(DEBUG) && _MSC_VER >= 1900 void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n) { return _aligned_malloc(size, align); @@ -1073,16 +1188,19 @@ void __cdecl _aligned_free_dbg( void * memblock) { _aligned_free(memblock); } +#endif // DEBUG +#if _MSC_VER < 1900 size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold) { assert(0); return 0; } +#endif //=========================================== // NEW!!! 64-bit - +#ifndef PROTECTED_THINGS_DISABLE char * __cdecl _strdup ( const char * string ) { int nSize = (int)strlen(string) + 1; @@ -1094,6 +1212,7 @@ char * __cdecl _strdup ( const char * string ) memcpy( pCopy, string, nSize ); return pCopy; } +#endif #if 0 _TSCHAR * __cdecl _tfullpath_dbg ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen, int nBlockUse, const char * szFileName, int nLine ) @@ -1156,6 +1275,7 @@ wchar_t * __cdecl _wcsdup ( const wchar_t * string ) return 0; } #endif + } // end extern "C" #if _MSC_VER >= 1400 @@ -1343,6 +1463,12 @@ _CRTIMP extern uintptr_t __cdecl __threadhandle(void); /* Structure for each thread's data */ +#if _MSC_VER >= 1900 +typedef __crt_multibyte_data* pthreadmbcinfo; +typedef __crt_locale_data* pthreadlocinfo; +typedef __crt_locale_pointers _locale_tstruct; +#endif + struct _tiddata { unsigned long _tid; /* thread ID */ @@ -1386,7 +1512,7 @@ struct _tiddata { * the thread */ pthreadmbcinfo ptmbcinfo; - /* pointer to the copy of the locale informaton used by the thead */ + /* pointer to the copy of the locale information used by the thread */ pthreadlocinfo ptlocinfo; int _ownlocale; /* if 1, this thread owns its own locale */ @@ -1501,7 +1627,7 @@ struct _tiddata { * the thread */ pthreadmbcinfo ptmbcinfo; - /* pointer to the copy of the locale informaton used by the thead */ + /* pointer to the copy of the locale information used by the thread */ pthreadlocinfo ptlocinfo; int _ownlocale; /* if 1, this thread owns its own locale */ diff --git a/public/tier0/minidump.h b/public/tier0/minidump.h index e6507256..fad2d073 100644 --- a/public/tier0/minidump.h +++ b/public/tier0/minidump.h @@ -82,23 +82,6 @@ PLATFORM_INTERFACE void MinidumpSetUnhandledExceptionFunction( FnMiniDump pfn ); // being silently swallowed. We should always call this at startup. PLATFORM_INTERFACE void EnableCrashingOnCrashes(); -#endif // defined(_WIN32) && !defined(_X360) - -// -// Minidump User Stream Info Comments. -// -// There currently is a single header string, and an array of 64 comment strings. -// MinidumpUserStreamInfoSetHeader() will set the single header string. -// MinidumpUserStreamInfoAppend() will round robin through and array and set the comment strings, overwriting old. -PLATFORM_INTERFACE void MinidumpUserStreamInfoSetHeader( const char *pFormat, ... ); -PLATFORM_INTERFACE void MinidumpUserStreamInfoAppend( const char *pFormat, ... ); - -// Retrieve the StreamInfo strings. -// Index 0: header string -// Index 1..: comment string -// Returns NULL when you've reached the end of the comment string array -// Empty strings ("\0") can be returned if comment hasn't been set -PLATFORM_INTERFACE const char *MinidumpUserStreamInfoGet( int Index ); +#endif #endif // MINIDUMP_H - diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 652c27c0..6d5751a8 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -9,18 +9,6 @@ #ifndef PLATFORM_H #define PLATFORM_H -#if defined(__x86_64__) || defined(_WIN64) -#define PLATFORM_64BITS 1 -#endif - -#if defined(__GCC__) || defined(__GNUC__) -#define COMPILER_GCC 1 -#endif - -#ifdef __clang__ -#define COMPILER_CLANG 1 -#endif - #if defined( _X360 ) #define NO_STEAM #define NO_VOICE @@ -63,13 +51,14 @@ // need this for _alloca #include #include -#include + #include #include #endif #include #include + // need this for memset #include @@ -159,6 +148,10 @@ typedef unsigned char uint8; typedef signed char int8; +#if defined(__x86_64__) || defined(_WIN64) + #define X64BITS +#endif // __x86_64__ + #if defined( _WIN32 ) typedef __int16 int16; @@ -198,7 +191,7 @@ typedef signed char int8; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; - #ifdef PLATFORM_64BITS + #ifdef X64BITS typedef long long intp; typedef unsigned long long uintp; #else @@ -209,39 +202,17 @@ typedef signed char int8; // Avoid redefinition warnings if a previous header defines this. #undef OVERRIDE - #if __cplusplus >= 201103L + #if defined(__clang__) #define OVERRIDE override - #if defined(__clang__) - // warning: 'override' keyword is a C++11 extension [-Wc++11-extensions] - // Disabling this warning is less intrusive than enabling C++11 extensions - #pragma GCC diagnostic ignored "-Wc++11-extensions" - #endif + // warning: 'override' keyword is a C++11 extension [-Wc++11-extensions] + // Disabling this warning is less intrusive than enabling C++11 extensions + #pragma GCC diagnostic ignored "-Wc++11-extensions" #else #define OVERRIDE #endif #endif // else _WIN32 -//----------------------------------------------------------------------------- -// Set up platform type defines. -//----------------------------------------------------------------------------- -#if defined( PLATFORM_X360 ) || defined( _PS3 ) - #if !defined( _GAMECONSOLE ) - #define _GAMECONSOLE - #endif - #define IsPC() false - #define IsGameConsole() true -#else - #define IsPC() true - #define IsGameConsole() false -#endif - -#ifdef PLATFORM_64BITS - #define IsPlatform64Bits() true -#else - #define IsPlatform64Bits() false -#endif - // From steam/steamtypes.h // RTime32 // We use this 32 bit time representing real world time. @@ -259,11 +230,7 @@ typedef unsigned int uint; // Ensure that everybody has the right compiler version installed. The version // number can be obtained by looking at the compiler output when you type 'cl' // and removing the last two digits and the periods: 16.00.40219.01 becomes 160040219 -#if _MSC_FULL_VER > 180000000 - #if _MSC_FULL_VER < 180030723 - #error You must install VS 2013 Update 3 - #endif -#elif _MSC_FULL_VER > 160000000 +#if _MSC_FULL_VER > 160000000 #if _MSC_FULL_VER < 160040219 #error You must install VS 2010 SP1 #endif @@ -400,7 +367,7 @@ typedef void * HINSTANCE; #define MAX_UNICODE_PATH MAX_PATH #endif -#define MAX_UNICODE_PATH_IN_UTF8 MAX_UNICODE_PATH*4 +#define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH*4) #ifdef GNUC #undef offsetof @@ -412,7 +379,7 @@ typedef void * HINSTANCE; #endif -#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression +#define ALIGN_VALUE( val, alignment ) ( ( (val) + (alignment) - 1 ) & ~( (alignment) - 1 ) ) // need macro for constant expression // Used to step into the debugger #if defined( _WIN32 ) && !defined( _X360 ) @@ -430,19 +397,6 @@ typedef void * HINSTANCE; #endif #define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() -#ifdef STAGING_ONLY -#define DebuggerBreakIfDebugging_StagingOnly() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() -#else -#define DebuggerBreakIfDebugging_StagingOnly() -#endif - -// Allows you to specify code that should only execute if we are in a staging build. Otherwise the code noops. -#ifdef STAGING_ONLY -#define STAGING_ONLY_EXEC( _exec ) do { _exec; } while (0) -#else -#define STAGING_ONLY_EXEC( _exec ) do { } while (0) -#endif - // C functions for external declarations that call the appropriate C++ methods #ifndef EXPORT #ifdef _WIN32 @@ -618,7 +572,16 @@ typedef void * HINSTANCE; #endif // GCC 3.4.1 has a bug in supporting forced inline of templated functions // this macro lets us not force inlining in that case - #define FORCEINLINE_TEMPLATE inline +#if __GNUC__ < 4 +#define FORCEINLINE_TEMPLATE inline +#else +#define FORCEINLINE_TEMPLATE inline __attribute__((always_inline)) +#endif +#if __cpp_constexpr >= 201304 +#define CONSTEXPR_FUNC constexpr +#else +#define CONSTEXPR_FUNC +#endif // #define __stdcall __attribute__ ((__stdcall__)) #endif @@ -718,6 +681,40 @@ typedef void * HINSTANCE; #pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size #endif +// Detect C++11 support for "rvalue references" / "move semantics" / other C++11 (and up) stuff +#if defined(_MSC_VER) +#if _MSC_VER >= 1600 +#define VALVE_RVALUE_REFS 1 +#endif +#if _MSC_VER >= 1800 +#define VALVE_INITIALIZER_LIST_SUPPORT 1 +#define VALVE_EXPLICIT_CONVERSION_OP 1 +#endif +#elif defined(__clang__) +#if __has_extension(cxx_rvalue_references) +#define VALVE_RVALUE_REFS 1 +#endif +#if __has_feature(cxx_generalized_initializers) +#define VALVE_INITIALIZER_LIST_SUPPORT 1 +#endif +#if __has_feature(cxx_explicit_conversions) +#define VALVE_EXPLICIT_CONVERSION_OP 1 +#endif +#elif defined(__GNUC__) +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#if defined(__GXX_EXPERIMENTAL_CXX0X__) +#define VALVE_RVALUE_REFS 1 +#define VALVE_INITIALIZER_LIST_SUPPORT 1 +#define VALVE_EXPLICIT_CONVERSION_OP 1 +#endif +#endif +#endif + +#ifdef VALVE_RVALUE_REFS +#include "tier0/valve_minmax_off.h" +#include +#include "tier0/valve_minmax_on.h" +#endif #ifdef POSIX #define _stricmp stricmp @@ -750,29 +747,6 @@ typedef uint32 HMODULE; typedef void *HANDLE; #endif -//----------------------------------------------------------------------------- -// fsel -//----------------------------------------------------------------------------- -#ifndef _X360 - -static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} -static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} - -#else - -// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT -// this is much faster than if ( aFloat > 0 ) { x = .. } -#define fsel __fsel - -#endif - - //----------------------------------------------------------------------------- // FP exception handling //----------------------------------------------------------------------------- @@ -1132,6 +1106,7 @@ PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded. PLATFORM_INTERFACE unsigned int Plat_MSTime(); // Time in milliseconds. +PLATFORM_INTERFACE char * Plat_asctime( const struct tm *tm, char *buf ); PLATFORM_INTERFACE char * Plat_ctime( const time_t *timep, char *buf, size_t bufsize ); PLATFORM_INTERFACE struct tm * Plat_gmtime( const time_t *timep, struct tm *result ); PLATFORM_INTERFACE time_t Plat_timegm( struct tm *timeptr ); @@ -1185,7 +1160,7 @@ inline uint64 Plat_Rdtsc() memcpy( this, &src, sizeof(_classname) ); \ return *this; \ } - + // Processor Information: struct CPUInformation { @@ -1213,9 +1188,6 @@ struct CPUInformation tchar* m_szProcessorID; // Processor vendor Identification. - uint32 m_nModel; - uint32 m_nFeatures[3]; - CPUInformation(): m_Size(0){} }; @@ -1292,7 +1264,7 @@ PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line ); // Returns true if debugger attached, false otherwise //----------------------------------------------------------------------------- #if defined(_WIN32) || defined(LINUX) || defined(OSX) -PLATFORM_INTERFACE bool Plat_IsInDebugSession(); +PLATFORM_INTERFACE bool Plat_IsInDebugSession( bool bForceRecheck = false ); PLATFORM_INTERFACE void Plat_DebugString( const char * ); #else inline bool Plat_IsInDebugSession( bool bForceRecheck = false ) { return false; } @@ -1305,6 +1277,15 @@ inline bool Plat_IsInDebugSession( bool bForceRecheck = false ) { return false; PLATFORM_INTERFACE bool Is64BitOS(); +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// General Mapbase version constants compiled into projects for versioning purposes +//----------------------------------------------------------------------------- +#define MAPBASE_VERSION "7.1" +#define MAPBASE_VER_INT 7100 // For use in #if in a similar fashion to macros like _MSC_VER +#endif + + //----------------------------------------------------------------------------- // XBOX Components valid in PC compilation space //----------------------------------------------------------------------------- @@ -1376,62 +1357,81 @@ inline const char *GetPlatformExt( void ) template inline T* Construct( T* pMemory ) { + HINT(pMemory != 0); return ::new( pMemory ) T; } template inline T* Construct( T* pMemory, ARG1 a1 ) { + HINT(pMemory != 0); return ::new( pMemory ) T( a1 ); } template inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2 ) { + HINT(pMemory != 0); return ::new( pMemory ) T( a1, a2 ); } template inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3 ) { + HINT(pMemory != 0); return ::new( pMemory ) T( a1, a2, a3 ); } template inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4 ) { + HINT(pMemory != 0); return ::new( pMemory ) T( a1, a2, a3, a4 ); } template inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5 ) { + HINT(pMemory != 0); return ::new( pMemory ) T( a1, a2, a3, a4, a5 ); } template inline void ConstructOneArg( T* pMemory, P const& arg) { + HINT(pMemory != 0); ::new( pMemory ) T(arg); } template inline void ConstructTwoArg( T* pMemory, P1 const& arg1, P2 const& arg2) { + HINT(pMemory != 0); ::new( pMemory ) T(arg1, arg2); } template inline void ConstructThreeArg( T* pMemory, P1 const& arg1, P2 const& arg2, P3 const& arg3) { + HINT(pMemory != 0); ::new( pMemory ) T(arg1, arg2, arg3); } template inline T* CopyConstruct( T* pMemory, T const& src ) { + HINT(pMemory != 0); return ::new( pMemory ) T(src); } + +#ifdef VALVE_RVALUE_REFS +template +inline void CopyConstruct(T* pMemory, T&& src) +{ + HINT(pMemory != 0); + ::new(pMemory)T(std::forward(src)); +} +#endif template inline void Destruct( T* pMemory ) @@ -1608,20 +1608,6 @@ class CDynamicFunction #endif -// Watchdog timer support. Call Plat_BeginWatchdogTimer( nn ) to kick the timer off. if you don't call -// Plat_EndWatchdogTimer within nn seconds, the program will kick off an exception. This is for making -// sure that hung dedicated servers abort (and restart) instead of staying hung. Calling -// Plat_EndWatchdogTimer more than once or when there is no active watchdog is fine. Only does anything -// under linux right now. It should be possible to implement this functionality in windows via a -// thread, if desired. -PLATFORM_INTERFACE void Plat_BeginWatchdogTimer( int nSecs ); -PLATFORM_INTERFACE void Plat_EndWatchdogTimer( void ); -PLATFORM_INTERFACE int Plat_GetWatchdogTime( void ); - -typedef void (*Plat_WatchDogHandlerFunction_t)(void); -PLATFORM_INTERFACE void Plat_SetWatchdogHandlerFunction( Plat_WatchDogHandlerFunction_t function ); - - //----------------------------------------------------------------------------- #include "tier0/valve_on.h" diff --git a/public/tier0/stacktools.h b/public/tier0/stacktools.h deleted file mode 100644 index c356b8c0..00000000 --- a/public/tier0/stacktools.h +++ /dev/null @@ -1,153 +0,0 @@ -//========= Copyright � 1996-2008, Valve Corporation, All rights reserved. ============// -// -// Purpose: Tools for grabbing/dumping the stack at runtime -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef TIER0_STACKTOOLS_H -#define TIER0_STACKTOOLS_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/platform.h" - -#if (defined( PLATFORM_WINDOWS ) || defined( PLATFORM_X360 )) && !defined( STEAM ) && !defined( _CERT ) && defined( TCHAR_IS_CHAR ) //designed for windows/x360, not built/tested with wide characters, not intended for release builds (but probably wouldn't damage anything) -# define ENABLE_RUNTIME_STACK_TRANSLATION //uncomment to enable runtime stack translation tools. All of which use on-demand loading of necessary dll's and pdb's -#endif - -#if defined( ENABLE_RUNTIME_STACK_TRANSLATION ) -//#define ENABLE_THREAD_PARENT_STACK_TRACING 1 //uncomment to actually enable tracking stack traces from threads and jobs to their parent thread. Must also define THREAD_PARENT_STACK_TRACE_SUPPORTED in threadtools.h -# if defined( ENABLE_THREAD_PARENT_STACK_TRACING ) -# define THREAD_PARENT_STACK_TRACE_LENGTH 32 -# endif -#endif - - - - -PLATFORM_INTERFACE int GetCallStack( void **pReturnAddressesOut, int iArrayCount, int iSkipCount ); - -//ONLY WORKS IF THE CRAWLED PORTION OF THE STACK DISABLES FRAME POINTER OMISSION (/Oy-) "vpc /nofpo" -PLATFORM_INTERFACE int GetCallStack_Fast( void **pReturnAddressesOut, int iArrayCount, int iSkipCount ); - -typedef int (*FN_GetCallStack)( void **pReturnAddressesOut, int iArrayCount, int iSkipCount ); - -//where we'll find our PDB's for win32. -PLATFORM_INTERFACE void SetStackTranslationSymbolSearchPath( const char *szSemicolonSeparatedList = NULL ); -PLATFORM_INTERFACE void StackToolsNotify_LoadedLibrary( const char *szLibName ); - -//maximum output sample "tier0.dll!TranslateStackInfo - u:\Dev\L4D\src\tier0\stacktools.cpp(162) + 4 bytes" -enum TranslateStackInfo_StyleFlags_t -{ - TSISTYLEFLAG_NONE = 0, - TSISTYLEFLAG_MODULENAME = (1<<0), //start with module Sample: "tier0.dll!" - TSISTYLEFLAG_SYMBOLNAME = (1<<1), //include the symbol name Sample: "TranslateStackInfo" - TSISTYLEFLAG_FULLPATH = (1<<2), //include full path Sample: "u:\Dev\L4D\src\tier0\stacktools.cpp" - TSISTYLEFLAG_SHORTPATH = (1<<3), //only include 2 directories Sample: "\src\tier0\stacktools.cpp" - TSISTYLEFLAG_LINE = (1<<4), //file line number Sample: "(162)" - TSISTYLEFLAG_LINEANDOFFSET = (1<<5), //file line + offset Sample: "(162) + 4 bytes" - TSISTYLEFLAG_LAST = TSISTYLEFLAG_LINEANDOFFSET, - TSISTYLEFLAG_DEFAULT = (TSISTYLEFLAG_MODULENAME | TSISTYLEFLAG_SYMBOLNAME | TSISTYLEFLAG_FULLPATH | TSISTYLEFLAG_LINEANDOFFSET), //produces sample above -}; - -//Generates a formatted list of function information, returns number of translated entries -//On 360 this generates a string that can be decoded by VXConsole in print functions. Optimal path for translation because it's one way. Other paths require multiple transactions. -PLATFORM_INTERFACE int TranslateStackInfo( const void * const *pCallStack, int iCallStackCount, tchar *szOutput, int iOutBufferSize, const tchar *szEntrySeparator, TranslateStackInfo_StyleFlags_t style = TSISTYLEFLAG_DEFAULT ); - -PLATFORM_INTERFACE void PreloadStackInformation( void * const *pAddresses, int iAddressCount ); //caches data and reduces communication with VXConsole to speed up 360 decoding when using any of the Get***FromAddress() functions. Nop on PC. -PLATFORM_INTERFACE bool GetFileAndLineFromAddress( const void *pAddress, tchar *pFileNameOut, int iMaxFileNameLength, uint32 &iLineNumberOut, uint32 *pDisplacementOut = NULL ); -PLATFORM_INTERFACE bool GetSymbolNameFromAddress( const void *pAddress, tchar *pSymbolNameOut, int iMaxSymbolNameLength, uint64 *pDisplacementOut = NULL ); -PLATFORM_INTERFACE bool GetModuleNameFromAddress( const void *pAddress, tchar *pModuleNameOut, int iMaxModuleNameLength ); - - - -class PLATFORM_CLASS CCallStackStorage //a helper class to grab a stack trace as close to the leaf code surface as possible, then pass it on to deeper functions intact with less unpredictable inlining pollution -{ -public: - CCallStackStorage( FN_GetCallStack GetStackFunction = GetCallStack, uint32 iSkipCalls = 0 ); - CCallStackStorage( const CCallStackStorage ©From ) - { - iValidEntries = copyFrom.iValidEntries; - memcpy( pStack, copyFrom.pStack, sizeof( void * ) * copyFrom.iValidEntries ); - } - - void *pStack[128]; //probably too big, possibly too small for some applications. Don't want to spend the time figuring out how to generalize this without templatizing pollution or mallocs - uint32 iValidEntries; -}; - - -//Hold onto one of these to denote the top of a functional stack trace. Also allows us to string together threads to their parents -class PLATFORM_CLASS CStackTop_Base -{ -protected: -#if defined( ENABLE_RUNTIME_STACK_TRANSLATION ) - CStackTop_Base *m_pPrevTop; - void *m_pStackBase; - void *m_pReplaceAddress; - - void * const *m_pParentStackTrace; - int m_iParentStackTraceLength; -#endif -}; - -//makes a copy of the parent stack -class PLATFORM_CLASS CStackTop_CopyParentStack : public CStackTop_Base -{ -public: - CStackTop_CopyParentStack( void * const * pParentStackTrace, int iParentStackTraceLength ); - ~CStackTop_CopyParentStack( void ); -}; - -//just references the parent stack. Assuming that you'll keep that memory around as long as you're keeping this Stack Top marker. -class PLATFORM_CLASS CStackTop_ReferenceParentStack : public CStackTop_Base -{ -public: - CStackTop_ReferenceParentStack( void * const * pParentStackTrace = NULL, int iParentStackTraceLength = 0 ); - ~CStackTop_ReferenceParentStack( void ); - void ReleaseParentStackReferences( void ); //in case you need to delete the parent stack trace before this class goes out of scope -}; - - -//Encodes data so that every byte's most significant bit is a 1. Ensuring no null terminators. -//This puts the encoded data in the 128-255 value range. Leaving all standard ascii characters for control. -//Returns string length (not including the written null terminator as is standard). -//Or if the buffer is too small. Returns negative of necessary buffer size (including room needed for null terminator) -PLATFORM_INTERFACE int EncodeBinaryToString( const void *pToEncode, int iDataLength, char *pEncodeOut, int iEncodeBufferSize ); - -//Decodes a string produced by EncodeBinaryToString(). Safe to decode in place if you don't mind trashing your string, binary byte count always less than string byte count. -//Returns: -// >= 0 is the decoded data size -// INT_MIN (most negative value possible) indicates an improperly formatted string (not our data) -// all other negative values are the negative of how much dest buffer size is necessary. -PLATFORM_INTERFACE int DecodeBinaryFromString( const char *pString, void *pDestBuffer, int iDestBufferSize, char **ppParseFinishOut = NULL ); - - - - -// 360<->VXConsole specific communication definitions -#define XBX_CALLSTACKDECODEPREFIX ":CSDECODE[" - -enum StackTranslation_BinaryHandler_Command_t -{ - ST_BHC_LOADEDLIBARY, - ST_BHC_GETTRANSLATIONINFO, -}; - -#pragma pack(push) -#pragma pack(1) -struct FullStackInfo_t -{ - const void *pAddress; - char szModuleName[24]; - char szFileName[MAX_PATH/2]; - char szSymbol[64]; - uint32 iLine; - uint32 iSymbolOffset; - -}; -#pragma pack(pop) - -#endif //#ifndef TIER0_STACKTOOLS_H diff --git a/public/tier0/threadtools.h b/public/tier0/threadtools.h index e5b720e2..a8e20985 100644 --- a/public/tier0/threadtools.h +++ b/public/tier0/threadtools.h @@ -233,7 +233,7 @@ inline void const *ThreadInterlockedExchangePointerToConst( void const * volatil inline void const *ThreadInterlockedCompareExchangePointerToConst( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedCompareExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); } inline bool ThreadInterlockedAssignPointerToConstIf( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedAssignPointerIf( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); } -#if defined( PLATFORM_64BITS ) +#if defined( X64BITS ) #if defined (_WIN32) typedef __m128i int128; inline int128 int128_zero() { return _mm_setzero_si128(); } @@ -289,30 +289,6 @@ PLATFORM_INTERFACE void ThreadNotifySyncReleasing(void *p); // work in a DLL loaded with LoadLibrary() //----------------------------------------------------------------------------- -#ifndef NO_THREAD_LOCAL - -#if defined(_LINUX) && !defined(OSX) -// linux totally supports compiler thread locals, even across dll's. -#define PLAT_COMPILER_SUPPORTED_THREADLOCALS 1 -#define CTHREADLOCALINTEGER( typ ) __thread int -#define CTHREADLOCALINT __thread int -#define CTHREADLOCALPTR( typ ) __thread typ * -#define CTHREADLOCAL( typ ) __thread typ -#define GETLOCAL( x ) ( x ) -#endif // _LINUX && !OSX - -#if defined(WIN32) || defined(OSX) -#ifndef __AFXTLS_H__ // not compatible with some Windows headers -#define CTHREADLOCALINT CThreadLocalInt -#define CTHREADLOCALINTEGER( typ ) CThreadLocalInt -#define CTHREADLOCALPTR( typ ) CThreadLocalPtr -#define CTHREADLOCAL( typ ) CThreadLocal -#define GETLOCAL( x ) ( x.Get() ) -#endif -#endif // WIN32 || OSX - -#endif // NO_THREAD_LOCALS - #ifndef __AFXTLS_H__ // not compatible with some Windows headers #ifndef NO_THREAD_LOCAL @@ -370,7 +346,7 @@ template COMPILE_TIME_ASSERT( sizeof(T) >= sizeof(int) ); } - operator int() const { return (int)this->Get(); } + operator const int() const { return (int)this->Get(); } int operator=( int i ) { this->Set( (intp)i ); return i; } int operator++() { T i = this->Get(); this->Set( ++i ); return (int)i; } @@ -508,7 +484,7 @@ class CInterlockedPtr bool operator==( T *rhs ) const { return ( m_value == rhs ); } bool operator!=( T *rhs ) const { return ( m_value != rhs ); } -#if defined( PLATFORM_64BITS ) +#ifdef X64BITS T *operator++() { return ((T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) )) + 1; } T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) ); } @@ -547,41 +523,6 @@ class CInterlockedPtr T * volatile m_value; }; -//----------------------------------------------------------------------------- -// -// Platform independent verification that multiple threads aren't getting into the same code at the same time. -// Note: This is intended for use to identify problems, it doesn't provide any sort of thread safety. -// -//----------------------------------------------------------------------------- -class ReentrancyVerifier -{ -public: - inline ReentrancyVerifier(CInterlockedInt* counter, int sleepTimeMS) - : mCounter(counter) - { - Assert(mCounter != NULL); - - if (++(*mCounter) != 1) { - DebuggerBreakIfDebugging_StagingOnly(); - } - - if (sleepTimeMS > 0) - { - ThreadSleep(sleepTimeMS); - } - } - - inline ~ReentrancyVerifier() - { - if (--(*mCounter) != 0) { - DebuggerBreakIfDebugging_StagingOnly(); - } - } - -private: - CInterlockedInt* mCounter; -}; - //----------------------------------------------------------------------------- // @@ -866,7 +807,7 @@ class CAutoLockT MUTEX_TYPE &m_lock; // Disallow copying - CAutoLockT( const CAutoLockT & ); + CAutoLockT( const CAutoLockT & ); CAutoLockT &operator=( const CAutoLockT & ); }; @@ -893,7 +834,7 @@ template T strip_cv_quals_for_mutex(volatile T&); template T strip_cv_quals_for_mutex(const volatile T&); #define AUTO_LOCK( mutex ) \ - AUTO_LOCK_( typeof(::strip_cv_quals_for_mutex(mutex)), mutex ) + AUTO_LOCK_( decltype(::strip_cv_quals_for_mutex(mutex)), mutex ) #else // GNUC @@ -1075,7 +1016,7 @@ inline int ThreadWaitForEvents( int nEvents, CThreadEvent * const *pEvents, bool return WAIT_TIMEOUT; #else HANDLE handles[64]; - for ( unsigned int i = 0; i < min( nEvents, ARRAYSIZE(handles) ); i++ ) + for ( unsigned int i = 0; i < MIN( nEvents, ARRAYSIZE(handles) ); i++ ) handles[i] = pEvents[i]->GetHandle(); return ThreadWaitForObjects( nEvents, handles, bWaitAll, timeout ); #endif @@ -1286,9 +1227,9 @@ class PLATFORM_CLASS CThread CThreadMutex m_Lock; #ifdef WIN32 - ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; } + const ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; } #else - ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; } + const ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; } #endif private: diff --git a/public/tier0/tmapi_dummy.h b/public/tier0/tmapi_dummy.h index 8a6aebcb..f50a039a 100644 --- a/public/tier0/tmapi_dummy.h +++ b/public/tier0/tmapi_dummy.h @@ -30,17 +30,11 @@ #define tmEnterEx(...) #define tmZone(...) #define tmZoneFiltered(...) -#define tmLeave(...) #define tmLeaveEx(...) #define tmBeginTimeSpan(...) #define tmEndTimeSpan(...) -#define tmBeginTimeSpanAt(...) -#define tmEndTimeSpanAt(...) - -#define tmDynamicString(...) "" - #define tmEmitAccumulationZone(...) #define tmGetStati(...) 0 diff --git a/public/tier0/valve_minmax_on.h b/public/tier0/valve_minmax_on.h index 738eabc1..f1e6e496 100644 --- a/public/tier0/valve_minmax_on.h +++ b/public/tier0/valve_minmax_on.h @@ -1,9 +1,9 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -#if !defined(POSIX) -#ifndef min - #define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef max - #define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#endif +//#if !defined(POSIX) +//#ifndef min +// #define MIN(a,b) (((a) < (b)) ? (a) : (b)) +//#endif +//#ifndef max +// #define MAX(a,b) (((a) > (b)) ? (a) : (b)) +//#endif +//#endif diff --git a/public/tier0/vprof.h b/public/tier0/vprof.h index 1c7321bb..2e60e17f 100644 --- a/public/tier0/vprof.h +++ b/public/tier0/vprof.h @@ -135,13 +135,11 @@ #define VPROF_BUDGETGROUP_JOBS_COROUTINES _T("Jobs/Coroutines") #define VPROF_BUDGETGROUP_SLEEPING _T("Sleeping") #define VPROF_BUDGETGROUP_THREADINGMAIN _T("ThreadingMain") -#define VPROF_BUDGETGROUP_HTMLSURFACE _T("HTMLSurface") -#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_HTMLSURFACE -#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_HTMLSURFACE -#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_HTMLSURFACE +#define VPROF_BUDGETGROUP_CHROMEHTML _T("Chromehtml") +#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_CHROMEHTML +#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_CHROMEHTML +#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_CHROMEHTML #define VPROF_BUDGETGROUP_ATTRIBUTES _T("Attributes") -#define VPROF_BUDGETGROUP_FINDATTRIBUTE _T("FindAttribute") -#define VPROF_BUDGETGROUP_FINDATTRIBUTEUNSAFE _T("FindAttributeUnsafe") #ifdef _X360 // update flags @@ -163,28 +161,28 @@ #define VPROF_VAR_NAME_INTERNAL( a, b ) VPROF_VAR_NAME_INTERNAL_CAT( a, b ) #define VPROF_VAR_NAME( a ) VPROF_VAR_NAME_INTERNAL( a, __LINE__ ) -#define VPROF_0(name,group,assertAccounted,budgetFlags) tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags); +#define VPROF_0(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags); #if VPROF_LEVEL > 0 -#define VPROF_1(name,group,assertAccounted,budgetFlags) tmZone( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags); +#define VPROF_1(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags); #else #define VPROF_1(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 1 -#define VPROF_2(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags); +#define VPROF_2(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL4, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags); #else #define VPROF_2(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 2 -#define VPROF_3(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags); +#define VPROF_3(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL5, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags); #else #define VPROF_3(name,group,assertAccounted,budgetFlags) ((void)0) #endif #if VPROF_LEVEL > 3 -#define VPROF_4(name,group,assertAccounted,budgetFlags) CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags); +#define VPROF_4(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL6, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags); #else #define VPROF_4(name,group,assertAccounted,budgetFlags) ((void)0) #endif diff --git a/public/tier0/vprof_telemetry.h b/public/tier0/vprof_telemetry.h index c60bde5d..f3df4f4b 100644 --- a/public/tier0/vprof_telemetry.h +++ b/public/tier0/vprof_telemetry.h @@ -15,35 +15,27 @@ #define RAD_TELEMETRY_ENABLED #endif -#endif // !MAKE_VPC +#endif // !defined( MAKE_VPC ) #if !defined( RAD_TELEMETRY_ENABLED ) // -// Kill all tmZone() macros, etc. +// If Telemetry isn't enabled, then kill all the tmZone() macros, etc. // +#define NTELEMETRY 1 +// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here. +#undef RADCOPYRIGHT + #include "tmapi_dummy.h" inline void TelemetryTick() {} inline void TelemetrySetLevel( unsigned int Level ) {} -#define TelemetrySetLockName( _ctx, _location, _description ) -class CTelemetryLock -{ -public: - CTelemetryLock(void *plocation, const char *description) {} - ~CTelemetryLock() {} - void Locked() {} - void Unlocked() {} -}; +#define TELEMETRY_REQUIRED( tmRequiredCode ) //a basic wrapper to only enable code if telemetry is present +#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) replacementCode //in case you need to replace the code with something specific if telemetry isn't present -class CTelemetrySpikeDetector -{ -public: - CTelemetrySpikeDetector( const char *msg, uint32 threshold = 50 ) {} - ~CTelemetrySpikeDetector() { } -}; +//#define TMZF_NONE #else @@ -54,29 +46,940 @@ class CTelemetrySpikeDetector // Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here. #undef RADCOPYRIGHT +PLATFORM_INTERFACE void TelemetryTick(); +PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level ); + struct TelemetryData { HTELEMETRY tmContext[32]; float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to milliseconds. uint32 FrameCount; // Count of frames to capture before turning off. char ServerAddress[128]; // Server name to connect to. + uint32 ZoneFilterVal; // tmZoneFiltered default filtered value (in MicroSeconds) int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo). + float dotatime; // CDOTAGamerules::GetDOTATime() uint32 DemoTickStart; // Start telemetry on demo tick # uint32 DemoTickEnd; // End telemetry on demo tick # uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify) }; PLATFORM_INTERFACE TelemetryData g_Telemetry; -PLATFORM_INTERFACE void TelemetryTick(); -PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level ); +#define TELEMETRY_REQUIRED( tmRequiredCode ) tmRequiredCode //a basic wrapper to only enable code if telemetry is present +#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) tmRequiredCode //in case you need to replace the code with something specific if telemetry isn't present + +#endif // RAD_TELEMETRY_ENABLED + + + + + + + + + + +#define TELEMETRY_ERROR_BUILD_DISABLED TELEMETRY_REQUIRED_REPLACE( TMERR_DISABLED, 0x0001 ) +#define TELEMETRY_ERROR_DISCONNECTED TELEMETRY_REQUIRED_REPLACE( TMCS_DISCONNECTED, 0 ) + + +#define TELEMETRY_LEVEL0 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[0], 0 ) // high level tmZone() +#define TELEMETRY_LEVEL1 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[1], 0 ) // lower level tmZone(), tmZoneFiltered() +#define TELEMETRY_LEVEL2 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[2], 0 ) // VPROF_0 +#define TELEMETRY_LEVEL3 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[3], 0 ) // VPROF_1 +#define TELEMETRY_LEVEL4 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[4], 0 ) // VPROF_2 +#define TELEMETRY_LEVEL5 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[5], 0 ) // VPROF_3 +#define TELEMETRY_LEVEL6 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[6], 0 ) // VPROF_4 + +//__rdtsc() +#define TM_FAST_TIME() TELEMETRY_REQUIRED_REPLACE( tmFastTime(), 0 ) + + +//int RADEXPLINK tmLoadTelemetry( int const kUseCheckedDLL ); +// +//Description +// On dynamic library platforms, this function loads the Telemetry DLL (or shared library) and then hooks up all of the dynamic function pointers. +//Parameters +// kUseCheckedDLL [in] set to 0 if you want to use the release mode DLL or 1 if you want to use the checked DLL. The checked DLL is compiled with optimizations but does extra run time checks and reporting. +#define TM_LOAD_TELEMETRY(kUseCheckedDll) TELEMETRY_REQUIRED_REPLACE( tmLoadTelemetry(kUseCheckedDll), 0 ) + + +//TmErrorCode tmStartup( ); +// +//Description +// Starts up all of Telemetry. +#define TM_STARTUP() TELEMETRY_REQUIRED_REPLACE( tmStartup(), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmShutdown( ); +// +//Description +// Shuts down all of Telemetry. +#define TM_SHUTDOWN() TELEMETRY_REQUIRED( tmShutdown() ) + + +//TmErrorCode tmInitializeContext( HTELEMETRY * pcx,void * pArena,TmU32 const kArenaSize ); +// +//Description +// Initializes a context. +// +//Parameters +// pcx [out] pointer to a TmHandle in which to store a handle to the initialized context +// pArena [in] pointer to a memory buffer for use by Telemetry to create the context. Applications should never free or modify this memory unless tmShutdownContext has been called! +// kArenaSize [in] size of the memory buffer pointed to by pArena. You want this large enough so that Telemetry never stalls trying to send over the network, but not so large that it takes up too much memory from your app. A good initial value is 1MB. +#define TM_INITIALIZE_CONTEXT( pContext, pArena, kArenaSize ) TELEMETRY_REQUIRED_REPLACE( tmInitializeContext( pContext, pArena, kArenaSize ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmZoneFiltered( HTELEMETRY cx,TmU64 const kThreshold,TmU32 const kFlags,char const * kpFormat,... ); +// +//Description +// Identical to tmZone however also allows specification of threshold duration. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kThreshold [in] microseconds that the zone must span before being sent to server. +// kFlags [in] flags for the zone (same as those passed to tmEnter. +// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers. +#define TM_ZONE_FILTERED( context, kThreshold, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZoneFiltered( context, kThreshold, kFlags, kpFormat, ##__VA_ARGS__ ) ) + + +//void tmZone( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormat,... ); +// +//Description +// Helper macro in C++ that creates an anonymous local object that automatically calls tmEnter and then tmLeave when exiting scope. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kFlags [in] flags for the zone (same as those passed to tmEnter +// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers. +#define TM_ZONE( context, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZone( context, kFlags, kpFormat, ##__VA_ARGS__ ) ) + +//Standardized zones +#define TM_ZONE_DEFAULT( context ) TM_ZONE( context, TMZF_NONE, __FUNCTION__ ) +#define TM_ZONE_IDLE( context ) TM_ZONE( context, TMZF_IDLE, __FUNCTION__ ) +#define TM_ZONE_STALL( context ) TM_ZONE( context, TMZF_STALL, __FUNCTION__ ) + + +//TmErrorCode tmCheckVersion( HTELEMETRY cx, TmU32 const major, TmU32 const minor, TmU32 const build, TmU32 const cust ); +// +//could not find documentation +#define TM_CHECK_VERSION( context, major, minor, build, cust ) TELEMETRY_REQUIRED_REPLACE( tmCheckVersion( context, major, minor, build, cust ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//TmErrorCode tmListenIPC( HTELEMETRY cx, char const *name ); +// +//could not find documentation +#define TM_LISTEN_IPC( context, name ) TELEMETRY_REQUIRED_REPLACE( tmListenIPC( context, name ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmUpdateSymbolData( HTELEMETRY cx ); +// +//Description +// Tells Telemetry to rescan loaded modules for symbol database information. +// +//Parameters +// cx [in] a valid context +#define TM_UPDATE_SYMBOL_DATA( context ) TELEMETRY_REQUIRED( tmUpdateSymbolData( context ) ) + + +//TmErrorCode tmGetSessionName( HTELEMETRY cx,char * dst,int const kDstSize ); +// +//Description +// Gets the name of the current session as determined by the server. +// +//Parameters +// cx [in] a valid context +// dst [in] pointer to buffer in which to copy the name +// kDstSize [in] size of dst +#define TM_GET_SESSION_NAME( context, dst, kDstSize ) TELEMETRY_REQUIRED_REPLACE( tmGetSessionName( context, dst, kDstSize ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmUnwindToDebugZoneLevel( HTELEMETRY cx,int const kLevel ); +// +//Description +// Unwinds the current thread's zone stack back to the given level. +// +//Parameters +// cx [in] a valid context +// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel +#define TM_UNWIND_TO_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmUnwindToDebugZoneLevel( context, kLevel ) ) + + +//void tmSetDebugZoneLevel( HTELEMETRY cx,int const kLevel ); +// +//Description +// Set the Telemetry debug zone level. +// +//Parameters +// cx [in] a valid context +// kLevel [in] an arbitrary constant used to differentiate this zone level from another +#define TM_SET_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmSetDebugZoneLevel( context, kLevel ) ) + + +//void tmCheckDebugZoneLevel( HTELEMETRY cx,int const kLevel ); +// +//Description +// Check the current Telemetry debug zone level. +// +//Parameters +// cx [in] a valid context +// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel +#define TM_CHECK_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmCheckDebugZoneLevel( context, kLevel ) ) + + +//int tmGetCallStack( HTELEMETRY cx,TmCallStack * dst ); +// +//Description +// Retrieves the callstack for the current thread. +// +//Parameters +// cx [in] a valid context +// dst [in] TmCallStack structure in which to store the callstack information +#define TM_GET_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmGetCallStack( context, TmCallStack_Ptr ), 0 ) + + +//int tmSendCallStack( HTELEMETRY cx,TmCallStack const * kpCallStack ); +// +//Description +// Sends the current callstack to the server so that later references with string format specifiers are up to date. +// +//Parameters +// cx [in] a valid context +// kpCallStack [in] pointer to a pre-existing callstack or 0 if it should use the current callstack +#define TM_SEND_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmSendCallStack( context, TmCallStack_Ptr ), 0 ) + + +//TmErrorCode tmGetLastError( HTELEMETRY cx ); +// +//Description +// Returns and clears the current error condition for the given context. +// +//Parameters +// cx [in] handle to a valid Telemetry context +#define TM_GET_LAST_ERROR( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastError( context ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmShutdownContext( HTELEMETRY cx ); +// +//Description +// Shuts down the given context. +// +//Parameters +// cx [in] handle to a valid context +#define TM_SHUTDOWN_CONTEXT( context ) TELEMETRY_REQUIRED( tmShutdownContext( context ) ) + + +//TmU64 tmGetAccumulationStart( HTELEMETRY cx ); +// +//Description +// Gets the start time for a set of accumulation zones. +// +//Parameters +// cx [in] handle to a telemetry context +// +//Return value +// return [out] start time for use with tmEmitAccumulationZone. +#define TM_GET_ACCUMULATION_START( context ) TELEMETRY_REQUIRED_REPLACE( tmGetAccumulationStart( context ), 0 ) + + +//TmU64 tmGetLastContextSwitchTime( HTELEMETRY cx ); +// +//Description +// Returns the time of the last received context switch event. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// +//Return value +// return [out] the time of the last received context switch event, or 0 on failure (e.g. invalid context, context switches disabled, etc.) +#define TM_GET_LAST_CONTEXT_SWITCH_TIME( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastContextSwitchTime( context ), 0 ) -#define TELEMETRY_LEVEL0 g_Telemetry.tmContext[0] // high level tmZone() -#define TELEMETRY_LEVEL1 g_Telemetry.tmContext[1] // lower level tmZone(), tmZoneFiltered() -#define TELEMETRY_LEVEL2 g_Telemetry.tmContext[2] // VPROF_0 -#define TELEMETRY_LEVEL3 g_Telemetry.tmContext[3] // VPROF_1 -#define TELEMETRY_LEVEL4 g_Telemetry.tmContext[4] // VPROF_2 -#define TELEMETRY_LEVEL5 g_Telemetry.tmContext[5] // VPROF_3 -#define TELEMETRY_LEVEL6 g_Telemetry.tmContext[6] // VPROF_4 + +//void tmEnterAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable ); +// +//Description +// Updates a zone variable passed to tmEmitAccumulationZone later. +// +//Parameters +// cx [in] handle to a telemetry context +// zone_variable [in] zone_variable to update +#define TM_ENTER_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmEnterAccumulationZone( context, zone_variable ) ) + + +//void tmLeaveAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable ); +// +//Description +// Updates a zone variable passed to tmEmitAccumulationZone later. +// +//Parameters +// cx [in] handle to a telemetry context +// zone_variable [in] zone_variable to update +#define TM_LEAVE_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmLeaveAccumulationZone( context, zone_variable ) ) + + +//void tmGetFormatCode( TmU32* pCode, char const * kpFmt ); +// +//could not find documentation +#define TM_GET_FORMAT_CODE( context, pCode, kpFmt ) TELEMETRY_REQUIRED( tmGetFormatCode( context, pCode, kpFmt ) ) + + +//char const * tmDynamicString( HTELEMETRY cx,char const * kpString ); +// +//Description +// Returns an opaque string identifier usable by Telemetry that is a copy of the kpString parameter. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpString [in] string to copy +#define TM_DYNAMIC_STRING( context, kpString ) TELEMETRY_REQUIRED_REPLACE( tmDynamicString( context, kpString ), NULL ) + + +//void tmClearStaticString( HTELEMETRY cx,char const * kpString ); +// +//Description +// Marks the given string pointer as 'changed', forcing Telemetry to resend its contents. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpString [in] string to reset +#define TM_CLEAR_STATIC_STRING( context, kpString ) TELEMETRY_REQUIRED( tmClearStaticString( context, kpString ) ) + + +//void tmEnable( HTELEMETRY cx,TmOption const kOption,int const kValue ); +// +//Description +// Enables or disables a specific Telemetry option. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kOption [in] the option to modify. One of the TmOption constants. +// kValue [in] the new value for the option. Must be 0 (disable) or 1 (enable). +#define TM_ENABLE( context, kOption, kValue ) TELEMETRY_REQUIRED( tmEnable( context, kOption, kValue ) ) + + +//int tmIsEnabled( HTELEMETRY cx,TmOption const kOption ); +// +//Description +// Inspects the state of a Telemetry option. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kOption [in] the option to inspect. Must be one of the TmOption constants. +// +//Return value +// return [out] 1 if the option is enabled, 0 if not enabled. In case of error, 0 is enabled and last error is set. +#define TM_IS_ENABLED( context, kOption ) TELEMETRY_REQUIRED_REPLACE( tmIsEnabled( context, kOption ), 0 ) + +//void tmSetParameter( HTELEMETRY cx,TmParameter const kParameter,void const * kpValue ); +// +//Description +// Sets a Telemetry parameter. +// +//Parameters +// cx [in] a valid context +// kParameter [in] TmParameter constant +// kpValue [in] pointer to value of the parameter. This varies depending on the value. +#define TM_SET_PARAMETER( context, kParameter, kpValue ) TELEMETRY_REQUIRED( tmSetParameter( context, kParameter, kpValue ) ) + + +//TmErrorCode tmOpen( HTELEMETRY cx,char const * kpAppName,char const * kpBuildInfo,char const * kpServerAddress,TmConnectionType const kConnection,TmU16 const kServerPort,TmU32 const kFlags,int const kTimeoutMS ); +// +//Description +// Starts a Telemetry context and attempts to connect to a Telemetry server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpAppName [in] name of the application. NOTE: This MUST be alphanumeric only, e.g. "Game234", no spaces, special characters, etc. are allowed. +// kpBuildInfo [in] information about the application. Used to annotate this Telemetry session. This information will show up when connecting to the server later to examine this particular run. Common uses include build numbers, compiled options, etc. +// kpServerAddress [in] name or IP address of the Telemetry server to connect to +// kConnection [in] type of connection to establish. Currently only TMCT_TCP is supported. +// kServerPort [in] port to connect to. Specify 0 or TELEMETRY_DEFAULT_PORT for the default port. +// kFlags [in] bitwise OR of TmOpenFlag flags +// kTimeoutMS [in] duration, in milliseconds, to wait for a connection to the Telemetry server. Specify -1 to wait indefinitely. +// +//Return value +// return [out] TM_OK on success, or on error one of the following: TMERR_INVALID_PARAM, TMERR_INVALID_CONTEXT, TMERR_UNKNOWN_NETWORK. +#define TM_OPEN( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ) TELEMETRY_REQUIRED_REPLACE( tmOpen( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ), TELEMETRY_ERROR_BUILD_DISABLED ) + + +//void tmClose( HTELEMETRY cx ); +// +//Description +// Closes a context previously opened with tmOpen. +// +//Parameters +// cx [in] handle to a valid and open Telemetry context +#define TM_CLOSE( context ) TELEMETRY_REQUIRED( tmClose( context ) ) + + +//void tmTick( HTELEMETRY cx ); +// +//Description +// "Ticks" the Telemetry context, i.e. signifies the end of a frame of execution so that Telemetry can perform internal processing and send data to the Telemetry server. +// +//Parameters +// cx [in] handle to a valid and open Telemetry context +#define TM_TICK( context ) TELEMETRY_REQUIRED( tmTick( context ) ) + + +//void tmFlush( HTELEMETRY cx ); +// +//cannot find documentation +#define TM_FLUSH( context ) TELEMETRY_REQUIRED( tmFlush( context ) ) + + +//void tmPause( HTELEMETRY cx,int const kPause ); +// +//Description +// Pauses/unpauses Telemetry capture. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPause [in] 1 to pause, 0 to unpause +#define TM_PAUSE( context, kPause ) TELEMETRY_REQUIRED( tmPause( context, kPause ) ) + + +//int tmIsPaused( HTELEMETRY cx ); +// +//cannot find documentation. Presumably returns 1 if paused, 0 if not +#define TM_IS_PAUSED( context ) TELEMETRY_REQUIRED_REPLACE( tmIsPaused( context ), 0 ) + + +//TmConnectionStatus tmGetConnectionStatus( HTELEMETRY cx ); +// +//Description +// Get the current connection status. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// +//Return value +// return [out] a TmConnectionStatus constant. On error returns TMCS_DISCONNECTED and sets the context's last error. +#define TM_GET_CONNECTION_STATUS( context ) TELEMETRY_REQUIRED_REPLACE( tmGetConnectionStatus( context ), TELEMETRY_ERROR_DISCONNECTED ) + + +//void tmFree( HTELEMETRY cx,void const * kpPtr ); +// +//Description +// Notify Telemetry that memory has been freed. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpPtr [in] address of the old memory block previously passed to a tmAlloc call +#define TM_FREE( context, kpPtr ) TELEMETRY_REQUIRED( tmFree( context, kpPtr ) ) + + +//TmI32 tmGetStati( HTELEMETRY cx,TmStat const kStat ); +// +//Description +// Retrieves internal Telemetry statistics. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kStat [in] the TmStat to retrieve +// +//Return value +// return [out] the value of the indicated internal statistic. On error returns 0 and sets last error. +#define TM_GET_STAT_I( context, kStat ) TELEMETRY_REQUIRED_REPLACE( tmGetStati( context, kStat ), 0 ) + + +//void tmLeave( HTELEMETRY cx ); +// +//Description +// Notify Telemetry that a zone is being left. +// +//Parameters +// cx [in] handle to a valid Telemetry context +#define TM_LEAVE( context ) TELEMETRY_REQUIRED( tmLeave( context ) ) + + +//void tmLeaveEx( HTELEMETRY cx,TmU64 const kMatchId,TmU32 const kThreadId,char const * kpFilename,int const kLine ); +// +//Description +// Notify Telemetry that a zone is being left. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kMatchId [in] match id returned by tmEnterEx, used for Zones: Runtime Zone Filtering by Duration . Pass 0 if you're not filtering. +// kThreadId [in] thread id for this zone. Pass 0 for 'current thread'. +// kpFilename [in] name of the file +// kLine [in] line number for the leave +#define TM_LEAVE_EX( context, kMatchId, kThreadId, kpFilename, kLine ) TELEMETRY_REQUIRED( tmLeaveEx( context, kMatchId, kThreadId, kpFilename, kLine ) ) + + +//void tmTryLock( HTELEMETRY cx,void const * kPtr,char const * kpLockName,... ); +// +//Description +// Notify Telemetry that an attempt to grab a lock is beginning. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] pointer to the item being locked +// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers. +#define TM_TRY_LOCK( context, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLock( context, kPtr, kpLockName, ##__VA_ARGS__ ) ) + + +//void tmTryLockEx( HTELEMETRY cx,TmU64 * matcher,TmU64 const kThreshold,char const * kpFileName,int const kLine,void const * kPtr,char const * kpLockName,... ); +// +//Description +// Same as tmTryLock, but also specifying file and line information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// matcher [in] reference in which to store a match ID used for later filtering by duration +// kpFileName [in] pointer to filename +// kLine [in] line number +// kPtr [in] pointer to the item being locked +// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers. +#define TM_TRY_LOCK_EX( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLockEx( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ##__VA_ARGS__ ) ) + + +//void tmEndTryLock( HTELEMETRY cx,void const * kPtr,TmLockResult const kResult ); +// +//Description +// Specify the result of a lock attempt previously started with tmTryLock. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] pointer for the object (mutex, etc.) being locked +// kResult [in] the result of the lock attempt, one of TmLockResult. +#define TM_END_TRY_LOCK( context, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLock( context, kPtr, kResult ) ) + + +//void tmEndTryLockEx( HTELEMETRY cx,TmU64 const kMatchId,char const * kpFileName,int const kLine,void const * kPtr,TmLockResult const kResult ); +// +//Description +// Specify the result of a lock attempt previously started with tmTryLock, but also with file and line information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kMatchId [in] match id returned from tmTryLockEx +// kpFileName [in] pointer to filename +// kLine [in] line number +// kPtr [in] pointer for the object (mutex, etc.) being locked +// kResult [in] the result of the lock attempt, one of TmLockResult. +#define TM_END_TRY_LOCK_EX( context, kMatchId, kpFileName, kLine, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLockEx( context, kMatchId, kpFileName, kLine, kPtr, kResult ) ) + + +//void tmBeginTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... ); +// +//Description +// Start the beginning of a timespan. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kId [in] a user defined identifier for the timespan. Should be > 0. +// kFlags [in] flags for the timespan. Reserved, must be 0. +// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. +#define TM_BEGIN_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmEndTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... ); +// +//Description +// Mark the end a timespan. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan. +// kFlags [in] flags for the timespan. Reserved, must be 0. +// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. +#define TM_END_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmBeginTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... ); +// +//Description +// Start the beginning of a timespan but at an explicit time. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kId [in] a user defined identifier for the timespan. Should be > 0. +// kFlags [in] flags for the timespan. Reserved, must be 0. +// kTimeStamp [in] explicit timestamp (e.g. from tmFastTime) +// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. +#define TM_BEGIN_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmEndTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... ); +// +//Description +// Mark the end a timespan, but with an explicit timestamp. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan. +// kFlags [in] flags for the timespan. Reserved, must be 0. +// kTimeStamp [in] a user specified timestamp (e.g. from tmFastTime. +// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers. +#define TM_END_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmSignalLockCount( HTELEMETRY cx,void const * kPtr,TmU32 const kCount,char const * kpDescription,... ); +// +//Description +// Signal that a semaphore's lock count has been incremented. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] pointer to the being whose count is being incremented (e.g. HANDLE) +// kCount [in] count value +// kpDescription [in] description of the event. This may contain printf-style format specifiers. +#define TM_SIGNAL_LOCK_COUNT( context, kPtr, kCount, kpDescription, ... ) TELEMETRY_REQUIRED( tmSignalLockCount( context, kPtr, kCount, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmSetLockState( HTELEMETRY cx,void const * kPtr,TmLockState const kState,char const * kpDescription,... ); +// +//Description +// Sets the state of a lock (mutex, critical section, semaphore, etc.) +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] identifier for the lock, typically its address or HANDLE +// kState [in] new state of the lock +// kpDescription [in] description of the event. This may contain printf-style format specifiers. +#define TM_SET_LOCK_STATE( context, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockState( context, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmSetLockStateEx( HTELEMETRY cx,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState ); +// +//Description +// Set the state of a lock but with explicit file and line information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpFilename [in] filename where the state change occurs +// kLine [in] line number of the state change +// kPtr [in] identifier for the lock, typically its address or HANDLE +// kState [in] new state of the lock +// kpDescription [in] description of the event. This may contain printf-style format specifiers. +#define TM_SET_LOCK_STATE_EX( context, kpFileName, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateEx( context, kpFileName, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmSetLockStateMinTime( HTELEMETRY cx,void * buf,void const * kPtr,TmLockState const kState,char const * fmt,... ); +// +//Description +// Set the state of a lock but with a minimum time threshold. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size. +// kPtr [in] identifier for the lock, typically its address or HANDLE +// kState [in] new state of the lock +// kpDescription [in] description of the event. This may contain printf-style format specifiers. +#define TM_SET_LOCK_STATE_MIN_TIME( context, buf, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTime( context, buf, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmSetLockStateMinTimeEx( HTELEMETRY cx,void * buf,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState ); +// +//Description +// This is the 'Ex' version of tmSetLockStateMinTimeEx. Please refer to tmSetLockStateEx and tmSetLockStateMinTime for more information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size. +// kpFilename [in] filename where the state change occurs +// kLine [in] line number of the state change +// kPtr [in] identifier for the lock, typically its address or HANDLE +// kState [in] new state of the lock +// kpDescription [in] description of the event. This may contain printf-style format specifiers. +#define TM_SET_LOCK_STATE_MIN_TIME_EX( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTimeEx( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmThreadName( HTELEMETRY cx,TmU32 const kThreadID,char const * kpNameFormat,... ); +// +//Description +// Sets the name of the specified thread. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kThreadID [in] thread identifier of the thread to name. Use 0 to specify the current thread. +// kpNameFormat [in] name of the thread. This may contain printf-style format specifiers. +#define TM_THREAD_NAME( context, kThreadID, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmThreadName( context, kThreadID, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmLockName( HTELEMETRY cx,void const* kPtr,char const * kpNameFormat,... ); +// +//Description +// Sets the name of the specified locking object. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] identifier for the lock. Usually you can supply a pointer/HANDLE. +// kpNameFormat [in] name of the lock. This may contain printf-style format specifiers. +#define TM_LOCK_NAME( context, kPtr, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmLockName( context, kPtr, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmEmitAccumulationZone( HTELEMETRY cx,TmU32 const kZoneFlags,TmU64 * pStart,int const kCount,TmU64 const kTotal,char const * kpZoneFormat,... ); +// +//Description +// Emits an accumulation zone. +// +//Parameters +// cx [in] handle to a valid telemetry context +// kZoneFlags [in] reserved, must be 0 +// pStart [out] pointer to start time variable retrieved with a prior call to tmGetAccumulationStart. This value is modified. +// kCount [in] number of times the accumulation zone was called +// kTotal [in] total amount of time spent in the accumulation zone +// kpZoneFormat [in] name of the accumulation zone. This may contain printf-style format specifiers. +#define TM_EMIT_ACCUMULATION_ZONE( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ... ) TELEMETRY_REQUIRED( tmEmitAccumulationZone( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ##__VA_ARGS__ ) ) + + +//void tmSetVariable( HTELEMETRY cx,char const * kpKey,char const * kpValueFormat,... ); +// +//Description +// Binds a string to a key name and sends to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpKey [in] pointer to string identify the key being set +// kpValueFormat [in] pointer to string to bind to the associated key. This may contain printf-style format specifiers. +#define TM_SET_VARIABLE( context, kpKey, kpValueFormat, ... ) TELEMETRY_REQUIRED( tmSetVariable( context, kpKey, kpValueFormat, ##__VA_ARGS__ ) ) + + +//void tmSetTimelineSectionName( HTELEMETRY cx,char const * kpNameFormat,... ); +// +//Description +// Changes the name of the global state. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpNameFormat [in] name of the current state. This may contain printf-style format specifiers. +#define TM_SET_TIMELINE_SECTION_NAME( context, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmSetTimelineSectionName( context, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmEnter( HTELEMETRY cx,TmU32 const kFlags,char const * kpZoneName,... ); +// +//Description +// Notify Telemetry that a zone is being entered. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kFlags [in] Bitwise OR of TmZoneFlag +// kpZoneName [in] name of the zone. This may contain printf-style format specifiers. +#define TM_ENTER( context, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnter( context, kFlags, kpZoneName, ##__VA_ARGS__ ) ) + + +//void tmEnterEx( HTELEMETRY cx,TmU64 * pMatchId,TmU32 const kThreadId,TmU64 const kThreshold,char const * kpFilename,int const kLine,TmU32 const kFlags,char const * kpZoneName,... ); +// +//Description +// Notify Telemetry that a zone is being entered, but with explicit file and line information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// pMatchId [in] pointer variable to assign a match ID, pass NULL if you are not Zones: Runtime Zone Filtering by Duration. +// kThreadId [in] thread ID for this zone, pass 0 for current thread +// kThreshold [in] microseconds that the zone must span before being sent to server. +// kpFilename [in] filename +// kLine [in] line number +// kFlags [in] Bitwise OR of TmZoneFlag +// kpZoneName [in] name of the zone. This may contain printf-style format specifiers. +#define TM_ENTER_EX( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnterEx( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ##__VA_ARGS__ ) ) + + +//void tmAlloc( HTELEMETRY cx,void const * kPtr,TmU64 const kSize,char const * kpDescription,... ); +// +//Description +// Notify Telemetry that memory has been allocated. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kPtr [in] address of the memory that has been allocated +// kSize [in] size of memory that has been allocated +// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers. +#define TM_ALLOC( context, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAlloc( context, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmAllocEx( HTELEMETRY cx,char const * kpFilename,int const kLineNumber,void const * kPtr,TmU64 const kSize,char const * kpDescription,... ); +// +//Description +// Notify Telemetry that memory has been allocated, but with explicit file and line information. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpFilename [in] name of the file +// kLineNumber [in] line number of the allocation +// kPtr [in] address of the memory that has been allocated +// kSize [in] size of memory that has been allocated +// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers. +#define TM_ALLOC_EX( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAllocEx( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) ) + + +//void tmMessage( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormatString,... ); +// +//Description +// Send a message to the server for later viewing in the Visualizer. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kFlags [in] Bitwise OR of TmMessageFlag +// kpFormatString [in] message string (not to exceed TM_MAX_STRING in length). This may contain printf-style format specifiers. Note that the message may have a Telemetry object path in it so that it can be hierarchically displayed with other messages. +#define TM_MESSAGE( context, kFlags, kpFormatString, ... ) TELEMETRY_REQUIRED( tmMessage( context, kFlags, kpFormatString, ##__VA_ARGS__ ) ) +#define TM_LOG( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_LOG, kpFormatString, ##__VA_ARGS__ ) +#define TM_WARNING( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_WARNING, kpFormatString, ##__VA_ARGS__ ) +#define TM_ERROR( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_ERROR, kpFormatString, ##__VA_ARGS__ ) + + + +//void tmPlot( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends a floating point plot value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlot( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//Identical to tmPlot() +//void tmPlotF32( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends a floating point plot value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_F32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmPlotF64( HTELEMETRY cx,TmPlotType const kType,double const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends a double precision floating point plot value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_F64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmPlotI32( HTELEMETRY cx,TmPlotType const kType,TmI32 const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends an signed 32-bit value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_I32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmPlotU32( HTELEMETRY cx,TmPlotType const kType,TmU32 const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends an unsigned 32-bit value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_U32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmPlotI64( HTELEMETRY cx,TmPlotType const kType,TmI64 const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends an signed 64-bit value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_I64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmPlotU64( HTELEMETRY cx,TmPlotType const kType,TmU64 const kValue,char const * kpNameFormat,... ); +// +//Description +// Sends an unsigned 64-bit value to the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value). +// kValue [in] the value of the plot at this moment in time +// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers. +#define TM_PLOT_U64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) ) + + +//void tmBlob( HTELEMETRY cx,void const * kpData,int const kDataSize,char const * kpPluginIdentifier,char const * kpBlobName,... ); +// +//Description +// Sends an arbitrary application specified blob of binary data for storage on the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kpData [in] the actual blob data +// kDataSize [in] size of kpData in bytes +// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier). +// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers. +#define TM_BLOB( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ...) TELEMETRY_REQUIRED( tmBlob( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) ) + + +//void tmDisjointBlob( HTELEMETRY cx,int const kNumPieces,void const ** kpData,int const * kDataSizes,char const* kpPluginIdentifier,char const * kpBlobName,... ); +// +//Description +// Sends an arbitrary application specified blob of binary data for storage on the server. +// +//Parameters +// cx [in] handle to a valid Telemetry context +// kNumPieces [in] number of elements in kpData and kDataSizes +// kpData [in] array of actual data blobs +// kDataSizes [in] array of data blob sizes in bytes +// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier). +// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers. +#define TM_DISJOINT_BLOB( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ... ) TELEMETRY_REQUIRED( tmDisjointBlob( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) ) + + + + + + + + + + + + +#if !defined( RAD_TELEMETRY_ENABLED ) + +// +// Telemetry is disabled. +// + +class CTelemetryLock +{ +public: + CTelemetryLock(void *plocation, const char *description) {} + ~CTelemetryLock() {} + void Locked() {} + void Unlocked() {} +}; + +class CTelemetrySpikeDetector +{ +public: + CTelemetrySpikeDetector( const char *msg, uint32 threshold = 50 ) {} + ~CTelemetrySpikeDetector() { } +}; + +#define TelemetrySetLockName( _ctx, _location, _description ) + +#else + +// +// Telemetry is enabled. +// #define TelemetrySetLockName( _ctx, _location, _description ) \ do \ @@ -97,7 +1000,7 @@ class CTelemetryLock m_plocation = (const char *)plocation; m_description = description; TelemetrySetLockName( TELEMETRY_LEVEL1, m_plocation, m_description ); - tmTryLock( TELEMETRY_LEVEL1, m_plocation, "%s", m_description ); + TM_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, "%s", m_description ); } ~CTelemetryLock() { @@ -105,14 +1008,14 @@ class CTelemetryLock } void Locked() { - tmEndTryLock( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS ); - tmSetLockState( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description ); + TM_END_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS ); + TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description ); } void Unlocked() { if( m_plocation ) { - tmSetLockState( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description ); + TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description ); m_plocation = NULL; } } @@ -133,7 +1036,7 @@ class CTelemetrySpikeDetector float time = ( tmFastTime() - time0 ) * g_Telemetry.flRDTSCToMilliSeconds; if( time >= m_threshold ) { - tmMessage( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(source/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) ); + TM_MESSAGE( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(dota/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) ); } } diff --git a/public/tier0/wchartypes.h b/public/tier0/wchartypes.h index 814470fd..9803870c 100644 --- a/public/tier0/wchartypes.h +++ b/public/tier0/wchartypes.h @@ -88,14 +88,6 @@ typedef char tchar; #define TCHAR_IS_CHAR #endif -#if defined( _MSC_VER ) || defined( WIN32 ) -typedef wchar_t uchar16; -typedef unsigned int uchar32; -#else -typedef unsigned short uchar16; -typedef wchar_t uchar32; -#endif - #ifdef FORCED_UNICODE #undef _UNICODE #endif diff --git a/public/tier1/KeyValues.h b/public/tier1/KeyValues.h index 97ae69c2..67b2f012 100644 --- a/public/tier1/KeyValues.h +++ b/public/tier1/KeyValues.h @@ -120,8 +120,8 @@ class KeyValues // File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t) void UsesEscapeSequences(bool state); // default false void UsesConditionals(bool state); // default true - bool LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, bool refreshCache = false ); - bool SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, bool sortKeys = false, bool bAllowEmptyString = false, bool bCacheResult = false ); + bool LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL ); + bool SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, bool sortKeys = false, bool bAllowEmptyString = false ); // Read from a buffer... Note that the buffer must be null terminated bool LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL ); @@ -144,8 +144,6 @@ class KeyValues // KeyValues *GetFirstSubKey() { return m_pSub; } // returns the first subkey in the list KeyValues *GetNextKey() { return m_pPeer; } // returns the next subkey - const KeyValues *GetNextKey() const { return m_pPeer; } // returns the next subkey - void SetNextKey( KeyValues * pDat); KeyValues *FindLastSubKey(); // returns the LAST subkey in the list. This requires a linked list iteration to find the key. Returns NULL if we don't have any children @@ -176,7 +174,7 @@ class KeyValues const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ); const wchar_t *GetWString( const char *keyName = NULL, const wchar_t *defaultValue = L"" ); void *GetPtr( const char *keyName = NULL, void *defaultValue = (void*)0 ); - bool GetBool( const char *keyName = NULL, bool defaultValue = false, bool* optGotDefault = NULL ); + bool GetBool( const char *keyName = NULL, bool defaultValue = false ); Color GetColor( const char *keyName = NULL /* default value is all black */); bool IsEmpty(const char *keyName = NULL); @@ -205,7 +203,7 @@ class KeyValues void operator delete( void *pMem ); void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ); - KeyValues& operator=( const KeyValues& src ); + KeyValues& operator=( KeyValues& src ); // Adds a chain... if we don't find stuff in this keyvalue, we'll look // in the one we're chained to. @@ -219,10 +217,6 @@ class KeyValues // Allocate & create a new copy of the keys KeyValues *MakeCopy( void ) const; - // Allocate & create a new copy of the keys, including the next keys. This is useful for top level files - // that don't use the usual convention of a root key with lots of children (like soundscape files). - KeyValues *MakeCopy( bool copySiblings ) const; - // Make a new copy of all subkeys, add them all to the passed-in keyvalues void CopySubkeys( KeyValues *pParent ) const; @@ -276,9 +270,7 @@ class KeyValues KeyValues* CreateKeyUsingKnownLastChild( const char *keyName, KeyValues *pLastChild ); void AddSubkeyUsingKnownLastChild( KeyValues *pSubKey, KeyValues *pLastChild ); - void CopyKeyValuesFromRecursive( const KeyValues& src ); - void CopyKeyValue( const KeyValues& src, size_t tmpBufferSizeB, char* tmpBuffer ); - + void RecursiveCopyKeyValues( KeyValues& src ); void RemoveEverything(); // void RecursiveSaveToFile( IBaseFileSystem *filesystem, CUtlBuffer &buffer, int indentLevel ); // void WriteConvertedString( CUtlBuffer &buffer, const char *pszString ); diff --git a/public/tier1/UtlSortVector.h b/public/tier1/UtlSortVector.h index 9890c607..b5bfef53 100644 --- a/public/tier1/UtlSortVector.h +++ b/public/tier1/UtlSortVector.h @@ -137,6 +137,7 @@ class CUtlSortVector : public BaseVector void *m_pLessContext; bool m_bNeedsSort; +private: private: template< typename TKey > int FindLessOrEqual( const TKey& search, bool *pFound ) const; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 832fbb00..37268cc4 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -21,6 +21,7 @@ #include "tier1/utlvector.h" #include "tier1/utlstring.h" #include "icvar.h" +#include "Color.h" #ifdef _WIN32 #define FORCEINLINE_CVAR FORCEINLINE @@ -137,7 +138,7 @@ class ConCommandBase virtual CVarDLLIdentifier_t GetDLLIdentifier() const; protected: - virtual void CreateBase( const char *pName, const char *pHelpString = 0, + virtual void Create( const char *pName, const char *pHelpString = 0, int flags = 0 ); // Used internally by OneTimeInit to initialize/shutdown @@ -300,6 +301,10 @@ friend class CCvar; ICommandCallback *m_pCommandCallback; }; +#ifdef MAPBASE_VSCRIPT + // Allow late modification of the completion callback. +public: +#endif union { FnCommandCompletionCallback m_fnCompletionCallback; @@ -307,6 +312,9 @@ friend class CCvar; }; bool m_bHasCompletionCallback : 1; +#ifdef MAPBASE_VSCRIPT +private: +#endif bool m_bUsingNewCommandCallback : 1; bool m_bUsingCommandCallbackInterface : 1; }; @@ -350,6 +358,7 @@ friend class ConVarRef; // Retrieve value FORCEINLINE_CVAR float GetFloat( void ) const; FORCEINLINE_CVAR int GetInt( void ) const; + FORCEINLINE_CVAR Color GetColor( void ) const; FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } FORCEINLINE_CVAR char const *GetString( void ) const; @@ -435,6 +444,16 @@ FORCEINLINE_CVAR int ConVar::GetInt( void ) const return m_pParent->m_nValue; } +//----------------------------------------------------------------------------- +// Purpose: Return ConVar value as a color +// Output : Color +//----------------------------------------------------------------------------- +FORCEINLINE_CVAR Color ConVar::GetColor( void ) const +{ + unsigned char *pColorElement = ((unsigned char *)&m_pParent->m_nValue); + return Color( pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3] ); +} + //----------------------------------------------------------------------------- // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. @@ -467,6 +486,7 @@ class ConVarRef // Get/Set value float GetFloat( void ) const; int GetInt( void ) const; + Color GetColor( void ) const; bool GetBool() const { return !!GetInt(); } const char *GetString( void ) const; @@ -521,6 +541,16 @@ FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const return m_pConVarState->m_nValue; } +//----------------------------------------------------------------------------- +// Purpose: Return ConVar value as a color +// Output : Color +//----------------------------------------------------------------------------- +FORCEINLINE_CVAR Color ConVarRef::GetColor( void ) const +{ + unsigned char *pColorElement = ((unsigned char *)&m_pConVarState->m_nValue); + return Color( pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3] ); +} + //----------------------------------------------------------------------------- // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. //----------------------------------------------------------------------------- @@ -632,6 +662,18 @@ class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, pu static ConCommand name##_command( #name, name, description ); \ static void name( const CCommand &args ) +#ifdef CLIENT_DLL + #define CON_COMMAND_SHARED( name, description ) \ + static void name( const CCommand &args ); \ + static ConCommand name##_command_client( #name "_client", name, description ); \ + static void name( const CCommand &args ) +#else + #define CON_COMMAND_SHARED( name, description ) \ + static void name( const CCommand &args ); \ + static ConCommand name##_command( #name, name, description ); \ + static void name( const CCommand &args ) +#endif + #define CON_COMMAND_F( name, description, flags ) \ static void name( const CCommand &args ); \ static ConCommand name##_command( #name, name, description, flags ); \ diff --git a/public/tier1/datamanager.h b/public/tier1/datamanager.h index 88030547..0c69133b 100644 --- a/public/tier1/datamanager.h +++ b/public/tier1/datamanager.h @@ -133,10 +133,10 @@ class CDataManager : public CDataManagerBase typedef CDataManagerBase BaseClass; public: - CDataManager( unsigned int size = (unsigned)-1 ) : BaseClass(size) {} + CDataManager( unsigned int size = (unsigned)-1 ) : BaseClass(size) {} - ~CDataManager() + ~CDataManager() { // NOTE: This must be called in all implementations of CDataManager FreeAllLists(); diff --git a/public/tier1/fmtstr.h b/public/tier1/fmtstr.h index 66ea88f5..556fc130 100644 --- a/public/tier1/fmtstr.h +++ b/public/tier1/fmtstr.h @@ -173,7 +173,7 @@ class CFmtStrN m_nLength = 0; } - void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 ) + void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... ) { char *pchEnd = m_szBuf + m_nLength; FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat, m_nLength, pchFormat ); diff --git a/public/tier1/ilocalize.h b/public/tier1/ilocalize.h index cbdb8f6e..fed7af6d 100644 --- a/public/tier1/ilocalize.h +++ b/public/tier1/ilocalize.h @@ -401,35 +401,6 @@ class CConstructLocalizedString } } - template < typename T, typename U, typename V, typename W, typename X, typename Y, typename Z > - CConstructLocalizedString( const locchar_t *loc_Format, T arg0, U arg1, V arg2, W arg3, X arg4, Y arg5, Z arg6) - { - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - COMPILE_TIME_ASSERT( CLocalizedStringArg::kIsValid ); - - m_loc_Buffer[0] = '\0'; - - if ( loc_Format ) - { - ::ILocalize::ConstructString( m_loc_Buffer, - sizeof( m_loc_Buffer ), - loc_Format, - 7, - CLocalizedStringArg( arg0 ).GetLocArg(), - CLocalizedStringArg( arg1 ).GetLocArg(), - CLocalizedStringArg( arg2 ).GetLocArg(), - CLocalizedStringArg( arg3 ).GetLocArg(), - CLocalizedStringArg( arg4 ).GetLocArg(), - CLocalizedStringArg( arg5 ).GetLocArg(), - CLocalizedStringArg( arg6 ).GetLocArg() ); - } - } - CConstructLocalizedString( const locchar_t *loc_Format, KeyValues *pKeyValues ) { m_loc_Buffer[0] = '\0'; diff --git a/game/shared/interval.h b/public/tier1/interval.h similarity index 100% rename from game/shared/interval.h rename to public/tier1/interval.h diff --git a/public/tier1/lzmaDecoder.h b/public/tier1/lzmaDecoder.h index 6f4b87fd..51ecfd1a 100644 --- a/public/tier1/lzmaDecoder.h +++ b/public/tier1/lzmaDecoder.h @@ -1,22 +1,15 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// // -// LZMA Codec interface for engine. +// LZMA Decoder. Designed for run time decoding. // -// LZMA SDK 9.38 beta -// 2015-01-03 : Igor Pavlov : Public domain -// http://www.7-zip.org/ +// LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) +// http://www.7-zip.org/ // -//========================================================================// +//=====================================================================================// #ifndef _LZMADECODER_H #define _LZMADECODER_H #pragma once -// Thanks for the useful define namespacing, LZMA -#include "../../utils/lzma/C/7zVersion.h" -#define LZMA_SDK_VERSION_MAJOR MY_VER_MAJOR -#define LZMA_SDK_VERSION_MINOR MY_VER_MINOR - #if !defined( _X360 ) #define LZMA_ID (('A'<<24)|('M'<<16)|('Z'<<8)|('L')) #else @@ -34,69 +27,15 @@ struct lzma_header_t }; #pragma pack() -class CLZMAStream; - class CLZMA { public: - static unsigned int Uncompress( unsigned char *pInput, unsigned char *pOutput ); - static bool IsCompressed( unsigned char *pInput ); - static unsigned int GetActualSize( unsigned char *pInput ); -}; - -// For files besides the implementation, we forward declare a dummy struct. We can't unconditionally forward declare -// this because LzmaEnc.h typedefs this directly to an unnamed struct :-/ -#ifndef CLzmaDec_t -struct _CLzmaDec_t; -#define CLzmaDec_t struct _CLzmaDec_t -#endif - -class CLZMAStream -{ -public: - CLZMAStream(); - ~CLZMAStream(); - - // Initialize a stream to read data from a LZMA style zip file, passing the original size from the zip headers. - // Streams with a source-engine style header (lzma_header_t) do not need an init call. - void InitZIPHeader( unsigned int nCompressedSize, unsigned int nOriginalSize ); - - // Attempt to read up to nMaxInputBytes from the compressed stream, writing up to nMaxOutputBytes to pOutput. - // Makes progress until blocked on input or output. - // Returns false if read stops due to an error or if called at EOF (GetExpectedBytesRemaining == 0) - bool Read( unsigned char *pInput, unsigned int nMaxInputBytes, - unsigned char *pOutput, unsigned int nMaxOutputBytes, - /* out */ unsigned int &nCompressedBytesRead, /* out */ unsigned int &nOutputBytesWritten ); - - // Get the expected uncompressed bytes yet to be read from this stream. Returns false if not yet known, such as - // before being fed the header. - bool GetExpectedBytesRemaining( /* out */ unsigned int &nBytesRemaining ); + unsigned int Uncompress( unsigned char *pInput, unsigned char *pOutput ); + bool IsCompressed( unsigned char *pInput ); + unsigned int GetActualSize( unsigned char *pInput ); private: - enum eHeaderParse - { - eHeaderParse_OK, - eHeaderParse_Fail, - eHeaderParse_NeedMoreBytes - }; - - eHeaderParse TryParseHeader( unsigned char *pInput, unsigned int nBytesAvailable, /* out */ unsigned int &nBytesConsumed ); - - void FreeDecoderState(); - bool CreateDecoderState( const unsigned char *pProperties ); - - // Init from a zip-embedded LZMA stream. Requires the original size be passed from zip headers. - CLzmaDec_t *m_pDecoderState; - - unsigned int m_nActualSize; - unsigned int m_nActualBytesRead; - unsigned int m_nCompressedSize; - unsigned int m_nCompressedBytesRead; - - // If we have read past the header - bool m_bParsedHeader : 1; - // If InitZIPHeader() was called. We're expecting a zip-style header and have size information. - bool m_bZIPStyleHeader : 1; }; #endif + diff --git a/public/tier1/mapbase_con_groups.h b/public/tier1/mapbase_con_groups.h new file mode 100644 index 00000000..7346092e --- /dev/null +++ b/public/tier1/mapbase_con_groups.h @@ -0,0 +1,63 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: See tier1/mapbase_con_groups.cpp for more information +// +// $NoKeywords: $ +//============================================================================= + +#ifndef CON_VERBOSE_COLORS_H +#define CON_VERBOSE_COLORS_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//static const Color CON_COLOR_DEV_VERBOSE( 192, 128, 192, 255 ); + +enum ConGroupID_t +{ + // General + CON_GROUP_MAPBASE_MISC, // "Mapbase misc." + CON_GROUP_PHYSICS, // "Physics" + CON_GROUP_IO_SYSTEM, // "Entity I/O" + CON_GROUP_RESPONSE_SYSTEM, // "Response System" + + // Game + CON_GROUP_NPC_AI, // "NPC AI" + CON_GROUP_NPC_SCRIPTS, // "NPC scripts" + CON_GROUP_SPEECH_AI, // "Speech AI" + CON_GROUP_CHOREO, // "Choreo" + + // VScript + CON_GROUP_VSCRIPT, // "VScript" + CON_GROUP_VSCRIPT_PRINT, // "VScript print" + + //-------------------------- + + // + // Mod groups can be inserted here + // + + //-------------------------- + + CON_GROUP_MAX, // Keep this at the end +}; + +// Mapbase console group message. +void CGMsg( int level, ConGroupID_t nGroup, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 ); + +#define CGWarning CGMsg + +//----------------------------------------------------------------------------- + +class IBaseFileSystem; + +void InitConsoleGroups( IBaseFileSystem *filesystem ); + +void PrintAllConsoleGroups(); +void ToggleConsoleGroups( const char *pszQuery ); +void SetConsoleGroupIncludeNames( bool bToggle ); + +#endif diff --git a/public/tier1/mapbase_matchers_base.h b/public/tier1/mapbase_matchers_base.h new file mode 100644 index 00000000..beb1d869 --- /dev/null +++ b/public/tier1/mapbase_matchers_base.h @@ -0,0 +1,61 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: General matching functions for things like wildcards and !=. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef MAPBASE_MATCHERS_BASE_H +#define MAPBASE_MATCHERS_BASE_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +#define MAPBASE_MATCHERS 1 + +// Regular expressions based off of the std library. +// pszQuery = The regex text. +// szValue = The value that should be matched. +bool Matcher_Regex( const char *pszQuery, const char *szValue ); + +// Compares two strings with support for wildcards or regex. This code is an expanded version of baseentity.cpp's NamesMatch(). +// pszQuery = The value that should have the wildcard. +// szValue = The value tested against the query. +// Use Matcher_Match if you want <, !=, etc. as well. +bool Matcher_NamesMatch( const char *pszQuery, const char *szValue ); + +// Identical to baseentity.cpp's original NamesMatch(). +// pszQuery = The value that should have the wildcard. +// szValue = The value tested against the query. +bool Matcher_NamesMatch_Classic( const char *pszQuery, const char *szValue ); + +// Identical to Matcher_NamesMatch_Classic(), but either value could use a wildcard. +// pszQuery = The value that serves as the query. This value can use wildcards. +// szValue = The value tested against the query. This value can use wildcards as well. +bool Matcher_NamesMatch_MutualWildcard( const char *pszQuery, const char *szValue ); + +// Returns true if the specified string contains a wildcard character. +bool Matcher_ContainsWildcard( const char *pszQuery ); + +// Taken from the Response System. +// Checks if the specified string appears to be a number of some sort. +static bool AppearsToBeANumber( char const *token ) +{ + if ( atof( token ) != 0.0f ) + return true; + + char const *p = token; + while ( *p ) + { + if ( *p != '0' ) + return false; + + p++; + } + + return true; +} + +#endif diff --git a/public/tier1/refcount.h b/public/tier1/refcount.h index 9c756b84..264da100 100644 --- a/public/tier1/refcount.h +++ b/public/tier1/refcount.h @@ -14,40 +14,6 @@ #pragma once #endif -template -inline void SafeAssign(T** ppInoutDst, T* pInoutSrc ) -{ - Assert( ppInoutDst ); - - // Do addref before release - if ( pInoutSrc ) - ( pInoutSrc )->AddRef(); - - // Do addref before release - if ( *ppInoutDst ) - ( *ppInoutDst )->Release(); - - // Do the assignment - ( *ppInoutDst ) = pInoutSrc; -} - -template -inline void SafeAddRef( T* pObj ) -{ - if ( pObj ) - pObj->AddRef(); -} - -template -inline void SafeRelease( T** ppInoutPtr ) -{ - Assert( ppInoutPtr ); - if ( *ppInoutPtr ) - ( *ppInoutPtr )->Release(); - - ( *ppInoutPtr ) = NULL; -} - //----------------------------------------------------------------------------- // Purpose: Implement a standard reference counted interface. Use of this // is optional insofar as all the concrete tools only require diff --git a/public/tier1/snappy-sinksource.h b/public/tier1/snappy-sinksource.h index faabfa1e..430baeab 100644 --- a/public/tier1/snappy-sinksource.h +++ b/public/tier1/snappy-sinksource.h @@ -60,7 +60,6 @@ class Sink { // The default implementation always returns the scratch buffer. virtual char* GetAppendBuffer(size_t length, char* scratch); - private: // No copying Sink(const Sink&); diff --git a/public/tier1/snappy-stubs-public.h b/public/tier1/snappy-stubs-public.h deleted file mode 100644 index 6b41bbe9..00000000 --- a/public/tier1/snappy-stubs-public.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. -// Author: sesse@google.com (Steinar H. Gunderson) -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Various type stubs for the open-source version of Snappy. -// -// This file cannot include config.h, as it is included from snappy.h, -// which is a public header. Instead, snappy-stubs-public.h is generated by -// from snappy-stubs-public.h.in at configure time. - -#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ -#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ - -#if 1 -#include -#endif - -#if 1 -#include -#endif - -#if 0 -#include -#endif - -#define SNAPPY_MAJOR 1 -#define SNAPPY_MINOR 1 -#define SNAPPY_PATCHLEVEL 2 -#define SNAPPY_VERSION \ - ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) - -#include - -namespace snappy { - -#if 1 -typedef int8_t int8; -typedef uint8_t uint8; -typedef int16_t int16; -typedef uint16_t uint16; -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#else -typedef signed char int8; -typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; -typedef int int32; -typedef unsigned int uint32; -typedef long long int64; -typedef unsigned long long uint64; -#endif - -typedef std::string string; - -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#if !0 -// Windows does not have an iovec type, yet the concept is universally useful. -// It is simple to define it ourselves, so we put it inside our own namespace. -struct iovec { - void* iov_base; - size_t iov_len; -}; -#endif - -} // namespace snappy - -#endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ diff --git a/public/tier1/snappy.h b/public/tier1/snappy.h index fbb1af7a..c5eeea01 100644 --- a/public/tier1/snappy.h +++ b/public/tier1/snappy.h @@ -49,7 +49,17 @@ #endif //_WIN32 #include -#include "snappy-stubs-public.h" +#include "tier0/platform.h" + +#define SNAPPY_MAJOR 1 +#define SNAPPY_MINOR 0 +#define SNAPPY_PATCHLEVEL 3 +#define SNAPPY_VERSION \ + ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) + +#define SNAPPY_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) namespace snappy { class Source; @@ -63,13 +73,6 @@ namespace snappy { // number of bytes written. size_t Compress(Source* source, Sink* sink); - // Find the uncompressed length of the given stream, as given by the header. - // Note that the true length could deviate from this; the stream could e.g. - // be truncated. - // - // Also note that this leaves "*source" in a state that is unsuitable for - // further operations, such as RawUncompress(). You will need to rewind - // or recreate the source yourself before attempting any further calls. bool GetUncompressedLength(Source* source, uint32* result); // ------------------------------------------------------------------------ @@ -131,28 +134,6 @@ namespace snappy { // returns false if the message is corrupted and could not be decrypted bool RawUncompress(Source* compressed, char* uncompressed); - // Given data in "compressed[0..compressed_length-1]" generated by - // calling the Snappy::Compress routine, this routine - // stores the uncompressed data to the iovec "iov". The number of physical - // buffers in "iov" is given by iov_cnt and their cumulative size - // must be at least GetUncompressedLength(compressed). The individual buffers - // in "iov" must not overlap with each other. - // - // returns false if the message is corrupted and could not be decrypted - bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, - const struct iovec* iov, size_t iov_cnt); - - // Given data from the byte source 'compressed' generated by calling - // the Snappy::Compress routine, this routine stores the uncompressed - // data to the iovec "iov". The number of physical - // buffers in "iov" is given by iov_cnt and their cumulative size - // must be at least GetUncompressedLength(compressed). The individual buffers - // in "iov" must not overlap with each other. - // - // returns false if the message is corrupted and could not be decrypted - bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, - size_t iov_cnt); - // Returns the maximal size of the compressed representation of // input data that is "source_bytes" bytes in length; size_t MaxCompressedLength(size_t source_bytes); @@ -171,20 +152,20 @@ namespace snappy { bool IsValidCompressedBuffer(const char* compressed, size_t compressed_length); - // The size of a compression block. Note that many parts of the compression - // code assumes that kBlockSize <= 65536; in particular, the hash table - // can only store 16-bit offsets, and EmitCopy() also assumes the offset - // is 65535 bytes or less. Note also that if you change this, it will - // affect the framing format (see framing_format.txt). + // *** DO NOT CHANGE THE VALUE OF kBlockSize *** // - // Note that there might be older data around that is compressed with larger - // block sizes, so the decompression code should not rely on the - // non-existence of long backreferences. - static const int kBlockLog = 16; - static const size_t kBlockSize = 1 << kBlockLog; + // New Compression code chops up the input into blocks of at most + // the following size. This ensures that back-references in the + // output never cross kBlockSize block boundaries. This can be + // helpful in implementing blocked decompression. However the + // decompression code should not rely on this guarantee since older + // compression code may not obey it. + static const int kBlockLog = 15; + static const int kBlockSize = 1 << kBlockLog; static const int kMaxHashTableBits = 14; - static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits; + static const int kMaxHashTableSize = 1 << kMaxHashTableBits; + } // end namespace snappy diff --git a/public/tier1/strtools.h b/public/tier1/strtools.h index 12e0a0c4..d127b53f 100644 --- a/public/tier1/strtools.h +++ b/public/tier1/strtools.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -97,19 +97,19 @@ inline wchar_t *_wcsupr( wchar_t *start ) #ifdef _DEBUG -#define V_memset(dest, fill, count) _V_memset (__FILE__, __LINE__, (dest), (fill), (count)) -#define V_memcpy(dest, src, count) _V_memcpy (__FILE__, __LINE__, (dest), (src), (count)) -#define V_memmove(dest, src, count) _V_memmove (__FILE__, __LINE__, (dest), (src), (count)) -#define V_memcmp(m1, m2, count) _V_memcmp (__FILE__, __LINE__, (m1), (m2), (count)) -#define V_strlen(str) _V_strlen (__FILE__, __LINE__, (str)) -#define V_strcpy(dest, src) _V_strcpy (__FILE__, __LINE__, (dest), (src)) -#define V_strrchr(s, c) _V_strrchr (__FILE__, __LINE__, (s), (c)) -#define V_strcmp(s1, s2) _V_strcmp (__FILE__, __LINE__, (s1), (s2)) -#define V_wcscmp(s1, s2) _V_wcscmp (__FILE__, __LINE__, (s1), (s2)) -#define V_strstr(s1, search ) _V_strstr (__FILE__, __LINE__, (s1), (search) ) -#define V_wcslen(pwch) _V_wcslen (__FILE__, __LINE__, (pwch)) -#define V_wcslower(start) _V_wcslower (__FILE__, __LINE__, (start)) -#define V_wcsupr(start) _V_wcsupr (__FILE__, __LINE__, (start)) +#define V_memset(dest, fill, count) _V_memset (__FILE__, __LINE__, (dest), (fill), (count)) +#define V_memcpy(dest, src, count) _V_memcpy (__FILE__, __LINE__, (dest), (src), (count)) +#define V_memmove(dest, src, count) _V_memmove (__FILE__, __LINE__, (dest), (src), (count)) +#define V_memcmp(m1, m2, count) _V_memcmp (__FILE__, __LINE__, (m1), (m2), (count)) +#define V_strlen(str) _V_strlen (__FILE__, __LINE__, (str)) +#define V_strcpy(dest, src) _V_strcpy (__FILE__, __LINE__, (dest), (src)) +#define V_strrchr(s, c) _V_strrchr (__FILE__, __LINE__, (s), (c)) +#define V_strcmp(s1, s2) _V_strcmp (__FILE__, __LINE__, (s1), (s2)) +#define V_wcscmp(s1, s2) _V_wcscmp (__FILE__, __LINE__, (s1), (s2)) +#define V_strstr(s1, search ) _V_strstr (__FILE__, __LINE__, (s1), (search) ) +#define V_wcslen(pwch) _V_wcslen (__FILE__, __LINE__, (pwch)) +#define V_wcslower(start) _V_wcslower (__FILE__, __LINE__, (start)) +#define V_wcsupr(start) _V_wcsupr (__FILE__, __LINE__, (start)) #else @@ -117,7 +117,7 @@ inline wchar_t *_wcsupr( wchar_t *start ) inline void V_memset (void *dest, int fill, int count) { memset( dest, fill, count ); } inline void V_memcpy (void *dest, const void *src, int count) { memcpy( dest, src, count ); } inline void V_memmove (void *dest, const void *src, int count) { memmove( dest, src, count ); } -inline int V_memcmp (const void *m1, const void *m2, int count){ return memcmp( m1, m2, count ); } +inline int V_memcmp (const void *m1, const void *m2, int count){ return memcmp( m1, m2, count ); } inline int V_strlen (const char *str) { return (int) strlen ( str ); } inline void V_strcpy (char *dest, const char *src) { strcpy( dest, src ); } inline int V_wcslen(const wchar_t *pwch) { return (int)wcslen(pwch); } @@ -151,27 +151,7 @@ inline bool StringHasPrefix ( const char *str, const char *prefix ) inline bool StringHasPrefixCaseSensitive( const char *str, const char *prefix ) { return StringAfterPrefixCaseSensitive( str, prefix ) != NULL; } -template< bool CASE_SENSITIVE > inline bool _V_strEndsWithInner( const char *pStr, const char *pSuffix ) -{ - int nSuffixLen = V_strlen( pSuffix ); - int nStringLen = V_strlen( pStr ); - if ( nSuffixLen == 0 ) - return true; // All strings end with the empty string (matches Java & .NET behaviour) - if ( nStringLen < nSuffixLen ) - return false; - pStr += nStringLen - nSuffixLen; - if ( CASE_SENSITIVE ) - return !V_strcmp( pStr, pSuffix ); - else - return !V_stricmp( pStr, pSuffix ); -} - -// Does 'pStr' end with 'pSuffix'? (case sensitive/insensitive variants) -inline bool V_strEndsWith( const char *pStr, const char *pSuffix ) { return _V_strEndsWithInner( pStr, pSuffix ); } -inline bool V_striEndsWith( const char *pStr, const char *pSuffix ) { return _V_strEndsWithInner( pStr, pSuffix ); } - - -// Normalizes a float string in place. +// Normalizes a float string in place. // (removes leading zeros, trailing zeros after the decimal point, and the decimal point itself where possible) void V_normalizeFloatString( char* pFloat ); @@ -235,9 +215,9 @@ inline bool V_isspace(char c) { return isspace( (unsigned char)c ) != 0; } void V_strncpy( OUT_Z_CAP(maxLenInChars) char *pDest, const char *pSrc, int maxLenInChars ); // Ultimate safe strcpy function, for arrays only -- buffer size is inferred by the compiler -template void V_strcpy_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pSrc ) -{ - V_strncpy( pDest, pSrc, (int)maxLenInChars ); +template void V_strcpy_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pSrc ) +{ + V_strncpy( pDest, pSrc, (int)maxLenInChars ); } // A function which duplicates a string using new[] to allocate the new string. @@ -250,196 +230,38 @@ inline char *V_strdup( const char *pSrc ) } void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes ); -template void V_wcscpy_safe( OUT_Z_ARRAY wchar_t (&pDest)[maxLenInChars], wchar_t const *pSrc ) -{ - V_wcsncpy( pDest, pSrc, maxLenInChars * sizeof(*pDest) ); +template void V_wcscpy_safe( OUT_Z_ARRAY wchar_t (&pDest)[maxLenInChars], wchar_t const *pSrc ) +{ + V_wcsncpy( pDest, pSrc, maxLenInChars * sizeof(*pDest) ); } #define COPY_ALL_CHARACTERS -1 char *V_strncat( INOUT_Z_CAP(cchDest) char *pDest, const char *pSrc, size_t cchDest, int max_chars_to_copy=COPY_ALL_CHARACTERS ); template char *V_strcat_safe( INOUT_Z_ARRAY char (&pDest)[cchDest], const char *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS ) -{ - return V_strncat( pDest, pSrc, (int)cchDest, nMaxCharsToCopy ); +{ + return V_strncat( pDest, pSrc, (int)cchDest, nMaxCharsToCopy ); } wchar_t *V_wcsncat( INOUT_Z_CAP(cchDest) wchar_t *pDest, const wchar_t *pSrc, size_t cchDest, int nMaxCharsToCopy=COPY_ALL_CHARACTERS ); template wchar_t *V_wcscat_safe( INOUT_Z_ARRAY wchar_t (&pDest)[cchDest], const wchar_t *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS ) -{ - return V_wcsncat( pDest, pSrc, (int)cchDest, nMaxCharsToCopy ); +{ + return V_wcsncat( pDest, pSrc, (int)cchDest, nMaxCharsToCopy ); } char *V_strnlwr( INOUT_Z_CAP(cchBuf) char *pBuf, size_t cchBuf); template char *V_strlwr_safe( INOUT_Z_ARRAY char (&pBuf)[cchDest] ) -{ - return _V_strnlwr( pBuf, (int)cchDest ); -} - -// Unicode string conversion policies - what to do if an illegal sequence is encountered -enum EStringConvertErrorPolicy { - _STRINGCONVERTFLAG_SKIP = 1, - _STRINGCONVERTFLAG_FAIL = 2, - _STRINGCONVERTFLAG_ASSERT = 4, - - STRINGCONVERT_REPLACE = 0, - STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP, - STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL, - - STRINGCONVERT_ASSERT_REPLACE = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE, - STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP, - STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL, -}; - -// Unicode (UTF-8, UTF-16, UTF-32) fundamental conversion functions. -bool Q_IsValidUChar32( uchar32 uValue ); -int Q_UChar32ToUTF8Len( uchar32 uValue ); -int Q_UChar32ToUTF8( uchar32 uValue, char *pOut ); -int Q_UChar32ToUTF16Len( uchar32 uValue ); -int Q_UChar32ToUTF16( uchar32 uValue, uchar16 *pOut ); - -// Validate that a Unicode string is well-formed and contains only valid code points -bool Q_UnicodeValidate( const char *pUTF8 ); -bool Q_UnicodeValidate( const uchar16 *pUTF16 ); -bool Q_UnicodeValidate( const uchar32 *pUTF32 ); - -// Returns length of string in Unicode code points (printed glyphs or non-printing characters) -int Q_UnicodeLength( const char *pUTF8 ); -int Q_UnicodeLength( const uchar16 *pUTF16 ); -int Q_UnicodeLength( const uchar32 *pUTF32 ); - -// Returns length of string in elements, not characters! These are analogous to Q_strlen and Q_wcslen -inline int Q_strlen16( const uchar16 *puc16 ) { int nElems = 0; while ( puc16[nElems] ) ++nElems; return nElems; } -inline int Q_strlen32( const uchar32 *puc32 ) { int nElems = 0; while ( puc32[nElems] ) ++nElems; return nElems; } - - -// Repair invalid Unicode strings by dropping truncated characters and fixing improperly-double-encoded UTF-16 sequences. -// Unlike conversion functions which replace with '?' by default, a repair operation assumes that you know that something -// is wrong with the string (eg, mid-sequence truncation) and you just want to do the best possible job of cleaning it up. -// You can pass a REPLACE or FAIL policy if you would prefer to replace characters with '?' or clear the entire string. -// Returns nonzero on success, or 0 if the policy is FAIL and an invalid sequence was found. -int Q_UnicodeRepair( char *pUTF8, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP ); -int Q_UnicodeRepair( uchar16 *pUTF16, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP ); -int Q_UnicodeRepair( uchar32 *pUTF32, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP ); - -// Advance pointer forward by N Unicode code points (printed glyphs or non-printing characters), stopping at terminating null if encountered. -char *Q_UnicodeAdvance( char *pUTF8, int nCharacters ); -uchar16 *Q_UnicodeAdvance( uchar16 *pUTF16, int nCharactersnCharacters ); -uchar32 *Q_UnicodeAdvance( uchar32 *pUTF32, int nChars ); -inline const char *Q_UnicodeAdvance( const char *pUTF8, int nCharacters ) { return Q_UnicodeAdvance( (char*) pUTF8, nCharacters ); } -inline const uchar16 *Q_UnicodeAdvance( const uchar16 *pUTF16, int nCharacters ) { return Q_UnicodeAdvance( (uchar16*) pUTF16, nCharacters ); } -inline const uchar32 *Q_UnicodeAdvance( const uchar32 *pUTF32, int nCharacters ) { return Q_UnicodeAdvance( (uchar32*) pUTF32, nCharacters ); } - -// Truncate to maximum of N Unicode code points (printed glyphs or non-printing characters) -inline void Q_UnicodeTruncate( char *pUTF8, int nCharacters ) { *Q_UnicodeAdvance( pUTF8, nCharacters ) = 0; } -inline void Q_UnicodeTruncate( uchar16 *pUTF16, int nCharacters ) { *Q_UnicodeAdvance( pUTF16, nCharacters ) = 0; } -inline void Q_UnicodeTruncate( uchar32 *pUTF32, int nCharacters ) { *Q_UnicodeAdvance( pUTF32, nCharacters ) = 0; } - - -// Conversion between Unicode string types (UTF-8, UTF-16, UTF-32). Deals with bytes, not element counts, -// to minimize harm from the programmer mistakes which continue to plague our wide-character string code. -// Returns the number of bytes written to the output, or if output is NULL, the number of bytes required. -int Q_UTF8ToUTF16( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF8ToUTF32( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF16ToUTF8( const uchar16 *pUTF16, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF16ToUTF32( const uchar16 *pUTF16, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF32ToUTF8( const uchar32 *pUTF32, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF32ToUTF16( const uchar32 *pUTF32, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); - -// This is disgusting and exist only easily to facilitate having 16-bit and 32-bit wchar_t's on different platforms -int Q_UTF32ToUTF32( const uchar32 *pUTF32Source, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32Dest, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); - -// Conversion between count-limited UTF-n character arrays, including any potential NULL characters. -// Output has a terminating NULL for safety; strip the last character if you want an unterminated string. -// Returns the number of bytes written to the output, or if output is NULL, the number of bytes required. -int Q_UTF8CharsToUTF16( const char *pUTF8, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF8CharsToUTF32( const char *pUTF8, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF16CharsToUTF8( const uchar16 *pUTF16, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF16CharsToUTF32( const uchar16 *pUTF16, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF32CharsToUTF8( const uchar32 *pUTF32, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); -int Q_UTF32CharsToUTF16( const uchar32 *pUTF32, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE ); - -// Decode a single UTF-8 character to a uchar32, returns number of UTF-8 bytes parsed -int Q_UTF8ToUChar32( const char *pUTF8_, uchar32 &uValueOut, bool &bErrorOut ); - -// Decode a single UTF-16 character to a uchar32, returns number of UTF-16 characters (NOT BYTES) consumed -int Q_UTF16ToUChar32( const uchar16 *pUTF16, uchar32 &uValueOut, bool &bErrorOut ); - - -// NOTE: WString means either UTF32 or UTF16 depending on the platform and compiler settings. -#if defined( _MSC_VER ) || defined( _WIN32 ) -#define Q_UTF8ToWString Q_UTF8ToUTF16 -#define Q_UTF8CharsToWString Q_UTF8CharsToUTF16 -#define Q_UTF32ToWString Q_UTF32ToUTF16 -#define Q_WStringToUTF8 Q_UTF16ToUTF8 -#define Q_WStringCharsToUTF8 Q_UTF16CharsToUTF8 -#define Q_WStringToUTF32 Q_UTF16ToUTF32 -#else -#define Q_UTF8ToWString Q_UTF8ToUTF32 -#define Q_UTF8CharsToWString Q_UTF8CharsToUTF32 -#define Q_UTF32ToWString Q_UTF32ToUTF32 -#define Q_WStringToUTF8 Q_UTF32ToUTF8 -#define Q_WStringCharsToUTF8 Q_UTF32CharsToUTF8 -#define Q_WStringToUTF32 Q_UTF32ToUTF32 -#endif - -// These are legacy names which don't make a lot of sense but are used everywhere. Prefer the WString convention wherever possible -#define V_UTF8ToUnicode Q_UTF8ToWString -#define V_UnicodeToUTF8 Q_WStringToUTF8 - - -#ifdef WIN32 -// This function is ill-defined as it relies on the current ANSI code page. Currently Win32 only for tools. -int Q_LocaleSpecificANSIToUTF8( const char *pANSI, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes ); -#endif - -// Windows-1252 is mostly the same as ISO Latin-1, and probably what you want if you are -// saddled with an 8-bit ANSI string that originated on a Windows system. -int Q_Windows1252CharsToUTF8( const char *pchSrc, int cchSrc, OUT_Z_BYTECAP(cchDestUTF8) char *pchDestUTF8, int cchDestUTF8 ); - -// CP 437 is used for VGA console text and some old-school file formats such as ZIP. It -// is also known as the "IBM PC OEM code page" and various related names. You probably -// don't want to use this function unless you know for a fact that you're dealing with -// old-school OEM code pages. Otherwise try the Windows-1252 function above. -int Q_CP437CharsToUTF8( const char *pchSrc, int cchSrc, OUT_Z_BYTECAP(cchDestUTF8) char *pchDestUTF8, int cchDestUTF8 ); - -// replaces characters in a UTF8 string with their identical-looking equivalent (non-roundtrippable) -// -// older version of API uses a small homoglyph table; newer version uses a larger one -// -// strings using old version are baked into the database, so we won't toss it quite yet, -// but don't use it for new features. -int Q_NormalizeUTF8Old( const char *pchSrc, OUT_Z_CAP(cchDest) char *pchDest, int cchDest ); -int Q_NormalizeUTF8( const char *pchSrc, OUT_Z_CAP(cchDest) char *pchDest, int cchDest ); - -//----------------------------------------------------------------------------- -// Purpose: replaces characters in a UTF8 string with similar-looking equivalents. -// Only replaces with ASCII characters.. non-recognized characters will be replaced with ? -// This operation is destructive (i.e. you can't roundtrip through the normalized -// form). -//----------------------------------------------------------------------------- -template int Q_NormalizeUTF8ToASCII( OUT_Z_ARRAY char (&pchDest)[maxLenInChars], const char *pchSrc ) -{ - int nResult = Q_NormalizeUTF8( pchSrc, pchDest, maxLenInChars ); - - // replace non ASCII characters with ? - for ( int i = 0; i < nResult; i++ ) - { - if ( pchDest[i] > 127 || pchDest[i] < 0 ) - { - pchDest[i] = '?'; - } - } - - return nResult; + return _V_strnlwr( pBuf, (int)cchDest ); } + // UNDONE: Find a non-compiler-specific way to do this #ifdef _WIN32 #ifndef _VA_LIST_DEFINED #ifdef _M_ALPHA -struct va_list +struct va_list { char *a0; /* pointer to first homed integer argument */ int offset; /* byte offset of next parameter */ @@ -508,43 +330,26 @@ char *V_pretifymem( float value, int digitsafterdecimal = 2, bool usebinaryonek // Prints out a pretified integer with comma separators (eg, 7,233,270,000) char *V_pretifynum( int64 value ); -int _V_UCS2ToUnicode( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pUnicode, int cubDestSizeInBytes ); -template< typename T > inline int V_UCS2ToUnicode( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pUnicode, T cubDestSizeInBytes ) -{ - return _V_UCS2ToUnicode( pUCS2, pUnicode, static_cast(cubDestSizeInBytes) ); -} - -int _V_UCS2ToUTF8( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes ); -template< typename T > inline int V_UCS2ToUTF8( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, T cubDestSizeInBytes ) -{ - return _V_UCS2ToUTF8( pUCS2, pUTF8, static_cast(cubDestSizeInBytes) ); -} - -int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUCS2, int cubDestSizeInBytes ); -template< typename T, typename U > inline int V_UnicodeToUCS2( const wchar_t *pUnicode, T cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUCS2, U cubDestSizeInBytes ) -{ - return _V_UnicodeToUCS2( pUnicode, static_cast(cubSrcInBytes), pUCS2, static_cast(cubDestSizeInBytes) ); -} - -int _V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2 *pUCS2, int cubDestSizeInBytes ); -template< typename T, typename U > inline int V_UTF8ToUCS2( const char *pUTF8, T cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2 *pUCS2, U cubDestSizeInBytes ) -{ - return _V_UTF8ToUCS2( pUTF8, static_cast(cubSrcInBytes), pUCS2, static_cast(cubDestSizeInBytes) ); -} +// conversion functions wchar_t <-> char, returning the number of characters converted +int V_UTF8ToUnicode( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pwchDest, int cubDestSizeInBytes ); +int V_UnicodeToUTF8( const wchar_t *pUnicode, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes ); +int V_UCS2ToUnicode( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pUnicode, int cubDestSizeInBytes ); +int V_UCS2ToUTF8( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes ); +int V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUCS2, int cubDestSizeInBytes ); +int V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2 *pUCS2, int cubDestSizeInBytes ); // strips leading and trailing whitespace; returns true if any characters were removed. UTF-8 and UTF-16 versions. bool Q_StripPrecedingAndTrailingWhitespace( char *pch ); bool Q_StripPrecedingAndTrailingWhitespaceW( wchar_t *pwch ); -// strips leading and trailing whitespace, also taking "aggressive" characters +// strips leading and trailing whitespace, also taking "aggressive" characters // like punctuation spaces, non-breaking spaces, composing characters, and so on bool Q_AggressiveStripPrecedingAndTrailingWhitespace( char *pch ); bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW( wchar_t *pwch ); -bool Q_RemoveAllEvilCharacters( char *pch ); // Functions for converting hexidecimal character strings back into binary data etc. // -// e.g., +// e.g., // int output; // V_hextobinary( "ffffffff", 8, &output, sizeof( output ) ); // would make output == 0xfffffff or -1 @@ -589,7 +394,7 @@ const char *V_GetFileName( const char * path ); // This removes "./" and "../" from the pathname. pFilename should be a full pathname. // Also incorporates the behavior of V_FixSlashes and optionally V_FixDoubleSlashes. -// Returns false if it tries to ".." past the root directory in the drive (in which case +// Returns false if it tries to ".." past the root directory in the drive (in which case // it is an invalid path). bool V_RemoveDotSlashes( char *pFilename, char separator = CORRECT_PATH_SEPARATOR, bool bRemoveDoubleSlashes = true ); @@ -674,6 +479,16 @@ inline void V_wcscat( INOUT_Z_CAP(cchDest) wchar_t *dest, const wchar_t *src, in V_wcsncat( dest, src, cchDest, COPY_ALL_CHARACTERS ); } +// Reentrant strtok +inline static char* V_strtok_s( char *str, const char *delimiters, char **context ) +{ +#ifdef _MSC_VER + return strtok_s( str, delimiters, context ); +#elif POSIX + return strtok_r( str, delimiters, context ); +#endif +} + //----------------------------------------------------------------------------- // generic unique name helper functions //----------------------------------------------------------------------------- @@ -776,7 +591,6 @@ class CStrAutoEncode m_pwch = NULL; #if !defined( WIN32 ) && !defined(_WIN32) m_pucs2 = NULL; - m_bCreatedUCS2 = false; #endif m_bCreatedUTF16 = false; } @@ -788,7 +602,6 @@ class CStrAutoEncode m_pwch = pwch; #if !defined( WIN32 ) && !defined(_WIN32) m_pucs2 = NULL; - m_bCreatedUCS2 = false; #endif m_bCreatedUTF16 = true; } @@ -799,8 +612,7 @@ class CStrAutoEncode m_pch = NULL; m_pwch = NULL; m_pucs2 = pwch; - m_bCreatedUCS2 = true; - m_bCreatedUTF16 = false; + m_bCreatedUTF16 = true; } #endif @@ -858,10 +670,6 @@ class CStrAutoEncode { delete [] m_pwch; } -#if !defined( WIN32 ) && !defined(_WIN32) - if ( !m_bCreatedUCS2 && m_pucs2 ) - delete [] m_pucs2; -#endif } private: @@ -940,8 +748,6 @@ class CStrAutoEncode // so we perform a second allocation that's just the size we need. void PopulateUCS2() { - if ( m_bCreatedUCS2 ) - return; if ( m_pch == NULL ) return; // no UTF-8 string to convert if ( m_pucs2 != NULL ) @@ -972,7 +778,6 @@ class CStrAutoEncode const wchar_t *m_pwch; #if !defined( WIN32 ) && !defined(_WIN32) const ucs2 *m_pucs2; - bool m_bCreatedUCS2; #endif // "created as UTF-16", means our owned string is the UTF-8 string not the UTF-16 one. bool m_bCreatedUTF16; @@ -987,20 +792,20 @@ void Q_URLEncodeRaw( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char // Dest buffer should be at least as large as source buffer to gurantee room for decode. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. // -// Returns the amount of space actually used in the output buffer. +// Returns the amount of space actually used in the output buffer. size_t Q_URLDecodeRaw( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); -// Encodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. +// Encodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. // This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data. // Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode. void Q_URLEncode( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ); -// Decodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. +// Decodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces. // This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data. // Dest buffer should be at least as large as source buffer to gurantee room for decode. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. // -// Returns the amount of space actually used in the output buffer. +// Returns the amount of space actually used in the output buffer. size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); @@ -1022,7 +827,7 @@ size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDest #define Q_strupr V_strupr #define Q_strlower V_strlower #define Q_wcslen V_wcslen -#define Q_strncmp V_strncmp +#define Q_strncmp V_strncmp #define Q_strcasecmp V_strcasecmp #define Q_strncasecmp V_strncasecmp #define Q_strnicmp V_strnicmp @@ -1081,11 +886,4 @@ size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDest #endif // !defined( VSTDLIB_DLL_EXPORT ) -#ifdef POSIX -#define FMT_WS L"%ls" -#else -#define FMT_WS L"%s" -#endif - - #endif // TIER1_STRTOOLS_H diff --git a/public/tier1/utlarray.h b/public/tier1/utlarray.h index ce5ffe8b..36850860 100644 --- a/public/tier1/utlarray.h +++ b/public/tier1/utlarray.h @@ -43,8 +43,6 @@ class CUtlArray : public base_array_t { public: typedef T ElemType_t; - typedef T* iterator; - typedef const T* const_iterator; CUtlArray(); CUtlArray( T* pMemory, size_t count ); @@ -61,13 +59,6 @@ class CUtlArray : public base_array_t T& Random(); const T& Random() const; - // STL compatible member functions. These allow easier use of std::sort - // and they are forward compatible with the C++ 11 range-based for loops. - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - T* Base(); const T* Base() const; @@ -139,30 +130,6 @@ inline CUtlArray::CUtlArray( CUtlArray const& vec ) } } -template< typename T, size_t MAX_SIZE > -typename CUtlArray::iterator CUtlArray::begin() -{ - return Base(); -} - -template< typename T, size_t MAX_SIZE > -typename CUtlArray::const_iterator CUtlArray::begin() const -{ - return Base(); -} - -template< typename T, size_t MAX_SIZE > -typename CUtlArray::iterator CUtlArray::end() -{ - return Base() + Count(); -} - -template< typename T, size_t MAX_SIZE > -typename CUtlArray::const_iterator CUtlArray::end() const -{ - return Base() + Count(); -} - template< typename T, size_t MAX_SIZE > inline T *CUtlArray::Base() { diff --git a/public/tier1/utlbinaryblock.h b/public/tier1/utlbinaryblock.h deleted file mode 100644 index 93c6e680..00000000 --- a/public/tier1/utlbinaryblock.h +++ /dev/null @@ -1,107 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#ifndef UTLBINARYBLOCK_H -#define UTLBINARYBLOCK_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlmemory.h" -#include "tier1/strtools.h" -#include "limits.h" - -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -class CUtlBinaryBlock -{ -public: - CUtlBinaryBlock( int growSize = 0, int initSize = 0 ); - - // NOTE: nInitialLength indicates how much of the buffer starts full - CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ); - CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ); - CUtlBinaryBlock( const CUtlBinaryBlock& src ); - - void Get( void *pValue, int nMaxLen ) const; - void Set( const void *pValue, int nLen ); - const void *Get( ) const; - void *Get( ); - - unsigned char& operator[]( int i ); - const unsigned char& operator[]( int i ) const; - - int Length() const; - void SetLength( int nLength ); // Undefined memory will result - bool IsEmpty() const; - void Clear(); - void Purge(); - - bool IsReadOnly() const; - - CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src ); - - // Test for equality - bool operator==( const CUtlBinaryBlock &src ) const; - -private: - CUtlMemory m_Memory; - int m_nActualLength; -}; - - -//----------------------------------------------------------------------------- -// class inlines -//----------------------------------------------------------------------------- -inline const void *CUtlBinaryBlock::Get( ) const -{ - return m_Memory.Base(); -} - -inline void *CUtlBinaryBlock::Get( ) -{ - return m_Memory.Base(); -} - -inline int CUtlBinaryBlock::Length() const -{ - return m_nActualLength; -} - -inline unsigned char& CUtlBinaryBlock::operator[]( int i ) -{ - return m_Memory[i]; -} - -inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const -{ - return m_Memory[i]; -} - -inline bool CUtlBinaryBlock::IsReadOnly() const -{ - return m_Memory.IsReadOnly(); -} - -inline bool CUtlBinaryBlock::IsEmpty() const -{ - return Length() == 0; -} - -inline void CUtlBinaryBlock::Clear() -{ - SetLength( 0 ); -} - -inline void CUtlBinaryBlock::Purge() -{ - SetLength( 0 ); - m_Memory.Purge(); -} - -#endif // UTLBINARYBLOCK_H - diff --git a/public/tier1/utlbuffer.h b/public/tier1/utlbuffer.h index 0de85fda..033407b4 100644 --- a/public/tier1/utlbuffer.h +++ b/public/tier1/utlbuffer.h @@ -142,6 +142,9 @@ class CUtlBuffer // Makes sure we've got at least this much memory void EnsureCapacity( int num ); + + // Access for direct read into buffer + void * AccessForDirectRead( int nBytes ); // Attaches the buffer to external memory.... void SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags = 0 ); @@ -189,16 +192,7 @@ class CUtlBuffer unsigned int GetUnsignedInt( ); float GetFloat( ); double GetDouble( ); - template void GetString( char( &pString )[maxLenInChars] ) - { - GetStringInternal( pString, maxLenInChars ); - } - - void GetStringManualCharCount( char *pString, size_t maxLenInChars ) - { - GetStringInternal( pString, maxLenInChars ); - } - + void GetString( char* pString, int nMaxChars = 0 ); void Get( void* pMem, int size ); void GetLine( char* pLine, int nMaxChars = 0 ); @@ -393,7 +387,6 @@ class CUtlBuffer // Call this to peek arbitrarily long into memory. It doesn't fail unless // it can't read *anything* new bool CheckArbitraryPeekGet( int nOffset, int &nIncrement ); - void GetStringInternal( char *pString, size_t maxLenInChars ); template void GetType( T& dest, const char *pszFmt ); template void GetTypeBin( T& dest ); @@ -596,7 +589,11 @@ inline void CUtlBuffer::GetObject( T *dest ) { if ( CheckGet( sizeof(T) ) ) { +#ifdef MAPBASE + if ( ( sizeof( T ) == 1 ) || !m_Byteswap.IsSwappingBytes() ) +#else if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) +#endif { *dest = *(T *)PeekGet(); } @@ -628,7 +625,11 @@ inline void CUtlBuffer::GetTypeBin( T &dest ) { if ( CheckGet( sizeof(T) ) ) { +#ifdef MAPBASE + if ( ( sizeof( T ) == 1 ) || !m_Byteswap.IsSwappingBytes() ) +#else if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) +#endif { dest = *(T *)PeekGet(); } @@ -814,7 +815,11 @@ inline void CUtlBuffer::PutObject( T *src ) { if ( CheckPut( sizeof(T) ) ) { +#ifdef MAPBASE + if ( ( sizeof( T ) == 1 ) || !m_Byteswap.IsSwappingBytes() ) +#else if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) +#endif { *(T *)PeekPut() = *src; } @@ -843,7 +848,11 @@ inline void CUtlBuffer::PutTypeBin( T src ) { if ( CheckPut( sizeof(T) ) ) { - if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) +#ifdef MAPBASE + if ((sizeof(T) == 1) || !m_Byteswap.IsSwappingBytes()) +#else + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) +#endif { *(T *)PeekPut() = src; } @@ -1090,5 +1099,13 @@ inline void CUtlBuffer::CopyBuffer( const void *pubData, int cubData ) } } +inline void *CUtlBuffer::AccessForDirectRead( int nBytes ) +{ + Assert( m_Get == 0 && m_Put == 0 && m_nMaxPut == 0 ); + EnsureCapacity( nBytes ); + m_nMaxPut = nBytes; + return Base(); +} + #endif // UTLBUFFER_H diff --git a/public/tier1/utlfixedmemory.h b/public/tier1/utlfixedmemory.h index 6ff8c19b..5d751554 100644 --- a/public/tier1/utlfixedmemory.h +++ b/public/tier1/utlfixedmemory.h @@ -124,7 +124,7 @@ class CUtlFixedMemory int NumAllocated() const; int Count() const { return NumAllocated(); } - // Grows memory by max(num,growsize), and returns the allocation index/ptr + // Grows memory by MAX(num,growsize), and returns the allocation index/ptr void Grow( int num = 1 ); // Makes sure we've got at least this much memory diff --git a/public/tier1/utlhashtable.h b/public/tier1/utlhashtable.h index 2517111f..7e5a94d9 100644 --- a/public/tier1/utlhashtable.h +++ b/public/tier1/utlhashtable.h @@ -686,7 +686,7 @@ void CUtlHashtable::DbgCheckIntegr // and also the validity of the user's Hash and Equal function objects. // NOTE: will fail if function objects require any sort of state! CUtlHashtable clone; - unsigned int bytes = sizeof(entry_t)*max(16,m_table.Count()); + unsigned int bytes = sizeof(entry_t)*MAX(16,m_table.Count()); byte* tempbuf = (byte*) malloc(bytes); clone.SetExternalBuffer( tempbuf, bytes, false, false ); clone = *this; diff --git a/public/tier1/utllinkedlist.h b/public/tier1/utllinkedlist.h index 46ac4a6f..822f0b36 100644 --- a/public/tier1/utllinkedlist.h +++ b/public/tier1/utllinkedlist.h @@ -679,8 +679,7 @@ I CUtlLinkedList::AllocInternal( bool multilist ) Assert( m_Memory.IsValidIterator( it ) ); if ( !m_Memory.IsValidIterator( it ) ) { - // We rarely if ever handle alloc failure. Continuing leads to corruption. - Error( "CUtlLinkedList overflow! (exhausted memory allocator)\n" ); + ExecuteNTimes( 10, Warning( "CUtlLinkedList overflow! (exhausted memory allocator)\n" ) ); return InvalidIndex(); } } @@ -688,8 +687,7 @@ I CUtlLinkedList::AllocInternal( bool multilist ) // We can overflow before the utlmemory overflows, since S != I if ( !IndexInRange( m_Memory.GetIndex( it ) ) ) { - // We rarely if ever handle alloc failure. Continuing leads to corruption. - Error( "CUtlLinkedList overflow! (exhausted index range)\n" ); + ExecuteNTimes( 10, Warning( "CUtlLinkedList overflow! (exhausted index range)\n" ) ); return InvalidIndex(); } diff --git a/public/tier1/utlmemory.h b/public/tier1/utlmemory.h index 9c5a1d14..061ec11c 100644 --- a/public/tier1/utlmemory.h +++ b/public/tier1/utlmemory.h @@ -136,7 +136,7 @@ class CUtlMemory const int MAX_GROW = 128; if ( m_nGrowSize * sizeof(T) > MAX_GROW ) { - m_nGrowSize = max( 1, MAX_GROW / sizeof(T) ); + m_nGrowSize = MAX( 1, MAX_GROW / sizeof(T) ); } } #endif @@ -552,7 +552,7 @@ inline T& CUtlMemory::operator[]( I i ) // Avoid function calls in the asserts to improve debug build performance Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() ); Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[(uint32)i]; + return m_pMemory[i]; } template< class T, class I > @@ -560,7 +560,7 @@ inline const T& CUtlMemory::operator[]( I i ) const { // Avoid function calls in the asserts to improve debug build performance Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[(uint32)i]; + return m_pMemory[i]; } template< class T, class I > @@ -569,7 +569,7 @@ inline T& CUtlMemory::Element( I i ) // Avoid function calls in the asserts to improve debug build performance Assert( m_nGrowSize != EXTERNAL_CONST_BUFFER_MARKER ); //Assert( !IsReadOnly() ); Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[(uint32)i]; + return m_pMemory[i]; } template< class T, class I > @@ -577,7 +577,7 @@ inline const T& CUtlMemory::Element( I i ) const { // Avoid function calls in the asserts to improve debug build performance Assert( (uint32)i < (uint32)m_nAllocationCount ); - return m_pMemory[(uint32)i]; + return m_pMemory[i]; } diff --git a/public/tier1/utlmultilist.h b/public/tier1/utlmultilist.h index 72a970ff..c677746c 100644 --- a/public/tier1/utlmultilist.h +++ b/public/tier1/utlmultilist.h @@ -399,8 +399,7 @@ I CUtlMultiList::Alloc( ) // We can overflow before the utlmemory overflows, since we have have I != int if ( !IndexInRange( m_MaxElementIndex ) ) { - // We rarely if ever handle alloc failure. Continuing leads to corruption. - Error( "CUtlMultiList overflow! (exhausted index range)\n" ); + ExecuteNTimes( 10, Warning( "CUtlMultiList overflow! (exhausted index range)\n" ) ); return InvalidIndex(); } @@ -414,8 +413,7 @@ I CUtlMultiList::Alloc( ) if ( m_MaxElementIndex >= m_Memory.NumAllocated() ) { - // We rarely if ever handle alloc failure. Continuing leads to corruption. - Error( "CUtlMultiList overflow! (exhausted memory allocator)\n" ); + ExecuteNTimes( 10, Warning( "CUtlMultiList overflow! (exhausted memory allocator)\n" ) ); return InvalidIndex(); } } diff --git a/public/tier1/utlobjectreference.h b/public/tier1/utlobjectreference.h index da9d3033..d1bc7e00 100644 --- a/public/tier1/utlobjectreference.h +++ b/public/tier1/utlobjectreference.h @@ -103,6 +103,16 @@ template class CUtlReference return ( o.m_pObject == m_pObject ); } + FORCEINLINE bool operator==( const T* pObj ) const + { + return ( pObj == m_pObject ); + } + + FORCEINLINE bool operator==( std::nullptr_t ) const + { + return ( nullptr == m_pObject ); + } + public: CUtlReference *m_pNext; CUtlReference *m_pPrev; diff --git a/public/tier1/utlqueue.h b/public/tier1/utlqueue.h index 05c89ee3..8624a3db 100644 --- a/public/tier1/utlqueue.h +++ b/public/tier1/utlqueue.h @@ -11,541 +11,104 @@ #pragma once #endif -#include "utlmemory.h" +#include "utlvector.h" -//#define TEST_UTLQUEUE - -enum QueueIter_t { QUEUE_ITERATOR_INVALID = 0xffffffff }; - -// T is the type stored in the queue -template< class T, class M = CUtlMemory< T > > +// T is the type stored in the stack +template< class T > class CUtlQueue { public: + // constructor: lessfunc is required, but may be set after the constructor with + // SetLessFunc CUtlQueue( int growSize = 0, int initSize = 0 ); CUtlQueue( T *pMemory, int numElements ); // return the item from the front of the queue and delete it - T RemoveAtHead(); - bool RemoveAtHead( T &removedElement ); - + T const& RemoveAtHead(); // return the item from the end of the queue and delete it - T RemoveAtTail(); - bool RemoveAtTail( T &removedElement ); + T const& RemoveAtTail(); // return item at the front of the queue - T const& Head() const; + T const& Head(); // return item at the end of the queue - T const& Tail() const; + T const& Tail(); // Add a new item to the end of the queue void Insert( T const &element ); // checks if an element of this value already exists on the stack, returns true if it does - bool Check( T const element ) const; - - // iterators may be invalidated by Insert() - QueueIter_t First() const; - QueueIter_t Next( QueueIter_t it ) const; - QueueIter_t Last() const; - QueueIter_t Previous( QueueIter_t it ) const; - bool IsValid( QueueIter_t it ) const; - T const& Element( QueueIter_t it ) const; - - // Returns the count of elements in the queue - int Count() const; - - // Return whether the queue is empty or not, faster than Count(). - bool IsEmpty() const; + bool Check( T const element ); + // Returns the count of elements in the stack + int Count() const { return m_heap.Count(); } + // doesn't deallocate memory - void RemoveAll(); + void RemoveAll() { m_heap.RemoveAll(); } // Memory deallocation - void Purge(); + void Purge() { m_heap.Purge(); } protected: - QueueIter_t Next_Unchecked( QueueIter_t it ) const; - QueueIter_t Previous_Unchecked( QueueIter_t it ) const; - - M m_memory; - - // if m_head == m_tail == QUEUE_ITERATOR_INVALID, then the queue is empty - QueueIter_t m_head; - QueueIter_t m_tail; - -#ifdef TEST_UTLQUEUE - friend void CUtlQueue_Test(); -#endif -}; - -//----------------------------------------------------------------------------- -// The CUtlQueueFixed class: -// A queue class with a fixed allocation scheme -//----------------------------------------------------------------------------- -template< class T, size_t MAX_SIZE > -class CUtlQueueFixed : public CUtlQueue< T, CUtlMemoryFixed > -{ - typedef CUtlQueue< T, CUtlMemoryFixed > BaseClass; -public: - - // constructor, destructor - CUtlQueueFixed( int growSize = 0, int initSize = 0 ) : BaseClass( growSize, initSize ) {} - CUtlQueueFixed( T* pMemory, int numElements ) : BaseClass( pMemory, numElements ) {} + CUtlVector m_heap; + T m_current; }; -template< class T, class M > -inline CUtlQueue::CUtlQueue( int growSize, int initSize ) : - m_memory( growSize, initSize ), m_head( QUEUE_ITERATOR_INVALID ), m_tail( QUEUE_ITERATOR_INVALID ) +template< class T > +inline CUtlQueue::CUtlQueue( int growSize, int initSize ) : + m_heap(growSize, initSize) { } -template< class T, class M > -inline CUtlQueue::CUtlQueue( T *pMemory, int numElements ) : - m_memory( pMemory, numElements ), m_head( QUEUE_ITERATOR_INVALID ), m_tail( QUEUE_ITERATOR_INVALID ) +template< class T > +inline CUtlQueue::CUtlQueue( T *pMemory, int numElements ) : + m_heap(pMemory, numElements) { } -template -inline T CUtlQueue::RemoveAtHead() +template +inline T const& CUtlQueue::RemoveAtHead() { - T temp; - RemoveAtHead( temp ); - return temp; + m_current = m_heap[0]; + m_heap.Remove((int)0); + return m_current; } -template -inline bool CUtlQueue::RemoveAtHead( T &removedElement ) +template +inline T const& CUtlQueue::RemoveAtTail() { - Assert( m_head != QUEUE_ITERATOR_INVALID ); - if ( m_head == QUEUE_ITERATOR_INVALID ) - { - Construct( &removedElement ); - return false; - } - - QueueIter_t it = m_head; - removedElement = m_memory[ it ]; - Destruct( &m_memory[ it ] ); - if ( m_head == m_tail ) - { - m_head = m_tail = QUEUE_ITERATOR_INVALID; - } - else - { - m_head = Next_Unchecked( m_head ); - } - return true; -} - -template -inline T CUtlQueue::RemoveAtTail() -{ - T temp; - RemoveAtTail( temp ); - return temp; -} - -template -inline bool CUtlQueue::RemoveAtTail( T &removedElement ) -{ - Assert( m_tail != QUEUE_ITERATOR_INVALID ); - if ( m_tail == QUEUE_ITERATOR_INVALID ) - { - Construct( &removedElement ); - return false; - } - - removedElement = m_memory[ m_tail ]; - Destruct( &m_memory[ m_tail ] ); - if ( m_head == m_tail ) - { - m_head = m_tail = QUEUE_ITERATOR_INVALID; - } - else - { - m_tail = Previous_Unchecked( m_tail ); - } - return true; + m_current = m_heap[ m_heap.Count() - 1 ]; + m_heap.Remove((int)(m_heap.Count() - 1)); + return m_current; } -template -inline T const& CUtlQueue::Head() const +template +inline T const& CUtlQueue::Head() { - Assert( m_head != QUEUE_ITERATOR_INVALID ); - if ( m_head == QUEUE_ITERATOR_INVALID ) - { - static T dummy; - return dummy; - } - - return m_memory[ m_head ]; + m_current = m_heap[0]; + return m_current; } -template -inline T const& CUtlQueue::Tail() const +template +inline T const& CUtlQueue::Tail() { - Assert( m_tail != QUEUE_ITERATOR_INVALID ); - if ( m_tail == QUEUE_ITERATOR_INVALID ) - { - static T dummy; - return dummy; - } - - return m_memory[ m_tail ]; + m_current = m_heap[ m_heap.Count() - 1 ]; + return m_current; } -template -void CUtlQueue::Insert( T const &element ) +template +void CUtlQueue::Insert( T const &element ) { - if ( m_tail == QUEUE_ITERATOR_INVALID ) - { - // empty - m_memory.EnsureCapacity( 1 ); - m_head = m_tail = QueueIter_t( 0 ); - } - else - { - // non-empty - QueueIter_t nextTail = Next_Unchecked( m_tail ); - if ( nextTail == m_head ) // if non-empty, and growing by 1 appears to make the queue of length 1, then we were already full before the Insert - { - int nOldAllocCount = m_memory.NumAllocated(); - m_memory.Grow(); - int nNewAllocCount = m_memory.NumAllocated(); - int nGrowAmount = nNewAllocCount - nOldAllocCount; - - nextTail = Next_Unchecked( m_tail ); // if nextTail was 0, then it now should be nOldAllocCount - - if ( m_head != QueueIter_t( 0 ) ) - { - // if the queue wraps around the end of m_memory, move the part at the end of memory to the new end of memory - Q_memmove( &m_memory[ m_head + nGrowAmount ], &m_memory[ m_head ], ( nOldAllocCount - m_head ) * sizeof( T ) ); -#ifdef _DEBUG - Q_memset( &m_memory[ m_head ], 0xdd, nGrowAmount * sizeof( T ) ); -#endif - m_head = QueueIter_t( m_head + nGrowAmount ); - } - } - m_tail = nextTail; - } - - CopyConstruct( &m_memory[ m_tail ], element ); + int index = m_heap.AddToTail(); + m_heap[index] = element; } -template -bool CUtlQueue::Check( T const element ) const +template +bool CUtlQueue::Check( T const element ) { - for ( QueueIter_t it = First(); it != QUEUE_ITERATOR_INVALID; it = Next( it ) ) - { - if ( m_memory[ it ] == element ) - return true; - } - return false; -} - -template -QueueIter_t CUtlQueue::First() const -{ - return m_head; -} - -template -QueueIter_t CUtlQueue::Next( QueueIter_t it ) const -{ - if ( it == QUEUE_ITERATOR_INVALID ) - return QUEUE_ITERATOR_INVALID; - - if ( it == m_tail ) - return QUEUE_ITERATOR_INVALID; - - Assert( IsValid( it ) ); - if ( !IsValid( it ) ) - return QUEUE_ITERATOR_INVALID; - - return Next_Unchecked( it ); -} - -template -QueueIter_t CUtlQueue::Last() const -{ - return m_tail; -} - -template -QueueIter_t CUtlQueue::Previous( QueueIter_t it ) const -{ - if ( it == QUEUE_ITERATOR_INVALID ) - return QUEUE_ITERATOR_INVALID; - - if ( it == m_head ) - return QUEUE_ITERATOR_INVALID; - - Assert( IsValid( it ) ); - if ( !IsValid( it ) ) - return QUEUE_ITERATOR_INVALID; - - return Previous_Unchecked( it ); -} - -template -QueueIter_t CUtlQueue::Next_Unchecked( QueueIter_t it ) const -{ - return it == m_memory.Count() - 1 ? QueueIter_t( 0 ) : QueueIter_t( it + 1 ); -} - -template -QueueIter_t CUtlQueue::Previous_Unchecked( QueueIter_t it ) const -{ - return it == 0 ? QueueIter_t( m_memory.Count() - 1 ) : QueueIter_t( it - 1 ); -} - -template -bool CUtlQueue::IsValid( QueueIter_t it ) const -{ - if ( it == QUEUE_ITERATOR_INVALID ) - return false; - - if ( m_head == QUEUE_ITERATOR_INVALID ) - return false; - - if ( m_head <= m_tail ) - return it >= m_head && it <= m_tail; - - return ( it >= m_head && it < m_memory.Count() ) || ( it >= 0 && it <= m_tail ); -} - -template -T const& CUtlQueue::Element( QueueIter_t it ) const -{ - Assert( it != QUEUE_ITERATOR_INVALID ); - if ( it == QUEUE_ITERATOR_INVALID ) - { - static T dummy; - return dummy; - } - - Assert( IsValid( it ) ); - return m_memory[ it ]; -} - -template -int CUtlQueue::Count() const -{ - if ( m_head == QUEUE_ITERATOR_INVALID ) - { - Assert( m_tail == QUEUE_ITERATOR_INVALID ); - return 0; - } - Assert( m_tail != QUEUE_ITERATOR_INVALID ); - - if ( m_head <= m_tail ) - return m_tail + 1 - m_head; - - return m_tail + 1 - m_head + m_memory.Count(); -} - -template -bool CUtlQueue::IsEmpty() const -{ - Assert( ( m_head == QUEUE_ITERATOR_INVALID ) == ( m_tail == QUEUE_ITERATOR_INVALID ) ); - return ( m_head == QUEUE_ITERATOR_INVALID ); -} - -template -void CUtlQueue::RemoveAll() -{ - m_head = m_tail = QUEUE_ITERATOR_INVALID; -} - -template -void CUtlQueue::Purge() -{ - m_head = m_tail = QUEUE_ITERATOR_INVALID; - m_memory.Purge(); -} - - -#ifdef TEST_UTLQUEUE - -#include - -struct Data_t -{ - Data_t( int i = 0xffffffff ) : m_id( i ) {} - Data_t( const Data_t &that ) : m_id( that.m_id ) {} - ~Data_t() { m_id = 0xdddddddd; } - Data_t &operator=( const Data_t &that ) { m_id = that.m_id; return *this; } - - int m_id; -}; - -inline void CUtlQueue_Test() -{ - CUtlQueue< Data_t > queue; - - for ( int n = 1; n < 100; ++n ) - { - Assert( queue.Count() == 0 ); - Assert( queue.m_head == QUEUE_ITERATOR_INVALID ); - Assert( queue.m_tail == QUEUE_ITERATOR_INVALID ); - - int w = rand() % n; - for ( int i = 0; i < w; ++i ) - { - queue.Insert( Data_t( i ) ); - } - - if ( w > 0 ) - { - Assert( queue.Head().m_id == queue.First() ); - Assert( queue.Tail().m_id == queue.Last() ); - Assert( queue.Head().m_id == 0 ); - Assert( queue.Tail().m_id == w - 1 ); - } - Assert( queue.Count() == w ); - - for ( int j = 0; j < n; ++j ) - { - queue.Insert( Data_t( w + j ) ); - - if ( j == 0 ) - { - Assert( queue.Count() == w + j + 1 ); - - for ( int i = 0; i < w; ++i ) - { - queue.RemoveAtHead(); - } - } - - Assert( queue.Count() == j + 1 ); - - Assert( queue.m_head != QUEUE_ITERATOR_INVALID ); - Assert( queue.m_tail != QUEUE_ITERATOR_INVALID ); - - int id = queue.Head().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.First(); it != QUEUE_ITERATOR_INVALID; it = queue.Next( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + 1 ) % queue.m_memory.Count(); - } - - id = queue.Tail().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.Last(); it != QUEUE_ITERATOR_INVALID; it = queue.Previous( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + queue.m_memory.Count() - 1 ) % queue.m_memory.Count(); - } - - for ( int i = 0; i < j; ++i ) - { - int id = queue.m_memory[ i ].m_id; - if ( queue.IsValid( QueueIter_t( i ) ) ) - { - Assert( ( id & 0xff000000 ) == 0 ); - } - else - { - Assert( id == 0xdddddddd ); - } - } - } - - Assert( queue.Count() == n ); -#if 0 - for ( int j = 0; j < n; ++j ) - { - Assert( queue.m_head != QUEUE_ITERATOR_INVALID ); - Assert( queue.m_tail != QUEUE_ITERATOR_INVALID ); - - Assert( queue.Count() == n - j ); - - Data_t data = queue.RemoveAtHead(); - - Assert( queue.Count() == n - j - 1 ); - - if ( queue.Count() > 0 ) - { - int id = queue.Head().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.First(); it != QUEUE_ITERATOR_INVALID; it = queue.Next( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + 1 ) % queue.m_memory.Count(); - } - - id = queue.Tail().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.Last(); it != QUEUE_ITERATOR_INVALID; it = queue.Previous( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + queue.m_memory.Count() - 1 ) % queue.m_memory.Count(); - } - } - - for ( int i = 0; i < j; ++i ) - { - int id = queue.m_memory[ i ].m_id; - if ( queue.IsValid( QueueIter_t( i ) ) ) - { - Assert( ( id & 0xff000000 ) == 0 ); - } - else - { - Assert( id == 0xdddddddd ); - } - } - } -#else - for ( int j = n - 1; j >= 0; --j ) - { - Assert( queue.m_head != QUEUE_ITERATOR_INVALID ); - Assert( queue.m_tail != QUEUE_ITERATOR_INVALID ); - - Assert( queue.Count() == j + 1 ); - - Data_t data = queue.RemoveAtTail(); - - Assert( queue.Count() == j ); - - if ( queue.Count() > 0 ) - { - int id = queue.Head().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.First(); it != QUEUE_ITERATOR_INVALID; it = queue.Next( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + 1 ) % queue.m_memory.Count(); - } - - id = queue.Tail().m_id % queue.m_memory.Count(); - for ( QueueIter_t it = queue.Last(); it != QUEUE_ITERATOR_INVALID; it = queue.Previous( it ) ) - { - Assert( queue.Element( it ).m_id % queue.m_memory.Count() == id ); - id = ( id + queue.m_memory.Count() - 1 ) % queue.m_memory.Count(); - } - } - - for ( int i = 0; i < j; ++i ) - { - int id = queue.m_memory[ i ].m_id; - if ( queue.IsValid( QueueIter_t( i ) ) ) - { - Assert( ( id & 0xff000000 ) == 0 ); - } - else - { - Assert( id == 0xdddddddd ); - } - } - } -#endif - - Assert( queue.Count() == 0 ); - Assert( queue.m_head == QUEUE_ITERATOR_INVALID ); - Assert( queue.m_tail == QUEUE_ITERATOR_INVALID ); - } + int index = m_heap.Find(element); + return ( index != -1 ); } -#endif // TEST_UTLQUEUE #endif // UTLQUEUE_H diff --git a/public/tier1/utlrbtree.h b/public/tier1/utlrbtree.h index ded22bf5..70b0d72c 100644 --- a/public/tier1/utlrbtree.h +++ b/public/tier1/utlrbtree.h @@ -217,8 +217,6 @@ class CUtlRBTree void RemoveAll( ); void Purge(); - bool HasElement( T const &search ) const { return Find( search ) != InvalidIndex(); } - // Allocation, deletion void FreeNode( I i ); @@ -1150,11 +1148,6 @@ void CUtlRBTree::RemoveAll() // Clear everything else out m_Root = InvalidIndex(); - // Technically, this iterator could become invalid. It will not, because it's - // always the same iterator. If we don't clear this here, the state of this - // container will be invalid after we start inserting elements again. - m_LastAlloc = m_Elements.InvalidIterator(); - m_FirstFree = InvalidIndex(); m_NumElements = 0; Assert( IsValid() ); @@ -1168,7 +1161,9 @@ template < class T, class I, typename L, class M > void CUtlRBTree::Purge() { RemoveAll(); + m_FirstFree = InvalidIndex(); m_Elements.Purge(); + m_LastAlloc = m_Elements.InvalidIterator(); } diff --git a/public/tier1/utlstring.h b/public/tier1/utlstring.h index 32714e12..c2a81d68 100644 --- a/public/tier1/utlstring.h +++ b/public/tier1/utlstring.h @@ -16,7 +16,8 @@ #include "limits.h" #if defined( OSX ) -inline wchar_t *wcsdup(const wchar_t *pString) +#define wcsdup wcsdup_osx +inline wchar_t *wcsdup_osx(const wchar_t *pString) { wchar_t *pMemory; @@ -31,14 +32,97 @@ inline wchar_t *wcsdup(const wchar_t *pString) return NULL; } +#endif -inline size_t strnlen(const char *s, size_t n) +//----------------------------------------------------------------------------- +// Base class, containing simple memory management +//----------------------------------------------------------------------------- +class CUtlBinaryBlock { - const char *p = (const char *)memchr(s, 0, n); - return (p ? p - s : n); +public: + CUtlBinaryBlock( int growSize = 0, int initSize = 0 ); + + // NOTE: nInitialLength indicates how much of the buffer starts full + CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ); + CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ); + CUtlBinaryBlock( const CUtlBinaryBlock& src ); + + void Get( void *pValue, int nMaxLen ) const; + void Set( const void *pValue, int nLen ); + const void *Get( ) const; + void *Get( ); + + unsigned char& operator[]( int i ); + const unsigned char& operator[]( int i ) const; + + int Length() const; + void SetLength( int nLength ); // Undefined memory will result + bool IsEmpty() const; + void Clear(); + void Purge(); + + bool IsReadOnly() const; + + CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src ); + + // Test for equality + bool operator==( const CUtlBinaryBlock &src ) const; + +private: + CUtlMemory m_Memory; + int m_nActualLength; +}; + + +//----------------------------------------------------------------------------- +// class inlines +//----------------------------------------------------------------------------- +inline const void *CUtlBinaryBlock::Get( ) const +{ + return m_Memory.Base(); +} + +inline void *CUtlBinaryBlock::Get( ) +{ + return m_Memory.Base(); +} + +inline int CUtlBinaryBlock::Length() const +{ + return m_nActualLength; +} + +inline unsigned char& CUtlBinaryBlock::operator[]( int i ) +{ + return m_Memory[i]; +} + +inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const +{ + return m_Memory[i]; +} + +inline bool CUtlBinaryBlock::IsReadOnly() const +{ + return m_Memory.IsReadOnly(); +} + +inline bool CUtlBinaryBlock::IsEmpty() const +{ + return Length() == 0; +} + +inline void CUtlBinaryBlock::Clear() +{ + SetLength( 0 ); +} + +inline void CUtlBinaryBlock::Purge() +{ + SetLength( 0 ); + m_Memory.Purge(); } -#endif //----------------------------------------------------------------------------- // Simple string class. @@ -56,154 +140,95 @@ class CUtlString public: CUtlString(); CUtlString( const char *pString ); - CUtlString( const char *pString, int length ); CUtlString( const CUtlString& string ); -#ifdef MOVE_CONSTRUCTOR_SUPPORT - // Support moving of CUtlString objects. Long live C++11 - // This move constructor will get called when appropriate, such as when - // returning objects from functions, or otherwise copying from temporaries - // which are about to be destroyed. It can also be explicitly invoked with - // std::move(). - // Move constructor: - CUtlString( CUtlString&& rhs ) - { - // Move the string pointer from the source to this -- be sure to - // zero out the source to avoid double frees. - m_pString = rhs.m_pString; - rhs.m_pString = 0; - } - // Move assignment operator: - CUtlString& operator=( CUtlString&& rhs ) - { - // Move the string pointer from the source to this -- be sure to - // zero out the source to avoid double frees. - m_pString = rhs.m_pString; - rhs.m_pString = 0; - return *this; - } -#endif - - ~CUtlString(); + // Attaches the string to external memory. Useful for avoiding a copy + CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ); + CUtlString( const void* pMemory, int nSizeInBytes ); const char *Get( ) const; void Set( const char *pValue ); - operator const char*() const; - // Set directly and don't look for a null terminator in pValue. - // nChars does not include the nul and this will only copy - // at most nChars (even if pValue is longer). If nChars - // is >strlen(pValue) it will copy past the end, don't do it - // Does nothing if pValue == String() - void SetDirect( const char *pValue, int nChars ); + void Clear() { Set( NULL ); } + + // Converts to c-strings + operator const char*() const; // for compatibility switching items from UtlSymbol const char *String() const { return Get(); } // Returns strlen int Length() const; - // IsEmpty() is more efficient than Length() == 0 bool IsEmpty() const; // Sets the length (used to serialize into the buffer ) // Note: If nLen != 0, then this adds an extra byte for a null-terminator. void SetLength( int nLen ); - char *GetForModify(); - void Clear(); + char *Get(); void Purge(); // Case Change void ToLower(); void ToUpper(); - void Append( const char *pAddition, int nChars ); void Append( const char *pchAddition ); - void Append( const char chAddition ) { char temp[2] = { chAddition, 0 }; Append( temp ); } + // Strips the trailing slash void StripTrailingSlash(); - void FixSlashes( char cSeparator = CORRECT_PATH_SEPARATOR ); - - // Trim whitespace - void TrimLeft( char cTarget ); - void TrimLeft( const char *szTargets = "\t\r\n " ); - void TrimRight( char cTarget ); - void TrimRight( const char *szTargets = "\t\r\n " ); - void Trim( char cTarget ); - void Trim( const char *szTargets = "\t\r\n " ); - - bool IsEqual_CaseSensitive( const char *src ) const; - bool IsEqual_CaseInsensitive( const char *src ) const; CUtlString &operator=( const CUtlString &src ); CUtlString &operator=( const char *src ); // Test for equality bool operator==( const CUtlString &src ) const; + bool operator==( const char *src ) const; bool operator!=( const CUtlString &src ) const { return !operator==( src ); } + bool operator!=( const char *src ) const { return !operator==( src ); } + + // If these are not defined, CUtlString as rhs will auto-convert + // to const char* and do logical operations on the raw pointers. Ugh. + inline friend bool operator==( const char *lhs, const CUtlString &rhs ) { return rhs.operator==( lhs ); } + inline friend bool operator!=( const char *lhs, const CUtlString &rhs ) { return rhs.operator!=( lhs ); } CUtlString &operator+=( const CUtlString &rhs ); CUtlString &operator+=( const char *rhs ); CUtlString &operator+=( char c ); CUtlString &operator+=( int rhs ); CUtlString &operator+=( double rhs ); - - CUtlString operator+( const char *pOther ) const; - CUtlString operator+( const CUtlString &other ) const; - CUtlString operator+( int rhs ) const; + + // is valid? + bool IsValid() const; bool MatchesPattern( const CUtlString &Pattern, int nFlags = 0 ) const; // case SENSITIVE, use * for wildcard in pattern string - char operator[]( int i ) const; - -#if ! defined(SWIG) - // Don't let SWIG see the PRINTF_FORMAT_STRING attribute or it will complain. - int Format( PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 2, 3 ); - int FormatV( PRINTF_FORMAT_STRING const char *pFormat, va_list marker ); -#else - int Format( const char *pFormat, ... ); - int FormatV( const char *pFormat, va_list marker ); -#endif + int Format( PRINTF_FORMAT_STRING const char *pFormat, ... ); + void SetDirect( const char *pValue, int nChars ); // Defining AltArgumentType_t hints that associative container classes should // also implement Find/Insert/Remove functions that take const char* params. typedef const char *AltArgumentType_t; - // Get a copy of part of the string. + // Take a piece out of the string. // If you only specify nStart, it'll go from nStart to the end. // You can use negative numbers and it'll wrap around to the start. - CUtlString Slice( int32 nStart=0, int32 nEnd=INT_MAX ) const; - - // Get a substring starting from the left or the right side. - CUtlString Left( int32 nChars ) const; - CUtlString Right( int32 nChars ) const; + CUtlString Slice( int32 nStart=0, int32 nEnd=INT_MAX ); - // Get a string with all instances of one character replaced with another. - CUtlString Replace( char cFrom, char cTo ) const; + // Grab a substring starting from the left or the right side. + CUtlString Left( int32 nChars ); + CUtlString Right( int32 nChars ); - // Replace all instances of specified string with another. - CUtlString Replace( const char *pszFrom, const char *pszTo ) const; + // Replace all instances of one character with another. + CUtlString Replace( char cFrom, char cTo ); - // Get this string as an absolute path (calls right through to V_MakeAbsolutePath). - CUtlString AbsPath( const char *pStartingDir=NULL ) const; + // Calls right through to V_MakeAbsolutePath. + CUtlString AbsPath( const char *pStartingDir=NULL ); // Gets the filename (everything except the path.. c:\a\b\c\somefile.txt -> somefile.txt). - CUtlString UnqualifiedFilename() const; + CUtlString UnqualifiedFilename(); + + // Strips off one directory. Uses V_StripLastDir but strips the last slash also! + CUtlString DirName(); - // Gets a string with one directory removed. Uses V_StripLastDir but strips the last slash also! - CUtlString DirName() const; - - // Get a string with the extension removed (with V_StripExtension). - CUtlString StripExtension() const; - - // Get a string with the filename removed (uses V_UnqualifiedFileName and also strips the last slash) - CUtlString StripFilename() const; - - // Get a string with the base filename (with V_FileBase). - CUtlString GetBaseFilename() const; - - // Get a string with the file extension (with V_FileBase). - CUtlString GetExtension() const; - // Works like V_ComposeFileName. static CUtlString PathJoin( const char *pStr1, const char *pStr2 ); @@ -211,93 +236,21 @@ class CUtlString static int __cdecl SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ); static int __cdecl SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 ); - // Empty string for those times when you need to return an empty string and - // either don't want to pay the construction cost, or are returning a - // const CUtlString& and cannot just return "". - static const CUtlString &GetEmptyString(); - private: - // INTERNALS - // AllocMemory allocates enough space for length characters plus a terminating zero. - // Previous characters are preserved, the buffer is null-terminated, but new characters - // are not touched. - void *AllocMemory( uint32 length ); - - // If m_pString is not NULL, it points to the start of the string, and the memory allocation. - char *m_pString; + CUtlBinaryBlock m_Storage; }; -// // If these are not defined, CUtlConstString as rhs will auto-convert -// // to const char* and do logical operations on the raw pointers. Ugh. -// inline friend bool operator<( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) > 0; } -// inline friend bool operator==( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) == 0; } -// inline friend bool operator!=( const T *lhs, const CUtlConstStringBase &rhs ) { return rhs.Compare( lhs ) != 0; } - -inline bool operator==( const char *pString, const CUtlString &utlString ) -{ - return utlString.IsEqual_CaseSensitive( pString ); -} - -inline bool operator!=( const char *pString, const CUtlString &utlString ) -{ - return !utlString.IsEqual_CaseSensitive( pString ); -} - -inline bool operator==( const CUtlString &utlString, const char *pString ) -{ - return utlString.IsEqual_CaseSensitive( pString ); -} - -inline bool operator!=( const CUtlString &utlString, const char *pString ) -{ - return !utlString.IsEqual_CaseSensitive( pString ); -} - - - //----------------------------------------------------------------------------- // Inline methods //----------------------------------------------------------------------------- -inline CUtlString::CUtlString() -: m_pString( NULL ) -{ -} - -inline CUtlString::CUtlString( const char *pString ) -: m_pString( NULL ) -{ - Set( pString ); -} - -inline CUtlString::CUtlString( const char *pString, int length ) -: m_pString( NULL ) -{ - SetDirect( pString, length ); -} - -inline CUtlString::CUtlString( const CUtlString& string ) -: m_pString( NULL ) -{ - Set( string.Get() ); -} - -inline CUtlString::~CUtlString() -{ - Purge(); -} - -inline int CUtlString::Length() const +inline bool CUtlString::IsEmpty() const { - if (m_pString) - { - return V_strlen( m_pString ); - } - return 0; + return Length() == 0; } -inline bool CUtlString::IsEmpty() const +inline bool CUtlString::IsValid() const { - return !m_pString || m_pString[0] == 0; + return ( String() != NULL ); } inline int __cdecl CUtlString::SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ) @@ -310,14 +263,6 @@ inline int __cdecl CUtlString::SortCaseSensitive( const CUtlString *pString1, co return V_strcmp( pString1->String(), pString2->String() ); } -// Converts to c-strings -inline CUtlString::operator const char*() const -{ - return Get(); -} - - - //----------------------------------------------------------------------------- // Purpose: Implementation of low-level string functionality for character types. //----------------------------------------------------------------------------- @@ -453,8 +398,5 @@ typedef CUtlConstStringBase CUtlConstWideString; template < typename T > struct UTLConstStringCaselessStringLessFunctor { bool operator()( const CUtlConstStringBase& a, const char *b ) const { return StringFuncs::CaselessCompare( a.Get(), b ) < 0; } }; template < typename T > struct UTLConstStringCaselessStringEqualFunctor { bool operator()( const CUtlConstStringBase& a, const char *b ) const { return StringFuncs::CaselessCompare( a.Get(), b ) == 0; } }; -// Helper function for CUtlMaps with a CUtlString key -inline bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs ) { return V_strcmp( lhs.Get(), rhs.Get() ) < 0; } -inline bool UtlStringCaseInsensitiveLessFunc( const CUtlString &lhs, const CUtlString &rhs ) { return V_stricmp( lhs.Get(), rhs.Get() ) < 0; } #endif // UTLSTRING_H diff --git a/public/tier1/utlsymbol.h b/public/tier1/utlsymbol.h index e90be466..340b7eac 100644 --- a/public/tier1/utlsymbol.h +++ b/public/tier1/utlsymbol.h @@ -46,6 +46,7 @@ class CUtlSymbol // operator== bool operator==( CUtlSymbol const& src ) const { return m_Id == src.m_Id; } + bool operator==( UtlSymId_t id ) const { return m_Id == id; } bool operator==( const char* pStr ) const; // Is valid? @@ -265,5 +266,51 @@ class CUtlFilenameSymbolTable mutable CThreadSpinRWLock m_lock; }; +// This creates a simple class that includes the underlying CUtlSymbol +// as a private member and then instances a private symbol table to +// manage those symbols. Avoids the possibility of the code polluting the +// 'global'/default symbol table, while letting the code look like +// it's just using = and .String() to look at CUtlSymbol type objects +// +// NOTE: You can't pass these objects between .dlls in an interface (also true of CUtlSymbol of course) +// +#define DECLARE_PRIVATE_SYMBOLTYPE(typename) \ + class typename \ + { \ + public: \ + typename(); \ + typename(const char *pStr); \ + typename &operator=(typename const &src); \ + bool operator==(typename const &src) const; \ + const char *String() const; \ + \ + private: \ + CUtlSymbol m_SymbolId; \ + }; + +// Put this in the .cpp file that uses the above typename +#define IMPLEMENT_PRIVATE_SYMBOLTYPE(typename) \ + static CUtlSymbolTable g_##typename##SymbolTable; \ + typename ::typename() \ + { \ + m_SymbolId = UTL_INVAL_SYMBOL; \ + } \ + typename ::typename(const char *pStr) \ + { \ + m_SymbolId = g_##typename##SymbolTable.AddString(pStr); \ + } \ + typename &typename ::operator=(typename const &src) \ + { \ + m_SymbolId = src.m_SymbolId; \ + return *this; \ + } \ + bool typename ::operator==(typename const &src) const \ + { \ + return (m_SymbolId == src.m_SymbolId); \ + } \ + const char *typename ::String() const \ + { \ + return g_##typename##SymbolTable.String(m_SymbolId); \ + } #endif // UTLSYMBOL_H diff --git a/public/tier1/utlvector.h b/public/tier1/utlvector.h index 5bd180fb..253e8b6b 100644 --- a/public/tier1/utlvector.h +++ b/public/tier1/utlvector.h @@ -23,7 +23,6 @@ #include "tier1/utlmemory.h" #include "tier1/utlblockmemory.h" #include "tier1/strtools.h" -#include "vstdlib/random.h" #define FOR_EACH_VEC( vecName, iteratorName ) \ for ( int iteratorName = 0; iteratorName < (vecName).Count(); iteratorName++ ) @@ -69,8 +68,6 @@ class CUtlVector const T& Head() const; T& Tail(); const T& Tail() const; - T& Random(); - const T& Random() const; // STL compatible member functions. These allow easier use of std::sort // and they are forward compatible with the C++ 11 range-based for loops. @@ -167,8 +164,6 @@ class CUtlVector void Sort( int (__cdecl *pfnCompare)(const T *, const T *) ); - void Shuffle( IUniformRandomStream* pSteam = NULL ); - #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, char *pchName ); // Validate our internal structures #endif // DBGFLAG_VALIDATE @@ -591,19 +586,6 @@ inline CUtlVector& CUtlVector::operator=( const CUtlVector &ot return *this; } -#ifdef STAGING_ONLY -inline void StagingUtlVectorBoundsCheck( int i, int size ) -{ - if ( (unsigned)i >= (unsigned)size ) - { - Msg( "Array access error: %d / %d\n", i, size ); - DebuggerBreak(); - } -} - -#else -#define StagingUtlVectorBoundsCheck( _i, _size ) -#endif //----------------------------------------------------------------------------- // element access @@ -613,7 +595,6 @@ inline T& CUtlVector::operator[]( int i ) { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); - StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -622,7 +603,6 @@ inline const T& CUtlVector::operator[]( int i ) const { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); - StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -631,7 +611,6 @@ inline T& CUtlVector::Element( int i ) { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); - StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -640,7 +619,6 @@ inline const T& CUtlVector::Element( int i ) const { // Do an inline unsigned check for maximum debug-build performance. Assert( (unsigned)i < (unsigned)m_Size ); - StagingUtlVectorBoundsCheck( i, m_Size ); return m_Memory[ i ]; } @@ -648,7 +626,6 @@ template< typename T, class A > inline T& CUtlVector::Head() { Assert( m_Size > 0 ); - StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ 0 ]; } @@ -656,7 +633,6 @@ template< typename T, class A > inline const T& CUtlVector::Head() const { Assert( m_Size > 0 ); - StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ 0 ]; } @@ -664,7 +640,6 @@ template< typename T, class A > inline T& CUtlVector::Tail() { Assert( m_Size > 0 ); - StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ m_Size - 1 ]; } @@ -672,7 +647,6 @@ template< typename T, class A > inline const T& CUtlVector::Tail() const { Assert( m_Size > 0 ); - StagingUtlVectorBoundsCheck( 0, m_Size ); return m_Memory[ m_Size - 1 ]; } @@ -686,37 +660,6 @@ inline int CUtlVector::Size() const return m_Size; } -template< typename T, class A > -inline T& CUtlVector::Random() -{ - Assert( m_Size > 0 ); - return m_Memory[ RandomInt( 0, m_Size - 1 ) ]; -} - -template< typename T, class A > -inline const T& CUtlVector::Random() const -{ - Assert( m_Size > 0 ); - return m_Memory[ RandomInt( 0, m_Size - 1 ) ]; -} - - -//----------------------------------------------------------------------------- -// Shuffle - Knuth/Fisher-Yates -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::Shuffle( IUniformRandomStream* pSteam ) -{ - for ( int i = 0; i < m_Size; i++ ) - { - int j = pSteam ? pSteam->RandomInt( i, m_Size - 1 ) : RandomInt( i, m_Size - 1 ); - if ( i != j ) - { - V_swap( m_Memory[ i ], m_Memory[ j ] ); - } - } -} - template< typename T, class A > inline int CUtlVector::Count() const { diff --git a/public/tier2/p4helpers.h b/public/tier2/p4helpers.h index 61c70c81..f4441974 100644 --- a/public/tier2/p4helpers.h +++ b/public/tier2/p4helpers.h @@ -33,15 +33,9 @@ class CP4File // Opens the file for add virtual bool Add( void ); - // Reverts the file - virtual bool Revert( void ); - // Is the file in perforce? virtual bool IsFileInPerforce(); - // Changes the file to the specified filetype. - virtual bool SetFileType( const CUtlString& desiredFileType ); - protected: // The filename that this class instance represents CUtlString m_sFilename; @@ -59,7 +53,6 @@ class CP4File_Dummy : public CP4File virtual bool Edit( void ) { return true; } virtual bool Add( void ) { return true; } virtual bool IsFileInPerforce() { return false; } - virtual bool SetFileType(const CUtlString& desiredFileType) { return true; } }; @@ -129,45 +122,11 @@ class CP4AutoAddFile class CP4AutoEditAddFile { public: - explicit CP4AutoEditAddFile( char const *szFilename ) - : m_spImpl( g_p4factory->AccessFile( szFilename ) ) - , m_bHasDesiredFileType( false ) - { - m_spImpl->Edit(); - } - - explicit CP4AutoEditAddFile( char const *szFilename, const char *szFiletype ) - : m_spImpl( g_p4factory->AccessFile( szFilename ) ) - , m_sFileType(szFiletype) - , m_bHasDesiredFileType( true ) + explicit CP4AutoEditAddFile( char const *szFilename ) : m_spImpl( g_p4factory->AccessFile( szFilename ) ) { m_spImpl->Edit(); - m_spImpl->SetFileType( m_sFileType ); } - - ~CP4AutoEditAddFile( void ) - { - m_spImpl->Add(); - if ( m_bHasDesiredFileType ) - m_spImpl->SetFileType( m_sFileType ); - } - - CP4File * File() const { return m_spImpl.Get(); } - -protected: - CPlainAutoPtr< CP4File > m_spImpl; - CUtlString m_sFileType; - bool m_bHasDesiredFileType; -}; - - -// -// CP4AutoRevert - reverts the file upon construction -// -class CP4AutoRevertFile -{ -public: - explicit CP4AutoRevertFile( char const *szFilename ) : m_spImpl( g_p4factory->AccessFile( szFilename ) ) { m_spImpl->Revert(); } + ~CP4AutoEditAddFile( void ) { m_spImpl->Add(); } CP4File * File() const { return m_spImpl.Get(); } diff --git a/public/togl/glfuncs.inl b/public/togl/glfuncs.inl index 1f6b3b45..55a24f45 100644 --- a/public/togl/glfuncs.inl +++ b/public/togl/glfuncs.inl @@ -1,2 +1,7 @@ +#if defined(LINUX) || defined(_WIN32) #include "togl/linuxwin/glfuncs.h" +#endif +#if defined(OSX) +#include "togl/osx/glfuncs.h" +#endif diff --git a/public/togl/linuxwin/cglmbuffer.h b/public/togl/linuxwin/cglmbuffer.h index 10782243..45c99882 100644 --- a/public/togl/linuxwin/cglmbuffer.h +++ b/public/togl/linuxwin/cglmbuffer.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // cglmprogram.h // GLMgr buffers (index / vertex) @@ -66,51 +44,6 @@ struct GLMBuffLockParams extern void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall = 128 * 1024 ); -//===========================================================================// - -// Creates an immutable storage for a buffer object -// https://www.opengl.org/registry/specs/ARB/buffer_storage.txt -class CPersistentBuffer -{ -public: - - CPersistentBuffer(); - ~CPersistentBuffer(); - - void Init( EGLMBufferType type,uint nSize ); - void Deinit(); - - void InsertFence(); - void BlockUntilNotBusy(); - - void Append( uint nSize ); - - inline uint GetBytesRemaining() const { return m_nSize - m_nOffset; } - inline uint GetOffset() const { return m_nOffset; } - inline void *GetPtr() const { return m_pImmutablePersistentBuf; } - inline GLuint GetHandle() const { return m_nHandle; } - -private: - - CPersistentBuffer( const CPersistentBuffer & ); - CPersistentBuffer & operator= (const CPersistentBuffer &); - - uint m_nSize; - - EGLMBufferType m_type; - GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB - GLuint m_nHandle; // handle of this program in the GL context - - // Holds a pointer to the persistently mapped buffer - void* m_pImmutablePersistentBuf; - - uint m_nOffset; - -#ifdef HAVE_GL_ARB_SYNC - GLsync m_nSyncObj; -#endif -}; - //=============================================================================== #if GL_ENABLE_INDEX_VERIFICATION @@ -159,7 +92,7 @@ class CGLMBufferSpanManager void DiscardAllSpans(); bool IsValid( uint nOffset, uint nSize ) const; - + private: bool AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf ); void ReleaseDynamicBuf( GLDynamicBuf_t &buf ); @@ -187,8 +120,6 @@ class CGLMBuffer public: void Lock( GLMBuffLockParams *pParams, char **pAddressOut ); void Unlock( int nActualSize = -1, const void *pActualData = NULL ); - - GLuint GetHandle() const; friend class GLMContext; // only GLMContext can make CGLMBuffer objects friend class GLMTester; @@ -228,9 +159,6 @@ class CGLMBuffer float *m_pLastMappedAddress; int m_nPinnedMemoryOfs; - - uint m_nPersistentBufferStartOffset; - bool m_bUsingPersistentBuffer; bool m_bPseudo; // true if the m_name is 0, and the backing is plain RAM diff --git a/public/togl/linuxwin/cglmfbo.h b/public/togl/linuxwin/cglmfbo.h index 93ebb11f..0cfd4226 100644 --- a/public/togl/linuxwin/cglmfbo.h +++ b/public/togl/linuxwin/cglmfbo.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // cglmfbo.h // GLMgr FBO's (render targets) diff --git a/public/togl/linuxwin/cglmprogram.h b/public/togl/linuxwin/cglmprogram.h index e3f4f60a..ca9a47a8 100644 --- a/public/togl/linuxwin/cglmprogram.h +++ b/public/togl/linuxwin/cglmprogram.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // cglmprogram.h // GLMgr programs (ARBVP/ARBfp) @@ -132,8 +110,8 @@ class CGLMProgram void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program void SetShaderName ( const char *name ); // only used for debugging/telemetry markup - void CompileActiveSources ( void ); // compile only the flavors that were provided. - void Compile ( EGLMProgramLang lang ); + bool CompileActiveSources ( void ); // compile only the flavors that were provided. + bool Compile ( EGLMProgramLang lang ); bool CheckValidity ( EGLMProgramLang lang ); void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that @@ -167,9 +145,6 @@ class CGLMProgram uint m_samplerMask; // (1<> 16 ); + uint nWidth = nWidthHeight & 0xFFFF, nHeight = nWidthHeight >> 16; // Apply half pixel offset to output vertices to account for the pixel center difference between D3D9 and OpenGL. // We output vertices in clip space, which ranges from [-1,1], so 1.0/width in clip space transforms into .5/width in screenspace, see: "Viewports and Clipping (Direct3D 9)" in the DXSDK - float v[4] = { 1.0f / fWidth, 1.0f / fHeight, fWidth, fHeight }; + float v[4] = { 1.0f / nWidth, 1.0f / nHeight, nWidth, nHeight }; if ( m_locVertexScreenParams >= 0 ) gGL->glUniform4fv( m_locVertexScreenParams, 1, v ); } @@ -264,10 +227,10 @@ class CGLMShaderPair // a container for a linked GLSL shader pair, and metad GLint m_locVertexBoneParams; // "vcbones" GLint m_locVertexInteger0; // "i0" - enum { cMaxVertexShaderBoolUniforms = 4, cMaxFragmentShaderBoolUniforms = 1 }; - - GLint m_locVertexBool[cMaxVertexShaderBoolUniforms]; // "b0", etc. - GLint m_locFragmentBool[cMaxFragmentShaderBoolUniforms]; // "fb0", etc. + GLint m_locVertexBool0; // "b0" + GLint m_locVertexBool1; // "b1" + GLint m_locVertexBool2; // "b2" + GLint m_locVertexBool3; // "b3" bool m_bHasBoolOrIntUniforms; // fragment stage uniforms @@ -280,11 +243,10 @@ class CGLMShaderPair // a container for a linked GLSL shader pair, and metad float m_fakeSRGBEnableValue; // shadow to avoid redundant sets of the m_locFragmentFakeSRGBEnable uniform // init it to -1.0 at link or relink, so it will trip on any legit incoming value (0.0 or 1.0) - GLint m_locSamplers[ GLM_SAMPLER_COUNT ]; // "sampler0 ... sampler1..." + GLint m_locSamplers[ 16 ]; // "sampler0 ... sampler1..." // other stuff bool m_valid; // true on successful link - bool m_bCheckLinkStatus; uint m_revision; // if this pair is relinked, bump this number. GLint m_locVertexScreenParams; // vcscreen diff --git a/public/togl/linuxwin/cglmquery.h b/public/togl/linuxwin/cglmquery.h index 168e3f7c..ff1ccfe9 100644 --- a/public/togl/linuxwin/cglmquery.h +++ b/public/togl/linuxwin/cglmquery.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // cglmquery.h // GLMgr queries @@ -32,6 +10,10 @@ #pragma once +#ifdef OSX +#include "glmgr/glmgrbasics.h" +#endif + //=============================================================================== // forward declarations diff --git a/public/togl/linuxwin/cglmtex.h b/public/togl/linuxwin/cglmtex.h index 90870a7f..cafdd1c7 100644 --- a/public/togl/linuxwin/cglmtex.h +++ b/public/togl/linuxwin/cglmtex.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // cglmtex.h // GLMgr textures @@ -33,7 +11,7 @@ #pragma once #ifdef OSX -#include "glmgrbasics.h" +#include "glmgr/glmgrbasics.h" #endif #include "tier1/utlhash.h" #include "tier1/utlmap.h" @@ -221,8 +199,6 @@ struct GLMTexLockDesc #define GLM_SAMPLER_COUNT 16 -#define GLM_MAX_PIXEL_TEX_SAMPLERS 16 -#define GLM_MAX_VERTEX_TEX_SAMPLERS 0 typedef CBitVec CTexBindMask; enum EGLMTexSliceFlag @@ -287,11 +263,9 @@ struct GLMTexSamplingParams m_packed.m_magFilter = D3DTEXF_POINT; m_packed.m_mipFilter = D3DTEXF_NONE; m_packed.m_maxAniso = 1; - m_packed.m_compareMode = 0; m_packed.m_isValid = true; } -#ifndef OSX FORCEINLINE void SetToSamplerObject( GLuint nSamplerObject ) const { static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 }; @@ -331,7 +305,6 @@ struct GLMTexSamplingParams gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT ); } } -#endif // !OSX inline void DeltaSetToTarget( GLenum target, const GLMTexSamplingParams &curState ) { @@ -404,7 +377,7 @@ struct GLMTexSamplingParams } } - inline void SetToTarget( GLenum target ) + inline void SetToTargetTexture( GLenum target ) { static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 }; static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR }; @@ -454,7 +427,6 @@ class CGLMTex void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut ); void Unlock( GLMTexLockParams *params ); - GLuint GetTexName() { return m_texName; } protected: friend class GLMContext; // only GLMContext can make CGLMTex objects @@ -468,7 +440,7 @@ class CGLMTex friend struct IDirect3DCubeTexture9; friend struct IDirect3DVolumeTexture9; - CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char *debugLabel = NULL ); + CGLMTex( GLMContext *ctx, GLMTexLayout *layout, const char *debugLabel = NULL ); ~CGLMTex( ); int CalcSliceIndex( int face, int mip ); @@ -478,17 +450,13 @@ class CGLMTex void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false ); // last param lets us send NULL data ptr (only legal with uncompressed formats, beware) // this helps out ResetSRGB. - -#if defined( OSX ) - void HandleSRGBMismatch( bool srgb, int &srgbFlipCount ); - void ResetSRGB( bool srgb, bool noDataWrite ); - // re-specify texture format to match desired sRGB form - // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's -#endif bool IsRBODirty() const; void ForceRBONonDirty(); void ForceRBODirty(); + + void AllocBacking(); + void ReleaseBacking(); // re-specify texture format to match desired sRGB form // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's @@ -496,26 +464,25 @@ class CGLMTex GLuint m_texName; // name of this texture in the context GLenum m_texGLTarget; uint m_nSamplerType; // SAMPLER_2D, etc. - GLMTexSamplingParams m_SamplingParams; - GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout) uint m_nLastResolvedBatchCounter; int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. + int m_mipCount; GLMContext *m_ctx; // link back to parent context - CGLMFBO *m_pBlitSrcFBO; CGLMFBO *m_pBlitDstFBO; + GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero) int m_rtAttachCount; // how many RT's have this texture attached somewhere - char *m_backing; // backing storage if available + char *m_pBacking; // backing storage if available int m_lockCount; // lock reqs are stored in the GLMContext for tracking @@ -526,7 +493,6 @@ class CGLMTex bool m_texClientStorage; // was CS selected for texture bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet - int m_srgbFlipCount; #if GLMDEBUG CGLMTex *m_pPrevTex; CGLMTex *m_pNextTex; diff --git a/public/togl/linuxwin/dxabstract.h b/public/togl/linuxwin/dxabstract.h index b601e78d..0e367329 100644 --- a/public/togl/linuxwin/dxabstract.h +++ b/public/togl/linuxwin/dxabstract.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // dxabstract.h // @@ -40,10 +18,8 @@ #define IUNKNOWN_ALLOC_SPEW 0 #define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0 - TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect ); - struct TOGL_CLASS IUnknown { int m_refcount[2]; @@ -162,6 +138,7 @@ struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A T { D3DSURFACE_DESC m_descZero; // desc of top level. CGLMTex *m_tex; // a CGLMTex can represent all forms of tex + int m_srgbFlipCount; virtual ~IDirect3DBaseTexture9(); D3DRESOURCETYPE TOGLMETHODCALLTYPE GetType(); @@ -293,8 +270,7 @@ struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnkno uint m_pixHighWater; // count of active constant slots referenced by shader. uint m_pixSamplerMask; // (1<SetSamplerDirty( Sampler ); @@ -780,7 +747,7 @@ FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerState( DWORD m_ctx->SetSamplerMaxAnisotropy( Sampler, Value); break; case D3DSAMP_SRGBTEXTURE: - //m_samplers[ Sampler ].m_srgb = Value; + m_samplers[ Sampler ].m_srgb = Value; m_ctx->SetSamplerSRGBTexture(Sampler, Value); break; case D3DSAMP_SHADOWFILTER: @@ -801,7 +768,7 @@ FORCEINLINE void TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerStates( SetSamplerStatesNonInline( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter ); #else Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); - Assert( Sampler < GLM_SAMPLER_COUNT); + Assert( Sampler < 16); m_ctx->SetSamplerDirty( Sampler ); @@ -815,7 +782,6 @@ FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetTexture(DWORD Stage, return SetTextureNonInline( Stage, pTexture ); #else Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); - Assert( Stage < GLM_SAMPLER_COUNT ); m_textures[Stage] = pTexture; m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL ); return S_OK; @@ -843,10 +809,13 @@ FORCEINLINE GLenum D3DBlendOperationToGL( DWORD operation ) switch (operation) { case D3DBLENDOP_ADD : return GL_FUNC_ADD; // The result is the destination added to the source. Result = Source + Destination - case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination - case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source - case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination) - case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination) + + /* not covered by dxabstract.h.. + case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination + case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source + case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination) + case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination) + */ default: DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF; @@ -1205,7 +1174,7 @@ FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetStreamSource(UINT St // OK, we are being given the stride, we don't need to calc it.. GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_name: -1, OffsetInBytes, Stride)); - + if ( !pStreamData ) { OffsetInBytes = 0; diff --git a/public/togl/linuxwin/dxabstract_types.h b/public/togl/linuxwin/dxabstract_types.h index 9713ec71..5f2ccba3 100644 --- a/public/togl/linuxwin/dxabstract_types.h +++ b/public/togl/linuxwin/dxabstract_types.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // dxabstract_types.h // @@ -72,6 +50,10 @@ class CGLMFBO; #define TOGL_GLOBAL DLL_GLOBAL_IMPORT #endif +#ifdef OSX +#error "Do not use this header's types on OSX until togo is ported to Mac!" +#endif + #define TOGLMETHODCALLTYPE __stdcall //#define TOGLMETHODCALLTYPE @@ -194,25 +176,6 @@ typedef enum _D3DFORMAT D3DFORMAT; #define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000 #define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16 -// Comparison for dynamic conditional instruction opcodes (i.e. if, breakc) -typedef enum _D3DSHADER_COMPARISON -{ - // < = > - D3DSPC_RESERVED0= 0, // 0 0 0 - D3DSPC_GT = 1, // 0 0 1 - D3DSPC_EQ = 2, // 0 1 0 - D3DSPC_GE = 3, // 0 1 1 - D3DSPC_LT = 4, // 1 0 0 - D3DSPC_NE = 5, // 1 0 1 - D3DSPC_LE = 6, // 1 1 0 - D3DSPC_RESERVED1= 7 // 1 1 1 -} D3DSHADER_COMPARISON; - - -// Comparison is part of instruction opcode token: -#define D3DSHADER_COMPARISON_SHIFT D3DSP_OPCODESPECIFICCONTROL_SHIFT -#define D3DSHADER_COMPARISON_MASK (0x7< -#include + #include + #include + #include + #include + #include + #include + #include + #include +#elif defined(DX_TO_GL_ABSTRACTION) + #include + #include +#else + #error #endif #ifdef DX_TO_GL_ABSTRACTION @@ -52,18 +37,20 @@ #endif #undef CurrentTime - #if defined( USE_SDL ) - #include "SDL.h" + // prevent some conflicts in SDL headers... + #undef M_PI + #include + #ifndef _STDINT_H_ + #define _STDINT_H_ 1 #endif #endif //=============================================================================== // glue to call out to Obj-C land (these are in glmgrcocoa.mm) #ifdef OSX - typedef void _PseudoNSGLContext; // aka NSOpenGLContext - typedef _PseudoNSGLContext *PseudoNSGLContextPtr; - + bool NewNSGLContext( unsigned long *attribs, PseudoNSGLContextPtr nsglShareCtx, PseudoNSGLContextPtr *nsglCtxOut, CGLContextObj *cglCtxOut ); CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx ); + void DelNSGLContext( PseudoNSGLContextPtr nsglCtx ); #endif // Set TOGL_SUPPORT_NULL_DEVICE to 1 to support the NULL ref device diff --git a/public/togl/linuxwin/glentrypoints.h b/public/togl/linuxwin/glentrypoints.h index 9b55c00a..cff42928 100644 --- a/public/togl/linuxwin/glentrypoints.h +++ b/public/togl/linuxwin/glentrypoints.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // glentrypoints.h // @@ -34,8 +12,10 @@ #ifdef DX_TO_GL_ABSTRACTION #include "tier0/platform.h" +#include "tier0/dynfunction.h" #include "tier0/vprof_telemetry.h" #include "interface.h" + #include "togl/rendermechanism.h" void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL); @@ -297,6 +277,7 @@ class COpenGLEntryPoints ~COpenGLEntryPoints(); void ClearEntryPoints(); + uint64 m_nTotalGLCycles, m_nTotalGLCalls; int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2. @@ -307,26 +288,20 @@ class COpenGLEntryPoints char *m_pGLDriverStrings[cGLTotalDriverStrings]; GLDriverProvider_t m_nDriverProvider; -#ifdef OSX -#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; -#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (*) arg, ret > fn; -#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (*) arg, void > fn; -#else -#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; -#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn; -#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn; -#endif + #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; + #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn; + #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn; #include "togl/glfuncs.inl" #undef GL_FUNC_VOID #undef GL_FUNC #undef GL_EXT - + bool HasSwapTearExtension() const { #ifdef _WIN32 - return m_bHave_WGL_EXT_swap_control_tear; + return m_bHave_WGL_EXT_swap_control_tear; #else - return m_bHave_GLX_EXT_swap_control_tear; + return m_bHave_GLX_EXT_swap_control_tear; #endif } }; diff --git a/public/togl/linuxwin/glfuncs.h b/public/togl/linuxwin/glfuncs.h index f543b4af..f5795139 100644 --- a/public/togl/linuxwin/glfuncs.h +++ b/public/togl/linuxwin/glfuncs.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // !!! FIXME: Some of these aren't base OpenGL...pick out the extensions. // !!! FIXME: Also, look up these -1, -1 versions numbers. GL_FUNC(OpenGL,true,GLenum,glGetError,(void),()) @@ -61,11 +39,8 @@ GL_FUNC_VOID(OpenGL,true,glDisable,(GLenum a),(a)) GL_FUNC_VOID(OpenGL,true,glDisableVertexAttribArray,(GLuint a),(a)) GL_FUNC_VOID(OpenGL,true,glDrawArrays,(GLenum a,GLint b,GLsizei c),(a,b,c)) GL_FUNC_VOID(OpenGL,true,glDrawBuffer,(GLenum a),(a)) -GL_FUNC_VOID(OpenGL,true,glDrawBuffers,(GLsizei a,const GLenum *b),(a,b)) GL_FUNC_VOID(OpenGL,true,glDrawRangeElements,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f),(a,b,c,d,e,f)) -#ifndef OSX // 10.6/GL 2.1 compatability GL_FUNC_VOID(OpenGL,true,glDrawRangeElementsBaseVertex,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f, GLenum g),(a,b,c,d,e,f,g)) -#endif GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a)) GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a)) GL_FUNC_VOID(OpenGL,true,glEnd,(void),()) @@ -210,24 +185,17 @@ GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glRenderbufferStorageMultisample,(G GL_EXT(GL_GREMEDY_string_marker,-1,-1) GL_FUNC_VOID(GL_GREMEDY_string_marker,false,glStringMarkerGREMEDY,(GLsizei a,const void *b),(a,b)) GL_EXT(GL_ARB_debug_output,-1,-1) -#ifdef OSX -GL_FUNC_VOID(GL_ARB_debug_output,false,glDebugMessageCallbackARB,(void ( *a)(GLenum, GLenum , GLuint , GLenum , GLsizei , const GLchar* , GLvoid*) ,void* b),(a,b)) -#else GL_FUNC_VOID(GL_ARB_debug_output,false,glDebugMessageCallbackARB,(void (APIENTRY *a)(GLenum, GLenum , GLuint , GLenum , GLsizei , const GLchar* , GLvoid*) ,void* b),(a,b)) -#endif GL_FUNC_VOID(GL_ARB_debug_output,false,glDebugMessageControlARB,(GLenum a, GLenum b, GLenum c, GLsizei d, const GLuint* e, GLboolean f),(a,b,c,d,e,f)) - GL_EXT(GL_EXT_direct_state_access,-1,-1) GL_FUNC_VOID(GL_EXT_direct_state_access,false,glBindMultiTextureEXT,(GLenum a,GLuint b, GLuint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glGenSamplers,(GLuint a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDeleteSamplers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBindSampler,(GLuint a, GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glSamplerParameteri,(GLuint a, GLenum b, GLint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glSamplerParameterf,(GLuint a, GLenum b, GLfloat c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glSamplerParameterfv,(GLuint a, GLenum b, const GLfloat *c),(a,b,c)) GL_EXT(GL_NV_bindless_texture,-1,-1) - -#ifndef OSX -GL_FUNC_VOID(OpenGL, true, glGenSamplers, (GLuint a, GLuint *b), (a, b)) -GL_FUNC_VOID(OpenGL, true, glDeleteSamplers, (GLsizei a, const GLuint *b), (a, b)) -GL_FUNC_VOID(OpenGL, true, glBindSampler, (GLuint a, GLuint b), (a, b)) -GL_FUNC_VOID(OpenGL, true, glSamplerParameteri, (GLuint a, GLenum b, GLint c), (a, b, c)) -GL_FUNC_VOID(OpenGL, true, glSamplerParameterf, (GLuint a, GLenum b, GLfloat c), (a, b, c)) -GL_FUNC_VOID(OpenGL, true, glSamplerParameterfv, (GLuint a, GLenum b, const GLfloat *c), (a, b, c)) GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureHandleNV, (GLuint texture), (texture)) GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureSamplerHandleNV, (GLuint texture, GLuint sampler), (texture, sampler)) GL_FUNC_VOID(GL_NV_bindless_texture, false, glMakeTextureHandleResidentNV, (GLuint64 handle), (handle)) @@ -245,17 +213,11 @@ GL_FUNC_VOID(OpenGL,true,glQueryCounter,(GLuint id, GLenum target), (id, target) GL_FUNC_VOID(OpenGL,true,glGetQueryObjectiv,(GLuint id, GLenum pname, GLint *params), (id, pname, params)) GL_FUNC_VOID(OpenGL,true,glGetQueryObjectui64v,(GLuint id, GLenum pname, GLuint64 *params), (id, pname, params)) GL_FUNC_VOID(OpenGL,true,glCopyBufferSubData,(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size),(readtarget, writetarget, readoffset, writeoffset, size)) -#endif // !OSX - GL_EXT(GL_AMD_pinned_memory,-1,-1) GL_EXT(GL_EXT_framebuffer_multisample_blit_scaled,-1,-1) - -#ifndef OSX GL_FUNC_VOID(OpenGL,true,glGenVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays)) GL_FUNC_VOID(OpenGL,true,glDeleteVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays)) GL_FUNC_VOID(OpenGL,true,glBindVertexArray,(GLuint a),(a)) -#endif // !OSX - GL_EXT(GL_EXT_texture_sRGB_decode,-1,-1) GL_FUNC_VOID(OpenGL,true,glPushClientAttrib,(GLbitfield a),(a)) GL_FUNC_VOID(OpenGL,true,glPopClientAttrib,(void),()) @@ -266,9 +228,6 @@ GL_EXT(GL_EXT_texture_compression_dxt1,-1,-1) GL_EXT(GL_ANGLE_texture_compression_dxt3,-1,-1) GL_EXT(GL_ANGLE_texture_compression_dxt5,-1,-1) -GL_EXT( GL_ARB_buffer_storage, 4, 4 ) -GL_FUNC_VOID( GL_ARB_buffer_storage, false, glBufferStorage, (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags), (target, size, data, flags) ) - // This one is an OS extension. We'll add a little helper function to look for it. #ifdef _WIN32 GL_EXT(WGL_EXT_swap_control_tear,-1,-1) diff --git a/public/togl/linuxwin/glmdebug.h b/public/togl/linuxwin/glmdebug.h index 08cb6f91..8efba8b4 100644 --- a/public/togl/linuxwin/glmdebug.h +++ b/public/togl/linuxwin/glmdebug.h @@ -1,33 +1,8 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. #ifndef GLMDEBUG_H #define GLMDEBUG_H #include "tier0/platform.h" -#if defined( OSX ) -#include -#endif // include this anywhere you need to be able to compile-out code related specifically to GLM debugging. @@ -157,7 +132,11 @@ inline void GLMDebugger( void ) { if (GLMDebugChannelMask() & (1< #include +#include #include #include #include -#endif - -#ifdef MAC_OS_X_VERSION_10_9 -typedef uint32_t CGDirectDisplayID; -typedef uint32_t CGOpenGLDisplayMask; -typedef double CGRefreshRate; +#include +#elif defined(DX_TO_GL_ABSTRACTION) +#include +#include +#include "tier0/platform.h" +#else +#error #endif typedef void _PseudoNSGLContext; // aka NSOpenGLContext @@ -149,7 +125,7 @@ struct GLMRendererInfoFields bool m_intel; bool m_intel95x; bool m_intel3100; - bool m_intelHD4000; + bool m_intelNewer; bool m_nv; bool m_nvG7x; @@ -193,7 +169,6 @@ struct GLMRendererInfoFields //--------------------------- " bads " - known bad drivers bool m_badDriver1064NV; // this is the bad NVIDIA driver on 10.6.4 - stutter, tex corruption, black screen issues - bool m_badDriver108Intel; // this is the bad Intel HD4000 driver on 10.8 - intermittent crash on GLSL compilation. }; diff --git a/public/togl/linuxwin/glmdisplaydb.h b/public/togl/linuxwin/glmdisplaydb.h index 686c792d..d9f64d80 100644 --- a/public/togl/linuxwin/glmdisplaydb.h +++ b/public/togl/linuxwin/glmdisplaydb.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. #ifndef GLMDISPLAYDB_H #define GLMDISPLAYDB_H @@ -54,24 +32,13 @@ class GLMDisplayInfo public: GLMDisplayInfoFields m_info; CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes - GLMDisplayMode m_DesktopMode; -#ifdef OSX - GLMDisplayInfo( CGDirectDisplayID displayID, CGOpenGLDisplayMask displayMask ); -#else GLMDisplayInfo( void ); -#endif - ~GLMDisplayInfo( void ); void PopulateModes( void ); void Dump( int which ); - -#ifdef OSX -private: - int m_display; -#endif }; //=============================================================================== @@ -81,55 +48,23 @@ class GLMDisplayInfo class GLMRendererInfo { public: - GLMRendererInfoFields m_info; -#ifdef OSX - CUtlVector< GLMDisplayInfo* > *m_displays; // starts out NULL, set by PopulateDisplays -#else - GLMDisplayInfo *m_display; -#endif - -#ifdef OSX - GLMRendererInfo ( GLMRendererInfoFields *info ); -#else + GLMRendererInfoFields m_info; + GLMDisplayInfo *m_display; + GLMRendererInfo (); -#endif ~GLMRendererInfo ( void ); -#ifndef OSX void Init( GLMRendererInfoFields *info ); -#endif void PopulateDisplays(); void Dump( int which ); }; //=============================================================================== -#ifdef OSX -// this is just a tuple describing fake adapters which are really renderer/display pairings. -// dxabstract bridges the gap between the d3d adapter-centric world and the GL renderer+display world. -// this makes it straightforward to handle cases like two video cards with two displays on one, and one on the other - -// you get three fake adapters which represent each useful screen. - -// the constraint that dxa will have to follow though, is that if the user wants to change their -// display selection for full screen, they would only be able to pick on that has the same underlying renderer. -// can't change fakeAdapter from one to another with different GL renderer under it. Screen hop but no card hop. - -struct GLMFakeAdapter -{ - int m_rendererIndex; - int m_displayIndex; -}; -#endif - class GLMDisplayDB { public: -#ifdef OSX - CUtlVector< GLMRendererInfo* > *m_renderers; // starts out NULL, set by PopulateRenderers - CUtlVector< GLMFakeAdapter > m_fakeAdapters; -#else GLMRendererInfo m_renderer; -#endif GLMDisplayDB ( void ); ~GLMDisplayDB ( void ); diff --git a/public/togl/linuxwin/glmgr.h b/public/togl/linuxwin/glmgr.h index aabcd708..2f555db9 100644 --- a/public/togl/linuxwin/glmgr.h +++ b/public/togl/linuxwin/glmgr.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // glmgr.h // singleton class, common basis for managing GL contexts @@ -33,11 +11,6 @@ #pragma once -#undef HAVE_GL_ARB_SYNC -#ifndef OSX -#define HAVE_GL_ARB_SYNC 1 -#endif - #include "glbase.h" #include "glentrypoints.h" #include "glmdebug.h" @@ -55,9 +28,6 @@ #include "dxabstract_types.h" #include "tier0/icommandline.h" -#undef FORCEINLINE -#define FORCEINLINE inline - //=============================================================================== #define GLM_OPENGL_VENDOR_ID 1 @@ -1096,7 +1066,7 @@ struct GLMVertexSetup #define kGLMProgramParamInt4Limit 16 #define kGLMVertexProgramParamFloat4Limit 256 -#define kGLMFragmentProgramParamFloat4Limit 256 +#define kGLMFragmentProgramParamFloat4Limit 32 struct GLMProgramParamsF { @@ -1204,7 +1174,6 @@ class CFlushDrawStatesStats }; //===========================================================================// -#ifndef OSX #ifndef GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD #define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 @@ -1218,16 +1187,7 @@ class CPinnedMemoryBuffer CPinnedMemoryBuffer & operator= ( const CPinnedMemoryBuffer & ); public: - CPinnedMemoryBuffer() - : - m_pRawBuf( NULL ) - , m_pBuf( NULL ) - , m_nSize( 0 ) - , m_nOfs( 0 ) - , m_nBufferObj( 0 ) -#ifdef HAVE_GL_ARB_SYNC - , m_nSyncObj( 0 ) -#endif + CPinnedMemoryBuffer() : m_pRawBuf( NULL ), m_pBuf( NULL ), m_nSize( 0 ), m_nOfs( 0 ), m_nBufferObj( 0 ), m_nSyncObj( 0 ) { } @@ -1239,7 +1199,7 @@ class CPinnedMemoryBuffer bool Init( uint nSize ) { Deinit(); - + // Guarantee 64KB alignment m_pRawBuf = malloc( nSize + 65535 ); m_pBuf = reinterpret_cast((reinterpret_cast(m_pRawBuf) + 65535) & (~65535)); @@ -1250,7 +1210,7 @@ class CPinnedMemoryBuffer gGL->glBindBufferARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nBufferObj ); gGL->glBufferDataARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nSize, m_pBuf, GL_STREAM_COPY ); - + return true; } @@ -1258,22 +1218,22 @@ class CPinnedMemoryBuffer { if ( !m_pRawBuf ) return; - + BlockUntilNotBusy(); - + gGL->glBindBufferARB(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nBufferObj ); gGL->glBufferDataARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0, (void*)NULL, GL_STREAM_COPY ); - + gGL->glBindBufferARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0 ); - + gGL->glDeleteBuffersARB( 1, &m_nBufferObj ); m_nBufferObj = 0; free( m_pRawBuf ); m_pRawBuf = NULL; m_pBuf = NULL; - + m_nSize = 0; m_nOfs = 0; } @@ -1286,49 +1246,43 @@ class CPinnedMemoryBuffer void InsertFence() { -#ifdef HAVE_GL_ARB_SYNC if ( m_nSyncObj ) { gGL->glDeleteSync( m_nSyncObj ); } m_nSyncObj = gGL->glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); -#endif } void BlockUntilNotBusy() { -#ifdef HAVE_GL_ARB_SYNC if ( m_nSyncObj ) { gGL->glClientWaitSync( m_nSyncObj, GL_SYNC_FLUSH_COMMANDS_BIT, 3000000000000ULL ); - + gGL->glDeleteSync( m_nSyncObj ); - + m_nSyncObj = 0; } -#endif m_nOfs = 0; } - + void Append( uint nSize ) { m_nOfs += nSize; Assert( m_nOfs <= m_nSize ); } - + private: void *m_pRawBuf; void *m_pBuf; uint m_nSize; uint m_nOfs; - + GLuint m_nBufferObj; -#ifdef HAVE_GL_ARB_SYNC + GLsync m_nSyncObj; -#endif }; -#endif // !OSX //===========================================================================// @@ -1356,7 +1310,7 @@ class GLMContext // textures // Lock and Unlock reqs go directly to the tex object - CGLMTex *NewTex( GLMTexLayoutKey *key, uint levels=1, const char *debugLabel=NULL ); + CGLMTex *NewTex( GLMTexLayoutKey *key, const char *debugLabel=NULL ); void DelTex( CGLMTex *tex ); // options for Blit (replacement for ResolveTex and BlitTex) @@ -1393,7 +1347,7 @@ class GLMContext // render targets (FBO's) CGLMFBO *NewFBO( void ); void DelFBO( CGLMFBO *fbo ); - + // programs CGLMProgram *NewProgram( EGLMProgramType type, char *progString, const char *pShaderName ); void DelProgram( CGLMProgram *pProg ); @@ -1406,7 +1360,6 @@ class GLMContext void SetDrawingLang( EGLMProgramLang lang, bool immediate=false ); // choose ARB or GLSL. immediate=false defers lang change to top of frame void LinkShaderPair( CGLMProgram *vp, CGLMProgram *fp ); // ensure this combo has been linked and is in the GLSL pair cache - void ValidateShaderPair( CGLMProgram *vp, CGLMProgram *fp ); void ClearShaderPairCache( void ); // call this to shoot down all the linked pairs void QueryShaderPair( int index, GLMShaderPairInfo *infoOut ); // this lets you query the shader pair cache for saving its state @@ -1450,12 +1403,8 @@ class GLMContext void FlushDrawStatesNoShaders(); // drawing -#ifndef OSX FORCEINLINE void DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf ); void DrawRangeElementsNonInline( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf ); -#else - void DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, CGLMBuffer *pIndexBuf ); -#endif void CheckNative( void ); @@ -1472,7 +1421,7 @@ class GLMContext // Called when IDirect3DDevice9::Reset() is called. void Reset(); - + // writers for the state block inputs FORCEINLINE void WriteAlphaTestEnable( GLAlphaTestEnable_t *src ) { m_AlphaTestEnable.Write( src ); } @@ -1533,6 +1482,7 @@ class GLMContext #endif FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants ); + FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; } protected: @@ -1557,10 +1507,8 @@ class GLMContext GLMContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params ); ~GLMContext(); -#ifndef OSX FORCEINLINE GLuint FindSamplerObject( const GLMTexSamplingParams &desiredParams ); -#endif - + FORCEINLINE void SetBufAndVertexAttribPointer( uint nIndex, GLuint nGLName, GLuint stride, GLuint datatype, GLboolean normalized, GLuint nCompCount, const void *pBuf, uint nRevision ) { VertexAttribs_t &curAttribs = m_boundVertexAttribs[nIndex]; @@ -1570,7 +1518,7 @@ class GLMContext gGL->glBindBufferARB( GL_ARRAY_BUFFER_ARB, nGLName ); } else if ( ( curAttribs.m_pPtr == pBuf ) && - ( curAttribs.m_revision == nRevision ) && + ( curAttribs.m_revision == nRevision ) && ( curAttribs.m_stride == stride ) && ( curAttribs.m_datatype == datatype ) && ( curAttribs.m_normalized == normalized ) && @@ -1585,7 +1533,7 @@ class GLMContext curAttribs.m_stride = stride; curAttribs.m_pPtr = pBuf; curAttribs.m_revision = nRevision; - + gGL->glVertexAttribPointer( nIndex, nCompCount, datatype, normalized, stride, pBuf ); } @@ -1607,7 +1555,7 @@ class GLMContext m_CurAttribs.m_vtxAttribMap[0] = 0xBBBBBBBBBBBBBBBBULL; m_CurAttribs.m_vtxAttribMap[1] = 0xBBBBBBBBBBBBBBBBULL; } - + FORCEINLINE void ReleasedShader() { NullProgram(); } // textures @@ -1624,7 +1572,7 @@ class GLMContext // render targets / FBO's void BindFBOToCtx( CGLMFBO *fbo, GLenum bindPoint = GL_FRAMEBUFFER_EXT ); // you can also choose GL_READ_FRAMEBUFFER_EXT / GL_DRAW_FRAMEBUFFER_EXT - + // buffers FORCEINLINE void BindGLBufferToCtx( GLenum nGLBufType, GLuint nGLName, bool bForce = false ) { @@ -1637,48 +1585,40 @@ class GLMContext gGL->glBindBufferARB( nGLBufType, nGLName ); } } - + void BindBufferToCtx( EGLMBufferType type, CGLMBuffer *buff, bool force = false ); // does not twiddle any enables. FORCEINLINE void BindIndexBufferToCtx( CGLMBuffer *buff ); FORCEINLINE void BindVertexBufferToCtx( CGLMBuffer *buff ); - - GLuint CreateTex( GLenum texBind, GLenum internalFormat ); - void CleanupTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ); - void DestroyTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ); - GLuint FillTexCache( bool holdOne, int newTextures ); - void PurgeTexCache( ); - - // debug font - void GenDebugFontTex( void ); - void DrawDebugText( float x, float y, float z, float drawCharWidth, float drawCharHeight, char *string ); - -#ifndef OSX + CPinnedMemoryBuffer *GetCurPinnedMemoryBuffer( ) { return &m_PinnedMemoryBuffers[m_nCurPinnedMemoryBuffer]; } -#endif - - CPersistentBuffer* GetCurPersistentBuffer( EGLMBufferType type ) { return &( m_persistentBuffer[m_nCurPersistentBuffer][type] ); } - - // members------------------------------------------ + // members------------------------------------------ + // context DWORD m_nCurOwnerThreadId; uint m_nThreadOwnershipReleaseCounter; bool m_bUseSamplerObjects; - bool m_bTexClientStorage; + bool m_bPreferMapBufferRange; IDirect3DDevice9 *m_pDevice; GLMRendererInfoFields m_caps; - + bool m_displayParamsValid; // is there a param block copied in yet GLMDisplayParams m_displayParams; // last known display config, either via constructor, or by SetDisplayParams... -#if defined( USE_SDL ) +#ifdef OSX + CGLPixelFormatAttribute m_pixelFormatAttribs[100]; // more than enough + PseudoNSGLContextPtr m_nsctx; + CGLContextObj m_ctx; +#elif defined( USE_SDL ) int m_pixelFormatAttribs[100]; // more than enough PseudoNSGLContextPtr m_nsctx; void * m_ctx; #endif + bool m_oneCtxEnable; // true if we use the window's context directly instead of making a second one shared against it + bool m_bUseBoneUniformBuffers; // if true, we use two uniform buffers for vertex shader constants vs. one // texture form table @@ -1772,17 +1712,15 @@ class GLMContext CGLMFBO *m_scratchFBO[ kGLMScratchFBOCount ]; // general purpose FBO's for internal use CUtlVector< CGLMFBO* > m_fboTable; // each live FBO goes in the table - - uint m_fragDataMask; // program bindings EGLMProgramLang m_drawingLangAtFrameStart; // selector for start of frame (spills into m_drawingLang) EGLMProgramLang m_drawingLang; // selector for which language we desire to draw with on the next batch CGLMProgram *m_drawingProgram[ kGLMNumProgramTypes ]; bool m_bDirtyPrograms; - + GLMProgramParamsF m_programParamsF[ kGLMNumProgramTypes ]; - GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; + GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used GLMProgramParamsI m_programParamsI[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used EGLMParamWriteMode m_paramWriteMode; @@ -1792,11 +1730,7 @@ class GLMContext CGLMProgram *m_preload2DTexFragmentProgram; CGLMProgram *m_preload3DTexFragmentProgram; CGLMProgram *m_preloadCubeTexFragmentProgram; - -#if defined( OSX ) && defined( GLMDEBUG ) - CGLMProgram *m_boundProgram[ kGLMNumProgramTypes ]; -#endif - + CGLMShaderPairCache *m_pairCache; // GLSL only CGLMShaderPair *m_pBoundPair; // GLSL only @@ -1807,7 +1741,7 @@ class GLMContext // buffer bindings GLuint m_nBoundGLBuffer[kGLMNumBufferTypes]; - + struct VertexAttribs_t { GLuint m_nCompCount; @@ -1839,39 +1773,23 @@ class GLMContext // batch/frame debugging support int m_debugFrameIndex; // init to -1. Increment at BeginFrame - + int m_nMaxUsedVertexProgramConstantsHint; uint32 m_dwRenderThreadId; volatile bool m_bIsThreading; - + uint m_nCurFrame; uint m_nBatchCounter; - struct TextureEntry_t - { - GLenum m_nTexBind; - GLenum m_nInternalFormat; - GLuint m_nTexName; - }; - - GLuint m_destroyPBO; - CUtlVector< TextureEntry_t > m_availableTextures; - -#ifndef OSX enum { cNumPinnedMemoryBuffers = 4 }; CPinnedMemoryBuffer m_PinnedMemoryBuffers[cNumPinnedMemoryBuffers]; uint m_nCurPinnedMemoryBuffer; -#endif - - enum { cNumPersistentBuffers = 3 }; - CPersistentBuffer m_persistentBuffer[cNumPersistentBuffers][kGLMNumBufferTypes]; - uint m_nCurPersistentBuffer; - + void SaveColorMaskAndSetToDefault(); void RestoreSavedColorMask(); GLColorMaskSingle_t m_SavedColorMask; - + #if GLMDEBUG // interactive (DebugHook) debug support @@ -1907,8 +1825,6 @@ class GLMContext #endif }; -#ifndef OSX - FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf ) { #if GL_ENABLE_INDEX_VERIFICATION @@ -1920,25 +1836,20 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin #else //tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s %d-%d count:%d mode:%d type:%d", __FUNCTION__, start, end, count, mode, type ); #endif - + ++m_nBatchCounter; SetIndexBuffer( pIndexBuf ); void *indicesActual = (void*)indices; - + if ( pIndexBuf->m_bPseudo ) { // you have to pass actual address, not offset indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf ); } - if (pIndexBuf->m_bUsingPersistentBuffer) - { - indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset ); - } -//#if GLMDEBUG -#if 0 +#if GLMDEBUG bool hasVP = m_drawingProgram[ kGLMVertexProgram ] != NULL; bool hasFP = m_drawingProgram[ kGLMFragmentProgram ] != NULL; @@ -2020,8 +1931,6 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin #endif // GL_ENABLE_INDEX_VERIFICATION } -#endif // #ifndef OSX - FORCEINLINE void GLMContext::SetVertexProgram( CGLMProgram *pProg ) { m_drawingProgram[kGLMVertexProgram] = pProg; @@ -2060,53 +1969,23 @@ FORCEINLINE void GLMContext::SetProgramParametersF( EGLMProgramType type, uint b if ( ( type == kGLMVertexProgram ) && ( m_bUseBoneUniformBuffers ) ) { - // changes here to handle vertex shaders which use constants before and after the bone array i.e. before c58 and after c216 - // a better change may be to modify the shaders and place the bone consts at either start or end - would simplify this and the flush code - // the current supporting code (shader translator(dx9asmtogl2), param setting(here) and flushing(glmgr_flush.inl) should work unchanged, even if the const mapping is changed. - int firstDirty = (int)baseSlot; - int highWater = (int)(baseSlot + slotCount); - - if ( highWater <= DXABSTRACT_VS_FIRST_BONE_SLOT ) - { - m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty ); - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater ); - } - else if ( highWater <= (DXABSTRACT_VS_LAST_BONE_SLOT+1) ) + if ( ( baseSlot + slotCount ) > DXABSTRACT_VS_FIRST_BONE_SLOT ) { - if ( firstDirty < DXABSTRACT_VS_FIRST_BONE_SLOT ) + if ( baseSlot < DXABSTRACT_VS_FIRST_BONE_SLOT ) { - m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty ); - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, MIN( DXABSTRACT_VS_FIRST_BONE_SLOT, highWater ) ); - firstDirty = DXABSTRACT_VS_FIRST_BONE_SLOT; + // The register set crosses between the constant buffers - should only happen at startup during init. + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, (int)baseSlot ); + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, (int)MIN( baseSlot + slotCount, DXABSTRACT_VS_FIRST_BONE_SLOT ) ); + baseSlot = DXABSTRACT_VS_FIRST_BONE_SLOT; } - int nNumActualBones = ( firstDirty + slotCount ) - DXABSTRACT_VS_FIRST_BONE_SLOT; + int nNumActualBones = ( baseSlot + slotCount ) - DXABSTRACT_VS_FIRST_BONE_SLOT; m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone, nNumActualBones ); } else { - const int maxBoneSlots = ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; - - if ( firstDirty > DXABSTRACT_VS_LAST_BONE_SLOT ) - { - m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty - maxBoneSlots ); - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); - } - else if ( firstDirty >= DXABSTRACT_VS_FIRST_BONE_SLOT ) - { - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = DXABSTRACT_VS_LAST_BONE_SLOT + 1; - - m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, DXABSTRACT_VS_FIRST_BONE_SLOT ); - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); - } - else - { - int nNumActualBones = ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone, nNumActualBones ); - - m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty ); - m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); - } + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, (int)baseSlot ); + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, (int)(baseSlot + slotCount) ); } } else @@ -2123,7 +2002,7 @@ FORCEINLINE void GLMContext::SetProgramParametersB( EGLMProgramType type, uint b #endif Assert( m_drawingLang == kGLMGLSL ); - Assert( type==kGLMVertexProgram || type==kGLMFragmentProgram ); + Assert( type==kGLMVertexProgram ); Assert( baseSlot < kGLMProgramParamBoolLimit ); Assert( baseSlot+boolCount <= kGLMProgramParamBoolLimit ); @@ -2190,21 +2069,21 @@ FORCEINLINE void GLMContext::SetSamplerTex( int sampler, CGLMTex *tex ) m_samplers[sampler].m_pBoundTex = tex; if ( tex ) { - if ( !gGL->m_bHave_GL_EXT_direct_state_access ) - { - if ( sampler != m_activeTexture ) - { - gGL->glActiveTexture( GL_TEXTURE0 + sampler ); - m_activeTexture = sampler; - } - - gGL->glBindTexture( tex->m_texGLTarget, tex->m_texName ); - } - else + if ( !gGL->m_bHave_GL_EXT_direct_state_access ) + { + if ( sampler != m_activeTexture ) { - gGL->glBindMultiTextureEXT( GL_TEXTURE0 + sampler, tex->m_texGLTarget, tex->m_texName ); + gGL->glActiveTexture( GL_TEXTURE0 + sampler ); + m_activeTexture = sampler; } + + gGL->glBindTexture( tex->m_texGLTarget, tex->m_texName ); + } + else + { + gGL->glBindMultiTextureEXT( GL_TEXTURE0 + sampler, tex->m_texGLTarget, tex->m_texName ); } + } if ( !m_bUseSamplerObjects ) { @@ -2305,8 +2184,8 @@ FORCEINLINE void GLMContext::BindIndexBufferToCtx( CGLMBuffer *buff ) GLMPRINTF(( "--- GLMContext::BindIndexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 )); Assert( !buff || ( buff->m_buffGLTarget == GL_ELEMENT_ARRAY_BUFFER_ARB ) ); - - GLuint nGLName = buff ? buff->GetHandle() : 0; + + GLuint nGLName = buff ? buff->m_nHandle : 0; if ( m_nBoundGLBuffer[ kGLMIndexBuffer] == nGLName ) return; @@ -2320,8 +2199,8 @@ FORCEINLINE void GLMContext::BindVertexBufferToCtx( CGLMBuffer *buff ) GLMPRINTF(( "--- GLMContext::BindVertexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 )); Assert( !buff || ( buff->m_buffGLTarget == GL_ARRAY_BUFFER_ARB ) ); - - GLuint nGLName = buff ? buff->GetHandle() : 0; + + GLuint nGLName = buff ? buff->m_nHandle : 0; if ( m_nBoundGLBuffer[ kGLMVertexBuffer] == nGLName ) return; @@ -2353,45 +2232,6 @@ struct GLMTestParams int m_frameCount; // how many frames to test. }; -class GLMTester -{ - public: - - GLMTester(GLMTestParams *params); - ~GLMTester(); - - - // optionally callable by test routines to get basic drawables wired up - void StdSetup( void ); - void StdCleanup( void ); - - // callable by test routines to clear the frame or present it - void Clear( void ); - void Present( int seed ); - - // error reporting - void CheckGLError( const char *comment ); // obey m_params setting for console / debugger response - void InternalError( int errcode, char *comment ); // if errcode!=0, obey m_params setting for console / debugger response - - void RunTests(); - - void RunOneTest( int testindex ); - - // test routines themselves - void Test0(); - void Test1(); - void Test2(); - void Test3(); - - GLMTestParams m_params; // copy of caller's params, do not mutate... - - // std-setup stuff - int m_drawWidth, m_drawHeight; - CGLMFBO *m_drawFBO; - CGLMTex *m_drawColorTex; - CGLMTex *m_drawDepthTex; -}; - class CShowPixelsParams { public: diff --git a/public/togl/linuxwin/glmgrbasics.h b/public/togl/linuxwin/glmgrbasics.h index a32938ad..ed380de4 100644 --- a/public/togl/linuxwin/glmgrbasics.h +++ b/public/togl/linuxwin/glmgrbasics.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // glmgrbasics.h // types, common headers, forward declarations, utilities @@ -32,20 +10,20 @@ #pragma once -#ifdef USE_SDL -#include "SDL_opengl.h" -#endif - #ifdef OSX + #include + #include + #include #include #include #include - #include - -#ifndef MAC_OS_X_VERSION_10_9 #include #include -#endif +#elif defined(DX_TO_GL_ABSTRACTION) + #include + #include +#else + #error #endif #include "tier0/platform.h" @@ -323,10 +301,8 @@ class CGLMTextSectioner CUtlVector< GLMTextSection > m_sectionTable; }; -#ifndef OSX void GLMGPUTimestampManagerInit(); void GLMGPUTimestampManagerDeinit(); void GLMGPUTimestampManagerTick(); -#endif #endif // GLMBASICS_H diff --git a/public/togl/linuxwin/glmgrext.h b/public/togl/linuxwin/glmgrext.h index 393942a7..8f1aba94 100644 --- a/public/togl/linuxwin/glmgrext.h +++ b/public/togl/linuxwin/glmgrext.h @@ -1,26 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. // // glmgrext.h // helper file for extension testing and runtime importing of entry points @@ -113,11 +91,3 @@ #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #endif -#ifndef GL_MAP_PERSISTENT_BIT -#define GL_MAP_PERSISTENT_BIT 0x0040 -#endif - -#ifndef GL_MAP_COHERENT_BIT -#define GL_MAP_COHERENT_BIT 0x0080 -#endif - diff --git a/public/togl/osx/cglmbuffer.h b/public/togl/osx/cglmbuffer.h new file mode 100644 index 00000000..0b161000 --- /dev/null +++ b/public/togl/osx/cglmbuffer.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// cglmprogram.h +// GLMgr buffers (index / vertex) +// ... maybe add PBO later as well +//=============================================================================== + +#ifndef CGLMBUFFER_H +#define CGLMBUFFER_H + +#pragma once + +// ext links + +// http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt + +//=============================================================================== + +// tokens not in the SDK headers + +//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT +// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 +//#endif + +//=============================================================================== + +// forward declarations + +class GLMContext; + +enum EGLMBufferType +{ + kGLMVertexBuffer, + kGLMIndexBuffer, + kGLMUniformBuffer, // for bindable uniform + kGLMPixelBuffer, // for PBO + + kGLMNumBufferTypes +}; + + // pass this in "options" to constructor to make a dynamic buffer +#define GLMBufferOptionDynamic 0x00000001 + +struct GLMBuffLockParams +{ + uint m_offset; + uint m_size; + bool m_nonblocking; + bool m_discard; +}; + +class CGLMBuffer +{ + +public: + void Lock( GLMBuffLockParams *params, char **addressOut ); + void Unlock( void ); + +//protected: + friend class GLMContext; // only GLMContext can make CGLMBuffer objects + friend class GLMTester; + friend class IDirect3D9; + friend class IDirect3DDevice9; + + CGLMBuffer ( GLMContext *ctx, EGLMBufferType type, uint size, uint options ); + ~CGLMBuffer ( ); + + void SetModes ( bool asyncMap, bool explicitFlush, bool force = false ); + void FlushRange ( uint offset, uint size ); + + GLMContext *m_ctx; // link back to parent context + EGLMBufferType m_type; + uint m_size; + GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB + GLuint m_name; // name of this program in the context + uint m_revision; // bump anytime the size changes or buffer is orphaned + bool m_enableAsyncMap; // mirror of the buffer state + bool m_enableExplicitFlush; // mirror of the buffer state + + bool m_bound; // true if bound to context + bool m_mapped; // is it currently mapped + uint m_dirtyMinOffset; // when equal, range is empty + uint m_dirtyMaxOffset; + + float *m_lastMappedAddress; + + // --------------------- pseudo-VBO support below here (explicitly for dynamic index buffers) + bool m_pseudo; // true if the m_name is 0, and the backing is plain RAM + + // in pseudo mode, there is just one RAM buffer that acts as the backing. + // expectation is that this mode would only be used for dynamic indices. + // since indices have to be consumed (copied to command stream) prior to return from a drawing call, + // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op. + + char *m_pseudoBuf; // storage for pseudo buffer +}; + + +#endif \ No newline at end of file diff --git a/public/togl/osx/cglmfbo.h b/public/togl/osx/cglmfbo.h new file mode 100644 index 00000000..ccf3e970 --- /dev/null +++ b/public/togl/osx/cglmfbo.h @@ -0,0 +1,91 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// cglmfbo.h +// GLMgr FBO's (render targets) +// +//=============================================================================== + +#ifndef CGLMFBO_H +#define CGLMFBO_H + +#pragma once + +#include "togl/rendermechanism.h" + +// good FBO references / recaps +// http://www.songho.ca/opengl/gl_fbo.html +// http://www.gamedev.net/reference/articles/article2331.asp + +// ext links + +// http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt +// http://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt + +//=============================================================================== + +// tokens not in the SDK headers + +#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT + #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 +#endif + +//=============================================================================== + +// forward declarations + +class GLMContext; + +// implicitly 16 maximum color attachments possible +enum EGLMFBOAttachment { + kAttColor0, kAttColor1, kAttColor2, kAttColor3, + kAttColor4, kAttColor5, kAttColor6, kAttColor7, + kAttColor8, kAttColor9, kAttColor10, kAttColor11, + kAttColor12, kAttColor13, kAttColor14, kAttColor15, + kAttDepth, kAttStencil, kAttDepthStencil, + kAttCount +}; + +struct GLMFBOTexAttachParams +{ + CGLMTex *m_tex; + int m_face; // keep zero if not cube map + int m_mip; // keep zero if notmip mapped + int m_zslice; // keep zero if not a 3D tex +}; + +class CGLMFBO +{ + +public: + +protected: + friend class GLMContext; // only GLMContext can make CGLMFBO objects + friend class GLMTester; + friend class CGLMTex; + + friend class IDirect3D9; + friend class IDirect3DDevice9; + + CGLMFBO( GLMContext *ctx ); + ~CGLMFBO( ); + + void TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT ); + void TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT ); + // you can also pass GL_READ_FRAMEBUFFER_EXT or GL_DRAW_FRAMEBUFFER_EXT to selectively bind the receiving FBO to one or the other. + + void TexScrub( CGLMTex *tex ); + // search and destroy any attachment for the named texture + + bool IsReady( void ); // aka FBO completeness check - ready to draw + + GLMContext *m_ctx; // link back to parent context + + GLuint m_name; // name of this FBO in the context + + GLMFBOTexAttachParams m_attach[ kAttCount ]; // indexed by EGLMFBOAttachment + + int m_sizeX,m_sizeY; +}; + + +#endif diff --git a/public/togl/osx/cglmprogram.h b/public/togl/osx/cglmprogram.h new file mode 100644 index 00000000..ee7f4de2 --- /dev/null +++ b/public/togl/osx/cglmprogram.h @@ -0,0 +1,291 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// cglmprogram.h +// GLMgr programs (ARBVP/ARBfp) +// +//=============================================================================== + +#ifndef CGLMPROGRAM_H +#define CGLMPROGRAM_H + +#include + +#pragma once + +// good ARB program references +// http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html +// http://petewarden.com/notes/archives/2005/06/fragment_progra_3.html + +// ext links + +// http://www.opengl.org/registry/specs/ARB/vertex_program.txt +// http://www.opengl.org/registry/specs/ARB/fragment_program.txt +// http://www.opengl.org/registry/specs/EXT/gpu_program_parameters.txt + + +//=============================================================================== + +// tokens not in the SDK headers + +//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT +// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 +//#endif + +//=============================================================================== + +// forward declarations + +class GLMContext; +class CGLMShaderPair; +class CGLMShaderPairCache; + +// CGLMProgram can contain two flavors of the same program, one in assembler, one in GLSL. +// these flavors are pretty different in terms of the API's that are used to activate them - +// for example, assembler programs can just get bound to the context, whereas GLSL programs +// have to be linked. To some extent we try to hide that detail inside GLM. + +// for now, make CGLMProgram a container, it does not set policy or hold a preference as to which +// flavor you want to use. GLMContext has to handle that. + +enum EGLMProgramType +{ + kGLMVertexProgram, + kGLMFragmentProgram, + + kGLMNumProgramTypes +}; + +enum EGLMProgramLang +{ + kGLMARB, + kGLMGLSL, + + kGLMNumProgramLangs +}; + +struct GLMShaderDesc +{ + union + { + GLuint arb; // ARB program object name + GLhandleARB glsl; // GLSL shader object handle (void*) + } m_object; + + // these can change if shader text is edited + bool m_textPresent; // is this flavor(lang) of text present in the buffer? + int m_textOffset; // where is it + int m_textLength; // how big + + bool m_compiled; // has this text been through a compile attempt + bool m_valid; // and if so, was the compile successful + + int m_slowMark; // has it been flagged during a non native draw batch before. increment every time it's slow. + + int m_highWater; // vount of vec4's in the major uniform array ("vc" on vs, "pc" on ps) + // written by dxabstract.... gross! +}; + +GLenum GLMProgTypeToARBEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target +GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target + +class CGLMProgram +{ +public: + friend class CGLMShaderPairCache; + friend class CGLMShaderPair; + friend class GLMContext; // only GLMContext can make CGLMProgram objects + friend class GLMTester; + friend class IDirect3D9; + friend class IDirect3DDevice9; + + //=============================== + + // constructor is very light, it just makes one empty program object per flavor. + CGLMProgram( GLMContext *ctx, EGLMProgramType type ); + ~CGLMProgram( ); + + void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program + + bool CompileActiveSources ( void ); // compile only the flavors that were provided. + bool Compile ( EGLMProgramLang lang ); + bool CheckValidity ( EGLMProgramLang lang ); + + void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that + + void GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut ); + void GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ); // mmmmmmmm-nnnnnnnn-filename + +#if GLMDEBUG + bool PollForChanges( void ); // check mirror for changes. + void ReloadStringFromEditable( void ); // populate m_string from editable item (react to change) + bool SyncWithEditable( void ); +#endif + + //=============================== + + // common stuff + + GLMContext *m_ctx; // link back to parent context + + EGLMProgramType m_type; // vertex or pixel + + uint m_serial; // serial number for hashing + + char *m_text; // copy of text passed into constructor. Can change if editable shaders is enabled. + // note - it can contain multiple flavors, so use CGLMTextSectioner to scan it and locate them +#if GLMDEBUG + CGLMEditableTextItem *m_editable; // editable text item for debugging +#endif + + GLMShaderDesc m_descs[ kGLMNumProgramLangs ]; + + uint m_samplerMask; // (1< m_layoutMap; +}; + +//=============================================================================== + +// a sampler specifies desired state for drawing on a given sampler index +// this is the combination of a texture choice and a set of sampler parameters +// see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx + + +struct GLMTexSamplingParams +{ + GLenum m_addressModes[3]; // S, T, R + GLfloat m_borderColor[4]; // R,G,B,A + + GLenum m_magFilter; + GLenum m_minFilter; + + GLfloat m_mipmapBias; + GLint m_minMipLevel; + GLint m_maxMipLevel; + GLint m_maxAniso; + GLenum m_compareMode; // only used for depth and stencil type textures + bool m_srgb; // srgb texture read... +}; + +struct GLMTexLockParams +{ + // input params which identify the slice of interest + CGLMTex *m_tex; + int m_face; + int m_mip; + + // identifies the region of the slice + GLMRegion m_region; + + // tells GLM to force re-read of the texels back from GL + // i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale" + bool m_readback; +}; + +struct GLMTexLockDesc +{ + GLMTexLockParams m_req; // form of the lock request + + bool m_active; // set true at lock time. cleared at unlock time. + + int m_sliceIndex; // which slice in the layout + int m_sliceBaseOffset; // where is that in the texture data + int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested +}; + +//=============================================================================== + +#define GLM_SAMPLER_COUNT 16 + +typedef CBitVec CTexBindMask; + +enum EGLMTexSliceFlag +{ + kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially + kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially + kSliceLocked = 0x04, // are one or more locks outstanding on this slice + kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects) +}; + +class CGLMTex +{ + +public: + + void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut ); + void Unlock( GLMTexLockParams *params ); + +protected: + friend class GLMContext; // only GLMContext can make CGLMTex objects + friend class GLMTester; + friend class CGLMFBO; + + friend class IDirect3DDevice9; + friend class IDirect3DBaseTexture9; + friend class IDirect3DTexture9; + friend class IDirect3DSurface9; + friend class IDirect3DCubeTexture9; + friend class IDirect3DVolumeTexture9; + + CGLMTex( GLMContext *ctx, GLMTexLayout *layout, GLMTexSamplingParams *sampling, char *debugLabel = NULL ); + ~CGLMTex( ); + + int CalcSliceIndex( int face, int mip ); + void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut ); + + void ApplySamplingParams( GLMTexSamplingParams *params, bool noCheck=FALSE ); + + void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true ); + void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false ); + // last param lets us send NULL data ptr (only legal with uncompressed formats, beware) + // this helps out ResetSRGB. + + void ResetSRGB( bool srgb, bool noDataWrite ); + // re-specify texture format to match desired sRGB form + // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's + + GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout) + int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. + int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. + + GLMTexSamplingParams m_sampling; // mirror of sampling params currently embodied in the texture + // (consult this at draw time, in order to know if changes need to be made) + + GLMContext *m_ctx; // link back to parent context + + GLuint m_texName; // name of this texture in the context + bool m_texClientStorage; // was CS selecetd for texture + bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet + + GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero) + bool m_rboDirty; // has RBO been drawn on - i.e. needs to be blitted back to texture if texture is going to be sampled from + + CTexBindMask m_bindPoints; // true for each place in the parent ctx where currently + // bound (indexed via EGLMTexCtxBindingIndex) + + int m_rtAttachCount; // how many RT's have this texture attached somewhere + + char *m_backing; // backing storage if available + + int m_lockCount; // lock reqs are stored in the GLMContext for tracking + + CUtlVector m_sliceFlags; + + char *m_debugLabel; // strdup() of debugLabel passed in, or NULL +}; + + +#endif diff --git a/public/togl/osx/dxabstract.h b/public/togl/osx/dxabstract.h new file mode 100644 index 00000000..92f6bc32 --- /dev/null +++ b/public/togl/osx/dxabstract.h @@ -0,0 +1,804 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// +// +//================================================================================================== + +#ifndef DXABSTRACT_H +#define DXABSTRACT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "togl/rendermechanism.h" + +#include "materialsystem/ishader.h" + +// Uncomment this on Windows if you want to compile the Windows GL version. +// #undef USE_ACTUAL_DX + +#ifdef USE_ACTUAL_DX + +#ifndef WIN32 +#error sorry man +#endif +#ifdef _X360 +#include "d3d9.h" +#include "d3dx9.h" +#else +#include +#include "../../dx9sdk/include/d3d9.h" +#include "../../dx9sdk/include/d3dx9.h" +#endif +typedef HWND VD3DHWND; + +#else + +#ifdef WIN32 +#error Gl on win32? +#endif + +#include "tier0/platform.h" + +#ifndef DX_TO_GL_ABSTRACTION +#define DX_TO_GL_ABSTRACTION +#endif + +#include "bitmap/imageformat.h" +#include "togl/rendermechanism.h" + +#ifdef OSX +extern "C" void Debugger(void); +#endif + +// turn this on to get refcount logging from IUnknown +#define IUNKNOWN_ALLOC_SPEW 0 +#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0 + + +// ------------------------------------------------------------------------------------------------------------------------------ // +// DEFINES +// ------------------------------------------------------------------------------------------------------------------------------ // + +typedef void* VD3DHWND; +typedef void* VD3DHANDLE; + + +TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect ); + +struct TOGL_CLASS IUnknown +{ + int m_refcount[2]; + bool m_mark; + + IUnknown( void ) + { + m_refcount[0] = 1; + m_refcount[1] = 0; + m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1])); + } + #endif + }; + + virtual ~IUnknown( void ) + { + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUdel (%08x) ",this )); + } + #endif + }; + + void AddRef( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + m_refcount[which]++; + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ; + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + }; + + ULONG __stdcall Release( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + + //int oldrefcs[2] = { m_refcount[0], m_refcount[1] }; + bool deleting = false; + + m_refcount[which]--; + if ( (!m_refcount[0]) && (!m_refcount[1]) ) + { + deleting = true; + } + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":"")); + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + + if (deleting) + { + if (m_mark) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + delete this; + return 0; + } + else + { + return m_refcount[0]; + } + }; + + void SetMark( bool markValue, char *comment=NULL ) + { + #if IUNKNOWN_ALLOC_SPEW + if (!m_mark && markValue) // leading edge detect + { + // print the same thing that the constructor would have printed if it had been marked from the beginning + // i.e. it's anticipated that callers asking for marking will do so right at create time + GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"...")); + } + #endif + + m_mark = markValue; + } +}; + + +// ------------------------------------------------------------------------------------------------------------------------------ // +// INTERFACES +// ------------------------------------------------------------------------------------------------------------------------------ // + +struct TOGL_CLASS IDirect3DResource9 : public IUnknown +{ + IDirect3DDevice9 *m_device; // parent device + D3DRESOURCETYPE m_restype; + + DWORD SetPriority(DWORD PriorityNew); +}; + +struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.." +{ + D3DSURFACE_DESC m_descZero; // desc of top level. + CGLMTex *m_tex; // a CGLMTex can represent all forms of tex + int m_srgbFlipCount; + + virtual ~IDirect3DBaseTexture9(); + D3DRESOURCETYPE GetType(); + DWORD GetLevelCount(); + HRESULT GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + + virtual ~IDirect3DTexture9(); + + HRESULT LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT UnlockRect(UINT Level); + HRESULT GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel); +}; + +struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map" +{ + IDirect3DSurface9 *m_surfZero[6]; // surfs of top level. + + virtual ~IDirect3DCubeTexture9(); + + HRESULT GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface); + HRESULT GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + D3DVOLUME_DESC m_volDescZero; // volume desc top level + + virtual ~IDirect3DVolumeTexture9(); + + HRESULT LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags); + HRESULT UnlockBox(UINT Level); + HRESULT GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc ); +}; + + +// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip. +// no Create method, these are filled in by the various create surface methods. + +struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9 +{ + virtual ~IDirect3DSurface9(); + + HRESULT LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT UnlockRect(); + HRESULT GetDesc(D3DSURFACE_DESC *pDesc); + + D3DSURFACE_DESC m_desc; + CGLMTex *m_tex; + int m_face; + int m_mip; +}; + + + +struct TOGL_CLASS IDirect3D9 : public IUnknown +{ +public: + virtual ~IDirect3D9(); + + UINT GetAdapterCount(); //cheese: returns 1 + + HRESULT GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps); + HRESULT GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier); + HRESULT CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat); + UINT GetAdapterModeCount (UINT Adapter,D3DFORMAT Format); + HRESULT EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode); + HRESULT CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed); + HRESULT GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode); + HRESULT CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat); + HRESULT CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels); + + HRESULT CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface); +}; + +struct TOGL_CLASS IDirect3DSwapChain9 : public IUnknown +{ +}; + + + + // typedef enum D3DDECLUSAGE + // { + // D3DDECLUSAGE_POSITION = 0, + // D3DDECLUSAGE_BLENDWEIGHT = 1, + // D3DDECLUSAGE_BLENDINDICES = 2, + // D3DDECLUSAGE_NORMAL = 3, + // D3DDECLUSAGE_PSIZE = 4, + // D3DDECLUSAGE_TEXCOORD = 5, + // D3DDECLUSAGE_TANGENT = 6, + // D3DDECLUSAGE_BINORMAL = 7, + // D3DDECLUSAGE_TESSFACTOR = 8, + // D3DDECLUSAGE_POSITIONT = 9, + // D3DDECLUSAGE_COLOR = 10, + // D3DDECLUSAGE_FOG = 11, + // D3DDECLUSAGE_DEPTH = 12, + // D3DDECLUSAGE_SAMPLE = 13, + // } D3DDECLUSAGE, *LPD3DDECLUSAGE; + // Constants + // + // D3DDECLUSAGE_POSITION + // Position data ranging from (-1,-1) to (1,1). Use D3DDECLUSAGE_POSITION with + // a usage index of 0 to specify untransformed position for fixed function + // vertex processing and the n-patch tessellator. Use D3DDECLUSAGE_POSITION + // with a usage index of 1 to specify untransformed position in the fixed + // function vertex shader for vertex tweening. + // + // D3DDECLUSAGE_BLENDWEIGHT + // Blending weight data. Use D3DDECLUSAGE_BLENDWEIGHT with a usage index of 0 + // to specify the blend weights used in indexed and nonindexed vertex + // blending. + // + // D3DDECLUSAGE_BLENDINDICES + // Blending indices data. Use D3DDECLUSAGE_BLENDINDICES with a usage index of + // 0 to specify matrix indices for indexed paletted skinning. + // + // D3DDECLUSAGE_NORMAL + // Vertex normal data. Use D3DDECLUSAGE_NORMAL with a usage index of 0 to + // specify vertex normals for fixed function vertex processing and the n-patch + // tessellator. Use D3DDECLUSAGE_NORMAL with a usage index of 1 to specify + // vertex normals for fixed function vertex processing for vertex tweening. + // + // D3DDECLUSAGE_PSIZE + // Point size data. Use D3DDECLUSAGE_PSIZE with a usage index of 0 to specify + // the point-size attribute used by the setup engine of the rasterizer to + // expand a point into a quad for the point-sprite functionality. + // + // D3DDECLUSAGE_TEXCOORD + // Texture coordinate data. Use D3DDECLUSAGE_TEXCOORD, n to specify texture + // coordinates in fixed function vertex processing and in pixel shaders prior + // to ps_3_0. These can be used to pass user defined data. + // + // D3DDECLUSAGE_TANGENT + // Vertex tangent data. + // + // D3DDECLUSAGE_BINORMAL + // Vertex binormal data. + // + // D3DDECLUSAGE_TESSFACTOR + // Single positive floating point value. Use D3DDECLUSAGE_TESSFACTOR with a + // usage index of 0 to specify a tessellation factor used in the tessellation + // unit to control the rate of tessellation. For more information about the + // data type, see D3DDECLTYPE_FLOAT1. + // + // D3DDECLUSAGE_POSITIONT + // Vertex data contains transformed position data ranging from (0,0) to + // (viewport width, viewport height). Use D3DDECLUSAGE_POSITIONT with a usage + // index of 0 to specify transformed position. When a declaration containing + // this is set, the pipeline does not perform vertex processing. + // + // D3DDECLUSAGE_COLOR + // Vertex data contains diffuse or specular color. Use D3DDECLUSAGE_COLOR with + // a usage index of 0 to specify the diffuse color in the fixed function + // vertex shader and pixel shaders prior to ps_3_0. Use D3DDECLUSAGE_COLOR + // with a usage index of 1 to specify the specular color in the fixed function + // vertex shader and pixel shaders prior to ps_3_0. + // + // D3DDECLUSAGE_FOG + // Vertex data contains fog data. Use D3DDECLUSAGE_FOG with a usage index of 0 + // to specify a fog blend value used after pixel shading finishes. This + // applies to pixel shaders prior to version ps_3_0. + // + // D3DDECLUSAGE_DEPTH + // Vertex data contains depth data. + // + // D3DDECLUSAGE_SAMPLE + // Vertex data contains sampler data. Use D3DDECLUSAGE_SAMPLE with a usage + // index of 0 to specify the displacement value to look up. It can be used + // only with D3DDECLUSAGE_LOOKUPPRESAMPLED or D3DDECLUSAGE_LOOKUP. + + //note the form of the list terminator.. + + // #define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} + // typedef struct _D3DVERTEXELEMENT9 + // { + // WORD Stream; // Stream index + // WORD Offset; // Offset in the stream in bytes + // BYTE Type; // Data type + // BYTE Method; // Processing method + // BYTE Usage; // Semantics + // BYTE UsageIndex; // Semantic index + // } D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; + +#define MAX_D3DVERTEXELEMENTS 16 + +struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown +{ +//public: + uint m_elemCount; + D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ]; + + virtual ~IDirect3DVertexDeclaration9(); +}; + +struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown +{ +//public: + D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT + GLMContext *m_ctx; + CGLMQuery *m_query; + + virtual ~IDirect3DQuery9(); + + HRESULT Issue(DWORD dwIssueFlags); + HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags); +}; + +struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown +{ +//public: + GLMContext *m_ctx; + CGLMBuffer *m_vtxBuffer; + D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc + + virtual ~IDirect3DVertexBuffer9(); + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + HRESULT UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); + +}; + +struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown +{ +//public: + GLMContext *m_ctx; + CGLMBuffer *m_idxBuffer; + D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc + + virtual ~IDirect3DIndexBuffer9(); + + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + HRESULT UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); + HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown +{ +//public: + CGLMProgram *m_pixProgram; + uint m_pixHighWater; // count of active constant slots referenced by shader. + uint m_pixSamplerMask; // (1< m_stack; + int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases. + + HRESULT Create( void ); + + D3DXMATRIX* GetTop(); + void Push(); + void Pop(); + void LoadIdentity(); + void LoadMatrix( const D3DXMATRIX *pMat ); + void MultMatrix( const D3DXMATRIX *pMat ); + void MultMatrixLocal( const D3DXMATRIX *pMat ); + HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z); + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle); + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z); +}; +typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK; + +struct TOGL_CLASS IDirect3DDevice9 : public IUnknown +{ +public: + // members + + IDirect3DDevice9Params m_params; // mirror of the creation inputs + + // D3D flavor stuff + IDirect3DSurface9 *m_rtSurfaces[16]; // current color RT surfaces. [0] is initially == m_defaultColorSurface + IDirect3DSurface9 *m_dsSurface; // current DS RT surface. can be changed! + + IDirect3DSurface9 *m_defaultColorSurface; // default color surface. + IDirect3DSurface9 *m_defaultDepthStencilSurface; // queried by GetDepthStencilSurface. + + IDirect3DVertexDeclaration9 *m_vertDecl; // Set by SetVertexDeclaration... + D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource.. + D3DIndexDesc m_indices; // Set by SetIndices.. + + IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader... + IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader... + + IDirect3DBaseTexture9 *m_textures[16]; // set by SetTexture... NULL if stage inactive + D3DSamplerDesc m_samplers[16]; // set by SetSamplerState.. + // GLM flavor stuff + GLMContext *m_ctx; + CGLMFBO *m_drawableFBO; // this FBO should have all the attachments set to match m_rtSurfaces and m_dsSurface. + + // GL state + struct + { + // render state buckets + GLAlphaTestEnable_t m_AlphaTestEnable; + GLAlphaTestFunc_t m_AlphaTestFunc; + + GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable; + + GLDepthTestEnable_t m_DepthTestEnable; + GLDepthMask_t m_DepthMask; + GLDepthFunc_t m_DepthFunc; + + GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes]; + GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes]; + + GLColorMaskSingle_t m_ColorMaskSingle; + GLColorMaskMultiple_t m_ColorMaskMultiple; + + GLCullFaceEnable_t m_CullFaceEnable; + GLCullFrontFace_t m_CullFrontFace; + GLPolygonMode_t m_PolygonMode; + GLDepthBias_t m_DepthBias; + GLScissorEnable_t m_ScissorEnable; + GLScissorBox_t m_ScissorBox; + GLViewportBox_t m_ViewportBox; + GLViewportDepthRange_t m_ViewportDepthRange; + + GLBlendEnable_t m_BlendEnable; + GLBlendFactor_t m_BlendFactor; + GLBlendEquation_t m_BlendEquation; + GLBlendColor_t m_BlendColor; + GLBlendEnableSRGB_t m_BlendEnableSRGB; + + GLStencilTestEnable_t m_StencilTestEnable; + GLStencilFunc_t m_StencilFunc; + GLStencilOp_t m_StencilOp; + GLStencilWriteMask_t m_StencilWriteMask; + + GLClearColor_t m_ClearColor; + GLClearDepth_t m_ClearDepth; + GLClearStencil_t m_ClearStencil; + + bool m_FogEnable; // not really pushed to GL, just latched here + + // samplers + GLMTexSamplingParams m_samplers[ 16 ]; + + // bindings...hmmm... + + // dirty-bits + uint m_stateDirtyMask; // covers the state blocks, indexed by 1<m_nCurOwnerThreadId; } + +}; + +struct ID3DXInclude +{ + virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) = 0; + virtual HRESULT Close(LPCVOID pData) = 0; +}; +typedef ID3DXInclude* LPD3DXINCLUDE; + + +struct TOGL_CLASS ID3DXBuffer : public IUnknown +{ + void* GetBufferPointer(); + DWORD GetBufferSize(); +}; + +typedef ID3DXBuffer* LPD3DXBUFFER; + +class TOGL_CLASS ID3DXConstantTable : public IUnknown +{ +}; +typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE; + + + +// ------------------------------------------------------------------------------------------------------------------------------ // +// D3DX stuff. +// ------------------------------------------------------------------------------------------------------------------------------ // + +TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice ); + + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); +TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack); +TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * ); + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build an ortho projection matrix. (right-handed) +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf ); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion); + +TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions ); + +TOGL_INTERFACE HRESULT D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + +#endif // USE_ACTUAL_DX + +// fake D3D usage constant for SRGB tex creation +#define D3DUSAGE_TEXTURE_SRGB (0x80000000L) + +#endif // DXABSTRACT_H diff --git a/public/togl/osx/dxabstract_types.h b/public/togl/osx/dxabstract_types.h new file mode 100644 index 00000000..6ecc82f0 --- /dev/null +++ b/public/togl/osx/dxabstract_types.h @@ -0,0 +1,1710 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// dxabstract_types.h +// +//================================================================================================== +#ifndef DXABSTRACT_TYPES_H +#define DXABSTRACT_TYPES_H + +#pragma once + +#if GL_BATCH_PERF_ANALYSIS + class simple_bitmap; +#endif + +struct IUnknown; +struct IDirect3D9; +struct IDirect3DDevice9; +struct IDirect3DResource9; +struct IDirect3DBaseTexture9; +struct IDirect3DTexture9; +struct IDirect3DCubeTexture9; +struct IDirect3DVolumeTexture9; +struct IDirect3DSurface9; +struct IDirect3DVertexDeclaration9; +struct IDirect3DQuery9; +struct IDirect3DVertexBuffer9; +struct IDirect3DIndexBuffer9; +struct IDirect3DPixelShader9; +struct IDirect3DVertexShader9; +struct IDirect3DDevice9Params; + +class GLMContext; +struct GLMRect; +struct GLMShaderPairInfo; +class CGLMBuffer; +class CGLMQuery; +class CGLMTex; +class CGLMProgram; +class CGLMFBO; + +#ifdef TOGL_DLL_EXPORT + #define TOGL_INTERFACE DLL_EXPORT + #define TOGL_OVERLOAD DLL_GLOBAL_EXPORT + #define TOGL_CLASS DLL_CLASS_EXPORT + #define TOGL_GLOBAL DLL_GLOBAL_EXPORT +#else + #define TOGL_INTERFACE DLL_IMPORT + #define TOGL_OVERLOAD DLL_GLOBAL_IMPORT + #define TOGL_CLASS DLL_CLASS_IMPORT + #define TOGL_GLOBAL DLL_GLOBAL_IMPORT +#endif + +#define TOGLMETHODCALLTYPE __stdcall +//#define TOGLMETHODCALLTYPE + +#define DXABSTRACT_BREAK_ON_ERROR() DebuggerBreak() + +typedef void* VD3DHWND; +typedef void* VD3DHANDLE; + +#define MAKEFOURCC(ch0, ch1, ch2, ch3) ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) + +// +// +// Stuff that would be in windows.h +// +// +#if !defined(_WINNT_) + + typedef int INT; + typedef unsigned long ULONG; + typedef long LONG; + typedef float FLOAT; + typedef unsigned short WORD; + typedef long long LONGLONG; + typedef unsigned int UINT; + typedef long HRESULT; + typedef unsigned char BYTE; + #define CONST const + + #if defined(POSIX) + typedef size_t ULONG_PTR; + #else + typedef unsigned long ULONG_PTR; + #endif + + typedef ULONG_PTR SIZE_T; + + typedef const char* LPCSTR; + typedef char* LPSTR; +#ifndef OSX + typedef unsigned int DWORD; + typedef DWORD* LPDWORD; +#endif + + + #define ZeroMemory RtlZeroMemory + #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length)) + + typedef union _LARGE_INTEGER + { + struct + { + DWORD LowPart; + LONG HighPart; + }; + struct + { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct _GUID + { + bool operator==( const struct _GUID &other ) const; + + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; + } GUID; + + typedef struct _RECT + { + int left; + int top; + int right; + int bottom; + } RECT; + + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *LPPOINT; + + typedef struct _MEMORYSTATUS + { + DWORD dwLength; + SIZE_T dwTotalPhys; + } MEMORYSTATUS, *LPMEMORYSTATUS; + + typedef DWORD COLORREF; + #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) + + #define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + + +// Mac header files like to define these +#ifdef S_FALSE +#undef S_FALSE +#endif +#ifdef S_OK +#undef S_OK +#endif +#ifdef E_FAIL +#undef E_FAIL +#endif +#ifdef E_OUTOFMEMORY +#undef E_OUTOFMEMORY +#endif +#ifdef FAILED +#undef FAILED +#endif +#ifdef SUCCEEDED +#undef SUCCEEDED +#endif + + #define S_FALSE ((HRESULT)0x00000001L) + #define S_OK 0 + #define E_FAIL ((HRESULT)0x80004005L) + #define E_OUTOFMEMORY ((HRESULT)0x8007000EL) + + #define FAILED(hr) ((HRESULT)(hr) < 0) + #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) + + struct RGNDATA + { + }; + + typedef const void* LPCVOID; +#endif + +//----------------------------------------------------------------------------- + +typedef enum _D3DFORMAT D3DFORMAT; + +#define D3DSI_OPCODE_MASK 0x0000FFFF +#define D3DSP_TEXTURETYPE_MASK 0x78000000 + +#define D3DUSAGE_AUTOGENMIPMAP 0x00000400L +#define D3DSP_DCL_USAGE_MASK 0x0000000f + +#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000 +#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16 + + +/* Flags to construct D3DRS_COLORWRITEENABLE */ +#define D3DCOLORWRITEENABLE_RED (1L<<0) +#define D3DCOLORWRITEENABLE_GREEN (1L<<1) +#define D3DCOLORWRITEENABLE_BLUE (1L<<2) +#define D3DCOLORWRITEENABLE_ALPHA (1L<<3) + +#define D3DSGR_NO_CALIBRATION 0x00000000L + +#define D3DXINLINE inline + +#define D3D_SDK_VERSION 32 + +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) + +#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) +#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) +#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) +#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) +#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) +#define D3D_OK S_OK + +#define D3DPRESENT_RATE_DEFAULT 0x00000000 + +// +// DevCaps +// +// we need to see who in Source land is interested in these values, as dxabstract is currently reporting zero for the whole Caps word +#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */ +#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */ +#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */ +#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */ +#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */ +#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */ +#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */ +#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */ +#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */ +#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */ +#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */ +#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */ +#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */ +#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */ +#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */ +#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */ + +// +// PrimitiveMiscCaps +// +#define D3DPMISCCAPS_MASKZ 0x00000002L +#define D3DPMISCCAPS_CULLNONE 0x00000010L +#define D3DPMISCCAPS_CULLCW 0x00000020L +#define D3DPMISCCAPS_CULLCCW 0x00000040L +#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L +#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */ +#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */ +#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */ +#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */ +#define D3DPMISCCAPS_NULLREFERENCE 0x00001000L /* Reference Device that doesnt render */ +#define D3DPMISCCAPS_PERSTAGECONSTANT 0x00008000L /* Device supports per-stage constants */ +#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000L /* Device supports different bit depths for MRT */ +#define D3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000L /* Device clamps fog blend factor per vertex */ + +// Flags field for Issue +#define D3DISSUE_END (1 << 0) // Tells the runtime to issue the end of a query, changing it's state to "non-signaled". +#define D3DISSUE_BEGIN (1 << 1) // Tells the runtime to issue the beginng of a query. + + +#define D3DPRESENT_INTERVAL_ONE 0x00000001L +#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L + +/* + * Options for clearing + */ +#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */ +#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */ +#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */ + + +#define D3DENUM_WHQL_LEVEL 0x00000002L + + + + +#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation + in programmable and fixed function pixel shaders */ +#define D3DDEVCAPS2_STREAMOFFSET 0x00000001L /* Device supports offsets in streams. Must be set by DX9 drivers */ + +#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */ + +#define D3DCREATE_PUREDEVICE 0x00000010L +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L +#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L +#define D3DCREATE_FPU_PRESERVE 0x00000002L +#define D3DPRASTERCAPS_FOGRANGE 0x00010000L +#define D3DPRASTERCAPS_FOGTABLE 0x00000100L +#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L +#define D3DPRASTERCAPS_WFOG 0x00100000L +#define D3DPRASTERCAPS_ZFOG 0x00200000L +#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L +#define D3DPRASTERCAPS_WBUFFER 0x00040000L +#define D3DPRASTERCAPS_ZTEST 0x00000010L + +// +// Caps2 +// +#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L +#define D3DPRASTERCAPS_SCISSORTEST 0x01000000L +#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */ +#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */ +#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */ +#define D3DCREATE_MULTITHREADED 0x00000004L +#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */ +#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L +#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L +#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */ +#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */ +#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L +#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */ +#define D3DTEXOPCAPS_ADD 0x00000040L +#define D3DTEXOPCAPS_MODULATE2X 0x00000010L +#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L +#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L +#define D3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100L /* device supports D3DTSS_TCI_SPHEREMAP */ +#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L + +// The following usages are valid only for querying CheckDeviceFormat +#define D3DUSAGE_QUERY_SRGBREAD (0x00010000L) +#define D3DUSAGE_QUERY_FILTER (0x00020000L) +#define D3DUSAGE_QUERY_SRGBWRITE (0x00040000L) +#define D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING (0x00080000L) +#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L) + +/* Usages for Vertex/Index buffers */ +#define D3DUSAGE_WRITEONLY (0x00000008L) +#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L) +#define D3DUSAGE_DONOTCLIP (0x00000020L) +#define D3DUSAGE_POINTS (0x00000040L) +#define D3DUSAGE_RTPATCHES (0x00000080L) +#define D3DUSAGE_NPATCHES (0x00000100L) + + +// Flags field for GetData +#define D3DGETDATA_FLUSH (1 << 0) // Tells the runtime to flush if the query is outstanding. + +#define D3DFVF_XYZ 0x002 + + +#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector +#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only) +#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write) +#define D3DTA_TEXTURE 0x00000002 // select texture color (read only) +#define D3DTA_TFACTOR 0x00000003 // select D3DRS_TEXTUREFACTOR (read only) +#define D3DTA_SPECULAR 0x00000004 // select specular color (read only) +#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write) +#define D3DTA_CONSTANT 0x00000006 // select texture stage constant +#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier) +#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier) + + +#define D3DUSAGE_RENDERTARGET (0x00000001L) +#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L) +#define D3DUSAGE_QUERY_FILTER (0x00020000L) +#define D3DUSAGE_DEPTHSTENCIL (0x00000002L) +#define D3DUSAGE_WRITEONLY (0x00000008L) +#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L) +#define D3DUSAGE_DYNAMIC (0x00000200L) + +#define D3DSI_INSTLENGTH_MASK 0x0F000000 +#define D3DSI_INSTLENGTH_SHIFT 24 +#define D3DSP_TEXTURETYPE_SHIFT 27 +#define D3DSP_REGTYPE_SHIFT 28 +#define D3DSP_REGTYPE_SHIFT2 8 +#define D3DSP_REGTYPE_MASK 0x70000000 +#define D3DSP_REGTYPE_MASK2 0x00001800 + +#define D3DSP_REGNUM_MASK 0x000007FF + +#define D3DSP_DSTMOD_SHIFT 20 +#define D3DSP_DSTMOD_MASK 0x00F00000 +#define D3DSPDM_MSAMPCENTROID (4<>8)&0xFF) +#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF) + +#define D3DSHADER_ADDRESSMODE_SHIFT 13 +#define D3DSHADER_ADDRESSMODE_MASK (1 << D3DSHADER_ADDRESSMODE_SHIFT) + +#define D3DPS_END() 0x0000FFFF + +// ps_2_0 texld controls +#define D3DSI_TEXLD_PROJECT (0x01 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) +#define D3DSI_TEXLD_BIAS (0x02 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) + + +// destination parameter write mask +#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red) +#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green) +#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue) +#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha) +#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components + +#define D3DVS_SWIZZLE_SHIFT 16 +#define D3DVS_SWIZZLE_MASK 0x00FF0000 + +// The following bits define where to take component X from: + +#define D3DVS_X_X (0 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Y (1 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Z (2 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_W (3 << D3DVS_SWIZZLE_SHIFT) + +// The following bits define where to take component Y from: + +#define D3DVS_Y_X (0 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Y (1 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Z (2 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_W (3 << (D3DVS_SWIZZLE_SHIFT + 2)) + +// The following bits define where to take component Z from: + +#define D3DVS_Z_X (0 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Y (1 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Z (2 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_W (3 << (D3DVS_SWIZZLE_SHIFT + 4)) + +// The following bits define where to take component W from: + +#define D3DVS_W_X (0 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Y (1 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Z (2 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_W (3 << (D3DVS_SWIZZLE_SHIFT + 6)) + +// source parameter modifiers +#define D3DSP_SRCMOD_SHIFT 24 +#define D3DSP_SRCMOD_MASK 0x0F000000 + +// ------------------------------------------------------------------------------------------------------------------------------ // +// ENUMS +// ------------------------------------------------------------------------------------------------------------------------------ // + +typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE +{ + D3DSPSM_NONE = 0<= 2.0 + + + D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 + D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) + D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) + D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) + D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) + D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) + D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) + D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) + D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values + D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. +} D3DDECLTYPE; + +typedef enum _D3DDECLMETHOD +{ + D3DDECLMETHOD_DEFAULT = 0, + D3DDECLMETHOD_PARTIALU, + D3DDECLMETHOD_PARTIALV, + D3DDECLMETHOD_CROSSUV, // Normal + D3DDECLMETHOD_UV, + D3DDECLMETHOD_LOOKUP, // Lookup a displacement map + D3DDECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map +} D3DDECLMETHOD; + +typedef enum _D3DDECLUSAGE +{ + D3DDECLUSAGE_POSITION = 0, + D3DDECLUSAGE_BLENDWEIGHT = 1, + D3DDECLUSAGE_BLENDINDICES = 2, + D3DDECLUSAGE_NORMAL = 3, + D3DDECLUSAGE_PSIZE = 4, + D3DDECLUSAGE_TEXCOORD = 5, + D3DDECLUSAGE_TANGENT = 6, + D3DDECLUSAGE_BINORMAL = 7, + D3DDECLUSAGE_TESSFACTOR = 8, + D3DDECLUSAGE_PLUGH = 9, // mystery value + D3DDECLUSAGE_COLOR = 10, + D3DDECLUSAGE_FOG = 11, + D3DDECLUSAGE_DEPTH = 12, + D3DDECLUSAGE_SAMPLE = 13, +} D3DDECLUSAGE; + +typedef enum _D3DPRIMITIVETYPE +{ + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// STRUCTURES +// ------------------------------------------------------------------------------------------------------------------------------ // + +typedef struct TOGL_CLASS D3DXPLANE +{ + float& operator[]( int i ); + bool operator==( const D3DXPLANE &o ); + bool operator!=( const D3DXPLANE &o ); + operator float*(); + operator const float*() const; + + float a, b, c, d; +} D3DXPLANE; + +typedef enum _D3DVERTEXBLENDFLAGS +{ + D3DVBF_DISABLE = 0, // Disable vertex blending + D3DVBF_1WEIGHTS = 1, // 2 matrix blending + D3DVBF_2WEIGHTS = 2, // 3 matrix blending + D3DVBF_3WEIGHTS = 3, // 4 matrix blending + D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR + D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0 + D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DVERTEXBLENDFLAGS; + +typedef struct _D3DINDEXBUFFER_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; +} D3DINDEXBUFFER_DESC; + +typedef struct _D3DVERTEXELEMENT9 +{ + WORD Stream; // Stream index + WORD Offset; // Offset in the stream in bytes + BYTE Type; // Data type + BYTE Method; // Processing method + BYTE Usage; // Semantics + BYTE UsageIndex; // Semantic index +} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; + + +#define MAX_DEVICE_IDENTIFIER_STRING 512 +typedef struct _D3DADAPTER_IDENTIFIER9 +{ + char Driver[MAX_DEVICE_IDENTIFIER_STRING]; + char Description[MAX_DEVICE_IDENTIFIER_STRING]; + char DeviceName[32]; /* Device name for GDI (ex. \\.\DISPLAY1) */ + + LARGE_INTEGER DriverVersion; /* Defined for 32 bit components */ + + DWORD VendorId; + DWORD DeviceId; + DWORD SubSysId; + DWORD Revision; + DWORD VideoMemory; + +} D3DADAPTER_IDENTIFIER9; + +typedef struct _D3DCOLORVALUE +{ + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; + +typedef struct _D3DMATERIAL9 +{ + D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE Ambient; /* Ambient color RGB */ + D3DCOLORVALUE Specular; /* Specular 'shininess' */ + D3DCOLORVALUE Emissive; /* Emissive color RGB */ + float Power; /* Sharpness if specular highlight */ +} D3DMATERIAL9; + +typedef struct _D3DVOLUME_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + + UINT Width; + UINT Height; + UINT Depth; +} D3DVOLUME_DESC; + +typedef struct _D3DVIEWPORT9 +{ + DWORD X; + DWORD Y; /* Viewport Top left */ + DWORD Width; + DWORD Height; /* Viewport Dimensions */ + float MinZ; /* Min/max of clip Volume */ + float MaxZ; +} D3DVIEWPORT9; + +typedef struct _D3DPSHADERCAPS2_0 +{ + DWORD Caps; + INT DynamicFlowControlDepth; + INT NumTemps; + INT StaticFlowControlDepth; + INT NumInstructionSlots; +} D3DPSHADERCAPS2_0; + +typedef struct _D3DCAPS9 +{ + /* Device Info */ + D3DDEVTYPE DeviceType; + + /* Caps from DX7 Draw */ + DWORD Caps; + DWORD Caps2; + + /* Cursor Caps */ + DWORD CursorCaps; + + /* 3D Device Caps */ + DWORD DevCaps; + + DWORD PrimitiveMiscCaps; + DWORD RasterCaps; + DWORD TextureCaps; + DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's + + DWORD MaxTextureWidth, MaxTextureHeight; + DWORD MaxVolumeExtent; + + DWORD MaxTextureAspectRatio; + DWORD MaxAnisotropy; + + DWORD TextureOpCaps; + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD VertexProcessingCaps; + DWORD MaxActiveLights; + DWORD MaxUserClipPlanes; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxStreams; + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + + // Here are the DX9 specific ones + DWORD DevCaps2; + D3DPSHADERCAPS2_0 PS20Caps; + + DWORD NumSimultaneousRTs; // Will be at least 1 + DWORD MaxVertexShader30InstructionSlots; + DWORD MaxPixelShader30InstructionSlots; + + // only on Posix/GL + DWORD FakeSRGBWrite; // 1 for parts which can't support SRGB writes due to driver issues - 0 for others + DWORD MixedSizeTargets; // 1 for parts which can mix attachment sizes (RT's color vs depth) + DWORD CanDoSRGBReadFromRTs; // 0 when we're on Leopard, 1 when on Snow Leopard +} D3DCAPS9; + +typedef struct _D3DDISPLAYMODE +{ + UINT Width; + UINT Height; + UINT RefreshRate; + D3DFORMAT Format; +} D3DDISPLAYMODE; + +typedef struct _D3DGAMMARAMP +{ + WORD red [256]; + WORD green[256]; + WORD blue [256]; +} D3DGAMMARAMP; + + +/* Resize Optional Parameters */ +typedef struct _D3DPRESENT_PARAMETERS_ +{ + UINT BackBufferWidth; + UINT BackBufferHeight; + D3DFORMAT BackBufferFormat; + UINT BackBufferCount; + + D3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + + D3DSWAPEFFECT SwapEffect; + VD3DHWND hDeviceWindow; + BOOL Windowed; + BOOL EnableAutoDepthStencil; + D3DFORMAT AutoDepthStencilFormat; + DWORD Flags; + + /* FullScreen_RefreshRateInHz must be zero for Windowed mode */ + UINT FullScreen_RefreshRateInHz; + UINT PresentationInterval; +} D3DPRESENT_PARAMETERS; + +typedef struct _D3DDEVICE_CREATION_PARAMETERS +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + VD3DHWND hFocusWindow; + DWORD BehaviorFlags; +} D3DDEVICE_CREATION_PARAMETERS; + +/* Structures for LockBox */ +typedef struct _D3DBOX +{ + UINT Left; + UINT Top; + UINT Right; + UINT Bottom; + UINT Front; + UINT Back; +} D3DBOX; + +typedef struct _D3DLOCKED_BOX +{ + INT RowPitch; + INT SlicePitch; + void* pBits; +} D3DLOCKED_BOX; + +typedef struct _D3DSURFACE_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + + D3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + UINT Width; + UINT Height; +} D3DSURFACE_DESC; + + +typedef struct _D3DLOCKED_RECT +{ + INT Pitch; + void* pBits; +} D3DLOCKED_RECT; + + +typedef struct _D3DRASTER_STATUS +{ + BOOL InVBlank; + UINT ScanLine; +} D3DRASTER_STATUS; + +typedef enum _D3DLIGHTTYPE +{ + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef struct TOGL_CLASS _D3DVECTOR +{ + float x; + float y; + float z; +} D3DVECTOR; + +class TOGL_CLASS D3DXVECTOR2 +{ +public: + operator FLOAT* (); + operator CONST FLOAT* () const; + + float x,y; +}; + +class TOGL_CLASS D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {} + D3DXVECTOR3( float a, float b, float c ); + operator FLOAT* (); + operator CONST FLOAT* () const; +}; + +typedef enum _D3DXINCLUDE_TYPE +{ + D3DXINC_LOCAL, + + // force 32-bit size enum + D3DXINC_FORCE_DWORD = 0x7fffffff + +} D3DXINCLUDE_TYPE; + +typedef struct _D3DLIGHT9 +{ + D3DLIGHTTYPE Type; /* Type of light source */ + D3DCOLORVALUE Diffuse; /* Diffuse color of light */ + D3DCOLORVALUE Specular; /* Specular color of light */ + D3DCOLORVALUE Ambient; /* Ambient color of light */ + D3DVECTOR Position; /* Position in world space */ + D3DVECTOR Direction; /* Direction in world space */ + float Range; /* Cutoff range */ + float Falloff; /* Falloff */ + float Attenuation0; /* Constant attenuation */ + float Attenuation1; /* Linear attenuation */ + float Attenuation2; /* Quadratic attenuation */ + float Theta; /* Inner angle of spotlight cone */ + float Phi; /* Outer angle of spotlight cone */ +} D3DLIGHT9; + +class TOGL_CLASS D3DXVECTOR4 +{ +public: + D3DXVECTOR4() {} + D3DXVECTOR4( float a, float b, float c, float d ); + + float x,y,z,w; +}; + +//---------------------------------------------------------------------------- +// D3DXMACRO: +// ---------- +// Preprocessor macro definition. The application pass in a NULL-terminated +// array of this structure to various D3DX APIs. This enables the application +// to #define tokens at runtime, before the file is parsed. +//---------------------------------------------------------------------------- + +typedef struct _D3DXMACRO +{ + LPCSTR Name; + LPCSTR Definition; + +} D3DXMACRO, *LPD3DXMACRO; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// ------------------------------------------------------------------------------------------------------------------------------ // +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +// +// Also look for any functions marked with "**** FIXED FUNCTION STUFF" +// +// It's only laying around here so we don't have to chop up the shader system a lot to strip out the fixed function code paths. +// ------------------------------------------------------------------------------------------------------------------------------ // +// ------------------------------------------------------------------------------------------------------------------------------ // + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTRANSFORMSTATETYPE +{ + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTEXTUREOP +{ + // Control + D3DTOP_DISABLE = 1, // disables stage + D3DTOP_SELECTARG1 = 2, // the default + D3DTOP_SELECTARG2 = 3, + + // Modulate + D3DTOP_MODULATE = 4, // multiply args together + D3DTOP_MODULATE2X = 5, // multiply and 1 bit + D3DTOP_MODULATE4X = 6, // multiply and 2 bits + + // Add + D3DTOP_ADD = 7, // add arguments together + D3DTOP_ADDSIGNED = 8, // add with -0.5 bias + D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit + D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation + D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product + // Arg1 + Arg2 - Arg1*Arg2 + // = Arg1 + (1-Arg1)*Arg2 + + // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) + D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha + D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha + D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR + + // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) + D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha + D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + + // Specular mapping + D3DTOP_PREMODULATE = 17, // modulate with next texture before use + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB + // COLOROP only + D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A + // COLOROP only + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB + // COLOROP only + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A + // COLOROP only + + // Bump mapping + D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation + D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel + + // This can do either diffuse or specular bump mapping with correct input. + // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) + // where each component has been scaled and offset to make it signed. + // The result is replicated into all four (including alpha) channels. + // This is a valid COLOROP only. + D3DTOP_DOTPRODUCT3 = 24, + + // Triadic ops + D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2 + D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2 + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTEXTURESTAGESTATETYPE +{ + D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */ + D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */ + D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */ + D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */ + D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */ + D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */ + D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + + + D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTURESTAGESTATETYPE; + +//===========================================================================// + +enum GLMVertexAttributeIndex +{ + kGLMGenericAttr00 = 0, + kGLMGenericAttr01, + kGLMGenericAttr02, + kGLMGenericAttr03, + kGLMGenericAttr04, + kGLMGenericAttr05, + kGLMGenericAttr06, + kGLMGenericAttr07, + kGLMGenericAttr08, + kGLMGenericAttr09, + kGLMGenericAttr10, + kGLMGenericAttr11, + kGLMGenericAttr12, + kGLMGenericAttr13, + kGLMGenericAttr14, + kGLMGenericAttr15, + + kGLMVertexAttributeIndexMax // ideally < 32 +}; + +struct GLMVertexAttributeDesc // all the info you need to do vertex setup for one attribute +{ + CGLMBuffer *m_buffer; // NULL allowed in which case m_offset is the full 32-bit pointer.. so you can draw from plain RAM if desired + GLuint m_datasize; // comp count of the attribute (1-4) + GLenum m_datatype; // data type of the attribute (GL_FLOAT, GL_UNSIGNED_BYTE, etc) + GLuint m_stride; + GLuint m_offset; // net offset to attribute 'zero' within the buffer. + GLboolean m_normalized; // apply to any fixed point data that needs normalizing, esp color bytes + + // may need a seed value at some point to be able to disambiguate re-lifed buffers holding same pointer + // simpler alternative is to do shoot-down inside the vertex/index buffer free calls. + // I'd rather not have to have each attribute fiddling a ref count on the buffer to which it refers.. + +#define EQ(fff) ( (src.fff) == (fff) ) + // test in decreasing order of likelihood of difference, but do not include the buffer revision as caller is not supplying it.. + bool operator==(const GLMVertexAttributeDesc& src) const { return EQ(m_buffer) && EQ(m_offset) && EQ(m_stride) && EQ(m_datatype) && EQ(m_normalized) && EQ(m_datasize); } +#undef EQ + + uint m_bufferRevision; // only set in GLM context's copy, to disambiguate references that are same offset / same buffer but cross an orphan event +}; + + +#define MAX_D3DVERTEXELEMENTS 16 + +struct D3DVERTEXELEMENT9_GL +{ + // fields right out of the original decl element (copied) + D3DVERTEXELEMENT9 m_dxdecl; // d3d info + // WORD Stream; // Stream index + // WORD Offset; // Offset in the stream in bytes + // BYTE Type; // Data type + // BYTE Method; // Processing method + // BYTE Usage; // Semantics + // BYTE UsageIndex; // Semantic index + + GLMVertexAttributeDesc m_gldecl; + // CGLMBuffer *m_buffer; // late-dropped from selected stream desc (left NULL, will replace with stream source buffer at sync time) + // GLuint m_datasize; // component count (1,2,3,4) of the attrib + // GLenum m_datatype; // data type of the attribute (GL_FLOAT et al) + // GLuint m_stride; // late-dropped from stream desc + // GLuint m_offset; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL. + // GLuint m_normalized; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL. +}; + +struct IDirect3DDevice9Params +{ + UINT m_adapter; + D3DDEVTYPE m_deviceType; + VD3DHWND m_focusWindow; + DWORD m_behaviorFlags; + D3DPRESENT_PARAMETERS m_presentationParameters; +}; + +#define D3D_MAX_STREAMS 4 +struct D3DStreamDesc +{ + IDirect3DVertexBuffer9 *m_vtxBuffer; + uint m_offset; + uint m_stride; +}; + +struct D3DIndexDesc +{ + IDirect3DIndexBuffer9 *m_idxBuffer; +}; + +// we latch sampler values until draw time and then convert them all to GL form +// note these are similar in name to the fields of a GLMTexSamplingParams but contents are not +// particularly in the texture filtering area + +struct D3DSamplerDesc +{ + D3DTEXTUREADDRESS m_addressModes[3]; // D3DTEXTUREADDRESS modes for S,T,R + DWORD m_borderColor; // DWORD bordercolor + D3DTEXTUREFILTERTYPE m_magFilter; // mag filter + D3DTEXTUREFILTERTYPE m_minFilter; // min filter + D3DTEXTUREFILTERTYPE m_mipFilter; // mip filter + float m_mipmapBias; // float: mipmap bias + DWORD m_maxMipLevel; // DWORD 0..(n-1) LOD index of largest map to use (0 == largest) + DWORD m_maxAniso; // D3DSAMP_MAXANISOTROPY max aniso + DWORD m_srgb; // D3DSAMP_SRGBTEXTURE 0 = no SRGB sampling + DWORD m_shadowFilter; // D3DSAMP_SHADOWFILTER +}; + +// Tracking and naming sampler dimensions +#define SAMPLER_TYPE_2D 0 +#define SAMPLER_TYPE_CUBE 1 +#define SAMPLER_TYPE_3D 2 +#define SAMPLER_TYPE_UNUSED 3 + +#endif // DXABSTRACT_TYPES_H diff --git a/public/togl/osx/glentrypoints.h b/public/togl/osx/glentrypoints.h new file mode 100644 index 00000000..be8d5446 --- /dev/null +++ b/public/togl/osx/glentrypoints.h @@ -0,0 +1,329 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// glentrypoints.h +// +//=============================================================================== + +#ifndef GLENTRYPOINTS_H +#define GLENTRYPOINTS_H + +#pragma once + +#ifdef DX_TO_GL_ABSTRACTION + +#include "tier0/platform.h" +#include "tier0/dynfunction.h" +#include "tier0/vprof_telemetry.h" +#include "interface.h" + +#include "togl/rendermechanism.h" + +#ifndef APIENTRY +#define APIENTRY +#endif + +#ifndef CALLBACK +#define CALLBACK +#endif + + +void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL); + +#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME +class CGLExecuteHelperBase +{ +public: + inline void StartCall(const char *pName); + inline void StopCall(const char *pName); +#if GL_TRACK_API_TIME + TmU64 m_nStartTime; +#endif +}; + +template < class FunctionType, typename Result > +class CGLExecuteHelper : public CGLExecuteHelperBase +{ +public: + inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); } + + inline operator Result() const { return m_Result; } + inline operator char*() const { return (char*)m_Result; } + + FunctionType m_pFn; + + Result m_Result; +}; + +template < class FunctionType> +class CGLExecuteHelper : public CGLExecuteHelperBase +{ +public: + inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); } + + FunctionType m_pFn; +}; +#endif + +template < class FunctionType, typename Result > +class CDynamicFunctionOpenGLBase +{ +public: + // Construct with a NULL function pointer. You must manually call + // Lookup() before you can call a dynamic function through this interface. + CDynamicFunctionOpenGLBase() : m_pFn(NULL) {} + + // Construct and do a lookup right away. You will need to make sure that + // the lookup actually succeeded, as the gl library might have failed to load + // or (fn) might not exist in it. + CDynamicFunctionOpenGLBase(const char *fn, FunctionType fallback=NULL) : m_pFn(NULL) + { + Lookup(fn, fallback); + } + + // Construct and do a lookup right away. See comments in Lookup() about what (okay) does. + CDynamicFunctionOpenGLBase(const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL) + { + Lookup(fn, okay, fallback); + } + + // Load library if necessary, look up symbol. Returns true and sets + // m_pFn on successful lookup, returns false otherwise. If the + // function pointer is already looked up, this return true immediately. + // Use Reset() first if you want to look up the symbol again. + // This function will return false immediately unless (okay) is true. + // This allows you to chain lookups like this: + // bool okay = true; + // x.Lookup(lib, "x", okay); + // y.Lookup(lib, "y", okay); + // z.Lookup(lib, "z", okay); + // if (okay) { printf("All functions were loaded successfully!\n"); } + // If you supply a fallback, it'll be used if the lookup fails (and if + // non-NULL, means this will always return (okay)). + bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL) + { + if (!okay) + return false; + else if (this->m_pFn == NULL) + { + this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, false, (void *) fallback); + this->SetFuncName( fn ); + } + return okay; + } + + // Load library if necessary, look up symbol. Returns true and sets + // m_pFn on successful lookup, returns false otherwise. If the + // function pointer is already looked up, this return true immediately. + // Use Reset() first if you want to look up the symbol again. + // This function will return false immediately unless (okay) is true. + // If you supply a fallback, it'll be used if the lookup fails (and if + // non-NULL, means this will always return true). + bool Lookup(const char *fn, FunctionType fallback=NULL) + { + bool okay = true; + return Lookup(fn, okay, fallback); + } + + // Invalidates the current lookup. Makes the function pointer NULL. You + // will need to call Lookup() before you can call a dynamic function + // through this interface again. + void Reset() { m_pFn = NULL; } + + // Force this to be a specific function pointer. + void Force(FunctionType ptr) { m_pFn = ptr; } + + // Retrieve the actual function pointer. + FunctionType Pointer() const { return m_pFn; } + +#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME + #if GL_TELEMETRY_ZONES + #define GL_FUNC_NAME m_szName + #else + #define GL_FUNC_NAME "" + #endif + + inline CGLExecuteHelper operator() () const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME ); } + + template + inline CGLExecuteHelper operator() (T a) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a); } + + template + inline CGLExecuteHelper operator() (T a, U b) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c ) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i, C j) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i, j); } +#else + operator FunctionType() const { return m_pFn; } +#endif + + // Can be used to verify that we have an actual function looked up and + // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); } + operator bool () const { return m_pFn != NULL; } + bool operator !() const { return m_pFn == NULL; } + +protected: + FunctionType m_pFn; + +#if GL_TELEMETRY_ZONES + char m_szName[32]; + inline void SetFuncName(const char *pFn) { V_strncpy( m_szName, pFn, sizeof( m_szName ) ); } +#else + inline void SetFuncName(const char *pFn) { (void)pFn; } +#endif +}; + +// This works a lot like CDynamicFunctionMustInit, but we use SDL_GL_GetProcAddress(). +template < const bool bRequired, class FunctionType, typename Result > +class CDynamicFunctionOpenGL : public CDynamicFunctionOpenGLBase< FunctionType, Result > +{ +private: // forbid default constructor. + CDynamicFunctionOpenGL() {} + +public: + CDynamicFunctionOpenGL(const char *fn, FunctionType fallback=NULL) + { + bool okay = true; + Lookup(fn, okay, fallback); + this->SetFuncName( fn ); + } + + CDynamicFunctionOpenGL(const char *fn, bool &okay, FunctionType fallback=NULL) + { + Lookup(fn, okay, fallback); + this->SetFuncName( fn ); + } + + // Please note this is not virtual. + // !!! FIXME: we might want to fall back and try "EXT" or "ARB" versions in some case. + bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL) + { + if (this->m_pFn == NULL) + { + this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, bRequired, (void *) fallback); + this->SetFuncName( fn ); + } + return okay; + } +}; + + +// This provides all the entry points for a given OpenGL context. +// ENTRY POINTS ARE ONLY VALID FOR THE CONTEXT THAT WAS CURRENT WHEN +// YOU LOOKED THEM UP. 99% of the time, this is not a problem, but +// that 1% is really hard to track down. Always access the GL +// through this class! +class COpenGLEntryPoints +{ +public: + // The GL context you are looking up entry points for must be current when you construct this object! + COpenGLEntryPoints(); + + uint64 m_nTotalGLCycles, m_nTotalGLCalls; + + int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2. + int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1. + int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0. + bool m_bHave_OpenGL; + + #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; + #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn; + #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn; + #include "togl/glfuncs.inl" + #undef GL_FUNC_VOID + #undef GL_FUNC + #undef GL_EXT +}; + +// This will be set to the current OpenGL context's entry points. +extern COpenGLEntryPoints *gGL; +typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, bool &, const bool, void *); + +#ifdef TOGL_DLL_EXPORT + DLL_EXPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory ); + DLL_EXPORT void ToGLDisconnectLibraries(); + DLL_EXPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback); +#else + DLL_IMPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory ); + DLL_IMPORT void ToGLDisconnectLibraries(); + DLL_IMPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback); +#endif + +#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME +inline void CGLExecuteHelperBase::StartCall(const char *pName) +{ + (void)pName; + +#if GL_TELEMETRY_ZONES + tmEnter( TELEMETRY_LEVEL3, TMZF_NONE, pName ); +#endif + +#if GL_TRACK_API_TIME + m_nStartTime = tmFastTime(); +#endif +} + +inline void CGLExecuteHelperBase::StopCall(const char *pName) +{ +#if GL_TRACK_API_TIME + uint64 nTotalCycles = tmFastTime() - m_nStartTime; +#endif + +#if GL_TELEMETRY_ZONES + tmLeave( TELEMETRY_LEVEL3 ); +#endif + +#if GL_TRACK_API_TIME + //double flMilliseconds = g_Telemetry.flRDTSCToMilliSeconds * nTotalCycles; + if (gGL) + { + gGL->m_nTotalGLCycles += nTotalCycles; + gGL->m_nTotalGLCalls++; + } +#endif +} +#endif + +#endif // DX_TO_GL_ABSTRACTION + +#endif // GLENTRYPOINTS_H diff --git a/public/togl/osx/glfuncs.h b/public/togl/osx/glfuncs.h new file mode 100644 index 00000000..78184bef --- /dev/null +++ b/public/togl/osx/glfuncs.h @@ -0,0 +1,184 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// !!! FIXME: Some of these aren't base OpenGL...pick out the extensions. +// !!! FIXME: Also, look up these -1, -1 versions numbers. +GL_FUNC(OpenGL,true,GLenum,glGetError,(void),()) +GL_FUNC_VOID(OpenGL,true,glActiveTexture,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glAlphaFunc,(GLenum a,GLclampf b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glAttachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBegin,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glBindAttribLocationARB,(GLhandleARB a,GLuint b,const GLcharARB *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glBindBufferARB,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBindProgramARB,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBindTexture,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBlendColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glBlendEquation,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glBlendFunc,(GLenum a,GLenum b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBufferDataARB,(GLenum a,GLsizeiptrARB b,const GLvoid *c,GLenum d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glClear,(GLbitfield a),(a)) +GL_FUNC_VOID(OpenGL,true,glClearColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glClearDepth,(GLclampd a),(a)) +GL_FUNC_VOID(OpenGL,true,glClearStencil,(GLint a),(a)) +GL_FUNC_VOID(OpenGL,true,glClipPlane,(GLenum a,const GLdouble *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glColorMask,(GLboolean a,GLboolean b,GLboolean c,GLboolean d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glCompileShaderARB,(GLhandleARB a),(a)) +GL_FUNC_VOID(OpenGL,true,glCompressedTexImage2D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLint f,GLsizei g,const GLvoid *h),(a,b,c,d,e,f,g,h)) +GL_FUNC_VOID(OpenGL,true,glCompressedTexImage3D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLsizei h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC(OpenGL,true,GLhandleARB,glCreateProgramObjectARB,(void),()) +GL_FUNC(OpenGL,true,GLhandleARB,glCreateShaderObjectARB,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteBuffersARB,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDeleteObjectARB,(GLhandleARB a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteProgramsARB,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDeleteQueriesARB,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDeleteShader,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteTextures,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDepthFunc,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDepthMask,(GLboolean a),(a)) +GL_FUNC_VOID(OpenGL,true,glDepthRange,(GLclampd a,GLclampd b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDetachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDisable,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDisableVertexAttribArray,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glDrawArrays,(GLenum a,GLint b,GLsizei c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glDrawBuffer,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDrawRangeElements,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glEnd,(void),()) +GL_FUNC_VOID(OpenGL,true,glFinish,(void),()) +GL_FUNC_VOID(OpenGL,true,glFlush,(void),()) +GL_FUNC_VOID(OpenGL,true,glFrontFace,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glGenBuffersARB,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGenProgramsARB,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGenQueriesARB,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGenTextures,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetBooleanv,(GLenum a,GLboolean *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetCompressedTexImage,(GLenum a,GLint b,GLvoid *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glGetDoublev,(GLenum a,GLdouble *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetFloatv,(GLenum a,GLfloat *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetInfoLogARB,(GLhandleARB a,GLsizei b,GLsizei *c,GLcharARB *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glGetIntegerv,(GLenum a,GLint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetObjectParameterivARB,(GLhandleARB a,GLenum b,GLint *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glGetProgramivARB,(GLenum a,GLenum b,GLint *c),(a,b,c)) +GL_FUNC(OpenGL,true,const GLubyte *,glGetString,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glGetTexImage,(GLenum a,GLint b,GLenum c,GLenum d,GLvoid *e),(a,b,c,d,e)) +GL_FUNC(OpenGL,true,GLint,glGetUniformLocationARB,(GLhandleARB a,const GLcharARB *b),(a,b)) +GL_FUNC(OpenGL,true,GLboolean,glIsEnabled,(GLenum a),(a)) +GL_FUNC(OpenGL,true,GLboolean,glIsTexture,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glLinkProgramARB,(GLhandleARB a),(a)) +GL_FUNC(OpenGL,true,GLvoid*,glMapBufferARB,(GLenum a,GLenum b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glOrtho,(GLdouble a,GLdouble b,GLdouble c,GLdouble d,GLdouble e,GLdouble f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glPixelStorei,(GLenum a,GLint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glPolygonMode,(GLenum a,GLenum b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glPolygonOffset,(GLfloat a,GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glPopAttrib,(void),()) +GL_FUNC_VOID(OpenGL,true,glProgramStringARB,(GLenum a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glPushAttrib,(GLbitfield a),(a)) +GL_FUNC_VOID(OpenGL,true,glReadBuffer,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glScissor,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glShaderSourceARB,(GLhandleARB a,GLsizei b,const GLcharARB **c,const GLint *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glStencilFunc,(GLenum a,GLint b,GLuint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glStencilMask,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glStencilOp,(GLenum a,GLenum b,GLenum c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glTexCoord2f,(GLfloat a,GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glTexImage2D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLint f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC_VOID(OpenGL,true,glTexImage3D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLenum h,GLenum i,const GLvoid *j),(a,b,c,d,e,f,g,h,i,j)) +GL_FUNC_VOID(OpenGL,true,glTexParameterfv,(GLenum a,GLenum b,const GLfloat *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glTexParameteri,(GLenum a,GLenum b,GLint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glTexSubImage2D,(GLenum a,GLint b,GLint c,GLint d,GLsizei e,GLsizei f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC_VOID(OpenGL,true,glUniform1f,(GLint a,GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glUniform1i,(GLint a,GLint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glUniform1iARB,(GLint a,GLint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glUniform4fv,(GLint a,GLsizei b,const GLfloat *c),(a,b,c)) +GL_FUNC(OpenGL,true,GLboolean,glUnmapBuffer,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glUseProgram,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glVertex3f,(GLfloat a,GLfloat b,GLfloat c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glVertexAttribPointer,(GLuint a,GLint b,GLenum c,GLboolean d,GLsizei e,const GLvoid *f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glViewport,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glEnableClientState,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDisableClientState,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glClientActiveTexture,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glVertexPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glTexCoordPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glProgramEnvParameters4fvEXT,(GLenum a,GLuint b,GLsizei c,const GLfloat *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glColor4sv,(const GLshort *a),(a)) +GL_FUNC_VOID(OpenGL,true,glStencilOpSeparate,(GLenum a,GLenum b,GLenum c,GLenum d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glStencilFuncSeparate,(GLenum a,GLenum b,GLint c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glGetTexLevelParameteriv,(GLenum a,GLint b,GLenum c,GLint *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glColor4f,(GLfloat a,GLfloat b,GLfloat c,GLfloat d),(a,b,c,d)) +GL_EXT(GL_EXT_framebuffer_object,-1,-1) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindFramebufferEXT,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindRenderbufferEXT,(GLenum a,GLuint b),(a,b)) +GL_FUNC(GL_EXT_framebuffer_object,false,GLenum,glCheckFramebufferStatusEXT,(GLenum a),(a)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteRenderbuffersEXT,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferRenderbufferEXT,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture2DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture3DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenFramebuffersEXT,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenRenderbuffersEXT,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteFramebuffersEXT,(GLsizei a,const GLuint *b),(a,b)) +GL_EXT(GL_EXT_framebuffer_blit,-1,-1) +GL_FUNC_VOID(GL_EXT_framebuffer_blit,false,glBlitFramebufferEXT,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j)) +GL_EXT(GL_EXT_framebuffer_multisample,-1,-1) +GL_FUNC_VOID(GL_EXT_framebuffer_multisample,false,glRenderbufferStorageMultisampleEXT,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e)) +GL_EXT(GL_APPLE_fence,-1,-1) +GL_FUNC(GL_APPLE_fence,false,GLboolean,glTestFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glSetFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glFinishFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glDeleteFencesAPPLE,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_APPLE_fence,false,glGenFencesAPPLE,(GLsizei a,GLuint *b),(a,b)) +GL_EXT(GL_NV_fence,-1,-1) +GL_FUNC(GL_NV_fence,false,GLboolean,glTestFenceNV,(GLuint a),(a)) +GL_FUNC_VOID(GL_NV_fence,false,glSetFenceNV,(GLuint a,GLenum b),(a,b)) +GL_FUNC_VOID(GL_NV_fence,false,glFinishFenceNV,(GLuint a),(a)) +GL_FUNC_VOID(GL_NV_fence,false,glDeleteFencesNV,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_NV_fence,false,glGenFencesNV,(GLsizei a,GLuint *b),(a,b)) +GL_EXT(GL_ARB_sync,3,2) +#ifdef HAVE_GL_ARB_SYNC +GL_FUNC_VOID(GL_ARB_sync,false,glGetSynciv,(GLsync a, GLenum b, GLsizei c, GLsizei *d, GLint *e),(a,b,c,d,e)) +GL_FUNC(GL_ARB_sync,false,GLenum,glClientWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c)) +GL_FUNC_VOID(GL_ARB_sync,false,glWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c)) +GL_FUNC_VOID(GL_ARB_sync,false,glDeleteSync,(GLsync a),(a)) +GL_FUNC(GL_ARB_sync,false,GLsync,glFenceSync,(GLenum a, GLbitfield b),(a,b)) +#endif +GL_EXT(GL_EXT_draw_buffers2,-1,-1) +GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glColorMaskIndexedEXT,(GLuint a,GLboolean b,GLboolean c,GLboolean d,GLboolean e),(a,b,c,d,e)) +GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glEnableIndexedEXT,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glDisableIndexedEXT,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glGetBooleanIndexedvEXT,(GLenum a,GLuint b,GLboolean *c),(a,b,c)) +GL_EXT(GL_EXT_bindable_uniform,-1,-1) +GL_FUNC_VOID(GL_EXT_bindable_uniform,false,glUniformBufferEXT,(GLuint a,GLint b,GLuint c),(a,b,c)) +GL_EXT(GL_APPLE_flush_buffer_range,-1,-1) +GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glBufferParameteriAPPLE,(GLenum a,GLenum b,GLint c),(a,b,c)) +GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glFlushMappedBufferRangeAPPLE,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c)) +GL_EXT(GL_ARB_map_buffer_range,-1,-1) +GL_FUNC(GL_ARB_map_buffer_range,false,void*,glMapBufferRange,(GLenum a,GLintptr b,GLsizeiptr c,GLbitfield d),(a,b,c,d)) +GL_FUNC_VOID(GL_ARB_map_buffer_range,false,glFlushMappedBufferRange,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c)) +GL_EXT(GL_ARB_occlusion_query,-1,-1) +GL_FUNC_VOID(GL_ARB_occlusion_query,false,glBeginQueryARB,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_ARB_occlusion_query,false,glEndQueryARB,(GLenum a),(a)) +GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectivARB,(GLuint a,GLenum b,GLint *c),(a,b,c)) +GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectuivARB,(GLuint a,GLenum b,GLuint *c),(a,b,c)) +GL_EXT(GL_APPLE_texture_range,-1,-1) +GL_FUNC_VOID(GL_APPLE_texture_range,false,glTextureRangeAPPLE,(GLenum a,GLsizei b,void *c),(a,b,c)) +GL_FUNC_VOID(GL_APPLE_texture_range,false,glGetTexParameterPointervAPPLE,(GLenum a,GLenum b,void* *c),(a,b,c)) +GL_EXT(GL_APPLE_client_storage,-1,-1) +GL_EXT(GL_ARB_uniform_buffer,-1,-1) +GL_EXT(GL_ARB_vertex_array_bgra,-1,-1) +GL_EXT(GL_EXT_vertex_array_bgra,-1,-1) +GL_EXT(GL_ARB_framebuffer_object,3,0) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindFramebuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindRenderbuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC(GL_ARB_framebuffer_object,false,GLenum,glCheckFramebufferStatus,(GLenum a),(a)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteRenderbuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferRenderbuffer,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture2D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture3D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenFramebuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenRenderbuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteFramebuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBlitFramebuffer,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glRenderbufferStorageMultisample,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e)) +GL_EXT(GL_GREMEDY_string_marker,-1,-1) +GL_FUNC_VOID(GL_GREMEDY_string_marker,false,glStringMarkerGREMEDY,(GLsizei a,const void *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glPushClientAttrib,(GLbitfield a),(a)) +GL_FUNC_VOID(OpenGL,true,glPopClientAttrib,(void),()) + diff --git a/public/togl/osx/glmdebug.h b/public/togl/osx/glmdebug.h new file mode 100644 index 00000000..ee60a3a4 --- /dev/null +++ b/public/togl/osx/glmdebug.h @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef GLMDEBUG_H +#define GLMDEBUG_H + +#include "tier0/platform.h" +#include + +// include this anywhere you need to be able to compile-out code related specifically to GLM debugging. + +// we expect DEBUG to be driven by the build system so you can include this header anywhere. +// when we come out, GLMDEBUG will be defined to a value - 0, 1, or 2 +// 0 means no GLM debugging is possible +// 1 means it's possible and resulted from being a debug build +// 2 means it's possible and resulted from being manually forced on for a release build + +#ifdef POSIX + #ifndef GLMDEBUG + #ifdef DEBUG + #define GLMDEBUG 1 // normally 1 here, testing + #else + // #define GLMDEBUG 2 // don't check this in enabled.. + #endif + + #ifndef GLMDEBUG + #define GLMDEBUG 0 + #endif + #endif +#else + #ifndef GLMDEBUG + #define GLMDEBUG 0 + #endif +#endif + + +//=============================================================================== +// debug channels + +enum EGLMDebugChannel +{ + ePrintf, + eDebugger, + eGLProfiler +}; + +#if GLMDEBUG + // make all these prototypes disappear in non GLMDEBUG + void GLMDebugInitialize( bool forceReinit=false ); + + bool GLMDetectOGLP( void ); + bool GLMDetectGDB( void ); + uint GLMDetectAvailableChannels( void ); + + uint GLMDebugChannelMask( uint *newValue = NULL ); + // note that GDB and OGLP can both come and go during run - forceCheck will allow that to be detected. + // mask returned is in form of 1< < + eComment, // 3 one off messages --- + eMatrixData, // 4 matrix data -M- + eShaderData, // 5 shader data (params) -S- + eFrameBufData, // 6 FBO data (attachments) -F- + eDXStuff, // 7 dxabstract spew -X- + eAllocations, // 8 tracking allocs and frees -A- + eSlowness, // 9 slow things happening (srgb flips..) -Z- + eDefaultFlavor, // not specified (no marker) + eFlavorCount +}; +uint GLMDebugFlavorMask( uint *newValue = NULL ); + +// make all these prototypes disappear in non GLMDEBUG +#if GLMDEBUG + // these are unconditional outputs, they don't interrogate the string + void GLMStringOut( const char *string ); + void GLMStringOutIndented( const char *string, int indentColumns ); + + #ifdef TOGL_DLL_EXPORT + // these will look at the string to guess its flavor: <, >, ---, -M-, -S- + DLL_EXPORT void GLMPrintfVA( const char *fmt, va_list vargs ); + DLL_EXPORT void GLMPrintf( const char *fmt, ... ); + #else + DLL_IMPORT void GLMPrintfVA( const char *fmt, va_list vargs ); + DLL_IMPORT void GLMPrintf( const char *fmt, ... ); + #endif + + // these take an explicit flavor with a default value + void GLMPrintStr( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor ); + + #define GLMPRINTTEXT_NUMBEREDLINES 0x80000000 + void GLMPrintText( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor, uint options=0 ); // indent each newline + + int GLMIncIndent( int indentDelta ); + int GLMGetIndent( void ); + void GLMSetIndent( int indent ); + +#endif + +// helpful macro if you are in a position to call GLM functions directly (i.e. you live in materialsystem / shaderapidx9) +#if GLMDEBUG + #define GLMPRINTF(args) GLMPrintf args + #define GLMPRINTSTR(args) GLMPrintStr args + #define GLMPRINTTEXT(args) GLMPrintText args +#else + #define GLMPRINTF(args) + #define GLMPRINTSTR(args) + #define GLMPRINTTEXT(args) +#endif + + +//=============================================================================== +// knob twiddling +#ifdef TOGL_DLL_EXPORT + DLL_EXPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value + DLL_EXPORT float GLMKnobToggle( char *knobname ); +#else + DLL_IMPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value + DLL_IMPORT float GLMKnobToggle( char *knobname ); +#endif + +//=============================================================================== +// other stuff + +#if GLMDEBUG +void GLMTriggerDebuggerBreak(); +inline void GLMDebugger( void ) +{ + if (GLMDebugChannelMask() & (1< +#include +#include +#include +#include +#include + +typedef uint32_t CGDirectDisplayID; +typedef uint32_t CGOpenGLDisplayMask; +typedef double CGRefreshRate; + +//#include +#elif defined(LINUX) +#include "tier0/platform.h" +#include +#include +#else +#error +#endif + +typedef void _PseudoNSGLContext; // aka NSOpenGLContext +typedef _PseudoNSGLContext *PseudoNSGLContextPtr; + +struct GLMDisplayModeInfoFields +{ + uint m_modePixelWidth; + uint m_modePixelHeight; + uint m_modeRefreshHz; + // are we even going to talk about bit depth... not yet +}; + +struct GLMDisplayInfoFields +{ +#ifdef OSX + CGDirectDisplayID m_cgDisplayID; + CGOpenGLDisplayMask m_glDisplayMask; // result of CGDisplayIDToOpenGLDisplayMask on the cg_displayID. +#endif + uint m_displayPixelWidth; + uint m_displayPixelHeight; +}; + +struct GLMRendererInfoFields +{ + /*properties of interest and their desired values. + + kCGLRPFullScreen = 54, true + kCGLRPAccelerated = 73, true + kCGLRPWindow = 80, true + + kCGLRPRendererID = 70, informational + kCGLRPDisplayMask = 84, informational + kCGLRPBufferModes = 100, informational + kCGLRPColorModes = 103, informational + kCGLRPAccumModes = 104, informational + kCGLRPDepthModes = 105, informational + kCGLRPStencilModes = 106, informational + kCGLRPMaxAuxBuffers = 107, informational + kCGLRPMaxSampleBuffers = 108, informational + kCGLRPMaxSamples = 109, informational + kCGLRPSampleModes = 110, informational + kCGLRPSampleAlpha = 111, informational + kCGLRPVideoMemory = 120, informational + kCGLRPTextureMemory = 121, informational + kCGLRPRendererCount = 128 number of renderers in the CGLRendererInfoObj under examination + + kCGLRPOffScreen = 53, D/C + kCGLRPRobust = 75, FALSE or D/C - aka we're asking for no-fallback + kCGLRPBackingStore = 76, D/C + kCGLRPMPSafe = 78, D/C + kCGLRPMultiScreen = 81, D/C + kCGLRPCompliant = 83, D/C + */ + + + //--------------------------- info we have from CGL renderer queries, IOKit, Gestalt + //--------------------------- these are set up in the displayDB by CocoaMgr + GLint m_fullscreen; + GLint m_accelerated; + GLint m_windowed; + + GLint m_rendererID; + GLint m_displayMask; + GLint m_bufferModes; + GLint m_colorModes; + GLint m_accumModes; + GLint m_depthModes; + GLint m_stencilModes; + + GLint m_maxAuxBuffers; + GLint m_maxSampleBuffers; + GLint m_maxSamples; + GLint m_sampleModes; + GLint m_sampleAlpha; + + GLint m_vidMemory; + GLint m_texMemory; + + uint m_pciVendorID; + uint m_pciDeviceID; + char m_pciModelString[64]; + char m_driverInfoString[64]; + + //--------------------------- OS version related - set up by CocoaMgr + + // OS version found + uint m_osComboVersion; // 0x00XXYYZZ : XX major, YY minor, ZZ minor minor : 10.6.3 --> 0x000A0603. 10.5.8 --> 0x000A0508. + + //--------------------------- shorthands - also set up by CocoaMgr - driven by vendorid / deviceid + + bool m_ati; + bool m_atiR5xx; + bool m_atiR6xx; + bool m_atiR7xx; + bool m_atiR8xx; + bool m_atiNewer; + + bool m_intel; + bool m_intel95x; + bool m_intel3100; + bool m_intelNewer; + + bool m_nv; + bool m_nvG7x; + bool m_nvG8x; + bool m_nvNewer; + + //--------------------------- context query results - left blank in the display DB - but valid in a GLMContext (call ctx->Caps() to get a const ref) + + // booleans + bool m_hasGammaWrites; // aka glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) / glEnable(GL_FRAMEBUFFER_SRGB_EXT) + bool m_hasMixedAttachmentSizes; // aka ARB_fbo in 10.6.3 - test for min OS vers, then exported ext string + bool m_hasBGRA; // aka GL_BGRA vertex attribs in 10.6.3 - - test for min OS vers, then exported ext string + bool m_hasNewFullscreenMode; // aka 10.6.x "big window" fullscreen mode + bool m_hasNativeClipVertexMode; // aka GLSL gl_ClipVertex does not fall back to SW- OS version and folklore-based + bool m_hasOcclusionQuery; // occlusion query: do you speak it ?! + bool m_hasFramebufferBlit; // framebuffer blit: know what I'm sayin?! + bool m_hasPerfPackage1; // means new MTGL, fast OQ, fast uniform upload, NV can resolve flipped (late summer 2010 post 10.6.4 update) + + // counts + int m_maxAniso; // aniso limit - context query + + // other exts + bool m_hasBindableUniforms; + bool m_hasUniformBuffers; + + // runtime options that aren't negotiable once set + bool m_hasDualShaders; // must supply CLI arg "-glmdualshaders" or we go GLSL only + + //--------------------------- " can'ts " - specific problems that need to be worked around + + bool m_cantBlitReliably; // Intel chipsets have problems blitting sRGB sometimes + bool m_cantAttachSRGB; // NV G8x on 10.5.8 can't have srgb tex on FBO color - separate issue from hasGammaWrites + bool m_cantResolveFlipped; // happens on NV in 10.6.4 and prior - console variable "gl_can_resolve_flipped" can overrule + bool m_cantResolveScaled; // happens everywhere per GL spec but may be relaxed some day - console variable "gl_can_resolve_scaled" can overrule + bool m_costlyGammaFlips; // this means that sRGB sampling state affects shader code gen, resulting in state-dependent code regen + + + //--------------------------- " bads " - known bad drivers + bool m_badDriver1064NV; // this is the bad NVIDIA driver on 10.6.4 - stutter, tex corruption, black screen issues +}; + + + +#endif diff --git a/public/togl/osx/glmdisplaydb.h b/public/togl/osx/glmdisplaydb.h new file mode 100644 index 00000000..05c98dc8 --- /dev/null +++ b/public/togl/osx/glmdisplaydb.h @@ -0,0 +1,115 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef GLMDISPLAYDB_H +#define GLMDISPLAYDB_H + +#include "tier1/utlvector.h" + +//=============================================================================== + +// modes, displays, and renderers +// think of renderers as being at the top of a tree. +// each renderer has displays hanging off of it. +// each display has modes hanging off of it. +// the tree is populated on demand and then queried as needed. + +//=============================================================================== + +// GLMDisplayModeInfoFields is in glmdisplay.h + +class GLMDisplayMode +{ +public: + GLMDisplayModeInfoFields m_info; + + GLMDisplayMode( uint width, uint height, uint refreshHz ); + GLMDisplayMode() { }; + ~GLMDisplayMode( void ); + + + void Init( uint width, uint height, uint refreshHz ); + void Dump( int which ); +}; + +//=============================================================================== + +// GLMDisplayInfoFields is in glmdisplay.h + +class GLMDisplayInfo +{ +public: + GLMDisplayInfoFields m_info; + CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes + + GLMDisplayInfo( void ); + ~GLMDisplayInfo( void ); + + void PopulateModes( void ); + + void Dump( int which ); +}; + +//=============================================================================== + +// GLMRendererInfoFields is in glmdisplay.h + +class GLMRendererInfo +{ +public: + GLMRendererInfoFields m_info; + GLMDisplayInfo *m_display; // starts out NULL, set by PopulateDisplays + + GLMRendererInfo ( GLMRendererInfoFields *info ); + ~GLMRendererInfo ( void ); + + void PopulateDisplays(); + void Dump( int which ); +}; + +//=============================================================================== + +// this is just a tuple describing fake adapters which are really renderer/display pairings. +// dxabstract bridges the gap between the d3d adapter-centric world and the GL renderer+display world. +// this makes it straightforward to handle cases like two video cards with two displays on one, and one on the other - +// you get three fake adapters which represent each useful screen. + +// the constraint that dxa will have to follow though, is that if the user wants to change their +// display selection for full screen, they would only be able to pick on that has the same underlying renderer. +// can't change fakeAdapter from one to another with different GL renderer under it. Screen hop but no card hop. + +struct GLMFakeAdapter +{ + int m_rendererIndex; + int m_displayIndex; +}; + +class GLMDisplayDB +{ +public: + CUtlVector< GLMRendererInfo* > *m_renderers; // starts out NULL, set by PopulateRenderers + + CUtlVector< GLMFakeAdapter > m_fakeAdapters; + + GLMDisplayDB ( void ); + ~GLMDisplayDB ( void ); + + virtual void PopulateRenderers( void ); + virtual void PopulateFakeAdapters( uint realRendererIndex ); // fake adapters = one real adapter times however many displays are on it + virtual void Populate( void ); + + // The info-get functions return false on success. + virtual int GetFakeAdapterCount( void ); + virtual bool GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut ); + + virtual int GetRendererCount( void ); + virtual bool GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut ); + + virtual int GetDisplayCount( int rendererIndex ); + virtual bool GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut ); + + virtual int GetModeCount( int rendererIndex, int displayIndex ); + virtual bool GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut ); + + virtual void Dump( void ); +}; + +#endif // GLMDISPLAYDB_H diff --git a/public/togl/osx/glmgr.h b/public/togl/osx/glmgr.h new file mode 100644 index 00000000..cdf64206 --- /dev/null +++ b/public/togl/osx/glmgr.h @@ -0,0 +1,1088 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// glmgr.h +// singleton class, common basis for managing GL contexts +// responsible for tracking adapters and contexts +// +//=============================================================================== + +#ifndef GLMGR_H +#define GLMGR_H + +#pragma once + +#undef HAVE_GL_ARB_SYNC +#ifdef LINUX +#define HAVE_GL_ARB_SYNC 1 +#endif + +#include "glentrypoints.h" +#include "glmdebug.h" +#include "glmdisplay.h" +#include "glmgrext.h" +#include "glmgrbasics.h" +#include "cglmtex.h" +#include "cglmfbo.h" +#include "cglmprogram.h" +#include "cglmbuffer.h" +#include "cglmquery.h" + +#include "tier0/vprof_telemetry.h" +#include "materialsystem/ishader.h" +#include "dxabstract_types.h" + + +#ifdef LINUX +#define Debugger DebuggerBreak +#undef CurrentTime + +// prevent some conflicts in SDL headers... +#undef M_PI +#include +#ifndef _STDINT_H_ +#define _STDINT_H_ 1 +#endif + +#include "SDL/SDL.h" +#endif + +//=============================================================================== +// glue to call out to Obj-C land (these are in glmgrcocoa.mm) +#ifdef OSX +PseudoNSGLContextPtr GetCurrentNSGLContext( ); +CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx ); +#endif + +#include "tier0/dynfunction.h" + +//=============================================================================== + +// parrot the D3D present parameters, more or less... "adapter" translates into "active display index" per the m_activeDisplayCount below. +class GLMDisplayParams +{ + public: + + // presumption, these indices are in sync with the current display DB that GLMgr has handy + //int m_rendererIndex; // index of renderer (-1 if root context) + //int m_displayIndex; // index of display in renderer - for FS + //int m_modeIndex; // index of mode in display - for FS + + void *m_focusWindow; // (VD3DHWND aka WindowRef) - what window does this context display into + + bool m_fsEnable; // fullscreen on or not + bool m_vsyncEnable; // vsync on or not + + // height and width have to match the display mode info if full screen. + + uint m_backBufferWidth; // pixel width (aka screen h-resolution if full screen) + uint m_backBufferHeight; // pixel height (aka screen v-resolution if full screen) + D3DFORMAT m_backBufferFormat; // pixel format + uint m_multiSampleCount; // 0 means no MSAA, 2 means 2x MSAA, etc + // uint m_multiSampleQuality; // no MSAA quality control yet + + bool m_enableAutoDepthStencil; // generally set to 'TRUE' per CShaderDeviceDx8::SetPresentParameters + D3DFORMAT m_autoDepthStencilFormat; + + uint m_fsRefreshHz; // if full screen, this refresh rate (likely 0 for LCD's) + + //uint m_rootRendererID; // only used if m_rendererIndex is -1. + //uint m_rootDisplayMask; // only used if m_rendererIndex is -1. + + bool m_mtgl; // enable multi threaded GL driver +}; + +//=============================================================================== + +class GLMgr +{ +public: + + //=========================================================================== + // class methods - singleton + static void NewGLMgr( void ); // instantiate singleton.. + static GLMgr *aGLMgr( void ); // return singleton.. + static void DelGLMgr( void ); // tear down singleton.. + + //=========================================================================== + // plain methods + + #if 0 // turned all these off while new approach is coded + void RefreshDisplayDB( void ); // blow away old display DB, make a new one + GLMDisplayDB *GetDisplayDB( void ); // get a ptr to the one GLMgr keeps. only valid til next refresh. + + // eligible renderers will be ranked by desirability starting at index 0 within the db + // within each renderer, eligible displays will be ranked some kind of desirability (area? dist from menu bar?) + // within each display, eligible modes will be ranked by descending areas + + // calls supplying indices are implicitly making reference to the current DB + bool CaptureDisplay( int rendIndex, int displayIndex, bool captureAll ); // capture one display or all displays + void ReleaseDisplays( void ); // release all captures + + int GetDisplayMode( int rendIndex, int displayIndex ); // retrieve current display res (returns modeIndex) + void SetDisplayMode( GLMDisplayParams *params ); // set the display res (only useful for FS) + #endif + + GLMContext *NewContext( GLMDisplayParams *params ); // this will have to change + void DelContext( GLMContext *context ); + + // with usage of CGLMacro.h we could dispense with the "current context" thing + // and just declare a member variable of GLMContext, allowing each glXXX call to be routed directly + // to the correct context + void SetCurrentContext( GLMContext *context ); // make current in calling thread only + GLMContext *GetCurrentContext( void ); + +protected: + friend class GLMContext; + + GLMgr(); + ~GLMgr(); +}; + + +//===========================================================================// + +// helper function to do enable or disable in one step +inline void glSetEnable( GLenum which, bool enable ) +{ + if (enable) + gGL->glEnable(which); + else + gGL->glDisable(which); +} + +// helper function for int vs enum clarity +inline void glGetEnumv( GLenum which, GLenum *dst ) +{ + gGL->glGetIntegerv( which, (int*)dst ); +} + +//===========================================================================// +// +// types to support the GLMContext +// +//===========================================================================// + +// Each state set/get path we are providing caching for, needs its own struct and a comparison operator. +// we also provide an enum of how many such types there are, handy for building dirty masks etc. + +// shorthand macros +#define EQ(fff) ( (src.fff) == (fff) ) + +//rasterizer +struct GLAlphaTestEnable_t { GLint enable; bool operator==(const GLAlphaTestEnable_t& src) const { return EQ(enable); } }; +struct GLAlphaTestFunc_t { GLenum func; GLclampf ref; bool operator==(const GLAlphaTestFunc_t& src) const { return EQ(func) && EQ(ref); } }; +struct GLCullFaceEnable_t { GLint enable; bool operator==(const GLCullFaceEnable_t& src) const { return EQ(enable); } }; +struct GLCullFrontFace_t { GLenum value; bool operator==(const GLCullFrontFace_t& src) const { return EQ(value); } }; +struct GLPolygonMode_t { GLenum values[2]; bool operator==(const GLPolygonMode_t& src) const { return EQ(values[0]) && EQ(values[1]); } }; +struct GLDepthBias_t { GLfloat factor; GLfloat units; bool operator==(const GLDepthBias_t& src) const { return EQ(factor) && EQ(units); } }; +struct GLScissorEnable_t { GLint enable; bool operator==(const GLScissorEnable_t& src) const { return EQ(enable); } }; +struct GLScissorBox_t { GLint x,y; GLsizei width, height; bool operator==(const GLScissorBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } }; +struct GLAlphaToCoverageEnable_t{ GLint enable; bool operator==(const GLAlphaToCoverageEnable_t& src) const { return EQ(enable); } }; +struct GLViewportBox_t { GLint x,y; GLsizei width, height; bool operator==(const GLViewportBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } }; +struct GLViewportDepthRange_t { GLdouble near,far; bool operator==(const GLViewportDepthRange_t& src) const { return EQ(near) && EQ(far); } }; +struct GLClipPlaneEnable_t { GLint enable; bool operator==(const GLClipPlaneEnable_t& src) const { return EQ(enable); } }; +struct GLClipPlaneEquation_t { GLfloat x,y,z,w; bool operator==(const GLClipPlaneEquation_t& src) const { return EQ(x) && EQ(y) && EQ(z) && EQ(w); } }; + +//blend +struct GLColorMaskSingle_t { char r,g,b,a; bool operator==(const GLColorMaskSingle_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLColorMaskMultiple_t { char r,g,b,a; bool operator==(const GLColorMaskMultiple_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLBlendEnable_t { GLint enable; bool operator==(const GLBlendEnable_t& src) const { return EQ(enable); } }; +struct GLBlendFactor_t { GLenum srcfactor,dstfactor; bool operator==(const GLBlendFactor_t& src) const { return EQ(srcfactor) && EQ(dstfactor); } }; +struct GLBlendEquation_t { GLenum equation; bool operator==(const GLBlendEquation_t& src) const { return EQ(equation); } }; +struct GLBlendColor_t { GLfloat r,g,b,a; bool operator==(const GLBlendColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLBlendEnableSRGB_t { GLint enable; bool operator==(const GLBlendEnableSRGB_t& src) const { return EQ(enable); } }; + +//depth +struct GLDepthTestEnable_t { GLint enable; bool operator==(const GLDepthTestEnable_t& src) const { return EQ(enable); } }; +struct GLDepthFunc_t { GLenum func; bool operator==(const GLDepthFunc_t& src) const { return EQ(func); } }; +struct GLDepthMask_t { char mask; bool operator==(const GLDepthMask_t& src) const { return EQ(mask); } }; + +//stencil +struct GLStencilTestEnable_t { GLint enable; bool operator==(const GLStencilTestEnable_t& src) const { return EQ(enable); } }; +struct GLStencilFunc_t { GLenum frontfunc, backfunc; GLint ref; GLuint mask; bool operator==(const GLStencilFunc_t& src) const { return EQ(frontfunc) && EQ(backfunc) && EQ(ref) && EQ(mask); } }; +struct GLStencilOp_t { GLenum sfail; GLenum dpfail; GLenum dppass; bool operator==(const GLStencilOp_t& src) const { return EQ(sfail) && EQ(dpfail) && EQ(dppass); } }; +struct GLStencilWriteMask_t { GLint mask; bool operator==(const GLStencilWriteMask_t& src) const { return EQ(mask); } }; + +//clearing +struct GLClearColor_t { GLfloat r,g,b,a; bool operator==(const GLClearColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLClearDepth_t { GLdouble d; bool operator==(const GLClearDepth_t& src) const { return EQ(d); } }; +struct GLClearStencil_t { GLint s; bool operator==(const GLClearStencil_t& src) const { return EQ(s); } }; + +#undef EQ + +enum EGLMStateBlockType +{ + kGLAlphaTestEnable, + kGLAlphaTestFunc, + + kGLCullFaceEnable, + kGLCullFrontFace, + + kGLPolygonMode, + + kGLDepthBias, + + kGLScissorEnable, + kGLScissorBox, + + kGLViewportBox, + kGLViewportDepthRange, + + kGLClipPlaneEnable, + kGLClipPlaneEquation, + + kGLColorMaskSingle, + kGLColorMaskMultiple, + + kGLBlendEnable, + kGLBlendFactor, + kGLBlendEquation, + kGLBlendColor, + kGLBlendEnableSRGB, + + kGLDepthTestEnable, + kGLDepthFunc, + kGLDepthMask, + + kGLStencilTestEnable, + kGLStencilFunc, + kGLStencilOp, + kGLStencilWriteMask, + + kGLClearColor, + kGLClearDepth, + kGLClearStencil, + + kGLAlphaToCoverageEnable, + + kGLMStateBlockLimit +}; + +//===========================================================================// + +// templated functions representing GL R/W bottlenecks +// one set of set/get/getdefault is instantiated for each of the GL*** types above. + +// use these from the non array state objects +template void GLContextSet( T *src ); +template void GLContextGet( T *dst ); +template void GLContextGetDefault( T *dst ); + +// use these from the array state objects +template void GLContextSetIndexed( T *src, int index ); +template void GLContextGetIndexed( T *dst, int index ); +template void GLContextGetDefaultIndexed( T *dst, int index ); + +//===========================================================================// + +// caching state object template. One of these is instantiated in the context per unique struct type above +template class GLState +{ + public: + + GLState() + { + dirty = false; + memset( &data, 0, sizeof(data) ); + }; + + // write: client src into cache + // common case is both false. dirty is calculated, context write is deferred. + void Write( T *src, bool noCompare=false, bool noDefer=false ) + { + if (noCompare) + { + dirty = true; + } + else + { + // only == is implemented, so test for equal and negate + // note, you only set dirty if mismatch, you never clear it until flush + if ( !(data == *src) ) + { + dirty = true; + } + } + + data = *src; + + if (noDefer) + { + Flush( true ); // dirty becomes false + } + }; + + // write cache->context if dirty or forced. + void Flush( bool noDefer=false ) + { + if (dirty || noDefer) + { + GLContextSet( &data ); + GLMCheckError(); + // good place for some error checking here + dirty = false; + } + }; + + // default: write default value to cache, optionally write through + void Default( bool noDefer=false ) + { + GLContextGetDefault( &data ); // read default values directly to our cache copy + dirty = true; + Flush(noDefer); + }; + + // read: sel = 0 for cache, 1 for context + void Read( T *dst, int sel ) + { + if (sel==0) + { + *dst = data; + } + else + { + GLContextGet( dst ); + GLMCheckError(); + } + }; + + // check: verify that context equals cache, return true if mismatched or if illegal values seen + bool Check ( void ) + { + T temp; + bool result; + + GLContextGet( &temp ); + GLMCheckError(); + result = !(temp == data); + return result; + }; + + protected: + T data; + bool dirty; +}; + +// caching state object template - with multiple values behind it that are indexed +template class GLStateArray +{ + public: + + GLStateArray() + { + memset( &dirty, 0, sizeof(dirty) ); + memset( &data, 0, sizeof(data) ); + }; + + // write: client src into cache + // common case is both false. dirty is calculated, context write is deferred. + void WriteIndex( T *src, int index, bool noCompare=false, bool noDefer=false ) + { + if (noCompare) + { + dirty[index] = true; + } + else + { + // only == is implemented, so test for equal and negate + // note, you only set dirty if mismatch, you never clear it until flush + if (! (data[index] == *src) ) + { + dirty[index] = true; + } + } + + data[index] = *src; + + if (noDefer) + { + FlushIndex( index, true ); // dirty becomes false + } + }; + + // write cache->context if dirty or forced. + void FlushIndex( int index, bool noDefer=false ) + { + if (dirty[index] || noDefer) + { + GLContextSetIndexed( &data[index], index ); + GLMCheckError(); + dirty[index] = false; + } + }; + + // write all slots in the array + void Flush( bool noDefer=false ) + { + for( int i=0; i m_AlphaTestEnable; + + GLState m_AlphaTestFunc; + + GLState m_CullFaceEnable; + GLState m_CullFrontFace; + GLState m_PolygonMode; + + GLState m_DepthBias; + + GLStateArray m_ClipPlaneEnable; + GLStateArray m_ClipPlaneEquation; // dxabstract puts them directly into param slot 253(0) and 254(1) + + GLState m_ScissorEnable; + GLState m_ScissorBox; + + GLState m_AlphaToCoverageEnable; + + GLState m_ViewportBox; + GLState m_ViewportDepthRange; + + GLState m_ColorMaskSingle; + GLStateArray m_ColorMaskMultiple; // need an official constant for the color buffers limit + + GLState m_BlendEnable; + GLState m_BlendFactor; + GLState m_BlendEquation; + GLState m_BlendColor; + GLState m_BlendEnableSRGB; // write to this one to transmit intent to write SRGB encoded pixels to drawing FB + bool m_FakeBlendEnableSRGB; // writes to above will be shunted here if fake SRGB is in effect. + + GLState m_DepthTestEnable; + GLState m_DepthFunc; + GLState m_DepthMask; + + GLState m_StencilTestEnable; // global stencil test enable + GLState m_StencilFunc; // holds front and back stencil funcs + GLStateArray m_StencilOp; // indexed: 0=front 1=back + GLState m_StencilWriteMask; + + GLState m_ClearColor; + GLState m_ClearDepth; + GLState m_ClearStencil; + + // texture bindings and sampler setup + int m_activeTexture; // mirror for glActiveTexture + GLMTexSampler m_samplers[GLM_SAMPLER_COUNT]; + + // texture lock tracking - CGLMTex objects share usage of this + CUtlVector< GLMTexLockDesc > m_texLocks; + + // render target binding - check before draw + // similar to tex sampler mechanism, we track "bound" from "chosen for drawing" separately, + // so binding for creation/setup need not disrupt any notion of what will be used at draw time + + CGLMFBO *m_boundDrawFBO; // FBO on GL_DRAW_FRAMEBUFFER bind point + CGLMFBO *m_boundReadFBO; // FBO on GL_READ_FRAMEBUFFER bind point + // ^ both are set if you bind to GL_FRAMEBUFFER_EXT + + CGLMFBO *m_drawingFBO; // what FBO should be bound at draw time (to both read/draw bp's). + + CGLMFBO *m_blitReadFBO; + CGLMFBO *m_blitDrawFBO; // scratch FBO's for framebuffer blit + + CGLMFBO *m_scratchFBO[ kGLMScratchFBOCount ]; // general purpose FBO's for internal use + + CUtlVector< CGLMFBO* > m_fboTable; // each live FBO goes in the table + + // program bindings + EGLMProgramLang m_drawingLangAtFrameStart; // selector for start of frame (spills into m_drawingLang) + EGLMProgramLang m_drawingLang; // selector for which language we desire to draw with on the next batch + CGLMProgram *m_drawingProgram[ kGLMNumProgramTypes ]; + + GLMProgramParamsF m_programParamsF[ kGLMNumProgramTypes ]; + GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used + GLMProgramParamsI m_programParamsI[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used + EGLMParamWriteMode m_paramWriteMode; + + CGLMProgram *m_nullFragmentProgram; // write opaque black. Activate when caller asks for null FP + + CGLMProgram *m_preloadTexVertexProgram; // programs to help preload textures (dummies) + CGLMProgram *m_preload2DTexFragmentProgram; + CGLMProgram *m_preload3DTexFragmentProgram; + CGLMProgram *m_preloadCubeTexFragmentProgram; + + CGLMProgram *m_boundProgram[ kGLMNumProgramTypes ]; + + CGLMShaderPairCache *m_pairCache; // GLSL only + CGLMShaderPair *m_boundPair; // GLSL only + uint m_boundPairRevision; // GLSL only + GLhandleARB m_boundPairProgram; // GLSL only + + // buffer bindings + CGLMBuffer *m_lastKnownBufferBinds[ kGLMNumBufferTypes ]; // tracked per bind point for dupe-bind-absorb + GLMVertexAttributeDesc m_lastKnownVertexAttribs[ kGLMVertexAttributeIndexMax ]; // tracked per attrib for dupe-set-absorb + uint m_lastKnownVertexAttribMask; // tracked for dupe-enable-absorb + + CGLMBuffer *m_drawIndexBuffer; // ... ? do we need dupe tracking for index buffer setup? ? + + GLMVertexSetup m_drawVertexSetup; + + EGLMAttribWriteMode m_attribWriteMode; + + bool m_slowCheckEnable; // turn this on or no native checking is done ("-glmassertslow" or "-glmsspewslow") + bool m_slowAssertEnable; // turn this on to assert on a non-native batch "-glmassertslow" + bool m_slowSpewEnable; // turn this on to log non-native batches to stdout "-glmspewslow" + + // debug font texture + CGLMTex *m_debugFontTex; // might be NULL unless you call GenDebugFontTex + CGLMBuffer *m_debugFontIndices; // up to 1024 indices (256 chars times 4) + CGLMBuffer *m_debugFontVertices; // up to 1024 verts + + // batch/frame debugging support + int m_debugFrameIndex; // init to -1. Increment at BeginFrame + int m_debugBatchIndex; // init to -1. Increment at any draw call + +#if GLMDEBUG + // interactive (DebugHook) debug support + + // using these you can implement frame advance, batch single step, and batch rewind (let it run til next frame and hold on prev batch #) + int m_holdFrameBegin; // -1 if no hold req'd, otherwise # of frame to hold at (at beginframe time) + int m_holdFrameEnd; // -1 if no hold req'd, otherwise # of frame to hold at (at endframe time) + + int m_holdBatch,m_holdBatchFrame; // -1 if no hold, else # of batch&frame to hold at (both must be set) + // these can be expired/cleared to -1 if the frame passes without a hit + // may be desirable to re-pause in that event, as user was expecting a hold to occur + + bool m_debugDelayEnable; // allow sleep delay + uint m_debugDelay; // sleep time per hook call in microseconds (for usleep()) + + // pre-draw global toggles / options + bool m_autoClearColor,m_autoClearDepth,m_autoClearStencil; + float m_autoClearColorValues[4]; + + // debug knobs + int m_selKnobIndex; + float m_selKnobMinValue,m_selKnobMaxValue,m_selKnobIncrement; +#endif + +}; + +struct GLMTestParams +{ + GLMContext *m_ctx; + int *m_testList; // -1 termed + + bool m_glErrToDebugger; + bool m_glErrToConsole; + + bool m_intlErrToDebugger; + bool m_intlErrToConsole; + + int m_frameCount; // how many frames to test. +}; + +class GLMTester +{ + public: + + GLMTester(GLMTestParams *params); + ~GLMTester(); + + + // optionally callable by test routines to get basic drawables wired up + void StdSetup( void ); + void StdCleanup( void ); + + // callable by test routines to clear the frame or present it + void Clear( void ); + void Present( int seed ); + + // error reporting + void CheckGLError( char *comment ); // obey m_params setting for console / debugger response + void InternalError( int errcode, char *comment ); // if errcode!=0, obey m_params setting for console / debugger response + + void RunTests(); + + void RunOneTest( int testindex ); + + // test routines themselves + void Test0(); + void Test1(); + void Test2(); + void Test3(); + + GLMTestParams m_params; // copy of caller's params, do not mutate... + + // std-setup stuff + int m_drawWidth, m_drawHeight; + CGLMFBO *m_drawFBO; + CGLMTex *m_drawColorTex; + CGLMTex *m_drawDepthTex; +}; + +class CShowPixelsParams +{ +public: + GLuint m_srcTexName; + int m_width,m_height; + bool m_vsyncEnable; + bool m_fsEnable; // want receiving view to be full screen. for now, just target the main screen. extend later. + bool m_useBlit; // use FBO blit - sending context says it is available. + bool m_noBlit; // the back buffer has already been populated by the caller (perhaps via direct MSAA resolve from multisampled RT tex) + bool m_onlySyncView; // react to full/windowed state change only, do not present bits +}; + + +#define kMaxCrawlFrames 100 +#define kMaxCrawlText (kMaxCrawlFrames * 256) +class CStackCrawlParams +{ + public: + uint m_frameLimit; // input: max frames to retrieve + uint m_frameCount; // output: frames found + void *m_crawl[kMaxCrawlFrames]; // call site addresses + char *m_crawlNames[kMaxCrawlFrames]; // pointers into text following, one per decoded name + char m_crawlText[kMaxCrawlText]; +}; + +#endif diff --git a/public/togl/osx/glmgrbasics.h b/public/togl/osx/glmgrbasics.h new file mode 100644 index 00000000..d6476b3d --- /dev/null +++ b/public/togl/osx/glmgrbasics.h @@ -0,0 +1,299 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// glmgrbasics.h +// types, common headers, forward declarations, utilities +// +//=============================================================================== + +#ifndef GLMBASICS_H +#define GLMBASICS_H + +#pragma once + +#ifdef OSX +#include +#include +#include +#include +#include +#include +//#include +//#include +#elif defined(LINUX) +#include +#include +#else +#error +#endif + +#include "tier0/platform.h" + +#include "bitmap/imageformat.h" +#include "bitvec.h" +#include "tier1/checksum_md5.h" +#include "tier1/utlvector.h" +#include "tier1/convar.h" + +#include + +#include "dxabstract_types.h" + +// types +struct GLMRect; +typedef void *PseudoGLContextPtr; + + + // 3-d integer box (used for texture lock/unlock etc) +struct GLMRegion +{ + int xmin,xmax; + int ymin,ymax; + int zmin,zmax; +}; + +struct GLMRect // follows GL convention - if coming from the D3D rect you will need to fiddle the Y's +{ + int xmin; // left + int ymin; // bottom + int xmax; // right + int ymax; // top +}; + +// macros + +//#define GLMassert(x) assert(x) + +// forward decls +class GLMgr; // singleton +class GLMContext; // GL context +class CGLMContextTester; // testing class +class CGLMTex; +class CGLMFBO; +class CGLMProgram; +class CGLMBuffer; + + +// utilities + +typedef enum +{ + // D3D codes + eD3D_DEVTYPE, + eD3D_FORMAT, + eD3D_RTYPE, + eD3D_USAGE, + eD3D_RSTATE, // render state + eD3D_SIO, // D3D shader bytecode + eD3D_VTXDECLUSAGE, + + // CGL codes + eCGL_RENDID, + + // OpenGL error codes + eGL_ERROR, + + // OpenGL enums + eGL_ENUM, + eGL_RENDERER + +} GLMThing_t; + +const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const +const char* GLMDecodeMask( GLMThing_t type, unsigned long value ); // decode a bitmask + +void GLMStop( void ); // aka Debugger() +void GLMCheckError( bool noStop = false, bool noLog= false ); +void GLMEnableTrace( bool on ); + +// expose these in release now +// Mimic PIX events so we can decorate debug spew +void GLMBeginPIXEvent( const char *str ); +void GLMEndPIXEvent( void ); + +//=============================================================================== +// knob twiddling +//float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value +//float GLMKnobToggle( char *knobname ); + +//=============================================================================== +// other stuff + +// helpers for CGLSetOption - no op if no profiler +void GLMProfilerClearTrace( void ); +void GLMProfilerEnableTrace( bool enable ); + +// helpers for CGLSetParameter - no op if no profiler +void GLMProfilerDumpState( void ); + + +//=============================================================================== +// classes + +// helper class making function tracking easier to wire up +#if GLMDEBUG +class GLMFuncLogger +{ + public: + + // simple function log + GLMFuncLogger( const char *funcName ) + { + m_funcName = funcName; + m_earlyOut = false; + + GLMPrintf( ">%s", m_funcName ); + }; + + // more advanced version lets you pass args (i.e. called parameters or anything else of interest) + // no macro for this one, since no easy way to pass through the args as well as the funcname + GLMFuncLogger( const char *funcName, char *fmt, ... ) + { + m_funcName = funcName; + m_earlyOut = false; + + // this acts like GLMPrintf here + // all the indent policy is down in GLMPrintfVA + // which means we need to inject a ">" at the front of the format string to make this work... sigh. + + char modifiedFmt[2000]; + modifiedFmt[0] = '>'; + strcpy( modifiedFmt+1, fmt ); + + va_list vargs; + va_start(vargs, fmt); + GLMPrintfVA( modifiedFmt, vargs ); + va_end( vargs ); + } + + ~GLMFuncLogger( ) + { + if (m_earlyOut) + { + GLMPrintf( "<%s (early out)", m_funcName ); + } + else + { + GLMPrintf( "<%s", m_funcName ); + } + }; + + void EarlyOut( void ) + { + m_earlyOut = true; + }; + + const char *m_funcName; // set at construction time + bool m_earlyOut; +}; + +// handy macro to go with the function tracking class +#define GLM_FUNC GLMFuncLogger _logger_ ( __FUNCTION__ ) +#else +#define GLM_FUNC +#endif + + +// class to keep an in-memory mirror of a file which may be getting edited during run +class CGLMFileMirror +{ +public: + CGLMFileMirror( char *fullpath ); // just associates mirror with file. if file exists it will be read. + //if non existent it will be created with size zero + ~CGLMFileMirror( ); + + bool HasData( void ); // see if data avail + void GetData( char **dataPtr, uint *dataSizePtr ); // read it out + void SetData( char *data, uint dataSize ); // put data in (and write it to disk) + bool PollForChanges( void ); // check disk copy. If different, read it back in and return true. + + void UpdateStatInfo( void ); // make sure stat info is current for our file + void ReadFile( void ); + void WriteFile( void ); + + void OpenInEditor( bool foreground=false ); // pass TRUE if you would like the editor to pop to foreground + + /// how about a "wait for change" method.. + + char *m_path; // fullpath to file + bool m_exists; + struct stat m_stat; // stat results for the file (last time checked) + + char *m_data; // content of file + uint m_size; // length of content + +}; + +// class based on the file mirror, that makes it easy to edit them outside the app. + +// it receives an initial block of text from the engine, and hashes it. ("orig") +// it munges it by duplicating all the text after the "!!" line, and appending it in commented form. ("munged") +// a mirror file is activated, using a filename based on the hash from the orig text. +// if there is already content on disk matching that filename, use that content *unless* the 'blitz' parameter is set. +// (i.e. engine is instructing this subsystem to wipe out any old/modified variants of the text) + + +class CGLMEditableTextItem +{ +public: + CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix = NULL ); // create a text blob from text source, optional filename suffix + ~CGLMEditableTextItem( ); + + bool HasData( void ); + bool PollForChanges( void ); // return true if stale i.e. you need to get a new edition + void GetCurrentText( char **textOut, uint *sizeOut ); // query for read access to the active blob (could be the original, could be external edited copy) + void OpenInEditor( bool foreground=false ); // call user attention to this text + + // internal methods + void GenHashOfOrigText( void ); + void GenBaseNameAndFullPath( char *prefix, char *suffix ); + void GenMungedText( bool fromMirror ); + + // members + // orig + uint m_origSize; + char *m_origText; // what was submitted + unsigned char m_origDigest[MD5_DIGEST_LENGTH]; // digest of what was submitted + + // munged + uint m_mungedSize; + char *m_mungedText; // re-processed edition, initial content submission to the file mirror + + // mirror + char *m_mirrorBaseName; // generated from the hash of the orig text, plus the label / prefix + char *m_mirrorFullPath; // base name + CGLMFileMirror *m_mirror; // file mirror itself. holds "official" copy for GetCurrentText to return. +}; + + +// debug font +extern unsigned char g_glmDebugFontMap[16384]; + +// class for cracking multi-part text blobs +// sections are demarcated by beginning-of-line markers submitted in a table by the caller + +struct GLMTextSection +{ + int m_markerIndex; // based on table of markers passed in to constructor + uint m_textOffset; // where is the text - offset + int m_textLength; // how big is the section +}; + +class CGLMTextSectioner +{ +public: + CGLMTextSectioner( char *text, int textSize, char **markers ); // constructor finds all the sections + ~CGLMTextSectioner( ); + + int Count( void ); // how many sections found + void GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut ); + // find section, size, what marker + // note that more than one section can be marked similarly. + // so policy isn't made here, you walk the sections and decide what to do if there are dupes. + + //members + + //section table + CUtlVector< GLMTextSection > m_sectionTable; +}; + +#endif diff --git a/public/togl/osx/glmgrext.h b/public/togl/osx/glmgrext.h new file mode 100644 index 00000000..02939bb6 --- /dev/null +++ b/public/togl/osx/glmgrext.h @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// glmgrext.h +// helper file for extension testing and runtime importing of entry points +// +//=============================================================================== + +#pragma once + +#ifdef OSX +#include +#include +#elif defined(LINUX) +#include +#include +#else +#error +#endif + +#ifndef GL_EXT_framebuffer_sRGB + #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 + #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef ARB_texture_rg + #define GL_COMPRESSED_RED 0x8225 + #define GL_COMPRESSED_RG 0x8226 + #define GL_RG 0x8227 + #define GL_RG_INTEGER 0x8228 + #define GL_R8 0x8229 + #define GL_R16 0x822A + #define GL_RG8 0x822B + #define GL_RG16 0x822C + #define GL_R16F 0x822D + #define GL_R32F 0x822E + #define GL_RG16F 0x822F + #define GL_RG32F 0x8230 + #define GL_R8I 0x8231 + #define GL_R8UI 0x8232 + #define GL_R16I 0x8233 + #define GL_R16UI 0x8234 + #define GL_R32I 0x8235 + #define GL_R32UI 0x8236 + #define GL_RG8I 0x8237 + #define GL_RG8UI 0x8238 + #define GL_RG16I 0x8239 + #define GL_RG16UI 0x823A + #define GL_RG32I 0x823B + #define GL_RG32UI 0x823C +#endif + +#ifndef GL_EXT_bindable_uniform + #define GL_UNIFORM_BUFFER_EXT 0x8DEE +#endif + +// unpublished extension enums (thus the "X") + +// from EXT_framebuffer_multisample_blit_scaled.. +#define XGL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define XGL_SCALED_RESOLVE_NICEST_EXT 0x90BB + +#ifndef GL_TEXTURE_MINIMIZE_STORAGE_APPLE +#define GL_TEXTURE_MINIMIZE_STORAGE_APPLE 0x85B6 +#endif + +#ifndef GL_ALL_COMPLETED_NV +#define GL_ALL_COMPLETED_NV 0x84F2 +#endif + +#ifndef GL_MAP_READ_BIT +#define GL_MAP_READ_BIT 0x0001 +#endif + +#ifndef GL_MAP_WRITE_BIT +#define GL_MAP_WRITE_BIT 0x0002 +#endif + +#ifndef GL_MAP_INVALIDATE_RANGE_BIT +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#endif + +#ifndef GL_MAP_INVALIDATE_BUFFER_BIT +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#endif + +#ifndef GL_MAP_FLUSH_EXPLICIT_BIT +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#endif + +#ifndef GL_MAP_UNSYNCHRONIZED_BIT +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + diff --git a/public/togl/rendermechanism.h b/public/togl/rendermechanism.h index 47be332d..928021a5 100644 --- a/public/togl/rendermechanism.h +++ b/public/togl/rendermechanism.h @@ -1,27 +1,4 @@ //========= Copyright Valve Corporation, All rights reserved. ============// -// TOGL CODE LICENSE -// -// Copyright 2011-2014 Valve Corporation -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// #ifndef RENDERMECHANISM_H #define RENDERMECHANISM_H @@ -31,10 +8,11 @@ #include #include - #include "tier0/basetypes.h" #include "tier0/platform.h" +#if defined(LINUX) || defined(_WIN32) + #include "togl/linuxwin/glmdebug.h" #include "togl/linuxwin/glbase.h" #include "togl/linuxwin/glentrypoints.h" @@ -51,6 +29,25 @@ #include "togl/linuxwin/dxabstract_types.h" #include "togl/linuxwin/dxabstract.h" +#elif defined(OSX) +#include "togl/osx/glmdebug.h" +//#include "togl/osx/glbase.h" +#include "togl/osx/glentrypoints.h" +#include "togl/osx/glmdisplay.h" +#include "togl/osx/glmdisplaydb.h" +#include "togl/osx/glmgrbasics.h" +#include "togl/osx/glmgrext.h" +#include "togl/osx/cglmbuffer.h" +#include "togl/osx/cglmtex.h" +#include "togl/osx/cglmfbo.h" +#include "togl/osx/cglmprogram.h" +#include "togl/osx/cglmquery.h" +#include "togl/osx/glmgr.h" +#include "togl/osx/dxabstract_types.h" +#include "togl/osx/dxabstract.h" + +#endif + #else //USE_ACTUAL_DX #ifdef WIN32 diff --git a/public/toolframework/itoolentity.h b/public/toolframework/itoolentity.h index 38790ef2..7433c14a 100644 --- a/public/toolframework/itoolentity.h +++ b/public/toolframework/itoolentity.h @@ -32,9 +32,6 @@ class CBaseAnimating; class CTakeDamageInfo; class ITempEntsSystem; class IEntityFactoryDictionary; -class CBaseTempEntity; -class CGlobalEntityList; -class IEntityFindFilter; //----------------------------------------------------------------------------- @@ -220,35 +217,13 @@ class IServerTools : public IBaseInterface virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore ) = 0; virtual ITempEntsSystem *GetTempEntsSystem( void ) = 0; - virtual CBaseTempEntity *GetTempEntList( void ) = 0; - - virtual CGlobalEntityList *GetEntityList( void ) = 0; - virtual bool IsEntityPtr( void *pTest ) = 0; - virtual CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) = 0; - virtual CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL ) = 0; - virtual CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) = 0; - virtual CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName ) = 0; - virtual CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName ) = 0; - virtual CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; - virtual CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; - virtual CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius ) = 0; - virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius ) = 0; - virtual CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecMins, const Vector &vecMaxs ) = 0; - virtual CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; - virtual CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; - virtual CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; - virtual CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold ) = 0; - virtual CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname ) = 0; - virtual CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) = 0; }; typedef IServerTools IServerTools001; -typedef IServerTools IServerTools002; #define VSERVERTOOLS_INTERFACE_VERSION_1 "VSERVERTOOLS001" -#define VSERVERTOOLS_INTERFACE_VERSION_2 "VSERVERTOOLS002" -#define VSERVERTOOLS_INTERFACE_VERSION "VSERVERTOOLS003" -#define VSERVERTOOLS_INTERFACE_VERSION_INT 3 +#define VSERVERTOOLS_INTERFACE_VERSION "VSERVERTOOLS002" +#define VSERVERTOOLS_INTERFACE_VERSION_INT 2 //----------------------------------------------------------------------------- // Purpose: Client side tool interace (right now just handles IClientRenderables). diff --git a/public/vallocator.h b/public/vallocator.h index ea26dbe6..d9f2130a 100644 --- a/public/vallocator.h +++ b/public/vallocator.h @@ -53,16 +53,16 @@ class DummyAllocatorHelper inline void* operator new(size_t size, void *ptr, DummyAllocatorHelper *asdf) { - (void)asdf; // Suppress unused-variable compiler warnings. - (void)size; + asdf=asdf; // compiler warning. + size=size; return ptr; } inline void operator delete(void *ptrToDelete, void *ptr, DummyAllocatorHelper *asdf) { - (void)asdf; // Suppress unused-variable compiler warnings. - (void)ptr; - (void)ptrToDelete; + asdf=asdf; // compiler warning. + ptr=ptr; + ptrToDelete=ptrToDelete; } // Use these to manually construct and destruct lists of objects. diff --git a/public/vgui/ISurface.h b/public/vgui/ISurface.h index 4ec58997..6289bd59 100644 --- a/public/vgui/ISurface.h +++ b/public/vgui/ISurface.h @@ -19,6 +19,7 @@ #include "appframework/IAppSystem.h" #include "mathlib/vector2d.h" // must be before the namespace line +#include #include "IVguiMatInfo.h" @@ -383,7 +384,7 @@ class ISurface : public IAppSystem virtual const char *GetWebkitHTMLUserAgentString() = 0; - virtual void *Deprecated_AccessChromeHTMLController() = 0; + virtual IHTMLChromeController *AccessChromeHTMLController() = 0; // the origin of the viewport on the framebuffer (Which might not be 0,0 for stereo) virtual void SetFullscreenViewport( int x, int y, int w, int h ) = 0; // this uses NULL for the render target. diff --git a/public/vgui/MouseCode.h b/public/vgui/MouseCode.h index 7ba16214..9b13fc81 100644 --- a/public/vgui/MouseCode.h +++ b/public/vgui/MouseCode.h @@ -18,6 +18,15 @@ namespace vgui { typedef ButtonCode_t MouseCode; + +static inline int MouseButtonBit(MouseCode code) +{ + if (code < MOUSE_FIRST || code > MOUSE_LAST) { + Assert(false); + return 0; + } + return 1 << (code - MOUSE_FIRST); +} } #endif // MOUSECODE_H diff --git a/public/vgui/VGUI.h b/public/vgui/VGUI.h index 34fddfeb..cd2e9650 100644 --- a/public/vgui/VGUI.h +++ b/public/vgui/VGUI.h @@ -66,10 +66,12 @@ const HFont INVALID_FONT = 0; // the value of an invalid font handle #include "tier1/strtools.h" -#if 0 // defined( OSX ) // || defined( LINUX ) -// Disabled all platforms. Did a major cleanup of osxfont.cpp, and having this -// turned off renders much closer to Windows and Linux and also uses the same -// code paths (which is good). +#if defined( OSX ) // || defined( LINUX ) +// Set to 1 to use GetKernedCharWidth() instead of GetCharABCwide(). Alfred +// initially started using that code on the Mac because it did better +// kerning, but he was a leery about switching win32 over. I enabled this +// for Linux, but it causes some strings to look different than Windows. So +// I've disabled it for now. mikesart - 12/2012. #define USE_GETKERNEDCHARWIDTH 1 #else #define USE_GETKERNEDCHARWIDTH 0 diff --git a/public/vgui_controls/AnimationController.h b/public/vgui_controls/AnimationController.h index 93ae7096..f4163e48 100644 --- a/public/vgui_controls/AnimationController.h +++ b/public/vgui_controls/AnimationController.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -16,6 +16,10 @@ #include "tier1/utlsymbol.h" #include "tier1/utlvector.h" +#ifdef MAPBASE +extern bool g_bUsingCustomHudAnimations; +#endif + namespace vgui { @@ -39,7 +43,7 @@ class AnimationController : public Panel // runs a frame of animation (time is passed in so slow motion, etc. works) void UpdateAnimations( float curtime ); - + int GetNumActiveAnimations( void ) { return m_ActiveAnimations.Count(); } // plays all animations to completion instantly @@ -52,9 +56,6 @@ class AnimationController : public Panel bool StartAnimationSequence(const char *sequenceName); bool StartAnimationSequence(Panel *pWithinParent, const char *sequenceName); - bool StopAnimationSequence( Panel *pWithinParent, const char *sequenceName ); - void CancelAnimationsForPanel( Panel *pWithinParent ); - // gets the length of an animation sequence, in seconds float GetAnimationSequenceLength(const char *sequenceName); @@ -79,7 +80,7 @@ class AnimationController : public Panel private: bool UpdateScreenSize(); - + bool LoadScriptFile(const char *fileName); bool ParseScriptFile(char *pMem, int length); @@ -99,9 +100,6 @@ class AnimationController : public Panel CMD_SETFONT, CMD_SETTEXTURE, CMD_SETSTRING, - CMD_RUNEVENTCHILD, - CMD_FIRECOMMAND, - CMD_SETVISIBLE, }; enum RelativeAlignment @@ -205,7 +203,7 @@ class AnimationController : public Panel // posted messages struct PostedMessage_t { - AnimCommandType_e commandType; + AnimCommandType_e commandType; UtlSymId_t seqName; UtlSymId_t event; UtlSymId_t variable; @@ -219,7 +217,7 @@ class AnimationController : public Panel { UtlSymId_t event; Panel *pParent; - + bool operator==( const RanEvent_t &other ) const { return ( event == other.event && pParent == other.pParent ); @@ -229,7 +227,6 @@ class AnimationController : public Panel // variable names UtlSymId_t m_sPosition, m_sSize, m_sFgColor, m_sBgColor; UtlSymId_t m_sXPos, m_sYPos, m_sWide, m_sTall; - UtlSymId_t m_sModelPos; // file name CUtlVector m_ScriptFileNames; diff --git a/public/vgui_controls/ComboBox.h b/public/vgui_controls/ComboBox.h index 266f4dc2..c5c3eba0 100644 --- a/public/vgui_controls/ComboBox.h +++ b/public/vgui_controls/ComboBox.h @@ -63,7 +63,7 @@ class ComboBox : public TextEntry virtual int AddItem(const char *itemText, const KeyValues *userData); virtual int AddItem(const wchar_t *itemText, const KeyValues *userData); - virtual int GetItemCount() const; + virtual int GetItemCount(); int GetItemIDFromRow( int row ); // update the item diff --git a/public/vgui_controls/HTML.h b/public/vgui_controls/HTML.h index ad786d20..24b043af 100644 --- a/public/vgui_controls/HTML.h +++ b/public/vgui_controls/HTML.h @@ -24,6 +24,7 @@ #endif #include "steam/steam_api.h" +class HTMLComboBoxHost; namespace vgui { @@ -79,7 +80,7 @@ class HTML: public Panel // overridden to paint our special web browser texture virtual void Paint(); - + // pass messages to the texture component to tell it about resizes virtual void OnSizeChanged(int wide,int tall); @@ -123,7 +124,7 @@ class HTML: public Panel void AddHeader( const char *pchHeader, const char *pchValue ); void OnKillFocus(); void OnSetFocus(); - + void Find( const char *pchSubStr ); void StopFind(); void FindNext(); @@ -146,6 +147,7 @@ class HTML: public Panel } #endif // DBGFLAG_VALIDATE + void PaintComboBox(); ISteamHTMLSurface *SteamHTMLSurface() { return m_SteamAPIContext.SteamHTMLSurface(); } void OnHTMLMouseMoved( int x, int y ) @@ -157,13 +159,16 @@ class HTML: public Panel protected: virtual void ApplySchemeSettings( IScheme *pScheme ); + friend class HTMLComboBoxHost; vgui::Menu *m_pContextMenu; + private: STEAM_CALLBACK( HTML, BrowserNeedsPaint, HTML_NeedsPaint_t, m_NeedsPaint ); STEAM_CALLBACK( HTML, BrowserStartRequest, HTML_StartRequest_t, m_StartRequest ); STEAM_CALLBACK( HTML, BrowserURLChanged, HTML_URLChanged_t, m_URLChanged ); STEAM_CALLBACK( HTML, BrowserFinishedRequest, HTML_FinishedRequest_t, m_FinishedRequest ); + STEAM_CALLBACK( HTML, BrowserOpenNewTab, HTML_OpenLinkInNewTab_t, m_LinkInNewTab ); STEAM_CALLBACK( HTML, BrowserSetHTMLTitle, HTML_ChangedTitle_t, m_ChangeTitle ); STEAM_CALLBACK( HTML, BrowserPopupHTMLWindow, HTML_NewWindow_t, m_NewWindow ); @@ -218,6 +223,7 @@ class HTML: public Panel }; CHTMLFindBar *m_pFindBar; + HTMLComboBoxHost *m_pComboBoxHost; int m_iMouseX,m_iMouseY; // where the mouse is on the control @@ -245,7 +251,10 @@ class HTML: public Panel // when the size has changed and reallocate the texture. int m_allocedTextureWidth; int m_allocedTextureHeight; - bool m_bNeedsFullTextureUpload; + int m_iComboBoxTextureID; // vgui texture id of the combo box + bool m_bNeedsFullTextureUpload; + int m_allocedComboBoxWidth; + int m_allocedComboBoxHeight; CUtlString m_sCurrentURL; // the url of our current page // find in page state bool m_bInFind; diff --git a/public/vgui_controls/Menu.h b/public/vgui_controls/Menu.h index 77937335..2b374373 100644 --- a/public/vgui_controls/Menu.h +++ b/public/vgui_controls/Menu.h @@ -216,7 +216,7 @@ class Menu : public Panel virtual int GetActiveItem(); // returns the itemID (not the row) of the active item // Return the number of items currently in the menu list - virtual int GetItemCount() const; + virtual int GetItemCount(); // return the menuID of the n'th item in the menu list, valid from [0, GetItemCount) virtual int GetMenuID(int index); @@ -351,29 +351,6 @@ class Menu : public Panel double m_fLastTypeAheadTime; }; - -//----------------------------------------------------------------------------- -// Helper class to create menu -//----------------------------------------------------------------------------- -class MenuBuilder -{ -public: - - MenuBuilder( Menu *pMenu, Panel *pActionTarget ); - - MenuItem* AddMenuItem( const char *pszButtonText, const char *pszCommand, const char *pszCategoryName ); - - MenuItem* AddCascadingMenuItem( const char *pszButtonText, Menu *pSubMenu, const char *pszCategoryName ); - -private: - - void AddSepratorIfNeeded( const char *pszCategoryName ); - - Menu *m_pMenu; - Panel *m_pActionTarget; - const char *m_pszLastCategory; -}; - } // namespace vgui #endif // MENU_H diff --git a/public/vgui_controls/Panel.h b/public/vgui_controls/Panel.h index a507d3af..9413b603 100644 --- a/public/vgui_controls/Panel.h +++ b/public/vgui_controls/Panel.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //===========================================================================// @@ -29,7 +29,7 @@ #include "tier1/utlsymbol.h" #include "vgui_controls/BuildGroup.h" -// undefine windows function macros that overlap +// undefine windows function macros that overlap #ifdef PostMessage #undef PostMessage #endif @@ -139,7 +139,7 @@ class IForceVirtualInheritancePanel // This is designed as an easy-access to the vgui-functionality; for more // low-level access to vgui functions use the IPanel/IClientPanel interfaces directly //----------------------------------------------------------------------------- -class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel +class Panel : public IClientPanel, virtual public IForceVirtualInheritancePanel { DECLARE_CLASS_SIMPLE_NOBASE( Panel ); @@ -180,8 +180,6 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel // all units are in pixels void SetPos(int x,int y); // sets position of panel, in local space (ie. relative to parent's position) void GetPos(int &x,int &y); // gets local position of panel - int GetXPos(); - int GetYPos(); void SetSize(int wide,int tall); // sets size of panel void GetSize(int &wide, int &tall); // gets size of panel void SetBounds(int x, int y, int wide, int tall); // combination of SetPos/SetSize @@ -225,7 +223,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel virtual void SetParent(Panel *newParent); virtual void SetParent(VPANEL newParent); virtual bool HasParent(VPANEL potentialParent); - + int GetChildCount(); Panel *GetChild(int index); virtual CUtlVector< VPANEL > &GetChildren(); @@ -234,7 +232,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel Panel *FindSiblingByName(const char *siblingName); void CallParentFunction(KeyValues *message); - template < class T > + template T *FindControl( const char *pszName, bool recurseDown = false ) { return dynamic_cast( FindChildByName( pszName, recurseDown ) ); } virtual void SetAutoDelete(bool state); // if set to true, panel automatically frees itself when parent is deleted @@ -264,7 +262,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel virtual void MoveToFront(); // pin positions for auto-layout - enum PinCorner_e + enum PinCorner_e { PIN_TOPLEFT = 0, PIN_TOPRIGHT, @@ -276,8 +274,6 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel PIN_CENTER_RIGHT, PIN_CENTER_BOTTOM, PIN_CENTER_LEFT, - - PIN_LAST }; // specifies the auto-resize directions for the panel @@ -391,7 +387,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel virtual void OnThink(); // called every frame before painting, but only if panel is visible virtual void OnChildAdded(VPANEL child); // called when a child has been added to this panel virtual void OnSizeChanged(int newWide, int newTall); // called after the size of a panel has been changed - + // called every frame if ivgui()->AddTickSignal() is called virtual void OnTick(); @@ -402,7 +398,6 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel virtual void OnMousePressed(MouseCode code); virtual void OnMouseDoublePressed(MouseCode code); virtual void OnMouseReleased(MouseCode code); - virtual void OnMouseMismatchedRelease( MouseCode code, Panel* pPressedPanel ); virtual void OnMouseWheeled(int delta); // Trip pressing (e.g., select all text in a TextEntry) requires this to be enabled @@ -451,7 +446,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel void RevertKeyBindingsToDefault(); void RemoveAllKeyBindings(); - void ReloadKeyBindings(); + void ReloadKeyBindings(); virtual void EditKeyBindings(); // calls RevertKeyBindingsToDefault() and then LoadKeyBindingsForOnePanel( GetKeyBindingsContext(), this ); @@ -466,7 +461,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel bool IsKeyBindingChainToParentAllowed() const; #endif // VGUI_USEKEYBINDINGMAPS - // base implementation forwards Key messages to the Panel's parent + // base implementation forwards Key messages to the Panel's parent // - override to 'swallow' the input virtual void OnKeyCodePressed(KeyCode code); virtual void OnKeyCodeTyped(KeyCode code); @@ -517,7 +512,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel //============================================================================= // HPE_BEGIN: //============================================================================= - + // [menglish] Draws a hollow box similar to the already existing draw hollow box function, but takes the indents as params virtual void DrawHollowBox( int x, int y, int wide, int tall, Color color, float normalizedAlpha, int cornerWide, int cornerTall ); @@ -528,7 +523,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel bool ShouldDrawTopRightCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_TOP_RIGHT ) != 0; } bool ShouldDrawBottomLeftCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_LEFT ) != 0; } bool ShouldDrawBottomRightCornerRounded() { return ( m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_RIGHT ) != 0; } - + //============================================================================= // HPE_END //============================================================================= @@ -672,8 +667,6 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel virtual void PaintTraverse(bool Repaint, bool allowForce = true); protected: - virtual void OnChildSettingsApplied( KeyValues *pInResourceData, Panel *pChild ); - MESSAGE_FUNC_ENUM_ENUM( OnRequestFocus, "OnRequestFocus", VPANEL, subFocus, VPANEL, defaultPanel); MESSAGE_FUNC_INT_INT( OnScreenSizeChanged, "OnScreenSizeChanged", oldwide, oldtall ); virtual void *QueryInterface(EInterfaceID id); @@ -702,7 +695,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel Will recursively look for the next visible panel in the navigation chain, parameters are for internal use. It will stop looking if first == nextpanel (to prevent infinite looping). */ - Panel* GetNavUp( Panel *first = NULL ); + Panel* GetNavUp( Panel *first = NULL ); Panel* GetNavDown( Panel *first = NULL ); Panel* GetNavLeft( Panel *first = NULL ); Panel* GetNavRight( Panel *first = NULL ); @@ -792,7 +785,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel MESSAGE_FUNC_INT_INT( InternalCursorMoved, "CursorMoved", xpos, ypos ); MESSAGE_FUNC( InternalCursorEntered, "CursorEntered" ); MESSAGE_FUNC( InternalCursorExited, "CursorExited" ); - + MESSAGE_FUNC_INT( InternalMousePressed, "MousePressed", code ); MESSAGE_FUNC_INT( InternalMouseDoublePressed, "MouseDoublePressed", code ); // Triple presses are synthesized @@ -920,8 +913,6 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel bool m_bForceStereoRenderToFrameBuffer; - static Panel* m_sMousePressedPanels[ ( MOUSE_MIDDLE - MOUSE_LEFT ) + 1 ]; - CPanelAnimationVar( float, m_flAlpha, "alpha", "255" ); // 1 == Textured (TextureId1 only) @@ -939,7 +930,7 @@ class Panel : public IClientPanel, virtual IForceVirtualInheritancePanel unsigned char m_roundedCorners; //============================================================================= // HPE_END - //============================================================================= + //============================================================================= friend class BuildGroup; friend class BuildModeDialog; friend class PHandle; @@ -958,7 +949,6 @@ inline bool Panel::IsMouseInputDisabledForThisPanel() const return _flags.IsFlagSet( IS_MOUSE_DISABLED_FOR_THIS_PANEL_ONLY ); } - // This function cannot be defined here because it requires on a full definition of // KeyValues (to call KeyValues::MakeCopy()) whereas the rest of this header file // assumes a forward declared definition of KeyValues. @@ -984,7 +974,6 @@ inline void Panel::PostMessageToAllSiblingsOfType( KeyValues *msg, float delaySe msg->deleteThis(); } - class Button; struct SortedPanel_t @@ -1020,7 +1009,7 @@ class CSortedPanelYLess void VguiPanelGetSortedChildPanelList( Panel *pParentPanel, void *pSortedPanels ); -void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, char *pchFilter = NULL, int nFilterType = 0 ); +void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, const char *pchFilter = NULL, int nFilterType = 0 ); int VguiPanelNavigateSortedChildButtonList( void *pSortedPanels, int nDir ); diff --git a/public/vgui_controls/SectionedListPanel.h b/public/vgui_controls/SectionedListPanel.h index 6fafedd3..c38f6c74 100644 --- a/public/vgui_controls/SectionedListPanel.h +++ b/public/vgui_controls/SectionedListPanel.h @@ -210,8 +210,6 @@ class SectionedListPanel : public Panel void MoveSelectionDown( void ); void MoveSelectionUp( void ); - ScrollBar *GetScrollBar( void ) { return m_pScrollBar; } - protected: virtual void PerformLayout(); virtual void ApplySchemeSettings(IScheme *pScheme); diff --git a/public/vgui_controls/TextImage.h b/public/vgui_controls/TextImage.h index 20446e7b..a410cb95 100644 --- a/public/vgui_controls/TextImage.h +++ b/public/vgui_controls/TextImage.h @@ -105,8 +105,10 @@ class TextImage : public Image void SetColorChangeStream( CUtlSortVector *pUtlVecStream ); void ClearColorChangeStream( void ) { m_ColorChangeStream.Purge(); } - const wchar_t *GetEllipsesPosition( void ) const { return m_pwszEllipsesPosition; } - bool IsWrapping() const { return m_LineBreaks.Count() != 0; } +#ifdef MAPBASE + // Gets the relative y coordinates of all new lines created by newline (\n) characters. + void GetNewlinePositions( CUtlVector *pOutCoords, bool bIgnoreEmptyLines = true ); +#endif protected: // truncate the _text string to fit into the draw width diff --git a/public/vscript/ivscript.h b/public/vscript/ivscript.h new file mode 100644 index 00000000..58f981e0 --- /dev/null +++ b/public/vscript/ivscript.h @@ -0,0 +1,2101 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: VScript +// +// Overview +// -------- +// VScript is an abstract binding layer that allows code to expose itself to +// multiple scripting languages in a uniform format. Code can expose +// functions, classes, and data to the scripting languages, and can also +// call functions that reside in scripts. +// +// Initializing +// ------------ +// +// To create a script virtual machine (VM), grab the global instance of +// IScriptManager, call CreateVM, then call Init on the returned VM. Right +// now you can have multiple VMs, but only VMs for a specific language. +// +// Exposing functions and classes +// ------------------------------ +// +// To expose a C++ function to the scripting system, you just need to fill out a +// description block. Using templates, the system will automatically deduce +// all of the binding requirements (parameters and return values). Functions +// are limited as to what the types of the parameters can be. See ScriptVariant_t. +// +// extern IScriptVM *pScriptVM; +// bool Foo( int ); +// void Bar(); +// float FooBar( int, const char * ); +// float OverlyTechnicalName( bool ); +// +// void RegisterFuncs() +// { +// ScriptRegisterFunction( pScriptVM, Foo ); +// ScriptRegisterFunction( pScriptVM, Bar ); +// ScriptRegisterFunction( pScriptVM, FooBar ); +// ScriptRegisterFunctionNamed( pScriptVM, OverlyTechnicalName, "SimpleName" ); +// } +// +// class CMyClass +// { +// public: +// bool Foo( int ); +// void Bar(); +// float FooBar( int, const char * ); +// float OverlyTechnicalName( bool ); +// }; +// +// BEGIN_SCRIPTDESC_ROOT( CMyClass ) +// DEFINE_SCRIPTFUNC( Foo ) +// DEFINE_SCRIPTFUNC( Bar ) +// DEFINE_SCRIPTFUNC( FooBar ) +// DEFINE_SCRIPTFUNC_NAMED( OverlyTechnicalName, "SimpleMemberName" ) +// END_SCRIPTDESC(); +// +// class CMyDerivedClass : public CMyClass +// { +// public: +// float DerivedFunc() const; +// }; +// +// BEGIN_SCRIPTDESC( CMyDerivedClass, CMyClass ) +// DEFINE_SCRIPTFUNC( DerivedFunc ) +// END_SCRIPTDESC(); +// +// CMyDerivedClass derivedInstance; +// +// void AnotherFunction() +// { +// // Manual class exposure +// pScriptVM->RegisterClass( GetScriptDescForClass( CMyClass ) ); +// +// // Auto registration by instance +// pScriptVM->RegisterInstance( &derivedInstance, "theInstance" ); +// } +// +// Classes with "DEFINE_SCRIPT_CONSTRUCTOR()" in their description can be instanced within scripts +// +// Scopes +// ------ +// Scripts can either be run at the global scope, or in a user defined scope. In the latter case, +// all "globals" within the script are actually in the scope. This can be used to bind private +// data spaces with C++ objects. +// +// Calling a function on a script +// ------------------------------ +// Generally, use the "Call" functions. This example is the equivalent of DoIt("Har", 6.0, 99). +// +// hFunction = pScriptVM->LookupFunction( "DoIt", hScope ); +// pScriptVM->Call( hFunction, hScope, true, NULL, "Har", 6.0, 99 ); +// +//============================================================================= + +#ifndef IVSCRIPT_H +#define IVSCRIPT_H + +#include +#include + +#include "utlmap.h" +#include "utlvector.h" + +#include "platform.h" +#include "datamap.h" +#include "appframework/IAppSystem.h" +#include "tier1/functors.h" +#include "tier0/memdbgon.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifdef VSCRIPT_DLL_EXPORT +#define VSCRIPT_INTERFACE DLL_EXPORT +#define VSCRIPT_OVERLOAD DLL_GLOBAL_EXPORT +#define VSCRIPT_CLASS DLL_CLASS_EXPORT +#else +#define VSCRIPT_INTERFACE DLL_IMPORT +#define VSCRIPT_OVERLOAD DLL_GLOBAL_IMPORT +#define VSCRIPT_CLASS DLL_CLASS_IMPORT +#endif + +class CUtlBuffer; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define VSCRIPT_INTERFACE_VERSION "VScriptManager009" + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +class IScriptVM; +#ifdef MAPBASE_VSCRIPT +class KeyValues; + +// This has been moved up a bit for IScriptManager +DECLARE_POINTER_HANDLE( HSCRIPT ); +#define INVALID_HSCRIPT ((HSCRIPT)-1) + +typedef unsigned int HScriptRaw; +#endif + +enum ScriptLanguage_t +{ + SL_NONE, + SL_GAMEMONKEY, + SL_SQUIRREL, + SL_LUA, + SL_PYTHON, + + SL_DEFAULT = SL_SQUIRREL +}; + +class IScriptManager : public IAppSystem +{ +public: + virtual IScriptVM *CreateVM( ScriptLanguage_t language = SL_DEFAULT ) = 0; + virtual void DestroyVM( IScriptVM * ) = 0; + +#ifdef MAPBASE_VSCRIPT + virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bAllowDestruct ) = 0; + virtual KeyValues *GetKeyValuesFromScriptKV( IScriptVM *pVM, HSCRIPT hSKV ) = 0; +#endif +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum ExtendedFieldType +{ + FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT, + FIELD_CSTRING, + FIELD_HSCRIPT, + FIELD_VARIANT, +}; + +typedef int ScriptDataType_t; +struct ScriptVariant_t; + +template struct ScriptDeducer { /*enum { FIELD_TYPE = FIELD_TYPEUNKNOWN };*/ }; +#define DECLARE_DEDUCE_FIELDTYPE( fieldType, type ) template<> struct ScriptDeducer { enum { FIELD_TYPE = fieldType }; }; + +DECLARE_DEDUCE_FIELDTYPE( FIELD_VOID, void ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_FLOAT, float ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CSTRING, const char * ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CSTRING, char * ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, Vector ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, const Vector &); +DECLARE_DEDUCE_FIELDTYPE( FIELD_INTEGER, int ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_BOOLEAN, bool ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_CHARACTER, char ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_HSCRIPT, HSCRIPT ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VARIANT, ScriptVariant_t ); +#ifdef MAPBASE_VSCRIPT +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, QAngle ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, const QAngle& ); +#endif + +#define ScriptDeduceType( T ) ScriptDeducer::FIELD_TYPE + +template +inline const char * ScriptFieldTypeName() +{ + return T::using_unknown_script_type(); +} + +#define DECLARE_NAMED_FIELDTYPE( fieldType, strName ) template <> inline const char * ScriptFieldTypeName() { return strName; } +DECLARE_NAMED_FIELDTYPE( void, "void" ); +DECLARE_NAMED_FIELDTYPE( float, "float" ); +DECLARE_NAMED_FIELDTYPE( const char *, "cstring" ); +DECLARE_NAMED_FIELDTYPE( char *, "cstring" ); +DECLARE_NAMED_FIELDTYPE( Vector, "vector" ); +DECLARE_NAMED_FIELDTYPE( const Vector&, "vector" ); +DECLARE_NAMED_FIELDTYPE( int, "integer" ); +DECLARE_NAMED_FIELDTYPE( bool, "boolean" ); +DECLARE_NAMED_FIELDTYPE( char, "character" ); +DECLARE_NAMED_FIELDTYPE( HSCRIPT, "hscript" ); +DECLARE_NAMED_FIELDTYPE( ScriptVariant_t, "variant" ); +#ifdef MAPBASE_VSCRIPT +DECLARE_NAMED_FIELDTYPE( QAngle, "vector" ); +DECLARE_NAMED_FIELDTYPE( const QAngle&, "vector" ); +#endif + +inline const char * ScriptFieldTypeName( int16 eType) +{ + switch( eType ) + { + case FIELD_VOID: return "void"; + case FIELD_FLOAT: return "float"; + case FIELD_CSTRING: return "cstring"; + case FIELD_VECTOR: return "vector"; + case FIELD_INTEGER: return "integer"; + case FIELD_BOOLEAN: return "boolean"; + case FIELD_CHARACTER: return "character"; + case FIELD_HSCRIPT: return "hscript"; + case FIELD_VARIANT: return "variant"; + default: return "unknown_script_type"; + } +} + +//--------------------------------------------------------- + +struct ScriptFuncDescriptor_t +{ + ScriptFuncDescriptor_t() + { + m_pszFunction = NULL; + m_ReturnType = FIELD_TYPEUNKNOWN; + m_pszDescription = NULL; + } + + const char *m_pszScriptName; + const char *m_pszFunction; + const char *m_pszDescription; + ScriptDataType_t m_ReturnType; + CUtlVector m_Parameters; +}; + +#ifdef MAPBASE_VSCRIPT +//--------------------------------------------------------- +// VScript Member Variables +// +// An odd concept. Because IScriptInstanceHelper now supports +// get/set metamethods, classes are capable of pretending they +// have member variables which VScript can get and set. +// +// There's no default way of documenting these variables, so even though +// these are not actually binding anything, this is here to allow VScript +// to describe these fake member variables in its documentation. +//--------------------------------------------------------- +struct ScriptMemberDesc_t +{ + const char *m_pszScriptName; + const char *m_pszDescription; + ScriptDataType_t m_ReturnType; +}; +#endif + + +//--------------------------------------------------------- + +// Prefix a script description with this in order to not show the function or class in help +#define SCRIPT_HIDE "@" + +// Prefix a script description of a class to indicate it is a singleton and the single instance should be in the help +#define SCRIPT_SINGLETON "!" + +// Prefix a script description with this to indicate it should be represented using an alternate name +#define SCRIPT_ALIAS( alias, description ) "#" alias ":" description + +//--------------------------------------------------------- + +enum ScriptFuncBindingFlags_t +{ + SF_MEMBER_FUNC = 0x01, +}; + +typedef bool (*ScriptBindingFunc_t)( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ); + +struct ScriptFunctionBinding_t +{ + ScriptFuncDescriptor_t m_desc; + ScriptBindingFunc_t m_pfnBinding; + void * m_pFunction; + unsigned m_flags; +}; + +//--------------------------------------------------------- +class IScriptInstanceHelper +{ +public: + virtual void *GetProxied( void *p ) { return p; } + virtual bool ToString( void *p, char *pBuf, int bufSize ) { return false; } + virtual void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId ) { return NULL; } + +#ifdef MAPBASE_VSCRIPT + virtual bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ) { return false; } + virtual bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ) { return false; } + + virtual ScriptVariant_t *Add( void *p, ScriptVariant_t &variant ) { return NULL; } + virtual ScriptVariant_t *Subtract( void *p, ScriptVariant_t &variant ) { return NULL; } + virtual ScriptVariant_t *Multiply( void *p, ScriptVariant_t &variant ) { return NULL; } + virtual ScriptVariant_t *Divide( void *p, ScriptVariant_t &variant ) { return NULL; } +#endif +}; + +//--------------------------------------------------------- + +#ifdef MAPBASE_VSCRIPT +struct ScriptHook_t; +#endif + +struct ScriptClassDesc_t +{ + ScriptClassDesc_t() : m_pszScriptName( 0 ), m_pszClassname( 0 ), m_pszDescription( 0 ), m_pBaseDesc( 0 ), m_pfnConstruct( 0 ), m_pfnDestruct( 0 ), pHelper(NULL) + { +#ifdef MAPBASE_VSCRIPT + AllClassesDesc().AddToTail(this); +#endif + } + + const char * m_pszScriptName; + const char * m_pszClassname; + const char * m_pszDescription; + ScriptClassDesc_t * m_pBaseDesc; + CUtlVector m_FunctionBindings; + +#ifdef MAPBASE_VSCRIPT + CUtlVector m_Hooks; + CUtlVector m_Members; +#endif + + void *(*m_pfnConstruct)(); + void (*m_pfnDestruct)( void *); + IScriptInstanceHelper * pHelper; // optional helper + +#ifdef MAPBASE_VSCRIPT + static CUtlVector& AllClassesDesc() + { + static CUtlVector classes; + return classes; + } +#endif +}; + +//--------------------------------------------------------- +// A simple variant type. Intentionally not full featured (no implicit conversion, no memory management) +//--------------------------------------------------------- + +enum SVFlags_t +{ + SV_FREE = 0x01, +}; + +#pragma warning(push) +#pragma warning(disable:4800) +struct ScriptVariant_t +{ + ScriptVariant_t() : m_flags( 0 ), m_type( FIELD_VOID ) { m_pVector = 0; } + ScriptVariant_t( int val ) : m_flags( 0 ), m_type( FIELD_INTEGER ) { m_int = val;} + ScriptVariant_t( float val ) : m_flags( 0 ), m_type( FIELD_FLOAT ) { m_float = val; } + ScriptVariant_t( double val ) : m_flags( 0 ), m_type( FIELD_FLOAT ) { m_float = (float)val; } + ScriptVariant_t( char val ) : m_flags( 0 ), m_type( FIELD_CHARACTER ) { m_char = val; } + ScriptVariant_t( bool val ) : m_flags( 0 ), m_type( FIELD_BOOLEAN ) { m_bool = val; } + ScriptVariant_t( HSCRIPT val ) : m_flags( 0 ), m_type( FIELD_HSCRIPT ) { m_hScript = val; } + + ScriptVariant_t( const Vector &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pVector = &val; } else { m_pVector = new Vector( val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const Vector *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pVector = val; } else { m_pVector = new Vector( *val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const char *val , bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_CSTRING ) { if ( !bCopy ) { m_pszString = val; } else { m_pszString = strdup( val ); m_flags |= SV_FREE; } } + +#ifdef MAPBASE_VSCRIPT + ScriptVariant_t( const QAngle &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = &val; } else { m_pAngle = new QAngle( val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const QAngle *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = val; } else { m_pAngle = new QAngle( *val ); m_flags |= SV_FREE; } } +#endif + + bool IsNull() const { return (m_type == FIELD_VOID ); } + + operator int() const { Assert( m_type == FIELD_INTEGER ); return m_int; } + operator float() const { Assert( m_type == FIELD_FLOAT ); return m_float; } + operator const char *() const { Assert( m_type == FIELD_CSTRING ); return ( m_pszString ) ? m_pszString : ""; } + operator const Vector &() const { Assert( m_type == FIELD_VECTOR ); static Vector vecNull(0, 0, 0); return (m_pVector) ? *m_pVector : vecNull; } + operator char() const { Assert( m_type == FIELD_CHARACTER ); return m_char; } + operator bool() const { Assert( m_type == FIELD_BOOLEAN ); return m_bool; } + operator HSCRIPT() const { Assert( m_type == FIELD_HSCRIPT ); return m_hScript; } +#ifdef MAPBASE_VSCRIPT + operator const QAngle &() const { Assert( m_type == FIELD_VECTOR ); static QAngle vecNull(0, 0, 0); return (m_pAngle) ? *m_pAngle : vecNull; } +#endif + + void operator=( int i ) { m_type = FIELD_INTEGER; m_int = i; } + void operator=( float f ) { m_type = FIELD_FLOAT; m_float = f; } + void operator=( double f ) { m_type = FIELD_FLOAT; m_float = (float)f; } + void operator=( const Vector &vec ) { m_type = FIELD_VECTOR; m_pVector = &vec; } + void operator=( const Vector *vec ) { m_type = FIELD_VECTOR; m_pVector = vec; } + void operator=( const char *psz ) { m_type = FIELD_CSTRING; m_pszString = psz; } + void operator=( char c ) { m_type = FIELD_CHARACTER; m_char = c; } + void operator=( bool b ) { m_type = FIELD_BOOLEAN; m_bool = b; } + void operator=( HSCRIPT h ) { m_type = FIELD_HSCRIPT; m_hScript = h; } +#ifdef MAPBASE_VSCRIPT + void operator=( const QAngle &vec ) { m_type = FIELD_VECTOR; m_pAngle = &vec; } + void operator=( const QAngle *vec ) { m_type = FIELD_VECTOR; m_pAngle = vec; } +#endif + + void Free() { if ( ( m_flags & SV_FREE ) && ( m_type == FIELD_HSCRIPT || m_type == FIELD_VECTOR || m_type == FIELD_CSTRING ) ) delete m_pszString; } // Generally only needed for return results + + template + T Get() + { + T value; + AssignTo( &value ); + return value; + } + + template + bool AssignTo( T *pDest ) + { + ScriptDataType_t destType = ScriptDeduceType( T ); + if ( destType == FIELD_TYPEUNKNOWN ) + { + DevWarning( "Unable to convert script variant to unknown type\n" ); + } + if ( destType == m_type ) + { + *pDest = *this; + return true; + } + + if ( m_type != FIELD_VECTOR && m_type != FIELD_CSTRING && destType != FIELD_VECTOR && destType != FIELD_CSTRING ) + { + switch ( m_type ) + { + case FIELD_VOID: *pDest = 0; break; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_CHARACTER: *pDest = m_char; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + case FIELD_HSCRIPT: *pDest = m_hScript; return true; + } + } + else + { + DevWarning( "No free conversion of %s script variant to %s right now\n", + ScriptFieldTypeName( m_type ), ScriptFieldTypeName() ); + if ( destType != FIELD_VECTOR ) + { + *pDest = 0; + } + } + return false; + } + + bool AssignTo( float *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to float now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( int *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to int now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( bool *pDest ) + { + switch( m_type ) + { + case FIELD_VOID: *pDest = 0; return false; + case FIELD_INTEGER: *pDest = m_int; return true; + case FIELD_FLOAT: *pDest = m_float; return true; + case FIELD_BOOLEAN: *pDest = m_bool; return true; + default: + DevWarning( "No conversion from %s to bool now\n", ScriptFieldTypeName( m_type ) ); + return false; + } + } + + bool AssignTo( char **pDest ) + { + DevWarning( "No free conversion of string or vector script variant right now\n" ); + // If want to support this, probably need to malloc string and require free on other side [3/24/2008 tom] + *pDest = ""; + return false; + } + + bool AssignTo( ScriptVariant_t *pDest ) + { + pDest->m_type = m_type; + if ( m_type == FIELD_VECTOR ) + { + pDest->m_pVector = new Vector; + ((Vector *)(pDest->m_pVector))->Init( m_pVector->x, m_pVector->y, m_pVector->z ); + pDest->m_flags |= SV_FREE; + } + else if ( m_type == FIELD_CSTRING ) + { + pDest->m_pszString = strdup( m_pszString ); + pDest->m_flags |= SV_FREE; + } + else + { + pDest->m_int = m_int; + } + return false; + } + + union + { + int m_int; + float m_float; + const char * m_pszString; + const Vector * m_pVector; + char m_char; + bool m_bool; + HSCRIPT m_hScript; +#ifdef MAPBASE_VSCRIPT + // This uses FIELD_VECTOR, so it's considered a Vector in the VM (just like save/restore) + const QAngle * m_pAngle; +#endif + }; + + int16 m_type; + int16 m_flags; + +private: +}; + +#define SCRIPT_VARIANT_NULL ScriptVariant_t() + +#ifdef MAPBASE_VSCRIPT +//--------------------------------------------------------- +struct ScriptConstantBinding_t +{ + const char *m_pszScriptName; + const char *m_pszDescription; + ScriptVariant_t m_data; + unsigned m_flags; +}; + +//--------------------------------------------------------- +struct ScriptEnumDesc_t +{ + ScriptEnumDesc_t() : m_pszScriptName( 0 ), m_pszDescription( 0 ), m_flags( 0 ) + { + AllEnumsDesc().AddToTail(this); + } + + virtual void RegisterDesc() = 0; + + const char *m_pszScriptName; + const char *m_pszDescription; + CUtlVector m_ConstantBindings; + unsigned m_flags; + + static CUtlVector& AllEnumsDesc() + { + static CUtlVector enums; + return enums; + } +}; +#endif + +#pragma warning(pop) + + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#include "vscript_templates.h" + +// Lower level macro primitives +#define ScriptInitFunctionBinding( pScriptFunction, func ) ScriptInitFunctionBindingNamed( pScriptFunction, func, #func ) +#define ScriptInitFunctionBindingNamed( pScriptFunction, func, scriptName ) do { ScriptInitFuncDescriptorNamed( (&(pScriptFunction)->m_desc), func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( &func ); (pScriptFunction)->m_pFunction = (void *)&func; } while (0) + +#define ScriptInitMemberFunctionBinding( pScriptFunction, class, func ) ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, #func ) +#define ScriptInitMemberFunctionBindingNamed( pScriptFunction, class, func, scriptName ) ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) +#define ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) do { ScriptInitMemberFuncDescriptor_( (&(pScriptFunction)->m_desc), class, func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( ((class *)0), &class::func ); (pScriptFunction)->m_pFunction = ScriptConvertFuncPtrToVoid( &class::func ); (pScriptFunction)->m_flags = SF_MEMBER_FUNC; } while (0) + +#define ScriptInitClassDesc( pClassDesc, class, pBaseClassDesc ) ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, #class ) +#define ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, scriptName ) ScriptInitClassDescNamed_( pClassDesc, class, pBaseClassDesc, scriptName ) +#define ScriptInitClassDescNoBase( pClassDesc, class ) ScriptInitClassDescNoBaseNamed( pClassDesc, class, #class ) +#define ScriptInitClassDescNoBaseNamed( pClassDesc, class, scriptName ) ScriptInitClassDescNamed_( pClassDesc, class, NULL, scriptName ) +#define ScriptInitClassDescNamed_( pClassDesc, class, pBaseClassDesc, scriptName ) do { (pClassDesc)->m_pszScriptName = scriptName; (pClassDesc)->m_pszClassname = #class; (pClassDesc)->m_pBaseDesc = pBaseClassDesc; } while ( 0 ) + +#define ScriptAddFunctionToClassDesc( pClassDesc, class, func, description ) ScriptAddFunctionToClassDescNamed( pClassDesc, class, func, #func, description ) +#define ScriptAddFunctionToClassDescNamed( pClassDesc, class, func, scriptName, description ) do { ScriptFunctionBinding_t *pBinding = &((pClassDesc)->m_FunctionBindings[(pClassDesc)->m_FunctionBindings.AddToTail()]); pBinding->m_desc.m_pszDescription = description; ScriptInitMemberFunctionBindingNamed( pBinding, class, func, scriptName ); } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define ScriptRegisterFunction( pVM, func, description ) ScriptRegisterFunctionNamed( pVM, func, #func, description ) +#define ScriptRegisterFunctionNamed( pVM, func, scriptName, description ) do { static ScriptFunctionBinding_t binding; binding.m_desc.m_pszDescription = description; binding.m_desc.m_Parameters.RemoveAll(); ScriptInitFunctionBindingNamed( &binding, func, scriptName ); pVM->RegisterFunction( &binding ); } while (0) + +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +// forwards T (and T&) if T is neither enum or an unsigned integer +// the overload for int below captures enums and unsigned integers and "bends" them to int +template +static inline typename std::enable_if::type>::value && !std::is_unsigned::type>::value, T&&>::type ToConstantVariant(T &&value) +{ + return std::forward(value); +} + +static inline int ToConstantVariant(int value) +{ + return value; +} + +#define ScriptRegisterConstant( pVM, constant, description ) ScriptRegisterConstantNamed( pVM, constant, #constant, description ) +#define ScriptRegisterConstantNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ToConstantVariant(constant); pVM->RegisterConstant( &binding ); } while (0) + +// Could probably use a better name. +// This is used for registering variants (particularly vectors) not tied to existing variables. +// The principal difference is that m_data is initted with bCopy set to true. +#define ScriptRegisterConstantFromTemp( pVM, constant, description ) ScriptRegisterConstantFromTempNamed( pVM, constant, #constant, description ) +#define ScriptRegisterConstantFromTempNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ScriptVariant_t( constant, true ); pVM->RegisterConstant( &binding ); } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define BEGIN_SCRIPTENUM( enumName, description ) \ + struct ScriptEnum##enumName##Desc_t : public ScriptEnumDesc_t \ + { \ + void RegisterDesc(); \ + }; \ + ScriptEnum##enumName##Desc_t g_##enumName##_EnumDesc; \ + \ + void ScriptEnum##enumName##Desc_t::RegisterDesc() \ + { \ + static bool bInitialized; \ + if ( bInitialized ) \ + return; \ + \ + bInitialized = true; \ + \ + m_pszScriptName = #enumName; \ + m_pszDescription = description; \ + +#define DEFINE_ENUMCONST( constant, description ) DEFINE_ENUMCONST_NAMED( constant, #constant, description ) +#define DEFINE_ENUMCONST_NAMED( constant, scriptName, description ) do { ScriptConstantBinding_t *pBinding = &(m_ConstantBindings[m_ConstantBindings.AddToTail()]); pBinding->m_pszScriptName = scriptName; pBinding->m_pszDescription = description; pBinding->m_data = constant; pBinding->m_flags = SF_MEMBER_FUNC; } while (0); + +#define END_SCRIPTENUM() \ + } \ + + +#define GetScriptDescForEnum( enumName ) GetScriptDesc( ( className *)NULL ) +#endif + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define ALLOW_SCRIPT_ACCESS() template friend ScriptClassDesc_t *GetScriptDesc(T *); + +#define BEGIN_SCRIPTDESC( className, baseClass, description ) BEGIN_SCRIPTDESC_NAMED( className, baseClass, #className, description ) +#define BEGIN_SCRIPTDESC_ROOT( className, description ) BEGIN_SCRIPTDESC_ROOT_NAMED( className, #className, description ) + +#define BEGIN_SCRIPTDESC_NAMED( className, baseClass, scriptName, description ) \ + template <> ScriptClassDesc_t* GetScriptDesc(baseClass*); \ + template <> ScriptClassDesc_t* GetScriptDesc(className*); \ + ScriptClassDesc_t & g_##className##_ScriptDesc = *GetScriptDesc(nullptr); \ + template <> ScriptClassDesc_t* GetScriptDesc(className*) \ + { \ + static ScriptClassDesc_t g_##className##_ScriptDesc; \ + typedef className _className; \ + ScriptClassDesc_t *pDesc = &g_##className##_ScriptDesc; \ + if (pDesc->m_pszClassname) return pDesc; \ + pDesc->m_pszDescription = description; \ + ScriptInitClassDescNamed( pDesc, className, GetScriptDescForClass( baseClass ), scriptName ); \ + ScriptClassDesc_t *pInstanceHelperBase = pDesc->m_pBaseDesc; \ + while ( pInstanceHelperBase ) \ + { \ + if ( pInstanceHelperBase->pHelper ) \ + { \ + pDesc->pHelper = pInstanceHelperBase->pHelper; \ + break; \ + } \ + pInstanceHelperBase = pInstanceHelperBase->m_pBaseDesc; \ + } + + +#define BEGIN_SCRIPTDESC_ROOT_NAMED( className, scriptName, description ) \ + BEGIN_SCRIPTDESC_NAMED( className, ScriptNoBase_t, scriptName, description ) + +#define END_SCRIPTDESC() \ + return pDesc; \ + } + +#define DEFINE_SCRIPTFUNC( func, description ) DEFINE_SCRIPTFUNC_NAMED( func, #func, description ) +#define DEFINE_SCRIPTFUNC_NAMED( func, scriptName, description ) ScriptAddFunctionToClassDescNamed( pDesc, _className, func, scriptName, description ); +#define DEFINE_SCRIPT_CONSTRUCTOR() ScriptAddConstructorToClassDesc( pDesc, _className ); +#define DEFINE_SCRIPT_INSTANCE_HELPER( p ) pDesc->pHelper = (p); + +#ifdef MAPBASE_VSCRIPT +// Use this for hooks which have no parameters +#define DEFINE_SIMPLE_SCRIPTHOOK( hook, hookName, returnType, description ) \ + if (!hook.m_bDefined) \ + { \ + ScriptHook_t *pHook = &hook; \ + pHook->m_desc.m_pszScriptName = hookName; pHook->m_desc.m_pszFunction = #hook; pHook->m_desc.m_ReturnType = returnType; pHook->m_desc.m_pszDescription = description; \ + pDesc->m_Hooks.AddToTail(pHook); \ + } + +#define BEGIN_SCRIPTHOOK( hook, hookName, returnType, description ) \ + if (!hook.m_bDefined) \ + { \ + ScriptHook_t *pHook = &hook; \ + pHook->m_desc.m_pszScriptName = hookName; pHook->m_desc.m_pszFunction = #hook; pHook->m_desc.m_ReturnType = returnType; pHook->m_desc.m_pszDescription = description; + +#define DEFINE_SCRIPTHOOK_PARAM( paramName, type ) pHook->AddParameter( paramName, type ); + +#define END_SCRIPTHOOK() \ + pDesc->m_Hooks.AddToTail(pHook); \ + } + +// Static hooks (or "global" hooks) are not tied to specific classes +#define END_SCRIPTHOOK_STATIC( pVM ) \ + pVM->RegisterHook( pHook ); \ + } + +#define ScriptRegisterSimpleHook( pVM, hook, hookName, returnType, description ) \ + if (!hook.m_bDefined) \ + { \ + ScriptHook_t *pHook = &hook; \ + pHook->m_desc.m_pszScriptName = hookName; pHook->m_desc.m_pszFunction = #hook; pHook->m_desc.m_ReturnType = returnType; pHook->m_desc.m_pszDescription = description; \ + pVM->RegisterHook( pHook ); \ + } + +#define ScriptRegisterConstant( pVM, constant, description ) ScriptRegisterConstantNamed( pVM, constant, #constant, description ) +#define ScriptRegisterConstantNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ToConstantVariant(constant); pVM->RegisterConstant( &binding ); } while (0) + + +#define DEFINE_MEMBERVAR( varName, returnType, description ) \ + do { ScriptMemberDesc_t *pBinding = &((pDesc)->m_Members[(pDesc)->m_Members.AddToTail()]); pBinding->m_pszScriptName = varName; pBinding->m_pszDescription = description; pBinding->m_ReturnType = returnType; } while (0); +#endif + +template ScriptClassDesc_t *GetScriptDesc(T *); + +struct ScriptNoBase_t; +template <> inline ScriptClassDesc_t *GetScriptDesc( ScriptNoBase_t *) { return NULL; } + +#define GetScriptDescForClass( className ) GetScriptDesc( ( className *)NULL ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +template +class CScriptConstructor +{ +public: + static void *Construct() { return new T; } + static void Destruct( void *p ) { delete (T *)p; } +}; + +#define ScriptAddConstructorToClassDesc( pClassDesc, class ) do { (pClassDesc)->m_pfnConstruct = &CScriptConstructor::Construct; (pClassDesc)->m_pfnDestruct = &CScriptConstructor::Destruct; } while (0) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum ScriptErrorLevel_t +{ + SCRIPT_LEVEL_WARNING = 0, + SCRIPT_LEVEL_ERROR, +}; + +typedef void ( *ScriptOutputFunc_t )( const char *pszText ); +typedef bool ( *ScriptErrorFunc_t )( ScriptErrorLevel_t eLevel, const char *pszText ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#ifdef RegisterClass +#undef RegisterClass +#endif + +enum ScriptStatus_t +{ + SCRIPT_ERROR = -1, + SCRIPT_DONE, + SCRIPT_RUNNING, +}; + +class IScriptVM +{ +public: + virtual ~IScriptVM() {} + + virtual bool Init() = 0; + virtual void Shutdown() = 0; + + virtual bool ConnectDebugger() = 0; + virtual void DisconnectDebugger() = 0; + + virtual ScriptLanguage_t GetLanguage() = 0; + virtual const char *GetLanguageName() = 0; + + virtual void AddSearchPath( const char *pszSearchPath ) = 0; + + //-------------------------------------------------------- + + virtual bool Frame( float simTime ) = 0; + + //-------------------------------------------------------- + // Simple script usage + //-------------------------------------------------------- + virtual ScriptStatus_t Run( const char *pszScript, bool bWait = true ) = 0; + inline ScriptStatus_t Run( const unsigned char *pszScript, bool bWait = true ) { return Run( (char *)pszScript, bWait ); } + + //-------------------------------------------------------- + // Compilation + //-------------------------------------------------------- + virtual HSCRIPT CompileScript( const char *pszScript, const char *pszId = NULL ) = 0; + inline HSCRIPT CompileScript( const unsigned char *pszScript, const char *pszId = NULL ) { return CompileScript( (char *)pszScript, pszId ); } + virtual void ReleaseScript( HSCRIPT ) = 0; + + //-------------------------------------------------------- + // Execution of compiled + //-------------------------------------------------------- + virtual ScriptStatus_t Run( HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true ) = 0; + virtual ScriptStatus_t Run( HSCRIPT hScript, bool bWait ) = 0; + + //-------------------------------------------------------- + // Scope + //-------------------------------------------------------- + virtual HSCRIPT CreateScope( const char *pszScope, HSCRIPT hParent = NULL ) = 0; + virtual void ReleaseScope( HSCRIPT hScript ) = 0; + + //-------------------------------------------------------- + // Script functions + //-------------------------------------------------------- + virtual HSCRIPT LookupFunction( const char *pszFunction, HSCRIPT hScope = NULL ) = 0; + virtual void ReleaseFunction( HSCRIPT hScript ) = 0; + + //-------------------------------------------------------- + // Script functions (raw, use Call()) + //-------------------------------------------------------- + virtual ScriptStatus_t ExecuteFunction( HSCRIPT hFunction, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) = 0; + +#ifdef MAPBASE_VSCRIPT + //-------------------------------------------------------- + // Hooks + //-------------------------------------------------------- + // Persistent unique identifier for an HSCRIPT variable + virtual HScriptRaw HScriptToRaw( HSCRIPT val ) = 0; + virtual ScriptStatus_t ExecuteHookFunction( const char *pszEventName, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) = 0; +#endif + + //-------------------------------------------------------- + // External functions + //-------------------------------------------------------- + virtual void RegisterFunction( ScriptFunctionBinding_t *pScriptFunction ) = 0; + + //-------------------------------------------------------- + // External classes + //-------------------------------------------------------- + virtual bool RegisterClass( ScriptClassDesc_t *pClassDesc ) = 0; + +#ifdef MAPBASE_VSCRIPT + //-------------------------------------------------------- + // External constants + //-------------------------------------------------------- + virtual void RegisterConstant( ScriptConstantBinding_t *pScriptConstant ) = 0; + + //-------------------------------------------------------- + // External enums + //-------------------------------------------------------- + virtual void RegisterEnum( ScriptEnumDesc_t *pEnumDesc ) = 0; + + //-------------------------------------------------------- + // External hooks + //-------------------------------------------------------- + virtual void RegisterHook( ScriptHook_t *pHookDesc ) = 0; +#endif + + //-------------------------------------------------------- + // External instances. Note class will be auto-registered. + //-------------------------------------------------------- + +#ifdef MAPBASE_VSCRIPT + // When a RegisterInstance instance is deleted, VScript normally treats it as a strong reference and only deregisters the instance itself, preserving the registered data + // it points to so the game can continue to use it. + // bAllowDestruct is supposed to allow VScript to treat it as a weak reference created by the script, destructing the registered data automatically like any other type. + // This is useful for classes pretending to be primitive types. + virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance, bool bAllowDestruct = false ) = 0; + virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) = 0; + template HSCRIPT RegisterInstance( T *pInstance, bool bAllowDestruct = false ) { return RegisterInstance( GetScriptDesc( pInstance ), pInstance, bAllowDestruct ); } + template HSCRIPT RegisterInstance( T *pInstance, const char *pszInstance, HSCRIPT hScope = NULL, bool bAllowDestruct = false) { HSCRIPT hInstance = RegisterInstance( GetScriptDesc( pInstance ), pInstance, bAllowDestruct ); SetValue( hScope, pszInstance, hInstance ); return hInstance; } +#else + virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance ) = 0; + virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) = 0; + template HSCRIPT RegisterInstance( T *pInstance ) { return RegisterInstance( GetScriptDesc( pInstance ), pInstance ); } + template HSCRIPT RegisterInstance( T *pInstance, const char *pszInstance, HSCRIPT hScope = NULL) { HSCRIPT hInstance = RegisterInstance( GetScriptDesc( pInstance ), pInstance ); SetValue( hScope, pszInstance, hInstance ); return hInstance; } +#endif + virtual void RemoveInstance( HSCRIPT ) = 0; + void RemoveInstance( HSCRIPT hInstance, const char *pszInstance, HSCRIPT hScope = NULL ) { ClearValue( hScope, pszInstance ); RemoveInstance( hInstance ); } + void RemoveInstance( const char *pszInstance, HSCRIPT hScope = NULL ) { ScriptVariant_t val; if ( GetValue( hScope, pszInstance, &val ) ) { if ( val.m_type == FIELD_HSCRIPT ) { RemoveInstance( val, pszInstance, hScope ); } ReleaseValue( val ); } } + + virtual void *GetInstanceValue( HSCRIPT hInstance, ScriptClassDesc_t *pExpectedType = NULL ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool GenerateUniqueKey( const char *pszRoot, char *pBuf, int nBufSize ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool ValueExists( HSCRIPT hScope, const char *pszKey ) = 0; + bool ValueExists( const char *pszKey ) { return ValueExists( NULL, pszKey ); } + + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) = 0; + virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) = 0; + bool SetValue( const char *pszKey, const ScriptVariant_t &value ) { return SetValue(NULL, pszKey, value ); } +#ifdef MAPBASE_VSCRIPT + virtual bool SetValue( HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val ) = 0; +#endif + + virtual void CreateTable( ScriptVariant_t &Table ) = 0; + virtual int GetNumTableEntries( HSCRIPT hScope ) = 0; + virtual int GetKeyValue( HSCRIPT hScope, int nIterator, ScriptVariant_t *pKey, ScriptVariant_t *pValue ) = 0; + + virtual bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) = 0; + bool GetValue( const char *pszKey, ScriptVariant_t *pValue ) { return GetValue(NULL, pszKey, pValue ); } +#ifdef MAPBASE_VSCRIPT + virtual bool GetValue( HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue ) = 0; +#endif + virtual void ReleaseValue( ScriptVariant_t &value ) = 0; + + virtual bool ClearValue( HSCRIPT hScope, const char *pszKey ) = 0; + bool ClearValue( const char *pszKey) { return ClearValue( NULL, pszKey ); } +#ifdef MAPBASE_VSCRIPT + virtual bool ClearValue( HSCRIPT hScope, ScriptVariant_t pKey ) = 0; +#endif + +#ifdef MAPBASE_VSCRIPT + virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0; + virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0; +#endif + + //---------------------------------------------------------------------------- + + virtual void WriteState( CUtlBuffer *pBuffer ) = 0; + virtual void ReadState( CUtlBuffer *pBuffer ) = 0; + virtual void RemoveOrphanInstances() = 0; + + virtual void DumpState() = 0; + + virtual void SetOutputCallback( ScriptOutputFunc_t pFunc ) = 0; + virtual void SetErrorCallback( ScriptErrorFunc_t pFunc ) = 0; + + //---------------------------------------------------------------------------- + + virtual bool RaiseException( const char *pszExceptionText ) = 0; + + //---------------------------------------------------------------------------- + // Call API + // + // Note for string and vector return types, the caller must delete the pointed to memory + //---------------------------------------------------------------------------- + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope = NULL, bool bWait = true, ScriptVariant_t *pReturn = NULL ) + { + return ExecuteFunction( hFunction, NULL, 0, pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, HSCRIPT hScope, bool bWait, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + return ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, hScope, bWait ); + } + +#ifdef MAPBASE_VSCRIPT + void RegisterAllClasses() + { + CUtlVector& classDescs = ScriptClassDesc_t::AllClassesDesc(); + FOR_EACH_VEC(classDescs, i) + { + RegisterClass(classDescs[i]); + } + } + + void RegisterAllEnums() + { + CUtlVector& enumDescs = ScriptEnumDesc_t::AllEnumsDesc(); + FOR_EACH_VEC(enumDescs, i) + { + enumDescs[i]->RegisterDesc(); + RegisterEnum(enumDescs[i]); + } + } +#endif +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#ifdef MAPBASE_VSCRIPT +template T *HScriptToClass( HSCRIPT hObj ) +{ + extern IScriptVM *g_pScriptVM; + return (hObj) ? (T*)g_pScriptVM->GetInstanceValue( hObj, GetScriptDesc( (T*)NULL ) ) : NULL; +} +#else +DECLARE_POINTER_HANDLE( HSCRIPT ); +#define INVALID_HSCRIPT ((HSCRIPT)-1) +#endif + +//----------------------------------------------------------------------------- +// Script scope helper class +//----------------------------------------------------------------------------- + +class CDefScriptScopeBase +{ +public: + static IScriptVM *GetVM() + { + extern IScriptVM *g_pScriptVM; + return g_pScriptVM; + } +}; + +template +class CScriptScopeT : public CDefScriptScopeBase +{ +public: + CScriptScopeT() : + m_hScope( INVALID_HSCRIPT ), + m_flags( 0 ) + { + } + + ~CScriptScopeT() + { + Term(); + } + + bool IsInitialized() + { + return m_hScope != INVALID_HSCRIPT; + } + + bool Init( const char *pszName ) + { + m_hScope = GetVM()->CreateScope( pszName ); + return ( m_hScope != NULL ); + } + + bool Init( HSCRIPT hScope, bool bExternal = true ) + { + if ( bExternal ) + { + m_flags |= EXTERNAL; + } + m_hScope = hScope; + return ( m_hScope != NULL ); + } + + bool InitGlobal() + { + Assert( 0 ); // todo [3/24/2008 tom] + m_hScope = GetVM()->CreateScope( "" ); + return ( m_hScope != NULL ); + } + + void Term() + { + if ( m_hScope != INVALID_HSCRIPT ) + { + IScriptVM *pVM = GetVM(); + if ( pVM ) + { + for ( int i = 0; i < m_FuncHandles.Count(); i++ ) + { + pVM->ReleaseFunction( *m_FuncHandles[i] ); + } + } + m_FuncHandles.Purge(); + if ( m_hScope && pVM && !(m_flags & EXTERNAL) ) + { + pVM->ReleaseScope( m_hScope ); + } + m_hScope = INVALID_HSCRIPT; + } + m_flags = 0; + } + + void InvalidateCachedValues() + { + IScriptVM *pVM = GetVM(); + for ( int i = 0; i < m_FuncHandles.Count(); i++ ) + { + if ( *m_FuncHandles[i] ) + pVM->ReleaseFunction( *m_FuncHandles[i] ); + *m_FuncHandles[i] = INVALID_HSCRIPT; + } + m_FuncHandles.RemoveAll(); + } + + operator HSCRIPT() + { + return ( m_hScope != INVALID_HSCRIPT ) ? m_hScope : NULL; + } + + bool ValueExists( const char *pszKey ) { return GetVM()->ValueExists( m_hScope, pszKey ); } + bool SetValue( const char *pszKey, const ScriptVariant_t &value ) { return GetVM()->SetValue(m_hScope, pszKey, value ); } + bool GetValue( const char *pszKey, ScriptVariant_t *pValue ) { return GetVM()->GetValue(m_hScope, pszKey, pValue ); } + void ReleaseValue( ScriptVariant_t &value ) { GetVM()->ReleaseValue( value ); } + bool ClearValue( const char *pszKey) { return GetVM()->ClearValue( m_hScope, pszKey ); } + + ScriptStatus_t Run( HSCRIPT hScript ) + { + InvalidateCachedValues(); + return GetVM()->Run( hScript, m_hScope ); + } + + ScriptStatus_t Run( const char *pszScriptText, const char *pszScriptName = NULL ) + { + InvalidateCachedValues(); + HSCRIPT hScript = GetVM()->CompileScript( pszScriptText, pszScriptName ); + if ( hScript ) + { + ScriptStatus_t result = GetVM()->Run( hScript, m_hScope ); + GetVM()->ReleaseScript( hScript ); + return result; + } + return SCRIPT_ERROR; + } + + ScriptStatus_t Run( const unsigned char *pszScriptText, const char *pszScriptName = NULL ) + { + return Run( (const char *)pszScriptText, pszScriptName); + } + + HSCRIPT LookupFunction( const char *pszFunction ) + { + return GetVM()->LookupFunction( pszFunction, m_hScope ); + } + + void ReleaseFunction( HSCRIPT hScript ) + { + GetVM()->ReleaseFunction( hScript ); + } + + bool FunctionExists( const char *pszFunction ) + { + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + GetVM()->ReleaseFunction( hFunction ); + return ( hFunction != NULL ) ; + } + + //----------------------------------------------------- + + enum Flags_t + { + EXTERNAL = 0x01, + }; + + //----------------------------------------------------- + + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn = NULL ) + { + return GetVM()->ExecuteFunction( hFunction, NULL, 0, pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + template + ScriptStatus_t Call( HSCRIPT hFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + return GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + } + + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn = NULL ) + { + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, NULL, 0, pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1 ) + { + ScriptVariant_t args[1]; args[0] = arg1; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2 ) + { + ScriptVariant_t args[2]; args[0] = arg1; args[1] = arg2; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3 ) + { + ScriptVariant_t args[3]; args[0] = arg1; args[1] = arg2; args[2] = arg3; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4 ) + { + ScriptVariant_t args[4]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5 ) + { + ScriptVariant_t args[5]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6 ) + { + ScriptVariant_t args[6]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7 ) + { + ScriptVariant_t args[7]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8 ) + { + ScriptVariant_t args[8]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9 ) + { + ScriptVariant_t args[9]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10 ) + { + ScriptVariant_t args[10]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11 ) + { + ScriptVariant_t args[11]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12 ) + { + ScriptVariant_t args[12]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13 ) + { + ScriptVariant_t args[13]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + + template + ScriptStatus_t Call( const char *pszFunction, ScriptVariant_t *pReturn, ARG_TYPE_1 arg1, ARG_TYPE_2 arg2, ARG_TYPE_3 arg3, ARG_TYPE_4 arg4, ARG_TYPE_5 arg5, ARG_TYPE_6 arg6, ARG_TYPE_7 arg7, ARG_TYPE_8 arg8, ARG_TYPE_9 arg9, ARG_TYPE_10 arg10, ARG_TYPE_11 arg11, ARG_TYPE_12 arg12, ARG_TYPE_13 arg13, ARG_TYPE_14 arg14 ) + { + ScriptVariant_t args[14]; args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5; args[5] = arg6; args[6] = arg7; args[7] = arg8; args[8] = arg9; args[9] = arg10; args[10] = arg11; args[11] = arg12; args[12] = arg13; args[13] = arg14; + HSCRIPT hFunction = GetVM()->LookupFunction( pszFunction, m_hScope ); + if ( !hFunction ) + return SCRIPT_ERROR; + ScriptStatus_t status = GetVM()->ExecuteFunction( hFunction, args, ARRAYSIZE(args), pReturn, m_hScope, true ); + GetVM()->ReleaseFunction( hFunction ); + return status; + } + +protected: + HSCRIPT m_hScope; + int m_flags; + CUtlVectorConservative m_FuncHandles; +}; + +typedef CScriptScopeT<> CScriptScope; + +#define VScriptAddEnumToScope_( scope, enumVal, scriptName ) (scope).SetValue( scriptName, (int)enumVal ) +#define VScriptAddEnumToScope( scope, enumVal ) VScriptAddEnumToScope_( scope, enumVal, #enumVal ) + +#define VScriptAddEnumToRoot( enumVal ) g_pScriptVM->SetValue( #enumVal, (int)enumVal ) + +#ifdef MAPBASE_VSCRIPT + +// +// Map pointer iteration +// +#define FOR_EACH_MAP_PTR( mapName, iteratorName ) \ + for ( int iteratorName = (mapName)->FirstInorder(); (mapName)->IsUtlMap && iteratorName != (mapName)->InvalidIndex(); iteratorName = (mapName)->NextInorder( iteratorName ) ) + +#define FOR_EACH_MAP_PTR_FAST( mapName, iteratorName ) \ + for ( int iteratorName = 0; (mapName)->IsUtlMap && iteratorName < (mapName)->MaxElement(); ++iteratorName ) if ( !(mapName)->IsValidIndex( iteratorName ) ) continue; else + +#define FOR_EACH_VEC_PTR( vecName, iteratorName ) \ + for ( int iteratorName = 0; iteratorName < (vecName)->Count(); iteratorName++ ) + +//----------------------------------------------------------------------------- + +static void __UpdateScriptHooks( HSCRIPT hooksList ); + +//----------------------------------------------------------------------------- +// +// Keeps track of which events and scopes are hooked without polling this from the script VM on each request. +// Local cache is updated each time there is a change to script hooks: on Add, on Remove, on game restore +// +//----------------------------------------------------------------------------- +class CScriptHookManager +{ +private: + typedef CUtlVector< char* > contextmap_t; + typedef CUtlMap< HScriptRaw, contextmap_t* > scopemap_t; + typedef CUtlMap< char*, scopemap_t* > hookmap_t; + + HSCRIPT m_hfnHookFunc; + + // { [string event], { [HSCRIPT scope], { [string context], [HSCRIPT callback] } } } + hookmap_t m_HookList; + +public: + + CScriptHookManager() : m_HookList( DefLessFunc(char*) ), m_hfnHookFunc(NULL) + { + } + + HSCRIPT GetHookFunction() + { + return m_hfnHookFunc; + } + + // For global hooks + bool IsEventHooked( const char *szEvent ) + { + return m_HookList.Find( const_cast< char* >( szEvent ) ) != m_HookList.InvalidIndex(); + } + + bool IsEventHookedInScope( const char *szEvent, HSCRIPT hScope ) + { + extern IScriptVM *g_pScriptVM; + + Assert( hScope ); + + int eventIdx = m_HookList.Find( const_cast< char* >( szEvent ) ); + if ( eventIdx == m_HookList.InvalidIndex() ) + return false; + + scopemap_t *scopeMap = m_HookList.Element( eventIdx ); + return scopeMap->Find( g_pScriptVM->HScriptToRaw( hScope ) ) != scopeMap->InvalidIndex(); + } + + // + // On VM init, registers script func and caches the hook func. + // + void OnInit() + { + extern IScriptVM *g_pScriptVM; + + ScriptRegisterFunctionNamed( g_pScriptVM, __UpdateScriptHooks, "__UpdateScriptHooks", SCRIPT_HIDE ); + + ScriptVariant_t hHooks; + g_pScriptVM->GetValue( "Hooks", &hHooks ); + + Assert( hHooks.m_type == FIELD_HSCRIPT ); + + if ( hHooks.m_type == FIELD_HSCRIPT ) + { + m_hfnHookFunc = g_pScriptVM->LookupFunction( "Call", hHooks ); + } + + Clear(); + } + + // + // On VM shutdown, clear the cache. + // Not exactly necessary, as the cache will be cleared on VM init next time. + // + void OnShutdown() + { + extern IScriptVM *g_pScriptVM; + + if ( m_hfnHookFunc ) + g_pScriptVM->ReleaseFunction( m_hfnHookFunc ); + + m_hfnHookFunc = NULL; + + Clear(); + } + + // + // On VM restore, update local cache. + // + void OnRestore() + { + extern IScriptVM *g_pScriptVM; + + ScriptVariant_t hHooks; + g_pScriptVM->GetValue( "Hooks", &hHooks ); + + if ( hHooks.m_type == FIELD_HSCRIPT ) + { + // Existing m_hfnHookFunc is invalid + m_hfnHookFunc = g_pScriptVM->LookupFunction( "Call", hHooks ); + + HSCRIPT func = g_pScriptVM->LookupFunction( "__UpdateHooks", hHooks ); + g_pScriptVM->Call( func ); + g_pScriptVM->ReleaseFunction( func ); + g_pScriptVM->ReleaseValue( hHooks ); + } + } + + // + // Clear local cache. + // + void Clear() + { + if ( m_HookList.Count() ) + { + FOR_EACH_MAP_FAST( m_HookList, i ) + { + scopemap_t *scopeMap = m_HookList.Element(i); + + FOR_EACH_MAP_PTR_FAST( scopeMap, j ) + { + contextmap_t *contextMap = scopeMap->Element(j); + contextMap->PurgeAndDeleteElements(); + } + + char *szEvent = m_HookList.Key(i); + free( szEvent ); + + scopeMap->PurgeAndDeleteElements(); + } + + m_HookList.PurgeAndDeleteElements(); + } + } + + // + // Called from script, update local cache. + // + void Update( HSCRIPT hooksList ) + { + extern IScriptVM *g_pScriptVM; + + // Rebuild from scratch + Clear(); + { + ScriptVariant_t varEvent, varScopeMap; + int it = -1; + while ( ( it = g_pScriptVM->GetKeyValue( hooksList, it, &varEvent, &varScopeMap ) ) != -1 ) + { + // types are checked in script + Assert( varEvent.m_type == FIELD_CSTRING ); + Assert( varScopeMap.m_type == FIELD_HSCRIPT ); + + scopemap_t *scopeMap; + + int eventIdx = m_HookList.Find( const_cast< char* >( varEvent.m_pszString ) ); + if ( eventIdx != m_HookList.InvalidIndex() ) + { + scopeMap = m_HookList.Element( eventIdx ); + } + else + { + scopeMap = new scopemap_t( DefLessFunc(HScriptRaw) ); + m_HookList.Insert( strdup( varEvent.m_pszString ), scopeMap ); + } + + ScriptVariant_t varScope, varContextMap; + int it2 = -1; + while ( ( it2 = g_pScriptVM->GetKeyValue( varScopeMap, it2, &varScope, &varContextMap ) ) != -1 ) + { + Assert( varScope.m_type == FIELD_HSCRIPT ); + Assert( varContextMap.m_type == FIELD_HSCRIPT); + + contextmap_t *contextMap; + + int scopeIdx = scopeMap->Find( g_pScriptVM->HScriptToRaw( varScope.m_hScript ) ); + if ( scopeIdx != scopeMap->InvalidIndex() ) + { + contextMap = scopeMap->Element( scopeIdx ); + } + else + { + contextMap = new contextmap_t(); + scopeMap->Insert( g_pScriptVM->HScriptToRaw( varScope.m_hScript ), contextMap ); + } + + ScriptVariant_t varContext, varCallback; + int it3 = -1; + while ( ( it3 = g_pScriptVM->GetKeyValue( varContextMap, it3, &varContext, &varCallback ) ) != -1 ) + { + Assert( varContext.m_type == FIELD_CSTRING ); + Assert( varCallback.m_type == FIELD_HSCRIPT ); + + bool skip = false; + + FOR_EACH_VEC_PTR( contextMap, k ) + { + char *szContext = contextMap->Element(k); + if ( V_strcmp( szContext, varContext.m_pszString ) == 0 ) + { + skip = true; + break; + } + } + + if ( !skip ) + contextMap->AddToTail( strdup( varContext.m_pszString ) ); + + g_pScriptVM->ReleaseValue( varContext ); + g_pScriptVM->ReleaseValue( varCallback ); + } + + g_pScriptVM->ReleaseValue( varScope ); + g_pScriptVM->ReleaseValue( varContextMap ); + } + + g_pScriptVM->ReleaseValue( varEvent ); + g_pScriptVM->ReleaseValue( varScopeMap ); + } + } + } +#ifdef _DEBUG + void Dump() + { + extern IScriptVM *g_pScriptVM; + + FOR_EACH_MAP( m_HookList, i ) + { + scopemap_t *scopeMap = m_HookList.Element(i); + char *szEvent = m_HookList.Key(i); + + Msg( "%s [%p]\n", szEvent, (void*)scopeMap ); + Msg( "{\n" ); + + FOR_EACH_MAP_PTR( scopeMap, j ) + { + HScriptRaw hScope = scopeMap->Key(j); + contextmap_t *contextMap = scopeMap->Element(j); + + Msg( "\t(0x%X) [%p]\n", hScope, (void*)contextMap ); + Msg( "\t{\n" ); + + FOR_EACH_VEC_PTR( contextMap, k ) + { + char *szContext = contextMap->Element(k); + + Msg( "\t\t%-.50s\n", szContext ); + } + + Msg( "\t}\n" ); + } + + Msg( "}\n" ); + } + } +#endif +}; + +inline CScriptHookManager &GetScriptHookManager() +{ + static CScriptHookManager g_ScriptHookManager; + return g_ScriptHookManager; +} + +static void __UpdateScriptHooks( HSCRIPT hooksList ) +{ + GetScriptHookManager().Update( hooksList ); +} + + +//----------------------------------------------------------------------------- +// Function bindings allow script functions to run C++ functions. +// Hooks allow C++ functions to run script functions. +// +// This was previously done with raw function lookups, but Mapbase adds more and +// it's hard to keep track of them without proper standards or documentation. +//----------------------------------------------------------------------------- +struct ScriptHook_t +{ + ScriptFuncDescriptor_t m_desc; + CUtlVector m_pszParameterNames; + bool m_bDefined; + + void AddParameter( const char *pszName, ScriptDataType_t type ) + { + int iCur = m_desc.m_Parameters.Count(); + m_desc.m_Parameters.SetGrowSize( 1 ); m_desc.m_Parameters.EnsureCapacity( iCur + 1 ); m_desc.m_Parameters.AddToTail( type ); + m_pszParameterNames.SetGrowSize( 1 ); m_pszParameterNames.EnsureCapacity( iCur + 1 ); m_pszParameterNames.AddToTail( pszName ); + } + + // ----------------------------------------------------------------- + + // Only valid between CanRunInScope() and Call() + HSCRIPT m_hFunc; + + ScriptHook_t() : + m_hFunc(NULL) + { + } + +#ifdef _DEBUG + // + // An uninitialised script scope will pass as null scope which is considered a valid hook scope (global hook) + // This should catch CanRunInScope() calls without CScriptScope::IsInitalised() checks first. + // + bool CanRunInScope( CScriptScope &hScope ) + { + Assert( hScope.IsInitialized() ); + return hScope.IsInitialized() && CanRunInScope( (HSCRIPT)hScope ); + } +#endif + + // Checks if there's a function of this name which would run in this scope + bool CanRunInScope( HSCRIPT hScope ) + { + // For now, assume null scope (which is used for global hooks) is always hooked + if ( !hScope || GetScriptHookManager().IsEventHookedInScope( m_desc.m_pszScriptName, hScope ) ) + { + m_hFunc = NULL; + return true; + } + + extern IScriptVM *g_pScriptVM; + + // Legacy support if the new system is not being used + m_hFunc = g_pScriptVM->LookupFunction( m_desc.m_pszScriptName, hScope ); + + return !!m_hFunc; + } + + // Call the function + // NOTE: `bRelease` only exists for weapon_custom_scripted legacy script func caching + bool Call( HSCRIPT hScope, ScriptVariant_t *pReturn, ScriptVariant_t *pArgs, bool bRelease = true ) + { + extern IScriptVM *g_pScriptVM; + + // Call() should not be called without CanRunInScope() check first, it caches m_hFunc for legacy support + Assert( CanRunInScope( hScope ) ); + + // Legacy + if ( m_hFunc ) + { + for (int i = 0; i < m_desc.m_Parameters.Count(); i++) + { + g_pScriptVM->SetValue( m_pszParameterNames[i], pArgs[i] ); + } + + ScriptStatus_t status = g_pScriptVM->ExecuteFunction( m_hFunc, NULL, 0, pReturn, hScope, true ); + + if ( bRelease ) + g_pScriptVM->ReleaseFunction( m_hFunc ); + m_hFunc = NULL; + + for (int i = 0; i < m_desc.m_Parameters.Count(); i++) + { + g_pScriptVM->ClearValue( m_pszParameterNames[i] ); + } + + return status == SCRIPT_DONE; + } + // New Hook System + else + { + ScriptStatus_t status = g_pScriptVM->ExecuteHookFunction( m_desc.m_pszScriptName, pArgs, m_desc.m_Parameters.Count(), pReturn, hScope, true ); + return status == SCRIPT_DONE; + } + } +}; +#endif + +//----------------------------------------------------------------------------- +// Script function proxy support +//----------------------------------------------------------------------------- + +class CScriptFuncHolder +{ +public: + CScriptFuncHolder() : hFunction( INVALID_HSCRIPT ) {} + bool IsValid() { return ( hFunction != INVALID_HSCRIPT ); } + bool IsNull() { return ( !hFunction ); } + HSCRIPT hFunction; +}; + +#define DEFINE_SCRIPT_PROXY_GUTS( FuncName, N ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + template < typename RET_TYPE FUNC_TEMPLATE_ARG_PARAMS_##N> \ + bool FuncName( RET_TYPE *pRetVal FUNC_ARG_FORMAL_PARAMS_##N ) \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + ScriptVariant_t returnVal; \ + Assert( N == m_desc.m_Parameters.Count() ); \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, &returnVal, FUNC_CALL_ARGS_##N ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + returnVal.AssignTo( pRetVal ); \ + returnVal.Free(); \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, N ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N> \ + bool FuncName( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + Assert( N == m_desc.m_Parameters.Count() ); \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, NULL, FUNC_CALL_ARGS_##N ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_0V( FuncName ) \ + CScriptFuncHolder m_hScriptFunc_##FuncName; \ + bool FuncName() \ + { \ + if ( !m_hScriptFunc_##FuncName.IsValid() ) \ + { \ + m_hScriptFunc_##FuncName.hFunction = LookupFunction( #FuncName ); \ + m_FuncHandles.AddToTail( &m_hScriptFunc_##FuncName.hFunction ); \ + } \ + \ + if ( !m_hScriptFunc_##FuncName.IsNull() ) \ + { \ + ScriptStatus_t result = Call( m_hScriptFunc_##FuncName.hFunction, NULL ); \ + if ( result != SCRIPT_ERROR ) \ + { \ + return true; \ + } \ + } \ + return false; \ + } + +#define DEFINE_SCRIPT_PROXY_0( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 0 ) +#define DEFINE_SCRIPT_PROXY_1( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 1 ) +#define DEFINE_SCRIPT_PROXY_2( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 2 ) +#define DEFINE_SCRIPT_PROXY_3( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 3 ) +#define DEFINE_SCRIPT_PROXY_4( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 4 ) +#define DEFINE_SCRIPT_PROXY_5( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 5 ) +#define DEFINE_SCRIPT_PROXY_6( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 6 ) +#define DEFINE_SCRIPT_PROXY_7( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 7 ) +#define DEFINE_SCRIPT_PROXY_8( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 8 ) +#define DEFINE_SCRIPT_PROXY_9( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 9 ) +#define DEFINE_SCRIPT_PROXY_10( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 10 ) +#define DEFINE_SCRIPT_PROXY_11( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 11 ) +#define DEFINE_SCRIPT_PROXY_12( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 12 ) +#define DEFINE_SCRIPT_PROXY_13( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 13 ) +#define DEFINE_SCRIPT_PROXY_14( FuncName ) DEFINE_SCRIPT_PROXY_GUTS( FuncName, 14 ) + +#define DEFINE_SCRIPT_PROXY_1V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 1 ) +#define DEFINE_SCRIPT_PROXY_2V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 2 ) +#define DEFINE_SCRIPT_PROXY_3V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 3 ) +#define DEFINE_SCRIPT_PROXY_4V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 4 ) +#define DEFINE_SCRIPT_PROXY_5V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 5 ) +#define DEFINE_SCRIPT_PROXY_6V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 6 ) +#define DEFINE_SCRIPT_PROXY_7V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 7 ) +#define DEFINE_SCRIPT_PROXY_8V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 8 ) +#define DEFINE_SCRIPT_PROXY_9V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 9 ) +#define DEFINE_SCRIPT_PROXY_10V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 10 ) +#define DEFINE_SCRIPT_PROXY_11V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 11 ) +#define DEFINE_SCRIPT_PROXY_12V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 12 ) +#define DEFINE_SCRIPT_PROXY_13V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 13 ) +#define DEFINE_SCRIPT_PROXY_14V( FuncName ) DEFINE_SCRIPT_PROXY_GUTS_NO_RETVAL( FuncName, 14 ) + +//----------------------------------------------------------------------------- + +#include "tier0/memdbgoff.h" + +#endif // IVSCRIPT_H diff --git a/public/vscript/vscript_templates.h b/public/vscript/vscript_templates.h new file mode 100644 index 00000000..2d7058a3 --- /dev/null +++ b/public/vscript/vscript_templates.h @@ -0,0 +1,432 @@ +//========== Copyright 2008, Valve Corporation, All rights reserved. ======== +// +// Purpose: +// +//============================================================================= + +#ifndef VSCRIPT_TEMPLATES_H +#define VSCRIPT_TEMPLATES_H + +#include "tier0/basetypes.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +#define FUNC_APPEND_PARAMS_0 +#define FUNC_APPEND_PARAMS_1 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 1 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); +#define FUNC_APPEND_PARAMS_2 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 2 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); +#define FUNC_APPEND_PARAMS_3 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 3 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); +#define FUNC_APPEND_PARAMS_4 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 4 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); +#define FUNC_APPEND_PARAMS_5 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 5 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); +#define FUNC_APPEND_PARAMS_6 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 6 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); +#define FUNC_APPEND_PARAMS_7 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 7 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); +#define FUNC_APPEND_PARAMS_8 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 8 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); +#define FUNC_APPEND_PARAMS_9 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 9 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); +#define FUNC_APPEND_PARAMS_10 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 10 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); +#define FUNC_APPEND_PARAMS_11 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 11 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); +#define FUNC_APPEND_PARAMS_12 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 12 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); +#define FUNC_APPEND_PARAMS_13 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 13 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); +#define FUNC_APPEND_PARAMS_14 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 14 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_14 ) ); + +#define DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER ); + +#define DEFINE_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER ); + +//------------------------------------- + +#define DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER(N) \ + template \ + inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \ + FUNC_APPEND_PARAMS_##N \ + } + +FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER ); + +#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); } + +#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); } +#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func ) +#define ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, scriptName ) ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) +#define ScriptInitMemberFuncDescriptor( pDesc, class, func ) ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, #func ) + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +template +inline void *ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc ) +{ + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) ) + { + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvert convert; + convert.pFunc = pFunc; + return convert.p; + } +#if defined( _MSC_VER ) + else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.pFunc = pFunc; + if ( convert.mfp.m_delta == 0 ) + { + return convert.mfp.p; + } + AssertMsg( 0, "Function pointer must be from primary vtable" ); + } + else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + int m_vtordisp; + int m_vtable_index; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.pFunc = pFunc; + if ( convert.mfp.m_delta == 0 ) + { + return convert.mfp.p; + } + AssertMsg( 0, "Function pointer must be from primary vtable" ); + } +#elif defined( GNUC ) + else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + struct GnuMFP + { + union + { + void *funcadr; // If vtable_index_2 is even, then this is the function pointer. + int vtable_index_2; // If vtable_index_2 is odd, then (vtable_index_2 - 1) * 2 is the index into the vtable. + }; + int delta; // Offset from this-ptr to vtable + }; + + GnuMFP *p = (GnuMFP*)&pFunc; + if ( p->delta == 0 ) + { + // No need to check whether this is a direct function pointer or not, + // this gets converted back to a "proper" member-function pointer in + // ScriptConvertFuncPtrFromVoid() to get invoked + return p->funcadr; + } + AssertMsg( 0, "Function pointer must be from primary vtable" ); + } +#else +#error "Need to implement code to crack non-offset member function pointer case" + // For gcc, see: http://www.codeproject.com/KB/cpp/FastDelegate.aspx + // + // Current versions of the GNU compiler use a strange and tricky + // optimization. It observes that, for virtual inheritance, you have to look + // up the vtable in order to get the voffset required to calculate the this + // pointer. While you're doing that, you might as well store the function + // pointer in the vtable. By doing this, they combine the m_func_address and + // m_vtable_index fields into one, and they distinguish between them by + // ensuring that function pointers always point to even addresses but vtable + // indices are always odd: + // + // // GNU g++ uses a tricky space optimisation, also adopted by IBM's VisualAge and XLC. + // struct GnuMFP { + // union { + // CODEPTR funcadr; // always even + // int vtable_index_2; // = vindex*2+1, always odd + // }; + // int delta; + // }; + // adjustedthis = this + delta + // if (funcadr & 1) CALL (* ( *delta + (vindex+1)/2) + 4) + // else CALL funcadr + // + // The G++ method is well documented, so it has been adopted by many other + // vendors, including IBM's VisualAge and XLC compilers, recent versions of + // Open64, Pathscale EKO, and Metrowerks' 64-bit compilers. A simpler scheme + // used by earlier versions of GCC is also very common. SGI's now + // discontinued MIPSPro and Pro64 compilers, and Apple's ancient MrCpp + // compiler used this method. (Note that the Pro64 compiler has become the + // open source Open64 compiler). + +#endif + else + AssertMsg( 0, "Member function pointer not supported. Why on earth are you using virtual inheritance!?" ); + return NULL; +} + +template +inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p ) +{ + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) ) + { + union FuncPtrConvert + { + void *p; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvert convert; + convert.p = p; + return convert.pFunc; + } + +#if defined( _MSC_VER ) + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.mfp.p = p; + convert.mfp.m_delta = 0; + return convert.pFunc; + } + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) + { + struct MicrosoftUnknownMFP + { + void *p; + int m_delta; + int m_vtordisp; + int m_vtable_index; + }; + + union FuncPtrConvertMI + { + MicrosoftUnknownMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertMI convert; + convert.mfp.p = p; + convert.mfp.m_delta = 0; + return convert.pFunc; + } +#elif defined( GNUC ) + if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) + { + struct GnuMFP + { + union + { + void *funcadr; // If vtable_index_2 is even, then this is the function pointer. + int vtable_index_2; // If vtable_index_2 is odd, then (vtable_index_2 - 1) * 2 is the index into the vtable. + }; + int delta; // Offset from this-ptr to vtable + }; + + union FuncPtrConvertGnu + { + GnuMFP mfp; + FUNCPTR_TYPE pFunc; + }; + + FuncPtrConvertGnu convert; + convert.mfp.funcadr = p; + convert.mfp.delta = 0; + return convert.pFunc; + } +#else +#error "Need to implement code to crack non-offset member function pointer case" +#endif + Assert( 0 ); + return NULL; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_0 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_1 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_1 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_2 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_2 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_3 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_3 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_4 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_4 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_5 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_5 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_6 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_6 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_7 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_7 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_8 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_8 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_9 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_9 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_10 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_10 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_11 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_11 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_12 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_12 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_13 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_13 +#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_14 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_14 + +#define SCRIPT_BINDING_ARGS_0 +#define SCRIPT_BINDING_ARGS_1 pArguments[0] +#define SCRIPT_BINDING_ARGS_2 pArguments[0], pArguments[1] +#define SCRIPT_BINDING_ARGS_3 pArguments[0], pArguments[1], pArguments[2] +#define SCRIPT_BINDING_ARGS_4 pArguments[0], pArguments[1], pArguments[2], pArguments[3] +#define SCRIPT_BINDING_ARGS_5 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4] +#define SCRIPT_BINDING_ARGS_6 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5] +#define SCRIPT_BINDING_ARGS_7 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6] +#define SCRIPT_BINDING_ARGS_8 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7] +#define SCRIPT_BINDING_ARGS_9 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8] +#define SCRIPT_BINDING_ARGS_10 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9] +#define SCRIPT_BINDING_ARGS_11 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10] +#define SCRIPT_BINDING_ARGS_12 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11] +#define SCRIPT_BINDING_ARGS_13 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12] +#define SCRIPT_BINDING_ARGS_14 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12], pArguments[13] + + +#define DEFINE_SCRIPT_BINDINGS(N) \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || !pReturn || pContext ) \ + { \ + return false; \ + } \ + *pReturn = ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \ + if ( pReturn->m_type == FIELD_VECTOR ) \ + pReturn->m_pVector = new Vector(*pReturn->m_pVector); \ + return true; \ + } \ + }; \ + \ + template \ + class CNonMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( !pContext ); \ + \ + if ( nArguments != N || pReturn || pContext ) \ + { \ + return false; \ + } \ + ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || !pReturn || !pContext ) \ + { \ + return false; \ + } \ + *pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + if ( pReturn->m_type == FIELD_VECTOR ) \ + pReturn->m_pVector = new Vector(*pReturn->m_pVector); \ + return true; \ + } \ + }; \ + \ + template \ + class CMemberScriptBinding##N \ + { \ + public: \ + static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \ + { \ + Assert( nArguments == N ); \ + Assert( !pReturn ); \ + Assert( pContext ); \ + \ + if ( nArguments != N || pReturn || !pContext ) \ + { \ + return false; \ + } \ + (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ + return true; \ + } \ + }; \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CNonMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } \ + \ + template \ + inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \ + { \ + typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ + return &CMemberScriptBinding##N::Call; \ + } + +FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +#endif // VSCRIPT_TEMPLATES_H diff --git a/public/vstdlib/IKeyValuesSystem.h b/public/vstdlib/IKeyValuesSystem.h index e999dd81..1bd5a8ab 100644 --- a/public/vstdlib/IKeyValuesSystem.h +++ b/public/vstdlib/IKeyValuesSystem.h @@ -16,9 +16,6 @@ typedef int HKeySymbol; #define INVALID_KEY_SYMBOL (-1) -class IBaseFileSystem; -class KeyValues; - //----------------------------------------------------------------------------- // Purpose: Interface to shared data repository for KeyValues (included in vgui_controls.lib) // allows for central data storage point of KeyValues symbol table @@ -42,12 +39,6 @@ class IKeyValuesSystem // for debugging, adds KeyValues record into global list so we can track memory leaks virtual void AddKeyValuesToMemoryLeakList(void *pMem, HKeySymbol name) = 0; virtual void RemoveKeyValuesFromMemoryLeakList(void *pMem) = 0; - - // maintain a cache of KeyValues we load from disk. This saves us quite a lot of time on app startup. - virtual void AddFileKeyValuesToCache( const KeyValues* _kv, const char *resourceName, const char *pathID ) = 0; - virtual bool LoadFileKeyValuesFromCache( KeyValues* _outKv, const char *resourceName, const char *pathID, IBaseFileSystem *filesystem ) const = 0; - virtual void InvalidateCache( ) = 0; - virtual void InvalidateCacheForFile( const char *resourceName, const char *pathID ) = 0; }; VSTDLIB_INTERFACE IKeyValuesSystem *KeyValuesSystem(); diff --git a/public/vstdlib/random.h b/public/vstdlib/random.h index fdfd09c6..88188031 100644 --- a/public/vstdlib/random.h +++ b/public/vstdlib/random.h @@ -22,11 +22,9 @@ //----------------------------------------------------------------------------- // A generator of uniformly distributed random numbers //----------------------------------------------------------------------------- -class VSTDLIB_CLASS IUniformRandomStream +class IUniformRandomStream { public: - //virtual ~IUniformRandomStream() { } - // Sets the seed of the random number generator virtual void SetSeed( int iSeed ) = 0; @@ -88,6 +86,7 @@ class VSTDLIB_CLASS CGaussianRandomStream CThreadFastMutex m_mutex; }; + //----------------------------------------------------------------------------- // A couple of convenience functions to access the library's global uniform stream //----------------------------------------------------------------------------- @@ -97,17 +96,6 @@ VSTDLIB_INTERFACE float RandomFloatExp( float flMinVal = 0.0f, float flMaxVal = VSTDLIB_INTERFACE int RandomInt( int iMinVal, int iMaxVal ); VSTDLIB_INTERFACE float RandomGaussianFloat( float flMean = 0.0f, float flStdDev = 1.0f ); -//----------------------------------------------------------------------------- -// IUniformRandomStream interface for free functions -//----------------------------------------------------------------------------- -class VSTDLIB_CLASS CDefaultUniformRandomStream : public IUniformRandomStream -{ -public: - virtual void SetSeed( int iSeed ) OVERRIDE { RandomSeed( iSeed ); } - virtual float RandomFloat( float flMinVal, float flMaxVal ) OVERRIDE { return ::RandomFloat( flMinVal, flMaxVal ); } - virtual int RandomInt( int iMinVal, int iMaxVal ) OVERRIDE { return ::RandomInt( iMinVal, iMaxVal ); } - virtual float RandomFloatExp( float flMinVal, float flMaxVal, float flExponent ) OVERRIDE { return ::RandomFloatExp( flMinVal, flMaxVal, flExponent ); } -}; //----------------------------------------------------------------------------- // Installs a global random number generator, which will affect the Random functions above diff --git a/public/vtf/vtf.h b/public/vtf/vtf.h index a77e7fb1..ecf10c88 100644 --- a/public/vtf/vtf.h +++ b/public/vtf/vtf.h @@ -56,9 +56,9 @@ enum CompiledVtfFlags TEXTUREFLAGS_NODEBUGOVERRIDE = 0x00020000, TEXTUREFLAGS_SINGLECOPY = 0x00040000, - TEXTUREFLAGS_STAGING_MEMORY = 0x00080000, - TEXTUREFLAGS_IMMEDIATE_CLEANUP = 0x00100000, - TEXTUREFLAGS_IGNORE_PICMIP = 0x00200000, + TEXTUREFLAGS_UNUSED_00080000 = 0x00080000, + TEXTUREFLAGS_UNUSED_00100000 = 0x00100000, + TEXTUREFLAGS_UNUSED_00200000 = 0x00200000, TEXTUREFLAGS_UNUSED_00400000 = 0x00400000, TEXTUREFLAGS_NODEPTHBUFFER = 0x00800000, diff --git a/public/xzp.cpp b/public/xzp.cpp index 8a8a0f06..64183812 100644 --- a/public/xzp.cpp +++ b/public/xzp.cpp @@ -770,7 +770,7 @@ bool xZipAddFile( const char* filename, CUtlBuffer &fileBuff, bool bPrecacheEnti else if( bProcessPrecacheHeaderOnly ) { customPreloadSize = xZipComputeCustomPreloads( filename ); - fileSize = min( fileSize, customPreloadSize ); + fileSize = MIN( fileSize, customPreloadSize ); } unsigned CRC = xZipCRCFilename( filename ); diff --git a/public/zip_uncompressed.h b/public/zip_uncompressed.h index 11f4e86d..0c8a45e6 100644 --- a/public/zip_uncompressed.h +++ b/public/zip_uncompressed.h @@ -14,10 +14,6 @@ #define PKID( a, b ) (((b)<<24)|((a)<<16)|('K'<<8)|'P') -// compressionMethod field -#define ZIP_COMPRESSION_NONE 0 -#define ZIP_COMPRESSION_LZMA 14 - #pragma pack(1) struct ZIP_EndOfCentralDirRecord diff --git a/public/zip_utils.cpp b/public/zip_utils.cpp index 848e7a79..620b57a7 100644 --- a/public/zip_utils.cpp +++ b/public/zip_utils.cpp @@ -23,13 +23,6 @@ #include "byteswap.h" #include "utlstring.h" -#include "tier1/lzmaDecoder.h" - -// Not every user of zip utils wants to link LZMA encoder -#ifdef ZIP_SUPPORT_LZMA_ENCODE -#include "lzma/lzma.h" -#endif - // Data descriptions for byte swapping - only needed // for structures that are written to file for use by the game. BEGIN_BYTESWAP_DATADESC( ZIP_EndOfCentralDirRecord ) @@ -255,7 +248,7 @@ class CBufferStream : public IWriteStream CBufferStream( CUtlBuffer& buff ) : IWriteStream(), m_buff( &buff ) {} // Implementing IWriteStream method - virtual void Put( const void* pMem, int size ) {m_buff->Put( pMem, size );} + virtual void Put( const void* pMem, int size ) { m_buff->Put( pMem, size ); } // Implementing IWriteStream method virtual unsigned int Tell( void ) { return m_buff->TellPut(); } @@ -328,13 +321,13 @@ class CZipFile void Reset( void ); // Add file to zip under relative name - void AddFileToZip( const char *relativename, const char *fullpath, IZip::eCompressionType compressionType ); + void AddFileToZip( const char *relativename, const char *fullpath ); // Delete file from zip void RemoveFileFromZip( const char *relativename ); // Add buffer to zip as a file with given name - void AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode, IZip::eCompressionType compressionType ); + void AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ); // Check if a file already exists in the zip. bool FileExistsInZip( const char *relativename ); @@ -380,12 +373,9 @@ class CZipFile typedef struct { - CUtlSymbol m_Name; - unsigned int filepos; - int filelen; - int uncompressedLen; - CRC32_t crc32; - IZip::eCompressionType compressionType; + CUtlSymbol m_Name; + unsigned int filepos; + int filelen; } TmpFileInfo_t; CByteswap m_Swap; @@ -415,25 +405,18 @@ class CZipFile CUtlSymbol m_Name; // Lenth of data element - int m_nCompressedSize; - - // Original, uncompressed size - int m_nUncompressedSize; - + int m_Length; // Raw data, could be null and data may be in disk write cache void *m_pData; // Offset in Zip ( set and valid during final write ) unsigned int m_ZipOffset; - // CRC of blob + // CRC of blob ( set and valid during final write ) CRC32_t m_ZipCRC; // Location of data in disk cache unsigned int m_DiskCacheOffset; unsigned int m_SourceDiskOffset; - - // The compression used on the data if any - IZip::eCompressionType m_eCompressionType; }; // For fast name lookup and sorting @@ -452,14 +435,12 @@ class CZipFile CZipFile::CZipEntry::CZipEntry( void ) { m_Name = ""; - m_nCompressedSize = 0; - m_nUncompressedSize = 0; + m_Length = 0; m_pData = NULL; m_ZipOffset = 0; m_ZipCRC = 0; m_DiskCacheOffset = 0; m_SourceDiskOffset = 0; - m_eCompressionType = IZip::eCompressionType_None; } //----------------------------------------------------------------------------- @@ -469,14 +450,12 @@ CZipFile::CZipEntry::CZipEntry( void ) CZipFile::CZipEntry::CZipEntry( const CZipFile::CZipEntry& src ) { m_Name = src.m_Name; - m_nCompressedSize = src.m_nCompressedSize; - m_nUncompressedSize = src.m_nUncompressedSize; - m_eCompressionType = src.m_eCompressionType; + m_Length = src.m_Length; - if ( src.m_nCompressedSize > 0 && src.m_pData ) + if ( src.m_Length > 0 && src.m_pData ) { - m_pData = malloc( src.m_nCompressedSize ); - memcpy( m_pData, src.m_pData, src.m_nCompressedSize ); + m_pData = malloc( src.m_Length ); + memcpy( m_pData, src.m_pData, src.m_Length ); } else { @@ -636,9 +615,7 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) ZIP_EndOfCentralDirRecord rec = { 0 }; -#ifdef DBGFLAG_ASSERT bool bFoundEndOfCentralDirRecord = false; -#endif unsigned int offset = fileLen - sizeof( ZIP_EndOfCentralDirRecord ); // If offset is ever greater than startOffset then it means that it has // wrapped. This used to be a tautological >= 0 test. @@ -649,15 +626,13 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) buf.GetObjects( &rec ); if ( rec.signature == PKID( 5, 6 ) ) { -#ifdef DBGFLAG_ASSERT bFoundEndOfCentralDirRecord = true; -#endif // Set any xzip configuration if ( rec.commentLength ) { char commentString[128]; - int commentLength = min( rec.commentLength, sizeof( commentString ) ); + int commentLength = MIN( rec.commentLength, sizeof( commentString ) ); buf.Get( commentString, commentLength ); if ( commentLength == sizeof( commentString ) ) --commentLength; @@ -695,27 +670,20 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) ZIP_FileHeader zipFileHeader; buf.GetObjects( &zipFileHeader ); Assert( zipFileHeader.signature == PKID( 1, 2 ) ); - if ( zipFileHeader.compressionMethod != IZip::eCompressionType_None && - zipFileHeader.compressionMethod != IZip::eCompressionType_LZMA ) - { - Assert( false ); - Warning( "Opening ZIP file with unsupported compression type\n"); - } - - char tmpString[1024] = { 0 }; - buf.Get( tmpString, Min( (unsigned int)zipFileHeader.fileNameLength, (unsigned int)sizeof( tmpString ) ) ); + Assert( zipFileHeader.compressionMethod == 0 ); + + char tmpString[1024]; + buf.Get( tmpString, zipFileHeader.fileNameLength ); + tmpString[zipFileHeader.fileNameLength] = '\0'; Q_strlower( tmpString ); // can determine actual filepos, assuming a well formed zip newfiles[i].m_Name = tmpString; newfiles[i].filelen = zipFileHeader.compressedSize; - newfiles[i].uncompressedLen = zipFileHeader.uncompressedSize; - newfiles[i].crc32 = zipFileHeader.crc32; newfiles[i].filepos = zipFileHeader.relativeOffsetOfLocalHeader + - sizeof( ZIP_LocalFileHeader ) + - zipFileHeader.fileNameLength + - zipFileHeader.extraFieldLength; - newfiles[i].compressionType = (IZip::eCompressionType)zipFileHeader.compressionMethod; + sizeof( ZIP_LocalFileHeader ) + + zipFileHeader.fileNameLength + + zipFileHeader.extraFieldLength; int nextOffset; if ( m_bCompatibleFormat ) @@ -734,19 +702,16 @@ void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) { CZipEntry e; e.m_Name = newfiles[i].m_Name; - e.m_nCompressedSize = newfiles[i].filelen; - e.m_ZipCRC = newfiles[i].crc32; - e.m_nUncompressedSize = newfiles[i].uncompressedLen; - e.m_eCompressionType = newfiles[i].compressionType; - + e.m_Length = newfiles[i].filelen; + // Make sure length is reasonable - if ( e.m_nCompressedSize > 0 ) + if ( e.m_Length > 0 ) { - e.m_pData = malloc( e.m_nCompressedSize ); + e.m_pData = malloc( e.m_Length ); // Copy in data buf.SeekGet( CUtlBuffer::SEEK_HEAD, newfiles[i].filepos ); - buf.Get( e.m_pData, e.m_nCompressedSize ); + buf.Get( e.m_pData, e.m_Length ); } else { @@ -814,7 +779,7 @@ HANDLE CZipFile::ParseFromDisk( const char *pFilename ) if ( rec.commentLength ) { char commentString[128]; - int commentLength = min( rec.commentLength, sizeof( commentString ) ); + int commentLength = MIN( rec.commentLength, sizeof( commentString ) ); CWin32File::FileRead( hFile, commentString, commentLength ); if ( commentLength == sizeof( commentString ) ) --commentLength; @@ -857,9 +822,7 @@ HANDLE CZipFile::ParseFromDisk( const char *pFilename ) ZIP_FileHeader zipFileHeader; zipDirBuff.GetObjects( &zipFileHeader ); - if ( zipFileHeader.signature != PKID( 1, 2 ) - || ( zipFileHeader.compressionMethod != IZip::eCompressionType_None - && zipFileHeader.compressionMethod != IZip::eCompressionType_LZMA ) ) + if ( zipFileHeader.signature != PKID( 1, 2 ) || zipFileHeader.compressionMethod != 0 ) { // bad contents #ifdef WIN32 @@ -869,7 +832,7 @@ HANDLE CZipFile::ParseFromDisk( const char *pFilename ) #endif return NULL; } - + char fileName[1024]; zipDirBuff.Get( fileName, zipFileHeader.fileNameLength ); fileName[zipFileHeader.fileNameLength] = '\0'; @@ -878,15 +841,11 @@ HANDLE CZipFile::ParseFromDisk( const char *pFilename ) // can determine actual filepos, assuming a well formed zip CZipEntry e; e.m_Name = fileName; - e.m_nCompressedSize = zipFileHeader.compressedSize; - e.m_nUncompressedSize = zipFileHeader.uncompressedSize; - e.m_ZipCRC = zipFileHeader.crc32; + e.m_Length = zipFileHeader.compressedSize; e.m_SourceDiskOffset = zipFileHeader.relativeOffsetOfLocalHeader + - sizeof( ZIP_LocalFileHeader ) + - zipFileHeader.fileNameLength + - zipFileHeader.extraFieldLength; - e.m_eCompressionType = (IZip::eCompressionType)zipFileHeader.compressionMethod; - + sizeof( ZIP_LocalFileHeader ) + + zipFileHeader.fileNameLength + + zipFileHeader.extraFieldLength; // Add to tree m_Files.Insert( e ); @@ -991,85 +950,19 @@ static void CopyTextData( char *pDst, const char *pSrc, int dstSize, int srcSize // *data - // length - //----------------------------------------------------------------------------- -void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode, IZip::eCompressionType compressionType ) +void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ) { // Lower case only char name[512]; Q_strcpy( name, relativename ); Q_strlower( name ); - int outLength = length; - int uncompressedLength = length; - void *outData = data; - CUtlBuffer textTransform; - CUtlBuffer compressionTransform; - + int dstLength = length; if ( bTextMode ) { - int textLen = GetLengthOfBinStringAsText( ( const char * )outData, outLength ); - textTransform.EnsureCapacity( textLen ); - CopyTextData( (char *)textTransform.Base(), (char *)outData, textLen, outLength ); - - outData = (void *)textTransform.Base(); - outLength = textLen; - uncompressedLength = textLen; - } - - // uncompressed data final at this point (CRC is before compression) - CRC32_t zipCRC; - CRC32_Init( &zipCRC ); - CRC32_ProcessBuffer( &zipCRC, outData, outLength ); - CRC32_Final( &zipCRC ); - -#ifdef ZIP_SUPPORT_LZMA_ENCODE - if ( compressionType == IZip::eCompressionType_LZMA ) - { - unsigned int compressedSize = 0; - unsigned char *pCompressedOutput = LZMA_Compress( (unsigned char *)outData, outLength, &compressedSize ); - if ( !pCompressedOutput || compressedSize < sizeof( lzma_header_t ) ) - { - Warning( "ZipFile: LZMA compression failed\n" ); - return; - } - - // Fixup LZMA header for ZIP payload usage - // The output of LZMA_Compress uses lzma_header_t, defined alongside it. - // - // ZIP payload format, see ZIP spec 5.8.8: - // LZMA Version Information 2 bytes - // LZMA Properties Size 2 bytes - // LZMA Properties Data variable, defined by "LZMA Properties Size" - unsigned int nZIPHeader = 2 + 2 + sizeof( lzma_header_t().properties ); - unsigned int finalCompressedSize = compressedSize - sizeof( lzma_header_t ) + nZIPHeader; - compressionTransform.EnsureCapacity( finalCompressedSize ); - - // LZMA version - compressionTransform.PutUnsignedChar( LZMA_SDK_VERSION_MAJOR ); - compressionTransform.PutUnsignedChar( LZMA_SDK_VERSION_MINOR ); - // properties size - uint16 nSwappedPropertiesSize = LittleWord( sizeof( lzma_header_t().properties ) ); - compressionTransform.Put( &nSwappedPropertiesSize, sizeof( nSwappedPropertiesSize ) ); - // properties - compressionTransform.Put( &(((lzma_header_t *)pCompressedOutput)->properties), sizeof( lzma_header_t().properties ) ); - // payload - compressionTransform.Put( pCompressedOutput + sizeof( lzma_header_t ), compressedSize - sizeof( lzma_header_t ) ); - - // Free original - free( pCompressedOutput ); - pCompressedOutput = NULL; - - outData = (void *)compressionTransform.Base(); - outLength = finalCompressedSize; - // (Not updating uncompressedLength) - } - else -#endif - /* else from ifdef */ if ( compressionType != IZip::eCompressionType_None ) - { - Error( "Calling AddBufferToZip with unknown compression type\n" ); - return; + dstLength = GetLengthOfBinStringAsText( ( const char * )data, length ); } - + // See if entry is in list already CZipEntry e; e.m_Name = name; @@ -1084,17 +977,23 @@ void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, free( update->m_pData ); } - update->m_eCompressionType = compressionType; - update->m_pData = malloc( outLength ); - memcpy( update->m_pData, outData, outLength ); - update->m_nCompressedSize = outLength; - update->m_nUncompressedSize = uncompressedLength; - update->m_ZipCRC = zipCRC; + if ( bTextMode ) + { + update->m_pData = malloc( dstLength ); + CopyTextData( ( char * )update->m_pData, ( char * )data, dstLength, length ); + update->m_Length = dstLength; + } + else + { + update->m_pData = malloc( length ); + memcpy( update->m_pData, data, length ); + update->m_Length = length; + } if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) { update->m_DiskCacheOffset = CWin32File::FileTell( m_hDiskCacheWriteFile ); - CWin32File::FileWrite( m_hDiskCacheWriteFile, update->m_pData, update->m_nCompressedSize ); + CWin32File::FileWrite( m_hDiskCacheWriteFile, update->m_pData, update->m_Length ); free( update->m_pData ); update->m_pData = NULL; } @@ -1102,19 +1001,24 @@ void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, else { // Create a new entry - e.m_nCompressedSize = outLength; - e.m_nUncompressedSize = uncompressedLength; - e.m_eCompressionType = compressionType; - e.m_ZipCRC = zipCRC; - if ( outLength > 0 ) + e.m_Length = dstLength; + if ( dstLength > 0 ) { - e.m_pData = malloc( outLength ); - memcpy( e.m_pData, outData, outLength ); - + if ( bTextMode ) + { + e.m_pData = malloc( dstLength ); + CopyTextData( (char *)e.m_pData, ( char * )data, dstLength, length ); + } + else + { + e.m_pData = malloc( length ); + memcpy( e.m_pData, data, length ); + } + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) { e.m_DiskCacheOffset = CWin32File::FileTell( m_hDiskCacheWriteFile ); - CWin32File::FileWrite( m_hDiskCacheWriteFile, e.m_pData, e.m_nCompressedSize ); + CWin32File::FileWrite( m_hDiskCacheWriteFile, e.m_pData, e.m_Length ); free( e.m_pData ); e.m_pData = NULL; } @@ -1134,11 +1038,38 @@ void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, //----------------------------------------------------------------------------- bool CZipFile::ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) { - return ReadFileFromZip( 0, pRelativeName, bTextMode, buf ); + // Lower case only + char pName[512]; + Q_strncpy( pName, pRelativeName, 512 ); + Q_strlower( pName ); + + // See if entry is in list already + CZipEntry e; + e.m_Name = pName; + int nIndex = m_Files.Find( e ); + if ( nIndex == m_Files.InvalidIndex() ) + { + // not found + return false; + } + + CZipEntry *pEntry = &m_Files[ nIndex ]; + if ( bTextMode ) + { + buf.SetBufferType( true, false ); + ReadTextData( (char*)pEntry->m_pData, pEntry->m_Length, buf ); + } + else + { + buf.SetBufferType( false, false ); + buf.Put( pEntry->m_pData, pEntry->m_Length ); + } + + return true; } //----------------------------------------------------------------------------- -// Reads a file from the zip. Requires the zip file handle if this zip was loaded via ParseFromDisk +// Reads a file from the zip //----------------------------------------------------------------------------- bool CZipFile::ReadFileFromZip( HANDLE hZipFile, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) { @@ -1159,63 +1090,27 @@ bool CZipFile::ReadFileFromZip( HANDLE hZipFile, const char *pRelativeName, bool CZipEntry *pEntry = &m_Files[nIndex]; - void *pData = pEntry->m_pData; - CUtlBuffer readBuffer; - if ( !pData && hZipFile ) + void *pData = malloc( pEntry->m_Length ); + CWin32File::FileSeek( hZipFile, pEntry->m_SourceDiskOffset, FILE_BEGIN ); + if ( !CWin32File::FileRead( hZipFile, pData, pEntry->m_Length ) ) { - readBuffer.EnsureCapacity( pEntry->m_nCompressedSize ); - CWin32File::FileSeek( hZipFile, pEntry->m_SourceDiskOffset, FILE_BEGIN ); - if ( !CWin32File::FileRead( hZipFile, readBuffer.Base(), pEntry->m_nCompressedSize ) ) - { - return false; - } - - pData = readBuffer.Base(); - } - - CUtlBuffer decompressTransform; - if ( pEntry->m_eCompressionType != IZip::eCompressionType_None ) - { - if ( pEntry->m_eCompressionType == IZip::eCompressionType_LZMA ) - { - decompressTransform.EnsureCapacity( pEntry->m_nUncompressedSize ); - - CLZMAStream decompressStream; - decompressStream.InitZIPHeader( pEntry->m_nCompressedSize, pEntry->m_nUncompressedSize ); - - unsigned int nCompressedBytesRead = 0; - unsigned int nOutputBytesWritten = 0; - bool bSuccess = decompressStream.Read( (unsigned char *)pData, pEntry->m_nCompressedSize, - (unsigned char *)decompressTransform.Base(), decompressTransform.Size(), - nCompressedBytesRead, nOutputBytesWritten ); - if ( !bSuccess || - (int)nCompressedBytesRead != pEntry->m_nCompressedSize || - (int)nOutputBytesWritten != pEntry->m_nUncompressedSize ) - { - Error( "Zip: Failed decompressing LZMA data\n" ); - return false; - } - - pData = decompressTransform.Base(); - } - else - { - Error( "Unsupported compression type in Zip file: %u\n", pEntry->m_eCompressionType ); - return false; - } + free( pData ); + return false; } if ( bTextMode ) { buf.SetBufferType( true, false ); - ReadTextData( (const char *)pData, pEntry->m_nUncompressedSize, buf ); + ReadTextData( (const char *)pData, pEntry->m_Length, buf ); } else { buf.SetBufferType( false, false ); - buf.Put( pData, pEntry->m_nUncompressedSize ); + buf.Put( pData, pEntry->m_Length ); } + free( pData ); + return true; } @@ -1243,7 +1138,7 @@ bool CZipFile::FileExistsInZip( const char *pRelativeName ) //----------------------------------------------------------------------------- // Purpose: Adds a new file to the zip. //----------------------------------------------------------------------------- -void CZipFile::AddFileToZip( const char *relativename, const char *fullpath, IZip::eCompressionType compressionType ) +void CZipFile::AddFileToZip( const char *relativename, const char *fullpath ) { FILE *temp = fopen( fullpath, "rb" ); if ( !temp ) @@ -1260,8 +1155,8 @@ void CZipFile::AddFileToZip( const char *relativename, const char *fullpath, IZi fclose( temp ); // Now add as a buffer - AddBufferToZip( relativename, buf, size, false, compressionType ); - + AddBufferToZip( relativename, buf, size, false ); + free( buf ); } @@ -1353,8 +1248,8 @@ unsigned int CZipFile::CalculateSize( void ) for ( int i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) { CZipEntry *e = &m_Files[ i ]; - - if ( e->m_nCompressedSize == 0 ) + + if ( e->m_Length == 0 ) continue; // local file header @@ -1369,7 +1264,7 @@ unsigned int CZipFile::CalculateSize( void ) { // round up to next boundary unsigned int nextBoundary = ( size + m_AlignmentSize ) & ~( m_AlignmentSize - 1 ); - + // the directory header also duplicates the padding dirHeaders += nextBoundary - size; @@ -1377,7 +1272,7 @@ unsigned int CZipFile::CalculateSize( void ) } // data size - size += e->m_nCompressedSize; + size += e->m_Length; } size += dirHeaders; @@ -1423,7 +1318,7 @@ int CZipFile::GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileS CZipEntry *e = &m_Files[id]; Q_strncpy( pBuffer, e->m_Name.String(), bufferSize ); - fileSize = e->m_nUncompressedSize; + fileSize = e->m_Length; return id; } @@ -1474,9 +1369,6 @@ void CZipFile::SaveDirectory( IWriteStream& stream ) #endif } - // Might be writing a zip into a larger stream - unsigned int zipOffsetInStream = stream.Tell(); - int i; for ( i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) { @@ -1484,50 +1376,47 @@ void CZipFile::SaveDirectory( IWriteStream& stream ) Assert( e ); // Fix up the offset - e->m_ZipOffset = stream.Tell() - zipOffsetInStream; + e->m_ZipOffset = stream.Tell(); - if ( e->m_nCompressedSize > 0 && ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) ) - { + if ( e->m_Length > 0 && ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) ) + { // get the data back from the write cache - e->m_pData = malloc( e->m_nCompressedSize ); + e->m_pData = malloc( e->m_Length ); if ( e->m_pData ) { CWin32File::FileSeek( m_hDiskCacheWriteFile, e->m_DiskCacheOffset, FILE_BEGIN ); - CWin32File::FileRead( m_hDiskCacheWriteFile, e->m_pData, e->m_nCompressedSize ); + CWin32File::FileRead( m_hDiskCacheWriteFile, e->m_pData, e->m_Length ); } } - if ( e->m_nCompressedSize > 0 && e->m_pData != NULL ) + if ( e->m_Length > 0 && e->m_pData != NULL ) { ZIP_LocalFileHeader hdr = { 0 }; hdr.signature = PKID( 3, 4 ); - hdr.versionNeededToExtract = 10; // No special features or even compression here, set to 1.0 -#ifdef ZIP_SUPPORT_LZMA_ENCODE - if ( e->m_eCompressionType == IZip::eCompressionType_LZMA ) - { - // Per ZIP spec 5.8.8 - hdr.versionNeededToExtract = 63; - } -#endif + hdr.versionNeededToExtract = 10; // This is the version that the winzip that I have writes. hdr.flags = 0; - hdr.compressionMethod = e->m_eCompressionType; + hdr.compressionMethod = 0; // NO COMPRESSION! hdr.lastModifiedTime = 0; hdr.lastModifiedDate = 0; - hdr.crc32 = e->m_ZipCRC; + CRC32_Init( &e->m_ZipCRC ); + CRC32_ProcessBuffer( &e->m_ZipCRC, e->m_pData, e->m_Length ); + CRC32_Final( &e->m_ZipCRC ); + hdr.crc32 = e->m_ZipCRC; + const char *pFilename = e->m_Name.String(); - hdr.compressedSize = e->m_nCompressedSize; - hdr.uncompressedSize = e->m_nUncompressedSize; + hdr.compressedSize = e->m_Length; + hdr.uncompressedSize = e->m_Length; hdr.fileNameLength = strlen( pFilename ); hdr.extraFieldLength = CalculatePadding( hdr.fileNameLength, e->m_ZipOffset ); int extraFieldLength = hdr.extraFieldLength; - + // Swap header in place m_Swap.SwapFieldsToTargetEndian( &hdr ); stream.Put( &hdr, sizeof( hdr ) ); stream.Put( pFilename, strlen( pFilename ) ); stream.Put( pPaddingBuffer, extraFieldLength ); - stream.Put( e->m_pData, e->m_nCompressedSize ); + stream.Put( e->m_pData, e->m_Length ); if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) { @@ -1544,7 +1433,7 @@ void CZipFile::SaveDirectory( IWriteStream& stream ) CWin32File::FileSeek( m_hDiskCacheWriteFile, 0, FILE_END ); } - unsigned int centralDirStart = stream.Tell() - zipOffsetInStream; + unsigned int centralDirStart = stream.Tell(); if ( m_AlignmentSize ) { // align the central directory starting position @@ -1562,28 +1451,21 @@ void CZipFile::SaveDirectory( IWriteStream& stream ) { CZipEntry *e = &m_Files[i]; Assert( e ); - - if ( e->m_nCompressedSize > 0 && e->m_pData != NULL ) + + if ( e->m_Length > 0 && e->m_pData != NULL ) { ZIP_FileHeader hdr = { 0 }; hdr.signature = PKID( 1, 2 ); hdr.versionMadeBy = 20; // This is the version that the winzip that I have writes. - hdr.versionNeededToExtract = 10; // No special features or even compression here, set to 1.0 -#ifdef ZIP_SUPPORT_LZMA_ENCODE - if ( e->m_eCompressionType == IZip::eCompressionType_LZMA ) - { - // Per ZIP spec 5.8.8 - hdr.versionNeededToExtract = 63; - } -#endif + hdr.versionNeededToExtract = 10; // This is the version that the winzip that I have writes. hdr.flags = 0; - hdr.compressionMethod = e->m_eCompressionType; + hdr.compressionMethod = 0; hdr.lastModifiedTime = 0; hdr.lastModifiedDate = 0; hdr.crc32 = e->m_ZipCRC; - hdr.compressedSize = e->m_nCompressedSize; - hdr.uncompressedSize = e->m_nUncompressedSize; + hdr.compressedSize = e->m_Length; + hdr.uncompressedSize = e->m_Length; hdr.fileNameLength = strlen( e->m_Name.String() ); hdr.extraFieldLength = CalculatePadding( hdr.fileNameLength, e->m_ZipOffset ); hdr.fileCommentLength = 0; @@ -1612,7 +1494,7 @@ void CZipFile::SaveDirectory( IWriteStream& stream ) } } - unsigned int centralDirEnd = stream.Tell() - zipOffsetInStream; + unsigned int centralDirEnd = stream.Tell(); if ( m_AlignmentSize ) { // align the central directory starting position @@ -1655,57 +1537,56 @@ class CZip : public IZip CZip( const char *pDiskCacheWritePath, bool bSortByName ); virtual ~CZip(); - virtual void Reset() OVERRIDE; + virtual void Reset(); // Add a single file to a zip - maintains the zip's previous alignment state - virtual void AddFileToZip( const char *relativename, const char *fullpath, eCompressionType compressionType ) OVERRIDE; + virtual void AddFileToZip( const char *relativename, const char *fullpath ); // Whether a file is contained in a zip - maintains alignment - virtual bool FileExistsInZip( const char *pRelativeName ) OVERRIDE; + virtual bool FileExistsInZip( const char *pRelativeName ); // Reads a file from the zip - maintains alignement - virtual bool ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) OVERRIDE; - virtual bool ReadFileFromZip( HANDLE hZipFile, const char *relativename, bool bTextMode, CUtlBuffer &buf ) OVERRIDE; + virtual bool ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ); + virtual bool ReadFileFromZip( HANDLE hZipFile, const char *relativename, bool bTextMode, CUtlBuffer &buf ); // Removes a single file from the zip - maintains alignment - virtual void RemoveFileFromZip( const char *relativename ) OVERRIDE; + virtual void RemoveFileFromZip( const char *relativename ); // Gets next filename in zip, for walking the directory - maintains alignment - virtual int GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ) OVERRIDE; + virtual int GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ); // Prints the zip's contents - maintains alignment - virtual void PrintDirectory( void ) OVERRIDE; + virtual void PrintDirectory( void ); // Estimate the size of the Zip (including header, padding, etc.) - virtual unsigned int EstimateSize( void ) OVERRIDE; + virtual unsigned int EstimateSize( void ); // Add buffer to zip as a file with given name - uses current alignment size, default 0 (no alignment) - virtual void AddBufferToZip( const char *relativename, void *data, int length, - bool bTextMode, eCompressionType compressionType ) OVERRIDE; + virtual void AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ); - // Writes out zip file to a buffer - uses current alignment size + // Writes out zip file to a buffer - uses current alignment size // (set by file's previous alignment, or a call to ForceAlignment) - virtual void SaveToBuffer( CUtlBuffer& outbuf ) OVERRIDE; + virtual void SaveToBuffer( CUtlBuffer& outbuf ); - // Writes out zip file to a filestream - uses current alignment size + // Writes out zip file to a filestream - uses current alignment size // (set by file's previous alignment, or a call to ForceAlignment) - virtual void SaveToDisk( FILE *fout ) OVERRIDE; - virtual void SaveToDisk( HANDLE hOutFile ) OVERRIDE; + virtual void SaveToDisk( FILE *fout ); + virtual void SaveToDisk( HANDLE hOutFile ); - // Reads a zip file from a buffer into memory - sets current alignment size to + // Reads a zip file from a buffer into memory - sets current alignment size to // the file's alignment size, unless overridden by a ForceAlignment call) - virtual void ParseFromBuffer( void *buffer, int bufferlength ) OVERRIDE; - virtual HANDLE ParseFromDisk( const char *pFilename ) OVERRIDE; + virtual void ParseFromBuffer( void *buffer, int bufferlength ); + virtual HANDLE ParseFromDisk( const char *pFilename ); // Forces a specific alignment size for all subsequent file operations, overriding files' previous alignment size. // Return to using files' individual alignment sizes by passing FALSE. - virtual void ForceAlignment( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize ) OVERRIDE; + virtual void ForceAlignment( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize ); // Sets the endianess of the zip - virtual void SetBigEndian( bool bigEndian ) OVERRIDE; - virtual void ActivateByteSwapping( bool bActivate ) OVERRIDE; + virtual void SetBigEndian( bool bigEndian ); + virtual void ActivateByteSwapping( bool bActivate ); - virtual unsigned int GetAlignment() OVERRIDE; + virtual unsigned int GetAlignment(); private: CZipFile m_ZipFile; @@ -1714,11 +1595,11 @@ class CZip : public IZip static CUtlLinkedList< CZip* > g_ZipUtils; IZip *IZip::CreateZip( const char *pDiskCacheWritePath, bool bSortByName ) -{ +{ CZip *pZip = new CZip( pDiskCacheWritePath, bSortByName ); g_ZipUtils.AddToTail( pZip ); - return pZip; + return pZip; } void IZip::ReleaseZip( IZip *pZip ) @@ -1747,9 +1628,9 @@ void CZip::ActivateByteSwapping( bool bActivate ) m_ZipFile.ActivateByteSwapping( bActivate ); } -void CZip::AddFileToZip( const char *relativename, const char *fullpath, eCompressionType compressionType ) +void CZip::AddFileToZip( const char *relativename, const char *fullpath ) { - m_ZipFile.AddFileToZip( relativename, fullpath, compressionType ); + m_ZipFile.AddFileToZip( relativename, fullpath ); } bool CZip::FileExistsInZip( const char *pRelativeName ) @@ -1793,9 +1674,9 @@ unsigned int CZip::EstimateSize( void ) } // Add buffer to zip as a file with given name -void CZip::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode, eCompressionType compressionType ) +void CZip::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ) { - m_ZipFile.AddBufferToZip( relativename, data, length, bTextMode, compressionType ); + m_ZipFile.AddBufferToZip( relativename, data, length, bTextMode ); } void CZip::SaveToBuffer( CUtlBuffer& outbuf ) diff --git a/public/zip_utils.h b/public/zip_utils.h index 2ac20052..be1cc8dd 100644 --- a/public/zip_utils.h +++ b/public/zip_utils.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -18,22 +18,15 @@ class CUtlBuffer; abstract_class IZip { public: - enum eCompressionType - { - // Type of compression used for this file in the zip - eCompressionType_Unknown = -1, - eCompressionType_None = 0, - eCompressionType_LZMA = 14 - }; virtual void Reset() = 0; - // Add a single file to a zip - maintains the zip's previous alignment state. - virtual void AddFileToZip ( const char *relativename, const char *fullpath, eCompressionType compressionType = eCompressionType_None ) = 0; + // Add a single file to a zip - maintains the zip's previous alignment state + virtual void AddFileToZip ( const char *relativename, const char *fullpath ) = 0; // Whether a file is contained in a zip - maintains alignment virtual bool FileExistsInZip ( const char *pRelativeName ) = 0; - // Reads a file from the zip - maintains alignement. + // Reads a file from the zip - maintains alignement virtual bool ReadFileFromZip ( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) = 0; virtual bool ReadFileFromZip ( HANDLE hFile, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) = 0; @@ -50,18 +43,18 @@ abstract_class IZip virtual unsigned int EstimateSize ( void ) = 0; // Add buffer to zip as a file with given name - uses current alignment size, default 0 (no alignment) - virtual void AddBufferToZip ( const char *relativename, void *data, int length, bool bTextMode, eCompressionType compressionType = eCompressionType_None ) = 0; + virtual void AddBufferToZip ( const char *relativename, void *data, int length, bool bTextMode ) = 0; - // Writes out zip file to a buffer - uses current alignment size + // Writes out zip file to a buffer - uses current alignment size // (set by file's previous alignment, or a call to ForceAlignment) virtual void SaveToBuffer ( CUtlBuffer& outbuf ) = 0; - // Writes out zip file to a filestream - uses current alignment size + // Writes out zip file to a filestream - uses current alignment size // (set by file's previous alignment, or a call to ForceAlignment) virtual void SaveToDisk ( FILE *fout ) = 0; virtual void SaveToDisk ( HANDLE hFileOut ) = 0; - - // Reads a zip file from a buffer into memory - sets current alignment size to + + // Reads a zip file from a buffer into memory - sets current alignment size to // the file's alignment size, unless overridden by a ForceAlignment call) virtual void ParseFromBuffer ( void *buffer, int bufferlength ) = 0; diff --git a/raytrace/raytrace.cpp b/raytrace/raytrace.cpp index 16d50a11..cb5a6005 100644 --- a/raytrace/raytrace.cpp +++ b/raytrace/raytrace.cpp @@ -141,7 +141,7 @@ void RayTracingEnvironment::AddAxisAlignedRectangularSolid(int id,Vector minc, V Vector(maxc.x,maxc.y,minc.z), Vector(maxc.x,minc.y,minc.z), Vector(maxc.x,minc.y,maxc.z),color); - + // "top" face AddQuad(id, Vector(minc.x,maxc.y,maxc.z), @@ -233,6 +233,9 @@ void CacheOptimizedTriangle::ChangeIntoIntersectionFormat(void) } +#ifndef MAPBASE +int n_intersection_calculations=0; +#endif int CacheOptimizedTriangle::ClassifyAgainstAxisSplit(int split_plane, float split_value) { @@ -241,8 +244,8 @@ int CacheOptimizedTriangle::ClassifyAgainstAxisSplit(int split_plane, float spli float maxc=minc; for(int v=1;v<3;v++) { - minc=min(minc,Vertex(v)[split_plane]); - maxc=max(maxc,Vertex(v)[split_plane]); + minc=MIN(minc,Vertex(v)[split_plane]); + maxc=MAX(maxc,Vertex(v)[split_plane]); } if (minc>=split_value) @@ -336,7 +339,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T rslt_out->surface_normal.Y(i) = tmpresults.surface_normal.Y(i); rslt_out->surface_normal.Z(i) = tmpresults.surface_normal.Z(i); } - + } } } @@ -356,7 +359,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T rslt_out->surface_normal.DuplicateVector(Vector(0.,0.,0.)); FourVectors OneOverRayDir=rays.direction; OneOverRayDir.MakeReciprocalSaturate(); - + // now, clip rays against bounding box for(int c=0;c<3;c++) { @@ -407,26 +410,26 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T back_idx[2]=1; front_idx[2]=0; } - + NodeToVisit NodeQueue[MAX_NODE_STACK_LEN]; CacheOptimizedKDNode const *CurNode=&(OptimizedKDTree[0]); NodeToVisit *stack_ptr=&NodeQueue[MAX_NODE_STACK_LEN]; while(1) { while (CurNode->NodeType() != KDNODE_STATE_LEAF) // traverse until next leaf - { + { int split_plane_number=CurNode->NodeType(); CacheOptimizedKDNode const *FrontChild=&(OptimizedKDTree[CurNode->LeftChild()]); - + fltx4 dist_to_sep_plane= // dist=(split-org)/dir MulSIMD( SubSIMD(ReplicateX4(CurNode->SplittingPlaneValue), rays.origin[split_plane_number]),OneOverRayDir[split_plane_number]); - fltx4 active=CmpLeSIMD(TMin,TMax); // mask of which rays are active + fltx4 activeLocl=CmpLeSIMD(TMin,TMax); // mask of which rays are active // now, decide how to traverse children. can either do front,back, or do front and push // back. - fltx4 hits_front=AndSIMD(active,CmpGeSIMD(dist_to_sep_plane,TMin)); + fltx4 hits_front=AndSIMD(activeLocl,CmpGeSIMD(dist_to_sep_plane,TMin)); if (! IsAnyNegative(hits_front)) { // missed the front. only traverse back @@ -437,7 +440,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T } else { - fltx4 hits_back=AndSIMD(active,CmpLeSIMD(dist_to_sep_plane,TMax)); + fltx4 hits_back=AndSIMD(activeLocl,CmpLeSIMD(dist_to_sep_plane,TMax)); if (! IsAnyNegative(hits_back) ) { // missed the back - only need to traverse front node @@ -475,6 +478,9 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T TriIntersectData_t const *tri = &( OptimizedTriangleList[tnum].m_Data.m_IntersectData ); if ( ( mailboxids[mbox_slot] != tnum ) && ( tri->m_nTriangleID != skip_id ) ) { +#ifndef MAPBASE + n_intersection_calculations++; +#endif mailboxids[mbox_slot] = tnum; // compute plane intersection @@ -505,7 +511,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T MulSIMD( isect_t, rays.direction[ tri->m_nCoordSelect0] ) ); fltx4 hitc2 = AddSIMD( rays.origin[tri->m_nCoordSelect1], MulSIMD( isect_t, rays.direction[tri->m_nCoordSelect1] ) ); - + // do barycentric coordinate check fltx4 B0 = MulSIMD( ReplicateX4( tri->m_ProjectedEdgeEquations[0] ), hitc1 ); @@ -524,7 +530,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T B1 = AddSIMD( B1, ReplicateX4( tri->m_ProjectedEdgeEquations[5] ) ); - + did_hit = AndSIMD( did_hit, CmpGeSIMD( B1, FourZeros ) ); fltx4 B2 = AddSIMD( B1, B0 ); @@ -569,7 +575,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T rslt_out->surface_normal.z=OrSIMD( AndSIMD(N.z,did_hit), AndNotSIMD(did_hit,rslt_out->surface_normal.z)); - + } } while (--ntris); // now, check if all rays have terminated @@ -579,7 +585,7 @@ void RayTracingEnvironment::Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 T return; } } - + if (stack_ptr==&NodeQueue[MAX_NODE_STACK_LEN]) { return; @@ -616,8 +622,8 @@ void RayTracingEnvironment::CalculateTriangleListBounds(int32 const *tris,int nt for(int v=0; v<3; v++) for(int c=0; c<3; c++) { - minout[c]=min(minout[c],tri.Vertex(v)[c]); - maxout[c]=max(maxout[c],tri.Vertex(v)[c]); + minout[c]=MIN(minout[c],tri.Vertex(v)[c]); + maxout[c]=MAX(maxout[c],tri.Vertex(v)[c]); } } } @@ -638,9 +644,9 @@ void RayTracingEnvironment::CalculateTriangleListBounds(int32 const *tris,int nt // termination criterion. // // the "quick" method just splits down the middle, while the slow method splits at the best -// discontinuity of the cost formula. The quick method splits along the longest axis ; the +// discontinuity of the cost formula. The quick method splits along the longest axis ; the // regular algorithm tries all 3 to find which one results in the minimum cost -// +// // both methods use the additional optimization of "growing" empty nodes - if the split results in // one side being devoid of triangles, the empty side is "grown" as much as possible. // @@ -658,7 +664,7 @@ float RayTracingEnvironment::CalculateCostsOfSplit( // that axis by storing the value in coordselect0. It will also return the number of // tris in the left, right, and nboth groups, in order to facilitate memory nleft=nboth=nright=0; - + // now, label each triangle. Since we have not converted the triangles into // intersection fromat yet, we can use the CoordSelect0 field of each as a temp. nleft=0; @@ -672,8 +678,8 @@ float RayTracingEnvironment::CalculateCostsOfSplit( // determine max and min coordinate values for later optimization for(int v=0;v<3;v++) { - min_coord = min( min_coord, tri.Vertex(v)[split_plane] ); - max_coord = max( max_coord, tri.Vertex(v)[split_plane] ); + min_coord = MIN( min_coord, tri.Vertex(v)[split_plane] ); + max_coord = MAX( max_coord, tri.Vertex(v)[split_plane] ); } switch(tri.ClassifyAgainstAxisSplit(split_plane,split_value)) { @@ -760,7 +766,7 @@ void RayTracingEnvironment::RefineNode(int node_number,int32 const *tri_list,int trial_splitvalue = tri.Vertex(tv)[axis]; if ((trial_splitvalue>MaxBound[axis]) || (trial_splitvalue + +using namespace ResponseRules; + +//----------------------------------------------------------------------------- +// Case-insensitive criteria symbol table +//----------------------------------------------------------------------------- +CUtlSymbolTable CriteriaSet::sm_CriteriaSymbols( 1024, 1024, true ); + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *raw - +// *key - +// keylen - +// *value - +// valuelen - +// *duration - +// Output : static bool +//----------------------------------------------------------------------------- +const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration, const char *entireContext ) +{ + char *colon1 = Q_strstr( raw, ":" ); + if ( !colon1 ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "SplitContext: warning, ignoring context '%s', missing colon separator!\n", raw ); + *key = *value = 0; + return NULL; + } + + int len = colon1 - raw; + Q_strncpy( key, raw, MIN( len + 1, keylen ) ); + key[ MIN( len, keylen - 1 ) ] = 0; + + bool last = false; + char *end = Q_strstr( colon1 + 1, "," ); + if ( !end ) + { + int remaining = Q_strlen( colon1 + 1 ); + end = colon1 + 1 + remaining; + last = true; + } + + char *colon2 = Q_strstr( colon1 + 1, ":" ); + if ( colon2 && ( colon2 < end ) ) + { + if ( duration ) + *duration = atof( colon2 + 1 ); + + char durationStartChar = *(colon2 + 1); + if ( durationStartChar < '0' || durationStartChar > '9' ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "SplitContext: warning, ignoring context '%s', missing comma separator! Entire context was '%s'.\n", raw, entireContext ); + *key = *value = 0; + return NULL; + } + + len = MIN( colon2 - ( colon1 + 1 ), valuelen - 1 ); + Q_strncpy( value, colon1 + 1, len + 1 ); + value[ len ] = 0; + } + else + { + if ( duration ) + *duration = 0.0; + + len = MIN( end - ( colon1 + 1 ), valuelen - 1 ); + Q_strncpy( value, colon1 + 1, len + 1 ); + value[ len ] = 0; + } + + return last ? NULL : end + 1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true), + m_nNumPrefixedContexts(0) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::CriteriaSet( const CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_nNumPrefixedContexts(src.m_nNumPrefixedContexts) +{ + m_Lookup.EnsureCapacity( src.m_Lookup.Count() ); + for ( short i = src.m_Lookup.FirstInorder(); + i != src.m_Lookup.InvalidIndex(); + i = src.m_Lookup.NextInorder( i ) ) + { + m_Lookup.Insert( src.m_Lookup[ i ] ); + } +} + +CriteriaSet::CriteriaSet( const char *criteria, const char *value ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true) +{ + AppendCriteria(criteria,value); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::~CriteriaSet() +{ +} + +//----------------------------------------------------------------------------- +// Computes a symbol for the criteria +//----------------------------------------------------------------------------- +CriteriaSet::CritSymbol_t CriteriaSet::ComputeCriteriaSymbol( const char *criteria ) +{ + return sm_CriteriaSymbols.AddString( criteria ); +} + + +//----------------------------------------------------------------------------- +// Computes a symbol for the criteria +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( CriteriaSet::CritSymbol_t criteria, const char *value, float weight ) +{ + int idx = FindCriterionIndex( criteria ); + if ( idx == -1 ) + { + CritEntry_t entry; + entry.criterianame = criteria; + MEM_ALLOC_CREDIT(); + idx = m_Lookup.Insert( entry ); + if ( sm_CriteriaSymbols.String(criteria)[0] == kAPPLYTOWORLDPREFIX ) + { + m_nNumPrefixedContexts += 1; + } + } + else // criteria already existed + { + // bail out if override existing criteria is not allowed + if ( !m_bOverrideOnAppend ) + return; + } + + CritEntry_t *entry = &m_Lookup[ idx ]; + entry->SetValue( value ); + entry->weight = weight; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criteria - +// "" - +// 1.0f - +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( const char *pCriteriaName, const char *value /*= ""*/, float weight /*= 1.0f*/ ) +{ + CUtlSymbol criteria = ComputeCriteriaSymbol( pCriteriaName ); + AppendCriteria( criteria, value, weight ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criteria - +// "" - +// 1.0f - +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( const char *criteria, float value, float weight /*= 1.0f*/ ) +{ + char buf[32]; + V_snprintf( buf, 32, "%f", value ); + AppendCriteria( criteria, buf, weight ); +} + + +//----------------------------------------------------------------------------- +// Removes criteria in a set +//----------------------------------------------------------------------------- +void CriteriaSet::RemoveCriteria( const char *criteria ) +{ + const int idx = FindCriterionIndex( criteria ); + if ( idx == -1 ) + return; + + if ( criteria[0] == kAPPLYTOWORLDPREFIX ) + { + Assert( m_nNumPrefixedContexts > 0 ); + m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 ); + } + RemoveCriteria( idx, false ); +} + +// bTestForIndex tells us whether the calling function has already checked for a +// $ prefix and decremented m_nNumPrefixedContexts appropriately (false), +// or if this function should do that (true). +void CriteriaSet::RemoveCriteria( int idx, bool bTestForPrefix ) +{ + Assert( m_Lookup.IsValidIndex(idx) ); + if ( bTestForPrefix ) + { + if ( sm_CriteriaSymbols.String( m_Lookup[idx].criterianame )[0] == kAPPLYTOWORLDPREFIX ) + { + Assert( m_nNumPrefixedContexts > 0 ); + m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 ); + } + } + m_Lookup.RemoveAt( idx ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CriteriaSet::GetCount() const +{ + return m_Lookup.Count(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// Output : int +//----------------------------------------------------------------------------- +int CriteriaSet::FindCriterionIndex( CritSymbol_t criteria ) const +{ + CritEntry_t search; + search.criterianame = criteria; + int idx = m_Lookup.Find( search ); + return ( idx == m_Lookup.InvalidIndex() ) ? -1 : idx; +} + +int CriteriaSet::FindCriterionIndex( const char *name ) const +{ + CUtlSymbol criteria = ComputeCriteriaSymbol( name ); + return FindCriterionIndex( criteria ); +} + + +//----------------------------------------------------------------------------- +// Returns the name symbol +//----------------------------------------------------------------------------- +CriteriaSet::CritSymbol_t CriteriaSet::GetNameSymbol( int nIndex ) const +{ + if ( nIndex < 0 || nIndex >= (int)m_Lookup.Count() ) + return UTL_INVAL_SYMBOL; + + const CritEntry_t *entry = &m_Lookup[ nIndex ]; + return entry->criterianame; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : char const +//----------------------------------------------------------------------------- +const char *CriteriaSet::GetName( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return ""; + else + { + const char *pCriteriaName = sm_CriteriaSymbols.String( m_Lookup[ index ].criterianame ); + return pCriteriaName ? pCriteriaName : ""; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : char const +//----------------------------------------------------------------------------- +const char *CriteriaSet::GetValue( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return ""; + + const CritEntry_t *entry = &m_Lookup[ index ]; + return entry->value ? entry->value : ""; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : float +//----------------------------------------------------------------------------- +float CriteriaSet::GetWeight( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return 1.0f; + + const CritEntry_t *entry = &m_Lookup[ index ]; + return entry->weight; +} + + +//----------------------------------------------------------------------------- +// Purpose: Merge another criteria set into this one. +//----------------------------------------------------------------------------- +void CriteriaSet::Merge( const CriteriaSet * RESTRICT otherCriteria ) +{ + Assert(otherCriteria); + if (!otherCriteria) + return; + + // for now, just duplicate everything. + int count = otherCriteria->GetCount(); + EnsureCapacity( count + GetCount() ); + for ( int i = 0 ; i < count ; ++i ) + { + AppendCriteria( otherCriteria->GetNameSymbol(i), otherCriteria->GetValue(i), otherCriteria->GetWeight(i) ); + } +} + +void CriteriaSet::Merge( const char *modifiers ) // add criteria parsed from a text string +{ + // Always include any optional modifiers + if ( modifiers == NULL ) + return; + + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + AppendCriteria( key, value, 1 ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CriteriaSet::Describe() const +{ + // build an alphabetized representation of the set for printing + typedef CUtlMap tMap; + tMap m_TempMap( 0, m_Lookup.Count(), CaselessStringLessThan ); + + for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) + { + const CritEntry_t *entry = &m_Lookup[ i ]; + + m_TempMap.Insert( sm_CriteriaSymbols.String( entry->criterianame ), entry ); + } + + for ( tMap::IndexType_t i = m_TempMap.FirstInorder(); i != m_TempMap.InvalidIndex(); i = m_TempMap.NextInorder( i ) ) + { + // const CritEntry_t *entry = &m_TempMap[ i ]; + // const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame ); + + const char *name = m_TempMap.Key( i ); + const CritEntry_t *entry = m_TempMap.Element( i ); + if ( entry->weight != 1.0f ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " %20s = '%s' (weight %f)\n", name, entry->value ? entry->value : "", entry->weight ); + } + else + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " %20s = '%s'\n", name, entry->value ? entry->value : "" ); + } + } + + /* + for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) + { + const CritEntry_t *entry = &m_Lookup[ i ]; + + const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame ); + if ( entry->weight != 1.0f ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " %20s = '%s' (weight %f)\n", pCriteriaName, entry->value ? entry->value : "", entry->weight ); + } + else + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " %20s = '%s'\n", pCriteriaName, entry->value ? entry->value : "" ); + } + } + */ +} + + +void CriteriaSet::Reset() +{ + m_Lookup.Purge(); +} + +void CriteriaSet::WriteToEntity( CBaseEntity *pEntity ) +{ +#if 0 + if ( GetCount() < 1 ) + return; + + for ( int i = Head() ; IsValidIndex(i); i = Next(i) ) + { + pEntity->AddContext( GetName(i), GetValue(i), 0 ); + } +#else + AssertMsg( false, "CriteriaSet::WriteToEntity has not been ported from l4d2.\n" ); +#endif +} + +int CriteriaSet::InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, CriteriaSet * RESTRICT pSetOnWorld ) +{ + // Assert( pFrom ); Assert( pTo ); Assert( pSetOnWorld ); + Assert( pSetOnWorld != pFrom ); + Assert( pSetOnWorld->GetCount() == 0 ); + + if ( pFrom->m_nNumPrefixedContexts == 0 ) + { + // nothing needs to be done to it. + return 0; + } + +#ifdef DEBUG + // save this off for later error checking. + const int nPrefixedContexts = pFrom->m_nNumPrefixedContexts; +#endif + + // make enough space for the expected output quantity. + pSetOnWorld->EnsureCapacity( pFrom->m_nNumPrefixedContexts ); + + // initialize a buffer with the "world" prefix (so we can use strncpy instead of snprintf and be much faster) + char buf[80] = { 'w', 'o', 'r', 'l', 'd', '\0' }; + const unsigned int PREFIXLEN = 5; // strlen("world") + + // create a second tree that has the appropriately renamed criteria, + // then swap it into pFrom + CriteriaSet rewrite; + rewrite.EnsureCapacity( pFrom->GetCount() + 1 ); + + for ( int i = pFrom->Head(); pFrom->IsValidIndex(i); i = pFrom->Next(i) ) + { + const char *pszName = pFrom->GetName( i ); + if ( pszName[0] == CriteriaSet::kAPPLYTOWORLDPREFIX ) + { // redirect to the world contexts + V_strncpy( buf+PREFIXLEN, pszName+1, sizeof(buf) - PREFIXLEN ); + rewrite.AppendCriteria( buf, pFrom->GetValue(i), pFrom->GetWeight(i) ); + pSetOnWorld->AppendCriteria( pszName+1, pFrom->GetValue(i), pFrom->GetWeight(i) ); + buf[PREFIXLEN] = 0; + } + else + { // does not need to be fiddled; do not write back to world + rewrite.AppendCriteria( pFrom->GetNameSymbol(i), pFrom->GetValue(i), pFrom->GetWeight(i) ); + } + } + AssertMsg2( pSetOnWorld->GetCount() == nPrefixedContexts, "Count of $ persistent RR contexts is inconsistent (%d vs %d)! Call Elan.", + pSetOnWorld->GetCount(), nPrefixedContexts ); + + pFrom->m_nNumPrefixedContexts = 0; + pFrom->m_Lookup.Swap(rewrite.m_Lookup); + return pSetOnWorld->GetCount(); +} diff --git a/responserules/runtime/response_rules.vpc b/responserules/runtime/response_rules.vpc new file mode 100644 index 00000000..9ab73afa --- /dev/null +++ b/responserules/runtime/response_rules.vpc @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// response_rules.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR "..\.." +$include "$SRCDIR\vpc_scripts\source_lib_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;..\public\responserules" + $PreprocessorDefinitions "$BASE;RR_RUNTIME" + } +} + +$Project "responserules_runtime" +{ + $Folder "Source Files" + { + $File "criteriaset.cpp" + $File "response_system.cpp" + $File "response_system.h" + $File "response_types.cpp" + $File "response_types_internal.cpp" + $File "response_types_internal.h" + $File "rr_convars.cpp" + $File "rr_response.cpp" + $File "rr_speechconcept.cpp" + $File "rrrlib.cpp" + } + + $Folder "Public Header Files" + { + $File "$SRCDIR\public\responserules\response_host_interface.h" + $File "$SRCDIR\public\responserules\response_types.h" + $File "$SRCDIR\public\responserules\rr_speechconcept.h" + } +} \ No newline at end of file diff --git a/responserules/runtime/response_system.cpp b/responserules/runtime/response_system.cpp new file mode 100644 index 00000000..acf64b43 --- /dev/null +++ b/responserules/runtime/response_system.cpp @@ -0,0 +1,2959 @@ +//========= Copyright © 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" +#include "vstdlib/random.h" +#include "utlbuffer.h" +#include "tier1/interval.h" +#include "convar.h" +#include "fmtstr.h" +#include "generichash.h" +#include "tier1/mapbase_con_groups.h" +#ifdef MAPBASE +#include "tier1/mapbase_matchers_base.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// #pragma optimize( "", off ) + +using namespace ResponseRules; +static void CC_RR_Debug_ResponseConcept_Exclude( const CCommand &args ); +static ConCommand rr_debug_responseconcept_exclude( "rr_debugresponseconcept_exclude", CC_RR_Debug_ResponseConcept_Exclude, "Set a list of concepts to exclude from rr_debugresponseconcept. Separate multiple concepts with spaces. Call with no arguments to see current list. Call 'rr_debug_responseconcept_exclude !' to reset."); + +namespace ResponseRules +{ + // ick + // Wrap string lookup with a hash on the string so that all of the repetitive playerxxx type strings get bucketed out better + #define STRING_BUCKETS_COUNT 64 // Must be power of two + #define STRING_BUCKETS_MASK ( STRING_BUCKETS_COUNT - 1 ) + + CUtlRBTree g_ResponseStrings[ STRING_BUCKETS_COUNT ]; + class CResponseStringBuckets + { + public: + CResponseStringBuckets() + { + for ( int i = 0; i < ARRAYSIZE( g_ResponseStrings ); ++i ) + { + g_ResponseStrings[ i ].SetLessFunc( &StringLessThan ); + } + } + } g_ReponseStringBucketInitializer; + + const char *ResponseCopyString( const char *in ) + { + if ( !in ) + return NULL; + if ( !*in ) + return ""; + + int bucket = ( RR_HASH( in ) & STRING_BUCKETS_MASK ); + + CUtlRBTree &list = g_ResponseStrings[ bucket ]; + + int i = list.Find( in ); + if ( i != list.InvalidIndex() ) +{ + return list[i]; + } + + int len = Q_strlen( in ); + char *out = new char[ len + 1 ]; + Q_memcpy( out, in, len ); + out[ len ] = 0; + list.Insert( out ); + return out; + } +} + +IEngineEmulator *IEngineEmulator::Get() +{ + AssertMsg( IEngineEmulator::s_pSingleton, "Response rules fail: no IEngineEmulator" ); + return IEngineEmulator::s_pSingleton; +} + + +//----------------------------------------------------------------------------- +// Convars +//----------------------------------------------------------------------------- + + +ConVar rr_debugresponses( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose matching output (1 for simple, 2 for rule scoring, 3 for noisy). If set to 4, it will only show response success/failure for npc_selected NPCs." ); +ConVar rr_debugrule( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); +ConVar rr_dumpresponses( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +ConVar rr_debugresponseconcept( "rr_debugresponseconcept", "", FCVAR_NONE, "If set, rr_debugresponses will print only responses testing for the specified concept" ); +#define RR_DEBUGRESPONSES_SPECIALCASE 4 + +#ifdef MAPBASE +ConVar rr_disableemptyrules( "rr_disableemptyrules", "0", FCVAR_NONE, "Disables rules with no remaining responses, e.g. rules which use norepeat responses." ); +#endif + + + +//----------------------------------------------------------------------------- +// Copied from SoundParametersInternal.cpp +//----------------------------------------------------------------------------- + +#define SNDLVL_PREFIX "SNDLVL_" + +struct SoundLevelLookup +{ + soundlevel_t level; + char const *name; +}; + +// NOTE: Needs to reflect the soundlevel_t enum defined in soundflags.h +static SoundLevelLookup g_pSoundLevels[] = +{ + { SNDLVL_NONE, "SNDLVL_NONE" }, + { SNDLVL_20dB, "SNDLVL_20dB" }, + { SNDLVL_25dB, "SNDLVL_25dB" }, + { SNDLVL_30dB, "SNDLVL_30dB" }, + { SNDLVL_35dB, "SNDLVL_35dB" }, + { SNDLVL_40dB, "SNDLVL_40dB" }, + { SNDLVL_45dB, "SNDLVL_45dB" }, + { SNDLVL_50dB, "SNDLVL_50dB" }, + { SNDLVL_55dB, "SNDLVL_55dB" }, + { SNDLVL_IDLE, "SNDLVL_IDLE" }, + { SNDLVL_TALKING, "SNDLVL_TALKING" }, + { SNDLVL_60dB, "SNDLVL_60dB" }, + { SNDLVL_65dB, "SNDLVL_65dB" }, + { SNDLVL_STATIC, "SNDLVL_STATIC" }, + { SNDLVL_70dB, "SNDLVL_70dB" }, + { SNDLVL_NORM, "SNDLVL_NORM" }, + { SNDLVL_75dB, "SNDLVL_75dB" }, + { SNDLVL_80dB, "SNDLVL_80dB" }, + { SNDLVL_85dB, "SNDLVL_85dB" }, + { SNDLVL_90dB, "SNDLVL_90dB" }, + { SNDLVL_95dB, "SNDLVL_95dB" }, + { SNDLVL_100dB, "SNDLVL_100dB" }, + { SNDLVL_105dB, "SNDLVL_105dB" }, + { SNDLVL_110dB, "SNDLVL_110dB" }, + { SNDLVL_120dB, "SNDLVL_120dB" }, + { SNDLVL_130dB, "SNDLVL_130dB" }, + { SNDLVL_GUNFIRE, "SNDLVL_GUNFIRE" }, + { SNDLVL_140dB, "SNDLVL_140dB" }, + { SNDLVL_150dB, "SNDLVL_150dB" }, + { SNDLVL_180dB, "SNDLVL_180dB" }, +}; + +static soundlevel_t TextToSoundLevel( const char *key ) +{ + if ( !key ) + { + Assert( 0 ); + return SNDLVL_NORM; + } + + int c = ARRAYSIZE( g_pSoundLevels ); + + int i; + + for ( i = 0; i < c; i++ ) + { + SoundLevelLookup *entry = &g_pSoundLevels[ i ]; + if ( !Q_strcasecmp( key, entry->name ) ) + return entry->level; + } + + if ( !Q_strnicmp( key, SNDLVL_PREFIX, Q_strlen( SNDLVL_PREFIX ) ) ) + { + char const *val = key + Q_strlen( SNDLVL_PREFIX ); + int sndlvl = atoi( val ); + if ( sndlvl > 0 && sndlvl <= 180 ) + { + return ( soundlevel_t )sndlvl; + } + } + + DevMsg( "CSoundEmitterSystem: Unknown sound level %s\n", key ); + + return SNDLVL_NORM; +} + +CResponseSystem::ExcludeList_t CResponseSystem::m_DebugExcludeList( 4, 0 ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CResponseSystem::CResponseSystem() : + m_RootCommandHashes( 0, 0, DefLessFunc( unsigned int ) ), + m_FileDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_RuleDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_ResponseDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_ResponseGroupDispatch( 0, 0, DefLessFunc( unsigned int ) ) +{ + token[0] = 0; + m_bUnget = false; + m_bCustomManagable = false; +#ifdef MAPBASE + m_bInProspective = false; +#endif + + BuildDispatchTables(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CResponseSystem::~CResponseSystem() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CResponseSystem::GetCurrentScript( char *buf, size_t buflen ) +{ + Assert( buf ); + buf[ 0 ] = 0; + if ( m_ScriptStack.Count() <= 0 ) + return; + + if ( IEngineEmulator::Get()->GetFilesystem()->String( m_ScriptStack[ 0 ].name, buf, buflen ) ) + { + return; + } + buf[ 0 ] = 0; +} + +void CResponseSystem::PushScript( const char *scriptfile, unsigned char *buffer ) +{ + ScriptEntry e; + e.name = IEngineEmulator::Get()->GetFilesystem()->FindOrAddFileName( scriptfile ); + e.buffer = buffer; + e.currenttoken = (char *)e.buffer; + e.tokencount = 0; + m_ScriptStack.AddToHead( e ); +} + +void CResponseSystem::PopScript(void) +{ + Assert( m_ScriptStack.Count() >= 1 ); + if ( m_ScriptStack.Count() <= 0 ) + return; + + m_ScriptStack.Remove( 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::Clear() +{ + m_Responses.RemoveAll(); + m_Criteria.RemoveAll(); +#ifdef MAPBASE + // Must purge to avoid issues with reloading the system + m_RulePartitions.PurgeAndDeleteElements(); +#else + m_RulePartitions.RemoveAll(); +#endif + m_Enumerations.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// found - +// Output : float +//----------------------------------------------------------------------------- +float CResponseSystem::LookupEnumeration( const char *name, bool& found ) +{ + int idx = m_Enumerations.Find( name ); + if ( idx == m_Enumerations.InvalidIndex() ) + { + found = false; + return 0.0f; + } + + + found = true; + return m_Enumerations[ idx ].value; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : matcher - +//----------------------------------------------------------------------------- +void CResponseSystem::ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ) +{ + if ( rawtoken[0] != '[' ) + { + Q_strncpy( token, rawtoken, bufsize ); + return; + } + + // Now lookup enumeration + bool found = false; + float f = LookupEnumeration( rawtoken, found ); + if ( !found ) + { + Q_strncpy( token, rawtoken, bufsize ); + ResponseWarning( "No such enumeration '%s'\n", token ); + return; + } + + Q_snprintf( token, bufsize, "%f", f ); +} + + +#ifndef MAPBASE // Already in mapbase_matchers_base +static bool AppearsToBeANumber( char const *token ) +{ + if ( atof( token ) != 0.0f ) + return true; + + char const *p = token; + while ( *p ) + { + if ( *p != '0' ) + return false; + + p++; + } + + return true; +} +#endif + +void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) +{ + const char *s = c->value; + if ( !s ) + { + matcher.valid = false; + return; + } + + const char *in = s; + + char token[ 128 ]; + char rawtoken[ 128 ]; + + token[ 0 ] = 0; + rawtoken[ 0 ] = 0; + + int n = 0; + + bool gt = false; + bool lt = false; + bool eq = false; + bool nt = false; +#ifdef MAPBASE + bool bit = false; +#endif + + bool done = false; + while ( !done ) + { + switch( *in ) + { + case '>': + { + gt = true; + Assert( !lt ); // Can't be both + } + break; + case '<': + { + lt = true; + Assert( !gt ); // Can't be both + } + break; + case '=': + { + eq = true; + } + break; + case ',': + case '\0': + { + rawtoken[ n ] = 0; + n = 0; + + // Convert raw token to real token in case token is an enumerated type specifier + ResolveToken( matcher, token, sizeof( token ), rawtoken ); + +#ifdef MAPBASE + // Bits are an entirely different and independent story + if (bit) + { + matcher.isbit = true; + matcher.notequal = nt; + + matcher.isnumeric = true; + } + else +#endif + // Fill in first data set + if ( gt ) + { + matcher.usemin = true; + matcher.minequals = eq; + matcher.minval = (float)atof( token ); + + matcher.isnumeric = true; + } + else if ( lt ) + { + matcher.usemax = true; + matcher.maxequals = eq; + matcher.maxval = (float)atof( token ); + + matcher.isnumeric = true; + } + else + { + if ( *in == ',' ) + { + // If there's a comma, this better have been a less than or a gt key + Assert( 0 ); + } + + matcher.notequal = nt; + + matcher.isnumeric = AppearsToBeANumber( token ); + } + + gt = lt = eq = nt = false; + + if ( !(*in) ) + { + done = true; + } + } + break; + case '!': + nt = true; + break; +#ifdef MAPBASE + case '~': + nt = true; + case '&': + bit = true; + break; +#endif + default: + rawtoken[ n++ ] = *in; + break; + } + + in++; + } + + matcher.SetToken( token ); + matcher.SetRaw( rawtoken ); + matcher.valid = true; +} + +bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose /*=false*/ ) +{ + if ( !m.valid ) + return false; + + float v = (float)atof( setValue ); + if ( setValue[0] == '[' ) + { + bool found = false; + v = LookupEnumeration( setValue, found ); + } + +#ifdef MAPBASE + // Bits are always a different story + if (m.isbit) + { + int v1 = v; + int v2 = atoi( m.GetToken() ); + if (m.notequal) + return (v1 & v2) == 0; + else + return (v1 & v2) != 0; + } +#endif + + int minmaxcount = 0; + + if ( m.usemin ) + { + if ( m.minequals ) + { + if ( v < m.minval ) + return false; + } + else + { + if ( v <= m.minval ) + return false; + } + + ++minmaxcount; + } + + if ( m.usemax ) + { + if ( m.maxequals ) + { + if ( v > m.maxval ) + return false; + } + else + { + if ( v >= m.maxval ) + return false; + } + + ++minmaxcount; + } + + // Had one or both criteria and met them + if ( minmaxcount >= 1 ) + { + return true; + } + + if ( m.notequal ) + { + if ( m.isnumeric ) + { + if ( v == (float)atof( m.GetToken() ) ) + return false; + } + else + { +#ifdef MAPBASE + if ( Matcher_NamesMatch( m.GetToken(), setValue ) ) +#else + if ( !Q_stricmp( setValue, m.GetToken() ) ) +#endif + return false; + } + + return true; + } + + if ( m.isnumeric ) + { + // If the setValue is "", the NPC doesn't have the key at all, + // in which case we shouldn't match "0". + if ( !setValue || !setValue[0] ) + return false; + + return v == (float)atof( m.GetToken() ); + } + +#ifdef MAPBASE + return Matcher_NamesMatch( m.GetToken(), setValue ); +#else + return !Q_stricmp( setValue, m.GetToken() ) ? true : false; +#endif +} + +bool CResponseSystem::Compare( const char *setValue, Criteria *c, bool verbose /*= false*/ ) +{ + Assert( c ); + Assert( setValue ); + + bool bret = CompareUsingMatcher( setValue, c->matcher, verbose ); + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "'%20s' vs. '%20s' = ", setValue, c->value ); + + { + //DevMsg( "\n" ); + //m.Describe(); + } + } + return bret; +} + +float CResponseSystem::RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ) +{ + float score = 0.0f; + int subcount = parent->subcriteria.Count(); + for ( int i = 0; i < subcount; i++ ) + { + int icriterion = parent->subcriteria[ i ]; + + bool excludesubrule = false; + if (verbose) + { + DevMsg( "\n" ); + } + score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, excludesubrule, verbose ); + } + + exclude = ( parent->required && score == 0.0f ) ? true : false; + + return score * parent->weight.GetFloat(); +} + +float CResponseSystem::RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent ) +{ + float flScore = 0.0f; + int nSubCount = pParent->subcriteria.Count(); + for ( int iSub = 0; iSub < nSubCount; ++iSub ) + { + int iCriteria = pParent->subcriteria[iSub]; + flScore += LookForCriteria( criteriaSet, iCriteria ); + } + + return flScore; +} + +float CResponseSystem::LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria ) +{ + Criteria *pCriteria = &m_Criteria[iCriteria]; + if ( pCriteria->IsSubCriteriaType() ) + { + return RecursiveLookForCriteria( criteriaSet, pCriteria ); + } + + int iIndex = criteriaSet.FindCriterionIndex( pCriteria->nameSym ); + if ( iIndex == -1 ) + return 0.0f; + + Assert( criteriaSet.GetValue( iIndex ) ); + if ( Q_stricmp( criteriaSet.GetValue( iIndex ), pCriteria->value ) ) + return 0.0f; + + return 1.0f; +} + +float CResponseSystem::ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose /*=false*/ ) +{ + Criteria *c = &m_Criteria[ icriterion ]; + + if ( c->IsSubCriteriaType() ) + { + return RecursiveScoreSubcriteriaAgainstRule( set, c, exclude, verbose ); + } + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " criterion '%25s':'%15s' ", m_Criteria.GetElementName( icriterion ), CriteriaSet::SymbolToStr(c->nameSym) ); + } + + exclude = false; + + float score = 0.0f; + + const char *actualValue = ""; + + /* + const char * RESTRICT critname = c->name; + CUtlSymbol sym(critname); + const char * nameDoubleCheck = sym.String(); + */ + int found = set.FindCriterionIndex( c->nameSym ); + if ( found != -1 ) + { + actualValue = set.GetValue( found ); + if ( !actualValue ) + { + Assert( 0 ); + return score; + } + } + + Assert( actualValue ); + + if ( Compare( actualValue, c, verbose ) ) + { + float w = set.GetWeight( found ); + score = w * c->weight.GetFloat(); + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "matched, weight %4.2f (s %4.2f x c %4.2f)", + score, w, c->weight.GetFloat() ); + } + } + else + { + if ( c->required ) + { + exclude = true; + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "failed (+exclude rule)" ); + } + } + else + { + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "failed" ); + } + } + } + + return score; +} + +float CResponseSystem::ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose /*=false*/ ) +{ + Rule * RESTRICT rule = dict[ irule ]; + float score = 0.0f; + + bool bBeingWatched = false; + + // See if we're trying to debug this rule + const char *pszText = rr_debugrule.GetString(); + if ( pszText && pszText[0] && !Q_stricmp( pszText, dict.GetElementName( irule ) ) ) + { + bBeingWatched = true; + } + + if ( !rule->IsEnabled() ) + { + if ( bBeingWatched ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Rule is disabled.\n" ); + } + return 0.0f; + } + + if ( bBeingWatched ) + { + verbose = true; + } + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Scoring rule '%s' (%i)\n{\n", dict.GetElementName( irule ), irule+1 ); + } + + // Iterate set criteria + int count = rule->m_Criteria.Count(); + int i; + for ( i = 0; i < count; i++ ) + { + int icriterion = rule->m_Criteria[ i ]; + + bool exclude = false; + score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, exclude, verbose ); + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, ", score %4.2f\n", score ); + } + + if ( exclude ) + { + score = 0.0f; + break; + } + } + + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "}\n" ); + } + + if ( rule->m_nForceWeight > 0 ) + { // this means override the cumulative weight of criteria and just force the rule's total score, + // assuming it matched at all. + return fsel( score - FLT_MIN, rule->m_nForceWeight, 0 ); + } + else + { + return score; +} +} + +void CResponseSystem::DebugPrint( int depth, const char *fmt, ... ) +{ + int indentchars = 3 * depth; + char *indent = (char *) stackalloc( indentchars + 1); + indent[ indentchars ] = 0; + while ( --indentchars >= 0 ) + { + indent[ indentchars ] = ' '; + } + + // Dump text to debugging console. + va_list argptr; + char szText[1024]; + + va_start (argptr, fmt); + Q_vsnprintf (szText, sizeof( szText ), fmt, argptr); + va_end (argptr); + + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "%s%s", indent, szText ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::ResetResponseGroups() +{ + int i; + int c = m_Responses.Count(); + for ( i = 0; i < c; i++ ) + { + m_Responses[ i ].Reset(); + } + +#ifdef MAPBASE + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + m_RulePartitions[ idx ].m_bEnabled = true; + } +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::DisableEmptyRules() +{ + if (rr_disableemptyrules.GetBool() == false) + return; + + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + Rule &rule = m_RulePartitions[ idx ]; + + // Set it as disabled in advance + rule.m_bEnabled = false; + + int c2 = rule.m_Responses.Count(); + for (int s = 0; s < c2; s++) + { + if (m_Responses[rule.m_Responses[s]].IsEnabled()) + { + // Re-enable it if there's any valid responses + rule.m_bEnabled = true; + break; + } + } + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Make certain responses unavailable by marking them as depleted +//----------------------------------------------------------------------------- +void CResponseSystem::FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter ) +{ + m_FakedDepletes.RemoveAll(); + + // Fake depletion of unavailable choices + int c = g->group.Count(); + if ( pFilter && g->ShouldCheckRepeats() ) + { + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( r->depletioncount != g->GetDepletionCount() && !pFilter->IsValidResponse( r->GetType(), r->value ) ) + { + m_FakedDepletes.AddToTail( i ); + g->MarkResponseUsed( i ); + } + } + } + + // Fake depletion of choices that fail the odds check + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( RandomInt( 1, 100 ) > r->params.odds ) + { + m_FakedDepletes.AddToTail( i ); + g->MarkResponseUsed( i ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Restore responses that were faked as being depleted +//----------------------------------------------------------------------------- +void CResponseSystem::RevertFakedDepletes( ResponseGroup *g ) +{ + for ( int i = 0; i < m_FakedDepletes.Count(); i++ ) + { + g->group[ m_FakedDepletes[ i ] ].depletioncount = 0; + } + m_FakedDepletes.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *g - +// Output : int +//----------------------------------------------------------------------------- +int CResponseSystem::SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ) +{ + int c = g->group.Count(); + if ( !c ) + { + Assert( !"Expecting response group with >= 1 elements" ); + return -1; + } + + FakeDepletes( g, pFilter ); + + if ( !g->HasUndepletedChoices() ) + { + g->ResetDepletionCount(); + + FakeDepletes( g, pFilter ); + + if ( !g->HasUndepletedChoices() ) + return -1; + + // Disable the group if we looped through all the way + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); +#ifdef MAPBASE + DisableEmptyRules(); +#endif + return -1; + } + } + + bool checkrepeats = g->ShouldCheckRepeats(); + int depletioncount = g->GetDepletionCount(); + + float totalweight = 0.0f; + int slot = -1; + + if ( checkrepeats ) + { + int check= -1; + // Snag the first slot right away + if ( g->HasUndepletedFirst( check ) && check != -1 ) + { + slot = check; + } + + if ( slot == -1 && g->HasUndepletedLast( check ) && check != -1 ) + { + // If this is the only undepleted one, use it now + int i; + for ( i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( checkrepeats && + ( r->depletioncount == depletioncount ) ) + { + continue; + } + + if ( r->last ) + { + Assert( i == check ); + continue; + } + + // There's still another undepleted entry + break; + } + + // No more undepleted so use the r->last slot + if ( i >= c ) + { + slot = check; + } + } + } + + if ( slot == -1 ) + { + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( checkrepeats && + ( r->depletioncount == depletioncount ) ) + { + continue; + } + + // Always skip last entry here since we will deal with it above + if ( checkrepeats && r->last ) + continue; + + int prevSlot = slot; + + if ( !totalweight ) + { + slot = i; + } + + // Always assume very first slot will match + totalweight += r->weight.GetFloat(); + if ( !totalweight || IEngineEmulator::Get()->GetRandomStream()->RandomFloat(0,totalweight) < r->weight.GetFloat() ) + { + slot = i; + } + + if ( !checkrepeats && slot != prevSlot && pFilter && !pFilter->IsValidResponse( r->GetType(), r->value ) ) + { + slot = prevSlot; + totalweight -= r->weight.GetFloat(); + } + } + } + + if ( slot != -1 ) + { +#ifdef MAPBASE + // Don't mark responses as used in prospective mode + if (m_bInProspective == false) +#endif + g->MarkResponseUsed( slot ); + } + + // Revert fake depletion of unavailable choices + RevertFakedDepletes( g ); + + return slot; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : searchResult - +// depth - +// *name - +// verbose - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CResponseSystem::ResolveResponse( ResponseSearchResult& searchResult, int depth, const char *name, bool verbose /*= false*/, IResponseFilter *pFilter ) +{ + int responseIndex = m_Responses.Find( name ); + if ( responseIndex == m_Responses.InvalidIndex() ) + return false; + + ResponseGroup *g = &m_Responses[ responseIndex ]; + // Group has been disabled + if ( !g->IsEnabled() ) + return false; + + int c = g->group.Count(); + if ( !c ) + return false; + + int idx = 0; + + if ( g->IsSequential() ) + { + // See if next index is valid + int initialIndex = g->GetCurrentIndex(); + bool bFoundValid = false; + + do + { + idx = g->GetCurrentIndex(); + g->SetCurrentIndex( idx + 1 ); + if ( idx >= c ) + { + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); +#ifdef MAPBASE + DisableEmptyRules(); +#endif + return false; + } + idx = 0; + g->SetCurrentIndex( 0 ); + } + + if ( !pFilter || pFilter->IsValidResponse( g->group[idx].GetType(), g->group[idx].value ) ) + { + bFoundValid = true; + break; + } + + } while ( g->GetCurrentIndex() != initialIndex ); + + if ( !bFoundValid ) + return false; + } + else + { + idx = SelectWeightedResponseFromResponseGroup( g, pFilter ); + if ( idx < 0 ) + return false; + } + + if ( verbose ) + { + DebugPrint( depth, "%s\n", m_Responses.GetElementName( responseIndex ) ); + DebugPrint( depth, "{\n" ); + DescribeResponseGroup( g, idx, depth ); + } + + bool bret = true; + + ParserResponse *result = &g->group[ idx ]; + if ( result->type == RESPONSE_RESPONSE ) + { + // Recurse + bret = ResolveResponse( searchResult, depth + 1, result->value, verbose, pFilter ); + } + else + { + searchResult.action = result; + searchResult.group = g; + } + + if( verbose ) + { + DebugPrint( depth, "}\n" ); + } + + return bret; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *group - +// selected - +// depth - +//----------------------------------------------------------------------------- +void CResponseSystem::DescribeResponseGroup( ResponseGroup *group, int selected, int depth ) +{ + int c = group->group.Count(); + + for ( int i = 0; i < c ; i++ ) + { + ParserResponse *r = &group->group[ i ]; + DebugPrint( depth + 1, "%s%20s : %40s %5.3f\n", + i == selected ? "-> " : " ", + CRR_Response::DescribeResponse( r->GetType() ), + r->value, + r->weight.GetFloat() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *rule - +// Output : CResponseSystem::Response +//----------------------------------------------------------------------------- +bool CResponseSystem::GetBestResponse( ResponseSearchResult& searchResult, Rule *rule, bool verbose /*=false*/, IResponseFilter *pFilter ) +{ + int c = rule->m_Responses.Count(); + if ( !c ) + return false; + + int index = IEngineEmulator::Get()->GetRandomStream()->RandomInt( 0, c - 1 ); + int groupIndex = rule->m_Responses[ index ]; + + ResponseGroup *g = &m_Responses[ groupIndex ]; + + // Group has been disabled + if ( !g->IsEnabled() ) + return false; + + int count = g->group.Count(); + if ( !count ) + return false; + + int responseIndex = 0; + + if ( g->IsSequential() ) + { + // See if next index is valid + int initialIndex = g->GetCurrentIndex(); + bool bFoundValid = false; + + do + { + responseIndex = g->GetCurrentIndex(); + g->SetCurrentIndex( responseIndex + 1 ); + if ( responseIndex >= count ) + { + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); +#ifdef MAPBASE + DisableEmptyRules(); +#endif + return false; + } + responseIndex = 0; + g->SetCurrentIndex( 0 ); + } + + if ( !pFilter || pFilter->IsValidResponse( g->group[responseIndex].GetType(), g->group[responseIndex].value ) ) + { + bFoundValid = true; + break; + } + + } while ( g->GetCurrentIndex() != initialIndex ); + + if ( !bFoundValid ) + return false; + } + else + { + responseIndex = SelectWeightedResponseFromResponseGroup( g, pFilter ); + if ( responseIndex < 0 ) + return false; + } + + + ParserResponse *r = &g->group[ responseIndex ]; + + int depth = 0; + + if ( verbose ) + { + DebugPrint( depth, "%s\n", m_Responses.GetElementName( groupIndex ) ); + DebugPrint( depth, "{\n" ); + + DescribeResponseGroup( g, responseIndex, depth ); + } + + bool bret = true; + + if ( r->type == RESPONSE_RESPONSE ) + { + bret = ResolveResponse( searchResult, depth + 1, r->value, verbose, pFilter ); + } + else + { + searchResult.action = r; + searchResult.group = g; + } + + if ( verbose ) + { + DebugPrint( depth, "}\n" ); + } + + return bret; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : set - +// verbose - +// Output : int +// Warning: If you change this, be sure to also change +// ResponseSystemImplementationCLI::FindAllRulesMatchingCriteria(). +//----------------------------------------------------------------------------- +ResponseRulePartition::tIndex CResponseSystem::FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule ) +{ + CUtlVector< ResponseRulePartition::tIndex > bestrules(16,4); + float bestscore = 0.001f; + scoreOfBestMatchingRule = 0; + + CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > buckets( 0, 2 ); + m_RulePartitions.GetDictsForCriteria( &buckets, set ); + for ( int b = 0 ; b < buckets.Count() ; ++b ) + { + ResponseRulePartition::tRuleDict *prules = buckets[b]; + int c = prules->Count(); + int i; + for ( i = 0; i < c; i++ ) + { + float score = ScoreCriteriaAgainstRule( set, *prules, i, verbose ); + // Check equals so that we keep track of all matching rules + if ( score >= bestscore ) + { + // Reset bucket + if( score != bestscore ) + { + bestscore = score; + bestrules.RemoveAll(); + } + + // Add to bucket + bestrules.AddToTail( m_RulePartitions.IndexFromDictElem( prules, i ) ); + } + } + } + + int bestCount = bestrules.Count(); + if ( bestCount <= 0 ) + return m_RulePartitions.InvalidIdx(); + + scoreOfBestMatchingRule = bestscore ; + if ( bestCount == 1 ) + { + return bestrules[ 0 ] ; + } + else + { + // Randomly pick one of the tied matching rules + int idx = IEngineEmulator::Get()->GetRandomStream()->RandomInt( 0, bestCount - 1 ); + if ( verbose ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Found %i matching rules, selecting slot %i\n", bestCount, idx ); + } + return bestrules[ idx ] ; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : set - +// Output : CRR_Response +//----------------------------------------------------------------------------- +bool CResponseSystem::FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter ) +{ + bool valid = false; + + int iDbgResponse = rr_debugresponses.GetInt(); + bool showRules = ( iDbgResponse >= 2 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ); + bool showResult = ( iDbgResponse >= 1 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ); + + // Look for match. verbose mode used to be at level 2, but disabled because the writers don't actually care for that info. + float scoreOfBestRule; + ResponseRulePartition::tIndex bestRule = FindBestMatchingRule( set, + ( iDbgResponse >= 3 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ), + scoreOfBestRule ); + + ResponseType_t responseType = RESPONSE_NONE; + ResponseParams rp; + + char ruleName[ 128 ]; + char responseName[ 128 ]; + const char *context; +#ifdef MAPBASE + int contextflags; +#else + bool bcontexttoworld; +#endif + ruleName[ 0 ] = 0; + responseName[ 0 ] = 0; + context = NULL; +#ifdef MAPBASE + contextflags = 0; +#else + bcontexttoworld = false; +#endif + if ( m_RulePartitions.IsValid( bestRule ) ) + { + Rule * RESTRICT r = &m_RulePartitions[ bestRule ]; + + ResponseSearchResult result; + if ( GetBestResponse( result, r, showResult, pFilter ) ) + { + Q_strncpy( responseName, result.action->value, sizeof( responseName ) ); + responseType = result.action->GetType(); + rp = result.action->params; + rp.m_pFollowup = &result.action->m_followup; + } + + Q_strncpy( ruleName, m_RulePartitions.GetElementName( bestRule ), sizeof( ruleName ) ); + + // Disable the rule if it only allows for matching one time + if ( r->IsMatchOnce() ) + { + r->Disable(); + } + context = r->GetContext(); +#ifdef MAPBASE + contextflags = r->GetContextFlags(); + + // Sets the internal indices for the response to call back to later for prospective responses + // (NOTE: Performance not tested; Be wary of turning off the m_bInProspective check!) + if (m_bInProspective) + { + for ( int i = 0; i < (int)m_Responses.Count(); i++ ) + { + if (&m_Responses[i] == result.group) + { + ResponseGroup &group = m_Responses[i]; + for ( int j = 0; j < group.group.Count(); j++) + { + if (&group.group[j] == result.action) + { + response.SetInternalIndices( i, j ); + } + } + } + } + } +#else + bcontexttoworld = r->IsApplyContextToWorld(); +#endif + + response.SetMatchScore(scoreOfBestRule); + valid = true; + } + +#ifdef MAPBASE + response.Init( responseType, responseName, rp, ruleName, context, contextflags ); +#else + response.Init( responseType, responseName, rp, ruleName, context, bcontexttoworld ); +#endif + + if ( showResult ) + { + /* + // clipped -- chet doesn't really want this info + if ( valid ) + { + // Rescore the winner and dump to console + ScoreCriteriaAgainstRule( set, bestRule, true ); + } + */ + + + if ( valid || showRules ) + { + const char *pConceptFilter = rr_debugresponseconcept.GetString(); + // Describe the response, too + if ( V_strlen(pConceptFilter) > 0 && !rr_debugresponseconcept.GetBool() ) + { // filter for only one concept + if ( V_stricmp(pConceptFilter, set.GetValue(set.FindCriterionIndex("concept")) ) == 0 ) + { + response.Describe(&set); + } // else don't print + } + else + { + // maybe we need to filter *out* some concepts + if ( m_DebugExcludeList.IsValidIndex( m_DebugExcludeList.Head() ) ) + { + // we are excluding at least one concept + CRR_Concept test( set.GetValue(set.FindCriterionIndex("concept")) ); + if ( ! m_DebugExcludeList.IsValidIndex( m_DebugExcludeList.Find( test ) ) ) + { // if not found in exclude list, then print + response.Describe(&set); + } + } + else + { + // describe everything + response.Describe(&set); + } + } + } + } + + return valid; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::GetAllResponses( CUtlVector *pResponses ) +{ + for ( int i = 0; i < (int)m_Responses.Count(); i++ ) + { + ResponseGroup &group = m_Responses[i]; + + for ( int j = 0; j < group.group.Count(); j++) + { + ParserResponse &response = group.group[j]; + if ( response.type != RESPONSE_RESPONSE ) + { + /* + CRR_Response *pResponse = new CRR_Response; + pResponse->Init( response.GetType(), response.value, CriteriaSet(), response.params, NULL, NULL, false ); + pResponses->AddToTail(pResponse); + */ + pResponses->Element(pResponses->AddToTail()).Init( response.GetType(), response.value, response.params, NULL, NULL, false ); + } + } + } +} + +#ifdef MAPBASE +void CResponseSystem::MarkResponseAsUsed( short iGroup, short iWithinGroup ) +{ + if (m_Responses.Count() > (unsigned int)iGroup) + { + ResponseGroup &group = m_Responses[iGroup]; + if (group.group.Count() > (int)iWithinGroup) + { + group.MarkResponseUsed( iWithinGroup ); + + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Marked response %s (%i) used\n", group.group[iWithinGroup].value, iWithinGroup ); + } + } +} +#endif + +void CResponseSystem::ParseInclude() +{ + char includefile[ 256 ]; + ParseToken(); + +#ifdef MAPBASE + char scriptfile[256]; + GetCurrentScript( scriptfile, sizeof( scriptfile ) ); + + // Gets first path + // (for example, an #include from a file in resource/script/resp will return resource) + size_t len = strlen(scriptfile)-1; + for (size_t i = 0; i < len; i++) + { + if (scriptfile[i] == CORRECT_PATH_SEPARATOR || scriptfile[i] == INCORRECT_PATH_SEPARATOR) + { + len = i; + } + } + Q_strncpy(includefile, scriptfile, len+1); + + if (len+1 != strlen(scriptfile)) + { + Q_strncat( includefile, "/", sizeof( includefile ) ); + Q_strncat( includefile, token, sizeof( includefile ) ); + } + else + includefile[0] = '\0'; + + if (!includefile[0]) + Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); +#else + Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); +#endif + + // check if the file is already included + if ( m_IncludedFiles.Find( includefile ) != NULL ) + { + return; + } + + MEM_ALLOC_CREDIT(); + + // Try and load it + CUtlBuffer buf; + if ( !IEngineEmulator::Get()->GetFilesystem()->ReadFile( includefile, "GAME", buf ) ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Unable to load #included script %s\n", includefile ); + return; + } + + LoadFromBuffer( includefile, (const char *)buf.PeekGet() ); +} + +void CResponseSystem::LoadFromBuffer( const char *scriptfile, const char *buffer ) +{ + COM_TimestampedLog( "CResponseSystem::LoadFromBuffer [%s] - Start", scriptfile ); + m_IncludedFiles.Allocate( scriptfile ); + PushScript( scriptfile, (unsigned char * )buffer ); + + if( rr_dumpresponses.GetBool() ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM,"Reading: %s\n", scriptfile ); + } + + while ( 1 ) + { + ParseToken(); + if ( !token[0] ) + { + break; + } + + unsigned int hash = RR_HASH( token ); + bool bSuccess = Dispatch( token, hash, m_FileDispatch ); + if ( !bSuccess ) + { + int byteoffset = m_ScriptStack[ 0 ].currenttoken - (const char *)m_ScriptStack[ 0 ].buffer; + + Error( "CResponseSystem::LoadFromBuffer: Unknown entry type '%s', expecting 'response', 'criterion', 'enumeration' or 'rules' in file %s(offset:%i)\n", + token, scriptfile, byteoffset ); + break; + } + } + + if ( m_ScriptStack.Count() == 1 ) + { + char cur[ 256 ]; + GetCurrentScript( cur, sizeof( cur ) ); + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "CResponseSystem: %s (%i rules, %i criteria, and %i responses)\n", + cur, m_RulePartitions.Count(), m_Criteria.Count(), m_Responses.Count() ); + + if( rr_dumpresponses.GetBool() ) + { + DumpRules(); + } + } + + PopScript(); + COM_TimestampedLog( "CResponseSystem::LoadFromBuffer [%s] - Finish", scriptfile ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::LoadRuleSet( const char *basescript ) +{ + float flStart = Plat_FloatTime(); + int length = 0; + unsigned char *buffer = (unsigned char *)IEngineEmulator::Get()->LoadFileForMe( basescript, &length ); + if ( length <= 0 || !buffer ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "CResponseSystem: failed to load %s\n", basescript ); + return; + } + + m_IncludedFiles.FreeAll(); + LoadFromBuffer( basescript, (const char *)buffer ); + + IEngineEmulator::Get()->FreeFile( buffer ); + + Assert( m_ScriptStack.Count() == 0 ); + float flEnd = Plat_FloatTime(); + COM_TimestampedLog( "CResponseSystem::LoadRuleSet took %f msec", 1000.0f * ( flEnd - flStart ) ); +} + +inline ResponseType_t ComputeResponseType( const char *s ) +{ + switch ( s[ 0 ] ) + { + default: + break; + case 's': + switch ( s[ 1 ] ) + { + default: + break; + case 'c': + return RESPONSE_SCENE; + case 'e': + return RESPONSE_SENTENCE; + case 'p': + return RESPONSE_SPEAK; + } + break; + case 'r': + return RESPONSE_RESPONSE; + case 'p': + return RESPONSE_PRINT; + case 'e': + return RESPONSE_ENTITYIO; +#ifdef MAPBASE + case 'v': + if (*(s + 7) == '_') + return RESPONSE_VSCRIPT_FILE; + else + return RESPONSE_VSCRIPT; +#endif + } + + return RESPONSE_NONE; +} + +void CResponseSystem::ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + newResponse.weight.SetFloat( (float)atof( token ) ); +} + +void CResponseSystem::ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; + rp->predelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.start = 0; + rp->delay.range = 0; +} + +void CResponseSystem::ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.start = AIS_DEF_MIN_DELAY; + rp->delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); +} + +void CResponseSystem::ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_SPEAKONCE; +} + +void CResponseSystem::ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_DONT_USE_SCENE; +} + +void CResponseSystem::ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; +} + +void CResponseSystem::ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_ODDS; + rp->odds = clamp( atoi( token ), 0, 100 ); +} + +void CResponseSystem::ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_RESPEAKDELAY; + rp->respeakdelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_WEAPONDELAY; + rp->weapondelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_SOUNDLEVEL; + rp->soundlevel = (soundlevel_t)TextToSoundLevel( token ); +} + +void CResponseSystem::ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + newResponse.first = true; + group.m_bHasFirst = true; +} + +void CResponseSystem::ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + newResponse.last = true; + group.m_bHasLast= true; +} + +void CResponseSystem::ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + // get target name + bool bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityiotarget = ResponseCopyString(token); + + bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityioinput = ResponseCopyString(token); + + bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityiodelay = atof( token ); + /* + m_followup.followup_entityioinput = ResponseCopyString(src.m_followup.followup_entityioinput); + m_followup.followup_entityiotarget = ResponseCopyString(src.m_followup.followup_entityiotarget); + */ +} + +void CResponseSystem::ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + // eg, "subject TALK_ANSWER saidunplant:1 3" + bool bSuc = ParseToken(); + if (!bSuc) + { + AssertMsg(false, "THEN token in response lacked any further info.\n"); + ResponseWarning( "THEN token in response lacked any further info.\n" ); + return; + } + + newResponse.m_followup.followup_target = ResponseCopyString(token); + + bSuc = ParseToken(); // get another token + if (!bSuc) + { + AssertMsg1(false, "THEN token in response had a target '%s', but lacked any further info.\n", newResponse.m_followup.followup_target ); + ResponseWarning( "THEN token in response had a target '%s', but lacked any further info.\n", newResponse.m_followup.followup_target ); + return; + } + + newResponse.m_followup.followup_concept = ResponseCopyString( token ); + + + // Okay, this is totally asinine. + // Because the ParseToken() function will split foo:bar into three tokens + // (which is reasonable), but we have no safe way to parse the file otherwise + // because it's all behind an engine interface, it's necessary to parse all + // the tokens to the end of the line and catenate them, except for the last one + // which is the delay. That's crap. + bSuc = ParseToken(); + if (!bSuc) + { + AssertMsg(false, "THEN token in response lacked contexts.\n"); + ResponseWarning( "THEN token in response lacked contexts.\n" ); + return; + } + + // okay, as long as there is at least one more token, catenate the ones we + // see onto a temporary buffer. When we're down to the last token, that is + // the delay. + char buf[4096]; + buf[0] = '\0'; + while ( TokenWaiting() ) + { + Q_strncat( buf, token, 4096 ); + bSuc = ParseToken(); + AssertMsg(bSuc, "Token parsing mysteriously failed."); + } + + // down here, token is the last token, and buf is everything up to there. + newResponse.m_followup.followup_contexts = ResponseCopyString( buf ); + + newResponse.m_followup.followup_delay = atof( token ); +} + +void CResponseSystem::ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams ) +{ + ParserResponse &newResponse = group.group[ group.group.AddToTail() ]; + newResponse.weight.SetFloat( 1.0f ); + // inherit from group if appropriate + if (defaultParams) + { + newResponse.params = *defaultParams; + } + + ResponseParams *rp = &newResponse.params; + + newResponse.type = ComputeResponseType( token ); + if ( RESPONSE_NONE == newResponse.type ) +{ + ResponseWarning( "response entry '%s' with unknown response type '%s'\n", responseGroupName, token ); + return; +} + +#ifdef MAPBASE + // HACKHACK: Some response system usage in the pre-Alien Swarm system require response names to preserve casing or even have escaped quotes. + ParseTokenIntact(); +#else + ParseToken(); +#endif + newResponse.value = ResponseCopyString( token ); + + while ( TokenWaiting() ) + { + ParseToken(); + + unsigned int hash = RR_HASH( token ); + if ( DispatchParseResponse( token, hash, m_ResponseDispatch, newResponse, group, rp ) ) + { + continue; + } + + ResponseWarning( "response entry '%s' with unknown command '%s'\n", responseGroupName, token ); + } + +} + +void CResponseSystem::ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + if ( !Q_stricmp( token, "permitrepeats" ) ) + { + newGroup.m_bDepleteBeforeRepeat = false; + continue; + } + else if ( !Q_stricmp( token, "sequential" ) ) + { + newGroup.SetSequential( true ); + continue; + } + else if ( !Q_stricmp( token, "norepeat" ) ) + { + newGroup.SetNoRepeat( true ); + continue; + } + + ParseOneResponse( responseGroupName, newGroup, &groupResponseParams ); + } + } + +void CResponseSystem::ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; + groupResponseParams.predelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.start = 0; + groupResponseParams.delay.range = 0; + } + +void CResponseSystem::ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.start = AIS_DEF_MIN_DELAY; + groupResponseParams.delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); + } + +void CResponseSystem::ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_SPEAKONCE; + } + +void CResponseSystem::ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_DONT_USE_SCENE; + } + +void CResponseSystem::ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; + } + +void CResponseSystem::ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_ODDS; + groupResponseParams.odds = clamp( atoi( token ), 0, 100 ); + } + +void CResponseSystem::ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_RESPEAKDELAY; + groupResponseParams.respeakdelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_WEAPONDELAY; + groupResponseParams.weapondelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_SOUNDLEVEL; + groupResponseParams.soundlevel = (soundlevel_t)TextToSoundLevel( token ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::ParseResponse( void ) +{ + AI_ResponseParams groupResponseParams; // default response parameters inherited from single line format for group + + // Should have groupname at start + ParseToken(); + char responseGroupName[ 128 ]; + Q_strncpy( responseGroupName, token, sizeof( responseGroupName ) ); + + int slot = m_Responses.Insert( responseGroupName ); + ResponseGroup &newGroup = m_Responses[ slot ]; + + while ( 1 ) + { +#ifdef MAPBASE + if ( !ParseToken() || !Q_stricmp( token, "}" ) ) + { + break; + } +#else + ParseToken(); +#endif + + unsigned int hash = RR_HASH( token ); + + // Oops, part of next definition + if( IsRootCommand( hash ) ) + { + Unget(); + break; + } + + if ( DispatchParseResponseGroup( token, hash, m_ResponseGroupDispatch, responseGroupName, newGroup, groupResponseParams ) ) + { + continue; + } + + ParseOneResponse( responseGroupName, newGroup, &groupResponseParams ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criterion - +//----------------------------------------------------------------------------- +int CResponseSystem::ParseOneCriterion( const char *criterionName ) +{ + char key[ 128 ]; + char value[ 128 ]; + + Criteria *pNewCriterion = NULL; + + int idx; +#ifdef MAPBASE + short existing = m_Criteria.Find( criterionName ); + if ( existing != m_Criteria.InvalidIndex() ) + { + //ResponseWarning( "Additional definition for criteria '%s', overwriting\n", criterionName ); + m_Criteria[existing] = Criteria(); + m_Criteria.SetElementName(existing, criterionName); + idx = existing; + pNewCriterion = &m_Criteria[ idx ]; + } +#else + if ( m_Criteria.Find( criterionName ) != m_Criteria.InvalidIndex() ) + { + static Criteria dummy; + pNewCriterion = &dummy; + + ResponseWarning( "Multiple definitions for criteria '%s' [%d]\n", criterionName, RR_HASH( criterionName ) ); + idx = m_Criteria.InvalidIndex(); + } +#endif + else + { + idx = m_Criteria.Insert( criterionName ); + pNewCriterion = &m_Criteria[ idx ]; + } + + bool gotbody = false; + + while ( TokenWaiting() || !gotbody ) + { +#ifdef MAPBASE + if ( !ParseToken() ) + { + break; + } +#else + ParseToken(); +#endif + + // Oops, part of next definition + if( IsRootCommand() ) + { + Unget(); + break; + } + + if ( !Q_stricmp( token, "{" ) ) + { + gotbody = true; + + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + // Look up subcriteria index + int idx = m_Criteria.Find( token ); + if ( idx != m_Criteria.InvalidIndex() ) + { + pNewCriterion->subcriteria.AddToTail( idx ); + } + else + { + ResponseWarning( "Skipping unrecongized subcriterion '%s' in '%s'\n", token, criterionName ); + } + } + continue; + } + else if ( !Q_stricmp( token, "required" ) ) + { + pNewCriterion->required = true; + } + else if ( !Q_stricmp( token, "weight" ) ) + { + ParseToken(); + pNewCriterion->weight.SetFloat( (float)atof( token ) ); + } + else + { + Assert( pNewCriterion->subcriteria.Count() == 0 ); + + // Assume it's the math info for a non-subcriteria resposne + Q_strncpy( key, token, sizeof( key ) ); + ParseToken(); + Q_strncpy( value, token, sizeof( value ) ); + + V_strlower( key ); + pNewCriterion->nameSym = CriteriaSet::ComputeCriteriaSymbol( key ); + pNewCriterion->value = ResponseCopyString( value ); + + gotbody = true; + } + } + + if ( !pNewCriterion->IsSubCriteriaType() ) + { + ComputeMatcher( pNewCriterion, pNewCriterion->matcher ); + } + + return idx; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseCriterion( void ) +{ + // Should have groupname at start + char criterionName[ 128 ]; + ParseToken(); + Q_strncpy( criterionName, token, sizeof( criterionName ) ); + + ParseOneCriterion( criterionName ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseEnumeration( void ) +{ + char enumerationName[ 128 ]; + ParseToken(); + Q_strncpy( enumerationName, token, sizeof( enumerationName ) ); + + ParseToken(); + if ( Q_stricmp( token, "{" ) ) + { + ResponseWarning( "Expecting '{' in enumeration '%s', got '%s'\n", enumerationName, token ); + return; + } + + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + if ( Q_strlen( token ) <= 0 ) + { + ResponseWarning( "Expecting more tokens in enumeration '%s'\n", enumerationName ); + break; + } + + char key[ 128 ]; + + Q_strncpy( key, token, sizeof( key ) ); + ParseToken(); + float value = (float)atof( token ); + + char sz[ 128 ]; + Q_snprintf( sz, sizeof( sz ), "[%s::%s]", enumerationName, key ); + Q_strlower( sz ); + + Enumeration newEnum; + newEnum.value = value; + + if ( m_Enumerations.Find( sz ) == m_Enumerations.InvalidIndex() ) + { + m_Enumerations.Insert( sz, newEnum ); + } + /* + else + { + ResponseWarning( "Ignoring duplication enumeration '%s'\n", sz ); + } + */ + } +} + +void CResponseSystem::ParseRule_MatchOnce( Rule &newRule ) + { + newRule.m_bMatchOnce = true; + } + +#ifdef MAPBASE +void CResponseSystem::ParseRule_ApplyContextToWorld( Rule &newRule ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_WORLD; + } + +void CResponseSystem::ParseRule_ApplyContextToSquad( Rule &newRule ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_SQUAD; + } + +void CResponseSystem::ParseRule_ApplyContextToEnemy( Rule &newRule ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_ENEMY; + } +#else +void CResponseSystem::ParseRule_ApplyContextToWorld( Rule &newRule ) + { + newRule.m_bApplyContextToWorld = true; + } +#endif + +void CResponseSystem::ParseRule_ApplyContext( Rule &newRule ) + { + ParseToken(); + if ( newRule.GetContext() == NULL ) + { + newRule.SetContext( token ); + } + else + { + CFmtStrN<1024> newContext( "%s,%s", newRule.GetContext(), token ); + newRule.SetContext( newContext ); + } + } + +void CResponseSystem::ParseRule_Response( Rule &newRule ) + { + // Read them until we run out. + while ( TokenWaiting() ) + { + ParseToken(); + int idx = m_Responses.Find( token ); + if ( idx != m_Responses.InvalidIndex() ) + { + MEM_ALLOC_CREDIT(); + newRule.m_Responses.AddToTail( idx ); + } + else + { + m_bParseRuleValid = false; + ResponseWarning( "No such response '%s' for rule '%s'\n", token, m_pParseRuleName ); + } + } +} + +/* +void CResponseSystem::ParseRule_ForceWeight( Rule &newRule ) +{ + ParseToken(); + if ( token[0] == 0 ) + { + // no token followed forceweight? + ResponseWarning( "Forceweight token in rule '%s' did not specify a numerical weight! Ignoring.\n", m_pParseRuleName ); + } + else + { + newRule.m_nForceWeight = atoi(token); + if ( newRule.m_nForceWeight == 0 ) + { + ResponseWarning( "Rule '%s' had forceweight '%s', which doesn't work out to a nonzero number. Ignoring.\n", + m_pParseRuleName, token ); + } + } + } +*/ + +void CResponseSystem::ParseRule_Criteria( Rule &newRule ) + { + // Read them until we run out. + while ( TokenWaiting() ) + { + ParseToken(); + + int idx = m_Criteria.Find( token ); + if ( idx != m_Criteria.InvalidIndex() ) + { + MEM_ALLOC_CREDIT(); + newRule.m_Criteria.AddToTail( idx ); + } + else + { + m_bParseRuleValid = false; + ResponseWarning( "No such criterion '%s' for rule '%s'\n", token, m_pParseRuleName ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseRule( void ) +{ + static int instancedCriteria = 0; + + char ruleName[ 128 ]; + ParseToken(); + Q_strncpy( ruleName, token, sizeof( ruleName ) ); + + ParseToken(); + if ( Q_stricmp( token, "{" ) ) + { + ResponseWarning( "Expecting '{' in rule '%s', got '%s'\n", ruleName, token ); + return; + } + + // entries are "criteria", "response" or an in-line criteria to instance + Rule *newRule = new Rule; + + char sz[ 128 ]; + + m_bParseRuleValid = true; + m_pParseRuleName = ruleName; + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + { + break; + } + + if ( Q_strlen( token ) <= 0 ) + { + ResponseWarning( "Expecting more tokens in rule '%s'\n", ruleName ); + break; + } + + unsigned int hash = RR_HASH( token ); + if ( DispatchParseRule( token, hash, m_RuleDispatch, *newRule ) ) + continue; + + // It's an inline criteria, generate a name and parse it in + Q_snprintf( sz, sizeof( sz ), "[%s%03i]", ruleName, ++instancedCriteria ); + Unget(); + int idx = ParseOneCriterion( sz ); + if ( idx != m_Criteria.InvalidIndex() ) + { + newRule->m_Criteria.AddToTail( idx ); + } + } + + if ( m_bParseRuleValid ) + { + m_RulePartitions.GetDictForRule( this, newRule ).Insert( ruleName, newRule ); + } + else + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Discarded rule %s\n", ruleName ); + delete newRule; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CResponseSystem::GetCurrentToken() const +{ + if ( m_ScriptStack.Count() <= 0 ) + return -1; + + return m_ScriptStack[ 0 ].tokencount; +} + + +void CResponseSystem::ResponseWarning( const char *fmt, ... ) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, fmt); + Q_vsnprintf(string, sizeof(string), fmt,argptr); + va_end (argptr); + + char cur[ 256 ]; + GetCurrentScript( cur, sizeof( cur ) ); + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "%s(token %i) : %s", cur, GetCurrentToken(), string ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) +{ + // Add criteria from this rule to global list in custom response system. + int nCriteriaCount = pSrcRule->m_Criteria.Count(); + for ( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) + { + int iSrcIndex = pSrcRule->m_Criteria[iCriteria]; + Criteria *pSrcCriteria = &m_Criteria[iSrcIndex]; + if ( pSrcCriteria ) + { + int iIndex = pCustomSystem->m_Criteria.Find( m_Criteria.GetElementName( iSrcIndex ) ); + if ( iIndex != pCustomSystem->m_Criteria.InvalidIndex() ) + { + pDstRule->m_Criteria.AddToTail( iIndex ); + continue; + } + + // Add the criteria. + Criteria dstCriteria; + + dstCriteria.nameSym = pSrcCriteria->nameSym ; + dstCriteria.value = ResponseCopyString( pSrcCriteria->value ); + dstCriteria.weight = pSrcCriteria->weight; + dstCriteria.required = pSrcCriteria->required; + dstCriteria.matcher = pSrcCriteria->matcher; + + int nSubCriteriaCount = pSrcCriteria->subcriteria.Count(); + for ( int iSubCriteria = 0; iSubCriteria < nSubCriteriaCount; ++iSubCriteria ) + { + int iSrcSubIndex = pSrcCriteria->subcriteria[iSubCriteria]; + Criteria *pSrcSubCriteria = &m_Criteria[iSrcSubIndex]; + if ( pSrcCriteria ) + { + int iSubIndex = pCustomSystem->m_Criteria.Find( pSrcSubCriteria->value ); + if ( iSubIndex != pCustomSystem->m_Criteria.InvalidIndex() ) + continue; + + // Add the criteria. + Criteria dstSubCriteria; + + dstSubCriteria.nameSym = pSrcSubCriteria->nameSym ; + dstSubCriteria.value = ResponseCopyString( pSrcSubCriteria->value ); + dstSubCriteria.weight = pSrcSubCriteria->weight; + dstSubCriteria.required = pSrcSubCriteria->required; + dstSubCriteria.matcher = pSrcSubCriteria->matcher; + + int iSubInsertIndex = pCustomSystem->m_Criteria.Insert( pSrcSubCriteria->value, dstSubCriteria ); + dstCriteria.subcriteria.AddToTail( iSubInsertIndex ); + } + } + + int iInsertIndex = pCustomSystem->m_Criteria.Insert( m_Criteria.GetElementName( iSrcIndex ), dstCriteria ); + pDstRule->m_Criteria.AddToTail( iInsertIndex ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) +{ + // Add responses from this rule to global list in custom response system. + int nResponseGroupCount = pSrcRule->m_Responses.Count(); + for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) + { + int iSrcResponseGroup = pSrcRule->m_Responses[iResponseGroup]; + ResponseGroup *pSrcResponseGroup = &m_Responses[iSrcResponseGroup]; + if ( pSrcResponseGroup ) + { + // Add response group. + ResponseGroup dstResponseGroup; + + dstResponseGroup.m_bDepleteBeforeRepeat = pSrcResponseGroup->m_bDepleteBeforeRepeat; + dstResponseGroup.m_nDepletionCount = pSrcResponseGroup->m_nDepletionCount; + dstResponseGroup.m_bHasFirst = pSrcResponseGroup->m_bHasFirst; + dstResponseGroup.m_bHasLast = pSrcResponseGroup->m_bHasLast; + dstResponseGroup.m_bSequential = pSrcResponseGroup->m_bSequential; + dstResponseGroup.m_bNoRepeat = pSrcResponseGroup->m_bNoRepeat; + dstResponseGroup.m_bEnabled = pSrcResponseGroup->m_bEnabled; + dstResponseGroup.m_nCurrentIndex = pSrcResponseGroup->m_nCurrentIndex; + + int nSrcResponseCount = pSrcResponseGroup->group.Count(); + for ( int iResponse = 0; iResponse < nSrcResponseCount; ++iResponse ) + { + ParserResponse *pSrcResponse = &pSrcResponseGroup->group[iResponse]; + if ( pSrcResponse ) + { + // Add Response + ParserResponse dstResponse; + + dstResponse.weight = pSrcResponse->weight; + dstResponse.type = pSrcResponse->type; + dstResponse.value = ResponseCopyString( pSrcResponse->value ); + dstResponse.depletioncount = pSrcResponse->depletioncount; + dstResponse.first = pSrcResponse->first; + dstResponse.last = pSrcResponse->last; + + dstResponseGroup.group.AddToTail( dstResponse ); + } + } + + int iInsertIndex = pCustomSystem->m_Responses.Insert( m_Responses.GetElementName( iSrcResponseGroup ), dstResponseGroup ); + pDstRule->m_Responses.AddToTail( iInsertIndex ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyEnumerationsFrom( CResponseSystem *pCustomSystem ) +{ + int nEnumerationCount = m_Enumerations.Count(); + for ( int iEnumeration = 0; iEnumeration < nEnumerationCount; ++iEnumeration ) + { + Enumeration *pSrcEnumeration = &m_Enumerations[iEnumeration]; + if ( pSrcEnumeration ) + { + Enumeration dstEnumeration; + dstEnumeration.value = pSrcEnumeration->value; + pCustomSystem->m_Enumerations.Insert( m_Enumerations.GetElementName( iEnumeration ), dstEnumeration ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem ) +{ + // Verify data. + Assert( pSrcRule ); + Assert( pCustomSystem ); + if ( !pSrcRule || !pCustomSystem ) + return; + + // New rule + Rule *dstRule = new Rule; + + dstRule->SetContext( pSrcRule->GetContext() ); + dstRule->m_bMatchOnce = pSrcRule->m_bMatchOnce; + dstRule->m_bEnabled = pSrcRule->m_bEnabled; +#ifdef MAPBASE + dstRule->m_iContextFlags = pSrcRule->m_iContextFlags; +#else + dstRule->m_bApplyContextToWorld = pSrcRule->m_bApplyContextToWorld; +#endif + + // Copy off criteria. + CopyCriteriaFrom( pSrcRule, dstRule, pCustomSystem ); + + // Copy off responses. + CopyResponsesFrom( pSrcRule, dstRule, pCustomSystem ); + + // Copy off enumerations - Don't think we use these. + // CopyEnumerationsFrom( pCustomSystem ); + + // Add rule. + pCustomSystem->m_RulePartitions.GetDictForRule( this, dstRule ).Insert( m_RulePartitions.GetElementName( iRule ), dstRule ); +} + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::DumpRules() +{ + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "%s\n", m_RulePartitions.GetElementName( idx ) ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::DumpDictionary( const char *pszName ) +{ + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\nDictionary: %s\n", pszName ); + + // int nRuleCount = m_Rules.Count(); + // for ( int iRule = 0; iRule < nRuleCount; ++iRule ) + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, " Rule %d/%d: %s\n", m_RulePartitions.BucketFromIdx( idx ), m_RulePartitions.PartFromIdx( idx ), m_RulePartitions.GetElementName( idx ) ); + + Rule *pRule = &m_RulePartitions[idx]; + + int nCriteriaCount = pRule->m_Criteria.Count(); + for( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) + { + int iRuleCriteria = pRule->m_Criteria[iCriteria]; + Criteria *pCriteria = &m_Criteria[iRuleCriteria]; + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, " Criteria %d: %s %s\n", iCriteria, CriteriaSet::SymbolToStr( pCriteria->nameSym ), pCriteria->value ); + } + + int nResponseGroupCount = pRule->m_Responses.Count(); + for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) + { + int iRuleResponse = pRule->m_Responses[iResponseGroup]; + ResponseGroup *pResponseGroup = &m_Responses[iRuleResponse]; + + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, " ResponseGroup %d: %s\n", iResponseGroup, m_Responses.GetElementName( iRuleResponse ) ); + + int nResponseCount = pResponseGroup->group.Count(); + for ( int iResponse = 0; iResponse < nResponseCount; ++iResponse ) + { + ParserResponse *pResponse = &pResponseGroup->group[iResponse]; + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, " Response %d: %s\n", iResponse, pResponse->value ); + } + } + } +} + +void CResponseSystem::BuildDispatchTables() +{ + m_RootCommandHashes.Insert( RR_HASH( "#include" ) ); + m_RootCommandHashes.Insert( RR_HASH( "response" ) ); + m_RootCommandHashes.Insert( RR_HASH( "enumeration" ) ); + m_RootCommandHashes.Insert( RR_HASH( "criterion" ) ); + m_RootCommandHashes.Insert( RR_HASH( "criteria" ) ); + m_RootCommandHashes.Insert( RR_HASH( "rule" ) ); + + m_FileDispatch.Insert( RR_HASH( "#include" ), &CResponseSystem::ParseInclude ); + m_FileDispatch.Insert( RR_HASH( "response" ), &CResponseSystem::ParseResponse ); + m_FileDispatch.Insert( RR_HASH( "criterion" ), &CResponseSystem::ParseCriterion ); + m_FileDispatch.Insert( RR_HASH( "criteria" ), &CResponseSystem::ParseCriterion ); + m_FileDispatch.Insert( RR_HASH( "rule" ), &CResponseSystem::ParseRule ); + m_FileDispatch.Insert( RR_HASH( "enumeration" ), &CResponseSystem::ParseEnumeration ); + + m_RuleDispatch.Insert( RR_HASH( "matchonce" ), &CResponseSystem::ParseRule_MatchOnce ); + m_RuleDispatch.Insert( RR_HASH( "applycontexttoworld" ), &CResponseSystem::ParseRule_ApplyContextToWorld ); +#ifdef MAPBASE + m_RuleDispatch.Insert( RR_HASH( "applycontexttosquad" ), &CResponseSystem::ParseRule_ApplyContextToSquad ); + m_RuleDispatch.Insert( RR_HASH( "applycontexttoenemy" ), &CResponseSystem::ParseRule_ApplyContextToEnemy ); +#endif + m_RuleDispatch.Insert( RR_HASH( "applycontext" ), &CResponseSystem::ParseRule_ApplyContext ); + m_RuleDispatch.Insert( RR_HASH( "response" ), &CResponseSystem::ParseRule_Response ); +// m_RuleDispatch.Insert( RR_HASH( "forceweight" ), &CResponseSystem::ParseRule_ForceWeight ); + m_RuleDispatch.Insert( RR_HASH( "criteria" ), &CResponseSystem::ParseRule_Criteria ); + m_RuleDispatch.Insert( RR_HASH( "criterion" ), &CResponseSystem::ParseRule_Criteria ); + + + m_ResponseDispatch.Insert( RR_HASH( "weight" ), &CResponseSystem::ParseResponse_Weight ); + m_ResponseDispatch.Insert( RR_HASH( "predelay" ), &CResponseSystem::ParseResponse_PreDelay ); + m_ResponseDispatch.Insert( RR_HASH( "nodelay" ), &CResponseSystem::ParseResponse_NoDelay ); + m_ResponseDispatch.Insert( RR_HASH( "defaultdelay" ), &CResponseSystem::ParseResponse_DefaultDelay ); + m_ResponseDispatch.Insert( RR_HASH( "delay" ), &CResponseSystem::ParseResponse_Delay ); + m_ResponseDispatch.Insert( RR_HASH( "speakonce" ), &CResponseSystem::ParseResponse_SpeakOnce ); + m_ResponseDispatch.Insert( RR_HASH( "noscene" ), &CResponseSystem::ParseResponse_NoScene ); + m_ResponseDispatch.Insert( RR_HASH( "stop_on_nonidle" ), &CResponseSystem::ParseResponse_StopOnNonIdle ); + m_ResponseDispatch.Insert( RR_HASH( "odds" ), &CResponseSystem::ParseResponse_Odds ); + m_ResponseDispatch.Insert( RR_HASH( "respeakdelay" ), &CResponseSystem::ParseResponse_RespeakDelay ); + m_ResponseDispatch.Insert( RR_HASH( "weapondelay" ), &CResponseSystem::ParseResponse_WeaponDelay ); + m_ResponseDispatch.Insert( RR_HASH( "soundlevel" ), &CResponseSystem::ParseResponse_Soundlevel ); + m_ResponseDispatch.Insert( RR_HASH( "displayfirst" ), &CResponseSystem::ParseResponse_DisplayFirst ); + m_ResponseDispatch.Insert( RR_HASH( "displaylast" ), &CResponseSystem::ParseResponse_DisplayLast ); + m_ResponseDispatch.Insert( RR_HASH( "fire" ), &CResponseSystem::ParseResponse_Fire ); + m_ResponseDispatch.Insert( RR_HASH( "then" ), &CResponseSystem::ParseResponse_Then ); + + m_ResponseGroupDispatch.Insert( RR_HASH( "{" ), &CResponseSystem::ParseResponseGroup_Start ); + m_ResponseGroupDispatch.Insert( RR_HASH( "predelay" ), &CResponseSystem::ParseResponseGroup_PreDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "nodelay" ), &CResponseSystem::ParseResponseGroup_NoDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "defaultdelay" ), &CResponseSystem::ParseResponseGroup_DefaultDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "delay" ), &CResponseSystem::ParseResponseGroup_Delay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "speakonce" ), &CResponseSystem::ParseResponseGroup_SpeakOnce ); + m_ResponseGroupDispatch.Insert( RR_HASH( "noscene" ), &CResponseSystem::ParseResponseGroup_NoScene ); + m_ResponseGroupDispatch.Insert( RR_HASH( "stop_on_nonidle" ), &CResponseSystem::ParseResponseGroup_StopOnNonIdle ); + m_ResponseGroupDispatch.Insert( RR_HASH( "odds" ), &CResponseSystem::ParseResponseGroup_Odds ); + m_ResponseGroupDispatch.Insert( RR_HASH( "respeakdelay" ), &CResponseSystem::ParseResponseGroup_RespeakDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "weapondelay" ), &CResponseSystem::ParseResponseGroup_WeaponDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "soundlevel" ), &CResponseSystem::ParseResponseGroup_Soundlevel ); +} + +bool CResponseSystem::Dispatch( char const *pToken, unsigned int uiHash, CResponseSystem::DispatchMap_t &rMap ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnResponseDispatch dispatch = rMap[ slot ]; + (this->*dispatch)(); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseRuleDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( newRule ); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseResponseDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( newResponse, group, rp ); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseResponseGroupDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( responseGroupName, newGroup, groupResponseParams ); + return true; + } + + return false; +} + +unsigned int ResponseRulePartition::GetBucketForSpeakerAndConcept( const char *pszSpeaker, const char *pszConcept, const char *pszSubject ) +{ + // make sure is a power of two + COMPILE_TIME_ASSERT( ( N_RESPONSE_PARTITIONS & ( N_RESPONSE_PARTITIONS - 1 ) ) == 0 ); + + // hash together the speaker and concept strings, and mask off by the bucket mask + unsigned hashSpeaker = 0; // pszSpeaker ? HashStringCaseless( pszSpeaker ) : 0; + unsigned hashConcept = pszConcept ? HashStringCaseless( pszConcept ) : 0; + unsigned hashSubject = pszSubject ? HashStringCaseless( pszSubject ) : 0; + unsigned hashBrowns = ( ( hashSubject >> 3 ) ^ (hashSpeaker >> 1) ^ hashConcept ) & ( N_RESPONSE_PARTITIONS - 1 ); + return hashBrowns; +} + +const char *Rule::GetValueForRuleCriterionByName( CResponseSystem * RESTRICT pSystem, const CUtlSymbol &pCritNameSym ) +{ + const char * retval = NULL; + // for each rule criterion... + for ( int i = 0 ; i < m_Criteria.Count() ; ++i ) + { + retval = RecursiveGetValueForRuleCriterionByName( pSystem, &pSystem->m_Criteria[m_Criteria[i]], pCritNameSym ); + if ( retval != NULL ) + { + // we found a result, early out + break; + } + } + + return retval; +} + +const Criteria *Rule::GetPointerForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ) +{ + const Criteria * retval = NULL; + // for each rule criterion... + for ( int i = 0 ; i < m_Criteria.Count() ; ++i ) + { + retval = RecursiveGetPointerForRuleCriterionByName( pSystem, &pSystem->m_Criteria[m_Criteria[i]], pCritNameSym ); + if ( retval != NULL ) + { + // we found a result, early out + break; + } + } + + return retval; +} + +const char *Rule::RecursiveGetValueForRuleCriterionByName( CResponseSystem * RESTRICT pSystem, + const Criteria * RESTRICT pCrit, const CUtlSymbol &pCritNameSym ) +{ + Assert( pCrit ); + if ( !pCrit ) return NULL; + if ( pCrit->IsSubCriteriaType() ) + { + // test each of the children (depth first) + const char *pRet = NULL; + for ( int i = 0 ; i < pCrit->subcriteria.Count() ; ++i ) + { + pRet = RecursiveGetValueForRuleCriterionByName( pSystem, &pSystem->m_Criteria[pCrit->subcriteria[i]], pCritNameSym ); + if ( pRet ) // if found something, early out + return pRet; + } + } + else // leaf criterion + { + if ( pCrit->nameSym == pCritNameSym ) + { + return pCrit->value; + } + else + { + return NULL; + } + } + + return NULL; +} + + +const Criteria *Rule::RecursiveGetPointerForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ) +{ + Assert( pCrit ); + if ( !pCrit ) return NULL; + if ( pCrit->IsSubCriteriaType() ) + { + // test each of the children (depth first) + const Criteria *pRet = NULL; + for ( int i = 0 ; i < pCrit->subcriteria.Count() ; ++i ) + { + pRet = RecursiveGetPointerForRuleCriterionByName( pSystem, &pSystem->m_Criteria[pCrit->subcriteria[i]], pCritNameSym ); + if ( pRet ) // if found something, early out + return pRet; + } + } + else // leaf criterion + { + if ( pCrit->nameSym == pCritNameSym ) + { + return pCrit; + } + else + { + return NULL; + } + } + + return NULL; +} + + +static void CC_RR_Debug_ResponseConcept_Exclude( const CCommand &args ) +{ + // shouldn't use this extern elsewhere -- it's meant to be a hidden + // implementation detail + extern CRR_ConceptSymbolTable *g_pRRConceptTable; + Assert( g_pRRConceptTable ); + if ( !g_pRRConceptTable ) return; + + + // different things for different argument lengths + switch ( args.ArgC() ) + { + case 0: + { + AssertMsg( args.ArgC() > 0, "WTF error in ccommand parsing: zero arguments!\n" ); + return; + } + case 1: + { + // print usage info + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "Usage: rr_debugresponseconcept_exclude Concept1 Concept2 Concept3...\n"); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\tseparate multiple concepts with spaces.\n"); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\tcall with no arguments to see this message and a list of current excludes.\n"); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\tto reset the exclude list, type \"rr_debugresponseconcept_exclude !\"\n"); + + // print current excludes + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\nCurrent exclude list:\n" ); + if ( !CResponseSystem::m_DebugExcludeList.IsValidIndex( CResponseSystem::m_DebugExcludeList.Head() ) ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\t\n" ); + } + else + { + CResponseSystem::ExcludeList_t::IndexLocalType_t i; + for ( i = CResponseSystem::m_DebugExcludeList.Head() ; + CResponseSystem::m_DebugExcludeList.IsValidIndex(i) ; + i = CResponseSystem::m_DebugExcludeList.Next(i) ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\t%s\n", CResponseSystem::m_DebugExcludeList[i].GetStringConcept() ); + } + } + return; + } + case 2: + // deal with the erase operator + if ( args[1][0] == '!' ) + { + CResponseSystem::m_DebugExcludeList.Purge(); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "Exclude list emptied.\n" ); + return; + } + // else, FALL THROUGH: + default: + // add each arg to the exclude list + for ( int i = 1 ; i < args.ArgC() ; ++i ) + { + if ( !g_pRRConceptTable->Find(args[i]).IsValid() ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\t'%s' is not a known concept (adding it anyway)\n", args[i] ); + } + CRR_Concept rrConcept( args[i] ); + CResponseSystem::m_DebugExcludeList.AddToTail( rrConcept ); + } + } +} +#if RR_DUMPHASHINFO_ENABLED +void ResponseRulePartition::PrintBucketInfo( CResponseSystem *pSys ) +{ + struct bucktuple_t + { + int nBucket; + int nCount; + bucktuple_t() : nBucket(-1), nCount(-1) {}; + bucktuple_t( int bucket, int count ) : nBucket(bucket), nCount(count) {}; + + static int __cdecl SortCompare( const bucktuple_t * a, const bucktuple_t * b ) + { + return a->nCount - b->nCount; + } + }; + + CUtlVector infos( N_RESPONSE_PARTITIONS, N_RESPONSE_PARTITIONS ); + + float nAverage = 0; + for ( int i = 0 ; i < N_RESPONSE_PARTITIONS ; ++i ) + { + int count = m_RuleParts[i].Count(); + infos.AddToTail( bucktuple_t( i, count ) ); + nAverage += count; + } + nAverage /= N_RESPONSE_PARTITIONS; + infos.Sort( bucktuple_t::SortCompare ); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "%d buckets, %d total, %.2f average size\n", N_RESPONSE_PARTITIONS, Count(), nAverage ); + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "8 shortest buckets:\n" ); + for ( int i = 0 ; i < 8 ; ++i ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\t%d: %d\n", infos[i].nBucket, infos[i].nCount ); + } + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "8 longest buckets:\n" ); + for ( int i = infos.Count() - 1 ; i >= infos.Count() - 9 ; --i ) + { + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "\t%d: %d\n", infos[i].nBucket, infos[i].nCount ); + } + int nempty = 0; + for ( nempty = 0 ; nempty < infos.Count() ; ++nempty ) + { + if ( infos[nempty].nCount != 0 ) + break; + } + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "%d empty buckets\n", nempty ); + + /* + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, " Contents of longest bucket\nwho\tconcept\n" ); + tRuleDict &bucket = m_RuleParts[infos[infos.Count()-1].nBucket]; + for ( tRuleDict::IndexType_t i = bucket.FirstInorder(); bucket.IsValidIndex(i); i = bucket.NextInorder(i) ) + { + Rule &rule = bucket.Element(i) ; + CGMsg( 0, CON_GROUP_RESPONSE_SYSTEM, "%s\t%s\n", rule.GetValueForRuleCriterionByName( pSys, "who" ), rule.GetValueForRuleCriterionByName( pSys, CriteriaSet::ComputeCriteriaSymbol("concept") ) ); + } + */ +} +#endif diff --git a/responserules/runtime/response_system.h b/responserules/runtime/response_system.h new file mode 100644 index 00000000..0c8441b7 --- /dev/null +++ b/responserules/runtime/response_system.h @@ -0,0 +1,339 @@ +//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: The CResponseSystem class. Don't include this header; include the response_types +// into which it is transcluded. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_SYSTEM_H +#define RESPONSE_SYSTEM_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utldict.h" +#include "stringpool.h" +#include "utllinkedlist.h" +#include "response_types_internal.h" + +namespace ResponseRules +{ + typedef ResponseParams AI_ResponseParams ; + #define AI_CriteriaSet ResponseRules::CriteriaSet + + //----------------------------------------------------------------------------- + // Purpose: The database of all available responses. + // The Rules are partitioned based on a variety of factors (presently, + // speaker and concept) for faster lookup, basically a seperate-chained hash. + //----------------------------------------------------------------------------- + class CResponseSystem : public IResponseSystem + { + public: + CResponseSystem(); + ~CResponseSystem(); + + typedef void (CResponseSystem::*pfnResponseDispatch)( void ); + typedef void (CResponseSystem::*pfnParseRuleDispatch)( Rule & ); + typedef void (CResponseSystem::*pfnParseResponseDispatch)( ParserResponse &, ResponseGroup&, AI_ResponseParams * ); + typedef void (CResponseSystem::*pfnParseResponseGroupDispatch) ( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + + typedef CUtlMap< unsigned,pfnResponseDispatch > DispatchMap_t; + typedef CUtlMap< unsigned,pfnParseRuleDispatch > ParseRuleDispatchMap_t; + typedef CUtlMap< unsigned,pfnParseResponseDispatch > ParseResponseDispatchMap_t; + typedef CUtlMap< unsigned,pfnParseResponseGroupDispatch > ParseResponseGroupDispatchMap_t; + +#pragma region IResponseSystem + // IResponseSystem + virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL ); + virtual void GetAllResponses( CUtlVector *pResponses ); + +#ifdef MAPBASE + virtual void SetProspective( bool bToggle ) { m_bInProspective = bToggle; } + + virtual void MarkResponseAsUsed( short iGroup, short iWithinGroup ); +#endif +#pragma endregion Implement interface from IResponseSystem + + virtual void Release() = 0; + + virtual void DumpRules(); + + bool IsCustomManagable() { return m_bCustomManagable; } + +#ifdef MAPBASE + virtual +#endif + void Clear(); + + void DumpDictionary( const char *pszName ); + + protected: + + void BuildDispatchTables(); + bool Dispatch( char const *pToken, unsigned int uiHash, DispatchMap_t &rMap ); + bool DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule ); + bool DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + bool DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams ); + + virtual const char *GetScriptFile( void ) = 0; + void LoadRuleSet( const char *setname ); + + void ResetResponseGroups(); + + float LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria ); + float RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent ); + + public: + + void CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem ); + void CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); + void CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); + void CopyEnumerationsFrom( CResponseSystem *pCustomSystem ); + + //private: + + struct Enumeration + { + float value; + }; + + struct ResponseSearchResult + { + ResponseSearchResult() + { + group = NULL; + action = NULL; + } + + ResponseGroup *group; + ParserResponse *action; + }; + + inline bool ParseToken( void ) + { + if ( m_bUnget ) + { + m_bUnget = false; + return true; + } + if ( m_ScriptStack.Count() <= 0 ) + { + Assert( 0 ); + return false; + } + + m_ScriptStack[ 0 ].currenttoken = IEngineEmulator::Get()->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); + m_ScriptStack[ 0 ].tokencount++; + return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + } + +#ifdef MAPBASE + inline bool ParseTokenIntact( void ) + { + if ( m_bUnget ) + { + m_bUnget = false; + return true; + } + if ( m_ScriptStack.Count() <= 0 ) + { + Assert( 0 ); + return false; + } + + m_ScriptStack[ 0 ].currenttoken = IEngineEmulator::Get()->ParseFilePreserve( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); + m_ScriptStack[ 0 ].tokencount++; + return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + } +#endif + + inline void Unget() + { + m_bUnget = true; + } + + inline bool TokenWaiting( void ) + { + if ( m_ScriptStack.Count() <= 0 ) + { + Assert( 0 ); + return false; + } + + const char *p = m_ScriptStack[ 0 ].currenttoken; + + if ( !p ) + { + Error( "AI_ResponseSystem: Unxpected TokenWaiting() with NULL buffer in %s", (char * ) m_ScriptStack[ 0 ].name ); + return false; + } + + + while ( *p && *p!='\n') + { + // Special handler for // comment blocks + if ( *p == '/' && *(p+1) == '/' ) + return false; + + if ( !V_isspace( *p ) || isalnum( *p ) ) + return true; + + p++; + } + + return false; + } + + void ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams = NULL ); + + void ParseInclude( void ); + void ParseResponse( void ); + void ParseCriterion( void ); + void ParseRule( void ); + void ParseEnumeration( void ); + + private: + void ParseRule_MatchOnce( Rule &newRule ); + void ParseRule_ApplyContextToWorld( Rule &newRule ); +#ifdef MAPBASE + void ParseRule_ApplyContextToSquad( Rule &newRule ); + void ParseRule_ApplyContextToEnemy( Rule &newRule ); +#endif + void ParseRule_ApplyContext( Rule &newRule ); + void ParseRule_Response( Rule &newRule ); + //void ParseRule_ForceWeight( Rule &newRule ); + void ParseRule_Criteria( Rule &newRule ); + char const *m_pParseRuleName; + bool m_bParseRuleValid; + + void ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + + void ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + +public: + int ParseOneCriterion( const char *criterionName ); + + bool Compare( const char *setValue, Criteria *c, bool verbose = false ); + bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false ); + void ComputeMatcher( Criteria *c, Matcher& matcher ); + void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ); + float LookupEnumeration( const char *name, bool& found ); + + ResponseRulePartition::tIndex FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule ); + +#ifdef MAPBASE + void DisableEmptyRules(); +#endif + + float ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose = false ); + float RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ); + float ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose = false ); + void FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter ); + void RevertFakedDepletes( ResponseGroup *g ); + bool GetBestResponse( ResponseSearchResult& result, Rule *rule, bool verbose = false, IResponseFilter *pFilter = NULL ); + bool ResolveResponse( ResponseSearchResult& result, int depth, const char *name, bool verbose = false, IResponseFilter *pFilter = NULL ); + int SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ); + void DescribeResponseGroup( ResponseGroup *group, int selected, int depth ); + void DebugPrint( int depth, const char *fmt, ... ); + + void LoadFromBuffer( const char *scriptfile, const char *buffer ); + + void GetCurrentScript( char *buf, size_t buflen ); + int GetCurrentToken() const; + void SetCurrentScript( const char *script ); + + inline bool IsRootCommand( unsigned int hash ) const + { + int slot = m_RootCommandHashes.Find( hash ); + return slot != m_RootCommandHashes.InvalidIndex(); + } + + inline bool IsRootCommand() const + { + return IsRootCommand( RR_HASH( token ) ); + } + + void PushScript( const char *scriptfile, unsigned char *buffer ); + void PopScript(void); + + void ResponseWarning( const char *fmt, ... ); + + CUtlDict< ResponseGroup, short > m_Responses; + CUtlDict< Criteria, short > m_Criteria; + // CUtlDict< Rule, short > m_Rules; + ResponseRulePartition m_RulePartitions; + CUtlDict< Enumeration, short > m_Enumerations; + + CUtlVector m_FakedDepletes; + + char token[ 1204 ]; + + bool m_bUnget; + + bool m_bCustomManagable; + +#ifdef MAPBASE + // This is a hack specifically designed to fix displayfirst, speakonce, etc. in "prospective" response searches, + // especially the prospective lookups in followup responses. + // It works by preventing responses from being marked as "used". + bool m_bInProspective; +#endif + + struct ScriptEntry + { + unsigned char *buffer; + FileNameHandle_t name; + const char *currenttoken; + int tokencount; + }; + + CUtlVector< ScriptEntry > m_ScriptStack; + CStringPool m_IncludedFiles; + + DispatchMap_t m_FileDispatch; + ParseRuleDispatchMap_t m_RuleDispatch; + ParseResponseDispatchMap_t m_ResponseDispatch; + ParseResponseGroupDispatchMap_t m_ResponseGroupDispatch; + CUtlRBTree< unsigned int > m_RootCommandHashes; + + // for debugging purposes only: concepts to be emitted from rr_debugresponses 2 + typedef CUtlLinkedList< CRR_Concept, unsigned short, false, unsigned int > ExcludeList_t; + static ExcludeList_t m_DebugExcludeList; + + friend class CDefaultResponseSystemSaveRestoreBlockHandler; + friend class CResponseSystemSaveRestoreOps; + }; + + // Some globals inherited from AI_Speech.h: + const float AIS_DEF_MIN_DELAY = 2.8; // Minimum amount of time an NPCs will wait after someone has spoken before considering speaking again + const float AIS_DEF_MAX_DELAY = 3.2; // Maximum amount of time an NPCs will wait after someone has spoken before considering speaking again +} + +#endif // RESPONSE_SYSTEM_H diff --git a/responserules/runtime/response_types.cpp b/responserules/runtime/response_types.cpp new file mode 100644 index 00000000..1d8f6b31 --- /dev/null +++ b/responserules/runtime/response_types.cpp @@ -0,0 +1,281 @@ +//========= Copyright 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" + +#include "tier1/mapbase_con_groups.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace ResponseRules; + + +// bizarre function handed down from the misty days of yore +// and the original response system. a lot of stuff uses it +// and I can't be arsed to replace everything with the c stdlib +// stuff +namespace ResponseRules +{ + extern const char *ResponseCopyString( const char *in ); +}; + + +//-------------------- MATCHER ---------------------------------------------- + +Matcher::Matcher() +{ + valid = false; + isnumeric = false; + notequal = false; + usemin = false; + minequals = false; + usemax = false; + maxequals = false; +#ifdef MAPBASE + isbit = false; +#endif + maxval = 0.0f; + minval = 0.0f; + + token = UTL_INVAL_SYMBOL; + rawtoken = UTL_INVAL_SYMBOL; +} + +void Matcher::Describe( void ) +{ + if ( !valid ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " invalid!\n" ); + return; + } + char sz[ 128 ]; + + sz[ 0] = 0; + int minmaxcount = 0; + if ( usemin ) + { + Q_snprintf( sz, sizeof( sz ), ">%s%.3f", minequals ? "=" : "", minval ); + minmaxcount++; + } + if ( usemax ) + { + char sz2[ 128 ]; + Q_snprintf( sz2, sizeof( sz2 ), "<%s%.3f", maxequals ? "=" : "", maxval ); + + if ( minmaxcount > 0 ) + { + Q_strncat( sz, " and ", sizeof( sz ), COPY_ALL_CHARACTERS ); + } + Q_strncat( sz, sz2, sizeof( sz ), COPY_ALL_CHARACTERS ); + minmaxcount++; + } + + if ( minmaxcount >= 1 ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " matcher: %s\n", sz ); + return; + } + +#ifdef MAPBASE + if ( isbit ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " matcher: &%s%s\n", notequal ? "~" : "", GetToken() ); + return; + } +#endif + + if ( notequal ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " matcher: !=%s\n", GetToken() ); + return; + } + + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, " matcher: ==%s\n", GetToken() ); +} + +void Matcher::SetToken( char const *s ) +{ + token = g_RS.AddString( s ); +} + +void Matcher::SetRaw( char const *raw ) +{ + rawtoken = g_RS.AddString( raw ); +} + +char const *Matcher::GetToken() +{ + if ( token.IsValid() ) + { + return g_RS.String( token ); + } + return ""; +} + +char const *Matcher::GetRaw() +{ + if ( rawtoken.IsValid() ) + { + return g_RS.String( rawtoken ); + } + return ""; +} + +//-------------------- CRITERIA ---------------------------------------------- + +Criteria::Criteria() +{ + value = NULL; + weight.SetFloat( 1.0f ); + required = false; +} +Criteria::Criteria(const Criteria& src ) +{ + operator=( src ); +} + +Criteria::~Criteria() +{ + // do nothing because we don't own name and value anymore +} + +Criteria& Criteria::operator =(const Criteria& src ) +{ + if ( this == &src ) + return *this; + + nameSym = src.nameSym; + value = ResponseCopyString( src.value ); + weight = src.weight; + required = src.required; + + matcher = src.matcher; + + int c = src.subcriteria.Count(); + subcriteria.EnsureCapacity( c ); + for ( int i = 0; i < c; i++ ) + { + subcriteria.AddToTail( src.subcriteria[ i ] ); + } + + return *this; +} + + +//-------------------- RESPONSE ---------------------------------------------- + + + +ParserResponse::ParserResponse() : m_followup() +{ + type = RESPONSE_NONE; + value = NULL; + weight.SetFloat( 1.0f ); + depletioncount = 0; + first = false; + last = false; +} + +ParserResponse& ParserResponse::operator =( const ParserResponse& src ) +{ + if ( this == &src ) + return *this; + weight = src.weight; + type = src.type; + value = ResponseCopyString( src.value ); + depletioncount = src.depletioncount; + first = src.first; + last = src.last; + params = src.params; + + m_followup.followup_concept = ResponseCopyString(src.m_followup.followup_concept); + m_followup.followup_contexts = ResponseCopyString(src.m_followup.followup_contexts); + m_followup.followup_target = ResponseCopyString(src.m_followup.followup_target); + m_followup.followup_entityioinput = ResponseCopyString(src.m_followup.followup_entityioinput); + m_followup.followup_entityiotarget = ResponseCopyString(src.m_followup.followup_entityiotarget); + m_followup.followup_delay = src.m_followup.followup_delay; + m_followup.followup_entityiodelay = src.m_followup.followup_entityiodelay; + + return *this; +} + +ParserResponse::ParserResponse( const ParserResponse& src ) +{ + operator=( src ); +} + +ParserResponse::~ParserResponse() +{ + // nothing to do, since we don't own + // the strings anymore +} + +// ------------ RULE --------------- + +Rule::Rule() : m_nForceWeight(0) +{ + m_bMatchOnce = false; + m_bEnabled = true; + m_szContext = NULL; +#ifdef MAPBASE + m_iContextFlags = 0; +#else + m_bApplyContextToWorld = false; +#endif +} + +Rule& Rule::operator =( const Rule& src ) +{ + if ( this == &src ) + return *this; + + int i; + int c; + + c = src.m_Criteria.Count(); + m_Criteria.EnsureCapacity( c ); + for ( i = 0; i < c; i++ ) + { + m_Criteria.AddToTail( src.m_Criteria[ i ] ); + } + + c = src.m_Responses.Count(); + m_Responses.EnsureCapacity( c ); + for ( i = 0; i < c; i++ ) + { + m_Responses.AddToTail( src.m_Responses[ i ] ); + } + + SetContext( src.m_szContext ); + m_bMatchOnce = src.m_bMatchOnce; + m_bEnabled = src.m_bEnabled; +#ifdef MAPBASE + m_iContextFlags = src.m_iContextFlags; +#else + m_bApplyContextToWorld = src.m_bApplyContextToWorld; +#endif + m_nForceWeight = src.m_nForceWeight; + return *this; +} + +Rule::Rule( const Rule& src ) +{ + operator=(src); +} + +Rule::~Rule() +{ +} + +void Rule::SetContext( const char *context ) +{ + // we don't own the data we point to, so just update pointer + m_szContext = ResponseCopyString( context ); +} + + diff --git a/responserules/runtime/response_types_internal.cpp b/responserules/runtime/response_types_internal.cpp new file mode 100644 index 00000000..873f8759 --- /dev/null +++ b/responserules/runtime/response_types_internal.cpp @@ -0,0 +1,172 @@ +//========= Copyright 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" +#ifdef MAPBASE +#include "convar.h" +#include "mapbase_matchers_base.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace ResponseRules; + +#ifdef MAPBASE +ConVar rr_bucket_name_who( "rr_bucket_name_who", "Classname", FCVAR_NONE, "The name of the criteria to use for the 'Who' bucket." ); // Default changed to "Classname" for HL2 +ConVar rr_bucket_name_concept( "rr_bucket_name_concept", "Concept", FCVAR_NONE, "The name of the criteria to use for the 'Concept' bucket." ); +ConVar rr_bucket_name_subject( "rr_bucket_name_subject", "Subject", FCVAR_NONE, "The name of the criteria to use for the 'Subject' bucket." ); +#endif + + + + +ResponseRulePartition::ResponseRulePartition() +{ + Assert(true); + COMPILE_TIME_ASSERT( kIDX_ELEM_MASK < (1 << 16) ); + COMPILE_TIME_ASSERT( (kIDX_ELEM_MASK & (kIDX_ELEM_MASK + 1)) == 0 ); /// assert is power of two minus one +} + +ResponseRulePartition::~ResponseRulePartition() +{ + RemoveAll(); +} + +ResponseRulePartition::tIndex ResponseRulePartition::IndexFromDictElem( tRuleDict* pDict, int elem ) +{ + Assert( pDict ); + // If this fails, you've tried to build an index for a rule that's not stored + // in this partition + Assert( pDict >= m_RuleParts && pDict < m_RuleParts + N_RESPONSE_PARTITIONS ); + AssertMsg1( elem <= kIDX_ELEM_MASK, "A rule dictionary has %d elements; this exceeds the 255 that can be packed into an index.\n", elem ); + + int bucket = pDict - m_RuleParts; + return ( bucket << 16 ) | ( elem & kIDX_ELEM_MASK ); // this is a native op on PPC +} + + +char const *ResponseRulePartition::GetElementName( const tIndex &i ) const +{ + Assert( IsValid(i) ); + return m_RuleParts[ BucketFromIdx(i) ].GetElementName( PartFromIdx(i) ); +} + + +Rule *ResponseRulePartition::FindByName( char const *name ) const +{ + int count; + + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + count = m_RuleParts[bukkit].Count(); + for ( int i = 0; i < count; ++i ) + { + if (V_strncmp( m_RuleParts[bukkit].GetElementName(i), name, CRR_Response::MAX_RULE_NAME ) == 0) + return m_RuleParts[bukkit][i]; + } + } + + return NULL; +} + + +int ResponseRulePartition::Count( void ) +{ + int count = 0 ; + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + count += m_RuleParts[bukkit].Count(); + } + + return count; +} + +void ResponseRulePartition::RemoveAll( void ) +{ + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + for ( int i = m_RuleParts[bukkit].FirstInorder(); i != m_RuleParts[bukkit].InvalidIndex(); i = m_RuleParts[bukkit].NextInorder( i ) ) + { + delete m_RuleParts[bukkit][ i ]; + } + m_RuleParts[bukkit].RemoveAll(); + } +} + +#ifdef MAPBASE +void ResponseRulePartition::PurgeAndDeleteElements() +{ + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + for ( int i = m_RuleParts[bukkit].FirstInorder(); i != m_RuleParts[bukkit].InvalidIndex(); i = m_RuleParts[bukkit].NextInorder( i ) ) + { + delete m_RuleParts[bukkit][ i ]; + } + m_RuleParts[bukkit].Purge(); + } +} +#endif + +// don't bucket "subject" criteria that prefix with operators, since stripping all that out again would +// be a big pain, and the most important rules that need subjects are tlk_remarks anyway. +static inline bool CanBucketBySubject( const char * RESTRICT pszSubject ) +{ + return pszSubject && + ( ( pszSubject[0] >= 'A' && pszSubject[0] <= 'Z' ) || + ( pszSubject[0] >= 'a' && pszSubject[0] <= 'z' ) ) +#ifdef MAPBASE + && !Matcher_ContainsWildcard( pszSubject ) +#endif + ; +} + +ResponseRulePartition::tRuleDict &ResponseRulePartition::GetDictForRule( CResponseSystem *pSystem, Rule *pRule ) +{ +#ifdef MAPBASE + const static CUtlSymbol kWHO = CriteriaSet::ComputeCriteriaSymbol( rr_bucket_name_who.GetString() ); + const static CUtlSymbol kCONCEPT = CriteriaSet::ComputeCriteriaSymbol( rr_bucket_name_concept.GetString() ); + const static CUtlSymbol kSUBJECT = CriteriaSet::ComputeCriteriaSymbol( rr_bucket_name_subject.GetString() ); +#else + const static CUtlSymbol kWHO = CriteriaSet::ComputeCriteriaSymbol("Who"); + const static CUtlSymbol kCONCEPT = CriteriaSet::ComputeCriteriaSymbol("Concept"); + const static CUtlSymbol kSUBJECT = CriteriaSet::ComputeCriteriaSymbol("Subject"); +#endif + + const char *pszSpeaker = pRule->GetValueForRuleCriterionByName( pSystem, kWHO ); + const char *pszConcept = pRule->GetValueForRuleCriterionByName( pSystem, kCONCEPT ); + const Criteria *pSubjCrit = pRule->GetPointerForRuleCriterionByName( pSystem, kSUBJECT ); + + return m_RuleParts[ + GetBucketForSpeakerAndConcept( pszSpeaker, pszConcept, + ( pSubjCrit && pSubjCrit->required && CanBucketBySubject(pSubjCrit->value) ) ? + pSubjCrit->value : + NULL ) + ]; +} + + +void ResponseRulePartition::GetDictsForCriteria( CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > *pResult, const CriteriaSet &criteria ) +{ + pResult->RemoveAll(); + pResult->EnsureCapacity( 2 ); + + // get the values for Who and Concept, which are what we bucket on + int speakerIdx = criteria.FindCriterionIndex( "Who" ); + const char *pszSpeaker = speakerIdx != -1 ? criteria.GetValue( speakerIdx ) : NULL ; + + int conceptIdx = criteria.FindCriterionIndex( "Concept" ); + const char *pszConcept = conceptIdx != -1 ? criteria.GetValue( conceptIdx ) : NULL ; + + int subjectIdx = criteria.FindCriterionIndex( "Subject" ); + const char *pszSubject = subjectIdx != -1 ? criteria.GetValue( subjectIdx ) : NULL ; + + pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, pszSubject) ] ); + // also try the rules not specifying subject + pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, NULL) ] ); + +} \ No newline at end of file diff --git a/responserules/runtime/response_types_internal.h b/responserules/runtime/response_types_internal.h new file mode 100644 index 00000000..08f31185 --- /dev/null +++ b/responserules/runtime/response_types_internal.h @@ -0,0 +1,560 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_TYPES_INTERNAL_H +#define RESPONSE_TYPES_INTERNAL_H +#ifdef _WIN32 +#pragma once +#endif + +#include "responserules/response_types.h" +#include "utldict.h" + + +namespace ResponseRules +{ + + inline unsigned FASTCALL HashStringConventional( const char *pszKey ) + { + unsigned hash = 0xAAAAAAAA; // Alternating 1's and 0's to maximize the effect of the later multiply and add + + for( ; *pszKey ; pszKey++ ) + { + hash = ( ( hash << 5 ) + hash ) + (uint8)(*pszKey); + } + + return hash; + } + + // Note: HashString causes collisions!!! +#define RR_HASH HashStringConventional + +#pragma pack(push,1) + + class Matcher + { + public: + Matcher(); + + void Describe( void ); + + float maxval; + float minval; + + bool valid : 1; //1 + bool isnumeric : 1; //2 + bool notequal : 1; //3 + bool usemin : 1; //4 + bool minequals : 1; //5 + bool usemax : 1; //6 + bool maxequals : 1; //7 +#ifdef MAPBASE + bool isbit : 1; //8 +#endif + + void SetToken( char const *s ); + + char const *GetToken(); + + void SetRaw( char const *raw ); + + char const *GetRaw(); + + private: + CUtlSymbol token; + CUtlSymbol rawtoken; + }; +#pragma pack(pop) + + struct Criteria + { + Criteria(); + Criteria& operator =(const Criteria& src ); + + Criteria(const Criteria& src ); + ~Criteria(); + + // Does this criterion recursively contain more criteria? + inline bool IsSubCriteriaType() const + { + return ( subcriteria.Count() > 0 ) ? true : false; + } + + // const char *name; + CUtlSymbol nameSym; + const char *value; + float16 weight; + bool required; + + Matcher matcher; + + // Indices into sub criteria + CUtlVectorConservative< unsigned short > subcriteria; + }; + +#pragma pack(push,1) + /// This is a response block as read from the file, + /// different from CRR_Response which is what is handed + /// back to queries. + struct ParserResponse + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + ParserResponse(); + ParserResponse( const ParserResponse& src ); + ParserResponse& operator =( const ParserResponse& src ); + ~ParserResponse(); + + ResponseType_t GetType() { return (ResponseType_t)type; } + + ResponseParams params; + + const char *value; // fixed up value spot // 4 + float16 weight; // 6 + + byte depletioncount; // 7 + byte type : 6; // 8 + byte first : 1; // + byte last : 1; // + + ALIGN32 AI_ResponseFollowup m_followup; // info on whether I should force the other guy to say something + }; +#pragma pack(pop) + +#pragma pack(push,1) + struct ResponseGroup + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + ResponseGroup() + { + // By default visit all nodes before repeating + m_bSequential = false; + m_bNoRepeat = false; + m_bEnabled = true; + m_nCurrentIndex = 0; + m_bDepleteBeforeRepeat = true; + m_nDepletionCount = 1; + m_bHasFirst = false; + m_bHasLast = false; + } + + ResponseGroup( const ResponseGroup& src ) + { + int c = src.group.Count(); + for ( int i = 0; i < c; i++ ) + { + group.AddToTail( src.group[ i ] ); + } + + m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; + m_nDepletionCount = src.m_nDepletionCount; + m_bHasFirst = src.m_bHasFirst; + m_bHasLast = src.m_bHasLast; + m_bSequential = src.m_bSequential; + m_bNoRepeat = src.m_bNoRepeat; + m_bEnabled = src.m_bEnabled; + m_nCurrentIndex = src.m_nCurrentIndex; + } + + ResponseGroup& operator=( const ResponseGroup& src ) + { + if ( this == &src ) + return *this; + int c = src.group.Count(); + for ( int i = 0; i < c; i++ ) + { + group.AddToTail( src.group[ i ] ); + } + + m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; + m_nDepletionCount = src.m_nDepletionCount; + m_bHasFirst = src.m_bHasFirst; + m_bHasLast = src.m_bHasLast; + m_bSequential = src.m_bSequential; + m_bNoRepeat = src.m_bNoRepeat; + m_bEnabled = src.m_bEnabled; + m_nCurrentIndex = src.m_nCurrentIndex; + return *this; + } + + bool HasUndepletedChoices() const + { + if ( !m_bDepleteBeforeRepeat ) + return true; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + if ( group[ i ].depletioncount != m_nDepletionCount ) + return true; + } + + return false; + } + + void MarkResponseUsed( int idx ) + { + if ( !m_bDepleteBeforeRepeat ) + return; + + if ( idx < 0 || idx >= group.Count() ) + { + Assert( 0 ); + return; + } + + group[ idx ].depletioncount = m_nDepletionCount; + } + + void ResetDepletionCount() + { + if ( !m_bDepleteBeforeRepeat ) + return; + ++m_nDepletionCount; + } + + void Reset() + { + ResetDepletionCount(); + SetEnabled( true ); + SetCurrentIndex( 0 ); + m_nDepletionCount = 1; + + for ( int i = 0; i < group.Count(); ++i ) + { + group[ i ].depletioncount = 0; + } + } + + bool HasUndepletedFirst( int& index ) + { + index = -1; + + if ( !m_bDepleteBeforeRepeat ) + return false; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &group[ i ]; + + if ( ( r->depletioncount != m_nDepletionCount ) && r->first ) + { + index = i; + return true; + } + } + + return false; + } + + bool HasUndepletedLast( int& index ) + { + index = -1; + + if ( !m_bDepleteBeforeRepeat ) + return false; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &group[ i ]; + + if ( ( r->depletioncount != m_nDepletionCount ) && r->last ) + { + index = i; + return true; + } + } + + return false; + } + + bool ShouldCheckRepeats() const { return m_bDepleteBeforeRepeat; } + int GetDepletionCount() const { return m_nDepletionCount; } + + bool IsSequential() const { return m_bSequential; } + void SetSequential( bool seq ) { m_bSequential = seq; } + + bool IsNoRepeat() const { return m_bNoRepeat; } + void SetNoRepeat( bool norepeat ) { m_bNoRepeat = norepeat; } + + bool IsEnabled() const { return m_bEnabled; } + void SetEnabled( bool enabled ) { m_bEnabled = enabled; } + + int GetCurrentIndex() const { return m_nCurrentIndex; } + void SetCurrentIndex( byte idx ) { m_nCurrentIndex = idx; } + + CUtlVector< ParserResponse > group; + + bool m_bEnabled; + + byte m_nCurrentIndex; + // Invalidation counter + byte m_nDepletionCount; + + // Use all slots before repeating any + bool m_bDepleteBeforeRepeat : 1; + bool m_bHasFirst : 1; + bool m_bHasLast : 1; + bool m_bSequential : 1; + bool m_bNoRepeat : 1; + }; +#pragma pack(pop) + +#pragma pack(push,1) + struct Rule + { + Rule(); + Rule( const Rule& src ); + ~Rule(); + Rule& operator =( const Rule& src ); + + void SetContext( const char *context ); + + const char *GetContext( void ) const { return m_szContext; } + + inline bool IsEnabled() const { return m_bEnabled; } + inline void Disable() { m_bEnabled = false; } + inline bool IsMatchOnce() const { return m_bMatchOnce; } +#ifdef MAPBASE + inline int GetContextFlags() const { return m_iContextFlags; } + inline bool IsApplyContextToWorld() const { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } +#else + inline bool IsApplyContextToWorld() const { return m_bApplyContextToWorld; } +#endif + + const char *GetValueForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ); + const Criteria *GetPointerForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ); + + // Indices into underlying criteria and response dictionaries + CUtlVectorConservative< unsigned short > m_Criteria; + CUtlVectorConservative< unsigned short> m_Responses; + + const char *m_szContext; + uint8 m_nForceWeight; + +#ifdef MAPBASE + // TODO: Could this cause any issues with the code optimization? + uint8 m_iContextFlags; +#else + bool m_bApplyContextToWorld : 1; +#endif + + bool m_bMatchOnce : 1; + bool m_bEnabled : 1; + + private: + // what is this, lisp? + const char *RecursiveGetValueForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ); + const Criteria *RecursiveGetPointerForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ); + }; +#pragma pack(pop) + + template + class CResponseDict : public CUtlMap + { + public: + CResponseDict() : CUtlMap( DefLessFunc( unsigned int ) ), m_ReverseMap( DefLessFunc( unsigned int ) ) + { + } + + I Insert( const char *pName, const T &element ) + { + extern const char *ResponseCopyString( const char *in ); + char const *pString = ResponseCopyString( pName ); + unsigned int hash = RR_HASH( pString ); + m_ReverseMap.Insert( hash, pString ); + return CUtlMap::Insert( hash, element ); + } + + I Insert( const char *pName ) + { + extern const char *ResponseCopyString( const char *in ); + char const *pString = ResponseCopyString( pName ); + unsigned int hash = RR_HASH( pString ); + m_ReverseMap.Insert( hash, pString ); + return CUtlMap::Insert( hash ); + } + + I Find( char const *pName ) const + { + unsigned int hash = RR_HASH( pName ); + return CUtlMap::Find( hash ); + } + + const char *GetElementName( I i ) + { + int k = this->Key( i ); + int slot = m_ReverseMap.Find( k ); + if ( slot == m_ReverseMap.InvalidIndex() ) + return ""; + return m_ReverseMap[ slot ]; + } + + const char *GetElementName( I i ) const + { + int k = this->Key( i ); + int slot = m_ReverseMap.Find( k ); + if ( slot == m_ReverseMap.InvalidIndex() ) + return ""; + return m_ReverseMap[ slot ]; + } + + private: + CUtlMap< unsigned int, const char * > m_ReverseMap; + + }; + + // define this to 1 to enable printing some occupancy + // information on the response system via concommmand + // rr_dumphashinfo + #define RR_DUMPHASHINFO_ENABLED 0 + // The Rules are partitioned based on a variety of factors (presently, + // speaker and concept) for faster lookup, basically a seperate-chained hash. + struct ResponseRulePartition + { + ResponseRulePartition( void ); + ~ResponseRulePartition(); + + typedef CResponseDict< Rule * > tRuleDict; + typedef uint32 tIndex; // an integer that can be used to find any rule in the dict + + /// get the appropriate m_rules dict for the provided rule + tRuleDict &GetDictForRule( CResponseSystem *pSystem, Rule *pRule ); + + /// get all bucket full of rules that might possibly match the given criteria. + /// (right now they are bucketed such that all rules that can possibly match a + /// criteria are in one of two dictionaries) + void GetDictsForCriteria( CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > *pResult, const CriteriaSet &criteria ); + + // dump everything. + void RemoveAll(); +#ifdef MAPBASE + void PurgeAndDeleteElements(); +#endif + + inline Rule &operator[]( tIndex idx ); + int Count( void ); // number of elements inside, but you can't iterate from 0 to this + char const *GetElementName( const tIndex &i ) const; + Rule *FindByName( char const *name ) const; + + /// given a dictionary and an element number inside that dict, + /// return a tIndex + tIndex IndexFromDictElem( tRuleDict* pDict, int elem ); + + // for iteration: + inline tIndex First( void ); + inline tIndex Next( const tIndex &idx ); + inline bool IsValid( const tIndex &idx ) const; + inline static tIndex InvalidIdx( void ) + { + return ((tIndex) -1); + } + + // used only for debug prints, do not rely on them otherwise + inline unsigned int BucketFromIdx( const tIndex &idx ) const ; + inline unsigned int PartFromIdx( const tIndex &idx ) const ; + + enum { + N_RESPONSE_PARTITIONS = 256, + kIDX_ELEM_MASK = 0xFFF, ///< this is used to mask the element number part of a ResponseRulePartition::tIndex + }; + +#if RR_DUMPHASHINFO_ENABLED + void PrintBucketInfo( CResponseSystem *pSys ); +#endif + + private: + tRuleDict m_RuleParts[N_RESPONSE_PARTITIONS]; + unsigned int GetBucketForSpeakerAndConcept( const char *pszSpeaker, const char *pszConcept, const char *pszSubject ); + }; + + // // // // // inline functions + + inline ResponseRulePartition::tIndex ResponseRulePartition::First( void ) + { + // find the first bucket that has anything + for ( int bucket = 0 ; bucket < N_RESPONSE_PARTITIONS; bucket++ ) + { + if ( m_RuleParts[bucket].Count() > 0 ) + return bucket << 16; + } + return InvalidIdx(); + } + + inline ResponseRulePartition::tIndex ResponseRulePartition::Next( const tIndex &idx ) + { + int bucket = BucketFromIdx( idx ); + unsigned int elem = PartFromIdx( idx ); + Assert( IsValid(idx) ); + AssertMsg( elem < kIDX_ELEM_MASK, "Too many response rules! Overflow! Doom!" ); + if ( elem + 1 < m_RuleParts[bucket].Count() ) + { + return idx+1; + } + else + { + // walk through the other buckets, skipping empty ones, until we find one with responses and give up. + while ( ++bucket < N_RESPONSE_PARTITIONS ) + { + if ( m_RuleParts[bucket].Count() > 0 ) + { + // 0th element in nth bucket + return bucket << 16; + } + } + + // out of buckets + return InvalidIdx(); + + } + } + + inline Rule &ResponseRulePartition::operator[]( tIndex idx ) + { + Assert( IsValid(idx) ); + return *m_RuleParts[ BucketFromIdx(idx) ][ PartFromIdx(idx) ] ; + } + + inline unsigned int ResponseRulePartition::BucketFromIdx( const tIndex &idx ) const + { + return idx >> 16; + } + + inline unsigned int ResponseRulePartition::PartFromIdx( const tIndex &idx ) const + { + return idx & kIDX_ELEM_MASK; + } + + inline bool ResponseRulePartition::IsValid( const tIndex & idx ) const + { + // make sure that the idx type for the dicts is still short + COMPILE_TIME_ASSERT( sizeof(m_RuleParts[0].FirstInorder()) == 2 ); + + if ( idx == -1 ) + return false; + + int bucket = idx >> 16; + unsigned int elem = idx & kIDX_ELEM_MASK; + + return ( bucket < N_RESPONSE_PARTITIONS && + elem < m_RuleParts[bucket].Count() ); + } + + //----------------------------------------------------------------------------- + // PARSER TYPES -- these are internal to the response system, and represent + // the objects as loaded from disk. + //----------------------------------------------------------------------------- + + +} + +#include "response_system.h" + +#endif \ No newline at end of file diff --git a/responserules/runtime/rr_convars.cpp b/responserules/runtime/rr_convars.cpp new file mode 100644 index 00000000..986ae0cd --- /dev/null +++ b/responserules/runtime/rr_convars.cpp @@ -0,0 +1,14 @@ +//========= Copyright 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Convars used by the response rule system. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" +#include + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + diff --git a/responserules/runtime/rr_response.cpp b/responserules/runtime/rr_response.cpp new file mode 100644 index 00000000..b652e8b3 --- /dev/null +++ b/responserules/runtime/rr_response.cpp @@ -0,0 +1,387 @@ +//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "rrbase.h" + +#include +#include "tier1/mapbase_con_groups.h" + +/* +#include "AI_Criteria.h" +#include "ai_speech.h" +#include +#include "engine/IEngineSound.h" +*/ + +// memdbgon must be the last include file in a .cpp file!!! +#include + +using namespace ResponseRules; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRR_Response::CRR_Response() : m_fMatchScore(0) +{ + m_Type = ResponseRules::RESPONSE_NONE; + m_szResponseName[0] = 0; + m_szMatchingRule[0]=0; + m_szContext = NULL; +#ifdef MAPBASE + m_iContextFlags = 0; +#else + m_bApplyContextToWorld = false; +#endif +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CRR_Response::CRR_Response( const CRR_Response &from ) : m_fMatchScore(0) +{ + // Assert( (void*)(&m_Type) == (void*)this ); + Invalidate(); + memcpy( this, &from, sizeof(*this) ); + m_szContext = NULL; + SetContext( from.m_szContext ); +#ifdef MAPBASE + m_iContextFlags = from.m_iContextFlags; +#else + m_bApplyContextToWorld = from.m_bApplyContextToWorld; +#endif +} + + +//----------------------------------------------------------------------------- +CRR_Response &CRR_Response::operator=( const CRR_Response &from ) +{ + // Assert( (void*)(&m_Type) == (void*)this ); + Invalidate(); + memcpy( this, &from, sizeof(*this) ); + m_szContext = NULL; + SetContext( from.m_szContext ); +#ifdef MAPBASE + m_iContextFlags = from.m_iContextFlags; +#else + m_bApplyContextToWorld = from.m_bApplyContextToWorld; +#endif + return *this; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRR_Response::~CRR_Response() +{ + if (m_szContext) + delete[] m_szContext; +} + +void CRR_Response::Invalidate() +{ + if (m_szContext) + { + delete[] m_szContext; + m_szContext = NULL; + } + m_Type = ResponseRules::RESPONSE_NONE; + m_szResponseName[0] = 0; + // not really necessary: + /* + m_szMatchingRule[0]=0; + m_szContext = NULL; + m_bApplyContextToWorld = false; + */ +} + +// please do not new or delete CRR_Responses. +void CRR_Response::operator delete(void* p) +{ + AssertMsg(false, "DO NOT new or delete CRR_Response s."); + free(p); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *response - +// *criteria - +//----------------------------------------------------------------------------- +void CRR_Response::Init( ResponseType_t type, const char *responseName, const ResponseParams& responseparams, const char *ruleName, const char *applyContext, bool bApplyContextToWorld ) +{ + m_Type = type; + Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); + // Copy underlying criteria + Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); + m_Params = responseparams; + SetContext( applyContext ); +#ifdef MAPBASE + bApplyContextToWorld ? m_iContextFlags = APPLYCONTEXT_WORLD : m_iContextFlags = 0; +#else + m_bApplyContextToWorld = bApplyContextToWorld; +#endif +} + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Input : *response - +// *criteria - +//----------------------------------------------------------------------------- +void CRR_Response::Init( ResponseType_t type, const char *responseName, const ResponseParams& responseparams, const char *ruleName, const char *applyContext, int iContextFlags ) +{ + m_Type = type; + Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); + // Copy underlying criteria + Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); + m_Params = responseparams; + SetContext( applyContext ); + m_iContextFlags = iContextFlags; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Debug-print the response. You can optionally pass in the criteria +// used to come up with this response (usually present in the calling function) +// if you want to print that as well. DO NOT store the entire criteria set in +// CRR_Response just to make this debug print cleaner. +//----------------------------------------------------------------------------- +void CRR_Response::Describe( const CriteriaSet *pDebugCriteria ) +{ + if ( pDebugCriteria ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Search criteria:\n" ); + pDebugCriteria->Describe(); + } + + if ( m_szMatchingRule[ 0 ] ) + { + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Matched rule '%s', ", m_szMatchingRule ); + } + if ( m_szContext ) + { +#ifdef MAPBASE + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "Contexts to set '%s' on ", m_szContext ); + if (m_iContextFlags & APPLYCONTEXT_WORLD) + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "world, " ); + else if (m_iContextFlags & APPLYCONTEXT_SQUAD) + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "squad, " ); + else if (m_iContextFlags & APPLYCONTEXT_ENEMY) + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "enemy, " ); + else + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "speaker, " ); +#else + DevMsg( "Contexts to set '%s' on %s, ", m_szContext, m_bApplyContextToWorld ? "world" : "speaker" ); +#endif + } + + CGMsg( 1, CON_GROUP_RESPONSE_SYSTEM, "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CRR_Response::GetName( char *buf, size_t buflen ) const +{ + Q_strncpy( buf, m_szResponseName, buflen ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CRR_Response::GetResponse( char *buf, size_t buflen ) const +{ + GetName( buf, buflen ); +} + + +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CRR_Response::GetRule( char *buf, size_t buflen ) const +{ + Q_strncpy( buf, m_szMatchingRule, buflen ); +} +#endif + + +const char* ResponseRules::CRR_Response::GetNamePtr() const +{ + return m_szResponseName; +} +const char* ResponseRules::CRR_Response::GetResponsePtr() const +{ + return m_szResponseName; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : type - +// Output : char const +//----------------------------------------------------------------------------- +const char *CRR_Response::DescribeResponse( ResponseType_t type ) +{ + if ( (int)type < 0 || (int)type >= ResponseRules::NUM_RESPONSES ) + { + Assert( 0 ); + return "???CRR_Response bogus index"; + } + + switch( type ) + { + default: + { + Assert( 0 ); + } + // Fall through + case ResponseRules::RESPONSE_NONE: + return "RESPONSE_NONE"; + case ResponseRules::RESPONSE_SPEAK: + return "RESPONSE_SPEAK"; + case ResponseRules::RESPONSE_SENTENCE: + return "RESPONSE_SENTENCE"; + case ResponseRules::RESPONSE_SCENE: + return "RESPONSE_SCENE"; + case ResponseRules::RESPONSE_RESPONSE: + return "RESPONSE_RESPONSE"; + case ResponseRules::RESPONSE_PRINT: + return "RESPONSE_PRINT"; + case ResponseRules::RESPONSE_ENTITYIO: + return "RESPONSE_ENTITYIO"; +#ifdef MAPBASE + case ResponseRules::RESPONSE_VSCRIPT: + return "RESPONSE_VSCRIPT"; + case ResponseRules::RESPONSE_VSCRIPT_FILE: + return "RESPONSE_VSCRIPT_FILE"; +#endif + } + + return "RESPONSE_NONE"; +} + +/* +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRR_Response::Release() +{ + delete this; +} +*/ + +//----------------------------------------------------------------------------- +// Purpose: +// Output : soundlevel_t +//----------------------------------------------------------------------------- +soundlevel_t CRR_Response::GetSoundLevel() const +{ + if ( m_Params.flags & ResponseParams::RG_SOUNDLEVEL ) + { + return (soundlevel_t)m_Params.soundlevel; + } + + return SNDLVL_TALKING; +} + +float CRR_Response::GetRespeakDelay( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_RESPEAKDELAY ) + { + interval_t temp; + m_Params.respeakdelay.ToInterval( temp ); + return RandomInterval( temp ); + } + + return 0.0f; +} + +float CRR_Response::GetWeaponDelay( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_WEAPONDELAY ) + { + interval_t temp; + m_Params.weapondelay.ToInterval( temp ); + return RandomInterval( temp ); + } + + return 0.0f; +} + +bool CRR_Response::GetSpeakOnce( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_SPEAKONCE ) + { + return true; + } + + return false; +} + +bool CRR_Response::ShouldntUseScene( void ) const +{ + return ( m_Params.flags & ResponseParams::RG_DONT_USE_SCENE ) != 0; +} + +bool CRR_Response::ShouldBreakOnNonIdle( void ) const +{ + return ( m_Params.flags & ResponseParams::RG_STOP_ON_NONIDLE ) != 0; +} + +int CRR_Response::GetOdds( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_ODDS ) + { + return m_Params.odds; + } + return 100; +} + +float CRR_Response::GetDelay() const +{ + if ( m_Params.flags & ResponseParams::RG_DELAYAFTERSPEAK ) + { + interval_t temp; + m_Params.delay.ToInterval( temp ); + return RandomInterval( temp ); + } + return 0.0f; +} + +float CRR_Response::GetPreDelay() const +{ + if ( m_Params.flags & ResponseParams::RG_DELAYBEFORESPEAK ) + { + interval_t temp; + m_Params.predelay.ToInterval( temp ); + return RandomInterval( temp ); + } + return 0.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: Sets context string +// Output : void +//----------------------------------------------------------------------------- +void CRR_Response::SetContext( const char *context ) +{ + if (m_szContext) + { + delete[] m_szContext; + m_szContext = NULL; + } + + if ( context ) + { + int len = Q_strlen( context ); + m_szContext = new char[ len + 1 ]; + Q_memcpy( m_szContext, context, len ); + m_szContext[ len ] = 0; + } +} diff --git a/responserules/runtime/rr_speechconcept.cpp b/responserules/runtime/rr_speechconcept.cpp new file mode 100644 index 00000000..7e1e04ab --- /dev/null +++ b/responserules/runtime/rr_speechconcept.cpp @@ -0,0 +1,73 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include + +#if RR_CONCEPTS_ARE_STRINGS +#pragma error("RR_CONCEPTS_ARE_STRINGS no longer supported") +#else + +using namespace ResponseRules; + +// Used to turn ad-hoc concept from strings into numbers. +CRR_ConceptSymbolTable *g_pRRConceptTable = NULL; + +// Q&D hack to defer initialization of concept table until I can figure out where it +// really needs to come from. +static void InitializeRRConceptTable() +{ + if (g_pRRConceptTable == NULL) + { + g_pRRConceptTable = new CRR_ConceptSymbolTable( 64, 64, true ); + } +} + +// construct from string +CRR_Concept::CRR_Concept(const char *fromString) +{ + InitializeRRConceptTable(); + m_iConcept = g_pRRConceptTable->AddString(fromString); +} + +CRR_Concept &CRR_Concept::operator=(const char *fromString) +{ + InitializeRRConceptTable(); + m_iConcept = g_pRRConceptTable->AddString(fromString); + return *this; +} + +bool CRR_Concept::operator==(const char *pszConcept) +{ + int otherConcept = g_pRRConceptTable->Find(pszConcept); + return ( otherConcept != UTL_INVAL_SYMBOL && otherConcept == m_iConcept ); +} + +const char *CRR_Concept::GetStringConcept() const +{ + InitializeRRConceptTable(); + AssertMsg( m_iConcept.IsValid(), "AI Concept has invalid string symbol.\n" ); + const char * retval = g_pRRConceptTable->String(m_iConcept); + AssertMsg( retval, "An RR_Concept couldn't find its string in the symbol table!\n" ); + if (retval == NULL) + { + Warning( "An RR_Concept couldn't find its string in the symbol table!\n" ); + retval = ""; + } + return retval; +} + +const char *CRR_Concept::GetStringForGenericId(tGenericId genericId) +{ + InitializeRRConceptTable(); + return g_pRRConceptTable->String(genericId); +} + +#endif diff --git a/responserules/runtime/rrbase.h b/responserules/runtime/rrbase.h new file mode 100644 index 00000000..e7af74de --- /dev/null +++ b/responserules/runtime/rrbase.h @@ -0,0 +1,59 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RRBASE_H +#define RRBASE_H +#ifdef _WIN32 +#pragma once +#endif + +#ifdef _WIN32 +// Silence certain warnings +// #pragma warning(disable : 4244) // int or float down-conversion +// #pragma warning(disable : 4305) // int or float data truncation +// #pragma warning(disable : 4201) // nameless struct/union +// #pragma warning(disable : 4511) // copy constructor could not be generated +// #pragma warning(disable : 4675) // resolved overload was found by argument dependent lookup +#endif + +#ifdef _DEBUG +#define DEBUG 1 +#endif + +// Misc C-runtime library headers +#include +#include +#include + +// tier 0 +#include "tier0/dbg.h" +#include "tier0/platform.h" +#include "basetypes.h" + +// tier 1 +#include "tier1/strtools.h" +#include "utlvector.h" +#include "utlsymbol.h" + +// tier 2 +#include "string_t.h" + +// Shared engine/DLL constants +#include "const.h" +#include "edict.h" + +// app +#if defined(_X360) +#define DISABLE_DEBUG_HISTORY 1 +#endif + +#include "responserules/response_types.h" +#include "response_types_internal.h" +#include "responserules/response_host_interface.h" + + +#endif // CBASE_H diff --git a/responserules/runtime/rrrlib.cpp b/responserules/runtime/rrrlib.cpp new file mode 100644 index 00000000..0d2c49fd --- /dev/null +++ b/responserules/runtime/rrrlib.cpp @@ -0,0 +1,13 @@ +/// PLACEHOLDER FILE FOR RESPONSE RULES RUNTIME LIBRARY + +#include "rrbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +namespace ResponseRules +{ + /// Custom symbol table for the response rules. + CUtlSymbolTable g_RS; +}; \ No newline at end of file diff --git a/responserules/runtime/stdafx.cpp b/responserules/runtime/stdafx.cpp new file mode 100644 index 00000000..4199359f --- /dev/null +++ b/responserules/runtime/stdafx.cpp @@ -0,0 +1,11 @@ +//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Builds the precompiled header for the game DLL +// +// $NoKeywords: $ +//=============================================================================// + + +#include "rrbase.h" + +// NOTE: DO NOT ADD ANY CODE OR HEADERS TO THIS FILE!!! diff --git a/run.sh b/run.sh new file mode 100755 index 00000000..fb183e55 --- /dev/null +++ b/run.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +cd "$(dirname "${BASH_SOURCE-$0}")" || exit +source devtools/linux/env.sh + +EXE=\"$GAME_DIR/hl2_linux\" +ARGS=(-game "$MOD_DIR" -windowed -w 1920 -h 1080 -dev -vulkan +map d1_town_05 "$*") + +echo Running command run ./hl2_linux "$EXE" "${ARGS[@]}" + +run "$EXE" "${ARGS[@]}" diff --git a/thirdparty/SDL/include/SDL/SDL.h b/thirdparty/SDL/include/SDL/SDL.h new file mode 100644 index 00000000..12e7f31a --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL.h @@ -0,0 +1,233 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL.h + * + * Main include header for the SDL library + */ + + +#ifndef SDL_h_ +#define SDL_h_ + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_audio.h" +#include "SDL_clipboard.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_filesystem.h" +#include "SDL_gamecontroller.h" +#include "SDL_guid.h" +#include "SDL_haptic.h" +#include "SDL_hidapi.h" +#include "SDL_hints.h" +#include "SDL_joystick.h" +#include "SDL_loadso.h" +#include "SDL_log.h" +#include "SDL_messagebox.h" +#include "SDL_metal.h" +#include "SDL_mutex.h" +#include "SDL_power.h" +#include "SDL_render.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_shape.h" +#include "SDL_system.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_locale.h" +#include "SDL_misc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/** + * \name SDL_INIT_* + * + * These are the flags which may be passed to SDL_Init(). You should + * specify the subsystems which you will be using in your application. + */ +/* @{ */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_SENSOR 0x00008000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ +#define SDL_INIT_EVERYTHING ( \ + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \ + ) +/* @} */ + +/** + * Initialize the SDL library. + * + * SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the + * two may be used interchangeably. Though for readability of your code + * SDL_InitSubSystem() might be preferred. + * + * The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread) + * subsystems are initialized by default. Message boxes + * (SDL_ShowSimpleMessageBox) also attempt to work without initializing the + * video subsystem, in hopes of being useful in showing an error dialog when + * SDL_Init fails. You must specifically initialize other subsystems if you + * use them in your application. + * + * Logging (such as SDL_Log) works without initialization, too. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_INIT_TIMER`: timer subsystem + * - `SDL_INIT_AUDIO`: audio subsystem + * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events + * subsystem + * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the + * events subsystem + * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem + * - `SDL_INIT_GAMECONTROLLER`: controller subsystem; automatically + * initializes the joystick subsystem + * - `SDL_INIT_EVENTS`: events subsystem + * - `SDL_INIT_EVERYTHING`: all of the above subsystems + * - `SDL_INIT_NOPARACHUTE`: compatibility; this flag is ignored + * + * Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem() + * for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or + * call SDL_Quit() to force shutdown). If a subsystem is already loaded then + * this call will increase the ref-count and return. + * + * \param flags subsystem initialization flags + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + * \sa SDL_SetMainReady + * \sa SDL_WasInit + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/** + * Compatibility function to initialize the SDL library. + * + * In SDL2, this function and SDL_Init() are interchangeable. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_Quit + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/** + * Shut down specific SDL subsystems. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * SDL_QuitSubSystem() and SDL_WasInit() will not work. You will need to use + * that subsystem's quit function (SDL_VideoQuit()) directly instead. But + * generally, you should not be using those functions directly anyhow; use + * SDL_Init() instead. + * + * You still need to call SDL_Quit() even if you close all open subsystems + * with SDL_QuitSubSystem(). + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/** + * Get a mask of the specified subsystems which are currently initialized. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns a mask of all initialized subsystems if `flags` is 0, otherwise it + * returns the initialization status of the specified subsystems. + * + * The return value does not include SDL_INIT_NOPARACHUTE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_InitSubSystem + */ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/** + * Clean up all initialized subsystems. + * + * You should call this function even if you have already shutdown each + * initialized subsystem with SDL_QuitSubSystem(). It is safe to call this + * function even in the case of errors in initialization. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * then you must use that subsystem's quit function (SDL_VideoQuit()) to shut + * it down before calling SDL_Quit(). But generally, you should not be using + * those functions directly anyhow; use SDL_Init() instead. + * + * You can use this function with atexit() to ensure that it is run when your + * application is shutdown, but it is not wise to do this from a library or + * other dynamically loaded code. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_assert.h b/thirdparty/SDL/include/SDL/SDL_assert.h new file mode 100644 index 00000000..e71cf979 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_assert.h @@ -0,0 +1,326 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_assert_h_ +#define SDL_assert_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SDL_ASSERT_LEVEL +#ifdef SDL_DEFAULT_ASSERT_LEVEL +#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL +#elif defined(_DEBUG) || defined(DEBUG) || \ + (defined(__GNUC__) && !defined(__OPTIMIZE__)) +#define SDL_ASSERT_LEVEL 2 +#else +#define SDL_ASSERT_LEVEL 1 +#endif +#endif /* SDL_ASSERT_LEVEL */ + +/* +These are macros and not first class functions so that the debugger breaks +on the assertion line and not in some random guts of SDL, and so each +assert can have unique static variables associated with it. +*/ + +#if defined(_MSC_VER) +/* Don't include intrin.h here because it contains C++ code */ + extern void __cdecl __debugbreak(void); + #define SDL_TriggerBreakpoint() __debugbreak() +#elif _SDL_HAS_BUILTIN(__builtin_debugtrap) + #define SDL_TriggerBreakpoint() __builtin_debugtrap() +#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) +#elif defined(__APPLE__) && defined(__arm__) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" ) +#elif defined(__386__) && defined(__WATCOMC__) + #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } +#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) + #include + #define SDL_TriggerBreakpoint() raise(SIGTRAP) +#else + /* How do we trigger breakpoints on this platform? */ + #define SDL_TriggerBreakpoint() +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ +# define SDL_FUNCTION __func__ +#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__)) +# define SDL_FUNCTION __FUNCTION__ +#else +# define SDL_FUNCTION "???" +#endif +#define SDL_FILE __FILE__ +#define SDL_LINE __LINE__ + +/* +sizeof (x) makes the compiler still parse the expression even without +assertions enabled, so the code is always checked at compile time, but +doesn't actually generate code for it, so there are no side effects or +expensive checks at run time, just the constant size of what x WOULD be, +which presumably gets optimized out as unused. +This also solves the problem of... + + int somevalue = blah(); + SDL_assert(somevalue == 1); + +...which would cause compiles to complain that somevalue is unused if we +disable assertions. +*/ + +/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking + this condition isn't constant. And looks like an owl's face! */ +#ifdef _MSC_VER /* stupid /W4 warnings. */ +#define SDL_NULL_WHILE_LOOP_CONDITION (0,0) +#else +#define SDL_NULL_WHILE_LOOP_CONDITION (0) +#endif + +#define SDL_disabled_assert(condition) \ + do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) + +typedef enum +{ + SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ + SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ + SDL_ASSERTION_ABORT, /**< Terminate the program. */ + SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ + SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ +} SDL_AssertState; + +typedef struct SDL_AssertData +{ + int always_ignore; + unsigned int trigger_count; + const char *condition; + const char *filename; + int linenum; + const char *function; + const struct SDL_AssertData *next; +} SDL_AssertData; + +#if (SDL_ASSERT_LEVEL > 0) + +/* Never call this directly. Use the SDL_assert* macros. */ +extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, + const char *, + const char *, int) +#if defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) +/* this tells Clang's static analysis that we're a custom assert function, + and that the analyzer should assume the condition was always true past this + SDL_assert test. */ + __attribute__((analyzer_noreturn)) +#endif +#endif +; + +/* the do {} while(0) avoids dangling else problems: + if (x) SDL_assert(y); else blah(); + ... without the do/while, the "else" could attach to this macro's "if". + We try to handle just the minimum we need here in a macro...the loop, + the static vars, and break points. The heavy lifting is handled in + SDL_ReportAssertion(), in SDL_assert.c. +*/ +#define SDL_enabled_assert(condition) \ + do { \ + while ( !(condition) ) { \ + static struct SDL_AssertData sdl_assert_data = { \ + 0, 0, #condition, 0, 0, 0, 0 \ + }; \ + const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ + if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ + continue; /* go again. */ \ + } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ + SDL_TriggerBreakpoint(); \ + } \ + break; /* not retrying. */ \ + } \ + } while (SDL_NULL_WHILE_LOOP_CONDITION) + +#endif /* enabled assertions support code */ + +/* Enable various levels of assertions. */ +#if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_disabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 1 /* release settings. */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) +#else +# error Unknown assertion level. +#endif + +/* this assertion is never disabled at any level. */ +#define SDL_assert_always(condition) SDL_enabled_assert(condition) + + +/** + * A callback that fires when an SDL assertion fails. + * + * \param data a pointer to the SDL_AssertData structure corresponding to the + * current assertion + * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler() + * \returns an SDL_AssertState value indicating how to handle the failure. + */ +typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( + const SDL_AssertData* data, void* userdata); + +/** + * Set an application-defined assertion handler. + * + * This function allows an application to show its own assertion UI and/or + * force the response to an assertion failure. If the application doesn't + * provide this, SDL will try to do the right thing, popping up a + * system-specific GUI dialog, and probably minimizing any fullscreen windows. + * + * This callback may fire from any thread, but it runs wrapped in a mutex, so + * it will only fire from one thread at a time. + * + * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! + * + * \param handler the SDL_AssertionHandler function to call when an assertion + * fails or NULL for the default handler + * \param userdata a pointer that is passed to `handler` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAssertionHandler + */ +extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( + SDL_AssertionHandler handler, + void *userdata); + +/** + * Get the default assertion handler. + * + * This returns the function pointer that is called by default when an + * assertion is triggered. This is an internal function provided by SDL, that + * is used for assertions when SDL_SetAssertionHandler() hasn't been used to + * provide a different function. + * + * \returns the default SDL_AssertionHandler that is called when an assert + * triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GetAssertionHandler + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); + +/** + * Get the current assertion handler. + * + * This returns the function pointer that is called when an assertion is + * triggered. This is either the value last passed to + * SDL_SetAssertionHandler(), or if no application-specified function is set, + * is equivalent to calling SDL_GetDefaultAssertionHandler(). + * + * The parameter `puserdata` is a pointer to a void*, which will store the + * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value + * will always be NULL for the default handler. If you don't care about this + * data, it is safe to pass a NULL pointer to this function to ignore it. + * + * \param puserdata pointer which is filled with the "userdata" pointer that + * was passed to SDL_SetAssertionHandler() + * \returns the SDL_AssertionHandler that is called when an assert triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_SetAssertionHandler + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); + +/** + * Get a list of all assertion failures. + * + * This function gets all assertions triggered since the last call to + * SDL_ResetAssertionReport(), or the start of the program. + * + * The proper way to examine this data looks something like this: + * + * ```c + * const SDL_AssertData *item = SDL_GetAssertionReport(); + * while (item) { + * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", + * item->condition, item->function, item->filename, + * item->linenum, item->trigger_count, + * item->always_ignore ? "yes" : "no"); + * item = item->next; + * } + * ``` + * + * \returns a list of all failed assertions or NULL if the list is empty. This + * memory should not be modified or freed by the application. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ResetAssertionReport + */ +extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); + +/** + * Clear the list of all assertion failures. + * + * This function will clear the list of all assertions triggered up to that + * point. Immediately following this call, SDL_GetAssertionReport will return + * no items. In addition, any previously-triggered assertions will be reset to + * a trigger_count of zero, and their always_ignore state will be false. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAssertionReport + */ +extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); + + +/* these had wrong naming conventions until 2.0.4. Please update your app! */ +#define SDL_assert_state SDL_AssertState +#define SDL_assert_data SDL_AssertData + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_assert_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_atomic.h b/thirdparty/SDL/include/SDL/SDL_atomic.h new file mode 100644 index 00000000..f0c05f4b --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_atomic.h @@ -0,0 +1,415 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_atomic.h + * + * Atomic operations. + * + * IMPORTANT: + * If you are not an expert in concurrent lockless programming, you should + * only be using the atomic lock and reference counting functions in this + * file. In all other cases you should be protecting your data structures + * with full mutexes. + * + * The list of "safe" functions to use are: + * SDL_AtomicLock() + * SDL_AtomicUnlock() + * SDL_AtomicIncRef() + * SDL_AtomicDecRef() + * + * Seriously, here be dragons! + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * + * You can find out a little more about lockless programming and the + * subtle issues that can arise here: + * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx + * + * There's also lots of good information here: + * http://www.1024cores.net/home/lock-free-algorithms + * http://preshing.com/ + * + * These operations may or may not actually be implemented using + * processor specific atomic operations. When possible they are + * implemented as true processor specific atomic operations. When that + * is not possible the are implemented using locks that *do* use the + * available atomic operations. + * + * All of the atomic operations that modify memory are full memory barriers. + */ + +#ifndef SDL_atomic_h_ +#define SDL_atomic_h_ + +#include "SDL_stdinc.h" +#include "SDL_platform.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SDL AtomicLock + * + * The atomic locks are efficient spinlocks using CPU instructions, + * but are vulnerable to starvation and can spin forever if a thread + * holding a lock has been terminated. For this reason you should + * minimize the code executed inside an atomic lock and never do + * expensive things like API or system calls while holding them. + * + * The atomic locks are not safe to lock recursively. + * + * Porting Note: + * The spin lock functions and type are required and can not be + * emulated because they are used in the atomic emulation code. + */ +/* @{ */ + +typedef int SDL_SpinLock; + +/** + * Try to lock a spin lock by setting it to a non-zero value. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * \returns SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already + * held. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicUnlock + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); + +/** + * Lock a spin lock by setting it to a non-zero value. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicTryLock + * \sa SDL_AtomicUnlock + */ +extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); + +/** + * Unlock a spin lock by setting it to 0. + * + * Always returns immediately. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicTryLock + */ +extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); + +/* @} *//* SDL AtomicLock */ + + +/** + * The compiler barrier prevents the compiler from reordering + * reads and writes to globally visible variables across the call. + */ +#if defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__) +void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) +#define SDL_CompilerBarrier() _ReadWriteBarrier() +#elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ +#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") +#elif defined(__WATCOMC__) +extern __inline void SDL_CompilerBarrier(void); +#pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; +#else +#define SDL_CompilerBarrier() \ +{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); } +#endif + +/** + * Memory barriers are designed to prevent reads and writes from being + * reordered by the compiler and being seen out of order on multi-core CPUs. + * + * A typical pattern would be for thread A to write some data and a flag, and + * for thread B to read the flag and get the data. In this case you would + * insert a release barrier between writing the data and the flag, + * guaranteeing that the data write completes no later than the flag is + * written, and you would insert an acquire barrier between reading the flag + * and reading the data, to ensure that all the reads associated with the flag + * have completed. + * + * In this pattern you should always see a release barrier paired with an + * acquire barrier and you should gate the data reads/writes with a single + * flag variable. + * + * For more information on these semantics, take a look at the blog post: + * http://preshing.com/20120913/acquire-and-release-semantics + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void); +extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); + +#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") +#elif defined(__GNUC__) && defined(__aarch64__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__GNUC__) && defined(__arm__) +#if 0 /* defined(__LINUX__) || defined(__ANDROID__) */ +/* Information from: + https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19 + + The Linux kernel provides a helper function which provides the right code for a memory barrier, + hard-coded at address 0xffff0fa0 +*/ +typedef void (*SDL_KernelMemoryBarrierFunc)(); +#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#elif 0 /* defined(__QNXNTO__) */ +#include + +#define SDL_MemoryBarrierRelease() __cpu_membarrier() +#define SDL_MemoryBarrierAcquire() __cpu_membarrier() +#else +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_5TE__) +#ifdef __thumb__ +/* The mcr instruction isn't available in thumb mode, use real functions */ +#define SDL_MEMORY_BARRIER_USES_FUNCTION +#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction() +#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction() +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#endif /* __thumb__ */ +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") +#endif /* __LINUX__ || __ANDROID__ */ +#endif /* __GNUC__ && __arm__ */ +#else +#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */ +#include +#define SDL_MemoryBarrierRelease() __machine_rel_barrier() +#define SDL_MemoryBarrierAcquire() __machine_acq_barrier() +#else +/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */ +#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() +#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() +#endif +#endif + +/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */ +#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */ +#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory") +#elif (defined(__powerpc__) || defined(__powerpc64__)) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27"); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + #define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */ +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + #define SDL_CPUPauseInstruction() __yield() +#elif defined(__WATCOMC__) && defined(__386__) + /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */ + extern __inline void SDL_CPUPauseInstruction(void); + #pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h" +#else + #define SDL_CPUPauseInstruction() +#endif + + +/** + * \brief A type representing an atomic integer value. It is a struct + * so people don't accidentally use numeric operations on it. + */ +typedef struct { int value; } SDL_atomic_t; + +/** + * Set an atomic variable to a new value if it is currently an old value. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param oldval the old value + * \param newval the new value + * \returns SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGet + * \sa SDL_AtomicSet + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); + +/** + * Set an atomic variable to a value. + * + * This function also acts as a full memory barrier. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicGet + */ +extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); + +/** + * Get the value of an atomic variable. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable + * \returns the current value of an atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicSet + */ +extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); + +/** + * Add to an atomic variable. + * + * This function also acts as a full memory barrier. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value to add + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicDecRef + * \sa SDL_AtomicIncRef + */ +extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); + +/** + * \brief Increment an atomic variable used as a reference count. + */ +#ifndef SDL_AtomicIncRef +#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) +#endif + +/** + * \brief Decrement an atomic variable used as a reference count. + * + * \return SDL_TRUE if the variable reached zero after decrementing, + * SDL_FALSE otherwise + */ +#ifndef SDL_AtomicDecRef +#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) +#endif + +/** + * Set a pointer to a new value if it is currently an old value. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \param oldval the old pointer value + * \param newval the new pointer value + * \returns SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCAS + * \sa SDL_AtomicGetPtr + * \sa SDL_AtomicSetPtr + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); + +/** + * Set a pointer to a value atomically. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \param v the desired pointer value + * \returns the previous value of the pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGetPtr + */ +extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); + +/** + * Get the value of a pointer atomically. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \returns the current value of a pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicSetPtr + */ +extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#include "close_code.h" + +#endif /* SDL_atomic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_audio.h b/thirdparty/SDL/include/SDL/SDL_audio.h new file mode 100644 index 00000000..c42de3ed --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_audio.h @@ -0,0 +1,1500 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* !!! FIXME: several functions in here need Doxygen comments. */ + +/** + * \file SDL_audio.h + * + * Access to the raw audio mixing buffer for the SDL library. + */ + +#ifndef SDL_audio_h_ +#define SDL_audio_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Audio format flags. + * + * These are what the 16 bits in SDL_AudioFormat currently mean... + * (Unspecified bits are always zero). + * + * \verbatim + ++-----------------------sample is signed if set + || + || ++-----------sample is bigendian if set + || || + || || ++---sample is float if set + || || || + || || || +---sample bit size---+ + || || || | | + 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + \endverbatim + * + * There are macros in SDL 2.0 and later to query these bits. + */ +typedef Uint16 SDL_AudioFormat; + +/** + * \name Audio flags + */ +/* @{ */ + +#define SDL_AUDIO_MASK_BITSIZE (0xFF) +#define SDL_AUDIO_MASK_DATATYPE (1<<8) +#define SDL_AUDIO_MASK_ENDIAN (1<<12) +#define SDL_AUDIO_MASK_SIGNED (1<<15) +#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) +#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) +#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) +#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) +#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) +#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) +#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) + +/** + * \name Audio format flags + * + * Defaults to LSB byte order. + */ +/* @{ */ +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB +/* @} */ + +/** + * \name int32 support + */ +/* @{ */ +#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ +#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ +#define AUDIO_S32 AUDIO_S32LSB +/* @} */ + +/** + * \name float32 support + */ +/* @{ */ +#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ +#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ +#define AUDIO_F32 AUDIO_F32LSB +/* @} */ + +/** + * \name Native audio byte ordering + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_S32SYS AUDIO_S32LSB +#define AUDIO_F32SYS AUDIO_F32LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_S32SYS AUDIO_S32MSB +#define AUDIO_F32SYS AUDIO_F32MSB +#endif +/* @} */ + +/** + * \name Allow change flags + * + * Which audio format changes are allowed when opening a device. + */ +/* @{ */ +#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 +#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 +#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 +#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008 +#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE) +/* @} */ + +/* @} *//* Audio flags */ + +/** + * This function is called when the audio device needs more data. + * + * \param userdata An application-specific parameter saved in + * the SDL_AudioSpec structure + * \param stream A pointer to the audio data buffer. + * \param len The length of that buffer in bytes. + * + * Once the callback returns, the buffer will no longer be valid. + * Stereo samples are stored in a LRLRLR ordering. + * + * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if + * you like. Just open your audio device with a NULL callback. + */ +typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, + int len); + +/** + * The calculated values in this structure are calculated by SDL_OpenAudio(). + * + * For multi-channel audio, the default SDL channel mapping is: + * 2: FL FR (stereo) + * 3: FL FR LFE (2.1 surround) + * 4: FL FR BL BR (quad) + * 5: FL FR LFE BL BR (4.1 surround) + * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) + * 7: FL FR FC LFE BC SL SR (6.1 surround) + * 8: FL FR FC LFE BL BR SL SR (7.1 surround) + */ +typedef struct SDL_AudioSpec +{ + int freq; /**< DSP frequency -- samples per second */ + SDL_AudioFormat format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ + void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ +} SDL_AudioSpec; + + +struct SDL_AudioCVT; +typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, + SDL_AudioFormat format); + +/** + * \brief Upper limit of filters in SDL_AudioCVT + * + * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is + * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers, + * one of which is the terminating NULL pointer. + */ +#define SDL_AUDIOCVT_MAX_FILTERS 9 + +/** + * \struct SDL_AudioCVT + * \brief A structure to hold a set of audio conversion filters and buffers. + * + * Note that various parts of the conversion pipeline can take advantage + * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require + * you to pass it aligned data, but can possibly run much faster if you + * set both its (buf) field to a pointer that is aligned to 16 bytes, and its + * (len) field to something that's a multiple of 16, if possible. + */ +#if defined(__GNUC__) && !defined(__CHERI_PURE_CAPABILITY__) +/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't + pad it out to 88 bytes to guarantee ABI compatibility between compilers. + This is not a concern on CHERI architectures, where pointers must be stored + at aligned locations otherwise they will become invalid, and thus structs + containing pointers cannot be packed without giving a warning or error. + vvv + The next time we rev the ABI, make sure to size the ints and add padding. +*/ +#define SDL_AUDIOCVT_PACKED __attribute__((packed)) +#else +#define SDL_AUDIOCVT_PACKED +#endif +/* */ +typedef struct SDL_AudioCVT +{ + int needed; /**< Set to 1 if conversion possible */ + SDL_AudioFormat src_format; /**< Source audio format */ + SDL_AudioFormat dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */ + int filter_index; /**< Current audio conversion function */ +} SDL_AUDIOCVT_PACKED SDL_AudioCVT; + + +/* Function prototypes */ + +/** + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + */ +/* @{ */ + +/** + * Use this function to get the number of built-in audio drivers. + * + * This function returns a hardcoded number. This never returns a negative + * value; if there are no drivers compiled into this build of SDL, this + * function returns zero. The presence of a driver in this list does not mean + * it will function, it just means SDL is capable of interacting with that + * interface. For example, a build of SDL might have esound support, but if + * there's no esound server available, SDL's esound driver would fail if used. + * + * By default, SDL tries all drivers, in its preferred order, until one is + * found to be usable. + * + * \returns the number of built-in audio drivers. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); + +/** + * Use this function to get the name of a built in audio driver. + * + * The list of audio drivers is given in the order that they are normally + * initialized by default; the drivers that seem more reasonable to choose + * first (as far as the SDL developers believe) are earlier in the list. + * + * The names of drivers are all simple, low-ASCII identifiers, like "alsa", + * "coreaudio" or "xaudio2". These never have Unicode characters, and are not + * meant to be proper names. + * + * \param index the index of the audio driver; the value ranges from 0 to + * SDL_GetNumAudioDrivers() - 1 + * \returns the name of the audio driver at the requested index, or NULL if an + * invalid index was specified. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); +/* @} */ + +/** + * \name Initialization and cleanup + * + * \internal These functions are used internally, and should not be used unless + * you have a specific need to specify the audio driver you want to + * use. You should normally use SDL_Init() or SDL_InitSubSystem(). + */ +/* @{ */ + +/** + * Use this function to initialize a particular audio driver. + * + * This function is used internally, and should not be used unless you have a + * specific need to designate the audio driver you want to use. You should + * normally use SDL_Init() or SDL_InitSubSystem(). + * + * \param driver_name the name of the desired audio driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioQuit + */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); + +/** + * Use this function to shut down audio if you initialized it with + * SDL_AudioInit(). + * + * This function is used internally, and should not be used unless you have a + * specific need to specify the audio driver you want to use. You should + * normally use SDL_Quit() or SDL_QuitSubSystem(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); +/* @} */ + +/** + * Get the name of the current audio driver. + * + * The returned string points to internal static memory and thus never becomes + * invalid, even if you quit the audio subsystem and initialize a new driver + * (although such a case would return a different static string from another + * call to this function, of course). As such, you should not modify or free + * the returned string. + * + * \returns the name of the current audio driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); + +/** + * This function is a legacy means of opening the audio device. + * + * This function remains for compatibility with SDL 1.2, but also because it's + * slightly easier to use than the new functions in SDL 2.0. The new, more + * powerful, and preferred way to do this is SDL_OpenAudioDevice(). + * + * This function is roughly equivalent to: + * + * ```c + * SDL_OpenAudioDevice(NULL, 0, desired, obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + * ``` + * + * With two notable exceptions: + * + * - If `obtained` is NULL, we use `desired` (and allow no changes), which + * means desired will be modified to have the correct values for silence, + * etc, and SDL will convert any differences between your app's specific + * request and the hardware behind the scenes. + * - The return value is always success or failure, and not a device ID, which + * means you can only have one device open at a time with this function. + * + * \param desired an SDL_AudioSpec structure representing the desired output + * format. Please refer to the SDL_OpenAudioDevice + * documentation for details on how to prepare this structure. + * \param obtained an SDL_AudioSpec structure filled in with the actual + * parameters, or NULL. + * \returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by `obtained`. + * + * If `obtained` is NULL, the audio data passed to the callback + * function will be guaranteed to be in the requested format, and + * will be automatically converted to the actual hardware audio + * format if necessary. If `obtained` is NULL, `desired` will have + * fields modified. + * + * This function returns a negative error code on failure to open the + * audio device or failure to set up the audio thread; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudio + * \sa SDL_LockAudio + * \sa SDL_PauseAudio + * \sa SDL_UnlockAudio + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, + SDL_AudioSpec * obtained); + +/** + * SDL Audio Device IDs. + * + * A successful call to SDL_OpenAudio() is always device id 1, and legacy + * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls + * always returns devices >= 2 on success. The legacy calls are good both + * for backwards compatibility and when you don't care about multiple, + * specific, or capture devices. + */ +typedef Uint32 SDL_AudioDeviceID; + +/** + * Get the number of built-in audio devices. + * + * This function is only valid after successfully initializing the audio + * subsystem. + * + * Note that audio capture support is not implemented as of SDL 2.0.4, so the + * `iscapture` parameter is for future expansion and should always be zero for + * now. + * + * This function will return -1 if an explicit list of devices can't be + * determined. Returning -1 is not an error. For example, if SDL is set up to + * talk to a remote audio server, it can't list every one available on the + * Internet, but it will still allow a specific host to be specified in + * SDL_OpenAudioDevice(). + * + * In many common cases, when this function returns a value <= 0, it can still + * successfully open the default device (NULL for first argument of + * SDL_OpenAudioDevice()). + * + * This function may trigger a complete redetect of available hardware. It + * should not be called for each iteration of a loop, but rather once at the + * start of a loop: + * + * ```c + * // Don't do this: + * for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) + * + * // do this instead: + * const int count = SDL_GetNumAudioDevices(0); + * for (int i = 0; i < count; ++i) { do_something_here(); } + * ``` + * + * \param iscapture zero to request playback devices, non-zero to request + * recording devices + * \returns the number of available devices exposed by the current driver or + * -1 if an explicit list of devices can't be determined. A return + * value of -1 does not necessarily mean an error condition. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceName + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); + +/** + * Get the human-readable name of a specific audio device. + * + * This function is only valid after successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * The string returned by this function is UTF-8 encoded, read-only, and + * managed internally. You are not to free it. If you need to keep the string + * for any length of time, you should make your own copy of it, as it will be + * invalid next time any of several other SDL functions are called. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \returns the name of the audio device at the requested index, or NULL on + * error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDevices + * \sa SDL_GetDefaultAudioInfo + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, + int iscapture); + +/** + * Get the preferred audio format of a specific audio device. + * + * This function is only valid after a successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * `spec` will be filled with the sample rate, sample format, and channel + * count. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \param spec The SDL_AudioSpec to be initialized by this function. + * \returns 0 on success, nonzero on error + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetNumAudioDevices + * \sa SDL_GetDefaultAudioInfo + */ +extern DECLSPEC int SDLCALL SDL_GetAudioDeviceSpec(int index, + int iscapture, + SDL_AudioSpec *spec); + + +/** + * Get the name and preferred format of the default audio device. + * + * Some (but not all!) platforms have an isolated mechanism to get information + * about the "default" device. This can actually be a completely different + * device that's not in the list you get from SDL_GetAudioDeviceSpec(). It can + * even be a network address! (This is discussed in SDL_OpenAudioDevice().) + * + * As a result, this call is not guaranteed to be performant, as it can query + * the sound server directly every time, unlike the other query functions. You + * should call this function sparingly! + * + * `spec` will be filled with the sample rate, sample format, and channel + * count, if a default device exists on the system. If `name` is provided, + * will be filled with either a dynamically-allocated UTF-8 string or NULL. + * + * \param name A pointer to be filled with the name of the default device (can + * be NULL). Please call SDL_free() when you are done with this + * pointer! + * \param spec The SDL_AudioSpec to be initialized by this function. + * \param iscapture non-zero to query the default recording device, zero to + * query the default output device. + * \returns 0 on success, nonzero on error + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetAudioDeviceName + * \sa SDL_GetAudioDeviceSpec + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, + SDL_AudioSpec *spec, + int iscapture); + + +/** + * Open a specific audio device. + * + * SDL_OpenAudio(), unlike this function, always acts on device ID 1. As such, + * this function will never return a 1 so as not to conflict with the legacy + * function. + * + * Please note that SDL 2.0 before 2.0.5 did not support recording; as such, + * this function would fail if `iscapture` was not zero. Starting with SDL + * 2.0.5, recording is implemented and this value can be non-zero. + * + * Passing in a `device` name of NULL requests the most reasonable default + * (and is equivalent to what SDL_OpenAudio() does to choose a device). The + * `device` name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but + * some drivers allow arbitrary and driver-specific strings, such as a + * hostname/IP address for a remote audio server, or a filename in the + * diskaudio driver. + * + * An opened audio device starts out paused, and should be enabled for playing + * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio + * callback function to be called. Since the audio driver may modify the + * requested size of the audio buffer, you should allocate any local mixing + * buffers after you open the audio device. + * + * The audio callback runs in a separate thread in most cases; you can prevent + * race conditions between your callback and other threads without fully + * pausing playback with SDL_LockAudioDevice(). For more information about the + * callback, see SDL_AudioSpec. + * + * Managing the audio spec via 'desired' and 'obtained': + * + * When filling in the desired audio spec structure: + * + * - `desired->freq` should be the frequency in sample-frames-per-second (Hz). + * - `desired->format` should be the audio format (`AUDIO_S16SYS`, etc). + * - `desired->samples` is the desired size of the audio buffer, in _sample + * frames_ (with stereo output, two samples--left and right--would make a + * single sample frame). This number should be a power of two, and may be + * adjusted by the audio driver to a value more suitable for the hardware. + * Good values seem to range between 512 and 8096 inclusive, depending on + * the application and CPU speed. Smaller values reduce latency, but can + * lead to underflow if the application is doing heavy processing and cannot + * fill the audio buffer in time. Note that the number of sample frames is + * directly related to time by the following formula: `ms = + * (sampleframes*1000)/freq` + * - `desired->size` is the size in _bytes_ of the audio buffer, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->silence` is the value used to set the buffer to silence, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->callback` should be set to a function that will be called when + * the audio device is ready for more data. It is passed a pointer to the + * audio buffer, and the length in bytes of the audio buffer. This function + * usually runs in a separate thread, and so you should protect data + * structures that it accesses by calling SDL_LockAudioDevice() and + * SDL_UnlockAudioDevice() in your code. Alternately, you may pass a NULL + * pointer here, and call SDL_QueueAudio() with some frequency, to queue + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). + * - `desired->userdata` is passed as the first parameter to your callback + * function. If you passed a NULL callback, this value is ignored. + * + * `allowed_changes` can have the following flags OR'd together: + * + * - `SDL_AUDIO_ALLOW_FREQUENCY_CHANGE` + * - `SDL_AUDIO_ALLOW_FORMAT_CHANGE` + * - `SDL_AUDIO_ALLOW_CHANNELS_CHANGE` + * - `SDL_AUDIO_ALLOW_SAMPLES_CHANGE` + * - `SDL_AUDIO_ALLOW_ANY_CHANGE` + * + * These flags specify how SDL should behave when a device cannot offer a + * specific feature. If the application requests a feature that the hardware + * doesn't offer, SDL will always try to get the closest equivalent. + * + * For example, if you ask for float32 audio format, but the sound card only + * supports int16, SDL will set the hardware to int16. If you had set + * SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL will change the format in the `obtained` + * structure. If that flag was *not* set, SDL will prepare to convert your + * callback's float32 audio to int16 before feeding it to the hardware and + * will keep the originally requested format in the `obtained` structure. + * + * The resulting audio specs, varying depending on hardware and on what + * changes were allowed, will then be written back to `obtained`. + * + * If your application can only handle one specific data format, pass a zero + * for `allowed_changes` and let SDL transparently handle any differences. + * + * \param device a UTF-8 string reported by SDL_GetAudioDeviceName() or a + * driver-specific name as appropriate. NULL requests the most + * reasonable default device. + * \param iscapture non-zero to specify a device should be opened for + * recording, not playback + * \param desired an SDL_AudioSpec structure representing the desired output + * format; see SDL_OpenAudio() for more information + * \param obtained an SDL_AudioSpec structure filled in with the actual output + * format; see SDL_OpenAudio() for more information + * \param allowed_changes 0, or one or more flags OR'd together + * \returns a valid device ID that is > 0 on success or 0 on failure; call + * SDL_GetError() for more information. + * + * For compatibility with SDL 1.2, this will never return 1, since + * SDL reserves that ID for the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudioDevice + * \sa SDL_GetAudioDeviceName + * \sa SDL_LockAudioDevice + * \sa SDL_OpenAudio + * \sa SDL_PauseAudioDevice + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice( + const char *device, + int iscapture, + const SDL_AudioSpec *desired, + SDL_AudioSpec *obtained, + int allowed_changes); + + + +/** + * \name Audio state + * + * Get the current audio state. + */ +/* @{ */ +typedef enum +{ + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_AudioStatus; + +/** + * This function is a legacy means of querying the audio device. + * + * New programs might want to use SDL_GetAudioDeviceStatus() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_GetAudioDeviceStatus(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \returns the SDL_AudioStatus of the audio device opened by SDL_OpenAudio(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceStatus + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); + +/** + * Use this function to get the current audio state of an audio device. + * + * \param dev the ID of an audio device previously opened with + * SDL_OpenAudioDevice() + * \returns the SDL_AudioStatus of the specified audio device. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); +/* @} *//* Audio State */ + +/** + * \name Pause audio functions + * + * These functions pause and unpause the audio callback processing. + * They should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +/* @{ */ + +/** + * This function is a legacy means of pausing the audio device. + * + * New programs might want to use SDL_PauseAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_PauseAudioDevice(1, pause_on); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioStatus + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); + +/** + * Use this function to pause and unpause audio playback on a specified + * device. + * + * This function pauses and unpauses the audio callback processing for a given + * device. Newly-opened audio devices start in the paused state, so you must + * call this function with **pause_on**=0 after opening the specified audio + * device to start playing sound. This allows you to safely initialize data + * for your callback function after opening the audio device. Silence will be + * written to the audio device while paused, and the audio callback is + * guaranteed to not be called. Pausing one device does not prevent other + * unpaused devices from running their callbacks. + * + * Pausing state does not stack; even if you pause a device several times, a + * single unpause will start the device playing again, and vice versa. This is + * different from how SDL_LockAudioDevice() works. + * + * If you just need to protect a few variables from race conditions vs your + * callback, you shouldn't pause the audio device, as it will lead to dropouts + * in the audio playback. Instead, you should use SDL_LockAudioDevice(). + * + * \param dev a device opened by SDL_OpenAudioDevice() + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, + int pause_on); +/* @} *//* Pause audio functions */ + +/** + * Load the audio data of a WAVE file into memory. + * + * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to + * be valid pointers. The entire data portion of the file is then loaded into + * memory and decoded if necessary. + * + * If `freesrc` is non-zero, the data source gets automatically closed and + * freed before the function returns. + * + * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and + * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and + * A-law and mu-law (8 bits). Other formats are currently unsupported and + * cause an error. + * + * If this function succeeds, the pointer returned by it is equal to `spec` + * and the pointer to the audio data allocated by the function is written to + * `audio_buf` and its length in bytes to `audio_len`. The SDL_AudioSpec + * members `freq`, `channels`, and `format` are set to the values of the audio + * data in the buffer. The `samples` member is set to a sane default and all + * others are set to zero. + * + * It's necessary to use SDL_FreeWAV() to free the audio data returned in + * `audio_buf` when it is no longer used. + * + * Because of the underspecification of the .WAV format, there are many + * problematic files in the wild that cause issues with strict decoders. To + * provide compatibility with these files, this decoder is lenient in regards + * to the truncation of the file, the fact chunk, and the size of the RIFF + * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`, + * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to + * tune the behavior of the loading process. + * + * Any file that is invalid (due to truncation, corruption, or wrong values in + * the headers), too big, or unsupported causes an error. Additionally, any + * critical I/O error from the data source will terminate the loading process + * with an error. The function returns NULL on error and in all cases (with + * the exception of `src` being NULL), an appropriate error message will be + * set. + * + * It is required that the data source supports seeking. + * + * Example: + * + * ```c + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, &spec, &buf, &len); + * ``` + * + * Note that the SDL_LoadWAV macro does this same thing for you, but in a less + * messy way: + * + * ```c + * SDL_LoadWAV("sample.wav", &spec, &buf, &len); + * ``` + * + * \param src The data source for the WAVE data + * \param freesrc If non-zero, SDL will _always_ free the data source + * \param spec An SDL_AudioSpec that will be filled in with the wave file's + * format details + * \param audio_buf A pointer filled with the audio data, allocated by the + * function. + * \param audio_len A pointer filled with the length of the audio data buffer + * in bytes + * \returns This function, if successfully called, returns `spec`, which will + * be filled with the audio data format of the wave source data. + * `audio_buf` will be filled with a pointer to an allocated buffer + * containing the audio data, and `audio_len` is filled with the + * length of that audio buffer in bytes. + * + * This function returns NULL if the .WAV file cannot be opened, uses + * an unknown data format, or is corrupt; call SDL_GetError() for + * more information. + * + * When the application is done with the data returned in + * `audio_buf`, it should call SDL_FreeWAV() to dispose of it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeWAV + * \sa SDL_LoadWAV + */ +extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, + int freesrc, + SDL_AudioSpec * spec, + Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file. + * Compatibility convenience function. + */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/** + * Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW(). + * + * After a WAVE file has been opened with SDL_LoadWAV() or SDL_LoadWAV_RW() + * its data can eventually be freed with SDL_FreeWAV(). It is safe to call + * this function with a NULL pointer. + * + * \param audio_buf a pointer to the buffer created by SDL_LoadWAV() or + * SDL_LoadWAV_RW() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadWAV + * \sa SDL_LoadWAV_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); + +/** + * Initialize an SDL_AudioCVT structure for conversion. + * + * Before an SDL_AudioCVT structure can be used to convert audio data it must + * be initialized with source and destination information. + * + * This function will zero out every field of the SDL_AudioCVT, so it must be + * called before the application fills in the final buffer information. + * + * Once this function has returned successfully, and reported that a + * conversion is necessary, the application fills in the rest of the fields in + * SDL_AudioCVT, now that it knows how large a buffer it needs to allocate, + * and then can call SDL_ConvertAudio() to complete the conversion. + * + * \param cvt an SDL_AudioCVT structure filled in with audio conversion + * information + * \param src_format the source format of the audio data; for more info see + * SDL_AudioFormat + * \param src_channels the number of channels in the source + * \param src_rate the frequency (sample-frames-per-second) of the source + * \param dst_format the destination format of the audio data; for more info + * see SDL_AudioFormat + * \param dst_channels the number of channels in the destination + * \param dst_rate the frequency (sample-frames-per-second) of the destination + * \returns 1 if the audio filter is prepared, 0 if no conversion is needed, + * or a negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ConvertAudio + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, + SDL_AudioFormat src_format, + Uint8 src_channels, + int src_rate, + SDL_AudioFormat dst_format, + Uint8 dst_channels, + int dst_rate); + +/** + * Convert audio data to a desired audio format. + * + * This function does the actual audio data conversion, after the application + * has called SDL_BuildAudioCVT() to prepare the conversion information and + * then filled in the buffer details. + * + * Once the application has initialized the `cvt` structure using + * SDL_BuildAudioCVT(), allocated an audio buffer and filled it with audio + * data in the source format, this function will convert the buffer, in-place, + * to the desired format. + * + * The data conversion may go through several passes; any given pass may + * possibly temporarily increase the size of the data. For example, SDL might + * expand 16-bit data to 32 bits before resampling to a lower frequency, + * shrinking the data size after having grown it briefly. Since the supplied + * buffer will be both the source and destination, converting as necessary + * in-place, the application must allocate a buffer that will fully contain + * the data during its largest conversion pass. After SDL_BuildAudioCVT() + * returns, the application should set the `cvt->len` field to the size, in + * bytes, of the source data, and allocate a buffer that is `cvt->len * + * cvt->len_mult` bytes long for the `buf` field. + * + * The source data should be copied into this buffer before the call to + * SDL_ConvertAudio(). Upon successful return, this buffer will contain the + * converted audio, and `cvt->len_cvt` will be the size of the converted data, + * in bytes. Any bytes in the buffer past `cvt->len_cvt` are undefined once + * this function returns. + * + * \param cvt an SDL_AudioCVT structure that was previously set up by + * SDL_BuildAudioCVT(). + * \returns 0 if the conversion was completed successfully or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BuildAudioCVT + */ +extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); + +/* SDL_AudioStream is a new audio conversion interface. + The benefits vs SDL_AudioCVT: + - it can handle resampling data in chunks without generating + artifacts, when it doesn't have the complete buffer available. + - it can handle incoming data in any variable size. + - You push data as you have it, and pull it when you need it + */ +/* this is opaque to the outside world. */ +struct _SDL_AudioStream; +typedef struct _SDL_AudioStream SDL_AudioStream; + +/** + * Create a new audio stream. + * + * \param src_format The format of the source audio + * \param src_channels The number of channels of the source audio + * \param src_rate The sampling rate of the source audio + * \param dst_format The format of the desired audio output + * \param dst_channels The number of channels of the desired audio output + * \param dst_rate The sampling rate of the desired audio output + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioFormat src_format, + const Uint8 src_channels, + const int src_rate, + const SDL_AudioFormat dst_format, + const Uint8 dst_channels, + const int dst_rate); + +/** + * Add data to be converted/resampled to the stream. + * + * \param stream The stream the audio data is being added to + * \param buf A pointer to the audio data to add + * \param len The number of bytes to write to the stream + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len); + +/** + * Get converted/resampled data from the stream + * + * \param stream The stream the audio is being requested from + * \param buf A buffer to fill with audio data + * \param len The maximum number of bytes to fill + * \returns the number of bytes read from the stream, or -1 on error + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); + +/** + * Get the number of converted/resampled bytes available. + * + * The stream may be buffering data behind the scenes until it has enough to + * resample correctly, so this number might be lower than what you expect, or + * even be zero. Add more data or flush the stream if you need the data now. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); + +/** + * Tell the stream that you're done sending data, and anything being buffered + * should be converted/resampled and made available immediately. + * + * It is legal to add more data to a stream after flushing, but there will be + * audio gaps in the output. Generally this is intended to signal the end of + * input, so the complete output becomes available. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); + +/** + * Clear any pending data in the stream without converting it + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); + +/** + * Free an audio stream + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + */ +extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); + +#define SDL_MIX_MAXVOLUME 128 + +/** + * This function is a legacy means of mixing audio. + * + * This function is equivalent to calling... + * + * ```c + * SDL_MixAudioFormat(dst, src, format, len, volume); + * ``` + * + * ...where `format` is the obtained format of the audio device from the + * legacy SDL_OpenAudio() function. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MixAudioFormat + */ +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, + Uint32 len, int volume); + +/** + * Mix audio data in a specified format. + * + * This takes an audio buffer `src` of `len` bytes of `format` data and mixes + * it into `dst`, performing addition, volume adjustment, and overflow + * clipping. The buffer pointed to by `dst` must also be `len` bytes of + * `format` data. + * + * This is provided for convenience -- you can mix your own audio data. + * + * Do not use this function for mixing together more than two streams of + * sample data. The output from repeated application of this function may be + * distorted by clipping, because there is no accumulator with greater range + * than the input (not to mention this being an inefficient way of doing it). + * + * It is a common misconception that this function is required to write audio + * data to an output stream in an audio callback. While you can do that, + * SDL_MixAudioFormat() is really only needed when you're mixing a single + * audio stream with a volume adjustment. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param format the SDL_AudioFormat structure representing the desired audio + * format + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, + const Uint8 * src, + SDL_AudioFormat format, + Uint32 len, int volume); + +/** + * Queue more audio on non-callback devices. + * + * If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. SDL_QueueAudio() will return + * -1 to signify an error if you use it with capture devices. + * + * SDL offers two ways to feed audio to the device: you can either supply a + * callback that SDL triggers with some frequency to obtain more audio (pull + * method), or you can supply no callback, and then SDL will expect you to + * supply data at regular intervals (push method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Queued data will drain to the device as + * necessary without further intervention from you. If the device needs audio + * but there is not enough queued, it will play silence to make up the + * difference. This means you will have skips in your audio playback if you + * aren't routinely queueing sufficient data. + * + * This function copies the supplied data, so you are safe to free it when the + * function returns. This function is thread-safe, but queueing to the same + * device from two threads at once does not promise which buffer will be + * queued first. + * + * You may not queue audio on a device that is using an application-supplied + * callback; doing so returns an error. You have to use the audio callback or + * queue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * Note that SDL2 does not support planar audio. You will need to resample + * from planar audio formats into a non-planar one (see SDL_AudioFormat) + * before queuing audio. + * + * \param dev the device ID to which we will queue audio + * \param data the data to queue to the device for later playback + * \param len the number of bytes (not samples!) to which `data` points + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); + +/** + * Dequeue more audio on non-callback devices. + * + * If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. SDL_DequeueAudio() will always + * return 0 if you use it with playback devices. + * + * SDL offers two ways to retrieve audio from a capture device: you can either + * supply a callback that SDL triggers with some frequency as the device + * records more audio data, (push method), or you can supply no callback, and + * then SDL will expect you to retrieve data at regular intervals (pull + * method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting to + * not need captured audio for some length of time, use SDL_PauseAudioDevice() + * to stop the capture device from queueing more data. This can be useful + * during, say, level loading times. When unpaused, capture devices will start + * queueing data from that point, having flushed any capturable data available + * while paused. + * + * This function is thread-safe, but dequeueing from the same device from two + * threads at once does not promise which thread will dequeue data first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before dequeueing; SDL + * handles locking internally for this function. + * + * \param dev the device ID from which we will dequeue audio + * \param data a pointer into where audio data should be copied + * \param len the number of bytes (not samples!) to which (data) points + * \returns the number of bytes dequeued, which could be less than requested; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + +/** + * Get the number of bytes of still-queued audio. + * + * For playback devices: this is the number of bytes that have been queued for + * playback with SDL_QueueAudio(), but have not yet been sent to the hardware. + * + * Once we've sent it to the hardware, this function can not decide the exact + * byte boundary of what has been played. It's possible that we just gave the + * hardware several kilobytes right before you called this function, but it + * hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices, this is the number of bytes that have been captured by + * the device and are waiting for you to dequeue. This number may grow at any + * time, so this only informs of the lower-bound of available data. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before querying; SDL + * handles locking internally for this function. + * + * \param dev the device ID of which we will query queued audio size + * \returns the number of bytes (not samples!) of queued audio. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); + +/** + * Drop any queued audio data waiting to be sent to the hardware. + * + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * output devices, the hardware will start playing silence if more audio isn't + * queued. For capture devices, the hardware will start filling the empty + * queue with new data if the capture device isn't paused. + * + * This will not prevent playback of queued audio that's already been sent to + * the hardware, as we can not undo that, so expect there to be some fraction + * of a second of audio that might still be heard. This can be useful if you + * want to, say, drop any pending music or any unprocessed microphone input + * during a level change in your game. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before clearing the + * queue; SDL handles locking internally for this function. + * + * This function always succeeds and thus returns void. + * + * \param dev the device ID of which to clear the audio queue + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); + + +/** + * \name Audio lock functions + * + * The lock manipulated by these functions protects the callback function. + * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that + * the callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +/* @{ */ + +/** + * This function is a legacy means of locking the audio device. + * + * New programs might want to use SDL_LockAudioDevice() instead. This function + * is equivalent to calling... + * + * ```c + * SDL_LockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + * \sa SDL_UnlockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); + +/** + * Use this function to lock out the audio callback function for a specified + * device. + * + * The lock manipulated by these functions protects the audio callback + * function specified in SDL_OpenAudioDevice(). During a + * SDL_LockAudioDevice()/SDL_UnlockAudioDevice() pair, you can be guaranteed + * that the callback function for that device is not running, even if the + * device is not paused. While a device is locked, any other unpaused, + * unlocked devices may still run their callbacks. + * + * Calling this function from inside your audio callback is unnecessary. SDL + * obtains this lock before calling your function, and releases it when the + * function returns. + * + * You should not hold the lock longer than absolutely necessary. If you hold + * it too long, you'll experience dropouts in your audio playback. Ideally, + * your application locks the device, sets a few variables and unlocks again. + * Do not do heavy work while holding the lock for a device. + * + * It is safe to lock the audio device multiple times, as long as you unlock + * it an equivalent number of times. The callback will not run until the + * device has been unlocked completely in this way. If your application fails + * to unlock the device appropriately, your callback will never run, you might + * hear repeating bursts of audio, and SDL_CloseAudioDevice() will probably + * deadlock. + * + * Internally, the audio device lock is a mutex; if you lock from two threads + * at once, not only will you block the audio callback, you'll block the other + * thread. + * + * \param dev the ID of the device to be locked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); + +/** + * This function is a legacy means of unlocking the audio device. + * + * New programs might want to use SDL_UnlockAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_UnlockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); + +/** + * Use this function to unlock the audio callback function for a specified + * device. + * + * This function should be paired with a previous SDL_LockAudioDevice() call. + * + * \param dev the ID of the device to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); +/* @} *//* Audio lock functions */ + +/** + * This function is a legacy means of closing the audio device. + * + * This function is equivalent to calling... + * + * ```c + * SDL_CloseAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudio + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); + +/** + * Use this function to shut down audio processing and close the audio device. + * + * The application should close open audio devices once they are no longer + * needed. Calling this function will wait until the device's audio callback + * is not running, release the audio hardware and then clean up internal + * state. No further audio will play from this device once this function + * returns. + * + * This function may block briefly while pending audio data is played by the + * hardware, so that applications don't drop the last buffer of data they + * supplied. + * + * The device ID is invalid as soon as the device is closed, and is eligible + * for reuse in a new SDL_OpenAudioDevice() call immediately. + * + * \param dev an audio device previously opened with SDL_OpenAudioDevice() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_audio_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_bits.h b/thirdparty/SDL/include/SDL/SDL_bits.h new file mode 100644 index 00000000..22cb8531 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_bits.h @@ -0,0 +1,126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_bits.h + * + * Functions for fiddling with bits and bitmasks. + */ + +#ifndef SDL_bits_h_ +#define SDL_bits_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_bits.h + */ + +/** + * Get the index of the most significant bit. Result is undefined when called + * with 0. This operation can also be stated as "count leading zeroes" and + * "log base 2". + * + * \return the index of the most significant bit, or -1 if the value is 0. + */ +#if defined(__WATCOMC__) && defined(__386__) +extern __inline int _SDL_bsr_watcom(Uint32); +#pragma aux _SDL_bsr_watcom = \ + "bsr eax, eax" \ + parm [eax] nomemory \ + value [eax] \ + modify exact [eax] nomemory; +#endif + +SDL_FORCE_INLINE int +SDL_MostSignificantBitIndex32(Uint32 x) +{ +#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + /* Count Leading Zeroes builtin in GCC. + * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html + */ + if (x == 0) { + return -1; + } + return 31 - __builtin_clz(x); +#elif defined(__WATCOMC__) && defined(__386__) + if (x == 0) { + return -1; + } + return _SDL_bsr_watcom(x); +#elif defined(_MSC_VER) + unsigned long index; + if (_BitScanReverse(&index, x)) { + return index; + } + return -1; +#else + /* Based off of Bit Twiddling Hacks by Sean Eron Anderson + * , released in the public domain. + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + */ + const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; + const int S[] = {1, 2, 4, 8, 16}; + + int msbIndex = 0; + int i; + + if (x == 0) { + return -1; + } + + for (i = 4; i >= 0; i--) + { + if (x & b[i]) + { + x >>= S[i]; + msbIndex |= S[i]; + } + } + + return msbIndex; +#endif +} + +SDL_FORCE_INLINE SDL_bool +SDL_HasExactlyOneBitSet32(Uint32 x) +{ + if (x && !(x & (x - 1))) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_bits_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_blendmode.h b/thirdparty/SDL/include/SDL/SDL_blendmode.h new file mode 100644 index 00000000..08c9f9dd --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_blendmode.h @@ -0,0 +1,198 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_blendmode.h + * + * Header file declaring the SDL_BlendMode enumeration + */ + +#ifndef SDL_blendmode_h_ +#define SDL_blendmode_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The blend mode used in SDL_RenderCopy() and drawing operations. + */ +typedef enum +{ + SDL_BLENDMODE_NONE = 0x00000000, /**< no blending + dstRGBA = srcRGBA */ + SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) */ + SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending + dstRGB = (srcRGB * srcA) + dstRGB + dstA = dstA */ + SDL_BLENDMODE_MOD = 0x00000004, /**< color modulate + dstRGB = srcRGB * dstRGB + dstA = dstA */ + SDL_BLENDMODE_MUL = 0x00000008, /**< color multiply + dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) + dstA = (srcA * dstA) + (dstA * (1-srcA)) */ + SDL_BLENDMODE_INVALID = 0x7FFFFFFF + + /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ + +} SDL_BlendMode; + +/** + * \brief The blend operation used when combining source and destination pixel components + */ +typedef enum +{ + SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ + SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */ + SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */ +} SDL_BlendOperation; + +/** + * \brief The normalized factor used to multiply pixel components + */ +typedef enum +{ + SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */ + SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */ + SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */ + SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */ + SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ + SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ +} SDL_BlendFactor; + +/** + * Compose a custom blend mode for renderers. + * + * The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept + * the SDL_BlendMode returned by this function if the renderer supports it. + * + * A blend mode controls how the pixels from a drawing operation (source) get + * combined with the pixels from the render target (destination). First, the + * components of the source and destination pixels get multiplied with their + * blend factors. Then, the blend operation takes the two products and + * calculates the result that will get stored in the render target. + * + * Expressed in pseudocode, it would look like this: + * + * ```c + * dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); + * dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); + * ``` + * + * Where the functions `colorOperation(src, dst)` and `alphaOperation(src, + * dst)` can return one of the following: + * + * - `src + dst` + * - `src - dst` + * - `dst - src` + * - `min(src, dst)` + * - `max(src, dst)` + * + * The red, green, and blue components are always multiplied with the first, + * second, and third components of the SDL_BlendFactor, respectively. The + * fourth component is not used. + * + * The alpha component is always multiplied with the fourth component of the + * SDL_BlendFactor. The other components are not used in the alpha + * calculation. + * + * Support for these blend modes varies for each renderer. To check if a + * specific SDL_BlendMode is supported, create a renderer and pass it to + * either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will + * return with an error if the blend mode is not supported. + * + * This list describes the support of custom blend modes for each renderer in + * SDL 2.0.6. All renderers support the four blend modes listed in the + * SDL_BlendMode enumeration. + * + * - **direct3d**: Supports all operations with all factors. However, some + * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and + * `SDL_BLENDOPERATION_MAXIMUM`. + * - **direct3d11**: Same as Direct3D 9. + * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL + * 2.0.6. + * - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. Color and alpha factors need to be the same. OpenGL ES 1 + * implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` + * and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha + * operations being different from each other. May support color and alpha + * factors being different from each other. + * - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, + * `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` + * operations with all factors. + * - **psp**: No custom blend mode support. + * - **software**: No custom blend mode support. + * + * Some renderers do not provide an alpha component for the default render + * target. The `SDL_BLENDFACTOR_DST_ALPHA` and + * `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this + * case. + * + * \param srcColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the source pixels + * \param dstColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the destination pixels + * \param colorOperation the SDL_BlendOperation used to combine the red, + * green, and blue components of the source and + * destination pixels + * \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the source pixels + * \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the destination pixels + * \param alphaOperation the SDL_BlendOperation used to combine the alpha + * component of the source and destination pixels + * \returns an SDL_BlendMode that represents the chosen factors and + * operations. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_SetTextureBlendMode + * \sa SDL_GetTextureBlendMode + */ +extern DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, + SDL_BlendFactor dstColorFactor, + SDL_BlendOperation colorOperation, + SDL_BlendFactor srcAlphaFactor, + SDL_BlendFactor dstAlphaFactor, + SDL_BlendOperation alphaOperation); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_blendmode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_clipboard.h b/thirdparty/SDL/include/SDL/SDL_clipboard.h new file mode 100644 index 00000000..93513630 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_clipboard.h @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef SDL_clipboard_h_ +#define SDL_clipboard_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * Put UTF-8 text into the clipboard. + * + * \param text the text to store in the clipboard + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_HasClipboardText + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * Get UTF-8 text from the clipboard, which must be freed with SDL_free(). + * + * This functions returns empty string if there was not enough memory left for + * a copy of the clipboard's content. + * + * \returns the clipboard text on success or an empty string on failure; call + * SDL_GetError() for more information. Caller must call SDL_free() + * on the returned pointer when done with it (even if there was an + * error). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * Query whether the clipboard exists and contains a non-empty text string. + * + * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_clipboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_config.h b/thirdparty/SDL/include/SDL/SDL_config.h new file mode 100644 index 00000000..f91cb47e --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config.h @@ -0,0 +1,61 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config.h + */ + +/* Add any platform that doesn't build using the configure system. */ +#if defined(__WIN32__) +#include "SDL_config_windows.h" +#elif defined(__WINRT__) +#include "SDL_config_winrt.h" +#elif defined(__WINGDK__) +#include "SDL_config_wingdk.h" +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) +#include "SDL_config_xbox.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +#elif defined(__IPHONEOS__) +#include "SDL_config_iphoneos.h" +#elif defined(__ANDROID__) +#include "SDL_config_android.h" +#elif defined(__OS2__) +#include "SDL_config_os2.h" +#elif defined(__EMSCRIPTEN__) +#include "SDL_config_emscripten.h" +#elif defined(__NGAGE__) +#include "SDL_config_ngage.h" +#else +/* This is a minimal configuration just to get SDL running on new platforms. */ +#include "SDL_config_minimal.h" +#endif /* platform config */ + +#ifdef USING_GENERATED_CONFIG_H +#error Wrong SDL_config.h, check your include path? +#endif + +#endif /* SDL_config_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config.h.cmake b/thirdparty/SDL/include/SDL/SDL_config.h.cmake new file mode 100644 index 00000000..204a12e0 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config.h.cmake @@ -0,0 +1,595 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_h_ +#define SDL_config_h_ + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C language features */ +#cmakedefine const @HAVE_CONST@ +#cmakedefine inline @HAVE_INLINE@ +#cmakedefine volatile @HAVE_VOLATILE@ + +/* C datatypes */ +/* Define SIZEOF_VOIDP for 64/32 architectures */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#cmakedefine HAVE_GCC_ATOMICS @HAVE_GCC_ATOMICS@ +#cmakedefine HAVE_GCC_SYNC_LOCK_TEST_AND_SET @HAVE_GCC_SYNC_LOCK_TEST_AND_SET@ + +/* Comment this if you want to build without any C library requirements */ +#cmakedefine HAVE_LIBC 1 +#if HAVE_LIBC + +/* Useful headers */ +#cmakedefine STDC_HEADERS 1 +#cmakedefine HAVE_ALLOCA_H 1 +#cmakedefine HAVE_CTYPE_H 1 +#cmakedefine HAVE_FLOAT_H 1 +#cmakedefine HAVE_ICONV_H 1 +#cmakedefine HAVE_INTTYPES_H 1 +#cmakedefine HAVE_LIMITS_H 1 +#cmakedefine HAVE_MALLOC_H 1 +#cmakedefine HAVE_MATH_H 1 +#cmakedefine HAVE_MEMORY_H 1 +#cmakedefine HAVE_SIGNAL_H 1 +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDDEF_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_STDIO_H 1 +#cmakedefine HAVE_STDLIB_H 1 +#cmakedefine HAVE_STRINGS_H 1 +#cmakedefine HAVE_STRING_H 1 +#cmakedefine HAVE_SYS_TYPES_H 1 +#cmakedefine HAVE_WCHAR_H 1 +#cmakedefine HAVE_PTHREAD_NP_H 1 +#cmakedefine HAVE_LIBUNWIND_H 1 + +/* C library functions */ +#cmakedefine HAVE_DLOPEN 1 +#cmakedefine HAVE_MALLOC 1 +#cmakedefine HAVE_CALLOC 1 +#cmakedefine HAVE_REALLOC 1 +#cmakedefine HAVE_FREE 1 +#cmakedefine HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#cmakedefine HAVE_GETENV 1 +#cmakedefine HAVE_SETENV 1 +#cmakedefine HAVE_PUTENV 1 +#cmakedefine HAVE_UNSETENV 1 +#endif +#cmakedefine HAVE_QSORT 1 +#cmakedefine HAVE_BSEARCH 1 +#cmakedefine HAVE_ABS 1 +#cmakedefine HAVE_BCOPY 1 +#cmakedefine HAVE_MEMSET 1 +#cmakedefine HAVE_MEMCPY 1 +#cmakedefine HAVE_MEMMOVE 1 +#cmakedefine HAVE_MEMCMP 1 +#cmakedefine HAVE_WCSLEN 1 +#cmakedefine HAVE_WCSLCPY 1 +#cmakedefine HAVE_WCSLCAT 1 +#cmakedefine HAVE__WCSDUP 1 +#cmakedefine HAVE_WCSDUP 1 +#cmakedefine HAVE_WCSSTR 1 +#cmakedefine HAVE_WCSCMP 1 +#cmakedefine HAVE_WCSNCMP 1 +#cmakedefine HAVE_WCSCASECMP 1 +#cmakedefine HAVE__WCSICMP 1 +#cmakedefine HAVE_WCSNCASECMP 1 +#cmakedefine HAVE__WCSNICMP 1 +#cmakedefine HAVE_STRLEN 1 +#cmakedefine HAVE_STRLCPY 1 +#cmakedefine HAVE_STRLCAT 1 +#cmakedefine HAVE__STRREV 1 +#cmakedefine HAVE__STRUPR 1 +#cmakedefine HAVE__STRLWR 1 +#cmakedefine HAVE_INDEX 1 +#cmakedefine HAVE_RINDEX 1 +#cmakedefine HAVE_STRCHR 1 +#cmakedefine HAVE_STRRCHR 1 +#cmakedefine HAVE_STRSTR 1 +#cmakedefine HAVE_STRTOK_R 1 +#cmakedefine HAVE_ITOA 1 +#cmakedefine HAVE__LTOA 1 +#cmakedefine HAVE__UITOA 1 +#cmakedefine HAVE__ULTOA 1 +#cmakedefine HAVE_STRTOL 1 +#cmakedefine HAVE_STRTOUL 1 +#cmakedefine HAVE__I64TOA 1 +#cmakedefine HAVE__UI64TOA 1 +#cmakedefine HAVE_STRTOLL 1 +#cmakedefine HAVE_STRTOULL 1 +#cmakedefine HAVE_STRTOD 1 +#cmakedefine HAVE_ATOI 1 +#cmakedefine HAVE_ATOF 1 +#cmakedefine HAVE_STRCMP 1 +#cmakedefine HAVE_STRNCMP 1 +#cmakedefine HAVE__STRICMP 1 +#cmakedefine HAVE_STRCASECMP 1 +#cmakedefine HAVE__STRNICMP 1 +#cmakedefine HAVE_STRNCASECMP 1 +#cmakedefine HAVE_SSCANF 1 +#cmakedefine HAVE_VSSCANF 1 +#cmakedefine HAVE_VSNPRINTF 1 +#cmakedefine HAVE_M_PI 1 +#cmakedefine HAVE_ACOS 1 +#cmakedefine HAVE_ACOSF 1 +#cmakedefine HAVE_ASIN 1 +#cmakedefine HAVE_ASINF 1 +#cmakedefine HAVE_ATAN 1 +#cmakedefine HAVE_ATANF 1 +#cmakedefine HAVE_ATAN2 1 +#cmakedefine HAVE_ATAN2F 1 +#cmakedefine HAVE_CEIL 1 +#cmakedefine HAVE_CEILF 1 +#cmakedefine HAVE_COPYSIGN 1 +#cmakedefine HAVE_COPYSIGNF 1 +#cmakedefine HAVE_COS 1 +#cmakedefine HAVE_COSF 1 +#cmakedefine HAVE_EXP 1 +#cmakedefine HAVE_EXPF 1 +#cmakedefine HAVE_FABS 1 +#cmakedefine HAVE_FABSF 1 +#cmakedefine HAVE_FLOOR 1 +#cmakedefine HAVE_FLOORF 1 +#cmakedefine HAVE_FMOD 1 +#cmakedefine HAVE_FMODF 1 +#cmakedefine HAVE_LOG 1 +#cmakedefine HAVE_LOGF 1 +#cmakedefine HAVE_LOG10 1 +#cmakedefine HAVE_LOG10F 1 +#cmakedefine HAVE_LROUND 1 +#cmakedefine HAVE_LROUNDF 1 +#cmakedefine HAVE_POW 1 +#cmakedefine HAVE_POWF 1 +#cmakedefine HAVE_ROUND 1 +#cmakedefine HAVE_ROUNDF 1 +#cmakedefine HAVE_SCALBN 1 +#cmakedefine HAVE_SCALBNF 1 +#cmakedefine HAVE_SIN 1 +#cmakedefine HAVE_SINF 1 +#cmakedefine HAVE_SQRT 1 +#cmakedefine HAVE_SQRTF 1 +#cmakedefine HAVE_TAN 1 +#cmakedefine HAVE_TANF 1 +#cmakedefine HAVE_TRUNC 1 +#cmakedefine HAVE_TRUNCF 1 +#cmakedefine HAVE_FOPEN64 1 +#cmakedefine HAVE_FSEEKO 1 +#cmakedefine HAVE_FSEEKO64 1 +#cmakedefine HAVE_SIGACTION 1 +#cmakedefine HAVE_SA_SIGACTION 1 +#cmakedefine HAVE_SETJMP 1 +#cmakedefine HAVE_NANOSLEEP 1 +#cmakedefine HAVE_SYSCONF 1 +#cmakedefine HAVE_SYSCTLBYNAME 1 +#cmakedefine HAVE_CLOCK_GETTIME 1 +#cmakedefine HAVE_GETPAGESIZE 1 +#cmakedefine HAVE_MPROTECT 1 +#cmakedefine HAVE_ICONV 1 +#cmakedefine HAVE_PTHREAD_SETNAME_NP 1 +#cmakedefine HAVE_PTHREAD_SET_NAME_NP 1 +#cmakedefine HAVE_SEM_TIMEDWAIT 1 +#cmakedefine HAVE_GETAUXVAL 1 +#cmakedefine HAVE_ELF_AUX_INFO 1 +#cmakedefine HAVE_POLL 1 +#cmakedefine HAVE__EXIT 1 + +#elif defined(__WIN32__) +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDDEF_H 1 +#cmakedefine HAVE_FLOAT_H 1 + +#else +/* We may need some replacement for stdarg.h here */ +#include +#endif /* HAVE_LIBC */ + +#cmakedefine HAVE_ALTIVEC_H 1 +#cmakedefine HAVE_DBUS_DBUS_H 1 +#cmakedefine HAVE_FCITX 1 +#cmakedefine HAVE_IBUS_IBUS_H 1 +#cmakedefine HAVE_SYS_INOTIFY_H 1 +#cmakedefine HAVE_INOTIFY_INIT 1 +#cmakedefine HAVE_INOTIFY_INIT1 1 +#cmakedefine HAVE_INOTIFY 1 +#cmakedefine HAVE_LIBUSB 1 +#cmakedefine HAVE_O_CLOEXEC 1 + +/* Apple platforms might be building universal binaries, where Intel builds + can use immintrin.h but other architectures can't. */ +#ifdef __APPLE__ +# if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +# endif +#else /* non-Apple platforms can use the normal CMake check for this. */ +#cmakedefine HAVE_IMMINTRIN_H 1 +#endif + +#cmakedefine HAVE_LIBUDEV_H 1 +#cmakedefine HAVE_LIBSAMPLERATE_H 1 +#cmakedefine HAVE_LIBDECOR_H 1 + +#cmakedefine HAVE_D3D_H @HAVE_D3D_H@ +#cmakedefine HAVE_D3D11_H @HAVE_D3D11_H@ +#cmakedefine HAVE_D3D12_H @HAVE_D3D12_H@ +#cmakedefine HAVE_DDRAW_H @HAVE_DDRAW_H@ +#cmakedefine HAVE_DSOUND_H @HAVE_DSOUND_H@ +#cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@ +#cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@ +#cmakedefine HAVE_WINDOWS_GAMING_INPUT_H @HAVE_WINDOWS_GAMING_INPUT_H@ +#cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@ + +#cmakedefine HAVE_MMDEVICEAPI_H @HAVE_MMDEVICEAPI_H@ +#cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@ +#cmakedefine HAVE_TPCSHRD_H @HAVE_TPCSHRD_H@ +#cmakedefine HAVE_SENSORSAPI_H @HAVE_SENSORSAPI_H@ +#cmakedefine HAVE_ROAPI_H @HAVE_ROAPI_H@ +#cmakedefine HAVE_SHELLSCALINGAPI_H @HAVE_SHELLSCALINGAPI_H@ + +#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@ +#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@ + +/* SDL internal assertion support */ +#if @SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED@ +#cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@ +#endif + +/* Allow disabling of core subsystems */ +#cmakedefine SDL_ATOMIC_DISABLED @SDL_ATOMIC_DISABLED@ +#cmakedefine SDL_AUDIO_DISABLED @SDL_AUDIO_DISABLED@ +#cmakedefine SDL_CPUINFO_DISABLED @SDL_CPUINFO_DISABLED@ +#cmakedefine SDL_EVENTS_DISABLED @SDL_EVENTS_DISABLED@ +#cmakedefine SDL_FILE_DISABLED @SDL_FILE_DISABLED@ +#cmakedefine SDL_JOYSTICK_DISABLED @SDL_JOYSTICK_DISABLED@ +#cmakedefine SDL_HAPTIC_DISABLED @SDL_HAPTIC_DISABLED@ +#cmakedefine SDL_HIDAPI_DISABLED @SDL_HIDAPI_DISABLED@ +#cmakedefine SDL_SENSOR_DISABLED @SDL_SENSOR_DISABLED@ +#cmakedefine SDL_LOADSO_DISABLED @SDL_LOADSO_DISABLED@ +#cmakedefine SDL_RENDER_DISABLED @SDL_RENDER_DISABLED@ +#cmakedefine SDL_THREADS_DISABLED @SDL_THREADS_DISABLED@ +#cmakedefine SDL_TIMERS_DISABLED @SDL_TIMERS_DISABLED@ +#cmakedefine SDL_VIDEO_DISABLED @SDL_VIDEO_DISABLED@ +#cmakedefine SDL_POWER_DISABLED @SDL_POWER_DISABLED@ +#cmakedefine SDL_FILESYSTEM_DISABLED @SDL_FILESYSTEM_DISABLED@ +#cmakedefine SDL_LOCALE_DISABLED @SDL_LOCALE_DISABLED@ +#cmakedefine SDL_MISC_DISABLED @SDL_MISC_DISABLED@ + +/* Enable various audio drivers */ +#cmakedefine SDL_AUDIO_DRIVER_ALSA @SDL_AUDIO_DRIVER_ALSA@ +#cmakedefine SDL_AUDIO_DRIVER_ALSA_DYNAMIC @SDL_AUDIO_DRIVER_ALSA_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_ANDROID @SDL_AUDIO_DRIVER_ANDROID@ +#cmakedefine SDL_AUDIO_DRIVER_OPENSLES @SDL_AUDIO_DRIVER_OPENSLES@ +#cmakedefine SDL_AUDIO_DRIVER_AAUDIO @SDL_AUDIO_DRIVER_AAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS @SDL_AUDIO_DRIVER_ARTS@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS_DYNAMIC @SDL_AUDIO_DRIVER_ARTS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_COREAUDIO @SDL_AUDIO_DRIVER_COREAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_DISK @SDL_AUDIO_DRIVER_DISK@ +#cmakedefine SDL_AUDIO_DRIVER_DSOUND @SDL_AUDIO_DRIVER_DSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_DUMMY @SDL_AUDIO_DRIVER_DUMMY@ +#cmakedefine SDL_AUDIO_DRIVER_EMSCRIPTEN @SDL_AUDIO_DRIVER_EMSCRIPTEN@ +#cmakedefine SDL_AUDIO_DRIVER_ESD @SDL_AUDIO_DRIVER_ESD@ +#cmakedefine SDL_AUDIO_DRIVER_ESD_DYNAMIC @SDL_AUDIO_DRIVER_ESD_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_HAIKU @SDL_AUDIO_DRIVER_HAIKU@ +#cmakedefine SDL_AUDIO_DRIVER_JACK @SDL_AUDIO_DRIVER_JACK@ +#cmakedefine SDL_AUDIO_DRIVER_JACK_DYNAMIC @SDL_AUDIO_DRIVER_JACK_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NAS @SDL_AUDIO_DRIVER_NAS@ +#cmakedefine SDL_AUDIO_DRIVER_NAS_DYNAMIC @SDL_AUDIO_DRIVER_NAS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NETBSD @SDL_AUDIO_DRIVER_NETBSD@ +#cmakedefine SDL_AUDIO_DRIVER_OSS @SDL_AUDIO_DRIVER_OSS@ +#cmakedefine SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H @SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H@ +#cmakedefine SDL_AUDIO_DRIVER_PAUDIO @SDL_AUDIO_DRIVER_PAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_PIPEWIRE @SDL_AUDIO_DRIVER_PIPEWIRE@ +#cmakedefine SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC @SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO @SDL_AUDIO_DRIVER_PULSEAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC @SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_QSA @SDL_AUDIO_DRIVER_QSA@ +#cmakedefine SDL_AUDIO_DRIVER_SNDIO @SDL_AUDIO_DRIVER_SNDIO@ +#cmakedefine SDL_AUDIO_DRIVER_SNDIO_DYNAMIC @SDL_AUDIO_DRIVER_SNDIO_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_SUNAUDIO @SDL_AUDIO_DRIVER_SUNAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_WASAPI @SDL_AUDIO_DRIVER_WASAPI@ +#cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@ +#cmakedefine SDL_AUDIO_DRIVER_OS2 @SDL_AUDIO_DRIVER_OS2@ +#cmakedefine SDL_AUDIO_DRIVER_VITA @SDL_AUDIO_DRIVER_VITA@ +#cmakedefine SDL_AUDIO_DRIVER_PSP @SDL_AUDIO_DRIVER_PSP@ +#cmakedefine SDL_AUDIO_DRIVER_PS2 @SDL_AUDIO_DRIVER_PS2@ + +/* Enable various input drivers */ +#cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@ +#cmakedefine SDL_INPUT_LINUXKD @SDL_INPUT_LINUXKD@ +#cmakedefine SDL_INPUT_FBSDKBIO @SDL_INPUT_FBSDKBIO@ +#cmakedefine SDL_JOYSTICK_ANDROID @SDL_JOYSTICK_ANDROID@ +#cmakedefine SDL_JOYSTICK_HAIKU @SDL_JOYSTICK_HAIKU@ +#cmakedefine SDL_JOYSTICK_WGI @SDL_JOYSTICK_WGI@ +#cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@ +#cmakedefine SDL_JOYSTICK_XINPUT @SDL_JOYSTICK_XINPUT@ +#cmakedefine SDL_JOYSTICK_DUMMY @SDL_JOYSTICK_DUMMY@ +#cmakedefine SDL_JOYSTICK_IOKIT @SDL_JOYSTICK_IOKIT@ +#cmakedefine SDL_JOYSTICK_MFI @SDL_JOYSTICK_MFI@ +#cmakedefine SDL_JOYSTICK_LINUX @SDL_JOYSTICK_LINUX@ +#cmakedefine SDL_JOYSTICK_OS2 @SDL_JOYSTICK_OS2@ +#cmakedefine SDL_JOYSTICK_USBHID @SDL_JOYSTICK_USBHID@ +#cmakedefine SDL_HAVE_MACHINE_JOYSTICK_H @SDL_HAVE_MACHINE_JOYSTICK_H@ +#cmakedefine SDL_JOYSTICK_HIDAPI @SDL_JOYSTICK_HIDAPI@ +#cmakedefine SDL_JOYSTICK_RAWINPUT @SDL_JOYSTICK_RAWINPUT@ +#cmakedefine SDL_JOYSTICK_EMSCRIPTEN @SDL_JOYSTICK_EMSCRIPTEN@ +#cmakedefine SDL_JOYSTICK_VIRTUAL @SDL_JOYSTICK_VIRTUAL@ +#cmakedefine SDL_JOYSTICK_VITA @SDL_JOYSTICK_VITA@ +#cmakedefine SDL_JOYSTICK_PSP @SDL_JOYSTICK_PSP@ +#cmakedefine SDL_JOYSTICK_PS2 @SDL_JOYSTICK_PS2@ +#cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@ +#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@ +#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@ +#cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@ +#cmakedefine SDL_HAPTIC_XINPUT @SDL_HAPTIC_XINPUT@ +#cmakedefine SDL_HAPTIC_ANDROID @SDL_HAPTIC_ANDROID@ +#cmakedefine SDL_LIBUSB_DYNAMIC @SDL_LIBUSB_DYNAMIC@ + +/* Enable various sensor drivers */ +#cmakedefine SDL_SENSOR_ANDROID @SDL_SENSOR_ANDROID@ +#cmakedefine SDL_SENSOR_COREMOTION @SDL_SENSOR_COREMOTION@ +#cmakedefine SDL_SENSOR_WINDOWS @SDL_SENSOR_WINDOWS@ +#cmakedefine SDL_SENSOR_DUMMY @SDL_SENSOR_DUMMY@ +#cmakedefine SDL_SENSOR_VITA @SDL_SENSOR_VITA@ + +/* Enable various shared object loading systems */ +#cmakedefine SDL_LOADSO_DLOPEN @SDL_LOADSO_DLOPEN@ +#cmakedefine SDL_LOADSO_DUMMY @SDL_LOADSO_DUMMY@ +#cmakedefine SDL_LOADSO_LDG @SDL_LOADSO_LDG@ +#cmakedefine SDL_LOADSO_WINDOWS @SDL_LOADSO_WINDOWS@ +#cmakedefine SDL_LOADSO_OS2 @SDL_LOADSO_OS2@ + +/* Enable various threading systems */ +#cmakedefine SDL_THREAD_GENERIC_COND_SUFFIX @SDL_THREAD_GENERIC_COND_SUFFIX@ +#cmakedefine SDL_THREAD_PTHREAD @SDL_THREAD_PTHREAD@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP@ +#cmakedefine SDL_THREAD_WINDOWS @SDL_THREAD_WINDOWS@ +#cmakedefine SDL_THREAD_OS2 @SDL_THREAD_OS2@ +#cmakedefine SDL_THREAD_VITA @SDL_THREAD_VITA@ +#cmakedefine SDL_THREAD_PSP @SDL_THREAD_PSP@ +#cmakedefine SDL_THREAD_PS2 @SDL_THREAD_PS2@ + +/* Enable various timer systems */ +#cmakedefine SDL_TIMER_HAIKU @SDL_TIMER_HAIKU@ +#cmakedefine SDL_TIMER_DUMMY @SDL_TIMER_DUMMY@ +#cmakedefine SDL_TIMER_UNIX @SDL_TIMER_UNIX@ +#cmakedefine SDL_TIMER_WINDOWS @SDL_TIMER_WINDOWS@ +#cmakedefine SDL_TIMER_OS2 @SDL_TIMER_OS2@ +#cmakedefine SDL_TIMER_VITA @SDL_TIMER_VITA@ +#cmakedefine SDL_TIMER_PSP @SDL_TIMER_PSP@ +#cmakedefine SDL_TIMER_PS2 @SDL_TIMER_PS2@ + +/* Enable various video drivers */ +#cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@ +#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@ +#cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@ +#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@ +#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ +#cmakedefine SDL_VIDEO_DRIVER_OFFSCREEN @SDL_VIDEO_DRIVER_OFFSCREEN@ +#cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ +#cmakedefine SDL_VIDEO_DRIVER_WINRT @SDL_VIDEO_DRIVER_WINRT@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@ +#cmakedefine SDL_VIDEO_DRIVER_RPI @SDL_VIDEO_DRIVER_RPI@ +#cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@ +#cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@ +#cmakedefine SDL_VIDEO_DRIVER_OS2 @SDL_VIDEO_DRIVER_OS2@ +#cmakedefine SDL_VIDEO_DRIVER_QNX @SDL_VIDEO_DRIVER_QNX@ +#cmakedefine SDL_VIDEO_DRIVER_RISCOS @SDL_VIDEO_DRIVER_RISCOS@ +#cmakedefine SDL_VIDEO_DRIVER_PSP @SDL_VIDEO_DRIVER_PSP@ +#cmakedefine SDL_VIDEO_DRIVER_PS2 @SDL_VIDEO_DRIVER_PS2@ + +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM @SDL_VIDEO_DRIVER_KMSDRM@ +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM@ + +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR@ + +#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES @SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS @SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XCURSOR @SDL_VIDEO_DRIVER_X11_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XDBE @SDL_VIDEO_DRIVER_X11_XDBE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2 @SDL_VIDEO_DRIVER_X11_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH @SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XFIXES @SDL_VIDEO_DRIVER_X11_XFIXES@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XRANDR @SDL_VIDEO_DRIVER_X11_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSCRNSAVER @SDL_VIDEO_DRIVER_X11_XSCRNSAVER@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSHAPE @SDL_VIDEO_DRIVER_X11_XSHAPE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS @SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM @SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM@ +#cmakedefine SDL_VIDEO_DRIVER_VITA @SDL_VIDEO_DRIVER_VITA@ + +#cmakedefine SDL_VIDEO_RENDER_D3D @SDL_VIDEO_RENDER_D3D@ +#cmakedefine SDL_VIDEO_RENDER_D3D11 @SDL_VIDEO_RENDER_D3D11@ +#cmakedefine SDL_VIDEO_RENDER_D3D12 @SDL_VIDEO_RENDER_D3D12@ +#cmakedefine SDL_VIDEO_RENDER_OGL @SDL_VIDEO_RENDER_OGL@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES @SDL_VIDEO_RENDER_OGL_ES@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES2 @SDL_VIDEO_RENDER_OGL_ES2@ +#cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@ +#cmakedefine SDL_VIDEO_RENDER_METAL @SDL_VIDEO_RENDER_METAL@ +#cmakedefine SDL_VIDEO_RENDER_VITA_GXM @SDL_VIDEO_RENDER_VITA_GXM@ +#cmakedefine SDL_VIDEO_RENDER_PS2 @SDL_VIDEO_RENDER_PS2@ +#cmakedefine SDL_VIDEO_RENDER_PSP @SDL_VIDEO_RENDER_PSP@ + +/* Enable OpenGL support */ +#cmakedefine SDL_VIDEO_OPENGL @SDL_VIDEO_OPENGL@ +#cmakedefine SDL_VIDEO_OPENGL_ES @SDL_VIDEO_OPENGL_ES@ +#cmakedefine SDL_VIDEO_OPENGL_ES2 @SDL_VIDEO_OPENGL_ES2@ +#cmakedefine SDL_VIDEO_OPENGL_BGL @SDL_VIDEO_OPENGL_BGL@ +#cmakedefine SDL_VIDEO_OPENGL_CGL @SDL_VIDEO_OPENGL_CGL@ +#cmakedefine SDL_VIDEO_OPENGL_GLX @SDL_VIDEO_OPENGL_GLX@ +#cmakedefine SDL_VIDEO_OPENGL_WGL @SDL_VIDEO_OPENGL_WGL@ +#cmakedefine SDL_VIDEO_OPENGL_EGL @SDL_VIDEO_OPENGL_EGL@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA @SDL_VIDEO_OPENGL_OSMESA@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA_DYNAMIC @SDL_VIDEO_OPENGL_OSMESA_DYNAMIC@ + +/* Enable Vulkan support */ +#cmakedefine SDL_VIDEO_VULKAN @SDL_VIDEO_VULKAN@ + +/* Enable Metal support */ +#cmakedefine SDL_VIDEO_METAL @SDL_VIDEO_METAL@ + +/* Enable system power support */ +#cmakedefine SDL_POWER_ANDROID @SDL_POWER_ANDROID@ +#cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@ +#cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@ +#cmakedefine SDL_POWER_WINRT @SDL_POWER_WINRT@ +#cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@ +#cmakedefine SDL_POWER_UIKIT @SDL_POWER_UIKIT@ +#cmakedefine SDL_POWER_HAIKU @SDL_POWER_HAIKU@ +#cmakedefine SDL_POWER_EMSCRIPTEN @SDL_POWER_EMSCRIPTEN@ +#cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@ +#cmakedefine SDL_POWER_VITA @SDL_POWER_VITA@ +#cmakedefine SDL_POWER_PSP @SDL_POWER_PSP@ + +/* Enable system filesystem support */ +#cmakedefine SDL_FILESYSTEM_ANDROID @SDL_FILESYSTEM_ANDROID@ +#cmakedefine SDL_FILESYSTEM_HAIKU @SDL_FILESYSTEM_HAIKU@ +#cmakedefine SDL_FILESYSTEM_COCOA @SDL_FILESYSTEM_COCOA@ +#cmakedefine SDL_FILESYSTEM_DUMMY @SDL_FILESYSTEM_DUMMY@ +#cmakedefine SDL_FILESYSTEM_RISCOS @SDL_FILESYSTEM_RISCOS@ +#cmakedefine SDL_FILESYSTEM_UNIX @SDL_FILESYSTEM_UNIX@ +#cmakedefine SDL_FILESYSTEM_WINDOWS @SDL_FILESYSTEM_WINDOWS@ +#cmakedefine SDL_FILESYSTEM_EMSCRIPTEN @SDL_FILESYSTEM_EMSCRIPTEN@ +#cmakedefine SDL_FILESYSTEM_OS2 @SDL_FILESYSTEM_OS2@ +#cmakedefine SDL_FILESYSTEM_VITA @SDL_FILESYSTEM_VITA@ +#cmakedefine SDL_FILESYSTEM_PSP @SDL_FILESYSTEM_PSP@ +#cmakedefine SDL_FILESYSTEM_PS2 @SDL_FILESYSTEM_PS2@ + +/* Enable misc subsystem */ +#cmakedefine SDL_MISC_DUMMY @SDL_MISC_DUMMY@ + +/* Enable locale subsystem */ +#cmakedefine SDL_LOCALE_DUMMY @SDL_LOCALE_DUMMY@ + +/* Enable assembly routines */ +#cmakedefine SDL_ALTIVEC_BLITTERS @SDL_ALTIVEC_BLITTERS@ +#cmakedefine SDL_ARM_SIMD_BLITTERS @SDL_ARM_SIMD_BLITTERS@ +#cmakedefine SDL_ARM_NEON_BLITTERS @SDL_ARM_NEON_BLITTERS@ + +/* Whether SDL_DYNAMIC_API needs dlopen */ +#cmakedefine DYNAPI_NEEDS_DLOPEN @DYNAPI_NEEDS_DLOPEN@ + +/* Enable dynamic libsamplerate support */ +#cmakedefine SDL_LIBSAMPLERATE_DYNAMIC @SDL_LIBSAMPLERATE_DYNAMIC@ + +/* Enable ime support */ +#cmakedefine SDL_USE_IME @SDL_USE_IME@ + +/* Platform specific definitions */ +#cmakedefine SDL_IPHONE_KEYBOARD @SDL_IPHONE_KEYBOARD@ +#cmakedefine SDL_IPHONE_LAUNCHSCREEN @SDL_IPHONE_LAUNCHSCREEN@ + +#cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@ +#cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@ +#cmakedefine SDL_VIDEO_VITA_PVR_OGL @SDL_VIDEO_VITA_PVR_OGL@ + +#if !defined(__WIN32__) && !defined(__WINRT__) +# if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +# endif /* if (stdint.h isn't available) */ +#else /* __WIN32__ */ +# if !defined(_STDINT_H_) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) +# if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__CODEGEARC__) +#define HAVE_STDINT_H 1 +# elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +# ifndef _UINTPTR_T_DEFINED +# ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +# else +typedef unsigned int uintptr_t; +# endif +#define _UINTPTR_T_DEFINED +# endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +# if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +# endif +# if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +# endif +# else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +# ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +# endif +typedef unsigned int uintptr_t; +# endif /* __GNUC__ || _MSC_VER */ +# endif /* !_STDINT_H_ && !HAVE_STDINT_H */ +#endif /* __WIN32__ */ + +#endif /* SDL_config_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config.h.in b/thirdparty/SDL/include/SDL/SDL_config.h.in new file mode 100644 index 00000000..56b53029 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config.h.in @@ -0,0 +1,493 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_h_ +#define SDL_config_h_ + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* Make sure that this isn't included by Visual C++ */ +#ifdef _MSC_VER +#error You should run git checkout -f include/SDL_config.h +#endif + +/* C language features */ +#undef const +#undef inline +#undef volatile + +/* C datatypes */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#undef HAVE_GCC_ATOMICS +#undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET + +/* Comment this if you want to build without any C library requirements */ +#undef HAVE_LIBC +#if HAVE_LIBC + +/* Useful headers */ +#undef STDC_HEADERS +#undef HAVE_ALLOCA_H +#undef HAVE_CTYPE_H +#undef HAVE_FLOAT_H +#undef HAVE_ICONV_H +#undef HAVE_INTTYPES_H +#undef HAVE_LIMITS_H +#undef HAVE_MALLOC_H +#undef HAVE_MATH_H +#undef HAVE_MEMORY_H +#undef HAVE_SIGNAL_H +#undef HAVE_STDARG_H +#undef HAVE_STDINT_H +#undef HAVE_STDIO_H +#undef HAVE_STDLIB_H +#undef HAVE_STRINGS_H +#undef HAVE_STRING_H +#undef HAVE_SYS_TYPES_H +#undef HAVE_WCHAR_H +#undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUNWIND_H + +/* C library functions */ +#undef HAVE_DLOPEN +#undef HAVE_MALLOC +#undef HAVE_CALLOC +#undef HAVE_REALLOC +#undef HAVE_FREE +#undef HAVE_ALLOCA +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#undef HAVE_GETENV +#undef HAVE_SETENV +#undef HAVE_PUTENV +#undef HAVE_UNSETENV +#endif +#undef HAVE_QSORT +#undef HAVE_BSEARCH +#undef HAVE_ABS +#undef HAVE_BCOPY +#undef HAVE_MEMSET +#undef HAVE_MEMCPY +#undef HAVE_MEMMOVE +#undef HAVE_MEMCMP +#undef HAVE_WCSLEN +#undef HAVE_WCSLCPY +#undef HAVE_WCSLCAT +#undef HAVE__WCSDUP +#undef HAVE_WCSDUP +#undef HAVE_WCSSTR +#undef HAVE_WCSCMP +#undef HAVE_WCSNCMP +#undef HAVE_WCSCASECMP +#undef HAVE__WCSICMP +#undef HAVE_WCSNCASECMP +#undef HAVE__WCSNICMP +#undef HAVE_STRLEN +#undef HAVE_STRLCPY +#undef HAVE_STRLCAT +#undef HAVE__STRREV +#undef HAVE__STRUPR +#undef HAVE__STRLWR +#undef HAVE_INDEX +#undef HAVE_RINDEX +#undef HAVE_STRCHR +#undef HAVE_STRRCHR +#undef HAVE_STRSTR +#undef HAVE_STRTOK_R +#undef HAVE_ITOA +#undef HAVE__LTOA +#undef HAVE__UITOA +#undef HAVE__ULTOA +#undef HAVE_STRTOL +#undef HAVE_STRTOUL +#undef HAVE__I64TOA +#undef HAVE__UI64TOA +#undef HAVE_STRTOLL +#undef HAVE_STRTOULL +#undef HAVE_STRTOD +#undef HAVE_ATOI +#undef HAVE_ATOF +#undef HAVE_STRCMP +#undef HAVE_STRNCMP +#undef HAVE__STRICMP +#undef HAVE_STRCASECMP +#undef HAVE__STRNICMP +#undef HAVE_STRNCASECMP +#undef HAVE_SSCANF +#undef HAVE_VSSCANF +#undef HAVE_SNPRINTF +#undef HAVE_VSNPRINTF +#undef HAVE_M_PI +#undef HAVE_ACOS +#undef HAVE_ACOSF +#undef HAVE_ASIN +#undef HAVE_ASINF +#undef HAVE_ATAN +#undef HAVE_ATANF +#undef HAVE_ATAN2 +#undef HAVE_ATAN2F +#undef HAVE_CEIL +#undef HAVE_CEILF +#undef HAVE_COPYSIGN +#undef HAVE_COPYSIGNF +#undef HAVE_COS +#undef HAVE_COSF +#undef HAVE_EXP +#undef HAVE_EXPF +#undef HAVE_FABS +#undef HAVE_FABSF +#undef HAVE_FLOOR +#undef HAVE_FLOORF +#undef HAVE_FMOD +#undef HAVE_FMODF +#undef HAVE_LOG +#undef HAVE_LOGF +#undef HAVE_LOG10 +#undef HAVE_LOG10F +#undef HAVE_LROUND +#undef HAVE_LROUNDF +#undef HAVE_POW +#undef HAVE_POWF +#undef HAVE_ROUND +#undef HAVE_ROUNDF +#undef HAVE_SCALBN +#undef HAVE_SCALBNF +#undef HAVE_SIN +#undef HAVE_SINF +#undef HAVE_SQRT +#undef HAVE_SQRTF +#undef HAVE_TAN +#undef HAVE_TANF +#undef HAVE_TRUNC +#undef HAVE_TRUNCF +#undef HAVE_FOPEN64 +#undef HAVE_FSEEKO +#undef HAVE_FSEEKO64 +#undef HAVE_SIGACTION +#undef HAVE_SA_SIGACTION +#undef HAVE_SETJMP +#undef HAVE_NANOSLEEP +#undef HAVE_SYSCONF +#undef HAVE_SYSCTLBYNAME +#undef HAVE_CLOCK_GETTIME +#undef HAVE_GETPAGESIZE +#undef HAVE_MPROTECT +#undef HAVE_ICONV +#undef HAVE_PTHREAD_SETNAME_NP +#undef HAVE_PTHREAD_SET_NAME_NP +#undef HAVE_SEM_TIMEDWAIT +#undef HAVE_GETAUXVAL +#undef HAVE_ELF_AUX_INFO +#undef HAVE_POLL +#undef HAVE__EXIT + +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#endif /* HAVE_LIBC */ + +#undef HAVE_O_CLOEXEC +#undef HAVE_ALTIVEC_H +#undef HAVE_DBUS_DBUS_H +#undef HAVE_FCITX +#undef HAVE_SYS_INOTIFY_H +#undef HAVE_INOTIFY_INIT +#undef HAVE_INOTIFY_INIT1 +#undef HAVE_INOTIFY +#undef HAVE_IBUS_IBUS_H +#undef HAVE_IMMINTRIN_H +#undef HAVE_LIBUDEV_H +#undef HAVE_LIBUSB +#undef HAVE_LIBSAMPLERATE_H +#undef HAVE_LIBDECOR_H +#undef HAVE_LSXINTRIN_H +#undef HAVE_LASXINTRIN_H + +#undef HAVE_DDRAW_H +#undef HAVE_DINPUT_H +#undef HAVE_DSOUND_H +#undef HAVE_DXGI_H +#undef HAVE_WINDOWS_GAMING_INPUT_H +#undef HAVE_XINPUT_H +#undef HAVE_XINPUT_GAMEPAD_EX +#undef HAVE_XINPUT_STATE_EX + +#undef HAVE_MMDEVICEAPI_H +#undef HAVE_AUDIOCLIENT_H +#undef HAVE_TPCSHRD_H +#undef HAVE_SENSORSAPI_H +#undef HAVE_ROAPI_H +#undef HAVE_SHELLSCALINGAPI_H + +/* SDL internal assertion support */ +#undef SDL_DEFAULT_ASSERT_LEVEL + +/* Allow disabling of core subsystems */ +#undef SDL_ATOMIC_DISABLED +#undef SDL_AUDIO_DISABLED +#undef SDL_CPUINFO_DISABLED +#undef SDL_EVENTS_DISABLED +#undef SDL_FILE_DISABLED +#undef SDL_JOYSTICK_DISABLED +#undef SDL_HAPTIC_DISABLED +#undef SDL_HIDAPI_DISABLED +#undef SDL_SENSOR_DISABLED +#undef SDL_LOADSO_DISABLED +#undef SDL_RENDER_DISABLED +#undef SDL_THREADS_DISABLED +#undef SDL_TIMERS_DISABLED +#undef SDL_VIDEO_DISABLED +#undef SDL_POWER_DISABLED +#undef SDL_FILESYSTEM_DISABLED +#undef SDL_LOCALE_DISABLED +#undef SDL_MISC_DISABLED + +/* Enable various audio drivers */ +#undef SDL_AUDIO_DRIVER_AAUDIO +#undef SDL_AUDIO_DRIVER_ALSA +#undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +#undef SDL_AUDIO_DRIVER_ANDROID +#undef SDL_AUDIO_DRIVER_ARTS +#undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC +#undef SDL_AUDIO_DRIVER_COREAUDIO +#undef SDL_AUDIO_DRIVER_DISK +#undef SDL_AUDIO_DRIVER_DSOUND +#undef SDL_AUDIO_DRIVER_DUMMY +#undef SDL_AUDIO_DRIVER_EMSCRIPTEN +#undef SDL_AUDIO_DRIVER_ESD +#undef SDL_AUDIO_DRIVER_ESD_DYNAMIC +#undef SDL_AUDIO_DRIVER_FUSIONSOUND +#undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC +#undef SDL_AUDIO_DRIVER_HAIKU +#undef SDL_AUDIO_DRIVER_JACK +#undef SDL_AUDIO_DRIVER_JACK_DYNAMIC +#undef SDL_AUDIO_DRIVER_NACL +#undef SDL_AUDIO_DRIVER_NAS +#undef SDL_AUDIO_DRIVER_NAS_DYNAMIC +#undef SDL_AUDIO_DRIVER_NETBSD +#undef SDL_AUDIO_DRIVER_OPENSLES +#undef SDL_AUDIO_DRIVER_OSS +#undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H +#undef SDL_AUDIO_DRIVER_PAUDIO +#undef SDL_AUDIO_DRIVER_PIPEWIRE +#undef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC +#undef SDL_AUDIO_DRIVER_PULSEAUDIO +#undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_QSA +#undef SDL_AUDIO_DRIVER_SNDIO +#undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_SUNAUDIO +#undef SDL_AUDIO_DRIVER_WASAPI +#undef SDL_AUDIO_DRIVER_WINMM +#undef SDL_AUDIO_DRIVER_OS2 + +/* Enable various input drivers */ +#undef SDL_INPUT_LINUXEV +#undef SDL_INPUT_FBSDKBIO +#undef SDL_INPUT_LINUXKD +#undef SDL_INPUT_WSCONS +#undef SDL_JOYSTICK_HAIKU +#undef SDL_JOYSTICK_DINPUT +#undef SDL_JOYSTICK_WGI +#undef SDL_JOYSTICK_XINPUT +#undef SDL_JOYSTICK_DUMMY +#undef SDL_JOYSTICK_IOKIT +#undef SDL_JOYSTICK_MFI +#undef SDL_JOYSTICK_LINUX +#undef SDL_JOYSTICK_ANDROID +#undef SDL_JOYSTICK_OS2 +#undef SDL_JOYSTICK_USBHID +#undef SDL_HAVE_MACHINE_JOYSTICK_H +#undef SDL_JOYSTICK_HIDAPI +#undef SDL_JOYSTICK_RAWINPUT +#undef SDL_JOYSTICK_EMSCRIPTEN +#undef SDL_JOYSTICK_VIRTUAL +#undef SDL_HAPTIC_DUMMY +#undef SDL_HAPTIC_ANDROID +#undef SDL_HAPTIC_LINUX +#undef SDL_HAPTIC_IOKIT +#undef SDL_HAPTIC_DINPUT +#undef SDL_HAPTIC_XINPUT + +/* Enable various sensor drivers */ +#undef SDL_SENSOR_ANDROID +#undef SDL_SENSOR_COREMOTION +#undef SDL_SENSOR_WINDOWS +#undef SDL_SENSOR_DUMMY + +/* Enable various shared object loading systems */ +#undef SDL_LOADSO_DLOPEN +#undef SDL_LOADSO_DUMMY +#undef SDL_LOADSO_LDG +#undef SDL_LOADSO_WINDOWS +#undef SDL_LOADSO_OS2 + +/* Enable various threading systems */ +#undef SDL_THREAD_GENERIC_COND_SUFFIX +#undef SDL_THREAD_PTHREAD +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP +#undef SDL_THREAD_WINDOWS +#undef SDL_THREAD_OS2 + +/* Enable various timer systems */ +#undef SDL_TIMER_HAIKU +#undef SDL_TIMER_DUMMY +#undef SDL_TIMER_UNIX +#undef SDL_TIMER_WINDOWS +#undef SDL_TIMER_OS2 + +/* Enable various video drivers */ +#undef SDL_VIDEO_DRIVER_HAIKU +#undef SDL_VIDEO_DRIVER_COCOA +#undef SDL_VIDEO_DRIVER_DIRECTFB +#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC +#undef SDL_VIDEO_DRIVER_DUMMY +#undef SDL_VIDEO_DRIVER_WINDOWS +#undef SDL_VIDEO_DRIVER_WAYLAND +#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +#undef SDL_VIDEO_DRIVER_X11 +#undef SDL_VIDEO_DRIVER_RPI +#undef SDL_VIDEO_DRIVER_KMSDRM +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM +#undef SDL_VIDEO_DRIVER_ANDROID +#undef SDL_VIDEO_DRIVER_EMSCRIPTEN +#undef SDL_VIDEO_DRIVER_OFFSCREEN +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +#undef SDL_VIDEO_DRIVER_X11_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_XDBE +#undef SDL_VIDEO_DRIVER_X11_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +#undef SDL_VIDEO_DRIVER_X11_XFIXES +#undef SDL_VIDEO_DRIVER_X11_XRANDR +#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#undef SDL_VIDEO_DRIVER_X11_XSHAPE +#undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#undef SDL_VIDEO_DRIVER_NACL +#undef SDL_VIDEO_DRIVER_VIVANTE +#undef SDL_VIDEO_DRIVER_VIVANTE_VDK +#undef SDL_VIDEO_DRIVER_OS2 +#undef SDL_VIDEO_DRIVER_QNX +#undef SDL_VIDEO_DRIVER_RISCOS + +#undef SDL_VIDEO_RENDER_D3D +#undef SDL_VIDEO_RENDER_D3D11 +#undef SDL_VIDEO_RENDER_D3D12 +#undef SDL_VIDEO_RENDER_OGL +#undef SDL_VIDEO_RENDER_OGL_ES +#undef SDL_VIDEO_RENDER_OGL_ES2 +#undef SDL_VIDEO_RENDER_DIRECTFB +#undef SDL_VIDEO_RENDER_METAL + +/* Enable OpenGL support */ +#undef SDL_VIDEO_OPENGL +#undef SDL_VIDEO_OPENGL_ES +#undef SDL_VIDEO_OPENGL_ES2 +#undef SDL_VIDEO_OPENGL_BGL +#undef SDL_VIDEO_OPENGL_CGL +#undef SDL_VIDEO_OPENGL_EGL +#undef SDL_VIDEO_OPENGL_GLX +#undef SDL_VIDEO_OPENGL_WGL +#undef SDL_VIDEO_OPENGL_OSMESA +#undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC + +/* Enable Vulkan support */ +#undef SDL_VIDEO_VULKAN + +/* Enable Metal support */ +#undef SDL_VIDEO_METAL + +/* Enable system power support */ +#undef SDL_POWER_LINUX +#undef SDL_POWER_WINDOWS +#undef SDL_POWER_MACOSX +#undef SDL_POWER_HAIKU +#undef SDL_POWER_ANDROID +#undef SDL_POWER_EMSCRIPTEN +#undef SDL_POWER_HARDWIRED + +/* Enable system filesystem support */ +#undef SDL_FILESYSTEM_ANDROID +#undef SDL_FILESYSTEM_HAIKU +#undef SDL_FILESYSTEM_COCOA +#undef SDL_FILESYSTEM_DUMMY +#undef SDL_FILESYSTEM_RISCOS +#undef SDL_FILESYSTEM_UNIX +#undef SDL_FILESYSTEM_WINDOWS +#undef SDL_FILESYSTEM_NACL +#undef SDL_FILESYSTEM_EMSCRIPTEN +#undef SDL_FILESYSTEM_OS2 +#undef SDL_FILESYSTEM_VITA +#undef SDL_FILESYSTEM_PSP +#undef SDL_FILESYSTEM_PS2 + +/* Enable misc subsystem */ +#undef SDL_MISC_DUMMY + +/* Enable locale subsystem */ +#undef SDL_LOCALE_DUMMY + +/* Enable assembly routines */ +#undef SDL_ALTIVEC_BLITTERS +#undef SDL_ARM_SIMD_BLITTERS +#undef SDL_ARM_NEON_BLITTERS + +/* Whether SDL_DYNAMIC_API needs dlopen() */ +#undef DYNAPI_NEEDS_DLOPEN + +/* Enable ime support */ +#undef SDL_USE_IME + +/* Enable dynamic udev support */ +#undef SDL_UDEV_DYNAMIC + +/* Enable dynamic libusb support */ +#undef SDL_LIBUSB_DYNAMIC + +/* Enable dynamic libsamplerate support */ +#undef SDL_LIBSAMPLERATE_DYNAMIC + +#endif /* SDL_config_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_android.h b/thirdparty/SDL/include/SDL/SDL_config_android.h new file mode 100644 index 00000000..5a9cfc04 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_android.h @@ -0,0 +1,193 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_android_h_ +#define SDL_config_android_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_android.h + * + * This is a configuration that can be used to build SDL for Android + */ + +#include + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_CLOCK_GETTIME 1 + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_ANDROID 1 +#define SDL_AUDIO_DRIVER_OPENSLES 1 +#define SDL_AUDIO_DRIVER_AAUDIO 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_ANDROID 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_ANDROID 1 + +/* Enable sensor driver */ +#define SDL_SENSOR_ANDROID 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_ANDROID 1 + +/* Enable OpenGL ES */ +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable Vulkan support */ +/* Android does not support Vulkan in native code using the "armeabi" ABI. */ +#if defined(__ARM_ARCH) && __ARM_ARCH < 7 +#define SDL_VIDEO_VULKAN 0 +#else +#define SDL_VIDEO_VULKAN 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_ANDROID 1 + +/* Enable the filesystem driver */ +#define SDL_FILESYSTEM_ANDROID 1 + +#endif /* SDL_config_android_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_emscripten.h b/thirdparty/SDL/include/SDL/SDL_config_emscripten.h new file mode 100644 index 00000000..989e1243 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_emscripten.h @@ -0,0 +1,218 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_config_emscripten_h_ +#define _SDL_config_emscripten_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_emscripten.h + * + * This is a configuration that can be used to build SDL for Emscripten. + */ + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif +#define HAVE_GCC_ATOMICS 1 + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_WCHAR_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_WCSCASECMP 1 +#define HAVE_WCSNCASECMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_FSEEKO 1 +#define HAVE_FSEEKO64 1 +#define HAVE_SIGACTION 1 +#define HAVE_SA_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_CLOCK_GETTIME 1 +/* #undef HAVE_GETPAGESIZE */ +#define HAVE_MPROTECT 1 +#define HAVE_ICONV 1 + +/* SDL internal assertion support */ +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ + +#define SDL_CPUINFO_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#define SDL_HIDAPI_DISABLED 1 +#ifndef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREADS_DISABLED 1 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_EMSCRIPTEN 1 + +/* Enable various sensor drivers */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#ifdef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1 + +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ +/* #undef SDL_VIDEO_OPENGL_ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +/* #undef SDL_VIDEO_OPENGL_GLX */ +/* #undef SDL_VIDEO_OPENGL_WGL */ +#define SDL_VIDEO_OPENGL_EGL 1 +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable system power support */ +#define SDL_POWER_EMSCRIPTEN 1 + +/* Enable system filesystem support */ +#define SDL_FILESYSTEM_EMSCRIPTEN 1 + +#endif /* _SDL_config_emscripten_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_iphoneos.h b/thirdparty/SDL/include/SDL/SDL_config_iphoneos.h new file mode 100644 index 00000000..48f9f9f9 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_iphoneos.h @@ -0,0 +1,216 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_iphoneos_h_ +#define SDL_config_iphoneos_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +/* The libunwind functions are only available on x86 */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 +#define HAVE_O_CLOEXEC 1 + +/* enable iPhone version of Core Audio driver */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DUMMY 1 + +/* Enable joystick support */ +/* Only enable HIDAPI support if you want to support Steam Controllers on iOS and tvOS */ +/*#define SDL_JOYSTICK_HIDAPI 1*/ +#define SDL_JOYSTICK_MFI 1 +#define SDL_JOYSTICK_VIRTUAL 1 + +#ifdef __TVOS__ +#define SDL_SENSOR_DUMMY 1 +#else +/* Enable the CoreMotion sensor driver */ +#define SDL_SENSOR_COREMOTION 1 +#endif + +/* Enable Unix style SO loading */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Supported video drivers */ +#define SDL_VIDEO_DRIVER_UIKIT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES */ +#if !TARGET_OS_MACCATALYST +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer + Also supported in simulator from iOS 13.0 and tvOS 13.0 + */ +#if (TARGET_OS_SIMULATOR && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (__TV_OS_VERSION_MIN_REQUIRED >= 130000))) || (!TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000))) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_UIKIT 1 + +/* enable iPhone keyboard support */ +#define SDL_IPHONE_KEYBOARD 1 + +/* enable iOS extended launch screen */ +#define SDL_IPHONE_LAUNCHSCREEN 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +#endif /* SDL_config_iphoneos_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_macosx.h b/thirdparty/SDL/include/SDL/SDL_config_macosx.h new file mode 100644 index 00000000..023ecaae --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_macosx.h @@ -0,0 +1,276 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_macosx_h_ +#define SDL_config_macosx_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ +#include + +/* This is a set of defines to configure the SDL features */ + +#ifdef __LP64__ + #define SIZEOF_VOIDP 8 +#else + #define SIZEOF_VOIDP 4 +#endif + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 + +#if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070) +#define HAVE_O_CLOEXEC 1 +#endif + +#define HAVE_GCC_ATOMICS 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_IOKIT 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_IOKIT 1 + +/* The MFI controller support requires ARC Objective C runtime */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__) +#define SDL_JOYSTICK_MFI 1 +#endif + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_COCOA 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#undef SDL_VIDEO_DRIVER_X11 +#define SDL_VIDEO_DRIVER_X11_DYNAMIC "/opt/X11/lib/libX11.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/opt/X11/lib/libXext.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/opt/X11/lib/libXi.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/opt/X11/lib/libXrandr.2.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/opt/X11/lib/libXss.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#define SDL_VIDEO_DRIVER_X11_XRANDR 1 +#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 +#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 + +#ifdef MAC_OS_X_VERSION_10_8 +/* + * No matter the versions targeted, this is the 10.8 or later SDK, so you have + * to use the external Xquartz, which is a more modern Xlib. Previous SDKs + * used an older Xlib. + */ +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal only supported on 64-bit architectures with 10.11+ */ +#if TARGET_RT_64_BIT && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#ifndef SDL_VIDEO_RENDER_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#else +#define SDL_VIDEO_RENDER_METAL 0 +#endif +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_CGL +#define SDL_VIDEO_OPENGL_CGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_GLX +#define SDL_VIDEO_OPENGL_GLX 1 +#endif + +/* Enable Vulkan and Metal support */ +#ifndef SDL_VIDEO_VULKAN +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#else +#define SDL_VIDEO_VULKAN 0 +#endif +#endif + +#ifndef SDL_VIDEO_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#else +#define SDL_VIDEO_METAL 0 +#endif +#endif + +/* Enable system power support */ +#define SDL_POWER_MACOSX 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +/* Enable assembly routines */ +#ifdef __ppc__ +#define SDL_ALTIVEC_BLITTERS 1 +#endif + +#endif /* SDL_config_macosx_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_minimal.h b/thirdparty/SDL/include/SDL/SDL_config_minimal.h new file mode 100644 index 00000000..c74fcdb1 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_minimal.h @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_minimal_h_ +#define SDL_config_minimal_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_minimal.h + * + * This is the minimal configuration that can be used to build SDL. + */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* Here are some reasonable defaults */ +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +#else +#define HAVE_STDINT_H 1 +#define HAVE_INTTYPES_H 1 +#endif /* Visual Studio 2008 */ + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable the stub timer support (src/timer/dummy/\*.c) */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable the dummy video driver (src/video/dummy/\*.c) */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_minimal_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_ngage.h b/thirdparty/SDL/include/SDL/SDL_config_ngage.h new file mode 100644 index 00000000..a9d2d37a --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_ngage.h @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_ngage_h_ +#define SDL_config_ngage_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_MATH_H 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_MALLOC 1 +#define SDL_MAIN_NEEDED 1 +#define LACKS_SYS_MMAN_H 1 + +/* Enable the N-Gage thread support (src/thread/ngage/\*.c) */ +#define SDL_THREAD_NGAGE 1 + +/* Enable the N-Gage timer support (src/timer/ngage/\*.c) */ +#define SDL_TIMER_NGAGE 1 + +/* Enable the N-Gage video driver (src/video/ngage/\*.c) */ +#define SDL_VIDEO_DRIVER_NGAGE 1 + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_ngage_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_os2.h b/thirdparty/SDL/include/SDL/SDL_config_os2.h new file mode 100644 index 00000000..c86769db --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_os2.h @@ -0,0 +1,207 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_os2_h_ +#define SDL_config_os2_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#define SIZEOF_VOIDP 4 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_OS2 1 + +#define SDL_POWER_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 + +#define SDL_SENSOR_DUMMY 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_OS2 1 +#define SDL_JOYSTICK_OS2 1 +#ifndef HAVE_LIBUSB_H /* see Makefile */ +#define SDL_HIDAPI_DISABLED 1 +/*#undef SDL_JOYSTICK_HIDAPI */ +#else +#define SDL_JOYSTICK_HIDAPI 1 +#define HAVE_LIBUSB 1 +/* dynamically loaded libusb-1.0 dll: */ +#define SDL_LIBUSB_DYNAMIC "usb100.dll" +#endif +/*#undef SDL_JOYSTICK_VIRTUAL */ + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ + +#define SDL_THREAD_OS2 1 +#define SDL_LOADSO_OS2 1 +#define SDL_TIMER_OS2 1 +#define SDL_FILESYSTEM_OS2 1 + +/* use libsamplerate for audio rate conversion. */ +/*#define HAVE_LIBSAMPLERATE_H 1 */ + +/* Enable dynamic libsamplerate support */ +#define SDL_LIBSAMPLERATE_DYNAMIC "SAMPRATE.DLL" + +#define HAVE_LIBC 1 + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 + +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_WCHAR_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_SIGNAL_H 1 + +#if 0 /* see Makefile */ +#define HAVE_ICONV 1 +#define HAVE_ICONV_H 1 +#endif + +/* #undef HAVE_DLOPEN */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#if defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE__FTELLI64 1 +#endif +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +#define HAVE_WCSCMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +/* #undef HAVE_WCSDUP */ +#define HAVE__WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +/* #undef HAVE_INDEX */ +/* #undef HAVE_RINDEX */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE__I64TOA 1 +#define HAVE__UI64TOA 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 +#define HAVE_ACOS 1 +/* #undef HAVE_ACOSF */ +#define HAVE_ASIN 1 +/* #undef HAVE_ASINF */ +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +/* #undef HAVE_ATAN2F */ +#define HAVE_CEIL 1 +/* #undef HAVE_CEILF */ +/* #undef HAVE_COPYSIGN */ +/* #undef HAVE_COPYSIGNF */ +#define HAVE_COS 1 +/* #undef HAVE_COSF */ +#define HAVE_EXP 1 +/* #undef HAVE_EXPF */ +#define HAVE_FABS 1 +/* #undef HAVE_FABSF */ +#define HAVE_FLOOR 1 +/* #undef HAVE_FLOORF */ +#define HAVE_FMOD 1 +/* #undef HAVE_FMODF */ +#define HAVE_LOG 1 +/* #undef HAVE_LOGF */ +#define HAVE_LOG10 1 +/* #undef HAVE_LOG10F */ +#define HAVE_POW 1 +/* #undef HAVE_POWF */ +#define HAVE_SIN 1 +/* #undef HAVE_SINF */ +/* #undef HAVE_SCALBN */ +/* #undef HAVE_SCALBNF */ +#define HAVE_SQRT 1 +/* #undef HAVE_SQRTF */ +#define HAVE_TAN 1 +/* #undef HAVE_TANF */ +/* #undef HAVE_TRUNC */ +/* #undef HAVE_TRUNCF */ +/* #undef HAVE_LROUND */ +/* #undef HAVE_LROUNDF */ +/* #undef HAVE_ROUND */ +/* #undef HAVE_ROUNDF */ + +#endif /* SDL_config_os2_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_pandora.h b/thirdparty/SDL/include/SDL/SDL_config_pandora.h new file mode 100644 index 00000000..01bbf49b --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_pandora.h @@ -0,0 +1,141 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_pandora_h_ +#define SDL_config_pandora_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define SDL_BYTEORDER 1234 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_OSS 1 + +#define SDL_INPUT_LINUXEV 1 +#define SDL_JOYSTICK_LINUX 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_LINUX 1 + +#define SDL_SENSOR_DUMMY 1 + +#define SDL_LOADSO_DLOPEN 1 + +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1 + +#define SDL_TIMER_UNIX 1 +#define SDL_FILESYSTEM_UNIX 1 + +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_X11 1 +#define SDL_VIDEO_DRIVER_PANDORA 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_OPENGL_ES 1 + +#endif /* SDL_config_pandora_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_windows.h b/thirdparty/SDL/include/SDL/SDL_config_windows.h new file mode 100644 index 00000000..3ad3e8ff --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_windows.h @@ -0,0 +1,351 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_windows_h_ +#define SDL_config_windows_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* winsdkver.h defines _WIN32_MAXVER for SDK version detection. It is present since at least the Windows 7 SDK, + * but out of caution we'll only use it if the compiler supports __has_include() to confirm its presence. + * If your compiler doesn't support __has_include() but you have winsdkver.h, define HAVE_WINSDKVER_H. */ +#if !defined(HAVE_WINSDKVER_H) && defined(__has_include) +#if __has_include() +#define HAVE_WINSDKVER_H 1 +#endif +#endif + +#ifdef HAVE_WINSDKVER_H +#include +#endif + +/* sdkddkver.h defines more specific SDK version numbers. This is needed because older versions of the + * Windows 10 SDK have broken declarations for the C API for DirectX 12. */ +#if !defined(HAVE_SDKDDKVER_H) && defined(__has_include) +#if __has_include() +#define HAVE_SDKDDKVER_H 1 +#endif +#endif + +#ifdef HAVE_SDKDDKVER_H +#include +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) || defined(__clang__) || defined(__BORLANDC__) || defined(__CODEGEARC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +#ifndef __WATCOMC__ +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0A00 /* Windows 10 SDK */ +#define HAVE_WINDOWS_GAMING_INPUT_H 1 +#endif +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602 /* Windows 8 SDK */ +#define HAVE_D3D11_H 1 +#define HAVE_ROAPI_H 1 +#endif +#if defined(WDK_NTDDI_VERSION) && WDK_NTDDI_VERSION > 0x0A000008 /* 10.0.19041.0 */ +#define HAVE_D3D12_H 1 +#endif +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0603 /* Windows 8.1 SDK */ +#define HAVE_SHELLSCALINGAPI_H 1 +#endif +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 +#define HAVE_SENSORSAPI_H 1 +#endif +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#ifndef __WATCOMC__ +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_EXPF 1 +#define HAVE_FABSF 1 +#define HAVE_FLOORF 1 +#define HAVE_FMODF 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10F 1 +#define HAVE_POWF 1 +#define HAVE_SINF 1 +#define HAVE_SQRTF 1 +#define HAVE_TANF 1 +#endif +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#if _MSC_VER >= 1800 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#endif +/* This function is available with at least the VC++ 2008 C runtime library */ +#if _MSC_VER >= 1400 +#define HAVE__FSEEKI64 1 +#endif +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 +#endif +#elif defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_ROUND 1 +#define HAVE_SCALBN 1 +#define HAVE_TRUNC 1 +#else +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) +#define SDL_AUDIO_DRIVER_WASAPI 1 +#endif +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#ifndef __WINRT__ +#define SDL_JOYSTICK_RAWINPUT 1 +#endif +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +#endif /* SDL_config_windows_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_wingdk.h b/thirdparty/SDL/include/SDL/SDL_config_wingdk.h new file mode 100644 index 00000000..d456024f --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_wingdk.h @@ -0,0 +1,285 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_wingdk_h_ +#define SDL_config_wingdk_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Windows GDK does not need Windows SDK version checks because it requires + * a recent version of the Windows 10 SDK. */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +/* At this time, only recent MSVC or clang are supported by Windows GDK */ +#if defined(__clang__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +typedef unsigned __int64 uintptr_t; +#define _UINTPTR_T_DEFINED +#endif +#else /* !__clang__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __clang__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +/* GDK only supports 64-bit */ +# define SIZEOF_VOIDP 8 + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +/* No SDK version checks needed for these because the SDK has to be new. */ +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 +#define HAVE_WINDOWS_GAMING_INPUT_H 1 +#define HAVE_D3D11_H 1 +#define HAVE_ROAPI_H 1 +#define HAVE_D3D12_H 1 +#define HAVE_SHELLSCALINGAPI_H 1 +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 +#define HAVE_SENSORSAPI_H 1 +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_EXPF 1 +#define HAVE_FABSF 1 +#define HAVE_FLOORF 1 +#define HAVE_FMODF 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10F 1 +#define HAVE_POWF 1 +#define HAVE_SINF 1 +#define HAVE_SQRTF 1 +#define HAVE_TANF 1 +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) +#define SDL_AUDIO_DRIVER_WASAPI 1 +#endif +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_RAWINPUT 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +#endif /* SDL_config_wingdk_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_winrt.h b/thirdparty/SDL/include/SDL/SDL_config_winrt.h new file mode 100644 index 00000000..55694036 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_winrt.h @@ -0,0 +1,263 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_winrt_h_ +#define SDL_config_winrt_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Make sure the Windows SDK's NTDDI_VERSION macro gets defined. This is used + by SDL to determine which version of the Windows SDK is being used. +*/ +#include + +/* Define possibly-undefined NTDDI values (used when compiling SDL against + older versions of the Windows SDK. +*/ +#ifndef NTDDI_WINBLUE +#define NTDDI_WINBLUE 0x06030000 +#endif +#ifndef NTDDI_WIN10 +#define NTDDI_WIN10 0x0A000000 +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +/* Useful headers */ +#define HAVE_DXGI_H 1 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#define HAVE_XINPUT_H 1 +#endif + +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 + +#define HAVE_LIBC 1 +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE_STRTOLL */ +/* #undef HAVE_STRTOULL */ +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_VSNPRINTF 1 +/* TODO, WinRT: consider using ??_s versions of the following */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +/* #undef HAVE_SSCANF */ +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE__SCALB 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 + +#define HAVE_ROAPI_H 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_WASAPI 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_VIRTUAL 1 +#if (NTDDI_VERSION >= NTDDI_WIN10) +#define SDL_JOYSTICK_WGI 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_XINPUT 1 +#endif /* WIN10 */ +#endif + +/* WinRT doesn't have HIDAPI available */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 +#else +/* WinRT on Windows 8.0 and Windows Phone 8.0 don't support CreateThread() */ +#define SDL_THREAD_STDCPP 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_WINRT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 + +/* Enable appropriate renderer(s) */ +#define SDL_VIDEO_RENDER_D3D11 1 + +/* Disable D3D12 as it's not implemented for WinRT */ +#define SDL_VIDEO_RENDER_D3D12 0 + +#if SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_WINRT 1 + +#endif /* SDL_config_winrt_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_config_xbox.h b/thirdparty/SDL/include/SDL/SDL_config_xbox.h new file mode 100644 index 00000000..4e68e9f9 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_config_xbox.h @@ -0,0 +1,267 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_wingdk_h_ +#define SDL_config_wingdk_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Windows GDK does not need Windows SDK version checks because it requires + * a recent version of the Windows 10 SDK. */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +/* At this time, only recent MSVC or clang are supported by Windows GDK */ +#if defined(__clang__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +typedef unsigned __int64 uintptr_t; +#define _UINTPTR_T_DEFINED +#endif +#else /* !__clang__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __clang__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +/* GDK only supports 64-bit */ +# define SIZEOF_VOIDP 8 + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +/*#define HAVE_DDRAW_H 1*/ +/*#define HAVE_DINPUT_H 1*/ +/*#define HAVE_DSOUND_H 1*/ +/* No SDK version checks needed for these because the SDK has to be new. */ +/* #define HAVE_DXGI_H 1 */ +#define HAVE_XINPUT_H 1 +/*#define HAVE_WINDOWS_GAMING_INPUT_H 1*/ +/*#define HAVE_D3D11_H 1*/ +/*#define HAVE_ROAPI_H 1*/ +#define HAVE_D3D12_H 1 +/*#define HAVE_SHELLSCALINGAPI_H 1*/ +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +/*#define HAVE_TPCSHRD_H 1*/ +/*#define HAVE_SENSORSAPI_H 1*/ +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_EXPF 1 +#define HAVE_FABSF 1 +#define HAVE_FLOORF 1 +#define HAVE_FMODF 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10F 1 +#define HAVE_POWF 1 +#define HAVE_SINF 1 +#define HAVE_SQRTF 1 +#define HAVE_TANF 1 +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) +#define SDL_AUDIO_DRIVER_WASAPI 1 +#endif +/*#define SDL_AUDIO_DRIVER_DSOUND 1*/ +/*#define SDL_AUDIO_DRIVER_WINMM 1*/ +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +/*#define SDL_JOYSTICK_DINPUT 1*/ +/*#define SDL_JOYSTICK_HIDAPI 1*/ +/*#define SDL_JOYSTICK_RAWINPUT 1*/ +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +/*#define SDL_HAPTIC_DINPUT 1*/ +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +/* #ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif*/ +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 +#endif + +/* Enable system power support */ +/*#define SDL_POWER_WINDOWS 1*/ +#define SDL_POWER_HARDWIRED 1 + +/* Enable filesystem support */ +/* #define SDL_FILESYSTEM_WINDOWS 1*/ +#define SDL_FILESYSTEM_XBOX 1 + +/* Disable IME as not supported yet (TODO: Xbox IME?) */ +#define SDL_DISABLE_WINDOWS_IME 1 + +#endif /* SDL_config_wingdk_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_copying.h b/thirdparty/SDL/include/SDL/SDL_copying.h new file mode 100644 index 00000000..49e3f9da --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_copying.h @@ -0,0 +1,20 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ diff --git a/thirdparty/SDL/include/SDL/SDL_cpuinfo.h b/thirdparty/SDL/include/SDL/SDL_cpuinfo.h new file mode 100644 index 00000000..43a8ac50 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_cpuinfo.h @@ -0,0 +1,593 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef SDL_cpuinfo_h_ +#define SDL_cpuinfo_h_ + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#ifdef __clang__ +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ + +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} + +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ +#include +#ifndef _WIN64 +#ifndef __MMX__ +#define __MMX__ +#endif +#ifndef __3dNOW__ +#define __3dNOW__ +#endif +#endif +#ifndef __SSE__ +#define __SSE__ +#endif +#ifndef __SSE2__ +#define __SSE2__ +#endif +#ifndef __SSE3__ +#define __SSE3__ +#endif +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) +# include +#endif +#else +/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ +#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) +#include +#endif +#if !defined(SDL_DISABLE_ARM_NEON_H) +# if defined(__ARM_NEON) +# include +# elif defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined(_M_ARM) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# if defined (_M_ARM64) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# endif +#endif +#endif /* compiler version */ + +#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) +#include +#endif +#if defined(__loongarch_sx) && !defined(SDL_DISABLE_LSX_H) +#include +#define __LSX__ +#endif +#if defined(__loongarch_asx) && !defined(SDL_DISABLE_LASX_H) +#include +#define __LASX__ +#endif +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#include +#else +#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) +#include +#endif +#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) +#include +#endif +#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) +#include +#endif +#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) +#include +#endif +#endif /* HAVE_IMMINTRIN_H */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * Get the number of CPU cores available. + * + * \returns the total number of logical CPU cores. On CPUs that include + * technologies such as hyperthreading, the number of logical cores + * may be more than the number of physical cores. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * Determine the L1 cache line size of the CPU. + * + * This is useful for determining multi-threaded structure padding or SIMD + * prefetch sizes. + * + * \returns the L1 cache line size of the CPU, in bytes. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * Determine whether the CPU has the RDTSC instruction. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * Determine whether the CPU has AltiVec features. + * + * This always returns false on CPUs that aren't using PowerPC instruction + * sets. + * + * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * Determine whether the CPU has MMX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * Determine whether the CPU has 3DNow! features. + * + * This always returns false on CPUs that aren't using AMD instruction sets. + * + * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * Determine whether the CPU has SSE features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * Determine whether the CPU has SSE2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * Determine whether the CPU has SSE3 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * Determine whether the CPU has SSE4.1 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * Determine whether the CPU has SSE4.2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * Determine whether the CPU has AVX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * Determine whether the CPU has AVX2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * Determine whether the CPU has AVX-512F (foundation) features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_HasAVX + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); + +/** + * Determine whether the CPU has ARM SIMD (ARMv6) features. + * + * This is different from ARM NEON, which is a different instruction set. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_HasNEON + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); + +/** + * Determine whether the CPU has NEON (ARM SIMD) features. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); + +/** + * Determine whether the CPU has LSX (LOONGARCH SIMD) features. + * + * This always returns false on CPUs that aren't using LOONGARCH instruction + * sets. + * + * \returns SDL_TRUE if the CPU has LOONGARCH LSX features or SDL_FALSE if + * not. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasLSX(void); + +/** + * Determine whether the CPU has LASX (LOONGARCH SIMD) features. + * + * This always returns false on CPUs that aren't using LOONGARCH instruction + * sets. + * + * \returns SDL_TRUE if the CPU has LOONGARCH LASX features or SDL_FALSE if + * not. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasLASX(void); + +/** + * Get the amount of RAM configured in the system. + * + * \returns the amount of RAM configured in the system in MiB. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + +/** + * Report the alignment this system needs for SIMD allocations. + * + * This will return the minimum number of bytes to which a pointer must be + * aligned to be compatible with SIMD instructions on the current machine. For + * example, if the machine supports SSE only, it will return 16, but if it + * supports AVX-512F, it'll return 64 (etc). This only reports values for + * instruction sets SDL knows about, so if your SDL build doesn't have + * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and + * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. + * Plan accordingly. + * + * \returns the alignment in bytes needed for available, known SIMD + * instructions. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); + +/** + * Allocate memory in a SIMD-friendly way. + * + * This will allocate a block of memory that is suitable for use with SIMD + * instructions. Specifically, it will be properly aligned and padded for the + * system's supported vector instructions. + * + * The memory returned will be padded such that it is safe to read or write an + * incomplete vector at the end of the memory block. This can be useful so you + * don't have to drop back to a scalar fallback at the end of your SIMD + * processing loop to deal with the final elements without overflowing the + * allocated buffer. + * + * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or + * delete[], etc. + * + * Note that SDL will only deal with SIMD instruction sets it is aware of; for + * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and + * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants + * 64. To be clear: if you can't decide to use an instruction set with an + * SDL_Has*() function, don't use that instruction set with memory allocated + * through here. + * + * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't + * out of memory, but you are not allowed to dereference it (because you only + * own zero bytes of that buffer). + * + * \param len The length, in bytes, of the block to allocate. The actual + * allocated block might be larger due to padding, etc. + * \returns a pointer to the newly-allocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDRealloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); + +/** + * Reallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, + * SDL_malloc, memalign, new[], etc. + * + * \param mem The pointer obtained from SDL_SIMDAlloc. This function also + * accepts NULL, at which point this function is the same as + * calling SDL_SIMDAlloc with a NULL pointer. + * \param len The length, in bytes, of the block to allocated. The actual + * allocated block might be larger due to padding, etc. Passing 0 + * will return a non-NULL pointer, assuming the system isn't out of + * memory. + * \returns a pointer to the newly-reallocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); + +/** + * Deallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from + * malloc, realloc, SDL_malloc, memalign, new[], etc. + * + * However, SDL_SIMDFree(NULL) is a legal no-op. + * + * The memory pointed to by `ptr` is no longer valid for access upon return, + * and may be returned to the system or reused by a future allocation. The + * pointer passed to this function is no longer safe to dereference once this + * function returns, and should be discarded. + * + * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to + * deallocate. NULL is a legal no-op. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDRealloc + */ +extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_cpuinfo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_egl.h b/thirdparty/SDL/include/SDL/SDL_egl.h new file mode 100644 index 00000000..f90e27b2 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_egl.h @@ -0,0 +1,2302 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_egl.h + * + * This is a simple file to encapsulate the EGL API headers. + */ +#if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) + +#if defined(__vita__) || defined(__psp2__) +#include +#endif + +#include +#include + +#else /* _MSC_VER */ + +/* EGL headers for Visual Studio */ + +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ + + +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* Platform-specific types and definitions for egl.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ + */ + +/*#include */ + +/* Macros used in EGL function prototype declarations. + * + * EGL functions should be prototyped as: + * + * EGLAPI return-type EGLAPIENTRY eglFunction(arguments); + * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); + * + * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h + */ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType + * are aliases of window-system-dependent types, such as X Display * or + * Windows Device Context. They must be defined in platform-specific + * code below. The EGL-prefixed versions of Native*Type are the same + * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. + */ + +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include + +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; + +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__ANDROID__) || defined(ANDROID) + +struct ANativeWindow; +struct egl_native_pixmap_t; + +typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; + +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; + +#elif defined(USE_X11) + +/* X11 (tentative) */ +#include +#include + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef khronos_int32_t EGLint; + + +/* C++ / C typecast macros for special EGL handle values */ +#if defined(__cplusplus) +#define EGL_CAST(type, value) (static_cast(value)) +#else +#define EGL_CAST(type, value) ((type) (value)) +#endif + +#endif /* __eglplatform_h */ + + +#ifndef __egl_h_ +#define __egl_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +** +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.khronos.org/registry/egl +** +** Khronos $Git commit SHA1: b35e89ca9a $ on $Git commit date: 2021-09-01 09:34:00 +0530 $ +*/ + +/*#include */ + +#ifndef EGL_EGL_PROTOTYPES +#define EGL_EGL_PROTOTYPES 1 +#endif + +/* Generated on date 20210901 */ + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_VERSION_1_0 +#define EGL_VERSION_1_0 1 +typedef unsigned int EGLBoolean; +typedef void *EGLDisplay; +/*#include */ +/*#include */ +typedef void *EGLConfig; +typedef void *EGLSurface; +typedef void *EGLContext; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BLUE_SIZE 0x3022 +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_CORE_NATIVE_ENGINE 0x305B +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_DONT_CARE EGL_CAST(EGLint,-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_HEIGHT 0x3056 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_NONE 0x3038 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_READ 0x305A +#define EGL_RED_SIZE 0x3024 +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SUCCESS 0x3000 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRUE 1 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_WIDTH 0x3057 +#define EGL_WINDOW_BIT 0x0004 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void); +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw); +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id); +EGLAPI EGLint EGLAPIENTRY eglGetError (void); +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif +#endif /* EGL_VERSION_1_0 */ + +#ifndef EGL_VERSION_1_1 +#define EGL_VERSION_1_1 1 +#define EGL_BACK_BUFFER 0x3084 +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_CONTEXT_LOST 0x300E +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_TARGET 0x3081 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif +#endif /* EGL_VERSION_1_1 */ + +#ifndef EGL_VERSION_1_2 +#define EGL_VERSION_1_2 1 +typedef unsigned int EGLenum; +typedef void *EGLClientBuffer; +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_CLIENT_APIS 0x308D +#define EGL_COLORSPACE 0x3087 +#define EGL_COLORSPACE_sRGB 0x3089 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_DISPLAY_SCALING 10000 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_RGB_BUFFER 0x308E +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_UNKNOWN EGL_CAST(EGLint,-1) +#define EGL_VERTICAL_RESOLUTION 0x3091 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif +#endif /* EGL_VERSION_1_2 */ + +#ifndef EGL_VERSION_1_3 +#define EGL_VERSION_1_3 1 +#define EGL_CONFORMANT 0x3042 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_COLORSPACE_sRGB 0x3089 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#endif /* EGL_VERSION_1_3 */ + +#ifndef EGL_VERSION_1_4 +#define EGL_VERSION_1_4 1 +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_OPENGL_API 0x30A2 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif +#endif /* EGL_VERSION_1_4 */ + +#ifndef EGL_VERSION_1_5 +#define EGL_VERSION_1_5 1 +typedef void *EGLSync; +typedef intptr_t EGLAttrib; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef void *EGLImage; +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SIGNALED 0x30F2 +#define EGL_UNSIGNALED 0x30F3 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_NO_SYNC EGL_CAST(EGLSync,0) +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image); +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif +#endif /* EGL_VERSION_1_5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __egl_h_ */ + + +#ifndef __eglext_h_ +#define __eglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +** +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.khronos.org/registry/egl +** +** Khronos $Git commit SHA1: b35e89ca9a $ on $Git commit date: 2021-09-01 09:34:00 +0530 $ +*/ + +/*#include */ + +#define EGL_EGLEXT_VERSION 20210901 + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: egl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#endif /* EGL_KHR_cl_event */ + +#ifndef EGL_KHR_cl_event2 +#define EGL_KHR_cl_event2 1 +typedef void *EGLSyncKHR; +typedef intptr_t EGLAttribKHR; +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#endif +#endif /* EGL_KHR_cl_event2 */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#endif /* EGL_KHR_config_attribs */ + +#ifndef EGL_KHR_context_flush_control +#define EGL_KHR_context_flush_control 1 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#endif /* EGL_KHR_context_flush_control */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#endif /* EGL_KHR_create_context */ + +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 +#endif /* EGL_KHR_create_context_no_error */ + +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value); +typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value); +EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#endif +#endif /* EGL_KHR_debug */ + +#ifndef EGL_KHR_display_reference +#define EGL_KHR_display_reference 1 +#define EGL_TRACK_REFERENCES_KHR 0x3352 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#endif +#endif /* EGL_KHR_display_reference */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_fence_sync */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 +#endif /* EGL_KHR_get_all_proc_addresses */ + +#ifndef EGL_KHR_gl_colorspace +#define EGL_KHR_gl_colorspace 1 +#define EGL_GL_COLORSPACE_KHR 0x309D +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#endif /* EGL_KHR_gl_colorspace */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 +#endif /* EGL_KHR_gl_renderbuffer_image */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC +#endif /* EGL_KHR_gl_texture_2D_image */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD +#endif /* EGL_KHR_gl_texture_3D_image */ + +#ifndef EGL_KHR_gl_texture_cubemap_image +#define EGL_KHR_gl_texture_cubemap_image 1 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +typedef void *EGLImageKHR; +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0) +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_KHR_image */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif /* EGL_KHR_image_base */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +#endif /* EGL_KHR_image_pixmap */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface); +#endif +#endif /* EGL_KHR_lock_surface */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif /* EGL_KHR_lock_surface2 */ + +#ifndef EGL_KHR_lock_surface3 +#define EGL_KHR_lock_surface3 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#endif +#endif /* EGL_KHR_lock_surface3 */ + +#ifndef EGL_KHR_mutable_render_buffer +#define EGL_KHR_mutable_render_buffer 1 +#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 +#endif /* EGL_KHR_mutable_render_buffer */ + +#ifndef EGL_KHR_no_config_context +#define EGL_KHR_no_config_context 1 +#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) +#endif /* EGL_KHR_no_config_context */ + +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 +#define EGL_BUFFER_AGE_KHR 0x313D +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_partial_update */ + +#ifndef EGL_KHR_platform_android +#define EGL_KHR_platform_android 1 +#define EGL_PLATFORM_ANDROID_KHR 0x3141 +#endif /* EGL_KHR_platform_android */ + +#ifndef EGL_KHR_platform_gbm +#define EGL_KHR_platform_gbm 1 +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif /* EGL_KHR_platform_gbm */ + +#ifndef EGL_KHR_platform_wayland +#define EGL_KHR_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#endif /* EGL_KHR_platform_wayland */ + +#ifndef EGL_KHR_platform_x11 +#define EGL_KHR_platform_x11 1 +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 +#endif /* EGL_KHR_platform_x11 */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0) +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_reusable_sync */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0) +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_PRODUCER_FRAME_KHR 0x3212 +#define EGL_CONSUMER_FRAME_KHR 0x3213 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 +#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 +#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 +#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 +#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A +#define EGL_BAD_STREAM_KHR 0x321B +#define EGL_BAD_STATE_KHR 0x321C +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream */ + +#ifndef EGL_KHR_stream_attrib +#define EGL_KHR_stream_attrib 1 +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream_attrib */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#ifdef EGL_KHR_stream +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_consumer_gltexture */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#ifdef EGL_KHR_stream +#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1) +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_cross_process_fd */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC +#define EGL_STREAM_TIME_NOW_KHR 0x31FD +#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE +#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_fifo */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#ifdef EGL_KHR_stream +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_BIT_KHR 0x0800 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_eglsurface */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +#endif /* EGL_KHR_surfaceless_context */ + +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_swap_buffers_with_damage */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA +#endif /* EGL_KHR_vg_parent_image */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif +#endif /* EGL_KHR_wait_sync */ + +#ifndef EGL_ANDROID_GLES_layers +#define EGL_ANDROID_GLES_layers 1 +#endif /* EGL_ANDROID_GLES_layers */ + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif +#endif /* EGL_ANDROID_blob_cache */ + +#ifndef EGL_ANDROID_create_native_client_buffer +#define EGL_ANDROID_create_native_client_buffer 1 +#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 +#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 +#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 +#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list); +#endif +#endif /* EGL_ANDROID_create_native_client_buffer */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif /* EGL_ANDROID_framebuffer_target */ + +#ifndef EGL_ANDROID_front_buffer_auto_refresh +#define EGL_ANDROID_front_buffer_auto_refresh 1 +#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C +#endif /* EGL_ANDROID_front_buffer_auto_refresh */ + +#ifndef EGL_ANDROID_get_frame_timestamps +#define EGL_ANDROID_get_frame_timestamps 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2) +#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1) +#define EGL_TIMESTAMPS_ANDROID 0x3430 +#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 +#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 +#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 +#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 +#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 +#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 +#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 +#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 +#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A +#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B +#define EGL_READS_DONE_TIME_ANDROID 0x343C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#endif +#endif /* EGL_ANDROID_get_frame_timestamps */ + +#ifndef EGL_ANDROID_get_native_client_buffer +#define EGL_ANDROID_get_native_client_buffer 1 +struct AHardwareBuffer; +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#endif +#endif /* EGL_ANDROID_get_native_client_buffer */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif /* EGL_ANDROID_image_native_buffer */ + +#ifndef EGL_ANDROID_native_fence_sync +#define EGL_ANDROID_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 +#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 +#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_ANDROID_native_fence_sync */ + +#ifndef EGL_ANDROID_presentation_time +#define EGL_ANDROID_presentation_time 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#endif +#endif /* EGL_ANDROID_presentation_time */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif /* EGL_ANDROID_recordable */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 +#endif /* EGL_ANGLE_device_d3d */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +#endif /* EGL_ANGLE_query_surface_pointer */ + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +#ifndef EGL_ANGLE_sync_control_rate +#define EGL_ANGLE_sync_control_rate 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#endif +#endif /* EGL_ANGLE_sync_control_rate */ + +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 +#define EGL_FIXED_SIZE_ANGLE 0x3201 +#endif /* EGL_ANGLE_window_fixed_size */ + +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A +#endif /* EGL_ARM_implicit_external_sync */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 +#define EGL_DISCARD_SAMPLES_ARM 0x3286 +#endif /* EGL_ARM_pixmap_multisample_discard */ + +#ifndef EGL_EXT_bind_to_front +#define EGL_EXT_bind_to_front 1 +#define EGL_FRONT_BUFFER_EXT 0x3464 +#endif /* EGL_EXT_bind_to_front */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif /* EGL_EXT_buffer_age */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 +#endif /* EGL_EXT_client_extensions */ + +#ifndef EGL_EXT_client_sync +#define EGL_EXT_client_sync 1 +#define EGL_SYNC_CLIENT_EXT 0x3364 +#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_client_sync */ + +#ifndef EGL_EXT_compositor +#define EGL_EXT_compositor 1 +#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 +#define EGL_EXTERNAL_REF_ID_EXT 0x3461 +#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462 +#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy); +#endif +#endif /* EGL_EXT_compositor */ + +#ifndef EGL_EXT_config_select_group +#define EGL_EXT_config_select_group 1 +#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0 +#endif /* EGL_EXT_config_select_group */ + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif /* EGL_EXT_create_context_robustness */ + +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 +typedef void *EGLDeviceEXT; +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#endif +#endif /* EGL_EXT_device_base */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C +#endif /* EGL_EXT_device_drm */ + +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 +#endif /* EGL_EXT_device_enumeration */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#define EGL_OPENWF_DEVICE_EXT 0x333D +#endif /* EGL_EXT_device_openwf */ + +#ifndef EGL_EXT_device_persistent_id +#define EGL_EXT_device_persistent_id 1 +#define EGL_DEVICE_UUID_EXT 0x335C +#define EGL_DRIVER_UUID_EXT 0x335D +#define EGL_DRIVER_NAME_EXT 0x335E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#endif +#endif /* EGL_EXT_device_persistent_id */ + +#ifndef EGL_EXT_device_query +#define EGL_EXT_device_query 1 +#endif /* EGL_EXT_device_query */ + +#ifndef EGL_EXT_device_query_name +#define EGL_EXT_device_query_name 1 +#define EGL_RENDERER_EXT 0x335F +#endif /* EGL_EXT_device_query_name */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_linear +#define EGL_EXT_gl_colorspace_bt2020_linear 1 +#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F +#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_pq +#define EGL_EXT_gl_colorspace_bt2020_pq 1 +#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 +#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ + +#ifndef EGL_EXT_gl_colorspace_display_p3 +#define EGL_EXT_gl_colorspace_display_p3 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363 +#endif /* EGL_EXT_gl_colorspace_display_p3 */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_linear +#define EGL_EXT_gl_colorspace_display_p3_linear 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 +#endif /* EGL_EXT_gl_colorspace_display_p3_linear */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough +#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 +#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ + +#ifndef EGL_EXT_gl_colorspace_scrgb +#define EGL_EXT_gl_colorspace_scrgb 1 +#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 +#endif /* EGL_EXT_gl_colorspace_scrgb */ + +#ifndef EGL_EXT_gl_colorspace_scrgb_linear +#define EGL_EXT_gl_colorspace_scrgb_linear 1 +#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 +#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ + +#ifndef EGL_EXT_image_dma_buf_import +#define EGL_EXT_image_dma_buf_import 1 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#endif /* EGL_EXT_image_dma_buf_import */ + +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#endif +#endif /* EGL_EXT_image_dma_buf_import_modifiers */ + +#ifndef EGL_EXT_image_gl_colorspace +#define EGL_EXT_image_gl_colorspace 1 +#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D +#endif /* EGL_EXT_image_gl_colorspace */ + +#ifndef EGL_EXT_image_implicit_sync_control +#define EGL_EXT_image_implicit_sync_control 1 +#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 +#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471 +#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472 +#endif /* EGL_EXT_image_implicit_sync_control */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif /* EGL_EXT_multiview_window */ + +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0) +#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0) +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#endif +#endif /* EGL_EXT_output_base */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 +#endif /* EGL_EXT_output_drm */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 +#endif /* EGL_EXT_output_openwf */ + +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float 1 +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B +#endif /* EGL_EXT_pixel_format_float */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#endif +#endif /* EGL_EXT_platform_base */ + +#ifndef EGL_EXT_platform_device +#define EGL_EXT_platform_device 1 +#define EGL_PLATFORM_DEVICE_EXT 0x313F +#endif /* EGL_EXT_platform_device */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#endif /* EGL_EXT_platform_wayland */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 +#endif /* EGL_EXT_platform_x11 */ + +#ifndef EGL_EXT_platform_xcb +#define EGL_EXT_platform_xcb 1 +#define EGL_PLATFORM_XCB_EXT 0x31DC +#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE +#endif /* EGL_EXT_platform_xcb */ + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + +#ifndef EGL_EXT_protected_content +#define EGL_EXT_protected_content 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_content */ + +#ifndef EGL_EXT_protected_surface +#define EGL_EXT_protected_surface 1 +#endif /* EGL_EXT_protected_surface */ + +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#endif +#endif /* EGL_EXT_stream_consumer_egloutput */ + +#ifndef EGL_EXT_surface_CTA861_3_metadata +#define EGL_EXT_surface_CTA861_3_metadata 1 +#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360 +#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361 +#endif /* EGL_EXT_surface_CTA861_3_metadata */ + +#ifndef EGL_EXT_surface_SMPTE2086_metadata +#define EGL_EXT_surface_SMPTE2086_metadata 1 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 +#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 +#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 +#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 +#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A +#define EGL_METADATA_SCALING_EXT 50000 +#endif /* EGL_EXT_surface_SMPTE2086_metadata */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_EXT_swap_buffers_with_damage */ + +#ifndef EGL_EXT_sync_reuse +#define EGL_EXT_sync_reuse 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_sync_reuse */ + +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D +#endif /* EGL_EXT_yuv_surface */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#endif +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_IMG_context_priority +#define EGL_IMG_context_priority 1 +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif /* EGL_IMG_context_priority */ + +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 +#endif /* EGL_IMG_image_plane_attribs */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif +#endif /* EGL_MESA_drm_image */ + +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#endif +#endif /* EGL_MESA_image_dma_buf_export */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif /* EGL_MESA_platform_gbm */ + +#ifndef EGL_MESA_platform_surfaceless +#define EGL_MESA_platform_surfaceless 1 +#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD +#endif /* EGL_MESA_platform_surfaceless */ + +#ifndef EGL_MESA_query_driver +#define EGL_MESA_query_driver 1 +typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); +typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy); +EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy); +#endif +#endif /* EGL_MESA_query_driver */ + +#ifndef EGL_NOK_swap_region +#define EGL_NOK_swap_region 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region */ + +#ifndef EGL_NOK_swap_region2 +#define EGL_NOK_swap_region2 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region2 */ + +#ifndef EGL_NOK_texture_from_pixmap +#define EGL_NOK_texture_from_pixmap 1 +#define EGL_Y_INVERTED_NOK 0x307F +#endif /* EGL_NOK_texture_from_pixmap */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif /* EGL_NV_3dvision_surface */ + +#ifndef EGL_NV_context_priority_realtime +#define EGL_NV_context_priority_realtime 1 +#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 +#endif /* EGL_NV_context_priority_realtime */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif /* EGL_NV_coverage_sample */ + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif /* EGL_NV_coverage_sample_resolve */ + +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D +#endif /* EGL_NV_cuda_event */ + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#endif /* EGL_NV_depth_nonlinear */ + +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 +#define EGL_CUDA_DEVICE_NV 0x323A +#endif /* EGL_NV_device_cuda */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#endif +#endif /* EGL_NV_native_query */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +#endif /* EGL_NV_post_convert_rounding */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif +#endif /* EGL_NV_post_sub_buffer */ + +#ifndef EGL_NV_quadruple_buffer +#define EGL_NV_quadruple_buffer 1 +#define EGL_QUADRUPLE_BUFFER_NV 0x3231 +#endif /* EGL_NV_quadruple_buffer */ + +#ifndef EGL_NV_robustness_video_memory_purge +#define EGL_NV_robustness_video_memory_purge 1 +#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#endif /* EGL_NV_robustness_video_memory_purge */ + +#ifndef EGL_NV_stream_consumer_eglimage +#define EGL_NV_stream_consumer_eglimage 1 +#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373 +#define EGL_STREAM_IMAGE_ADD_NV 0x3374 +#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375 +#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#endif +#endif /* EGL_NV_stream_consumer_eglimage */ + +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +#ifndef EGL_NV_stream_cross_display +#define EGL_NV_stream_cross_display 1 +#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E +#endif /* EGL_NV_stream_cross_display */ + +#ifndef EGL_NV_stream_cross_object +#define EGL_NV_stream_cross_object 1 +#define EGL_STREAM_CROSS_OBJECT_NV 0x334D +#endif /* EGL_NV_stream_cross_object */ + +#ifndef EGL_NV_stream_cross_partition +#define EGL_NV_stream_cross_partition 1 +#define EGL_STREAM_CROSS_PARTITION_NV 0x323F +#endif /* EGL_NV_stream_cross_partition */ + +#ifndef EGL_NV_stream_cross_process +#define EGL_NV_stream_cross_process 1 +#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 +#endif /* EGL_NV_stream_cross_process */ + +#ifndef EGL_NV_stream_cross_system +#define EGL_NV_stream_cross_system 1 +#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F +#endif /* EGL_NV_stream_cross_system */ + +#ifndef EGL_NV_stream_dma +#define EGL_NV_stream_dma 1 +#define EGL_STREAM_DMA_NV 0x3371 +#define EGL_STREAM_DMA_SERVER_NV 0x3372 +#endif /* EGL_NV_stream_dma */ + +#ifndef EGL_NV_stream_fifo_next +#define EGL_NV_stream_fifo_next 1 +#define EGL_PENDING_FRAME_NV 0x3329 +#define EGL_STREAM_TIME_PENDING_NV 0x332A +#endif /* EGL_NV_stream_fifo_next */ + +#ifndef EGL_NV_stream_fifo_synchronous +#define EGL_NV_stream_fifo_synchronous 1 +#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 +#endif /* EGL_NV_stream_fifo_synchronous */ + +#ifndef EGL_NV_stream_flush +#define EGL_NV_stream_flush 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_flush */ + +#ifndef EGL_NV_stream_frame_limits +#define EGL_NV_stream_frame_limits 1 +#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 +#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 +#endif /* EGL_NV_stream_frame_limits */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_PENDING_METADATA_NV 0x3328 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#endif +#endif /* EGL_NV_stream_metadata */ + +#ifndef EGL_NV_stream_origin +#define EGL_NV_stream_origin 1 +#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 +#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 +#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 +#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 +#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A +#define EGL_LEFT_NV 0x336B +#define EGL_RIGHT_NV 0x336C +#define EGL_TOP_NV 0x336D +#define EGL_BOTTOM_NV 0x336E +#define EGL_X_AXIS_NV 0x336F +#define EGL_Y_AXIS_NV 0x3370 +#endif /* EGL_NV_stream_origin */ + +#ifndef EGL_NV_stream_remote +#define EGL_NV_stream_remote 1 +#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 +#define EGL_STREAM_TYPE_NV 0x3241 +#define EGL_STREAM_PROTOCOL_NV 0x3242 +#define EGL_STREAM_ENDPOINT_NV 0x3243 +#define EGL_STREAM_LOCAL_NV 0x3244 +#define EGL_STREAM_PRODUCER_NV 0x3247 +#define EGL_STREAM_CONSUMER_NV 0x3248 +#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 +#endif /* EGL_NV_stream_remote */ + +#ifndef EGL_NV_stream_reset +#define EGL_NV_stream_reset 1 +#define EGL_SUPPORT_RESET_NV 0x3334 +#define EGL_SUPPORT_REUSE_NV 0x3335 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_reset */ + +#ifndef EGL_NV_stream_socket +#define EGL_NV_stream_socket 1 +#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B +#define EGL_SOCKET_HANDLE_NV 0x324C +#define EGL_SOCKET_TYPE_NV 0x324D +#endif /* EGL_NV_stream_socket */ + +#ifndef EGL_NV_stream_socket_inet +#define EGL_NV_stream_socket_inet 1 +#define EGL_SOCKET_TYPE_INET_NV 0x324F +#endif /* EGL_NV_stream_socket_inet */ + +#ifndef EGL_NV_stream_socket_unix +#define EGL_NV_stream_socket_unix 1 +#define EGL_SOCKET_TYPE_UNIX_NV 0x324E +#endif /* EGL_NV_stream_socket_unix */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 +#define EGL_SYNC_NEW_FRAME_NV 0x321F +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#endif +#endif /* EGL_NV_stream_sync */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 +#define EGL_SYNC_STATUS_NV 0x30E7 +#define EGL_SIGNALED_NV 0x30E8 +#define EGL_UNSIGNALED_NV 0x30E9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull +#define EGL_ALREADY_SIGNALED_NV 0x30EA +#define EGL_TIMEOUT_EXPIRED_NV 0x30EB +#define EGL_CONDITION_SATISFIED_NV 0x30EC +#define EGL_SYNC_TYPE_NV 0x30ED +#define EGL_SYNC_CONDITION_NV 0x30EE +#define EGL_SYNC_FENCE_NV 0x30EF +#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0) +typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); +EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_sync */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_system_time */ + +#ifndef EGL_NV_triple_buffer +#define EGL_NV_triple_buffer 1 +#define EGL_TRIPLE_BUFFER_NV 0x3230 +#endif /* EGL_NV_triple_buffer */ + +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 +#endif /* EGL_TIZEN_image_native_buffer */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif /* EGL_TIZEN_image_native_surface */ + +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + +#ifdef __cplusplus +} +#endif + +#endif /* __eglext_h_ */ + +#endif /* _MSC_VER */ diff --git a/thirdparty/SDL/include/SDL/SDL_endian.h b/thirdparty/SDL/include/SDL/SDL_endian.h new file mode 100644 index 00000000..c3f84317 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_endian.h @@ -0,0 +1,348 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_endian.h + * + * Functions for reading and writing endian-specific values + */ + +#ifndef SDL_endian_h_ +#define SDL_endian_h_ + +#include "SDL_stdinc.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ +#ifdef __clang__ +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */); +} +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ + +#include +#endif + +/** + * \name The two types of endianness + */ +/* @{ */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 +/* @} */ + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifdef __linux__ +#include +#define SDL_BYTEORDER __BYTE_ORDER +#elif defined(__OpenBSD__) || defined(__DragonFly__) +#include +#define SDL_BYTEORDER BYTE_ORDER +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#include +#define SDL_BYTEORDER BYTE_ORDER +/* predefs from newer gcc and clang versions: */ +#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ +#else +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MIPSEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ + +#ifndef SDL_FLOATWORDORDER /* Not defined in SDL_config.h? */ +/* predefs from newer gcc versions: */ +#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__) +#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ +#elif defined(__MAVERICK__) +/* For Maverick, float words are always little-endian. */ +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__) +/* For FPA, float words are always big-endian. */ +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +/* By default, assume that floats words follow the memory system mode. */ +#define SDL_FLOATWORDORDER SDL_BYTEORDER +#endif /* __FLOAT_WORD_ORDER__ */ +#endif /* !SDL_FLOATWORDORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_endian.h + */ + +/* various modern compilers may have builtin swap */ +#if defined(__GNUC__) || defined(__clang__) +# define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +# define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAS_BUILTIN_BSWAP64 (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + + /* this one is broken */ +# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95) +#else +# define HAS_BUILTIN_BSWAP16 0 +# define HAS_BUILTIN_BSWAP32 0 +# define HAS_BUILTIN_BSWAP64 0 +# define HAS_BROKEN_BSWAP 0 +#endif + +#if HAS_BUILTIN_BSWAP16 +#define SDL_Swap16(x) __builtin_bswap16(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ushort) +#define SDL_Swap16(x) _byteswap_ushort(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); + return (Uint16)result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint16 SDL_Swap16(Uint16); +#pragma aux SDL_Swap16 = \ + "xchg al, ah" \ + parm [ax] \ + modify [ax]; +#else +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); +} +#endif + +#if HAS_BUILTIN_BSWAP32 +#define SDL_Swap32(x) __builtin_bswap32(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ulong) +#define SDL_Swap32(x) _byteswap_ulong(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0": "=r"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); + return result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint32 SDL_Swap32(Uint32); +#pragma aux SDL_Swap32 = \ + "bswap eax" \ + parm [eax] \ + modify [eax]; +#else +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | (x >> 24))); +} +#endif + +#if HAS_BUILTIN_BSWAP64 +#define SDL_Swap64(x) __builtin_bswap64(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_uint64) +#define SDL_Swap64(x) _byteswap_uint64(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + union { + struct { + Uint32 a, b; + } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r"(v.s.a), "=r"(v.s.b) + : "0" (v.s.a), "1"(v.s.b)); + return v.u; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint64 SDL_Swap64(Uint64); +#pragma aux SDL_Swap64 = \ + "bswap eax" \ + "bswap edx" \ + "xchg eax,edx" \ + parm [eax edx] \ + modify [eax edx]; +#else +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif + + +SDL_FORCE_INLINE float +SDL_SwapFloat(float x) +{ + union { + float f; + Uint32 ui32; + } swapper; + swapper.f = x; + swapper.ui32 = SDL_Swap32(swapper.ui32); + return swapper.f; +} + +/* remove extra macros */ +#undef HAS_BROKEN_BSWAP +#undef HAS_BUILTIN_BSWAP16 +#undef HAS_BUILTIN_BSWAP32 +#undef HAS_BUILTIN_BSWAP64 + +/** + * \name Swap to native + * Byteswap item from the specified endianness to the native endianness. + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapFloatLE(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#define SDL_SwapFloatBE(X) (X) +#endif +/* @} *//* Swap to native */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_endian_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_error.h b/thirdparty/SDL/include/SDL/SDL_error.h new file mode 100644 index 00000000..5c961e42 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_error.h @@ -0,0 +1,163 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_error.h + * + * Simple error message routines for SDL. + */ + +#ifndef SDL_error_h_ +#define SDL_error_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ + + +/** + * Set the SDL error message for the current thread. + * + * Calling this function will replace any previous error message that was set. + * + * This function always returns -1, since SDL frequently uses -1 to signify an + * failing result, leading to this idiom: + * + * ```c + * if (error_code) { + * return SDL_SetError("This operation has failed: %d", error_code); + * } + * ``` + * + * \param fmt a printf()-style message format string + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * \returns always -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_GetError + */ +extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Retrieve a message about the last error that occurred on the current + * thread. + * + * It is possible for multiple errors to occur before calling SDL_GetError(). + * Only the last error is returned. + * + * The message is only applicable when an SDL function has signaled an error. + * You must check the return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). You should *not* use the results of + * SDL_GetError() to decide if an error has occurred! Sometimes SDL will set + * an error string even when reporting success. + * + * SDL will *not* clear the error string for successful API calls. You *must* + * check return values for failure cases before you can assume the error + * string applies. + * + * Error strings are set per-thread, so an error set in a different thread + * will not interfere with the current thread's operation. + * + * The returned string is internally allocated and must not be freed by the + * application. + * + * \returns a message with information about the specific error that occurred, + * or an empty string if there hasn't been an error message set since + * the last call to SDL_ClearError(). The message is only applicable + * when an SDL function has signaled an error. You must check the + * return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_SetError + */ +extern DECLSPEC const char *SDLCALL SDL_GetError(void); + +/** + * Get the last error message that was set for the current thread. + * + * This allows the caller to copy the error string into a provided buffer, but + * otherwise operates exactly the same as SDL_GetError(). + * + * \param errstr A buffer to fill with the last error message that was set for + * the current thread + * \param maxlen The size of the buffer pointed to by the errstr parameter + * \returns the pointer passed in as the `errstr` parameter. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetError + */ +extern DECLSPEC char * SDLCALL SDL_GetErrorMsg(char *errstr, int maxlen); + +/** + * Clear any previous error message for this thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetError + * \sa SDL_SetError + */ +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/** + * \name Internal error functions + * + * \internal + * Private error reporting function - used internally. + */ +/* @{ */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) +typedef enum +{ + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +/* SDL_Error() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); +/* @} *//* Internal error functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_error_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_events.h b/thirdparty/SDL/include/SDL/SDL_events.h new file mode 100644 index 00000000..c0fc9bb1 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_events.h @@ -0,0 +1,1162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_events.h + * + * Include file for SDL event handling. + */ + +#ifndef SDL_events_h_ +#define SDL_events_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_quit.h" +#include "SDL_gesture.h" +#include "SDL_touch.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/** + * The types of events that can be delivered. + */ +typedef enum +{ + SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ + + /* Application events */ + SDL_QUIT = 0x100, /**< User-requested quit */ + + /* These application events have special meaning on iOS, see README-ios.md for details */ + SDL_APP_TERMINATING, /**< The application is being terminated by the OS + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + */ + SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onLowMemory() + */ + SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + */ + SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + */ + SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + */ + SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + */ + + SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ + + /* Display events */ + SDL_DISPLAYEVENT = 0x150, /**< Display state change */ + + /* Window events */ + SDL_WINDOWEVENT = 0x200, /**< Window state change */ + SDL_SYSWMEVENT, /**< System specific event */ + + /* Keyboard events */ + SDL_KEYDOWN = 0x300, /**< Key pressed */ + SDL_KEYUP, /**< Key released */ + SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ + SDL_TEXTINPUT, /**< Keyboard text input */ + SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an + input language or keyboard layout change. + */ + SDL_TEXTEDITING_EXT, /**< Extended keyboard text editing (composition) */ + + /* Mouse events */ + SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ + + /* Joystick events */ + SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + SDL_JOYBATTERYUPDATED, /**< Joystick battery level change */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ + SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */ + SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */ + SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */ + SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */ + + /* Touch events */ + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + + /* Gesture events */ + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + + /* Clipboard events */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + + /* Drag and drop events */ + SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ + + /* Audio hotplug events */ + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ + + /* Sensor events */ + SDL_SENSORUPDATE = 0x1200, /**< A sensor was updated */ + + /* Render events */ + SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ + SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + + /* Internal events */ + SDL_POLLSENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */ + + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, + * and should be allocated with SDL_RegisterEvents() + */ + SDL_USEREVENT = 0x8000, + + /** + * This last event is only for bounding internal arrays + */ + SDL_LASTEVENT = 0xFFFF +} SDL_EventType; + +/** + * \brief Fields shared by every event + */ +typedef struct SDL_CommonEvent +{ + Uint32 type; + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_CommonEvent; + +/** + * \brief Display state change event data (event.display.*) + */ +typedef struct SDL_DisplayEvent +{ + Uint32 type; /**< ::SDL_DISPLAYEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 display; /**< The associated display index */ + Uint8 event; /**< ::SDL_DisplayEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ +} SDL_DisplayEvent; + +/** + * \brief Window state change event data (event.window.*) + */ +typedef struct SDL_WindowEvent +{ + Uint32 type; /**< ::SDL_WINDOWEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window */ + Uint8 event; /**< ::SDL_WindowEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ + Sint32 data2; /**< event dependent data */ +} SDL_WindowEvent; + +/** + * \brief Keyboard button event structure (event.key.*) + */ +typedef struct SDL_KeyboardEvent +{ + Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 repeat; /**< Non-zero if this is a key repeat */ + Uint8 padding2; + Uint8 padding3; + SDL_Keysym keysym; /**< The key that was pressed or released */ +} SDL_KeyboardEvent; + +#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text editing event structure (event.edit.*) + */ +typedef struct SDL_TextEditingEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingEvent; + +/** + * \brief Extended keyboard text editing event structure (event.editExt.*) when text would be + * truncated if stored in the text buffer SDL_TextEditingEvent + */ +typedef struct SDL_TextEditingExtEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING_EXT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingExtEvent; + +#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text input event structure (event.text.*) + */ +typedef struct SDL_TextInputEvent +{ + Uint32 type; /**< ::SDL_TEXTINPUT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ +} SDL_TextInputEvent; + +/** + * \brief Mouse motion event structure (event.motion.*) + */ +typedef struct SDL_MouseMotionEvent +{ + Uint32 type; /**< ::SDL_MOUSEMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint32 state; /**< The current button state */ + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ + Sint32 xrel; /**< The relative motion in the X direction */ + Sint32 yrel; /**< The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/** + * \brief Mouse button event structure (event.button.*) + */ +typedef struct SDL_MouseButtonEvent +{ + Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ + Uint8 padding1; + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ +} SDL_MouseButtonEvent; + +/** + * \brief Mouse wheel event structure (event.wheel.*) + */ +typedef struct SDL_MouseWheelEvent +{ + Uint32 type; /**< ::SDL_MOUSEWHEEL */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ + Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ + Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ + float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */ + float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */ +} SDL_MouseWheelEvent; + +/** + * \brief Joystick axis motion event structure (event.jaxis.*) + */ +typedef struct SDL_JoyAxisEvent +{ + Uint32 type; /**< ::SDL_JOYAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The joystick axis index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_JoyAxisEvent; + +/** + * \brief Joystick trackball motion event structure (event.jball.*) + */ +typedef struct SDL_JoyBallEvent +{ + Uint32 type; /**< ::SDL_JOYBALLMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 ball; /**< The joystick trackball index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/** + * \brief Joystick hat position change event structure (event.jhat.*) + */ +typedef struct SDL_JoyHatEvent +{ + Uint32 type; /**< ::SDL_JOYHATMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value. + * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP + * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT + * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyHatEvent; + +/** + * \brief Joystick button event structure (event.jbutton.*) + */ +typedef struct SDL_JoyButtonEvent +{ + Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyButtonEvent; + +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ +} SDL_JoyDeviceEvent; + +/** + * \brief Joysick battery level change event structure (event.jbattery.*) + */ +typedef struct SDL_JoyBatteryEvent +{ + Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + SDL_JoystickPowerLevel level; /**< The joystick battery level */ +} SDL_JoyBatteryEvent; + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The controller button (SDL_GameControllerButton) */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ +} SDL_ControllerDeviceEvent; + +/** + * \brief Game controller touchpad event structure (event.ctouchpad.*) + */ +typedef struct SDL_ControllerTouchpadEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 touchpad; /**< The index of the touchpad */ + Sint32 finger; /**< The index of the finger on the touchpad */ + float x; /**< Normalized in the range 0...1 with 0 being on the left */ + float y; /**< Normalized in the range 0...1 with 0 being at the top */ + float pressure; /**< Normalized in the range 0...1 */ +} SDL_ControllerTouchpadEvent; + +/** + * \brief Game controller sensor event structure (event.csensor.*) + */ +typedef struct SDL_ControllerSensorEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ + float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ +} SDL_ControllerSensorEvent; + +/** + * \brief Audio device event structure (event.adevice.*) + */ +typedef struct SDL_AudioDeviceEvent +{ + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; +} SDL_AudioDeviceEvent; + + +/** + * \brief Touch finger event structure (event.tfinger.*) + */ +typedef struct SDL_TouchFingerEvent +{ + Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_FingerID fingerId; + float x; /**< Normalized in the range 0...1 */ + float y; /**< Normalized in the range 0...1 */ + float dx; /**< Normalized in the range -1...1 */ + float dy; /**< Normalized in the range -1...1 */ + float pressure; /**< Normalized in the range 0...1 */ + Uint32 windowID; /**< The window underneath the finger, if any */ +} SDL_TouchFingerEvent; + + +/** + * \brief Multiple Finger Gesture Event (event.mgesture.*) + */ +typedef struct SDL_MultiGestureEvent +{ + Uint32 type; /**< ::SDL_MULTIGESTURE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + float dTheta; + float dDist; + float x; + float y; + Uint16 numFingers; + Uint16 padding; +} SDL_MultiGestureEvent; + + +/** + * \brief Dollar Gesture Event (event.dgesture.*) + */ +typedef struct SDL_DollarGestureEvent +{ + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_GestureID gestureId; + Uint32 numFingers; + float error; + float x; /**< Normalized center of gesture */ + float y; /**< Normalized center of gesture */ +} SDL_DollarGestureEvent; + + +/** + * \brief An event used to request a file open by the system (event.drop.*) + * This event is enabled by default, you can disable it with SDL_EventState(). + * \note If this event is enabled, you must free the filename in the event. + */ +typedef struct SDL_DropEvent +{ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ +} SDL_DropEvent; + + +/** + * \brief Sensor event structure (event.sensor.*) + */ +typedef struct SDL_SensorEvent +{ + Uint32 type; /**< ::SDL_SENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The instance ID of the sensor */ + float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ +} SDL_SensorEvent; + +/** + * \brief The "quit requested" event + */ +typedef struct SDL_QuitEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_QuitEvent; + +/** + * \brief OS Specific event + */ +typedef struct SDL_OSEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_OSEvent; + +/** + * \brief A user-defined event type (event.user.*) + */ +typedef struct SDL_UserEvent +{ + Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window if any */ + Sint32 code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ +} SDL_UserEvent; + + +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; + +/** + * \brief A video driver dependent system event (event.syswm.*) + * This event is disabled by default, you can enable it with SDL_EventState() + * + * \note If you want to use this event, you should include SDL_syswm.h. + */ +typedef struct SDL_SysWMEvent +{ + Uint32 type; /**< ::SDL_SYSWMEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ +} SDL_SysWMEvent; + +/** + * \brief General event structure + */ +typedef union SDL_Event +{ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_DisplayEvent display; /**< Display event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextEditingExtEvent editExt; /**< Extended text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */ + SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_SensorEvent sensor; /**< Sensor event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC. + Visual C++ will respect the push pack pragma and use 52 bytes (size of + SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit + architectures) for this union, and GCC will use the alignment of the + largest datatype within the union, which is 8 bytes on 64-bit + architectures. + + So... we'll add padding to force the size to be 56 bytes for both. + + On architectures where pointers are 16 bytes, this needs rounding up to + the next multiple of 16, 64, and on architectures where pointers are + even larger the size of SDL_UserEvent will dominate as being 3 pointers. + */ + Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; +} SDL_Event; + +/* Make sure we haven't broken binary compatibility */ +SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); + + +/* Function prototypes */ + +/** + * Pump the event loop, gathering events from the input devices. + * + * This function updates the event queue and internal input device state. + * + * **WARNING**: This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider only doing those + * things on the main thread in any case. + * + * SDL_PumpEvents() gathers all the pending input information from devices and + * places it in the event queue. Without calls to SDL_PumpEvents() no events + * would ever be placed on the queue. Often the need for calls to + * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and + * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not + * polling or waiting for events (e.g. you are filtering them), then you must + * call SDL_PumpEvents() to force an event queue update. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent + */ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* @{ */ +typedef enum +{ + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; + +/** + * Check the event queue for messages and optionally return them. + * + * `action` may be any of the following: + * + * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the + * event queue. + * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will _not_ be removed from the queue. + * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will be removed from the queue. + * + * You may have to call SDL_PumpEvents() before calling this function. + * Otherwise, the events may not be ready to be filtered when you call + * SDL_PeepEvents(). + * + * This function is thread-safe. + * + * \param events destination buffer for the retrieved events + * \param numevents if action is SDL_ADDEVENT, the number of events to add + * back to the event queue; if action is SDL_PEEKEVENT or + * SDL_GETEVENT, the maximum number of events to retrieve + * \param action action to take; see [[#action|Remarks]] for details + * \param minType minimum value of the event type to be considered; + * SDL_FIRSTEVENT is a safe choice + * \param maxType maximum value of the event type to be considered; + * SDL_LASTEVENT is a safe choice + * \returns the number of events actually stored or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, + SDL_eventaction action, + Uint32 minType, Uint32 maxType); +/* @} */ + +/** + * Check for the existence of a certain event type in the event queue. + * + * If you need to check for a range of event types, use SDL_HasEvents() + * instead. + * + * \param type the type of event to be queried; see SDL_EventType for details + * \returns SDL_TRUE if events matching `type` are present, or SDL_FALSE if + * events matching `type` are not present. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); + + +/** + * Check for the existence of certain event types in the event queue. + * + * If you need to check for a single event type, use SDL_HasEvent() instead. + * + * \param minType the low end of event type to be queried, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be queried, inclusive; see + * SDL_EventType for details + * \returns SDL_TRUE if events with type >= `minType` and <= `maxType` are + * present, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); + +/** + * Clear events of a specific type from the event queue. + * + * This will unconditionally remove any events from the queue that match + * `type`. If you need to remove a range of event types, use SDL_FlushEvents() + * instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param type the type of event to be cleared; see SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvents + */ +extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); + +/** + * Clear events of a range of types from the event queue. + * + * This will unconditionally remove any events from the queue that are in the + * range of `minType` to `maxType`, inclusive. If you need to remove a single + * event type, use SDL_FlushEvent() instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param minType the low end of event type to be cleared, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be cleared, inclusive; see + * SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvent + */ +extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); + +/** + * Poll for currently pending events. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. The 1 returned refers to + * this event, immediately stored in the SDL Event structure -- not an event + * to follow. + * + * If `event` is NULL, it simply returns 1 if there is an event in the queue, + * but will not remove it from the queue. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that set the video mode. + * + * SDL_PollEvent() is the favored way of receiving system events since it can + * be done from the main loop and does not suspend the main loop while waiting + * on an event to be posted. + * + * The common practice is to fully process the event queue once every frame, + * usually as a first step before updating the game's state: + * + * ```c + * while (game_is_still_running) { + * SDL_Event event; + * while (SDL_PollEvent(&event)) { // poll until all events are handled! + * // decide what to do with this event. + * } + * + * // update game state, draw the current frame + * } + * ``` + * + * \param event the SDL_Event structure to be filled with the next event from + * the queue, or NULL + * \returns 1 if there is a pending event or 0 if there are none available. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + * \sa SDL_SetEventFilter + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); + +/** + * Wait indefinitely for the next available event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); + +/** + * Wait until the specified timeout (in milliseconds) for the next available + * event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \param timeout the maximum number of milliseconds to wait for the next + * available event + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. This also returns 0 if + * the timeout elapsed without an event arriving. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEvent + */ +extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, + int timeout); + +/** + * Add an event to the event queue. + * + * The event queue can actually be used as a two way communication channel. + * Not only can events be read from the queue, but the user can also push + * their own events onto it. `event` is a pointer to the event structure you + * wish to push onto the queue. The event is copied into the queue, and the + * caller may dispose of the memory pointed to after SDL_PushEvent() returns. + * + * Note: Pushing device input events onto the queue doesn't modify the state + * of the device within SDL. + * + * This function is thread-safe, and can be called from other threads safely. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter but events added with SDL_PeepEvents() do not. + * + * For pushing application-specific events, please use SDL_RegisterEvents() to + * get an event type that does not conflict with other code that also wants + * its own custom event types. + * + * \param event the SDL_Event to be added to the queue + * \returns 1 on success, 0 if the event was filtered, or a negative error + * code on failure; call SDL_GetError() for more information. A + * common reason for error is the event queue being full. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PeepEvents + * \sa SDL_PollEvent + * \sa SDL_RegisterEvents + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); + +/** + * A function pointer used for callbacks that watch the event queue. + * + * \param userdata what was passed as `userdata` to SDL_SetEventFilter() + * or SDL_AddEventWatch, etc + * \param event the event that triggered the callback + * \returns 1 to permit event to be added to the queue, and 0 to disallow + * it. When used with SDL_AddEventWatch, the return value is ignored. + * + * \sa SDL_SetEventFilter + * \sa SDL_AddEventWatch + */ +typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); + +/** + * Set up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * If the filter function returns 1 when called, then the event will be added + * to the internal queue. If it returns 0, then the event will be dropped from + * the queue, but the internal state will still be updated. This allows + * selective filtering of dynamically arriving events. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * On platforms that support it, if the quit event is generated by an + * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the + * application at the next event poll. + * + * There is one caveat when dealing with the ::SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will be + * closed, otherwise the window will remain open if possible. + * + * Note: Disabled events never make it to the event filter function; see + * SDL_EventState(). + * + * Note: If you just want to inspect events without filtering, you should use + * SDL_AddEventWatch() instead. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter, but events pushed onto the queue with SDL_PeepEvents() do + * not. + * + * \param filter An SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + * \sa SDL_EventState + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, + void *userdata); + +/** + * Query the current event filter. + * + * This function can be used to "chain" filters, by saving the existing filter + * before replacing it with a function that will call that saved filter. + * + * \param filter the current callback function will be stored here + * \param userdata the pointer that is passed to the current event filter will + * be stored here + * \returns SDL_TRUE on success or SDL_FALSE if there is no event filter set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetEventFilter + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, + void **userdata); + +/** + * Add a callback to be triggered when an event is added to the event queue. + * + * `filter` will be called when an event happens, and its return value is + * ignored. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * If the quit event is generated by a signal (e.g. SIGINT), it will bypass + * the internal queue and be delivered to the watch callback immediately, and + * arrive at the next event poll. + * + * Note: the callback is called for events posted by the user through + * SDL_PushEvent(), but not for disabled events, nor for events by a filter + * callback set with SDL_SetEventFilter(), nor for events posted by the user + * through SDL_PeepEvents(). + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelEventWatch + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch callback added with SDL_AddEventWatch(). + * + * This function takes the same input as SDL_AddEventWatch() to identify and + * delete the corresponding callback. + * + * \param filter the function originally passed to SDL_AddEventWatch() + * \param userdata the pointer originally passed to SDL_AddEventWatch() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Run a specific filter function on the current event queue, removing any + * events for which the filter returns 0. + * + * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), + * this function does not change the filter permanently, it only uses the + * supplied filter until this function returns. + * + * \param filter the SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, + void *userdata); + +/* @{ */ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 + +/** + * Set the state of processing events by type. + * + * `state` may be any of the following: + * + * - `SDL_QUERY`: returns the current processing state of the specified event + * - `SDL_IGNORE` (aka `SDL_DISABLE`): the event will automatically be dropped + * from the event queue and will not be filtered + * - `SDL_ENABLE`: the event will be processed normally + * + * \param type the type of event; see SDL_EventType for details + * \param state how to process the event + * \returns `SDL_DISABLE` or `SDL_ENABLE`, representing the processing state + * of the event before this function makes any changes to it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventState + */ +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); +/* @} */ +#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) + +/** + * Allocate a set of user-defined events, and return the beginning event + * number for that set of events. + * + * Calling this function with `numevents` <= 0 is an error and will return + * (Uint32)-1. + * + * Note, (Uint32)-1 means the maximum unsigned 32-bit integer value (or + * 0xFFFFFFFF), but is clearer to write. + * + * \param numevents the number of events to be allocated + * \returns the beginning event number, or (Uint32)-1 if there are not enough + * user-defined events left. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PushEvent + */ +extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_events_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_filesystem.h b/thirdparty/SDL/include/SDL/SDL_filesystem.h new file mode 100644 index 00000000..a7606bde --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_filesystem.h @@ -0,0 +1,145 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_filesystem.h + * + * \brief Include file for filesystem SDL API functions + */ + +#ifndef SDL_filesystem_h_ +#define SDL_filesystem_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the directory where the application was run from. + * + * This is not necessarily a fast call, so you should call this once near + * startup and save the string if you need it. + * + * **Mac OS X and iOS Specific Functionality**: If the application is in a + * ".app" bundle, this function returns the Resource directory (e.g. + * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding + * a property to the Info.plist file. Adding a string key with the name + * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the + * behaviour. + * + * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an + * application in /Applications/SDLApp/MyApp.app): + * + * - `resource`: bundle resource directory (the default). For example: + * `/Applications/SDLApp/MyApp.app/Contents/Resources` + * - `bundle`: the Bundle directory. For example: + * `/Applications/SDLApp/MyApp.app/` + * - `parent`: the containing directory of the bundle. For example: + * `/Applications/SDLApp/` + * + * The returned path is guaranteed to end with a path separator ('\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \returns an absolute path in UTF-8 encoding to the application data + * directory. NULL will be returned on error or when the platform + * doesn't implement this functionality, call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetPrefPath + */ +extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); + +/** + * Get the user-and-app-specific path where files can be written. + * + * Get the "pref dir". This is meant to be where users can write personal + * files (preferences and save games, etc) that are specific to your + * application. This directory is unique per user, per application. + * + * This function will decide the appropriate location in the native + * filesystem, create the directory if necessary, and return a string of the + * absolute path to the directory in UTF-8 encoding. + * + * On Windows, the string might look like: + * + * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\` + * + * On Linux, the string might look like: + * + * `/home/bob/.local/share/My Program Name/` + * + * On Mac OS X, the string might look like: + * + * `/Users/bob/Library/Application Support/My Program Name/` + * + * You should assume the path returned by this function is the only safe place + * to write files (and that SDL_GetBasePath(), while it might be writable, or + * even the parent of the returned path, isn't where you should be writing + * things). + * + * Both the org and app strings may become part of a directory name, so please + * follow these rules: + * + * - Try to use the same org string (_including case-sensitivity_) for all + * your applications that use this function. + * - Always use a unique app string for each one, and make sure it never + * changes for an app once you've decided on it. + * - Unicode characters are legal, as long as it's UTF-8 encoded, but... + * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game + * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. + * + * The returned path is guaranteed to end with a path separator ('\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \param org the name of your organization + * \param app the name of your application + * \returns a UTF-8 string of the user directory in platform-dependent + * notation. NULL if there's a problem (creating directory failed, + * etc.). + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetBasePath + */ +extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_filesystem_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_gamecontroller.h b/thirdparty/SDL/include/SDL/SDL_gamecontroller.h new file mode 100644 index 00000000..ace1c163 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_gamecontroller.h @@ -0,0 +1,1055 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef SDL_gamecontroller_h_ +#define SDL_gamecontroller_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + * + * If you would like to receive controller updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The gamecontroller structure used to identify an SDL game controller + */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + +typedef enum +{ + SDL_CONTROLLER_TYPE_UNKNOWN = 0, + SDL_CONTROLLER_TYPE_XBOX360, + SDL_CONTROLLER_TYPE_XBOXONE, + SDL_CONTROLLER_TYPE_PS3, + SDL_CONTROLLER_TYPE_PS4, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO, + SDL_CONTROLLER_TYPE_VIRTUAL, + SDL_CONTROLLER_TYPE_PS5, + SDL_CONTROLLER_TYPE_AMAZON_LUNA, + SDL_CONTROLLER_TYPE_GOOGLE_STADIA, + SDL_CONTROLLER_TYPE_NVIDIA_SHIELD, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR +} SDL_GameControllerType; + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +/** + * Get the SDL joystick layer binding for this controller button/axis mapping + */ +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * + * ```c + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for (int i = 0; i < nJoysticks; i++) { + * if (SDL_IsGameController(i)) { + * nGameControllers++; + * } + * } + * ``` + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * + * ```c + * "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * ``` + */ + +/** + * Load a set of Game Controller mappings from a seekable SDL data stream. + * + * You can call this function several times, if needed, to load different + * database files. + * + * If a new mapping is loaded for an already known controller GUID, the later + * version will overwrite the one currently loaded. + * + * Mappings not belonging to the current platform or with no platform field + * specified will be ignored (i.e. mappings for Linux will be ignored in + * Windows, etc). + * + * This function will load the text database entirely in memory before + * processing it, so take this into consideration if you are in a memory + * constrained environment. + * + * \param rw the data stream for the mappings to be added + * \param freerw non-zero to close the stream after being read + * \returns the number of mappings added or -1 on error; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerAddMappingsFromFile + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw); + +/** + * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() + * + * Convenience macro. + */ +#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Add support for controllers that SDL is unaware of or to cause an existing + * controller to have a different binding. + * + * The mapping string has the format "GUID,name,mapping", where GUID is the + * string value from SDL_JoystickGetGUIDString(), name is the human readable + * string for the device and mappings are controller mappings to joystick + * ones. Under Windows there is a reserved GUID of "xinput" that covers all + * XInput devices. The mapping format for joystick is: {| |bX |a joystick + * button, index X |- |hX.Y |hat X with value Y |- |aX |axis X of the joystick + * |} Buttons can be used as a controller axes and vice versa. + * + * This string shows an example of a valid mapping for a controller: + * + * ```c + * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" + * ``` + * + * \param mappingString the mapping string + * \returns 1 if a new mapping is added, 0 if an existing mapping is updated, + * -1 on error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString); + +/** + * Get the number of mappings installed. + * + * \returns the number of mappings. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void); + +/** + * Get the mapping at a particular index. + * + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * the index is out of range. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index); + +/** + * Get the game controller mapping string for a given GUID. + * + * The returned string must be freed with SDL_free(). + * + * \param guid a structure containing the GUID for which a mapping is desired + * \returns a mapping string or NULL on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid); + +/** + * Get the current mapping of a Game Controller. + * + * The returned string must be freed with SDL_free(). + * + * Details about mappings are discussed with SDL_GameControllerAddMapping(). + * + * \param gamecontroller the game controller you want to get the current + * mapping for + * \returns a string that has the controller's mapping or NULL if no mapping + * is available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller); + +/** + * Check if the given joystick is supported by the game controller interface. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns SDL_TRUE if the given joystick is supported by the game controller + * interface, SDL_FALSE if it isn't or it's an invalid index. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); + +/** + * Get the implementation dependent name for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent name for the game controller, or NULL + * if there is no name or the index is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerName + * \sa SDL_GameControllerOpen + * \sa SDL_IsGameController + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Get the implementation dependent path for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent path for the game controller, or NULL + * if there is no path or the index is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPath + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPathForIndex(int joystick_index); + +/** + * Get the type of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index); + +/** + * Get the mapping of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * no mapping is available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); + +/** + * Open a game controller for use. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * The index passed as an argument refers to the N'th game controller on the + * system. This index is not the value which will identify this controller in + * future controller events. The joystick's instance id (SDL_JoystickID) will + * be used there instead. + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns a gamecontroller identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerNameForIndex + * \sa SDL_IsGameController + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Get the SDL_GameController associated with an instance id. + * + * \param joyid the instance id to get the SDL_GameController for + * \returns an SDL_GameController on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); + +/** + * Get the SDL_GameController associated with a player index. + * + * Please note that the player index is _not_ the device index, nor is it the + * instance id! + * + * \param player_index the player index, which is not the device index or the + * instance id! + * \returns the SDL_GameController associated with a player index. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GameControllerGetPlayerIndex + * \sa SDL_GameControllerSetPlayerIndex + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(int player_index); + +/** + * Get the implementation-dependent name for an opened game controller. + * + * This is the same name as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent name for the game controller, or NULL + * if there is no name or the identifier passed is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); + +/** + * Get the implementation-dependent path for an opened game controller. + * + * This is the same path as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent path for the game controller, or NULL + * if there is no path or the identifier passed is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPath(SDL_GameController *gamecontroller); + +/** + * Get the type of this currently opened controller + * + * This is the same name as returned by SDL_GameControllerTypeForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller the game controller object to query. + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller); + +/** + * Get the player index of an opened game controller. + * + * For XInput controllers this returns the XInput user index. + * + * \param gamecontroller the game controller object to query. + * \returns the player index for controller, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller); + +/** + * Set the player index of an opened game controller. + * + * \param gamecontroller the game controller object to adjust. + * \param player_index Player index to assign to this controller, or -1 to + * clear the player index and turn off player LEDs. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index); + +/** + * Get the USB vendor ID of an opened controller, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB vendor ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController *gamecontroller); + +/** + * Get the USB product ID of an opened controller, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *gamecontroller); + +/** + * Get the product version of an opened controller, if available. + * + * If the product version isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product version, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller); + +/** + * Get the firmware version of an opened controller, if available. + * + * If the firmware version isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the controller firmware version, or zero if unavailable. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller); + +/** + * Get the serial number of an opened controller, if available. + * + * Returns the serial number of the controller, or NULL if it is not + * available. + * + * \param gamecontroller the game controller object to query. + * \return the serial number, or NULL if unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller); + +/** + * Check if a controller has been opened and is currently connected. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns SDL_TRUE if the controller has been opened and is currently + * connected, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); + +/** + * Get the Joystick ID from a Game Controller. + * + * This function will give you a SDL_Joystick object, which allows you to use + * the SDL_Joystick functions with a SDL_GameController object. This would be + * useful for getting a joystick's position at any given time, even if it + * hasn't moved (moving it would produce an event, which would have the axis' + * value). + * + * The pointer returned is owned by the SDL_GameController. You should not + * call SDL_JoystickClose() on it, for example, since doing so will likely + * cause SDL to crash. + * + * \param gamecontroller the game controller object that you want to get a + * joystick from + * \returns a SDL_Joystick object; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); + +/** + * Query or change current state of Game Controller events. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * Any number can be passed to SDL_GameControllerEventState(), but only -1, 0, + * and 1 will have any effect. Other numbers will just be returned. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns the same value passed to the function, with exception to -1 + * (SDL_QUERY), which will return the current state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * Manually pump game controller updates if not using the loop. + * + * This function is called automatically by the event loop if events are + * enabled. Under such circumstances, it will not be necessary to call this + * function. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); + + +/** + * The list of axes available from a controller + * + * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to SDL_JOYSTICK_AXIS_MAX, + * and are centered within ~8000 of zero, though advanced UI will allow users to set + * or autodetect the dead zone, which varies between controllers. + * + * Trigger axis values range from 0 to SDL_JOYSTICK_AXIS_MAX. + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_GameControllerAxis; + +/** + * Convert a string into SDL_GameControllerAxis enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * Note specially that "righttrigger" and "lefttrigger" map to + * `SDL_CONTROLLER_AXIS_TRIGGERRIGHT` and `SDL_CONTROLLER_AXIS_TRIGGERLEFT`, + * respectively. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerAxis enum corresponding to the input string, + * or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetStringForAxis + */ +extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *str); + +/** + * Convert from an SDL_GameControllerAxis enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param axis an enum value for a given SDL_GameControllerAxis + * \returns a string for the given axis, or NULL if an invalid axis is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxisFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); + +/** + * Get the SDL joystick layer binding for a controller axis mapping. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (one of the SDL_GameControllerAxis values) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller axis doesn't exist on the device), its + * `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForButton + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * Query whether a game controller has a given axis. + * + * This merely reports whether the controller's mapping defined this axis, as + * that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (an SDL_GameControllerAxis value) + * \returns SDL_TRUE if the controller has this axis, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL +SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * Get the current state of an axis control on a game controller. + * + * The axis indices start at index 0. + * + * The state is a value ranging from -32768 to 32767. Triggers, however, range + * from 0 to 32767 (they never return a negative value). + * + * \param gamecontroller a game controller + * \param axis an axis index (one of the SDL_GameControllerAxis values) + * \returns axis state (including 0) on success or 0 (also) on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButton + */ +extern DECLSPEC Sint16 SDLCALL +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ + SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 */ + SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 */ + SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 */ + SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 */ + SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ + SDL_CONTROLLER_BUTTON_MAX +} SDL_GameControllerButton; + +/** + * Convert a string into an SDL_GameControllerButton enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerButton enum corresponding to the input + * string, or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *str); + +/** + * Convert from an SDL_GameControllerButton enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param button an enum value for a given SDL_GameControllerButton + * \returns a string for the given button, or NULL if an invalid axis is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButtonFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); + +/** + * Get the SDL joystick layer binding for a controller button mapping. + * + * \param gamecontroller a game controller + * \param button an button enum value (an SDL_GameControllerButton value) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller button doesn't exist on the device), + * its `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForAxis + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Query whether a game controller has a given button. + * + * This merely reports whether the controller's mapping defined this button, + * as that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param button a button enum value (an SDL_GameControllerButton value) + * \returns SDL_TRUE if the controller has this button, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the current state of a button on a game controller. + * + * \param gamecontroller a game controller + * \param button a button index (one of the SDL_GameControllerButton values) + * \returns 1 for pressed state or 0 for not pressed state or error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxis + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the number of touchpads on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller); + +/** + * Get the number of supported simultaneous fingers on a touchpad on a game + * controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad); + +/** + * Get the current state of a finger on a touchpad on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure); + +/** + * Return whether a game controller has a particular sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor exists, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Set whether data reporting for a game controller sensor is enabled. + * + * \param gamecontroller The controller to update + * \param type The type of sensor to enable/disable + * \param enabled Whether data reporting should be enabled + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled); + +/** + * Query whether sensor data reporting is enabled for a game controller. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor is enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the data rate (number of events per second) of a game controller + * sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \return the data rate, or 0.0f if the data rate is not available. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC float SDLCALL SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the current state of a game controller sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * See SDL_sensor.h for the details for each type of sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \return 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values); + +/** + * Start a rumble effect on a game controller. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param gamecontroller The controller to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GameControllerHasRumble + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the game controller's triggers. + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. This is currently only supported on Xbox One controllers. If you + * want the (more common) whole-controller rumble, use + * SDL_GameControllerRumble() instead. + * + * \param gamecontroller The controller to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GameControllerHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a game controller has an LED. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have a + * modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have rumble + * support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumble(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support on triggers. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have trigger + * rumble support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller); + +/** + * Update a game controller's LED color. + * + * \param gamecontroller The controller to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0, or -1 if this controller does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a controller specific effect packet + * + * \param gamecontroller The controller to affect + * \param data The data to send to the controller + * \param size The size of the data to send to the controller + * \returns 0, or -1 if this controller or driver doesn't support effect + * packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size); + +/** + * Close a game controller previously opened with SDL_GameControllerOpen(). + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); + +/** + * Return the sfSymbolsName for a given button on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param button a button on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForAxis + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button); + +/** + * Return the sfSymbolsName for a given axis on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param axis an axis on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForButton + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gamecontroller_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_gesture.h b/thirdparty/SDL/include/SDL/SDL_gesture.h new file mode 100644 index 00000000..e2caea2a --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_gesture.h @@ -0,0 +1,117 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gesture.h + * + * Include file for SDL gesture event handling. + */ + +#ifndef SDL_gesture_h_ +#define SDL_gesture_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "SDL_touch.h" + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_GestureID; + +/* Function prototypes */ + +/** + * Begin recording a gesture on a specified touch device or all touch devices. + * + * If the parameter `touchId` is -1 (i.e., all devices), this function will + * always return 1, regardless of whether there actually are any devices. + * + * \param touchId the touch device id, or -1 for all touch devices + * \returns 1 on success or 0 if the specified device could not be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice + */ +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); + + +/** + * Save all currently loaded Dollar Gesture templates. + * + * \param dst a SDL_RWops to save to + * \returns the number of saved templates on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); + +/** + * Save a currently loaded Dollar Gesture template. + * + * \param gestureId a gesture id + * \param dst a SDL_RWops to save to + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveAllDollarTemplates + */ +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); + + +/** + * Load Dollar Gesture templates from a file. + * + * \param touchId a touch id + * \param src a SDL_RWops to load from + * \returns the number of loaded templates on success or a negative error code + * (or 0) on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SaveAllDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gesture_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_guid.h b/thirdparty/SDL/include/SDL/SDL_guid.h new file mode 100644 index 00000000..b971636a --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_guid.h @@ -0,0 +1,100 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_guid.h + * + * Include file for handling ::SDL_GUID values. + */ + +#ifndef SDL_guid_h_ +#define SDL_guid_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An SDL_GUID is a 128-bit identifier for an input device that + * identifies that device across runs of SDL programs on the same + * platform. If the device is detached and then re-attached to a + * different port, or if the base system is rebooted, the device + * should still report the same GUID. + * + * GUIDs are as precise as possible but are not guaranteed to + * distinguish physically distinct but equivalent devices. For + * example, two game controllers from the same vendor with the same + * product ID and revision may have the same GUID. + * + * GUIDs may be platform-dependent (i.e., the same device may report + * different GUIDs on different operating systems). + */ +typedef struct { + Uint8 data[16]; +} SDL_GUID; + +/* Function prototypes */ + +/** + * Get an ASCII string representation for a given ::SDL_GUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the ::SDL_GUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a ::SDL_GUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a ::SDL_GUID structure. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GUIDToString + */ +extern DECLSPEC SDL_GUID SDLCALL SDL_GUIDFromString(const char *pchGUID); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_guid_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_haptic.h b/thirdparty/SDL/include/SDL/SDL_haptic.h new file mode 100644 index 00000000..f240ae92 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_haptic.h @@ -0,0 +1,1341 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_haptic.h + * + * \brief The SDL haptic subsystem allows you to control haptic (force feedback) + * devices. + * + * The basic usage is as follows: + * - Initialize the subsystem (::SDL_INIT_HAPTIC). + * - Open a haptic device. + * - SDL_HapticOpen() to open from index. + * - SDL_HapticOpenFromJoystick() to open from an existing joystick. + * - Create an effect (::SDL_HapticEffect). + * - Upload the effect with SDL_HapticNewEffect(). + * - Run the effect with SDL_HapticRunEffect(). + * - (optional) Free the effect with SDL_HapticDestroyEffect(). + * - Close the haptic device with SDL_HapticClose(). + * + * \par Simple rumble example: + * \code + * SDL_Haptic *haptic; + * + * // Open the device + * haptic = SDL_HapticOpen( 0 ); + * if (haptic == NULL) + * return -1; + * + * // Initialize simple rumble + * if (SDL_HapticRumbleInit( haptic ) != 0) + * return -1; + * + * // Play effect at 50% strength for 2 seconds + * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) + * return -1; + * SDL_Delay( 2000 ); + * + * // Clean up + * SDL_HapticClose( haptic ); + * \endcode + * + * \par Complete example: + * \code + * int test_haptic( SDL_Joystick * joystick ) { + * SDL_Haptic *haptic; + * SDL_HapticEffect effect; + * int effect_id; + * + * // Open the device + * haptic = SDL_HapticOpenFromJoystick( joystick ); + * if (haptic == NULL) return -1; // Most likely joystick isn't haptic + * + * // See if it can do sine waves + * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { + * SDL_HapticClose(haptic); // No sine effect + * return -1; + * } + * + * // Create the effect + * SDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + * effect.type = SDL_HAPTIC_SINE; + * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates + * effect.periodic.direction.dir[0] = 18000; // Force comes from south + * effect.periodic.period = 1000; // 1000 ms + * effect.periodic.magnitude = 20000; // 20000/32767 strength + * effect.periodic.length = 5000; // 5 seconds long + * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength + * effect.periodic.fade_length = 1000; // Takes 1 second to fade away + * + * // Upload the effect + * effect_id = SDL_HapticNewEffect( haptic, &effect ); + * + * // Test the effect + * SDL_HapticRunEffect( haptic, effect_id, 1 ); + * SDL_Delay( 5000); // Wait for the effect to finish + * + * // We destroy the effect, although closing the device also does this + * SDL_HapticDestroyEffect( haptic, effect_id ); + * + * // Close the device + * SDL_HapticClose(haptic); + * + * return 0; // Success + * } + * \endcode + */ + +#ifndef SDL_haptic_h_ +#define SDL_haptic_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF). + * + * At the moment the magnitude variables are mixed between signed/unsigned, and + * it is also not made clear that ALL of those variables expect a max of 0x7FFF. + * + * Some platforms may have higher precision than that (Linux FF, Windows XInput) + * so we should fix the inconsistency in favor of higher possible precision, + * adjusting for platforms that use different scales. + * -flibit + */ + +/** + * \typedef SDL_Haptic + * + * \brief The haptic structure used to identify an SDL haptic. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + */ +struct _SDL_Haptic; +typedef struct _SDL_Haptic SDL_Haptic; + + +/** + * \name Haptic features + * + * Different haptic features a device can have. + */ +/* @{ */ + +/** + * \name Haptic effects + */ +/* @{ */ + +/** + * \brief Constant effect supported. + * + * Constant haptic effect. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_CONSTANT (1u<<0) + +/** + * \brief Sine wave effect supported. + * + * Periodic haptic effect that simulates sine waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SINE (1u<<1) + +/** + * \brief Left/Right effect supported. + * + * Haptic effect for direct control over high/low frequency motors. + * + * \sa SDL_HapticLeftRight + * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, + * we ran out of bits, and this is important for XInput devices. + */ +#define SDL_HAPTIC_LEFTRIGHT (1u<<2) + +/* !!! FIXME: put this back when we have more bits in 2.1 */ +/* #define SDL_HAPTIC_SQUARE (1<<2) */ + +/** + * \brief Triangle wave effect supported. + * + * Periodic haptic effect that simulates triangular waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_TRIANGLE (1u<<3) + +/** + * \brief Sawtoothup wave effect supported. + * + * Periodic haptic effect that simulates saw tooth up waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) + +/** + * \brief Sawtoothdown wave effect supported. + * + * Periodic haptic effect that simulates saw tooth down waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) + +/** + * \brief Ramp effect supported. + * + * Ramp haptic effect. + * + * \sa SDL_HapticRamp + */ +#define SDL_HAPTIC_RAMP (1u<<6) + +/** + * \brief Spring effect supported - uses axes position. + * + * Condition haptic effect that simulates a spring. Effect is based on the + * axes position. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_SPRING (1u<<7) + +/** + * \brief Damper effect supported - uses axes velocity. + * + * Condition haptic effect that simulates dampening. Effect is based on the + * axes velocity. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_DAMPER (1u<<8) + +/** + * \brief Inertia effect supported - uses axes acceleration. + * + * Condition haptic effect that simulates inertia. Effect is based on the axes + * acceleration. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_INERTIA (1u<<9) + +/** + * \brief Friction effect supported - uses axes movement. + * + * Condition haptic effect that simulates friction. Effect is based on the + * axes movement. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_FRICTION (1u<<10) + +/** + * \brief Custom effect is supported. + * + * User defined custom haptic effect. + */ +#define SDL_HAPTIC_CUSTOM (1u<<11) + +/* @} *//* Haptic effects */ + +/* These last few are features the device has, not effects */ + +/** + * \brief Device can set global gain. + * + * Device supports setting the global gain. + * + * \sa SDL_HapticSetGain + */ +#define SDL_HAPTIC_GAIN (1u<<12) + +/** + * \brief Device can set autocenter. + * + * Device supports setting autocenter. + * + * \sa SDL_HapticSetAutocenter + */ +#define SDL_HAPTIC_AUTOCENTER (1u<<13) + +/** + * \brief Device can be queried for effect status. + * + * Device supports querying effect status. + * + * \sa SDL_HapticGetEffectStatus + */ +#define SDL_HAPTIC_STATUS (1u<<14) + +/** + * \brief Device can be paused. + * + * Devices supports being paused. + * + * \sa SDL_HapticPause + * \sa SDL_HapticUnpause + */ +#define SDL_HAPTIC_PAUSE (1u<<15) + + +/** + * \name Direction encodings + */ +/* @{ */ + +/** + * \brief Uses polar coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_POLAR 0 + +/** + * \brief Uses cartesian coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_CARTESIAN 1 + +/** + * \brief Uses spherical coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_SPHERICAL 2 + +/** + * \brief Use this value to play an effect on the steering wheel axis. This + * provides better compatibility across platforms and devices as SDL will guess + * the correct axis. + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_STEERING_AXIS 3 + +/* @} *//* Direction encodings */ + +/* @} *//* Haptic features */ + +/* + * Misc defines. + */ + +/** + * \brief Used to play a device an infinite number of times. + * + * \sa SDL_HapticRunEffect + */ +#define SDL_HAPTIC_INFINITY 4294967295U + + +/** + * \brief Structure that represents a haptic direction. + * + * This is the direction where the force comes from, + * instead of the direction in which the force is exerted. + * + * Directions can be specified by: + * - ::SDL_HAPTIC_POLAR : Specified by polar coordinates. + * - ::SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates. + * - ::SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates. + * + * Cardinal directions of the haptic device are relative to the positioning + * of the device. North is considered to be away from the user. + * + * The following diagram represents the cardinal directions: + * \verbatim + .--. + |__| .-------. + |=.| |.-----.| + |--| || || + | | |'-----'| + |__|~')_____(' + [ COMPUTER ] + + + North (0,-1) + ^ + | + | + (-1,0) West <----[ HAPTIC ]----> East (1,0) + | + | + v + South (0,1) + + + [ USER ] + \|||/ + (o o) + ---ooO-(_)-Ooo--- + \endverbatim + * + * If type is ::SDL_HAPTIC_POLAR, direction is encoded by hundredths of a + * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses + * the first \c dir parameter. The cardinal directions would be: + * - North: 0 (0 degrees) + * - East: 9000 (90 degrees) + * - South: 18000 (180 degrees) + * - West: 27000 (270 degrees) + * + * If type is ::SDL_HAPTIC_CARTESIAN, direction is encoded by three positions + * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses + * the first three \c dir parameters. The cardinal directions would be: + * - North: 0,-1, 0 + * - East: 1, 0, 0 + * - South: 0, 1, 0 + * - West: -1, 0, 0 + * + * The Z axis represents the height of the effect if supported, otherwise + * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you + * can use any multiple you want, only the direction matters. + * + * If type is ::SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. + * The first two \c dir parameters are used. The \c dir parameters are as + * follows (all values are in hundredths of degrees): + * - Degrees from (1, 0) rotated towards (0, 1). + * - Degrees towards (0, 0, 1) (device needs at least 3 axes). + * + * + * Example of force coming from the south with all encodings (force coming + * from the south means the user will have to pull the stick to counteract): + * \code + * SDL_HapticDirection direction; + * + * // Cartesian directions + * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding. + * direction.dir[0] = 0; // X position + * direction.dir[1] = 1; // Y position + * // Assuming the device has 2 axes, we don't need to specify third parameter. + * + * // Polar directions + * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding. + * direction.dir[0] = 18000; // Polar only uses first parameter + * + * // Spherical coordinates + * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding + * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters. + * \endcode + * + * \sa SDL_HAPTIC_POLAR + * \sa SDL_HAPTIC_CARTESIAN + * \sa SDL_HAPTIC_SPHERICAL + * \sa SDL_HAPTIC_STEERING_AXIS + * \sa SDL_HapticEffect + * \sa SDL_HapticNumAxes + */ +typedef struct SDL_HapticDirection +{ + Uint8 type; /**< The type of encoding. */ + Sint32 dir[3]; /**< The encoded direction. */ +} SDL_HapticDirection; + + +/** + * \brief A structure containing a template for a Constant effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CONSTANT effect. + * + * A constant effect applies a constant force in the specified direction + * to the joystick. + * + * \sa SDL_HAPTIC_CONSTANT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticConstant +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CONSTANT */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Constant */ + Sint16 level; /**< Strength of the constant effect. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticConstant; + +/** + * \brief A structure containing a template for a Periodic effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SINE + * - ::SDL_HAPTIC_LEFTRIGHT + * - ::SDL_HAPTIC_TRIANGLE + * - ::SDL_HAPTIC_SAWTOOTHUP + * - ::SDL_HAPTIC_SAWTOOTHDOWN + * + * A periodic effect consists in a wave-shaped effect that repeats itself + * over time. The type determines the shape of the wave and the parameters + * determine the dimensions of the wave. + * + * Phase is given by hundredth of a degree meaning that giving the phase a value + * of 9000 will displace it 25% of its period. Here are sample values: + * - 0: No phase displacement. + * - 9000: Displaced 25% of its period. + * - 18000: Displaced 50% of its period. + * - 27000: Displaced 75% of its period. + * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred. + * + * Examples: + * \verbatim + SDL_HAPTIC_SINE + __ __ __ __ + / \ / \ / \ / + / \__/ \__/ \__/ + + SDL_HAPTIC_SQUARE + __ __ __ __ __ + | | | | | | | | | | + | |__| |__| |__| |__| | + + SDL_HAPTIC_TRIANGLE + /\ /\ /\ /\ /\ + / \ / \ / \ / \ / + / \/ \/ \/ \/ + + SDL_HAPTIC_SAWTOOTHUP + /| /| /| /| /| /| /| + / | / | / | / | / | / | / | + / |/ |/ |/ |/ |/ |/ | + + SDL_HAPTIC_SAWTOOTHDOWN + \ |\ |\ |\ |\ |\ |\ | + \ | \ | \ | \ | \ | \ | \ | + \| \| \| \| \| \| \| + \endverbatim + * + * \sa SDL_HAPTIC_SINE + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HAPTIC_TRIANGLE + * \sa SDL_HAPTIC_SAWTOOTHUP + * \sa SDL_HAPTIC_SAWTOOTHDOWN + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticPeriodic +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT, + ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or + ::SDL_HAPTIC_SAWTOOTHDOWN */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Periodic */ + Uint16 period; /**< Period of the wave. */ + Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ + Sint16 offset; /**< Mean value of the wave. */ + Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticPeriodic; + +/** + * \brief A structure containing a template for a Condition effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SPRING: Effect based on axes position. + * - ::SDL_HAPTIC_DAMPER: Effect based on axes velocity. + * - ::SDL_HAPTIC_INERTIA: Effect based on axes acceleration. + * - ::SDL_HAPTIC_FRICTION: Effect based on axes movement. + * + * Direction is handled by condition internals instead of a direction member. + * The condition effect specific members have three parameters. The first + * refers to the X axis, the second refers to the Y axis and the third + * refers to the Z axis. The right terms refer to the positive side of the + * axis and the left terms refer to the negative side of the axis. Please + * refer to the ::SDL_HapticDirection diagram for which side is positive and + * which is negative. + * + * \sa SDL_HapticDirection + * \sa SDL_HAPTIC_SPRING + * \sa SDL_HAPTIC_DAMPER + * \sa SDL_HAPTIC_INERTIA + * \sa SDL_HAPTIC_FRICTION + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCondition +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SPRING, ::SDL_HAPTIC_DAMPER, + ::SDL_HAPTIC_INERTIA or ::SDL_HAPTIC_FRICTION */ + SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Condition */ + Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */ + Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */ + Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */ + Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */ + Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */ + Sint16 center[3]; /**< Position of the dead zone. */ +} SDL_HapticCondition; + +/** + * \brief A structure containing a template for a Ramp effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect. + * + * The ramp effect starts at start strength and ends at end strength. + * It augments in linear fashion. If you use attack and fade with a ramp + * the effects get added to the ramp effect making the effect become + * quadratic instead of linear. + * + * \sa SDL_HAPTIC_RAMP + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticRamp +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_RAMP */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Ramp */ + Sint16 start; /**< Beginning strength level. */ + Sint16 end; /**< Ending strength level. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticRamp; + +/** + * \brief A structure containing a template for a Left/Right effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect. + * + * The Left/Right effect is used to explicitly control the large and small + * motors, commonly found in modern game controllers. The small (right) motor + * is high frequency, and the large (left) motor is low frequency. + * + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticLeftRight +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_LEFTRIGHT */ + + /* Replay */ + Uint32 length; /**< Duration of the effect in milliseconds. */ + + /* Rumble */ + Uint16 large_magnitude; /**< Control of the large controller motor. */ + Uint16 small_magnitude; /**< Control of the small controller motor. */ +} SDL_HapticLeftRight; + +/** + * \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CUSTOM effect. + * + * A custom force feedback effect is much like a periodic effect, where the + * application can define its exact shape. You will have to allocate the + * data yourself. Data should consist of channels * samples Uint16 samples. + * + * If channels is one, the effect is rotated using the defined direction. + * Otherwise it uses the samples in data for the different axes. + * + * \sa SDL_HAPTIC_CUSTOM + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCustom +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CUSTOM */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Custom */ + Uint8 channels; /**< Axes to use, minimum of one. */ + Uint16 period; /**< Sample periods. */ + Uint16 samples; /**< Amount of samples. */ + Uint16 *data; /**< Should contain channels*samples items. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticCustom; + +/** + * \brief The generic template for any haptic effect. + * + * All values max at 32767 (0x7FFF). Signed values also can be negative. + * Time values unless specified otherwise are in milliseconds. + * + * You can also pass ::SDL_HAPTIC_INFINITY to length instead of a 0-32767 + * value. Neither delay, interval, attack_length nor fade_length support + * ::SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends. + * + * Additionally, the ::SDL_HAPTIC_RAMP effect does not support a duration of + * ::SDL_HAPTIC_INFINITY. + * + * Button triggers may not be supported on all devices, it is advised to not + * use them if possible. Buttons start at index 1 instead of index 0 like + * the joystick. + * + * If both attack_length and fade_level are 0, the envelope is not used, + * otherwise both values are used. + * + * Common parts: + * \code + * // Replay - All effects have this + * Uint32 length; // Duration of effect (ms). + * Uint16 delay; // Delay before starting effect. + * + * // Trigger - All effects have this + * Uint16 button; // Button that triggers effect. + * Uint16 interval; // How soon before effect can be triggered again. + * + * // Envelope - All effects except condition effects have this + * Uint16 attack_length; // Duration of the attack (ms). + * Uint16 attack_level; // Level at the start of the attack. + * Uint16 fade_length; // Duration of the fade out (ms). + * Uint16 fade_level; // Level at the end of the fade. + * \endcode + * + * + * Here we have an example of a constant effect evolution in time: + * \verbatim + Strength + ^ + | + | effect level --> _________________ + | / \ + | / \ + | / \ + | / \ + | attack_level --> | \ + | | | <--- fade_level + | + +--------------------------------------------------> Time + [--] [---] + attack_length fade_length + + [------------------][-----------------------] + delay length + \endverbatim + * + * Note either the attack_level or the fade_level may be above the actual + * effect level. + * + * \sa SDL_HapticConstant + * \sa SDL_HapticPeriodic + * \sa SDL_HapticCondition + * \sa SDL_HapticRamp + * \sa SDL_HapticLeftRight + * \sa SDL_HapticCustom + */ +typedef union SDL_HapticEffect +{ + /* Common for all force feedback effects */ + Uint16 type; /**< Effect type. */ + SDL_HapticConstant constant; /**< Constant effect. */ + SDL_HapticPeriodic periodic; /**< Periodic effect. */ + SDL_HapticCondition condition; /**< Condition effect. */ + SDL_HapticRamp ramp; /**< Ramp effect. */ + SDL_HapticLeftRight leftright; /**< Left/Right effect. */ + SDL_HapticCustom custom; /**< Custom effect. */ +} SDL_HapticEffect; + + +/* Function prototypes */ + +/** + * Count the number of haptic devices attached to the system. + * + * \returns the number of haptic devices detected on the system or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticName + */ +extern DECLSPEC int SDLCALL SDL_NumHaptics(void); + +/** + * Get the implementation dependent name of a haptic device. + * + * This can be called before any joysticks are opened. If no name can be + * found, this function returns NULL. + * + * \param device_index index of the device to query. + * \returns the name of the device or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_NumHaptics + */ +extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); + +/** + * Open a haptic device for use. + * + * The index passed as an argument refers to the N'th haptic device on this + * system. + * + * When opening a haptic device, its gain will be set to maximum and + * autocenter will be disabled. To modify these values use SDL_HapticSetGain() + * and SDL_HapticSetAutocenter(). + * + * \param device_index index of the device to open + * \returns the device identifier or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticOpenFromMouse + * \sa SDL_HapticPause + * \sa SDL_HapticSetAutocenter + * \sa SDL_HapticSetGain + * \sa SDL_HapticStopAll + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); + +/** + * Check if the haptic device at the designated index has been opened. + * + * \param device_index the index of the device to query + * \returns 1 if it has been opened, 0 if it hasn't or on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticIndex + * \sa SDL_HapticOpen + */ +extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); + +/** + * Get the index of a haptic device. + * + * \param haptic the SDL_Haptic device to query + * \returns the index of the specified haptic device or a negative error code + * on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpened + */ +extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); + +/** + * Query whether or not the current mouse has haptic capabilities. + * + * \returns SDL_TRUE if the mouse is haptic or SDL_FALSE if it isn't. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromMouse + */ +extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); + +/** + * Try to open a haptic device from the current mouse. + * + * \returns the haptic device identifier or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_MouseIsHaptic + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); + +/** + * Query if a joystick has haptic features. + * + * \param joystick the SDL_Joystick to test for haptic capabilities + * \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromJoystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); + +/** + * Open a haptic device for use from a joystick device. + * + * You must still close the haptic device separately. It will not be closed + * with the joystick. + * + * When opened from a joystick you should first close the haptic device before + * closing the joystick device. If not, on some implementations the haptic + * device will also get unallocated and you'll be unable to use force feedback + * on that device. + * + * \param joystick the SDL_Joystick to create a haptic device from + * \returns a valid haptic device identifier on success or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticOpen + * \sa SDL_JoystickIsHaptic + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * + joystick); + +/** + * Close a haptic device previously opened with SDL_HapticOpen(). + * + * \param haptic the SDL_Haptic device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + */ +extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); + +/** + * Get the number of effects a haptic device can store. + * + * On some platforms this isn't fully supported, and therefore is an + * approximation. Always check to see if your created effect was actually + * created and do not rely solely on SDL_HapticNumEffects(). + * + * \param haptic the SDL_Haptic device to query + * \returns the number of effects the haptic device can store or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffectsPlaying + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); + +/** + * Get the number of effects a haptic device can play at the same time. + * + * This is not supported on all platforms, but will always return a value. + * + * \param haptic the SDL_Haptic device to query maximum playing effects + * \returns the number of effects the haptic device can play at the same time + * or a negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); + +/** + * Get the haptic device's supported features in bitwise manner. + * + * \param haptic the SDL_Haptic device to query + * \returns a list of supported haptic features in bitwise manner (OR'd), or 0 + * on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticEffectSupported + * \sa SDL_HapticNumEffects + */ +extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); + + +/** + * Get the number of haptic axes the device has. + * + * The number of haptic axes might be useful if working with the + * SDL_HapticDirection effect. + * + * \param haptic the SDL_Haptic device to query + * \returns the number of axes on success or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); + +/** + * Check to see if an effect is supported by a haptic device. + * + * \param haptic the SDL_Haptic device to query + * \param effect the desired effect to query + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, + SDL_HapticEffect * + effect); + +/** + * Create a new haptic effect on a specified device. + * + * \param haptic an SDL_Haptic device to create the effect on + * \param effect an SDL_HapticEffect structure containing the properties of + * the effect to create + * \returns the ID of the effect on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticUpdateEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, + SDL_HapticEffect * effect); + +/** + * Update the properties of an effect. + * + * Can be used dynamically, although behavior when dynamically changing + * direction may be strange. Specifically the effect may re-upload itself and + * start playing from the start. You also cannot change the type either when + * running SDL_HapticUpdateEffect(). + * + * \param haptic the SDL_Haptic device that has the effect + * \param effect the identifier of the effect to update + * \param data an SDL_HapticEffect structure containing the new effect + * properties to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticNewEffect + * \sa SDL_HapticRunEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, + int effect, + SDL_HapticEffect * data); + +/** + * Run the haptic effect on its associated haptic device. + * + * To repeat the effect over and over indefinitely, set `iterations` to + * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make + * one instance of the effect last indefinitely (so the effect does not fade), + * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY` + * instead. + * + * \param haptic the SDL_Haptic device to run the effect on + * \param effect the ID of the haptic effect to run + * \param iterations the number of iterations to run the effect; use + * `SDL_HAPTIC_INFINITY` to repeat forever + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticGetEffectStatus + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, + int effect, + Uint32 iterations); + +/** + * Stop the haptic effect on its associated haptic device. + * + * * + * + * \param haptic the SDL_Haptic device to stop the effect on + * \param effect the ID of the haptic effect to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, + int effect); + +/** + * Destroy a haptic effect on the device. + * + * This will stop the effect if it's running. Effects are automatically + * destroyed when the device is closed. + * + * \param haptic the SDL_Haptic device to destroy the effect on + * \param effect the ID of the haptic effect to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, + int effect); + +/** + * Get the status of the current effect on the specified haptic device. + * + * Device must support the SDL_HAPTIC_STATUS feature. + * + * \param haptic the SDL_Haptic device to query for the effect status on + * \param effect the ID of the haptic effect to query its status + * \returns 0 if it isn't playing, 1 if it is playing, or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, + int effect); + +/** + * Set the global gain of the specified haptic device. + * + * Device must support the SDL_HAPTIC_GAIN feature. + * + * The user may specify the maximum gain by setting the environment variable + * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to + * SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the + * maximum. + * + * \param haptic the SDL_Haptic device to set the gain on + * \param gain value to set the gain to, should be between 0 and 100 (0 - 100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); + +/** + * Set the global autocenter of the device. + * + * Autocenter should be between 0 and 100. Setting it to 0 will disable + * autocentering. + * + * Device must support the SDL_HAPTIC_AUTOCENTER feature. + * + * \param haptic the SDL_Haptic device to set autocentering on + * \param autocenter value to set autocenter to (0-100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, + int autocenter); + +/** + * Pause a haptic device. + * + * Device must support the `SDL_HAPTIC_PAUSE` feature. Call + * SDL_HapticUnpause() to resume playback. + * + * Do not modify the effects nor add new ones while the device is paused. That + * can cause all sorts of weird errors. + * + * \param haptic the SDL_Haptic device to pause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticUnpause + */ +extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); + +/** + * Unpause a haptic device. + * + * Call to unpause after SDL_HapticPause(). + * + * \param haptic the SDL_Haptic device to unpause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticPause + */ +extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); + +/** + * Stop all the currently playing effects on a haptic device. + * + * \param haptic the SDL_Haptic device to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); + +/** + * Check whether rumble is supported on a haptic device. + * + * \param haptic haptic device to check for rumble support + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); + +/** + * Initialize a haptic device for simple rumble playback. + * + * \param haptic the haptic device to initialize for simple rumble playback + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); + +/** + * Run a simple rumble effect on a haptic device. + * + * \param haptic the haptic device to play the rumble effect on + * \param strength strength of the rumble to play as a 0-1 float value + * \param length length of the rumble to play in milliseconds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); + +/** + * Stop the simple rumble on a haptic device. + * + * \param haptic the haptic device to stop the rumble effect on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_haptic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_hidapi.h b/thirdparty/SDL/include/SDL/SDL_hidapi.h new file mode 100644 index 00000000..354af5c5 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_hidapi.h @@ -0,0 +1,451 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hidapi.h + * + * Header file for SDL HIDAPI functions. + * + * This is an adaptation of the original HIDAPI interface by Alan Ott, + * and includes source code licensed under the following BSD license: + * + Copyright (c) 2010, Alan Ott, Signal 11 Software + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Signal 11 Software nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + * + * If you would like a version of SDL without this code, you can build SDL + * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for example + * on iOS or tvOS to avoid a dependency on the CoreBluetooth framework. + */ + +#ifndef SDL_hidapi_h_ +#define SDL_hidapi_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle representing an open HID device + */ +struct SDL_hid_device_; +typedef struct SDL_hid_device_ SDL_hid_device; /**< opaque hidapi structure */ + +/** hidapi info structure */ +/** + * \brief Information about a connected HID device + */ +typedef struct SDL_hid_device_info +{ + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. */ + int interface_number; + + /** Additional information about the USB interface. + Valid on libusb and Android implementations. */ + int interface_class; + int interface_subclass; + int interface_protocol; + + /** Pointer to the next device */ + struct SDL_hid_device_info *next; +} SDL_hid_device_info; + + +/** + * Initialize the HIDAPI library. + * + * This function initializes the HIDAPI library. Calling it is not strictly + * necessary, as it will be called automatically by SDL_hid_enumerate() and + * any of the SDL_hid_open_*() functions if it is needed. This function should + * be called at the beginning of execution however, if there is a chance of + * HIDAPI handles being opened by different threads simultaneously. + * + * Each call to this function should have a matching call to SDL_hid_exit() + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_exit + */ +extern DECLSPEC int SDLCALL SDL_hid_init(void); + +/** + * Finalize the HIDAPI library. + * + * This function frees all of the static data associated with HIDAPI. It + * should be called at the end of execution to avoid memory leaks. + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_init + */ +extern DECLSPEC int SDLCALL SDL_hid_exit(void); + +/** + * Check to see if devices may have been added or removed. + * + * Enumerating the HID devices is an expensive operation, so you can call this + * to see if there have been any system device changes since the last call to + * this function. A change in the counter returned doesn't necessarily mean + * that anything has changed, but you can call SDL_hid_enumerate() to get an + * updated device list. + * + * Calling this function for the first time may cause a thread or other system + * resource to be allocated to track device change notifications. + * + * \returns a change counter that is incremented with each potential device + * change, or 0 if device change detection isn't available. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_enumerate + */ +extern DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void); + +/** + * Enumerate the HID Devices. + * + * This function returns a linked list of all the HID devices attached to the + * system which match vendor_id and product_id. If `vendor_id` is set to 0 + * then any vendor matches. If `product_id` is set to 0 then any product + * matches. If `vendor_id` and `product_id` are both set to 0, then all HID + * devices will be returned. + * + * \param vendor_id The Vendor ID (VID) of the types of device to open. + * \param product_id The Product ID (PID) of the types of device to open. + * \returns a pointer to a linked list of type SDL_hid_device_info, containing + * information about the HID devices attached to the system, or NULL + * in the case of failure. Free this linked list by calling + * SDL_hid_free_enumeration(). + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_device_change_count + */ +extern DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id); + +/** + * Free an enumeration Linked List + * + * This function frees a linked list created by SDL_hid_enumerate(). + * + * \param devs Pointer to a list of struct_device returned from + * SDL_hid_enumerate(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs); + +/** + * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally + * a serial number. + * + * If `serial_number` is NULL, the first device with the specified VID and PID + * is opened. + * + * \param vendor_id The Vendor ID (VID) of the device to open. + * \param product_id The Product ID (PID) of the device to open. + * \param serial_number The Serial Number of the device to open (Optionally + * NULL). + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + +/** + * Open a HID device by its path name. + * + * The path name be determined by calling SDL_hid_enumerate(), or a + * platform-specific path name can be used (eg: /dev/hidraw0 on Linux). + * + * \param path The path name of the device to open + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */); + +/** + * Write an Output report to a HID device. + * + * The first byte of `data` must contain the Report ID. For devices which only + * support a single report, this must be set to 0x0. The remaining bytes + * contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_write() will always contain one more byte than the report contains. + * For example, if a hid report is 16 bytes long, 17 bytes must be passed to + * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report), + * followed by the report data (16 bytes). In this example, the length passed + * in would be 17. + * + * SDL_hid_write() will send the data on the first OUT endpoint, if one + * exists. If it does not, it will send the data through the Control Endpoint + * (Endpoint 0). + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Read an Input report from a HID device with timeout. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \param milliseconds timeout in milliseconds or -1 for blocking wait. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read within the timeout period, this function + * returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds); + +/** + * Read an Input report from a HID device. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read and the handle is in non-blocking mode, this + * function returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Set the device handle to be non-blocking. + * + * In non-blocking mode calls to SDL_hid_read() will return immediately with a + * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read() + * will wait (block) until there is data to read before returning. + * + * Nonblocking can be turned on and off at any time. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param nonblock enable or not the nonblocking reads - 1 to enable + * nonblocking - 0 to disable nonblocking. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock); + +/** + * Send a Feature report to the device. + * + * Feature reports are sent over the Control endpoint as a Set_Report + * transfer. The first byte of `data` must contain the Report ID. For devices + * which only support a single report, this must be set to 0x0. The remaining + * bytes contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_send_feature_report() will always contain one more byte than the + * report contains. For example, if a hid report is 16 bytes long, 17 bytes + * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for + * devices which do not use numbered reports), followed by the report data (16 + * bytes). In this example, the length passed in would be 17. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send, including the report + * number. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Get a feature report from a HID device. + * + * Set the first byte of `data` to the Report ID of the report to be read. + * Make sure to allow space for this extra byte in `data`. Upon return, the + * first byte will still contain the Report ID, and the report data will start + * in data[1]. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into, including the Report ID. + * Set the first byte of `data` to the Report ID of the report to + * be read, or set it to zero if your device does not use numbered + * reports. + * \param length The number of bytes to read, including an extra byte for the + * report ID. The buffer can be longer than the actual report. + * \returns the number of bytes read plus one for the report ID (which is + * still in the first byte), or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Close a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_close(SDL_hid_device *dev); + +/** + * Get The Manufacturer String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Product String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Serial Number String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get a string from a HID device, based on its string index. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string_index The index of the string to get. + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen); + +/** + * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers + * + * \param active SDL_TRUE to start the scan, SDL_FALSE to stop the scan + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_ble_scan(SDL_bool active); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hidapi_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_hints.h b/thirdparty/SDL/include/SDL/SDL_hints.h new file mode 100644 index 00000000..e7cddba0 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_hints.h @@ -0,0 +1,2405 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hints.h + * + * Official documentation for SDL configuration variables + * + * This file contains functions to set and get configuration hints, + * as well as listing each of them alphabetically. + * + * The convention for naming hints is SDL_HINT_X, where "SDL_X" is + * the environment variable that can be used to override the default. + * + * In general these hints are just that - they may or may not be + * supported or applicable on any given platform, but they provide + * a way for an application or user to give the library a hint as + * to how they would like the library to work. + */ + +#ifndef SDL_hints_h_ +#define SDL_hints_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A variable controlling whether the Android / iOS built-in + * accelerometer should be listed as a joystick device. + * + * This variable can be set to the following values: + * "0" - The accelerometer is not listed as a joystick + * "1" - The accelerometer is available as a 3 axis joystick (the default). + */ +#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" + +/** + * \brief Specify the behavior of Alt+Tab while the keyboard is grabbed. + * + * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed + * and your window is full-screen. This prevents the user from getting stuck in + * your application if you've enabled keyboard grab. + * + * The variable can be set to the following values: + * "0" - SDL will not handle Alt+Tab. Your application is responsible + for handling Alt+Tab while the keyboard is grabbed. + * "1" - SDL will minimize your window when Alt+Tab is pressed (default) +*/ +#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" + +/** + * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. + * This is a debugging aid for developers and not expected to be used by end users. The default is "1" + * + * This variable can be set to the following values: + * "0" - don't allow topmost + * "1" - allow topmost + */ +#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" + +/** + * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" + +/** + * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" + +/** + * \brief A variable to control whether the event loop will block itself when the app is paused. + * + * The variable can be set to the following values: + * "0" - Non blocking. + * "1" - Blocking. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE" + +/** + * \brief A variable to control whether SDL will pause audio in background + * (Requires SDL_ANDROID_BLOCK_ON_PAUSE as "Non blocking") + * + * The variable can be set to the following values: + * "0" - Non paused. + * "1" - Paused. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO "SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO" + +/** + * \brief A variable to control whether we trap the Android back button to handle it manually. + * This is necessary for the right mouse button to work on some Android devices, or + * to be able to trap the back button for use in your code reliably. If set to true, + * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of + * SDL_SCANCODE_AC_BACK. + * + * The variable can be set to the following values: + * "0" - Back button will be handled as usual for system. (default) + * "1" - Back button will be trapped, allowing you to handle the key press + * manually. (This will also let right mouse click work on systems + * where the right mouse button functions as back.) + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" + +/** + * \brief Specify an application name. + * + * This hint lets you specify the application name sent to the OS when + * required. For example, this will often appear in volume control applets for + * audio streams, and in lists of applications which are inhibiting the + * screensaver. You should use a string that describes your program ("My Game + * 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: probably the application's name or "SDL Application" if SDL + * doesn't have any better information. + * + * Note that, for audio streams, this can be overridden with + * SDL_HINT_AUDIO_DEVICE_APP_NAME. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_APP_NAME "SDL_APP_NAME" + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + +/** + * \brief A variable controlling the audio category on iOS and Mac OS X + * + * This variable can be set to the following values: + * + * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default) + * "playback" - Use the AVAudioSessionCategoryPlayback category + * + * For more information, see Apple's documentation: + * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html + */ +#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your program ("My Game 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: this will be the name set with SDL_HINT_APP_NAME, if that hint is + * set. Otherwise, it'll probably the application's name or "SDL Application" + * if SDL doesn't have any better information. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing ("audio stream" is + * probably sufficient in many cases, but this could be useful for something + * like "team chat" if you have a headset playing VoIP audio separately). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "audio stream" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME" + +/** + * \brief Specify an application role for an audio device. + * + * Some audio backends (such as Pipewire) allow you to describe the role of + * your audio stream. Among other things, this description might show up in + * a system control panel or software for displaying and manipulating media + * playback/capture graphs. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing (Game, Music, Movie, + * etc...). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE" + +/** + * \brief A variable controlling speed/quality tradeoff of audio resampling. + * + * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ ) + * to handle audio resampling. There are different resampling modes available + * that produce different levels of quality, using more CPU. + * + * If this hint isn't specified to a valid setting, or libsamplerate isn't + * available, SDL will use the default, internal resampling algorithm. + * + * Note that this is currently only applicable to resampling audio that is + * being written to a device for playback or audio being read from a device + * for capture. SDL_AudioCVT always uses the default resampler (although this + * might change for SDL 2.1). + * + * This hint is currently only checked at audio subsystem initialization. + * + * This variable can be set to the following values: + * + * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast) + * "1" or "fast" - Use fast, slightly higher quality resampling, if available + * "2" or "medium" - Use medium quality resampling, if available + * "3" or "best" - Use high quality resampling, if available + */ +#define SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" + +/** + * \brief A variable controlling whether SDL updates joystick state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_JoystickUpdate() manually + * "1" - SDL will automatically call SDL_JoystickUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_JOYSTICKS "SDL_AUTO_UPDATE_JOYSTICKS" + +/** + * \brief A variable controlling whether SDL updates sensor state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_SensorUpdate() manually + * "1" - SDL will automatically call SDL_SensorUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_SENSORS "SDL_AUTO_UPDATE_SENSORS" + +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Override for SDL_GetDisplayUsableBounds() + * + * If set, this hint will override the expected results for + * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want + * to do this, but this allows an embedded system to request that some of the + * screen be reserved for other uses when paired with a well-behaved + * application. + * + * The contents of this hint must be 4 comma-separated integers, the first + * is the bounds x, then y, width and height, in that order. + */ +#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" + +/** + * \brief Disable giving back control to the browser automatically + * when running with asyncify + * + * With -s ASYNCIFY, SDL2 calls emscripten_sleep during operations + * such as refreshing the screen or polling events. + * + * This hint only applies to the emscripten platform + * + * The variable can be set to the following values: + * "0" - Disable emscripten_sleep calls (if you give back browser control manually or use asyncify for other purposes) + * "1" - Enable emscripten_sleep calls (the default) + */ +#define SDL_HINT_EMSCRIPTEN_ASYNCIFY "SDL_EMSCRIPTEN_ASYNCIFY" + +/** + * \brief override the binding element for keyboard inputs for Emscripten builds + * + * This hint only applies to the emscripten platform + * + * The variable can be one of + * "#window" - The javascript window object (this is the default) + * "#document" - The javascript document object + * "#screen" - the javascript window.screen object + * "#canvas" - the WebGL canvas element + * any other string without a leading # sign applies to the element on the page with that ID. + */ +#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" + +/** + * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs + * + * The variable can be set to the following values: + * "0" - Do not scan for Steam Controllers + * "1" - Scan for Steam Controllers (the default) + * + * The default value is "1". This hint must be set before initializing the joystick subsystem. + */ +#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" + +/** + * \brief A variable controlling verbosity of the logging of SDL events pushed onto the internal queue. + * + * This variable can be set to the following values, from least to most verbose: + * + * "0" - Don't log any events (default) + * "1" - Log most events (other than the really spammy ones). + * "2" - Include mouse and finger motion events. + * "3" - Include SDL_SysWMEvent events. + * + * This is generally meant to be used to debug SDL itself, but can be useful + * for application developers that need better visibility into what is going + * on in the event queue. Logged events are sent through SDL_Log(), which + * means by default they appear on stdout on most platforms or maybe + * OutputDebugString() on Windows, and can be funneled by the app with + * SDL_LogSetOutputFunction(), etc. + * + * This hint can be toggled on and off at runtime, if you only need to log + * events for a small subset of program execution. + */ +#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" + +/** + * \brief A variable controlling whether raising the window should be done more forcefully + * + * This variable can be set to the following values: + * "0" - No forcing (the default) + * "1" - Extra level of forcing + * + * At present, this is only an issue under MS Windows, which makes it nearly impossible to + * programmatically move a window to the foreground, for "security" reasons. See + * http://stackoverflow.com/a/34414846 for a discussion. + */ +#define SDL_HINT_FORCE_RAISEWINDOW "SDL_HINT_FORCE_RAISEWINDOW" + +/** + * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. + * + * SDL can try to accelerate the SDL screen surface by using streaming + * textures with a 3D rendering engine. This variable controls whether and + * how this is done. + * + * This variable can be set to the following values: + * "0" - Disable 3D acceleration + * "1" - Enable 3D acceleration, using the default renderer. + * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) + * + * By default SDL tries to make a best guess for each platform whether + * to use acceleration or not. + */ +#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" + +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries. + * + * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + +/** + * \brief A variable that lets you provide a file with extra gamecontroller db entries. + * + * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE" + +/** + * \brief A variable that overrides the automatic controller type detection + * + * The variable should be comma separated entries, in the form: VID/PID=type + * + * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd + * + * The type should be one of: + * Xbox360 + * XboxOne + * PS3 + * PS4 + * PS5 + * SwitchPro + * + * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + */ +#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE" + +/** + * \brief A variable containing a list of devices to skip when scanning for game controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES" + +/** + * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT" + +/** + * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. + * + * For example, on Nintendo Switch controllers, normally you'd get: + * + * (Y) + * (X) (B) + * (A) + * + * but if this hint is set, you'll get: + * + * (X) + * (Y) (A) + * (B) + * + * The variable can be set to the following values: + * "0" - Report the face buttons by position, as though they were on an Xbox controller. + * "1" - Report the face buttons by label instead of position + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + +/** + * \brief A variable controlling whether the idle timer is disabled on iOS. + * + * When an iOS app does not receive touches for some time, the screen is + * dimmed automatically. For games where the accelerometer is the only input + * this is problematic. This functionality can be disabled by setting this + * hint. + * + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. + * + * This variable can be set to the following values: + * "0" - Enable idle timer + * "1" - Disable idle timer + */ +#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" + +/** + * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. + * + * The variable can be set to the following values: + * "0" - SDL_TEXTEDITING events are sent, and it is the application's + * responsibility to render the text from these events and + * differentiate it somehow from committed text. (default) + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * and text that is being composed will be rendered in its own UI. + */ +#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" + +/** + * \brief A variable to control whether certain IMEs should show native UI components (such as the Candidate List) instead of suppressing them. + * + * The variable can be set to the following values: + * "0" - Native UI components are not display. (default) + * "1" - Native UI components are displayed. + */ +#define SDL_HINT_IME_SHOW_UI "SDL_IME_SHOW_UI" + +/** + * \brief A variable to control if extended IME text support is enabled. + * If enabled then SDL_TextEditingExtEvent will be issued if the text would be truncated otherwise. + * Additionally SDL_TextInputEvent will be dispatched multiple times so that it is not truncated. + * + * The variable can be set to the following values: + * "0" - Legacy behavior. Text can be truncated, no heap allocations. (default) + * "1" - Modern behavior. + */ +#define SDL_HINT_IME_SUPPORT_EXTENDED_TEXT "SDL_IME_SUPPORT_EXTENDED_TEXT" + +/** + * \brief A variable controlling whether the home indicator bar on iPhone X + * should be hidden. + * + * This variable can be set to the following values: + * "0" - The indicator bar is not hidden (default for windowed applications) + * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) + * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) + */ +#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" + +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the background. + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + +/** + * \brief A variable controlling whether the HIDAPI joystick drivers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI drivers are not used + * "1" - HIDAPI drivers are used (the default) + * + * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below. + */ +#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE" + +/** + * \brief A variable controlling whether "low_frequency_rumble" and "high_frequency_rumble" is used to implement + * the GameCube controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2) + * this is useful for applications that need full compatibility for things like ADSR envelopes. + * Stop is implemented by setting "low_frequency_rumble" to "0" and "high_frequency_rumble" ">0" + * Rumble is both at any arbitrary value, + * StopHard is implemented by setting both "low_frequency_rumble" and "high_frequency_rumble" to "0" + * + * This variable can be set to the following values: + * "0" - Normal rumble behavior is behavior is used (default) + * "1" - Proper GameCube controller rumble behavior is used + * + */ +#define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch Joy-Cons should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS" + +/** + * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver + * + * This variable can be set to the following values: + * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad + * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS" + +/** + * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Online classic controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC "SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC" + +/** + * \brief A variable controlling whether the HIDAPI driver for NVIDIA SHIELD controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SHIELD "SDL_JOYSTICK_HIDAPI_SHIELD" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4" + +/** + * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS4 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value will also + * control the state of extended reports on PS5 controllers when the + * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE hint is not explicitly set. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS5 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5 "SDL_JOYSTICK_HIDAPI_PS5" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a PS5 controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED "SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED" + +/** + * \brief A variable controlling whether extended input reports should be used for PS5 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS5 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value defaults to + * the value of SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE "SDL_JOYSTICK_HIDAPI_PS5_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Google Stadia controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STADIA "SDL_JOYSTICK_HIDAPI_STADIA" + +/** + * \brief A variable controlling whether the HIDAPI driver for Steam Controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used for Steam Controllers, which requires Bluetooth access + * and may prompt the user for permission on iOS and Android. + * + * The default is "0" + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Pro controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Joy-Con controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED "SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Nintendo Switch controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED "SDL_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" + +/** + * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices. + * + * This variable can be set to the following values: + * "0" - RAWINPUT drivers are not used + * "1" - RAWINPUT drivers are used (the default) + */ +#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT" + +/** + * \brief A variable controlling whether the RAWINPUT driver should pull correlated data from XInput. + * + * This variable can be set to the following values: + * "0" - RAWINPUT driver will only use data from raw input APIs + * "1" - RAWINPUT driver will also pull data from XInput, providing + * better trigger axes, guide button presses, and rumble support + * for Xbox controllers + * + * The default is "1". This hint applies to any joysticks opened after setting the hint. + */ +#define SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT "SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT" + +/** + * \brief A variable controlling whether the ROG Chakram mice should show up as joysticks + * + * This variable can be set to the following values: + * "0" - ROG Chakram mice do not show up as joysticks (the default) + * "1" - ROG Chakram mice show up as joysticks + */ +#define SDL_HINT_JOYSTICK_ROG_CHAKRAM "SDL_JOYSTICK_ROG_CHAKRAM" + +/** + * \brief A variable controlling whether a separate thread should be used + * for handling joystick detection and raw input messages on Windows + * + * This variable can be set to the following values: + * "0" - A separate thread is not used (the default) + * "1" - A separate thread is used for handling raw input messages + * + */ +#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD" + +/** + * \brief Determines whether SDL enforces that DRM master is required in order + * to initialize the KMSDRM video backend. + * + * The DRM subsystem has a concept of a "DRM master" which is a DRM client that + * has the ability to set planes, set cursor, etc. When SDL is DRM master, it + * can draw to the screen using the SDL rendering APIs. Without DRM master, SDL + * is still able to process input and query attributes of attached displays, + * but it cannot change display state or draw to the screen directly. + * + * In some cases, it can be useful to have the KMSDRM backend even if it cannot + * be used for rendering. An app may want to use SDL for input processing while + * using another rendering API (such as an MMAL overlay on Raspberry Pi) or + * using its own code to render to DRM overlays that SDL doesn't support. + * + * This hint must be set before initializing the video subsystem. + * + * This variable can be set to the following values: + * "0" - SDL will allow usage of the KMSDRM backend without DRM master + * "1" - SDL Will require DRM master to use the KMSDRM backend (default) + */ +#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER" + +/** + * \brief A comma separated list of devices to open as joysticks + * + * This variable is currently only used by the Linux joystick driver. + */ +#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE" + +/** + * \brief A variable controlling whether joysticks on Linux will always treat 'hat' axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking whether they may be analog. + * + * This variable can be set to the following values: + * "0" - Only map hat axis inputs to digital hat outputs if the input axes appear to actually be digital (the default) + * "1" - Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as digital hats + */ +#define SDL_HINT_LINUX_DIGITAL_HATS "SDL_LINUX_DIGITAL_HATS" + +/** + * \brief A variable controlling whether digital hats on Linux will apply deadzones to their underlying input axes or use unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return digital hat values based on unfiltered input axis values + * "1" - Return digital hat values with deadzones on the input axes taken into account (the default) + */ +#define SDL_HINT_LINUX_HAT_DEADZONES "SDL_LINUX_HAT_DEADZONES" + +/** + * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux + * + * This variable can be set to the following values: + * "0" - Use /dev/input/event* + * "1" - Use /dev/input/js* + * + * By default the /dev/input/event* interfaces are used + */ +#define SDL_HINT_LINUX_JOYSTICK_CLASSIC "SDL_LINUX_JOYSTICK_CLASSIC" + +/** + * \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return unfiltered joystick axis values (the default) + * "1" - Return axis values with deadzones taken into account + */ +#define SDL_HINT_LINUX_JOYSTICK_DEADZONES "SDL_LINUX_JOYSTICK_DEADZONES" + +/** +* \brief When set don't force the SDL app to become a foreground process +* +* This hint only applies to Mac OS X. +* +*/ +#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" + +/** + * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac + * + * If present, holding ctrl while left clicking will generate a right click + * event when on Mac. + */ +#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" + +/** + * \brief A variable controlling whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing + * + * This variable can be set to the following values: + * "0" - Dispatching OpenGL context updates will block the dispatching thread until the main thread finishes processing (default). + * "1" - Dispatching OpenGL context updates will allow the dispatching thread to continue execution. + * + * Generally you want the default, but if you have OpenGL code in a background thread on a Mac, and the main thread + * hangs because it's waiting for that background thread, but that background thread is also hanging because it's + * waiting for the main thread to do an update, this might fix your issue. + * + * This hint only applies to macOS. + * + * This hint is available since SDL 2.24.0. + * + */ +#define SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH "SDL_MAC_OPENGL_ASYNC_DISPATCH" + +/** + * \brief A variable setting the double click radius, in pixels. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS" + +/** + * \brief A variable setting the double click time, in milliseconds. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME" + +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + +/** + * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode + */ +#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE" + +/** + * \brief A variable controlling whether relative mouse mode constrains the mouse to the center of the window + * + * This variable can be set to the following values: + * "0" - Relative mouse mode constrains the mouse to the window + * "1" - Relative mouse mode constrains the mouse to the center of the window + * + * Constraining to the center of the window works better for FPS games and when the + * application is running over RDP. Constraining to the whole window works better + * for 2D games and increases the chance that the mouse will be in the correct + * position when using high DPI mice. + * + * By default SDL will constrain the mouse to the center of the window + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_CENTER "SDL_MOUSE_RELATIVE_MODE_CENTER" + +/** + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" + +/** + * \brief A variable controlling whether relative mouse motion is affected by renderer scaling + * + * This variable can be set to the following values: + * "0" - Relative motion is unaffected by DPI or renderer's logical size + * "1" - Relative motion is scaled according to DPI scaling and logical size + * + * By default relative mouse deltas are affected by DPI and renderer scaling + */ +#define SDL_HINT_MOUSE_RELATIVE_SCALING "SDL_MOUSE_RELATIVE_SCALING" + +/** + * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode + */ +#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE" + +/** + * \brief A variable controlling whether a motion event should be generated for mouse warping in relative mode. + * + * This variable can be set to the following values: + * "0" - Warping the mouse will not generate a motion event in relative mode + * "1" - Warping the mouse will generate a motion event in relative mode + * + * By default warping the mouse will not generate motion events in relative mode. This avoids the application having to filter out large relative motion due to warping. + */ +#define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION" + +/** + * \brief A variable controlling whether mouse events should generate synthetic touch events + * + * This variable can be set to the following values: + * "0" - Mouse events will not generate touch events (default for desktop platforms) + * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS) + */ +#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS" + +/** + * \brief A variable controlling whether the mouse is captured while mouse buttons are pressed + * + * This variable can be set to the following values: + * "0" - The mouse is not captured while mouse buttons are pressed + * "1" - The mouse is captured while mouse buttons are pressed + * + * By default the mouse is captured while mouse buttons are pressed so if the mouse is dragged + * outside the window, the application continues to receive mouse events until the button is + * released. + */ +#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE" + +/** + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. + * + * This hint only applies to Unix-like platforms, and should set before + * any calls to SDL_Init() + * + * The variable can be set to the following values: + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it + * catches a signal, convert it into an SDL_QUIT event. + * "1" - SDL will not install a signal handler at all. + */ +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" + +/** + * \brief A variable controlling what driver to use for OpenGL ES contexts. + * + * On some platforms, currently Windows and X11, OpenGL drivers may support + * creating contexts with an OpenGL ES profile. By default SDL uses these + * profiles, when available, otherwise it attempts to load an OpenGL ES + * library, e.g. that provided by the ANGLE project. This variable controls + * whether SDL follows this default behaviour or will always load an + * OpenGL ES library. + * + * Circumstances where this is useful include + * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE, + * or emulator, e.g. those from ARM, Imagination or Qualcomm. + * - Resolving OpenGL ES function addresses at link time by linking with + * the OpenGL ES library instead of querying them at run time with + * SDL_GL_GetProcAddress(). + * + * Caution: for an application to work with the default behaviour across + * different OpenGL drivers it must query the OpenGL ES function + * addresses at run time using SDL_GL_GetProcAddress(). + * + * This variable is ignored on most platforms because OpenGL ES is native + * or not supported. + * + * This variable can be set to the following values: + * "0" - Use ES profile of OpenGL, if available. (Default when not set.) + * "1" - Load OpenGL ES library using the default library names. + * + */ +#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER" + +/** + * \brief A variable controlling which orientations are allowed on iOS/Android. + * + * In some circumstances it is necessary to be able to explicitly control + * which UI orientations are allowed. + * + * This variable is a space delimited list of the following values: + * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" + */ +#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" + +/** + * \brief A variable controlling the use of a sentinel event when polling the event queue + * + * This variable can be set to the following values: + * "0" - Disable poll sentinels + * "1" - Enable poll sentinels + * + * When polling for events, SDL_PumpEvents is used to gather new events from devices. + * If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will + * become stuck until the new events stop. + * This is most noticable when moving a high frequency mouse. + * + * By default, poll sentinels are enabled. + */ +#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL" + +/** + * \brief Override for SDL_GetPreferredLocales() + * + * If set, this will be favored over anything the OS might report for the + * user's preferred locales. Changing this hint at runtime will not generate + * a SDL_LOCALECHANGED event (but if you can change the hint, you can push + * your own event, if you want). + * + * The format of this hint is a comma-separated list of language and locale, + * combined with an underscore, as is a common format: "en_GB". Locale is + * optional: "en". So you might have a list like this: "en_GB,jp,es_PT" + */ +#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES" + +/** + * \brief A variable describing the content orientation on QtWayland-based platforms. + * + * On QtWayland platforms, windows are rotated client-side to allow for custom + * transitions. In order to correctly position overlays (e.g. volume bar) and + * gestures (e.g. events view, close/minimize gestures), the system needs to + * know in which orientation the application is currently drawing its contents. + * + * This does not cause the window to be rotated or resized, the application + * needs to take care of drawing the content in the right orientation (the + * framebuffer is always in portrait mode). + * + * This variable can be one of the following values: + * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" + */ +#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" + +/** + * \brief Flags to set on QtWayland windows to integrate with the native window manager. + * + * On QtWayland platforms, this hint controls the flags to set on the windows. + * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures. + * + * This variable is a space-separated list of the following values (empty = no flags): + * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager" + */ +#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS "SDL_QTWAYLAND_WINDOW_FLAGS" + +/** + * \brief A variable controlling whether the 2D render API is compatible or efficient. + * + * This variable can be set to the following values: + * + * "0" - Don't use batching to make rendering more efficient. + * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls. + * + * Up to SDL 2.0.9, the render API would draw immediately when requested. Now + * it batches up draw requests and sends them all to the GPU only when forced + * to (during SDL_RenderPresent, when changing render targets, by updating a + * texture that the batch needs, etc). This is significantly more efficient, + * but it can cause problems for apps that expect to render on top of the + * render API's output. As such, SDL will disable batching if a specific + * render backend is requested (since this might indicate that the app is + * planning to use the underlying graphics API directly). This hint can + * be used to explicitly request batching in this instance. It is a contract + * that you will either never use the underlying graphics API directly, or + * if you do, you will call SDL_RenderFlush() before you do so any current + * batch goes to the GPU before your work begins. Not following this contract + * will result in undefined behavior. + */ +#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" + +/** + * \brief A variable controlling how the 2D render API renders lines + * + * This variable can be set to the following values: + * "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20) + * "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points) + * "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20) + * "3" - Use the driver geometry API (correct, draws thicker diagonal lines) + * + * This variable should be set when the renderer is created. + */ +#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD" + +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Layer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" + +/** + * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. + * + * This variable can be set to the following values: + * "0" - Thread-safety is not enabled (faster) + * "1" - Thread-safety is enabled + * + * By default the Direct3D device is created with thread-safety disabled. + */ +#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" + +/** + * \brief A variable specifying which render driver to use. + * + * If the application doesn't pick a specific renderer to use, this variable + * specifies the name of the preferred renderer. If the preferred renderer + * can't be initialized, the normal default renderer is used. + * + * This variable is case insensitive and can be set to the following values: + * "direct3d" + * "direct3d11" + * "direct3d12" + * "opengl" + * "opengles2" + * "opengles" + * "metal" + * "software" + * + * The default varies by platform, but it's the first one in the list that + * is available on the current platform. + */ +#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" + +/** + * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize. + * + * This variable can be set to the following values: + * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen + * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen + * + * By default letterbox is used + */ +#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_RENDER_LOGICAL_SIZE_MODE" + +/** + * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. + * + * This variable can be set to the following values: + * "0" - Disable shaders + * "1" - Enable shaders + * + * By default shaders are used if OpenGL supports them. + */ +#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" + +/** + * \brief A variable controlling the scaling quality + * + * This variable can be set to the following values: + * "0" or "nearest" - Nearest pixel sampling + * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) + * "2" or "best" - Currently this is the same as "linear" + * + * By default nearest pixel sampling is used + */ +#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" + +/** + * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. + * + * This variable can be set to the following values: + * "0" - Disable vsync + * "1" - Enable vsync + * + * By default SDL does not sync screen surface updates with vertical refresh. + */ +#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" + +/** + * \brief A variable to control whether the return key on the soft keyboard + * should hide the soft keyboard on Android and iOS. + * + * The variable can be set to the following values: + * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default) + * "1" - The return key will hide the keyboard. + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + +/** + * \brief Specify an "activity name" for screensaver inhibition. + * + * Some platforms, notably Linux desktops, list the applications which are + * inhibiting the screensaver or other power-saving features. + * + * This hint lets you specify the "activity name" sent to the OS when + * SDL_DisableScreenSaver() is used (or the screensaver is automatically + * disabled). The contents of this hint are used when the screensaver is + * disabled. You should use a string that describes what your program is doing + * (and, therefore, why the screensaver is disabled). For example, "Playing a + * game" or "Watching a video". + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Playing a game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME "SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME" + +/** + * \brief Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime. + * + * On some platforms, like Linux, a realtime priority thread may be subject to restrictions + * that require special handling by the application. This hint exists to let SDL know that + * the app is prepared to handle said restrictions. + * + * On Linux, SDL will apply the following configuration to any thread that becomes realtime: + * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy, + * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit. + * * Exceeding this limit will result in the kernel sending SIGKILL to the app, + * * Refer to the man pages for more information. + * + * This variable can be set to the following values: + * "0" - default platform specific behaviour + * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy + */ +#define SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL "SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL" + +/** +* \brief A string specifying additional information to use with SDL_SetThreadPriority. +* +* By default SDL_SetThreadPriority will make appropriate system changes in order to +* apply a thread priority. For example on systems using pthreads the scheduler policy +* is changed automatically to a policy that works well with a given priority. +* Code which has specific requirements can override SDL's default behavior with this hint. +* +* pthread hint values are "current", "other", "fifo" and "rr". +* Currently no other platform hint values are defined but may be in the future. +* +* \note On Linux, the kernel may send SIGKILL to realtime tasks which exceed the distro +* configured execution budget for rtkit. This budget can be queried through RLIMIT_RTTIME +* after calling SDL_SetThreadPriority(). +*/ +#define SDL_HINT_THREAD_PRIORITY_POLICY "SDL_THREAD_PRIORITY_POLICY" + +/** +* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size +* +* Use this hint in case you need to set SDL's threads stack size to other than the default. +* This is specially useful if you build SDL against a non glibc libc library (such as musl) which +* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. +* +* Instead of this hint, in 2.0.9 and later, you can use +* SDL_CreateThreadWithStackSize(). This hint only works with the classic +* SDL_CreateThread(). +*/ +#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" + +/** + * \brief A variable that controls the timer resolution, in milliseconds. + * + * The higher resolution the timer, the more frequently the CPU services + * timer interrupts, and the more precise delays are, but this takes up + * power and CPU time. This hint is only used on Windows. + * + * See this blog post for more information: + * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ + * + * If this variable is set to "0", the system timer resolution is not set. + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" + +/** + * \brief A variable controlling whether touch events should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Touch events will not generate mouse events + * "1" - Touch events will generate mouse events + * + * By default SDL will generate mouse events for touch events + */ +#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" + +/** + * \brief A variable controlling which touchpad should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Only front touchpad should generate mouse events. Default + * "1" - Only back touchpad should generate mouse events. + * "2" - Both touchpads should generate mouse events. + * + * By default SDL will generate mouse events for all touch devices + */ +#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE" + +/** + * \brief A variable controlling whether the Android / tvOS remotes + * should be listed as joystick devices, instead of sending keyboard events. + * + * This variable can be set to the following values: + * "0" - Remotes send enter/escape/arrow key events + * "1" - Remotes are available as 2 axis, 2 button joysticks (the default). + */ +#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" + +/** + * \brief A variable controlling whether the screensaver is enabled. + * + * This variable can be set to the following values: + * "0" - Disable screensaver + * "1" - Enable screensaver + * + * By default SDL will disable the screensaver. + */ +#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" + +/** + * \brief Tell the video driver that we only want a double buffer. + * + * By default, most lowlevel 2D APIs will use a triple buffer scheme that + * wastes no CPU time on waiting for vsync after issuing a flip, but + * introduces a frame of latency. On the other hand, using a double buffer + * scheme instead is recommended for cases where low latency is an important + * factor because we save a whole frame of latency. + * We do so by waiting for vsync immediately after issuing a flip, usually just + * after eglSwapBuffers call in the backend's *_SwapWindow function. + * + * Since it's driver-specific, it's only supported where possible and + * implemented. Currently supported the following drivers: + * + * - KMSDRM (kmsdrm) + * - Raspberry Pi (raspberrypi) + */ +#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER" + +/** + * \brief A variable controlling whether the EGL window is allowed to be + * composited as transparent, rather than opaque. + * + * Most window systems will always render windows opaque, even if the surface + * format has an alpha channel. This is not always true, however, so by default + * SDL will try to enforce opaque composition. To override this behavior, you + * can set this hint to "1". + */ +#define SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY "SDL_VIDEO_EGL_ALLOW_TRANSPARENCY" + +/** + * \brief A variable controlling whether the graphics context is externally managed. + * + * This variable can be set to the following values: + * "0" - SDL will manage graphics contexts that are attached to windows. + * "1" - Disable graphics context management on windows. + * + * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the + * context will be automatically saved and restored when pausing the application. Additionally, some + * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this + * behavior, which is desireable when the application manages the graphics context, such as + * an externally managed OpenGL context or attaching a Vulkan surface to the window. + */ +#define SDL_HINT_VIDEO_EXTERNAL_CONTEXT "SDL_VIDEO_EXTERNAL_CONTEXT" + +/** + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) + */ +#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" + +/** + * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. + * + * This hint only applies to Mac OS X. + * + * The variable can be set to the following values: + * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and + * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" + * button on their titlebars). + * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and + * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" + * button on their titlebars). + * + * The default value is "1". This hint must be set before any windows are created. + */ +#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" + +/** + * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to false. + * \warning Before SDL 2.0.14, this defaulted to true! In 2.0.14, we're + * seeing if "true" causes more problems than it solves in modern times. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + +/** + * \brief A variable controlling whether the libdecor Wayland backend is allowed to be used. + * + * This variable can be set to the following values: + * "0" - libdecor use is disabled. + * "1" - libdecor use is enabled (default). + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" + +/** + * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations. + * + * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is + * available. (Note that, by default, libdecor will use xdg-decoration itself if available). + * + * This variable can be set to the following values: + * "0" - libdecor is enabled only if server-side decorations are unavailable. + * "1" - libdecor is always enabled if available. + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR" + +/** + * \brief A variable controlling whether video mode emulation is enabled under Wayland. + * + * When this hint is set, a standard set of emulated CVT video modes will be exposed for use by the application. + * If it is disabled, the only modes exposed will be the logical desktop size and, in the case of a scaled + * desktop, the native display resolution. + * + * This variable can be set to the following values: + * "0" - Video mode emulation is disabled. + * "1" - Video mode emulation is enabled. + * + * By default video mode emulation is enabled. + */ +#define SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION "SDL_VIDEO_WAYLAND_MODE_EMULATION" + +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: +* +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + +/** + * \brief When calling SDL_CreateWindowFrom(), make the window compatible with OpenGL. + * + * This variable can be set to the following values: + * "0" - Don't add any graphics flags to the SDL_WindowFlags + * "1" - Add SDL_WINDOW_OPENGL to the SDL_WindowFlags + * + * By default SDL will not make the foreign window compatible with OpenGL. + */ +#define SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL "SDL_VIDEO_FOREIGN_WINDOW_OPENGL" + +/** + * \brief When calling SDL_CreateWindowFrom(), make the window compatible with Vulkan. + * + * This variable can be set to the following values: + * "0" - Don't add any graphics flags to the SDL_WindowFlags + * "1" - Add SDL_WINDOW_VULKAN to the SDL_WindowFlags + * + * By default SDL will not make the foreign window compatible with Vulkan. + */ +#define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN "SDL_VIDEO_FOREIGN_WINDOW_VULKAN" + +/** +* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries +* +* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It +* can use two different sets of binaries, those compiled by the user from source +* or those provided by the Chrome browser. In the later case, these binaries require +* that SDL loads a DLL providing the shader compiler. +* +* This variable can be set to the following values: +* "d3dcompiler_46.dll" - default, best for Vista or later. +* "d3dcompiler_43.dll" - for XP support. +* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. +* +*/ +#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" + +/** + * \brief A variable controlling whether X11 should use GLX or EGL by default + * + * This variable can be set to the following values: + * "0" - Use GLX + * "1" - Use EGL + * + * By default SDL will use GLX when both are present. + */ +#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" + +/** + * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_BYPASS_COMPOSITOR + * "1" - Enable _NET_WM_BYPASS_COMPOSITOR + * + * By default SDL will use _NET_WM_BYPASS_COMPOSITOR + * + */ +#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" + +/** + * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_PING + * "1" - Enable _NET_WM_PING + * + * By default SDL will use _NET_WM_PING, but for applications that know they + * will not always be able to respond to ping requests in a timely manner they can + * turn it off to avoid the window manager thinking the app is hung. + * The hint is checked in CreateWindow. + */ +#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" + +/** + * \brief A variable forcing the visual ID chosen for new X11 windows + * + */ +#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" + +/** + * \brief A no-longer-used variable controlling whether the X11 Xinerama extension should be used. + * + * Before SDL 2.0.24, this would let apps and users disable Xinerama support on X11. + * Now SDL never uses Xinerama, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will use XRandR. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A no-longer-used variable controlling whether the X11 VidMode extension should be used. + * + * Before SDL 2.0.24, this would let apps and users disable XVidMode support on X11. + * Now SDL never uses XVidMode, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief Controls how the fact chunk affects the loading of a WAVE file. + * + * The fact chunk stores information about the number of samples of a WAVE + * file. The Standards Update from Microsoft notes that this value can be used + * to 'determine the length of the data in seconds'. This is especially useful + * for compressed formats (for which this is a mandatory chunk) if they produce + * multiple sample frames per block and truncating the block is not allowed. + * The fact chunk can exactly specify how many sample frames there should be + * in this case. + * + * Unfortunately, most application seem to ignore the fact chunk and so SDL + * ignores it by default as well. + * + * This variable can be set to the following values: + * + * "truncate" - Use the number of samples to truncate the wave data if + * the fact chunk is present and valid + * "strict" - Like "truncate", but raise an error if the fact chunk + * is invalid, not present for non-PCM formats, or if the + * data chunk doesn't have that many samples + * "ignorezero" - Like "truncate", but ignore fact chunk if the number of + * samples is zero + * "ignore" - Ignore fact chunk entirely (default) + */ +#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK" + +/** + * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file. + * + * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE + * file) is not always reliable. In case the size is wrong, it's possible to + * just ignore it and step through the chunks until a fixed limit is reached. + * + * Note that files that have trailing data unrelated to the WAVE file or + * corrupt files may slow down the loading process without a reliable boundary. + * By default, SDL stops after 10000 chunks to prevent wasting time. Use the + * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value. + * + * This variable can be set to the following values: + * + * "force" - Always use the RIFF chunk size as a boundary for the chunk search + * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default) + * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB + * "maximum" - Search for chunks until the end of file (not recommended) + */ +#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE" + +/** + * \brief Controls how a truncated WAVE file is handled. + * + * A WAVE file is considered truncated if any of the chunks are incomplete or + * the data chunk size is not a multiple of the block size. By default, SDL + * decodes until the first incomplete block, as most applications seem to do. + * + * This variable can be set to the following values: + * + * "verystrict" - Raise an error if the file is truncated + * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored + * "dropframe" - Decode until the first incomplete sample frame + * "dropblock" - Decode until the first incomplete block (default) + */ +#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION" + +/** + * \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception. + * The 0x406D1388 Exception is a trick used to inform Visual Studio of a + * thread's name, but it tends to cause problems with other debuggers, + * and the .NET runtime. Note that SDL 2.0.6 and later will still use + * the (safer) SetThreadDescription API, introduced in the Windows 10 + * Creators Update, if available. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. + * "1" - SDL will not raise this exception, and threads will be unnamed. (default) + * This is necessary with .NET languages or debuggers that aren't Visual Studio. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL + * + * This variable can be set to the following values: + * "0" - The window message loop is not run + * "1" - The window message loop is processed in SDL_PumpEvents() + * + * By default SDL will process the windows message loop + */ +#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" + +/** + * \brief Force SDL to use Critical Sections for mutexes on Windows. + * On Windows 7 and newer, Slim Reader/Writer Locks are available. + * They offer better performance, allocate no kernel ressources and + * use less memory. SDL will fall back to Critical Sections on older + * OS versions or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use SRW Locks when available. If not, fall back to Critical Sections. (default) + * "1" - Force the use of Critical Sections in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS "SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS" + +/** + * \brief Force SDL to use Kernel Semaphores on Windows. + * Kernel Semaphores are inter-process and require a context + * switch on every interaction. On Windows 8 and newer, the + * WaitOnAddress API is available. Using that and atomics to + * implement semaphores increases performance. + * SDL will fall back to Kernel Objects on older OS versions + * or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use Atomics and WaitOnAddress API when available. If not, fall back to Kernel Objects. (default) + * "1" - Force the use of Kernel Objects in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL" + +/** + * \brief A variable to specify custom icon resource id from RC file on Windows platform + */ +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" + +/** + * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will generate a window-close event when it sees Alt+F4. + * "1" - SDL will only do normal key handling for Alt+F4. + */ +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" + +/** + * \brief Use the D3D9Ex API introduced in Windows Vista, instead of normal D3D9. + * Direct3D 9Ex contains changes to state management that can eliminate device + * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may require + * some changes to your application to cope with the new behavior, so this + * is disabled by default. + * + * This hint must be set before initializing the video subsystem. + * + * For more information on Direct3D 9Ex, see: + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements + * + * This variable can be set to the following values: + * "0" - Use the original Direct3D 9 API (default) + * "1" - Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex is unavailable) + * + */ +#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX" + +/** + * \brief Controls whether SDL will declare the process to be DPI aware. + * + * This hint must be set before initializing the video subsystem. + * + * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with + * a DPI scale factor. + * + * This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext) + * and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel + * even on high-DPI displays. + * + * For more information, see: + * https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows + * + * This variable can be set to the following values: + * "" - Do not change the DPI awareness (default). + * "unaware" - Declare the process as DPI unaware. (Windows 8.1 and later). + * "system" - Request system DPI awareness. (Vista and later). + * "permonitor" - Request per-monitor DPI awareness. (Windows 8.1 and later). + * "permonitorv2" - Request per-monitor V2 DPI awareness. (Windows 10, version 1607 and later). + * The most visible difference from "permonitor" is that window title bar will be scaled + * to the visually correct size when dragging between monitors with different scale factors. + * This is the preferred DPI awareness level. + * + * If the requested DPI awareness is not available on the currently running OS, SDL will try to request the best + * available match. + */ +#define SDL_HINT_WINDOWS_DPI_AWARENESS "SDL_WINDOWS_DPI_AWARENESS" + +/** + * \brief Uses DPI-scaled points as the SDL coordinate system on Windows. + * + * This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere. + * This means windows will be appropriately sized, even when created on high-DPI displays with scaling. + * + * e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings, + * will create a window with an 800x600 client area (in pixels). + * + * Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary), + * and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows. + * + * This variable can be set to the following values: + * "0" - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging + * between monitors with different scale factors (unless this is performed by + * Windows itself, which is the case when the process is DPI unaware). + * "1" - SDL coordinates are in DPI-scaled points. Automatically resize windows as needed on + * displays with non-100% scale factors. + */ +#define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING" + +/** + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * + * This variable can be set to the following values: + * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) + * "1" - The window frame is interactive when the cursor is hidden + * + * By default SDL will allow interaction with the window frame when the cursor is hidden + */ +#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" + +/** +* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called +* +* This variable can be set to the following values: +* "0" - The window is activated when the SDL_ShowWindow function is called +* "1" - The window is not activated when the SDL_ShowWindow function is called +* +* By default SDL will activate the window when the SDL_ShowWindow function is called +*/ +#define SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN "SDL_WINDOW_NO_ACTIVATION_WHEN_SHOWN" + +/** \brief Allows back-button-press events on Windows Phone to be marked as handled + * + * Windows Phone devices typically feature a Back button. When pressed, + * the OS will emit back-button-press events, which apps are expected to + * handle in an appropriate manner. If apps do not explicitly mark these + * events as 'Handled', then the OS will invoke its default behavior for + * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to + * terminate the app (and attempt to switch to the previous app, or to the + * device's home screen). + * + * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL + * to mark back-button-press events as Handled, if and when one is sent to + * the app. + * + * Internally, Windows Phone sends back button events as parameters to + * special back-button-press callback functions. Apps that need to respond + * to back-button-press events are expected to register one or more + * callback functions for such, shortly after being launched (during the + * app's initialization phase). After the back button is pressed, the OS + * will invoke these callbacks. If the app's callback(s) do not explicitly + * mark the event as handled by the time they return, or if the app never + * registers one of these callback, the OS will consider the event + * un-handled, and it will apply its default back button behavior (terminate + * the app). + * + * SDL registers its own back-button-press callback with the Windows Phone + * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN + * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which + * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. + * If the hint's value is set to "1", the back button event's Handled + * property will get set to 'true'. If the hint's value is set to something + * else, or if it is unset, SDL will leave the event's Handled property + * alone. (By default, the OS sets this property to 'false', to note.) + * + * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a + * back button is pressed, or can set it in direct-response to a back button + * being pressed. + * + * In order to get notified when a back button is pressed, SDL apps should + * register a callback function with SDL_AddEventWatch(), and have it listen + * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. + * (Alternatively, SDL_KEYUP events can be listened-for. Listening for + * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON + * set by such a callback, will be applied to the OS' current + * back-button-press event. + * + * More details on back button behavior in Windows Phone apps can be found + * at the following page, on Microsoft's developer site: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with its label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init(). + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" + +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init() functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" + +/** + * \brief Mark X11 windows as override-redirect. + * + * If set, this _might_ increase framerate at the expense of the desktop + * not working as expected. Override-redirect windows aren't noticed by the + * window manager at all. + * + * You should probably only use this for fullscreen windows, and you probably + * shouldn't even use it for that. But it's here if you want to try! + */ +#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT" + +/** + * \brief A variable that lets you disable the detection and use of Xinput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable XInput detection (only uses direct input) + * "1" - Enable XInput detection (the default) + */ +#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" + + /** + * \brief A variable that lets you disable the detection and use of DirectInput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable DirectInput detection (only uses XInput) + * "1" - Enable DirectInput detection (the default) + */ +#define SDL_HINT_DIRECTINPUT_ENABLED "SDL_DIRECTINPUT_ENABLED" + +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + +/** + * \brief A variable that causes SDL to not ignore audio "monitors" + * + * This is currently only used for PulseAudio and ignored elsewhere. + * + * By default, SDL ignores audio devices that aren't associated with physical + * hardware. Changing this hint to "1" will expose anything SDL sees that + * appears to be an audio source or sink. This will add "devices" to the list + * that the user probably doesn't want or need, but it can be useful in + * scenarios where you want to hook up SDL to some sort of virtual device, + * etc. + * + * The default value is "0". This hint must be set before SDL_Init(). + * + * This hint is available since SDL 2.0.16. Before then, virtual devices are + * always ignored. + */ +#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS" + +/** + * \brief A variable that forces X11 windows to create as a custom type. + * + * This is currently only used for X11 and ignored elsewhere. + * + * During SDL_CreateWindow, SDL uses the _NET_WM_WINDOW_TYPE X11 property + * to report to the window manager the type of window it wants to create. + * This might be set to various things if SDL_WINDOW_TOOLTIP or + * SDL_WINDOW_POPUP_MENU, etc, were specified. For "normal" windows that + * haven't set a specific type, this hint can be used to specify a custom + * type. For example, a dock window might set this to + * "_NET_WM_WINDOW_TYPE_DOCK". + * + * If not set or set to "", this hint is ignored. This hint must be set + * before the SDL_CreateWindow() call that it is intended to affect. + * + * This hint is available since SDL 2.0.22. + */ +#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE" + +/** + * \brief A variable that decides whether to send SDL_QUIT when closing the final window. + * + * By default, SDL sends an SDL_QUIT event when there is only one window + * and it receives an SDL_WINDOWEVENT_CLOSE event, under the assumption most + * apps would also take the loss of this window as a signal to terminate the + * program. + * + * However, it's not unreasonable in some cases to have the program continue + * to live on, perhaps to create new windows later. + * + * Changing this hint to "0" will cause SDL to not send an SDL_QUIT event + * when the final window is requesting to close. Note that in this case, + * there are still other legitimate reasons one might get an SDL_QUIT + * event: choosing "Quit" from the macOS menu bar, sending a SIGINT (ctrl-c) + * on Unix, etc. + * + * The default value is "1". This hint can be changed at any time. + * + * This hint is available since SDL 2.0.22. Before then, you always get + * an SDL_QUIT event when closing the final window. + */ +#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE" + + +/** + * \brief A variable that decides what video backend to use. + * + * By default, SDL will try all available video backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "x11" if, say, you are + * on Wayland but want to try talking to the X server instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best video backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER" + +/** + * \brief A variable that decides what audio backend to use. + * + * By default, SDL will try all available audio backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "alsa" if, say, you are + * on PulseAudio but want to try talking to the lower level instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best audio backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER" + +/** + * \brief A variable that decides what KMSDRM device to use. + * + * Internally, SDL might open something like "/dev/dri/cardNN" to + * access KMSDRM functionality, where "NN" is a device index number. + * + * SDL makes a guess at the best index to use (usually zero), but the + * app or user can set this hint to a number between 0 and 99 to + * force selection. + * + * This hint is available since SDL 2.24.0. + */ +#define SDL_HINT_KMSDRM_DEVICE_INDEX "SDL_KMSDRM_DEVICE_INDEX" + + +/** + * \brief A variable that treats trackpads as touch devices. + * + * On macOS (and possibly other platforms in the future), SDL will report + * touches on a trackpad as mouse input, which is generally what users + * expect from this device; however, these are often actually full + * multitouch-capable touch devices, so it might be preferable to some apps + * to treat them as such. + * + * Setting this hint to true will make the trackpad input report as a + * multitouch device instead of a mouse. The default is false. + * + * Note that most platforms don't support this hint. As of 2.24.0, it + * only supports MacBooks' trackpads on macOS. Others may follow later. + * + * This hint is checked during SDL_Init and can not be changed after. + * + * This hint is available since SDL 2.24.0. + */ +#define SDL_HINT_TRACKPAD_IS_TOUCH_ONLY "SDL_TRACKPAD_IS_TOUCH_ONLY" + + +/** + * \brief An enumeration of hint priorities + */ +typedef enum +{ + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE +} SDL_HintPriority; + + +/** + * Set a hint with a specific priority. + * + * The priority controls the behavior when setting a hint that already has a + * value. Hints will replace existing hints of their priority and lower. + * Environment variables are considered to have override priority. + * + * \param name the hint to set + * \param value the value of the hint variable + * \param priority the SDL_HintPriority level for the hint + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, + const char *value, + SDL_HintPriority priority); + +/** + * Set a hint with normal priority. + * + * Hints will not be set if there is an existing override hint or environment + * variable that takes precedence. You can use SDL_SetHintWithPriority() to + * set the hint with override priority instead. + * + * \param name the hint to set + * \param value the value of the hint variable + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, + const char *value); + +/** + * Reset a hint to the default value. + * + * This will reset a hint to the value of the environment variable, or NULL if + * the environment isn't set. Callbacks will be called normally with this + * change. + * + * \param name the hint to set + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name); + +/** + * Get the value of a hint. + * + * \param name the hint to query + * \returns the string value of a hint or NULL if the hint isn't set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); + +/** + * Get the boolean value of a hint variable. + * + * \param name the name of the hint to get the boolean value from + * \param default_value the value to return if the hint does not exist + * \returns the boolean value of a hint or the provided default value if the + * hint does not exist. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + +/** + * Type definition of the hint callback function. + * + * \param userdata what was passed as `userdata` to SDL_AddHintCallback() + * \param name what was passed as `name` to SDL_AddHintCallback() + * \param oldValue the previous hint value + * \param newValue the new value hint is to be set to + */ +typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); + +/** + * Add a function to watch a particular hint. + * + * \param name the hint to watch + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer to pass to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelHintCallback + */ +extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Remove a function watching a particular hint. + * + * \param name the hint being watched + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer being passed to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddHintCallback + */ +extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Clear all hints. + * + * This function is automatically called during SDL_Quit(). + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_ClearHints(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hints_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_joystick.h b/thirdparty/SDL/include/SDL/SDL_joystick.h new file mode 100644 index 00000000..1a7c66ee --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_joystick.h @@ -0,0 +1,1038 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_joystick.h + * + * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term "player_index" is the number assigned to a player on a specific + * controller. For XInput controllers this returns the XInput user index. + * Many joysticks will not be able to supply this information. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + */ + +#ifndef SDL_joystick_h_ +#define SDL_joystick_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_guid.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_joystick.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for joysticks, and load appropriate drivers. + * + * If you would like to receive joystick updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The joystick structure used to identify an SDL joystick + */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + +/* A structure that encodes the stable unique id for a joystick device */ +typedef SDL_GUID SDL_JoystickGUID; + +/** + * This is a unique ID for a joystick for the time it is connected to the system, + * and is never reused for the lifetime of the application. If the joystick is + * disconnected and reconnected, it will get a new ID. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_JoystickID; + +typedef enum +{ + SDL_JOYSTICK_TYPE_UNKNOWN, + SDL_JOYSTICK_TYPE_GAMECONTROLLER, + SDL_JOYSTICK_TYPE_WHEEL, + SDL_JOYSTICK_TYPE_ARCADE_STICK, + SDL_JOYSTICK_TYPE_FLIGHT_STICK, + SDL_JOYSTICK_TYPE_DANCE_PAD, + SDL_JOYSTICK_TYPE_GUITAR, + SDL_JOYSTICK_TYPE_DRUM_KIT, + SDL_JOYSTICK_TYPE_ARCADE_PAD, + SDL_JOYSTICK_TYPE_THROTTLE +} SDL_JoystickType; + +typedef enum +{ + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, /* <= 5% */ + SDL_JOYSTICK_POWER_LOW, /* <= 20% */ + SDL_JOYSTICK_POWER_MEDIUM, /* <= 70% */ + SDL_JOYSTICK_POWER_FULL, /* <= 100% */ + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX +} SDL_JoystickPowerLevel; + +/* Set max recognized G-force from accelerometer + See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed + */ +#define SDL_IPHONE_MAX_GFORCE 5.0 + + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); + + +/** + * Unlocking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); + +/** + * Count the number of joysticks attached to the system. + * + * \returns the number of attached joysticks on success or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickPath + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/** + * Get the implementation dependent name of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); + +/** + * Get the implementation dependent path of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPath + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index); + +/** + * Get the player index of a joystick, or -1 if it's not available This can be + * called before any joysticks are opened. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index); + +/** + * Get the implementation-dependent GUID for the joystick at a given device + * index. + * + * This function can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the GUID of the selected joystick. If called on an invalid index, + * this function returns a zero GUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); + +/** + * Get the USB vendor ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the vendor ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB vendor ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceVendor(int device_index); + +/** + * Get the USB product ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB product ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProduct(int device_index); + +/** + * Get the product version of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product version + * isn't available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the product version of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProductVersion(int device_index); + +/** + * Get the type of a joystick, if available. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the SDL_JoystickType of the selected joystick. If called on an + * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN` + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_index); + +/** + * Get the instance ID of a joystick. + * + * This can be called before any joysticks are opened. If the index is out of + * range, this function will return -1. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the instance id of the selected joystick. If called on an invalid + * index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickGetDeviceInstanceID(int device_index); + +/** + * Open a joystick for use. + * + * The `device_index` argument refers to the N'th joystick presently + * recognized by SDL on the system. It is **NOT** the same as the instance ID + * used to identify the joystick in future events. See + * SDL_JoystickInstanceID() for more details about instance IDs. + * + * The joystick subsystem must be initialized before a joystick can be opened + * for use. + * + * \param device_index the index of the joystick to query + * \returns a joystick identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickInstanceID + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); + +/** + * Get the SDL_Joystick associated with an instance id. + * + * \param instance_id the instance id to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID instance_id); + +/** + * Get the SDL_Joystick associated with a player index. + * + * \param player_index the player index to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_index); + +/** + * Attach a new virtual joystick. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, + int naxes, + int nbuttons, + int nhats); + +/** + * The structure that defines an extended virtual joystick description + * + * The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx() + * All other elements of this structure are optional and can be left 0. + * + * \sa SDL_JoystickAttachVirtualEx + */ +typedef struct SDL_VirtualJoystickDesc +{ + Uint16 version; /**< `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` */ + Uint16 type; /**< `SDL_JoystickType` */ + Uint16 naxes; /**< the number of axes on this joystick */ + Uint16 nbuttons; /**< the number of buttons on this joystick */ + Uint16 nhats; /**< the number of hats on this joystick */ + Uint16 vendor_id; /**< the USB vendor ID of this joystick */ + Uint16 product_id; /**< the USB product ID of this joystick */ + Uint16 padding; /**< unused */ + Uint32 button_mask; /**< A mask of which buttons are valid for this controller + e.g. (1 << SDL_CONTROLLER_BUTTON_A) */ + Uint32 axis_mask; /**< A mask of which axes are valid for this controller + e.g. (1 << SDL_CONTROLLER_AXIS_LEFTX) */ + const char *name; /**< the name of the joystick */ + + void *userdata; /**< User data pointer passed to callbacks */ + void (SDLCALL *Update)(void *userdata); /**< Called when the joystick state should be updated */ + void (SDLCALL *SetPlayerIndex)(void *userdata, int player_index); /**< Called when the player index is set */ + int (SDLCALL *Rumble)(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); /**< Implements SDL_JoystickRumble() */ + int (SDLCALL *RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_JoystickRumbleTriggers() */ + int (SDLCALL *SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_JoystickSetLED() */ + int (SDLCALL *SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_JoystickSendEffect() */ + +} SDL_VirtualJoystickDesc; + +/** + * \brief The current version of the SDL_VirtualJoystickDesc structure + */ +#define SDL_VIRTUAL_JOYSTICK_DESC_VERSION 1 + +/** + * Attach a new virtual joystick with extended properties. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc); + +/** + * Detach a virtual joystick. + * + * \param device_index a value previously returned from + * SDL_JoystickAttachVirtual() + * \returns 0 on success, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickDetachVirtual(int device_index); + +/** + * Query whether or not the joystick at a given device index is virtual. + * + * \param device_index a joystick device index. + * \returns SDL_TRUE if the joystick is virtual, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index); + +/** + * Set values on an opened, virtual-joystick's axis. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param axis the specific axis on the virtual joystick to set. + * \param value the new value for the specified axis. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value); + +/** + * Set values on an opened, virtual-joystick's button. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param button the specific button on the virtual joystick to set. + * \param value the new value for the specified button. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value); + +/** + * Set values on an opened, virtual-joystick's hat. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param hat the specific hat on the virtual joystick to set. + * \param value the new value for the specified hat. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value); + +/** + * Get the implementation dependent name of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNameForIndex + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); + +/** + * Get the implementation dependent path of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPath(SDL_Joystick *joystick); + +/** + * Get the player index of an opened joystick. + * + * For XInput controllers this returns the XInput user index. Many joysticks + * will not be able to supply this information. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the player index, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick); + +/** + * Set the player index of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \param player_index Player index to assign to this joystick, or -1 to clear + * the player index and turn off player LEDs. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index); + +/** + * Get the implementation-dependent GUID for the joystick. + * + * This function requires an open joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the GUID of the given joystick. If called on an invalid index, + * this function returns a zero GUID; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick); + +/** + * Get the USB vendor ID of an opened joystick, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB vendor ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick *joystick); + +/** + * Get the USB product ID of an opened joystick, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB product ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick *joystick); + +/** + * Get the product version of an opened joystick, if available. + * + * If the product version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the product version of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick); + +/** + * Get the firmware version of an opened joystick, if available. + * + * If the firmware version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the firmware version of the selected joystick, or 0 if + * unavailable. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick); + +/** + * Get the serial number of an opened joystick, if available. + * + * Returns the serial number of the joystick, or NULL if it is not available. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the serial number of the selected joystick, or NULL if + * unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick); + +/** + * Get the type of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the SDL_JoystickType of the selected joystick. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick *joystick); + +/** + * Get an ASCII string representation for a given SDL_JoystickGUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the SDL_JoystickGUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a SDL_JoystickGUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a SDL_JoystickGUID structure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Get the status of a specified joystick. + * + * \param joystick the joystick to query + * \returns SDL_TRUE if the joystick has been opened, SDL_FALSE if it has not; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick); + +/** + * Get the instance ID of an opened joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the instance ID of the specified joystick on success or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick); + +/** + * Get the number of general axis controls on a joystick. + * + * Often, the directional pad on a game controller will either look like 4 + * separate buttons or a POV hat, and not axes, but all of this is up to the + * device and platform. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of axis controls/number of axes on success or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetAxis + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); + +/** + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated with them + * and their state cannot be polled. + * + * Most joysticks do not have trackballs. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of trackballs on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetBall + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); + +/** + * Get the number of POV hats on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of POV hats on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetHat + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); + +/** + * Get the number of buttons on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of buttons on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetButton + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); + +/** + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick events are + * enabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/** + * Enable/disable joystick event polling. + * + * If joystick events are disabled, you must call SDL_JoystickUpdate() + * yourself and manually check the state of the joystick when you want + * joystick information. + * + * It is recommended that you leave joystick event handling enabled. + * + * **WARNING**: Calling this function may delete all events currently in SDL's + * event queue. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns 1 if enabled, 0 if disabled, or a negative error code on failure; + * call SDL_GetError() for more information. + * + * If `state` is `SDL_QUERY` then the current state is returned, + * otherwise the new processing state is returned. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerEventState + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +#define SDL_JOYSTICK_AXIS_MAX 32767 +#define SDL_JOYSTICK_AXIS_MIN -32768 + +/** + * Get the current state of an axis control on a joystick. + * + * SDL makes no promises about what part of the joystick any given axis refers + * to. Your game should have some sort of configuration UI to let users + * specify what each axis should be bound to. Alternately, SDL's higher-level + * Game Controller API makes a great effort to apply order to this lower-level + * interface, so you know that a specific axis is the "left thumb stick," etc. + * + * The value returned by SDL_JoystickGetAxis() is a signed integer (-32768 to + * 32767) representing the current position of the axis. It may be necessary + * to impose certain tolerances on these values to account for jitter. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \returns a 16-bit signed integer representing the current position of the + * axis or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumAxes + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, + int axis); + +/** + * Get the initial state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \param state Upon return, the initial value is supplied here. + * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, + int axis, Sint16 *state); + +/** + * \name Hat positions + */ +/* @{ */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* @} */ + +/** + * Get the current state of a POV hat on a joystick. + * + * The returned value will be one of the following positions: + * + * - `SDL_HAT_CENTERED` + * - `SDL_HAT_UP` + * - `SDL_HAT_RIGHT` + * - `SDL_HAT_DOWN` + * - `SDL_HAT_LEFT` + * - `SDL_HAT_RIGHTUP` + * - `SDL_HAT_RIGHTDOWN` + * - `SDL_HAT_LEFTUP` + * - `SDL_HAT_LEFTDOWN` + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param hat the hat index to get the state from; indices start at index 0 + * \returns the current hat position. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumHats + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, + int hat); + +/** + * Get the ball axis change since the last poll. + * + * Trackballs can only return relative motion since the last call to + * SDL_JoystickGetBall(), these motion deltas are placed into `dx` and `dy`. + * + * Most joysticks do not have trackballs. + * + * \param joystick the SDL_Joystick to query + * \param ball the ball index to query; ball indices start at index 0 + * \param dx stores the difference in the x axis position since the last poll + * \param dy stores the difference in the y axis position since the last poll + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumBalls + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, + int ball, int *dx, int *dy); + +/** + * Get the current state of a button on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param button the button index to get the state from; indices start at + * index 0 + * \returns 1 if the specified button is pressed, 0 otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumButtons + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, + int button); + +/** + * Start a rumble effect. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param joystick The joystick to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_JoystickHasRumble + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the joystick's triggers + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. This is currently only supported on Xbox One controllers. If you + * want the (more common) whole-controller rumble, use SDL_JoystickRumble() + * instead. + * + * \param joystick The joystick to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_JoystickHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a joystick has an LED. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has a modifiable LED, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumble(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support on triggers. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick); + +/** + * Update a joystick's LED color. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0 on success, -1 if this joystick does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a joystick specific effect packet + * + * \param joystick The joystick to affect + * \param data The data to send to the joystick + * \param size The size of the data to send to the joystick + * \returns 0, or -1 if this joystick or driver doesn't support effect packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size); + +/** + * Close a joystick previously opened with SDL_JoystickOpen(). + * + * \param joystick The joystick device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); + +/** + * Get the battery level of a joystick as SDL_JoystickPowerLevel. + * + * \param joystick the SDL_Joystick to query + * \returns the current battery level as SDL_JoystickPowerLevel on success or + * `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_joystick_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_keyboard.h b/thirdparty/SDL/include/SDL/SDL_keyboard.h new file mode 100644 index 00000000..e7663fb3 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_keyboard.h @@ -0,0 +1,353 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keyboard.h + * + * Include file for SDL keyboard event handling + */ + +#ifndef SDL_keyboard_h_ +#define SDL_keyboard_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keycode.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The SDL keysym structure, used in key events. + * + * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. + */ +typedef struct SDL_Keysym +{ + SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ + SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ + Uint16 mod; /**< current key modifiers */ + Uint32 unused; +} SDL_Keysym; + +/* Function prototypes */ + +/** + * Query the window which currently has keyboard focus. + * + * \returns the window with keyboard focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); + +/** + * Get a snapshot of the current state of the keyboard. + * + * The pointer returned is a pointer to an internal SDL array. It will be + * valid for the whole lifetime of the application and should not be freed by + * the caller. + * + * A array element with a value of 1 means that the key is pressed and a value + * of 0 means that it is not. Indexes into this array are obtained by using + * SDL_Scancode values. + * + * Use SDL_PumpEvents() to update the state array. + * + * This function gives you the current state after all events have been + * processed, so if a key or button has been pressed and released before you + * process events, then the pressed state will never show up in the + * SDL_GetKeyboardState() calls. + * + * Note: This function doesn't take into account whether shift has been + * pressed or not. + * + * \param numkeys if non-NULL, receives the length of the returned array + * \returns a pointer to an array of key states. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PumpEvents + * \sa SDL_ResetKeyboard + */ +extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); + +/** + * Clear the state of the keyboard + * + * This function will generate key up events for all pressed keys. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetKeyboardState + */ +extern DECLSPEC void SDLCALL SDL_ResetKeyboard(void); + +/** + * Get the current key modifier state for the keyboard. + * + * \returns an OR'd combination of the modifier keys for the keyboard. See + * SDL_Keymod for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyboardState + * \sa SDL_SetModState + */ +extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); + +/** + * Set the current key modifier state for the keyboard. + * + * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose + * modifier key states on your application. Simply pass your desired modifier + * states into `modstate`. This value may be a bitwise, OR'd combination of + * SDL_Keymod values. + * + * This does not change the keyboard state, only the key modifier flags that + * SDL reports. + * + * \param modstate the desired SDL_Keymod for the keyboard + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetModState + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); + +/** + * Get the key code corresponding to the given scancode according to the + * current keyboard layout. + * + * See SDL_Keycode for details. + * + * \param scancode the desired SDL_Scancode to query + * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); + +/** + * Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * See SDL_Scancode for details. + * + * \param key the desired SDL_Keycode to query + * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); + +/** + * Get a human-readable name for a scancode. + * + * See SDL_Scancode for details. + * + * **Warning**: The returned name is by design not stable across platforms, + * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left + * Windows" under Microsoft Windows, and some scancodes like + * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even + * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and + * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore + * unsuitable for creating a stable cross-platform two-way mapping between + * strings and scancodes. + * + * \param scancode the desired SDL_Scancode to query + * \returns a pointer to the name for the scancode. If the scancode doesn't + * have a name this function returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); + +/** + * Get a scancode from a human-readable name. + * + * \param name the human-readable scancode name + * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't + * recognized; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); + +/** + * Get a human-readable name for a key. + * + * See SDL_Scancode and SDL_Keycode for details. + * + * \param key the desired SDL_Keycode to query + * \returns a pointer to a UTF-8 string that stays valid at least until the + * next call to this function. If you need it around any longer, you + * must copy it. If the key doesn't have a name, this function + * returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); + +/** + * Get a key code from a human-readable name. + * + * \param name the human-readable key name + * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); + +/** + * Start accepting Unicode text input events. + * + * This function will start accepting Unicode text input events in the focused + * SDL window, and start emitting SDL_TextInputEvent (SDL_TEXTINPUT) and + * SDL_TextEditingEvent (SDL_TEXTEDITING) events. Please use this function in + * pair with SDL_StopTextInput(). + * + * On some platforms using this function activates the screen keyboard. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextInputRect + * \sa SDL_StopTextInput + */ +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); + +/** + * Check whether or not Unicode text input events are enabled. + * + * \returns SDL_TRUE if text input events are enabled else SDL_FALSE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + +/** + * Stop receiving any text input events. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); + +/** + * Dismiss the composition window/IME without disabling the subsystem. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_StartTextInput + * \sa SDL_StopTextInput + */ +extern DECLSPEC void SDLCALL SDL_ClearComposition(void); + +/** + * Returns if an IME Composite or Candidate window is currently shown. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputShown(void); + +/** + * Set the rectangle used to type Unicode text inputs. + * + * To start text input in a given location, this function is intended to be + * called before SDL_StartTextInput, although some platforms support moving + * the rectangle even while text input (and a composition) is active. + * + * Note: If you want to use the system native IME window, try setting hint + * **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you + * any feedback. + * + * \param rect the SDL_Rect structure representing the rectangle to receive + * text (ignored if NULL) + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_SetTextInputRect(const SDL_Rect *rect); + +/** + * Check whether the platform has screen keyboard support. + * + * \returns SDL_TRUE if the platform has some screen keyboard support or + * SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + * \sa SDL_IsScreenKeyboardShown + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); + +/** + * Check whether the screen keyboard is shown for given window. + * + * \param window the window for which screen keyboard should be queried + * \returns SDL_TRUE if screen keyboard is shown or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasScreenKeyboardSupport + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_keyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_keycode.h b/thirdparty/SDL/include/SDL/SDL_keycode.h new file mode 100644 index 00000000..65420f29 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_keycode.h @@ -0,0 +1,358 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keycode.h + * + * Defines constants which identify keyboard keys and modifiers. + */ + +#ifndef SDL_keycode_h_ +#define SDL_keycode_h_ + +#include "SDL_stdinc.h" +#include "SDL_scancode.h" + +/** + * \brief The SDL virtual key representation. + * + * Values of this type are used to represent keyboard keys using the current + * layout of the keyboard. These values include Unicode values representing + * the unmodified character that would be generated by pressing the key, or + * an SDLK_* constant for those keys that do not generate characters. + * + * A special exception is the number keys at the top of the keyboard which + * always map to SDLK_0...SDLK_9, regardless of layout. + */ +typedef Sint32 SDL_Keycode; + +#define SDLK_SCANCODE_MASK (1<<30) +#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK) + +typedef enum +{ + SDLK_UNKNOWN = 0, + + SDLK_RETURN = '\r', + SDLK_ESCAPE = '\x1B', + SDLK_BACKSPACE = '\b', + SDLK_TAB = '\t', + SDLK_SPACE = ' ', + SDLK_EXCLAIM = '!', + SDLK_QUOTEDBL = '"', + SDLK_HASH = '#', + SDLK_PERCENT = '%', + SDLK_DOLLAR = '$', + SDLK_AMPERSAND = '&', + SDLK_QUOTE = '\'', + SDLK_LEFTPAREN = '(', + SDLK_RIGHTPAREN = ')', + SDLK_ASTERISK = '*', + SDLK_PLUS = '+', + SDLK_COMMA = ',', + SDLK_MINUS = '-', + SDLK_PERIOD = '.', + SDLK_SLASH = '/', + SDLK_0 = '0', + SDLK_1 = '1', + SDLK_2 = '2', + SDLK_3 = '3', + SDLK_4 = '4', + SDLK_5 = '5', + SDLK_6 = '6', + SDLK_7 = '7', + SDLK_8 = '8', + SDLK_9 = '9', + SDLK_COLON = ':', + SDLK_SEMICOLON = ';', + SDLK_LESS = '<', + SDLK_EQUALS = '=', + SDLK_GREATER = '>', + SDLK_QUESTION = '?', + SDLK_AT = '@', + + /* + Skip uppercase letters + */ + + SDLK_LEFTBRACKET = '[', + SDLK_BACKSLASH = '\\', + SDLK_RIGHTBRACKET = ']', + SDLK_CARET = '^', + SDLK_UNDERSCORE = '_', + SDLK_BACKQUOTE = '`', + SDLK_a = 'a', + SDLK_b = 'b', + SDLK_c = 'c', + SDLK_d = 'd', + SDLK_e = 'e', + SDLK_f = 'f', + SDLK_g = 'g', + SDLK_h = 'h', + SDLK_i = 'i', + SDLK_j = 'j', + SDLK_k = 'k', + SDLK_l = 'l', + SDLK_m = 'm', + SDLK_n = 'n', + SDLK_o = 'o', + SDLK_p = 'p', + SDLK_q = 'q', + SDLK_r = 'r', + SDLK_s = 's', + SDLK_t = 't', + SDLK_u = 'u', + SDLK_v = 'v', + SDLK_w = 'w', + SDLK_x = 'x', + SDLK_y = 'y', + SDLK_z = 'z', + + SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK), + + SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1), + SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2), + SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3), + SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4), + SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5), + SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6), + SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7), + SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8), + SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9), + SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10), + SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11), + SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12), + + SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN), + SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK), + SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE), + SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), + SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), + SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), + SDLK_DELETE = '\x7F', + SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), + SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), + SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), + SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT), + SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN), + SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP), + + SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR), + SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE), + SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY), + SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS), + SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS), + SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER), + SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1), + SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2), + SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3), + SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4), + SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5), + SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6), + SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7), + SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8), + SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9), + SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0), + SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD), + + SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION), + SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER), + SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS), + SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13), + SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14), + SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15), + SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16), + SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17), + SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18), + SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19), + SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20), + SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21), + SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22), + SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23), + SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24), + SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE), + SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP), + SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU), + SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT), + SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP), + SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN), + SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO), + SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT), + SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY), + SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE), + SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND), + SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE), + SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP), + SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN), + SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA), + SDLK_KP_EQUALSAS400 = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400), + + SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE), + SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ), + SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL), + SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR), + SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR), + SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2), + SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR), + SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT), + SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER), + SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN), + SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL), + SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL), + + SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00), + SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000), + SDLK_THOUSANDSSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR), + SDLK_DECIMALSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR), + SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT), + SDLK_CURRENCYSUBUNIT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT), + SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN), + SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN), + SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE), + SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE), + SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB), + SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE), + SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A), + SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B), + SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C), + SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D), + SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E), + SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F), + SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR), + SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER), + SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT), + SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS), + SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER), + SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND), + SDLK_KP_DBLAMPERSAND = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND), + SDLK_KP_VERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR), + SDLK_KP_DBLVERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR), + SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON), + SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH), + SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE), + SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT), + SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM), + SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE), + SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL), + SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR), + SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD), + SDLK_KP_MEMSUBTRACT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT), + SDLK_KP_MEMMULTIPLY = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY), + SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE), + SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS), + SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR), + SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY), + SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY), + SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL), + SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL), + SDLK_KP_HEXADECIMAL = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL), + + SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL), + SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT), + SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT), + SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI), + SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL), + SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT), + SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT), + SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI), + + SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE), + + SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT), + SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV), + SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP), + SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY), + SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE), + SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT), + SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW), + SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL), + SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR), + SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER), + SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH), + SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME), + SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK), + SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD), + SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP), + SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH), + SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS), + + SDLK_BRIGHTNESSDOWN = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN), + SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP), + SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH), + SDLK_KBDILLUMTOGGLE = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE), + SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN), + SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP), + SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT), + SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP), + SDLK_APP1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP1), + SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), + + SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), + SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD), + + SDLK_SOFTLEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTLEFT), + SDLK_SOFTRIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTRIGHT), + SDLK_CALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALL), + SDLK_ENDCALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ENDCALL) +} SDL_KeyCode; + +/** + * \brief Enumeration of valid key mods (possibly OR'd together). + */ +typedef enum +{ + KMOD_NONE = 0x0000, + KMOD_LSHIFT = 0x0001, + KMOD_RSHIFT = 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LGUI = 0x0400, + KMOD_RGUI = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_SCROLL = 0x8000, + + KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL, + KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT, + KMOD_ALT = KMOD_LALT | KMOD_RALT, + KMOD_GUI = KMOD_LGUI | KMOD_RGUI, + + KMOD_RESERVED = KMOD_SCROLL /* This is for source-level compatibility with SDL 2.0.0. */ +} SDL_Keymod; + +#endif /* SDL_keycode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_loadso.h b/thirdparty/SDL/include/SDL/SDL_loadso.h new file mode 100644 index 00000000..61857c81 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_loadso.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_loadso.h + * + * System dependent library loading routines + * + * Some things to keep in mind: + * \li These functions only work on C function names. Other languages may + * have name mangling and intrinsic language support that varies from + * compiler to compiler. + * \li Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * \li Avoid namespace collisions. If you load a symbol from the library, + * it is not defined whether or not it goes into the global symbol + * namespace for the application. If it does and it conflicts with + * symbols in your code or other shared libraries, you will not get + * the results you expect. :) + */ + +#ifndef SDL_loadso_h_ +#define SDL_loadso_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Dynamically load a shared object. + * + * \param sofile a system-dependent name of the object file + * \returns an opaque pointer to the object handle or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_UnloadObject + */ +extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); + +/** + * Look up the address of the named function in a shared object. + * + * This function pointer is no longer valid after calling SDL_UnloadObject(). + * + * This function can only look up C function names. Other languages may have + * name mangling and intrinsic language support that varies from compiler to + * compiler. + * + * Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * + * If the requested function doesn't exist, NULL is returned. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * \param name the name of the function to look up + * \returns a pointer to the function or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadObject + * \sa SDL_UnloadObject + */ +extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, + const char *name); + +/** + * Unload a shared object from memory. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_LoadObject + */ +extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_loadso_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_locale.h b/thirdparty/SDL/include/SDL/SDL_locale.h new file mode 100644 index 00000000..75157799 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_locale.h @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_locale.h + * + * Include file for SDL locale services + */ + +#ifndef _SDL_locale_h +#define _SDL_locale_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +typedef struct SDL_Locale +{ + const char *language; /**< A language name, like "en" for English. */ + const char *country; /**< A country, like "US" for America. Can be NULL. */ +} SDL_Locale; + +/** + * Report the user's preferred locale. + * + * This returns an array of SDL_Locale structs, the final item zeroed out. + * When the caller is done with this array, it should call SDL_free() on the + * returned value; all the memory involved is allocated in a single block, so + * a single SDL_free() will suffice. + * + * Returned language strings are in the format xx, where 'xx' is an ISO-639 + * language specifier (such as "en" for English, "de" for German, etc). + * Country strings are in the format YY, where "YY" is an ISO-3166 country + * code (such as "US" for the United States, "CA" for Canada, etc). Country + * might be NULL if there's no specific guidance on them (so you might get { + * "en", "US" } for American English, but { "en", NULL } means "English + * language, generically"). Language strings are never NULL, except to + * terminate the array. + * + * Please note that not all of these strings are 2 characters; some are three + * or more. + * + * The returned list of locales are in the order of the user's preference. For + * example, a German citizen that is fluent in US English and knows enough + * Japanese to navigate around Tokyo might have a list like: { "de", "en_US", + * "jp", NULL }. Someone from England might prefer British English (where + * "color" is spelled "colour", etc), but will settle for anything like it: { + * "en_GB", "en", NULL }. + * + * This function returns NULL on error, including when the platform does not + * supply this information at all. + * + * This might be a "slow" call that has to query the operating system. It's + * best to ask for this once and save the results. However, this list can + * change, usually because the user has changed a system preference outside of + * your program; SDL will send an SDL_LOCALECHANGED event in this case, if + * possible, and you can call this function again to get an updated copy of + * preferred locales. + * + * \return array of locales, terminated with a locale with a NULL language + * field. Will return NULL on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_locale_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_log.h b/thirdparty/SDL/include/SDL/SDL_log.h new file mode 100644 index 00000000..1d8b20b6 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_log.h @@ -0,0 +1,404 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_log.h + * + * Simple log messages with categories and priorities. + * + * By default logs are quiet, but if you're debugging SDL you might want: + * + * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); + * + * Here's where the messages go on different platforms: + * Windows: debug output stream + * Android: log output + * Others: standard error output (stderr) + */ + +#ifndef SDL_log_h_ +#define SDL_log_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief The maximum size of a log message prior to SDL 2.0.24 + * + * As of 2.0.24 there is no limit to the length of SDL log messages. + */ +#define SDL_MAX_LOG_MESSAGE 4096 + +/** + * \brief The predefined log categories + * + * By default the application category is enabled at the INFO level, + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * CRITICAL level. + */ +typedef enum +{ + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + /* Reserved for future SDL library use */ + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + /* Beyond this point is reserved for application use, e.g. + enum { + MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, + MYAPP_CATEGORY_AWESOME2, + MYAPP_CATEGORY_AWESOME3, + ... + }; + */ + SDL_LOG_CATEGORY_CUSTOM +} SDL_LogCategory; + +/** + * \brief The predefined log priorities + */ +typedef enum +{ + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} SDL_LogPriority; + + +/** + * Set the priority of all log categories. + * + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); + +/** + * Set the priority of a particular log category. + * + * \param category the category to assign a priority to + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetPriority + * \sa SDL_LogSetAllPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, + SDL_LogPriority priority); + +/** + * Get the priority of a particular log category. + * + * \param category the category to query + * \returns the SDL_LogPriority for the requested category + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); + +/** + * Reset all priorities to default. + * + * This is called by SDL_Quit(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetAllPriority + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); + +/** + * Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO. + * + * = * \param fmt a printf() style message format string + * + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Log a message with SDL_LOG_PRIORITY_VERBOSE. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_DEBUG. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_INFO. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_WARN. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + */ +extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_ERROR. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_CRITICAL. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessage(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ap a variable argument list + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, + SDL_LogPriority priority, + const char *fmt, va_list ap); + +/** + * The prototype for the log output callback function. + * + * This function is called by SDL when there is new text to be logged. + * + * \param userdata what was passed as `userdata` to SDL_LogSetOutputFunction() + * \param category the category of the message + * \param priority the priority of the message + * \param message the message being output + */ +typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); + +/** + * Get the current log output function. + * + * \param callback an SDL_LogOutputFunction filled in with the current log + * callback + * \param userdata a pointer filled in with the pointer that is passed to + * `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); + +/** + * Replace the default log output function with one of your own. + * + * \param callback an SDL_LogOutputFunction to call instead of the default + * \param userdata a pointer that is passed to `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_main.h b/thirdparty/SDL/include/SDL/SDL_main.h new file mode 100644 index 00000000..8b267082 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_main.h @@ -0,0 +1,266 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_main_h_ +#define SDL_main_h_ + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__GDK__) +/* On GDK, SDL provides a main function that initializes the game runtime. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. You must either link against SDL2main or, if not possible, + call the SDL_GDKRunApp function from your entry point. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + If you link with SDL dynamically on iOS, the main function can't be in a + shared library, so you need to link with libSDLmain.a, which includes a + stub main function that calls into the shared library to start execution. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See docs/README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +/* We need to export SDL_main so it can be launched from Java */ +#define SDLMAIN_DECLSPEC DECLSPEC + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__PSP__) +/* On PSP SDL provides a main function that sets the module info, + activates the GPU and starts the thread required to be able to exit + the software. + + If you provide this yourself, you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__PS2__) +#define SDL_MAIN_AVAILABLE + +#define SDL_PS2_SKIP_IOP_RESET() \ + void reset_IOP(); \ + void reset_IOP() {} + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifndef SDLMAIN_DECLSPEC +#define SDLMAIN_DECLSPEC +#endif + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The prototype for the application's main() function + */ +typedef int (*SDL_main_func)(int argc, char *argv[]); +extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); + + +/** + * Circumvent failure of SDL_Init() when not using SDL_main() as an entry + * point. + * + * This function is defined in SDL_main.h, along with the preprocessor rule to + * redefine main() as SDL_main(). Thus to ensure that your main() function + * will not be changed it is necessary to define SDL_MAIN_HANDLED before + * including SDL.h. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#if defined(__WIN32__) || defined(__GDK__) + +/** + * Register a win32 window class for SDL's use. + * + * This can be called to set the application window class at startup. It is + * safe to call this multiple times, as long as every call is eventually + * paired with a call to SDL_UnregisterApp, but a second registration attempt + * while a previous registration is still active will be ignored, other than + * to increment a counter. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when initializing the video subsystem. + * + * \param name the window class name, in UTF-8 encoding. If NULL, SDL + * currently uses "SDL_app" but this isn't guaranteed. + * \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL + * currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of + * what is specified here. + * \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL + * will use `GetModuleHandle(NULL)` instead. + * \returns 0 on success, -1 on error. SDL_GetError() may have details. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst); + +/** + * Deregister the win32 window class from an SDL_RegisterApp call. + * + * This can be called to undo the effects of SDL_RegisterApp. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when deinitializing the video subsystem. + * + * It is safe to call this multiple times, as long as every call is eventually + * paired with a prior call to SDL_RegisterApp. The window class will only be + * deregistered when the registration counter in SDL_RegisterApp decrements to + * zero through calls to this function. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + + +#ifdef __WINRT__ + +/** + * Initialize and launch an SDL/WinRT application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.0.3. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); + +#endif /* __WINRT__ */ + +#if defined(__IPHONEOS__) + +/** + * Initializes and launches an SDL application. + * + * \param argc The argc parameter from the application's main() function + * \param argv The argv parameter from the application's main() function + * \param mainFunction The SDL app's C-style main(), an SDL_main_func + * \return the return value from mainFunction + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); + +#endif /* __IPHONEOS__ */ + +#ifdef __GDK__ + +/** + * Initialize and launch an SDL GDK application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved); + +#endif /* __GDK__ */ + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_main_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_messagebox.h b/thirdparty/SDL/include/SDL/SDL_messagebox.h new file mode 100644 index 00000000..d763534d --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_messagebox.h @@ -0,0 +1,193 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_messagebox_h_ +#define SDL_messagebox_h_ + +#include "SDL_stdinc.h" +#include "SDL_video.h" /* For SDL_Window */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SDL_MessageBox flags. If supported will display warning icon, etc. + */ +typedef enum +{ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040, /**< informational dialog */ + SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = 0x00000080, /**< buttons placed left to right */ + SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = 0x00000100 /**< buttons placed right to left */ +} SDL_MessageBoxFlags; + +/** + * Flags for SDL_MessageBoxButtonData. + */ +typedef enum +{ + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ +} SDL_MessageBoxButtonFlags; + +/** + * Individual button data. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ + int buttonid; /**< User defined button id (value returned via SDL_ShowMessageBox) */ + const char * text; /**< The UTF-8 button text */ +} SDL_MessageBoxButtonData; + +/** + * RGB value used in a message box color scheme + */ +typedef struct +{ + Uint8 r, g, b; +} SDL_MessageBoxColor; + +typedef enum +{ + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX +} SDL_MessageBoxColorType; + +/** + * A set of colors to use for message box dialogs + */ +typedef struct +{ + SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; +} SDL_MessageBoxColorScheme; + +/** + * MessageBox structure containing title, text, window, etc. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxFlags */ + SDL_Window *window; /**< Parent window, can be NULL */ + const char *title; /**< UTF-8 title */ + const char *message; /**< UTF-8 message text */ + + int numbuttons; + const SDL_MessageBoxButtonData *buttons; + + const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ +} SDL_MessageBoxData; + +/** + * Create a modal message box. + * + * If your needs aren't complex, it might be easier to use + * SDL_ShowSimpleMessageBox. + * + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. + * + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param messageboxdata the SDL_MessageBoxData structure with title, text and + * other options + * \param buttonid the pointer to which user id of hit button should be copied + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowSimpleMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +/** + * Display a simple modal message box. + * + * If your needs aren't complex, this function is preferred over + * SDL_ShowMessageBox. + * + * `flags` may be any of the following: + * + * - `SDL_MESSAGEBOX_ERROR`: error dialog + * - `SDL_MESSAGEBOX_WARNING`: warning dialog + * - `SDL_MESSAGEBOX_INFORMATION`: informational dialog + * + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. + * + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param flags an SDL_MessageBoxFlags value + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window the parent window, or NULL for no parent + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_messagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_metal.h b/thirdparty/SDL/include/SDL/SDL_metal.h new file mode 100644 index 00000000..eb308287 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_metal.h @@ -0,0 +1,113 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_metal.h + * + * Header file for functions to creating Metal layers and views on SDL windows. + */ + +#ifndef SDL_metal_h_ +#define SDL_metal_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS). + * + * \note This can be cast directly to an NSView or UIView. + */ +typedef void *SDL_MetalView; + +/** + * \name Metal support functions + */ +/* @{ */ + +/** + * Create a CAMetalLayer-backed NSView/UIView and attach it to the specified + * window. + * + * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on + * its own. It is up to user code to do that. + * + * The returned handle can be casted directly to a NSView or UIView. To access + * the backing CAMetalLayer, call SDL_Metal_GetLayer(). + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_Metal_DestroyView + * \sa SDL_Metal_GetLayer + */ +extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window); + +/** + * Destroy an existing SDL_MetalView object. + * + * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was + * called after SDL_CreateWindow. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_Metal_CreateView + */ +extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view); + +/** + * Get a pointer to the backing CAMetalLayer for the given view. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_MetalCreateView + */ +extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view); + +/** + * Get the size of a window's underlying drawable in pixels (for use with + * setting viewport, scissor & etc). + * + * \param window SDL_Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, may be NULL + * \param h Pointer to variable for storing the height in pixels, may be NULL + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + */ +extern DECLSPEC void SDLCALL SDL_Metal_GetDrawableSize(SDL_Window* window, int *w, + int *h); + +/* @} *//* Metal support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_metal_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_misc.h b/thirdparty/SDL/include/SDL/SDL_misc.h new file mode 100644 index 00000000..261b6b87 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_misc.h @@ -0,0 +1,79 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_misc.h + * + * \brief Include file for SDL API functions that don't fit elsewhere. + */ + +#ifndef SDL_misc_h_ +#define SDL_misc_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Open a URL/URI in the browser or other appropriate external application. + * + * Open a URL in a separate, system-provided application. How this works will + * vary wildly depending on the platform. This will likely launch what makes + * sense to handle a specific URL's protocol (a web browser for `http://`, + * etc), but it might also be able to launch file managers for directories and + * other things. + * + * What happens when you open a URL varies wildly as well: your game window + * may lose focus (and may or may not lose focus if your game was fullscreen + * or grabbing input at the time). On mobile devices, your app will likely + * move to the background or your process might be paused. Any given platform + * may or may not handle a given URL. + * + * If this is unimplemented (or simply unavailable) for a platform, this will + * fail with an error. A successful result does not mean the URL loaded, just + * that we launched _something_ to handle it (or at least believe we did). + * + * All this to say: this function can be useful, but you should definitely + * test it on every platform you target. + * + * \param url A valid URL/URI to open. Use `file:///full/path/to/file` for + * local files, if supported. + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_OpenURL(const char *url); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_misc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_mouse.h b/thirdparty/SDL/include/SDL/SDL_mouse.h new file mode 100644 index 00000000..b318c703 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_mouse.h @@ -0,0 +1,465 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_mouse.h + * + * Include file for SDL mouse event handling. + */ + +#ifndef SDL_mouse_h_ +#define SDL_mouse_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDL_Cursor SDL_Cursor; /**< Implementation dependent */ + +/** + * \brief Cursor types for SDL_CreateSystemCursor(). + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ + SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ + SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ + SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ + SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ + SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ + SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ + SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ + SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ + SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ + SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ + SDL_SYSTEM_CURSOR_HAND, /**< Hand */ + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; + +/** + * \brief Scroll direction types for the Scroll event + */ +typedef enum +{ + SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ + SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ +} SDL_MouseWheelDirection; + +/* Function prototypes */ + +/** + * Get the window which currently has mouse focus. + * + * \returns the window with mouse focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); + +/** + * Retrieve the current state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse cursor position relative to the focus window. You can pass NULL for + * either `x` or `y`. + * + * \param x the x coordinate of the mouse cursor position relative to the + * focus window + * \param y the y coordinate of the mouse cursor position relative to the + * focus window + * \returns a 32-bit button bitmask of the current button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGlobalMouseState + * \sa SDL_GetRelativeMouseState + * \sa SDL_PumpEvents + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); + +/** + * Get the current state of the mouse in relation to the desktop. + * + * This works similarly to SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if you + * need to track the mouse outside of a specific window and SDL_CaptureMouse() + * doesn't fit your needs. For example, it could be useful if you need to + * track the mouse while dragging a window, where coordinates relative to a + * window might not be in sync at all times. + * + * Note: SDL_GetMouseState() returns the mouse position as SDL understands it + * from the last pump of the event queue. This function, however, queries the + * OS for the current mouse position, and as such, might be a slightly less + * efficient function. Unless you know what you're doing and have a good + * reason to use this function, you probably want SDL_GetMouseState() instead. + * + * \param x filled in with the current X coord relative to the desktop; can be + * NULL + * \param y filled in with the current Y coord relative to the desktop; can be + * NULL + * \returns the current button state as a bitmask which can be tested using + * the SDL_BUTTON(X) macros. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_CaptureMouse + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); + +/** + * Retrieve the relative state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState() or since + * event initialization. You can pass NULL for either `x` or `y`. + * + * \param x a pointer filled with the last recorded x coordinate of the mouse + * \param y a pointer filled with the last recorded y coordinate of the mouse + * \returns a 32-bit button bitmask of the relative button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetMouseState + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/** + * Move the mouse cursor to the given position within the window. + * + * This function generates a mouse motion event if relative mode is not + * enabled. If relative mode is enabled, you can force mouse events for the + * warp by setting the SDL_HINT_MOUSE_RELATIVE_WARP_MOTION hint. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param window the window to move the mouse into, or NULL for the current + * mouse focus + * \param x the x coordinate within the window + * \param y the y coordinate within the window + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WarpMouseGlobal + */ +extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, + int x, int y); + +/** + * Move the mouse to the given position in global screen space. + * + * This function generates a mouse motion event. + * + * A failure of this function usually means that it is unsupported by a + * platform. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param x the x coordinate + * \param y the y coordinate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_WarpMouseInWindow + */ +extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); + +/** + * Set relative mouse mode. + * + * While the mouse is in relative mode, the cursor is hidden, and the driver + * will try to report continuous motion in the current window. Only relative + * motion events will be delivered, the mouse position will not change. + * + * Note that this function will not be able to provide continuous relative + * motion when used over Microsoft Remote Desktop, instead motion is limited + * to the bounds of the screen. + * + * This function will flush any pending mouse motion. + * + * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * If relative mode is not supported, this returns -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRelativeMouseMode + */ +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); + +/** + * Capture the mouse and to track input outside an SDL window. + * + * Capturing enables your app to obtain mouse events globally, instead of just + * within your window. Not all video targets support this function. When + * capturing is enabled, the current window will get all mouse events, but + * unlike relative mode, no change is made to the cursor and it is not + * restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this function + * sparingly, and in small bursts. For example, you might want to track the + * mouse while the user is dragging something, until the user releases a mouse + * button. It is not recommended that you capture the mouse for long periods + * of time, such as the entire time your app is running. For that, you should + * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowGrab(), depending + * on your goals. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only allowed + * for the foreground window. If the window loses focus while capturing, the + * capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * `SDL_WINDOW_MOUSE_CAPTURE` flag set. + * + * Please note that as of SDL 2.0.22, SDL will attempt to "auto capture" the + * mouse while the user is pressing a button; this is to try and make mouse + * behavior more consistent between platforms, and deal with the common case + * of a user dragging the mouse outside of the window. This means that if you + * are calling SDL_CaptureMouse() only to deal with this situation, you no + * longer have to (although it is safe to do so). If this causes problems for + * your app, you can disable auto capture by setting the + * `SDL_HINT_MOUSE_AUTO_CAPTURE` hint to zero. + * + * \param enabled SDL_TRUE to enable capturing, SDL_FALSE to disable. + * \returns 0 on success or -1 if not supported; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetGlobalMouseState + */ +extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); + +/** + * Query whether relative mouse mode is enabled. + * + * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRelativeMouseMode + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); + +/** + * Create a cursor using the specified bitmap data and mask (in MSB format). + * + * `mask` has to be in MSB (Most Significant Bit) format. + * + * The cursor width (`w`) must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * + * - data=0, mask=1: white + * - data=1, mask=1: black + * - data=0, mask=0: transparent + * - data=1, mask=0: inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_FreeCursor(). + * + * If you want to have a color cursor, or create your cursor from an + * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can + * hide the cursor and draw your own as part of your game's rendering, but it + * will be bound to the framerate. + * + * Also, since SDL 2.0.0, SDL_CreateSystemCursor() is available, which + * provides twelve readily available system cursors to pick from. + * + * \param data the color value for each pixel of the cursor + * \param mask the mask value for each pixel of the cursor + * \param w the width of the cursor + * \param h the height of the cursor + * \param hot_x the X-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \param hot_y the Y-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \returns a new cursor with the specified parameters on success or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + * \sa SDL_SetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, + const Uint8 * mask, + int w, int h, int hot_x, + int hot_y); + +/** + * Create a color cursor. + * + * \param surface an SDL_Surface structure representing the cursor image + * \param hot_x the x position of the cursor hot spot + * \param hot_y the y position of the cursor hot spot + * \returns the new cursor on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, + int hot_x, + int hot_y); + +/** + * Create a system cursor. + * + * \param id an SDL_SystemCursor enum value + * \returns a cursor on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + +/** + * Set the active cursor. + * + * This function sets the currently active cursor to the specified one. If the + * cursor is currently visible, the change will be immediately represented on + * the display. SDL_SetCursor(NULL) can be used to force cursor redraw, if + * this is desired for any reason. + * + * \param cursor a cursor to make active + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_GetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); + +/** + * Get the active cursor. + * + * This function returns a pointer to the current cursor which is owned by the + * library. It is not necessary to free the cursor with SDL_FreeCursor(). + * + * \returns the active cursor or NULL if there is no mouse. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); + +/** + * Get the default cursor. + * + * \returns the default cursor on success or NULL on failure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); + +/** + * Free a previously-created cursor. + * + * Use this function to free cursor resources created with SDL_CreateCursor(), + * SDL_CreateColorCursor() or SDL_CreateSystemCursor(). + * + * \param cursor the cursor to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateColorCursor + * \sa SDL_CreateCursor + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); + +/** + * Toggle whether or not the cursor is shown. + * + * The cursor starts off displayed but can be turned off. Passing `SDL_ENABLE` + * displays the cursor and passing `SDL_DISABLE` hides it. + * + * The current state of the mouse cursor can be queried by passing + * `SDL_QUERY`; either `SDL_DISABLE` or `SDL_ENABLE` will be returned. + * + * \param toggle `SDL_ENABLE` to show the cursor, `SDL_DISABLE` to hide it, + * `SDL_QUERY` to query the current state without changing it. + * \returns `SDL_ENABLE` if the cursor is shown, or `SDL_DISABLE` if the + * cursor is hidden, or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_SetCursor + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/** + * Used as a mask when testing buttons in buttonstate. + * + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_X1 4 +#define SDL_BUTTON_X2 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_mutex.h b/thirdparty/SDL/include/SDL/SDL_mutex.h new file mode 100644 index 00000000..173468f6 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_mutex.h @@ -0,0 +1,471 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_mutex_h_ +#define SDL_mutex_h_ + +/** + * \file SDL_mutex.h + * + * Functions to provide thread synchronization primitives. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Synchronization functions which can time out return this value + * if they time out. + */ +#define SDL_MUTEX_TIMEDOUT 1 + +/** + * This is the timeout value which corresponds to never time out. + */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/** + * \name Mutex functions + */ +/* @{ */ + +/* The SDL mutex structure, defined in SDL_sysmutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/** + * Create a new mutex. + * + * All newly-created mutexes begin in the _unlocked_ state. + * + * Calls to SDL_LockMutex() will not return while the mutex is locked by + * another thread. See SDL_TryLockMutex() to attempt to lock without blocking. + * + * SDL mutexes are reentrant. + * + * \returns the initialized and unlocked mutex or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); + +/** + * Lock the mutex. + * + * This will block until the mutex is available, which is to say it is in the + * unlocked state and the OS has chosen the caller as the next thread to lock + * it. Of all threads waiting to lock the mutex, only one may do so at a time. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * \param mutex the mutex to lock + * \return 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); +#define SDL_mutexP(m) SDL_LockMutex(m) + +/** + * Try to lock a mutex without blocking. + * + * This works just like SDL_LockMutex(), but if the mutex is not available, + * this function returns `SDL_MUTEX_TIMEOUT` immediately. + * + * This technique is useful if you need exclusive access to a resource but + * don't want to wait for it, and will return to it to try again later. + * + * \param mutex the mutex to try to lock + * \returns 0, `SDL_MUTEX_TIMEDOUT`, or -1 on error; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); + +/** + * Unlock the mutex. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * It is an error to unlock a mutex that has not been locked by the current + * thread, and doing so results in undefined behavior. + * + * It is also an error to unlock a mutex that isn't locked at all. + * + * \param mutex the mutex to unlock. + * \returns 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex); +#define SDL_mutexV(m) SDL_UnlockMutex(m) + +/** + * Destroy a mutex created with SDL_CreateMutex(). + * + * This function must be called on any mutex that is no longer needed. Failure + * to destroy a mutex will result in a system memory or resource leak. While + * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt + * to destroy a locked mutex, and may result in undefined behavior depending + * on the platform. + * + * \param mutex the mutex to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); + +/* @} *//* Mutex functions */ + + +/** + * \name Semaphore functions + */ +/* @{ */ + +/* The SDL semaphore structure, defined in SDL_syssem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/** + * Create a semaphore. + * + * This function creates a new semaphore and initializes it with the value + * `initial_value`. Each wait operation on the semaphore will atomically + * decrement the semaphore value and potentially block if the semaphore value + * is 0. Each post operation will atomically increment the semaphore value and + * wake waiting threads and allow them to retry the wait operation. + * + * \param initial_value the starting value of the semaphore + * \returns a new semaphore or NULL on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/** + * Destroy a semaphore. + * + * It is not safe to destroy a semaphore if there are threads currently + * waiting on it. + * + * \param sem the semaphore to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value or the call is interrupted by a + * signal or error. If the call is successful it will atomically decrement the + * semaphore value. + * + * This function is the equivalent of calling SDL_SemWaitTimeout() with a time + * length of `SDL_MUTEX_MAXWAIT`. + * + * \param sem the semaphore wait on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); + +/** + * See if a semaphore has a positive value and decrement it if it does. + * + * This function checks to see if the semaphore pointed to by `sem` has a + * positive value and atomically decrements the semaphore value if it does. If + * the semaphore doesn't have a positive value, the function immediately + * returns SDL_MUTEX_TIMEDOUT. + * + * \param sem the semaphore to wait on + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait would + * block, or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value, the call is interrupted by a + * signal or error, or the specified time has elapsed. If the call is + * successful it will atomically decrement the semaphore value. + * + * \param sem the semaphore to wait on + * \param ms the length of the timeout, in milliseconds + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not + * succeed in the allotted time, or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + */ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms); + +/** + * Atomically increment a semaphore's value and wake waiting threads. + * + * \param sem the semaphore to increment + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); + +/** + * Get the current value of a semaphore. + * + * \param sem the semaphore to query + * \returns the current value of the semaphore. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); + +/* @} *//* Semaphore functions */ + + +/** + * \name Condition variable functions + */ +/* @{ */ + +/* The SDL condition variable structure, defined in SDL_syscond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/** + * Create a condition variable. + * + * \returns a new condition variable or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_DestroyCond + */ +extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); + +/** + * Destroy a condition variable. + * + * \param cond the condition variable to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); + +/** + * Restart one of the threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); + +/** + * Restart all threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); + +/** + * Wait until a condition variable is signaled. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`. Once the condition variable is signaled, the mutex is re-locked and + * the function returns. + * + * The mutex must be locked before calling this function. + * + * This function is the equivalent of calling SDL_CondWaitTimeout() with a + * time length of `SDL_MUTEX_MAXWAIT`. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \returns 0 when it is signaled or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); + +/** + * Wait until a condition variable is signaled or a certain time has passed. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`, or for the specified time to elapse. Once the condition variable is + * signaled or the time elapsed, the mutex is re-locked and the function + * returns. + * + * The mutex must be locked before calling this function. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT` + * to wait indefinitely + * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if + * the condition is not signaled in the allotted time, or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +/* @} *//* Condition variable functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mutex_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_name.h b/thirdparty/SDL/include/SDL/SDL_name.h new file mode 100644 index 00000000..6ff35b46 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_name.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDLname_h_ +#define SDLname_h_ + +#if defined(__STDC__) || defined(__cplusplus) +#define NeedFunctionPrototypes 1 +#endif + +#define SDL_NAME(X) SDL_##X + +#endif /* SDLname_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_opengl.h b/thirdparty/SDL/include/SDL/SDL_opengl.h new file mode 100644 index 00000000..9aed5035 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengl.h @@ -0,0 +1,2183 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengl.h + * + * This is a simple file to encapsulate the OpenGL API headers. + */ + +/** + * \def NO_SDL_GLEXT + * + * Define this if you have your own version of glext.h and want to disable the + * version included in SDL_opengl.h. + */ + +#ifndef SDL_opengl_h_ +#define SDL_opengl_h_ + +#include "SDL_config.h" + +#ifndef __IPHONEOS__ /* No OpenGL on iOS. */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __gl_h_ +#define __gl_h_ + +#if defined(USE_MGL_NAMESPACE) +#include "gl_mangle.h" +#endif + + +/********************************************************************** + * Begin system-specific stuff. + */ + +#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) +#define __WIN32__ +#endif + +#if defined(__WIN32__) && !defined(__CYGWIN__) +# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ +# define GLAPI __declspec(dllexport) +# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ +# define GLAPI __declspec(dllimport) +# else /* for use with static link lib build of Win32 edition only */ +# define GLAPI extern +# endif /* _STATIC_MESA support */ +# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ +# define GLAPIENTRY +# else +# define GLAPIENTRY __stdcall +# endif +#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ +# define GLAPI extern +# define GLAPIENTRY __stdcall +#elif defined(__OS2__) || defined(__EMX__) /* native os/2 opengl */ +# define GLAPI extern +# define GLAPIENTRY _System +# define APIENTRY _System +# if defined(__GNUC__) && !defined(_System) +# define _System +# endif +#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define GLAPI __attribute__((visibility("default"))) +# define GLAPIENTRY +#endif /* WIN32 && !CYGWIN */ + +/* + * WINDOWS: Include windows.h here to define APIENTRY. + * It is also useful when applications include this file by + * including only glut.h, since glut.h depends on windows.h. + * Applications needing to include windows.h with parms other + * than "WIN32_LEAN_AND_MEAN" may include windows.h before + * glut.h or gl.h. + */ +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef GLAPI +#define GLAPI extern +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef APIENTRY +#define APIENTRY GLAPIENTRY +#endif + +/* "P" suffix to be used for a pointer to a function */ +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GLAPIENTRYP +#define GLAPIENTRYP GLAPIENTRY * +#endif + +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export on +#endif + +/* + * End system-specific stuff. + **********************************************************************/ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 +#define GL_VERSION_1_3 1 +#define GL_ARB_imaging 1 + + +/* + * Datatypes + */ +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; /* 1-byte signed */ +typedef short GLshort; /* 2-byte signed */ +typedef int GLint; /* 4-byte signed */ +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef unsigned short GLushort; /* 2-byte unsigned */ +typedef unsigned int GLuint; /* 4-byte unsigned */ +typedef int GLsizei; /* 4-byte signed */ +typedef float GLfloat; /* single precision float */ +typedef float GLclampf; /* single precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ +typedef double GLclampd; /* double precision float in [0,1] */ + + + +/* + * Constants + */ + +/* Boolean values */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* Data types */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + +/* Primitives */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* Vertex Arrays */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* Matrix Mode */ +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* Points */ +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 + +/* Lines */ +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 + +/* Polygons */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* Display Lists */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 + +/* Depth buffer */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_COMPONENT 0x1902 + +/* Lighting */ +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_SHININESS 0x1601 +#define GL_EMISSION 0x1600 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_SHADE_MODEL 0x0B54 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_NORMALIZE 0x0BA1 + +/* User clipping planes */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* Accumulation buffer */ +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM 0x0100 +#define GL_ADD 0x0104 +#define GL_LOAD 0x0101 +#define GL_MULT 0x0103 +#define GL_RETURN 0x0102 + +/* Alpha testing */ +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +/* Blending */ +#define GL_BLEND 0x0BE2 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_DST 0x0BE0 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 + +/* Render Mode */ +#define GL_FEEDBACK 0x1C01 +#define GL_RENDER 0x1C00 +#define GL_SELECT 0x1C02 + +/* Feedback */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + +/* Selection */ +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 + +/* Fog */ +#define GL_FOG 0x0B60 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_LINEAR 0x2601 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* Logic Ops */ +#define GL_LOGIC_OP 0x0BF1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_CLEAR 0x1500 +#define GL_SET 0x150F +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_NOOP 0x1505 +#define GL_INVERT 0x150A +#define GL_AND 0x1501 +#define GL_NAND 0x150E +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_XOR 0x1506 +#define GL_EQUIV 0x1509 +#define GL_AND_REVERSE 0x1502 +#define GL_AND_INVERTED 0x1504 +#define GL_OR_REVERSE 0x150B +#define GL_OR_INVERTED 0x150D + +/* Stencil */ +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_INDEX 0x1901 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 + +/* Buffers, Pixel Drawing/Reading */ +#define GL_NONE 0 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +/*GL_FRONT 0x0404 */ +/*GL_BACK 0x0405 */ +/*GL_FRONT_AND_BACK 0x0408 */ +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_COLOR_INDEX 0x1900 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_ALPHA_BITS 0x0D55 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_INDEX_BITS 0x0D51 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_READ_BUFFER 0x0C02 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_BITMAP 0x1A00 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_DITHER 0x0BD0 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 + +/* Implementation limits */ +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + +/* Gets */ +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_RENDER_MODE 0x0C40 +#define GL_RGBA_MODE 0x0C31 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_VIEWPORT 0x0BA2 + +/* Evaluators */ +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 + +/* Hints */ +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* Scissor box */ +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 + +/* Pixel Mode / Transfer */ +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + +/* Texture mapping */ +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_SPHERE_MAP 0x2402 +#define GL_DECAL 0x2101 +#define GL_MODULATE 0x2100 +#define GL_NEAREST 0x2600 +#define GL_REPEAT 0x2901 +#define GL_CLAMP 0x2900 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 + +/* Utility */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* Errors */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 + +/* glPush/PopAttrib bits */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000FFFFF + + +/* OpenGL 1.1 */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF + + + +/* + * Miscellaneous + */ + +GLAPI void GLAPIENTRY glClearIndex( GLfloat c ); + +GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glClear( GLbitfield mask ); + +GLAPI void GLAPIENTRY glIndexMask( GLuint mask ); + +GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); + +GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref ); + +GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); + +GLAPI void GLAPIENTRY glLogicOp( GLenum opcode ); + +GLAPI void GLAPIENTRY glCullFace( GLenum mode ); + +GLAPI void GLAPIENTRY glFrontFace( GLenum mode ); + +GLAPI void GLAPIENTRY glPointSize( GLfloat size ); + +GLAPI void GLAPIENTRY glLineWidth( GLfloat width ); + +GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern ); + +GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode ); + +GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units ); + +GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask ); + +GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask ); + +GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag ); + +GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag ); + +GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height); + +GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation ); + +GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation ); + +GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glReadBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glEnable( GLenum cap ); + +GLAPI void GLAPIENTRY glDisable( GLenum cap ); + +GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap ); + + +GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */ + +GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */ + + +GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params ); + +GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params ); + +GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params ); + +GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask ); + +GLAPI void GLAPIENTRY glPopAttrib( void ); + + +GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */ + +GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */ + + +GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode ); + +GLAPI GLenum GLAPIENTRY glGetError( void ); + +GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name ); + +GLAPI void GLAPIENTRY glFinish( void ); + +GLAPI void GLAPIENTRY glFlush( void ); + +GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode ); + + +/* + * Depth Buffer + */ + +GLAPI void GLAPIENTRY glClearDepth( GLclampd depth ); + +GLAPI void GLAPIENTRY glDepthFunc( GLenum func ); + +GLAPI void GLAPIENTRY glDepthMask( GLboolean flag ); + +GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val ); + + +/* + * Accumulation Buffer + */ + +GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); + +GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value ); + + +/* + * Transformation + */ + +GLAPI void GLAPIENTRY glMatrixMode( GLenum mode ); + +GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, + GLsizei width, GLsizei height ); + +GLAPI void GLAPIENTRY glPushMatrix( void ); + +GLAPI void GLAPIENTRY glPopMatrix( void ); + +GLAPI void GLAPIENTRY glLoadIdentity( void ); + +GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glRotated( GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z ); + + +/* + * Display Lists + */ + +GLAPI GLboolean GLAPIENTRY glIsList( GLuint list ); + +GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ); + +GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ); + +GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ); + +GLAPI void GLAPIENTRY glEndList( void ); + +GLAPI void GLAPIENTRY glCallList( GLuint list ); + +GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type, + const GLvoid *lists ); + +GLAPI void GLAPIENTRY glListBase( GLuint base ); + + +/* + * Drawing Functions + */ + +GLAPI void GLAPIENTRY glBegin( GLenum mode ); + +GLAPI void GLAPIENTRY glEnd( void ); + + +GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex2iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex3iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex4iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ); +GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ); +GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ); +GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz ); +GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz ); + +GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glNormal3iv( const GLint *v ); +GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glIndexd( GLdouble c ); +GLAPI void GLAPIENTRY glIndexf( GLfloat c ); +GLAPI void GLAPIENTRY glIndexi( GLint c ); +GLAPI void GLAPIENTRY glIndexs( GLshort c ); +GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c ); +GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c ); +GLAPI void GLAPIENTRY glIndexiv( const GLint *c ); +GLAPI void GLAPIENTRY glIndexsv( const GLshort *c ); +GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue ); +GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue ); +GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue ); +GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue ); +GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue ); +GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue ); +GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue ); +GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue ); + +GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green, + GLbyte blue, GLbyte alpha ); +GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green, + GLdouble blue, GLdouble alpha ); +GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ); +GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green, + GLint blue, GLint alpha ); +GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green, + GLshort blue, GLshort alpha ); +GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ); +GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green, + GLuint blue, GLuint alpha ); +GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green, + GLushort blue, GLushort alpha ); + + +GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor3iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor3sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor3usv( const GLushort *v ); + +GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor4iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor4sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor4usv( const GLushort *v ); + + +GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s ); +GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s ); +GLAPI void GLAPIENTRY glTexCoord1i( GLint s ); +GLAPI void GLAPIENTRY glTexCoord1s( GLshort s ); + +GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t ); +GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t ); +GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t ); +GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ); +GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r ); +GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r ); +GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); +GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); +GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q ); +GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); +GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); +GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 ); +GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); + + +GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ); +GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ); +GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 ); +GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ); + + +/* + * Vertex Arrays (1.1) + */ + +GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params ); + +GLAPI void GLAPIENTRY glArrayElement( GLint i ); + +GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); + +GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride, + const GLvoid *pointer ); + +/* + * Lighting + */ + +GLAPI void GLAPIENTRY glShadeModel( GLenum mode ); + +GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname, + GLfloat *params ); +GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode ); + + +/* + * Raster functions + */ + +GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor ); + +GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize, + const GLfloat *values ); +GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize, + const GLuint *values ); +GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize, + const GLushort *values ); + +GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ); +GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ); +GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values ); + +GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + +GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels ); + +GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type ); + +/* + * Stenciling + */ + +GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask ); + +GLAPI void GLAPIENTRY glStencilMask( GLuint mask ); + +GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ); + +GLAPI void GLAPIENTRY glClearStencil( GLint s ); + + + +/* + * Texture mapping + */ + +GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param ); +GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params ); +GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); +GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target, + GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target, + GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level, + GLenum format, GLenum type, + GLvoid *pixels ); + + +/* 1.1 functions */ + +GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures ); + +GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures); + +GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture ); + +GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n, + const GLuint *textures, + const GLclampf *priorities ); + +GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, + const GLuint *textures, + GLboolean *residences ); + +GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture ); + + +GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level, + GLint xoffset, + GLsizei width, GLenum format, + GLenum type, const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + + +/* + * Evaluators + */ + +GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2, + GLint stride, + GLint order, const GLdouble *points ); +GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2, + GLint stride, + GLint order, const GLfloat *points ); + +GLAPI void GLAPIENTRY glMap2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ); +GLAPI void GLAPIENTRY glMap2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ); + +GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ); +GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ); +GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ); + +GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u ); +GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u ); + +GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v ); +GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v ); + +GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); +GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); + +GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ); +GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +GLAPI void GLAPIENTRY glEvalPoint1( GLint i ); + +GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j ); + +GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 ); + +GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); + + +/* + * Fog + */ + +GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param ); + +GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params ); + +GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params ); + + +/* + * Selection and Feedback + */ + +GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); + +GLAPI void GLAPIENTRY glPassThrough( GLfloat token ); + +GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ); + +GLAPI void GLAPIENTRY glInitNames( void ); + +GLAPI void GLAPIENTRY glLoadName( GLuint name ); + +GLAPI void GLAPIENTRY glPushName( GLuint name ); + +GLAPI void GLAPIENTRY glPopName( void ); + + + +/* + * OpenGL 1.2 + */ + +#define GL_RESCALE_NORMAL 0x803A +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_TEXTURE_BINDING_3D 0x806A + +GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, + GLenum type, const GLvoid *pixels); + +GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, + GLint y, GLsizei width, + GLsizei height ); + +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + +/* + * GL_ARB_imaging + */ + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_BLEND_EQUATION 0x8009 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_COLOR 0x8005 + + +GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat, + GLsizei width, GLenum format, + GLenum type, const GLvoid *table ); + +GLAPI void GLAPIENTRY glColorSubTable( GLenum target, + GLsizei start, GLsizei count, + GLenum format, GLenum type, + const GLvoid *data ); + +GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname, + const GLint *params); + +GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + +GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *table ); + +GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glBlendEquation( GLenum mode ); + +GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width, + GLenum internalformat, GLboolean sink ); + +GLAPI void GLAPIENTRY glResetHistogram( GLenum target ); + +GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset, + GLenum format, GLenum type, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat, + GLboolean sink ); + +GLAPI void GLAPIENTRY glResetMinmax( GLenum target ); + +GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset, + GLenum format, GLenum types, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target, + GLenum internalformat, GLsizei width, GLenum format, GLenum type, + const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname, + GLfloat params ); + +GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); + +GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname, + GLint params ); + +GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height); + +GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format, + GLenum type, GLvoid *image ); + +GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *row, const GLvoid *column ); + +GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, + GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); + + + + +/* + * OpenGL 1.3 + */ + +/* multitexture */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +/* texture_cube_map */ +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +/* texture_compression */ +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +/* multisample */ +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +/* transpose_matrix */ +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +/* texture_env_combine */ +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +/* texture_env_dot3 */ +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +/* texture_border_clamp */ +#define GL_CLAMP_TO_BORDER 0x812D + +GLAPI void GLAPIENTRY glActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ); + +GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v ); + + +GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); + + +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); + + + +/* + * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) + */ +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s); +GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s); +GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s); +GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s); +GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t); +GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t); +GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v); + +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#endif /* GL_ARB_multitexture */ + + + +/* + * Define this token if you want "old-style" header file behaviour (extensions + * defined in gl.h). Otherwise, extensions will be included from glext.h. + */ +#if !defined(NO_SDL_GLEXT) && !defined(GL_GLEXT_LEGACY) +#include "SDL_opengl_glext.h" +#endif /* GL_GLEXT_LEGACY */ + + + +/* + * ???. GL_MESA_packed_depth_stencil + * XXX obsolete + */ +#ifndef GL_MESA_packed_depth_stencil +#define GL_MESA_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_MESA 0x8750 +#define GL_UNSIGNED_INT_24_8_MESA 0x8751 +#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 +#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 +#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 + +#endif /* GL_MESA_packed_depth_stencil */ + + +#ifndef GL_ATI_blend_equation_separate +#define GL_ATI_blend_equation_separate 1 + +#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D + +GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); + +#endif /* GL_ATI_blend_equation_separate */ + + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + + +/** + ** NOTE!!!!! If you add new functions to this file, or update + ** glext.h be sure to regenerate the gl_mangle.h file. See comments + ** in that file for details. + **/ + + + +/********************************************************************** + * Begin system-specific stuff + */ +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export off +#endif + +/* + * End system-specific stuff + **********************************************************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* __gl_h_ */ + +#endif /* !__IPHONEOS__ */ + +#endif /* SDL_opengl_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_opengl_glext.h b/thirdparty/SDL/include/SDL/SDL_opengl_glext.h new file mode 100644 index 00000000..6a402b15 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengl_glext.h @@ -0,0 +1,11180 @@ +#ifndef __glext_h_ +#define __glext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 26745 $ on $Date: 2014-05-21 03:12:26 -0700 (Wed, 21 May 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +#define GL_GLEXT_VERSION 20140521 + +/* Generated C header for: + * API: gl + * Profile: compatibility + * Versions considered: .* + * Versions emitted: 1\.[2-9]|[234]\.[0-9] + * Default extensions included: gl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_VERSION_1_2 */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum texture); +GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); +GLAPI void APIENTRY glClientActiveTexture (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); +#endif +#endif /* GL_VERSION_1_3 */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFogCoordf (GLfloat coord); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); +GLAPI void APIENTRY glFogCoordd (GLdouble coord); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2iv (const GLint *v); +GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); +GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3iv (const GLint *v); +GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); +GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glBlendEquation (GLenum mode); +#endif +#endif /* GL_VERSION_1_4 */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#include +#ifdef __MACOSX__ +typedef long GLsizeiptr; +typedef long GLintptr; +#else +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; +#endif +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQuery (GLuint id); +GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQuery (GLenum target); +GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); +GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_VERSION_1_5 */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +typedef char GLchar; +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GLAPI void APIENTRY glCompileShader (GLuint shader); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum type); +GLAPI void APIENTRY glDeleteProgram (GLuint program); +GLAPI void APIENTRY glDeleteShader (GLuint shader); +GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgram (GLuint program); +GLAPI GLboolean APIENTRY glIsShader (GLuint shader); +GLAPI void APIENTRY glLinkProgram (GLuint program); +GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GLAPI void APIENTRY glUseProgram (GLuint program); +GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glValidateProgram (GLuint program); +GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#endif +#endif /* GL_VERSION_2_0 */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_VERSION_2_1 */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); +GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); +GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedback (void); +GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); +GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRender (void); +GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); +GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmap (GLenum target); +GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glBindVertexArray (GLuint array); +GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); +#endif +#endif /* GL_VERSION_3_0 */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); +GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#endif +#endif /* GL_VERSION_3_1 */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +typedef struct __GLsync *GLsync; +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef uint64_t GLuint64; +typedef int64_t GLint64; +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +GLAPI void APIENTRY glProvokingVertex (GLenum mode); +GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GLAPI GLboolean APIENTRY glIsSync (GLsync sync); +GLAPI void APIENTRY glDeleteSync (GLsync sync); +GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +#endif +#endif /* GL_VERSION_3_2 */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#define GL_INT_2_10_10_10_REV 0x8D9F +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); +GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); +GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); +GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); +GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); +GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); +#endif +#endif /* GL_VERSION_3_3 */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); +typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); +typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); +typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); +typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShading (GLfloat value); +GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); +GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); +GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); +GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); +GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); +GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); +GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedback (void); +GLAPI void APIENTRY glResumeTransformFeedback (void); +GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); +GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); +GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); +GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); +GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_VERSION_4_0 */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_RGB565 0x8D62 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); +typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); +typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReleaseShaderCompiler (void); +GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GLAPI void APIENTRY glClearDepthf (GLfloat d); +GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); +GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); +GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); +GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); +GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); +GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); +#endif +#endif /* GL_VERSION_4_1 */ + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); +GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); +GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#endif +#endif /* GL_VERSION_4_2 */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_DISPLAY_LIST 0x82E7 +typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); +GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); +GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GLAPI void APIENTRY glPopDebugGroup (void); +GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_VERSION_4_3 */ + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); +GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#endif +#endif /* GL_VERSION_4_4 */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 +#endif /* GL_ARB_ES2_compatibility */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 +#endif /* GL_ARB_ES3_compatibility */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 +#endif /* GL_ARB_arrays_of_arrays */ + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 +#endif /* GL_ARB_base_instance */ + +#ifndef GL_ARB_bindless_texture +#define GL_ARB_bindless_texture 1 +typedef uint64_t GLuint64EXT; +#define GL_UNSIGNED_INT64_ARB 0x140F +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_ARB_bindless_texture */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 +#endif /* GL_ARB_blend_func_extended */ + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 +#endif /* GL_ARB_buffer_storage */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 +struct _cl_context; +struct _cl_event; +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#endif +#endif /* GL_ARB_cl_event */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 +#endif /* GL_ARB_clear_buffer_object */ + +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 +#endif /* GL_ARB_clear_texture */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); +#endif +#endif /* GL_ARB_color_buffer_float */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 +#endif /* GL_ARB_compatibility */ + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#endif /* GL_ARB_compute_shader */ + +#ifndef GL_ARB_compute_variable_group_size +#define GL_ARB_compute_variable_group_size 1 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#endif +#endif /* GL_ARB_compute_variable_group_size */ + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 +#endif /* GL_ARB_conservative_depth */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#endif /* GL_ARB_copy_buffer */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 +#endif /* GL_ARB_copy_image */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#endif +#endif /* GL_ARB_debug_output */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 +#endif /* GL_ARB_depth_buffer_float */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 +#endif /* GL_ARB_depth_clamp */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif /* GL_ARB_depth_texture */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ARB_draw_buffers */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif +#endif /* GL_ARB_draw_buffers_blend */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 +#endif /* GL_ARB_draw_elements_base_vertex */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 +#endif /* GL_ARB_draw_indirect */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_ARB_draw_instanced */ + +#ifndef GL_ARB_enhanced_layouts +#define GL_ARB_enhanced_layouts 1 +#endif /* GL_ARB_enhanced_layouts */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 +#endif /* GL_ARB_explicit_attrib_location */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 +#endif /* GL_ARB_explicit_uniform_location */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 +#endif /* GL_ARB_fragment_coord_conventions */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 +#endif /* GL_ARB_fragment_layer_viewport */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, void *string); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); +#endif +#endif /* GL_ARB_fragment_program */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif /* GL_ARB_fragment_program_shadow */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif /* GL_ARB_fragment_shader */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 +#endif /* GL_ARB_framebuffer_no_attachments */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +#endif /* GL_ARB_framebuffer_object */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 +#endif /* GL_ARB_framebuffer_sRGB */ + +#ifndef GL_KHR_context_flush_control +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#endif /* GL_KHR_context_flush_control */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_ARB_geometry_shader4 */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 +#endif /* GL_ARB_get_program_binary */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 +#endif /* GL_ARB_gpu_shader5 */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 +#endif /* GL_ARB_gpu_shader_fp64 */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +typedef unsigned short GLhalfARB; +#define GL_HALF_FLOAT_ARB 0x140B +#endif /* GL_ARB_half_float_pixel */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 +#endif /* GL_ARB_half_float_vertex */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogram (GLenum target); +GLAPI void APIENTRY glResetMinmax (GLenum target); +#endif +#endif /* GL_ARB_imaging */ + +#ifndef GL_ARB_indirect_parameters +#define GL_ARB_indirect_parameters 1 +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_ARB_indirect_parameters */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); +#endif +#endif /* GL_ARB_instanced_arrays */ + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 +#endif /* GL_ARB_internalformat_query */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 +#define GL_SRGB_DECODE_ARB 0x8299 +#endif /* GL_ARB_internalformat_query2 */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +#endif /* GL_ARB_invalidate_subdata */ + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 +#endif /* GL_ARB_map_buffer_alignment */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 +#endif /* GL_ARB_map_buffer_range */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_ARB_matrix_palette */ + +#ifndef GL_ARB_multi_bind +#define GL_ARB_multi_bind 1 +#endif /* GL_ARB_multi_bind */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 +#endif /* GL_ARB_multi_draw_indirect */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); +#endif +#endif /* GL_ARB_multisample */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); +#endif +#endif /* GL_ARB_multitexture */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); +GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQueryARB (GLenum target); +GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_ARB_occlusion_query */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 +#endif /* GL_ARB_occlusion_query2 */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif /* GL_ARB_pixel_buffer_object */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_ARB_point_parameters */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif /* GL_ARB_point_sprite */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 +#endif /* GL_ARB_program_interface_query */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 +#endif /* GL_ARB_provoking_vertex */ + +#ifndef GL_ARB_query_buffer_object +#define GL_ARB_query_buffer_object 1 +#endif /* GL_ARB_query_buffer_object */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 +#endif /* GL_ARB_robust_buffer_access_behavior */ + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); +GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); +GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#endif +#endif /* GL_ARB_robustness */ + +#ifndef GL_ARB_robustness_isolation +#define GL_ARB_robustness_isolation 1 +#endif /* GL_ARB_robustness_isolation */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); +#endif +#endif /* GL_ARB_sample_shading */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 +#endif /* GL_ARB_sampler_objects */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 +#endif /* GL_ARB_seamless_cube_map */ + +#ifndef GL_ARB_seamless_cubemap_per_texture +#define GL_ARB_seamless_cubemap_per_texture 1 +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 +#endif /* GL_ARB_separate_shader_objects */ + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 +#endif /* GL_ARB_shader_atomic_counters */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 +#endif /* GL_ARB_shader_bit_encoding */ + +#ifndef GL_ARB_shader_draw_parameters +#define GL_ARB_shader_draw_parameters 1 +#endif /* GL_ARB_shader_draw_parameters */ + +#ifndef GL_ARB_shader_group_vote +#define GL_ARB_shader_group_vote 1 +#endif /* GL_ARB_shader_group_vote */ + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 +#endif /* GL_ARB_shader_image_load_store */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 +#endif /* GL_ARB_shader_image_size */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef char GLcharARB; +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); +GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); +GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); +GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); +GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); +GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); +GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); +GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); +GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); +GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif +#endif /* GL_ARB_shader_objects */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 +#endif /* GL_ARB_shader_precision */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 +#endif /* GL_ARB_shader_stencil_export */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +#endif /* GL_ARB_shader_storage_buffer_object */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 +#endif /* GL_ARB_shader_subroutine */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 +#endif /* GL_ARB_shader_texture_lod */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif /* GL_ARB_shading_language_100 */ + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 +#endif /* GL_ARB_shading_language_420pack */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#endif +#endif /* GL_ARB_shading_language_include */ + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 +#endif /* GL_ARB_shading_language_packing */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif /* GL_ARB_shadow */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif /* GL_ARB_shadow_ambient */ + +#ifndef GL_ARB_sparse_texture +#define GL_ARB_sparse_texture 1 +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_MIN_SPARSE_LEVEL_ARB 0x919B +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#endif +#endif /* GL_ARB_sparse_texture */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 +#endif /* GL_ARB_stencil_texturing */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 +#endif /* GL_ARB_sync */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 +#endif /* GL_ARB_tessellation_shader */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif /* GL_ARB_texture_border_clamp */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_ARB_texture_buffer_object */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 +#endif /* GL_ARB_texture_buffer_range */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void *img); +#endif +#endif /* GL_ARB_texture_compression */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif /* GL_ARB_texture_compression_bptc */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 +#endif /* GL_ARB_texture_compression_rgtc */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif /* GL_ARB_texture_cube_map */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#endif /* GL_ARB_texture_cube_map_array */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif /* GL_ARB_texture_env_add */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif /* GL_ARB_texture_env_combine */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif /* GL_ARB_texture_env_crossbar */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif /* GL_ARB_texture_env_dot3 */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif /* GL_ARB_texture_float */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F +#endif /* GL_ARB_texture_gather */ + +#ifndef GL_ARB_texture_mirror_clamp_to_edge +#define GL_ARB_texture_mirror_clamp_to_edge 1 +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 +#endif /* GL_ARB_texture_multisample */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 +#endif /* GL_ARB_texture_query_levels */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 +#endif /* GL_ARB_texture_query_lod */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif /* GL_ARB_texture_rectangle */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 +#endif /* GL_ARB_texture_rg */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 +#endif /* GL_ARB_texture_rgb10_a2ui */ + +#ifndef GL_ARB_texture_stencil8 +#define GL_ARB_texture_stencil8 1 +#endif /* GL_ARB_texture_stencil8 */ + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 +#endif /* GL_ARB_texture_storage */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 +#endif /* GL_ARB_texture_storage_multisample */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 +#endif /* GL_ARB_texture_swizzle */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 +#endif /* GL_ARB_texture_view */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 +#endif /* GL_ARB_timer_query */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#endif /* GL_ARB_transform_feedback2 */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 +#endif /* GL_ARB_transform_feedback3 */ + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 +#endif /* GL_ARB_transform_feedback_instanced */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); +#endif +#endif /* GL_ARB_transpose_matrix */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#endif /* GL_ARB_uniform_buffer_object */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 +#endif /* GL_ARB_vertex_array_bgra */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 +#endif /* GL_ARB_vertex_array_object */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 +#endif /* GL_ARB_vertex_attrib_64bit */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 +#endif /* GL_ARB_vertex_attrib_binding */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); +GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); +GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); +GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); +GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); +GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); +GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); +GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); +GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexBlendARB (GLint count); +#endif +#endif /* GL_ARB_vertex_blend */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef __MACOSX__ /* The OS X headers haven't caught up with Khronos yet */ +typedef long GLsizeiptrARB; +typedef long GLintptrARB; +#else +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; +#endif +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); +GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_ARB_vertex_buffer_object */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, void **pointer); +#endif +#endif /* GL_ARB_vertex_program */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); +#endif +#endif /* GL_ARB_vertex_shader */ + +#ifndef GL_ARB_vertex_type_10f_11f_11f_rev +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 +#endif /* GL_ARB_viewport_array */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); +#endif +#endif /* GL_ARB_window_pos */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD1BOESPROC) (GLbyte s); +typedef void (APIENTRYP PFNGLTEXCOORD1BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLTEXCOORD2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x); +typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); +GLAPI void APIENTRY glMultiTexCoord1bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord2bOES (GLenum texture, GLbyte s, GLbyte t); +GLAPI void APIENTRY glMultiTexCoord2bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord3bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glMultiTexCoord3bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord4bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glMultiTexCoord4bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glTexCoord1bOES (GLbyte s); +GLAPI void APIENTRY glTexCoord1bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord2bOES (GLbyte s, GLbyte t); +GLAPI void APIENTRY glTexCoord2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex2bOES (GLbyte x); +GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z); +GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); +#endif +#endif /* GL_OES_byte_coordinates */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point 1 +typedef GLint GLfixed; +#define GL_FIXED_OES 0x140C +typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); +typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth); +typedef void (APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); +typedef void (APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); +typedef void (APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width); +typedef void (APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); +typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); +typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLACCUMXOESPROC) (GLenum op, GLfixed value); +typedef void (APIENTRYP PFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +typedef void (APIENTRYP PFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); +typedef void (APIENTRYP PFNGLCOLOR3XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCOLOR4XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLEVALCOORD1XOESPROC) (GLfixed u); +typedef void (APIENTRYP PFNGLEVALCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); +typedef void (APIENTRYP PFNGLEVALCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); +typedef void (APIENTRYP PFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); +typedef void (APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLINDEXXOESPROC) (GLfixed component); +typedef void (APIENTRYP PFNGLINDEXXVOESPROC) (const GLfixed *component); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +typedef void (APIENTRYP PFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +typedef void (APIENTRYP PFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); +typedef void (APIENTRYP PFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLNORMAL3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLPASSTHROUGHXOESPROC) (GLfixed token); +typedef void (APIENTRYP PFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); +typedef void (APIENTRYP PFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); +typedef void (APIENTRYP PFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLRASTERPOS2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLRASTERPOS3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +typedef void (APIENTRYP PFNGLRASTERPOS4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +typedef void (APIENTRYP PFNGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); +typedef void (APIENTRYP PFNGLTEXCOORD1XOESPROC) (GLfixed s); +typedef void (APIENTRYP PFNGLTEXCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLTEXCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLTEXCOORD3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLTEXCOORD4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLVERTEX2XOESPROC) (GLfixed x); +typedef void (APIENTRYP PFNGLVERTEX2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLVERTEX3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLVERTEX4XVOESPROC) (const GLfixed *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref); +GLAPI void APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearDepthxOES (GLfixed depth); +GLAPI void APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation); +GLAPI void APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glDepthRangexOES (GLfixed n, GLfixed f); +GLAPI void APIENTRY glFogxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glFogxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation); +GLAPI void APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glLightModelxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glLineWidthxOES (GLfixed width); +GLAPI void APIENTRY glLoadMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glMultMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz); +GLAPI void APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glPointSizexOES (GLfixed size); +GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); +GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); +GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glAccumxOES (GLenum op, GLfixed value); +GLAPI void APIENTRY glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +GLAPI void APIENTRY glBlendColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glColor3xOES (GLfixed red, GLfixed green, GLfixed blue); +GLAPI void APIENTRY glColor3xvOES (const GLfixed *components); +GLAPI void APIENTRY glColor4xvOES (const GLfixed *components); +GLAPI void APIENTRY glConvolutionParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glConvolutionParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glEvalCoord1xOES (GLfixed u); +GLAPI void APIENTRY glEvalCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glEvalCoord2xOES (GLfixed u, GLfixed v); +GLAPI void APIENTRY glEvalCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glFeedbackBufferxOES (GLsizei n, GLenum type, const GLfixed *buffer); +GLAPI void APIENTRY glGetConvolutionParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetHistogramParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetLightxOES (GLenum light, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetMapxvOES (GLenum target, GLenum query, GLfixed *v); +GLAPI void APIENTRY glGetMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glGetPixelMapxv (GLenum map, GLint size, GLfixed *values); +GLAPI void APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexLevelParameterxvOES (GLenum target, GLint level, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glIndexxOES (GLfixed component); +GLAPI void APIENTRY glIndexxvOES (const GLfixed *component); +GLAPI void APIENTRY glLoadTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMap1xOES (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +GLAPI void APIENTRY glMap2xOES (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +GLAPI void APIENTRY glMapGrid1xOES (GLint n, GLfixed u1, GLfixed u2); +GLAPI void APIENTRY glMapGrid2xOES (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +GLAPI void APIENTRY glMultTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord1xOES (GLenum texture, GLfixed s); +GLAPI void APIENTRY glMultiTexCoord1xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord2xOES (GLenum texture, GLfixed s, GLfixed t); +GLAPI void APIENTRY glMultiTexCoord2xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord3xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glMultiTexCoord3xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord4xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glNormal3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glPassThroughxOES (GLfixed token); +GLAPI void APIENTRY glPixelMapx (GLenum map, GLint size, const GLfixed *values); +GLAPI void APIENTRY glPixelStorex (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelTransferxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelZoomxOES (GLfixed xfactor, GLfixed yfactor); +GLAPI void APIENTRY glPrioritizeTexturesxOES (GLsizei n, const GLuint *textures, const GLfixed *priorities); +GLAPI void APIENTRY glRasterPos2xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glRasterPos2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos3xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glRasterPos3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos4xOES (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +GLAPI void APIENTRY glRasterPos4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRectxOES (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +GLAPI void APIENTRY glRectxvOES (const GLfixed *v1, const GLfixed *v2); +GLAPI void APIENTRY glTexCoord1xOES (GLfixed s); +GLAPI void APIENTRY glTexCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord2xOES (GLfixed s, GLfixed t); +GLAPI void APIENTRY glTexCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord3xOES (GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glTexCoord3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord4xOES (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glTexCoord4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glVertex2xOES (GLfixed x); +GLAPI void APIENTRY glVertex2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex3xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glVertex3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex4xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glVertex4xvOES (const GLfixed *coords); +#endif +#endif /* GL_OES_fixed_point */ + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix 1 +typedef GLbitfield (APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLbitfield APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent); +#endif +#endif /* GL_OES_query_matrix */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif /* GL_OES_read_format */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 +typedef void (APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); +typedef void (APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); +typedef void (APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); +typedef void (APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearDepthfOES (GLclampf depth); +GLAPI void APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation); +GLAPI void APIENTRY glDepthRangefOES (GLclampf n, GLclampf f); +GLAPI void APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +GLAPI void APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation); +GLAPI void APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#endif +#endif /* GL_OES_single_precision */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif /* GL_3DFX_multisample */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); +#endif +#endif /* GL_3DFX_tbuffer */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D +#endif /* GL_AMD_blend_minmax_factor */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 +#endif /* GL_AMD_conservative_depth */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#endif +#endif /* GL_AMD_debug_output */ + +#ifndef GL_AMD_depth_clamp_separate +#define GL_AMD_depth_clamp_separate 1 +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#endif /* GL_AMD_depth_clamp_separate */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_AMD_draw_buffers_blend */ + +#ifndef GL_AMD_gcn_shader +#define GL_AMD_gcn_shader 1 +#endif /* GL_AMD_gcn_shader */ + +#ifndef GL_AMD_gpu_shader_int64 +#define GL_AMD_gpu_shader_int64 1 +typedef int64_t GLint64EXT; +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); +GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); +GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); +GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); +GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); +GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); +GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_AMD_gpu_shader_int64 */ + +#ifndef GL_AMD_interleaved_elements +#define GL_AMD_interleaved_elements 1 +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 +typedef void (APIENTRYP PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribParameteriAMD (GLuint index, GLenum pname, GLint param); +#endif +#endif /* GL_AMD_interleaved_elements */ + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#endif +#endif /* GL_AMD_multi_draw_indirect */ + +#ifndef GL_AMD_name_gen_delete +#define GL_AMD_name_gen_delete 1 +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_SAMPLER_OBJECT_AMD 0x9155 +typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); +typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); +typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); +GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); +GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); +#endif +#endif /* GL_AMD_name_gen_delete */ + +#ifndef GL_AMD_occlusion_query_event +#define GL_AMD_occlusion_query_event 1 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF +typedef void (APIENTRYP PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glQueryObjectParameteruiAMD (GLenum target, GLuint id, GLenum pname, GLuint param); +#endif +#endif /* GL_AMD_occlusion_query_event */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +#endif /* GL_AMD_performance_monitor */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#endif /* GL_AMD_pinned_memory */ + +#ifndef GL_AMD_query_buffer_object +#define GL_AMD_query_buffer_object 1 +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#endif /* GL_AMD_query_buffer_object */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); +#endif +#endif /* GL_AMD_sample_positions */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +#ifndef GL_AMD_shader_atomic_counter_ops +#define GL_AMD_shader_atomic_counter_ops 1 +#endif /* GL_AMD_shader_atomic_counter_ops */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 +#endif /* GL_AMD_shader_stencil_export */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 +#endif /* GL_AMD_shader_trinary_minmax */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#endif +#endif /* GL_AMD_sparse_texture */ + +#ifndef GL_AMD_stencil_operation_extended +#define GL_AMD_stencil_operation_extended 1 +#define GL_SET_AMD 0x874A +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); +#endif +#endif /* GL_AMD_stencil_operation_extended */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 +#endif /* GL_AMD_texture_texture4 */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +#ifndef GL_AMD_transform_feedback4 +#define GL_AMD_transform_feedback4 1 +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 +#endif /* GL_AMD_transform_feedback4 */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 +#endif /* GL_AMD_vertex_shader_layer */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 +typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); +GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); +#endif +#endif /* GL_AMD_vertex_shader_tessellator */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 +#endif /* GL_AMD_vertex_shader_viewport_index */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#endif /* GL_APPLE_aux_depth_stencil */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif /* GL_APPLE_client_storage */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif +#endif /* GL_APPLE_element_array */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); +#endif +#endif /* GL_APPLE_fence */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#endif /* GL_APPLE_float_pixels */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_APPLE_flush_buffer_range */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D +typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#endif +#endif /* GL_APPLE_object_purgeable */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#endif /* GL_APPLE_row_bytes */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif /* GL_APPLE_specular_vector */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_APPLE_texture_range */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif /* GL_APPLE_transform_hint */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); +#endif +#endif /* GL_APPLE_vertex_array_object */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); +#endif +#endif /* GL_APPLE_vertex_array_range */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#endif +#endif /* GL_APPLE_vertex_program_evaluators */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#define GL_YCBCR_422_APPLE 0x85B9 +#endif /* GL_APPLE_ycbcr_422 */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ATI_draw_buffers */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif +#endif /* GL_ATI_element_array */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); +#endif +#endif /* GL_ATI_envmap_bumpmap */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); +GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); +#endif +#endif /* GL_ATI_fragment_shader */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +typedef void *(APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void *APIENTRY glMapObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); +#endif +#endif /* GL_ATI_map_object_buffer */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#endif /* GL_ATI_meminfo */ + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif /* GL_ATI_pixel_format_float */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_pn_triangles */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif +#endif /* GL_ATI_separate_stencil */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif /* GL_ATI_text_fragment_shader */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif /* GL_ATI_texture_env_combine3 */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif /* GL_ATI_texture_float */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif /* GL_ATI_texture_mirror_once */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const void *pointer, GLenum usage); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_array_object */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); +GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); +GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_vertex_streams */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif /* GL_EXT_422_pixels */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#define GL_ABGR_EXT 0x8000 +#endif /* GL_EXT_abgr */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif /* GL_EXT_bgra */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); +GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); +GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); +#endif +#endif /* GL_EXT_bindable_uniform */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#endif +#endif /* GL_EXT_blend_color */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_EXT_blend_equation_separate */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_EXT_blend_func_separate */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif /* GL_EXT_blend_logic_op */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_BLEND_EQUATION_EXT 0x8009 +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); +#endif +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif /* GL_EXT_blend_subtract */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif /* GL_EXT_clip_volume_hint */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif /* GL_EXT_cmyka */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif +#endif /* GL_EXT_color_subtable */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif +#endif /* GL_EXT_compiled_vertex_array */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#endif +#endif /* GL_EXT_convolution */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); +GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); +GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); +GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_coordinate_frame */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_copy_texture */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_cull_vertex */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +typedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_EXT_debug_label */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPopGroupMarkerEXT (void); +#endif +#endif /* GL_EXT_debug_marker */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); +#endif +#endif /* GL_EXT_depth_bounds_test */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); +typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); +GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); +GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); +GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); +GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); +GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data); +GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); +GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); +GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params); +GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params); +GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string); +GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); +GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); +GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); +GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param); +GLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param); +GLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); +GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); +#endif +#endif /* GL_EXT_direct_state_access */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#endif +#endif /* GL_EXT_draw_buffers2 */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#endif +#endif /* GL_EXT_draw_range_elements */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_fog_coord */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_framebuffer_multisample */ + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_EXT_framebuffer_multisample_blit_scaled 1 +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); +#endif +#endif /* GL_EXT_framebuffer_object */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif /* GL_EXT_framebuffer_sRGB */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +#endif +#endif /* GL_EXT_geometry_shader4 */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#endif +#endif /* GL_EXT_gpu_program_parameters */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +#endif +#endif /* GL_EXT_gpu_shader4 */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogramEXT (GLenum target); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); +#endif +#endif /* GL_EXT_histogram */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif /* GL_EXT_index_array_formats */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); +#endif +#endif /* GL_EXT_index_func */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_index_material */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif /* GL_EXT_index_texture */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); +GLAPI void APIENTRY glTextureLightEXT (GLenum pname); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_light_texture */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif /* GL_EXT_misc_attribute */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#endif +#endif /* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); +#endif +#endif /* GL_EXT_multisample */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif /* GL_EXT_packed_depth_stencil */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif /* GL_EXT_packed_float */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif /* GL_EXT_packed_pixels */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, void *data); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_paletted_texture */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif /* GL_EXT_pixel_buffer_object */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_pixel_transform */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_EXT_point_parameters */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); +#endif +#endif /* GL_EXT_polygon_offset */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); +#endif +#endif /* GL_EXT_provoking_vertex */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif /* GL_EXT_rescale_normal */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_secondary_color */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); +typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); +GLAPI void APIENTRY glActiveProgramEXT (GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); +#endif +#endif /* GL_EXT_separate_shader_objects */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif /* GL_EXT_separate_specular_color */ + +#ifndef GL_EXT_shader_image_load_formatted +#define GL_EXT_shader_image_load_formatted 1 +#endif /* GL_EXT_shader_image_load_formatted */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); +#endif +#endif /* GL_EXT_shader_image_load_store */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif /* GL_EXT_shadow_funcs */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif /* GL_EXT_shared_texture_palette */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); +#endif +#endif /* GL_EXT_stencil_clear_tag */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); +#endif +#endif /* GL_EXT_stencil_two_side */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif /* GL_EXT_stencil_wrap */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_subtexture */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif /* GL_EXT_texture */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_texture3D */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#endif /* GL_EXT_texture_array */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_EXT_texture_buffer_object */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif /* GL_EXT_texture_compression_latc */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif /* GL_EXT_texture_cube_map */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif /* GL_EXT_texture_env_add */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif /* GL_EXT_texture_env_combine */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif /* GL_EXT_texture_env_dot3 */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif +#endif /* GL_EXT_texture_integer */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif /* GL_EXT_texture_lod_bias */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif +#endif /* GL_EXT_texture_object */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); +#endif +#endif /* GL_EXT_texture_perturb_normal */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_sRGB */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif /* GL_EXT_texture_shared_exponent */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#endif /* GL_EXT_texture_snorm */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif /* GL_EXT_texture_swizzle */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#define GL_TIME_ELAPSED_EXT 0x88BF +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_EXT_timer_query */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackEXT (void); +GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#endif +#endif /* GL_EXT_transform_feedback */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, void **params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint i); +GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); +GLAPI void APIENTRY glGetPointervEXT (GLenum pname, void **params); +GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#endif +#endif /* GL_EXT_vertex_array */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 +#endif /* GL_EXT_vertex_array_bgra */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); +#endif +#endif /* GL_EXT_vertex_attrib_64bit */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const void *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); +GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); +GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); +GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); +GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); +GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); +GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); +GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); +GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); +GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); +GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const void *addr); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, void **data); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +#endif +#endif /* GL_EXT_vertex_shader */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_vertex_weighting */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#endif +#endif /* GL_EXT_x11_sync_object */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); +#endif +#endif /* GL_GREMEDY_frame_terminator */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const void *string); +#endif +#endif /* GL_GREMEDY_string_marker */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif /* GL_HP_convolution_border_modes */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_HP_image_transform */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif /* GL_HP_occlusion_test */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif /* GL_HP_texture_lighting */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#define GL_CULL_VERTEX_IBM 103050 +#endif /* GL_IBM_cull_vertex */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#endif +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif /* GL_IBM_rasterpos_clip */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +typedef void (APIENTRYP PFNGLFLUSHSTATICDATAIBMPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushStaticDataIBM (GLenum target); +#endif +#endif /* GL_IBM_static_data */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean **pointer, GLint ptrstride); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#endif +#endif /* GL_IBM_vertex_array_lists */ + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_INGR_blend_func_separate */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif /* GL_INGR_color_clamp */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#define GL_INTERLACE_READ_INGR 0x8568 +#endif /* GL_INGR_interlace_read */ + +#ifndef GL_INTEL_fragment_shader_ordering +#define GL_INTEL_fragment_shader_ordering 1 +#endif /* GL_INTEL_fragment_shader_ordering */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +typedef void (APIENTRYP PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); +typedef void *(APIENTRYP PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSyncTextureINTEL (GLuint texture); +GLAPI void APIENTRY glUnmapTexture2DINTEL (GLuint texture, GLint level); +GLAPI void *APIENTRY glMapTexture2DINTEL (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#endif +#endif /* GL_INTEL_map_texture */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const void **pointer); +GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const void **pointer); +#endif +#endif /* GL_INTEL_parallel_arrays */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +typedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); +typedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); +typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); +typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); +typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); +GLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); +GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); +GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); +GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#endif +#endif /* GL_INTEL_performance_query */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif /* GL_MESAX_texture_stack */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#define GL_PACK_INVERT_MESA 0x8758 +#endif /* GL_MESA_pack_invert */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif +#endif /* GL_MESA_resize_buffers */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); +#endif +#endif /* GL_MESA_window_pos */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif /* GL_MESA_ycbcr_texture */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNVX (GLuint id); +GLAPI void APIENTRY glEndConditionalRenderNVX (void); +#endif +#endif /* GL_NVX_conditional_render */ + +#ifndef GL_NVX_gpu_memory_info +#define GL_NVX_gpu_memory_info 1 +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#endif /* GL_NVX_gpu_memory_info */ + +#ifndef GL_NV_bindless_multi_draw_indirect +#define GL_NV_bindless_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#endif +#endif /* GL_NV_bindless_multi_draw_indirect */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); +#endif +#endif /* GL_NV_bindless_texture */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +typedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GLAPI void APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif /* GL_NV_blend_square */ + +#ifndef GL_NV_compute_program5 +#define GL_NV_compute_program5 1 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#endif /* GL_NV_compute_program5 */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRenderNV (void); +#endif +#endif /* GL_NV_conditional_render */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif /* GL_NV_copy_depth_to_color */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_NV_copy_image */ + +#ifndef GL_NV_deep_texture3D +#define GL_NV_deep_texture3D 1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#endif /* GL_NV_deep_texture3D */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); +GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); +#endif +#endif /* GL_NV_depth_buffer_float */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#define GL_DEPTH_CLAMP_NV 0x864F +#endif /* GL_NV_depth_clamp */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 +typedef void (APIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#endif +#endif /* GL_NV_draw_texture */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); +#endif +#endif /* GL_NV_evaluators */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); +GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); +#endif +#endif /* GL_NV_explicit_multisample */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); +GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GLAPI void APIENTRY glFinishFenceNV (GLuint fence); +GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif /* GL_NV_float_buffer */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#endif /* GL_NV_fog_distance */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif +#endif /* GL_NV_fragment_program */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif /* GL_NV_fragment_program2 */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 +#endif /* GL_NV_fragment_program4 */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif /* GL_NV_fragment_program_option */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); +GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_NV_geometry_program4 */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#endif /* GL_NV_geometry_shader4 */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); +#endif +#endif /* GL_NV_gpu_program4 */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F +#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 +#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 +typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); +#endif +#endif /* GL_NV_gpu_program5 */ + +#ifndef GL_NV_gpu_program5_mem_extended +#define GL_NV_gpu_program5_mem_extended 1 +#endif /* GL_NV_gpu_program5_mem_extended */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 +#endif /* GL_NV_gpu_shader5 */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +typedef unsigned short GLhalfNV; +#define GL_HALF_FLOAT_NV 0x140B +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +#endif +#endif /* GL_NV_half_float */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif /* GL_NV_light_max_exponent */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#endif /* GL_NV_multisample_coverage */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif /* GL_NV_multisample_filter_hint */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_occlusion_query */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif /* GL_NV_packed_depth_stencil */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#endif +#endif /* GL_NV_parameter_buffer_object */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 +#endif /* GL_NV_parameter_buffer_object2 */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); +typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); +typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); +typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); +typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); +typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); +GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); +GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); +GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); +GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); +GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); +GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); +GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); +GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); +GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); +GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); +GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); +GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); +GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); +GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); +GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); +GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); +GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); +GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +#endif +#endif /* GL_NV_path_rendering */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); +#endif +#endif /* GL_NV_pixel_data_range */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); +#endif +#endif /* GL_NV_point_sprite */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); +GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_NV_present_video */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); +#endif +#endif /* GL_NV_primitive_restart */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_register_combiners */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); +#endif +#endif /* GL_NV_register_combiners2 */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 +#endif /* GL_NV_shader_atomic_counters */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 +#endif /* GL_NV_shader_atomic_float */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); +typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); +GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); +GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); +GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); +GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); +GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); +GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); +GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); +GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); +GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_NV_shader_buffer_load */ + +#ifndef GL_NV_shader_buffer_store +#define GL_NV_shader_buffer_store 1 +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#endif /* GL_NV_shader_buffer_store */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 +#endif /* GL_NV_shader_storage_buffer_object */ + +#ifndef GL_NV_shader_thread_group +#define GL_NV_shader_thread_group 1 +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_SM_COUNT_NV 0x933B +#endif /* GL_NV_shader_thread_group */ + +#ifndef GL_NV_shader_thread_shuffle +#define GL_NV_shader_thread_shuffle 1 +#endif /* GL_NV_shader_thread_shuffle */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#endif /* GL_NV_tessellation_program5 */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif /* GL_NV_texgen_emboss */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif /* GL_NV_texgen_reflection */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 +typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureBarrierNV (void); +#endif +#endif /* GL_NV_texture_barrier */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif /* GL_NV_texture_compression_vtc */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif /* GL_NV_texture_env_combine4 */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif /* GL_NV_texture_expand_normal */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#endif +#endif /* GL_NV_texture_multisample */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif /* GL_NV_texture_rectangle */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif /* GL_NV_texture_shader */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif /* GL_NV_texture_shader2 */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif /* GL_NV_texture_shader3 */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_LAYER_NV 0x8DAA +#define GL_NEXT_BUFFER_NV -2 +#define GL_SKIP_COMPONENTS4_NV -3 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS1_NV -6 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackNV (void); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); +GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); +GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); +GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#endif +#endif /* GL_NV_transform_feedback */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedbackNV (void); +GLAPI void APIENTRY glResumeTransformFeedbackNV (void); +GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); +#endif +#endif /* GL_NV_transform_feedback2 */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 +typedef GLintptr GLvdpauSurfaceNV; +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_WRITE_DISCARD_NV 0x88BE +typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const void *vdpDevice, const void *getProcAddress); +typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVDPAUInitNV (const void *vdpDevice, const void *getProcAddress); +GLAPI void APIENTRY glVDPAUFiniNV (void); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); +GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#endif +#endif /* GL_NV_vdpau_interop */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const void *pointer); +#endif +#endif /* GL_NV_vertex_array_range */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif /* GL_NV_vertex_array_range2 */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); +GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +#endif +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 +typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); +GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); +#endif +#endif /* GL_NV_vertex_buffer_unified_memory */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); +GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); +GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); +GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); +#endif +#endif /* GL_NV_vertex_program */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif /* GL_NV_vertex_program1_1 */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif /* GL_NV_vertex_program2 */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif /* GL_NV_vertex_program2_option */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif /* GL_NV_vertex_program3 */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_vertex_program4 */ + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture 1 +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#endif +#endif /* GL_NV_video_capture */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif /* GL_OML_interlace */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif /* GL_OML_resample */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif /* GL_OML_subsample */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); +#endif +#endif /* GL_PGI_misc_hints */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif /* GL_PGI_vertex_hints */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif /* GL_REND_screen_coordinates */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 +#endif /* GL_S3_s3tc */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_detail_texture */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); +#endif +#endif /* GL_SGIS_fog_function */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif /* GL_SGIS_generate_mipmap */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); +#endif +#endif /* GL_SGIS_multisample */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); +#endif +#endif /* GL_SGIS_pixel_texture */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif /* GL_SGIS_point_line_texgen */ + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_SGIS_point_parameters */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_sharpen_texture */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_SGIS_texture4D */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif /* GL_SGIS_texture_border_clamp */ + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif +#endif /* GL_SGIS_texture_color_mask */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif +#endif /* GL_SGIS_texture_filter4 */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif /* GL_SGIS_texture_lod */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif /* GL_SGIS_texture_select */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#define GL_ASYNC_MARKER_SGIX 0x8329 +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); +#endif +#endif /* GL_SGIX_async */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif /* GL_SGIX_async_histogram */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif /* GL_SGIX_async_pixel */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif /* GL_SGIX_calligraphic_fragment */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif /* GL_SGIX_clipmap */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif /* GL_SGIX_convolution_accuracy */ + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif /* GL_SGIX_depth_pass_instrument */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif /* GL_SGIX_depth_texture */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif +#endif /* GL_SGIX_flush_raster */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif /* GL_SGIX_fog_offset */ + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); +GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); +#endif +#endif /* GL_SGIX_fragment_lighting */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); +#endif +#endif /* GL_SGIX_framezoom */ + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const void *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const void *params); +#endif +#endif /* GL_SGIX_igloo_interface */ + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); +#endif +#endif /* GL_SGIX_instruments */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#define GL_INTERLACE_SGIX 0x8094 +#endif /* GL_SGIX_interlace */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif /* GL_SGIX_ir_instrument1 */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#define GL_LIST_PRIORITY_SGIX 0x8182 +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); +GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); +GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_list_priority */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); +#endif +#endif /* GL_SGIX_pixel_texture */ + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif /* GL_SGIX_pixel_tiles */ + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); +#endif +#endif /* GL_SGIX_polynomial_ffd */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); +#endif +#endif /* GL_SGIX_reference_plane */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif /* GL_SGIX_resample */ + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif /* GL_SGIX_scalebias_hint */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif /* GL_SGIX_shadow */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif /* GL_SGIX_shadow_ambient */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_sprite */ + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif /* GL_SGIX_subsample */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif /* GL_SGIX_texture_add_env */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif /* GL_SGIX_texture_lod_bias */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif /* GL_SGIX_texture_scale_bias */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif /* GL_SGIX_vertex_preclip */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif /* GL_SGIX_ycrcb */ + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif /* GL_SGIX_ycrcb_subsample */ + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif /* GL_SGIX_ycrcba */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif /* GL_SGI_color_matrix */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_SGI_color_table */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif /* GL_SGI_texture_color_table */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif +#endif /* GL_SUNX_constant_data */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif /* GL_SUN_convolution_border_modes */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); +#endif +#endif /* GL_SUN_global_alpha */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif +#endif /* GL_SUN_mesh_array */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif /* GL_SUN_slice_accum */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const void **pointer); +#endif +#endif /* GL_SUN_triangle_list */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif +#endif /* GL_SUN_vertex */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif /* GL_WIN_phong_shading */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif /* GL_WIN_specular_fog */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/SDL/include/SDL/SDL_opengles.h b/thirdparty/SDL/include/SDL/SDL_opengles.h new file mode 100644 index 00000000..8511b960 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles.h + * + * This is a simple file to encapsulate the OpenGL ES 1.X API headers. + */ +#include "SDL_config.h" + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif diff --git a/thirdparty/SDL/include/SDL/SDL_opengles2.h b/thirdparty/SDL/include/SDL/SDL_opengles2.h new file mode 100644 index 00000000..172fcb3f --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles2.h @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles2.h + * + * This is a simple file to encapsulate the OpenGL ES 2.0 API headers. + */ +#include "SDL_config.h" + +#if !defined(_MSC_VER) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#include +#endif + +#else /* _MSC_VER */ + +/* OpenGL ES2 headers for Visual Studio */ +#include "SDL_opengles2_khrplatform.h" +#include "SDL_opengles2_gl2platform.h" +#include "SDL_opengles2_gl2.h" +#include "SDL_opengles2_gl2ext.h" + +#endif /* _MSC_VER */ + +#ifndef APIENTRY +#define APIENTRY GL_APIENTRY +#endif diff --git a/thirdparty/SDL/include/SDL/SDL_opengles2_gl2.h b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2.h new file mode 100644 index 00000000..c62fb0a5 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */ + +/*#include */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ + diff --git a/thirdparty/SDL/include/SDL/SDL_opengles2_gl2ext.h b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2ext.h new file mode 100644 index 00000000..e8ca8b13 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2ext.h @@ -0,0 +1,2050 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ + +/* $Revision: 22801 $ on $Date:: 2013-08-21 03:20:48 -0700 #$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#ifndef GL_APIENTRYP +# define GL_APIENTRYP GL_APIENTRY* +#endif + +/* New types shared by several extensions */ + +#ifndef __gl3_h_ +/* These are defined with respect to in the + * Apple extension spec, but they are also used by non-APPLE + * extensions, and in the Khronos header we use the Khronos + * portable types in khrplatform.h, which must be defined. + */ +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + + +/*------------------------------------------------------------------------* + * OES extension tokens + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif + +/* GL_OES_depth_texture */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +/* GLeglImageOES defined in GL_OES_EGL_image already. */ +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_UNSIGNED_INT 0x1405 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +/* reuse GL_DEPTH_COMPONENT24_OES */ +/* reuse GL_DEPTH24_STENCIL8_OES */ +/* reuse GL_DEPTH_COMPONENT32_OES */ +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +/* reuse GL_RGB8_OES */ +/* reuse GL_RGBA8_OES */ +/* reuse GL_RGB10_EXT */ +/* reuse GL_RGB10_A2_EXT */ +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#endif + +/* GL_OES_texture_float */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_HALF_FLOAT_OES 0x8D61 +#endif + +/* GL_OES_texture_half_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_npot */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#endif + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif + +/*------------------------------------------------------------------------* + * KHR extension tokens + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_QUERY_KHR 0x82E3 +/* PROGRAM_PIPELINE only in GL */ +#define GL_SAMPLER_KHR 0x82E6 +/* DISPLAY_LIST only in GL */ +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif + +/* GL_AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_Z400_BINARY_AMD 0x8740 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#endif + +/*------------------------------------------------------------------------* + * APPLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +/* No new tokens introduced by this extension. */ + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync + +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif + +/*------------------------------------------------------------------------* + * ARM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif + +/* GL_ARM_rgba8 */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#endif + +/* GL_EXT_debug_marker */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#endif + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#endif + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */ +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#endif + +/* GL_EXT_multi_draw_arrays */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +/* reuse GL_NO_ERROR */ +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif + +/* GL_EXT_shader_texture_lod */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif + +/* GL_EXT_sRGB_write_control */ +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif + +/* GL_EXT_texture_sRGB_decode */ +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +/* reuse GL_RGBA16F_EXT */ +/* reuse GL_RGB16F_EXT */ +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_BGRA8_EXT 0x93A1 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif + +/*------------------------------------------------------------------------* + * DMP extension tokens + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_SHADER_BINARY_DMP 0x9250 +#endif + +/*------------------------------------------------------------------------* + * FJ extension tokens + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_SGX_BINARY_IMG 0x8C0A +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#endif + +/* GL_NV_draw_instanced */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +#endif + +/* GL_NV_generate_mipmap_sRGB */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_READ_BUFFER_NV 0x0C02 +#endif + +/* GL_NV_read_buffer_front */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif + +/* GL_NV_texture_compression_s3tc_update */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_npot_2D_mipmap */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +#endif + +/* GL_QCOM_extended_get2 */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------* + * OES extension functions + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#endif + +/* GL_OES_depth_texture */ +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif + +/* GL_OES_fbo_render_mipmap */ +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif + +/* GL_OES_fragment_precision_high */ +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid **params); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid **params); +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif + +/* GL_OES_texture_float */ +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif + +/* GL_OES_texture_float_linear */ +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#endif + +/* GL_OES_texture_half_float_linear */ +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif + +/* GL_OES_texture_npot */ +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#endif + +/* GL_OES_vertex_half_float */ +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#endif + +/*------------------------------------------------------------------------* + * KHR extension functions + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, GLvoid **params); +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif + + +/*------------------------------------------------------------------------* + * AMD extension functions + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#endif + +/* AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#endif + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif + +/*------------------------------------------------------------------------* + * APPLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#endif + +/*------------------------------------------------------------------------* + * ARM extension functions + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#endif + +/* GL_ARM_rgba8 */ +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif + +/*------------------------------------------------------------------------* + * EXT extension functions + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +/* GL_EXT_debug_marker */ +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#endif + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#endif /* GL_EXT_draw_buffers */ + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +/* All entry points also exist in GL_EXT_disjoint_timer_query */ +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#endif + +/* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#endif + +/*------------------------------------------------------------------------* + * DMP extension functions + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#endif + +/*------------------------------------------------------------------------* + * FJ extension functions + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension functions + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/*------------------------------------------------------------------------* + * NV extension functions + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#endif + +/* GL_NV_draw_instanced */ +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +/* GL_NV_generate_mipmap_sRGB */ +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#endif + +/* GL_NV_read_buffer_front */ +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif + +/* GL_NV_read_depth */ +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif + +/* GL_NV_read_depth_stencil */ +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif + +/* GL_NV_read_stencil */ +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#endif + +/* GL_NV_texture_compression_s3tc_update */ +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif + +/* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif + +/*------------------------------------------------------------------------* + * QCOM extension functions + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#endif + +/* GL_QCOM_driver_control */ +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#endif + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); +#endif + +/* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2ext_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_opengles2_gl2platform.h b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2platform.h new file mode 100644 index 00000000..c325686f --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles2_gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +/*#include */ + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_opengles2_khrplatform.h b/thirdparty/SDL/include/SDL/SDL_opengles2_khrplatform.h new file mode 100644 index 00000000..c9e6f17d --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_opengles2_khrplatform.h @@ -0,0 +1,282 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_pixels.h b/thirdparty/SDL/include/SDL/SDL_pixels.h new file mode 100644 index 00000000..5d2c0c89 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_pixels.h @@ -0,0 +1,644 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_pixels.h + * + * Header for the enumerated pixel format definitions. + */ + +#ifndef SDL_pixels_h_ +#define SDL_pixels_h_ + +#include "SDL_stdinc.h" +#include "SDL_endian.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Transparency definitions + * + * These define alpha as the opacity of a surface. + */ +/* @{ */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 +/* @} */ + +/** Pixel type. */ +typedef enum +{ + SDL_PIXELTYPE_UNKNOWN, + SDL_PIXELTYPE_INDEX1, + SDL_PIXELTYPE_INDEX4, + SDL_PIXELTYPE_INDEX8, + SDL_PIXELTYPE_PACKED8, + SDL_PIXELTYPE_PACKED16, + SDL_PIXELTYPE_PACKED32, + SDL_PIXELTYPE_ARRAYU8, + SDL_PIXELTYPE_ARRAYU16, + SDL_PIXELTYPE_ARRAYU32, + SDL_PIXELTYPE_ARRAYF16, + SDL_PIXELTYPE_ARRAYF32 +} SDL_PixelType; + +/** Bitmap pixel order, high bit -> low bit. */ +typedef enum +{ + SDL_BITMAPORDER_NONE, + SDL_BITMAPORDER_4321, + SDL_BITMAPORDER_1234 +} SDL_BitmapOrder; + +/** Packed component order, high bit -> low bit. */ +typedef enum +{ + SDL_PACKEDORDER_NONE, + SDL_PACKEDORDER_XRGB, + SDL_PACKEDORDER_RGBX, + SDL_PACKEDORDER_ARGB, + SDL_PACKEDORDER_RGBA, + SDL_PACKEDORDER_XBGR, + SDL_PACKEDORDER_BGRX, + SDL_PACKEDORDER_ABGR, + SDL_PACKEDORDER_BGRA +} SDL_PackedOrder; + +/** Array component order, low byte -> high byte. */ +/* !!! FIXME: in 2.1, make these not overlap differently with + !!! FIXME: SDL_PACKEDORDER_*, so we can simplify SDL_ISPIXELFORMAT_ALPHA */ +typedef enum +{ + SDL_ARRAYORDER_NONE, + SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_RGBA, + SDL_ARRAYORDER_ARGB, + SDL_ARRAYORDER_BGR, + SDL_ARRAYORDER_BGRA, + SDL_ARRAYORDER_ABGR +} SDL_ArrayOrder; + +/** Packed component layout. */ +typedef enum +{ + SDL_PACKEDLAYOUT_NONE, + SDL_PACKEDLAYOUT_332, + SDL_PACKEDLAYOUT_4444, + SDL_PACKEDLAYOUT_1555, + SDL_PACKEDLAYOUT_5551, + SDL_PACKEDLAYOUT_565, + SDL_PACKEDLAYOUT_8888, + SDL_PACKEDLAYOUT_2101010, + SDL_PACKEDLAYOUT_1010102 +} SDL_PackedLayout; + +#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) + +#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ + ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ + ((bits) << 8) | ((bytes) << 0)) + +#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) +#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) +#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) +#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) +#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF) +#define SDL_BYTESPERPIXEL(X) \ + (SDL_ISPIXELFORMAT_FOURCC(X) ? \ + ((((X) == SDL_PIXELFORMAT_YUY2) || \ + ((X) == SDL_PIXELFORMAT_UYVY) || \ + ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF)) + +#define SDL_ISPIXELFORMAT_INDEXED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) + +#define SDL_ISPIXELFORMAT_PACKED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32))) + +#define SDL_ISPIXELFORMAT_ARRAY(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32))) + +#define SDL_ISPIXELFORMAT_ALPHA(format) \ + ((SDL_ISPIXELFORMAT_PACKED(format) && \ + ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \ + (SDL_ISPIXELFORMAT_ARRAY(format) && \ + ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA)))) + +/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ +#define SDL_ISPIXELFORMAT_FOURCC(format) \ + ((format) && (SDL_PIXELFLAG(format) != 1)) + +/* Note: If you modify this list, update SDL_GetPixelFormatName() */ +typedef enum +{ + SDL_PIXELFORMAT_UNKNOWN, + SDL_PIXELFORMAT_INDEX1LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX1MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX4LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX4MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX8 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), + SDL_PIXELFORMAT_RGB332 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_332, 8, 1), + SDL_PIXELFORMAT_XRGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_RGB444 = SDL_PIXELFORMAT_XRGB4444, + SDL_PIXELFORMAT_XBGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_BGR444 = SDL_PIXELFORMAT_XBGR4444, + SDL_PIXELFORMAT_XRGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_RGB555 = SDL_PIXELFORMAT_XRGB1555, + SDL_PIXELFORMAT_XBGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_BGR555 = SDL_PIXELFORMAT_XBGR1555, + SDL_PIXELFORMAT_ARGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_RGBA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ABGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_BGRA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ARGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_RGBA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_ABGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_BGRA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_RGB565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_BGR565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_RGB24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, + 24, 3), + SDL_PIXELFORMAT_BGR24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, + 24, 3), + SDL_PIXELFORMAT_XRGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888, + SDL_PIXELFORMAT_RGBX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_XBGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGR888 = SDL_PIXELFORMAT_XBGR8888, + SDL_PIXELFORMAT_BGRX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_ARGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_RGBA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ABGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_BGRA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ARGB2101010 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_2101010, 32, 4), + + /* Aliases for RGBA byte arrays of color data, for the current platform */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, +#else + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, +#endif + + SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), + SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ + SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), + SDL_PIXELFORMAT_YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), + SDL_PIXELFORMAT_UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), + SDL_PIXELFORMAT_YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), + SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), + SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'), + SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */ + SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') +} SDL_PixelFormatEnum; + +/** + * The bits of this structure can be directly reinterpreted as an integer-packed + * color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 + * on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). + */ +typedef struct SDL_Color +{ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} SDL_Color; +#define SDL_Colour SDL_Color + +typedef struct SDL_Palette +{ + int ncolors; + SDL_Color *colors; + Uint32 version; + int refcount; +} SDL_Palette; + +/** + * \note Everything in the pixel format structure is read-only. + */ +typedef struct SDL_PixelFormat +{ + Uint32 format; + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 padding[2]; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + int refcount; + struct SDL_PixelFormat *next; +} SDL_PixelFormat; + +/** + * Get the human readable name of a pixel format. + * + * \param format the pixel format to query + * \returns the human readable name of the specified pixel format or + * `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); + +/** + * Convert one of the enumerated pixel formats to a bpp value and RGBA masks. + * + * \param format one of the SDL_PixelFormatEnum values + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask a pointer filled in with the red mask for the format + * \param Gmask a pointer filled in with the green mask for the format + * \param Bmask a pointer filled in with the blue mask for the format + * \param Amask a pointer filled in with the alpha mask for the format + * \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't + * possible; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MasksToPixelFormatEnum + */ +extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, + int *bpp, + Uint32 * Rmask, + Uint32 * Gmask, + Uint32 * Bmask, + Uint32 * Amask); + +/** + * Convert a bpp value and RGBA masks to an enumerated pixel format. + * + * This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't + * possible. + * + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask the red mask for the format + * \param Gmask the green mask for the format + * \param Bmask the blue mask for the format + * \param Amask the alpha mask for the format + * \returns one of the SDL_PixelFormatEnum values + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PixelFormatEnumToMasks + */ +extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/** + * Create an SDL_PixelFormat structure corresponding to a pixel format. + * + * Returned structure may come from a shared global cache (i.e. not newly + * allocated), and hence should not be modified, especially the palette. Weird + * errors such as `Blit combination not supported` may occur. + * + * \param pixel_format one of the SDL_PixelFormatEnum values + * \returns the new SDL_PixelFormat structure or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeFormat + */ +extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); + +/** + * Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). + * + * \param format the SDL_PixelFormat structure to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + */ +extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); + +/** + * Create a palette structure with the specified number of color entries. + * + * The palette entries are initialized to white. + * + * \param ncolors represents the number of color entries in the color palette + * \returns a new SDL_Palette structure on success or NULL on failure (e.g. if + * there wasn't enough memory); call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreePalette + */ +extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); + +/** + * Set the palette for a pixel format structure. + * + * \param format the SDL_PixelFormat structure that will use the palette + * \param palette the SDL_Palette structure that will be used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_FreePalette + */ +extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, + SDL_Palette *palette); + +/** + * Set a range of colors in a palette. + * + * \param palette the SDL_Palette structure to modify + * \param colors an array of SDL_Color structures to copy into the palette + * \param firstcolor the index of the first palette entry to modify + * \param ncolors the number of entries to modify + * \returns 0 on success or a negative error code if not all of the colors + * could be set; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, + const SDL_Color * colors, + int firstcolor, int ncolors); + +/** + * Free a palette created with SDL_AllocPalette(). + * + * \param palette the SDL_Palette structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + */ +extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); + +/** + * Map an RGB triple to an opaque pixel value for a given pixel format. + * + * This function maps the RGB color value to the specified pixel format and + * returns the pixel value best approximating the given RGB color value for + * the given pixel format. + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the specified pixel format has an alpha component it will be returned as + * all 1 bits (fully opaque). + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the pixel format + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGBA + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b); + +/** + * Map an RGBA quadruple to a pixel value for a given pixel format. + * + * This function maps the RGBA color value to the specified pixel format and + * returns the pixel value best approximating the given RGBA color value for + * the given pixel format. + * + * If the specified pixel format has no alpha component the alpha value will + * be ignored (as it will be in formats with a palette). + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \param a the alpha component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGB + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * Get RGB values from a pixel in the specified format. + * + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGBA + * \sa SDL_MapRGB + * \sa SDL_MapRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b); + +/** + * Get RGBA values from a pixel in the specified format. + * + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * If the surface has no alpha component, the alpha will be returned as 0xff + * (100% opaque). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * \param a a pointer filled in with the alpha component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_MapRGB + * \sa SDL_MapRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * Calculate a 256 entry gamma ramp for a gamma value. + * + * \param gamma a gamma value where 0.0 is black and 1.0 is identity + * \param ramp an array of 256 values filled in with the gamma ramp + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_pixels_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_platform.h b/thirdparty/SDL/include/SDL/SDL_platform.h new file mode 100644 index 00000000..f1f6f8b0 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_platform.h @@ -0,0 +1,256 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_platform.h + * + * Try to get a standard set of platform defines. + */ + +#ifndef SDL_platform_h_ +#define SDL_platform_h_ + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__HAIKU__) +#undef __HAIKU__ +#define __HAIKU__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if (defined(linux) || defined(__linux) || defined(__linux__)) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(ANDROID) || defined(__ANDROID__) +#undef __ANDROID__ +#undef __LINUX__ /* do we need to do this? */ +#define __ANDROID__ 1 +#endif +#if defined(__NGAGE__) +#undef __NGAGE__ +#define __NGAGE__ 1 +#endif + +#if defined(__APPLE__) +/* lets us know what version of Mac OS X we're compiling on */ +#include +#include + +/* Fix building with older SDKs that don't define these + See this for more information: + https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets +*/ +#ifndef TARGET_OS_MACCATALYST +#define TARGET_OS_MACCATALYST 0 +#endif +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS 0 +#endif +#ifndef TARGET_OS_IPHONE +#define TARGET_OS_IPHONE 0 +#endif +#ifndef TARGET_OS_TV +#define TARGET_OS_TV 0 +#endif +#ifndef TARGET_OS_SIMULATOR +#define TARGET_OS_SIMULATOR 0 +#endif + +#if TARGET_OS_TV +#undef __TVOS__ +#define __TVOS__ 1 +#endif +#if TARGET_OS_IPHONE +/* if compiling for iOS */ +#undef __IPHONEOS__ +#define __IPHONEOS__ 1 +#undef __MACOSX__ +#else +/* if not compiling for iOS */ +#undef __MACOSX__ +#define __MACOSX__ 1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +# error SDL for Mac OS X only supports deploying on 10.7 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1070 */ +#endif /* TARGET_OS_IPHONE */ +#endif /* defined(__APPLE__) */ + +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) || defined(__EMX__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__sun) && defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +/* Try to find out if we're compiling for WinRT, GDK or non-WinRT/GDK */ +#if defined(_MSC_VER) && defined(__has_include) +#if __has_include() +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */ +#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */ +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +#if HAVE_WINAPIFAMILY_H +#include +#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) +#else +#define WINAPI_FAMILY_WINRT 0 +#endif /* HAVE_WINAPIFAMILY_H */ + +#if WINAPI_FAMILY_WINRT +#undef __WINRT__ +#define __WINRT__ 1 +#elif defined(_GAMING_DESKTOP) /* GDK project configuration always defines _GAMING_XXX */ +#undef __WINGDK__ +#define __WINGDK__ 1 +#elif defined(_GAMING_XBOX_XBOXONE) +#undef __XBOXONE__ +#define __XBOXONE__ 1 +#elif defined(_GAMING_XBOX_SCARLETT) +#undef __XBOXSERIES__ +#define __XBOXSERIES__ 1 +#else +#undef __WINDOWS__ +#define __WINDOWS__ 1 +#endif +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + +#if defined(__WINDOWS__) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +/* This is to support generic "any GDK" separate from a platform-specific GDK */ +#if defined(__WINGDK__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) +#undef __GDK__ +#define __GDK__ 1 +#endif +#if defined(__PSP__) +#undef __PSP__ +#define __PSP__ 1 +#endif +#if defined(PS2) +#define __PS2__ 1 +#endif + +/* The NACL compiler defines __native_client__ and __pnacl__ + * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi + */ +#if defined(__native_client__) +#undef __LINUX__ +#undef __NACL__ +#define __NACL__ 1 +#endif +#if defined(__pnacl__) +#undef __LINUX__ +#undef __PNACL__ +#define __PNACL__ 1 +/* PNACL with newlib supports static linking only */ +#define __SDL_NOGETPROCADDR__ +#endif + +#if defined(__vita__) +#define __VITA__ 1 +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the name of the platform. + * + * Here are the names returned for some (but not all) supported platforms: + * + * - "Windows" + * - "Mac OS X" + * - "Linux" + * - "iOS" + * - "Android" + * + * \returns the name of the platform. If the correct platform name is not + * available, returns a string beginning with the text "Unknown". + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_platform_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_power.h b/thirdparty/SDL/include/SDL/SDL_power.h new file mode 100644 index 00000000..ecb3f4b0 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_power.h @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_power_h_ +#define SDL_power_h_ + +/** + * \file SDL_power.h + * + * Header for the SDL power management routines. + */ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The basic state for the system's power supply. + */ +typedef enum +{ + SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ + SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ + SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ + SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ + SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ +} SDL_PowerState; + + +/** + * Get the current power supply details. + * + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. + * + * Battery status can change at any time; if you are concerned with power + * state, you should call this function frequently, and perhaps ignore changes + * until they seem to be stable for a few seconds. + * + * It's possible a platform can only report battery percentage or time left + * but not both. + * + * \param secs seconds of battery life left, you can pass a NULL here if you + * don't care, will return -1 if we can't determine a value, or + * we're not running on a battery + * \param pct percentage of battery life left, between 0 and 100, you can pass + * a NULL here if you don't care, will return -1 if we can't + * determine a value, or we're not running on a battery + * \returns an SDL_PowerState enum representing the current battery state. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_power_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_quit.h b/thirdparty/SDL/include/SDL/SDL_quit.h new file mode 100644 index 00000000..4090f7f1 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_quit.h @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_quit.h + * + * Include file for SDL quit event handling. + */ + +#ifndef SDL_quit_h_ +#define SDL_quit_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/** + * \file SDL_quit.h + * + * An ::SDL_QUIT event is generated when the user tries to close the application + * window. If it is ignored or filtered out, the window will remain open. + * If it is not ignored or filtered, it is queued normally and the window + * is allowed to close. When the window is closed, screen updates will + * complete, but have no effect. + * + * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) + * and SIGTERM (system termination request), if handlers do not already + * exist, that generate ::SDL_QUIT events as well. There is no way + * to determine the cause of an ::SDL_QUIT event, but setting a signal + * handler in your application will override the default generation of + * quit events for that signal. + * + * \sa SDL_Quit() + */ + +/* There are no functions directly affecting the quit event */ + +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0)) + +#endif /* SDL_quit_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_rect.h b/thirdparty/SDL/include/SDL/SDL_rect.h new file mode 100644 index 00000000..6c641c58 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_rect.h @@ -0,0 +1,376 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rect.h + * + * Header file for SDL_rect definition and management functions. + */ + +#ifndef SDL_rect_h_ +#define SDL_rect_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The structure that defines a point (integer) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_Point +{ + int x; + int y; +} SDL_Point; + +/** + * The structure that defines a point (floating point) + * + * \sa SDL_EncloseFPoints + * \sa SDL_PointInFRect + */ +typedef struct SDL_FPoint +{ + float x; + float y; +} SDL_FPoint; + + +/** + * A rectangle, with the origin at the upper left (integer). + * + * \sa SDL_RectEmpty + * \sa SDL_RectEquals + * \sa SDL_HasIntersection + * \sa SDL_IntersectRect + * \sa SDL_IntersectRectAndLine + * \sa SDL_UnionRect + * \sa SDL_EnclosePoints + */ +typedef struct SDL_Rect +{ + int x, y; + int w, h; +} SDL_Rect; + + +/** + * A rectangle, with the origin at the upper left (floating point). + * + * \sa SDL_FRectEmpty + * \sa SDL_FRectEquals + * \sa SDL_FRectEqualsEpsilon + * \sa SDL_HasIntersectionF + * \sa SDL_IntersectFRect + * \sa SDL_IntersectFRectAndLine + * \sa SDL_UnionFRect + * \sa SDL_EncloseFPoints + * \sa SDL_PointInFRect + */ +typedef struct SDL_FRect +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + + +/** + * Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) +{ + return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) +{ + return (a && b && (a->x == b->x) && (a->y == b->y) && + (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Determine whether two rectangles intersect. + * + * If either pointer is NULL the function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_IntersectRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, + const SDL_Rect * B); + +/** + * Calculate the intersection of two rectangles. + * + * If `result` is NULL then this function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the intersection of + * rectangles `A` and `B` + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasIntersection + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate the union of two rectangles. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the union of rectangles + * `A` and `B` + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate a minimal rectangle enclosing a set of points. + * + * If `clip` is not NULL then only points inside of the clipping rectangle are + * considered. + * + * \param points an array of SDL_Point structures representing points to be + * enclosed + * \param count the number of structures in the `points` array + * \param clip an SDL_Rect used for clipping or NULL to enclose all points + * \param result an SDL_Rect structure filled in with the minimal enclosing + * rectangle + * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + * points were outside of the clipping rectangle. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, + int count, + const SDL_Rect * clip, + SDL_Rect * result); + +/** + * Calculate the intersection of a rectangle and line segment. + * + * This function is used to clip a line segment to a rectangle. A line segment + * contained entirely within the rectangle or that does not intersect will + * remain unchanged. A line segment that crosses the rectangle at either or + * both ends will be clipped to the boundary of the rectangle and the new + * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + * + * \param rect an SDL_Rect structure representing the rectangle to intersect + * \param X1 a pointer to the starting X-coordinate of the line + * \param Y1 a pointer to the starting Y-coordinate of the line + * \param X2 a pointer to the ending X-coordinate of the line + * \param Y2 a pointer to the ending Y-coordinate of the line + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + + +/* SDL_FRect versions... */ + +/** + * Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) +{ + return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal, within some given epsilon. + * + * \since This function is available since SDL 2.0.22. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon) +{ + return (a && b && ((a == b) || + ((SDL_fabsf(a->x - b->x) <= epsilon) && + (SDL_fabsf(a->y - b->y) <= epsilon) && + (SDL_fabsf(a->w - b->w) <= epsilon) && + (SDL_fabsf(a->h - b->h) <= epsilon)))) + ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal, using a default epsilon. + * + * \since This function is available since SDL 2.0.22. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b) +{ + return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON); +} + +/** + * Determine whether two rectangles intersect with float precision. + * + * If either pointer is NULL the function will return SDL_FALSE. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_IntersectRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersectionF(const SDL_FRect * A, + const SDL_FRect * B); + +/** + * Calculate the intersection of two rectangles with float precision. + * + * If `result` is NULL then this function will return SDL_FALSE. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \param result an SDL_FRect structure filled in with the intersection of + * rectangles `A` and `B` + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_HasIntersectionF + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRect(const SDL_FRect * A, + const SDL_FRect * B, + SDL_FRect * result); + +/** + * Calculate the union of two rectangles with float precision. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \param result an SDL_FRect structure filled in with the union of rectangles + * `A` and `B` + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC void SDLCALL SDL_UnionFRect(const SDL_FRect * A, + const SDL_FRect * B, + SDL_FRect * result); + +/** + * Calculate a minimal rectangle enclosing a set of points with float + * precision. + * + * If `clip` is not NULL then only points inside of the clipping rectangle are + * considered. + * + * \param points an array of SDL_FPoint structures representing points to be + * enclosed + * \param count the number of structures in the `points` array + * \param clip an SDL_FRect used for clipping or NULL to enclose all points + * \param result an SDL_FRect structure filled in with the minimal enclosing + * rectangle + * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + * points were outside of the clipping rectangle. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EncloseFPoints(const SDL_FPoint * points, + int count, + const SDL_FRect * clip, + SDL_FRect * result); + +/** + * Calculate the intersection of a rectangle and line segment with float + * precision. + * + * This function is used to clip a line segment to a rectangle. A line segment + * contained entirely within the rectangle or that does not intersect will + * remain unchanged. A line segment that crosses the rectangle at either or + * both ends will be clipped to the boundary of the rectangle and the new + * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + * + * \param rect an SDL_FRect structure representing the rectangle to intersect + * \param X1 a pointer to the starting X-coordinate of the line + * \param Y1 a pointer to the starting Y-coordinate of the line + * \param X2 a pointer to the ending X-coordinate of the line + * \param Y2 a pointer to the ending Y-coordinate of the line + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRectAndLine(const SDL_FRect * + rect, float *X1, + float *Y1, float *X2, + float *Y2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rect_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_render.h b/thirdparty/SDL/include/SDL/SDL_render.h new file mode 100644 index 00000000..30ef3d63 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_render.h @@ -0,0 +1,1916 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_render.h + * + * Header file for SDL 2D rendering functions. + * + * This API supports the following features: + * * single pixel points + * * single pixel lines + * * filled rectangles + * * texture images + * + * The primitives may be drawn in opaque, blended, or additive modes. + * + * The texture images may be drawn in opaque, blended, or additive modes. + * They can have an additional color tint or alpha modulation applied to + * them, and may also be stretched with linear interpolation. + * + * This API is designed to accelerate simple 2D operations. You may + * want more functionality such as polygons and particle effects and + * in that case you should use SDL's OpenGL/Direct3D support or one + * of the many good 3D engines. + * + * These functions must be called from the main thread. + * See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995 + */ + +#ifndef SDL_render_h_ +#define SDL_render_h_ + +#include "SDL_stdinc.h" +#include "SDL_rect.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Flags used when creating a rendering context + */ +typedef enum +{ + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ +} SDL_RendererFlags; + +/** + * Information on the capabilities of a render driver or context. + */ +typedef struct SDL_RendererInfo +{ + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximum texture width */ + int max_texture_height; /**< The maximum texture height */ +} SDL_RendererInfo; + +/** + * Vertex structure + */ +typedef struct SDL_Vertex +{ + SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */ + SDL_Color color; /**< Vertex color */ + SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ +} SDL_Vertex; + +/** + * The scaling mode for a texture. + */ +typedef enum +{ + SDL_ScaleModeNearest, /**< nearest pixel sampling */ + SDL_ScaleModeLinear, /**< linear filtering */ + SDL_ScaleModeBest /**< anisotropic filtering */ +} SDL_ScaleMode; + +/** + * The access pattern allowed for a texture. + */ +typedef enum +{ + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ +} SDL_TextureAccess; + +/** + * The texture channel modulation used in SDL_RenderCopy(). + */ +typedef enum +{ + SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ + SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ +} SDL_TextureModulate; + +/** + * Flip constants for SDL_RenderCopyEx + */ +typedef enum +{ + SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ + SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ + SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ +} SDL_RendererFlip; + +/** + * A structure representing rendering state + */ +struct SDL_Renderer; +typedef struct SDL_Renderer SDL_Renderer; + +/** + * An efficient driver-specific representation of pixel data + */ +struct SDL_Texture; +typedef struct SDL_Texture SDL_Texture; + +/* Function prototypes */ + +/** + * Get the number of 2D rendering drivers available for the current display. + * + * A render driver is a set of code that handles rendering and texture + * management on a particular display. Normally there is only one, but some + * drivers may have several available with different capabilities. + * + * There may be none if SDL was compiled without render support. + * + * \returns a number >= 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetRenderDriverInfo + */ +extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); + +/** + * Get info about a specific 2D rendering driver for the current display. + * + * \param index the index of the driver to query information about + * \param info an SDL_RendererInfo structure to be filled with information on + * the rendering driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetNumRenderDrivers + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, + SDL_RendererInfo * info); + +/** + * Create a window and default renderer. + * + * \param width the width of the window + * \param height the height of the window + * \param window_flags the flags used to create the window (see + * SDL_CreateWindow()) + * \param window a pointer filled with the window, or NULL on error + * \param renderer a pointer filled with the renderer, or NULL on error + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindow + */ +extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( + int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer); + + +/** + * Create a 2D rendering context for a window. + * + * \param window the window where rendering is displayed + * \param index the index of the rendering driver to initialize, or -1 to + * initialize the first one supporting the requested flags + * \param flags 0, or one or more SDL_RendererFlags OR'd together + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSoftwareRenderer + * \sa SDL_DestroyRenderer + * \sa SDL_GetNumRenderDrivers + * \sa SDL_GetRendererInfo + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, + int index, Uint32 flags); + +/** + * Create a 2D software rendering context for a surface. + * + * Two other API which can be used to create SDL_Renderer: + * SDL_CreateRenderer() and SDL_CreateWindowAndRenderer(). These can _also_ + * create a software renderer, but they are intended to be used with an + * SDL_Window as the final destination and not an SDL_Surface. + * + * \param surface the SDL_Surface structure representing the surface where + * rendering is done + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindowRenderer + * \sa SDL_DestroyRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); + +/** + * Get the renderer associated with a window. + * + * \param window the window to query + * \returns the rendering context on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); + +/** + * Get the window associated with a renderer. + * + * \param renderer the renderer to query + * \returns the window on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer); + +/** + * Get information about a rendering context. + * + * \param renderer the rendering context + * \param info an SDL_RendererInfo structure filled with information about the + * current renderer + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, + SDL_RendererInfo * info); + +/** + * Get the output size in pixels of a rendering context. + * + * Due to high-dpi displays, you might end up with a rendering context that + * has more pixels than the window that contains it, so use this instead of + * SDL_GetWindowSize() to decide how much drawing area you have. + * + * \param renderer the rendering context + * \param w an int filled with the width + * \param h an int filled with the height + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, + int *w, int *h); + +/** + * Create a texture for a rendering context. + * + * You can set the texture scaling method by setting + * `SDL_HINT_RENDER_SCALE_QUALITY` before creating the texture. + * + * \param renderer the rendering context + * \param format one of the enumerated values in SDL_PixelFormatEnum + * \param access one of the enumerated values in SDL_TextureAccess + * \param w the width of the texture in pixels + * \param h the height of the texture in pixels + * \returns a pointer to the created texture or NULL if no rendering context + * was active, the format was unsupported, or the width or height + * were out of range; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTextureFromSurface + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + * \sa SDL_UpdateTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, + Uint32 format, + int access, int w, + int h); + +/** + * Create a texture from an existing surface. + * + * The surface is not modified or freed by this function. + * + * The SDL_TextureAccess hint for the created texture is + * `SDL_TEXTUREACCESS_STATIC`. + * + * The pixel format of the created texture may be different from the pixel + * format of the surface. Use SDL_QueryTexture() to query the pixel format of + * the texture. + * + * \param renderer the rendering context + * \param surface the SDL_Surface structure containing pixel data used to fill + * the texture + * \returns the created texture or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); + +/** + * Query the attributes of a texture. + * + * \param texture the texture to query + * \param format a pointer filled in with the raw format of the texture; the + * actual format may differ, but pixel transfers will use this + * format (one of the SDL_PixelFormatEnum values). This argument + * can be NULL if you don't need this information. + * \param access a pointer filled in with the actual access to the texture + * (one of the SDL_TextureAccess values). This argument can be + * NULL if you don't need this information. + * \param w a pointer filled in with the width of the texture in pixels. This + * argument can be NULL if you don't need this information. + * \param h a pointer filled in with the height of the texture in pixels. This + * argument can be NULL if you don't need this information. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + */ +extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, + Uint32 * format, int *access, + int *w, int *h); + +/** + * Set an additional color value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * Color modulation is not always supported by the renderer; it will return -1 + * if color modulation is not supported. + * + * \param texture the texture to update + * \param r the red color value multiplied into copy operations + * \param g the green color value multiplied into copy operations + * \param b the blue color value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into render copy operations. + * + * \param texture the texture to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * Alpha modulation is not always supported by the renderer; it will return -1 + * if alpha modulation is not supported. + * + * \param texture the texture to update + * \param alpha the source alpha value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, + Uint8 alpha); + +/** + * Get the additional alpha value multiplied into render copy operations. + * + * \param texture the texture to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, + Uint8 * alpha); + +/** + * Set the blend mode for a texture, used by SDL_RenderCopy(). + * + * If the blend mode is not supported, the closest supported mode is chosen + * and this function returns -1. + * + * \param texture the texture to update + * \param blendMode the SDL_BlendMode to use for texture blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureBlendMode + * \sa SDL_RenderCopy + */ +extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for texture copy operations. + * + * \param texture the texture to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextureBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode *blendMode); + +/** + * Set the scale mode used for texture scale operations. + * + * If the scale mode is not supported, the closest supported mode is chosen. + * + * \param texture The texture to update. + * \param scaleMode the SDL_ScaleMode to use for texture scaling. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_SetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode scaleMode); + +/** + * Get the scale mode used for texture scale operations. + * + * \param texture the texture to query. + * \param scaleMode a pointer filled in with the current scale mode. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_SetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode *scaleMode); + +/** + * Associate a user-specified pointer with a texture. + * + * \param texture the texture to update. + * \param userdata the pointer to associate with the texture. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetTextureUserData + */ +extern DECLSPEC int SDLCALL SDL_SetTextureUserData(SDL_Texture * texture, + void *userdata); + +/** + * Get the user-specified pointer associated with a texture + * + * \param texture the texture to query. + * \return the pointer associated with the texture, or NULL if the texture is + * not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetTextureUserData + */ +extern DECLSPEC void * SDLCALL SDL_GetTextureUserData(SDL_Texture * texture); + +/** + * Update the given texture rectangle with new pixel data. + * + * The pixel data must be in the pixel format of the texture. Use + * SDL_QueryTexture() to query the pixel format of the texture. + * + * This is a fairly slow function, intended for use with static textures that + * do not change often. + * + * If the texture is intended to be updated often, it is preferred to create + * the texture as streaming and use the locking functions referenced below. + * While this function will work with streaming textures, for optimization + * reasons you may not get the pixels back if you lock the texture afterward. + * + * \param texture the texture to update + * \param rect an SDL_Rect structure representing the area to update, or NULL + * to update the entire texture + * \param pixels the raw pixel data in the format of the texture + * \param pitch the number of bytes in a row of pixel data, including padding + * between lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const void *pixels, int pitch); + +/** + * Update a rectangle within a planar YV12 or IYUV texture with new pixel + * data. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of Y and U/V planes in the proper order, but this function is + * available if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture + * \param Yplane the raw pixel data for the Y plane + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane + * \param Uplane the raw pixel data for the U plane + * \param Upitch the number of bytes between rows of pixel data for the U + * plane + * \param Vplane the raw pixel data for the V plane + * \param Vpitch the number of bytes between rows of pixel data for the V + * plane + * \returns 0 on success or -1 if the texture is not valid; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_UpdateTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +/** + * Update a rectangle within a planar NV12 or NV21 texture with new pixels. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of NV12/21 planes in the proper order, but this function is available + * if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param Yplane the raw pixel data for the Y plane. + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane. + * \param UVplane the raw pixel data for the UV plane. + * \param UVpitch the number of bytes between rows of pixel data for the UV + * plane. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_UpdateNVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); + +/** + * Lock a portion of the texture for **write-only** pixel access. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect an SDL_Rect structure representing the area to lock for access; + * NULL to lock the entire texture + * \param pixels this is filled in with a pointer to the locked pixels, + * appropriately offset by the locked area + * \param pitch this is filled in with the pitch of the locked pixels; the + * pitch is the length of one row in bytes + * \returns 0 on success or a negative error code if the texture is not valid + * or was not created with `SDL_TEXTUREACCESS_STREAMING`; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, + const SDL_Rect * rect, + void **pixels, int *pitch); + +/** + * Lock a portion of the texture for **write-only** pixel access, and expose + * it as a SDL surface. + * + * Besides providing an SDL_Surface instead of raw pixel data, this function + * operates like SDL_LockTexture. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * The returned surface is freed internally after calling SDL_UnlockTexture() + * or SDL_DestroyTexture(). The caller should not free it. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect a pointer to the rectangle to lock for access. If the rect is + * NULL, the entire texture will be locked + * \param surface this is filled in with an SDL surface representing the + * locked area + * \returns 0 on success, or -1 if the texture is not valid or was not created + * with `SDL_TEXTUREACCESS_STREAMING` + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture, + const SDL_Rect *rect, + SDL_Surface **surface); + +/** + * Unlock a texture, uploading the changes to video memory, if needed. + * + * **Warning**: Please note that SDL_LockTexture() is intended to be + * write-only; it will not guarantee the previous contents of the texture will + * be provided. You must fully initialize any area of a texture that you lock + * before unlocking it, as the pixels might otherwise be uninitialized memory. + * + * Which is to say: locking and immediately unlocking a texture can result in + * corrupted textures, depending on the renderer in use. + * + * \param texture a texture locked by SDL_LockTexture() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockTexture + */ +extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); + +/** + * Determine whether a renderer supports the use of render targets. + * + * \param renderer the renderer that will be checked + * \returns SDL_TRUE if supported or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); + +/** + * Set a texture as the current rendering target. + * + * Before using this function, you should check the + * `SDL_RENDERER_TARGETTEXTURE` bit in the flags of SDL_RendererInfo to see if + * render targets are supported. + * + * The default render target is the window for which the renderer was created. + * To stop rendering to a texture and render to the window again, call this + * function with a NULL `texture`. + * + * \param renderer the rendering context + * \param texture the targeted texture, which must be created with the + * `SDL_TEXTUREACCESS_TARGET` flag, or NULL to render to the + * window instead of a texture. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderTarget + */ +extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +/** + * Get the current render target. + * + * The default render target is the window for which the renderer was created, + * and is reported a NULL here. + * + * \param renderer the rendering context + * \returns the current render target or NULL for the default render target. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * Set a device independent resolution for rendering. + * + * This function uses the viewport and scaling functionality to allow a fixed + * logical resolution for rendering, regardless of the actual output + * resolution. If the actual output resolution doesn't have the same aspect + * ratio the output rendering will be centered within the output display. + * + * If the output display is a window, mouse and touch events in the window + * will be filtered and scaled so they seem to arrive within the logical + * resolution. The SDL_HINT_MOUSE_RELATIVE_SCALING hint controls whether + * relative motion events are also scaled. + * + * If this function results in scaling or subpixel drawing by the rendering + * backend, it will be handled using the appropriate quality hints. + * + * \param renderer the renderer for which resolution should be set + * \param w the width of the logical resolution + * \param h the height of the logical resolution + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * Get device independent resolution for rendering. + * + * When using the main rendering target (eg no target texture is set): this + * may return 0 for `w` and `h` if the SDL_Renderer has never had its logical + * size set by SDL_RenderSetLogicalSize(). Otherwise it returns the logical + * width and height. + * + * When using a target texture: Never return 0 for `w` and `h` at first. Then + * it returns the logical width and height that are set. + * + * \param renderer a rendering context + * \param w an int to be filled with the width + * \param h an int to be filled with the height + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); + +/** + * Set whether to force integer scales for resolution-independent rendering. + * + * This function restricts the logical viewport to integer values - that is, + * when a resolution is between two multiples of a logical size, the viewport + * size is rounded down to the lower multiple. + * + * \param renderer the renderer for which integer scaling should be set + * \param enable enable or disable the integer scaling for rendering + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderGetIntegerScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * Get whether integer scales are forced for resolution-independent rendering. + * + * \param renderer the renderer from which integer scaling should be queried + * \returns SDL_TRUE if integer scales are forced or SDL_FALSE if not and on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderSetIntegerScale + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + +/** + * Set the drawing area for rendering on the current target. + * + * When the window is resized, the viewport is reset to fill the entire new + * window size. + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the drawing area, or NULL + * to set the viewport to the entire target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetViewport + */ +extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the drawing area for the current target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure filled in with the current drawing area + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetViewport + */ +extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Set the clip rectangle for rendering on the specified target. + * + * \param renderer the rendering context for which clip rectangle should be + * set + * \param rect an SDL_Rect structure representing the clip area, relative to + * the viewport, or NULL to disable clipping + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderIsClipEnabled + */ +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the clip rectangle for the current target. + * + * \param renderer the rendering context from which clip rectangle should be + * queried + * \param rect an SDL_Rect structure filled in with the current clipping area + * or an empty rectangle if clipping is disabled + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderIsClipEnabled + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Get whether clipping is enabled on the given renderer. + * + * \param renderer the renderer from which clip state should be queried + * \returns SDL_TRUE if clipping is enabled or SDL_FALSE if not; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); + + +/** + * Set the drawing scale for rendering on the current target. + * + * The drawing coordinates are scaled by the x/y scaling factors before they + * are used by the renderer. This allows resolution independent drawing with a + * single coordinate system. + * + * If this results in scaling or subpixel drawing by the rendering backend, it + * will be handled using the appropriate quality hints. For best results use + * integer scaling factors. + * + * \param renderer a rendering context + * \param scaleX the horizontal scaling factor + * \param scaleY the vertical scaling factor + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * Get the drawing scale for the current target. + * + * \param renderer the renderer from which drawing scale should be queried + * \param scaleX a pointer filled in with the horizontal scaling factor + * \param scaleY a pointer filled in with the vertical scaling factor + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetScale + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + +/** + * Get logical coordinates of point in renderer when given real coordinates of + * point in window. + * + * Logical coordinates will differ from real coordinates when render is scaled + * and logical renderer size set + * + * \param renderer the renderer from which the logical coordinates should be + * calculated + * \param windowX the real X coordinate in the window + * \param windowY the real Y coordinate in the window + * \param logicalX the pointer filled with the logical x coordinate + * \param logicalY the pointer filled with the logical y coordinate + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer, + int windowX, int windowY, + float *logicalX, float *logicalY); + + +/** + * Get real coordinates of point in window when given logical coordinates of + * point in renderer. + * + * Logical coordinates will differ from real coordinates when render is scaled + * and logical renderer size set + * + * \param renderer the renderer from which the window coordinates should be + * calculated + * \param logicalX the logical x coordinate + * \param logicalY the logical y coordinate + * \param windowX the pointer filled with the real X coordinate in the window + * \param windowY the pointer filled with the real Y coordinate in the window + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer, + float logicalX, float logicalY, + int *windowX, int *windowY); + +/** + * Set the color used for drawing operations (Rect, Line and Clear). + * + * Set the color for drawing or filling rectangles, lines, and points, and for + * SDL_RenderClear(). + * + * \param renderer the rendering context + * \param r the red value used to draw on the rendering target + * \param g the green value used to draw on the rendering target + * \param b the blue value used to draw on the rendering target + * \param a the alpha value used to draw on the rendering target; usually + * `SDL_ALPHA_OPAQUE` (255). Use SDL_SetRenderDrawBlendMode to + * specify how the alpha channel is used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawColor + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * Get the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer the rendering context + * \param r a pointer filled in with the red value used to draw on the + * rendering target + * \param g a pointer filled in with the green value used to draw on the + * rendering target + * \param b a pointer filled in with the blue value used to draw on the + * rendering target + * \param a a pointer filled in with the alpha value used to draw on the + * rendering target; usually `SDL_ALPHA_OPAQUE` (255) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * Set the blend mode used for drawing operations (Fill and Line). + * + * If the blend mode is not supported, the closest supported mode is chosen. + * + * \param renderer the rendering context + * \param blendMode the SDL_BlendMode to use for blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for drawing operations. + * + * \param renderer the rendering context + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode *blendMode); + +/** + * Clear the current rendering target with the drawing color. + * + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); + +/** + * Draw a point on the current rendering target. + * + * SDL_RenderDrawPoint() draws a single point. If you want to draw multiple, + * use SDL_RenderDrawPoints() instead. + * + * \param renderer the rendering context + * \param x the x coordinate of the point + * \param y the y coordinate of the point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, + int x, int y); + +/** + * Draw multiple points on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures that represent the points to + * draw + * \param count the number of points to draw + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a line on the current rendering target. + * + * SDL_RenderDrawLine() draws the line to include both end points. If you want + * to draw multiple, connecting lines use SDL_RenderDrawLines() instead. + * + * \param renderer the rendering context + * \param x1 the x coordinate of the start point + * \param y1 the y coordinate of the start point + * \param x2 the x coordinate of the end point + * \param y2 the y coordinate of the end point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, + int x1, int y1, int x2, int y2); + +/** + * Draw a series of connected lines on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures representing points along + * the lines + * \param count the number of points, drawing count-1 lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a rectangle on the current rendering target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the rectangle to draw, or + * NULL to outline the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Draw some number of rectangles on the current rendering target. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be drawn + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color. + * + * The current drawing color is set by SDL_SetRenderDrawColor(), and the + * color's alpha value is ignored unless blending is enabled with the + * appropriate call to SDL_SetRenderDrawBlendMode(). + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL for the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be filled + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderPresent + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target; the texture will be stretched to fill the + * given rectangle + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopyEx + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); + +/** + * Copy a portion of the texture to the current rendering, with optional + * rotation and flipping. + * + * Copy a portion of the texture to the current rendering target, optionally + * rotating it by angle around the given center and also flipping it + * top-bottom and/or left-right. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target + * \param angle an angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center a pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around `dstrect.w / 2`, `dstrect.h / 2`) + * \param flip a SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopy + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, + const double angle, + const SDL_Point *center, + const SDL_RendererFlip flip); + + +/** + * Draw a point on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer, + float x, float y); + +/** + * Draw multiple points on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a line on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer, + float x1, float y1, float x2, float y2); + +/** + * Draw a series of connected lines on the current rendering target at + * subpixel precision. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a rectangle on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Draw some number of rectangles on the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color at + * subpixel precision. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color at subpixel precision. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect); + +/** + * Copy a portion of the source texture to the current rendering target, with + * rotation and flipping, at subpixel precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center A pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect, + const double angle, + const SDL_FPoint *center, + const SDL_RendererFlip flip); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex array Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param renderer The rendering context. + * \param texture (optional) The SDL texture to use. + * \param vertices Vertices. + * \param num_vertices Number of vertices. + * \param indices (optional) An array of integer indices into the 'vertices' + * array, if NULL all vertices will be rendered in sequential + * order. + * \param num_indices Number of indices. + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometryRaw + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Vertex *vertices, int num_vertices, + const int *indices, int num_indices); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex arrays Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param renderer The rendering context. + * \param texture (optional) The SDL texture to use. + * \param xy Vertex positions + * \param xy_stride Byte size to move from one element to the next element + * \param color Vertex colors (as SDL_Color) + * \param color_stride Byte size to move from one element to the next element + * \param uv Vertex normalized texture coordinates + * \param uv_stride Byte size to move from one element to the next element + * \param num_vertices Number of vertices. + * \param indices (optional) An array of indices into the 'vertices' arrays, + * if NULL all vertices will be rendered in sequential order. + * \param num_indices Number of indices. + * \param size_indices Index size: 1 (byte), 2 (short), 4 (int) + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometry + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices); + +/** + * Read pixels from the current rendering target to an array of pixels. + * + * **WARNING**: This is a very slow operation, and should not be used + * frequently. If you're using this on the main rendering target, it should be + * called after rendering and before SDL_RenderPresent(). + * + * `pitch` specifies the number of bytes between rows in the destination + * `pixels` data. This allows you to write to a subrectangle or have padded + * rows in the destination. Generally, `pitch` should equal the number of + * pixels per row in the `pixels` data times the number of bytes per pixel, + * but it might contain additional padding (for example, 24bit RGB Windows + * Bitmap data pads all rows to multiples of 4 bytes). + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the area to read, or NULL + * for the entire render target + * \param format an SDL_PixelFormatEnum value of the desired format of the + * pixel data, or 0 to use the format of the rendering target + * \param pixels a pointer to the pixel data to copy into + * \param pitch the pitch of the `pixels` parameter + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void *pixels, int pitch); + +/** + * Update the screen with any rendering performed since the previous call. + * + * SDL's rendering functions operate on a backbuffer; that is, calling a + * rendering function such as SDL_RenderDrawLine() does not directly put a + * line on the screen, but rather updates the backbuffer. As such, you compose + * your entire scene and *present* the composed backbuffer to the screen as a + * complete picture. + * + * Therefore, when using SDL's rendering API, one does all drawing intended + * for the frame, and then calls this function once per frame to present the + * final drawing to the user. + * + * The backbuffer should be considered invalidated after each present; do not + * assume that previous contents will exist between frames. You are strongly + * encouraged to call SDL_RenderClear() to initialize the backbuffer before + * starting each new frame's drawing, even if you plan to overwrite every + * pixel. + * + * \param renderer the rendering context + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); + +/** + * Destroy the specified texture. + * + * Passing NULL or an otherwise invalid texture will set the SDL error message + * to "Invalid texture". + * + * \param texture the texture to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_CreateTextureFromSurface + */ +extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); + +/** + * Destroy the rendering context for a window and free associated textures. + * + * \param renderer the rendering context + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); + +/** + * Force the rendering context to flush any pending commands to the underlying + * rendering API. + * + * You do not need to (and in fact, shouldn't) call this function unless you + * are planning to call into OpenGL/Direct3D/Metal/whatever directly in + * addition to using an SDL_Renderer. + * + * This is for a very-specific case: if you are using SDL's render API, you + * asked for a specific renderer backend (OpenGL, Direct3D, etc), you set + * SDL_HINT_RENDER_BATCHING to "1", and you plan to make OpenGL/D3D/whatever + * calls in addition to SDL render API calls. If all of this applies, you + * should call SDL_RenderFlush() between calls to SDL's render API and the + * low-level API you're using in cooperation. + * + * In all other cases, you can ignore this function. This is only here to get + * maximum performance out of a specific situation. In all other cases, SDL + * will do the right thing, perhaps at a performance loss. + * + * This function is first available in SDL 2.0.10, and is not needed in 2.0.9 + * and earlier, as earlier versions did not queue rendering commands at all, + * instead flushing them to the OS immediately. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFlush(SDL_Renderer * renderer); + + +/** + * Bind an OpenGL/ES/ES2 texture to the current context. + * + * This is for use with OpenGL instructions when rendering OpenGL primitives + * directly. + * + * If not NULL, `texw` and `texh` will be filled with the width and height + * values suitable for the provided texture. In most cases, both will be 1.0, + * however, on systems that support the GL_ARB_texture_rectangle extension, + * these values will actually be the pixel width and height used to create the + * texture, so this factor needs to be taken into account when providing + * texture coordinates to OpenGL. + * + * You need a renderer to create an SDL_Texture, therefore you can only use + * this function with an implicit OpenGL context from SDL_CreateRenderer(), + * not with your own OpenGL context. If you need control over your OpenGL + * context, you need to write your own texture-loading methods. + * + * Also note that SDL may upload RGB textures as BGR (or vice-versa), and + * re-order the color channels in the shaders phase, so the uploaded texture + * may have swapped color channels. + * + * \param texture the texture to bind to the current OpenGL/ES/ES2 context + * \param texw a pointer to a float value which will be filled with the + * texture width or NULL if you don't need that value + * \param texh a pointer to a float value which will be filled with the + * texture height or NULL if you don't need that value + * \returns 0 on success, or -1 if the operation is not supported; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + * \sa SDL_GL_UnbindTexture + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * Unbind an OpenGL/ES/ES2 texture from the current context. + * + * See SDL_GL_BindTexture() for examples on how to use these functions + * + * \param texture the texture to unbind from the current OpenGL/ES/ES2 context + * \returns 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_BindTexture + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + +/** + * Get the CAMetalLayer associated with the given Metal renderer. + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to a `CAMetalLayer *`. + * + * \param renderer The renderer to query + * \returns a `CAMetalLayer *` on success, or NULL if the renderer isn't a + * Metal renderer + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalCommandEncoder + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); + +/** + * Get the Metal command encoder for the current frame + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to an `id`. + * + * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give + * SDL a drawable to render to, which might happen if the window is + * hidden/minimized/offscreen. This doesn't apply to command encoders for + * render targets, just the window's backbacker. Check your return values! + * + * \param renderer The renderer to query + * \returns an `id` on success, or NULL if the + * renderer isn't a Metal renderer or there was an error. + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalLayer + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer); + +/** + * Toggle VSync of the given renderer. + * + * \param renderer The renderer to toggle + * \param vsync 1 for on, 0 for off. All other values are reserved + * \returns a 0 int on success, or non-zero on failure + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_RenderSetVSync(SDL_Renderer* renderer, int vsync); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_render_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_revision.h b/thirdparty/SDL/include/SDL/SDL_revision.h new file mode 100644 index 00000000..3e9b63af --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_revision.h @@ -0,0 +1,2 @@ +#define SDL_REVISION "" +#define SDL_REVISION_NUMBER 0 diff --git a/thirdparty/SDL/include/SDL/SDL_revision.h.cmake b/thirdparty/SDL/include/SDL/SDL_revision.h.cmake new file mode 100644 index 00000000..b27ec11b --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_revision.h.cmake @@ -0,0 +1,6 @@ +#cmakedefine SDL_REVISION "@SDL_REVISION@" +#define SDL_REVISION_NUMBER 0 + +#ifndef SDL_REVISION +#define SDL_REVISION "" +#endif diff --git a/thirdparty/SDL/include/SDL/SDL_rwops.h b/thirdparty/SDL/include/SDL/SDL_rwops.h new file mode 100644 index 00000000..3960f567 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_rwops.h @@ -0,0 +1,841 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rwops.h + * + * This file provides a general interface for SDL to read and write + * data streams. It can easily be extended to files, memory, etc. + */ + +#ifndef SDL_rwops_h_ +#define SDL_rwops_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* RWops Types */ +#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ +#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ +#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ + +/** + * This is the read/write operation structure -- very basic. + */ +typedef struct SDL_RWops +{ + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + + /** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); + + /** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); + + /** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); + + /** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ + int (SDLCALL * close) (struct SDL_RWops * context); + + Uint32 type; + union + { +#if defined(__ANDROID__) + struct + { + void *asset; + } androidio; +#elif defined(__WIN32__) || defined(__GDK__) + struct + { + SDL_bool append; + void *h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } windowsio; +#endif + +#ifdef HAVE_STDIO_H + struct + { + SDL_bool autoclose; + FILE *fp; + } stdio; +#endif + struct + { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct + { + void *data1; + void *data2; + } unknown; + } hidden; + +} SDL_RWops; + + +/** + * \name RWFrom functions + * + * Functions to create SDL_RWops structures from various data streams. + */ +/* @{ */ + +/** + * Use this function to create a new SDL_RWops structure for reading from + * and/or writing to a named file. + * + * The `mode` string is treated roughly the same as in a call to the C + * library's fopen(), even if SDL doesn't happen to use fopen() behind the + * scenes. + * + * Available `mode` strings: + * + * - "r": Open a file for reading. The file must exist. + * - "w": Create an empty file for writing. If a file with the same name + * already exists its content is erased and the file is treated as a new + * empty file. + * - "a": Append to a file. Writing operations append data at the end of the + * file. The file is created if it does not exist. + * - "r+": Open a file for update both reading and writing. The file must + * exist. + * - "w+": Create an empty file for both reading and writing. If a file with + * the same name already exists its content is erased and the file is + * treated as a new empty file. + * - "a+": Open a file for reading and appending. All writing operations are + * performed at the end of the file, protecting the previous content to be + * overwritten. You can reposition (fseek, rewind) the internal pointer to + * anywhere in the file for reading, but writing operations will move it + * back to the end of file. The file is created if it does not exist. + * + * **NOTE**: In order to open a file as a binary file, a "b" character has to + * be included in the `mode` string. This additional "b" character can either + * be appended at the end of the string (thus making the following compound + * modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the + * letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). + * Additional characters may follow the sequence, although they should have no + * effect. For example, "t" is sometimes appended to make explicit the file is + * a text file. + * + * This function supports Unicode filenames, but they must be encoded in UTF-8 + * format, regardless of the underlying operating system. + * + * As a fallback, SDL_RWFromFile() will transparently open a matching filename + * in an Android app's `assets`. + * + * Closing the SDL_RWops will close the file handle SDL is holding internally. + * + * \param file a UTF-8 string representing the filename to open + * \param mode an ASCII string representing the mode to be used for opening + * the file. + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, + const char *mode); + +#ifdef HAVE_STDIO_H + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, SDL_bool autoclose); + +#else + +/** + * Use this function to create an SDL_RWops structure from a standard I/O file + * pointer (stdio.h's `FILE*`). + * + * This function is not available on Windows, since files opened in an + * application on that platform cannot be used by a dynamically linked + * library. + * + * On some platforms, the first parameter is a `void*`, on others, it's a + * `FILE*`, depending on what system headers are available to SDL. It is + * always intended to be the `FILE*` type from the C runtime's stdio.h. + * + * \param fp the `FILE*` that feeds the SDL_RWops stream + * \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, + * SDL_FALSE to leave the `FILE*` open when the RWops is + * closed + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, + SDL_bool autoclose); +#endif + +/** + * Use this function to prepare a read-write memory buffer for use with + * SDL_RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size, for both read and write access. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to make sure the RWops never writes to the memory buffer, you + * should use SDL_RWFromConstMem() with a read-only buffer of memory instead. + * + * \param mem a pointer to a buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); + +/** + * Use this function to prepare a read-only memory buffer for use with RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size. It assumes the memory area is not writable. + * + * Attempting to write to this RWops stream will report an error without + * writing to the memory buffer. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to write to a memory buffer, you should use SDL_RWFromMem() + * with a writable buffer of memory instead. + * + * \param mem a pointer to a read-only buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, + int size); + +/* @} *//* RWFrom functions */ + + +/** + * Use this function to allocate an empty, unpopulated SDL_RWops structure. + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. + * + * You must free the returned pointer with SDL_FreeRW(). Depending on your + * operating system and compiler, there may be a difference between the + * malloc() and free() your program uses and the versions SDL calls + * internally. Trying to mix the two can cause crashing such as segmentation + * faults. Since all SDL_RWops must free themselves when their **close** + * method is called, all SDL_RWops must be allocated through this function, so + * they can all be freed correctly with SDL_FreeRW(). + * + * \returns a pointer to the allocated memory on success, or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeRW + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); + +/** + * Use this function to free an SDL_RWops structure allocated by + * SDL_AllocRW(). + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and + * call the **close** method on those SDL_RWops pointers when you are done + * with them. + * + * Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is + * invalid as soon as this function returns. Any extra memory allocated during + * creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must + * be responsible for managing that memory in their **close** method. + * + * \param area the SDL_RWops structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocRW + */ +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); + +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ + +/** + * Use this function to get the size of the data stream in an SDL_RWops. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context the SDL_RWops to get the size of the data stream from + * \returns the size of the data stream in the SDL_RWops on success, -1 if + * unknown or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); + +/** + * Seek within an SDL_RWops data stream. + * + * This function seeks to byte `offset`, relative to `whence`. + * + * `whence` may be any of the following values: + * + * - `RW_SEEK_SET`: seek from the beginning of data + * - `RW_SEEK_CUR`: seek relative to current read point + * - `RW_SEEK_END`: seek relative to the end of data + * + * If this stream can not seek, it will return -1. + * + * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's + * `seek` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param offset an offset in bytes, relative to **whence** location; can be + * negative + * \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` + * \returns the final offset in the data stream after the seek or -1 on error. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, + Sint64 offset, int whence); + +/** + * Determine the current read/write offset in an SDL_RWops data stream. + * + * SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` + * method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify + * application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a SDL_RWops data stream object from which to get the current + * offset + * \returns the current offset in the stream, or -1 if the information can not + * be determined. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); + +/** + * Read from a data source. + * + * This function reads up to `maxnum` objects each of size `size` from the + * data source to the area pointed at by `ptr`. This function may read less + * objects than requested. It will return zero when there has been an error or + * the data stream is completely read. + * + * SDL_RWread() is actually a function wrapper that calls the SDL_RWops's + * `read` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer to read data into + * \param size the size of each object to read, in bytes + * \param maxnum the maximum number of objects to be read + * \returns the number of objects read, or 0 at error or end of file; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, + void *ptr, size_t size, + size_t maxnum); + +/** + * Write to an SDL_RWops data stream. + * + * This function writes exactly `num` objects each of size `size` from the + * area pointed at by `ptr` to the stream. If this fails for any reason, it'll + * return less than `num` to demonstrate how far the write progressed. On + * success, it returns `num`. + * + * SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's + * `write` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer containing data to write + * \param size the size of an object to write, in bytes + * \param num the number of objects to write + * \returns the number of objects written, which will be less than **num** on + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + */ +extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, + const void *ptr, size_t size, + size_t num); + +/** + * Close and free an allocated SDL_RWops structure. + * + * SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any + * resources used by the stream and frees the SDL_RWops itself with + * SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to + * flush to its output (e.g. to disk). + * + * Note that if this fails to flush the stream to disk, this function reports + * an error, but the SDL_RWops is still invalid once this function returns. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context SDL_RWops structure to close + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); + +/** + * Load all the data from an SDL data stream. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * \param src the SDL_RWops to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, + size_t *datasize, + int freesrc); + +/** + * Load all the data from a file path. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * Prior to SDL 2.0.10, this function was a macro wrapping around + * SDL_LoadFile_RW. + * + * \param file the path to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); + +/** + * \name Read endian functions + * + * Read an item of the specified endianness and return in native format. + */ +/* @{ */ + +/** + * Use this function to read a byte from an SDL_RWops. + * + * \param src the SDL_RWops to read from + * \returns the read byte on success or 0 on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteU8 + */ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); + +/** + * Use this function to read 16 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); + +/** + * Use this function to read 16 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); + +/** + * Use this function to read 32 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); + +/** + * Use this function to read 32 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); + +/** + * Use this function to read 64 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); + +/** + * Use this function to read 64 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +/* @} *//* Read endian functions */ + +/** + * \name Write endian functions + * + * Write an item of native format to the specified endianness. + */ +/* @{ */ + +/** + * Use this function to write a byte to an SDL_RWops. + * + * \param dst the SDL_RWops to write to + * \param value the byte value to write + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadU8 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +/* @} *//* Write endian functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rwops_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_scancode.h b/thirdparty/SDL/include/SDL/SDL_scancode.h new file mode 100644 index 00000000..aaa782f8 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_scancode.h @@ -0,0 +1,433 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_scancode.h + * + * Defines keyboard scancodes. + */ + +#ifndef SDL_scancode_h_ +#define SDL_scancode_h_ + +#include "SDL_stdinc.h" + +/** + * \brief The SDL keyboard scancode representation. + * + * Values of this type are used to represent keyboard keys, among other places + * in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the + * SDL_Event structure. + * + * The values in this enumeration are based on the USB usage page standard: + * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf + */ +typedef enum +{ + SDL_SCANCODE_UNKNOWN = 0, + + /** + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + */ + /* @{ */ + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + */ + SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + */ + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + */ + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) */ + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards + */ + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. */ + SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ + SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. */ + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, /**< redo */ + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, +/* not sure whether there's a reason to enable these */ +/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ +/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ +/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see + footnotes in USB doc */ + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ + SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ + SDL_SCANCODE_LANG3 = 146, /**< Katakana */ + SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ + SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ + SDL_SCANCODE_LANG6 = 149, /**< reserved */ + SDL_SCANCODE_LANG7 = 150, /**< reserved */ + SDL_SCANCODE_LANG8 = 151, /**< reserved */ + SDL_SCANCODE_LANG9 = 152, /**< reserved */ + + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, /**< alt, option */ + SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, /**< alt gr, option */ + SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ + + SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special KMOD_MODE for it I'm adding it here + */ + + /* @} *//* Usage page 0x07 */ + + /** + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + /* @} *//* Usage page 0x0C */ + + /** + * \name Walther keys + * + * These are values that Christian Walther added (for mac keyboard?). + */ + /* @{ */ + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display + switch, video mode switch */ + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + /* @} *//* Walther keys */ + + /** + * \name Usage page 0x0C (additional media keys) + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIOREWIND = 285, + SDL_SCANCODE_AUDIOFASTFORWARD = 286, + + /* @} *//* Usage page 0x0C (additional media keys) */ + + /** + * \name Mobile keys + * + * These are values that are often used on mobile phones. + */ + /* @{ */ + + SDL_SCANCODE_SOFTLEFT = 287, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom left + of the display. */ + SDL_SCANCODE_SOFTRIGHT = 288, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom right + of the display. */ + SDL_SCANCODE_CALL = 289, /**< Used for accepting phone calls. */ + SDL_SCANCODE_ENDCALL = 290, /**< Used for rejecting phone calls. */ + + /* @} *//* Mobile keys */ + + /* Add any other keys here. */ + + SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes + for array bounds */ +} SDL_Scancode; + +#endif /* SDL_scancode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_sensor.h b/thirdparty/SDL/include/SDL/SDL_sensor.h new file mode 100644 index 00000000..a2f30e0f --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_sensor.h @@ -0,0 +1,301 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_sensor.h + * + * Include file for SDL sensor event handling + * + */ + +#ifndef SDL_sensor_h_ +#define SDL_sensor_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief SDL_sensor.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system + * for sensors, and load appropriate drivers. + */ + +struct _SDL_Sensor; +typedef struct _SDL_Sensor SDL_Sensor; + +/** + * This is a unique ID for a sensor for the time it is connected to the system, + * and is never reused for the lifetime of the application. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_SensorID; + +/* The different sensors defined by SDL + * + * Additional sensors may be available, using platform dependent semantics. + * + * Hare are the additional Android sensors: + * https://developer.android.com/reference/android/hardware/SensorEvent.html#values + */ +typedef enum +{ + SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ + SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ + SDL_SENSOR_ACCEL, /**< Accelerometer */ + SDL_SENSOR_GYRO /**< Gyroscope */ +} SDL_SensorType; + +/** + * Accelerometer sensor + * + * The accelerometer returns the current acceleration in SI meters per + * second squared. This measurement includes the force of gravity, so + * a device at rest will have an value of SDL_STANDARD_GRAVITY away + * from the center of the earth. + * + * values[0]: Acceleration on the x axis + * values[1]: Acceleration on the y axis + * values[2]: Acceleration on the z axis + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ +#define SDL_STANDARD_GRAVITY 9.80665f + +/** + * Gyroscope sensor + * + * The gyroscope returns the current rate of rotation in radians per second. + * The rotation is positive in the counter-clockwise direction. That is, + * an observer looking from a positive location on one of the axes would + * see positive rotation on that axis when it appeared to be rotating + * counter-clockwise. + * + * values[0]: Angular speed around the x axis (pitch) + * values[1]: Angular speed around the y axis (yaw) + * values[2]: Angular speed around the z axis (roll) + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone or controller is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the sensor API + * + * If you are using the sensor API or handling events from multiple threads + * you should use these locking functions to protect access to the sensors. + * + * In particular, you are guaranteed that the sensor list won't change, so the + * API functions that take a sensor index will be valid, and sensor events + * will not be delivered. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC void SDLCALL SDL_LockSensors(void); +extern DECLSPEC void SDLCALL SDL_UnlockSensors(void); + +/** + * Count the number of sensors attached to the system right now. + * + * \returns the number of sensors detected. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_NumSensors(void); + +/** + * Get the implementation dependent name of a sensor. + * + * \param device_index The sensor to obtain name from + * \returns the sensor name, or NULL if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index); + +/** + * Get the type of a sensor. + * + * \param device_index The sensor to get the type from + * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `device_index` is + * out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index); + +/** + * Get the platform dependent type of a sensor. + * + * \param device_index The sensor to check + * \returns the sensor platform dependent type, or -1 if `device_index` is out + * of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index); + +/** + * Get the instance ID of a sensor. + * + * \param device_index The sensor to get instance id from + * \returns the sensor instance ID, or -1 if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index); + +/** + * Open a sensor for use. + * + * \param device_index The sensor to open + * \returns an SDL_Sensor sensor object, or NULL if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index); + +/** + * Return the SDL_Sensor associated with an instance id. + * + * \param instance_id The sensor from instance id + * \returns an SDL_Sensor object. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id); + +/** + * Get the implementation dependent name of a sensor + * + * \param sensor The SDL_Sensor object + * \returns the sensor name, or NULL if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor); + +/** + * Get the type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID` if `sensor` is + * NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor); + +/** + * Get the platform dependent type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor platform dependent type, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor); + +/** + * Get the instance ID of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor instance ID, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor); + +/** + * Get the current state of an opened sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor The SDL_Sensor object to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values); + +/** + * Close a sensor previously opened with SDL_SensorOpen(). + * + * \param sensor The SDL_Sensor object to close + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor); + +/** + * Update the current state of the open sensors. + * + * This is called automatically by the event loop if sensor events are + * enabled. + * + * This needs to be called from the thread that initialized the sensor + * subsystem. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorUpdate(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* SDL_sensor_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_shape.h b/thirdparty/SDL/include/SDL/SDL_shape.h new file mode 100644 index 00000000..1bca9270 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_shape.h @@ -0,0 +1,155 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_shape_h_ +#define SDL_shape_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** \file SDL_shape.h + * + * Header file for the shaped window API. + */ + +#define SDL_NONSHAPEABLE_WINDOW -1 +#define SDL_INVALID_SHAPE_ARGUMENT -2 +#define SDL_WINDOW_LACKS_SHAPE -3 + +/** + * Create a window that can be shaped with the specified position, dimensions, + * and flags. + * + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window. + * \param h The height of the window. + * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with + * any of the following: ::SDL_WINDOW_OPENGL, + * ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN, + * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, + * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set, + * and ::SDL_WINDOW_FULLSCREEN is always unset. + * \return the window created, or NULL if window creation failed. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); + +/** + * Return whether the given window is a shaped window. + * + * \param window The window to query for being shaped. + * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if + * the window is unshaped or NULL. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateShapedWindow + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window); + +/** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. */ +typedef enum { + /** \brief The default mode, a binarized alpha cutoff of 1. */ + ShapeModeDefault, + /** \brief A binarized alpha cutoff with a given integer value. */ + ShapeModeBinarizeAlpha, + /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ + ShapeModeReverseBinarizeAlpha, + /** \brief A color key is applied. */ + ShapeModeColorKey +} WindowShapeMode; + +#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) + +/** \brief A union containing parameters for shaped windows. */ +typedef union { + /** \brief A cutoff alpha value for binarization of the window shape's alpha channel. */ + Uint8 binarizationCutoff; + SDL_Color colorKey; +} SDL_WindowShapeParams; + +/** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ +typedef struct SDL_WindowShapeMode { + /** \brief The mode of these window-shape parameters. */ + WindowShapeMode mode; + /** \brief Window-shape parameters. */ + SDL_WindowShapeParams parameters; +} SDL_WindowShapeMode; + +/** + * Set the shape and parameters of a shaped window. + * + * \param window The shaped window whose parameters should be set. + * \param shape A surface encoding the desired shape for the window. + * \param shape_mode The parameters to set for the shaped window. + * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape + * argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does + * not reference a valid shaped window. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WindowShapeMode + * \sa SDL_GetShapedWindowMode + */ +extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + +/** + * Get the shape parameters of a shaped window. + * + * \param window The shaped window whose parameters should be retrieved. + * \param shape_mode An empty shape-mode structure to fill, or NULL to check + * whether the window has a shape. + * \return 0 if the window has a shape and, provided shape_mode was not NULL, + * shape_mode has been filled with the mode data, + * SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped + * window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a + * shapeable window currently lacking a shape. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WindowShapeMode + * \sa SDL_SetWindowShape + */ +extern DECLSPEC int SDLCALL SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_shape_h_ */ diff --git a/thirdparty/SDL/include/SDL/SDL_stdinc.h b/thirdparty/SDL/include/SDL/SDL_stdinc.h new file mode 100644 index 00000000..3514ba92 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_stdinc.h @@ -0,0 +1,829 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_stdinc.h + * + * This is a general header that includes C language support. + */ + +#ifndef SDL_stdinc_h_ +#define SDL_stdinc_h_ + +#include "SDL_config.h" + +#ifdef __APPLE__ +#ifndef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */ +#endif +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_WCHAR_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_MATH_H +# if defined(_MSC_VER) +/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on + Visual Studio. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx + for more information. +*/ +# define _USE_MATH_DEFINES +# endif +# include +#endif +#ifdef HAVE_FLOAT_H +# include +#endif +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +#pragma alloca +# elif defined(__MRC__) +void *alloca(unsigned); +# else +char *alloca(); +# endif +#endif + +#ifdef SIZE_MAX +# define SDL_SIZE_MAX SIZE_MAX +#else +# define SDL_SIZE_MAX ((size_t) -1) +#endif + +/** + * Check if the compiler supports a given builtin. + * Supported by virtually all clang versions and recent gcc. Use this + * instead of checking the clang version if possible. + */ +#ifdef __has_builtin +#define _SDL_HAS_BUILTIN(x) __has_builtin(x) +#else +#define _SDL_HAS_BUILTIN(x) 0 +#endif + +/** + * The number of elements in an array. + */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/** + * Macro useful for building other macros with strings in them + * + * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") + */ +#define SDL_STRINGIFY_ARG(arg) #arg + +/** + * \name Cast operators + * + * Use proper C++ casts when compiled as C++ to be compatible with the option + * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). + */ +/* @{ */ +#ifdef __cplusplus +#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) +#define SDL_static_cast(type, expression) static_cast(expression) +#define SDL_const_cast(type, expression) const_cast(expression) +#else +#define SDL_reinterpret_cast(type, expression) ((type)(expression)) +#define SDL_static_cast(type, expression) ((type)(expression)) +#define SDL_const_cast(type, expression) ((type)(expression)) +#endif +/* @} *//* Cast operators */ + +/* Define a four character code as a Uint32 */ +#define SDL_FOURCC(A, B, C, D) \ + ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) + +/** + * \name Basic data types + */ +/* @{ */ + +#ifdef __CC_ARM +/* ARM's compiler throws warnings if we use an enum: like "SDL_bool x = a < b;" */ +#define SDL_FALSE 0 +#define SDL_TRUE 1 +typedef int SDL_bool; +#else +typedef enum +{ + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; +#endif + +/** + * \brief A signed 8-bit integer type. + */ +#define SDL_MAX_SINT8 ((Sint8)0x7F) /* 127 */ +#define SDL_MIN_SINT8 ((Sint8)(~0x7F)) /* -128 */ +typedef int8_t Sint8; +/** + * \brief An unsigned 8-bit integer type. + */ +#define SDL_MAX_UINT8 ((Uint8)0xFF) /* 255 */ +#define SDL_MIN_UINT8 ((Uint8)0x00) /* 0 */ +typedef uint8_t Uint8; +/** + * \brief A signed 16-bit integer type. + */ +#define SDL_MAX_SINT16 ((Sint16)0x7FFF) /* 32767 */ +#define SDL_MIN_SINT16 ((Sint16)(~0x7FFF)) /* -32768 */ +typedef int16_t Sint16; +/** + * \brief An unsigned 16-bit integer type. + */ +#define SDL_MAX_UINT16 ((Uint16)0xFFFF) /* 65535 */ +#define SDL_MIN_UINT16 ((Uint16)0x0000) /* 0 */ +typedef uint16_t Uint16; +/** + * \brief A signed 32-bit integer type. + */ +#define SDL_MAX_SINT32 ((Sint32)0x7FFFFFFF) /* 2147483647 */ +#define SDL_MIN_SINT32 ((Sint32)(~0x7FFFFFFF)) /* -2147483648 */ +typedef int32_t Sint32; +/** + * \brief An unsigned 32-bit integer type. + */ +#define SDL_MAX_UINT32 ((Uint32)0xFFFFFFFFu) /* 4294967295 */ +#define SDL_MIN_UINT32 ((Uint32)0x00000000) /* 0 */ +typedef uint32_t Uint32; + +/** + * \brief A signed 64-bit integer type. + */ +#define SDL_MAX_SINT64 ((Sint64)0x7FFFFFFFFFFFFFFFll) /* 9223372036854775807 */ +#define SDL_MIN_SINT64 ((Sint64)(~0x7FFFFFFFFFFFFFFFll)) /* -9223372036854775808 */ +typedef int64_t Sint64; +/** + * \brief An unsigned 64-bit integer type. + */ +#define SDL_MAX_UINT64 ((Uint64)0xFFFFFFFFFFFFFFFFull) /* 18446744073709551615 */ +#define SDL_MIN_UINT64 ((Uint64)(0x0000000000000000ull)) /* 0 */ +typedef uint64_t Uint64; + +/* @} *//* Basic data types */ + +/** + * \name Floating-point constants + */ +/* @{ */ + +#ifdef FLT_EPSILON +#define SDL_FLT_EPSILON FLT_EPSILON +#else +#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */ +#endif + +/* @} *//* Floating-point constants */ + +/* Make sure we have macros for printing width-based integers. + * should define these but this is not true all platforms. + * (for example win32) */ +#ifndef SDL_PRIs64 +#ifdef PRIs64 +#define SDL_PRIs64 PRIs64 +#elif defined(__WIN32__) || defined(__GDK__) +#define SDL_PRIs64 "I64d" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIs64 "ld" +#else +#define SDL_PRIs64 "lld" +#endif +#endif +#ifndef SDL_PRIu64 +#ifdef PRIu64 +#define SDL_PRIu64 PRIu64 +#elif defined(__WIN32__) || defined(__GDK__) +#define SDL_PRIu64 "I64u" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIu64 "lu" +#else +#define SDL_PRIu64 "llu" +#endif +#endif +#ifndef SDL_PRIx64 +#ifdef PRIx64 +#define SDL_PRIx64 PRIx64 +#elif defined(__WIN32__) || defined(__GDK__) +#define SDL_PRIx64 "I64x" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIx64 "lx" +#else +#define SDL_PRIx64 "llx" +#endif +#endif +#ifndef SDL_PRIX64 +#ifdef PRIX64 +#define SDL_PRIX64 PRIX64 +#elif defined(__WIN32__) || defined(__GDK__) +#define SDL_PRIX64 "I64X" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIX64 "lX" +#else +#define SDL_PRIX64 "llX" +#endif +#endif +#ifndef SDL_PRIs32 +#ifdef PRId32 +#define SDL_PRIs32 PRId32 +#else +#define SDL_PRIs32 "d" +#endif +#endif +#ifndef SDL_PRIu32 +#ifdef PRIu32 +#define SDL_PRIu32 PRIu32 +#else +#define SDL_PRIu32 "u" +#endif +#endif +#ifndef SDL_PRIx32 +#ifdef PRIx32 +#define SDL_PRIx32 PRIx32 +#else +#define SDL_PRIx32 "x" +#endif +#endif +#ifndef SDL_PRIX32 +#ifdef PRIX32 +#define SDL_PRIX32 PRIX32 +#else +#define SDL_PRIX32 "X" +#endif +#endif + +/* Annotations to help code analysis tools */ +#ifdef SDL_DISABLE_ANALYZE_MACROS +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#else +#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ +#include + +#define SDL_IN_BYTECAP(x) _In_bytecount_(x) +#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x) +#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x) +#define SDL_OUT_CAP(x) _Out_cap_(x) +#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x) +#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x) + +#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_ +#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_ +#else +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#endif +#if defined(__GNUC__) +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) +#else +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#endif +#endif /* SDL_DISABLE_ANALYZE_MACROS */ + +#ifndef SDL_COMPILE_TIME_ASSERT +#if defined(__cplusplus) +#if (__cplusplus >= 201103L) +#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) +#endif +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x) +#endif +#endif /* !SDL_COMPILE_TIME_ASSERT */ + +#ifndef SDL_COMPILE_TIME_ASSERT +/* universal, but may trigger -Wunused-local-typedefs */ +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] +#endif + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#if !defined(__ANDROID__) && !defined(__VITA__) + /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ +typedef enum +{ + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); +extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); +extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); +extern DECLSPEC void SDLCALL SDL_free(void *mem); + +typedef void *(SDLCALL *SDL_malloc_func)(size_t size); +typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); +typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); +typedef void (SDLCALL *SDL_free_func)(void *mem); + +/** + * Get the original set of SDL memory functions + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * Get the current set of SDL memory functions + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * Replace SDL's memory allocation functions with a custom set + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func); + +/** + * Get the number of outstanding (unfreed) allocations + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); + +extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); + +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); +extern DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); + +extern DECLSPEC int SDLCALL SDL_abs(int x); + +/* NOTE: these double-evaluate their arguments, so you should never have side effects in the parameters */ +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) +#define SDL_clamp(x, a, b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x))) + +extern DECLSPEC int SDLCALL SDL_isalpha(int x); +extern DECLSPEC int SDLCALL SDL_isalnum(int x); +extern DECLSPEC int SDLCALL SDL_isblank(int x); +extern DECLSPEC int SDLCALL SDL_iscntrl(int x); +extern DECLSPEC int SDLCALL SDL_isdigit(int x); +extern DECLSPEC int SDLCALL SDL_isxdigit(int x); +extern DECLSPEC int SDLCALL SDL_ispunct(int x); +extern DECLSPEC int SDLCALL SDL_isspace(int x); +extern DECLSPEC int SDLCALL SDL_isupper(int x); +extern DECLSPEC int SDLCALL SDL_islower(int x); +extern DECLSPEC int SDLCALL SDL_isprint(int x); +extern DECLSPEC int SDLCALL SDL_isgraph(int x); +extern DECLSPEC int SDLCALL SDL_toupper(int x); +extern DECLSPEC int SDLCALL SDL_tolower(int x); + +extern DECLSPEC Uint16 SDLCALL SDL_crc16(Uint16 crc, const void *data, size_t len); +extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); + +#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) +#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) +#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) + +#define SDL_copyp(dst, src) \ + { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \ + SDL_memcpy((dst), (src), sizeof (*(src))) + + +/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ +SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) +{ +#ifdef __APPLE__ + memset_pattern4(dst, &val, dwords * 4); +#elif defined(__GNUC__) && defined(__i386__) + int u0, u1, u2; + __asm__ __volatile__ ( + "cld \n\t" + "rep ; stosl \n\t" + : "=&D" (u0), "=&a" (u1), "=&c" (u2) + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords)) + : "memory" + ); +#else + size_t _n = (dwords + 3) / 4; + Uint32 *_p = SDL_static_cast(Uint32 *, dst); + Uint32 _val = (val); + if (dwords == 0) { + return; + } + switch (dwords % 4) { + case 0: do { *_p++ = _val; SDL_FALLTHROUGH; + case 3: *_p++ = _val; SDL_FALLTHROUGH; + case 2: *_p++ = _val; SDL_FALLTHROUGH; + case 1: *_p++ = _val; + } while ( --_n ); + } +#endif +} + +extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); + +extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr); +extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr); +extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle); + +extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2); +extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_wcscasecmp(const wchar_t *str1, const wchar_t *str2); +extern DECLSPEC int SDLCALL SDL_wcsncasecmp(const wchar_t *str1, const wchar_t *str2, size_t len); + +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes); +extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC char *SDLCALL SDL_strdup(const char *str); +extern DECLSPEC char *SDLCALL SDL_strrev(char *str); +extern DECLSPEC char *SDLCALL SDL_strupr(char *str); +extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); +extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); +extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr); +extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes); + +extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix); + +extern DECLSPEC int SDLCALL SDL_atoi(const char *str); +extern DECLSPEC double SDLCALL SDL_atof(const char *str); +extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base); +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base); +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base); +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base); +extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp); + +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); + +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); +extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, const char *fmt, va_list ap); + +#ifndef HAVE_M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 /**< pi */ +#endif +#endif + +/** + * Use this function to compute arc cosine of `x`. + * + * The definition of `y = acos(x)` is `x = cos(y)`. + * + * Domain: `-1 <= x <= 1` + * + * Range: `0 <= y <= Pi` + * + * \param x floating point value, in radians. + * \returns arc cosine of `x`. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC double SDLCALL SDL_acos(double x); +extern DECLSPEC float SDLCALL SDL_acosf(float x); +extern DECLSPEC double SDLCALL SDL_asin(double x); +extern DECLSPEC float SDLCALL SDL_asinf(float x); +extern DECLSPEC double SDLCALL SDL_atan(double x); +extern DECLSPEC float SDLCALL SDL_atanf(float x); +extern DECLSPEC double SDLCALL SDL_atan2(double y, double x); +extern DECLSPEC float SDLCALL SDL_atan2f(float y, float x); +extern DECLSPEC double SDLCALL SDL_ceil(double x); +extern DECLSPEC float SDLCALL SDL_ceilf(float x); +extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); +extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y); +extern DECLSPEC double SDLCALL SDL_cos(double x); +extern DECLSPEC float SDLCALL SDL_cosf(float x); +extern DECLSPEC double SDLCALL SDL_exp(double x); +extern DECLSPEC float SDLCALL SDL_expf(float x); +extern DECLSPEC double SDLCALL SDL_fabs(double x); +extern DECLSPEC float SDLCALL SDL_fabsf(float x); +extern DECLSPEC double SDLCALL SDL_floor(double x); +extern DECLSPEC float SDLCALL SDL_floorf(float x); +extern DECLSPEC double SDLCALL SDL_trunc(double x); +extern DECLSPEC float SDLCALL SDL_truncf(float x); +extern DECLSPEC double SDLCALL SDL_fmod(double x, double y); +extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y); +extern DECLSPEC double SDLCALL SDL_log(double x); +extern DECLSPEC float SDLCALL SDL_logf(float x); +extern DECLSPEC double SDLCALL SDL_log10(double x); +extern DECLSPEC float SDLCALL SDL_log10f(float x); +extern DECLSPEC double SDLCALL SDL_pow(double x, double y); +extern DECLSPEC float SDLCALL SDL_powf(float x, float y); +extern DECLSPEC double SDLCALL SDL_round(double x); +extern DECLSPEC float SDLCALL SDL_roundf(float x); +extern DECLSPEC long SDLCALL SDL_lround(double x); +extern DECLSPEC long SDLCALL SDL_lroundf(float x); +extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); +extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n); +extern DECLSPEC double SDLCALL SDL_sin(double x); +extern DECLSPEC float SDLCALL SDL_sinf(float x); +extern DECLSPEC double SDLCALL SDL_sqrt(double x); +extern DECLSPEC float SDLCALL SDL_sqrtf(float x); +extern DECLSPEC double SDLCALL SDL_tan(double x); +extern DECLSPEC float SDLCALL SDL_tanf(float x); + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +/* SDL_iconv_* are now always real symbols/types, not macros or inlined. */ +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, + const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, + size_t * inbytesleft, char **outbuf, + size_t * outbytesleft); + +/** + * This function converts a string between encodings in one pass, returning a + * string that must be freed with SDL_free() or NULL on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, + const char *fromcode, + const char *inbuf, + size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t)) + +/* force builds using Clang's static analysis tools to use literal C runtime + here, since there are possibly tests that are ineffective otherwise. */ +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) + +/* The analyzer knows about strlcpy even when the system doesn't provide it */ +#ifndef HAVE_STRLCPY +size_t strlcpy(char* dst, const char* src, size_t size); +#endif + +/* The analyzer knows about strlcat even when the system doesn't provide it */ +#ifndef HAVE_STRLCAT +size_t strlcat(char* dst, const char* src, size_t size); +#endif + +#define SDL_malloc malloc +#define SDL_calloc calloc +#define SDL_realloc realloc +#define SDL_free free +#define SDL_memset memset +#define SDL_memcpy memcpy +#define SDL_memmove memmove +#define SDL_memcmp memcmp +#define SDL_strlcpy strlcpy +#define SDL_strlcat strlcat +#define SDL_strlen strlen +#define SDL_wcslen wcslen +#define SDL_wcslcpy wcslcpy +#define SDL_wcslcat wcslcat +#define SDL_strdup strdup +#define SDL_wcsdup wcsdup +#define SDL_strchr strchr +#define SDL_strrchr strrchr +#define SDL_strstr strstr +#define SDL_wcsstr wcsstr +#define SDL_strtokr strtok_r +#define SDL_strcmp strcmp +#define SDL_wcscmp wcscmp +#define SDL_strncmp strncmp +#define SDL_wcsncmp wcsncmp +#define SDL_strcasecmp strcasecmp +#define SDL_strncasecmp strncasecmp +#define SDL_sscanf sscanf +#define SDL_vsscanf vsscanf +#define SDL_snprintf snprintf +#define SDL_vsnprintf vsnprintf +#endif + +SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords) +{ + return SDL_memcpy(dst, src, dwords * 4); +} + +/** + * If a * b would overflow, return -1. Otherwise store a * b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (a != 0 && b > SDL_SIZE_MAX / a) { + return -1; + } + *ret = a * b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_mul_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * because __builtin_mul_overflow() is type-generic, but we want to be + * consistent about interpreting a and b as size_t. */ +SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_mul_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_mul_overflow(a, b, ret) (_SDL_size_mul_overflow_builtin(a, b, ret)) +#endif + +/** + * If a + b would overflow, return -1. Otherwise store a + b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (b > SDL_SIZE_MAX - a) { + return -1; + } + *ret = a + b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_add_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * the same as the call to __builtin_mul_overflow() above. */ +SDL_FORCE_INLINE int _SDL_size_add_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_add_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_add_overflow(a, b, ret) (_SDL_size_add_overflow_builtin(a, b, ret)) +#endif + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_stdinc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_surface.h b/thirdparty/SDL/include/SDL/SDL_surface.h new file mode 100644 index 00000000..838de654 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_surface.h @@ -0,0 +1,997 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_surface.h + * + * Header file for ::SDL_Surface definition and management functions. + */ + +#ifndef SDL_surface_h_ +#define SDL_surface_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_blendmode.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Surface flags + * + * These are the currently supported flags for the ::SDL_Surface. + * + * \internal + * Used internally (read-only). + */ +/* @{ */ +#define SDL_SWSURFACE 0 /**< Just here for compatibility */ +#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ +#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ +#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ +#define SDL_SIMD_ALIGNED 0x00000008 /**< Surface uses aligned memory */ +/* @} *//* Surface flags */ + +/** + * Evaluates to true if the surface needs to be locked before access. + */ +#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) + +typedef struct SDL_BlitMap SDL_BlitMap; /* this is an opaque type. */ + +/** + * \brief A collection of pixels used in software blitting. + * + * \note This structure should be treated as read-only, except for \c pixels, + * which, if not NULL, contains the raw pixel data for the surface. + */ +typedef struct SDL_Surface +{ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + int pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + + /** Application data associated with the surface */ + void *userdata; /**< Read-write */ + + /** information needed for surfaces requiring locks */ + int locked; /**< Read-only */ + + /** list of BlitMap that hold a reference to this surface */ + void *list_blitmap; /**< Private */ + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + + /** info for fast blit mapping to other surfaces */ + SDL_BlitMap *map; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ +} SDL_Surface; + +/** + * \brief The type of function used for surface blitting functions. + */ +typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, + struct SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief The formula used for converting between YUV and RGB + */ +typedef enum +{ + SDL_YUV_CONVERSION_JPEG, /**< Full range JPEG */ + SDL_YUV_CONVERSION_BT601, /**< BT.601 (the default) */ + SDL_YUV_CONVERSION_BT709, /**< BT.709 */ + SDL_YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */ +} SDL_YUV_CONVERSION_MODE; + +/** + * Allocate a new RGB surface. + * + * If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. + * If `depth` is greater than 8 bits, the pixel format is set using the + * [RGBA]mask parameters. + * + * The [RGBA]mask parameters are the bitmasks used to extract that color from + * a pixel. For instance, `Rmask` being 0xFF000000 means the red data is + * stored in the most significant byte. Using zeros for the RGB masks sets a + * default value, based on the depth. For example: + * + * ```c++ + * SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); + * ``` + * + * However, using zero for the Amask results in an Amask of 0. + * + * By default surfaces with an alpha mask are set up for blending as with: + * + * ```c++ + * SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) + * ``` + * + * You can change this by calling SDL_SetSurfaceBlendMode() and selecting a + * different `blendMode`. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with a specific pixel format. + * + * This function operates mostly like SDL_CreateRGBSurface(), except instead + * of providing pixel color masks, you provide it with a predefined format + * from SDL_PixelFormatEnum. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); + +/** + * Allocate a new RGB surface with existing pixel data. + * + * This function operates mostly like SDL_CreateRGBSurface(), except it does + * not allocate memory for the pixel data, instead the caller provides an + * existing buffer of data for the surface to use. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, + int height, + int depth, + int pitch, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with with a specific pixel format and existing + * pixel data. + * + * This function operates mostly like SDL_CreateRGBSurfaceFrom(), except + * instead of providing pixel color masks, you provide it with a predefined + * format from SDL_PixelFormatEnum. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); + +/** + * Free an RGB surface. + * + * It is safe to pass NULL to this function. + * + * \param surface the SDL_Surface to free. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_LoadBMP + * \sa SDL_LoadBMP_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); + +/** + * Set the palette used by a surface. + * + * A single palette can be shared with many surfaces. + * + * \param surface the SDL_Surface structure to update + * \param palette the SDL_Palette structure to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, + SDL_Palette * palette); + +/** + * Set up a surface for directly accessing the pixels. + * + * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to + * and read from `surface->pixels`, using the pixel format stored in + * `surface->format`. Once you are done accessing the surface, you should use + * SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to + * 0, then you can read and write to the surface at any time, and the pixel + * format of the surface will not change. + * + * \param surface the SDL_Surface structure to be locked + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MUSTLOCK + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); + +/** + * Release a surface after directly accessing the pixels. + * + * \param surface the SDL_Surface structure to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockSurface + */ +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); + +/** + * Load a BMP image from a seekable SDL data stream. + * + * The new surface should be freed with SDL_FreeSurface(). Not doing so will + * result in a memory leak. + * + * src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. + * Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap + * from a file, convert it to an SDL_Surface and then close the file. + * + * \param src the data stream for the surface + * \param freesrc non-zero to close the stream after being read + * \returns a pointer to a new SDL_Surface structure or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeSurface + * \sa SDL_RWFromFile + * \sa SDL_LoadBMP + * \sa SDL_SaveBMP_RW + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, + int freesrc); + +/** + * Load a surface from a file. + * + * Convenience macro. + */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Save a surface to a seekable SDL data stream in BMP format. + * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * + * \param surface the SDL_Surface structure containing the image to be saved + * \param dst a data stream to save to + * \param freedst non-zero to close the stream after being written + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadBMP_RW + * \sa SDL_SaveBMP + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface * surface, SDL_RWops * dst, int freedst); + +/** + * Save a surface to a file. + * + * Convenience macro. + */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/** + * Set the RLE acceleration hint for a surface. + * + * If RLE is enabled, color key and alpha blending blits are much faster, but + * the surface must be locked before directly accessing the pixels. + * + * \param surface the SDL_Surface structure to optimize + * \param flag 0 to disable, non-zero to enable RLE acceleration + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_LockSurface + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, + int flag); + +/** + * Returns whether the surface is RLE enabled + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SetSurfaceRLE + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSurfaceRLE(SDL_Surface * surface); + +/** + * Set the color key (transparent pixel) in a surface. + * + * The color key defines a pixel value that will be treated as transparent in + * a blit. For example, one can use this to specify that cyan pixels should be + * considered transparent, and therefore not rendered. + * + * It is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * RLE acceleration can substantially speed up blitting of images with large + * horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. + * + * \param surface the SDL_Surface structure to update + * \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key + * \param key the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetColorKey + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, + int flag, Uint32 key); + +/** + * Returns whether the surface has a color key + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_SetColorKey + * \sa SDL_GetColorKey + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface); + +/** + * Get the color key (transparent pixel) for a surface. + * + * The color key is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * If the surface doesn't have color key enabled this function returns -1. + * + * \param surface the SDL_Surface structure to query + * \param key a pointer filled in with the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetColorKey + */ +extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, + Uint32 * key); + +/** + * Set an additional color value multiplied into blit operations. + * + * When this surface is blitted, during the blit operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * \param surface the SDL_Surface structure to update + * \param r the red color value multiplied into blit operations + * \param g the green color value multiplied into blit operations + * \param b the blue color value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into blit operations. + * + * \param surface the SDL_Surface structure to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value used in blit operations. + * + * When this surface is blitted, during the blit operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * \param surface the SDL_Surface structure to update + * \param alpha the alpha value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 alpha); + +/** + * Get the additional alpha value used in blit operations. + * + * \param surface the SDL_Surface structure to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 * alpha); + +/** + * Set the blend mode used for blit operations. + * + * To copy a surface to another surface (or texture) without blending with the + * existing data, the blendmode of the SOURCE surface should be set to + * `SDL_BLENDMODE_NONE`. + * + * \param surface the SDL_Surface structure to update + * \param blendMode the SDL_BlendMode to use for blit blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for blit operations. + * + * \param surface the SDL_Surface structure to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode *blendMode); + +/** + * Set the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * Note that blits are automatically clipped to the edges of the source and + * destination surfaces. + * + * \param surface the SDL_Surface structure to be clipped + * \param rect the SDL_Rect structure representing the clipping rectangle, or + * NULL to disable clipping + * \returns SDL_TRUE if the rectangle intersects the surface, otherwise + * SDL_FALSE and blits will be completely clipped. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, + const SDL_Rect * rect); + +/** + * Get the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * \param surface the SDL_Surface structure representing the surface to be + * clipped + * \param rect an SDL_Rect structure filled in with the clipping rectangle for + * the surface + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetClipRect + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, + SDL_Rect * rect); + +/* + * Creates a new surface identical to the existing surface. + * + * The returned surface should be freed with SDL_FreeSurface(). + * + * \param surface the surface to duplicate. + * \returns a copy of the surface, or NULL on failure; call SDL_GetError() for + * more information. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_DuplicateSurface(SDL_Surface * surface); + +/** + * Copy an existing surface to a new surface of the specified format. + * + * This function is used to optimize images for faster *repeat* blitting. This + * is accomplished by converting the original and storing the result as a new + * surface. The new, optimized surface can then be used as the source for + * future blits, making them faster. + * + * \param src the existing SDL_Surface structure to convert + * \param fmt the SDL_PixelFormat structure that the new surface is optimized + * for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurfaceFormat + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface + (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); + +/** + * Copy an existing surface to a new surface of the specified format enum. + * + * This function operates just like SDL_ConvertSurface(), but accepts an + * SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, + * it might be easier to call but it doesn't have access to palette + * information for the destination surface, in case that would be important. + * + * \param src the existing SDL_Surface structure to convert + * \param pixel_format the SDL_PixelFormatEnum that the new surface is + * optimized for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurface + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat + (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); + +/** + * Copy a block of pixels of one format to another format. + * + * \param width the width of the block to copy, in pixels + * \param height the height of the block to copy, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with new pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Premultiply the alpha on a block of pixels. + * + * This is safe to use with src == dst, but not for other overlapping areas. + * + * This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. + * + * \param width the width of the block to convert, in pixels + * \param height the height of the block to convert, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with premultiplied pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_PremultiplyAlpha(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Perform a fast fill of a rectangle with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL to fill the entire surface + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRects + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); + +/** + * Perform a fast fill of a set of rectangles with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rects an array of SDL_Rects representing the rectangles to fill. + * \param count the number of rectangles in the array + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRect + */ +extern DECLSPEC int SDLCALL SDL_FillRects + (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); + +/* !!! FIXME: merge this documentation with the wiki */ +/** + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \returns 0 if the blit is successful, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + */ +#define SDL_BlitSurface SDL_UpperBlit + +/** + * Perform a fast blit from the source surface to the destination surface. + * + * SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a + * macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface blitting only. + * + * This is a semi-private blit function and it performs low-level surface + * blitting, assuming the input rectangles have already been clipped. + * + * Unless you know what you're doing, you should be using SDL_BlitSurface() + * instead. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied, or NULL to copy the entire surface + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + + +/** + * Perform a fast, low quality, stretch blit between two surfaces of the same + * format. + * + * Please use SDL_BlitScaled() instead. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + +/** + * Perform bilinear scaling between two surfaces of the same format, 32BPP. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + + +#define SDL_BlitScaled SDL_UpperBlitScaled + +/** + * Perform a scaled surface copy to a destination surface. + * + * SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is + * merely a macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_UpperBlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface scaled blitting only. + * + * This is a semi-private function and it performs low-level surface blitting, + * assuming the input rectangles have already been clipped. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_LowerBlitScaled + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Set the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode); + +/** + * Get the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void); + +/** + * Get the YUV conversion mode, returning the correct mode for the resolution + * when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_surface_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_system.h b/thirdparty/SDL/include/SDL/SDL_system.h new file mode 100644 index 00000000..0edca635 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_system.h @@ -0,0 +1,623 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef SDL_system_h_ +#define SDL_system_h_ + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#if defined(__WIN32__) || defined(__GDK__) + +typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); + +/** + * Set a callback for every Windows message, run before TranslateMessage(). + * + * \param callback The SDL_WindowsMessageHook function to call. + * \param userdata a pointer to pass to every iteration of `callback` + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +#if defined(__WIN32__) || defined(__WINGDK__) + +/** + * Get the D3D9 adapter index that matches the specified display index. + * + * The returned adapter index can be passed to `IDirect3D9::CreateDevice` and + * controls on which monitor a full screen application will appear. + * + * \param displayIndex the display index for which to get the D3D9 adapter + * index + * \returns the D3D9 adapter index on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +typedef struct IDirect3DDevice9 IDirect3DDevice9; + +/** + * Get the D3D9 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D device + * \returns the D3D9 device associated with given renderer or NULL if it is + * not a D3D9 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +typedef struct ID3D11Device ID3D11Device; + +/** + * Get the D3D11 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D11 device + * \returns the D3D11 device associated with given renderer or NULL if it is + * not a D3D11 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC ID3D11Device* SDLCALL SDL_RenderGetD3D11Device(SDL_Renderer * renderer); + +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +#if defined(__WIN32__) || defined(__GDK__) + +typedef struct ID3D12Device ID3D12Device; + +/** + * Get the D3D12 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D12 device + * \returns the D3D12 device associated with given renderer or NULL if it is + * not a D3D12 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC ID3D12Device* SDLCALL SDL_RenderGetD3D12Device(SDL_Renderer* renderer); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +#if defined(__WIN32__) || defined(__WINGDK__) + +/** + * Get the DXGI Adapter and Output indices for the specified display index. + * + * The DXGI Adapter and Output indices can be passed to `EnumAdapters` and + * `EnumOutputs` respectively to get the objects required to create a DX10 or + * DX11 device and swap chain. + * + * Before SDL 2.0.4 this function did not return a value. Since SDL 2.0.4 it + * returns an SDL_bool. + * + * \param displayIndex the display index for which to get both indices + * \param adapterIndex a pointer to be filled in with the adapter index + * \param outputIndex a pointer to be filled in with the output index + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); + +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +/* Platform specific functions for Linux */ +#ifdef __LINUX__ + +/** + * Sets the UNIX nice value for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID the Unix thread ID to change priority of. + * \param priority The new, Unix-specific, priority value. + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority); + +/** + * Sets the priority (not nice level) and scheduling policy for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID The Unix thread ID to change priority of. + * \param sdlPriority The new SDL_ThreadPriority value. + * \param schedPolicy The new scheduling policy (SCHED_FIFO, SCHED_RR, + * SCHED_OTHER, etc...) + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy); + +#endif /* __LINUX__ */ + +/* Platform specific functions for iOS */ +#ifdef __IPHONEOS__ + +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) + +/** + * Use this function to set the animation callback on Apple iOS. + * + * The function prototype for `callback` is: + * + * ```c + * void callback(void* callbackParam); + * ``` + * + * Where its parameter, `callbackParam`, is what was passed as `callbackParam` + * to SDL_iPhoneSetAnimationCallback(). + * + * This function is only available on Apple iOS. + * + * For more information see: + * https://github.com/libsdl-org/SDL/blob/main/docs/README-ios.md + * + * This functions is also accessible using the macro + * SDL_iOSSetAnimationCallback() since SDL 2.0.4. + * + * \param window the window for which the animation callback should be set + * \param interval the number of frames after which **callback** will be + * called + * \param callback the function to call for every frame. + * \param callbackParam a pointer that is passed to `callback`. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetEventPump + */ +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (SDLCALL *callback)(void*), void *callbackParam); + +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) + +/** + * Use this function to enable or disable the SDL event pump on Apple iOS. + * + * This function is only available on Apple iOS. + * + * This functions is also accessible using the macro SDL_iOSSetEventPump() + * since SDL 2.0.4. + * + * \param enabled SDL_TRUE to enable the event pump, SDL_FALSE to disable it + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetAnimationCallback + */ +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#ifdef __ANDROID__ + +/** + * Get the Android Java Native Interface Environment of the current thread. + * + * This is the JNIEnv one needs to access the Java virtual machine from native + * code, and is needed for many Android APIs to be usable from C. + * + * The prototype of the function in SDL's code actually declare a void* return + * type, even if the implementation returns a pointer to a JNIEnv. The + * rationale being that the SDL headers can avoid including jni.h. + * + * \returns a pointer to Java native interface object (JNIEnv) to which the + * current thread is attached, or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetActivity + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void); + +/** + * Retrieve the Java instance of the Android activity class. + * + * The prototype of the function in SDL's code actually declares a void* + * return type, even if the implementation returns a jobject. The rationale + * being that the SDL headers can avoid including jni.h. + * + * The jobject returned by the function is a local reference and must be + * released by the caller. See the PushLocalFrame() and PopLocalFrame() or + * DeleteLocalRef() functions of the Java native interface: + * + * https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html + * + * \returns the jobject representing the instance of the Activity class of the + * Android application, or NULL on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetJNIEnv + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void); + +/** + * Query Android API level of the current device. + * + * - API level 31: Android 12 + * - API level 30: Android 11 + * - API level 29: Android 10 + * - API level 28: Android 9 + * - API level 27: Android 8.1 + * - API level 26: Android 8.0 + * - API level 25: Android 7.1 + * - API level 24: Android 7.0 + * - API level 23: Android 6.0 + * - API level 22: Android 5.1 + * - API level 21: Android 5.0 + * - API level 20: Android 4.4W + * - API level 19: Android 4.4 + * - API level 18: Android 4.3 + * - API level 17: Android 4.2 + * - API level 16: Android 4.1 + * - API level 15: Android 4.0.3 + * - API level 14: Android 4.0 + * - API level 13: Android 3.2 + * - API level 12: Android 3.1 + * - API level 11: Android 3.0 + * - API level 10: Android 2.3.3 + * + * \returns the Android API level. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void); + +/** + * Query if the application is running on Android TV. + * + * \returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void); + +/** + * Query if the application is running on a Chromebook. + * + * \returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void); + +/** + * Query if the application is running on a Samsung DeX docking station. + * + * \returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); + +/** + * Trigger the Android system back button behavior. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void); + +/** + See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/** + * Get the path used for internal storage for this application. + * + * This path is unique to your application and cannot be written to by other + * applications. + * + * Your internal storage path is typically: + * `/data/data/your.app.package/files`. + * + * \returns the path used for internal storage or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void); + +/** + * Get the current state of external storage. + * + * The current state of external storage, a bitmask of these values: + * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`. + * + * If external storage is currently unavailable, this will return 0. + * + * \returns the current state of external storage on success or 0 on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStoragePath + */ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(void); + +/** + * Get the path used for external storage for this application. + * + * This path is unique to your application, but is public and can be written + * to by other applications. + * + * Your external storage path is typically: + * `/storage/sdcard0/Android/data/your.app.package/files`. + * + * \returns the path used for external storage for this application on success + * or NULL on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void); + +/** + * Request permissions at runtime. + * + * This blocks the calling thread until the permission is granted or denied. + * + * \param permission The permission to request. + * \returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AndroidRequestPermission(const char *permission); + +/** + * Shows an Android toast notification. + * + * Toasts are a sort of lightweight notification that are unique to Android. + * + * https://developer.android.com/guide/topics/ui/notifiers/toasts + * + * Shows toast in UI thread. + * + * For the `gravity` parameter, choose a value from here, or -1 if you don't + * have a preference: + * + * https://developer.android.com/reference/android/view/Gravity + * + * \param message text message to be shown + * \param duration 0=short, 1=long + * \param gravity where the notification should appear on the screen. + * \param xoffset set this parameter only when gravity >=0 + * \param yoffset set this parameter only when gravity >=0 + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int duration, int gravity, int xoffset, int yoffset); + +/** + * Send a user command to SDLActivity. + * + * Override "boolean onUnhandledMessage(Message msg)" to handle the message. + * + * \param command user command that must be greater or equal to 0x8000 + * \param param user parameter + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC int SDLCALL SDL_AndroidSendMessage(Uint32 command, int param); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#ifdef __WINRT__ + +/** + * \brief WinRT / Windows Phone path types + */ +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, + + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, + + /** \brief The app's roaming data store. Unsupported on Windows Phone. + Files written here may be copied to other machines via a network + connection. + */ + SDL_WINRT_PATH_ROAMING_FOLDER, + + /** \brief The app's temporary data store. Unsupported on Windows Phone. + Files written here may be deleted at any time. */ + SDL_WINRT_PATH_TEMP_FOLDER +} SDL_WinRT_Path; + + +/** + * \brief WinRT Device Family + */ +typedef enum +{ + /** \brief Unknown family */ + SDL_WINRT_DEVICEFAMILY_UNKNOWN, + + /** \brief Desktop family*/ + SDL_WINRT_DEVICEFAMILY_DESKTOP, + + /** \brief Mobile family (for example smartphone) */ + SDL_WINRT_DEVICEFAMILY_MOBILE, + + /** \brief XBox family */ + SDL_WINRT_DEVICEFAMILY_XBOX, +} SDL_WinRT_DeviceFamily; + + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UCS-2 string (16-bit, wide-char) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUTF8 + */ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UTF-8 string (8-bit, multi-byte) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUNICODE + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); + +/** + * Detects the device family of WinRT platform at runtime. + * + * \returns a value from the SDL_WinRT_DeviceFamily enum. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); + +#endif /* __WINRT__ */ + +/** + * Query if the current device is a tablet. + * + * If SDL can't determine this, it will return SDL_FALSE. + * + * \returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void); + +/* Functions used by iOS application delegates to notify SDL about state changes */ +extern DECLSPEC void SDLCALL SDL_OnApplicationWillTerminate(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidReceiveMemoryWarning(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillResignActive(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidEnterBackground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillEnterForeground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidBecomeActive(void); +#ifdef __IPHONEOS__ +extern DECLSPEC void SDLCALL SDL_OnApplicationDidChangeStatusBarOrientation(void); +#endif + +/* Functions used only by GDK */ +#if defined(__GDK__) +typedef struct XTaskQueueObject * XTaskQueueHandle; + +/** + * Gets a reference to the global async task queue handle for GDK, + * initializing if needed. + * + * Once you are done with the task queue, you should call + * XTaskQueueCloseHandle to reduce the reference count to avoid a resource + * leak. + * + * \param outTaskQueue a pointer to be filled in with task queue handle. + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_GDKGetTaskQueue(XTaskQueueHandle * outTaskQueue); + +#endif + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_system_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_syswm.h b/thirdparty/SDL/include/SDL/SDL_syswm.h new file mode 100644 index 00000000..45f8e754 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_syswm.h @@ -0,0 +1,386 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_syswm.h + * + * Include file for SDL custom system window manager hooks. + */ + +#ifndef SDL_syswm_h_ +#define SDL_syswm_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_version.h" + +/** + * \brief SDL_syswm.h + * + * Your application has access to a special type of event ::SDL_SYSWMEVENT, + * which contains window-manager specific information and arrives whenever + * an unhandled window event occurs. This event is ignored by default, but + * you can enable it with SDL_EventState(). + */ +struct SDL_SysWMinfo; + +#if !defined(SDL_PROTOTYPES_ONLY) + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + +/* This is the structure for custom window manager events */ +#if defined(SDL_VIDEO_DRIVER_X11) +#if defined(__APPLE__) && defined(__MACH__) +/* conflicts with Quickdraw.h */ +#define Cursor X11Cursor +#endif + +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +/* matches the re-define above */ +#undef Cursor +#endif + +#endif /* defined(SDL_VIDEO_DRIVER_X11) */ + +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_COCOA) +#ifdef __OBJC__ +@class NSWindow; +#else +typedef struct _NSWindow NSWindow; +#endif +#endif + +#if defined(SDL_VIDEO_DRIVER_UIKIT) +#ifdef __OBJC__ +#include +#else +typedef struct _UIWindow UIWindow; +typedef struct _UIViewController UIViewController; +#endif +typedef Uint32 GLuint; +#endif + +#if defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL) +#define SDL_METALVIEW_TAG 255 +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) +typedef struct ANativeWindow ANativeWindow; +typedef void *EGLSurface; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) +#include "SDL_egl.h" +#endif + +#if defined(SDL_VIDEO_DRIVER_OS2) +#define INCL_WIN +#include +#endif +#endif /* SDL_PROTOTYPES_ONLY */ + +#if defined(SDL_VIDEO_DRIVER_KMSDRM) +struct gbm_device; +#endif + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(SDL_PROTOTYPES_ONLY) +/** + * These are the various supported windowing subsystems + */ +typedef enum +{ + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE, + SDL_SYSWM_OS2, + SDL_SYSWM_HAIKU, + SDL_SYSWM_KMSDRM, + SDL_SYSWM_RISCOS +} SDL_SYSWM_TYPE; + +/** + * The custom event structure. + */ +struct SDL_SysWMmsg +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct { + HWND hwnd; /**< The window for the message */ + UINT msg; /**< The type of message */ + WPARAM wParam; /**< WORD message parameter */ + LPARAM lParam; /**< LONG message parameter */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct { + XEvent event; + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct { + DFBEvent event; + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { + /* Latest version of Xcode clang complains about empty structs in C v. C++: + error: empty struct has size 0 in C, size 1 in C++ + */ + int dummy; + /* No Cocoa window events yet */ + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { + int dummy; + /* No UIKit window events yet */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + int dummy; + /* No Vivante window events yet */ + } vivante; +#endif +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + BOOL fFrame; /**< TRUE if hwnd is a frame window */ + HWND hwnd; /**< The window receiving the message */ + ULONG msg; /**< The message identifier */ + MPARAM mp1; /**< The first first message parameter */ + MPARAM mp2; /**< The second first message parameter */ + } os2; +#endif + /* Can't have an empty union */ + int dummy; + } msg; +}; + +/** + * The custom window manager information structure. + * + * When this structure is returned, it holds information about which + * low level system it is using, and will be one of SDL_SYSWM_TYPE. + */ +struct SDL_SysWMinfo +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct + { + HWND window; /**< The window handle */ + HDC hdc; /**< The window device context */ + HINSTANCE hinstance; /**< The instance handle */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + struct + { + IInspectable * window; /**< The WinRT CoreWindow */ + } winrt; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct + { + Display *display; /**< The X11 display */ + Window window; /**< The X11 window */ + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct + { + IDirectFB *dfb; /**< The directfb main interface */ + IDirectFBWindow *window; /**< The directfb window handle */ + IDirectFBSurface *surface; /**< The directfb client surface */ + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) + NSWindow __unsafe_unretained *window; /**< The Cocoa window */ + #else + NSWindow *window; /**< The Cocoa window */ + #endif +#else + NSWindow *window; /**< The Cocoa window */ +#endif + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) + UIWindow __unsafe_unretained *window; /**< The UIKit window */ + #else + UIWindow *window; /**< The UIKit window */ + #endif +#else + UIWindow *window; /**< The UIKit window */ +#endif + GLuint framebuffer; /**< The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. */ + GLuint colorbuffer; /**< The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. */ + GLuint resolveFramebuffer; /**< The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + struct + { + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ + void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */ + struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ + struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */ + struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */ + struct xdg_popup *xdg_popup; /**< Wayland xdg popup role */ + struct xdg_positioner *xdg_positioner; /**< Wayland xdg positioner, for popup */ + } wl; +#endif +#if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + struct + { + void *connection; /**< Mir display server connection */ + void *surface; /**< Mir surface */ + } mir; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) + struct + { + ANativeWindow *window; + EGLSurface surface; + } android; +#endif + +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + HWND hwnd; /**< The window handle */ + HWND hwndFrame; /**< The frame window handle */ + } os2; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + EGLNativeDisplayType display; + EGLNativeWindowType window; + } vivante; +#endif + +#if defined(SDL_VIDEO_DRIVER_KMSDRM) + struct + { + int dev_index; /**< Device index (ex: the X in /dev/dri/cardX) */ + int drm_fd; /**< DRM FD (unavailable on Vulkan windows) */ + struct gbm_device *gbm_dev; /**< GBM device (unavailable on Vulkan windows) */ + } kmsdrm; +#endif + + /* Make sure this union is always 64 bytes (8 64-bit pointers). */ + /* Be careful not to overflow this if you add a new target! */ + Uint8 dummy[64]; + } info; +}; + +#endif /* SDL_PROTOTYPES_ONLY */ + +typedef struct SDL_SysWMinfo SDL_SysWMinfo; + + +/** + * Get driver-specific information about a window. + * + * You must include SDL_syswm.h for the declaration of SDL_SysWMinfo. + * + * The caller must initialize the `info` structure's version by using + * `SDL_VERSION(&info.version)`, and then this function will fill in the rest + * of the structure with information about the given window. + * + * \param window the window about which information is being requested + * \param info an SDL_SysWMinfo structure filled in with window information + * \returns SDL_TRUE if the function is implemented and the `version` member + * of the `info` struct is valid, or SDL_FALSE if the information + * could not be retrieved; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, + SDL_SysWMinfo * info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_syswm_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test.h b/thirdparty/SDL/include/SDL/SDL_test.h new file mode 100644 index 00000000..8cc9d616 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_h_ +#define SDL_test_h_ + +#include "SDL.h" +#include "SDL_test_assert.h" +#include "SDL_test_common.h" +#include "SDL_test_compare.h" +#include "SDL_test_crc32.h" +#include "SDL_test_font.h" +#include "SDL_test_fuzzer.h" +#include "SDL_test_harness.h" +#include "SDL_test_images.h" +#include "SDL_test_log.h" +#include "SDL_test_md5.h" +#include "SDL_test_memory.h" +#include "SDL_test_random.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Global definitions */ + +/* + * Note: Maximum size of SDLTest log message is less than SDL's limit + * to ensure we can fit additional information such as the timestamp. + */ +#define SDLTEST_MAX_LOGMESSAGE_LENGTH 3584 + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_assert.h b/thirdparty/SDL/include/SDL/SDL_test_assert.h new file mode 100644 index 00000000..73423052 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_assert.h @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_assert.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Assert API for test code and test cases + * + */ + +#ifndef SDL_test_assert_h_ +#define SDL_test_assert_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Fails the assert. + */ +#define ASSERT_FAIL 0 + +/** + * \brief Passes the assert. + */ +#define ASSERT_PASS 1 + +/** + * \brief Assert that logs and break execution flow on failures. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Assert for test cases that logs but does not break execution flow on failures. Updates assertion counters. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + * + * \returns the assertCondition so it can be used to externally to break execution flow if desired. + */ +int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Explicitly pass without checking an assertion condition. Updates assertion counter. + * + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Resets the assert summary counters to zero. + */ +void SDLTest_ResetAssertSummary(void); + +/** + * \brief Logs summary of all assertions (total, pass, fail) since last reset as INFO or ERROR. + */ +void SDLTest_LogAssertSummary(void); + + +/** + * \brief Converts the current assert summary state to a test result. + * + * \returns TEST_RESULT_PASSED, TEST_RESULT_FAILED, or TEST_RESULT_NO_ASSERT + */ +int SDLTest_AssertSummaryToTestResult(void); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_assert_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_common.h b/thirdparty/SDL/include/SDL/SDL_test_common.h new file mode 100644 index 00000000..b86520d3 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_common.h @@ -0,0 +1,236 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_common.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* Ported from original test\common.h file. */ + +#ifndef SDL_test_common_h_ +#define SDL_test_common_h_ + +#include "SDL.h" + +#if defined(__PSP__) +#define DEFAULT_WINDOW_WIDTH 480 +#define DEFAULT_WINDOW_HEIGHT 272 +#elif defined(__VITA__) +#define DEFAULT_WINDOW_WIDTH 960 +#define DEFAULT_WINDOW_HEIGHT 544 +#else +#define DEFAULT_WINDOW_WIDTH 640 +#define DEFAULT_WINDOW_HEIGHT 480 +#endif + +#define VERBOSE_VIDEO 0x00000001 +#define VERBOSE_MODES 0x00000002 +#define VERBOSE_RENDER 0x00000004 +#define VERBOSE_EVENT 0x00000008 +#define VERBOSE_AUDIO 0x00000010 +#define VERBOSE_MOTION 0x00000020 + +typedef struct +{ + /* SDL init flags */ + char **argv; + Uint32 flags; + Uint32 verbose; + + /* Video info */ + const char *videodriver; + int display; + const char *window_title; + const char *window_icon; + Uint32 window_flags; + SDL_bool flash_on_focus_loss; + int window_x; + int window_y; + int window_w; + int window_h; + int window_minW; + int window_minH; + int window_maxW; + int window_maxH; + int logical_w; + int logical_h; + float scale; + int depth; + int refresh_rate; + int num_windows; + SDL_Window **windows; + + /* Renderer info */ + const char *renderdriver; + Uint32 render_flags; + SDL_bool skip_renderer; + SDL_Renderer **renderers; + SDL_Texture **targets; + + /* Audio info */ + const char *audiodriver; + SDL_AudioSpec audiospec; + + /* GL settings */ + int gl_red_size; + int gl_green_size; + int gl_blue_size; + int gl_alpha_size; + int gl_buffer_size; + int gl_depth_size; + int gl_stencil_size; + int gl_double_buffer; + int gl_accum_red_size; + int gl_accum_green_size; + int gl_accum_blue_size; + int gl_accum_alpha_size; + int gl_stereo; + int gl_multisamplebuffers; + int gl_multisamplesamples; + int gl_retained_backing; + int gl_accelerated; + int gl_major_version; + int gl_minor_version; + int gl_debug; + int gl_profile_mask; + + /* Additional fields added in 2.0.18 */ + SDL_Rect confine; + +} SDLTest_CommonState; + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * \brief Parse command line parameters and create common state. + * + * \param argv Array of command line parameters + * \param flags Flags indicating which subsystem to initialize (i.e. SDL_INIT_VIDEO | SDL_INIT_AUDIO) + * + * \returns a newly allocated common state object. + */ +SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); + +/** + * \brief Process one common argument. + * + * \param state The common state describing the test window to create. + * \param index The index of the argument to process in argv[]. + * + * \returns the number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. + */ +int SDLTest_CommonArg(SDLTest_CommonState * state, int index); + + +/** + * \brief Logs command line usage info. + * + * This logs the appropriate command line options for the subsystems in use + * plus other common options, and then any application-specific options. + * This uses the SDL_Log() function and splits up output to be friendly to + * 80-character-wide terminals. + * + * \param state The common state describing the test window for the app. + * \param argv0 argv[0], as passed to main/SDL_main. + * \param options an array of strings for application specific options. The last element of the array should be NULL. + */ +void SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, const char **options); + +/** + * \brief Returns common usage information + * + * You should (probably) be using SDLTest_CommonLogUsage() instead, but this + * function remains for binary compatibility. Strings returned from this + * function are valid until SDLTest_CommonQuit() is called, in which case + * those strings' memory is freed and can no longer be used. + * + * \param state The common state describing the test window to create. + * \returns a string with usage information + */ +const char *SDLTest_CommonUsage(SDLTest_CommonState * state); + +/** + * \brief Open test window. + * + * \param state The common state describing the test window to create. + * + * \returns SDL_TRUE if initialization succeeded, false otherwise + */ +SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); + +/** + * \brief Easy argument handling when test app doesn't need any custom args. + * + * \param state The common state describing the test window to create. + * \param argc argc, as supplied to SDL_main + * \param argv argv, as supplied to SDL_main + * + * \returns SDL_FALSE if app should quit, true otherwise. + */ +SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState * state, const int argc, char **argv); + +/** + * \brief Common event handler for test windows. + * + * \param state The common state used to create test window. + * \param event The event to handle. + * \param done Flag indicating we are done. + * + */ +void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done); + +/** + * \brief Close test window. + * + * \param state The common state used to create test window. + * + */ +void SDLTest_CommonQuit(SDLTest_CommonState * state); + +/** + * \brief Draws various window information (position, size, etc.) to the renderer. + * + * \param renderer The renderer to draw to. + * \param window The window whose information should be displayed. + * \param usedHeight Returns the height used, so the caller can draw more below. + * + */ +void SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * usedHeight); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_common_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_compare.h b/thirdparty/SDL/include/SDL/SDL_test_compare.h new file mode 100644 index 00000000..8a7a0700 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_compare.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_compare.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines comparison functions (i.e. for surfaces). + +*/ + +#ifndef SDL_test_compare_h_ +#define SDL_test_compare_h_ + +#include "SDL.h" + +#include "SDL_test_images.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compares a surface and with reference image data for equality + * + * \param surface Surface used in comparison + * \param referenceSurface Test Surface used in comparison + * \param allowable_error Allowable difference (=sum of squared difference for each RGB component) in blending accuracy. + * + * \returns 0 if comparison succeeded, >0 (=number of pixels for which the comparison failed) if comparison failed, -1 if any of the surfaces were NULL, -2 if the surface sizes differ. + */ +int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_compare_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_crc32.h b/thirdparty/SDL/include/SDL/SDL_test_crc32.h new file mode 100644 index 00000000..049da740 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_crc32.h @@ -0,0 +1,124 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_crc32.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Implements CRC32 calculations (default output is Perl String::CRC32 compatible). + +*/ + +#ifndef SDL_test_crc32_h_ +#define SDL_test_crc32_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ------------ Definitions --------- */ + +/* Definition shared by all CRC routines */ + +#ifndef CrcUint32 + #define CrcUint32 unsigned int +#endif +#ifndef CrcUint8 + #define CrcUint8 unsigned char +#endif + +#ifdef ORIGINAL_METHOD + #define CRC32_POLY 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */ +#else + #define CRC32_POLY 0xEDB88320 /* Perl String::CRC32 compatible */ +#endif + +/** + * Data structure for CRC32 (checksum) computation + */ + typedef struct { + CrcUint32 crc32_table[256]; /* CRC table */ + } SDLTest_Crc32Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief Initialize the CRC context + * + * Note: The function initializes the crc table required for all crc calculations. + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * + */ + int SDLTest_Crc32Init(SDLTest_Crc32Context * crcContext); + + +/** + * \brief calculate a crc32 from a data block + * + * \param crcContext pointer to context variable + * \param inBuf input buffer to checksum + * \param inLen length of input buffer + * \param crc32 pointer to Uint32 to store the final CRC into + * + * \returns 0 for OK, -1 on error + * + */ +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + +/* Same routine broken down into three steps */ +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + + +/** + * \brief clean up CRC context + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * +*/ + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_crc32_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_font.h b/thirdparty/SDL/include/SDL/SDL_test_font.h new file mode 100644 index 00000000..6e7247dd --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_font.h @@ -0,0 +1,168 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_font.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_font_h_ +#define SDL_test_font_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +#define FONT_CHARACTER_SIZE 8 +#define FONT_LINE_HEIGHT (FONT_CHARACTER_SIZE + 2) + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the character. + * \param y The Y coordinate of the upper left corner of the character. + * \param c The character to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, Uint32 c); + +/** + * \brief Draw a UTF-8 string in the currently set font. + * + * The font currently only supports characters in the Basic Latin and Latin-1 Supplement sets. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the string. + * \param y The Y coordinate of the upper left corner of the string. + * \param s The string to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawString(SDL_Renderer *renderer, int x, int y, const char *s); + +/** + * \brief Data used for multi-line text output + */ +typedef struct SDLTest_TextWindow +{ + SDL_Rect rect; + int current; + int numlines; + char **lines; +} SDLTest_TextWindow; + +/** + * \brief Create a multi-line text output window + * + * \param x The X coordinate of the upper left corner of the window. + * \param y The Y coordinate of the upper left corner of the window. + * \param w The width of the window (currently ignored) + * \param h The height of the window (currently ignored) + * + * \returns the new window, or NULL on failure. + * + * \since This function is available since SDL 2.24.0 + */ +SDLTest_TextWindow *SDLTest_TextWindowCreate(int x, int y, int w, int h); + +/** + * \brief Display a multi-line text output window + * + * This function should be called every frame to display the text + * + * \param textwin The text output window + * \param renderer The renderer to use for display + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowDisplay(SDLTest_TextWindow *textwin, SDL_Renderer *renderer); + +/** + * \brief Add text to a multi-line text output window + * + * Adds UTF-8 text to the end of the current text. The newline character starts a + * new line of text. The backspace character deletes the last character or, if the + * line is empty, deletes the line and goes to the end of the previous line. + * + * \param textwin The text output window + * \param fmt A printf() style format string + * \param ... additional parameters matching % tokens in the `fmt` string, if any + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowAddText(SDLTest_TextWindow *textwin, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Add text to a multi-line text output window + * + * Adds UTF-8 text to the end of the current text. The newline character starts a + * new line of text. The backspace character deletes the last character or, if the + * line is empty, deletes the line and goes to the end of the previous line. + * + * \param textwin The text output window + * \param text The text to add to the window + * \param len The length, in bytes, of the text to add to the window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowAddTextWithLength(SDLTest_TextWindow *textwin, const char *text, size_t len); + +/** + * \brief Clear the text in a multi-line text output window + * + * \param textwin The text output window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowClear(SDLTest_TextWindow *textwin); + +/** + * \brief Free the storage associated with a multi-line text output window + * + * \param textwin The text output window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowDestroy(SDLTest_TextWindow *textwin); + +/** + * \brief Cleanup textures used by font drawing functions. + */ +void SDLTest_CleanupTextDrawing(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_font_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_fuzzer.h b/thirdparty/SDL/include/SDL/SDL_test_fuzzer.h new file mode 100644 index 00000000..bbe8eb87 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_fuzzer.h @@ -0,0 +1,386 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_fuzzer.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Data generators for fuzzing test data in a reproducible way. + +*/ + +#ifndef SDL_test_fuzzer_h_ +#define SDL_test_fuzzer_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* + Based on GSOC code by Markus Kauppila +*/ + + +/** + * \file + * Note: The fuzzer implementation uses a static instance of random context + * internally which makes it thread-UNsafe. + */ + +/** + * Initializes the fuzzer for a test + * + * \param execKey Execution "Key" that initializes the random number generator uniquely for the test. + * + */ +void SDLTest_FuzzerInit(Uint64 execKey); + + +/** + * Returns a random Uint8 + * + * \returns a generated integer + */ +Uint8 SDLTest_RandomUint8(void); + +/** + * Returns a random Sint8 + * + * \returns a generated signed integer + */ +Sint8 SDLTest_RandomSint8(void); + + +/** + * Returns a random Uint16 + * + * \returns a generated integer + */ +Uint16 SDLTest_RandomUint16(void); + +/** + * Returns a random Sint16 + * + * \returns a generated signed integer + */ +Sint16 SDLTest_RandomSint16(void); + + +/** + * Returns a random integer + * + * \returns a generated integer + */ +Sint32 SDLTest_RandomSint32(void); + + +/** + * Returns a random positive integer + * + * \returns a generated integer + */ +Uint32 SDLTest_RandomUint32(void); + +/** + * Returns random Uint64. + * + * \returns a generated integer + */ +Uint64 SDLTest_RandomUint64(void); + + +/** + * Returns random Sint64. + * + * \returns a generated signed integer + */ +Sint64 SDLTest_RandomSint64(void); + +/** + * \returns a random float in range [0.0 - 1.0] + */ +float SDLTest_RandomUnitFloat(void); + +/** + * \returns a random double in range [0.0 - 1.0] + */ +double SDLTest_RandomUnitDouble(void); + +/** + * \returns a random float. + * + */ +float SDLTest_RandomFloat(void); + +/** + * \returns a random double. + * + */ +double SDLTest_RandomDouble(void); + +/** + * Returns a random boundary value for Uint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint8BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint8BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint8BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint8BoundaryValue(0, 255, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint16BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint16BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint16BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint16BoundaryValue(0, 0xFFFF, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint32BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint32BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint32BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint32BoundaryValue(0, 0xFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint64BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint64BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint64BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint64BoundaryValue(0, 0xFFFFFFFFFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint8BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint8BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint8BoundaryValue(SINT8_MIN, 99, SDL_FALSE) returns 100 + * RandomSint8BoundaryValue(SINT8_MIN, SINT8_MAX, SDL_FALSE) returns SINT8_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT8_MIN with error set + */ +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain); + + +/** + * Returns a random boundary value for Sint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint16BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint16BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint16BoundaryValue(SINT16_MIN, 99, SDL_FALSE) returns 100 + * RandomSint16BoundaryValue(SINT16_MIN, SINT16_MAX, SDL_FALSE) returns SINT16_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT16_MIN with error set + */ +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint32BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint32BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint32BoundaryValue(SINT32_MIN, 99, SDL_FALSE) returns 100 + * RandomSint32BoundaryValue(SINT32_MIN, SINT32_MAX, SDL_FALSE) returns SINT32_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT32_MIN with error set + */ +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint64BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint64BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint64BoundaryValue(SINT64_MIN, 99, SDL_FALSE) returns 100 + * RandomSint64BoundaryValue(SINT64_MIN, SINT64_MAX, SDL_FALSE) returns SINT64_MIN (== error value) and error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT64_MIN with error set + */ +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain); + + +/** + * Returns integer in range [min, max] (inclusive). + * Min and max values can be negative values. + * If Max in smaller than min, then the values are swapped. + * Min and max are the same value, that value will be returned. + * + * \param min Minimum inclusive value of returned random number + * \param max Maximum inclusive value of returned random number + * + * \returns a generated random integer in range + */ +Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); + + +/** + * Generates random null-terminated string. The minimum length for + * the string is 1 character, maximum length for the string is 255 + * characters and it can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \returns a newly allocated random string; or NULL if length was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiString(void); + + +/** + * Generates random null-terminated string. The maximum length for + * the string is defined by the maxLength parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param maxLength The maximum length of the generated string. + * + * \returns a newly allocated random string; or NULL if maxLength was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); + + +/** + * Generates random null-terminated string. The length for + * the string is defined by the size parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param size The length of the generated string + * + * \returns a newly allocated random string; or NULL if size was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringOfSize(int size); + +/** + * Get the invocation count for the fuzzer since last ...FuzzerInit. + * + * \returns the invocation count. + */ +int SDLTest_GetFuzzerInvocationCount(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_fuzzer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_harness.h b/thirdparty/SDL/include/SDL/SDL_test_harness.h new file mode 100644 index 00000000..1fd4236b --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_harness.h @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_harness.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + Defines types for test case definitions and the test execution harness API. + + Based on original GSOC code by Markus Kauppila +*/ + +#ifndef SDL_test_h_arness_h +#define SDL_test_h_arness_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ! Definitions for test case structures */ +#define TEST_ENABLED 1 +#define TEST_DISABLED 0 + +/* ! Definition of all the possible test return values of the test case method */ +#define TEST_ABORTED -1 +#define TEST_STARTED 0 +#define TEST_COMPLETED 1 +#define TEST_SKIPPED 2 + +/* ! Definition of all the possible test results for the harness */ +#define TEST_RESULT_PASSED 0 +#define TEST_RESULT_FAILED 1 +#define TEST_RESULT_NO_ASSERT 2 +#define TEST_RESULT_SKIPPED 3 +#define TEST_RESULT_SETUP_FAILURE 4 + +/* !< Function pointer to a test case setup function (run before every test) */ +typedef void (*SDLTest_TestCaseSetUpFp)(void *arg); + +/* !< Function pointer to a test case function */ +typedef int (*SDLTest_TestCaseFp)(void *arg); + +/* !< Function pointer to a test case teardown function (run after every test) */ +typedef void (*SDLTest_TestCaseTearDownFp)(void *arg); + +/** + * Holds information about a single test case. + */ +typedef struct SDLTest_TestCaseReference { + /* !< Func2Stress */ + SDLTest_TestCaseFp testCase; + /* !< Short name (or function name) "Func2Stress" */ + const char *name; + /* !< Long name or full description "This test pushes func2() to the limit." */ + const char *description; + /* !< Set to TEST_ENABLED or TEST_DISABLED (test won't be run) */ + int enabled; +} SDLTest_TestCaseReference; + +/** + * Holds information about a test suite (multiple test cases). + */ +typedef struct SDLTest_TestSuiteReference { + /* !< "PlatformSuite" */ + const char *name; + /* !< The function that is run before each test. NULL skips. */ + SDLTest_TestCaseSetUpFp testSetUp; + /* !< The test cases that are run as part of the suite. Last item should be NULL. */ + const SDLTest_TestCaseReference **testCases; + /* !< The function that is run after each test. NULL skips. */ + SDLTest_TestCaseTearDownFp testTearDown; +} SDLTest_TestSuiteReference; + + +/** + * \brief Generates a random run seed string for the harness. The generated seed will contain alphanumeric characters (0-9A-Z). + * + * Note: The returned string needs to be deallocated by the caller. + * + * \param length The length of the seed string to generate + * + * \returns the generated seed string + */ +char *SDLTest_GenerateRunSeed(const int length); + +/** + * \brief Execute a test suite using the given run seed and execution key. + * + * \param testSuites Suites containing the test case. + * \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. + * \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. + * \param filter Filter specification. NULL disables. Case sensitive. + * \param testIterations Number of iterations to run each test case. + * + * \returns the test run result: 0 when all tests passed, 1 if any tests failed. + */ +int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_h_arness_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_images.h b/thirdparty/SDL/include/SDL/SDL_test_images.h new file mode 100644 index 00000000..e2bfc360 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_images.h @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_images.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines some images for tests. + +*/ + +#ifndef SDL_test_images_h_ +#define SDL_test_images_h_ + +#include "SDL.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + *Type for test images. + */ +typedef struct SDLTest_SurfaceImage_s { + int width; + int height; + unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ + const char *pixel_data; +} SDLTest_SurfaceImage_t; + +/* Test images */ +SDL_Surface *SDLTest_ImageBlit(void); +SDL_Surface *SDLTest_ImageBlitColor(void); +SDL_Surface *SDLTest_ImageBlitAlpha(void); +SDL_Surface *SDLTest_ImageBlitBlendAdd(void); +SDL_Surface *SDLTest_ImageBlitBlend(void); +SDL_Surface *SDLTest_ImageBlitBlendMod(void); +SDL_Surface *SDLTest_ImageBlitBlendNone(void); +SDL_Surface *SDLTest_ImageBlitBlendAll(void); +SDL_Surface *SDLTest_ImageFace(void); +SDL_Surface *SDLTest_ImagePrimitives(void); +SDL_Surface *SDLTest_ImagePrimitivesBlend(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_images_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_log.h b/thirdparty/SDL/include/SDL/SDL_test_log.h new file mode 100644 index 00000000..e3d39ad2 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_log.h @@ -0,0 +1,67 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_log.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Wrapper to log in the TEST category + * + */ + +#ifndef SDL_test_log_h_ +#define SDL_test_log_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Prints given message with a timestamp in the TEST category and INFO priority. + * + * \param fmt Message to be logged + */ +void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Prints given message with a timestamp in the TEST category and the ERROR priority. + * + * \param fmt Message to be logged + */ +void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_md5.h b/thirdparty/SDL/include/SDL/SDL_test_md5.h new file mode 100644 index 00000000..17b1d2be --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_md5.h @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_md5.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + *********************************************************************** + ** Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** +*/ + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** +*/ + +#ifndef SDL_test_md5_h_ +#define SDL_test_md5_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------ Definitions --------- */ + +/* typedef a 32-bit type */ + typedef unsigned long int MD5UINT4; + +/* Data structure for MD5 (Message-Digest) computation */ + typedef struct { + MD5UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + MD5UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after Md5Final call */ + } SDLTest_Md5Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief initialize the context + * + * \param mdContext pointer to context variable + * + * Note: The function initializes the message-digest context + * mdContext. Call before each new use of the context - + * all fields are set to zero. + */ + void SDLTest_Md5Init(SDLTest_Md5Context * mdContext); + + +/** + * \brief update digest from variable length data + * + * \param mdContext pointer to context variable + * \param inBuf pointer to data array/string + * \param inLen length of data array/string + * + * Note: The function updates the message-digest context to account + * for the presence of each of the characters inBuf[0..inLen-1] + * in the message whose digest is being computed. +*/ + + void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf, + unsigned int inLen); + + +/** + * \brief complete digest computation + * + * \param mdContext pointer to context variable + * + * Note: The function terminates the message-digest computation and + * ends with the desired message digest in mdContext.digest[0..15]. + * Always call before using the digest[] variable. +*/ + + void SDLTest_Md5Final(SDLTest_Md5Context * mdContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_md5_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_memory.h b/thirdparty/SDL/include/SDL/SDL_test_memory.h new file mode 100644 index 00000000..cc2edc1b --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_memory.h @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_memory.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_memory_h_ +#define SDL_test_memory_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Start tracking SDL memory allocations + * + * \note This should be called before any other SDL functions for complete tracking coverage + */ +int SDLTest_TrackAllocations(void); + +/** + * \brief Print a log of any outstanding allocations + * + * \note This can be called after SDL_Quit() + */ +void SDLTest_LogAllocations(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_memory_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_test_random.h b/thirdparty/SDL/include/SDL/SDL_test_random.h new file mode 100644 index 00000000..b1d6060c --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_test_random.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_random.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + A "32-bit Multiply with carry random number generator. Very fast. + Includes a list of recommended multipliers. + + multiply-with-carry generator: x(n) = a*x(n-1) + carry mod 2^32. + period: (a*2^31)-1 + +*/ + +#ifndef SDL_test_random_h_ +#define SDL_test_random_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Definitions */ + +/* + * Macros that return a random number in a specific format. + */ +#define SDLTest_RandomInt(c) ((int)SDLTest_Random(c)) + +/* + * Context structure for the random number generator state. + */ + typedef struct { + unsigned int a; + unsigned int x; + unsigned int c; + unsigned int ah; + unsigned int al; + } SDLTest_RandomContext; + + +/* --- Function prototypes */ + +/** + * \brief Initialize random number generator with two integers. + * + * Note: The random sequence of numbers returned by ...Random() is the + * same for the same two integers and has a period of 2^31. + * + * \param rndContext pointer to context structure + * \param xi integer that defines the random sequence + * \param ci integer that defines the random sequence + * + */ + void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi, + unsigned int ci); + +/** + * \brief Initialize random number generator based on current system time. + * + * \param rndContext pointer to context structure + * + */ + void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext); + + +/** + * \brief Initialize random number generator based on current system time. + * + * Note: ...RandomInit() or ...RandomInitTime() must have been called + * before using this function. + * + * \param rndContext pointer to context structure + * + * \returns a random number (32bit unsigned integer) + * + */ + unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_random_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_thread.h b/thirdparty/SDL/include/SDL/SDL_thread.h new file mode 100644 index 00000000..7364f813 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_thread.h @@ -0,0 +1,464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_thread_h_ +#define SDL_thread_h_ + +/** + * \file SDL_thread.h + * + * Header for the SDL thread management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_atomic.h" +#include "SDL_mutex.h" + +#if defined(__WIN32__) || defined(__GDK__) +#include /* _beginthreadex() and _endthreadex() */ +#endif +#if defined(__OS2__) /* for _beginthread() and _endthread() */ +#ifndef __EMX__ +#include +#else +#include +#endif +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* The SDL thread ID */ +typedef unsigned long SDL_threadID; + +/* Thread local storage ID, 0 is the invalid ID */ +typedef unsigned int SDL_TLSID; + +/** + * The SDL thread priority. + * + * SDL will make system changes as necessary in order to apply the thread priority. + * Code which attempts to control thread state related to priority should be aware + * that calling SDL_SetThreadPriority may alter such state. + * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior. + * + * \note On many systems you require special privileges to set high or time critical priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH, + SDL_THREAD_PRIORITY_TIME_CRITICAL +} SDL_ThreadPriority; + +/** + * The function passed to SDL_CreateThread(). + * + * \param data what was passed as `data` to SDL_CreateThread() + * \returns a value that can be reported through SDL_WaitThread(). + */ +typedef int (SDLCALL * SDL_ThreadFunction) (void *data); + + +#if defined(__WIN32__) || defined(__GDK__) +/** + * \file SDL_thread.h + * + * We compile SDL into a DLL. This means, that it's the DLL which + * creates a new thread for the calling process with the SDL_CreateThread() + * API. There is a problem with this, that only the RTL of the SDL2.DLL will + * be initialized for those threads, and not the RTL of the calling + * application! + * + * To solve this, we make a little hack here. + * + * We'll always use the caller's _beginthread() and _endthread() APIs to + * start a new thread. This way, if it's the SDL2.DLL which uses this API, + * then the RTL of SDL2.DLL will be used to create the new thread, and if it's + * the application, then the RTL of the application will be used. + * + * So, in short: + * Always use the _beginthread() and _endthread() of the calling runtime + * library! + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) + (void *, unsigned, unsigned (__stdcall *func)(void *), + void * /*arg*/, unsigned, unsigned * /* threadID */); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthreadex +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthreadex +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#elif defined(__OS2__) +/* + * just like the windows case above: We compile SDL2 + * into a dll with Watcom's runtime statically linked. + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); +typedef void (*pfnSDL_CurrentEndThread)(void); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthread +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthread +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#else + +/** + * Create a new thread with a default stack size. + * + * This is equivalent to calling: + * + * ```c + * SDL_CreateThreadWithStackSize(fn, name, 0, data); + * ``` + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThreadWithStackSize + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); + +/** + * Create a new thread with a specific stack size. + * + * SDL makes an attempt to report `name` to the system, so that debuggers can + * display it. Not all platforms support this. + * + * Thread naming is a little complicated: Most systems have very small limits + * for the string length (Haiku has 32 bytes, Linux currently has 16, Visual + * C++ 6.0 has _nine_!), and possibly other arbitrary rules. You'll have to + * see what happens with your system's debugger. The name should be UTF-8 (but + * using the naming limits of C identifiers is a better bet). There are no + * requirements for thread naming conventions, so long as the string is + * null-terminated UTF-8, but these guidelines are helpful in choosing a name: + * + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for it + * (truncate, etc), but the original string contents will be available from + * SDL_GetThreadName(). + * + * The size (in bytes) of the new stack can be specified. Zero means "use the + * system default" which might be wildly different between platforms. x86 + * Linux generally defaults to eight megabytes, an embedded device might be a + * few kilobytes instead. You generally need to specify a stack that is a + * multiple of the system's page size (in many cases, this is 4 kilobytes, but + * check your system documentation). + * + * In SDL 2.1, stack size will be folded into the original SDL_CreateThread + * function, but for backwards compatibility, this is currently a separate + * function. + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param stacksize the size, in bytes, to allocate for the new thread stack. + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data); + +#endif + +/** + * Get the thread name as it was specified in SDL_CreateThread(). + * + * This is internal memory, not to be freed by the caller, and remains valid + * until the specified thread is cleaned up by SDL_WaitThread(). + * + * \param thread the thread to query + * \returns a pointer to a UTF-8 string that names the specified thread, or + * NULL if it doesn't have a name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + +/** + * Get the thread identifier for the current thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * This function also returns a valid thread ID when called from the main + * thread. + * + * \returns the ID of the current thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); + +/** + * Get the thread identifier for the specified thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * \param thread the thread to query + * \returns the ID of the specified thread, or the ID of the current thread if + * `thread` is NULL. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); + +/** + * Set the priority for the current thread. + * + * Note that some platforms will not let you alter the priority (or at least, + * promote the thread to a higher priority) at all, and some require you to be + * an administrator account. Be prepared for this to fail. + * + * \param priority the SDL_ThreadPriority to set + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); + +/** + * Wait for a thread to finish. + * + * Threads that haven't been detached will remain (as a "zombie") until this + * function cleans them up. Not doing so is a resource leak. + * + * Once a thread has been cleaned up through this function, the SDL_Thread + * that references it becomes invalid and should not be referenced again. As + * such, only one thread may call SDL_WaitThread() on another. + * + * The return code for the thread function is placed in the area pointed to by + * `status`, if `status` is not NULL. + * + * You may not wait on a thread that has been used in a call to + * SDL_DetachThread(). Use either that function or this one, but not both, or + * behavior is undefined. + * + * It is safe to pass a NULL thread to this function; it is a no-op. + * + * Note that the thread pointer is freed by this function and is not valid + * afterward. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * \param status pointer to an integer that will receive the value returned + * from the thread function by its 'return', or NULL to not + * receive such value back. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + * \sa SDL_DetachThread + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); + +/** + * Let a thread clean up on exit without intervention. + * + * A thread may be "detached" to signify that it should not remain until + * another thread has called SDL_WaitThread() on it. Detaching a thread is + * useful for long-running threads that nothing needs to synchronize with or + * further manage. When a detached thread is done, it simply goes away. + * + * There is no way to recover the return code of a detached thread. If you + * need this, don't detach the thread and instead use SDL_WaitThread(). + * + * Once a thread is detached, you should usually assume the SDL_Thread isn't + * safe to reference again, as it will become invalid immediately upon the + * detached thread's exit, instead of remaining until someone has called + * SDL_WaitThread() to finally clean it up. As such, don't detach the same + * thread more than once. + * + * If a thread has already exited when passed to SDL_DetachThread(), it will + * stop waiting for a call to SDL_WaitThread() and clean up immediately. It is + * not safe to detach a thread that might be used with SDL_WaitThread(). + * + * You may not call SDL_WaitThread() on a thread that has been detached. Use + * either that function or this one, but not both, or behavior is undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_CreateThread + * \sa SDL_WaitThread + */ +extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); + +/** + * Create a piece of thread-local storage. + * + * This creates an identifier that is globally visible to all threads but + * refers to data that is thread-specific. + * + * \returns the newly created thread local storage identifier or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSGet + * \sa SDL_TLSSet + */ +extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); + +/** + * Get the current thread's value associated with a thread local storage ID. + * + * \param id the thread local storage ID + * \returns the value associated with the ID for the current thread or NULL if + * no value has been set; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSSet + */ +extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); + +/** + * Set the current thread's value associated with a thread local storage ID. + * + * The function prototype for `destructor` is: + * + * ```c + * void destructor(void *value) + * ``` + * + * where its parameter `value` is what was passed as `value` to SDL_TLSSet(). + * + * \param id the thread local storage ID + * \param value the value to associate with the ID for the current thread + * \param destructor a function called when the thread exits, to free the + * value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSGet + */ +extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); + +/** + * Cleanup all TLS data for this thread. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC void SDLCALL SDL_TLSCleanup(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_thread_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_timer.h b/thirdparty/SDL/include/SDL/SDL_timer.h new file mode 100644 index 00000000..62f81d42 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_timer.h @@ -0,0 +1,222 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_timer_h_ +#define SDL_timer_h_ + +/** + * \file SDL_timer.h + * + * Header for the SDL time management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the number of milliseconds since SDL library initialization. + * + * This value wraps if the program runs for more than ~49 days. + * + * This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64() + * instead, where the value doesn't wrap every ~49 days. There are places in + * SDL where we provide a 32-bit timestamp that can not change without + * breaking binary compatibility, though, so this function isn't officially + * deprecated. + * + * \returns an unsigned 32-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TICKS_PASSED + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/** + * Get the number of milliseconds since SDL library initialization. + * + * Note that you should not use the SDL_TICKS_PASSED macro with values + * returned by this function, as that macro does clever math to compensate for + * the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit + * values from this function can be safely compared directly. + * + * For example, if you want to wait 100 ms, you could do this: + * + * ```c + * const Uint64 timeout = SDL_GetTicks64() + 100; + * while (SDL_GetTicks64() < timeout) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * \returns an unsigned 64-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void); + +/** + * Compare 32-bit SDL ticks values, and return true if `A` has passed `B`. + * + * This should be used with results from SDL_GetTicks(), as this macro + * attempts to deal with the 32-bit counter wrapping back to zero every ~49 + * days, but should _not_ be used with SDL_GetTicks64(), which does not have + * that problem. + * + * For example, with SDL_GetTicks(), if you want to wait 100 ms, you could + * do this: + * + * ```c + * const Uint32 timeout = SDL_GetTicks() + 100; + * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * Note that this does not handle tick differences greater + * than 2^31 so take care when using the above kind of code + * with large timeout delays (tens of days). + */ +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) + +/** + * Get the current value of the high resolution counter. + * + * This function is typically used for profiling. + * + * The counter values are only meaningful relative to each other. Differences + * between values can be converted to times by using + * SDL_GetPerformanceFrequency(). + * + * \returns the current counter value. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceFrequency + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); + +/** + * Get the count per second of the high resolution counter. + * + * \returns a platform-specific count per second. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceCounter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); + +/** + * Wait a specified number of milliseconds before returning. + * + * This function waits a specified number of milliseconds before returning. It + * waits at least the specified time, but possibly longer due to OS + * scheduling. + * + * \param ms the number of milliseconds to delay + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/** + * Function prototype for the timer callback function. + * + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); + +/** + * Definition of the timer ID type. + */ +typedef int SDL_TimerID; + +/** + * Call a callback function at a future time. + * + * If you use this function, you must pass `SDL_INIT_TIMER` to SDL_Init(). + * + * The callback function is passed the current timer interval and the user + * supplied parameter from the SDL_AddTimer() call and should return the next + * timer interval. If the value returned from the callback is 0, the timer is + * canceled. + * + * The callback is run on a separate thread. + * + * Timers take into account the amount of time it took to execute the + * callback. For example, if the callback took 250 ms to execute and returned + * 1000 (ms), the timer would only wait another 750 ms before its next + * iteration. + * + * Timing may be inexact due to OS scheduling. Be sure to note the current + * time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your + * callback needs to adjust for variances. + * + * \param interval the timer delay, in milliseconds, passed to `callback` + * \param callback the SDL_TimerCallback function to call when the specified + * `interval` elapses + * \param param a pointer that is passed to `callback` + * \returns a timer ID or 0 if an error occurs; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RemoveTimer + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, + SDL_TimerCallback callback, + void *param); + +/** + * Remove a timer created with SDL_AddTimer(). + * + * \param id the ID of the timer to remove + * \returns SDL_TRUE if the timer is removed or SDL_FALSE if the timer wasn't + * found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddTimer + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_timer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_touch.h b/thirdparty/SDL/include/SDL/SDL_touch.h new file mode 100644 index 00000000..95924135 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_touch.h @@ -0,0 +1,150 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_touch.h + * + * Include file for SDL touch event handling. + */ + +#ifndef SDL_touch_h_ +#define SDL_touch_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_TouchID; +typedef Sint64 SDL_FingerID; + +typedef enum +{ + SDL_TOUCH_DEVICE_INVALID = -1, + SDL_TOUCH_DEVICE_DIRECT, /* touch screen with window-relative coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, /* trackpad with absolute device coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_RELATIVE /* trackpad with screen cursor-relative coordinates */ +} SDL_TouchDeviceType; + +typedef struct SDL_Finger +{ + SDL_FingerID id; + float x; + float y; + float pressure; +} SDL_Finger; + +/* Used as the device ID for mouse events simulated with touch input */ +#define SDL_TOUCH_MOUSEID ((Uint32)-1) + +/* Used as the SDL_TouchID for touch events simulated with mouse input */ +#define SDL_MOUSE_TOUCHID ((Sint64)-1) + + +/** + * Get the number of registered touch devices. + * + * On some platforms SDL first sees the touch device if it was actually used. + * Therefore SDL_GetNumTouchDevices() may return 0 although devices are + * available. After using all devices at least once the number will be + * correct. + * + * This was fixed for Android in SDL 2.0.1. + * + * \returns the number of registered touch devices. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); + +/** + * Get the touch ID with the given index. + * + * \param index the touch device index + * \returns the touch ID with the given index on success or 0 if the index is + * invalid; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumTouchDevices + */ +extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); + +/** + * Get the touch device name as reported from the driver or NULL if the index + * is invalid. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index); + +/** + * Get the type of the given touch device. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); + +/** + * Get the number of active fingers for a given touch device. + * + * \param touchID the ID of a touch device + * \returns the number of active fingers for a given touch device on success + * or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchFinger + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); + +/** + * Get the finger object for specified touch device ID and finger index. + * + * The returned resource is owned by SDL and should not be deallocated. + * + * \param touchID the ID of the requested touch device + * \param index the index of the requested finger + * \returns a pointer to the SDL_Finger object or NULL if no object at the + * given ID and index could be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RecordGesture + */ +extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_touch_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_types.h b/thirdparty/SDL/include/SDL/SDL_types.h new file mode 100644 index 00000000..355fb501 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_types.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_types.h + * + * \deprecated + */ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/thirdparty/SDL/include/SDL/SDL_version.h b/thirdparty/SDL/include/SDL/SDL_version.h new file mode 100644 index 00000000..95d47bb2 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_version.h @@ -0,0 +1,204 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_version.h + * + * This header defines the current SDL version. + */ + +#ifndef SDL_version_h_ +#define SDL_version_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Information about the version of SDL in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa SDL_VERSION + * \sa SDL_GetVersion + */ +typedef struct SDL_version +{ + Uint8 major; /**< major version */ + Uint8 minor; /**< minor version */ + Uint8 patch; /**< update version */ +} SDL_version; + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 2 +#define SDL_MINOR_VERSION 24 +#define SDL_PATCHLEVEL 2 + +/** + * Macro to determine SDL version program was compiled against. + * + * This macro fills in a SDL_version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), + * is not a macro. + * + * \param x A pointer to a SDL_version struct to initialize. + * + * \sa SDL_version + * \sa SDL_GetVersion + */ +#define SDL_VERSION(x) \ +{ \ + (x)->major = SDL_MAJOR_VERSION; \ + (x)->minor = SDL_MINOR_VERSION; \ + (x)->patch = SDL_PATCHLEVEL; \ +} + +/* TODO: Remove this whole block in SDL 3 */ +#if SDL_MAJOR_VERSION < 3 +/** + * This macro turns the version numbers into a numeric value: + * \verbatim + (1,2,3) -> (1203) + \endverbatim + * + * This assumes that there will never be more than 100 patchlevels. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300, + * and 2.255.99 would be encoded as 25799. + * This macro will not be available in SDL 3.x. + */ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/** + * This is the version number macro for the current SDL version. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300. + * This macro will not be available in SDL 3.x. + * + * Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead. + */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) +#endif /* SDL_MAJOR_VERSION < 3 */ + +/** + * This macro will evaluate to true if compiled with SDL at least X.Y.Z. + */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + ((SDL_MAJOR_VERSION >= X) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION >= Y) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION > Y || SDL_PATCHLEVEL >= Z)) + +/** + * Get the version of SDL that is linked against your program. + * + * If you are linking to SDL dynamically, then it is possible that the current + * version will be different than the version you compiled against. This + * function returns the current version, while SDL_VERSION() is a macro that + * tells you what version you compiled with. + * + * This function may be called safely at any time, even before SDL_Init(). + * + * \param ver the SDL_version structure that contains the version information + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); + +/** + * Get the code revision of SDL that is linked against your program. + * + * This value is the revision of the code you are linked with and may be + * different from the code you are compiling with, which is found in the + * constant SDL_REVISION. + * + * The revision is arbitrary string (a hash value) uniquely identifying the + * exact revision of the SDL library in use, and is only useful in comparing + * against other revisions. It is NOT an incrementing number. + * + * If SDL wasn't built from a git repository with the appropriate tools, this + * will return an empty string. + * + * Prior to SDL 2.0.16, before development moved to GitHub, this returned a + * hash for a Mercurial repository. + * + * You shouldn't use this function for anything but logging it for debugging + * purposes. The string is not intended to be reliable in any way. + * + * \returns an arbitrary string, uniquely identifying the exact revision of + * the SDL library in use. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVersion + */ +extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); + +/** + * Obsolete function, do not use. + * + * When SDL was hosted in a Mercurial repository, and was built carefully, + * this would return the revision number that the build was created from. This + * number was not reliable for several reasons, but more importantly, SDL is + * now hosted in a git repository, which does not offer numbers at all, only + * hashes. This function only ever returns zero now. Don't use it. + * + * Before SDL 2.0.16, this might have returned an unreliable, but non-zero + * number. + * + * \deprecated Use SDL_GetRevision() instead; if SDL was carefully built, it + * will return a git hash. + * + * \returns zero, always, in modern SDL releases. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern SDL_DEPRECATED DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_version_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_video.h b/thirdparty/SDL/include/SDL/SDL_video.h new file mode 100644 index 00000000..0b1065db --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_video.h @@ -0,0 +1,2126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_video.h + * + * Header file for SDL video functions. + */ + +#ifndef SDL_video_h_ +#define SDL_video_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a display mode + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + * \sa SDL_GetDesktopDisplayMode() + * \sa SDL_GetCurrentDisplayMode() + * \sa SDL_GetClosestDisplayMode() + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +typedef struct +{ + Uint32 format; /**< pixel format */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ + int refresh_rate; /**< refresh rate (or zero for unspecified) */ + void *driverdata; /**< driver-specific data, initialize to 0 */ +} SDL_DisplayMode; + +/** + * \brief The type used to identify a window + * + * \sa SDL_CreateWindow() + * \sa SDL_CreateWindowFrom() + * \sa SDL_DestroyWindow() + * \sa SDL_FlashWindow() + * \sa SDL_GetWindowData() + * \sa SDL_GetWindowFlags() + * \sa SDL_GetWindowGrab() + * \sa SDL_GetWindowKeyboardGrab() + * \sa SDL_GetWindowMouseGrab() + * \sa SDL_GetWindowPosition() + * \sa SDL_GetWindowSize() + * \sa SDL_GetWindowTitle() + * \sa SDL_HideWindow() + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + * \sa SDL_RaiseWindow() + * \sa SDL_RestoreWindow() + * \sa SDL_SetWindowData() + * \sa SDL_SetWindowFullscreen() + * \sa SDL_SetWindowGrab() + * \sa SDL_SetWindowKeyboardGrab() + * \sa SDL_SetWindowMouseGrab() + * \sa SDL_SetWindowIcon() + * \sa SDL_SetWindowPosition() + * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() + * \sa SDL_SetWindowTitle() + * \sa SDL_ShowWindow() + */ +typedef struct SDL_Window SDL_Window; + +/** + * \brief The flags on a window + * + * \sa SDL_GetWindowFlags() + */ +typedef enum +{ + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ + SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ + SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ + SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ + SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ + SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ + SDL_WINDOW_MOUSE_GRABBED = 0x00000100, /**< window has grabbed mouse input */ + SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), + SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, /**< window should be created in high-DPI mode if supported. + On macOS NSHighResolutionCapable must be set true in the + application's Info.plist for this to have any effect. */ + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, /**< window has mouse captured (unrelated to MOUSE_GRABBED) */ + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */ + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */ + SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */ + SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */ + SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */ + SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000, /**< window has grabbed keyboard input */ + SDL_WINDOW_VULKAN = 0x10000000, /**< window usable for Vulkan surface */ + SDL_WINDOW_METAL = 0x20000000, /**< window usable for Metal view */ + + SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */ +} SDL_WindowFlags; + +/** + * \brief Used to indicate that you don't care what the window position is. + */ +#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u +#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) +#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) +#define SDL_WINDOWPOS_ISUNDEFINED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) + +/** + * \brief Used to indicate that the window position should be centered. + */ +#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u +#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X)) +#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0) +#define SDL_WINDOWPOS_ISCENTERED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) + +/** + * \brief Event subtype for window events + */ +typedef enum +{ + SDL_WINDOWEVENT_NONE, /**< Never used */ + SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ + SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ + SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be + redrawn */ + SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 + */ + SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ + SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as + a result of an API call or through the + system or user changing the window size. */ + SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ + SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ + SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size + and position */ + SDL_WINDOWEVENT_ENTER, /**< Window has gained mouse focus */ + SDL_WINDOWEVENT_LEAVE, /**< Window has lost mouse focus */ + SDL_WINDOWEVENT_FOCUS_GAINED, /**< Window has gained keyboard focus */ + SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */ + SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ + SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */ + SDL_WINDOWEVENT_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ + SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */ + SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */ +} SDL_WindowEventID; + +/** + * \brief Event subtype for display events + */ +typedef enum +{ + SDL_DISPLAYEVENT_NONE, /**< Never used */ + SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ + SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */ + SDL_DISPLAYEVENT_DISCONNECTED /**< Display has been removed from the system */ +} SDL_DisplayEventID; + +/** + * \brief Display orientation + */ +typedef enum +{ + SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */ + SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ + SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ + SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ + SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */ +} SDL_DisplayOrientation; + +/** + * \brief Window flash operation + */ +typedef enum +{ + SDL_FLASH_CANCEL, /**< Cancel any window flash state */ + SDL_FLASH_BRIEFLY, /**< Flash the window briefly to get attention */ + SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */ +} SDL_FlashOperation; + +/** + * \brief An opaque handle to an OpenGL context. + */ +typedef void *SDL_GLContext; + +/** + * \brief OpenGL configuration attributes + */ +typedef enum +{ + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR, + SDL_GL_FLOATBUFFERS +} SDL_GLattr; + +typedef enum +{ + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +} SDL_GLprofile; + +typedef enum +{ + SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 +} SDL_GLcontextFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 +} SDL_GLcontextReleaseFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, + SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001 +} SDL_GLContextResetNotification; + +/* Function prototypes */ + +/** + * Get the number of video drivers compiled into SDL. + * + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void); + +/** + * Get the name of a built in video driver. + * + * The video drivers are presented in the order in which they are normally + * checked during initialization. + * + * \param index the index of a video driver + * \returns the name of the video driver with the given **index**. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); + +/** + * Initialize the video subsystem, optionally specifying a video driver. + * + * This function initializes the video subsystem, setting up a connection to + * the window manager, etc, and determines the available display modes and + * pixel formats, but does not initialize a window or graphics mode. + * + * If you use this function and you haven't used the SDL_INIT_VIDEO flag with + * either SDL_Init() or SDL_InitSubSystem(), you should call SDL_VideoQuit() + * before calling SDL_Quit(). + * + * It is safe to call this function multiple times. SDL_VideoInit() will call + * SDL_VideoQuit() itself if the video subsystem has already been initialized. + * + * You can use SDL_GetNumVideoDrivers() and SDL_GetVideoDriver() to find a + * specific `driver_name`. + * + * \param driver_name the name of a video driver to initialize, or NULL for + * the default driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + * \sa SDL_InitSubSystem + * \sa SDL_VideoQuit + */ +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); + +/** + * Shut down the video subsystem, if initialized with SDL_VideoInit(). + * + * This function closes all windows, and restores the original video mode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_VideoInit + */ +extern DECLSPEC void SDLCALL SDL_VideoQuit(void); + +/** + * Get the name of the currently initialized video driver. + * + * \returns the name of the current video driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); + +/** + * Get the number of available video displays. + * + * \returns a number >= 1 or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); + +/** + * Get the name of a display in UTF-8 encoding. + * + * \param displayIndex the index of display from which the name should be + * queried + * \returns the name of a display or NULL for an invalid display index or + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex); + +/** + * Get the desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * \param displayIndex the index of the display to query + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the usable desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * This is the same area as SDL_GetDisplayBounds() reports, but with portions + * reserved by the system removed. For example, on Apple's macOS, this + * subtracts the area occupied by the menu bar and dock. + * + * Setting a window to be fullscreen generally bypasses these unusable areas, + * so these are good guidelines for the maximum space available to a + * non-fullscreen window. + * + * The parameter `rect` is ignored if it is NULL. + * + * This function also returns -1 if the parameter `displayIndex` is out of + * range. + * + * \param displayIndex the index of the display to query the usable bounds + * from + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the dots/pixels-per-inch for a display. + * + * Diagonal, horizontal and vertical DPI can all be optionally returned if the + * appropriate parameter is non-NULL. + * + * A failure of this function usually means that either no DPI information is + * available or the `displayIndex` is out of range. + * + * **WARNING**: This reports the DPI that the hardware reports, and it is not + * always reliable! It is almost always better to use SDL_GetWindowSize() to + * find the window size, which might be in logical points instead of pixels, + * and then SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(), + * SDL_Metal_GetDrawableSize(), or SDL_GetRendererOutputSize(), and compare + * the two values to get an actual scaling value between the two. We will be + * rethinking how high-dpi details should be managed in SDL3 to make things + * more consistent, reliable, and clear. + * + * \param displayIndex the index of the display from which DPI information + * should be queried + * \param ddpi a pointer filled in with the diagonal DPI of the display; may + * be NULL + * \param hdpi a pointer filled in with the horizontal DPI of the display; may + * be NULL + * \param vdpi a pointer filled in with the vertical DPI of the display; may + * be NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi); + +/** + * Get the orientation of a display. + * + * \param displayIndex the index of the display to query + * \returns The SDL_DisplayOrientation enum value of the display, or + * `SDL_ORIENTATION_UNKNOWN` if it isn't available. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex); + +/** + * Get the number of available display modes. + * + * The `displayIndex` needs to be in the range from 0 to + * SDL_GetNumVideoDisplays() - 1. + * + * \param displayIndex the index of the display to query + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex); + +/** + * Get information about a specific display mode. + * + * The display modes are sorted in this priority: + * + * - width -> largest to smallest + * - height -> largest to smallest + * - bits per pixel -> more colors to fewer colors + * - packed pixel layout -> largest to smallest + * - refresh rate -> highest to lowest + * + * \param displayIndex the index of the display to query + * \param modeIndex the index of the display mode to query + * \param mode an SDL_DisplayMode structure filled in with the mode at + * `modeIndex` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayMode(int displayIndex, int modeIndex, + SDL_DisplayMode * mode); + +/** + * Get information about the desktop's display mode. + * + * There's a difference between this function and SDL_GetCurrentDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the previous native display mode, and not the current + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetCurrentDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode); + +/** + * Get information about the current display mode. + * + * There's a difference between this function and SDL_GetDesktopDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the current display mode, and not the previous native + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDesktopDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode); + + +/** + * Get the closest match to the requested display mode. + * + * The available display modes are scanned and `closest` is filled in with the + * closest mode matching the requested mode and returned. The mode format and + * refresh rate default to the desktop mode if they are set to 0. The modes + * are scanned with size being first priority, format being second priority, + * and finally checking the refresh rate. If all the available modes are too + * small, then NULL is returned. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure containing the desired display + * mode + * \param closest an SDL_DisplayMode structure filled in with the closest + * match of the available display modes + * \returns the passed in value `closest` or NULL if no matching video mode + * was available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest); + +/** + * Get the index of the display containing a point + * + * \param point the point to query + * \returns the index of the display containing the point or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetPointDisplayIndex(const SDL_Point * point); + +/** + * Get the index of the display primarily containing a rect + * + * \param rect the rect to query + * \returns the index of the display entirely containing the rect or closest + * to the center of the rect on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetRectDisplayIndex(const SDL_Rect * rect); + +/** + * Get the index of the display associated with a window. + * + * \param window the window to query + * \returns the index of the display containing the center of the window on + * success or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayIndex(SDL_Window * window); + +/** + * Set the display mode to use when a window is visible at fullscreen. + * + * This only affects the display mode used when the window is fullscreen. To + * change the window size when the window is not fullscreen, use + * SDL_SetWindowSize(). + * + * \param window the window to affect + * \param mode the SDL_DisplayMode structure representing the mode to use, or + * NULL to use the window's dimensions and the desktop's format + * and refresh rate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window, + const SDL_DisplayMode * mode); + +/** + * Query the display mode to use when a window is visible at fullscreen. + * + * \param window the window to query + * \param mode an SDL_DisplayMode structure filled in with the fullscreen + * display mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window, + SDL_DisplayMode * mode); + +/** + * Get the raw ICC profile data for the screen the window is currently on. + * + * Data returned should be freed with SDL_free. + * + * \param window the window to query + * \param size the size of the ICC profile + * \returns the raw ICC profile data on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void* SDLCALL SDL_GetWindowICCProfile(SDL_Window * window, size_t* size); + +/** + * Get the pixel format associated with the window. + * + * \param window the window to query + * \returns the pixel format of the window on success or + * SDL_PIXELFORMAT_UNKNOWN on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); + +/** + * Create a window with the specified position, dimensions, and flags. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_WINDOW_FULLSCREEN`: fullscreen window + * - `SDL_WINDOW_FULLSCREEN_DESKTOP`: fullscreen window at desktop resolution + * - `SDL_WINDOW_OPENGL`: window usable with an OpenGL context + * - `SDL_WINDOW_VULKAN`: window usable with a Vulkan instance + * - `SDL_WINDOW_METAL`: window usable with a Metal instance + * - `SDL_WINDOW_HIDDEN`: window is not visible + * - `SDL_WINDOW_BORDERLESS`: no window decoration + * - `SDL_WINDOW_RESIZABLE`: window can be resized + * - `SDL_WINDOW_MINIMIZED`: window is minimized + * - `SDL_WINDOW_MAXIMIZED`: window is maximized + * - `SDL_WINDOW_INPUT_GRABBED`: window has grabbed input focus + * - `SDL_WINDOW_ALLOW_HIGHDPI`: window should be created in high-DPI mode if + * supported (>= SDL 2.0.1) + * + * `SDL_WINDOW_SHOWN` is ignored by SDL_CreateWindow(). The SDL_Window is + * implicitly shown if SDL_WINDOW_HIDDEN is not set. `SDL_WINDOW_SHOWN` may be + * queried later using SDL_GetWindowFlags(). + * + * On Apple's macOS, you **must** set the NSHighResolutionCapable Info.plist + * property to YES, otherwise you will not receive a High-DPI OpenGL canvas. + * + * If the window is created with the `SDL_WINDOW_ALLOW_HIGHDPI` flag, its size + * in pixels may differ from its size in screen coordinates on platforms with + * high-DPI support (e.g. iOS and macOS). Use SDL_GetWindowSize() to query the + * client area's size in screen coordinates, and SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to query the drawable size in pixels. Note that + * when this flag is set, the drawable size can vary after the window is + * created and should be queried after major window events such as when the + * window is resized or moved between displays. + * + * If the window is set fullscreen, the width and height parameters `w` and + * `h` will not be used. However, invalid size parameters (e.g. too large) may + * still fail. Window size is actually limited to 16384 x 16384 for all + * platforms at window creation. + * + * If the window is created with any of the SDL_WINDOW_OPENGL or + * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function + * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the + * corresponding UnloadLibrary function is called by SDL_DestroyWindow(). + * + * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, + * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. + * + * If SDL_WINDOW_METAL is specified on an OS that does not support Metal, + * SDL_CreateWindow() will fail. + * + * On non-Apple devices, SDL requires you to either not link to the Vulkan + * loader or link to a dynamic library version. This limitation may be removed + * in a future version of SDL. + * + * \param title the title of the window, in UTF-8 encoding + * \param x the x position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param y the y position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param w the width of the window, in screen coordinates + * \param h the height of the window, in screen coordinates + * \param flags 0, or one or more SDL_WindowFlags OR'd together + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindowFrom + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, + int x, int y, int w, + int h, Uint32 flags); + +/** + * Create an SDL window from an existing native window. + * + * In some cases (e.g. OpenGL) and on some platforms (e.g. Microsoft Windows) + * the hint `SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT` needs to be configured + * before using SDL_CreateWindowFrom(). + * + * \param data a pointer to driver-dependent window creation data, typically + * your native window cast to a void* + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowFrom(const void *data); + +/** + * Get the numeric ID of a window. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param window the window to query + * \returns the ID of the window on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFromID + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowID(SDL_Window * window); + +/** + * Get a window from a stored ID. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param id the ID of the window + * \returns the window associated with `id` or NULL if it doesn't exist; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowID + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromID(Uint32 id); + +/** + * Get the window flags. + * + * \param window the window to query + * \returns a mask of the SDL_WindowFlags associated with `window` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_HideWindow + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + * \sa SDL_SetWindowFullscreen + * \sa SDL_SetWindowGrab + * \sa SDL_ShowWindow + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window * window); + +/** + * Set the title of a window. + * + * This string is expected to be in UTF-8 encoding. + * + * \param window the window to change + * \param title the desired window title in UTF-8 format + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowTitle + */ +extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_Window * window, + const char *title); + +/** + * Get the title of a window. + * + * \param window the window to query + * \returns the title of the window in UTF-8 format or "" if there is no + * title. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowTitle + */ +extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window * window); + +/** + * Set the icon for a window. + * + * \param window the window to change + * \param icon an SDL_Surface structure containing the icon for the window + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, + SDL_Surface * icon); + +/** + * Associate an arbitrary named pointer with a window. + * + * `name` is case-sensitive. + * + * \param window the window to associate with the pointer + * \param name the name of the pointer + * \param userdata the associated pointer + * \returns the previous value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowData + */ +extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, + const char *name, + void *userdata); + +/** + * Retrieve the data pointer associated with a window. + * + * \param window the window to query + * \param name the name of the pointer + * \returns the value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowData + */ +extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, + const char *name); + +/** + * Set the position of a window. + * + * The window coordinate origin is the upper left of the display. + * + * \param window the window to reposition + * \param x the x coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * \param y the y coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, + int x, int y); + +/** + * Get the position of a window. + * + * If you do not need the value for one of the positions a NULL may be passed + * in the `x` or `y` parameter. + * + * \param window the window to query + * \param x a pointer filled in with the x position of the window, in screen + * coordinates, may be NULL + * \param y a pointer filled in with the y position of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, + int *x, int *y); + +/** + * Set the size of a window's client area. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to get the real client area size in pixels. + * + * Fullscreen windows automatically match the size of the display mode, and + * you should use SDL_SetWindowDisplayMode() to change their size. + * + * \param window the window to change + * \param w the width of the window in pixels, in screen coordinates, must be + * > 0 + * \param h the height of the window in pixels, in screen coordinates, must be + * > 0 + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSize + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, + int h); + +/** + * Get the size of a window's client area. + * + * NULL can safely be passed as the `w` or `h` parameter if the width or + * height value is not desired. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize(), + * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to get the + * real client area size in pixels. + * + * \param window the window to query the width and height from + * \param w a pointer filled in with the width of the window, in screen + * coordinates, may be NULL + * \param h a pointer filled in with the height of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetDrawableSize + * \sa SDL_Vulkan_GetDrawableSize + * \sa SDL_SetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, + int *h); + +/** + * Get the size of a window's borders (decorations) around the client area. + * + * Note: If this function fails (returns -1), the size values will be + * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as if the + * window in question was borderless. + * + * Note: This function may fail on systems where the window has not yet been + * decorated by the display server (for example, immediately after calling + * SDL_CreateWindow). It is recommended that you wait at least until the + * window has been presented and composited, so that the window system has a + * chance to decorate the window and provide the border dimensions to SDL. + * + * This function also returns -1 if getting the information is not supported. + * + * \param window the window to query the size values of the border + * (decorations) from + * \param top pointer to variable for storing the size of the top border; NULL + * is permitted + * \param left pointer to variable for storing the size of the left border; + * NULL is permitted + * \param bottom pointer to variable for storing the size of the bottom + * border; NULL is permitted + * \param right pointer to variable for storing the size of the right border; + * NULL is permitted + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowSize + */ +extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, + int *top, int *left, + int *bottom, int *right); + +/** + * Set the minimum size of a window's client area. + * + * \param window the window to change + * \param min_w the minimum width of the window in pixels + * \param min_h the minimum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, + int min_w, int min_h); + +/** + * Get the minimum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the minimum width of the window, may be + * NULL + * \param h a pointer filled in with the minimum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the maximum size of a window's client area. + * + * \param window the window to change + * \param max_w the maximum width of the window in pixels + * \param max_h the maximum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, + int max_w, int max_h); + +/** + * Get the maximum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the maximum width of the window, may be + * NULL + * \param h a pointer filled in with the maximum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the border state of a window. + * + * This will add or remove the window's `SDL_WINDOW_BORDERLESS` flag and add + * or remove the border from the actual window. This is a no-op if the + * window's border already matches the requested state. + * + * You can't change the border state of a fullscreen window. + * + * \param window the window of which to change the border state + * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, + SDL_bool bordered); + +/** + * Set the user-resizable state of a window. + * + * This will add or remove the window's `SDL_WINDOW_RESIZABLE` flag and + * allow/disallow user resizing of the window. This is a no-op if the window's + * resizable state already matches the requested state. + * + * You can't change the resizable state of a fullscreen window. + * + * \param window the window of which to change the resizable state + * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, + SDL_bool resizable); + +/** + * Set the window to always be above the others. + * + * This will add or remove the window's `SDL_WINDOW_ALWAYS_ON_TOP` flag. This + * will bring the window to the front and keep the window above the rest. + * + * \param window The window of which to change the always on top state + * \param on_top SDL_TRUE to set the window always on top, SDL_FALSE to + * disable + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowAlwaysOnTop(SDL_Window * window, + SDL_bool on_top); + +/** + * Show a window. + * + * \param window the window to show + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HideWindow + * \sa SDL_RaiseWindow + */ +extern DECLSPEC void SDLCALL SDL_ShowWindow(SDL_Window * window); + +/** + * Hide a window. + * + * \param window the window to hide + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowWindow + */ +extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_Window * window); + +/** + * Raise a window above other windows and set the input focus. + * + * \param window the window to raise + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_Window * window); + +/** + * Make a window as large as possible. + * + * \param window the window to maximize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MinimizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window * window); + +/** + * Minimize a window to an iconic representation. + * + * \param window the window to minimize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MinimizeWindow(SDL_Window * window); + +/** + * Restore the size and position of a minimized or maximized window. + * + * \param window the window to restore + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + */ +extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); + +/** + * Set a window's fullscreen state. + * + * `flags` may be `SDL_WINDOW_FULLSCREEN`, for "real" fullscreen with a + * videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" fullscreen + * that takes the size of the desktop; and 0 for windowed mode. + * + * \param window the window to change + * \param flags `SDL_WINDOW_FULLSCREEN`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0 + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, + Uint32 flags); + +/** + * Get the SDL surface associated with the window. + * + * A new surface will be created with the optimal format for the window, if + * necessary. This surface will be freed when the window is destroyed. Do not + * free this surface. + * + * This surface will be invalidated if the window is resized. After resizing a + * window this function must be called again to return a valid surface. + * + * You may not combine this with 3D or the rendering API on this window. + * + * This function is affected by `SDL_HINT_FRAMEBUFFER_ACCELERATION`. + * + * \param window the window to query + * \returns the surface associated with the window, or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UpdateWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window); + +/** + * Copy the window surface to the screen. + * + * This is the function you use to reflect any changes to the surface on the + * screen. + * + * This function is equivalent to the SDL 1.2 API SDL_Flip(). + * + * \param window the window to update + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); + +/** + * Copy areas of the window surface to the screen. + * + * This is the function you use to reflect changes to portions of the surface + * on the screen. + * + * This function is equivalent to the SDL 1.2 API SDL_UpdateRects(). + * + * \param window the window to update + * \param rects an array of SDL_Rect structures representing areas of the + * surface to copy + * \param numrects the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurface + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, + const SDL_Rect * rects, + int numrects); + +/** + * Set a window's input grab mode. + * + * When input is grabbed, the mouse is confined to the window. This function + * will also grab the keyboard if `SDL_HINT_GRAB_KEYBOARD` is set. To grab the + * keyboard without also grabbing the mouse, use SDL_SetWindowKeyboardGrab(). + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window the window for which the input grab mode should be set + * \param grabbed SDL_TRUE to grab input or SDL_FALSE to release input + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGrabbedWindow + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's keyboard grab mode. + * + * Keyboard grab enables capture of system keyboard shortcuts like Alt+Tab or + * the Meta/Super key. Note that not all system keyboard shortcuts can be + * captured by applications (one example is Ctrl+Alt+Del on Windows). + * + * This is primarily intended for specialized applications such as VNC clients + * or VM frontends. Normal games should not use keyboard grab. + * + * When keyboard grab is enabled, SDL will continue to handle Alt+Tab when the + * window is full-screen to ensure the user is not trapped in your + * application. If you have a custom keyboard shortcut to exit fullscreen + * mode, you may suppress this behavior with + * `SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED`. + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window The window for which the keyboard grab mode should be set. + * \param grabbed This is SDL_TRUE to grab keyboard, and SDL_FALSE to release. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowKeyboardGrab + * \sa SDL_SetWindowMouseGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's mouse grab mode. + * + * Mouse grab confines the mouse cursor to the window. + * + * \param window The window for which the mouse grab mode should be set. + * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowMouseGrab + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMouseGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Get a window's input grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if input is grabbed, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); + +/** + * Get a window's keyboard grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if keyboard is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowKeyboardGrab(SDL_Window * window); + +/** + * Get a window's mouse grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if mouse is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowMouseGrab(SDL_Window * window); + +/** + * Get the window that currently has an input grab enabled. + * + * \returns the window if input is grabbed or NULL otherwise. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetWindowGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void); + +/** + * Confines the cursor to the specified area of a window. + * + * Note that this does NOT grab the cursor, it only defines the area a cursor + * is restricted to when the window has mouse focus. + * + * \param window The window that will be associated with the barrier. + * \param rect A rectangle area in window-relative coordinates. If NULL the + * barrier for the specified window will be destroyed. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetWindowMouseRect + * \sa SDL_SetWindowMouseGrab + */ +extern DECLSPEC int SDLCALL SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect); + +/** + * Get the mouse confinement rectangle of a window. + * + * \param window The window to query + * \returns A pointer to the mouse confinement rectangle of a window, or NULL + * if there isn't one. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetWindowMouseRect + */ +extern DECLSPEC const SDL_Rect * SDLCALL SDL_GetWindowMouseRect(SDL_Window * window); + +/** + * Set the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method sets the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The + * brightness set will not follow the window if it is moved to another + * display. + * + * Many platforms will refuse to set the display brightness in modern times. + * You are better off using a shader to adjust gamma during rendering, or + * something similar. + * + * \param window the window used to select the display whose brightness will + * be changed + * \param brightness the brightness (gamma multiplier) value to set where 0.0 + * is completely dark and 1.0 is normal brightness + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowBrightness + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float brightness); + +/** + * Get the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method retrieves the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose brightness will + * be queried + * \returns the brightness for the display where 0.0 is completely dark and + * 1.0 is normal brightness. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowBrightness + */ +extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window); + +/** + * Set the opacity for a window. + * + * The parameter `opacity` will be clamped internally between 0.0f + * (transparent) and 1.0f (opaque). + * + * This function also returns -1 if setting the opacity isn't supported. + * + * \param window the window which will be made transparent or opaque + * \param opacity the opacity value (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity); + +/** + * Get the opacity of a window. + * + * If transparency isn't supported on this platform, opacity will be reported + * as 1.0f without error. + * + * The parameter `opacity` is ignored if it is NULL. + * + * This function also returns -1 if an invalid window was provided. + * + * \param window the window to get the current opacity value from + * \param out_opacity the float filled in (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_SetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity); + +/** + * Set the window as a modal for another window. + * + * \param modal_window the window that should be set modal + * \param parent_window the parent window for the modal window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window); + +/** + * Explicitly set input focus to the window. + * + * You almost certainly want SDL_RaiseWindow() instead of this function. Use + * this with caution, as you might give focus to a window that is completely + * obscured by other windows. + * + * \param window the window that should get the input focus + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RaiseWindow + */ +extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window); + +/** + * Set the gamma ramp for the display that owns a given window. + * + * Set the gamma translation table for the red, green, and blue channels of + * the video hardware. Each table is an array of 256 16-bit quantities, + * representing a mapping between the input and output for that channel. The + * input is the index into the array, and the output is the 16-bit gamma value + * at that index, scaled to the output color precision. + * + * Despite the name and signature, this method sets the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The gamma + * ramp set will not follow the window if it is moved to another display. + * + * \param window the window used to select the display whose gamma ramp will + * be changed + * \param red a 256 element array of 16-bit quantities representing the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities representing the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities representing the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowGammaRamp(SDL_Window * window, + const Uint16 * red, + const Uint16 * green, + const Uint16 * blue); + +/** + * Get the gamma ramp for a given window's display. + * + * Despite the name and signature, this method retrieves the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose gamma ramp will + * be queried + * \param red a 256 element array of 16-bit quantities filled in with the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities filled in with the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities filled in with the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window, + Uint16 * red, + Uint16 * green, + Uint16 * blue); + +/** + * Possible return values from the SDL_HitTest callback. + * + * \sa SDL_HitTest + */ +typedef enum +{ + SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */ + SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */ + SDL_HITTEST_RESIZE_TOPLEFT, + SDL_HITTEST_RESIZE_TOP, + SDL_HITTEST_RESIZE_TOPRIGHT, + SDL_HITTEST_RESIZE_RIGHT, + SDL_HITTEST_RESIZE_BOTTOMRIGHT, + SDL_HITTEST_RESIZE_BOTTOM, + SDL_HITTEST_RESIZE_BOTTOMLEFT, + SDL_HITTEST_RESIZE_LEFT +} SDL_HitTestResult; + +/** + * Callback used for hit-testing. + * + * \param win the SDL_Window where hit-testing was set on + * \param area an SDL_Point which should be hit-tested + * \param data what was passed as `callback_data` to SDL_SetWindowHitTest() + * \return an SDL_HitTestResult value. + * + * \sa SDL_SetWindowHitTest + */ +typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win, + const SDL_Point *area, + void *data); + +/** + * Provide a callback that decides if a window region has special properties. + * + * Normally windows are dragged and resized by decorations provided by the + * system window manager (a title bar, borders, etc), but for some apps, it + * makes sense to drag them from somewhere else inside the window itself; for + * example, one might have a borderless window that wants to be draggable from + * any part, or simulate its own title bar, etc. + * + * This function lets the app provide a callback that designates pieces of a + * given window as special. This callback is run during event processing if we + * need to tell the OS to treat a region of the window specially; the use of + * this callback is known as "hit testing." + * + * Mouse input may not be delivered to your application if it is within a + * special area; the OS will often apply that input to moving the window or + * resizing the window and not deliver it to the application. + * + * Specifying NULL for a callback disables hit-testing. Hit-testing is + * disabled by default. + * + * Platforms that don't support this functionality will return -1 + * unconditionally, even if you're attempting to disable hit-testing. + * + * Your callback may fire at any time, and its firing does not indicate any + * specific behavior (for example, on Windows, this certainly might fire when + * the OS is deciding whether to drag your window, but it fires for lots of + * other reasons, too, some unrelated to anything you probably care about _and + * when the mouse isn't actually at the location it is testing_). Since this + * can fire at any time, you should try to keep your callback efficient, + * devoid of allocations, etc. + * + * \param window the window to set hit-testing on + * \param callback the function to call when doing a hit-test + * \param callback_data an app-defined void pointer passed to **callback** + * \returns 0 on success or -1 on error (including unsupported); call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window, + SDL_HitTest callback, + void *callback_data); + +/** + * Request a window to demand attention from the user. + * + * \param window the window to be flashed + * \param operation the flash operation + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation); + +/** + * Destroy a window. + * + * If `window` is NULL, this function will return immediately after setting + * the SDL error message to "Invalid window". See SDL_GetError(). + * + * \param window the window to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_CreateWindowFrom + */ +extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window); + + +/** + * Check whether the screensaver is currently enabled. + * + * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 + * the screensaver was enabled by default. + * + * The default can also be changed using `SDL_HINT_VIDEO_ALLOW_SCREENSAVER`. + * + * \returns SDL_TRUE if the screensaver is enabled, SDL_FALSE if it is + * disabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_EnableScreenSaver + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenSaverEnabled(void); + +/** + * Allow the screen to be blanked by a screen saver. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void); + +/** + * Prevent the screen from being blanked by a screen saver. + * + * If you disable the screensaver, it is automatically re-enabled when SDL + * quits. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_EnableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); + + +/** + * \name OpenGL support functions + */ +/* @{ */ + +/** + * Dynamically load an OpenGL library. + * + * This should be done after initializing the video driver, but before + * creating any OpenGL windows. If no OpenGL library is loaded, the default + * library will be loaded upon creation of the first OpenGL window. + * + * If you do this, you need to retrieve all of the GL functions used in your + * program from the dynamic library using SDL_GL_GetProcAddress(). + * + * \param path the platform dependent OpenGL library name, or NULL to open the + * default OpenGL library + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetProcAddress + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); + +/** + * Get an OpenGL function by name. + * + * If the GL library is loaded at runtime with SDL_GL_LoadLibrary(), then all + * GL functions must be retrieved this way. Usually this is used to retrieve + * function pointers to OpenGL extensions. + * + * There are some quirks to looking up OpenGL functions that require some + * extra care from the application. If you code carefully, you can handle + * these quirks without any platform-specific code, though: + * + * - On Windows, function pointers are specific to the current GL context; + * this means you need to have created a GL context and made it current + * before calling SDL_GL_GetProcAddress(). If you recreate your context or + * create a second context, you should assume that any existing function + * pointers aren't valid to use with it. This is (currently) a + * Windows-specific limitation, and in practice lots of drivers don't suffer + * this limitation, but it is still the way the wgl API is documented to + * work and you should expect crashes if you don't respect it. Store a copy + * of the function pointers that comes and goes with context lifespan. + * - On X11, function pointers returned by this function are valid for any + * context, and can even be looked up before a context is created at all. + * This means that, for at least some common OpenGL implementations, if you + * look up a function that doesn't exist, you'll get a non-NULL result that + * is _NOT_ safe to call. You must always make sure the function is actually + * available for a given GL context before calling it, by checking for the + * existence of the appropriate extension with SDL_GL_ExtensionSupported(), + * or verifying that the version of OpenGL you're using offers the function + * as core functionality. + * - Some OpenGL drivers, on all platforms, *will* return NULL if a function + * isn't supported, but you can't count on this behavior. Check for + * extensions you use, and if you get a NULL anyway, act as if that + * extension wasn't available. This is probably a bug in the driver, but you + * can code defensively for this scenario anyhow. + * - Just because you're on Linux/Unix, don't assume you'll be using X11. + * Next-gen display servers are waiting to replace it, and may or may not + * make the same promises about function pointers. + * - OpenGL function pointers must be declared `APIENTRY` as in the example + * code. This will ensure the proper calling convention is followed on + * platforms where this matters (Win32) thereby avoiding stack corruption. + * + * \param proc the name of an OpenGL function + * \returns a pointer to the named OpenGL function. The returned pointer + * should be cast to the appropriate function signature. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ExtensionSupported + * \sa SDL_GL_LoadLibrary + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); + +/** + * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void); + +/** + * Check if an OpenGL extension is supported for the current context. + * + * This function operates on the current GL context; you must have created a + * context and it must be current before calling this function. Do not assume + * that all contexts you create will have the same set of extensions + * available, or that recreating an existing context will offer the same + * extensions again. + * + * While it's probably not a massive overhead, this function is not an O(1) + * operation. Check the extensions you care about after creating the GL + * context and save that information somewhere instead of calling the function + * every time you need to know. + * + * \param extension the name of the extension to check + * \returns SDL_TRUE if the extension is supported, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char + *extension); + +/** + * Reset all previously set OpenGL context attributes to their default values. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC void SDLCALL SDL_GL_ResetAttributes(void); + +/** + * Set an OpenGL window attribute before window creation. + * + * This function sets the OpenGL attribute `attr` to `value`. The requested + * attributes should be set before creating an OpenGL window. You should use + * SDL_GL_GetAttribute() to check the values after creating the OpenGL + * context, since the values obtained can differ from the requested ones. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to set + * \param value the desired value for the attribute + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_ResetAttributes + */ +extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/** + * Get the actual value for an attribute from the current context. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to get + * \param value a pointer filled in with the current value of `attr` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ResetAttributes + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); + +/** + * Create an OpenGL context for an OpenGL window, and make it current. + * + * Windows users new to OpenGL should note that, for historical reasons, GL + * functions added after OpenGL version 1.1 are not available by default. + * Those functions must be loaded at run-time, either with an OpenGL + * extension-handling library or with SDL_GL_GetProcAddress() and its related + * functions. + * + * SDL_GLContext is an alias for `void *`. It's opaque to the application. + * + * \param window the window to associate with the context + * \returns the OpenGL context associated with `window` or NULL on error; call + * SDL_GetError() for more details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_DeleteContext + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * + window); + +/** + * Set up an OpenGL context for rendering into an OpenGL window. + * + * The context must have been created with a compatible window. + * + * \param window the window to associate with the context + * \param context the OpenGL context to associate with the window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, + SDL_GLContext context); + +/** + * Get the currently active OpenGL window. + * + * \returns the currently active OpenGL window on success or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); + +/** + * Get the currently active OpenGL context. + * + * \returns the currently active OpenGL context or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); + +/** + * Get the size of a window's underlying drawable in pixels. + * + * This returns info useful for calling glViewport(). + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window the window from which the drawable size should be queried + * \param w a pointer to variable for storing the width in pixels, may be NULL + * \param h a pointer to variable for storing the height in pixels, may be + * NULL + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_CreateWindow + * \sa SDL_GetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w, + int *h); + +/** + * Set the swap interval for the current OpenGL context. + * + * Some systems allow specifying -1 for the interval, to enable adaptive + * vsync. Adaptive vsync works the same as vsync, but if you've already missed + * the vertical retrace for a given frame, it swaps buffers immediately, which + * might be less jarring for the user during occasional framerate drops. If an + * application requests adaptive vsync and the system does not support it, + * this function will fail and return -1. In such a case, you should probably + * retry the call with 1 for the interval. + * + * Adaptive vsync is implemented for some glX drivers with + * GLX_EXT_swap_control_tear, and for some Windows drivers with + * WGL_EXT_swap_control_tear. + * + * Read more on the Khronos wiki: + * https://www.khronos.org/opengl/wiki/Swap_Interval#Adaptive_Vsync + * + * \param interval 0 for immediate updates, 1 for updates synchronized with + * the vertical retrace, -1 for adaptive vsync + * \returns 0 on success or -1 if setting the swap interval is not supported; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); + +/** + * Get the swap interval for the current OpenGL context. + * + * If the system can't determine the swap interval, or there isn't a valid + * current context, this function will return 0 as a safe default. + * + * \returns 0 if there is no vertical retrace synchronization, 1 if the buffer + * swap is synchronized with the vertical retrace, and -1 if late + * swaps happen immediately instead of waiting for the next retrace; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_SetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); + +/** + * Update a window with OpenGL rendering. + * + * This is used with double-buffered OpenGL contexts, which are the default. + * + * On macOS, make sure you bind 0 to the draw framebuffer before swapping the + * window, otherwise nothing will happen. If you aren't using + * glBindFramebuffer(), this is the default and you won't have to do anything + * extra. + * + * \param window the window to change + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window * window); + +/** + * Delete an OpenGL context. + * + * \param context the OpenGL context to be deleted + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context); + +/* @} *//* OpenGL support functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/thirdparty/SDL/include/SDL/SDL_vulkan.h b/thirdparty/SDL/include/SDL/SDL_vulkan.h new file mode 100644 index 00000000..ab86a0b8 --- /dev/null +++ b/thirdparty/SDL/include/SDL/SDL_vulkan.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef SDL_vulkan_h_ +#define SDL_vulkan_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid including vulkan.h, don't define VkInstance if it's already included */ +#ifdef VULKAN_H_ +#define NO_SDL_VULKAN_TYPEDEFS +#endif +#ifndef NO_SDL_VULKAN_TYPEDEFS +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#endif /* !NO_SDL_VULKAN_TYPEDEFS */ + +typedef VkInstance SDL_vulkanInstance; +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */ + +/** + * \name Vulkan support functions + * + * \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API + * is compatable with Tizen's implementation of Vulkan in SDL. + */ +/* @{ */ + +/** + * Dynamically load the Vulkan loader library. + * + * This should be called after initializing the video driver, but before + * creating any Vulkan windows. If no Vulkan loader library is loaded, the + * default library will be loaded upon creation of the first Vulkan window. + * + * It is fairly common for Vulkan applications to link with libvulkan instead + * of explicitly loading it at run time. This will work with SDL provided the + * application links to a dynamic library and both it and SDL use the same + * search path. + * + * If you specify a non-NULL `path`, an application should retrieve all of the + * Vulkan functions it uses from the dynamic library using + * SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points + * to the same vulkan loader library the application linked to. + * + * On Apple devices, if `path` is NULL, SDL will attempt to find the + * `vkGetInstanceProcAddr` address within all the Mach-O images of the current + * process. This is because it is fairly common for Vulkan applications to + * link with libvulkan (and historically MoltenVK was provided as a static + * library). If it is not found, on macOS, SDL will attempt to load + * `vulkan.framework/vulkan`, `libvulkan.1.dylib`, + * `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On + * iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a + * dynamic framework or .dylib must ensure it is included in its application + * bundle. + * + * On non-Apple devices, application linking with a static libvulkan is not + * supported. Either do not link to the Vulkan loader or link to a dynamic + * library version. + * + * \param path The platform dependent Vulkan loader library name or NULL + * \returns 0 on success or -1 if the library couldn't be loaded; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetVkInstanceProcAddr + * \sa SDL_Vulkan_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path); + +/** + * Get the address of the `vkGetInstanceProcAddr` function. + * + * This should be called after either calling SDL_Vulkan_LoadLibrary() or + * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag. + * + * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void); + +/** + * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary() + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void); + +/** + * Get the names of the Vulkan instance extensions needed to create a surface + * with SDL_Vulkan_CreateSurface. + * + * If `pNames` is NULL, then the number of required Vulkan instance extensions + * is returned in `pCount`. Otherwise, `pCount` must point to a variable set + * to the number of elements in the `pNames` array, and on return the variable + * is overwritten with the number of names actually written to `pNames`. If + * `pCount` is less than the number of required extensions, at most `pCount` + * structures will be written. If `pCount` is smaller than the number of + * required extensions, SDL_FALSE will be returned instead of SDL_TRUE, to + * indicate that not all the required extensions were returned. + * + * The `window` parameter is currently needed to be valid as of SDL 2.0.8, + * however, this parameter will likely be removed in future releases + * + * \param window A window for which the required Vulkan instance extensions + * should be retrieved (will be deprecated in a future release) + * \param pCount A pointer to an unsigned int corresponding to the number of + * extensions to be returned + * \param pNames NULL or a pointer to an array to be filled with required + * Vulkan instance extensions + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, + unsigned int *pCount, + const char **pNames); + +/** + * Create a Vulkan rendering surface for a window. + * + * The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and + * `instance` must have been created with extensions returned by + * SDL_Vulkan_GetInstanceExtensions() enabled. + * + * \param window The window to which to attach the Vulkan surface + * \param instance The Vulkan instance handle + * \param surface A pointer to a VkSurfaceKHR handle to output the newly + * created surface + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetInstanceExtensions + * \sa SDL_Vulkan_GetDrawableSize + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * Get the size of the window's underlying drawable dimensions in pixels. + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window an SDL_Window for which the size is to be queried + * \param w Pointer to the variable to write the width to or NULL + * \param h Pointer to the variable to write the height to or NULL + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + +/* @} *//* Vulkan support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_vulkan_h_ */ diff --git a/thirdparty/SDL/include/SDL/begin_code.h b/thirdparty/SDL/include/SDL/begin_code.h new file mode 100644 index 00000000..b3e69e85 --- /dev/null +++ b/thirdparty/SDL/include/SDL/begin_code.h @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file begin_code.h + * + * This file sets things up for C dynamic library function definitions, + * static inlined functions, and structures aligned at 4-byte alignment. + * If you don't like ugly C preprocessor code, don't look at this file. :) + */ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +#ifndef SDL_DEPRECATED +# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# define SDL_DEPRECATED __attribute__((deprecated)) +# else +# define SDL_DEPRECATED +# endif +#endif + +#ifndef SDL_UNUSED +# ifdef __GNUC__ +# define SDL_UNUSED __attribute__((unused)) +# else +# define SDL_UNUSED +# endif +#endif + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) || defined(__GDK__) +# ifdef DLL_EXPORT +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# elif defined(__OS2__) +# ifdef BUILD_SDL +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if (defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)) && !defined(__GNUC__) +#define SDLCALL __cdecl +#elif defined(__OS2__) || defined(__EMX__) +#define SDLCALL _System +# if defined (__GNUC__) && !defined(_System) +# define _System /* for old EMX/GCC compat. */ +# endif +#else +#define SDLCALL +#endif +#endif /* SDLCALL */ + +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ +#ifdef __SYMBIAN32__ +#undef DECLSPEC +#define DECLSPEC +#endif /* __SYMBIAN32__ */ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpragma-pack" +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#ifdef _WIN64 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ +#pragma pack(push,8) +#else +#pragma pack(push,4) +#endif +#endif /* Compiler needs structure packing set */ + +#ifndef SDL_INLINE +#if defined(__GNUC__) +#define SDL_INLINE __inline__ +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) || defined(__CC_ARM) +#define SDL_INLINE __inline +#ifndef __inline__ +#define __inline__ __inline +#endif +#else +#define SDL_INLINE inline +#ifndef __inline__ +#define __inline__ inline +#endif +#endif +#endif /* SDL_INLINE not defined */ + +#ifndef SDL_FORCE_INLINE +#if defined(_MSC_VER) +#define SDL_FORCE_INLINE __forceinline +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ +#else +#define SDL_FORCE_INLINE static SDL_INLINE +#endif +#endif /* SDL_FORCE_INLINE not defined */ + +#ifndef SDL_NORETURN +#if defined(__GNUC__) +#define SDL_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define SDL_NORETURN __declspec(noreturn) +#else +#define SDL_NORETURN +#endif +#endif /* SDL_NORETURN not defined */ + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ + +#ifndef SDL_FALLTHROUGH +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) +#define SDL_FALLTHROUGH [[fallthrough]] +#else +#if defined(__has_attribute) +#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__) +#else +#define _HAS_FALLTHROUGH 0 +#endif /* __has_attribute */ +#if _HAS_FALLTHROUGH && \ + ((defined(__GNUC__) && __GNUC__ >= 7) || \ + (defined(__clang_major__) && __clang_major__ >= 10)) +#define SDL_FALLTHROUGH __attribute__((__fallthrough__)) +#else +#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ +#endif /* _HAS_FALLTHROUGH */ +#undef _HAS_FALLTHROUGH +#endif /* C++17 or C2x */ +#endif /* SDL_FALLTHROUGH not defined */ diff --git a/thirdparty/SDL/include/SDL/close_code.h b/thirdparty/SDL/include/SDL/close_code.h new file mode 100644 index 00000000..dc73432f --- /dev/null +++ b/thirdparty/SDL/include/SDL/close_code.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file close_code.h + * + * This file reverses the effects of begin_code.h and should be included + * after you finish any function and structure declarations in your headers + */ + +#ifndef _begin_code_h +#error close_code.h included without matching begin_code.h +#endif +#undef _begin_code_h + +/* Reset structure packing at previous byte alignment */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(pop) +#endif /* Compiler needs structure packing set */ diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.sln b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.sln new file mode 100644 index 00000000..829b4019 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.vcproj new file mode 100644 index 00000000..9ce4b96e --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest-md.vcproj @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.sln b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.sln new file mode 100644 index 00000000..c1b29296 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcproj new file mode 100644 index 00000000..a4eb20ad --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcproj @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcxproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcxproj new file mode 100644 index 00000000..fa7d3509 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} + Win32Proj + + + + StaticLibrary + MultiByte + v110_xp + + + StaticLibrary + MultiByte + v110_xp + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + + + + Disabled + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + OldStyle + + + $(OutDir)gtestd.lib + + + + + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + OldStyle + + + $(OutDir)gtest.lib + + + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main-md.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main-md.vcproj new file mode 100644 index 00000000..0f92f224 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main-md.vcproj @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcproj new file mode 100644 index 00000000..c65046f2 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcproj @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcxproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcxproj new file mode 100644 index 00000000..effef802 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_main.vcxproj @@ -0,0 +1,106 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {3AF54C8A-10BF-4332-9147-F68ED9862032} + Win32Proj + + + + StaticLibrary + MultiByte + v110_xp + + + StaticLibrary + MultiByte + v110_xp + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + + + + Disabled + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + OldStyle + + + $(OutDir)$(ProjectName)d.lib + + + + + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + OldStyle + + + $(OutDir)$(ProjectName).lib + + + + + {c8f6c172-56f2-4e76-b5fa-c3b423b31be7} + true + true + + + + + ..;..\include;%(AdditionalIncludeDirectories) + ..;..\include;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test-md.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test-md.vcproj new file mode 100644 index 00000000..4071d28f --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test-md.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test.vcproj new file mode 100644 index 00000000..8cda7c02 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_prod_test.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest-md.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest-md.vcproj new file mode 100644 index 00000000..15259397 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest-md.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest.vcproj b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest.vcproj new file mode 100644 index 00000000..45523405 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/msvc/gtest_unittest.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/thirdparty/protobuf-2.3.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj new file mode 100644 index 00000000..82449104 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj @@ -0,0 +1,320 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; }; + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; + 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC271046D72200DEF522 /* gtest.framework */; }; + 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC421046D7B300DEF522 /* libgtest_main.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = gTestExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = ""; }; + 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = ""; }; + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = ""; }; + 408BEC271046D72200DEF522 /* gtest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = gtest.framework; path = /Library/Frameworks/gtest.framework; sourceTree = ""; }; + 408BEC421046D7B300DEF522 /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /Library/Frameworks/gtest.framework/Versions/A/Resources/libgtest_main.a; sourceTree = ""; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3B07BDE80E3F3F9E00647869 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, + 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */, + 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */, + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gTestExample */ = { + isa = PBXGroup; + children = ( + 08FB77ACFE841707C02AAC07 /* Source */, + 089C1665FE841158C02AAC07 /* Resources */, + 3B07BE350E4094E400647869 /* Test */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gTestExample; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 408BEC421046D7B300DEF522 /* libgtest_main.a */, + 408BEC271046D72200DEF522 /* gtest.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 3B7EB1230E5AEE3500C7F239 /* widget.cc */, + 3B7EB1240E5AEE3500C7F239 /* widget.h */, + ); + name = Source; + sourceTree = ""; + }; + 3B07BE350E4094E400647869 /* Test */ = { + isa = PBXGroup; + children = ( + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */, + ); + name = Test; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */; + buildPhases = ( + 3B07BDE70E3F3F9E00647869 /* Sources */, + 3B07BDE80E3F3F9E00647869 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */, + ); + name = WidgetFrameworkTest; + productName = gTestExampleTest; + productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WidgetFramework; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gTestExample; + productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */, + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3B07BDE70E3F3F9E00647869 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B07BDEC0E3F3F9F00647869 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Debug; + }; + 3B07BDED0E3F3F9F00647869 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B07BDEC0E3F3F9F00647869 /* Debug */, + 3B07BDED0E3F3F9F00647869 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/thirdparty/protobuf-2.3.0/gtest/xcode/gtest.xcodeproj/project.pbxproj b/thirdparty/protobuf-2.3.0/gtest/xcode/gtest.xcodeproj/project.pbxproj new file mode 100644 index 00000000..4234e728 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/gtest/xcode/gtest.xcodeproj/project.pbxproj @@ -0,0 +1,1080 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 3B238F5F0E828B5400846E11 /* Check */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */; + buildPhases = ( + 3B238F5E0E828B5400846E11 /* ShellScript */, + ); + dependencies = ( + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, + 40C849F7101A43440083642A /* PBXTargetDependency */, + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, + 40C849F9101A43490083642A /* PBXTargetDependency */, + ); + name = Check; + productName = Check; + }; + 40C44ADC0E3798F4008FCC51 /* Version Info */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; + buildPhases = ( + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */, + ); + comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target."; + dependencies = ( + ); + name = "Version Info"; + productName = Version.h; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; }; + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; + 404884AE0E2F7CD900CF7658 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* COPYING */; }; + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40899F420FFA7184000B29AE; + remoteInfo = gtest_unittest; + }; + 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4089A0120FFACEFC000B29AE; + remoteInfo = sample1_unittest; + }; + 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; + remoteInfo = Version.h; + }; + 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8497A101A36850083642A; + remoteInfo = "gtest_unittest-static"; + }; + 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C84989101A36A60083642A; + remoteInfo = "sample1_unittest-static"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Headers/internal; + dstSubfolderSpec = 6; + files = ( + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */, + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */, + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, + ); + name = "Copy Headers Internal"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = ""; }; + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = ""; }; + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = ""; }; + 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = ""; }; + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = ""; }; + 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = ""; }; + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = ""; }; + 404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = ""; }; + 404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = ""; }; + 404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = ""; }; + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = ""; }; + 404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = ""; }; + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = ""; }; + 404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = ""; }; + 404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = ""; }; + 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = ""; }; + 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = ""; }; + 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; + 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = ""; }; + 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; + 404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; }; + 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = ""; }; + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = ""; }; + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = ""; }; + 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = ""; }; + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = ""; }; + 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = ""; }; + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = ""; }; + 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = ""; }; + 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = ""; }; + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = ""; }; + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = ""; }; + 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 40899F410FFA7184000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A4101A37150083642A /* gtest.framework in Frameworks */, + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0110FFACEFC000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A2101A37050083642A /* gtest.framework in Frameworks */, + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84981101A36850083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84982101A36850083642A /* libgtest.a in Frameworks */, + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84991101A36A60083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84992101A36A60083642A /* libgtest.a in Frameworks */, + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 4539C8FF0EC27F6400A70F4C /* gtest.framework */, + 40C848FA101A209C0083642A /* libgtest.a */, + 40C8490B101A217E0083642A /* libgtest_main.a */, + 40899F430FFA7184000B29AE /* gtest_unittest-framework */, + 40C84987101A36850083642A /* gtest_unittest */, + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84997101A36A60083642A /* sample1_unittest-static */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gtest */ = { + isa = PBXGroup; + children = ( + 40D4CDF00E30E07400294801 /* Config */, + 08FB77ACFE841707C02AAC07 /* Source */, + 40D4CF4E0E30F5E200294801 /* Resources */, + 403EE37B0E377822004BD1E2 /* Scripts */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gtest; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 404884A90E2F7CD900CF7658 /* CHANGES */, + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, + 404884AB0E2F7CD900CF7658 /* COPYING */, + 404883F60E2F799B00CF7658 /* README */, + 404883D90E2F799B00CF7658 /* include */, + 4089A02F0FFACF84000B29AE /* samples */, + 404884070E2F799B00CF7658 /* src */, + 3B238BF00E7FE13B00846E11 /* test */, + ); + name = Source; + sourceTree = ""; + }; + 3B238BF00E7FE13B00846E11 /* test */ = { + isa = PBXGroup; + children = ( + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, + ); + name = test; + path = ../test; + sourceTree = SOURCE_ROOT; + }; + 403EE37B0E377822004BD1E2 /* Scripts */ = { + isa = PBXGroup; + children = ( + 403EE37C0E377822004BD1E2 /* versiongenerate.py */, + 3B87D2100E96B92E000D1852 /* runtests.sh */, + ); + path = Scripts; + sourceTree = ""; + }; + 404883D90E2F799B00CF7658 /* include */ = { + isa = PBXGroup; + children = ( + 404883DA0E2F799B00CF7658 /* gtest */, + ); + name = include; + path = ../include; + sourceTree = SOURCE_ROOT; + }; + 404883DA0E2F799B00CF7658 /* gtest */ = { + isa = PBXGroup; + children = ( + 404883E10E2F799B00CF7658 /* internal */, + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */, + 404883DC0E2F799B00CF7658 /* gtest-message.h */, + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */, + 404883DD0E2F799B00CF7658 /* gtest-spi.h */, + 404883DE0E2F799B00CF7658 /* gtest.h */, + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, + 404883E00E2F799B00CF7658 /* gtest_prod.h */, + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, + ); + path = gtest; + sourceTree = ""; + }; + 404883E10E2F799B00CF7658 /* internal */ = { + isa = PBXGroup; + children = ( + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, + 404883E30E2F799B00CF7658 /* gtest-filepath.h */, + 404883E40E2F799B00CF7658 /* gtest-internal.h */, + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */, + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */, + 4539C9370EC280E200A70F4C /* gtest-param-util.h */, + 404883E50E2F799B00CF7658 /* gtest-port.h */, + 404883E60E2F799B00CF7658 /* gtest-string.h */, + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, + ); + path = internal; + sourceTree = ""; + }; + 404884070E2F799B00CF7658 /* src */ = { + isa = PBXGroup; + children = ( + 224A12A10E9EADA700BD17FD /* gtest-all.cc */, + 4048840D0E2F799B00CF7658 /* gtest_main.cc */, + ); + name = src; + path = ../src; + sourceTree = SOURCE_ROOT; + }; + 4089A02F0FFACF84000B29AE /* samples */ = { + isa = PBXGroup; + children = ( + 4089A02C0FFACF7F000B29AE /* sample1.cc */, + 4089A02D0FFACF7F000B29AE /* sample1.h */, + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, + ); + name = samples; + path = ../samples; + sourceTree = SOURCE_ROOT; + }; + 40D4CDF00E30E07400294801 /* Config */ = { + isa = PBXGroup; + children = ( + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, + 40D4CDF30E30E07400294801 /* General.xcconfig */, + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, + ); + path = Config; + sourceTree = ""; + }; + 40D4CF4E0E30F5E200294801 /* Resources */ = { + isa = PBXGroup; + children = ( + 40D4CF510E30F5E200294801 /* Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */, + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */, + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */, + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */, + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */, + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; + buildPhases = ( + 40899F400FFA7184000B29AE /* Sources */, + 40899F410FFA7184000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C849A0101A36F10083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-framework"; + productName = gtest_unittest; + productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; + buildPhases = ( + 4089A0100FFACEFC000B29AE /* Sources */, + 4089A0110FFACEFC000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8499E101A36E50083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-framework"; + productName = sample1_unittest; + productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 40C848F9101A209C0083642A /* gtest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; + buildPhases = ( + 40C848F7101A209C0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest-static"; + productName = "gtest-static"; + productReference = 40C848FA101A209C0083642A /* libgtest.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8490A101A217E0083642A /* gtest_main-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; + buildPhases = ( + 40C84908101A217E0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest_main-static"; + productName = "gtest_main-static"; + productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8497A101A36850083642A /* gtest_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; + buildPhases = ( + 40C8497F101A36850083642A /* Sources */, + 40C84981101A36850083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8497B101A36850083642A /* PBXTargetDependency */, + 40C8497D101A36850083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-static"; + productName = gtest_unittest; + productReference = 40C84987101A36850083642A /* gtest_unittest */; + productType = "com.apple.product-type.tool"; + }; + 40C84989101A36A60083642A /* sample1_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; + buildPhases = ( + 40C8498E101A36A60083642A /* Sources */, + 40C84991101A36A60083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8498A101A36A60083642A /* PBXTargetDependency */, + 40C8498C101A36A60083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-static"; + productName = sample1_unittest; + productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 40C44AE60E379922008FCC51 /* PBXTargetDependency */, + 408BEC101046CFE900DEF522 /* PBXTargetDependency */, + 40C8499C101A36DC0083642A /* PBXTargetDependency */, + ); + name = "gtest-framework"; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gtest; + productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* gtest */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, + 40C848F9101A209C0083642A /* gtest-static */, + 40C8490A101A217E0083642A /* gtest_main-static */, + 40899F420FFA7184000B29AE /* gtest_unittest-framework */, + 40C8497A101A36850083642A /* gtest_unittest-static */, + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84989101A36A60083642A /* sample1_unittest-static */, + 3B238F5F0E828B5400846E11 /* Check */, + 40C44ADC0E3798F4008FCC51 /* Version Info */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884500E2F799B00CF7658 /* README in Resources */, + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, + 404884AE0E2F7CD900CF7658 /* COPYING in Resources */, + 40C84978101A36540083642A /* libgtest_main.a in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B238F5E0E828B5400846E11 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh"; + }; + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Scripts/versiongenerate.py", + "$(SRCROOT)/../configure.ac", + ); + name = "Generate Version.h"; + outputPaths = ( + "$(PROJECT_TEMP_DIR)/Version.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 40899F400FFA7184000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0100FFACEFC000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C848F7101A209C0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C848FF101A21150083642A /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84908101A217E0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8497F101A36850083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8498E101A36A60083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C8498F101A36A60083642A /* sample1.cc in Sources */, + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; + targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; + }; + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; + targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; + }; + 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; + }; + 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C44ADC0E3798F4008FCC51 /* Version Info */; + targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; + }; + 40C8497B101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8497D101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8498A101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8498C101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; + }; + 40C8499E101A36E50083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; + }; + 40C849A0101A36F10083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; + }; + 40C849F7101A43440083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8497A101A36850083642A /* gtest_unittest-static */; + targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; + }; + 40C849F9101A43490083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C84989101A36A60083642A /* sample1_unittest-static */; + targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B238F600E828B5400846E11 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = Check; + }; + name = Debug; + }; + 3B238F610E828B5400846E11 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = Check; + ZERO_LINK = NO; + }; + name = Release; + }; + 40899F450FFA7185000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + }; + name = Debug; + }; + 40899F460FFA7185000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + }; + name = Release; + }; + 4089A0150FFACEFD000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-framework"; + }; + name = Debug; + }; + 4089A0160FFACEFD000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-framework"; + }; + name = Release; + }; + 40C44ADF0E3798F4008FCC51 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = gtest; + TARGET_NAME = gtest; + }; + name = Debug; + }; + 40C44AE00E3798F4008FCC51 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = gtest; + TARGET_NAME = gtest; + }; + name = Release; + }; + 40C848FB101A209D0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + }; + name = Debug; + }; + 40C848FC101A209D0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + }; + name = Release; + }; + 40C8490E101A217F0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + }; + name = Debug; + }; + 40C8490F101A217F0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + }; + name = Release; + }; + 40C84985101A36850083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + }; + name = Debug; + }; + 40C84986101A36850083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + }; + name = Release; + }; + 40C84995101A36A60083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-static"; + }; + name = Debug; + }; + 40C84996101A36A60083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-static"; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B238F600E828B5400846E11 /* Debug */, + 3B238F610E828B5400846E11 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40899F450FFA7185000B29AE /* Debug */, + 40899F460FFA7185000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4089A0150FFACEFD000B29AE /* Debug */, + 4089A0160FFACEFD000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C44ADF0E3798F4008FCC51 /* Debug */, + 40C44AE00E3798F4008FCC51 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C848FB101A209D0083642A /* Debug */, + 40C848FC101A209D0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C8490E101A217F0083642A /* Debug */, + 40C8490F101A217F0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84985101A36850083642A /* Debug */, + 40C84986101A36850083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84995101A36A60083642A /* Debug */, + 40C84996101A36A60083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/thirdparty/protobuf-2.3.0/ps3projects/libprotobuf.vcproj b/thirdparty/protobuf-2.3.0/ps3projects/libprotobuf.vcproj new file mode 100644 index 00000000..66dd8ba1 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/ps3projects/libprotobuf.vcproj @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/ps3projects/protobuf.sln b/thirdparty/protobuf-2.3.0/ps3projects/protobuf.sln new file mode 100644 index 00000000..e1906fe4 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/ps3projects/protobuf.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{EBBA93AA-DDB9-4704-977E-EE85B0420822}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + PS3 SNC Debug|Win32 = PS3 SNC Debug|Win32 + PS3 SNC Release|Win32 = PS3 SNC Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EBBA93AA-DDB9-4704-977E-EE85B0420822}.PS3 SNC Debug|Win32.ActiveCfg = PS3 SNC Debug|Win32 + {EBBA93AA-DDB9-4704-977E-EE85B0420822}.PS3 SNC Debug|Win32.Build.0 = PS3 SNC Debug|Win32 + {EBBA93AA-DDB9-4704-977E-EE85B0420822}.PS3 SNC Release|Win32.ActiveCfg = PS3 SNC Release|Win32 + {EBBA93AA-DDB9-4704-977E-EE85B0420822}.PS3 SNC Release|Win32.Build.0 = PS3 SNC Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcproj new file mode 100644 index 00000000..5776156a --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcproj @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcxproj new file mode 100644 index 00000000..e64614ee --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf-lite.vcxproj @@ -0,0 +1,166 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {49EA010D-706F-4BE2-A397-77854B72A040} + libprotobuf-lite + Win32Proj + + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + $(OutDir)$(ProjectName).pdb + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + OldStyle + + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;;%(PreprocessorDefinitions) + MultiThreaded + + + $(OutDir)$(ProjectName).pdb + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + OldStyle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcproj new file mode 100644 index 00000000..61f953d8 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcproj @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcxproj new file mode 100644 index 00000000..e00ad74a --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotobuf.vcxproj @@ -0,0 +1,208 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + libprotobuf + Win32Proj + + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + $(OutDir)$(ProjectName).pdb + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)libprotobuf.pdb + Level3 + OldStyle + + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions) + MultiThreaded + + + $(OutDir)$(ProjectName).pdb + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions) + MultiThreaded + + + $(IntDir)libprotobuf.pdb + Level3 + OldStyle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcproj new file mode 100644 index 00000000..3ec76fec --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcproj @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcxproj new file mode 100644 index 00000000..f5cb8130 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/libprotoc.vcxproj @@ -0,0 +1,202 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + Win32Proj + + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + StaticLibrary + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + OldStyle + + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + OldStyle + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /d2Zi+ %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + OldStyle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {3e283f37-a4ed-41b7-a3e6-a2d89d131a30} + false + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcproj new file mode 100644 index 00000000..de4c24ab --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcproj @@ -0,0 +1,482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcxproj new file mode 100644 index 00000000..d34e648b --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/lite-test.vcxproj @@ -0,0 +1,252 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {12015ACE-42BE-4952-A5A0-44A9A46908E2} + tests + Win32Proj + + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + true + Console + MachineX64 + + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + + + + + + + + + + + + Generating unittest_import_lite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto + + google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc;%(Outputs) + Generating unittest_import_lite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto + + google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc;%(Outputs) + Generating unittest_import_lite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto + + google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc;%(Outputs) + Generating unittest_import_lite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto + + google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc;%(Outputs) + + + Generating unittest_lite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto + + google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc;%(Outputs) + Generating unittest_lite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto + + google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc;%(Outputs) + Generating unittest_lite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto + + google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc;%(Outputs) + Generating unittest_lite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto + + google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc;%(Outputs) + + + + + {49ea010d-706f-4be2-a397-77854b72a040} + false + + + {1738d5f6-ed1e-47e0-b2f0-456864b93c1e} + false + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/protobuf.sln b/thirdparty/protobuf-2.3.0/vsprojects/protobuf.sln new file mode 100644 index 00000000..7528d305 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/protobuf.sln @@ -0,0 +1,130 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}" + ProjectSection(ProjectDependencies) = postProject + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} + {3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032} + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcproj", "{49EA010D-706F-4BE2-A397-77854B72A040}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}" + ProjectSection(ProjectDependencies) = postProject + {49EA010D-706F-4BE2-A397-77854B72A040} = {49EA010D-706F-4BE2-A397-77854B72A040} + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|x64.ActiveCfg = Debug|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|x64.Build.0 = Debug|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|x64.ActiveCfg = Release|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|x64.Build.0 = Release|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|x64.ActiveCfg = Debug|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|x64.Build.0 = Debug|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|x64.ActiveCfg = Release|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|x64.Build.0 = Release|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|x64.ActiveCfg = Debug|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|x64.Build.0 = Debug|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|x64.ActiveCfg = Release|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|x64.Build.0 = Release|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|x64.ActiveCfg = Debug|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|x64.Build.0 = Debug|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|x64.ActiveCfg = Release|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|x64.Build.0 = Release|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.ActiveCfg = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.Build.0 = Debug|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.ActiveCfg = Release|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.Build.0 = Release|x64 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|x64.ActiveCfg = Debug|x64 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|x64.Build.0 = Debug|x64 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|x64.ActiveCfg = Release|x64 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|x64.Build.0 = Release|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|x64.ActiveCfg = Debug|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|x64.Build.0 = Debug|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|x64.ActiveCfg = Release|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|x64.Build.0 = Release|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|x64.ActiveCfg = Debug|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|x64.Build.0 = Debug|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|x64.ActiveCfg = Release|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|x64.Build.0 = Release|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|x64.ActiveCfg = Debug|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|x64.Build.0 = Debug|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|x64.ActiveCfg = Release|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/thirdparty/protobuf-2.3.0/vsprojects/protobuf_2010.sln b/thirdparty/protobuf-2.3.0/vsprojects/protobuf_2010.sln new file mode 100644 index 00000000..84da5758 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/protobuf_2010.sln @@ -0,0 +1,102 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcxproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcxproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcxproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcxproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcxproj", "{49EA010D-706F-4BE2-A397-77854B72A040}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcxproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcxproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|x64.ActiveCfg = Debug|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|x64.Build.0 = Debug|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|x64.ActiveCfg = Release|x64 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|x64.Build.0 = Release|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|x64.ActiveCfg = Debug|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|x64.Build.0 = Debug|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|x64.ActiveCfg = Release|x64 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|x64.Build.0 = Release|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|x64.ActiveCfg = Debug|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|x64.Build.0 = Debug|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|x64.ActiveCfg = Release|x64 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|x64.Build.0 = Release|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|x64.ActiveCfg = Debug|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|x64.Build.0 = Debug|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|x64.ActiveCfg = Release|x64 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|x64.Build.0 = Release|x64 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|x64.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|x64.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|x64.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|x64.ActiveCfg = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|x64.ActiveCfg = Debug|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|x64.Build.0 = Debug|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|x64.ActiveCfg = Release|x64 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|x64.Build.0 = Release|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|x64.ActiveCfg = Debug|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|x64.Build.0 = Debug|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|x64.ActiveCfg = Release|x64 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|x64.Build.0 = Release|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|x64.ActiveCfg = Debug|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|x64.Build.0 = Debug|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|x64.ActiveCfg = Release|x64 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcproj new file mode 100644 index 00000000..1bdb4d90 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcproj @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcxproj new file mode 100644 index 00000000..d215ec26 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/protoc.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} + Win32Proj + + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + _HAS_ITERATOR_DEBUGGING=0;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + false + libcmt;%(IgnoreSpecificDefaultLibraries) + true + Console + MachineX64 + + + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + + + + {3e283f37-a4ed-41b7-a3e6-a2d89d131a30} + false + + + {b84ff31a-5f9a-46f8-ab22-dbfc9bece3be} + false + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcproj new file mode 100644 index 00000000..e9104caa --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcproj @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcxproj new file mode 100644 index 00000000..b17399b8 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/test_plugin.vcxproj @@ -0,0 +1,216 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} + test_plugin + Win32Proj + + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + true + Console + MachineX64 + + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + + + + + + + + + + {c8f6c172-56f2-4e76-b5fa-c3b423b31be7} + false + + + {3e283f37-a4ed-41b7-a3e6-a2d89d131a30} + false + + + {b84ff31a-5f9a-46f8-ab22-dbfc9bece3be} + false + + + + + + \ No newline at end of file diff --git a/thirdparty/protobuf-2.3.0/vsprojects/tests.vcproj b/thirdparty/protobuf-2.3.0/vsprojects/tests.vcproj new file mode 100644 index 00000000..d2ee939b --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/tests.vcproj @@ -0,0 +1,974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/protobuf-2.3.0/vsprojects/tests.vcxproj b/thirdparty/protobuf-2.3.0/vsprojects/tests.vcxproj new file mode 100644 index 00000000..16aac128 --- /dev/null +++ b/thirdparty/protobuf-2.3.0/vsprojects/tests.vcxproj @@ -0,0 +1,440 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4DF72760-C055-40A5-A77E-30A17E2AC2DB} + tests + Win32Proj + + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + Application + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\$(ProjectName)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + Disabled + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + true + Console + MachineX64 + + + + + + + + + %(Inputs) + %(Outputs) + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + + + + + %(Inputs) + %(Outputs) + + + X64 + + + /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 %(AdditionalOptions) + ../src;.;../gtest/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Generating cpp_test_bad_identifiers.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + + google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc;%(Outputs) + Generating cpp_test_bad_identifiers.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + + google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc;%(Outputs) + Generating cpp_test_bad_identifiers.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + + google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc;%(Outputs) + Generating cpp_test_bad_identifiers.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + + google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc;%(Outputs) + + + Generating unittest.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto + + google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc;%(Outputs) + Generating unittest.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto + + google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc;%(Outputs) + Generating unittest.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto + + google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc;%(Outputs) + Generating unittest.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto + + google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc;%(Outputs) + + + Generating unittest_custom_options.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto + + google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc;%(Outputs) + Generating unittest_custom_options.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto + + google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc;%(Outputs) + Generating unittest_custom_options.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto + + google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc;%(Outputs) + Generating unittest_custom_options.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto + + google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc;%(Outputs) + + + Generating unittest_embed_optimize_for.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto + + google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc;%(Outputs) + Generating unittest_embed_optimize_for.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto + + google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc;%(Outputs) + Generating unittest_embed_optimize_for.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto + + google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc;%(Outputs) + Generating unittest_embed_optimize_for.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto + + google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc;%(Outputs) + + + Generating unittest_import.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto + + google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc;%(Outputs) + Generating unittest_import.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto + + google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc;%(Outputs) + Generating unittest_import.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto + + google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc;%(Outputs) + Generating unittest_import.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto + + google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc;%(Outputs) + + + Generating unittest_lite_imports_nonlite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto + + google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc;%(Outputs) + Generating unittest_lite_imports_nonlite.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto + + google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc;%(Outputs) + Generating unittest_lite_imports_nonlite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto + + google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc;%(Outputs) + Generating unittest_lite_imports_nonlite.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto + + google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc;%(Outputs) + + + Generating unittest_mset.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto + + google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc;%(Outputs) + Generating unittest_mset.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto + + google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc;%(Outputs) + Generating unittest_mset.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto + + google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc;%(Outputs) + Generating unittest_mset.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto + + google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc;%(Outputs) + + + Generating unittest_no_generic_services.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto + + google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc;%(Outputs) + Generating unittest_no_generic_services.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto + + google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc;%(Outputs) + Generating unittest_no_generic_services.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto + + google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc;%(Outputs) + Generating unittest_no_generic_services.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto + + google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc;%(Outputs) + + + Generating unittest_optimize_for.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto + + google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc;%(Outputs) + Generating unittest_optimize_for.pb.{h,cc}... + Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto + + google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc;%(Outputs) + Generating unittest_optimize_for.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto + + google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc;%(Outputs) + Generating unittest_optimize_for.pb.{h,cc}... + Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto + + google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc;%(Outputs) + + + + + {c8f6c172-56f2-4e76-b5fa-c3b423b31be7} + false + + + {3af54c8a-10bf-4332-9147-f68ed9862032} + false + + + {3e283f37-a4ed-41b7-a3e6-a2d89d131a30} + false + + + {b84ff31a-5f9a-46f8-ab22-dbfc9bece3be} + false + + + {1738d5f6-ed1e-47e0-b2f0-456864b93c1e} + false + + + {cbbd34e5-02b0-40d5-b6d8-bfea83e18b32} + false + + + + + + \ No newline at end of file diff --git a/thirdpartylegalnotices.txt b/thirdpartylegalnotices.txt deleted file mode 100644 index 126ea8ce..00000000 --- a/thirdpartylegalnotices.txt +++ /dev/null @@ -1,870 +0,0 @@ -The Source engine and Valve games use Third Party code for certain functions. The -required legal notices for using such code are reproduced below in accordance with -Valves obligations to provide such notices: - -************************************************************************************ -Xzip/Xunzip: -************************************************************************************ - - // This is version 2002-Feb-16 of the Info-ZIP copyright and license. The - // definitive version of this document should be available at - // ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. - // - // Copyright (c) 1990-2002 Info-ZIP. All rights reserved. - // - // For the purposes of this copyright and license, "Info-ZIP" is defined as - // the following set of individuals: - // - // Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, - // Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, - // Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, - // David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, - // Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, - // Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler, - // Antoine Verheijen, Paul von Behren, Rich Wales, Mike White - // - // This software is provided "as is", without warranty of any kind, express - // or implied. In no event shall Info-ZIP or its contributors be held liable - // for any direct, indirect, incidental, special or consequential damages - // arising out of the use of or inability to use this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. Redistributions of source code must retain the above copyright notice, - // definition, disclaimer, and this list of conditions. - // - // 2. Redistributions in binary form (compiled executables) must reproduce - // the above copyright notice, definition, disclaimer, and this list of - // conditions in documentation and/or other materials provided with the - // distribution. The sole exception to this condition is redistribution - // of a standard UnZipSFX binary as part of a self-extracting archive; - // that is permitted without inclusion of this license, as long as the - // normal UnZipSFX banner has not been removed from the binary or disabled. - // - // 3. Altered versions--including, but not limited to, ports to new - // operating systems, existing ports with new graphical interfaces, and - // dynamic, shared, or static library versions--must be plainly marked - // as such and must not be misrepresented as being the original source. - // Such altered versions also must not be misrepresented as being - // Info-ZIP releases--including, but not limited to, labeling of the - // altered versions with the names "Info-ZIP" (or any variation thereof, - // including, but not limited to, different capitalizations), - // "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of - // Info-ZIP. Such altered versions are further prohibited from - // misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or - // of the Info-ZIP URL(s). - // - // 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip", - // "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its - // own source and binary releases. - // - /////////////////////////////////////////////////////////////////////////////// - -************************************************************************************ -JPEG image support: -************************************************************************************ - - The Source engine and SDK also make use of library functions for working with .jpg - files. Specifically, the Source engine jpeg library is based in part on the work of - the Independent JPEG Group (IJG). The original source code and project files for the IJG's - JPEG libraries may be found at: http://www.ijg.org/files/jpegsrc.v6b.tar.gz - - The following is the README. File from that archive and is produced in accordance with the legal - notices required by the library: - - The Independent JPEG Group's JPEG software - ========================================== - - README for release 6b of 27-Mar-1998 - ==================================== - - This distribution contains the sixth public release of the Independent JPEG - Group's free JPEG software. You are welcome to redistribute this software and - to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. - - Serious users of this software (particularly those incorporating it into - larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to - our electronic mailing list. Mailing list members are notified of updates - and have a chance to participate in technical discussions, etc. - - This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, - Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, - Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG - Group. - - IJG is not affiliated with the official ISO JPEG standards committee. - - - DOCUMENTATION ROADMAP - ===================== - - This file contains the following sections: - - OVERVIEW General description of JPEG and the IJG software. - LEGAL ISSUES Copyright, lack of warranty, terms of distribution. - REFERENCES Where to learn more about JPEG. - ARCHIVE LOCATIONS Where to find newer versions of this software. - RELATED SOFTWARE Other stuff you should get. - FILE FORMAT WARS Software *not* to get. - TO DO Plans for future IJG releases. - - Other documentation files in the distribution are: - - User documentation: - install.doc How to configure and install the IJG software. - usage.doc Usage instructions for cjpeg, djpeg, jpegtran, - rdjpgcom, and wrjpgcom. - *.1 Unix-style man pages for programs (same info as usage.doc). - wizard.doc Advanced usage instructions for JPEG wizards only. - change.log Version-to-version change highlights. - Programmer and internal documentation: - libjpeg.doc How to use the JPEG library in your own programs. - example.c Sample code for calling the JPEG library. - structure.doc Overview of the JPEG library's internal structure. - filelist.doc Road map of IJG files. - coderules.doc Coding style rules --- please read if you contribute code. - - Please read at least the files install.doc and usage.doc. Useful information - can also be found in the JPEG FAQ (Frequently Asked Questions) article. See - ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. - - If you want to understand how the JPEG code works, we suggest reading one or - more of the REFERENCES, then looking at the documentation files (in roughly - the order listed) before diving into the code. - - - OVERVIEW - ======== - - This package contains C software to implement JPEG image compression and - decompression. JPEG (pronounced "jay-peg") is a standardized compression - method for full-color and gray-scale images. JPEG is intended for compressing - "real-world" scenes; line drawings, cartoons and other non-realistic images - are not its strong suit. JPEG is lossy, meaning that the output image is not - exactly identical to the input image. Hence you must not use JPEG if you - have to have identical output bits. However, on typical photographic images, - very good compression levels can be obtained with no visible change, and - remarkably high compression levels are possible if you can tolerate a - low-quality image. For more details, see the references, or just experiment - with various compression settings. - - This software implements JPEG baseline, extended-sequential, and progressive - compression processes. Provision is made for supporting all variants of these - processes, although some uncommon parameter settings aren't implemented yet. - For legal reasons, we are not distributing code for the arithmetic-coding - variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting - the hierarchical or lossless processes defined in the standard. - - We provide a set of library routines for reading and writing JPEG image files, - plus two sample applications "cjpeg" and "djpeg", which use the library to - perform conversion between JPEG and some other popular image file formats. - The library is intended to be reused in other applications. - - In order to support file conversion and viewing software, we have included - considerable functionality beyond the bare JPEG coding/decoding capability; - for example, the color quantization modules are not strictly part of JPEG - decoding, but they are essential for output to colormapped file formats or - colormapped displays. These extra functions can be compiled out of the - library if not required for a particular application. We have also included - "jpegtran", a utility for lossless transcoding between different JPEG - processes, and "rdjpgcom" and "wrjpgcom", two simple applications for - inserting and extracting textual comments in JFIF files. - - The emphasis in designing this software has been on achieving portability and - flexibility, while also making it fast enough to be useful. In particular, - the software is not intended to be read as a tutorial on JPEG. (See the - REFERENCES section for introductory material.) Rather, it is intended to - be reliable, portable, industrial-strength code. We do not claim to have - achieved that goal in every aspect of the software, but we strive for it. - - We welcome the use of this software as a component of commercial products. - No royalty is required, but we do ask for an acknowledgement in product - documentation, as described under LEGAL ISSUES. - - - LEGAL ISSUES - ============ - - In plain English: - - 1. We don't promise that this software works. (But if you find any bugs, - please let us know!) - 2. You can use this software for whatever you want. You don't have to pay us. - 3. You may not pretend that you wrote this software. If you use it in a - program, you must acknowledge somewhere in your documentation that - you've used the IJG code. - - In legalese: - - The authors make NO WARRANTY or representation, either express or implied, - with respect to this software, its quality, accuracy, merchantability, or - fitness for a particular purpose. This software is provided "AS IS", and you, - its user, assume the entire risk as to its quality and accuracy. - - This software is copyright (C) 1991-1998, Thomas G. Lane. - All Rights Reserved except as specified below. - - Permission is hereby granted to use, copy, modify, and distribute this - software (or portions thereof) for any purpose, without fee, subject to these - conditions: - (1) If any part of the source code for this software is distributed, then this - README file must be included, with this copyright and no-warranty notice - unaltered; and any additions, deletions, or changes to the original files - must be clearly indicated in accompanying documentation. - (2) If only executable code is distributed, then the accompanying - documentation must state that "this software is based in part on the work of - the Independent JPEG Group". - (3) Permission for use of this software is granted only if the user accepts - full responsibility for any undesirable consequences; the authors accept - NO LIABILITY for damages of any kind. - - These conditions apply to any software derived from or based on the IJG code, - not just to the unmodified library. If you use our work, you ought to - acknowledge us. - - Permission is NOT granted for the use of any IJG author's name or company name - in advertising or publicity relating to this software or products derived from - it. This software may be referred to only as "the Independent JPEG Group's - software". - - We specifically permit and encourage the use of this software as the basis of - commercial products, provided that all warranty or liability claims are - assumed by the product vendor. - - - ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, - sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. - ansi2knr.c is NOT covered by the above copyright and conditions, but instead - by the usual distribution terms of the Free Software Foundation; principally, - that you must include source code if you redistribute it. (See the file - ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part - of any program generated from the IJG code, this does not limit you more than - the foregoing paragraphs do. - - The Unix configuration script "configure" was produced with GNU Autoconf. - It is copyright by the Free Software Foundation but is freely distributable. - The same holds for its supporting scripts (config.guess, config.sub, - ltconfig, ltmain.sh). Another support script, install-sh, is copyright - by M.I.T. but is also freely distributable. - - It appears that the arithmetic coding option of the JPEG spec is covered by - patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot - legally be used without obtaining one or more licenses. For this reason, - support for arithmetic coding has been removed from the free JPEG software. - (Since arithmetic coding provides only a marginal gain over the unpatented - Huffman mode, it is unlikely that very many implementations will support it.) - So far as we are aware, there are no patent restrictions on the remaining - code. - - The IJG distribution formerly included code to read and write GIF files. - To avoid entanglement with the Unisys LZW patent, GIF reading support has - been removed altogether, and the GIF writer has been simplified to produce - "uncompressed GIFs". This technique does not use the LZW algorithm; the - resulting GIF files are larger than usual, but are readable by all standard - GIF decoders. - - We are required to state that - "The Graphics Interchange Format(c) is the Copyright property of - CompuServe Incorporated. GIF(sm) is a Service Mark property of - CompuServe Incorporated." - - - REFERENCES - ========== - - We highly recommend reading one or more of these references before trying to - understand the innards of the JPEG software. - - The best short technical introduction to the JPEG compression algorithm is - Wallace, Gregory K. "The JPEG Still Picture Compression Standard", - Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. - (Adjacent articles in that issue discuss MPEG motion picture compression, - applications of JPEG, and related topics.) If you don't have the CACM issue - handy, a PostScript file containing a revised version of Wallace's article is - available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually - a preprint for an article that appeared in IEEE Trans. Consumer Electronics) - omits the sample images that appeared in CACM, but it includes corrections - and some added material. Note: the Wallace article is copyright ACM and IEEE, - and it may not be used for commercial purposes. - - A somewhat less technical, more leisurely introduction to JPEG can be found in - "The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by - M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides - good explanations and example C code for a multitude of compression methods - including JPEG. It is an excellent source if you are comfortable reading C - code but don't know much about data compression in general. The book's JPEG - sample code is far from industrial-strength, but when you are ready to look - at a full implementation, you've got one here... - - The best full description of JPEG is the textbook "JPEG Still Image Data - Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published - by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. - The book includes the complete text of the ISO JPEG standards (DIS 10918-1 - and draft DIS 10918-2). This is by far the most complete exposition of JPEG - in existence, and we highly recommend it. - - The JPEG standard itself is not available electronically; you must order a - paper copy through ISO or ITU. (Unless you feel a need to own a certified - official copy, we recommend buying the Pennebaker and Mitchell book instead; - it's much cheaper and includes a great deal of useful explanatory material.) - In the USA, copies of the standard may be ordered from ANSI Sales at (212) - 642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI - doesn't take credit card orders, but Global does.) It's not cheap: as of - 1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% - shipping/handling. The standard is divided into two parts, Part 1 being the - actual specification, while Part 2 covers compliance testing methods. Part 1 - is titled "Digital Compression and Coding of Continuous-tone Still Images, - Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS - 10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of - Continuous-tone Still Images, Part 2: Compliance testing" and has document - numbers ISO/IEC IS 10918-2, ITU-T T.83. - - Some extensions to the original JPEG standard are defined in JPEG Part 3, - a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG - currently does not support any Part 3 extensions. - - The JPEG standard does not specify all details of an interchangeable file - format. For the omitted details we follow the "JFIF" conventions, revision - 1.02. A copy of the JFIF spec is available from: - Literature Department - C-Cube Microsystems, Inc. - 1778 McCarthy Blvd. - Milpitas, CA 95035 - phone (408) 944-6300, fax (408) 944-6314 - A PostScript version of this document is available by FTP at - ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text - version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing - the figures. - - The TIFF 6.0 file format specification can be obtained by FTP from - ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme - found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. - IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). - Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 - (Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or - from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision - of the TIFF spec will replace the 6.0 JPEG design with the Note's design. - Although IJG's own code does not support TIFF/JPEG, the free libtiff library - uses our library to implement TIFF/JPEG per the Note. libtiff is available - from ftp://ftp.sgi.com/graphics/tiff/. - - - ARCHIVE LOCATIONS - ================= - - The "official" archive site for this software is ftp.uu.net (Internet - address 192.48.96.9). The most recent released version can always be found - there in directory graphics/jpeg. This particular version will be archived - as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have - direct Internet access, UUNET's archives are also available via UUCP; contact - help@uunet.uu.net for information on retrieving files that way. - - Numerous Internet sites maintain copies of the UUNET files. However, only - ftp.uu.net is guaranteed to have the latest official version. - - You can also obtain this software in DOS-compatible "zip" archive format from - the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or - on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 - "JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net - release. - - The JPEG FAQ (Frequently Asked Questions) article is a useful source of - general information about JPEG. It is updated constantly and therefore is - not included in this distribution. The FAQ is posted every two weeks to - Usenet newsgroups comp.graphics.misc, news.answers, and other groups. - It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ - and other news.answers archive sites, including the official news.answers - archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. - If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu - with body - send usenet/news.answers/jpeg-faq/part1 - send usenet/news.answers/jpeg-faq/part2 - - - RELATED SOFTWARE - ================ - - Numerous viewing and image manipulation programs now support JPEG. (Quite a - few of them use this library to do so.) The JPEG FAQ described above lists - some of the more popular free and shareware viewers, and tells where to - obtain them on Internet. - - If you are on a Unix machine, we highly recommend Jef Poskanzer's free - PBMPLUS software, which provides many useful operations on PPM-format image - files. In particular, it can convert PPM images to and from a wide range of - other formats, thus making cjpeg/djpeg considerably more useful. The latest - version is distributed by the NetPBM group, and is available from numerous - sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. - Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; - you are likely to have difficulty making it work on any non-Unix machine. - - A different free JPEG implementation, written by the PVRG group at Stanford, - is available from ftp://havefun.stanford.edu/pub/jpeg/. This program - is designed for research and experimentation rather than production use; - it is slower, harder to use, and less portable than the IJG code, but it - is easier to read and modify. Also, the PVRG code supports lossless JPEG, - which we do not. (On the other hand, it doesn't do progressive JPEG.) - - - FILE FORMAT WARS - ================ - - Some JPEG programs produce files that are not compatible with our library. - The root of the problem is that the ISO JPEG committee failed to specify a - concrete file format. Some vendors "filled in the blanks" on their own, - creating proprietary formats that no one else could read. (For example, none - of the early commercial JPEG implementations for the Macintosh were able to - exchange compressed files.) - - The file format we have adopted is called JFIF (see REFERENCES). This format - has been agreed to by a number of major commercial JPEG vendors, and it has - become the de facto standard. JFIF is a minimal or "low end" representation. - We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF - Technical Note #2) for "high end" applications that need to record a lot of - additional data about an image. TIFF/JPEG is fairly new and not yet widely - supported, unfortunately. - - The upcoming JPEG Part 3 standard defines a file format called SPIFF. - SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should - be able to read the most common variant of SPIFF. SPIFF has some technical - advantages over JFIF, but its major claim to fame is simply that it is an - official standard rather than an informal one. At this point it is unclear - whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto - standard. IJG intends to support SPIFF once the standard is frozen, but we - have not decided whether it should become our default output format or not. - (In any case, our decoder will remain capable of reading JFIF indefinitely.) - - Various proprietary file formats incorporating JPEG compression also exist. - We have little or no sympathy for the existence of these formats. Indeed, - one of the original reasons for developing this free software was to help - force convergence on common, open format standards for JPEG files. Don't - use a proprietary file format! - - - TO DO - ===== - - The major thrust for v7 will probably be improvement of visual quality. - The current method for scaling the quantization tables is known not to be - very good at low Q values. We also intend to investigate block boundary - smoothing, "poor man's variable quantization", and other means of improving - quality-vs-file-size performance without sacrificing compatibility. - - In future versions, we are considering supporting some of the upcoming JPEG - Part 3 extensions --- principally, variable quantization and the SPIFF file - format. - - As always, speeding things up is of great interest. - - Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. - -************************************************************************************ -Celt Codec: -************************************************************************************ - - Copyright 2001-2009 Jean-Marc Valin, Timothy B. Terriberry, - CSIRO, and other contributors - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -************************************************************************************ -SPEEX Codes: -************************************************************************************ - SPEEX 2002-2003, Jean-Marc Valin/Xiph.Org Foundation - Redistribution and use in source and binary forms, with or without modification, are permitted - provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this list of - conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of - conditions and the following disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of the Xiph.org Foundation nor the names of its contributors may be - used to endorse or promote products derived from this software without specific prior - written permission. - This software is provided by the copyright holders and contributors as is and any express or - implied warranties, including, but not limited to, the implied warranties of merchantability and - fitness for a particular purpose are disclaimed. In no event shall the foundation or contributors be - liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, - but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or - business interruption) however caused and on any theory of liability, whether in contract, strict - liability, or tort (including negligence or otherwise) arising in any way out of the use of this - software, even if advised of the possibility of such damage. - -************************************************************************************ -google-perftools: -************************************************************************************ - - http://code.google.com/p/gperftools/ - - Copyright (c) 2012, Google Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - For Google libjingle: - http://sourceforge.net/projects/libjingle/ - Copyright (c) 2004--2005, Google Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - -************************************************************************************ -CakePHP: -************************************************************************************ - - CakePHP(tm) : Rapid Development Framework - Copyright 2005-2007, Cake Software Foundation, Inc. - 1785 E. Sahara Avenue, Suite 490-204 - Las Vegas, Nevada 89104 - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - -************************************************************************************ -LZMA -************************************************************************************ - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this Code, expressly permits you to - statically or dynamically link your Code (or bind by name) to the - interfaces of this file without subjecting your linked Code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. - -************************************************************************************ -Fast Pow Function -************************************************************************************ - - /* - * (c) Ian Stephenson - * - * ian@dctsystems.co.uk - * - * Fast pow() reference implementation - */ - - Used with permission from author - - For libantlr3c: - // [The "BSD licence"] - // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC - // http://www.temporal-wave.com - // http://www.linkedin.com/in/jimidle - // - // All rights reserved. - // - // Redistribution and use in source and binary forms, with or without - // modification, are permitted provided that the following conditions - // are met: - // 1. Redistributions of source code must retain the above copyright - // notice, this list of conditions and the following disclaimer. - // 2. Redistributions in binary form must reproduce the above copyright - // notice, this list of conditions and the following disclaimer in the - // documentation and/or other materials provided with the distribution. - // 3. The name of the author may not be used to endorse or promote products - // derived from this software without specific prior written permission. - // - // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -************************************************************************************ -Autodesk FBX: -************************************************************************************ - - This software contains Autodesk FBX code developed by Autodesk, Inc. Copyright 2012 Autodesk, Inc. - All rights, reserved. Such code is provided as is and Autodesk, Inc. disclaims any and all warranties, - whether express or implied, including without limitation the implied warranties of merchantability, fitness for a - particular purpose or non-infringement of third party rights. In no event shall Autodesk, Inc. be liable for any - direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, - procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however - caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or - otherwise) arising in any way out of such code. - -************************************************************************************ -OpenSSL: -************************************************************************************ - - * This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/) - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - /* ==================================================================== - * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be - used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * - */ - - - /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an - acknowledgement: - * "This product includes software written by Tim Hudson - (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -************************************************************************************ -Google protocol buffers -************************************************************************************ - - // Protocol Buffers - Google's data interchange format - // Copyright 2008 Google Inc. All rights reserved. - // http://code.google.com/p/protobuf/ - // - // Redistribution and use in source and binary forms, with or without - // modification, are permitted provided that the following conditions are - // met: - // - // * Redistributions of source code must retain the above copyright - // notice, this list of conditions and the following disclaimer. - // * Redistributions in binary form must reproduce the above - // copyright notice, this list of conditions and the following disclaimer - // in the documentation and/or other materials provided with the - // distribution. - // * Neither the name of Google Inc. nor the names of its - // contributors may be used to endorse or promote products derived from - // this software without specific prior written permission. - // - // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - // Author: kenton@google.com (Kenton Varda) - // Based on original Protocol Buffers design by - // Sanjay Ghemawat, Jeff Dean, and others. - -************************************************************************************ -Google Snappy -************************************************************************************ - - // Copyright 2005 Google Inc. All Rights Reserved. - // - // Redistribution and use in source and binary forms, with or without - // modification, are permitted provided that the following conditions are - // met: - // - // * Redistributions of source code must retain the above copyright - // notice, this list of conditions and the following disclaimer. - // * Redistributions in binary form must reproduce the above - // copyright notice, this list of conditions and the following disclaimer - // in the documentation and/or other materials provided with the - // distribution. - // * Neither the name of Google Inc. nor the names of its - // contributors may be used to endorse or promote products derived from - // this software without specific prior written permission. - // - // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tier0/tier0_exclude.vpc b/tier0/tier0_exclude.vpc deleted file mode 100644 index ed521975..00000000 --- a/tier0/tier0_exclude.vpc +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------------- -// tier0_exclude.vpc -// -// Project Script -//----------------------------------------------------------------------------- - -$Project -{ - $Folder "Link Libraries" - { - -$Lib "$LIBPUBLIC\tier0" - } - $Folder "Source Files" - { - -$File "$SRCDIR\public\tier0\memoverride.cpp" - } -} diff --git a/tier1/KeyValues.cpp b/tier1/KeyValues.cpp index ad4af096..37bc267b 100644 --- a/tier1/KeyValues.cpp +++ b/tier1/KeyValues.cpp @@ -18,18 +18,19 @@ #include #include "filesystem.h" #include -#include "tier0/icommandline.h" #include #include #include "tier0/dbg.h" #include "tier0/mem.h" +#include "utlvector.h" #include "utlbuffer.h" #include "utlhash.h" -#include "utlvector.h" -#include "utlqueue.h" #include "UtlSortVector.h" #include "convar.h" +#ifdef MAPBASE +#include "icommandline.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include @@ -70,7 +71,7 @@ class CKeyValuesErrorStack m_errorStack[m_errorIndex] = symName; } m_errorIndex++; - m_maxErrorIndex = max( m_maxErrorIndex, (m_errorIndex-1) ); + m_maxErrorIndex = MAX( m_maxErrorIndex, (m_errorIndex-1) ); return m_errorIndex-1; } @@ -86,19 +87,16 @@ class CKeyValuesErrorStack { Assert( stackLevel >= 0 ); Assert( stackLevel < m_errorIndex ); - if ( stackLevel < MAX_ERROR_STACK ) - m_errorStack[stackLevel] = symName; + m_errorStack[stackLevel] = symName; } // Hit an error, report it and the parsing stack for context void ReportError( const char *pError ) { - bool bSpewCR = false; - Warning( "KeyValues Error: %s in file %s\n", pError, m_pFilename ); for ( int i = 0; i < m_maxErrorIndex; i++ ) { - if ( i < MAX_ERROR_STACK && m_errorStack[i] != INVALID_KEY_SYMBOL ) + if ( m_errorStack[i] != INVALID_KEY_SYMBOL ) { if ( i < m_errorIndex ) { @@ -108,13 +106,9 @@ class CKeyValuesErrorStack { Warning( "(*%s*), ", KeyValues::CallGetStringForSymbol(m_errorStack[i]) ); } - - bSpewCR = true; } } - - if ( bSpewCR ) - Warning( "\n" ); + Warning( "\n" ); } private: @@ -146,10 +140,6 @@ class CKeyErrorContext { g_KeyValuesErrorStack.Reset( m_stackLevel, symName ); } - int GetStackLevel() const - { - return m_stackLevel; - } private: void Init( int symName ) { @@ -643,62 +633,15 @@ void KeyValues::UsesConditionals(bool state) //----------------------------------------------------------------------------- // Purpose: Load keyValues from disk //----------------------------------------------------------------------------- -bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID, bool refreshCache ) +bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID ) { Assert(filesystem); #ifdef WIN32 Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) ); #endif - -#ifdef STAGING_ONLY - static bool s_bCacheEnabled = !!CommandLine()->FindParm( "-enable_keyvalues_cache" ); - const bool bUseCache = s_bCacheEnabled && ( s_pfGetSymbolForString == KeyValues::GetSymbolForStringClassic ); -#else - /* - People are cheating with the keyvalue cache enabled by doing the below, so disable it. - - For example if one is to allow a blue demoman texture on sv_pure they - change it to this, "$basetexture" "temp/demoman_blue". Remember to move the - demoman texture to the temp folder in the materials folder. It will likely - not be there so make a new folder for it. Once the directory in the - demoman_blue vmt is changed to the temp folder and the vtf texture is in - the temp folder itself you are finally done. - - I packed my mods into a vpk but I don't think it's required. Once in game - you must create a server via the create server button and select the map - that will load the custom texture before you join a valve server. I suggest - you only do this with player textures and such as they are always loaded. - After you load the map you join the valve server and the textures should - appear and work on valve servers. - - This can be done on any sv_pure 1 server but it depends on what is type of - files are allowed. All valve servers allow temp files so that is the - example I used here." - - So all vmt's files can bypass sv_pure 1. And I believe this mod is mostly - made of vmt files, so valve's sv_pure 1 bull is pretty redundant. - */ - const bool bUseCache = false; -#endif - - // If pathID is null, we cannot cache the result because that has a weird iterate-through-a-bunch-of-locations behavior. - const bool bUseCacheForRead = bUseCache && !refreshCache && pathID != NULL; - const bool bUseCacheForWrite = bUseCache && pathID != NULL; - - COM_TimestampedLog( "KeyValues::LoadFromFile(%s%s%s): Begin", pathID ? pathID : "", pathID && resourceName ? "/" : "", resourceName ? resourceName : "" ); - - // Keep a cache of keyvalues, try to load it here. - if ( bUseCacheForRead && KeyValuesSystem()->LoadFileKeyValuesFromCache( this, resourceName, pathID, filesystem ) ) { - COM_TimestampedLog( "KeyValues::LoadFromFile(%s%s%s): End / CacheHit", pathID ? pathID : "", pathID && resourceName ? "/" : "", resourceName ? resourceName : "" ); - return true; - } - FileHandle_t f = filesystem->Open(resourceName, "rb", pathID); if ( !f ) - { - COM_TimestampedLog("KeyValues::LoadFromFile(%s%s%s): End / FileNotFound", pathID ? pathID : "", pathID && resourceName ? "/" : "", resourceName ? resourceName : ""); return false; - } s_LastFileLoadingFrom = (char*)resourceName; @@ -720,41 +663,28 @@ bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceN buffer[fileSize+1] = 0; // double NULL terminating in case this is a unicode file bRetOK = LoadFromBuffer( resourceName, buffer, filesystem ); } - - // The cache relies on the KeyValuesSystem string table, which will only be valid if we're - // using classic mode. - if ( bUseCacheForWrite && bRetOK ) - { - KeyValuesSystem()->AddFileKeyValuesToCache( this, resourceName, pathID ); - } - ( (IFileSystem *)filesystem )->FreeOptimalReadBuffer( buffer ); - - COM_TimestampedLog("KeyValues::LoadFromFile(%s%s%s): End / Success", pathID ? pathID : "", pathID && resourceName ? "/" : "", resourceName ? resourceName : ""); + ((IFileSystem *)filesystem)->FreeOptimalReadBuffer( buffer ); return bRetOK; } //----------------------------------------------------------------------------- // Purpose: Save the keyvalues to disk -// Creates the path to the file if it doesn't exist +// Creates the path to the file if it doesn't exist //----------------------------------------------------------------------------- -bool KeyValues::SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID, bool sortKeys /*= false*/, bool bAllowEmptyString /*= false*/, bool bCacheResult /*= false*/ ) +bool KeyValues::SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID, bool sortKeys /*= false*/, bool bAllowEmptyString /*= false*/ ) { // create a write file FileHandle_t f = filesystem->Open(resourceName, "wb", pathID); if ( f == FILESYSTEM_INVALID_HANDLE ) { - DevMsg(1, "KeyValues::SaveToFile: couldn't open file \"%s\" in path \"%s\".\n", + DevMsg(1, "KeyValues::SaveToFile: couldn't open file \"%s\" in path \"%s\".\n", resourceName?resourceName:"NULL", pathID?pathID:"NULL" ); return false; } - KeyValuesSystem()->InvalidateCacheForFile( resourceName, pathID ); - if ( bCacheResult ) { - KeyValuesSystem()->AddFileKeyValuesToCache( this, resourceName, pathID ); - } RecursiveSaveToFile(filesystem, f, NULL, 0, sortKeys, bAllowEmptyString ); filesystem->Close(f); @@ -798,7 +728,7 @@ void KeyValues::WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t j++; } - INTERNALWRITE(convertedString, Q_strlen(convertedString)); + INTERNALWRITE(convertedString, strlen(convertedString)); } @@ -1421,11 +1351,8 @@ const char *KeyValues::GetString( const char *keyName, const char *defaultValue Q_snprintf( buf, sizeof( buf ), "%f", dat->m_flValue ); SetString( keyName, buf ); break; - case TYPE_PTR: - Q_snprintf( buf, sizeof( buf ), "%lld", (int64)(size_t)dat->m_pValue ); - SetString( keyName, buf ); - break; case TYPE_INT: + case TYPE_PTR: Q_snprintf( buf, sizeof( buf ), "%d", dat->m_iValue ); SetString( keyName, buf ); break; @@ -1474,11 +1401,8 @@ const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaul swprintf(wbuf, Q_ARRAYSIZE(wbuf), L"%f", dat->m_flValue); SetWString( keyName, wbuf); break; - case TYPE_PTR: - swprintf( wbuf, Q_ARRAYSIZE(wbuf), L"%lld", (int64)(size_t)dat->m_pValue ); - SetWString( keyName, wbuf ); - break; case TYPE_INT: + case TYPE_PTR: swprintf( wbuf, Q_ARRAYSIZE(wbuf), L"%d", dat->m_iValue ); SetWString( keyName, wbuf ); break; @@ -1520,17 +1444,10 @@ const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaul //----------------------------------------------------------------------------- // Purpose: Get a bool interpretation of the key. //----------------------------------------------------------------------------- -bool KeyValues::GetBool( const char *keyName, bool defaultValue, bool* optGotDefault ) +bool KeyValues::GetBool( const char *keyName, bool defaultValue ) { if ( FindKey( keyName ) ) - { - if ( optGotDefault ) - (*optGotDefault) = false; return 0 != GetInt( keyName, 0 ); - } - - if ( optGotDefault ) - (*optGotDefault) = true; return defaultValue; } @@ -1668,7 +1585,7 @@ void KeyValues::SetWString( const char *keyName, const wchar_t *value ) } // allocate memory for the new value and copy it in - int len = Q_wcslen( value ); + int len = wcslen( value ); dat->m_wsValue = new wchar_t[len + 1]; Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) ); @@ -1744,138 +1661,115 @@ void KeyValues::SetPtr( const char *keyName, void *value ) } } -//----------------------------------------------------------------------------- -// Purpose: Copies the tree from the other KeyValues into this one, recursively -// beginning with the root specified by rootSrc. -//----------------------------------------------------------------------------- -void KeyValues::CopyKeyValuesFromRecursive( const KeyValues& rootSrc ) +void KeyValues::RecursiveCopyKeyValues( KeyValues& src ) { - // This code used to be recursive, which was more elegant. Unfortunately, it also blew the stack for large - // KeyValues. So now we have the iterative version which is uglier but doesn't blow the stack. - // This uses breadth-first traversal. - - struct CopyStruct - { - KeyValues* dst; - const KeyValues* src; - }; - - char tmp[256]; - KeyValues* localDst = NULL; - - CUtlQueue nodeQ; - nodeQ.Insert({ this, &rootSrc }); + // garymcthack - need to check this code for possible buffer overruns. + + m_iKeyName = src.GetNameSymbol(); - while ( nodeQ.Count() > 0 ) + if( !src.m_pSub ) { - CopyStruct cs = nodeQ.RemoveAtHead(); - - // Process all the siblings of the current node. If anyone has a child, add it to the queue. - while (cs.src) + m_iDataType = src.m_iDataType; + char buf[256]; + switch( src.m_iDataType ) { - Assert( (cs.src != NULL) == (cs.dst != NULL) ); - - // Copy the node contents - cs.dst->CopyKeyValue( *cs.src, sizeof(tmp), tmp ); - - // Add children to the queue to process later. - if (cs.src->m_pSub) { - cs.dst->m_pSub = localDst = new KeyValues( NULL ); - nodeQ.Insert({ localDst, cs.src->m_pSub }); + case TYPE_NONE: + break; + case TYPE_STRING: + if( src.m_sValue ) + { + int len = Q_strlen(src.m_sValue) + 1; + m_sValue = new char[len]; + Q_strncpy( m_sValue, src.m_sValue, len ); } - - // Process siblings until we hit the end of the line. - if (cs.src->m_pPeer) { - cs.dst->m_pPeer = new KeyValues( NULL ); + break; + case TYPE_INT: + { + m_iValue = src.m_iValue; + Q_snprintf( buf,sizeof(buf), "%d", m_iValue ); + int len = Q_strlen(buf) + 1; + m_sValue = new char[len]; + Q_strncpy( m_sValue, buf, len ); } - else { - cs.dst->m_pPeer = NULL; + break; + case TYPE_FLOAT: + { + m_flValue = src.m_flValue; + Q_snprintf( buf,sizeof(buf), "%f", m_flValue ); + int len = Q_strlen(buf) + 1; + m_sValue = new char[len]; + Q_strncpy( m_sValue, buf, len ); } - - // Advance to the next peer. - cs.src = cs.src->m_pPeer; - cs.dst = cs.dst->m_pPeer; + break; + case TYPE_PTR: + { + m_pValue = src.m_pValue; + } + break; + case TYPE_UINT64: + { + m_sValue = new char[sizeof(uint64)]; + Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) ); + } + break; + case TYPE_COLOR: + { + m_Color[0] = src.m_Color[0]; + m_Color[1] = src.m_Color[1]; + m_Color[2] = src.m_Color[2]; + m_Color[3] = src.m_Color[3]; + } + break; + + default: + { + // do nothing . .what the heck is this? + Assert( 0 ); + } + break; } - } -} -//----------------------------------------------------------------------------- -// Purpose: Copies a single KeyValue from src to this, using the provided temporary -// buffer if the keytype requires it. Does NOT recurse. -//----------------------------------------------------------------------------- -void KeyValues::CopyKeyValue( const KeyValues& src, size_t tmpBufferSizeB, char* tmpBuffer ) -{ - m_iKeyName = src.GetNameSymbol(); - - if ( src.m_pSub ) - return; - - m_iDataType = src.m_iDataType; - - switch( src.m_iDataType ) + } +#if 0 + KeyValues *pDst = this; + for ( KeyValues *pSrc = src.m_pSub; pSrc; pSrc = pSrc->m_pPeer ) { - case TYPE_NONE: - break; - case TYPE_STRING: - if( src.m_sValue ) - { - int len = Q_strlen(src.m_sValue) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, src.m_sValue, len ); - } - break; - case TYPE_INT: - { - m_iValue = src.m_iValue; - Q_snprintf( tmpBuffer, tmpBufferSizeB, "%d", m_iValue ); - int len = Q_strlen(tmpBuffer) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, tmpBuffer, len ); - } - break; - case TYPE_FLOAT: + if ( pSrc->m_pSub ) { - m_flValue = src.m_flValue; - Q_snprintf( tmpBuffer, tmpBufferSizeB, "%f", m_flValue ); - int len = Q_strlen(tmpBuffer) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, tmpBuffer, len ); + pDst->m_pSub = new KeyValues( pSrc->m_pSub->getName() ); + pDst->m_pSub->RecursiveCopyKeyValues( *pSrc->m_pSub ); } - break; - case TYPE_PTR: - { - m_pValue = src.m_pValue; - } - break; - case TYPE_UINT64: - { - m_sValue = new char[sizeof(uint64)]; - Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) ); - } - break; - case TYPE_COLOR: - { - m_Color[0] = src.m_Color[0]; - m_Color[1] = src.m_Color[1]; - m_Color[2] = src.m_Color[2]; - m_Color[3] = src.m_Color[3]; - } - break; - - default: + else { - // do nothing . .what the heck is this? - Assert( 0 ); + // copy non-empty keys + if ( pSrc->m_sValue && *(pSrc->m_sValue) ) + { + pDst->m_pPeer = new KeyValues( + } } - break; + } +#endif + + // Handle the immediate child + if( src.m_pSub ) + { + m_pSub = new KeyValues( NULL ); + m_pSub->RecursiveCopyKeyValues( *src.m_pSub ); + } + + // Handle the immediate peer + if( src.m_pPeer ) + { + m_pPeer = new KeyValues( NULL ); + m_pPeer->RecursiveCopyKeyValues( *src.m_pPeer ); } } -KeyValues& KeyValues::operator=( const KeyValues& src ) +KeyValues& KeyValues::operator=( KeyValues& src ) { RemoveEverything(); Init(); // reset all values - CopyKeyValuesFromRecursive( src ); + RecursiveCopyKeyValues( src ); return *this; } @@ -1937,7 +1831,7 @@ KeyValues *KeyValues::MakeCopy( void ) const { if ( m_wsValue ) { - int len = Q_wcslen( m_wsValue ); + int len = wcslen( m_wsValue ); newKeyValue->m_wsValue = new wchar_t[len+1]; Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t)); } @@ -1974,25 +1868,6 @@ KeyValues *KeyValues::MakeCopy( void ) const return newKeyValue; } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -KeyValues *KeyValues::MakeCopy( bool copySiblings ) const -{ - KeyValues* rootDest = MakeCopy(); - if ( !copySiblings ) - return rootDest; - - const KeyValues* curSrc = GetNextKey(); - KeyValues* curDest = rootDest; - while (curSrc) { - curDest->SetNextKey( curSrc->MakeCopy() ); - curDest = curDest->GetNextKey(); - curSrc = curSrc->GetNextKey(); - } - - return rootDest; -} //----------------------------------------------------------------------------- // Purpose: Check if a keyName has no value assigned to it. @@ -2176,6 +2051,12 @@ void KeyValues::RecursiveMergeKeyValues( KeyValues *baseKV ) } } +static bool IsSteamDeck() +{ + static bool bIsSteamDeck = getenv( "SteamDeck" ) != nullptr || CommandLine()->FindParm( "-gamepadui" ); + return bIsSteamDeck; +} + //----------------------------------------------------------------------------- // Returns whether a keyvalues conditional evaluates to true or false // Needs more flexibility with conditionals, checking convars would be nice. @@ -2209,6 +2090,31 @@ bool EvaluateConditional( const char *str ) if ( Q_stristr( str, "$POSIX" ) ) return IsPosix() ^ bNot; + + if ( Q_stristr( str, "$DECK" ) ) + return IsSteamDeck() ^ bNot; + +#ifdef MAPBASE + // Custom conditional + switch( str[bNot ? 1 : 0] ) + { + case '%': + { + // Look for a cvar + ConVarRef cvar( str + (bNot ? 2 : 1), true ); + if (cvar.IsValid()) + { + return cvar.GetBool() ^ bNot; + } + } break; + + case '-': + { + // Look for a command line param + return (CommandLine()->CheckParm( bNot ? str+1 : str ) != 0) ^ bNot; + } break; + } +#endif return false; } @@ -2358,8 +2264,6 @@ bool KeyValues::LoadFromBuffer( char const *resourceName, const char *pBuffer, I if ( !pBuffer ) return true; - COM_TimestampedLog("KeyValues::LoadFromBuffer(%s%s%s): Begin", pPathID ? pPathID : "", pPathID && resourceName ? "/" : "", resourceName ? resourceName : ""); - int nLen = Q_strlen( pBuffer ); CUtlBuffer buf( pBuffer, nLen, CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER ); @@ -2372,11 +2276,7 @@ bool KeyValues::LoadFromBuffer( char const *resourceName, const char *pBuffer, I buf.AssumeMemory( pUTF8Buf, nUTF8Len, nUTF8Len, CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER ); } - bool retVal = LoadFromBuffer( resourceName, buf, pFileSystem, pPathID ); - - COM_TimestampedLog("KeyValues::LoadFromBuffer(%s%s%s): End", pPathID ? pPathID : "", pPathID && resourceName ? "/" : "", resourceName ? resourceName : ""); - - return retVal; + return LoadFromBuffer( resourceName, buf, pFileSystem, pPathID ); } //----------------------------------------------------------------------------- @@ -2387,12 +2287,6 @@ void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &b CKeyErrorContext errorReport(this); bool wasQuoted; bool wasConditional; - if ( errorReport.GetStackLevel() > 100 ) - { - g_KeyValuesErrorStack.ReportError( "RecursiveLoadFromBuffer: recursion overflow" ); - return; - } - // keep this out of the stack until a key is parsed CKeyErrorContext errorKey( INVALID_KEY_SYMBOL ); @@ -2697,7 +2591,7 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer, int nStackDepth ) { char token[KEYVALUES_TOKEN_SIZE]; - buffer.GetString( token ); + buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); token[KEYVALUES_TOKEN_SIZE-1] = 0; dat->SetName( token ); } @@ -2713,7 +2607,7 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer, int nStackDepth ) case TYPE_STRING: { char token[KEYVALUES_TOKEN_SIZE]; - buffer.GetString( token ); + buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); token[KEYVALUES_TOKEN_SIZE-1] = 0; int len = Q_strlen( token ); @@ -2787,13 +2681,13 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer, int nStackDepth ) void *KeyValues::operator new( size_t iAllocSize ) { MEM_ALLOC_CREDIT(); - return KeyValuesSystem()->AllocKeyValuesMemory( (int)iAllocSize ); + return KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); } void *KeyValues::operator new( size_t iAllocSize, int nBlockUse, const char *pFileName, int nLine ) { MemAlloc_PushAllocDbgInfo( pFileName, nLine ); - void *p = KeyValuesSystem()->AllocKeyValuesMemory( (int)iAllocSize ); + void *p = KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); MemAlloc_PopAllocDbgInfo(); return p; } @@ -3166,4 +3060,4 @@ bool CKeyValuesDumpContextAsDevMsg::KvWriteText( char const *szText ) Msg( "%s", szText ); } return true; -} +} \ No newline at end of file diff --git a/tier1/characterset.cpp b/tier1/characterset.cpp index a7c518b1..01b669a4 100644 --- a/tier1/characterset.cpp +++ b/tier1/characterset.cpp @@ -34,7 +34,7 @@ void CharacterSetBuild( characterset_t *pSetBuffer, const char *pszSetString ) while ( pszSetString[i] ) { - pSetBuffer->set[ (unsigned)pszSetString[i] ] = 1; + pSetBuffer->set[ pszSetString[i] ] = 1; i++; } diff --git a/tier1/convar.cpp b/tier1/convar.cpp index 772586f2..c49a6efb 100644 --- a/tier1/convar.cpp +++ b/tier1/convar.cpp @@ -116,7 +116,7 @@ ConCommandBase::ConCommandBase( void ) //----------------------------------------------------------------------------- ConCommandBase::ConCommandBase( const char *pName, const char *pHelpString /*=0*/, int flags /*= 0*/ ) { - CreateBase( pName, pHelpString, flags ); + Create( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -153,14 +153,16 @@ CVarDLLIdentifier_t ConCommandBase::GetDLLIdentifier() const // *pHelpString - // flags - //----------------------------------------------------------------------------- -void ConCommandBase::CreateBase( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ ) +void ConCommandBase::Create( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ ) { + static char *empty_string = ""; + m_bRegistered = false; // Name should be static data Assert( pName ); m_pszName = pName; - m_pszHelpString = pHelpString ? pHelpString : ""; + m_pszHelpString = pHelpString ? pHelpString : empty_string; m_nFlags = flags; @@ -515,7 +517,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, con m_bHasCompletionCallback = completionFunc != 0 ? true : false; // Setup the rest - BaseClass::CreateBase( pName, pHelpString, flags ); + BaseClass::Create( pName, pHelpString, flags ); } ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) @@ -528,7 +530,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const c m_bUsingCommandCallbackInterface = false; // Setup the rest - BaseClass::CreateBase( pName, pHelpString, flags ); + BaseClass::Create( pName, pHelpString, flags ); } ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) @@ -541,7 +543,7 @@ ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const ch m_bUsingCommandCallbackInterface = true; // Setup the rest - BaseClass::CreateBase( pName, pHelpString, flags ); + BaseClass::Create( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -592,7 +594,7 @@ void ConCommand::Dispatch( const CCommand &command ) } // Command without callback!!! - AssertMsg( 0, "Encountered ConCommand '%s' without a callback!\n", GetName() ); + AssertMsg( 0, ( "Encountered ConCommand '%s' without a callback!\n", GetName() ) ); } @@ -777,10 +779,10 @@ void ConVar::InternalSetValue( const char *value ) Q_snprintf( tempVal,sizeof(tempVal), "%f", fNewValue ); val = tempVal; } - + // Redetermine value m_fValue = fNewValue; - m_nValue = ( int )( fNewValue ); + m_nValue = ( int )( m_fValue ); if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) { @@ -821,18 +823,14 @@ void ConVar::ChangeStringValue( const char *tempVal, float flOldValue ) *m_pszString = 0; } - // If nothing has changed, don't do the callbacks. - if (V_strcmp(pszOldValue, m_pszString) != 0) + // Invoke any necessary callback function + if ( m_fnChangeCallback ) { - // Invoke any necessary callback function - if ( m_fnChangeCallback ) - { - m_fnChangeCallback( this, pszOldValue, flOldValue ); - } - - g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue ); + m_fnChangeCallback( this, pszOldValue, flOldValue ); } + g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue ); + stackfree( pszOldValue ); } @@ -978,7 +976,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*= Assert( 0 ); } - BaseClass::CreateBase( pName, pHelpString, flags ); + BaseClass::Create( pName, pHelpString, flags ); } //----------------------------------------------------------------------------- @@ -1053,7 +1051,8 @@ const char *ConVar::GetDefault( void ) const void ConVar::SetDefault( const char *pszDefault ) { - m_pszDefaultValue = pszDefault ? pszDefault : ""; + static char *empty_string = ""; + m_pszDefaultValue = pszDefault ? pszDefault : empty_string; Assert( m_pszDefaultValue ); } diff --git a/tier1/diff.cpp b/tier1/diff.cpp index 048a3e22..113b2d0b 100644 --- a/tier1/diff.cpp +++ b/tier1/diff.cpp @@ -219,8 +219,8 @@ int FindDiffsForLargeFiles(uint8 const *NewBlock, uint8 const *OldBlock, int match_of=b->dataptr-lastmatchend; if ((match_of>-32768) && (match_of<32767)) { - int max_mlength=min(65535,OldBlock+OldSize-b->dataptr); - max_mlength=min(max_mlength,NewBlock+NewSize-walk); + int max_mlength=MIN(65535,OldBlock+OldSize-b->dataptr); + max_mlength=MIN(max_mlength,NewBlock+NewSize-walk); int i; for(i=0;idataptr[i]) @@ -355,8 +355,8 @@ int FindDiffs(uint8 const *NewBlock, uint8 const *OldBlock, int match_of=b->dataptr-lastmatchend; if ((match_of>-32768) && (match_of<32767)) { - int max_mlength=min(65535,OldBlock+OldSize-b->dataptr); - max_mlength=min(max_mlength,NewBlock+NewSize-walk); + int max_mlength=MIN(65535,OldBlock+OldSize-b->dataptr); + max_mlength=MIN(max_mlength,NewBlock+NewSize-walk); int i; for(i=0;idataptr[i]) @@ -467,7 +467,7 @@ int FindDiffsLowMemory(uint8 const *NewBlock, uint8 const *OldBlock, uint16 hash1=(walk[0]+walk[1]+walk[2]+walk[3]) & (NELEMS(old_data_hash)-1); if (old_data_hash[hash1]) { - int max_bytes_to_compare=min(NewBlock+NewSize-walk,OldBlock+OldSize-old_data_hash[hash1]); + int max_bytes_to_compare=MIN(NewBlock+NewSize-walk,OldBlock+OldSize-old_data_hash[hash1]); int nmatches; for(nmatches=0;nmatches> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; + odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -159,16 +159,16 @@ unsigned FASTCALL HashInt( const int n ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash4( const void *pKey ) { - const uint32 * p = (const uint32 *) pKey; - unsigned even, - odd, - n; + register const uint32 * p = (const uint32 *) pKey; + register unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; + odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -181,16 +181,16 @@ unsigned FASTCALL Hash4( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash8( const void *pKey ) { - const uint32 * p = (const uint32 *) pKey; - unsigned even, - odd, - n; + register const uint32 * p = (const uint32 *) pKey; + register unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; + odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -209,16 +209,16 @@ unsigned FASTCALL Hash8( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash12( const void *pKey ) { - const uint32 * p = (const uint32 *) pKey; - unsigned even, - odd, - n; + register const uint32 * p = (const uint32 *) pKey; + register unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; + odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; @@ -243,16 +243,16 @@ unsigned FASTCALL Hash12( const void *pKey ) //----------------------------------------------------------------------------- unsigned FASTCALL Hash16( const void *pKey ) { - const uint32 * p = (const uint32 *) pKey; - unsigned even, - odd, - n; + register const uint32 * p = (const uint32 *) pKey; + register unsigned even, + odd, + n; n = *p; even = g_nRandomValues[n & 0xff]; odd = g_nRandomValues[((n >> 8) & 0xff)]; even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; + odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; odd = g_nRandomValues[even ^ (n & 0xff)]; diff --git a/tier1/ilocalize.cpp b/tier1/ilocalize.cpp index 66673e64..d95bbf29 100644 --- a/tier1/ilocalize.cpp +++ b/tier1/ilocalize.cpp @@ -17,8 +17,7 @@ int ILocalize::ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSizeInBytes) { #ifdef POSIX - // Q_UTF8ToUnicode returns the number of bytes. This function is expected to return the number of chars. - return Q_UTF8ToUnicode(ansi, unicode, unicodeBufferSizeInBytes) / sizeof( wchar_t ); + return Q_UTF8ToUnicode(ansi, unicode, unicodeBufferSizeInBytes); #else int chars = MultiByteToWideChar(CP_UTF8, 0, ansi, -1, unicode, unicodeBufferSizeInBytes / sizeof(wchar_t)); unicode[(unicodeBufferSizeInBytes / sizeof(wchar_t)) - 1] = 0; @@ -257,4 +256,4 @@ void ILocalize::ConstructStringKeyValuesInternal(char *unicodeOutput, int unicod void ILocalize::ConstructStringKeyValuesInternal(wchar_t *unicodeOutput, int unicodeBufferSizeInBytes, const wchar_t *formatString, KeyValues *localizationVariables) { ConstructStringKeyValuesInternal_Impl( unicodeOutput, unicodeBufferSizeInBytes, formatString, localizationVariables ); -} +} \ No newline at end of file diff --git a/tier1/interface.cpp b/tier1/interface.cpp index 031a49a7..c221ac87 100644 --- a/tier1/interface.cpp +++ b/tier1/interface.cpp @@ -143,7 +143,6 @@ static void *Sys_GetProcAddress( const char *pModuleName, const char *pName ) #endif } -#if !defined(LINUX) static void *Sys_GetProcAddress( HMODULE hModule, const char *pName ) { #ifdef WIN32 @@ -152,7 +151,6 @@ static void *Sys_GetProcAddress( HMODULE hModule, const char *pName ) return (void *)dlsym( (void *)hModule, pName ); #endif } -#endif bool Sys_IsDebuggerPresent() { @@ -284,7 +282,7 @@ CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags /* = SYS_NO int i = CommandLine()->FindParm( "-basedir" ); if ( i ) { - V_strcpy_safe( szCwd, CommandLine()->GetParm( i + 1 ) ); + strcpy( szCwd, CommandLine()->GetParm( i+1 ) ); } } if (szCwd[strlen(szCwd) - 1] == '/' || szCwd[strlen(szCwd) - 1] == '\\' ) @@ -542,26 +540,3 @@ void CDllDemandLoader::Unload() m_hModule = 0; } } - -#if defined( STAGING_ONLY ) && defined( _WIN32 ) - -typedef USHORT( WINAPI RtlCaptureStackBackTrace_FUNC )( - ULONG frames_to_skip, - ULONG frames_to_capture, - PVOID *backtrace, - PULONG backtrace_hash ); - -extern "C" int backtrace( void **buffer, int size ) -{ - HMODULE hNTDll = GetModuleHandleA( "ntdll.dll" ); - static RtlCaptureStackBackTrace_FUNC * const pfnRtlCaptureStackBackTrace = - ( RtlCaptureStackBackTrace_FUNC * )GetProcAddress( hNTDll, "RtlCaptureStackBackTrace" ); - - if ( !pfnRtlCaptureStackBackTrace ) - return 0; - - return (int)pfnRtlCaptureStackBackTrace( 2, size, buffer, 0 ); -} - -#endif // STAGING_ONLY && _WIN32 - diff --git a/game/shared/interval.cpp b/tier1/interval.cpp similarity index 100% rename from game/shared/interval.cpp rename to tier1/interval.cpp diff --git a/tier1/kvpacker.cpp b/tier1/kvpacker.cpp index 53f7672e..3672a2d0 100644 --- a/tier1/kvpacker.cpp +++ b/tier1/kvpacker.cpp @@ -181,7 +181,7 @@ bool KVPacker::ReadAsBinary( KeyValues *pNode, CUtlBuffer &buffer ) if ( ePackType == PACKTYPE_NULLMARKER ) break; // no more peers - buffer.GetString( token ); + buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); token[KEYVALUES_TOKEN_SIZE-1] = 0; dat->SetName( token ); @@ -198,7 +198,7 @@ bool KVPacker::ReadAsBinary( KeyValues *pNode, CUtlBuffer &buffer ) } case PACKTYPE_STRING: { - buffer.GetString( token ); + buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); token[KEYVALUES_TOKEN_SIZE-1] = 0; dat->SetStringValue( token ); break; @@ -206,26 +206,15 @@ bool KVPacker::ReadAsBinary( KeyValues *pNode, CUtlBuffer &buffer ) case PACKTYPE_WSTRING: { int nLength = buffer.GetShort(); - if ( nLength >= 0 && nLength*sizeof( uint16 ) <= (uint)buffer.GetBytesRemaining() ) - { - if ( nLength > 0 ) - { - wchar_t *pTemp = (wchar_t *)malloc( sizeof( wchar_t ) * (1 + nLength) ); - - for ( int k = 0; k < nLength; ++k ) - { - pTemp[k] = buffer.GetShort(); // ugly, but preserving existing behavior - } - - pTemp[nLength] = 0; - dat->SetWString( NULL, pTemp ); - - free( pTemp ); - } - else - dat->SetWString( NULL, L"" ); + wchar_t *pTemp = (wchar_t *)stackalloc( sizeof(wchar_t) * ( 1 + nLength ) ); + for( int k = 0; k < nLength; ++ k ) + { + pTemp[k] = buffer.GetShort(); } + pTemp[ nLength ] = 0; + + dat->SetWString( NULL, pTemp ); break; } diff --git a/tier1/lzmaDecoder.cpp b/tier1/lzmaDecoder.cpp index 473f9c36..d547c2bc 100644 --- a/tier1/lzmaDecoder.cpp +++ b/tier1/lzmaDecoder.cpp @@ -1,348 +1,764 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// // -// LZMA Codec interface for engine. +// LZMA Codec. // -// LZMA SDK 9.38 beta -// 2015-01-03 : Igor Pavlov : Public domain -// http://www.7-zip.org/ +// LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) +// http://www.7-zip.org/ // -//========================================================================// - -#define _LZMADECODER_CPP +// Modified to use Source platform utilities and memory allocation overrides. +//=====================================================================================// #include "tier0/platform.h" -#include "tier0/basetypes.h" #include "tier0/dbg.h" - -#include "../utils/lzma/C/7zTypes.h" -#include "../utils/lzma/C/LzmaEnc.h" -#include "../utils/lzma/C/LzmaDec.h" - -// Ugly define to let us forward declare the anonymous-struct-typedef that is CLzmaDec in the header. -#define CLzmaDec_t CLzmaDec #include "tier1/lzmaDecoder.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -// Allocator to pass to LZMA functions -static void *SzAlloc(void *p, size_t size) { return malloc(size); } -static void SzFree(void *p, void *address) { free(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -//----------------------------------------------------------------------------- -// Returns true if buffer is compressed. -//----------------------------------------------------------------------------- -/* static */ -bool CLZMA::IsCompressed( unsigned char *pInput ) +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _LZMA_SYSTEM_SIZE_T */ +/* Use system's size_t. You can use it to enable 64-bit sizes supporting */ + +#ifndef _7ZIP_SIZET_DEFINED +#define _7ZIP_SIZET_DEFINED +#ifdef _LZMA_SYSTEM_SIZE_T +#include +typedef size_t SizeT; +#else +typedef UInt32 SizeT; +#endif +#endif + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +#define _LZMA_PROB32 +/* It can increase speed on some 32-bit CPUs, +but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback { - lzma_header_t *pHeader = (lzma_header_t *)pInput; - if ( pHeader && pHeader->id == LZMA_ID ) - { - return true; - } + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif - // unrecognized - return false; -} +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 -//----------------------------------------------------------------------------- -// Returns uncompressed size of compressed input buffer. Used for allocating output -// buffer for decompression. Returns 0 if input buffer is not compressed. -//----------------------------------------------------------------------------- -/* static */ -unsigned int CLZMA::GetActualSize( unsigned char *pInput ) +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties { - lzma_header_t *pHeader = (lzma_header_t *)pInput; - if ( pHeader && pHeader->id == LZMA_ID ) - { - return LittleLong( pHeader->actualSize ); - } + int lc; + int lp; + int pb; +#ifdef _LZMA_OUT_READ + UInt32 DictionarySize; +#endif +}CLzmaProperties; - // unrecognized - return 0; -} +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); -//----------------------------------------------------------------------------- -// Uncompress a buffer, Returns the uncompressed size. Caller must provide an -// adequate sized output buffer or memory corruption will occur. -//----------------------------------------------------------------------------- -/* static */ -unsigned int CLZMA::Uncompress( unsigned char *pInput, unsigned char *pOutput ) +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState { - lzma_header_t *pHeader = (lzma_header_t *)pInput; - if ( pHeader->id != LZMA_ID ) - { - // not ours - return false; - } + CLzmaProperties Properties; + CProb *Probs; - CLzmaDec state; +#ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; +#endif - LzmaDec_Construct(&state); +#ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; +#endif +} CLzmaDecoderState; - if ( LzmaDec_Allocate(&state, pHeader->properties, LZMA_PROPS_SIZE, &g_Alloc) != SZ_OK ) - { - Assert( false ); - return 0; - } +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif - // These are in/out variables - SizeT outProcessed = pHeader->actualSize; - SizeT inProcessed = pHeader->lzmaSize; - ELzmaStatus status; - SRes result = LzmaDecode( (Byte *)pOutput, &outProcessed, (Byte *)(pInput + sizeof( lzma_header_t ) ), - &inProcessed, (Byte *)pHeader->properties, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc ); +int LzmaDecode(CLzmaDecoderState *vs, +#ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, +#else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, +#endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) - LzmaDec_Free(&state, &g_Alloc); +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 - if ( result != SZ_OK || pHeader->actualSize != outProcessed ) - { - Warning( "LZMA Decompression failed (%i)\n", result ); - return 0; - } +#define RC_READ_BYTE (*Buffer++) - return outProcessed; -} +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ +{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} -CLZMAStream::CLZMAStream() - : m_pDecoderState( NULL ), - m_nActualSize( 0 ), - m_nActualBytesRead ( 0 ), - m_nCompressedSize( 0 ), - m_nCompressedBytesRead ( 0 ), - m_bParsedHeader( false ), - m_bZIPStyleHeader( false ) -{} - -CLZMAStream::~CLZMAStream() -{ - FreeDecoderState(); -} +#ifdef _LZMA_IN_CB -void CLZMAStream::FreeDecoderState() -{ - if ( m_pDecoderState ) - { - LzmaDec_Free( m_pDecoderState, &g_Alloc ); - m_pDecoderState = NULL; - } -} +#define RC_TEST { if (Buffer == BufferLim) \ +{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} -bool CLZMAStream::CreateDecoderState( const unsigned char *pProperties ) -{ - if ( m_pDecoderState ) - { - Assert( !m_pDecoderState ); - FreeDecoderState(); - } +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 - m_pDecoderState = new CLzmaDec(); +#else - LzmaDec_Construct( m_pDecoderState ); - if ( LzmaDec_Allocate( m_pDecoderState, pProperties, LZMA_PROPS_SIZE, &g_Alloc) != SZ_OK ) - { - AssertMsg( false, "Failed to allocate lzma decoder state" ); - m_pDecoderState = NULL; - return false; - } +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } - LzmaDec_Init( m_pDecoderState ); +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 - return true; -} +#endif -// Attempt to read up to nMaxInputBytes from the compressed stream, writing up to nMaxOutputBytes to pOutput. -// Returns false if read stops due to an error. -bool CLZMAStream::Read( unsigned char *pInput, unsigned int nMaxInputBytes, - unsigned char *pOutput, unsigned int nMaxOutputBytes, - /* out */ unsigned int &nCompressedBytesRead, - /* out */ unsigned int &nOutputBytesWritten ) -{ - nCompressedBytesRead = 0; - nOutputBytesWritten = 0; - bool bStartedWithHeader = m_bParsedHeader; +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } - // Check for initial chunk of data - if ( !m_bParsedHeader ) - { - unsigned int nBytesConsumed = 0; - eHeaderParse parseResult = TryParseHeader( pInput, nMaxInputBytes, nBytesConsumed ); +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; - if ( parseResult == eHeaderParse_NeedMoreBytes ) - { - // Not an error, just need more data to continue - return true; - } - else if ( parseResult != eHeaderParse_OK ) - { - Assert( parseResult == eHeaderParse_Fail ); - // Invalid header - return false; - } +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ +{ UpdateBit0(p); mi <<= 1; A0; } else \ +{ UpdateBit1(p); mi = (mi + mi) + 1; A1; } - // Header consumed, fall through to continue read after it - nCompressedBytesRead += nBytesConsumed; - pInput += nBytesConsumed; - nMaxInputBytes -= nBytesConsumed; - } +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) - // These are input ( available size ) *and* output ( size processed ) vars for lzma - SizeT expectedInputRemaining = m_nCompressedSize - Min( m_nCompressedBytesRead + nCompressedBytesRead, m_nCompressedSize ); - SizeT expectedOutputRemaining = m_nActualSize - m_nActualBytesRead; - SizeT inSize = Min( (SizeT)nMaxInputBytes, expectedInputRemaining ); - SizeT outSize = Min( (SizeT)nMaxOutputBytes, expectedOutputRemaining ); - ELzmaStatus status; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if ( inSize == expectedInputRemaining && outSize == expectedOutputRemaining ) - { - // Expect to finish decoding this call. - finishMode = LZMA_FINISH_END; - } - SRes result = LzmaDec_DecodeToBuf( m_pDecoderState, pOutput, &outSize, - pInput, &inSize, finishMode, &status ); - - // DevMsg("[%p] Running lzmaDecode:\n" - // " pInput: %p\n" - // " nMaxInputBytes: %i\n" - // " pOutput: %p\n" - // " nMaxOutputBytes: %u\n" - // " inSize: %u\n" - // " outSize: %u\n" - // " result: %u\n" - // " status: %i\n" - // " m_nActualSize: %u\n" - // " m_nActualBytesRead: %u\n", - // this, pInput, nMaxInputBytes, pOutput, nMaxOutputBytes, - // inSize, outSize, result, status, m_nActualSize, m_nActualBytesRead); - - if ( result != SZ_OK ) - { - if ( !bStartedWithHeader ) - { - // If we're returning false, we need to pretend we didn't consume anything. - FreeDecoderState(); - m_bParsedHeader = false; - } - return false; - } +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ +{ int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } - nCompressedBytesRead += inSize; - nOutputBytesWritten += outSize; - m_nCompressedBytesRead += nCompressedBytesRead; - m_nActualBytesRead += nOutputBytesWritten; +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) - Assert( m_nCompressedBytesRead <= m_nCompressedSize ); - return true; -} +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) -bool CLZMAStream::GetExpectedBytesRemaining( /* out */ unsigned int &nBytesRemaining ) -{ - if ( !m_bParsedHeader && !m_bZIPStyleHeader ) { - return false; - } +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - nBytesRemaining = m_nActualSize - m_nActualBytesRead; - return true; -} +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 -void CLZMAStream::InitZIPHeader( unsigned int nCompressedSize, unsigned int nOriginalSize ) +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) { - if ( m_bParsedHeader || m_bZIPStyleHeader ) + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; { - AssertMsg( !m_bParsedHeader && !m_bZIPStyleHeader, - "LZMA Stream: InitZIPHeader() called on stream past header" ); - return; + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ } - m_nCompressedSize = nCompressedSize; - m_nActualSize = nOriginalSize; - // Signal to TryParseHeader to expect a zip-style header (which wont have the size values) - m_bZIPStyleHeader = true; +#ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } +#endif + return LZMA_RESULT_OK; } -CLZMAStream::eHeaderParse CLZMAStream::TryParseHeader( unsigned char *pInput, unsigned int nBytesAvailable, /* out */ unsigned int &nBytesConsumed ) -{ - nBytesConsumed = 0; +#define kLzmaStreamWasFinishedId (-1) - if ( m_bParsedHeader ) +int LzmaDecode(CLzmaDecoderState *vs, +#ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, +#else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, +#endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + +#ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; +#ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; +#else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; +#endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + +#ifndef _LZMA_IN_CB + *inSizeProcessed = 0; +#endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) { - AssertMsg( !m_bParsedHeader, "CLZMAStream::ReadSourceHeader called on already initialized stream" ); - return eHeaderParse_Fail; + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; } - if ( m_bZIPStyleHeader ) + if (len == kLzmaNeedInitId) { - // ZIP Spec, 5.8.8 - // LZMA Version Information 2 bytes - // LZMA Properties Size 2 bytes - // LZMA Properties Data variable, defined by "LZMA Properties Size" - - if ( nBytesAvailable < 4 ) { - // No error, but need more input to continue - return eHeaderParse_NeedMoreBytes; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; +#ifdef _LZMA_IN_CB + RC_INIT; +#else + RC_INIT(inStream, inSize); +#endif } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + +#else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; - // Should probably check this - // unsigned char nLZMAVer[2] = { pInput[0], pInput[1] }; +#ifndef _LZMA_IN_CB + *inSizeProcessed = 0; +#endif + *outSizeProcessed = 0; - uint16 nLZMAPropertiesSize = LittleWord( *(uint16 *)(pInput + 2) ); + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + +#ifdef _LZMA_IN_CB + RC_INIT; +#else + RC_INIT(inStream, inSize); +#endif - nBytesConsumed += 4; +#endif /* _LZMA_OUT_READ */ - if ( nLZMAPropertiesSize != LZMA_PROPS_SIZE ) + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos +#ifdef _LZMA_OUT_READ + + globalPos +#endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) { - Warning( "LZMA stream: Unexpected LZMA properties size: %hu, expecting %u. Version mismatch?\n", - nLZMAPropertiesSize, LZMA_PROPS_SIZE ); - return eHeaderParse_Fail; + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos +#ifdef _LZMA_OUT_READ + + globalPos +#endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; +#ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; +#else + matchByte = outStream[nowPos - rep0]; +#endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; +#ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; +#endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; } - - if ( nBytesAvailable < static_cast(nLZMAPropertiesSize) + 4 ) +else +{ + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { +#ifdef _LZMA_OUT_READ + UInt32 pos; +#endif + UpdateBit0(prob); + +#ifdef _LZMA_OUT_READ + if (distanceLimit == 0) +#else + if (nowPos == 0) +#endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; +#ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; +#else + previousByte = outStream[nowPos - rep0]; +#endif + outStream[nowPos++] = previousByte; +#ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; +#endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else { - return eHeaderParse_NeedMoreBytes; + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; } - - // Looks reasonable, try to parse - if ( !CreateDecoderState( (Byte *)pInput + 4 ) ) + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else { - AssertMsg( false, "Failed decoding Lzma properties" ); - return eHeaderParse_Fail; + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; +#ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) +#else + if (rep0 > nowPos) +#endif + return LZMA_RESULT_DATA_ERROR; + +#ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; +#endif + + do + { +#ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; +#else + previousByte = outStream[nowPos - rep0]; +#endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); +} + } + RC_NORMALIZE; + +#ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; +#endif + +#ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; +#else + *inSizeProcessed = (SizeT)(Buffer - inStream); +#endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} - nBytesConsumed += nLZMAPropertiesSize; +//----------------------------------------------------------------------------- +// Returns true if buffer is compressed. +//----------------------------------------------------------------------------- +bool CLZMA::IsCompressed( unsigned char *pInput ) +{ + lzma_header_t *pHeader = (lzma_header_t *)pInput; + if ( pHeader && pHeader->id == LZMA_ID ) + { + return true; } - else + + // unrecognized + return false; +} + +//----------------------------------------------------------------------------- +// Returns uncompressed size of compressed input buffer. Used for allocating output +// buffer for decompression. Returns 0 if input buffer is not compressed. +//----------------------------------------------------------------------------- +unsigned int CLZMA::GetActualSize( unsigned char *pInput ) +{ + lzma_header_t *pHeader = (lzma_header_t *)pInput; + if ( pHeader && pHeader->id == LZMA_ID ) { - // Else native source engine style header - if ( nBytesAvailable < sizeof( lzma_header_t ) ) - { - // need more input to continue - return eHeaderParse_NeedMoreBytes; - } + return LittleLong( pHeader->actualSize ); + } - m_nActualSize = CLZMA::GetActualSize( pInput ); + // unrecognized + return 0; +} - if ( !m_nActualSize ) - { - // unrecognized - Warning( "Unrecognized LZMA data\n" ); - return eHeaderParse_Fail; - } +//----------------------------------------------------------------------------- +// Uncompress a buffer, Returns the uncompressed size. Caller must provide an +// adequate sized output buffer or memory corruption will occur. +//----------------------------------------------------------------------------- +unsigned int CLZMA::Uncompress( unsigned char *pInput, unsigned char *pOutput ) +{ + unsigned int actualSize = GetActualSize( pInput ); + if ( !actualSize ) + { + // unrecognized + return 0; + } - if ( !CreateDecoderState( ((lzma_header_t *)pInput)->properties ) ) - { - AssertMsg( false, "Failed decoding Lzma properties" ); - return eHeaderParse_Fail; - } + CLzmaDecoderState state; + if ( LzmaDecodeProperties( &state.Properties, ((lzma_header_t *)pInput)->properties, LZMA_PROPERTIES_SIZE ) != LZMA_RESULT_OK ) + { + Assert( 0 ); + } + state.Probs = (CProb *)malloc( LzmaGetNumProbs( &state.Properties ) * sizeof( CProb ) ); + + unsigned int lzmaSize = LittleLong( ((lzma_header_t *)pInput)->lzmaSize ); + + SizeT inProcessed; + SizeT outProcessed; + int result = LzmaDecode( &state, pInput + sizeof( lzma_header_t ), lzmaSize, &inProcessed, pOutput, actualSize, &outProcessed ); + + free( state.Probs ); - m_nCompressedSize = LittleLong( ((lzma_header_t *)pInput)->lzmaSize ) + sizeof( lzma_header_t ); - nBytesConsumed += sizeof( lzma_header_t ); + if ( result != LZMA_RESULT_OK || outProcessed != (SizeT)actualSize ) + { + Assert( 0 ); + return 0; } - m_bParsedHeader = true; - return eHeaderParse_OK; + return outProcessed; } + diff --git a/tier1/mapbase_con_groups.cpp b/tier1/mapbase_con_groups.cpp new file mode 100644 index 00000000..5f23b3f8 --- /dev/null +++ b/tier1/mapbase_con_groups.cpp @@ -0,0 +1,193 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: Mapbase classifies certain types of console messages into groups with specific colors. +// +// This is inspired by similar groups seen in CS:GO and Source 2 games. +// +// $NoKeywords: $ +//============================================================================= + +#include +#include +#include +#include "basetypes.h" +#include "tier1.h" +#include "utldict.h" +#include "Color.h" +#include "mapbase_con_groups.h" +#include "KeyValues.h" +#include "filesystem.h" +#include "mapbase_matchers_base.h" + +struct ConGroup_t +{ + ConGroup_t( const char *_pszName, const char *_pszDescription ) + { + pszName = _pszName; + pszDescription = _pszDescription; + _clr.SetColor( 224, 224, 224, 255 ); // Default to a shade of gray + } + + const Color &GetColor() + { + return _clr; + } + + const char *pszName; + const char *pszDescription; + Color _clr; + + bool bDisabled; +}; + +// TODO: Something more reliable? +static bool g_bIncludeConGroupNames = false; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//#define DEFINE_CON_GROUP(id, name, codename) { name, &con_group_##codename##_color } +#define DEFINE_CON_GROUP(id, name, description) { name, description } + +ConGroup_t g_ConGroups[CON_GROUP_MAX] = { + + // General + DEFINE_CON_GROUP( CON_GROUP_MAPBASE_MISC, "Mapbase misc.", "Messages from misc. Mapbase functions, like map-specific files." ), + DEFINE_CON_GROUP( CON_GROUP_PHYSICS, "Physics", "Messages from physics-related events." ), + DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, "Entity IO", "Messages from I/O events. (these display in developer 2)" ), + DEFINE_CON_GROUP( CON_GROUP_RESPONSE_SYSTEM, "Response System", "Messages from the Response System, a library primarily used for NPC speech." ), + + // Game + DEFINE_CON_GROUP( CON_GROUP_NPC_AI, "NPC AI", "Messages from NPC AI, etc. which display at various verbose levels." ), + DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, "NPC scripts", "Messages from scripted_sequence, etc. (these display in developer 2)" ), + DEFINE_CON_GROUP( CON_GROUP_SPEECH_AI, "Speech AI", "Messages from response expressers. (these display in developer 1, 2, etc.)" ), + DEFINE_CON_GROUP( CON_GROUP_CHOREO, "Choreo", "Messages from choreographed scenes. (these display in developer 1, 2, etc.)" ), + + // VScript + DEFINE_CON_GROUP( CON_GROUP_VSCRIPT, "VScript", "Internal messages from VScript not produced by actual scripts." ), + DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, "VScript print", "Messages from VScript's 'print' function." ), + +}; + +int FindConGroup( const char *pszName ) +{ + for (int i = 0; i < CON_GROUP_MAX; i++) + { + if (Q_stricmp( pszName, g_ConGroups[i].pszName ) == 0) + return i; + } + + return -1; +} + +//----------------------------------------------------------------------------- +// Loads console groups +//----------------------------------------------------------------------------- +void LoadConsoleGroupsFromFile( IBaseFileSystem *filesystem, const char *pszFileName, const char *pathID ) +{ + KeyValues *pGroupRoot = new KeyValues( "ConsoleGroups" ); + + pGroupRoot->LoadFromFile( filesystem, pszFileName, pathID ); + + KeyValues *pGroup = NULL; + for ( pGroup = pGroupRoot->GetFirstTrueSubKey(); pGroup; pGroup = pGroup->GetNextTrueSubKey() ) + { + int index = FindConGroup( pGroup->GetName() ); + if (index != -1) + { + Color msgClr = pGroup->GetColor( "MessageColor" ); + + // Make sure the color isn't 0,0,0,0 before assigning + if (msgClr.GetRawColor() != 0) + g_ConGroups[index]._clr = msgClr; + + g_ConGroups[index].bDisabled = pGroup->GetBool( "Disabled", false ); + } + else + { + Warning( "Invalid console group %s (new groups should be defined in the code)\n", pGroup->GetName() ); + } + } + + pGroupRoot->deleteThis(); +} + +void InitConsoleGroups( IBaseFileSystem *filesystem ) +{ + LoadConsoleGroupsFromFile( filesystem, "scripts/mapbase_con_groups.txt", "MOD" ); + LoadConsoleGroupsFromFile( filesystem, "scripts/mod_con_groups.txt", "MOD" ); +} + +void PrintAllConsoleGroups() +{ + Msg( "============================================================\n" ); + for (int i = 0; i < CON_GROUP_MAX; i++) + { + ConColorMsg( g_ConGroups[i].GetColor(), " # %s", g_ConGroups[i].pszName ); + + if (g_ConGroups[i].bDisabled) + Msg(" [DISABLED]"); + + Msg( " - %s ", g_ConGroups[i].pszDescription ); + + Msg("\n"); + } + Msg( "============================================================\n" ); +} + +void ToggleConsoleGroups( const char *pszQuery ) +{ + bool bMatched = false; + + for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++) + { + if (Matcher_NamesMatch( pszQuery, g_ConGroups[i].pszName )) + { + Msg( "%s is now %s\n", g_ConGroups[i].pszName, g_ConGroups[i].bDisabled ? "enabled" : "disabled" ); + g_ConGroups[i].bDisabled = !g_ConGroups[i].bDisabled; + bMatched = true; + } + } + + if (!bMatched) + Msg( "No groups matching \"%s\"\n", pszQuery ); +} + +void SetConsoleGroupIncludeNames( bool bToggle ) +{ + g_bIncludeConGroupNames = bToggle; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void CGMsg( int level, ConGroupID_t nGroup, const tchar* pMsg, ... ) +{ + // Return early if we're not at this level + if (!IsSpewActive("developer", level)) + return; + + char string[ 2048 ]; + va_list argptr; + va_start( argptr, pMsg ); + Q_vsnprintf( string, sizeof(string), pMsg, argptr ); + va_end( argptr ); + + Assert( nGroup >= 0 ); + Assert( nGroup < CON_GROUP_MAX ); + + ConGroup_t *pGroup = &g_ConGroups[nGroup]; + + if (pGroup->bDisabled) + { + // Do nothing + } + else if (g_bIncludeConGroupNames) + { + ConColorMsg(level, pGroup->GetColor(), "[%s] %s", pGroup->pszName, string); + } + else + { + ConColorMsg(level, pGroup->GetColor(), "%s", string); + } +} diff --git a/tier1/mapbase_matchers_base.cpp b/tier1/mapbase_matchers_base.cpp new file mode 100644 index 00000000..85cdb6e1 --- /dev/null +++ b/tier1/mapbase_matchers_base.cpp @@ -0,0 +1,243 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: General matching functions for things like wildcards and !=. +// +// $NoKeywords: $ +//============================================================================= + +#include "mapbase_matchers_base.h" +#include "convar.h" + +// glibc (Linux) uses these tokens when including , so we must not #define them +#undef max +#undef min +#include +#undef MINMAX_H +#include "minmax.h" + +ConVar mapbase_wildcards_enabled("mapbase_wildcards_enabled", "1", FCVAR_NONE, "Toggles Mapbase's '?' wildcard and true '*' features. Useful for maps that have '?' in their targetnames."); +ConVar mapbase_wildcards_lazy_hack("mapbase_wildcards_lazy_hack", "1", FCVAR_NONE, "Toggles a hack which prevents Mapbase's lazy '?' wildcards from picking up \"???\", the default instance parameter."); +ConVar mapbase_regex_enabled("mapbase_regex_enabled", "1", FCVAR_NONE, "Toggles Mapbase's regex matching handover."); + +//============================================================================= +// These are the "matchers" that compare with wildcards ("any*" for text starting with "any") +// and operators (<3 for numbers less than 3). +// +// Matcher_Regex - Uses regex functions from the std library. +// Matcher_NamesMatch - Based on Valve's original NamesMatch function, using wildcards and regex. +// +// AppearsToBeANumber - Response System-based function which checks if the string might be a number. +//============================================================================= + +// The recursive part of Mapbase's modified version of Valve's NamesMatch(). +bool Matcher_RunCharCompare(const char *pszQuery, const char *szValue) +{ + // This matching model is based off of the ASW SDK + while ( *szValue && *pszQuery ) + { + char cName = *szValue; + char cQuery = *pszQuery; + if ( cName != cQuery && tolower(cName) != tolower(cQuery) ) // people almost always use lowercase, so assume that first + { + // Now we'll try the new and improved Mapbase wildcards! + switch (*pszQuery) + { + case '*': + { + // Return true at classic trailing * + if ( *(pszQuery+1) == 0 ) + return true; + + if (mapbase_wildcards_enabled.GetBool()) + { + // There's text after this * which we need to test. + // This recursion allows for multiple wildcards + int vlen = Q_strlen(szValue); + ++pszQuery; + for (int i = 0; i < vlen; i++) + { + if (Matcher_RunCharCompare(pszQuery, szValue + i)) + return true; + } + } + return false; + } break; + case '?': + // Just skip if we're capable of lazy wildcards + if (mapbase_wildcards_enabled.GetBool()) + break; + default: + return false; + } + } + ++szValue; + ++pszQuery; + } + + // Include a classic trailing * check for when szValue is something like "value" and pszQuery is "value*" + return ( ( *pszQuery == 0 && *szValue == 0 ) || *pszQuery == '*' ); +} + +// Regular expressions based off of the std library. +// The C++ is strong in this one. +bool Matcher_Regex(const char *pszQuery, const char *szValue) +{ + std::regex regex; + + // Since I can't find any other way to check for valid regex, + // use a try-catch here to see if it throws an exception. + try { regex = std::regex(pszQuery); } + catch (std::regex_error &e) + { + Msg("Invalid regex \"%s\" (%s)\n", pszQuery, e.what()); + return false; + } + + std::match_results results; + bool bMatch = std::regex_match( szValue, results, regex ); + if (!bMatch) + return false; + + // Only match the *whole* string + return Q_strlen(results.str(0).c_str()) == Q_strlen(szValue); +} + +// The entry point for Mapbase's modified version of Valve's NamesMatch(). +bool Matcher_NamesMatch(const char *pszQuery, const char *szValue) +{ + if ( szValue == NULL ) + return (*pszQuery == 0 || *pszQuery == '*'); + + // If the pointers are identical, we're identical + if ( szValue == pszQuery ) + return true; + + // Check for regex + if ( *pszQuery == '@' && mapbase_regex_enabled.GetBool() ) + { + // Make sure it has a forward slash + // (prevents confusion with instance fixup escape) + if (*(pszQuery+1) == '/') + { + return Matcher_Regex( pszQuery+2, szValue ); + } + } + else if (pszQuery[0] == '?' && pszQuery[1] == '?' && pszQuery[2] == '?' && mapbase_wildcards_lazy_hack.GetBool()) + { + // HACKHACK: There's a nasty issue where instances with blank parameters use "???", but Mapbase's lazy wildcard code + // recognizes this as essentially meaning "any name with 3 characters". This is a serious problem when the instance + // specifically expects the game to interpret "???" as a blank space, such as with damage filters, which crash when targeting + // a non-filter entity. + return false; + } + + return Matcher_RunCharCompare( pszQuery, szValue ); +} + +bool Matcher_NamesMatch_Classic(const char *pszQuery, const char *szValue) +{ + if ( szValue == NULL ) + return (!pszQuery || *pszQuery == 0 || *pszQuery == '*'); + + // If the pointers are identical, we're identical + if ( szValue == pszQuery ) + return true; + + while ( *szValue && *pszQuery ) + { + unsigned char cName = *szValue; + unsigned char cQuery = *pszQuery; + // simple ascii case conversion + if ( cName == cQuery ) + ; + else if ( cName - 'A' <= (unsigned char)'Z' - 'A' && cName - 'A' + 'a' == cQuery ) + ; + else if ( cName - 'a' <= (unsigned char)'z' - 'a' && cName - 'a' + 'A' == cQuery ) + ; + else + break; + ++szValue; + ++pszQuery; + } + + if ( *pszQuery == 0 && *szValue == 0 ) + return true; + + // @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing * + if ( *pszQuery == '*' ) + return true; + + return false; +} + +bool Matcher_NamesMatch_MutualWildcard(const char *pszQuery, const char *szValue) +{ + if ( szValue == NULL ) + return (!pszQuery || *pszQuery == 0 || *pszQuery == '*'); + + if ( pszQuery == NULL ) + return (!szValue || *szValue == 0 || *szValue == '*'); + + // If the pointers are identical, we're identical + if ( szValue == pszQuery ) + return true; + + while ( *szValue && *pszQuery ) + { + unsigned char cName = *szValue; + unsigned char cQuery = *pszQuery; + // simple ascii case conversion + if ( cName == cQuery ) + ; + else if ( cName - 'A' <= (unsigned char)'Z' - 'A' && cName - 'A' + 'a' == cQuery ) + ; + else if ( cName - 'a' <= (unsigned char)'z' - 'a' && cName - 'a' + 'A' == cQuery ) + ; + else + break; + ++szValue; + ++pszQuery; + } + + if ( *pszQuery == 0 && *szValue == 0 ) + return true; + + // @TODO (toml 03-18-03): Perhaps support real wildcards. Right now, only thing supported is trailing * + if ( *pszQuery == '*' || *szValue == '*' ) + return true; + + return false; +} + +// Returns true if a string contains a wildcard. +bool Matcher_ContainsWildcard(const char *pszQuery) +{ + if ( pszQuery == NULL ) + return false; + + while ( *pszQuery ) + { + unsigned char cQuery = *pszQuery; + if (cQuery == '*' || cQuery == '?') + return true; + ++pszQuery; + } + + return false; +} + +// Matcher_Compare is a deprecated alias originally used when Matcher_Match didn't support wildcards. +/* +bool Matcher_Compare(const char *pszQuery, const char *szValue) +{ + return Matcher_Match(pszQuery, szValue); +#if 0 + // I have to do this so wildcards could test *before* the response system comparison. + // I know it removes the operators twice, but I won't worry about it. + bool match = Matcher_NamesMatch(Matcher_RemoveOperators(pszQuery), szValue); + if (match) + return Matcher_Match(pszQuery, szValue); + return false; +#endif +} +*/ diff --git a/tier1/math_proxy.cpp b/tier1/math_proxy.cpp new file mode 100644 index 00000000..5a221433 --- /dev/null +++ b/tier1/math_proxy.cpp @@ -0,0 +1,51 @@ +/** + * + * math_proxy.cpp - Implements certain unresolved symbols and points them to their proper endpoints + * + */ + +#if __GNUC__ > 5 + +#include + +extern "C" float __powf_finite(float x, float y) +{ + return powf(x, y); +} + +extern "C" double __atan2_finite(double y, double x) +{ + return atan2(y, x); +} + +extern "C" float __logf_finite(float f) +{ + return logf(f); +} + +extern "C" float __acosf_finite(float f) +{ + return acosf(f); +} + +extern "C" double __exp_finite(double f) +{ + return exp(f); +} + +extern "C" float __expf_finite(float f) +{ + return expf(f); +} + +extern "C" double __pow_finite(double x, double y) +{ + return pow(x, y); +} + +extern "C" double __log_finite(double f) +{ + return log(f); +} + +#endif diff --git a/tier1/mempool.cpp b/tier1/mempool.cpp index fa49edb5..ba2eb28a 100644 --- a/tier1/mempool.cpp +++ b/tier1/mempool.cpp @@ -249,7 +249,7 @@ void *CUtlMemoryPool::Alloc( size_t amount ) } } m_BlocksAllocated++; - m_PeakAlloc = max(m_PeakAlloc, m_BlocksAllocated); + m_PeakAlloc = MAX(m_PeakAlloc, m_BlocksAllocated); returnBlock = m_pHeadOfFreeList; diff --git a/tier1/newbitbuf.cpp b/tier1/newbitbuf.cpp index ef90f479..11e8f0c5 100644 --- a/tier1/newbitbuf.cpp +++ b/tier1/newbitbuf.cpp @@ -383,7 +383,7 @@ bool CBitRead::Seek( int nPosition ) m_nBitsAvail = 1; } m_nInBufWord >>= ( nAdjPosition & 31 ); - m_nBitsAvail = min( m_nBitsAvail, 32 - ( nAdjPosition & 31 ) ); // in case grabnextdword overflowed + m_nBitsAvail = MIN( m_nBitsAvail, 32 - ( nAdjPosition & 31 ) ); // in case grabnextdword overflowed } return bSucc; } diff --git a/tier1/pathmatch.cpp b/tier1/pathmatch.cpp index f828a9ae..c29c6ed3 100644 --- a/tier1/pathmatch.cpp +++ b/tier1/pathmatch.cpp @@ -316,7 +316,6 @@ inline __attribute__ ((always_inline)) static int utf8casecmp_loop(const uint32_ } } -#ifdef UTF8_PATHMATCH static int utf8casecmp(const char *str1, const char *str2) { uint32_t *folded1 = fold_utf8(str1); @@ -326,7 +325,6 @@ static int utf8casecmp(const char *str1, const char *str2) delete[] folded2; return retval; } -#endif // Simple object to help make sure a DIR* from opendir // gets closed when it goes out of scope. diff --git a/tier1/snappy-internal.h b/tier1/snappy-internal.h index c99d3313..8bc4a529 100644 --- a/tier1/snappy-internal.h +++ b/tier1/snappy-internal.h @@ -50,7 +50,7 @@ class WorkingMemory { uint16 small_table_[1<<10]; // 2KB uint16* large_table_; // Allocated only when needed - DISALLOW_COPY_AND_ASSIGN(WorkingMemory); + SNAPPY_DISALLOW_COPY_AND_ASSIGN(WorkingMemory); }; // Flat array compression that does not emit the "uncompressed length" @@ -85,7 +85,7 @@ char* CompressFragment(const char* input, static inline int FindMatchLength(const char* s1, const char* s2, const char* s2_limit) { - assert(s2_limit >= s2); + DCHECK_GE(s2_limit, s2); int matched = 0; // Find out how long the match is. We loop over the data 64 bits at a @@ -122,7 +122,7 @@ static inline int FindMatchLength(const char* s1, const char* s2, const char* s2_limit) { // Implementation based on the x86-64 version, above. - assert(s2_limit >= s2); + DCHECK_GE(s2_limit, s2); int matched = 0; while (s2 <= s2_limit - 4 && diff --git a/tier1/snappy-sinksource.cpp b/tier1/snappy-sinksource.cpp index 8e868bb4..2dd88a36 100644 --- a/tier1/snappy-sinksource.cpp +++ b/tier1/snappy-sinksource.cpp @@ -36,8 +36,7 @@ Source::~Source() { } Sink::~Sink() { } -char* Sink::GetAppendBuffer(size_t length, char* scratch) { - (void)length; +char* Sink::GetAppendBuffer(size_t, char* scratch) { return scratch; } @@ -65,10 +64,9 @@ void UncheckedByteArraySink::Append(const char* data, size_t n) { dest_ += n; } -char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) { - (void)scratch; - (void)len; +char* UncheckedByteArraySink::GetAppendBuffer(size_t, char*) { return dest_; } + } diff --git a/tier1/snappy-stubs-internal.h b/tier1/snappy-stubs-internal.h index 1413825a..9a6f0c2b 100644 --- a/tier1/snappy-stubs-internal.h +++ b/tier1/snappy-stubs-internal.h @@ -37,18 +37,18 @@ #include "tier0/platform.h" +// don't use iostream, this make us fail to run under OS X 10.5 +//#include #include #include #include #include -#ifdef HAVE_SYS_MMAN_H +#ifdef HAVE_SYS_MMAN #include #endif -#include "snappy-stubs-public.h" - #if defined(__x86_64__) // Enable 64-bit optimized versions of some routines. @@ -65,13 +65,13 @@ // header file is never used from any public header files. using namespace std; +// We only define ARRAYSIZE if it isn't already defined, because this definition +// is not very good. +#ifndef ARRAYSIZE // The size of an array, if known at compile-time. // Will give unexpected results if used on a pointer. -// We undefine it first, since some compilers already have a definition. -#ifdef ARRAYSIZE -#undef ARRAYSIZE -#endif #define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) +#endif // Static prediction hints. #ifdef HAVE_BUILTIN_EXPECT @@ -87,71 +87,126 @@ using namespace std; // version (anyone who wants to regenerate it can just do the call // themselves within main()). #define DEFINE_bool(flag_name, default_value, description) \ - bool FLAGS_ ## flag_name = default_value + bool FLAGS_ ## flag_name = default_value; #define DECLARE_bool(flag_name) \ - extern bool FLAGS_ ## flag_name + extern bool FLAGS_ ## flag_name; +#define REGISTER_MODULE_INITIALIZER(name, code) + +#define SNAPPY_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) namespace snappy { static const uint32 kuint32max = static_cast(0xFFFFFFFF); static const int64 kint64max = static_cast(0x7FFFFFFFFFFFFFFFLL); -// Potentially unaligned loads and stores. +// Logging. -// x86 and PowerPC can simply do these loads and stores native. +#define LOG(level) LogMessage() +#define VLOG(level) true ? (void)0 : \ + snappy::LogMessageVoidify() & snappy::LogMessage() -#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) +class LogMessage { + public: + LogMessage() { } + ~LogMessage() { + fprintf( stderr, "\n" ); + //cerr << endl; + } -#define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) -#define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) -#define UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) + LogMessage& operator<<(const std::string& msg) { + //cerr << msg; + fprintf( stderr, "%s", msg.c_str() ); -#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) -#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) -#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) + return *this; + } + LogMessage& operator<<(int x) { + fprintf( stderr, "%d", x ); + //cerr << x; + return *this; + } +}; -// ARMv7 and newer support native unaligned accesses, but only of 16-bit -// and 32-bit values (not 64-bit); older versions either raise a fatal signal, -// do an unaligned read and rotate the words around a bit, or do the reads very -// slowly (trip through kernel mode). There's no simple #define that says just -// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6 -// sub-architectures. -// -// This is a mess, but there's not much we can do about it. - -#elif defined(__arm__) && \ - !defined(__ARM_ARCH_4__) && \ - !defined(__ARM_ARCH_4T__) && \ - !defined(__ARM_ARCH_5__) && \ - !defined(__ARM_ARCH_5T__) && \ - !defined(__ARM_ARCH_5TE__) && \ - !defined(__ARM_ARCH_5TEJ__) && \ - !defined(__ARM_ARCH_6__) && \ - !defined(__ARM_ARCH_6J__) && \ - !defined(__ARM_ARCH_6K__) && \ - !defined(__ARM_ARCH_6Z__) && \ - !defined(__ARM_ARCH_6ZK__) && \ - !defined(__ARM_ARCH_6T2__) +// Asserts, both versions activated in debug mode only, +// and ones that are always active. + +#define CRASH_UNLESS(condition) \ + PREDICT_TRUE(condition) ? (void)0 : \ + snappy::LogMessageVoidify() & snappy::LogMessageCrash() + +class LogMessageCrash : public LogMessage { + public: + LogMessageCrash() { } +#if _MSC_VER == 1700 || _MSC_VER >= 1800 +// Bogus warning from VS 2012 and VS 2013: +// warning C4722: 'snappy::LogMessageCrash::~LogMessageCrash' : destructor never returns, potential memory leak +#pragma warning(push) +#pragma warning(disable : 4722) +#endif + ~LogMessageCrash() { + fprintf( stderr, "\n" ); +// cerr << endl; + abort(); + } +}; +#if _MSC_VER == 1700 || _MSC_VER >= 1800 +#pragma warning(pop) +#endif + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". + +class LogMessageVoidify { + public: + LogMessageVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(const LogMessage&) { } +}; + +#define CHECK(cond) CRASH_UNLESS(cond) +#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b)) +#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b)) +#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b)) +#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b)) +#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b)) +#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b)) + +#ifdef NDEBUG + +#define DCHECK(cond) CRASH_UNLESS(true) +#define DCHECK_LE(a, b) CRASH_UNLESS(true) +#define DCHECK_GE(a, b) CRASH_UNLESS(true) +#define DCHECK_EQ(a, b) CRASH_UNLESS(true) +#define DCHECK_NE(a, b) CRASH_UNLESS(true) +#define DCHECK_LT(a, b) CRASH_UNLESS(true) +#define DCHECK_GT(a, b) CRASH_UNLESS(true) + +#else + +#define DCHECK(cond) CHECK(cond) +#define DCHECK_LE(a, b) CHECK_LE(a, b) +#define DCHECK_GE(a, b) CHECK_GE(a, b) +#define DCHECK_EQ(a, b) CHECK_EQ(a, b) +#define DCHECK_NE(a, b) CHECK_NE(a, b) +#define DCHECK_LT(a, b) CHECK_LT(a, b) +#define DCHECK_GT(a, b) CHECK_GT(a, b) + +#endif + +// Potentially unaligned loads and stores. + +#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) #define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) #define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) #define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) #define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) - -// TODO(user): NEON supports unaligned 64-bit loads and stores. -// See if that would be more efficient on platforms supporting it, -// at least for copies. - -inline uint64 UNALIGNED_LOAD64(const void *p) { - uint64 t; - memcpy(&t, p, sizeof t); - return t; -} - -inline void UNALIGNED_STORE64(void *p, uint64 v) { - memcpy(p, &v, sizeof v); -} +#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) #else @@ -190,31 +245,9 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) { #endif -// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64 -// on some platforms, in particular ARM. -inline void UnalignedCopy64(const void *src, void *dst) { - if (sizeof(void *) == 8) { - UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src)); - } else { - const char *src_char = reinterpret_cast(src); - char *dst_char = reinterpret_cast(dst); - - UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char)); - UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4)); - } -} - // The following guarantees declaration of the byte swap functions. #ifdef WORDS_BIGENDIAN -#ifdef HAVE_SYS_BYTEORDER_H -#include -#endif - -#ifdef HAVE_SYS_ENDIAN_H -#include -#endif - #ifdef _MSC_VER #include #define bswap_16(x) _byteswap_ushort(x) @@ -228,38 +261,8 @@ inline void UnalignedCopy64(const void *src, void *dst) { #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#elif defined(HAVE_BYTESWAP_H) -#include - -#elif defined(bswap32) -// FreeBSD defines bswap{16,32,64} in (already #included). -#define bswap_16(x) bswap16(x) -#define bswap_32(x) bswap32(x) -#define bswap_64(x) bswap64(x) - -#elif defined(BSWAP_64) -// Solaris 10 defines BSWAP_{16,32,64} in (already #included). -#define bswap_16(x) BSWAP_16(x) -#define bswap_32(x) BSWAP_32(x) -#define bswap_64(x) BSWAP_64(x) - #else - -inline uint16 bswap_16(uint16 x) { - return (x << 8) | (x >> 8); -} - -inline uint32 bswap_32(uint32 x) { - x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8); - return (x >> 16) | (x << 16); -} - -inline uint64 bswap_64(uint64 x) { - x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8); - x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16); - return (x >> 32) | (x << 32); -} - +#include #endif #endif // WORDS_BIGENDIAN @@ -329,7 +332,7 @@ class Bits { static int FindLSBSetNonZero64(uint64 n); private: - DISALLOW_COPY_AND_ASSIGN(Bits); + SNAPPY_DISALLOW_COPY_AND_ASSIGN(Bits); }; #ifdef HAVE_BUILTIN_CTZ diff --git a/tier1/snappy.cpp b/tier1/snappy.cpp index 72e26e01..009dec75 100644 --- a/tier1/snappy.cpp +++ b/tier1/snappy.cpp @@ -37,17 +37,8 @@ #include #ifdef _WIN32 - #pragma warning(disable:4018) // warning C4018: '<' : signed/unsigned mismatch #pragma warning(disable:4389) // warning C4389: '==' : signed/unsigned mismatch - -/* Define like size_t, omitting the "unsigned" */ -#ifdef _WIN64 -typedef __int64 ssize_t; -#else -typedef int ssize_t; -#endif - #endif //_WIN32 namespace snappy { @@ -95,7 +86,6 @@ enum { COPY_2_BYTE_OFFSET = 2, COPY_4_BYTE_OFFSET = 3 }; -static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset. // Copy "len" bytes from "src" to "op", one byte at a time. Used for // handling COPY operations where the input and output regions may @@ -108,8 +98,8 @@ static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual o // ababababababababababab // Note that this does not match the semantics of either memcpy() // or memmove(). -static inline void IncrementalCopy(const char* src, char* op, ssize_t len) { - assert(len > 0); +static inline void IncrementalCopy(const char* src, char* op, int len) { + DCHECK_GT(len, 0); do { *op++ = *src++; } while (--len > 0); @@ -150,22 +140,22 @@ namespace { const int kMaxIncrementCopyOverflow = 10; -inline void IncrementalCopyFastPath(const char* src, char* op, ssize_t len) { +} // namespace + +static inline void IncrementalCopyFastPath(const char* src, char* op, int len) { while (op - src < 8) { - UnalignedCopy64(src, op); + UNALIGNED_STORE64(op, UNALIGNED_LOAD64(src)); len -= op - src; op += op - src; } while (len > 0) { - UnalignedCopy64(src, op); + UNALIGNED_STORE64(op, UNALIGNED_LOAD64(src)); src += 8; op += 8; len -= 8; } } -} // namespace - static inline char* EmitLiteral(char* op, const char* literal, int len, @@ -186,8 +176,8 @@ static inline char* EmitLiteral(char* op, // - The output will always have 32 spare bytes (see // MaxCompressedLength). if (allow_fast_path && len <= 16) { - UnalignedCopy64(literal, op); - UnalignedCopy64(literal + 8, op + 8); + UNALIGNED_STORE64(op, UNALIGNED_LOAD64(literal)); + UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(literal + 8)); return op + len; } } else { @@ -208,25 +198,25 @@ static inline char* EmitLiteral(char* op, return op + len; } -static inline char* EmitCopyLessThan64(char* op, size_t offset, int len) { - assert(len <= 64); - assert(len >= 4); - assert(offset < 65536); +static inline char* EmitCopyLessThan64(char* op, int offset, int len) { + DCHECK_LE(len, 64); + DCHECK_GE(len, 4); + DCHECK_LT(offset, 65536); if ((len < 12) && (offset < 2048)) { - size_t len_minus_4 = len - 4; + int len_minus_4 = len - 4; assert(len_minus_4 < 8); // Must fit in 3 bits - *op++ = (char)(COPY_1_BYTE_OFFSET + ((len_minus_4) << 2) + ((offset >> 8) << 5)); + *op++ = COPY_1_BYTE_OFFSET | ((len_minus_4) << 2) | ((offset >> 8) << 5); *op++ = offset & 0xff; } else { - *op++ = COPY_2_BYTE_OFFSET + ((len-1) << 2); - LittleEndian::Store16(op, (snappy::uint16)offset); + *op++ = COPY_2_BYTE_OFFSET | ((len-1) << 2); + LittleEndian::Store16(op, offset); op += 2; } return op; } -static inline char* EmitCopy(char* op, size_t offset, int len) { +static inline char* EmitCopy(char* op, int offset, int len) { // Emit 64 byte copies but make sure to keep at least four bytes reserved while (len >= 68) { op = EmitCopyLessThan64(op, offset, 64); @@ -263,10 +253,12 @@ uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) { // compression, and if the input is short, we won't need that // many hash table entries anyway. assert(kMaxHashTableSize >= 256); - size_t htsize = 256; + int htsize = 256; while (htsize < kMaxHashTableSize && htsize < input_size) { htsize <<= 1; } + CHECK_EQ(0, htsize & (htsize - 1)) << ": must be power of two"; + CHECK_LE(htsize, kMaxHashTableSize) << ": hash table too large"; uint16* table; if (htsize <= ARRAYSIZE(small_table_)) { @@ -278,55 +270,22 @@ uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) { table = large_table_; } - *table_size = (int)htsize; + *table_size = htsize; memset(table, 0, htsize * sizeof(*table)); return table; } } // end namespace internal -// For 0 <= offset <= 4, GetUint32AtOffset(GetEightBytesAt(p), offset) will +// For 0 <= offset <= 4, GetUint32AtOffset(UNALIGNED_LOAD64(p), offset) will // equal UNALIGNED_LOAD32(p + offset). Motivation: On x86-64 hardware we have // empirically found that overlapping loads such as // UNALIGNED_LOAD32(p) ... UNALIGNED_LOAD32(p+1) ... UNALIGNED_LOAD32(p+2) // are slower than UNALIGNED_LOAD64(p) followed by shifts and casts to uint32. -// -// We have different versions for 64- and 32-bit; ideally we would avoid the -// two functions and just inline the UNALIGNED_LOAD64 call into -// GetUint32AtOffset, but GCC (at least not as of 4.6) is seemingly not clever -// enough to avoid loading the value multiple times then. For 64-bit, the load -// is done when GetEightBytesAt() is called, whereas for 32-bit, the load is -// done at GetUint32AtOffset() time. - -#ifdef ARCH_K8 - -typedef uint64 EightBytesReference; - -static inline EightBytesReference GetEightBytesAt(const char* ptr) { - return UNALIGNED_LOAD64(ptr); -} - static inline uint32 GetUint32AtOffset(uint64 v, int offset) { - assert(offset >= 0); - assert(offset <= 4); + DCHECK(0 <= offset && offset <= 4) << offset; return v >> (LittleEndian::IsLittleEndian() ? 8 * offset : 32 - 8 * offset); } -#else - -typedef const char* EightBytesReference; - -static inline EightBytesReference GetEightBytesAt(const char* ptr) { - return ptr; -} - -static inline uint32 GetUint32AtOffset(const char* v, int offset) { - assert(offset >= 0); - assert(offset <= 4); - return UNALIGNED_LOAD32(v + offset); -} - -#endif - // Flat array compression that does not emit the "uncompressed length" // prefix. Compresses "input" string to the "*op" buffer. // @@ -339,29 +298,29 @@ static inline uint32 GetUint32AtOffset(const char* v, int offset) { // Returns an "end" pointer into "op" buffer. // "end - op" is the compressed size of "input". namespace internal { -char* CompressFragment(const char* input, - size_t input_size, +char* CompressFragment(const char* const input, + const size_t input_size, char* op, uint16* table, const int table_size) { // "ip" is the input pointer, and "op" is the output pointer. const char* ip = input; - assert(input_size <= kBlockSize); - assert((table_size & (table_size - 1)) == 0); // table must be power of two + CHECK_LE(input_size, kBlockSize); + CHECK_EQ(table_size & (table_size - 1), 0) << ": table must be power of two"; const int shift = 32 - Bits::Log2Floor(table_size); - assert(static_cast(kuint32max >> shift) == table_size - 1); + DCHECK_EQ(kuint32max >> shift, table_size - 1); const char* ip_end = input + input_size; const char* base_ip = ip; // Bytes in [next_emit, ip) will be emitted as literal bytes. Or // [next_emit, ip_end) after the main loop. const char* next_emit = ip; - const size_t kInputMarginBytes = 15; + const int kInputMarginBytes = 15; if (PREDICT_TRUE(input_size >= kInputMarginBytes)) { const char* ip_limit = input + input_size - kInputMarginBytes; for (uint32 next_hash = Hash(++ip, shift); ; ) { - assert(next_emit < ip); + DCHECK_LT(next_emit, ip); // The body of this loop calls EmitLiteral once and then EmitCopy one or // more times. (The exception is that when we're close to exhausting // the input we goto emit_remainder.) @@ -394,7 +353,7 @@ char* CompressFragment(const char* input, do { ip = next_ip; uint32 hash = next_hash; - assert(hash == Hash(ip, shift)); + DCHECK_EQ(hash, Hash(ip, shift)); uint32 bytes_between_hash_lookups = skip++ >> 5; next_ip = ip + bytes_between_hash_lookups; if (PREDICT_FALSE(next_ip > ip_limit)) { @@ -402,8 +361,8 @@ char* CompressFragment(const char* input, } next_hash = Hash(next_ip, shift); candidate = base_ip + table[hash]; - assert(candidate >= base_ip); - assert(candidate < ip); + DCHECK_GE(candidate, base_ip); + DCHECK_LT(candidate, ip); table[hash] = ip - base_ip; } while (PREDICT_TRUE(UNALIGNED_LOAD32(ip) != @@ -412,7 +371,7 @@ char* CompressFragment(const char* input, // Step 2: A 4-byte match has been found. We'll later see if more // than 4 bytes match. But, prior to the match, input // bytes [next_emit, ip) are unmatched. Emit them as "literal bytes." - assert(next_emit + 16 <= ip_end); + DCHECK_LE(next_emit + 16, ip_end); op = EmitLiteral(op, next_emit, ip - next_emit, true); // Step 3: Call EmitCopy, and then see if another EmitCopy could @@ -423,7 +382,7 @@ char* CompressFragment(const char* input, // though we don't yet know how big the literal will be. We handle that // by proceeding to the next iteration of the main loop. We also can exit // this loop via goto if we get close to exhausting the input. - EightBytesReference input_bytes; + uint64 input_bytes = 0; uint32 candidate_bytes = 0; do { @@ -432,8 +391,8 @@ char* CompressFragment(const char* input, const char* base = ip; int matched = 4 + FindMatchLength(candidate + 4, ip + 4, ip_end); ip += matched; - size_t offset = base - candidate; - assert(0 == memcmp(base, candidate, matched)); + int offset = base - candidate; + DCHECK_EQ(0, memcmp(base, candidate, matched)); op = EmitCopy(op, offset, matched); // We could immediately start working at ip now, but to improve // compression we first update table[Hash(ip - 1, ...)]. @@ -442,7 +401,7 @@ char* CompressFragment(const char* input, if (PREDICT_FALSE(ip >= ip_limit)) { goto emit_remainder; } - input_bytes = GetEightBytesAt(insert_tail); + input_bytes = UNALIGNED_LOAD64(insert_tail); uint32 prev_hash = HashBytes(GetUint32AtOffset(input_bytes, 0), shift); table[prev_hash] = ip - base_ip - 1; uint32 cur_hash = HashBytes(GetUint32AtOffset(input_bytes, 1), shift); @@ -480,31 +439,12 @@ char* CompressFragment(const char* input, // bool CheckLength() const; // // // Called repeatedly during decompression -// bool Append(const char* ip, size_t length); -// bool AppendFromSelf(uint32 offset, size_t length); -// -// // The rules for how TryFastAppend differs from Append are somewhat -// // convoluted: -// // -// // - TryFastAppend is allowed to decline (return false) at any -// // time, for any reason -- just "return false" would be -// // a perfectly legal implementation of TryFastAppend. -// // The intention is for TryFastAppend to allow a fast path -// // in the common case of a small append. -// // - TryFastAppend is allowed to read up to bytes -// // from the input buffer, whereas Append is allowed to read -// // . However, if it returns true, it must leave -// // at least five (kMaximumTagLength) bytes in the input buffer -// // afterwards, so that there is always enough space to read the -// // next tag without checking for a refill. -// // - TryFastAppend must always return decline (return false) -// // if is 61 or more, as in this case the literal length is not -// // decoded fully. In practice, this should not be a big problem, -// // as it is unlikely that one would implement a fast path accepting -// // this much data. -// // -// bool TryFastAppend(const char* ip, size_t available, size_t length); +// bool Append(const char* ip, uint32 length, bool allow_fast_path); +// bool AppendFromSelf(uint32 offset, uint32 length); // }; +// +// "allow_fast_path" is a parameter that says if there is at least 16 +// readable bytes in "ip". It is currently only used by SnappyArrayWriter. // ----------------------------------------------------------------------- // Lookup table for decompression code. Generated by ComputeTable() below. @@ -571,9 +511,9 @@ static uint16 MakeEntry(unsigned int extra, unsigned int len, unsigned int copy_offset) { // Check that all of the fields fit within the allocated space - assert(extra == (extra & 0x7)); // At most 3 bits - assert(copy_offset == (copy_offset & 0x7)); // At most 3 bits - assert(len == (len & 0x7f)); // At most 7 bits + DCHECK_EQ(extra, extra & 0x7); // At most 3 bits + DCHECK_EQ(copy_offset, copy_offset & 0x7); // At most 3 bits + DCHECK_EQ(len, len & 0x7f); // At most 7 bits return len | (copy_offset << 8) | (extra << 11); } @@ -631,15 +571,9 @@ static void ComputeTable() { } // Check that each entry was initialized exactly once. - if (assigned != 256) { - fprintf(stderr, "ComputeTable: assigned only %d of 256\n", assigned); - abort(); - } + CHECK_EQ(assigned, 256); for (int i = 0; i < 256; i++) { - if (dst[i] == 0xffff) { - fprintf(stderr, "ComputeTable: did not assign byte %d\n", i); - abort(); - } + CHECK_NE(dst[i], 0xffff); } if (FLAGS_snappy_dump_decompression_table) { @@ -654,13 +588,10 @@ static void ComputeTable() { // Check that computed table matched recorded table for (int i = 0; i < 256; i++) { - if (dst[i] != char_table[i]) { - fprintf(stderr, "ComputeTable: byte %d: computed (%x), expect (%x)\n", - i, static_cast(dst[i]), static_cast(char_table[i])); - abort(); - } + CHECK_EQ(dst[i], char_table[i]); } } +REGISTER_MODULE_INITIALIZER(snappy, ComputeTable()); #endif /* !NDEBUG */ // Helper class for decompression @@ -671,7 +602,7 @@ class SnappyDecompressor { const char* ip_limit_; // Points just past buffered bytes uint32 peeked_; // Bytes peeked from reader (need to skip) bool eof_; // Hit end of input without an error? - char scratch_[kMaximumTagLength]; // See RefillTag(). + char scratch_[5]; // Temporary buffer for PeekFast() boundaries // Ensure that all of the tag metadata for the next tag is available // in [ip_..ip_limit_-1]. Also ensures that [ip,ip+4] is readable even @@ -703,7 +634,7 @@ class SnappyDecompressor { // On succcess, stores the length in *result and returns true. // On failure, returns false. bool ReadUncompressedLength(uint32* result) { - assert(ip_ == NULL); // Must not have read anything yet + DCHECK(ip_ == NULL); // Must not have read anything yet // Length is encoded in 1..5 bytes *result = 0; uint32 shift = 0; @@ -728,63 +659,40 @@ class SnappyDecompressor { template void DecompressAllTags(Writer* writer) { const char* ip = ip_; - - // We could have put this refill fragment only at the beginning of the loop. - // However, duplicating it at the end of each branch gives the compiler more - // scope to optimize the expression based on the local - // context, which overall increases speed. - #define MAYBE_REFILL() \ - if (ip_limit_ - ip < kMaximumTagLength) { \ - ip_ = ip; \ - if (!RefillTag()) return; \ - ip = ip_; \ - } - - MAYBE_REFILL(); for ( ;; ) { + if (ip_limit_ - ip < 5) { + ip_ = ip; + if (!RefillTag()) return; + ip = ip_; + } + const unsigned char c = *(reinterpret_cast(ip++)); + const uint32 entry = char_table[c]; + const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11]; + ip += entry >> 11; + const uint32 length = entry & 0xff; if ((c & 0x3) == LITERAL) { - size_t literal_length = (c >> 2) + 1u; - if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) { - assert(literal_length < 61); - ip += literal_length; - // NOTE(user): There is no MAYBE_REFILL() here, as TryFastAppend() - // will not return true unless there's already at least five spare - // bytes in addition to the literal. - continue; - } - if (PREDICT_FALSE(literal_length >= 61)) { - // Long literal. - const size_t literal_length_length = literal_length - 60; - literal_length = - (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1; - ip += literal_length_length; - } - - size_t avail = ip_limit_ - ip; + uint32 literal_length = length + trailer; + uint32 avail = ip_limit_ - ip; while (avail < literal_length) { - if (!writer->Append(ip, avail)) return; + bool allow_fast_path = (avail >= 16); + if (!writer->Append(ip, avail, allow_fast_path)) return; literal_length -= avail; reader_->Skip(peeked_); size_t n; ip = reader_->Peek(&n); - avail = n; - peeked_ = (snappy::uint32)avail; + avail = (uint32)n; + peeked_ = avail; if (avail == 0) return; // Premature end of input ip_limit_ = ip + avail; } - if (!writer->Append(ip, literal_length)) { + bool allow_fast_path = (avail >= 16); + if (!writer->Append(ip, literal_length, allow_fast_path)) { return; } ip += literal_length; - MAYBE_REFILL(); } else { - const uint32 entry = char_table[c]; - const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11]; - const uint32 length = entry & 0xff; - ip += entry >> 11; - // copy_offset/256 is encoded in bits 8..10. By just fetching // those bits, we get copy_offset (since the bit-field starts at // bit 8). @@ -792,11 +700,8 @@ class SnappyDecompressor { if (!writer->AppendFromSelf(copy_offset + trailer, length)) { return; } - MAYBE_REFILL(); } } - -#undef MAYBE_REFILL } }; @@ -807,7 +712,7 @@ bool SnappyDecompressor::RefillTag() { reader_->Skip(peeked_); // All peeked bytes are used up size_t n; ip = reader_->Peek(&n); - peeked_ = (snappy::uint32)n; + peeked_ = (uint32)n; if (n == 0) { eof_ = true; return false; @@ -816,11 +721,11 @@ bool SnappyDecompressor::RefillTag() { } // Read the tag character - assert(ip < ip_limit_); + DCHECK_LT(ip, ip_limit_); const unsigned char c = *(reinterpret_cast(ip)); const uint32 entry = char_table[c]; const uint32 needed = (entry >> 11) + 1; // +1 byte for 'c' - assert(needed <= sizeof(scratch_)); + DCHECK_LE(needed, sizeof(scratch_)); // Read more bytes from reader if needed uint32 nbuf = ip_limit_ - ip; @@ -836,15 +741,15 @@ bool SnappyDecompressor::RefillTag() { size_t length; const char* src = reader_->Peek(&length); if (length == 0) return false; - uint32 to_add = Min(needed - nbuf, (uint32)length); + uint32 to_add = min(needed - nbuf, (uint32)length); memcpy(scratch_ + nbuf, src, to_add); nbuf += to_add; reader_->Skip(to_add); } - assert(nbuf == needed); + DCHECK_EQ(nbuf, needed); ip_ = scratch_; ip_limit_ = scratch_ + needed; - } else if (nbuf < kMaximumTagLength) { + } else if (nbuf < 5) { // Have enough bytes, but move into scratch_ so that we do not // read past end of input memmove(scratch_, ip, nbuf); @@ -860,23 +765,23 @@ bool SnappyDecompressor::RefillTag() { } template -static bool InternalUncompress(Source* r, Writer* writer) { +static bool InternalUncompress(Source* r, + Writer* writer, + uint32 max_len) { // Read the uncompressed length from the front of the compressed input SnappyDecompressor decompressor(r); uint32 uncompressed_len = 0; if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false; - return InternalUncompressAllTags(&decompressor, writer, uncompressed_len); -} + // Protect against possible DoS attack + if (static_cast(uncompressed_len) > max_len) { + return false; + } -template -static bool InternalUncompressAllTags(SnappyDecompressor* decompressor, - Writer* writer, - uint32 uncompressed_len) { writer->SetExpectedLength(uncompressed_len); // Process the entire input - decompressor->DecompressAllTags(writer); - return (decompressor->eof() && writer->CheckLength()); + decompressor.DecompressAllTags(writer); + return (decompressor.eof() && writer->CheckLength()); } bool GetUncompressedLength(Source* source, uint32* result) { @@ -886,9 +791,9 @@ bool GetUncompressedLength(Source* source, uint32* result) { size_t Compress(Source* reader, Sink* writer) { size_t written = 0; - size_t N = reader->Available(); + int N = (int)reader->Available(); char ulength[Varint::kMax32]; - char* p = Varint::Encode32(ulength, (snappy::uint32)N); + char* p = Varint::Encode32(ulength, N); writer->Append(ulength, p-ulength); written += (p - ulength); @@ -900,11 +805,11 @@ size_t Compress(Source* reader, Sink* writer) { // Get next block to compress (without copying if possible) size_t fragment_size; const char* fragment = reader->Peek(&fragment_size); - assert(fragment_size != 0); // premature end of input - const size_t num_to_read = min(N, kBlockSize); + DCHECK_NE(fragment_size, 0) << ": premature end of input"; + const int num_to_read = MIN(N, kBlockSize); size_t bytes_read = fragment_size; - size_t pending_advance = 0; + int pending_advance = 0; if (bytes_read >= num_to_read) { // Buffer returned by reader is large enough pending_advance = num_to_read; @@ -922,23 +827,23 @@ size_t Compress(Source* reader, Sink* writer) { while (bytes_read < num_to_read) { fragment = reader->Peek(&fragment_size); - size_t n = Min(fragment_size, num_to_read - bytes_read); + size_t n = min(fragment_size, num_to_read - bytes_read); memcpy(scratch + bytes_read, fragment, n); bytes_read += n; reader->Skip(n); } - assert(bytes_read == num_to_read); + DCHECK_EQ(bytes_read, num_to_read); fragment = scratch; fragment_size = num_to_read; } - assert(fragment_size == num_to_read); + DCHECK_EQ(fragment_size, num_to_read); // Get encoding table for compression int table_size; uint16* table = wmem.GetHashTable(num_to_read, &table_size); // Compress input_fragment and append to dest - const int max_output = (int)MaxCompressedLength(num_to_read); + const size_t max_output = MaxCompressedLength(num_to_read); // Need a scratch buffer for the output, in case the byte sink doesn't // have room for us directly. @@ -965,183 +870,6 @@ size_t Compress(Source* reader, Sink* writer) { return written; } -// ----------------------------------------------------------------------- -// IOVec interfaces -// ----------------------------------------------------------------------- - -// A type that writes to an iovec. -// Note that this is not a "ByteSink", but a type that matches the -// Writer template argument to SnappyDecompressor::DecompressAllTags(). -class SnappyIOVecWriter { - private: - const struct iovec* output_iov_; - const size_t output_iov_count_; - - // We are currently writing into output_iov_[curr_iov_index_]. - int curr_iov_index_; - - // Bytes written to output_iov_[curr_iov_index_] so far. - size_t curr_iov_written_; - - // Total bytes decompressed into output_iov_ so far. - size_t total_written_; - - // Maximum number of bytes that will be decompressed into output_iov_. - size_t output_limit_; - - inline char* GetIOVecPointer(int index, size_t offset) { - return reinterpret_cast(output_iov_[index].iov_base) + - offset; - } - - public: - // Does not take ownership of iov. iov must be valid during the - // entire lifetime of the SnappyIOVecWriter. - inline SnappyIOVecWriter(const struct iovec* iov, size_t iov_count) - : output_iov_(iov), - output_iov_count_(iov_count), - curr_iov_index_(0), - curr_iov_written_(0), - total_written_(0), - output_limit_((size_t)-1) { - } - - inline void SetExpectedLength(size_t len) { - output_limit_ = len; - } - - inline bool CheckLength() const { - return total_written_ == output_limit_; - } - - inline bool Append(const char* ip, size_t len) { - if (total_written_ + len > output_limit_) { - return false; - } - - while (len > 0) { - assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); - if (curr_iov_written_ >= output_iov_[curr_iov_index_].iov_len) { - // This iovec is full. Go to the next one. - if (curr_iov_index_ + 1 >= output_iov_count_) { - return false; - } - curr_iov_written_ = 0; - ++curr_iov_index_; - } - - const size_t to_write = Min( - len, output_iov_[curr_iov_index_].iov_len - curr_iov_written_); - memcpy(GetIOVecPointer(curr_iov_index_, curr_iov_written_), - ip, - to_write); - curr_iov_written_ += to_write; - total_written_ += to_write; - ip += to_write; - len -= to_write; - } - - return true; - } - - inline bool TryFastAppend(const char* ip, size_t available, size_t len) { - const size_t space_left = output_limit_ - total_written_; - if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16 && - output_iov_[curr_iov_index_].iov_len - curr_iov_written_ >= 16) { - // Fast path, used for the majority (about 95%) of invocations. - char* ptr = GetIOVecPointer(curr_iov_index_, curr_iov_written_); - UnalignedCopy64(ip, ptr); - UnalignedCopy64(ip + 8, ptr + 8); - curr_iov_written_ += len; - total_written_ += len; - return true; - } - - return false; - } - - inline bool AppendFromSelf(size_t offset, size_t len) { - if (offset > total_written_ || offset == 0) { - return false; - } - const size_t space_left = output_limit_ - total_written_; - if (len > space_left) { - return false; - } - - // Locate the iovec from which we need to start the copy. - int from_iov_index = curr_iov_index_; - size_t from_iov_offset = curr_iov_written_; - while (offset > 0) { - if (from_iov_offset >= offset) { - from_iov_offset -= offset; - break; - } - - offset -= from_iov_offset; - --from_iov_index; - assert(from_iov_index >= 0); - from_iov_offset = output_iov_[from_iov_index].iov_len; - } - - // Copy bytes starting from the iovec pointed to by from_iov_index to - // the current iovec. - while (len > 0) { - assert(from_iov_index <= curr_iov_index_); - if (from_iov_index != curr_iov_index_) { - const size_t to_copy = Min( - output_iov_[from_iov_index].iov_len - from_iov_offset, - len); - Append(GetIOVecPointer(from_iov_index, from_iov_offset), to_copy); - len -= to_copy; - if (len > 0) { - ++from_iov_index; - from_iov_offset = 0; - } - } else { - assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); - size_t to_copy = Min(output_iov_[curr_iov_index_].iov_len - - curr_iov_written_, - len); - if (to_copy == 0) { - // This iovec is full. Go to the next one. - if (curr_iov_index_ + 1 >= output_iov_count_) { - return false; - } - ++curr_iov_index_; - curr_iov_written_ = 0; - continue; - } - if (to_copy > len) { - to_copy = len; - } - IncrementalCopy(GetIOVecPointer(from_iov_index, from_iov_offset), - GetIOVecPointer(curr_iov_index_, curr_iov_written_), - to_copy); - curr_iov_written_ += to_copy; - from_iov_offset += to_copy; - total_written_ += to_copy; - len -= to_copy; - } - } - - return true; - } - -}; - -bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, - const struct iovec* iov, size_t iov_cnt) { - ByteArraySource reader(compressed, compressed_length); - return RawUncompressToIOVec(&reader, iov, iov_cnt); -} - -bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, - size_t iov_cnt) { - SnappyIOVecWriter output(iov, iov_cnt); - return InternalUncompress(compressed, &output); -} - // ----------------------------------------------------------------------- // Flat array interfaces // ----------------------------------------------------------------------- @@ -1169,51 +897,34 @@ class SnappyArrayWriter { return op_ == op_limit_; } - inline bool Append(const char* ip, size_t len) { + inline bool Append(const char* ip, uint32 len, bool allow_fast_path) { char* op = op_; - const size_t space_left = op_limit_ - op; - if (space_left < len) { - return false; + const int space_left = op_limit_ - op; + if (allow_fast_path && len <= 16 && space_left >= 16) { + // Fast path, used for the majority (about 90%) of dynamic invocations. + UNALIGNED_STORE64(op, UNALIGNED_LOAD64(ip)); + UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(ip + 8)); + } else { + if (space_left < len) { + return false; + } + memcpy(op, ip, len); } - memcpy(op, ip, len); op_ = op + len; return true; } - inline bool TryFastAppend(const char* ip, size_t available, size_t len) { + inline bool AppendFromSelf(uint32 offset, uint32 len) { char* op = op_; - const size_t space_left = op_limit_ - op; - if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16) { - // Fast path, used for the majority (about 95%) of invocations. - UnalignedCopy64(ip, op); - UnalignedCopy64(ip + 8, op + 8); - op_ = op + len; - return true; - } else { - return false; - } - } + const int space_left = op_limit_ - op; - inline bool AppendFromSelf(size_t offset, size_t len) { - char* op = op_; - const size_t space_left = op_limit_ - op; - - // Check if we try to append from before the start of the buffer. - // Normally this would just be a check for "produced < offset", - // but "produced <= offset - 1u" is equivalent for every case - // except the one where offset==0, where the right side will wrap around - // to a very big number. This is convenient, as offset==0 is another - // invalid case that we also want to catch, so that we do not go - // into an infinite loop. - assert(op >= base_); - size_t produced = op - base_; - if (produced <= offset - 1u) { + if (op - base_ <= offset - 1u) { // -1u catches offset==0 return false; } if (len <= 16 && offset >= 8 && space_left >= 16) { // Fast path, used for the majority (70-80%) of dynamic invocations. - UnalignedCopy64(op - offset, op); - UnalignedCopy64(op - offset + 8, op + 8); + UNALIGNED_STORE64(op, UNALIGNED_LOAD64(op - offset)); + UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(op - offset + 8)); } else { if (space_left >= len + kMaxIncrementCopyOverflow) { IncrementalCopyFastPath(op - offset, op, len); @@ -1237,7 +948,7 @@ bool RawUncompress(const char* compressed, size_t n, char* uncompressed) { bool RawUncompress(Source* compressed, char* uncompressed) { SnappyArrayWriter output(uncompressed); - return InternalUncompress(compressed, &output); + return InternalUncompress(compressed, &output, kuint32max); } bool Uncompress(const char* compressed, size_t n, string* uncompressed) { @@ -1245,9 +956,9 @@ bool Uncompress(const char* compressed, size_t n, string* uncompressed) { if (!GetUncompressedLength(compressed, n, &ulength)) { return false; } - // On 32-bit builds: max_size() < kuint32max. Check for that instead - // of crashing (e.g., consider externally specified compressed data). - if (ulength > uncompressed->max_size()) { + // Protect against possible DoS attack + if ((static_cast(ulength) + uncompressed->size()) > + uncompressed->max_size()) { return false; } STLStringResizeUninitialized(uncompressed, ulength); @@ -1269,17 +980,12 @@ class SnappyDecompressionValidator { inline bool CheckLength() const { return expected_ == produced_; } - inline bool Append(const char* ip, size_t len) { + inline bool Append(const char* ip, uint32 len, bool allow_fast_path) { produced_ += len; return produced_ <= expected_; } - inline bool TryFastAppend(const char* ip, size_t available, size_t length) { - return false; - } - inline bool AppendFromSelf(size_t offset, size_t len) { - // See SnappyArrayWriter::AppendFromSelf for an explanation of - // the "offset - 1u" trick. - if (produced_ <= offset - 1u) return false; + inline bool AppendFromSelf(uint32 offset, uint32 len) { + if (produced_ <= offset - 1u) return false; // -1u catches offset==0 produced_ += len; return produced_ <= expected_; } @@ -1288,7 +994,7 @@ class SnappyDecompressionValidator { bool IsValidCompressedBuffer(const char* compressed, size_t n) { ByteArraySource reader(compressed, n); SnappyDecompressionValidator writer; - return InternalUncompress(&reader, &writer); + return InternalUncompress(&reader, &writer, kuint32max); } void RawCompress(const char* input, diff --git a/tier1/splitstring.cpp b/tier1/splitstring.cpp index 448f6d03..461aa61d 100644 --- a/tier1/splitstring.cpp +++ b/tier1/splitstring.cpp @@ -70,8 +70,7 @@ void CSplitString::Construct( const char *pString, const char **pSeparators, int else { // Copy the rest of the string - int nTokenLength = strlen( pCurPos ); - if ( nTokenLength ) + if ( int nTokenLength = strlen( pCurPos ) ) { ////////////////////////////////////////////////////////////////////////// // There's no need to cut this token, because there's no separator after it. diff --git a/tier1/strtools.cpp b/tier1/strtools.cpp index 2c5f72fa..7d3b4b6d 100644 --- a/tier1/strtools.cpp +++ b/tier1/strtools.cpp @@ -928,7 +928,7 @@ char *V_strncat(char *pDest, const char *pSrc, size_t destBufferSize, int max_ch } else { - charstocopy = (size_t)min( max_chars_to_copy, (int)srclen ); + charstocopy = (size_t)MIN( max_chars_to_copy, (int)srclen ); } if ( len + charstocopy >= destBufferSize ) @@ -960,7 +960,7 @@ wchar_t *V_wcsncat( INOUT_Z_CAP(cchDest) wchar_t *pDest, const wchar_t *pSrc, si } else { - charstocopy = (size_t)min( max_chars_to_copy, (int)srclen ); + charstocopy = (size_t)MIN( max_chars_to_copy, (int)srclen ); } if ( len + charstocopy >= cchDest ) @@ -1020,7 +1020,7 @@ char *V_pretifymem( float value, int digitsafterdecimal /*= 2*/, bool usebinaryo char val[ 32 ]; // Clamp to >= 0 - digitsafterdecimal = max( digitsafterdecimal, 0 ); + digitsafterdecimal = MAX( digitsafterdecimal, 0 ); // If it's basically integral, don't do any decimals if ( FloatMakePositive( value - (int)value ) < 0.00001 ) @@ -1190,7 +1190,6 @@ bool Q_IsMeanSpaceW( wchar_t wch ) case L'\x200B': // ZERO-WIDTH SPACE case L'\x200C': // ZERO-WIDTH NON-JOINER case L'\x200D': // ZERO WIDTH JOINER - case L'\x200E': // LEFT-TO-RIGHT MARK case L'\x2028': // LINE SEPARATOR case L'\x2029': // PARAGRAPH SEPARATOR case L'\x202F': // NARROW NO-BREAK SPACE @@ -1241,61 +1240,14 @@ static wchar_t *StripWhitespaceWorker( int cchLength, wchar_t *pwch, bool *pbStr return pwch; } -//----------------------------------------------------------------------------- -// Purpose: Strips all evil characters (ie. zero-width no-break space) -// from a string. -//----------------------------------------------------------------------------- -bool Q_RemoveAllEvilCharacters( char *pch ) -{ - // convert to unicode - int cch = Q_strlen( pch ); - int cubDest = (cch + 1 ) * sizeof( wchar_t ); - wchar_t *pwch = (wchar_t *)stackalloc( cubDest ); - int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t ); - - bool bStrippedWhitespace = false; - - // Walk through and skip over evil characters - int nWalk = 0; - for( int i=0; i 0 ) + { + AssertValidWritePtr(pwchDest); + pwchDest[0] = 0; + } + + if ( !pUTF8 ) + return 0; + + AssertValidStringPtr(pUTF8); + +#ifdef _WIN32 + int cchResult = MultiByteToWideChar( CP_UTF8, 0, pUTF8, -1, pwchDest, cubDestSizeInBytes / sizeof(wchar_t) ); +#elif POSIX + int cchResult = mbstowcs( pwchDest, pUTF8, cubDestSizeInBytes / sizeof(wchar_t) ) + 1; +#endif + + if ( cubDestSizeInBytes > 0 ) + { + pwchDest[(cubDestSizeInBytes / sizeof(wchar_t)) - 1] = 0; + } + + return cchResult; +} + +//----------------------------------------------------------------------------- +// Purpose: Converts a unicode string into a UTF8 (standard) string +//----------------------------------------------------------------------------- +int V_UnicodeToUTF8( const wchar_t *pUnicode, char *pUTF8, int cubDestSizeInBytes ) +{ + //AssertValidStringPtr(pUTF8, cubDestSizeInBytes); // no, we are sometimes pasing in NULL to fetch the length of the buffer needed. + AssertValidReadPtr(pUnicode); + + if ( cubDestSizeInBytes > 0 ) + { + pUTF8[0] = 0; + } + +#ifdef _WIN32 + int cchResult = WideCharToMultiByte( CP_UTF8, 0, pUnicode, -1, pUTF8, cubDestSizeInBytes, NULL, NULL ); +#elif POSIX + int cchResult = 0; + if ( pUnicode && pUTF8 ) + cchResult = wcstombs( pUTF8, pUnicode, cubDestSizeInBytes ) + 1; +#endif + + if ( cubDestSizeInBytes > 0 ) + { + pUTF8[cubDestSizeInBytes - 1] = 0; + } + + return cchResult; +} + + //----------------------------------------------------------------------------- // Purpose: Converts a ucs2 string to a unicode (wchar_t) one, no-op on win32 //----------------------------------------------------------------------------- -int _V_UCS2ToUnicode( const ucs2 *pUCS2, wchar_t *pUnicode, int cubDestSizeInBytes ) +int V_UCS2ToUnicode( const ucs2 *pUCS2, wchar_t *pUnicode, int cubDestSizeInBytes ) { Assert( cubDestSizeInBytes >= sizeof( *pUnicode ) ); AssertValidWritePtr(pUnicode); @@ -1403,7 +1412,7 @@ int _V_UCS2ToUnicode( const ucs2 *pUCS2, wchar_t *pUnicode, int cubDestSizeInByt pUnicode[0] = 0; #ifdef _WIN32 int cchResult = V_wcslen( pUCS2 ); - V_memcpy( pUnicode, pUCS2, cubDestSizeInBytes ); + Q_memcpy( pUnicode, pUCS2, cubDestSizeInBytes ); #else iconv_t conv_t = iconv_open( "UCS-4LE", "UCS-2LE" ); int cchResult = -1; @@ -1411,8 +1420,9 @@ int _V_UCS2ToUnicode( const ucs2 *pUCS2, wchar_t *pUnicode, int cubDestSizeInByt size_t nMaxUTF8 = cubDestSizeInBytes; char *pIn = (char *)pUCS2; char *pOut = (char *)pUnicode; - if ( conv_t > 0 ) + if ( uintptr_t( conv_t ) > 0 ) { + cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1434,12 +1444,12 @@ int _V_UCS2ToUnicode( const ucs2 *pUCS2, wchar_t *pUnicode, int cubDestSizeInByt //----------------------------------------------------------------------------- // Purpose: Converts a wchar_t string into a UCS2 string -noop on windows //----------------------------------------------------------------------------- -int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, int cubDestSizeInBytes ) +int V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, int cubDestSizeInBytes ) { #ifdef _WIN32 // Figure out which buffer is smaller and convert from bytes to character // counts. - int cchResult = min( (size_t)cubSrcInBytes/sizeof(wchar_t), cubDestSizeInBytes/sizeof(wchar_t) ); + int cchResult = MIN( (size_t)cubSrcInBytes/sizeof(wchar_t), cubDestSizeInBytes/sizeof(wchar_t) ); wchar_t *pDest = (wchar_t*)pUCS2; wcsncpy( pDest, pUnicode, cchResult ); // Make sure we NULL-terminate. @@ -1451,8 +1461,9 @@ int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, i size_t nMaxUCS2 = cubDestSizeInBytes; char *pIn = (char*)pUnicode; char *pOut = pUCS2; - if ( conv_t > 0 ) + if ( uintptr_t( conv_t ) > 0 ) { + cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUCS2 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1460,8 +1471,6 @@ int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, i else cchResult = cubSrcInBytes / sizeof( wchar_t ); } -#else - #error Must be implemented for this platform #endif return cchResult; } @@ -1470,7 +1479,7 @@ int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, char *pUCS2, i //----------------------------------------------------------------------------- // Purpose: Converts a ucs-2 (windows wchar_t) string into a UTF8 (standard) string //----------------------------------------------------------------------------- -int _V_UCS2ToUTF8( const ucs2 *pUCS2, char *pUTF8, int cubDestSizeInBytes ) +int V_UCS2ToUTF8( const ucs2 *pUCS2, char *pUTF8, int cubDestSizeInBytes ) { AssertValidStringPtr(pUTF8, cubDestSizeInBytes); AssertValidReadPtr(pUCS2); @@ -1499,8 +1508,9 @@ int _V_UCS2ToUTF8( const ucs2 *pUCS2, char *pUTF8, int cubDestSizeInBytes ) size_t nMaxUTF8 = cubDestSizeInBytes - 1; char *pIn = (char *)pUCS2; char *pOut = (char *)pUTF8; - if ( conv_t > 0 ) + if ( uintptr_t( conv_t ) > 0 ) { + cchResult = 0; const size_t nBytesToWrite = nMaxUTF8; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); @@ -1524,7 +1534,7 @@ int _V_UCS2ToUTF8( const ucs2 *pUCS2, char *pUTF8, int cubDestSizeInBytes ) //----------------------------------------------------------------------------- // Purpose: Converts a UTF8 to ucs-2 (windows wchar_t) //----------------------------------------------------------------------------- -int _V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, ucs2 *pUCS2, int cubDestSizeInBytes ) +int V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, ucs2 *pUCS2, int cubDestSizeInBytes ) { Assert( cubDestSizeInBytes >= sizeof(pUCS2[0]) ); AssertValidStringPtr(pUTF8, cubDestSizeInBytes); @@ -1544,8 +1554,9 @@ int _V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, ucs2 *pUCS2, int cubDes size_t nMaxUTF8 = cubDestSizeInBytes; char *pIn = (char *)pUTF8; char *pOut = (char *)pUCS2; - if ( conv_t > 0 ) + if ( uintptr_t( conv_t ) > 0 ) { + cchResult = 0; cchResult = iconv( conv_t, &pIn, &nLenUnicde, &pOut, &nMaxUTF8 ); iconv_close( conv_t ); if ( (int)cchResult < 0 ) @@ -1599,7 +1610,7 @@ unsigned char V_nibble( char c ) void V_hextobinary( char const *in, int numchars, byte *out, int maxoutputbytes ) { int len = V_strlen( in ); - numchars = min( len, numchars ); + numchars = MIN( len, numchars ); // Make sure it's even numchars = ( numchars ) & ~0x1; @@ -1710,7 +1721,7 @@ void V_FileBase( const char *in, char *out, int maxlen ) // Length of new sting len = end - start + 1; - int maxcopy = min( len + 1, maxlen ); + int maxcopy = MIN( len + 1, maxlen ); // Copy partial string V_strncpy( out, &in[start], maxcopy ); @@ -1754,7 +1765,7 @@ void V_StripExtension( const char *in, char *out, int outSize ) if (end > 0 && !PATHSEPARATOR( in[end] ) && end < outSize) { - int nChars = min( end, outSize-1 ); + int nChars = MIN( end, outSize-1 ); if ( out != in ) { memcpy( out, in, nChars ); @@ -2001,7 +2012,7 @@ bool V_ExtractFilePath (const char *path, char *dest, int destSize ) src--; } - int copysize = min( src - path, destSize - 1 ); + int copysize = MIN( src - path, destSize - 1 ); memcpy( dest, path, copysize ); dest[copysize] = 0; @@ -2392,7 +2403,7 @@ char* AllocString( const char *pStr, int nMaxChars ) if ( nMaxChars == -1 ) allocLen = strlen( pStr ) + 1; else - allocLen = min( (int)strlen(pStr), nMaxChars ) + 1; + allocLen = MIN( (int)strlen(pStr), nMaxChars ) + 1; char *pOut = new char[allocLen]; V_strncpy( pOut, pStr, allocLen ); diff --git a/tier1/strtools_unicode.cpp b/tier1/strtools_unicode.cpp deleted file mode 100644 index 77685ec3..00000000 --- a/tier1/strtools_unicode.cpp +++ /dev/null @@ -1,572 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#include -#include "tier0/dbg.h" -#include "tier1/strtools.h" - -// This code was copied from steam -#define DbgAssert Assert - -//----------------------------------------------------------------------------- -// Purpose: determine if a uchar32 represents a valid Unicode code point -//----------------------------------------------------------------------------- -bool Q_IsValidUChar32( uchar32 uVal ) -{ - // Values > 0x10FFFF are explicitly invalid; ditto for UTF-16 surrogate halves, - // values ending in FFFE or FFFF, or values in the 0x00FDD0-0x00FDEF reserved range - return ( uVal < 0x110000u ) && ( (uVal - 0x00D800u) > 0x7FFu ) && ( (uVal & 0xFFFFu) < 0xFFFEu ) && ( ( uVal - 0x00FDD0u ) > 0x1Fu ); -} - -//----------------------------------------------------------------------------- -// Purpose: return number of UTF-8 bytes required to encode a Unicode code point -//----------------------------------------------------------------------------- -int Q_UChar32ToUTF8Len( uchar32 uVal ) -{ - DbgAssert( Q_IsValidUChar32( uVal ) ); - if ( uVal <= 0x7F ) - return 1; - if ( uVal <= 0x7FF ) - return 2; - if ( uVal <= 0xFFFF ) - return 3; - return 4; -} - - -//----------------------------------------------------------------------------- -// Purpose: return number of UTF-16 elements required to encode a Unicode code point -//----------------------------------------------------------------------------- -int Q_UChar32ToUTF16Len( uchar32 uVal ) -{ - DbgAssert( Q_IsValidUChar32( uVal ) ); - if ( uVal <= 0xFFFF ) - return 1; - return 2; -} - - -//----------------------------------------------------------------------------- -// Purpose: encode Unicode code point as UTF-8, returns number of bytes written -//----------------------------------------------------------------------------- -int Q_UChar32ToUTF8( uchar32 uVal, char *pUTF8Out ) -{ - DbgAssert( Q_IsValidUChar32( uVal ) ); - if ( uVal <= 0x7F ) - { - pUTF8Out[0] = (unsigned char) uVal; - return 1; - } - if ( uVal <= 0x7FF ) - { - pUTF8Out[0] = (unsigned char)(uVal >> 6) | 0xC0; - pUTF8Out[1] = (unsigned char)(uVal & 0x3F) | 0x80; - return 2; - } - if ( uVal <= 0xFFFF ) - { - pUTF8Out[0] = (unsigned char)(uVal >> 12) | 0xE0; - pUTF8Out[1] = (unsigned char)((uVal >> 6) & 0x3F) | 0x80; - pUTF8Out[2] = (unsigned char)(uVal & 0x3F) | 0x80; - return 3; - } - pUTF8Out[0] = (unsigned char)((uVal >> 18) & 0x07) | 0xF0; - pUTF8Out[1] = (unsigned char)((uVal >> 12) & 0x3F) | 0x80; - pUTF8Out[2] = (unsigned char)((uVal >> 6) & 0x3F) | 0x80; - pUTF8Out[3] = (unsigned char)(uVal & 0x3F) | 0x80; - return 4; -} - -//----------------------------------------------------------------------------- -// Purpose: encode Unicode code point as UTF-16, returns number of elements written -//----------------------------------------------------------------------------- -int Q_UChar32ToUTF16( uchar32 uVal, uchar16 *pUTF16Out ) -{ - DbgAssert( Q_IsValidUChar32( uVal ) ); - if ( uVal <= 0xFFFF ) - { - pUTF16Out[0] = (uchar16) uVal; - return 1; - } - uVal -= 0x010000; - pUTF16Out[0] = (uchar16)(uVal >> 10) | 0xD800; - pUTF16Out[1] = (uchar16)(uVal & 0x3FF) | 0xDC00; - return 2; -} - - -// Decode one character from a UTF-8 encoded string. Treats 6-byte CESU-8 sequences -// as a single character, as if they were a correctly-encoded 4-byte UTF-8 sequence. -int Q_UTF8ToUChar32( const char *pUTF8_, uchar32 &uValueOut, bool &bErrorOut ) -{ - const uint8 *pUTF8 = (const uint8 *)pUTF8_; - - int nBytes = 1; - uint32 uValue = pUTF8[0]; - uint32 uMinValue = 0; - - // 0....... single byte - if ( uValue < 0x80 ) - goto decodeFinishedNoCheck; - - // Expecting at least a two-byte sequence with 0xC0 <= first <= 0xF7 (110...... and 11110...) - if ( (uValue - 0xC0u) > 0x37u || ( pUTF8[1] & 0xC0 ) != 0x80 ) - goto decodeError; - - uValue = (uValue << 6) - (0xC0 << 6) + pUTF8[1] - 0x80; - nBytes = 2; - uMinValue = 0x80; - - // 110..... two-byte lead byte - if ( !( uValue & (0x20 << 6) ) ) - goto decodeFinished; - - // Expecting at least a three-byte sequence - if ( ( pUTF8[2] & 0xC0 ) != 0x80 ) - goto decodeError; - - uValue = (uValue << 6) - (0x20 << 12) + pUTF8[2] - 0x80; - nBytes = 3; - uMinValue = 0x800; - - // 1110.... three-byte lead byte - if ( !( uValue & (0x10 << 12) ) ) - goto decodeFinishedMaybeCESU8; - - // Expecting a four-byte sequence, longest permissible in UTF-8 - if ( ( pUTF8[3] & 0xC0 ) != 0x80 ) - goto decodeError; - - uValue = (uValue << 6) - (0x10 << 18) + pUTF8[3] - 0x80; - nBytes = 4; - uMinValue = 0x10000; - - // 11110... four-byte lead byte. fall through to finished. - -decodeFinished: - if ( uValue >= uMinValue && Q_IsValidUChar32( uValue ) ) - { -decodeFinishedNoCheck: - uValueOut = uValue; - bErrorOut = false; - return nBytes; - } -decodeError: - uValueOut = '?'; - bErrorOut = true; - return nBytes; - -decodeFinishedMaybeCESU8: - // Do we have a full UTF-16 surrogate pair that's been UTF-8 encoded afterwards? - // That is, do we have 0xD800-0xDBFF followed by 0xDC00-0xDFFF? If so, decode it all. - if ( ( uValue - 0xD800u ) < 0x400u && pUTF8[3] == 0xED && (uint8)( pUTF8[4] - 0xB0 ) < 0x10 && ( pUTF8[5] & 0xC0 ) == 0x80 ) - { - uValue = 0x10000 + ( ( uValue - 0xD800u ) << 10 ) + ( (uint8)( pUTF8[4] - 0xB0 ) << 6 ) + pUTF8[5] - 0x80; - nBytes = 6; - uMinValue = 0x10000; - } - goto decodeFinished; -} - -// Decode one character from a UTF-16 encoded string. -int Q_UTF16ToUChar32( const uchar16 *pUTF16, uchar32 &uValueOut, bool &bErrorOut ) -{ - if ( Q_IsValidUChar32( pUTF16[0] ) ) - { - uValueOut = pUTF16[0]; - bErrorOut = false; - return 1; - } - else if ( (pUTF16[0] - 0xD800u) < 0x400u && (pUTF16[1] - 0xDC00u) < 0x400u ) - { - // Valid surrogate pair, but maybe not encoding a valid Unicode code point... - uchar32 uVal = 0x010000 + ((pUTF16[0] - 0xD800u) << 10) + (pUTF16[1] - 0xDC00); - if ( Q_IsValidUChar32( uVal ) ) - { - uValueOut = uVal; - bErrorOut = false; - return 2; - } - else - { - uValueOut = '?'; - bErrorOut = true; - return 2; - } - } - else - { - uValueOut = '?'; - bErrorOut = true; - return 1; - } -} - -namespace // internal use only -{ - // Identity transformations and validity tests for use with Q_UnicodeConvertT - int Q_UTF32ToUChar32( const uchar32 *pUTF32, uchar32 &uVal, bool &bErr ) - { - bErr = !Q_IsValidUChar32( *pUTF32 ); - uVal = bErr ? '?' : *pUTF32; - return 1; - } - - int Q_UChar32ToUTF32Len( uchar32 uVal ) - { - return 1; - } - - int Q_UChar32ToUTF32( uchar32 uVal, uchar32 *pUTF32 ) - { - *pUTF32 = uVal; - return 1; - } - - // A generic Unicode processing loop: decode one character from input to uchar32, handle errors, encode uchar32 to output - template < typename SrcType, typename DstType, bool bStopAtNull, int (&DecodeSrc)( const SrcType*, uchar32&, bool& ), int (&EncodeDstLen)( uchar32 ), int (&EncodeDst)( uchar32, DstType* ) > - int Q_UnicodeConvertT( const SrcType *pIn, int nInChars, DstType *pOut, int nOutBytes, EStringConvertErrorPolicy ePolicy ) - { - if ( !pIn ) - { - // For now, assert and return 0. Once these are cleaned out a bit - // we should remove this return and just leave in the assert... - AssertMsg( pIn, "We shouldn't be passing in NULL!" ); - return 0; - } - - int nOut = 0; - - if ( !pOut ) - { - while ( bStopAtNull ? ( *pIn ) : ( nInChars-- > 0 ) ) - { - uchar32 uVal; - // Initialize in order to avoid /analyze warnings. - bool bErr = false; - pIn += DecodeSrc( pIn, uVal, bErr ); - nOut += EncodeDstLen( uVal ); - if ( bErr ) - { -#ifdef _DEBUG - AssertMsg( !(ePolicy & _STRINGCONVERTFLAG_ASSERT), "invalid Unicode byte sequence" ); -#endif - if ( ePolicy & _STRINGCONVERTFLAG_SKIP ) - { - nOut -= EncodeDstLen( uVal ); - } - else if ( ePolicy & _STRINGCONVERTFLAG_FAIL ) - { - pOut[0] = 0; - return 0; - } - } - } - } - else - { - int nOutElems = nOutBytes / sizeof( DstType ); - if ( nOutElems <= 0 ) - return 0; - - int nMaxOut = nOutElems - 1; - while ( bStopAtNull ? ( *pIn ) : ( nInChars-- > 0 ) ) - { - uchar32 uVal; - // Initialize in order to avoid /analyze warnings. - bool bErr = false; - pIn += DecodeSrc( pIn, uVal, bErr ); - if ( nOut + EncodeDstLen( uVal ) > nMaxOut ) - break; - nOut += EncodeDst( uVal, pOut + nOut ); - if ( bErr ) - { -#ifdef _DEBUG - AssertMsg( !(ePolicy & _STRINGCONVERTFLAG_ASSERT), "invalid Unicode byte sequence" ); -#endif - if ( ePolicy & _STRINGCONVERTFLAG_SKIP ) - { - nOut -= EncodeDstLen( uVal ); - } - else if ( ePolicy & _STRINGCONVERTFLAG_FAIL ) - { - pOut[0] = 0; - return 0; - } - } - } - pOut[nOut] = 0; - } - - return (nOut + 1) * sizeof( DstType ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if UTF-8 string contains invalid sequences. -//----------------------------------------------------------------------------- -bool Q_UnicodeValidate( const char *pUTF8 ) -{ - bool bError = false; - while ( *pUTF8 ) - { - uchar32 uVal; - // Our UTF-8 decoder silently fixes up 6-byte CESU-8 (improperly re-encoded UTF-16) sequences. - // However, these are technically not valid UTF-8. So if we eat 6 bytes at once, it's an error. - int nCharSize = Q_UTF8ToUChar32( pUTF8, uVal, bError ); - if ( bError || nCharSize == 6 ) - return false; - pUTF8 += nCharSize; - } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if UTF-16 string contains invalid sequences. -//----------------------------------------------------------------------------- -bool Q_UnicodeValidate( const uchar16 *pUTF16 ) -{ - bool bError = false; - while ( *pUTF16 ) - { - uchar32 uVal; - pUTF16 += Q_UTF16ToUChar32( pUTF16, uVal, bError ); - if ( bError ) - return false; - } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if UTF-32 string contains invalid sequences. -//----------------------------------------------------------------------------- -bool Q_UnicodeValidate( const uchar32 *pUTF32 ) -{ - while ( *pUTF32 ) - { - if ( !Q_IsValidUChar32( *pUTF32++ ) ) - return false; - ++pUTF32; - } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns number of Unicode code points (aka glyphs / characters) encoded in the UTF-8 string -//----------------------------------------------------------------------------- -int Q_UnicodeLength( const char *pUTF8 ) -{ - int nChars = 0; - while ( *pUTF8 ) - { - bool bError; - uchar32 uVal; - pUTF8 += Q_UTF8ToUChar32( pUTF8, uVal, bError ); - ++nChars; - } - return nChars; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns number of Unicode code points (aka glyphs / characters) encoded in the UTF-16 string -//----------------------------------------------------------------------------- -int Q_UnicodeLength( const uchar16 *pUTF16 ) -{ - int nChars = 0; - while ( *pUTF16 ) - { - bool bError; - uchar32 uVal; - pUTF16 += Q_UTF16ToUChar32( pUTF16, uVal, bError ); - ++nChars; - } - return nChars; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns number of Unicode code points (aka glyphs / characters) encoded in the UTF-32 string -//----------------------------------------------------------------------------- -int Q_UnicodeLength( const uchar32 *pUTF32 ) -{ - int nChars = 0; - while ( *pUTF32++ ) - ++nChars; - return nChars; -} - -//----------------------------------------------------------------------------- -// Purpose: Advance a UTF-8 string pointer by a certain number of Unicode code points, stopping at end of string -//----------------------------------------------------------------------------- -char *Q_UnicodeAdvance( char *pUTF8, int nChars ) -{ - while ( nChars > 0 && *pUTF8 ) - { - uchar32 uVal; - bool bError; - pUTF8 += Q_UTF8ToUChar32( pUTF8, uVal, bError ); - --nChars; - } - return pUTF8; -} - -//----------------------------------------------------------------------------- -// Purpose: Advance a UTF-16 string pointer by a certain number of Unicode code points, stopping at end of string -//----------------------------------------------------------------------------- -uchar16 *Q_UnicodeAdvance( uchar16 *pUTF16, int nChars ) -{ - while ( nChars > 0 && *pUTF16 ) - { - uchar32 uVal; - bool bError; - pUTF16 += Q_UTF16ToUChar32( pUTF16, uVal, bError ); - --nChars; - } - return pUTF16; -} - -//----------------------------------------------------------------------------- -// Purpose: Advance a UTF-32 string pointer by a certain number of Unicode code points, stopping at end of string -//----------------------------------------------------------------------------- -uchar32 *Q_UnicodeAdvance( uchar32 *pUTF32, int nChars ) -{ - while ( nChars > 0 && *pUTF32 ) - { - ++pUTF32; - --nChars; - } - return pUTF32; -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF8ToUTF16( const char *pUTF8, uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< char, uchar16, true, Q_UTF8ToUChar32, Q_UChar32ToUTF16Len, Q_UChar32ToUTF16 >( pUTF8, 0, pUTF16, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF8ToUTF32( const char *pUTF8, uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< char, uchar32, true, Q_UTF8ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF8, 0, pUTF32, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF16ToUTF8( const uchar16 *pUTF16, char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar16, char, true, Q_UTF16ToUChar32, Q_UChar32ToUTF8Len, Q_UChar32ToUTF8 >( pUTF16, 0, pUTF8, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF16ToUTF32( const uchar16 *pUTF16, uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar16, uchar32, true, Q_UTF16ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF16, 0, pUTF32, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF32ToUTF8( const uchar32 *pUTF32, char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, char, true, Q_UTF32ToUChar32, Q_UChar32ToUTF8Len, Q_UChar32ToUTF8 >( pUTF32, 0, pUTF8, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF32ToUTF16( const uchar32 *pUTF32, uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, uchar16, true, Q_UTF32ToUChar32, Q_UChar32ToUTF16Len, Q_UChar32ToUTF16 >( pUTF32, 0, pUTF16, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF32ToUTF32( const uchar32 *pUTF32Source, uchar32 *pUTF32Dest, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, uchar32, true, Q_UTF32ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF32Source, 0, pUTF32Dest, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF8CharsToUTF16( const char *pUTF8, int nElements, uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< char, uchar16, false, Q_UTF8ToUChar32, Q_UChar32ToUTF16Len, Q_UChar32ToUTF16 >( pUTF8, nElements, pUTF16, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF8CharsToUTF32( const char *pUTF8, int nElements, uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< char, uchar32, false, Q_UTF8ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF8, nElements, pUTF32, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF16CharsToUTF8( const uchar16 *pUTF16, int nElements, char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar16, char, false, Q_UTF16ToUChar32, Q_UChar32ToUTF8Len, Q_UChar32ToUTF8 >( pUTF16, nElements, pUTF8, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF16CharsToUTF32( const uchar16 *pUTF16, int nElements, uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar16, uchar32, false, Q_UTF16ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF16, nElements, pUTF32, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF32CharsToUTF8( const uchar32 *pUTF32, int nElements, char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, char, false, Q_UTF32ToUChar32, Q_UChar32ToUTF8Len, Q_UChar32ToUTF8 >( pUTF32, nElements, pUTF8, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Perform conversion. Returns number of *bytes* required if output pointer is NULL. -//----------------------------------------------------------------------------- -int Q_UTF32CharsToUTF16( const uchar32 *pUTF32, int nElements, uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, uchar16, false, Q_UTF32ToUChar32, Q_UChar32ToUTF16Len, Q_UChar32ToUTF16 >( pUTF32, nElements, pUTF16, cubDestSizeInBytes, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Repair a UTF-8 string by removing or replacing invalid seqeuences. Returns non-zero on success. -//----------------------------------------------------------------------------- -int Q_UnicodeRepair( char *pUTF8, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< char, char, true, Q_UTF8ToUChar32, Q_UChar32ToUTF8Len, Q_UChar32ToUTF8 >( pUTF8, 0, pUTF8, INT_MAX, ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Repair a UTF-16 string by removing or replacing invalid seqeuences. Returns non-zero on success. -//----------------------------------------------------------------------------- -int Q_UnicodeRepair( uchar16 *pUTF16, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar16, uchar16, true, Q_UTF16ToUChar32, Q_UChar32ToUTF16Len, Q_UChar32ToUTF16 >( pUTF16, 0, pUTF16, INT_MAX/sizeof(uchar16), ePolicy ); -} - -//----------------------------------------------------------------------------- -// Purpose: Repair a UTF-32 string by removing or replacing invalid seqeuences. Returns non-zero on success. -//----------------------------------------------------------------------------- -int Q_UnicodeRepair( uchar32 *pUTF32, EStringConvertErrorPolicy ePolicy ) -{ - return Q_UnicodeConvertT< uchar32, uchar32, true, Q_UTF32ToUChar32, Q_UChar32ToUTF32Len, Q_UChar32ToUTF32 >( pUTF32, 0, pUTF32, INT_MAX/sizeof(uchar32), ePolicy ); -} - diff --git a/tier1/tier1.vpc b/tier1/tier1.vpc index 6f163a8b..b368ad97 100644 --- a/tier1/tier1.vpc +++ b/tier1/tier1.vpc @@ -39,10 +39,12 @@ $Project "tier1" $File "generichash.cpp" $File "ilocalize.cpp" $File "interface.cpp" + $File "interval.cpp" $File "KeyValues.cpp" $File "kvpacker.cpp" $File "lzmaDecoder.cpp" $File "lzss.cpp" [!$SOURCESDK] + $File "math_proxy.cpp" [$POSIX] $File "mempool.cpp" $File "memstack.cpp" $File "NetAdr.cpp" @@ -64,7 +66,6 @@ $Project "tier1" $File "reliabletimer.cpp" $File "stringpool.cpp" $File "strtools.cpp" - $File "strtools_unicode.cpp" $File "tier1.cpp" $File "tokenreader.cpp" $File "sparsematrix.cpp" @@ -73,20 +74,12 @@ $Project "tier1" $File "utlbufferutil.cpp" $File "utlstring.cpp" $File "utlsymbol.cpp" - $File "utlbinaryblock.cpp" $File "pathmatch.cpp" [$LINUXALL] $File "snappy.cpp" $File "snappy-sinksource.cpp" $File "snappy-stubs-internal.cpp" - } - - // Select bits from the LZMA SDK to support lzmaDecoder.h - // Encoding support requires the full lzma project - $Folder "LZMA Decompression Support" - { - $File "$SRCDIR\utils\lzma\C\LzmaDec.h" - $File "$SRCDIR\utils\lzma\C\LzmaDec.c" - $File "$SRCDIR\utils\lzma\C\7zTypes.h" + $File "mapbase_con_groups.cpp" [$MAPBASE] + $File "mapbase_matchers_base.cpp" [$MAPBASE] } $Folder "Header Files" @@ -158,7 +151,8 @@ $Project "tier1" $File "$SRCDIR\public\tier1\utlsymbol.h" $File "$SRCDIR\public\tier1\utlsymbollarge.h" $File "$SRCDIR\public\tier1\utlvector.h" - $File "$SRCDIR\public\tier1\utlbinaryblock.h" + $File "$SRCDIR\public\tier1\mapbase_con_groups.h" [$MAPBASE] + $File "$SRCDIR\public\tier1\mapbase_matchers_base.h" [$MAPBASE] $File "$SRCDIR\common\xbox\xboxstubs.h" [$WINDOWS] } } diff --git a/tier1/uniqueid.cpp b/tier1/uniqueid.cpp index d75e4fd9..0d51c4cf 100644 --- a/tier1/uniqueid.cpp +++ b/tier1/uniqueid.cpp @@ -163,7 +163,7 @@ bool Unserialize( CUtlBuffer &buf, UniqueId_t &dest ) { int nTextLen = buf.PeekStringLength(); char *pBuf = (char*)stackalloc( nTextLen ); - buf.GetStringManualCharCount( pBuf, nTextLen ); + buf.GetString( pBuf, nTextLen ); UniqueIdFromString( &dest, pBuf, nTextLen ); } else diff --git a/tier1/utlbinaryblock.cpp b/tier1/utlbinaryblock.cpp deleted file mode 100644 index 7f64c4ec..00000000 --- a/tier1/utlbinaryblock.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//====== Copyright 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#include "tier1/utlbinaryblock.h" - -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) : m_Memory( growSize, initSize ) -{ - m_nActualLength = 0; -} - -CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nInitialLength; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nSizeInBytes; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src ) -{ - Set( src.Get(), src.Length() ); -} - -void CUtlBinaryBlock::Get( void *pValue, int nLen ) const -{ - Assert( nLen > 0 ); - if ( m_nActualLength < nLen ) - { - nLen = m_nActualLength; - } - - if ( nLen > 0 ) - { - memcpy( pValue, m_Memory.Base(), nLen ); - } -} - -void CUtlBinaryBlock::SetLength( int nLength ) -{ - Assert( !m_Memory.IsReadOnly() ); - - m_nActualLength = nLength; - if ( nLength > m_Memory.NumAllocated() ) - { - int nOverFlow = nLength - m_Memory.NumAllocated(); - m_Memory.Grow( nOverFlow ); - - // If the reallocation failed, clamp length - if ( nLength > m_Memory.NumAllocated() ) - { - m_nActualLength = m_Memory.NumAllocated(); - } - } - -#ifdef _DEBUG - if ( m_Memory.NumAllocated() > m_nActualLength ) - { - memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength ); - } -#endif -} - - -void CUtlBinaryBlock::Set( const void *pValue, int nLen ) -{ - Assert( !m_Memory.IsReadOnly() ); - - if ( !pValue ) - { - nLen = 0; - } - - SetLength( nLen ); - - if ( m_nActualLength ) - { - if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen || - ( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) ) - { - memcpy( m_Memory.Base(), pValue, m_nActualLength ); - } - else - { - memmove( m_Memory.Base(), pValue, m_nActualLength ); - } - } -} - - -CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src ) -{ - Assert( !m_Memory.IsReadOnly() ); - Set( src.Get(), src.Length() ); - return *this; -} - - -bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const -{ - if ( src.Length() != Length() ) - return false; - - return !memcmp( src.Get(), Get(), Length() ); -} - - - - diff --git a/tier1/utlbuffer.cpp b/tier1/utlbuffer.cpp index fc89d773..55dd8f6b 100644 --- a/tier1/utlbuffer.cpp +++ b/tier1/utlbuffer.cpp @@ -607,19 +607,17 @@ int CUtlBuffer::PeekDelimitedStringLength( CUtlCharConversion *pConv, bool bActu //----------------------------------------------------------------------------- // Reads a null-terminated string //----------------------------------------------------------------------------- -void CUtlBuffer::GetStringInternal( char *pString, size_t maxLenInChars ) +void CUtlBuffer::GetString( char* pString, int nMaxChars ) { - if ( !IsValid() ) + if (!IsValid()) { *pString = 0; return; } - Assert( maxLenInChars != 0 ); - - if ( maxLenInChars == 0 ) + if ( nMaxChars == 0 ) { - return; + nMaxChars = INT_MAX; } // Remember, this *includes* the null character @@ -631,21 +629,24 @@ void CUtlBuffer::GetStringInternal( char *pString, size_t maxLenInChars ) EatWhiteSpace(); } - if ( nLen <= 0 ) + if ( nLen == 0 ) { *pString = 0; m_Error |= GET_OVERFLOW; return; } - - const size_t nCharsToRead = min( (size_t)nLen, maxLenInChars ) - 1; - - Get( pString, nCharsToRead ); - pString[nCharsToRead] = 0; - - if ( (size_t)nLen > (nCharsToRead + 1) ) + + // Strip off the terminating NULL + if ( nLen <= nMaxChars ) { - SeekGet( SEEK_CURRENT, nLen - (nCharsToRead + 1) ); + Get( pString, nLen - 1 ); + pString[ nLen - 1 ] = 0; + } + else + { + Get( pString, nMaxChars - 1 ); + pString[ nMaxChars - 1 ] = 0; + SeekGet( SEEK_CURRENT, nLen - 1 - nMaxChars ); } // Read the terminating NULL in binary formats @@ -730,7 +731,7 @@ void CUtlBuffer::GetDelimitedString( CUtlCharConversion *pConv, char *pString, i { if ( !IsText() || !pConv ) { - GetStringInternal( pString, nMaxChars ); + GetString( pString, nMaxChars ); return; } @@ -1040,7 +1041,7 @@ int CUtlBuffer::VaScanf( const char* pFmt, va_list list ) case 's': { char* s = va_arg( list, char * ); - GetStringInternal( s, 256 ); + GetString( s ); } break; diff --git a/tier1/utlbufferutil.cpp b/tier1/utlbufferutil.cpp index 79949bf6..b911206d 100644 --- a/tier1/utlbufferutil.cpp +++ b/tier1/utlbufferutil.cpp @@ -20,7 +20,6 @@ #include #include #include -#include "tier1/utlbinaryblock.h" #include "tier1/utlstring.h" #include "tier1/strtools.h" #include "tier1/characterset.h" @@ -551,7 +550,7 @@ bool Unserialize( CUtlBuffer &buf, CUtlString &dest ) { int nLen = buf.PeekDelimitedStringLength( s_pConv ); dest.SetLength( nLen - 1 ); // -1 because the length returned includes space for \0 - buf.GetDelimitedString( s_pConv, dest.GetForModify(), nLen ); + buf.GetDelimitedString( s_pConv, dest.Get(), nLen ); return buf.IsValid(); } diff --git a/tier1/utlstring.cpp b/tier1/utlstring.cpp index 570aab85..580e1e97 100644 --- a/tier1/utlstring.cpp +++ b/tier1/utlstring.cpp @@ -4,9 +4,6 @@ // //============================================================================= -#define __STDC_LIMIT_MACROS -#include - #include "tier1/utlstring.h" #include "tier1/strtools.h" #include @@ -14,256 +11,312 @@ // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" + //----------------------------------------------------------------------------- -// Simple string class. +// Base class, containing simple memory management //----------------------------------------------------------------------------- +CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) +{ + MEM_ALLOC_CREDIT(); + m_Memory.Init( growSize, initSize ); -//----------------------------------------------------------------------------- -// Either allocates or reallocates memory to the length -// -// Allocated space for length characters. It automatically adds space for the -// nul and the cached length at the start of the memory block. Will adjust -// m_pString and explicitly set the nul at the end before returning. -void *CUtlString::AllocMemory( uint32 length ) + m_nActualLength = 0; +} + +CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes ) { - void *pMemoryBlock; - if ( m_pString ) + m_nActualLength = nInitialLength; +} + +CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes ) +{ + m_nActualLength = nSizeInBytes; +} + +CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src ) +{ + Set( src.Get(), src.Length() ); +} + +void CUtlBinaryBlock::Get( void *pValue, int nLen ) const +{ + Assert( nLen > 0 ); + if ( m_nActualLength < nLen ) { - pMemoryBlock = realloc( m_pString, length + 1 ); + nLen = m_nActualLength; } - else + + if ( nLen > 0 ) { - pMemoryBlock = malloc( length + 1 ); + memcpy( pValue, m_Memory.Base(), nLen ); } - m_pString = (char*)pMemoryBlock; - m_pString[ length ] = 0; - - return pMemoryBlock; } -//----------------------------------------------------------------------------- -void CUtlString::SetDirect( const char *pValue, int nChars ) +void CUtlBinaryBlock::SetLength( int nLength ) { - if ( pValue && nChars > 0 ) + MEM_ALLOC_CREDIT(); + Assert( !m_Memory.IsReadOnly() ); + + m_nActualLength = nLength; + if ( nLength > m_Memory.NumAllocated() ) { - if ( pValue == m_pString ) + int nOverFlow = nLength - m_Memory.NumAllocated(); + m_Memory.Grow( nOverFlow ); + + // If the reallocation failed, clamp length + if ( nLength > m_Memory.NumAllocated() ) { - AssertMsg( nChars == Q_strlen(m_pString), "CUtlString::SetDirect does not support resizing strings in place." ); - return; // Do nothing. Realloc in AllocMemory might move pValue's location resulting in a bad memcpy. + m_nActualLength = m_Memory.NumAllocated(); } - - Assert( nChars <= Min( strnlen(pValue, nChars) + 1, nChars ) ); - AllocMemory( nChars ); - Q_memcpy( m_pString, pValue, nChars ); } - else + +#ifdef _DEBUG + if ( m_Memory.NumAllocated() > m_nActualLength ) { - Purge(); + memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength ); } - +#endif } -void CUtlString::Set( const char *pValue ) +void CUtlBinaryBlock::Set( const void *pValue, int nLen ) { - int length = pValue ? V_strlen( pValue ) : 0; - SetDirect( pValue, length ); -} + Assert( !m_Memory.IsReadOnly() ); -// Sets the length (used to serialize into the buffer ) -void CUtlString::SetLength( int nLen ) -{ - if ( nLen > 0 ) + if ( !pValue ) { -#ifdef _DEBUG - int prevLen = m_pString ? Length() : 0; -#endif - AllocMemory( nLen ); -#ifdef _DEBUG - if ( nLen > prevLen ) - { - V_memset( m_pString + prevLen, 0xEB, nLen - prevLen ); - } -#endif + nLen = 0; } - else + + SetLength( nLen ); + + if ( m_nActualLength ) { - Purge(); + if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen || + ( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) ) + { + memcpy( m_Memory.Base(), pValue, m_nActualLength ); + } + else + { + memmove( m_Memory.Base(), pValue, m_nActualLength ); + } } } -const char *CUtlString::Get( ) const + +CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src ) { - if (!m_pString) - { - return ""; - } - return m_pString; + Assert( !m_Memory.IsReadOnly() ); + Set( src.Get(), src.Length() ); + return *this; } -char *CUtlString::GetForModify() + +bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const { - if ( !m_pString ) - { - // In general, we optimise away small mallocs for empty strings - // but if you ask for the non-const bytes, they must be writable - // so we can't return "" here, like we do for the const version - jd - void *pMemoryBlock = malloc( 1 ); - m_pString = (char *)pMemoryBlock; - *m_pString = 0; - } + if ( src.Length() != Length() ) + return false; - return m_pString; + return !memcmp( src.Get(), Get(), Length() ); } -char CUtlString::operator[]( int i ) const + +//----------------------------------------------------------------------------- +// Simple string class. +//----------------------------------------------------------------------------- +CUtlString::CUtlString() { - if ( !m_pString ) - return '\0'; +} - if ( i >= Length() ) - { - return '\0'; - } +CUtlString::CUtlString( const char *pString ) +{ + Set( pString ); +} - return m_pString[i]; +CUtlString::CUtlString( const CUtlString& string ) +{ + Set( string.Get() ); } -void CUtlString::Clear() +// Attaches the string to external memory. Useful for avoiding a copy +CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength ) { - Purge(); } -void CUtlString::Purge() +CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes ) +{ +} + + +//----------------------------------------------------------------------------- +// Purpose: Set directly and don't look for a null terminator in pValue. +//----------------------------------------------------------------------------- +void CUtlString::SetDirect( const char *pValue, int nChars ) +{ + Assert( !m_Storage.IsReadOnly() ); + m_Storage.Set( pValue, nChars + 1 ); + + // Make sure to null terminate the copied string + *(((char *)m_Storage.Get()) + nChars) = NULL; +} + + +void CUtlString::Set( const char *pValue ) { - free( m_pString ); - m_pString = NULL; + Assert( !m_Storage.IsReadOnly() ); + int nLen = pValue ? Q_strlen(pValue) + 1 : 0; + m_Storage.Set( pValue, nLen ); +} + + +// Returns strlen +int CUtlString::Length() const +{ + return m_Storage.Length() ? m_Storage.Length() - 1 : 0; +} + +// Sets the length (used to serialize into the buffer ) +void CUtlString::SetLength( int nLen ) +{ + Assert( !m_Storage.IsReadOnly() ); + + // Add 1 to account for the NULL + m_Storage.SetLength( nLen > 0 ? nLen + 1 : 0 ); } -bool CUtlString::IsEqual_CaseSensitive( const char *src ) const +const char *CUtlString::Get( ) const { - if ( !src ) + if ( m_Storage.Length() == 0 ) { - return (Length() == 0); + return ""; } - return ( V_strcmp( Get(), src ) == 0 ); + + return reinterpret_cast< const char* >( m_Storage.Get() ); +} + +// Converts to c-strings +CUtlString::operator const char*() const +{ + return Get(); } -bool CUtlString::IsEqual_CaseInsensitive( const char *src ) const +char *CUtlString::Get() { - if ( !src ) + Assert( !m_Storage.IsReadOnly() ); + + if ( m_Storage.Length() == 0 ) { - return (Length() == 0); + // In general, we optimise away small mallocs for empty strings + // but if you ask for the non-const bytes, they must be writable + // so we can't return "" here, like we do for the const version - jd + m_Storage.SetLength( 1 ); + m_Storage[ 0 ] = '\0'; } - return ( V_stricmp( Get(), src ) == 0 ); + + return reinterpret_cast< char* >( m_Storage.Get() ); +} + +void CUtlString::Purge() +{ + m_Storage.Purge(); } void CUtlString::ToLower() { - if ( !m_pString ) + for( int nLength = Length() - 1; nLength >= 0; nLength-- ) { - return; + m_Storage[ nLength ] = tolower( m_Storage[ nLength ] ); } - - V_strlower( m_pString ); } + void CUtlString::ToUpper() { - if ( !m_pString ) + for( int nLength = Length() - 1; nLength >= 0; nLength-- ) { - return; + m_Storage[ nLength ] = toupper( m_Storage[ nLength ] ); } - - V_strupr( m_pString ); } + CUtlString &CUtlString::operator=( const CUtlString &src ) { - SetDirect( src.Get(), src.Length() ); + Assert( !m_Storage.IsReadOnly() ); + m_Storage = src.m_Storage; return *this; } CUtlString &CUtlString::operator=( const char *src ) { + Assert( !m_Storage.IsReadOnly() ); Set( src ); return *this; } bool CUtlString::operator==( const CUtlString &src ) const { - if ( IsEmpty() ) - { - if ( src.IsEmpty() ) - { - return true; - } - - return false; - } - else - { - if ( src.IsEmpty() ) - { - return false; - } + return m_Storage == src.m_Storage; +} - return Q_strcmp( m_pString, src.m_pString ) == 0; - } +bool CUtlString::operator==( const char *src ) const +{ + return ( strcmp( Get(), src ) == 0 ); } CUtlString &CUtlString::operator+=( const CUtlString &rhs ) { + Assert( !m_Storage.IsReadOnly() ); + const int lhsLength( Length() ); const int rhsLength( rhs.Length() ); - - if (!rhsLength) - { - return *this; - } - const int requestedLength( lhsLength + rhsLength ); - AllocMemory( requestedLength ); - Q_memcpy( m_pString + lhsLength, rhs.m_pString, rhsLength ); + SetLength( requestedLength ); + const int allocatedLength( Length() ); + const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); + memcpy( Get() + lhsLength, rhs.Get(), copyLength ); + m_Storage[ allocatedLength ] = '\0'; return *this; } CUtlString &CUtlString::operator+=( const char *rhs ) { + Assert( !m_Storage.IsReadOnly() ); + const int lhsLength( Length() ); - const int rhsLength( V_strlen( rhs ) ); + const int rhsLength( Q_strlen( rhs ) ); const int requestedLength( lhsLength + rhsLength ); - if (!requestedLength) - { - return *this; - } - - AllocMemory( requestedLength ); - Q_memcpy( m_pString + lhsLength, rhs, rhsLength ); + SetLength( requestedLength ); + const int allocatedLength( Length() ); + const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); + memcpy( Get() + lhsLength, rhs, copyLength ); + m_Storage[ allocatedLength ] = '\0'; return *this; } CUtlString &CUtlString::operator+=( char c ) { - const int lhsLength( Length() ); - - AllocMemory( lhsLength + 1 ); - m_pString[ lhsLength ] = c; + Assert( !m_Storage.IsReadOnly() ); + int nLength = Length(); + SetLength( nLength + 1 ); + m_Storage[ nLength ] = c; + m_Storage[ nLength+1 ] = '\0'; return *this; } CUtlString &CUtlString::operator+=( int rhs ) { + Assert( !m_Storage.IsReadOnly() ); Assert( sizeof( rhs ) == 4 ); char tmpBuf[ 12 ]; // Sufficient for a signed 32 bit integer [ -2147483648 to +2147483647 ] - V_snprintf( tmpBuf, sizeof( tmpBuf ), "%d", rhs ); + Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%d", rhs ); tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; return operator+=( tmpBuf ); @@ -271,8 +324,10 @@ CUtlString &CUtlString::operator+=( int rhs ) CUtlString &CUtlString::operator+=( double rhs ) { + Assert( !m_Storage.IsReadOnly() ); + char tmpBuf[ 256 ]; // How big can doubles be??? Dunno. - V_snprintf( tmpBuf, sizeof( tmpBuf ), "%lg", rhs ); + Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%lg", rhs ); tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; return operator+=( tmpBuf ); @@ -358,27 +413,31 @@ bool CUtlString::MatchesPattern( const CUtlString &Pattern, int nFlags ) const int CUtlString::Format( const char *pFormat, ... ) { + Assert( !m_Storage.IsReadOnly() ); + + char tmpBuf[ 4096 ]; //< Nice big 4k buffer, as much memory as my first computer had, a Radio Shack Color Computer + va_list marker; va_start( marker, pFormat ); - int len = FormatV( pFormat, marker ); +#ifdef _WIN32 + int len = _vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); +#elif POSIX + int len = vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); +#else +#error "define vsnprintf type." +#endif va_end( marker ); - return len; -} - -//-------------------------------------------------------------------------------------------------- -// This can be called from functions that take varargs. -//-------------------------------------------------------------------------------------------------- - -int CUtlString::FormatV( const char *pFormat, va_list marker ) -{ - char tmpBuf[ 4096 ]; //< Nice big 4k buffer, as much memory as my first computer had, a Radio Shack Color Computer + // Len > maxLen represents an overflow on POSIX, < 0 is an overflow on windows + if( len < 0 || len >= sizeof( tmpBuf ) - 1 ) + { + len = sizeof( tmpBuf ) - 1; + tmpBuf[sizeof( tmpBuf ) - 1] = 0; + } - //va_start( marker, pFormat ); - int len = V_vsprintf_safe( tmpBuf, pFormat, marker ); - //va_end( marker ); Set( tmpBuf ); + return len; } @@ -391,322 +450,88 @@ void CUtlString::StripTrailingSlash() return; int nLastChar = Length() - 1; - char c = m_pString[ nLastChar ]; + char c = m_Storage[ nLastChar ]; if ( c == '\\' || c == '/' ) { - SetLength( nLastChar ); - } -} - -void CUtlString::FixSlashes( char cSeparator/*=CORRECT_PATH_SEPARATOR*/ ) -{ - if ( m_pString ) - { - V_FixSlashes( m_pString, cSeparator ); - } -} - -//----------------------------------------------------------------------------- -// Trim functions -//----------------------------------------------------------------------------- -void CUtlString::TrimLeft( char cTarget ) -{ - int nIndex = 0; - - if ( IsEmpty() ) - { - return; - } - - while( m_pString[nIndex] == cTarget ) - { - ++nIndex; - } - - // We have some whitespace to remove - if ( nIndex > 0 ) - { - memcpy( m_pString, &m_pString[nIndex], Length() - nIndex ); - SetLength( Length() - nIndex ); - } -} - - -void CUtlString::TrimLeft( const char *szTargets ) -{ - int i; - - if ( IsEmpty() ) - { - return; - } - - for( i = 0; m_pString[i] != 0; i++ ) - { - bool bWhitespace = false; - - for( int j = 0; szTargets[j] != 0; j++ ) - { - if ( m_pString[i] == szTargets[j] ) - { - bWhitespace = true; - break; - } - } - - if ( !bWhitespace ) - { - break; - } - } - - // We have some whitespace to remove - if ( i > 0 ) - { - memcpy( m_pString, &m_pString[i], Length() - i ); - SetLength( Length() - i ); - } -} - - -void CUtlString::TrimRight( char cTarget ) -{ - const int nLastCharIndex = Length() - 1; - int nIndex = nLastCharIndex; - - while ( nIndex >= 0 && m_pString[nIndex] == cTarget ) - { - --nIndex; - } - - // We have some whitespace to remove - if ( nIndex < nLastCharIndex ) - { - m_pString[nIndex + 1] = 0; - SetLength( nIndex + 2 ); - } -} - - -void CUtlString::TrimRight( const char *szTargets ) -{ - const int nLastCharIndex = Length() - 1; - int i; - - for( i = nLastCharIndex; i > 0; i-- ) - { - bool bWhitespace = false; - - for( int j = 0; szTargets[j] != 0; j++ ) - { - if ( m_pString[i] == szTargets[j] ) - { - bWhitespace = true; - break; - } - } - - if ( !bWhitespace ) - { - break; - } - } - - // We have some whitespace to remove - if ( i < nLastCharIndex ) - { - m_pString[i + 1] = 0; - SetLength( i + 2 ); + m_Storage[ nLastChar ] = 0; + m_Storage.SetLength( m_Storage.Length() - 1 ); } } - -void CUtlString::Trim( char cTarget ) -{ - TrimLeft( cTarget ); - TrimRight( cTarget ); -} - - -void CUtlString::Trim( const char *szTargets ) +CUtlString CUtlString::Slice( int32 nStart, int32 nEnd ) { - TrimLeft( szTargets ); - TrimRight( szTargets ); -} - - -CUtlString CUtlString::Slice( int32 nStart, int32 nEnd ) const -{ - int length = Length(); - if ( length == 0 ) - { - return CUtlString(); - } - if ( nStart < 0 ) - nStart = length - (-nStart % length); - else if ( nStart >= length ) - nStart = length; + nStart = Length() - (-nStart % Length()); + else if ( nStart >= Length() ) + nStart = Length(); - if ( nEnd == INT32_MAX ) - nEnd = length; + if ( nEnd == 0x7FFFFFFF ) + nEnd = Length(); else if ( nEnd < 0 ) - nEnd = length - (-nEnd % length); - else if ( nEnd >= length ) - nEnd = length; + nEnd = Length() - (-nEnd % Length()); + else if ( nEnd >= Length() ) + nEnd = Length(); if ( nStart >= nEnd ) - return CUtlString(); + return CUtlString( "" ); const char *pIn = String(); CUtlString ret; - ret.SetDirect( pIn + nStart, nEnd - nStart ); + ret.m_Storage.SetLength( nEnd - nStart + 1 ); + char *pOut = (char*)ret.m_Storage.Get(); + + memcpy( ret.m_Storage.Get(), &pIn[nStart], nEnd - nStart ); + pOut[nEnd - nStart] = 0; + return ret; } // Grab a substring starting from the left or the right side. -CUtlString CUtlString::Left( int32 nChars ) const +CUtlString CUtlString::Left( int32 nChars ) { return Slice( 0, nChars ); } -CUtlString CUtlString::Right( int32 nChars ) const +CUtlString CUtlString::Right( int32 nChars ) { return Slice( -nChars ); } -CUtlString CUtlString::Replace( char cFrom, char cTo ) const +CUtlString CUtlString::Replace( char cFrom, char cTo ) { - if (!m_pString) - { - return CUtlString(); - } - CUtlString ret = *this; int len = ret.Length(); for ( int i=0; i < len; i++ ) { - if ( ret.m_pString[i] == cFrom ) - ret.m_pString[i] = cTo; + if ( ret.m_Storage[i] == cFrom ) + ret.m_Storage[i] = cTo; } return ret; } -CUtlString CUtlString::Replace( const char *pszFrom, const char *pszTo ) const -{ - Assert( pszTo ); // Can be 0 length, but not null - Assert( pszFrom && *pszFrom ); // Must be valid and have one character. - - - const char *pos = V_strstr( String(), pszFrom ); - if ( !pos ) - { - return *this; - } - - const char *pFirstFound = pos; - - // count number of search string - int nSearchCount = 0; - int nSearchLength = V_strlen( pszFrom ); - while ( pos ) - { - nSearchCount++; - int nSrcOffset = ( pos - String() ) + nSearchLength; - pos = V_strstr( String() + nSrcOffset, pszFrom ); - } - - // allocate the new string - int nReplaceLength = V_strlen( pszTo ); - int nAllocOffset = nSearchCount * ( nReplaceLength - nSearchLength ); - size_t srcLength = Length(); - CUtlString strDest; - size_t destLength = srcLength + nAllocOffset; - strDest.SetLength( destLength ); - - // find and replace the search string - pos = pFirstFound; - int nDestOffset = 0; - int nSrcOffset = 0; - while ( pos ) - { - // Found an instance - int nCurrentSearchOffset = pos - String(); - int nCopyLength = nCurrentSearchOffset - nSrcOffset; - V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, nCopyLength + 1 ); - nDestOffset += nCopyLength; - V_strncpy( strDest.GetForModify() + nDestOffset, pszTo, nReplaceLength + 1 ); - nDestOffset += nReplaceLength; - - nSrcOffset = nCurrentSearchOffset + nSearchLength; - pos = V_strstr( String() + nSrcOffset, pszFrom ); - } - - // making sure that the left over string from the source is the same size as the left over dest buffer - Assert( destLength - nDestOffset == srcLength - nSrcOffset ); - if ( destLength - nDestOffset > 0 ) - { - V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, destLength - nDestOffset + 1 ); - } - - return strDest; -} - -CUtlString CUtlString::AbsPath( const char *pStartingDir ) const +CUtlString CUtlString::AbsPath( const char *pStartingDir ) { char szNew[MAX_PATH]; V_MakeAbsolutePath( szNew, sizeof( szNew ), this->String(), pStartingDir ); return CUtlString( szNew ); } -CUtlString CUtlString::UnqualifiedFilename() const +CUtlString CUtlString::UnqualifiedFilename() { const char *pFilename = V_UnqualifiedFileName( this->String() ); return CUtlString( pFilename ); } -CUtlString CUtlString::DirName() const +CUtlString CUtlString::DirName() { CUtlString ret( this->String() ); - V_StripLastDir( (char*)ret.Get(), ret.Length() + 1 ); - V_StripTrailingSlash( (char*)ret.Get() ); + V_StripLastDir( (char*)ret.m_Storage.Get(), ret.m_Storage.Length() ); + V_StripTrailingSlash( (char*)ret.m_Storage.Get() ); return ret; } -CUtlString CUtlString::StripExtension() const -{ - char szTemp[MAX_PATH]; - V_StripExtension( String(), szTemp, sizeof( szTemp ) ); - return CUtlString( szTemp ); -} - -CUtlString CUtlString::StripFilename() const -{ - const char *pFilename = V_UnqualifiedFileName( Get() ); // NOTE: returns 'Get()' on failure, never NULL - int nCharsToCopy = pFilename - Get(); - CUtlString result; - result.SetDirect( Get(), nCharsToCopy ); - result.StripTrailingSlash(); - return result; -} - -CUtlString CUtlString::GetBaseFilename() const -{ - char szTemp[MAX_PATH]; - V_FileBase( String(), szTemp, sizeof( szTemp ) ); - return CUtlString( szTemp ); -} - -CUtlString CUtlString::GetExtension() const -{ - char szTemp[MAX_PATH]; - V_ExtractFileExtension( String(), szTemp, sizeof( szTemp ) ); - return CUtlString( szTemp ); -} - - CUtlString CUtlString::PathJoin( const char *pStr1, const char *pStr2 ) { char szPath[MAX_PATH]; @@ -714,54 +539,10 @@ CUtlString CUtlString::PathJoin( const char *pStr1, const char *pStr2 ) return CUtlString( szPath ); } -CUtlString CUtlString::operator+( const char *pOther ) const -{ - CUtlString s = *this; - s += pOther; - return s; -} - -CUtlString CUtlString::operator+( const CUtlString &other ) const -{ - CUtlString s = *this; - s += other; - return s; -} - -CUtlString CUtlString::operator+( int rhs ) const -{ - CUtlString ret = *this; - ret += rhs; - return ret; -} - //----------------------------------------------------------------------------- // Purpose: concatenate the provided string to our current content //----------------------------------------------------------------------------- void CUtlString::Append( const char *pchAddition ) { - (*this) += pchAddition; -} - -void CUtlString::Append( const char *pchAddition, int nChars ) -{ - nChars = Min( nChars, V_strlen( pchAddition ) ); - - const int lhsLength( Length() ); - const int rhsLength( nChars ); - const int requestedLength( lhsLength + rhsLength ); - - AllocMemory( requestedLength ); - const int allocatedLength( requestedLength ); - const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); - memcpy( GetForModify() + lhsLength, pchAddition, copyLength ); - m_pString[ allocatedLength ] = '\0'; -} - -// Shared static empty string. -const CUtlString &CUtlString::GetEmptyString() -{ - static const CUtlString s_emptyString; - - return s_emptyString; + *this += pchAddition; } diff --git a/tier1/utlsymbol.cpp b/tier1/utlsymbol.cpp index d75eaa52..72cea6db 100644 --- a/tier1/utlsymbol.cpp +++ b/tier1/utlsymbol.cpp @@ -232,7 +232,7 @@ CUtlSymbol CUtlSymbolTable::AddString( const char* pString ) if ( iPool == -1 ) { // Add a new pool. - int newPoolSize = max( len, MIN_STRING_POOL_SIZE ); + int newPoolSize = MAX( len, MIN_STRING_POOL_SIZE ); StringPool_t *pPool = (StringPool_t*)malloc( sizeof( StringPool_t ) + newPoolSize - 1 ); pPool->m_TotalLen = newPoolSize; pPool->m_SpaceUsed = 0; diff --git a/utils/captioncompiler/captioncompiler.vpc b/utils/captioncompiler/captioncompiler.vpc index da5a3b4e..3d1e24ad 100644 --- a/utils/captioncompiler/captioncompiler.vpc +++ b/utils/captioncompiler/captioncompiler.vpc @@ -14,7 +14,8 @@ $Configuration $Compiler { $AdditionalIncludeDirectories "$BASE,..\common,$SRCDIR\game\shared,.\" - $PreprocessorDefinitions "$BASE;captioncompiler" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;captioncompiler" [($VS2015||$VS2017||$VS2019||$VS2022)] + $PreprocessorDefinitions "$BASE;captioncompiler" [!($VS2015||$VS2017||$VS2019||$VS2022)] } } diff --git a/utils/common/bsplib.cpp b/utils/common/bsplib.cpp index cadf7af5..c3ad433e 100644 --- a/utils/common/bsplib.cpp +++ b/utils/common/bsplib.cpp @@ -26,13 +26,11 @@ #include "tier0/dbg.h" #include "lumpfiles.h" #include "vtf/vtf.h" -#include "lzma/lzma.h" -#include "tier1/lzmaDecoder.h" //============================================================================= // Boundary each lump should be aligned to -#define LUMP_ALIGNMENT 4 +#define LUMP_ALIGNMENT 4 // Data descriptions for byte swapping - only needed // for structures that are written to file for use by the game. @@ -47,7 +45,7 @@ BEGIN_BYTESWAP_DATADESC( lump_t ) DEFINE_FIELD( fileofs, FIELD_INTEGER ), DEFINE_FIELD( filelen, FIELD_INTEGER ), DEFINE_FIELD( version, FIELD_INTEGER ), - DEFINE_FIELD( uncompressedSize, FIELD_INTEGER ), + DEFINE_ARRAY( fourCC, FIELD_CHARACTER, 4 ), END_BYTESWAP_DATADESC() BEGIN_BYTESWAP_DATADESC( dflagslump_t ) @@ -817,10 +815,9 @@ void ClearPakFile( IZip *pak ) // Input : *relativename - // *fullpath - //----------------------------------------------------------------------------- -void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath, IZip::eCompressionType compressionType ) +void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath ) { - DevMsg( "Adding file to pakfile [ %s ]\n", fullpath ); - pak->AddFileToZip( relativename, fullpath, compressionType ); + pak->AddFileToZip( relativename, fullpath ); } //----------------------------------------------------------------------------- @@ -829,65 +826,9 @@ void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath, IZ // *data - // length - //----------------------------------------------------------------------------- -void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode, IZip::eCompressionType compressionType ) +void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode ) { - pak->AddBufferToZip( pRelativeName, data, length, bTextMode, compressionType ); -} - -//----------------------------------------------------------------------------- -// Purpose: Add entire directory to .bsp PAK lump as named file -// Input : *relativename - -// *data - -// length - -//----------------------------------------------------------------------------- -void AddDirToPak( IZip *pak, const char *pDirPath, const char *pPakPrefix ) -{ - if ( !g_pFullFileSystem->IsDirectory( pDirPath ) ) - { - Warning( "Passed non-directory to AddDirToPak [ %s ]\n", pDirPath ); - return; - } - - DevMsg( "Adding directory to pakfile [ %s ]\n", pDirPath ); - - // Enumerate dir - char szEnumerateDir[MAX_PATH] = { 0 }; - V_snprintf( szEnumerateDir, sizeof( szEnumerateDir ), "%s/*.*", pDirPath ); - V_FixSlashes( szEnumerateDir ); - - FileFindHandle_t handle; - const char *szFindResult = g_pFullFileSystem->FindFirst( szEnumerateDir, &handle ); - do - { - if ( szFindResult[0] != '.' ) - { - char szPakName[MAX_PATH] = { 0 }; - char szFullPath[MAX_PATH] = { 0 }; - if ( pPakPrefix ) - { - V_snprintf( szPakName, sizeof( szPakName ), "%s/%s", pPakPrefix, szFindResult ); - } - else - { - V_strncpy( szPakName, szFindResult, sizeof( szPakName ) ); - } - V_snprintf( szFullPath, sizeof( szFullPath ), "%s/%s", pDirPath, szFindResult ); - V_FixDoubleSlashes( szFullPath ); - V_FixDoubleSlashes( szPakName ); - - if ( g_pFullFileSystem->FindIsDirectory( handle ) ) - { - // Recurse - AddDirToPak( pak, szFullPath, szPakName ); - } - else - { - // Just add this file - AddFileToPak( pak, szPakName, szFullPath ); - } - } - szFindResult = g_pFullFileSystem->FindNext( handle ); - } while ( szFindResult); + pak->AddBufferToZip( pRelativeName, data, length, bTextMode ); } //----------------------------------------------------------------------------- @@ -1349,11 +1290,14 @@ static void AddOcclusionLump( ) 3 * sizeof(int); lump_t *lump = &g_pBSPHeader->lumps[LUMP_OCCLUSION]; - + lump->fileofs = g_pFileSystem->Tell( g_hBSPFile ); lump->filelen = nLumpLength; lump->version = LUMP_OCCLUSION_VERSION; - lump->uncompressedSize = 0; + lump->fourCC[0] = ( char )0; + lump->fourCC[1] = ( char )0; + lump->fourCC[2] = ( char )0; + lump->fourCC[3] = ( char )0; // Data is swapped in place, so the 'Count' variables aren't safe to use after they're written WriteData( FIELD_INTEGER, &nOccluderCount ); @@ -2540,11 +2484,14 @@ static void AddLumpInternal( int lumpnum, void *data, int len, int version ) g_Lumps.size[lumpnum] = 0; // mark it written lump = &g_pBSPHeader->lumps[lumpnum]; - + lump->fileofs = g_pFileSystem->Tell( g_hBSPFile ); lump->filelen = len; lump->version = version; - lump->uncompressedSize = 0; + lump->fourCC[0] = ( char )0; + lump->fourCC[1] = ( char )0; + lump->fourCC[2] = ( char )0; + lump->fourCC[3] = ( char )0; SafeWrite( g_hBSPFile, data, len ); @@ -3758,6 +3705,19 @@ void BuildClusterTable( void ) } } +// There's a version of this in host.cpp!!! Make sure that they match. +void GetPlatformMapPath( const char *pMapPath, char *pPlatformMapPath, int dxlevel, int maxLength ) +{ + Q_StripExtension( pMapPath, pPlatformMapPath, maxLength ); + +// if( dxlevel <= 60 ) +// { +// Q_strncat( pPlatformMapPath, "_dx60", maxLength, COPY_ALL_CHARACTERS ); +// } + + Q_strncat( pPlatformMapPath, ".bsp", maxLength, COPY_ALL_CHARACTERS ); +} + // There's a version of this in checksum_engine.cpp!!! Make sure that they match. static bool CRC_MapFile(CRC32_t *crcvalue, const char *pszFileName) { @@ -4019,7 +3979,7 @@ void ConvertPakFileContents( const char *pInFilename ) if ( !bConverted ) { // straight copy - AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false, IZip::eCompressionType_None ); + AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false ); } else { @@ -4027,7 +3987,7 @@ void ConvertPakFileContents( const char *pInFilename ) V_StripExtension( relativeName, relativeName, sizeof( relativeName ) ); V_strcat( relativeName, ".360", sizeof( relativeName ) ); V_strcat( relativeName, pExt, sizeof( relativeName ) ); - AddBufferToPak( newPakFile, relativeName, targetBuf.Base(), targetBuf.TellMaxPut(), false, IZip::eCompressionType_None ); + AddBufferToPak( newPakFile, relativeName, targetBuf.Base(), targetBuf.TellMaxPut(), false ); } if ( V_stristr( relativeName, ".hdr" ) || V_stristr( relativeName, "_hdr" ) ) @@ -4447,28 +4407,21 @@ bool CompressGameLump( dheader_t *pInBSPHeader, dheader_t *pOutBSPHeader, CUtlBu dgamelumpheader_t* pInGameLumpHeader = (dgamelumpheader_t*)(((byte *)pInBSPHeader) + pInBSPHeader->lumps[LUMP_GAME_LUMP].fileofs); dgamelump_t* pInGameLump = (dgamelump_t*)(pInGameLumpHeader + 1); - if ( IsX360() ) - { - byteSwap.ActivateByteSwapping( true ); - byteSwap.SwapFieldsToTargetEndian( pInGameLumpHeader ); - byteSwap.SwapFieldsToTargetEndian( pInGameLump, pInGameLumpHeader->lumpCount ); - } + byteSwap.ActivateByteSwapping( true ); + byteSwap.SwapFieldsToTargetEndian( pInGameLumpHeader ); + byteSwap.SwapFieldsToTargetEndian( pInGameLump, pInGameLumpHeader->lumpCount ); unsigned int newOffset = outputBuffer.TellPut(); - // Make room for gamelump header and gamelump structs, which we'll write at the end - outputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, sizeof( dgamelumpheader_t ) ); - outputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) ); + outputBuffer.Put( pInGameLumpHeader, sizeof( dgamelumpheader_t ) ); + outputBuffer.Put( pInGameLump, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) ); - // Start with input lumps, and fixup - dgamelumpheader_t sOutGameLumpHeader = *pInGameLumpHeader; - CUtlBuffer sOutGameLumpBuf; - sOutGameLumpBuf.Put( pInGameLump, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) ); - dgamelump_t *sOutGameLump = (dgamelump_t *)sOutGameLumpBuf.Base(); + dgamelumpheader_t* pOutGameLumpHeader = (dgamelumpheader_t*)((byte *)outputBuffer.Base() + newOffset); + dgamelump_t* pOutGameLump = (dgamelump_t*)(pOutGameLumpHeader + 1); // add a dummy terminal gamelump // purposely NOT updating the .filelen to reflect the compressed size, but leaving as original size // callers use the next entry offset to determine compressed size - sOutGameLumpHeader.lumpCount++; + pOutGameLumpHeader->lumpCount++; dgamelump_t dummyLump = { 0 }; outputBuffer.Put( &dummyLump, sizeof( dgamelump_t ) ); @@ -4477,130 +4430,62 @@ bool CompressGameLump( dheader_t *pInBSPHeader, dheader_t *pOutBSPHeader, CUtlBu CUtlBuffer inputBuffer; CUtlBuffer compressedBuffer; - sOutGameLump[i].fileofs = AlignBuffer( outputBuffer, 4 ); + pOutGameLump[i].fileofs = AlignBuffer( outputBuffer, 4 ); if ( pInGameLump[i].filelen ) { - if ( pInGameLump[i].flags & GAMELUMPFLAG_COMPRESSED ) - { - byte *pCompressedLump = ((byte *)pInBSPHeader) + pInGameLump[i].fileofs; - if ( CLZMA::IsCompressed( pCompressedLump ) ) - { - inputBuffer.EnsureCapacity( CLZMA::GetActualSize( pCompressedLump ) ); - unsigned int outSize = CLZMA::Uncompress( pCompressedLump, (unsigned char *)inputBuffer.Base() ); - inputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, outSize ); - if ( outSize != CLZMA::GetActualSize( pCompressedLump ) ) - { - Warning( "Decompressed size differs from header, BSP may be corrupt\n" ); - } - } - else - { - Assert( CLZMA::IsCompressed( pCompressedLump ) ); - Warning( "Unsupported BSP: Unrecognized compressed game lump\n" ); - } + inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pInGameLump[i].fileofs, pInGameLump[i].filelen, pInGameLump[i].filelen ); - } - else - { - inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pInGameLump[i].fileofs, - pInGameLump[i].filelen, pInGameLump[i].filelen ); - } - - bool bCompressed = pCompressFunc ? pCompressFunc( inputBuffer, compressedBuffer ) : false; + bool bCompressed = pCompressFunc( inputBuffer, compressedBuffer ); if ( bCompressed ) { - sOutGameLump[i].flags |= GAMELUMPFLAG_COMPRESSED; + pOutGameLump[i].flags |= GAMELUMPFLAG_COMPRESSED; outputBuffer.Put( compressedBuffer.Base(), compressedBuffer.TellPut() ); compressedBuffer.Purge(); } else { - // as is, clear compression flag from input lump - sOutGameLump[i].flags &= ~GAMELUMPFLAG_COMPRESSED; + // as is outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() ); } } } // fix the dummy terminal lump - int lastLump = sOutGameLumpHeader.lumpCount-1; - sOutGameLump[lastLump].fileofs = outputBuffer.TellPut(); + int lastLump = pOutGameLumpHeader->lumpCount-1; + pOutGameLump[lastLump].fileofs = outputBuffer.TellPut(); - if ( IsX360() ) - { - // fix the output for 360, swapping it back - byteSwap.SwapFieldsToTargetEndian( sOutGameLump, sOutGameLumpHeader.lumpCount ); - byteSwap.SwapFieldsToTargetEndian( &sOutGameLumpHeader ); - } + // fix the output for 360, swapping it back + byteSwap.SwapFieldsToTargetEndian( pOutGameLump, pOutGameLumpHeader->lumpCount ); + byteSwap.SwapFieldsToTargetEndian( pOutGameLumpHeader ); pOutBSPHeader->lumps[LUMP_GAME_LUMP].fileofs = newOffset; pOutBSPHeader->lumps[LUMP_GAME_LUMP].filelen = outputBuffer.TellPut() - newOffset; - // We set GAMELUMPFLAG_COMPRESSED and handle compression at the sub-lump level, this whole lump is not - // decompressable as a block. - pOutBSPHeader->lumps[LUMP_GAME_LUMP].uncompressedSize = 0; - - // Rewind to start and write lump headers - unsigned int endOffset = outputBuffer.TellPut(); - outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, newOffset ); - outputBuffer.Put( &sOutGameLumpHeader, sizeof( dgamelumpheader_t ) ); - outputBuffer.Put( sOutGameLumpBuf.Base(), sOutGameLumpBuf.TellPut() ); - outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, endOffset ); return true; } -//----------------------------------------------------------------------------- -// Compress callback for RepackBSP -//----------------------------------------------------------------------------- -bool RepackBSPCallback_LZMA( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer ) +bool CompressBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_t pCompressFunc ) { - if ( !inputBuffer.TellPut() ) - { - // nothing to do - return false; - } - - unsigned int originalSize = inputBuffer.TellPut() - inputBuffer.TellGet(); - unsigned int compressedSize = 0; - unsigned char *pCompressedOutput = LZMA_Compress( (unsigned char *)inputBuffer.Base() + inputBuffer.TellGet(), - originalSize, &compressedSize ); - if ( pCompressedOutput ) - { - outputBuffer.Put( pCompressedOutput, compressedSize ); - DevMsg( "Compressed bsp lump %u -> %u bytes\n", originalSize, compressedSize ); - free( pCompressedOutput ); - return true; - } - - return false; -} - + CByteswap byteSwap; -bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_t pCompressFunc, IZip::eCompressionType packfileCompression ) -{ dheader_t *pInBSPHeader = (dheader_t *)inputBuffer.Base(); - // The 360 swaps this header to disk. For some reason. - if ( pInBSPHeader->ident != ( IsX360() ? BigLong( IDBSPHEADER ) : IDBSPHEADER ) ) + if ( pInBSPHeader->ident != BigLong( IDBSPHEADER ) || !pCompressFunc ) { - Warning( "RepackBSP given invalid input data\n" ); + // only compress 360 bsp's return false; } - CByteswap byteSwap; - if ( IsX360() ) - { - // bsp is 360, swap the header back - byteSwap.ActivateByteSwapping( true ); - byteSwap.SwapFieldsToTargetEndian( pInBSPHeader ); - } + // bsp is 360, swap the header back + byteSwap.ActivateByteSwapping( true ); + byteSwap.SwapFieldsToTargetEndian( pInBSPHeader ); - unsigned int headerOffset = outputBuffer.TellPut(); + // output will be smaller, use input size as upper bound + outputBuffer.EnsureCapacity( inputBuffer.TellMaxPut() ); outputBuffer.Put( pInBSPHeader, sizeof( dheader_t ) ); - // This buffer grows dynamically, don't keep pointers to it around. Write out header at end. - dheader_t sOutBSPHeader = *pInBSPHeader; + dheader_t *pOutBSPHeader = (dheader_t *)outputBuffer.Base(); // must adhere to input lump's offset order and process according to that, NOT lump num // sort by offset order @@ -4619,13 +4504,12 @@ bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_ SortedLump_t *pSortedLump = &sortedLumps[i]; int lumpNum = pSortedLump->lumpNum; - // Should be set below, don't copy over old data - sOutBSPHeader.lumps[lumpNum].fileofs = 0; - sOutBSPHeader.lumps[lumpNum].filelen = 0; - // Only set by compressed lumps - sOutBSPHeader.lumps[lumpNum].uncompressedSize = 0; - - if ( pSortedLump->pLump->filelen ) // Otherwise its degenerate + if ( !pSortedLump->pLump->filelen ) + { + // degenerate + pOutBSPHeader->lumps[lumpNum].fileofs = 0; + } + else { int alignment = 4; if ( lumpNum == LUMP_PAKFILE ) @@ -4634,114 +4518,49 @@ bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_ } unsigned int newOffset = AlignBuffer( outputBuffer, alignment ); + // only set by compressed lumps, hides the uncompressed size + *((unsigned int *)pOutBSPHeader->lumps[lumpNum].fourCC) = 0; + CUtlBuffer inputBuffer; - if ( pSortedLump->pLump->uncompressedSize ) - { - byte *pCompressedLump = ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs; - if ( CLZMA::IsCompressed( pCompressedLump ) && pSortedLump->pLump->uncompressedSize == CLZMA::GetActualSize( pCompressedLump ) ) - { - inputBuffer.EnsureCapacity( CLZMA::GetActualSize( pCompressedLump ) ); - unsigned int outSize = CLZMA::Uncompress( pCompressedLump, (unsigned char *)inputBuffer.Base() ); - inputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, outSize ); - if ( outSize != pSortedLump->pLump->uncompressedSize ) - { - Warning( "Decompressed size differs from header, BSP may be corrupt\n" ); - } - } - else - { - Assert( CLZMA::IsCompressed( pCompressedLump ) && - pSortedLump->pLump->uncompressedSize == CLZMA::GetActualSize( pCompressedLump ) ); - Warning( "Unsupported BSP: Unrecognized compressed lump\n" ); - } - } - else - { - // Just use input - inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs, - pSortedLump->pLump->filelen, pSortedLump->pLump->filelen ); - } + inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs, pSortedLump->pLump->filelen, pSortedLump->pLump->filelen ); if ( lumpNum == LUMP_GAME_LUMP ) { // the game lump has to have each of its components individually compressed - CompressGameLump( pInBSPHeader, &sOutBSPHeader, outputBuffer, pCompressFunc ); + CompressGameLump( pInBSPHeader, pOutBSPHeader, outputBuffer, pCompressFunc ); } else if ( lumpNum == LUMP_PAKFILE ) { - IZip *newPakFile = IZip::CreateZip( NULL ); - IZip *oldPakFile = IZip::CreateZip( NULL ); - oldPakFile->ParseFromBuffer( inputBuffer.Base(), inputBuffer.Size() ); - - int id = -1; - int fileSize; - while ( 1 ) - { - char relativeName[MAX_PATH]; - id = GetNextFilename( oldPakFile, id, relativeName, sizeof( relativeName ), fileSize ); - if ( id == -1 ) - break; - - CUtlBuffer sourceBuf; - CUtlBuffer targetBuf; - - bool bOK = ReadFileFromPak( oldPakFile, relativeName, false, sourceBuf ); - if ( !bOK ) - { - Error( "Failed to load '%s' from lump pak for repacking.\n", relativeName ); - continue; - } - - AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false, packfileCompression ); - - DevMsg( "Repacking BSP: Created '%s' in lump pak\n", relativeName ); - } - - // save new pack to buffer - newPakFile->SaveToBuffer( outputBuffer ); - sOutBSPHeader.lumps[lumpNum].fileofs = newOffset; - sOutBSPHeader.lumps[lumpNum].filelen = outputBuffer.TellPut() - newOffset; - // Note that this *lump* is uncompressed, it just contains a packfile that uses compression, so we're - // not setting lumps[lumpNum].uncompressedSize - - IZip::ReleaseZip( oldPakFile ); - IZip::ReleaseZip( newPakFile ); + // add as is + pOutBSPHeader->lumps[lumpNum].fileofs = newOffset; + outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() ); } else { CUtlBuffer compressedBuffer; - bool bCompressed = pCompressFunc ? pCompressFunc( inputBuffer, compressedBuffer ) : false; + bool bCompressed = pCompressFunc( inputBuffer, compressedBuffer ); if ( bCompressed ) { - sOutBSPHeader.lumps[lumpNum].uncompressedSize = inputBuffer.TellPut(); - sOutBSPHeader.lumps[lumpNum].filelen = compressedBuffer.TellPut(); - sOutBSPHeader.lumps[lumpNum].fileofs = newOffset; + // placing the uncompressed size in the unused fourCC, will decode at runtime + *((unsigned int *)pOutBSPHeader->lumps[lumpNum].fourCC) = BigLong( inputBuffer.TellPut() ); + pOutBSPHeader->lumps[lumpNum].filelen = compressedBuffer.TellPut(); + pOutBSPHeader->lumps[lumpNum].fileofs = newOffset; outputBuffer.Put( compressedBuffer.Base(), compressedBuffer.TellPut() ); compressedBuffer.Purge(); } else { // add as is - sOutBSPHeader.lumps[lumpNum].fileofs = newOffset; - sOutBSPHeader.lumps[lumpNum].filelen = inputBuffer.TellPut(); + pOutBSPHeader->lumps[lumpNum].fileofs = newOffset; outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() ); } } } } - if ( IsX360() ) - { - // fix the output for 360, swapping it back - byteSwap.SetTargetBigEndian( true ); - byteSwap.SwapFieldsToTargetEndian( &sOutBSPHeader ); - } - - // Write out header - unsigned int endOffset = outputBuffer.TellPut(); - outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, headerOffset ); - outputBuffer.Put( &sOutBSPHeader, sizeof( sOutBSPHeader ) ); - outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, endOffset ); + // fix the output for 360, swapping it back + byteSwap.SetTargetBigEndian( true ); + byteSwap.SwapFieldsToTargetEndian( pOutBSPHeader ); return true; } @@ -4949,12 +4768,12 @@ bool SwapBSPFile( const char *pInFilename, const char *pOutFilename, bool bSwapO } CUtlBuffer outputBuffer; - if ( !RepackBSP( inputBuffer, outputBuffer, pCompressFunc, IZip::eCompressionType_None ) ) + if ( !CompressBSP( inputBuffer, outputBuffer, pCompressFunc ) ) { - Warning( "Error! Failed to compress BSP '%s'!\n", pOutFilename ); + Warning( "Error! Failed to compress BSP '%s'!\n", pOutFilename ); return false; } - + g_hBSPFile = SafeOpenWrite( pOutFilename ); if ( !g_hBSPFile ) { diff --git a/utils/common/bsplib.h b/utils/common/bsplib.h index f7e50f3f..80952ba9 100644 --- a/utils/common/bsplib.h +++ b/utils/common/bsplib.h @@ -14,7 +14,7 @@ #pragma once #endif -#include "zip_utils.h" + #include "bspfile.h" #include "utlvector.h" #include "utlstring.h" @@ -196,9 +196,8 @@ extern int g_PhysDispSize; IZip *GetPakFile( void ); IZip *GetSwapPakFile( void ); void ClearPakFile( IZip *pak ); -void AddFileToPak( IZip *pak, const char *pRelativeName, const char *fullpath, IZip::eCompressionType compressionType = IZip::eCompressionType_None ); -void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode, IZip::eCompressionType compressionType = IZip::eCompressionType_None ); -void AddDirToPak( IZip *pak, const char *pDirPath, const char *pPakPrefix = NULL ); +void AddFileToPak( IZip *pak, const char *pRelativeName, const char *fullpath ); +void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode ); bool FileExistsInPak( IZip *pak, const char *pRelativeName ); bool ReadFileFromPak( IZip *pak, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ); void RemoveFileFromPak( IZip *pak, const char *pRelativeName ); @@ -296,11 +295,7 @@ void WriteBSPFile( const char *filename, char *pUnused = NULL ); void PrintBSPFileSizes(void); void PrintBSPPackDirectory(void); void ReleasePakFileLumps(void); - -bool RepackBSPCallback_LZMA( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer ); -bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_t pCompressFunc, IZip::eCompressionType packfileCompression ); bool SwapBSPFile( const char *filename, const char *swapFilename, bool bSwapOnLoad, VTFConvertFunc_t pVTFConvertFunc, VHVFixupFunc_t pVHVFixupFunc, CompressFunc_t pCompressFunc ); - bool GetPakFileLump( const char *pBSPFilename, void **pPakData, int *pPakSize ); bool SetPakFileLump( const char *pBSPFilename, const char *pNewFilename, void *pPakData, int pakSize ); void WriteLumpToFile( char *filename, int lump ); @@ -387,6 +382,8 @@ extern CUtlVector g_ClusterLeaves; // Call this to build the mapping from cluster to leaves void BuildClusterTable( ); +void GetPlatformMapPath( const char *pMapPath, char *pPlatformMapPath, int dxlevel, int maxLength ); + void SetHDRMode( bool bHDR ); // ----------------------------------------------------------------------------- // diff --git a/utils/common/filesystem_tools.cpp b/utils/common/filesystem_tools.cpp index 9401c4ad..b1306c59 100644 --- a/utils/common/filesystem_tools.cpp +++ b/utils/common/filesystem_tools.cpp @@ -84,6 +84,9 @@ bool FileSystem_Init_Normal( const char *pFilename, FSInitType_t initType, bool if ( FileSystem_GetFileSystemDLLName( fileSystemDLLName, MAX_PATH, bSteam ) != FS_OK ) return false; + // If we're under Steam we need extra setup to let us find the proper modules + FileSystem_SetupSteamInstallPath(); + // Next, load the module, call Connect/Init. CFSLoadModuleInfo loadModuleInfo; loadModuleInfo.m_pFileSystemDLLName = fileSystemDLLName; diff --git a/utils/common/mpi_stats.cpp b/utils/common/mpi_stats.cpp index f5840cea..0d835a84 100644 --- a/utils/common/mpi_stats.cpp +++ b/utils/common/mpi_stats.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -39,9 +39,9 @@ flush privileges; -- SQL code to (re)create the tables. -- Master generates a unique job ID (in job_master_start) and sends it to workers. --- Each worker (and the master) make a job_worker_start, link it to the primary job ID, +-- Each worker (and the master) make a job_worker_start, link it to the primary job ID, -- get their own unique ID, which represents that process in that job. --- All JobWorkerID fields link to the JobWorkerID field in job_worker_start. +-- All JobWorkerID fields link to the JobWorkerID field in job_worker_start. -- NOTE: do a "use vrad" or "use vvis" first, depending on the DB you want to create. @@ -50,7 +50,7 @@ use vrad; drop table job_master_start; -create table job_master_start ( +create table job_master_start ( JobID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, index id( JobID, MachineName(5) ), BSPFilename TINYTEXT NOT NULL, StartTime TIMESTAMP NOT NULL, @@ -69,10 +69,10 @@ create table job_master_end ( drop table job_worker_start; create table job_worker_start ( - JobWorkerID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + JobWorkerID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, index index_jobid( JobID ), index index_jobworkerid( JobWorkerID ), - + JobID INTEGER UNSIGNED NOT NULL, -- links to job_master_start::JobID IsMaster BOOL NOT NULL, -- Set to 1 if this "worker" is the master process. RunningTimeMS INTEGER UNSIGNED NOT NULL default 0, @@ -165,7 +165,7 @@ void CMySQLQuery::Format( const char *pFormat, ... ) { #define QUERYTEXT_GROWSIZE 1024 - // This keeps growing the buffer and calling _vsnprintf until the buffer is + // This keeps growing the buffer and calling _vsnprintf until the buffer is // large enough to hold all the data. m_QueryText.SetSize( QUERYTEXT_GROWSIZE ); while ( 1 ) @@ -210,7 +210,7 @@ char* FormatStringForSQL( const char *pText ) { if ( *pCur == '\"' || *pCur == '\\' ) ++nChars; - + ++pCur; ++nChars; } @@ -221,7 +221,7 @@ char* FormatStringForSQL( const char *pText ) { if ( *pCur == '\"' || *pCur == '\\' ) pRetVal[i++] = '\\'; - + pRetVal[i++] = *pCur; ++pCur; } @@ -263,7 +263,7 @@ class CSQLDBCommand_WorkerStats : public CSQLDBCommandBase g_JobPrimaryID ); g_pSQL->Execute( query ); - + // Update the job_master_worker_stats stuff. for ( int i=1; i < nCurConnections; i++ ) { @@ -273,10 +273,10 @@ class CSQLDBCommand_WorkerStats : public CSQLDBCommandBase { Q_snprintf( query, sizeof( query ), "update " "job_worker_start set WorkerState=%d, NumWorkUnits=%d where JobWorkerID=%lu", - VMPI_IsProcConnected( i ), + VMPI_IsProcConnected( i ), (int) VMPI_GetNumWorkUnitsCompleted( i ), VMPI_GetJobWorkerID( i ) - ); + ); g_pSQL->Execute( query ); } } @@ -287,11 +287,11 @@ class CSQLDBCommand_WorkerStats : public CSQLDBCommandBase class CSQLDBCommand_JobMasterEnd : public CSQLDBCommandBase { public: - + virtual int RunCommand() { CMySQLQuery query; - query.Format( "insert into job_master_end values ( %lu, %d, %d, \"no errors\" )", g_JobPrimaryID, g_nWorkersConnected, g_nWorkersDisconnected ); + query.Format( "insert into job_master_end values ( %lu, %d, %d, \"no errors\" )", g_JobPrimaryID, g_nWorkersConnected, g_nWorkersDisconnected ); query.Execute( g_pSQL ); // Now set RunningTimeMS. @@ -306,14 +306,14 @@ class CSQLDBCommand_JobMasterEnd : public CSQLDBCommandBase void UpdateJobWorkerRunningTime() { unsigned long runningTimeMS = GetTickCount() - g_StatsStartTime; - + char curStage[256]; VMPI_GetCurrentStage( curStage, sizeof( curStage ) ); - + CMySQLQuery query; query.Format( "update job_worker_start set RunningTimeMS=%lu, CurrentStage=\"%s\", " - "Thread0WU=%d, Thread1WU=%d, Thread2WU=%d, Thread3WU=%d where JobWorkerID=%lu", - runningTimeMS, + "Thread0WU=%d, Thread1WU=%d, Thread2WU=%d, Thread3WU=%d where JobWorkerID=%lu", + runningTimeMS, curStage, (int) g_ThreadWUs[0], (int) g_ThreadWUs[1], @@ -327,7 +327,7 @@ void UpdateJobWorkerRunningTime() class CSQLDBCommand_GraphEntry : public CSQLDBCommandBase { public: - + CSQLDBCommand_GraphEntry( DWORD msTime, DWORD nBytesSent, DWORD nBytesReceived ) { m_msTime = msTime; @@ -339,12 +339,12 @@ class CSQLDBCommand_GraphEntry : public CSQLDBCommandBase { CMySQLQuery query; query.Format( "insert into graph_entry (JobWorkerID, MSSinceJobStart, BytesSent, BytesReceived) " - "values ( %lu, %lu, %lu, %lu )", - g_JobWorkerID, - m_msTime, - m_nBytesSent, + "values ( %lu, %lu, %lu, %lu )", + g_JobWorkerID, + m_msTime, + m_nBytesSent, m_nBytesReceived ); - + query.Execute( g_pSQL ); UpdateJobWorkerRunningTime(); @@ -363,7 +363,7 @@ class CSQLDBCommand_GraphEntry : public CSQLDBCommandBase class CSQLDBCommand_TextMessage : public CSQLDBCommandBase { public: - + CSQLDBCommand_TextMessage( const char *pText ) { m_pText = FormatStringForSQL( pText ); @@ -412,11 +412,11 @@ void PerfThread_SendSpewText() // Send the spew text to the database. CCriticalSectionLock csLock( &g_SpewTextCS ); csLock.Lock(); - + if ( g_SpewText.Count() > 0 ) { g_SpewText.AddToTail( 0 ); - + if ( g_bMPI_StatsTextOutput ) { g_pDB->AddCommandToQueue( new CSQLDBCommand_TextMessage( g_SpewText.Base() ), NULL ); @@ -434,7 +434,7 @@ void PerfThread_SendSpewText() g_pDB->AddCommandToQueue( new CSQLDBCommand_TextMessage( msg ), NULL ); } } - + g_SpewText.RemoveAll(); } @@ -448,11 +448,11 @@ void PerfThread_AddGraphEntry( DWORD startTicks, DWORD &lastSent, DWORD &lastRec DWORD curSent = g_nBytesSent + g_nMulticastBytesSent; DWORD curReceived = g_nBytesReceived + g_nMulticastBytesReceived; - g_pDB->AddCommandToQueue( - new CSQLDBCommand_GraphEntry( + g_pDB->AddCommandToQueue( + new CSQLDBCommand_GraphEntry( GetTickCount() - startTicks, - curSent - lastSent, - curReceived - lastReceived ), + curSent - lastSent, + curReceived - lastReceived ), NULL ); lastSent = curSent; @@ -477,8 +477,8 @@ DWORD WINAPI PerfThreadFn( LPVOID pParameter ) // If we're the master, update all the worker stats. if ( g_bMaster ) { - g_pDB->AddCommandToQueue( - new CSQLDBCommand_WorkerStats, + g_pDB->AddCommandToQueue( + new CSQLDBCommand_WorkerStats, NULL ); } } @@ -511,7 +511,7 @@ void UnloadMySQLWrapper() g_pSQL->Release(); g_pSQL = NULL; } - + Sys_UnloadModule( g_hMySQLDLL ); g_hMySQLDLL = NULL; } @@ -519,8 +519,8 @@ void UnloadMySQLWrapper() bool LoadMySQLWrapper( - const char *pHostName, - const char *pDBName, + const char *pHostName, + const char *pDBName, const char *pUserName ) { @@ -541,17 +541,17 @@ bool LoadMySQLWrapper( } -bool VMPI_Stats_Init_Master( - const char *pHostName, - const char *pDBName, +bool VMPI_Stats_Init_Master( + const char *pHostName, + const char *pDBName, const char *pUserName, - const char *pBSPFilename, + const char *pBSPFilename, unsigned long *pDBJobID ) { Assert( !g_pDB ); g_bMaster = true; - + // Connect the database. g_pDB = new CMySqlDatabase; if ( !g_pDB || !g_pDB->Initialize() || !LoadMySQLWrapper( pHostName, pDBName, pUserName ) ) @@ -569,7 +569,7 @@ bool VMPI_Stats_Init_Master( g_JobPrimaryID = 0; CMySQLQuery query; - query.Format( "insert into job_master_start ( BSPFilename, StartTime, MachineName, RunningTimeMS ) values ( \"%s\", null, \"%s\", %lu )", g_BSPFilename, g_MachineName, RUNNINGTIME_MS_SENTINEL ); + query.Format( "insert into job_master_start ( BSPFilename, StartTime, MachineName, RunningTimeMS ) values ( \"%s\", null, \"%s\", %lu )", g_BSPFilename, g_MachineName, RUNNINGTIME_MS_SENTINEL ); query.Execute( g_pSQL ); g_JobPrimaryID = g_pSQL->InsertID(); @@ -591,12 +591,12 @@ bool VMPI_Stats_Init_Master( bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const char *pUserName, unsigned long DBJobID ) { g_StatsStartTime = GetTickCount(); - + // If pDBServerName is null, then we're the master and we just want to make the job_worker_start entry. if ( pHostName ) { Assert( !g_pDB ); - + // Connect the database. g_pDB = new CMySqlDatabase; if ( !g_pDB || !g_pDB->Initialize() || !LoadMySQLWrapper( pHostName, pDBName, pUserName ) ) @@ -605,7 +605,7 @@ bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const c g_pDB = NULL; return false; } - + // Get our machine name to store in the database. DWORD size = sizeof( g_MachineName ); GetComputerName( g_MachineName, &size ); @@ -619,7 +619,7 @@ bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const c query.Format( "insert into job_worker_start ( JobID, CurrentStage, IsMaster, MachineName ) values ( %lu, \"none\", %d, \"%s\" )", g_JobPrimaryID, g_bMaster, g_MachineName ); query.Execute( g_pSQL ); - + g_JobWorkerID = g_pSQL->InsertID(); if ( g_JobWorkerID == 0 ) { @@ -638,7 +638,7 @@ bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const c 0, &g_PerfThreadID ); - return true; + return true; } @@ -650,7 +650,7 @@ void VMPI_Stats_Term() // Stop the thread. SetEvent( g_hPerfThreadExitEvent ); WaitForSingleObject( g_hPerfThread, INFINITE ); - + CloseHandle( g_hPerfThreadExitEvent ); g_hPerfThreadExitEvent = NULL; @@ -702,7 +702,7 @@ void GetDBInfo( const char *pDBInfoFilename, CDBInfo *pInfo ) char baseExeFilename[512]; if ( !GetModuleFileName( GetModuleHandle( NULL ), baseExeFilename, sizeof( baseExeFilename ) ) ) Error( "GetModuleFileName failed." ); - + // Look for the info file in the same directory as the exe. char dbInfoFilename[512]; Q_strncpy( dbInfoFilename, baseExeFilename, sizeof( dbInfoFilename ) ); @@ -721,8 +721,8 @@ void GetDBInfo( const char *pDBInfoFilename, CDBInfo *pInfo ) } if ( !ReadStringFromFile( fp, pInfo->m_HostName, sizeof( pInfo->m_HostName ) ) || - !ReadStringFromFile( fp, pInfo->m_DBName, sizeof( pInfo->m_DBName ) ) || - !ReadStringFromFile( fp, pInfo->m_UserName, sizeof( pInfo->m_UserName ) ) + !ReadStringFromFile( fp, pInfo->m_DBName, sizeof( pInfo->m_DBName ) ) || + !ReadStringFromFile( fp, pInfo->m_UserName, sizeof( pInfo->m_UserName ) ) ) { Error( "%s is not a valid database info file.\n", dbInfoFilename ); @@ -750,12 +750,12 @@ void RunJobWatchApp( char *pCmdLine ) if ( s1 || s2 ) { // Get rid of the last slash. - s1 = max( s1, s2 ); + s1 = MAX( s1, s2 ); s1[0] = 0; - - if ( !CreateProcess( - NULL, - pCmdLine, + + if ( !CreateProcess( + NULL, + pCmdLine, NULL, // security NULL, TRUE, @@ -772,9 +772,9 @@ void RunJobWatchApp( char *pCmdLine ) } -void StatsDB_InitStatsDatabase( - int argc, - char **argv, +void StatsDB_InitStatsDatabase( + int argc, + char **argv, const char *pDBInfoFilename ) { // Did they disable the stats database? @@ -794,14 +794,14 @@ void StatsDB_InitStatsDatabase( Warning( "VMPI_Stats_Init_Master( %s, %s, %s ) failed.\n", dbInfo.m_HostName, dbInfo.m_DBName, dbInfo.m_UserName ); // Tell the workers not to use stats. - dbInfo.m_HostName[0] = 0; + dbInfo.m_HostName[0] = 0; } char cmdLine[2048]; Q_snprintf( cmdLine, sizeof( cmdLine ), "vmpi_job_watch -JobID %d", jobPrimaryID ); - + Msg( "\nTo watch this job, run this command line:\n%s\n\n", cmdLine ); - + if ( VMPI_IsParamUsed( mpi_Job_Watch ) ) { // Convenience thing to automatically launch the job watch for this job. @@ -817,7 +817,7 @@ void StatsDB_InitStatsDatabase( CDBInfo dbInfo; unsigned long jobPrimaryID; RecvDBInfo( &dbInfo, &jobPrimaryID ); - + if ( dbInfo.m_HostName[0] != 0 ) { if ( !VMPI_Stats_Init_Worker( dbInfo.m_HostName, dbInfo.m_DBName, dbInfo.m_UserName, jobPrimaryID ) ) @@ -836,4 +836,4 @@ unsigned long StatsDB_GetUniqueJobID() unsigned long VMPI_Stats_GetJobWorkerID() { return g_JobWorkerID; -} \ No newline at end of file +} diff --git a/utils/common/threads.cpp b/utils/common/threads.cpp index 74e457a9..28f0894c 100644 --- a/utils/common/threads.cpp +++ b/utils/common/threads.cpp @@ -19,7 +19,13 @@ #include "threads.h" #include "pacifier.h" +#ifdef MAPBASE +// This was suggested in that Source 2013 pull request that fixed Vrad. +// I trust their judgement on this. +#define MAX_THREADS 32 +#else #define MAX_THREADS 16 +#endif class CRunThreadsData diff --git a/utils/common/threads.h b/utils/common/threads.h index 0908b67a..7d6beb9f 100644 --- a/utils/common/threads.h +++ b/utils/common/threads.h @@ -16,9 +16,15 @@ #pragma once +#ifdef MAPBASE +// This was suggested in that Source 2013 pull request that fixed Vrad. +// I trust their judgement on this. +#define MAX_TOOL_THREADS 32 +#else // Arrays that are indexed by thread should always be MAX_TOOL_THREADS+1 // large so THREADINDEX_MAIN can be used from the main thread. #define MAX_TOOL_THREADS 16 +#endif #define THREADINDEX_MAIN (MAX_TOOL_THREADS) diff --git a/utils/lzma/C/7z.h b/utils/lzma/C/7z.h deleted file mode 100644 index ca4a2233..00000000 --- a/utils/lzma/C/7z.h +++ /dev/null @@ -1,216 +0,0 @@ -/* 7z.h -- 7z interface -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_H -#define __7Z_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define k7zStartHeaderSize 0x20 -#define k7zSignatureSize 6 - -extern Byte k7zSignature[k7zSignatureSize]; - -typedef struct -{ - const Byte *Data; - size_t Size; -} CSzData; - -/* CSzCoderInfo & CSzFolder support only default methods */ - -typedef struct -{ - size_t PropsOffset; - UInt32 MethodID; - Byte NumInStreams; - Byte NumOutStreams; - Byte PropsSize; -} CSzCoderInfo; - -typedef struct -{ - UInt32 InIndex; - UInt32 OutIndex; -} CSzBindPair; - -#define SZ_NUM_CODERS_IN_FOLDER_MAX 4 -#define SZ_NUM_BINDS_IN_FOLDER_MAX 3 -#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4 -#define SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX 4 - -typedef struct -{ - UInt32 NumCoders; - UInt32 NumBindPairs; - UInt32 NumPackStreams; - UInt32 MainOutStream; - UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; - CSzBindPair BindPairs[SZ_NUM_BINDS_IN_FOLDER_MAX]; - CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; - UInt64 CodersUnpackSizes[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX]; -} CSzFolder; - -/* -typedef struct -{ - size_t CodersDataOffset; - size_t UnpackSizeDataOffset; - // UInt32 StartCoderUnpackSizesIndex; - UInt32 StartPackStreamIndex; - // UInt32 IndexOfMainOutStream; -} CSzFolder2; -*/ - -SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes); - -typedef struct -{ - UInt32 Low; - UInt32 High; -} CNtfsFileTime; - -typedef struct -{ - Byte *Defs; /* MSB 0 bit numbering */ - UInt32 *Vals; -} CSzBitUi32s; - -typedef struct -{ - Byte *Defs; /* MSB 0 bit numbering */ - // UInt64 *Vals; - CNtfsFileTime *Vals; -} CSzBitUi64s; - -#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) - -#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) - -typedef struct -{ - UInt32 NumPackStreams; - UInt32 NumFolders; - - UInt64 *PackPositions; // NumPackStreams + 1 - CSzBitUi32s FolderCRCs; - - size_t *FoCodersOffsets; - size_t *FoSizesOffsets; - // UInt32 StartCoderUnpackSizesIndex; - UInt32 *FoStartPackStreamIndex; - - // CSzFolder2 *Folders; // +1 item for sum values - Byte *CodersData; - Byte *UnpackSizesData; - size_t UnpackSizesDataSize; - // UInt64 *CoderUnpackSizes; -} CSzAr; - - -SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *stream, UInt64 startPos, - Byte *outBuffer, size_t outSize, - ISzAlloc *allocMain); - -/* - SzExtract extracts file from archive - - *outBuffer must be 0 before first call for each new archive. - - Extracting cache: - If you need to decompress more than one file, you can send - these values from previous call: - *blockIndex, - *outBuffer, - *outBufferSize - You can consider "*outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - If you use external function, you can declare these 3 cache variables - (blockIndex, outBuffer, outBufferSize) as static in that external function. - - Free *outBuffer and set *outBuffer to 0, if you want to flush cache. -*/ - -typedef struct -{ - CSzAr db; - - UInt64 startPosAfterHeader; - UInt64 dataPos; - - UInt32 NumFiles; - - UInt64 *UnpackPositions; - // Byte *IsEmptyFiles; - Byte *IsDirs; - CSzBitUi32s CRCs; - - CSzBitUi32s Attribs; - // CSzBitUi32s Parents; - CSzBitUi64s MTime; - CSzBitUi64s CTime; - - // UInt32 *FolderStartPackStreamIndex; - UInt32 *FolderStartFileIndex; // + 1 - UInt32 *FileIndexToFolderIndexMap; - - size_t *FileNameOffsets; /* in 2-byte steps */ - Byte *FileNames; /* UTF-16-LE */ -} CSzArEx; - -#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i)) - -#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) - -void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); - -/* -if dest == NULL, the return value specifies the required size of the buffer, - in 16-bit characters, including the null-terminating character. -if dest != NULL, the return value specifies the number of 16-bit characters that - are written to the dest, including the null-terminating character. */ - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); - -/* -size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex); -UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); -*/ - -SRes SzArEx_Extract( - const CSzArEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - - -/* -SzArEx_Open Errors: -SZ_ERROR_NO_ARCHIVE -SZ_ERROR_ARCHIVE -SZ_ERROR_UNSUPPORTED -SZ_ERROR_MEM -SZ_ERROR_CRC -SZ_ERROR_INPUT_EOF -SZ_ERROR_FAIL -*/ - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, - ISzAlloc *allocMain, ISzAlloc *allocTemp); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/7zAlloc.h b/utils/lzma/C/7zAlloc.h deleted file mode 100644 index 3344e937..00000000 --- a/utils/lzma/C/7zAlloc.h +++ /dev/null @@ -1,15 +0,0 @@ -/* 7zAlloc.h -- Allocation functions -2010-10-29 : Igor Pavlov : Public domain */ - -#ifndef __7Z_ALLOC_H -#define __7Z_ALLOC_H - -#include - -void *SzAlloc(void *p, size_t size); -void SzFree(void *p, void *address); - -void *SzAllocTemp(void *p, size_t size); -void SzFreeTemp(void *p, void *address); - -#endif diff --git a/utils/lzma/C/7zArcIn.c b/utils/lzma/C/7zArcIn.c deleted file mode 100644 index cdca6564..00000000 --- a/utils/lzma/C/7zArcIn.c +++ /dev/null @@ -1,1839 +0,0 @@ -/* 7zArcIn.c -- 7z Input functions -2014-06-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7z.h" -#include "7zBuf.h" -#include "7zCrc.h" -#include "CpuArch.h" - -#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ - if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } - -#define k7zMajorVersion 0 - -enum EIdEnum -{ - k7zIdEnd, - k7zIdHeader, - k7zIdArchiveProperties, - k7zIdAdditionalStreamsInfo, - k7zIdMainStreamsInfo, - k7zIdFilesInfo, - k7zIdPackInfo, - k7zIdUnpackInfo, - k7zIdSubStreamsInfo, - k7zIdSize, - k7zIdCRC, - k7zIdFolder, - k7zIdCodersUnpackSize, - k7zIdNumUnpackStream, - k7zIdEmptyStream, - k7zIdEmptyFile, - k7zIdAnti, - k7zIdName, - k7zIdCTime, - k7zIdATime, - k7zIdMTime, - k7zIdWinAttrib, - k7zIdComment, - k7zIdEncodedHeader, - k7zIdStartPos, - k7zIdDummy - // k7zNtSecure, - // k7zParent, - // k7zIsReal -}; - -Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - -#define NUM_FOLDER_CODERS_MAX 32 -#define NUM_CODER_STREAMS_MAX 32 - -/* -static int SzFolder_FindBindPairForInStream(const CSzFolder *p, UInt32 inStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].InIndex == inStreamIndex) - return i; - return -1; -} -*/ - -#define SzBitUi32s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; } - -static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc) -{ - MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc); - MY_ALLOC(UInt32, p->Vals, num, alloc); - return SZ_OK; -} - -void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->Defs); p->Defs = 0; - IAlloc_Free(alloc, p->Vals); p->Vals = 0; -} - -#define SzBitUi64s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; } - -void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->Defs); p->Defs = 0; - IAlloc_Free(alloc, p->Vals); p->Vals = 0; -} - -static void SzAr_Init(CSzAr *p) -{ - p->NumPackStreams = 0; - p->NumFolders = 0; - p->PackPositions = 0; - SzBitUi32s_Init(&p->FolderCRCs); - // p->Folders = 0; - p->FoCodersOffsets = 0; - p->FoSizesOffsets = 0; - p->FoStartPackStreamIndex = 0; - - p->CodersData = 0; - // p->CoderUnpackSizes = 0; - p->UnpackSizesData = 0; -} - -static void SzAr_Free(CSzAr *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->UnpackSizesData); - IAlloc_Free(alloc, p->CodersData); - // IAlloc_Free(alloc, p->CoderUnpackSizes); - - IAlloc_Free(alloc, p->PackPositions); - - // IAlloc_Free(alloc, p->Folders); - IAlloc_Free(alloc, p->FoCodersOffsets); - IAlloc_Free(alloc, p->FoSizesOffsets); - IAlloc_Free(alloc, p->FoStartPackStreamIndex); - - SzBitUi32s_Free(&p->FolderCRCs, alloc); - - SzAr_Init(p); -} - - -void SzArEx_Init(CSzArEx *p) -{ - SzAr_Init(&p->db); - p->NumFiles = 0; - p->dataPos = 0; - // p->Files = 0; - p->UnpackPositions = 0; - // p->IsEmptyFiles = 0; - p->IsDirs = 0; - // p->FolderStartPackStreamIndex = 0; - // p->PackStreamStartPositions = 0; - p->FolderStartFileIndex = 0; - p->FileIndexToFolderIndexMap = 0; - p->FileNameOffsets = 0; - p->FileNames = 0; - SzBitUi32s_Init(&p->CRCs); - SzBitUi32s_Init(&p->Attribs); - // SzBitUi32s_Init(&p->Parents); - SzBitUi64s_Init(&p->MTime); - SzBitUi64s_Init(&p->CTime); -} - -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) -{ - // IAlloc_Free(alloc, p->FolderStartPackStreamIndex); - // IAlloc_Free(alloc, p->PackStreamStartPositions); - IAlloc_Free(alloc, p->FolderStartFileIndex); - IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); - - IAlloc_Free(alloc, p->FileNameOffsets); - IAlloc_Free(alloc, p->FileNames); - - SzBitUi64s_Free(&p->CTime, alloc); - SzBitUi64s_Free(&p->MTime, alloc); - SzBitUi32s_Free(&p->CRCs, alloc); - // SzBitUi32s_Free(&p->Parents, alloc); - SzBitUi32s_Free(&p->Attribs, alloc); - IAlloc_Free(alloc, p->IsDirs); - // IAlloc_Free(alloc, p->IsEmptyFiles); - IAlloc_Free(alloc, p->UnpackPositions); - // IAlloc_Free(alloc, p->Files); - - SzAr_Free(&p->db, alloc); - SzArEx_Init(p); -} - -static int TestSignatureCandidate(Byte *testBytes) -{ - size_t i; - for (i = 0; i < k7zSignatureSize; i++) - if (testBytes[i] != k7zSignature[i]) - return 0; - return 1; -} - -#define SzData_Clear(p) { (p)->Data = 0; (p)->Size = 0; } - -static SRes SzReadByte(CSzData *sd, Byte *b) -{ - if (sd->Size == 0) - return SZ_ERROR_ARCHIVE; - sd->Size--; - *b = *sd->Data++; - return SZ_OK; -} - -#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++; -#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) -#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++; - -#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } -#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } - -#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \ - dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4); - -static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) -{ - Byte firstByte, mask; - unsigned i; - UInt32 v; - - SZ_READ_BYTE(firstByte); - if ((firstByte & 0x80) == 0) - { - *value = firstByte; - return SZ_OK; - } - SZ_READ_BYTE(v); - if ((firstByte & 0x40) == 0) - { - *value = (((UInt32)firstByte & 0x3F) << 8) | v; - return SZ_OK; - } - SZ_READ_BYTE(mask); - *value = v | ((UInt32)mask << 8); - mask = 0x20; - for (i = 2; i < 8; i++) - { - Byte b; - if ((firstByte & mask) == 0) - { - UInt64 highPart = firstByte & (mask - 1); - *value |= (highPart << (8 * i)); - return SZ_OK; - } - SZ_READ_BYTE(b); - *value |= ((UInt64)b << (8 * i)); - mask >>= 1; - } - return SZ_OK; -} - -/* -static MY_NO_INLINE const Byte *SzReadNumbers(const Byte *data, const Byte *dataLim, UInt64 *values, UInt32 num) -{ - for (; num != 0; num--) - { - Byte firstByte; - Byte mask; - - unsigned i; - UInt32 v; - UInt64 value; - - if (data == dataLim) - return NULL; - firstByte = *data++; - - if ((firstByte & 0x80) == 0) - { - *values++ = firstByte; - continue; - } - if (data == dataLim) - return NULL; - v = *data++; - if ((firstByte & 0x40) == 0) - { - *values++ = (((UInt32)firstByte & 0x3F) << 8) | v; - continue; - } - if (data == dataLim) - return NULL; - value = v | ((UInt32)*data++ << 8); - mask = 0x20; - for (i = 2; i < 8; i++) - { - if ((firstByte & mask) == 0) - { - UInt64 highPart = firstByte & (mask - 1); - value |= (highPart << (8 * i)); - break; - } - if (data == dataLim) - return NULL; - value |= ((UInt64)*data++ << (8 * i)); - mask >>= 1; - } - *values++ = value; - } - return data; -} -*/ - -static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) -{ - Byte firstByte; - UInt64 value64; - if (sd->Size == 0) - return SZ_ERROR_ARCHIVE; - firstByte = *sd->Data; - if ((firstByte & 0x80) == 0) - { - *value = firstByte; - sd->Data++; - sd->Size--; - return SZ_OK; - } - RINOK(ReadNumber(sd, &value64)); - if (value64 >= (UInt32)0x80000000 - 1) - return SZ_ERROR_UNSUPPORTED; - if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4))) - return SZ_ERROR_UNSUPPORTED; - *value = (UInt32)value64; - return SZ_OK; -} - -#define ReadID(sd, value) ReadNumber(sd, value) - -static SRes SkipData(CSzData *sd) -{ - UInt64 size; - RINOK(ReadNumber(sd, &size)); - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, size); - return SZ_OK; -} - -static SRes WaitId(CSzData *sd, UInt64 id) -{ - for (;;) - { - UInt64 type; - RINOK(ReadID(sd, &type)); - if (type == id) - return SZ_OK; - if (type == k7zIdEnd) - return SZ_ERROR_ARCHIVE; - RINOK(SkipData(sd)); - } -} - -static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v) -{ - UInt32 numBytes = (numItems + 7) >> 3; - if (numBytes > sd->Size) - return SZ_ERROR_ARCHIVE; - *v = sd->Data; - SKIP_DATA(sd, numBytes); - return SZ_OK; -} - -static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) -{ - Byte b = 0; - unsigned m = 0; - UInt32 sum = 0; - for (; numItems != 0; numItems--) - { - if (m == 0) - { - b = *bits++; - m = 8; - } - m--; - sum += ((b >> m) & 1); - } - return sum ; -} - -static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc) -{ - Byte allAreDefined; - UInt32 i; - Byte *v2; - UInt32 numBytes = (numItems + 7) >> 3; - RINOK(SzReadByte(sd, &allAreDefined)); - if (allAreDefined == 0) - { - if (numBytes > sd->Size) - return SZ_ERROR_ARCHIVE; - MY_ALLOC(Byte, *v, numBytes, alloc); - memcpy(*v, sd->Data, numBytes); - SKIP_DATA(sd, numBytes); - return SZ_OK; - } - MY_ALLOC(Byte, *v, numBytes, alloc); - v2 = *v; - for (i = 0; i < numBytes; i++) - v2[i] = 0xFF; - { - unsigned numBits = (unsigned)numItems & 7; - if (numBits != 0) - v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); - } - return SZ_OK; -} - -static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) -{ - UInt32 i; - CSzData sd; - UInt32 *vals; - const Byte *defs; - MY_ALLOC(UInt32, crcs->Vals, numItems, alloc); - sd = *sd2; - defs = crcs->Defs; - vals = crcs->Vals; - for (i = 0; i < numItems; i++) - if (SzBitArray_Check(defs, i)) - { - SZ_READ_32(vals[i]); - } - else - vals[i] = 0; - *sd2 = sd; - return SZ_OK; -} - -static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) -{ - SzBitUi32s_Free(crcs, alloc); - RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); - return ReadUi32s(sd, numItems, crcs, alloc); -} - -static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) -{ - Byte allAreDefined; - UInt32 numDefined = numItems; - RINOK(SzReadByte(sd, &allAreDefined)); - if (!allAreDefined) - { - size_t numBytes = (numItems + 7) >> 3; - if (numBytes > sd->Size) - return SZ_ERROR_ARCHIVE; - numDefined = CountDefinedBits(sd->Data, numItems); - SKIP_DATA(sd, numBytes); - } - if (numDefined > (sd->Size >> 2)) - return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, (size_t)numDefined * 4); - return SZ_OK; -} - -static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc) -{ - RINOK(SzReadNumber32(sd, &p->NumPackStreams)); - - RINOK(WaitId(sd, k7zIdSize)); - MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc); - { - UInt64 sum = 0; - UInt32 i; - UInt32 numPackStreams = p->NumPackStreams; - for (i = 0; i < numPackStreams; i++) - { - UInt64 packSize; - p->PackPositions[i] = sum; - RINOK(ReadNumber(sd, &packSize)); - sum += packSize; - if (sum < packSize) - return SZ_ERROR_ARCHIVE; - } - p->PackPositions[i] = sum; - } - - for (;;) - { - UInt64 type; - RINOK(ReadID(sd, &type)); - if (type == k7zIdEnd) - return SZ_OK; - if (type == k7zIdCRC) - { - /* CRC of packed streams is unused now */ - RINOK(SkipBitUi32s(sd, p->NumPackStreams)); - continue; - } - RINOK(SkipData(sd)); - } -} - -/* -static SRes SzReadSwitch(CSzData *sd) -{ - Byte external; - RINOK(SzReadByte(sd, &external)); - return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; -} -*/ - -#define SZ_NUM_IN_STREAMS_IN_FOLDER_MAX 16 - -SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes) -{ - UInt32 numCoders, numBindPairs, numPackStreams, i; - UInt32 numInStreams = 0, numOutStreams = 0; - const Byte *dataStart = sd->Data; - Byte inStreamUsed[SZ_NUM_IN_STREAMS_IN_FOLDER_MAX]; - - RINOK(SzReadNumber32(sd, &numCoders)); - if (numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) - return SZ_ERROR_UNSUPPORTED; - f->NumCoders = numCoders; - - for (i = 0; i < numCoders; i++) - { - Byte mainByte; - CSzCoderInfo *coder = f->Coders + i; - unsigned idSize, j; - UInt64 id; - RINOK(SzReadByte(sd, &mainByte)); - if ((mainByte & 0xC0) != 0) - return SZ_ERROR_UNSUPPORTED; - idSize = (unsigned)(mainByte & 0xF); - if (idSize > sizeof(id)) - return SZ_ERROR_UNSUPPORTED; - if (idSize > sd->Size) - return SZ_ERROR_ARCHIVE; - id = 0; - for (j = 0; j < idSize; j++) - { - id = ((id << 8) | *sd->Data); - sd->Data++; - sd->Size--; - } - if (id > (UInt32)0xFFFFFFFF) - return SZ_ERROR_UNSUPPORTED; - coder->MethodID = (UInt32)id; - - coder->NumInStreams = 1; - coder->NumOutStreams = 1; - coder->PropsOffset = 0; - coder->PropsSize = 0; - - if ((mainByte & 0x10) != 0) - { - UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - if (numStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - coder->NumInStreams = (Byte)numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - if (numStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - coder->NumOutStreams = (Byte)numStreams; - } - if ((mainByte & 0x20) != 0) - { - UInt32 propsSize = 0; - RINOK(SzReadNumber32(sd, &propsSize)); - if (propsSize >= 0x40) - return SZ_ERROR_UNSUPPORTED; - if (propsSize > sd->Size) - return SZ_ERROR_ARCHIVE; - coder->PropsOffset = sd->Data - dataStart; - coder->PropsSize = (Byte)propsSize; - sd->Data += (size_t)propsSize; - sd->Size -= (size_t)propsSize; - } - numInStreams += coder->NumInStreams; - numOutStreams += coder->NumOutStreams; - } - - if (numOutStreams == 0) - return SZ_ERROR_UNSUPPORTED; - - f->NumBindPairs = numBindPairs = numOutStreams - 1; - if (numInStreams < numBindPairs) - return SZ_ERROR_ARCHIVE; - if (numInStreams > SZ_NUM_IN_STREAMS_IN_FOLDER_MAX) - return SZ_ERROR_UNSUPPORTED; - f->MainOutStream = 0; - f->NumPackStreams = numPackStreams = numInStreams - numBindPairs; - if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) - return SZ_ERROR_UNSUPPORTED; - for (i = 0; i < numInStreams; i++) - inStreamUsed[i] = False; - if (numBindPairs != 0) - { - Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX]; - - if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX) - return SZ_ERROR_UNSUPPORTED; - - for (i = 0; i < numOutStreams; i++) - outStreamUsed[i] = False; - - for (i = 0; i < numBindPairs; i++) - { - CSzBindPair *bp = f->BindPairs + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); - if (bp->InIndex >= numInStreams) - return SZ_ERROR_ARCHIVE; - inStreamUsed[bp->InIndex] = True; - RINOK(SzReadNumber32(sd, &bp->OutIndex)); - if (bp->OutIndex >= numInStreams) - return SZ_ERROR_ARCHIVE; - outStreamUsed[bp->OutIndex] = True; - } - for (i = 0; i < numOutStreams; i++) - if (!outStreamUsed[i]) - { - f->MainOutStream = i; - break; - } - if (i == numOutStreams) - return SZ_ERROR_ARCHIVE; - } - - if (numPackStreams == 1) - { - for (i = 0; i < numInStreams; i++) - if (!inStreamUsed[i]) - break; - if (i == numInStreams) - return SZ_ERROR_ARCHIVE; - f->PackStreams[0] = i; - } - else - for (i = 0; i < numPackStreams; i++) - { - RINOK(SzReadNumber32(sd, f->PackStreams + i)); - } - - for (i = 0; i < numOutStreams; i++) - { - RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i)); - } - - return SZ_OK; -} - -static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) -{ - CSzData sd; - sd = *sd2; - for (; num != 0; num--) - { - Byte firstByte, mask; - unsigned i; - SZ_READ_BYTE_2(firstByte); - if ((firstByte & 0x80) == 0) - continue; - if ((firstByte & 0x40) == 0) - { - if (sd.Size == 0) - return SZ_ERROR_ARCHIVE; - sd.Size--; - sd.Data++; - continue; - } - mask = 0x20; - for (i = 2; i < 8 && (firstByte & mask) != 0; i++) - mask >>= 1; - if (i > sd.Size) - return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, i); - } - *sd2 = sd; - return SZ_OK; -} - -#define k_InStreamUsed_MAX 64 -#define k_OutStreamUsed_MAX 64 - -static SRes ReadUnpackInfo(CSzAr *p, - CSzData *sd2, - UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, - ISzAlloc *alloc) -{ - CSzData sd; - Byte inStreamUsed[k_InStreamUsed_MAX]; - Byte outStreamUsed[k_OutStreamUsed_MAX]; - UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex; - const Byte *startBufPtr; - Byte external; - - RINOK(WaitId(sd2, k7zIdFolder)); - RINOK(SzReadNumber32(sd2, &numFolders)); - if (p->NumFolders > numFoldersMax) - return SZ_ERROR_UNSUPPORTED; - p->NumFolders = numFolders; - - SZ_READ_BYTE_SD(sd2, external); - if (external == 0) - sd = *sd2; - else - { - UInt32 index; - SzReadNumber32(sd2, &index); - if (index >= numTempBufs) - return SZ_ERROR_ARCHIVE; - sd.Data = tempBufs[index].data; - sd.Size = tempBufs[index].size; - } - - MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc); - MY_ALLOC(size_t, p->FoSizesOffsets, (size_t)numFolders + 1, alloc); - MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc); - - startBufPtr = sd.Data; - - packStreamIndex = 0; - numCodersOutStreams = 0; - - for (fo = 0; fo < numFolders; fo++) - { - UInt32 numCoders, ci, numInStreams = 0, numOutStreams = 0; - - p->FoCodersOffsets[fo] = sd.Data - startBufPtr; - RINOK(SzReadNumber32(&sd, &numCoders)); - if (numCoders > NUM_FOLDER_CODERS_MAX) - return SZ_ERROR_UNSUPPORTED; - - for (ci = 0; ci < numCoders; ci++) - { - Byte mainByte; - unsigned idSize; - UInt32 coderInStreams, coderOutStreams; - - SZ_READ_BYTE_2(mainByte); - if ((mainByte & 0xC0) != 0) - return SZ_ERROR_UNSUPPORTED; - idSize = (mainByte & 0xF); - if (idSize > 8) - return SZ_ERROR_UNSUPPORTED; - if (idSize > sd.Size) - return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, idSize); - - coderInStreams = 1; - coderOutStreams = 1; - if ((mainByte & 0x10) != 0) - { - RINOK(SzReadNumber32(&sd, &coderInStreams)); - RINOK(SzReadNumber32(&sd, &coderOutStreams)); - if (coderInStreams > NUM_CODER_STREAMS_MAX || - coderOutStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - } - numInStreams += coderInStreams; - numOutStreams += coderOutStreams; - if ((mainByte & 0x20) != 0) - { - UInt32 propsSize; - RINOK(SzReadNumber32(&sd, &propsSize)); - if (propsSize > sd.Size) - return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, propsSize); - } - } - - { - UInt32 indexOfMainStream = 0; - UInt32 numPackStreams = 1; - if (numOutStreams != 1 || numInStreams != 1) - { - UInt32 i; - UInt32 numBindPairs = numOutStreams - 1; - if (numOutStreams == 0 || numInStreams < numBindPairs) - return SZ_ERROR_ARCHIVE; - - if (numInStreams > k_InStreamUsed_MAX || - numOutStreams > k_OutStreamUsed_MAX) - return SZ_ERROR_UNSUPPORTED; - - for (i = 0; i < numInStreams; i++) - inStreamUsed[i] = False; - for (i = 0; i < numOutStreams; i++) - outStreamUsed[i] = False; - - for (i = 0; i < numBindPairs; i++) - { - UInt32 index; - RINOK(SzReadNumber32(&sd, &index)); - if (index >= numInStreams || inStreamUsed[index]) - return SZ_ERROR_ARCHIVE; - inStreamUsed[index] = True; - RINOK(SzReadNumber32(&sd, &index)); - if (index >= numInStreams || outStreamUsed[index]) - return SZ_ERROR_ARCHIVE; - outStreamUsed[index] = True; - } - - numPackStreams = numInStreams - numBindPairs; - - if (numPackStreams != 1) - for (i = 0; i < numPackStreams; i++) - { - UInt32 temp; - RINOK(SzReadNumber32(&sd, &temp)); - if (temp >= numInStreams) - return SZ_ERROR_ARCHIVE; - } - - for (i = 0; i < numOutStreams; i++) - if (!outStreamUsed[i]) - { - indexOfMainStream = i; - break; - } - - if (i == numOutStreams) - return SZ_ERROR_ARCHIVE; - } - p->FoStartPackStreamIndex[fo] = packStreamIndex; - p->FoSizesOffsets[fo] = (numOutStreams << 8) | indexOfMainStream; - numCodersOutStreams += numOutStreams; - if (numCodersOutStreams < numOutStreams) - return SZ_ERROR_UNSUPPORTED; - packStreamIndex += numPackStreams; - if (packStreamIndex < numPackStreams) - return SZ_ERROR_UNSUPPORTED; - if (packStreamIndex > p->NumPackStreams) - return SZ_ERROR_ARCHIVE; - } - } - - { - size_t dataSize = sd.Data - startBufPtr; - p->FoStartPackStreamIndex[fo] = packStreamIndex; - p->FoCodersOffsets[fo] = dataSize; - MY_ALLOC(Byte, p->CodersData, dataSize, alloc); - memcpy(p->CodersData, startBufPtr, dataSize); - } - - if (external != 0) - { - if (sd.Size != 0) - return SZ_ERROR_ARCHIVE; - sd = *sd2; - } - - RINOK(WaitId(&sd, k7zIdCodersUnpackSize)); - - // MY_ALLOC(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc); - { - size_t dataSize = sd.Size; - /* - UInt32 i; - for (i = 0; i < numCodersOutStreams; i++) - { - RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)); - } - */ - RINOK(SkipNumbers(&sd, numCodersOutStreams)); - dataSize -= sd.Size; - MY_ALLOC(Byte, p->UnpackSizesData, dataSize, alloc); - memcpy(p->UnpackSizesData, sd.Data - dataSize, dataSize); - p->UnpackSizesDataSize = dataSize; - /* - const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams); - if (data == NULL) - return SZ_ERROR_ARCHIVE; - sd.Size = sd.Data + sd.Size - data; - sd.Data = data; - */ - } - - for (;;) - { - UInt64 type; - RINOK(ReadID(&sd, &type)); - if (type == k7zIdEnd) - { - *sd2 = sd; - return SZ_OK; - } - if (type == k7zIdCRC) - { - RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)); - continue; - } - RINOK(SkipData(&sd)); - } -} - -typedef struct -{ - UInt32 NumTotalSubStreams; - UInt32 NumSubDigests; - CSzData sdNumSubStreams; - CSzData sdSizes; - CSzData sdCRCs; -} CSubStreamInfo; - -#define SzUi32IndexMax (((UInt32)1 << 31) - 2) - -static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) -{ - UInt64 type = 0; - UInt32 i; - UInt32 numSubDigests = 0; - UInt32 numFolders = p->NumFolders; - UInt32 numUnpackStreams = numFolders; - UInt32 numUnpackSizesInData = 0; - - for (;;) - { - RINOK(ReadID(sd, &type)); - if (type == k7zIdNumUnpackStream) - { - ssi->sdNumSubStreams.Data = sd->Data; - numUnpackStreams = 0; - numSubDigests = 0; - for (i = 0; i < numFolders; i++) - { - UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - if (numUnpackStreams > numUnpackStreams + numStreams) - return SZ_ERROR_UNSUPPORTED; - numUnpackStreams += numStreams; - if (numStreams != 0) - numUnpackSizesInData += (numStreams - 1); - if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i)) - numSubDigests += numStreams; - } - ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data; - continue; - } - if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd) - break; - RINOK(SkipData(sd)); - } - - if (!ssi->sdNumSubStreams.Data) - { - numSubDigests = numFolders; - if (p->FolderCRCs.Defs) - numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders); - } - - ssi->NumTotalSubStreams = numUnpackStreams; - ssi->NumSubDigests = numSubDigests; - - if (type == k7zIdSize) - { - ssi->sdSizes.Data = sd->Data; - RINOK(SkipNumbers(sd, numUnpackSizesInData)); - ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data; - RINOK(ReadID(sd, &type)); - } - - for (;;) - { - if (type == k7zIdEnd) - return SZ_OK; - if (type == k7zIdCRC) - { - ssi->sdCRCs.Data = sd->Data; - RINOK(SkipBitUi32s(sd, numSubDigests)); - ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data; - } - else - { - RINOK(SkipData(sd)); - } - RINOK(ReadID(sd, &type)); - } -} - -static SRes SzReadStreamsInfo(CSzAr *p, - CSzData *sd, - UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, - UInt64 *dataOffset, - CSubStreamInfo *ssi, - ISzAlloc *alloc) -{ - UInt64 type; - - SzData_Clear(&ssi->sdSizes); - SzData_Clear(&ssi->sdCRCs); - SzData_Clear(&ssi->sdNumSubStreams); - - *dataOffset = 0; - RINOK(ReadID(sd, &type)); - if (type == k7zIdPackInfo) - { - RINOK(ReadNumber(sd, dataOffset)); - RINOK(ReadPackInfo(p, sd, alloc)); - RINOK(ReadID(sd, &type)); - } - if (type == k7zIdUnpackInfo) - { - RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)); - RINOK(ReadID(sd, &type)); - } - if (type == k7zIdSubStreamsInfo) - { - RINOK(ReadSubStreamsInfo(p, sd, ssi)); - RINOK(ReadID(sd, &type)); - } - else - { - ssi->NumTotalSubStreams = p->NumFolders; - // ssi->NumSubDigests = 0; - } - - return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED); -} - -static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, - CSzData *sd, - CBuf *tempBufs, - UInt32 numFoldersMax, - UInt64 baseOffset, - CSzAr *p, - ISzAlloc *allocTemp) -{ - UInt64 dataStartPos; - UInt32 fo; - CSubStreamInfo ssi; - CSzData sdCodersUnpSizes; - - RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)); - - dataStartPos += baseOffset; - if (p->NumFolders == 0) - return SZ_ERROR_ARCHIVE; - - sdCodersUnpSizes.Data = p->UnpackSizesData; - sdCodersUnpSizes.Size = p->UnpackSizesDataSize; - for (fo = 0; fo < p->NumFolders; fo++) - Buf_Init(tempBufs + fo); - for (fo = 0; fo < p->NumFolders; fo++) - { - CBuf *tempBuf = tempBufs + fo; - // folder = p->Folders; - // unpackSize = SzAr_GetFolderUnpackSize(p, 0); - UInt32 mix = (UInt32)p->FoSizesOffsets[fo]; - UInt32 mainIndex = mix & 0xFF; - UInt32 numOutStreams = mix >> 8; - UInt32 si; - UInt64 unpackSize = 0; - p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData; - for (si = 0; si < numOutStreams; si++) - { - UInt64 curSize; - RINOK(ReadNumber(&sdCodersUnpSizes, &curSize)); - if (si == mainIndex) - { - unpackSize = curSize; - break; - } - } - if (si == numOutStreams) - return SZ_ERROR_FAIL; - if ((size_t)unpackSize != unpackSize) - return SZ_ERROR_MEM; - if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) - return SZ_ERROR_MEM; - } - p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData; - - for (fo = 0; fo < p->NumFolders; fo++) - { - const CBuf *tempBuf = tempBufs + fo; - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)); - if (SzBitWithVals_Check(&p->FolderCRCs, fo)) - if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo]) - return SZ_ERROR_CRC; - } - return SZ_OK; -} - -static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets) -{ - size_t pos = 0; - *offsets++ = 0; - if (numFiles == 0) - return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE; - if (data[size - 2] != 0 || data[size - 1] != 0) - return SZ_ERROR_ARCHIVE; - do - { - const Byte *p; - if (pos == size) - return SZ_ERROR_ARCHIVE; - for (p = data + pos; - #ifdef _WIN32 - *(const UInt16 *)p != 0 - #else - p[0] != 0 || p[1] != 0 - #endif - ; p += 2); - pos = p - data + 2; - *offsets++ = (pos >> 1); - } - while (--numFiles); - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; -} - -static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, - CSzData *sd2, - const CBuf *tempBufs, UInt32 numTempBufs, - ISzAlloc *alloc) -{ - CSzData sd; - UInt32 i; - CNtfsFileTime *vals; - Byte *defs; - Byte external; - RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)); - RINOK(SzReadByte(sd2, &external)); - if (external == 0) - sd = *sd2; - else - { - UInt32 index; - SzReadNumber32(sd2, &index); - if (index >= numTempBufs) - return SZ_ERROR_ARCHIVE; - sd.Data = tempBufs[index].data; - sd.Size = tempBufs[index].size; - } - MY_ALLOC(CNtfsFileTime, p->Vals, num, alloc); - vals = p->Vals; - defs = p->Defs; - for (i = 0; i < num; i++) - if (SzBitArray_Check(defs, i)) - { - if (sd.Size < 8) - return SZ_ERROR_ARCHIVE; - vals[i].Low = GetUi32(sd.Data); - vals[i].High = GetUi32(sd.Data + 4); - SKIP_DATA2(sd, 8); - } - else - vals[i].High = vals[i].Low = 0; - if (external == 0) - *sd2 = sd; - return SZ_OK; -} - -#define NUM_ADDITIONAL_STREAMS_MAX 8 - -static SRes SzReadHeader2( - CSzArEx *p, /* allocMain */ - CSzData *sd, - // Byte **emptyStreamVector, /* allocTemp */ - // Byte **emptyFileVector, /* allocTemp */ - // Byte **lwtVector, /* allocTemp */ - ILookInStream *inStream, - CBuf *tempBufs, - UInt32 *numTempBufs, - ISzAlloc *allocMain, - ISzAlloc *allocTemp - ) -{ - UInt64 type; - UInt32 numFiles = 0; - UInt32 numEmptyStreams = 0; - UInt32 i; - CSubStreamInfo ssi; - const Byte *emptyStreams = 0; - const Byte *emptyFiles = 0; - - SzData_Clear(&ssi.sdSizes); - SzData_Clear(&ssi.sdCRCs); - SzData_Clear(&ssi.sdNumSubStreams); - - ssi.NumSubDigests = 0; - ssi.NumTotalSubStreams = 0; - - RINOK(ReadID(sd, &type)); - - if (type == k7zIdArchiveProperties) - { - for (;;) - { - UInt64 type; - RINOK(ReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(SkipData(sd)); - } - RINOK(ReadID(sd, &type)); - } - - // if (type == k7zIdAdditionalStreamsInfo) return SZ_ERROR_UNSUPPORTED; - - if (type == k7zIdAdditionalStreamsInfo) - { - CSzAr tempAr; - SRes res; - UInt32 numTempFolders; - - SzAr_Init(&tempAr); - res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX, - p->startPosAfterHeader, &tempAr, allocTemp); - numTempFolders = tempAr.NumFolders; - SzAr_Free(&tempAr, allocTemp); - if (res != SZ_OK) - return res; - *numTempBufs = numTempFolders; - RINOK(ReadID(sd, &type)); - } - - if (type == k7zIdMainStreamsInfo) - { - RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, - &p->dataPos, &ssi, allocMain)); - p->dataPos += p->startPosAfterHeader; - RINOK(ReadID(sd, &type)); - } - - if (type == k7zIdEnd) - { - // *sd2 = sd; - return SZ_OK; - } - if (type != k7zIdFilesInfo) - return SZ_ERROR_ARCHIVE; - - RINOK(SzReadNumber32(sd, &numFiles)); - p->NumFiles = numFiles; - - for (;;) - { - UInt64 type; - UInt64 size; - RINOK(ReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(ReadNumber(sd, &size)); - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - if ((UInt64)(int)type != type) - { - SKIP_DATA(sd, size); - } - else switch((int)type) - { - case k7zIdName: - { - size_t namesSize; - const Byte *namesData; - Byte external; - - SZ_READ_BYTE(external); - if (external == 0) - { - namesSize = (size_t)size - 1; - namesData = sd->Data; - } - else - { - UInt32 index; - SzReadNumber32(sd, &index); - if (index >= *numTempBufs) - return SZ_ERROR_ARCHIVE; - namesData = (tempBufs)[index].data; - namesSize = (tempBufs)[index].size; - } - - if ((namesSize & 1) != 0) - return SZ_ERROR_ARCHIVE; - MY_ALLOC(Byte, p->FileNames, namesSize, allocMain); - MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); - memcpy(p->FileNames, namesData, namesSize); - RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) - if (external == 0) - { - SKIP_DATA(sd, namesSize); - } - break; - } - case k7zIdEmptyStream: - { - RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); - numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); - break; - } - case k7zIdEmptyFile: - { - RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)); - break; - } - case k7zIdWinAttrib: - { - Byte external; - CSzData sdSwitch; - CSzData *sdPtr; - SzBitUi32s_Free(&p->Attribs, allocMain); - RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)); - - SZ_READ_BYTE(external); - if (external == 0) - sdPtr = sd; - else - { - UInt32 index; - SzReadNumber32(sd, &index); - if (index >= *numTempBufs) - return SZ_ERROR_ARCHIVE; - sdSwitch.Data = (tempBufs)[index].data; - sdSwitch.Size = (tempBufs)[index].size; - sdPtr = &sdSwitch; - } - RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)); - break; - } - /* - case k7zParent: - { - SzBitUi32s_Free(&p->Parents, allocMain); - RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain)); - RINOK(SzReadSwitch(sd)); - RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain)); - break; - } - */ - case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; - case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; - default: - { - SKIP_DATA(sd, size); - } - } - } - - if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams) - return SZ_ERROR_ARCHIVE; - - for (;;) - { - UInt64 type; - RINOK(ReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(SkipData(sd)); - } - - { - UInt32 emptyFileIndex = 0; - - UInt32 folderIndex = 0; - UInt32 indexInFolder = 0; - UInt64 unpackPos = 0; - const Byte *digestsDefs = 0; - const Byte *digestsVals = 0; - UInt32 digestsValsIndex = 0; - UInt32 digestIndex; - Byte allDigestsDefined = 0; - UInt32 curNumSubStreams = (UInt32)(Int32)-1; - Byte isDirMask = 0; - Byte crcMask = 0; - Byte mask = 0x80; - // size_t unpSizesOffset = 0; - CSzData sdCodersUnpSizes; - sdCodersUnpSizes.Data = p->db.UnpackSizesData; - sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize; - - MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain); - MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain); - MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain); - MY_ALLOC(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain); - - RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)); - - if (ssi.sdCRCs.Size != 0) - { - RINOK(SzReadByte(&ssi.sdCRCs, &allDigestsDefined)); - if (allDigestsDefined) - digestsVals = ssi.sdCRCs.Data; - else - { - size_t numBytes = (ssi.NumSubDigests + 7) >> 3; - digestsDefs = ssi.sdCRCs.Data; - digestsVals = digestsDefs + numBytes; - } - } - - digestIndex = 0; - for (i = 0; i < numFiles; i++, mask >>= 1) - { - if (mask == 0) - { - UInt32 byteIndex = (i - 1) >> 3; - p->IsDirs[byteIndex] = isDirMask; - p->CRCs.Defs[byteIndex] = crcMask; - isDirMask = 0; - crcMask = 0; - mask = 0x80; - } - - p->UnpackPositions[i] = unpackPos; - p->CRCs.Vals[i] = 0; - // p->CRCs.Defs[i] = 0; - if (emptyStreams && SzBitArray_Check(emptyStreams , i)) - { - if (!emptyFiles || !SzBitArray_Check(emptyFiles, emptyFileIndex)) - isDirMask |= mask; - emptyFileIndex++; - if (indexInFolder == 0) - { - p->FileIndexToFolderIndexMap[i] = (UInt32)-1; - continue; - } - } - if (indexInFolder == 0) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: Loop for skipping empty folders - */ - for (;;) - { - if (folderIndex >= p->db.NumFolders) - return SZ_ERROR_ARCHIVE; - p->FolderStartFileIndex[folderIndex] = i; - if (curNumSubStreams == (UInt32)(Int32)-1); - { - curNumSubStreams = 1; - if (ssi.sdNumSubStreams.Data != 0) - { - RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &curNumSubStreams)); - } - } - if (curNumSubStreams != 0) - break; - curNumSubStreams = (UInt32)(Int32)-1; - folderIndex++; // check it - } - } - p->FileIndexToFolderIndexMap[i] = folderIndex; - if (emptyStreams && SzBitArray_Check(emptyStreams , i)) - continue; - - indexInFolder++; - if (indexInFolder >= curNumSubStreams) - { - UInt64 folderUnpackSize = 0; - UInt64 startFolderUnpackPos; - { - UInt32 mix = (UInt32)p->db.FoSizesOffsets[folderIndex]; - UInt32 mainIndex = mix & 0xFF; - UInt32 numOutStreams = mix >> 8; - UInt32 si; - p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData; - for (si = 0; si < numOutStreams; si++) - { - UInt64 curSize; - RINOK(ReadNumber(&sdCodersUnpSizes, &curSize)); - if (si == mainIndex) - { - folderUnpackSize = curSize; - break; - } - } - if (si == numOutStreams) - return SZ_ERROR_FAIL; - } - - // UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); - startFolderUnpackPos = p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]; - if (folderUnpackSize < unpackPos - startFolderUnpackPos) - return SZ_ERROR_ARCHIVE; - unpackPos = startFolderUnpackPos + folderUnpackSize; - - if (curNumSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i)) - { - p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; - crcMask |= mask; - } - else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) - { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; - crcMask |= mask; - } - folderIndex++; - indexInFolder = 0; - } - else - { - UInt64 v; - RINOK(ReadNumber(&ssi.sdSizes, &v)); - unpackPos += v; - if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) - { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; - crcMask |= mask; - } - } - } - if (mask != 0x80) - { - UInt32 byteIndex = (i - 1) >> 3; - p->IsDirs[byteIndex] = isDirMask; - p->CRCs.Defs[byteIndex] = crcMask; - } - p->UnpackPositions[i] = unpackPos; - p->FolderStartFileIndex[folderIndex] = i; - p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData; - } - return SZ_OK; -} - -static SRes SzReadHeader( - CSzArEx *p, - CSzData *sd, - ILookInStream *inStream, - ISzAlloc *allocMain - ,ISzAlloc *allocTemp - ) -{ - // Byte *emptyStreamVector = 0; - // Byte *emptyFileVector = 0; - // Byte *lwtVector = 0; - UInt32 i; - UInt32 numTempBufs = 0; - SRes res; - CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX]; - - for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) - Buf_Init(tempBufs + i); - // SzBitUi32s_Init(&digests); - - res = SzReadHeader2(p, sd, - // &emptyStreamVector, - // &emptyFileVector, - // &lwtVector, - inStream, - tempBufs, &numTempBufs, - allocMain, allocTemp - ); - - for (i = 0; i < numTempBufs; i++) - Buf_Free(tempBufs + i, allocTemp); - - // IAlloc_Free(allocTemp, emptyStreamVector); - // IAlloc_Free(allocTemp, emptyFileVector); - // IAlloc_Free(allocTemp, lwtVector); - - RINOK(res); - { - if (sd->Size != 0) - return SZ_ERROR_FAIL; - } - - return res; -} - -/* -static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex) -{ - const CSzFolder2 *f = p->Folders + folderIndex; - - // return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream]; - - UInt32 si; - CSzData sdCodersUnpSizes; - sdCodersUnpSizes.Data = p->UnpackSizesData + f->UnpackSizeDataOffset; - sdCodersUnpSizes.Size = p->UnpackSizesDataSize - f->UnpackSizeDataOffset; - for (si = 0; si < numOutStreams; si++) - { - UInt64 curSize; - ReadNumber(&sdCodersUnpSizes, &curSize); - if (si == mainIndex) - return curSize; - } - return 0; -} -*/ - -static SRes SzArEx_Open2( - CSzArEx *p, - ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - Byte header[k7zStartHeaderSize]; - Int64 startArcPos; - UInt64 nextHeaderOffset, nextHeaderSize; - size_t nextHeaderSizeT; - UInt32 nextHeaderCRC; - CBuf buf; - SRes res; - - startArcPos = 0; - RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); - - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); - - if (!TestSignatureCandidate(header)) - return SZ_ERROR_NO_ARCHIVE; - if (header[6] != k7zMajorVersion) - return SZ_ERROR_UNSUPPORTED; - - nextHeaderOffset = GetUi64(header + 12); - nextHeaderSize = GetUi64(header + 20); - nextHeaderCRC = GetUi32(header + 28); - - p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; - - if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) - return SZ_ERROR_CRC; - - nextHeaderSizeT = (size_t)nextHeaderSize; - if (nextHeaderSizeT != nextHeaderSize) - return SZ_ERROR_MEM; - if (nextHeaderSizeT == 0) - return SZ_OK; - if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || - nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) - return SZ_ERROR_NO_ARCHIVE; - - { - Int64 pos = 0; - RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); - if ((UInt64)pos < startArcPos + nextHeaderOffset || - (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || - (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) - return SZ_ERROR_INPUT_EOF; - } - - RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); - - if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) - return SZ_ERROR_MEM; - - res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT); - if (res == SZ_OK) - { - res = SZ_ERROR_ARCHIVE; - if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC) - { - CSzData sd; - UInt64 type; - sd.Data = buf.data; - sd.Size = buf.size; - res = ReadID(&sd, &type); - if (res == SZ_OK && type == k7zIdEncodedHeader) - { - CSzAr tempAr; - CBuf tempBuf; - Buf_Init(&tempBuf); - - SzAr_Init(&tempAr); - res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp); - SzAr_Free(&tempAr, allocTemp); - - if (res != SZ_OK) - { - Buf_Free(&tempBuf, allocTemp); - } - else - { - Buf_Free(&buf, allocTemp); - buf.data = tempBuf.data; - buf.size = tempBuf.size; - sd.Data = buf.data; - sd.Size = buf.size; - res = ReadID(&sd, &type); - } - } - if (res == SZ_OK) - { - if (type == k7zIdHeader) - { - CSzData sd2; - int ttt; - for (ttt = 0; ttt < 1; ttt++) - // for (ttt = 0; ttt < 40000; ttt++) - { - SzArEx_Free(p, allocMain); - sd2 = sd; - res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp - ); - if (res != SZ_OK) - break; - } - - // res = SzReadHeader(p, &sd, allocMain, allocTemp); - } - else - res = SZ_ERROR_UNSUPPORTED; - } - } - } - Buf_Free(&buf, allocTemp); - return res; -} - -// #include - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, - ISzAlloc *allocMain, ISzAlloc *allocTemp) -{ - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); - if (res != SZ_OK) - SzArEx_Free(p, allocMain); - // printf ("\nrrr=%d\n", rrr); - return res; -} - -SRes SzArEx_Extract( - const CSzArEx *p, - ILookInStream *inStream, - UInt32 fileIndex, - UInt32 *blockIndex, - Byte **tempBuf, - size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; - SRes res = SZ_OK; - *offset = 0; - *outSizeProcessed = 0; - if (folderIndex == (UInt32)-1) - { - IAlloc_Free(allocMain, *tempBuf); - *blockIndex = folderIndex; - *tempBuf = 0; - *outBufferSize = 0; - return SZ_OK; - } - - if (*tempBuf == 0 || *blockIndex != folderIndex) - { - // UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); - UInt64 unpackSizeSpec = - p->UnpackPositions[p->FolderStartFileIndex[folderIndex + 1]] - - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]; - size_t unpackSize = (size_t)unpackSizeSpec; - - if (unpackSize != unpackSizeSpec) - return SZ_ERROR_MEM; - *blockIndex = folderIndex; - IAlloc_Free(allocMain, *tempBuf); - *tempBuf = 0; - - // RINOK(LookInStream_SeekTo(inStream, startOffset)); - - if (res == SZ_OK) - { - *outBufferSize = unpackSize; - if (unpackSize != 0) - { - *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize); - if (*tempBuf == 0) - res = SZ_ERROR_MEM; - } - if (res == SZ_OK) - { - res = SzAr_DecodeFolder(&p->db, folderIndex, - inStream, - p->dataPos, - *tempBuf, unpackSize, allocTemp); - if (res == SZ_OK) - { - if (SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex)) - { - if (CrcCalc(*tempBuf, unpackSize) != p->db.FolderCRCs.Vals[folderIndex]) - res = SZ_ERROR_CRC; - } - } - } - } - } - if (res == SZ_OK) - { - UInt64 unpackPos = p->UnpackPositions[fileIndex]; - *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]); - *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos); - if (*offset + *outSizeProcessed > *outBufferSize) - return SZ_ERROR_FAIL; - if (SzBitWithVals_Check(&p->CRCs, fileIndex) && CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex]) - res = SZ_ERROR_CRC; - } - return res; -} - - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) -{ - size_t offs = p->FileNameOffsets[fileIndex]; - size_t len = p->FileNameOffsets[fileIndex + 1] - offs; - if (dest != 0) - { - size_t i; - const Byte *src = p->FileNames + offs * 2; - for (i = 0; i < len; i++) - dest[i] = GetUi16(src + i * 2); - } - return len; -} - -/* -size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex) -{ - size_t len; - if (!p->FileNameOffsets) - return 1; - len = 0; - for (;;) - { - UInt32 parent = (UInt32)(Int32)-1; - len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; - if SzBitWithVals_Check(&p->Parents, fileIndex) - parent = p->Parents.Vals[fileIndex]; - if (parent == (UInt32)(Int32)-1) - return len; - fileIndex = parent; - } -} - -UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest) -{ - Bool needSlash; - if (!p->FileNameOffsets) - { - *(--dest) = 0; - return dest; - } - needSlash = False; - for (;;) - { - UInt32 parent = (UInt32)(Int32)-1; - size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; - SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen); - if (needSlash) - *(dest - 1) = '/'; - needSlash = True; - dest -= curLen; - - if SzBitWithVals_Check(&p->Parents, fileIndex) - parent = p->Parents.Vals[fileIndex]; - if (parent == (UInt32)(Int32)-1) - return dest; - fileIndex = parent; - } -} -*/ diff --git a/utils/lzma/C/7zBuf.c b/utils/lzma/C/7zBuf.c deleted file mode 100644 index 089a5c4f..00000000 --- a/utils/lzma/C/7zBuf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* 7zBuf.c -- Byte Buffer -2013-01-21 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zBuf.h" - -void Buf_Init(CBuf *p) -{ - p->data = 0; - p->size = 0; -} - -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) -{ - p->size = 0; - if (size == 0) - { - p->data = 0; - return 1; - } - p->data = (Byte *)alloc->Alloc(alloc, size); - if (p->data != 0) - { - p->size = size; - return 1; - } - return 0; -} - -void Buf_Free(CBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; -} diff --git a/utils/lzma/C/7zBuf.h b/utils/lzma/C/7zBuf.h deleted file mode 100644 index 65f1d7a7..00000000 --- a/utils/lzma/C/7zBuf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* 7zBuf.h -- Byte Buffer -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_BUF_H -#define __7Z_BUF_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -typedef struct -{ - Byte *data; - size_t size; -} CBuf; - -void Buf_Init(CBuf *p); -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); -void Buf_Free(CBuf *p, ISzAlloc *alloc); - -typedef struct -{ - Byte *data; - size_t size; - size_t pos; -} CDynBuf; - -void DynBuf_Construct(CDynBuf *p); -void DynBuf_SeekToBeg(CDynBuf *p); -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/7zBuf2.c b/utils/lzma/C/7zBuf2.c deleted file mode 100644 index e14e65f4..00000000 --- a/utils/lzma/C/7zBuf2.c +++ /dev/null @@ -1,48 +0,0 @@ -/* 7zBuf2.c -- Byte Buffer -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zBuf.h" - -void DynBuf_Construct(CDynBuf *p) -{ - p->data = 0; - p->size = 0; - p->pos = 0; -} - -void DynBuf_SeekToBeg(CDynBuf *p) -{ - p->pos = 0; -} - -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) -{ - if (size > p->size - p->pos) - { - size_t newSize = p->pos + size; - Byte *data; - newSize += newSize / 4; - data = (Byte *)alloc->Alloc(alloc, newSize); - if (data == 0) - return 0; - p->size = newSize; - memcpy(data, p->data, p->pos); - alloc->Free(alloc, p->data); - p->data = data; - } - memcpy(p->data + p->pos, buf, size); - p->pos += size; - return 1; -} - -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; - p->pos = 0; -} diff --git a/utils/lzma/C/7zCrc.c b/utils/lzma/C/7zCrc.c deleted file mode 100644 index 503e3591..00000000 --- a/utils/lzma/C/7zCrc.c +++ /dev/null @@ -1,85 +0,0 @@ -/* 7zCrc.c -- CRC32 init -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zCrc.h" -#include "CpuArch.h" - -#define kCrcPoly 0xEDB88320 - -#ifdef MY_CPU_X86_OR_AMD64 - #define CRC_NUM_TABLES 8 - UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); -#elif defined(MY_CPU_LE) - #define CRC_NUM_TABLES 4 -#else - #define CRC_NUM_TABLES 5 - #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -#endif - -#ifndef MY_CPU_BE - UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -#endif - -typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); - -CRC_FUNC g_CrcUpdate; -UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; - -UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) -{ - return g_CrcUpdate(v, data, size, g_CrcTable); -} - -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) -{ - return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; -} - -void MY_FAST_CALL CrcGenerateTable() -{ - UInt32 i; - for (i = 0; i < 256; i++) - { - UInt32 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - g_CrcTable[i] = r; - } - for (; i < 256 * CRC_NUM_TABLES; i++) - { - UInt32 r = g_CrcTable[i - 256]; - g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); - } - - #ifdef MY_CPU_LE - - g_CrcUpdate = CrcUpdateT4; - - #if CRC_NUM_TABLES == 8 - if (!CPU_Is_InOrder()) - g_CrcUpdate = CrcUpdateT8; - #endif - - #else - { - #ifndef MY_CPU_BE - UInt32 k = 1; - if (*(const Byte *)&k == 1) - g_CrcUpdate = CrcUpdateT4; - else - #endif - { - for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) - { - UInt32 x = g_CrcTable[i - 256]; - g_CrcTable[i] = CRC_UINT32_SWAP(x); - } - g_CrcUpdate = CrcUpdateT1_BeT4; - } - } - #endif -} diff --git a/utils/lzma/C/7zCrc.h b/utils/lzma/C/7zCrc.h deleted file mode 100644 index 8fd57958..00000000 --- a/utils/lzma/C/7zCrc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* 7zCrc.h -- CRC32 calculation -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_CRC_H -#define __7Z_CRC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -extern UInt32 g_CrcTable[]; - -/* Call CrcGenerateTable one time before other CRC functions */ -void MY_FAST_CALL CrcGenerateTable(void); - -#define CRC_INIT_VAL 0xFFFFFFFF -#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) -#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/7zCrcOpt.c b/utils/lzma/C/7zCrcOpt.c deleted file mode 100644 index ce132b5d..00000000 --- a/utils/lzma/C/7zCrcOpt.c +++ /dev/null @@ -1,66 +0,0 @@ -/* 7zCrcOpt.c -- CRC32 calculation -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -#ifndef MY_CPU_BE - -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)p; - v = - table[0x300 + (v & 0xFF)] ^ - table[0x200 + ((v >> 8) & 0xFF)] ^ - table[0x100 + ((v >> 16) & 0xFF)] ^ - table[0x000 + ((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - return CrcUpdateT4(v, data, size, table); -} - -#endif - - -#ifndef MY_CPU_LE - -#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - -UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - v = CRC_UINT32_SWAP(v); - table += 0x100; - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)p; - v = - table[0x000 + (v & 0xFF)] ^ - table[0x100 + ((v >> 8) & 0xFF)] ^ - table[0x200 + ((v >> 16) & 0xFF)] ^ - table[0x300 + ((v >> 24))]; - } - table -= 0x100; - v = CRC_UINT32_SWAP(v); - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#endif diff --git a/utils/lzma/C/7zDec.c b/utils/lzma/C/7zDec.c deleted file mode 100644 index 2c7c2cd0..00000000 --- a/utils/lzma/C/7zDec.c +++ /dev/null @@ -1,493 +0,0 @@ -/* 7zDec.c -- Decoding from 7z folder -2014-06-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -/* #define _7ZIP_PPMD_SUPPPORT */ - -#include "7z.h" - -#include "Bcj2.h" -#include "Bra.h" -#include "CpuArch.h" -#include "LzmaDec.h" -#include "Lzma2Dec.h" -#ifdef _7ZIP_PPMD_SUPPPORT -#include "Ppmd7.h" -#endif - -#define k_Copy 0 -#define k_LZMA2 0x21 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_PPC 0x03030205 -#define k_ARM 0x03030501 -#define k_ARMT 0x03030701 -#define k_SPARC 0x03030805 -#define k_BCJ2 0x0303011B - -#ifdef _7ZIP_PPMD_SUPPPORT - -#define k_PPMD 0x30401 - -typedef struct -{ - IByteIn p; - const Byte *cur; - const Byte *end; - const Byte *begin; - UInt64 processed; - Bool extra; - SRes res; - ILookInStream *inStream; -} CByteInToLook; - -static Byte ReadByte(void *pp) -{ - CByteInToLook *p = (CByteInToLook *)pp; - if (p->cur != p->end) - return *p->cur++; - if (p->res == SZ_OK) - { - size_t size = p->cur - p->begin; - p->processed += size; - p->res = p->inStream->Skip(p->inStream, size); - size = (1 << 25); - p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); - p->cur = p->begin; - p->end = p->begin + size; - if (size != 0) - return *p->cur++;; - } - p->extra = True; - return 0; -} - -static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CPpmd7 ppmd; - CByteInToLook s; - SRes res = SZ_OK; - - s.p.Read = ReadByte; - s.inStream = inStream; - s.begin = s.end = s.cur = NULL; - s.extra = False; - s.res = SZ_OK; - s.processed = 0; - - if (propsSize != 5) - return SZ_ERROR_UNSUPPORTED; - - { - unsigned order = props[0]; - UInt32 memSize = GetUi32(props + 1); - if (order < PPMD7_MIN_ORDER || - order > PPMD7_MAX_ORDER || - memSize < PPMD7_MIN_MEM_SIZE || - memSize > PPMD7_MAX_MEM_SIZE) - return SZ_ERROR_UNSUPPORTED; - Ppmd7_Construct(&ppmd); - if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) - return SZ_ERROR_MEM; - Ppmd7_Init(&ppmd, order); - } - { - CPpmd7z_RangeDec rc; - Ppmd7z_RangeDec_CreateVTable(&rc); - rc.Stream = &s.p; - if (!Ppmd7z_RangeDec_Init(&rc)) - res = SZ_ERROR_DATA; - else if (s.extra) - res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); - else - { - SizeT i; - for (i = 0; i < outSize; i++) - { - int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); - if (s.extra || sym < 0) - break; - outBuffer[i] = (Byte)sym; - } - if (i != outSize) - res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); - else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) - res = SZ_ERROR_DATA; - } - } - Ppmd7_Free(&ppmd, allocMain); - return res; -} - -#endif - - -static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzmaDec state; - SRes res = SZ_OK; - - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); - state.dic = outBuffer; - state.dicBufSize = outSize; - LzmaDec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; - ELzmaStatus status; - res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) - { - if (state.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - LzmaDec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzma2Dec state; - SRes res = SZ_OK; - - Lzma2Dec_Construct(&state); - if (propsSize != 1) - return SZ_ERROR_DATA; - RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); - state.decoder.dic = outBuffer; - state.decoder.dicBufSize = outSize; - Lzma2Dec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; - ELzmaStatus status; - res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) - { - if (state.decoder.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - Lzma2Dec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) -{ - while (inSize > 0) - { - void *inBuf; - size_t curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)inSize; - RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); - if (curSize == 0) - return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuf, curSize); - outBuffer += curSize; - inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); - } - return SZ_OK; -} - -static Bool IS_MAIN_METHOD(UInt32 m) -{ - switch (m) - { - case k_Copy: - case k_LZMA: - case k_LZMA2: - #ifdef _7ZIP_PPMD_SUPPPORT - case k_PPMD: - #endif - return True; - } - return False; -} - -static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) -{ - return - c->NumInStreams == 1 && - c->NumOutStreams == 1 && - /* c->MethodID <= (UInt32)0xFFFFFFFF && */ - IS_MAIN_METHOD((UInt32)c->MethodID); -} - -#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) - -static SRes CheckSupportedFolder(const CSzFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZ_ERROR_UNSUPPORTED; - if (!IS_SUPPORTED_CODER(&f->Coders[0])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 2) - { - const CSzCoderInfo *c = &f->Coders[1]; - if ( - /* c->MethodID > (UInt32)0xFFFFFFFF || */ - c->NumInStreams != 1 || - c->NumOutStreams != 1 || - f->NumPackStreams != 1 || - f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || - f->BindPairs[0].OutIndex != 0) - return SZ_ERROR_UNSUPPORTED; - switch ((UInt32)c->MethodID) - { - case k_BCJ: - case k_ARM: - break; - default: - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (!IS_SUPPORTED_CODER(&f->Coders[1]) || - !IS_SUPPORTED_CODER(&f->Coders[2]) || - !IS_BCJ2(&f->Coders[3])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - return SZ_ERROR_UNSUPPORTED; -} - -#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; - -static SRes SzFolder_Decode2(const CSzFolder *folder, - const Byte *propsData, - const UInt64 *unpackSizes, - const UInt64 *packPositions, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, - Byte *tempBuf[]) -{ - UInt32 ci; - SizeT tempSizes[3] = { 0, 0, 0}; - SizeT tempSize3 = 0; - Byte *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - const CSzCoderInfo *coder = &folder->Coders[ci]; - - if (IS_MAIN_METHOD((UInt32)coder->MethodID)) - { - UInt32 si = 0; - UInt64 offset; - UInt64 inSize; - Byte *outBufCur = outBuffer; - SizeT outSizeCur = outSize; - if (folder->NumCoders == 4) - { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = unpackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - Byte *temp; - outSizeCur = (SizeT)unpackSize; - if (outSizeCur != unpackSize) - return SZ_ERROR_MEM; - temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZ_ERROR_MEM; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) /* check it */ - return SZ_ERROR_PARAM; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (SizeT)unpackSize; - } - else - return SZ_ERROR_UNSUPPORTED; - } - offset = packPositions[si]; - inSize = packPositions[si + 1] - offset; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) /* check it */ - return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - } - else if (coder->MethodID == k_LZMA) - { - RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else if (coder->MethodID == k_LZMA2) - { - RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else - { - #ifdef _7ZIP_PPMD_SUPPPORT - RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); - #else - return SZ_ERROR_UNSUPPORTED; - #endif - } - } - else if (coder->MethodID == k_BCJ2) - { - UInt64 offset = packPositions[1]; - UInt64 s3Size = packPositions[2] - offset; - SRes res; - if (ci != 3) - return SZ_ERROR_UNSUPPORTED; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - tempSizes[2] = (SizeT)s3Size; - if (tempSizes[2] != s3Size) - return SZ_ERROR_MEM; - tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZ_ERROR_MEM; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) - } - else - { - if (ci != 1) - return SZ_ERROR_UNSUPPORTED; - switch (coder->MethodID) - { - case k_BCJ: - { - UInt32 state; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - break; - } - CASE_BRA_CONV(ARM) - default: - return SZ_ERROR_UNSUPPORTED; - } - } - } - return SZ_OK; -} - -SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, size_t outSize, - ISzAlloc *allocMain) -{ - SRes res; - CSzFolder folder; - CSzData sd; - CSzData sdSizes; - - const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; - sd.Data = data; - sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; - - sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex]; - sdSizes.Size = - p->FoSizesOffsets[folderIndex + 1] - - p->FoSizesOffsets[folderIndex]; - - res = SzGetNextFolderItem(&folder, &sd, &sdSizes); - - if (res != SZ_OK) - return res; - - if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.MainOutStream]) - return SZ_ERROR_FAIL; - { - int i; - Byte *tempBuf[3] = { 0, 0, 0}; - res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes, - p->PackPositions + p->FoStartPackStreamIndex[folderIndex], - inStream, startPos, - outBuffer, (SizeT)outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); - return res; - } -} diff --git a/utils/lzma/C/7zFile.c b/utils/lzma/C/7zFile.c deleted file mode 100644 index 041e5b15..00000000 --- a/utils/lzma/C/7zFile.c +++ /dev/null @@ -1,286 +0,0 @@ -/* 7zFile.c -- File IO -2009-11-24 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zFile.h" - -#ifndef USE_WINDOWS_FILE - -#ifndef UNDER_CE -#include -#endif - -#else - -/* - ReadFile and WriteFile functions in Windows have BUG: - If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) - from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES - (Insufficient system resources exist to complete the requested service). - Probably in some version of Windows there are problems with other sizes: - for 32 MB (maybe also for 16 MB). - And message can be "Network connection was lost" -*/ - -#define kChunkSizeMax (1 << 22) - -#endif - -void File_Construct(CSzFile *p) -{ - #ifdef USE_WINDOWS_FILE - p->handle = INVALID_HANDLE_VALUE; - #else - p->file = NULL; - #endif -} - -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -static WRes File_Open(CSzFile *p, const char *name, int writeMode) -{ - #ifdef USE_WINDOWS_FILE - p->handle = CreateFileA(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); - #else - p->file = fopen(name, writeMode ? "wb+" : "rb"); - return (p->file != 0) ? 0 : - #ifdef UNDER_CE - 2; /* ENOENT */ - #else - errno; - #endif - #endif -} - -WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } -WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } -#endif - -#ifdef USE_WINDOWS_FILE -static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) -{ - p->handle = CreateFileW(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); -} -WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } -#endif - -WRes File_Close(CSzFile *p) -{ - #ifdef USE_WINDOWS_FILE - if (p->handle != INVALID_HANDLE_VALUE) - { - if (!CloseHandle(p->handle)) - return GetLastError(); - p->handle = INVALID_HANDLE_VALUE; - } - #else - if (p->file != NULL) - { - int res = fclose(p->file); - if (res != 0) - return res; - p->file = NULL; - } - #endif - return 0; -} - -WRes File_Read(CSzFile *p, void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - - #ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((Byte *)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - - #else - - *size = fread(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - - #endif -} - -WRes File_Write(CSzFile *p, const void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - - #ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((Byte *)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - - #else - - *size = fwrite(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - - #endif -} - -WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) -{ - #ifdef USE_WINDOWS_FILE - - LARGE_INTEGER value; - DWORD moveMethod; - value.LowPart = (DWORD)*pos; - value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ - switch (origin) - { - case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; - case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; - case SZ_SEEK_END: moveMethod = FILE_END; break; - default: return ERROR_INVALID_PARAMETER; - } - value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); - if (value.LowPart == 0xFFFFFFFF) - { - WRes res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *pos = ((Int64)value.HighPart << 32) | value.LowPart; - return 0; - - #else - - int moveMethod; - int res; - switch (origin) - { - case SZ_SEEK_SET: moveMethod = SEEK_SET; break; - case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; - case SZ_SEEK_END: moveMethod = SEEK_END; break; - default: return 1; - } - res = fseek(p->file, (long)*pos, moveMethod); - *pos = ftell(p->file); - return res; - - #endif -} - -WRes File_GetLength(CSzFile *p, UInt64 *length) -{ - #ifdef USE_WINDOWS_FILE - - DWORD sizeHigh; - DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); - if (sizeLow == 0xFFFFFFFF) - { - DWORD res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *length = (((UInt64)sizeHigh) << 32) + sizeLow; - return 0; - - #else - - long pos = ftell(p->file); - int res = fseek(p->file, 0, SEEK_END); - *length = ftell(p->file); - fseek(p->file, pos, SEEK_SET); - return res; - - #endif -} - - -/* ---------- FileSeqInStream ---------- */ - -static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileSeqInStream *p = (CFileSeqInStream *)pp; - return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; -} - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p) -{ - p->s.Read = FileSeqInStream_Read; -} - - -/* ---------- FileInStream ---------- */ - -static SRes FileInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileInStream *p = (CFileInStream *)pp; - return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; -} - -static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) -{ - CFileInStream *p = (CFileInStream *)pp; - return File_Seek(&p->file, pos, origin); -} - -void FileInStream_CreateVTable(CFileInStream *p) -{ - p->s.Read = FileInStream_Read; - p->s.Seek = FileInStream_Seek; -} - - -/* ---------- FileOutStream ---------- */ - -static size_t FileOutStream_Write(void *pp, const void *data, size_t size) -{ - CFileOutStream *p = (CFileOutStream *)pp; - File_Write(&p->file, data, &size); - return size; -} - -void FileOutStream_CreateVTable(CFileOutStream *p) -{ - p->s.Write = FileOutStream_Write; -} diff --git a/utils/lzma/C/7zFile.h b/utils/lzma/C/7zFile.h deleted file mode 100644 index 658987ed..00000000 --- a/utils/lzma/C/7zFile.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 7zFile.h -- File IO -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_FILE_H -#define __7Z_FILE_H - -#ifdef _WIN32 -#define USE_WINDOWS_FILE -#endif - -#ifdef USE_WINDOWS_FILE -#include -#else -#include -#endif - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* ---------- File ---------- */ - -typedef struct -{ - #ifdef USE_WINDOWS_FILE - HANDLE handle; - #else - FILE *file; - #endif -} CSzFile; - -void File_Construct(CSzFile *p); -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -WRes InFile_Open(CSzFile *p, const char *name); -WRes OutFile_Open(CSzFile *p, const char *name); -#endif -#ifdef USE_WINDOWS_FILE -WRes InFile_OpenW(CSzFile *p, const WCHAR *name); -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); -#endif -WRes File_Close(CSzFile *p); - -/* reads max(*size, remain file's size) bytes */ -WRes File_Read(CSzFile *p, void *data, size_t *size); - -/* writes *size bytes */ -WRes File_Write(CSzFile *p, const void *data, size_t *size); - -WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); -WRes File_GetLength(CSzFile *p, UInt64 *length); - - -/* ---------- FileInStream ---------- */ - -typedef struct -{ - ISeqInStream s; - CSzFile file; -} CFileSeqInStream; - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p); - - -typedef struct -{ - ISeekInStream s; - CSzFile file; -} CFileInStream; - -void FileInStream_CreateVTable(CFileInStream *p); - - -typedef struct -{ - ISeqOutStream s; - CSzFile file; -} CFileOutStream; - -void FileOutStream_CreateVTable(CFileOutStream *p); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/7zStream.c b/utils/lzma/C/7zStream.c deleted file mode 100644 index 88f9c42b..00000000 --- a/utils/lzma/C/7zStream.c +++ /dev/null @@ -1,171 +0,0 @@ -/* 7zStream.c -- 7z Stream functions -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zTypes.h" - -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((Byte *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) -{ - return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) -{ - size_t processed = 1; - RINOK(stream->Read(stream, buf, &processed)); - return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; -} - -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) -{ - Int64 t = offset; - return stream->Seek(stream, &t, SZ_SEEK_SET); -} - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) -{ - const void *lookBuf; - if (*size == 0) - return SZ_OK; - RINOK(stream->Look(stream, &lookBuf, size)); - memcpy(buf, lookBuf, *size); - return stream->Skip(stream, *size); -} - -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((Byte *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) -{ - return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - size2 = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, &size2); - p->size = size2; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - if (*size > LookToRead_BUF_SIZE) - *size = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, size); - size2 = p->size = *size; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Skip(void *pp, size_t offset) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos += offset; - return SZ_OK; -} - -static SRes LookToRead_Read(void *pp, void *buf, size_t *size) -{ - CLookToRead *p = (CLookToRead *)pp; - size_t rem = p->size - p->pos; - if (rem == 0) - return p->realStream->Read(p->realStream, buf, size); - if (rem > *size) - rem = *size; - memcpy(buf, p->buf + p->pos, rem); - p->pos += rem; - *size = rem; - return SZ_OK; -} - -static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos = p->size = 0; - return p->realStream->Seek(p->realStream, pos, origin); -} - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead) -{ - p->s.Look = lookahead ? - LookToRead_Look_Lookahead : - LookToRead_Look_Exact; - p->s.Skip = LookToRead_Skip; - p->s.Read = LookToRead_Read; - p->s.Seek = LookToRead_Seek; -} - -void LookToRead_Init(CLookToRead *p) -{ - p->pos = p->size = 0; -} - -static SRes SecToLook_Read(void *pp, void *buf, size_t *size) -{ - CSecToLook *p = (CSecToLook *)pp; - return LookInStream_LookRead(p->realStream, buf, size); -} - -void SecToLook_CreateVTable(CSecToLook *p) -{ - p->s.Read = SecToLook_Read; -} - -static SRes SecToRead_Read(void *pp, void *buf, size_t *size) -{ - CSecToRead *p = (CSecToRead *)pp; - return p->realStream->Read(p->realStream, buf, size); -} - -void SecToRead_CreateVTable(CSecToRead *p) -{ - p->s.Read = SecToRead_Read; -} diff --git a/utils/lzma/C/7zTypes.h b/utils/lzma/C/7zTypes.h deleted file mode 100644 index 778413ef..00000000 --- a/utils/lzma/C/7zTypes.h +++ /dev/null @@ -1,256 +0,0 @@ -/* 7zTypes.h -- Basic types -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H - -#ifdef _WIN32 -/* #include */ -#endif - -#include - -#ifndef EXTERN_C_BEGIN -#ifdef __cplusplus -#define EXTERN_C_BEGIN extern "C" { -#define EXTERN_C_END } -#else -#define EXTERN_C_BEGIN -#define EXTERN_C_END -#endif -#endif - -EXTERN_C_BEGIN - -#define SZ_OK 0 - -#define SZ_ERROR_DATA 1 -#define SZ_ERROR_MEM 2 -#define SZ_ERROR_CRC 3 -#define SZ_ERROR_UNSUPPORTED 4 -#define SZ_ERROR_PARAM 5 -#define SZ_ERROR_INPUT_EOF 6 -#define SZ_ERROR_OUTPUT_EOF 7 -#define SZ_ERROR_READ 8 -#define SZ_ERROR_WRITE 9 -#define SZ_ERROR_PROGRESS 10 -#define SZ_ERROR_FAIL 11 -#define SZ_ERROR_THREAD 12 - -#define SZ_ERROR_ARCHIVE 16 -#define SZ_ERROR_NO_ARCHIVE 17 - -typedef int SRes; - -#ifdef _WIN32 -/* typedef DWORD WRes; */ -typedef unsigned WRes; -#else -typedef int WRes; -#endif - -#ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -#endif - -typedef unsigned char Byte; -typedef short Int16; -typedef unsigned short UInt16; - -#ifdef _LZMA_UINT32_IS_ULONG -typedef long Int32; -typedef unsigned long UInt32; -#else -typedef int Int32; -typedef unsigned int UInt32; -#endif - -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ - -typedef long Int64; -typedef unsigned long UInt64; - -#else - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n -#else -typedef long long int Int64; -typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL -#endif - -#endif - -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -typedef size_t SizeT; -#endif - -typedef int Bool; -#define True 1 -#define False 0 - - -#ifdef _WIN32 -#define MY_STD_CALL __stdcall -#else -#define MY_STD_CALL -#endif - -#ifdef _MSC_VER - -#if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) -#else -#define MY_NO_INLINE -#endif - -#define MY_CDECL __cdecl -#define MY_FAST_CALL __fastcall - -#else - -#define MY_NO_INLINE -#define MY_CDECL -#define MY_FAST_CALL - -#endif - - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; - -typedef struct -{ - void (*Write)(void *p, Byte b); -} IByteOut; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) < input(*size)) is allowed */ -} ISeqInStream; - -/* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); - -typedef struct -{ - size_t (*Write)(void *p, const void *buf, size_t size); - /* Returns: result - the number of actually written bytes. - (result < size) means error */ -} ISeqOutStream; - -typedef enum -{ - SZ_SEEK_SET = 0, - SZ_SEEK_CUR = 1, - SZ_SEEK_END = 2 -} ESzSeek; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ISeekInStream; - -typedef struct -{ - SRes (*Look)(void *p, const void **buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) > input(*size)) is not allowed - (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(void *p, size_t offset); - /* offset must be <= output(*size) of Look */ - - SRes (*Read)(void *p, void *buf, size_t *size); - /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ILookInStream; - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); - -/* reads via ILookInStream::Read */ -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); - -#define LookToRead_BUF_SIZE (1 << 14) - -typedef struct -{ - ILookInStream s; - ISeekInStream *realStream; - size_t pos; - size_t size; - Byte buf[LookToRead_BUF_SIZE]; -} CLookToRead; - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -void LookToRead_Init(CLookToRead *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToLook; - -void SecToLook_CreateVTable(CSecToLook *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToRead; - -void SecToRead_CreateVTable(CSecToRead *p); - -typedef struct -{ - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); - /* Returns: result. (result != SZ_OK) means break. - Value (UInt64)(Int64)-1 for size means unknown value. */ -} ICompressProgress; - -typedef struct -{ - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ -} ISzAlloc; - -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -#define IAlloc_Free(p, a) (p)->Free((p), a) - -#ifdef _WIN32 - -#define CHAR_PATH_SEPARATOR '\\' -#define WCHAR_PATH_SEPARATOR L'\\' -#define STRING_PATH_SEPARATOR "\\" -#define WSTRING_PATH_SEPARATOR L"\\" - -#else - -#define CHAR_PATH_SEPARATOR '/' -#define WCHAR_PATH_SEPARATOR L'/' -#define STRING_PATH_SEPARATOR "/" -#define WSTRING_PATH_SEPARATOR L"/" - -#endif - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/7zVersion.h b/utils/lzma/C/7zVersion.h deleted file mode 100644 index 47591835..00000000 --- a/utils/lzma/C/7zVersion.h +++ /dev/null @@ -1,10 +0,0 @@ -#define MY_VER_MAJOR 9 -#define MY_VER_MINOR 38 -#define MY_VER_BUILD 00 -#define MY_VERSION "9.38 beta" -// #define MY_7ZIP_VERSION "9.38" -#define MY_DATE "2015-01-03" -#undef MY_COPYRIGHT -#undef MY_VERSION_COPYRIGHT_DATE -#define MY_COPYRIGHT ": Igor Pavlov : Public domain" -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/utils/lzma/C/7zVersion.rc b/utils/lzma/C/7zVersion.rc deleted file mode 100644 index e520995d..00000000 --- a/utils/lzma/C/7zVersion.rc +++ /dev/null @@ -1,55 +0,0 @@ -#define MY_VS_FFI_FILEFLAGSMASK 0x0000003FL -#define MY_VOS_NT_WINDOWS32 0x00040004L -#define MY_VOS_CE_WINDOWS32 0x00050004L - -#define MY_VFT_APP 0x00000001L -#define MY_VFT_DLL 0x00000002L - -// #include - -#ifndef MY_VERSION -#include "7zVersion.h" -#endif - -#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0 - -#ifdef DEBUG -#define DBG_FL VS_FF_DEBUG -#else -#define DBG_FL 0 -#endif - -#define MY_VERSION_INFO(fileType, descr, intName, origName) \ -LANGUAGE 9, 1 \ -1 VERSIONINFO \ - FILEVERSION MY_VER \ - PRODUCTVERSION MY_VER \ - FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \ - FILEFLAGS DBG_FL \ - FILEOS MY_VOS_NT_WINDOWS32 \ - FILETYPE fileType \ - FILESUBTYPE 0x0L \ -BEGIN \ - BLOCK "StringFileInfo" \ - BEGIN \ - BLOCK "040904b0" \ - BEGIN \ - VALUE "CompanyName", "Igor Pavlov" \ - VALUE "FileDescription", descr \ - VALUE "FileVersion", MY_VERSION \ - VALUE "InternalName", intName \ - VALUE "LegalCopyright", MY_COPYRIGHT \ - VALUE "OriginalFilename", origName \ - VALUE "ProductName", "7-Zip" \ - VALUE "ProductVersion", MY_VERSION \ - END \ - END \ - BLOCK "VarFileInfo" \ - BEGIN \ - VALUE "Translation", 0x409, 1200 \ - END \ -END - -#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe") - -#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll") diff --git a/utils/lzma/C/7zAlloc.c b/utils/lzma/C/7zip/Archive/7z_C/7zAlloc.c similarity index 79% rename from utils/lzma/C/7zAlloc.c rename to utils/lzma/C/7zip/Archive/7z_C/7zAlloc.c index 97cea299..21bb30c7 100644 --- a/utils/lzma/C/7zAlloc.c +++ b/utils/lzma/C/7zip/Archive/7z_C/7zAlloc.c @@ -1,8 +1,6 @@ -/* 7zAlloc.c -- Allocation functions -2010-10-29 : Igor Pavlov : Public domain */ - -#include "Precomp.h" +/* 7zAlloc.c */ +#include #include "7zAlloc.h" /* #define _SZ_ALLOC_DEBUG */ @@ -13,16 +11,13 @@ #ifdef _WIN32 #include #endif - #include int g_allocCount = 0; int g_allocCountTemp = 0; - #endif -void *SzAlloc(void *p, size_t size) +void *SzAlloc(size_t size) { - p = p; if (size == 0) return 0; #ifdef _SZ_ALLOC_DEBUG @@ -32,9 +27,8 @@ void *SzAlloc(void *p, size_t size) return malloc(size); } -void SzFree(void *p, void *address) +void SzFree(void *address) { - p = p; #ifdef _SZ_ALLOC_DEBUG if (address != 0) { @@ -45,9 +39,8 @@ void SzFree(void *p, void *address) free(address); } -void *SzAllocTemp(void *p, size_t size) +void *SzAllocTemp(size_t size) { - p = p; if (size == 0) return 0; #ifdef _SZ_ALLOC_DEBUG @@ -60,9 +53,8 @@ void *SzAllocTemp(void *p, size_t size) return malloc(size); } -void SzFreeTemp(void *p, void *address) +void SzFreeTemp(void *address) { - p = p; #ifdef _SZ_ALLOC_DEBUG if (address != 0) { diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zAlloc.h b/utils/lzma/C/7zip/Archive/7z_C/7zAlloc.h new file mode 100644 index 00000000..4ca4170c --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zAlloc.h @@ -0,0 +1,20 @@ +/* 7zAlloc.h */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include + +typedef struct _ISzAlloc +{ + void *(*Alloc)(size_t size); + void (*Free)(void *address); /* address can be 0 */ +} ISzAlloc; + +void *SzAlloc(size_t size); +void SzFree(void *address); + +void *SzAllocTemp(size_t size); +void SzFreeTemp(void *address); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.c b/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.c new file mode 100644 index 00000000..3c4b71e8 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.c @@ -0,0 +1,29 @@ +/* 7zBuffer.c */ + +#include "7zBuffer.h" +#include "7zAlloc.h" + +void SzByteBufferInit(CSzByteBuffer *buffer) +{ + buffer->Capacity = 0; + buffer->Items = 0; +} + +int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)) +{ + buffer->Capacity = newCapacity; + if (newCapacity == 0) + { + buffer->Items = 0; + return 1; + } + buffer->Items = (Byte *)allocFunc(newCapacity); + return (buffer->Items != 0); +} + +void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)) +{ + freeFunc(buffer->Items); + buffer->Items = 0; + buffer->Capacity = 0; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.h b/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.h new file mode 100644 index 00000000..17e59060 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zBuffer.h @@ -0,0 +1,19 @@ +/* 7zBuffer.h */ + +#ifndef __7Z_BUFFER_H +#define __7Z_BUFFER_H + +#include +#include "7zTypes.h" + +typedef struct _CSzByteBuffer +{ + size_t Capacity; + Byte *Items; +}CSzByteBuffer; + +void SzByteBufferInit(CSzByteBuffer *buffer); +int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)); +void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zCrc.c b/utils/lzma/C/7zip/Archive/7z_C/7zCrc.c new file mode 100644 index 00000000..97738404 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zCrc.c @@ -0,0 +1,76 @@ +/* 7zCrc.c */ + +#include "7zCrc.h" + +#define kCrcPoly 0xEDB88320 + +UInt32 g_CrcTable[256]; + +void InitCrcTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCrcPoly; + else + r >>= 1; + g_CrcTable[i] = r; + } +} + +void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; } +UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; } + +void CrcUpdateByte(UInt32 *crc, Byte b) +{ + *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8); +} + +void CrcUpdateUInt16(UInt32 *crc, UInt16 v) +{ + CrcUpdateByte(crc, (Byte)v); + CrcUpdateByte(crc, (Byte)(v >> 8)); +} + +void CrcUpdateUInt32(UInt32 *crc, UInt32 v) +{ + int i; + for (i = 0; i < 4; i++) + CrcUpdateByte(crc, (Byte)(v >> (8 * i))); +} + +void CrcUpdateUInt64(UInt32 *crc, UInt64 v) +{ + int i; + for (i = 0; i < 8; i++) + { + CrcUpdateByte(crc, (Byte)(v)); + v >>= 8; + } +} + +void CrcUpdate(UInt32 *crc, const void *data, size_t size) +{ + UInt32 v = *crc; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8); + *crc = v; +} + +UInt32 CrcCalculateDigest(const void *data, size_t size) +{ + UInt32 crc; + CrcInit(&crc); + CrcUpdate(&crc, data, size); + return CrcGetDigest(&crc); +} + +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size) +{ + return (CrcCalculateDigest(data, size) == digest); +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zCrc.h b/utils/lzma/C/7zip/Archive/7z_C/7zCrc.h new file mode 100644 index 00000000..adcc563a --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zCrc.h @@ -0,0 +1,24 @@ +/* 7zCrc.h */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include + +#include "7zTypes.h" + +extern UInt32 g_CrcTable[256]; +void InitCrcTable(); + +void CrcInit(UInt32 *crc); +UInt32 CrcGetDigest(UInt32 *crc); +void CrcUpdateByte(UInt32 *crc, Byte v); +void CrcUpdateUInt16(UInt32 *crc, UInt16 v); +void CrcUpdateUInt32(UInt32 *crc, UInt32 v); +void CrcUpdateUInt64(UInt32 *crc, UInt64 v); +void CrcUpdate(UInt32 *crc, const void *data, size_t size); + +UInt32 CrcCalculateDigest(const void *data, size_t size); +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zDecode.c b/utils/lzma/C/7zip/Archive/7z_C/7zDecode.c new file mode 100644 index 00000000..b42ff927 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zDecode.c @@ -0,0 +1,150 @@ +/* 7zDecode.c */ + +#include "7zDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#else +#include "../../Compress/LZMA_C/LzmaDecode.h" +#endif + +CMethodID k_Copy = { { 0x0 }, 1 }; +CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; + +#ifdef _LZMA_IN_CB + +typedef struct _CLzmaInCallbackImp +{ + ILzmaInCallback InCallback; + ISzInStream *InStream; + size_t Size; +} CLzmaInCallbackImp; + +int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size) +{ + CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; + size_t processedSize; + SZ_RESULT res; + *size = 0; + res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize); + *size = (SizeT)processedSize; + if (processedSize > cb->Size) + return (int)SZE_FAIL; + cb->Size -= processedSize; + if (res == SZ_OK) + return 0; + return (int)res; +} + +#endif + +SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, + #ifdef _LZMA_IN_CB + ISzInStream *inStream, + #else + const Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain) +{ + UInt32 si; + size_t inSize = 0; + CCoderInfo *coder; + if (folder->NumPackStreams != 1) + return SZE_NOTIMPL; + if (folder->NumCoders != 1) + return SZE_NOTIMPL; + coder = folder->Coders; + *outSizeProcessed = 0; + + for (si = 0; si < folder->NumPackStreams; si++) + inSize += (size_t)packSizes[si]; + + if (AreMethodsEqual(&coder->MethodID, &k_Copy)) + { + size_t i; + if (inSize != outSize) + return SZE_DATA_ERROR; + #ifdef _LZMA_IN_CB + for (i = 0; i < inSize;) + { + size_t j; + Byte *inBuffer; + size_t bufferSize; + RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize)); + if (bufferSize == 0) + return SZE_DATA_ERROR; + if (bufferSize > inSize - i) + return SZE_FAIL; + *outSizeProcessed += bufferSize; + for (j = 0; j < bufferSize && i < inSize; j++, i++) + outBuffer[i] = inBuffer[j]; + } + #else + for (i = 0; i < inSize; i++) + outBuffer[i] = inBuffer[i]; + *outSizeProcessed = inSize; + #endif + return SZ_OK; + } + + if (AreMethodsEqual(&coder->MethodID, &k_LZMA)) + { + #ifdef _LZMA_IN_CB + CLzmaInCallbackImp lzmaCallback; + #else + SizeT inProcessed; + #endif + + CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ + int result; + SizeT outSizeProcessedLoc; + + #ifdef _LZMA_IN_CB + lzmaCallback.Size = inSize; + lzmaCallback.InStream = inStream; + lzmaCallback.InCallback.Read = LzmaReadImp; + #endif + + if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, + coder->Properties.Capacity) != LZMA_RESULT_OK) + return SZE_FAIL; + + state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (state.Probs == 0) + return SZE_OUTOFMEMORY; + + #ifdef _LZMA_OUT_READ + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else + { + state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); + if (state.Dictionary == 0) + { + allocMain->Free(state.Probs); + return SZE_OUTOFMEMORY; + } + } + LzmaDecoderInit(&state); + #endif + + result = LzmaDecode(&state, + #ifdef _LZMA_IN_CB + &lzmaCallback.InCallback, + #else + inBuffer, (SizeT)inSize, &inProcessed, + #endif + outBuffer, (SizeT)outSize, &outSizeProcessedLoc); + *outSizeProcessed = (size_t)outSizeProcessedLoc; + allocMain->Free(state.Probs); + #ifdef _LZMA_OUT_READ + allocMain->Free(state.Dictionary); + #endif + if (result == LZMA_RESULT_DATA_ERROR) + return SZE_DATA_ERROR; + if (result != LZMA_RESULT_OK) + return SZE_FAIL; + return SZ_OK; + } + return SZE_NOTIMPL; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zDecode.h b/utils/lzma/C/7zip/Archive/7z_C/7zDecode.h new file mode 100644 index 00000000..74bb180f --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zDecode.h @@ -0,0 +1,21 @@ +/* 7zDecode.h */ + +#ifndef __7Z_DECODE_H +#define __7Z_DECODE_H + +#include "7zItem.h" +#include "7zAlloc.h" +#ifdef _LZMA_IN_CB +#include "7zIn.h" +#endif + +SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, + #ifdef _LZMA_IN_CB + ISzInStream *stream, + #else + const Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zExtract.c b/utils/lzma/C/7zip/Archive/7z_C/7zExtract.c new file mode 100644 index 00000000..6ef872c3 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zExtract.c @@ -0,0 +1,116 @@ +/* 7zExtract.c */ + +#include "7zExtract.h" +#include "7zDecode.h" +#include "7zCrc.h" + +SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex]; + SZ_RESULT res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + allocMain->Free(*outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize unPackSize = SzFolderGetUnPackSize(folder); + #ifndef _LZMA_IN_CB + CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex); + Byte *inBuffer = 0; + size_t processedSize; + #endif + *blockIndex = folderIndex; + allocMain->Free(*outBuffer); + *outBuffer = 0; + + RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); + + #ifndef _LZMA_IN_CB + if (packSize != 0) + { + inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); + if (inBuffer == 0) + return SZE_OUTOFMEMORY; + } + res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); + if (res == SZ_OK && processedSize != (size_t)packSize) + res = SZE_FAIL; + #endif + if (res == SZ_OK) + { + *outBufferSize = (size_t)unPackSize; + if (unPackSize != 0) + { + *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); + if (*outBuffer == 0) + res = SZE_OUTOFMEMORY; + } + if (res == SZ_OK) + { + size_t outRealSize; + res = SzDecode(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, + #ifdef _LZMA_IN_CB + inStream, + #else + inBuffer, + #endif + *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp); + if (res == SZ_OK) + { + if (outRealSize == (size_t)unPackSize) + { + if (folder->UnPackCRCDefined) + { + if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize)) + res = SZE_FAIL; + } + } + else + res = SZE_FAIL; + } + } + } + #ifndef _LZMA_IN_CB + allocTemp->Free(inBuffer); + #endif + } + if (res == SZ_OK) + { + UInt32 i; + CFileItem *fileItem = db->Database.Files + fileIndex; + *offset = 0; + for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)db->Database.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZE_FAIL; + { + if (fileItem->IsFileCRCDefined) + { + if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed)) + res = SZE_FAIL; + } + } + } + return res; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zExtract.h b/utils/lzma/C/7zip/Archive/7z_C/7zExtract.h new file mode 100644 index 00000000..e9a4fb4e --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zExtract.h @@ -0,0 +1,40 @@ +/* 7zExtract.h */ + +#ifndef __7Z_EXTRACT_H +#define __7Z_EXTRACT_H + +#include "7zIn.h" + +/* + SzExtract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zHeader.c b/utils/lzma/C/7zip/Archive/7z_C/7zHeader.c new file mode 100644 index 00000000..3be4bc27 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zHeader.c @@ -0,0 +1,5 @@ +/* 7zHeader.c */ + +#include "7zHeader.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zHeader.h b/utils/lzma/C/7zip/Archive/7z_C/7zHeader.h new file mode 100644 index 00000000..0356aaa6 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zHeader.h @@ -0,0 +1,55 @@ +/* 7zHeader.h */ + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "7zTypes.h" + +#define k7zSignatureSize 6 +extern Byte k7zSignature[k7zSignatureSize]; + +#define k7zMajorVersion 0 + +#define k7zStartHeaderSize 0x20 + +enum EIdEnum +{ + k7zIdEnd, + + k7zIdHeader, + + k7zIdArchiveProperties, + + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + + k7zIdPackInfo, + k7zIdUnPackInfo, + k7zIdSubStreamsInfo, + + k7zIdSize, + k7zIdCRC, + + k7zIdFolder, + + k7zIdCodersUnPackSize, + k7zIdNumUnPackStream, + + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + + k7zIdName, + k7zIdCreationTime, + k7zIdLastAccessTime, + k7zIdLastWriteTime, + k7zIdWinAttributes, + k7zIdComment, + + k7zIdEncodedHeader, + + k7zIdStartPos +}; + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zIn.c b/utils/lzma/C/7zip/Archive/7z_C/7zIn.c new file mode 100644 index 00000000..8ff1e62d --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zIn.c @@ -0,0 +1,1281 @@ +/* 7zIn.c */ + +#include "7zIn.h" +#include "7zCrc.h" +#include "7zDecode.h" + +#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; } + +void SzArDbExInit(CArchiveDatabaseEx *db) +{ + SzArchiveDatabaseInit(&db->Database); + db->FolderStartPackStreamIndex = 0; + db->PackStreamStartPositions = 0; + db->FolderStartFileIndex = 0; + db->FileIndexToFolderIndexMap = 0; +} + +void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)) +{ + freeFunc(db->FolderStartPackStreamIndex); + freeFunc(db->PackStreamStartPositions); + freeFunc(db->FolderStartFileIndex); + freeFunc(db->FileIndexToFolderIndexMap); + SzArchiveDatabaseFree(&db->Database, freeFunc); + SzArDbExInit(db); +} + +/* +CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const +{ + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; +} + +CFileSize GetFilePackSize(int fileIndex) const +{ + int folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; +} +*/ + +#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \ + if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; } + +SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) +{ + UInt32 startPos = 0; + CFileSize startPosSize = 0; + UInt32 i; + UInt32 folderIndex = 0; + UInt32 indexInFolder = 0; + MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc); + for(i = 0; i < db->Database.NumFolders; i++) + { + db->FolderStartPackStreamIndex[i] = startPos; + startPos += db->Database.Folders[i].NumPackStreams; + } + + MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc); + + for(i = 0; i < db->Database.NumPackStreams; i++) + { + db->PackStreamStartPositions[i] = startPosSize; + startPosSize += db->Database.PackSizes[i]; + } + + MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc); + MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc); + + for (i = 0; i < db->Database.NumFiles; i++) + { + CFileItem *file = db->Database.Files + i; + int emptyStream = !file->HasStream; + if (emptyStream && indexInFolder == 0) + { + db->FileIndexToFolderIndexMap[i] = (UInt32)-1; + continue; + } + if (indexInFolder == 0) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: Loop for skipping empty folders + */ + while(1) + { + if (folderIndex >= db->Database.NumFolders) + return SZE_ARCHIVE_ERROR; + db->FolderStartFileIndex[folderIndex] = i; + if (db->Database.Folders[folderIndex].NumUnPackStreams != 0) + break; + folderIndex++; + } + } + db->FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams) + { + folderIndex++; + indexInFolder = 0; + } + } + return SZ_OK; +} + + +CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder) +{ + return db->ArchiveInfo.DataStartPosition + + db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; +} + +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex) +{ + UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex]; + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize size = 0; + UInt32 i; + for (i = 0; i < folder->NumPackStreams; i++) + size += db->Database.PackSizes[packStreamIndex + i]; + return size; +} + + +/* +SZ_RESULT SzReadTime(const CObjectVector &dataVector, + CObjectVector &files, UInt64 type) +{ + CBoolVector boolVector; + RINOK(ReadBoolVector2(files.Size(), boolVector)) + + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + + for(int i = 0; i < files.Size(); i++) + { + CFileItem &file = files[i]; + CArchiveFileTime fileTime; + bool defined = boolVector[i]; + if (defined) + { + UInt32 low, high; + RINOK(SzReadUInt32(low)); + RINOK(SzReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; + } + switch(type) + { + case k7zIdCreationTime: + file.IsCreationTimeDefined = defined; + if (defined) + file.CreationTime = fileTime; + break; + case k7zIdLastWriteTime: + file.IsLastWriteTimeDefined = defined; + if (defined) + file.LastWriteTime = fileTime; + break; + case k7zIdLastAccessTime: + file.IsLastAccessTimeDefined = defined; + if (defined) + file.LastAccessTime = fileTime; + break; + } + } + return SZ_OK; +} +*/ + +SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size) +{ + #ifdef _LZMA_IN_CB + while (size > 0) + { + Byte *inBuffer; + size_t processedSize; + RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize)); + if (processedSize == 0 || processedSize > size) + return SZE_FAIL; + size -= processedSize; + do + { + *data++ = *inBuffer++; + } + while (--processedSize != 0); + } + #else + size_t processedSize; + RINOK(inStream->Read(inStream, data, size, &processedSize)); + if (processedSize != size) + return SZE_FAIL; + #endif + return SZ_OK; +} + +SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data) +{ + return SafeReadDirect(inStream, data, 1); +} + +SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + return SZ_OK; +} + +SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value) +{ + int i; + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + return SZ_OK; +} + +int TestSignatureCandidate(Byte *testBytes) +{ + size_t i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +typedef struct _CSzState +{ + Byte *Data; + size_t Size; +}CSzData; + +SZ_RESULT SzReadByte(CSzData *sd, Byte *b) +{ + if (sd->Size == 0) + return SZE_ARCHIVE_ERROR; + sd->Size--; + *b = *sd->Data++; + return SZ_OK; +} + +SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + { + RINOK(SzReadByte(sd, data + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt32)(b) << (8 * i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte; + Byte mask = 0x80; + int i; + RINOK(SzReadByte(sd, &firstByte)); + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + *value += (highPart << (8 * i)); + return SZ_OK; + } + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + +SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + *value = (CFileSize)value64; + return SZ_OK; +} + +SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + if (value64 >= 0x80000000) + return SZE_NOTIMPL; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) + return SZE_NOTIMPL; + *value = (UInt32)value64; + return SZ_OK; +} + +SZ_RESULT SzReadID(CSzData *sd, UInt64 *value) +{ + return SzReadNumber(sd, value); +} + +SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size) +{ + if (size > sd->Size) + return SZE_ARCHIVE_ERROR; + sd->Size -= (size_t)size; + sd->Data += (size_t)size; + return SZ_OK; +} + +SZ_RESULT SzSkeepData(CSzData *sd) +{ + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + return SzSkeepDataSize(sd, size); +} + +SZ_RESULT SzReadArchiveProperties(CSzData *sd) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == attribute) + return SZ_OK; + if (type == k7zIdEnd) + return SZE_ARCHIVE_ERROR; + RINOK(SzSkeepData(sd)); + } +} + +SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size)) +{ + Byte b = 0; + Byte mask = 0; + size_t i; + MY_ALLOC(Byte, *v, numItems, allocFunc); + for(i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(SzReadByte(sd, &b)); + mask = 0x80; + } + (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); + mask >>= 1; + } + return SZ_OK; +} + +SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size)) +{ + Byte allAreDefined; + size_t i; + RINOK(SzReadByte(sd, &allAreDefined)); + if (allAreDefined == 0) + return SzReadBoolVector(sd, numItems, v, allocFunc); + MY_ALLOC(Byte, *v, numItems, allocFunc); + for(i = 0; i < numItems; i++) + (*v)[i] = 1; + return SZ_OK; +} + +SZ_RESULT SzReadHashDigests( + CSzData *sd, + size_t numItems, + Byte **digestsDefined, + UInt32 **digests, + void * (*allocFunc)(size_t size)) +{ + size_t i; + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc)); + MY_ALLOC(UInt32, *digests, numItems, allocFunc); + for(i = 0; i < numItems; i++) + if ((*digestsDefined)[i]) + { + RINOK(SzReadUInt32(sd, (*digests) + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadPackInfo( + CSzData *sd, + CFileSize *dataOffset, + UInt32 *numPackStreams, + CFileSize **packSizes, + Byte **packCRCsDefined, + UInt32 **packCRCs, + void * (*allocFunc)(size_t size)) +{ + UInt32 i; + RINOK(SzReadSize(sd, dataOffset)); + RINOK(SzReadNumber32(sd, numPackStreams)); + + RINOK(SzWaitAttribute(sd, k7zIdSize)); + + MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc); + + for(i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadSize(sd, (*packSizes) + i)); + } + + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + if (type == k7zIdCRC) + { + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc)); + continue; + } + RINOK(SzSkeepData(sd)); + } + if (*packCRCsDefined == 0) + { + MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc); + MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc); + for(i = 0; i < *numPackStreams; i++) + { + (*packCRCsDefined)[i] = 0; + (*packCRCs)[i] = 0; + } + } + return SZ_OK; +} + +SZ_RESULT SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR; +} + +SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size)) +{ + UInt32 numCoders; + UInt32 numBindPairs; + UInt32 numPackedStreams; + UInt32 i; + UInt32 numInStreams = 0; + UInt32 numOutStreams = 0; + RINOK(SzReadNumber32(sd, &numCoders)); + folder->NumCoders = numCoders; + + MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc); + + for (i = 0; i < numCoders; i++) + SzCoderInfoInit(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CCoderInfo *coder = folder->Coders + i; + { + RINOK(SzReadByte(sd, &mainByte)); + coder->MethodID.IDSize = (Byte)(mainByte & 0xF); + RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize)); + if ((mainByte & 0x10) != 0) + { + RINOK(SzReadNumber32(sd, &coder->NumInStreams)); + RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); + } + else + { + coder->NumInStreams = 1; + coder->NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc)) + return SZE_OUTOFMEMORY; + RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize)); + } + } + while ((mainByte & 0x80) != 0) + { + RINOK(SzReadByte(sd, &mainByte)); + RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); + if ((mainByte & 0x10) != 0) + { + UInt32 n; + RINOK(SzReadNumber32(sd, &n)); + RINOK(SzReadNumber32(sd, &n)); + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + RINOK(SzSkeepDataSize(sd, propertiesSize)); + } + } + numInStreams += (UInt32)coder->NumInStreams; + numOutStreams += (UInt32)coder->NumOutStreams; + } + + numBindPairs = numOutStreams - 1; + folder->NumBindPairs = numBindPairs; + + + MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc); + + for (i = 0; i < numBindPairs; i++) + { + CBindPair *bindPair = folder->BindPairs + i;; + RINOK(SzReadNumber32(sd, &bindPair->InIndex)); + RINOK(SzReadNumber32(sd, &bindPair->OutIndex)); + } + + numPackedStreams = numInStreams - (UInt32)numBindPairs; + + folder->NumPackStreams = numPackedStreams; + MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc); + + if (numPackedStreams == 1) + { + UInt32 j; + UInt32 pi = 0; + for (j = 0; j < numInStreams; j++) + if (SzFolderFindBindPairForInStream(folder, j) < 0) + { + folder->PackStreams[pi++] = j; + break; + } + } + else + for(i = 0; i < numPackedStreams; i++) + { + RINOK(SzReadNumber32(sd, folder->PackStreams + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadUnPackInfo( + CSzData *sd, + UInt32 *numFolders, + CFolder **folders, /* for allocFunc */ + void * (*allocFunc)(size_t size), + ISzAlloc *allocTemp) +{ + UInt32 i; + RINOK(SzWaitAttribute(sd, k7zIdFolder)); + RINOK(SzReadNumber32(sd, numFolders)); + { + RINOK(SzReadSwitch(sd)); + + MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc); + + for(i = 0; i < *numFolders; i++) + SzFolderInit((*folders) + i); + + for(i = 0; i < *numFolders; i++) + { + RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc)); + } + } + + RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize)); + + for(i = 0; i < *numFolders; i++) + { + UInt32 j; + CFolder *folder = (*folders) + i; + UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); + + MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc); + + for(j = 0; j < numOutStreams; j++) + { + RINOK(SzReadSize(sd, folder->UnPackSizes + j)); + } + } + + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + SZ_RESULT res; + Byte *crcsDefined = 0; + UInt32 *crcs = 0; + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc); + if (res == SZ_OK) + { + for(i = 0; i < *numFolders; i++) + { + CFolder *folder = (*folders) + i; + folder->UnPackCRCDefined = crcsDefined[i]; + folder->UnPackCRC = crcs[i]; + } + } + allocTemp->Free(crcs); + allocTemp->Free(crcsDefined); + RINOK(res); + continue; + } + RINOK(SzSkeepData(sd)); + } +} + +SZ_RESULT SzReadSubStreamsInfo( + CSzData *sd, + UInt32 numFolders, + CFolder *folders, + UInt32 *numUnPackStreams, + CFileSize **unPackSizes, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *allocTemp) +{ + UInt64 type = 0; + UInt32 i; + UInt32 si = 0; + UInt32 numDigests = 0; + + for(i = 0; i < numFolders; i++) + folders[i].NumUnPackStreams = 1; + *numUnPackStreams = numFolders; + + while(1) + { + RINOK(SzReadID(sd, &type)); + if (type == k7zIdNumUnPackStream) + { + *numUnPackStreams = 0; + for(i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + folders[i].NumUnPackStreams = numStreams; + *numUnPackStreams += numStreams; + } + continue; + } + if (type == k7zIdCRC || type == k7zIdSize) + break; + if (type == k7zIdEnd) + break; + RINOK(SzSkeepData(sd)); + } + + if (*numUnPackStreams == 0) + { + *unPackSizes = 0; + *digestsDefined = 0; + *digests = 0; + } + else + { + *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize)); + RINOM(*unPackSizes); + *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte)); + RINOM(*digestsDefined); + *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); + RINOM(*digests); + } + + for(i = 0; i < numFolders; i++) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: we check that folder is empty + */ + CFileSize sum = 0; + UInt32 j; + UInt32 numSubstreams = folders[i].NumUnPackStreams; + if (numSubstreams == 0) + continue; + if (type == k7zIdSize) + for (j = 1; j < numSubstreams; j++) + { + CFileSize size; + RINOK(SzReadSize(sd, &size)); + (*unPackSizes)[si++] = size; + sum += size; + } + (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum; + } + if (type == k7zIdSize) + { + RINOK(SzReadID(sd, &type)); + } + + for(i = 0; i < *numUnPackStreams; i++) + { + (*digestsDefined)[i] = 0; + (*digests)[i] = 0; + } + + + for(i = 0; i < numFolders; i++) + { + UInt32 numSubstreams = folders[i].NumUnPackStreams; + if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) + numDigests += numSubstreams; + } + + + si = 0; + while(1) + { + if (type == k7zIdCRC) + { + int digestIndex = 0; + Byte *digestsDefined2 = 0; + UInt32 *digests2 = 0; + SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc); + if (res == SZ_OK) + { + for (i = 0; i < numFolders; i++) + { + CFolder *folder = folders + i; + UInt32 numSubstreams = folder->NumUnPackStreams; + if (numSubstreams == 1 && folder->UnPackCRCDefined) + { + (*digestsDefined)[si] = 1; + (*digests)[si] = folder->UnPackCRC; + si++; + } + else + { + UInt32 j; + for (j = 0; j < numSubstreams; j++, digestIndex++) + { + (*digestsDefined)[si] = digestsDefined2[digestIndex]; + (*digests)[si] = digests2[digestIndex]; + si++; + } + } + } + } + allocTemp->Free(digestsDefined2); + allocTemp->Free(digests2); + RINOK(res); + } + else if (type == k7zIdEnd) + return SZ_OK; + else + { + RINOK(SzSkeepData(sd)); + } + RINOK(SzReadID(sd, &type)); + } +} + + +SZ_RESULT SzReadStreamsInfo( + CSzData *sd, + CFileSize *dataOffset, + CArchiveDatabase *db, + UInt32 *numUnPackStreams, + CFileSize **unPackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + void * (*allocFunc)(size_t size), + ISzAlloc *allocTemp) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if ((UInt64)(int)type != type) + return SZE_FAIL; + switch((int)type) + { + case k7zIdEnd: + return SZ_OK; + case k7zIdPackInfo: + { + RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams, + &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc)); + break; + } + case k7zIdUnPackInfo: + { + RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp)); + break; + } + case k7zIdSubStreamsInfo: + { + RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders, + numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp)); + break; + } + default: + return SZE_FAIL; + } + } +} + +Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, + void * (*allocFunc)(size_t size)) +{ + UInt32 i; + for(i = 0; i < numFiles; i++) + { + UInt32 len = 0; + UInt32 pos = 0; + CFileItem *file = files + i; + while(pos + 2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + len++; + if (value == 0) + break; + if (value < 0x80) + continue; + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00) + return SZE_ARCHIVE_ERROR; + if (pos + 2 > sd->Size) + return SZE_ARCHIVE_ERROR; + c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + if (c2 < 0xDC00 || c2 >= 0xE000) + return SZE_ARCHIVE_ERROR; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + len += numAdds; + } + + MY_ALLOC(char, file->Name, (size_t)len, allocFunc); + + len = 0; + while(2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + if (value < 0x80) + { + file->Name[len++] = (char)value; + if (value == 0) + break; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while(numAdds > 0); + + len += numAdds; + } + } + return SZ_OK; +} + +SZ_RESULT SzReadHeader2( + CSzData *sd, + CArchiveDatabaseEx *db, /* allocMain */ + CFileSize **unPackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + Byte **emptyStreamVector, /* allocTemp */ + Byte **emptyFileVector, /* allocTemp */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 type; + UInt32 numUnPackStreams = 0; + UInt32 numFiles = 0; + CFileItem *files = 0; + UInt32 numEmptyStreams = 0; + UInt32 i; + + RINOK(SzReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + RINOK(SzReadArchiveProperties(sd)); + RINOK(SzReadID(sd, &type)); + } + + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(sd, + &db->ArchiveInfo.DataStartPosition, + &db->Database, + &numUnPackStreams, + unPackSizes, + digestsDefined, + digests, allocMain->Alloc, allocTemp)); + db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader; + RINOK(SzReadID(sd, &type)); + } + + if (type == k7zIdEnd) + return SZ_OK; + if (type != k7zIdFilesInfo) + return SZE_ARCHIVE_ERROR; + + RINOK(SzReadNumber32(sd, &numFiles)); + db->Database.NumFiles = numFiles; + + MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc); + + db->Database.Files = files; + for(i = 0; i < numFiles; i++) + SzFileInit(files + i); + + while(1) + { + UInt64 type; + UInt64 size; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SzReadNumber(sd, &size)); + + if ((UInt64)(int)type != type) + { + RINOK(SzSkeepDataSize(sd, size)); + } + else + switch((int)type) + { + case k7zIdName: + { + RINOK(SzReadSwitch(sd)); + RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc)) + break; + } + case k7zIdEmptyStream: + { + RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc)); + numEmptyStreams = 0; + for (i = 0; i < numFiles; i++) + if ((*emptyStreamVector)[i]) + numEmptyStreams++; + break; + } + case k7zIdEmptyFile: + { + RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc)); + break; + } + default: + { + RINOK(SzSkeepDataSize(sd, size)); + } + } + } + + { + UInt32 emptyFileIndex = 0; + UInt32 sizeIndex = 0; + for(i = 0; i < numFiles; i++) + { + CFileItem *file = files + i; + file->IsAnti = 0; + if (*emptyStreamVector == 0) + file->HasStream = 1; + else + file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); + if(file->HasStream) + { + file->IsDirectory = 0; + file->Size = (*unPackSizes)[sizeIndex]; + file->FileCRC = (*digests)[sizeIndex]; + file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; + sizeIndex++; + } + else + { + if (*emptyFileVector == 0) + file->IsDirectory = 1; + else + file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); + emptyFileIndex++; + file->Size = 0; + file->IsFileCRCDefined = 0; + } + } + } + return SzArDbExFill(db, allocMain->Alloc); +} + +SZ_RESULT SzReadHeader( + CSzData *sd, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + CFileSize *unPackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + Byte *emptyStreamVector = 0; + Byte *emptyFileVector = 0; + SZ_RESULT res = SzReadHeader2(sd, db, + &unPackSizes, &digestsDefined, &digests, + &emptyStreamVector, &emptyFileVector, + allocMain, allocTemp); + allocTemp->Free(unPackSizes); + allocTemp->Free(digestsDefined); + allocTemp->Free(digests); + allocTemp->Free(emptyStreamVector); + allocTemp->Free(emptyFileVector); + return res; +} + +SZ_RESULT SzReadAndDecodePackedStreams2( + ISzInStream *inStream, + CSzData *sd, + CSzByteBuffer *outBuffer, + CFileSize baseOffset, + CArchiveDatabase *db, + CFileSize **unPackSizes, + Byte **digestsDefined, + UInt32 **digests, + #ifndef _LZMA_IN_CB + Byte **inBuffer, + #endif + ISzAlloc *allocTemp) +{ + + UInt32 numUnPackStreams = 0; + CFileSize dataStartPos; + CFolder *folder; + #ifndef _LZMA_IN_CB + CFileSize packSize = 0; + UInt32 i = 0; + #endif + CFileSize unPackSize; + size_t outRealSize; + SZ_RESULT res; + + RINOK(SzReadStreamsInfo(sd, &dataStartPos, db, + &numUnPackStreams, unPackSizes, digestsDefined, digests, + allocTemp->Alloc, allocTemp)); + + dataStartPos += baseOffset; + if (db->NumFolders != 1) + return SZE_ARCHIVE_ERROR; + + folder = db->Folders; + unPackSize = SzFolderGetUnPackSize(folder); + + RINOK(inStream->Seek(inStream, dataStartPos)); + + #ifndef _LZMA_IN_CB + for (i = 0; i < db->NumPackStreams; i++) + packSize += db->PackSizes[i]; + + MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc); + + RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); + #endif + + if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc)) + return SZE_OUTOFMEMORY; + + res = SzDecode(db->PackSizes, folder, + #ifdef _LZMA_IN_CB + inStream, + #else + *inBuffer, + #endif + outBuffer->Items, (size_t)unPackSize, + &outRealSize, allocTemp); + RINOK(res) + if (outRealSize != (UInt32)unPackSize) + return SZE_FAIL; + if (folder->UnPackCRCDefined) + if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize)) + return SZE_FAIL; + return SZ_OK; +} + +SZ_RESULT SzReadAndDecodePackedStreams( + ISzInStream *inStream, + CSzData *sd, + CSzByteBuffer *outBuffer, + CFileSize baseOffset, + ISzAlloc *allocTemp) +{ + CArchiveDatabase db; + CFileSize *unPackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + #ifndef _LZMA_IN_CB + Byte *inBuffer = 0; + #endif + SZ_RESULT res; + SzArchiveDatabaseInit(&db); + res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, + &db, &unPackSizes, &digestsDefined, &digests, + #ifndef _LZMA_IN_CB + &inBuffer, + #endif + allocTemp); + SzArchiveDatabaseFree(&db, allocTemp->Free); + allocTemp->Free(unPackSizes); + allocTemp->Free(digestsDefined); + allocTemp->Free(digests); + #ifndef _LZMA_IN_CB + allocTemp->Free(inBuffer); + #endif + return res; +} + +SZ_RESULT SzArchiveOpen2( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + Byte signature[k7zSignatureSize]; + Byte version; + UInt32 crcFromArchive; + UInt64 nextHeaderOffset; + UInt64 nextHeaderSize; + UInt32 nextHeaderCRC; + UInt32 crc; + CFileSize pos = 0; + CSzByteBuffer buffer; + CSzData sd; + SZ_RESULT res; + + RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize)); + + if (!TestSignatureCandidate(signature)) + return SZE_ARCHIVE_ERROR; + + /* + db.Clear(); + db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + */ + RINOK(SafeReadDirectByte(inStream, &version)); + if (version != k7zMajorVersion) + return SZE_ARCHIVE_ERROR; + RINOK(SafeReadDirectByte(inStream, &version)); + + RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive)); + + CrcInit(&crc); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset)); + CrcUpdateUInt64(&crc, nextHeaderOffset); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize)); + CrcUpdateUInt64(&crc, nextHeaderSize); + RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC)); + CrcUpdateUInt32(&crc, nextHeaderCRC); + + pos = k7zStartHeaderSize; + db->ArchiveInfo.StartPositionAfterHeader = pos; + + if (CrcGetDigest(&crc) != crcFromArchive) + return SZE_ARCHIVE_ERROR; + + if (nextHeaderSize == 0) + return SZ_OK; + + RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset))); + + if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc)) + return SZE_OUTOFMEMORY; + + res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize); + if (res == SZ_OK) + { + if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize)) + { + while (1) + { + UInt64 type; + sd.Data = buffer.Items; + sd.Size = buffer.Capacity; + res = SzReadID(&sd, &type); + if (res != SZ_OK) + break; + if (type == k7zIdHeader) + { + res = SzReadHeader(&sd, db, allocMain, allocTemp); + break; + } + if (type != k7zIdEncodedHeader) + { + res = SZE_ARCHIVE_ERROR; + break; + } + { + CSzByteBuffer outBuffer; + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, + db->ArchiveInfo.StartPositionAfterHeader, + allocTemp); + if (res != SZ_OK) + { + SzByteBufferFree(&outBuffer, allocTemp->Free); + break; + } + SzByteBufferFree(&buffer, allocTemp->Free); + buffer.Items = outBuffer.Items; + buffer.Capacity = outBuffer.Capacity; + } + } + } + } + SzByteBufferFree(&buffer, allocTemp->Free); + return res; +} + +SZ_RESULT SzArchiveOpen( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp); + if (res != SZ_OK) + SzArDbExFree(db, allocMain->Free); + return res; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zIn.h b/utils/lzma/C/7zip/Archive/7z_C/7zIn.h new file mode 100644 index 00000000..6bfa2a70 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zIn.h @@ -0,0 +1,55 @@ +/* 7zIn.h */ + +#ifndef __7Z_IN_H +#define __7Z_IN_H + +#include "7zHeader.h" +#include "7zItem.h" +#include "7zAlloc.h" + +typedef struct _CInArchiveInfo +{ + CFileSize StartPositionAfterHeader; + CFileSize DataStartPosition; +}CInArchiveInfo; + +typedef struct _CArchiveDatabaseEx +{ + CArchiveDatabase Database; + CInArchiveInfo ArchiveInfo; + UInt32 *FolderStartPackStreamIndex; + CFileSize *PackStreamStartPositions; + UInt32 *FolderStartFileIndex; + UInt32 *FileIndexToFolderIndexMap; +}CArchiveDatabaseEx; + +void SzArDbExInit(CArchiveDatabaseEx *db); +void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)); +CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder); +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex); + +typedef struct _ISzInStream +{ + #ifdef _LZMA_IN_CB + SZ_RESULT (*Read)( + void *object, /* pointer to ISzInStream itself */ + void **buffer, /* out: pointer to buffer with data */ + size_t maxRequiredSize, /* max required size to read */ + size_t *processedSize); /* real processed size. + processedSize can be less than maxRequiredSize. + If processedSize == 0, then there are no more + bytes in stream. */ + #else + SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize); + #endif + SZ_RESULT (*Seek)(void *object, CFileSize pos); +} ISzInStream; + + +int SzArchiveOpen( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zItem.c b/utils/lzma/C/7zip/Archive/7z_C/7zItem.c new file mode 100644 index 00000000..2a408050 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zItem.c @@ -0,0 +1,133 @@ +/* 7zItem.c */ + +#include "7zItem.h" +#include "7zAlloc.h" + +void SzCoderInfoInit(CCoderInfo *coder) +{ + SzByteBufferInit(&coder->Properties); +} + +void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)) +{ + SzByteBufferFree(&coder->Properties, freeFunc); + SzCoderInfoInit(coder); +} + +void SzFolderInit(CFolder *folder) +{ + folder->NumCoders = 0; + folder->Coders = 0; + folder->NumBindPairs = 0; + folder->BindPairs = 0; + folder->NumPackStreams = 0; + folder->PackStreams = 0; + folder->UnPackSizes = 0; + folder->UnPackCRCDefined = 0; + folder->UnPackCRC = 0; + folder->NumUnPackStreams = 0; +} + +void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p)) +{ + UInt32 i; + for (i = 0; i < folder->NumCoders; i++) + SzCoderInfoFree(&folder->Coders[i], freeFunc); + freeFunc(folder->Coders); + freeFunc(folder->BindPairs); + freeFunc(folder->PackStreams); + freeFunc(folder->UnPackSizes); + SzFolderInit(folder); +} + +UInt32 SzFolderGetNumOutStreams(CFolder *folder) +{ + UInt32 result = 0; + UInt32 i; + for (i = 0; i < folder->NumCoders; i++) + result += folder->Coders[i].NumOutStreams; + return result; +} + +int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex) +{ + UInt32 i; + for(i = 0; i < folder->NumBindPairs; i++) + if (folder->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex) +{ + UInt32 i; + for(i = 0; i < folder->NumBindPairs; i++) + if (folder->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +CFileSize SzFolderGetUnPackSize(CFolder *folder) +{ + int i = (int)SzFolderGetNumOutStreams(folder); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolderFindBindPairForOutStream(folder, i) < 0) + return folder->UnPackSizes[i]; + /* throw 1; */ + return 0; +} + +/* +int FindPackStreamArrayIndex(int inStreamIndex) const +{ + for(int i = 0; i < PackStreams.Size(); i++) + if (PackStreams[i] == inStreamIndex) + return i; + return -1; +} +*/ + +void SzFileInit(CFileItem *fileItem) +{ + fileItem->IsFileCRCDefined = 0; + fileItem->HasStream = 1; + fileItem->IsDirectory = 0; + fileItem->IsAnti = 0; + fileItem->Name = 0; +} + +void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p)) +{ + freeFunc(fileItem->Name); + SzFileInit(fileItem); +} + +void SzArchiveDatabaseInit(CArchiveDatabase *db) +{ + db->NumPackStreams = 0; + db->PackSizes = 0; + db->PackCRCsDefined = 0; + db->PackCRCs = 0; + db->NumFolders = 0; + db->Folders = 0; + db->NumFiles = 0; + db->Files = 0; +} + +void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)) +{ + UInt32 i; + for (i = 0; i < db->NumFolders; i++) + SzFolderFree(&db->Folders[i], freeFunc); + for (i = 0; i < db->NumFiles; i++) + SzFileFree(&db->Files[i], freeFunc); + freeFunc(db->PackSizes); + freeFunc(db->PackCRCsDefined); + freeFunc(db->PackCRCs); + freeFunc(db->Folders); + freeFunc(db->Files); + SzArchiveDatabaseInit(db); +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zItem.h b/utils/lzma/C/7zip/Archive/7z_C/7zItem.h new file mode 100644 index 00000000..876539a9 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zItem.h @@ -0,0 +1,90 @@ +/* 7zItem.h */ + +#ifndef __7Z_ITEM_H +#define __7Z_ITEM_H + +#include "7zMethodID.h" +#include "7zHeader.h" +#include "7zBuffer.h" + +typedef struct _CCoderInfo +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + CMethodID MethodID; + CSzByteBuffer Properties; +}CCoderInfo; + +void SzCoderInfoInit(CCoderInfo *coder); +void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)); + +typedef struct _CBindPair +{ + UInt32 InIndex; + UInt32 OutIndex; +}CBindPair; + +typedef struct _CFolder +{ + UInt32 NumCoders; + CCoderInfo *Coders; + UInt32 NumBindPairs; + CBindPair *BindPairs; + UInt32 NumPackStreams; + UInt32 *PackStreams; + CFileSize *UnPackSizes; + int UnPackCRCDefined; + UInt32 UnPackCRC; + + UInt32 NumUnPackStreams; +}CFolder; + +void SzFolderInit(CFolder *folder); +CFileSize SzFolderGetUnPackSize(CFolder *folder); +int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex); +UInt32 SzFolderGetNumOutStreams(CFolder *folder); +CFileSize SzFolderGetUnPackSize(CFolder *folder); + +/* #define CArchiveFileTime UInt64 */ + +typedef struct _CFileItem +{ + /* + CArchiveFileTime LastWriteTime; + CFileSize StartPos; + UInt32 Attributes; + */ + CFileSize Size; + UInt32 FileCRC; + char *Name; + + Byte IsFileCRCDefined; + Byte HasStream; + Byte IsDirectory; + Byte IsAnti; + /* + int AreAttributesDefined; + int IsLastWriteTimeDefined; + int IsStartPosDefined; + */ +}CFileItem; + +void SzFileInit(CFileItem *fileItem); + +typedef struct _CArchiveDatabase +{ + UInt32 NumPackStreams; + CFileSize *PackSizes; + Byte *PackCRCsDefined; + UInt32 *PackCRCs; + UInt32 NumFolders; + CFolder *Folders; + UInt32 NumFiles; + CFileItem *Files; +}CArchiveDatabase; + +void SzArchiveDatabaseInit(CArchiveDatabase *db); +void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)); + + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zMain.c b/utils/lzma/C/7zip/Archive/7z_C/7zMain.c new file mode 100644 index 00000000..73bf36bb --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zMain.c @@ -0,0 +1,225 @@ +/* +7zMain.c +Test application for 7z Decoder +LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04) +*/ + +#include +#include +#include + +#include "7zCrc.h" +#include "7zIn.h" +#include "7zExtract.h" + +typedef struct _CFileInStream +{ + ISzInStream InStream; + FILE *File; +} CFileInStream; + +#ifdef _LZMA_IN_CB + +#define kBufferSize (1 << 12) +Byte g_Buffer[kBufferSize]; + +SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) +{ + CFileInStream *s = (CFileInStream *)object; + size_t processedSizeLoc; + if (maxRequiredSize > kBufferSize) + maxRequiredSize = kBufferSize; + processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File); + *buffer = g_Buffer; + if (processedSize != 0) + *processedSize = processedSizeLoc; + return SZ_OK; +} + +#else + +SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize) +{ + CFileInStream *s = (CFileInStream *)object; + size_t processedSizeLoc = fread(buffer, 1, size, s->File); + if (processedSize != 0) + *processedSize = processedSizeLoc; + return SZ_OK; +} + +#endif + +SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) +{ + CFileInStream *s = (CFileInStream *)object; + int res = fseek(s->File, (long)pos, SEEK_SET); + if (res == 0) + return SZ_OK; + return SZE_FAIL; +} + +void PrintError(char *sz) +{ + printf("\nERROR: %s\n", sz); +} + +int main(int numargs, char *args[]) +{ + CFileInStream archiveStream; + CArchiveDatabaseEx db; + SZ_RESULT res; + ISzAlloc allocImp; + ISzAlloc allocTempImp; + + printf("\n7z ANSI-C Decoder 4.43 Copyright (c) 1999-2006 Igor Pavlov 2006-06-04\n"); + if (numargs == 1) + { + printf( + "\nUsage: 7zDec \n\n" + "\n" + " e: Extract files from archive\n" + " l: List contents of archive\n" + " t: Test integrity of archive\n"); + return 0; + } + if (numargs < 3) + { + PrintError("incorrect command"); + return 1; + } + + archiveStream.File = fopen(args[2], "rb"); + if (archiveStream.File == 0) + { + PrintError("can not open input file"); + return 1; + } + + archiveStream.InStream.Read = SzFileReadImp; + archiveStream.InStream.Seek = SzFileSeekImp; + + allocImp.Alloc = SzAlloc; + allocImp.Free = SzFree; + + allocTempImp.Alloc = SzAllocTemp; + allocTempImp.Free = SzFreeTemp; + + InitCrcTable(); + SzArDbExInit(&db); + res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); + if (res == SZ_OK) + { + char *command = args[1]; + int listCommand = 0; + int testCommand = 0; + int extractCommand = 0; + if (strcmp(command, "l") == 0) + listCommand = 1; + if (strcmp(command, "t") == 0) + testCommand = 1; + else if (strcmp(command, "e") == 0) + extractCommand = 1; + + if (listCommand) + { + UInt32 i; + for (i = 0; i < db.Database.NumFiles; i++) + { + CFileItem *f = db.Database.Files + i; + printf("%10d %s\n", (int)f->Size, f->Name); + } + } + else if (testCommand || extractCommand) + { + UInt32 i; + + /* + if you need cache, use these 3 variables. + if you use external function, you can make these variable as static. + */ + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ + Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ + size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ + + printf("\n"); + for (i = 0; i < db.Database.NumFiles; i++) + { + size_t offset; + size_t outSizeProcessed; + CFileItem *f = db.Database.Files + i; + if (f->IsDirectory) + printf("Directory "); + else + printf(testCommand ? + "Testing ": + "Extracting"); + printf(" %s", f->Name); + if (f->IsDirectory) + { + printf("\n"); + continue; + } + res = SzExtract(&archiveStream.InStream, &db, i, + &blockIndex, &outBuffer, &outBufferSize, + &offset, &outSizeProcessed, + &allocImp, &allocTempImp); + if (res != SZ_OK) + break; + if (!testCommand) + { + FILE *outputHandle; + UInt32 processedSize; + char *fileName = f->Name; + size_t nameLen = strlen(f->Name); + for (; nameLen > 0; nameLen--) + if (f->Name[nameLen - 1] == '/') + { + fileName = f->Name + nameLen; + break; + } + + outputHandle = fopen(fileName, "wb+"); + if (outputHandle == 0) + { + PrintError("can not open output file"); + res = SZE_FAIL; + break; + } + processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); + if (processedSize != outSizeProcessed) + { + PrintError("can not write output file"); + res = SZE_FAIL; + break; + } + if (fclose(outputHandle)) + { + PrintError("can not close output file"); + res = SZE_FAIL; + break; + } + } + printf("\n"); + } + allocImp.Free(outBuffer); + } + else + { + PrintError("incorrect command"); + res = SZE_FAIL; + } + } + SzArDbExFree(&db, allocImp.Free); + + fclose(archiveStream.File); + if (res == SZ_OK) + { + printf("\nEverything is Ok\n"); + return 0; + } + if (res == SZE_OUTOFMEMORY) + PrintError("can not allocate memory"); + else + printf("\nERROR #%d\n", res); + return 1; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.c b/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.c new file mode 100644 index 00000000..5047359f --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.c @@ -0,0 +1,14 @@ +/* 7zMethodID.c */ + +#include "7zMethodID.h" + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2) +{ + int i; + if (a1->IDSize != a2->IDSize) + return 0; + for (i = 0; i < a1->IDSize; i++) + if (a1->ID[i] != a2->ID[i]) + return 0; + return 1; +} diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.h b/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.h new file mode 100644 index 00000000..162fcd15 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zMethodID.h @@ -0,0 +1,18 @@ +/* 7zMethodID.h */ + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "7zTypes.h" + +#define kMethodIDSize 15 + +typedef struct _CMethodID +{ + Byte ID[kMethodIDSize]; + Byte IDSize; +} CMethodID; + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2); + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7zTypes.h b/utils/lzma/C/7zip/Archive/7z_C/7zTypes.h new file mode 100644 index 00000000..60dd68c3 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7zTypes.h @@ -0,0 +1,67 @@ +/* 7zTypes.h */ + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _SZ_NO_INT_64 */ +/* define it your compiler doesn't support long long int */ + +#ifndef _7ZIP_UINT64_DEFINED +#define _7ZIP_UINT64_DEFINED +#ifdef _SZ_NO_INT_64 +typedef unsigned long UInt64; +#else +#ifdef _MSC_VER +typedef unsigned __int64 UInt64; +#else +typedef unsigned long long int UInt64; +#endif +#endif +#endif + + +/* #define _SZ_FILE_SIZE_64 */ +/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/ + +#ifndef CFileSize +#ifdef _SZ_FILE_SIZE_64 +typedef UInt64 CFileSize; +#else +typedef UInt32 CFileSize; +#endif +#endif + +#define SZ_RESULT int + +#define SZ_OK (0) +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) +#define SZE_CRC_ERROR (3) + +#define SZE_NOTIMPL (4) +#define SZE_FAIL (5) + +#define SZE_ARCHIVE_ERROR (6) + +#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; } + +#endif diff --git a/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsp b/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsp new file mode 100644 index 00000000..cf45463e --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsp @@ -0,0 +1,182 @@ +# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=7z_C - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7z_C.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z_C - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" + +!ELSEIF "$(CFG)" == "7z_C - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z_C - Win32 Release" +# Name "7z_C - Win32 Debug" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaDecode.c +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaTypes.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=.\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=.\7zBuffer.c +# End Source File +# Begin Source File + +SOURCE=.\7zBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=.\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.c +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.c +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.h +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.c +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=.\7zIn.c +# End Source File +# Begin Source File + +SOURCE=.\7zIn.h +# End Source File +# Begin Source File + +SOURCE=.\7zItem.c +# End Source File +# Begin Source File + +SOURCE=.\7zItem.h +# End Source File +# Begin Source File + +SOURCE=.\7zMain.c +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.c +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=.\7zTypes.h +# End Source File +# End Target +# End Project diff --git a/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsw b/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsw new file mode 100644 index 00000000..6fd39621 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/7z_C.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z_C"=.\7z_C.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/utils/lzma/C/7zip/Archive/7z_C/makefile b/utils/lzma/C/7zip/Archive/7z_C/makefile new file mode 100644 index 00000000..9ce2c346 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/makefile @@ -0,0 +1,55 @@ +PROG = 7zDec.exe + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS- +CFLAGS_O1 = $(CFLAGS) -O1 +CFLAGS_O2 = $(CFLAGS) -O2 + +LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CPP) $(CFLAGS_O1) $** +COMPL_O2 = $(CPP) $(CFLAGS_O2) $** +COMPL = $(CPP) $(CFLAGS_O1) $** + + +7Z_OBJS = \ + $O\7zAlloc.obj \ + $O\7zBuffer.obj \ + $O\7zCrc.obj \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zItem.obj \ + $O\7zMain.obj \ + $O\7zMethodID.obj \ + +OBJS = \ + $(7Z_OBJS) \ + $O\LzmaDecode.obj \ + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch + +$O: + if not exist "$O" mkdir "$O" + +$(PROGPATH): $O $(OBJS) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) + + +$(7Z_OBJS): $(*B).c + $(COMPL) +$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c + $(COMPL_O2) diff --git a/utils/lzma/C/7zip/Archive/7z_C/makefile.gcc b/utils/lzma/C/7zip/Archive/7z_C/makefile.gcc new file mode 100644 index 00000000..21b7df47 --- /dev/null +++ b/utils/lzma/C/7zip/Archive/7z_C/makefile.gcc @@ -0,0 +1,50 @@ +PROG = 7zDec +CXX = g++ +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall + +OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +7zAlloc.o: 7zAlloc.c + $(CXX) $(CFLAGS) 7zAlloc.c + +7zBuffer.o: 7zBuffer.c + $(CXX) $(CFLAGS) 7zBuffer.c + +7zCrc.o: 7zCrc.c + $(CXX) $(CFLAGS) 7zCrc.c + +7zDecode.o: 7zDecode.c + $(CXX) $(CFLAGS) 7zDecode.c + +7zExtract.o: 7zExtract.c + $(CXX) $(CFLAGS) 7zExtract.c + +7zHeader.o: 7zHeader.c + $(CXX) $(CFLAGS) 7zHeader.c + +7zIn.o: 7zIn.c + $(CXX) $(CFLAGS) 7zIn.c + +7zItem.o: 7zItem.c + $(CXX) $(CFLAGS) 7zItem.c + +7zMain.o: 7zMain.c + $(CXX) $(CFLAGS) 7zMain.c + +7zMethodID.o: 7zMethodID.c + $(CXX) $(CFLAGS) 7zMethodID.c + +LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c + $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/utils/lzma/C/7zip/Common/FileStreams.cpp b/utils/lzma/C/7zip/Common/FileStreams.cpp new file mode 100644 index 00000000..8a000e4e --- /dev/null +++ b/utils/lzma/C/7zip/Common/FileStreams.cpp @@ -0,0 +1,251 @@ +// FileStreams.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#include +#endif + +#include "FileStreams.h" + +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + // return result ? S_OK: E_FAIL; + #ifdef _WIN32 + return result ? S_OK: (::GetLastError()); + #else + return result ? S_OK: E_FAIL; + #endif +} + +bool CInFileStream::Open(LPCTSTR fileName) +{ + return File.Open(fileName); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool CInFileStream::Open(LPCWSTR fileName) +{ + return File.Open(fileName); +} +#endif +#endif + +STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + UInt32 realProcessedSize; + bool result = File.ReadPart(data, size, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Read(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#ifndef _WIN32_WCE +STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), + data, size, (DWORD *)&realProcessedSize, NULL); + if(processedSize != NULL) + *processedSize = realProcessedSize; + if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) + return S_OK; + return ConvertBoolToHRESULT(res != FALSE); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res; + do + { + res = read(0, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#endif + +STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + + #ifdef _WIN32 + + UInt64 realNewPosition; + bool result = File.Seek(offset, seekOrigin, realNewPosition); + if(newPosition != NULL) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +STDMETHODIMP CInFileStream::GetSize(UInt64 *size) +{ + return ConvertBoolToHRESULT(File.GetLength(*size)); +} + + +////////////////////////// +// COutFileStream + +bool COutFileStream::Create(LPCTSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool COutFileStream::Create(LPCWSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} +#endif +#endif + +STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + UInt32 realProcessedSize; + bool result = File.WritePart(data, size, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Write(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + #ifdef _WIN32 + + UInt64 realNewPosition; + bool result = File.Seek(offset, seekOrigin, realNewPosition); + if(newPosition != NULL) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::SetSize(Int64 newSize) +{ + #ifdef _WIN32 + UInt64 currentPos; + if(!File.Seek(0, FILE_CURRENT, currentPos)) + return E_FAIL; + bool result = File.SetLength(newSize); + UInt64 currentPos2; + result = result && File.Seek(currentPos, currentPos2); + return result ? S_OK : E_FAIL; + #else + return E_FAIL; + #endif +} + +#ifndef _WIN32_WCE +STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = TRUE; + if (size > 0) + { + // Seems that Windows doesn't like big amounts writing to stdout. + // So we limit portions by 32KB. + UInt32 sizeTemp = (1 << 15); + if (sizeTemp > size) + sizeTemp = size; + res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + data, sizeTemp, (DWORD *)&realProcessedSize, NULL); + size -= realProcessedSize; + data = (const void *)((const Byte *)data + realProcessedSize); + if(processedSize != NULL) + *processedSize += realProcessedSize; + } + return ConvertBoolToHRESULT(res != FALSE); + + #else + + ssize_t res; + do + { + res = write(1, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + return S_OK; + #endif +} + +#endif diff --git a/utils/lzma/C/7zip/Common/FileStreams.h b/utils/lzma/C/7zip/Common/FileStreams.h new file mode 100644 index 00000000..9326372a --- /dev/null +++ b/utils/lzma/C/7zip/Common/FileStreams.h @@ -0,0 +1,98 @@ +// FileStreams.h + +#ifndef __FILESTREAMS_H +#define __FILESTREAMS_H + +#ifdef _WIN32 +#include "../../Windows/FileIO.h" +#else +#include "../../Common/C_FileIO.h" +#endif + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +class CInFileStream: + public IInStream, + public IStreamGetSize, + public CMyUnknownImp +{ +public: + #ifdef _WIN32 + NWindows::NFile::NIO::CInFile File; + #else + NC::NFile::NIO::CInFile File; + #endif + CInFileStream() {} + virtual ~CInFileStream() {} + + bool Open(LPCTSTR fileName); + #ifdef _WIN32 + #ifndef _UNICODE + bool Open(LPCWSTR fileName); + #endif + #endif + + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + + STDMETHOD(GetSize)(UInt64 *size); +}; + +#ifndef _WIN32_WCE +class CStdInFileStream: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + // HANDLE File; + // CStdInFileStream() File(INVALID_HANDLE_VALUE): {} + // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); }; + MY_UNKNOWN_IMP + + virtual ~CStdInFileStream() {} + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; +#endif + +class COutFileStream: + public IOutStream, + public CMyUnknownImp +{ +public: + #ifdef _WIN32 + NWindows::NFile::NIO::COutFile File; + #else + NC::NFile::NIO::COutFile File; + #endif + virtual ~COutFileStream() {} + bool Create(LPCTSTR fileName, bool createAlways); + #ifdef _WIN32 + #ifndef _UNICODE + bool Create(LPCWSTR fileName, bool createAlways); + #endif + #endif + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#ifndef _WIN32_WCE +class CStdOutFileStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + virtual ~CStdOutFileStream() {} + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; +#endif + +#endif diff --git a/utils/lzma/C/7zip/Common/InBuffer.cpp b/utils/lzma/C/7zip/Common/InBuffer.cpp new file mode 100644 index 00000000..02f2adfa --- /dev/null +++ b/utils/lzma/C/7zip/Common/InBuffer.cpp @@ -0,0 +1,80 @@ +// InBuffer.cpp + +#include "StdAfx.h" + +#include "InBuffer.h" + +#include "../../Common/Alloc.h" + +CInBuffer::CInBuffer(): + _buffer(0), + _bufferLimit(0), + _bufferBase(0), + _stream(0), + _bufferSize(0) +{} + +bool CInBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_bufferBase != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _bufferBase = (Byte *)::MidAlloc(bufferSize); + return (_bufferBase != 0); +} + +void CInBuffer::Free() +{ + ::MidFree(_bufferBase); + _bufferBase = 0; +} + +void CInBuffer::SetStream(ISequentialInStream *stream) +{ + _stream = stream; +} + +void CInBuffer::Init() +{ + _processedSize = 0; + _buffer = _bufferBase; + _bufferLimit = _buffer; + _wasFinished = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +bool CInBuffer::ReadBlock() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) + return false; + _processedSize += (_buffer - _bufferBase); + UInt32 numProcessedBytes; + HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw CInBufferException(result); + #endif + _buffer = _bufferBase; + _bufferLimit = _buffer + numProcessedBytes; + _wasFinished = (numProcessedBytes == 0); + return (!_wasFinished); +} + +Byte CInBuffer::ReadBlock2() +{ + if(!ReadBlock()) + return 0xFF; + return *_buffer++; +} diff --git a/utils/lzma/C/7zip/Common/InBuffer.h b/utils/lzma/C/7zip/Common/InBuffer.h new file mode 100644 index 00000000..057caa16 --- /dev/null +++ b/utils/lzma/C/7zip/Common/InBuffer.h @@ -0,0 +1,76 @@ +// InBuffer.h + +#ifndef __INBUFFER_H +#define __INBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +class CInBufferException +{ +public: + HRESULT ErrorCode; + CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class CInBuffer +{ + Byte *_buffer; + Byte *_bufferLimit; + Byte *_bufferBase; + CMyComPtr _stream; + UInt64 _processedSize; + UInt32 _bufferSize; + bool _wasFinished; + + bool ReadBlock(); + Byte ReadBlock2(); + +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + CInBuffer(); + ~CInBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetStream(ISequentialInStream *stream); + void Init(); + void ReleaseStream() { _stream.Release(); } + + bool ReadByte(Byte &b) + { + if(_buffer >= _bufferLimit) + if(!ReadBlock()) + return false; + b = *_buffer++; + return true; + } + Byte ReadByte() + { + if(_buffer >= _bufferLimit) + return ReadBlock2(); + return *_buffer++; + } + void ReadBytes(void *data, UInt32 size, UInt32 &processedSize) + { + for(processedSize = 0; processedSize < size; processedSize++) + if (!ReadByte(((Byte *)data)[processedSize])) + return; + } + bool ReadBytes(void *data, UInt32 size) + { + UInt32 processedSize; + ReadBytes(data, size, processedSize); + return (processedSize == size); + } + UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/utils/lzma/C/7zip/Common/OutBuffer.cpp b/utils/lzma/C/7zip/Common/OutBuffer.cpp new file mode 100644 index 00000000..a73fa7c5 --- /dev/null +++ b/utils/lzma/C/7zip/Common/OutBuffer.cpp @@ -0,0 +1,116 @@ +// OutByte.cpp + +#include "StdAfx.h" + +#include "OutBuffer.h" + +#include "../../Common/Alloc.h" + +bool COutBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_buffer != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _buffer = (Byte *)::MidAlloc(bufferSize); + return (_buffer != 0); +} + +void COutBuffer::Free() +{ + ::MidFree(_buffer); + _buffer = 0; +} + +void COutBuffer::SetStream(ISequentialOutStream *stream) +{ + _stream = stream; +} + +void COutBuffer::Init() +{ + _streamPos = 0; + _limitPos = _bufferSize; + _pos = 0; + _processedSize = 0; + _overDict = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +UInt64 COutBuffer::GetProcessedSize() const +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufferSize; + return res; +} + + +HRESULT COutBuffer::FlushPart() +{ + // _streamPos < _bufferSize + UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + result = ErrorCode; + #endif + if (_buffer2 != 0) + { + memmove(_buffer2, _buffer + _streamPos, size); + _buffer2 += size; + } + + if (_stream != 0 + #ifdef _NO_EXCEPTIONS + && (ErrorCode == S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buffer + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + if (_streamPos == _bufferSize) + _streamPos = 0; + if (_pos == _bufferSize) + { + _overDict = true; + _pos = 0; + } + _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; + _processedSize += size; + return result; +} + +HRESULT COutBuffer::Flush() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + while(_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = FlushPart(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff --git a/utils/lzma/C/7zip/Common/OutBuffer.h b/utils/lzma/C/7zip/Common/OutBuffer.h new file mode 100644 index 00000000..0ce54e21 --- /dev/null +++ b/utils/lzma/C/7zip/Common/OutBuffer.h @@ -0,0 +1,64 @@ +// OutBuffer.h + +#ifndef __OUTBUFFER_H +#define __OUTBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +struct COutBufferException +{ + HRESULT ErrorCode; + COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buffer; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufferSize; + CMyComPtr _stream; + UInt64 _processedSize; + Byte *_buffer2; + bool _overDict; + + HRESULT FlushPart(); + void FlushWithCheck(); +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {} + ~COutBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetMemStream(Byte *buffer) { _buffer2 = buffer; } + void SetStream(ISequentialOutStream *stream); + void Init(); + HRESULT Flush(); + void ReleaseStream() { _stream.Release(); } + + void WriteByte(Byte b) + { + _buffer[_pos++] = b; + if(_pos == _limitPos) + FlushWithCheck(); + } + void WriteBytes(const void *data, size_t size) + { + for (size_t i = 0; i < size; i++) + WriteByte(((const Byte *)data)[i]); + } + + UInt64 GetProcessedSize() const; +}; + +#endif diff --git a/utils/lzma/C/7zip/Common/StdAfx.h b/utils/lzma/C/7zip/Common/StdAfx.h new file mode 100644 index 00000000..27a77b10 --- /dev/null +++ b/utils/lzma/C/7zip/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" + +#endif diff --git a/utils/lzma/C/7zip/Common/StreamUtils.cpp b/utils/lzma/C/7zip/Common/StreamUtils.cpp new file mode 100644 index 00000000..a5d9ac0e --- /dev/null +++ b/utils/lzma/C/7zip/Common/StreamUtils.cpp @@ -0,0 +1,44 @@ +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" +#include "StreamUtils.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (Byte *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + break; + } + return S_OK; +} diff --git a/utils/lzma/C/7zip/Common/StreamUtils.h b/utils/lzma/C/7zip/Common/StreamUtils.h new file mode 100644 index 00000000..59f88733 --- /dev/null +++ b/utils/lzma/C/7zip/Common/StreamUtils.h @@ -0,0 +1,11 @@ +// StreamUtils.h + +#ifndef __STREAMUTILS_H +#define __STREAMUTILS_H + +#include "../IStream.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize); +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/ARM.cpp b/utils/lzma/C/7zip/Compress/Branch/ARM.cpp new file mode 100644 index 00000000..4bd5e183 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/ARM.cpp @@ -0,0 +1,16 @@ +// ARM.cpp + +#include "StdAfx.h" +#include "ARM.h" + +#include "BranchARM.c" + +UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARM_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARM_Convert(data, size, _bufferPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/ARM.h b/utils/lzma/C/7zip/Compress/Branch/ARM.h new file mode 100644 index 00000000..5561299b --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/ARM.h @@ -0,0 +1,10 @@ +// ARM.h + +#ifndef __ARM_H +#define __ARM_H + +#include "BranchCoder.h" + +MyClassA(BC_ARM, 0x05, 1) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/ARMThumb.cpp b/utils/lzma/C/7zip/Compress/Branch/ARMThumb.cpp new file mode 100644 index 00000000..fbd25701 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/ARMThumb.cpp @@ -0,0 +1,16 @@ +// ARMThumb.cpp + +#include "StdAfx.h" +#include "ARMThumb.h" + +#include "BranchARMThumb.c" + +UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARMThumb_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARMThumb_Convert(data, size, _bufferPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/ARMThumb.h b/utils/lzma/C/7zip/Compress/Branch/ARMThumb.h new file mode 100644 index 00000000..601e40bf --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/ARMThumb.h @@ -0,0 +1,10 @@ +// ARMThumb.h + +#ifndef __ARMTHUMB_H +#define __ARMTHUMB_H + +#include "BranchCoder.h" + +MyClassA(BC_ARMThumb, 0x07, 1) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchARM.c b/utils/lzma/C/7zip/Compress/Branch/BranchARM.c new file mode 100644 index 00000000..04bd81e0 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchARM.c @@ -0,0 +1,26 @@ +/* BranchARM.c */ + +#include "BranchARM.h" + +UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + UInt32 dest; + if (encoding) + dest = nowPos + i + 8 + src; + else + dest = src - (nowPos + i + 8); + dest >>= 2; + data[i + 2] = (dest >> 16); + data[i + 1] = (dest >> 8); + data[i + 0] = dest; + } + } + return i; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchARM.h b/utils/lzma/C/7zip/Compress/Branch/BranchARM.h new file mode 100644 index 00000000..02eb1b47 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchARM.h @@ -0,0 +1,10 @@ +// BranchARM.h + +#ifndef __BRANCH_ARM_H +#define __BRANCH_ARM_H + +#include "BranchTypes.h" + +UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.c b/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.c new file mode 100644 index 00000000..4e4b04b0 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.c @@ -0,0 +1,35 @@ +/* BranchARMThumb.c */ + +#include "BranchARMThumb.h" + +UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 src = + ((data[i + 1] & 0x7) << 19) | + (data[i + 0] << 11) | + ((data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + UInt32 dest; + if (encoding) + dest = nowPos + i + 4 + src; + else + dest = src - (nowPos + i + 4); + dest >>= 1; + + data[i + 1] = 0xF0 | ((dest >> 19) & 0x7); + data[i + 0] = (dest >> 11); + data[i + 3] = 0xF8 | ((dest >> 8) & 0x7); + data[i + 2] = (dest); + i += 2; + } + } + return i; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.h b/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.h new file mode 100644 index 00000000..d67e6e5a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchARMThumb.h @@ -0,0 +1,10 @@ +// BranchARMThumb.h + +#ifndef __BRANCH_ARM_THUMB_H +#define __BRANCH_ARM_THUMB_H + +#include "BranchTypes.h" + +UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchCoder.cpp b/utils/lzma/C/7zip/Compress/Branch/BranchCoder.cpp new file mode 100644 index 00000000..8d25f0d5 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchCoder.cpp @@ -0,0 +1,18 @@ +// BranchCoder.cpp + +#include "StdAfx.h" +#include "BranchCoder.h" + +STDMETHODIMP CBranchConverter::Init() +{ + _bufferPos = 0; + SubInit(); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size) +{ + UInt32 processedSize = SubFilter(data, size); + _bufferPos += processedSize; + return processedSize; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchCoder.h b/utils/lzma/C/7zip/Compress/Branch/BranchCoder.h new file mode 100644 index 00000000..4b53b6cb --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchCoder.h @@ -0,0 +1,54 @@ +// BranchCoder.h + +#ifndef __BRANCH_CODER_H +#define __BRANCH_CODER_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "Common/Alloc.h" + +#include "../../ICoder.h" + +class CBranchConverter: + public ICompressFilter, + public CMyUnknownImp +{ +protected: + UInt32 _bufferPos; + virtual void SubInit() {} + virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0; +public: + MY_UNKNOWN_IMP; + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClass2b(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClassA(Name, id, subId) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderA(Name ## _Encoder) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderA(Name ## _Decoder) + +#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchIA64.c b/utils/lzma/C/7zip/Compress/Branch/BranchIA64.c new file mode 100644 index 00000000..e7775564 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchIA64.c @@ -0,0 +1,63 @@ +/* BranchIA64.c */ + +#include "BranchIA64.h" + +const Byte kBranchTable[32] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 6, 6, 0, 0, 7, 7, + 4, 4, 0, 0, 4, 4, 0, 0 +}; + +UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 16 <= size; i += 16) + { + UInt32 instrTemplate = data[i] & 0x1F; + UInt32 mask = kBranchTable[instrTemplate]; + UInt32 bitPos = 5; + for (int slot = 0; slot < 3; slot++, bitPos += 41) + { + if (((mask >> slot) & 1) == 0) + continue; + UInt32 bytePos = (bitPos >> 3); + UInt32 bitRes = bitPos & 0x7; + UInt64 instruction = 0; + int j; + for (j = 0; j < 6; j++) + instruction += (UInt64)(data[i + j + bytePos]) << (8 * j); + + UInt64 instNorm = instruction >> bitRes; + if (((instNorm >> 37) & 0xF) == 0x5 + && ((instNorm >> 9) & 0x7) == 0 + /* && (instNorm & 0x3F)== 0 */ + ) + { + UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF); + src |= ((instNorm >> 36) & 1) << 20; + + src <<= 4; + + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + + dest >>= 4; + + instNorm &= ~(UInt64(0x8FFFFF) << 13); + instNorm |= (UInt64(dest & 0xFFFFF) << 13); + instNorm |= (UInt64(dest & 0x100000) << (36 - 20)); + + instruction &= (1 << bitRes) - 1; + instruction |= (instNorm << bitRes); + for (j = 0; j < 6; j++) + data[i + j + bytePos] = Byte(instruction >> (8 * j)); + } + } + } + return i; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchIA64.h b/utils/lzma/C/7zip/Compress/Branch/BranchIA64.h new file mode 100644 index 00000000..b7757fe9 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchIA64.h @@ -0,0 +1,10 @@ +// BranchIA64.h + +#ifndef __BRANCH_IA64_H +#define __BRANCH_IA64_H + +#include "BranchTypes.h" + +UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchPPC.c b/utils/lzma/C/7zip/Compress/Branch/BranchPPC.c new file mode 100644 index 00000000..a173eb15 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchPPC.c @@ -0,0 +1,36 @@ +/* BranchPPC.c */ + +#include "BranchPPC.h" + +UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + /* PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) */ + if ((data[i] >> 2) == 0x12 && + ( + (data[i + 3] & 3) == 1 + /* || (data[i+3] & 3) == 3 */ + ) + ) + { + UInt32 src = ((data[i + 0] & 3) << 24) | + (data[i + 1] << 16) | + (data[i + 2] << 8) | + (data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + data[i + 0] = 0x48 | ((dest >> 24) & 0x3); + data[i + 1] = (dest >> 16); + data[i + 2] = (dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchPPC.h b/utils/lzma/C/7zip/Compress/Branch/BranchPPC.h new file mode 100644 index 00000000..c02bba19 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchPPC.h @@ -0,0 +1,10 @@ +// BranchPPC.h + +#ifndef __BRANCH_PPC_H +#define __BRANCH_PPC_H + +#include "BranchTypes.h" + +UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.c b/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.c new file mode 100644 index 00000000..c175875b --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.c @@ -0,0 +1,36 @@ +/* BranchSPARC.c */ + +#include "BranchSPARC.h" + +UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || + data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + + src <<= 2; + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.h b/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.h new file mode 100644 index 00000000..fbe9e673 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchSPARC.h @@ -0,0 +1,10 @@ +// BranchSPARC.h + +#ifndef __BRANCH_SPARC_H +#define __BRANCH_SPARC_H + +#include "BranchTypes.h" + +UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchTypes.h b/utils/lzma/C/7zip/Compress/Branch/BranchTypes.h new file mode 100644 index 00000000..f7ad3abc --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchTypes.h @@ -0,0 +1,25 @@ +/* BranchTypes.h */ + +#ifndef __BRANCHTYPES_H +#define __BRANCHTYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchX86.c b/utils/lzma/C/7zip/Compress/Branch/BranchX86.c new file mode 100644 index 00000000..2c6f69a5 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchX86.c @@ -0,0 +1,101 @@ +/* BranchX86.c */ + +#include "BranchX86.h" + +/* +static int inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} +*/ +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +/* +void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos) +{ + *prevMask = 0; + *prevPos = (UInt32)(-5); +} +*/ + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding) +{ + UInt32 bufferPos = 0; + UInt32 limit; + + if (endPos < 5) + return 0; + + if (nowPos - *prevPos > 5) + *prevPos = nowPos - 5; + + limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = buffer[bufferPos]; + UInt32 offset; + if (b != 0xE8 && b != 0xE9) + { + bufferPos++; + continue; + } + offset = (nowPos + bufferPos - *prevPos); + *prevPos = (nowPos + bufferPos); + if (offset > 5) + *prevMask = 0; + else + { + UInt32 i; + for (i = 0; i < offset; i++) + { + *prevMask &= 0x77; + *prevMask <<= 1; + } + } + b = buffer[bufferPos + 4]; + if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] && + (*prevMask >> 1) < 0x10) + { + UInt32 src = + ((UInt32)(b) << 24) | + ((UInt32)(buffer[bufferPos + 3]) << 16) | + ((UInt32)(buffer[bufferPos + 2]) << 8) | + (buffer[bufferPos + 1]); + + UInt32 dest; + while(1) + { + UInt32 index; + if (encoding) + dest = (nowPos + bufferPos + 5) + src; + else + dest = src - (nowPos + bufferPos + 5); + if (*prevMask == 0) + break; + index = kMaskToBitNumber[*prevMask >> 1]; + b = (Byte)(dest >> (24 - index * 8)); + if (!Test86MSByte(b)) + break; + src = dest ^ ((1 << (32 - index * 8)) - 1); + } + buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1)); + buffer[bufferPos + 3] = (Byte)(dest >> 16); + buffer[bufferPos + 2] = (Byte)(dest >> 8); + buffer[bufferPos + 1] = (Byte)dest; + bufferPos += 5; + *prevMask = 0; + } + else + { + bufferPos++; + *prevMask |= 1; + if (Test86MSByte(b)) + *prevMask |= 0x10; + } + } + return bufferPos; +} diff --git a/utils/lzma/C/7zip/Compress/Branch/BranchX86.h b/utils/lzma/C/7zip/Compress/Branch/BranchX86.h new file mode 100644 index 00000000..25c1ae51 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/BranchX86.h @@ -0,0 +1,13 @@ +/* BranchX86.h */ + +#ifndef __BRANCHX86_H +#define __BRANCHX86_H + +#include "BranchTypes.h" + +#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); } + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/IA64.cpp b/utils/lzma/C/7zip/Compress/Branch/IA64.cpp new file mode 100644 index 00000000..75dfdcba --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/IA64.cpp @@ -0,0 +1,16 @@ +// IA64.cpp + +#include "StdAfx.h" +#include "IA64.h" + +#include "BranchIA64.c" + +UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::IA64_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::IA64_Convert(data, size, _bufferPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/IA64.h b/utils/lzma/C/7zip/Compress/Branch/IA64.h new file mode 100644 index 00000000..7fe715ed --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/IA64.h @@ -0,0 +1,10 @@ +// IA64.h + +#ifndef __IA64_H +#define __IA64_H + +#include "BranchCoder.h" + +MyClassA(BC_IA64, 0x04, 1) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/PPC.cpp b/utils/lzma/C/7zip/Compress/Branch/PPC.cpp new file mode 100644 index 00000000..197a8e58 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/PPC.cpp @@ -0,0 +1,17 @@ +// PPC.cpp + +#include "StdAfx.h" +#include "PPC.h" + +#include "Windows/Defs.h" +#include "BranchPPC.c" + +UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::PPC_B_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::PPC_B_Convert(data, size, _bufferPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/PPC.h b/utils/lzma/C/7zip/Compress/Branch/PPC.h new file mode 100644 index 00000000..a0e33444 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/PPC.h @@ -0,0 +1,10 @@ +// PPC.h + +#ifndef __PPC_H +#define __PPC_H + +#include "BranchCoder.h" + +MyClassA(BC_PPC_B, 0x02, 5) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/SPARC.cpp b/utils/lzma/C/7zip/Compress/Branch/SPARC.cpp new file mode 100644 index 00000000..d054eaaf --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/SPARC.cpp @@ -0,0 +1,17 @@ +// SPARC.cpp + +#include "StdAfx.h" +#include "SPARC.h" + +#include "Windows/Defs.h" +#include "BranchSPARC.c" + +UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/SPARC.h b/utils/lzma/C/7zip/Compress/Branch/SPARC.h new file mode 100644 index 00000000..e0a682ef --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/SPARC.h @@ -0,0 +1,10 @@ +// SPARC.h + +#ifndef __SPARC_H +#define __SPARC_H + +#include "BranchCoder.h" + +MyClassA(BC_SPARC, 0x08, 5) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/StdAfx.h b/utils/lzma/C/7zip/Compress/Branch/StdAfx.h new file mode 100644 index 00000000..e7fb6986 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/x86.cpp b/utils/lzma/C/7zip/Compress/Branch/x86.cpp new file mode 100644 index 00000000..013e42b6 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/x86.cpp @@ -0,0 +1,18 @@ +// x86.cpp + +#include "StdAfx.h" +#include "x86.h" + +#include "Windows/Defs.h" + +#include "BranchX86.c" + +UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1); +} + +UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0); +} diff --git a/utils/lzma/C/7zip/Compress/Branch/x86.h b/utils/lzma/C/7zip/Compress/Branch/x86.h new file mode 100644 index 00000000..10d03982 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/x86.h @@ -0,0 +1,19 @@ +// x86.h + +#ifndef __X86_H +#define __X86_H + +#include "BranchCoder.h" +#include "BranchX86.h" + +struct CBranch86 +{ + UInt32 _prevMask; + UInt32 _prevPos; + void x86Init() { x86_Convert_Init(_prevMask, _prevPos); } +}; + +MyClassB(BCJ_x86, 0x01, 3, CBranch86 , + virtual void SubInit() { x86Init(); }) + +#endif diff --git a/utils/lzma/C/7zip/Compress/Branch/x86_2.cpp b/utils/lzma/C/7zip/Compress/Branch/x86_2.cpp new file mode 100644 index 00000000..8f7bff21 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/x86_2.cpp @@ -0,0 +1,412 @@ +// x86_2.cpp + +#include "StdAfx.h" +#include "x86_2.h" + +#include "../../../Common/Alloc.h" + +static const int kBufferSize = 1 << 17; + +inline bool IsJcc(Byte b0, Byte b1) +{ + return (b0 == 0x0F && (b1 & 0xF0) == 0x80); +} + +#ifndef EXTRACT_ONLY + +static bool inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} + +bool CBCJ2_x86_Encoder::Create() +{ + if (!_mainStream.Create(1 << 16)) + return false; + if (!_callStream.Create(1 << 20)) + return false; + if (!_jumpStream.Create(1 << 20)) + return false; + if (!_rangeEncoder.Create(1 << 20)) + return false; + if (_buffer == 0) + { + _buffer = (Byte *)MidAlloc(kBufferSize); + if (_buffer == 0) + return false; + } + return true; +} + +CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder() +{ + ::MidFree(_buffer); +} + +HRESULT CBCJ2_x86_Encoder::Flush() +{ + RINOK(_mainStream.Flush()); + RINOK(_callStream.Flush()); + RINOK(_jumpStream.Flush()); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +const UInt32 kDefaultLimit = (1 << 24); + +HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 1 || numOutStreams != 4) + return E_INVALIDARG; + + if (!Create()) + return E_OUTOFMEMORY; + + bool sizeIsDefined = false; + UInt64 inSize; + if (inSizes != NULL) + if (inSizes[0] != NULL) + { + inSize = *inSizes[0]; + if (inSize <= kDefaultLimit) + sizeIsDefined = true; + } + + ISequentialInStream *inStream = inStreams[0]; + + _mainStream.SetStream(outStreams[0]); + _mainStream.Init(); + _callStream.SetStream(outStreams[1]); + _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); + _jumpStream.Init(); + _rangeEncoder.SetStream(outStreams[3]); + _rangeEncoder.Init(); + for (int i = 0; i < 256; i++) + _statusE8Encoder[i].Init(); + _statusE9Encoder.Init(); + _statusJccEncoder.Init(); + CCoderReleaser releaser(this); + + CMyComPtr getSubStreamSize; + { + inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + } + + UInt32 nowPos = 0; + UInt64 nowPos64 = 0; + UInt32 bufferPos = 0; + + Byte prevByte = 0; + + UInt64 subStreamIndex = 0; + UInt64 subStreamStartPos = 0; + UInt64 subStreamEndPos = 0; + + while(true) + { + UInt32 processedSize = 0; + while(true) + { + UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 processedSizeLoc; + if (size == 0) + break; + RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + if (processedSizeLoc == 0) + break; + processedSize += processedSizeLoc; + } + UInt32 endPos = bufferPos + processedSize; + + if (endPos < 5) + { + // change it + for (bufferPos = 0; bufferPos < endPos; bufferPos++) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else if (IsJcc(prevByte, b)) + _statusJccEncoder.Encode(&_rangeEncoder, 0); + prevByte = b; + } + return Flush(); + } + + bufferPos = 0; + + UInt32 limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + bufferPos++; + prevByte = b; + continue; + } + Byte nextByte = _buffer[bufferPos + 4]; + UInt32 src = + (UInt32(nextByte) << 24) | + (UInt32(_buffer[bufferPos + 3]) << 16) | + (UInt32(_buffer[bufferPos + 2]) << 8) | + (_buffer[bufferPos + 1]); + UInt32 dest = (nowPos + bufferPos + 5) + src; + // if (Test86MSByte(nextByte)) + bool convert; + if (getSubStreamSize != NULL) + { + UInt64 currentPos = (nowPos64 + bufferPos); + while (subStreamEndPos < currentPos) + { + UInt64 subStreamSize; + HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); + if (result == S_OK) + { + subStreamStartPos = subStreamEndPos; + subStreamEndPos += subStreamSize; + subStreamIndex++; + } + else if (result == S_FALSE || result == E_NOTIMPL) + { + getSubStreamSize.Release(); + subStreamStartPos = 0; + subStreamEndPos = subStreamStartPos - 1; + } + else + return result; + } + if (getSubStreamSize == NULL) + { + if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + } + else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) + convert = Test86MSByte(nextByte); + else + { + UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); + convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); + } + } + else if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + if (convert) + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 1); + else + _statusJccEncoder.Encode(&_rangeEncoder, 1); + + bufferPos += 5; + if (b == 0xE8) + { + _callStream.WriteByte((Byte)(dest >> 24)); + _callStream.WriteByte((Byte)(dest >> 16)); + _callStream.WriteByte((Byte)(dest >> 8)); + _callStream.WriteByte((Byte)(dest)); + } + else + { + _jumpStream.WriteByte((Byte)(dest >> 24)); + _jumpStream.WriteByte((Byte)(dest >> 16)); + _jumpStream.WriteByte((Byte)(dest >> 8)); + _jumpStream.WriteByte((Byte)(dest)); + } + prevByte = nextByte; + } + else + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else + _statusJccEncoder.Encode(&_rangeEncoder, 0); + bufferPos++; + prevByte = b; + } + } + nowPos += bufferPos; + nowPos64 += bufferPos; + + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + } + + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} + +STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +#endif + +HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 4 || numOutStreams != 1) + return E_INVALIDARG; + + if (!_mainInStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + _mainInStream.SetStream(inStreams[0]); + _callStream.SetStream(inStreams[1]); + _jumpStream.SetStream(inStreams[2]); + _rangeDecoder.SetStream(inStreams[3]); + _outStream.SetStream(outStreams[0]); + + _mainInStream.Init(); + _callStream.Init(); + _jumpStream.Init(); + _rangeDecoder.Init(); + _outStream.Init(); + + for (int i = 0; i < 256; i++) + _statusE8Decoder[i].Init(); + _statusE9Decoder.Init(); + _statusJccDecoder.Init(); + + CCoderReleaser releaser(this); + + Byte prevByte = 0; + UInt32 processedBytes = 0; + while(true) + { + if (processedBytes > (1 << 20) && progress != NULL) + { + UInt64 nowPos64 = _outStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(NULL, &nowPos64)); + processedBytes = 0; + } + processedBytes++; + Byte b; + if (!_mainInStream.ReadByte(b)) + return Flush(); + _outStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + prevByte = b; + continue; + } + bool status; + if (b == 0xE8) + status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1); + else if (b == 0xE9) + status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1); + else + status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1); + if (status) + { + UInt32 src; + if (b == 0xE8) + { + Byte b0; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + else + { + Byte b0; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; + _outStream.WriteByte((Byte)(dest)); + _outStream.WriteByte((Byte)(dest >> 8)); + _outStream.WriteByte((Byte)(dest >> 16)); + _outStream.WriteByte((Byte)(dest >> 24)); + prevByte = (dest >> 24); + processedBytes += 4; + } + else + prevByte = b; + } +} + +STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} diff --git a/utils/lzma/C/7zip/Compress/Branch/x86_2.h b/utils/lzma/C/7zip/Compress/Branch/x86_2.h new file mode 100644 index 00000000..3d34eb8d --- /dev/null +++ b/utils/lzma/C/7zip/Compress/Branch/x86_2.h @@ -0,0 +1,133 @@ +// x86_2.h + +#ifndef __BRANCH_X86_2_H +#define __BRANCH_X86_2_H + +#include "../../../Common/MyCom.h" +#include "../RangeCoder/RangeCoderBit.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278B-0303-010100000100} +#define MyClass2_a(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClass_a(Name, id, subId) \ +MyClass2_a(Name ## _Encoder, id, subId, 0x01) \ +MyClass2_a(Name ## _Decoder, id, subId, 0x00) + +MyClass_a(BCJ2_x86, 0x01, 0x1B) + +const int kNumMoveBits = 5; + +#ifndef EXTRACT_ONLY + +class CBCJ2_x86_Encoder: + public ICompressCoder2, + public CMyUnknownImp +{ + Byte *_buffer; +public: + CBCJ2_x86_Encoder(): _buffer(0) {}; + ~CBCJ2_x86_Encoder(); + bool Create(); + + COutBuffer _mainStream; + COutBuffer _callStream; + COutBuffer _jumpStream; + NCompress::NRangeCoder::CEncoder _rangeEncoder; + NCompress::NRangeCoder::CBitEncoder _statusE8Encoder[256]; + NCompress::NRangeCoder::CBitEncoder _statusE9Encoder; + NCompress::NRangeCoder::CBitEncoder _statusJccEncoder; + + HRESULT Flush(); + void ReleaseStreams() + { + _mainStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeEncoder.ReleaseStream(); + } + + class CCoderReleaser + { + CBCJ2_x86_Encoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + + MY_UNKNOWN_IMP + + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +#endif + +class CBCJ2_x86_Decoder: + public ICompressCoder2, + public CMyUnknownImp +{ +public: + CInBuffer _mainInStream; + CInBuffer _callStream; + CInBuffer _jumpStream; + NCompress::NRangeCoder::CDecoder _rangeDecoder; + NCompress::NRangeCoder::CBitDecoder _statusE8Decoder[256]; + NCompress::NRangeCoder::CBitDecoder _statusE9Decoder; + NCompress::NRangeCoder::CBitDecoder _statusJccDecoder; + + COutBuffer _outStream; + + void ReleaseStreams() + { + _mainInStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeDecoder.ReleaseStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + class CCoderReleaser + { + CBCJ2_x86_Decoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + MY_UNKNOWN_IMP + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h new file mode 100644 index 00000000..b3b3f13a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h @@ -0,0 +1,54 @@ +// BinTree.h + +#include "../LZInWindow.h" +#include "../IMatchFinder.h" + +namespace BT_NAMESPACE { + +typedef UInt32 CIndex; +const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1; + +class CMatchFinder: + public IMatchFinder, + public CLZInWindow, + public CMyUnknownImp, + public IMatchFinderSetNumPasses +{ + UInt32 _cyclicBufferPos; + UInt32 _cyclicBufferSize; // it must be historySize + 1 + UInt32 _matchMaxLen; + CIndex *_hash; + CIndex *_son; + UInt32 _hashMask; + UInt32 _cutValue; + UInt32 _hashSizeSum; + + void Normalize(); + void FreeThisClassMemory(); + void FreeMemory(); + + MY_UNKNOWN_IMP + + STDMETHOD(SetStream)(ISequentialInStream *inStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(Init)(); + HRESULT MovePos(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes); + STDMETHOD_(void, ChangeBufferPos)(); + + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter); + STDMETHOD(GetMatches)(UInt32 *distances); + STDMETHOD(Skip)(UInt32 num); + +public: + CMatchFinder(); + virtual ~CMatchFinder(); + virtual void SetNumPasses(UInt32 numPasses) { _cutValue = numPasses; } +}; + +} diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h new file mode 100644 index 00000000..74ca8d9d --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h @@ -0,0 +1,12 @@ +// BinTree2.h + +#ifndef __BINTREE2_H +#define __BINTREE2_H + +#define BT_NAMESPACE NBT2 + +#include "BinTreeMain.h" + +#undef BT_NAMESPACE + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h new file mode 100644 index 00000000..76bd9ddd --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h @@ -0,0 +1,16 @@ +// BinTree3.h + +#ifndef __BINTREE3_H +#define __BINTREE3_H + +#define BT_NAMESPACE NBT3 + +#define HASH_ARRAY_2 + +#include "BinTreeMain.h" + +#undef HASH_ARRAY_2 + +#undef BT_NAMESPACE + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h new file mode 100644 index 00000000..d2c092b4 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h @@ -0,0 +1,16 @@ +// BinTree3Z.h + +#ifndef __BINTREE3Z_H +#define __BINTREE3Z_H + +#define BT_NAMESPACE NBT3Z + +#define HASH_ZIP + +#include "BinTreeMain.h" + +#undef HASH_ZIP + +#undef BT_NAMESPACE + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h new file mode 100644 index 00000000..08e2d1ce --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h @@ -0,0 +1,18 @@ +// BinTree4.h + +#ifndef __BINTREE4_H +#define __BINTREE4_H + +#define BT_NAMESPACE NBT4 + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 + +#include "BinTreeMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 + +#undef BT_NAMESPACE + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h new file mode 100644 index 00000000..7a6f621a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h @@ -0,0 +1,531 @@ +// BinTreeMain.h + +#include "../../../../Common/Defs.h" +#include "../../../../Common/CRC.h" +#include "../../../../Common/Alloc.h" + +#include "BinTree.h" + +// #include +// It's for prefetch +// But prefetch doesn't give big gain in K8. + +namespace BT_NAMESPACE { + +#ifdef HASH_ARRAY_2 + static const UInt32 kHash2Size = 1 << 10; + #define kNumHashDirectBytes 0 + #ifdef HASH_ARRAY_3 + static const UInt32 kNumHashBytes = 4; + static const UInt32 kHash3Size = 1 << 16; + #else + static const UInt32 kNumHashBytes = 3; + #endif + static const UInt32 kHashSize = 0; + static const UInt32 kMinMatchCheck = kNumHashBytes; + static const UInt32 kStartMaxLen = 1; +#else + #ifdef HASH_ZIP + #define kNumHashDirectBytes 0 + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << 16; + static const UInt32 kMinMatchCheck = kNumHashBytes; + static const UInt32 kStartMaxLen = 1; + #else + #define kNumHashDirectBytes 2 + static const UInt32 kNumHashBytes = 2; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); + static const UInt32 kMinMatchCheck = kNumHashBytes + 1; + static const UInt32 kStartMaxLen = 1; + #endif +#endif + +#ifdef HASH_ARRAY_2 +#ifdef HASH_ARRAY_3 +static const UInt32 kHash3Offset = kHash2Size; +#endif +#endif + +static const UInt32 kFixHashSize = 0 + #ifdef HASH_ARRAY_2 + + kHash2Size + #ifdef HASH_ARRAY_3 + + kHash3Size + #endif + #endif + ; + +CMatchFinder::CMatchFinder(): + _hash(0) +{ +} + +void CMatchFinder::FreeThisClassMemory() +{ + BigFree(_hash); + _hash = 0; +} + +void CMatchFinder::FreeMemory() +{ + FreeThisClassMemory(); + CLZInWindow::Free(); +} + +CMatchFinder::~CMatchFinder() +{ + FreeMemory(); +} + +STDMETHODIMP CMatchFinder::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) +{ + if (historySize > kMaxValForNormalize - 256) + { + FreeMemory(); + return E_INVALIDARG; + } + _cutValue = + #ifdef _HASH_CHAIN + 8 + (matchMaxLen >> 2); + #else + 16 + (matchMaxLen >> 1); + #endif + UInt32 sizeReserv = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + if (CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, sizeReserv)) + { + _matchMaxLen = matchMaxLen; + UInt32 newCyclicBufferSize = historySize + 1; + if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize) + return S_OK; + FreeThisClassMemory(); + _cyclicBufferSize = newCyclicBufferSize; // don't change it + + UInt32 hs = kHashSize; + + #ifdef HASH_ARRAY_2 + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + { + #ifdef HASH_ARRAY_3 + hs >>= 1; + #else + hs = (1 << 24) - 1; + #endif + } + _hashMask = hs; + hs++; + #endif + _hashSizeSum = hs + kFixHashSize; + UInt32 numItems = _hashSizeSum + _cyclicBufferSize + #ifndef _HASH_CHAIN + * 2 + #endif + ; + size_t sizeInBytes = (size_t)numItems * sizeof(CIndex); + if (sizeInBytes / sizeof(CIndex) != numItems) + return E_OUTOFMEMORY; + _hash = (CIndex *)BigAlloc(sizeInBytes); + _son = _hash + _hashSizeSum; + if (_hash != 0) + return S_OK; + } + FreeMemory(); + return E_OUTOFMEMORY; +} + +static const UInt32 kEmptyHashValue = 0; + +STDMETHODIMP CMatchFinder::SetStream(ISequentialInStream *stream) +{ + CLZInWindow::SetStream(stream); + return S_OK; +} + +STDMETHODIMP CMatchFinder::Init() +{ + RINOK(CLZInWindow::Init()); + for(UInt32 i = 0; i < _hashSizeSum; i++) + _hash[i] = kEmptyHashValue; + _cyclicBufferPos = 0; + ReduceOffsets(-1); + return S_OK; +} + +STDMETHODIMP_(void) CMatchFinder::ReleaseStream() +{ + // ReleaseStream(); +} + +#ifdef HASH_ARRAY_2 +#ifdef HASH_ARRAY_3 + +#define HASH_CALC { \ + UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ (UInt32(cur[2]) << 8)) & (kHash3Size - 1); \ + hashValue = (temp ^ (UInt32(cur[2]) << 8) ^ (CCRC::Table[cur[3]] << 5)) & _hashMask; } + +#else // no HASH_ARRAY_3 +#define HASH_CALC { \ + UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hashValue = (temp ^ (UInt32(cur[2]) << 8)) & _hashMask; } +#endif // HASH_ARRAY_3 +#else // no HASH_ARRAY_2 +#ifdef HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1); +} +#else // no HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return pointer[0] ^ (UInt32(pointer[1]) << 8); +} +#endif // HASH_ZIP +#endif // HASH_ARRAY_2 + +STDMETHODIMP CMatchFinder::GetMatches(UInt32 *distances) +{ + UInt32 lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if(lenLimit < kMinMatchCheck) + { + distances[0] = 0; + return MovePos(); + } + } + + int offset = 1; + + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + const Byte *cur = _buffer + _pos; + + UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + #endif + UInt32 hashValue; + HASH_CALC; + #else + UInt32 hashValue = Hash(cur); + #endif + + UInt32 curMatch = _hash[kFixHashSize + hashValue]; + #ifdef HASH_ARRAY_2 + UInt32 curMatch2 = _hash[hash2Value]; + #ifdef HASH_ARRAY_3 + UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; + #endif + _hash[hash2Value] = _pos; + if(curMatch2 > matchMinPos) + if (_buffer[curMatch2] == cur[0]) + { + distances[offset++] = maxLen = 2; + distances[offset++] = _pos - curMatch2 - 1; + } + + #ifdef HASH_ARRAY_3 + _hash[kHash3Offset + hash3Value] = _pos; + if(curMatch3 > matchMinPos) + if (_buffer[curMatch3] == cur[0]) + { + if (curMatch3 == curMatch2) + offset -= 2; + distances[offset++] = maxLen = 3; + distances[offset++] = _pos - curMatch3 - 1; + curMatch2 = curMatch3; + } + #endif + if (offset != 1 && curMatch2 == curMatch) + { + offset -= 2; + maxLen = kStartMaxLen; + } + #endif + + _hash[kFixHashSize + hashValue] = _pos; + + CIndex *son = _son; + + #ifdef _HASH_CHAIN + son[_cyclicBufferPos] = curMatch; + #else + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); + + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + #endif + + #if kNumHashDirectBytes != 0 + if(curMatch > matchMinPos) + { + if (_buffer[curMatch + kNumHashDirectBytes] != cur[kNumHashDirectBytes]) + { + distances[offset++] = maxLen = kNumHashDirectBytes; + distances[offset++] = _pos - curMatch - 1; + } + } + #endif + UInt32 count = _cutValue; + while(true) + { + if(curMatch <= matchMinPos || count-- == 0) + { + #ifndef _HASH_CHAIN + *ptr0 = *ptr1 = kEmptyHashValue; + #endif + break; + } + UInt32 delta = _pos - curMatch; + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + + #ifdef _HASH_CHAIN + cyclicPos; + #else + (cyclicPos << 1); + #endif + + // _mm_prefetch((const char *)pair, _MM_HINT_T0); + + const Byte *pb = _buffer + curMatch; + UInt32 len = + #ifdef _HASH_CHAIN + kNumHashDirectBytes; + if (pb[maxLen] == cur[maxLen]) + #else + MyMin(len0, len1); + #endif + if (pb[len] == cur[len]) + { + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + distances[offset++] = maxLen = len; + distances[offset++] = delta - 1; + if (len == lenLimit) + { + #ifndef _HASH_CHAIN + *ptr1 = pair[0]; + *ptr0 = pair[1]; + #endif + break; + } + } + } + #ifdef _HASH_CHAIN + curMatch = *pair; + #else + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + #endif + } + distances[0] = offset - 1; + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; +} + +STDMETHODIMP CMatchFinder::Skip(UInt32 num) +{ + do + { + #ifdef _HASH_CHAIN + if (_streamPos - _pos < kNumHashBytes) + { + RINOK(MovePos()); + continue; + } + #else + UInt32 lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if(lenLimit < kMinMatchCheck) + { + RINOK(MovePos()); + continue; + } + } + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + #endif + const Byte *cur = _buffer + _pos; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + UInt32 hashValue; + HASH_CALC; + _hash[kHash3Offset + hash3Value] = _pos; + #else + UInt32 hashValue; + HASH_CALC; + #endif + _hash[hash2Value] = _pos; + #else + UInt32 hashValue = Hash(cur); + #endif + + UInt32 curMatch = _hash[kFixHashSize + hashValue]; + _hash[kFixHashSize + hashValue] = _pos; + + #ifdef _HASH_CHAIN + _son[_cyclicBufferPos] = curMatch; + #else + CIndex *son = _son; + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); + + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + UInt32 count = _cutValue; + while(true) + { + if(curMatch <= matchMinPos || count-- == 0) + { + *ptr0 = *ptr1 = kEmptyHashValue; + break; + } + + UInt32 delta = _pos - curMatch; + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + (cyclicPos << 1); + + // _mm_prefetch((const char *)pair, _MM_HINT_T0); + + const Byte *pb = _buffer + curMatch; + UInt32 len = MyMin(len0, len1); + + if (pb[len] == cur[len]) + { + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + break; + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + #endif + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + } + while(--num != 0); + return S_OK; +} + +void CMatchFinder::Normalize() +{ + UInt32 subValue = _pos - _cyclicBufferSize; + CIndex *items = _hash; + UInt32 numItems = (_hashSizeSum + _cyclicBufferSize + #ifndef _HASH_CHAIN + * 2 + #endif + ); + for (UInt32 i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } + ReduceOffsets(subValue); +} + +HRESULT CMatchFinder::MovePos() +{ + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; +} + +STDMETHODIMP_(Byte) CMatchFinder::GetIndexByte(Int32 index) + { return CLZInWindow::GetIndexByte(index); } + +STDMETHODIMP_(UInt32) CMatchFinder::GetMatchLen(Int32 index, + UInt32 back, UInt32 limit) + { return CLZInWindow::GetMatchLen(index, back, limit); } + +STDMETHODIMP_(UInt32) CMatchFinder::GetNumAvailableBytes() + { return CLZInWindow::GetNumAvailableBytes(); } + +STDMETHODIMP_(const Byte *) CMatchFinder::GetPointerToCurrentPos() + { return CLZInWindow::GetPointerToCurrentPos(); } + +STDMETHODIMP_(Int32) CMatchFinder::NeedChangeBufferPos(UInt32 numCheckBytes) + { return CLZInWindow::NeedMove(numCheckBytes) ? 1: 0; } + +STDMETHODIMP_(void) CMatchFinder::ChangeBufferPos() + { CLZInWindow::MoveBlock();} + +#undef HASH_CALC +#undef kNumHashDirectBytes + +} diff --git a/utils/lzma/C/7zip/Compress/LZ/HashChain/HC2.h b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC2.h new file mode 100644 index 00000000..d8e61a74 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC2.h @@ -0,0 +1,13 @@ +// HC2.h + +#ifndef __HC2_H +#define __HC2_H + +#define BT_NAMESPACE NHC2 + +#include "HCMain.h" + +#undef BT_NAMESPACE + +#endif + diff --git a/utils/lzma/C/7zip/Compress/LZ/HashChain/HC3.h b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC3.h new file mode 100644 index 00000000..263690af --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC3.h @@ -0,0 +1,16 @@ +// HC3.h + +#ifndef __HC3_H +#define __HC3_H + +#define BT_NAMESPACE NHC3 + +#define HASH_ARRAY_2 + +#include "HCMain.h" + +#undef HASH_ARRAY_2 +#undef BT_NAMESPACE + +#endif + diff --git a/utils/lzma/C/7zip/Compress/LZ/HashChain/HC4.h b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC4.h new file mode 100644 index 00000000..1fda4ac6 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/HashChain/HC4.h @@ -0,0 +1,19 @@ +// HC4.h + +#ifndef __HC4_H +#define __HC4_H + +#define BT_NAMESPACE NHC4 + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 + +#include "HCMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 + +#undef BT_NAMESPACE + +#endif + diff --git a/utils/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h b/utils/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h new file mode 100644 index 00000000..d509befe --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h @@ -0,0 +1,6 @@ +// HCMain.h + +#define _HASH_CHAIN +#include "../BinTree/BinTreeMain.h" +#undef _HASH_CHAIN + diff --git a/utils/lzma/C/7zip/Compress/LZ/IMatchFinder.h b/utils/lzma/C/7zip/Compress/LZ/IMatchFinder.h new file mode 100644 index 00000000..528b7b1c --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/IMatchFinder.h @@ -0,0 +1,32 @@ +// MatchFinders/IMatchFinder.h + +#ifndef __IMATCHFINDER_H +#define __IMATCHFINDER_H + +struct IInWindowStream: public IUnknown +{ + STDMETHOD(SetStream)(ISequentialInStream *inStream) PURE; + STDMETHOD_(void, ReleaseStream)() PURE; + STDMETHOD(Init)() PURE; + STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE; + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE; + STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE; + STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE; + STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes) PURE; + STDMETHOD_(void, ChangeBufferPos)() PURE; +}; + +struct IMatchFinder: public IInWindowStream +{ + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE; + STDMETHOD(GetMatches)(UInt32 *distances) PURE; + STDMETHOD(Skip)(UInt32 num) PURE; +}; + +struct IMatchFinderSetNumPasses +{ + virtual void SetNumPasses(UInt32 numPasses) PURE; +}; + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/LZInWindow.cpp b/utils/lzma/C/7zip/Compress/LZ/LZInWindow.cpp new file mode 100644 index 00000000..0e65c425 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/LZInWindow.cpp @@ -0,0 +1,105 @@ +// LZInWindow.cpp + +#include "StdAfx.h" + +#include "LZInWindow.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" + +void CLZInWindow::Free() +{ + ::BigFree(_bufferBase); + _bufferBase = 0; +} + +bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) +{ + _keepSizeBefore = keepSizeBefore; + _keepSizeAfter = keepSizeAfter; + UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; + if (_bufferBase == 0 || _blockSize != blockSize) + { + Free(); + _blockSize = blockSize; + if (_blockSize != 0) + _bufferBase = (Byte *)::BigAlloc(_blockSize); + } + _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; + if (_blockSize == 0) + return true; + return (_bufferBase != 0); +} + +void CLZInWindow::SetStream(ISequentialInStream *stream) +{ + _stream = stream; +} + +HRESULT CLZInWindow::Init() +{ + _buffer = _bufferBase; + _pos = 0; + _streamPos = 0; + _streamEndWasReached = false; + return ReadBlock(); +} + +/* +void CLZInWindow::ReleaseStream() +{ + _stream.Release(); +} +*/ + +/////////////////////////////////////////// +// ReadBlock + +// In State: +// (_buffer + _streamPos) <= (_bufferBase + _blockSize) +// Out State: +// _posLimit <= _blockSize - _keepSizeAfter; +// if(_streamEndWasReached == false): +// _streamPos >= _pos + _keepSizeAfter +// _posLimit = _streamPos - _keepSizeAfter; +// else +// + +HRESULT CLZInWindow::ReadBlock() +{ + if(_streamEndWasReached) + return S_OK; + while(true) + { + UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos; + if(size == 0) + return S_OK; + UInt32 numReadBytes; + RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes)); + if(numReadBytes == 0) + { + _posLimit = _streamPos; + const Byte *pointerToPostion = _buffer + _posLimit; + if(pointerToPostion > _pointerToLastSafePosition) + _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer); + _streamEndWasReached = true; + return S_OK; + } + _streamPos += numReadBytes; + if(_streamPos >= _pos + _keepSizeAfter) + { + _posLimit = _streamPos - _keepSizeAfter; + return S_OK; + } + } +} + +void CLZInWindow::MoveBlock() +{ + UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore; + // we need one additional byte, since MovePos moves on 1 byte. + if (offset > 0) + offset--; + UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos - offset; + memmove(_bufferBase, _bufferBase + offset, numBytes); + _buffer -= offset; +} diff --git a/utils/lzma/C/7zip/Compress/LZ/LZInWindow.h b/utils/lzma/C/7zip/Compress/LZ/LZInWindow.h new file mode 100644 index 00000000..54f2cb7b --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/LZInWindow.h @@ -0,0 +1,87 @@ +// LZInWindow.h + +#ifndef __LZ_IN_WINDOW_H +#define __LZ_IN_WINDOW_H + +#include "../../IStream.h" + +class CLZInWindow +{ + Byte *_bufferBase; // pointer to buffer with data + ISequentialInStream *_stream; + UInt32 _posLimit; // offset (from _buffer) when new block reading must be done + bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream + const Byte *_pointerToLastSafePosition; +protected: + Byte *_buffer; // Pointer to virtual Buffer begin + UInt32 _blockSize; // Size of Allocated memory block + UInt32 _pos; // offset (from _buffer) of curent byte + UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos + UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos + UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream + + void MoveBlock(); + HRESULT ReadBlock(); + void Free(); +public: + CLZInWindow(): _bufferBase(0) {} + virtual ~CLZInWindow() { Free(); } + + // keepSizeBefore + keepSizeAfter + keepSizeReserv < 4G) + bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv = (1<<17)); + + void SetStream(ISequentialInStream *stream); + HRESULT Init(); + // void ReleaseStream(); + + Byte *GetBuffer() const { return _buffer; } + + const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; } + + HRESULT MovePos() + { + _pos++; + if (_pos > _posLimit) + { + const Byte *pointerToPostion = _buffer + _pos; + if(pointerToPostion > _pointerToLastSafePosition) + MoveBlock(); + return ReadBlock(); + } + else + return S_OK; + } + Byte GetIndexByte(Int32 index) const { return _buffer[(size_t)_pos + index]; } + + // index + limit have not to exceed _keepSizeAfter; + // -2G <= index < 2G + UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const + { + if(_streamEndWasReached) + if ((_pos + index) + limit > _streamPos) + limit = _streamPos - (_pos + index); + distance++; + const Byte *pby = _buffer + (size_t)_pos + index; + UInt32 i; + for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); + return i; + } + + UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; } + + void ReduceOffsets(Int32 subValue) + { + _buffer += subValue; + _posLimit -= subValue; + _pos -= subValue; + _streamPos -= subValue; + } + + bool NeedMove(UInt32 numCheckBytes) + { + UInt32 reserv = _pointerToLastSafePosition - (_buffer + _pos); + return (reserv <= numCheckBytes); + } +}; + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp b/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp new file mode 100644 index 00000000..e2d6aba1 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp @@ -0,0 +1,17 @@ +// LZOutWindow.cpp + +#include "StdAfx.h" + +#include "../../../Common/Alloc.h" +#include "LZOutWindow.h" + +void CLZOutWindow::Init(bool solid) +{ + if(!solid) + COutBuffer::Init(); + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + + diff --git a/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.h b/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.h new file mode 100644 index 00000000..3c50c6e7 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/LZOutWindow.h @@ -0,0 +1,56 @@ +// LZOutWindow.h + +#ifndef __LZ_OUT_WINDOW_H +#define __LZ_OUT_WINDOW_H + +#include "../../IStream.h" +#include "../../Common/OutBuffer.h" + +#ifndef _NO_EXCEPTIONS +typedef COutBufferException CLZOutWindowException; +#endif + +class CLZOutWindow: public COutBuffer +{ +public: + void Init(bool solid = false); + + // distance >= 0, len > 0, + bool CopyBlock(UInt32 distance, UInt32 len) + { + UInt32 pos = _pos - distance - 1; + if (distance >= _pos) + { + if (!_overDict || distance >= _bufferSize) + return false; + pos += _bufferSize; + } + do + { + if (pos == _bufferSize) + pos = 0; + _buffer[_pos++] = _buffer[pos++]; + if (_pos == _limitPos) + FlushWithCheck(); + } + while(--len != 0); + return true; + } + + void PutByte(Byte b) + { + _buffer[_pos++] = b; + if (_pos == _limitPos) + FlushWithCheck(); + } + + Byte GetByte(UInt32 distance) const + { + UInt32 pos = _pos - distance - 1; + if (pos >= _bufferSize) + pos += _bufferSize; + return _buffer[pos]; + } +}; + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZ/StdAfx.h b/utils/lzma/C/7zip/Compress/LZ/StdAfx.h new file mode 100644 index 00000000..3ff6d8a2 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZ/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA/LZMA.h b/utils/lzma/C/7zip/Compress/LZMA/LZMA.h new file mode 100644 index 00000000..7bc4c438 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/LZMA.h @@ -0,0 +1,82 @@ +// LZMA.h + +#ifndef __LZMA_H +#define __LZMA_H + +namespace NCompress { +namespace NLZMA { + +const UInt32 kNumRepDistances = 4; + +const int kNumStates = 12; + +const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +class CState +{ +public: + Byte Index; + void Init() { Index = 0; } + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } + bool IsCharState() const { return Index < 7; } +}; + +const int kNumPosSlotBits = 6; +const int kDicLogSizeMin = 0; +const int kDicLogSizeMax = 32; +const int kDistTableSizeMax = kDicLogSizeMax * 2; + +const UInt32 kNumLenToPosStates = 4; + +inline UInt32 GetLenToPosState(UInt32 len) +{ + len -= 2; + if (len < kNumLenToPosStates) + return len; + return kNumLenToPosStates - 1; +} + +namespace NLength { + +const int kNumPosStatesBitsMax = 4; +const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax); + +const int kNumPosStatesBitsEncodingMax = 4; +const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); + +const int kNumLowBits = 3; +const int kNumMidBits = 3; +const int kNumHighBits = 8; +const UInt32 kNumLowSymbols = 1 << kNumLowBits; +const UInt32 kNumMidSymbols = 1 << kNumMidBits; +const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits); + +} + +const UInt32 kMatchMinLen = 2; +const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1; + +const int kNumAlignBits = 4; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; +const UInt32 kAlignMask = (kAlignTableSize - 1); + +const UInt32 kStartPosModelIndex = 4; +const UInt32 kEndPosModelIndex = 14; +const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; + +const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2); + +const int kNumLitPosStatesBitsEncodingMax = 4; +const int kNumLitContextBitsMax = 8; + +const int kNumMoveBits = 5; + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp b/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp new file mode 100644 index 00000000..af984c4a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp @@ -0,0 +1,337 @@ +// LZMADecoder.cpp + +#include "StdAfx.h" + +#include "LZMADecoder.h" +#include "../../../Common/Defs.h" + +namespace NCompress { +namespace NLZMA { + +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +void CDecoder::Init() +{ + { + for(int i = 0; i < kNumStates; i++) + { + for (UInt32 j = 0; j <= _posStateMask; j++) + { + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); + } + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); + } + } + { + for (UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotDecoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posDecoders[i].Init(); + } + _posAlignDecoder.Init(); + _lenDecoder.Init(_posStateMask + 1); + _repMatchLenDecoder.Init(_posStateMask + 1); + _literalDecoder.Init(); + + _state.Init(); + _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0; +} + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize(); + if (curSize > rem) + curSize = (UInt32)rem; + } + + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + _rangeDecoder.Init(); + Init(); + _remainLen = 0; + } + if (curSize == 0) + return S_OK; + + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + CState state = _state; + Byte previousByte; + + while(_remainLen > 0 && curSize > 0) + { + previousByte = _outWindowStream.GetByte(rep0); + _outWindowStream.PutByte(previousByte); + _remainLen--; + curSize--; + } + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); + if (nowPos64 == 0) + previousByte = 0; + else + previousByte = _outWindowStream.GetByte(0); + + while(curSize > 0) + { + { + #ifdef _NO_EXCEPTIONS + if (_rangeDecoder.Stream.ErrorCode != S_OK) + return _rangeDecoder.Stream.ErrorCode; + #endif + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + UInt32 posState = UInt32(nowPos64) & _posStateMask; + if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0) + { + if(!state.IsCharState()) + previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder, + (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0)); + else + previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder, + (UInt32)nowPos64, previousByte); + _outWindowStream.PutByte(previousByte); + state.UpdateChar(); + curSize--; + nowPos64++; + } + else + { + UInt32 len; + if(_isRep[state.Index].Decode(&_rangeDecoder) == 1) + { + len = 0; + if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0) + { + if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0) + { + state.UpdateShortRep(); + len = 1; + } + } + else + { + UInt32 distance; + if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep1; + else + { + if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + if (len == 0) + { + len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen; + state.UpdateRep(); + } + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState); + state.UpdateMatch(); + UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder); + if (posSlot >= kStartPosModelIndex) + { + UInt32 numDirectBits = (posSlot >> 1) - 1; + rep0 = ((2 | (posSlot & 1)) << numDirectBits); + + if (posSlot < kEndPosModelIndex) + rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders + + rep0 - posSlot - 1, &_rangeDecoder, numDirectBits); + else + { + rep0 += (_rangeDecoder.DecodeDirectBits( + numDirectBits - kNumAlignBits) << kNumAlignBits); + rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder); + if (rep0 == 0xFFFFFFFF) + { + _remainLen = kLenIdFinished; + return S_OK; + } + } + } + else + rep0 = posSlot; + } + UInt32 locLen = len; + if (len > curSize) + locLen = (UInt32)curSize; + if (!_outWindowStream.CopyBlock(rep0, locLen)) + return S_FALSE; + previousByte = _outWindowStream.GetByte(0); + curSize -= locLen; + nowPos64 += locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + break; + } + + #ifdef _NO_EXCEPTIONS + if (_outWindowStream.ErrorCode != S_OK) + return _outWindowStream.ErrorCode; + #endif + } + } + } + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _state = state; + + return S_OK; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + SetInStream(inStream); + _outWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + while (true) + { + UInt32 curSize = 1 << 18; + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + if (_outSizeDefined) + if (_outWindowStream.GetProcessedSize() >= _outSize) + break; + } + flusher.NeedFlush = false; + return Flush(); +} + + +#ifdef _NO_EXCEPTIONS + +#define LZMA_TRY_BEGIN +#define LZMA_TRY_END + +#else + +#define LZMA_TRY_BEGIN try { +#define LZMA_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + LZMA_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + LZMA_TRY_END +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) +{ + if (size < 5) + return E_INVALIDARG; + int lc = properties[0] % 9; + Byte remainder = (Byte)(properties[0] / 9); + int lp = remainder % 5; + int pb = remainder / 5; + if (pb > NLength::kNumPosStatesBitsMax) + return E_INVALIDARG; + _posStateMask = (1 << pb) - 1; + UInt32 dictionarySize = 0; + for (int i = 0; i < 4; i++) + dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); + if (!_outWindowStream.Create(dictionarySize)) + return E_OUTOFMEMORY; + if (!_literalDecoder.Create(lp, lc)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + *value = _rangeDecoder.GetProcessedSize(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if ((_outSizeDefined = (outSize != NULL))) + _outSize = *outSize; + _remainLen = kLenIdNeedInit; + _outWindowStream.Init(); + return S_OK; +} + +#ifdef _ST_MODE + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + LZMA_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = _outWindowStream.GetProcessedSize(); + _outWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos); + return Flush(); + LZMA_TRY_END +} + +#endif + +}} diff --git a/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.h b/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.h new file mode 100644 index 00000000..1c10409f --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/LZMADecoder.h @@ -0,0 +1,251 @@ +// LZMA/Decoder.h + +#ifndef __LZMA_DECODER_H +#define __LZMA_DECODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitDecoder CMyBitDecoder; + +class CLiteralDecoder2 +{ + CMyBitDecoder _decoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _decoders[i].Init(); + } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + UInt32 matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder); + // symbol = (symbol << 1) | bit; + UInt32 bit; + RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, + bit = 0, bit = 1) + if (matchBit != bit) + { + while (symbol < 0x100) + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + break; + } + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } +}; + +class CLiteralDecoder +{ + CLiteralDecoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralDecoder(): _coders(0) {} + ~CLiteralDecoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != + (_numPrevBits + _numPosBits) ) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + UInt32 GetState(UInt32 pos, Byte prevByte) const + { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte) + { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte) + { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } +}; + +namespace NLength { + +class CDecoder +{ + CMyBitDecoder _choice; + CMyBitDecoder _choice2; + NRangeCoder::CBitTreeDecoder _lowCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _midCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _highCoder; +public: + void Init(UInt32 numPosStates) + { + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); + } + UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState) + { + if(_choice.Decode(rangeDecoder) == 0) + return _lowCoder[posState].Decode(rangeDecoder); + if(_choice2.Decode(rangeDecoder) == 0) + return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder); + return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder); + } +}; + +} + +class CDecoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressGetInStreamProcessedSize, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CLZOutWindow _outWindowStream; + NRangeCoder::CDecoder _rangeDecoder; + + CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax]; + CMyBitDecoder _isRep[kNumStates]; + CMyBitDecoder _isRepG0[kNumStates]; + CMyBitDecoder _isRepG1[kNumStates]; + CMyBitDecoder _isRepG2[kNumStates]; + CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax]; + + NRangeCoder::CBitTreeDecoder _posSlotDecoder[kNumLenToPosStates]; + + CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeDecoder _posAlignDecoder; + + NLength::CDecoder _lenDecoder; + NLength::CDecoder _repMatchLenDecoder; + + CLiteralDecoder _literalDecoder; + + UInt32 _posStateMask; + + /////////////////// + // State + UInt32 _reps[4]; + CState _state; + Int32 _remainLen; // -1 means end of stream. // -2 means need Init + UInt64 _outSize; + bool _outSizeDefined; + + void Init(); + HRESULT CodeSpec(UInt32 size); +public: + + #ifdef _ST_MODE + MY_UNKNOWN_IMP5( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP2( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize) + #endif + + void ReleaseStreams() + { + _outWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + + HRESULT Flush() { return _outWindowStream.Flush(); } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} + virtual ~CDecoder() {} +}; + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp b/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp new file mode 100644 index 00000000..30aa4524 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp @@ -0,0 +1,1564 @@ +// LZMA/Encoder.cpp + +#include "StdAfx.h" + +#include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" + +#include "LZMAEncoder.h" + +// for minimal compressing code size define these: +// #define COMPRESS_MF_BT +// #define COMPRESS_MF_BT4 + +#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_HC) +#define COMPRESS_MF_BT +#define COMPRESS_MF_HC +#endif + +#ifdef COMPRESS_MF_BT +#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4) +#define COMPRESS_MF_BT2 +#define COMPRESS_MF_BT3 +#define COMPRESS_MF_BT4 +#endif +#ifdef COMPRESS_MF_BT2 +#include "../LZ/BinTree/BinTree2.h" +#endif +#ifdef COMPRESS_MF_BT3 +#include "../LZ/BinTree/BinTree3.h" +#endif +#ifdef COMPRESS_MF_BT4 +#include "../LZ/BinTree/BinTree4.h" +#endif +#endif + +#ifdef COMPRESS_MF_HC +#include "../LZ/HashChain/HC4.h" +#endif + +#ifdef COMPRESS_MF_MT +#include "../LZ/MT/MT.h" +#endif + +namespace NCompress { +namespace NLZMA { + +const int kDefaultDictionaryLogSize = 22; +const UInt32 kNumFastBytesDefault = 0x20; + +enum +{ + kBT2, + kBT3, + kBT4, + kHC4 +}; + +static const wchar_t *kMatchFinderIDs[] = +{ + L"BT2", + L"BT3", + L"BT4", + L"HC4" +}; + +Byte g_FastPos[1 << 11]; + +class CFastPosInit +{ +public: + CFastPosInit() { Init(); } + void Init() + { + const Byte kFastSlots = 22; + int c = 2; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + for (UInt32 j = 0; j < k; j++, c++) + g_FastPos[c] = slotFast; + } + } +} g_FastPosInit; + + +void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + while(i != 0); +} + +void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, + Byte matchByte, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + UInt32 matchBit = (matchByte >> i) & 1; + _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + if (matchBit != bit) + { + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + break; + } + } + while(i != 0); +} + +UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const +{ + UInt32 price = 0; + UInt32 context = 1; + int i = 8; + if (matchMode) + { + do + { + i--; + UInt32 matchBit = (matchByte >> i) & 1; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit); + context = (context << 1) | bit; + if (matchBit != bit) + break; + } + while (i != 0); + } + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[context].GetPrice(bit); + context = (context << 1) | bit; + } + return price; +}; + + +namespace NLength { + +void CEncoder::Init(UInt32 numPosStates) +{ + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); +} + +void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState) +{ + if(symbol < kNumLowSymbols) + { + _choice.Encode(rangeEncoder, 0); + _lowCoder[posState].Encode(rangeEncoder, symbol); + } + else + { + _choice.Encode(rangeEncoder, 1); + if(symbol < kNumLowSymbols + kNumMidSymbols) + { + _choice2.Encode(rangeEncoder, 0); + _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols); + } + else + { + _choice2.Encode(rangeEncoder, 1); + _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols); + } + } +} + +void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const +{ + UInt32 a0 = _choice.GetPrice0(); + UInt32 a1 = _choice.GetPrice1(); + UInt32 b0 = a1 + _choice2.GetPrice0(); + UInt32 b1 = a1 + _choice2.GetPrice1(); + UInt32 i = 0; + for (i = 0; i < kNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + _lowCoder[posState].GetPrice(i); + } + for (; i < kNumLowSymbols + kNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols); + } + for (; i < numSymbols; i++) + prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols); +} + +} +CEncoder::CEncoder(): + _numFastBytes(kNumFastBytesDefault), + _distTableSize(kDefaultDictionaryLogSize * 2), + _posStateBits(2), + _posStateMask(4 - 1), + _numLiteralPosStateBits(0), + _numLiteralContextBits(3), + _dictionarySize(1 << kDefaultDictionaryLogSize), + _dictionarySizePrev(UInt32(-1)), + _numFastBytesPrev(UInt32(-1)), + _matchFinderCycles(0), + _matchFinderIndex(kBT4), + #ifdef COMPRESS_MF_MT + _multiThread(false), + #endif + _writeEndMark(false), + setMfPasses(0) +{ + // _maxMode = false; + _fastMode = false; +} + +HRESULT CEncoder::Create() +{ + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_matchFinder) + { + switch(_matchFinderIndex) + { + #ifdef COMPRESS_MF_BT + #ifdef COMPRESS_MF_BT2 + case kBT2: + { + NBT2::CMatchFinder *mfSpec = new NBT2::CMatchFinder; + setMfPasses = mfSpec; + _matchFinder = mfSpec; + break; + } + #endif + #ifdef COMPRESS_MF_BT3 + case kBT3: + { + NBT3::CMatchFinder *mfSpec = new NBT3::CMatchFinder; + setMfPasses = mfSpec; + _matchFinder = mfSpec; + break; + } + #endif + #ifdef COMPRESS_MF_BT4 + case kBT4: + { + NBT4::CMatchFinder *mfSpec = new NBT4::CMatchFinder; + setMfPasses = mfSpec; + _matchFinder = mfSpec; + break; + } + #endif + #endif + + #ifdef COMPRESS_MF_HC + case kHC4: + { + NHC4::CMatchFinder *mfSpec = new NHC4::CMatchFinder; + setMfPasses = mfSpec; + _matchFinder = mfSpec; + break; + } + #endif + } + if (_matchFinder == 0) + return E_OUTOFMEMORY; + + #ifdef COMPRESS_MF_MT + if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC4))) + { + CMatchFinderMT *mfSpec = new CMatchFinderMT; + if (mfSpec == 0) + return E_OUTOFMEMORY; + CMyComPtr mf = mfSpec; + RINOK(mfSpec->SetMatchFinder(_matchFinder)); + _matchFinder.Release(); + _matchFinder = mf; + } + #endif + } + + if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits)) + return E_OUTOFMEMORY; + + if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) + return S_OK; + RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen + 1)); // actually it's + _numFastBytes - _numFastBytes + if (_matchFinderCycles != 0 && setMfPasses != 0) + setMfPasses->SetNumPasses(_matchFinderCycles); + _dictionarySizePrev = _dictionarySize; + _numFastBytesPrev = _numFastBytes; + return S_OK; +} + +static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString) +{ + while (true) + { + wchar_t c = *testString; + if (c >= 'a' && c <= 'z') + c -= 0x20; + if (*base != c) + return false; + if (c == 0) + return true; + base++; + testString++; + } +} + +static int FindMatchFinder(const wchar_t *s) +{ + for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++) + if (AreStringsEqual(kMatchFinderIDs[m], s)) + return m; + return -1; +} + +STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for (UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &prop = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kNumFastBytes: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 numFastBytes = prop.ulVal; + if(numFastBytes < 5 || numFastBytes > kMatchMaxLen) + return E_INVALIDARG; + _numFastBytes = numFastBytes; + break; + } + case NCoderPropID::kMatchFinderCycles: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + _matchFinderCycles = prop.ulVal; + break; + } + case NCoderPropID::kAlgorithm: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 maximize = prop.ulVal; + _fastMode = (maximize == 0); + // _maxMode = (maximize >= 2); + break; + } + case NCoderPropID::kMatchFinder: + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + int matchFinderIndexPrev = _matchFinderIndex; + int m = FindMatchFinder(prop.bstrVal); + if (m < 0) + return E_INVALIDARG; + _matchFinderIndex = m; + if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex) + { + _dictionarySizePrev = (UInt32)-1; + ReleaseMatchFinder(); + } + break; + } + #ifdef COMPRESS_MF_MT + case NCoderPropID::kMultiThread: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + bool newMultiThread = (prop.boolVal == VARIANT_TRUE); + if (newMultiThread != _multiThread) + { + _dictionarySizePrev = (UInt32)-1; + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + break; + } + case NCoderPropID::kNumThreads: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + bool newMultiThread = (prop.ulVal > 1); + if (newMultiThread != _multiThread) + { + _dictionarySizePrev = (UInt32)-1; + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + break; + } + #endif + case NCoderPropID::kDictionarySize: + { + const int kDicLogSizeMaxCompress = 30; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 dictionarySize = prop.ulVal; + if (dictionarySize < UInt32(1 << kDicLogSizeMin) || + dictionarySize > UInt32(1 << kDicLogSizeMaxCompress)) + return E_INVALIDARG; + _dictionarySize = dictionarySize; + UInt32 dicLogSize; + for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) + if (dictionarySize <= (UInt32(1) << dicLogSize)) + break; + _distTableSize = dicLogSize * 2; + break; + } + case NCoderPropID::kPosStateBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax) + return E_INVALIDARG; + _posStateBits = value; + _posStateMask = (1 << _posStateBits) - 1; + break; + } + case NCoderPropID::kLitPosBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitPosStatesBitsEncodingMax) + return E_INVALIDARG; + _numLiteralPosStateBits = value; + break; + } + case NCoderPropID::kLitContextBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitContextBitsMax) + return E_INVALIDARG; + _numLiteralContextBits = value; + break; + } + case NCoderPropID::kEndMarker: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE); + break; + } + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + const UInt32 kPropSize = 5; + Byte properties[kPropSize]; + properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits; + for (int i = 0; i < 4; i++) + properties[1 + i] = Byte(_dictionarySize >> (8 * i)); + return WriteStream(outStream, properties, kPropSize, NULL); +} + +STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream) +{ + _rangeEncoder.SetStream(outStream); + return S_OK; +} + +STDMETHODIMP CEncoder::ReleaseOutStream() +{ + _rangeEncoder.ReleaseStream(); + return S_OK; +} + +HRESULT CEncoder::Init() +{ + CBaseState::Init(); + + // RINOK(_matchFinder->Init(inStream)); + _rangeEncoder.Init(); + + for(int i = 0; i < kNumStates; i++) + { + for (UInt32 j = 0; j <= _posStateMask; j++) + { + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); + } + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); + } + + _literalEncoder.Init(); + + { + for(UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotEncoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posEncoders[i].Init(); + } + + _lenEncoder.Init(1 << _posStateBits); + _repMatchLenEncoder.Init(1 << _posStateBits); + + _posAlignEncoder.Init(); + + _longestMatchWasFound = false; + _optimumEndIndex = 0; + _optimumCurrentIndex = 0; + _additionalOffset = 0; + + return S_OK; +} + +HRESULT CEncoder::MovePos(UInt32 num) +{ + if (num == 0) + return S_OK; + _additionalOffset += num; + return _matchFinder->Skip(num); +} + +UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur) +{ + _optimumEndIndex = cur; + UInt32 posMem = _optimum[cur].PosPrev; + UInt32 backMem = _optimum[cur].BackPrev; + do + { + if (_optimum[cur].Prev1IsChar) + { + _optimum[posMem].MakeAsChar(); + _optimum[posMem].PosPrev = posMem - 1; + if (_optimum[cur].Prev2) + { + _optimum[posMem - 1].Prev1IsChar = false; + _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; + _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; + } + } + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = _optimum[posPrev].BackPrev; + posMem = _optimum[posPrev].PosPrev; + + _optimum[posPrev].BackPrev = backCur; + _optimum[posPrev].PosPrev = cur; + cur = posPrev; + } + while(cur != 0); + backRes = _optimum[0].BackPrev; + _optimumCurrentIndex = _optimum[0].PosPrev; + return _optimumCurrentIndex; +} + +/* +Out: + (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal +*/ + +HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes) +{ + if(_optimumEndIndex != _optimumCurrentIndex) + { + const COptimal &optimum = _optimum[_optimumCurrentIndex]; + lenRes = optimum.PosPrev - _optimumCurrentIndex; + backRes = optimum.BackPrev; + _optimumCurrentIndex = optimum.PosPrev; + return S_OK; + } + _optimumCurrentIndex = _optimumEndIndex = 0; + + UInt32 lenMain, numDistancePairs; + if (!_longestMatchWasFound) + { + RINOK(ReadMatchDistances(lenMain, numDistancePairs)); + } + else + { + lenMain = _longestMatchLength; + numDistancePairs = _numDistancePairs; + _longestMatchWasFound = false; + } + + const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1; + UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1; + if (numAvailableBytes < 2) + { + backRes = (UInt32)(-1); + lenRes = 1; + return S_OK; + } + if (numAvailableBytes > kMatchMaxLen) + numAvailableBytes = kMatchMaxLen; + + UInt32 reps[kNumRepDistances]; + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + UInt32 i; + for(i = 0; i < kNumRepDistances; i++) + { + reps[i] = _repDistances[i]; + UInt32 backOffset = reps[i] + 1; + if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 lenTest; + for (lenTest = 2; lenTest < numAvailableBytes && + data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if(repLens[repMaxIndex] >= _numFastBytes) + { + backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + return MovePos(lenRes - 1); + } + + UInt32 *matchDistances = _matchDistances + 1; + if(lenMain >= _numFastBytes) + { + backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 1); + } + Byte currentByte = *data; + Byte matchByte = data[(size_t)0 - reps[0] - 1]; + + if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + backRes = (UInt32)-1; + lenRes = 1; + return S_OK; + } + + _optimum[0].State = _state; + + UInt32 posState = (position & _posStateMask); + + _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() + + _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte); + _optimum[1].MakeAsChar(); + + UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); + + if(matchByte == currentByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); + if(shortRepPrice < _optimum[1].Price) + { + _optimum[1].Price = shortRepPrice; + _optimum[1].MakeAsShortRep(); + } + } + UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if(lenEnd < 2) + { + backRes = _optimum[1].BackPrev; + lenRes = 1; + return S_OK; + } + + _optimum[1].PosPrev = 0; + for (i = 0; i < kNumRepDistances; i++) + _optimum[0].Backs[i] = reps[i]; + + UInt32 len = lenEnd; + do + _optimum[len--].Price = kIfinityPrice; + while (len >= 2); + + for(i = 0; i < kNumRepDistances; i++) + { + UInt32 repLen = repLens[i]; + if (repLen < 2) + continue; + UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState); + do + { + UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); + COptimal &optimum = _optimum[repLen]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = i; + optimum.Prev1IsChar = false; + } + } + while(--repLen >= 2); + } + + UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0(); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + UInt32 offs = 0; + while (len > matchDistances[offs]) + offs += 2; + for(; ; len++) + { + UInt32 distance = matchDistances[offs + 1]; + UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); + COptimal &optimum = _optimum[len]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = distance + kNumRepDistances; + optimum.Prev1IsChar = false; + } + if (len == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + UInt32 cur = 0; + + while(true) + { + cur++; + if(cur == lenEnd) + { + lenRes = Backward(backRes, cur); + return S_OK; + } + UInt32 newLen, numDistancePairs; + RINOK(ReadMatchDistances(newLen, numDistancePairs)); + if(newLen >= _numFastBytes) + { + _numDistancePairs = numDistancePairs; + _longestMatchLength = newLen; + _longestMatchWasFound = true; + lenRes = Backward(backRes, cur); + return S_OK; + } + position++; + COptimal &curOptimum = _optimum[cur]; + UInt32 posPrev = curOptimum.PosPrev; + CState state; + if (curOptimum.Prev1IsChar) + { + posPrev--; + if (curOptimum.Prev2) + { + state = _optimum[curOptimum.PosPrev2].State; + if (curOptimum.BackPrev2 < kNumRepDistances) + state.UpdateRep(); + else + state.UpdateMatch(); + } + else + state = _optimum[posPrev].State; + state.UpdateChar(); + } + else + state = _optimum[posPrev].State; + if (posPrev == cur - 1) + { + if (curOptimum.IsShortRep()) + state.UpdateShortRep(); + else + state.UpdateChar(); + } + else + { + UInt32 pos; + if (curOptimum.Prev1IsChar && curOptimum.Prev2) + { + posPrev = curOptimum.PosPrev2; + pos = curOptimum.BackPrev2; + state.UpdateRep(); + } + else + { + pos = curOptimum.BackPrev; + if (pos < kNumRepDistances) + state.UpdateRep(); + else + state.UpdateMatch(); + } + const COptimal &prevOptimum = _optimum[posPrev]; + if (pos < kNumRepDistances) + { + reps[0] = prevOptimum.Backs[pos]; + UInt32 i; + for(i = 1; i <= pos; i++) + reps[i] = prevOptimum.Backs[i - 1]; + for(; i < kNumRepDistances; i++) + reps[i] = prevOptimum.Backs[i]; + } + else + { + reps[0] = (pos - kNumRepDistances); + for(UInt32 i = 1; i < kNumRepDistances; i++) + reps[i] = prevOptimum.Backs[i - 1]; + } + } + curOptimum.State = state; + for(UInt32 i = 0; i < kNumRepDistances; i++) + curOptimum.Backs[i] = reps[i]; + UInt32 curPrice = curOptimum.Price; + const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1; + const Byte currentByte = *data; + const Byte matchByte = data[(size_t)0 - reps[0] - 1]; + + UInt32 posState = (position & _posStateMask); + + UInt32 curAnd1Price = curPrice + + _isMatch[state.Index][posState].GetPrice0() + + _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte); + + COptimal &nextOptimum = _optimum[cur + 1]; + + bool nextIsChar = false; + if (curAnd1Price < nextOptimum.Price) + { + nextOptimum.Price = curAnd1Price; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsChar(); + nextIsChar = true; + } + + UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); + + if(matchByte == currentByte && + !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); + if(shortRepPrice <= nextOptimum.Price) + { + nextOptimum.Price = shortRepPrice; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsShortRep(); + nextIsChar = true; + } + } + /* + if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ? + continue; + */ + + UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1; + numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull); + UInt32 numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > _numFastBytes) + numAvailableBytes = _numFastBytes; + if (!nextIsChar && matchByte != currentByte) // speed optimization + { + // try Literal + rep0 + UInt32 backOffset = reps[0] + 1; + UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1); + UInt32 temp; + for (temp = 1; temp < limit && + data[temp] == data[(size_t)temp - backOffset]; temp++); + UInt32 lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateChar(); + UInt32 posStateNext = (position + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAnd1Price + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + // for (; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = false; + } + } + } + } + + UInt32 startLen = 2; // speed optimization + for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++) + { + // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it; + UInt32 backOffset = reps[repIndex] + 1; + if (data[0] != data[(size_t)0 - backOffset] || + data[1] != data[(size_t)1 - backOffset]) + continue; + UInt32 lenTest; + for (lenTest = 2; lenTest < numAvailableBytes && + data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++); + while(lenEnd < cur + lenTest) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 lenTestTemp = lenTest; + UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState); + COptimal &optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = repIndex; + optimum.Prev1IsChar = false; + } + } + while(--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + // if (_maxMode) + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit && + data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateRep(); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = + price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice( + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (position + lenTest + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAndLenCharPrice + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + + // for(; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = repIndex; + } + } + } + } + } + + // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++) + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); + matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0(); + while(lenEnd < cur + newLen) + _optimum[++lenEnd].Price = kIfinityPrice; + + UInt32 offs = 0; + while(startLen > matchDistances[offs]) + offs += 2; + UInt32 curBack = matchDistances[offs + 1]; + UInt32 posSlot = GetPosSlot2(curBack); + for(UInt32 lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice; + UInt32 lenToPosState = GetLenToPosState(lenTest); + if (curBack < kNumFullDistances) + curAndLenPrice += _distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask]; + + curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState); + + COptimal &optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = curBack + kNumRepDistances; + optimum.Prev1IsChar = false; + } + + if (/*_maxMode && */lenTest == matchDistances[offs]) + { + // Try Match + Literal + Rep0 + UInt32 backOffset = curBack + 1; + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit && + data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateMatch(); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice( + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (posStateNext + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAndLenCharPrice + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + + // for(; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = curBack + kNumRepDistances; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + curBack = matchDistances[offs + 1]; + if (curBack >= kNumFullDistances) + posSlot = GetPosSlot2(curBack); + } + } + } + } +} + +static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist) +{ + return ((bigDist >> 7) > smallDist); +} + + +HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes, UInt32 &numDistancePairs) +{ + lenRes = 0; + RINOK(_matchFinder->GetMatches(_matchDistances)); + numDistancePairs = _matchDistances[0]; + if (numDistancePairs > 0) + { + lenRes = _matchDistances[1 + numDistancePairs - 2]; + if (lenRes == _numFastBytes) + lenRes += _matchFinder->GetMatchLen(lenRes - 1, _matchDistances[1 + numDistancePairs - 1], + kMatchMaxLen - lenRes); + } + _additionalOffset++; + return S_OK; +} + +HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes) +{ + UInt32 lenMain, numDistancePairs; + if (!_longestMatchWasFound) + { + RINOK(ReadMatchDistances(lenMain, numDistancePairs)); + } + else + { + lenMain = _longestMatchLength; + numDistancePairs = _numDistancePairs; + _longestMatchWasFound = false; + } + + const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1; + UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1; + if (numAvailableBytes > kMatchMaxLen) + numAvailableBytes = kMatchMaxLen; + if (numAvailableBytes < 2) + { + backRes = (UInt32)(-1); + lenRes = 1; + return S_OK; + } + + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + UInt32 backOffset = _repDistances[i] + 1; + if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 len; + for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++); + if(len >= _numFastBytes) + { + backRes = i; + lenRes = len; + return MovePos(lenRes - 1); + } + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + UInt32 *matchDistances = _matchDistances + 1; + if(lenMain >= _numFastBytes) + { + backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 1); + } + + UInt32 backMain = 0; // for GCC + if (lenMain >= 2) + { + backMain = matchDistances[numDistancePairs - 1]; + while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) + { + if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) + break; + numDistancePairs -= 2; + lenMain = matchDistances[numDistancePairs - 2]; + backMain = matchDistances[numDistancePairs - 1]; + } + if (lenMain == 2 && backMain >= 0x80) + lenMain = 1; + } + + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + ( repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ) || + ( repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)) ) ) + { + backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + return MovePos(lenRes - 1); + } + } + + if (lenMain >= 2 && numAvailableBytes > 2) + { + RINOK(ReadMatchDistances(_longestMatchLength, _numDistancePairs)); + if (_longestMatchLength >= 2) + { + UInt32 newDistance = matchDistances[_numDistancePairs - 1]; + if (( _longestMatchLength >= lenMain && newDistance < backMain ) || + ( _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ) || + ( _longestMatchLength > lenMain + 1 ) || + ( _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain) ) ) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; + } + } + data++; + numAvailableBytes--; + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + UInt32 backOffset = _repDistances[i] + 1; + if (data[1] != data[(size_t)1 - backOffset] || data[2] != data[(size_t)2 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 len; + for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++); + if (len + 1 >= lenMain) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; + } + } + backRes = backMain + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 2); + } + backRes = UInt32(-1); + lenRes = 1; + return S_OK; +} + +HRESULT CEncoder::Flush(UInt32 nowPos) +{ + ReleaseMFStream(); + WriteEndMarker(nowPos & _posStateMask); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +void CEncoder::WriteEndMarker(UInt32 posState) +{ + // This function for writing End Mark for stream version of LZMA. + // In current version this feature is not used. + if (!_writeEndMark) + return; + + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); + _isRep[_state.Index].Encode(&_rangeEncoder, 0); + _state.UpdateMatch(); + UInt32 len = kMatchMinLen; // kMatchMaxLen; + _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + UInt32 posSlot = (1 << kNumPosSlotBits) - 1; + UInt32 lenToPosState = GetLenToPosState(len); + _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot); + UInt32 footerBits = 30; + UInt32 posReduced = (UInt32(1) << footerBits) - 1; + _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); +} + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + _needReleaseMFStream = false; + CCoderReleaser coderReleaser(this); + RINOK(SetStreams(inStream, outStream, inSize, outSize)); + while(true) + { + UInt64 processedInSize; + UInt64 processedOutSize; + Int32 finished; + RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished)); + if (finished != 0) + return S_OK; + if (progress != 0) + { + RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize)); + } + } +} + +HRESULT CEncoder::SetStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize) +{ + _inStream = inStream; + _finished = false; + RINOK(Create()); + RINOK(SetOutStream(outStream)); + RINOK(Init()); + + // CCoderReleaser releaser(this); + + /* + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(); + */ + + if (!_fastMode) + { + FillDistancesPrices(); + FillAlignPrices(); + } + + _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _lenEncoder.UpdateTables(1 << _posStateBits); + _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _repMatchLenEncoder.UpdateTables(1 << _posStateBits); + + nowPos64 = 0; + return S_OK; +} + +HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished) +{ + if (_inStream != 0) + { + RINOK(_matchFinder->SetStream(_inStream)); + RINOK(_matchFinder->Init()); + _needReleaseMFStream = true; + _inStream = 0; + } + + + *finished = 1; + if (_finished) + return S_OK; + _finished = true; + + if (nowPos64 == 0) + { + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(UInt32(nowPos64)); + UInt32 len, numDistancePairs; + RINOK(ReadMatchDistances(len, numDistancePairs)); + UInt32 posState = UInt32(nowPos64) & _posStateMask; + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + _state.UpdateChar(); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte); + _previousByte = curByte; + _additionalOffset--; + nowPos64++; + } + + UInt32 nowPos32 = (UInt32)nowPos64; + UInt32 progressPosValuePrev = nowPos32; + + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(nowPos32); + + while(true) + { + #ifdef _NO_EXCEPTIONS + if (_rangeEncoder.Stream.ErrorCode != S_OK) + return _rangeEncoder.Stream.ErrorCode; + #endif + UInt32 pos, len; + HRESULT result; + if (_fastMode) + result = GetOptimumFast(nowPos32, pos, len); + else + result = GetOptimum(nowPos32, pos, len); + RINOK(result); + + UInt32 posState = nowPos32 & _posStateMask; + if(len == 1 && pos == 0xFFFFFFFF) + { + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte); + if(_state.IsCharState()) + subCoder->Encode(&_rangeEncoder, curByte); + else + { + Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset); + subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte); + } + _state.UpdateChar(); + _previousByte = curByte; + } + else + { + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); + if(pos < kNumRepDistances) + { + _isRep[_state.Index].Encode(&_rangeEncoder, 1); + if(pos == 0) + { + _isRepG0[_state.Index].Encode(&_rangeEncoder, 0); + _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = _repDistances[pos]; + _isRepG0[_state.Index].Encode(&_rangeEncoder, 1); + if (pos == 1) + _isRepG1[_state.Index].Encode(&_rangeEncoder, 0); + else + { + _isRepG1[_state.Index].Encode(&_rangeEncoder, 1); + _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2); + if (pos == 3) + _repDistances[3] = _repDistances[2]; + _repDistances[2] = _repDistances[1]; + } + _repDistances[1] = _repDistances[0]; + _repDistances[0] = distance; + } + if (len == 1) + _state.UpdateShortRep(); + else + { + _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + _state.UpdateRep(); + } + } + else + { + _isRep[_state.Index].Encode(&_rangeEncoder, 0); + _state.UpdateMatch(); + _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + pos -= kNumRepDistances; + UInt32 posSlot = GetPosSlot(pos); + _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1, + &_rangeEncoder, footerBits, posReduced); + else + { + _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); + _alignPriceCount++; + } + } + _repDistances[3] = _repDistances[2]; + _repDistances[2] = _repDistances[1]; + _repDistances[1] = _repDistances[0]; + _repDistances[0] = pos; + _matchPriceCount++; + } + _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset); + } + _additionalOffset -= len; + nowPos32 += len; + if (_additionalOffset == 0) + { + if (!_fastMode) + { + if (_matchPriceCount >= (1 << 7)) + FillDistancesPrices(); + if (_alignPriceCount >= kAlignTableSize) + FillAlignPrices(); + } + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(nowPos32); + if (nowPos32 - progressPosValuePrev >= (1 << 14)) + { + nowPos64 += nowPos32 - progressPosValuePrev; + *inSize = nowPos64; + *outSize = _rangeEncoder.GetProcessedSize(); + _finished = false; + *finished = 0; + return S_OK; + } + } + } +} + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + #ifndef _NO_EXCEPTIONS + try + { + #endif + return CodeReal(inStream, outStream, inSize, outSize, progress); + #ifndef _NO_EXCEPTIONS + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } + #endif +} + +void CEncoder::FillDistancesPrices() +{ + UInt32 tempPrices[kNumFullDistances]; + for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders + + base - posSlot - 1, footerBits, i - base); + } + + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + NRangeCoder::CBitTreeEncoder &encoder = _posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = _posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < _distTableSize; posSlot++) + posSlotPrices[posSlot] = encoder.GetPrice(posSlot); + for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits); + + UInt32 *distancesPrices = _distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i]; + } + _matchPriceCount = 0; +} + +void CEncoder::FillAlignPrices() +{ + for (UInt32 i = 0; i < kAlignTableSize; i++) + _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); + _alignPriceCount = 0; +} + +}} diff --git a/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h b/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h new file mode 100644 index 00000000..f4c2c151 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h @@ -0,0 +1,411 @@ +// LZMA/Encoder.h + +#ifndef __LZMA_ENCODER_H +#define __LZMA_ENCODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" +#include "../LZ/IMatchFinder.h" +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitEncoder CMyBitEncoder; + +class CBaseState +{ +protected: + CState _state; + Byte _previousByte; + UInt32 _repDistances[kNumRepDistances]; + void Init() + { + _state.Init(); + _previousByte = 0; + for(UInt32 i = 0 ; i < kNumRepDistances; i++) + _repDistances[i] = 0; + } +}; + +struct COptimal +{ + CState State; + + bool Prev1IsChar; + bool Prev2; + + UInt32 PosPrev2; + UInt32 BackPrev2; + + UInt32 Price; + UInt32 PosPrev; // posNext; + UInt32 BackPrev; + UInt32 Backs[kNumRepDistances]; + void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; } + void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } + bool IsShortRep() { return (BackPrev == 0); } +}; + + +extern Byte g_FastPos[1 << 11]; +inline UInt32 GetPosSlot(UInt32 pos) +{ + if (pos < (1 << 11)) + return g_FastPos[pos]; + if (pos < (1 << 21)) + return g_FastPos[pos >> 10] + 20; + return g_FastPos[pos >> 20] + 40; +} + +inline UInt32 GetPosSlot2(UInt32 pos) +{ + if (pos < (1 << 17)) + return g_FastPos[pos >> 6] + 12; + if (pos < (1 << 27)) + return g_FastPos[pos >> 16] + 32; + return g_FastPos[pos >> 26] + 52; +} + +const UInt32 kIfinityPrice = 0xFFFFFFF; + +const UInt32 kNumOpts = 1 << 12; + + +class CLiteralEncoder2 +{ + CMyBitEncoder _encoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _encoders[i].Init(); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol); + void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol); + UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const; +}; + +class CLiteralEncoder +{ + CLiteralEncoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralEncoder(): _coders(0) {} + ~CLiteralEncoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits)) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte) + { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; } +}; + +namespace NLength { + +class CEncoder +{ + CMyBitEncoder _choice; + CMyBitEncoder _choice2; + NRangeCoder::CBitTreeEncoder _lowCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _midCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _highCoder; +public: + void Init(UInt32 numPosStates); + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState); + void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const; +}; + +const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; + +class CPriceTableEncoder: public CEncoder +{ + UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal]; + UInt32 _tableSize; + UInt32 _counters[kNumPosStatesEncodingMax]; +public: + void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; } + void UpdateTable(UInt32 posState) + { + SetPrices(posState, _tableSize, _prices[posState]); + _counters[posState] = _tableSize; + } + void UpdateTables(UInt32 numPosStates) + { + for (UInt32 posState = 0; posState < numPosStates; posState++) + UpdateTable(posState); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice) + { + CEncoder::Encode(rangeEncoder, symbol, posState); + if (updatePrice) + if (--_counters[posState] == 0) + UpdateTable(posState); + } +}; + +} + +class CEncoder : + public ICompressCoder, + public ICompressSetOutStream, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public CBaseState, + public CMyUnknownImp +{ + COptimal _optimum[kNumOpts]; + CMyComPtr _matchFinder; // test it + NRangeCoder::CEncoder _rangeEncoder; + + CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax]; + CMyBitEncoder _isRep[kNumStates]; + CMyBitEncoder _isRepG0[kNumStates]; + CMyBitEncoder _isRepG1[kNumStates]; + CMyBitEncoder _isRepG2[kNumStates]; + CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax]; + + NRangeCoder::CBitTreeEncoder _posSlotEncoder[kNumLenToPosStates]; + + CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeEncoder _posAlignEncoder; + + NLength::CPriceTableEncoder _lenEncoder; + NLength::CPriceTableEncoder _repMatchLenEncoder; + + CLiteralEncoder _literalEncoder; + + UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1]; + + bool _fastMode; + // bool _maxMode; + UInt32 _numFastBytes; + UInt32 _longestMatchLength; + UInt32 _numDistancePairs; + + UInt32 _additionalOffset; + + UInt32 _optimumEndIndex; + UInt32 _optimumCurrentIndex; + + bool _longestMatchWasFound; + + UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + + UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances]; + + UInt32 _alignPrices[kAlignTableSize]; + UInt32 _alignPriceCount; + + UInt32 _distTableSize; + + UInt32 _posStateBits; + UInt32 _posStateMask; + UInt32 _numLiteralPosStateBits; + UInt32 _numLiteralContextBits; + + UInt32 _dictionarySize; + + UInt32 _dictionarySizePrev; + UInt32 _numFastBytesPrev; + + UInt32 _matchPriceCount; + UInt64 nowPos64; + bool _finished; + ISequentialInStream *_inStream; + + UInt32 _matchFinderCycles; + int _matchFinderIndex; + #ifdef COMPRESS_MF_MT + bool _multiThread; + #endif + + bool _writeEndMark; + + bool _needReleaseMFStream; + + IMatchFinderSetNumPasses *setMfPasses; + + void ReleaseMatchFinder() + { + setMfPasses = 0; + _matchFinder.Release(); + } + + HRESULT ReadMatchDistances(UInt32 &len, UInt32 &numDistancePairs); + + HRESULT MovePos(UInt32 num); + UInt32 GetRepLen1Price(CState state, UInt32 posState) const + { + return _isRepG0[state.Index].GetPrice0() + + _isRep0Long[state.Index][posState].GetPrice0(); + } + + UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const + { + UInt32 price; + if(repIndex == 0) + { + price = _isRepG0[state.Index].GetPrice0(); + price += _isRep0Long[state.Index][posState].GetPrice1(); + } + else + { + price = _isRepG0[state.Index].GetPrice1(); + if (repIndex == 1) + price += _isRepG1[state.Index].GetPrice0(); + else + { + price += _isRepG1[state.Index].GetPrice1(); + price += _isRepG2[state.Index].GetPrice(repIndex - 2); + } + } + return price; + } + UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const + { + return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) + + GetPureRepPrice(repIndex, state, posState); + } + /* + UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const + { + if (pos >= kNumFullDistances) + return kIfinityPrice; + return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState); + } + UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const + { + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); + if (pos < kNumFullDistances) + price = _distancesPrices[lenToPosState][pos]; + else + price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + + _alignPrices[pos & kAlignMask]; + return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); + } + */ + UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const + { + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); + if (pos < kNumFullDistances) + price = _distancesPrices[lenToPosState][pos]; + else + price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + + _alignPrices[pos & kAlignMask]; + return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); + } + + UInt32 Backward(UInt32 &backRes, UInt32 cur); + HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes); + HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes); + + void FillDistancesPrices(); + void FillAlignPrices(); + + void ReleaseMFStream() + { + if (_matchFinder && _needReleaseMFStream) + { + _matchFinder->ReleaseStream(); + _needReleaseMFStream = false; + } + } + + void ReleaseStreams() + { + ReleaseMFStream(); + ReleaseOutStream(); + } + + HRESULT Flush(UInt32 nowPos); + class CCoderReleaser + { + CEncoder *_coder; + public: + CCoderReleaser(CEncoder *coder): _coder(coder) {} + ~CCoderReleaser() + { + _coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void WriteEndMarker(UInt32 posState); + +public: + CEncoder(); + void SetWriteEndMarkerMode(bool writeEndMarker) + { _writeEndMark= writeEndMarker; } + + HRESULT Create(); + + MY_UNKNOWN_IMP3( + ICompressSetOutStream, + ICompressSetCoderProperties, + ICompressWriteCoderProperties + ) + + HRESULT Init(); + + // ICompressCoder interface + HRESULT SetStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize); + HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished); + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressCoder interface + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressSetCoderProperties2 + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); + + // ICompressWriteCoderProperties + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + + virtual ~CEncoder() {} +}; + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA/StdAfx.h b/utils/lzma/C/7zip/Compress/LZMA/StdAfx.h new file mode 100644 index 00000000..e7fb6986 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp new file mode 100644 index 00000000..dace1476 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -0,0 +1,475 @@ +# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=AloneLZMA - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "AloneLZMA - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "AloneLZMA - Win32 Release" +# Name "AloneLZMA - Win32 Debug" +# Name "AloneLZMA - Win32 ReleaseU" +# Name "AloneLZMA - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Group "BT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3Z.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeMain.h +# End Source File +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Branch\BranchTypes.h +# End Source File +# Begin Source File + +SOURCE=..\Branch\BranchX86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\Branch\BranchX86.h +# End Source File +# End Group +# Begin Group "LZMA_C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA_C\LzmaTypes.h +# End Source File +# End Group +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaAlone.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.h +# End Source File +# End Target +# End Project diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw b/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw new file mode 100644 index 00000000..d7482d8a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp new file mode 100644 index 00000000..cce01eb2 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -0,0 +1,524 @@ +// LzmaAlone.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include + +#if defined(_WIN32) || defined(OS2) || defined(MSDOS) +#include +#include +#define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY) +#else +#define MY_SET_BINARY_MODE(file) +#endif + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +#include "LzmaBench.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "LzmaRamDecode.h" +} + +using namespace NCommandLineParser; + +#ifdef _WIN32 +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +static const char *kCantAllocate = "Can not allocate memory"; +static const char *kReadError = "Read error"; +static const char *kWriteError = "Write error"; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kMode, + kDictionary, + kFastBytes, + kMatchFinderCycles, + kLitContext, + kLitPos, + kPosBits, + kMatchFinder, + kEOS, + kStdIn, + kStdOut, + kFilter86 +}; +} + +static const CSwitchForm kSwitchForms[] = +{ + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"A", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"D", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"FB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LP", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"PB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MF", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"EOS", NSwitchType::kSimple, false }, + { L"SI", NSwitchType::kSimple, false }, + { L"SO", NSwitchType::kSimple, false }, + { L"F86", NSwitchType::kSimple, false } +}; + +static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]); + +static void PrintHelp() +{ + fprintf(stderr, "\nUsage: LZMA inputFile outputFile [...]\n" + " e: encode file\n" + " d: decode file\n" + " b: Benchmark\n" + "\n" + " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + " -d{N}: set dictionary - [0,30], default: 23 (8MB)\n" + " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + " -mc{N}: set number of cycles for match finder\n" + " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n" + " -eos: write End Of Stream marker\n" + " -si: read data from stdin\n" + " -so: write data to stdout\n" + ); +} + +static void PrintHelpAndExit(const char *s) +{ + fprintf(stderr, "\nError: %s\n\n", s); + PrintHelp(); + throw -1; +} + +static void IncorrectCommand() +{ + PrintHelpAndExit("Incorrect command"); +} + +static void WriteArgumentsToStringList(int numArguments, const char *arguments[], + UStringVector &strings) +{ + for(int i = 1; i < numArguments; i++) + strings.Add(MultiByteToUnicodeString(arguments[i])); +} + +static bool GetNumber(const wchar_t *s, UInt32 &value) +{ + value = 0; + if (MyStringLen(s) == 0) + return false; + const wchar_t *end; + UInt64 res = ConvertStringToUInt64(s, &end); + if (*end != L'\0') + return false; + if (res > 0xFFFFFFFF) + return false; + value = UInt32(res); + return true; +} + +int main2(int n, const char *args[]) +{ + #ifdef _WIN32 + g_IsNT = IsItWindowsNT(); + #endif + + fprintf(stderr, "\nLZMA 4.43 Copyright (c) 1999-2006 Igor Pavlov 2006-06-04\n"); + + if (n == 1) + { + PrintHelp(); + return 0; + } + + if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4) + { + fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile"); + return 1; + } + + UStringVector commandStrings; + WriteArgumentsToStringList(n, args, commandStrings); + CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + IncorrectCommand(); + } + + if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + + int paramIndex = 0; + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &command = nonSwitchStrings[paramIndex++]; + + bool dictionaryIsDefined = false; + UInt32 dictionary = 1 << 21; + if(parser[NKey::kDictionary].ThereIs) + { + UInt32 dicLog; + if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog)) + IncorrectCommand(); + dictionary = 1 << dicLog; + dictionaryIsDefined = true; + } + UString mf = L"BT4"; + if (parser[NKey::kMatchFinder].ThereIs) + mf = parser[NKey::kMatchFinder].PostStrings[0]; + + if (command.CompareNoCase(L"b") == 0) + { + const UInt32 kNumDefaultItereations = 10; + UInt32 numIterations = kNumDefaultItereations; + { + if (paramIndex < nonSwitchStrings.Size()) + if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations)) + numIterations = kNumDefaultItereations; + } + return LzmaBenchmark(stderr, numIterations, dictionary); + } + + bool encodeMode = false; + if (command.CompareNoCase(L"e") == 0) + encodeMode = true; + else if (command.CompareNoCase(L"d") == 0) + encodeMode = false; + else + IncorrectCommand(); + + bool stdInMode = parser[NKey::kStdIn].ThereIs; + bool stdOutMode = parser[NKey::kStdOut].ThereIs; + + CMyComPtr inStream; + CInFileStream *inStreamSpec = 0; + if (stdInMode) + { + inStream = new CStdInFileStream; + MY_SET_BINARY_MODE(stdin); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &inputName = nonSwitchStrings[paramIndex++]; + inStreamSpec = new CInFileStream; + inStream = inStreamSpec; + if (!inStreamSpec->Open(GetSystemString(inputName))) + { + fprintf(stderr, "\nError: can not open input file %s\n", + (const char *)GetOemString(inputName)); + return 1; + } + } + + CMyComPtr outStream; + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &outputName = nonSwitchStrings[paramIndex++]; + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + if (!outStreamSpec->Create(GetSystemString(outputName), true)) + { + fprintf(stderr, "\nError: can not open output file %s\n", + (const char *)GetOemString(outputName)); + return 1; + } + } + + if (parser[NKey::kFilter86].ThereIs) + { + // -f86 switch is for x86 filtered mode: BCJ + LZMA. + if (parser[NKey::kEOS].ThereIs || stdInMode) + throw "Can not use stdin in this mode"; + UInt64 fileSize; + inStreamSpec->File.GetLength(fileSize); + if (fileSize > 0xF0000000) + throw "File is too big"; + UInt32 inSize = (UInt32)fileSize; + Byte *inBuffer = 0; + if (inSize != 0) + { + inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (inBuffer == 0) + throw kCantAllocate; + } + + UInt32 processedSize; + if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK) + throw "Can not read"; + if ((UInt32)inSize != processedSize) + throw "Read size error"; + + Byte *outBuffer = 0; + size_t outSizeProcessed; + if (encodeMode) + { + // we allocate 105% of original size for output buffer + size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16); + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (outBuffer == 0) + throw kCantAllocate; + } + if (!dictionaryIsDefined) + dictionary = 1 << 23; + int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, + dictionary, SZ_FILTER_AUTO); + if (res != 0) + { + fprintf(stderr, "\nEncoder error = %d\n", (int)res); + return 1; + } + } + else + { + size_t outSize; + if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0) + throw "data error"; + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc(outSize); + if (outBuffer == 0) + throw kCantAllocate; + } + int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free); + if (res != 0) + throw "LzmaDecoder error"; + } + if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK) + throw kWriteError; + MyFree(outBuffer); + MyFree(inBuffer); + return 0; + } + + + UInt64 fileSize; + if (encodeMode) + { + NCompress::NLZMA::CEncoder *encoderSpec = + new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + if (!dictionaryIsDefined) + dictionary = 1 << 23; + + UInt32 posStateBits = 2; + UInt32 litContextBits = 3; // for normal files + // UInt32 litContextBits = 0; // for 32-bit data + UInt32 litPosBits = 0; + // UInt32 litPosBits = 2; // for 32-bit data + UInt32 algorithm = 2; + UInt32 numFastBytes = 128; + UInt32 matchFinderCycles = 16 + numFastBytes / 2; + bool matchFinderCyclesDefined = false; + + bool eos = parser[NKey::kEOS].ThereIs || stdInMode; + + if(parser[NKey::kMode].ThereIs) + if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm)) + IncorrectCommand(); + + if(parser[NKey::kFastBytes].ThereIs) + if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes)) + IncorrectCommand(); + if (matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs) + if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles)) + IncorrectCommand(); + if(parser[NKey::kLitContext].ThereIs) + if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits)) + IncorrectCommand(); + if(parser[NKey::kLitPos].ThereIs) + if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits)) + IncorrectCommand(); + if(parser[NKey::kPosBits].ThereIs) + if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits)) + IncorrectCommand(); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker, + NCoderPropID::kMatchFinderCycles + }; + const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]); + /* + NWindows::NCOM::CPropVariant properties[kNumProps]; + properties[0] = UInt32(dictionary); + properties[1] = UInt32(posStateBits); + properties[2] = UInt32(litContextBits); + + properties[3] = UInt32(litPosBits); + properties[4] = UInt32(algorithm); + properties[5] = UInt32(numFastBytes); + properties[6] = mf; + properties[7] = eos; + */ + PROPVARIANT properties[kNumPropsMax]; + for (int p = 0; p < 6; p++) + properties[p].vt = VT_UI4; + + properties[0].ulVal = UInt32(dictionary); + properties[1].ulVal = UInt32(posStateBits); + properties[2].ulVal = UInt32(litContextBits); + properties[3].ulVal = UInt32(litPosBits); + properties[4].ulVal = UInt32(algorithm); + properties[5].ulVal = UInt32(numFastBytes); + + properties[8].vt = VT_UI4; + properties[8].ulVal = UInt32(matchFinderCycles); + + properties[6].vt = VT_BSTR; + properties[6].bstrVal = (BSTR)(const wchar_t *)mf; + + properties[7].vt = VT_BOOL; + properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; + + int numProps = kNumPropsMax; + if (!matchFinderCyclesDefined) + numProps--; + + if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK) + IncorrectCommand(); + encoderSpec->WriteCoderProperties(outStream); + + if (eos || stdInMode) + fileSize = (UInt64)(Int64)-1; + else + inStreamSpec->File.GetLength(fileSize); + + for (int i = 0; i < 8; i++) + { + Byte b = Byte(fileSize >> (8 * i)); + if (outStream->Write(&b, 1, 0) != S_OK) + { + fprintf(stderr, kWriteError); + return 1; + } + } + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); + if (result == E_OUTOFMEMORY) + { + fprintf(stderr, "\nError: Can not allocate memory\n"); + return 1; + } + else if (result != S_OK) + { + fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result); + return 1; + } + } + else + { + NCompress::NLZMA::CDecoder *decoderSpec = + new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + const UInt32 kPropertiesSize = 5; + Byte properties[kPropertiesSize]; + UInt32 processedSize; + if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK) + { + fprintf(stderr, kReadError); + return 1; + } + if (processedSize != kPropertiesSize) + { + fprintf(stderr, kReadError); + return 1; + } + if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK) + { + fprintf(stderr, "SetDecoderProperties error"); + return 1; + } + fileSize = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + if (inStream->Read(&b, 1, &processedSize) != S_OK) + { + fprintf(stderr, kReadError); + return 1; + } + if (processedSize != 1) + { + fprintf(stderr, kReadError); + return 1; + } + fileSize |= ((UInt64)b) << (8 * i); + } + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) + { + fprintf(stderr, "Decoder error"); + return 1; + } + } + return 0; +} + +int main(int n, const char *args[]) +{ + try { return main2(n, args); } + catch(const char *s) + { + fprintf(stderr, "\nError: %s\n", s); + return 1; + } + catch(...) + { + fprintf(stderr, "\nError\n"); + return 1; + } +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp new file mode 100644 index 00000000..7b54b26c --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp @@ -0,0 +1,506 @@ +// LzmaBench.cpp + +#include "StdAfx.h" + +#include "LzmaBench.h" + +#ifndef _WIN32 +#include +#endif + +#include "../../../Common/CRC.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +static const UInt32 kAdditionalSize = +#ifdef _WIN32_WCE +(1 << 20); +#else +(6 << 20); +#endif + +static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const UInt32 kMaxLzmaPropSize = 10; + +class CRandomGenerator +{ + UInt32 A1; + UInt32 A2; +public: + CRandomGenerator() { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + UInt32 GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + } +}; + +class CBitRandomGenerator +{ + CRandomGenerator RG; + UInt32 Value; + int NumBits; +public: + void Init() + { + Value = 0; + NumBits = 0; + } + UInt32 GetRnd(int numBits) + { + if (NumBits > numBits) + { + UInt32 result = Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + UInt32 result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits = 32 - numBits; + return result; + } +}; + +class CBenchRandomGenerator +{ + CBitRandomGenerator RG; + UInt32 Pos; + UInt32 Rep0; +public: + UInt32 BufferSize; + Byte *Buffer; + CBenchRandomGenerator(): Buffer(0) {} + ~CBenchRandomGenerator() { Free(); } + void Free() + { + ::MidFree(Buffer); + Buffer = 0; + } + bool Alloc(UInt32 bufferSize) + { + if (Buffer != 0 && BufferSize == bufferSize) + return true; + Free(); + Buffer = (Byte *)::MidAlloc(bufferSize); + Pos = 0; + BufferSize = bufferSize; + return (Buffer != 0); + } + UInt32 GetRndBit() { return RG.GetRnd(1); } + /* + UInt32 GetLogRand(int maxLen) + { + UInt32 len = GetRnd() % (maxLen + 1); + return GetRnd() & ((1 << len) - 1); + } + */ + UInt32 GetLogRandBits(int numBits) + { + UInt32 len = RG.GetRnd(numBits); + return RG.GetRnd(len); + } + UInt32 GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); } + UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); } + void Generate() + { + RG.Init(); + Rep0 = 1; + while(Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = (Byte)RG.GetRnd(8); + else + { + UInt32 len; + if (RG.GetRnd(3) == 0) + len = 1 + GetLen1(); + else + { + do + Rep0 = GetOffset(); + while (Rep0 >= Pos); + Rep0++; + len = 2 + GetLen2(); + } + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - Rep0]; + } + } + } +}; + +class CBenchmarkInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + UInt32 Pos; + UInt32 Size; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, UInt32 size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + ((Byte *)data)[i] = Data[Pos + i]; + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +class CBenchmarkOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt32 BufferSize; + FILE *_f; +public: + UInt32 Pos; + Byte *Buffer; + CBenchmarkOutStream(): _f(0), Buffer(0) {} + virtual ~CBenchmarkOutStream() { delete []Buffer; } + void Init(FILE *f, UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + _f = f; + } + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < BufferSize; i++) + Buffer[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + fprintf(_f, "\nERROR: Buffer is full\n"); + return E_FAIL; + } + return S_OK; +} + +class CCrcOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + CCRC CRC; + MY_UNKNOWN_IMP + void Init() { CRC.Init(); } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + CRC.Update(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +static UInt64 GetTimeCount() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return value.QuadPart; + return GetTickCount(); + #else + return clock(); + #endif +} + +static UInt64 GetFreq() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return value.QuadPart; + return 1000; + #else + return CLOCKS_PER_SEC; + #endif +} + +struct CProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + UInt64 ApprovedStart; + UInt64 InSize; + UInt64 Time; + void Init() + { + InSize = 0; + Time = 0; + } + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + if (*inSize >= ApprovedStart && InSize == 0) + { + Time = ::GetTimeCount(); + InSize = *inSize; + } + return S_OK; +} + +static const int kSubBits = 8; + +static UInt32 GetLogSize(UInt32 size) +{ + for (int i = kSubBits; i < 32; i++) + for (UInt32 j = 0; j < (1 << kSubBits); j++) + if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) + return (i << kSubBits) + j; + return (32 << kSubBits); +} + +static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime) +{ + UInt64 freq = GetFreq(); + UInt64 elTime = elapsedTime; + while(freq > 1000000) + { + freq >>= 1; + elTime >>= 1; + } + if (elTime == 0) + elTime = 1; + return value * freq / elTime; +} + +static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size) +{ + UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits); + UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits)); + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; + return MyMultDiv64(numCommands, elapsedTime); +} + +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) +{ + UInt64 numCommands = inSize * 220 + outSize * 20; + return MyMultDiv64(numCommands, elapsedTime); +} + +/* +static UInt64 GetTotalRating( + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) +{ + return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; +} +*/ + +static void PrintRating(FILE *f, UInt64 rating) +{ + fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000)); +} + +static void PrintResults( + FILE *f, + UInt32 dictionarySize, + UInt64 elapsedTime, + UInt64 size, + bool decompressMode, UInt64 secondSize) +{ + UInt64 speed = MyMultDiv64(size, elapsedTime); + fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024)); + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, elapsedTime, size); + PrintRating(f, rating); +} + +static void ThrowError(FILE *f, HRESULT result, const char *s) +{ + fprintf(f, "\nError: "); + if (result == E_ABORT) + fprintf(f, "User break"); + if (result == E_OUTOFMEMORY) + fprintf(f, "Can not allocate memory"); + else + fprintf(f, s); + fprintf(f, "\n"); +} + +const wchar_t *bt2 = L"BT2"; +const wchar_t *bt4 = L"BT4"; + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize) +{ + if (numIterations == 0) + return 0; + if (dictionarySize < (1 << 18)) + { + fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n"); + return 1; + } + fprintf(f, "\n Compressing Decompressing\n\n"); + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + + CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream; + CMyComPtr propStream = propStreamSpec; + propStreamSpec->Init(f, kMaxLzmaPropSize); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[0].ulVal = UInt32(dictionarySize); + + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + { + fprintf(f, "\nError: Incorrect command\n"); + return 1; + } + encoderSpec->WriteCoderProperties(propStream); + + CBenchRandomGenerator rg; + if (!rg.Alloc(kBufferSize)) + { + fprintf(f, "\nError: Can't allocate memory\n"); + return 1; + } + + rg.Generate(); + CCRC crc; + crc.Update(rg.Buffer, rg.BufferSize); + + CProgressInfo *progressInfoSpec = new CProgressInfo; + CMyComPtr progressInfo = progressInfoSpec; + + progressInfoSpec->ApprovedStart = dictionarySize; + + UInt64 totalBenchSize = 0; + UInt64 totalEncodeTime = 0; + UInt64 totalDecodeTime = 0; + UInt64 totalCompressedSize = 0; + + for (UInt32 i = 0; i < numIterations; i++) + { + progressInfoSpec->Init(); + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + inStreamSpec->Init(rg.Buffer, rg.BufferSize); + CMyComPtr inStream = inStreamSpec; + CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream; + outStreamSpec->Init(f, kCompressedBufferSize); + CMyComPtr outStream = outStreamSpec; + HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo); + UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time; + UInt32 compressedSize = outStreamSpec->Pos; + if(result != S_OK) + { + ThrowError(f, result, "Encoder Error"); + return 1; + } + if (progressInfoSpec->InSize == 0) + { + fprintf(f, "\nError: Internal ERROR 1282\n"); + return 1; + } + + /////////////////////// + // Decompressing + + CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; + CMyComPtr crcOutStream = crcOutStreamSpec; + + UInt64 decodeTime; + for (int j = 0; j < 2; j++) + { + inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + crcOutStreamSpec->Init(); + + if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK) + { + fprintf(f, "\nError: Set Decoder Properties Error\n"); + return 1; + } + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); + result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0); + decodeTime = ::GetTimeCount() - startTime; + if(result != S_OK) + { + ThrowError(f, result, "Decode Error"); + return 1; + } + if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest()) + { + fprintf(f, "\nError: CRC Error\n"); + return 1; + } + } + UInt64 benchSize = kBufferSize - progressInfoSpec->InSize; + PrintResults(f, dictionarySize, encodeTime, benchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, decodeTime, kBufferSize, true, compressedSize); + fprintf(f, "\n"); + + totalBenchSize += benchSize; + totalEncodeTime += encodeTime; + totalDecodeTime += decodeTime; + totalCompressedSize += compressedSize; + } + fprintf(f, "---------------------------------------------------\n"); + PrintResults(f, dictionarySize, totalEncodeTime, totalBenchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, totalDecodeTime, + kBufferSize * numIterations, true, totalCompressedSize); + fprintf(f, " Average\n"); + return 0; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h new file mode 100644 index 00000000..a6a0e82e --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h @@ -0,0 +1,11 @@ +// LzmaBench.h + +#ifndef __LzmaBench_h +#define __LzmaBench_h + +#include +#include "../../../Common/Types.h" + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize); + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp new file mode 100644 index 00000000..090d73d8 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -0,0 +1,228 @@ +// LzmaRam.cpp + +#include "StdAfx.h" +#include "../../../Common/Types.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "../Branch/BranchX86.h" +} + +class CInStreamRam: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + size_t Size; + size_t Pos; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + ((Byte *)data)[i] = Data[Pos + i]; + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +class COutStreamRam: + public ISequentialOutStream, + public CMyUnknownImp +{ + size_t Size; +public: + Byte *Data; + size_t Pos; + bool Overflow; + void Init(Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + Overflow = false; + } + void SetPos(size_t pos) + { + Overflow = false; + Pos = pos; + } + MY_UNKNOWN_IMP + HRESULT WriteByte(Byte b) + { + if (Pos >= Size) + { + Overflow = true; + return E_FAIL; + } + Data[Pos++] = b; + return S_OK; + } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < Size; i++) + Data[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + Overflow = true; + return E_FAIL; + } + return S_OK; +} + +#define SZE_FAIL (1) +#define SZE_OUTOFMEMORY (2) +#define SZE_OUT_OVERFLOW (3) + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode) +{ + #ifndef _NO_EXCEPTIONS + try { + #endif + + *outSizeProcessed = 0; + const size_t kIdSize = 1; + const size_t kLzmaPropsSize = 5; + const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8; + if (outSize < kMinDestSize) + return SZE_OUT_OVERFLOW; + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + PROPID propIDs[] = + { + NCoderPropID::kAlgorithm, + NCoderPropID::kDictionarySize, + NCoderPropID::kNumFastBytes, + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[1].vt = VT_UI4; + properties[2].vt = VT_UI4; + properties[0].ulVal = (UInt32)2; + properties[1].ulVal = (UInt32)dictionarySize; + properties[2].ulVal = (UInt32)64; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + return 1; + + COutStreamRam *outStreamSpec = new COutStreamRam; + if (outStreamSpec == 0) + return SZE_OUTOFMEMORY; + CMyComPtr outStream = outStreamSpec; + CInStreamRam *inStreamSpec = new CInStreamRam; + if (inStreamSpec == 0) + return SZE_OUTOFMEMORY; + CMyComPtr inStream = inStreamSpec; + + outStreamSpec->Init(outBuffer, outSize); + if (outStreamSpec->WriteByte(0) != S_OK) + return SZE_OUT_OVERFLOW; + + if (encoderSpec->WriteCoderProperties(outStream) != S_OK) + return SZE_OUT_OVERFLOW; + if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize) + return 1; + + int i; + for (i = 0; i < 8; i++) + { + UInt64 t = (UInt64)(inSize); + if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK) + return SZE_OUT_OVERFLOW; + } + + Byte *filteredStream = 0; + + bool useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (inSize != 0) + { + filteredStream = (Byte *)MyAlloc(inSize); + if (filteredStream == 0) + return SZE_OUTOFMEMORY; + memmove(filteredStream, inBuffer, inSize); + } + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1); + } + + UInt32 minSize = 0; + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + bool bestIsFiltered = false; + int mainResult = 0; + size_t startPos = outStreamSpec->Pos; + for (i = 0; i < numPasses; i++) + { + if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered) + break; + outStreamSpec->SetPos(startPos); + bool curModeIsFiltered = false; + if (useFilter && i == 0) + curModeIsFiltered = true; + if (numPasses > 1 && i == numPasses - 1) + curModeIsFiltered = true; + + inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize); + + HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0); + + mainResult = 0; + if (lzmaResult == E_OUTOFMEMORY) + { + mainResult = SZE_OUTOFMEMORY; + break; + } + if (i == 0 || outStreamSpec->Pos <= minSize) + { + minSize = outStreamSpec->Pos; + bestIsFiltered = curModeIsFiltered; + } + if (outStreamSpec->Overflow) + mainResult = SZE_OUT_OVERFLOW; + else if (lzmaResult != S_OK) + { + mainResult = SZE_FAIL; + break; + } + } + *outSizeProcessed = outStreamSpec->Pos; + if (bestIsFiltered) + outBuffer[0] = 1; + if (useFilter) + MyFree(filteredStream); + return mainResult; + + #ifndef _NO_EXCEPTIONS + } catch(...) { return SZE_OUTOFMEMORY; } + #endif +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h new file mode 100644 index 00000000..1244dc86 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h @@ -0,0 +1,46 @@ +// LzmaRam.h + +#ifndef __LzmaRam_h +#define __LzmaRam_h + +#include +#include "../../../Common/Types.h" + +/* +LzmaRamEncode: BCJ + LZMA RAM->RAM compressing. +It uses .lzma format, but it writes one additional byte to .lzma file: + 0: - no filter + 1: - x86(BCJ) filter. + +To provide best compression ratio dictionarySize mustbe >= inSize + +LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions. +RAM Requirements: + RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize + FilterBlockSize = 0, if useFilter == false + FilterBlockSize = inSize, if useFilter == true + + Return code: + 0 - OK + 1 - Unspecified Error + 2 - Memory allocating error + 3 - Output buffer OVERFLOW + +If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode); + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c new file mode 100644 index 00000000..11ff7f69 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c @@ -0,0 +1,79 @@ +/* LzmaRamDecode.c */ + +#include "LzmaRamDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#include "BranchX86.h" +#else +#include "../LZMA_C/LzmaDecode.h" +#include "../Branch/BranchX86.h" +#endif + +#define LZMA_PROPS_SIZE 14 +#define LZMA_SIZE_OFFSET 6 + +int LzmaRamGetUncompressedSize( + const unsigned char *inBuffer, + size_t inSize, + size_t *outSize) +{ + unsigned int i; + if (inSize < LZMA_PROPS_SIZE) + return 1; + *outSize = 0; + for(i = 0; i < sizeof(size_t); i++) + *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i); + for(; i < 8; i++) + if (inBuffer[LZMA_SIZE_OFFSET + i] != 0) + return 1; + return 0; +} + +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) + +int LzmaRamDecompress( + const unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)) +{ + CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */ + int result; + SizeT outSizeProcessedLoc; + SizeT inProcessed; + int useFilter; + + if (inSize < LZMA_PROPS_SIZE) + return 1; + useFilter = inBuffer[0]; + + *outSizeProcessed = 0; + if (useFilter > 1) + return 1; + + if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) + return 1; + state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (state.Probs == 0) + return SZE_OUTOFMEMORY; + + result = LzmaDecode(&state, + inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed, + outBuffer, (SizeT)outSize, &outSizeProcessedLoc); + freeFunc(state.Probs); + if (result != LZMA_RESULT_OK) + return 1; + *outSizeProcessed = (size_t)outSizeProcessedLoc; + if (useFilter == 1) + { + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); + } + return 0; +} \ No newline at end of file diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h new file mode 100644 index 00000000..7e641c55 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h @@ -0,0 +1,55 @@ +/* LzmaRamDecode.h */ + +#ifndef __LzmaRamDecode_h +#define __LzmaRamDecode_h + +#include + +/* +LzmaRamGetUncompressedSize: + In: + inBuffer - input data + inSize - input data size + Out: + outSize - uncompressed size + Return code: + 0 - OK + 1 - Error in headers +*/ + +int LzmaRamGetUncompressedSize( + const unsigned char *inBuffer, + size_t inSize, + size_t *outSize); + + +/* +LzmaRamDecompress: + In: + inBuffer - input data + inSize - input data size + outBuffer - output data + outSize - output size + allocFunc - alloc function (can be malloc) + freeFunc - free function (can be free) + Out: + outSizeProcessed - processed size + Return code: + 0 - OK + 1 - Error in headers / data stream + 2 - Memory allocating error + +Memory requirements depend from properties of LZMA stream. +With default lzma settings it's about 16 KB. +*/ + +int LzmaRamDecompress( + const unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)); + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp b/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp new file mode 100644 index 00000000..d0feea85 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h b/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h new file mode 100644 index 00000000..e7fb6986 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile b/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile new file mode 100644 index 00000000..63a63ae4 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile @@ -0,0 +1,100 @@ +PROG = lzma.exe +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/ -GS- +CFLAGS_O1 = $(CFLAGS) -O1 +CFLAGS_O2 = $(CFLAGS) -O2 + +LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CPP) $(CFLAGS_O1) $** +COMPL_O2 = $(CPP) $(CFLAGS_O2) $** +COMPL = $(CPP) $(CFLAGS_O1) $** + + +LZMA_OBJS = \ + $O\LzmaAlone.obj \ + $O\LzmaBench.obj \ + $O\LzmaRam.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\CommandLineParser.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZInWindow.obj \ + $O\LZOutWindow.obj \ + + +OBJS = \ + $(LZMA_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $O\LzmaRamDecode.obj \ + $O\LzmaDecode.obj \ + $O\FileStreams.obj \ + $O\FileIO.obj \ + $O\RangeCoderBit.obj \ + $O\BranchX86.obj \ + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch + +$O: + if not exist "$O" mkdir "$O" + +$(PROGPATH): $O $(OBJS) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) + + +$(LZMA_OBJS): $(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp + $(COMPL) +$O\LzmaRamDecode.obj: LzmaRamDecode.c + $(COMPL_O1) +$O\LzmaDecode.obj: ../LZMA_C/LzmaDecode.c + $(COMPL_O2) +$O\BranchX86.obj: ../Branch/BranchX86.c + $(COMPL_O2) +$O\FileStreams.obj: ../../Common/FileStreams.cpp + $(COMPL) +$O\FileIO.obj: ../../../Windows/FileIO.cpp + $(COMPL) diff --git a/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc b/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc new file mode 100644 index 00000000..1e180742 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc @@ -0,0 +1,113 @@ +PROG = lzma +CXX = g++ -O2 -Wall +CXX_C = gcc -O2 -Wall +LIB = -lm +RM = rm -f +CFLAGS = -c -I ../../../ + +OBJS = \ + LzmaAlone.o \ + LzmaBench.o \ + LzmaRam.o \ + LzmaRamDecode.o \ + LzmaDecode.o \ + BranchX86.o \ + LZMADecoder.o \ + LZMAEncoder.o \ + LZInWindow.o \ + LZOutWindow.o \ + RangeCoderBit.o \ + InBuffer.o \ + OutBuffer.o \ + FileStreams.o \ + StreamUtils.o \ + Alloc.o \ + C_FileIO.o \ + CommandLineParser.o \ + CRC.o \ + String.o \ + StringConvert.o \ + StringToInt.o \ + Vector.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CFLAGS) LzmaAlone.cpp + +LzmaBench.o: LzmaBench.cpp + $(CXX) $(CFLAGS) LzmaBench.cpp + +LzmaRam.o: LzmaRam.cpp + $(CXX) $(CFLAGS) LzmaRam.cpp + +LzmaRamDecode.o: LzmaRamDecode.c + $(CXX_C) $(CFLAGS) LzmaRamDecode.c + +LzmaDecode.o: ../LZMA_C/LzmaDecode.c + $(CXX_C) $(CFLAGS) ../LZMA_C/LzmaDecode.c + +BranchX86.o: ../Branch/BranchX86.c + $(CXX_C) $(CFLAGS) ../Branch/BranchX86.c + +LZMADecoder.o: ../LZMA/LZMADecoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp + +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp + +LZInWindow.o: ../LZ/LZInWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp + +LZOutWindow.o: ../LZ/LZOutWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp + +RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp + $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp + +InBuffer.o: ../../Common/InBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp + +OutBuffer.o: ../../Common/OutBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp + +FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp + +StreamUtils.o: ../../Common/StreamUtils.cpp + $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp + +Alloc.o: ../../../Common/Alloc.cpp + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp + +C_FileIO.o: ../../../Common/C_FileIO.cpp + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp + +CommandLineParser.o: ../../../Common/CommandLineParser.cpp + $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp + +CRC.o: ../../../Common/CRC.cpp + $(CXX) $(CFLAGS) ../../../Common/CRC.cpp + +MyWindows.o: ../../../Common/MyWindows.cpp + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp + +String.o: ../../../Common/String.cpp + $(CXX) $(CFLAGS) ../../../Common/String.cpp + +StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp + +StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp + +Vector.o: ../../../Common/Vector.cpp + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c new file mode 100644 index 00000000..cb834537 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c @@ -0,0 +1,584 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + #ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; + #else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; + #endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + + #endif /* _LZMA_OUT_READ */ + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + #else + *inSizeProcessed = (SizeT)(Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h new file mode 100644 index 00000000..2870eeb9 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h @@ -0,0 +1,113 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +#include "LzmaTypes.h" + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + #ifdef _LZMA_OUT_READ + UInt32 DictionarySize; + #endif +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + #ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; + #endif + + #ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; + #endif +} CLzmaDecoderState; + +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c new file mode 100644 index 00000000..a3a5eb9d --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c @@ -0,0 +1,712 @@ +/* + LzmaDecodeSize.c + LZMA Decoder (optimized for Size version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +typedef struct _CRangeDecoder +{ + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback; + int Result; + #endif + int ExtraBytes; +} CRangeDecoder; + +Byte RangeDecoderReadByte(CRangeDecoder *rd) +{ + if (rd->Buffer == rd->BufferLim) + { + #ifdef _LZMA_IN_CB + SizeT size; + rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); + rd->BufferLim = rd->Buffer + size; + if (size == 0) + #endif + { + rd->ExtraBytes = 1; + return 0xFF; + } + } + return (*rd->Buffer++); +} + +/* #define ReadByte (*rd->Buffer++) */ +#define ReadByte (RangeDecoderReadByte(rd)) + +void RangeDecoderInit(CRangeDecoder *rd + #ifndef _LZMA_IN_CB + , const Byte *stream, SizeT bufferSize + #endif + ) +{ + int i; + #ifdef _LZMA_IN_CB + rd->Buffer = rd->BufferLim = 0; + #else + rd->Buffer = stream; + rd->BufferLim = stream + bufferSize; + #endif + rd->ExtraBytes = 0; + rd->Code = 0; + rd->Range = (0xFFFFFFFF); + for(i = 0; i < 5; i++) + rd->Code = (rd->Code << 8) | ReadByte; +} + +#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; +#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; +#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } + +UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) +{ + RC_INIT_VAR + UInt32 result = 0; + int i; + for (i = numTotalBits; i != 0; i--) + { + /* UInt32 t; */ + range >>= 1; + + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + /* + t = (code - range) >> 31; + t &= 1; + code -= range & (t - 1); + result = (result + result) | (1 - t); + */ + RC_NORMALIZE + } + RC_FLUSH_VAR + return result; +} + +int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) +{ + UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; + if (rd->Code < bound) + { + rd->Range = bound; + *prob += (kBitModelTotal - *prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 0; + } + else + { + rd->Range -= bound; + rd->Code -= bound; + *prob -= (*prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 1; + } +} + +#define RC_GET_BIT2(prob, mi, A0, A1) \ + UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ + if (code < bound) \ + { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ + RC_NORMALIZE + +#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) + +int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = numLevels; i != 0; i--) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT(prob, mi) + #else + mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return mi - (1 << numLevels); +} + +int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + int symbol = 0; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = 0; i < numLevels; i++) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) + #else + int bit = RangeDecoderBitDecode(probs + mi, rd); + mi = mi + mi + bit; + symbol |= (bit << i); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + int bit; + int matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + #ifdef _LZMA_LOC_OPT + { + CProb *prob = probs + 0x100 + (matchBit << 8) + symbol; + RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) + } + #else + bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd); + symbol = (symbol << 1) | bit; + #endif + if (matchBit != bit) + { + while (symbol < 0x100) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + break; + } + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) +{ + if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) + return RangeDecoderBitTreeDecode(p + LenLow + + (posState << kLenNumLowBits), kLenNumLowBits, rd); + if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) + return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + + (posState << kLenNumMidBits), kLenNumMidBits, rd); + return kLenNumLowSymbols + kLenNumMidSymbols + + RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); +} + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + CRangeDecoder rd; + + #ifdef _LZMA_OUT_READ + + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + rd.Range = vs->Range; + rd.Code = vs->Code; + #ifdef _LZMA_IN_CB + rd.InCallback = InCallback; + rd.Buffer = vs->Buffer; + rd.BufferLim = vs->BufferLim; + #else + rd.Buffer = inStream; + rd.BufferLim = inStream + inSize; + #endif + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + RangeDecoderInit(&rd + #ifndef _LZMA_IN_CB + , inStream, inSize + #endif + ); + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #ifdef _LZMA_IN_CB + rd.Result = LZMA_RESULT_OK; + #endif + rd.ExtraBytes = 0; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + rd.InCallback = InCallback; + #endif + RangeDecoderInit(&rd + #ifndef _LZMA_IN_CB + , inStream, inSize + #endif + ); + + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + + #endif /* _LZMA_OUT_READ */ + + + while(nowPos < outSize) + { + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + CProb *probs = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + Byte matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); + } + else + previousByte = LzmaLiteralDecode(probs, &rd); + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) + { + if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) + { + if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < 7 ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + continue; + } + } + else + { + UInt32 distance; + if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) + distance = rep1; + else + { + if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + len = LzmaLenDecode(p + RepLenCoder, &rd, posState); + state = state < 7 ? 8 : 11; + } + else + { + int posSlot; + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < 7 ? 7 : 10; + len = LzmaLenDecode(p + LenCoder, &rd, posState); + posSlot = RangeDecoderBitTreeDecode(p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits), kNumPosSlotBits, &rd); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); + if (posSlot < kEndPosModelIndex) + { + rep0 += RangeDecoderReverseBitTreeDecode( + p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); + } + else + { + rep0 += RangeDecoderDecodeDirectBits(&rd, + numDirectBits - kNumAlignBits) << kNumAlignBits; + rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + + + #ifdef _LZMA_OUT_READ + vs->Range = rd.Range; + vs->Code = rd.Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = rd.Buffer; + vs->BufferLim = rd.BufferLim; + #else + *inSizeProcessed = (SizeT)(rd.Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c new file mode 100644 index 00000000..e50f88b5 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c @@ -0,0 +1,521 @@ +/* + LzmaStateDecode.c + LZMA Decoder (State version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaStateDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }} + +#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +/* kRequiredInBufferSize = number of required input bytes for worst case: + longest match with longest distance. + kLzmaInBufferSize must be larger than kRequiredInBufferSize + 23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE) +*/ + +#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8) + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + return LZMA_RESULT_OK; + } +} + +int LzmaDecode( + CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed, + int finishDecoding) +{ + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + + unsigned char *Buffer = vs->Buffer; + int BufferSize = vs->BufferSize; /* don't change it to unsigned int */ + CProb *p = vs->Probs; + + int state = vs->State; + unsigned char previousByte; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + SizeT nowPos = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + unsigned char *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + unsigned char tempDictionary[4]; + + (*inSizeProcessed) = 0; + (*outSizeProcessed) = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + while (inSize > 0 && BufferSize < kLzmaInBufferSize) + { + Buffer[BufferSize++] = *inStream++; + (*inSizeProcessed)++; + inSize--; + } + if (BufferSize < 5) + { + vs->BufferSize = BufferSize; + return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK; + } + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + RC_INIT; + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + while(1) + { + int bufferPos = (int)(Buffer - vs->Buffer); + if (BufferSize - bufferPos < kRequiredInBufferSize) + { + int i; + BufferSize -= bufferPos; + if (BufferSize < 0) + return LZMA_RESULT_DATA_ERROR; + for (i = 0; i < BufferSize; i++) + vs->Buffer[i] = Buffer[i]; + Buffer = vs->Buffer; + while (inSize > 0 && BufferSize < kLzmaInBufferSize) + { + Buffer[BufferSize++] = *inStream++; + (*inSizeProcessed)++; + inSize--; + } + if (BufferSize < kRequiredInBufferSize && !finishDecoding) + break; + } + if (nowPos >= outSize) + break; + { + CProb *prob; + UInt32 bound; + int posState = (int)((nowPos + globalPos) & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (unsigned char)symbol; + + outStream[nowPos++] = previousByte; + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + UInt32 pos; + UpdateBit0(prob); + if (distanceLimit == 0) + return LZMA_RESULT_DATA_ERROR; + if (distanceLimit < dictionarySize) + distanceLimit++; + state = state < kNumLitStates ? 9 : 11; + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + outStream[nowPos++] = previousByte; + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + if (rep0 > distanceLimit) + return LZMA_RESULT_DATA_ERROR; + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + + do + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + } + RC_NORMALIZE; + + BufferSize -= (int)(Buffer - vs->Buffer); + if (BufferSize < 0) + return LZMA_RESULT_DATA_ERROR; + { + int i; + for (i = 0; i < BufferSize; i++) + vs->Buffer[i] = Buffer[i]; + } + vs->BufferSize = BufferSize; + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = (UInt32)(globalPos + nowPos); + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + + (*outSizeProcessed) = nowPos; + return LZMA_RESULT_OK; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h new file mode 100644 index 00000000..26490d61 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h @@ -0,0 +1,96 @@ +/* + LzmaStateDecode.h + LZMA Decoder interface (State version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMASTATEDECODE_H +#define __LZMASTATEDECODE_H + +#include "LzmaTypes.h" + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + UInt32 DictionarySize; +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp))) + +#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */ + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + unsigned char *Dictionary; + + unsigned char Buffer[kLzmaInBufferSize]; + int BufferSize; + + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; /* -2: decoder needs internal initialization + -1: stream was finished, + 0: ok + > 0: need to write RemainLen bytes as match Reps[0], + */ + unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */ +} CLzmaDecoderState; + +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; } + +/* LzmaDecode: decoding from input stream to output stream. + If finishDecoding != 0, then there are no more bytes in input stream + after inStream[inSize - 1]. */ + +int LzmaDecode(CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed, + int finishDecoding); + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c new file mode 100644 index 00000000..5df4e438 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c @@ -0,0 +1,195 @@ +/* +LzmaStateTest.c +Test application for LZMA Decoder (State version) + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.26 (2005-08-02) +*/ + +#include +#include +#include + +#include "LzmaStateDecode.h" + +const char *kCantReadMessage = "Can not read input file"; +const char *kCantWriteMessage = "Can not write output file"; +const char *kCantAllocateMessage = "Can not allocate memory"; + +#define kInBufferSize (1 << 15) +#define kOutBufferSize (1 << 15) + +unsigned char g_InBuffer[kInBufferSize]; +unsigned char g_OutBuffer[kOutBufferSize]; + +size_t MyReadFile(FILE *file, void *data, size_t size) + { return fread(data, 1, size, file); } + +int MyReadFileAndCheck(FILE *file, void *data, size_t size) + { return (MyReadFile(file, data, size) == size); } + +int PrintError(char *buffer, const char *message) +{ + sprintf(buffer + strlen(buffer), "\nError: "); + sprintf(buffer + strlen(buffer), message); + return 1; +} + +int main3(FILE *inFile, FILE *outFile, char *rs) +{ + /* We use two 32-bit integers to construct 64-bit integer for file size. + You can remove outSizeHigh, if you don't need >= 4GB supporting, + or you can use UInt64 outSize, if your compiler supports 64-bit integers*/ + UInt32 outSize = 0; + UInt32 outSizeHigh = 0; + + int waitEOS = 1; + /* waitEOS = 1, if there is no uncompressed size in headers, + so decoder will wait EOS (End of Stream Marker) in compressed stream */ + + int i; + int res = 0; + CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */ + unsigned char properties[LZMA_PROPERTIES_SIZE]; + SizeT inAvail = 0; + unsigned char *inBuffer = 0; + + if (sizeof(UInt32) < 4) + return PrintError(rs, "LZMA decoder needs correct UInt32"); + + /* Read LZMA properties for compressed stream */ + + if (!MyReadFileAndCheck(inFile, properties, sizeof(properties))) + return PrintError(rs, kCantReadMessage); + + /* Read uncompressed size */ + + for (i = 0; i < 8; i++) + { + unsigned char b; + if (!MyReadFileAndCheck(inFile, &b, 1)) + return PrintError(rs, kCantReadMessage); + if (b != 0xFF) + waitEOS = 0; + if (i < 4) + outSize += (UInt32)(b) << (i * 8); + else + outSizeHigh += (UInt32)(b) << ((i - 4) * 8); + } + + /* Decode LZMA properties and allocate memory */ + + if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) + return PrintError(rs, "Incorrect stream properties"); + state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (state.Probs == 0) + return PrintError(rs, kCantAllocateMessage); + + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else + { + state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); + if (state.Dictionary == 0) + { + free(state.Probs); + return PrintError(rs, kCantAllocateMessage); + } + } + + /* Decompress */ + + LzmaDecoderInit(&state); + + do + { + SizeT inProcessed, outProcessed; + int finishDecoding; + UInt32 outAvail = kOutBufferSize; + if (!waitEOS && outSizeHigh == 0 && outAvail > outSize) + outAvail = outSize; + if (inAvail == 0) + { + inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize); + inBuffer = g_InBuffer; + } + finishDecoding = (inAvail == 0); + res = LzmaDecode(&state, + inBuffer, inAvail, &inProcessed, + g_OutBuffer, outAvail, &outProcessed, + finishDecoding); + if (res != 0) + { + sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); + res = 1; + break; + } + inAvail -= inProcessed; + inBuffer += inProcessed; + + if (outFile != 0) + if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed) + { + PrintError(rs, kCantWriteMessage); + res = 1; + break; + } + + if (outSize < outProcessed) + outSizeHigh--; + outSize -= (UInt32)outProcessed; + outSize &= 0xFFFFFFFF; + + if (outProcessed == 0 && finishDecoding) + { + if (!waitEOS && (outSize != 0 || outSizeHigh != 0)) + res = 1; + break; + } + } + while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS); + + free(state.Dictionary); + free(state.Probs); + return res; +} + +int main2(int numArgs, const char *args[], char *rs) +{ + FILE *inFile = 0; + FILE *outFile = 0; + int res; + + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); + if (numArgs < 2 || numArgs > 3) + { + sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); + return 1; + } + + inFile = fopen(args[1], "rb"); + if (inFile == 0) + return PrintError(rs, "Can not open input file"); + + if (numArgs > 2) + { + outFile = fopen(args[2], "wb+"); + if (outFile == 0) + return PrintError(rs, "Can not open output file"); + } + + res = main3(inFile, outFile, rs); + + if (outFile != 0) + fclose(outFile); + fclose(inFile); + return res; +} + +int main(int numArgs, const char *args[]) +{ + char rs[800] = { 0 }; + int res = main2(numArgs, args, rs); + printf(rs); + return res; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c new file mode 100644 index 00000000..f95a753b --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c @@ -0,0 +1,342 @@ +/* +LzmaTest.c +Test application for LZMA Decoder + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.26 (2005-08-05) +*/ + +#include +#include +#include + +#include "LzmaDecode.h" + +const char *kCantReadMessage = "Can not read input file"; +const char *kCantWriteMessage = "Can not write output file"; +const char *kCantAllocateMessage = "Can not allocate memory"; + +size_t MyReadFile(FILE *file, void *data, size_t size) +{ + if (size == 0) + return 0; + return fread(data, 1, size, file); +} + +int MyReadFileAndCheck(FILE *file, void *data, size_t size) + { return (MyReadFile(file, data, size) == size);} + +size_t MyWriteFile(FILE *file, const void *data, size_t size) +{ + if (size == 0) + return 0; + return fwrite(data, 1, size, file); +} + +int MyWriteFileAndCheck(FILE *file, const void *data, size_t size) + { return (MyWriteFile(file, data, size) == size); } + +#ifdef _LZMA_IN_CB +#define kInBufferSize (1 << 15) +typedef struct _CBuffer +{ + ILzmaInCallback InCallback; + FILE *File; + unsigned char Buffer[kInBufferSize]; +} CBuffer; + +int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size) +{ + CBuffer *b = (CBuffer *)object; + *buffer = b->Buffer; + *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize); + return LZMA_RESULT_OK; +} +CBuffer g_InBuffer; + +#endif + +#ifdef _LZMA_OUT_READ +#define kOutBufferSize (1 << 15) +unsigned char g_OutBuffer[kOutBufferSize]; +#endif + +int PrintError(char *buffer, const char *message) +{ + sprintf(buffer + strlen(buffer), "\nError: "); + sprintf(buffer + strlen(buffer), message); + return 1; +} + +int main3(FILE *inFile, FILE *outFile, char *rs) +{ + /* We use two 32-bit integers to construct 64-bit integer for file size. + You can remove outSizeHigh, if you don't need >= 4GB supporting, + or you can use UInt64 outSize, if your compiler supports 64-bit integers*/ + UInt32 outSize = 0; + UInt32 outSizeHigh = 0; + #ifndef _LZMA_OUT_READ + SizeT outSizeFull; + unsigned char *outStream; + #endif + + int waitEOS = 1; + /* waitEOS = 1, if there is no uncompressed size in headers, + so decoder will wait EOS (End of Stream Marker) in compressed stream */ + + #ifndef _LZMA_IN_CB + SizeT compressedSize; + unsigned char *inStream; + #endif + + CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ + unsigned char properties[LZMA_PROPERTIES_SIZE]; + + int res; + + #ifdef _LZMA_IN_CB + g_InBuffer.File = inFile; + #endif + + if (sizeof(UInt32) < 4) + return PrintError(rs, "LZMA decoder needs correct UInt32"); + + #ifndef _LZMA_IN_CB + { + long length; + fseek(inFile, 0, SEEK_END); + length = ftell(inFile); + fseek(inFile, 0, SEEK_SET); + if ((long)(SizeT)length != length) + return PrintError(rs, "Too big compressed stream"); + compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8)); + } + #endif + + /* Read LZMA properties for compressed stream */ + + if (!MyReadFileAndCheck(inFile, properties, sizeof(properties))) + return PrintError(rs, kCantReadMessage); + + /* Read uncompressed size */ + + { + int i; + for (i = 0; i < 8; i++) + { + unsigned char b; + if (!MyReadFileAndCheck(inFile, &b, 1)) + return PrintError(rs, kCantReadMessage); + if (b != 0xFF) + waitEOS = 0; + if (i < 4) + outSize += (UInt32)(b) << (i * 8); + else + outSizeHigh += (UInt32)(b) << ((i - 4) * 8); + } + + #ifndef _LZMA_OUT_READ + if (waitEOS) + return PrintError(rs, "Stream with EOS marker is not supported"); + outSizeFull = (SizeT)outSize; + if (sizeof(SizeT) >= 8) + outSizeFull |= (((SizeT)outSizeHigh << 16) << 16); + else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) + return PrintError(rs, "Too big uncompressed stream"); + #endif + } + + /* Decode LZMA properties and allocate memory */ + + if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) + return PrintError(rs, "Incorrect stream properties"); + state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + + #ifdef _LZMA_OUT_READ + if (state.Properties.DictionarySize == 0) + state.Dictionary = 0; + else + state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); + #else + if (outSizeFull == 0) + outStream = 0; + else + outStream = (unsigned char *)malloc(outSizeFull); + #endif + + #ifndef _LZMA_IN_CB + if (compressedSize == 0) + inStream = 0; + else + inStream = (unsigned char *)malloc(compressedSize); + #endif + + if (state.Probs == 0 + #ifdef _LZMA_OUT_READ + || (state.Dictionary == 0 && state.Properties.DictionarySize != 0) + #else + || (outStream == 0 && outSizeFull != 0) + #endif + #ifndef _LZMA_IN_CB + || (inStream == 0 && compressedSize != 0) + #endif + ) + { + free(state.Probs); + #ifdef _LZMA_OUT_READ + free(state.Dictionary); + #else + free(outStream); + #endif + #ifndef _LZMA_IN_CB + free(inStream); + #endif + return PrintError(rs, kCantAllocateMessage); + } + + /* Decompress */ + + #ifdef _LZMA_IN_CB + g_InBuffer.InCallback.Read = LzmaReadCompressed; + #else + if (!MyReadFileAndCheck(inFile, inStream, compressedSize)) + return PrintError(rs, kCantReadMessage); + #endif + + #ifdef _LZMA_OUT_READ + { + #ifndef _LZMA_IN_CB + SizeT inAvail = compressedSize; + const unsigned char *inBuffer = inStream; + #endif + LzmaDecoderInit(&state); + do + { + #ifndef _LZMA_IN_CB + SizeT inProcessed; + #endif + SizeT outProcessed; + SizeT outAvail = kOutBufferSize; + if (!waitEOS && outSizeHigh == 0 && outAvail > outSize) + outAvail = (SizeT)outSize; + res = LzmaDecode(&state, + #ifdef _LZMA_IN_CB + &g_InBuffer.InCallback, + #else + inBuffer, inAvail, &inProcessed, + #endif + g_OutBuffer, outAvail, &outProcessed); + if (res != 0) + { + sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); + res = 1; + break; + } + #ifndef _LZMA_IN_CB + inAvail -= inProcessed; + inBuffer += inProcessed; + #endif + + if (outFile != 0) + if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed)) + { + PrintError(rs, kCantWriteMessage); + res = 1; + break; + } + + if (outSize < outProcessed) + outSizeHigh--; + outSize -= (UInt32)outProcessed; + outSize &= 0xFFFFFFFF; + + if (outProcessed == 0) + { + if (!waitEOS && (outSize != 0 || outSizeHigh != 0)) + res = 1; + break; + } + } + while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS); + } + + #else + { + #ifndef _LZMA_IN_CB + SizeT inProcessed; + #endif + SizeT outProcessed; + res = LzmaDecode(&state, + #ifdef _LZMA_IN_CB + &g_InBuffer.InCallback, + #else + inStream, compressedSize, &inProcessed, + #endif + outStream, outSizeFull, &outProcessed); + if (res != 0) + { + sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); + res = 1; + } + else if (outFile != 0) + { + if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed)) + { + PrintError(rs, kCantWriteMessage); + res = 1; + } + } + } + #endif + + free(state.Probs); + #ifdef _LZMA_OUT_READ + free(state.Dictionary); + #else + free(outStream); + #endif + #ifndef _LZMA_IN_CB + free(inStream); + #endif + return res; +} + +int main2(int numArgs, const char *args[], char *rs) +{ + FILE *inFile = 0; + FILE *outFile = 0; + int res; + + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n"); + if (numArgs < 2 || numArgs > 3) + { + sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); + return 1; + } + + inFile = fopen(args[1], "rb"); + if (inFile == 0) + return PrintError(rs, "Can not open input file"); + + if (numArgs > 2) + { + outFile = fopen(args[2], "wb+"); + if (outFile == 0) + return PrintError(rs, "Can not open output file"); + } + + res = main3(inFile, outFile, rs); + + if (outFile != 0) + fclose(outFile); + fclose(inFile); + return res; +} + +int main(int numArgs, const char *args[]) +{ + char rs[800] = { 0 }; + int res = main2(numArgs, args, rs); + printf(rs); + return res; +} diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTypes.h b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTypes.h new file mode 100644 index 00000000..288c5e45 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/LzmaTypes.h @@ -0,0 +1,45 @@ +/* +LzmaTypes.h + +Types for LZMA Decoder + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.40 (2006-05-01) +*/ + +#ifndef __LZMATYPES_H +#define __LZMATYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _LZMA_SYSTEM_SIZE_T */ +/* Use system's size_t. You can use it to enable 64-bit sizes supporting */ + +#ifndef _7ZIP_SIZET_DEFINED +#define _7ZIP_SIZET_DEFINED +#ifdef _LZMA_SYSTEM_SIZE_T +#include +typedef size_t SizeT; +#else +typedef UInt32 SizeT; +#endif +#endif + +#endif diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/makefile b/utils/lzma/C/7zip/Compress/LZMA_C/makefile new file mode 100644 index 00000000..7d6a93be --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/makefile @@ -0,0 +1,43 @@ +PROG = lzmaDec.exe + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS- +CFLAGS_O1 = $(CFLAGS) -O1 +CFLAGS_O2 = $(CFLAGS) -O2 + +LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CPP) $(CFLAGS_O1) $** +COMPL_O2 = $(CPP) $(CFLAGS_O2) $** +COMPL = $(CPP) $(CFLAGS_O1) $** + + +OBJS = \ + $O\LzmaTest.obj \ + $O\LzmaDecode.obj \ + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch + +$O: + if not exist "$O" mkdir "$O" + +$(PROGPATH): $O $(OBJS) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) + + +$O\LzmaTest.obj: $(*B).c + $(COMPL) +$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c + $(COMPL_O2) diff --git a/utils/lzma/C/7zip/Compress/LZMA_C/makefile.gcc b/utils/lzma/C/7zip/Compress/LZMA_C/makefile.gcc new file mode 100644 index 00000000..9b9c1a33 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/LZMA_C/makefile.gcc @@ -0,0 +1,23 @@ +PROG = lzmadec +CXX = gcc +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall -pedantic -D _LZMA_PROB32 + +OBJS = LzmaTest.o LzmaDecode.o + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaTest.o: LzmaTest.c + $(CXX) $(CFLAGS) LzmaTest.c + +LzmaDecode.o: LzmaDecode.c + $(CXX) $(CFLAGS) LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h new file mode 100644 index 00000000..bbb2ba82 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h @@ -0,0 +1,205 @@ +// Compress/RangeCoder/RangeCoder.h + +#ifndef __COMPRESS_RANGECODER_H +#define __COMPRESS_RANGECODER_H + +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); + +class CEncoder +{ + UInt32 _cacheSize; + Byte _cache; +public: + UInt64 Low; + UInt32 Range; + COutBuffer Stream; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Low = 0; + Range = 0xFFFFFFFF; + _cacheSize = 1; + _cache = 0; + } + + void FlushData() + { + // Low += 1; + for(int i = 0; i < 5; i++) + ShiftLow(); + } + + HRESULT FlushStream() { return Stream.Flush(); } + + void ReleaseStream() { Stream.ReleaseStream(); } + + void Encode(UInt32 start, UInt32 size, UInt32 total) + { + Low += start * (Range /= total); + Range *= size; + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + void ShiftLow() + { + if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) + { + Byte temp = _cache; + do + { + Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); + temp = 0xFF; + } + while(--_cacheSize != 0); + _cache = (Byte)((UInt32)Low >> 24); + } + _cacheSize++; + Low = (UInt32)Low << 8; + } + + void EncodeDirectBits(UInt32 value, int numTotalBits) + { + for (int i = numTotalBits - 1; i >= 0; i--) + { + Range >>= 1; + if (((value >> i) & 1) == 1) + Low += Range; + if (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + } + + void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + if (symbol == 0) + Range = newBound; + else + { + Low += newBound; + Range -= newBound; + } + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } +}; + +class CDecoder +{ +public: + CInBuffer Stream; + UInt32 Range; + UInt32 Code; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void Normalize() + { + while (Range < kTopValue) + { + Code = (Code << 8) | Stream.ReadByte(); + Range <<= 8; + } + } + + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Code = 0; + Range = 0xFFFFFFFF; + for(int i = 0; i < 5; i++) + Code = (Code << 8) | Stream.ReadByte(); + } + + void ReleaseStream() { Stream.ReleaseStream(); } + + UInt32 GetThreshold(UInt32 total) + { + return (Code) / ( Range /= total); + } + + void Decode(UInt32 start, UInt32 size) + { + Code -= start * Range; + Range *= size; + Normalize(); + } + + UInt32 DecodeDirectBits(int numTotalBits) + { + UInt32 range = Range; + UInt32 code = Code; + UInt32 result = 0; + for (int i = numTotalBits; i != 0; i--) + { + range >>= 1; + /* + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + */ + UInt32 t = (code - range) >> 31; + code -= range & (t - 1); + result = (result << 1) | (1 - t); + + if (range < kTopValue) + { + code = (code << 8) | Stream.ReadByte(); + range <<= 8; + } + } + Range = range; + Code = code; + return result; + } + + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + UInt32 symbol; + if (Code < newBound) + { + symbol = 0; + Range = newBound; + } + else + { + symbol = 1; + Code -= newBound; + Range -= newBound; + } + Normalize(); + return symbol; + } + + UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } +}; + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp new file mode 100644 index 00000000..8e4c4d3a --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp @@ -0,0 +1,80 @@ +// Compress/RangeCoder/RangeCoderBit.cpp + +#include "StdAfx.h" + +#include "RangeCoderBit.h" + +namespace NCompress { +namespace NRangeCoder { + +UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; +static CPriceTables g_PriceTables; + +CPriceTables::CPriceTables() { Init(); } + +void CPriceTables::Init() +{ + const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); + for(int i = kNumBits - 1; i >= 0; i--) + { + UInt32 start = 1 << (kNumBits - i - 1); + UInt32 end = 1 << (kNumBits - i); + for (UInt32 j = start; j < end; j++) + ProbPrices[j] = (i << kNumBitPriceShiftBits) + + (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); + } + + /* + // simplest: bad solution + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = kBitPrice; + */ + + /* + const double kDummyMultMid = (1.0 / kBitPrice) / 2; + const double kDummyMultMid = 0; + // float solution + double ln2 = log(double(2)); + double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits)); + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice); + */ + + /* + // experimental, slow, solution: + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + { + const int kCyclesBits = 5; + const UInt32 kCycles = (1 << kCyclesBits); + + UInt32 range = UInt32(-1); + UInt32 bitCount = 0; + for (UInt32 j = 0; j < kCycles; j++) + { + range >>= (kNumBitModelTotalBits - kNumMoveReducingBits); + range *= i; + while(range < (1 << 31)) + { + range <<= 1; + bitCount++; + } + } + bitCount <<= kNumBitPriceShiftBits; + range -= (1 << 31); + for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--) + { + range <<= 1; + if (range > (1 << 31)) + { + bitCount += (1 << k); + range -= (1 << 31); + } + } + ProbPrices[i] = (bitCount + // + (1 << (kCyclesBits - 1)) + ) >> kCyclesBits; + } + */ +} + +}} diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h new file mode 100644 index 00000000..624f887c --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h @@ -0,0 +1,120 @@ +// Compress/RangeCoder/RangeCoderBit.h + +#ifndef __COMPRESS_RANGECODER_BIT_H +#define __COMPRESS_RANGECODER_BIT_H + +#include "RangeCoder.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumBitModelTotalBits = 11; +const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); + +const int kNumMoveReducingBits = 2; + +const int kNumBitPriceShiftBits = 6; +const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; + +class CPriceTables +{ +public: + static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + static void Init(); + CPriceTables(); +}; + +template +class CBitModel +{ +public: + UInt32 Prob; + void UpdateModel(UInt32 symbol) + { + /* + Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; + Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); + */ + if (symbol == 0) + Prob += (kBitModelTotal - Prob) >> numMoveBits; + else + Prob -= (Prob) >> numMoveBits; + } +public: + void Init() { Prob = kBitModelTotal / 2; } +}; + +template +class CBitEncoder: public CBitModel +{ +public: + void Encode(CEncoder *encoder, UInt32 symbol) + { + /* + encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); + this->UpdateModel(symbol); + */ + UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (symbol == 0) + { + encoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + } + else + { + encoder->Low += newBound; + encoder->Range -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + } + if (encoder->Range < kTopValue) + { + encoder->Range <<= 8; + encoder->ShiftLow(); + } + } + UInt32 GetPrice(UInt32 symbol) const + { + return CPriceTables::ProbPrices[ + (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; + } + UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; } + UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; } +}; + + +template +class CBitDecoder: public CBitModel +{ +public: + UInt32 Decode(CDecoder *decoder) + { + UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (decoder->Code < newBound) + { + decoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 0; + } + else + { + decoder->Range -= newBound; + decoder->Code -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 1; + } + } +}; + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h new file mode 100644 index 00000000..4f0c78b4 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h @@ -0,0 +1,161 @@ +// Compress/RangeCoder/RangeCoderBitTree.h + +#ifndef __COMPRESS_RANGECODER_BIT_TREE_H +#define __COMPRESS_RANGECODER_BIT_TREE_H + +#include "RangeCoderBit.h" +#include "RangeCoderOpt.h" + +namespace NCompress { +namespace NRangeCoder { + +template +class CBitTreeEncoder +{ + CBitEncoder Models[1 << NumBitLevels]; +public: + void Init() + { + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) + Models[i].Init(); + } + void Encode(CEncoder *rangeEncoder, UInt32 symbol) + { + UInt32 modelIndex = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0 ;) + { + bitIndex--; + UInt32 bit = (symbol >> bitIndex) & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + } + }; + void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol) + { + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) + { + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; + } + } + UInt32 GetPrice(UInt32 symbol) const + { + symbol |= (1 << NumBitLevels); + UInt32 price = 0; + while (symbol != 1) + { + price += Models[symbol >> 1].GetPrice(symbol & 1); + symbol >>= 1; + } + return price; + } + UInt32 ReverseGetPrice(UInt32 symbol) const + { + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += Models[modelIndex].GetPrice(bit); + modelIndex = (modelIndex << 1) | bit; + } + return price; + } +}; + +template +class CBitTreeDecoder +{ + CBitDecoder Models[1 << NumBitLevels]; +public: + void Init() + { + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) + Models[i].Init(); + } + UInt32 Decode(CDecoder *rangeDecoder) + { + UInt32 modelIndex = 1; + RC_INIT_VAR + for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--) + { + // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); + RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex) + } + RC_FLUSH_VAR + return modelIndex - (1 << NumBitLevels); + }; + UInt32 ReverseDecode(CDecoder *rangeDecoder) + { + UInt32 modelIndex = 1; + UInt32 symbol = 0; + RC_INIT_VAR + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); + // modelIndex <<= 1; + // modelIndex += bit; + // symbol |= (bit << bitIndex); + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) + } + RC_FLUSH_VAR + return symbol; + } +}; + +template +void ReverseBitTreeEncode(CBitEncoder *Models, + CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol) +{ + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) + { + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; + } +} + +template +UInt32 ReverseBitTreeGetPrice(CBitEncoder *Models, + UInt32 NumBitLevels, UInt32 symbol) +{ + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += Models[modelIndex].GetPrice(bit); + modelIndex = (modelIndex << 1) | bit; + } + return price; +} + +template +UInt32 ReverseBitTreeDecode(CBitDecoder *Models, + CDecoder *rangeDecoder, int NumBitLevels) +{ + UInt32 modelIndex = 1; + UInt32 symbol = 0; + RC_INIT_VAR + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); + // modelIndex <<= 1; + // modelIndex += bit; + // symbol |= (bit << bitIndex); + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) + } + RC_FLUSH_VAR + return symbol; +} + +}} + +#endif diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h new file mode 100644 index 00000000..668b9a5b --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h @@ -0,0 +1,31 @@ +// Compress/RangeCoder/RangeCoderOpt.h + +#ifndef __COMPRESS_RANGECODER_OPT_H +#define __COMPRESS_RANGECODER_OPT_H + +#define RC_INIT_VAR \ + UInt32 range = rangeDecoder->Range; \ + UInt32 code = rangeDecoder->Code; + +#define RC_FLUSH_VAR \ + rangeDecoder->Range = range; \ + rangeDecoder->Code = code; + +#define RC_NORMALIZE \ + if (range < NCompress::NRangeCoder::kTopValue) \ + { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; } + +#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \ + { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \ + if (code < bound) \ + { A0; range = bound; \ + prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \ + mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \ + mi = (mi + mi) + 1; }} \ + RC_NORMALIZE + +#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;) + +#endif diff --git a/utils/lzma/C/7zip/Compress/RangeCoder/StdAfx.h b/utils/lzma/C/7zip/Compress/RangeCoder/StdAfx.h new file mode 100644 index 00000000..b637fd40 --- /dev/null +++ b/utils/lzma/C/7zip/Compress/RangeCoder/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/utils/lzma/C/7zip/ICoder.h b/utils/lzma/C/7zip/ICoder.h new file mode 100644 index 00000000..d84575dc --- /dev/null +++ b/utils/lzma/C/7zip/ICoder.h @@ -0,0 +1,163 @@ +// ICoder.h + +#ifndef __ICODER_H +#define __ICODER_H + +#include "IStream.h" + +// "23170F69-40C1-278A-0000-000400xx0000" +#define CODER_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +CODER_INTERFACE(ICompressProgressInfo, 0x04) +{ + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressCoder, 0x05) +{ + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, + const UInt64 *outSize, + ICompressProgressInfo *progress) PURE; +}; + +CODER_INTERFACE(ICompressCoder2, 0x18) +{ + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) PURE; +}; + +namespace NCoderPropID +{ + enum EEnum + { + kDictionarySize = 0x400, + kUsedMemorySize, + kOrder, + kPosStateBits = 0x440, + kLitContextBits, + kLitPosBits, + kNumFastBytes = 0x450, + kMatchFinder, + kMatchFinderCycles, + kNumPasses = 0x460, + kAlgorithm = 0x470, + kMultiThread = 0x480, + kNumThreads, + kEndMarker = 0x490 + }; +} + +CODER_INTERFACE(ICompressSetCoderProperties, 0x20) +{ + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) PURE; +}; + +/* +CODER_INTERFACE(ICompressSetCoderProperties, 0x21) +{ + STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; +}; +*/ + +CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) +{ + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) +{ + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE; +}; + +CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) +{ + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetCoderMt, 0x25) +{ + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; +}; + +CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) +{ + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetInStream, 0x31) +{ + STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; + STDMETHOD(ReleaseInStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetOutStream, 0x32) +{ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; + STDMETHOD(ReleaseOutStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetInStreamSize, 0x33) +{ + STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; +}; + +CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) +{ + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressFilter, 0x40) +{ + STDMETHOD(Init)() PURE; + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE; + // Filter return outSize (UInt32) + // if (outSize <= size): Filter have converted outSize bytes + // if (outSize > size): Filter have not converted anything. + // and it needs at least outSize bytes to convert one block + // (it's for crypto block algorithms). +}; + +CODER_INTERFACE(ICryptoProperties, 0x80) +{ + STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetPassword, 0x90) +{ + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetCRC, 0xA0) +{ + STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; +}; + +////////////////////// +// It's for DLL file +namespace NMethodPropID +{ + enum EEnum + { + kID, + kName, + kDecoder, + kEncoder, + kInStreams, + kOutStreams, + kDescription + }; +} + +#endif diff --git a/utils/lzma/C/7zip/IStream.h b/utils/lzma/C/7zip/IStream.h new file mode 100644 index 00000000..bba21a31 --- /dev/null +++ b/utils/lzma/C/7zip/IStream.h @@ -0,0 +1,62 @@ +// IStream.h + +#ifndef __ISTREAM_H +#define __ISTREAM_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +// "23170F69-40C1-278A-0000-000300xx0000" + +#define STREAM_INTERFACE_SUB(i, b, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \ +struct i: public b + +#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) + +STREAM_INTERFACE(ISequentialInStream, 0x01) +{ + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + Out: if size != 0, return_value = S_OK and (*processedSize == 0), + then there are no more bytes in stream. + if (size > 0) && there are bytes in stream, + this function must read at least 1 byte. + This function is allowed to read less than number of remaining bytes in stream. + You must call Read function in loop, if you need exact amount of data + */ +}; + +STREAM_INTERFACE(ISequentialOutStream, 0x02) +{ + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + if (size > 0) this function must write at least 1 byte. + This function is allowed to write less than "size". + You must call Write function in loop, if you need to write exact amount of data + */ +}; + +STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; +}; + +STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; + STDMETHOD(SetSize)(Int64 newSize) PURE; +}; + +STREAM_INTERFACE(IStreamGetSize, 0x06) +{ + STDMETHOD(GetSize)(UInt64 *size) PURE; +}; + +STREAM_INTERFACE(IOutStreamFlush, 0x07) +{ + STDMETHOD(Flush)() PURE; +}; + +#endif diff --git a/utils/lzma/C/Aes.c b/utils/lzma/C/Aes.c deleted file mode 100644 index 6c49dc98..00000000 --- a/utils/lzma/C/Aes.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Aes.c -- AES encryption / decryption -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Aes.h" -#include "CpuArch.h" - -static UInt32 T[256 * 4]; -static Byte Sbox[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; - -void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); - -void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); - -AES_CODE_FUNC g_AesCbc_Encode; -AES_CODE_FUNC g_AesCbc_Decode; -AES_CODE_FUNC g_AesCtr_Code; - -static UInt32 D[256 * 4]; -static Byte InvS[256]; - -static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; - -#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) - -#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) - -#define gb0(x) ( (x) & 0xFF) -#define gb1(x) (((x) >> ( 8)) & 0xFF) -#define gb2(x) (((x) >> (16)) & 0xFF) -#define gb3(x) (((x) >> (24)) & 0xFF) - -void AesGenTables(void) -{ - unsigned i; - for (i = 0; i < 256; i++) - InvS[Sbox[i]] = (Byte)i; - for (i = 0; i < 256; i++) - { - { - UInt32 a1 = Sbox[i]; - UInt32 a2 = xtime(a1); - UInt32 a3 = a2 ^ a1; - T[ i] = Ui32(a2, a1, a1, a3); - T[0x100 + i] = Ui32(a3, a2, a1, a1); - T[0x200 + i] = Ui32(a1, a3, a2, a1); - T[0x300 + i] = Ui32(a1, a1, a3, a2); - } - { - UInt32 a1 = InvS[i]; - UInt32 a2 = xtime(a1); - UInt32 a4 = xtime(a2); - UInt32 a8 = xtime(a4); - UInt32 a9 = a8 ^ a1; - UInt32 aB = a8 ^ a2 ^ a1; - UInt32 aD = a8 ^ a4 ^ a1; - UInt32 aE = a8 ^ a4 ^ a2; - D[ i] = Ui32(aE, a9, aD, aB); - D[0x100 + i] = Ui32(aB, aE, a9, aD); - D[0x200 + i] = Ui32(aD, aB, aE, a9); - D[0x300 + i] = Ui32(a9, aD, aB, aE); - } - } - g_AesCbc_Encode = AesCbc_Encode; - g_AesCbc_Decode = AesCbc_Decode; - g_AesCtr_Code = AesCtr_Code; - #ifdef MY_CPU_X86_OR_AMD64 - if (CPU_Is_Aes_Supported()) - { - g_AesCbc_Encode = AesCbc_Encode_Intel; - g_AesCbc_Decode = AesCbc_Decode_Intel; - g_AesCtr_Code = AesCtr_Code_Intel; - } - #endif -} - -#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])] -#define HT4(m, i, s, p) m[i] = \ - HT(i, 0, s) ^ \ - HT(i, 1, s) ^ \ - HT(i, 2, s) ^ \ - HT(i, 3, s) ^ w[p + i] -/* such order (2031) in HT16 is for VC6/K8 speed optimization) */ -#define HT16(m, s, p) \ - HT4(m, 2, s, p); \ - HT4(m, 0, s, p); \ - HT4(m, 3, s, p); \ - HT4(m, 1, s, p); \ - -#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] -#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; - -#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])] -#define HD4(m, i, s, p) m[i] = \ - HD(i, 0, s) ^ \ - HD(i, 1, s) ^ \ - HD(i, 2, s) ^ \ - HD(i, 3, s) ^ w[p + i]; -/* such order (0231) in HD16 is for VC6/K8 speed optimization) */ -#define HD16(m, s, p) \ - HD4(m, 0, s, p); \ - HD4(m, 2, s, p); \ - HD4(m, 3, s, p); \ - HD4(m, 1, s, p); \ - -#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])] -#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; - -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, wSize; - wSize = keySize + 28; - keySize /= 4; - w[0] = ((UInt32)keySize / 2) + 3; - w += 4; - - for (i = 0; i < keySize; i++, key += 4) - w[i] = GetUi32(key); - - for (; i < wSize; i++) - { - UInt32 t = w[i - 1]; - unsigned rem = i % keySize; - if (rem == 0) - t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); - else if (keySize > 6 && rem == 4) - t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); - w[i] = w[i - keySize] ^ t; - } -} - -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, num; - Aes_SetKey_Enc(w, key, keySize); - num = keySize + 20; - w += 8; - for (i = 0; i < num; i++) - { - UInt32 r = w[i]; - w[i] = - D[ Sbox[gb0(r)]] ^ - D[0x100 + Sbox[gb1(r)]] ^ - D[0x200 + Sbox[gb2(r)]] ^ - D[0x300 + Sbox[gb3(r)]]; - } -} - -/* Aes_Encode and Aes_Decode functions work with little-endian words. - src and dest are pointers to 4 UInt32 words. - arc and dest can point to same block */ - -static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - w += 4; - for (;;) - { - HT16(m, s, 0); - if (--numRounds2 == 0) - break; - HT16(s, m, 4); - w += 8; - } - w += 4; - FT4(0); FT4(1); FT4(2); FT4(3); -} - -static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4 + numRounds2 * 8; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - for (;;) - { - w -= 8; - HD16(m, s, 4); - if (--numRounds2 == 0) - break; - HD16(s, m, 0); - } - FD4(0); FD4(1); FD4(2); FD4(3); -} - -void AesCbc_Init(UInt32 *p, const Byte *iv) -{ - unsigned i; - for (i = 0; i < 4; i++) - p[i] = GetUi32(iv + i * 4); -} - -void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - p[0] ^= GetUi32(data); - p[1] ^= GetUi32(data + 4); - p[2] ^= GetUi32(data + 8); - p[3] ^= GetUi32(data + 12); - - Aes_Encode(p + 4, p, p); - - SetUi32(data, p[0]); - SetUi32(data + 4, p[1]); - SetUi32(data + 8, p[2]); - SetUi32(data + 12, p[3]); - } -} - -void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) -{ - UInt32 in[4], out[4]; - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - in[0] = GetUi32(data); - in[1] = GetUi32(data + 4); - in[2] = GetUi32(data + 8); - in[3] = GetUi32(data + 12); - - Aes_Decode(p + 4, out, in); - - SetUi32(data, p[0] ^ out[0]); - SetUi32(data + 4, p[1] ^ out[1]); - SetUi32(data + 8, p[2] ^ out[2]); - SetUi32(data + 12, p[3] ^ out[3]); - - p[0] = in[0]; - p[1] = in[1]; - p[2] = in[2]; - p[3] = in[3]; - } -} - -void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--) - { - UInt32 temp[4]; - Byte buf[16]; - int i; - if (++p[0] == 0) - p[1]++; - Aes_Encode(p + 4, temp, p); - SetUi32(buf, temp[0]); - SetUi32(buf + 4, temp[1]); - SetUi32(buf + 8, temp[2]); - SetUi32(buf + 12, temp[3]); - for (i = 0; i < 16; i++) - *data++ ^= buf[i]; - } -} diff --git a/utils/lzma/C/Aes.h b/utils/lzma/C/Aes.h deleted file mode 100644 index 64979b5b..00000000 --- a/utils/lzma/C/Aes.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Aes.h -- AES encryption / decryption -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __AES_H -#define __AES_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define AES_BLOCK_SIZE 16 - -/* Call AesGenTables one time before other AES functions */ -void AesGenTables(void); - -/* UInt32 pointers must be 16-byte aligned */ - -/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ -#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) - -/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ -/* keySize = 16 or 24 or 32 (bytes) */ -typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); - -/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ -void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ -/* data - 16-byte aligned pointer to data */ -/* numBlocks - the number of 16-byte blocks in data array */ -typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); -extern AES_CODE_FUNC g_AesCbc_Encode; -extern AES_CODE_FUNC g_AesCbc_Decode; -extern AES_CODE_FUNC g_AesCtr_Code; - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/AesOpt.c b/utils/lzma/C/AesOpt.c deleted file mode 100644 index 10a8fb25..00000000 --- a/utils/lzma/C/AesOpt.c +++ /dev/null @@ -1,184 +0,0 @@ -/* AesOpt.c -- Intel's AES -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#ifdef MY_CPU_X86_OR_AMD64 -#if _MSC_VER >= 1500 -#define USE_INTEL_AES -#endif -#endif - -#ifdef USE_INTEL_AES - -#include - -void MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks) -{ - __m128i m = *p; - for (; numBlocks != 0; numBlocks--, data++) - { - UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; - const __m128i *w = p + 3; - m = _mm_xor_si128(m, *data); - m = _mm_xor_si128(m, p[2]); - do - { - m = _mm_aesenc_si128(m, w[0]); - m = _mm_aesenc_si128(m, w[1]); - w += 2; - } - while (--numRounds2 != 0); - m = _mm_aesenc_si128(m, w[0]); - m = _mm_aesenclast_si128(m, w[1]); - *data = m; - } - *p = m; -} - -#define NUM_WAYS 3 - -#define AES_OP_W(op, n) { \ - const __m128i t = w[n]; \ - m0 = op(m0, t); \ - m1 = op(m1, t); \ - m2 = op(m2, t); \ - } - -#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n) -#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n) -#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n) -#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n) - -void MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks) -{ - __m128i iv = *p; - for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) - { - UInt32 numRounds2 = *(const UInt32 *)(p + 1); - const __m128i *w = p + numRounds2 * 2; - __m128i m0, m1, m2; - { - const __m128i t = w[2]; - m0 = _mm_xor_si128(t, data[0]); - m1 = _mm_xor_si128(t, data[1]); - m2 = _mm_xor_si128(t, data[2]); - } - numRounds2--; - do - { - AES_DEC(1) - AES_DEC(0) - w -= 2; - } - while (--numRounds2 != 0); - AES_DEC(1) - AES_DEC_LAST(0) - - { - __m128i t; - t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t; - t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t; - t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t; - } - } - for (; numBlocks != 0; numBlocks--, data++) - { - UInt32 numRounds2 = *(const UInt32 *)(p + 1); - const __m128i *w = p + numRounds2 * 2; - __m128i m = _mm_xor_si128(w[2], *data); - numRounds2--; - do - { - m = _mm_aesdec_si128(m, w[1]); - m = _mm_aesdec_si128(m, w[0]); - w -= 2; - } - while (--numRounds2 != 0); - m = _mm_aesdec_si128(m, w[1]); - m = _mm_aesdeclast_si128(m, w[0]); - - m = _mm_xor_si128(m, iv); - iv = *data; - *data = m; - } - *p = iv; -} - -void MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks) -{ - __m128i ctr = *p; - __m128i one; - one.m128i_u64[0] = 1; - one.m128i_u64[1] = 0; - for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) - { - UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; - const __m128i *w = p; - __m128i m0, m1, m2; - { - const __m128i t = w[2]; - ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t); - ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t); - ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t); - } - w += 3; - do - { - AES_ENC(0) - AES_ENC(1) - w += 2; - } - while (--numRounds2 != 0); - AES_ENC(0) - AES_ENC_LAST(1) - data[0] = _mm_xor_si128(data[0], m0); - data[1] = _mm_xor_si128(data[1], m1); - data[2] = _mm_xor_si128(data[2], m2); - } - for (; numBlocks != 0; numBlocks--, data++) - { - UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; - const __m128i *w = p; - __m128i m; - ctr = _mm_add_epi64(ctr, one); - m = _mm_xor_si128(ctr, p[2]); - w += 3; - do - { - m = _mm_aesenc_si128(m, w[0]); - m = _mm_aesenc_si128(m, w[1]); - w += 2; - } - while (--numRounds2 != 0); - m = _mm_aesenc_si128(m, w[0]); - m = _mm_aesenclast_si128(m, w[1]); - *data = _mm_xor_si128(*data, m); - } - *p = ctr; -} - -#else - -void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); - -void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks) -{ - AesCbc_Encode(p, data, numBlocks); -} - -void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks) -{ - AesCbc_Decode(p, data, numBlocks); -} - -void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks) -{ - AesCtr_Code(p, data, numBlocks); -} - -#endif diff --git a/utils/lzma/C/Alloc.c b/utils/lzma/C/Alloc.c deleted file mode 100644 index a9a69575..00000000 --- a/utils/lzma/C/Alloc.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Alloc.c -- Memory allocation functions -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#ifdef _WIN32 -#include -#endif -#include - -#include "Alloc.h" - -/* #define _SZ_ALLOC_DEBUG */ - -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ -#ifdef _SZ_ALLOC_DEBUG -#include -int g_allocCount = 0; -int g_allocCountMid = 0; -int g_allocCountBig = 0; -#endif - -void *MyAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - { - void *p = malloc(size); - fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); - return p; - } - #else - return malloc(size); - #endif -} - -void MyFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); - #endif - free(address); -} - -#ifdef _WIN32 - -void *MidAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); - #endif - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); -} - -void MidFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); - #endif - if (address == 0) - return; - VirtualFree(address, 0, MEM_RELEASE); -} - -#ifndef MEM_LARGE_PAGES -#undef _7ZIP_LARGE_PAGES -#endif - -#ifdef _7ZIP_LARGE_PAGES -SIZE_T g_LargePageSize = 0; -typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); -#endif - -void SetLargePageSize() -{ - #ifdef _7ZIP_LARGE_PAGES - SIZE_T size = 0; - GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) - GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); - if (largePageMinimum == 0) - return; - size = largePageMinimum(); - if (size == 0 || (size & (size - 1)) != 0) - return; - g_LargePageSize = size; - #endif -} - - -void *BigAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) - { - void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), - MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); - if (res != 0) - return res; - } - #endif - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); -} - -void BigFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); - #endif - - if (address == 0) - return; - VirtualFree(address, 0, MEM_RELEASE); -} - -#endif diff --git a/utils/lzma/C/Alloc.h b/utils/lzma/C/Alloc.h deleted file mode 100644 index b8e41436..00000000 --- a/utils/lzma/C/Alloc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Alloc.h -- Memory allocation functions -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __COMMON_ALLOC_H -#define __COMMON_ALLOC_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void *MyAlloc(size_t size); -void MyFree(void *address); - -#ifdef _WIN32 - -void SetLargePageSize(); - -void *MidAlloc(size_t size); -void MidFree(void *address); -void *BigAlloc(size_t size); -void BigFree(void *address); - -#else - -#define MidAlloc(size) MyAlloc(size) -#define MidFree(address) MyFree(address) -#define BigAlloc(size) MyAlloc(size) -#define BigFree(address) MyFree(address) - -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/utils/lzma/C/Bcj2.c b/utils/lzma/C/Bcj2.c deleted file mode 100644 index 4e81cdc2..00000000 --- a/utils/lzma/C/Bcj2.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Bcj2.c -- Converter for x86 code (BCJ2) -2008-10-04 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bcj2.h" - -#ifdef _LZMA_PROB32 -#define CProb UInt32 -#else -#define CProb UInt16 -#endif - -#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) -#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*buffer++) -#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } -#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ - { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} - -#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } - -#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; - -int Bcj2_Decode( - const Byte *buf0, SizeT size0, - const Byte *buf1, SizeT size1, - const Byte *buf2, SizeT size2, - const Byte *buf3, SizeT size3, - Byte *outBuf, SizeT outSize) -{ - CProb p[256 + 2]; - SizeT inPos = 0, outPos = 0; - - const Byte *buffer, *bufferLim; - UInt32 range, code; - Byte prevByte = 0; - - unsigned int i; - for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) - p[i] = kBitModelTotal >> 1; - - buffer = buf3; - bufferLim = buffer + size3; - RC_INIT2 - - if (outSize == 0) - return SZ_OK; - - for (;;) - { - Byte b; - CProb *prob; - UInt32 bound; - UInt32 ttt; - - SizeT limit = size0 - inPos; - if (outSize - outPos < limit) - limit = outSize - outPos; - while (limit != 0) - { - Byte b = buf0[inPos]; - outBuf[outPos++] = b; - if (IsJ(prevByte, b)) - break; - inPos++; - prevByte = b; - limit--; - } - - if (limit == 0 || outPos == outSize) - break; - - b = buf0[inPos++]; - - if (b == 0xE8) - prob = p + prevByte; - else if (b == 0xE9) - prob = p + 256; - else - prob = p + 257; - - IF_BIT_0(prob) - { - UPDATE_0(prob) - prevByte = b; - } - else - { - UInt32 dest; - const Byte *v; - UPDATE_1(prob) - if (b == 0xE8) - { - v = buf1; - if (size1 < 4) - return SZ_ERROR_DATA; - buf1 += 4; - size1 -= 4; - } - else - { - v = buf2; - if (size2 < 4) - return SZ_ERROR_DATA; - buf2 += 4; - size2 -= 4; - } - dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | - ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); - outBuf[outPos++] = (Byte)dest; - if (outPos == outSize) - break; - outBuf[outPos++] = (Byte)(dest >> 8); - if (outPos == outSize) - break; - outBuf[outPos++] = (Byte)(dest >> 16); - if (outPos == outSize) - break; - outBuf[outPos++] = prevByte = (Byte)(dest >> 24); - } - } - return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; -} diff --git a/utils/lzma/C/Bcj2.h b/utils/lzma/C/Bcj2.h deleted file mode 100644 index 1db8ea0a..00000000 --- a/utils/lzma/C/Bcj2.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Bcj2.h -- Converter for x86 code (BCJ2) -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __BCJ2_H -#define __BCJ2_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -Conditions: - outSize <= FullOutputSize, - where FullOutputSize is full size of output stream of x86_2 filter. - -If buf0 overlaps outBuf, there are two required conditions: - 1) (buf0 >= outBuf) - 2) (buf0 + size0 >= outBuf + FullOutputSize). - -Returns: - SZ_OK - SZ_ERROR_DATA - Data error -*/ - -int Bcj2_Decode( - const Byte *buf0, SizeT size0, - const Byte *buf1, SizeT size1, - const Byte *buf2, SizeT size2, - const Byte *buf3, SizeT size3, - Byte *outBuf, SizeT outSize); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Bra.c b/utils/lzma/C/Bra.c deleted file mode 100644 index cdb94569..00000000 --- a/utils/lzma/C/Bra.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Bra.c -- Converters for RISC code -2010-04-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 8; - for (i = 0; i <= size; i += 4) - { - if (data[i + 3] == 0xEB) - { - UInt32 dest; - UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); - src <<= 2; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 2; - data[i + 2] = (Byte)(dest >> 16); - data[i + 1] = (Byte)(dest >> 8); - data[i + 0] = (Byte)dest; - } - } - return i; -} - -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 4; - for (i = 0; i <= size; i += 2) - { - if ((data[i + 1] & 0xF8) == 0xF0 && - (data[i + 3] & 0xF8) == 0xF8) - { - UInt32 dest; - UInt32 src = - (((UInt32)data[i + 1] & 0x7) << 19) | - ((UInt32)data[i + 0] << 11) | - (((UInt32)data[i + 3] & 0x7) << 8) | - (data[i + 2]); - - src <<= 1; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 1; - - data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); - data[i + 0] = (Byte)(dest >> 11); - data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); - data[i + 2] = (Byte)dest; - i += 2; - } - } - return i; -} - -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) - { - UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3] & (~3)); - - UInt32 dest; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] &= 0x3; - data[i + 3] |= dest; - } - } - return i; -} - -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - UInt32 i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || - (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) - { - UInt32 src = - ((UInt32)data[i + 0] << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3]); - UInt32 dest; - - src <<= 2; - if (encoding) - dest = ip + i + src; - else - dest = src - (ip + i); - dest >>= 2; - - dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; - - data[i + 0] = (Byte)(dest >> 24); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] = (Byte)dest; - } - } - return i; -} diff --git a/utils/lzma/C/Bra.h b/utils/lzma/C/Bra.h deleted file mode 100644 index 855e37a6..00000000 --- a/utils/lzma/C/Bra.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Bra.h -- Branch converters for executables -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __BRA_H -#define __BRA_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -These functions convert relative addresses to absolute addresses -in CALL instructions to increase the compression ratio. - - In: - data - data buffer - size - size of data - ip - current virtual Instruction Pinter (IP) value - state - state variable for x86 converter - encoding - 0 (for decoding), 1 (for encoding) - - Out: - state - state variable for x86 converter - - Returns: - The number of processed bytes. If you call these functions with multiple calls, - you must start next call with first byte after block of processed bytes. - - Type Endian Alignment LookAhead - - x86 little 1 4 - ARMT little 2 2 - ARM little 4 0 - PPC big 4 0 - SPARC big 4 0 - IA64 little 16 0 - - size must be >= Alignment + LookAhead, if it's not last block. - If (size < Alignment + LookAhead), converter returns 0. - - Example: - - UInt32 ip = 0; - for () - { - ; size must be >= Alignment + LookAhead, if it's not last block - SizeT processed = Convert(data, size, ip, 1); - data += processed; - size -= processed; - ip += processed; - } -*/ - -#define x86_Convert_Init(state) { state = 0; } -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Bra86.c b/utils/lzma/C/Bra86.c deleted file mode 100644 index 6db15e7e..00000000 --- a/utils/lzma/C/Bra86.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Bra86.c -- Converter for x86 code (BCJ) -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) - -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) -{ - SizeT pos = 0; - UInt32 mask = *state & 7; - if (size < 5) - return 0; - size -= 4; - ip += 5; - - for (;;) - { - Byte *p = data + pos; - const Byte *limit = data + size; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - - { - SizeT d = (SizeT)(p - data - pos); - pos = (SizeT)(p - data); - if (p >= limit) - { - *state = (d > 2 ? 0 : mask >> (unsigned)d); - return pos; - } - if (d > 2) - mask = 0; - else - { - mask >>= (unsigned)d; - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) - { - mask = (mask >> 1) | 4; - pos++; - continue; - } - } - } - - if (Test86MSByte(p[4])) - { - UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 cur = ip + (UInt32)pos; - pos += 5; - if (encoding) - v += cur; - else - v -= cur; - if (mask != 0) - { - unsigned sh = (mask & 6) << 2; - if (Test86MSByte((Byte)(v >> sh))) - { - v ^= (((UInt32)0x100 << sh) - 1); - if (encoding) - v += cur; - else - v -= cur; - } - mask = 0; - } - p[1] = (Byte)v; - p[2] = (Byte)(v >> 8); - p[3] = (Byte)(v >> 16); - p[4] = (Byte)(0 - ((v >> 24) & 1)); - } - else - { - mask = (mask >> 1) | 4; - pos++; - } - } -} diff --git a/utils/lzma/C/BraIA64.c b/utils/lzma/C/BraIA64.c deleted file mode 100644 index fa60356b..00000000 --- a/utils/lzma/C/BraIA64.c +++ /dev/null @@ -1,69 +0,0 @@ -/* BraIA64.c -- Converter for IA-64 code -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -static const Byte kBranchTable[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 -}; - -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 16) - return 0; - size -= 16; - for (i = 0; i <= size; i += 16) - { - UInt32 instrTemplate = data[i] & 0x1F; - UInt32 mask = kBranchTable[instrTemplate]; - UInt32 bitPos = 5; - int slot; - for (slot = 0; slot < 3; slot++, bitPos += 41) - { - UInt32 bytePos, bitRes; - UInt64 instruction, instNorm; - int j; - if (((mask >> slot) & 1) == 0) - continue; - bytePos = (bitPos >> 3); - bitRes = bitPos & 0x7; - instruction = 0; - for (j = 0; j < 6; j++) - instruction += (UInt64)data[i + j + bytePos] << (8 * j); - - instNorm = instruction >> bitRes; - if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) - { - UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); - UInt32 dest; - src |= ((UInt32)(instNorm >> 36) & 1) << 20; - - src <<= 4; - - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - - dest >>= 4; - - instNorm &= ~((UInt64)(0x8FFFFF) << 13); - instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); - instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); - - instruction &= (1 << bitRes) - 1; - instruction |= (instNorm << bitRes); - for (j = 0; j < 6; j++) - data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); - } - } - } - return i; -} diff --git a/utils/lzma/C/Common/Alloc.cpp b/utils/lzma/C/Common/Alloc.cpp new file mode 100644 index 00000000..e2b8c3d2 --- /dev/null +++ b/utils/lzma/C/Common/Alloc.cpp @@ -0,0 +1,118 @@ +// Common/Alloc.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#else +#include +#endif + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); + #endif + return ::malloc(size); +} + +void MyFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d", --g_allocCount); + #endif + + ::free(address); +} + +#ifdef _WIN32 + +void *MidAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); + #endif + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void MidFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); + #endif + if (address == 0) + return; + ::VirtualFree(address, 0, MEM_RELEASE); +} + +static SIZE_T g_LargePageSize = + #ifdef _WIN64 + (1 << 21); + #else + (1 << 22); + #endif + +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); + +bool SetLargePageSize() +{ + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (largePageMinimum == 0) + return false; + SIZE_T size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return false; + g_LargePageSize = size; + return true; +} + + +void *BigAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + if (size >= (1 << 18)) + { + void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), + MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (res != 0) + return res; + } + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); + #endif + + if (address == 0) + return; + ::VirtualFree(address, 0, MEM_RELEASE); +} + +#endif diff --git a/utils/lzma/C/Common/Alloc.h b/utils/lzma/C/Common/Alloc.h new file mode 100644 index 00000000..d444f631 --- /dev/null +++ b/utils/lzma/C/Common/Alloc.h @@ -0,0 +1,29 @@ +// Common/Alloc.h + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include + +void *MyAlloc(size_t size) throw(); +void MyFree(void *address) throw(); + +#ifdef _WIN32 + +bool SetLargePageSize(); + +void *MidAlloc(size_t size) throw(); +void MidFree(void *address) throw(); +void *BigAlloc(size_t size) throw(); +void BigFree(void *address) throw(); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +#endif diff --git a/utils/lzma/C/Common/CRC.cpp b/utils/lzma/C/Common/CRC.cpp new file mode 100644 index 00000000..35e1a187 --- /dev/null +++ b/utils/lzma/C/Common/CRC.cpp @@ -0,0 +1,61 @@ +// Common/CRC.cpp + +#include "StdAfx.h" + +#include "CRC.h" + +static const UInt32 kCRCPoly = 0xEDB88320; + +UInt32 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::UpdateByte(Byte b) +{ + _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8); +} + +void CCRC::UpdateUInt16(UInt16 v) +{ + UpdateByte(Byte(v)); + UpdateByte(Byte(v >> 8)); +} + +void CCRC::UpdateUInt32(UInt32 v) +{ + for (int i = 0; i < 4; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::UpdateUInt64(UInt64 v) +{ + for (int i = 0; i < 8; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::Update(const void *data, size_t size) +{ + UInt32 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = Table[((Byte)(v)) ^ *p] ^ (v >> 8); + _value = v; +} diff --git a/utils/lzma/C/Common/CRC.h b/utils/lzma/C/Common/CRC.h new file mode 100644 index 00000000..6b4f1b79 --- /dev/null +++ b/utils/lzma/C/Common/CRC.h @@ -0,0 +1,36 @@ +// Common/CRC.h + +#ifndef __COMMON_CRC_H +#define __COMMON_CRC_H + +#include +#include "Types.h" + +class CCRC +{ + UInt32 _value; +public: + static UInt32 Table[256]; + static void InitTable(); + + CCRC(): _value(0xFFFFFFFF){}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte v); + void UpdateUInt16(UInt16 v); + void UpdateUInt32(UInt32 v); + void UpdateUInt64(UInt64 v); + void Update(const void *data, size_t size); + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } + static UInt32 CalculateDigest(const void *data, size_t size) + { + CCRC crc; + crc.Update(data, size); + return crc.GetDigest(); + } + static bool VerifyDigest(UInt32 digest, const void *data, size_t size) + { + return (CalculateDigest(data, size) == digest); + } +}; + +#endif diff --git a/utils/lzma/C/Common/C_FileIO.cpp b/utils/lzma/C/Common/C_FileIO.cpp new file mode 100644 index 00000000..7d9e00d0 --- /dev/null +++ b/utils/lzma/C/Common/C_FileIO.cpp @@ -0,0 +1,78 @@ +// Common/C_FileIO.h + +#include "C_FileIO.h" + +#include +#include + +namespace NC { +namespace NFile { +namespace NIO { + +bool CFileBase::OpenBinary(const char *name, int flags) +{ + #ifdef O_BINARY + flags |= O_BINARY; + #endif + Close(); + _handle = ::open(name, flags, 0666); + return _handle != -1; +} + +bool CFileBase::Close() +{ + if(_handle == -1) + return true; + if (close(_handle) != 0) + return false; + _handle = -1; + return true; +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + off_t curPos = Seek(0, SEEK_CUR); + off_t lengthTemp = Seek(0, SEEK_END); + Seek(curPos, SEEK_SET); + length = (UInt64)lengthTemp; + return true; +} + +off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const +{ + return ::lseek(_handle, distanceToMove, moveMethod); +} + +///////////////////////// +// CInFile + +bool CInFile::Open(const char *name) +{ + return CFileBase::OpenBinary(name, O_RDONLY); +} + +ssize_t CInFile::Read(void *data, size_t size) +{ + return read(_handle, data, size); +} + +///////////////////////// +// COutFile + +bool COutFile::Create(const char *name, bool createAlways) +{ + if (createAlways) + { + Close(); + _handle = ::creat(name, 0666); + return _handle != -1; + } + return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY); +} + +ssize_t COutFile::Write(const void *data, size_t size) +{ + return write(_handle, data, size); +} + +}}} diff --git a/utils/lzma/C/Common/C_FileIO.h b/utils/lzma/C/Common/C_FileIO.h new file mode 100644 index 00000000..2ad07167 --- /dev/null +++ b/utils/lzma/C/Common/C_FileIO.h @@ -0,0 +1,45 @@ +// Common/C_FileIO.h + +#ifndef __COMMON_C_FILEIO_H +#define __COMMON_C_FILEIO_H + +#include +#include + +#include "Types.h" +#include "MyWindows.h" + +namespace NC { +namespace NFile { +namespace NIO { + +class CFileBase +{ +protected: + int _handle; + bool OpenBinary(const char *name, int flags); +public: + CFileBase(): _handle(-1) {}; + ~CFileBase() { Close(); } + bool Close(); + bool GetLength(UInt64 &length) const; + off_t Seek(off_t distanceToMove, int moveMethod) const; +}; + +class CInFile: public CFileBase +{ +public: + bool Open(const char *name); + ssize_t Read(void *data, size_t size); +}; + +class COutFile: public CFileBase +{ +public: + bool Create(const char *name, bool createAlways); + ssize_t Write(const void *data, size_t size); +}; + +}}} + +#endif diff --git a/utils/lzma/C/Common/ComTry.h b/utils/lzma/C/Common/ComTry.h new file mode 100644 index 00000000..5153362f --- /dev/null +++ b/utils/lzma/C/Common/ComTry.h @@ -0,0 +1,17 @@ +// ComTry.h + +#ifndef __COM_TRY_H +#define __COM_TRY_H + +#include "MyWindows.h" +// #include "Exception.h" +// #include "NewHandler.h" + +#define COM_TRY_BEGIN try { +#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } + + // catch(const CNewException &) { return E_OUTOFMEMORY; }\ + // catch(const CSystemException &e) { return e.ErrorCode; }\ + // catch(...) { return E_FAIL; } + +#endif diff --git a/utils/lzma/C/Common/CommandLineParser.cpp b/utils/lzma/C/Common/CommandLineParser.cpp new file mode 100644 index 00000000..69c41841 --- /dev/null +++ b/utils/lzma/C/Common/CommandLineParser.cpp @@ -0,0 +1,232 @@ +// CommandLineParser.cpp + +#include "StdAfx.h" + +#include "CommandLineParser.h" + +namespace NCommandLineParser { + +void SplitCommandLine(const UString &src, UString &dest1, UString &dest2) +{ + dest1.Empty(); + dest2.Empty(); + bool quoteMode = false; + int i; + for (i = 0; i < src.Length(); i++) + { + wchar_t c = src[i]; + if (c == L'\"') + quoteMode = !quoteMode; + else if (c == L' ' && !quoteMode) + { + i++; + break; + } + else + dest1 += c; + } + dest2 = src.Mid(i); +} + +void SplitCommandLine(const UString &s, UStringVector &parts) +{ + UString sTemp = s; + sTemp.Trim(); + parts.Clear(); + while (true) + { + UString s1, s2; + SplitCommandLine(sTemp, s1, s2); + // s1.Trim(); + // s2.Trim(); + if (!s1.IsEmpty()) + parts.Add(s1); + if (s2.IsEmpty()) + return; + sTemp = s2; + } +} + + +static const wchar_t kSwitchID1 = '-'; +// static const wchar_t kSwitchID2 = '/'; + +static const wchar_t kSwitchMinus = '-'; +static const wchar_t *kStopSwitchParsing = L"--"; + +static bool IsItSwitchChar(wchar_t c) +{ + return (c == kSwitchID1 /*|| c == kSwitchID2 */); +} + +CParser::CParser(int numSwitches): + _numSwitches(numSwitches) +{ + _switches = new CSwitchResult[_numSwitches]; +} + +CParser::~CParser() +{ + delete []_switches; +} + +void CParser::ParseStrings(const CSwitchForm *switchForms, + const UStringVector &commandStrings) +{ + int numCommandStrings = commandStrings.Size(); + bool stopSwitch = false; + for (int i = 0; i < numCommandStrings; i++) + { + const UString &s = commandStrings[i]; + if (stopSwitch) + NonSwitchStrings.Add(s); + else + if (s == kStopSwitchParsing) + stopSwitch = true; + else + if (!ParseString(s, switchForms)) + NonSwitchStrings.Add(s); + } +} + +// if string contains switch then function updates switch structures +// out: (string is a switch) +bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) +{ + int len = s.Length(); + if (len == 0) + return false; + int pos = 0; + if (!IsItSwitchChar(s[pos])) + return false; + while(pos < len) + { + if (IsItSwitchChar(s[pos])) + pos++; + const int kNoLen = -1; + int matchedSwitchIndex = 0; // GCC Warning + int maxLen = kNoLen; + for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++) + { + int switchLen = MyStringLen(switchForms[switchIndex].IDString); + if (switchLen <= maxLen || pos + switchLen > len) + continue; + + UString temp = s + pos; + temp = temp.Left(switchLen); + if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0) + // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0) + { + matchedSwitchIndex = switchIndex; + maxLen = switchLen; + } + } + if (maxLen == kNoLen) + throw "maxLen == kNoLen"; + CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex]; + const CSwitchForm &switchForm = switchForms[matchedSwitchIndex]; + if ((!switchForm.Multi) && matchedSwitch.ThereIs) + throw "switch must be single"; + matchedSwitch.ThereIs = true; + pos += maxLen; + int tailSize = len - pos; + NSwitchType::EEnum type = switchForm.Type; + switch(type) + { + case NSwitchType::kPostMinus: + { + if (tailSize == 0) + matchedSwitch.WithMinus = false; + else + { + matchedSwitch.WithMinus = (s[pos] == kSwitchMinus); + if (matchedSwitch.WithMinus) + pos++; + } + break; + } + case NSwitchType::kPostChar: + { + if (tailSize < switchForm.MinLen) + throw "switch is not full"; + UString set = switchForm.PostCharSet; + const int kEmptyCharValue = -1; + if (tailSize == 0) + matchedSwitch.PostCharIndex = kEmptyCharValue; + else + { + int index = set.Find(s[pos]); + if (index < 0) + matchedSwitch.PostCharIndex = kEmptyCharValue; + else + { + matchedSwitch.PostCharIndex = index; + pos++; + } + } + break; + } + case NSwitchType::kLimitedPostString: + case NSwitchType::kUnLimitedPostString: + { + int minLen = switchForm.MinLen; + if (tailSize < minLen) + throw "switch is not full"; + if (type == NSwitchType::kUnLimitedPostString) + { + matchedSwitch.PostStrings.Add(s.Mid(pos)); + return true; + } + int maxLen = switchForm.MaxLen; + UString stringSwitch = s.Mid(pos, minLen); + pos += minLen; + for(int i = minLen; i < maxLen && pos < len; i++, pos++) + { + wchar_t c = s[pos]; + if (IsItSwitchChar(c)) + break; + stringSwitch += c; + } + matchedSwitch.PostStrings.Add(stringSwitch); + break; + } + case NSwitchType::kSimple: + break; + } + } + return true; +} + +const CSwitchResult& CParser::operator[](size_t index) const +{ + return _switches[index]; +} + +///////////////////////////////// +// Command parsing procedures + +int ParseCommand(int numCommandForms, const CCommandForm *commandForms, + const UString &commandString, UString &postString) +{ + for(int i = 0; i < numCommandForms; i++) + { + const UString id = commandForms[i].IDString; + if (commandForms[i].PostStringMode) + { + if(commandString.Find(id) == 0) + { + postString = commandString.Mid(id.Length()); + return i; + } + } + else + if (commandString == id) + { + postString.Empty(); + return i; + } + } + return -1; +} + +} diff --git a/utils/lzma/C/Common/CommandLineParser.h b/utils/lzma/C/Common/CommandLineParser.h new file mode 100644 index 00000000..af698db8 --- /dev/null +++ b/utils/lzma/C/Common/CommandLineParser.h @@ -0,0 +1,72 @@ +// Common/CommandLineParser.h + +#ifndef __COMMON_COMMANDLINEPARSER_H +#define __COMMON_COMMANDLINEPARSER_H + +#include "Common/String.h" + +namespace NCommandLineParser { + +void SplitCommandLine(const UString &src, UString &dest1, UString &dest2); +void SplitCommandLine(const UString &s, UStringVector &parts); + +namespace NSwitchType { + enum EEnum + { + kSimple, + kPostMinus, + kLimitedPostString, + kUnLimitedPostString, + kPostChar + }; +} + +struct CSwitchForm +{ + const wchar_t *IDString; + NSwitchType::EEnum Type; + bool Multi; + int MinLen; + int MaxLen; + const wchar_t *PostCharSet; +}; + +struct CSwitchResult +{ + bool ThereIs; + bool WithMinus; + UStringVector PostStrings; + int PostCharIndex; + CSwitchResult(): ThereIs(false) {}; +}; + +class CParser +{ + int _numSwitches; + CSwitchResult *_switches; + bool ParseString(const UString &s, const CSwitchForm *switchForms); +public: + UStringVector NonSwitchStrings; + CParser(int numSwitches); + ~CParser(); + void ParseStrings(const CSwitchForm *switchForms, + const UStringVector &commandStrings); + const CSwitchResult& operator[](size_t index) const; +}; + +///////////////////////////////// +// Command parsing procedures + +struct CCommandForm +{ + wchar_t *IDString; + bool PostStringMode; +}; + +// Returns: Index of form and postString; -1, if there is no match +int ParseCommand(int numCommandForms, const CCommandForm *commandForms, + const UString &commandString, UString &postString); + +} + +#endif diff --git a/utils/lzma/C/Common/Defs.h b/utils/lzma/C/Common/Defs.h new file mode 100644 index 00000000..dad3ae8f --- /dev/null +++ b/utils/lzma/C/Common/Defs.h @@ -0,0 +1,20 @@ +// Common/Defs.h + +#ifndef __COMMON_DEFS_H +#define __COMMON_DEFS_H + +template inline T MyMin(T a, T b) + { return a < b ? a : b; } +template inline T MyMax(T a, T b) + { return a > b ? a : b; } + +template inline int MyCompare(T a, T b) + { return a < b ? -1 : (a == b ? 0 : 1); } + +inline int BoolToInt(bool value) + { return (value ? 1: 0); } + +inline bool IntToBool(int value) + { return (value != 0); } + +#endif diff --git a/utils/lzma/C/Common/MyCom.h b/utils/lzma/C/Common/MyCom.h new file mode 100644 index 00000000..e9034930 --- /dev/null +++ b/utils/lzma/C/Common/MyCom.h @@ -0,0 +1,203 @@ +// MyCom.h + +#ifndef __MYCOM_H +#define __MYCOM_H + +#include "MyWindows.h" + +#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } + +template +class CMyComPtr +{ + T* _p; +public: + // typedef T _PtrClass; + CMyComPtr() { _p = NULL;} + CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr& lp) + { + if ((_p = lp._p) != NULL) + _p->AddRef(); + } + ~CMyComPtr() { if (_p) _p->Release(); } + void Release() { if (_p) { _p->Release(); _p = NULL; } } + operator T*() const { return (T*)_p; } + // T& operator*() const { return *_p; } + T** operator&() { return &_p; } + T* operator->() const { return _p; } + T* operator=(T* p) + { + if (p != 0) + p->AddRef(); + if (_p) + _p->Release(); + _p = p; + return p; + } + T* operator=(const CMyComPtr& lp) { return (*this = lp._p); } + bool operator!() const { return (_p == NULL); } + // bool operator==(T* pT) const { return _p == pT; } + // Compare two objects for equivalence + void Attach(T* p2) + { + Release(); + _p = p2; + } + T* Detach() + { + T* pt = _p; + _p = NULL; + return pt; + } + #ifdef _WIN32 + HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); + } + #endif + /* + HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + ATLASSERT(_p == NULL); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); + return hr; + } + */ + template + HRESULT QueryInterface(REFGUID iid, Q** pp) const + { + return _p->QueryInterface(iid, (void**)pp); + } +}; + +////////////////////////////////////////////////////////// + +class CMyComBSTR +{ +public: + BSTR m_str; + CMyComBSTR() { m_str = NULL; } + CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); } + // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } + // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } + CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } + /* + CMyComBSTR(REFGUID src) + { + LPOLESTR szGuid; + StringFromCLSID(src, &szGuid); + m_str = ::SysAllocString(szGuid); + CoTaskMemFree(szGuid); + } + */ + ~CMyComBSTR() { ::SysFreeString(m_str); } + CMyComBSTR& operator=(const CMyComBSTR& src) + { + if (m_str != src.m_str) + { + if (m_str) + ::SysFreeString(m_str); + m_str = src.MyCopy(); + } + return *this; + } + CMyComBSTR& operator=(LPCOLESTR pSrc) + { + ::SysFreeString(m_str); + m_str = ::SysAllocString(pSrc); + return *this; + } + unsigned int Length() const { return ::SysStringLen(m_str); } + operator BSTR() const { return m_str; } + BSTR* operator&() { return &m_str; } + BSTR MyCopy() const + { + int byteLen = ::SysStringByteLen(m_str); + BSTR res = ::SysAllocStringByteLen(NULL, byteLen); + memmove(res, m_str, byteLen); + return res; + } + void Attach(BSTR src) { m_str = src; } + BSTR Detach() + { + BSTR s = m_str; + m_str = NULL; + return s; + } + void Empty() + { + ::SysFreeString(m_str); + m_str = NULL; + } + bool operator!() const { return (m_str == NULL); } +}; + + +////////////////////////////////////////////////////////// + +class CMyUnknownImp +{ +public: + ULONG __m_RefCount; + CMyUnknownImp(): __m_RefCount(0) {} +}; + +#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ + (REFGUID iid, void **outObject) { + +#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ + { *outObject = (void *)(i *)this; AddRef(); return S_OK; } + +#define MY_QUERYINTERFACE_END return E_NOINTERFACE; } + +#define MY_ADDREF_RELEASE \ +STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ +STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ + return __m_RefCount; delete this; return 0; } + +#define MY_UNKNOWN_IMP_SPEC(i) \ + MY_QUERYINTERFACE_BEGIN \ + i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + + +#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + +#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + ) + +#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + ) + +#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + +#endif diff --git a/utils/lzma/C/Common/MyGuidDef.h b/utils/lzma/C/Common/MyGuidDef.h new file mode 100644 index 00000000..2c954f81 --- /dev/null +++ b/utils/lzma/C/Common/MyGuidDef.h @@ -0,0 +1,54 @@ +// Common/MyGuidDef.h + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +#include "Types.h" + +typedef struct { + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + unsigned char Data4[8]; +} GUID; + +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * +#endif + +#define REFCLSID REFGUID +#define REFIID REFGUID + +#ifdef __cplusplus +inline bool operator==(REFGUID g1, REFGUID g2) +{ + for (int i = 0; i < (int)sizeof(g1); i++) + if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) + return false; + return true; +} +inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } +#endif + +#ifdef __cplusplus + #define MY_EXTERN_C extern "C" +#else + #define MY_EXTERN_C extern +#endif + +#endif // GUID_DEFINED + + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name +#endif diff --git a/utils/lzma/C/Common/MyInitGuid.h b/utils/lzma/C/Common/MyInitGuid.h new file mode 100644 index 00000000..5bdfeed5 --- /dev/null +++ b/utils/lzma/C/Common/MyInitGuid.h @@ -0,0 +1,13 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MYINITGUID_H +#define __COMMON_MYINITGUID_H + +#ifdef _WIN32 +#include +#else +#define INITGUID +#include "MyGuidDef.h" +#endif + +#endif diff --git a/utils/lzma/C/Common/MyUnknown.h b/utils/lzma/C/Common/MyUnknown.h new file mode 100644 index 00000000..d28d8542 --- /dev/null +++ b/utils/lzma/C/Common/MyUnknown.h @@ -0,0 +1,24 @@ +// MyUnknown.h + +#ifndef __MYUNKNOWN_H +#define __MYUNKNOWN_H + +#ifdef _WIN32 + +#ifdef _WIN32_WCE +#if (_WIN32_WCE > 300) +#include +#else +#define MIDL_INTERFACE(x) struct +#endif +#else +#include +#endif + +#include + +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/utils/lzma/C/Common/MyWindows.h b/utils/lzma/C/Common/MyWindows.h new file mode 100644 index 00000000..e1ea41fb --- /dev/null +++ b/utils/lzma/C/Common/MyWindows.h @@ -0,0 +1,200 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#include // for wchar_t +#include + +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; + +#undef BYTE +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; + +#undef WORD +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; +typedef CHAR TCHAR; +typedef const TCHAR *LPCTSTR; +typedef wchar_t WCHAR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +}FILETIME; + +#define HRESULT LONG +#define FAILED(Status) ((HRESULT)(Status)<0) +typedef ULONG PROPID; +typedef LONG SCODE; + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOTIMPL ((HRESULT)0x80004001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#else +#define STDMETHODCALLTYPE +#endif + +#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + +#define PURE = 0 + +#define MIDL_INTERFACE(x) struct + +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; +}; + +typedef IUnknown *LPUNKNOWN; + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +MY_EXTERN_C void SysFreeString(BSTR bstr); +MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); +MY_EXTERN_C UINT SysStringLen(BSTR bstr); + +MY_EXTERN_C DWORD GetLastError(); +MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); +MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +#define CP_ACP 0 +#define CP_OEMCP 1 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +#endif +#endif diff --git a/utils/lzma/C/Common/NewHandler.cpp b/utils/lzma/C/Common/NewHandler.cpp new file mode 100644 index 00000000..094eb642 --- /dev/null +++ b/utils/lzma/C/Common/NewHandler.cpp @@ -0,0 +1,116 @@ +// NewHandler.cpp + +#include "StdAfx.h" + +#include + +#include "NewHandler.h" + +// #define DEBUG_MEMORY_LEAK + +#ifndef DEBUG_MEMORY_LEAK + +#ifdef _WIN32 +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + void *p = ::malloc(size); + if (p == 0) + throw CNewException(); + return p; +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() +{ + /* + if (p == 0) + return; + ::HeapFree(::GetProcessHeap(), 0, p); + */ + ::free(p); +} +#endif + +#else + +#pragma init_seg(lib) +const int kDebugSize = 1000000; +static void *a[kDebugSize]; +static int index = 0; + +static int numAllocs = 0; +void * __cdecl operator new(size_t size) +{ + numAllocs++; + void *p = HeapAlloc(GetProcessHeap(), 0, size); + if (index == 40) + { + int t = 1; + } + if (index < kDebugSize) + { + a[index] = p; + index++; + } + if (p == 0) + throw CNewException(); + printf("Alloc %6d, size = %8d\n", numAllocs, size); + return p; +} + +class CC +{ +public: + CC() + { + for (int i = 0; i < kDebugSize; i++) + a[i] = 0; + } + ~CC() + { + for (int i = 0; i < kDebugSize; i++) + if (a[i] != 0) + return; + } +} g_CC; + + +void __cdecl operator delete(void *p) +{ + if (p == 0) + return; + /* + for (int i = 0; i < index; i++) + if (a[i] == p) + a[i] = 0; + */ + HeapFree(GetProcessHeap(), 0, p); + numAllocs--; + printf("Free %d\n", numAllocs); +} + +#endif + +/* +int MemErrorVC(size_t) +{ + throw CNewException(); + // return 1; +} +CNewHandlerSetter::CNewHandlerSetter() +{ + // MemErrorOldVCFunction = _set_new_handler(MemErrorVC); +} +CNewHandlerSetter::~CNewHandlerSetter() +{ + // _set_new_handler(MemErrorOldVCFunction); +} +*/ diff --git a/utils/lzma/C/Common/NewHandler.h b/utils/lzma/C/Common/NewHandler.h new file mode 100644 index 00000000..0619fc69 --- /dev/null +++ b/utils/lzma/C/Common/NewHandler.h @@ -0,0 +1,16 @@ +// Common/NewHandler.h + +#ifndef __COMMON_NEWHANDLER_H +#define __COMMON_NEWHANDLER_H + +class CNewException {}; + +#ifdef _WIN32 +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); +#endif + +#endif diff --git a/utils/lzma/C/Common/StdAfx.h b/utils/lzma/C/Common/StdAfx.h new file mode 100644 index 00000000..681ee935 --- /dev/null +++ b/utils/lzma/C/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +// #include "MyWindows.h" +#include "NewHandler.h" + +#endif diff --git a/utils/lzma/C/Common/String.cpp b/utils/lzma/C/Common/String.cpp new file mode 100644 index 00000000..7921fe41 --- /dev/null +++ b/utils/lzma/C/Common/String.cpp @@ -0,0 +1,198 @@ +// Common/String.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "StringConvert.h" +#else +#include +#endif + +#include "Common/String.h" + + +#ifdef _WIN32 + +#ifndef _UNICODE + +wchar_t MyCharUpper(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharUpperW((LPWSTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 0; + ::CharUpperA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +wchar_t MyCharLower(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharLowerW((LPWSTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 0; + ::CharLowerA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +wchar_t * MyStringUpper(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharUpperW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeUpper(); + return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); +} + +wchar_t * MyStringLower(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharLowerW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeLower(); + return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); +} + +#endif + +/* +inline int ConvertCompareResult(int r) { return r - 2; } + +int MyStringCollate(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollate(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} + +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); +} + +int MyStringCollateNoCase(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); +} +#endif + +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} +*/ + +#else + +wchar_t MyCharUpper(wchar_t c) +{ + return toupper(c); +} + +/* +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + + if (u1 < u2) return -1; + if (u1 > u2) return 1; + if (u1 == 0) return 0; + } +} +*/ + +#endif + +int MyStringCompare(const char *s1, const char *s2) +{ + while (true) + { + unsigned char c1 = (unsigned char)*s1++; + unsigned char c2 = (unsigned char)*s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2) +{ + return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); +} +#endif diff --git a/utils/lzma/C/Common/String.h b/utils/lzma/C/Common/String.h new file mode 100644 index 00000000..c4277c1c --- /dev/null +++ b/utils/lzma/C/Common/String.h @@ -0,0 +1,631 @@ +// Common/String.h + +#ifndef __COMMON_STRING_H +#define __COMMON_STRING_H + +#include +// #include + +#include "Vector.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#endif + +static const char *kTrimDefaultCharSet = " \n\t"; + +template +inline int MyStringLen(const T *s) +{ + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +template +inline T * MyStringCopy(T *dest, const T *src) +{ + T *destStart = dest; + while((*dest++ = *src++) != 0); + return destStart; +} + +inline wchar_t* MyStringGetNextCharPointer(wchar_t *p) + { return (p + 1); } +inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p) + { return (p + 1); } +inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p) + { return (p - 1); } +inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p) + { return (p - 1); } + +#ifdef _WIN32 + +inline char* MyStringGetNextCharPointer(char *p) + { return CharNextA(p); } +inline const char* MyStringGetNextCharPointer(const char *p) + { return CharNextA(p); } + +inline char* MyStringGetPrevCharPointer(char *base, char *p) + { return CharPrevA(base, p); } +inline const char* MyStringGetPrevCharPointer(const char *base, const char *p) + { return CharPrevA(base, p); } + +inline char MyCharUpper(char c) + { return (char)(unsigned int)CharUpperA((LPSTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharUpper(wchar_t c) + { return (wchar_t)CharUpperW((LPWSTR)c); } +#else +wchar_t MyCharUpper(wchar_t c); +#endif + +inline char MyCharLower(char c) + { return (char)(unsigned int)CharLowerA((LPSTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharLower(wchar_t c) + { return (wchar_t)CharLowerW((LPWSTR)c); } +#else +wchar_t MyCharLower(wchar_t c); +#endif + +inline char * MyStringUpper(char *s) { return CharUpperA(s); } +#ifdef _UNICODE +inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } +#else +wchar_t * MyStringUpper(wchar_t *s); +#endif + +inline char * MyStringLower(char *s) { return CharLowerA(s); } +#ifdef _UNICODE +inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } +#else +wchar_t * MyStringLower(wchar_t *s); +#endif + +#else // Standard-C +wchar_t MyCharUpper(wchar_t c); +#endif + +////////////////////////////////////// +// Compare + +/* +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2); +int MyStringCollateNoCase(const char *s1, const char *s2); +#endif +int MyStringCollate(const wchar_t *s1, const wchar_t *s2); +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2); +*/ + +int MyStringCompare(const char *s1, const char *s2); +int MyStringCompare(const wchar_t *s1, const wchar_t *s2); + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2); +#endif + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2); + +template +class CStringBase +{ + void TrimLeftWithCharSet(const CStringBase &charSet) + { + const T *p = _chars; + while (charSet.Find(*p) >= 0 && (*p != 0)) + p = GetNextCharPointer(p); + Delete(0, (int)(p - _chars)); + } + void TrimRightWithCharSet(const CStringBase &charSet) + { + const T *p = _chars; + const T *pLast = NULL; + while (*p != 0) + { + if (charSet.Find(*p) >= 0) + { + if (pLast == NULL) + pLast = p; + } + else + pLast = NULL; + p = GetNextCharPointer(p); + } + if(pLast != NULL) + { + int i = (int)(pLast - _chars); + Delete(i, _length - i); + } + + } + void MoveItems(int destIndex, int srcIndex) + { + memmove(_chars + destIndex, _chars + srcIndex, + sizeof(T) * (_length - srcIndex + 1)); + } + + void InsertSpace(int &index, int size) + { + CorrectIndex(index); + GrowLength(size); + MoveItems(index + size, index); + } + + static T *GetNextCharPointer(T *p) + { return MyStringGetNextCharPointer(p); } + static const T *GetNextCharPointer(const T *p) + { return MyStringGetNextCharPointer(p); } + static T *GetPrevCharPointer(T *base, T *p) + { return MyStringGetPrevCharPointer(base, p); } + static const T *GetPrevCharPointer(const T *base, const T *p) + { return MyStringGetPrevCharPointer(base, p); } +protected: + T *_chars; + int _length; + int _capacity; + + void SetCapacity(int newCapacity) + { + int realCapacity = newCapacity + 1; + if(realCapacity == _capacity) + return; + /* + const int kMaxStringSize = 0x20000000; + #ifndef _WIN32_WCE + if(newCapacity > kMaxStringSize || newCapacity < _length) + throw 1052337; + #endif + */ + T *newBuffer = new T[realCapacity]; + if(_capacity > 0) + { + for (int i = 0; i < (_length + 1); i++) + newBuffer[i] = _chars[i]; + delete []_chars; + _chars = newBuffer; + } + else + { + _chars = newBuffer; + _chars[0] = 0; + } + _capacity = realCapacity; + } + + void GrowLength(int n) + { + int freeSize = _capacity - _length - 1; + if (n <= freeSize) + return; + int delta; + if (_capacity > 64) + delta = _capacity / 2; + else if (_capacity > 8) + delta = 16; + else + delta = 4; + if (freeSize + delta < n) + delta = n - freeSize; + SetCapacity(_capacity + delta); + } + + void CorrectIndex(int &index) const + { + if (index > _length) + index = _length; + } + +public: + CStringBase(): _chars(0), _length(0), _capacity(0) + { SetCapacity(16 - 1); } + CStringBase(T c): _chars(0), _length(0), _capacity(0) + { + SetCapacity(1); + _chars[0] = c; + _chars[1] = 0; + _length = 1; + } + CStringBase(const T *chars): _chars(0), _length(0), _capacity(0) + { + int length = MyStringLen(chars); + SetCapacity(length); + MyStringCopy(_chars, chars); // can be optimized by memove() + _length = length; + } + CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0) + { + SetCapacity(s._length); + MyStringCopy(_chars, s._chars); + _length = s._length; + } + ~CStringBase() { delete []_chars; } + + operator const T*() const { return _chars;} + + // The minimum size of the character buffer in characters. + // This value does not include space for a null terminator. + T* GetBuffer(int minBufLength) + { + if(minBufLength >= _capacity) + SetCapacity(minBufLength + 1); + return _chars; + } + void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } + void ReleaseBuffer(int newLength) + { + /* + #ifndef _WIN32_WCE + if(newLength >= _capacity) + throw 282217; + #endif + */ + _chars[newLength] = 0; + _length = newLength; + } + + CStringBase& operator=(T c) + { + Empty(); + SetCapacity(1); + _chars[0] = c; + _chars[1] = 0; + _length = 1; + return *this; + } + CStringBase& operator=(const T *chars) + { + Empty(); + int length = MyStringLen(chars); + SetCapacity(length); + MyStringCopy(_chars, chars); + _length = length; + return *this; + } + CStringBase& operator=(const CStringBase& s) + { + if(&s == this) + return *this; + Empty(); + SetCapacity(s._length); + MyStringCopy(_chars, s._chars); + _length = s._length; + return *this; + } + + CStringBase& operator+=(T c) + { + GrowLength(1); + _chars[_length] = c; + _chars[++_length] = 0; + return *this; + } + CStringBase& operator+=(const T *s) + { + int len = MyStringLen(s); + GrowLength(len); + MyStringCopy(_chars + _length, s); + _length += len; + return *this; + } + CStringBase& operator+=(const CStringBase &s) + { + GrowLength(s._length); + MyStringCopy(_chars + _length, s._chars); + _length += s._length; + return *this; + } + void Empty() + { + _length = 0; + _chars[0] = 0; + } + int Length() const { return _length; } + bool IsEmpty() const { return (_length == 0); } + + CStringBase Mid(int startIndex) const + { return Mid(startIndex, _length - startIndex); } + CStringBase Mid(int startIndex, int count ) const + { + if (startIndex + count > _length) + count = _length - startIndex; + + if (startIndex == 0 && startIndex + count == _length) + return *this; + + CStringBase result; + result.SetCapacity(count); + // MyStringNCopy(result._chars, _chars + startIndex, count); + for (int i = 0; i < count; i++) + result._chars[i] = _chars[startIndex + i]; + result._chars[count] = 0; + result._length = count; + return result; + } + CStringBase Left(int count) const + { return Mid(0, count); } + CStringBase Right(int count) const + { + if (count > _length) + count = _length; + return Mid(_length - count, count); + } + + void MakeUpper() + { MyStringUpper(_chars); } + void MakeLower() + { MyStringLower(_chars); } + + int Compare(const CStringBase& s) const + { return MyStringCompare(_chars, s._chars); } + + int CompareNoCase(const CStringBase& s) const + { return MyStringCompareNoCase(_chars, s._chars); } + /* + int Collate(const CStringBase& s) const + { return MyStringCollate(_chars, s._chars); } + int CollateNoCase(const CStringBase& s) const + { return MyStringCollateNoCase(_chars, s._chars); } + */ + + int Find(T c) const { return Find(c, 0); } + int Find(T c, int startIndex) const + { + T *p = _chars + startIndex; + while (true) + { + if (*p == c) + return (int)(p - _chars); + if (*p == 0) + return -1; + p = GetNextCharPointer(p); + } + } + int Find(const CStringBase &s) const { return Find(s, 0); } + int Find(const CStringBase &s, int startIndex) const + { + if (s.IsEmpty()) + return startIndex; + for (; startIndex < _length; startIndex++) + { + int j; + for (j = 0; j < s._length && startIndex + j < _length; j++) + if (_chars[startIndex+j] != s._chars[j]) + break; + if (j == s._length) + return startIndex; + } + return -1; + } + int ReverseFind(T c) const + { + if (_length == 0) + return -1; + T *p = _chars + _length - 1; + while (true) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p = GetPrevCharPointer(_chars, p); + } + } + int FindOneOf(const CStringBase &s) const + { + for(int i = 0; i < _length; i++) + if (s.Find(_chars[i]) >= 0) + return i; + return -1; + } + + void TrimLeft(T c) + { + const T *p = _chars; + while (c == *p) + p = GetNextCharPointer(p); + Delete(0, p - _chars); + } + private: + CStringBase GetTrimDefaultCharSet() + { + CStringBase charSet; + for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) / + sizeof(kTrimDefaultCharSet[0])); i++) + charSet += (T)kTrimDefaultCharSet[i]; + return charSet; + } + public: + + void TrimLeft() + { + TrimLeftWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight() + { + TrimRightWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight(T c) + { + const T *p = _chars; + const T *pLast = NULL; + while (*p != 0) + { + if (*p == c) + { + if (pLast == NULL) + pLast = p; + } + else + pLast = NULL; + p = GetNextCharPointer(p); + } + if(pLast != NULL) + { + int i = pLast - _chars; + Delete(i, _length - i); + } + } + void Trim() + { + TrimRight(); + TrimLeft(); + } + + int Insert(int index, T c) + { + InsertSpace(index, 1); + _chars[index] = c; + _length++; + return _length; + } + int Insert(int index, const CStringBase &s) + { + CorrectIndex(index); + if (s.IsEmpty()) + return _length; + int numInsertChars = s.Length(); + InsertSpace(index, numInsertChars); + for(int i = 0; i < numInsertChars; i++) + _chars[index + i] = s[i]; + _length += numInsertChars; + return _length; + } + + // !!!!!!!!!!!!!!! test it if newChar = '\0' + int Replace(T oldChar, T newChar) + { + if (oldChar == newChar) + return 0; + int number = 0; + int pos = 0; + while (pos < Length()) + { + pos = Find(oldChar, pos); + if (pos < 0) + break; + _chars[pos] = newChar; + pos++; + number++; + } + return number; + } + int Replace(const CStringBase &oldString, const CStringBase &newString) + { + if (oldString.IsEmpty()) + return 0; + if (oldString == newString) + return 0; + int oldStringLength = oldString.Length(); + int newStringLength = newString.Length(); + int number = 0; + int pos = 0; + while (pos < _length) + { + pos = Find(oldString, pos); + if (pos < 0) + break; + Delete(pos, oldStringLength); + Insert(pos, newString); + pos += newStringLength; + number++; + } + return number; + } + int Delete(int index, int count = 1 ) + { + if (index + count > _length) + count = _length - index; + if (count > 0) + { + MoveItems(index, index + count); + _length -= count; + } + return _length; + } +}; + +template +CStringBase operator+(const CStringBase& s1, const CStringBase& s2) +{ + CStringBase result(s1); + result += s2; + return result; +} + +template +CStringBase operator+(const CStringBase& s, T c) +{ + CStringBase result(s); + result += c; + return result; +} + +template +CStringBase operator+(T c, const CStringBase& s) +{ + CStringBase result(c); + result += s; + return result; +} + +template +CStringBase operator+(const CStringBase& s, const T * chars) +{ + CStringBase result(s); + result += chars; + return result; +} + +template +CStringBase operator+(const T * chars, const CStringBase& s) +{ + CStringBase result(chars); + result += s; + return result; +} + +template +bool operator==(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator<(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) < 0); } + +template +bool operator==(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) == 0); } + +template +bool operator==(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator!=(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) != 0); } + +template +bool operator!=(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) != 0); } + +template +bool operator!=(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) != 0); } + +typedef CStringBase AString; +typedef CStringBase UString; + +typedef CObjectVector AStringVector; +typedef CObjectVector UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector CSysStringVector; + +#endif diff --git a/utils/lzma/C/Common/StringConvert.cpp b/utils/lzma/C/Common/StringConvert.cpp new file mode 100644 index 00000000..d6d05d6c --- /dev/null +++ b/utils/lzma/C/Common/StringConvert.cpp @@ -0,0 +1,93 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef _WIN32 +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + if(!srcString.IsEmpty()) + { + int numChars = MultiByteToWideChar(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(srcString.Length()), + srcString.Length() + 1); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282228; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 2; + int numChars = WideCharToMultiByte(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(numRequiredBytes), + numRequiredBytes + 1, NULL, NULL); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282229; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString) +{ + AString result; + CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); + result.ReleaseBuffer(); + return result; +} +#endif + +#else + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += char(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 6 + 1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +#endif + diff --git a/utils/lzma/C/Common/StringConvert.h b/utils/lzma/C/Common/StringConvert.h new file mode 100644 index 00000000..648ca028 --- /dev/null +++ b/utils/lzma/C/Common/StringConvert.h @@ -0,0 +1,71 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRINGCONVERT_H +#define __COMMON_STRINGCONVERT_H + +#include "MyWindows.h" +#include "Common/String.h" +#include "Types.h" + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); + +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString) + { return unicodeString; } +inline UString GetUnicodeString(const AString &ansiString) + { return MultiByteToUnicodeString(ansiString); } +inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage); } +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString, UINT) + { return unicodeString; } + +inline const char* GetAnsiString(const char* ansiString) + { return ansiString; } +inline const AString& GetAnsiString(const AString &ansiString) + { return ansiString; } +inline AString GetAnsiString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + +inline const char* GetOemString(const char* oemString) + { return oemString; } +inline const AString& GetOemString(const AString &oemString) + { return oemString; } +inline AString GetOemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } + + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t* unicodeString) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString) + { return unicodeString;} + inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString, UINT codePage) + { return unicodeString;} + inline UString GetSystemString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage);} + inline UString GetSystemString(const AString &multiByteString) + { return MultiByteToUnicodeString(multiByteString);} +#else + inline const char* GetSystemString(const char *ansiString) + { return ansiString; } + inline const AString& GetSystemString(const AString &multiByteString, UINT) + { return multiByteString; } + inline const char * GetSystemString(const char *multiByteString, UINT) + { return multiByteString; } + inline AString GetSystemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + inline AString GetSystemString(const UString &unicodeString, UINT codePage) + { return UnicodeStringToMultiByte(unicodeString, codePage); } +#endif + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString); +#endif + +#endif diff --git a/utils/lzma/C/Common/StringToInt.cpp b/utils/lzma/C/Common/StringToInt.cpp new file mode 100644 index 00000000..1fa8ef21 --- /dev/null +++ b/utils/lzma/C/Common/StringToInt.cpp @@ -0,0 +1,68 @@ +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include "StringToInt.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + while(true) + { + char c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + while(true) + { + char c = *s; + if (c < '0' || c > '7') + { + if (end != NULL) + *end = s; + return result; + } + result <<= 3; + result += (c - '0'); + s++; + } +} + + +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) +{ + UInt64 result = 0; + while(true) + { + wchar_t c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + + +Int64 ConvertStringToInt64(const char *s, const char **end) +{ + if (*s == '-') + return -(Int64)ConvertStringToUInt64(s + 1, end); + return ConvertStringToUInt64(s, end); +} diff --git a/utils/lzma/C/Common/StringToInt.h b/utils/lzma/C/Common/StringToInt.h new file mode 100644 index 00000000..bb971f62 --- /dev/null +++ b/utils/lzma/C/Common/StringToInt.h @@ -0,0 +1,17 @@ +// Common/StringToInt.h + +#ifndef __COMMON_STRINGTOINT_H +#define __COMMON_STRINGTOINT_H + +#include +#include "Types.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end); +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); + +Int64 ConvertStringToInt64(const char *s, const char **end); + +#endif + + diff --git a/utils/lzma/C/Common/Types.h b/utils/lzma/C/Common/Types.h new file mode 100644 index 00000000..b5befd3b --- /dev/null +++ b/utils/lzma/C/Common/Types.h @@ -0,0 +1,66 @@ +// Common/Types.h + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +#ifdef _MSC_VER +#pragma warning(disable : 4127) // warning C4127: conditional expression is constant +#pragma warning(disable : 4706) // warning C4706: assignment within conditional expression +#pragma warning(disable : 4100) // warning C4100: unreferenced formal parameter +//#pragma warning(disable : 4312) // warning C4312: conversion from 'unsigned int' to 'LPSTR' of greater size +#pragma warning(disable : 4244) // warning C4244: 'initializing' : conversion from '__w64 int' to 'UInt32', possible loss of data +#pragma warning(disable : 4267) // warning C4267: 'conversion from 'size_t' to 'UInt32', possible loss of data +#endif + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_INT16_DEFINED +#define _7ZIP_INT16_DEFINED +typedef short Int16; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_INT32_DEFINED +#define _7ZIP_INT32_DEFINED +typedef int Int32; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +typedef unsigned int UInt32; +#endif + +#ifdef _MSC_VER + +#ifndef _7ZIP_INT64_DEFINED +#define _7ZIP_INT64_DEFINED +typedef __int64 Int64; +#endif + +#ifndef _7ZIP_UINT64_DEFINED +#define _7ZIP_UINT64_DEFINED +typedef unsigned __int64 UInt64; +#endif + +#else + +#ifndef _7ZIP_INT64_DEFINED +#define _7ZIP_INT64_DEFINED +typedef long long int Int64; +#endif + +#ifndef _7ZIP_UINT64_DEFINED +#define _7ZIP_UINT64_DEFINED +typedef unsigned long long int UInt64; +#endif + +#endif + +#endif diff --git a/utils/lzma/C/Common/Vector.cpp b/utils/lzma/C/Common/Vector.cpp new file mode 100644 index 00000000..cb3d8752 --- /dev/null +++ b/utils/lzma/C/Common/Vector.cpp @@ -0,0 +1,74 @@ +// Common/Vector.cpp + +#include "StdAfx.h" + +#include + +#include "Vector.h" + +CBaseRecordVector::~CBaseRecordVector() + { delete []((unsigned char *)_items); } +void CBaseRecordVector::Clear() + { DeleteFrom(0); } +void CBaseRecordVector::DeleteBack() + { Delete(_size - 1); } +void CBaseRecordVector::DeleteFrom(int index) + { Delete(index, _size - index); } + +void CBaseRecordVector::ReserveOnePosition() +{ + if(_size != _capacity) + return; + int delta; + if (_capacity > 64) + delta = _capacity / 2; + else if (_capacity > 8) + delta = 8; + else + delta = 4; + Reserve(_capacity + delta); +} + +void CBaseRecordVector::Reserve(int newCapacity) +{ + if(newCapacity <= _capacity) + return; + /* + #ifndef _DEBUG + static const unsigned int kMaxVectorSize = 0xF0000000; + if(newCapacity < _size || + ((unsigned int )newCapacity * (unsigned int )_itemSize) > kMaxVectorSize) + throw 1052354; + #endif + */ + unsigned char *p = new unsigned char[newCapacity * _itemSize]; + int numRecordsToMove = _capacity; + memmove(p, _items, _itemSize * numRecordsToMove); + delete [](unsigned char *)_items; + _items = p; + _capacity = newCapacity; +} + +void CBaseRecordVector::MoveItems(int destIndex, int srcIndex) +{ + memmove(((unsigned char *)_items) + destIndex * _itemSize, + ((unsigned char *)_items) + srcIndex * _itemSize, + _itemSize * (_size - srcIndex)); +} + +void CBaseRecordVector::InsertOneItem(int index) +{ + ReserveOnePosition(); + MoveItems(index + 1, index); + _size++; +} + +void CBaseRecordVector::Delete(int index, int num) +{ + TestIndexAndCorrectNum(index, num); + if (num > 0) + { + MoveItems(index, index + num); + _size -= num; + } +} diff --git a/utils/lzma/C/Common/Vector.h b/utils/lzma/C/Common/Vector.h new file mode 100644 index 00000000..210c385e --- /dev/null +++ b/utils/lzma/C/Common/Vector.h @@ -0,0 +1,228 @@ +// Common/Vector.h + +#ifndef __COMMON_VECTOR_H +#define __COMMON_VECTOR_H + +#include "Defs.h" + +class CBaseRecordVector +{ + void MoveItems(int destIndex, int srcIndex); +protected: + int _capacity; + int _size; + void *_items; + size_t _itemSize; + + void ReserveOnePosition(); + void InsertOneItem(int index); + void TestIndexAndCorrectNum(int index, int &num) const + { if (index + num > _size) num = _size - index; } +public: + CBaseRecordVector(size_t itemSize): + _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} + virtual ~CBaseRecordVector(); + int Size() const { return _size; } + bool IsEmpty() const { return (_size == 0); } + void Reserve(int newCapacity); + virtual void Delete(int index, int num = 1); + void Clear(); + void DeleteFrom(int index); + void DeleteBack(); +}; + +template +class CRecordVector: public CBaseRecordVector +{ +public: + CRecordVector():CBaseRecordVector(sizeof(T)){}; + CRecordVector(const CRecordVector &v): + CBaseRecordVector(sizeof(T)) { *this = v;} + CRecordVector& operator=(const CRecordVector &v) + { + Clear(); + return (*this += v); + } + CRecordVector& operator+=(const CRecordVector &v) + { + int size = v.Size(); + Reserve(Size() + size); + for(int i = 0; i < size; i++) + Add(v[i]); + return *this; + } + int Add(T item) + { + ReserveOnePosition(); + ((T *)_items)[_size] = item; + return _size++; + } + void Insert(int index, T item) + { + InsertOneItem(index); + ((T *)_items)[index] = item; + } + // T* GetPointer() const { return (T*)_items; } + // operator const T *() const { return _items; }; + const T& operator[](int index) const { return ((T *)_items)[index]; } + T& operator[](int index) { return ((T *)_items)[index]; } + const T& Front() const { return operator[](0); } + T& Front() { return operator[](0); } + const T& Back() const { return operator[](_size - 1); } + T& Back() { return operator[](_size - 1); } + + void Swap(int i, int j) + { + T temp = operator[](i); + operator[](i) = operator[](j); + operator[](j) = temp; + } + + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + + void Sort(int left, int right) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (operator[](i) < operator[](left)) + Swap(++last, i); + Swap(left, last); + Sort(left, last); + Sort(last + 1, right); + } + void Sort() { Sort(0, Size()); } + void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (compare(&operator[](i), &operator[](left), param) < 0) + Swap(++last, i); + Swap(left, last); + Sort(left, last, compare, param); + Sort(last + 1, right, compare, param); + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + Sort(0, Size(), compare, param); + } +}; + +typedef CRecordVector CIntVector; +typedef CRecordVector CUIntVector; +typedef CRecordVector CBoolVector; +typedef CRecordVector CByteVector; +typedef CRecordVector CPointerVector; + +template +class CObjectVector: public CPointerVector +{ +public: + CObjectVector(){}; + ~CObjectVector() { Clear(); } + CObjectVector(const CObjectVector &objectVector) + { *this = objectVector; } + CObjectVector& operator=(const CObjectVector &objectVector) + { + Clear(); + return (*this += objectVector); + } + CObjectVector& operator+=(const CObjectVector &objectVector) + { + int size = objectVector.Size(); + Reserve(Size() + size); + for(int i = 0; i < size; i++) + Add(objectVector[i]); + return *this; + } + const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); } + T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); } + T& Front() { return operator[](0); } + const T& Front() const { return operator[](0); } + T& Back() { return operator[](_size - 1); } + const T& Back() const { return operator[](_size - 1); } + int Add(const T& item) + { return CPointerVector::Add(new T(item)); } + void Insert(int index, const T& item) + { CPointerVector::Insert(index, new T(item)); } + virtual void Delete(int index, int num = 1) + { + TestIndexAndCorrectNum(index, num); + for(int i = 0; i < num; i++) + delete (T *)(((void **)_items)[index + i]); + CPointerVector::Delete(index, num); + } + int Find(const T& item) const + { + for(int i = 0; i < Size(); i++) + if (item == (*this)[i]) + return i; + return -1; + } + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + int AddToSorted(const T& item) + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + { + right = mid + 1; + break; + } + if (item < midValue) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { CPointerVector::Sort(compare, param); } + + static int CompareObjectItems(void *const *a1, void *const *a2, void *param) + { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } + void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } +}; + +#endif diff --git a/utils/lzma/C/Compiler.h b/utils/lzma/C/Compiler.h deleted file mode 100644 index 6e964897..00000000 --- a/utils/lzma/C/Compiler.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Compiler.h -- Compiler ypes -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_COMPILER_H -#define __7Z_COMPILER_H - -#ifdef _MSC_VER - - #ifdef UNDER_CE - #define RPC_NO_WINDOWS_H - /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ - #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union - #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int - #endif - - #if _MSC_VER >= 1300 - #pragma warning(disable : 4996) // This function or variable may be unsafe - #else - #pragma warning(disable : 4511) // copy constructor could not be generated - #pragma warning(disable : 4512) // assignment operator could not be generated - #pragma warning(disable : 4702) // unreachable code - #pragma warning(disable : 4710) // not inlined - #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information - #endif - -#endif - -#endif diff --git a/utils/lzma/C/CpuArch.c b/utils/lzma/C/CpuArch.c deleted file mode 100644 index d7f8b1d8..00000000 --- a/utils/lzma/C/CpuArch.c +++ /dev/null @@ -1,190 +0,0 @@ -/* CpuArch.c -- CPU specific code -2012-05-29: Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#ifdef MY_CPU_X86_OR_AMD64 - -#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) -#define USE_ASM -#endif - -#if !defined(USE_ASM) && _MSC_VER >= 1500 -#include -#endif - -#if defined(USE_ASM) && !defined(MY_CPU_AMD64) -static UInt32 CheckFlag(UInt32 flag) -{ - #ifdef _MSC_VER - __asm pushfd; - __asm pop EAX; - __asm mov EDX, EAX; - __asm xor EAX, flag; - __asm push EAX; - __asm popfd; - __asm pushfd; - __asm pop EAX; - __asm xor EAX, EDX; - __asm push EDX; - __asm popfd; - __asm and flag, EAX; - #else - __asm__ __volatile__ ( - "pushf\n\t" - "pop %%EAX\n\t" - "movl %%EAX,%%EDX\n\t" - "xorl %0,%%EAX\n\t" - "push %%EAX\n\t" - "popf\n\t" - "pushf\n\t" - "pop %%EAX\n\t" - "xorl %%EDX,%%EAX\n\t" - "push %%EDX\n\t" - "popf\n\t" - "andl %%EAX, %0\n\t": - "=c" (flag) : "c" (flag)); - #endif - return flag; -} -#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; -#else -#define CHECK_CPUID_IS_SUPPORTED -#endif - -static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) -{ - #ifdef USE_ASM - - #ifdef _MSC_VER - - UInt32 a2, b2, c2, d2; - __asm xor EBX, EBX; - __asm xor ECX, ECX; - __asm xor EDX, EDX; - __asm mov EAX, function; - __asm cpuid; - __asm mov a2, EAX; - __asm mov b2, EBX; - __asm mov c2, ECX; - __asm mov d2, EDX; - - *a = a2; - *b = b2; - *c = c2; - *d = d2; - - #else - - __asm__ __volatile__ ( - #if defined(MY_CPU_X86) && defined(__PIC__) - "mov %%ebx, %%edi;" - "cpuid;" - "xchgl %%ebx, %%edi;" - : "=a" (*a) , - "=D" (*b) , - #else - "cpuid" - : "=a" (*a) , - "=b" (*b) , - #endif - "=c" (*c) , - "=d" (*d) - : "0" (function)) ; - - #endif - - #else - - int CPUInfo[4]; - __cpuid(CPUInfo, function); - *a = CPUInfo[0]; - *b = CPUInfo[1]; - *c = CPUInfo[2]; - *d = CPUInfo[3]; - - #endif -} - -Bool x86cpuid_CheckAndRead(Cx86cpuid *p) -{ - CHECK_CPUID_IS_SUPPORTED - MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); - MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); - return True; -} - -static UInt32 kVendors[][3] = -{ - { 0x756E6547, 0x49656E69, 0x6C65746E}, - { 0x68747541, 0x69746E65, 0x444D4163}, - { 0x746E6543, 0x48727561, 0x736C7561} -}; - -int x86cpuid_GetFirm(const Cx86cpuid *p) -{ - unsigned i; - for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) - { - const UInt32 *v = kVendors[i]; - if (v[0] == p->vendor[0] && - v[1] == p->vendor[1] && - v[2] == p->vendor[2]) - return (int)i; - } - return -1; -} - -Bool CPU_Is_InOrder() -{ - Cx86cpuid p; - int firm; - UInt32 family, model; - if (!x86cpuid_CheckAndRead(&p)) - return True; - family = x86cpuid_GetFamily(&p); - model = x86cpuid_GetModel(&p); - firm = x86cpuid_GetFirm(&p); - switch (firm) - { - case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( - /* Atom CPU */ - model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ - || model == 0x2006 /* 45 nm, Z6xx */ - || model == 0x2007 /* 32 nm, Z2460 */ - || model == 0x3005 /* 32 nm, Z2760 */ - || model == 0x3006 /* 32 nm, N2xxx, D2xxx */ - ))); - case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); - case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); - } - return True; -} - -#if !defined(MY_CPU_AMD64) && defined(_WIN32) -#include -static Bool CPU_Sys_Is_SSE_Supported() -{ - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi)) - return False; - return (vi.dwMajorVersion >= 5); -} -#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; -#else -#define CHECK_SYS_SSE_SUPPORT -#endif - -Bool CPU_Is_Aes_Supported() -{ - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) - return False; - return (p.c >> 25) & 1; -} - -#endif diff --git a/utils/lzma/C/CpuArch.h b/utils/lzma/C/CpuArch.h deleted file mode 100644 index 4fee0093..00000000 --- a/utils/lzma/C/CpuArch.h +++ /dev/null @@ -1,157 +0,0 @@ -/* CpuArch.h -- CPU specific code -2013-11-12: Igor Pavlov : Public domain */ - -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -MY_CPU_LE means that CPU is LITTLE ENDIAN. -If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). - -MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. -If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. -*/ - -#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) -#define MY_CPU_AMD64 -#endif - -#if defined(MY_CPU_AMD64) || defined(_M_IA64) -#define MY_CPU_64BIT -#endif - -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 -#endif - -#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) -#define MY_CPU_X86_OR_AMD64 -#endif - -#if defined(MY_CPU_X86) || defined(_M_ARM) -#define MY_CPU_32BIT -#endif - -#if defined(_WIN32) && defined(_M_ARM) -#define MY_CPU_ARM_LE -#endif - -#if defined(_WIN32) && defined(_M_IA64) -#define MY_CPU_IA64_LE -#endif - -#if defined(MY_CPU_X86_OR_AMD64) -#define MY_CPU_LE_UNALIGN -#endif - -#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) -#define MY_CPU_LE -#endif - -#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) -#define MY_CPU_BE -#endif - -#if defined(MY_CPU_LE) && defined(MY_CPU_BE) -Stop_Compiling_Bad_Endian -#endif - -#ifdef MY_CPU_LE_UNALIGN - -#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) -#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) -#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) -#define SetUi16(p, d) *(UInt16 *)(p) = (d); -#define SetUi32(p, d) *(UInt32 *)(p) = (d); -#define SetUi64(p, d) *(UInt64 *)(p) = (d); - -#else - -#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) - -#define GetUi32(p) ( \ - ((const Byte *)(p))[0] | \ - ((UInt32)((const Byte *)(p))[1] << 8) | \ - ((UInt32)((const Byte *)(p))[2] << 16) | \ - ((UInt32)((const Byte *)(p))[3] << 24)) - -#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) - -#define SetUi16(p, d) { UInt32 _x_ = (d); \ - ((Byte *)(p))[0] = (Byte)_x_; \ - ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } - -#define SetUi32(p, d) { UInt32 _x_ = (d); \ - ((Byte *)(p))[0] = (Byte)_x_; \ - ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ - ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ - ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } - -#define SetUi64(p, d) { UInt64 _x64_ = (d); \ - SetUi32(p, (UInt32)_x64_); \ - SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } - -#endif - -#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) - -#include - -#pragma intrinsic(_byteswap_ulong) -#pragma intrinsic(_byteswap_uint64) -#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) -#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) - -#else - -#define GetBe32(p) ( \ - ((UInt32)((const Byte *)(p))[0] << 24) | \ - ((UInt32)((const Byte *)(p))[1] << 16) | \ - ((UInt32)((const Byte *)(p))[2] << 8) | \ - ((const Byte *)(p))[3] ) - -#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) - -#endif - -#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])) - - -#ifdef MY_CPU_X86_OR_AMD64 - -typedef struct -{ - UInt32 maxFunc; - UInt32 vendor[3]; - UInt32 ver; - UInt32 b; - UInt32 c; - UInt32 d; -} Cx86cpuid; - -enum -{ - CPU_FIRM_INTEL, - CPU_FIRM_AMD, - CPU_FIRM_VIA -}; - -Bool x86cpuid_CheckAndRead(Cx86cpuid *p); -int x86cpuid_GetFirm(const Cx86cpuid *p); - -#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) -#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) -#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) - -Bool CPU_Is_InOrder(); -Bool CPU_Is_Aes_Supported(); - -#endif - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Delta.c b/utils/lzma/C/Delta.c deleted file mode 100644 index e3edd21e..00000000 --- a/utils/lzma/C/Delta.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Delta.c -- Delta converter -2009-05-26 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Delta.h" - -void Delta_Init(Byte *state) -{ - unsigned i; - for (i = 0; i < DELTA_STATE_SIZE; i++) - state[i] = 0; -} - -static void MyMemCpy(Byte *dest, const Byte *src, unsigned size) -{ - unsigned i; - for (i = 0; i < size; i++) - dest[i] = src[i]; -} - -void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) -{ - Byte buf[DELTA_STATE_SIZE]; - unsigned j = 0; - MyMemCpy(buf, state, delta); - { - SizeT i; - for (i = 0; i < size;) - { - for (j = 0; j < delta && i < size; i++, j++) - { - Byte b = data[i]; - data[i] = (Byte)(b - buf[j]); - buf[j] = b; - } - } - } - if (j == delta) - j = 0; - MyMemCpy(state, buf + j, delta - j); - MyMemCpy(state + delta - j, buf, j); -} - -void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) -{ - Byte buf[DELTA_STATE_SIZE]; - unsigned j = 0; - MyMemCpy(buf, state, delta); - { - SizeT i; - for (i = 0; i < size;) - { - for (j = 0; j < delta && i < size; i++, j++) - { - buf[j] = data[i] = (Byte)(buf[j] + data[i]); - } - } - } - if (j == delta) - j = 0; - MyMemCpy(state, buf + j, delta - j); - MyMemCpy(state + delta - j, buf, j); -} diff --git a/utils/lzma/C/Delta.h b/utils/lzma/C/Delta.h deleted file mode 100644 index 2fa54ad6..00000000 --- a/utils/lzma/C/Delta.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Delta.h -- Delta converter -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __DELTA_H -#define __DELTA_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define DELTA_STATE_SIZE 256 - -void Delta_Init(Byte *state); -void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); -void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/LzFind.c b/utils/lzma/C/LzFind.c deleted file mode 100644 index 262b395b..00000000 --- a/utils/lzma/C/LzFind.c +++ /dev/null @@ -1,763 +0,0 @@ -/* LzFind.c -- Match finder for LZ algorithms -2009-04-22 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "LzFind.h" -#include "LzHash.h" - -#define kEmptyHashValue 0 -#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -#define kNormalizeMask (~(kNormalizeStepMin - 1)) -#define kMaxHistorySize ((UInt32)3 << 30) - -#define kStartMaxLen 3 - -static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -{ - if (!p->directInput) - { - alloc->Free(alloc, p->bufferBase); - p->bufferBase = 0; - } -} - -/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ - -static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -{ - UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; - if (p->directInput) - { - p->blockSize = blockSize; - return 1; - } - if (p->bufferBase == 0 || p->blockSize != blockSize) - { - LzInWindow_Free(p, alloc); - p->blockSize = blockSize; - p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); - } - return (p->bufferBase != 0); -} - -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } - -UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } - -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -{ - p->posLimit -= subValue; - p->pos -= subValue; - p->streamPos -= subValue; -} - -static void MatchFinder_ReadBlock(CMatchFinder *p) -{ - if (p->streamEndWasReached || p->result != SZ_OK) - return; - if (p->directInput) - { - UInt32 curSize = 0xFFFFFFFF - p->streamPos; - if (curSize > p->directInputRem) - curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; - p->streamPos += curSize; - if (p->directInputRem == 0) - p->streamEndWasReached = 1; - return; - } - for (;;) - { - Byte *dest = p->buffer + (p->streamPos - p->pos); - size_t size = (p->bufferBase + p->blockSize - dest); - if (size == 0) - return; - p->result = p->stream->Read(p->stream, dest, &size); - if (p->result != SZ_OK) - return; - if (size == 0) - { - p->streamEndWasReached = 1; - return; - } - p->streamPos += (UInt32)size; - if (p->streamPos - p->pos > p->keepSizeAfter) - return; - } -} - -void MatchFinder_MoveBlock(CMatchFinder *p) -{ - memmove(p->bufferBase, - p->buffer - p->keepSizeBefore, - (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); - p->buffer = p->bufferBase + p->keepSizeBefore; -} - -int MatchFinder_NeedMove(CMatchFinder *p) -{ - if (p->directInput) - return 0; - /* if (p->streamEndWasReached) return 0; */ - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -} - -void MatchFinder_ReadIfRequired(CMatchFinder *p) -{ - if (p->streamEndWasReached) - return; - if (p->keepSizeAfter >= p->streamPos - p->pos) - MatchFinder_ReadBlock(p); -} - -static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -{ - if (MatchFinder_NeedMove(p)) - MatchFinder_MoveBlock(p); - MatchFinder_ReadBlock(p); -} - -static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -{ - p->cutValue = 32; - p->btMode = 1; - p->numHashBytes = 4; - p->bigHash = 0; -} - -#define kCrcPoly 0xEDB88320 - -void MatchFinder_Construct(CMatchFinder *p) -{ - UInt32 i; - p->bufferBase = 0; - p->directInput = 0; - p->hash = 0; - MatchFinder_SetDefaultSettings(p); - - for (i = 0; i < 256; i++) - { - UInt32 r = i; - int j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - p->crc[i] = r; - } -} - -static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->hash); - p->hash = 0; -} - -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -{ - MatchFinder_FreeThisClassMemory(p, alloc); - LzInWindow_Free(p, alloc); -} - -static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -{ - size_t sizeInBytes = (size_t)num * sizeof(CLzRef); - if (sizeInBytes / sizeof(CLzRef) != num) - return 0; - return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -} - -int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc) -{ - UInt32 sizeReserv; - if (historySize > kMaxHistorySize) - { - MatchFinder_Free(p, alloc); - return 0; - } - sizeReserv = historySize >> 1; - if (historySize > ((UInt32)2 << 30)) - sizeReserv = historySize >> 2; - sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); - - p->keepSizeBefore = historySize + keepAddBufferBefore + 1; - p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; - /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ - if (LzInWindow_Create(p, sizeReserv, alloc)) - { - UInt32 newCyclicBufferSize = historySize + 1; - UInt32 hs; - p->matchMaxLen = matchMaxLen; - { - p->fixedHashSize = 0; - if (p->numHashBytes == 2) - hs = (1 << 16) - 1; - else - { - hs = historySize - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; /* don't change it! It's required for Deflate */ - if (hs > (1 << 24)) - { - if (p->numHashBytes == 3) - hs = (1 << 24) - 1; - else - hs >>= 1; - } - } - p->hashMask = hs; - hs++; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; - hs += p->fixedHashSize; - } - - { - UInt32 prevSize = p->hashSizeSum + p->numSons; - UInt32 newSize; - p->historySize = historySize; - p->hashSizeSum = hs; - p->cyclicBufferSize = newCyclicBufferSize; - p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); - newSize = p->hashSizeSum + p->numSons; - if (p->hash != 0 && prevSize == newSize) - return 1; - MatchFinder_FreeThisClassMemory(p, alloc); - p->hash = AllocRefs(newSize, alloc); - if (p->hash != 0) - { - p->son = p->hash + p->hashSizeSum; - return 1; - } - } - } - MatchFinder_Free(p, alloc); - return 0; -} - -static void MatchFinder_SetLimits(CMatchFinder *p) -{ - UInt32 limit = kMaxValForNormalize - p->pos; - UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; - if (limit2 < limit) - limit = limit2; - limit2 = p->streamPos - p->pos; - if (limit2 <= p->keepSizeAfter) - { - if (limit2 > 0) - limit2 = 1; - } - else - limit2 -= p->keepSizeAfter; - if (limit2 < limit) - limit = limit2; - { - UInt32 lenLimit = p->streamPos - p->pos; - if (lenLimit > p->matchMaxLen) - lenLimit = p->matchMaxLen; - p->lenLimit = lenLimit; - } - p->posLimit = p->pos + limit; -} - -void MatchFinder_Init(CMatchFinder *p) -{ - UInt32 i; - for (i = 0; i < p->hashSizeSum; i++) - p->hash[i] = kEmptyHashValue; - p->cyclicBufferPos = 0; - p->buffer = p->bufferBase; - p->pos = p->streamPos = p->cyclicBufferSize; - p->result = SZ_OK; - p->streamEndWasReached = 0; - MatchFinder_ReadBlock(p); - MatchFinder_SetLimits(p); -} - -static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -{ - return (p->pos - p->historySize - 1) & kNormalizeMask; -} - -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -{ - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt32 value = items[i]; - if (value <= subValue) - value = kEmptyHashValue; - else - value -= subValue; - items[i] = value; - } -} - -static void MatchFinder_Normalize(CMatchFinder *p) -{ - UInt32 subValue = MatchFinder_GetSubValue(p); - MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); - MatchFinder_ReduceOffsets(p, subValue); -} - -static void MatchFinder_CheckLimits(CMatchFinder *p) -{ - if (p->pos == kMaxValForNormalize) - MatchFinder_Normalize(p); - if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) - MatchFinder_CheckAndMoveAndRead(p); - if (p->cyclicBufferPos == p->cyclicBufferSize) - p->cyclicBufferPos = 0; - MatchFinder_SetLimits(p); -} - -static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) -{ - son[_cyclicBufferPos] = curMatch; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - return distances; - { - const Byte *pb = cur - delta; - curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; - if (pb[maxLen] == cur[maxLen] && *pb == *cur) - { - UInt32 len = 0; - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - return distances; - } - } - } - } -} - -UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) -{ - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - return distances; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - if (++len != lenLimit && pb[len] == cur[len]) - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return distances; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } -} - -static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -{ - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - return; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - { - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } -} - -#define MOVE_POS \ - ++p->cyclicBufferPos; \ - p->buffer++; \ - if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); - -#define MOVE_POS_RET MOVE_POS return offset; - -static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } - -#define GET_MATCHES_HEADER2(minLen, ret_op) \ - UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ - lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ - cur = p->buffer; - -#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) - -#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue - -#define GET_MATCHES_FOOTER(offset, maxLen) \ - offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ - distances + offset, maxLen) - distances); MOVE_POS_RET; - -#define SKIP_FOOTER \ - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; - -static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 1) -} - -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 2) -} - -static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 hash2Value, delta2, maxLen, offset; - GET_MATCHES_HEADER(3) - - HASH3_CALC; - - delta2 = p->pos - p->hash[hash2Value]; - curMatch = p->hash[kFix3HashSize + hashValue]; - - p->hash[hash2Value] = - p->hash[kFix3HashSize + hashValue] = p->pos; - - - maxLen = 2; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) - { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[0] = maxLen; - distances[1] = delta2 - 1; - offset = 2; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } - } - GET_MATCHES_FOOTER(offset, maxLen) -} - -static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; - GET_MATCHES_HEADER(4) - - HASH4_CALC; - - delta2 = p->pos - p->hash[ hash2Value]; - delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; - curMatch = p->hash[kFix4HashSize + hashValue]; - - p->hash[ hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; - - maxLen = 1; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = delta2 - 1; - offset = 2; - } - if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) - { - maxLen = 3; - distances[offset + 1] = delta3 - 1; - offset += 2; - delta2 = delta3; - } - if (offset != 0) - { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } - } - if (maxLen < 3) - maxLen = 3; - GET_MATCHES_FOOTER(offset, maxLen) -} - -static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; - GET_MATCHES_HEADER(4) - - HASH4_CALC; - - delta2 = p->pos - p->hash[ hash2Value]; - delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; - curMatch = p->hash[kFix4HashSize + hashValue]; - - p->hash[ hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; - - maxLen = 1; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = delta2 - 1; - offset = 2; - } - if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) - { - maxLen = 3; - distances[offset + 1] = delta3 - 1; - offset += 2; - delta2 = delta3; - } - if (offset != 0) - { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; - } - } - if (maxLen < 3) - maxLen = 3; - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances + offset, maxLen) - (distances)); - MOVE_POS_RET -} - -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances, 2) - (distances)); - MOVE_POS_RET -} - -static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 hash2Value; - SKIP_HEADER(3) - HASH3_CALC; - curMatch = p->hash[kFix3HashSize + hashValue]; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hashValue] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 hash2Value, hash3Value; - SKIP_HEADER(4) - HASH4_CALC; - curMatch = p->hash[kFix4HashSize + hashValue]; - p->hash[ hash2Value] = - p->hash[kFix3HashSize + hash3Value] = p->pos; - p->hash[kFix4HashSize + hashValue] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 hash2Value, hash3Value; - SKIP_HEADER(4) - HASH4_CALC; - curMatch = p->hash[kFix4HashSize + hashValue]; - p->hash[ hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } - while (--num != 0); -} - -void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } - while (--num != 0); -} - -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -{ - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; - if (!p->btMode) - { - vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; - } - else if (p->numHashBytes == 2) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; - } - else if (p->numHashBytes == 3) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; - } - else - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; - } -} diff --git a/utils/lzma/C/LzFind.h b/utils/lzma/C/LzFind.h deleted file mode 100644 index 706143d2..00000000 --- a/utils/lzma/C/LzFind.h +++ /dev/null @@ -1,111 +0,0 @@ -/* LzFind.h -- Match finder for LZ algorithms -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_H -#define __LZ_FIND_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -typedef UInt32 CLzRef; - -typedef struct _CMatchFinder -{ - Byte *buffer; - UInt32 pos; - UInt32 posLimit; - UInt32 streamPos; - UInt32 lenLimit; - - UInt32 cyclicBufferPos; - UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ - - UInt32 matchMaxLen; - CLzRef *hash; - CLzRef *son; - UInt32 hashMask; - UInt32 cutValue; - - Byte *bufferBase; - ISeqInStream *stream; - int streamEndWasReached; - - UInt32 blockSize; - UInt32 keepSizeBefore; - UInt32 keepSizeAfter; - - UInt32 numHashBytes; - int directInput; - size_t directInputRem; - int btMode; - int bigHash; - UInt32 historySize; - UInt32 fixedHashSize; - UInt32 hashSizeSum; - UInt32 numSons; - SRes result; - UInt32 crc[256]; -} CMatchFinder; - -#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) - -#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) - -int MatchFinder_NeedMove(CMatchFinder *p); -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -void MatchFinder_MoveBlock(CMatchFinder *p); -void MatchFinder_ReadIfRequired(CMatchFinder *p); - -void MatchFinder_Construct(CMatchFinder *p); - -/* Conditions: - historySize <= 3 GB - keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -*/ -int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); - -UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, - UInt32 *distances, UInt32 maxLen); - -/* -Conditions: - Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. - Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -*/ - -typedef void (*Mf_Init_Func)(void *object); -typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -typedef void (*Mf_Skip_Func)(void *object, UInt32); - -typedef struct _IMatchFinder -{ - Mf_Init_Func Init; - Mf_GetIndexByte_Func GetIndexByte; - Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; - Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; - Mf_GetMatches_Func GetMatches; - Mf_Skip_Func Skip; -} IMatchFinder; - -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); - -void MatchFinder_Init(CMatchFinder *p); -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/LzFindMt.c b/utils/lzma/C/LzFindMt.c deleted file mode 100644 index cee8ea74..00000000 --- a/utils/lzma/C/LzFindMt.c +++ /dev/null @@ -1,794 +0,0 @@ -/* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2014-12-29 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "LzHash.h" - -#include "LzFindMt.h" - -void MtSync_Construct(CMtSync *p) -{ - p->wasCreated = False; - p->csWasInitialized = False; - p->csWasEntered = False; - Thread_Construct(&p->thread); - Event_Construct(&p->canStart); - Event_Construct(&p->wasStarted); - Event_Construct(&p->wasStopped); - Semaphore_Construct(&p->freeSemaphore); - Semaphore_Construct(&p->filledSemaphore); -} - -void MtSync_GetNextBlock(CMtSync *p) -{ - if (p->needStart) - { - p->numProcessedBlocks = 1; - p->needStart = False; - p->stopWriting = False; - p->exit = False; - Event_Reset(&p->wasStarted); - Event_Reset(&p->wasStopped); - - Event_Set(&p->canStart); - Event_Wait(&p->wasStarted); - } - else - { - CriticalSection_Leave(&p->cs); - p->csWasEntered = False; - p->numProcessedBlocks++; - Semaphore_Release1(&p->freeSemaphore); - } - Semaphore_Wait(&p->filledSemaphore); - CriticalSection_Enter(&p->cs); - p->csWasEntered = True; -} - -/* MtSync_StopWriting must be called if Writing was started */ - -void MtSync_StopWriting(CMtSync *p) -{ - UInt32 myNumBlocks = p->numProcessedBlocks; - if (!Thread_WasCreated(&p->thread) || p->needStart) - return; - p->stopWriting = True; - if (p->csWasEntered) - { - CriticalSection_Leave(&p->cs); - p->csWasEntered = False; - } - Semaphore_Release1(&p->freeSemaphore); - - Event_Wait(&p->wasStopped); - - while (myNumBlocks++ != p->numProcessedBlocks) - { - Semaphore_Wait(&p->filledSemaphore); - Semaphore_Release1(&p->freeSemaphore); - } - p->needStart = True; -} - -void MtSync_Destruct(CMtSync *p) -{ - if (Thread_WasCreated(&p->thread)) - { - MtSync_StopWriting(p); - p->exit = True; - if (p->needStart) - Event_Set(&p->canStart); - Thread_Wait(&p->thread); - Thread_Close(&p->thread); - } - if (p->csWasInitialized) - { - CriticalSection_Delete(&p->cs); - p->csWasInitialized = False; - } - - Event_Close(&p->canStart); - Event_Close(&p->wasStarted); - Event_Close(&p->wasStopped); - Semaphore_Close(&p->freeSemaphore); - Semaphore_Close(&p->filledSemaphore); - - p->wasCreated = False; -} - -#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } - -static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) -{ - if (p->wasCreated) - return SZ_OK; - - RINOK_THREAD(CriticalSection_Init(&p->cs)); - p->csWasInitialized = True; - - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); - - RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); - RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); - - p->needStart = True; - - RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj)); - p->wasCreated = True; - return SZ_OK; -} - -static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) -{ - SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); - if (res != SZ_OK) - MtSync_Destruct(p); - return res; -} - -void MtSync_Init(CMtSync *p) { p->needStart = True; } - -#define kMtMaxValForNormalize 0xFFFFFFFF - -#define DEF_GetHeads2(name, v, action) \ -static void GetHeads ## name(const Byte *p, UInt32 pos, \ -UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ -{ action; for (; numHeads != 0; numHeads--) { \ -const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } } - -#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) - -DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; ) -DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) -DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) -DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) -/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ - -void HashThreadFunc(CMatchFinderMt *mt) -{ - CMtSync *p = &mt->hashSync; - for (;;) - { - UInt32 numProcessedBlocks = 0; - Event_Wait(&p->canStart); - Event_Set(&p->wasStarted); - for (;;) - { - if (p->exit) - return; - if (p->stopWriting) - { - p->numProcessedBlocks = numProcessedBlocks; - Event_Set(&p->wasStopped); - break; - } - - { - CMatchFinder *mf = mt->MatchFinder; - if (MatchFinder_NeedMove(mf)) - { - CriticalSection_Enter(&mt->btSync.cs); - CriticalSection_Enter(&mt->hashSync.cs); - { - const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf); - const Byte *afterPtr; - MatchFinder_MoveBlock(mf); - afterPtr = MatchFinder_GetPointerToCurrentPos(mf); - mt->pointerToCurPos -= beforePtr - afterPtr; - mt->buffer -= beforePtr - afterPtr; - } - CriticalSection_Leave(&mt->btSync.cs); - CriticalSection_Leave(&mt->hashSync.cs); - continue; - } - - Semaphore_Wait(&p->freeSemaphore); - - MatchFinder_ReadIfRequired(mf); - if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize)) - { - UInt32 subValue = (mf->pos - mf->historySize - 1); - MatchFinder_ReduceOffsets(mf, subValue); - MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1); - } - { - UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize; - UInt32 num = mf->streamPos - mf->pos; - heads[0] = 2; - heads[1] = num; - if (num >= mf->numHashBytes) - { - num = num - mf->numHashBytes + 1; - if (num > kMtHashBlockSize - 2) - num = kMtHashBlockSize - 2; - mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); - heads[0] += num; - } - mf->pos += num; - mf->buffer += num; - } - } - - Semaphore_Release1(&p->filledSemaphore); - } - } -} - -void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) -{ - MtSync_GetNextBlock(&p->hashSync); - p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize; - p->hashBufPosLimit += p->hashBuf[p->hashBufPos++]; - p->hashNumAvail = p->hashBuf[p->hashBufPos++]; -} - -#define kEmptyHashValue 0 - -/* #define MFMT_GM_INLINE */ - -#ifdef MFMT_GM_INLINE - -#define NO_INLINE MY_FAST_CALL - -Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, - UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) -{ - do - { - UInt32 *distances = _distances + 1; - UInt32 curMatch = pos - *hash++; - - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - UInt32 cutValue = _cutValue; - UInt32 maxLen = _maxLen; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - break; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - if (++len != lenLimit && pb[len] == cur[len]) - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - break; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } - pos++; - _cyclicBufferPos++; - cur++; - { - UInt32 num = (UInt32)(distances - _distances); - *_distances = num - 1; - _distances += num; - limit -= num; - } - } - while (limit > 0 && --size != 0); - *posRes = pos; - return limit; -} - -#endif - -void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - UInt32 numProcessed = 0; - UInt32 curPos = 2; - UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); - distances[1] = p->hashNumAvail; - while (curPos < limit) - { - if (p->hashBufPos == p->hashBufPosLimit) - { - MatchFinderMt_GetNextBlock_Hash(p); - distances[1] = numProcessed + p->hashNumAvail; - if (p->hashNumAvail >= p->numHashBytes) - continue; - for (; p->hashNumAvail != 0; p->hashNumAvail--) - distances[curPos++] = 0; - break; - } - { - UInt32 size = p->hashBufPosLimit - p->hashBufPos; - UInt32 lenLimit = p->matchMaxLen; - UInt32 pos = p->pos; - UInt32 cyclicBufferPos = p->cyclicBufferPos; - if (lenLimit >= p->hashNumAvail) - lenLimit = p->hashNumAvail; - { - UInt32 size2 = p->hashNumAvail - lenLimit + 1; - if (size2 < size) - size = size2; - size2 = p->cyclicBufferSize - cyclicBufferPos; - if (size2 < size) - size = size2; - } - #ifndef MFMT_GM_INLINE - while (curPos < limit && size-- != 0) - { - UInt32 *startDistances = distances + curPos; - UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], - pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, - startDistances + 1, p->numHashBytes - 1) - startDistances); - *startDistances = num - 1; - curPos += num; - cyclicBufferPos++; - pos++; - p->buffer++; - } - #else - { - UInt32 posRes; - curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, - distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes); - p->hashBufPos += posRes - pos; - cyclicBufferPos += posRes - pos; - p->buffer += posRes - pos; - pos = posRes; - } - #endif - - numProcessed += pos - p->pos; - p->hashNumAvail -= pos - p->pos; - p->pos = pos; - if (cyclicBufferPos == p->cyclicBufferSize) - cyclicBufferPos = 0; - p->cyclicBufferPos = cyclicBufferPos; - } - } - distances[0] = curPos; -} - -void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) -{ - CMtSync *sync = &p->hashSync; - if (!sync->needStart) - { - CriticalSection_Enter(&sync->cs); - sync->csWasEntered = True; - } - - BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize); - - if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) - { - UInt32 subValue = p->pos - p->cyclicBufferSize; - MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2); - p->pos -= subValue; - } - - if (!sync->needStart) - { - CriticalSection_Leave(&sync->cs); - sync->csWasEntered = False; - } -} - -void BtThreadFunc(CMatchFinderMt *mt) -{ - CMtSync *p = &mt->btSync; - for (;;) - { - UInt32 blockIndex = 0; - Event_Wait(&p->canStart); - Event_Set(&p->wasStarted); - for (;;) - { - if (p->exit) - return; - if (p->stopWriting) - { - p->numProcessedBlocks = blockIndex; - MtSync_StopWriting(&mt->hashSync); - Event_Set(&p->wasStopped); - break; - } - Semaphore_Wait(&p->freeSemaphore); - BtFillBlock(mt, blockIndex++); - Semaphore_Release1(&p->filledSemaphore); - } - } -} - -void MatchFinderMt_Construct(CMatchFinderMt *p) -{ - p->hashBuf = 0; - MtSync_Construct(&p->hashSync); - MtSync_Construct(&p->btSync); -} - -void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->hashBuf); - p->hashBuf = 0; -} - -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) -{ - MtSync_Destruct(&p->hashSync); - MtSync_Destruct(&p->btSync); - MatchFinderMt_FreeMem(p, alloc); -} - -#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) -#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) -{ - Byte allocaDummy[0x180]; - allocaDummy[0] = 0; - allocaDummy[1] = allocaDummy[0]; - BtThreadFunc((CMatchFinderMt *)p); - return 0; -} - -SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) -{ - CMatchFinder *mf = p->MatchFinder; - p->historySize = historySize; - if (kMtBtBlockSize <= matchMaxLen * 4) - return SZ_ERROR_PARAM; - if (p->hashBuf == 0) - { - p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); - if (p->hashBuf == 0) - return SZ_ERROR_MEM; - p->btBuf = p->hashBuf + kHashBufferSize; - } - keepAddBufferBefore += (kHashBufferSize + kBtBufferSize); - keepAddBufferAfter += kMtHashBlockSize; - if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) - return SZ_ERROR_MEM; - - RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks)); - RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks)); - return SZ_OK; -} - -/* Call it after ReleaseStream / SetStream */ -void MatchFinderMt_Init(CMatchFinderMt *p) -{ - CMatchFinder *mf = p->MatchFinder; - p->btBufPos = p->btBufPosLimit = 0; - p->hashBufPos = p->hashBufPosLimit = 0; - MatchFinder_Init(mf); - p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); - p->btNumAvailBytes = 0; - p->lzPos = p->historySize + 1; - - p->hash = mf->hash; - p->fixedHashSize = mf->fixedHashSize; - p->crc = mf->crc; - - p->son = mf->son; - p->matchMaxLen = mf->matchMaxLen; - p->numHashBytes = mf->numHashBytes; - p->pos = mf->pos; - p->buffer = mf->buffer; - p->cyclicBufferPos = mf->cyclicBufferPos; - p->cyclicBufferSize = mf->cyclicBufferSize; - p->cutValue = mf->cutValue; -} - -/* ReleaseStream is required to finish multithreading */ -void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) -{ - MtSync_StopWriting(&p->btSync); - /* p->MatchFinder->ReleaseStream(); */ -} - -void MatchFinderMt_Normalize(CMatchFinderMt *p) -{ - MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize); - p->lzPos = p->historySize + 1; -} - -void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) -{ - UInt32 blockIndex; - MtSync_GetNextBlock(&p->btSync); - blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask); - p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize; - p->btBufPosLimit += p->btBuf[p->btBufPos++]; - p->btNumAvailBytes = p->btBuf[p->btBufPos++]; - if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize) - MatchFinderMt_Normalize(p); -} - -const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) -{ - return p->pointerToCurPos; -} - -#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); - -UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) -{ - GET_NEXT_BLOCK_IF_REQUIRED; - return p->btNumAvailBytes; -} - -Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index) -{ - return p->pointerToCurPos[index]; -} - -UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 hash2Value, curMatch2; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH2_CALC - - curMatch2 = hash[hash2Value]; - hash[hash2Value] = lzPos; - - if (curMatch2 >= matchMinPos) - if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - *distances++ = 2; - *distances++ = lzPos - curMatch2 - 1; - } - return distances; -} - -UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 hash2Value, hash3Value, curMatch2, curMatch3; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH3_CALC - - curMatch2 = hash[ hash2Value]; - curMatch3 = hash[kFix3HashSize + hash3Value]; - - hash[ hash2Value] = - hash[kFix3HashSize + hash3Value] = - lzPos; - - if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch2 - 1; - if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) - { - distances[0] = 3; - return distances + 2; - } - distances[0] = 2; - distances += 2; - } - if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) - { - *distances++ = 3; - *distances++ = lzPos - curMatch3 - 1; - } - return distances; -} - -/* -UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH4_CALC - - curMatch2 = hash[ hash2Value]; - curMatch3 = hash[kFix3HashSize + hash3Value]; - curMatch4 = hash[kFix4HashSize + hash4Value]; - - hash[ hash2Value] = - hash[kFix3HashSize + hash3Value] = - hash[kFix4HashSize + hash4Value] = - lzPos; - - if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch2 - 1; - if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) - { - distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; - return distances + 2; - } - distances[0] = 2; - distances += 2; - } - if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch3 - 1; - if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3]) - { - distances[0] = 4; - return distances + 2; - } - distances[0] = 3; - distances += 2; - } - - if (curMatch4 >= matchMinPos) - if ( - cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] && - cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3] - ) - { - *distances++ = 4; - *distances++ = lzPos - curMatch4 - 1; - } - return distances; -} -*/ - -#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; - -UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - const UInt32 *btBuf = p->btBuf + p->btBufPos; - UInt32 len = *btBuf++; - p->btBufPos += 1 + len; - p->btNumAvailBytes--; - { - UInt32 i; - for (i = 0; i < len; i += 2) - { - *distances++ = *btBuf++; - *distances++ = *btBuf++; - } - } - INCREASE_LZ_POS - return len; -} - -UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - const UInt32 *btBuf = p->btBuf + p->btBufPos; - UInt32 len = *btBuf++; - p->btBufPos += 1 + len; - - if (len == 0) - { - if (p->btNumAvailBytes-- >= 4) - len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances)); - } - else - { - /* Condition: there are matches in btBuf with length < p->numHashBytes */ - UInt32 *distances2; - p->btNumAvailBytes--; - distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); - do - { - *distances2++ = *btBuf++; - *distances2++ = *btBuf++; - } - while ((len -= 2) != 0); - len = (UInt32)(distances2 - (distances)); - } - INCREASE_LZ_POS - return len; -} - -#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED -#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; -#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); - -void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER2_MT { p->btNumAvailBytes--; - SKIP_FOOTER_MT -} - -void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(2) - UInt32 hash2Value; - MT_HASH2_CALC - hash[hash2Value] = p->lzPos; - SKIP_FOOTER_MT -} - -void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(3) - UInt32 hash2Value, hash3Value; - MT_HASH3_CALC - hash[kFix3HashSize + hash3Value] = - hash[ hash2Value] = - p->lzPos; - SKIP_FOOTER_MT -} - -/* -void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(4) - UInt32 hash2Value, hash3Value, hash4Value; - MT_HASH4_CALC - hash[kFix4HashSize + hash4Value] = - hash[kFix3HashSize + hash3Value] = - hash[ hash2Value] = - p->lzPos; - SKIP_FOOTER_MT -} -*/ - -void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) -{ - vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; - vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; - switch(p->MatchFinder->numHashBytes) - { - case 2: - p->GetHeadsFunc = GetHeads2; - p->MixMatchesFunc = (Mf_Mix_Matches)0; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; - break; - case 3: - p->GetHeadsFunc = GetHeads3; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip; - break; - default: - /* case 4: */ - p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4; - /* p->GetHeadsFunc = GetHeads4; */ - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; - break; - /* - default: - p->GetHeadsFunc = GetHeads5; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip; - break; - */ - } -} diff --git a/utils/lzma/C/LzFindMt.h b/utils/lzma/C/LzFindMt.h deleted file mode 100644 index 6a7095b0..00000000 --- a/utils/lzma/C/LzFindMt.h +++ /dev/null @@ -1,101 +0,0 @@ -/* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_MT_H -#define __LZ_FIND_MT_H - -#include "LzFind.h" -#include "Threads.h" - -EXTERN_C_BEGIN - -#define kMtHashBlockSize (1 << 13) -#define kMtHashNumBlocks (1 << 3) -#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1) - -#define kMtBtBlockSize (1 << 14) -#define kMtBtNumBlocks (1 << 6) -#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1) - -typedef struct _CMtSync -{ - Bool wasCreated; - Bool needStart; - Bool exit; - Bool stopWriting; - - CThread thread; - CAutoResetEvent canStart; - CAutoResetEvent wasStarted; - CAutoResetEvent wasStopped; - CSemaphore freeSemaphore; - CSemaphore filledSemaphore; - Bool csWasInitialized; - Bool csWasEntered; - CCriticalSection cs; - UInt32 numProcessedBlocks; -} CMtSync; - -typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); - -/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ -#define kMtCacheLineDummy 128 - -typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, - UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); - -typedef struct _CMatchFinderMt -{ - /* LZ */ - const Byte *pointerToCurPos; - UInt32 *btBuf; - UInt32 btBufPos; - UInt32 btBufPosLimit; - UInt32 lzPos; - UInt32 btNumAvailBytes; - - UInt32 *hash; - UInt32 fixedHashSize; - UInt32 historySize; - const UInt32 *crc; - - Mf_Mix_Matches MixMatchesFunc; - - /* LZ + BT */ - CMtSync btSync; - Byte btDummy[kMtCacheLineDummy]; - - /* BT */ - UInt32 *hashBuf; - UInt32 hashBufPos; - UInt32 hashBufPosLimit; - UInt32 hashNumAvail; - - CLzRef *son; - UInt32 matchMaxLen; - UInt32 numHashBytes; - UInt32 pos; - Byte *buffer; - UInt32 cyclicBufferPos; - UInt32 cyclicBufferSize; /* it must be historySize + 1 */ - UInt32 cutValue; - - /* BT + Hash */ - CMtSync hashSync; - /* Byte hashDummy[kMtCacheLineDummy]; */ - - /* Hash */ - Mf_GetHeads GetHeadsFunc; - CMatchFinder *MatchFinder; -} CMatchFinderMt; - -void MatchFinderMt_Construct(CMatchFinderMt *p); -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); -SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); -void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); -void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/LzHash.h b/utils/lzma/C/LzHash.h deleted file mode 100644 index f3e89966..00000000 --- a/utils/lzma/C/LzHash.h +++ /dev/null @@ -1,54 +0,0 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZ_HASH_H -#define __LZ_HASH_H - -#define kHash2Size (1 << 10) -#define kHash3Size (1 << 16) -#define kHash4Size (1 << 20) - -#define kFix3HashSize (kHash2Size) -#define kFix4HashSize (kHash2Size + kHash3Size) -#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) - -#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); - -#define HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } - -#define HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } - -#define HASH5_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ - hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ - hash4Value &= (kHash4Size - 1); } - -/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; - - -#define MT_HASH2_CALC \ - hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); - -#define MT_HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } - -#define MT_HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } - -#endif diff --git a/utils/lzma/C/Lzma2Dec.c b/utils/lzma/C/Lzma2Dec.c deleted file mode 100644 index 502a1588..00000000 --- a/utils/lzma/C/Lzma2Dec.c +++ /dev/null @@ -1,352 +0,0 @@ -/* Lzma2Dec.c -- LZMA2 Decoder -2010-12-15 : Igor Pavlov : Public domain */ - -/* #define SHOW_DEBUG_INFO */ - -#include "Precomp.h" - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include - -#include "Lzma2Dec.h" - -/* -00000000 - EOS -00000001 U U - Uncompressed Reset Dic -00000010 U U - Uncompressed No Reset -100uuuuu U U P P - LZMA no reset -101uuuuu U U P P - LZMA reset state -110uuuuu U U P P S - LZMA reset state + new prop -111uuuuu U U P P S - LZMA reset state + new prop + reset dic - - u, U - Unpack Size - P - Pack Size - S - Props -*/ - -#define LZMA2_CONTROL_LZMA (1 << 7) -#define LZMA2_CONTROL_COPY_NO_RESET 2 -#define LZMA2_CONTROL_COPY_RESET_DIC 1 -#define LZMA2_CONTROL_EOF 0 - -#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) - -#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) -#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) - -#define LZMA2_LCLP_MAX 4 -#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -typedef enum -{ - LZMA2_STATE_CONTROL, - LZMA2_STATE_UNPACK0, - LZMA2_STATE_UNPACK1, - LZMA2_STATE_PACK0, - LZMA2_STATE_PACK1, - LZMA2_STATE_PROP, - LZMA2_STATE_DATA, - LZMA2_STATE_DATA_CONT, - LZMA2_STATE_FINISHED, - LZMA2_STATE_ERROR -} ELzma2State; - -static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) -{ - UInt32 dicSize; - if (prop > 40) - return SZ_ERROR_UNSUPPORTED; - dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); - props[0] = (Byte)LZMA2_LCLP_MAX; - props[1] = (Byte)(dicSize); - props[2] = (Byte)(dicSize >> 8); - props[3] = (Byte)(dicSize >> 16); - props[4] = (Byte)(dicSize >> 24); - return SZ_OK; -} - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) -{ - Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) -{ - Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -void Lzma2Dec_Init(CLzma2Dec *p) -{ - p->state = LZMA2_STATE_CONTROL; - p->needInitDic = True; - p->needInitState = True; - p->needInitProp = True; - LzmaDec_Init(&p->decoder); -} - -static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) -{ - switch(p->state) - { - case LZMA2_STATE_CONTROL: - p->control = b; - PRF(printf("\n %4X ", p->decoder.dicPos)); - PRF(printf(" %2X", b)); - if (p->control == 0) - return LZMA2_STATE_FINISHED; - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if ((p->control & 0x7F) > 2) - return LZMA2_STATE_ERROR; - p->unpackSize = 0; - } - else - p->unpackSize = (UInt32)(p->control & 0x1F) << 16; - return LZMA2_STATE_UNPACK0; - - case LZMA2_STATE_UNPACK0: - p->unpackSize |= (UInt32)b << 8; - return LZMA2_STATE_UNPACK1; - - case LZMA2_STATE_UNPACK1: - p->unpackSize |= (UInt32)b; - p->unpackSize++; - PRF(printf(" %8d", p->unpackSize)); - return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; - - case LZMA2_STATE_PACK0: - p->packSize = (UInt32)b << 8; - return LZMA2_STATE_PACK1; - - case LZMA2_STATE_PACK1: - p->packSize |= (UInt32)b; - p->packSize++; - PRF(printf(" %8d", p->packSize)); - return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: - (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); - - case LZMA2_STATE_PROP: - { - int lc, lp; - if (b >= (9 * 5 * 5)) - return LZMA2_STATE_ERROR; - lc = b % 9; - b /= 9; - p->decoder.prop.pb = b / 5; - lp = b % 5; - if (lc + lp > LZMA2_LCLP_MAX) - return LZMA2_STATE_ERROR; - p->decoder.prop.lc = lc; - p->decoder.prop.lp = lp; - p->needInitProp = False; - return LZMA2_STATE_DATA; - } - } - return LZMA2_STATE_ERROR; -} - -static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) -{ - memcpy(p->dic + p->dicPos, src, size); - p->dicPos += size; - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) - p->checkDicSize = p->prop.dicSize; - p->processedPos += (UInt32)size; -} - -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT inSize = *srcLen; - *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->state != LZMA2_STATE_FINISHED) - { - SizeT dicPos = p->decoder.dicPos; - if (p->state == LZMA2_STATE_ERROR) - return SZ_ERROR_DATA; - if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - (*srcLen)++; - p->state = Lzma2Dec_UpdateState(p, *src++); - continue; - } - { - SizeT destSizeCur = dicLimit - dicPos; - SizeT srcSizeCur = inSize - *srcLen; - ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; - - if (p->unpackSize <= destSizeCur) - { - destSizeCur = (SizeT)p->unpackSize; - curFinishMode = LZMA_FINISH_END; - } - - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - - if (p->state == LZMA2_STATE_DATA) - { - Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); - if (initDic) - p->needInitProp = p->needInitState = True; - else if (p->needInitDic) - return SZ_ERROR_DATA; - p->needInitDic = False; - LzmaDec_InitDicAndState(&p->decoder, initDic, False); - } - - if (srcSizeCur > destSizeCur) - srcSizeCur = destSizeCur; - - if (srcSizeCur == 0) - return SZ_ERROR_DATA; - - LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->unpackSize -= (UInt32)srcSizeCur; - p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; - } - else - { - SizeT outSizeProcessed; - SRes res; - - if (p->state == LZMA2_STATE_DATA) - { - int mode = LZMA2_GET_LZMA_MODE(p); - Bool initDic = (mode == 3); - Bool initState = (mode > 0); - if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) - return SZ_ERROR_DATA; - - LzmaDec_InitDicAndState(&p->decoder, initDic, initState); - p->needInitDic = False; - p->needInitState = False; - p->state = LZMA2_STATE_DATA_CONT; - } - if (srcSizeCur > p->packSize) - srcSizeCur = (SizeT)p->packSize; - - res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->packSize -= (UInt32)srcSizeCur; - - outSizeProcessed = p->decoder.dicPos - dicPos; - p->unpackSize -= (UInt32)outSizeProcessed; - - RINOK(res); - if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) - return res; - - if (srcSizeCur == 0 && outSizeProcessed == 0) - { - if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || - p->unpackSize != 0 || p->packSize != 0) - return SZ_ERROR_DATA; - p->state = LZMA2_STATE_CONTROL; - } - if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - *status = LZMA_STATUS_NOT_FINISHED; - } - } - } - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return SZ_OK; -} - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT outSize = *destLen, inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - SizeT srcSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->decoder.dicPos == p->decoder.dicBufSize) - p->decoder.dicPos = 0; - dicPos = p->decoder.dicPos; - if (outSize > p->decoder.dicBufSize - dicPos) - { - outSizeCur = p->decoder.dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); - src += srcSizeCur; - inSize -= srcSizeCur; - *srcLen += srcSizeCur; - outSizeCur = p->decoder.dicPos - dicPos; - memcpy(dest, p->decoder.dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzma2Dec p; - SRes res; - SizeT outSize = *destLen, inSize = *srcLen; - *destLen = *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - Lzma2Dec_Construct(&p); - RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); - p.decoder.dic = dest; - p.decoder.dicBufSize = outSize; - Lzma2Dec_Init(&p); - *srcLen = inSize; - res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - *destLen = p.decoder.dicPos; - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - Lzma2Dec_FreeProbs(&p, alloc); - return res; -} diff --git a/utils/lzma/C/Lzma2Dec.h b/utils/lzma/C/Lzma2Dec.h deleted file mode 100644 index 367daf6b..00000000 --- a/utils/lzma/C/Lzma2Dec.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Lzma2Dec.h -- LZMA2 Decoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA2_DEC_H -#define __LZMA2_DEC_H - -#include "LzmaDec.h" - -EXTERN_C_BEGIN - -/* ---------- State Interface ---------- */ - -typedef struct -{ - CLzmaDec decoder; - UInt32 packSize; - UInt32 unpackSize; - int state; - Byte control; - Bool needInitDic; - Bool needInitState; - Bool needInitProp; -} CLzma2Dec; - -#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) -#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); -#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); -void Lzma2Dec_Init(CLzma2Dec *p); - - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen or dicLimit). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - SZ_ERROR_DATA - Data error -*/ - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Lzma2Enc.c b/utils/lzma/C/Lzma2Enc.c deleted file mode 100644 index 0c8e02e9..00000000 --- a/utils/lzma/C/Lzma2Enc.c +++ /dev/null @@ -1,493 +0,0 @@ -/* Lzma2Enc.c -- LZMA2 Encoder -2012-06-19 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -/* #include */ -#include - -/* #define _7ZIP_ST */ - -#include "Lzma2Enc.h" - -#ifndef _7ZIP_ST -#include "MtCoder.h" -#else -#define NUM_MT_CODER_THREADS_MAX 1 -#endif - -#define LZMA2_CONTROL_LZMA (1 << 7) -#define LZMA2_CONTROL_COPY_NO_RESET 2 -#define LZMA2_CONTROL_COPY_RESET_DIC 1 -#define LZMA2_CONTROL_EOF 0 - -#define LZMA2_LCLP_MAX 4 - -#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) - -#define LZMA2_PACK_SIZE_MAX (1 << 16) -#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX -#define LZMA2_UNPACK_SIZE_MAX (1 << 21) -#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX - -#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16) - - -#define PRF(x) /* x */ - -/* ---------- CLzma2EncInt ---------- */ - -typedef struct -{ - CLzmaEncHandle enc; - UInt64 srcPos; - Byte props; - Bool needInitState; - Bool needInitProp; -} CLzma2EncInt; - -static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props) -{ - Byte propsEncoded[LZMA_PROPS_SIZE]; - SizeT propsSize = LZMA_PROPS_SIZE; - RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)); - RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)); - p->srcPos = 0; - p->props = propsEncoded[0]; - p->needInitState = True; - p->needInitProp = True; - return SZ_OK; -} - -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, - Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); -void LzmaEnc_Finish(CLzmaEncHandle pp); -void LzmaEnc_SaveState(CLzmaEncHandle pp); -void LzmaEnc_RestoreState(CLzmaEncHandle pp); - - -static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, - size_t *packSizeRes, ISeqOutStream *outStream) -{ - size_t packSizeLimit = *packSizeRes; - size_t packSize = packSizeLimit; - UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; - unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); - Bool useCopyBlock; - SRes res; - - *packSizeRes = 0; - if (packSize < lzHeaderSize) - return SZ_ERROR_OUTPUT_EOF; - packSize -= lzHeaderSize; - - LzmaEnc_SaveState(p->enc); - res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, - outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); - - PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); - - if (unpackSize == 0) - return res; - - if (res == SZ_OK) - useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16)); - else - { - if (res != SZ_ERROR_OUTPUT_EOF) - return res; - res = SZ_OK; - useCopyBlock = True; - } - - if (useCopyBlock) - { - size_t destPos = 0; - PRF(printf("################# COPY ")); - while (unpackSize > 0) - { - UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; - if (packSizeLimit - destPos < u + 3) - return SZ_ERROR_OUTPUT_EOF; - outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); - outBuf[destPos++] = (Byte)((u - 1) >> 8); - outBuf[destPos++] = (Byte)(u - 1); - memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u); - unpackSize -= u; - destPos += u; - p->srcPos += u; - if (outStream) - { - *packSizeRes += destPos; - if (outStream->Write(outStream, outBuf, destPos) != destPos) - return SZ_ERROR_WRITE; - destPos = 0; - } - else - *packSizeRes = destPos; - /* needInitState = True; */ - } - LzmaEnc_RestoreState(p->enc); - return SZ_OK; - } - { - size_t destPos = 0; - UInt32 u = unpackSize - 1; - UInt32 pm = (UInt32)(packSize - 1); - unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); - - PRF(printf(" ")); - - outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F)); - outBuf[destPos++] = (Byte)(u >> 8); - outBuf[destPos++] = (Byte)u; - outBuf[destPos++] = (Byte)(pm >> 8); - outBuf[destPos++] = (Byte)pm; - - if (p->needInitProp) - outBuf[destPos++] = p->props; - - p->needInitProp = False; - p->needInitState = False; - destPos += packSize; - p->srcPos += unpackSize; - - if (outStream) - if (outStream->Write(outStream, outBuf, destPos) != destPos) - return SZ_ERROR_WRITE; - *packSizeRes = destPos; - return SZ_OK; - } -} - -/* ---------- Lzma2 Props ---------- */ - -void Lzma2EncProps_Init(CLzma2EncProps *p) -{ - LzmaEncProps_Init(&p->lzmaProps); - p->numTotalThreads = -1; - p->numBlockThreads = -1; - p->blockSize = 0; -} - -void Lzma2EncProps_Normalize(CLzma2EncProps *p) -{ - int t1, t1n, t2, t3; - { - CLzmaEncProps lzmaProps = p->lzmaProps; - LzmaEncProps_Normalize(&lzmaProps); - t1n = lzmaProps.numThreads; - } - - t1 = p->lzmaProps.numThreads; - t2 = p->numBlockThreads; - t3 = p->numTotalThreads; - - if (t2 > NUM_MT_CODER_THREADS_MAX) - t2 = NUM_MT_CODER_THREADS_MAX; - - if (t3 <= 0) - { - if (t2 <= 0) - t2 = 1; - t3 = t1n * t2; - } - else if (t2 <= 0) - { - t2 = t3 / t1n; - if (t2 == 0) - { - t1 = 1; - t2 = t3; - } - if (t2 > NUM_MT_CODER_THREADS_MAX) - t2 = NUM_MT_CODER_THREADS_MAX; - } - else if (t1 <= 0) - { - t1 = t3 / t2; - if (t1 == 0) - t1 = 1; - } - else - t3 = t1n * t2; - - p->lzmaProps.numThreads = t1; - - LzmaEncProps_Normalize(&p->lzmaProps); - - if (p->blockSize == 0) - { - UInt32 dictSize = p->lzmaProps.dictSize; - UInt64 blockSize = (UInt64)dictSize << 2; - const UInt32 kMinSize = (UInt32)1 << 20; - const UInt32 kMaxSize = (UInt32)1 << 28; - if (blockSize < kMinSize) blockSize = kMinSize; - if (blockSize > kMaxSize) blockSize = kMaxSize; - if (blockSize < dictSize) blockSize = dictSize; - p->blockSize = (size_t)blockSize; - } - if (t2 > 1) - { - UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1; - if (temp > p->lzmaProps.reduceSize) - { - UInt64 numBlocks = temp / p->blockSize; - if (numBlocks < t2) - { - t2 = (UInt32)numBlocks; - t3 = t1 * t2; - } - } - } - p->numBlockThreads = t2; - p->numTotalThreads = t3; -} - -static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) -{ - return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; -} - -/* ---------- Lzma2 ---------- */ - -typedef struct -{ - Byte propEncoded; - CLzma2EncProps props; - - Byte *outBuf; - - ISzAlloc *alloc; - ISzAlloc *allocBig; - - CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX]; - - #ifndef _7ZIP_ST - CMtCoder mtCoder; - #endif - -} CLzma2Enc; - - -/* ---------- Lzma2EncThread ---------- */ - -static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) -{ - UInt64 packTotal = 0; - SRes res = SZ_OK; - - if (mainEncoder->outBuf == 0) - { - mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); - if (mainEncoder->outBuf == 0) - return SZ_ERROR_MEM; - } - RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); - RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE, - mainEncoder->alloc, mainEncoder->allocBig)); - for (;;) - { - size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; - res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream); - if (res != SZ_OK) - break; - packTotal += packSize; - res = Progress(progress, p->srcPos, packTotal); - if (res != SZ_OK) - break; - if (packSize == 0) - break; - } - LzmaEnc_Finish(p->enc); - if (res == SZ_OK) - { - Byte b = 0; - if (outStream->Write(outStream, &b, 1) != 1) - return SZ_ERROR_WRITE; - } - return res; -} - -#ifndef _7ZIP_ST - -typedef struct -{ - IMtCoderCallback funcTable; - CLzma2Enc *lzma2Enc; -} CMtCallbackImp; - -static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize, - const Byte *src, size_t srcSize, int finished) -{ - CMtCallbackImp *imp = (CMtCallbackImp *)pp; - CLzma2Enc *mainEncoder = imp->lzma2Enc; - CLzma2EncInt *p = &mainEncoder->coders[index]; - - SRes res = SZ_OK; - { - size_t destLim = *destSize; - *destSize = 0; - - if (srcSize != 0) - { - RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); - - RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE, - mainEncoder->alloc, mainEncoder->allocBig)); - - while (p->srcPos < srcSize) - { - size_t packSize = destLim - *destSize; - res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL); - if (res != SZ_OK) - break; - *destSize += packSize; - - if (packSize == 0) - { - res = SZ_ERROR_FAIL; - break; - } - - if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK) - { - res = SZ_ERROR_PROGRESS; - break; - } - } - LzmaEnc_Finish(p->enc); - if (res != SZ_OK) - return res; - } - if (finished) - { - if (*destSize == destLim) - return SZ_ERROR_OUTPUT_EOF; - dest[(*destSize)++] = 0; - } - } - return res; -} - -#endif - -/* ---------- Lzma2Enc ---------- */ - -CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc)); - if (p == 0) - return NULL; - Lzma2EncProps_Init(&p->props); - Lzma2EncProps_Normalize(&p->props); - p->outBuf = 0; - p->alloc = alloc; - p->allocBig = allocBig; - { - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - p->coders[i].enc = 0; - } - #ifndef _7ZIP_ST - MtCoder_Construct(&p->mtCoder); - #endif - - return p; -} - -void Lzma2Enc_Destroy(CLzma2EncHandle pp) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - { - CLzma2EncInt *t = &p->coders[i]; - if (t->enc) - { - LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); - t->enc = 0; - } - } - - #ifndef _7ZIP_ST - MtCoder_Destruct(&p->mtCoder); - #endif - - IAlloc_Free(p->alloc, p->outBuf); - IAlloc_Free(p->alloc, pp); -} - -SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - CLzmaEncProps lzmaProps = props->lzmaProps; - LzmaEncProps_Normalize(&lzmaProps); - if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) - return SZ_ERROR_PARAM; - p->props = *props; - Lzma2EncProps_Normalize(&p->props); - return SZ_OK; -} - -Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - unsigned i; - UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); - for (i = 0; i < 40; i++) - if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i)) - break; - return (Byte)i; -} - -SRes Lzma2Enc_Encode(CLzma2EncHandle pp, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - int i; - - for (i = 0; i < p->props.numBlockThreads; i++) - { - CLzma2EncInt *t = &p->coders[i]; - if (t->enc == NULL) - { - t->enc = LzmaEnc_Create(p->alloc); - if (t->enc == NULL) - return SZ_ERROR_MEM; - } - } - - #ifndef _7ZIP_ST - if (p->props.numBlockThreads <= 1) - #endif - return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress); - - #ifndef _7ZIP_ST - - { - CMtCallbackImp mtCallback; - - mtCallback.funcTable.Code = MtCallbackImp_Code; - mtCallback.lzma2Enc = p; - - p->mtCoder.progress = progress; - p->mtCoder.inStream = inStream; - p->mtCoder.outStream = outStream; - p->mtCoder.alloc = p->alloc; - p->mtCoder.mtCallback = &mtCallback.funcTable; - - p->mtCoder.blockSize = p->props.blockSize; - p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; - p->mtCoder.numThreads = p->props.numBlockThreads; - - return MtCoder_Code(&p->mtCoder); - } - #endif -} diff --git a/utils/lzma/C/Lzma2Enc.h b/utils/lzma/C/Lzma2Enc.h deleted file mode 100644 index f409f184..00000000 --- a/utils/lzma/C/Lzma2Enc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Lzma2Enc.h -- LZMA2 Encoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA2_ENC_H -#define __LZMA2_ENC_H - -#include "LzmaEnc.h" - -EXTERN_C_BEGIN - -typedef struct -{ - CLzmaEncProps lzmaProps; - size_t blockSize; - int numBlockThreads; - int numTotalThreads; -} CLzma2EncProps; - -void Lzma2EncProps_Init(CLzma2EncProps *p); -void Lzma2EncProps_Normalize(CLzma2EncProps *p); - -/* ---------- CLzmaEnc2Handle Interface ---------- */ - -/* Lzma2Enc_* functions can return the following exit codes: -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error - SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -typedef void * CLzma2EncHandle; - -CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig); -void Lzma2Enc_Destroy(CLzma2EncHandle p); -SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); -Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); -SRes Lzma2Enc_Encode(CLzma2EncHandle p, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress); - -/* ---------- One Call Interface ---------- */ - -/* Lzma2Encode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -/* -SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -*/ - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Lzma86.h b/utils/lzma/C/Lzma86.h deleted file mode 100644 index bebed5cb..00000000 --- a/utils/lzma/C/Lzma86.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Lzma86.h -- LZMA + x86 (BCJ) Filter -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA86_H -#define __LZMA86_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define LZMA86_SIZE_OFFSET (1 + 5) -#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) - -/* -It's an example for LZMA + x86 Filter use. -You can use .lzma86 extension, if you write that stream to file. -.lzma86 header adds one additional byte to standard .lzma header. -.lzma86 header (14 bytes): - Offset Size Description - 0 1 = 0 - no filter, pure LZMA - = 1 - x86 filter + LZMA - 1 1 lc, lp and pb in encoded form - 2 4 dictSize (little endian) - 6 8 uncompressed size (little endian) - - -Lzma86_Encode -------------- -level - compression level: 0 <= level <= 9, the default value for "level" is 5. - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes, for level = 5. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - For better compression ratio dictSize must be >= inSize. - -filterMode: - SZ_FILTER_NO - no Filter - SZ_FILTER_YES - x86 Filter - SZ_FILTER_AUTO - it tries both alternatives to select best. - Encoder will use 2 or 3 passes: - 2 passes when FILTER_NO provides better compression. - 3 passes when FILTER_YES provides better compression. - -Lzma86Encode allocates Data with MyAlloc functions. -RAM Requirements for compressing: - RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize - filterMode FilterBlockSize - SZ_FILTER_NO 0 - SZ_FILTER_YES inSize - SZ_FILTER_AUTO inSize - - -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -enum ESzFilterMode -{ - SZ_FILTER_NO, - SZ_FILTER_YES, - SZ_FILTER_AUTO -}; - -SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode); - - -/* -Lzma86_GetUnpackSize: - In: - src - input data - srcLen - input data size - Out: - unpackSize - size of uncompressed stream - Return code: - SZ_OK - OK - SZ_ERROR_INPUT_EOF - Error in headers -*/ - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); - -/* -Lzma86_Decode: - In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size - Out: - destLen - processed output size - srcLen - processed input size - Return code: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - unsupported file - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer -*/ - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Lzma86Dec.c b/utils/lzma/C/Lzma86Dec.c deleted file mode 100644 index fe772609..00000000 --- a/utils/lzma/C/Lzma86Dec.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2009-08-14 : Igor Pavlov : Public domain */ - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaDec.h" - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) -{ - unsigned i; - if (srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - *unpackSize = 0; - for (i = 0; i < sizeof(UInt64); i++) - *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); - return SZ_OK; -} - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) -{ - ISzAlloc g_Alloc = { SzAlloc, SzFree }; - SRes res; - int useFilter; - SizeT inSizePure; - ELzmaStatus status; - - if (*srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - - useFilter = src[0]; - - if (useFilter > 1) - { - *destLen = 0; - return SZ_ERROR_UNSUPPORTED; - } - - inSizePure = *srcLen - LZMA86_HEADER_SIZE; - res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, - src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); - *srcLen = inSizePure + LZMA86_HEADER_SIZE; - if (res != SZ_OK) - return res; - if (useFilter == 1) - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(dest, *destLen, 0, &x86State, 0); - } - return SZ_OK; -} diff --git a/utils/lzma/C/Lzma86Enc.c b/utils/lzma/C/Lzma86Enc.c deleted file mode 100644 index 16467149..00000000 --- a/utils/lzma/C/Lzma86Enc.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2009-08-14 : Igor Pavlov : Public domain */ - -#include - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaEnc.h" - -#define SZE_OUT_OVERFLOW SZE_DATA_ERROR - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } - -int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode) -{ - ISzAlloc g_Alloc = { SzAlloc, SzFree }; - size_t outSize2 = *destLen; - Byte *filteredStream; - Bool useFilter; - int mainResult = SZ_ERROR_OUTPUT_EOF; - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - - *destLen = 0; - if (outSize2 < LZMA86_HEADER_SIZE) - return SZ_ERROR_OUTPUT_EOF; - - { - int i; - UInt64 t = srcLen; - for (i = 0; i < 8; i++, t >>= 8) - dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; - } - - filteredStream = 0; - useFilter = (filterMode != SZ_FILTER_NO); - if (useFilter) - { - if (srcLen != 0) - { - filteredStream = (Byte *)MyAlloc(srcLen); - if (filteredStream == 0) - return SZ_ERROR_MEM; - memcpy(filteredStream, src, srcLen); - } - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(filteredStream, srcLen, 0, &x86State, 1); - } - } - - { - size_t minSize = 0; - Bool bestIsFiltered = False; - - /* passes for SZ_FILTER_AUTO: - 0 - BCJ + LZMA - 1 - LZMA - 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. - */ - int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; - - int i; - for (i = 0; i < numPasses; i++) - { - size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; - size_t outPropsSize = 5; - SRes curRes; - Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); - if (curModeIsFiltered && !bestIsFiltered) - break; - if (useFilter && i == 0) - curModeIsFiltered = True; - - curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, - curModeIsFiltered ? filteredStream : src, srcLen, - &props, dest + 1, &outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); - - if (curRes != SZ_ERROR_OUTPUT_EOF) - { - if (curRes != SZ_OK) - { - mainResult = curRes; - break; - } - if (outSizeProcessed <= minSize || mainResult != SZ_OK) - { - minSize = outSizeProcessed; - bestIsFiltered = curModeIsFiltered; - mainResult = SZ_OK; - } - } - } - dest[0] = (Byte)(bestIsFiltered ? 1 : 0); - *destLen = LZMA86_HEADER_SIZE + minSize; - } - if (useFilter) - MyFree(filteredStream); - return mainResult; -} diff --git a/utils/lzma/C/LzmaDec.c b/utils/lzma/C/LzmaDec.c deleted file mode 100644 index bbf650de..00000000 --- a/utils/lzma/C/LzmaDec.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* LzmaDec.c -- LZMA Decoder -2015-01-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "LzmaDec.h" - -#include - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_INIT_SIZE 5 - -#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) - -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -#define TREE_DECODE(probs, limit, i) \ - { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } - -/* #define _LZMA_SIZE_OPT */ - -#ifdef _LZMA_SIZE_OPT -#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -#else -#define TREE_6_DECODE(probs, i) \ - { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - i -= 0x40; } -#endif - -#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) -#define MATCHED_LITER_DEC \ - matchByte <<= 1; \ - bit = (matchByte & offs); \ - probLit = prob + offs + bit + symbol; \ - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) - -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0_CHECK range = bound; -#define UPDATE_1_CHECK range -= bound; code -= bound; -#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -#define TREE_DECODE_CHECK(probs, limit, i) \ - { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -#define LZMA_DIC_MIN (1 << 12) - -/* First LZMA-symbol is always decoded. -And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -Out: - Result: - SZ_OK - OK - SZ_ERROR_DATA - Error - p->remainLen: - < kMatchSpecLenStart : normal remain - = kMatchSpecLenStart : finished - = kMatchSpecLenStart + 1 : Flush marker - = kMatchSpecLenStart + 2 : State Init Marker -*/ - -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - CLzmaProb *probs = p->probs; - - unsigned state = p->state; - UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; - unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; - unsigned lc = p->prop.lc; - - Byte *dic = p->dic; - SizeT dicBufSize = p->dicBufSize; - SizeT dicPos = p->dicPos; - - UInt32 processedPos = p->processedPos; - UInt32 checkDicSize = p->checkDicSize; - unsigned len = 0; - - const Byte *buf = p->buf; - UInt32 range = p->range; - UInt32 code = p->code; - - do - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = processedPos & pbMask; - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - unsigned symbol; - UPDATE_0(prob); - prob = probs + Literal; - if (checkDicSize != 0 || processedPos != 0) - prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); - - if (state < kNumLitStates) - { - state -= (state < 4) ? state : 3; - symbol = 1; - #ifdef _LZMA_SIZE_OPT - do { NORMAL_LITER_DEC } while (symbol < 0x100); - #else - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - #endif - } - else - { - unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - unsigned offs = 0x100; - state -= (state < 10) ? 3 : 6; - symbol = 1; - #ifdef _LZMA_SIZE_OPT - do - { - unsigned bit; - CLzmaProb *probLit; - MATCHED_LITER_DEC - } - while (symbol < 0x100); - #else - { - unsigned bit; - CLzmaProb *probLit; - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - } - #endif - } - dic[dicPos++] = (Byte)symbol; - processedPos++; - continue; - } - else - { - UPDATE_1(prob); - prob = probs + IsRep + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - state += kNumStates; - prob = probs + LenCoder; - } - else - { - UPDATE_1(prob); - if (checkDicSize == 0 && processedPos == 0) - return SZ_ERROR_DATA; - prob = probs + IsRepG0 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - UPDATE_0(prob); - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - processedPos++; - state = state < kNumLitStates ? 9 : 11; - continue; - } - UPDATE_1(prob); - } - else - { - UInt32 distance; - UPDATE_1(prob); - prob = probs + IsRepG1 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep1; - } - else - { - UPDATE_1(prob); - prob = probs + IsRepG2 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep2; - } - else - { - UPDATE_1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = (1 << kLenNumLowBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenChoice2; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = (1 << kLenNumMidBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = (1 << kLenNumHighBits); - } - } - TREE_DECODE(probLen, limit, len); - len += offset; - } - - if (state >= kNumStates) - { - UInt32 distance; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); - if (distance >= kStartPosModelIndex) - { - unsigned posSlot = (unsigned)distance; - int numDirectBits = (int)(((distance >> 1) - 1)); - distance = (2 | (distance & 1)); - if (posSlot < kEndPosModelIndex) - { - distance <<= numDirectBits; - prob = probs + SpecPos + distance - posSlot - 1; - { - UInt32 mask = 1; - unsigned i = 1; - do - { - GET_BIT2(prob + i, i, ; , distance |= mask); - mask <<= 1; - } - while (--numDirectBits != 0); - } - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE - range >>= 1; - - { - UInt32 t; - code -= range; - t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ - distance = (distance << 1) + (t + 1); - code += range & t; - } - /* - distance <<= 1; - if (code >= range) - { - code -= range; - distance |= 1; - } - */ - } - while (--numDirectBits != 0); - prob = probs + Align; - distance <<= kNumAlignBits; - { - unsigned i = 1; - GET_BIT2(prob + i, i, ; , distance |= 1); - GET_BIT2(prob + i, i, ; , distance |= 2); - GET_BIT2(prob + i, i, ; , distance |= 4); - GET_BIT2(prob + i, i, ; , distance |= 8); - } - if (distance == (UInt32)0xFFFFFFFF) - { - len += kMatchSpecLenStart; - state -= kNumStates; - break; - } - } - } - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (checkDicSize == 0) - { - if (distance >= processedPos) - return SZ_ERROR_DATA; - } - else if (distance >= checkDicSize) - return SZ_ERROR_DATA; - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - } - - len += kMatchMinLen; - - if (limit == dicPos) - return SZ_ERROR_DATA; - { - SizeT rem = limit - dicPos; - unsigned curLen = ((rem < len) ? (unsigned)rem : len); - SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); - - processedPos += curLen; - - len -= curLen; - if (pos + curLen <= dicBufSize) - { - Byte *dest = dic + dicPos; - ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; - const Byte *lim = dest + curLen; - dicPos += curLen; - do - *(dest) = (Byte)*(dest + src); - while (++dest != lim); - } - else - { - do - { - dic[dicPos++] = dic[pos]; - if (++pos == dicBufSize) - pos = 0; - } - while (--curLen != 0); - } - } - } - } - while (dicPos < limit && buf < bufLimit); - NORMALIZE; - p->buf = buf; - p->range = range; - p->code = code; - p->remainLen = len; - p->dicPos = dicPos; - p->processedPos = processedPos; - p->reps[0] = rep0; - p->reps[1] = rep1; - p->reps[2] = rep2; - p->reps[3] = rep3; - p->state = state; - - return SZ_OK; -} - -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -{ - if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) - { - Byte *dic = p->dic; - SizeT dicPos = p->dicPos; - SizeT dicBufSize = p->dicBufSize; - unsigned len = p->remainLen; - UInt32 rep0 = p->reps[0]; - if (limit - dicPos < len) - len = (unsigned)(limit - dicPos); - - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) - p->checkDicSize = p->prop.dicSize; - - p->processedPos += len; - p->remainLen -= len; - while (len != 0) - { - len--; - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - } - p->dicPos = dicPos; - } -} - -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - do - { - SizeT limit2 = limit; - if (p->checkDicSize == 0) - { - UInt32 rem = p->prop.dicSize - p->processedPos; - if (limit - p->dicPos > rem) - limit2 = p->dicPos + rem; - } - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); - if (p->processedPos >= p->prop.dicSize) - p->checkDicSize = p->prop.dicSize; - LzmaDec_WriteRem(p, limit); - } - while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); - - if (p->remainLen > kMatchSpecLenStart) - { - p->remainLen = kMatchSpecLenStart; - } - return 0; -} - -typedef enum -{ - DUMMY_ERROR, /* unexpected end of input stream */ - DUMMY_LIT, - DUMMY_MATCH, - DUMMY_REP -} ELzmaDummy; - -static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -{ - UInt32 range = p->range; - UInt32 code = p->code; - const Byte *bufLimit = buf + inSize; - CLzmaProb *probs = p->probs; - unsigned state = p->state; - ELzmaDummy res; - - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK - - /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ - - prob = probs + Literal; - if (p->checkDicSize != 0 || p->processedPos != 0) - prob += (LZMA_LIT_SIZE * - ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + - (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); - - if (state < kNumLitStates) - { - unsigned symbol = 1; - do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[p->dicPos - p->reps[0] + - ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; - unsigned offs = 0x100; - unsigned symbol = 1; - do - { - unsigned bit; - CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - res = DUMMY_LIT; - } - else - { - unsigned len; - UPDATE_1_CHECK; - - prob = probs + IsRep + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - state = 0; - prob = probs + LenCoder; - res = DUMMY_MATCH; - } - else - { - UPDATE_1_CHECK; - res = DUMMY_REP; - prob = probs + IsRepG0 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - NORMALIZE_CHECK; - return DUMMY_REP; - } - else - { - UPDATE_1_CHECK; - } - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG1 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG2 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - } - } - } - state = kNumStates; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = 1 << kLenNumLowBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenChoice2; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = 1 << kLenNumMidBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = 1 << kLenNumHighBits; - } - } - TREE_DECODE_CHECK(probLen, limit, len); - len += offset; - } - - if (state < 4) - { - unsigned posSlot; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - - /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ - - if (posSlot < kEndPosModelIndex) - { - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE_CHECK - range >>= 1; - code -= range & (((code - range) >> 31) - 1); - /* if (code >= range) code -= range; */ - } - while (--numDirectBits != 0); - prob = probs + Align; - numDirectBits = kNumAlignBits; - } - { - unsigned i = 1; - do - { - GET_BIT_CHECK(prob + i, i); - } - while (--numDirectBits != 0); - } - } - } - } - } - NORMALIZE_CHECK; - return res; -} - - -static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -{ - p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); - p->range = 0xFFFFFFFF; - p->needFlush = 0; -} - -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -{ - p->needFlush = 1; - p->remainLen = 0; - p->tempBufSize = 0; - - if (initDic) - { - p->processedPos = 0; - p->checkDicSize = 0; - p->needInitState = 1; - } - if (initState) - p->needInitState = 1; -} - -void LzmaDec_Init(CLzmaDec *p) -{ - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); -} - -static void LzmaDec_InitStateReal(CLzmaDec *p) -{ - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); - UInt32 i; - CLzmaProb *probs = p->probs; - for (i = 0; i < numProbs; i++) - probs[i] = kBitModelTotal >> 1; - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; - p->state = 0; - p->needInitState = 0; -} - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT inSize = *srcLen; - (*srcLen) = 0; - LzmaDec_WriteRem(p, dicLimit); - - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->remainLen != kMatchSpecLenStart) - { - int checkEndMarkNow; - - if (p->needFlush != 0) - { - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) - p->tempBuf[p->tempBufSize++] = *src++; - if (p->tempBufSize < RC_INIT_SIZE) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (p->tempBuf[0] != 0) - return SZ_ERROR_DATA; - - LzmaDec_InitRc(p, p->tempBuf); - p->tempBufSize = 0; - } - - checkEndMarkNow = 0; - if (p->dicPos >= dicLimit) - { - if (p->remainLen == 0 && p->code == 0) - { - *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; - return SZ_OK; - } - if (finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->remainLen != 0) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - checkEndMarkNow = 1; - } - - if (p->needInitState) - LzmaDec_InitStateReal(p); - - if (p->tempBufSize == 0) - { - SizeT processed; - const Byte *bufLimit; - if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, src, inSize); - if (dummyRes == DUMMY_ERROR) - { - memcpy(p->tempBuf, src, inSize); - p->tempBufSize = (unsigned)inSize; - (*srcLen) += inSize; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - bufLimit = src; - } - else - bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; - p->buf = src; - if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) - return SZ_ERROR_DATA; - processed = (SizeT)(p->buf - src); - (*srcLen) += processed; - src += processed; - inSize -= processed; - } - else - { - unsigned rem = p->tempBufSize, lookAhead = 0; - while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) - p->tempBuf[rem++] = src[lookAhead++]; - p->tempBufSize = rem; - if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); - if (dummyRes == DUMMY_ERROR) - { - (*srcLen) += lookAhead; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - } - p->buf = p->tempBuf; - if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) - return SZ_ERROR_DATA; - lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); - (*srcLen) += lookAhead; - src += lookAhead; - inSize -= lookAhead; - p->tempBufSize = 0; - } - } - if (p->code == 0) - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -} - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT outSize = *destLen; - SizeT inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - SizeT inSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->dicPos == p->dicBufSize) - p->dicPos = 0; - dicPos = p->dicPos; - if (outSize > p->dicBufSize - dicPos) - { - outSizeCur = p->dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); - src += inSizeCur; - inSize -= inSizeCur; - *srcLen += inSizeCur; - outSizeCur = p->dicPos - dicPos; - memcpy(dest, p->dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->probs); - p->probs = 0; -} - -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->dic); - p->dic = 0; -} - -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -{ - LzmaDec_FreeProbs(p, alloc); - LzmaDec_FreeDict(p, alloc); -} - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -{ - UInt32 dicSize; - Byte d; - - if (size < LZMA_PROPS_SIZE) - return SZ_ERROR_UNSUPPORTED; - else - dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); - - if (dicSize < LZMA_DIC_MIN) - dicSize = LZMA_DIC_MIN; - p->dicSize = dicSize; - - d = data[0]; - if (d >= (9 * 5 * 5)) - return SZ_ERROR_UNSUPPORTED; - - p->lc = d % 9; - d /= 9; - p->pb = d / 5; - p->lp = d % 5; - - return SZ_OK; -} - -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -{ - UInt32 numProbs = LzmaProps_GetNumProbs(propNew); - if (p->probs == 0 || numProbs != p->numProbs) - { - LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); - p->numProbs = numProbs; - if (p->probs == 0) - return SZ_ERROR_MEM; - } - return SZ_OK; -} - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - dicBufSize = propNew.dicSize; - if (p->dic == 0 || dicBufSize != p->dicBufSize) - { - LzmaDec_FreeDict(p, alloc); - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); - if (p->dic == 0) - { - LzmaDec_FreeProbs(p, alloc); - return SZ_ERROR_MEM; - } - } - p->dicBufSize = dicBufSize; - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzmaDec p; - SRes res; - SizeT outSize = *destLen, inSize = *srcLen; - *destLen = *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - if (inSize < RC_INIT_SIZE) - return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); - p.dic = dest; - p.dicBufSize = outSize; - LzmaDec_Init(&p); - *srcLen = inSize; - res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - *destLen = p.dicPos; - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - LzmaDec_FreeProbs(&p, alloc); - return res; -} diff --git a/utils/lzma/C/LzmaDec.h b/utils/lzma/C/LzmaDec.h deleted file mode 100644 index cc44daef..00000000 --- a/utils/lzma/C/LzmaDec.h +++ /dev/null @@ -1,227 +0,0 @@ -/* LzmaDec.h -- LZMA Decoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, - but memory usage for CLzmaDec::probs will be doubled in that case */ - -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 -#else -#define CLzmaProb UInt16 -#endif - - -/* ---------- LZMA Properties ---------- */ - -#define LZMA_PROPS_SIZE 5 - -typedef struct _CLzmaProps -{ - unsigned lc, lp, pb; - UInt32 dicSize; -} CLzmaProps; - -/* LzmaProps_Decode - decodes properties -Returns: - SZ_OK - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); - - -/* ---------- LZMA Decoder state ---------- */ - -/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. - Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ - -#define LZMA_REQUIRED_INPUT_MAX 20 - -typedef struct -{ - CLzmaProps prop; - CLzmaProb *probs; - Byte *dic; - const Byte *buf; - UInt32 range, code; - SizeT dicPos; - SizeT dicBufSize; - UInt32 processedPos; - UInt32 checkDicSize; - unsigned state; - UInt32 reps[4]; - unsigned remainLen; - int needFlush; - int needInitState; - UInt32 numProbs; - unsigned tempBufSize; - Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -} CLzmaDec; - -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - -void LzmaDec_Init(CLzmaDec *p); - -/* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - -typedef enum -{ - LZMA_FINISH_ANY, /* finish at any point */ - LZMA_FINISH_END /* block must be finished at the end */ -} ELzmaFinishMode; - -/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! - - You must use LZMA_FINISH_END, when you know that current output buffer - covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. - - If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, - and output value of destLen will be less than output buffer size limit. - You can check status result also. - - You can use multiple checks to test data integrity after full decompression: - 1) Check Result and "status" variable. - 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. - 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. - You must use correct finish mode in that case. */ - -typedef enum -{ - LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ - LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ - LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -} ELzmaStatus; - -/* ELzmaStatus is used only as output value for function call */ - - -/* ---------- Interfaces ---------- */ - -/* There are 3 levels of interfaces: - 1) Dictionary Interface - 2) Buffer Interface - 3) One Call Interface - You can select any of these interfaces, but don't mix functions from different - groups for same object. */ - - -/* There are two variants to allocate state for Dictionary Interface: - 1) LzmaDec_Allocate / LzmaDec_Free - 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs - You can use variant 2, if you set dictionary buffer manually. - For Buffer Interface you must always use variant 1. - -LzmaDec_Allocate* can return: - SZ_OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); - -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); - -/* ---------- Dictionary Interface ---------- */ - -/* You can use it, if you want to eliminate the overhead for data copying from - dictionary to some other external buffer. - You must work with CLzmaDec variables directly in this interface. - - STEPS: - LzmaDec_Constr() - LzmaDec_Allocate() - for (each new stream) - { - LzmaDec_Init() - while (it needs more decompression) - { - LzmaDec_DecodeToDic() - use data from CLzmaDec::dic and update CLzmaDec::dicPos - } - } - LzmaDec_Free() -*/ - -/* LzmaDec_DecodeToDic - - The decoding to internal dictionary buffer (CLzmaDec::dic). - You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! - -finishMode: - It has meaning only if the decoding reaches output limit (dicLimit). - LZMA_FINISH_ANY - Decode just dicLimit bytes. - LZMA_FINISH_END - Stream must be finished after dicLimit. - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error -*/ - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- Buffer Interface ---------- */ - -/* It's zlib-like interface. - See LzmaDec_DecodeToDic description for information about STEPS and return results, - but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need - to work with CLzmaDec variables manually. - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). -*/ - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* LzmaDecode - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/LzmaEnc.c b/utils/lzma/C/LzmaEnc.c deleted file mode 100644 index 37e05a95..00000000 --- a/utils/lzma/C/LzmaEnc.c +++ /dev/null @@ -1,2278 +0,0 @@ -/* LzmaEnc.c -- LZMA Encoder -2014-12-29 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -/* #define SHOW_STAT */ -/* #define SHOW_STAT2 */ - -#if defined(SHOW_STAT) || defined(SHOW_STAT2) -#include -#endif - -#include "LzmaEnc.h" - -#include "LzFind.h" -#ifndef _7ZIP_ST -#include "LzFindMt.h" -#endif - -#ifdef SHOW_STAT -static unsigned g_STAT_OFFSET = 0; -#endif - -#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) - -#define kBlockSize (9 << 10) -#define kUnpackBlockSize (1 << 18) -#define kMatchArraySize (1 << 21) -#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) - -#define kNumMaxDirectBits (31) - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 -#define kProbInitValue (kBitModelTotal >> 1) - -#define kNumMoveReducingBits 4 -#define kNumBitPriceShiftBits 4 -#define kBitPrice (1 << kNumBitPriceShiftBits) - -void LzmaEncProps_Init(CLzmaEncProps *p) -{ - p->level = 5; - p->dictSize = p->mc = 0; - p->reduceSize = (UInt64)(Int64)-1; - p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; - p->writeEndMark = 0; -} - -void LzmaEncProps_Normalize(CLzmaEncProps *p) -{ - int level = p->level; - if (level < 0) level = 5; - p->level = level; - if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); - if (p->dictSize > p->reduceSize) - { - unsigned i; - for (i = 11; i <= 30; i++) - { - if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } - if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } - } - } - if (p->lc < 0) p->lc = 3; - if (p->lp < 0) p->lp = 0; - if (p->pb < 0) p->pb = 2; - if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); - if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); - if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); - if (p->numHashBytes < 0) p->numHashBytes = 4; - if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); - if (p->numThreads < 0) - p->numThreads = - #ifndef _7ZIP_ST - ((p->btMode && p->algo) ? 2 : 1); - #else - 1; - #endif -} - -UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -{ - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); - return props.dictSize; -} - -/* #define LZMA_LOG_BSR */ -/* Define it for Intel's CPU */ - - -#ifdef LZMA_LOG_BSR - -#define kDicLogSizeMaxCompress 30 - -#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } - -UInt32 GetPosSlot1(UInt32 pos) -{ - UInt32 res; - BSR2_RET(pos, res); - return res; -} -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } - -#else - -#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) - -void LzmaEnc_FastPosInit(Byte *g_FastPos) -{ - int c = 2, slotFast; - g_FastPos[0] = 0; - g_FastPos[1] = 1; - - for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) - { - UInt32 k = (1 << ((slotFast >> 1) - 1)); - UInt32 j; - for (j = 0; j < k; j++, c++) - g_FastPos[c] = (Byte)slotFast; - } -} - -#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ - (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ - res = p->g_FastPos[pos >> i] + (i * 2); } -/* -#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ - p->g_FastPos[pos >> 6] + 12 : \ - p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -*/ - -#define GetPosSlot1(pos) p->g_FastPos[pos] -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } - -#endif - - -#define LZMA_NUM_REPS 4 - -typedef unsigned CState; - -typedef struct -{ - UInt32 price; - - CState state; - int prev1IsChar; - int prev2; - - UInt32 posPrev2; - UInt32 backPrev2; - - UInt32 posPrev; - UInt32 backPrev; - UInt32 backs[LZMA_NUM_REPS]; -} COptimal; - -#define kNumOpts (1 << 12) - -#define kNumLenToPosStates 4 -#define kNumPosSlotBits 6 -#define kDicLogSizeMin 0 -#define kDicLogSizeMax 32 -#define kDistTableSizeMax (kDicLogSizeMax * 2) - - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) -#define kAlignMask (kAlignTableSize - 1) - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) - -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 -#else -#define CLzmaProb UInt16 -#endif - -#define LZMA_PB_MAX 4 -#define LZMA_LC_MAX 8 -#define LZMA_LP_MAX 4 - -#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) - - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define LZMA_MATCH_LEN_MIN 2 -#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) - -#define kNumStates 12 - -typedef struct -{ - CLzmaProb choice; - CLzmaProb choice2; - CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; - CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; - CLzmaProb high[kLenNumHighSymbols]; -} CLenEnc; - -typedef struct -{ - CLenEnc p; - UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; - UInt32 tableSize; - UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -} CLenPriceEnc; - -typedef struct -{ - UInt32 range; - Byte cache; - UInt64 low; - UInt64 cacheSize; - Byte *buf; - Byte *bufLim; - Byte *bufBase; - ISeqOutStream *outStream; - UInt64 processed; - SRes res; -} CRangeEnc; - -typedef struct -{ - CLzmaProb *litProbs; - - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; - - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; -} CSaveState; - -typedef struct -{ - IMatchFinder matchFinder; - void *matchFinderObj; - - #ifndef _7ZIP_ST - Bool mtMode; - CMatchFinderMt matchFinderMt; - #endif - - CMatchFinder matchFinderBase; - - #ifndef _7ZIP_ST - Byte pad[128]; - #endif - - UInt32 optimumEndIndex; - UInt32 optimumCurrentIndex; - - UInt32 longestMatchLength; - UInt32 numPairs; - UInt32 numAvail; - COptimal opt[kNumOpts]; - - #ifndef LZMA_LOG_BSR - Byte g_FastPos[1 << kNumLogBits]; - #endif - - UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; - UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; - UInt32 numFastBytes; - UInt32 additionalOffset; - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; - - UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; - UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; - UInt32 alignPrices[kAlignTableSize]; - UInt32 alignPriceCount; - - UInt32 distTableSize; - - unsigned lc, lp, pb; - unsigned lpMask, pbMask; - - CLzmaProb *litProbs; - - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; - - unsigned lclp; - - Bool fastMode; - - CRangeEnc rc; - - Bool writeEndMark; - UInt64 nowPos64; - UInt32 matchPriceCount; - Bool finished; - Bool multiThread; - - SRes result; - UInt32 dictSize; - - int needInit; - - CSaveState saveState; -} CLzmaEnc; - -void LzmaEnc_SaveState(CLzmaEncHandle pp) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - CSaveState *dest = &p->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -} - -void LzmaEnc_RestoreState(CLzmaEncHandle pp) -{ - CLzmaEnc *dest = (CLzmaEnc *)pp; - const CSaveState *p = &dest->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -} - -SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); - - if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || - props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) - return SZ_ERROR_PARAM; - p->dictSize = props.dictSize; - { - unsigned fb = props.fb; - if (fb < 5) - fb = 5; - if (fb > LZMA_MATCH_LEN_MAX) - fb = LZMA_MATCH_LEN_MAX; - p->numFastBytes = fb; - } - p->lc = props.lc; - p->lp = props.lp; - p->pb = props.pb; - p->fastMode = (props.algo == 0); - p->matchFinderBase.btMode = props.btMode; - { - UInt32 numHashBytes = 4; - if (props.btMode) - { - if (props.numHashBytes < 2) - numHashBytes = 2; - else if (props.numHashBytes < 4) - numHashBytes = props.numHashBytes; - } - p->matchFinderBase.numHashBytes = numHashBytes; - } - - p->matchFinderBase.cutValue = props.mc; - - p->writeEndMark = props.writeEndMark; - - #ifndef _7ZIP_ST - /* - if (newMultiThread != _multiThread) - { - ReleaseMatchFinder(); - _multiThread = newMultiThread; - } - */ - p->multiThread = (props.numThreads > 1); - #endif - - return SZ_OK; -} - -static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; - -#define IsCharState(s) ((s) < 7) - -#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) - -#define kInfinityPrice (1 << 30) - -static void RangeEnc_Construct(CRangeEnc *p) -{ - p->outStream = 0; - p->bufBase = 0; -} - -#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) - -#define RC_BUF_SIZE (1 << 16) -static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -{ - if (p->bufBase == 0) - { - p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); - if (p->bufBase == 0) - return 0; - p->bufLim = p->bufBase + RC_BUF_SIZE; - } - return 1; -} - -static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->bufBase); - p->bufBase = 0; -} - -static void RangeEnc_Init(CRangeEnc *p) -{ - /* Stream.Init(); */ - p->low = 0; - p->range = 0xFFFFFFFF; - p->cacheSize = 1; - p->cache = 0; - - p->buf = p->bufBase; - - p->processed = 0; - p->res = SZ_OK; -} - -static void RangeEnc_FlushStream(CRangeEnc *p) -{ - size_t num; - if (p->res != SZ_OK) - return; - num = p->buf - p->bufBase; - if (num != p->outStream->Write(p->outStream, p->bufBase, num)) - p->res = SZ_ERROR_WRITE; - p->processed += num; - p->buf = p->bufBase; -} - -static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -{ - if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0) - { - Byte temp = p->cache; - do - { - Byte *buf = p->buf; - *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); - p->buf = buf; - if (buf == p->bufLim) - RangeEnc_FlushStream(p); - temp = 0xFF; - } - while (--p->cacheSize != 0); - p->cache = (Byte)((UInt32)p->low >> 24); - } - p->cacheSize++; - p->low = (UInt32)p->low << 8; -} - -static void RangeEnc_FlushData(CRangeEnc *p) -{ - int i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); -} - -static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits) -{ - do - { - p->range >>= 1; - p->low += p->range & (0 - ((value >> --numBits) & 1)); - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); - } - } - while (numBits != 0); -} - -static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -{ - UInt32 ttt = *prob; - UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; - if (symbol == 0) - { - p->range = newBound; - ttt += (kBitModelTotal - ttt) >> kNumMoveBits; - } - else - { - p->low += newBound; - p->range -= newBound; - ttt -= ttt >> kNumMoveBits; - } - *prob = (CLzmaProb)ttt; - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -{ - symbol |= 0x100; - do - { - RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); - symbol <<= 1; - } - while (symbol < 0x10000); -} - -static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -{ - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } - while (symbol < 0x10000); -} - -void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -{ - UInt32 i; - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) - { - const int kCyclesBits = kNumBitPriceShiftBits; - UInt32 w = i; - UInt32 bitCount = 0; - int j; - for (j = 0; j < kCyclesBits; j++) - { - w = w * w; - bitCount <<= 1; - while (w >= ((UInt32)1 << 16)) - { - w >>= 1; - bitCount++; - } - } - ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); - } -} - - -#define GET_PRICE(prob, symbol) \ - p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; - -#define GET_PRICEa(prob, symbol) \ - ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; - -#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] - -#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] - -static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -{ - UInt32 price = 0; - symbol |= 0x100; - do - { - price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); - symbol <<= 1; - } - while (symbol < 0x10000); - return price; -} - -static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -{ - UInt32 price = 0; - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } - while (symbol < 0x10000); - return price; -} - - -static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -{ - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0;) - { - UInt32 bit; - i--; - bit = (symbol >> i) & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - } -} - -static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -{ - UInt32 m = 1; - int i; - for (i = 0; i < numBitLevels; i++) - { - UInt32 bit = symbol & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - symbol >>= 1; - } -} - -static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -{ - UInt32 price = 0; - symbol |= (1 << numBitLevels); - while (symbol != 1) - { - price += GET_PRICEa(probs[symbol >> 1], symbol & 1); - symbol >>= 1; - } - return price; -} - -static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -{ - UInt32 price = 0; - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0; i--) - { - UInt32 bit = symbol & 1; - symbol >>= 1; - price += GET_PRICEa(probs[m], bit); - m = (m << 1) | bit; - } - return price; -} - - -static void LenEnc_Init(CLenEnc *p) -{ - unsigned i; - p->choice = p->choice2 = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) - p->low[i] = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) - p->mid[i] = kProbInitValue; - for (i = 0; i < kLenNumHighSymbols; i++) - p->high[i] = kProbInitValue; -} - -static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -{ - if (symbol < kLenNumLowSymbols) - { - RangeEnc_EncodeBit(rc, &p->choice, 0); - RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice, 1); - if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) - { - RangeEnc_EncodeBit(rc, &p->choice2, 0); - RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice2, 1); - RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); - } - } -} - -static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -{ - UInt32 a0 = GET_PRICE_0a(p->choice); - UInt32 a1 = GET_PRICE_1a(p->choice); - UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); - UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); - UInt32 i = 0; - for (i = 0; i < kLenNumLowSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); - } - for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); - } - for (; i < numSymbols; i++) - prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -} - -static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -{ - LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); - p->counters[posState] = p->tableSize; -} - -static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -{ - UInt32 posState; - for (posState = 0; posState < numPosStates; posState++) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - -static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -{ - LenEnc_Encode(&p->p, rc, symbol, posState); - if (updatePrice) - if (--p->counters[posState] == 0) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - - - - -static void MovePos(CLzmaEnc *p, UInt32 num) -{ - #ifdef SHOW_STAT - g_STAT_OFFSET += num; - printf("\n MovePos %d", num); - #endif - - if (num != 0) - { - p->additionalOffset += num; - p->matchFinder.Skip(p->matchFinderObj, num); - } -} - -static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -{ - UInt32 lenRes = 0, numPairs; - p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); - numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); - - #ifdef SHOW_STAT - printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2); - g_STAT_OFFSET++; - { - UInt32 i; - for (i = 0; i < numPairs; i += 2) - printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); - } - #endif - - if (numPairs > 0) - { - lenRes = p->matches[numPairs - 2]; - if (lenRes == p->numFastBytes) - { - const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - UInt32 distance = p->matches[numPairs - 1] + 1; - UInt32 numAvail = p->numAvail; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - { - const Byte *pby2 = pby - distance; - for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); - } - } - } - p->additionalOffset++; - *numDistancePairsRes = numPairs; - return lenRes; -} - - -#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -#define IsShortRep(p) ((p)->backPrev == 0) - -static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -{ - return - GET_PRICE_0(p->isRepG0[state]) + - GET_PRICE_0(p->isRep0Long[state][posState]); -} - -static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -{ - UInt32 price; - if (repIndex == 0) - { - price = GET_PRICE_0(p->isRepG0[state]); - price += GET_PRICE_1(p->isRep0Long[state][posState]); - } - else - { - price = GET_PRICE_1(p->isRepG0[state]); - if (repIndex == 1) - price += GET_PRICE_0(p->isRepG1[state]); - else - { - price += GET_PRICE_1(p->isRepG1[state]); - price += GET_PRICE(p->isRepG2[state], repIndex - 2); - } - } - return price; -} - -static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -{ - return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + - GetPureRepPrice(p, repIndex, state, posState); -} - -static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -{ - UInt32 posMem = p->opt[cur].posPrev; - UInt32 backMem = p->opt[cur].backPrev; - p->optimumEndIndex = cur; - do - { - if (p->opt[cur].prev1IsChar) - { - MakeAsChar(&p->opt[posMem]) - p->opt[posMem].posPrev = posMem - 1; - if (p->opt[cur].prev2) - { - p->opt[posMem - 1].prev1IsChar = False; - p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; - p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; - } - } - { - UInt32 posPrev = posMem; - UInt32 backCur = backMem; - - backMem = p->opt[posPrev].backPrev; - posMem = p->opt[posPrev].posPrev; - - p->opt[posPrev].backPrev = backCur; - p->opt[posPrev].posPrev = cur; - cur = posPrev; - } - } - while (cur != 0); - *backRes = p->opt[0].backPrev; - p->optimumCurrentIndex = p->opt[0].posPrev; - return p->optimumCurrentIndex; -} - -#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) - -static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -{ - UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; - UInt32 matchPrice, repMatchPrice, normalMatchPrice; - UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; - UInt32 *matches; - const Byte *data; - Byte curByte, matchByte; - if (p->optimumEndIndex != p->optimumCurrentIndex) - { - const COptimal *opt = &p->opt[p->optimumCurrentIndex]; - UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; - *backRes = opt->backPrev; - p->optimumCurrentIndex = opt->posPrev; - return lenRes; - } - p->optimumCurrentIndex = p->optimumEndIndex = 0; - - if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); - else - { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; - } - - numAvail = p->numAvail; - if (numAvail < 2) - { - *backRes = (UInt32)(-1); - return 1; - } - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - repMaxIndex = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 lenTest; - const Byte *data2; - reps[i] = p->reps[i]; - data2 = data - (reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - { - repLens[i] = 0; - continue; - } - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - repLens[i] = lenTest; - if (lenTest > repLens[repMaxIndex]) - repMaxIndex = i; - } - if (repLens[repMaxIndex] >= p->numFastBytes) - { - UInt32 lenRes; - *backRes = repMaxIndex; - lenRes = repLens[repMaxIndex]; - MovePos(p, lenRes - 1); - return lenRes; - } - - matches = p->matches; - if (mainLen >= p->numFastBytes) - { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; - } - curByte = *data; - matchByte = *(data - (reps[0] + 1)); - - if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) - { - *backRes = (UInt32)-1; - return 1; - } - - p->opt[0].state = (CState)p->state; - - posState = (position & p->pbMask); - - { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + - (!IsCharState(p->state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); - } - - MakeAsChar(&p->opt[1]); - - matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); - - if (matchByte == curByte) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); - if (shortRepPrice < p->opt[1].price) - { - p->opt[1].price = shortRepPrice; - MakeAsShortRep(&p->opt[1]); - } - } - lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); - - if (lenEnd < 2) - { - *backRes = p->opt[1].backPrev; - return 1; - } - - p->opt[1].posPrev = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - p->opt[0].backs[i] = reps[i]; - - len = lenEnd; - do - p->opt[len--].price = kInfinityPrice; - while (len >= 2); - - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 repLen = repLens[i]; - UInt32 price; - if (repLen < 2) - continue; - price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); - do - { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; - COptimal *opt = &p->opt[repLen]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = i; - opt->prev1IsChar = False; - } - } - while (--repLen >= 2); - } - - normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); - - len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); - if (len <= mainLen) - { - UInt32 offs = 0; - while (len > matches[offs]) - offs += 2; - for (; ; len++) - { - COptimal *opt; - UInt32 distance = matches[offs + 1]; - - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; - UInt32 lenToPosState = GetLenToPosState(len); - if (distance < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][distance]; - else - { - UInt32 slot; - GetPosSlot2(distance, slot); - curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; - } - opt = &p->opt[len]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = distance + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - if (len == matches[offs]) - { - offs += 2; - if (offs == numPairs) - break; - } - } - } - - cur = 0; - - #ifdef SHOW_STAT2 - if (position >= 0) - { - unsigned i; - printf("\n pos = %4X", position); - for (i = cur; i <= lenEnd; i++) - printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); - } - #endif - - for (;;) - { - UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; - UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; - Bool nextIsChar; - Byte curByte, matchByte; - const Byte *data; - COptimal *curOpt; - COptimal *nextOpt; - - cur++; - if (cur == lenEnd) - return Backward(p, backRes, cur); - - newLen = ReadMatchDistances(p, &numPairs); - if (newLen >= p->numFastBytes) - { - p->numPairs = numPairs; - p->longestMatchLength = newLen; - return Backward(p, backRes, cur); - } - position++; - curOpt = &p->opt[cur]; - posPrev = curOpt->posPrev; - if (curOpt->prev1IsChar) - { - posPrev--; - if (curOpt->prev2) - { - state = p->opt[curOpt->posPrev2].state; - if (curOpt->backPrev2 < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; - } - else - state = p->opt[posPrev].state; - state = kLiteralNextStates[state]; - } - else - state = p->opt[posPrev].state; - if (posPrev == cur - 1) - { - if (IsShortRep(curOpt)) - state = kShortRepNextStates[state]; - else - state = kLiteralNextStates[state]; - } - else - { - UInt32 pos; - const COptimal *prevOpt; - if (curOpt->prev1IsChar && curOpt->prev2) - { - posPrev = curOpt->posPrev2; - pos = curOpt->backPrev2; - state = kRepNextStates[state]; - } - else - { - pos = curOpt->backPrev; - if (pos < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; - } - prevOpt = &p->opt[posPrev]; - if (pos < LZMA_NUM_REPS) - { - UInt32 i; - reps[0] = prevOpt->backs[pos]; - for (i = 1; i <= pos; i++) - reps[i] = prevOpt->backs[i - 1]; - for (; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i]; - } - else - { - UInt32 i; - reps[0] = (pos - LZMA_NUM_REPS); - for (i = 1; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i - 1]; - } - } - curOpt->state = (CState)state; - - curOpt->backs[0] = reps[0]; - curOpt->backs[1] = reps[1]; - curOpt->backs[2] = reps[2]; - curOpt->backs[3] = reps[3]; - - curPrice = curOpt->price; - nextIsChar = False; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - curByte = *data; - matchByte = *(data - (reps[0] + 1)); - - posState = (position & p->pbMask); - - curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); - { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - curAnd1Price += - (!IsCharState(state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); - } - - nextOpt = &p->opt[cur + 1]; - - if (curAnd1Price < nextOpt->price) - { - nextOpt->price = curAnd1Price; - nextOpt->posPrev = cur; - MakeAsChar(nextOpt); - nextIsChar = True; - } - - matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); - - if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); - if (shortRepPrice <= nextOpt->price) - { - nextOpt->price = shortRepPrice; - nextOpt->posPrev = cur; - MakeAsShortRep(nextOpt); - nextIsChar = True; - } - } - numAvailFull = p->numAvail; - { - UInt32 temp = kNumOpts - 1 - cur; - if (temp < numAvailFull) - numAvailFull = temp; - } - - if (numAvailFull < 2) - continue; - numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); - - if (!nextIsChar && matchByte != curByte) /* speed optimization */ - { - /* try Literal + rep0 */ - UInt32 temp; - UInt32 lenTest2; - const Byte *data2 = data - (reps[0] + 1); - UInt32 limit = p->numFastBytes + 1; - if (limit > numAvailFull) - limit = numAvailFull; - - for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); - lenTest2 = temp - 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kLiteralNextStates[state]; - UInt32 posStateNext = (position + 1) & p->pbMask; - UInt32 nextRepMatchPrice = curAnd1Price + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = False; - } - } - } - } - - startLen = 2; /* speed optimization */ - { - UInt32 repIndex; - for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) - { - UInt32 lenTest; - UInt32 lenTestTemp; - UInt32 price; - const Byte *data2 = data - (reps[repIndex] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - while (lenEnd < cur + lenTest) - p->opt[++lenEnd].price = kInfinityPrice; - lenTestTemp = lenTest; - price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); - do - { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; - COptimal *opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = repIndex; - opt->prev1IsChar = False; - } - } - while (--lenTest >= 2); - lenTest = lenTestTemp; - - if (repIndex == 0) - startLen = lenTest + 1; - - /* if (_maxMode) */ - { - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - UInt32 nextRepMatchPrice; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kRepNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = - price + p->repLenEnc.prices[posState][lenTest - 2] + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (position + lenTest + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + lenTest + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = repIndex; - } - } - } - } - } - } - /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ - if (newLen > numAvail) - { - newLen = numAvail; - for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); - matches[numPairs] = newLen; - numPairs += 2; - } - if (newLen >= startLen) - { - UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); - UInt32 offs, curBack, posSlot; - UInt32 lenTest; - while (lenEnd < cur + newLen) - p->opt[++lenEnd].price = kInfinityPrice; - - offs = 0; - while (startLen > matches[offs]) - offs += 2; - curBack = matches[offs + 1]; - GetPosSlot2(curBack, posSlot); - for (lenTest = /*2*/ startLen; ; lenTest++) - { - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; - UInt32 lenToPosState = GetLenToPosState(lenTest); - COptimal *opt; - if (curBack < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; - else - curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; - - opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = curBack + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - - if (/*_maxMode && */lenTest == matches[offs]) - { - /* Try Match + Literal + Rep0 */ - const Byte *data2 = data - (curBack + 1); - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - UInt32 nextRepMatchPrice; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kMatchNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = curAndLenPrice + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (posStateNext + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 offset = cur + lenTest + 1 + lenTest2; - UInt32 curAndLenPrice; - COptimal *opt; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = curBack + LZMA_NUM_REPS; - } - } - } - offs += 2; - if (offs == numPairs) - break; - curBack = matches[offs + 1]; - if (curBack >= kNumFullDistances) - GetPosSlot2(curBack, posSlot); - } - } - } - } -} - -#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) - -static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -{ - UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; - const Byte *data; - const UInt32 *matches; - - if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); - else - { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; - } - - numAvail = p->numAvail; - *backRes = (UInt32)-1; - if (numAvail < 2) - return 1; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - - repLen = repIndex = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 len; - const Byte *data2 = data - (p->reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (len = 2; len < numAvail && data[len] == data2[len]; len++); - if (len >= p->numFastBytes) - { - *backRes = i; - MovePos(p, len - 1); - return len; - } - if (len > repLen) - { - repIndex = i; - repLen = len; - } - } - - matches = p->matches; - if (mainLen >= p->numFastBytes) - { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; - } - - mainDist = 0; /* for GCC */ - if (mainLen >= 2) - { - mainDist = matches[numPairs - 1]; - while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) - { - if (!ChangePair(matches[numPairs - 3], mainDist)) - break; - numPairs -= 2; - mainLen = matches[numPairs - 2]; - mainDist = matches[numPairs - 1]; - } - if (mainLen == 2 && mainDist >= 0x80) - mainLen = 1; - } - - if (repLen >= 2 && ( - (repLen + 1 >= mainLen) || - (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || - (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) - { - *backRes = repIndex; - MovePos(p, repLen - 1); - return repLen; - } - - if (mainLen < 2 || numAvail <= 2) - return 1; - - p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); - if (p->longestMatchLength >= 2) - { - UInt32 newDistance = matches[p->numPairs - 1]; - if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || - (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || - (p->longestMatchLength > mainLen + 1) || - (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) - return 1; - } - - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 len, limit; - const Byte *data2 = data - (p->reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - limit = mainLen - 1; - for (len = 2; len < limit && data[len] == data2[len]; len++); - if (len >= limit) - return 1; - } - *backRes = mainDist + LZMA_NUM_REPS; - MovePos(p, mainLen - 2); - return mainLen; -} - -static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -{ - UInt32 len; - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - len = LZMA_MATCH_LEN_MIN; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); - RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -} - -static SRes CheckErrors(CLzmaEnc *p) -{ - if (p->result != SZ_OK) - return p->result; - if (p->rc.res != SZ_OK) - p->result = SZ_ERROR_WRITE; - if (p->matchFinderBase.result != SZ_OK) - p->result = SZ_ERROR_READ; - if (p->result != SZ_OK) - p->finished = True; - return p->result; -} - -static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -{ - /* ReleaseMFStream(); */ - p->finished = True; - if (p->writeEndMark) - WriteEndMarker(p, nowPos & p->pbMask); - RangeEnc_FlushData(&p->rc); - RangeEnc_FlushStream(&p->rc); - return CheckErrors(p); -} - -static void FillAlignPrices(CLzmaEnc *p) -{ - UInt32 i; - for (i = 0; i < kAlignTableSize; i++) - p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); - p->alignPriceCount = 0; -} - -static void FillDistancesPrices(CLzmaEnc *p) -{ - UInt32 tempPrices[kNumFullDistances]; - UInt32 i, lenToPosState; - for (i = kStartPosModelIndex; i < kNumFullDistances; i++) - { - UInt32 posSlot = GetPosSlot1(i); - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); - } - - for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) - { - UInt32 posSlot; - const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; - UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; - for (posSlot = 0; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); - for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); - - { - UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; - UInt32 i; - for (i = 0; i < kStartPosModelIndex; i++) - distancesPrices[i] = posSlotPrices[i]; - for (; i < kNumFullDistances; i++) - distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; - } - } - p->matchPriceCount = 0; -} - -void LzmaEnc_Construct(CLzmaEnc *p) -{ - RangeEnc_Construct(&p->rc); - MatchFinder_Construct(&p->matchFinderBase); - #ifndef _7ZIP_ST - MatchFinderMt_Construct(&p->matchFinderMt); - p->matchFinderMt.MatchFinder = &p->matchFinderBase; - #endif - - { - CLzmaEncProps props; - LzmaEncProps_Init(&props); - LzmaEnc_SetProps(p, &props); - } - - #ifndef LZMA_LOG_BSR - LzmaEnc_FastPosInit(p->g_FastPos); - #endif - - LzmaEnc_InitPriceTables(p->ProbPrices); - p->litProbs = 0; - p->saveState.litProbs = 0; -} - -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -{ - void *p; - p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); - if (p != 0) - LzmaEnc_Construct((CLzmaEnc *)p); - return p; -} - -void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); - p->litProbs = 0; - p->saveState.litProbs = 0; -} - -void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - #ifndef _7ZIP_ST - MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); - #endif - MatchFinder_Free(&p->matchFinderBase, allocBig); - LzmaEnc_FreeLits(p, alloc); - RangeEnc_Free(&p->rc, alloc); -} - -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); - alloc->Free(alloc, p); -} - -static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -{ - UInt32 nowPos32, startPos32; - if (p->needInit) - { - p->matchFinder.Init(p->matchFinderObj); - p->needInit = 0; - } - - if (p->finished) - return p->result; - RINOK(CheckErrors(p)); - - nowPos32 = (UInt32)p->nowPos64; - startPos32 = nowPos32; - - if (p->nowPos64 == 0) - { - UInt32 numPairs; - Byte curByte; - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - return Flush(p, nowPos32); - ReadMatchDistances(p, &numPairs); - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); - p->state = kLiteralNextStates[p->state]; - curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); - LitEnc_Encode(&p->rc, p->litProbs, curByte); - p->additionalOffset--; - nowPos32++; - } - - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) - for (;;) - { - UInt32 pos, len, posState; - - if (p->fastMode) - len = GetOptimumFast(p, &pos); - else - len = GetOptimum(p, nowPos32, &pos); - - #ifdef SHOW_STAT2 - printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); - #endif - - posState = nowPos32 & p->pbMask; - if (len == 1 && pos == (UInt32)-1) - { - Byte curByte; - CLzmaProb *probs; - const Byte *data; - - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; - curByte = *data; - probs = LIT_PROBS(nowPos32, *(data - 1)); - if (IsCharState(p->state)) - LitEnc_Encode(&p->rc, probs, curByte); - else - LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); - p->state = kLiteralNextStates[p->state]; - } - else - { - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - if (pos < LZMA_NUM_REPS) - { - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); - if (pos == 0) - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); - RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); - } - else - { - UInt32 distance = p->reps[pos]; - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); - if (pos == 1) - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); - else - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); - if (pos == 3) - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - } - p->reps[1] = p->reps[0]; - p->reps[0] = distance; - } - if (len == 1) - p->state = kShortRepNextStates[p->state]; - else - { - LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - p->state = kRepNextStates[p->state]; - } - } - else - { - UInt32 posSlot; - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - pos -= LZMA_NUM_REPS; - GetPosSlot(pos, posSlot); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); - - if (posSlot >= kStartPosModelIndex) - { - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - UInt32 posReduced = pos - base; - - if (posSlot < kEndPosModelIndex) - RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); - else - { - RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); - p->alignPriceCount++; - } - } - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - p->reps[1] = p->reps[0]; - p->reps[0] = pos; - p->matchPriceCount++; - } - } - p->additionalOffset -= len; - nowPos32 += len; - if (p->additionalOffset == 0) - { - UInt32 processed; - if (!p->fastMode) - { - if (p->matchPriceCount >= (1 << 7)) - FillDistancesPrices(p); - if (p->alignPriceCount >= kAlignTableSize) - FillAlignPrices(p); - } - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - break; - processed = nowPos32 - startPos32; - if (useLimits) - { - if (processed + kNumOpts + 300 >= maxUnpackSize || - RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) - break; - } - else if (processed >= (1 << 15)) - { - p->nowPos64 += nowPos32 - startPos32; - return CheckErrors(p); - } - } - } - p->nowPos64 += nowPos32 - startPos32; - return Flush(p, nowPos32); -} - -#define kBigHashDicLimit ((UInt32)1 << 24) - -static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - UInt32 beforeSize = kNumOpts; - if (!RangeEnc_Alloc(&p->rc, alloc)) - return SZ_ERROR_MEM; - #ifndef _7ZIP_ST - p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); - #endif - - { - unsigned lclp = p->lc + p->lp; - if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) - { - LzmaEnc_FreeLits(p, alloc); - p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); - p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); - if (p->litProbs == 0 || p->saveState.litProbs == 0) - { - LzmaEnc_FreeLits(p, alloc); - return SZ_ERROR_MEM; - } - p->lclp = lclp; - } - } - - p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); - - if (beforeSize + p->dictSize < keepWindowSize) - beforeSize = keepWindowSize - p->dictSize; - - #ifndef _7ZIP_ST - if (p->mtMode) - { - RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); - p->matchFinderObj = &p->matchFinderMt; - MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); - } - else - #endif - { - if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) - return SZ_ERROR_MEM; - p->matchFinderObj = &p->matchFinderBase; - MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); - } - return SZ_OK; -} - -void LzmaEnc_Init(CLzmaEnc *p) -{ - UInt32 i; - p->state = 0; - for (i = 0 ; i < LZMA_NUM_REPS; i++) - p->reps[i] = 0; - - RangeEnc_Init(&p->rc); - - - for (i = 0; i < kNumStates; i++) - { - UInt32 j; - for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) - { - p->isMatch[i][j] = kProbInitValue; - p->isRep0Long[i][j] = kProbInitValue; - } - p->isRep[i] = kProbInitValue; - p->isRepG0[i] = kProbInitValue; - p->isRepG1[i] = kProbInitValue; - p->isRepG2[i] = kProbInitValue; - } - - { - UInt32 num = 0x300 << (p->lp + p->lc); - for (i = 0; i < num; i++) - p->litProbs[i] = kProbInitValue; - } - - { - for (i = 0; i < kNumLenToPosStates; i++) - { - CLzmaProb *probs = p->posSlotEncoder[i]; - UInt32 j; - for (j = 0; j < (1 << kNumPosSlotBits); j++) - probs[j] = kProbInitValue; - } - } - { - for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) - p->posEncoders[i] = kProbInitValue; - } - - LenEnc_Init(&p->lenEnc.p); - LenEnc_Init(&p->repLenEnc.p); - - for (i = 0; i < (1 << kNumAlignBits); i++) - p->posAlignEncoder[i] = kProbInitValue; - - p->optimumEndIndex = 0; - p->optimumCurrentIndex = 0; - p->additionalOffset = 0; - - p->pbMask = (1 << p->pb) - 1; - p->lpMask = (1 << p->lp) - 1; -} - -void LzmaEnc_InitPrices(CLzmaEnc *p) -{ - if (!p->fastMode) - { - FillDistancesPrices(p); - FillAlignPrices(p); - } - - p->lenEnc.tableSize = - p->repLenEnc.tableSize = - p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; - LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); - LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -} - -static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - UInt32 i; - for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) - if (p->dictSize <= ((UInt32)1 << i)) - break; - p->distTableSize = i * 2; - - p->finished = False; - p->result = SZ_OK; - RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - p->nowPos64 = 0; - return SZ_OK; -} - -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - p->rc.outStream = outStream; - return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -} - -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, - ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -{ - p->matchFinderBase.directInput = 1; - p->matchFinderBase.bufferBase = (Byte *)src; - p->matchFinderBase.directInputRem = srcLen; -} - -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - LzmaEnc_SetInputBuf(p, src, srcLen); - p->needInit = 1; - - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -void LzmaEnc_Finish(CLzmaEncHandle pp) -{ - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; - if (p->mtMode) - MatchFinderMt_ReleaseStream(&p->matchFinderMt); - #else - pp = pp; - #endif -} - -typedef struct -{ - ISeqOutStream funcTable; - Byte *data; - SizeT rem; - Bool overflow; -} CSeqOutStreamBuf; - -static size_t MyWrite(void *pp, const void *data, size_t size) -{ - CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; - if (p->rem < size) - { - size = p->rem; - p->overflow = True; - } - memcpy(p->data, data, size); - p->rem -= size; - p->data += size; - return size; -} - - -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -{ - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -} - -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -{ - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -} - -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, - Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - UInt64 nowPos64; - SRes res; - CSeqOutStreamBuf outStream; - - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; - - p->writeEndMark = False; - p->finished = False; - p->result = SZ_OK; - - if (reInit) - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - nowPos64 = p->nowPos64; - RangeEnc_Init(&p->rc); - p->rc.outStream = &outStream.funcTable; - - res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); - - *unpackSize = (UInt32)(p->nowPos64 - nowPos64); - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - - return res; -} - -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -{ - SRes res = SZ_OK; - - #ifndef _7ZIP_ST - Byte allocaDummy[0x300]; - allocaDummy[0] = 0; - allocaDummy[1] = allocaDummy[0]; - #endif - - for (;;) - { - res = LzmaEnc_CodeOneBlock(p, False, 0, 0); - if (res != SZ_OK || p->finished != 0) - break; - if (progress != 0) - { - res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); - if (res != SZ_OK) - { - res = SZ_ERROR_PROGRESS; - break; - } - } - } - LzmaEnc_Finish(p); - return res; -} - -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -} - -SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - int i; - UInt32 dictSize = p->dictSize; - if (*size < LZMA_PROPS_SIZE) - return SZ_ERROR_PARAM; - *size = LZMA_PROPS_SIZE; - props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); - - for (i = 11; i <= 30; i++) - { - if (dictSize <= ((UInt32)2 << i)) - { - dictSize = (2 << i); - break; - } - if (dictSize <= ((UInt32)3 << i)) - { - dictSize = (3 << i); - break; - } - } - - for (i = 0; i < 4; i++) - props[1 + i] = (Byte)(dictSize >> (8 * i)); - return SZ_OK; -} - -SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - SRes res; - CLzmaEnc *p = (CLzmaEnc *)pp; - - CSeqOutStreamBuf outStream; - - LzmaEnc_SetInputBuf(p, src, srcLen); - - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; - - p->writeEndMark = writeEndMark; - - p->rc.outStream = &outStream.funcTable; - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); - if (res == SZ_OK) - res = LzmaEnc_Encode2(p, progress); - - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - return res; -} - -SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); - SRes res; - if (p == 0) - return SZ_ERROR_MEM; - - res = LzmaEnc_SetProps(p, props); - if (res == SZ_OK) - { - res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); - if (res == SZ_OK) - res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, - writeEndMark, progress, alloc, allocBig); - } - - LzmaEnc_Destroy(p, alloc, allocBig); - return res; -} diff --git a/utils/lzma/C/LzmaEnc.h b/utils/lzma/C/LzmaEnc.h deleted file mode 100644 index cffe220b..00000000 --- a/utils/lzma/C/LzmaEnc.h +++ /dev/null @@ -1,78 +0,0 @@ -/* LzmaEnc.h -- LZMA Encoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define LZMA_PROPS_SIZE 5 - -typedef struct _CLzmaEncProps -{ - int level; /* 0 <= level <= 9 */ - UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version - (1 << 12) <= dictSize <= (1 << 30) for 64-bit version - default = (1 << 24) */ - UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. - Encoder uses this value to reduce dictionary size */ - int lc; /* 0 <= lc <= 8, default = 3 */ - int lp; /* 0 <= lp <= 4, default = 0 */ - int pb; /* 0 <= pb <= 4, default = 2 */ - int algo; /* 0 - fast, 1 - normal, default = 1 */ - int fb; /* 5 <= fb <= 273, default = 32 */ - int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ - int numHashBytes; /* 2, 3 or 4, default = 4 */ - UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ - unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ - int numThreads; /* 1 or 2, default = 2 */ -} CLzmaEncProps; - -void LzmaEncProps_Init(CLzmaEncProps *p); -void LzmaEncProps_Normalize(CLzmaEncProps *p); -UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); - - -/* ---------- CLzmaEncHandle Interface ---------- */ - -/* LzmaEnc_* functions can return the following exit codes: -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error. - SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -typedef void * CLzmaEncHandle; - -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - -/* ---------- One Call Interface ---------- */ - -/* LzmaEncode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/LzmaLib.c b/utils/lzma/C/LzmaLib.c deleted file mode 100644 index 02a51185..00000000 --- a/utils/lzma/C/LzmaLib.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LzmaLib.c -- LZMA library wrapper -2008-08-05 -Igor Pavlov -Public domain */ - -#include "LzmaEnc.h" -#include "LzmaDec.h" -#include "Alloc.h" -#include "LzmaLib.h" - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ -) -{ - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - props.lc = lc; - props.lp = lp; - props.pb = pb; - props.fb = fb; - props.numThreads = numThreads; - - return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); -} - - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, - const unsigned char *props, size_t propsSize) -{ - ELzmaStatus status; - return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); -} diff --git a/utils/lzma/C/LzmaLib.h b/utils/lzma/C/LzmaLib.h deleted file mode 100644 index 88fa87d3..00000000 --- a/utils/lzma/C/LzmaLib.h +++ /dev/null @@ -1,131 +0,0 @@ -/* LzmaLib.h -- LZMA library interface -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_LIB_H -#define __LZMA_LIB_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define MY_STDAPI int MY_STD_CALL - -#define LZMA_PROPS_SIZE 5 - -/* -RAM requirements for LZMA: - for compression: (dictSize * 11.5 + 6 MB) + state_size - for decompression: dictSize + state_size - state_size = (4 + (1.5 << (lc + lp))) KB - by default (lc=3, lp=0), state_size = 16 KB. - -LZMA properties (5 bytes) format - Offset Size Description - 0 1 lc, lp and pb in encoded form. - 1 4 dictSize (little endian). -*/ - -/* -LzmaCompress ------------- - -outPropsSize - - In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - - LZMA Encoder will use defult values for any parameter, if it is - -1 for any from: level, loc, lp, pb, fb, numThreads - 0 for dictSize - -level - compression level: 0 <= level <= 9; - - level dictSize algo fb - 0: 16 KB 0 32 - 1: 64 KB 0 32 - 2: 256 KB 0 32 - 3: 1 MB 0 32 - 4: 4 MB 0 32 - 5: 16 MB 1 32 - 6: 32 MB 1 32 - 7+: 64 MB 1 64 - - The default value for "level" is 5. - - algo = 0 means fast method - algo = 1 means normal method - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - -lc - The number of literal context bits (high bits of previous literal). - It can be in the range from 0 to 8. The default value is 3. - Sometimes lc=4 gives the gain for big files. - -lp - The number of literal pos bits (low bits of current position for literals). - It can be in the range from 0 to 4. The default value is 0. - The lp switch is intended for periodical data when the period is equal to 2^lp. - For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's - better to set lc=0, if you change lp switch. - -pb - The number of pos bits (low bits of current position). - It can be in the range from 0 to 4. The default value is 2. - The pb switch is intended for periodical data when the period is equal 2^pb. - -fb - Word size (the number of fast bytes). - It can be in the range from 5 to 273. The default value is 32. - Usually, a big number gives a little bit better compression ratio and - slower compression process. - -numThreads - The number of thereads. 1 or 2. The default value is 2. - Fast mode (algo = 0) can use only 1 thread. - -Out: - destLen - processed output size -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* default = (1 << 24) */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ - ); - -/* -LzmaUncompress --------------- -In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size -Out: - destLen - processed output size - srcLen - processed input size -Returns: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation arror - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) -*/ - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, - const unsigned char *props, size_t propsSize); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/MtCoder.c b/utils/lzma/C/MtCoder.c deleted file mode 100644 index 616f0b41..00000000 --- a/utils/lzma/C/MtCoder.c +++ /dev/null @@ -1,329 +0,0 @@ -/* MtCoder.c -- Multi-thread Coder -2010-09-24 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "MtCoder.h" - -void LoopThread_Construct(CLoopThread *p) -{ - Thread_Construct(&p->thread); - Event_Construct(&p->startEvent); - Event_Construct(&p->finishedEvent); -} - -void LoopThread_Close(CLoopThread *p) -{ - Thread_Close(&p->thread); - Event_Close(&p->startEvent); - Event_Close(&p->finishedEvent); -} - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp) -{ - CLoopThread *p = (CLoopThread *)pp; - for (;;) - { - if (Event_Wait(&p->startEvent) != 0) - return SZ_ERROR_THREAD; - if (p->stop) - return 0; - p->res = p->func(p->param); - if (Event_Set(&p->finishedEvent) != 0) - return SZ_ERROR_THREAD; - } -} - -WRes LoopThread_Create(CLoopThread *p) -{ - p->stop = 0; - RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent)); - RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent)); - return Thread_Create(&p->thread, LoopThreadFunc, p); -} - -WRes LoopThread_StopAndWait(CLoopThread *p) -{ - p->stop = 1; - if (Event_Set(&p->startEvent) != 0) - return SZ_ERROR_THREAD; - return Thread_Wait(&p->thread); -} - -WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); } -WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); } - -static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) -{ - return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; -} - -static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress) -{ - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - p->inSizes[i] = p->outSizes[i] = 0; - p->totalInSize = p->totalOutSize = 0; - p->progress = progress; - p->res = SZ_OK; -} - -static void MtProgress_Reinit(CMtProgress *p, unsigned index) -{ - p->inSizes[index] = 0; - p->outSizes[index] = 0; -} - -#define UPDATE_PROGRESS(size, prev, total) \ - if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; } - -SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize) -{ - SRes res; - CriticalSection_Enter(&p->cs); - UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize) - UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize) - if (p->res == SZ_OK) - p->res = Progress(p->progress, p->totalInSize, p->totalOutSize); - res = p->res; - CriticalSection_Leave(&p->cs); - return res; -} - -static void MtProgress_SetError(CMtProgress *p, SRes res) -{ - CriticalSection_Enter(&p->cs); - if (p->res == SZ_OK) - p->res = res; - CriticalSection_Leave(&p->cs); -} - -static void MtCoder_SetError(CMtCoder* p, SRes res) -{ - CriticalSection_Enter(&p->cs); - if (p->res == SZ_OK) - p->res = res; - CriticalSection_Leave(&p->cs); -} - -/* ---------- MtThread ---------- */ - -void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder) -{ - p->mtCoder = mtCoder; - p->outBuf = 0; - p->inBuf = 0; - Event_Construct(&p->canRead); - Event_Construct(&p->canWrite); - LoopThread_Construct(&p->thread); -} - -#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; } - -static void CMtThread_CloseEvents(CMtThread *p) -{ - Event_Close(&p->canRead); - Event_Close(&p->canWrite); -} - -static void CMtThread_Destruct(CMtThread *p) -{ - CMtThread_CloseEvents(p); - - if (Thread_WasCreated(&p->thread.thread)) - { - LoopThread_StopAndWait(&p->thread); - LoopThread_Close(&p->thread); - } - - if (p->mtCoder->alloc) - IAlloc_Free(p->mtCoder->alloc, p->outBuf); - p->outBuf = 0; - - if (p->mtCoder->alloc) - IAlloc_Free(p->mtCoder->alloc, p->inBuf); - p->inBuf = 0; -} - -#define MY_BUF_ALLOC(buf, size, newSize) \ - if (buf == 0 || size != newSize) \ - { IAlloc_Free(p->mtCoder->alloc, buf); \ - size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \ - if (buf == 0) return SZ_ERROR_MEM; } - -static SRes CMtThread_Prepare(CMtThread *p) -{ - MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize) - MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize) - - p->stopReading = False; - p->stopWriting = False; - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite)); - - return SZ_OK; -} - -static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize) -{ - size_t size = *processedSize; - *processedSize = 0; - while (size != 0) - { - size_t curSize = size; - SRes res = stream->Read(stream, data, &curSize); - *processedSize += curSize; - data += curSize; - size -= curSize; - RINOK(res); - if (curSize == 0) - return SZ_OK; - } - return SZ_OK; -} - -#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads - 1 ? 0 : p->index + 1] - -static SRes MtThread_Process(CMtThread *p, Bool *stop) -{ - CMtThread *next; - *stop = True; - if (Event_Wait(&p->canRead) != 0) - return SZ_ERROR_THREAD; - - next = GET_NEXT_THREAD(p); - - if (p->stopReading) - { - next->stopReading = True; - return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD; - } - - { - size_t size = p->mtCoder->blockSize; - size_t destSize = p->outBufSize; - - RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size)); - next->stopReading = *stop = (size != p->mtCoder->blockSize); - if (Event_Set(&next->canRead) != 0) - return SZ_ERROR_THREAD; - - RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index, - p->outBuf, &destSize, p->inBuf, size, *stop)); - - MtProgress_Reinit(&p->mtCoder->mtProgress, p->index); - - if (Event_Wait(&p->canWrite) != 0) - return SZ_ERROR_THREAD; - if (p->stopWriting) - return SZ_ERROR_FAIL; - if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize) - return SZ_ERROR_WRITE; - return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD; - } -} - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp) -{ - CMtThread *p = (CMtThread *)pp; - for (;;) - { - Bool stop; - CMtThread *next = GET_NEXT_THREAD(p); - SRes res = MtThread_Process(p, &stop); - if (res != SZ_OK) - { - MtCoder_SetError(p->mtCoder, res); - MtProgress_SetError(&p->mtCoder->mtProgress, res); - next->stopReading = True; - next->stopWriting = True; - Event_Set(&next->canRead); - Event_Set(&next->canWrite); - return res; - } - if (stop) - return 0; - } -} - -void MtCoder_Construct(CMtCoder* p) -{ - unsigned i; - p->alloc = 0; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - { - CMtThread *t = &p->threads[i]; - t->index = i; - CMtThread_Construct(t, p); - } - CriticalSection_Init(&p->cs); - CriticalSection_Init(&p->mtProgress.cs); -} - -void MtCoder_Destruct(CMtCoder* p) -{ - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - CMtThread_Destruct(&p->threads[i]); - CriticalSection_Delete(&p->cs); - CriticalSection_Delete(&p->mtProgress.cs); -} - -SRes MtCoder_Code(CMtCoder *p) -{ - unsigned i, numThreads = p->numThreads; - SRes res = SZ_OK; - p->res = SZ_OK; - - MtProgress_Init(&p->mtProgress, p->progress); - - for (i = 0; i < numThreads; i++) - { - RINOK(CMtThread_Prepare(&p->threads[i])); - } - - for (i = 0; i < numThreads; i++) - { - CMtThread *t = &p->threads[i]; - CLoopThread *lt = &t->thread; - - if (!Thread_WasCreated(<->thread)) - { - lt->func = ThreadFunc; - lt->param = t; - - if (LoopThread_Create(lt) != SZ_OK) - { - res = SZ_ERROR_THREAD; - break; - } - } - } - - if (res == SZ_OK) - { - unsigned j; - for (i = 0; i < numThreads; i++) - { - CMtThread *t = &p->threads[i]; - if (LoopThread_StartSubThread(&t->thread) != SZ_OK) - { - res = SZ_ERROR_THREAD; - p->threads[0].stopReading = True; - break; - } - } - - Event_Set(&p->threads[0].canWrite); - Event_Set(&p->threads[0].canRead); - - for (j = 0; j < i; j++) - LoopThread_WaitSubThread(&p->threads[j].thread); - } - - for (i = 0; i < numThreads; i++) - CMtThread_CloseEvents(&p->threads[i]); - return (res == SZ_OK) ? p->res : res; -} diff --git a/utils/lzma/C/MtCoder.h b/utils/lzma/C/MtCoder.h deleted file mode 100644 index f0f06da2..00000000 --- a/utils/lzma/C/MtCoder.h +++ /dev/null @@ -1,98 +0,0 @@ -/* MtCoder.h -- Multi-thread Coder -2009-11-19 : Igor Pavlov : Public domain */ - -#ifndef __MT_CODER_H -#define __MT_CODER_H - -#include "Threads.h" - -EXTERN_C_BEGIN - -typedef struct -{ - CThread thread; - CAutoResetEvent startEvent; - CAutoResetEvent finishedEvent; - int stop; - - THREAD_FUNC_TYPE func; - LPVOID param; - THREAD_FUNC_RET_TYPE res; -} CLoopThread; - -void LoopThread_Construct(CLoopThread *p); -void LoopThread_Close(CLoopThread *p); -WRes LoopThread_Create(CLoopThread *p); -WRes LoopThread_StopAndWait(CLoopThread *p); -WRes LoopThread_StartSubThread(CLoopThread *p); -WRes LoopThread_WaitSubThread(CLoopThread *p); - -#ifndef _7ZIP_ST -#define NUM_MT_CODER_THREADS_MAX 32 -#else -#define NUM_MT_CODER_THREADS_MAX 1 -#endif - -typedef struct -{ - UInt64 totalInSize; - UInt64 totalOutSize; - ICompressProgress *progress; - SRes res; - CCriticalSection cs; - UInt64 inSizes[NUM_MT_CODER_THREADS_MAX]; - UInt64 outSizes[NUM_MT_CODER_THREADS_MAX]; -} CMtProgress; - -SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize); - -struct _CMtCoder; - -typedef struct -{ - struct _CMtCoder *mtCoder; - Byte *outBuf; - size_t outBufSize; - Byte *inBuf; - size_t inBufSize; - unsigned index; - CLoopThread thread; - - Bool stopReading; - Bool stopWriting; - CAutoResetEvent canRead; - CAutoResetEvent canWrite; -} CMtThread; - -typedef struct -{ - SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize, - const Byte *src, size_t srcSize, int finished); -} IMtCoderCallback; - -typedef struct _CMtCoder -{ - size_t blockSize; - size_t destBlockSize; - unsigned numThreads; - - ISeqInStream *inStream; - ISeqOutStream *outStream; - ICompressProgress *progress; - ISzAlloc *alloc; - - IMtCoderCallback *mtCallback; - CCriticalSection cs; - SRes res; - - CMtProgress mtProgress; - CMtThread threads[NUM_MT_CODER_THREADS_MAX]; -} CMtCoder; - -void MtCoder_Construct(CMtCoder* p); -void MtCoder_Destruct(CMtCoder* p); -SRes MtCoder_Code(CMtCoder *p); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Ppmd.h b/utils/lzma/C/Ppmd.h deleted file mode 100644 index 4356dd1d..00000000 --- a/utils/lzma/C/Ppmd.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Ppmd.h -- PPMD codec common code -2013-01-18 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#ifndef __PPMD_H -#define __PPMD_H - -#include "CpuArch.h" - -EXTERN_C_BEGIN - -#ifdef MY_CPU_32BIT - #define PPMD_32BIT -#endif - -#define PPMD_INT_BITS 7 -#define PPMD_PERIOD_BITS 7 -#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) - -#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) -#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) -#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) -#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) - -#define PPMD_N1 4 -#define PPMD_N2 4 -#define PPMD_N3 4 -#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) -#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) - -#pragma pack(push, 1) -/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */ - -/* SEE-contexts for PPM-contexts with masked symbols */ -typedef struct -{ - UInt16 Summ; /* Freq */ - Byte Shift; /* Speed of Freq change; low Shift is for fast change */ - Byte Count; /* Count to next change of Shift */ -} CPpmd_See; - -#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ - { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } - -typedef struct -{ - Byte Symbol; - Byte Freq; - UInt16 SuccessorLow; - UInt16 SuccessorHigh; -} CPpmd_State; - -#pragma pack(pop) - -typedef - #ifdef PPMD_32BIT - CPpmd_State * - #else - UInt32 - #endif - CPpmd_State_Ref; - -typedef - #ifdef PPMD_32BIT - void * - #else - UInt32 - #endif - CPpmd_Void_Ref; - -typedef - #ifdef PPMD_32BIT - Byte * - #else - UInt32 - #endif - CPpmd_Byte_Ref; - -#define PPMD_SetAllBitsIn256Bytes(p) \ - { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ - p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Ppmd7.c b/utils/lzma/C/Ppmd7.c deleted file mode 100644 index bb5d175e..00000000 --- a/utils/lzma/C/Ppmd7.c +++ /dev/null @@ -1,710 +0,0 @@ -/* Ppmd7.c -- PPMdH codec -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include - -#include "Ppmd7.h" - -const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; - -#define MAX_FREQ 124 -#define UNIT_SIZE 12 - -#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) -#define I2U(indx) (p->Indx2Units[indx]) - -#ifdef PPMD_32BIT - #define REF(ptr) (ptr) -#else - #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) -#endif - -#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) - -#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) -#define STATS(ctx) Ppmd7_GetStats(p, ctx) -#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) -#define SUFFIX(ctx) CTX((ctx)->Suffix) - -typedef CPpmd7_Context * CTX_PTR; - -struct CPpmd7_Node_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Node_ * - #else - UInt32 - #endif - CPpmd7_Node_Ref; - -typedef struct CPpmd7_Node_ -{ - UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ - UInt16 NU; - CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ - CPpmd7_Node_Ref Prev; -} CPpmd7_Node; - -#ifdef PPMD_32BIT - #define NODE(ptr) (ptr) -#else - #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) -#endif - -void Ppmd7_Construct(CPpmd7 *p) -{ - unsigned i, k, m; - - p->Base = 0; - - for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) - { - unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while(--step); - p->Indx2Units[i] = (Byte)k; - } - - p->NS2BSIndx[0] = (0 << 1); - p->NS2BSIndx[1] = (1 << 1); - memset(p->NS2BSIndx + 2, (2 << 1), 9); - memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); - - for (i = 0; i < 3; i++) - p->NS2Indx[i] = (Byte)i; - for (m = i, k = 1; i < 256; i++) - { - p->NS2Indx[i] = (Byte)m; - if (--k == 0) - k = (++m) - 2; - } - - memset(p->HB2Flag, 0, 0x40); - memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); -} - -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->Base); - p->Size = 0; - p->Base = 0; -} - -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) -{ - if (p->Base == 0 || p->Size != size) - { - Ppmd7_Free(p, alloc); - p->AlignOffset = - #ifdef PPMD_32BIT - (4 - size) & 3; - #else - 4 - (size & 3); - #endif - if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size - #ifndef PPMD_32BIT - + UNIT_SIZE - #endif - )) == 0) - return False; - p->Size = size; - } - return True; -} - -static void InsertNode(CPpmd7 *p, void *node, unsigned indx) -{ - *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; - p->FreeList[indx] = REF(node); -} - -static void *RemoveNode(CPpmd7 *p, unsigned indx) -{ - CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); - p->FreeList[indx] = *node; - return node; -} - -static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) -{ - unsigned i, nu = I2U(oldIndx) - I2U(newIndx); - ptr = (Byte *)ptr + U2B(I2U(newIndx)); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); - } - InsertNode(p, ptr, i); -} - -static void GlueFreeBlocks(CPpmd7 *p) -{ - #ifdef PPMD_32BIT - CPpmd7_Node headItem; - CPpmd7_Node_Ref head = &headItem; - #else - CPpmd7_Node_Ref head = p->AlignOffset + p->Size; - #endif - - CPpmd7_Node_Ref n = head; - unsigned i; - - p->GlueCount = 255; - - /* create doubly-linked list of free blocks */ - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - UInt16 nu = I2U(i); - CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; - p->FreeList[i] = 0; - while (next != 0) - { - CPpmd7_Node *node = NODE(next); - node->Next = n; - n = NODE(n)->Prev = next; - next = *(const CPpmd7_Node_Ref *)node; - node->Stamp = 0; - node->NU = (UInt16)nu; - } - } - NODE(head)->Stamp = 1; - NODE(head)->Next = n; - NODE(n)->Prev = head; - if (p->LoUnit != p->HiUnit) - ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; - - /* Glue free blocks */ - while (n != head) - { - CPpmd7_Node *node = NODE(n); - UInt32 nu = (UInt32)node->NU; - for (;;) - { - CPpmd7_Node *node2 = NODE(n) + nu; - nu += node2->NU; - if (node2->Stamp != 0 || nu >= 0x10000) - break; - NODE(node2->Prev)->Next = node2->Next; - NODE(node2->Next)->Prev = node2->Prev; - node->NU = (UInt16)nu; - } - n = node->Next; - } - - /* Fill lists of free blocks */ - for (n = NODE(head)->Next; n != head;) - { - CPpmd7_Node *node = NODE(n); - unsigned nu; - CPpmd7_Node_Ref next = node->Next; - for (nu = node->NU; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, node + k, nu - k - 1); - } - InsertNode(p, node, i); - n = next; - } -} - -static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) -{ - unsigned i; - void *retVal; - if (p->GlueCount == 0) - { - GlueFreeBlocks(p); - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - } - i = indx; - do - { - if (++i == PPMD_NUM_INDEXES) - { - UInt32 numBytes = U2B(I2U(indx)); - p->GlueCount--; - return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); - } - } - while (p->FreeList[i] == 0); - retVal = RemoveNode(p, i); - SplitBlock(p, retVal, i, indx); - return retVal; -} - -static void *AllocUnits(CPpmd7 *p, unsigned indx) -{ - UInt32 numBytes; - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - numBytes = U2B(I2U(indx)); - if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) - { - void *retVal = p->LoUnit; - p->LoUnit += numBytes; - return retVal; - } - return AllocUnitsRare(p, indx); -} - -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } - -static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) -{ - unsigned i0 = U2I(oldNU); - unsigned i1 = U2I(newNU); - if (i0 == i1) - return oldPtr; - if (p->FreeList[i1] != 0) - { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); - return ptr; - } - SplitBlock(p, oldPtr, i0, i1); - return oldPtr; -} - -#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) - -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) -{ - (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); -} - -static void RestartModel(CPpmd7 *p) -{ - unsigned i, k, m; - - memset(p->FreeList, 0, sizeof(p->FreeList)); - p->Text = p->Base + p->AlignOffset; - p->HiUnit = p->Text + p->Size; - p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; - p->GlueCount = 0; - - p->OrderFall = p->MaxOrder; - p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; - p->PrevSuccess = 0; - - p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - p->MinContext->Suffix = 0; - p->MinContext->NumStats = 256; - p->MinContext->SummFreq = 256 + 1; - p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ - p->LoUnit += U2B(256 / 2); - p->MinContext->Stats = REF(p->FoundState); - for (i = 0; i < 256; i++) - { - CPpmd_State *s = &p->FoundState[i]; - s->Symbol = (Byte)i; - s->Freq = 1; - SetSuccessor(s, 0); - } - - for (i = 0; i < 128; i++) - for (k = 0; k < 8; k++) - { - UInt16 *dest = p->BinSumm[i] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); - for (m = 0; m < 64; m += 8) - dest[m] = val; - } - - for (i = 0; i < 25; i++) - for (k = 0; k < 16; k++) - { - CPpmd_See *s = &p->See[i][k]; - s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); - s->Count = 4; - } -} - -void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) -{ - p->MaxOrder = maxOrder; - RestartModel(p); - p->DummySee.Shift = PPMD_PERIOD_BITS; - p->DummySee.Summ = 0; /* unused */ - p->DummySee.Count = 64; /* unused */ -} - -static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) -{ - CPpmd_State upState; - CTX_PTR c = p->MinContext; - CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); - CPpmd_State *ps[PPMD7_MAX_ORDER]; - unsigned numPs = 0; - - if (!skip) - ps[numPs++] = p->FoundState; - - while (c->Suffix) - { - CPpmd_Void_Ref successor; - CPpmd_State *s; - c = SUFFIX(c); - if (c->NumStats != 1) - { - for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); - } - else - s = ONE_STATE(c); - successor = SUCCESSOR(s); - if (successor != upBranch) - { - c = CTX(successor); - if (numPs == 0) - return c; - break; - } - ps[numPs++] = s; - } - - upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); - SetSuccessor(&upState, upBranch + 1); - - if (c->NumStats == 1) - upState.Freq = ONE_STATE(c)->Freq; - else - { - UInt32 cf, s0; - CPpmd_State *s; - for (s = STATS(c); s->Symbol != upState.Symbol; s++); - cf = s->Freq - 1; - s0 = c->SummFreq - c->NumStats - cf; - upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); - } - - do - { - /* Create Child */ - CTX_PTR c1; /* = AllocContext(p); */ - if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); - else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); - else - { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); - if (!c1) - return NULL; - } - c1->NumStats = 1; - *ONE_STATE(c1) = upState; - c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); - c = c1; - } - while (numPs != 0); - - return c; -} - -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) -{ - CPpmd_State tmp = *t1; - *t1 = *t2; - *t2 = tmp; -} - -static void UpdateModel(CPpmd7 *p) -{ - CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; - unsigned s0, ns; - - if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) - { - c = SUFFIX(p->MinContext); - - if (c->NumStats == 1) - { - CPpmd_State *s = ONE_STATE(c); - if (s->Freq < 32) - s->Freq++; - } - else - { - CPpmd_State *s = STATS(c); - if (s->Symbol != p->FoundState->Symbol) - { - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s[0].Freq >= s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - s--; - } - } - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - } - - if (p->OrderFall == 0) - { - p->MinContext = p->MaxContext = CreateSuccessors(p, True); - if (p->MinContext == 0) - { - RestartModel(p); - return; - } - SetSuccessor(p->FoundState, REF(p->MinContext)); - return; - } - - *p->Text++ = p->FoundState->Symbol; - successor = REF(p->Text); - if (p->Text >= p->UnitsStart) - { - RestartModel(p); - return; - } - - if (fSuccessor) - { - if (fSuccessor <= successor) - { - CTX_PTR cs = CreateSuccessors(p, False); - if (cs == NULL) - { - RestartModel(p); - return; - } - fSuccessor = REF(cs); - } - if (--p->OrderFall == 0) - { - successor = fSuccessor; - p->Text -= (p->MaxContext != p->MinContext); - } - } - else - { - SetSuccessor(p->FoundState, successor); - fSuccessor = REF(p->MinContext); - } - - s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); - - for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) - { - unsigned ns1; - UInt32 cf, sf; - if ((ns1 = c->NumStats) != 1) - { - if ((ns1 & 1) == 0) - { - /* Expand for one UNIT */ - unsigned oldNU = ns1 >> 1; - unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) - { - void *ptr = AllocUnits(p, i + 1); - void *oldPtr; - if (!ptr) - { - RestartModel(p); - return; - } - oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); - c->Stats = STATS_REF(ptr); - } - } - c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); - } - else - { - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); - if (!s) - { - RestartModel(p); - return; - } - *s = *ONE_STATE(c); - c->Stats = REF(s); - if (s->Freq < MAX_FREQ / 4 - 1) - s->Freq <<= 1; - else - s->Freq = MAX_FREQ - 4; - c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); - } - cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); - sf = (UInt32)s0 + c->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf) + (cf >= 4 * sf); - c->SummFreq += 3; - } - else - { - cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); - c->SummFreq = (UInt16)(c->SummFreq + cf); - } - { - CPpmd_State *s = STATS(c) + ns1; - SetSuccessor(s, successor); - s->Symbol = p->FoundState->Symbol; - s->Freq = (Byte)cf; - c->NumStats = (UInt16)(ns1 + 1); - } - } - p->MaxContext = p->MinContext = CTX(fSuccessor); -} - -static void Rescale(CPpmd7 *p) -{ - unsigned i, adder, sumFreq, escFreq; - CPpmd_State *stats = STATS(p->MinContext); - CPpmd_State *s = p->FoundState; - { - CPpmd_State tmp = *s; - for (; s != stats; s--) - s[0] = s[-1]; - *s = tmp; - } - escFreq = p->MinContext->SummFreq - s->Freq; - s->Freq += 4; - adder = (p->OrderFall != 0); - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq = s->Freq; - - i = p->MinContext->NumStats - 1; - do - { - escFreq -= (++s)->Freq; - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq += s->Freq; - if (s[0].Freq > s[-1].Freq) - { - CPpmd_State *s1 = s; - CPpmd_State tmp = *s1; - do - s1[0] = s1[-1]; - while (--s1 != stats && tmp.Freq > s1[-1].Freq); - *s1 = tmp; - } - } - while (--i); - - if (s->Freq == 0) - { - unsigned numStats = p->MinContext->NumStats; - unsigned n0, n1; - do { i++; } while ((--s)->Freq == 0); - escFreq += i; - p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); - if (p->MinContext->NumStats == 1) - { - CPpmd_State tmp = *stats; - do - { - tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); - escFreq >>= 1; - } - while (escFreq > 1); - InsertNode(p, stats, U2I(((numStats + 1) >> 1))); - *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; - return; - } - n0 = (numStats + 1) >> 1; - n1 = (p->MinContext->NumStats + 1) >> 1; - if (n0 != n1) - p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); - } - p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); - p->FoundState = STATS(p->MinContext); -} - -CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) -{ - CPpmd_See *see; - unsigned nonMasked = p->MinContext->NumStats - numMasked; - if (p->MinContext->NumStats != 256) - { - see = p->See[p->NS2Indx[nonMasked - 1]] + - (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + - 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + - 4 * (numMasked > nonMasked) + - p->HiBitsFlag; - { - unsigned r = (see->Summ >> see->Shift); - see->Summ = (UInt16)(see->Summ - r); - *escFreq = r + (r == 0); - } - } - else - { - see = &p->DummySee; - *escFreq = 1; - } - return see; -} - -static void NextContext(CPpmd7 *p) -{ - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); - if (p->OrderFall == 0 && (Byte *)c > p->Text) - p->MinContext = p->MaxContext = c; - else - UpdateModel(p); -} - -void Ppmd7_Update1(CPpmd7 *p) -{ - CPpmd_State *s = p->FoundState; - s->Freq += 4; - p->MinContext->SummFreq += 4; - if (s[0].Freq > s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - p->FoundState = --s; - if (s->Freq > MAX_FREQ) - Rescale(p); - } - NextContext(p); -} - -void Ppmd7_Update1_0(CPpmd7 *p) -{ - p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); - p->RunLength += p->PrevSuccess; - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - NextContext(p); -} - -void Ppmd7_UpdateBin(CPpmd7 *p) -{ - p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); - p->PrevSuccess = 1; - p->RunLength++; - NextContext(p); -} - -void Ppmd7_Update2(CPpmd7 *p) -{ - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - p->RunLength = p->InitRL; - UpdateModel(p); -} diff --git a/utils/lzma/C/Ppmd7.h b/utils/lzma/C/Ppmd7.h deleted file mode 100644 index 96521c31..00000000 --- a/utils/lzma/C/Ppmd7.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Ppmd7.h -- PPMdH compression codec -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -/* This code supports virtual RangeDecoder and includes the implementation -of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. -If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ - -#ifndef __PPMD7_H -#define __PPMD7_H - -#include "Ppmd.h" - -EXTERN_C_BEGIN - -#define PPMD7_MIN_ORDER 2 -#define PPMD7_MAX_ORDER 64 - -#define PPMD7_MIN_MEM_SIZE (1 << 11) -#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) - -struct CPpmd7_Context_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Context_ * - #else - UInt32 - #endif - CPpmd7_Context_Ref; - -typedef struct CPpmd7_Context_ -{ - UInt16 NumStats; - UInt16 SummFreq; - CPpmd_State_Ref Stats; - CPpmd7_Context_Ref Suffix; -} CPpmd7_Context; - -#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) - -typedef struct -{ - CPpmd7_Context *MinContext, *MaxContext; - CPpmd_State *FoundState; - unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; - Int32 RunLength, InitRL; /* must be 32-bit at least */ - - UInt32 Size; - UInt32 GlueCount; - Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; - UInt32 AlignOffset; - - Byte Indx2Units[PPMD_NUM_INDEXES]; - Byte Units2Indx[128]; - CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; - Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; - CPpmd_See DummySee, See[25][16]; - UInt16 BinSumm[128][64]; -} CPpmd7; - -void Ppmd7_Construct(CPpmd7 *p); -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); -void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); -#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) - - -/* ---------- Internal Functions ---------- */ - -extern const Byte PPMD7_kExpEscape[16]; - -#ifdef PPMD_32BIT - #define Ppmd7_GetPtr(p, ptr) (ptr) - #define Ppmd7_GetContext(p, ptr) (ptr) - #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) -#else - #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) - #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) - #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) -#endif - -void Ppmd7_Update1(CPpmd7 *p); -void Ppmd7_Update1_0(CPpmd7 *p); -void Ppmd7_Update2(CPpmd7 *p); -void Ppmd7_UpdateBin(CPpmd7 *p); - -#define Ppmd7_GetBinSumm(p) \ - &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ - p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ - (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ - 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ - ((p->RunLength >> 26) & 0x20)] - -CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); - - -/* ---------- Decode ---------- */ - -typedef struct -{ - UInt32 (*GetThreshold)(void *p, UInt32 total); - void (*Decode)(void *p, UInt32 start, UInt32 size); - UInt32 (*DecodeBit)(void *p, UInt32 size0); -} IPpmd7_RangeDec; - -typedef struct -{ - IPpmd7_RangeDec p; - UInt32 Range; - UInt32 Code; - IByteIn *Stream; -} CPpmd7z_RangeDec; - -void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); -Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); -#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) - -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); - - -/* ---------- Encode ---------- */ - -typedef struct -{ - UInt64 Low; - UInt32 Range; - Byte Cache; - UInt64 CacheSize; - IByteOut *Stream; -} CPpmd7z_RangeEnc; - -void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); -void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); - -void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Ppmd7Dec.c b/utils/lzma/C/Ppmd7Dec.c deleted file mode 100644 index 04b4b09e..00000000 --- a/utils/lzma/C/Ppmd7Dec.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Ppmd7Dec.c -- PPMdH Decoder -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd7.h" - -#define kTopValue (1 << 24) - -Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) -{ - unsigned i; - p->Code = 0; - p->Range = 0xFFFFFFFF; - if (p->Stream->Read((void *)p->Stream) != 0) - return False; - for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - return (p->Code < 0xFFFFFFFF); -} - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - return (p->Code) / (p->Range /= total); -} - -static void Range_Normalize(CPpmd7z_RangeDec *p) -{ - if (p->Range < kTopValue) - { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - p->Range <<= 8; - if (p->Range < kTopValue) - { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - p->Range <<= 8; - } - } -} - -static void Range_Decode(void *pp, UInt32 start, UInt32 size) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - p->Code -= start * p->Range; - p->Range *= size; - Range_Normalize(p); -} - -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - UInt32 newBound = (p->Range >> 14) * size0; - UInt32 symbol; - if (p->Code < newBound) - { - symbol = 0; - p->Range = newBound; - } - else - { - symbol = 1; - p->Code -= newBound; - p->Range -= newBound; - } - Range_Normalize(p); - return symbol; -} - -void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) -{ - p->p.GetThreshold = Range_GetThreshold; - p->p.Decode = Range_Decode; - p->p.DecodeBit = Range_DecodeBit; -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - unsigned i; - UInt32 count, hiCnt; - if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) - { - Byte symbol; - rc->Decode(rc, 0, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1_0(p); - return symbol; - } - p->PrevSuccess = 0; - i = p->MinContext->NumStats - 1; - do - { - if ((hiCnt += (++s)->Freq) > count) - { - Byte symbol; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1(p); - return symbol; - } - } - while (--i); - if (count >= p->MinContext->SummFreq) - return -2; - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - if (rc->DecodeBit(rc, *prob) == 0) - { - Byte symbol; - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; - Ppmd7_UpdateBin(p); - return symbol; - } - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; - p->PrevSuccess = 0; - } - for (;;) - { - CPpmd_State *ps[256], *s; - UInt32 freqSum, count, hiCnt; - CPpmd_See *see; - unsigned i, num, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return -1; - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - hiCnt = 0; - s = Ppmd7_GetStats(p, p->MinContext); - i = 0; - num = p->MinContext->NumStats - numMasked; - do - { - int k = (int)(MASK(s->Symbol)); - hiCnt += (s->Freq & k); - ps[i] = s++; - i -= k; - } - while (i != num); - - see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); - freqSum += hiCnt; - count = rc->GetThreshold(rc, freqSum); - - if (count < hiCnt) - { - Byte symbol; - CPpmd_State **pps = ps; - for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); - s = *pps; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - Ppmd_See_Update(see); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update2(p); - return symbol; - } - if (count >= freqSum) - return -2; - rc->Decode(rc, hiCnt, freqSum - hiCnt); - see->Summ = (UInt16)(see->Summ + freqSum); - do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); - } -} diff --git a/utils/lzma/C/Ppmd7Enc.c b/utils/lzma/C/Ppmd7Enc.c deleted file mode 100644 index 51c19c9f..00000000 --- a/utils/lzma/C/Ppmd7Enc.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Ppmd7Enc.c -- PPMdH Encoder -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd7.h" - -#define kTopValue (1 << 24) - -void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p) -{ - p->Low = 0; - p->Range = 0xFFFFFFFF; - p->Cache = 0; - p->CacheSize = 1; -} - -static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) -{ - if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0) - { - Byte temp = p->Cache; - do - { - p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); - temp = 0xFF; - } - while(--p->CacheSize != 0); - p->Cache = (Byte)((UInt32)p->Low >> 24); - } - p->CacheSize++; - p->Low = (UInt32)p->Low << 8; -} - -static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) -{ - p->Low += start * (p->Range /= total); - p->Range *= size; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - p->Range = (p->Range >> 14) * size0; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - UInt32 newBound = (p->Range >> 14) * size0; - p->Low += newBound; - p->Range -= newBound; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p) -{ - unsigned i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - UInt32 sum; - unsigned i; - if (s->Symbol == symbol) - { - RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1_0(p); - return; - } - p->PrevSuccess = 0; - sum = s->Freq; - i = p->MinContext->NumStats - 1; - do - { - if ((++s)->Symbol == symbol) - { - RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1(p); - return; - } - sum += s->Freq; - } - while (--i); - - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); - if (s->Symbol == symbol) - { - RangeEnc_EncodeBit_0(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - p->FoundState = s; - Ppmd7_UpdateBin(p); - return; - } - else - { - RangeEnc_EncodeBit_1(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - p->PrevSuccess = 0; - } - } - for (;;) - { - UInt32 escFreq; - CPpmd_See *see; - CPpmd_State *s; - UInt32 sum; - unsigned i, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return; /* EndMarker (symbol = -1) */ - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - - see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); - s = Ppmd7_GetStats(p, p->MinContext); - sum = 0; - i = p->MinContext->NumStats; - do - { - int cur = s->Symbol; - if (cur == symbol) - { - UInt32 low = sum; - CPpmd_State *s1 = s; - do - { - sum += (s->Freq & (int)(MASK(s->Symbol))); - s++; - } - while (--i); - RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq); - Ppmd_See_Update(see); - p->FoundState = s1; - Ppmd7_Update2(p); - return; - } - sum += (s->Freq & (int)(MASK(cur))); - MASK(cur) = 0; - s++; - } - while (--i); - - RangeEnc_Encode(rc, sum, escFreq, sum + escFreq); - see->Summ = (UInt16)(see->Summ + sum + escFreq); - } -} diff --git a/utils/lzma/C/Precomp.h b/utils/lzma/C/Precomp.h deleted file mode 100644 index e8ff8b40..00000000 --- a/utils/lzma/C/Precomp.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Precomp.h -- StdAfx -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "Compiler.h" -/* #include "7zTypes.h" */ - -#endif diff --git a/utils/lzma/C/RotateDefs.h b/utils/lzma/C/RotateDefs.h deleted file mode 100644 index 1b83e5ea..00000000 --- a/utils/lzma/C/RotateDefs.h +++ /dev/null @@ -1,26 +0,0 @@ -/* RotateDefs.h -- Rotate functions -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __ROTATE_DEFS_H -#define __ROTATE_DEFS_H - -#ifdef _MSC_VER - -#include - -// #if (_MSC_VER >= 1200) -#pragma intrinsic(_rotl) -#pragma intrinsic(_rotr) -// #endif - -#define rotlFixed(x, n) _rotl((x), (n)) -#define rotrFixed(x, n) _rotr((x), (n)) - -#else - -#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) -#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) - -#endif - -#endif diff --git a/utils/lzma/C/Sha256.c b/utils/lzma/C/Sha256.c deleted file mode 100644 index db0c7061..00000000 --- a/utils/lzma/C/Sha256.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Crypto/Sha256.c -- SHA-256 Hash -2010-06-11 : Igor Pavlov : Public domain -This code is based on public domain code from Wei Dai's Crypto++ library. */ - -#include "Precomp.h" - -#include "RotateDefs.h" -#include "Sha256.h" - -/* define it for speed optimization */ -/* #define _SHA256_UNROLL */ -/* #define _SHA256_UNROLL2 */ - -void Sha256_Init(CSha256 *p) -{ - p->state[0] = 0x6a09e667; - p->state[1] = 0xbb67ae85; - p->state[2] = 0x3c6ef372; - p->state[3] = 0xa54ff53a; - p->state[4] = 0x510e527f; - p->state[5] = 0x9b05688c; - p->state[6] = 0x1f83d9ab; - p->state[7] = 0x5be0cd19; - p->count = 0; -} - -#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) -#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) -#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) -#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) - -#define blk0(i) (W[i] = data[i]) -#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15])) - -#define Ch(x,y,z) (z^(x&(y^z))) -#define Maj(x,y,z) ((x&y)|(z&(x|y))) - -#define a(i) T[(0-(i))&7] -#define b(i) T[(1-(i))&7] -#define c(i) T[(2-(i))&7] -#define d(i) T[(3-(i))&7] -#define e(i) T[(4-(i))&7] -#define f(i) T[(5-(i))&7] -#define g(i) T[(6-(i))&7] -#define h(i) T[(7-(i))&7] - - -#ifdef _SHA256_UNROLL2 - -#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\ - d += h; h += S0(a) + Maj(a, b, c) - -#define RX_8(i) \ - R(a,b,c,d,e,f,g,h, i); \ - R(h,a,b,c,d,e,f,g, i+1); \ - R(g,h,a,b,c,d,e,f, i+2); \ - R(f,g,h,a,b,c,d,e, i+3); \ - R(e,f,g,h,a,b,c,d, i+4); \ - R(d,e,f,g,h,a,b,c, i+5); \ - R(c,d,e,f,g,h,a,b, i+6); \ - R(b,c,d,e,f,g,h,a, i+7) - -#else - -#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\ - d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) - -#ifdef _SHA256_UNROLL - -#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); - -#endif - -#endif - -static const UInt32 K[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -static void Sha256_Transform(UInt32 *state, const UInt32 *data) -{ - UInt32 W[16]; - unsigned j; - #ifdef _SHA256_UNROLL2 - UInt32 a,b,c,d,e,f,g,h; - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - f = state[5]; - g = state[6]; - h = state[7]; - #else - UInt32 T[8]; - for (j = 0; j < 8; j++) - T[j] = state[j]; - #endif - - for (j = 0; j < 64; j += 16) - { - #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2) - RX_8(0); RX_8(8); - #else - unsigned i; - for (i = 0; i < 16; i++) { R(i); } - #endif - } - - #ifdef _SHA256_UNROLL2 - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - state[5] += f; - state[6] += g; - state[7] += h; - #else - for (j = 0; j < 8; j++) - state[j] += T[j]; - #endif - - /* Wipe variables */ - /* memset(W, 0, sizeof(W)); */ - /* memset(T, 0, sizeof(T)); */ -} - -#undef S0 -#undef S1 -#undef s0 -#undef s1 - -static void Sha256_WriteByteBlock(CSha256 *p) -{ - UInt32 data32[16]; - unsigned i; - for (i = 0; i < 16; i++) - data32[i] = - ((UInt32)(p->buffer[i * 4 ]) << 24) + - ((UInt32)(p->buffer[i * 4 + 1]) << 16) + - ((UInt32)(p->buffer[i * 4 + 2]) << 8) + - ((UInt32)(p->buffer[i * 4 + 3])); - Sha256_Transform(p->state, data32); -} - -void Sha256_Update(CSha256 *p, const Byte *data, size_t size) -{ - UInt32 curBufferPos = (UInt32)p->count & 0x3F; - while (size > 0) - { - p->buffer[curBufferPos++] = *data++; - p->count++; - size--; - if (curBufferPos == 64) - { - curBufferPos = 0; - Sha256_WriteByteBlock(p); - } - } -} - -void Sha256_Final(CSha256 *p, Byte *digest) -{ - UInt64 lenInBits = (p->count << 3); - UInt32 curBufferPos = (UInt32)p->count & 0x3F; - unsigned i; - p->buffer[curBufferPos++] = 0x80; - while (curBufferPos != (64 - 8)) - { - curBufferPos &= 0x3F; - if (curBufferPos == 0) - Sha256_WriteByteBlock(p); - p->buffer[curBufferPos++] = 0; - } - for (i = 0; i < 8; i++) - { - p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56); - lenInBits <<= 8; - } - Sha256_WriteByteBlock(p); - - for (i = 0; i < 8; i++) - { - *digest++ = (Byte)(p->state[i] >> 24); - *digest++ = (Byte)(p->state[i] >> 16); - *digest++ = (Byte)(p->state[i] >> 8); - *digest++ = (Byte)(p->state[i]); - } - Sha256_Init(p); -} diff --git a/utils/lzma/C/Sha256.h b/utils/lzma/C/Sha256.h deleted file mode 100644 index 3f455dbc..00000000 --- a/utils/lzma/C/Sha256.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Sha256.h -- SHA-256 Hash -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __CRYPTO_SHA256_H -#define __CRYPTO_SHA256_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define SHA256_DIGEST_SIZE 32 - -typedef struct -{ - UInt32 state[8]; - UInt64 count; - Byte buffer[64]; -} CSha256; - -void Sha256_Init(CSha256 *p); -void Sha256_Update(CSha256 *p, const Byte *data, size_t size); -void Sha256_Final(CSha256 *p, Byte *digest); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Sort.c b/utils/lzma/C/Sort.c deleted file mode 100644 index e1097e38..00000000 --- a/utils/lzma/C/Sort.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Sort.c -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Sort.h" - -#define HeapSortDown(p, k, size, temp) \ - { for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && p[s + 1] > p[s]) s++; \ - if (temp >= p[s]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } - -void HeapSort(UInt32 *p, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt32 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt32 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) - } - { - UInt32 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) - { - p[1] = p[2]; - p[2] = temp; - } - else - p[1] = temp; - } -} - -void HeapSort64(UInt64 *p, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt64 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt64 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt64 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) - } - { - UInt64 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) - { - p[1] = p[2]; - p[2] = temp; - } - else - p[1] = temp; - } -} - -/* -#define HeapSortRefDown(p, vals, n, size, temp) \ - { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ - if (val >= vals[p[s]]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } - -void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt32 temp = p[i]; - HeapSortRefDown(p, vals, i, size, temp); - } - while (--i != 0); - } - do - { - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortRefDown(p, vals, 1, size, temp); - } - while (size > 1); -} -*/ diff --git a/utils/lzma/C/Sort.h b/utils/lzma/C/Sort.h deleted file mode 100644 index 2e2963a2..00000000 --- a/utils/lzma/C/Sort.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Sort.h -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ - -#ifndef __7Z_SORT_H -#define __7Z_SORT_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -void HeapSort(UInt32 *p, size_t size); -void HeapSort64(UInt64 *p, size_t size); - -/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Threads.c b/utils/lzma/C/Threads.c deleted file mode 100644 index d71e13a4..00000000 --- a/utils/lzma/C/Threads.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Threads.c -- multithreading library -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#ifndef _WIN32_WCE -#include -#endif - -#include "Threads.h" - -static WRes GetError() -{ - DWORD res = GetLastError(); - return (res) ? (WRes)(res) : 1; -} - -WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } -WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } - -WRes HandlePtr_Close(HANDLE *p) -{ - if (*p != NULL) - if (!CloseHandle(*p)) - return GetError(); - *p = NULL; - return 0; -} - -WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } - -WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) -{ - /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ - - #ifdef UNDER_CE - - DWORD threadId; - *p = CreateThread(0, 0, func, param, 0, &threadId); - - #else - - unsigned threadId; - *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); - - #endif - - /* maybe we must use errno here, but probably GetLastError() is also OK. */ - return HandleToWRes(*p); -} - -WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) -{ - *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); - return HandleToWRes(*p); -} - -WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } -WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } - -WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } -WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } - - -WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) -{ - *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); - return HandleToWRes(*p); -} - -static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) - { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) - { return Semaphore_Release(p, (LONG)num, NULL); } -WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } - -WRes CriticalSection_Init(CCriticalSection *p) -{ - /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ - #ifdef _MSC_VER - __try - #endif - { - InitializeCriticalSection(p); - /* InitializeCriticalSectionAndSpinCount(p, 0); */ - } - #ifdef _MSC_VER - __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } - #endif - return 0; -} diff --git a/utils/lzma/C/Threads.h b/utils/lzma/C/Threads.h deleted file mode 100644 index 9b3e1c55..00000000 --- a/utils/lzma/C/Threads.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Threads.h -- multithreading library -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_THREADS_H -#define __7Z_THREADS_H - -#ifdef _WIN32 -#include -#endif - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -WRes HandlePtr_Close(HANDLE *h); -WRes Handle_WaitObject(HANDLE h); - -typedef HANDLE CThread; -#define Thread_Construct(p) *(p) = NULL -#define Thread_WasCreated(p) (*(p) != NULL) -#define Thread_Close(p) HandlePtr_Close(p) -#define Thread_Wait(p) Handle_WaitObject(*(p)) - -typedef -#ifdef UNDER_CE - DWORD -#else - unsigned -#endif - THREAD_FUNC_RET_TYPE; - -#define THREAD_FUNC_CALL_TYPE MY_STD_CALL -#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE -typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); -WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); - -typedef HANDLE CEvent; -typedef CEvent CAutoResetEvent; -typedef CEvent CManualResetEvent; -#define Event_Construct(p) *(p) = NULL -#define Event_IsCreated(p) (*(p) != NULL) -#define Event_Close(p) HandlePtr_Close(p) -#define Event_Wait(p) Handle_WaitObject(*(p)) -WRes Event_Set(CEvent *p); -WRes Event_Reset(CEvent *p); -WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); -WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); - -typedef HANDLE CSemaphore; -#define Semaphore_Construct(p) (*p) = NULL -#define Semaphore_Close(p) HandlePtr_Close(p) -#define Semaphore_Wait(p) Handle_WaitObject(*(p)) -WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); -WRes Semaphore_Release1(CSemaphore *p); - -typedef CRITICAL_SECTION CCriticalSection; -WRes CriticalSection_Init(CCriticalSection *p); -#define CriticalSection_Delete(p) DeleteCriticalSection(p) -#define CriticalSection_Enter(p) EnterCriticalSection(p) -#define CriticalSection_Leave(p) LeaveCriticalSection(p) - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/Util/7z/7z.dsp b/utils/lzma/C/Util/7z/7z.dsp deleted file mode 100644 index 92818667..00000000 --- a/utils/lzma/C/Util/7z/7z.dsp +++ /dev/null @@ -1,229 +0,0 @@ -# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=7z - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "7z.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "7z - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /Yu"Precomp.h" /FD /c -# ADD BASE RSC /l 0x419 /d "NDEBUG" -# ADD RSC /l 0x419 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7zDec.exe" /opt:NOWIN98 -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "7z - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c -# ADD BASE RSC /l 0x419 /d "_DEBUG" -# ADD RSC /l 0x419 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7zDec.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "7z - Win32 Release" -# Name "7z - Win32 Debug" -# Begin Group "Common" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\7z.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zAlloc.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zAlloc.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zArcIn.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zBuf.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zBuf.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrc.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrc.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrcOpt.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zDec.c -# ADD CPP /D "_7ZIP_PPMD_SUPPPORT" -# End Source File -# Begin Source File - -SOURCE=..\..\7zFile.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zFile.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zStream.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zTypes.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bcj2.c -# End Source File -# Begin Source File - -SOURCE=..\..\Bcj2.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bra.c -# End Source File -# Begin Source File - -SOURCE=..\..\Bra.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bra86.c -# End Source File -# Begin Source File - -SOURCE=..\..\CpuArch.c -# End Source File -# Begin Source File - -SOURCE=..\..\CpuArch.h -# End Source File -# Begin Source File - -SOURCE=..\..\Lzma2Dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\Lzma2Dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.h -# End Source File -# Begin Source File - -SOURCE=..\..\Ppmd.h -# End Source File -# Begin Source File - -SOURCE=..\..\Ppmd7.c -# End Source File -# Begin Source File - -SOURCE=..\..\Ppmd7.h -# End Source File -# Begin Source File - -SOURCE=..\..\Ppmd7Dec.c -# End Source File -# End Group -# Begin Group "Spec" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\Compiler.h -# End Source File -# Begin Source File - -SOURCE=.\Precomp.c -# ADD CPP /Yc"Precomp.h" -# End Source File -# Begin Source File - -SOURCE=.\Precomp.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\7zMain.c -# End Source File -# End Target -# End Project diff --git a/utils/lzma/C/Util/7z/7z.dsw b/utils/lzma/C/Util/7z/7z.dsw deleted file mode 100644 index 848d13cb..00000000 --- a/utils/lzma/C/Util/7z/7z.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "7z"=.\7z.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/utils/lzma/C/Util/7z/7zMain.c b/utils/lzma/C/Util/7z/7zMain.c deleted file mode 100644 index 8ba02efd..00000000 --- a/utils/lzma/C/Util/7z/7zMain.c +++ /dev/null @@ -1,546 +0,0 @@ -/* 7zMain.c - Test application for 7z Decoder -2015-01-02 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include -#include - -#include "../../7z.h" -#include "../../7zAlloc.h" -#include "../../7zBuf.h" -#include "../../7zCrc.h" -#include "../../7zFile.h" -#include "../../7zVersion.h" - -#ifndef USE_WINDOWS_FILE -/* for mkdir */ -#ifdef _WIN32 -#include -#else -#include -#include -#endif -#endif - -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -static int Buf_EnsureSize(CBuf *dest, size_t size) -{ - if (dest->size >= size) - return 1; - Buf_Free(dest, &g_Alloc); - return Buf_Create(dest, size, &g_Alloc); -} - -#ifndef _WIN32 - -static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen) -{ - size_t destPos = 0, srcPos = 0; - for (;;) - { - unsigned numAdds; - UInt32 value; - if (srcPos == srcLen) - { - *destLen = destPos; - return True; - } - value = src[srcPos++]; - if (value < 0x80) - { - if (dest) - dest[destPos] = (char)value; - destPos++; - continue; - } - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2; - if (value >= 0xDC00 || srcPos == srcLen) - break; - c2 = src[srcPos++]; - if (c2 < 0xDC00 || c2 >= 0xE000) - break; - value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; - } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - if (dest) - dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); - destPos++; - do - { - numAdds--; - if (dest) - dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); - destPos++; - } - while (numAdds != 0); - } - *destLen = destPos; - return False; -} - -static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen) -{ - size_t destLen = 0; - Bool res; - Utf16_To_Utf8(NULL, &destLen, src, srcLen); - destLen += 1; - if (!Buf_EnsureSize(dest, destLen)) - return SZ_ERROR_MEM; - res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen); - dest->data[destLen] = 0; - return res ? SZ_OK : SZ_ERROR_FAIL; -} - -#endif - -static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s - #ifdef _WIN32 - , UINT codePage - #endif - ) -{ - unsigned len = 0; - for (len = 0; s[len] != 0; len++); - - #ifdef _WIN32 - { - unsigned size = len * 3 + 100; - if (!Buf_EnsureSize(buf, size)) - return SZ_ERROR_MEM; - { - buf->data[0] = 0; - if (len != 0) - { - char defaultChar = '_'; - BOOL defUsed; - unsigned numChars = 0; - numChars = WideCharToMultiByte(codePage, 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed); - if (numChars == 0 || numChars >= size) - return SZ_ERROR_FAIL; - buf->data[numChars] = 0; - } - return SZ_OK; - } - } - #else - return Utf16_To_Utf8Buf(buf, s, len); - #endif -} - -#ifdef _WIN32 - #ifndef USE_WINDOWS_FILE - static UINT g_FileCodePage = CP_ACP; - #endif - #define MY_FILE_CODE_PAGE_PARAM ,g_FileCodePage -#else - #define MY_FILE_CODE_PAGE_PARAM -#endif - -static WRes MyCreateDir(const UInt16 *name) -{ - #ifdef USE_WINDOWS_FILE - - return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); - - #else - - CBuf buf; - WRes res; - Buf_Init(&buf); - RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)); - - res = - #ifdef _WIN32 - _mkdir((const char *)buf.data) - #else - mkdir((const char *)buf.data, 0777) - #endif - == 0 ? 0 : errno; - Buf_Free(&buf, &g_Alloc); - return res; - - #endif -} - -static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name) -{ - #ifdef USE_WINDOWS_FILE - return OutFile_OpenW(p, name); - #else - CBuf buf; - WRes res; - Buf_Init(&buf); - RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)); - res = OutFile_Open(p, (const char *)buf.data); - Buf_Free(&buf, &g_Alloc); - return res; - #endif -} - -static SRes PrintString(const UInt16 *s) -{ - CBuf buf; - SRes res; - Buf_Init(&buf); - res = Utf16_To_Char(&buf, s - #ifdef _WIN32 - , CP_OEMCP - #endif - ); - if (res == SZ_OK) - fputs((const char *)buf.data, stdout); - Buf_Free(&buf, &g_Alloc); - return res; -} - -static void UInt64ToStr(UInt64 value, char *s) -{ - char temp[32]; - int pos = 0; - do - { - temp[pos++] = (char)('0' + (unsigned)(value % 10)); - value /= 10; - } - while (value != 0); - do - *s++ = temp[--pos]; - while (pos); - *s = '\0'; -} - -static char *UIntToStr(char *s, unsigned value, int numDigits) -{ - char temp[16]; - int pos = 0; - do - temp[pos++] = (char)('0' + (value % 10)); - while (value /= 10); - for (numDigits -= pos; numDigits > 0; numDigits--) - *s++ = '0'; - do - *s++ = temp[--pos]; - while (pos); - *s = '\0'; - return s; -} - -static void UIntToStr_2(char *s, unsigned value) -{ - s[0] = (char)('0' + (value / 10)); - s[1] = (char)('0' + (value % 10)); -} - -#define PERIOD_4 (4 * 365 + 1) -#define PERIOD_100 (PERIOD_4 * 25 - 1) -#define PERIOD_400 (PERIOD_100 * 4 + 1) - -static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s) -{ - unsigned year, mon, hour, min, sec; - Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - unsigned t; - UInt32 v; - UInt64 v64 = nt->Low | ((UInt64)nt->High << 32); - v64 /= 10000000; - sec = (unsigned)(v64 % 60); v64 /= 60; - min = (unsigned)(v64 % 60); v64 /= 60; - hour = (unsigned)(v64 % 24); v64 /= 24; - - v = (UInt32)v64; - - year = (unsigned)(1601 + v / PERIOD_400 * 400); - v %= PERIOD_400; - - t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; - t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; - t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; - - if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) - ms[1] = 29; - for (mon = 0;; mon++) - { - unsigned s = ms[mon]; - if (v < s) - break; - v -= s; - } - s = UIntToStr(s, year, 4); *s++ = '-'; - UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3; - UIntToStr_2(s, (unsigned)v + 1); s[2] = ' '; s += 3; - UIntToStr_2(s, hour); s[2] = ':'; s += 3; - UIntToStr_2(s, min); s[2] = ':'; s += 3; - UIntToStr_2(s, sec); s[2] = 0; -} - -void PrintError(const char *sz) -{ - printf("\nERROR: %s\n", sz); -} - -#ifdef USE_WINDOWS_FILE -static void GetAttribString(UInt32 wa, Bool isDir, char *s) -{ - s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.'); - s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.'); - s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.'); - s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.'); - s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.'); - s[5] = '\0'; -} -#else -static void GetAttribString(UInt32, Bool, char *s) -{ - s[0] = '\0'; -} -#endif - -// #define NUM_PARENTS_MAX 128 - -int MY_CDECL main(int numargs, char *args[]) -{ - CFileInStream archiveStream; - CLookToRead lookStream; - CSzArEx db; - SRes res; - ISzAlloc allocImp; - ISzAlloc allocTempImp; - UInt16 *temp = NULL; - size_t tempSize = 0; - // UInt32 parents[NUM_PARENTS_MAX]; - - printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); - if (numargs == 1) - { - printf( - "Usage: 7zDec \n\n" - "\n" - " e: Extract files from archive (without using directory names)\n" - " l: List contents of archive\n" - " t: Test integrity of archive\n" - " x: eXtract files with full paths\n"); - return 0; - } - if (numargs < 3) - { - PrintError("incorrect command"); - return 1; - } - - #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) - g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - #endif - - allocImp.Alloc = SzAlloc; - allocImp.Free = SzFree; - - allocTempImp.Alloc = SzAllocTemp; - allocTempImp.Free = SzFreeTemp; - - #ifdef UNDER_CE - if (InFile_OpenW(&archiveStream.file, L"\test.7z")) - #else - if (InFile_Open(&archiveStream.file, args[2])) - #endif - { - PrintError("can not open input file"); - return 1; - } - - FileInStream_CreateVTable(&archiveStream); - LookToRead_CreateVTable(&lookStream, False); - - lookStream.realStream = &archiveStream.s; - LookToRead_Init(&lookStream); - - CrcGenerateTable(); - - SzArEx_Init(&db); - res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); - if (res == SZ_OK) - { - char *command = args[1]; - int listCommand = 0, testCommand = 0, fullPaths = 0; - if (strcmp(command, "l") == 0) listCommand = 1; - else if (strcmp(command, "t") == 0) testCommand = 1; - else if (strcmp(command, "e") == 0) { } - else if (strcmp(command, "x") == 0) { fullPaths = 1; } - else - { - PrintError("incorrect command"); - res = SZ_ERROR_FAIL; - } - - if (res == SZ_OK) - { - UInt32 i; - - /* - if you need cache, use these 3 variables. - if you use external function, you can make these variable as static. - */ - UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ - Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ - size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ - - for (i = 0; i < db.NumFiles; i++) - { - size_t offset = 0; - size_t outSizeProcessed = 0; - // const CSzFileItem *f = db.Files + i; - size_t len; - int isDir = SzArEx_IsDir(&db, i); - if (listCommand == 0 && isDir && !fullPaths) - continue; - len = SzArEx_GetFileNameUtf16(&db, i, NULL); - // len = SzArEx_GetFullNameLen(&db, i); - - if (len > tempSize) - { - SzFree(NULL, temp); - tempSize = len; - temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); - if (!temp) - { - res = SZ_ERROR_MEM; - break; - } - } - - SzArEx_GetFileNameUtf16(&db, i, temp); - /* - if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) - { - res = SZ_ERROR_FAIL; - break; - } - */ - - if (listCommand) - { - char attr[8], s[32], t[32]; - UInt64 fileSize; - - GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); - - fileSize = SzArEx_GetFileSize(&db, i); - UInt64ToStr(fileSize, s); - if (SzBitWithVals_Check(&db.MTime, i)) - ConvertFileTimeToString(&db.MTime.Vals[i], t); - else - { - size_t j; - for (j = 0; j < 19; j++) - t[j] = ' '; - t[j] = '\0'; - } - - printf("%s %s %10s ", t, attr, s); - res = PrintString(temp); - if (res != SZ_OK) - break; - if (isDir) - printf("/"); - printf("\n"); - continue; - } - fputs(testCommand ? - "Testing ": - "Extracting ", - stdout); - res = PrintString(temp); - if (res != SZ_OK) - break; - if (isDir) - printf("/"); - else - { - res = SzArEx_Extract(&db, &lookStream.s, i, - &blockIndex, &outBuffer, &outBufferSize, - &offset, &outSizeProcessed, - &allocImp, &allocTempImp); - if (res != SZ_OK) - break; - } - if (!testCommand) - { - CSzFile outFile; - size_t processedSize; - size_t j; - UInt16 *name = (UInt16 *)temp; - const UInt16 *destPath = (const UInt16 *)name; - for (j = 0; name[j] != 0; j++) - if (name[j] == '/') - { - if (fullPaths) - { - name[j] = 0; - MyCreateDir(name); - name[j] = CHAR_PATH_SEPARATOR; - } - else - destPath = name + j + 1; - } - - if (isDir) - { - MyCreateDir(destPath); - printf("\n"); - continue; - } - else if (OutFile_OpenUtf16(&outFile, destPath)) - { - PrintError("can not open output file"); - res = SZ_ERROR_FAIL; - break; - } - processedSize = outSizeProcessed; - if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) - { - PrintError("can not write output file"); - res = SZ_ERROR_FAIL; - break; - } - if (File_Close(&outFile)) - { - PrintError("can not close output file"); - res = SZ_ERROR_FAIL; - break; - } - #ifdef USE_WINDOWS_FILE - if (SzBitWithVals_Check(&db.Attribs, i)) - SetFileAttributesW(destPath, db.Attribs.Vals[i]); - #endif - } - printf("\n"); - } - IAlloc_Free(&allocImp, outBuffer); - } - } - SzArEx_Free(&db, &allocImp); - SzFree(NULL, temp); - - File_Close(&archiveStream.file); - if (res == SZ_OK) - { - printf("\nEverything is Ok\n"); - return 0; - } - if (res == SZ_ERROR_UNSUPPORTED) - PrintError("decoder doesn't support this archive"); - else if (res == SZ_ERROR_MEM) - PrintError("can not allocate memory"); - else if (res == SZ_ERROR_CRC) - PrintError("CRC error"); - else - printf("\nERROR #%d\n", res); - return 1; -} diff --git a/utils/lzma/C/Util/7z/Precomp.c b/utils/lzma/C/Util/7z/Precomp.c deleted file mode 100644 index 01605e3c..00000000 --- a/utils/lzma/C/Util/7z/Precomp.c +++ /dev/null @@ -1,4 +0,0 @@ -/* Precomp.c -- StdAfx -2013-01-21 : Igor Pavlov : Public domain */ - -#include "Precomp.h" diff --git a/utils/lzma/C/Util/7z/Precomp.h b/utils/lzma/C/Util/7z/Precomp.h deleted file mode 100644 index 588a66f7..00000000 --- a/utils/lzma/C/Util/7z/Precomp.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Precomp.h -- StdAfx -2013-06-16 : Igor Pavlov : Public domain */ - -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "../../Compiler.h" -#include "../../7zTypes.h" - -#endif diff --git a/utils/lzma/C/Util/7z/makefile b/utils/lzma/C/Util/7z/makefile deleted file mode 100644 index e0aa1e37..00000000 --- a/utils/lzma/C/Util/7z/makefile +++ /dev/null @@ -1,39 +0,0 @@ -# MY_STATIC_LINK=1 -CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT - -PROG = 7zDec.exe - -C_OBJS = \ - $O\7zAlloc.obj \ - $O\7zBuf.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ - $O\7zFile.obj \ - $O\7zDec.obj \ - $O\7zArcIn.obj \ - $O\7zStream.obj \ - $O\Bcj2.obj \ - $O\Bra.obj \ - $O\Bra86.obj \ - $O\CpuArch.obj \ - $O\Lzma2Dec.obj \ - $O\LzmaDec.obj \ - $O\Ppmd7.obj \ - $O\Ppmd7Dec.obj \ - -7Z_OBJS = \ - $O\7zMain.obj \ - -OBJS = \ - $O\Precomp.obj \ - $(7Z_OBJS) \ - $(C_OBJS) \ - -!include "../../../CPP/Build.mak" - -$(7Z_OBJS): $(*B).c - $(CCOMPL_USE) -$(C_OBJS): ../../$(*B).c - $(CCOMPL_USE) -$O\Precomp.obj: Precomp.c - $(CCOMPL_PCH) diff --git a/utils/lzma/C/Util/7z/makefile.gcc b/utils/lzma/C/Util/7z/makefile.gcc deleted file mode 100644 index 46018201..00000000 --- a/utils/lzma/C/Util/7z/makefile.gcc +++ /dev/null @@ -1,70 +0,0 @@ -PROG = 7zDec -CXX = g++ -LIB = -RM = rm -f -CFLAGS = -c -O2 -Wall - -OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o - -all: $(PROG) - -$(PROG): $(OBJS) - $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) - -7zMain.o: 7zMain.c - $(CXX) $(CFLAGS) 7zMain.c - -7zAlloc.o: ../../7zAlloc.c - $(CXX) $(CFLAGS) ../../7zAlloc.c - -7zArcIn.o: ../../7zArcIn.c - $(CXX) $(CFLAGS) ../../7zArcIn.c - -7zBuf.o: ../../7zBuf.c - $(CXX) $(CFLAGS) ../../7zBuf.c - -7zBuf2.o: ../../7zBuf2.c - $(CXX) $(CFLAGS) ../../7zBuf2.c - -7zCrc.o: ../../7zCrc.c - $(CXX) $(CFLAGS) ../../7zCrc.c - -7zCrcOpt.o: ../../7zCrc.c - $(CXX) $(CFLAGS) ../../7zCrcOpt.c - -7zDec.o: ../../7zDec.c - $(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c - -CpuArch.o: ../../CpuArch.c - $(CXX) $(CFLAGS) ../../CpuArch.c - -LzmaDec.o: ../../LzmaDec.c - $(CXX) $(CFLAGS) ../../LzmaDec.c - -Lzma2Dec.o: ../../Lzma2Dec.c - $(CXX) $(CFLAGS) ../../Lzma2Dec.c - -Bra.o: ../../Bra.c - $(CXX) $(CFLAGS) ../../Bra.c - -Bra86.o: ../../Bra86.c - $(CXX) $(CFLAGS) ../../Bra86.c - -Bcj2.o: ../../Bcj2.c - $(CXX) $(CFLAGS) ../../Bcj2.c - -Ppmd7.o: ../../Ppmd7.c - $(CXX) $(CFLAGS) ../../Ppmd7.c - -Ppmd7Dec.o: ../../Ppmd7Dec.c - $(CXX) $(CFLAGS) ../../Ppmd7Dec.c - -7zFile.o: ../../7zFile.c - $(CXX) $(CFLAGS) ../../7zFile.c - -7zStream.o: ../../7zStream.c - $(CXX) $(CFLAGS) ../../7zStream.c - -clean: - -$(RM) $(PROG) $(OBJS) - diff --git a/utils/lzma/C/Util/Lzma/LzmaUtil.c b/utils/lzma/C/Util/Lzma/LzmaUtil.c deleted file mode 100644 index 4606107e..00000000 --- a/utils/lzma/C/Util/Lzma/LzmaUtil.c +++ /dev/null @@ -1,254 +0,0 @@ -/* LzmaUtil.c -- Test application for LZMA compression -2014-12-31 : Igor Pavlov : Public domain */ - -#include "../../Precomp.h" - -#include -#include -#include - -#include "../../Alloc.h" -#include "../../7zFile.h" -#include "../../7zVersion.h" -#include "../../LzmaDec.h" -#include "../../LzmaEnc.h" - -const char *kCantReadMessage = "Can not read input file"; -const char *kCantWriteMessage = "Can not write output file"; -const char *kCantAllocateMessage = "Can not allocate memory"; -const char *kDataErrorMessage = "Data error"; - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -void PrintHelp(char *buffer) -{ - strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n" - "\nUsage: lzma inputFile outputFile\n" - " e: encode file\n" - " d: decode file\n"); -} - -int PrintError(char *buffer, const char *message) -{ - strcat(buffer, "\nError: "); - strcat(buffer, message); - strcat(buffer, "\n"); - return 1; -} - -int PrintErrorNumber(char *buffer, SRes val) -{ - sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val); - return 1; -} - -int PrintUserError(char *buffer) -{ - return PrintError(buffer, "Incorrect command"); -} - -#define IN_BUF_SIZE (1 << 16) -#define OUT_BUF_SIZE (1 << 16) - -static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, - UInt64 unpackSize) -{ - int thereIsSize = (unpackSize != (UInt64)(Int64)-1); - Byte inBuf[IN_BUF_SIZE]; - Byte outBuf[OUT_BUF_SIZE]; - size_t inPos = 0, inSize = 0, outPos = 0; - LzmaDec_Init(state); - for (;;) - { - if (inPos == inSize) - { - inSize = IN_BUF_SIZE; - RINOK(inStream->Read(inStream, inBuf, &inSize)); - inPos = 0; - } - { - SRes res; - SizeT inProcessed = inSize - inPos; - SizeT outProcessed = OUT_BUF_SIZE - outPos; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - ELzmaStatus status; - if (thereIsSize && outProcessed > unpackSize) - { - outProcessed = (SizeT)unpackSize; - finishMode = LZMA_FINISH_END; - } - - res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, - inBuf + inPos, &inProcessed, finishMode, &status); - inPos += inProcessed; - outPos += outProcessed; - unpackSize -= outProcessed; - - if (outStream) - if (outStream->Write(outStream, outBuf, outPos) != outPos) - return SZ_ERROR_WRITE; - - outPos = 0; - - if (res != SZ_OK || (thereIsSize && unpackSize == 0)) - return res; - - if (inProcessed == 0 && outProcessed == 0) - { - if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) - return SZ_ERROR_DATA; - return res; - } - } - } -} - -static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream) -{ - UInt64 unpackSize; - int i; - SRes res = 0; - - CLzmaDec state; - - /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ - unsigned char header[LZMA_PROPS_SIZE + 8]; - - /* Read and parse header */ - - RINOK(SeqInStream_Read(inStream, header, sizeof(header))); - - unpackSize = 0; - for (i = 0; i < 8; i++) - unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8); - - LzmaDec_Construct(&state); - RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)); - res = Decode2(&state, outStream, inStream, unpackSize); - LzmaDec_Free(&state, &g_Alloc); - return res; -} - -static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs) -{ - CLzmaEncHandle enc; - SRes res; - CLzmaEncProps props; - - rs = rs; - - enc = LzmaEnc_Create(&g_Alloc); - if (enc == 0) - return SZ_ERROR_MEM; - - LzmaEncProps_Init(&props); - res = LzmaEnc_SetProps(enc, &props); - - if (res == SZ_OK) - { - Byte header[LZMA_PROPS_SIZE + 8]; - size_t headerSize = LZMA_PROPS_SIZE; - int i; - - res = LzmaEnc_WriteProperties(enc, header, &headerSize); - for (i = 0; i < 8; i++) - header[headerSize++] = (Byte)(fileSize >> (8 * i)); - if (outStream->Write(outStream, header, headerSize) != headerSize) - res = SZ_ERROR_WRITE; - else - { - if (res == SZ_OK) - res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc); - } - } - LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); - return res; -} - -int main2(int numArgs, const char *args[], char *rs) -{ - CFileSeqInStream inStream; - CFileOutStream outStream; - char c; - int res; - int encodeMode; - Bool useOutFile = False; - - FileSeqInStream_CreateVTable(&inStream); - File_Construct(&inStream.file); - - FileOutStream_CreateVTable(&outStream); - File_Construct(&outStream.file); - - if (numArgs == 1) - { - PrintHelp(rs); - return 0; - } - - if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1) - return PrintUserError(rs); - - c = args[1][0]; - encodeMode = (c == 'e' || c == 'E'); - if (!encodeMode && c != 'd' && c != 'D') - return PrintUserError(rs); - - { - size_t t4 = sizeof(UInt32); - size_t t8 = sizeof(UInt64); - if (t4 != 4 || t8 != 8) - return PrintError(rs, "Incorrect UInt32 or UInt64"); - } - - if (InFile_Open(&inStream.file, args[2]) != 0) - return PrintError(rs, "Can not open input file"); - - if (numArgs > 3) - { - useOutFile = True; - if (OutFile_Open(&outStream.file, args[3]) != 0) - return PrintError(rs, "Can not open output file"); - } - else if (encodeMode) - PrintUserError(rs); - - if (encodeMode) - { - UInt64 fileSize; - File_GetLength(&inStream.file, &fileSize); - res = Encode(&outStream.s, &inStream.s, fileSize, rs); - } - else - { - res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL); - } - - if (useOutFile) - File_Close(&outStream.file); - File_Close(&inStream.file); - - if (res != SZ_OK) - { - if (res == SZ_ERROR_MEM) - return PrintError(rs, kCantAllocateMessage); - else if (res == SZ_ERROR_DATA) - return PrintError(rs, kDataErrorMessage); - else if (res == SZ_ERROR_WRITE) - return PrintError(rs, kCantWriteMessage); - else if (res == SZ_ERROR_READ) - return PrintError(rs, kCantReadMessage); - return PrintErrorNumber(rs, res); - } - return 0; -} - -int MY_CDECL main(int numArgs, const char *args[]) -{ - char rs[800] = { 0 }; - int res = main2(numArgs, args, rs); - fputs(rs, stdout); - return res; -} diff --git a/utils/lzma/C/Util/Lzma/LzmaUtil.dsp b/utils/lzma/C/Util/Lzma/LzmaUtil.dsp deleted file mode 100644 index 43b8e176..00000000 --- a/utils/lzma/C/Util/Lzma/LzmaUtil.dsp +++ /dev/null @@ -1,168 +0,0 @@ -# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=LzmaUtil - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "LzmaUtil.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "LzmaUtil - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W4 /WX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x419 /d "NDEBUG" -# ADD RSC /l 0x419 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7lzma.exe" - -!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x419 /d "_DEBUG" -# ADD RSC /l 0x419 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7lzma.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "LzmaUtil - Win32 Release" -# Name "LzmaUtil - Win32 Debug" -# Begin Source File - -SOURCE=..\..\7zFile.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zFile.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zStream.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zVersion.h -# End Source File -# Begin Source File - -SOURCE=..\..\Alloc.c -# End Source File -# Begin Source File - -SOURCE=..\..\Alloc.h -# End Source File -# Begin Source File - -SOURCE=..\..\CpuArch.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzFind.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzFind.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzFindMt.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzFindMt.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzHash.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaEnc.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaEnc.h -# End Source File -# Begin Source File - -SOURCE=.\LzmaUtil.c -# End Source File -# Begin Source File - -SOURCE=..\..\Threads.c -# End Source File -# Begin Source File - -SOURCE=..\..\Threads.h -# End Source File -# Begin Source File - -SOURCE=..\..\Types.h -# End Source File -# End Target -# End Project diff --git a/utils/lzma/C/Util/Lzma/LzmaUtil.dsw b/utils/lzma/C/Util/Lzma/LzmaUtil.dsw deleted file mode 100644 index c52eaf6d..00000000 --- a/utils/lzma/C/Util/Lzma/LzmaUtil.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "LzmaUtil"=.\LzmaUtil.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/utils/lzma/C/Util/Lzma/makefile b/utils/lzma/C/Util/Lzma/makefile deleted file mode 100644 index 47953227..00000000 --- a/utils/lzma/C/Util/Lzma/makefile +++ /dev/null @@ -1,28 +0,0 @@ -# MY_STATIC_LINK=1 -PROG = LZMAc.exe - -CFLAGS = $(CFLAGS) \ - -LIB_OBJS = \ - $O\LzmaUtil.obj \ - -C_OBJS = \ - $O\Alloc.obj \ - $O\LzFind.obj \ - $O\LzFindMt.obj \ - $O\LzmaDec.obj \ - $O\LzmaEnc.obj \ - $O\7zFile.obj \ - $O\7zStream.obj \ - $O\Threads.obj \ - -OBJS = \ - $(LIB_OBJS) \ - $(C_OBJS) \ - -!include "../../../CPP/Build.mak" - -$(LIB_OBJS): $(*B).c - $(COMPL_O2) -$(C_OBJS): ../../$(*B).c - $(COMPL_O2) diff --git a/utils/lzma/C/Util/Lzma/makefile.gcc b/utils/lzma/C/Util/Lzma/makefile.gcc deleted file mode 100644 index 67aa8b17..00000000 --- a/utils/lzma/C/Util/Lzma/makefile.gcc +++ /dev/null @@ -1,44 +0,0 @@ -PROG = lzma -CXX = g++ -LIB = -RM = rm -f -CFLAGS = -c -O2 -Wall -D_7ZIP_ST - -OBJS = \ - LzmaUtil.o \ - Alloc.o \ - LzFind.o \ - LzmaDec.o \ - LzmaEnc.o \ - 7zFile.o \ - 7zStream.o \ - - -all: $(PROG) - -$(PROG): $(OBJS) - $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2) - -LzmaUtil.o: LzmaUtil.c - $(CXX) $(CFLAGS) LzmaUtil.c - -Alloc.o: ../../Alloc.c - $(CXX) $(CFLAGS) ../../Alloc.c - -LzFind.o: ../../LzFind.c - $(CXX) $(CFLAGS) ../../LzFind.c - -LzmaDec.o: ../../LzmaDec.c - $(CXX) $(CFLAGS) ../../LzmaDec.c - -LzmaEnc.o: ../../LzmaEnc.c - $(CXX) $(CFLAGS) ../../LzmaEnc.c - -7zFile.o: ../../7zFile.c - $(CXX) $(CFLAGS) ../../7zFile.c - -7zStream.o: ../../7zStream.c - $(CXX) $(CFLAGS) ../../7zStream.c - -clean: - -$(RM) $(PROG) $(OBJS) diff --git a/utils/lzma/C/Util/LzmaLib/LzmaLib.def b/utils/lzma/C/Util/LzmaLib/LzmaLib.def deleted file mode 100644 index 8bc6add9..00000000 --- a/utils/lzma/C/Util/LzmaLib/LzmaLib.def +++ /dev/null @@ -1,4 +0,0 @@ -EXPORTS - LzmaCompress - LzmaUncompress - diff --git a/utils/lzma/C/Util/LzmaLib/LzmaLib.dsp b/utils/lzma/C/Util/LzmaLib/LzmaLib.dsp deleted file mode 100644 index 3421de83..00000000 --- a/utils/lzma/C/Util/LzmaLib/LzmaLib.dsp +++ /dev/null @@ -1,178 +0,0 @@ -# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=LzmaLib - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "LzmaLib.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "LzmaLib.mak" CFG="LzmaLib - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "LzmaLib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "NDEBUG" -# ADD RSC /l 0x419 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98 -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "LzmaLib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "_DEBUG" -# ADD RSC /l 0x419 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "LzmaLib - Win32 Release" -# Name "LzmaLib - Win32 Debug" -# Begin Group "Spec" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\LzmaLib.def -# End Source File -# Begin Source File - -SOURCE=.\LzmaLibExports.c -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\7zTypes.h -# End Source File -# Begin Source File - -SOURCE=..\..\Alloc.c -# End Source File -# Begin Source File - -SOURCE=..\..\Alloc.h -# End Source File -# Begin Source File - -SOURCE=..\..\IStream.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzFind.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzFind.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzFindMt.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzFindMt.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzHash.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaEnc.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaEnc.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaLib.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaLib.h -# End Source File -# Begin Source File - -SOURCE=.\resource.rc -# End Source File -# Begin Source File - -SOURCE=..\..\Threads.c -# End Source File -# Begin Source File - -SOURCE=..\..\Threads.h -# End Source File -# End Target -# End Project diff --git a/utils/lzma/C/Util/LzmaLib/LzmaLib.dsw b/utils/lzma/C/Util/LzmaLib/LzmaLib.dsw deleted file mode 100644 index 6faf3336..00000000 --- a/utils/lzma/C/Util/LzmaLib/LzmaLib.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "LzmaLib"=.\LzmaLib.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/utils/lzma/C/Util/LzmaLib/LzmaLibExports.c b/utils/lzma/C/Util/LzmaLib/LzmaLibExports.c deleted file mode 100644 index 845545db..00000000 --- a/utils/lzma/C/Util/LzmaLib/LzmaLibExports.c +++ /dev/null @@ -1,12 +0,0 @@ -/* LzmaLibExports.c -- LZMA library DLL Entry point -2008-10-04 : Igor Pavlov : Public domain */ - -#include - -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) -{ - hInstance = hInstance; - dwReason = dwReason; - lpReserved = lpReserved; - return TRUE; -} diff --git a/utils/lzma/C/Util/LzmaLib/makefile b/utils/lzma/C/Util/LzmaLib/makefile deleted file mode 100644 index 74103bb0..00000000 --- a/utils/lzma/C/Util/LzmaLib/makefile +++ /dev/null @@ -1,34 +0,0 @@ -MY_STATIC_LINK=1 -SLIB = sLZMA.lib -PROG = LZMA.dll -SLIBPATH = $O\$(SLIB) - -DEF_FILE = LzmaLib.def -CFLAGS = $(CFLAGS) \ - -LIB_OBJS = \ - $O\LzmaLibExports.obj \ - -C_OBJS = \ - $O\Alloc.obj \ - $O\LzFind.obj \ - $O\LzFindMt.obj \ - $O\LzmaDec.obj \ - $O\LzmaEnc.obj \ - $O\LzmaLib.obj \ - $O\Threads.obj \ - -OBJS = \ - $(LIB_OBJS) \ - $(C_OBJS) \ - $O\resource.res - -!include "../../../CPP/Build.mak" - -$(SLIBPATH): $O $(OBJS) - lib -out:$(SLIBPATH) $(OBJS) $(LIBS) - -$(LIB_OBJS): $(*B).c - $(COMPL_O2) -$(C_OBJS): ../../$(*B).c - $(COMPL_O2) diff --git a/utils/lzma/C/Util/LzmaLib/resource.rc b/utils/lzma/C/Util/LzmaLib/resource.rc deleted file mode 100644 index 674832e0..00000000 --- a/utils/lzma/C/Util/LzmaLib/resource.rc +++ /dev/null @@ -1,3 +0,0 @@ -#include "../../7zVersion.rc" - -MY_VERSION_INFO_DLL("LZMA library", "LZMA") diff --git a/utils/lzma/C/Util/SfxSetup/Precomp.c b/utils/lzma/C/Util/SfxSetup/Precomp.c deleted file mode 100644 index 01605e3c..00000000 --- a/utils/lzma/C/Util/SfxSetup/Precomp.c +++ /dev/null @@ -1,4 +0,0 @@ -/* Precomp.c -- StdAfx -2013-01-21 : Igor Pavlov : Public domain */ - -#include "Precomp.h" diff --git a/utils/lzma/C/Util/SfxSetup/Precomp.h b/utils/lzma/C/Util/SfxSetup/Precomp.h deleted file mode 100644 index 588a66f7..00000000 --- a/utils/lzma/C/Util/SfxSetup/Precomp.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Precomp.h -- StdAfx -2013-06-16 : Igor Pavlov : Public domain */ - -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "../../Compiler.h" -#include "../../7zTypes.h" - -#endif diff --git a/utils/lzma/C/Util/SfxSetup/SfxSetup.c b/utils/lzma/C/Util/SfxSetup/SfxSetup.c deleted file mode 100644 index 570bd70f..00000000 --- a/utils/lzma/C/Util/SfxSetup/SfxSetup.c +++ /dev/null @@ -1,617 +0,0 @@ -/* SfxSetup.c - 7z SFX Setup -2014-12-07 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#ifndef UNICODE -#define UNICODE -#endif - -#ifndef _UNICODE -#define _UNICODE -#endif - -#ifdef _CONSOLE -#include -#endif - -#include "../../7z.h" -#include "../../7zAlloc.h" -#include "../../7zCrc.h" -#include "../../7zFile.h" -#include "../../CpuArch.h" - -#define k_EXE_ExtIndex 2 - -static const char *kExts[] = -{ - "bat" - , "cmd" - , "exe" - , "inf" - , "msi" - #ifdef UNDER_CE - , "cab" - #endif - , "html" - , "htm" -}; - -static const char *kNames[] = -{ - "setup" - , "install" - , "run" - , "start" -}; - -static unsigned FindExt(const wchar_t *s, unsigned *extLen) -{ - unsigned len = (unsigned)wcslen(s); - unsigned i; - for (i = len; i > 0; i--) - { - if (s[i - 1] == '.') - { - *extLen = len - i; - return i - 1; - } - } - *extLen = 0; - return len; -} - -#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c))) - -static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len) -{ - unsigned i; - for (i = 0; i < num; i++) - { - const char *item = items[i]; - unsigned itemLen = (unsigned)strlen(item); - unsigned j; - if (len != itemLen) - continue; - for (j = 0; j < len; j++) - { - unsigned c = item[j]; - if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j]) - break; - } - if (j == len) - return i; - } - return i; -} - -#ifdef _CONSOLE -static BOOL WINAPI HandlerRoutine(DWORD ctrlType) -{ - ctrlType = ctrlType; - return TRUE; -} -#endif - -static void PrintErrorMessage(const char *message) -{ - #ifdef _CONSOLE - printf("\n7-Zip Error: %s\n", message); - #else - #ifdef UNDER_CE - WCHAR messageW[256 + 4]; - unsigned i; - for (i = 0; i < 256 && message[i] != 0; i++) - messageW[i] = message[i]; - messageW[i] = 0; - MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR); - #else - MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR); - #endif - #endif -} - -static WRes MyCreateDir(const WCHAR *name) -{ - return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); -} - -#ifdef UNDER_CE -#define kBufferSize (1 << 13) -#else -#define kBufferSize (1 << 15) -#endif - -#define kSignatureSearchLimit (1 << 22) - -static Bool FindSignature(CSzFile *stream, UInt64 *resPos) -{ - Byte buf[kBufferSize]; - size_t numPrevBytes = 0; - *resPos = 0; - for (;;) - { - size_t processed, pos; - if (*resPos > kSignatureSearchLimit) - return False; - processed = kBufferSize - numPrevBytes; - if (File_Read(stream, buf + numPrevBytes, &processed) != 0) - return False; - processed += numPrevBytes; - if (processed < k7zStartHeaderSize || - (processed == k7zStartHeaderSize && numPrevBytes != 0)) - return False; - processed -= k7zStartHeaderSize; - for (pos = 0; pos <= processed; pos++) - { - for (; buf[pos] != '7' && pos <= processed; pos++); - if (pos > processed) - break; - if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) - if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8)) - { - *resPos += pos; - return True; - } - } - *resPos += processed; - numPrevBytes = k7zStartHeaderSize; - memmove(buf, buf + processed, k7zStartHeaderSize); - } -} - -static Bool DoesFileOrDirExist(const WCHAR *path) -{ - WIN32_FIND_DATAW fd; - HANDLE handle; - handle = FindFirstFileW(path, &fd); - if (handle == INVALID_HANDLE_VALUE) - return False; - FindClose(handle); - return True; -} - -static WRes RemoveDirWithSubItems(WCHAR *path) -{ - WIN32_FIND_DATAW fd; - HANDLE handle; - WRes res = 0; - size_t len = wcslen(path); - wcscpy(path + len, L"*"); - handle = FindFirstFileW(path, &fd); - path[len] = L'\0'; - if (handle == INVALID_HANDLE_VALUE) - return GetLastError(); - for (;;) - { - if (wcscmp(fd.cFileName, L".") != 0 && - wcscmp(fd.cFileName, L"..") != 0) - { - wcscpy(path + len, fd.cFileName); - if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - { - wcscat(path, WSTRING_PATH_SEPARATOR); - res = RemoveDirWithSubItems(path); - } - else - { - SetFileAttributesW(path, 0); - if (DeleteFileW(path) == 0) - res = GetLastError(); - } - if (res != 0) - break; - } - if (!FindNextFileW(handle, &fd)) - { - res = GetLastError(); - if (res == ERROR_NO_MORE_FILES) - res = 0; - break; - } - } - path[len] = L'\0'; - FindClose(handle); - if (res == 0) - { - if (!RemoveDirectoryW(path)) - res = GetLastError(); - } - return res; -} - -#ifdef _CONSOLE -int MY_CDECL main() -#else -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - #ifdef UNDER_CE - LPWSTR - #else - LPSTR - #endif - lpCmdLine, int nCmdShow) -#endif -{ - CFileInStream archiveStream; - CLookToRead lookStream; - CSzArEx db; - SRes res = SZ_OK; - ISzAlloc allocImp; - ISzAlloc allocTempImp; - WCHAR sfxPath[MAX_PATH + 2]; - WCHAR path[MAX_PATH * 3 + 2]; - #ifndef UNDER_CE - WCHAR workCurDir[MAX_PATH + 32]; - #endif - size_t pathLen; - DWORD winRes; - const wchar_t *cmdLineParams; - const char *errorMessage = NULL; - Bool useShellExecute = True; - - #ifdef _CONSOLE - SetConsoleCtrlHandler(HandlerRoutine, TRUE); - #else - hInstance = hInstance; - hPrevInstance = hPrevInstance; - lpCmdLine = lpCmdLine; - nCmdShow = nCmdShow; - #endif - - CrcGenerateTable(); - - allocImp.Alloc = SzAlloc; - allocImp.Free = SzFree; - - allocTempImp.Alloc = SzAllocTemp; - allocTempImp.Free = SzFreeTemp; - - FileInStream_CreateVTable(&archiveStream); - LookToRead_CreateVTable(&lookStream, False); - - winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); - if (winRes == 0 || winRes > MAX_PATH) - return 1; - { - cmdLineParams = GetCommandLineW(); - #ifndef UNDER_CE - { - Bool quoteMode = False; - for (;; cmdLineParams++) - { - wchar_t c = *cmdLineParams; - if (c == L'\"') - quoteMode = !quoteMode; - else if (c == 0 || (c == L' ' && !quoteMode)) - break; - } - } - #endif - } - - { - unsigned i; - DWORD d; - winRes = GetTempPathW(MAX_PATH, path); - if (winRes == 0 || winRes > MAX_PATH) - return 1; - pathLen = wcslen(path); - d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); - - for (i = 0;; i++, d += GetTickCount()) - { - if (i >= 100) - { - res = SZ_ERROR_FAIL; - break; - } - wcscpy(path + pathLen, L"7z"); - - { - wchar_t *s = path + wcslen(path); - UInt32 value = d; - unsigned k; - for (k = 0; k < 8; k++) - { - unsigned t = value & 0xF; - value >>= 4; - s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } - s[k] = '\0'; - } - - if (DoesFileOrDirExist(path)) - continue; - if (CreateDirectoryW(path, NULL)) - { - wcscat(path, WSTRING_PATH_SEPARATOR); - pathLen = wcslen(path); - break; - } - if (GetLastError() != ERROR_ALREADY_EXISTS) - { - res = SZ_ERROR_FAIL; - break; - } - } - - #ifndef UNDER_CE - wcscpy(workCurDir, path); - #endif - if (res != SZ_OK) - errorMessage = "Can't create temp folder"; - } - - if (res != SZ_OK) - { - if (!errorMessage) - errorMessage = "Error"; - PrintErrorMessage(errorMessage); - return 1; - } - - if (InFile_OpenW(&archiveStream.file, sfxPath) != 0) - { - errorMessage = "can not open input file"; - res = SZ_ERROR_FAIL; - } - else - { - UInt64 pos = 0; - if (!FindSignature(&archiveStream.file, &pos)) - res = SZ_ERROR_FAIL; - else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0) - res = SZ_ERROR_FAIL; - if (res != 0) - errorMessage = "Can't find 7z archive"; - } - - if (res == SZ_OK) - { - lookStream.realStream = &archiveStream.s; - LookToRead_Init(&lookStream); - } - - SzArEx_Init(&db); - if (res == SZ_OK) - { - res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); - } - - if (res == SZ_OK) - { - UInt32 executeFileIndex = (UInt32)(Int32)-1; - UInt32 minPrice = 1 << 30; - UInt32 i; - UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ - Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ - size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ - - for (i = 0; i < db.NumFiles; i++) - { - size_t offset = 0; - size_t outSizeProcessed = 0; - size_t len; - WCHAR *temp; - len = SzArEx_GetFileNameUtf16(&db, i, NULL); - - if (len >= MAX_PATH) - { - res = SZ_ERROR_FAIL; - break; - } - - temp = path + pathLen; - - SzArEx_GetFileNameUtf16(&db, i, temp); - { - res = SzArEx_Extract(&db, &lookStream.s, i, - &blockIndex, &outBuffer, &outBufferSize, - &offset, &outSizeProcessed, - &allocImp, &allocTempImp); - if (res != SZ_OK) - break; - } - { - CSzFile outFile; - size_t processedSize; - size_t j; - size_t nameStartPos = 0; - for (j = 0; temp[j] != 0; j++) - { - if (temp[j] == '/') - { - temp[j] = 0; - MyCreateDir(path); - temp[j] = CHAR_PATH_SEPARATOR; - nameStartPos = j + 1; - } - } - - if (SzArEx_IsDir(&db, i)) - { - MyCreateDir(path); - continue; - } - else - { - unsigned extLen; - const WCHAR *name = temp + nameStartPos; - unsigned len = (unsigned)wcslen(name); - unsigned nameLen = FindExt(temp + nameStartPos, &extLen); - unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen); - unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen); - - unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12)); - if (minPrice > price) - { - minPrice = price; - executeFileIndex = i; - useShellExecute = (extPrice != k_EXE_ExtIndex); - } - - if (DoesFileOrDirExist(path)) - { - errorMessage = "Duplicate file"; - res = SZ_ERROR_FAIL; - break; - } - if (OutFile_OpenW(&outFile, path)) - { - errorMessage = "Can't open output file"; - res = SZ_ERROR_FAIL; - break; - } - } - - processedSize = outSizeProcessed; - if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) - { - errorMessage = "Can't write output file"; - res = SZ_ERROR_FAIL; - } - - #ifdef USE_WINDOWS_FILE - if (SzBitWithVals_Check(&db.MTime, i)) - { - const CNtfsFileTime *t = db.MTime.Vals + i; - FILETIME mTime; - mTime.dwLowDateTime = t->Low; - mTime.dwHighDateTime = t->High; - SetFileTime(outFile.handle, NULL, NULL, &mTime); - } - #endif - - { - SRes res2 = File_Close(&outFile); - if (res != SZ_OK) - break; - if (res2 != SZ_OK) - { - res = res2; - break; - } - } - #ifdef USE_WINDOWS_FILE - if (SzBitWithVals_Check(&db.Attribs, i)) - SetFileAttributesW(path, db.Attribs.Vals[i]); - #endif - } - } - - if (res == SZ_OK) - { - if (executeFileIndex == (UInt32)(Int32)-1) - { - errorMessage = "There is no file to execute"; - res = SZ_ERROR_FAIL; - } - else - { - WCHAR *temp = path + pathLen; - UInt32 j; - SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp); - for (j = 0; temp[j] != 0; j++) - if (temp[j] == '/') - temp[j] = CHAR_PATH_SEPARATOR; - } - } - IAlloc_Free(&allocImp, outBuffer); - } - SzArEx_Free(&db, &allocImp); - - File_Close(&archiveStream.file); - - if (res == SZ_OK) - { - HANDLE hProcess = 0; - - #ifndef UNDER_CE - WCHAR oldCurDir[MAX_PATH + 2]; - oldCurDir[0] = 0; - { - DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir); - if (needLen == 0 || needLen > MAX_PATH) - oldCurDir[0] = 0; - SetCurrentDirectory(workCurDir); - } - #endif - - if (useShellExecute) - { - SHELLEXECUTEINFO ei; - UINT32 executeRes; - BOOL success; - - memset(&ei, 0, sizeof(ei)); - ei.cbSize = sizeof(ei); - ei.lpFile = path; - ei.fMask = SEE_MASK_NOCLOSEPROCESS - #ifndef UNDER_CE - | SEE_MASK_FLAG_DDEWAIT - #endif - /* | SEE_MASK_NO_CONSOLE */ - ; - if (wcslen(cmdLineParams) != 0) - ei.lpParameters = cmdLineParams; - ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */ - success = ShellExecuteEx(&ei); - executeRes = (UINT32)(UINT_PTR)ei.hInstApp; - if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */ - res = SZ_ERROR_FAIL; - else - hProcess = ei.hProcess; - } - else - { - STARTUPINFOW si; - PROCESS_INFORMATION pi; - WCHAR cmdLine[MAX_PATH * 3]; - - wcscpy(cmdLine, path); - wcscat(cmdLine, cmdLineParams); - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) - res = SZ_ERROR_FAIL; - else - { - CloseHandle(pi.hThread); - hProcess = pi.hProcess; - } - } - - if (hProcess != 0) - { - WaitForSingleObject(hProcess, INFINITE); - CloseHandle(hProcess); - } - - #ifndef UNDER_CE - SetCurrentDirectory(oldCurDir); - #endif - } - - path[pathLen] = L'\0'; - RemoveDirWithSubItems(path); - - if (res == SZ_OK) - return 0; - - { - if (res == SZ_ERROR_UNSUPPORTED) - errorMessage = "Decoder doesn't support this archive"; - else if (res == SZ_ERROR_MEM) - errorMessage = "Can't allocate required memory"; - else if (res == SZ_ERROR_CRC) - errorMessage = "CRC error"; - else - { - if (!errorMessage) - errorMessage = "ERROR"; - } - if (errorMessage) - PrintErrorMessage(errorMessage); - } - return 1; -} diff --git a/utils/lzma/C/Util/SfxSetup/SfxSetup.dsp b/utils/lzma/C/Util/SfxSetup/SfxSetup.dsp deleted file mode 100644 index 5ce7195b..00000000 --- a/utils/lzma/C/Util/SfxSetup/SfxSetup.dsp +++ /dev/null @@ -1,211 +0,0 @@ -# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=SfxSetup - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "SfxSetup.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "SfxSetup.mak" CFG="SfxSetup - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "SfxSetup - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "NDEBUG" -# ADD RSC /l 0x419 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 - -!ELSEIF "$(CFG)" == "SfxSetup - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "_DEBUG" -# ADD RSC /l 0x419 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "SfxSetup - Win32 Release" -# Name "SfxSetup - Win32 Debug" -# Begin Group "Common" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\7z.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zAlloc.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zAlloc.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zArcIn.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zBuf.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zBuf.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrc.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrc.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zCrcOpt.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zDec.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zFile.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zFile.h -# End Source File -# Begin Source File - -SOURCE=..\..\7zStream.c -# End Source File -# Begin Source File - -SOURCE=..\..\7zTypes.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bcj2.c -# End Source File -# Begin Source File - -SOURCE=..\..\Bcj2.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bra.c -# End Source File -# Begin Source File - -SOURCE=..\..\Bra.h -# End Source File -# Begin Source File - -SOURCE=..\..\Bra86.c -# End Source File -# Begin Source File - -SOURCE=..\..\CpuArch.c -# End Source File -# Begin Source File - -SOURCE=..\..\CpuArch.h -# End Source File -# Begin Source File - -SOURCE=..\..\Lzma2Dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\Lzma2Dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.c -# End Source File -# Begin Source File - -SOURCE=..\..\LzmaDec.h -# End Source File -# End Group -# Begin Group "Spec" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\Precomp.c -# ADD CPP /Yc"Precomp.h" -# End Source File -# Begin Source File - -SOURCE=.\Precomp.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\SfxSetup.c -# End Source File -# End Target -# End Project diff --git a/utils/lzma/C/Util/SfxSetup/SfxSetup.dsw b/utils/lzma/C/Util/SfxSetup/SfxSetup.dsw deleted file mode 100644 index ea231112..00000000 --- a/utils/lzma/C/Util/SfxSetup/SfxSetup.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "SfxSetup"=.\SfxSetup.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/utils/lzma/C/Util/SfxSetup/makefile b/utils/lzma/C/Util/SfxSetup/makefile deleted file mode 100644 index 5b519807..00000000 --- a/utils/lzma/C/Util/SfxSetup/makefile +++ /dev/null @@ -1,33 +0,0 @@ -PROG = 7zS2.sfx - -C_OBJS = \ - $O\7zAlloc.obj \ - $O\7zArcIn.obj \ - $O\7zBuf.obj \ - $O\7zBuf2.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ - $O\7zFile.obj \ - $O\7zDec.obj \ - $O\7zStream.obj \ - $O\Bcj2.obj \ - $O\Bra.obj \ - $O\Bra86.obj \ - $O\CpuArch.obj \ - $O\Lzma2Dec.obj \ - $O\LzmaDec.obj \ - -7Z_OBJS = \ - $O\SfxSetup.obj \ - -OBJS = \ - $(7Z_OBJS) \ - $(C_OBJS) \ - $O\resource.res - -!include "../../../CPP/Build.mak" - -$(7Z_OBJS): $(*B).c - $(COMPL_O1) -$(C_OBJS): ../../$(*B).c - $(COMPL_O1) diff --git a/utils/lzma/C/Util/SfxSetup/makefile_con b/utils/lzma/C/Util/SfxSetup/makefile_con deleted file mode 100644 index 492191f5..00000000 --- a/utils/lzma/C/Util/SfxSetup/makefile_con +++ /dev/null @@ -1,34 +0,0 @@ -PROG = 7zS2con.sfx -CFLAGS = $(CFLAGS) -D_CONSOLE - -C_OBJS = \ - $O\7zAlloc.obj \ - $O\7zArcIn.obj \ - $O\7zBuf.obj \ - $O\7zBuf2.obj \ - $O\7zCrc.obj \ - $O\7zCrcOpt.obj \ - $O\7zFile.obj \ - $O\7zDec.obj \ - $O\7zStream.obj \ - $O\Bcj2.obj \ - $O\Bra.obj \ - $O\Bra86.obj \ - $O\CpuArch.obj \ - $O\Lzma2Dec.obj \ - $O\LzmaDec.obj \ - -7Z_OBJS = \ - $O\SfxSetup.obj \ - -OBJS = \ - $(7Z_OBJS) \ - $(C_OBJS) \ - $O\resource.res - -!include "../../../CPP/Build.mak" - -$(7Z_OBJS): $(*B).c - $(COMPL_O1) -$(C_OBJS): ../../$(*B).c - $(COMPL_O1) diff --git a/utils/lzma/C/Util/SfxSetup/resource.rc b/utils/lzma/C/Util/SfxSetup/resource.rc deleted file mode 100644 index 0c1637f2..00000000 --- a/utils/lzma/C/Util/SfxSetup/resource.rc +++ /dev/null @@ -1,5 +0,0 @@ -#include "../../7zVersion.rc" - -MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx") - -1 ICON "setup.ico" diff --git a/utils/lzma/C/Util/SfxSetup/setup.ico b/utils/lzma/C/Util/SfxSetup/setup.ico deleted file mode 100644 index dbb6ca8b..00000000 Binary files a/utils/lzma/C/Util/SfxSetup/setup.ico and /dev/null differ diff --git a/utils/lzma/C/Windows/Defs.h b/utils/lzma/C/Windows/Defs.h new file mode 100644 index 00000000..c0038d61 --- /dev/null +++ b/utils/lzma/C/Windows/Defs.h @@ -0,0 +1,18 @@ +// Windows/Defs.h + +#ifndef __WINDOWS_DEFS_H +#define __WINDOWS_DEFS_H + +inline bool BOOLToBool(BOOL value) + { return (value != FALSE); } + +inline BOOL BoolToBOOL(bool value) + { return (value ? TRUE: FALSE); } + +inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value) + { return (value ? VARIANT_TRUE: VARIANT_FALSE); } + +inline bool VARIANT_BOOLToBool(VARIANT_BOOL value) + { return (value != VARIANT_FALSE); } + +#endif diff --git a/utils/lzma/C/Windows/FileIO.cpp b/utils/lzma/C/Windows/FileIO.cpp new file mode 100644 index 00000000..203de843 --- /dev/null +++ b/utils/lzma/C/Windows/FileIO.cpp @@ -0,0 +1,245 @@ +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#include "FileIO.h" +#include "Defs.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { +namespace NIO { + +CFileBase::~CFileBase() { Close(); } + +bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + Close(); + _handle = ::CreateFile(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE) NULL); + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); +} + +#ifndef _UNICODE +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (g_IsNT) + { + Close(); + _handle = ::CreateFileW(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE) NULL); + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); + } + return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), + desiredAccess, shareMode, creationDisposition, flagsAndAttributes); +} +#endif + +bool CFileBase::Close() +{ + if(!_fileIsOpen) + return true; + bool result = BOOLToBool(::CloseHandle(_handle)); + _fileIsOpen = !result; + return result; +} + +bool CFileBase::GetPosition(UInt64 &position) const +{ + return Seek(0, FILE_CURRENT, position); +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + DWORD sizeHigh; + DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh); + if(sizeLow == 0xFFFFFFFF) + if(::GetLastError() != NO_ERROR) + return false; + length = (((UInt64)sizeHigh) << 32) + sizeLow; + return true; +} + +bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const +{ + LARGE_INTEGER value; + value.QuadPart = distanceToMove; + value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + if(::GetLastError() != NO_ERROR) + return false; + newPosition = value.QuadPart; + return true; +} + +bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) +{ + return Seek(position, FILE_BEGIN, newPosition); +} + +bool CFileBase::SeekToBegin() +{ + UInt64 newPosition; + return Seek(0, newPosition); +} + +bool CFileBase::SeekToEnd(UInt64 &newPosition) +{ + return Seek(0, FILE_END, newPosition); +} + +bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const +{ + BY_HANDLE_FILE_INFORMATION winFileInfo; + if(!::GetFileInformationByHandle(_handle, &winFileInfo)) + return false; + fileInfo.Attributes = winFileInfo.dwFileAttributes; + fileInfo.CreationTime = winFileInfo.ftCreationTime; + fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime; + fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime; + fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes; + fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow; + fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks; + fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow; + return true; +} + +///////////////////////// +// CInFile + +bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } + +bool CInFile::Open(LPCTSTR fileName) + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } + +#ifndef _UNICODE +bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } + +bool CInFile::Open(LPCWSTR fileName) + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } +#endif + +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +static UInt32 kChunkSizeMax = (1 << 24); + +bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = ReadPart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +///////////////////////// +// COutFile + +bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +static inline DWORD GetCreationDisposition(bool createAlways) + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } + +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCTSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#ifndef _UNICODE + +bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCWSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#endif + +bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime) + { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); } + +bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime) + { return SetTime(NULL, NULL, lastWriteTime); } + +bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = WritePart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (const void *)((const unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); } + +bool COutFile::SetLength(UInt64 length) +{ + UInt64 newPosition; + if(!Seek(length, newPosition)) + return false; + if(newPosition != length) + return false; + return SetEndOfFile(); +} + +}}} diff --git a/utils/lzma/C/Windows/FileIO.h b/utils/lzma/C/Windows/FileIO.h new file mode 100644 index 00000000..18014844 --- /dev/null +++ b/utils/lzma/C/Windows/FileIO.h @@ -0,0 +1,98 @@ +// Windows/FileIO.h + +#ifndef __WINDOWS_FILEIO_H +#define __WINDOWS_FILEIO_H + +#include "../Common/Types.h" + +namespace NWindows { +namespace NFile { +namespace NIO { + +struct CByHandleFileInfo +{ + DWORD Attributes; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + DWORD VolumeSerialNumber; + UInt64 Size; + DWORD NumberOfLinks; + UInt64 FileIndex; +}; + +class CFileBase +{ +protected: + bool _fileIsOpen; + HANDLE _handle; + bool Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + #ifndef _UNICODE + bool Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + #endif + +public: + CFileBase(): _fileIsOpen(false){}; + virtual ~CFileBase(); + + virtual bool Close(); + + bool GetPosition(UInt64 &position) const; + bool GetLength(UInt64 &length) const; + + bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const; + bool Seek(UInt64 position, UInt64 &newPosition); + bool SeekToBegin(); + bool SeekToEnd(UInt64 &newPosition); + + bool GetFileInformation(CByHandleFileInfo &fileInfo) const; +}; + +class CInFile: public CFileBase +{ +public: + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCTSTR fileName); + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCWSTR fileName); + #endif + bool ReadPart(void *data, UInt32 size, UInt32 &processedSize); + bool Read(void *data, UInt32 size, UInt32 &processedSize); +}; + +class COutFile: public CFileBase +{ + // DWORD m_CreationDisposition; +public: + // COutFile(): m_CreationDisposition(CREATE_NEW){}; + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCTSTR fileName, DWORD creationDisposition); + bool Create(LPCTSTR fileName, bool createAlways); + + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCWSTR fileName, DWORD creationDisposition); + bool Create(LPCWSTR fileName, bool createAlways); + #endif + + /* + void SetOpenCreationDisposition(DWORD creationDisposition) + { m_CreationDisposition = creationDisposition; } + void SetOpenCreationDispositionCreateAlways() + { m_CreationDisposition = CREATE_ALWAYS; } + */ + + bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); + bool SetLastWriteTime(const FILETIME *lastWriteTime); + bool WritePart(const void *data, UInt32 size, UInt32 &processedSize); + bool Write(const void *data, UInt32 size, UInt32 &processedSize); + bool SetEndOfFile(); + bool SetLength(UInt64 length); +}; + +}}} + +#endif diff --git a/utils/lzma/C/Windows/StdAfx.h b/utils/lzma/C/Windows/StdAfx.h new file mode 100644 index 00000000..e7924c8f --- /dev/null +++ b/utils/lzma/C/Windows/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../Common/MyWindows.h" +#include "../Common/NewHandler.h" + +#endif diff --git a/utils/lzma/C/Xz.c b/utils/lzma/C/Xz.c deleted file mode 100644 index fbc732a8..00000000 --- a/utils/lzma/C/Xz.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Xz.c - Xz -2009-04-15 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zCrc.h" -#include "CpuArch.h" -#include "Xz.h" -#include "XzCrc64.h" - -Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 }; -Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; - -unsigned Xz_WriteVarInt(Byte *buf, UInt64 v) -{ - unsigned i = 0; - do - { - buf[i++] = (Byte)((v & 0x7F) | 0x80); - v >>= 7; - } - while (v != 0); - buf[i - 1] &= 0x7F; - return i; -} - -void Xz_Construct(CXzStream *p) -{ - p->numBlocks = p->numBlocksAllocated = 0; - p->blocks = 0; - p->flags = 0; -} - -void Xz_Free(CXzStream *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->blocks); - p->numBlocks = p->numBlocksAllocated = 0; - p->blocks = 0; -} - -unsigned XzFlags_GetCheckSize(CXzStreamFlags f) -{ - int t = XzFlags_GetCheckType(f); - return (t == 0) ? 0 : (4 << ((t - 1) / 3)); -} - -void XzCheck_Init(CXzCheck *p, int mode) -{ - p->mode = mode; - switch (mode) - { - case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; - case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; - case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; - } -} - -void XzCheck_Update(CXzCheck *p, const void *data, size_t size) -{ - switch (p->mode) - { - case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; - case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; - case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; - } -} - -int XzCheck_Final(CXzCheck *p, Byte *digest) -{ - switch (p->mode) - { - case XZ_CHECK_CRC32: - SetUi32(digest, CRC_GET_DIGEST(p->crc)); - break; - case XZ_CHECK_CRC64: - { - int i; - UInt64 v = CRC64_GET_DIGEST(p->crc64); - for (i = 0; i < 8; i++, v >>= 8) - digest[i] = (Byte)(v & 0xFF); - break; - } - case XZ_CHECK_SHA256: - Sha256_Final(&p->sha, digest); - break; - default: - return 0; - } - return 1; -} diff --git a/utils/lzma/C/Xz.h b/utils/lzma/C/Xz.h deleted file mode 100644 index 7e6fc564..00000000 --- a/utils/lzma/C/Xz.h +++ /dev/null @@ -1,275 +0,0 @@ -/* Xz.h - Xz interface -2014-12-30 : Igor Pavlov : Public domain */ - -#ifndef __XZ_H -#define __XZ_H - -#include "Sha256.h" - -EXTERN_C_BEGIN - -#define XZ_ID_Subblock 1 -#define XZ_ID_Delta 3 -#define XZ_ID_X86 4 -#define XZ_ID_PPC 5 -#define XZ_ID_IA64 6 -#define XZ_ID_ARM 7 -#define XZ_ID_ARMT 8 -#define XZ_ID_SPARC 9 -#define XZ_ID_LZMA2 0x21 - -unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); -unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); - -/* ---------- xz block ---------- */ - -#define XZ_BLOCK_HEADER_SIZE_MAX 1024 - -#define XZ_NUM_FILTERS_MAX 4 -#define XZ_BF_NUM_FILTERS_MASK 3 -#define XZ_BF_PACK_SIZE (1 << 6) -#define XZ_BF_UNPACK_SIZE (1 << 7) - -#define XZ_FILTER_PROPS_SIZE_MAX 20 - -typedef struct -{ - UInt64 id; - UInt32 propsSize; - Byte props[XZ_FILTER_PROPS_SIZE_MAX]; -} CXzFilter; - -typedef struct -{ - UInt64 packSize; - UInt64 unpackSize; - Byte flags; - CXzFilter filters[XZ_NUM_FILTERS_MAX]; -} CXzBlock; - -#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) -#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) -#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) - -SRes XzBlock_Parse(CXzBlock *p, const Byte *header); -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes); - -/* ---------- xz stream ---------- */ - -#define XZ_SIG_SIZE 6 -#define XZ_FOOTER_SIG_SIZE 2 - -extern Byte XZ_SIG[XZ_SIG_SIZE]; -extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; - -#define XZ_STREAM_FLAGS_SIZE 2 -#define XZ_STREAM_CRC_SIZE 4 - -#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) -#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) - -#define XZ_CHECK_MASK 0xF -#define XZ_CHECK_NO 0 -#define XZ_CHECK_CRC32 1 -#define XZ_CHECK_CRC64 4 -#define XZ_CHECK_SHA256 10 - -typedef struct -{ - int mode; - UInt32 crc; - UInt64 crc64; - CSha256 sha; -} CXzCheck; - -void XzCheck_Init(CXzCheck *p, int mode); -void XzCheck_Update(CXzCheck *p, const void *data, size_t size); -int XzCheck_Final(CXzCheck *p, Byte *digest); - -typedef UInt16 CXzStreamFlags; - -#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) -#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) -#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) -unsigned XzFlags_GetCheckSize(CXzStreamFlags f); - -SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); - -typedef struct -{ - UInt64 unpackSize; - UInt64 totalSize; -} CXzBlockSizes; - -typedef struct -{ - CXzStreamFlags flags; - size_t numBlocks; - size_t numBlocksAllocated; - CXzBlockSizes *blocks; - UInt64 startOffset; -} CXzStream; - -void Xz_Construct(CXzStream *p); -void Xz_Free(CXzStream *p, ISzAlloc *alloc); - -#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) - -UInt64 Xz_GetUnpackSize(const CXzStream *p); -UInt64 Xz_GetPackSize(const CXzStream *p); - -typedef struct -{ - size_t num; - size_t numAllocated; - CXzStream *streams; -} CXzs; - -void Xzs_Construct(CXzs *p); -void Xzs_Free(CXzs *p, ISzAlloc *alloc); -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc); - -UInt64 Xzs_GetNumBlocks(const CXzs *p); -UInt64 Xzs_GetUnpackSize(const CXzs *p); - -typedef enum -{ - CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ - CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - CODER_STATUS_NOT_FINISHED, /* stream was not finished */ - CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ -} ECoderStatus; - -typedef enum -{ - CODER_FINISH_ANY, /* finish at any point */ - CODER_FINISH_END /* block must be finished at the end */ -} ECoderFinishMode; - -typedef struct _IStateCoder -{ - void *p; - void (*Free)(void *p, ISzAlloc *alloc); - SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc); - void (*Init)(void *p); - SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished); -} IStateCoder; - -#define MIXCODER_NUM_FILTERS_MAX 4 - -typedef struct -{ - ISzAlloc *alloc; - Byte *buf; - int numCoders; - int finished[MIXCODER_NUM_FILTERS_MAX - 1]; - size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; - size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; - UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; - IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; -} CMixCoder; - -void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc); -void MixCoder_Free(CMixCoder *p); -void MixCoder_Init(CMixCoder *p); -SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId); -SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int srcWasFinished, - ECoderFinishMode finishMode, ECoderStatus *status); - -typedef enum -{ - XZ_STATE_STREAM_HEADER, - XZ_STATE_STREAM_INDEX, - XZ_STATE_STREAM_INDEX_CRC, - XZ_STATE_STREAM_FOOTER, - XZ_STATE_STREAM_PADDING, - XZ_STATE_BLOCK_HEADER, - XZ_STATE_BLOCK, - XZ_STATE_BLOCK_FOOTER -} EXzState; - -typedef struct -{ - EXzState state; - UInt32 pos; - unsigned alignPos; - unsigned indexPreSize; - - CXzStreamFlags streamFlags; - - UInt32 blockHeaderSize; - UInt64 packSize; - UInt64 unpackSize; - - UInt64 numBlocks; - UInt64 indexSize; - UInt64 indexPos; - UInt64 padSize; - - UInt64 numStartedStreams; - UInt64 numFinishedStreams; - UInt64 numTotalBlocks; - - UInt32 crc; - CMixCoder decoder; - CXzBlock block; - CXzCheck check; - CSha256 sha; - Byte shaDigest[SHA256_DIGEST_SIZE]; - Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; -} CXzUnpacker; - -void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc); -void XzUnpacker_Init(CXzUnpacker *p); -void XzUnpacker_Free(CXzUnpacker *p); - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - CODER_FINISH_ANY - use smallest number of input bytes - CODER_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - CODER_STATUS_NOT_FINISHED, - CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams, - call XzUnpacker_IsStreamWasFinished to check that current stream was finished - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_DATA - Data error - SZ_ERROR_UNSUPPORTED - Unsupported method or method properties - SZ_ERROR_CRC - CRC error - // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). - - SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: - - xz Stream Signature failure - - CRC32 of xz Stream Header is failed - - The size of Stream padding is not multiple of four bytes. - It's possible to get that error, if xz stream was finished and the stream - contains some another data. In that case you can call XzUnpacker_GetExtraSize() - function to get real size of xz stream. -*/ - - -SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, - ECoderStatus *status); - -Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p); - -/* -Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of -xz stream in two cases: -XzUnpacker_Code() returns: - res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT - res == SZ_ERROR_NO_ARCHIVE -*/ - -UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/XzCrc64.c b/utils/lzma/C/XzCrc64.c deleted file mode 100644 index aa812548..00000000 --- a/utils/lzma/C/XzCrc64.c +++ /dev/null @@ -1,90 +0,0 @@ -/* XzCrc64.c -- CRC64 calculation -2011-06-28 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "XzCrc64.h" -#include "CpuArch.h" - -#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) - -#ifdef MY_CPU_LE - #define CRC_NUM_TABLES 4 -#else - #define CRC_NUM_TABLES 5 - #define CRC_UINT64_SWAP(v) \ - ((v >> 56) | \ - ((v >> 40) & ((UInt64)0xFF << 8)) | \ - ((v >> 24) & ((UInt64)0xFF << 16)) | \ - ((v >> 8) & ((UInt64)0xFF << 24)) | \ - ((v << 8) & ((UInt64)0xFF << 32)) | \ - ((v << 24) & ((UInt64)0xFF << 40)) | \ - ((v << 40) & ((UInt64)0xFF << 48)) | \ - (v << 56)) - UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -#endif - -#ifndef MY_CPU_BE - UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -#endif - -typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); - -static CRC_FUNC g_Crc64Update; -UInt64 g_Crc64Table[256 * CRC_NUM_TABLES]; - -UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) -{ - return g_Crc64Update(v, data, size, g_Crc64Table); -} - -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) -{ - return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; -} - -void MY_FAST_CALL Crc64GenerateTable() -{ - UInt32 i; - for (i = 0; i < 256; i++) - { - UInt64 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1)); - g_Crc64Table[i] = r; - } - for (; i < 256 * CRC_NUM_TABLES; i++) - { - UInt64 r = g_Crc64Table[i - 256]; - g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); - } - - #ifdef MY_CPU_LE - - g_Crc64Update = XzCrc64UpdateT4; - - - - - - - #else - { - #ifndef MY_CPU_BE - UInt32 k = 1; - if (*(const Byte *)&k == 1) - g_Crc64Update = XzCrc64UpdateT4; - else - #endif - { - for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) - { - UInt64 x = g_Crc64Table[i - 256]; - g_Crc64Table[i] = CRC_UINT64_SWAP(x); - } - g_Crc64Update = XzCrc64UpdateT1_BeT4; - } - } - #endif -} diff --git a/utils/lzma/C/XzCrc64.h b/utils/lzma/C/XzCrc64.h deleted file mode 100644 index 08dbc330..00000000 --- a/utils/lzma/C/XzCrc64.h +++ /dev/null @@ -1,26 +0,0 @@ -/* XzCrc64.h -- CRC64 calculation -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __XZ_CRC64_H -#define __XZ_CRC64_H - -#include - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -extern UInt64 g_Crc64Table[]; - -void MY_FAST_CALL Crc64GenerateTable(void); - -#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) -#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) -#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size); -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/XzCrc64Opt.c b/utils/lzma/C/XzCrc64Opt.c deleted file mode 100644 index dccae1c1..00000000 --- a/utils/lzma/C/XzCrc64Opt.c +++ /dev/null @@ -1,69 +0,0 @@ -/* XzCrc64Opt.c -- CRC64 calculation -2011-06-28 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -#ifndef MY_CPU_BE - -UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - UInt32 d = (UInt32)v ^ *(const UInt32 *)p; - v = (v >> 32) ^ - table[0x300 + ((d ) & 0xFF)] ^ - table[0x200 + ((d >> 8) & 0xFF)] ^ - table[0x100 + ((d >> 16) & 0xFF)] ^ - table[0x000 + ((d >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#endif - - -#ifndef MY_CPU_LE - -#define CRC_UINT64_SWAP(v) \ - ((v >> 56) | \ - ((v >> 40) & ((UInt64)0xFF << 8)) | \ - ((v >> 24) & ((UInt64)0xFF << 16)) | \ - ((v >> 8) & ((UInt64)0xFF << 24)) | \ - ((v << 8) & ((UInt64)0xFF << 32)) | \ - ((v << 24) & ((UInt64)0xFF << 40)) | \ - ((v << 40) & ((UInt64)0xFF << 48)) | \ - (v << 56)) - -UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - v = CRC_UINT64_SWAP(v); - table += 0x100; - for (; size >= 4; size -= 4, p += 4) - { - UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p; - v = (v << 32) ^ - table[0x000 + ((d ) & 0xFF)] ^ - table[0x100 + ((d >> 8) & 0xFF)] ^ - table[0x200 + ((d >> 16) & 0xFF)] ^ - table[0x300 + ((d >> 24))]; - } - table -= 0x100; - v = CRC_UINT64_SWAP(v); - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#endif diff --git a/utils/lzma/C/XzDec.c b/utils/lzma/C/XzDec.c deleted file mode 100644 index a5698e86..00000000 --- a/utils/lzma/C/XzDec.c +++ /dev/null @@ -1,909 +0,0 @@ -/* XzDec.c -- Xz Decode -2014-12-30 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -/* #define XZ_DUMP */ - -#ifdef XZ_DUMP -#include -#endif - -#include -#include - -#include "7zCrc.h" -#include "Alloc.h" -#include "Bra.h" -#include "CpuArch.h" -#include "Delta.h" -#include "Lzma2Dec.h" - -#ifdef USE_SUBBLOCK -#include "Bcj3Dec.c" -#include "SbDec.c" -#endif - -#include "Xz.h" - -#define XZ_CHECK_SIZE_MAX 64 - -#define CODER_BUF_SIZE (1 << 17) - -unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) -{ - int i, limit; - *value = 0; - limit = (maxSize > 9) ? 9 : (int)maxSize; - - for (i = 0; i < limit;) - { - Byte b = p[i]; - *value |= (UInt64)(b & 0x7F) << (7 * i++); - if ((b & 0x80) == 0) - return (b == 0 && i != 1) ? 0 : i; - } - return 0; -} - -/* ---------- BraState ---------- */ - -#define BRA_BUF_SIZE (1 << 14) - -typedef struct -{ - size_t bufPos; - size_t bufConv; - size_t bufTotal; - - UInt32 methodId; - int encodeMode; - UInt32 delta; - UInt32 ip; - UInt32 x86State; - Byte deltaState[DELTA_STATE_SIZE]; - - Byte buf[BRA_BUF_SIZE]; -} CBraState; - -void BraState_Free(void *pp, ISzAlloc *alloc) -{ - alloc->Free(alloc, pp); -} - -SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - CBraState *p = ((CBraState *)pp); - alloc = alloc; - p->ip = 0; - if (p->methodId == XZ_ID_Delta) - { - if (propSize != 1) - return SZ_ERROR_UNSUPPORTED; - p->delta = (unsigned)props[0] + 1; - } - else - { - if (propSize == 4) - { - UInt32 v = GetUi32(props); - switch(p->methodId) - { - case XZ_ID_PPC: - case XZ_ID_ARM: - case XZ_ID_SPARC: - if ((v & 3) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - case XZ_ID_ARMT: - if ((v & 1) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - case XZ_ID_IA64: - if ((v & 0xF) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - } - p->ip = v; - } - else if (propSize != 0) - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; -} - -void BraState_Init(void *pp) -{ - CBraState *p = ((CBraState *)pp); - p->bufPos = p->bufConv = p->bufTotal = 0; - x86_Convert_Init(p->x86State); - if (p->methodId == XZ_ID_Delta) - Delta_Init(p->deltaState); -} - -#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break; - -static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - CBraState *p = ((CBraState *)pp); - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - *destLen = 0; - *srcLen = 0; - finishMode = finishMode; - *wasFinished = 0; - while (destLenOrig > 0) - { - if (p->bufPos != p->bufConv) - { - size_t curSize = p->bufConv - p->bufPos; - if (curSize > destLenOrig) - curSize = destLenOrig; - memcpy(dest, p->buf + p->bufPos, curSize); - p->bufPos += curSize; - *destLen += curSize; - dest += curSize; - destLenOrig -= curSize; - continue; - } - p->bufTotal -= p->bufPos; - memmove(p->buf, p->buf + p->bufPos, p->bufTotal); - p->bufPos = 0; - p->bufConv = 0; - { - size_t curSize = BRA_BUF_SIZE - p->bufTotal; - if (curSize > srcLenOrig) - curSize = srcLenOrig; - memcpy(p->buf + p->bufTotal, src, curSize); - *srcLen += curSize; - src += curSize; - srcLenOrig -= curSize; - p->bufTotal += curSize; - } - if (p->bufTotal == 0) - break; - switch(p->methodId) - { - case XZ_ID_Delta: - if (p->encodeMode) - Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal); - else - Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal); - p->bufConv = p->bufTotal; - break; - case XZ_ID_X86: - p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode); - break; - CASE_BRA_CONV(PPC) - CASE_BRA_CONV(IA64) - CASE_BRA_CONV(ARM) - CASE_BRA_CONV(ARMT) - CASE_BRA_CONV(SPARC) - default: - return SZ_ERROR_UNSUPPORTED; - } - p->ip += (UInt32)p->bufConv; - - if (p->bufConv == 0) - { - if (!srcWasFinished) - break; - p->bufConv = p->bufTotal; - } - } - if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished) - *wasFinished = 1; - return SZ_OK; -} - -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc) -{ - CBraState *decoder; - if (id != XZ_ID_Delta && - id != XZ_ID_X86 && - id != XZ_ID_PPC && - id != XZ_ID_IA64 && - id != XZ_ID_ARM && - id != XZ_ID_ARMT && - id != XZ_ID_SPARC) - return SZ_ERROR_UNSUPPORTED; - p->p = 0; - decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState)); - if (decoder == 0) - return SZ_ERROR_MEM; - decoder->methodId = (UInt32)id; - decoder->encodeMode = encodeMode; - p->p = decoder; - p->Free = BraState_Free; - p->SetProps = BraState_SetProps; - p->Init = BraState_Init; - p->Code = BraState_Code; - return SZ_OK; -} - -/* ---------- SbState ---------- */ - -#ifdef USE_SUBBLOCK - -static void SbState_Free(void *pp, ISzAlloc *alloc) -{ - CSbDec *p = (CSbDec *)pp; - SbDec_Free(p); - alloc->Free(alloc, pp); -} - -static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - pp = pp; - props = props; - alloc = alloc; - return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; -} - -static void SbState_Init(void *pp) -{ - SbDec_Init((CSbDec *)pp); -} - -static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - CSbDec *p = (CSbDec *)pp; - SRes res; - srcWasFinished = srcWasFinished; - p->dest = dest; - p->destLen = *destLen; - p->src = src; - p->srcLen = *srcLen; - p->finish = finishMode; /* change it */ - res = SbDec_Decode((CSbDec *)pp); - *destLen -= p->destLen; - *srcLen -= p->srcLen; - *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ - return res; -} - -SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) -{ - CSbDec *decoder; - p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CSbDec)); - if (decoder == 0) - return SZ_ERROR_MEM; - p->p = decoder; - p->Free = SbState_Free; - p->SetProps = SbState_SetProps; - p->Init = SbState_Init; - p->Code = SbState_Code; - SbDec_Construct(decoder); - SbDec_SetAlloc(decoder, alloc); - return SZ_OK; -} -#endif - -/* ---------- Lzma2State ---------- */ - -static void Lzma2State_Free(void *pp, ISzAlloc *alloc) -{ - Lzma2Dec_Free((CLzma2Dec *)pp, alloc); - alloc->Free(alloc, pp); -} - -static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - if (propSize != 1) - return SZ_ERROR_UNSUPPORTED; - return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc); -} - -static void Lzma2State_Init(void *pp) -{ - Lzma2Dec_Init((CLzma2Dec *)pp); -} - -static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - ELzmaStatus status; - /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ - SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); - srcWasFinished = srcWasFinished; - *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); - return res; -} - -static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) -{ - CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec)); - p->p = decoder; - if (decoder == 0) - return SZ_ERROR_MEM; - p->Free = Lzma2State_Free; - p->SetProps = Lzma2State_SetProps; - p->Init = Lzma2State_Init; - p->Code = Lzma2State_Code; - Lzma2Dec_Construct(decoder); - return SZ_OK; -} - - -void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc) -{ - int i; - p->alloc = alloc; - p->buf = 0; - p->numCoders = 0; - for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) - p->coders[i].p = NULL; -} - -void MixCoder_Free(CMixCoder *p) -{ - int i; - for (i = 0; i < p->numCoders; i++) - { - IStateCoder *sc = &p->coders[i]; - if (p->alloc && sc->p) - sc->Free(sc->p, p->alloc); - } - p->numCoders = 0; - if (p->buf) - { - p->alloc->Free(p->alloc, p->buf); - p->buf = 0; /* 9.31: the BUG was fixed */ - } -} - -void MixCoder_Init(CMixCoder *p) -{ - int i; - for (i = 0; i < p->numCoders - 1; i++) - { - p->size[i] = 0; - p->pos[i] = 0; - p->finished[i] = 0; - } - for (i = 0; i < p->numCoders; i++) - { - IStateCoder *coder = &p->coders[i]; - coder->Init(coder->p); - } -} - -SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId) -{ - IStateCoder *sc = &p->coders[coderIndex]; - p->ids[coderIndex] = methodId; - switch(methodId) - { - case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc); - #ifdef USE_SUBBLOCK - case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); - #endif - } - if (coderIndex == 0) - return SZ_ERROR_UNSUPPORTED; - return BraState_SetFromMethod(sc, methodId, 0, p->alloc); -} - -SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int srcWasFinished, - ECoderFinishMode finishMode, ECoderStatus *status) -{ - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - Bool allFinished = True; - *destLen = 0; - *srcLen = 0; - *status = CODER_STATUS_NOT_FINISHED; - - if (p->buf == 0) - { - p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); - if (p->buf == 0) - return SZ_ERROR_MEM; - } - - if (p->numCoders != 1) - finishMode = CODER_FINISH_ANY; - - for (;;) - { - Bool processed = False; - int i; - /* - if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) - break; - */ - - for (i = 0; i < p->numCoders; i++) - { - SRes res; - IStateCoder *coder = &p->coders[i]; - Byte *destCur; - SizeT destLenCur, srcLenCur; - const Byte *srcCur; - int srcFinishedCur; - int encodingWasFinished; - - if (i == 0) - { - srcCur = src; - srcLenCur = srcLenOrig - *srcLen; - srcFinishedCur = srcWasFinished; - } - else - { - srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1]; - srcLenCur = p->size[i - 1] - p->pos[i - 1]; - srcFinishedCur = p->finished[i - 1]; - } - - if (i == p->numCoders - 1) - { - destCur = dest; - destLenCur = destLenOrig - *destLen; - } - else - { - if (p->pos[i] != p->size[i]) - continue; - destCur = p->buf + (CODER_BUF_SIZE * i); - destLenCur = CODER_BUF_SIZE; - } - - res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished); - - if (!encodingWasFinished) - allFinished = False; - - if (i == 0) - { - *srcLen += srcLenCur; - src += srcLenCur; - } - else - { - p->pos[i - 1] += srcLenCur; - } - - if (i == p->numCoders - 1) - { - *destLen += destLenCur; - dest += destLenCur; - } - else - { - p->size[i] = destLenCur; - p->pos[i] = 0; - p->finished[i] = encodingWasFinished; - } - - if (res != SZ_OK) - return res; - - if (destLenCur != 0 || srcLenCur != 0) - processed = True; - } - if (!processed) - break; - } - if (allFinished) - *status = CODER_STATUS_FINISHED_WITH_MARK; - return SZ_OK; -} - -SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) -{ - *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); - if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != - GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) - return SZ_ERROR_NO_ARCHIVE; - return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; -} - -static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) -{ - return - indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) && - (GetUi32(buf) == CrcCalc(buf + 4, 6) && - flags == GetBe16(buf + 8) && - memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0); -} - -#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ - if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } - - -SRes XzBlock_Parse(CXzBlock *p, const Byte *header) -{ - unsigned pos; - int numFilters, i; - UInt32 headerSize = (UInt32)header[0] << 2; - - if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) - return SZ_ERROR_ARCHIVE; - - pos = 1; - if (pos == headerSize) - return SZ_ERROR_ARCHIVE; - p->flags = header[pos++]; - - if (XzBlock_HasPackSize(p)) - { - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize); - if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) - return SZ_ERROR_ARCHIVE; - } - - if (XzBlock_HasUnpackSize(p)) - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize); - - numFilters = XzBlock_GetNumFilters(p); - for (i = 0; i < numFilters; i++) - { - CXzFilter *filter = p->filters + i; - UInt64 size; - READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id); - READ_VARINT_AND_CHECK(header, pos, headerSize, &size); - if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) - return SZ_ERROR_ARCHIVE; - filter->propsSize = (UInt32)size; - memcpy(filter->props, header + pos, (size_t)size); - pos += (unsigned)size; - - #ifdef XZ_DUMP - printf("\nf[%d] = %2X: ", i, filter->id); - { - int i; - for (i = 0; i < size; i++) - printf(" %2X", filter->props[i]); - } - #endif - } - - while (pos < headerSize) - if (header[pos++] != 0) - return SZ_ERROR_ARCHIVE; - return SZ_OK; -} - -SRes XzDec_Init(CMixCoder *p, const CXzBlock *block) -{ - int i; - Bool needReInit = True; - int numFilters = XzBlock_GetNumFilters(block); - if (numFilters == p->numCoders) - { - for (i = 0; i < numFilters; i++) - if (p->ids[i] != block->filters[numFilters - 1 - i].id) - break; - needReInit = (i != numFilters); - } - if (needReInit) - { - MixCoder_Free(p); - p->numCoders = numFilters; - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &block->filters[numFilters - 1 - i]; - RINOK(MixCoder_SetFromMethod(p, i, f->id)); - } - } - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &block->filters[numFilters - 1 - i]; - IStateCoder *sc = &p->coders[i]; - RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)); - } - MixCoder_Init(p); - return SZ_OK; -} - -void XzUnpacker_Init(CXzUnpacker *p) -{ - p->state = XZ_STATE_STREAM_HEADER; - p->pos = 0; - p->numStartedStreams = 0; - p->numFinishedStreams = 0; - p->numTotalBlocks = 0; - p->padSize = 0; -} - -void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc) -{ - MixCoder_Construct(&p->decoder, alloc); - XzUnpacker_Init(p); -} - -void XzUnpacker_Free(CXzUnpacker *p) -{ - MixCoder_Free(&p->decoder); -} - -SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status) -{ - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - *destLen = 0; - *srcLen = 0; - *status = CODER_STATUS_NOT_SPECIFIED; - for (;;) - { - SizeT srcRem = srcLenOrig - *srcLen; - - if (p->state == XZ_STATE_BLOCK) - { - SizeT destLen2 = destLenOrig - *destLen; - SizeT srcLen2 = srcLenOrig - *srcLen; - SRes res; - if (srcLen2 == 0 && destLen2 == 0) - { - *status = CODER_STATUS_NOT_FINISHED; - return SZ_OK; - } - - res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status); - XzCheck_Update(&p->check, dest, destLen2); - - (*srcLen) += srcLen2; - src += srcLen2; - p->packSize += srcLen2; - - (*destLen) += destLen2; - dest += destLen2; - p->unpackSize += destLen2; - - RINOK(res); - - if (*status == CODER_STATUS_FINISHED_WITH_MARK) - { - Byte temp[32]; - unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags)); - num += Xz_WriteVarInt(temp + num, p->unpackSize); - Sha256_Update(&p->sha, temp, num); - p->indexSize += num; - p->numBlocks++; - - p->state = XZ_STATE_BLOCK_FOOTER; - p->pos = 0; - p->alignPos = 0; - } - else if (srcLen2 == 0 && destLen2 == 0) - return SZ_OK; - - continue; - } - - if (srcRem == 0) - { - *status = CODER_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - - switch (p->state) - { - case XZ_STATE_STREAM_HEADER: - { - if (p->pos < XZ_STREAM_HEADER_SIZE) - { - if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) - return SZ_ERROR_NO_ARCHIVE; - p->buf[p->pos++] = *src++; - (*srcLen)++; - } - else - { - RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); - p->numStartedStreams++; - p->state = XZ_STATE_BLOCK_HEADER; - Sha256_Init(&p->sha); - p->indexSize = 0; - p->numBlocks = 0; - p->pos = 0; - } - break; - } - - case XZ_STATE_BLOCK_HEADER: - { - if (p->pos == 0) - { - p->buf[p->pos++] = *src++; - (*srcLen)++; - if (p->buf[0] == 0) - { - p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); - p->indexPos = p->indexPreSize; - p->indexSize += p->indexPreSize; - Sha256_Final(&p->sha, p->shaDigest); - Sha256_Init(&p->sha); - p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); - p->state = XZ_STATE_STREAM_INDEX; - } - p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; - } - else if (p->pos != p->blockHeaderSize) - { - UInt32 cur = p->blockHeaderSize - p->pos; - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - } - else - { - RINOK(XzBlock_Parse(&p->block, p->buf)); - p->numTotalBlocks++; - p->state = XZ_STATE_BLOCK; - p->packSize = 0; - p->unpackSize = 0; - XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); - RINOK(XzDec_Init(&p->decoder, &p->block)); - } - break; - } - - case XZ_STATE_BLOCK_FOOTER: - { - if (((p->packSize + p->alignPos) & 3) != 0) - { - (*srcLen)++; - p->alignPos++; - if (*src++ != 0) - return SZ_ERROR_CRC; - } - else - { - UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); - UInt32 cur = checkSize - p->pos; - if (cur != 0) - { - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - } - else - { - Byte digest[XZ_CHECK_SIZE_MAX]; - p->state = XZ_STATE_BLOCK_HEADER; - p->pos = 0; - if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) - return SZ_ERROR_CRC; - } - } - break; - } - - case XZ_STATE_STREAM_INDEX: - { - if (p->pos < p->indexPreSize) - { - (*srcLen)++; - if (*src++ != p->buf[p->pos++]) - return SZ_ERROR_CRC; - } - else - { - if (p->indexPos < p->indexSize) - { - UInt64 cur = p->indexSize - p->indexPos; - if (srcRem > cur) - srcRem = (SizeT)cur; - p->crc = CrcUpdate(p->crc, src, srcRem); - Sha256_Update(&p->sha, src, srcRem); - (*srcLen) += srcRem; - src += srcRem; - p->indexPos += srcRem; - } - else if ((p->indexPos & 3) != 0) - { - Byte b = *src++; - p->crc = CRC_UPDATE_BYTE(p->crc, b); - (*srcLen)++; - p->indexPos++; - p->indexSize++; - if (b != 0) - return SZ_ERROR_CRC; - } - else - { - Byte digest[SHA256_DIGEST_SIZE]; - p->state = XZ_STATE_STREAM_INDEX_CRC; - p->indexSize += 4; - p->pos = 0; - Sha256_Final(&p->sha, digest); - if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) - return SZ_ERROR_CRC; - } - } - break; - } - - case XZ_STATE_STREAM_INDEX_CRC: - { - if (p->pos < 4) - { - (*srcLen)++; - p->buf[p->pos++] = *src++; - } - else - { - p->state = XZ_STATE_STREAM_FOOTER; - p->pos = 0; - if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf)) - return SZ_ERROR_CRC; - } - break; - } - - case XZ_STATE_STREAM_FOOTER: - { - UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - if (p->pos == XZ_STREAM_FOOTER_SIZE) - { - p->state = XZ_STATE_STREAM_PADDING; - p->numFinishedStreams++; - p->padSize = 0; - if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) - return SZ_ERROR_CRC; - } - break; - } - - case XZ_STATE_STREAM_PADDING: - { - if (*src != 0) - { - if (((UInt32)p->padSize & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - p->pos = 0; - p->state = XZ_STATE_STREAM_HEADER; - } - else - { - (*srcLen)++; - src++; - p->padSize++; - } - break; - } - - case XZ_STATE_BLOCK: break; /* to disable GCC warning */ - } - } - /* - if (p->state == XZ_STATE_FINISHED) - *status = CODER_STATUS_FINISHED_WITH_MARK; - return SZ_OK; - */ -} - -Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p) -{ - return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); -} - -UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p) -{ - UInt64 num = 0; - if (p->state == XZ_STATE_STREAM_PADDING) - num += p->padSize; - else if (p->state == XZ_STATE_STREAM_HEADER) - num += p->padSize + p->pos; - return num; -} diff --git a/utils/lzma/C/XzEnc.c b/utils/lzma/C/XzEnc.c deleted file mode 100644 index ed6e1ba6..00000000 --- a/utils/lzma/C/XzEnc.c +++ /dev/null @@ -1,522 +0,0 @@ -/* XzEnc.c -- Xz Encode -2014-12-30 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include -#include - -#include "7zCrc.h" -#include "Alloc.h" -#include "Bra.h" -#include "CpuArch.h" -#ifdef USE_SUBBLOCK -#include "Bcj3Enc.c" -#include "SbFind.c" -#include "SbEnc.c" -#endif - -#include "XzEnc.h" - -static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); } -static void SzBigFree(void *p, void *address) { p = p; BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -#define XzBlock_ClearFlags(p) (p)->flags = 0; -#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1); -#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; -#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; - -static SRes WriteBytes(ISeqOutStream *s, const void *buf, UInt32 size) -{ - return (s->Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; -} - -static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UInt32 *crc) -{ - *crc = CrcUpdate(*crc, buf, size); - return WriteBytes(s, buf, size); -} - -SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s) -{ - UInt32 crc; - Byte header[XZ_STREAM_HEADER_SIZE]; - memcpy(header, XZ_SIG, XZ_SIG_SIZE); - header[XZ_SIG_SIZE] = (Byte)(f >> 8); - header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); - crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); - SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc); - return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); -} - -SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s) -{ - Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; - - unsigned pos = 1; - int numFilters, i; - header[pos++] = p->flags; - - if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); - if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); - numFilters = XzBlock_GetNumFilters(p); - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &p->filters[i]; - pos += Xz_WriteVarInt(header + pos, f->id); - pos += Xz_WriteVarInt(header + pos, f->propsSize); - memcpy(header + pos, f->props, f->propsSize); - pos += f->propsSize; - } - while((pos & 3) != 0) - header[pos++] = 0; - header[0] = (Byte)(pos >> 2); - SetUi32(header + pos, CrcCalc(header, pos)); - return WriteBytes(s, header, pos + 4); -} - -SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s) -{ - Byte buf[32]; - UInt64 globalPos; - { - UInt32 crc = CRC_INIT_VAL; - unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); - size_t i; - - globalPos = pos; - buf[0] = 0; - RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); - for (i = 0; i < p->numBlocks; i++) - { - const CXzBlockSizes *block = &p->blocks[i]; - pos = Xz_WriteVarInt(buf, block->totalSize); - pos += Xz_WriteVarInt(buf + pos, block->unpackSize); - globalPos += pos; - RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); - } - pos = ((unsigned)globalPos & 3); - if (pos != 0) - { - buf[0] = buf[1] = buf[2] = 0; - RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc)); - globalPos += 4 - pos; - } - { - SetUi32(buf, CRC_GET_DIGEST(crc)); - RINOK(WriteBytes(s, buf, 4)); - globalPos += 4; - } - } - - { - UInt32 indexSize = (UInt32)((globalPos >> 2) - 1); - SetUi32(buf + 4, indexSize); - buf[8] = (Byte)(p->flags >> 8); - buf[9] = (Byte)(p->flags & 0xFF); - SetUi32(buf, CrcCalc(buf + 4, 6)); - memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE); - return WriteBytes(s, buf, 12); - } -} - -SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc) -{ - if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks) - { - size_t num = (p->numBlocks + 1) * 2; - size_t newSize = sizeof(CXzBlockSizes) * num; - CXzBlockSizes *blocks; - if (newSize / sizeof(CXzBlockSizes) != num) - return SZ_ERROR_MEM; - blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize); - if (blocks == 0) - return SZ_ERROR_MEM; - if (p->numBlocks != 0) - { - memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes)); - Xz_Free(p, alloc); - } - p->blocks = blocks; - p->numBlocksAllocated = num; - } - { - CXzBlockSizes *block = &p->blocks[p->numBlocks++]; - block->totalSize = totalSize; - block->unpackSize = unpackSize; - } - return SZ_OK; -} - -/* ---------- CSeqCheckInStream ---------- */ - -typedef struct -{ - ISeqInStream p; - ISeqInStream *realStream; - UInt64 processed; - CXzCheck check; -} CSeqCheckInStream; - -void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode) -{ - p->processed = 0; - XzCheck_Init(&p->check, mode); -} - -void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest) -{ - XzCheck_Final(&p->check, digest); -} - -static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size) -{ - CSeqCheckInStream *p = (CSeqCheckInStream *)pp; - SRes res = p->realStream->Read(p->realStream, data, size); - XzCheck_Update(&p->check, data, *size); - p->processed += *size; - return res; -} - -/* ---------- CSeqSizeOutStream ---------- */ - -typedef struct -{ - ISeqOutStream p; - ISeqOutStream *realStream; - UInt64 processed; -} CSeqSizeOutStream; - -static size_t MyWrite(void *pp, const void *data, size_t size) -{ - CSeqSizeOutStream *p = (CSeqSizeOutStream *)pp; - size = p->realStream->Write(p->realStream, data, size); - p->processed += size; - return size; -} - -/* ---------- CSeqInFilter ---------- */ - -#define FILTER_BUF_SIZE (1 << 20) - -typedef struct -{ - ISeqInStream p; - ISeqInStream *realStream; - IStateCoder StateCoder; - Byte *buf; - size_t curPos; - size_t endPos; - int srcWasFinished; -} CSeqInFilter; - -static SRes SeqInFilter_Read(void *pp, void *data, size_t *size) -{ - CSeqInFilter *p = (CSeqInFilter *)pp; - size_t sizeOriginal = *size; - if (sizeOriginal == 0) - return SZ_OK; - *size = 0; - for (;;) - { - if (!p->srcWasFinished && p->curPos == p->endPos) - { - p->curPos = 0; - p->endPos = FILTER_BUF_SIZE; - RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos)); - if (p->endPos == 0) - p->srcWasFinished = 1; - } - { - SizeT srcLen = p->endPos - p->curPos; - int wasFinished; - SRes res; - *size = sizeOriginal; - res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen, - p->srcWasFinished, CODER_FINISH_ANY, &wasFinished); - p->curPos += srcLen; - if (*size != 0 || srcLen == 0 || res != 0) - return res; - } - } -} - -static void SeqInFilter_Construct(CSeqInFilter *p) -{ - p->buf = NULL; - p->p.Read = SeqInFilter_Read; -} - -static void SeqInFilter_Free(CSeqInFilter *p) -{ - if (p->buf) - { - g_Alloc.Free(&g_Alloc, p->buf); - p->buf = NULL; - } -} - -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc); - -static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props) -{ - if (!p->buf) - { - p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE); - if (!p->buf) - return SZ_ERROR_MEM; - } - p->curPos = p->endPos = 0; - p->srcWasFinished = 0; - RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc)); - RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc)); - p->StateCoder.Init(p->StateCoder.p); - return SZ_OK; -} - -/* ---------- CSbEncInStream ---------- */ - -#ifdef USE_SUBBLOCK - -typedef struct -{ - ISeqInStream p; - ISeqInStream *inStream; - CSbEnc enc; -} CSbEncInStream; - -static SRes SbEncInStream_Read(void *pp, void *data, size_t *size) -{ - CSbEncInStream *p = (CSbEncInStream *)pp; - size_t sizeOriginal = *size; - if (sizeOriginal == 0) - return S_OK; - for (;;) - { - if (p->enc.needRead && !p->enc.readWasFinished) - { - size_t processed = p->enc.needReadSizeMax; - RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)); - p->enc.readPos += processed; - if (processed == 0) - { - p->enc.readWasFinished = True; - p->enc.isFinalFinished = True; - } - p->enc.needRead = False; - } - *size = sizeOriginal; - RINOK(SbEnc_Read(&p->enc, data, size)); - if (*size != 0 || !p->enc.needRead) - return S_OK; - } -} - -void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc) -{ - SbEnc_Construct(&p->enc, alloc); - p->p.Read = SbEncInStream_Read; -} - -SRes SbEncInStream_Init(CSbEncInStream *p) -{ - return SbEnc_Init(&p->enc); -} - -void SbEncInStream_Free(CSbEncInStream *p) -{ - SbEnc_Free(&p->enc); -} - -#endif - - -typedef struct -{ - CLzma2EncHandle lzma2; - #ifdef USE_SUBBLOCK - CSbEncInStream sb; - #endif - CSeqInFilter filter; - ISzAlloc *alloc; - ISzAlloc *bigAlloc; -} CLzma2WithFilters; - - -static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, ISzAlloc *bigAlloc) -{ - p->alloc = alloc; - p->bigAlloc = bigAlloc; - p->lzma2 = NULL; - #ifdef USE_SUBBLOCK - SbEncInStream_Construct(&p->sb, alloc); - #endif - SeqInFilter_Construct(&p->filter); -} - -static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p) -{ - p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc); - if (p->lzma2 == 0) - return SZ_ERROR_MEM; - return SZ_OK; -} - -static void Lzma2WithFilters_Free(CLzma2WithFilters *p) -{ - SeqInFilter_Free(&p->filter); - #ifdef USE_SUBBLOCK - SbEncInStream_Free(&p->sb); - #endif - if (p->lzma2) - { - Lzma2Enc_Destroy(p->lzma2); - p->lzma2 = NULL; - } -} - -void XzProps_Init(CXzProps *p) -{ - p->lzma2Props = 0; - p->filterProps = 0; - p->checkId = XZ_CHECK_CRC32; -} - -void XzFilterProps_Init(CXzFilterProps *p) -{ - p->id = 0; - p->delta = 0; - p->ip= 0; - p->ipDefined = False; -} - -static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, - ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress) -{ - xz->flags = (Byte)props->checkId; - - RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props)); - RINOK(Xz_WriteHeader(xz->flags, outStream)); - - { - CSeqCheckInStream checkInStream; - CSeqSizeOutStream seqSizeOutStream; - CXzBlock block; - int filterIndex = 0; - CXzFilter *filter = NULL; - const CXzFilterProps *fp = props->filterProps; - - XzBlock_ClearFlags(&block); - XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); - - if (fp) - { - filter = &block.filters[filterIndex++]; - filter->id = fp->id; - filter->propsSize = 0; - if (fp->id == XZ_ID_Delta) - { - filter->props[0] = (Byte)(fp->delta - 1); - filter->propsSize = 1; - } - else if (fp->ipDefined) - { - SetUi32(filter->props, fp->ip); - filter->propsSize = 4; - } - } - - { - CXzFilter *f = &block.filters[filterIndex++]; - f->id = XZ_ID_LZMA2; - f->propsSize = 1; - f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); - } - - seqSizeOutStream.p.Write = MyWrite; - seqSizeOutStream.realStream = outStream; - seqSizeOutStream.processed = 0; - - RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); - - checkInStream.p.Read = SeqCheckInStream_Read; - checkInStream.realStream = inStream; - SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); - - if (fp) - { - #ifdef USE_SUBBLOCK - if (fp->id == XZ_ID_Subblock) - { - lzmaf->sb.inStream = &checkInStream.p; - RINOK(SbEncInStream_Init(&lzmaf->sb)); - } - else - #endif - { - lzmaf->filter.realStream = &checkInStream.p; - RINOK(SeqInFilter_Init(&lzmaf->filter, filter)); - } - } - - { - UInt64 packPos = seqSizeOutStream.processed; - SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, - fp ? - #ifdef USE_SUBBLOCK - (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p: - #endif - &lzmaf->filter.p: - &checkInStream.p, - progress); - RINOK(res); - block.unpackSize = checkInStream.processed; - block.packSize = seqSizeOutStream.processed - packPos; - } - - { - unsigned padSize = 0; - Byte buf[128]; - while((((unsigned)block.packSize + padSize) & 3) != 0) - buf[padSize++] = 0; - SeqCheckInStream_GetDigest(&checkInStream, buf + padSize); - RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags))); - RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc)); - } - } - return Xz_WriteFooter(xz, outStream); -} - -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress) -{ - SRes res; - CXzStream xz; - CLzma2WithFilters lzmaf; - Xz_Construct(&xz); - Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc); - res = Lzma2WithFilters_Create(&lzmaf); - if (res == SZ_OK) - res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress); - Lzma2WithFilters_Free(&lzmaf); - Xz_Free(&xz, &g_Alloc); - return res; -} - -SRes Xz_EncodeEmpty(ISeqOutStream *outStream) -{ - SRes res; - CXzStream xz; - Xz_Construct(&xz); - res = Xz_WriteHeader(xz.flags, outStream); - if (res == SZ_OK) - res = Xz_WriteFooter(&xz, outStream); - Xz_Free(&xz, &g_Alloc); - return res; -} diff --git a/utils/lzma/C/XzEnc.h b/utils/lzma/C/XzEnc.h deleted file mode 100644 index c3c19eca..00000000 --- a/utils/lzma/C/XzEnc.h +++ /dev/null @@ -1,39 +0,0 @@ -/* XzEnc.h -- Xz Encode -2011-02-07 : Igor Pavlov : Public domain */ - -#ifndef __XZ_ENC_H -#define __XZ_ENC_H - -#include "Lzma2Enc.h" - -#include "Xz.h" - -EXTERN_C_BEGIN - -typedef struct -{ - UInt32 id; - UInt32 delta; - UInt32 ip; - int ipDefined; -} CXzFilterProps; - -void XzFilterProps_Init(CXzFilterProps *p); - -typedef struct -{ - const CLzma2EncProps *lzma2Props; - const CXzFilterProps *filterProps; - unsigned checkId; -} CXzProps; - -void XzProps_Init(CXzProps *p); - -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress); - -SRes Xz_EncodeEmpty(ISeqOutStream *outStream); - -EXTERN_C_END - -#endif diff --git a/utils/lzma/C/XzIn.c b/utils/lzma/C/XzIn.c deleted file mode 100644 index 05b4a5f0..00000000 --- a/utils/lzma/C/XzIn.c +++ /dev/null @@ -1,307 +0,0 @@ -/* XzIn.c - Xz input -2014-12-30 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zCrc.h" -#include "CpuArch.h" -#include "Xz.h" - -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) -{ - Byte sig[XZ_STREAM_HEADER_SIZE]; - RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) - return SZ_ERROR_NO_ARCHIVE; - return Xz_ParseHeader(p, sig); -} - -#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ - if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } - -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes) -{ - Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; - unsigned headerSize; - *headerSizeRes = 0; - RINOK(SeqInStream_ReadByte(inStream, &header[0])); - headerSize = ((unsigned)header[0] << 2) + 4; - if (headerSize == 0) - { - *headerSizeRes = 1; - *isIndex = True; - return SZ_OK; - } - - *isIndex = False; - *headerSizeRes = headerSize; - RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1)); - return XzBlock_Parse(p, header); -} - -#define ADD_SIZE_CHECH(size, val) \ - { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; } - -UInt64 Xz_GetUnpackSize(const CXzStream *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECH(size, p->blocks[i].unpackSize); - return size; -} - -UInt64 Xz_GetPackSize(const CXzStream *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECH(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3); - return size; -} - -/* -SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) -{ - return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); -} -*/ - -static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) -{ - size_t i, numBlocks, pos = 1; - UInt32 crc; - - if (size < 5 || buf[0] != 0) - return SZ_ERROR_ARCHIVE; - - size -= 4; - crc = CrcCalc(buf, size); - if (crc != GetUi32(buf + size)) - return SZ_ERROR_ARCHIVE; - - { - UInt64 numBlocks64; - READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64); - numBlocks = (size_t)numBlocks64; - if (numBlocks != numBlocks64 || numBlocks * 2 > size) - return SZ_ERROR_ARCHIVE; - } - - Xz_Free(p, alloc); - if (numBlocks != 0) - { - p->numBlocks = numBlocks; - p->numBlocksAllocated = numBlocks; - p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); - if (p->blocks == 0) - return SZ_ERROR_MEM; - for (i = 0; i < numBlocks; i++) - { - CXzBlockSizes *block = &p->blocks[i]; - READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize); - READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize); - if (block->totalSize == 0) - return SZ_ERROR_ARCHIVE; - } - } - while ((pos & 3) != 0) - if (buf[pos++] != 0) - return SZ_ERROR_ARCHIVE; - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; -} - -static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc) -{ - SRes res; - size_t size; - Byte *buf; - if (indexSize > ((UInt32)1 << 31)) - return SZ_ERROR_UNSUPPORTED; - size = (size_t)indexSize; - if (size != indexSize) - return SZ_ERROR_UNSUPPORTED; - buf = alloc->Alloc(alloc, size); - if (buf == 0) - return SZ_ERROR_MEM; - res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); - if (res == SZ_OK) - res = Xz_ReadIndex2(p, buf, size, alloc); - alloc->Free(alloc, buf); - return res; -} - -static SRes SeekFromCur(ILookInStream *inStream, Int64 *res) -{ - return inStream->Seek(inStream, res, SZ_SEEK_CUR); -} - -static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc) -{ - UInt64 indexSize; - Byte buf[XZ_STREAM_FOOTER_SIZE]; - - if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - *startOffset = -XZ_STREAM_FOOTER_SIZE; - RINOK(SeekFromCur(stream, startOffset)); - - RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) - { - UInt32 total = 0; - *startOffset += XZ_STREAM_FOOTER_SIZE; - for (;;) - { - size_t i; - #define TEMP_BUF_SIZE (1 << 10) - Byte tempBuf[TEMP_BUF_SIZE]; - if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) - return SZ_ERROR_NO_ARCHIVE; - i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset; - total += (UInt32)i; - *startOffset = -(Int64)i; - RINOK(SeekFromCur(stream, startOffset)); - RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE)); - for (; i != 0; i--) - if (tempBuf[i - 1] != 0) - break; - if (i != 0) - { - if ((i & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - *startOffset += i; - break; - } - } - if (*startOffset < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - *startOffset -= XZ_STREAM_FOOTER_SIZE; - RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); - RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) - return SZ_ERROR_NO_ARCHIVE; - } - - p->flags = (CXzStreamFlags)GetBe16(buf + 8); - - if (!XzFlags_IsSupported(p->flags)) - return SZ_ERROR_UNSUPPORTED; - - if (GetUi32(buf) != CrcCalc(buf + 4, 6)) - return SZ_ERROR_ARCHIVE; - - indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; - - *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE); - RINOK(SeekFromCur(stream, startOffset)); - - RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)); - - { - UInt64 totalSize = Xz_GetPackSize(p); - UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize; - if (totalSize == XZ_SIZE_OVERFLOW || - sum >= ((UInt64)1 << 63) || - totalSize >= ((UInt64)1 << 63)) - return SZ_ERROR_ARCHIVE; - *startOffset = -(Int64)sum; - RINOK(SeekFromCur(stream, startOffset)); - } - { - CXzStreamFlags headerFlags; - CSecToRead secToRead; - SecToRead_CreateVTable(&secToRead); - secToRead.realStream = stream; - - RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s)); - return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; - } -} - - -/* ---------- Xz Streams ---------- */ - -void Xzs_Construct(CXzs *p) -{ - p->num = p->numAllocated = 0; - p->streams = 0; -} - -void Xzs_Free(CXzs *p, ISzAlloc *alloc) -{ - size_t i; - for (i = 0; i < p->num; i++) - Xz_Free(&p->streams[i], alloc); - alloc->Free(alloc, p->streams); - p->num = p->numAllocated = 0; - p->streams = 0; -} - -UInt64 Xzs_GetNumBlocks(const CXzs *p) -{ - UInt64 num = 0; - size_t i; - for (i = 0; i < p->num; i++) - num += p->streams[i].numBlocks; - return num; -} - -UInt64 Xzs_GetUnpackSize(const CXzs *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->num; i++) - ADD_SIZE_CHECH(size, Xz_GetUnpackSize(&p->streams[i])); - return size; -} - -/* -UInt64 Xzs_GetPackSize(const CXzs *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->num; i++) - ADD_SIZE_CHECH(size, Xz_GetTotalSize(&p->streams[i])); - return size; -} -*/ - -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc) -{ - Int64 endOffset = 0; - RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END)); - *startOffset = endOffset; - for (;;) - { - CXzStream st; - SRes res; - Xz_Construct(&st); - res = Xz_ReadBackward(&st, stream, startOffset, alloc); - st.startOffset = *startOffset; - RINOK(res); - if (p->num == p->numAllocated) - { - size_t newNum = p->num + p->num / 4 + 1; - Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream)); - if (data == 0) - return SZ_ERROR_MEM; - p->numAllocated = newNum; - if (p->num != 0) - memcpy(data, p->streams, p->num * sizeof(CXzStream)); - alloc->Free(alloc, p->streams); - p->streams = (CXzStream *)data; - } - p->streams[p->num++] = st; - if (*startOffset == 0) - break; - RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); - if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK) - return SZ_ERROR_PROGRESS; - } - return SZ_OK; -} diff --git a/utils/phonemeextractor/phonemeextractor.cpp b/utils/phonemeextractor/phonemeextractor.cpp index 271f1850..a4d336fb 100644 --- a/utils/phonemeextractor/phonemeextractor.cpp +++ b/utils/phonemeextractor/phonemeextractor.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -50,8 +50,8 @@ void LogReset( void ) char *va( const char *fmt, ... ); //----------------------------------------------------------------------------- -// Purpose: -// Input : *words - +// Purpose: +// Input : *words - //----------------------------------------------------------------------------- void LogWords( CSentence& sentence ) { @@ -65,8 +65,8 @@ void LogWords( CSentence& sentence ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *phonemes - +// Purpose: +// Input : *phonemes - //----------------------------------------------------------------------------- void LogPhonemes( CSentence& sentence ) { @@ -91,9 +91,9 @@ void LogPhonemes( CSentence& sentence ) //----------------------------------------------------------------------------- // Purpose: Walk list of words and phonemes and create phoneme tags in CSentence object // FIXME: Right now, phonemes are assumed to evenly space out across a word. -// Input : *converter - -// result - -// sentence - +// Input : *converter - +// result - +// sentence - //----------------------------------------------------------------------------- void EnumeratePhonemes( ISpPhoneConverter *converter, const ISpRecoResult* result, CSentence& sentence ) { @@ -177,10 +177,10 @@ void EnumeratePhonemes( ISpPhoneConverter *converter, const ISpRecoResult* resul wszPhoneme[ 0 ] = L'\0'; converter->IdToPhone( pstr, wszPhoneme ); - + CPhonemeTag *p = new CPhonemeTag( W2A( wszPhoneme ) ); Assert( p ); - + float weight = WeightForPhoneme( W2A( wszPhoneme ) ); p->m_uiStartByte = wordstart + (int)( startWeight * psize ); @@ -195,7 +195,7 @@ void EnumeratePhonemes( ISpPhoneConverter *converter, const ISpRecoResult* resul number++; } - } + } } // Free memory @@ -215,10 +215,10 @@ typedef struct //----------------------------------------------------------------------------- // Purpose: Creates start for word of sentence -// Input : cpRecoGrammar - -// *root - -// *rules - -// word - +// Input : cpRecoGrammar - +// *root - +// *rules - +// word - //----------------------------------------------------------------------------- void AddWordRule( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector< WORDRULETYPE > *rules, CSpDynamicString& word ) { @@ -241,10 +241,10 @@ void AddWordRule( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector } //----------------------------------------------------------------------------- -// Purpose: -// Input : cpRecoGrammar - -// *from - -// *to - +// Purpose: +// Input : cpRecoGrammar - +// *from - +// *to - //----------------------------------------------------------------------------- void AddWordTransitionRule( ISpRecoGrammar* cpRecoGrammar, WORDRULETYPE *from, WORDRULETYPE *to ) { @@ -267,10 +267,10 @@ void AddWordTransitionRule( ISpRecoGrammar* cpRecoGrammar, WORDRULETYPE *from, W } //----------------------------------------------------------------------------- -// Purpose: -// Input : cpRecoGrammar - -// *from - -// *to - +// Purpose: +// Input : cpRecoGrammar - +// *from - +// *to - //----------------------------------------------------------------------------- void AddOptionalTransitionRule( ISpRecoGrammar* cpRecoGrammar, WORDRULETYPE *from, WORDRULETYPE *to ) { @@ -295,10 +295,10 @@ void AddOptionalTransitionRule( ISpRecoGrammar* cpRecoGrammar, WORDRULETYPE *fro #define MAX_WORD_SKIP 1 //----------------------------------------------------------------------------- // Purpose: Links together all word rule states into a sentence rule CFG -// Input : singleword - -// cpRecoGrammar - -// *root - -// *rules - +// Input : singleword - +// cpRecoGrammar - +// *root - +// *rules - //----------------------------------------------------------------------------- bool BuildRules( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector< WORDRULETYPE > *rules ) { @@ -330,7 +330,7 @@ bool BuildRules( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector< if ( numrules > 1 ) { - for ( int skip = 1; skip <= min( MAX_WORD_SKIP, numrules ); skip++ ) + for ( int skip = 1; skip <= MIN( MAX_WORD_SKIP, numrules ); skip++ ) { OutputDebugString( va( "Opt transition from Root to %s\r\n", (*rules)[ 0 ].plaintext ) ); @@ -340,7 +340,7 @@ bool BuildRules( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector< for ( int i = 1; i < numrules; i++ ) { // Start at the beginning? - rule = &(*rules)[ i ]; + rule = &(*rules)[ i ]; if ( i < numrules - skip ) { next = &(*rules)[ i + skip ]; @@ -369,8 +369,8 @@ bool BuildRules( ISpRecoGrammar* cpRecoGrammar, SPSTATEHANDLE *root, CUtlVector< //----------------------------------------------------------------------------- // Purpose: Debugging, prints alternate list if one is created -// Input : cpResult - -// (*pfnPrint - +// Input : cpResult - +// (*pfnPrint - //----------------------------------------------------------------------------- void PrintAlternates( ISpRecoResult* cpResult, void (*pfnPrint)( const char *fmt, ... ) ) { @@ -378,7 +378,7 @@ void PrintAlternates( ISpRecoResult* cpResult, void (*pfnPrint)( const char *fmt memset( rgPhraseAlt, 0, sizeof( rgPhraseAlt ) ); ULONG ulCount; - + ISpPhrase *phrase = ( ISpPhrase * )cpResult; if ( phrase ) { @@ -389,13 +389,13 @@ void PrintAlternates( ISpRecoResult* cpResult, void (*pfnPrint)( const char *fmt { HRESULT hr = cpResult->GetAlternates( pElements->Rule.ulFirstElement, - pElements->Rule.ulCountOfElements, + pElements->Rule.ulCountOfElements, 32, rgPhraseAlt, &ulCount); - + Assert( !FAILED( hr ) ); - + for ( ULONG r = 0 ; r < ulCount; r++ ) { CSpDynamicString dstrText; @@ -408,7 +408,7 @@ void PrintAlternates( ISpRecoResult* cpResult, void (*pfnPrint)( const char *fmt } } } - + } for ( int i = 0; i < 32; i++ ) @@ -434,7 +434,7 @@ void PrintWordsAndPhonemes( CSentence& sentence, void (*pfnPrint)( const char *f if ( !word ) continue; - sprintf( sz, "<%u - %u> %s\r\n", + sprintf( sz, "<%u - %u> %s\r\n", word->m_uiStartByte, word->m_uiEndByte, word->GetWord() ); pfnPrint( sz ); @@ -445,7 +445,7 @@ void PrintWordsAndPhonemes( CSentence& sentence, void (*pfnPrint)( const char *f if ( !phoneme ) continue; - sprintf( sz, " <%u - %u> %s\r\n", + sprintf( sz, " <%u - %u> %s\r\n", phoneme->m_uiStartByte, phoneme->m_uiEndByte, phoneme->GetTag() ); pfnPrint( sz ); @@ -458,10 +458,10 @@ void PrintWordsAndPhonemes( CSentence& sentence, void (*pfnPrint)( const char *f //----------------------------------------------------------------------------- // Purpose: Given a wave file and a string of words "text", creates a CFG from the // sentence and stores the resulting words/phonemes in CSentence -// Input : *wavname - -// text - -// sentence - -// (*pfnPrint - +// Input : *wavname - +// text - +// sentence - +// (*pfnPrint - // Output : SR_RESULT //----------------------------------------------------------------------------- SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentence& sentence, void (*pfnPrint)( const char *fmt, ...) ) @@ -477,7 +477,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc USES_CONVERSION; HRESULT hr; - + CUtlVector < WORDRULETYPE > wordRules; CComPtr cpInputStream; @@ -485,7 +485,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc CComPtr cpRecoContext; CComPtr cpRecoGrammar; CComPtr cpPhoneConv; - + // Create basic SAPI stream object // NOTE: The helper SpBindToFile can be used to perform the following operations hr = cpInputStream.CoCreateInstance(CLSID_SpStream); @@ -496,7 +496,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc } CSpStreamFormat sInputFormat; - + // setup stream object with wav file MY_WAVE_AUDIO_FILENAME // for read-only access, since it will only be access by the SR engine hr = cpInputStream->BindToFile( @@ -511,7 +511,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc pfnPrint( "Error: couldn't open wav file %s\n", wavname ); return result; } - + // Create in-process speech recognition engine hr = cpRecognizer.CoCreateInstance(CLSID_SpInprocRecognizer); if ( FAILED( hr ) ) @@ -527,7 +527,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc pfnPrint( "Error: SAPI 5.1 Unable to create recognizer context\n" ); return result; } - + // Create a grammar hr = cpRecoContext->CreateGrammar( EP_GRAM_ID, &cpRecoGrammar ); if ( FAILED( hr ) ) @@ -662,15 +662,15 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc } // check for recognitions and end of stream event - const ULONGLONG ullInterest = - SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM) | SPFEI(SPEI_FALSE_RECOGNITION) | + const ULONGLONG ullInterest = + SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM) | SPFEI(SPEI_FALSE_RECOGNITION) | SPFEI(SPEI_PHRASE_START ) | SPFEI(SPEI_HYPOTHESIS ) | SPFEI(SPEI_INTERFERENCE) ; hr = cpRecoContext->SetInterest( ullInterest, ullInterest ); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to set interest level\n" ); return result; - } + } // use Win32 events for command-line style application hr = cpRecoContext->SetNotifyWin32Event(); if ( FAILED( hr ) ) @@ -685,7 +685,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc { pfnPrint( "Error: SAPI 5.1 Unable to associate input stream\n" ); return result; - } + } // Activate the CFG ( rather than using dictation ) hr = cpRecoGrammar->SetRuleState( NULL, NULL, SPRS_ACTIVE ); @@ -723,7 +723,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc { CSpEvent spEvent; // pull all queued events from the reco context's event queue - + while (!fEndStreamReached && S_OK == spEvent.GetFrom(cpRecoContext)) { // Check event type @@ -797,7 +797,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc pfnPrint( va( "%s%s\r\n", spEvent.eEventId == SPEI_HYPOTHESIS ? "[ Hypothesis ] " : "", dstrText.CopyToChar() ) ); } - + cpResult.Release(); } break; @@ -806,12 +806,12 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc fEndStreamReached = TRUE; break; } - + // clear any event data/object references spEvent.Clear(); }// END event pulling loop - break on empty event queue OR end stream }// END event polling loop - break on event timeout OR end stream - + // Deactivate rule hr = cpRecoGrammar->SetRuleState( NULL, NULL, SPRS_INACTIVE ); if ( FAILED( hr ) ) @@ -835,7 +835,7 @@ SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentenc //----------------------------------------------------------------------------- // Purpose: HACK HACK: We have to delete the RecoContext key or sapi starts to train // itself on each iteration which was causing some problems. -// Input : hKey - +// Input : hKey - //----------------------------------------------------------------------------- void RecursiveRegDelKey(HKEY hKey) { @@ -855,7 +855,7 @@ void RecursiveRegDelKey(HKEY hKey) LONG lResult2; LONG lDelResult; lResult2=RegOpenKeyEx(hKey,keyname,0,KEY_ALL_ACCESS,&subkey); - + if (lResult2==ERROR_SUCCESS) { RecursiveRegDelKey(subkey); @@ -867,7 +867,7 @@ void RecursiveRegDelKey(HKEY hKey) lResult=RegEnumKeyEx(hKey,0,keyname,&namesize,NULL,NULL,NULL,NULL); } - else + else { break; } @@ -928,7 +928,7 @@ int FindFirstUsableWord( CSentence& outwords ) //----------------------------------------------------------------------------- // Purpose: Counts words which have either a valid start or end byte -// Input : *outwords - +// Input : *outwords - // Output : int //----------------------------------------------------------------------------- int CountUsableWords( CSentence& outwords ) @@ -954,7 +954,7 @@ int CountUsableWords( CSentence& outwords ) //----------------------------------------------------------------------------- // Purpose: Counts words which have either a valid start or end byte -// Input : *outwords - +// Input : *outwords - // Output : int //----------------------------------------------------------------------------- int CountUnuseableWords( CSentence& outwords ) @@ -991,7 +991,7 @@ void RepartitionPhonemes( CWordTag *word, unsigned int oldStart, unsigned int ol float frac1 = 0.0f, frac2 = 0.0f; float delta1, delta2; - + delta1 = ( float ) ( tag->m_uiStartByte - oldStart ); delta2 = ( float ) ( tag->m_uiEndByte - oldStart ); if ( oldRange > 0.0f ) @@ -1034,8 +1034,8 @@ void MergeWords( CWordTag *w1, CWordTag *w2 ) { unsigned int start, end; - start = min( w1->m_uiStartByte, w2->m_uiStartByte ); - end = max( w1->m_uiEndByte, w2->m_uiEndByte ); + start = MIN( w1->m_uiStartByte, w2->m_uiStartByte ); + end = MAX( w1->m_uiEndByte, w2->m_uiEndByte ); unsigned int mid = ( start + end ) / 2; @@ -1195,14 +1195,14 @@ void ComputeMissingByteSpans( int numsamples, CSentence& outwords ) } //----------------------------------------------------------------------------- -// Purpose: Given a wavfile and a list of inwords, determines the word/phonene +// Purpose: Given a wavfile and a list of inwords, determines the word/phonene // sample counts for the sentce -// Input : *wavfile - -// *inwords - -// *outphonemes{ text.Clear( - +// Input : *wavfile - +// *inwords - +// *outphonemes{ text.Clear( - // Output : SR_RESULT //----------------------------------------------------------------------------- -static SR_RESULT SAPI_ExtractPhonemes( +static SR_RESULT SAPI_ExtractPhonemes( const char *wavfile, int numsamples, void (*pfnPrint)( const char *fmt, ... ), @@ -1251,7 +1251,7 @@ static SR_RESULT SAPI_ExtractPhonemes( outwords.Reset(); outwords.SetText( inwords.GetText() ); - + Log( "Starting\n" ); LogWords( inwords ); @@ -1346,7 +1346,7 @@ static SR_RESULT SAPI_ExtractPhonemes( else { // Copy words from from source list into destination - // + // int skipCount = skipAhead - frompos; while ( --skipCount>= 0 ) @@ -1411,7 +1411,7 @@ class CPhonemeExtractorSAPI : public IPhonemeExtractor return "MS SAPI 5.1"; } - SR_RESULT Extract( + SR_RESULT Extract( const char *wavfile, int numsamples, void (*pfnPrint)( const char *fmt, ... ), @@ -1422,4 +1422,4 @@ class CPhonemeExtractorSAPI : public IPhonemeExtractor } }; -EXPOSE_SINGLE_INTERFACE( CPhonemeExtractorSAPI, IPhonemeExtractor, VPHONEME_EXTRACTOR_INTERFACE ); \ No newline at end of file +EXPOSE_SINGLE_INTERFACE( CPhonemeExtractorSAPI, IPhonemeExtractor, VPHONEME_EXTRACTOR_INTERFACE ); diff --git a/utils/phonemeextractor/phonemeextractor_ims.cpp b/utils/phonemeextractor/phonemeextractor_ims.cpp index 29dabab4..e93cee54 100644 --- a/utils/phonemeextractor/phonemeextractor_ims.cpp +++ b/utils/phonemeextractor/phonemeextractor_ims.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -42,7 +42,7 @@ class CPhonemeExtractorLipSinc : public IPhonemeExtractor return "IMS (LipSinc)"; } - SR_RESULT Extract( + SR_RESULT Extract( const char *wavfile, int numsamples, void (*pfnPrint)( const char *fmt, ... ), @@ -124,7 +124,7 @@ CPhonemeExtractorLipSinc::CPhonemeExtractorLipSinc( void ) m_pfnPrint = NULL; m_bInitialized = false; - + m_flSampleCount = 0.0f; m_flDuration = 0.0f; @@ -175,15 +175,15 @@ void CPhonemeExtractorLipSinc::DescribeError( TALKBACK_ERR err ) { talkback->TalkBackGetErrorString( err, sizeof(errorDesc), errorDesc ); } - + // Report or log the error... (*m_pfnPrint)( "LIPSINC ERROR: %s\n", errorDesc ); } //----------------------------------------------------------------------------- -// Purpose: -// Input : *fmt - -// .. - +// Purpose: +// Input : *fmt - +// .. - //----------------------------------------------------------------------------- void CPhonemeExtractorLipSinc::Printf( char const *fmt, ... ) { @@ -244,7 +244,7 @@ bool CPhonemeExtractorLipSinc::CheckSoundFile( char const *filename ) typedef IImsHelper *(*pfnImsHelper)(void); //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CPhonemeExtractorLipSinc::InitLipSinc( void ) @@ -259,7 +259,7 @@ bool CPhonemeExtractorLipSinc::InitLipSinc( void ) { return false; } - + pfnImsHelper factory = (pfnImsHelper)::GetProcAddress( m_hHelper, "GetImsHelper" ); if ( !factory ) { @@ -308,7 +308,7 @@ bool CPhonemeExtractorLipSinc::InitLipSinc( void ) } TALKBACK_ERR err; - + err = talkback->TalkBackStartupLibrary( coreDataDir ); if ( err != TALKBACK_NOERR ) { @@ -320,10 +320,10 @@ bool CPhonemeExtractorLipSinc::InitLipSinc( void ) long verMajor = 0; long verMinor = 0; long verRevision = 0; - + err = talkback->TalkBackGetVersion( - &verMajor, - &verMinor, + &verMajor, + &verMinor, &verRevision); if ( err != TALKBACK_NOERR ) { @@ -340,7 +340,7 @@ bool CPhonemeExtractorLipSinc::InitLipSinc( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CPhonemeExtractorLipSinc::ShutdownLipSinc( void ) { @@ -358,8 +358,8 @@ void CPhonemeExtractorLipSinc::ShutdownLipSinc( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : inwords - +// Purpose: +// Input : inwords - // Output : char const //----------------------------------------------------------------------------- char const *CPhonemeExtractorLipSinc::ConstructInputSentence( CSentence& inwords ) @@ -381,7 +381,7 @@ char const *CPhonemeExtractorLipSinc::ConstructInputSentence( CSentence& inwords } } - if ( inwords.m_Words.Count() == 1 && + if ( inwords.m_Words.Count() == 1 && !Q_strnicmp( inwords.GetText(), TEXTLESS_WORDNAME, Q_strlen( TEXTLESS_WORDNAME ) ) ) { sentence[ 0 ] = 0; @@ -400,7 +400,7 @@ bool CPhonemeExtractorLipSinc::AttemptAnalysis( TALKBACK_ANALYSIS **ppAnalysis, // Set this field to sizeof(TALKBACK_ANALYSIS_SETTINGS) before using the // structure. settings.fSize = sizeof( TALKBACK_ANALYSIS_SETTINGS ); - + // Default value: 30 (frames per second). settings.fFrameRate = 100; @@ -425,7 +425,7 @@ bool CPhonemeExtractorLipSinc::AttemptAnalysis( TALKBACK_ANALYSIS **ppAnalysis, Printf( "Analyzing: \"%s\"\n", text[ 0 ] ? text : TEXTLESS_WORDNAME ); - TALKBACK_ERR err = talkback->TalkBackGetAnalysis( + TALKBACK_ERR err = talkback->TalkBackGetAnalysis( ppAnalysis, wavfile, text, @@ -506,10 +506,10 @@ char const *TBPhonemeToString( TALKBACK_PHONEME phoneme ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *analysis - -// time - -// start - +// Purpose: +// Input : *analysis - +// time - +// start - // Output : int //----------------------------------------------------------------------------- int CPhonemeExtractorLipSinc::GetPhonemeIndexAtWord( TALKBACK_ANALYSIS *analysis, double time, bool start ) @@ -567,9 +567,9 @@ int CPhonemeExtractorLipSinc::GetPhonemeIndexAtWord( TALKBACK_ANALYSIS *analysis } //----------------------------------------------------------------------------- -// Purpose: -// Input : *analysis - -// starttime - +// Purpose: +// Input : *analysis - +// starttime - // Output : int //----------------------------------------------------------------------------- int CPhonemeExtractorLipSinc::GetPhonemeIndexAtWordStart( TALKBACK_ANALYSIS *analysis, double starttime ) @@ -578,9 +578,9 @@ int CPhonemeExtractorLipSinc::GetPhonemeIndexAtWordStart( TALKBACK_ANALYSIS *ana } //----------------------------------------------------------------------------- -// Purpose: -// Input : *analysis - -// endtime - +// Purpose: +// Input : *analysis - +// endtime - // Output : int //----------------------------------------------------------------------------- int CPhonemeExtractorLipSinc::GetPhonemeIndexAtWordEnd( TALKBACK_ANALYSIS *analysis, double endtime ) @@ -653,9 +653,9 @@ CPhonemeExtractorLipSinc::CAnalyzedWord *CPhonemeExtractorLipSinc::GetAnalyzedWo } //----------------------------------------------------------------------------- -// Purpose: -// Input : *w1 - -// *w2 - +// Purpose: +// Input : *w1 - +// *w2 - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool FuzzyWordMatch( char const *w1, char const *w2 ) @@ -663,7 +663,7 @@ bool FuzzyWordMatch( char const *w1, char const *w2 ) int len1 = strlen( w1 ); int len2 = strlen( w2 ); - int minlen = min( len1, len2 ); + int minlen = MIN( len1, len2 ); // Found a match if ( !strnicmp( w1, w2, minlen ) ) @@ -748,8 +748,8 @@ bool FuzzyWordMatch( char const *w1, char const *w2 ) //----------------------------------------------------------------------------- // Purpose: For foreign language stuff, if inwords is empty, process anyway... -// Input : *analysis - -// outwords - +// Input : *analysis - +// outwords - //----------------------------------------------------------------------------- void CPhonemeExtractorLipSinc::ProcessWordsTextless( TALKBACK_ANALYSIS *analysis, CSentence& outwords ) { @@ -813,10 +813,10 @@ void CPhonemeExtractorLipSinc::ProcessWordsTextless( TALKBACK_ANALYSIS *analysis } //----------------------------------------------------------------------------- -// Purpose: -// Input : *analysis - -// inwords - -// outwords - +// Purpose: +// Input : *analysis - +// inwords - +// outwords - //----------------------------------------------------------------------------- void CPhonemeExtractorLipSinc::ProcessWords( TALKBACK_ANALYSIS *analysis, CSentence& inwords, CSentence& outwords ) { @@ -831,7 +831,7 @@ void CPhonemeExtractorLipSinc::ProcessWords( TALKBACK_ANALYSIS *analysis, CSente if ( count <= 0L ) { - if ( inwords.m_Words.Count() == 0 || + if ( inwords.m_Words.Count() == 0 || !Q_strnicmp( inwords.GetText(), TEXTLESS_WORDNAME, Q_strlen( TEXTLESS_WORDNAME ) ) ) { ProcessWordsTextless( analysis, outwords ); @@ -1018,11 +1018,11 @@ char const *CPhonemeExtractorLipSinc::ApplyTBWordRules( char const *word ) } //----------------------------------------------------------------------------- -// Purpose: Given a wavfile and a list of inwords, determines the word/phonene +// Purpose: Given a wavfile and a list of inwords, determines the word/phonene // sample counts for the sentce // Output : SR_RESULT //----------------------------------------------------------------------------- -SR_RESULT CPhonemeExtractorLipSinc::Extract( +SR_RESULT CPhonemeExtractorLipSinc::Extract( const char *wavfile, int numsamples, void (*pfnPrint)( const char *fmt, ... ), @@ -1037,7 +1037,7 @@ SR_RESULT CPhonemeExtractorLipSinc::Extract( { return SR_RESULT_ERROR; } - + m_flSampleCount = numsamples; if ( !CheckSoundFile( wavfile ) ) @@ -1053,7 +1053,7 @@ SR_RESULT CPhonemeExtractorLipSinc::Extract( FreeLibrary( m_hHelper ); return SR_RESULT_FAILED; } - + if ( strlen( inwords.GetText() ) <= 0 ) { inwords.SetTextFromWords(); @@ -1072,4 +1072,4 @@ SR_RESULT CPhonemeExtractorLipSinc::Extract( return SR_RESULT_SUCCESS; } -EXPOSE_SINGLE_INTERFACE( CPhonemeExtractorLipSinc, IPhonemeExtractor, VPHONEME_EXTRACTOR_INTERFACE ); \ No newline at end of file +EXPOSE_SINGLE_INTERFACE( CPhonemeExtractorLipSinc, IPhonemeExtractor, VPHONEME_EXTRACTOR_INTERFACE ); diff --git a/utils/smdlexp/smdlexp.mak b/utils/smdlexp/smdlexp.mak new file mode 100644 index 00000000..07a171b5 --- /dev/null +++ b/utils/smdlexp/smdlexp.mak @@ -0,0 +1,325 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +!IF "$(CFG)" == "" +CFG=smdlexp - Win32 Debug +!MESSAGE No configuration specified. Defaulting to smdlexp - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "smdlexp - Win32 Release" && "$(CFG)" !=\ + "smdlexp - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "smdlexp.mak" CFG="smdlexp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "smdlexp - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "smdlexp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "smdlexp - Win32 Debug" +RSC=rc.exe +MTL=mktyplib.exe +CPP=cl.exe + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" + +CLEAN : + -@erase "$(INTDIR)\smdlexp.obj" + -@erase "$(INTDIR)\smdlexp.res" + -@erase "$(OUTDIR)\SMDLEXP.exp" + -@erase "$(OUTDIR)\SMDLEXP.lib" + -@erase "..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "\3DSMAX2.5\MAXSDK\INCLUDE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "\3DSMAX2.5\MAXSDK\INCLUDE" /D "WIN32" /D\ + "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)/smdlexp.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/smdlexp.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/smdlexp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib COMCTL32.LIB /nologo /subsystem:windows /dll /machine:I386 /out:"\3DSMAX\STDPLUGS\SMDLEXP.DLE" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib COMCTL32.LIB /nologo\ + /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)/SMDLEXP.pdb"\ + /machine:I386 /def:".\smdlexp.def" /out:"\3DSMAX\STDPLUGS\SMDLEXP.DLE"\ + /implib:"$(OUTDIR)/SMDLEXP.lib" +DEF_FILE= \ + ".\smdlexp.def" +LINK32_OBJS= \ + "$(INTDIR)\smdlexp.obj" \ + "$(INTDIR)\smdlexp.res" \ + "..\..\..\quiver\src\utils\3dsmax\CORE.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\GEOM.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\MESH.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\UTIL.LIB" + +"..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" "$(OUTDIR)\smdlexp.bsc" + +CLEAN : + -@erase "$(INTDIR)\smdlexp.obj" + -@erase "$(INTDIR)\smdlexp.res" + -@erase "$(INTDIR)\smdlexp.sbr" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\smdlexp.bsc" + -@erase "$(OUTDIR)\SMDLEXP.exp" + -@erase "$(OUTDIR)\SMDLEXP.lib" + -@erase "$(OUTDIR)\SMDLEXP.pdb" + -@erase "..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" + -@erase "..\..\..\3DSMAX\STDPLUGS\SMDLEXP.ILK" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MD /W3 /Gm /GX /Zi /Od /I "\3DSMAX2.5\MAXSDK\INCLUDE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +CPP_PROJ=/nologo /MD /W3 /Gm /GX /Zi /Od /I "\3DSMAX2.5\MAXSDK\INCLUDE" /D\ + "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/smdlexp.pch"\ + /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\Debug/ +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/smdlexp.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/smdlexp.bsc" +BSC32_SBRS= \ + "$(INTDIR)\smdlexp.sbr" + +"$(OUTDIR)\smdlexp.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib COMCTL32.LIB /nologo /subsystem:windows /dll /debug /machine:I386 /out:"\3DSMAX\STDPLUGS\SMDLEXP.DLE" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib COMCTL32.LIB /nologo\ + /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)/SMDLEXP.pdb" /debug\ + /machine:I386 /def:".\smdlexp.def" /out:"\3DSMAX\STDPLUGS\SMDLEXP.DLE"\ + /implib:"$(OUTDIR)/SMDLEXP.lib" +DEF_FILE= \ + ".\smdlexp.def" +LINK32_OBJS= \ + "$(INTDIR)\smdlexp.obj" \ + "$(INTDIR)\smdlexp.res" \ + "..\..\..\quiver\src\utils\3dsmax\CORE.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\GEOM.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\MESH.LIB" \ + "..\..\..\quiver\src\utils\3dsmax\UTIL.LIB" + +"..\..\..\3DSMAX\STDPLUGS\SMDLEXP.DLE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "smdlexp - Win32 Release" +# Name "smdlexp - Win32 Debug" + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\smdlexp.cpp +DEP_CPP_SMDLE=\ + ".\smedefs.h"\ + +NODEP_CPP_SMDLE=\ + ".\ANIMTBL.H"\ + ".\DECOMP.H"\ + ".\istdplug.h"\ + ".\MAX.H"\ + ".\STDMAT.H"\ + + +!IF "$(CFG)" == "smdlexp - Win32 Release" + + +"$(INTDIR)\smdlexp.obj" : $(SOURCE) $(DEP_CPP_SMDLE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + + +"$(INTDIR)\smdlexp.obj" : $(SOURCE) $(DEP_CPP_SMDLE) "$(INTDIR)" + +"$(INTDIR)\smdlexp.sbr" : $(SOURCE) $(DEP_CPP_SMDLE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\smdlexp.def + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\smdlexp.rc + +"$(INTDIR)\smdlexp.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quiver\src\utils\3dsmax\UTIL.LIB + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quiver\src\utils\3dsmax\GEOM.LIB + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quiver\src\utils\3dsmax\MESH.LIB + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quiver\src\utils\3dsmax\CORE.LIB + +!IF "$(CFG)" == "smdlexp - Win32 Release" + +!ELSEIF "$(CFG)" == "smdlexp - Win32 Debug" + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/utils/smdlexp/smdlexp.vcproj b/utils/smdlexp/smdlexp.vcproj new file mode 100644 index 00000000..fce2bc77 --- /dev/null +++ b/utils/smdlexp/smdlexp.vcproj @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/utils/vbsp/csg.cpp b/utils/vbsp/csg.cpp index 5de1d680..a8c39afb 100644 --- a/utils/vbsp/csg.cpp +++ b/utils/vbsp/csg.cpp @@ -594,6 +594,13 @@ void PrintBrushContentsToString( int contents, char *pOut, int nMaxChars ) ADD_CONTENTS(CONTENTS_BLOCKLOS) ADD_CONTENTS(CONTENTS_OPAQUE) ADD_CONTENTS(CONTENTS_TESTFOGVOLUME) +#ifdef MAPBASE + ADD_CONTENTS(CONTENTS_UNUSED) + ADD_CONTENTS(CONTENTS_UNUSED6) + ADD_CONTENTS(CONTENTS_TEAM1) + ADD_CONTENTS(CONTENTS_TEAM2) + ADD_CONTENTS(CONTENTS_IGNORE_NODRAW_OPAQUE) +#endif ADD_CONTENTS(CONTENTS_MOVEABLE) ADD_CONTENTS(CONTENTS_AREAPORTAL) ADD_CONTENTS(CONTENTS_PLAYERCLIP) diff --git a/utils/vbsp/cubemap.cpp b/utils/vbsp/cubemap.cpp index 3c2fe1ea..091253ec 100644 --- a/utils/vbsp/cubemap.cpp +++ b/utils/vbsp/cubemap.cpp @@ -77,33 +77,27 @@ struct CubemapSideData_t static CubemapSideData_t s_aCubemapSideData[MAX_MAP_BRUSHSIDES]; -struct cubemapCorrectionData_t -{ - Vector origin; - float radius = -1; // -1 = No cubemap correction -}; -static cubemapCorrectionData_t s_CubemapCorrected[MAX_MAP_CUBEMAPSAMPLES]; inline bool SideHasCubemapAndWasntManuallyReferenced( int iSide ) { return s_aCubemapSideData[iSide].bHasEnvMapInMaterial && !s_aCubemapSideData[iSide].bManuallyPickedByAnEnvCubemap; } - -void Cubemap_InsertSample( const Vector& origin, int size, float radius ) +#ifdef PARALLAX_CORRECTED_CUBEMAPS +char* g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES]; +void Cubemap_InsertSample( const Vector& origin, int size, char* pParallaxObbStr = "" ) { + g_pParallaxObbStrs[g_nCubemapSamples] = pParallaxObbStr; +#else +void Cubemap_InsertSample( const Vector& origin, int size ) +{ +#endif dcubemapsample_t *pSample = &g_CubemapSamples[g_nCubemapSamples]; pSample->origin[0] = ( int )origin[0]; pSample->origin[1] = ( int )origin[1]; pSample->origin[2] = ( int )origin[2]; pSample->size = size; - cubemapCorrectionData_t* pCorrrectionData = &s_CubemapCorrected[g_nCubemapSamples]; - pCorrrectionData->origin = origin; - pCorrrectionData->radius = radius; - - Msg("Filling Parallax corrected cubemap info: id%d [%d %d %d] %d\n", g_nCubemapSamples, (int)pCorrrectionData->origin[0], (int)pCorrrectionData->origin[1], (int)pCorrrectionData->origin[2], (int)pCorrrectionData->radius); - g_nCubemapSamples++; } @@ -289,7 +283,15 @@ void VTFNameToHDRVTFName( const char *pSrcName, char *pDest, int maxLen, bool bH Q_strncpy( pDot, ".hdr.vtf", maxLen - ( pDot - pDest ) ); } -#define DEFAULT_CUBEMAP_SIZE g_SkyboxCubemapRes +#ifdef MAPBASE + +extern bool g_bSkyboxCubemaps; +extern int g_iDefaultCubemapSize; +#define DEFAULT_CUBEMAP_SIZE g_iDefaultCubemapSize + +#else +#define DEFAULT_CUBEMAP_SIZE 32 +#endif void CreateDefaultCubemaps( bool bHDR ) { @@ -314,7 +316,7 @@ void CreateDefaultCubemaps( bool bHDR ) IVTFTexture *pSrcVTFTextures[6]; int unionTextureFlags = 0; - if( !LoadSrcVTFFiles( pSrcVTFTextures, skyboxMaterialName, &unionTextureFlags,/*bHDR*/ false ) ) + if( !LoadSrcVTFFiles( pSrcVTFTextures, skyboxMaterialName, &unionTextureFlags, bHDR ) ) { Warning( "Can't load skybox file %s to build the default cubemap!\n", skyboxMaterialName ); return; @@ -352,12 +354,18 @@ void CreateDefaultCubemaps( bool bHDR ) int iSize = pDstCubemap->ComputeMipSize( iMip ); int iSrcMipSize = pSrcVTFTextures[iFace]->ComputeMipSize( iMip + iMipLevelOffset ); - if (!g_SkyboxCubemap) +#ifdef MAPBASE + if (!g_bSkyboxCubemaps) { - // !!! FIXME: Set this to black until HDR cubemaps are built properly! memset( pDstBits, 0, iSize ); continue; } +#else + // !!! FIXME: Set this to black until HDR cubemaps are built properly! + memset( pDstBits, 0, iSize ); + continue; +#endif + if ( ( pSrcVTFTextures[iFace]->Width() == 4 ) && ( pSrcVTFTextures[iFace]->Height() == 4 ) ) // If texture is 4x4 square { // Force mip level 2 to get the 1x1 face @@ -429,7 +437,7 @@ void CreateDefaultCubemaps( bool bHDR ) if( !bHDR ) { // Convert the cube to format that we can apply tools to it... - pDstCubemap->ConvertImageFormat(IMAGE_FORMAT_DEFAULT, false ); + pDstCubemap->ConvertImageFormat( IMAGE_FORMAT_DEFAULT, false ); } // Fixup the cubemap facing @@ -444,11 +452,13 @@ void CreateDefaultCubemaps( bool bHDR ) pDstCubemap->ConvertImageFormat( originalFormat, false ); } - // FIXME: uncomment these lines if you want to match the seams on cubemap - // Convert the cube to format that we can apply tools to it... - //pDstCubemap->ConvertImageFormat(IMAGE_FORMAT_RGBA8888, false); - //pDstCubemap->MatchCubeMapBorders(1, IMAGE_FORMAT_RGBA8888, false); - //pDstCubemap->MatchCubeMapBorders(2, originalFormat, false); +#ifdef MAPBASE + // Apply a seam fix + pDstCubemap->ConvertImageFormat( IMAGE_FORMAT_RGBA8888, false ); + + pDstCubemap->MatchCubeMapBorders( 1, IMAGE_FORMAT_RGBA8888, false ); + pDstCubemap->MatchCubeMapBorders( 2, originalFormat, false ); +#endif // Write the puppy out! char dstVTFFileName[1024]; @@ -468,13 +478,6 @@ void CreateDefaultCubemaps( bool bHDR ) return; } - if (g_SkyboxCubemapDump) - { - FileHandle_t outFile = g_pFileSystem->Open(dstVTFFileName, "w"); - g_pFileSystem->Write(outputBuf.Base(), outputBuf.TellPut(), outFile); - g_pFileSystem->Close(outFile); - } - IZip *pak = GetPakFile(); // spit out the default one. @@ -556,7 +559,11 @@ static void GeneratePatchedName( const char *pMaterialName, const PatchInfo_t &i //----------------------------------------------------------------------------- // Patches the $envmap for a material and all its dependents, returns true if any patching happened //----------------------------------------------------------------------------- -static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture, float radius ) +#ifdef PARALLAX_CORRECTED_CUBEMAPS +static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture, const char *pParallaxObbMatrix = "" ) +#else +static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture ) +#endif { // Do *NOT* patch the material if there is an $envmap specified and it's not 'env_cubemap' @@ -574,7 +581,11 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons const char *pDependentMaterial = FindDependentMaterial( pMaterialName, &pDependentMaterialVar ); if ( pDependentMaterial ) { - bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture, radius ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture, pParallaxObbMatrix ); +#else + bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture ); +#endif } // If we have neither to patch, we're done @@ -585,31 +596,46 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons char pPatchedMaterialName[1024]; GeneratePatchedName( pMaterialName, info, true, pPatchedMaterialName, 1024 ); - MaterialPatchInfo_t pPatchInfo[4]; +#ifdef PARALLAX_CORRECTED_CUBEMAPS + MaterialPatchInfo_t pPatchInfo[7]; +#else + MaterialPatchInfo_t pPatchInfo[2]; +#endif int nPatchCount = 0; if ( bShouldPatchEnvCubemap ) { - char originAppendedString[1024] = ""; - char radiusppendedString[256] = ""; - pPatchInfo[nPatchCount].m_pKey = "$envmap"; pPatchInfo[nPatchCount].m_pRequiredOriginalValue = "env_cubemap"; pPatchInfo[nPatchCount].m_pValue = pCubemapTexture; - Msg("$envmap: %s\n", pCubemapTexture); + ++nPatchCount; + } + +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Parallax cubemap matrix + CUtlVector matRowList; + if (pParallaxObbMatrix[0] != '\0') + { + V_SplitString( pParallaxObbMatrix, ";", matRowList ); + + // Needed for editor + pPatchInfo[nPatchCount].m_pKey = "$envMapParallax"; + pPatchInfo[nPatchCount].m_pValue = "1"; ++nPatchCount; - Q_snprintf(originAppendedString, 1024, "[%d %d %d]", info.m_pOrigin[0], info.m_pOrigin[1], info.m_pOrigin[2]); - pPatchInfo[nPatchCount].m_pKey = "$envmaporigin"; - pPatchInfo[nPatchCount].m_pValue = originAppendedString; - Msg("$envmaporigin: %s\n", originAppendedString); - nPatchCount++; - - Q_snprintf(radiusppendedString, 256, "%d", (int)radius); - pPatchInfo[nPatchCount].m_pKey = "$envmapradius"; - pPatchInfo[nPatchCount].m_pValue = radiusppendedString; - Msg("$envmapradius: %s\n", radiusppendedString); - nPatchCount++; + pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB1"; + pPatchInfo[nPatchCount].m_pValue = matRowList[0]; + ++nPatchCount; + pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB2"; + pPatchInfo[nPatchCount].m_pValue = matRowList[1]; + ++nPatchCount; + pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB3"; + pPatchInfo[nPatchCount].m_pValue = matRowList[2]; + ++nPatchCount; + pPatchInfo[nPatchCount].m_pKey = "$envMapOrigin"; + pPatchInfo[nPatchCount].m_pValue = matRowList[3]; + ++nPatchCount; } +#endif char pDependentPatchedMaterialName[1024]; if ( bDependentMaterialPatched ) @@ -622,7 +648,14 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons ++nPatchCount; } - CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_INSERT); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_INSERT ); + + // Clean up parallax stuff + matRowList.PurgeAndDeleteElements(); +#else + CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_REPLACE ); +#endif return true; } @@ -641,7 +674,11 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons // default (skybox) cubemap into this file so the cubemap doesn't have the pink checkerboard at // runtime before they run buildcubemaps. //----------------------------------------------------------------------------- -static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], float radius ) +#ifdef PARALLAX_CORRECTED_CUBEMAPS +static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], int cubemapIndex ) +#else +static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] ) +#endif { // Don't make cubemap tex infos for nodes if ( originalTexInfo == TEXINFO_NODE ) @@ -673,6 +710,15 @@ static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], float radi char pGeneratedTexDataName[1024]; GeneratePatchedName( pMaterialName, info, true, pGeneratedTexDataName, 1024 ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Append origin info if this cubemap has a parallax OBB + char originAppendedString[1024] = ""; + if (g_pParallaxObbStrs[cubemapIndex] && g_pParallaxObbStrs[cubemapIndex][0] != '\0') + { + Q_snprintf(originAppendedString, 1024, "%s;[%d %d %d]", g_pParallaxObbStrs[cubemapIndex], origin[0], origin[1], origin[2]); + } +#endif + // Make sure the texdata doesn't already exist. int nTexDataID = FindTexData( pGeneratedTexDataName ); bool bHasTexData = (nTexDataID != -1); @@ -684,7 +730,11 @@ static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], float radi // Hook the texture into the material and all dependent materials // but if no hooking was necessary, exit out - if ( !PatchEnvmapForMaterialAndDependents(pMaterialName, info, pTextureName, radius) ) +#ifdef PARALLAX_CORRECTED_CUBEMAPS + if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName, originAppendedString ) ) +#else + if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName ) ) +#endif return originalTexInfo; // Store off the name of the cubemap that we need to create since we successfully patched @@ -774,7 +824,11 @@ void Cubemap_FixupBrushSidesMaterials( void ) } #endif - pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin, s_CubemapCorrected[cubemapID].radius); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin, cubemapID ); +#else + pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin ); +#endif if ( pSide->pMapDisp ) { pSide->pMapDisp->face.texinfo = pSide->texinfo; @@ -990,7 +1044,11 @@ void Cubemap_AttachDefaultCubemapToSpecularSides( void ) Assert( pSide->texinfo == pSide->pMapDisp->face.texinfo ); } #endif - pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin, s_CubemapCorrected[iCubemap].radius); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin, iCubemap ); +#else + pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin ); +#endif if ( pSide->pMapDisp ) { pSide->pMapDisp->face.texinfo = pSide->texinfo; diff --git a/utils/vbsp/detail.cpp b/utils/vbsp/detail.cpp index 840068de..b17917bc 100644 --- a/utils/vbsp/detail.cpp +++ b/utils/vbsp/detail.cpp @@ -440,6 +440,9 @@ face_t *MakeBrushFace( side_t *originalSide, winding_t *winding ) f->split[0] = f->split[1] = NULL; f->w = CopyWinding( winding ); f->originalface = originalSide; +#ifdef MAPBASE + f->smoothingGroups = originalSide->smoothingGroups; +#endif // // save material info // diff --git a/utils/vbsp/disp_ivp.cpp b/utils/vbsp/disp_ivp.cpp index 1ed16518..d96a7e95 100644 --- a/utils/vbsp/disp_ivp.cpp +++ b/utils/vbsp/disp_ivp.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// #include "vbsp.h" @@ -102,7 +102,7 @@ void Disp_AddCollisionModels( CUtlVector &collisionList, int dispIndex; // Add each displacement to the grid hash - for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ ) + for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ ) { CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ]; mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ]; @@ -150,7 +150,7 @@ void Disp_AddCollisionModels( CUtlVector &collisionList, CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false ); if ( pCollide ) { - collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); + collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); } // Throw this polysoup away and start over for the remaining triangles physcollision->PolysoupDestroy( pTerrainPhysics ); @@ -185,7 +185,7 @@ void Disp_AddCollisionModels( CUtlVector &collisionList, CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false ); if ( pCollide ) { - collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); + collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); } // now that we have the collide, we're done with the soup physcollision->PolysoupDestroy( pTerrainPhysics ); @@ -240,7 +240,7 @@ void CDispMeshEvent::GetVirtualMesh( void *userData, virtualmeshlist_t *pList ) pList->surfacePropsIndex = 0; // doesn't matter here, reset at runtime pList->pHull = NULL; int indexMax = ARRAYSIZE(pList->indices); - int indexCount = min(m_indexCount, indexMax); + int indexCount = MIN(m_indexCount, indexMax); Assert(m_indexCount < indexMax); Q_memcpy( pList->indices, m_pIndices, sizeof(*m_pIndices) * indexCount ); } @@ -260,7 +260,7 @@ void CDispMeshEvent::GetTrianglesInSphere( void *userData, const Vector ¢er, Assert(userData==((void *)this)); pList->triangleCount = m_indexCount/3; int indexMax = ARRAYSIZE(pList->triangleIndices); - int indexCount = min(m_indexCount, indexMax); + int indexCount = MIN(m_indexCount, indexMax); Assert(m_indexCount < MAX_VIRTUAL_TRIANGLES*3); Q_memcpy( pList->triangleIndices, m_pIndices, sizeof(*m_pIndices) * indexCount ); } @@ -269,7 +269,7 @@ void Disp_BuildVirtualMesh( int contentsMask ) { CUtlVector virtualMeshes; virtualMeshes.EnsureCount( g_CoreDispInfos.Count() ); - for ( int i = 0; i < g_CoreDispInfos.Count(); i++ ) + for ( int i = 0; i < g_CoreDispInfos.Count(); i++ ) { CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ]; mapdispinfo_t *pMapDisp = &mapdispinfo[ i ]; diff --git a/utils/vbsp/ivp.cpp b/utils/vbsp/ivp.cpp index 3c234c2f..dafd2c6b 100644 --- a/utils/vbsp/ivp.cpp +++ b/utils/vbsp/ivp.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -64,7 +64,7 @@ void CTextBuffer::WriteText( const char *pText ) void CTextBuffer::WriteIntKey( const char *pKeyName, int outputData ) { char tmp[1024]; - + // FAIL! if ( strlen(pKeyName) > 1000 ) { @@ -86,7 +86,7 @@ void CTextBuffer::WriteStringKey( const char *pKeyName, const char *outputData ) void CTextBuffer::WriteFloatKey( const char *pKeyName, float outputData ) { char tmp[1024]; - + // FAIL! if ( strlen(pKeyName) > 1000 ) { @@ -100,7 +100,7 @@ void CTextBuffer::WriteFloatKey( const char *pKeyName, float outputData ) void CTextBuffer::WriteFloatArrayKey( const char *pKeyName, const float *outputData, int count ) { char tmp[1024]; - + // FAIL! if ( strlen(pKeyName) > 1000 ) { @@ -141,8 +141,8 @@ void CTextBuffer::CopyData( const char *pData, int len ) //----------------------------------------------------------------------------- // Purpose: Writes a glview text file containing the collision surface in question -// Input : *pCollide - -// *pFilename - +// Input : *pCollide - +// *pFilename - //----------------------------------------------------------------------------- void DumpCollideToGlView( CPhysCollide *pCollide, const char *pFilename ) { @@ -197,13 +197,13 @@ CPhysCollisionEntry::CPhysCollisionEntry( CPhysCollide *pCollide ) m_pCollide = pCollide; } -unsigned int CPhysCollisionEntry::GetCollisionBinarySize() -{ - return physcollision->CollideSize( m_pCollide ); +unsigned int CPhysCollisionEntry::GetCollisionBinarySize() +{ + return physcollision->CollideSize( m_pCollide ); } -unsigned int CPhysCollisionEntry::WriteCollisionBinary( char *pDest ) -{ +unsigned int CPhysCollisionEntry::WriteCollisionBinary( char *pDest ) +{ return physcollision->CollideWrite( pDest, m_pCollide ); } @@ -583,7 +583,7 @@ int CPlaneList::GetFirstBrushSide() return 0; } -// UNDONE: Try using this kind of algorithm if we run into precision problems. +// UNDONE: Try using this kind of algorithm if we run into precision problems. // NOTE: ConvexFromPlanes will be doing a bunch of matrix inversions that can suffer // if plane normals are too close to each other... #if 0 @@ -728,7 +728,7 @@ static bool IsLowerLeaf( const waterleaf_t &newleaf, const waterleaf_t ¤tl } //----------------------------------------------------------------------------- -// Purpose: Water surfaces are stored in an RB tree and the tree is used to +// Purpose: Water surfaces are stored in an RB tree and the tree is used to // create one-off .vmt files embedded in the .bsp for each surface so that the // water depth effect occurs on a per-water surface level. //----------------------------------------------------------------------------- @@ -753,8 +753,8 @@ struct WaterTexInfo //----------------------------------------------------------------------------- // Purpose: Helper for RB tree operations ( we compare full mangled names ) -// Input : src1 - -// src2 - +// Input : src1 - +// src2 - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool WaterLessFunc( WaterTexInfo const& src1, WaterTexInfo const& src2 ) @@ -776,11 +776,11 @@ float GetSubdivSizeForFogVolume( int fogVolumeID ) #endif //----------------------------------------------------------------------------- -// Purpose: -// Input : *mapname - -// *materialname - -// waterdepth - -// *fullname - +// Purpose: +// Input : *mapname - +// *materialname - +// waterdepth - +// *fullname - //----------------------------------------------------------------------------- void GetWaterTextureName( char const *mapname, char const *materialname, int waterdepth, char *fullname ) { @@ -808,7 +808,7 @@ void EmitWaterMaterialFile( WaterTexInfo *wti ) } GetWaterTextureName( mapbase, wti->m_MaterialName.String(), ( int )wti->m_nWaterDepth, waterTextureName ); - + // Convert to string char szDepth[ 32 ]; sprintf( szDepth, "%i", wti->m_nWaterDepth ); @@ -818,8 +818,8 @@ void EmitWaterMaterialFile( WaterTexInfo *wti ) //----------------------------------------------------------------------------- // Purpose: Takes the texinfo_t referenced by the .vmt and the computed depth for the // surface and looks up or creates a texdata/texinfo for the mangled one-off water .vmt file -// Input : *pBaseInfo - -// depth - +// Input : *pBaseInfo - +// depth - // Output : int //----------------------------------------------------------------------------- int FindOrCreateWaterTexInfo( texinfo_t *pBaseInfo, float depth ) @@ -875,7 +875,7 @@ extern node_t *dfacenodes[MAX_MAP_FACES]; static void WriteFogVolumeIDs( dmodel_t *pModel ) { int i; - + // write fog volume ID to each face in this model for( i = pModel->firstface; i < pModel->firstface + pModel->numfaces; i++ ) { @@ -889,7 +889,7 @@ static void WriteFogVolumeIDs( dmodel_t *pModel ) { pFace->surfaceFogVolumeID = dleafs[pFaceNode->diskId].leafWaterDataID; dleafwaterdata_t *pLeafWaterData = &dleafwaterdata[pFace->surfaceFogVolumeID]; - + // HACKHACK: Should probably mark these faces as water bottom or "bottommaterial" faces. // HACKHACK: Use a heuristic, if it points up, it's the water top. if ( dplanes[pFace->planenum].normal.z > 0 ) @@ -1000,7 +1000,7 @@ static void BuildWaterLeaf( node_t *pLeafIn, waterleaf_t &waterLeafOut ) if ( (waterLeafOut.surfaceNormal.z == plane->normal.z) && waterLeafOut.surfaceDist >= plane->dist ) continue; } - // water surface needs to point at least somewhat up, this is + // water surface needs to point at least somewhat up, this is // probably a map error if ( plane->normal.z <= 0 ) continue; @@ -1054,7 +1054,7 @@ static void Flood_FindConnectedWaterVolumes_r( CUtlVector &list, node_ visited.Set( pLeaf->diskId ); list.AddToTail( pLeaf ); - baseleaf.minZ = min( pLeaf->mins.z, baseleaf.minZ ); + baseleaf.minZ = MIN( pLeaf->mins.z, baseleaf.minZ ); for (portal_t *p = pLeaf->portals ; p ; p = p->next[!oppositeNodeIndex]) { @@ -1087,7 +1087,7 @@ int FirstWaterTexinfo( bspbrush_t *brushlist, int contents ) return 0; } -// This is a list of water data that will be turned into physics models +// This is a list of water data that will be turned into physics models struct watermodel_t { int modelIndex; @@ -1111,7 +1111,7 @@ void EmitWaterVolumesForBSP( dmodel_t *pModel, node_t *node ) // make a sorted list to flood fill CUtlVector list; - + int i; for ( i = 0; i < leafListAnyWater.Count(); i++ ) { @@ -1138,7 +1138,7 @@ void EmitWaterVolumesForBSP( dmodel_t *pModel, node_t *node ) tmp.waterLeafData = list[i]; tmp.firstWaterLeafIndex = g_WaterLeafList.Count(); tmp.waterLeafCount = waterAreaList.Count(); - + float waterDepth = tmp.waterLeafData.surfaceDist - tmp.waterLeafData.minZ; if ( tmp.waterLeafData.surfaceTexInfo < 0 ) { @@ -1162,7 +1162,7 @@ void EmitWaterVolumesForBSP( dmodel_t *pModel, node_t *node ) } -static void ConvertWaterModelToPhysCollide( CUtlVector &collisionList, int modelIndex, +static void ConvertWaterModelToPhysCollide( CUtlVector &collisionList, int modelIndex, float shrinkSize, float mergeTolerance ) { dmodel_t *pModel = dmodels + modelIndex; @@ -1176,7 +1176,7 @@ static void ConvertWaterModelToPhysCollide( CUtlVector &c CPlaneList planes( shrinkSize, mergeTolerance ); int firstLeaf = waterModel.firstWaterLeafIndex; planes.m_contentsMask = waterModel.contents; - + // push all of the leaves into the collision list for ( int j = 0; j < waterModel.waterLeafCount; j++ ) { @@ -1187,7 +1187,7 @@ static void ConvertWaterModelToPhysCollide( CUtlVector &c pLeaf->leafWaterDataID = waterModel.fogVolumeIndex; planes.ReferenceLeaf( leafIndex ); } - + // visit the referenced leaves that belong to this model VisitLeaves_r( planes, pModel->headnode ); @@ -1226,7 +1226,7 @@ static void ConvertWaterModelToPhysCollide( CUtlVector &c Vector top = physcollision->CollideGetExtent( pCollide, vec3_origin, vec3_angle, waterModel.waterLeafData.surfaceNormal ); waterModel.waterLeafData.surfaceDist = top.z; } - CPhysCollisionEntryFluid *pCollisionEntryFuild = new CPhysCollisionEntryFluid( pCollide, + CPhysCollisionEntryFluid *pCollisionEntryFuild = new CPhysCollisionEntryFluid( pCollide, pSurfaceProp, damping, waterModel.waterLeafData.surfaceNormal, waterModel.waterLeafData.surfaceDist, waterModel.contents ); collisionList.AddToTail( pCollisionEntryFuild ); } @@ -1240,7 +1240,7 @@ static Vector TriangleNormal( const Vector &p0, const Vector &p1, const Vector & Vector e1 = p2 - p0; Vector normal = CrossProduct( e1, e0 ); VectorNormalize( normal ); - + return normal; } @@ -1277,7 +1277,7 @@ static void ConvertWorldBrushesToPhysCollide( CUtlVector VisitLeaves_r( planes, dmodels[0].headnode ); planes.AddBrushes(); - + int count = planes.m_convex.Count(); if ( count ) { @@ -1370,11 +1370,11 @@ static void ConvertModelToPhysCollide( CUtlVector &collis // So compute it for 1% error (on the smallest side, less on larger sides) params.dragAreaEpsilon = clamp( minSurfaceArea * 1e-2f, 1.0f, 1024.0f ); CPhysCollide *pCollide = physcollision->ConvertConvexToCollideParams( planes.m_convex.Base(), count, params ); - + if ( !pCollide ) return; - struct + struct { int prop; float area; @@ -1435,13 +1435,13 @@ static void ConvertModelToPhysCollide( CUtlVector &collis // add up the total surface area totalArea += proplist[i].area; } - + float mass = 1.0f; const char *pMaterial = "default"; if ( maxIndex >= 0 ) { int prop = proplist[maxIndex].prop; - + // use default if this material has no prop if ( prop < 0 ) prop = 0; @@ -1498,7 +1498,7 @@ static void ClearLeafWaterData( void ) void EmitPhysCollision() { ClearLeafWaterData(); - + CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( physicsFactory ) { @@ -1534,7 +1534,7 @@ void EmitPhysCollision() { ConvertModelToPhysCollide( collisionList[i], i, MASK_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|MASK_WATER, VPHYSICS_SHRINK, VPHYSICS_MERGE ); } - + pTextBuffer[i] = NULL; if ( !collisionList[i].Count() ) continue; @@ -1589,7 +1589,7 @@ void EmitPhysCollision() } // add one for tail of list marker - physModelCount++; + physModelCount++; // DWORD align the lump because AddLump assumes that it is DWORD aligned. byte *ptr ; diff --git a/utils/vbsp/manifest.cpp b/utils/vbsp/manifest.cpp index c72a9564..4ba2952a 100644 --- a/utils/vbsp/manifest.cpp +++ b/utils/vbsp/manifest.cpp @@ -5,13 +5,31 @@ #include "manifest.h" #include "windows.h" +#ifdef MAPBASE +entity_t *g_ManifestWorldSpawn = NULL; + +extern char g_MainMapPath[ MAX_PATH ]; +#endif + +//----------------------------------------------------------------------------- +// Purpose: default constructor +//----------------------------------------------------------------------------- +CManifestMapPrefs::CManifestMapPrefs( void ) +{ + m_nInternalId = 0; + m_bIsVisible = true; + //m_bIsPrimary = false; +} + //----------------------------------------------------------------------------- // Purpose: default constructor //----------------------------------------------------------------------------- CManifestMap::CManifestMap( void ) { + m_nInternalId = 0; m_RelativeMapFileName[ 0 ] = 0; m_bTopLevelMap = false; + m_bIsVisible = true; } @@ -35,7 +53,11 @@ CManifest::CManifest( void ) //----------------------------------------------------------------------------- ChunkFileResult_t CManifest::LoadManifestMapKeyCallback( const char *szKey, const char *szValue, CManifestMap *pManifestMap ) { - if ( !stricmp( szKey, "Name" ) ) + if ( !stricmp( szKey, "InternalID" ) ) + { + pManifestMap->m_nInternalId = atoi( szValue ); + } + else if ( !stricmp( szKey, "Name" ) ) { // pManifestMap->m_FriendlyName = szValue; } @@ -260,6 +282,82 @@ ChunkFileResult_t CManifest::LoadManifestCordoningPrefsCallback( CChunkFile *pFi return( eResult ); } +//----------------------------------------------------------------------------- +// Parses the preferences chunk that pertains to specific submaps in the map: +// +// Maps +// { +// VMF +// { +// "InternalID" "1" +// "IsPrimary" "1" +// } +// VMF +// { +// "InternalID" "2" +// } +// VMF +// { +// "InternalID" "3" +// "IsVisible" "0" +// } +// } +// +//----------------------------------------------------------------------------- + +ChunkFileResult_t CManifest::LoadPrefsVmfKeyCallback( const char *szKey, const char *szValue, CManifestMapPrefs *pManifestMapPrefs ) +{ + if ( !stricmp( szKey, "InternalID" ) ) + { + pManifestMapPrefs->m_nInternalId = atoi( szValue ); + } + else if ( !stricmp( szKey, "IsVisible" ) ) + { + pManifestMapPrefs->m_bIsVisible = ( atoi( szValue ) == 1 ); + } + //else if ( !stricmp( szKey, "IsPrimary" ) ) + //{ + // pManifestMapPrefs->m_bIsPrimary = ( atoi( szValue ) == 1 ); + //} + + return ChunkFile_Ok; +} + +//----------------------------------------------------------------------------- +// Parses preferences and applies them to their corresponding submaps +//----------------------------------------------------------------------------- +ChunkFileResult_t CManifest::LoadPrefsVmfCallback( CChunkFile *pFile, CManifest *pManifest ) +{ + CManifestMapPrefs prefs; + ChunkFileResult_t eResult = pFile->ReadChunk( (KeyHandler_t)LoadPrefsVmfKeyCallback, &prefs ); + + if (eResult == ChunkFile_Ok && prefs.m_nInternalId != 0) + { + for( int i = 0; i < pManifest->m_Maps.Count(); i++ ) + { + if ( pManifest->m_Maps[ i ]->m_nInternalId == prefs.m_nInternalId ) + { + pManifest->m_Maps[ i ]->m_bIsVisible = prefs.m_bIsVisible; + break; + } + } + } + + return(eResult); +} +ChunkFileResult_t CManifest::LoadPrefsMapsCallback( CChunkFile *pFile, CManifest *pManifest ) +{ + CChunkHandlerMap Handlers; + Handlers.AddHandler( "VMF", ( ChunkHandler_t )CManifest::LoadPrefsVmfCallback, pManifest ); + pFile->PushHandlers(&Handlers); + + ChunkFileResult_t eResult = pFile->ReadChunk(); + + pFile->PopHandlers(); + + return( eResult ); +} + //----------------------------------------------------------------------------- // Purpose: this function will create a new entity pair @@ -298,12 +396,20 @@ bool CManifest::LoadSubMaps( CMapFile *pMapFile, const char *pszFileName ) memset( InstanceEntity, 0, sizeof( *InstanceEntity ) ); InstanceEntity->origin.Init( 0.0f, 0.0f, 0.0f ); + +#ifdef MAPBASE + g_ManifestWorldSpawn = InstanceEntity; +#else pEPair = CreateEPair( "classname", "worldspawn" ); pEPair->next = InstanceEntity->epairs; InstanceEntity->epairs = pEPair; +#endif for( int i = 0; i < m_Maps.Count(); i++ ) { + if ( g_bNoHiddenManifestMaps && !m_Maps[ i ]->m_bIsVisible ) + continue; + // if ( m_Maps[ i ]->m_bTopLevelMap == false ) { char FileName[ MAX_PATH ]; @@ -361,7 +467,11 @@ bool CManifest::LoadVMFManifestUserPrefs( const char *pszFileName ) UserNameSize = sizeof( UserName ); if ( GetUserName( UserName, &UserNameSize ) == 0 ) { +#ifdef MAPBASE + strcpy( UserName, "default" ); +#else strcpy( UserPrefsFileName, "default" ); +#endif } sprintf( UserPrefsFileName, "\\%s.vmm_prefs", UserName ); @@ -385,6 +495,9 @@ bool CManifest::LoadVMFManifestUserPrefs( const char *pszFileName ) CChunkHandlerMap Handlers; Handlers.AddHandler( "cordoning", ( ChunkHandler_t )CManifest::LoadManifestCordoningPrefsCallback, this ); + if (g_bNoHiddenManifestMaps) + Handlers.AddHandler( "Maps", ( ChunkHandler_t )CManifest::LoadPrefsMapsCallback, this ); + // Handlers.SetErrorHandler( ( ChunkErrorHandler_t )CMapDoc::HandleLoadError, this); File.PushHandlers(&Handlers); @@ -456,11 +569,14 @@ bool CManifest::LoadVMFManifest( const char *pszFileName ) if ( g_MainMap == NULL ) { g_MainMap = g_LoadingMap; +#ifdef MAPBASE + V_ExtractFilePath( pszFileName, g_MainMapPath, sizeof( g_MainMapPath ) ); +#endif } - LoadSubMaps( g_LoadingMap, pszFileName ); - LoadVMFManifestUserPrefs( pszFileName ); + + LoadSubMaps( g_LoadingMap, pszFileName ); } return ( eResult == ChunkFile_Ok ); diff --git a/utils/vbsp/manifest.h b/utils/vbsp/manifest.h index e7b801e1..3d772117 100644 --- a/utils/vbsp/manifest.h +++ b/utils/vbsp/manifest.h @@ -32,8 +32,19 @@ class CManifestMap { public: CManifestMap( void ); + int m_nInternalId; char m_RelativeMapFileName[ MAX_PATH ]; bool m_bTopLevelMap; + bool m_bIsVisible; +}; + +class CManifestMapPrefs +{ +public: + CManifestMapPrefs( void ); + int m_nInternalId; + bool m_bIsVisible; + //int m_bIsPrimary; }; class CManifest @@ -51,6 +62,9 @@ class CManifest static ChunkFileResult_t LoadCordonsKeyCallback( const char *pszKey, const char *pszValue, CManifest *pManifest ); static ChunkFileResult_t LoadCordonsCallback( CChunkFile *pFile, CManifest *pManifest ); static ChunkFileResult_t LoadManifestCordoningPrefsCallback( CChunkFile *pFile, CManifest *pManifest ); + static ChunkFileResult_t LoadPrefsVmfKeyCallback( const char *szKey, const char *szValue, CManifestMapPrefs *pManifestMapPrefs ); + static ChunkFileResult_t LoadPrefsVmfCallback( CChunkFile *pFile, CManifest *pManifest ); + static ChunkFileResult_t LoadPrefsMapsCallback( CChunkFile *pFile, CManifest *pManifest ); bool LoadSubMaps( CMapFile *pMapFile, const char *pszFileName ); epair_t *CreateEPair( char *pKey, char *pValue ); diff --git a/utils/vbsp/map.cpp b/utils/vbsp/map.cpp index d80ab771..c479b279 100644 --- a/utils/vbsp/map.cpp +++ b/utils/vbsp/map.cpp @@ -15,6 +15,12 @@ #include "materialsub.h" #include "fgdlib/fgdlib.h" #include "manifest.h" +#ifdef PARALLAX_CORRECTED_CUBEMAPS +#include "matrixinvert.h" +#endif +#ifdef MAPBASE_VSCRIPT +#include "vscript_vbsp.h" +#endif #ifdef VSVMFIO #include "VmfImport.h" @@ -46,6 +52,15 @@ struct LoadSide_t extern qboolean onlyents; +#ifdef MAPBASE +extern entity_t *g_ManifestWorldSpawn; + +char g_MainMapPath[ MAX_PATH ]; + +// This is done for the instancing fix +bool g_pParallaxObbsDone[MAX_MAP_CUBEMAPSAMPLES]; +#endif + CUtlVector< CMapFile * > g_Maps; CMapFile *g_MainMap = NULL; @@ -1618,10 +1633,16 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam) if( ( g_nDXLevel == 0 ) || ( g_nDXLevel >= 70 ) ) { const char *pSideListStr = ValueForKey( mapent, "sides" ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + char *pParallaxObbStr = ValueForKey( mapent, "parallaxobb" ); +#endif int size; size = IntForKey( mapent, "cubemapsize" ); - float radius = FloatForKey(mapent, "radius"); - Cubemap_InsertSample( mapent->origin, size, radius); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + Cubemap_InsertSample( mapent->origin, size, pParallaxObbStr ); +#else + Cubemap_InsertSample( mapent->origin, size ); +#endif Cubemap_SaveBrushSides( pSideListStr ); } // clear out this entity @@ -1629,6 +1650,88 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam) return(ChunkFile_Ok); } +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // + // parallax_obb brushes are removed after the transformation matrix is found and saved into + // the entity's data (ent will be removed after data transferred to patched materials) + // + if (!strcmp("parallax_obb", pClassName)) + { + matrix3x4_t obbMatrix, invObbMatrix; + SetIdentityMatrix(obbMatrix); + SetIdentityMatrix(invObbMatrix); + + // Get corner and its 3 edges (scaled, local x, y, and z axes) + mapbrush_t *brush = &mapbrushes[mapent->firstbrush]; + Vector corner, x, y, z; + + // Find first valid winding (with these whiles, if not enough valid windings then identity matrix is passed through to vmts) + int i = 0; + while (i < brush->numsides) + { + winding_t* wind = brush->original_sides[i].winding; + if (!wind) + { + i++; + continue; + } + + corner = wind->p[0]; + y = wind->p[1] - corner; + z = wind->p[3] - corner; + x = CrossProduct(y, z).Normalized(); + + i++; + break; + } + + // Skip second valid winding (opposite face from first, unusable for finding Z's length) + while (i < brush->numsides) + { + winding_t* wind = brush->original_sides[i].winding; + if (!wind) + { + i++; + continue; + } + i++; + break; + } + + // Find third valid winding + while (i < brush->numsides) + { + winding_t* wind = brush->original_sides[i].winding; + if (!wind) + { + i++; + continue; + } + + // Find length of x + // Start with diagonal, then scale x by the projection of diag onto x + Vector diag = wind->p[0] - wind->p[2]; + x *= abs(DotProduct(diag, x)); + + // Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush) + MatrixSetColumn(x, 0, obbMatrix); + MatrixSetColumn(y, 1, obbMatrix); + MatrixSetColumn(z, 2, obbMatrix); + MatrixSetColumn(corner, 3, obbMatrix); + + //find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer) + MatrixInversion(obbMatrix, invObbMatrix); + break; + } + + char szMatrix[1024]; + Q_snprintf(szMatrix, 1024, "[%f %f %f %f];[%f %f %f %f];[%f %f %f %f]", invObbMatrix[0][0], invObbMatrix[0][1], invObbMatrix[0][2], invObbMatrix[0][3], invObbMatrix[1][0], invObbMatrix[1][1], invObbMatrix[1][2], invObbMatrix[1][3], invObbMatrix[2][0], invObbMatrix[2][1], invObbMatrix[2][2], invObbMatrix[2][3]); + SetKeyValue(mapent, "transformationmatrix", szMatrix); + + return (ChunkFile_Ok); + } +#endif + if ( !strcmp( "test_sidelist", pClassName ) ) { ConvertSideList(mapent, "sides"); @@ -2002,7 +2105,12 @@ void CMapFile::CheckForInstances( const char *pszFileName ) } char FDGPath[ MAX_PATH ]; +#ifdef MAPBASE + // Mapbase's FGD would be in a MOD path + if ( !g_pFullFileSystem->RelativePathToFullPath( GameDataFile, "MOD", FDGPath, sizeof( FDGPath ) ) ) +#else if ( !g_pFullFileSystem->RelativePathToFullPath( GameDataFile, "EXECUTABLE_PATH", FDGPath, sizeof( FDGPath ) ) ) +#endif { if ( !g_pFullFileSystem->RelativePathToFullPath( GameDataFile, NULL, FDGPath, sizeof( FDGPath ) ) ) { @@ -2025,7 +2133,11 @@ void CMapFile::CheckForInstances( const char *pszFileName ) char InstancePath[ MAX_PATH ]; bool bLoaded = false; +#ifdef MAPBASE + if ( DeterminePath( pszFileName, pInstanceFile, InstancePath ) || DeterminePath( g_MainMapPath, pInstanceFile, InstancePath ) ) +#else if ( DeterminePath( pszFileName, pInstanceFile, InstancePath ) ) +#endif { if ( LoadMapFile( InstancePath ) ) { @@ -2334,6 +2446,11 @@ void CMapFile::MergeEntities( entity_t *pInstanceEntity, CMapFile *Instance, Vec entity_t *WorldspawnEnt = NULL; GameData::TNameFixup FixupStyle; +#ifdef MAPBASE + // For fixing AI node problems with manifests and instances + int max_ai_node_id = 0; +#endif + char *pTargetName = ValueForKey( pInstanceEntity, "targetname" ); char *pName = ValueForKey( pInstanceEntity, "name" ); if ( pTargetName[ 0 ] ) @@ -2360,6 +2477,20 @@ void CMapFile::MergeEntities( entity_t *pInstanceEntity, CMapFile *Instance, Vec max_entity_id = value; } } + +#ifdef MAPBASE + // If this is a classname starting with "info_node", look for a node ID keyvalue and + // add it to the counter. + if ( strnicmp( ValueForKey( &entities[ i ], "classname" ), "info_node", 9 ) == 0 ) + { + int value = atoi( ValueForKey( &entities[i], "nodeid" ) ); + if ( value > max_ai_node_id ) + { + max_ai_node_id = value; + //Warning( "Max AI nodes is now %i", max_ai_node_id ); + } + } +#endif } FixupStyle = ( GameData::TNameFixup )( IntForKey( pInstanceEntity, "fixup_style" ) ); @@ -2404,6 +2535,11 @@ void CMapFile::MergeEntities( entity_t *pInstanceEntity, CMapFile *Instance, Vec GDclass *EntClass = GD.BeginInstanceRemap( pEntity, NameFixup, InstanceOrigin, InstanceAngle ); if ( EntClass ) { +#ifdef MAPBASE + // Sets up for additional instance remap fixes from Mapbase + GD.SetupInstanceRemapParams( max_ai_node_id, nummapbrushsides - Instance->nummapbrushsides, IntForKey( pInstanceEntity, "remap_vecline" ) > 0 ); +#endif + for( int i = 0; i < EntClass->GetVariableCount(); i++ ) { GDinputvariable *EntVar = EntClass->GetVariableAt( i ); @@ -2443,13 +2579,60 @@ void CMapFile::MergeEntities( entity_t *pInstanceEntity, CMapFile *Instance, Vec Q_snprintf( temp, sizeof( temp ), "%f", vOutNormal.z ); SetKeyValue( entity, "normal.z", temp );*/ } + +#ifdef MAPBASE + else if ( !strcmp( pEntity, "func_instance" ) ) + { + int iNumReplaces = 0; + for ( epair_t *epSubInstance = entity->epairs; epSubInstance != NULL; epSubInstance = epSubInstance->next ) + { + if ( strnicmp( epSubInstance->key, INSTANCE_VARIABLE_KEY, strlen( INSTANCE_VARIABLE_KEY ) ) == 0 ) + { + iNumReplaces++; + } + } + + // Merge this instance's keys + for ( epair_t *epInstance = pInstanceEntity->epairs; epInstance != NULL; epInstance = epInstance->next ) + { + if ( strnicmp( epInstance->key, INSTANCE_VARIABLE_KEY, strlen( INSTANCE_VARIABLE_KEY ) ) == 0 ) + { + iNumReplaces++; + char szKey[32]; + Q_snprintf(szKey, sizeof(szKey), "replace%i", iNumReplaces); + SetKeyValue( entity, szKey, epInstance->value ); + } + } + + // If the parent instance is within a relative path and no file relative to the main map exists, change it to be relative to the parent + char *pParentInstanceFile = ValueForKey( pInstanceEntity, "file" ); + if ( pParentInstanceFile[ 0 ] && (strchr( pParentInstanceFile, '\\' ) || strchr( pParentInstanceFile, '/' )) ) + { + char *pInstanceFile = ValueForKey( entity, "file" ); + if ( pInstanceFile[ 0 ] ) + { + char InstancePath[ MAX_PATH ]; + + if ( !DeterminePath( g_MainMapPath, pInstanceFile, InstancePath ) ) + { + strcpy( InstancePath, pParentInstanceFile ); + V_StripFilename( InstancePath ); + V_strncat( InstancePath, "\\", sizeof( InstancePath ) ); + V_strncat( InstancePath, pInstanceFile, sizeof( InstancePath ) ); + + SetKeyValue( entity, "file", InstancePath ); + } + } + } + } +#endif } #ifdef MERGE_INSTANCE_DEBUG_INFO Msg( "Instance Entity %d remapped to %d\n", i, num_entities + i ); Msg( " FirstBrush: from %d to %d\n", Instance->entities[ i ].firstbrush, entity->firstbrush ); Msg( " KV Pairs:\n" ); - for ( epair_t *ep = entity->epairs; ep->next != NULL; ep = ep->next ) + for ( epair_t *ep = entity->epairs; ep != NULL; ep = ep->next ) { Msg( " %s %s\n", ep->key, ep->value ); } @@ -2497,7 +2680,16 @@ void CMapFile::MergeEntities( entity_t *pInstanceEntity, CMapFile *Instance, Vec MoveBrushesToWorldGeneral( WorldspawnEnt ); WorldspawnEnt->numbrushes = 0; +#ifdef MAPBASE + char *pIsTopLevel = ValueForKey( pInstanceEntity, "toplevel" ); + if ( strcmp( pIsTopLevel, "1" ) == 0 ) + { + g_ManifestWorldSpawn->epairs = WorldspawnEnt->epairs; + } WorldspawnEnt->epairs = NULL; +#else + WorldspawnEnt->epairs = NULL; +#endif } @@ -2516,10 +2708,27 @@ void CMapFile::MergeOverlays( entity_t *pInstanceEntity, CMapFile *Instance, Vec for( int i = Instance->m_StartMapOverlays; i < g_aMapOverlays.Count(); i++ ) { Overlay_Translate( &g_aMapOverlays[ i ], InstanceOrigin, InstanceAngle, InstanceMatrix ); + +#ifdef MAPBASE + int iSides = (nummapbrushsides - Instance->nummapbrushsides); + for (int i2 = 0; i2 < g_aMapOverlays[i].aSideList.Count(); i2++) + { + //Warning( "Remapping overlay side %i to %i\n", g_aMapOverlays[i].aSideList[i2], g_aMapOverlays[i].aSideList[i2] + iSides ); + g_aMapOverlays[i].aSideList[i2] += iSides; + } +#endif } for( int i = Instance->m_StartMapWaterOverlays; i < g_aMapWaterOverlays.Count(); i++ ) { Overlay_Translate( &g_aMapWaterOverlays[ i ], InstanceOrigin, InstanceAngle, InstanceMatrix ); + +#ifdef MAPBASE + int iSides = (nummapbrushsides - Instance->nummapbrushsides); + for (int i2 = 0; i2 < g_aMapWaterOverlays[i].aSideList.Count(); i2++) + { + g_aMapWaterOverlays[i].aSideList[i2] += iSides; + } +#endif } } @@ -2574,6 +2783,9 @@ bool LoadMapFile( const char *pszFileName ) if ( g_MainMap == NULL ) { g_MainMap = g_LoadingMap; +#ifdef MAPBASE + V_ExtractFilePath( pszFileName, g_MainMapPath, sizeof( g_MainMapPath ) ); +#endif } if ( g_MainMap == g_LoadingMap || verbose ) @@ -2612,6 +2824,21 @@ bool LoadMapFile( const char *pszFileName ) if ((eResult == ChunkFile_Ok) || (eResult == ChunkFile_EOF)) { +#ifdef MAPBASE_VSCRIPT + if ( g_pScriptVM ) + { + if (CMapFile::g_Hook_OnMapLoaded.CanRunInScope( NULL )) + { + // Use GetLoadingMap() + //g_pScriptVM->SetValue( "map", g_LoadingMap->GetScriptInstance() ); + + CMapFile::g_Hook_OnMapLoaded.Call( NULL, NULL, NULL ); + + //g_pScriptVM->ClearValue( "map" ); + } + } +#endif + // Update the overlay/side list(s). Overlay_UpdateSideLists( g_LoadingMap->m_StartMapOverlays ); OverlayTransition_UpdateSideLists( g_LoadingMap->m_StartMapWaterOverlays ); @@ -2623,6 +2850,51 @@ bool LoadMapFile( const char *pszFileName ) pMainManifest->CordonWorld(); } +#ifdef PARALLAX_CORRECTED_CUBEMAPS + // Fill out parallax obb matrix array + // "i" is static so this code could account for + // multiple LoadMapFile() calls from instances, etc. + for (int i = 0; i < g_nCubemapSamples; i++) + { + if (g_pParallaxObbStrs[i][0] != '\0' && g_pParallaxObbsDone[i] == false) + { + //Warning( "Testing OBB string %s\n", g_pParallaxObbStrs[i] ); + + entity_t* obbEnt = NULL; + for (int i2 = 0; i2 < g_LoadingMap->num_entities; i2++) + { + if (stricmp( ValueForKey( &g_LoadingMap->entities[i2], "targetname" ), g_pParallaxObbStrs[i] ) != 0) + continue; + + obbEnt = &g_LoadingMap->entities[i2]; + g_pParallaxObbStrs[i] = ValueForKey(obbEnt, "transformationmatrix"); + //Warning( "Using OBB transformation matrix \"%s\"\n", g_pParallaxObbStrs[i] ); + g_pParallaxObbsDone[i] = true; + + break; + } + + if (!obbEnt) + { + Warning( "Cannot find parallax obb \"%s\" (num_entities is %i)\n", g_pParallaxObbStrs[i], g_LoadingMap->num_entities ); + //g_pParallaxObbStrs[i][0] = '\0'; + } + } + } + + // Remove parallax_obb entities (in a nice slow linear search) + for (int i = 0; i < g_LoadingMap->num_entities; i++) + { + entity_t* mapent = &g_LoadingMap->entities[i]; + const char *pClassName = ValueForKey( mapent, "classname" ); + if ( !strcmp( "parallax_obb", pClassName ) ) + { + mapent->numbrushes = 0; + mapent->epairs = NULL; + } + } +#endif + ClearBounds (g_LoadingMap->map_mins, g_LoadingMap->map_maxs); for (int i=0 ; ientities[0].numbrushes ; i++) { @@ -3121,6 +3393,133 @@ ChunkFileResult_t LoadSolidKeyCallback(const char *szKey, const char *szValue, m } +#ifdef MAPBASE_VSCRIPT +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HSCRIPT CMapFile::GetScriptInstance() +{ + if (!m_hScriptInstance) + m_hScriptInstance = g_pScriptVM->RegisterInstance( this ); + + return m_hScriptInstance; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMapFile::ScriptGetEntityKeyValues( int idx, HSCRIPT hKeyTable, HSCRIPT hValTable ) +{ + epair_t *curPair = entities[idx].epairs; + while (curPair) + { + g_pScriptVM->ArrayAppend( hKeyTable, curPair->key ); + g_pScriptVM->ArrayAppend( hValTable, curPair->value ); + + curPair = curPair->next; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CMapFile::ScriptAddSimpleEntityKV( HSCRIPT hKV ) +{ + if (num_entities == MAX_MAP_ENTITIES) + { + // Exits. + g_MapError.ReportError ("num_entities == MAX_MAP_ENTITIES"); + return -1; + } + + entity_t *mapent = NULL; + if (::num_entities > 0) + { + // We're not loading maps anymore. Add this to the central BSP + mapent = &::entities[num_entities]; + ::num_entities++; + } + else + { + mapent = &entities[num_entities]; + num_entities++; + } + + memset(mapent, 0, sizeof(*mapent)); + mapent->firstbrush = nummapbrushes; + mapent->numbrushes = 0; + //mapent->portalareas[0] = -1; + //mapent->portalareas[1] = -1; + + LoadEntity_t LoadEntity; + LoadEntity.pEntity = mapent; + + // No default flags/contents + LoadEntity.nBaseFlags = 0; + LoadEntity.nBaseContents = 0; + + int nIterator = -1; + ScriptVariant_t varKey, varValue; + char szValue[256]; + while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1) + { + switch (varValue.m_type) + { + case FIELD_CSTRING: Q_strncpy( szValue, varValue.m_pszString, sizeof(szValue) ); break; + case FIELD_INTEGER: Q_snprintf( szValue, sizeof(szValue), "%i", varValue.m_int ); break; + case FIELD_FLOAT: Q_snprintf( szValue, sizeof(szValue), "%f", varValue.m_float ); break; + case FIELD_CHARACTER: Q_snprintf( szValue, sizeof( szValue ), "%c", varValue.m_char ); break; + case FIELD_BOOLEAN: Q_snprintf( szValue, sizeof(szValue), "%d", varValue.m_bool ); break; + case FIELD_VECTOR: Q_snprintf( szValue, sizeof(szValue), "%f %f %f", (*varValue.m_pVector).x, (*varValue.m_pVector).y, (*varValue.m_pVector).z ); break; + default: szValue[0] = '\0'; break; + } + + LoadEntityKeyCallback( varKey, szValue, &LoadEntity ); + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } + + return num_entities - 1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CMapFile::ScriptAddInstance( const char *pszVMF, const Vector& vecOrigin, const QAngle& angAngles ) +{ + if (num_entities == MAX_MAP_ENTITIES) + { + // Exits. + g_MapError.ReportError ("num_entities == MAX_MAP_ENTITIES"); + return -1; + } + + entity_t *mapent = &entities[num_entities]; + num_entities++; + memset(mapent, 0, sizeof(*mapent)); + mapent->firstbrush = nummapbrushes; + mapent->numbrushes = 0; + //mapent->portalareas[0] = -1; + //mapent->portalareas[1] = -1; + + SetKeyValue( mapent, "classname", "func_instance" ); + + SetKeyValue( mapent, "file", pszVMF ); + SetKeyValue( mapent, "fixup_style", "2" ); // No fixup + + char szValue[256]; + Q_snprintf( szValue, sizeof(szValue), "%f %f %f", vecOrigin.x, vecOrigin.y, vecOrigin.z ); + SetKeyValue( mapent, "origin", szValue ); + + Q_snprintf( szValue, sizeof(szValue), "%f %f %f", angAngles.x, angAngles.y, angAngles.z ); + SetKeyValue( mapent, "angles", szValue ); + + return num_entities - 1; +} +#endif + + /* ================ TestExpandBrushes diff --git a/utils/vbsp/matrixinvert.h b/utils/vbsp/matrixinvert.h new file mode 100644 index 00000000..6e676ad3 --- /dev/null +++ b/utils/vbsp/matrixinvert.h @@ -0,0 +1,117 @@ +// By Jason Yu-Tseh Chi +// From http://chi3x10.wordpress.com/2008/05/28/calculate-matrix-inversion-in-c/ +// Modified to work with valve's matrix_3x4_t + +#include "mathlib\mathlib.h" + +// Calculate the cofactor of element (row,col) +int GetMatrixMinor(float **src, float **dest, int row, int col, int order) +{ + // Indicate which col and row is being copied to dest + int colCount = 0, rowCount = 0; + + for (int i = 0; i < order; i++) + { + if (i != row) + { + colCount = 0; + for (int j = 0; j < order; j++) + { + // When j is not the element + if (j != col) + { + dest[rowCount][colCount] = src[i][j]; + colCount++; + } + } + rowCount++; + } + } + + return 1; +} + +// Calculate the determinant recursively. +double CalcMatrixDeterminant(float **mat, int order) +{ + // Order must be >= 0 + // Stop the recursion when matrix is a single element + if (order == 1) + return mat[0][0]; + + // The determinant value + float det = 0; + + // Allocate the cofactor matrix + float **minor; + minor = new float*[order - 1]; + for (int i = 0; inodes[s] ); } } + +#ifdef MAPBASE + if (!noleaktest) + { + Warning( ("--- AREAPORTAL LEAK ---\n") ); + exit(0); + } +#endif } diff --git a/utils/vbsp/staticprop.cpp b/utils/vbsp/staticprop.cpp index 48f6279e..a08ab4e2 100644 --- a/utils/vbsp/staticprop.cpp +++ b/utils/vbsp/staticprop.cpp @@ -54,8 +54,6 @@ struct StaticPropBuild_t float m_flForcedFadeScale; unsigned short m_nMinDXLevel; unsigned short m_nMaxDXLevel; - int m_LightmapResolutionX; - int m_LightmapResolutionY; }; @@ -104,6 +102,7 @@ isstaticprop_ret IsStaticProp( studiohdr_t* pHdr ) if (!(pHdr->flags & STUDIOHDR_FLAGS_STATIC_PROP)) return RET_FAIL_NOT_MARKED_STATIC_PROP; +#ifndef MAPBASE // If it's got a propdata section in the model's keyvalues, it's not allowed to be a prop_static KeyValues *modelKeyValues = new KeyValues(pHdr->pszName()); if ( StudioKeyValues( pHdr, modelKeyValues ) ) @@ -119,6 +118,7 @@ isstaticprop_ret IsStaticProp( studiohdr_t* pHdr ) } } modelKeyValues->deleteThis(); +#endif return RET_VALID; } @@ -167,7 +167,7 @@ bool LoadStudioModel( char const* pModelName, char const* pEntityType, CUtlBuffe return false; } - /*isstaticprop_ret isStaticProp = IsStaticProp(pHdr); + isstaticprop_ret isStaticProp = IsStaticProp(pHdr); if ( isStaticProp != RET_VALID ) { if ( isStaticProp == RET_FAIL_NOT_MARKED_STATIC_PROP ) @@ -180,7 +180,7 @@ bool LoadStudioModel( char const* pModelName, char const* pEntityType, CUtlBuffe Warning("Error! %s using model \"%s\", which must be used on a dynamic entity (i.e. prop_physics). Deleted.\n", pEntityType, pModelName ); } return false; - }*/ + } // ensure reset pHdr->pVertexBase = NULL; @@ -518,9 +518,6 @@ static void AddStaticPropToLump( StaticPropBuild_t const& build ) } } - propLump.m_nLightmapResolutionX = build.m_LightmapResolutionX; - propLump.m_nLightmapResolutionY = build.m_LightmapResolutionY; - // Add the leaves to the leaf lump for (int j = 0; j < leafList.Size(); ++j) { @@ -528,7 +525,6 @@ static void AddStaticPropToLump( StaticPropBuild_t const& build ) insert.m_Leaf = leafList[j]; s_StaticPropLeafLump.AddToTail( insert ); } - } @@ -569,6 +565,10 @@ static void SetLumpData( ) void EmitStaticProps() { +#ifdef MAPBASE + Msg("Placing static props...\n"); +#endif + CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( physicsFactory ) { @@ -592,13 +592,43 @@ void EmitStaticProps() for ( i = 0; i < num_entities; ++i) { char* pEntity = ValueForKey(&entities[i], "classname"); +#ifdef MAPBASE + const int iInsertAsStatic = IntForKey( &entities[i], "insertasstaticprop" ); // If the key is absent, IntForKey will return 0. + bool bInsertAsStatic = g_bPropperInsertAllAsStatic; + + // 1 = No, 2 = Yes; Any other number will just use what g_bPropperInsertAllAsStatic is set as. + if ( iInsertAsStatic == 1 ) { bInsertAsStatic = false; } + else if ( iInsertAsStatic == 2 ) { bInsertAsStatic = true; } + + if ( !strcmp( pEntity, "static_prop" ) || !strcmp( pEntity, "prop_static" ) || ( !strcmp( pEntity, "propper_model" ) && bInsertAsStatic ) ) +#else if (!strcmp(pEntity, "static_prop") || !strcmp(pEntity, "prop_static")) +#endif { StaticPropBuild_t build; GetVectorForKey( &entities[i], "origin", build.m_Origin ); GetAnglesForKey( &entities[i], "angles", build.m_Angles ); +#ifdef MAPBASE + if ( !strcmp( pEntity, "propper_model" ) ) + { + char* pModelName = ValueForKey( &entities[i], "modelname" ); + + // The modelname keyvalue lacks 'models/' at the start and '.mdl' at the end, so we have to add them. + char modelpath[MAX_VALUE]; + sprintf( modelpath, "models/%s.mdl", pModelName ); + + Msg( "Inserting propper_model (%.0f %.0f %.0f) as prop_static: %s\n", build.m_Origin[0], build.m_Origin[1], build.m_Origin[2], modelpath ); + + build.m_pModelName = modelpath; + } + else // Otherwise we just assume it's a normal prop_static + { + build.m_pModelName = ValueForKey( &entities[i], "model" ); + } +#else build.m_pModelName = ValueForKey( &entities[i], "model" ); +#endif build.m_Solid = IntForKey( &entities[i], "solid" ); build.m_Skin = IntForKey( &entities[i], "skin" ); build.m_FadeMaxDist = FloatForKey( &entities[i], "fademaxdist" ); @@ -625,18 +655,6 @@ void EmitStaticProps() build.m_Flags |= STATIC_PROP_SCREEN_SPACE_FADE; } - if (IntForKey( &entities[i], "generatelightmaps") == 0) - { - build.m_Flags |= STATIC_PROP_NO_PER_TEXEL_LIGHTING; - build.m_LightmapResolutionX = 0; - build.m_LightmapResolutionY = 0; - } - else - { - build.m_LightmapResolutionX = IntForKey( &entities[i], "lightmapresolutionx" ); - build.m_LightmapResolutionY = IntForKey( &entities[i], "lightmapresolutiony" ); - } - const char *pKey = ValueForKey( &entities[i], "fadescale" ); if ( pKey && pKey[0] ) { @@ -667,6 +685,13 @@ void EmitStaticProps() // strip this ent from the .bsp file entities[i].epairs = 0; } +#ifdef MAPBASE + else if ( g_bPropperStripEntities && !strncmp( pEntity, "propper_", 8 ) ) // Strip out any entities with 'propper_' in their classname, as they don't actually exist in-game. + { + Warning( "Not including %s in BSP compile due to it being a propper entity that isn't used in-game.\n", pEntity ); + entities[i].epairs = 0; + } +#endif } // Strip out lighting origins; has to be done here because they are used when diff --git a/utils/vbsp/textures.cpp b/utils/vbsp/textures.cpp index 4f49c5d4..3a7cffde 100644 --- a/utils/vbsp/textures.cpp +++ b/utils/vbsp/textures.cpp @@ -153,6 +153,13 @@ int FindMiptex (const char *name) { textureref[i].flags |= SURF_NOLIGHT; } +#ifdef MAPBASE + // handle Slammin-inspired %compileNoShadows% + else if ( ( propVal = GetMaterialVar( matID, "%compileNoShadows" ) ) && StringIsTrue( propVal ) ) + { + textureref[i].flags |= SURF_NOSHADOWS; + } +#endif else { // HANDLE ALL OF THE STUFF THAT IS RENDERED WITH THE MATERIAL THAT IS ON IT. diff --git a/utils/vbsp/vbsp.cpp b/utils/vbsp/vbsp.cpp index 49408915..75722bfe 100644 --- a/utils/vbsp/vbsp.cpp +++ b/utils/vbsp/vbsp.cpp @@ -20,6 +20,11 @@ #include "byteswap.h" #include "worldvertextransitionfixup.h" +#ifdef MAPBASE_VSCRIPT +#include "vscript/ivscript.h" +#include "vscript_vbsp.h" +#endif + extern float g_maxLightmapDimension; char source[1024]; @@ -43,7 +48,11 @@ qboolean noshare; qboolean nosubdiv; qboolean notjunc; qboolean noopt; +#ifdef MAPBASE +qboolean noleaktest; +#else qboolean leaktest; +#endif qboolean verboseentities; qboolean dumpcollide = false; qboolean g_bLowPriority = false; @@ -56,21 +65,27 @@ bool g_NodrawTriggers = false; bool g_DisableWaterLighting = false; bool g_bAllowDetailCracks = false; bool g_bNoVirtualMesh = false; +bool g_bNoHiddenManifestMaps = false; +#ifdef MAPBASE +bool g_bNoDefaultCubemaps = true; +bool g_bSkyboxCubemaps = false; +bool g_bPropperInsertAllAsStatic = false; +bool g_bPropperStripEntities = false; +int g_iDefaultCubemapSize = 32; +#endif +#ifdef MAPBASE_VSCRIPT +ScriptLanguage_t g_iScripting = SL_NONE; +#endif float g_defaultLuxelSize = DEFAULT_LUXEL_SIZE; float g_luxelScale = 1.0f; float g_minLuxelScale = 1.0f; bool g_BumpAll = false; -bool g_SkyboxCubemap = false; -bool g_SkyboxCubemapDump = false; -int g_SkyboxCubemapRes = 32; int g_nDXLevel = 0; // default dxlevel if you don't specify it on the command-line. CUtlVector g_SkyAreas; char outbase[32]; -char g_szEmbedDir[MAX_PATH] = { 0 }; - // HLTOOLS: Introduce these calcs to make the block algorithm proportional to the proper // world coordinate extents. Assumes square spatial constraints. #define BLOCKS_SIZE 1024 @@ -299,7 +314,11 @@ void ProcessWorldModel (void) Warning( ("**** leaked ****\n") ); leaked = true; LeakFile (tree); +#ifdef MAPBASE + if (!noleaktest) +#else if (leaktest) +#endif { Warning( ("--- MAP LEAKED ---\n") ); exit (0); @@ -673,6 +692,7 @@ void SetOccluderArea( int nOccluder, int nArea, int nEntityNum ) { g_OccluderData[nOccluder].area = nArea; } +#ifndef MAPBASE else if ( (nArea != 0) && (g_OccluderData[nOccluder].area != nArea) ) { const char *pTargetName = ValueForKey( &entities[nEntityNum], "targetname" ); @@ -682,6 +702,7 @@ void SetOccluderArea( int nOccluder, int nArea, int nEntityNum ) } Warning("Occluder \"%s\" straddles multiple areas. This is invalid!\n", pTargetName ); } +#endif } @@ -862,7 +883,12 @@ void ProcessModels (void) } // Turn the skybox into a cubemap in case we don't build env_cubemap textures. +#ifdef MAPBASE + if (!g_bNoDefaultCubemaps) + Cubemap_CreateDefaultCubemaps(); +#else Cubemap_CreateDefaultCubemaps(); +#endif EndBSPFile (); } @@ -901,12 +927,6 @@ int RunVBSP( int argc, char **argv ) Q_FileBase( source, mapbase, sizeof( mapbase ) ); strlwr( mapbase ); - // Maintaining legacy behavior here to avoid breaking tools: regardless of the extension we are passed, we strip it - // to get the "source" name, and append extensions as desired... - char mapFile[1024]; - V_strncpy( mapFile, source, sizeof( mapFile ) ); - V_strncat( mapFile, ".bsp", sizeof( mapFile ) ); - LoadCmdLineFromFile( argc, argv, mapbase, "vbsp" ); Msg( "Valve Software - vbsp.exe (%s)\n", __DATE__ ); @@ -1003,11 +1023,19 @@ int RunVBSP( int argc, char **argv ) Msg ("microvolume = %f\n", microvolume); i++; } +#ifdef MAPBASE + else if (!Q_stricmp(argv[i], "-noleaktest")) + { + Msg ("noleaktest = true\n"); + noleaktest = true; + } +#else else if (!Q_stricmp(argv[i], "-leaktest")) { Msg ("leaktest = true\n"); leaktest = true; } +#endif else if (!Q_stricmp(argv[i], "-verboseentities")) { Msg ("verboseentities = true\n"); @@ -1077,8 +1105,8 @@ int RunVBSP( int argc, char **argv ) else if( !strcmp( argv[i], "-minluxelscale" ) ) { g_minLuxelScale = atof( argv[i+1] ); - //if (g_minLuxelScale < 1) - // g_minLuxelScale = 1; + if (g_minLuxelScale < 1) + g_minLuxelScale = 1; i++; } else if( !Q_stricmp( argv[i], "-dxlevel" ) ) @@ -1106,7 +1134,7 @@ int RunVBSP( int argc, char **argv ) { // nothing to do here, but don't bail on this option } - else if ( !Q_stricmp( argv[i], "-vproject" ) || !Q_stricmp( argv[i], "-game" ) || !Q_stricmp( argv[i], "-insert_search_path" ) ) + else if ( !Q_stricmp( argv[i], "-vproject" ) || !Q_stricmp( argv[i], "-game" ) ) { ++i; } @@ -1140,32 +1168,108 @@ int RunVBSP( int argc, char **argv ) { EnableFullMinidumps( true ); } - else if ( !Q_stricmp( argv[i], "-embed" ) && i < argc - 1 ) + else if ( !Q_stricmp( argv[i], "-nohiddenmaps" ) ) { - V_MakeAbsolutePath( g_szEmbedDir, sizeof( g_szEmbedDir ), argv[++i], "." ); - V_FixSlashes( g_szEmbedDir ); - if ( !V_RemoveDotSlashes( g_szEmbedDir ) ) - { - Error( "Bad -embed - Can't resolve pathname for '%s'", g_szEmbedDir ); - break; - } - V_StripTrailingSlash( g_szEmbedDir ); - g_pFullFileSystem->AddSearchPath( g_szEmbedDir, "GAME", PATH_ADD_TO_TAIL ); - g_pFullFileSystem->AddSearchPath( g_szEmbedDir, "MOD", PATH_ADD_TO_TAIL ); + g_bNoHiddenManifestMaps = true; } - else if (!Q_stricmp(argv[i], "-skyboxcubemap")) +#ifdef MAPBASE + // Thanks to Mapbase's shader changes, default all-black cubemaps are no longer needed. + // The command has been switched from "-nodefaultcubemap" to "-defaultcubemap", + // meaning maps are compiled without them by default. + else if ( !Q_stricmp( argv[i], "-defaultcubemap" ) ) { - g_SkyboxCubemap = true; + g_bNoDefaultCubemaps = false; } - else if (!Q_stricmp(argv[i], "-skyboxcubemapdump")) + // Default cubemaps are supposed to show the sky texture, but Valve disabled this + // because they didn't get it working for HDR cubemaps. As a result, all default + // cubemaps appear as all-black textures. However, this parameter has been added to + // re-enable skybox cubemaps for LDR cubemaps. (HDR skybox cubemaps are not supported) + else if ( !Q_stricmp( argv[i], "-skyboxcubemap" ) ) { - g_SkyboxCubemapDump = true; + g_bNoDefaultCubemaps = false; + g_bSkyboxCubemaps = true; } - else if (!Q_stricmp(argv[i], "-skyboxcubemapres")) + else if ( !Q_stricmp( argv[i], "-defaultcubemapres" ) ) { - g_SkyboxCubemapRes = atoi(argv[i + 1]); + g_iDefaultCubemapSize = atoi( argv[i + 1] ); + Msg( "Default cubemap size = %i\n", g_iDefaultCubemapSize ); i++; } + else if ( !Q_stricmp( argv[i], "-defaultproppermodelsstatic" ) ) + { + g_bPropperInsertAllAsStatic = true; + } + else if ( !Q_stricmp( argv[i], "-strippropperentities" ) ) + { + g_bPropperStripEntities = true; + } +#endif +#ifdef MAPBASE_VSCRIPT + else if ( !Q_stricmp( argv[i], "-scripting" ) ) + { + const char *pszScriptLanguage = argv[i + 1]; + if( pszScriptLanguage[0] == '-') + { + // It's another command. Just use default + g_iScripting = SL_DEFAULT; + } + else + { + // Use a specific language + if( !Q_stricmp(pszScriptLanguage, "gamemonkey") ) + { + g_iScripting = SL_GAMEMONKEY; + } + else if( !Q_stricmp(pszScriptLanguage, "squirrel") ) + { + g_iScripting = SL_SQUIRREL; + } + else if( !Q_stricmp(pszScriptLanguage, "python") ) + { + g_iScripting = SL_PYTHON; + } + else if( !Q_stricmp(pszScriptLanguage, "lua") ) + { + g_iScripting = SL_LUA; + } + else + { + DevWarning("-server_script does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage ); + g_iScripting = SL_NONE; + } + i++; + } + } + else if ( !Q_stricmp( argv[i], "-doc" ) ) + { + // Only print the documentation + + if (g_iScripting) + { + scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL); + VScriptVBSPInit(); + + const char *pszArg1 = argv[i + 1]; + if (pszArg1[0] == '-') + { + // It's another command. Just use * + pszArg1 = "*"; + } + + char szCommand[512]; + _snprintf( szCommand, sizeof( szCommand ), "__Documentation.PrintHelp( \"%s\" );", pszArg1 ); + g_pScriptVM->Run( szCommand ); + } + else + { + Warning("Cannot print documentation without scripting enabled!\n"); + } + + DeleteCmdLine( argc, argv ); + CmdLib_Cleanup(); + CmdLib_Exit( 1 ); + } +#endif else if (argv[i][0] == '-') { Warning("VBSP: Unknown option \"%s\"\n\n", argv[i]); @@ -1199,9 +1303,6 @@ int RunVBSP( int argc, char **argv ) " what affects visibility.\n" " -nowater : Get rid of water brushes.\n" " -low : Run as an idle-priority process.\n" - " -embed : Use as an additional search path for assets\n" - " and embed all assets in this directory into the compiled\n" - " map\n" "\n" " -vproject : Override the VPROJECT environment variable.\n" " -game : Same as -vproject.\n" @@ -1252,9 +1353,7 @@ int RunVBSP( int argc, char **argv ) " -nox360 : Disable generation Xbox360 version of vsp (default)\n" " -replacematerials : Substitute materials according to materialsub.txt in content\\maps\n" " -FullMinidumps : Write large minidumps on crash.\n" - " -skyboxcubemap : Generate default cubemap based on skybox texture.\n" - " -skyboxcubemapres : Resolution of the generated cubemap texture (default: 32).\n" - " -skyboxcubemapdump : Save generated cubemap texture in 'materials/maps/map_name/'.\n" + " -nohiddenmaps : Exclude manifest maps if they are currently hidden.\n" ); } @@ -1263,17 +1362,6 @@ int RunVBSP( int argc, char **argv ) CmdLib_Exit( 1 ); } - // Sanity check - if ( *g_szEmbedDir && ( onlyents || onlyprops ) ) - { - Warning( "-embed only makes sense alongside full BSP compiles.\n" - "\n" - "Use the bspzip utility to update embedded files.\n" ); - DeleteCmdLine( argc, argv ); - CmdLib_Cleanup(); - CmdLib_Exit( 1 ); - } - start = Plat_FloatTime(); // Run in the background? @@ -1316,6 +1404,15 @@ int RunVBSP( int argc, char **argv ) InitMaterialSystem( materialPath, CmdLib_GetFileSystemFactory() ); Msg( "materialPath: %s\n", materialPath ); +#ifdef MAPBASE_VSCRIPT + if (g_iScripting) + { + scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL); + + VScriptVBSPInit(); + } +#endif + // delete portal and line files sprintf (path, "%s.prt", source); remove (path); @@ -1334,6 +1431,9 @@ int RunVBSP( int argc, char **argv ) } } + char platformBSPFileName[1024]; + GetPlatformMapPath( source, platformBSPFileName, g_nDXLevel, 1024 ); + // if we're combining materials, load the script file if ( g_ReplaceMaterials ) { @@ -1345,7 +1445,7 @@ int RunVBSP( int argc, char **argv ) // if (onlyents) { - LoadBSPFile (mapFile); + LoadBSPFile (platformBSPFileName); num_entities = 0; // Clear out the cubemap samples since they will be reparsed even with -onlyents g_nCubemapSamples = 0; @@ -1377,12 +1477,12 @@ int RunVBSP( int argc, char **argv ) // Doing this here because stuff abov may filter out entities UnparseEntities (); - WriteBSPFile (mapFile); + WriteBSPFile (platformBSPFileName); } else if (onlyprops) { // In the only props case, deal with static + detail props only - LoadBSPFile (mapFile); + LoadBSPFile (platformBSPFileName); LoadMapFile(name); SetModelNumbers(); @@ -1395,7 +1495,7 @@ int RunVBSP( int argc, char **argv ) LoadEmitDetailObjectDictionary( gamedir ); EmitDetailObjects(); - WriteBSPFile (mapFile); + WriteBSPFile (platformBSPFileName); } else { @@ -1404,9 +1504,9 @@ int RunVBSP( int argc, char **argv ) // // Load just the file system from the bsp - if( g_bKeepStaleZip && FileExists( mapFile ) ) + if( g_bKeepStaleZip && FileExists( platformBSPFileName ) ) { - LoadBSPFile_FileSystemOnly (mapFile); + LoadBSPFile_FileSystemOnly (platformBSPFileName); // Mark as stale since the lighting could be screwed with new ents. AddBufferToPak( GetPakFile(), "stale.txt", "stale", strlen( "stale" ) + 1, false ); } @@ -1423,13 +1523,6 @@ int RunVBSP( int argc, char **argv ) SetLightStyles (); LoadEmitDetailObjectDictionary( gamedir ); ProcessModels (); - - // Add embed dir if provided - if ( *g_szEmbedDir ) - { - AddDirToPak( GetPakFile(), g_szEmbedDir ); - WriteBSPFile( mapFile ); - } } end = Plat_FloatTime(); @@ -1442,6 +1535,9 @@ int RunVBSP( int argc, char **argv ) ReleasePakFileLumps(); DeleteMaterialReplacementKeys(); ShutdownMaterialSystem(); +#ifdef MAPBASE_VSCRIPT + VScriptVBSPTerm(); +#endif CmdLib_Cleanup(); return 0; } diff --git a/utils/vbsp/vbsp.h b/utils/vbsp/vbsp.h index df3144ac..9147876a 100644 --- a/utils/vbsp/vbsp.h +++ b/utils/vbsp/vbsp.h @@ -19,6 +19,9 @@ #include "qfiles.h" #include "utilmatlib.h" #include "ChunkFile.h" +#ifdef MAPBASE_VSCRIPT +#include "vscript/ivscript.h" +#endif #ifdef WIN32 #pragma warning( disable: 4706 ) @@ -34,6 +37,12 @@ class CUtlBuffer; // this will output glview files for the given brushmodel. Brushmodel 1 is the world, 2 is the first brush entity, etc. #define DEBUG_BRUSHMODEL 0 +#ifdef MAPBASE +// Activates compiler code for parallax corrected cubemaps +// https://developer.valvesoftware.com/wiki/Parallax_Corrected_Cubemaps +#define PARALLAX_CORRECTED_CUBEMAPS 1 +#endif + struct portal_t; struct node_t; @@ -170,9 +179,6 @@ extern float g_luxelScale; extern float g_minLuxelScale; extern bool g_BumpAll; extern int g_nDXLevel; -extern bool g_SkyboxCubemap; -extern bool g_SkyboxCubemapDump; -extern int g_SkyboxCubemapRes; int GetDispInfoEntityNum( mapdispinfo_t *pDisp ); void ComputeBoundsNoSkybox( ); @@ -337,6 +343,34 @@ class CMapFile int m_StartMapOverlays; int m_StartMapWaterOverlays; + +#ifdef MAPBASE_VSCRIPT + HSCRIPT GetScriptInstance(); + + static ScriptHook_t g_Hook_OnMapLoaded; + + // VScript functions + ALLOW_SCRIPT_ACCESS(); +private: + + const Vector& GetMins() { return map_mins; } + const Vector& GetMaxs() { return map_maxs; } + + int GetNumMapBrushes() { return nummapbrushes; } + + const Vector& GetEntityOrigin(int idx) { return (idx < num_entities && idx >= 0) ? entities[idx].origin : vec3_origin; } + int GetEntityFirstBrush(int idx) { return (idx < num_entities && idx >= 0) ? entities[idx].firstbrush : 0; } + int GetEntityNumBrushes(int idx) { return (idx < num_entities && idx >= 0) ? entities[idx].numbrushes : 0; } + + void ScriptGetEntityKeyValues(int idx, HSCRIPT hKeyTable, HSCRIPT hValTable); + + int ScriptAddSimpleEntityKV(HSCRIPT hKV/*, const Vector& vecOrigin, int iFirstBrush, int iNumBrushes*/); + int ScriptAddInstance(const char *pszVMF, const Vector& vecOrigin, const QAngle& angAngles); + + int GetNumEntities() { return num_entities; } + + HSCRIPT m_hScriptInstance; +#endif }; extern CMapFile *g_MainMap; @@ -368,6 +402,11 @@ extern bool g_NodrawTriggers; extern bool g_DisableWaterLighting; extern bool g_bAllowDetailCracks; extern bool g_bNoVirtualMesh; +extern bool g_bNoHiddenManifestMaps; +#ifdef MAPBASE +extern bool g_bPropperInsertAllAsStatic; +extern bool g_bPropperStripEntities; +#endif extern char outbase[32]; extern char source[1024]; @@ -610,7 +649,12 @@ void SaveVertexNormals( void ); //============================================================================= // cubemap.cpp -void Cubemap_InsertSample( const Vector& origin, int size, float radius = 0.0f ); +#ifdef PARALLAX_CORRECTED_CUBEMAPS +extern char* g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES]; +void Cubemap_InsertSample( const Vector& origin, int size, char* pParallaxObbStr ); +#else +void Cubemap_InsertSample( const Vector& origin, int size ); +#endif void Cubemap_CreateDefaultCubemaps( void ); void Cubemap_SaveBrushSides( const char *pSideListStr ); void Cubemap_FixupBrushSidesMaterials( void ); diff --git a/utils/vbsp/vbsp.vpc b/utils/vbsp/vbsp.vpc index e55762f2..ff52752c 100644 --- a/utils/vbsp/vbsp.vpc +++ b/utils/vbsp/vbsp.vpc @@ -6,6 +6,7 @@ $Macro SRCDIR "..\.." $Macro OUTBINDIR "$SRCDIR\..\game\bin" +$Macro OUTBINNAME "vbsp" $Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc" @@ -15,6 +16,8 @@ $Configuration { $AdditionalIncludeDirectories "$BASE,..\common,..\vmpi" $PreprocessorDefinitions "$BASE;MACRO_MATHLIB;PROTECTED_THINGS_DISABLE" + + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] } $Linker @@ -65,6 +68,14 @@ $Project "Vbsp" $File "worldvertextransitionfixup.cpp" $File "writebsp.cpp" $File "$SRCDIR\public\zip_utils.cpp" + + $File "vscript_vbsp.cpp" [$MAPBASE_VSCRIPT] + $File "vscript_vbsp.h" [$MAPBASE_VSCRIPT] + $File "vscript_vbsp.nut" [$MAPBASE_VSCRIPT] + $File "vscript_funcs_vmfs.cpp" [$MAPBASE_VSCRIPT] + $File "vscript_funcs_vmfs.h" [$MAPBASE_VSCRIPT] + $File "vscript_funcs_vis.cpp" [$MAPBASE_VSCRIPT] + $File "vscript_funcs_vis.h" [$MAPBASE_VSCRIPT] $Folder "Common Files" { @@ -178,7 +189,7 @@ $Project "Vbsp" $Lib mathlib $Lib tier2 $Lib vtf - $Lib "$LIBCOMMON/lzma" + $Lib vscript [$MAPBASE_VSCRIPT] } $File "notes.txt" diff --git a/utils/vbsp/vscript_funcs_vis.cpp b/utils/vbsp/vscript_funcs_vis.cpp new file mode 100644 index 00000000..7a5fbfb6 --- /dev/null +++ b/utils/vbsp/vscript_funcs_vis.cpp @@ -0,0 +1,29 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "tier1/KeyValues.h" +#include "tier1/fmtstr.h" + +#include "vbsp.h" +#include "map.h" +#include "fgdlib/fgdlib.h" + +#include "vscript_vbsp.h" +#include "vscript_funcs_vis.h" + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +// There are currently no vis-related functions, but it would be nice to have them in the future. + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void RegisterVisScriptFunctions() +{ + //ScriptRegisterFunction( g_pScriptVM, VMFKV_CreateBlank, "Creates a CScriptKeyValues instance with VMF formatting." ); +} diff --git a/utils/vbsp/vscript_funcs_vis.h b/utils/vbsp/vscript_funcs_vis.h new file mode 100644 index 00000000..906b7d7a --- /dev/null +++ b/utils/vbsp/vscript_funcs_vis.h @@ -0,0 +1,16 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_FUNCS_VIS +#define VSCRIPT_FUNCS_VIS +#ifdef _WIN32 +#pragma once +#endif + +void RegisterVisScriptFunctions(); + +#endif diff --git a/utils/vbsp/vscript_funcs_vmfs.cpp b/utils/vbsp/vscript_funcs_vmfs.cpp new file mode 100644 index 00000000..8ef38c81 --- /dev/null +++ b/utils/vbsp/vscript_funcs_vmfs.cpp @@ -0,0 +1,157 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "tier1/KeyValues.h" +#include "tier1/fmtstr.h" + +#include "vbsp.h" +#include "map.h" +#include "fgdlib/fgdlib.h" + +#include "vscript_vbsp.h" +#include "vscript_funcs_vmfs.h" + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +static HSCRIPT VMFKV_CreateBlank() +{ + KeyValues *pKV = new KeyValues("VMF"); + + KeyValues *pWorld = pKV->FindKey( "world", true ); + if (pWorld) + { + pWorld->SetString( "classname", "worldspawn" ); + } + + return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true ); +} + +static bool VMFKV_SaveToFile( const char *szFile, HSCRIPT hKV ) +{ + Warning( "Getting keyvalues from thing\n" ); + + KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV ); + if (!pKV) + return false; + + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + for (KeyValues *pSubKey = pKV->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey()) + { + pSubKey->RecursiveSaveToFile( buf, 0 ); + } + + char pszFullName[MAX_PATH]; + Q_ExtractFilePath( source, pszFullName, sizeof(pszFullName) ); + V_snprintf( pszFullName, sizeof(pszFullName), "%s/vscript_io/%s", pszFullName, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + Warning( "Invalid file location : %s\n", szFile ); + buf.Purge(); + return false; + } + + int nSize = V_strlen(pszFullName) + 1; + char *pszDir = (char*)stackalloc(nSize); + V_memcpy( pszDir, pszFullName, nSize ); + V_StripFilename( pszDir ); + + //g_pFullFileSystem->RelativePathToFullPath( szFile, NULL, pszFullName, sizeof( pszFullName ) ); + Warning( "Full path is %s!\n", pszFullName ); + g_pFullFileSystem->CreateDirHierarchy( pszDir, NULL ); + bool res = g_pFullFileSystem->WriteFile( pszFullName, NULL, buf ); + buf.Purge(); + return res; +} + +static HSCRIPT VMFKV_LoadFromFile( const char *szFile ) +{ + char pszFullName[MAX_PATH]; + V_snprintf( pszFullName, sizeof(pszFullName), NULL, szFile ); + + if ( !V_RemoveDotSlashes( pszFullName, CORRECT_PATH_SEPARATOR, true ) ) + { + DevWarning( 2, "Invalid file location : %s\n", szFile ); + return NULL; + } + + KeyValues *pKV = new KeyValues( szFile ); + if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFullName, NULL ) ) + { + pKV->deleteThis(); + return NULL; + } + + HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true ); // bAllowDestruct is supposed to automatically remove the involved KV + + return hScript; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +inline void ScriptVarsToKV( ScriptVariant_t &varKey, ScriptVariant_t &varValue, KeyValues *pKV ) +{ + switch (varValue.m_type) + { + case FIELD_CSTRING: pKV->SetString( varKey.m_pszString, varValue.m_pszString ); break; + case FIELD_INTEGER: pKV->SetInt( varKey.m_pszString, varValue.m_int ); break; + case FIELD_FLOAT: pKV->SetFloat( varKey.m_pszString, varValue.m_float ); break; + case FIELD_BOOLEAN: pKV->SetBool( varKey.m_pszString, varValue.m_bool ); break; + case FIELD_VECTOR: pKV->SetString( varKey.m_pszString, CFmtStr( "%f %f %f", varValue.m_pVector->x, varValue.m_pVector->y, varValue.m_pVector->z ) ); break; + } +} + +static HSCRIPT VMFKV_AddEntityFromTables( HSCRIPT hVMF, HSCRIPT hKV, HSCRIPT hIO ) +{ + KeyValues *pVMF = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hVMF ); + if (!pVMF) + return false; + + KeyValues *pEnt = pVMF->CreateNewKey(); + if (!pEnt) + return false; + + pEnt->SetName( "entity" ); + + int nIterator = -1; + ScriptVariant_t varKey, varValue; + while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1) + { + ScriptVarsToKV( varKey, varValue, pEnt ); + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } + + KeyValues *pConnections = pEnt->FindKey( "connections", true ); + if (hIO && pConnections) + { + nIterator = -1; + while ((nIterator = g_pScriptVM->GetKeyValue( hIO, nIterator, &varKey, &varValue )) != -1) + { + ScriptVarsToKV( varKey, varValue, pEnt ); + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } + } + + return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pEnt, false ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void RegisterVMFScriptFunctions() +{ + ScriptRegisterFunction( g_pScriptVM, VMFKV_CreateBlank, "Creates a CScriptKeyValues instance with VMF formatting." ); + ScriptRegisterFunction( g_pScriptVM, VMFKV_SaveToFile, "Saves a CScriptKeyValues instance with VMF formatting." ); + ScriptRegisterFunction( g_pScriptVM, VMFKV_LoadFromFile, "Loads a VMF as a CScriptKeyValues instance with VMF formatting." ); + ScriptRegisterFunction( g_pScriptVM, VMFKV_AddEntityFromTables, "Adds a VMF-formatted entity to a CScriptKeyValues instance." ); +} diff --git a/utils/vbsp/vscript_funcs_vmfs.h b/utils/vbsp/vscript_funcs_vmfs.h new file mode 100644 index 00000000..0b3237a7 --- /dev/null +++ b/utils/vbsp/vscript_funcs_vmfs.h @@ -0,0 +1,16 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_FUNCS_VMFS +#define VSCRIPT_FUNCS_VMFS +#ifdef _WIN32 +#pragma once +#endif + +void RegisterVMFScriptFunctions(); + +#endif diff --git a/utils/vbsp/vscript_vbsp.cpp b/utils/vbsp/vscript_vbsp.cpp new file mode 100644 index 00000000..bcb94845 --- /dev/null +++ b/utils/vbsp/vscript_vbsp.cpp @@ -0,0 +1,369 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase's implementation of VScript in VBSP, allowing users to modify map compilation behavior with scripts. +// +// $NoKeywords: $ +//=============================================================================// + +#include "tier1/KeyValues.h" +#include "tier1/fmtstr.h" + +#include "vbsp.h" +#include "map.h" +#include "fgdlib/fgdlib.h" +#include "convar.h" + +#include "vscript_vbsp.h" +#include "vscript_vbsp.nut" +#include "vscript_funcs_vmfs.h" +#include "vscript_funcs_vis.h" + +IScriptVM *g_pScriptVM; +IScriptManager *scriptmanager = NULL; + +extern ScriptLanguage_t g_iScripting; + +extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); + +// #define VMPROFILE 1 + +#ifdef VMPROFILE + +#define VMPROF_START float debugStartTime = Plat_FloatTime(); +#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 ); + +#else // !VMPROFILE + +#define VMPROF_START +#define VMPROF_SHOW + +#endif // VMPROFILE + +// This is to ensure a dependency exists between the vscript library and the game DLLs +extern int vscript_token; +int vscript_token_hack = vscript_token; + +// HACKHACK: VScript library relies on developer convar existing +ConVar developer( "developer", "1", 0, "Set developer message level." ); // developer mode + +HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing ) +{ + if ( !g_pScriptVM ) + { + return NULL; + } + + static const char *pszExtensions[] = + { + "", // SL_NONE + ".gm", // SL_GAMEMONKEY + ".nut", // SL_SQUIRREL + ".lua", // SL_LUA + ".py", // SL_PYTHON + }; + + const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()]; + const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); + if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) + { + Warning( "Script file type does not match VM type\n" ); + return NULL; + } + + CFmtStr scriptPath; + if ( pszIncomingExtension ) + { + scriptPath = pszScriptName; + } + else + { + scriptPath.sprintf( "%s%s", pszScriptName, pszVMExtension ); + } + + const char *pBase; + CUtlBuffer bufferScript; + + if ( g_pScriptVM->GetLanguage() == SL_PYTHON ) + { + // python auto-loads raw or precompiled modules - don't load data here + pBase = NULL; + } + else + { + /* + FileFindHandle_t handle = NULL; + const char *file = g_pFullFileSystem->FindFirst( "*", &handle ); + while (file) + { + Msg( "File in this directory: %s\n", file ); + file = g_pFullFileSystem->FindNext(handle); + } + + Msg( "File exists: %d\n", g_pFullFileSystem->FileExists( scriptPath ) ); + */ + + + bool bResult = g_pFullFileSystem->ReadFile( scriptPath, NULL, bufferScript ); + + if ( !bResult && bWarnMissing ) + { + Warning( "Script not found (%s) \n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + + pBase = (const char *) bufferScript.Base(); + + if ( !pBase || !*pBase ) + { + return NULL; + } + } + + + const char *pszFilename = V_strrchr( scriptPath, '\\' ); + pszFilename++; + HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, pszFilename ); + if ( !hScript ) + { + Warning( "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + return hScript; +} + +static int g_ScriptVBSPRunScriptDepth; + +bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing ) +{ + if ( !g_pScriptVM ) + { + return false; + } + + if ( !pszScriptName || !*pszScriptName ) + { + Warning( "Cannot run script: NULL script name\n" ); + return false; + } + + // Prevent infinite recursion in VM + if ( g_ScriptVBSPRunScriptDepth > 16 ) + { + Warning( "IncludeScript stack overflow\n" ); + return false; + } + + g_ScriptVBSPRunScriptDepth++; + HSCRIPT hScript = VScriptCompileScript( pszScriptName, bWarnMissing ); + bool bSuccess = false; + if ( hScript ) + { + bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR ); + if ( !bSuccess ) + { + Warning( "Error running script named %s\n", pszScriptName ); + Assert( "Error running script" ); + } + } + g_ScriptVBSPRunScriptDepth--; + return bSuccess; +} + +ScriptHook_t CMapFile::g_Hook_OnMapLoaded; + +BEGIN_SCRIPTDESC_ROOT( CMapFile, "Map file" ) + + DEFINE_SCRIPTFUNC( GetMins, "Get the map's mins." ) + DEFINE_SCRIPTFUNC( GetMaxs, "Get the map's maxs." ) + + DEFINE_SCRIPTFUNC( GetEntityOrigin, "Get the origin of the entity with the specified index." ) + DEFINE_SCRIPTFUNC( GetEntityFirstBrush, "Get the first brush ID of the entity with the specified index." ) + DEFINE_SCRIPTFUNC( GetEntityNumBrushes, "Get the number of brushes in the entity with the specified index." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetEntityKeyValues, "GetEntityKeyValues", "Export an entity's keyvalues to two arrays." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptAddSimpleEntityKV, "AddSimpleEntityKV", "Add a simple entity from a keyvalue table." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptAddInstance, "AddInstance", "Add an instance to the map." ) + + DEFINE_SCRIPTFUNC( GetNumEntities, "Get the number of entities in the map." ) + + // + // Hooks + // + DEFINE_SIMPLE_SCRIPTHOOK( CMapFile::g_Hook_OnMapLoaded, "OnMapLoaded", FIELD_VOID, "Called when the NPC is deciding whether to hear a CSound or not." ) + +END_SCRIPTDESC(); + + +static float cvar_getf( const char* sz ) +{ + ConVarRef cvar(sz); + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return NULL; + return cvar.GetFloat(); +} + +static bool cvar_setf( const char* sz, float val ) +{ + ConVarRef cvar(sz); + if ( !cvar.IsValid() ) + return false; + + if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) ) + return false; + + cvar.SetValue(val); + return true; +} + +static const char *GetSource() +{ + return source; +} + +static const char *GetMapBase() +{ + return mapbase; +} + +static HSCRIPT GetMainMap() +{ + return g_MainMap ? g_MainMap->GetScriptInstance() : NULL; +} + +static HSCRIPT GetLoadingMap() +{ + return g_LoadingMap ? g_LoadingMap->GetScriptInstance() : NULL; +} + +static const char *DoUniqueString( const char *pszBase ) +{ + static char szBuf[512]; + g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) ); + return szBuf; +} + +bool DoIncludeScript( const char *pszScript, HSCRIPT hScope ) +{ + if ( !VScriptRunScript( pszScript, hScope, true ) ) + { + g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) ); + return false; + } + return true; +} + +extern qboolean glview; +extern qboolean onlyents; +extern bool onlyprops; +extern qboolean noleaktest; +extern qboolean verboseentities; +extern qboolean g_bLowPriority; +extern bool g_bKeepStaleZip; +extern bool g_bNoDefaultCubemaps; +extern bool g_bSkyboxCubemaps; +extern int g_iDefaultCubemapSize; + +bool VScriptVBSPInit() +{ + VMPROF_START + + if( g_iScripting != SL_NONE && scriptmanager != NULL ) + { + if ( g_pScriptVM == NULL ) + g_pScriptVM = scriptmanager->CreateVM( g_iScripting ); + + if( g_pScriptVM ) + { + Log( "VSCRIPT VBSP: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); + + ScriptRegisterFunction( g_pScriptVM, cvar_getf, "Gets the value of the given cvar, as a float." ); + ScriptRegisterFunction( g_pScriptVM, cvar_setf, "Sets the value of the given cvar, as a float." ); + + ScriptRegisterFunction( g_pScriptVM, GetSource, "Gets the base directory of the first map loaded." ); + ScriptRegisterFunction( g_pScriptVM, GetMapBase, "Gets the base name of the first map loaded." ); + ScriptRegisterFunction( g_pScriptVM, GetMainMap, "Gets the first map loaded." ); + ScriptRegisterFunction( g_pScriptVM, GetLoadingMap, "Gets the map which is currently loading (e.g. an instance)." ); + + ScriptRegisterFunction( g_pScriptVM, DoUniqueString, SCRIPT_ALIAS( "UniqueString", "Generate a string guaranteed to be unique across the life of the script VM, with an optional root string. Useful for adding data to tables when not sure what keys are already in use in that table." ) ); + ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" ); + + ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_PREFIX, "NAME_FIXUP_PREFIX", "Prefix name fixup" ); + ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_POSTFIX, "NAME_FIXUP_PREFIX", "Postfix name fixup" ); + ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_NONE, "NAME_FIXUP_NONE", "No name fixup" ); + + ScriptRegisterConstant( g_pScriptVM, microvolume, "" ); + ScriptRegisterConstant( g_pScriptVM, noprune, "" ); + ScriptRegisterConstant( g_pScriptVM, glview, "" ); + ScriptRegisterConstant( g_pScriptVM, nodetail, "" ); + ScriptRegisterConstant( g_pScriptVM, fulldetail, "" ); + ScriptRegisterConstant( g_pScriptVM, onlyents, "" ); + ScriptRegisterConstant( g_pScriptVM, onlyprops, "" ); + ScriptRegisterConstant( g_pScriptVM, nomerge, "" ); + ScriptRegisterConstant( g_pScriptVM, nomergewater, "" ); + ScriptRegisterConstant( g_pScriptVM, nowater, "" ); + ScriptRegisterConstant( g_pScriptVM, nocsg, "" ); + ScriptRegisterConstant( g_pScriptVM, noweld, "" ); + ScriptRegisterConstant( g_pScriptVM, noshare, "" ); + ScriptRegisterConstant( g_pScriptVM, nosubdiv, "" ); + ScriptRegisterConstant( g_pScriptVM, notjunc, "" ); + ScriptRegisterConstant( g_pScriptVM, noopt, "" ); + ScriptRegisterConstant( g_pScriptVM, noleaktest, "" ); + ScriptRegisterConstant( g_pScriptVM, verboseentities, "" ); + ScriptRegisterConstant( g_pScriptVM, dumpcollide, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bLowPriority, "" ); + ScriptRegisterConstant( g_pScriptVM, g_DumpStaticProps, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bSkyVis, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bLightIfMissing, "" ); + ScriptRegisterConstant( g_pScriptVM, g_snapAxialPlanes, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bKeepStaleZip, "" ); + ScriptRegisterConstant( g_pScriptVM, g_NodrawTriggers, "" ); + ScriptRegisterConstant( g_pScriptVM, g_DisableWaterLighting, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bAllowDetailCracks, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bNoVirtualMesh, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bNoHiddenManifestMaps, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bNoDefaultCubemaps, "" ); + ScriptRegisterConstant( g_pScriptVM, g_bSkyboxCubemaps, "" ); + ScriptRegisterConstant( g_pScriptVM, g_iDefaultCubemapSize, "" ); + + if (g_iScripting == SL_SQUIRREL) + { + g_pScriptVM->Run( g_Script_vscript_vbsp ); + } + + RegisterVMFScriptFunctions(); + + // Run the map's script + char script[96]; + Q_snprintf( script, sizeof(script), "%s_vbsp", source ); + //Msg("VBSP script: \"%s\"\n", script); + VScriptRunScript( script, true ); + + VMPROF_SHOW( g_iScripting, "virtual machine startup" ); + + return true; + } + else + { + DevWarning("VM Did not start!\n"); + } + } + else + { + Log( "\nVSCRIPT: Scripting is disabled.\n" ); + } + g_pScriptVM = NULL; + return false; +} + +void VScriptVBSPTerm() +{ + if( g_pScriptVM != NULL ) + { + if( g_pScriptVM ) + { + scriptmanager->DestroyVM( g_pScriptVM ); + g_pScriptVM = NULL; + } + } +} diff --git a/utils/vbsp/vscript_vbsp.h b/utils/vbsp/vscript_vbsp.h new file mode 100644 index 00000000..1a6e390a --- /dev/null +++ b/utils/vbsp/vscript_vbsp.h @@ -0,0 +1,27 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Mapbase's implementation of VScript in VBSP, allowing users to modify map compilation behavior with scripts. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VSCRIPT_VBSP_H +#define VSCRIPT_VBSP_H + +#include "vscript/ivscript.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +extern IScriptVM *g_pScriptVM; +extern IScriptManager *scriptmanager; + +HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing = false ); +bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing = false ); +inline bool VScriptRunScript( const char *pszScriptName, bool bWarnMissing = false ) { return VScriptRunScript( pszScriptName, NULL, bWarnMissing ); } + +bool VScriptVBSPInit(); +void VScriptVBSPTerm(); + +#endif // VSCRIPT_SERVER_H diff --git a/utils/vbsp/vscript_vbsp.nut b/utils/vbsp/vscript_vbsp.nut new file mode 100644 index 00000000..2aa99060 --- /dev/null +++ b/utils/vbsp/vscript_vbsp.nut @@ -0,0 +1,52 @@ +static char g_Script_vscript_vbsp[] = R"vscript( +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +function UniqueString( string = "" ) +{ + return ::DoUniqueString( string.tostring() ); +} + +function __ReplaceClosures( script, scope ) +{ + if ( !scope ) + { + scope = getroottable(); + } + + local tempParent = { getroottable = function() { return null; } }; + local temp = { runscript = script }; + temp.set_delegate(tempParent); + + temp.runscript() + foreach( key,val in temp ) + { + if ( typeof(val) == "function" && key != "runscript" ) + { + printl( " Replacing " + key ); + scope[key] <- val; + } + } +} + +function IncludeScript( name, scope = null ) +{ + if ( !scope ) + { + scope = this; + } + return ::DoIncludeScript( name, scope ); +} + +// VBSP logs don't support ConColorMsg() +print <- Msg + +function printdoc( text ) +{ + return ::print(text + "\n"); +} + +)vscript"; \ No newline at end of file diff --git a/utils/vbsp/writebsp.cpp b/utils/vbsp/writebsp.cpp index 005990d6..60d05980 100644 --- a/utils/vbsp/writebsp.cpp +++ b/utils/vbsp/writebsp.cpp @@ -1271,24 +1271,23 @@ void EndBSPFile (void) // Compute bounds after creating disp info because we need to reference it ComputeBoundsNoSkybox(); - + // Make sure that we have a water lod control eneity if we have water in the map. EnsurePresenceOfWaterLODControlEntity(); // Doing this here because stuff about may filter out entities UnparseEntities (); - + // remove unused texinfos CompactTexinfos(); // Figure out which faces want macro textures. DiscoverMacroTextures(); - - char fileName[1024]; - V_strncpy( fileName, source, sizeof( fileName ) ); - V_DefaultExtension( fileName, ".bsp", sizeof( fileName ) ); - Msg ("Writing %s\n", fileName); - WriteBSPFile (fileName); + + char targetPath[1024]; + GetPlatformMapPath( source, targetPath, g_nDXLevel, 1024 ); + Msg ("Writing %s\n", targetPath); + WriteBSPFile (targetPath); } diff --git a/utils/vrad/incremental.cpp b/utils/vrad/incremental.cpp index ad46d04d..fb15f897 100644 --- a/utils/vrad/incremental.cpp +++ b/utils/vrad/incremental.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -193,20 +193,20 @@ bool CIncremental::PrepareForLighting() for( int iUnmatched=unmatched.Head(); iUnmatched != unmatched.InvalidIndex(); iUnmatched = unmatched.Next( iUnmatched ) ) { CIncLight *pLight = m_Lights[ unmatched[iUnmatched] ]; - + // First tag faces that it touched so they get recomposited. for( unsigned short iFace=pLight->m_LightFaces.Head(); iFace != pLight->m_LightFaces.InvalidIndex(); iFace = pLight->m_LightFaces.Next( iFace ) ) { m_FacesTouched[ pLight->m_LightFaces[iFace]->m_FaceIndex ] = 1; } - + delete pLight; m_Lights.Remove( unmatched[iUnmatched] ); } // Now add a light structure for each new light. AddLightsForActiveLights(); - + return true; } @@ -246,7 +246,7 @@ bool CIncremental::WriteIncrementalHeader( long fp ) } FileWrite( fp, hdr.m_FaceLightmapSizes.Base(), sizeof(CIncrementalHeader::CLMSize) * nFaces ); - + return !FileError(); } @@ -268,7 +268,7 @@ bool CIncremental::IsIncrementalFileValid() int i; for( i=0; i < numfaces; i++ ) { - if( hdr.m_FaceLightmapSizes[i].m_Width != g_pFaces[i].m_LightmapTextureSizeInLuxels[0] || + if( hdr.m_FaceLightmapSizes[i].m_Width != g_pFaces[i].m_LightmapTextureSizeInLuxels[0] || hdr.m_FaceLightmapSizes[i].m_Height != g_pFaces[i].m_LightmapTextureSizeInLuxels[1] ) { break; @@ -286,9 +286,9 @@ bool CIncremental::IsIncrementalFileValid() } -void CIncremental::AddLightToFace( - IncrementalLightID lightID, - int iFace, +void CIncremental::AddLightToFace( + IncrementalLightID lightID, + int iFace, int iSample, int lmSize, float dot, @@ -302,7 +302,7 @@ void CIncremental::AddLightToFace( // Check for the 99.99% case in which the face already exists. CLightFace *pFace; - if( pLight->m_pCachedFaces[iThread] && + if( pLight->m_pCachedFaces[iThread] && pLight->m_pCachedFaces[iThread]->m_FaceIndex == iFace ) { pFace = pLight->m_pCachedFaces[iThread]; @@ -310,7 +310,7 @@ void CIncremental::AddLightToFace( else { bool bNew; - + EnterCriticalSection( &pLight->m_CS ); pFace = pLight->FindOrCreateLightFace( iFace, lmSize, &bNew ); LeaveCriticalSection( &pLight->m_CS ); @@ -377,9 +377,9 @@ void DecompressLightData( CUtlBuffer *pIn, CUtlVector *pOut ) #pragma warning (disable:4701) #endif -void CompressLightData( - CLightValue const *pValues, - int nValues, +void CompressLightData( + CLightValue const *pValues, + int nValues, CUtlBuffer *pBuf ) { unsigned char runLength=0; @@ -442,11 +442,11 @@ void CIncremental::FinishFace( // Compress the data. MultiplyValues( pFace->m_LightValues, pLight->m_flMaxIntensity ); - + pFace->m_CompressedData.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); - CompressLightData( - pFace->m_LightValues.Base(), - pFace->m_LightValues.Count(), + CompressLightData( + pFace->m_LightValues.Base(), + pFace->m_LightValues.Count(), &pFace->m_CompressedData ); #if 0 @@ -483,7 +483,7 @@ bool CIncremental::Finalize() CUtlVector faceLights; LinkLightsToFaces( faceLights ); - + Vector faceLight[(MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) * (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2)]; CUtlVector faceLightValues; faceLightValues.SetSize( (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) * (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) ); @@ -506,7 +506,7 @@ bool CIncremental::Finalize() for( int iFace=0; iFace < faceLights[facenum].Count(); iFace++ ) { CLightFace *pFace = faceLights[facenum][iFace]; - + pFace->m_CompressedData.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); DecompressLightData( &pFace->m_CompressedData, &faceLightValues ); @@ -515,10 +515,10 @@ bool CIncremental::Finalize() float flDot = faceLightValues[iSample].m_Dot; if( flDot ) { - VectorMA( - faceLight[iSample], + VectorMA( + faceLight[iSample], flDot / pFace->m_pLight->m_flMaxIntensity, - pFace->m_pLight->m_Light.intensity, + pFace->m_pLight->m_Light.intensity, faceLight[iSample] ); } } @@ -535,7 +535,7 @@ bool CIncremental::Finalize() pSrc++; } } - + m_bSuccessfulRun = true; return true; } @@ -574,7 +574,7 @@ void CIncremental::AddLightsForActiveLights() // Copy the light information. pLight->m_Light = dl->light; - pLight->m_flMaxIntensity = max( dl->light.intensity[0], max( dl->light.intensity[1], dl->light.intensity[2] ) ); + pLight->m_flMaxIntensity = MAX( dl->light.intensity[0], MAX( dl->light.intensity[1], dl->light.intensity[2] ) ); } } @@ -608,9 +608,9 @@ bool CIncremental::LoadIncrementalFile() m_Lights.AddToTail( pLight ); FileRead( fp, pLight->m_Light ); - pLight->m_flMaxIntensity = - max( pLight->m_Light.intensity.x, - max( pLight->m_Light.intensity.y, pLight->m_Light.intensity.z ) ); + pLight->m_flMaxIntensity = + MAX( pLight->m_Light.intensity.x, + MAX( pLight->m_Light.intensity.y, pLight->m_Light.intensity.z ) ); int nFaces; FileRead( fp, nFaces ); @@ -631,7 +631,7 @@ bool CIncremental::LoadIncrementalFile() while( dataSize ) { --dataSize; - + unsigned char ucData; FileRead( fp, ucData ); @@ -640,7 +640,7 @@ bool CIncremental::LoadIncrementalFile() } } - + FileClose( fp ); return !FileError(); } @@ -664,7 +664,7 @@ bool CIncremental::SaveIncrementalFile() for( int iLight=m_Lights.Head(); iLight != m_Lights.InvalidIndex(); iLight = m_Lights.Next( iLight ) ) { CIncLight *pLight = m_Lights[iLight]; - + FileWrite( fp, pLight->m_Light ); int nFaces = pLight->m_LightFaces.Count(); @@ -674,7 +674,7 @@ bool CIncremental::SaveIncrementalFile() CLightFace *pFace = pLight->m_LightFaces[iFace]; FileWrite( fp, pFace->m_FaceIndex ); - + int dataSize = pFace->m_CompressedData.TellPut(); FileWrite( fp, dataSize ); @@ -696,7 +696,7 @@ bool CIncremental::SaveIncrementalFile() void CIncremental::LinkLightsToFaces( CUtlVector &faceLights ) { faceLights.SetSize( numfaces ); - + for( int iLight=m_Lights.Head(); iLight != m_Lights.InvalidIndex(); iLight = m_Lights.Next( iLight ) ) { CIncLight *pLight = m_Lights[iLight]; @@ -752,7 +752,7 @@ CLightFace* CIncLight::FindOrCreateLightFace( int iFace, int lmSize, bool *bNew CLightFace *pFace = new CLightFace; pFace->m_LightFacesIndex = m_LightFaces.AddToTail( pFace ); pFace->m_pLight = this; - + pFace->m_FaceIndex = iFace; pFace->m_LightValues.SetSize( lmSize ); memset( pFace->m_LightValues.Base(), 0, sizeof( CLightValue ) * lmSize ); diff --git a/utils/vrad/leaf_ambient_lighting.cpp b/utils/vrad/leaf_ambient_lighting.cpp index 3836592e..cd44b7eb 100644 --- a/utils/vrad/leaf_ambient_lighting.cpp +++ b/utils/vrad/leaf_ambient_lighting.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// @@ -17,19 +17,19 @@ #include "vmpi.h" #include "vmpi_distribute_work.h" -static TableVector g_BoxDirections[6] = +static TableVector g_BoxDirections[6] = { - { 1, 0, 0 }, + { 1, 0, 0 }, { -1, 0, 0 }, - { 0, 1, 0 }, - { 0, -1, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 }, + { 0, 1, 0 }, + { 0, -1, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, }; -static void ComputeAmbientFromSurface( dface_t *surfID, dworldlight_t* pSkylight, +static void ComputeAmbientFromSurface( dface_t *surfID, dworldlight_t* pSkylight, Vector& radcolor ) { if ( !surfID ) @@ -132,7 +132,7 @@ void AddEmitSurfaceLights( const Vector &vStart, Vector lightBoxColor[6] ) lightBoxColor[i] += wl->intensity * (t * ratio); } } - } + } } @@ -150,7 +150,7 @@ void ComputeAmbientFromSphericalSamples( int iThread, const Vector &vStart, Vect Vector lightStyleColors[MAX_LIGHTSTYLES]; lightStyleColors[0].Init(); // We only care about light style 0 here. CalcRayAmbientLighting( iThread, vStart, vEnd, tanTheta, lightStyleColors ); - + radcolor[i] = lightStyleColors[0]; } @@ -170,7 +170,7 @@ void ComputeAmbientFromSphericalSamples( int iThread, const Vector &vStart, Vect lightBoxColor[j] += radcolor[i] * c; } } - + lightBoxColor[j] *= 1/t; } @@ -191,9 +191,9 @@ bool IsLeafAmbientSurfaceLight( dworldlight_t *wl ) if ( wl->style != 0 ) return false; - float intensity = max( wl->intensity[0], wl->intensity[1] ); - intensity = max( intensity, wl->intensity[2] ); - + float intensity = MAX( wl->intensity[0], wl->intensity[1] ); + intensity = MAX( intensity, wl->intensity[2] ); + return (intensity * g_flWorldLightMinEmitSurfaceDistanceRatio) < g_flWorldLightMinEmitSurface; } @@ -205,7 +205,7 @@ class CLeafSampler // Generate a random point in the leaf's bounding volume // reject any points that aren't actually in the leaf - // do a couple of tracing heuristics to eliminate points that are inside detail brushes + // do a couple of tracing heuristics to eliminate points that are inside detail brushes // or underneath displacement surfaces in the leaf // return once we have a valid point, use the center if one can't be computed quickly void GenerateLeafSamplePosition( int leafIndex, const CUtlVector &leafPlanes, Vector &samplePosition ) @@ -228,7 +228,7 @@ class CLeafSampler float d = DotProduct(leafPlanes[j].normal, samplePosition) - leafPlanes[j].dist; if ( d < DIST_EPSILON ) { - // not inside the leaf, try again + // not inside the leaf, try again bValid = false; break; } @@ -345,7 +345,7 @@ void AddSampleToList( CUtlVector &list, const Vector &samplePos for (int s = 0; s < 3; s++ ) { float dc = fabs(list[i].cube[k][s] - list[j].cube[k][s]); - maxDC = max(maxDC,dc); + maxDC = MAX(maxDC,dc); } totalDC += maxDC; } @@ -412,7 +412,7 @@ void Mod_LeafAmbientColorAtPos( Vector *pOut, const Vector &pos, const CUtlVecto { if ( i == skipIndex ) continue; - // do an inverse squared distance weighted average of the samples to reconstruct + // do an inverse squared distance weighted average of the samples to reconstruct // the original function float dist = (list[i].pos - pos).LengthSqr(); float factor = 1.0f / (dist + 1.0f); @@ -452,8 +452,8 @@ float AABBDistance( const Vector &mins0, const Vector &maxs0, const Vector &mins Vector delta; for ( int i = 0; i < 3; i++ ) { - float greatestMin = max(mins0[i], mins1[i]); - float leastMax = min(maxs0[i], maxs1[i]); + float greatestMin = MAX(mins0[i], mins1[i]); + float leastMax = MIN(maxs0[i], maxs1[i]); delta[i] = (greatestMin < leastMax) ? 0 : (leastMax - greatestMin); } return delta.Length(); @@ -533,9 +533,9 @@ void ComputeAmbientForLeaf( int iThread, int leafID, CUtlVector int xSize = (dleafs[leafID].maxs[0] - dleafs[leafID].mins[0]) / 32; int ySize = (dleafs[leafID].maxs[1] - dleafs[leafID].mins[1]) / 32; int zSize = (dleafs[leafID].maxs[2] - dleafs[leafID].mins[2]) / 64; - xSize = max(xSize,1); - ySize = max(xSize,1); - zSize = max(xSize,1); + xSize = MAX(xSize,1); + ySize = MAX(xSize,1); + zSize = MAX(xSize,1); // generate update 128 candidate samples, always at least one sample int volumeCount = xSize * ySize * zSize; if ( g_bFastAmbient ) @@ -625,12 +625,12 @@ void ComputePerLeafAmbientLighting() for ( int i=0; i < *pNumworldlights; i++ ) { dworldlight_t *wl = &dworldlights[i]; - + if ( IsLeafAmbientSurfaceLight( wl ) ) wl->flags |= DWL_FLAGS_INAMBIENTCUBE; else wl->flags &= ~DWL_FLAGS_INAMBIENTCUBE; - + if ( wl->type == emit_surface ) ++nSurfaceLights; diff --git a/utils/vrad/lightmap.cpp b/utils/vrad/lightmap.cpp index dfe1c180..9123dfd7 100644 --- a/utils/vrad/lightmap.cpp +++ b/utils/vrad/lightmap.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -31,44 +31,22 @@ enum #define SMOOTHING_GROUP_HARD_EDGE 0xff000000 -//==========================================================================// -// Give surfaces a softer look instead of the harsher linear N.L look -//==========================================================================// -float SoftenCosineTerm(float flDot) -{ - if (!do_soften) - return flDot; - - flDot = MAX(flDot, 0.0f); - return (flDot + (flDot * flDot)) * 0.5f; // This is cheaper than an exponent in shader code -} - -fltx4 SoftenCosineTerm(fltx4 dots) -{ - if (!do_soften) - return dots; - - dots = MaxSIMD(dots, Four_Zeros); - fltx4 dotsSquared = MulSIMD(dots, dots); - return MulSIMD(AddSIMD(dots, dotsSquared), Four_PointFives); -} - //==========================================================================// // CNormalList. //==========================================================================// -// This class keeps a list of unique normals and provides a fast +// This class keeps a list of unique normals and provides a fast class CNormalList { public: CNormalList(); - + // Adds the normal if unique. Otherwise, returns the normal's index into m_Normals. int FindOrAddNormal( Vector const &vNormal ); public: - + CUtlVector m_Normals; @@ -112,8 +90,8 @@ int CNormalList::FindOrAddNormal( Vector const &vNormal ) for( int iDim=0; iDim < 3; iDim++ ) { gi[iDim] = (int)( ((vNormal[iDim] + 1.0f) * 0.5f) * NUM_SUBDIVS - 0.000001f ); - gi[iDim] = min( gi[iDim], NUM_SUBDIVS ); - gi[iDim] = max( gi[iDim], 0 ); + gi[iDim] = MIN( gi[iDim], NUM_SUBDIVS ); + gi[iDim] = MAX( gi[iDim], 0 ); } // Look for a matching vector in there. @@ -134,7 +112,7 @@ int CNormalList::FindOrAddNormal( Vector const &vNormal ) } // FIXME: HACK until the plane normals are made more happy -void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, +void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ) { Vector stmp( sVect[0], sVect[1], sVect[2] ); @@ -203,7 +181,7 @@ void PairEdges (void) for (j=0 ; jnumedges ; j++) { n = EdgeVertex(f,j); - + for (k = 0; k < vertexref[n]; k++) { if (vertexface[n][k] == i) @@ -242,17 +220,17 @@ void PairEdges (void) // allocate room for vertex normals fn->normal = ( Vector* )calloc( f->numedges, sizeof( fn->normal[0] ) ); - + // look up all faces sharing vertices and add them to the list for (j=0 ; jnumedges ; j++) { n = EdgeVertex(f,j); - + for (k = 0; k < vertexref[n]; k++) { double cos_normals_angle; Vector *pNeighbornormal; - + // skip self if (vertexface[n][k] == i) continue; @@ -263,7 +241,7 @@ void PairEdges (void) pNeighbornormal = &faceneighbor[vertexface[n][k]].facenormal; cos_normals_angle = DotProduct( *pNeighbornormal, fn->facenormal ); - + // add normal if >= threshold or its a displacement surface (this is only if the original // face is a displacement) if ( fn->bHasDisp ) @@ -312,7 +290,7 @@ void PairEdges (void) if (tmpneighbor[m] == vertexface[n][k]) break; } - + if (m >= numneighbors) { // add to neighbor list @@ -336,7 +314,7 @@ void PairEdges (void) fn->neighbor[m] = tmpneighbor[m]; } } - + // fixup normals for (j = 0; j < f->numedges; j++) { @@ -363,7 +341,7 @@ void SaveVertexNormals( void ) for( j = 0; j < f->numedges; j++ ) { - Vector vNormal; + Vector vNormal; if( fn->normal ) { vNormal = fn->normal[j]; @@ -373,12 +351,12 @@ void SaveVertexNormals( void ) // original faces don't have normals vNormal.Init( 0, 0, 0 ); } - + if( g_numvertnormalindices == MAX_MAP_VERTNORMALINDICES ) { Error( "g_numvertnormalindices == MAX_MAP_VERTNORMALINDICES" ); } - + g_vertnormalindices[g_numvertnormalindices] = (unsigned short)normalList.FindOrAddNormal( vNormal ); g_numvertnormalindices++; } @@ -442,7 +420,7 @@ void CalcFaceVectors(lightinfo_t *l) int i, j; tex = &texinfo[l->face->texinfo]; - + // move into lightinfo_t for (i=0 ; i<2 ; i++) { @@ -459,14 +437,14 @@ void CalcFaceVectors(lightinfo_t *l) Vector luxelSpaceCross; - luxelSpaceCross[0] = - tex->lightmapVecsLuxelsPerWorldUnits[1][1] * tex->lightmapVecsLuxelsPerWorldUnits[0][2] - + luxelSpaceCross[0] = + tex->lightmapVecsLuxelsPerWorldUnits[1][1] * tex->lightmapVecsLuxelsPerWorldUnits[0][2] - tex->lightmapVecsLuxelsPerWorldUnits[1][2] * tex->lightmapVecsLuxelsPerWorldUnits[0][1]; - luxelSpaceCross[1] = - tex->lightmapVecsLuxelsPerWorldUnits[1][2] * tex->lightmapVecsLuxelsPerWorldUnits[0][0] - + luxelSpaceCross[1] = + tex->lightmapVecsLuxelsPerWorldUnits[1][2] * tex->lightmapVecsLuxelsPerWorldUnits[0][0] - tex->lightmapVecsLuxelsPerWorldUnits[1][0] * tex->lightmapVecsLuxelsPerWorldUnits[0][2]; - luxelSpaceCross[2] = - tex->lightmapVecsLuxelsPerWorldUnits[1][0] * tex->lightmapVecsLuxelsPerWorldUnits[0][1] - + luxelSpaceCross[2] = + tex->lightmapVecsLuxelsPerWorldUnits[1][0] * tex->lightmapVecsLuxelsPerWorldUnits[0][1] - tex->lightmapVecsLuxelsPerWorldUnits[1][1] * tex->lightmapVecsLuxelsPerWorldUnits[0][0]; float det = -DotProduct( l->facenormal, luxelSpaceCross ); @@ -481,11 +459,11 @@ void CalcFaceVectors(lightinfo_t *l) l->luxelToWorldSpace[0][0] = (l->facenormal[2] * l->worldToLuxelSpace[1][1] - l->facenormal[1] * l->worldToLuxelSpace[1][2]) / det; l->luxelToWorldSpace[1][0] = (l->facenormal[1] * l->worldToLuxelSpace[0][2] - l->facenormal[2] * l->worldToLuxelSpace[0][1]) / det; l->luxelOrigin[0] = -(l->facedist * luxelSpaceCross[0]) / det; - l->luxelToWorldSpace[0][1] = (l->facenormal[0] * l->worldToLuxelSpace[1][2] - l->facenormal[2] * l->worldToLuxelSpace[1][0]) / det; - l->luxelToWorldSpace[1][1] = (l->facenormal[2] * l->worldToLuxelSpace[0][0] - l->facenormal[0] * l->worldToLuxelSpace[0][2]) / det; + l->luxelToWorldSpace[0][1] = (l->facenormal[0] * l->worldToLuxelSpace[1][2] - l->facenormal[2] * l->worldToLuxelSpace[1][0]) / det; + l->luxelToWorldSpace[1][1] = (l->facenormal[2] * l->worldToLuxelSpace[0][0] - l->facenormal[0] * l->worldToLuxelSpace[0][2]) / det; l->luxelOrigin[1] = -(l->facedist * luxelSpaceCross[1]) / det; - l->luxelToWorldSpace[0][2] = (l->facenormal[1] * l->worldToLuxelSpace[1][0] - l->facenormal[0] * l->worldToLuxelSpace[1][1]) / det; - l->luxelToWorldSpace[1][2] = (l->facenormal[0] * l->worldToLuxelSpace[0][1] - l->facenormal[1] * l->worldToLuxelSpace[0][0]) / det; + l->luxelToWorldSpace[0][2] = (l->facenormal[1] * l->worldToLuxelSpace[1][0] - l->facenormal[0] * l->worldToLuxelSpace[1][1]) / det; + l->luxelToWorldSpace[1][2] = (l->facenormal[0] * l->worldToLuxelSpace[0][1] - l->facenormal[1] * l->worldToLuxelSpace[0][0]) / det; l->luxelOrigin[2] = -(l->facedist * luxelSpaceCross[2]) / det; // adjust for luxel offset @@ -550,7 +528,7 @@ void DumpFaces( lightinfo_t *pLightInfo, int ndxFace ) // disable threading (not a multi-threadable function!) ThreadLock(); - + if( !out ) { // open the file @@ -558,7 +536,7 @@ void DumpFaces( lightinfo_t *pLightInfo, int ndxFace ) if( !out ) return; } - + // // write out face // @@ -569,25 +547,25 @@ void DumpFaces( lightinfo_t *pLightInfo, int ndxFace ) Vector p1, p2; VectorAdd( dvertexes[EdgeVertex( pLightInfo->face, ndxEdge )].point, pLightInfo->modelorg, p1 ); VectorAdd( dvertexes[EdgeVertex( pLightInfo->face, ndxEdge+1 )].point, pLightInfo->modelorg, p2 ); - + Vector &n1 = fn->normal[ndxEdge]; Vector &n2 = fn->normal[(ndxEdge+1)%pLightInfo->face->numedges]; - + CmdLib_FPrintf( out, "3\n"); - + CmdLib_FPrintf(out, "%f %f %f %f %f %f\n", p1[0], p1[1], p1[2], n1[0] * 0.5 + 0.5, n1[1] * 0.5 + 0.5, n1[2] * 0.5 + 0.5 ); - + CmdLib_FPrintf(out, "%f %f %f %f %f %f\n", p2[0], p2[1], p2[2], n2[0] * 0.5 + 0.5, n2[1] * 0.5 + 0.5, n2[2] * 0.5 + 0.5 ); - - CmdLib_FPrintf(out, "%f %f %f %f %f %f\n", centroid[0] + pLightInfo->modelorg[0], - centroid[1] + pLightInfo->modelorg[1], - centroid[2] + pLightInfo->modelorg[2], - fn->facenormal[0] * 0.5 + 0.5, - fn->facenormal[1] * 0.5 + 0.5, + + CmdLib_FPrintf(out, "%f %f %f %f %f %f\n", centroid[0] + pLightInfo->modelorg[0], + centroid[1] + pLightInfo->modelorg[1], + centroid[2] + pLightInfo->modelorg[2], + fn->facenormal[0] * 0.5 + 0.5, + fn->facenormal[1] * 0.5 + 0.5, fn->facenormal[2] * 0.5 + 0.5 ); - + } - + // enable threading ThreadUnlock(); } @@ -603,9 +581,9 @@ bool BuildFacesamplesAndLuxels_DoFast( lightinfo_t *pLightInfo, facelight_t *pFa // ratio of world area / lightmap area texinfo_t *pTex = &texinfo[pLightInfo->face->texinfo]; - pFaceLight->worldAreaPerLuxel = 1.0 / ( sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[0], - pTex->lightmapVecsLuxelsPerWorldUnits[0] ) ) * - sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[1], + pFaceLight->worldAreaPerLuxel = 1.0 / ( sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[0], + pTex->lightmapVecsLuxelsPerWorldUnits[0] ) ) * + sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[1], pTex->lightmapVecsLuxelsPerWorldUnits[1] ) ) ); // @@ -677,9 +655,9 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) // ratio of world area / lightmap area texinfo_t *pTex = &texinfo[pLightInfo->face->texinfo]; - pFaceLight->worldAreaPerLuxel = 1.0 / ( sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[0], - pTex->lightmapVecsLuxelsPerWorldUnits[0] ) ) * - sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[1], + pFaceLight->worldAreaPerLuxel = 1.0 / ( sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[0], + pTex->lightmapVecsLuxelsPerWorldUnits[0] ) ) * + sqrt( DotProduct( pTex->lightmapVecsLuxelsPerWorldUnits[1], pTex->lightmapVecsLuxelsPerWorldUnits[1] ) ) ); // allocate a large number of samples for creation -- get copied later! @@ -689,7 +667,7 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) sample_t *pSamples = samples; // lightmap space winding - winding_t *pLightmapWinding = LightmapCoordWindingForFace( pLightInfo ); + winding_t *pLightmapWinding = LightmapCoordWindingForFace( pLightInfo ); // // build vector pointing along the lightmap cutting planes @@ -710,7 +688,7 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) for( int t = 0; t < height && pLightmapWinding; t++ ) { dist = t + sampleOffset; - + // lop off a sample in the t dimension // hack - need a separate epsilon for lightmap space since ON_EPSILON is for texture space ClipWindingEpsilon( pLightmapWinding, tNorm, dist, ON_EPSILON / 16.0f, &pWindingT1, &pWindingT2 ); @@ -736,15 +714,15 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) // and find the center (then convert it to 2D) Vector center; pSamples->area = WindingAreaAndBalancePoint( pWindingS2, center ) * pFaceLight->worldAreaPerLuxel; - pSamples->coord[0] = center.x; + pSamples->coord[0] = center.x; pSamples->coord[1] = center.y; // find winding bounds (then convert it to 2D) Vector minbounds, maxbounds; WindingBounds( pWindingS2, minbounds, maxbounds ); - pSamples->mins[0] = minbounds.x; + pSamples->mins[0] = minbounds.x; pSamples->mins[1] = minbounds.y; - pSamples->maxs[0] = maxbounds.x; + pSamples->maxs[0] = maxbounds.x; pSamples->maxs[1] = maxbounds.y; // convert from lightmap space to world space @@ -786,7 +764,7 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) } // - // if the original lightmap winding exists free it and set it equal to T1 (the rest of the winding not cut into samples) + // if the original lightmap winding exists free it and set it equal to T1 (the rest of the winding not cut into samples) // if( pLightmapWinding ) { @@ -918,7 +896,7 @@ bool BuildLuxels( lightinfo_t *pLightInfo, facelight_t *pFaceLight, int ndxFace void CalcPoints( lightinfo_t *pLightInfo, facelight_t *pFaceLight, int ndxFace ) { // debugging! - if( g_bDumpPatches ) + if( g_bDumpPatches ) { DumpFaces( pLightInfo, ndxFace ); } @@ -1085,7 +1063,7 @@ int LightForString( char *pLight, Vector& intensity ) // scanf into doubles, then assign, so it is vec_t size independent r = g = b = scaler = 0; double r_hdr,g_hdr,b_hdr,scaler_hdr; - argCnt = sscanf ( pLight, "%lf %lf %lf %lf %lf %lf %lf %lf", + argCnt = sscanf ( pLight, "%lf %lf %lf %lf %lf %lf %lf %lf", &r, &g, &b, &scaler, &r_hdr,&g_hdr,&b_hdr,&scaler_hdr ); if (argCnt==8) // 2 4-tuples @@ -1108,20 +1086,20 @@ int LightForString( char *pLight, Vector& intensity ) } intensity[0] = pow( r / 255.0, 2.2 ) * 255; // convert to linear - + switch( argCnt) { case 1: // The R,G,B values are all equal. - intensity[1] = intensity[2] = intensity[0]; + intensity[1] = intensity[2] = intensity[0]; break; - + case 3: case 4: // Save the other two G,B values. intensity[1] = pow( g / 255.0, 2.2 ) * 255; intensity[2] = pow( b / 255.0, 2.2 ) * 255; - + // Did we also get an "intensity" scaler value too? if ( argCnt == 4 ) { @@ -1150,16 +1128,16 @@ static void ParseLightGeneric( entity_t *e, directlight_t *dl ) Vector dest; dl->light.style = (int)FloatForKey (e, "style"); - + // get intenfsity - if( g_bHDR && LightForKey( e, "_light", dl->light.intensity ) ) + if( g_bHDR && LightForKey( e, "_lightHDR", dl->light.intensity ) ) { } else { LightForKey( e, "_light", dl->light.intensity ); } - + // check angle, targets target = ValueForKey (e, "target"); if (target[0]) @@ -1176,7 +1154,7 @@ static void ParseLightGeneric( entity_t *e, directlight_t *dl ) } } else - { + { // point down angle Vector angles; GetVectorForKey( e, "angles", angles ); @@ -1185,7 +1163,7 @@ static void ParseLightGeneric( entity_t *e, directlight_t *dl ) SetupLightNormalFromProps( QAngle( angles.x, angles.y, angles.z ), angle, pitch, dl->light.normal ); } if ( g_bHDR ) - VectorScale( dl->light.intensity, + VectorScale( dl->light.intensity, FloatForKeyWithDefault( e, "_lightscaleHDR", 1.0 ), dl->light.intensity ); } @@ -1295,7 +1273,7 @@ static void ParseLightSpot( entity_t* e, directlight_t* dl ) dl->light.stopdot = 10; dl->light.stopdot2 = FloatForKey (e, "_cone"); - if (!dl->light.stopdot2) + if (!dl->light.stopdot2) dl->light.stopdot2 = dl->light.stopdot; if (dl->light.stopdot2 < dl->light.stopdot) dl->light.stopdot2 = dl->light.stopdot; @@ -1309,7 +1287,7 @@ static void ParseLightSpot( entity_t* e, directlight_t* dl ) } else { - // Clamp to 90, that's all DX8 can handle! + // Clamp to 90, that's all DX8 can handle! if (dl->light.stopdot > 90) { Warning("WARNING: light_spot at (%i %i %i) has inner angle larger than 90 degrees! Clamping to 90...\n", @@ -1349,8 +1327,8 @@ bool CanLeafTraceToSky( int iLeaf ) for ( int j = 0; j < NUMVERTEXNORMALS; j+=4 ) { // search back to see if we can hit a sky brush - delta.LoadAndSwizzle( g_anorms[j], g_anorms[min( j+1, NUMVERTEXNORMALS-1 )], - g_anorms[min( j+2, NUMVERTEXNORMALS-1 )], g_anorms[min( j+3, NUMVERTEXNORMALS-1 )] ); + delta.LoadAndSwizzle( g_anorms[j], g_anorms[MIN( j+1, NUMVERTEXNORMALS-1 )], + g_anorms[MIN( j+2, NUMVERTEXNORMALS-1 )], g_anorms[MIN( j+3, NUMVERTEXNORMALS-1 )] ); delta *= -MAX_TRACE_LENGTH; delta += center4; @@ -1373,7 +1351,7 @@ void BuildVisForLightEnvironment( void ) for ( int iLeafFace = 0; iLeafFace < dleafs[iLeaf].numleaffaces; ++iLeafFace ) { unsigned int iFace = dleaffaces[iFirstFace+iLeafFace]; - + texinfo_t &tex = texinfo[g_pFaces[iFace].texinfo]; if ( tex.flags & SURF_SKY ) { @@ -1487,7 +1465,7 @@ void BuildVisForLightEnvironment( void ) static char *ValueForKeyWithDefault (entity_t *ent, char *key, char *default_value = NULL) { epair_t *ep; - + for (ep=ent->epairs ; ep ; ep=ep->next) if (!strcmp (ep->key, key) ) return ep->value; @@ -1502,8 +1480,6 @@ static void ParseLightEnvironment( entity_t* e, directlight_t* dl ) ParseLightGeneric( e, dl ); - // always true for now - dl->m_bStatic = true; char *angle_str=ValueForKeyWithDefault( e, "SunSpreadAngle" ); if (angle_str) { @@ -1520,7 +1496,7 @@ static void ParseLightEnvironment( entity_t* e, directlight_t* dl ) // Sky ambient light. gAmbient = AllocDLight( dl->light.origin, false ); gAmbient->light.type = emit_skyambient; - if( g_bHDR && LightForKey( e, "_ambient", gAmbient->light.intensity ) ) + if( g_bHDR && LightForKey( e, "_ambientHDR", gAmbient->light.intensity ) ) { // we have a valid HDR ambient light value } @@ -1530,13 +1506,13 @@ static void ParseLightEnvironment( entity_t* e, directlight_t* dl ) } if ( g_bHDR ) { - VectorScale( gAmbient->light.intensity, - FloatForKeyWithDefault( e, "_AmbientScaleHDR", 1.0 ), + VectorScale( gAmbient->light.intensity, + FloatForKeyWithDefault( e, "_AmbientScaleHDR", 1.0 ), gAmbient->light.intensity ); } - + BuildVisForLightEnvironment(); - + // Add sky and sky ambient lights to the list. AddDLightToActiveList( gSkyLight ); AddDLightToActiveList( gAmbient ); @@ -1556,65 +1532,6 @@ static void ParseLightPoint( entity_t* e, directlight_t* dl ) SetLightFalloffParams(e,dl); } -static void ParseLightProjectedTexture(entity_t* e, directlight_t* dl) -{ - Vector dest; - GetVectorForKey(e, "origin", dest); - dl = AllocDLight(dest, true); - - LightForKey(e, "lightcolor", dl->light.intensity); - dl->m_bStatic = true; - // point down angle - Vector angles; - GetVectorForKey(e, "angles", angles); - float angle = FloatForKey(e, "angle"); - SetupLightNormalFromProps(QAngle(angles.x, angles.y, angles.z), angle, -angles.x, dl->light.normal); - - dl->light.type = emit_spotlight; - - dl->light.stopdot2 = FloatForKey(e, "lightfov") / 2.0f; - - dl->light.stopdot = dl->light.stopdot2 - 5.0f; - - // Clamp to 90, that's all DX8 can handle! - if (dl->light.stopdot > 90) - { - Warning("WARNING: light_spot at (%i %i %i) has inner angle larger than 90 degrees! Clamping to 90...\n", - (int)dl->light.origin[0], (int)dl->light.origin[1], (int)dl->light.origin[2]); - dl->light.stopdot = 90; - } - - if (dl->light.stopdot2 > 90) - { - Warning("WARNING: light_spot at (%i %i %i) has outer angle larger than 90 degrees! Clamping to 90...\n", - (int)dl->light.origin[0], (int)dl->light.origin[1], (int)dl->light.origin[2]); - dl->light.stopdot2 = 90; - } - - dl->light.stopdot2 = (float)cos(dl->light.stopdot2 / 180 * M_PI); - dl->light.stopdot = (float)cos(dl->light.stopdot / 180 * M_PI); - dl->light.exponent = 1.0f; - - dl->m_flStartFadeDistance = 0; - dl->m_flEndFadeDistance = -1; - dl->m_flCapDist = 1.0e22; - dl->light.constant_attn = FloatForKey(e, "constant"); - dl->light.linear_attn = FloatForKey(e, "linear"); - dl->light.quadratic_attn = FloatForKey(e, "quadratic"); - - dl->light.radius = 0.0f; - - if (dl->light.constant_attn < EQUAL_EPSILON && dl->light.linear_attn < EQUAL_EPSILON && dl->light.quadratic_attn < EQUAL_EPSILON) - dl->light.constant_attn = 1; - - // scale intensity for unit 100 distance - float ratio = (dl->light.constant_attn + 100 * dl->light.linear_attn + 100 * 100 * dl->light.quadratic_attn); - if (ratio > 0) - { - VectorScale(dl->light.intensity, ratio, dl->light.intensity); - } -} - /* ============= CreateDirectLights @@ -1663,7 +1580,7 @@ void CreateDirectLights (void) VectorScale( dl->light.intensity, DIRECT_SCALE, dl->light.intensity ); } } - + // // entities // @@ -1671,17 +1588,6 @@ void CreateDirectLights (void) { e = &entities[i]; name = ValueForKey (e, "classname"); - - // env_projectedtexture is an exception, we want to have baked radiosity for it, so we have to include it here (if its set to be static) - if (!strcmp(name, "env_projectedtexture")) - { - if (IntForKey(e, "static")) - { - ParseLightProjectedTexture(e, dl); - continue; - } - } - if (strncmp (name, "light", 5)) continue; @@ -1693,11 +1599,11 @@ void CreateDirectLights (void) { ParseLightSpot( e, dl ); } - else if (!strcmp(name, "light_environment")) + else if (!strcmp(name, "light_environment")) { ParseLightEnvironment( e, dl ); } - else if (!strcmp(name, "light")) + else if (!strcmp(name, "light")) { ParseLightPoint( e, dl ); } @@ -1726,10 +1632,6 @@ void ExportDirectLightsToWorldLights() for (dl = activelights; dl != NULL; dl = dl->next ) { - // no need to have direct lighting being computed in the engine/shaderapi, its handled in the game - if (dl->m_bStatic) - continue; - dworldlight_t *wl = &dworldlights[(*pNumworldlights)++]; if (*pNumworldlights > MAX_MAP_WORLDLIGHTS) @@ -1768,7 +1670,7 @@ void ExportDirectLightsToWorldLights() // non-point sun light // Helper function - gathers light from sun (emit_skylight) -void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, +void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread, int nLFlags, int static_prop_index_to_ignore, float flEpsilon ) @@ -1792,10 +1694,8 @@ void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, i if ( g_SunAngularExtent > 0.0f ) { nsamples = NSAMPLES_SUN_AREA_LIGHT; - if (do_fast || force_fast) + if ( do_fast || force_fast ) nsamples /= 4; - - nsamples *= g_flSunSampleScale; } fltx4 totalFractionVisible = Four_Zeros; @@ -1809,12 +1709,7 @@ void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, i // serach back to see if we can hit a sky brush Vector delta; VectorScale( dl->light.normal, -MAX_TRACE_LENGTH, delta ); - - bool shouldSample = !do_fastsample || roundf(((float)rand() / VALVE_RAND_MAX) * (nsamples - 1)) == d; - if (!shouldSample) - continue; - - if ( d || do_fastsample ) + if ( d ) { // jitter light source location Vector ofs = sampler.NextValue(); @@ -1825,12 +1720,12 @@ void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, i delta4.DuplicateVector ( delta ); delta4 += pos; + TestLine_DoesHitSky ( pos, delta4, &fractionVisible, true, static_prop_index_to_ignore ); - TestLine_DoesHitSky(pos, delta4, &fractionVisible, true, static_prop_index_to_ignore); - totalFractionVisible = AddSIMD(totalFractionVisible, fractionVisible); + totalFractionVisible = AddSIMD ( totalFractionVisible, fractionVisible ); } - fltx4 seeAmount = MulSIMD ( totalFractionVisible, ReplicateX4 ( 1.0f / (do_fastsample ? 1 : nsamples) ) ); + fltx4 seeAmount = MulSIMD ( totalFractionVisible, ReplicateX4 ( 1.0f / nsamples ) ); out.m_flDot[0] = MulSIMD ( dot, seeAmount ); out.m_flFalloff = Four_Ones; out.m_flSunAmount = MulSIMD ( seeAmount, ReplicateX4( 10000.0f ) ); @@ -1847,7 +1742,7 @@ void GatherSampleSkyLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, i } // Helper function - gathers light from ambient sky light -void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, +void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread, int nLFlags, int static_prop_index_to_ignore, float flEpsilon ) @@ -1871,18 +1766,14 @@ void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int nsky_samples = NUMVERTEXNORMALS; if (do_fast || force_fast ) nsky_samples /= 4; - - nsky_samples *= g_flSkySampleScale; + else + nsky_samples *= g_flSkySampleScale; for (int j = 0; j < nsky_samples; j++) { FourVectors anorm; anorm.DuplicateVector( sampler.NextValue() ); - bool shouldSample = !do_fastsample || roundf(((float)rand() / VALVE_RAND_MAX) * (nsky_samples - 1)) == j; - if (!shouldSample) - continue; - if ( bIgnoreNormals ) dots[0] = ReplicateX4( CONSTANT_DOT ); else @@ -1919,12 +1810,13 @@ void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, surfacePos -= offset; fltx4 fractionVisible = Four_Ones; - TestLine_DoesHitSky(surfacePos, delta, &fractionVisible, true, static_prop_index_to_ignore); - for (int i = 0; i < normalCount; i++) + TestLine_DoesHitSky( surfacePos, delta, &fractionVisible, true, static_prop_index_to_ignore ); + for ( int i = 0; i < normalCount; i++ ) { - fltx4 addedAmount = MulSIMD(fractionVisible, dots[i]); - ambient_intensity[i] = AddSIMD(ambient_intensity[i], addedAmount); + fltx4 addedAmount = MulSIMD( fractionVisible, dots[i] ); + ambient_intensity[i] = AddSIMD( ambient_intensity[i], addedAmount ); } + } out.m_flFalloff = Four_Ones; @@ -1941,7 +1833,7 @@ void GatherSampleAmbientSkySSE( SSE_sampleLightOutput_t &out, directlight_t *dl, } // Helper function - gathers light from area lights, spot lights, and point lights -void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, +void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread, int nLFlags, int static_prop_index_to_ignore, float flEpsilon ) @@ -1971,8 +1863,6 @@ void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t * dot = delta * pNormals[0]; dot = MaxSIMD( Four_Zeros, dot ); - dot = SoftenCosineTerm(dot); - // Affix dot to zero if past fade distz bool bHasHardFalloff = ( dl->m_flEndFadeDistance > dl->m_flStartFadeDistance ); if ( bHasHardFalloff ) @@ -2064,7 +1954,7 @@ void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t * } // we may be in the fade region - modulate lighting by the fade curve - //float t = ( dist - dl->m_flStartFadeDistance ) / + //float t = ( dist - dl->m_flStartFadeDistance ) / // ( dl->m_flEndFadeDistance - dl->m_flStartFadeDistance ); if ( bHasHardFalloff ) { @@ -2110,11 +2000,11 @@ void GatherSampleStandardLightSSE( SSE_sampleLightOutput_t &out, directlight_t * // normal - surface normal of sample // out.m_flDot[] - returned dot products with light vector and each normal // out.m_flFalloff - amount of light falloff -bool GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, +void GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int facenum, FourVectors const& pos, FourVectors *pNormals, int normalCount, int iThread, int nLFlags, int static_prop_index_to_ignore, - float flEpsilon, bool fastsample ) + float flEpsilon ) { for ( int b = 0; b < normalCount; b++ ) out.m_flDot[b] = Four_Zeros; @@ -2122,16 +2012,12 @@ bool GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int out.m_flSunAmount = Four_Zeros; Assert( normalCount <= (NUM_BUMP_VECTS+1) ); - bool shouldSample = !fastsample || (roundf(((float)rand() / VALVE_RAND_MAX) * (numdlights - 1)) == dl->index) || dl->light.type == emit_skylight || dl->light.type == emit_skyambient; - if (!shouldSample) - return false; - // skylights work fundamentally differently than normal lights switch( dl->light.type ) { case emit_skylight: - GatherSampleSkyLightSSE(out, dl, facenum, pos, pNormals, normalCount, - iThread, nLFlags, static_prop_index_to_ignore, flEpsilon); + GatherSampleSkyLightSSE( out, dl, facenum, pos, pNormals, normalCount, + iThread, nLFlags, static_prop_index_to_ignore, flEpsilon ); break; case emit_skyambient: GatherSampleAmbientSkySSE( out, dl, facenum, pos, pNormals, normalCount, @@ -2145,7 +2031,7 @@ bool GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int break; default: Error ("Bad dl->light.type"); - return false; + return; } // NOTE: Notice here that if the light is on the back side of the face @@ -2160,7 +2046,6 @@ bool GatherSampleLightSSE( SSE_sampleLightOutput_t &out, directlight_t *dl, int out.m_flDot[n] = AndSIMD( out.m_flDot[n], notZero ); } - return true; } /* @@ -2184,7 +2069,7 @@ void AddSampleToPatch (sample_t *s, LightingValue_t& light, int facenum) return; // - // fixed the sample position and normal -- need to find the equiv pos, etc to set up + // fixed the sample position and normal -- need to find the equiv pos, etc to set up // patches // if( g_FacePatches.Element( facenum ) == g_FacePatches.InvalidIndex() ) @@ -2268,7 +2153,7 @@ void GetPhongNormal( int facenum, Vector const& spot, Vector& phongnormal ) Vector& n2 = fn->normal[(j+1)%f->numedges]; /* - if (VectorCompare( n1, fn->facenormal ) + if (VectorCompare( n1, fn->facenormal ) && VectorCompare( n2, fn->facenormal) ) continue; */ @@ -2295,7 +2180,7 @@ void GetPhongNormal( int facenum, Vector const& spot, Vector& phongnormal ) // calculate distance from edge to pos Vector temp; float scale; - + // Interpolate between the center and edge normals based on sample position scale = 1.0 - a1 - a2; VectorScale( fn->facenormal, scale, phongnormal ); @@ -2386,7 +2271,7 @@ void GetPhongNormal( int facenum, FourVectors const& spot, FourVectors& phongnor a2 = MulSIMD( a2, SubSIMD( vspot * v2, MulSIMD( a1, ReplicateX4( ab ) ) ) ); fltx4 resultMask = AndSIMD( CmpGeSIMD( a1, Four_Zeros ), CmpGeSIMD( a2, Four_Zeros ) ); - + if ( !TestSignSIMD( resultMask ) ) continue; @@ -2424,11 +2309,11 @@ int GetVisCache( int lastoffset, int cluster, byte *pvs ) { // get the PVS for the pos to limit the number of checks if ( !visdatasize ) - { + { memset (pvs, 255, (dvis->numclusters+7)/8 ); lastoffset = -1; } - else + else { if (cluster < 0) { @@ -2441,7 +2326,7 @@ int GetVisCache( int lastoffset, int cluster, byte *pvs ) { int thisoffset = dvis->bitofs[ cluster ][DVIS_PVS]; if ( thisoffset != lastoffset ) - { + { if ( thisoffset == -1 ) { Error ("visofs == -1"); @@ -2502,7 +2387,6 @@ static inline void AllocateLightstyleSamples( facelight_t* fl, int styleIndex, i for (int n = 0; n < numnormals; ++n) { fl->light[styleIndex][n] = ( LightingValue_t* )calloc( fl->numsamples, sizeof(LightingValue_t ) ); - fl->radiosity[styleIndex][n] = (LightingValue_t*)calloc(fl->numsamples, sizeof(LightingValue_t)); } } @@ -2610,7 +2494,7 @@ static void GatherSampleLightAt4Points( SSE_SampleInfo_t& info, int sampleIdx, i // Iterate over all direct lights and add them to the particular sample for (directlight_t *dl = activelights; dl != NULL; dl = dl->next) - { + { // is this lights cluster visible? fltx4 dotMask = Four_Zeros; bool skipLight = true; @@ -2622,19 +2506,11 @@ static void GatherSampleLightAt4Points( SSE_SampleInfo_t& info, int sampleIdx, i skipLight = false; } } - - //if (dl->light.type == emit_skylight) - // skipLight = true; - - if (dl->m_bStatic == true) - skipLight = true; - if ( skipLight ) continue; - if(!GatherSampleLightSSE( out, dl, info.m_FaceNum, info.m_Points, info.m_PointNormals, info.m_NormalCount, info.m_iThread, 0, -1, 0.0f, do_fastsample )) - continue; - + GatherSampleLightSSE( out, dl, info.m_FaceNum, info.m_Points, info.m_PointNormals, info.m_NormalCount, info.m_iThread ); + // Apply the PVS check filter and compute falloff x dot fltx4 fxdot[NUM_BUMP_VECTS + 1]; skipLight = true; @@ -2651,7 +2527,7 @@ static void GatherSampleLightAt4Points( SSE_SampleInfo_t& info, int sampleIdx, i continue; // Figure out the lightstyle for this particular sample - int lightStyleIndex = FindOrAllocateLightstyleSamples( info.m_pFace, info.m_pFaceLight, + int lightStyleIndex = FindOrAllocateLightstyleSamples( info.m_pFace, info.m_pFaceLight, dl->light.style, info.m_NormalCount ); if (lightStyleIndex < 0) { @@ -2673,7 +2549,7 @@ static void GatherSampleLightAt4Points( SSE_SampleInfo_t& info, int sampleIdx, i { for ( int i = 0; i < numSamples; i++ ) { - g_pIncremental->AddLightToFace( dl->m_IncrementalID, info.m_FaceNum, sampleIdx + i, + g_pIncremental->AddLightToFace( dl->m_IncrementalID, info.m_FaceNum, sampleIdx + i, info.m_LightmapSize, SubFloat( fxdot[0], i ), info.m_iThread ); } } @@ -2682,92 +2558,29 @@ static void GatherSampleLightAt4Points( SSE_SampleInfo_t& info, int sampleIdx, i { for ( int i = 0; i < numSamples; i++ ) { - pLightmaps[n][sampleIdx + i].AddLight( SubFloat( fxdot[n], i ) * (1.0f / fastsamples), dl->light.intensity, SubFloat( out.m_flSunAmount, i ) ); + pLightmaps[n][sampleIdx + i].AddLight( SubFloat( fxdot[n], i ), dl->light.intensity, SubFloat( out.m_flSunAmount, i ) ); } } } } + + //----------------------------------------------------------------------------- -// Iterates over all lights and computes sun light at up to 4 sample points +// Iterates over all lights and computes lighting at a sample point //----------------------------------------------------------------------------- -static void GatherSampleRadiosityOnlyAt4Points(SSE_SampleInfo_t& info, int sampleIdx, int numSamples) +static void ResampleLightAt4Points( SSE_SampleInfo_t& info, int lightStyleIndex, int flags, LightingValue_t pLightmap[4][NUM_BUMP_VECTS+1] ) { SSE_sampleLightOutput_t out; - // Iterate over all direct lights and add them to the particular sample - for (directlight_t* dl = activelights; dl != NULL; dl = dl->next) + // Clear result + for ( int i = 0; i < 4; ++i ) { - // is this lights cluster visible? - fltx4 dotMask = Four_Zeros; - bool skipLight = true; - for (int s = 0; s < numSamples; s++) - { - if (PVSCheck(dl->pvs, info.m_Clusters[s])) - { - dotMask = SetComponentSIMD(dotMask, s, 1.0f); - skipLight = false; - } - } - - if (dl->m_bStatic == false) - skipLight = true; - - if (skipLight) - continue; - - GatherSampleLightSSE(out, dl, info.m_FaceNum, info.m_Points, info.m_PointNormals, info.m_NormalCount, info.m_iThread); - - // Apply the PVS check filter and compute falloff x dot - fltx4 fxdot[NUM_BUMP_VECTS + 1]; - skipLight = true; - for (int b = 0; b < info.m_NormalCount; b++) - { - fxdot[b] = MulSIMD(out.m_flDot[b], dotMask); - fxdot[b] = MulSIMD(fxdot[b], out.m_flFalloff); - if (!IsAllZeros(fxdot[b])) - { - skipLight = false; - } - } - if (skipLight) - continue; - - // Figure out the lightstyle for this particular sample - int lightStyleIndex = FindOrAllocateLightstyleSamples(info.m_pFace, info.m_pFaceLight, - dl->light.style, info.m_NormalCount); - if (lightStyleIndex < 0) - { - if (info.m_WarnFace != info.m_FaceNum) - { - Warning("\nWARNING: Too many light styles on a face at (%f, %f, %f)\n", - info.m_Points.x.m128_f32[0], info.m_Points.y.m128_f32[0], info.m_Points.z.m128_f32[0]); - info.m_WarnFace = info.m_FaceNum; - } - continue; - } - - // pLightmaps is an array of the lightmaps for each normal direction, - // here's where the result of the sample gathering goes - LightingValue_t** pLightmaps = info.m_pFaceLight->radiosity[lightStyleIndex]; - - for (int n = 0; n < info.m_NormalCount; ++n) + for ( int n = 0; n < info.m_NormalCount; ++n ) { - for (int i = 0; i < numSamples; i++) - { - pLightmaps[n][sampleIdx + i].AddLight(SubFloat(fxdot[n], i), dl->light.intensity, SubFloat(out.m_flSunAmount, i)); - } + pLightmap[i][n].Zero(); } } -} - - -//----------------------------------------------------------------------------- -// Iterates over all lights and computes lighting at a sample point -//----------------------------------------------------------------------------- -static void ResampleLightAt4Points( SSE_SampleInfo_t& info, int lightStyleIndex, int flags, LightingValue_t pLightmap[4][NUM_BUMP_VECTS+1] ) -{ - SSE_sampleLightOutput_t out; // Iterate over all direct lights and add them to the particular sample for (directlight_t *dl = activelights; dl != NULL; dl = dl->next) @@ -2778,7 +2591,7 @@ static void ResampleLightAt4Points( SSE_SampleInfo_t& info, int lightStyleIndex, if ((flags & NON_AMBIENT_ONLY) && (dl->light.type == emit_skyambient)) continue; - // Only add contributions that match the lightstyle + // Only add contributions that match the lightstyle Assert( lightStyleIndex <= MAXLIGHTMAPS ); Assert( info.m_pFace->styles[lightStyleIndex] != 255 ); if (dl->light.style != info.m_pFace->styles[lightStyleIndex]) @@ -2795,9 +2608,6 @@ static void ResampleLightAt4Points( SSE_SampleInfo_t& info, int lightStyleIndex, skipLight = false; } } - if (dl->m_bStatic) - skipLight = true; - if ( skipLight ) continue; @@ -2805,8 +2615,7 @@ static void ResampleLightAt4Points( SSE_SampleInfo_t& info, int lightStyleIndex, // (tested by checking the dot product of the face normal and the light position) // we don't want it to contribute to *any* of the bumped lightmaps. It glows // in disturbing ways if we don't do this. - if(!GatherSampleLightSSE( out, dl, info.m_FaceNum, info.m_Points, info.m_PointNormals, info.m_NormalCount, info.m_iThread )) - continue; + GatherSampleLightSSE( out, dl, info.m_FaceNum, info.m_Points, info.m_PointNormals, info.m_NormalCount, info.m_iThread ); // Apply the PVS check filter and compute falloff x dot fltx4 fxdot[NUM_BUMP_VECTS + 1]; @@ -2871,7 +2680,7 @@ bool PointsInWinding ( FourVectors const & point, winding_t *w, int &invalidBits //----------------------------------------------------------------------------- // Perform supersampling at a particular point //----------------------------------------------------------------------------- -static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, +static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, int sampleIndex, int lightStyleIndex, LightingValue_t *pLight, int flags ) { sample_t& sample = info.m_pFaceLight->sample[sampleIndex]; @@ -2898,18 +2707,6 @@ static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, FourVectors superSampleLightCoord; FourVectors superSamplePosition; - - // Resample the light at this point... - LightingValue_t result[4][NUM_BUMP_VECTS + 1]; - // Clear result - for (int i = 0; i < 4; ++i) - { - for (int n = 0; n < info.m_NormalCount; ++n) - { - result[i][n].Zero(); - } - } - if ( flags & NON_AMBIENT_ONLY ) { float aRow[4]; @@ -2939,17 +2736,18 @@ static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, // We're assuming the flat normal is the same for all supersamples ComputeIlluminationPointAndNormalsSSE( l, superSamplePosition, superSampleNormal, &info, 4 ); - ResampleLightAt4Points(info, lightStyleIndex, NON_AMBIENT_ONLY, result); + // Resample the non-ambient light at this point... + LightingValue_t result[4][NUM_BUMP_VECTS+1]; + ResampleLightAt4Points( info, lightStyleIndex, NON_AMBIENT_ONLY, result ); // Got more subsamples - for (int i = 0; i < 4; i++) + for ( int i = 0; i < 4; i++ ) { - if (!((invalidBits >> i) & 0x1)) + if ( !( ( invalidBits >> i ) & 0x1 ) ) { - for (int n = 0; n < info.m_NormalCount; ++n) + for ( int n = 0; n < info.m_NormalCount; ++n ) { - result[i][n].Scale(1.0f / max(1, fastsamples)); - pLight[n].AddLight(result[i][n]); + pLight[n].AddLight( result[i][n] ); } ++subsampleCount; } @@ -2972,27 +2770,17 @@ static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, ComputeIlluminationPointAndNormalsSSE( l, superSamplePosition, superSampleNormal, &info, 4 ); - if (!do_fastsample) - { - ResampleLightAt4Points(info, lightStyleIndex, AMBIENT_ONLY, result); - } - else - { - for (int i = 0; i < fastsamples; i++) - { - ResampleLightAt4Points(info, lightStyleIndex, AMBIENT_ONLY, result); - } - } + LightingValue_t result[4][NUM_BUMP_VECTS+1]; + ResampleLightAt4Points( info, lightStyleIndex, AMBIENT_ONLY, result ); // Got more subsamples - for (int i = 0; i < 4; i++) + for ( int i = 0; i < 4; i++ ) { - if (!((invalidBits >> i) & 0x1)) + if ( !( ( invalidBits >> i ) & 0x1 ) ) { - for (int n = 0; n < info.m_NormalCount; ++n) + for ( int n = 0; n < info.m_NormalCount; ++n ) { - result[i][n].Scale(1.0f / max(1, fastsamples)); - pLight[n].AddLight(result[i][n]); + pLight[n].AddLight( result[i][n] ); } ++subsampleCount; } @@ -3006,7 +2794,7 @@ static int SupersampleLightAtPoint( lightinfo_t& l, SSE_SampleInfo_t& info, //----------------------------------------------------------------------------- // Compute gradients of a lightmap //----------------------------------------------------------------------------- -static void ComputeLightmapGradients( SSE_SampleInfo_t& info, bool const* pHasProcessedSample, +static void ComputeLightmapGradients( SSE_SampleInfo_t& info, bool const* pHasProcessedSample, float* pIntensity, float* gradient ) { int w = info.m_LightmapWidth; @@ -3029,18 +2817,18 @@ static void ComputeLightmapGradients( SSE_SampleInfo_t& info, bool const* pHasPr if (sample.t > 0) { - if (sample.s > 0) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j-1-w] ) ); - gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j-w] ) ); - if (sample.s < w-1) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j+1-w] ) ); + if (sample.s > 0) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j-1-w] ) ); + gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j-w] ) ); + if (sample.s < w-1) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j+1-w] ) ); } if (sample.t < h-1) { - if (sample.s > 0) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j-1+w] ) ); - gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j+w] ) ); - if (sample.s < w-1) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j+1+w] ) ); + if (sample.s > 0) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j-1+w] ) ); + gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j+w] ) ); + if (sample.s < w-1) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j+1+w] ) ); } - if (sample.s > 0) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j-1] ) ); - if (sample.s < w-1) gradient[i] = max( gradient[i], fabs( pIntensity[j] - pIntensity[j+1] ) ); + if (sample.s > 0) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j-1] ) ); + if (sample.s < w-1) gradient[i] = MAX( gradient[i], fabs( pIntensity[j] - pIntensity[j+1] ) ); } } } @@ -3048,7 +2836,7 @@ static void ComputeLightmapGradients( SSE_SampleInfo_t& info, bool const* pHasPr //----------------------------------------------------------------------------- // ComputeLuxelIntensity... //----------------------------------------------------------------------------- -static inline void ComputeLuxelIntensity( SSE_SampleInfo_t& info, int sampleIdx, +static inline void ComputeLuxelIntensity( SSE_SampleInfo_t& info, int sampleIdx, LightingValue_t **ppLightSamples, float* pSampleIntensity ) { // Compute a separate intensity for each @@ -3102,7 +2890,7 @@ static void BuildSupersampleFaceLights( lightinfo_t& l, SSE_SampleInfo_t& info, { int visualizationSize = info.m_pFaceLight->numsamples * sizeof(Vector); pVisualizePass = (Vector*)stackalloc( visualizationSize ); - memset( pVisualizePass, 0, visualizationSize ); + memset( pVisualizePass, 0, visualizationSize ); } // What's going on here is that we're looking for large lighting discontinuities @@ -3129,7 +2917,7 @@ static void BuildSupersampleFaceLights( lightinfo_t& l, SSE_SampleInfo_t& info, continue; // Don't supersample if the lighting is pretty uniform near the sample - if (pGradient[i] < 0.01) + if (pGradient[i] < 0.0625) continue; // Joy! We're supersampling now, and we therefore must do another pass @@ -3159,10 +2947,9 @@ static void BuildSupersampleFaceLights( lightinfo_t& l, SSE_SampleInfo_t& info, // Add the ambient + directional terms together, stick it back into the lightmap for (int n = 0; n < info.m_NormalCount; ++n) { - //ppLightSamples[n][i].Zero(); + ppLightSamples[n][i].Zero(); ppLightSamples[n][i].AddWeighted( pDirectLight[n],1.0f / directSupersampleCount ); ppLightSamples[n][i].AddWeighted( pAmbientLight[n], 1.0f / ambientSupersampleCount ); - ppLightSamples[n][i].Scale(1.0f / 2.0f); } // Recompute the luxel intensity based on the supersampling @@ -3183,7 +2970,7 @@ static void BuildSupersampleFaceLights( lightinfo_t& l, SSE_SampleInfo_t& info, { for (int j = 0; j face = f; // - // rotate plane + // rotate plane // VectorCopy (dplanes[f->planenum].normal, pl->facenormal); pl->facedist = dplanes[f->planenum].dist; @@ -3257,8 +3044,8 @@ static void InitSampleInfo( lightinfo_t const& l, int iThread, SSE_SampleInfo_t& if( info.m_NormalCount > 1 ) { Vector bumpVects[NUM_BUMP_VECTS]; - GetBumpNormals( info.m_pTexInfo->textureVecsTexelsPerWorldUnits[0], - info.m_pTexInfo->textureVecsTexelsPerWorldUnits[1], l.facenormal, + GetBumpNormals( info.m_pTexInfo->textureVecsTexelsPerWorldUnits[0], + info.m_pTexInfo->textureVecsTexelsPerWorldUnits[1], l.facenormal, l.facenormal, bumpVects );//&info.m_PointNormal[1] ); for ( int b = 0; b < NUM_BUMP_VECTS; ++b ) @@ -3302,7 +3089,7 @@ void BuildFacelights (int iThread, int facenum) for (j=0 ; jstyles[j] = 255; - // Trivial-reject the whole face? + // Trivial-reject the whole face? if( !( g_FacesVisibleToLights[facenum>>3] & (1 << (facenum & 7)) ) ) return; @@ -3326,11 +3113,11 @@ void BuildFacelights (int iThread, int facenum) f->styles[0] = 0; AllocateLightstyleSamples( fl, 0, sampleInfo.m_NormalCount ); - srand(facenum); // this is NOT GOOD // sample the lights at each sample location for ( int grp = 0; grp < numGroups; ++grp ) { int nSample = 4 * grp; + sample_t *sample = sampleInfo.m_pFaceLight->sample + nSample; int numSamples = min ( 4, sampleInfo.m_pFaceLight->numsamples - nSample ); @@ -3355,49 +3142,9 @@ void BuildFacelights (int iThread, int facenum) } // Iterate over all the lights and add their contribution to this group of spots - if (!do_fastsample) - { - GatherSampleLightAt4Points(sampleInfo, nSample, numSamples); - GatherSampleRadiosityOnlyAt4Points(sampleInfo, nSample, numSamples); - } - else - { - for (int i = 0; i < fastsamples; i++) - { - GatherSampleLightAt4Points(sampleInfo, nSample, numSamples); - } - - /*for (int k = 0; k < MAXLIGHTMAPS; k++) - { - LightingValue_t** pLightmaps = sampleInfo.m_pFaceLight->light[k]; - if (*pLightmaps) - { - for (int n = 0; n < sampleInfo.m_NormalCount; ++n) - { - for (int i = 0; i < numSamples; i++) - { - pLightmaps[n][nSample + i].Scale(1.0f / max(1, fastsamples) ); - } - } - } - }*/ - } + GatherSampleLightAt4Points( sampleInfo, nSample, numSamples ); } - // get rid of the -extra functionality on displacement surfaces - if (do_extra && !sampleInfo.m_IsDispFace) - { - // For each lightstyle, perform a supersampling pass - for (i = 0; i < MAXLIGHTMAPS; ++i) - { - // Stop when we run out of lightstyles - if (f->styles[i] == 255) - break; - - BuildSupersampleFaceLights(l, sampleInfo, i); - } - } - // Tell the incremental light manager that we're done with this face. if( g_pIncremental ) { @@ -3413,7 +3160,21 @@ void BuildFacelights (int iThread, int facenum) return; } - if (!g_bUseMPI) + // get rid of the -extra functionality on displacement surfaces + if (do_extra && !sampleInfo.m_IsDispFace) + { + // For each lightstyle, perform a supersampling pass + for ( i = 0; i < MAXLIGHTMAPS; ++i ) + { + // Stop when we run out of lightstyles + if (f->styles[i] == 255) + break; + + BuildSupersampleFaceLights( l, sampleInfo, i ); + } + } + + if (!g_bUseMPI) { // // This is done on the master node when MPI is used @@ -3453,7 +3214,6 @@ void BuildPatchLights( int facenum ) for (i = 0; i < fl->numsamples; i++) { AddSampleToPatch( &fl->sample[i], fl->light[k][0][i], facenum); - AddSampleToPatch(&fl->sample[i], fl->radiosity[k][0][i], facenum); } // check for a valid face @@ -3495,7 +3255,7 @@ void BuildPatchLights( int facenum ) } if (patch->samplearea) - { + { float scale; Vector v; scale = 1.0 / patch->samplearea; @@ -3578,12 +3338,12 @@ void BuildPatchLights( int facenum ) for (i=0 ; inumsamples ; i++) { // garymctchange - VectorAdd( fl->light[j][0][i], g_FacePatches[facenum]->baselight, fl->light[j][0][i] ); + VectorAdd( fl->light[j][0][i], g_FacePatches[facenum]->baselight, fl->light[j][0][i] ); if( needsBumpmap ) { for( bumpSample = 1; bumpSample < NUM_BUMP_VECTS + 1; bumpSample++ ) { - VectorAdd( fl->light[j][bumpSample][i], g_FacePatches[facenum]->baselight, fl->light[j][bumpSample][i] ); + VectorAdd( fl->light[j][bumpSample][i], g_FacePatches[facenum]->baselight, fl->light[j][bumpSample][i] ); } } } @@ -3607,7 +3367,7 @@ void PrecompLightmapOffsets() dface_t *f; int lightstyles; int lightdatasize = 0; - + // NOTE: We store avg face light data in this lump *before* the lightmap data itself // in *reverse order* of the way the lightstyles appear in the styles array. for( facenum = 0; facenum < numfaces; facenum++ ) @@ -3616,16 +3376,16 @@ void PrecompLightmapOffsets() if ( texinfo[f->texinfo].flags & TEX_SPECIAL) continue; // non-lit texture - + if ( dlight_map != 0 ) f->styles[1] = 0; - + for (lightstyles=0; lightstyles < MAXLIGHTMAPS; lightstyles++ ) { if ( f->styles[lightstyles] == 255 ) break; } - + if ( !lightstyles ) continue; @@ -3670,7 +3430,7 @@ static void ColorClampBumped( Vector& color1, Vector& color2, Vector& color3 ) // HACK! Clean this up, and add some else statements #define CONDITION(a,b,c) do { if( maxs[a] >= maxs[b] && maxs[b] >= maxs[c] ) { order[0] = a; order[1] = b; order[2] = c; } } while( 0 ) - + int order[3]; CONDITION(0,1,2); CONDITION(0,2,1); @@ -3687,7 +3447,7 @@ static void ColorClampBumped( Vector& color1, Vector& color2, Vector& color3 ) { continue; } - // This channel is too bright. . take half of the amount that we are over and + // This channel is too bright. . take half of the amount that we are over and // add it to the other two channel. float factorToRedist = ( max - 1.0f ) / max; Vector colorToRedist = factorToRedist * *colors[order[i]]; @@ -3700,7 +3460,7 @@ static void ColorClampBumped( Vector& color1, Vector& color2, Vector& color3 ) ColorClamp( color1 ); ColorClamp( color2 ); ColorClamp( color3 ); - + if( color1[0] < 0.f ) color1[0] = 0.f; if( color1[1] < 0.f ) color1[1] = 0.f; if( color1[2] < 0.f ) color1[2] = 0.f; @@ -3713,13 +3473,13 @@ static void ColorClampBumped( Vector& color1, Vector& color2, Vector& color3 ) } static void LinearToBumpedLightmap( - const float *linearColor, + const float *linearColor, const float *linearBumpColor1, - const float *linearBumpColor2, + const float *linearBumpColor2, const float *linearBumpColor3, - unsigned char *ret, + unsigned char *ret, unsigned char *retBump1, - unsigned char *retBump2, + unsigned char *retBump2, unsigned char *retBump3 ) { const Vector &linearBump1 = *( ( const Vector * )linearBumpColor1 ); @@ -3735,7 +3495,7 @@ static void LinearToBumpedLightmap( bumpAverage += linearBump2; bumpAverage += linearBump3; bumpAverage *= ( 1.0f / 3.0f ); - + Vector correctionScale; if( *( int * )&bumpAverage[0] != 0 && *( int * )&bumpAverage[1] != 0 && *( int * )&bumpAverage[2] != 0 ) { @@ -3788,51 +3548,30 @@ static void LinearToBumpedLightmap( // Convert a RGBExp32 to a RGBA8888 // This matches the engine's conversion, so the lighting result is consistent. //----------------------------------------------------------------------------- -void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst, Vector* _optOutLinear ) +void ConvertRGBExp32ToRGBA8888( const ColorRGBExp32 *pSrc, unsigned char *pDst ) { Vector linearColor; + Vector vertexColor; // convert from ColorRGBExp32 to linear space linearColor[0] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->r, ((ColorRGBExp32 *)pSrc)->exponent ); linearColor[1] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->g, ((ColorRGBExp32 *)pSrc)->exponent ); linearColor[2] = TexLightToLinear( ((ColorRGBExp32 *)pSrc)->b, ((ColorRGBExp32 *)pSrc)->exponent ); - ConvertLinearToRGBA8888( &linearColor, pDst ); - if ( _optOutLinear ) - *_optOutLinear = linearColor; -} - -//----------------------------------------------------------------------------- -// Converts a RGBExp32 to a linear color value. -//----------------------------------------------------------------------------- -void ConvertRGBExp32ToLinear(const ColorRGBExp32 *pSrc, Vector* pDst) -{ - - (*pDst)[0] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->r, ((ColorRGBExp32 *)pSrc)->exponent); - (*pDst)[1] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->g, ((ColorRGBExp32 *)pSrc)->exponent); - (*pDst)[2] = TexLightToLinear(((ColorRGBExp32 *)pSrc)->b, ((ColorRGBExp32 *)pSrc)->exponent); -} - -//----------------------------------------------------------------------------- -// Converts a linear color value (suitable for combining linearly) to an RBGA8888 value expected by the engine. -//----------------------------------------------------------------------------- -void ConvertLinearToRGBA8888(const Vector *pSrcLinear, unsigned char *pDst) -{ - Vector vertexColor; - // convert from linear space to lightmap space // cannot use mathlib routine directly because it doesn't match // the colorspace version found in the engine, which *is* the same sequence here - vertexColor[0] = LinearToVertexLight((*pSrcLinear)[0]); - vertexColor[1] = LinearToVertexLight((*pSrcLinear)[1]); - vertexColor[2] = LinearToVertexLight((*pSrcLinear)[2]); + vertexColor[0] = LinearToVertexLight( linearColor[0] ); + vertexColor[1] = LinearToVertexLight( linearColor[1] ); + vertexColor[2] = LinearToVertexLight( linearColor[2] ); // this is really a color normalization with a floor - ColorClamp(vertexColor); + ColorClamp( vertexColor ); // final [0..255] scale - pDst[0] = RoundFloatToByte(vertexColor[0] * 255.0f); - pDst[1] = RoundFloatToByte(vertexColor[1] * 255.0f); - pDst[2] = RoundFloatToByte(vertexColor[2] * 255.0f); + pDst[0] = RoundFloatToByte( vertexColor[0] * 255.0f ); + pDst[1] = RoundFloatToByte( vertexColor[1] * 255.0f ); + pDst[2] = RoundFloatToByte( vertexColor[2] * 255.0f ); pDst[3] = 255; } + diff --git a/utils/vrad/lightmap.h b/utils/vrad/lightmap.h index 89c2b9b9..a4c698da 100644 --- a/utils/vrad/lightmap.h +++ b/utils/vrad/lightmap.h @@ -73,7 +73,6 @@ struct facelight_t int numsamples; sample_t *sample; LightingValue_t *light[MAXLIGHTMAPS][NUM_BUMP_VECTS+1]; // result of direct illumination, indexed by sample - LightingValue_t* radiosity[MAXLIGHTMAPS][NUM_BUMP_VECTS + 1]; // result of sun direct illumination, indexed by sample // regularly spaced lightmap grid int numluxels; diff --git a/utils/vrad/radial.cpp b/utils/vrad/radial.cpp index 5dc99b50..767982a1 100644 --- a/utils/vrad/radial.cpp +++ b/utils/vrad/radial.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -67,9 +67,9 @@ void LuxelSpaceToWorld( lightinfo_t const *l, fltx4 s, fltx4 t, FourVectors &wor -void AddDirectToRadial( radial_t *rad, - Vector const &pnt, - Vector2D const &coordmins, Vector2D const &coordmaxs, +void AddDirectToRadial( radial_t *rad, + Vector const &pnt, + Vector2D const &coordmins, Vector2D const &coordmaxs, LightingValue_t const light[NUM_BUMP_VECTS+1], bool hasBumpmap, bool neighborHasBumpmap ) { @@ -89,19 +89,19 @@ void AddDirectToRadial( radial_t *rad, s_max = ( int )( coordmaxs[0] + 0.9999f ) + 1; // ???? t_max = ( int )( coordmaxs[1] + 0.9999f ) + 1; - s_min = max( s_min, 0 ); - t_min = max( t_min, 0 ); - s_max = min( s_max, rad->w ); - t_max = min( t_max, rad->h ); + s_min = MAX( s_min, 0 ); + t_min = MAX( t_min, 0 ); + s_max = MIN( s_max, rad->w ); + t_max = MIN( t_max, rad->h ); for( s = s_min; s < s_max; s++ ) { for( t = t_min; t < t_max; t++ ) { - float s0 = max( coordmins[0] - s, -1.0 ); - float t0 = max( coordmins[1] - t, -1.0 ); - float s1 = min( coordmaxs[0] - s, 1.0 ); - float t1 = min( coordmaxs[1] - t, 1.0 ); + float s0 = MAX( coordmins[0] - s, -1.0 ); + float t0 = MAX( coordmins[1] - t, -1.0 ); + float s1 = MIN( coordmaxs[0] - s, 1.0 ); + float t1 = MIN( coordmaxs[1] - t, 1.0 ); area = (s1 - s0) * (t1 - t0); @@ -110,7 +110,7 @@ void AddDirectToRadial( radial_t *rad, ds = fabs( coord[0] - s ); dt = fabs( coord[1] - t ); - r = max( ds, dt ); + r = MAX( ds, dt ); if (r < 0.1) { @@ -145,7 +145,7 @@ void AddDirectToRadial( radial_t *rad, { rad->light[0][i].AddWeighted( light[0], r ); } - + rad->weight[i] += r; } } @@ -154,9 +154,9 @@ void AddDirectToRadial( radial_t *rad, -void AddBouncedToRadial( radial_t *rad, - Vector const &pnt, - Vector2D const &coordmins, Vector2D const &coordmaxs, +void AddBouncedToRadial( radial_t *rad, + Vector const &pnt, + Vector2D const &coordmins, Vector2D const &coordmaxs, Vector const light[NUM_BUMP_VECTS+1], bool hasBumpmap, bool neighborHasBumpmap ) { @@ -176,8 +176,8 @@ void AddBouncedToRadial( radial_t *rad, distt = (coordmaxs[1] - coordmins[1]); // patches less than a luxel in size could be mistakeningly filtered, so clamp. - dists = max( 1.0, dists ); - distt = max( 1.0, distt ); + dists = MAX( 1.0, dists ); + distt = MAX( 1.0, distt ); // find possible domain of patch influence s_min = ( int )( coord[0] - dists * RADIALDIST ); @@ -186,10 +186,10 @@ void AddBouncedToRadial( radial_t *rad, t_max = ( int )( coord[1] + distt * RADIALDIST + 1.0f ); // clamp to valid luxel - s_min = max( s_min, 0 ); - t_min = max( t_min, 0 ); - s_max = min( s_max, rad->w ); - t_max = min( t_max, rad->h ); + s_min = MAX( s_min, 0 ); + t_min = MAX( t_min, 0 ); + s_max = MIN( s_max, rad->w ); + t_max = MIN( t_max, rad->h ); for( s = s_min; s < s_max; s++ ) { @@ -198,11 +198,11 @@ void AddBouncedToRadial( radial_t *rad, // patch influence is based on patch size ds = ( coord[0] - s ) / dists; dt = ( coord[1] - t ) / distt; - + r = RADIALDIST2 - (ds * ds + dt * dt); int i = s+t*rad->w; - + if (r > 0) { if( hasBumpmap ) @@ -227,7 +227,7 @@ void AddBouncedToRadial( radial_t *rad, { rad->light[0][i].AddWeighted( light[0], r ); } - + rad->weight[i] += r; } } @@ -249,10 +249,10 @@ void PatchLightmapCoordRange( radial_t *rad, int ndxPatch, Vector2D &mins, Vecto for (i = 0; i < w->numpoints; i++) { WorldToLuxelSpace( &rad->l, w->p[i], coord ); - mins[0] = min( mins[0], coord[0] ); - maxs[0] = max( maxs[0], coord[0] ); - mins[1] = min( mins[1], coord[1] ); - maxs[1] = max( maxs[1], coord[1] ); + mins[0] = MIN( mins[0], coord[0] ); + maxs[0] = MAX( maxs[0], coord[0] ); + mins[1] = MIN( mins[1], coord[1] ); + maxs[1] = MAX( maxs[1], coord[1] ); } } @@ -290,7 +290,7 @@ radial_t *BuildPatchRadial( int facenum ) needsBumpmap = texinfo[g_pFaces[facenum].texinfo].flags & SURF_BUMPLIGHT ? true : false; rad = AllocateRadial( facenum ); - + fn = &faceneighbor[ rad->facenum ]; CPatch *pNextPatch; @@ -305,21 +305,21 @@ radial_t *BuildPatchRadial( int facenum ) { pNextPatch = &g_Patches.Element( patch->ndxNext ); } - + // skip patches with children if (patch->child1 != g_Patches.InvalidIndex() ) continue; - + // get the range of patch lightmap texture coords int ndxPatch = patch - g_Patches.Base(); PatchLightmapCoordRange( rad, ndxPatch, mins, maxs ); - + if (patch->numtransfers == 0) { // Error, using patch that was never evaluated or has no samples // patch->totallight[1] = 255; } - + // // displacement surface patch origin position and normal vectors have been changed to // represent the displacement surface position and normal -- for radial "blending" @@ -329,12 +329,12 @@ radial_t *BuildPatchRadial( int facenum ) { Vector patchOrigin; WindingCenter (patch->winding, patchOrigin ); - AddBouncedToRadial( rad, patchOrigin, mins, maxs, patch->totallight.light, - needsBumpmap, needsBumpmap ); + AddBouncedToRadial( rad, patchOrigin, mins, maxs, patch->totallight.light, + needsBumpmap, needsBumpmap ); } else { - AddBouncedToRadial( rad, patch->origin, mins, maxs, patch->totallight.light, + AddBouncedToRadial( rad, patch->origin, mins, maxs, patch->totallight.light, needsBumpmap, needsBumpmap ); } } @@ -352,17 +352,17 @@ radial_t *BuildPatchRadial( int facenum ) { pNextPatch = &g_Patches.Element( patch->ndxNext ); } - + // skip patches with children if (patch->child1 != g_Patches.InvalidIndex() ) continue; - + // get the range of patch lightmap texture coords int ndxPatch = patch - g_Patches.Base(); PatchLightmapCoordRange( rad, ndxPatch, mins, maxs ); - + neighborNeedsBumpmap = texinfo[g_pFaces[facenum].texinfo].flags & SURF_BUMPLIGHT ? true : false; - + // // displacement surface patch origin position and normal vectors have been changed to // represent the displacement surface position and normal -- for radial "blending" @@ -372,8 +372,8 @@ radial_t *BuildPatchRadial( int facenum ) { Vector patchOrigin; WindingCenter (patch->winding, patchOrigin ); - AddBouncedToRadial( rad, patchOrigin, mins, maxs, patch->totallight.light, - needsBumpmap, needsBumpmap ); + AddBouncedToRadial( rad, patchOrigin, mins, maxs, patch->totallight.light, + needsBumpmap, needsBumpmap ); } else { @@ -421,7 +421,7 @@ radial_t *BuildLuxelRadial( int facenum, int style ) fl = &facelight[fn->neighbor[j]]; bool neighborHasBumpmap = false; - + if( texinfo[g_pFaces[fn->neighbor[j]].texinfo].flags & SURF_BUMPLIGHT ) { neighborHasBumpmap = true; @@ -551,16 +551,16 @@ bool FloatLess( float const& src1, float const& src2 ) void GetRandomColor( unsigned char *color ) { static bool firstTime = true; - + if( firstTime ) { firstTime = false; srand( 0 ); } - - color[0] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); - color[1] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); - color[2] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); + + color[0] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); + color[1] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); + color[2] = ( unsigned char )( rand() * ( 255.0f / VALVE_RAND_MAX ) ); } @@ -656,7 +656,7 @@ void FinalLightFace( int iThread, int facenum ) // test for non-lit texture if ( texinfo[f->texinfo].flags & TEX_SPECIAL) - return; + return; fl = &facelight[facenum]; @@ -669,7 +669,7 @@ void FinalLightFace( int iThread, int facenum ) if ( !lightstyles ) return; - + // // sample the triangulation // @@ -686,7 +686,7 @@ void FinalLightFace( int iThread, int facenum ) unsigned char randomColor[3]; GetRandomColor( randomColor ); #endif - + // NOTE: I'm using these RB trees to sort all the illumination values // to compute median colors. Turns out that this is a somewhat better @@ -728,7 +728,7 @@ void FinalLightFace( int iThread, int facenum ) } } - // pack the nonbump texture and the three bump texture for the given + // pack the nonbump texture and the three bump texture for the given // lightstyle right next to each other. // NOTE: Even though it's building positions for all bump-mapped data, // it isn't going to use those positions (see loop over bumpSample below) @@ -736,7 +736,7 @@ void FinalLightFace( int iThread, int facenum ) // of light data if we don't have bumped lighting. for( bumpSample = 0; bumpSample < bumpSampleCount; ++bumpSample ) { - pdata[bumpSample] = &(*pdlightdata)[f->lightofs + (k * bumpSampleCount + bumpSample) * fl->numluxels*4]; + pdata[bumpSample] = &(*pdlightdata)[f->lightofs + (k * bumpSampleCount + bumpSample) * fl->numluxels*4]; } // Compute the average luxel color, but not for the bump samples @@ -810,14 +810,14 @@ void FinalLightFace( int iThread, int facenum ) // garymct: minlight is a per entity minimum light value? for( i=0; i<3; i++ ) { - lb[bumpSample].m_vecLighting[i] = max( lb[bumpSample].m_vecLighting[i], minlight ); + lb[bumpSample].m_vecLighting[i] = MAX( lb[bumpSample].m_vecLighting[i], minlight ); } - + // Do the average light computation, I'm assuming (perhaps incorrectly?) - // that all luxels in a particular lightmap have the same area here. - // Also, don't bother doing averages for the bump samples. Doing it here - // because of the minlight clamp above + the random color testy thingy. - // Also have to do it before Vec3toColorRGBExp32 because it + // that all luxels in a particular lightmap have the same area here. + // Also, don't bother doing averages for the bump samples. Doing it here + // because of the minlight clamp above + the random color testy thingy. + // Also have to do it before Vec3toColorRGBExp32 because it // destructively modifies lb[bumpSample] (Feh!) if ((bumpSample == 0) && baseSampleOk) { diff --git a/utils/vrad/samplehash.cpp b/utils/vrad/samplehash.cpp index 09bc94ec..2c0983ea 100644 --- a/utils/vrad/samplehash.cpp +++ b/utils/vrad/samplehash.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -35,9 +35,9 @@ unsigned int SampleData_KeyFunc( SampleData_t const &src ) } -CUtlHash g_SampleHashTable( SAMPLEHASH_NUM_BUCKETS, - SAMPLEHASH_GROW_SIZE, - SAMPLEHASH_INIT_SIZE, +CUtlHash g_SampleHashTable( SAMPLEHASH_NUM_BUCKETS, + SAMPLEHASH_GROW_SIZE, + SAMPLEHASH_INIT_SIZE, SampleData_CompareFunc, SampleData_KeyFunc ); @@ -46,7 +46,7 @@ CUtlHash g_SampleHashTable( SAMPLEHASH_NUM_BUCKETS, //----------------------------------------------------------------------------- UtlHashHandle_t SampleData_Find( sample_t *pSample ) { - SampleData_t sampleData; + SampleData_t sampleData; sampleData.x = ( int )( pSample->pos.x / SAMPLEHASH_VOXEL_SIZE ) * 100; sampleData.y = ( int )( pSample->pos.y / SAMPLEHASH_VOXEL_SIZE ) * 10; sampleData.z = ( int )( pSample->pos.z / SAMPLEHASH_VOXEL_SIZE ); @@ -182,13 +182,13 @@ void PatchSampleData_AddSample( CPatch *pPatch, int ndxPatch ) GetPatchSampleHashXYZ( pPatch->origin, patchSampleMins[0], patchSampleMins[1], patchSampleMins[2] ); memcpy( patchSampleMaxs, patchSampleMins, sizeof( patchSampleMaxs ) ); #endif - + // Make sure mins are smaller than maxs so we don't iterate for 4 bil. Assert( patchSampleMins[0] <= patchSampleMaxs[0] && patchSampleMins[1] <= patchSampleMaxs[1] && patchSampleMins[2] <= patchSampleMaxs[2] ); - patchSampleMins[0] = min( patchSampleMins[0], patchSampleMaxs[0] ); - patchSampleMins[1] = min( patchSampleMins[1], patchSampleMaxs[1] ); - patchSampleMins[2] = min( patchSampleMins[2], patchSampleMaxs[2] ); - + patchSampleMins[0] = MIN( patchSampleMins[0], patchSampleMaxs[0] ); + patchSampleMins[1] = MIN( patchSampleMins[1], patchSampleMaxs[1] ); + patchSampleMins[2] = MIN( patchSampleMins[2], patchSampleMaxs[2] ); + int iterateCoords[3]; for ( iterateCoords[0]=patchSampleMins[0]; iterateCoords[0] <= patchSampleMaxs[0]; iterateCoords[0]++ ) { diff --git a/utils/vrad/vrad.cpp b/utils/vrad/vrad.cpp index ef5a77fd..c4b85496 100644 --- a/utils/vrad/vrad.cpp +++ b/utils/vrad/vrad.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -33,7 +33,7 @@ every surface must be divided into at least two patches each axis */ -CUtlVector g_Patches; +CUtlVector g_Patches; CUtlVector g_FacePatches; // contains all patches, children first CUtlVector faceParents; // contains only root patches, use next parent to iterate CUtlVector clusterChildren; @@ -60,8 +60,6 @@ bool g_bDumpRtEnv = false; bool bRed2Black = true; bool g_bFastAmbient = false; bool g_bNoSkyRecurse = false; -bool g_bDumpPropLightmaps = false; - int junk; @@ -71,6 +69,7 @@ float lightscale = 1.0; float dlight_threshold = 0.1; // was DIRECT_LIGHT constant char source[MAX_PATH] = ""; +char platformPath[MAX_PATH] = ""; char level_name[MAX_PATH] = ""; // map filename, without extension or path info @@ -87,7 +86,6 @@ bool g_bInterrupt = false; // Wsed with background lighting in WC. Tells VRAD float g_SunAngularExtent=0.0; float g_flSkySampleScale = 1.0; -float g_flSunSampleScale = 1.0; bool g_bLargeDispSampleRadius = false; @@ -101,12 +99,9 @@ float reflectivityScale = 1.0; qboolean do_extra = true; bool debug_extra = false; qboolean do_fast = false; -bool do_fastsample = false; -bool do_soften = false; -int fastsamples = 1; qboolean do_centersamples = false; int extrapasses = 4; -float smoothing_threshold = 0.7071067; // cos(45.0*(M_PI/180)) +float smoothing_threshold = 0.7071067; // cos(45.0*(M_PI/180)) // Cosine of smoothing angle(in radians) float coring = 1.0; // Light threshold to force to blackness(minimizes lightmaps) qboolean texscale = true; @@ -119,9 +114,9 @@ qboolean g_bLowPriority = false; qboolean g_bLogHashData = false; bool g_bNoDetailLighting = false; double g_flStartTime; -bool g_bStaticPropLighting = true; -bool g_bStaticPropPolys = true; -bool g_bTextureShadows = true; +bool g_bStaticPropLighting = false; +bool g_bStaticPropPolys = false; +bool g_bTextureShadows = false; bool g_bDisablePropSelfShadowing = false; @@ -287,8 +282,8 @@ void ReadLightFile (char *filename) VectorCopy( value, texlights[j].value ); texlights[j].filename = filename; file_texlights ++; - - num_texlights = max( num_texlights, j + 1 ); + + num_texlights = MAX( num_texlights, j + 1 ); } } qprintf ( "[%i texlights parsed from '%s']\n\n", file_texlights, filename); @@ -417,7 +412,7 @@ void BaseLightForFace( dface_t *f, Vector& light, float *parea, Vector& reflecti *parea = texdata->height * texdata->width; VectorScale( texdata->reflectivity, reflectivityScale, reflectivity ); - + // always keep this less than 1 or the solution will not converge for ( int i = 0; i < 3; i++ ) { @@ -566,11 +561,11 @@ void MakePatchForFace (int fn, winding_t *w) chopscale[i] = 0.0f; for( j=0; j<3; j++ ) { - patch->scale[i] += - tx->textureVecsTexelsPerWorldUnits[i][j] * + patch->scale[i] += + tx->textureVecsTexelsPerWorldUnits[i][j] * tx->textureVecsTexelsPerWorldUnits[i][j]; - chopscale[i] += - tx->lightmapVecsLuxelsPerWorldUnits[i][j] * + chopscale[i] += + tx->lightmapVecsLuxelsPerWorldUnits[i][j] * tx->lightmapVecsLuxelsPerWorldUnits[i][j]; } patch->scale[i] = sqrt( patch->scale[i] ); @@ -583,7 +578,7 @@ void MakePatchForFace (int fn, winding_t *w) } patch->area = area; - + patch->sky = IsSky( f ); // chop scaled up lightmaps coarser @@ -601,7 +596,7 @@ void MakePatchForFace (int fn, winding_t *w) // make a new plane to adjust for origined bmodels if (face_offset[fn][0] || face_offset[fn][1] || face_offset[fn][2] ) - { + { dplane_t *pl; // origin offset faces must create new planes @@ -621,7 +616,7 @@ void MakePatchForFace (int fn, winding_t *w) WindingCenter (w, patch->origin); // Save "center" for generating the face normals later. - VectorSubtract( patch->origin, face_offset[fn], face_centroids[fn] ); + VectorSubtract( patch->origin, face_offset[fn], face_centroids[fn] ); VectorCopy( patch->plane->normal, patch->normal ); @@ -823,7 +818,7 @@ int CreateChildPatch( int nParentIndex, winding_t *pWinding, float flArea, const if ( (child->face_maxs[i] == child->maxs[i] || child->face_mins[i] == child->mins[i] ) && total[i] > minchop ) { - child->chop = max( minchop, child->chop / 2 ); + child->chop = MAX( minchop, child->chop / 2 ); break; } } @@ -883,7 +878,7 @@ void SubdividePatch( int ndxPatch ) if (patch->chop > minchop) { bSubdivide = true; - patch->chop = max( minchop, patch->chop / 2 ); + patch->chop = MAX( minchop, patch->chop / 2 ); } } } @@ -915,7 +910,7 @@ void SubdividePatch( int ndxPatch ) // FIXME: This could go into CreateChildPatch if child1, child2 were stored in the patch as child[0], child[1] patch = &g_Patches.Element( ndxPatch ); patch->child1 = ndxChild1Patch; - patch->child2 = ndxChild2Patch; + patch->child2 = ndxChild2Patch; SubdividePatch( ndxChild1Patch ); SubdividePatch( ndxChild2Patch ); @@ -1239,7 +1234,7 @@ void MakeScales ( int ndxPatch, transfer_t *all_transfers ) // the total transfer should be PI, but we need to correct errors due to overlaping surfaces if (total > M_PI) total = 1.0f/total; - else + else total = 1.0f/M_PI; t = patch->transfers; @@ -1356,16 +1351,16 @@ void WriteWinding (FileHandle_t out, winding_t *w, Vector& color ) } -void WriteNormal( FileHandle_t out, Vector const &nPos, Vector const &nDir, +void WriteNormal( FileHandle_t out, Vector const &nPos, Vector const &nDir, float length, Vector const &color ) { CmdLib_FPrintf( out, "2\n" ); - CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", nPos.x, nPos.y, nPos.z, color.x / 256, color.y / 256, color.z / 256 ); - CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", - nPos.x + ( nDir.x * length ), - nPos.y + ( nDir.y * length ), + CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + nPos.x + ( nDir.x * length ), + nPos.y + ( nDir.y * length ), nPos.z + ( nDir.z * length ), color.x / 256, color.y / 256, color.z / 256 ); } @@ -1373,10 +1368,10 @@ void WriteNormal( FileHandle_t out, Vector const &nPos, Vector const &nDir, void WriteLine( FileHandle_t out, const Vector &vecPos1, const Vector &vecPos2, const Vector &color ) { CmdLib_FPrintf( out, "2\n" ); - CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", vecPos1.x, vecPos1.y, vecPos1.z, color.x / 256, color.y / 256, color.z / 256 ); - CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + CmdLib_FPrintf( out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", vecPos2.x, vecPos2.y, vecPos2.z, color.x / 256, color.y / 256, color.z / 256 ); } @@ -1491,7 +1486,7 @@ Get light from other patches #pragma warning (disable:4701) #endif -extern void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, +extern void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ); @@ -1561,7 +1556,7 @@ void GatherLight (int threadnum, void *pUserData) Vector normals[NUM_BUMP_VECTS+1]; // Disps - bool bDisp = ( g_pFaces[patch->faceNumber].dispinfo != -1 ); + bool bDisp = ( g_pFaces[patch->faceNumber].dispinfo != -1 ); if ( bDisp ) { normals[0] = patch->normal; @@ -1570,7 +1565,7 @@ void GatherLight (int threadnum, void *pUserData) PreGetBumpNormalsForDisp( pTexinfo, vecTexU, vecTexV, normals[0] ); // use facenormal along with the smooth normal to build the three bump map vectors - GetBumpNormals( vecTexU, vecTexV, normals[0], normals[0], &normals[1] ); + GetBumpNormals( vecTexU, vecTexV, normals[0], normals[0], &normals[1] ); } else { @@ -1578,8 +1573,8 @@ void GatherLight (int threadnum, void *pUserData) texinfo_t *pTexinfo = &texinfo[g_pFaces[patch->faceNumber].texinfo]; // use facenormal along with the smooth normal to build the three bump map vectors - GetBumpNormals( pTexinfo->textureVecsTexelsPerWorldUnits[0], - pTexinfo->textureVecsTexelsPerWorldUnits[1], patch->normal, + GetBumpNormals( pTexinfo->textureVecsTexelsPerWorldUnits[0], + pTexinfo->textureVecsTexelsPerWorldUnits[1], patch->normal, normals[0], &normals[1] ); } @@ -1608,7 +1603,7 @@ void GatherLight (int threadnum, void *pUserData) // remove normal already factored into transfer steradian float scale = 1.0f / DotProduct (delta, patch->normal); VectorScale( v, trans->transfer * scale, v ); - + Vector bumpTransfer; for ( i = 0; i < NUM_BUMP_VECTS+1; i++ ) { @@ -1803,7 +1798,7 @@ void RadWorld_Start() } } } - + UpdateAllFaceLightmapExtents(); } @@ -1816,7 +1811,7 @@ void RadWorld_Start() PairEdges (); // store the vertex normals calculated in PairEdges - // so that the can be written to the bsp file for + // so that the can be written to the bsp file for // use in the engine SaveVertexNormals(); @@ -1896,7 +1891,7 @@ void BuildFacesVisibleToLights( bool bAllVisible ) { int index = dleafs[iLeaf].firstleafface + iFace; index = dleaffaces[index]; - + assert( index < numfaces ); g_FacesVisibleToLights[index >> 3] |= (1 << (index & 7)); } @@ -1930,7 +1925,7 @@ void MakeAllScales (void) { // determine visibility between patches BuildVisMatrix (); - + // release visibility matrix FreeVisMatrix (); @@ -1964,7 +1959,7 @@ void MakeAllScales (void) v = dedges[-se].v[1]; else v = dedges[se].v[0]; - + dvertex_t *dv = &dvertexes[v]; points.AddToTail( dv->point ); } @@ -1988,12 +1983,12 @@ void MakeAllScales (void) params.m_bOutline = true; params.m_flLetterWidth = 2; params.m_vColor.Init( 1, 0, 0 ); - + VectorAngles( dplanes[f->planenum].normal, params.m_vAngles ); params.m_bTwoSided = true; params.m_vPos = vCenter; - + pPad->DrawText( str, params ); } @@ -2024,12 +2019,12 @@ bool RadWorld_Go() } // build initial facelights - if (g_bUseMPI) + if (g_bUseMPI) { // RunThreadsOnIndividual (numfaces, true, BuildFacelights); RunMPIBuildFacelights(); } - else + else { RunThreadsOnIndividual (numfaces, true, BuildFacelights); } @@ -2040,7 +2035,7 @@ bool RadWorld_Go() // Figure out the offset into lightmap data for each face. PrecompLightmapOffsets(); - + // If we're doing incremental lighting, stop here. if( g_pIncremental ) { @@ -2087,10 +2082,10 @@ bool RadWorld_Go() VMPI_SetCurrentStage( "FinalLightFace" ); if ( !g_bUseMPI || g_bMPIMaster ) RunThreadsOnIndividual (numfaces, true, FinalLightFace); - + // Distribute the lighting data to workers. VMPI_DistributeLightData(); - + Msg("FinalLightFace Done\n"); fflush(stdout); } @@ -2124,7 +2119,6 @@ void InitDumpPatchesFiles() } } -extern IFileSystem *g_pOriginalPassThruFileSystem; void VRAD_LoadBSP( char const *pFilename ) { @@ -2162,7 +2156,7 @@ void VRAD_LoadBSP( char const *pFilename ) if ( !g_pFileSystem->FileExists( global_lights ) ) { // Otherwise, try looking in the BIN directory from which we were run from - Msg( "Could not find lights.rad in %s.\nTrying VRAD BIN directory instead...\n", + Msg( "Could not find lights.rad in %s.\nTrying VRAD BIN directory instead...\n", global_lights ); GetModuleFileName( NULL, global_lights, sizeof( global_lights ) ); Q_ExtractFilePath( global_lights, global_lights, sizeof( global_lights ) ); @@ -2173,8 +2167,8 @@ void VRAD_LoadBSP( char const *pFilename ) strcpy( level_lights, source ); Q_DefaultExtension( level_lights, ".rad", sizeof( level_lights ) ); - if ( !g_pFileSystem->FileExists( level_lights ) ) - *level_lights = 0; + if ( !g_pFileSystem->FileExists( level_lights ) ) + *level_lights = 0; ReadLightFile(global_lights); // Required if ( *designer_lights ) ReadLightFile(designer_lights); // Command-line @@ -2184,23 +2178,11 @@ void VRAD_LoadBSP( char const *pFilename ) Q_DefaultExtension(incrementfile, ".r0", sizeof(incrementfile)); Q_DefaultExtension(source, ".bsp", sizeof( source )); - Msg( "Loading %s\n", source ); - VMPI_SetCurrentStage( "LoadBSPFile" ); - LoadBSPFile (source); + GetPlatformMapPath( source, platformPath, 0, MAX_PATH ); - // Add this bsp to our search path so embedded resources can be found - if ( g_bUseMPI && g_bMPIMaster ) - { - // MPI Master, MPI workers don't need to do anything - g_pOriginalPassThruFileSystem->AddSearchPath(source, "GAME", PATH_ADD_TO_HEAD); - g_pOriginalPassThruFileSystem->AddSearchPath(source, "MOD", PATH_ADD_TO_HEAD); - } - else if ( !g_bUseMPI ) - { - // Non-MPI - g_pFullFileSystem->AddSearchPath(source, "GAME", PATH_ADD_TO_HEAD); - g_pFullFileSystem->AddSearchPath(source, "MOD", PATH_ADD_TO_HEAD); - } + Msg( "Loading %s\n", platformPath ); + VMPI_SetCurrentStage( "LoadBSPFile" ); + LoadBSPFile (platformPath); // now, set whether or not static prop lighting is present if (g_bStaticPropLighting) @@ -2318,7 +2300,7 @@ extern void CloseDispLuxels(); void VRAD_Finish() { - Msg( "Ready to Finish\n" ); + Msg( "Ready to Finish\n" ); fflush( stdout ); if ( verbose ) @@ -2326,9 +2308,9 @@ void VRAD_Finish() PrintBSPFileSizes(); } - Msg( "Writing %s\n", source ); + Msg( "Writing %s\n", platformPath ); VMPI_SetCurrentStage( "WriteBSPFile" ); - WriteBSPFile(source); + WriteBSPFile(platformPath); if ( g_bDumpPatches ) { @@ -2346,7 +2328,7 @@ void VRAD_Finish() StaticPropMgr()->Shutdown(); double end = Plat_FloatTime(); - + char str[512]; GetHourMinuteSecondsString( (int)( end - g_flStartTime ), str, sizeof( str ) ); Msg( "%s elapsed\n", str ); @@ -2355,7 +2337,7 @@ void VRAD_Finish() } -// Run startup code like initialize mathlib (called from main() and from the +// Run startup code like initialize mathlib (called from main() and from the // WorldCraft interface into vrad). void VRAD_Init() { @@ -2369,17 +2351,14 @@ int ParseCommandLine( int argc, char **argv, bool *onlydetail ) { *onlydetail = false; - int mapArg = -1; - // default to LDR SetHDRMode( false ); - int i; for( i=1 ; i= 1310 ) @@ -2950,18 +2876,13 @@ int RunVRAD( int argc, char **argv ) bool onlydetail; int i = ParseCommandLine( argc, argv, &onlydetail ); - if (i == -1) + if (i != argc - 1) { PrintUsage( argc, argv ); DeleteCmdLine( argc, argv ); CmdLib_Exit( 1 ); } - // Initialize the filesystem, so additional commandline options can be loaded - Q_StripExtension( argv[ i ], source, sizeof( source ) ); - CmdLib_InitFileSystem( argv[ i ] ); - Q_FileBase( source, source, sizeof( source ) ); - VRAD_LoadBSP( argv[i] ); if ( (! onlydetail) && (! g_bOnlyStaticProps ) ) @@ -2990,6 +2911,11 @@ int VRAD_Main(int argc, char **argv) // This must come first. VRAD_SetupMPI( argc, argv ); + // Initialize the filesystem, so additional commandline options can be loaded + Q_StripExtension( argv[ argc - 1 ], source, sizeof( source ) ); + CmdLib_InitFileSystem( argv[ argc - 1 ] ); + Q_FileBase( source, source, sizeof( source ) ); + #if !defined( _DEBUG ) if ( g_bUseMPI && !g_bMPIMaster ) { @@ -3001,7 +2927,7 @@ int VRAD_Main(int argc, char **argv) LoadCmdLineFromFile( argc, argv, source, "vrad" ); // Don't do this if we're a VMPI worker.. SetupDefaultToolsMinidumpHandler(); } - + return RunVRAD( argc, argv ); } diff --git a/utils/vrad/vrad.h b/utils/vrad/vrad.h index 4ef9e488..95fcd151 100644 --- a/utils/vrad/vrad.h +++ b/utils/vrad/vrad.h @@ -90,14 +90,13 @@ struct directlight_t float m_flStartFadeDistance; float m_flEndFadeDistance; float m_flCapDist; // max distance to feed in - bool m_bStatic; // for radiosity only calculations (direct light is assumed to be rendered in game) directlight_t(void) { m_flEndFadeDistance = -1.0; // endlightmapVecsLuxelsPerWorldUnits[0][2] ); float flWidth = 1.0f / VectorLength( vecTmp ); float flHeight = flWidth; - + // Save off the sample width and height. m_flSampleWidth = flWidth; m_flSampleHeight = flHeight; // Calculate the sample radius squared. - float flSampleRadius = sqrt( ( ( flWidth * flWidth ) + ( flHeight * flHeight ) ) ) * 2.2f;//RADIALDIST2; + float flSampleRadius = sqrt( ( ( flWidth * flWidth ) + ( flHeight * flHeight ) ) ) * 2.2f;//RADIALDIST2; if ( flSampleRadius > g_flMaxDispSampleSize ) { flSampleRadius = g_flMaxDispSampleSize; @@ -109,7 +109,7 @@ void CVRADDispColl::CalcSampleRadius2AndBox( dface_t *pFace ) m_flSampleRadius2 = flSampleRadius * flSampleRadius; // Calculate the patch radius - the max sample edge length * the number of luxels per edge "chop." - float flSampleSize = max( m_flSampleWidth, m_flSampleHeight ); + float flSampleSize = MAX( m_flSampleWidth, m_flSampleHeight ); float flPatchSampleRadius = flSampleSize * dispchop * 2.2f; if ( flPatchSampleRadius > g_MaxDispPatchRadius ) { @@ -211,8 +211,8 @@ void CVRADDispColl::DispUVToSurfPoint( Vector2D const &dispUV, Vector &vecPoint, //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CVRADDispColl::DispUVToSurf_TriTLToBR( Vector &vecPoint, float flPushEps, - float flU, float flV, int nSnapU, int nSnapV, +void CVRADDispColl::DispUVToSurf_TriTLToBR( Vector &vecPoint, float flPushEps, + float flU, float flV, int nSnapU, int nSnapV, int nWidth, int nHeight ) { int nNextU = nSnapU + 1; @@ -227,7 +227,7 @@ void CVRADDispColl::DispUVToSurf_TriTLToBR( Vector &vecPoint, float flPushEps, { int nIndices[3]; nIndices[0] = nNextV * nWidth + nSnapU; - nIndices[1] = nNextV * nWidth + nNextU; + nIndices[1] = nNextV * nWidth + nNextU; nIndices[2] = nSnapV * nWidth + nNextU; Vector edgeU = m_aVerts[nIndices[0]] - m_aVerts[nIndices[1]]; @@ -266,8 +266,8 @@ void CVRADDispColl::DispUVToSurf_TriTLToBR( Vector &vecPoint, float flPushEps, //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -void CVRADDispColl::DispUVToSurf_TriBLToTR( Vector &vecPoint, float flPushEps, - float flU, float flV, int nSnapU, int nSnapV, +void CVRADDispColl::DispUVToSurf_TriBLToTR( Vector &vecPoint, float flPushEps, + float flU, float flV, int nSnapU, int nSnapV, int nWidth, int nHeight ) { int nNextU = nSnapU + 1; @@ -355,7 +355,7 @@ void CVRADDispColl::DispUVToSurfNormal( Vector2D const &dispUV, Vector &vecNorma // Find the blended normal (bi-linear). Vector vecTmpNormals[2], vecBlendedNormals[2], vecDispNormals[4]; - + for ( int iVert = 0; iVert < VRAD_QUAD_SIZE; ++iVert ) { GetVertNormal( iQuad[iVert], vecDispNormals[iVert] ); @@ -379,7 +379,7 @@ void CVRADDispColl::DispUVToSurfNormal( Vector2D const &dispUV, Vector &vecNorma } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: // Output : float //----------------------------------------------------------------------------- float CVRADDispColl::CreateParentPatches( void ) @@ -414,9 +414,9 @@ float CVRADDispColl::CreateParentPatches( void ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : iParentPatch - -// nLevel - +// Purpose: +// Input : iParentPatch - +// nLevel - //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatchesFromRoot( int iParentPatch, int *pChildPatch ) { @@ -440,7 +440,7 @@ void CVRADDispColl::CreateChildPatchesFromRoot( int iParentPatch, int *pChildPat vecEdges[3] = pParentPatch->winding->p[3] - pParentPatch->winding->p[0]; // Should the patch be subdivided - check the area. - float flMaxLength = max( m_flSampleWidth, m_flSampleHeight ); + float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Find the longest edge. @@ -521,8 +521,8 @@ void CVRADDispColl::CreateChildPatchesFromRoot( int iParentPatch, int *pChildPat } //----------------------------------------------------------------------------- -// Purpose: -// Input : flMinArea - +// Purpose: +// Input : flMinArea - // Output : float //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatches( int iParentPatch, int nLevel ) @@ -551,7 +551,7 @@ void CVRADDispColl::CreateChildPatches( int iParentPatch, int nLevel ) return; // Should the patch be subdivided - check the area. - float flMaxLength = max( m_flSampleWidth, m_flSampleHeight ); + float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Split along the longest edge. @@ -634,7 +634,7 @@ void CVRADDispColl::CreateChildPatches( int iParentPatch, int nLevel ) } } } - + // Continue creating children patches. int nNewLevel = ++nLevel; CreateChildPatches( iChildPatch[0], nNewLevel ); @@ -642,8 +642,8 @@ void CVRADDispColl::CreateChildPatches( int iParentPatch, int nLevel ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : flMinArea - +// Purpose: +// Input : flMinArea - // Output : float //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatchesSub( int iParentPatch ) @@ -659,7 +659,7 @@ void CVRADDispColl::CreateChildPatchesSub( int iParentPatch ) return; // Should the patch be subdivided - check the area. - float flMaxLength = max( m_flSampleWidth, m_flSampleHeight ); + float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Split along the longest edge. @@ -757,7 +757,7 @@ void CVRADDispColl::CreateChildPatchesSub( int iParentPatch ) } } } - + // Continue creating children patches. CreateChildPatchesSub( iChildPatch[0] ); CreateChildPatchesSub( iChildPatch[1] ); @@ -767,7 +767,7 @@ int PlaneTypeForNormal (Vector& normal) { vec_t ax, ay, az; - // NOTE: should these have an epsilon around 1.0? + // NOTE: should these have an epsilon around 1.0? if (normal[0] == 1.0 || normal[0] == -1.0) return PLANE_X; if (normal[1] == 1.0 || normal[1] == -1.0) @@ -787,13 +787,13 @@ int PlaneTypeForNormal (Vector& normal) } //----------------------------------------------------------------------------- -// Purpose: -// Input : iPatch - -// iParentPatch - -// iChild - -// *pPoints - -// *pIndices - -// &flArea - +// Purpose: +// Input : iPatch - +// iParentPatch - +// iChild - +// *pPoints - +// *pIndices - +// &flArea - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CVRADDispColl::InitParentPatch( int iPatch, Vector *pPoints, float &flArea ) @@ -870,8 +870,8 @@ bool CVRADDispColl::InitParentPatch( int iPatch, Vector *pPoints, float &flArea { for ( int iAxis = 0; iAxis < 3; ++iAxis ) { - vecMin[iAxis] = min( vecMin[iAxis], pPoints[iPoint][iAxis] ); - vecMax[iAxis] = max( vecMax[iAxis], pPoints[iPoint][iAxis] ); + vecMin[iAxis] = MIN( vecMin[iAxis], pPoints[iPoint][iAxis] ); + vecMax[iAxis] = MAX( vecMax[iAxis], pPoints[iPoint][iAxis] ); } } @@ -895,11 +895,11 @@ bool CVRADDispColl::InitParentPatch( int iPatch, Vector *pPoints, float &flArea } //----------------------------------------------------------------------------- -// Purpose: -// Input : *pPatch - -// *pPoints - -// &vecNormal - -// flArea - +// Purpose: +// Input : *pPatch - +// *pPoints - +// &vecNormal - +// flArea - //----------------------------------------------------------------------------- bool CVRADDispColl::InitPatch( int iPatch, int iParentPatch, int iChild, Vector *pPoints, int *pIndices, float &flArea ) { @@ -1019,8 +1019,8 @@ bool CVRADDispColl::InitPatch( int iPatch, int iParentPatch, int iChild, Vector { for ( int iAxis = 0; iAxis < 3; ++iAxis ) { - vecMin[iAxis] = min( vecMin[iAxis], pPoints[iPoint][iAxis] ); - vecMax[iAxis] = max( vecMax[iAxis], pPoints[iPoint][iAxis] ); + vecMin[iAxis] = MIN( vecMin[iAxis], pPoints[iPoint][iAxis] ); + vecMax[iAxis] = MAX( vecMax[iAxis], pPoints[iPoint][iAxis] ); } } @@ -1077,4 +1077,4 @@ void CVRADDispColl::AddPolysForRayTrace( void ) fullCoverage.x = 1.0f; g_RtEnv.AddTriangle( TRACE_ID_OPAQUE, m_aVerts[v[0]], m_aVerts[v[1]], m_aVerts[v[2]], fullCoverage ); } -} \ No newline at end of file +} diff --git a/utils/vrad/vrad_dll.vpc b/utils/vrad/vrad_dll.vpc index 7ebef01d..e4a34226 100644 --- a/utils/vrad/vrad_dll.vpc +++ b/utils/vrad/vrad_dll.vpc @@ -6,6 +6,7 @@ $Macro SRCDIR "..\.." $Macro OUTBINDIR "$SRCDIR\..\game\bin" +$Macro OUTBINNAME "vrad_dll" $Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" @@ -219,7 +220,6 @@ $Project "Vrad_dll" $Lib tier2 $Lib vmpi $Lib vtf - $Lib "$LIBCOMMON/lzma" } $File "notes.txt" diff --git a/utils/vrad/vraddetailprops.cpp b/utils/vrad/vraddetailprops.cpp index c782ca29..93232595 100644 --- a/utils/vrad/vraddetailprops.cpp +++ b/utils/vrad/vraddetailprops.cpp @@ -738,9 +738,7 @@ void ComputeIndirectLightingAtPoint( Vector &position, Vector &normal, Vector &o ColorRGBExp32ToVector( *pLightmap, lightmapColor ); } - float invLengthSqr = 1.0f / (1.0f + ((vEnd - position) * surfEnum.m_HitFrac / 128.0).LengthSqr()); - // Include falloff using invsqrlaw. - VectorMultiply( lightmapColor, invLengthSqr * dtexdata[pTex->texdata].reflectivity, lightmapColor ); + VectorMultiply( lightmapColor, dtexdata[pTex->texdata].reflectivity, lightmapColor ); VectorAdd( outColor, lightmapColor, outColor ); } diff --git a/utils/vrad/vraddisps.cpp b/utils/vrad/vraddisps.cpp index d6bc6f7a..717804bc 100644 --- a/utils/vrad/vraddisps.cpp +++ b/utils/vrad/vraddisps.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -41,7 +41,7 @@ class CBSPDispFaceListEnumerator : public ISpatialLeafEnumerator, public IBSPTre } // ISpatialLeafEnumerator - bool EnumerateLeaf( int ndxLeaf, int context ); + bool EnumerateLeaf( int ndxLeaf, int context ); // IBSPTreeDataEnumerator bool FASTCALL EnumerateElement( int userId, int context ); @@ -111,9 +111,9 @@ class CVRadDispMgr : public IVRadDispMgr // bsp tree functions bool ClipRayToDisp( DispTested_t &dispTested, Ray_t const &ray ); bool ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf ); - void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf, + void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf, float& dist, dface_t*& pFace, Vector2D& luxelCoord ); - void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, + void ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf, float& dist, Vector *pNormal ); void StartRayTest( DispTested_t &dispTested ); @@ -159,14 +159,14 @@ class CVRadDispMgr : public IVRadDispMgr radial_t *pRadial, int ndxRadial, bool bBump, int lightStyle ); void RadialPatchBuild( CVRADDispColl *pDispTree, radial_t *pRadial, bool bBump ); - void RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, - Vector const &luxelNormal, float radius, + void RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, + Vector const &luxelNormal, float radius, radial_t *pRadial, int ndxRadial, bool bBump, CUtlVector &interestingPatches ); bool IsNeighbor( int iDispFace, int iNeighborFace ); - void GetInterestingPatchesForLuxels( + void GetInterestingPatchesForLuxels( int ndxFace, CUtlVector &interestingPatches, float patchSampleRadius ); @@ -215,8 +215,8 @@ IVRadDispMgr *StaticDispMgr( void ) // Displacement/Face List // // ISpatialLeafEnumerator -bool CBSPDispFaceListEnumerator::EnumerateLeaf( int ndxLeaf, int context ) -{ +bool CBSPDispFaceListEnumerator::EnumerateLeaf( int ndxLeaf, int context ) +{ return s_DispMgr.DispFaceList_EnumerateLeaf( ndxLeaf, context ); } @@ -298,7 +298,7 @@ void CVRadDispMgr::InsertDispIntoTree( int ndxDisp ) dispTree.m_Handle = m_pBSPTreeData->Insert( ndxDisp, boxMin, boxMax ); } - + //----------------------------------------------------------------------------- // Remove a displacement from the tree for collision //----------------------------------------------------------------------------- @@ -358,7 +358,7 @@ void CVRadDispMgr::DispBuilderInit( CCoreDispInfo *pBuilderDisp, dface_t *pFace, CCoreDispSurface *pSurf = pBuilderDisp->GetSurface(); pSurf->SetPointCount( 4 ); pSurf->SetHandle( ndxFace ); - pSurf->SetContents( pDisp->contents ); + pSurf->SetContents( pDisp->contents ); Vector pt[4]; int ndxPt; @@ -405,16 +405,16 @@ void CVRadDispMgr::DispBuilderInit( CCoreDispInfo *pBuilderDisp, dface_t *pFace, pSurf->CalcLuxelCoords( nLuxelsPerWorldUnit, false, vecU, vecV ); pBuilderDisp->SetNeighborData( pDisp->m_EdgeNeighbors, pDisp->m_CornerNeighbors ); - + CDispVert *pVerts = &g_DispVerts[ pDisp->m_iDispVertStart ]; CDispTri *pTris = &g_DispTris[pDisp->m_iDispTriStart]; // // initialize the displacement data // - pBuilderDisp->InitDispInfo( - pDisp->power, - pDisp->minTess, + pBuilderDisp->InitDispInfo( + pDisp->power, + pDisp->minTess, pDisp->smoothingAngle, pVerts, pTris ); @@ -423,7 +423,7 @@ void CVRadDispMgr::DispBuilderInit( CCoreDispInfo *pBuilderDisp, dface_t *pFace, //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CVRadDispMgr::UnserializeDisps( void ) +void CVRadDispMgr::UnserializeDisps( void ) { // temporarily create the "builder" displacements CUtlVector builderDisps; @@ -527,7 +527,7 @@ void CVRadDispMgr::SubdividePatch( int iPatch ) // Create children patches. DispCollTree_t &dispTree = m_DispTrees[g_pFaces[pPatch->faceNumber].dispinfo]; - CVRADDispColl *pTree = dispTree.m_pDispTree; + CVRADDispColl *pTree = dispTree.m_pDispTree; if( pTree ) { pTree->CreateChildPatches( iPatch, 0 ); @@ -568,7 +568,7 @@ bool CVRadDispMgr::ClipRayToDisp( DispTested_t &dispTested, Ray_t const &ray ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -bool CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, +bool CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf ) { EnumContext_t ctx; @@ -580,7 +580,7 @@ bool CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &r //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, +void CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf, float& dist, dface_t*& pFace, Vector2D& luxelCoord ) { CBSPDispRayDistanceEnumerator rayTestEnum; @@ -597,7 +597,7 @@ void CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &r } } -void CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, +void CVRadDispMgr::ClipRayToDispInLeaf( DispTested_t &dispTested, Ray_t const &ray, int ndxLeaf, float& dist, Vector *pNormal ) { CBSPDispRayDistanceEnumerator rayTestEnum; @@ -634,7 +634,7 @@ void CVRadDispMgr::GetDispSurfNormal( int ndxFace, Vector &pt, Vector &ptNormal, // get the displacement surface data DispCollTree_t &dispTree = m_DispTrees[g_pFaces[ndxFace].dispinfo]; CVRADDispColl *pDispTree = dispTree.m_pDispTree; - + // find the parameterized displacement indices Vector2D uv; pDispTree->BaseFacePlaneToDispUV( pt, uv ); @@ -728,7 +728,7 @@ bool CVRadDispMgr::DispRayDistance_EnumerateElement( int userId, CBSPDispRayDist pCtx->m_pSurface = &g_pFaces[dispTree.m_pDispTree->GetParentIndex()]; // Get the luxel coordinate - ComputePointFromBarycentric( + ComputePointFromBarycentric( dispTree.m_pDispTree->GetLuxelCoord(output.ndxVerts[0]), dispTree.m_pDispTree->GetLuxelCoord(output.ndxVerts[1]), dispTree.m_pDispTree->GetLuxelCoord(output.ndxVerts[2]), @@ -828,7 +828,7 @@ bool CVRadDispMgr::DispFaceList_EnumerateElement( int userId, int context ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -inline void GetSampleLight( facelight_t *pFaceLight, int ndxStyle, bool bBumped, +inline void GetSampleLight( facelight_t *pFaceLight, int ndxStyle, bool bBumped, int ndxSample, LightingValue_t *pSampleLight ) { // SampleLight[0].Init( 20.0f, 10.0f, 10.0f ); @@ -855,8 +855,8 @@ inline void GetSampleLight( facelight_t *pFaceLight, int ndxStyle, bool bBumped, void AddSampleLightToRadial( Vector const &samplePos, Vector const &sampleNormal, LightingValue_t *pSampleLight, float sampleRadius2, Vector const &luxelPos, Vector const &luxelNormal, - radial_t *pRadial, int ndxRadial, bool bBumped, - bool bNeighborBumped ) + radial_t *pRadial, int ndxRadial, bool bBumped, + bool bNeighborBumped ) { // check normals to see if sample contributes any light at all float angle = sampleNormal.Dot( luxelNormal ); @@ -941,7 +941,7 @@ void CVRadDispMgr::RadialLuxelAddSamples( int ndxFace, Vector const &luxelPt, Ve voxelMax[axis] = ( int )( ( luxelPt[axis] + radius ) * ooVoxelSize ) + 1; } - SampleData_t sampleData; + SampleData_t sampleData; for( int ndxZ = voxelMin[2]; ndxZ < voxelMax[2] + 1; ndxZ++ ) { for( int ndxY = voxelMin[1]; ndxY < voxelMax[1] + 1; ndxY++ ) @@ -951,7 +951,7 @@ void CVRadDispMgr::RadialLuxelAddSamples( int ndxFace, Vector const &luxelPt, Ve sampleData.x = ndxX * 100; sampleData.y = ndxY * 10; sampleData.z = ndxZ; - + UtlHashHandle_t handle = g_SampleHashTable.Find( sampleData ); if( handle != g_SampleHashTable.InvalidHandle() ) { @@ -983,10 +983,10 @@ void CVRadDispMgr::RadialLuxelAddSamples( int ndxFace, Vector const &luxelPt, Ve } if( ndxNeighborStyle == -1 ) continue; - + // is this surface bumped??? bool bNeighborBump = texinfo[pFace->texinfo].flags & SURF_BUMPLIGHT ? true : false; - + LightingValue_t sampleLight[NUM_BUMP_VECTS+1]; GetSampleLight( pFaceLight, ndxNeighborStyle, bNeighborBump, ndxSample, sampleLight ); AddSampleLightToRadial( pFaceLight->sample[ndxSample].pos, pFaceLight->sample[ndxSample].normal, @@ -1099,7 +1099,7 @@ void GetPatchLight( CPatch *pPatch, bool bBump, Vector *pPatchLight ) } } -extern void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, +extern void GetBumpNormals( const float* sVect, const float* tVect, const Vector& flatNormal, const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ); extern void PreGetBumpNormalsForDisp( texinfo_t *pTexinfo, Vector &vecU, Vector &vecV, Vector &vecNormal ); @@ -1108,8 +1108,8 @@ extern void PreGetBumpNormalsForDisp( texinfo_t *pTexinfo, Vector &vecU, Vector void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal, Vector *pPatchLight, float patchRadius2, Vector const &luxelPos, Vector const &luxelNormal, - radial_t *pRadial, int ndxRadial, bool bBump, - bool bNeighborBump ) + radial_t *pRadial, int ndxRadial, bool bBump, + bool bNeighborBump ) { // calculate the light vector Vector vSegment = patchOrigin - luxelPos; @@ -1130,12 +1130,12 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal texinfo_t *pTexinfo = &texinfo[g_pFaces[pRadial->facenum].texinfo]; Vector vecTexU, vecTexV; PreGetBumpNormalsForDisp( pTexinfo, vecTexU, vecTexV, normals[0] ); - GetBumpNormals( vecTexU, vecTexV, normals[0], normals[0], &normals[1] ); + GetBumpNormals( vecTexU, vecTexV, normals[0], normals[0], &normals[1] ); if( bNeighborBump ) { float flScale = patchNormal.Dot( normals[0] ); - flScale = max( 0.0f, flScale ); + flScale = MAX( 0.0f, flScale ); float flBumpInfluence = influence * flScale; for( int ndxBump = 0; ndxBump < ( NUM_BUMP_VECTS+1 ); ndxBump++ ) @@ -1148,7 +1148,7 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal else { float flScale = patchNormal.Dot( normals[0] ); - flScale = max( 0.0f, flScale ); + flScale = MAX( 0.0f, flScale ); float flBumpInfluence = influence * flScale * 0.05f; for( int ndxBump = 0; ndxBump < ( NUM_BUMP_VECTS+1 ); ndxBump++ ) @@ -1162,7 +1162,7 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal else { float flScale = patchNormal.Dot( luxelNormal ); - flScale = max( 0.0f, flScale ); + flScale = MAX( 0.0f, flScale ); influence *= flScale; pRadial->light[0][ndxRadial].AddWeighted( pPatchLight[0], influence ); @@ -1173,17 +1173,17 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, - Vector const &luxelNormal, float radius, +void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, + Vector const &luxelNormal, float radius, radial_t *pRadial, int ndxRadial, bool bBump, CUtlVector &interestingPatches ) { #ifdef SAMPLEHASH_QUERY_ONCE for ( int i=0; i < interestingPatches.Count(); i++ ) { - CPatch *pPatch = interestingPatches[i]; + CPatch *pPatch = interestingPatches[i]; bool bNeighborBump = texinfo[g_pFaces[pPatch->faceNumber].texinfo].flags & SURF_BUMPLIGHT ? true : false; - + Vector patchLight[NUM_BUMP_VECTS+1]; GetPatchLight( pPatch, bBump, patchLight ); AddPatchLightToRadial( pPatch->origin, pPatch->normal, patchLight, radius*radius, @@ -1204,7 +1204,7 @@ void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, } unsigned short curIterationKey = IncrementPatchIterationKey(); - PatchSampleData_t patchData; + PatchSampleData_t patchData; for ( int ndxZ = voxelMin[2]; ndxZ < voxelMax[2] + 1; ndxZ++ ) { for ( int ndxY = voxelMin[1]; ndxY < voxelMax[1] + 1; ndxY++ ) @@ -1214,7 +1214,7 @@ void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, patchData.x = ndxX * 100; patchData.y = ndxY * 10; patchData.z = ndxZ; - + UtlHashHandle_t handle = g_PatchSampleHashTable.Find( patchData ); if ( handle != g_PatchSampleHashTable.InvalidHandle() ) { @@ -1227,11 +1227,11 @@ void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, if ( pPatch && pPatch->m_IterationKey != curIterationKey ) { pPatch->m_IterationKey = curIterationKey; - + if ( IsNeighbor( ndxFace, pPatch->faceNumber ) ) - { + { bool bNeighborBump = texinfo[g_pFaces[pPatch->faceNumber].texinfo].flags & SURF_BUMPLIGHT ? true : false; - + Vector patchLight[NUM_BUMP_VECTS+1]; GetPatchLight( pPatch, bBump, patchLight ); AddPatchLightToRadial( pPatch->origin, pPatch->normal, patchLight, radius*radius, @@ -1247,12 +1247,12 @@ void CVRadDispMgr::RadialLuxelAddPatch( int ndxFace, Vector const &luxelPt, } -void CVRadDispMgr::GetInterestingPatchesForLuxels( +void CVRadDispMgr::GetInterestingPatchesForLuxels( int ndxFace, CUtlVector &interestingPatches, float patchSampleRadius ) { - facelight_t *pFaceLight = &facelight[ndxFace]; + facelight_t *pFaceLight = &facelight[ndxFace]; // Get the max bounds of all voxels that these luxels touch. Vector vLuxelMin( FLT_MAX, FLT_MAX, FLT_MAX ); @@ -1262,7 +1262,7 @@ void CVRadDispMgr::GetInterestingPatchesForLuxels( VectorMin( pFaceLight->luxel[i], vLuxelMin, vLuxelMin ); VectorMax( pFaceLight->luxel[i], vLuxelMax, vLuxelMax ); } - + int allVoxelMin[3], allVoxelMax[3]; for ( int axis = 0; axis < 3; axis++ ) { @@ -1276,7 +1276,7 @@ void CVRadDispMgr::GetInterestingPatchesForLuxels( CUtlVector voxelBits; voxelBits.SetSize( ((allVoxelSize[0] * allVoxelSize[1] * allVoxelSize[2]) + 7) / 8 ); memset( voxelBits.Base(), 0, voxelBits.Count() ); - + for ( int i=0; i < pFaceLight->numluxels; i++ ) { int voxelMin[3], voxelMax[3]; @@ -1292,17 +1292,17 @@ void CVRadDispMgr::GetInterestingPatchesForLuxels( { for ( int z=voxelMin[2]; z < voxelMax[2]; z++ ) { - int iBit = (z - allVoxelMin[2])*(allVoxelSize[0]*allVoxelSize[1]) + - (y-allVoxelMin[1])*allVoxelSize[0] + + int iBit = (z - allVoxelMin[2])*(allVoxelSize[0]*allVoxelSize[1]) + + (y-allVoxelMin[1])*allVoxelSize[0] + (x-allVoxelMin[0]); voxelBits[iBit>>3] |= (1 << (iBit & 7)); } } } } - - - // Now get the list of patches that touch those voxels. + + + // Now get the list of patches that touch those voxels. unsigned short curIterationKey = IncrementPatchIterationKey(); for ( int x=0; x < allVoxelSize[0]; x++ ) @@ -1316,28 +1316,28 @@ void CVRadDispMgr::GetInterestingPatchesForLuxels( unsigned char val = voxelBits[iBit>>3] & (1 << (iBit & 7)); if ( !val ) continue; - - PatchSampleData_t patchData; + + PatchSampleData_t patchData; patchData.x = (x + allVoxelMin[0]) * 100; patchData.y = (y + allVoxelMin[1]) * 10; patchData.z = (z + allVoxelMin[2]); - + UtlHashHandle_t handle = g_PatchSampleHashTable.Find( patchData ); if ( handle != g_PatchSampleHashTable.InvalidHandle() ) { PatchSampleData_t *pPatchData = &g_PatchSampleHashTable.Element( handle ); - + // For all patches that touch this hash table element.. for ( int ndx = 0; ndx < pPatchData->m_ndxPatches.Count(); ndx++ ) { int ndxPatch = pPatchData->m_ndxPatches.Element( ndx ); CPatch *pPatch = &g_Patches.Element( ndxPatch ); - + // If we haven't touched the patch already and it's a valid neighbor, then we want to use it. if ( pPatch && pPatch->m_IterationKey != curIterationKey ) { pPatch->m_IterationKey = curIterationKey; - + if ( IsNeighbor( ndxFace, pPatch->faceNumber ) ) { interestingPatches.AddToTail( pPatch ); @@ -1374,13 +1374,13 @@ void CVRadDispMgr::RadialPatchBuild( CVRADDispColl *pDispTree, radial_t *pRadial int radialSize = pRadial->w * pRadial->h; for( int ndxRadial = 0; ndxRadial < radialSize; ndxRadial++ ) { - RadialLuxelAddPatch( - ndxFace, - pFaceLight->luxel[ndxRadial], + RadialLuxelAddPatch( + ndxFace, + pFaceLight->luxel[ndxRadial], pFaceLight->luxelNormals[ndxRadial], - radius, - pRadial, - ndxRadial, + radius, + pRadial, + ndxRadial, bBump, interestingPatches ); } @@ -1435,7 +1435,7 @@ void CVRadDispMgr::InsertSamplesDataIntoHashTable( void ) facelight_t *pFaceLight = &facelight[ndxFace]; if( !pFace || !pFaceLight ) continue; - + if( texinfo[pFace->texinfo].flags & TEX_SPECIAL ) continue; @@ -1465,7 +1465,7 @@ void CVRadDispMgr::InsertSamplesDataIntoHashTable( void ) // create the sample handle SampleHandle_t sampleHandle = ndxSample; sampleHandle |= ( ndxFace << 16 ); - + SampleData_AddSample( pSample, sampleHandle ); } @@ -1500,10 +1500,10 @@ void CVRadDispMgr::InsertPatchSampleDataIntoHashTable( void ) facelight_t *pFaceLight = &facelight[ndxFace]; if( !pFace || !pFaceLight ) continue; - + if( texinfo[pFace->texinfo].flags & TEX_SPECIAL ) continue; - + // // for each patch // @@ -1518,11 +1518,11 @@ void CVRadDispMgr::InsertPatchSampleDataIntoHashTable( void ) { pNextPatch = &g_Patches.Element( pPatch->ndxNext ); } - + // skip patches with children if( pPatch->child1 != g_Patches.InvalidIndex() ) continue; - + int ndxPatch = pPatch - g_Patches.Base(); PatchSampleData_AddSample( pPatch, ndxPatch ); @@ -1573,7 +1573,7 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace float stepV = 1.0f / ( float )height; float halfStepU = stepU * 0.5f; float halfStepV = stepV * 0.5f; - + // // build the winding points (used to generate world space winding and // calculate the area of the "sample") @@ -1612,10 +1612,10 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace pWinding->p[1] = pWorldPoints[((ndxV+1)*(width+1))+ndxU]; pWinding->p[2] = pWorldPoints[((ndxV+1)*(width+1))+(ndxU+1)]; pWinding->p[3] = pWorldPoints[(ndxV*(width+1))+(ndxU+1)]; - + // calculate the area float area = WindingArea( pWinding ); - + int ndxSample = ( ndxV * width ) + ndxU; pSamples[ndxSample].w = pWinding; pSamples[ndxSample].area = area; @@ -1641,7 +1641,7 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace pSamples[ndxSample].coord[0] = ( ndxU * stepU ) + halfStepU; pSamples[ndxSample].coord[1] = ( ndxV * stepV ) + halfStepV; pDispTree->DispUVToSurfPoint( pSamples[ndxSample].coord, pSamples[ndxSample].pos, 1.0f ); - pDispTree->DispUVToSurfNormal( pSamples[ndxSample].coord, pSamples[ndxSample].normal ); + pDispTree->DispUVToSurfNormal( pSamples[ndxSample].coord, pSamples[ndxSample].normal ); } } @@ -1693,11 +1693,11 @@ bool CVRadDispMgr::BuildDispLuxels( lightinfo_t *pLightInfo, facelight_t *pFaceL { for( int ndxU = 0; ndxU < width; ndxU++ ) { - int ndxLuxel = ( ndxV * width ) + ndxU; + int ndxLuxel = ( ndxV * width ) + ndxU; Vector2D uv( ndxU * stepU, ndxV * stepV ); pDispTree->DispUVToSurfPoint( uv, pFaceLight->luxel[ndxLuxel], 1.0f ); - pDispTree->DispUVToSurfNormal( uv, pFaceLight->luxelNormals[ndxLuxel] ); + pDispTree->DispUVToSurfNormal( uv, pFaceLight->luxelNormals[ndxLuxel] ); } } @@ -1748,7 +1748,7 @@ bool CVRadDispMgr::BuildDispSamplesAndLuxels_DoFast( lightinfo_t *pLightInfo, fa pFaceLight->sample[ndx].coord[1] = ( ndxV * stepV ) + halfStepV; pDispTree->DispUVToSurfPoint( pFaceLight->sample[ndx].coord, pFaceLight->sample[ndx].pos, 1.0f ); - pDispTree->DispUVToSurfNormal( pFaceLight->sample[ndx].coord, pFaceLight->sample[ndx].normal ); + pDispTree->DispUVToSurfNormal( pFaceLight->sample[ndx].coord, pFaceLight->sample[ndx].normal ); pFaceLight->luxel[ndx] = pFaceLight->sample[ndx].pos; pFaceLight->luxelNormals[ndx] = pFaceLight->sample[ndx].normal; diff --git a/utils/vrad/vradstaticprops.cpp b/utils/vrad/vradstaticprops.cpp index 010a53b8..041610b4 100644 --- a/utils/vrad/vradstaticprops.cpp +++ b/utils/vrad/vradstaticprops.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $Revision: $ // $NoKeywords: $ @@ -27,13 +27,11 @@ #include "pacifier.h" #include "materialsystem/imaterial.h" #include "materialsystem/hardwareverts.h" -#include "materialsystem/hardwaretexels.h" #include "byteswap.h" #include "mpivrad.h" #include "vtf/vtf.h" #include "tier1/utldict.h" #include "tier1/utlsymbol.h" -#include "bitmap/tgawriter.h" #include "messbuf.h" #include "vmpi.h" @@ -59,187 +57,26 @@ struct colorVertex_t bool m_bValid; }; -// a texel suitable for a model -struct colorTexel_t -{ - Vector m_Color; - Vector m_WorldPosition; - Vector m_WorldNormal; - float m_fDistanceToTri; // If we are outside of the triangle, how far away is it? - bool m_bValid; - bool m_bPossiblyInteresting; - -}; - class CComputeStaticPropLightingResults { public: ~CComputeStaticPropLightingResults() { m_ColorVertsArrays.PurgeAndDeleteElements(); - m_ColorTexelsArrays.PurgeAndDeleteElements(); - } - - CUtlVector< CUtlVector* > m_ColorVertsArrays; - CUtlVector< CUtlVector* > m_ColorTexelsArrays; -}; - -//----------------------------------------------------------------------------- -struct Rasterizer -{ - struct Location - { - Vector barycentric; - Vector2D uv; - bool insideTriangle; - }; - - Rasterizer(Vector2D t0, Vector2D t1, Vector2D t2, size_t resX, size_t resY) - : mT0(t0) - , mT1(t1) - , mT2(t2) - , mResX(resX) - , mResY(resY) - , mUvStepX(1.0f / resX) - , mUvStepY(1.0f / resY) - { - Build(); } - CUtlVector< Location >::iterator begin() { return mRasterizedLocations.begin(); } - CUtlVector< Location >::iterator end() { return mRasterizedLocations.end(); } - - void Build(); - - inline size_t GetRow(float y) const { return size_t(y * mResY); } - inline size_t GetCol(float x) const { return size_t(x * mResX); } - - inline size_t GetLinearPos( const CUtlVector< Location >::iterator& it ) const - { - // Given an iterator, return what the linear position in the buffer would be for the data. - return (size_t)(GetRow(it->uv.y) * mResX) - + (size_t)(GetCol(it->uv.x)); - } - -private: - const Vector2D mT0, mT1, mT2; - const size_t mResX, mResY; - const float mUvStepX, mUvStepY; - - // Right now, we just fill this out and directly iterate over it. - // It could be large. This is a memory/speed tradeoff. We could instead generate them - // on demand. - CUtlVector< Location > mRasterizedLocations; + CUtlVector< CUtlVector* > m_ColorVertsArrays; }; -//----------------------------------------------------------------------------- -inline Vector ComputeBarycentric( Vector2D _edgeC, Vector2D _edgeA, Vector2D _edgeB, float _dAA, float _dAB, float _dBB, float _invDenom ) -{ - float dCA = _edgeC.Dot(_edgeA); - float dCB = _edgeC.Dot(_edgeB); - - Vector retVal; - retVal.y = (_dBB * dCA - _dAB * dCB) * _invDenom; - retVal.z = (_dAA * dCB - _dAB * dCA) * _invDenom; - retVal.x = 1.0f - retVal.y - retVal.z; - - return retVal; -} - -//----------------------------------------------------------------------------- -void Rasterizer::Build() -{ - // For now, use the barycentric method. It's easy, I'm lazy. - // We can optimize later if it's a performance issue. - const float baseX = mUvStepX / 2.0f; - const float baseY = mUvStepY / 2.0f; - - - float fMinX = min(min(mT0.x, mT1.x), mT2.x); - float fMinY = min(min(mT0.y, mT1.y), mT2.y); - float fMaxX = max(max(mT0.x, mT1.x), mT2.x); - float fMaxY = max(max(mT0.y, mT1.y), mT2.y); - - // Degenerate. Consider warning about these, but otherwise no problem. - if (fMinX == fMaxX || fMinY == fMaxY) - return; - - // Clamp to 0..1 - fMinX = max(0, fMinX); - fMinY = max(0, fMinY); - fMaxX = min(1.0f, fMaxX); - fMaxY = min(1.0f, fMaxY); - - // We puff the interesting area up by 1 so we can hit an inflated region for the necessary bilerp data. - // If we wanted to support better texturing (almost definitely unnecessary), we'd change this to a larger size. - const int kFilterSampleRadius = 1; - - int iMinX = GetCol(fMinX) - kFilterSampleRadius; - int iMinY = GetRow(fMinY) - kFilterSampleRadius; - int iMaxX = GetCol(fMaxX) + 1 + kFilterSampleRadius; - int iMaxY = GetRow(fMaxY) + 1 + kFilterSampleRadius; - - // Clamp to valid texture (integer) locations - iMinX = max(0, iMinX); - iMinY = max(0, iMinY); - iMaxX = min(iMaxX, mResX - 1); - iMaxY = min(iMaxY, mResY - 1); - - // Set the size to be as expected. - // TODO: Pass this in from outside to minimize allocations - int count = (iMaxY - iMinY + 1) - * (iMaxX - iMinX + 1); - mRasterizedLocations.EnsureCount(count); - memset( mRasterizedLocations.Base(), 0, mRasterizedLocations.Count() * sizeof( Location ) ); - - // Computing Barycentrics adapted from here http://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates - Vector2D edgeA = mT1 - mT0; - Vector2D edgeB = mT2 - mT0; - - float dAA = edgeA.Dot(edgeA); - float dAB = edgeA.Dot(edgeB); - float dBB = edgeB.Dot(edgeB); - float invDenom = 1.0f / (dAA * dBB - dAB * dAB); - - int linearPos = 0; - for (int j = iMinY; j <= iMaxY; ++j) { - for (int i = iMinX; i <= iMaxX; ++i) { - Vector2D testPt( i * mUvStepX + baseX, j * mUvStepY + baseY ); - Vector barycentric = ComputeBarycentric( testPt - mT0, edgeA, edgeB, dAA, dAB, dBB, invDenom ); - - // Test whether the point is inside the triangle. - // MCJOHNTODO: Edge rules and whatnot--right now we re-rasterize points on the edge. - Location& newLoc = mRasterizedLocations[linearPos++]; - newLoc.barycentric = barycentric; - newLoc.uv = testPt; - - newLoc.insideTriangle = (barycentric.x >= 0.0f && barycentric.x <= 1.0f && barycentric.y >= 0.0f && barycentric.y <= 1.0f && barycentric.z >= 0.0f && barycentric.z <= 1.0f); - } - } -} - - //----------------------------------------------------------------------------- // Globals //----------------------------------------------------------------------------- CUtlSymbolTable g_ForcedTextureShadowsModels; -// DON'T USE THIS FROM WITHIN A THREAD. THERE IS A THREAD CONTEXT CREATED +// DON'T USE THIS FROM WITHIN A THREAD. THERE IS A THREAD CONTEXT CREATED // INSIDE PropTested_t. USE THAT INSTEAD. IPhysicsCollision *s_pPhysCollision = NULL; -static void ConvertTexelDataToTexture(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _srcTexels, CUtlMemory* _outTexture); - -// Such a monstrosity. :( -static void GenerateLightmapSamplesForMesh( const matrix3x4_t& _matPos, const matrix3x4_t& _matNormal, int _iThread, int _skipProp, int _nFlags, int _lightmapResX, int _lightmapResY, - studiohdr_t* _pStudioHdr, mstudiomodel_t* _pStudioModel, OptimizedModel::ModelHeader_t* _pVtxModel, int _meshID, - CComputeStaticPropLightingResults *_pResults ); - -// Debug function, converts lightmaps to linear space then dumps them out. -// TODO: Write out the file in a .dds instead of a .tga, in whatever format we're supposed to use. -static void DumpLightmapLinear( const char* _dstFilename, const CUtlVector& _srcTexels, int _width, int _height ); - - //----------------------------------------------------------------------------- // Vrad's static prop manager //----------------------------------------------------------------------------- @@ -264,7 +101,7 @@ class CVradStaticPropMgr : public IVradStaticPropMgr static void VMPI_ReceiveStaticPropResults_Static( uint64 iStaticProp, MessageBuffer *pBuf, int iWorker ); void VMPI_ProcessStaticProp( int iThread, int iStaticProp, MessageBuffer *pBuf ); void VMPI_ReceiveStaticPropResults( int iStaticProp, MessageBuffer *pBuf, int iWorker ); - + // local thread version static void ThreadComputeStaticPropLighting( int iThread, void *pUserData ); void ComputeLightingForProp( int iThread, int iStaticProp ); @@ -293,8 +130,7 @@ class CVradStaticPropMgr : public IVradStaticPropMgr struct MeshData_t { - CUtlVector m_VertexColors; - CUtlMemory m_TexelsEncoded; + CUtlVector m_Verts; int m_nLod; }; @@ -311,15 +147,6 @@ class CVradStaticPropMgr : public IVradStaticPropMgr CUtlVector m_MeshData; int m_Flags; bool m_bLightingOriginValid; - - // Note that all lightmaps for a given prop share the same resolution (and format)--and there can be multiple lightmaps - // per prop (if there are multiple pieces--the watercooler is an example). - // This is effectively because there's not a good way in hammer for a prop to say "this should be the resolution - // of each of my sub-pieces." - ImageFormat m_LightmapImageFormat; - unsigned int m_LightmapImageWidth; - unsigned int m_LightmapImageHeight; - }; // Enumeration context @@ -336,7 +163,7 @@ class CVradStaticPropMgr : public IVradStaticPropMgr bool m_bIgnoreStaticPropTrace; void ComputeLighting( CStaticProp &prop, int iThread, int prop_index, CComputeStaticPropLightingResults *pResults ); - void ApplyLightingToStaticProp( int iStaticProp, CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ); + void ApplyLightingToStaticProp( CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ); void SerializeLighting(); void AddPolysForRayTrace(); @@ -461,7 +288,7 @@ CPhysCollide* ComputeConvexHull( studiohdr_t* pStudioHdr ) bool LoadStudioModel( char const* pModelName, CUtlBuffer& buf ) { - // No luck, gotta build it + // No luck, gotta build it // Construct the file name... if (!LoadFile( pModelName, buf )) { @@ -506,7 +333,7 @@ bool LoadStudioCollisionModel( char const* pModelName, CUtlBuffer& buf ) char tmp[1024]; Q_strncpy( tmp, pModelName, sizeof( tmp ) ); Q_SetExtension( tmp, ".phy", sizeof( tmp ) ); - // No luck, gotta build it + // No luck, gotta build it if (!LoadFile( tmp, buf )) { // this is not an error, the model simply has no PHY file @@ -564,8 +391,8 @@ inline static Vector* PositionFromIndex( const mstudio_meshvertexdata_t *vertDat //----------------------------------------------------------------------------- // Purpose: Writes a glview text file containing the collision surface in question -// Input : *pCollide - -// *pFilename - +// Input : *pCollide - +// *pFilename - //----------------------------------------------------------------------------- void DumpCollideToGlView( vcollide_t *pCollide, const char *pFilename ) { @@ -593,13 +420,13 @@ void DumpCollideToGlView( vcollide_t *pCollide, const char *pFilename ) for ( int i = 0; i < triCount; i++ ) { fprintf( fp, "3\n" ); - fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", + fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", outVerts[vert].x, outVerts[vert].y, outVerts[vert].z, fr, fg, fb ); vert++; - fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", + fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", outVerts[vert].x, outVerts[vert].y, outVerts[vert].z, fr, fg, fb ); vert++; - fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", + fprintf( fp, "%6.3f %6.3f %6.3f %.2f %.3f %.3f\n", outVerts[vert].x, outVerts[vert].y, outVerts[vert].z, fr, fg, fb ); vert++; } @@ -669,7 +496,7 @@ class CShadowTextureList *pClampV = (pTex->Flags() & TEXTUREFLAGS_CLAMPT) ? true : false; unsigned char *pDstImage = new unsigned char[ImageLoader::GetMemRequired( iWidth, iHeight, 1, dstFormat, false )]; - if( !ImageLoader::ConvertImageFormat( pSrcImage, srcFormat, + if( !ImageLoader::ConvertImageFormat( pSrcImage, srcFormat, pDstImage, dstFormat, iWidth, iHeight, 0, 0 ) ) { delete[] pDstImage; @@ -765,7 +592,7 @@ class CShadowTextureList pTextureList[i] = textureIndex; } } - + int AddMaterialEntry( int shadowTextureIndex, const Vector2D &t0, const Vector2D &t1, const Vector2D &t2 ) { int index = m_MaterialEntries.AddToTail(); @@ -779,15 +606,15 @@ class CShadowTextureList // HACKHACK: Compute the average coverage for this triangle by sampling the AABB of its texture space float ComputeCoverageForTriangle( int shadowTextureIndex, const Vector2D &t0, const Vector2D &t1, const Vector2D &t2 ) { - float umin = min(t0.x, t1.x); - umin = min(umin, t2.x); - float umax = max(t0.x, t1.x); - umax = max(umax, t2.x); + float umin = MIN(t0.x, t1.x); + umin = MIN(umin, t2.x); + float umax = MAX(t0.x, t1.x); + umax = MAX(umax, t2.x); - float vmin = min(t0.y, t1.y); - vmin = min(vmin, t2.y); - float vmax = max(t0.y, t1.y); - vmax = max(vmax, t2.y); + float vmin = MIN(t0.y, t1.y); + vmin = MIN(vmin, t2.y); + float vmax = MAX(t0.y, t1.y); + vmax = MAX(vmax, t2.y); // UNDONE: Do something about tiling umin = clamp(umin, 0, 1); @@ -820,7 +647,7 @@ class CShadowTextureList } return 1.0f; } - + int SampleMaterial( int materialIndex, const Vector &coords, bool bBackface ) { const materialentry_t &mat = m_MaterialEntries[materialIndex]; @@ -830,7 +657,7 @@ class CShadowTextureList Vector2D uv = coords.x * mat.uv[0] + coords.y * mat.uv[1] + coords.z * mat.uv[2]; int u = RoundFloatToInt( uv[0] * tex.width ); int v = RoundFloatToInt( uv[1] * tex.height ); - + // asume power of 2, clamp or wrap // UNDONE: Support clamp? This code should work #if 0 @@ -845,7 +672,7 @@ class CShadowTextureList return tex.pAlphaTexels[v * tex.width + u]; } - struct alphatexture_t + struct alphatexture_t { short width; short height; @@ -1018,7 +845,7 @@ void CVradStaticPropMgr::UnserializeModelDict( CUtlBuffer& buf ) { StaticPropDictLump_t lump; buf.Get( &lump, sizeof(StaticPropDictLump_t) ); - + CreateCollisionModel( lump.m_Name ); } } @@ -1027,13 +854,12 @@ void CVradStaticPropMgr::UnserializeModels( CUtlBuffer& buf ) { int count = buf.GetInt(); - m_StaticProps.AddMultipleToTail(count); - for ( int i = 0; i < count; ++i ) + for ( int i = 0; i < count; ++i ) { StaticPropLump_t lump; buf.Get( &lump, sizeof(StaticPropLump_t) ); - + VectorCopy( lump.m_Origin, m_StaticProps[i].m_Origin ); VectorCopy( lump.m_Angles, m_StaticProps[i].m_Angles ); VectorCopy( lump.m_LightingOrigin, m_StaticProps[i].m_LightingOrigin ); @@ -1041,12 +867,6 @@ void CVradStaticPropMgr::UnserializeModels( CUtlBuffer& buf ) m_StaticProps[i].m_ModelIdx = lump.m_PropType; m_StaticProps[i].m_Handle = TREEDATA_INVALID_HANDLE; m_StaticProps[i].m_Flags = lump.m_Flags; - - // Changed this from using DXT1 to RGB888 because the compression artifacts were pretty nasty. - // TODO: Consider changing back or basing this on user selection in hammer. - m_StaticProps[i].m_LightmapImageFormat = IMAGE_FORMAT_RGB888; - m_StaticProps[i].m_LightmapImageWidth = lump.m_nLightmapResolutionX; - m_StaticProps[i].m_LightmapImageHeight = lump.m_nLightmapResolutionY; } } @@ -1089,7 +909,7 @@ void CVradStaticPropMgr::Init() CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( !physicsFactory ) Error( "Unable to load vphysics DLL." ); - + s_pPhysCollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); if( !s_pPhysCollision ) { @@ -1164,9 +984,6 @@ void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &out continue; } - if (dl->m_bStatic) - continue; - // is this lights cluster visible? if ( !PVSCheck( dl->pvs, cluster ) ) continue; @@ -1189,7 +1006,7 @@ void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &out fudge *= 4.0; adjusted_pos += fudge; } - else + else { // push out along normal adjusted_pos += 4.0 * normal; @@ -1203,7 +1020,7 @@ void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &out GatherSampleLightSSE( sampleOutput, dl, -1, adjusted_pos4, &normal4, 1, iThread, nLFlags | GATHERLFLAGS_FORCE_FAST, static_prop_id_to_skip, flEpsilon ); - + VectorMA( outColor, sampleOutput.m_flFalloff.m128_f32[0] * sampleOutput.m_flDot[0].m128_f32[0], dl->light.intensity, outColor ); } } @@ -1211,9 +1028,9 @@ void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &out //----------------------------------------------------------------------------- // Takes the results from a ComputeLighting call and applies it to the static prop in question. //----------------------------------------------------------------------------- -void CVradStaticPropMgr::ApplyLightingToStaticProp( int iStaticProp, CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ) +void CVradStaticPropMgr::ApplyLightingToStaticProp( CStaticProp &prop, const CComputeStaticPropLightingResults *pResults ) { - if ( pResults->m_ColorVertsArrays.Count() == 0 && pResults->m_ColorTexelsArrays.Count() == 0 ) + if ( pResults->m_ColorVertsArrays.Count() == 0 ) return; StaticPropDict_t &dict = m_StaticPropDict[prop.m_ModelIdx]; @@ -1222,8 +1039,6 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( int iStaticProp, CStaticProp Assert( pStudioHdr && pVtxHdr ); int iCurColorVertsArray = 0; - int iCurColorTexelsArray = 0; - for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); @@ -1233,10 +1048,9 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( int iStaticProp, CStaticProp { OptimizedModel::ModelHeader_t* pVtxModel = pVtxBodyPart->pModel( modelID ); mstudiomodel_t *pStudioModel = pBodyPart->pModel( modelID ); - - const CUtlVector *colorVerts = pResults->m_ColorVertsArrays.Count() ? pResults->m_ColorVertsArrays[iCurColorVertsArray++] : nullptr; - const CUtlVector *colorTexels = pResults->m_ColorTexelsArrays.Count() ? pResults->m_ColorTexelsArrays[iCurColorTexelsArray++] : nullptr; - + + const CUtlVector &colorVerts = *pResults->m_ColorVertsArrays[iCurColorVertsArray++]; + for ( int nLod = 0; nLod < pVtxHdr->numLODs; nLod++ ) { OptimizedModel::ModelLODHeader_t *pVtxLOD = pVtxModel->pLOD( nLod ); @@ -1250,52 +1064,15 @@ void CVradStaticPropMgr::ApplyLightingToStaticProp( int iStaticProp, CStaticProp { OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup( nGroup ); int nMeshIdx = prop.m_MeshData.AddToTail(); + prop.m_MeshData[nMeshIdx].m_Verts.AddMultipleToTail( pStripGroup->numVerts ); + prop.m_MeshData[nMeshIdx].m_nLod = nLod; - if (colorVerts) - { - prop.m_MeshData[nMeshIdx].m_VertexColors.AddMultipleToTail( pStripGroup->numVerts ); - prop.m_MeshData[nMeshIdx].m_nLod = nLod; - - for ( int nVertex = 0; nVertex < pStripGroup->numVerts; ++nVertex ) - { - int nIndex = pMesh->vertexoffset + pStripGroup->pVertex( nVertex )->origMeshVertID; - - Assert( nIndex < pStudioModel->numvertices ); - prop.m_MeshData[nMeshIdx].m_VertexColors[nVertex] = (*colorVerts)[nIndex].m_Color; - } - } - - if (colorTexels) + for ( int nVertex = 0; nVertex < pStripGroup->numVerts; ++nVertex ) { - // TODO: Consider doing this work in the worker threads, because then we distribute it. - ConvertTexelDataToTexture(prop.m_LightmapImageWidth, prop.m_LightmapImageHeight, prop.m_LightmapImageFormat, (*colorTexels), &prop.m_MeshData[nMeshIdx].m_TexelsEncoded); + int nIndex = pMesh->vertexoffset + pStripGroup->pVertex( nVertex )->origMeshVertID; - if (g_bDumpPropLightmaps) - { - char buffer[_MAX_PATH]; - V_snprintf( - buffer, - _MAX_PATH - 1, - "staticprop_lightmap_%d_%.0f_%.0f_%.0f_%s_%d_%d_%d_%d_%d.tga", - iStaticProp, - prop.m_Origin.x, - prop.m_Origin.y, - prop.m_Origin.z, - dict.m_pStudioHdr->pszName(), - bodyID, - modelID, - nLod, - nMesh, - nGroup - ); - - for ( int i = 0; buffer[i]; ++i ) - { - if (buffer[i] == '/' || buffer[i] == '\\') - buffer[i] = '-'; - } - DumpLightmapLinear( buffer, (*colorTexels), prop.m_LightmapImageWidth, prop.m_LightmapImageHeight ); - } + Assert( nIndex < pStudioModel->numvertices ); + prop.m_MeshData[nMeshIdx].m_Verts[nVertex] = colorVerts[nIndex].m_Color; } } } @@ -1323,42 +1100,24 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr return; } - const bool withVertexLighting = (prop.m_Flags & STATIC_PROP_NO_PER_VERTEX_LIGHTING) == 0; - const bool withTexelLighting = (prop.m_Flags & STATIC_PROP_NO_PER_TEXEL_LIGHTING) == 0; - - if (!withVertexLighting && !withTexelLighting) + if (prop.m_Flags & STATIC_PROP_NO_PER_VERTEX_LIGHTING ) return; - const int skip_prop = (g_bDisablePropSelfShadowing || (prop.m_Flags & STATIC_PROP_NO_SELF_SHADOWING)) ? prop_index : -1; - const int nFlags = ( prop.m_Flags & STATIC_PROP_IGNORE_NORMALS ) ? GATHERLFLAGS_IGNORE_NORMALS : 0; - VMPI_SetCurrentStage( "ComputeLighting" ); - matrix3x4_t matPos, matNormal; - AngleMatrix(prop.m_Angles, prop.m_Origin, matPos); - AngleMatrix(prop.m_Angles, matNormal); - for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { - OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( bodyID ); for ( int modelID = 0; modelID < pBodyPart->nummodels; ++modelID ) { - OptimizedModel::ModelHeader_t* pVtxModel = pVtxBodyPart->pModel(modelID); mstudiomodel_t *pStudioModel = pBodyPart->pModel( modelID ); - if (withTexelLighting) - { - CUtlVector *pColorTexelArray = new CUtlVector; - pResults->m_ColorTexelsArrays.AddToTail(pColorTexelArray); - } - // light all unique vertexes CUtlVector *pColorVertsArray = new CUtlVector; pResults->m_ColorVertsArrays.AddToTail( pColorVertsArray ); - - CUtlVector &colorVerts = *pColorVertsArray; + + CUtlVector &colorVerts = *pColorVertsArray; colorVerts.EnsureCount( pStudioModel->numvertices ); memset( colorVerts.Base(), 0, colorVerts.Count() * sizeof(colorVertex_t) ); @@ -1367,23 +1126,17 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr { mstudiomesh_t *pStudioMesh = pStudioModel->pMesh( meshID ); const mstudio_meshvertexdata_t *vertData = pStudioMesh->GetVertexData((void *)pStudioHdr); - - Assert(vertData); // This can only return NULL on X360 for now - - // TODO: Move this into its own function. In fact, refactor this whole function. - if (withTexelLighting) - { - GenerateLightmapSamplesForMesh( matPos, matNormal, iThread, skip_prop, nFlags, prop.m_LightmapImageWidth, prop.m_LightmapImageHeight, pStudioHdr, pStudioModel, pVtxModel, meshID, pResults ); - } - - // If we do lightmapping, we also do vertex lighting as a potential fallback. This may change. + Assert( vertData ); // This can only return NULL on X360 for now for ( int vertexID = 0; vertexID < pStudioMesh->numvertices; ++vertexID ) { Vector sampleNormal; Vector samplePosition; // transform position and normal into world coordinate system - VectorTransform(*vertData->Position(vertexID), matPos, samplePosition); - VectorTransform(*vertData->Normal(vertexID), matNormal, sampleNormal); + matrix3x4_t matrix; + AngleMatrix( prop.m_Angles, prop.m_Origin, matrix ); + VectorTransform( *vertData->Position( vertexID ), matrix, samplePosition ); + AngleMatrix( prop.m_Angles, matrix ); + VectorTransform( *vertData->Normal( vertexID ), matrix, sampleNormal ); if ( PositionInSolid( samplePosition ) ) { @@ -1392,18 +1145,23 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr badVertex.m_ColorVertex = numVertexes; badVertex.m_Position = samplePosition; badVertex.m_Normal = sampleNormal; - badVerts.AddToTail( badVertex ); + badVerts.AddToTail( badVertex ); } else { Vector direct_pos=samplePosition; - - + int skip_prop = -1; + if ( g_bDisablePropSelfShadowing || ( prop.m_Flags & STATIC_PROP_NO_SELF_SHADOWING ) ) + { + skip_prop = prop_index; + } + + int nFlags = ( prop.m_Flags & STATIC_PROP_IGNORE_NORMALS ) ? GATHERLFLAGS_IGNORE_NORMALS : 0; Vector directColor(0,0,0); ComputeDirectLightingAtPoint( direct_pos, - sampleNormal, directColor, iThread, - skip_prop, nFlags ); + sampleNormal, directColor, iThread, + skip_prop, nFlags ); Vector indirectColor(0,0,0); if (g_bShowStaticPropNormals) @@ -1415,28 +1173,28 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr else { if (numbounce >= 1) - ComputeIndirectLightingAtPoint( - samplePosition, sampleNormal, + ComputeIndirectLightingAtPoint( + samplePosition, sampleNormal, indirectColor, iThread, true, ( prop.m_Flags & STATIC_PROP_IGNORE_NORMALS) != 0 ); } - + colorVerts[numVertexes].m_bValid = true; colorVerts[numVertexes].m_Position = samplePosition; VectorAdd( directColor, indirectColor, colorVerts[numVertexes].m_Color ); } - + numVertexes++; } } - + // color in the bad vertexes // when entire model has no lighting origin and no valid neighbors // must punt, leave black coloring if ( badVerts.Count() && ( prop.m_bLightingOriginValid || badVerts.Count() != numVertexes ) ) { for ( int nBadVertex = 0; nBadVertex < badVerts.Count(); nBadVertex++ ) - { + { Vector bestPosition; if ( prop.m_bLightingOriginValid ) { @@ -1496,7 +1254,7 @@ void CVradStaticPropMgr::ComputeLighting( CStaticProp &prop, int iThread, int pr VectorAdd( directColor, indirectColor, colorVerts[badVerts[nBadVertex].m_ColorVertex].m_Color ); } } - + // discard bad verts badVerts.Purge(); } @@ -1526,7 +1284,7 @@ void CVradStaticPropMgr::SerializeLighting() for (int i = 0; i < count; ++i) { // no need to write this file if we didn't compute the data - // props marked this way will not load the info anyway + // props marked this way will not load the info anyway if ( m_StaticProps[i].m_Flags & STATIC_PROP_NO_PER_VERTEX_LIGHTING ) continue; @@ -1542,11 +1300,11 @@ void CVradStaticPropMgr::SerializeLighting() int totalVertexes = 0; for ( int j=0; jm_nVersion = VHV_VERSION; pVhvHdr->m_nChecksum = m_StaticPropDict[m_StaticProps[i].m_ModelIdx].m_pStudioHdr->checksum; @@ -1571,16 +1329,16 @@ void CVradStaticPropMgr::SerializeLighting() // construct mesh dictionary HardwareVerts::MeshHeader_t *pMesh = pVhvHdr->pMesh( n ); pMesh->m_nLod = m_StaticProps[i].m_MeshData[n].m_nLod; - pMesh->m_nVertexes = m_StaticProps[i].m_MeshData[n].m_VertexColors.Count(); - pMesh->m_nOffset = (unsigned int)pVertexData - (unsigned int)pVhvHdr; + pMesh->m_nVertexes = m_StaticProps[i].m_MeshData[n].m_Verts.Count(); + pMesh->m_nOffset = (unsigned int)pVertexData - (unsigned int)pVhvHdr; // construct vertexes for (int k=0; km_nVertexes; k++) { - Vector &vertexColor = m_StaticProps[i].m_MeshData[n].m_VertexColors[k]; + Vector &vector = m_StaticProps[i].m_MeshData[n].m_Verts[k]; ColorRGBExp32 rgbColor; - VectorToColorRGBExp32( vertexColor, rgbColor ); + VectorToColorRGBExp32( vector, rgbColor ); unsigned char dstColor[4]; ConvertRGBExp32ToRGBA8888( &rgbColor, dstColor ); @@ -1599,63 +1357,6 @@ void CVradStaticPropMgr::SerializeLighting() AddBufferToPak( GetPakFile(), filename, (void*)pVhvHdr, pVertexData - (unsigned char*)pVhvHdr, false ); } - - for (int i = 0; i < count; ++i) - { - const int kAlignment = 512; - // no need to write this file if we didn't compute the data - // props marked this way will not load the info anyway - if (m_StaticProps[i].m_Flags & STATIC_PROP_NO_PER_TEXEL_LIGHTING) - continue; - - sprintf(filename, "texelslighting_%d.ppl", i); - - ImageFormat fmt = m_StaticProps[i].m_LightmapImageFormat; - - unsigned int totalTexelSizeBytes = 0; - for (int j = 0; j < m_StaticProps[i].m_MeshData.Count(); j++) - { - totalTexelSizeBytes += m_StaticProps[i].m_MeshData[j].m_TexelsEncoded.Count(); - } - - // allocate a buffer with enough padding for alignment - size = sizeof(HardwareTexels::FileHeader_t) - + m_StaticProps[i].m_MeshData.Count() * sizeof(HardwareTexels::MeshHeader_t) - + totalTexelSizeBytes - + 2 * kAlignment; - - utlBuf.EnsureCapacity(size); - Q_memset(utlBuf.Base(), 0, size); - - HardwareTexels::FileHeader_t *pVhtHdr = (HardwareTexels::FileHeader_t *)utlBuf.Base(); - - // align start of texel data - unsigned char *pTexelData = (unsigned char *)(sizeof(HardwareTexels::FileHeader_t) + m_StaticProps[i].m_MeshData.Count() * sizeof(HardwareTexels::MeshHeader_t)); - pTexelData = (unsigned char*)pVhtHdr + ALIGN_TO_POW2((unsigned int)pTexelData, kAlignment); - - pVhtHdr->m_nVersion = VHT_VERSION; - pVhtHdr->m_nChecksum = m_StaticPropDict[m_StaticProps[i].m_ModelIdx].m_pStudioHdr->checksum; - pVhtHdr->m_nTexelFormat = fmt; - pVhtHdr->m_nMeshes = m_StaticProps[i].m_MeshData.Count(); - - for (int n = 0; n < pVhtHdr->m_nMeshes; n++) - { - HardwareTexels::MeshHeader_t *pMesh = pVhtHdr->pMesh(n); - pMesh->m_nLod = m_StaticProps[i].m_MeshData[n].m_nLod; - pMesh->m_nOffset = (unsigned int)pTexelData - (unsigned int)pVhtHdr; - pMesh->m_nBytes = m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count(); - pMesh->m_nWidth = m_StaticProps[i].m_LightmapImageWidth; - pMesh->m_nHeight = m_StaticProps[i].m_LightmapImageHeight; - - Q_memcpy(pTexelData, m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Base(), m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count()); - pTexelData += m_StaticProps[i].m_MeshData[n].m_TexelsEncoded.Count(); - } - - pTexelData = (unsigned char *)((unsigned int)pTexelData - (unsigned int)pVhtHdr); - pTexelData = (unsigned char*)pVhtHdr + ALIGN_TO_POW2((unsigned int)pTexelData, kAlignment); - - AddBufferToPak(GetPakFile(), filename, (void*)pVhtHdr, pTexelData - (unsigned char*)pVhtHdr, false); - } } void CVradStaticPropMgr::VMPI_ProcessStaticProp_Static( int iThread, uint64 iStaticProp, MessageBuffer *pBuf ) @@ -1667,7 +1368,7 @@ void CVradStaticPropMgr::VMPI_ReceiveStaticPropResults_Static( uint64 iStaticPro { g_StaticPropMgr.VMPI_ReceiveStaticPropResults( iStaticProp, pBuf, iWorker ); } - + //----------------------------------------------------------------------------- // Called on workers to do the computation for a static prop and send // it to the master. @@ -1679,11 +1380,11 @@ void CVradStaticPropMgr::VMPI_ProcessStaticProp( int iThread, int iStaticProp, M ComputeLighting( m_StaticProps[iStaticProp], iThread, iStaticProp, &results ); VMPI_SetCurrentStage( "EncodeLightingResults" ); - + // Encode the results. int nLists = results.m_ColorVertsArrays.Count(); pBuf->write( &nLists, sizeof( nLists ) ); - + for ( int i=0; i < nLists; i++ ) { CUtlVector &curList = *results.m_ColorVertsArrays[i]; @@ -1691,17 +1392,6 @@ void CVradStaticPropMgr::VMPI_ProcessStaticProp( int iThread, int iStaticProp, M pBuf->write( &count, sizeof( count ) ); pBuf->write( curList.Base(), curList.Count() * sizeof( colorVertex_t ) ); } - - nLists = results.m_ColorTexelsArrays.Count(); - pBuf->write(&nLists, sizeof(nLists)); - - for (int i = 0; i < nLists; i++) - { - CUtlVector &curList = *results.m_ColorTexelsArrays[i]; - int count = curList.Count(); - pBuf->write(&count, sizeof(count)); - pBuf->write(curList.Base(), curList.Count() * sizeof(colorTexel_t)); - } } //----------------------------------------------------------------------------- @@ -1711,36 +1401,23 @@ void CVradStaticPropMgr::VMPI_ReceiveStaticPropResults( int iStaticProp, Message { // Read in the results. CComputeStaticPropLightingResults results; - + int nLists; pBuf->read( &nLists, sizeof( nLists ) ); - + for ( int i=0; i < nLists; i++ ) { CUtlVector *pList = new CUtlVector; results.m_ColorVertsArrays.AddToTail( pList ); - + int count; pBuf->read( &count, sizeof( count ) ); pList->SetSize( count ); pBuf->read( pList->Base(), count * sizeof( colorVertex_t ) ); } - pBuf->read(&nLists, sizeof(nLists)); - - for (int i = 0; i < nLists; i++) - { - CUtlVector *pList = new CUtlVector; - results.m_ColorTexelsArrays.AddToTail(pList); - - int count; - pBuf->read(&count, sizeof(count)); - pList->SetSize(count); - pBuf->read(pList->Base(), count * sizeof(colorTexel_t)); - } - // Apply the results. - ApplyLightingToStaticProp( iStaticProp, m_StaticProps[iStaticProp], &results ); + ApplyLightingToStaticProp( m_StaticProps[iStaticProp], &results ); } @@ -1749,7 +1426,7 @@ void CVradStaticPropMgr::ComputeLightingForProp( int iThread, int iStaticProp ) // Compute the lighting. CComputeStaticPropLightingResults results; ComputeLighting( m_StaticProps[iStaticProp], iThread, iStaticProp, &results ); - ApplyLightingToStaticProp( iStaticProp, m_StaticProps[iStaticProp], &results ); + ApplyLightingToStaticProp( m_StaticProps[iStaticProp], &results ); } void CVradStaticPropMgr::ThreadComputeStaticPropLighting( int iThread, void *pUserData ) @@ -1787,11 +1464,11 @@ void CVradStaticPropMgr::ComputeLighting( int iThread ) { // Distribute the work among the workers. VMPI_SetCurrentStage( "CVradStaticPropMgr::ComputeLighting" ); - - DistributeWork( - count, + + DistributeWork( + count, VMPI_DISTRIBUTEWORK_PACKETID, - &CVradStaticPropMgr::VMPI_ProcessStaticProp_Static, + &CVradStaticPropMgr::VMPI_ProcessStaticProp_Static, &CVradStaticPropMgr::VMPI_ReceiveStaticPropResults_Static ); } else @@ -1859,7 +1536,7 @@ void CVradStaticPropMgr::AddPolysForRayTrace( void ) VectorAdd ( dict.m_Maxs, prop.m_Origin, prop.m_maxs ); g_RtEnv.AddAxisAlignedRectangularSolid ( TRACE_ID_STATICPROP | nProp, prop.m_mins, prop.m_maxs, fullCoverage ); } - + continue; } @@ -1876,7 +1553,7 @@ void CVradStaticPropMgr::AddPolysForRayTrace( void ) // meshes are deeply hierarchial, divided between three stores, follow the white rabbit // body parts -> models -> lod meshes -> strip groups -> strips - // the vertices and indices are pooled, the trick is knowing the offset to determine your indexed base + // the vertices and indices are pooled, the trick is knowing the offset to determine your indexed base for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); @@ -2020,10 +1697,10 @@ struct tl_tri_t Vector n1; Vector n2; - bool operator == (const tl_tri_t &t) const - { - return ( p0 == t.p0 && - p1 == t.p1 && + bool operator == (const tl_tri_t &t) const + { + return ( p0 == t.p0 && + p1 == t.p1 && p2 == t.p2 && n0 == t.n0 && n1 == t.n1 && @@ -2080,7 +1757,7 @@ void CVradStaticPropMgr::BuildTriList( CStaticProp &prop ) // meshes are deeply hierarchial, divided between three stores, follow the white rabbit // body parts -> models -> lod meshes -> strip groups -> strips - // the vertices and indices are pooled, the trick is knowing the offset to determine your indexed base + // the vertices and indices are pooled, the trick is knowing the offset to determine your indexed base for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID ) { OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID ); @@ -2180,7 +1857,7 @@ const vertexFileHeader_t * mstudiomodel_t::CacheVertexData( void *pModelData ) // mandatory callback to make requested data resident // load and persist the vertex file char fileName[MAX_PATH]; - strcpy( fileName, "models/" ); + strcpy( fileName, "models/" ); strcat( fileName, pActiveStudioHdr->pszName() ); Q_StripExtension( fileName, fileName, sizeof( fileName ) ); strcat( fileName, ".vvd" ); @@ -2236,462 +1913,3 @@ const vertexFileHeader_t * mstudiomodel_t::CacheVertexData( void *pModelData ) pActiveStudioHdr->pVertexBase = (void*)pVvdHdr; return pVvdHdr; } - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -struct ColorTexelValue -{ - Vector mLinearColor; // Linear color value for this texel - bool mValidData; // Whether there is valid data in this texel. - size_t mTriangleIndex; // Which triangle we used to generate the texel. -}; - -// ------------------------------------------------------------------------------------------------ -inline int ComputeLinearPos( int _x, int _y, int _resX, int _resY ) -{ - return Min( Max( 0, _y ), _resY - 1 ) * _resX - + Min( Max( 0, _x ), _resX - 1 ); -} - -// ------------------------------------------------------------------------------------------------ -inline float ComputeBarycentricDistanceToTri( Vector _barycentricCoord, Vector2D _v[3] ) -{ - Vector2D realPos = _barycentricCoord.x * _v[0] - + _barycentricCoord.y * _v[1] - + _barycentricCoord.z * _v[2]; - - int minIndex = 0; - float minVal = _barycentricCoord[0]; - for (int i = 1; i < 3; ++i) { - if (_barycentricCoord[i] < minVal) { - minVal = _barycentricCoord[i]; - minIndex = i; - } - } - - Vector2D& first = _v[ (minIndex + 1) % 3]; - Vector2D& second = _v[ (minIndex + 2) % 3]; - - return CalcDistanceToLineSegment2D( realPos, first, second ); -} - -// ------------------------------------------------------------------------------------------------ -static void GenerateLightmapSamplesForMesh( const matrix3x4_t& _matPos, const matrix3x4_t& _matNormal, int _iThread, int _skipProp, int _flags, int _lightmapResX, int _lightmapResY, studiohdr_t* _pStudioHdr, mstudiomodel_t* _pStudioModel, OptimizedModel::ModelHeader_t* _pVtxModel, int _meshID, CComputeStaticPropLightingResults *_outResults ) -{ - // Could iterate and gen this if needed. - int nLod = 0; - - OptimizedModel::ModelLODHeader_t *pVtxLOD = _pVtxModel->pLOD(nLod); - - CUtlVector &colorTexels = (*_outResults->m_ColorTexelsArrays.Tail()); - const int cTotalPixelCount = _lightmapResX * _lightmapResY; - colorTexels.EnsureCount(cTotalPixelCount); - memset(colorTexels.Base(), 0, colorTexels.Count() * sizeof(colorTexel_t)); - - for (int i = 0; i < colorTexels.Count(); ++i) { - colorTexels[i].m_fDistanceToTri = FLT_MAX; - } - - mstudiomesh_t* pMesh = _pStudioModel->pMesh(_meshID); - OptimizedModel::MeshHeader_t* pVtxMesh = pVtxLOD->pMesh(_meshID); - const mstudio_meshvertexdata_t *vertData = pMesh->GetVertexData((void *)_pStudioHdr); - Assert(vertData); // This can only return NULL on X360 for now - - for (int nGroup = 0; nGroup < pVtxMesh->numStripGroups; ++nGroup) - { - OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup(nGroup); - - int nStrip; - for (nStrip = 0; nStrip < pStripGroup->numStrips; nStrip++) - { - OptimizedModel::StripHeader_t *pStrip = pStripGroup->pStrip(nStrip); - - // If this hits, re-factor the code to iterate over triangles, and build the triangles - // from the underlying structures. - Assert((pStrip->flags & OptimizedModel::STRIP_IS_TRISTRIP) == 0); - - if (pStrip->flags & OptimizedModel::STRIP_IS_TRILIST) - { - for (int i = 0; i < pStrip->numIndices; i += 3) - { - int idx = pStrip->indexOffset + i; - - unsigned short i1 = *pStripGroup->pIndex(idx); - unsigned short i2 = *pStripGroup->pIndex(idx + 1); - unsigned short i3 = *pStripGroup->pIndex(idx + 2); - - int vertex1 = pStripGroup->pVertex(i1)->origMeshVertID; - int vertex2 = pStripGroup->pVertex(i2)->origMeshVertID; - int vertex3 = pStripGroup->pVertex(i3)->origMeshVertID; - - Vector modelPos[3] = { - *vertData->Position(vertex1), - *vertData->Position(vertex2), - *vertData->Position(vertex3) - }; - - Vector modelNormal[3] = { - *vertData->Normal(vertex1), - *vertData->Normal(vertex2), - *vertData->Normal(vertex3) - }; - - Vector worldPos[3]; - Vector worldNormal[3]; - - VectorTransform(modelPos[0], _matPos, worldPos[0]); - VectorTransform(modelPos[1], _matPos, worldPos[1]); - VectorTransform(modelPos[2], _matPos, worldPos[2]); - - VectorTransform(modelNormal[0], _matNormal, worldNormal[0]); - VectorTransform(modelNormal[1], _matNormal, worldNormal[1]); - VectorTransform(modelNormal[2], _matNormal, worldNormal[2]); - - Vector2D texcoord[3] = { - *vertData->Texcoord(vertex1), - *vertData->Texcoord(vertex2), - *vertData->Texcoord(vertex3) - }; - - Rasterizer rasterizer(texcoord[0], texcoord[1], texcoord[2], - _lightmapResX, _lightmapResY); - - for (auto it = rasterizer.begin(); it != rasterizer.end(); ++it) - { - size_t linearPos = rasterizer.GetLinearPos(it); - Assert(linearPos < cTotalPixelCount); - - if ( colorTexels[linearPos].m_bValid ) - { - continue; - } - - float ourDistancetoTri = ComputeBarycentricDistanceToTri( it->barycentric, texcoord ); - - bool doWrite = it->insideTriangle - || !colorTexels[linearPos].m_bPossiblyInteresting - || colorTexels[linearPos].m_fDistanceToTri > ourDistancetoTri; - - if (doWrite) - { - Vector itWorldPos = worldPos[0] * it->barycentric.x - + worldPos[1] * it->barycentric.y - + worldPos[2] * it->barycentric.z; - - Vector itWorldNormal = worldNormal[0] * it->barycentric.x - + worldNormal[1] * it->barycentric.y - + worldNormal[2] * it->barycentric.z; - itWorldNormal.NormalizeInPlace(); - - colorTexels[linearPos].m_WorldPosition = itWorldPos; - colorTexels[linearPos].m_WorldNormal = itWorldNormal; - colorTexels[linearPos].m_bValid = it->insideTriangle; - colorTexels[linearPos].m_bPossiblyInteresting = true; - colorTexels[linearPos].m_fDistanceToTri = ourDistancetoTri; - } - } - } - } - } - } - - // Process neighbors to the valid region. Walk through the existing array, look for samples that - // are not valid but are adjacent to valid samples. Works if we are only bilinearly sampling - // on the other side. - // First attempt: Just pretend the triangle was larger and cast a ray from this new world pos - // as above. - int linearPos = 0; - for ( int j = 0; j < _lightmapResY; ++j ) - { - for (int i = 0; i < _lightmapResX; ++i ) - { - bool shouldProcess = colorTexels[linearPos].m_bValid; - // Are any of the eight neighbors valid?? - if ( colorTexels[linearPos].m_bPossiblyInteresting ) - { - // Look at our neighborhood (3x3 centerd on us). - shouldProcess = shouldProcess - || colorTexels[ComputeLinearPos( i - 1, j - 1, _lightmapResX, _lightmapResY )].m_bValid // TL - || colorTexels[ComputeLinearPos( i , j - 1, _lightmapResX, _lightmapResY )].m_bValid // T - || colorTexels[ComputeLinearPos( i + 1, j - 1, _lightmapResX, _lightmapResY )].m_bValid // TR - - || colorTexels[ComputeLinearPos( i - 1, j , _lightmapResX, _lightmapResY )].m_bValid // L - || colorTexels[ComputeLinearPos( i + 1, j , _lightmapResX, _lightmapResY )].m_bValid // R - - || colorTexels[ComputeLinearPos( i - 1, j + 1, _lightmapResX, _lightmapResY )].m_bValid // BL - || colorTexels[ComputeLinearPos( i , j + 1, _lightmapResX, _lightmapResY )].m_bValid // B - || colorTexels[ComputeLinearPos( i + 1, j + 1, _lightmapResX, _lightmapResY )].m_bValid; // BR - } - - if (shouldProcess) - { - Vector directColor(0, 0, 0), - indirectColor(0, 0, 0); - - - ComputeDirectLightingAtPoint( colorTexels[linearPos].m_WorldPosition, colorTexels[linearPos].m_WorldNormal, directColor, _iThread, _skipProp, _flags); - - if (numbounce >= 1) { - ComputeIndirectLightingAtPoint( colorTexels[linearPos].m_WorldPosition, colorTexels[linearPos].m_WorldNormal, indirectColor, _iThread, true, (_flags & GATHERLFLAGS_IGNORE_NORMALS) != 0 ); - } - - VectorAdd(directColor, indirectColor, colorTexels[linearPos].m_Color); - } - - ++linearPos; - } - } -} - -// ------------------------------------------------------------------------------------------------ -static int GetTexelCount(unsigned int _resX, unsigned int _resY, bool _mipmaps) -{ - // Because they are unsigned, this is a != check--but if we were to change to ints, this would be - // the right assert (and it's no worse than != now). - Assert(_resX > 0 && _resY > 0); - - if (_mipmaps == false) - return _resX * _resY; - - int retVal = 0; - while (_resX > 1 || _resY > 1) - { - retVal += _resX * _resY; - _resX = max(1, _resX >> 1); - _resY = max(1, _resY >> 1); - } - - // Add in the 1x1 mipmap level, which wasn't hit above. This could be done in the initializer of - // retVal, but it's more obvious here. - retVal += 1; - - return retVal; -} - -// ------------------------------------------------------------------------------------------------ -static void FilterFineMipmap(unsigned int _resX, unsigned int _resY, const CUtlVector& _srcTexels, CUtlVector* _outLinear) -{ - Assert(_outLinear); - // We can't filter in place, so go ahead and create a linear buffer here. - CUtlVector filterSrc; - filterSrc.EnsureCount(_srcTexels.Count()); - - for (int i = 0; i < _srcTexels.Count(); ++i) - { - ColorRGBExp32 rgbColor; - VectorToColorRGBExp32(_srcTexels[i].m_Color, rgbColor); - ConvertRGBExp32ToLinear( &rgbColor, &(filterSrc[i]) ); - } - - const int cRadius = 1; - const float cOneOverDiameter = 1.0f / pow(2.0f * cRadius + 1.0f, 2.0f) ; - // Filter here. - for (int j = 0; j < _resY; ++j) - { - for (int i = 0; i < _resX; ++i) - { - Vector value(0, 0, 0); - int thisIndex = ComputeLinearPos(i, j, _resX, _resY); - - if (!_srcTexels[thisIndex].m_bValid) - { - (*_outLinear)[thisIndex] = filterSrc[thisIndex]; - continue; - } - - // TODO: Check ASM for this, unroll by hand if needed. - for ( int offsetJ = -cRadius; offsetJ <= cRadius; ++offsetJ ) - { - for ( int offsetI = -cRadius; offsetI <= cRadius; ++offsetI ) - { - int finalIndex = ComputeLinearPos( i + offsetI, j + offsetJ, _resX, _resY ); - if ( !_srcTexels[finalIndex].m_bValid ) - { - finalIndex = thisIndex; - } - - value += filterSrc[finalIndex]; - } - } - - (*_outLinear)[thisIndex] = value * cOneOverDiameter; - } - } -} - -// ------------------------------------------------------------------------------------------------ -static void BuildFineMipmap(unsigned int _resX, unsigned int _resY, bool _applyFilter, const CUtlVector& _srcTexels, CUtlVector* _outTexelsRGB888, CUtlVector* _outLinear) -{ - // At least one of these needs to be non-null, otherwise what are we doing here? - Assert(_outTexelsRGB888 || _outLinear); - Assert(!_applyFilter || _outLinear); - Assert(_srcTexels.Count() == GetTexelCount(_resX, _resY, false)); - - int texelCount = GetTexelCount(_resX, _resY, true); - - if (_outTexelsRGB888) - (*_outTexelsRGB888).EnsureCount(texelCount); - - if (_outLinear) - (*_outLinear).EnsureCount(GetTexelCount(_resX, _resY, false)); - - // This code can take awhile, so minimize the branchiness of the inner-loop. - if (_applyFilter) - { - - FilterFineMipmap(_resX, _resY, _srcTexels, _outLinear); - - if ( _outTexelsRGB888 ) - { - for (int i = 0; i < _srcTexels.Count(); ++i) - { - RGBA8888_t encodedColor; - - Vector linearColor = (*_outLinear)[i]; - - ConvertLinearToRGBA8888( &linearColor, (unsigned char*)&encodedColor ); - (*_outTexelsRGB888)[i].r = encodedColor.r; - (*_outTexelsRGB888)[i].g = encodedColor.g; - (*_outTexelsRGB888)[i].b = encodedColor.b; - } - } - } - else - { - for (int i = 0; i < _srcTexels.Count(); ++i) - { - ColorRGBExp32 rgbColor; - RGBA8888_t encodedColor; - VectorToColorRGBExp32(_srcTexels[i].m_Color, rgbColor); - ConvertRGBExp32ToRGBA8888(&rgbColor, (unsigned char*)&encodedColor, (_outLinear ? (&(*_outLinear)[i]) : NULL) ); - // We drop alpha on the floor here, if this were to fire we'd need to consider using a different compressed format. - Assert(encodedColor.a == 0xFF); - - if (_outTexelsRGB888) - { - (*_outTexelsRGB888)[i].r = encodedColor.r; - (*_outTexelsRGB888)[i].g = encodedColor.g; - (*_outTexelsRGB888)[i].b = encodedColor.b; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -static void FilterCoarserMipmaps(unsigned int _resX, unsigned int _resY, CUtlVector* _scratchLinear, CUtlVector *_outTexelsRGB888) -{ - Assert(_outTexelsRGB888); - - int srcResX = _resX; - int srcResY = _resY; - int dstResX = max(1, (srcResX >> 1)); - int dstResY = max(1, (srcResY >> 1)); - int dstOffset = GetTexelCount(srcResX, srcResY, false); - - // Build mipmaps here, after being converted to linear space. - // TODO: Should do better filtering for downsampling. But this will work for now. - while (srcResX > 1 || srcResY > 1) - { - for (int j = 0; j < srcResY; j += 2) { - for (int i = 0; i < srcResX; i += 2) { - int srcCol0 = i; - int srcCol1 = i + 1 > srcResX - 1 ? srcResX - 1 : i + 1; - int srcRow0 = j; - int srcRow1 = j + 1 > srcResY - 1 ? srcResY - 1 : j + 1;; - - int dstCol = i >> 1; - int dstRow = j >> 1; - - - const Vector& tl = (*_scratchLinear)[srcCol0 + (srcRow0 * srcResX)]; - const Vector& tr = (*_scratchLinear)[srcCol1 + (srcRow0 * srcResX)]; - const Vector& bl = (*_scratchLinear)[srcCol0 + (srcRow1 * srcResX)]; - const Vector& br = (*_scratchLinear)[srcCol1 + (srcRow1 * srcResX)]; - - Vector sample = (tl + tr + bl + br) / 4.0f; - - ConvertLinearToRGBA8888(&sample, (unsigned char*)&(*_outTexelsRGB888)[dstOffset + dstCol + dstRow * dstResX]); - - // Also overwrite the srcBuffer to filter the next loop. This is safe because we won't be reading this source value - // again during this mipmap level. - (*_scratchLinear)[dstCol + dstRow * dstResX] = sample; - } - } - - srcResX = dstResX; - srcResY = dstResY; - dstResX = max(1, (srcResX >> 1)); - dstResY = max(1, (srcResY >> 1)); - dstOffset += GetTexelCount(srcResX, srcResY, false); - } -} - -// ------------------------------------------------------------------------------------------------ -static void ConvertToDestinationFormat(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _scratchRBG888, CUtlMemory* _outTexture) -{ - const ImageFormat cSrcImageFormat = IMAGE_FORMAT_RGB888; - - // Converts from the scratch RGB888 buffer, which should be fully filled out to the output texture. - int destMemoryUsage = ImageLoader::GetMemRequired(_resX, _resY, 1, _destFmt, true); - (*_outTexture).EnsureCapacity(destMemoryUsage); - - int srcResX = _resX; - int srcResY = _resY; - int srcOffset = 0; - int dstOffset = 0; - - // The usual case--that they'll be different. - if (cSrcImageFormat != _destFmt) - { - while (srcResX > 1 || srcResY > 1) - { - // Convert this mipmap level. - ImageLoader::ConvertImageFormat((unsigned char*)(&_scratchRBG888[srcOffset]), cSrcImageFormat, (*_outTexture).Base() + dstOffset, _destFmt, srcResX, srcResY); - - // Then update offsets for the next mipmap level. - srcOffset += GetTexelCount(srcResX, srcResY, false); - dstOffset += ImageLoader::GetMemRequired(srcResX, srcResY, 1, _destFmt, false); - - srcResX = max(1, (srcResX >> 1)); - srcResY = max(1, (srcResY >> 1)); - } - - // Do the 1x1 level also. - ImageLoader::ConvertImageFormat((unsigned char*)_scratchRBG888.Base() + srcOffset, cSrcImageFormat, (*_outTexture).Base() + dstOffset, _destFmt, srcResX, srcResY); - } else { - // But sometimes (particularly for debugging) they will be the same. - Q_memcpy( (*_outTexture).Base(), _scratchRBG888.Base(), destMemoryUsage ); - } -} - -// ------------------------------------------------------------------------------------------------ -static void ConvertTexelDataToTexture(unsigned int _resX, unsigned int _resY, ImageFormat _destFmt, const CUtlVector& _srcTexels, CUtlMemory* _outTexture) -{ - Assert(_outTexture); - Assert(_srcTexels.Count() == _resX * _resY); - - CUtlVector scratchRGB888; - CUtlVector scratchLinear; - - BuildFineMipmap(_resX, _resY, true, _srcTexels, &scratchRGB888, &scratchLinear); - FilterCoarserMipmaps(_resX, _resY, &scratchLinear, &scratchRGB888 ); - ConvertToDestinationFormat(_resX, _resY, _destFmt, scratchRGB888, _outTexture); -} - -// ------------------------------------------------------------------------------------------------ -static void DumpLightmapLinear( const char* _dstFilename, const CUtlVector& _srcTexels, int _width, int _height ) -{ - CUtlVector< Vector > linearFloats; - CUtlVector< BGR888_t > linearBuffer; - BuildFineMipmap( _width, _height, true, _srcTexels, NULL, &linearFloats ); - linearBuffer.SetCount( linearFloats.Count() ); - - for ( int i = 0; i < linearFloats.Count(); ++i ) { - linearBuffer[i].b = RoundFloatToByte(linearFloats[i].z * 255.0f); - linearBuffer[i].g = RoundFloatToByte(linearFloats[i].y * 255.0f); - linearBuffer[i].r = RoundFloatToByte(linearFloats[i].x * 255.0f); - } - - TGAWriter::WriteTGAFile( _dstFilename, _width, _height, IMAGE_FORMAT_BGR888, (uint8*)(linearBuffer.Base()), _width * ImageLoader::SizeInBytes(IMAGE_FORMAT_BGR888) ); -} diff --git a/utils/vrad_launcher/vrad_launcher.cpp b/utils/vrad_launcher/vrad_launcher.cpp index a4d31834..0afb27d7 100644 --- a/utils/vrad_launcher/vrad_launcher.cpp +++ b/utils/vrad_launcher/vrad_launcher.cpp @@ -103,6 +103,18 @@ int main(int argc, char* argv[]) if (mode && (! both_arg)) continue; +#ifdef MAPBASE + // Coming through! + if ( !pModule ) + { + // With this, we just load the DLL with our filename. + // This allows for custom DLLs without having to bother with the launcher. + char filename[64]; + Q_FileBase(argv[0], filename, sizeof(filename)); + Q_snprintf(dllName, sizeof(dllName), "%s%s", filename, "_dll.dll"); + pModule = Sys_LoadModule( dllName ); + } +#endif // If it didn't load the module above, then use the if ( !pModule ) diff --git a/utils/vrad_launcher/vrad_launcher.vpc b/utils/vrad_launcher/vrad_launcher.vpc index 6c1e7b2d..293e5514 100644 --- a/utils/vrad_launcher/vrad_launcher.vpc +++ b/utils/vrad_launcher/vrad_launcher.vpc @@ -15,12 +15,7 @@ $Configuration $Compiler { $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" - $PrecompiledHeaderFile "$(IntDir)/vrad_launcher.pch" - } - - $Linker [$WIN32] - { - $EnableLargeAddresses "Support Addresses Larger Than 2 Gigabytes (/LARGEADDRESSAWARE)" + $PrecompiledHeaderFile "Debug/vrad_launcher.pch" } } diff --git a/utils/vtf2tga/vtf2tga.cpp b/utils/vtf2tga/vtf2tga.cpp index 926473c7..c06999b0 100644 --- a/utils/vtf2tga/vtf2tga.cpp +++ b/utils/vtf2tga/vtf2tga.cpp @@ -187,7 +187,7 @@ int main( int argc, char **argv ) for ( int z = 0; z < iDepth; ++z ) { // Construct output filename - char *pTempNameBuf = new char[iTGANameLen + 13];//(char *)stackalloc( iTGANameLen + 13 ); + char *pTempNameBuf = (char *)stackalloc( iTGANameLen + 13 ); Q_strncpy( pTempNameBuf, pOutFileNameBase, iTGANameLen + 1 ); char *pExt = Q_strrchr( pTempNameBuf, '.' ); if ( pExt ) @@ -306,8 +306,6 @@ int main( int argc, char **argv ) { PFMWrite( ( float * )pDstImage, pTempNameBuf, iWidth, iHeight ); } - - delete[] pTempNameBuf; } } } diff --git a/utils/vtfdiff/vtfdiff.cpp b/utils/vtfdiff/vtfdiff.cpp index 765fb405..068cb319 100644 --- a/utils/vtfdiff/vtfdiff.cpp +++ b/utils/vtfdiff/vtfdiff.cpp @@ -102,9 +102,9 @@ void PrintFlags( int flags ) PRNFLAG( TEXTUREFLAGS_DEPTHRENDERTARGET ) PRNFLAG( TEXTUREFLAGS_NODEBUGOVERRIDE ) PRNFLAG( TEXTUREFLAGS_SINGLECOPY ) - PRNFLAG( TEXTUREFLAGS_STAGING_MEMORY ) - PRNFLAG( TEXTUREFLAGS_IMMEDIATE_CLEANUP ) - PRNFLAG( TEXTUREFLAGS_IGNORE_PICMIP ) + PRNFLAG( TEXTUREFLAGS_UNUSED_00080000 ) + PRNFLAG( TEXTUREFLAGS_UNUSED_00100000 ) + PRNFLAG( TEXTUREFLAGS_UNUSED_00200000 ) PRNFLAG( TEXTUREFLAGS_UNUSED_00400000 ) PRNFLAG( TEXTUREFLAGS_NODEPTHBUFFER ) PRNFLAG( TEXTUREFLAGS_UNUSED_01000000 ) diff --git a/utils/vvis/vvis.cpp b/utils/vvis/vvis.cpp index 42edd0bf..0fb61388 100644 --- a/utils/vvis/vvis.cpp +++ b/utils/vvis/vvis.cpp @@ -1072,7 +1072,6 @@ int RunVVis( int argc, char **argv ) { char portalfile[1024]; char source[1024]; - char mapFile[1024]; double start, end; @@ -1080,25 +1079,17 @@ int RunVVis( int argc, char **argv ) verbose = false; - LoadCmdLineFromFile( argc, argv, source, "vvis" ); - int i = ParseCommandLine( argc, argv ); - + Q_StripExtension( argv[ argc - 1 ], source, sizeof( source ) ); CmdLib_InitFileSystem( argv[ argc - 1 ] ); - // The ExpandPath is just for VMPI. VMPI's file system needs the basedir in front of all filenames, - // so we prepend qdir here. + Q_FileBase( source, source, sizeof( source ) ); - // XXX(johns): Somewhat preserving legacy behavior here to avoid changing tool behavior, there's no specific rhyme - // or reason to this. We get just the base name we were passed, discarding any directory or extension - // information. We then ExpandPath() it (see VMPI comment above), and tack on .bsp for the file access - // parts. - V_FileBase( argv[ argc - 1 ], mapFile, sizeof( mapFile ) ); - V_strncpy( mapFile, ExpandPath( mapFile ), sizeof( mapFile ) ); - V_strncat( mapFile, ".bsp", sizeof( mapFile ) ); + LoadCmdLineFromFile( argc, argv, source, "vvis" ); + int i = ParseCommandLine( argc, argv ); - // Source is just the mapfile without an extension at this point... - V_strncpy( source, mapFile, sizeof( mapFile ) ); - V_StripExtension( source, source, sizeof( source ) ); + // This part is just for VMPI. VMPI's file system needs the basedir in front of all filenames, + // so we prepend qdir here. + strcpy( source, ExpandPath( source ) ); if (i != argc - 1) { @@ -1123,11 +1114,13 @@ int RunVVis( int argc, char **argv ) { SetLowPriority(); } - + ThreadSetDefault (); - Msg ("reading %s\n", mapFile); - LoadBSPFile (mapFile); + char targetPath[1024]; + GetPlatformMapPath( source, targetPath, 0, 1024 ); + Msg ("reading %s\n", targetPath); + LoadBSPFile (targetPath); if (numnodes == 0 || numfaces == 0) Error ("Empty map"); ParseEntities (); @@ -1158,7 +1151,7 @@ int RunVVis( int argc, char **argv ) Q_StripExtension( portalfile, portalfile, sizeof( portalfile ) ); } strcat (portalfile, ".prt"); - + Msg ("reading %s\n", portalfile); LoadPortals (portalfile); @@ -1169,17 +1162,17 @@ int RunVVis( int argc, char **argv ) CalcPAS (); // We need a mapping from cluster to leaves, since the PVS - // deals with clusters for both CalcVisibleFogVolumes and + // deals with clusters for both CalcVisibleFogVolumes and BuildClusterTable(); CalcVisibleFogVolumes(); CalcDistanceFromLeavesToWater(); - visdatasize = vismap_p - dvisdata; + visdatasize = vismap_p - dvisdata; Msg ("visdatasize:%i compressed from %i\n", visdatasize, originalvismapsize*2); - Msg ("writing %s\n", mapFile); - WriteBSPFile (mapFile); + Msg ("writing %s\n", targetPath); + WriteBSPFile (targetPath); } else { @@ -1194,9 +1187,9 @@ int RunVVis( int argc, char **argv ) CalcVisTrace (); WritePortalTrace(source); } - + end = Plat_FloatTime(); - + char str[512]; GetHourMinuteSecondsString( (int)( end - start ), str, sizeof( str ) ); Msg( "%s elapsed\n", str ); diff --git a/utils/vvis/vvis_dll.vpc b/utils/vvis/vvis_dll.vpc index 211719ff..dbd2b955 100644 --- a/utils/vvis/vvis_dll.vpc +++ b/utils/vvis/vvis_dll.vpc @@ -6,6 +6,7 @@ $Macro SRCDIR "..\.." $Macro OUTBINDIR "$SRCDIR\..\game\bin" +$Macro OUTBINNAME "vvis_dll" $Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" @@ -97,6 +98,5 @@ $Project "Vvis_dll" $Lib mathlib $Lib tier2 $Lib vmpi - $Lib "$LIBCOMMON/lzma" } } diff --git a/utils/vvis_launcher/vvis_launcher.cpp b/utils/vvis_launcher/vvis_launcher.cpp index edf03d25..ddc2b83f 100644 --- a/utils/vvis_launcher/vvis_launcher.cpp +++ b/utils/vvis_launcher/vvis_launcher.cpp @@ -45,6 +45,7 @@ char* GetLastErrorString() int main(int argc, char* argv[]) { CommandLine()->CreateCmdLine( argc, argv ); +#ifndef MAPBASE const char *pDLLName = "vvis_dll.dll"; CSysModule *pModule = Sys_LoadModule( pDLLName ); @@ -53,6 +54,31 @@ int main(int argc, char* argv[]) printf( "vvis launcher error: can't load %s\n%s", pDLLName, GetLastErrorString() ); return 1; } +#else + // Coming through! + const char *pDLLName = "vvis_dll.dll"; + + // With this, we just load the DLL with our filename. + // This allows for custom DLLs without having to bother with the launcher. + char filename[128]; + Q_FileBase(argv[0], filename, sizeof(filename)); + Q_snprintf(filename, sizeof(filename), "%s_dll.dll", filename); + pDLLName = filename; + + CSysModule *pModule = Sys_LoadModule( pDLLName ); + if ( !pModule ) + { + // Try loading the default then + pDLLName = "vvis_dll.dll"; + pModule = Sys_LoadModule( pDLLName ); + } + + if ( !pModule ) + { + printf( "vvis launcher error: can't load %s\n%s", pDLLName, GetLastErrorString() ); + return 1; + } +#endif CreateInterfaceFn fn = Sys_GetFactory( pModule ); if( !fn ) diff --git a/utils/vvis_launcher/vvis_launcher.vpc b/utils/vvis_launcher/vvis_launcher.vpc index 71713400..f3c5e958 100644 --- a/utils/vvis_launcher/vvis_launcher.vpc +++ b/utils/vvis_launcher/vvis_launcher.vpc @@ -18,11 +18,6 @@ $Configuration $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" $PrecompiledHeaderFile "Debug/vvis_launcher.pch" } - - $Linker [$WIN32] - { - $EnableLargeAddresses "Support Addresses Larger Than 2 Gigabytes (/LARGEADDRESSAWARE)" - } } $Project "Vvis_launcher" diff --git a/vgui2/chromehtml/chromewrapper.cpp b/vgui2/chromehtml/chromewrapper.cpp new file mode 100644 index 00000000..88f6ee9d --- /dev/null +++ b/vgui2/chromehtml/chromewrapper.cpp @@ -0,0 +1,441 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Creates a HTML control +// +// $NoKeywords: $ +//=============================================================================// +#include "winlite.h" +#include "html_chrome.h" +#include "tier1/interface.h" +#include "reliabletimer.h" +#include "htmlmanager.h" + +#include "html/htmlprotobuf.h" +#include + +//----------------------------------------------------------------------------- +// Purpose: owner object that gets responses from the CEF thread and dispatches them +//----------------------------------------------------------------------------- +class CHTMLController : public IHTMLChromeController +{ +public: + CHTMLController() { m_BrowserSerial = 0; m_nCefTargetFrameRate = 0; SetDefLessFunc( m_mapBrowserRequests ); SetDefLessFunc( m_mapBrowsers ); } + ~CHTMLController() {} + + bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ); + void Shutdown(); + + void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ); + void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ); + void SetClientBuildID( uint64 ulBuildID ); + + bool BHasPendingMessages(); + + void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ); + void RemoveBrowser( IHTMLResponses *pBrowser ); + bool RunFrame(); + + void WakeThread() { AccessHTMLWrapper().WakeThread(); } + HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) { return AccessHTMLWrapper().GetFreeCommandBuffer( eCmd, iBrowser ); } + void PushCommand( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().PushCommand( pCmd ); } + + + bool GetMainThreadCommand( HTMLCommandBuffer_t **pCmd ) { return AccessHTMLWrapper().GetMainThreadCommand( pCmd ); } + void ReleaseCommandBuffer( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().ReleaseCommandBuffer( pCmd ); } + +#ifdef DBGFLAG_VALIDATE + void Validate( CValidator &validator, const char *pchName ); + bool ChromePrepareForValidate(); + bool ChromeResumeFromValidate(); +#endif + + void SetCefThreadTargetFrameRate( uint32 nFPS ); + +private: + // keeps track of outstanding browser create requests + CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowserRequests; + // the next unique identifier to use when doing a browser create + uint32 m_BrowserSerial; + // the map of browser handles to our html panel objects, used for cef thread command dispatching + CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowsers; + + int m_nCefTargetFrameRate; +}; + + +static CHTMLController s_HTMLController; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHTMLController, IHTMLChromeController, CHROMEHTML_CONTROLLER_INTERFACE_VERSION, s_HTMLController ); + + +//----------------------------------------------------------------------------- +// Purpose: request the cef thread to make a new browser +//----------------------------------------------------------------------------- +void CHTMLController::CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) +{ + m_BrowserSerial++; + m_mapBrowserRequests.Insert( m_BrowserSerial, pBrowser ); + + CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserCreate ); + cmd.Body().set_request_id( m_BrowserSerial ); + cmd.Body().set_popup( bPopupWindow ); + cmd.Body().set_useragent( pchUserAgentIdentifier ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserCreate, -1 ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: delete a browser we have +//----------------------------------------------------------------------------- +void CHTMLController::RemoveBrowser( IHTMLResponses *pBrowser ) +{ + + // pull ourselves from the browser handle list as we are doing away + FOR_EACH_MAP_FAST( m_mapBrowsers, i) + { + if ( m_mapBrowsers[i] == pBrowser ) + { + // tell the cef thread this browser is going away + CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserRemove ); + cmd.Body().set_browser_handle( pBrowser->BrowserGetIndex() ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserRemove, pBrowser->BrowserGetIndex() ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); + + // now kill it + m_mapBrowsers.RemoveAt( i ); + } + } + + // also remove us from pending list if in it + FOR_EACH_MAP_FAST( m_mapBrowserRequests, i) + { + if ( m_mapBrowserRequests[i] == pBrowser ) + m_mapBrowserRequests.RemoveAt( i ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: turn on the cef engine +//----------------------------------------------------------------------------- +bool CHTMLController::Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeInit( pchHTMLCacheDir, pchCookiePath ); +#endif + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: shutdown chrome +//----------------------------------------------------------------------------- +void CHTMLController::Shutdown() +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeShutdown(); +#endif +} + + + +// helper macro to dispatch messages from the cef thread +#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ + case eHTMLCommand: \ +{ \ + CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ +{ \ + bError = true; \ +} \ + else \ +{ \ + int idx = m_mapBrowsers.Find( cmd.BodyConst().browser_handle() ); \ + if ( idx != m_mapBrowsers.InvalidIndex() ) \ +{ \ + if ( m_mapBrowsers[idx] ) \ + m_mapBrowsers[idx]->commandFunc( &cmd.BodyConst() ); \ +} \ +} \ +} \ + break; \ + + +//----------------------------------------------------------------------------- +// Purpose: process any ipc responses we have pending +//----------------------------------------------------------------------------- +bool CHTMLController::RunFrame() +{ + VPROF_BUDGET( "CHTMLController::RunFrame", VPROF_BUDGETGROUP_TENFOOT ); + HTMLCommandBuffer_t *pCmd; + bool bError = false; + bool bDidwork = false; + + // Paint messages are dispatched last to avoid doing excessive work on + // the main thread when two paint messages have stacked up in the queue. + // This could be greatly optimized by doing atomic buffer swaps instead + // of pushing the paint updates through a queue, but this helps for now. + // -henryg + CUtlVector< HTMLCommandBuffer_t * > vecDeferredPaint; + + while( GetMainThreadCommand( &pCmd ) ) + { + bool bRelease = true; + bDidwork = true; + //Msg( "Got response %d\n", pCmd->m_eCmd ); + switch( pCmd->m_eCmd ) + { + default: + break; + case eHTMLCommands_BrowserCreateResponse: + { + CHTMLProtoBufMsg< CMsgBrowserCreateResponse > cmd( pCmd->m_eCmd ); + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) + { + bError = true; + } + else + { + int idx = m_mapBrowserRequests.Find( cmd.BodyConst().request_id() ); + if ( idx != m_mapBrowserRequests.InvalidIndex() ) + { + m_mapBrowsers.Insert( cmd.BodyConst().browser_handle(), m_mapBrowserRequests[idx] ); + m_mapBrowserRequests[idx]->BrowserSetIndex( cmd.BodyConst().browser_handle() ); + m_mapBrowserRequests.RemoveAt( idx ); + } + } + } + break; + case eHTMLCommands_NeedsPaint: + { + bRelease = false; + vecDeferredPaint.AddToTail( pCmd ); + } + break; + + HTML_MSG_FUNC( eHTMLCommands_BrowserReady, CMsgBrowserReady, BrowserReady ); + HTML_MSG_FUNC( eHTMLCommands_StartRequest, CMsgStartRequest, BrowserStartRequest ); + HTML_MSG_FUNC( eHTMLCommands_URLChanged, CMsgURLChanged, BrowserURLChanged ); + HTML_MSG_FUNC( eHTMLCommands_FinishedRequest, CMsgFinishedRequest, BrowserFinishedRequest ); + HTML_MSG_FUNC( eHTMLCommands_ShowPopup, CMsgShowPopup, BrowserShowPopup ); + HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, BrowserHidePopup ); + HTML_MSG_FUNC( eHTMLCommands_OpenNewTab, CMsgOpenNewTab, BrowserOpenNewTab ); + HTML_MSG_FUNC( eHTMLCommands_PopupHTMLWindow, CMsgPopupHTMLWindow, BrowserPopupHTMLWindow ); + HTML_MSG_FUNC( eHTMLCommands_SetHTMLTitle, CMsgSetHTMLTitle, BrowserSetHTMLTitle ); + HTML_MSG_FUNC( eHTMLCommands_LoadingResource, CMsgLoadingResource, BrowserLoadingResource ); + HTML_MSG_FUNC( eHTMLCommands_StatusText, CMsgStatusText, BrowserStatusText ); + HTML_MSG_FUNC( eHTMLCommands_SetCursor, CMsgSetCursor, BrowserSetCursor ); + HTML_MSG_FUNC( eHTMLCommands_FileLoadDialog, CMsgFileLoadDialog, BrowserFileLoadDialog ); + HTML_MSG_FUNC( eHTMLCommands_ShowToolTip, CMsgShowToolTip, BrowserShowToolTip ); + HTML_MSG_FUNC( eHTMLCommands_UpdateToolTip, CMsgUpdateToolTip, BrowserUpdateToolTip ); + HTML_MSG_FUNC( eHTMLCommands_HideToolTip, CMsgHideToolTip, BrowserHideToolTip ); + HTML_MSG_FUNC( eHTMLCommands_SearchResults, CMsgSearchResults, BrowserSearchResults ); + HTML_MSG_FUNC( eHTMLCommands_Close, CMsgClose, BrowserClose ); + HTML_MSG_FUNC( eHTMLCommands_GetZoomResponse, CMsgGetZoomResponse, BrowserGetZoomResponse ); + HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSizeResponse, CMsgHorizontalScrollBarSizeResponse, BrowserHorizontalScrollBarSizeResponse ); + HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSizeResponse, CMsgVerticalScrollBarSizeResponse, BrowserVerticalScrollBarSizeResponse ); + HTML_MSG_FUNC( eHTMLCommands_LinkAtPositionResponse, CMsgLinkAtPositionResponse, BrowserLinkAtPositionResponse ); + HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPositionResponse, CMsgZoomToElementAtPositionResponse, BrowserZoomToElementAtPositionResponse ); + HTML_MSG_FUNC( eHTMLCommands_JSAlert, CMsgJSAlert, BrowserJSAlert ); + HTML_MSG_FUNC( eHTMLCommands_JSConfirm, CMsgJSConfirm, BrowserJSConfirm ); + HTML_MSG_FUNC( eHTMLCommands_OpenSteamURL, CMsgOpenSteamURL, BrowserOpenSteamURL ); + HTML_MSG_FUNC( eHTMLCommands_CanGoBackandForward, CMsgCanGoBackAndForward, BrowserCanGoBackandForward ); + HTML_MSG_FUNC( eHTMLCommands_SizePopup, CMsgSizePopup, BrowserSizePopup ); + HTML_MSG_FUNC( eHTMLCommands_ScaleToValueResponse, CMsgScalePageToValueResponse, BrowserScalePageToValueResponse ); + HTML_MSG_FUNC( eHTMLCommands_RequestFullScreen, CMsgRequestFullScreen, BrowserRequestFullScreen ); + HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, BrowserExitFullScreen ); + HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURLResponse, CMsgGetCookiesForURLResponse, BrowserGetCookiesForURLResponse ); + HTML_MSG_FUNC( eHTMLCommands_NodeGotFocus, CMsgNodeHasFocus, BrowserNodeGotFocus ); + HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEGResponse, CMsgSavePageToJPEGResponse, BrowserSavePageToJPEGResponse ); + HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValueResponse, CMsgFocusedNodeTextResponse, BrowserFocusedNodeValueResponse ); + } + if ( bError ) + { + Warning( "Failed to parse command %d", pCmd->m_eCmd ); + Assert( !"Bad Command" ); + } + if ( bRelease ) + { + ReleaseCommandBuffer( pCmd ); + } + } + + // Collapse deferred paints by browser ID and process them; the latest texture always + // has fully updated bits, we simply union its dirty rect with the skipped updates. + // Note: browser resizes always include a full dirty rect, we don't have to check here. + while ( vecDeferredPaint.Count() ) + { + // Pull the last paint off the queue + pCmd = vecDeferredPaint[ vecDeferredPaint.Count() - 1 ]; + int iBrowser = pCmd->m_iBrowser; + CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaint ); + DbgVerify( cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ); + ReleaseCommandBuffer( pCmd ); + vecDeferredPaint.Remove( vecDeferredPaint.Count() - 1 ); + + + CMsgNeedsPaint &body = cmd.Body(); + CChromeUpdateRegion region; + if ( body.updatewide() && body.updatetall() ) + { + region.MarkDirtyRect( body.updatex(), body.updatey(), body.updatex() + body.updatewide(), body.updatey() + body.updatetall() ); + } + else + { + region.MarkAllDirty(); + } + + // Remove earlier paints for the same browser from the queue + for ( int i = vecDeferredPaint.Count() - 1; i >= 0; --i ) + { + if ( vecDeferredPaint[i]->m_iBrowser == iBrowser ) + { + // Decode + CHTMLProtoBufMsg cmdMerge( eHTMLCommands_NeedsPaint ); + DbgVerify( cmdMerge.BDeserializeCrossProc( &vecDeferredPaint[i]->m_Buffer ) ); + CMsgNeedsPaint &bodyMerge = cmdMerge.Body(); + + if ( body.browser_handle() == bodyMerge.browser_handle() ) + { + ReleaseCommandBuffer( vecDeferredPaint[i] ); + vecDeferredPaint.Remove( i ); + + // Merge update region + if ( bodyMerge.updatewide() && bodyMerge.updatetall() ) + { + region.MarkDirtyRect( bodyMerge.updatex(), bodyMerge.updatey(), bodyMerge.updatex() + bodyMerge.updatewide(), bodyMerge.updatey() + bodyMerge.updatetall() ); + } + else + { + region.MarkAllDirty(); + } + + // Send response to the skipped paint update to free up the texture slot + pCmd = GetFreeCommandBuffer( eHTMLCommands_NeedsPaintResponse, bodyMerge.browser_handle() ); + CHTMLProtoBufMsg cmdResponse( eHTMLCommands_NeedsPaintResponse ); + cmdResponse.Body().set_browser_handle( bodyMerge.browser_handle() ); + cmdResponse.Body().set_textureid( bodyMerge.textureid() ); + cmdResponse.SerializeCrossProc( &pCmd->m_Buffer ); + PushCommand( pCmd ); + } + } + } + + // Dispatch the merged update + int idxBrowser = m_mapBrowsers.Find( body.browser_handle() ); + if ( idxBrowser != m_mapBrowsers.InvalidIndex() ) + { + if ( m_mapBrowsers[idxBrowser] ) + { + int updateWide = region.GetUpdateWide( body.wide() ); + int updateTall = region.GetUpdateTall( body.tall() ); + if ( updateWide != body.wide() || updateTall != body.tall() ) + { + body.set_updatex( region.GetUpdateX( body.wide() ) ); + body.set_updatey( region.GetUpdateY( body.tall() ) ); + body.set_updatewide( updateWide ); + body.set_updatetall( updateTall ); + } + else + { + body.clear_updatex(); + body.clear_updatey(); + body.clear_updatewide(); + body.clear_updatetall(); + } + m_mapBrowsers[idxBrowser]->BrowserNeedsPaint( &body ); + } + } + } + + return bDidwork; +} + +//----------------------------------------------------------------------------- +// Purpose: set a cef cookie +//----------------------------------------------------------------------------- +void CHTMLController::SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeSetWebCookie( pchHostname, pchKey, pchValue, pchPath, nExpires ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: set the buildid to report +//----------------------------------------------------------------------------- +void CHTMLController::SetClientBuildID( uint64 ulBuildID ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeSetClientBuildID( ulBuildID ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: get the cef cookies for a url +//----------------------------------------------------------------------------- +void CHTMLController::GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeGetWebCookiesForURL( pstrValue, pchURL, pchName ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: true if any pending html message in the queue +//----------------------------------------------------------------------------- +bool CHTMLController::BHasPendingMessages() +{ + return AccessHTMLWrapper().BHasPendingMessages(); +} + + +//----------------------------------------------------------------------------- +// Purpose: tell the cef thread the frame rate to use if it changes +//----------------------------------------------------------------------------- +void CHTMLController::SetCefThreadTargetFrameRate( uint32 nFPS ) +{ + if ( nFPS != m_nCefTargetFrameRate ) + { + m_nCefTargetFrameRate = nFPS; + CHTMLProtoBufMsg cmd( eHTMLCommands_SetTargetFrameRate ); + cmd.Body().set_ntargetframerate( nFPS ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_SetTargetFrameRate, -1 ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); + } +} + +#ifdef DBGFLAG_VALIDATE +//----------------------------------------------------------------------------- +// Purpose: validate mem +//----------------------------------------------------------------------------- +void CHTMLController::Validate( CValidator &validator, const char *pchName ) +{ + ChromeValidate( validator, "ChromeValidate" ); + + validator.Push( "CHTMLController::ValidateStatics", NULL, pchName ); + ValidateObj( m_mapBrowserRequests ); + ValidateObj( m_mapBrowsers ); + validator.Pop(); +} + +bool CHTMLController::ChromeResumeFromValidate() +{ + return ::ChromeResumeFromValidate(); +} + +bool CHTMLController::ChromePrepareForValidate() +{ + return ::ChromePrepareForValidate(); +} +#endif // DBGFLAG_VALIDATE + + + diff --git a/vgui2/chromehtml/html_chrome.cpp b/vgui2/chromehtml/html_chrome.cpp new file mode 100644 index 00000000..83ea654c --- /dev/null +++ b/vgui2/chromehtml/html_chrome.cpp @@ -0,0 +1,3557 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#include "winlite.h" +#include "html_chrome.h" +#include "cef/include/cef_cookie.h" +#include "imageloadwrapper.h" +#include "html/ichromehtmlwrapper.h" +#include "input/mousecursors.h" +//#include "rtime.h" +#ifdef OSX +extern "C" void *CreateAutoReleasePool(); +extern "C" void ReleaseAutoReleasePool( void *pool ); +#endif +#ifdef WIN32 +#include +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include + +static uint64 sm_ulBuildID = 0; // will be appended to the user agent +static CCEFThread g_CEFThread; // main thread for CEF to do its thinking + +// access for main thread to get to the html object +CCEFThread &AccessHTMLWrapper() +{ + return g_CEFThread; +} + +// helper macro to send a command to the CEF thread +#define DISPATCH_MESSAGE( eCmd ) \ + cmd.Body().set_browser_handle( m_iBrowser ); \ + HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eCmd, m_iBrowser ); \ + cmd.SerializeCrossProc( &pBuf->m_Buffer ); \ + g_CEFThread.PushResponse( pBuf ); \ + +// wrappers for our handle to list index/serial, lower 16 bits are list index, top 16 bits are the serial number +#define BROWSER_HANDLE_FROM_INDEX_SERIAL( iList, nSerial ) iList + ((int)nSerial<<16) +#define BROWSER_SERIAL_FROM_HANDLE( nHandle ) (uint32)nHandle>>16 + +const int k_ScreenshotQuality = 95; // quality value used when making a jpeg image of a web page +const float k_flMaxScreenshotWaitTime = 5.0; // wait up to 5 sec before taking a screenshot + +//----------------------------------------------------------------------------- +// Purpose: thread to manage pumping the CEF message loop +//----------------------------------------------------------------------------- +CCEFThread::CCEFThread() +{ + m_bExit = false; + m_nTargetFrameRate = 60; // 60 Hz by default + m_nBrowserSerial = 0; + m_bFullScreenFlashVisible = false; + m_bSawUserInputThisFrame = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: destructor +//----------------------------------------------------------------------------- +CCEFThread::~CCEFThread() +{ + // This can get called by the main thread before the actual thread exits, + // if there is a forced process exit due to some error. In this case, + // force the thread to exit before destroying the member variables it + // is depending on. + if ( !m_bExit ) + { + TriggerShutdown(); + Join( 20 * k_nThousand ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: tell cef where to place its state dirs +//----------------------------------------------------------------------------- +void CCEFThread::SetCEFPaths( const char *pchHTMLCacheDir, const char *pchCookiePath ) +{ + Assert( !IsAlive() ); + m_sHTMLCacheDir = pchHTMLCacheDir; + m_sCookiePath = pchCookiePath; +} + + +//----------------------------------------------------------------------------- +// Purpose: set the exit event on the cef thread +//----------------------------------------------------------------------------- +void CCEFThread::TriggerShutdown() +{ + m_bExit = true; + m_WakeEvent.Set(); + m_evWaitingForCommand.Set(); + m_eventDidExit.Wait( k_nThousand ); // wait 1 second at most for it to go away +} + + +//----------------------------------------------------------------------------- +// Purpose: tickle the run loop of the thread to run more commands +//----------------------------------------------------------------------------- +void CCEFThread::WakeThread() +{ + m_WakeEvent.Set(); +} + + +//----------------------------------------------------------------------------- +// Purpose: helper macro for message dispatch +//----------------------------------------------------------------------------- +#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ + case eHTMLCommand: \ +{ \ + CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ +{ \ + bError = true; \ +} \ + else \ +{ \ + cmd.Body().set_browser_handle( pCmd->m_iBrowser ); \ + g_CEFThread.commandFunc( cmd ); \ +} \ +} \ + break; + + +#define HTML_MSG_FUNC_NOHANDLE( eHTMLCommand, bodyType, commandFunc ) \ + case eHTMLCommand: \ + { \ + CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ + { \ + bError = true; \ + } \ + else \ + { \ + g_CEFThread.commandFunc( cmd ); \ + } \ + } \ + break; + + +//----------------------------------------------------------------------------- +// Purpose: clear any pending commands from the main thread +//----------------------------------------------------------------------------- +void CCEFThread::RunCurrentCommands() +{ + bool bError = false; + HTMLCommandBuffer_t *pCmd =NULL; + + while( GetCEFThreadCommand( &pCmd ) ) + { + //Msg( "Got command %d\n", pCmd->m_eCmd ); + switch( pCmd->m_eCmd ) + { + HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_BrowserCreate, CMsgBrowserCreate, ThreadCreateBrowser ); + HTML_MSG_FUNC( eHTMLCommands_BrowserRemove, CMsgBrowserRemove, ThreadRemoveBrowser ); + HTML_MSG_FUNC( eHTMLCommands_BrowserSize, CMsgBrowserSize, ThreadBrowserSize ); + HTML_MSG_FUNC( eHTMLCommands_BrowserPosition, CMsgBrowserPosition, ThreadBrowserPosition ); + HTML_MSG_FUNC( eHTMLCommands_PostURL, CMsgPostURL, ThreadBrowserPostURL ); + HTML_MSG_FUNC( eHTMLCommands_StopLoad, CMsgStopLoad, ThreadBrowserStopLoad ); + HTML_MSG_FUNC( eHTMLCommands_Reload, CMsgReload, ThreadBrowserReload ); + HTML_MSG_FUNC( eHTMLCommands_GoForward, CMsgGoForward, ThreadBrowserGoForward ); + HTML_MSG_FUNC( eHTMLCommands_GoBack, CMsgGoBack, ThreadBrowserGoBack ); + HTML_MSG_FUNC( eHTMLCommands_Copy, CMsgCopy, ThreadBrowserCopy ); + HTML_MSG_FUNC( eHTMLCommands_Paste, CMsgPaste, ThreadBrowserPaste ); + HTML_MSG_FUNC( eHTMLCommands_ExecuteJavaScript, CMsgExecuteJavaScript, ThreadBrowserExecuteJavascript ); + HTML_MSG_FUNC( eHTMLCommands_SetFocus, CMsgSetFocus, ThreadBrowserSetFocus ); + HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSize, CMsgHorizontalScrollBarSize, ThreadBrowserHorizontalScrollBarSize ); + HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSize, CMsgVerticalScrollBarSize, ThreadBrowserVerticalScrollBarSize ); + HTML_MSG_FUNC( eHTMLCommands_Find, CMsgFind, ThreadBrowserFind ); + HTML_MSG_FUNC( eHTMLCommands_StopFind, CMsgStopFind, ThreadBrowserStopFind ); + HTML_MSG_FUNC( eHTMLCommands_SetHorizontalScroll, CMsgSetHorizontalScroll, ThreadBrowserSetHorizontalScroll ); + HTML_MSG_FUNC( eHTMLCommands_SetVerticalScroll, CMsgSetVerticalScroll, ThreadBrowserSetVerticalScroll ); + HTML_MSG_FUNC( eHTMLCommands_SetZoomLevel, CMsgSetZoomLevel, ThreadBrowserSetZoomLevel ); + HTML_MSG_FUNC( eHTMLCommands_ViewSource, CMsgViewSource, ThreadBrowserViewSource ); + HTML_MSG_FUNC( eHTMLCommands_NeedsPaintResponse, CMsgNeedsPaintResponse, ThreadNeedsPaintResponse ); + HTML_MSG_FUNC( eHTMLCommands_BrowserErrorStrings, CMsgBrowserErrorStrings, ThreadBrowserErrorStrings ); + HTML_MSG_FUNC( eHTMLCommands_AddHeader, CMsgAddHeader, ThreadAddHeader ); + HTML_MSG_FUNC( eHTMLCommands_GetZoom, CMsgGetZoom, ThreadGetZoom ); + HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_SetCookie, CMsgSetCookie, ThreadSetCookie ); + HTML_MSG_FUNC_NOHANDLE( eHTMLCommands_SetTargetFrameRate, CMsgSetTargetFrameRate, ThreadSetTargetFrameRate ); + HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, ThreadHidePopup ); + HTML_MSG_FUNC( eHTMLCommands_FullRepaint, CMsgFullRepaint, ThreadFullRepaint ); + HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURL, CMsgGetCookiesForURL, ThreadGetCookiesForURL ); + HTML_MSG_FUNC( eHTMLCommands_ZoomToCurrentlyFocusedNode, CMsgZoomToFocusedElement, ThreadZoomToFocusedElement ); + HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValue, CMsgFocusedNodeText, ThreadGetFocusedNodeText ); + + HTML_MSG_FUNC( eHTMLCommands_MouseDown, CMsgMouseDown, ThreadMouseButtonDown ); + HTML_MSG_FUNC( eHTMLCommands_MouseUp, CMsgMouseUp, ThreadMouseButtonUp ); + HTML_MSG_FUNC( eHTMLCommands_MouseDblClick, CMsgMouseDblClick, ThreadMouseButtonDlbClick ); + HTML_MSG_FUNC( eHTMLCommands_MouseWheel, CMsgMouseWheel, ThreadMouseWheel ); + HTML_MSG_FUNC( eHTMLCommands_KeyDown, CMsgKeyDown, ThreadKeyDown ); + HTML_MSG_FUNC( eHTMLCommands_KeyUp, CMsgKeyUp, ThreadKeyUp ); + HTML_MSG_FUNC( eHTMLCommands_KeyChar, CMsgKeyChar, ThreadKeyTyped ); + HTML_MSG_FUNC( eHTMLCommands_MouseMove, CMsgMouseMove, ThreadMouseMove ); + HTML_MSG_FUNC( eHTMLCommands_MouseLeave, CMsgMouseLeave, ThreadMouseLeave ); + HTML_MSG_FUNC( eHTMLCommands_LinkAtPosition, CMsgLinkAtPosition, ThreadLinkAtPosition ); + HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPosition, CMsgZoomToElementAtPosition, ThreadZoomToElementAtPosition ); + HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEG, CMsgSavePageToJPEG, ThreadSavePageToJPEG ); + HTML_MSG_FUNC( eHTMLCommands_SetPageScale, CMsgScalePageToValue, ThreadSetPageScale ); + HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, ThreadExitFullScreen ); + HTML_MSG_FUNC( eHTMLCommands_CloseFullScreenFlashIfOpen, CMsgCloseFullScreenFlashIfOpen, ThreadCloseFullScreenFlashIfOpen ); + HTML_MSG_FUNC( eHTMLCommands_PauseFullScreenFlashMovieIfOpen, CMsgPauseFullScreenFlashMovieIfOpen, ThreadPauseFullScreenFlashMovieIfOpen ); + + default: + bError = true; + AssertMsg1( false, "Invalid message in browser stream (%d)", pCmd->m_eCmd ); + break; + } + + if ( pCmd->m_eCmd == eHTMLCommands_MouseDown || pCmd->m_eCmd == eHTMLCommands_MouseDblClick || pCmd->m_eCmd == eHTMLCommands_KeyDown ) + m_bSawUserInputThisFrame = true; + + ReleaseCommandBuffer( pCmd ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: done with this buffer, put it in the free queue +//----------------------------------------------------------------------------- +void CCEFThread::ReleaseCommandBuffer( HTMLCommandBuffer_t *pBuf ) +{ + pBuf->m_eCmd = eHTMLCommands_None; + pBuf->m_iBrowser = -1; + pBuf->m_Buffer.Clear(); + m_tslUnsedBuffers.PushItem( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get the next free cef thread command buffer to write into +//----------------------------------------------------------------------------- +HTMLCommandBuffer_t *CCEFThread::GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) +{ + HTMLCommandBuffer_t *pBuf; + if ( !m_tslUnsedBuffers.PopItem( &pBuf ) ) // if nothing in the free queue just make a new one + pBuf = new HTMLCommandBuffer_t; + + pBuf->m_eCmd = eCmd; + pBuf->m_iBrowser = iBrowser; + return pBuf; +} + + +//----------------------------------------------------------------------------- +// Purpose: wait for a command of this type on the cef thread +//----------------------------------------------------------------------------- +HTMLCommandBuffer_t *CCEFThread::BWaitForCommand( EHTMLCommands eCmd, int iBrowser ) +{ + while ( !m_bExit ) + { + if ( m_bSleepForValidate ) + { + m_bSleepingForValidate = true; + ThreadSleep( 100 ); + continue; + } + m_bSleepingForValidate = false; + + HTMLCommandBuffer_t *pBuf = NULL; + while ( m_tslCommandBuffers.PopItem( &pBuf ) && pBuf ) + { + if ( pBuf->m_iBrowser == iBrowser ) + { + if ( pBuf->m_eCmd == eCmd ) // it is what we have been waiting for + return pBuf; + if ( pBuf->m_eCmd == eHTMLCommands_BrowserRemove ) // check to see if this is being deleted while its launching + return NULL; + } + + m_vecQueueCommands.AddToTail( pBuf ); + pBuf = NULL; + } + Assert( pBuf == NULL ); + m_evWaitingForCommand.Wait(); + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: wait for a command of this type on the cef thread +//----------------------------------------------------------------------------- +HTMLCommandBuffer_t *CCEFThread::BWaitForResponse( EHTMLCommands eCmd, int iBrowser ) +{ + while ( !m_bExit ) + { + if ( m_bSleepForValidate ) + { + m_bSleepingForValidate = true; + ThreadSleep( 100 ); + continue; + } + m_bSleepingForValidate = false; + + HTMLCommandBuffer_t *pBuf = NULL; + while ( m_tslResponseBuffers.PopItem( &pBuf ) && pBuf ) + { + if ( pBuf->m_iBrowser == iBrowser ) + { + if ( pBuf->m_eCmd == eCmd ) // it is what we have been waiting for + return pBuf; + if ( pBuf->m_eCmd == eHTMLCommands_BrowserRemove ) // check to see if this is being deleted while its launching + return NULL; + } + + m_vecQueueResponses.AddToTail( pBuf ); + pBuf = NULL; + } + Assert( pBuf == NULL ); + m_evWaitingForResponse.Wait(); + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: add a command for the cef thread +//----------------------------------------------------------------------------- +void CCEFThread::PushCommand( HTMLCommandBuffer_t *pBuf ) +{ + m_tslCommandBuffers.PushItem( pBuf ); + m_evWaitingForCommand.Set(); +} + + +//----------------------------------------------------------------------------- +// Purpose: add a command for the main thread +//----------------------------------------------------------------------------- +void CCEFThread::PushResponse( HTMLCommandBuffer_t *pBuf ) +{ + m_tslResponseBuffers.PushItem( pBuf ); + m_evWaitingForResponse.Set(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: get any cef responses on the main thread, returns false if there are none +//----------------------------------------------------------------------------- +bool CCEFThread::GetMainThreadCommand( HTMLCommandBuffer_t **pBuf ) +{ + if ( m_vecQueueResponses.Count() ) + { + *pBuf = m_vecQueueResponses[0]; + m_vecQueueResponses.Remove(0); + return true; + } + else + return m_tslResponseBuffers.PopItem( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get the next cef thread protobuf command to run, return false if there are none +//----------------------------------------------------------------------------- +bool CCEFThread::GetCEFThreadCommand( HTMLCommandBuffer_t **pBuf ) +{ + if ( m_vecQueueCommands.Count() ) + { + *pBuf = m_vecQueueCommands[0]; + m_vecQueueCommands.Remove(0); + return true; + } + else + return m_tslCommandBuffers.PopItem( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: the user agent to report when using this browser control +//----------------------------------------------------------------------------- +const char *CCEFThread::PchWebkitUserAgent() +{ + return "Mozilla/5.0 (%s; U; %s; en-US; %s/%llu; %s) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"; +} + + +//----------------------------------------------------------------------------- +// Purpose: make a new browser object +//----------------------------------------------------------------------------- +void CCEFThread::ThreadCreateBrowser( const CHTMLProtoBufMsg &htmlCommand ) +{ + int idx = m_listClientHandlers.AddToTail(); + ++m_nBrowserSerial; + CClientHandler *pBrowser = new CClientHandler( BROWSER_HANDLE_FROM_INDEX_SERIAL( idx, m_nBrowserSerial ), PchWebkitUserAgent(), m_nBrowserSerial ); + pBrowser->SetUserAgentIdentifier( htmlCommand.BodyConst().useragent().c_str() ); + + // send the handle info back to the main thread, needs to be before the CreateBrowser below + // to stop a race condition of the browser being ready before the main thread knows its handle + CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserCreateResponse ); + cmd.Body().set_browser_handle( BROWSER_HANDLE_FROM_INDEX_SERIAL( idx, m_nBrowserSerial ) ); + cmd.Body().set_request_id( htmlCommand.BodyConst().request_id() ); + HTMLCommandBuffer_t *pBuf = GetFreeCommandBuffer( eHTMLCommands_BrowserCreateResponse, idx ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + PushResponse( pBuf ); + + m_listClientHandlers[idx] = pBrowser; + pBrowser->AddRef(); + + CefWindowInfo info; + info.SetAsOffScreen( NULL ); + info.m_bPopupWindow = htmlCommand.BodyConst().popup(); + CefBrowserSettings settings; + settings.fullscreen_enabled = true; + settings.threaded_compositing_enabled = true; + settings.java_disabled = true; + //settings.accelerated_compositing_enabled = true; // not supported when going into fullscreen mode + + // Drag and drop is supposed to be disabled automatically for offscreen views, but + // ports for Mac and Linux have bugs where it is not really disabled, causing havoc + settings.drag_drop_disabled = true; + +#ifdef LINUX + // Turn off web features here that don't work on Linux + settings.webgl_disabled = true; +#endif + + // CEF HTML local storage, databases, and offline application cache are all busted; + // they live in a temp dir which gets cleaned up on shutdown. There's no point in + // enabling them just to generate extra files to cleanup on shutdown when there's + // no actual disk persistence. we need to upgrade CEF again before they will work. + settings.local_storage_disabled = true; + settings.databases_disabled = true; + settings.application_cache_disabled = true; + settings.java_disabled = true; + + // We don't provide a UI to connect to the WebKit developer tools API + // so there is no point having it suck up CPU and listening on a port. + settings.developer_tools_disabled = true; + + // Drag and drop is supposed to be disabled automatically for offscreen views, but + // ports for Mac and Linux have bugs where it is not really disabled, causing havoc + settings.drag_drop_disabled = true; + +#ifdef LINUX + // Turn off web features here that don't work on Linux + settings.webgl_disabled = true; +#endif + + CefBrowser::CreateBrowserSync( info, pBrowser, "", settings ); + CefDoMessageLoopWork(); +} + + +//----------------------------------------------------------------------------- +// Purpose: return true if this browser handle resolves into a currently valid browser handler object +//----------------------------------------------------------------------------- +bool CCEFThread::BIsValidBrowserHandle( uint32 nHandle, int &iClient ) +{ + iClient = nHandle & 0xffff; + if ( m_listClientHandlers.IsValidIndex( nHandle & 0xffff ) ) + { + if ( m_listClientHandlers[ iClient ]->NSerial() == BROWSER_SERIAL_FROM_HANDLE( nHandle ) ) + return true; + } + iClient = -1; + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: delete this browser object, we are done with it +//----------------------------------------------------------------------------- +void CCEFThread::ThreadRemoveBrowser( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[iClient]->CloseBrowser(); + m_listClientHandlers[iClient]->Release(); + m_listClientHandlers[iClient] = NULL; + m_listClientHandlers.Remove( iClient ); + } +} + + +// helper macro to call browser functions if you have a valid handle +#define GET_BROSWER_FUNC( msg, cmd ) \ + int iClient; \ + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) \ + { \ + if ( m_listClientHandlers[iClient]->GetBrowser() ) \ + m_listClientHandlers[iClient]->GetBrowser()->cmd; \ + } \ + + //else \ + // Assert( false ); + + +//----------------------------------------------------------------------------- +// Purpose: make the web page this many pixels wide&tall +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserSize( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, SetSize( PET_VIEW, htmlCommand.BodyConst().width(), htmlCommand.BodyConst().height() ) ); + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + m_listClientHandlers[iClient]->SetSize( htmlCommand.BodyConst().width(), htmlCommand.BodyConst().height() ); + } + + +//----------------------------------------------------------------------------- +// Purpose: set the global position of the browser to these co-ords, used by some activeX controls +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserPosition( const CHTMLProtoBufMsg &htmlCommand ) +{ + // no longer used - BUGBUG remove me +} + + +//----------------------------------------------------------------------------- +// Purpose: load this url in the browser with optional post data +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserPostURL( const CHTMLProtoBufMsg &htmlCommand ) +{ + if ( htmlCommand.BodyConst().url().empty() ) + return; // they asked us to load nothing, ignore them + + const char *pchPostData = htmlCommand.BodyConst().post().c_str(); + if ( !pchPostData || !pchPostData[0] ) + { + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->LoadURL( std::wstring( CStrAutoEncode( htmlCommand.BodyConst().url().c_str() ).ToWString() ) ) ); + } + else + { + // Create a new request + CefRefPtr request(CefRequest::CreateRequest()); + + // Set the request URL + request->SetURL( CStrAutoEncode( htmlCommand.BodyConst().url().c_str() ).ToWString() ); + + // Add post data to the request. The correct method and content- + // type headers will be set by CEF. + CefRefPtr postDataElement( CefPostDataElement::CreatePostDataElement() ); + + std::string data = pchPostData; + + postDataElement->SetToBytes(data.length(), data.c_str()); + + CefRefPtr postData(CefPostData::CreatePostData()); + + postData->AddElement(postDataElement); + request->SetPostData(postData); + + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->LoadRequest( request ) ); + } + + int iClient; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + m_listClientHandlers[iClient]->SetPendingPageSerial( htmlCommand.BodyConst().pageserial() ); + + CefDoMessageLoopWork(); // make sure CEF processes this load before we do anything else (like delete the browser control) +} + + +//----------------------------------------------------------------------------- +// Purpose: stop loading the page we are on +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserStopLoad( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, StopLoad() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: reload the current page +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserReload( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, Reload() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: go forward one page in its history +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserGoForward( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GoForward() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: go back one page in its history +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserGoBack( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GoBack() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: copy selected text to the clipboard +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserCopy( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->Copy() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: paste from the clipboard into the web page +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserPaste( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->Paste() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: run this javascript on the current page +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserExecuteJavascript( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->ExecuteJavaScript( + CStrAutoEncode( htmlCommand.BodyConst().script().c_str() ).ToWString(), L"", 0 ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: tell the browser it has key focus +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserSetFocus( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, SetFocus( htmlCommand.BodyConst().focus() ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get the size of the horizontal scroll bar +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserHorizontalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ) +{ + ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: tell the main thread details of the horiztonal scrollbar +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserHorizontalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ) +{ + CClientHandler::CachedScrollBarState_t scroll = { }; + float flZoom = 0.0f; + int iClient = 0; + if ( BIsValidBrowserHandle( iBrowser, iClient ) ) + { + CClientHandler *pHandler = m_listClientHandlers[iClient]; + + if ( pHandler->GetBrowser() ) + { + scroll.m_nMax = pHandler->GetBrowser()->HorizontalScrollMax(); + scroll.m_nScroll = pHandler->GetBrowser()->HorizontalScroll(); + scroll.m_bVisible = pHandler->GetBrowser()->IsHorizontalScrollBarVisible(); + pHandler->GetBrowser()->HorizontalScrollBarSize( scroll.m_nX, scroll.m_nY, scroll.m_nWide, scroll.m_nTall ); + flZoom = pHandler->GetBrowser()->GetZoomLevel(); + if ( scroll.m_nMax < 0 ) + scroll.m_nMax = 0; + if ( flZoom == 0.0f ) + flZoom = 1.0f; + } + + if ( bForceSendUpdate || 0 != memcmp( &pHandler->m_CachedHScroll, &scroll, sizeof( scroll ) ) ) + { + pHandler->m_CachedHScroll = scroll; + + CHTMLProtoBufMsg cmd( eHTMLCommands_HorizontalScrollBarSizeResponse ); + cmd.Body().set_x( scroll.m_nX ); + cmd.Body().set_y( scroll.m_nY ); + cmd.Body().set_wide( scroll.m_nWide ); + cmd.Body().set_tall( scroll.m_nTall ); + cmd.Body().set_scroll_max( scroll.m_nMax ); + cmd.Body().set_scroll( scroll.m_nScroll ); + cmd.Body().set_visible( scroll.m_bVisible != 0 ); + cmd.Body().set_zoom( flZoom ); + int m_iBrowser = iBrowser; + DISPATCH_MESSAGE( eHTMLCommands_HorizontalScrollBarSizeResponse ); +} + } +} + + +//----------------------------------------------------------------------------- +// Purpose: get the size of the verical scrollbar +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserVerticalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ) +{ + ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: tell the main thread details of the vertical scrollbar +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserVerticalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ) +{ + CClientHandler::CachedScrollBarState_t scroll = { }; + float flZoom = 0.0f; + int iClient = 0; + if ( BIsValidBrowserHandle( iBrowser, iClient ) ) + { + CClientHandler *pHandler = m_listClientHandlers[iClient]; + + if ( pHandler->GetBrowser() ) + { + scroll.m_nMax = pHandler->GetBrowser()->VerticalScrollMax(); + scroll.m_nScroll = pHandler->GetBrowser()->VerticalScroll(); + scroll.m_bVisible = pHandler->GetBrowser()->IsVeritcalScrollBarVisible(); + pHandler->GetBrowser()->VerticalScrollBarSize( scroll.m_nX, scroll.m_nY, scroll.m_nWide, scroll.m_nTall ); + flZoom = pHandler->GetBrowser()->GetZoomLevel(); + if ( scroll.m_nMax < 0 ) + scroll.m_nMax = 0; + if ( flZoom == 0.0f ) + flZoom = 1.0f; + } + + if ( bForceSendUpdate || 0 != memcmp( &pHandler->m_CachedVScroll, &scroll, sizeof( scroll ) ) ) + { + pHandler->m_CachedVScroll = scroll; + + CHTMLProtoBufMsg cmd( eHTMLCommands_VerticalScrollBarSizeResponse ); + cmd.Body().set_x( scroll.m_nX ); + cmd.Body().set_y( scroll.m_nY ); + cmd.Body().set_wide( scroll.m_nWide ); + cmd.Body().set_tall( scroll.m_nTall ); + cmd.Body().set_scroll_max( scroll.m_nMax ); + cmd.Body().set_scroll( scroll.m_nScroll ); + cmd.Body().set_visible( scroll.m_bVisible != 0 ); + cmd.Body().set_zoom( flZoom ); + int m_iBrowser = iBrowser; + DISPATCH_MESSAGE( eHTMLCommands_VerticalScrollBarSizeResponse ); +} + } +} + + +//----------------------------------------------------------------------------- +// Purpose: start a find in a web page +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserFind( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, Find( 1, htmlCommand.BodyConst().find().c_str(), !htmlCommand.BodyConst().reverse(), false, htmlCommand.BodyConst().infind() ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: dismiss a current find +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserStopFind( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, StopFinding( 1 ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: scroll the page horizontally to this pos +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserSetHorizontalScroll( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, SetHorizontalScroll( htmlCommand.BodyConst().scroll() ) ); + + ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); + } + + +//----------------------------------------------------------------------------- +// Purpose: scroll the page vertically to this pos +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserSetVerticalScroll( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, SetVerticalScroll( htmlCommand.BodyConst().scroll() ) ); + + ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: set the zoom to this level, 100% means normal size, 200% double size +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserSetZoomLevel( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, SetZoomLevel( htmlCommand.BodyConst().zoom() ) ); + + CefDoMessageLoopWork(); // tell cef to think one frame, Zoom is in a work queue and we want it to apply right away so think now + + // now tell if about the scrollbars we now have + ThreadBrowserHorizontalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); + ThreadBrowserVerticalScrollBarSizeHelper( htmlCommand.BodyConst().browser_handle(), true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: show the page source in notepad +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserViewSource( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, GetMainFrame()->ViewSource() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: add a header to any requests we make +//----------------------------------------------------------------------------- +void CCEFThread::ThreadAddHeader( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[iClient]->AddHeader( htmlCommand.BodyConst().key().c_str(), htmlCommand.BodyConst().value().c_str() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: main thread is done with a paint buffer, tell our handler +//----------------------------------------------------------------------------- +void CCEFThread::ThreadNeedsPaintResponse( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[iClient]->SetTextureUploaded( htmlCommand.BodyConst().textureid() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: set the error strings to display on page load +//----------------------------------------------------------------------------- +void CCEFThread::ThreadBrowserErrorStrings( const CHTMLProtoBufMsg &cmd ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( cmd.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[iClient]->SetErrorStrings( cmd.BodyConst().title().c_str(), cmd.BodyConst().header().c_str(), + cmd.BodyConst().cache_miss().c_str(), cmd.BodyConst().bad_url().c_str(), + cmd.BodyConst().connection_problem().c_str(), + cmd.BodyConst().proxy_problem().c_str(), cmd.BodyConst().unknown().c_str() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: return the zoom level for the current page, 100% means actual size, 200% double size +//----------------------------------------------------------------------------- +void CCEFThread::ThreadGetZoom( const CHTMLProtoBufMsg &htmlCmd ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCmd.BodyConst().browser_handle(), iClient ) ) + { + float flZoom = 0.0f; + if ( m_listClientHandlers[iClient]->GetBrowser() ) + flZoom = m_listClientHandlers[iClient]->GetBrowser()->GetZoomLevel(); + if ( flZoom == 0.0f ) + flZoom = 1.0f; + if ( flZoom > 100.0f ) + flZoom /= 100.0f; + CHTMLProtoBufMsg cmd( eHTMLCommands_GetZoomResponse ); + cmd.Body().set_zoom( flZoom ); + int m_iBrowser = htmlCmd.BodyConst().browser_handle(); + DISPATCH_MESSAGE( eHTMLCommands_GetZoomResponse ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: handler func to throw the cookie call to the cef IO thread +//----------------------------------------------------------------------------- +void IOT_SetCookie(const CefString& url, CefCookie* cookie, CThreadEvent *pEvent ) +{ + CefCookieManager::GetGlobalManager()->SetCookie(url, *cookie); + pEvent->Set(); +} + + +//----------------------------------------------------------------------------- +// Purpose: set this cookie into the cef instance +//----------------------------------------------------------------------------- +void CCEFThread::ThreadSetCookie( const CHTMLProtoBufMsg &htmlCommand ) +{ + CefCookie cookie; + cef_string_utf8_copy( htmlCommand.BodyConst().key().c_str(), htmlCommand.BodyConst().key().size(), &cookie.name ); + cef_string_utf8_copy( htmlCommand.BodyConst().value().c_str(), htmlCommand.BodyConst().value().size(), &cookie.value ); + cef_string_utf8_copy( htmlCommand.BodyConst().path().c_str(), htmlCommand.BodyConst().path().size(), &cookie.path ); + if ( htmlCommand.BodyConst().has_expires() ) + { + AssertMsg( false, "Cookie expiration not implemented -- rtime.cpp needs to be ported." ); + /* + cookie.has_expires = true; + CRTime rtExpire( (RTime32)htmlCommand.BodyConst().expires() ); + cookie.expires.year = rtExpire.GetLocalYear(); + cookie.expires.month = rtExpire.GetLocalMonth(); +#if !defined(OS_MACOSX) + cookie.expires.day_of_week = rtExpire.GetLocalDayOfWeek(); +#endif + cookie.expires.day_of_month = rtExpire.GetLocalMonth(); + cookie.expires.hour = rtExpire.GetLocalHour(); + cookie.expires.minute = rtExpire.GetLocalMinute(); + cookie.expires.second = rtExpire.GetLocalSecond(); + */ + } + + CThreadEvent event; + CefPostTask(TID_IO, NewCefRunnableFunction( IOT_SetCookie, htmlCommand.BodyConst().host().c_str(), &cookie, &event)); + event.Wait(); +} + + +struct CCefCookie +{ + CUtlString sValue; + CUtlString sName; + CUtlString sDomain; + CUtlString sPath; +}; +//----------------------------------------------------------------------------- +// Purpose: helper class to iterator cookies +//----------------------------------------------------------------------------- +class CookieVisitor : public CefCookieVisitor { +public: + CookieVisitor( CUtlVector *pVec, CThreadEvent *pEvent ) + { + m_pVecCookies = pVec; + m_pEvent = pEvent; + } + ~CookieVisitor() + { + m_pEvent->Set(); + } + + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) { + + CCefCookie cookieCopy; + cookieCopy.sValue = cookie.value.str; + cookieCopy.sName = cookie.name.str; + cookieCopy.sDomain = cookie.domain.str; + cookieCopy.sPath = cookie.path.str; + m_pVecCookies->AddToTail( cookieCopy ); + return true; + } + +private: + CUtlVector *m_pVecCookies; + CThreadEvent *m_pEvent; + + IMPLEMENT_REFCOUNTING(CookieVisitor); +}; + + +//----------------------------------------------------------------------------- +// Purpose: handler func to throw the cookie call to the cef IO thread +//----------------------------------------------------------------------------- +void IOT_CookiesForURL(const CefString& url, CThreadEvent *pEvent, CUtlVector *pVecCookies ) +{ + CefCookieManager::GetGlobalManager()->VisitUrlCookies( url, false, new CookieVisitor( pVecCookies, pEvent ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get all the cookies for this URL +//----------------------------------------------------------------------------- +void CCEFThread::ThreadGetCookiesForURL( const CHTMLProtoBufMsg &htmlCommand ) +{ + CUtlVector vecCookies; + CThreadEvent event; + CefPostTask(TID_IO, NewCefRunnableFunction( IOT_CookiesForURL, htmlCommand.BodyConst().url().c_str(), &event, &vecCookies )); + event.Wait(); + + CHTMLProtoBufMsg cmd( eHTMLCommands_GetCookiesForURLResponse ); + int m_iBrowser = htmlCommand.BodyConst().browser_handle(); + cmd.Body().set_url( htmlCommand.BodyConst().url() ); + + FOR_EACH_VEC( vecCookies, i ) + { + CCookie *pCookie = cmd.Body().add_cookies(); + pCookie->set_name( vecCookies[i].sName ); + pCookie->set_value( vecCookies[i].sValue ); + pCookie->set_domain( vecCookies[i].sDomain ); + pCookie->set_path( vecCookies[i].sPath ); + } + + DISPATCH_MESSAGE( eHTMLCommands_GetCookiesForURLResponse ); +} + + +//----------------------------------------------------------------------------- +// Purpose: set the framerate to run CEF at +//----------------------------------------------------------------------------- +void CCEFThread::ThreadSetTargetFrameRate( const CHTMLProtoBufMsg &htmlCommand ) +{ + m_nTargetFrameRate = htmlCommand.BodyConst().ntargetframerate(); +} + + +//----------------------------------------------------------------------------- +// Purpose: hide any showing popup for this browser +//----------------------------------------------------------------------------- +void CCEFThread::ThreadHidePopup( const CHTMLProtoBufMsg &htmlCommand ) +{ + GET_BROSWER_FUNC( htmlCommand, HidePopup() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: request a full redraw of the client +//----------------------------------------------------------------------------- +void CCEFThread::ThreadFullRepaint( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + if ( m_listClientHandlers[iClient]->GetBrowser()->IsVisuallyNonEmpty() ) + { + int wide, tall; + m_listClientHandlers[iClient]->GetExpectedSize( wide, tall); + CefRect rect; + rect.x = rect.y = 0; + rect.width = wide; + rect.height = tall; + m_listClientHandlers[iClient]->GetBrowser()->Invalidate( rect ); + } + else + m_listClientHandlers[iClient]->GetBrowser()->Reload(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: configure the options we want for cef +//----------------------------------------------------------------------------- +void CCEFThread::AppGetSettings(CefSettings& settings, CefRefPtr& app) +{ + settings.multi_threaded_message_loop = false; +#if defined(OS_WIN) + settings.auto_detect_proxy_settings_enabled = true; +#endif + + CefString(&settings.cache_path) = m_sHTMLCacheDir; + CefString(&settings.product_version) = "Steam"; +// CefString(&settings.log_file) = +/*#ifdef WIN32 + settings.graphics_implementation = ANGLE_IN_PROCESS_COMMAND_BUFFER; +#else*/ + settings.graphics_implementation = DESKTOP_IN_PROCESS_COMMAND_BUFFER; +//#endif +} + +//----------------------------------------------------------------------------- +// Purpose: clean up the temp folders cef can leave around on crash +//----------------------------------------------------------------------------- +void CCEFThread::CleanupTempFolders() +{ + /* + // Temporarily commented out to avoid bringing in additional code. +#if defined( WIN32 ) + char rgchPath[MAX_PATH]; + if ( GetTempPathA( Q_ARRAYSIZE( rgchPath ), rgchPath ) == 0 ) + return; + + CUtlString strPath = rgchPath; +#elif defined( LINUX ) || defined( OSX ) + // TMPDIR first, T_tmpdir next, /tmp last. + char *pszDir = getenv( "TMPDIR" ); + if ( pszDir == NULL ) + { + pszDir = P_tmpdir; + if ( pszDir == NULL ) + pszDir = "/tmp"; + } + if ( pszDir == NULL ) + return; + + CUtlString strPath = pszDir; +#endif + + if ( strPath[strPath.Length()-1] != CORRECT_PATH_SEPARATOR ) + strPath += CORRECT_PATH_SEPARATOR_S; + + CUtlString strSearch = strPath; + strSearch += "scoped_dir*"; + CDirIterator tempDirIterator( strSearch.String() ); + + while ( tempDirIterator.BNextFile() ) + { + if ( tempDirIterator.BCurrentIsDir() ) + { + CUtlString sStrDir = strPath; + sStrDir += tempDirIterator.CurrentFileName(); + BRemoveDirectoryRecursive( sStrDir ); + } + } + */ +} + + +//----------------------------------------------------------------------------- +// Purpose: main thread for pumping CEF, get commands from the main thread and dispatches responses to it +//----------------------------------------------------------------------------- +int CCEFThread::Run() +{ + { // scope to trigger destructors before setting the we have exited event + CefSettings settings; + CefRefPtr app; + + // blow away any temp folders CEF left lying around if we crashed last + CleanupTempFolders(); + + // Populate the settings based on command line arguments. + AppGetSettings(settings, app); + settings.pack_loading_disabled = true; + + // Initialize CEF. + CefInitialize(settings, app, ""); + + #if defined( VPROF_ENABLED ) +// CVProfile *pProfile = GetVProfProfileForCurrentThread(); + #endif + + CLimitTimer timer; + CLimitTimer timerLastCefThink; // track when we think cef so we can do it at a minimum of 10hz + timerLastCefThink.SetLimit( k_nMillion ); // 1Hz min think time +#ifdef WIN32 + CLimitTimer timerLastFlashFullscreenThink; // track when we think cef so we can do it at a minimum of 10hz + timerLastFlashFullscreenThink.SetLimit( k_nMillion * k_nMillion ); // think again in the distance future + bool bInitialThinkAfterInput = false; +#endif + while( !m_bExit ) + { + #ifdef OSX + void *pool = CreateAutoReleasePool(); + #endif + + if ( m_bSleepForValidate ) + { + m_bSleepingForValidate = true; + ThreadSleep( 100 ); + continue; + } + m_bSleepingForValidate = false; + + m_bSawUserInputThisFrame = false; + + #if defined( VPROF_ENABLED ) +// if ( pProfile ) +// pProfile->MarkFrame( "UI CEF HTML Thread" ); + #endif + // Limit animation frame rate + timer.SetLimit( k_nMillion/m_nTargetFrameRate ); + + // run any pending commands, get ack'd paint buffers + { + VPROF_BUDGET( "CCEFThread - RunCurrentCommands()", VPROF_BUDGETGROUP_VGUI ); + RunCurrentCommands(); + } + + // now let cef think + if ( !m_bExit && ( m_listClientHandlers.Count() || timerLastCefThink.BLimitReached() ) && m_nTargetFrameRate > 0 ) + { + VPROF_BUDGET( "CCEFThread - CefDoMessageLoopWork()", VPROF_BUDGETGROUP_TENFOOT ); + CefDoMessageLoopWork(); + timerLastCefThink.SetLimit( k_nMillion ); // 1Hz min think time + } + #ifdef OSX + ReleaseAutoReleasePool( pool ); + #endif + + // push any changes to scrollbar data and refresh HTML element hover states + { + VPROF_BUDGET( "CCEFThread - Scroll", VPROF_BUDGETGROUP_VGUI ); + FOR_EACH_LL( m_listClientHandlers, i ) + { + int nBrowser = BROWSER_HANDLE_FROM_INDEX_SERIAL( i, m_listClientHandlers[i]->NSerial() ); + ThreadBrowserHorizontalScrollBarSizeHelper( nBrowser, false ); + ThreadBrowserVerticalScrollBarSizeHelper( nBrowser, false ); + + // workaround a CEF issue where mouse hover states don't update after scrolling + m_listClientHandlers[i]->RefreshCEFHoverStatesAfterScroll(); + } + } + + { + VPROF_BUDGET( "CCEFThread - SendSizeChangeEvents", VPROF_BUDGETGROUP_VGUI ); + SendSizeChangeEvents(); + } + + //see if we need a paint + { + VPROF_BUDGET( "CCEFThread - Paint", VPROF_BUDGETGROUP_VGUI ); + FOR_EACH_LL( m_listClientHandlers, i ) + { + if ( !m_listClientHandlers[i]->GetBrowser() ) + continue; + + m_listClientHandlers[i]->Paint(); + if ( m_listClientHandlers[i]->BPaintBufferReady() && m_listClientHandlers[i]->BNeedsPaint() ) + { + uint32 textureID = m_listClientHandlers[i]->FlipTexture(); + const byte *pRGBA = m_listClientHandlers[i]->PComposedTextureData( textureID ); + if ( pRGBA ) + { + CClientHandler *pHandler = m_listClientHandlers[i]; + pHandler->Lock(); + if ( pHandler->BPendingScreenShot() ) + { + pHandler->SavePageToJPEGIfNeeded( pHandler->GetBrowser(), pRGBA, pHandler->GetTextureWide(), pHandler->GetTextureTall() ); + } + CHTMLProtoBufMsg cmd( eHTMLCommands_NeedsPaint ); + cmd.Body().set_browser_handle( BROWSER_HANDLE_FROM_INDEX_SERIAL( i, pHandler->NSerial() ) ); + cmd.Body().set_wide( pHandler->GetTextureWide() ); + cmd.Body().set_tall( pHandler->GetTextureTall() ); + cmd.Body().set_rgba( (uint64)pRGBA ); + cmd.Body().set_pageserial( pHandler->GetPageSerial() ); + cmd.Body().set_textureid( textureID ); + cmd.Body().set_updatex( pHandler->GetUpdateX() ); + cmd.Body().set_updatey( pHandler->GetUpdateY() ); + cmd.Body().set_updatewide( pHandler->GetUpdateWide() ); + cmd.Body().set_updatetall( pHandler->GetUpdateTall() ); + cmd.Body().set_scrollx( pHandler->GetBrowser()->HorizontalScroll() ); + cmd.Body().set_scrolly( pHandler->GetBrowser()->VerticalScroll() ); + + if ( pHandler->BPopupVisibleAndPainted() ) // add in the combo box's texture data if visible + { + int x,y,wide,tall; // popup sizes + pHandler->PopupRect( x, y, wide, tall ); + cmd.Body().set_combobox_rgba( (uint64)pHandler->PPopupTextureDataCached() ); + cmd.Body().set_combobox_wide( wide ); + cmd.Body().set_combobox_tall( tall ); + } + + // Texture update rect has now been pushed to main thread + pHandler->ClearUpdateRect(); + + HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_NeedsPaint, i ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + pHandler->Unlock(); + + g_CEFThread.PushResponse( pBuf ); + } + else + { + m_listClientHandlers[i]->SetTextureUploaded( textureID ); + } + } + } + } + +#ifdef WIN32 + if ( m_bSawUserInputThisFrame ) + { + if ( timerLastFlashFullscreenThink.CMicroSecLeft() > k_nMillion/10 || timerLastFlashFullscreenThink.BLimitReached() ) + { + timerLastFlashFullscreenThink.SetLimit( k_nMillion/10 ); // check in 100msec + } + bInitialThinkAfterInput = true; + } + + if ( m_listClientHandlers.Count() && timerLastFlashFullscreenThink.BLimitReached() ) + { + CheckForFullScreenFlashControl(); + if ( ( !m_bFullScreenFlashVisible && bInitialThinkAfterInput ) || m_bFullScreenFlashVisible ) + { + timerLastFlashFullscreenThink.SetLimit( k_nMillion ); // could be a slow machine, check again in 1 sec + } + else + { + timerLastFlashFullscreenThink.SetLimit( k_nMillion * k_nMillion ); // think again in the distance future + } + + bInitialThinkAfterInput= false; + } +#endif + + { + VPROF_BUDGET( "Sleep - FPS Limiting", VPROF_BUDGETGROUP_TENFOOT ); + if ( timer.BLimitReached() ) + ThreadSleep( 1 ); + else + m_WakeEvent.Wait( timer.CMicroSecLeft() / 1000 ); + } + } + + FOR_EACH_LL( m_listClientHandlers, i ) + { + if ( m_listClientHandlers[i] ) + m_listClientHandlers[i]->CloseBrowser(); + m_listClientHandlers[i] = NULL;; + } + m_listClientHandlers.RemoveAll(); + + CefDoMessageLoopWork(); // pump the message loop to clear the close browser calls from above + + CefShutdown(); + } + m_eventDidExit.Set(); + return 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: special code to sniff for flash doing its usual naughty things +//----------------------------------------------------------------------------- +void CCEFThread::CheckForFullScreenFlashControl() +{ +#ifdef WIN32 + VPROF_BUDGET( "Searching for Flash fullscreen - FindWindowEx", VPROF_BUDGETGROUP_TENFOOT ); + + // see if we need to drag the flash fullscreen window to front + HWND flashfullscreenHWND = ::FindWindowEx( NULL, NULL, "ShockwaveFlashFullScreen", NULL ); + if ( flashfullscreenHWND ) + { + DWORD proccess_id; + GetWindowThreadProcessId( flashfullscreenHWND, &proccess_id); + TCHAR exe_path[MAX_PATH]; + GetModuleFileName( GetModuleHandle(NULL), exe_path, MAX_PATH); + HANDLE hmodule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proccess_id); + MODULEENTRY32 mod = { sizeof(MODULEENTRY32) }; + if ( Module32First( hmodule, &mod) ) + { + if ( Q_stricmp(mod.szExePath, exe_path) == 0 ) + { + if ( !m_bFullScreenFlashVisible ) + { + m_bFullScreenFlashVisible = true; + m_flashfullscreenHWND = flashfullscreenHWND; + + FOR_EACH_LL( m_listClientHandlers, i ) + { + if ( m_listClientHandlers[i] ) + m_listClientHandlers[i]->GetRenderHandler()->OnEnterFullScreen( m_listClientHandlers[i]->GetBrowser() ); + } + + SetForegroundWindow( m_flashfullscreenHWND ); + } + } + else + { + if ( m_bFullScreenFlashVisible ) + { + m_bFullScreenFlashVisible = false; + m_flashfullscreenHWND = NULL; + FOR_EACH_LL( m_listClientHandlers, i ) + { + if ( m_listClientHandlers[i] ) + m_listClientHandlers[i]->GetRenderHandler()->OnExitFullScreen( m_listClientHandlers[i]->GetBrowser() ); + } + } + } + } + CloseHandle( hmodule ); + } + else + { + if ( m_bFullScreenFlashVisible ) + { + m_bFullScreenFlashVisible = false; + m_flashfullscreenHWND = NULL; + FOR_EACH_LL( m_listClientHandlers, i ) + { + if ( m_listClientHandlers[i] ) + m_listClientHandlers[i]->GetRenderHandler()->OnExitFullScreen( m_listClientHandlers[i]->GetBrowser() ); + } + } + } +#else +#warning "Do we need to sniff for fullscreen flash and it breaking us?" +#endif +} + + +#ifdef DBGFLAG_VALIDATE +//----------------------------------------------------------------------------- +// Purpose: validate mem +//----------------------------------------------------------------------------- +void CCEFThread::Validate( CValidator &validator, const tchar *pchName ) +{ + // hacky but reliable way to avoid both vgui and panorama validating all this stuff twice + if ( !validator.IsClaimed( m_sHTMLCacheDir.Access() ) ) + { + VALIDATE_SCOPE(); + ValidateObj( m_sHTMLCacheDir ); + ValidateObj( m_sCookiePath ); + ValidateObj( m_listClientHandlers ); + FOR_EACH_LL( m_listClientHandlers, i ) + { + ValidatePtr( m_listClientHandlers[i] ); + } + ValidateObj( m_vecQueueCommands ); + FOR_EACH_VEC( m_vecQueueCommands, i ) + { + ValidatePtr( m_vecQueueCommands[i] ); + } + ValidateObj( m_vecQueueResponses ); + FOR_EACH_VEC( m_vecQueueResponses, i ) + { + ValidatePtr( m_vecQueueResponses[i] ); + } + + ValidateObj( m_tslUnsedBuffers ); + { + CTSList::Node_t *pNode = m_tslUnsedBuffers.Detach(); + while ( pNode ) + { + CTSList::Node_t *pNext = (CTSList::Node_t *)pNode->Next; + ValidatePtr( pNode->elem ); + m_tslUnsedBuffers.Push( pNode ); + pNode = pNext; + } + } + + ValidateObj( m_tslCommandBuffers ); + ValidateObj( m_tslResponseBuffers ); +} +} +#endif + + +//----------------------------------------------------------------------------- +// Purpose: turn on CEF and its supporting thread +//----------------------------------------------------------------------------- +void ChromeInit( const char *pchHTMLCacheDir, const char *pchCookiePath ) +{ + Assert( !g_CEFThread.IsAlive() ); + g_CEFThread.SetCEFPaths( pchHTMLCacheDir, pchCookiePath ); + g_CEFThread.SetName( "UICEFThread" ); + g_CEFThread.Start(); +} + + +//----------------------------------------------------------------------------- +// Purpose: turn off CEF +//----------------------------------------------------------------------------- +void ChromeShutdown() +{ + g_CEFThread.TriggerShutdown(); + g_CEFThread.Join( 20 *k_nThousand ); +} + + +#ifdef DBGFLAG_VALIDATE +//----------------------------------------------------------------------------- +// Purpose: suspend the cef thread so we can validate mem +//----------------------------------------------------------------------------- +bool ChromePrepareForValidate() +{ + g_CEFThread.SleepForValidate(); + while ( !g_CEFThread.BSleepingForValidate() ) + ThreadSleep( 100 ); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: wake the cef thread back up +//----------------------------------------------------------------------------- +bool ChromeResumeFromValidate() +{ + g_CEFThread.WakeFromValidate(); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void ChromeValidate( CValidator &validator, const char *pchName ) +{ + g_CEFThread.Validate( validator, "g_CEFThread" ); +} +#endif + + +//----------------------------------------------------------------------------- +// Purpose: set this cookie to be used by cef +//----------------------------------------------------------------------------- +bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath, RTime32 nExpires ) +{ + CHTMLProtoBufMsg< CMsgSetCookie > cmd( eHTMLCommands_SetCookie ); + cmd.Body().set_value( pchValue ); + cmd.Body().set_key( pchName ); + cmd.Body().set_path( pchPath ); + cmd.Body().set_host( pchHostname ); + if ( nExpires ) + cmd.Body().set_expires( nExpires ); + + HTMLCommandBuffer_t *pBuf = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_SetCookie, -1 ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + g_CEFThread.PushCommand( pBuf ); + g_CEFThread.WakeThread(); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: set this cookie to be used by cef +//----------------------------------------------------------------------------- +bool ChromeGetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) +{ + pstrValue->Clear(); + + { + CHTMLProtoBufMsg cmd( eHTMLCommands_GetCookiesForURL ); + cmd.Body().set_url( pchURL ); + + HTMLCommandBuffer_t *pCmd = g_CEFThread.GetFreeCommandBuffer( eHTMLCommands_GetCookiesForURL, -1 ); + cmd.SerializeCrossProc( &pCmd->m_Buffer ); + g_CEFThread.PushCommand( pCmd ); + } + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForResponse( eHTMLCommands_GetCookiesForURLResponse, -1 ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgGetCookiesForURLResponse > cmdResponse( eHTMLCommands_GetCookiesForURLResponse ); + if ( cmdResponse.BDeserializeCrossProc( &pBuf->m_Buffer ) ) + { + for ( int i = 0; i < cmdResponse.BodyConst().cookies_size(); i++ ) + { + const CCookie &cookie = cmdResponse.BodyConst().cookies(i); + if ( cookie.name() == pchName ) + pstrValue->Set( cookie.value().c_str() ); + } + } + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: set the build number to report in our user agent +//----------------------------------------------------------------------------- +void ChromeSetClientBuildID( uint64 ulBuildID ) +{ + sm_ulBuildID = ulBuildID; +} + + +//----------------------------------------------------------------------------- +// Purpose: constructor +//----------------------------------------------------------------------------- +CChromePainter::CChromePainter( CClientHandler *pParent ) +{ + m_iNextTexture = 0; + m_iTexturesInFlightBits = 0; + m_pParent = pParent; + m_bUpdated = false; + m_bPopupVisible = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: destructor +//----------------------------------------------------------------------------- +CChromePainter::~CChromePainter() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: cef is calling us back and saying it updated the html texture +//----------------------------------------------------------------------------- +void CChromePainter::OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer) +{ + VPROF_BUDGET( "CChromePainter::DrawSubTextureRGBA", VPROF_BUDGETGROUP_VGUI ); + + int wide, tall; + browser->GetSize( type, wide, tall ); + + if ( wide <= 0 || tall <= 0 ) + return; + + if ( type == PET_POPUP ) + { + m_nPopupWide = wide; + m_nPopupTall = tall; + + m_PopupTexture.EnsureCount( tall*wide*4 ); + Q_memcpy( m_PopupTexture.Base(), buffer, tall*wide*4 ); + + // force a recomposition + display whenever painting a popup + m_bUpdated = true; + } + else + { + // main browser painting + + if ( !m_pParent->IsVisuallyNonEmpty() ) + { + return; + } + + // If there were no dirty regions (unlikely), perhaps due to a bug, be conservative and paint all + if ( dirtyRects.empty() ) + { + m_MainTexture.MarkAllDirty(); + } + else + { + for ( RectList::const_iterator iter = dirtyRects.begin(); iter != dirtyRects.end(); ++iter ) + { + m_MainTexture.MarkDirtyRect( iter->x, iter->y, iter->x + iter->width, iter->y + iter->height ); + } + } + + // Refresh all dirty main texture pixels from the chromium rendering buffer + if ( m_MainTexture.BUpdatePixels( (byte*)buffer, wide, tall ) ) + { + // at least one pixel in the main texture has changed + m_bUpdated = true; + + // Notify the main thread that this newly painted region is dirty + m_UpdateRect.MarkDirtyRect( m_MainTexture ); + + // Merge update region into all buffer textures so that at composition time, + // they know to copy the union of all updates since the last composition + for ( size_t i = 0; i < Q_ARRAYSIZE(m_Texture); ++i ) + { + m_Texture[i].MarkDirtyRect( m_MainTexture ); + } + } + + // The main texture is now a clean copy of chromium's canvas backing + m_MainTexture.MarkAllClean(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: true if we have had a paint call from cef +//----------------------------------------------------------------------------- +bool CChromePainter::BUpdated() +{ + return m_bUpdated; +} + + +//----------------------------------------------------------------------------- +// Purpose: force the updated state +//----------------------------------------------------------------------------- +void CChromePainter::SetUpdated( bool state ) +{ + m_bUpdated = state; +} + + +//----------------------------------------------------------------------------- +// Purpose: move to the next html texture to render into +//----------------------------------------------------------------------------- +uint32 CChromePainter::FlipTexture() +{ + int iTex = m_iNextTexture; + m_iTexturesInFlightBits |= ( 1< 0 && m_MainTexture.GetTall() > 0) && !( m_iTexturesInFlightBits & (1< parentBrowser, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + bool bForeground, + CefRefPtr& client, + CefBrowserSettings& settings ) +{ + CHTMLProtoBufMsg cmd( eHTMLCommands_OpenNewTab ); + cmd.Body().set_url( url.c_str() ); + cmd.Body().set_bforeground( bForeground ); + + DISPATCH_MESSAGE( eHTMLCommands_OpenNewTab ); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Called before a new popup window is created. The |parentBrowser| parameter +// will point to the parent browser window. The |popupFeatures| parameter will +// contain information about the style of popup window requested. Return false +// to have the framework create the new popup window based on the parameters +// in |windowInfo|. Return true to cancel creation of the popup window. By +// default, a newly created popup window will have the same client and +// settings as the parent window. To change the client for the new window +// modify the object that |client| points to. To change the settings for the +// new window modify the |settings| structure. +//----------------------------------------------------------------------------- +bool CClientHandler::OnBeforePopup(CefRefPtr parentBrowser, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + CefRefPtr& client, + CefBrowserSettings& settings) +{ + // If it's a steam:// url we already have a scheme handler installed, however that's too late to block the frame navigating + // and we'll end up loading a blank new window. So preempt that happening here and handle early returning that we've handled so + // chromium won't actually change URLs or navigate at all. + if ( url.size() > 0 && ( Q_stristr( url.c_str(), "steam://" ) || Q_stristr( url.c_str(), "steambeta://" ) ) && Q_stristr( url.c_str(), "/close" ) == NULL ) + { + CStrAutoEncode urlString( url.c_str() ); + CHTMLProtoBufMsg cmd( eHTMLCommands_OpenSteamURL ); + cmd.Body().set_url( urlString.ToString() ); + DISPATCH_MESSAGE( eHTMLCommands_OpenSteamURL ); + + return true; + } + + CStrAutoEncode urlString( url.c_str() ); + static bool bInPopup = false; + // if we get an empty url string when loading a new popup page just don't load it, we don't support the make a + // new popup and .write() into the buffer to make the contents because we want to make a whole new VGUI HTML object + // that contains the webkit widget for that popup, not allow this inline one + if ( urlString.ToString() && Q_strlen( urlString.ToString() ) > 0 ) + { + if ( !bInPopup ) + { + bInPopup = true; + CHTMLProtoBufMsg cmd( eHTMLCommands_PopupHTMLWindow ); + cmd.Body().set_url( urlString.ToString() ); + if ( popupFeatures.xSet ) + cmd.Body().set_x( popupFeatures.x ); + if ( popupFeatures.ySet ) + cmd.Body().set_y( popupFeatures.y ); + if ( popupFeatures.widthSet ) + cmd.Body().set_wide( popupFeatures.width ); + if ( popupFeatures.heightSet ) + cmd.Body().set_tall( popupFeatures.height ); + + DISPATCH_MESSAGE( eHTMLCommands_PopupHTMLWindow ); + bInPopup = false; + return true; + } + } + if ( !bInPopup ) + { + return true; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called after a new window is created. The return value is currently +// ignored. +//----------------------------------------------------------------------------- +void CClientHandler::OnAfterCreated(CefRefPtr browser) +{ + Lock(); + if ( !m_Browser ) + { + // We need to keep the main child window, but not popup windows + m_Browser = browser; + browser->SetShowScrollBars( false ); + SetBrowserAgent( browser ); + if ( m_nExpectedWide > 0 && m_nExpectedTall > 0 ) + browser->SetSize( PET_VIEW, m_nExpectedWide, m_nExpectedTall ); + + CHTMLProtoBufMsg cmd( eHTMLCommands_BrowserReady ); + DISPATCH_MESSAGE( eHTMLCommands_BrowserReady ); + } + Unlock(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called when the page title changes. The return value is currently +// ignored. +//----------------------------------------------------------------------------- +void CClientHandler::OnTitleChange(CefRefPtr browser, const CefString& title) +{ + if ( !title.empty() ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_SetHTMLTitle ); + cmd.Body().set_title( title ); + + DISPATCH_MESSAGE( eHTMLCommands_SetHTMLTitle ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called before browser navigation. The client has an opportunity to +// modify the |request| object if desired. Return RV_HANDLED to cancel +// navigation. +//----------------------------------------------------------------------------- +bool CClientHandler::OnBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + NavType navType, + bool isRedirect, + bool isNewTabRequest + ) +{ + std::string sURL = request->GetURL(); + + // If it's a steam:// url we already have a scheme handler installed, however that's too late to block the frame navigating + // and we'll end up loading a blank page. So preempt that happening here and handle early returning that we've handled so + // chromium won't actually change URLs or navigate at all. + if ( sURL.size() > 0 && (sURL.find( "steam://" ) == 0 || sURL.find( "steambeta://" ) == 0) && sURL.find( "/close" ) == std::wstring::npos ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_OpenSteamURL ); + cmd.Body().set_url( CStrAutoEncode( request->GetURL().c_str() ).ToString() ); + DISPATCH_MESSAGE( eHTMLCommands_OpenSteamURL ); + + return true ; + } + + if ( isNewTabRequest ) + return false; + + // We only care about these on the main frame + if( !frame.get() || !frame->IsMain() ) + return false; + + if ( request->GetPostData() ) + { + CefPostData::ElementVector elements; + request->GetPostData()->GetElements( elements ); + CefPostData::ElementVector::const_iterator it = elements.begin(); + m_strPostData = ""; + CUtlVector vecPostBytes; + while ( it != elements.end() ) + { + if ( it->get()->GetType() == PDE_TYPE_BYTES ) + { + size_t nBytes = it->get()->GetBytesCount(); + int curInsertPos = vecPostBytes.Count(); + vecPostBytes.EnsureCount( curInsertPos + nBytes + 1 ); + it->get()->GetBytes( nBytes, vecPostBytes.Base() + curInsertPos ); + vecPostBytes[ curInsertPos + nBytes ] = 0; + } + it++; + } + + m_strPostData = vecPostBytes.Base(); + } + else + m_strPostData = ""; + + CStrAutoEncode strURL( sURL.c_str() ); + + if ( isRedirect ) + m_strLastRedirectURL = strURL.ToString(); + + bool rv = false; + + { + // scope this so the wait below doesn't keep this allocation on the stack + CHTMLProtoBufMsg cmd( eHTMLCommands_StartRequest ); + cmd.Body().set_url( strURL.ToString() ); + CefString frameName = frame->GetName(); + if ( !frameName.empty() ) + cmd.Body().set_target( frameName.c_str() ); + cmd.Body().set_postdata( m_strPostData ); + cmd.Body().set_bisredirect( isRedirect ); + + DISPATCH_MESSAGE( eHTMLCommands_StartRequest ); + } + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_StartRequestResponse, m_iBrowser ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgStartRequestResponse > cmd( eHTMLCommands_StartRequestResponse ); + if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) + { + if ( !cmd.BodyConst().ballow() ) + rv = true ; + } + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + + if ( m_Snapshot.m_sURLSnapshot.IsValid() ) + m_Snapshot.m_flRequestTimeout = Plat_FloatTime(); // before we change URL lets queue up a snapshot for the next paint + + return rv; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called when the browser begins loading a page. The |frame| pointer +// will be empty if the event represents the overall load status and not the +// load status for a particular frame. The return value is currently ignored. +//----------------------------------------------------------------------------- +void CClientHandler::OnLoadStart(CefRefPtr browser, + CefRefPtr frame, bool bIsNewNavigation ) +{ + if ( !frame.get() ) + return; + + { + if ( !frame->IsMain() ) + return; + + std::wstring sURL = frame->GetURL(); + if ( sURL.empty() ) + return; + + CStrAutoEncode url( sURL.c_str() ); + m_strCurrentUrl = url.ToString(); + + if ( m_strCurrentUrl.IsEmpty() ) + return; + + bool bIsRedirect = false; + if ( m_strCurrentUrl == m_strLastRedirectURL ) + bIsRedirect = true; + + CHTMLProtoBufMsg cmd( eHTMLCommands_URLChanged ); + cmd.Body().set_url( url.ToString() ); + cmd.Body().set_bnewnavigation( bIsNewNavigation ); + + if ( !m_strPostData.IsEmpty() ) + cmd.Body().set_postdata( m_strPostData.String() ); + + cmd.Body().set_bisredirect( bIsRedirect ); + CefString frameName = frame->GetName(); + if ( !frameName.empty() ) + cmd.Body().set_pagetitle( frameName.c_str() ); + + DISPATCH_MESSAGE( eHTMLCommands_URLChanged ); +} + + { + CHTMLProtoBufMsg cmd( eHTMLCommands_CanGoBackandForward ); + cmd.Body().set_bgoback( browser->CanGoBack() ); + cmd.Body().set_bgoforward( browser->CanGoForward() ); + DISPATCH_MESSAGE( eHTMLCommands_CanGoBackandForward ); + } + + m_nPageSerial = m_nPendingPageSerial; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called when the browser is done loading a page. The |frame| pointer +// will be empty if the event represents the overall load status and not the +// load status for a particular frame. This event will be generated +// irrespective of whether the request completes successfully. The return +// value is currently ignored. +//----------------------------------------------------------------------------- +void CClientHandler::OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode, CefRefPtr request ) +{ + // We only care about these on the main frame + if( !frame.get() || !frame->IsMain() ) + return; + + { + CHTMLProtoBufMsg cmd( eHTMLCommands_FinishedRequest ); + + if ( browser->GetMainFrame()->GetURL().size() > 0 ) + cmd.Body().set_url( CStrAutoEncode( browser->GetMainFrame()->GetURL().c_str() ).ToString() ); + else + cmd.Body().set_url( "" ); + + CefString frameName = browser->GetMainFrame()->GetName(); + if ( !frameName.empty() ) + cmd.Body().set_pagetitle( frameName.c_str() ); + + if ( request.get() ) + { + CefRequest::HeaderMap headerMap; + request->GetHeaderMap( headerMap ); + + CefRequest::HeaderMap::const_iterator it; + for(it = headerMap.begin(); it != headerMap.end(); ++it) + { + CHTMLHeader *pHeader = cmd.Body().add_headers(); + if ( !it->first.empty() ) + pHeader->set_key( it->first.c_str() ); + if ( !it->second.empty() ) + pHeader->set_value( it->second.c_str() ); + } + + CefRefPtr pRefSecurityDetails = request->SecurityDetails(); + CHTMLPageSecurityInfo *pSecurityInfo = cmd.Body().mutable_security_info(); + if ( pRefSecurityDetails.get() ) + { + pSecurityInfo->set_bissecure( pRefSecurityDetails->BIsSecure() ); + pSecurityInfo->set_bhascerterror( pRefSecurityDetails->BHasCertError() ); + pSecurityInfo->set_issuername( pRefSecurityDetails->PchCertIssuer() ); + pSecurityInfo->set_certname( pRefSecurityDetails->PchCertCommonName() ); + pSecurityInfo->set_certexpiry( pRefSecurityDetails->TCertExpiry() ); + pSecurityInfo->set_bisevcert( pRefSecurityDetails->BIsEVCert() ); + pSecurityInfo->set_ncertbits( pRefSecurityDetails->NCertBits() ); + } + else + { + pSecurityInfo->set_bissecure( false ); + } + } + + DISPATCH_MESSAGE( eHTMLCommands_FinishedRequest ); + } + + { + CHTMLProtoBufMsg cmd( eHTMLCommands_CanGoBackandForward ); + cmd.Body().set_bgoback( browser->CanGoBack() ); + cmd.Body().set_bgoforward( browser->CanGoForward() ); + DISPATCH_MESSAGE( eHTMLCommands_CanGoBackandForward ); + } + + if ( m_Snapshot.m_sURLSnapshot.IsValid() ) + m_Snapshot.m_flRequestTimeout = Plat_FloatTime(); // finished page load, lets queue up a snapshot for the next paint +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Called when the browser fails to load a resource. |errorCode| is the +// error code number and |failedUrl| is the URL that failed to load. To +// provide custom error text assign the text to |errorText| and return +// RV_HANDLED. Otherwise, return RV_CONTINUE for the default error text. +//----------------------------------------------------------------------------- +bool CClientHandler::OnLoadError(CefRefPtr browser, + CefRefPtr frame, + ErrorCode errorCode, + const CefString& failedUrl, + CefString& errorText) +{ + // If it's a steam:// url we always get an error, but we handle it ok internally already, just ignore + if ( failedUrl.size() > 0 && ( Q_stristr( failedUrl.c_str(), "steam://" ) || Q_stristr( failedUrl.c_str(), "steambeta://" ) ) ) + return false; + + const char *pchDetail = NULL; + switch ( errorCode ) + { + case ERR_ABORTED: + // We'll get this in cases where we just start another URL before finishing a previous and such, don't show it. + return false; + break; + case ERR_CACHE_MISS: + pchDetail = m_sErrorCacheMiss; + break; + case ERR_UNKNOWN_URL_SCHEME: + case ERR_INVALID_URL: + pchDetail = m_sErrorBadURL; + break; + case ERR_CONNECTION_CLOSED: + case ERR_CONNECTION_RESET: + case ERR_CONNECTION_REFUSED: + case ERR_CONNECTION_ABORTED: + case ERR_CONNECTION_FAILED: + case ERR_NAME_NOT_RESOLVED: + case ERR_INTERNET_DISCONNECTED: + case ERR_CONNECTION_TIMED_OUT: + pchDetail = m_sErrorConnectionProblem; + break; + case ERR_UNEXPECTED_PROXY_AUTH: + case ERR_EMPTY_PROXY_LIST: + pchDetail = m_sErrorProxyProblem; + break; + default: + pchDetail = m_sErrorUnknown; + break; + } + + char rgchError[4096]; + Q_snprintf( rgchError, Q_ARRAYSIZE( rgchError ), + "" + "" + "%s" + "" + "" + "

%s%d

" + "

" + "%s" + "

" + "" + "", + m_sErrorTitle.String(), + m_sErrorHeader.String(), + errorCode, + pchDetail ); + + errorText = rgchError; + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Event called before a resource is loaded. To allow the resource to load +// normally return RV_CONTINUE. To redirect the resource to a new url +// populate the |redirectUrl| value and return RV_CONTINUE. To specify +// data for the resource return a CefStream object in |resourceStream|, set +// 'mimeType| to the resource stream's mime type, and return RV_CONTINUE. +// To cancel loading of the resource return RV_HANDLED. +//----------------------------------------------------------------------------- +bool CClientHandler::OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr request, + CefString& redirectUrl, + CefRefPtr& resourceStream, + CefRefPtr response, + int loadFlags) +{ + if ( request->GetURL().size() == 0 ) + return false; + + CHTMLProtoBufMsg cmd( eHTMLCommands_LoadingResource ); + cmd.Body().set_url( CStrAutoEncode( request->GetURL().c_str() ).ToString() ); + DISPATCH_MESSAGE( eHTMLCommands_LoadingResource ); + + // insert custom headers + CefRequest::HeaderMap headerMap; + request->GetHeaderMap( headerMap ); + FOR_EACH_VEC( m_vecHeaders, i ) + { + headerMap.insert( m_vecHeaders[i] ); + } + + request->SetHeaderMap( headerMap ); + + return false; +} + + + +//----------------------------------------------------------------------------- +// Purpose: +// Run a JS alert message. Return RV_CONTINUE to display the default alert +// or RV_HANDLED if you displayed a custom alert. +//----------------------------------------------------------------------------- +bool CClientHandler::OnJSAlert(CefRefPtr browser, + CefRefPtr frame, + const CefString& message) +{ + { + // scope this so the wait below doesn't keep this allocation on the stack + CHTMLProtoBufMsg cmd( eHTMLCommands_JSAlert ); + cmd.Body().set_message( message.c_str() ); + DISPATCH_MESSAGE( eHTMLCommands_JSAlert ); + } + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_JSDialogResponse, m_iBrowser ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgJSDialogResponse > cmd( eHTMLCommands_JSDialogResponse ); + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Run a JS confirm request. Return RV_CONTINUE to display the default alert +// or RV_HANDLED if you displayed a custom alert. If you handled the alert +// set |CefHandler::RetVal| to true if the user accepted the confirmation. +//----------------------------------------------------------------------------- +bool CClientHandler::OnJSConfirm(CefRefPtr browser, + CefRefPtr frame, + const CefString& message, + bool& retval) +{ + { + // scope this so the wait below doesn't keep this allocation on the stack + CHTMLProtoBufMsg cmd( eHTMLCommands_JSConfirm ); + cmd.Body().set_message( message.c_str() ); + DISPATCH_MESSAGE( eHTMLCommands_JSConfirm ); + } + + retval = false; + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_JSDialogResponse, m_iBrowser ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgJSDialogResponse > cmd( eHTMLCommands_JSDialogResponse ); + if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) + { + if ( cmd.BodyConst().result() ) + retval = true ; + } + + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Run a JS prompt request. Return RV_CONTINUE to display the default prompt +// or RV_HANDLED if you displayed a custom prompt. If you handled the prompt +// set |CefHandler::RetVal| to true if the user accepted the prompt and request and +// |result| to the resulting value. +//----------------------------------------------------------------------------- +bool CClientHandler::OnJSPrompt(CefRefPtr browser, + CefRefPtr frame, + const CefString& message, + const CefString& defaultValue, + bool& retval, + CefString& result) +{ + retval = false; // just don't pop JS prompts for now + result = defaultValue; + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Called just before a window is closed. +//----------------------------------------------------------------------------- +void CClientHandler::OnBeforeClose(CefRefPtr browser) +{ + Lock(); + if ( m_Browser ) + { + // Free the browser pointer so that the browser can be destroyed + m_Browser = NULL; + + if ( !m_bBrowserClosing ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_Close ); + DISPATCH_MESSAGE( eHTMLCommands_Close ); + } + } + Unlock(); +} + + +//----------------------------------------------------------------------------- +// Purpose: show a html popup, a pulldown menu or the like +//----------------------------------------------------------------------------- +void CChromePainter::OnPopupShow(CefRefPtr browser, bool show) +{ + m_bPopupVisible = show; + int m_iBrowser = m_pParent->m_iBrowser; + if ( show ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_ShowPopup ); + DISPATCH_MESSAGE( eHTMLCommands_ShowPopup ); + } + else + { + CHTMLProtoBufMsg cmd( eHTMLCommands_HidePopup ); + DISPATCH_MESSAGE( eHTMLCommands_HidePopup ); + + // redraw the buffered texture behind the rectangle that was previously composited + for ( size_t i = 0; i < Q_ARRAYSIZE( m_Texture ); ++i ) + { + m_Texture[i].MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); + } + + // and notify the main thread to redraw the previously composited area as well + m_UpdateRect.MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: make the popup this big +//----------------------------------------------------------------------------- +void CChromePainter::OnPopupSize(CefRefPtr browser, const CefRect& rect ) +{ + if ( m_bPopupVisible ) + { + // redraw the buffered texture behind the rectangle that was previously composited + for ( size_t i = 0; i < Q_ARRAYSIZE( m_Texture ); ++i ) + { + m_Texture[i].MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); + } + + // and notify the main thread to redraw the previously composited area as well + m_UpdateRect.MarkDirtyRect( m_nPopupX, m_nPopupY, m_nPopupX + m_nPopupWide, m_nPopupY + m_nPopupTall ); + } + + m_bPopupVisible = true; + m_nPopupX = rect.x; + m_nPopupWide = rect.width; + m_nPopupY = rect.y; + m_nPopupTall = rect.height; + + int m_iBrowser = m_pParent->m_iBrowser; + CHTMLProtoBufMsg cmd( eHTMLCommands_SizePopup ); + cmd.Body().set_x( m_nPopupX ); + cmd.Body().set_y( m_nPopupY ); + cmd.Body().set_wide( m_nPopupWide ); + cmd.Body().set_tall( m_nPopupTall ); + DISPATCH_MESSAGE( eHTMLCommands_SizePopup ); +} + + +//----------------------------------------------------------------------------- +// Purpose: cef has status text for us +//----------------------------------------------------------------------------- +void CClientHandler::OnStatusMessage(CefRefPtr browser, const CefString& value, StatusType type) +{ + if ( !value.empty() ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_StatusText ); + cmd.Body().set_text( value.c_str() ); + DISPATCH_MESSAGE( eHTMLCommands_StatusText ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: show tooltip please +//----------------------------------------------------------------------------- +bool CClientHandler::OnTooltip(CefRefPtr browser, CefString& text) +{ + if ( !m_bShowingToolTip && !text.empty() ) + { + m_bShowingToolTip = true; + m_strToolTip = text.c_str(); + + CHTMLProtoBufMsg cmd( eHTMLCommands_ShowToolTip ); + cmd.Body().set_text( m_strToolTip ); + DISPATCH_MESSAGE( eHTMLCommands_ShowToolTip ); + } + else if ( m_bShowingToolTip && !text.empty() ) + { + if ( m_strToolTip != text.c_str() ) + { + m_strToolTip = text.c_str(); + + CHTMLProtoBufMsg cmd( eHTMLCommands_UpdateToolTip ); + cmd.Body().set_text( m_strToolTip ); + DISPATCH_MESSAGE( eHTMLCommands_UpdateToolTip ); + } + } + else if ( m_bShowingToolTip ) + { + CHTMLProtoBufMsg cmd( eHTMLCommands_HideToolTip ); + DISPATCH_MESSAGE( eHTMLCommands_HideToolTip ); + + m_bShowingToolTip = false; + m_strToolTip.Clear(); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: set the mouse cursor to this image +//----------------------------------------------------------------------------- +bool CChromePainter::OnSetCursor( CefRefPtr browser, const CursorType type, const void *pchIconData, int iWide, int iTall, int xHotSpot, int yHotSpot ) +{ + int m_iBrowser = m_pParent->m_iBrowser; + CHTMLProtoBufMsg cmd( eHTMLCommands_SetCursor ); + + EMouseCursor cursor; + switch( type ) + { + case TypeCustom: + cursor = dc_last; + break; + case TypeCross: + cursor = dc_crosshair; + break; + case TypeHand: + cursor = dc_hand; + break; + case TypeIBeam: + cursor = dc_ibeam; + break; + case TypeWait: + cursor = dc_hourglass; + break; + case TypeHelp: + cursor = dc_help; + break; + case TypeEastResize: + cursor = dc_sizee; + break; + case TypeNorthResize: + cursor = dc_sizen; + break; + case TypeNorthEastResize: + cursor = dc_sizene; + break; + case TypeNorthWestResize: + cursor = dc_sizenw; + break; + case TypeSouthResize: + cursor = dc_sizes; + break; + case TypeSouthEastResize: + cursor = dc_sizese; + break; + case TypeSouthWestResize: + cursor = dc_sizesw; + break; + case TypeNorthSouthResize: + cursor = dc_sizes; + break; + case TypeEastWestResize: + cursor = dc_sizew; + break; + case TypeNorthEastSouthWestResize: + cursor = dc_sizeall; + break; + case TypeColumnResize: + cursor = dc_colresize; + break; + case TypeRowResize: + cursor = dc_rowresize; + break; + case TypeMiddlePanning: + cursor = dc_middle_pan; + break; + case TypeEastPanning: + cursor = dc_east_pan; + break; + case TypeNorthPanning: + cursor = dc_north_pan; + break; + case TypeNorthEastPanning: + cursor = dc_north_east_pan; + break; + case TypeNorthWestPanning: + cursor = dc_north_west_pan; + break; + case TypeSouthPanning: + cursor = dc_south_pan; + break; + case TypeSouthEastPanning: + cursor = dc_south_east_pan; + break; + case TypeSouthWestPanning: + cursor = dc_south_west_pan; + break; + case TypeWestPanning: + cursor = dc_west_pan; + break; + case TypeMove: + cursor = dc_sizeall; + break; + case TypeVerticalText: + cursor = dc_verticaltext; + break; + case TypeCell: + cursor = dc_cell; + break; + case TypeContextMenu: + cursor = dc_none; + break; + case TypeAlias: + cursor = dc_alias; + break; + case TypeProgress: + cursor = dc_waitarrow; + break; + case TypeNoDrop: + cursor = dc_no; + break; + case TypeCopy: + cursor = dc_copycur; + break; + case TypeNone: + cursor = dc_none; + break; + case TypeNotAllowed: + cursor = dc_no; + break; + case TypeZoomIn: + cursor = dc_zoomin; + break; + case TypeZoomOut: + cursor = dc_zoomout; + break; + case TypePointer: + default: + cursor = dc_arrow; + } + cmd.Body().set_cursor( cursor ); + cmd.Body().set_data( (uint32)pchIconData ); // we are relying on chrome keeping around the cursor data after this call completes, it does right now. + cmd.Body().set_wide( iWide ); + cmd.Body().set_tall( iTall ); + cmd.Body().set_xhotspot( xHotSpot ); + cmd.Body().set_yhotspot( yHotSpot ); + DISPATCH_MESSAGE( eHTMLCommands_SetCursor ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: file open dialog to be shown +//----------------------------------------------------------------------------- +bool CChromePainter::OnFileOpenDialog( CefRefPtr browser, bool bMultiSelect, const CefString &default_title, const CefString &default_file, CefWebFileChooserCallback *pCallback ) +{ + if ( !pCallback ) + return true; + + int m_iBrowser = m_pParent->m_iBrowser; + { + // scope this so this allocation doesn't stay on the stack during validate + CHTMLProtoBufMsg cmd( eHTMLCommands_FileLoadDialog ); + if ( !default_title.empty() ) + cmd.Body().set_title( default_title ); + if ( !default_file.empty() ) + cmd.Body().set_initialfile( default_file ); + DISPATCH_MESSAGE( eHTMLCommands_FileLoadDialog ); + } + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_FileLoadDialogResponse, m_iBrowser ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgFileLoadDialogResponse > cmd( eHTMLCommands_FileLoadDialogResponse ); + if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) + { + std::vector files; + for ( int i = 0; i < cmd.BodyConst().files_size(); i++ ) + { + if ( !cmd.BodyConst().files(i).empty() ) + { + CPathString path( cmd.BodyConst().files(i).c_str() ); + files.push_back( path.GetWCharPathPrePended() ); + } + } + + // if you have a DEBUG build and are crashing here it is because + // Chrome is a release library and the std::vector iterator isn't crossing + // the interface happyily. Build release and you will run fine. +#if defined(DEBUG) && defined(WIN32) + Assert( !"File select dialog not available in debug due to STL debug/release issues\n" ); +#else + pCallback->OnFileChoose( files ); +#endif + } + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: CEF is asking if it can show itself fullscreen +//----------------------------------------------------------------------------- +bool CChromePainter::OnEnterFullScreen( CefRefPtr browser ) +{ + int m_iBrowser = m_pParent->m_iBrowser; + { + // scope this so this allocation doesn't stay on the stack during validate + CHTMLProtoBufMsg cmd( eHTMLCommands_RequestFullScreen ); + DISPATCH_MESSAGE( eHTMLCommands_RequestFullScreen ); + } + + HTMLCommandBuffer_t *pBuf = g_CEFThread.BWaitForCommand( eHTMLCommands_RequestFullScreenResponse, m_iBrowser ); + if ( pBuf ) + { + CHTMLProtoBufMsg< CMsgRequestFullScreenResponse > cmd( eHTMLCommands_RequestFullScreenResponse ); + if ( cmd.BDeserializeCrossProc( &pBuf->m_Buffer ) ) + { + return cmd.BodyConst().ballow(); + } + g_CEFThread.ReleaseCommandBuffer( pBuf ); + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: cef is spewing to its console, print it +//----------------------------------------------------------------------------- +bool CChromePainter::OnExitFullScreen( CefRefPtr browser ) +{ + int m_iBrowser = m_pParent->m_iBrowser; + { + // scope this so this allocation doesn't stay on the stack during validate + // tell the main thread we are exiting fullscreen + CHTMLProtoBufMsg cmd( eHTMLCommands_ExitFullScreen ); + DISPATCH_MESSAGE( eHTMLCommands_ExitFullScreen ); + } + + // BUGUBG - add a request/response here so you can disallow leaving fullscreen?? + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: cef is spewing to its console, print it +//----------------------------------------------------------------------------- +bool CClientHandler::OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) +{ + // the console is very chatty and doesn't provide useful information for us app developers, just for html/css editors, so lets ignore this for now + //Msg( "Browser Message: %s - %s:%d\n", message.c_str(), source.c_str(), line ); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: helper function to recurvisely search down the DOM for any input nodes and an input button name +//----------------------------------------------------------------------------- +void SearchForInputButtonAndOtherInputs_R( CefRefPtr root, CefRefPtr focusNode, bool &bHasMultipleTextInputNodes, CUtlString &sSearchButtonName, int nMaxRecurse ) +{ + CefRefPtr nodeChildren = root->GetFirstChild(); + while ( nodeChildren.get() ) + { + if ( !nodeChildren->IsSame( focusNode ) && nodeChildren->IsElement() ) + { + CUtlString sElementType = nodeChildren->GetElementTagName().c_str(); + if ( !Q_stricmp( "input", sElementType ) ) + { + CUtlString sChildControlType = nodeChildren->GetFormControlElementType().c_str(); + if ( sSearchButtonName.IsEmpty() && !Q_stricmp( sChildControlType, "submit" ) ) + { + if ( nodeChildren->HasElementAttribute( "value" ) ) + sSearchButtonName = nodeChildren->GetElementAttribute( "value" ).c_str(); + } + else if ( !Q_stricmp( "text", sChildControlType ) || !Q_stricmp( "password", sChildControlType ) || !Q_stricmp( "email", sChildControlType ) ) + { + //CefDOMNode::AttributeMap attrMap; + //nodeChildren->GetElementAttributes( attrMap ); + if ( !nodeChildren->HasElementAttribute( "disabled" ) ) + bHasMultipleTextInputNodes = true; + } + } + else if ( !Q_stricmp( "textarea", sElementType ) ) + { + if ( !nodeChildren->HasElementAttribute( "disabled" ) ) + bHasMultipleTextInputNodes = true; + } + else if ( nMaxRecurse > 0 /*&& !Q_stricmp( "div", sElementType ) || !Q_stricmp( "tr", sElementType ) || !Q_stricmp( "td", sElementType ) || !Q_stricmp( "table", sElementType ) || !Q_stricmp( "tbody", sElementType )*/ ) + { + SearchForInputButtonAndOtherInputs_R( nodeChildren, focusNode, bHasMultipleTextInputNodes, sSearchButtonName, nMaxRecurse - 1 ); + } + } + nodeChildren = nodeChildren->GetNextSibling(); + + if ( bHasMultipleTextInputNodes && sSearchButtonName.IsValid() ) + break; // if we found both multiple nodes and a search button name we can bail early + } +} + + +//----------------------------------------------------------------------------- +// Purpose: a new node in the DOM has focus now +//----------------------------------------------------------------------------- +void CClientHandler::OnFocusedNodeChanged(CefRefPtr browser, CefRefPtr frame, CefRefPtr node) +{ + VPROF_BUDGET( "CCEFThread - CClientHandler::OnFocusedNodeChanged()", VPROF_BUDGETGROUP_VGUI ); + + bool bIsInputNode = false; + CUtlString sElementType; + if ( node.get() ) + sElementType = node->GetElementTagName().c_str(); + + CUtlString sName; + if ( node.get() ) + sName = node->GetName().c_str(); + + CUtlString sSearchButtonName; + CUtlString sControlType; + bool bInputNode = !Q_stricmp( "input", sElementType ); + bool bHasMultipleInputNodes = false; + if ( sElementType.IsValid() && ( bInputNode || !Q_stricmp( "textarea", sElementType ) ) ) + { + sControlType = node->GetFormControlElementType().c_str(); + + // lets go searching for the submit button and grab the text it shows + bIsInputNode = true; + CefRefPtr nodeParent = node->GetParent(); + while( nodeParent.get() ) + { + CUtlString sParentElementType = nodeParent->GetElementTagName().c_str(); + if ( !Q_stricmp( "form", sParentElementType ) ) + break; + nodeParent = nodeParent->GetParent(); + } + + if ( nodeParent.get() ) + SearchForInputButtonAndOtherInputs_R( nodeParent, node, bHasMultipleInputNodes, sSearchButtonName, 32 ); + } + + if ( sElementType.IsValid() && !Q_stricmp( "div", sElementType ) ) + { + if ( node->HasElementAttribute( "contenteditable" ) ) + bIsInputNode = true; + } + + if ( sSearchButtonName.IsEmpty() ) + sSearchButtonName = "#Web_FormSubmit"; + + CHTMLProtoBufMsg cmd( eHTMLCommands_NodeGotFocus ); + cmd.Body().set_binput( bIsInputNode ); + if ( sName.IsValid() ) + cmd.Body().set_name( sName ); + if ( sElementType.IsValid() ) + cmd.Body().set_elementtagname( sElementType ); + if ( sSearchButtonName.IsValid() ) + cmd.Body().set_searchbuttontext( sSearchButtonName ); + cmd.Body().set_bhasmultipleinputs( bHasMultipleInputNodes ); + if ( sControlType.IsValid() ) + cmd.Body().set_input_type( sControlType ); + + DISPATCH_MESSAGE( eHTMLCommands_NodeGotFocus ); +} + + +//----------------------------------------------------------------------------- +// Purpose: a find has found matches on the page, feed back that info +//----------------------------------------------------------------------------- +void CClientHandler::OnFindResult(CefRefPtr browser, + int identifier, + int count, + const CefRect& selectionRect, + int activeMatchOrdinal, + bool finalUpdate) +{ + CHTMLProtoBufMsg cmd( eHTMLCommands_SearchResults ); + cmd.Body().set_activematch( activeMatchOrdinal ); + cmd.Body().set_results( count ); + DISPATCH_MESSAGE( eHTMLCommands_SearchResults ); +} + + +//----------------------------------------------------------------------------- +// Purpose: return a pointer to the CEF browser object +//----------------------------------------------------------------------------- +CefRefPtr CClientHandler::GetBrowser() +{ + return m_Browser; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CClientHandler::CloseBrowser() +{ + if ( m_Browser ) + { + m_bBrowserClosing = true; + m_Browser->CloseBrowser(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CClientHandler::SetMouseLocation( int nMouseX, int nMouseY ) +{ + m_nMouseX = nMouseX; + m_nMouseY = nMouseY; + if ( m_Browser.get() ) + { + m_nMouseScrolledX = nMouseX + m_Browser->VerticalScroll(); + m_nMouseScrolledY = nMouseY + m_Browser->HorizontalScroll(); + m_bMouseFocus = true; + m_Browser->SendMouseMoveEvent( m_nMouseX, m_nMouseY, false ); +} +} + +//----------------------------------------------------------------------------- +// Purpose: check if window has scrolled and generate a fake mouse move event +// to force CEF to check for hover state changes (seems like a CEF bug...) +//----------------------------------------------------------------------------- +void CClientHandler::RefreshCEFHoverStatesAfterScroll() +{ + if ( m_Browser.get() && m_bMouseFocus ) + { + int nScrolledX = m_nMouseX + m_Browser->VerticalScroll(); + int nScrolledY = m_nMouseY + m_Browser->HorizontalScroll(); + if ( nScrolledX != m_nMouseScrolledX || nScrolledY != m_nMouseScrolledY ) + { + m_nMouseScrolledX = nScrolledX; + m_nMouseScrolledY = nScrolledY; + m_Browser->SendMouseMoveEvent( m_nMouseX, m_nMouseY, false ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: make the user agent for this browser +//----------------------------------------------------------------------------- +void CClientHandler::SetBrowserAgent( CefRefPtr browser ) +{ + static bool bGotIEVersion = false; + static char rgchWindowsVersion[64] = "Windows NT 5.1"; // XP SP1 + static char *rgchOS = ""; + + if ( !bGotIEVersion ) + { +#ifdef WIN32 + rgchOS = "Windows"; + // First get windows version + OSVERSIONINFO verInfo; + memset( &verInfo, 0, sizeof(OSVERSIONINFO) ); + verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if ( ::GetVersionEx( &verInfo ) ) + { + // We only run on "Windows NT" os's, so we just need to append the major/minor version dynamically + Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "Windows NT %u.%u", verInfo.dwMajorVersion, verInfo.dwMinorVersion ); + //Log( "Windows Version is: %u.%u\n", verInfo.dwMajorVersion, verInfo.dwMinorVersion ); + } + +#elif defined(OSX) + Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "Macintosh" ); + rgchOS = "Macintosh"; +#elif defined(LINUX) + Q_snprintf( rgchWindowsVersion, sizeof(rgchWindowsVersion), "X11" );// strange, but that's what Firefox uses + rgchOS = "Linux"; +#endif + } + + // user agent is process wide for Chrome so you can only set it once and it appplies to everything you open + { + char szAgent[ 2048 ]; + Q_snprintf( szAgent, sizeof(szAgent), m_strUserAgent.String(), rgchOS, rgchWindowsVersion, m_strUserAgentIdentifier.String(), sm_ulBuildID, m_szUserAgentExtras ); + browser->SetUserAgent( szAgent ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: paint the cef control +//----------------------------------------------------------------------------- +void CClientHandler::Paint() +{ + Lock(); + if ( m_Browser ) + { + m_bPendingPaint |= m_Painter.BUpdated(); + m_Painter.SetUpdated( false ); + } + Unlock(); +} + + +//----------------------------------------------------------------------------- +// Purpose: did we have a paint that updated the texture buffer? +//----------------------------------------------------------------------------- +bool CClientHandler::BNeedsPaint() +{ + bool bVal = m_bPendingPaint; + m_bPendingPaint = false; + return bVal; +} + + +//----------------------------------------------------------------------------- +// Purpose: get the texture data for the control +//----------------------------------------------------------------------------- +const byte *CClientHandler::PComposedTextureData( uint32 iTexture ) +{ + VPROF_BUDGET( "CClientHandler::PTextureData", VPROF_BUDGETGROUP_VGUI ); + + return m_Painter.PComposedTextureData( iTexture ); + } + + +//----------------------------------------------------------------------------- +// Purpose: true if something valid has rendered (i.e not the blank page) +//----------------------------------------------------------------------------- +bool CClientHandler::IsVisuallyNonEmpty() +{ + if ( m_Browser ) + return m_Browser->IsVisuallyNonEmpty(); + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: set the loc strings to display on error +//----------------------------------------------------------------------------- +void CClientHandler::SetErrorStrings( const char *pchTitle, const char *pchHeader, const char *pchCacheMiss, const char *pchBadURL, const char *pchConnectionProblem, + const char *pchProxyProblem, const char *pchUnknown ) +{ + m_sErrorTitle = pchTitle; + m_sErrorHeader = pchHeader; + m_sErrorCacheMiss = pchCacheMiss; + m_sErrorBadURL = pchBadURL; + m_sErrorConnectionProblem = pchConnectionProblem; + m_sErrorProxyProblem = pchProxyProblem; + m_sErrorUnknown = pchUnknown; +} + + +//----------------------------------------------------------------------------- +// Purpose: the user wants us to take a screenshot of a page +//----------------------------------------------------------------------------- +void CClientHandler::RequestScreenShot( const CHTMLProtoBufMsg &cmd ) +{ + m_Snapshot.m_sURLSnapshot = cmd.BodyConst().url().c_str(); + m_Snapshot.m_sFileNameSnapshot = cmd.BodyConst().filename().c_str(); + m_Snapshot.m_nWide = cmd.BodyConst().width(); + m_Snapshot.m_nTall = cmd.BodyConst().height(); + m_Snapshot.m_flRequestTimeout = Plat_FloatTime() + k_flMaxScreenshotWaitTime; +} + + +//----------------------------------------------------------------------------- +// Purpose: save a screenshot of the current html page to this file with this size +//----------------------------------------------------------------------------- +void CClientHandler::SavePageToJPEGIfNeeded( CefRefPtr browser, const byte *pRGBA, int wide, int tall ) +{ + if ( m_Snapshot.m_sURLSnapshot.IsValid() && wide && tall && ( browser->GetMainFrame()->GetURL().size() > 0 ) ) + { + if ( m_Snapshot.m_sURLSnapshot == CStrAutoEncode( browser->GetMainFrame()->GetURL().c_str() ).ToString() ) + { + VPROF_BUDGET( "CClientHandler::SavePageToJPEGIfNeeded", VPROF_BUDGETGROUP_TENFOOT ); + + CUtlBuffer bufRGB; + + bufRGB.Put( pRGBA, wide * tall *4 ); + if ( !BConvertRGBAToRGB( bufRGB, wide, tall ) ) + return; + + BResizeImageRGB( bufRGB, wide, tall, m_Snapshot.m_nWide, m_Snapshot.m_nTall ); + // input format is actually BGRA so now swizzle to rgb + byte *pBGR = (byte *)bufRGB.Base(); + for ( int i = 0; i < m_Snapshot.m_nTall; i++ ) + { + for ( int j = 0; j < m_Snapshot.m_nWide; j++ ) + { + char cR = pBGR[0]; + pBGR[0] = pBGR[2]; + pBGR[2] = cR; + pBGR += 3; + } + } + + if ( !ConvertRGBToJpeg( m_Snapshot.m_sFileNameSnapshot, k_ScreenshotQuality, m_Snapshot.m_nWide, m_Snapshot.m_nTall, bufRGB ) ) + return; + + CHTMLProtoBufMsg cmd( eHTMLCommands_SavePageToJPEGResponse ); + cmd.Body().set_url( m_Snapshot.m_sURLSnapshot ); + cmd.Body().set_filename( m_Snapshot.m_sFileNameSnapshot ); + DISPATCH_MESSAGE( eHTMLCommands_SavePageToJPEGResponse ); + + m_Snapshot.m_sURLSnapshot.Clear(); + m_Snapshot.m_flRequestTimeout = 0.0f; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: return the url located at this position if there is one +//----------------------------------------------------------------------------- +void CCEFThread::ThreadLinkAtPosition( const CHTMLProtoBufMsg &htmlCommand ) +{ + CefString pchURL; + int iClient = 0; + int bLiveLink = false; + int bInput = false; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + if ( m_listClientHandlers[iClient]->GetBrowser() ) + m_listClientHandlers[iClient]->GetBrowser()->GetLinkAtPosition( htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y(), + pchURL, bLiveLink, bInput); + } + + CHTMLProtoBufMsg cmd( eHTMLCommands_LinkAtPositionResponse ); + cmd.Body().set_x( htmlCommand.BodyConst().x() ); + cmd.Body().set_y( htmlCommand.BodyConst().y() ); + cmd.Body().set_blivelink( bLiveLink>0 ? true: false ); + cmd.Body().set_binput( bInput>0 ? true: false ); + if ( !pchURL.empty() ) + cmd.Body().set_url( pchURL ); + int m_iBrowser = htmlCommand.BodyConst().browser_handle(); + DISPATCH_MESSAGE( eHTMLCommands_LinkAtPositionResponse ); +} + + +//----------------------------------------------------------------------------- +// Purpose: zoom the screen to the element at this position +//----------------------------------------------------------------------------- +void CCEFThread::ThreadZoomToElementAtPosition( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + if ( m_listClientHandlers[iClient]->GetBrowser() ) + { + CefRect initialRect, finalRect; + float zoomLevel = m_listClientHandlers[iClient]->GetBrowser()->scalePageToFitElementAt( + htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y(), + initialRect, finalRect ); + int m_iBrowser = htmlCommand.BodyConst().browser_handle(); + ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); + ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); + { + CHTMLProtoBufMsg cmd( eHTMLCommands_ZoomToElementAtPositionResponse ); + cmd.Body().set_zoom( zoomLevel ); + cmd.Body().set_initial_x( initialRect.x ); + cmd.Body().set_initial_y( initialRect.y ); + cmd.Body().set_initial_width( initialRect.width ); + cmd.Body().set_initial_height( initialRect.height ); + cmd.Body().set_final_x( finalRect.x ); + cmd.Body().set_final_y( finalRect.y ); + cmd.Body().set_final_width( finalRect.width ); + cmd.Body().set_final_height( finalRect.height ); + DISPATCH_MESSAGE( eHTMLCommands_ZoomToElementAtPositionResponse ); + } + } + } + } + + +//----------------------------------------------------------------------------- +// Purpose: zoom the screen to the element at this position +//----------------------------------------------------------------------------- +void CCEFThread::ThreadZoomToFocusedElement( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + if ( m_listClientHandlers[iClient]->GetBrowser() ) + { + CefRect initialRect, finalRect; + float zoomLevel = m_listClientHandlers[iClient]->GetBrowser()->scalePageToFocusedElement( htmlCommand.BodyConst().leftoffset(), htmlCommand.BodyConst().topoffset(), initialRect, finalRect ); + int m_iBrowser = htmlCommand.BodyConst().browser_handle(); + ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); + ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); + { + CHTMLProtoBufMsg cmd( eHTMLCommands_ZoomToElementAtPositionResponse ); + cmd.Body().set_zoom( zoomLevel ); + cmd.Body().set_initial_x( initialRect.x ); + cmd.Body().set_initial_y( initialRect.y ); + cmd.Body().set_initial_width( initialRect.width ); + cmd.Body().set_initial_height( initialRect.height ); + cmd.Body().set_final_x( finalRect.x ); + cmd.Body().set_final_y( finalRect.y ); + cmd.Body().set_final_width( finalRect.width ); + cmd.Body().set_final_height( finalRect.height ); + DISPATCH_MESSAGE( eHTMLCommands_ZoomToElementAtPositionResponse ); + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: increment the scale factor on the page by an increment +//----------------------------------------------------------------------------- +void CCEFThread::ThreadSetPageScale( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CClientHandler *pHandler = m_listClientHandlers[iClient]; + if ( pHandler->GetBrowser() ) + { + int nPageHeightBefore = pHandler->GetBrowser()->VerticalScrollMax(); + int nPageWidthBefore = pHandler->GetBrowser()->HorizontalScrollMax(); + + float zoomLevel = pHandler->GetBrowser()->setPageScaleFactor( htmlCommand.BodyConst().scale(), htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y() ); + + int idx = m_mapSizeChangesPending.Find( htmlCommand.BodyConst().browser_handle() ); + if ( idx == m_mapSizeChangesPending.InvalidIndex() ) + { + SizeChange_t &sizeChange = m_mapSizeChangesPending [ m_mapSizeChangesPending.Insert( htmlCommand.BodyConst().browser_handle() ) ]; + sizeChange.iBrowser = htmlCommand.BodyConst().browser_handle(); + sizeChange.nBeforeHeight = nPageHeightBefore; + sizeChange.nBeforeWidth = nPageWidthBefore; + sizeChange.flNewZoom = zoomLevel; + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: fire off the details of any page scale changes we had pending from last frame +//----------------------------------------------------------------------------- +void CCEFThread::SendSizeChangeEvents() +{ + FOR_EACH_MAP_FAST( m_mapSizeChangesPending, i ) + { + int iClient = 0; + if ( BIsValidBrowserHandle( m_mapSizeChangesPending[i].iBrowser, iClient ) ) + { + CClientHandler *pHandler = m_listClientHandlers[iClient]; + if ( pHandler->GetBrowser() ) + { + int nPageHeightAfter = pHandler->GetBrowser()->VerticalScrollMax(); + int nPageWidthAfter = pHandler->GetBrowser()->HorizontalScrollMax(); + + int m_iBrowser = m_mapSizeChangesPending[i].iBrowser; + + ThreadBrowserVerticalScrollBarSizeHelper( m_iBrowser, true ); + ThreadBrowserHorizontalScrollBarSizeHelper( m_iBrowser, true ); + { + CHTMLProtoBufMsg cmd( eHTMLCommands_ScaleToValueResponse ); + cmd.Body().set_zoom( m_mapSizeChangesPending[i].flNewZoom ); + cmd.Body().set_width_delta( nPageWidthAfter - m_mapSizeChangesPending[i].nBeforeWidth ); + cmd.Body().set_height_delta( nPageHeightAfter - m_mapSizeChangesPending[i].nBeforeHeight ); + DISPATCH_MESSAGE( eHTMLCommands_ScaleToValueResponse ); + } + } + } + } + m_mapSizeChangesPending.RemoveAll(); +} + + +//----------------------------------------------------------------------------- +// Purpose: exit from fullscreen if in it +//----------------------------------------------------------------------------- +void CCEFThread::ThreadExitFullScreen( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[ iClient ]->GetBrowser()->ExitFullScreen(); + } + +} + + +//----------------------------------------------------------------------------- +// Purpose: the user has requested we save this url to a file on local disk +//----------------------------------------------------------------------------- +void CCEFThread::ThreadSavePageToJPEG( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[ iClient ]->RequestScreenShot( htmlCommand ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse moved to this x,y on the page +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseMove( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + m_listClientHandlers[ iClient ]->SetMouseLocation( htmlCommand.BodyConst().x(), htmlCommand.BodyConst().y() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse left the control, tell cef +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseLeave( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + + m_listClientHandlers[ iClient ]->SetMouseFocus( false ); + + int mx, my; + m_listClientHandlers[ iClient ]->GetMouseLocation( mx, my ); + browser->SendMouseMoveEvent( mx, my, true ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: helper to convert UI mouse codes to CEF ones +//----------------------------------------------------------------------------- +CefBrowser::MouseButtonType ConvertMouseCodeToCEFCode( int code ) +{ + // BUGBUG + switch( code ) + { + case 0: + return MBT_LEFT; + break; + case 1: + return MBT_RIGHT; + break; + case 2: + return MBT_MIDDLE; + break; + default: + return MBT_LEFT; + break; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse button pressed +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseButtonDown( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + int nMouseX, nMouseY; + m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); + + browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), false, 1 ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse button released +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseButtonUp( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + int nMouseX, nMouseY; + m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); + + browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), true, 1 ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse button double pressed +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseButtonDlbClick( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + int nMouseX, nMouseY; + m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); + + browser->SendMouseClickEvent( nMouseX, nMouseY, ConvertMouseCodeToCEFCode( htmlCommand.BodyConst().mouse_button() ), false, 2 ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: mouse was wheeled +//----------------------------------------------------------------------------- +void CCEFThread::ThreadMouseWheel( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + int nMouseX, nMouseY; + m_listClientHandlers[ iClient ]->GetMouseLocation( nMouseX, nMouseY ); + + browser->SendMouseWheelEvent( nMouseX, nMouseY, 0, htmlCommand.BodyConst().delta() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: unicode character was typed +//----------------------------------------------------------------------------- +void CCEFThread::ThreadKeyTyped( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + + CefKeyInfo keyInfo; +#ifdef OSX + keyInfo.character = htmlCommand.BodyConst().unichar(); +#else + keyInfo.key = htmlCommand.BodyConst().unichar(); +#endif + browser->SendKeyEvent( KT_CHAR, keyInfo, 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: raw key was pressed +//----------------------------------------------------------------------------- +void CCEFThread::ThreadKeyDown( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + + CefKeyInfo keyInfo; +#ifdef OSX + keyInfo.keyCode = htmlCommand.BodyConst().keycode(); +#else + keyInfo.key = htmlCommand.BodyConst().keycode(); +#endif + browser->SendKeyEvent( KT_KEYDOWN, keyInfo, htmlCommand.BodyConst().modifiers() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: raw key was released +//----------------------------------------------------------------------------- +void CCEFThread::ThreadKeyUp( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + + CefKeyInfo keyInfo; +#ifdef OSX + keyInfo.keyCode = htmlCommand.BodyConst().keycode(); +#else + keyInfo.key = htmlCommand.BodyConst().keycode(); +#endif + browser->SendKeyEvent( KT_KEYUP, keyInfo, htmlCommand.BodyConst().modifiers() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: please close any fullscreen flash controls you see +//----------------------------------------------------------------------------- +void CCEFThread::ThreadCloseFullScreenFlashIfOpen( const CHTMLProtoBufMsg &htmlCommand ) +{ + CheckForFullScreenFlashControl(); + if ( m_bFullScreenFlashVisible ) + { +#ifdef WIN32 + ::PostMessageA( m_flashfullscreenHWND, WM_KEYDOWN, VK_ESCAPE, 0 ); + ::PostMessageA( m_flashfullscreenHWND, WM_KEYUP, VK_ESCAPE, 0 ); +#endif + } +} + + +//----------------------------------------------------------------------------- +// Purpose: please close any fullscreen flash controls you see +//----------------------------------------------------------------------------- +void CCEFThread::ThreadPauseFullScreenFlashMovieIfOpen( const CHTMLProtoBufMsg &htmlCommand ) +{ + CheckForFullScreenFlashControl(); + if ( m_bFullScreenFlashVisible ) + { +#ifdef WIN32 + ::PostMessageA( m_flashfullscreenHWND, WM_KEYDOWN, VK_SPACE, 0 ); + ::PostMessageA( m_flashfullscreenHWND, WM_KEYUP, VK_SPACE, 0 ); +#endif + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: helper class to get the focused node in the dom +//----------------------------------------------------------------------------- +class CVisitor : public CefDOMVisitor +{ +public: + CVisitor( CThreadEvent *pEvent, CUtlString *psValue ) + { + m_pEvent = pEvent; + m_psValue = psValue; + } + + ~CVisitor() + { + m_pEvent->Set(); + } + + virtual void Visit(CefRefPtr document) { + CefRefPtr focusedNode = document->GetFocusedNode(); + *m_psValue = focusedNode->GetValue().c_str(); + } + + +private: + CThreadEvent *m_pEvent; + CUtlString *m_psValue; + + IMPLEMENT_REFCOUNTING(CVisitor); +}; + + +//----------------------------------------------------------------------------- +// Purpose: get the text out of the current dom field that has focus +//----------------------------------------------------------------------------- +void CCEFThread::ThreadGetFocusedNodeText( const CHTMLProtoBufMsg &htmlCommand ) +{ + int iClient = 0; + if ( BIsValidBrowserHandle( htmlCommand.BodyConst().browser_handle(), iClient ) ) + { + CefRefPtr browser = m_listClientHandlers[ iClient ]->GetBrowser(); + if ( !browser.get() ) + return; + + CThreadEvent event; + CUtlString sValue; + browser->GetFocusedFrame()->VisitDOM( new CVisitor( &event, &sValue ) ); + do + { + CefDoMessageLoopWork(); + } + while ( !event.Wait( 100 ) ); // keep pumping CEF until it has done our walk + + { + int m_iBrowser = htmlCommand.BodyConst().browser_handle(); + CHTMLProtoBufMsg cmd( eHTMLCommands_GetFocusedNodeValueResponse ); + cmd.Body().set_value( sValue ); + DISPATCH_MESSAGE( eHTMLCommands_GetFocusedNodeValueResponse ); + } + } +} diff --git a/vgui2/chromehtml/html_chrome.h b/vgui2/chromehtml/html_chrome.h new file mode 100644 index 00000000..d6ae5495 --- /dev/null +++ b/vgui2/chromehtml/html_chrome.h @@ -0,0 +1,637 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTML_CHROME_H +#define HTML_CHROME_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "cef/include/cef_render_handler.h" +#include "cef/include/cef_client.h" +#include "cef/include/cef_app.h" +#include "cef/include/cef_browser.h" +#include "cef/include/cef_command_line.h" +#include "cef/include/cef_frame.h" +#include "cef/include/cef_runnable.h" +#include "cef/include/cef_web_urlrequest.h" +#include "cef/include/cef_request_handler.h" +#include "cef/include/cef_load_handler.h" +#include "cef/include/cef_display_handler.h" +#include "cef/include/cef_life_span_handler.h" +#include "cef/include/cef_render_handler.h" + +#include "tier0/platform.h" +#include "tier0/vprof.h" +#include "tier1/utlarray.h" +#include "tier1/utlbuffer.h" +#include "fileio.h" +//#include "constants.h" +#include "tier0/validator.h" +#include "tier1/utlmap.h" +#include "tier1/utlstring.h" +#include "tier0/tslist.h" +#include "html/ihtmlchrome.h" +#include "html/htmlprotobuf.h" +// These must be undefed so that the MacOS build will work -- their STL +// fails if min and max are defined. I'm undefing them in all builds to +// avoid having a Windows dependency on min/max creep in. +#undef min +#undef max +#include "htmlmessages.pb.h" + +class CClientHandler; +class CChromePainter; +class ICookieCallback; + +bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath, RTime32 nExpires ); +bool ChromeGetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ); + +//----------------------------------------------------------------------------- +// Purpose: track dirty rects, shuttle bits between renderer and main thread +//----------------------------------------------------------------------------- +class CChromeUpdateRegion +{ +public: + CChromeUpdateRegion() { MarkAllClean(); } + int GetUpdateX( int clampWide ) const { return clamp( m_nUpdateX0, 0, clampWide ); } + int GetUpdateY( int clampTall ) const { return clamp( m_nUpdateY0, 0, clampTall ); } + int GetUpdateWide( int clampWide ) const { return clamp( m_nUpdateX1, 0, clampWide ) - GetUpdateX( clampWide ); } + int GetUpdateTall( int clampTall ) const { return clamp( m_nUpdateY1, 0, clampTall ) - GetUpdateY( clampTall ); } + + void MarkAllClean() { m_nUpdateX0 = m_nUpdateY0 = INT_MAX; m_nUpdateX1 = m_nUpdateY1 = 0; } + void MarkAllDirty() { m_nUpdateX0 = m_nUpdateY0 = 0; m_nUpdateX1 = m_nUpdateY1 = INT_MAX; } + void MarkDirtyRect( int x0, int y0, int x1, int y1 ) + { + if ( x0 >= x1 || y0 >= y1 ) return; + if ( m_nUpdateX0 > x0 ) m_nUpdateX0 = x0; + if ( m_nUpdateY0 > y0 ) m_nUpdateY0 = y0; + if ( m_nUpdateX1 < x1 ) m_nUpdateX1 = x1; + if ( m_nUpdateY1 < y1 ) m_nUpdateY1 = y1; + } + void MarkDirtyRect( const CChromeUpdateRegion& other ) + { + MarkDirtyRect( other.m_nUpdateX0, other.m_nUpdateY0, other.m_nUpdateX1, other.m_nUpdateY1 ); + } + +protected: + int m_nUpdateX0; + int m_nUpdateY0; + int m_nUpdateX1; + int m_nUpdateY1; +}; + +class CChromeRenderBuffer : public CChromeUpdateRegion +{ +public: + CChromeRenderBuffer() { m_nWide = m_nTall = 0; } + void SetSize( int wide, int tall ) + { + if ( wide != m_nWide || tall != m_nTall ) + { + m_nWide = wide; + m_nTall = tall; + MarkAllDirty(); + m_Texture.EnsureCapacity( wide * tall * 4 ); + } + } + int GetWide() const { return m_nWide; } + int GetTall() const { return m_nTall; } + byte *GetPixels() { return m_Texture.Base(); } + + bool BUpdatePixels( byte *pOther, int wide, int tall ) + { + SetSize( wide, tall ); + int x0 = clamp( m_nUpdateX0, 0, wide ); + int y0 = clamp( m_nUpdateY0, 0, tall ); + int x1 = clamp( m_nUpdateX1, 0, wide ); + int y1 = clamp( m_nUpdateY1, 0, tall ); + if ( x0 >= x1 || y0 >= y1 ) + return false; + + if ( x0 == 0 && x1 == wide ) + { + byte *pDst = GetPixels() + y0*wide*4; + byte *pSrc = pOther + y0*wide*4; + Q_memcpy( pDst, pSrc, wide * ( y1 - y0 ) * 4 ); + } + else + { + byte *pDst = GetPixels() + y0*wide*4 + x0*4; + byte *pSrc = pOther + y0*wide*4 + x0*4; + int nCopyBytesPerRow = (x1 - x0)*4; + for ( int rows = y1 - y0; rows > 0; --rows ) + { + Q_memcpy( pDst, pSrc, nCopyBytesPerRow ); + pSrc += wide * 4; + pDst += wide * 4; + } + } + return true; + } + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ) + { + VALIDATE_SCOPE(); + ValidateObj( m_Texture ); + } +#endif + +protected: + int m_nWide; // dimensions of the buffer + int m_nTall; + CUtlVector m_Texture; // rgba data +}; + +//----------------------------------------------------------------------------- +// Purpose: interface Chrome uses to send up paint messages +//----------------------------------------------------------------------------- +class CChromePainter : public CefRenderHandler +{ +public: + CChromePainter( CClientHandler *pParent ); + ~CChromePainter(); + + virtual bool GetViewRect(CefRefPtr browser, CefRect& rect) OVERRIDE { return false; } + virtual bool GetScreenRect(CefRefPtr browser, CefRect& rect) OVERRIDE { return false; } + virtual bool GetScreenPoint(CefRefPtr browser, int viewX, int viewY, int& screenX, int& screenY) OVERRIDE { return false; } + + virtual void OnPopupShow(CefRefPtr browser, bool show) OVERRIDE; + virtual void OnPopupSize(CefRefPtr browser, const CefRect& rect) OVERRIDE; + + virtual void OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer) OVERRIDE; + virtual void OnCursorChange(CefRefPtr browser, CefCursorHandle cursor) OVERRIDE {} + virtual bool OnSetCursor( CefRefPtr browser, const CursorType type, const void *pchIconData, int iWide, int iTall, int xHotSpot, int yHotSpot ) OVERRIDE; + virtual bool OnFileOpenDialog( CefRefPtr browser, bool bMultiSelect, const CefString &default_title, const CefString &default_file, CefWebFileChooserCallback *pCallback ) OVERRIDE; + virtual bool OnEnterFullScreen( CefRefPtr browser ) OVERRIDE; + virtual bool OnExitFullScreen( CefRefPtr browser ) OVERRIDE; + + bool BUpdated(); + void SetUpdated( bool state ); + + int GetPopupTall() const { return m_nPopupTall; } + int GetPopupWide() const { return m_nPopupWide; } + int GetPopupX() const { return m_nPopupX; } + int GetPopupY() const { return m_nPopupY; } + const byte *PPopupTextureData() + { + return m_PopupTexture.Base(); + } + + uint32 FlipTexture(); + void SetTextureUploaded( uint32 id ); + bool BPaintBufferAvailable(); + + byte *PComposedTextureData( uint32 iTexture ); + int GetTall() const { return m_MainTexture.GetTall(); } + int GetWide() const { return m_MainTexture.GetWide(); } + int GetUpdateX() const { return m_UpdateRect.GetUpdateX( GetWide() ); } + int GetUpdateY() const { return m_UpdateRect.GetUpdateY( GetTall() ); } + int GetUpdateWide() const { return m_UpdateRect.GetUpdateWide( GetWide() ); } + int GetUpdateTall() const { return m_UpdateRect.GetUpdateTall( GetTall() ); } + void ClearUpdateRect() { m_UpdateRect.MarkAllClean(); } + + // XXX not shuttled safely between threads, should use real buffering + const byte *PPopupTextureDataCached(); + + bool BPopupVisible() const { return m_bPopupVisible; } + // WebKit will show popups before they have been given a size and painted and we may do + // a drawing pass during that time, so we want to make sure to only do something + // with the popup when it has an actual size and content. + bool BPopupVisibleAndPainted() const + { + return m_bPopupVisible && + m_nPopupWide != 0 && + m_nPopupTall != 0 && + m_PopupTexture.Count() >= m_nPopupWide * m_nPopupTall * 4; + } + void PopupRect( int &x, int &y, int &wide, int &tall ) const { x = m_nPopupX; y = m_nPopupY; wide = m_nPopupWide; tall = m_nPopupTall; } + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ) + { + VALIDATE_SCOPE(); + for ( int i = 0; i < Q_ARRAYSIZE(m_Texture); i++ ) + ValidateObj( m_Texture[i] ); + + ValidateObj( m_PopupTextureCache ); + ValidateObj( m_PopupTexture ); + ValidateObj( m_MainTexture ); + } +#endif + IMPLEMENT_REFCOUNTING(CChromePainter); + +private: + uint32 m_iNextTexture; + uint32 m_iTexturesInFlightBits; + int m_nPopupWide; + int m_nPopupTall; + CChromeRenderBuffer m_MainTexture; + CChromeRenderBuffer m_Texture[2]; // buffering -- XXX should use atomic swap, not push multiple buffers to command buffer + CChromeUpdateRegion m_UpdateRect; + CUtlVector m_PopupTextureCache; + CUtlVector m_PopupTexture; + bool m_bUpdated; + CClientHandler *m_pParent; + bool m_bPopupVisible; + int m_nPopupX, m_nPopupY; +}; + + + +//----------------------------------------------------------------------------- +// Purpose: CEF callback object +//----------------------------------------------------------------------------- +class CClientHandler : public CefClient, + public CefLifeSpanHandler, + public CefLoadHandler, + public CefRequestHandler, + public CefDisplayHandler, + + public CefJSDialogHandler, + public CefFindHandler, + public CefMenuHandler, + public CefFocusHandler, + public CefPermissionHandler +{ +public: + CClientHandler( int iBrowser, const char *pchUserAgent, uint16 nSerial ); + ~CClientHandler(); + + // CefClient methods + virtual CefRefPtr GetLifeSpanHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetLoadHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetRequestHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetDisplayHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetRenderHandler() OVERRIDE { + return &m_Painter; + } + + virtual CefRefPtr GetFocusHandler() OVERRIDE { + return this; + } + + virtual CefRefPtr GetMenuHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetPermissionHandler() OVERRIDE { + return this; + } + + virtual CefRefPtr GetFindHandler() OVERRIDE { + return this; + } + virtual CefRefPtr GetJSDialogHandler() OVERRIDE { + return this; + } + + + // CefLifeSpanHandler methods + + virtual bool OnBeforePopup(CefRefPtr parentBrowser, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, const CefString& url, CefRefPtr& client, CefBrowserSettings& settings) OVERRIDE; + virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + virtual bool DoClose(CefRefPtr browser) { return false; } + virtual bool OnNewTab(CefRefPtr parentBrowser, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, const CefString& url, bool bForeground, CefRefPtr& client, CefBrowserSettings& settings ); + + // CefLoadHandler methods + virtual void OnLoadStart(CefRefPtr browser, CefRefPtr frame, bool bIsNewNavigation ) OVERRIDE; + + virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode, CefRefPtr request ) OVERRIDE; + virtual bool OnLoadError(CefRefPtr browser, CefRefPtr frame, ErrorCode errorCode, const CefString& failedUrl, CefString& errorText); + + // CefRequestHandler methods + virtual bool OnBeforeBrowse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, NavType navType, bool isRedirect, bool isNewTabRequest ); + virtual bool OnBeforeResourceLoad(CefRefPtr browser, CefRefPtr request, CefString& redirectUrl, CefRefPtr& resourceStream, CefRefPtr response, int loadFlags); + + // CefDisplayHandler methods + virtual void OnNavStateChange(CefRefPtr browser, bool canGoBack, bool canGoForward) OVERRIDE {} + virtual void OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) OVERRIDE { } + virtual void OnTitleChange(CefRefPtr browser, const CefString& title) OVERRIDE; + + virtual bool OnTooltip(CefRefPtr browser, CefString& text); + virtual void OnStatusMessage(CefRefPtr browser, const CefString& value, StatusType type); + virtual bool OnConsoleMessage(CefRefPtr browser, const CefString& message, const CefString& source, int line); + + virtual void OnTakeFocus(CefRefPtr browser, bool next) {} + virtual bool OnSetFocus(CefRefPtr browser, FocusSource source) { return true; } + virtual void OnFocusedNodeChanged(CefRefPtr browser, CefRefPtr frame, CefRefPtr node); + + virtual bool OnBeforeMenu(CefRefPtr browser, const CefMenuInfo& menuInfo) { return true; } + virtual void GetMenuLabel(CefRefPtr browser, MenuId menuId, CefString& label) {} + virtual bool OnMenuAction(CefRefPtr browser, MenuId menuId) { return true; } + virtual bool OnBeforeScriptExtensionLoad(CefRefPtr browser, CefRefPtr frame, const CefString& extensionName) { return false; } + + virtual void OnFindResult(CefRefPtr browser, int identifier, int count, const CefRect& selectionRect, int activeMatchOrdinal, bool finalUpdate); + virtual bool OnJSAlert(CefRefPtr browser, CefRefPtr frame, const CefString& message); + virtual bool OnJSConfirm(CefRefPtr browser, CefRefPtr frame, const CefString& message, bool& retval); + virtual bool OnJSPrompt(CefRefPtr browser, CefRefPtr frame, const CefString& message, const CefString& defaultValue, bool& retval, CefString& result); + + void FileOpenDialogResult( const char *pchFileName ); + + + // paint helpers + void Paint(); + bool BNeedsPaint(); + + int GetTextureTall() const { return m_Painter.GetTall(); } + int GetTextureWide() const { return m_Painter.GetWide(); } + int GetUpdateX() const { return m_Painter.GetUpdateX(); } + int GetUpdateY() const { return m_Painter.GetUpdateY(); } + int GetUpdateWide() const { return m_Painter.GetUpdateWide(); } + int GetUpdateTall() const { return m_Painter.GetUpdateTall(); } + + const byte *PPopupTextureDataCached() { return m_Painter.PPopupTextureDataCached(); } + bool BPopupVisible() const { return m_Painter.BPopupVisible(); } + bool BPopupVisibleAndPainted() const { return m_Painter.BPopupVisibleAndPainted(); } + void PopupRect( int &x, int &y, int &wide, int &tall ) const { m_Painter.PopupRect( x, y, wide, tall ); } + + const byte *PComposedTextureData( uint32 iTexture ); + uint32 FlipTexture() { return m_Painter.FlipTexture(); } + void SetTextureUploaded( uint32 iTexture ) { m_Painter.SetTextureUploaded( iTexture ); } + void ClearUpdateRect() { m_Painter.ClearUpdateRect(); } + bool BPaintBufferReady() { return m_Painter.BPaintBufferAvailable(); } + + // Helpers + CefRefPtr GetBrowser(); + void CloseBrowser(); + uint32 GetPageSerial() { return m_nPageSerial; } + void SetPendingPageSerial( uint32 nPageSerial ) + { + m_nPendingPageSerial = nPageSerial; + } + + + void SetUserAgent( const char *pchAgent ) { Q_strncpy( m_szUserAgentExtras, pchAgent, sizeof(m_szUserAgentExtras) ); } + const char *PchCurrentURL() { return m_strCurrentUrl.String(); } + bool IsVisuallyNonEmpty(); + void SetErrorStrings( const char *pchTitle, const char *pchHeader, const char *pchCacheMiss, const char *pchBadURL, const char *pchConnectionProblem, + const char *pchProxyProblem, const char *pchUnknown ); + void SetMouseLocation( int x, int y ); + void GetMouseLocation( int &x, int &y ) { x = m_nMouseX; y = m_nMouseY; } + void SetMouseFocus( bool bFocus ) { m_bMouseFocus = bFocus; } + void SetSize( int wide, int tall ) { m_nExpectedWide = wide; m_nExpectedTall = tall; } + void GetExpectedSize( int &wide, int &tall ) { wide = m_nExpectedWide; tall =m_nExpectedTall; } + + //----------------------------------------------------------------------------- + // Purpose: Adds a custom header to all requests + //----------------------------------------------------------------------------- + void AddHeader( const char *pchHeader, const char *pchValue ) + { + m_vecHeaders.AddToTail( std::make_pair( CStrAutoEncode( pchHeader ).ToWString(), CStrAutoEncode( pchValue ).ToWString() ) ); + } + + void RequestScreenShot( const CHTMLProtoBufMsg &cmd ); + void SavePageToJPEGIfNeeded( CefRefPtr browser, const byte *pRGBA, int wide, int tall ); + bool BPendingScreenShot() + { + return m_Snapshot.m_flRequestTimeout > 0.0f && m_Snapshot.m_sURLSnapshot.IsValid() && m_Snapshot.m_flRequestTimeout < Plat_FloatTime(); + } + + void SetUserAgentIdentifier( const char *pchIdent ) + { + m_strUserAgentIdentifier = pchIdent; + } + + uint16 NSerial() { return m_nSerial; } + + void RefreshCEFHoverStatesAfterScroll(); + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ) + { + VALIDATE_SCOPE(); + ValidateObj( m_strCurrentUrl ); + ValidateObj( m_strPostData ); + ValidateObj( m_strLastRedirectURL ); + ValidateObj( m_vecHeaders ); + ValidateObj( m_strUserAgent ); + ValidateObj( m_Painter ); + ValidateObj( m_sErrorTitle ); + ValidateObj( m_sErrorHeader ); + ValidateObj( m_sErrorCacheMiss ); + ValidateObj( m_sErrorBadURL ); + ValidateObj( m_sErrorConnectionProblem ); + ValidateObj( m_sErrorProxyProblem ); + ValidateObj( m_sErrorUnknown ); + ValidateObj( m_strUserAgentIdentifier ); + // ValidateObj( m_vecHCursor ); + } +#endif + + IMPLEMENT_REFCOUNTING(CClientHandler); + IMPLEMENT_LOCKING(CClientHandler); +private: + friend class CChromePainter; + friend class CCEFThread; + + void SetBrowserAgent( CefRefPtr browser ); + + // The child browser window + CefRefPtr m_Browser; + + CefRenderHandler::CefWebFileChooserCallback *m_pOpenFileCallback; + + uint16 m_nSerial; + char m_szUserAgentExtras[ 256 ]; + CUtlString m_strCurrentUrl; + CUtlString m_strPostData; + CUtlString m_strLastRedirectURL; + CUtlString m_strUserAgent; + CUtlString m_strUserAgentIdentifier; + CUtlString m_strToolTip; + bool m_bShowingToolTip; + bool m_bPendingPaint; + bool m_bBrowserClosing; + bool m_bMouseFocus; + CChromePainter m_Painter; + CUtlVector< std::pair< std::wstring, std::wstring > > m_vecHeaders; + int m_iBrowser; + int m_nExpectedWide; + int m_nExpectedTall; + uint32 m_nPageSerial; + uint32 m_nPendingPageSerial; + + CUtlString m_sErrorTitle; + CUtlString m_sErrorHeader; + CUtlString m_sErrorCacheMiss; + CUtlString m_sErrorBadURL; + CUtlString m_sErrorConnectionProblem; + CUtlString m_sErrorProxyProblem; + CUtlString m_sErrorUnknown; + int m_nMouseX; + int m_nMouseY; + int m_nMouseScrolledX; + int m_nMouseScrolledY; + + struct SnapshotData_t + { + CUtlString m_sURLSnapshot; + CUtlString m_sFileNameSnapshot; + int m_nWide, m_nTall; + float m_flRequestTimeout; + }; + + SnapshotData_t m_Snapshot; + + // Scroll bar state is cached and compared to CEF's current values every frame; + // any changes are passed on to the client handler as serialized update messages. + struct CachedScrollBarState_t + { + int m_nX; + int m_nY; + int m_nWide; + int m_nTall; + int m_nMax; + int m_nScroll; + int m_bVisible; // using 'int' to avoid padding bytes so memcmp can be used + }; + CachedScrollBarState_t m_CachedVScroll; + CachedScrollBarState_t m_CachedHScroll; +}; + + + +//----------------------------------------------------------------------------- +// Purpose: CEF thinking thread +//----------------------------------------------------------------------------- +class CCEFThread : public CValidatableThread +{ +public: + CCEFThread(); + ~CCEFThread(); + void SetCEFPaths( const char *pchHTMLCacheDir, const char *pchCookiePath ); + void TriggerShutdown(); + void WakeThread(); + virtual int Run(); + + bool BHasPendingMessages() { return m_tslResponseBuffers.Count() > 0; } + + HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ); + void ReleaseCommandBuffer( HTMLCommandBuffer_t *pBuf ); + void PushCommand( HTMLCommandBuffer_t * ); + void PushResponse( HTMLCommandBuffer_t * ); + bool GetMainThreadCommand( HTMLCommandBuffer_t ** ); + HTMLCommandBuffer_t *BWaitForCommand( EHTMLCommands eCmd, int iBrowser ); + HTMLCommandBuffer_t *BWaitForResponse( EHTMLCommands eCmd, int iBrowser ); + bool GetCEFThreadCommand( HTMLCommandBuffer_t **pBuf ); + +#ifdef DBGFLAG_VALIDATE + virtual void SleepForValidate() { CValidatableThread::SleepForValidate(); m_evWaitingForCommand.Set(); WakeThread(); } + virtual void Validate( CValidator &validator, const tchar *pchName ); +#endif + + +private: + void RunCurrentCommands(); + const char *PchWebkitUserAgent(); + void AppGetSettings(CefSettings& settings, CefRefPtr& app); + void CleanupTempFolders(); + + void ThreadCreateBrowser( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadRemoveBrowser( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserSize( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserPosition( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserPostURL( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserStopLoad( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserReload( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserGoForward( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserGoBack( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserCopy( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserPaste( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserExecuteJavascript( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserSetFocus( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserHorizontalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserVerticalScrollBarSize( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserFind( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserStopFind( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserSetHorizontalScroll( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserSetVerticalScroll( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserSetZoomLevel( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserViewSource( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadNeedsPaintResponse( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadBrowserErrorStrings( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadAddHeader( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadGetZoom( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadHidePopup( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadGetCookiesForURL( const CHTMLProtoBufMsg &htmlCommand ); + + void ThreadKeyDown( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadKeyUp( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadKeyTyped( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseButtonDown( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseButtonUp( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseButtonDlbClick( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseWheel( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseMove( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadMouseLeave( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadLinkAtPosition( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadZoomToElementAtPosition( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadZoomToFocusedElement( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadSavePageToJPEG( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadSetCookie( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadSetTargetFrameRate( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadFullRepaint( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadSetPageScale( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadExitFullScreen( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadCloseFullScreenFlashIfOpen( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadPauseFullScreenFlashMovieIfOpen( const CHTMLProtoBufMsg &htmlCommand ); + void ThreadGetFocusedNodeText( const CHTMLProtoBufMsg &htmlCommand ); + + void ThreadBrowserVerticalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ); + void ThreadBrowserHorizontalScrollBarSizeHelper( int iBrowser, bool bForceSendUpdate ); + + bool BIsValidBrowserHandle( uint32 nHandle, int &iClient ); + void SendSizeChangeEvents(); + void CheckForFullScreenFlashControl(); + + CThreadEvent m_WakeEvent; + CUtlString m_sHTMLCacheDir; + CUtlString m_sCookiePath; + bool m_bExit; + CThreadEvent m_eventDidExit; + + CUtlLinkedList m_listClientHandlers; + + CTSQueue m_tslCommandBuffers; + CUtlVector m_vecQueueCommands; + CTSQueue m_tslResponseBuffers; + CUtlVector m_vecQueueResponses; + + CTSList m_tslUnsedBuffers; + + CThreadEvent m_evWaitingForCommand; + CThreadEvent m_evWaitingForResponse; + int m_nTargetFrameRate; + uint16 m_nBrowserSerial; + bool m_bFullScreenFlashVisible; +#ifdef WIN32 + HWND m_flashfullscreenHWND; +#endif + bool m_bSawUserInputThisFrame; + + struct SizeChange_t + { + int iBrowser; + int nBeforeWidth; + int nBeforeHeight; + float flNewZoom; + }; + CUtlMap< int, SizeChange_t, int > m_mapSizeChangesPending; +}; + +CCEFThread &AccessHTMLWrapper(); + +#endif // HTML_CHROME_H diff --git a/vgui2/chromehtml/html_mac.mm b/vgui2/chromehtml/html_mac.mm new file mode 100644 index 00000000..6feb9046 --- /dev/null +++ b/vgui2/chromehtml/html_mac.mm @@ -0,0 +1,16 @@ +//=========== Copyright Valve Corporation, All rights reserved. ===============// +// +// Purpose: +//=============================================================================// + +#include + +extern "C" void *CreateAutoReleasePool() +{ + return [[NSAutoreleasePool alloc] init]; +} + +extern "C" void ReleaseAutoReleasePool( void *pool ) +{ + [pool release]; +} \ No newline at end of file diff --git a/vgui2/chromehtml/htmlmanager.h b/vgui2/chromehtml/htmlmanager.h new file mode 100644 index 00000000..3aaa551c --- /dev/null +++ b/vgui2/chromehtml/htmlmanager.h @@ -0,0 +1,30 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTMLMANAGER_H +#define HTMLMANAGER_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: helper funcs to pump chrome +//----------------------------------------------------------------------------- +void ChromeInit( const char *pchHTMLCacheDir, const char *pchCookiePath ); +void ChromeShutdown(); + +#ifdef DBGFLAG_VALIDATE +void ChromeValidate( CValidator &validator, const char *pchName ); +bool ChromeResumeFromValidate(); +bool ChromePrepareForValidate(); +#endif + +bool ChromeSetWebCookie( const char *pchHostname, const char *pchName, const char *pchValue, const char *pchPath ); +void ChromeSetClientBuildID( uint64 ulBuildID ); + +enum EMouseState { UP,DOWN,MOVE,DBLCLICK }; + +#endif // HTMLMANAGER_H diff --git a/vgui2/chromehtml/htmlmessages.proto b/vgui2/chromehtml/htmlmessages.proto new file mode 100644 index 00000000..6ad706ef --- /dev/null +++ b/vgui2/chromehtml/htmlmessages.proto @@ -0,0 +1,1025 @@ +//====== Copyright 1996-2010, Valve Corporation, All rights reserved. ======= +// +// Purpose: The file defines our Google Protocol Buffers which are used in IPC +// and inter-thread communcations in the tenfoot UI rendering system. +// +//============================================================================= + +// We care more about speed than code size +option optimize_for = SPEED; + +// We don't use the service generation functionality +option cc_generic_services = false; + +// +// STYLE NOTES: +// +// Use CamelCase CMsgMyMessageName style names for messages. +// +// Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, +// but plays nice with the Google formatted code generation. +// +// Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. +// Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors +// your message and wants to remove or rename fields. This is especially important for messages sent from the server +// to clients. We may be able to safely remove a field if it's optional even if an old client expects it, but if it +// was required we can't remove it. Using required doesn't really offer any advantages at all as you'll just end up +// with an empty message with all default values if you receive a message missing a required field, so there is no +// real advantage to using it ever. +// +// Use fixed64 for JobId_t, GID_t, or SteamID or GameID. This is appropriate for any field that is normally +// going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller +// than 2^56 as it will safe space on the wire in those cases. +// +// Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than +// 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. +// An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual +// time. +// +// Use uint32 with [default = 2] for EResult values in messages. The default is important since the normal int/uint +// default of 0 is not a valid EResult value. 2 is k_EResultFail. +// +// See: http://code.google.com/apis/protocolbuffers/docs/proto.html for a complete language guide. +// + + +// +// key up - eHTMLCommands_KeyUp +// +message CMsgKeyUp +{ + optional uint32 browser_handle = 1; + optional uint32 keyCode = 2; + optional uint32 modifiers = 3; +} + + +// +// key down - eHTMLCommands_KeyDown +// +message CMsgKeyDown +{ + optional uint32 browser_handle = 1; + optional uint32 keyCode = 2; + optional uint32 modifiers = 3; +} + + +// +// key unichar - eHTMLCommands_KeyChar +// +message CMsgKeyChar +{ + optional uint32 browser_handle = 1; + optional uint32 unichar = 2; +} + + +// +// mouse down - eHTMLCommands_MouseDown +// +message CMsgMouseDown +{ + optional uint32 browser_handle = 1; + optional uint32 mouse_button = 2; +} + + +// +// mouse up - eHTMLCommands_MouseUp +// +message CMsgMouseUp +{ + optional uint32 browser_handle = 1; + optional uint32 mouse_button = 2; +} + + +// +// mouse dbl click - eHTMLCommands_MouseDblClick +// +message CMsgMouseDblClick +{ + optional uint32 browser_handle = 1; + optional uint32 mouse_button = 2; +} + + +// +// mouse wheel - eHTMLCommands_MouseWheel +// +message CMsgMouseWheel +{ + optional uint32 browser_handle = 1; + optional int32 delta = 2; +} + + +// +// mouse move - eHTMLCommands_MouseMove +// +message CMsgMouseMove +{ + optional uint32 browser_handle = 1; + optional int32 x = 2; + optional int32 y = 3; +} + + +// +// mouse leave - eHTMLCommands_MouseLeave +// +message CMsgMouseLeave +{ + optional uint32 browser_handle = 1; +} + + +// +// make a cef control - eHTMLCommands_BrowserCreate +// +message CMsgBrowserCreate +{ + optional uint32 request_id = 1; + optional bool popup = 2 [default = false]; + optional string useragent = 3; +} + + +// +// ack to the main thread a control was made - eHTMLCommands_BrowserCreateResponse +// +message CMsgBrowserCreateResponse +{ + optional uint32 browser_handle = 1; + optional uint32 request_id = 2; +} + + +// +// delete a browser - eHTMLCommands_BrowserRemove +// +message CMsgBrowserRemove +{ + optional uint32 browser_handle = 1; +} + + +// +// send loc strings over to use for error page - eHTMLCommands_BrowserErrorStrings +// +message CMsgBrowserErrorStrings +{ + optional uint32 browser_handle = 1; + optional string title = 2; + optional string header = 3; + optional string cache_miss = 4; + optional string bad_url = 5; + optional string connection_problem = 6; + optional string proxy_problem = 7; + optional string unknown = 8; +} + + +// +// Set a browser to this size - eHTMLCommands_BrowserSize +// +message CMsgBrowserSize +{ + optional uint32 browser_handle = 1; + optional uint32 width = 2; + optional uint32 height = 3; +} + + +// +// Set position in the window - eHTMLCommands_BrowserPosition +// +message CMsgBrowserPosition +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; +} + + +// +// load this url - eHTMLCommands_PostURL +// +message CMsgPostURL +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string post = 3; + optional uint32 pageserial = 4; +} + + +// +// have cef send this html header for all page loads -eHTMLCommands_AddHeader +// +message CMsgAddHeader +{ + optional uint32 browser_handle = 1; + optional string key = 2; + optional string value = 3; +} + + +// +// stop loading a page - eHTMLCommands_StopLoad +// +message CMsgStopLoad +{ + optional uint32 browser_handle = 1; +} + + +// +// reload a page - eHTMLCommands_Reload +// +message CMsgReload +{ + optional uint32 browser_handle = 1; +} + + +// +// next page - eHTMLCommands_GoForward +// +message CMsgGoForward +{ + optional uint32 browser_handle = 1; +} + + +// +// back a page in the stack - eHTMLCommands_GoBack +// +message CMsgGoBack +{ + optional uint32 browser_handle = 1; +} + + +// +// copy the currently selected text - eHTMLCommands_Copy +// +message CMsgCopy +{ + optional uint32 browser_handle = 1; +} + + +// +// paste text here from the clipboard - eHTMLCommands_Paste +// +message CMsgPaste +{ + optional uint32 browser_handle = 1; +} + + +// +// run this javascript on the current page - eHTMLCommands_ExecuteJavaScript +// +message CMsgExecuteJavaScript +{ + optional uint32 browser_handle = 1; + optional string script = 2; +} + + +// +// tell it that it has key focus - eHTMLCommands_SetFocus +// +message CMsgSetFocus +{ + optional uint32 browser_handle = 1; + optional bool focus = 2; +} + + +// +// how big is the scroll bar plz - eHTMLCommands_HorizontalScrollBarSize +// +message CMsgHorizontalScrollBarSize +{ + optional uint32 browser_handle = 1; +} + + +// +// its this big! - eHTMLCommands_HorizontalScrollBarSizeResponse +// +message CMsgHorizontalScrollBarSizeResponse +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; + optional uint32 wide = 4; + optional uint32 tall = 5; + optional uint32 scroll_max = 6; + optional uint32 scroll = 7; + optional float zoom = 8; + optional bool visible = 9; +} + + +// +// eHTMLCommands_VerticalScrollBarSize +// +message CMsgVerticalScrollBarSize +{ + optional uint32 browser_handle = 1; +} + + +// +// eHTMLCommands_VerticalScrollBarSizeResponse +// +message CMsgVerticalScrollBarSizeResponse +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; + optional uint32 wide = 4; + optional uint32 tall = 5; + optional uint32 scroll_max = 6; + optional uint32 scroll = 7; + optional float zoom = 8; + optional bool visible = 9; +} + + +// +// find this string in the page - eHTMLCommands_Find +// +message CMsgFind +{ + optional uint32 browser_handle = 1; + optional string find = 2; + optional bool infind = 3; + optional bool reverse = 4 [ default = false ]; +} + +// +// done finding - eHTMLCommands_StopFind +// +message CMsgStopFind +{ + optional uint32 browser_handle = 1; +} + +// +// scroll here - eHTMLCommands_SetHorizontalScroll +// +message CMsgSetHorizontalScroll +{ + optional uint32 browser_handle = 1; + optional uint32 scroll = 2; +} + + +// +// scroll here - eHTMLCommands_SetHorizontalScroll +// +message CMsgSetVerticalScroll +{ + optional uint32 browser_handle = 1; + optional uint32 scroll = 2; +} + + +// +// zoom the page this much, 0 to 100 - eHTMLCommands_SetZoomLevel +// +message CMsgSetZoomLevel +{ + optional uint32 browser_handle = 1; + optional uint32 zoom = 2; +} + + +// +// look at the page source in notepad - eHTMLCommands_ViewSource +// +message CMsgViewSource +{ + optional uint32 browser_handle = 1; +} + + +// +// browser is setup and ready to load pages after a create - eHTMLCommands_BrowserReady +// +message CMsgBrowserReady +{ + optional uint32 browser_handle = 1; +} + + +// +// new url loaded - eHTMLCommands_URLChanged +// +message CMsgURLChanged +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string postData = 3; + optional bool bIsRedirect = 4; + optional string pagetitle = 5; + optional bool bNewNavigation = 6; +} + + +message CHTMLHeader +{ + optional string key = 1; + optional string value = 2; +} + +message CHTMLPageSecurityInfo +{ + optional bool bIsSecure = 1 [default = false]; + optional bool bHasCertError = 2 [default = false]; + optional string issuerName = 3 [default = ""]; + optional string certName = 4 [default = "" ]; + optional int32 certExpiry = 5 [default = 0]; + optional int32 nCertBits = 6 [default = 0]; + optional bool bIsEVCert = 7 [default = false]; + +} + +// +// finished loading a page - eHTMLCommands_FinishedRequest +// +message CMsgFinishedRequest +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string pageTitle = 3; + optional CHTMLPageSecurityInfo security_info = 4; + repeated CHTMLHeader headers = 5; +} + + +// +// starting a page load - eHTMLCommands_StartRequest +// +message CMsgStartRequest +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string target = 3; + optional string postData = 4; + optional bool bIsRedirect = 5; +} + + +// +// do we want to allow this load - eHTMLCommands_StartRequestResponse +// +message CMsgStartRequestResponse +{ + optional uint32 browser_handle = 1; + optional bool bAllow = 2; +} + + +// +// a html popup is showing - eHTMLCommands_ShowPopup +// +message CMsgShowPopup +{ + optional uint32 browser_handle = 1; +} + + +// +// done with the popup - eHTMLCommands_HidePopup +// +message CMsgHidePopup +{ + optional uint32 browser_handle = 1; +} + + +// +// a html popup is changing size - eHTMLCommands_SizePopup +// +message CMsgSizePopup +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; + optional uint32 wide = 4; + optional uint32 tall = 5; +} + + +// +// new tab plz - eHTMLCommands_OpenNewTab +// +message CMsgOpenNewTab +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional bool bForeground = 3; +} + + +// +// do we allow the tab - eHTMLCommands_OpenNewTabResponse +// +message CMsgOpenNewTabResponse +{ + optional uint32 browser_handle = 1; + optional bool bAllow = 2; +} + + +// +// popup a new page here please - eHTMLCommands_PopupHTMLWindow +// +message CMsgPopupHTMLWindow +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional uint32 x = 3; + optional uint32 y = 4; + optional uint32 wide = 5; + optional uint32 tall = 6; +} + + +// +// do we allow the popup - eHTMLCommands_PopupHTMLWindowResponse +// +message CMsgPopupHTMLWindowResponse +{ + optional uint32 browser_handle = 1; + optional bool bAllow = 2; +} + + +// +// title for the page - eHTMLCommands_SetHTMLTitle +// +message CMsgSetHTMLTitle +{ + optional uint32 browser_handle = 1; + optional string title = 2; +} + +// +// loading a url on a page - eHTMLCommands_LoadingResource +// +message CMsgLoadingResource +{ + optional uint32 browser_handle = 1; + optional string url = 2; +} + +// +// status to display - eHTMLCommands_StatusText +// +message CMsgStatusText +{ + optional uint32 browser_handle = 1; + optional string text = 2; +} + +// +// mouse cursor to this - eHTMLCommands_SetCursor +// +message CMsgSetCursor +{ + optional uint32 browser_handle = 1; + optional uint32 cursor = 2; + optional uint32 data = 3; + optional uint32 wide = 4; + optional uint32 tall = 5; + optional uint32 xhotspot = 6; + optional uint32 yhotspot = 7; +} + +// +// let the user pick a file - eHTMLCommands_FileLoadDialog +// +message CMsgFileLoadDialog +{ + optional uint32 browser_handle = 1; + optional string title = 2; + optional string initialFile = 3; +} + +// +// the user picked this - eHTMLCommands_FileLoadDialogResponse +// +message CMsgFileLoadDialogResponse +{ + optional uint32 browser_handle = 1; + repeated string files = 2; +} + + +// +// show a tooltip - eHTMLCommands_ShowToolTip +// +message CMsgShowToolTip +{ + optional uint32 browser_handle = 1; + optional string text = 2; +} + + +// +// update tooltip - eHTMLCommands_UpdateToolTip +// +message CMsgUpdateToolTip +{ + optional uint32 browser_handle = 1; + optional string text = 2; +} + + +// +// done with tooltip - eHTMLCommands_HideToolTip +// +message CMsgHideToolTip +{ + optional uint32 browser_handle = 1; +} + + +// +// got search answers - eHTMLCommands_SearchResults +// +message CMsgSearchResults +{ + optional uint32 browser_handle = 1; + optional int32 activeMatch = 2; + optional int32 results = 3; +} + + +// +// close this window plz - eHTMLCommands_Close +// +message CMsgClose +{ + optional uint32 browser_handle = 1; +} + + +// +// need image for the page - eHTMLCommands_NeedsPaint +// +message CMsgNeedsPaint +{ + optional uint32 browser_handle = 1; + optional uint64 rgba = 2; + optional uint32 wide = 3; + optional uint32 tall = 4; + optional uint32 textureid = 5; + optional uint32 updatex = 6; + optional uint32 updatey = 7; + optional uint32 updatewide = 8; + optional uint32 updatetall = 9; + optional uint32 scrollx = 10; + optional uint32 scrolly = 11; + + optional uint64 combobox_rgba = 12 [default = 0]; + optional uint32 combobox_wide = 13 [default = 0]; + optional uint32 combobox_tall = 14 [default = 0]; + + optional uint32 pageserial = 15; +} + + +// +// all done with the paint pointer - eHTMLCommands_NeedsPaintResponse +// +message CMsgNeedsPaintResponse +{ + optional uint32 browser_handle = 1; + optional uint32 textureid = 2; +} + +// +// what zoom lvl we at? - eHTMLCommands_GetZoom +// +message CMsgGetZoom +{ + optional uint32 browser_handle = 1; +} + + +// +// this zoom level! - eHTMLCommands_GetZoomResponse +// +message CMsgGetZoomResponse +{ + optional uint32 browser_handle = 1; + optional float zoom = 2; +} + + +// +// get the link at this x,y - eHTMLCommands_LinkAtPosition +// +message CMsgLinkAtPosition +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; +} + + +// +// link at this pos - eHTMLCommands_LinkAtPosition +// +message CMsgLinkAtPositionResponse +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; + optional string url = 4; + optional bool blivelink = 5; + optional bool binput = 6; +} + + +// +// scale the page to the element at this position on the page, for at least this size +// +message CMsgZoomToElementAtPosition +{ + optional uint32 browser_handle = 1; + optional uint32 x = 2; + optional uint32 y = 3; +} + +// +// response from the zoom, what rect did we pick and what zoom factor +// +message CMsgZoomToElementAtPositionResponse +{ + optional uint32 browser_handle = 1; + optional sint32 initial_x = 2; + optional sint32 initial_y = 3; + optional uint32 initial_width = 4; + optional uint32 initial_height = 5; + optional sint32 final_x = 6; + optional sint32 final_y = 7; + optional uint32 final_width = 8; + optional uint32 final_height = 9; + optional float zoom = 10; +} + + +// +// increase (or decrease if negative) the page scale factor used on this page +// +message CMsgScalePageToValue +{ + optional uint32 browser_handle = 1; + optional float scale = 2; + optional float x = 3; + optional float y = 4; +} + + +// +// increase (or decrease if negative) the page scale factor used on this page +// +message CMsgScalePageToValueResponse +{ + optional uint32 browser_handle = 1; + optional float zoom = 2; + optional int32 width_delta = 3; + optional int32 height_delta = 4; +} + +// +// request a screenshot get written for this loaded url +// +message CMsgSavePageToJPEG +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string filename = 3; + optional uint32 width = 4; + optional uint32 height = 5; +} + + +// +// screenshot taken, tell the main thread we did it +// +message CMsgSavePageToJPEGResponse +{ + optional uint32 browser_handle = 1; + optional string url = 2; + optional string filename = 3; +} + + +// +// web control wants to pop an alert dialog +// +message CMsgJSAlert +{ + optional uint32 browser_handle = 1; + optional string message = 2; +} + +// +// web control wants to pop an confirmation dialog +// +message CMsgJSConfirm +{ + optional uint32 browser_handle = 1; + optional string message = 2; +} + + +// +// done showing the confirmation +// +message CMsgJSDialogResponse +{ + optional uint32 browser_handle = 1; + optional bool result = 2; +} + +// +// web control telling us the forward and back state +// +message CMsgCanGoBackAndForward +{ + optional uint32 browser_handle = 1; + optional bool bgoback = 2; + optional bool bgoforward = 3; +} + +// +// web control telling us to open a steam dialog +// +message CMsgOpenSteamURL +{ + optional uint32 browser_handle = 1; + optional string url = 2; +} + + +// +// set a cookie for the cef instance +// +message CMsgSetCookie +{ + optional string key = 1; + optional string value = 2; + optional string path = 3; + optional string host = 4; + optional uint32 expires = 5; +} + + +// +// tell cef that html isn't active so run slow +// +message CMsgSetTargetFrameRate +{ + optional uint32 nTargetFrameRate = 1; // FPS to run the CEF think loop at +} + + +// +// request a full repaint of the control +// +message CMsgFullRepaint +{ + optional uint32 browser_handle = 1; +} + + +// +// CEF wants to go fullscreen please +// +message CMsgRequestFullScreen +{ + optional uint32 browser_handle = 1; +} + + +// +// do we allow fullscreen +// +message CMsgRequestFullScreenResponse +{ + optional uint32 browser_handle = 1; + optional bool ballow = 2; +} + + +// +// exit fullscreen if we are in it +// +message CMsgExitFullScreen +{ + optional uint32 browser_handle = 1; +} + + +// +// request all the cookies for this url +// +message CMsgGetCookiesForURL +{ + optional uint32 browser_handle = 1; + optional string url = 2; +} + + +message CCookie +{ + optional string name = 1; + optional string value = 2; + optional string domain = 3; + optional string path = 4; +} + + +// +// return all the cookies for this url +// +message CMsgGetCookiesForURLResponse +{ + optional uint32 browser_handle = 1; + optional string url = 2; + repeated CCookie cookies = 3; +} + + +// +// sent when a html node gets key focus +// +message CMsgNodeHasFocus +{ + optional uint32 browser_handle = 1; + optional bool bInput = 2; + optional string name = 3; + optional string elementtagname = 4; + optional string searchbuttontext = 5; + optional bool bHasMultipleInputs = 6; + optional string input_type = 7; // type of input, if node is input; otherwise unset +} + + +// +// zoom the html control to the node with input focus +// +message CMsgZoomToFocusedElement +{ + optional uint32 browser_handle = 1; + optional uint32 leftoffset = 2 [default = 0]; + optional uint32 topoffset = 3 [default = 0]; +} + + +// +// ask a fullscreen flash control to close if open +// +message CMsgCloseFullScreenFlashIfOpen +{ + optional uint32 browser_handle = 1; +} + +// +// ask a fullscreen flash control to pause itself if open +// +message CMsgPauseFullScreenFlashMovieIfOpen +{ + optional uint32 browser_handle = 1; +} + + +// +// get the string currently contained in the focused node +// +message CMsgFocusedNodeText +{ + optional uint32 browser_handle = 1; +} + + +// +// what text is in the focused node +// +message CMsgFocusedNodeTextResponse +{ + optional uint32 browser_handle = 1; + optional string value = 2; +} diff --git a/vgui2/chromehtml/stdafx.h b/vgui2/chromehtml/stdafx.h new file mode 100644 index 00000000..9f38e71f --- /dev/null +++ b/vgui2/chromehtml/stdafx.h @@ -0,0 +1,19 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef STDAFX_H +#define STDAFX_H + +#include "tier0/platform.h" +#include "tier0/vprof.h" +#include "tier1/utlarray.h" +#include "tier1/utlbuffer.h" +#include "fileio.h" +//#include "constants.h" +#include "steam/steamtypes.h" +#include "tier0/validator.h" +#include "tier1/utlmap.h" +#include "tier1/utlstring.h" +#include "tier0/tslist.h" +#include "html/ihtmlchrome.h" +#include "html/htmlprotobuf.h" + +#endif diff --git a/vgui2/vgui_controls/AnimationController.cpp b/vgui2/vgui_controls/AnimationController.cpp index b8780a89..fd182221 100644 --- a/vgui2/vgui_controls/AnimationController.cpp +++ b/vgui2/vgui_controls/AnimationController.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // //=============================================================================// #pragma warning( disable : 4244 ) // conversion from 'double' to 'float', possible loss of data @@ -31,6 +31,11 @@ using namespace vgui; static CUtlSymbolTable g_ScriptSymbols(0, 128, true); +#ifdef MAPBASE +// Allows animation sequences to be overridden by map-specific files +bool g_bUsingCustomHudAnimations; +#endif + // singleton accessor for animation controller for use by the vgui controls namespace vgui { @@ -59,8 +64,8 @@ AnimationController::AnimationController(Panel *parent) : BaseClass(parent, NULL // get the names of common types m_sPosition = g_ScriptSymbols.AddString("position"); - m_sSize = g_ScriptSymbols.AddString("size"); - m_sFgColor = g_ScriptSymbols.AddString("fgcolor"); + m_sSize = g_ScriptSymbols.AddString("size"); + m_sFgColor = g_ScriptSymbols.AddString("fgcolor"); m_sBgColor = g_ScriptSymbols.AddString("bgcolor"); m_sXPos = g_ScriptSymbols.AddString("xpos"); @@ -68,8 +73,6 @@ AnimationController::AnimationController(Panel *parent) : BaseClass(parent, NULL m_sWide = g_ScriptSymbols.AddString("wide"); m_sTall = g_ScriptSymbols.AddString("tall"); - m_sModelPos = g_ScriptSymbols.AddString( "model_pos" ); - m_flCurrentTime = 0.0f; } @@ -116,7 +119,7 @@ void AnimationController::ReloadScriptFile() { // Clear all current sequences m_Sequences.RemoveAll(); - + UpdateScreenSize(); // Reload each file we've loaded @@ -188,7 +191,7 @@ AnimationController::RelativeAlignmentLookup AnimationController::g_AlignmentLoo }; //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- AnimationController::RelativeAlignment AnimationController::LookupAlignment( char const *token ) { @@ -206,7 +209,7 @@ AnimationController::RelativeAlignment AnimationController::LookupAlignment( cha } //----------------------------------------------------------------------------- -// Purpose: Parse position including right edge and center adjustment out of a +// Purpose: Parse position including right edge and center adjustment out of a // token. This is relative to the screen //----------------------------------------------------------------------------- void AnimationController::SetupPosition( AnimCmdAnimate_t& cmd, float *output, char const *psz, int screendimension ) @@ -239,7 +242,7 @@ void AnimationController::SetupPosition( AnimCmdAnimate_t& cmd, float *output, c if ( Q_strlen( panelName ) > 0 ) { - // + // cmd.align.relativePosition = true; cmd.align.alignPanel = g_ScriptSymbols.AddString(panelName); cmd.align.alignment = ra; @@ -318,19 +321,48 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) Warning("Couldn't parse script file: expected , found nothing\n"); return false; } - - int seqIndex; + + int seqIndex = -1; UtlSymId_t nameIndex = g_ScriptSymbols.AddString(token); - - // Create a new sequence - seqIndex = m_Sequences.AddToTail(); + +#ifdef MAPBASE + if (g_bUsingCustomHudAnimations) + { + // look through for the sequence + for (seqIndex = 0; seqIndex < m_Sequences.Count(); seqIndex++) + { + if (m_Sequences[seqIndex].name == nameIndex) + break; + } + + if (seqIndex >= m_Sequences.Count()) + seqIndex = -1; + else + { + // Clear some stuff + m_Sequences[seqIndex].cmdList.RemoveAll(); + } + } + + if (seqIndex == -1) +#endif + { + // Create a new sequence + seqIndex = m_Sequences.AddToTail(); + } + AnimSequence_t &seq = m_Sequences[seqIndex]; seq.name = nameIndex; seq.duration = 0.0f; // get the open brace or a conditional pMem = ParseFile(pMem, token, NULL); +#ifdef MAPBASE + // Fixes ! conditionals + if ( Q_stristr( token, "[$" ) || Q_stristr( token, "[!$" ) ) +#else if ( Q_stristr( token, "[$" ) ) +#endif { bAccepted = EvaluateConditional( token ); @@ -395,16 +427,16 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) // XPos and YPos both use target ".a" SetupPosition( cmdAnimate, &cmdAnimate.target.a, token, screenTall ); } - else + else { // parse the floating point values right out if (0 == sscanf(token, "%f %f %f %f", &cmdAnimate.target.a, &cmdAnimate.target.b, &cmdAnimate.target.c, &cmdAnimate.target.d)) { //============================================================================= // HPE_BEGIN: - // [pfreese] Improved handling colors not defined in scheme + // [pfreese] Improved handling colors not defined in scheme //============================================================================= - + // could be referencing a value in the scheme file, lookup Color default_invisible_black(0, 0, 0, 0); Color col = scheme->GetColor(token, default_invisible_black); @@ -423,7 +455,7 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) // Warning("Missing color in scheme: %s\n", token); // } } - + //============================================================================= // HPE_END //============================================================================= @@ -453,7 +485,7 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) cmdAnimate.target.a = static_cast( vgui::scheme()->GetProportionalScaledValueEx(GetScheme(), cmdAnimate.target.a) ); } } - + // interpolation function pMem = ParseFile(pMem, token, NULL); if (!stricmp(token, "Accel")) @@ -510,34 +542,6 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) pMem = ParseFile(pMem, token, NULL); animCmd.cmdData.runEvent.timeDelay = (float)atof(token); } - else if (!stricmp(token, "runeventchild")) - { - animCmd.commandType = CMD_RUNEVENTCHILD; - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.variable = g_ScriptSymbols.AddString(token); - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.event = g_ScriptSymbols.AddString(token); - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.timeDelay = (float)atof(token); - } - else if (!stricmp(token, "firecommand")) - { - animCmd.commandType = CMD_FIRECOMMAND; - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.timeDelay = (float)atof(token); - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.variable = g_ScriptSymbols.AddString(token); - } - else if (!stricmp(token, "setvisible")) - { - animCmd.commandType = CMD_SETVISIBLE; - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.variable = g_ScriptSymbols.AddString(token); - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.variable2 = atoi(token); - pMem = ParseFile(pMem, token, NULL); - animCmd.cmdData.runEvent.timeDelay = (float)atof(token); - } else if (!stricmp(token, "stopevent")) { animCmd.commandType = CMD_STOPEVENT; @@ -620,10 +624,15 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) Warning("Couldn't parse script sequence '%s': expected , found '%s'\n", g_ScriptSymbols.String(seq.name), token); return false; } - + // Look ahead one token for a conditional char *peek = ParseFile(pMem, token, NULL); +#ifdef MAPBASE + // Fixes ! conditionals + if ( Q_stristr( token, "[$" ) || Q_stristr( token, "[!$" ) ) +#else if ( Q_stristr( token, "[$" ) ) +#endif { if ( !EvaluateConditional( token ) ) { @@ -637,7 +646,7 @@ bool AnimationController::ParseScriptFile(char *pMem, int length) { // Attempt to find a collision in the sequences, replacing the old one if found int seqIterator; - for ( seqIterator = 0; seqIterator < m_Sequences.Count()-1; seqIterator++ ) + for ( seqIterator = 0; seqIterator < m_Sequences.Count()-1; seqIterator++ ) { if ( m_Sequences[seqIterator].name == nameIndex ) { @@ -689,28 +698,9 @@ void AnimationController::UpdatePostedMessages(bool bRunToCompletion) case CMD_RUNEVENT: { RanEvent_t curEvent; - curEvent.pParent = NULL; curEvent.event = msg.event; - curEvent.pParent = msg.parent.Get(); - - // run the event, but only if we haven't already run it this frame, for this parent - if (!eventsRanThisFrame.HasElement(curEvent)) - { - eventsRanThisFrame.AddToTail(curEvent); - RunCmd_RunEvent(msg); - } - } - break; - case CMD_RUNEVENTCHILD: - { - RanEvent_t curEvent; - curEvent.pParent = NULL; - curEvent.event = msg.event; - curEvent.pParent = msg.parent.Get()->FindChildByName( g_ScriptSymbols.String(msg.variable) ); - msg.parent = curEvent.pParent; - // run the event, but only if we haven't already run it this frame, for this parent if (!eventsRanThisFrame.HasElement(curEvent)) { @@ -719,20 +709,6 @@ void AnimationController::UpdatePostedMessages(bool bRunToCompletion) } } break; - case CMD_FIRECOMMAND: - { - msg.parent->OnCommand( g_ScriptSymbols.String(msg.variable) ); - } - break; - case CMD_SETVISIBLE: - { - Panel* pPanel = msg.parent.Get()->FindChildByName( g_ScriptSymbols.String(msg.variable) ); - if ( pPanel ) - { - pPanel->SetVisible( msg.variable2 == 1 ); - } - } - break; case CMD_STOPEVENT: RunCmd_StopEvent(msg); break; @@ -828,9 +804,9 @@ bool AnimationController::UpdateScreenSize() surface()->GetScreenSize(screenWide, screenTall); } - bool changed = m_nScreenBounds[ 0 ] != sx || + bool changed = m_nScreenBounds[ 0 ] != sx || m_nScreenBounds[ 1 ] != sy || - m_nScreenBounds[ 2 ] != screenWide || + m_nScreenBounds[ 2 ] != screenWide || m_nScreenBounds[ 3 ] != screenTall; m_nScreenBounds[ 0 ] = sx; @@ -961,7 +937,7 @@ void AnimationController::SetAutoReloadScript(bool state) //----------------------------------------------------------------------------- bool AnimationController::StartAnimationSequence(const char *sequenceName) { - // We support calling an animation on elements that are not the calling + // We support calling an animation on elements that are not the calling // panel's children. Use the base parent to start the search. return StartAnimationSequence( GetParent(), sequenceName ); @@ -1006,66 +982,9 @@ bool AnimationController::StartAnimationSequence(Panel *pWithinParent, const cha ExecAnimationCommand(seqName, m_Sequences[i].cmdList[cmdIndex], pWithinParent); } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: stops an animation sequence script -//----------------------------------------------------------------------------- -bool AnimationController::StopAnimationSequence( Panel *pWithinParent, const char *sequenceName ) -{ - Assert( pWithinParent ); - - // lookup the symbol for the name - UtlSymId_t seqName = g_ScriptSymbols.Find( sequenceName ); - if (seqName == UTL_INVAL_SYMBOL) - return false; - - // remove the existing command from the queue - RemoveQueuedAnimationCommands( seqName, pWithinParent ); - return true; } -//----------------------------------------------------------------------------- -// Purpose: Runs a custom command from code, not from a script file -//----------------------------------------------------------------------------- -void AnimationController::CancelAnimationsForPanel( Panel *pWithinParent ) -{ - // Msg("Removing queued anims for sequence %s\n", g_ScriptSymbols.String(seqName)); - - // remove messages posted by this sequence - // if pWithinParent is specified, remove only messages under that parent - { - for (int i = 0; i < m_PostedMessages.Count(); i++) - { - if ( m_PostedMessages[i].parent == pWithinParent ) - { - m_PostedMessages.Remove(i); - --i; - } - } - } - - // remove all animations - // if pWithinParent is specified, remove only animations under that parent - for (int i = 0; i < m_ActiveAnimations.Count(); i++) - { - Panel *animPanel = m_ActiveAnimations[i].panel; - - if ( !animPanel ) - continue; - - Panel *foundPanel = pWithinParent->FindChildByName(animPanel->GetName(),true); - - if ( foundPanel != animPanel ) - continue; - - m_ActiveAnimations.Remove(i); - --i; - } -} - //----------------------------------------------------------------------------- // Purpose: Runs a custom command from code, not from a script file //----------------------------------------------------------------------------- @@ -1299,7 +1218,7 @@ void AnimationController::RunCmd_StopPanelAnimations(PostedMessage_t &msg) if (!panel) return; - // loop through all the active animations cancelling any that + // loop through all the active animations cancelling any that // are operating on said panel, except for the event specified for (int i = 0; i < m_ActiveAnimations.Count(); i++) { @@ -1325,7 +1244,7 @@ void AnimationController::RunCmd_StopAnimation(PostedMessage_t &msg) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void AnimationController::RunCmd_SetFont( PostedMessage_t &msg ) { @@ -1351,7 +1270,7 @@ void AnimationController::RunCmd_SetFont( PostedMessage_t &msg ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void AnimationController::RunCmd_SetTexture( PostedMessage_t &msg ) { @@ -1370,7 +1289,7 @@ void AnimationController::RunCmd_SetTexture( PostedMessage_t &msg ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void AnimationController::RunCmd_SetString( PostedMessage_t &msg ) { @@ -1389,7 +1308,7 @@ void AnimationController::RunCmd_SetString( PostedMessage_t &msg ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int AnimationController::GetRelativeOffset( AnimAlign_t& align, bool xcoord ) { @@ -1673,7 +1592,7 @@ PanelAnimationMap *CPanelAnimationDictionary::FindPanelAnimationMap( char const } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- PanelAnimationMap *CPanelAnimationDictionary::FindOrAddPanelAnimationMap( char const *className ) { @@ -1690,7 +1609,7 @@ PanelAnimationMap *CPanelAnimationDictionary::FindOrAddPanelAnimationMap( char c } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CPanelAnimationDictionary::PanelAnimationDumpMap( PanelAnimationMap *map, bool recursive ) { @@ -1712,7 +1631,7 @@ void CPanelAnimationDictionary::PanelAnimationDumpMap( PanelAnimationMap *map, b } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void CPanelAnimationDictionary::PanelAnimationDumpVars( char const *className ) { @@ -1747,7 +1666,7 @@ CPanelAnimationDictionary& GetPanelAnimationDictionary() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- PanelAnimationMap *FindOrAddPanelAnimationMap( char const *className ) { @@ -1763,9 +1682,9 @@ PanelAnimationMap *FindPanelAnimationMap( char const *className ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void PanelAnimationDumpVars( char const *className ) { GetPanelAnimationDictionary().PanelAnimationDumpVars( className ); -} \ No newline at end of file +} diff --git a/vgui2/vgui_controls/BitmapImagePanel.cpp b/vgui2/vgui_controls/BitmapImagePanel.cpp index 7e76a3cc..b8140d25 100644 --- a/vgui2/vgui_controls/BitmapImagePanel.cpp +++ b/vgui2/vgui_controls/BitmapImagePanel.cpp @@ -17,7 +17,7 @@ #include "tier0/memdbgon.h" #ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif using namespace vgui; @@ -95,7 +95,7 @@ void CBitmapImagePanel::ComputeImagePosition(int &x, int &y, int &w, int &h) { float xScale = (float)panelWide / (float)imageWide; float yScale = (float)panelTall / (float)imageTall; - float scale = min( xScale, yScale ); + float scale = MIN( xScale, yScale ); w = (int) (imageWide * scale); h = (int) (imageTall * scale); diff --git a/vgui2/vgui_controls/BuildGroup.cpp b/vgui2/vgui_controls/BuildGroup.cpp index 749a20c9..e52c3dcd 100644 --- a/vgui2/vgui_controls/BuildGroup.cpp +++ b/vgui2/vgui_controls/BuildGroup.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ // //=============================================================================// - //========= Copyright 1996-2003, Valve LLC, All rights reserved. ============ + //========= Copyright � 1996-2003, Valve LLC, All rights reserved. ============ // // The copyright to the contents herein is the property of Valve, L.L.C. // The contents may be used and/or copied only with the written permission of @@ -309,8 +309,8 @@ bool BuildGroup::CursorMoved(int x, int y, Panel *panel) if (_dragMouseCode == MOUSE_RIGHT) { - int newW = max( 1, _dragStartPanelSize[ 0 ] + x - _dragStartCursorPos[0] ); - int newH = max( 1, _dragStartPanelSize[ 1 ] + y - _dragStartCursorPos[1] ); + int newW = MAX( 1, _dragStartPanelSize[ 0 ] + x - _dragStartCursorPos[0] ); + int newH = MAX( 1, _dragStartPanelSize[ 1 ] + y - _dragStartCursorPos[1] ); bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ); bool ctrl = ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) ); diff --git a/vgui2/vgui_controls/Button.cpp b/vgui2/vgui_controls/Button.cpp index cceb8043..406c3e13 100644 --- a/vgui2/vgui_controls/Button.cpp +++ b/vgui2/vgui_controls/Button.cpp @@ -695,12 +695,12 @@ void Button::SetMouseClickEnabled(MouseCode code,bool state) if(state) { //set bit to 1 - _mouseClickMask|=1<<((int)(code+1)); + _mouseClickMask|=MouseButtonBit(code); } else { //set bit to 0 - _mouseClickMask&=~(1<<((int)(code+1))); + _mouseClickMask&=~MouseButtonBit(code); } } @@ -709,7 +709,7 @@ void Button::SetMouseClickEnabled(MouseCode code,bool state) //----------------------------------------------------------------------------- bool Button::IsMouseClickEnabled(MouseCode code) { - if(_mouseClickMask&(1<<((int)(code+1)))) + if(_mouseClickMask&MouseButtonBit(code)) { return true; } diff --git a/vgui2/vgui_controls/ComboBox.cpp b/vgui2/vgui_controls/ComboBox.cpp index e7d0f86f..bd04a52c 100644 --- a/vgui2/vgui_controls/ComboBox.cpp +++ b/vgui2/vgui_controls/ComboBox.cpp @@ -234,7 +234,7 @@ void ComboBox::RemoveAll() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -int ComboBox::GetItemCount() const +int ComboBox::GetItemCount() { return m_pDropDown->GetItemCount(); } @@ -323,14 +323,14 @@ void ComboBox::PerformLayout() HFont buttonFont = m_pButton->GetFont(); int fontTall = surface()->GetFontTall( buttonFont ); - int buttonSize = min( tall, fontTall ); + int buttonSize = MIN( tall, fontTall ); int buttonY = ( ( tall - 1 ) - buttonSize ) / 2; // Some dropdown button icons in our games are wider than they are taller. We need to factor that in. int button_wide, button_tall; m_pButton->GetContentSize(button_wide, button_tall); - button_wide = max( buttonSize, button_wide ); + button_wide = MAX( buttonSize, button_wide ); m_pButton->SetBounds( wide - button_wide, buttonY, button_wide, buttonSize ); if ( IsEditable() ) diff --git a/vgui2/vgui_controls/Frame.cpp b/vgui2/vgui_controls/Frame.cpp index 35b5d761..8caa230a 100644 --- a/vgui2/vgui_controls/Frame.cpp +++ b/vgui2/vgui_controls/Frame.cpp @@ -2323,8 +2323,8 @@ void Frame::OnScreenSizeChanged(int iOldWide, int iOldTall) } // make sure the top-left is visible - x = max( 0, x ); - y = max( 0, y ); + x = MAX( 0, x ); + y = MAX( 0, y ); // apply SetPos(x, y); diff --git a/vgui2/vgui_controls/HTML.cpp b/vgui2/vgui_controls/HTML.cpp index 1a1ca440..ac8076f2 100644 --- a/vgui2/vgui_controls/HTML.cpp +++ b/vgui2/vgui_controls/HTML.cpp @@ -26,6 +26,9 @@ using namespace vgui; + +const int k_nMaxCustomCursors = 2; // the max number of custom cursors we keep cached PER html control + //----------------------------------------------------------------------------- // Purpose: A simple passthrough panel to render the border onto the HTML widget //----------------------------------------------------------------------------- @@ -45,6 +48,54 @@ class HTMLInterior : public Panel HTML *m_pHTML; }; + +//----------------------------------------------------------------------------- +// Purpose: a vgui container for popup menus displayed by a control, only 1 menu for any control can be visible at a time +//----------------------------------------------------------------------------- +class HTMLComboBoxHost : public vgui::EditablePanel +{ + DECLARE_CLASS_SIMPLE( HTMLComboBoxHost, EditablePanel ); +public: + HTMLComboBoxHost( HTML *parent, const char *panelName ) : EditablePanel( parent, panelName ) + { + m_pParent = parent; + MakePopup(false); + } + ~HTMLComboBoxHost() {} + + virtual void PaintBackground(); + + virtual void OnMousePressed(MouseCode code); + virtual void OnMouseReleased(MouseCode code); + virtual void OnCursorMoved(int x,int y); + virtual void OnMouseDoublePressed(MouseCode code); + virtual void OnKeyTyped(wchar_t unichar); + virtual void OnKeyCodeTyped(KeyCode code); + virtual void OnKeyCodeReleased(KeyCode code); + virtual void OnMouseWheeled(int delta); + + virtual void OnKillFocus() + { + if ( vgui::input()->GetFocus() != m_pParent->GetVPanel() ) // if its not our parent trying to steal focus + { + BaseClass::OnKillFocus(); + if ( m_pParent ) + m_pParent->HidePopup(); + } + } + + virtual void PerformLayout() + { + // no op the perform layout as we just render the html controls popup texture into it + // we don't want the menu logic trying to play with its size + } + + +private: + HTML *m_pParent; +}; + + //----------------------------------------------------------------------------- // Purpose: container class for any external popup windows the browser requests //----------------------------------------------------------------------------- @@ -106,6 +157,9 @@ class HTMLPopup : public vgui::Frame PopupHTML *m_pHTML; }; +// HACKHACK: cant be bothered remaking entire callback system or removing this file +#pragma warning( push ) +#pragma warning( disable : 4355 ) //----------------------------------------------------------------------------- // Purpose: Constructor @@ -117,7 +171,6 @@ m_URLChanged( this, &HTML::BrowserURLChanged ), m_FinishedRequest( this, &HTML::BrowserFinishedRequest ), m_LinkInNewTab( this, &HTML::BrowserOpenNewTab ), m_ChangeTitle( this, &HTML::BrowserSetHTMLTitle ), -m_NewWindow( this, &HTML::BrowserPopupHTMLWindow ), m_FileLoadDialog( this, &HTML::BrowserFileLoadDialog ), m_SearchResults( this, &HTML::BrowserSearchResults ), m_CloseBrowser( this, &HTML::BrowserClose ), @@ -127,6 +180,7 @@ m_LinkAtPosResp( this, &HTML::BrowserLinkAtPositionResponse ), m_JSAlert( this, &HTML::BrowserJSAlert ), m_JSConfirm( this, &HTML::BrowserJSConfirm ), m_CanGoBackForward( this, &HTML::BrowserCanGoBackandForward ), +m_NewWindow( this, &HTML::BrowserPopupHTMLWindow ), m_SetCursor( this, &HTML::BrowserSetCursor ), m_StatusText( this, &HTML::BrowserStatusText ), m_ShowTooltip( this, &HTML::BrowserShowToolTip ), @@ -134,6 +188,7 @@ m_UpdateTooltip( this, &HTML::BrowserUpdateToolTip ), m_HideTooltip( this, &HTML::BrowserHideToolTip ) { m_iHTMLTextureID = 0; + m_iComboBoxTextureID = 0; m_bCanGoBack = false; m_bCanGoForward = false; m_bInFind = false; @@ -177,6 +232,10 @@ m_HideTooltip( this, &HTML::BrowserHideToolTip ) m_pFindBar = new HTML::CHTMLFindBar( this ); m_pFindBar->SetZPos( 2 ); m_pFindBar->SetVisible( false ); + + m_pComboBoxHost = new HTMLComboBoxHost( this, "ComboBoxHost" ); + m_pComboBoxHost->SetPaintBackgroundEnabled( true ); + m_pComboBoxHost->SetVisible( false ); m_pContextMenu = new Menu( this, "contextmenu" ); m_pContextMenu->AddMenuItem( "#vgui_HTMLBack", new KeyValues( "Command", "command", "back" ), this ); @@ -192,6 +251,7 @@ m_HideTooltip( this, &HTML::BrowserHideToolTip ) m_nViewSourceAllowedIndex = m_pContextMenu->AddMenuItem( "#vgui_HTMLViewSource", new KeyValues( "Command", "command", "viewsource" ), this ); } +#pragma warning( pop ) //----------------------------------------------------------------------------- // Purpose: browser is ready to show pages @@ -289,6 +349,36 @@ void HTML::Paint() } } + +//----------------------------------------------------------------------------- +// Purpose: paint the combo box texture if we have one +//----------------------------------------------------------------------------- +void HTML::PaintComboBox() +{ + BaseClass::Paint(); + if ( m_iComboBoxTextureID != 0 ) + { + surface()->DrawSetTexture( m_iComboBoxTextureID ); + surface()->DrawSetColor( Color( 255, 255, 255, 255 ) ); + int tw = m_allocedComboBoxWidth; + int tt = m_allocedComboBoxHeight; + surface()->DrawTexturedRect( 0, 0, tw, tt ); + } + +} + + +//----------------------------------------------------------------------------- +// Purpose: overrides panel class, paints a texture of the HTML window as a background +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::PaintBackground() +{ + BaseClass::PaintBackground(); + + m_pParent->PaintComboBox(); +} + + //----------------------------------------------------------------------------- // Purpose: causes a repaint when the layout changes //----------------------------------------------------------------------------- @@ -341,6 +431,11 @@ void HTML::OnMove() // tell cef where we are on the screen so plugins can correctly render int nPanelAbsX, nPanelAbsY; ipanel()->GetAbsPos( GetVPanel(), nPanelAbsX, nPanelAbsY ); + + if ( m_pComboBoxHost && m_pComboBoxHost->IsVisible() ) + { + m_pComboBoxHost->SetVisible( false ); + } } @@ -579,7 +674,7 @@ void HTML::OnMouseReleased(MouseCode code) input()->SetMouseCapture( NULL ); input()->SetCursorOveride( 0 ); - if ( !m_sDragURL.IsEmpty() && input()->GetMouseOver() != GetVPanel() && input()->GetMouseOver() ) + if ( !m_sDragURL.IsEmpty() && input()->GetMouseOver() != GetVPanel() && input()->GetMouseOver() != NULL ) { // post the text as a drag drop to the target panel KeyValuesAD kv( "DragDrop" ); @@ -614,7 +709,7 @@ void HTML::OnCursorMoved(int x,int y) } else if ( !m_sDragURL.IsEmpty() ) { - if ( !input()->GetMouseOver() ) + if ( input()->GetMouseOver() == NULL ) { // we're not over any vgui window, switch to the OS implementation of drag/drop // BR FIXME @@ -830,8 +925,8 @@ void HTML::OnKeyCodeReleased(KeyCode code) // Purpose: scrolls the vertical scroll bar on a web page //----------------------------------------------------------------------------- void HTML::OnMouseWheeled(int delta) -{ - if (_vbar ) +{ + if (_vbar && ( ( m_pComboBoxHost && !m_pComboBoxHost->IsVisible() ) ) ) { int val = _vbar->GetValue(); val -= (delta * 100.0/3.0 ); // 100 for every 3 lines matches chromes code @@ -1025,12 +1120,16 @@ void HTML::OnSetFocus() //----------------------------------------------------------------------------- void HTML::OnKillFocus() { - BaseClass::OnKillFocus(); + if ( vgui::input()->GetFocus() != m_pComboBoxHost->GetVPanel() ) // if its not the menu stealing our focus + BaseClass::OnKillFocus(); // Don't clear the actual html focus if a context menu is what took focus if ( m_pContextMenu->HasFocus() ) return; + if ( m_pComboBoxHost->HasFocus() ) + return; + if (m_SteamAPIContext.SteamHTMLSurface()) m_SteamAPIContext.SteamHTMLSurface()->SetKeyFocus( m_unBrowserHandle, false ); } @@ -1180,6 +1279,83 @@ void HTML::OnTextChanged( Panel *pPanel ) Find( rgchText ); } + +//----------------------------------------------------------------------------- +// Purpose: passes mouse clicks to the control +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnMousePressed(MouseCode code) +{ + m_pParent->OnMousePressed(code); +} + + +//----------------------------------------------------------------------------- +// Purpose: passes mouse up events +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnMouseReleased(MouseCode code) +{ + m_pParent->OnMouseReleased(code); +} + + +//----------------------------------------------------------------------------- +// Purpose: keeps track of where the cursor is +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnCursorMoved(int x,int y) +{ + // Only do this when we are over the current panel + if ( vgui::input()->GetMouseOver() == GetVPanel() ) + { + m_pParent->OnHTMLMouseMoved( x, y ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: passes double click events to the browser +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnMouseDoublePressed(MouseCode code) +{ + m_pParent->OnMouseDoublePressed(code); +} + + +//----------------------------------------------------------------------------- +// Purpose: passes key presses to the browser (we don't current do this) +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnKeyTyped(wchar_t unichar) +{ + m_pParent->OnKeyTyped(unichar); +} + + +//----------------------------------------------------------------------------- +// Purpose: passes key presses to the browser +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnKeyCodeTyped(KeyCode code) +{ + m_pParent->OnKeyCodeTyped(code); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnKeyCodeReleased(KeyCode code) +{ + m_pParent->OnKeyCodeReleased(code); +} + + +//----------------------------------------------------------------------------- +// Purpose: scrolls the vertical scroll bar on a web page +//----------------------------------------------------------------------------- +void HTMLComboBoxHost::OnMouseWheeled(int delta) +{ + m_pParent->OnMouseWheeled( delta ); +} + + //----------------------------------------------------------------------------- // Purpose: helper class for the find bar //----------------------------------------------------------------------------- @@ -1265,6 +1441,7 @@ void HTML::BrowserNeedsPaint( HTML_NeedsPaint_t *pCallback ) Repaint(); } + //----------------------------------------------------------------------------- // Purpose: browser wants to start loading this url, do we let it? //----------------------------------------------------------------------------- @@ -1366,6 +1543,16 @@ void HTML::BrowserFinishedRequest( HTML_FinishedRequest_t *pCmd ) OnFinishRequest( pCmd->pchURL, pCmd->pchPageTitle, mapHeaders ); } + +//----------------------------------------------------------------------------- +// Purpose: hide the popup +//----------------------------------------------------------------------------- +void HTML::HidePopup() +{ + m_pComboBoxHost->SetVisible( false ); +} + + //----------------------------------------------------------------------------- // Purpose: browser wants to open a new tab //----------------------------------------------------------------------------- @@ -1375,8 +1562,9 @@ void HTML::BrowserOpenNewTab( HTML_OpenLinkInNewTab_t *pCmd ) // Not suppored by default, if a child class overrides us and knows how to handle tabs, then it can do this. } + //----------------------------------------------------------------------------- -// Purpose: display a new html window +// Purpose: display a new html window //----------------------------------------------------------------------------- void HTML::BrowserPopupHTMLWindow( HTML_NewWindow_t *pCmd ) { diff --git a/vgui2/vgui_controls/Label.cpp b/vgui2/vgui_controls/Label.cpp index 2178f390..3d94e790 100644 --- a/vgui2/vgui_controls/Label.cpp +++ b/vgui2/vgui_controls/Label.cpp @@ -28,7 +28,7 @@ using namespace vgui; #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif DECLARE_BUILD_FACTORY_DEFAULT_TEXT( Label, Label ); @@ -142,7 +142,7 @@ void Label::GetContentSize(int &wide, int &tall) for (int i=0; i < _imageDar.Size(); i++) wide += _imageDar[i].offset; - tall = max((ty1 - ty0) + _textInset[1], iTall); + tall = MAX((ty1 - ty0) + _textInset[1], iTall); } //----------------------------------------------------------------------------- @@ -361,14 +361,8 @@ void Label::SetTextInset(int xInset, int yInset) //----------------------------------------------------------------------------- void Label::GetTextInset(int *xInset, int *yInset ) { - if ( xInset ) - { - *xInset = _textInset[0]; - } - if ( yInset ) - { - *yInset = _textInset[1]; - } + *xInset = _textInset[0]; + *yInset = _textInset[1]; } //----------------------------------------------------------------------------- @@ -417,7 +411,7 @@ void Label::ComputeAlignment(int &tx0, int &ty0, int &tx1, int &ty1) actualXAlignment = Label::a_west; // get the max height - maxY = max(maxY, iTall); + maxY = MAX(maxY, iTall); maxX += iWide; // add the offset to x diff --git a/vgui2/vgui_controls/ListPanel.cpp b/vgui2/vgui_controls/ListPanel.cpp index 73c8a984..1b4ffc84 100644 --- a/vgui2/vgui_controls/ListPanel.cpp +++ b/vgui2/vgui_controls/ListPanel.cpp @@ -44,11 +44,11 @@ enum #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifndef clamp @@ -1092,7 +1092,7 @@ void ListPanel::IndexItem(int itemID) FastSortListPanelItem *newitem = (FastSortListPanelItem*) m_DataItems[itemID]; // remove the item from the indexes and re-add - int maxCount = min(m_ColumnsHistory.Count(), newitem->m_SortedTreeIndexes.Count()); + int maxCount = MIN(m_ColumnsHistory.Count(), newitem->m_SortedTreeIndexes.Count()); for (int i = 0; i < maxCount; i++) { IndexRBTree_t &rbtree = m_ColumnsData[m_ColumnsHistory[i]].m_SortedTree; @@ -1504,7 +1504,7 @@ Panel *ListPanel::GetCellRenderer(int itemID, int col) // set cell size Panel *header = column.m_pHeader; int wide = header->GetWide(); - m_pTextImage->SetSize( min( cw, wide - 5 ), tall); + m_pTextImage->SetSize( MIN( cw, wide - 5 ), tall); m_pLabel->SetTextImageIndex( 0 ); m_pLabel->SetImageAtIndex(0, m_pTextImage, 3); @@ -2005,7 +2005,7 @@ void ListPanel::Paint() render->SetPos( xpos, (drawcount * m_iRowHeight) + m_iTableStartY); - int right = min( xpos + wide, maxw ); + int right = MIN( xpos + wide, maxw ); int usew = right - xpos; render->SetSize( usew, m_iRowHeight - 1 ); diff --git a/vgui2/vgui_controls/Menu.cpp b/vgui2/vgui_controls/Menu.cpp index 9978824e..6b04a683 100644 --- a/vgui2/vgui_controls/Menu.cpp +++ b/vgui2/vgui_controls/Menu.cpp @@ -769,7 +769,7 @@ void Menu::PerformLayout() AddScrollBar(); // This fills in m_VisibleSortedItems as needed - MakeItemsVisibleInScrollRange( m_iNumVisibleLines, min( fullHeightWouldRequire, workTall ) ); + MakeItemsVisibleInScrollRange( m_iNumVisibleLines, MIN( fullHeightWouldRequire, workTall ) ); } else { @@ -1888,7 +1888,7 @@ void Menu::ApplySchemeSettings(IScheme *pScheme) int wide, tall; m_MenuItems[i]->GetCheckImageSize( wide, tall ); - m_iCheckImageWidth = max ( m_iCheckImageWidth, wide ); + m_iCheckImageWidth = MAX ( m_iCheckImageWidth, wide ); } } _recalculateWidth = true; @@ -2107,7 +2107,7 @@ void Menu::ActivateItemByRow(int row) //----------------------------------------------------------------------------- // Purpose: Return the number of items currently in the menu list //----------------------------------------------------------------------------- -int Menu::GetItemCount() const +int Menu::GetItemCount() { return m_MenuItems.Count(); } @@ -2701,33 +2701,3 @@ void Menu::Validate( CValidator &validator, char *pchName ) validator.Pop(); } #endif // DBGFLAG_VALIDATE - - -MenuBuilder::MenuBuilder( Menu *pMenu, Panel *pActionTarget ) - : m_pMenu( pMenu ) - , m_pActionTarget( pActionTarget ) - , m_pszLastCategory( NULL ) -{} - -MenuItem* MenuBuilder::AddMenuItem( const char *pszButtonText, const char *pszCommand, const char *pszCategoryName ) -{ - AddSepratorIfNeeded( pszCategoryName ); - return m_pMenu->GetMenuItem( m_pMenu->AddMenuItem( pszButtonText, new KeyValues( pszCommand ), m_pActionTarget ) ); -} - -MenuItem* MenuBuilder::AddCascadingMenuItem( const char *pszButtonText, Menu *pSubMenu, const char *pszCategoryName ) -{ - AddSepratorIfNeeded( pszCategoryName ); - return m_pMenu->GetMenuItem( m_pMenu->AddCascadingMenuItem( pszButtonText, m_pActionTarget, pSubMenu ) ); -} - -void MenuBuilder::AddSepratorIfNeeded( const char *pszCategoryName ) -{ - // Add a separator if the categories are different - if ( m_pszLastCategory && V_stricmp( pszCategoryName, m_pszLastCategory ) != 0 ) - { - m_pMenu->AddSeparator(); - } - - m_pszLastCategory = pszCategoryName; -} diff --git a/vgui2/vgui_controls/MenuItem.cpp b/vgui2/vgui_controls/MenuItem.cpp index 49c39570..ac0eb4d0 100644 --- a/vgui2/vgui_controls/MenuItem.cpp +++ b/vgui2/vgui_controls/MenuItem.cpp @@ -643,5 +643,5 @@ void MenuItem::GetContentSize( int& cw, int &ch ) m_pCurrentKeyBinding->GetSize( iw, ih ); cw += iw + KEYBINDING_INSET; - ch = max( ch, ih ); + ch = MAX( ch, ih ); } diff --git a/vgui2/vgui_controls/MessageBox.cpp b/vgui2/vgui_controls/MessageBox.cpp index e825e6bc..15f737ee 100644 --- a/vgui2/vgui_controls/MessageBox.cpp +++ b/vgui2/vgui_controls/MessageBox.cpp @@ -20,7 +20,7 @@ using namespace vgui; #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif vgui::Panel *MessageBox_Factory() @@ -257,8 +257,8 @@ void MessageBox::PerformLayout() int btnWide, btnTall; m_pOkButton->GetContentSize(btnWide, btnTall); - btnWide = max(oldWide, btnWide + 10); - btnTall = max(oldTall, btnTall + 10); + btnWide = MAX(oldWide, btnWide + 10); + btnTall = MAX(oldTall, btnTall + 10); m_pOkButton->SetSize(btnWide, btnTall); int btnWide2 = 0, btnTall2 = 0; @@ -267,13 +267,13 @@ void MessageBox::PerformLayout() m_pCancelButton->GetSize(oldWide, oldTall); m_pCancelButton->GetContentSize(btnWide2, btnTall2); - btnWide2 = max(oldWide, btnWide2 + 10); - btnTall2 = max(oldTall, btnTall2 + 10); + btnWide2 = MAX(oldWide, btnWide2 + 10); + btnTall2 = MAX(oldTall, btnTall2 + 10); m_pCancelButton->SetSize(btnWide2, btnTall2); } - boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100); - boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30); + boxWidth = MAX(boxWidth, m_pMessageLabel->GetWide() + 100); + boxWidth = MAX(boxWidth, (btnWide + btnWide2) * 2 + 30); SetSize(boxWidth, boxTall); GetSize(boxWidth, boxTall); diff --git a/vgui2/vgui_controls/MessageDialog.cpp b/vgui2/vgui_controls/MessageDialog.cpp index dc0d491d..4a255d0f 100644 --- a/vgui2/vgui_controls/MessageDialog.cpp +++ b/vgui2/vgui_controls/MessageDialog.cpp @@ -188,7 +188,7 @@ void CMessageDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) // position the buttons with even horizontal spacing int xpos = 0; - int ypos = GetTall() - max( nButtonTall, nTextTall ) - m_ButtonMargin; + int ypos = GetTall() - MAX( nButtonTall, nTextTall ) - m_ButtonMargin; int nSpacing = ( GetWide() - nTotalWide ) / ( cButtons + 1 ); for ( int i = 0; i < MAX_BUTTONS; ++i ) { @@ -238,7 +238,7 @@ void CMessageDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) // If we're animating, we push our text label in, and reduce its width int iX,iY,iW,iH; m_pMsg->GetBounds( iX, iY, iW, iH ); - m_pMsg->SetBounds( iX + m_ActivityIndent, iY, max(0,iW-m_ActivityIndent), iH ); + m_pMsg->SetBounds( iX + m_ActivityIndent, iY, MAX(0,iW-m_ActivityIndent), iH ); } // Invalidate the scheme on our message label so that it recalculates diff --git a/vgui2/vgui_controls/Panel.cpp b/vgui2/vgui_controls/Panel.cpp index 5291c437..e279a0c9 100644 --- a/vgui2/vgui_controls/Panel.cpp +++ b/vgui2/vgui_controls/Panel.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ //=============================================================================// @@ -40,7 +40,6 @@ #include "mempool.h" #include "filesystem.h" #include "tier0/icommandline.h" -#include "tier0/minidump.h" #include "tier0/vprof.h" @@ -51,38 +50,7 @@ using namespace vgui; #define TRIPLE_PRESS_MSEC 300 -const char *g_PinCornerStrings [] = -{ - "PIN_TOPLEFT", - "PIN_TOPRIGHT", - "PIN_BOTTOMLEFT", - "PIN_BOTTOMRIGHT", - - "PIN_CENTER_TOP", - "PIN_CENTER_RIGHT", - "PIN_CENTER_BOTTOM", - "PIN_CENTER_LEFT", -}; - -COMPILE_TIME_ASSERT( Panel::PIN_LAST == ARRAYSIZE( g_PinCornerStrings ) ); - -static const char *COM_GetModDirectory() -{ - static char modDir[MAX_PATH]; - if ( Q_strlen( modDir ) == 0 ) - { - const char *gamedir = CommandLine()->ParmValue("-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) ); - Q_strncpy( modDir, gamedir, sizeof(modDir) ); - if ( strchr( modDir, '/' ) || strchr( modDir, '\\' ) ) - { - Q_StripLastDir( modDir, sizeof(modDir) ); - int dirlen = Q_strlen( modDir ); - Q_strncpy( modDir, gamedir + dirlen, sizeof(modDir) - dirlen ); - } - } - return modDir; -} extern int GetBuildModeDialogCount(); static char *CopyString( const char *in ) @@ -96,16 +64,16 @@ static char *CopyString( const char *in ) return n; } -#ifdef STAGING_ONLY -ConVar tf_strict_mouse_up_events( "tf_strict_mouse_up_events", "0", FCVAR_ARCHIVE, "Only allow Mouse-Release events to happens on panels we also Mouse-Downed in" ); -#endif +#ifdef MAPBASE +ConVar vgui_mapbase_custom_schemes( "vgui_mapbase_custom_schemes", "1" ); -// Temporary convar to help debug why the MvMVictoryMannUpPanel TabContainer is sometimes way off to the left. -ConVar tf_debug_tabcontainer( "tf_debug_tabcontainer", "0", FCVAR_HIDDEN, "Spew TabContainer dimensions." ); +// This is used in mapbase_shared.cpp +HScheme g_iCustomClientSchemeOverride; +#endif #if defined( VGUI_USEDRAGDROP ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- struct vgui::DragDrop_t { @@ -243,7 +211,7 @@ KeyBindingMap_t::~KeyBindingMap_t() class CKeyBindingsMgr { public: - + CKeyBindingsMgr() : m_Bindings( 0, 0, KeyBindingContextHandleLessFunc ), m_nKeyBindingContexts( 0 ) @@ -330,7 +298,7 @@ class CKeyBindingsMgr kb->m_Panels.FindAndRemove( panel ); } } - + KBContext_t *Find( KeyBindingContextHandle_t handle ) { KBContext_t search; @@ -378,11 +346,11 @@ class CKeyBindingsMgr //----------------------------------------------------------------------------- // Purpose: static method - // Input : index - + // Input : index - // Output : Panel //----------------------------------------------------------------------------- Panel *GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index ) - { + { KBContext_t *kb = Find( handle ); if ( kb ) { @@ -401,7 +369,7 @@ static CKeyBindingsMgr g_KBMgr; //----------------------------------------------------------------------------- // Purpose: Static method to allocate a context -// Input : - +// Input : - // Output : KeyBindingContextHandle_t //----------------------------------------------------------------------------- KeyBindingContextHandle_t Panel::CreateKeyBindingsContext( char const *filename, char const *pathID /*=0*/ ) @@ -409,12 +377,10 @@ KeyBindingContextHandle_t Panel::CreateKeyBindingsContext( char const *filename, return g_KBMgr.CreateContext( filename, pathID ); } -COMPILE_TIME_ASSERT( ( MOUSE_MIDDLE - MOUSE_LEFT ) == 2 ); -Panel* Panel::m_sMousePressedPanels[] = { NULL, NULL, NULL }; //----------------------------------------------------------------------------- // Purpose: static method -// Input : - +// Input : - // Output : int //----------------------------------------------------------------------------- int Panel::GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle ) @@ -424,7 +390,7 @@ int Panel::GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle ) //----------------------------------------------------------------------------- // Purpose: static method -// Input : index - +// Input : index - // Output : Panel //----------------------------------------------------------------------------- Panel *Panel::GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index ) @@ -452,7 +418,7 @@ int Panel::GetKeyMappingCount( ) //----------------------------------------------------------------------------- // Purpose: static method. Reverts key bindings for all registered panels (panels with keybindings actually // loaded from file -// Input : - +// Input : - //----------------------------------------------------------------------------- void Panel::RevertKeyBindings( KeyBindingContextHandle_t handle ) { @@ -482,8 +448,8 @@ static void BufPrint( CUtlBuffer& buf, int level, char const *fmt, ... ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : handle - +// Purpose: +// Input : handle - //----------------------------------------------------------------------------- void Panel::SaveKeyBindings( KeyBindingContextHandle_t handle ) { @@ -495,7 +461,7 @@ void Panel::SaveKeyBindings( KeyBindingContextHandle_t handle ) //----------------------------------------------------------------------------- // Purpose: static method. Saves key binding files out for all keybindings -// Input : - +// Input : - //----------------------------------------------------------------------------- void Panel::SaveKeyBindingsToFile( KeyBindingContextHandle_t handle, char const *filename, char const *pathID /*= 0*/ ) { @@ -517,7 +483,7 @@ void Panel::SaveKeyBindingsToFile( KeyBindingContextHandle_t handle, char const if ( !kbPanel->GetName() || !kbPanel->GetName()[ 0 ] ) continue; - + BufPrint( buf, 1, "\"%s\"\n", kbPanel->GetName() ); BufPrint( buf, 1, "{\n" ); @@ -543,9 +509,9 @@ void Panel::SaveKeyBindingsToFile( KeyBindingContextHandle_t handle, char const } //----------------------------------------------------------------------------- -// Purpose: -// Input : handle - -// *panelOfInterest - +// Purpose: +// Input : handle - +// *panelOfInterest - //----------------------------------------------------------------------------- void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel *panelOfInterest ) { @@ -567,7 +533,7 @@ void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel { Panel *kbPanel = GetPanelWithKeyBindings( handle, i ); Assert( kbPanel ); - + char const *panelName = kbPanel->GetName(); if ( !panelName ) { @@ -583,7 +549,7 @@ void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName ); continue; } - + kbPanel->ParseKeyBindings( subKey ); } } @@ -592,7 +558,7 @@ void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel //----------------------------------------------------------------------------- // Purpose: static method. Loads all key bindings again -// Input : - +// Input : - //----------------------------------------------------------------------------- void Panel::ReloadKeyBindings( KeyBindingContextHandle_t handle ) @@ -608,7 +574,7 @@ void Panel::ReloadKeyBindings( KeyBindingContextHandle_t handle ) { Panel *kbPanel = GetPanelWithKeyBindings( handle, i ); Assert( kbPanel ); - + char const *panelName = kbPanel->GetName(); if ( !panelName ) { @@ -621,7 +587,7 @@ void Panel::ReloadKeyBindings( KeyBindingContextHandle_t handle ) Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName ); continue; } - + kbPanel->ParseKeyBindings( subKey ); } } @@ -763,6 +729,7 @@ void Panel::Init( int x, int y, int wide, int tall ) m_bForceStereoRenderToFrameBuffer = false; } + //----------------------------------------------------------------------------- // Purpose: Destructor //----------------------------------------------------------------------------- @@ -825,13 +792,6 @@ Panel::~Panel() #if defined( VGUI_USEDRAGDROP ) delete m_pDragDrop; #endif // VGUI_USEDRAGDROP - -#if defined( VGUI_PANEL_VERIFY_DELETES ) - // Zero out our vtbl pointer. This should hopefully help us catch bad guys using - // this panel after it has been deleted. - uintp *panel_vtbl = (uintp *)this; - *panel_vtbl = NULL; -#endif } //----------------------------------------------------------------------------- @@ -844,15 +804,15 @@ void Panel::MakeReadyForUse() surface()->SolveTraverse( GetVPanel(), true ); } - + //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetName( const char *panelName ) { // No change? - if ( _panelName && - panelName && + if ( _panelName && + panelName && !Q_strcmp( _panelName, panelName ) ) { return; @@ -907,11 +867,11 @@ const char *Panel::GetClassName() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetPos(int x, int y) { - if ( !HushAsserts() ) + if (!CommandLine()->FindParm("-hushasserts")) { Assert( abs(x) < 32768 && abs(y) < 32768 ); } @@ -919,7 +879,7 @@ void Panel::SetPos(int x, int y) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::GetPos(int &x, int &y) { @@ -927,27 +887,7 @@ void Panel::GetPos(int &x, int &y) } //----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int Panel::GetXPos() -{ - int x,y; - GetPos( x, y ); - return x; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int Panel::GetYPos() -{ - int x,y; - GetPos( x, y ); - return y; -} - -//----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetSize(int wide, int tall) { @@ -956,7 +896,7 @@ void Panel::SetSize(int wide, int tall) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::GetSize(int &wide, int &tall) { @@ -964,7 +904,7 @@ void Panel::GetSize(int &wide, int &tall) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetBounds(int x, int y, int wide, int tall) { @@ -973,7 +913,7 @@ void Panel::SetBounds(int x, int y, int wide, int tall) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::GetBounds(int &x, int &y, int &wide, int &tall) { @@ -1048,7 +988,7 @@ void Panel::OnScreenSizeChanged(int nOldWide, int nOldTall) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetVisible(bool state) { @@ -1056,7 +996,7 @@ void Panel::SetVisible(bool state) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::IsVisible() { @@ -1069,7 +1009,7 @@ bool Panel::IsVisible() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetEnabled(bool state) { @@ -1082,7 +1022,7 @@ void Panel::SetEnabled(bool state) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::IsEnabled() { @@ -1090,7 +1030,7 @@ bool Panel::IsEnabled() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::IsPopup() { @@ -1098,7 +1038,7 @@ bool Panel::IsPopup() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::Repaint() { @@ -1110,12 +1050,12 @@ void Panel::Repaint() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::Think() { if (IsVisible()) - { + { // update any tooltips if (m_pTooltips) { @@ -1130,17 +1070,8 @@ void Panel::Think() OnThink(); } -void Panel::OnChildSettingsApplied( KeyValues *pInResourceData, Panel *pChild ) -{ - Panel* pParent = GetParent(); - if( pParent ) - { - pParent->OnChildSettingsApplied( pInResourceData, pChild ); - } -} - //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::PaintTraverse( bool repaint, bool allowForce ) { @@ -1269,20 +1200,20 @@ void Panel::PaintTraverse( bool repaint, bool allowForce ) // IsBuildGroupEnabled recurses up all the parents and ends up being very expensive as it wanders all over memory if ( GetBuildModeDialogCount() && IsBuildGroupEnabled() ) //&& HasFocus() ) { - // outline all selected panels + // outline all selected panels CUtlVector *controlGroup = _buildGroup->GetControlGroup(); for (int i=0; i < controlGroup->Size(); ++i) { - // outline all selected panels + // outline all selected panels CUtlVector *controlGroup = _buildGroup->GetControlGroup(); for (int i=0; i < controlGroup->Size(); ++i) { surface()->PushMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel(), false ); ((*controlGroup)[i].Get())->PaintBuildOverlay(); surface()->PopMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel() ); - } - - _buildGroup->DrawRulers(); + } + + _buildGroup->DrawRulers(); } } #endif @@ -1308,7 +1239,7 @@ void Panel::PaintTraverse( bool repaint, bool allowForce ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::PaintBorder() { @@ -1317,10 +1248,10 @@ void Panel::PaintBorder() //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::PaintBackground() -{ +{ int wide, tall; GetSize( wide, tall ); if ( m_SkipChild.Get() && m_SkipChild->IsVisible() ) @@ -1376,7 +1307,7 @@ void Panel::PaintBackground() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::Paint() { @@ -1385,13 +1316,13 @@ void Panel::Paint() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::PostChildPaint() { // Empty on purpose // This is called if _postChildPaintEnabled is true and allows painting to - // continue on the surface after all of the panel's children have painted + // continue on the surface after all of the panel's children have painted // themselves. Allows drawing an overlay on top of the children, etc. } @@ -1458,7 +1389,7 @@ void Panel::SetParent(Panel *newParent) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetParent(VPANEL newParent) { @@ -1491,7 +1422,7 @@ void Panel::SetParent(VPANEL newParent) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::OnChildAdded(VPANEL child) { @@ -1653,6 +1584,7 @@ void Panel::CallParentFunction(KeyValues *message) } } + //----------------------------------------------------------------------------- // Purpose: if set to true, panel automatically frees itself when parent is deleted //----------------------------------------------------------------------------- @@ -1663,7 +1595,7 @@ void Panel::SetAutoDelete( bool state ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::IsAutoDeleteSet() { @@ -1687,17 +1619,31 @@ void Panel::DeletePanel() //----------------------------------------------------------------------------- HScheme Panel::GetScheme() { + HScheme iScheme; + if (m_iScheme) { - return m_iScheme; // return our internal scheme + iScheme = m_iScheme; // return our internal scheme } - - if (GetVParent()) // recurse down the heirarchy + else if (GetVParent()) // recurse down the heirarchy { - return ipanel()->GetScheme(GetVParent()); + iScheme = ipanel()->GetScheme(GetVParent()); } + else + { + iScheme = scheme()->GetDefaultScheme(); + } + +#ifdef MAPBASE + // If a custom client scheme is available, use the custom scheme. + // TODO: Need a better way to detect that this panel actually uses ClientScheme.res + if (g_iCustomClientSchemeOverride != 0 && iScheme == scheme()->GetScheme( "ClientScheme" ) && vgui_mapbase_custom_schemes.GetBool()) + { + return g_iCustomClientSchemeOverride; + } +#endif - return scheme()->GetDefaultScheme(); + return iScheme; } //----------------------------------------------------------------------------- @@ -1712,7 +1658,7 @@ void Panel::SetScheme(const char *tag) } //----------------------------------------------------------------------------- -// Purpose: set the scheme to render this panel with +// Purpose: set the scheme to render this panel with //----------------------------------------------------------------------------- void Panel::SetScheme(HScheme scheme) { @@ -1764,7 +1710,7 @@ void Panel::InternalCursorMoved(int x, int y) if ( IsCursorNone() ) return; - + if ( !IsMouseInputEnabled() ) { return; @@ -1796,7 +1742,7 @@ void Panel::InternalCursorEntered() { if (IsCursorNone() || !IsMouseInputEnabled()) return; - + if (IsBuildGroupEnabled()) return; @@ -1818,7 +1764,7 @@ void Panel::InternalCursorExited() { if (IsCursorNone() || !IsMouseInputEnabled()) return; - + if (IsBuildGroupEnabled()) return; @@ -1844,8 +1790,8 @@ bool Panel::IsChildOfSurfaceModalPanel() //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsChildOfModalSubTree() @@ -1862,7 +1808,7 @@ bool Panel::IsChildOfModalSubTree() //----------------------------------------------------------------------------- // Purpose: Checks to see if message is being subverted due to modal subtree logic -// Input : - +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- static bool ShouldHandleInputMessage( VPANEL p ) @@ -1907,7 +1853,7 @@ void Panel::InternalMousePressed(int code) } } - // The menu system passively watches for mouse released messages so it + // The menu system passively watches for mouse released messages so it // can clear any open menus if the release is somewhere other than on a menu Menu::OnInternalMousePressed( this, (MouseCode)code ); @@ -1916,7 +1862,7 @@ void Panel::InternalMousePressed(int code) if ( IsCursorNone() ) return; - + if ( !IsMouseInputEnabled()) { #if defined( VGUI_USEDRAGDROP ) @@ -1924,7 +1870,7 @@ void Panel::InternalMousePressed(int code) #endif return; } - + if (IsBuildGroupEnabled()) { if ( _buildGroup->MousePressed((MouseCode)code, this) ) @@ -1935,24 +1881,13 @@ void Panel::InternalMousePressed(int code) #ifdef STAGING_ONLY // If holding CTRL + ALT, invalidate layout. For debugging purposes - if ( ( vgui::input()->IsKeyDown(KEY_LCONTROL) || vgui::input()->IsKeyDown(KEY_RCONTROL) ) + if ( ( vgui::input()->IsKeyDown(KEY_LCONTROL) || vgui::input()->IsKeyDown(KEY_RCONTROL) ) && ( vgui::input()->IsKeyDown(KEY_LALT) || vgui::input()->IsKeyDown(KEY_RALT) ) ) { InvalidateLayout( true, true ); } #endif -#ifdef STAGING_ONLY - const char *pGameDir = COM_GetModDirectory(); - if ( Q_stristr( pGameDir, "tf" ) ) - { - if ( code >= MOUSE_LEFT && code <= MOUSE_MIDDLE ) - { - m_sMousePressedPanels[ code - MOUSE_LEFT ] = this; - } - } -#endif - Panel *pMouseHandler = m_hMouseEventHandler.Get(); if ( pMouseHandler ) { @@ -1977,12 +1912,12 @@ void Panel::InternalMouseDoublePressed(int code) if ( IsCursorNone() ) return; - + if ( !IsMouseInputEnabled()) { return; } - + if (IsBuildGroupEnabled()) { if ( _buildGroup->MouseDoublePressed((MouseCode)code, this) ) @@ -2034,7 +1969,7 @@ void Panel::InternalMouseTriplePressed( int code ) if ( IsCursorNone() ) return; - + if ( !IsMouseInputEnabled()) { #if defined( VGUI_USEDRAGDROP ) @@ -2042,7 +1977,7 @@ void Panel::InternalMouseTriplePressed( int code ) #endif return; } - + if (IsBuildGroupEnabled()) { return; @@ -2073,12 +2008,12 @@ void Panel::InternalMouseReleased(int code) if ( IsCursorNone() ) return; - + if ( !IsMouseInputEnabled()) { return; } - + if (IsBuildGroupEnabled()) { if ( _buildGroup->MouseReleased((MouseCode)code, this) ) @@ -2087,26 +2022,6 @@ void Panel::InternalMouseReleased(int code) } } -#ifdef STAGING_ONLY - const char *pGameDir = COM_GetModDirectory(); - if ( Q_stristr( pGameDir, "tf" ) && tf_strict_mouse_up_events.GetBool() ) - { - // Only allow mouse release events to go to panels that we also - // first clicked into - if ( code >= MOUSE_LEFT && code <= MOUSE_MIDDLE ) - { - const int nIndex = code - MOUSE_LEFT; - Panel* pPressedPanel = m_sMousePressedPanels[ nIndex ]; - m_sMousePressedPanels[ nIndex ] = NULL; // Clear out pressed panel - if ( pPressedPanel != this ) - { - OnMouseMismatchedRelease( (MouseCode)code, pPressedPanel ); - return; - } - } - } -#endif - OnMouseReleased((MouseCode)code); } @@ -2128,7 +2043,7 @@ void Panel::InternalKeyCodePressed(int code) if ( !ShouldHandleInputMessage() ) return; - if (IsKeyBoardInputEnabled()) + if (IsKeyBoardInputEnabled()) { OnKeyCodePressed((KeyCode)code); } @@ -2140,10 +2055,10 @@ void Panel::InternalKeyCodePressed(int code) #if defined( VGUI_USEKEYBINDINGMAPS ) //----------------------------------------------------------------------------- -// Purpose: -// Input : *bindingName - -// keycode - -// modifiers - +// Purpose: +// Input : *bindingName - +// keycode - +// modifiers - //----------------------------------------------------------------------------- void Panel::AddKeyBinding( char const *bindingName, int keycode, int modifiers ) { @@ -2152,15 +2067,15 @@ void Panel::AddKeyBinding( char const *bindingName, int keycode, int modifiers ) { Assert( 0 ); return; - } + } - BoundKey_t kb; - kb.isbuiltin = false; - kb.bindingname = CopyString( bindingName ); - kb.keycode = keycode; - kb.modifiers = modifiers; + BoundKey_t kb; + kb.isbuiltin = false; + kb.bindingname = CopyString( bindingName ); + kb.keycode = keycode; + kb.modifiers = modifiers; - map->boundkeys.AddToTail( kb ); + map->boundkeys.AddToTail( kb ); } KeyBindingMap_t *Panel::LookupBinding( char const *bindingName ) @@ -2289,8 +2204,8 @@ void Panel::RemoveAllKeyBindings() } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- void Panel::ReloadKeyBindings() { @@ -2467,7 +2382,7 @@ static void AddModifierToString( char const *modifiername, char *buf, size_t buf } Q_strncat( buf, add, bufsize, COPY_ALL_CHARACTERS ); - + } wchar_t const *Panel::KeyCodeModifiersToDisplayString( KeyCode code, int modifiers ) @@ -2528,9 +2443,9 @@ static void WriteKeyBindingToBuffer( CUtlBuffer& buf, int level, const BoundKey_ } //----------------------------------------------------------------------------- -// Purpose: -// Input : *filename - -// *pathID - +// Purpose: +// Input : *filename - +// *pathID - //----------------------------------------------------------------------------- void Panel::SaveKeyBindingsToBuffer( int level, CUtlBuffer& buf ) { @@ -2549,7 +2464,7 @@ void Panel::SaveKeyBindingsToBuffer( int level, CUtlBuffer& buf ) // Spew to file BufPrint( buf, level, "\"%s\"\n", binding.bindingname ); BufPrint( buf, level, "{\n" ); - + WriteKeyBindingToBuffer( buf, level + 1, binding ); BufPrint( buf, level, "}\n" ); @@ -2622,7 +2537,7 @@ bool Panel::ParseKeyBindings( KeyValues *kv ) for( int i = 0; i < c ; ++i ) { KeyBindingMap_t *binding = &map->entries[ i ]; - + // See if there is a bound key CUtlVector< BoundKey_t * > list; LookupBoundKeys( binding->bindingname, list ); @@ -2652,8 +2567,8 @@ bool Panel::ParseKeyBindings( KeyValues *kv ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : handle - +// Purpose: +// Input : handle - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void Panel::SetKeyBindingsContext( KeyBindingContextHandle_t handle ) @@ -2664,8 +2579,8 @@ void Panel::SetKeyBindingsContext( KeyBindingContextHandle_t handle ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : KeyBindingContextHandle_t //----------------------------------------------------------------------------- KeyBindingContextHandle_t Panel::GetKeyBindingsContext() const @@ -2674,8 +2589,8 @@ KeyBindingContextHandle_t Panel::GetKeyBindingsContext() const } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsValidKeyBindingsContext() const @@ -2703,7 +2618,7 @@ void Panel::EditKeyBindings() //----------------------------------------------------------------------------- // Purpose: Set this to false to disallow IsKeyRebound chaining to GetParent() Panels... -// Input : state - +// Input : state - //----------------------------------------------------------------------------- void Panel::SetAllowKeyBindingChainToParent( bool state ) { @@ -2712,8 +2627,8 @@ void Panel::SetAllowKeyBindingChainToParent( bool state ) //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsKeyBindingChainToParentAllowed() const @@ -2730,7 +2645,7 @@ bool Panel::IsKeyOverridden( KeyCode code, int modifiers ) bool Panel::IsKeyRebound( KeyCode code, int modifiers ) { if ( IsKeyBoardInputEnabled() ) - { + { KeyBindingMap_t* binding = LookupBindingByKeyCode( code, modifiers ); // Only dispatch if we're part of the current modal subtree if ( binding && IsChildOfSurfaceModalPanel() ) @@ -2774,7 +2689,7 @@ void Panel::InternalKeyCodeTyped( int code ) return; } - if (IsKeyBoardInputEnabled()) + if (IsKeyBoardInputEnabled()) { bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT)); bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL)); @@ -2849,7 +2764,7 @@ void Panel::InternalKeyCodeReleased(int code) if ( !ShouldHandleInputMessage() ) return; - if (IsKeyBoardInputEnabled()) + if (IsKeyBoardInputEnabled()) { if (IsBuildGroupEnabled()) { @@ -2871,7 +2786,7 @@ void Panel::InternalKeyFocusTicked() { if (IsBuildGroupEnabled()) return; - + OnKeyFocusTicked(); } @@ -2912,17 +2827,17 @@ void Panel::InternalSetCursor() visible &= ipanel()->IsVisible(p); p = ipanel()->GetParent(p); } - + // only change the cursor if this panel is visible, and if its part of the main VGUI tree - if (visible && HasParent(surface()->GetEmbeddedPanel())) - { + if (visible && HasParent(surface()->GetEmbeddedPanel())) + { HCursor cursor = GetCursor(); - + if (IsBuildGroupEnabled()) { cursor = _buildGroup->GetCursor(this); } - + if (input()->GetCursorOveride()) { cursor = input()->GetCursorOveride(); @@ -2939,7 +2854,7 @@ void Panel::InternalSetCursor() void Panel::OnThink() { #if defined( VGUI_USEDRAGDROP ) - if ( IsPC() && + if ( IsPC() && m_pDragDrop->m_bDragEnabled && m_pDragDrop->m_bDragging && m_pDragDrop->m_bDragStarted ) @@ -2977,7 +2892,7 @@ void Panel::OnThink() m_pDragDrop->m_bDropMenuShown = true; CUtlVector< KeyValues * > data; - + GetDragData( data ); int x, y; @@ -2989,7 +2904,7 @@ void Panel::OnThink() } Menu *menu = new Menu( m_pDragDrop->m_hCurrentDrop.Get(), "DropContext" ); - + bool useMenu = m_pDragDrop->m_hCurrentDrop->GetDropContextMenu( menu, data ); if ( useMenu ) { @@ -3057,10 +2972,6 @@ void Panel::OnMouseReleased(MouseCode code) { } -void Panel::OnMouseMismatchedRelease( MouseCode code, Panel* pPressedPanel ) -{ -} - void Panel::OnMouseWheeled(int delta) { CallParentFunction(new KeyValues("MouseWheeled", "delta", delta)); @@ -3462,7 +3373,7 @@ void Panel::SetBuildModeDeletable(bool state) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::IsBuildModeActive() { @@ -3470,7 +3381,7 @@ bool Panel::IsBuildModeActive() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::GetClipRect(int& x0,int& y0,int& x1,int& y1) { @@ -3478,7 +3389,7 @@ void Panel::GetClipRect(int& x0,int& y0,int& x1,int& y1) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int Panel::GetChildCount() { @@ -3519,7 +3430,7 @@ bool Panel::RequestFocusPrev(VPANEL panel) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- bool Panel::RequestFocusNext(VPANEL panel) { @@ -3552,7 +3463,7 @@ void Panel::OnRequestFocus(VPANEL subFocus, VPANEL defaultPanel) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- VPANEL Panel::GetCurrentKeyFocus() { @@ -3572,7 +3483,7 @@ bool Panel::HasFocus() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetTabPosition(int position) { @@ -3580,7 +3491,7 @@ void Panel::SetTabPosition(int position) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- int Panel::GetTabPosition() { @@ -3588,7 +3499,7 @@ int Panel::GetTabPosition() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::InternalFocusChanged(bool lost) { @@ -3613,7 +3524,7 @@ void Panel::OnMouseCaptureLost() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::AddActionSignalTarget(Panel *messageTarget) { @@ -3625,7 +3536,7 @@ void Panel::AddActionSignalTarget(Panel *messageTarget) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::AddActionSignalTarget(VPANEL messageTarget) { @@ -3637,7 +3548,7 @@ void Panel::AddActionSignalTarget(VPANEL messageTarget) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::RemoveActionSignalTarget(Panel *oldTarget) { @@ -3650,7 +3561,7 @@ void Panel::RemoveActionSignalTarget(Panel *oldTarget) void Panel::PostActionSignal( KeyValues *message ) { if ( m_bIsSilent != true ) - { + { // add who it was from the message message->SetPtr("panel", this); int i; @@ -3775,7 +3686,7 @@ void Panel::SetBuildGroup(BuildGroup* buildGroup) //TODO: remove from old group Assert(buildGroup != NULL); - + _buildGroup = buildGroup; _buildGroup->PanelAdded(this); @@ -3838,12 +3749,12 @@ void Panel::PerformLayout() void Panel::InvalidateLayout( bool layoutNow, bool reloadScheme ) { _flags.SetFlag( NEEDS_LAYOUT ); - + if (reloadScheme) { // make all our children reload the scheme _flags.SetFlag( NEEDS_SCHEME_UPDATE ); - + for (int i = 0; i < GetChildCount(); i++) { vgui::Panel* panel = GetChild(i); @@ -3852,10 +3763,10 @@ void Panel::InvalidateLayout( bool layoutNow, bool reloadScheme ) panel->InvalidateLayout(layoutNow, true); } } - + PerformApplySchemeSettings(); } - + if (layoutNow) { InternalPerformLayout(); @@ -3871,7 +3782,7 @@ bool Panel::IsCursorNone() { return true; } - + return false; } @@ -3959,7 +3870,7 @@ bool Panel::IsLayoutInvalid() //----------------------------------------------------------------------------- // Sets the pin corner + resize mode for resizing panels //----------------------------------------------------------------------------- -void Panel::SetAutoResize( PinCorner_e pinCorner, AutoResize_e resizeDir, +void Panel::SetAutoResize( PinCorner_e pinCorner, AutoResize_e resizeDir, int nPinOffsetX, int nPinOffsetY, int nUnpinnedCornerOffsetX, int nUnpinnedCornerOffsetY ) { _pinCorner = pinCorner; @@ -3984,7 +3895,7 @@ void Panel::SetPinCorner( PinCorner_e pinCorner, int nOffsetX, int nOffsetY ) m_nResizeDeltaY = 0; } - + //----------------------------------------------------------------------------- // Purpose: data accessor //----------------------------------------------------------------------------- @@ -4051,7 +3962,7 @@ void Panel::PinToSibling( const char *pszSibling, PinCorner_e pinOurCorner, PinC } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::UpdateSiblingPin( void ) { @@ -4079,7 +3990,7 @@ void Panel::UpdateSiblingPin( void ) //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::ApplySchemeSettings(IScheme *pScheme) { @@ -4121,7 +4032,7 @@ void Panel::PerformApplySchemeSettings() if ( pScheme ) // this should NEVER be null, but if it is bad things would happen in ApplySchemeSettings... { ApplySchemeSettings( pScheme ); - //_needsSchemeUpdate = false; + //_needsSchemeUpdate = false; ApplyOverridableColors(); @@ -4248,7 +4159,7 @@ int Panel::ComputeWide( KeyValues *inResourceData, int nParentWide, int nParentT _buildModeFlags |= BUILDMODE_SAVE_WIDE_FULL; wstr++; } - else + else { if ( wstr[0] == 'o' || wstr[0] == 'O' ) { @@ -4322,7 +4233,7 @@ int Panel::ComputeTall( KeyValues *inResourceData, int nParentWide, int nParentT _buildModeFlags |= BUILDMODE_SAVE_TALL_FULL; tstr++; } - else + else { if ( tstr[0] == 'o' || tstr[0] == 'O' ) { @@ -4391,7 +4302,6 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const const int nFlagProportionalParent = bX ? BUILDMODE_SAVE_XPOS_PROPORTIONAL_PARENT : BUILDMODE_SAVE_YPOS_PROPORTIONAL_PARENT; int nFlags = 0; - int nPosDelta = 0; if ( pszInput ) { // look for alignment flags @@ -4430,6 +4340,7 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const flProportion = (float)nPos / (float)nOldPos; } + int nPosDelta = 0; if ( nFlags & nFlagProportionalSlef ) { nPosDelta = nSize * flPos; @@ -4458,40 +4369,9 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const } } - if ( tf_debug_tabcontainer.GetBool() && !Q_stricmp( "TabContainer", GetName() ) ) - { - Msg( "TabContainer nFlags:%x nPos:%d nParentSize:%d nPosDelta:%d nSize:%d GetParent:%p (%s) pszInput:'%s'\n", - nFlags, nPos, nParentSize, nPosDelta, nSize, GetParent(), GetParent() ? GetParent()->GetName() : "??", - pszInput ? pszInput : "??" ); - } - return nFlags; } -Panel::PinCorner_e GetPinCornerFromString( const char* pszCornerName ) -{ - if ( pszCornerName == NULL ) - { - return Panel::PIN_TOPLEFT; - } - - // Optimize for all the old entries of a single digit - if ( strlen( pszCornerName ) == 1 ) - { - return (Panel::PinCorner_e)atoi( pszCornerName ); - } - - for( int i=0; iGetString( "ypos", NULL ); _buildModeFlags |= ComputePos( xstr, x, wide, alignScreenWide, true ); _buildModeFlags |= ComputePos( ystr, y, tall, alignScreenTall, false ); - + bool bUsesTitleSafeArea = false; int titleSafeWide = 0; @@ -4763,23 +4643,10 @@ void Panel::ApplySettings(KeyValues *inResourceData) SetName(newName); } - // Automatically add an action signal target if one is specified. This allows for - // nested child buttons to add their distant parents as action signal targets. - int nActionSignalLevel = inResourceData->GetInt( "actionsignallevel", -1 ); - if ( nActionSignalLevel != -1 ) - { - Panel *pActionSignalTarget = this; - while( nActionSignalLevel-- ) - { - pActionSignalTarget = pActionSignalTarget->GetParent(); - } - AddActionSignalTarget( pActionSignalTarget ); - } - - // check to see if we need to render to the frame buffer even if + // check to see if we need to render to the frame buffer even if // stereo mode is trying to render all of the ui to a render target m_bForceStereoRenderToFrameBuffer = inResourceData->GetBool( "ForceStereoRenderToFrameBuffer", false ); - + //============================================================================= // HPE_BEGIN: // [pfreese] Support for reading rounded corner flags @@ -4794,8 +4661,8 @@ void Panel::ApplySettings(KeyValues *inResourceData) //============================================================================= const char *pszSiblingName = inResourceData->GetString("pin_to_sibling", NULL); - PinCorner_e pinOurCornerToSibling = GetPinCornerFromString( inResourceData->GetString( "pin_corner_to_sibling", NULL ) ); - PinCorner_e pinSiblingCorner = GetPinCornerFromString( inResourceData->GetString( "pin_to_sibling_corner", NULL ) ); + PinCorner_e pinOurCornerToSibling = (PinCorner_e)inResourceData->GetInt( "pin_corner_to_sibling", PIN_TOPLEFT ); + PinCorner_e pinSiblingCorner = (PinCorner_e)inResourceData->GetInt( "pin_to_sibling_corner", PIN_TOPLEFT ); PinToSibling( pszSiblingName, pinOurCornerToSibling, pinSiblingCorner ); @@ -4834,8 +4701,6 @@ void Panel::ApplySettings(KeyValues *inResourceData) { SetKeyBoardInputEnabled( atoi( pKeyboardInputEnabled ) ); } - - OnChildSettingsApplied( inResourceData, this ); } //----------------------------------------------------------------------------- @@ -4980,7 +4845,7 @@ void Panel::ApplyOverridableColors( void ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetOverridableColor( Color *pColor, const Color &newColor ) { @@ -4998,7 +4863,7 @@ void Panel::SetOverridableColor( Color *pColor, const Color &newColor ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Color Panel::GetSchemeColor(const char *keyName, IScheme *pScheme) { @@ -5006,7 +4871,7 @@ Color Panel::GetSchemeColor(const char *keyName, IScheme *pScheme) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Color Panel::GetSchemeColor(const char *keyName, Color defaultColor, IScheme *pScheme) { @@ -5047,7 +4912,7 @@ bool Panel::HasUserConfigSettings() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::InternalInvalidateLayout() { @@ -5062,7 +4927,7 @@ void Panel::OnMove() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::InternalMove() { @@ -5146,7 +5011,7 @@ void PreparePanelMessageMap(PanelMessageMap *panelMap) item->secondParamSymbol = INVALID_KEY_SYMBOL; } } - + panelMap->processed = true; panelMap = panelMap->baseMap; } @@ -5193,7 +5058,7 @@ void Panel::OnMessage(const KeyValues *params, VPANEL ifromPanel) (this->*(pMap->func))(); break; } - + case 1: { KeyValues *param1 = params->FindKey(pMap->firstParamSymbol); @@ -5459,7 +5324,7 @@ void Panel::OnOldMessage(KeyValues *params, VPANEL ifromPanel) typedef void (Panel::*MessageFunc_Ptr_t)(void *); (this->*((MessageFunc_Ptr_t)pMessageMap[i].func))( (void *)params->GetPtr(pMessageMap[i].firstParamName) ); break; - + case DATATYPE_HANDLE: { typedef void (Panel::*MessageFunc_Ptr_t)(void *); @@ -5679,7 +5544,7 @@ void Panel::PreparePanelMap( PanelMap_t *panelMap ) item->secondParamSymbol = INVALID_KEY_SYMBOL; } } - + panelMap->processed = true; panelMap = panelMap->baseMap; } @@ -5703,7 +5568,7 @@ void Panel::OnDelete() // Purpose: Panel handle implementation // Returns a pointer to a valid panel, NULL if the panel has been deleted //----------------------------------------------------------------------------- -Panel *PHandle::Get() +Panel *PHandle::Get() { if (m_iPanelID != INVALID_PANEL) { @@ -5730,7 +5595,7 @@ Panel *PHandle::Set(Panel *pent) { m_iPanelID = INVALID_PANEL; } - return pent; + return pent; } Panel *PHandle::Set( HPanel hPanel ) @@ -5768,7 +5633,7 @@ VPANEL VPanelHandle::Set(VPANEL pent) { m_iPanelID = INVALID_PANEL; } - return pent; + return pent; } //----------------------------------------------------------------------------- @@ -5780,7 +5645,7 @@ BaseTooltip *Panel::GetTooltip() { m_pTooltips = new TextTooltip(this, NULL); m_bToolTipOverridden = false; - + if ( IsConsoleStylePanel() ) { m_pTooltips->SetEnabled( false ); @@ -5791,7 +5656,7 @@ BaseTooltip *Panel::GetTooltip() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetTooltip( BaseTooltip *pToolTip, const char *pszText ) { @@ -5840,11 +5705,11 @@ const char *Panel::GetEffectiveTooltipText() const // Purpose: sets the proportional flag on this panel and all it's children //----------------------------------------------------------------------------- void Panel::SetProportional(bool state) -{ +{ // only do something if the state changes if( state != _flags.IsFlagSet( IS_PROPORTIONAL ) ) { - _flags.SetFlag( IS_PROPORTIONAL, state ); + _flags.SetFlag( IS_PROPORTIONAL, state ); for(int i=0;im_pfnLookup)( panel ) ); kv->SetFloat( entry->name(), *(float *)data ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -5936,7 +5801,7 @@ class CProportionalFloatProperty : public vgui::IPanelAnimationPropertyConverter f = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), f ); kv->SetFloat( entry->name(), f ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -5962,7 +5827,7 @@ class CIntProperty : public vgui::IPanelAnimationPropertyConverter void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); kv->SetInt( entry->name(), *(int *)data ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -5986,7 +5851,7 @@ class CProportionalIntProperty : public vgui::IPanelAnimationPropertyConverter i = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), i ); kv->SetInt( entry->name(), i ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -6030,7 +5895,7 @@ class CProportionalIntWithScreenspacePropertyX : public vgui::IPanelAnimationPro // now correct the alignment if ( bRightAlign ) { - iValue = screenSize - iValue; + iValue = screenSize - iValue; } else if ( bCenterAlign ) { @@ -6084,7 +5949,7 @@ class CColorProperty : public vgui::IPanelAnimationPropertyConverter void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); kv->SetColor( entry->name(), *(Color *)data ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() ); @@ -6125,7 +5990,7 @@ class CBoolProperty : public vgui::IPanelAnimationPropertyConverter void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); kv->SetInt( entry->name(), *(bool *)data ? 1 : 0 ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -6154,7 +6019,7 @@ class CStringProperty : public vgui::IPanelAnimationPropertyConverter void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); kv->SetString( entry->name(), (char *)data ); } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -6182,7 +6047,7 @@ class CHFontProperty : public vgui::IPanelAnimationPropertyConverter kv->SetString( entry->name(), fontName ); } } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() ); @@ -6227,7 +6092,7 @@ class CTextureIdProperty : public vgui::IPanelAnimationPropertyConverter kv->SetString( entry->name(), "" ); } } - + virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry ) { void *data = ( void * )( (*entry->m_pfnLookup)( panel ) ); @@ -6416,7 +6281,7 @@ void Panel::InternalApplySettings( PanelAnimationMap *map, KeyValues *inResource { // Loop through keys KeyValues *kv; - + for ( kv = inResourceData->GetFirstSubKey(); kv; kv = kv->GetNextKey() ) { char const *varname = kv->GetName(); @@ -6455,14 +6320,14 @@ void Panel::InternalInitDefaultValues( PanelAnimationMap *map ) } if ( map->baseMap ) - { + { InternalInitDefaultValues( map->baseMap ); } } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- int Panel::GetPaintBackgroundType() { @@ -6470,9 +6335,9 @@ int Panel::GetPaintBackgroundType() } //----------------------------------------------------------------------------- -// Purpose: -// Input : w - -// h - +// Purpose: +// Input : w - +// h - //----------------------------------------------------------------------------- void Panel::GetCornerTextureSize( int& w, int& h ) { @@ -6667,13 +6532,13 @@ void Panel::DrawBoxFade(int x, int y, int wide, int tall, Color color, float nor } //----------------------------------------------------------------------------- -// Purpose: -// Input : x - -// y - -// wide - -// tall - -// color - -// normalizedAlpha - +// Purpose: +// Input : x - +// y - +// wide - +// tall - +// color - +// normalizedAlpha - //----------------------------------------------------------------------------- void Panel::DrawHollowBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha ) { @@ -6737,13 +6602,13 @@ void Panel::DrawTexturedBox(int x, int y, int wide, int tall, Color color, float //----------------------------------------------------------------------------- // Purpose: Marks this panel as draggable (note that children will chain to their parents to see if any parent is draggable) -// Input : enabled - +// Input : enabled - //----------------------------------------------------------------------------- void Panel::SetDragEnabled( bool enabled ) { #if defined( VGUI_USEDRAGDROP ) // If turning it off, quit dragging if mid-drag - if ( !enabled && + if ( !enabled && m_pDragDrop->m_bDragging ) { OnFinishDragging( false, (MouseCode)-1 ); @@ -6753,8 +6618,8 @@ void Panel::SetDragEnabled( bool enabled ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsDragEnabled() const @@ -6782,8 +6647,8 @@ void Panel::SetBlockDragChaining( bool block ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsBlockingDragChaining() const @@ -6816,7 +6681,7 @@ void Panel::SetDragSTartTolerance( int nTolerance ) //----------------------------------------------------------------------------- // Purpose: Marks this panel as droppable ( note that children will chain to their parents to see if any parent is droppable) -// Input : enabled - +// Input : enabled - //----------------------------------------------------------------------------- void Panel::SetDropEnabled( bool enabled, float flHoverContextTime /* = 0.0f */ ) { @@ -6827,8 +6692,8 @@ void Panel::SetDropEnabled( bool enabled, float flHoverContextTime /* = 0.0f */ } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsDropEnabled() const @@ -6840,17 +6705,17 @@ bool Panel::IsDropEnabled() const } //----------------------------------------------------------------------------- -// Purpose: Chains up to any parent -// 1) marked DropEnabled; and +// Purpose: Chains up to any parent +// 1) marked DropEnabled; and // 2) willing to accept the drop payload -// Input : - +// Input : - // Output : Panel //----------------------------------------------------------------------------- Panel *Panel::GetDropTarget( CUtlVector< KeyValues * >& msglist ) { #if defined( VGUI_USEDRAGDROP ) // Found one - if ( m_pDragDrop->m_bDropEnabled && + if ( m_pDragDrop->m_bDropEnabled && IsDroppable( msglist ) ) { return this; @@ -6868,7 +6733,7 @@ Panel *Panel::GetDropTarget( CUtlVector< KeyValues * >& msglist ) //----------------------------------------------------------------------------- // Purpose: Chains up to first parent marked DragEnabled -// Input : - +// Input : - // Output : Panel //----------------------------------------------------------------------------- Panel *Panel::GetDragPanel() @@ -6892,8 +6757,8 @@ Panel *Panel::GetDragPanel() } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- void Panel::OnStartDragging() { @@ -6923,15 +6788,15 @@ void Panel::OnStartDragging() //----------------------------------------------------------------------------- // Purpose: Called if drag drop is started but not dropped on top of droppable panel... -// Input : - +// Input : - //----------------------------------------------------------------------------- void Panel::OnDragFailed( CUtlVector< KeyValues * >& msglist ) { } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- void Panel::OnFinishDragging( bool mousereleased, MouseCode code, bool abort /*= false*/ ) { @@ -7075,8 +6940,8 @@ void Panel::OnDropContextHoverHide( CUtlVector< KeyValues * >& msglist ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *msg - +// Purpose: +// Input : *msg - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsDroppable( CUtlVector< KeyValues * >& msglist ) @@ -7085,11 +6950,11 @@ bool Panel::IsDroppable( CUtlVector< KeyValues * >& msglist ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : startx - -// starty - -// mx - -// my - +// Purpose: +// Input : startx - +// starty - +// mx - +// my - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::CanStartDragging( int startx, int starty, int mx, int my ) @@ -7135,8 +7000,8 @@ bool IsSelfDroppable( CUtlVector< KeyValues * > &dragData ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- void Panel::OnContinueDragging() { @@ -7264,8 +7129,8 @@ void Panel::OnContinueDragging() #if defined( VGUI_USEDRAGDROP ) //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : DragDrop_t //----------------------------------------------------------------------------- DragDrop_t *Panel::GetDragDropInfo() @@ -7282,7 +7147,7 @@ void Panel::OnGetAdditionalDragPanels( CUtlVector< Panel * >& dragabbles ) //----------------------------------------------------------------------------- // Purpose: Virtual method to allow panels to add to the default values -// Input : *msg - +// Input : *msg - //----------------------------------------------------------------------------- void Panel::OnCreateDragData( KeyValues *msg ) { @@ -7341,8 +7206,8 @@ void Panel::CreateDragData() } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : KeyValues //----------------------------------------------------------------------------- void Panel::GetDragData( CUtlVector< KeyValues * >& list ) @@ -7458,8 +7323,8 @@ void CDragDropHelperPanel::AddPanel( Panel *current ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : *search - +// Purpose: +// Input : *search - //----------------------------------------------------------------------------- void CDragDropHelperPanel::RemovePanel( Panel *search ) { @@ -7476,10 +7341,10 @@ void CDragDropHelperPanel::RemovePanel( Panel *search ) #endif //----------------------------------------------------------------------------- // Purpose: Enumerates panels under mouse x,y -// Input : panelList - -// x - -// y - -// check - +// Input : panelList - +// x - +// y - +// check - //----------------------------------------------------------------------------- void Panel::FindDropTargetPanel_R( CUtlVector< VPANEL >& panelList, int x, int y, VPANEL check ) { @@ -7503,8 +7368,8 @@ void Panel::FindDropTargetPanel_R( CUtlVector< VPANEL >& panelList, int x, int y } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Panel //----------------------------------------------------------------------------- Panel *Panel::FindDropTargetPanel() @@ -7568,7 +7433,7 @@ Panel *Panel::FindDropTargetPanel() //----------------------------------------------------------------------------- // Purpose: Mouse is on draggable panel and has started moving, but is not over a droppable panel yet -// Input : - +// Input : - //----------------------------------------------------------------------------- void Panel::OnDraggablePanelPaint() { @@ -7580,8 +7445,8 @@ void Panel::OnDraggablePanelPaint() input()->GetCursorPos( x, y ); int w, h; - w = min( sw, 80 ); - h = min( sh, 80 ); + w = MIN( sw, 80 ); + h = MIN( sh, 80 ); x -= ( w >> 1 ); y -= ( h >> 1 ); @@ -7604,7 +7469,7 @@ void Panel::OnDraggablePanelPaint() //----------------------------------------------------------------------------- // Purpose: Mouse is now over a droppable panel -// Input : *dragPanel - +// Input : *dragPanel - //----------------------------------------------------------------------------- void Panel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels ) { @@ -7628,8 +7493,8 @@ void Panel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVecto } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Color //----------------------------------------------------------------------------- Color Panel::GetDropFrameColor() @@ -7641,8 +7506,8 @@ Color Panel::GetDropFrameColor() } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Color //----------------------------------------------------------------------------- Color Panel::GetDragFrameColor() @@ -7654,8 +7519,8 @@ Color Panel::GetDragFrameColor() } //----------------------------------------------------------------------------- -// Purpose: -// Input : *data - +// Purpose: +// Input : *data - //----------------------------------------------------------------------------- void Panel::OnPanelDropped( CUtlVector< KeyValues * >& data ) { @@ -7679,8 +7544,8 @@ void Panel::OnPanelExitedDroppablePanel ( CUtlVector< KeyValues * >& msglist ) } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - //----------------------------------------------------------------------------- void Panel::DragDropStartDragging() { @@ -7719,8 +7584,8 @@ void Panel::DragDropStartDragging() } //----------------------------------------------------------------------------- -// Purpose: -// Input : - +// Purpose: +// Input : - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool Panel::IsBeingDragged() @@ -7827,8 +7692,8 @@ void Panel::FillRectSkippingPanel( const Color &clr, int x, int y, int w, int h, //----------------------------------------------------------------------------- -// Purpose: -// Input : *child - +// Purpose: +// Input : *child - //----------------------------------------------------------------------------- void Panel::SetSkipChildDuringPainting( Panel *child ) { @@ -7840,7 +7705,7 @@ HPanel Panel::ToHandle() const return ivgui()->PanelToHandle( _vpanel ); } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::NavigateUp() { @@ -7856,7 +7721,7 @@ Panel* Panel::NavigateUp() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::NavigateDown() { @@ -7872,7 +7737,7 @@ Panel* Panel::NavigateDown() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::NavigateLeft() { @@ -7887,7 +7752,7 @@ Panel* Panel::NavigateLeft() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::NavigateRight() { @@ -7926,7 +7791,7 @@ Panel* Panel::NavigateBack() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::NavigateTo() { @@ -7947,7 +7812,7 @@ void Panel::NavigateTo() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::NavigateFrom() { @@ -7982,7 +7847,7 @@ void Panel::NavigateToChild( Panel *pNavigateTo ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::SetNavUp( Panel* navUp ) { @@ -7998,7 +7863,7 @@ Panel* Panel::SetNavUp( Panel* navUp ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::SetNavDown( Panel* navDown ) { @@ -8014,7 +7879,7 @@ Panel* Panel::SetNavDown( Panel* navDown ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::SetNavLeft( Panel* navLeft ) { @@ -8030,7 +7895,7 @@ Panel* Panel::SetNavLeft( Panel* navLeft ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel* Panel::SetNavRight( Panel* navRight ) { @@ -8070,7 +7935,7 @@ Panel* Panel::SetNavBack( Panel* navBack ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- Panel::NAV_DIRECTION Panel::GetLastNavDirection() { @@ -8078,21 +7943,21 @@ Panel::NAV_DIRECTION Panel::GetLastNavDirection() } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::OnNavigateTo( const char* panelName ) { } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::OnNavigateFrom( const char* panelName ) { } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetNavUp( const char* controlName ) { @@ -8104,7 +7969,7 @@ void Panel::SetNavUp( const char* controlName ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetNavDown( const char* controlName ) { @@ -8115,7 +7980,7 @@ void Panel::SetNavDown( const char* controlName ) } } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetNavLeft( const char* controlName ) { @@ -8127,7 +7992,7 @@ void Panel::SetNavLeft( const char* controlName ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- void Panel::SetNavRight( const char* controlName ) { @@ -8166,7 +8031,7 @@ void Panel::SetNavBack( const char* controlName ) } //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- vgui::Panel* Panel::GetNavUp( Panel *first ) { @@ -8472,7 +8337,7 @@ class CPanelMessageMapDictionary }; char const *StripNamespace( char const *className ); - + CUtlDict< PanelMessageMapDictionaryEntry, int > m_MessageMaps; CUtlMemoryPool m_PanelMessageMapPool; }; @@ -8502,7 +8367,7 @@ PanelMessageMap *CPanelMessageMapDictionary::FindPanelMessageMap( char const *cl #include //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- PanelMessageMap *CPanelMessageMapDictionary::FindOrAddPanelMessageMap( char const *className ) { @@ -8541,7 +8406,7 @@ class CPanelKeyBindingMapDictionary }; char const *StripNamespace( char const *className ); - + CUtlDict< PanelKeyBindingMapDictionaryEntry, int > m_MessageMaps; CUtlMemoryPool m_PanelKeyBindingMapPool; }; @@ -8571,7 +8436,7 @@ PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindPanelKeyBindingMap( char #include //----------------------------------------------------------------------------- -// Purpose: +// Purpose: //----------------------------------------------------------------------------- PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindOrAddPanelKeyBindingMap( char const *className ) { @@ -8607,7 +8472,7 @@ namespace vgui { //----------------------------------------------------------------------------- - // Purpose: + // Purpose: //----------------------------------------------------------------------------- PanelMessageMap *FindOrAddPanelMessageMap( char const *className ) { @@ -8629,7 +8494,7 @@ namespace vgui return dictionary; } //----------------------------------------------------------------------------- - // Purpose: + // Purpose: //----------------------------------------------------------------------------- PanelKeyBindingMap *FindOrAddPanelKeyBindingMap( char const *className ) { @@ -8666,7 +8531,7 @@ void VguiPanelGetSortedChildPanelList( Panel *pParentPanel, void *pSortedPanels } } -void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, char *pchFilter /*= NULL*/, int nFilterType /*= 0*/ ) +void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, const char *pchFilter /*= NULL*/, int nFilterType /*= 0*/ ) { CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels ); diff --git a/vgui2/vgui_controls/PanelListPanel.cpp b/vgui2/vgui_controls/PanelListPanel.cpp index 995ce460..355ac08f 100644 --- a/vgui2/vgui_controls/PanelListPanel.cpp +++ b/vgui2/vgui_controls/PanelListPanel.cpp @@ -248,8 +248,7 @@ void PanelListPanel::DeleteAllItems() { if ( m_DataItems[i].panel ) { - m_DataItems[i].panel->MarkForDeletion(); - m_DataItems[i].panel = NULL; + delete m_DataItems[i].panel; } } diff --git a/vgui2/vgui_controls/PerforceFileExplorer.cpp b/vgui2/vgui_controls/PerforceFileExplorer.cpp index 50c1a419..130599bb 100644 --- a/vgui2/vgui_controls/PerforceFileExplorer.cpp +++ b/vgui2/vgui_controls/PerforceFileExplorer.cpp @@ -102,7 +102,7 @@ void PerforceFileExplorer::SetCurrentDirectory( const char *pFullPath ) m_CurrentDirectory = pFullPath; m_CurrentDirectory.StripTrailingSlash(); - m_CurrentDirectory.FixSlashes(); + Q_FixSlashes( m_CurrentDirectory.Get() ); PopulateFileList(); PopulateDriveList(); diff --git a/vgui2/vgui_controls/ProgressBox.cpp b/vgui2/vgui_controls/ProgressBox.cpp index c67f1737..b87354ee 100644 --- a/vgui2/vgui_controls/ProgressBox.cpp +++ b/vgui2/vgui_controls/ProgressBox.cpp @@ -26,7 +26,7 @@ using namespace vgui; #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif //----------------------------------------------------------------------------- diff --git a/vgui2/vgui_controls/PropertySheet.cpp b/vgui2/vgui_controls/PropertySheet.cpp index 18a36ca2..b76ad523 100644 --- a/vgui2/vgui_controls/PropertySheet.cpp +++ b/vgui2/vgui_controls/PropertySheet.cpp @@ -338,7 +338,7 @@ class PageTab : public Button GetSize(wide, tall); GetContentSize(contentWide, contentTall); - wide = max(m_bMaxTabWidth, contentWide + 10); // 10 = 5 pixels margin on each side + wide = MAX(m_bMaxTabWidth, contentWide + 10); // 10 = 5 pixels margin on each side wide += m_pContextLabel ? 10 : 0; SetSize(wide, tall); } @@ -1193,7 +1193,7 @@ void PropertySheet::RemovePage(Panel *panel) { _activePage = NULL; // if this page is currently active, backup to the page before this. - ChangeActiveTab( max( location - 1, 0 ) ); + ChangeActiveTab( MAX( location - 1, 0 ) ); } PerformLayout(); diff --git a/vgui2/vgui_controls/QueryBox.cpp b/vgui2/vgui_controls/QueryBox.cpp index 44226993..3102bdd4 100644 --- a/vgui2/vgui_controls/QueryBox.cpp +++ b/vgui2/vgui_controls/QueryBox.cpp @@ -17,7 +17,7 @@ #include #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif using namespace vgui; @@ -91,13 +91,13 @@ void QueryBox::PerformLayout() int btnWide, btnTall; m_pCancelButton->GetContentSize(btnWide, btnTall); - btnWide = max(oldWide, btnWide + 10); - btnTall = max(oldTall, btnTall + 10); + btnWide = MAX(oldWide, btnWide + 10); + btnTall = MAX(oldTall, btnTall + 10); m_pCancelButton->SetSize(btnWide, btnTall); //nt boxWidth, boxTall; GetSize(boxWidth, boxTall); -// wide = max(wide, btnWide * 2 + 100); +// wide = MAX(wide, btnWide * 2 + 100); // SetSize(wide, tall); m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide())-1 + x, tall - m_pOkButton->GetTall() - 15); diff --git a/vgui2/vgui_controls/RichText.cpp b/vgui2/vgui_controls/RichText.cpp index 66802324..3b24f1df 100644 --- a/vgui2/vgui_controls/RichText.cpp +++ b/vgui2/vgui_controls/RichText.cpp @@ -21,7 +21,7 @@ enum using namespace vgui; #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif namespace vgui @@ -2547,12 +2547,12 @@ int RichText::ParseTextStringForUrls( const char *text, int startPos, char *pchU // get the url i += Q_strlen( "" ); - Q_strncpy( pchURL, text + i, min( pchURLEnd - text - i + 1, cchURL ) ); + Q_strncpy( pchURL, text + i, MIN( pchURLEnd - text - i + 1, cchURL ) ); i += ( pchURLEnd - text - i + 1 ); // get the url text pchURLEnd = Q_strstr( text, "" ); - Q_strncpy( pchURLText, text + i, min( pchURLEnd - text - i + 1, cchURLText ) ); + Q_strncpy( pchURLText, text + i, MIN( pchURLEnd - text - i + 1, cchURLText ) ); i += ( pchURLEnd - text - i ); i += Q_strlen( "" ); diff --git a/vgui2/vgui_controls/ScalableImagePanel.cpp b/vgui2/vgui_controls/ScalableImagePanel.cpp index 24b707ba..9342532e 100644 --- a/vgui2/vgui_controls/ScalableImagePanel.cpp +++ b/vgui2/vgui_controls/ScalableImagePanel.cpp @@ -124,8 +124,8 @@ void ScalableImagePanel::PaintBackground() else { //uvh - row 1, is tall - ( 2 * src_corner_height ) ( min 0 ) - uvh = max( 1.0 - 2 * m_flCornerHeightPercent, 0.0f ); - drawH = max( 0, ( tall - 2 * m_iCornerHeight ) ); + uvh = MAX( 1.0 - 2 * m_flCornerHeightPercent, 0.0f ); + drawH = MAX( 0, ( tall - 2 * m_iCornerHeight ) ); } for ( col=0;col<3;col++ ) @@ -139,8 +139,8 @@ void ScalableImagePanel::PaintBackground() else { //uvw - col 1, is wide - ( 2 * src_corner_width ) ( min 0 ) - uvw = max( 1.0 - 2 * m_flCornerWidthPercent, 0.0f ); - drawW = max( 0, ( wide - 2 * m_iCornerWidth ) ); + uvw = MAX( 1.0 - 2 * m_flCornerWidthPercent, 0.0f ); + drawW = MAX( 0, ( wide - 2 * m_iCornerWidth ) ); } Vector2D uv11( uvx, uvy ); diff --git a/vgui2/vgui_controls/ScrollBar.cpp b/vgui2/vgui_controls/ScrollBar.cpp index 94d76088..d4e8a9b4 100644 --- a/vgui2/vgui_controls/ScrollBar.cpp +++ b/vgui2/vgui_controls/ScrollBar.cpp @@ -625,7 +625,7 @@ void ScrollBar::UseImages( const char *pszUpArrow, const char *pszDownArrow, con } else if ( m_pUpArrow ) { - m_pUpArrow->MarkForDeletion(); + m_pUpArrow->DeletePanel(); m_pUpArrow = NULL; } @@ -648,7 +648,7 @@ void ScrollBar::UseImages( const char *pszUpArrow, const char *pszDownArrow, con } else if ( m_pDownArrow ) { - m_pDownArrow->MarkForDeletion(); + m_pDownArrow->DeletePanel(); m_pDownArrow = NULL; } @@ -669,7 +669,7 @@ void ScrollBar::UseImages( const char *pszUpArrow, const char *pszDownArrow, con } else if ( m_pLine ) { - m_pLine->MarkForDeletion(); + m_pLine->DeletePanel(); m_pLine = NULL; } @@ -690,7 +690,7 @@ void ScrollBar::UseImages( const char *pszUpArrow, const char *pszDownArrow, con } else if ( m_pBox ) { - m_pBox->MarkForDeletion(); + m_pBox->DeletePanel(); m_pBox = NULL; } diff --git a/vgui2/vgui_controls/ScrollBarSlider.cpp b/vgui2/vgui_controls/ScrollBarSlider.cpp index 32df2fae..6f127558 100644 --- a/vgui2/vgui_controls/ScrollBarSlider.cpp +++ b/vgui2/vgui_controls/ScrollBarSlider.cpp @@ -18,7 +18,9 @@ #include #include +#if _MSC_VER < 1900 #include +#endif // memdbgon must be the last include file in a .cpp file!!! #include diff --git a/vgui2/vgui_controls/SectionedListPanel.cpp b/vgui2/vgui_controls/SectionedListPanel.cpp index 65e90239..7cc0e4a2 100644 --- a/vgui2/vgui_controls/SectionedListPanel.cpp +++ b/vgui2/vgui_controls/SectionedListPanel.cpp @@ -579,7 +579,7 @@ class CItemButton : public Label wide = imageWide; } - xpos += wide;//max(maxWidth,wide); + xpos += wide;//MAX(maxWidth,wide); surface()->DrawOutlinedRect( xpos, 0, xpos, GetTall() ); } } diff --git a/vgui2/vgui_controls/TextEntry.cpp b/vgui2/vgui_controls/TextEntry.cpp index 825cb4ab..14465387 100644 --- a/vgui2/vgui_controls/TextEntry.cpp +++ b/vgui2/vgui_controls/TextEntry.cpp @@ -3632,7 +3632,7 @@ void TextEntry::GetText(OUT_Z_BYTECAP(bufLenInBytes) wchar_t *wbuf, int bufLenIn int len = m_TextStream.Count(); if (m_TextStream.Count()) { - int terminator = min(len, (bufLenInBytes / (int)sizeof(wchar_t)) - 1); + int terminator = MIN(len, (bufLenInBytes / (int)sizeof(wchar_t)) - 1); wcsncpy(wbuf, m_TextStream.Base(), terminator); wbuf[terminator] = 0; } @@ -3645,18 +3645,18 @@ void TextEntry::GetText(OUT_Z_BYTECAP(bufLenInBytes) wchar_t *wbuf, int bufLenIn void TextEntry::GetTextRange( wchar_t *buf, int from, int numchars ) { int len = m_TextStream.Count(); - int cpChars = max( 0, min( numchars, len - from ) ); + int cpChars = MAX( 0, MIN( numchars, len - from ) ); - wcsncpy( buf, m_TextStream.Base() + max( 0, min( len, from ) ), cpChars ); + wcsncpy( buf, m_TextStream.Base() + MAX( 0, MIN( len, from ) ), cpChars ); buf[ cpChars ] = 0; } void TextEntry::GetTextRange( char *buf, int from, int numchars ) { int len = m_TextStream.Count(); - int cpChars = max( 0, min( numchars, len - from ) ); + int cpChars = MAX( 0, MIN( numchars, len - from ) ); - g_pVGuiLocalize->ConvertUnicodeToANSI( m_TextStream.Base() + max( 0, min( len, from ) ), buf, cpChars + 1 ); + g_pVGuiLocalize->ConvertUnicodeToANSI( m_TextStream.Base() + MAX( 0, MIN( len, from ) ), buf, cpChars + 1 ); buf[ cpChars ] = 0; } diff --git a/vgui2/vgui_controls/TextImage.cpp b/vgui2/vgui_controls/TextImage.cpp index 61532126..b6b9ff29 100644 --- a/vgui2/vgui_controls/TextImage.cpp +++ b/vgui2/vgui_controls/TextImage.cpp @@ -983,3 +983,117 @@ void TextImage::SetColorChangeStream( CUtlSortVector *pOutCoords, bool bIgnoreEmptyLines ) +{ + HFont font = GetFont(); + if (!_utext || font == INVALID_FONT ) + return; + + // Early out if there's no newlines in our text + if (wcschr( _utext, L'\n' ) == NULL) + return; + + if (m_bRecalculateTruncation) + { + if ( m_bWrap || m_bWrapCenter ) + { + RecalculateNewLinePositions(); + } + + RecalculateEllipsesPosition(); + } + + int lineHeight = surface()->GetFontTall( GetFont() ); + float x = 0.0f; + int y = 0; + int iIndent = 0; + + int px, py; + GetPos(px, py); + + int currentLineBreak = 0; + + if ( m_bWrapCenter && m_LineXIndent.Count() ) + { + x = m_LineXIndent[0]; + } + + for (wchar_t *wsz = _utext; *wsz != 0; wsz++) + { + wchar_t ch = wsz[0]; + + if ( m_bAllCaps ) + { + ch = towupper( ch ); + } + + // check for special characters + if ( ch == '\r' || ch <= 8 ) + { + // ignore, just use \n for newlines + continue; + } + else if (ch == '\n') + { + // newline + iIndent++; + if ( m_bWrapCenter && iIndent < m_LineXIndent.Count() ) + { + x = m_LineXIndent[iIndent]; + } + else + { + x = 0; + } + y += lineHeight; + + if (!bIgnoreEmptyLines || (*(wsz + 1) != 0 && wsz[1] != '\n')) + { + pOutCoords->AddToTail( y ); + } + + continue; + } + else if (ch == '&') + { + // "&&" means draw a single ampersand, single one is a shortcut character + if (wsz[1] == '&') + { + // just move on and draw the second ampersand + wsz++; + } + } + + // see if we've hit the truncated portion of the string + if (wsz == m_pwszEllipsesPosition) + { + // do nothing + } + + if (currentLineBreak != m_LineBreaks.Count()) + { + if (wsz == m_LineBreaks[currentLineBreak]) + { + // newline + iIndent++; + if ( m_bWrapCenter && iIndent < m_LineXIndent.Count() ) + { + x = m_LineXIndent[iIndent]; + } + else + { + x = 0; + } + + y += lineHeight; + currentLineBreak++; + } + } + + // Underlined text wants to draw the spaces anyway + x += surface()->GetCharacterWidth(font, ch); + } +} +#endif diff --git a/vgui2/vgui_controls/Tooltip.cpp b/vgui2/vgui_controls/Tooltip.cpp index e18427eb..7f9738d2 100644 --- a/vgui2/vgui_controls/Tooltip.cpp +++ b/vgui2/vgui_controls/Tooltip.cpp @@ -6,8 +6,8 @@ // and implement another button here. //=============================================================================// -#include -#define PROTECTED_THINGS_DISABLE +//#include +//#define PROTECTED_THINGS_DISABLE #include #include diff --git a/vgui2/vgui_controls/TreeView.cpp b/vgui2/vgui_controls/TreeView.cpp index b7ad4d3b..ae45d098 100644 --- a/vgui2/vgui_controls/TreeView.cpp +++ b/vgui2/vgui_controls/TreeView.cpp @@ -35,7 +35,7 @@ #include #ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif using namespace vgui; @@ -902,7 +902,7 @@ void TreeNode::CalculateVisibleMaxWidth() int childMaxWidth = GetMaxChildrenWidth(); childMaxWidth += TREE_INDENT_AMOUNT; - width = max(childMaxWidth, m_iNodeWidth); + width = MAX(childMaxWidth, m_iNodeWidth); } else { diff --git a/vgui2/vgui_controls/TreeViewListControl.cpp b/vgui2/vgui_controls/TreeViewListControl.cpp index 30cb3b75..2a678a08 100644 --- a/vgui2/vgui_controls/TreeViewListControl.cpp +++ b/vgui2/vgui_controls/TreeViewListControl.cpp @@ -301,7 +301,7 @@ void CTreeViewListControl::DrawTitleBars() } else { - int textRight = min( right, rightEdge ); + int textRight = MIN( right, rightEdge ); int midx = (left+textRight)/2; int midy = (top+bottom)/2; diff --git a/vpc_scripts/default.vgc b/vpc_scripts/default.vgc index 44974f60..f64f4dd2 100644 --- a/vpc_scripts/default.vgc +++ b/vpc_scripts/default.vgc @@ -10,10 +10,11 @@ $Games { - "HL2" "EPISODIC" + "HL2" "HL2MP" "VANCE" + } // Makes the VPC scripts work in the SDK's context diff --git a/vpc_scripts/groups.vgc b/vpc_scripts/groups.vgc index 3c3a7cb3..f0bf3a32 100644 --- a/vpc_scripts/groups.vgc +++ b/vpc_scripts/groups.vgc @@ -8,18 +8,35 @@ // Group definitions // /////////////////////// +$Group "gamedlls" +{ + "client" + "gamepadui" + "server" +} + $Group "game" { "client" "gamepadui" + "mathlib" + "raytrace" "server" "tier1" - "mathlib" + "vgui_controls" + "vscript" + "responserules" +} + +$Group "shaderdlls" +{ + "game_shader" } $Group "shaders" { - "game_shader_dx9" + "game_shader" + "mathlib" } $Group "everything" @@ -27,14 +44,15 @@ $Group "everything" "captioncompiler" "client" "fgdlib" - "game_shader_dx9" + "game_shader" "glview" "height2normal" "mathlib" "motionmapper" "phonemeextractor" - "raytrace" + "responserules" "qc_eyes" + "raytrace" "server" "serverplugin_empty" "tgadiff" @@ -44,29 +62,31 @@ $Group "everything" "vice" "vrad_dll" "vrad_launcher" + "vscript" "vtf2tga" "vtfdiff" "vvis_dll" "vvis_launcher" } -$Group "tools" +$Group "dedicated" { "mathlib" - "raytrace" + "server" "tier1" +} + +$Group "maptools" +{ "vbsp" - "vice" "vrad_dll" "vrad_launcher" "vvis_dll" "vvis_launcher" -} - -$Group "dedicated" -{ + "fgdlib" "mathlib" - "server" + "raytrace" "tier1" + "vscript" } diff --git a/vpc_scripts/newer_vs_toolsets.vpc b/vpc_scripts/newer_vs_toolsets.vpc new file mode 100644 index 00000000..292ee70f --- /dev/null +++ b/vpc_scripts/newer_vs_toolsets.vpc @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// NEWER_VS_TOOLSETS.VPC +// +// Additional toolsets added by Mapbase. +// +// NOTE: Enabling any of these makes the solution incompatible with Visual Studio 2013! +// +//----------------------------------------------------------------------------- + +$Conditional VS2015 "0" // Toggles Visual Studio 2015 (v140) toolset +$Conditional VS2017 "0" // Toggles Visual Studio 2017 (v141) toolset +$Conditional VS2019 "0" // Toggles Visual Studio 2019 (v142) toolset +$Conditional VS2022 "1" // Toggles Visual Studio 2022 (v143) toolset + +// +// VPC may still say "Generating for Visual Studio 2013" even when using one of the above toolsets. This message is irrelevant and can be ignored. +// +// The following projects currently do not compile with any of the above toolsets and are not included in their solutions: +// +// - phonemeextractor (may be fixable with modification) +// - qc_eyes (might be fixed by having C++ MFC for v141 build tools and/or C++ ATL for v141 build tools installed) +// + +//----------------------------------------------------------------------------- diff --git a/vpc_scripts/projects.vgc b/vpc_scripts/projects.vgc index fbd21df7..b77ce640 100644 --- a/vpc_scripts/projects.vgc +++ b/vpc_scripts/projects.vgc @@ -19,6 +19,7 @@ $Project "client" "game\client\client_episodic.vpc" [($WIN32||$X360||$POSIX) && $EPISODIC] "game\client\client_vance.vpc" [($WIN32||$X360||$POSIX) && $VANCE] "game\client\client_hl2mp.vpc" [($WIN32||$POSIX) && $HL2MP] + } $Project "fgdlib" @@ -26,7 +27,9 @@ $Project "fgdlib" "fgdlib\fgdlib.vpc" [$WIN32] } -$Project "game_shader_dx9" +// Echoes; Yes, I deliberately renamed this to game_shader. +// It's a part of my shader override trick. +$Project "game_shader" { "materialsystem\stdshaders\game_shader_dx9_hl2.vpc" [$HL2] "materialsystem\stdshaders\game_shader_dx9_episodic.vpc" [$EPISODIC] @@ -50,6 +53,12 @@ $Project "server" "game\server\server_episodic.vpc" [($WIN32||$X360||$POSIX) && $EPISODIC] "game\server\server_vance.vpc" [($WIN32||$X360||$POSIX) && $VANCE] "game\server\server_hl2mp.vpc" [($WIN32||$POSIX) && $HL2MP] + +} + +$Project "responserules" +{ + "responserules\runtime\response_rules.vpc" [($WINDOWS||$X360||$POSIX) && $NEW_RESPONSE_SYSTEM] } $Project "mathlib" @@ -64,7 +73,7 @@ $Project "motionmapper" $Project "phonemeextractor" { - "utils\phonemeextractor\phonemeextractor.vpc" [$WIN32] + "utils\phonemeextractor\phonemeextractor.vpc" [$WIN32 && !($VS2015||$VS2017||$VS2019||$VS2022)] // Not currently working with newer toolsets; may be fixable with modification } $Project "raytrace" @@ -74,7 +83,7 @@ $Project "raytrace" $Project "qc_eyes" { - "utils\qc_eyes\qc_eyes.vpc" [$WIN32] + "utils\qc_eyes\qc_eyes.vpc" [$WIN32 && !($VS2015||$VS2017||$VS2019||$VS2022)] // Not currently working with newer toolsets; might be fixed by having C++ MFC for v141 build tools and/or C++ ATL for v141 build tools installed } $Project "serverplugin_empty" @@ -117,6 +126,11 @@ $Project "vrad_launcher" "utils\vrad_launcher\vrad_launcher.vpc" [$WIN32] } +$Project "vscript" +{ + "vscript\vscript.vpc" +} + $Project "vtf2tga" { "utils\vtf2tga\vtf2tga.vpc" [$WIN32] @@ -142,4 +156,4 @@ $Project "gamepadui" "game\gamepadui\gamepadui_hl2.vpc" [$HL2] "game\gamepadui\gamepadui_episodic.vpc" [$EPISODIC] "game\gamepadui\gamepadui_vance.vpc" [$VANCE] -} \ No newline at end of file +} diff --git a/vpc_scripts/source_base.vpc b/vpc_scripts/source_base.vpc index 17de60eb..eb655e83 100644 --- a/vpc_scripts/source_base.vpc +++ b/vpc_scripts/source_base.vpc @@ -15,6 +15,16 @@ // rel/tf_beta branch: //$Conditional TF_BETA "1" +//----------------------------------------------------------------------------- + +// Mapbase functionality conditionals +$Conditional MAPBASE "1" // Equivalent to (and required for) our MAPBASE preprocessor defined below +$Conditional MAPBASE_RPC "0" // Toggles Mapbase's Rich Presence Client implementations (requires discord-rpc.dll in game bin) +$Conditional MAPBASE_VSCRIPT "1" // Toggles VScript implementation (note: interfaces still exist, just the provided implementation is not present) +$Conditional NEW_RESPONSE_SYSTEM "1" // Toggles the new Response System library based on the Alien Swarm SDK + +//----------------------------------------------------------------------------- + $Configuration "Debug" { $Compiler @@ -27,6 +37,9 @@ $Configuration "Debug" // Need to revisit the code to make things run with the _RETAIL preprocessor definition // This line was added in the previous check-in, but had previously not been defined in this branch // $PreprocessorDefinitions "$BASE;_RETAIL" [$RETAIL] + + // Mapbase base definitions + $PreprocessorDefinitions "$BASE;MAPBASE" [$MAPBASE] } } @@ -42,5 +55,8 @@ $Configuration "Release" // Need to revisit the code to make things run with the _RETAIL preprocessor definition // This line was added in the previous check-in, but had previously not been defined in this branch // $PreprocessorDefinitions "$BASE;_RETAIL" [$RETAIL] + + // Mapbase base definitions + $PreprocessorDefinitions "$BASE;MAPBASE" [$MAPBASE] } } diff --git a/vpc_scripts/source_dll_win32_base.vpc b/vpc_scripts/source_dll_win32_base.vpc index cec539ad..fdac37d0 100644 --- a/vpc_scripts/source_dll_win32_base.vpc +++ b/vpc_scripts/source_dll_win32_base.vpc @@ -39,12 +39,14 @@ $Configuration $Compiler [$WIN32] { - $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" + $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" [!($VS2015||$VS2017||$VS2019||$VS2022)] + $EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [($VS2015||$VS2017||$VS2019||$VS2022)] } $Linker { - $AdditionalDependencies "$BASE shell32.lib user32.lib advapi32.lib gdi32.lib comdlg32.lib ole32.lib" [$WIN32||$WIN64] + $AdditionalDependencies "$BASE shell32.lib user32.lib advapi32.lib gdi32.lib comdlg32.lib ole32.lib" [($WIN32||$WIN64) && !($VS2015||$VS2017||$VS2019||$VS2022)] + $AdditionalDependencies "$BASE shell32.lib user32.lib advapi32.lib gdi32.lib comdlg32.lib ole32.lib legacy_stdio_definitions.lib" [($WIN32||$WIN64) && ($VS2015||$VS2017||$VS2019||$VS2022)] $TargetMachine "MachineX86 (/MACHINE:X86)" [$WIN32] $TargetMachine "MachineX64 (/MACHINE:X64)" [$WIN64] // Suppress this pointless warning using the undocumented /ignore linker switch @@ -69,7 +71,7 @@ $Configuration "if ERRORLEVEL 1 goto BuildEventFailed" "\n" \ "if exist $QUOTE$(TargetDir)$(TargetName).map$QUOTE copy $QUOTE$(TargetDir)$(TargetName).map$QUOTE $OUTBINDIR\$(TargetName).map" "\n" $CommandLine "$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $QUOTE$OUTBINDIR\$(TargetName).pdb$QUOTE $SRCDIR" "\n" [!$SOURCESDK] - $CommandLine "$BASE" "copy $QUOTE$(TargetDir)$(TargetName).pdb$QUOTE $OUTBINDIR\$(TargetName).pdb" "\n" \ + $CommandLine "$BASE" "copy $QUOTE$(TargetDir)$(TargetName).pdb$QUOTE $QUOTE$OUTBINDIR\$(TargetName).pdb$QUOTE" "\n" \ "if ERRORLEVEL 1 goto BuildEventFailed" "\n" \ "goto BuildEventOK" "\n" \ ":BuildEventFailed" "\n" \ @@ -114,7 +116,8 @@ $Project $CustomBuildStep { // General - $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /safeseh /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" + $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /safeseh /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" [!($VS2015||$VS2017||$VS2019||$VS2022)] + $CommandLine "$QUOTE$(VC_ExecutablePath_x64_x86)\ml.exe$QUOTE /safeseh /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" [($VS2015||$VS2017||$VS2019||$VS2022)] $Description "Compiling pointeroverride.asm" $Outputs "$(IntDir)\$(InputName).obj" } diff --git a/vpc_scripts/source_dll_win32_debug.vpc b/vpc_scripts/source_dll_win32_debug.vpc index 52e111bf..c5b786d2 100644 --- a/vpc_scripts/source_dll_win32_debug.vpc +++ b/vpc_scripts/source_dll_win32_debug.vpc @@ -153,7 +153,7 @@ $Configuration "Debug" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmt;libcpmt;libcpmt1" + $IgnoreSpecificLibrary "libc;libcd;libcmt" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile diff --git a/vpc_scripts/source_dll_win32_release.vpc b/vpc_scripts/source_dll_win32_release.vpc index ba676d49..880e5efc 100644 --- a/vpc_scripts/source_dll_win32_release.vpc +++ b/vpc_scripts/source_dll_win32_release.vpc @@ -142,11 +142,8 @@ $Configuration "Release" $ErrorReporting "Prompt Immediately (/errorReport:prompt)" $AdditionalOptions "/Zm200" - // Enable extra debugging information. This switch requires VS 2013 Update 3. - // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that - // the debugger uses the enhanced debug information. - // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ - $AdditionalOptions "$BASE /Zo" + // Enable extra debugging information. + $AdditionalOptions "$BASE /d2Zi+" $AdditionalOptions "$BASE /Oy-" [$NOFPO] } @@ -168,7 +165,7 @@ $Configuration "Release" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmtd;libcpmtd;libcpmtd0;libcpmtd1" + $IgnoreSpecificLibrary "libc;libcd;libcmtd" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile diff --git a/vpc_scripts/source_exe_win_win32_base.vpc b/vpc_scripts/source_exe_win_win32_base.vpc index 47ce40fd..4d61b306 100644 --- a/vpc_scripts/source_exe_win_win32_base.vpc +++ b/vpc_scripts/source_exe_win_win32_base.vpc @@ -39,7 +39,8 @@ $Configuration $Compiler [$WIN32] { - $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" + $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" [!($VS2015||$VS2017||$VS2019||$VS2022)] + $EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [($VS2015||$VS2017||$VS2019||$VS2022)] } $Linker @@ -66,7 +67,9 @@ $Configuration $PostBuildEvent [!$ANALYZE] { - $CommandLine "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK] + $CommandLine "if not exist $QUOTE$OUTBINDIR$QUOTE mkdir $QUOTE$OUTBINDIR$QUOTE" "\n" [($VS2015||$VS2017||$VS2019||$VS2022)] + $CommandLine "$BASE" "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK && ($VS2015||$VS2017||$VS2019||$VS2022)] + $CommandLine "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\$(TargetFileName) $SRCDIR" "\n" [!$SOURCESDK && !($VS2015||$VS2017||$VS2019||$VS2022)] $CommandLine "$BASE" "copy $QUOTE$(TargetDir)$QUOTE$(TargetFileName) $OUTBINDIR\$(TargetFileName) >nul" "\n" \ "if ERRORLEVEL 1 goto BuildEventFailed" "\n" \ "if exist $QUOTE$(TargetDir)$QUOTE$(TargetName).map copy $QUOTE$(TargetDir)$QUOTE$(TargetName).map $OUTBINDIR\$(TargetName).map >nul" "\n" @@ -109,7 +112,8 @@ $Project $CustomBuildStep { // General - $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" + $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" [!($VS2015||$VS2017||$VS2019||$VS2022)] + $CommandLine "$QUOTE$(VC_ExecutablePath_x64_x86)\ml.exe$QUOTE /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE" [($VS2015||$VS2017||$VS2019||$VS2022)] $Description "Compiling pointeroverride.asm" $Outputs "$(IntDir)\$(InputName).obj" } diff --git a/vpc_scripts/source_exe_win_win32_debug.vpc b/vpc_scripts/source_exe_win_win32_debug.vpc index e329a255..399d1761 100644 --- a/vpc_scripts/source_exe_win_win32_debug.vpc +++ b/vpc_scripts/source_exe_win_win32_debug.vpc @@ -158,7 +158,7 @@ $Configuration "Debug" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmt;libcpmt;libcpmt1" + $IgnoreSpecificLibrary "libc;libcd;libcmt" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile diff --git a/vpc_scripts/source_exe_win_win32_release.vpc b/vpc_scripts/source_exe_win_win32_release.vpc index 2f9ab59f..6cb5c335 100644 --- a/vpc_scripts/source_exe_win_win32_release.vpc +++ b/vpc_scripts/source_exe_win_win32_release.vpc @@ -82,7 +82,7 @@ $Configuration "Release" // Preprocessor $PreprocessorDefinitions "$BASE;WIN32;_WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions)" - $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] + $PreprocessorDefinitions "$BASE;RELEASE_ASSERTS" [$RELEASEASSERTS] $IgnoreStandardIncludePath $GeneratePreprocessedFile $KeepComments @@ -141,11 +141,8 @@ $Configuration "Release" $OmitDefaultLibraryNames $ErrorReporting "Prompt Immediately (/errorReport:prompt)" - // Enable extra debugging information. This switch requires VS 2013 Update 3. - // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that - // the debugger uses the enhanced debug information. - // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ - $AdditionalOptions "$BASE /Zo" + // Enable extra debugging information. + $AdditionalOptions "$BASE /d2Zi+" // Command Line $AdditionalOptions "$BASE /Oy-" [$NOFPO] } @@ -168,7 +165,7 @@ $Configuration "Release" // Input $AdditionalDependencies $IgnoreAllDefaultLibraries - $IgnoreSpecificLibrary "libc;libcd;libcmtd;libcpmtd;libcpmtd0;libcpmtd1" + $IgnoreSpecificLibrary "libc;libcd;libcmtd" $ModuleDefinitionFile $AddModuleToAssembly $EmbedManagedResourceFile diff --git a/vpc_scripts/source_lib_win32_base.vpc b/vpc_scripts/source_lib_win32_base.vpc index 02caa800..bea9d867 100644 --- a/vpc_scripts/source_lib_win32_base.vpc +++ b/vpc_scripts/source_lib_win32_base.vpc @@ -38,7 +38,8 @@ $Configuration $Compiler [$WIN32] { - $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" + $EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)" [!($VS2015||$VS2017||$VS2019||$VS2022)] + $EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [($VS2015||$VS2017||$VS2019||$VS2022)] } $PreBuildEvent diff --git a/vpc_scripts/source_lib_win32_release.vpc b/vpc_scripts/source_lib_win32_release.vpc index 0ceb1eeb..cbfe4cab 100644 --- a/vpc_scripts/source_lib_win32_release.vpc +++ b/vpc_scripts/source_lib_win32_release.vpc @@ -139,11 +139,8 @@ $Configuration "Release" $OmitDefaultLibraryNames $ErrorReporting "Prompt Immediately (/errorReport:prompt)" - // Enable extra debugging information. This switch requires VS 2013 Update 3. - // With VS 2013 make sure that Edit-And-Continue is disabled in the debugger settings so that - // the debugger uses the enhanced debug information. - // http://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ - $AdditionalOptions "$BASE /Zo" + // Enable extra debugging information. + $AdditionalOptions "/d2Zi+" $AdditionalOptions "$BASE /Oy-" [$NOFPO] } diff --git a/vpc_scripts/source_linux_base_project.vpc b/vpc_scripts/source_linux_base_project.vpc index efb0bbbb..1c920c1b 100644 --- a/vpc_scripts/source_linux_base_project.vpc +++ b/vpc_scripts/source_linux_base_project.vpc @@ -13,8 +13,7 @@ $Configuration "Debug" $Compiler { $PreprocessorDefinitions "DEBUG;_DEBUG" - $OptimizerLevel "-gdwarf-2 -g $(OptimizerLevel_CompilerSpecific)" [$OSXALL] - $OptimizerLevel "-gdwarf-4 -g $(OptimizerLevel_CompilerSpecific)" [$LINUX] + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" } } @@ -23,9 +22,8 @@ $Configuration "Release" $Compiler { $PreprocessorDefinitions "NDEBUG" - $OptimizerLevel "-gdwarf-2 -g $(OptimizerLevel_CompilerSpecific)" [$OSXALL] - $OptimizerLevel "-gdwarf-4 -g $(OptimizerLevel_CompilerSpecific)" [$LINUX] $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" } } diff --git a/vpc_scripts/source_posix_base.vpc b/vpc_scripts/source_posix_base.vpc index 907a008c..9e17f832 100644 --- a/vpc_scripts/source_posix_base.vpc +++ b/vpc_scripts/source_posix_base.vpc @@ -12,8 +12,7 @@ $Configuration "Debug" $Compiler { $PreprocessorDefinitions "$BASE;DEBUG;_DEBUG" - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" [$OSXALL] - $OptimizerLevel "-gdwarf-4 -g2 $(OptimizerLevel_CompilerSpecific)" [$LINUX] + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" } } @@ -22,9 +21,7 @@ $Configuration "Release" $Compiler { $PreprocessorDefinitions "$BASE;NDEBUG" - $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" [$OSXALL] - $OptimizerLevel "-gdwarf-4 -g2 $(OptimizerLevel_CompilerSpecific)" [$LINUX] - $PreprocessorDefinitions "$BASE;RELEASEASSERTS" [$RELEASEASSERTS] + $OptimizerLevel "-gdwarf-2 -g2 $(OptimizerLevel_CompilerSpecific)" } } @@ -45,7 +42,6 @@ $Configuration $PreprocessorDefinitions "$BASE;_OSX;OSX;_DARWIN_UNLIMITED_SELECT;FD_SETSIZE=10240;" [$OSXALL] $PreprocessorDefinitions "$BASE;OVERRIDE_V_DEFINES" [$OSXALL] $PreprocessorDefinitions "$BASE;_LINUX;LINUX;" [$LINUXALL] - $PreprocessorDefinitions "$BASE;PLATFORM_64BITS" [$LINUX64] $SymbolVisibility "hidden" [$POSIX] $PreprocessorDefinitions "$BASE;POSIX;_POSIX" [$POSIX] diff --git a/vpc_scripts/source_win32_analyze.vpc b/vpc_scripts/source_win32_analyze.vpc index a1332dee..ceb6e0b0 100644 --- a/vpc_scripts/source_win32_analyze.vpc +++ b/vpc_scripts/source_win32_analyze.vpc @@ -36,8 +36,7 @@ $Configuration $DisableSpecificWarnings "$BASE;6308;6255;6387;6309;6011;6211;6326;6239;6285;6237;6235;6240;6323;6326;6335;6320;6250;6384;6318;6322" [$ANALYZE] // See http://randomascii.wordpress.com/2011/10/04/analyzecommand-line-options/ for details on these options. // /analyze:only may result in fewer warnings being reported, but the warnings it misses should show up in the regular build. - $AdditionalOptions "$BASE /analyze /analyze:stacksize100000" [$ANALYZE] - $AdditionalOptions "$BASE /analyze:only" [$ANALYZE && $ANALYZE_MACHINE] // /analyze:only makes builds faster on buildbot but is terrible for incremental /analyze on developer machines + $AdditionalOptions "$BASE /analyze /analyze:only /analyze:stacksize100000" [$ANALYZE] // Specify /define:ALLOWSHADOWING to suppress variable shadowing warnings $DisableSpecificWarnings "$BASE;6244;6246" [$ANALYZE && $ALLOWSHADOWING] diff --git a/vpc_scripts/source_win32_base.vpc b/vpc_scripts/source_win32_base.vpc index 4d41cb31..e94ebd76 100644 --- a/vpc_scripts/source_win32_base.vpc +++ b/vpc_scripts/source_win32_base.vpc @@ -3,16 +3,22 @@ // builds the analyze.vpc file will not be listed as a dependency. $Include "$SRCDIR\vpc_scripts\source_win32_analyze.vpc" [$ANALYZE] +// Mapbase - Implement any newer toolsets +$Include "$SRCDIR\vpc_scripts\newer_vs_toolsets.vpc" + $Configuration { $General { // Request a specific compiler toolset. - $PlatformToolset "v100" [$VS2010] - $PlatformToolset "v110_xp" [$VS2012 && !$ANALYZE] // VS 2012 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx - $PlatformToolset "v110" [$VS2012 && $ANALYZE] // VS 2012 for /analyze - $PlatformToolset "v120_xp" [$VS2013 && !$ANALYZE] // VS 2013 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx - $PlatformToolset "v120" [$VS2013 && $ANALYZE] // VS 2013 for /analyze + $PlatformToolset "v110_xp" [$VS2012 && !$ANALYZE && !($VS2015||$VS2017||$VS2019||$VS2022)] // VS 2012 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx + $PlatformToolset "v110" [$VS2012 && $ANALYZE && !($VS2015||$VS2017||$VS2019||$VS2022)] // VS 2012 for /analyze + $PlatformToolset "v120_xp" [$VS2013 && !$ANALYZE && !($VS2015||$VS2017||$VS2019||$VS2022)] // VS 2013 targeting Windows XP - http://msdn.microsoft.com/en-us/library/vstudio/jj851139.aspx + $PlatformToolset "v120" [$VS2013 && $ANALYZE && !($VS2015||$VS2017||$VS2019||$VS2022)] // VS 2013 for /analyze + $PlatformToolset "v140" [$VS2015] // VS 2015 + $PlatformToolset "v141" [$VS2017] // VS 2017 + $PlatformToolset "v142" [$VS2019] // VS 2019 + $PlatformToolset "v143" [$VS2022] // VS 2022 } $General @@ -32,6 +38,10 @@ $Configuration // warning C4316: object allocated on the heap may not be aligned 16 $DisableSpecificWarnings "$BASE;4316" [$VS2013] + + // warning C4838: conversion requires a narrowing conversion + // warning C4456-4459: variable shadowing. TODO: fix those! + $DisableSpecificWarnings "$BASE;4316;4838;4456;4457;4458;4459" [($VS2015||$VS2017||$VS2019||$VS2022)] // Having lots of warnings makes it harder to notice new, and possibly // important warnings, both on buildbot and in the output window. Lots @@ -51,8 +61,5 @@ $Configuration // effect. This option does not show up in the IDE so we need to add it in $AdditionalOptions. // http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx $AdditionalOptions "$BASE /Gw" [$VS2013] - // Strip unreferenced inline functions from object files to shrink .obj files and .lib files, - // improve linker speed, and improve conformance. Requires VS 2013 Update 3 - $AdditionalOptions "$BASE /Zc:inline" [$VS2013] } } diff --git a/vscript/sqstdtime.h b/vscript/sqstdtime.h new file mode 100644 index 00000000..fbf1bee7 --- /dev/null +++ b/vscript/sqstdtime.h @@ -0,0 +1,88 @@ +//----------------------------------------------------------------------- +// see copyright notice in squirrel.h +// +// Purpose : Squirrel time library cropped out from +// the system library as a safe include. +// +//----------------------------------------------------------------------- + +#include "squirrel.h" +#include "time.h" + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v, ((SQFloat)clock()) / (SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + SQInteger t = (SQInteger)time(NULL); + sq_pushinteger(v, t); + return 1; +} + +static void _set_integer_slot(HSQUIRRELVM v, const SQChar *name, SQInteger val) +{ + sq_pushstring(v, name, -1); + sq_pushinteger(v, val); + sq_rawset(v, -3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if (sq_gettop(v) > 1) { + sq_getinteger(v, 2, &it); + t = it; + if (sq_gettop(v) > 2) { + sq_getinteger(v, 3, (SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if (format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if (!date) + return sq_throwerror(v, _SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year + 1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static const SQRegFunction timelib_funcs[] = { + _DECL_FUNC(clock, 0, NULL), + _DECL_FUNC(time, 1, NULL), + _DECL_FUNC(date, -1, _SC(".nn")), + { NULL, (SQFUNCTION)0, 0, NULL } +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_timelib(HSQUIRRELVM v) +{ + SQInteger i = 0; + while (timelib_funcs[i].name != 0) + { + sq_pushstring(v, timelib_funcs[i].name, -1); + sq_newclosure(v, timelib_funcs[i].f, 0); + sq_setparamscheck(v, timelib_funcs[i].nparamscheck, timelib_funcs[i].typemask); + sq_setnativeclosurename(v, -1, timelib_funcs[i].name); + sq_newslot(v, -3, SQFalse); + i++; + } + return 1; +} diff --git a/vscript/squirrel/.gitignore b/vscript/squirrel/.gitignore new file mode 100644 index 00000000..6e97beb7 --- /dev/null +++ b/vscript/squirrel/.gitignore @@ -0,0 +1,6 @@ +# Folders created at compilation +bin/ +lib/ + +# Folders created at documentation generation +doc/build/ diff --git a/vscript/squirrel/.travis.yml b/vscript/squirrel/.travis.yml new file mode 100644 index 00000000..1e31c1d6 --- /dev/null +++ b/vscript/squirrel/.travis.yml @@ -0,0 +1,17 @@ +language: cpp +compiler: + - gcc + - clang + +# Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the +# 32-bit builds to work, we need gcc-multilib. +addons: + apt: + packages: + - gcc-multilib + - g++-multilib + +# Enable container-based builds. +sudo: false + +script: mkdir build && cd build && cmake .. && make -j2 diff --git a/vscript/squirrel/CMakeLists.txt b/vscript/squirrel/CMakeLists.txt new file mode 100644 index 00000000..dc35b6f4 --- /dev/null +++ b/vscript/squirrel/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.4) +project(squirrel VERSION 3.1 LANGUAGES C CXX) + +option(DISABLE_STATIC "Avoid building/installing static libraries.") +option(LONG_OUTPUT_NAMES "Use longer names for binaries and libraries: squirrel3 (not sq).") + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif () + +include(GNUInstallDirs) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") +set(CMAKE_CXX_STANDARD 11) + +if(CMAKE_COMPILER_IS_GNUCXX) + add_compile_options( + "$<$:-fno-rtti;-fno-exceptions>" + -fno-strict-aliasing + -Wall + -Wextra + -pedantic + -Wcast-qual + "$<$:-O3>" + "$<$:-O3;-g>" + "$<$:-Os>" + "$<$:-pg;-pie;-gstabs;-g3;-Og>" + ) +elseif(MSVC) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +add_subdirectory(squirrel) +add_subdirectory(sqstdlib) +add_subdirectory(sq) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(tgts) + if(NOT DISABLE_DYNAMIC) + list(APPEND tgts squirrel sqstdlib sq) + endif() + if(NOT DISABLE_STATIC) + list(APPEND tgts squirrel_static sqstdlib_static sq_static) + endif() + foreach(t ${tgts}) + target_compile_definitions(${t} PUBLIC -D_SQ64) + endforeach() +endif() + +if(NOT DISABLE_DYNAMIC) + set_target_properties(squirrel sqstdlib PROPERTIES SOVERSION 0 VERSION 0.0.0) +endif() + +if(NOT SQ_DISABLE_INSTALLER AND NOT SQ_DISABLE_HEADER_INSTALLER) + install(FILES + include/sqconfig.h + include/squirrel.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT Development + ) + install(FILES + include/sqstdaux.h + include/sqstdblob.h + include/sqstdio.h + include/sqstdmath.h + include/sqstdstring.h + include/sqstdsystem.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT Development + ) +endif() + +include(CMakePackageConfigHelpers) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config-version.cmake" + VERSION "${squirrel_VERSION}" + COMPATIBILITY AnyNewerVersion + ) + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/squirrel-config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" + ) + +export(EXPORT squirrel + NAMESPACE squirrel:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-targets.cmake" + ) + +if(NOT SQ_DISABLE_INSTALLER AND NOT SQ_DISABLE_CMAKE_INSTALLER) + install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config-version.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" + COMPONENT Development + ) + + install(EXPORT squirrel + NAMESPACE squirrel:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" + FILE "squirrel-targets.cmake" + COMPONENT Development + ) +endif() diff --git a/vscript/squirrel/COMPILE b/vscript/squirrel/COMPILE new file mode 100644 index 00000000..375a9209 --- /dev/null +++ b/vscript/squirrel/COMPILE @@ -0,0 +1,86 @@ +Squirrel 3.1 stable +-------------------------------------------------------- +What is in this distribution? + +squirrel + static library implementing the compiler and interpreter of the language + +sqstdlib + the standard utility libraries + +sq + stand alone interpreter + +doc + The manual + +etc + a minimalistic embedding sample + +samples + samples programs + + +HOW TO COMPILE +--------------------------------------------------------- +CMAKE USERS +......................................................... +If you want to build the shared libraries under Windows using Visual +Studio, you will have to use CMake version 3.4 or newer. If not, an +earlier version will suffice. For a traditional out-of-source build +under Linux, type something like + + $ mkdir build # Create temporary build directory + $ cd build + $ cmake .. # CMake will determine all the necessary information, + # including the platform (32- vs. 64-bit) + $ make + $ make install + $ cd ..; rm -r build + +The default installation directory will be /usr/local on Unix platforms, +and C:/Program Files/squirrel on Windows. The binaries will go into bin/ +and the libraries into lib/. You can change this behavior by calling CMake like +this: + + $ cmake .. -DCMAKE_INSTALL_PREFIX=/some/path/on/your/system + +With the CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBDIR options, the directories +the binaries & libraries will go in (relative to CMAKE_INSTALL_PREFIX) +can be specified. For instance, + + $ cmake .. -DCMAKE_INSTALL_LIBDIR=lib64 + +will install the libraries into a 'lib64' subdirectory in the top +source directory. The public header files will be installed into the directory +the value of CMAKE_INSTALL_INCLUDEDIR points to. If you want only the +binaries and no headers, just set -DSQ_DISABLE_HEADER_INSTALLER=ON, and no +header files will be installed. + +Under Windows, it is probably easiest to use the CMake GUI interface, +although invoking CMake from the command line as explained above +should work as well. + +GCC USERS +......................................................... +There is a very simple makefile that compiles all libraries and exes +from the root of the project run 'make' + +for 32 bits systems + + $ make + +for 64 bits systems + + $ make sq64 + +VISUAL C++ USERS +......................................................... +Open squirrel.dsw from the root project directory and build(dho!) + +DOCUMENTATION GENERATION +......................................................... +To be able to compile the documentation, make sure that you have Python +installed and the packages sphinx and sphinx_rtd_theme. Browse into doc/ +and use either the Makefile for GCC-based platforms or make.bat for +Windows platforms. diff --git a/vscript/squirrel/COPYRIGHT b/vscript/squirrel/COPYRIGHT new file mode 100644 index 00000000..17d13ac1 --- /dev/null +++ b/vscript/squirrel/COPYRIGHT @@ -0,0 +1,21 @@ +Copyright (c) 2003-2017 Alberto Demichelis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------- +END OF COPYRIGHT diff --git a/vscript/squirrel/HISTORY b/vscript/squirrel/HISTORY new file mode 100644 index 00000000..f8c29e6b --- /dev/null +++ b/vscript/squirrel/HISTORY @@ -0,0 +1,533 @@ +***version 3.2 stable*** +-added sq_tailcall +-added rawcall keyword +-added post call initializer syntax +-added table.keys() and table.values() +-added table.filter() +-additional parameters in array.map() and array.apply() +-additional optional initializer in array.reduce() +-closure.call() is now a "native tailcall" and the invoked function can now be suspended +-fixed sq_newmember and sq_rawnewmember properly pop parameters +-fixed capturing free variable on for loop counter before a break statement +-fixed \u in lexer +-various bugfixes + +***version 3.1.1 stable*** +-sq_gettypetag doesn't set last error(it's treated as SQBool function but keeps a SQRESULT for backward compatibility) +-fixed _set method in userdata delegates +-fixed some warnings + +***version 3.1 stable*** +-added slice range for tolower and toupper +-added startswith() and endswith() in string lib +-added SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS to exclude default mem fuction from compilation +-added sq_getreleasehook +-added thread.wakeupthrow() +-added sq_pushthread +-added \u and \U escape sequence for UTF8,UTF16 or UCS4 characters +-added CMake scripts(thx Fabian Wolff) +-the escape character \x is based on sizeof(SQChar) +-fixed several warnings(thx Markus Oberhumer) +-fixed optimizer bug in compound arith oprators(+=,-= etc...) +-fixed sq_getrefvmcount() (thx Gerrit) +-fixed sq_getrefcount() when no references were added with sq_addref() (thx Gerrit) +-fixed bug in string.tointeger() (thx Domingo) +-fixed weakref comparison in 32bit builds using doubles(thx Domingo) +-fixed compiler bug(thx Peter) +-fixed some error in the documentation(thx Alexander) +-fixed some error reporting in compiler(thx Alexander) +-fixed incorrect optional semicolon after "if block"(thx Alexander) +-fixed crash bug in compiler related to compound arith operators(+=,-= etc...) (thx Jeff1) + +***2015-01-10 *** +***version 3.1 RC 1*** +-added new header sqconfig.h for all optional type declarations(unicode, 64bits etc..) +-added sq_setsharedforeignptr sq_getsharedforeignptr +-added sq_setsharedreleasehook sq_getsharedreleasehook +-added escape() in sqstd string library +-added __LINE__ and __FILE__ (thx mingodad) +-widechar support on gcc builds +-now boolean can be used in constants +-reduced dependencies on C runtime library +-newthread and sq_newthread() no longer reinitialize the root table on friend VMs(thx Lucas Cardellini) +-exceptions in the _inherited metamethod are propagated(thx Lucas Cardellini) +-'in' operator performance improvement(thx unagipai and mingodad) +-fixes crash in compiler when trying to write 'base' +-fixed bug in switch statement when using locals as case values (thx mingodad) +-fixed bug in print()(thx Lucas Cardellini) + +***2013-08-30 *** +***version 3.1 beta 1*** +-added new scoping rule(root attached to closures) +-added closure.setroot() closure.getroot() +-added sq_setclosureroot() and sq_getclosureroot() +-added sq_setvmreleasehook() and sq_getvmreleasehook() +-added documentaion for sq_getbase() +-now string.tointeger() accepts an optional parameter 'base' +-now format accepts zeroes in the format string (thx mingodad) +-fixed bug in sqstd_createfile() (thx mingodad) +-minor buxfixes + +***2012-11-10 *** +***version 3.0.4 stable*** +-sq_deleteslot slot now pops the key in case of failure +-fixed bug when _get metamethod throws null +-fixed a bug in rstrip +-added some error handling +-minor bugfixes + +***2012-06-19 *** +***version 3.1.0 alpha 1*** +-changed in and instanceof operator precendence +-root object in closures +-added closure.setroot closure.getroot +-added sq_setclosureroot and sq_getclosureroot + +***version 3.0.3 stable*** +-improved error messages for _cmp(when a non integer value is returned) (thx Yexo) +-added class.newmember() built in method (thx Nam) +-added class.rawnewmember() built in method (thx Nam) +-added sq_rawnewmember() (thx Nam) +-added sq_getversion() +-added sq_typeof() +-added sq_getclosurename() +-added file.close() in stdlib +-documented closure.getinfos() built-in method +-fixed string iteration doesn't return negative numbers for characters > 127 +-fixed bug in tofloat() when converting a string with scientific notation without a decimal point (thx wr2) +-fixed potential infinite loop in array.sort() when the _cmp function is inconsistent (thx Yexo) +-fixed obscure bug in the compiler(thx yishin) +-fixed some minor bug + +***2011-11-28 *** +***version 3.0.2 stable*** +-added sq_gethash API +-now array.sort() is implemented with heapsort +-now floats in scientific notation also accept numbers with no '.' (eg. 1e+6 or 1e6) +-fixed some warning +-fixed some documentation +-fixed bug in GC + +***2011-09-08 *** +***version 3.0.1 stable*** +-added # as alternative symbol for "line comment"(mostly useful for shell scripts) +-added sq_throwobject() to throw an arbitrary object from the C API +-added alignement flag for userdata types, SQ_ALIGNMENT (thx Shigemasa) +-added rawset() and rawget() to class and instance default delegate +-changed bytecode format now ensures matching integer size and float size +-now inherited classes also inherit userdatasize +-added SQUIRREL_VERSION_NUMBER in squirrel.h and _versionnumber_ global symbol +-fixed sq_getmemberhandle +-fixed sq_getrefcount +-refactored some sqstdio code +-refactored some clone code +-refactored some stuff in the string lib +-added -s and -fno-exceptions in GCC makefile(better performance when using GCC) + +***2011-03-13 *** +***version 3.0 stable*** +-added sq_getcallee() +-sq_getfreevariable() also works for native closures +-minior optimizations +-removed several warning when compiling with GCC 4.x +-fixed some errors in the documentation +-fixed bug when using SQUSEDOUBLE and 32bits intengers +-fixed bug when invoking generators with closure.call() (thx huntercool) + +***2010-12-19 *** +***version 3.0 release candidate 1(RC 1)*** +-improved metamethods error handling +-added parameter 'isstatic' to _newmember metamethod(thx G.Meyer) +-added sq_getrefcount() to return number of refences from C++(thx G.Meyer) + +***2010-11-07 *** +***version 3.0 beta 3*** +-license changed to "MIT license" +-added sq_resurrectunreachable() and resurrectunreachable() +-added callee() built in function, returns the current running closure +-added thread.getstackinfos() +-added sq_objtouserpointer() +-added sq_newtableex() +-various refactoring and optimizations +-fixed several 64bits issues regarding integer to string conversions +-fixed some bugs when SQUSEDOUBLE is used in 32bits systems + +***2010-08-18 *** +***version 3.0 beta 2.1*** +-fixed bug in class constructor +-fixed bug in compound arith + +***2010-08-12 *** +***version 3.0 beta 2*** +-class methods can be added or replaced after the class as been instantiated +-JSON compliant table syntax, this is currently an experimental feature (thx atai) +-sq_getsize() now returns userdatasize for classes and instances +-now setroottable() and setconsttable() return the previous value of the respective table +-fixed bug in compound arith operators when used on a free variable (thx ellon) +-fixed some x64 minor bugs +-fixed minor bug in the compiler +-refactored some VM internals +-documented sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes + +***2009-11-15 *** +***version 3.0 beta 1*** +-various refactoring and optimizations +-fixed bug in free variables (thx mokehehe) +-fixed bug in functions with default parameters (thx ara & Yexo) +-fixed bug in exception handling +-improved error propagation in _set and _get metamethods ( and 'throw null' for clean failure) +-added sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes + +***2009-06-30 *** +***version 3.0 alpha 2*** +-added real free variables(thx Paul Ruizendaal) +-added refactored function call implementation and compiler(thx Paul Ruizendaal) +-added sq_getfunctioninfo +-added compile time flag SQUSEDOUBLE to use double precision floats +-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds +-sq_wakeupvm can now resume the vm with an exception +-added sqstd_format +-now blobs can be cloned +-generators can now be instantiated by calling sq_call() or closure.call() +-fixed debughook bug +-fixed cooroutine error propagation + +***2008-07-23 *** +***version 3.0 alpha 1*** +-first branch from 2.x source tree +-added 'base' keyword +-removed 'delegate' keyword +-now compiled scripts are vararg functions +-added setdelegate() and getdelegate() table builtin methods +-added <=> 3 ways compare operator +-added lambda expression @(a,b) a + b +-added local function statement +-added array built-in map(),reduce(),apply(),filter() and find() +-generators hold only a weak reference of the enviroment object +-removed 'vargv' and 'vargc' keywords +-now var args are passed as an array called vargv(as a paramter) +-removed 'parent' keyword +-added class getbase() built in method +-instanceof doesn't throw an exception if the left expression is not a class +-lexical scoping for free variables(free variables are no longer in the second parameter list) +-sq_setprintfunc accept error func +-sq_geterrorfunc() +-added sq_arrayremove() and sq_arrayinsert() +-error() built in function(works like print but prints using the errorfunc) +-added native debug hook + +***2008-02-17 *** +***version 2.2 stable*** +-added _newslot metamethod in classes +-added enums added constants +-added sq_pushconsttable, sq_setconsttable +-added default param +-added octal literals(thx Dinosaur) +-fixed debug hook, 'calls' and 'returns' are properly notified in the same number. +-fixed a coroutine bug + +***2007-07-29 *** +***version 2.1.2 stable*** +-new behaviour for generators iteration using foreach +now when a generator is iterated by foreach the value returned by a 'return val' statement +will terminate the iteration but will not be returned as foreach iteration +-added sq_setclassudsize() +-added sq_clear() +-added table.clear(), array.clear() +-fixed sq_cmp() (thx jyuill) +-fixed minor bugs + +***2006-08-21 *** +***version 2.1.1 stable*** +-vm refactoring +-optimized internal function memory layout +-new global symbol _version_ (is the version string) +-code size optimization for float literals(on 32bits float builts) +-now the raw ref API(sq_addref etc...) is fully reentrant. +-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB) +-improved C reference performances in NO_GARBAGE_COLLECTOR builds +-sq_getlocal() now enumerates also outer values. +-fixed regexp library for GCC users. + +***2006-03-19 *** +***version 2.1 stable*** +-added static class fields, new keyword static +-added 64bits architecture support +-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds +-added functions with fixed environment, closure.bindenv() built-in function +-all types except userdata and null implement the tostring() method +-string concatenation now invokes metamethod _tostring +-new metamethods for class objects _newmember and _inherited +-sq_call() sq_resume() sq_wakeupvm() have a new signature +-new C referencing implementation(scales more with the amount of references) +-refactored hash table +-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv() +-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot +-sq_setreleasehook() now also works for classes +-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob) +-fixed squirrel.h undeclared api calls +-fixed few minor bugs +-SQChar is now defined as wchar_t +-removed warning when building with -Wall -pedantic for GCC users +-added new std io function writeclosuretofile() +-added new std string functions strip(),rstrip(),lstrip() and split() +-regular expressions operators (+,*) now have more POSIX greedyness behaviour +-class constructors are now invoked as normal functions + +***2005-10-02 *** +***version 2.0.5 stable*** +-fixed some 64bits incompatibilities (thx sarge) +-fixed minor bug in the stdlib format() function (thx Rick) +-fixed a bug in dofile() that was preventing to compile empty files +-added new API sq_poptop() & sq_getfreevariable() +-some performance improvements + +***2005-08-14 *** +***version 2.0.4 stable*** +-weak references and related API calls +-added sq_objtobool() +-class instances memory policies improved(1 mem allocation for the whole instance) +-typetags are now declared as SQUserPointer instead of unsigned int +-first pass for 64bits compatibility +-fixed minor bug in the stdio stream +-fixed a bug in format() +-fixed bug in string.tointeger() and string.tofloat() + +***2005-06-24 *** +***version 2.0.3 stable*** +-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian +-sq_setparamscheck() : now typemesk can check for null +-added string escape sequence \xhhhh +-fixed some C++ standard incompatibilities + +***2005-05-15 *** +***version 2.0.2 stable*** +-performances improvements (expecially for GCC users) +-removed all dependencies from C++ exception handling +-various bugfixes + +***2005-04-12 *** +***version 2.0.1 stable*** +-various bugfixes +-sq_setparamscheck() now allows spaces in the typemask + +***2005-04-03 *** +***version 2.0 stable*** +-added API sq_gettypetag() +-added built-in function to the bool type(tointeger, tostring etc...) + +***2005-02-27 *** +***version 2.0 release candidate 1(RC 1)*** +-added API sq_reseterror() +-modified sq_release() +-now class instances can be cloned +-various bufixes + +***2005-01-26 *** +***version 2.0 beta 1*** +-added bool type +-class properties can be redefined in a derived class +-added ops *= /= and %= +-new syntax for class attributes declaration instead of ( and ) +-increased the max number of literals per function from 65535 to 16777215 +-now free variables have proper lexical scoping +-added API sq_createinstance(), sq_pushbool(), sq_getbool() +-added built-in function type() +-added built-in function obj.rawin(key) in table,class and instance +-sq_rawget() and sq_rawset() now work also on classes and instances +-the VM no longer uses C++ exception handling (more suitable for embedded devices) +-various bufixes + +***2004-12-21 *** +***version 2.0 alpha 2*** +-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table +-various bufixes +-added class level attributes + +***2004-12-12 *** +***version 2.0 alpha 1*** +-codebase branch from version 1.x +-added classes +-added functions with variable number of parameters(vargc & vargv and the ...) +-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while) +-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes() +-modified api sq_settypetag() + +***2004-11-01 *** +***version 1.0 stable*** +-fixed some minor bug +-improved operator 'delete' performances +-added scientific notation for float numbers( eg. 2.e16 or 2.e-2) + +***2004-08-30 *** +***version 1.0 release candidate 2(RC 2)*** +-fixed bug in the vm(thx Pierre Renaux) +-fixed bug in the optimizer(thx Pierre Renaux) +-fixed some bug in the documentation(thx JD) +-added new api functions for raw object handling +-removed nested multiline comments +-reduced memory footprint in C references + +***2004-08-23 *** +***version 1.0 release candidate 1(RC 1)*** +-fixed division by zero +-the 'in' operator and obj.rawget() do not query the default delegate anymore +-added function sq_getprintfunc() +-added new standard library 'auxlib'(implements default error handlers) + +***2004-07-12 *** +***version 1.0 beta 4*** +-fixed a bug in the integer.tochar() built-in method +-fixed unary minus operator +-fixed bug in dofile() +-fixed inconsistency between != and == operators(on float/integer comparison) +-added javascript style unsigned right shift operator '>>>' +-added array(size) constructor built-in function +-array.resize(size,[fill]) built-in function accepts an optional 'fill' value +-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename() + +***2004-05-23 *** +***version 1.0 beta 3*** +-minor vm bug fixes +-string allocation is now faster +-tables and array memory usage is now less conservative(they shrink) +-added regular expression routines in the standard library +-The 'c' expression now accepts only 1 character(thx irbrian) +-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string") +-added new keyword 'parent' for accessing the delegate of tables and unserdata +-The metamethod '_clone' has been renamed '_cloned' +-the _delslot metamethod's behaviour and prototype have been changed +-new default function in the integer and float object 'tochar()' +-the built-in function chcode2string has been removed +-the default method [table].getdelegate() has been removed +-new api sq_rawdeleteslot() +-new table built-in method rawdelete(key) +-the dynamic mudule loading has been removed from the standard distribution +-some optimizations in the VM + +***2004-04-21 *** +***version 1.0 beta 2*** +-minor compiler/parser bug fixes +-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck() +-sq_setparamscheck allows to add automatic parameters type checking in native closures +-sq_compile() lost the lineinfo parameter +-new api sq_enabledebuginfo() globally sets compiler's debug info generation +-added consistency check on bytecode serialization +-fixed += operator, now works on strings like + +-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime +-added registry table +-new api call sq_pushregistrytable() +-added type tag to the userdata type sq_settypetag() +-sq_getuserdata now queries the userdata typetag +-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons +-new standard libraries(sqlibs are now obsolete) + +***2004-02-20 *** +***version 1.0 beta 1*** +-fixed a bug in the compiler (thanks Martin Kofler) +-fixed bug in the switch case statement +-fixed the _unm metamethod +-fixed minor bugs in the API +-fixed automatic stack resizing +-first beta version + first pass code clean up in the VM and base lib + first pass code coverege test has been done on VM and built-in lib +-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete) +-new api allows to specifiy a "print" function to output text(sq_printfunc) +-added some small optimizations +-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread") +-new built in functions have been added for manipulating the new "thread" type +-friend virtual machines share the same root table, error handler and debug hook by default +-new compile time options + +***2004-01-19 *** +***version 0.9 alpha*** +-fixed a garbage collection bug +-fixed some API bugs(thanks to Joshua Jensen) +-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled) +-new function parameters semantic, now passing a wrong number of parameters generates an exception +-native closures have now a built in parameter number checking +-sq_rawget and sq_rawset now work also on arrays +-sq_getsize now woks also on userdata +-the userdata release hook prototype is changed(now passes the size of the userdata) +-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen) +-faster compiler +-try/catch blocks do not cause any runtime memory allocation anymore + +***2003-12-06 *** +***version 0.8 alpha*** +-fixed a bug that was preventing to have callable userdata throught the metamethod _call +-fixed a garbage collection bug +-fixed == operator now can compare correctly different types +-new built in method getstackinfos(level) +-improved line informations precision for the debug hook +-new api call sq_compilebuffer() +-new built-in api function compilestring() +-new syntactic sugar for function declarations inside tables +-the debug API has been finalized + +***2003-11-17 *** +***version 0.7 alpha*** +-fixed critical bug SQInteger the tail call system +-fixed bug in the continue statement code generation +-fixed func call param issue(thanks to Rewoonenco Andrew) +-added _delslot metamethod(thanks to Rewoonenco Andrew) +-new multiline string expression ( delimited by <[ and ]> ) +-normal strings ("") do not allow embedded new line anymore +-reduced vm memory footprint(C refs are shared between friend VMs) +-new api method sq_deleteslot() +-new debug hook event 'r' is triggered when a function returns + +***2003-11-04 *** +***version 0.6 alpha*** +-fixed switch statement(was executing the default case after a break) +-sq_call() doesn't pop the closure (just the params) +-the vm execution can be suspended from the C API anytime (micro-threads) +-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack() + +***2003-10-13 *** +***version 0.5 alpha*** +-fixed some minor bug +-tested with non ASCII identifiers in unicode mode(I've tried chinese chars) +-added built-in function string.find() +-the built-in function array.sort() optionally accepts a cmp(a,b) function +-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname) +-fixed some debug info imprecision + +***2003-10-01 *** +***version 0.4 alpha*** +-faster VM +-sq_call will pop arguments and closure also in case of failure +-fixed a bug in sq_remove +-now the VM detects delegation cycles(and throws an exception) +-new operators ++ and -- +-new operator ',' comma operator +-fixed some expression precedence issue +-fixed bug in sq_arraypop + +***2003-09-15 *** +***version 0.3 alpha*** +-fixed a bug in array::insert() +-optional Unicode core(define SQUNICODE or _UNICODE on Win32) +-sq_compiler uses a new reader function SQLEXREADFUNC +-the debug hook passes 'l' instead of 'line' for line callbacks + and 'c' instead of 'call' for call callbacks +-new array.extend() bulit-in function +-new API sq_clone() + +***2003-09-10 *** +***version 0.2 pre-alpha*** +-new completely reentrant VM (sq_open and sq_close are now obsolete) +-sq_newvm() has a new prototype +-allocators are now global and linked in the VM +-_newslot meta method added +-rawset creates a slot if doesn't exists +-the compiler error callback pass the vm handle(thanks Pierre Renaux) +-sq_setforeignptr() sq_getforeingptr() are now public +-sq_resume() now is possible to resume generators from C +-sq_getlasterror() retrieve the last thrown error +-improved docs + +***2003-09-06 *** +***version 0.1 pre-alpha*** +first release diff --git a/vscript/squirrel/Makefile b/vscript/squirrel/Makefile new file mode 100644 index 00000000..2ed97e26 --- /dev/null +++ b/vscript/squirrel/Makefile @@ -0,0 +1,22 @@ + +SQUIRREL=. +MAKE=make + +sq32: folders + cd squirrel; $(MAKE) + cd sqstdlib; $(MAKE) + cd sq; $(MAKE) + +sqprof: folders + cd squirrel; $(MAKE) sqprof + cd sqstdlib; $(MAKE) sqprof + cd sq; $(MAKE) sqprof + +sq64: folders + cd squirrel; $(MAKE) sq64 + cd sqstdlib; $(MAKE) sq64 + cd sq; $(MAKE) sq64 + +folders: + mkdir -p lib + mkdir -p bin diff --git a/vscript/squirrel/README b/vscript/squirrel/README new file mode 100644 index 00000000..298aec75 --- /dev/null +++ b/vscript/squirrel/README @@ -0,0 +1,33 @@ +The programming language SQUIRREL 3.1 stable + +-------------------------------------------------- +This project has successfully been compiled and run on + * Windows (x86 and amd64) + * Linux (x86, amd64 and ARM) + * Illumos (x86 and amd64) + * FreeBSD (x86 and ARM) + +The following compilers have been confirmed to be working: + MS Visual C++ 6.0 (all on x86 and amd64) + 7.0 | + 7.1 v + 8.0 + 9.0 + 10.0 + 12.0 --- + MinGW gcc 3.2 (mingw special 20020817-1) + Cygnus gcc 3.2 + Linux gcc 3.2.3 + 4.0.0 (x86 and amd64) + 5.3.1 (amd64) + Illumos gcc 4.0.0 (x86 and amd64) + ARM Linux gcc 4.6.3 (Raspberry Pi Model B) + + +Feedback and suggestions are appreciated +project page - http://www.squirrel-lang.org +community forums - http://forum.squirrel-lang.org +wiki - http://wiki.squirrel-lang.org +author - alberto@demichelis.net + +END OF README diff --git a/vscript/squirrel/appveyor.yml b/vscript/squirrel/appveyor.yml new file mode 100644 index 00000000..4da9b37b --- /dev/null +++ b/vscript/squirrel/appveyor.yml @@ -0,0 +1,28 @@ +version: 0.0.{build} + +platform: + - x86 + - x64 + +configuration: + - Debug + - Release + +clone_folder: c:\sq + +before_build: + - mkdir build + - cd build + - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %platform% + - echo %platform% + - if %platform%==X64 (cmake .. -G "Visual Studio 14 2015 Win64") + - if %platform%==x86 (cmake .. -G "Visual Studio 14 2015") + +build_script: + - cmake --build . --config %configuration% -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + +artifacts: + - path: build\*\%configuration%\*.exe + - path: build\*\%configuration%\*.dll + +test: off diff --git a/vscript/squirrel/doc/Makefile b/vscript/squirrel/doc/Makefile new file mode 100644 index 00000000..b01e98db --- /dev/null +++ b/vscript/squirrel/doc/Makefile @@ -0,0 +1,216 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/testy_sphinxy.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/testy_sphinxy.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/testy_sphinxy" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/testy_sphinxy" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/vscript/squirrel/doc/make.bat b/vscript/squirrel/doc/make.bat new file mode 100644 index 00000000..a32fa10a --- /dev/null +++ b/vscript/squirrel/doc/make.bat @@ -0,0 +1,263 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +set I18NSPHINXOPTS=%SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\testy_sphinxy.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\testy_sphinxy.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/vscript/squirrel/doc/source/_static/nut.ico b/vscript/squirrel/doc/source/_static/nut.ico new file mode 100644 index 00000000..c28977b0 Binary files /dev/null and b/vscript/squirrel/doc/source/_static/nut.ico differ diff --git a/vscript/squirrel/doc/source/_static/simple_nut.png b/vscript/squirrel/doc/source/_static/simple_nut.png new file mode 100644 index 00000000..4c0e8a20 Binary files /dev/null and b/vscript/squirrel/doc/source/_static/simple_nut.png differ diff --git a/vscript/squirrel/doc/source/conf.py b/vscript/squirrel/doc/source/conf.py new file mode 100644 index 00000000..996eafef --- /dev/null +++ b/vscript/squirrel/doc/source/conf.py @@ -0,0 +1,288 @@ +# -*- coding: utf-8 -*- +# +# Squirrel documentation build configuration file, created by +# sphinx-quickstart on Sun Jan 31 00:26:52 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Squirrel documentation' +copyright = '2003-%s, Alberto Demichelis' % time.strftime('%Y') +author = u'Alberto Demichelis' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'3.1' +# The full version, including alpha/beta/rc tags. +release = u'3.1 stable' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = 'simple_nut.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'nut.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'squirrel_doc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +_stdauthor = r'Alberto Demichelis' +latex_documents = [ + ('reference/index', 'reference.tex', + 'Squirrel Reference Manual', _stdauthor, 'manual'), + ('stdlib/index', 'stdlib.tex', + 'Squirrel Standard Library', _stdauthor, 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'Squirrel', u'Squirrel Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Squirrel', u'Squirrel Documentation', + author, 'Squirrel', 'The Programming Language.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/vscript/squirrel/doc/source/index.rst b/vscript/squirrel/doc/source/index.rst new file mode 100644 index 00000000..0cc1bb4d --- /dev/null +++ b/vscript/squirrel/doc/source/index.rst @@ -0,0 +1,24 @@ +.. Squirrel documentation master file, created by + sphinx-quickstart on Sun Jan 31 00:26:52 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Squirrel's documentation +========================================= + +Contents: + +.. toctree:: + :maxdepth: 1 + + reference/index.rst + stdlib/index.rst + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + + diff --git a/vscript/squirrel/doc/source/reference/api/bytecode_serialization.rst b/vscript/squirrel/doc/source/reference/api/bytecode_serialization.rst new file mode 100644 index 00000000..0e1f586a --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/bytecode_serialization.rst @@ -0,0 +1,32 @@ +.. _api_ref_bytecode_serialization: + +====================== +Bytecode serialization +====================== + +.. _sq_readclosure: + +.. c:function:: SQRESULT sq_readclosure(HSQUIRRELVM v, SQREADFUNC readf, SQUserPointer up) + + :param HSQUIRRELVM v: the target VM + :param SQREADFUNC readf: pointer to a read function that will be invoked by the vm during the serialization. + :param SQUserPointer up: pointer that will be passed to each call to the read function + :returns: a SQRESULT + +serialize (read) a closure and pushes it on top of the stack, the source is user defined through a read callback. + + + + + +.. _sq_writeclosure: + +.. c:function:: SQRESULT sq_writeclosure(HSQUIRRELVM v, SQWRITEFUNC writef, SQUserPointer up) + + :param HSQUIRRELVM v: the target VM + :param SQWRITEFUNC writef: pointer to a write function that will be invoked by the vm during the serialization. + :param SQUserPointer up: pointer that will be passed to each call to the write function + :returns: a SQRESULT + :remarks: closures with free variables cannot be serialized + +serializes(writes) the closure on top of the stack, the destination is user defined through a write callback. diff --git a/vscript/squirrel/doc/source/reference/api/calls.rst b/vscript/squirrel/doc/source/reference/api/calls.rst new file mode 100644 index 00000000..7ba43fb6 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/calls.rst @@ -0,0 +1,130 @@ +.. _api_ref_calls: + +===== +Calls +===== + +.. _sq_call: + +.. c:function:: SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror) + + :param HSQUIRRELVM v: the target VM + :param SQInteger params: number of parameters of the function + :param SQBool retval: if true the function will push the return value in the stack + :param SQBool raiseerror: if true, if a runtime error occurs during the execution of the call, the vm will invoke the error handler. + :returns: a SQRESULT + +calls a closure or a native closure. The function pops all the parameters and leave the closure in the stack; if retval is true the return value of the closure is pushed. If the execution of the function is suspended through sq_suspendvm(), the closure and the arguments will not be automatically popped from the stack. + +When using to create an instance, push a dummy parameter to be filled with the newly-created instance for the constructor's 'this' parameter. + + + +.. _sq_getcallee: + +.. c:function:: SQRESULT sq_getcallee(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: a SQRESULT + +push in the stack the currently running closure. + + + + + +.. _sq_getlasterror: + +.. c:function:: SQRESULT sq_getlasterror(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: a SQRESULT + :remarks: the pushed error descriptor can be any valid squirrel type. + +pushes the last error in the stack. + + + + + +.. _sq_getlocal: + +.. c:function:: const SQChar * sq_getlocal(HSQUIRRELVM v, SQUnsignedInteger level, SQUnsignedInteger nseq) + + :param HSQUIRRELVM v: the target VM + :param SQUnsignedInteger level: the function index in the calls stack, 0 is the current function + :param SQUnsignedInteger nseq: the index of the local variable in the stack frame (0 is 'this') + :returns: the name of the local variable if a variable exists at the given level/seq otherwise NULL. + +Returns the name of a local variable given stackframe and sequence in the stack and pushes is current value. Free variables are treated as local variables, by sq_getlocal(), and will be returned as they would be at the base of the stack, just before the real local variables. + + + + + +.. _sq_reseterror: + +.. c:function:: void sq_reseterror(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + +reset the last error in the virtual machine to null + + + + + +.. _sq_resume: + +.. c:function:: SQRESULT sq_resume(HSQUIRRELVM v, SQBool retval, SQBool raiseerror) + + :param HSQUIRRELVM v: the target VM + :param SQBool retval: if true the function will push the return value in the stack + :param SQBool raiseerror: if true, if a runtime error occurs during the execution of the call, the vm will invoke the error handler. + :returns: a SQRESULT + :remarks: if retval != 0 the return value of the generator is pushed. + +resumes the generator at the top position of the stack. + + +.. _sq_tailcall: + +.. c:function:: SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams) + + :param HSQUIRRELVM v: the target VM + :param SQInteger params: number of parameters of the function + + Calls a closure and removes the caller function from the call stack. + This function must be invoke from a native closure and + he return value of sq_tailcall must be returned by the caller function(see example). + +*.eg* + +:: + + SQInteger tailcall_something_example(HSQUIRRELVM v) + { + //push closure and parameters here + ... + return sq_tailcall(v,2); + } + +.. _sq_throwerror: + +.. c:function:: SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar * err) + + :param HSQUIRRELVM v: the target VM + :param const SQChar * err: the description of the error that has to be thrown + :returns: the value that has to be returned by a native closure in order to throw an exception in the virtual machine. + +sets the last error in the virtual machine and returns the value that has to be returned by a native closure in order to trigger an exception in the virtual machine. + + +.. _sq_throwobject: + +.. c:function:: SQRESULT sq_throwobject(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: the value that has to be returned by a native closure in order to throw an exception in the virtual machine. + +pops a value from the stack sets it as the last error in the virtual machine. Returns the value that has to be returned by a native closure in order to trigger an exception in the virtual machine (aka SQ_ERROR). diff --git a/vscript/squirrel/doc/source/reference/api/compiler.rst b/vscript/squirrel/doc/source/reference/api/compiler.rst new file mode 100644 index 00000000..7fcb933d --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/compiler.rst @@ -0,0 +1,79 @@ +.. _api_ref_compiler: + +======== +Compiler +======== + +.. _sq_compile: + +.. c:function:: SQRESULT sq_compile(HSQUIRRELVM v, HSQLEXREADFUNC read, SQUserPointer p, const SQChar * sourcename, SQBool raiseerror) + + :param HSQUIRRELVM v: the target VM + :param HSQLEXREADFUNC read: a pointer to a read function that will feed the compiler with the program. + :param SQUserPointer p: a user defined pointer that will be passed by the compiler to the read function at each invocation. + :param const SQChar * sourcename: the symbolic name of the program (used only for more meaningful runtime errors) + :param SQBool raiseerror: if this value is true the compiler error handler will be called in case of an error + :returns: a SQRESULT. If the sq_compile fails nothing is pushed in the stack. + :remarks: in case of an error the function will call the function set by sq_setcompilererrorhandler(). + +compiles a squirrel program; if it succeeds, push the compiled script as function in the stack. + + + + + +.. _sq_compilebuffer: + +.. c:function:: SQRESULT sq_compilebuffer(HSQUIRRELVM v, const SQChar* s, SQInteger size, const SQChar * sourcename, SQBool raiseerror) + + :param HSQUIRRELVM v: the target VM + :param const SQChar* s: a pointer to the buffer that has to be compiled. + :param SQInteger size: size in characters of the buffer passed in the parameter 's'. + :param const SQChar * sourcename: the symbolic name of the program (used only for more meaningful runtime errors) + :param SQBool raiseerror: if this value true the compiler error handler will be called in case of an error + :returns: a SQRESULT. If the sq_compilebuffer fails nothing is pushed in the stack. + :remarks: in case of an error the function will call the function set by sq_setcompilererrorhandler(). + +compiles a squirrel program from a memory buffer; if it succeeds, push the compiled script as function in the stack. + + + + + +.. _sq_enabledebuginfo: + +.. c:function:: void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) + + :param HSQUIRRELVM v: the target VM + :param SQBool enable: if true enables the debug info generation, if == 0 disables it. + :remarks: The function affects all threads as well. + +enable/disable the debug line information generation at compile time. + + + + + +.. _sq_notifyallexceptions: + +.. c:function:: void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) + + :param HSQUIRRELVM v: the target VM + :param SQBool enable: if true enables the error callback notification of handled exceptions. + :remarks: By default the VM will invoke the error callback only if an exception is not handled (no try/catch traps are present in the call stack). If notifyallexceptions is enabled, the VM will call the error callback for any exception even if between try/catch blocks. This feature is useful for implementing debuggers. + +enable/disable the error callback notification of handled exceptions. + + + + + +.. _sq_setcompilererrorhandler: + +.. c:function:: void sq_setcompilererrorhandler(HSQUIRRELVM v, SQCOMPILERERROR f) + + :param HSQUIRRELVM v: the target VM + :param SQCOMPILERERROR f: A pointer to the error handler function + :remarks: if the parameter f is NULL no function will be called when a compiler error occurs. The compiler error handler is shared between friend VMs. + +sets the compiler error handler function diff --git a/vscript/squirrel/doc/source/reference/api/debug_interface.rst b/vscript/squirrel/doc/source/reference/api/debug_interface.rst new file mode 100644 index 00000000..ac929e14 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/debug_interface.rst @@ -0,0 +1,72 @@ +.. _api_ref_debug_interface: + +=============== +Debug interface +=============== + +.. _sq_getfunctioninfo: + +.. c:function:: SQRESULT sq_getfunctioninfo(HSQUIRRELVM v, SQInteger level, SQFunctionInfo * fi) + + :param HSQUIRRELVM v: the target VM + :param SQInteger level: calls stack level + :param SQFunctionInfo * fi: pointer to the SQFunctionInfo structure that will store the closure informations + :returns: a SQRESULT. + :remarks: the member 'funcid' of the returned SQFunctionInfo structure is a unique identifier of the function; this can be useful to identify a specific piece of squirrel code in an application like for instance a profiler. this method will fail if the closure in the stack is a native C closure. + + + +*.eg* + +:: + + + typedef struct tagSQFunctionInfo { + SQUserPointer funcid; //unique idetifier for a function (all it's closures will share the same funcid) + const SQChar *name; //function name + const SQChar *source; //function source file name + }SQFunctionInfo; + + + + + + + +.. _sq_setdebughook: + +.. c:function:: void sq_setdebughook(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :remarks: In order to receive a 'per line' callback, is necessary to compile the scripts with the line informations. Without line informations activated, only the 'call/return' callbacks will be invoked. + +pops a closure from the stack an sets it as debug hook. When a debug hook is set it overrides any previously set native or non native hooks. if the hook is null the debug hook will be disabled. + + + + + +.. _sq_setnativedebughook: + +.. c:function:: void sq_setnativedebughook(HSQUIRRELVM v, SQDEBUGHOOK hook) + + :param HSQUIRRELVM v: the target VM + :param SQDEBUGHOOK hook: the native hook function + :remarks: In order to receive a 'per line' callback, is necessary to compile the scripts with the line informations. Without line informations activated, only the 'call/return' callbacks will be invoked. + +sets the native debug hook. When a native hook is set it overrides any previously set native or non native hooks. if the hook is NULL the debug hook will be disabled. + + + + + +.. _sq_stackinfos: + +.. c:function:: SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos * si) + + :param HSQUIRRELVM v: the target VM + :param SQInteger level: calls stack level + :param SQStackInfos * si: pointer to the SQStackInfos structure that will store the stack informations + :returns: a SQRESULT. + +retrieve the calls stack informations of a ceratain level in the calls stack. diff --git a/vscript/squirrel/doc/source/reference/api/garbage_collector.rst b/vscript/squirrel/doc/source/reference/api/garbage_collector.rst new file mode 100644 index 00000000..cfe03e68 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/garbage_collector.rst @@ -0,0 +1,27 @@ +.. _api_ref_garbage_collector: + +================= +Garbage Collector +================= + +.. _sq_collectgarbage: + +.. c:function:: SQInteger sq_collectgarbage(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined) + +runs the garbage collector and returns the number of reference cycles found (and deleted) + + + + + +.. _sq_resurrectunreachable: + +.. c:function:: SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined) + +runs the garbage collector and pushes an array in the stack containing all unreachable object found. If no unreachable object is found, null is pushed instead. This function is meant to help debug reference cycles. diff --git a/vscript/squirrel/doc/source/reference/api/object_creation_and_handling.rst b/vscript/squirrel/doc/source/reference/api/object_creation_and_handling.rst new file mode 100644 index 00000000..5345c05c --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/object_creation_and_handling.rst @@ -0,0 +1,695 @@ +.. _api_ref_object_creation_and_handling: + +============================ +Object creation and handling +============================ + +.. _sq_bindenv: + +.. c:function:: SQRESULT sq_bindenv(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target closure + :returns: a SQRESULT + :remarks: the cloned closure holds the environment object as weak reference + +pops an object from the stack (must be a table, instance, or class); clones the closure at position idx in the stack and sets the popped object as environment of the cloned closure. Then pushes the new cloned closure on top of the stack. + + + + + +.. _sq_createinstance: + +.. c:function:: SQRESULT sq_createinstance(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target class + :returns: a SQRESULT + :remarks: the function doesn't invoke the instance contructor. To create an instance and automatically invoke its contructor, sq_call must be used instead. + +creates an instance of the class at 'idx' position in the stack. The new class instance is pushed on top of the stack. + + + + + +.. _sq_getbool: + +.. c:function:: SQRESULT sq_getbool(HSQUIRRELVM v, SQInteger idx, SQBool * b) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQBool * b: A pointer to the bool that will store the value + :returns: a SQRESULT + +gets the value of the bool at the idx position in the stack. + + + + + +.. _sq_getbyhandle: + +.. c:function:: SQRESULT sq_getbyhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack pointing to the class or instance + :param HSQMEMBERHANDLE* handle: a pointer to the member handle + :returns: a SQRESULT + +pushes the value of a class or instance member using a member handle (see sq_getmemberhandle) + + + + + +.. _sq_getclosureinfo: + +.. c:function:: SQRESULT sq_getclosureinfo(HSQUIRRELVM v, SQInteger idx, SQInteger * nparams, SQInteger * nfreevars) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target closure + :param SQInteger * nparams: a pointer to an integer that will store the number of parameters + :param SQInteger * nfreevars: a pointer to an integer that will store the number of free variables + :returns: an SQRESULT + +retrieves number of parameters and number of freevariables from a squirrel closure. + + + + + +.. _sq_getclosurename: + +.. c:function:: SQRESULT sq_getclosurename(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target closure + :returns: an SQRESULT + +pushes the name of the closure at position idx in the stack. Note that the name can be a string or null if the closure is anonymous or a native closure with no name assigned to it. + + + + + +.. _sq_getclosureroot: + +.. c:function:: SQRESULT sq_getclosureroot(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target closure + :returns: an SQRESULT + +pushes the root table of the closure at position idx in the stack + + + + + +.. _sq_getfloat: + +.. c:function:: SQRESULT sq_getfloat(HSQUIRRELVM v, SQInteger idx, SQFloat * f) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQFloat * f: A pointer to the float that will store the value + :returns: a SQRESULT + +gets the value of the float at the idx position in the stack. + + + + + +.. _sq_gethash: + +.. c:function:: SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :returns: the hash key of the value at the position idx in the stack + :remarks: the hash value function is the same used by the VM. + +returns the hash key of a value at the idx position in the stack. + + + + + +.. _sq_getinstanceup: + +.. c:function:: SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer * up, SQUSerPointer typetag) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer * up: a pointer to the userpointer that will store the result + :param SQUSerPointer typetag: the typetag that has to be checked, if this value is set to 0 the typetag is ignored. + :returns: a SQRESULT + +gets the userpointer of the class instance at position idx in the stack. if the parameter 'typetag' is different than 0, the function checks that the class or a base class of the instance is tagged with the specified tag; if not the function fails. If 'typetag' is 0 the function will ignore the tag check. + + + + + +.. _sq_getinteger: + +.. c:function:: SQRESULT sq_getinteger(HSQUIRRELVM v, SQInteger idx, SQInteger * i) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQInteger * i: A pointer to the integer that will store the value + :returns: a SQRESULT + +gets the value of the integer at the idx position in the stack. + + + + + +.. _sq_getmemberhandle: + +.. c:function:: SQRESULT sq_getmemberhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack pointing to the class + :param HSQMEMBERHANDLE* handle: a pointer to the variable that will store the handle + :returns: a SQRESULT + :remarks: This method works only with classes. A handle retrieved through a class can be later used to set or get values from one of the class instances. Handles retrieved from base classes are still valid in derived classes and respect inheritance rules. + +pops a value from the stack and uses it as index to fetch the handle of a class member. The handle can be later used to set or get the member value using sq_getbyhandle(), sq_setbyhandle(). + + + + + +.. _sq_getreleasehook: + +.. c:function:: SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :remarks: if the object that position idx is not an userdata, class instance or class the function returns NULL. + +gets the release hook of the userdata, class instance or class at position idx in the stack. + + + + + +.. _sq_getscratchpad: + +.. c:function:: SQChar * sq_getscratchpad(HSQUIRRELVM v, SQInteger minsize) + + :param HSQUIRRELVM v: the target VM + :param SQInteger minsize: the requested size for the scratchpad buffer + :remarks: the buffer is valid until the next call to sq_getscratchpad + +returns a pointer to a memory buffer that is at least as big as minsize. + + + + + +.. _sq_getsize: + +.. c:function:: SQObjectType sq_getsize(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :returns: the size of the value at the position idx in the stack + :remarks: this function only works with strings, arrays, tables, classes, instances, and userdata if the value is not a valid type, the function will return -1. + +returns the size of a value at the idx position in the stack. If the value is a class or a class instance the size returned is the size of the userdata buffer (see sq_setclassudsize). + + + + + +.. _sq_getstring: + +.. c:function:: SQRESULT sq_getstring(HSQUIRRELVM v, SQInteger idx, const SQChar ** c) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param const SQChar ** c: a pointer to the pointer that will point to the string + :returns: a SQRESULT + +gets a pointer to the string at the idx position in the stack. + + + + + +.. _sq_getstringandsize: + +.. c:function:: SQRESULT sq_getstringandsize(HSQUIRRELVM v, SQInteger idx, const SQChar ** c, SQInteger* size) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param const SQChar ** c: a pointer to the pointer that will point to the string + :param SQInteger * size: a pointer to a SQInteger which will receive the size of the string + :returns: a SQRESULT + +gets a pointer to the string at the idx position in the stack; additionally retrieves its size. + + + + +.. _sq_getthread: + +.. c:function:: SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* v) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param HSQUIRRELVM* v: A pointer to the variable that will store the thread pointer + :returns: a SQRESULT + +gets a pointer to the thread the idx position in the stack. + + + + + +.. _sq_gettype: + +.. c:function:: SQObjectType sq_gettype(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :returns: the type of the value at the position idx in the stack + +returns the type of the value at the position idx in the stack + + + + + +.. _sq_gettypetag: + +.. c:function:: SQRESULT sq_gettypetag(HSQUIRRELVM v, SQInteger idx, SQUserPointer * typetag) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer * typetag: a pointer to the variable that will store the tag + :returns: a SQRESULT + :remarks: the function works also with instances. if the taget object is an instance, the typetag of it's base class is fetched. + +gets the typetag of the object (userdata or class) at position idx in the stack. + + + + + +.. _sq_getuserdata: + +.. c:function:: SQRESULT sq_getuserdata(HSQUIRRELVM v, SQInteger idx, SQUserPointer * p, SQUserPointer * typetag) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer * p: A pointer to the userpointer that will point to the userdata's payload + :param SQUserPointer * typetag: A pointer to a SQUserPointer that will store the userdata tag(see sq_settypetag). The parameter can be NULL. + :returns: a SQRESULT + +gets a pointer to the value of the userdata at the idx position in the stack. + + + + + +.. _sq_getuserpointer: + +.. c:function:: SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer * p) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer * p: A pointer to the userpointer that will store the value + :returns: a SQRESULT + +gets the value of the userpointer at the idx position in the stack. + + + + + +.. _sq_newarray: + +.. c:function:: void sq_newarray(HSQUIRRELVM v, SQInteger size) + + :param HSQUIRRELVM v: the target VM + :param SQInteger size: the size of the array that as to be created + +creates a new array and pushes it in the stack + + + + + +.. _sq_newclass: + +.. c:function:: SQRESULT sq_newclass(HSQUIRRELVM v, SQBool hasbase) + + :param HSQUIRRELVM v: the target VM + :param SQBool hasbase: if the parameter is true the function expects a base class on top of the stack. + :returns: a SQRESULT + +creates a new class object. If the parameter 'hasbase' is different than 0, the function pops a class from the stack and inherits the new created class from it. The new class is pushed in the stack. + + + + + +.. _sq_newclosure: + +.. c:function:: void sq_newclosure(HSQUIRRELVM v, HSQFUNCTION func, SQInteger nfreevars) + + :param HSQUIRRELVM v: the target VM + :param HSQFUNCTION func: a pointer to a native-function + :param SQInteger nfreevars: number of free variables(can be 0) + +create a new native closure, pops n values set those as free variables of the new closure, and push the new closure in the stack. + + + + + +.. _sq_newtable: + +.. c:function:: void sq_newtable(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + +creates a new table and pushes it in the stack + + + + + +.. _sq_newtableex: + +.. c:function:: void sq_newtableex(HSQUIRRELVM v, SQInteger initialcapacity) + + :param HSQUIRRELVM v: the target VM + :param SQInteger initialcapacity: number of key/value pairs to preallocate + +creates a new table and pushes it in the stack. This function allows you to specify the initial capacity of the table to prevent unnecessary rehashing when the number of slots required is known at creation-time. + + + + + +.. _sq_newuserdata: + +.. c:function:: SQUserPointer sq_newuserdata(HSQUIRRELVM v, SQUnsignedInteger size) + + :param HSQUIRRELVM v: the target VM + :param SQUnsignedInteger size: the size of the userdata that as to be created in bytes + +creates a new userdata and pushes it in the stack + + + + + +.. _sq_pushbool: + +.. c:function:: void sq_pushbool(HSQUIRRELVM v, SQBool b) + + :param HSQUIRRELVM v: the target VM + :param SQBool b: the bool that has to be pushed(SQTrue or SQFalse) + +pushes a bool into the stack + + + + + +.. _sq_pushfloat: + +.. c:function:: void sq_pushfloat(HSQUIRRELVM v, SQFloat f) + + :param HSQUIRRELVM v: the target VM + :param SQFloat f: the float that has to be pushed + +pushes a float into the stack + + + + + +.. _sq_pushinteger: + +.. c:function:: void sq_pushinteger(HSQUIRRELVM v, SQInteger n) + + :param HSQUIRRELVM v: the target VM + :param SQInteger n: the integer that has to be pushed + +pushes an integer into the stack + + + + + +.. _sq_pushnull: + +.. c:function:: void sq_pushnull(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + +pushes a null value into the stack + + + + + +.. _sq_pushstring: + +.. c:function:: void sq_pushstring(HSQUIRRELVM v, const SQChar * s, SQInteger len) + + :param HSQUIRRELVM v: the target VM + :param const SQChar * s: pointer to the string that has to be pushed + :param SQInteger len: length of the string pointed by s + :remarks: if the parameter len is less than 0 the VM will calculate the length using strlen(s) + +pushes a string in the stack + + + + + +.. _sq_pushuserpointer: + +.. c:function:: void sq_pushuserpointer(HSQUIRRELVM v, SQUserPointer p) + + :param HSQUIRRELVM v: the target VM + :param SQUserPointer p: the pointer that as to be pushed + +pushes a userpointer into the stack + + + + + +.. _sq_setbyhandle: + +.. c:function:: SQRESULT sq_setbyhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack pointing to the class + :param HSQMEMBERHANDLE* handle: a pointer the member handle + :returns: a SQRESULT + +pops a value from the stack and sets it to a class or instance member using a member handle (see sq_getmemberhandle) + + + + + +.. _sq_setclassudsize: + +.. c:function:: SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack pointing to the class + :param SQInteger udsize: size in bytes reserved for user data + :returns: a SQRESULT + +Sets the user data size of a class. If a class 'user data size' is greater than 0. When an instance of the class is created additional space will be reserved at the end of the memory chunk where the instance is stored. The userpointer of the instance will also be automatically set to this memory area. This allows you to minimize allocations in applications that have to carry data along with the class instance. + + + + + +.. _sq_setclosureroot: + +.. c:function:: SQRESULT sq_setclosureroot(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target closure + :returns: an SQRESULT + +pops a table from the stack and sets it as root of the closure at position idx in the stack + + + + + +.. _sq_setinstanceup: + +.. c:function:: SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer up) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer up: an arbitrary user pointer + :returns: a SQRESULT + +sets the userpointer of the class instance at position idx in the stack. + + + + + +.. _sq_setnativeclosurename: + +.. c:function:: SQRESULT sq_setnativeclosurename(HSQUIRRELVM v, SQInteger idx, const SQChar * name) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target native closure + :param const SQChar * name: the name that has to be set + :returns: an SQRESULT + +sets the name of the native closure at the position idx in the stack. The name of a native closure is purely for debug purposes. The name is retrieved through the function sq_stackinfos() while the closure is in the call stack. + + + + + +.. _sq_setparamscheck: + +.. c:function:: SQRESULT sq_setparamscheck(HSQUIRRELVM v, SQInteger nparamscheck, const SQChar * typemask) + + :param HSQUIRRELVM v: the target VM + :param SQInteger nparamscheck: defines the parameters number check policy (0 disables the param checking). If nparamscheck is greater than 0, the VM ensures that the number of parameters is exactly the number specified in nparamscheck (eg. if nparamscheck == 3 the function can only be called with 3 parameters). If nparamscheck is less than 0 the VM ensures that the closure is called with at least the absolute value of the number specified in nparamcheck (eg. nparamscheck == -3 will check that the function is called with at least 3 parameters). The hidden parameter 'this' is included in this number; free variables aren't. If SQ_MATCHTYPEMASKSTRING is passed instead of the number of parameters, the function will automatically infer the number of parameters to check from the typemask (eg. if the typemask is ".sn", it is like passing 3). + :param const SQChar * typemask: defines a mask to validate the parametes types passed to the function. If the parameter is NULL, no typechecking is applied (default). + :remarks: The typemask consists in a zero terminated string that represent the expected parameter type. The types are expressed as follows: 'o' null, 'i' integer, 'f' float, 'n' integer or float, 's' string, 't' table, 'a' array, 'u' userdata, 'c' closure and nativeclosure, 'g' generator, 'p' userpointer, 'v' thread, 'x' instance(class instance), 'y' class, 'b' bool. and '.' any type. The symbol '|' can be used as 'or' to accept multiple types on the same parameter. There isn't any limit on the number of 'or' that can be used. Spaces are ignored so can be inserted between types to increase readability. For instance to check a function that expect a table as 'this' a string as first parameter and a number or a userpointer as second parameter, the string would be "tsn|p" (table,string,number or userpointer). If the parameters mask is contains fewer parameters than 'nparamscheck', the remaining parameters will not be typechecked. + +Sets the parameter validation scheme for the native closure at the top position in the stack. Allows you to validate the number of parameters accepted by the function and optionally their types. If the function call does not comply with the parameter schema set by sq_setparamscheck, an exception is thrown. + +*.eg* + +:: + + //example + SQInteger testy(HSQUIRRELVM v) + { + SQUserPointer p; + const SQChar *s; + SQInteger i; + //no type checking, if the call complies with the mask + //surely the functions will succeed. + sq_getuserdata(v,1,&p,NULL); + sq_getstring(v,2,&s); + sq_getinteger(v,3,&i); + //... do something + return 0; + } + + //the reg code + + //....stuff + sq_newclosure(v,testy,0); + //expects exactly 3 parameters(userdata,string,number) + sq_setparamscheck(v,3,_SC("usn")); + //....stuff + + + + + + +.. _sq_setreleasehook: + +.. c:function:: void sq_setreleasehook(HSQUIRRELVM v, SQInteger idx, SQRELEASEHOOK hook) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQRELEASEHOOK hook: a function pointer to the hook(see sample below) + :remarks: the function hook is called by the VM before the userdata memory is deleted. + +sets the release hook of the userdata, class instance, or class at position idx in the stack. + +*.eg* + +:: + + + /* tyedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); */ + + SQInteger my_release_hook(SQUserPointer p,SQInteger size) + { + /* do something here */ + return 1; + } + + + + + + +.. _sq_settypetag: + +.. c:function:: SQRESULT sq_settypetag(HSQUIRRELVM v, SQInteger idx, SQUserPointer typetag) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQUserPointer typetag: an arbitrary SQUserPointer + :returns: a SQRESULT + +sets the typetag of the object (userdata or class) at position idx in the stack. + + + + + +.. _sq_tobool: + +.. c:function:: void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool * b) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :param SQBool * b: A pointer to the bool that will store the value + :remarks: if the object is not a bool the function converts the value to bool according to squirrel's rules. For instance the number 1 will result in true, and the number 0 in false. + +gets the value at position idx in the stack as bool. + + + + + +.. _sq_tostring: + +.. c:function:: void sq_tostring(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + +converts the object at position idx in the stack to string and pushes the resulting string in the stack. + + + + + +.. _sq_typeof: + +.. c:function:: SQObjectType sq_typeof(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: an index in the stack + :returns: a SQRESULT + +pushes the type name of the value at the position idx in the stack. It also invokes the _typeof metamethod for tables and class instances that implement it; in that case the pushed object could be something other than a string (is up to the _typeof implementation). + + + diff --git a/vscript/squirrel/doc/source/reference/api/object_manipulation.rst b/vscript/squirrel/doc/source/reference/api/object_manipulation.rst new file mode 100644 index 00000000..d5fe5336 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/object_manipulation.rst @@ -0,0 +1,451 @@ +.. _api_ref_object_manipulation: + +==================== +Object manipulation +==================== + +.. _sq_arrayappend: + +.. c:function:: SQRESULT sq_arrayappend(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :returns: a SQRESULT + :remarks: Only works on arrays. + +pops a value from the stack and pushes it in the back of the array at the position idx in the stack. + + + + + +.. _sq_arrayinsert: + +.. c:function:: SQRESULT sq_arrayinsert(HSQUIRRELVM v, SQInteger idx, SQInteger destpos) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :param SQInteger destpos: the position in the array where the item has to be inserted + :returns: a SQRESULT + :remarks: Only works on arrays. + +pops a value from the stack and inserts it in an array at the specified position + + + + + +.. _sq_arraypop: + +.. c:function:: SQRESULT sq_arraypop(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :returns: a SQRESULT + :remarks: Only works on arrays. + +pops a value from the back of the array at the position idx in the stack. + + + + + +.. _sq_arrayremove: + +.. c:function:: SQRESULT sq_arrayremove(HSQUIRRELVM v, SQInteger idx, SQInteger itemidx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :param SQInteger itemidx: the index of the item in the array that has to be removed + :returns: a SQRESULT + :remarks: Only works on arrays. + +removes an item from an array + + + + + +.. _sq_arrayresize: + +.. c:function:: SQRESULT sq_arrayresize(HSQUIRRELVM v, SQInteger idx, SQInteger newsize) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :param SQInteger newsize: requested size of the array + :returns: a SQRESULT + :remarks: Only works on arrays. If newsize if greater than the current size the new array slots will be filled with nulls. + +resizes the array at the position idx in the stack. + + + + + +.. _sq_arrayreverse: + +.. c:function:: SQRESULT sq_arrayreverse(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target array in the stack + :returns: a SQRESULT + :remarks: Only works on arrays. + +reverses an array in place. + + + + + +.. _sq_clear: + +.. c:function:: SQRESULT sq_clear(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: Only works on tables and arrays. + +clears all the elements of the table/array at position idx in the stack. + + + + + +.. _sq_clone: + +.. c:function:: SQRESULT sq_clone(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + +pushes a clone of the table, array, or class instance at the position idx. + + + + + +.. _sq_createslot: + +.. c:function:: SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :returns: a SQRESULT + :remarks: invoke the _newslot metamethod in the table delegate. it only works on tables. [this function is deperecated since version 2.0.5 use sq_newslot() instead] + +pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack; if the slot does not exist, it will be created. + + + + + +.. _sq_deleteslot: + +.. c:function:: SQRESULT sq_deleteslot(HSQUIRRELVM v, SQInteger idx, SQBool pushval) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :param SQBool pushval: if this param is true the function will push the value of the deleted slot. + :returns: a SQRESULT + :remarks: invoke the _delslot metamethod in the table delegate. it only works on tables. + +pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack; if the slot does not exist, nothing happens. + + + + + +.. _sq_get: + +.. c:function:: SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: this call will invokes the delegation system like a normal dereference it only works on tables, arrays, classes, instances and userdata; if the function fails, nothing will be pushed in the stack. + +pops a key from the stack and performs a get operation on the object at the position idx in the stack; and pushes the result in the stack. + + + + + +.. _sq_getattributes: + +.. c:function:: SQRESULT sq_getattributes(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target class in the stack + :returns: a SQRESULT + +Gets the attribute of a class member. The function pops a key from the stack and pushes the attribute of the class member indexed by they key from a class at position idx in the stack. If key is null the function gets the class level attribute. + + + + + +.. _sq_getbase: + +.. c:function:: SQRESULT sq_getbase(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target class in the stack + :returns: a SQRESULT + +pushes the base class of the 'class' at stored position idx in the stack. + + + + + +.. _sq_getclass: + +.. c:function:: SQRESULT sq_getclass(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target class instance in the stack + :returns: a SQRESULT + +pushes the class of the 'class instance' at stored position idx in the stack. + + + + + +.. _sq_getdelegate: + +.. c:function:: SQRESULT sq_getdelegate(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + +pushes the current delegate of the object at the position idx in the stack. + + + + + +.. _sq_getfreevariable: + +.. c:function:: const SQChar * sq_getfreevariable(HSQUIRRELVM v, SQInteger idx, SQInteger nval) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack(closure) + :param SQInteger nval: 0 based index of the free variable(relative to the closure). + :returns: the name of the free variable for pure squirrel closures. NULL in case of error or if the index of the variable is out of range. In case the target closure is a native closure, the return name is always "@NATIVE". + :remarks: The function works for both squirrel closure and native closure. + +gets the value of the free variable of the closure at the position idx in the stack. + + + + + +.. _sq_getweakrefval: + +.. c:function:: SQRESULT sq_getweakrefval(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target weak reference + :returns: a SQRESULT + :remarks: if the function fails, nothing is pushed in the stack. + +pushes the object pointed by the weak reference at position idx in the stack. + + + + + +.. _sq_instanceof: + +.. c:function:: SQBool sq_instanceof(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: SQTrue if the instance at position -2 in the stack is an instance of the class object at position -1 in the stack. + :remarks: The function doesn't pop any object from the stack. + +Determines if an object is an instance of a certain class. Expects an instance and a class in the stack. + + + + + +.. _sq_newmember: + +.. c:function:: SQRESULT sq_newmember(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :param SQBool bstatic: if SQTrue creates a static member. + :returns: a SQRESULT + :remarks: Invokes the _newmember metamethod in the class. it only works on classes. + +pops a key, a value and an object (which will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack; if the slot does not exist, it will be created. + + + + + +.. _sq_newslot: + +.. c:function:: SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :param SQBool bstatic: if SQTrue creates a static member. This parameter is only used if the target object is a class. + :returns: a SQRESULT + :remarks: Invokes the _newslot metamethod in the table delegate. it only works on tables and classes. + +pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack, if the slot does not exist it will be created. + + + + + +.. _sq_next: + +.. c:function:: SQRESULT sq_next(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + +Pushes in the stack the next key and value of an array, table, or class slot. To start the iteration this function expects a null value on top of the stack; at every call the function will substitute the null value with an iterator and push key and value of the container slot. Every iteration the application has to pop the previous key and value but leave the iterator(that is used as reference point for the next iteration). The function will fail when all slots have been iterated(see Tables and arrays manipulation). + + + + + +.. _sq_rawdeleteslot: + +.. c:function:: SQRESULT sq_rawdeleteslot(HSQUIRRELVM v, SQInteger idx, SQBool pushval) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :param SQBool pushval: if this param is true the function will push the value of the deleted slot. + :returns: a SQRESULT + +Deletes a slot from a table without employing the _delslot metamethod. Pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack; if the slot does not exist nothing happens. + + + + + +.. _sq_rawget: + +.. c:function:: SQRESULT sq_rawget(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: Only works on tables and arrays. + +pops a key from the stack and performs a get operation on the object at position idx in the stack, without employing delegation or metamethods. + + + + + +.. _sq_rawnewmember: + +.. c:function:: SQRESULT sq_rawnewmember(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target table in the stack + :param SQBool bstatic: if SQTrue creates a static member. + :returns: a SQRESULT + :remarks: it only works on classes. + +pops a key, a value and an object(that will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack; if the slot does not exist it will be created. + + + + + +.. _sq_rawset: + +.. c:function:: SQRESULT sq_rawset(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: it only works on tables and arrays. if the function fails nothing will be pushed in the stack. + +pops a key and a value from the stack and performs a set operation on the object at position idx in the stack, without employing delegation or metamethods. + + + + + +.. _sq_set: + +.. c:function:: SQRESULT sq_set(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: this call will invoke the delegation system like a normal assignment, it only works on tables, arrays and userdata. + +pops a key and a value from the stack and performs a set operation on the object at position idx in the stack. + + + + + +.. _sq_setattributes: + +.. c:function:: SQRESULT sq_setattributes(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target class in the stack. + :returns: a SQRESULT + +Sets the attribute of a class member. The function pops a key and a value from the stack and sets the attribute (indexed by the key) on the class at position idx in the stack. If key is null the function sets the class level attribute. If the function succeed, the old attribute value is pushed in the stack. + + + + + +.. _sq_setdelegate: + +.. c:function:: SQRESULT sq_setdelegate(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :returns: a SQRESULT + :remarks: to remove the delegate from an object, set a null value. + +pops a table from the stack and sets it as the delegate of the object at the position idx in the stack. + + + + + +.. _sq_setfreevariable: + +.. c:function:: SQRESULT sq_setfreevariable(HSQUIRRELVM v, SQInteger idx, SQInteger nval) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :param SQInteger nval: 0 based index of the free variable(relative to the closure). + :returns: a SQRESULT + +pops a value from the stack and sets it as a free variable of the closure at the position idx in the stack. + + + + + +.. _sq_weakref: + +.. c:function:: void sq_weakref(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index to the target object in the stack + :returns: a SQRESULT + :remarks: if the object at idx position is one of (integer, float, bool, null), the object itself is pushed instead of a weak ref. + +pushes a weak reference to the object at position idx in the stack. diff --git a/vscript/squirrel/doc/source/reference/api/raw_object_handling.rst b/vscript/squirrel/doc/source/reference/api/raw_object_handling.rst new file mode 100644 index 00000000..f655c345 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/raw_object_handling.rst @@ -0,0 +1,163 @@ +.. _api_ref_raw_object_handling: + +=================== +Raw object handling +=================== + +.. _sq_addref: + +.. c:function:: void sq_addref(HSQUIRRELVM v, HSQOBJECT* po) + + :param HSQUIRRELVM v: the target VM + :param HSQOBJECT* po: pointer to an object handler + +adds a reference to an object handler. + + + + + +.. _sq_getobjtypetag: + +.. c:function:: SQRESULT sq_getobjtypetag(HSQOBJECT* o, SQUserPointer* typetag) + + :param HSQOBJECT* o: pointer to an object handler + :param SQUserPointer* typetag: a pointer to the variable that will store the tag + :returns: a SQRESULT + :remarks: the function works also with instances. if the target object is an instance, the typetag of it's base class is fetched. + +gets the typetag of a raw object reference(userdata or class). + + + + + +.. _sq_getrefcount: + +.. c:function:: SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v, HSQOBJECT* po) + + :param HSQUIRRELVM v: the target VM + :param HSQOBJECT* po: object handler + +returns the number of references of a given object. + + + + + +.. _sq_getstackobj: + +.. c:function:: SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, HSQOBJECT* po) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: index of the target object in the stack + :param HSQOBJECT* po: pointer to an object handler + :returns: a SQRESULT + +gets an object from the stack and stores it in a object handler. + + + + + +.. _sq_objtobool: + +.. c:function:: SQBool sq_objtobool(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: If the object is not a bool will always return false. + +return the bool value of a raw object reference. + + + + + +.. _sq_objtofloat: + +.. c:function:: SQFloat sq_objtofloat(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: If the object is an integer will convert it to float. If the object is not a number will always return 0. + +return the float value of a raw object reference. + + + + + +.. _sq_objtointeger: + +.. c:function:: SQInteger sq_objtointeger(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: If the object is a float will convert it to integer. If the object is not a number will always return 0. + +return the integer value of a raw object reference. + + + + + +.. _sq_objtostring: + +.. c:function:: const SQChar* sq_objtostring(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: If the object doesn't reference a string it returns NULL. + +return the string value of a raw object reference. + + + + + +.. _sq_objtouserpointer: + +.. c:function:: SQUserPointer sq_objtouserpointer(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: If the object doesn't reference a userpointer it returns NULL. + +return the userpointer value of a raw object reference. + + + + + +.. _sq_pushobject: + +.. c:function:: void sq_pushobject(HSQUIRRELVM v, HSQOBJECT obj) + + :param HSQUIRRELVM v: the target VM + :param HSQOBJECT obj: object handler + +push an object referenced by an object handler into the stack. + + + + + +.. _sq_release: + +.. c:function:: SQBool sq_release(HSQUIRRELVM v, HSQOBJECT* po) + + :param HSQUIRRELVM v: the target VM + :param HSQOBJECT* po: pointer to an object handler + :returns: SQTrue if the object handler released has lost all is references(the ones added with sq_addref). SQFalse otherwise. + :remarks: the function will reset the object handler to null when it loses all references. + +remove a reference from an object handler. + + + + + +.. _sq_resetobject: + +.. c:function:: void sq_resetobject(HSQOBJECT* po) + + :param HSQOBJECT* po: pointer to an object handler + :remarks: Every object handler has to be initialized with this function. + +resets(initialize) an object handler. diff --git a/vscript/squirrel/doc/source/reference/api/stack_operations.rst b/vscript/squirrel/doc/source/reference/api/stack_operations.rst new file mode 100644 index 00000000..bcd0e6c2 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/api/stack_operations.rst @@ -0,0 +1,107 @@ +.. _api_ref_stack_operations: + +================ +Stack Operations +================ + +.. _sq_cmp: + +.. c:function:: SQInteger sq_cmp(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: > 0 if obj1>obj2 + :returns: == 0 if obj1==obj2 + :returns: < 0 if obj1 0. :: + + sq_pushroottable(v); + sq_pushstring(v,"foo",-1); + sq_get(v,-2); //get the function from the root table + sq_pushroottable(v); //'this' (function environment object) + sq_pushinteger(v,1); + sq_pushfloat(v,2.0); + sq_pushstring(v,"three",-1); + sq_call(v,4,SQFalse,SQFalse); + sq_pop(v,2); //pops the roottable and the function + +this is equivalent to the following Squirrel code:: + + foo(1,2.0,"three"); + +If a runtime error occurs (or a exception is thrown) during the squirrel code execution +the sq_call will fail. diff --git a/vscript/squirrel/doc/source/reference/embedding/compiling_a_script.rst b/vscript/squirrel/doc/source/reference/embedding/compiling_a_script.rst new file mode 100644 index 00000000..88c15c86 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/compiling_a_script.rst @@ -0,0 +1,58 @@ +.. embedding_compiling_a_script: + +================== +Compiling a script +================== + +You can compile a Squirrel script with the function *sq_compile*.:: + + typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer userdata); + + SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p, + const SQChar *sourcename,SQBool raiseerror); + +In order to compile a script is necessary for the host application to implement a reader +function (SQLEXREADFUNC); this function is used to feed the compiler with the script +data. +The function is called every time the compiler needs a character; It has to return a +character code if succeed or 0 if the source is finished. + +If sq_compile succeeds, the compiled script will be pushed as Squirrel function in the +stack. + +.. :note:: + In order to execute the script, the function generated by *sq_compile()* has + to be called through *sq_call()* + +Here an example of a 'read' function that read from a file: :: + + SQInteger file_lexfeedASCII(SQUserPointer file) + { + int ret; + char c; + if( ( ret=fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return c; + return 0; + } + + int compile_file(HSQUIRRELVM v,const char *filename) + { + FILE *f=fopen(filename,"rb"); + if(f) + { + sq_compile(v,file_lexfeedASCII,f,filename,1); + fclose(f); + return 1; + } + return 0; + } + +When the compiler fails for a syntax error it will try to call the 'compiler error handler'; +this function must be declared as follow: :: + + typedef void (*SQCOMPILERERROR)(HSQUIRRELVM /*v*/,const SQChar * /*desc*/,const SQChar * /*source*/, + SQInteger /*line*/,SQInteger /*column*/); + +and can be set with the following API call:: + + void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); diff --git a/vscript/squirrel/doc/source/reference/embedding/creating_a_c_function.rst b/vscript/squirrel/doc/source/reference/embedding/creating_a_c_function.rst new file mode 100644 index 00000000..43772f38 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/creating_a_c_function.rst @@ -0,0 +1,106 @@ +.. _embedding_creating_a_c_function: + +=================== +Create a C function +=================== + +A native C function must have the following prototype: :: + + typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); + +The parameters is an handle to the calling VM and the return value is an integer +respecting the following rules: + +* 1 if the function returns a value +* 0 if the function does not return a value +* SQ_ERROR runtime error is thrown + +In order to obtain a new callable squirrel function from a C function pointer, is necessary +to call sq_newclosure() passing the C function to it; the new Squirrel function will be +pushed in the stack. + +When the function is called, the stackbase is the first parameter of the function and the +top is the last. In order to return a value the function has to push it in the stack and +return 1. + +Function parameters are in the stack from position 1 ('this') to *n*. +*sq_gettop()* can be used to determinate the number of parameters. + +If the function has free variables, those will be in the stack after the explicit parameters +an can be handled as normal parameters. Note also that the value returned by *sq_gettop()* will be +affected by free variables. *sq_gettop()* will return the number of parameters plus +number of free variables. + +Here an example, the following function print the value of each argument and return the +number of arguments. :: + + SQInteger print_args(HSQUIRRELVM v) + { + SQInteger nargs = sq_gettop(v); //number of arguments + for(SQInteger n=1;n<=nargs;n++) + { + printf("arg %d is ",n); + switch(sq_gettype(v,n)) + { + case OT_NULL: + printf("null"); + break; + case OT_INTEGER: + printf("integer"); + break; + case OT_FLOAT: + printf("float"); + break; + case OT_STRING: + printf("string"); + break; + case OT_TABLE: + printf("table"); + break; + case OT_ARRAY: + printf("array"); + break; + case OT_USERDATA: + printf("userdata"); + break; + case OT_CLOSURE: + printf("closure(function)"); + break; + case OT_NATIVECLOSURE: + printf("native closure(C function)"); + break; + case OT_GENERATOR: + printf("generator"); + break; + case OT_USERPOINTER: + printf("userpointer"); + break; + case OT_CLASS: + printf("class"); + break; + case OT_INSTANCE: + printf("instance"); + break; + case OT_WEAKREF: + printf("weak reference"); + break; + default: + return sq_throwerror(v,"invalid param"); //throws an exception + } + } + printf("\n"); + sq_pushinteger(v,nargs); //push the number of arguments as return value + return 1; //1 because 1 value is returned + } + +Here an example of how to register a function:: + + SQInteger register_global_func(HSQUIRRELVM v,SQFUNCTION f,const char *fname) + { + sq_pushroottable(v); + sq_pushstring(v,fname,-1); + sq_newclosure(v,f,0); //create a new function + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); //pops the root table + return 0; + } diff --git a/vscript/squirrel/doc/source/reference/embedding/debug_interface.rst b/vscript/squirrel/doc/source/reference/embedding/debug_interface.rst new file mode 100644 index 00000000..3d38bf27 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/debug_interface.rst @@ -0,0 +1,58 @@ +.. _embedding_debug_interface: + +=============== +Debug Interface +=============== + +The squirrel VM exposes a very simple debug interface that allows to easily built a full +featured debugger. +Through the functions sq_setdebughook and sq_setnativedebughook is possible in fact to set a callback function that +will be called every time the VM executes an new line of a script or if a function get +called/returns. The callback will pass as argument the current line the current source and the +current function name (if any).:: + + SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); + +or :: + + SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook); + +The following code shows how a debug hook could look like(obviously is possible to +implement this function in C as well). :: + + function debughook(event_type,sourcefile,line,funcname) + { + local fname=funcname?funcname:"unknown"; + local srcfile=sourcefile?sourcefile:"unknown" + switch (event_type) { + case 'l': //called every line(that contains some code) + ::print("LINE line [" + line + "] func [" + fname + "]"); + ::print("file [" + srcfile + "]\n"); + break; + case 'c': //called when a function has been called + ::print("LINE line [" + line + "] func [" + fname + "]"); + ::print("file [" + srcfile + "]\n"); + break; + case 'r': //called when a function returns + ::print("LINE line [" + line + "] func [" + fname + "]"); + ::print("file [" + srcfile + "]\n"); + break; + } + } + +The parameter *event_type* can be 'l' ,'c' or 'r' ; a hook with a 'l' event is called for each line that +gets executed, 'c' every time a function gets called and 'r' every time a function returns. + +A full-featured debugger always allows displaying local variables and calls stack. +The call stack information are retrieved through sq_getstackinfos():: + + SQInteger sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); + +While the local variables info through sq_getlocal():: + + SQInteger sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger nseq); + +In order to receive line callbacks the scripts have to be compiled with debug infos enabled +this is done through sq_enabledebuginfo(); :: + + void sq_enabledebuginfo(HSQUIRRELVM v, SQInteger debuginfo); diff --git a/vscript/squirrel/doc/source/reference/embedding/error_conventions.rst b/vscript/squirrel/doc/source/reference/embedding/error_conventions.rst new file mode 100644 index 00000000..f86e7416 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/error_conventions.rst @@ -0,0 +1,16 @@ +.. _embedding_error_convetions: + + +======================== +Error Conventions +======================== + +.. index:: + single: Error Conventions + +Most of the functions in the API return a SQRESULT value; SQRESULT indicates if a +function completed successfully or not. +The macros SQ_SUCCEEDED() and SQ_FAILED() are used to test the result of a function.:: + + if(SQ_FAILED(sq_getstring(v,-1,&s))) + printf("getstring failed"); diff --git a/vscript/squirrel/doc/source/reference/embedding/memory_management.rst b/vscript/squirrel/doc/source/reference/embedding/memory_management.rst new file mode 100644 index 00000000..ad0fb082 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/memory_management.rst @@ -0,0 +1,28 @@ +.. _embedding_memory_management: + +======================== +Memory Management +======================== + +.. index:: single: Memory Management + +Squirrel uses reference counting (RC) as primary system for memory management; +however, the virtual machine (VM) has an auxiliary +mark and sweep garbage collector that can be invoked on demand. + +There are 2 possible compile time options: + + * The default configuration consists in RC plus a mark and sweep garbage collector. + The host program can call the function sq_collectgarbage() and perform a garbage collection cycle + during the program execution. The garbage collector isn't invoked by the VM and has to + be explicitly called by the host program. + + * The second a situation consists in RC only(define NO_GARBAGE_COLLECTOR); in this case is impossible for + the VM to detect reference cycles, so is the programmer that has to solve them explicitly in order to + avoid memory leaks. + +The only advantage introduced by the second option is that saves 2 additional +pointers that have to be stored for each object in the default configuration with +garbage collector(8 bytes for 32 bits systems). +The types involved are: tables, arrays, functions, threads, userdata and generators; all other +types are untouched. These options do not affect execution speed. diff --git a/vscript/squirrel/doc/source/reference/embedding/references_from_c.rst b/vscript/squirrel/doc/source/reference/embedding/references_from_c.rst new file mode 100644 index 00000000..ba84042c --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/references_from_c.rst @@ -0,0 +1,21 @@ +.. embedding_references_from_c: + +======================================================== +Mantaining references to Squirrel values from the C API +======================================================== + +Squirrel allows to reference values through the C API; the function sq_getstackobj() gets +a handle to a squirrel object(any type). The object handle can be used to control the lifetime +of an object by adding or removing references to it( see sq_addref() and sq_release()). +The object can be also re-pushed in the VM stack using sq_pushobject().:: + + HSQOBJECT obj; + + sq_resetobject(&obj); //initialize the handle + sq_getstackobj(v,-2,&obj); //retrieve an object handle from the pos -2 + sq_addref(v,&obj); //adds a reference to the object + + ... //do stuff + + sq_pushobject(v,obj); //push the object in the stack + sq_release(v,&obj); //relese the object diff --git a/vscript/squirrel/doc/source/reference/embedding/runtime_error_handling.rst b/vscript/squirrel/doc/source/reference/embedding/runtime_error_handling.rst new file mode 100644 index 00000000..b956e4be --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/runtime_error_handling.rst @@ -0,0 +1,17 @@ +.. _embedding_runtime_error_handling: + +====================== +Runtime error handling +====================== + +When an exception is not handled by Squirrel code with a try/catch statement, a runtime +error is raised and the execution of the current program is interrupted. It is possible to +set a call back function to intercept the runtime error from the host program; this is +useful to show meaningful errors to the script writer and for implementing visual +debuggers. +The following API call pops a Squirrel function from the stack and sets it as error handler.:: + + SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); + +The error handler is called with 2 parameters, an environment object (this) and a object. +The object can be any squirrel type. diff --git a/vscript/squirrel/doc/source/reference/embedding/tables_and_arrays_manipulation.rst b/vscript/squirrel/doc/source/reference/embedding/tables_and_arrays_manipulation.rst new file mode 100644 index 00000000..8378a102 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/tables_and_arrays_manipulation.rst @@ -0,0 +1,70 @@ +.. _embedding_tables_and_arrays_manipulation: + +============================== +Tables and arrays manipulation +============================== + +A new table is created calling sq_newtable, this function pushes a new table in the stack.:: + + void sq_newtable(HSQUIRRELVM v); + +To create a new slot:: + + SQRESULT sq_newslot(HSQUIRRELVM v,SQInteger idx,SQBool bstatic); + +To set or get the table delegate:: + + SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); + SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); + + +A new array is created calling sq_newarray, the function pushes a new array in the +stack; if the parameters size is bigger than 0 the elements are initialized to null.:: + + void sq_newarray (HSQUIRRELVM v,SQInteger size); + +To append a value to the back of the array:: + + SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); + +To remove a value from the back of the array:: + + SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQInteger pushval); + +To resize the array:: + + SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); + +To retrieve the size of a table or an array you must use sq_getsize():: + + SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); + +To set a value in an array or table:: + + SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); + +To get a value from an array or table:: + + SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); + +To get or set a value from a table without employing delegation:: + + SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); + SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); + +To iterate a table or an array:: + + SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); + +Here an example of how to perform an iteration: :: + + //push your table/array here + sq_pushnull(v) //null iterator + while(SQ_SUCCEEDED(sq_next(v,-2))) + { + //here -1 is the value and -2 is the key + + sq_pop(v,2); //pops key and val before the nex iteration + } + + sq_pop(v,1); //pops the null iterator diff --git a/vscript/squirrel/doc/source/reference/embedding/the_registry_table.rst b/vscript/squirrel/doc/source/reference/embedding/the_registry_table.rst new file mode 100644 index 00000000..4aa5f782 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/the_registry_table.rst @@ -0,0 +1,14 @@ +.. _embedding_the_registry_table: + +================== +The registry table +================== + +The registry table is an hidden table shared between vm and all his thread(friend vms). +This table is accessible only through the C API and is meant to be an utility structure +for native C library implementation. +For instance the sqstdlib(squirrel standard library)uses it to store configuration and shared objects +delegates. +The registry is accessible through the API call *sq_pushregistrytable()*.:: + + void sq_pushregistrytable(HSQUIRRELVM v); diff --git a/vscript/squirrel/doc/source/reference/embedding/the_stack.rst b/vscript/squirrel/doc/source/reference/embedding/the_stack.rst new file mode 100644 index 00000000..9c5f9aef --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/the_stack.rst @@ -0,0 +1,104 @@ +.. _embedding_the_stack: + + +========== +The Stack +========== + +Squirrel exchanges values with the virtual machine through a stack. This mechanism has +been inherited from the language Lua. +For instance to call a Squirrel function from C it is necessary to push the function and the +arguments in the stack and then invoke the function; also when Squirrel calls a C +function the parameters will be in the stack as well. + +------------- +Stack indexes +------------- + +Many API functions can arbitrarily refer to any element in the stack through an index. +The stack indexes follow those conventions: + +* 1 is the stack base +* Negative indexes are considered an offset from top of the stack. For instance -1 isthe top of the stack. +* 0 is an invalid index + +Here an example (let's pretend that this table is the VM stack) + ++------------+--------------------+--------------------+ +| **STACK** | **positive index** | **negative index** | ++============+====================+====================+ +| "test" | 4 | -1(top) | ++------------+--------------------+--------------------+ +| 1 | 3 | -2 | ++------------+--------------------+--------------------+ +| 0.5 | 2 | -3 | ++------------+--------------------+--------------------+ +| "foo" | 1(base) | -4 | ++------------+--------------------+--------------------+ + +In this case, the function *sq_gettop* would return 4; + +------------------ +Stack manipulation +------------------ + +The API offers several functions to push and retrieve data from the Squirrel stack. + +To push a value that is already present in the stack in the top position:: + + void sq_push(HSQUIRRELVM v,SQInteger idx); + +To pop an arbitrary number of elements:: + + void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); + +To remove an element from the stack:: + + void sq_remove(HSQUIRRELVM v,SQInteger idx); + +To retrieve the top index (and size) of the current +virtual stack you must call *sq_gettop* :: + + SQInteger sq_gettop(HSQUIRRELVM v); + +To force the stack to a certain size you can call *sq_settop* :: + + void sq_settop(HSQUIRRELVM v,SQInteger newtop); + +If the newtop is bigger than the previous one, the new positions in the stack will be +filled with null values. + +The following function pushes a C value into the stack:: + + void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); + void sq_pushfloat(HSQUIRRELVM v,SQFloat f); + void sq_pushinteger(HSQUIRRELVM v,SQInteger n); + void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); + void sq_pushbool(HSQUIRRELVM v,SQBool b); + +this function pushes a null into the stack:: + + void sq_pushnull(HSQUIRRELVM v); + +returns the type of the value in a arbitrary position in the stack:: + + SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); + +the result can be one of the following values: :: + + OT_NULL,OT_INTEGER,OT_FLOAT,OT_STRING,OT_TABLE,OT_ARRAY,OT_USERDATA, + OT_CLOSURE,OT_NATIVECLOSURE,OT_GENERATOR,OT_USERPOINTER,OT_BOOL,OT_INSTANCE,OT_CLASS,OT_WEAKREF + +The following functions convert a squirrel value in the stack to a C value:: + + SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); + SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger size); + SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); + SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); + SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); + SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); + SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *p); + +The function sq_cmp compares 2 values from the stack and returns their relation (like strcmp() in ANSI C).:: + + SQInteger sq_cmp(HSQUIRRELVM v); diff --git a/vscript/squirrel/doc/source/reference/embedding/userdata_and_userpointers.rst b/vscript/squirrel/doc/source/reference/embedding/userdata_and_userpointers.rst new file mode 100644 index 00000000..81e14f03 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/userdata_and_userpointers.rst @@ -0,0 +1,33 @@ +.. _embedding_userdata_and_userpointers: + +========================= +Userdata and UserPointers +========================= + +Squirrel allows the host application put arbitrary data chunks into a Squirrel value, this is +possible through the data type userdata.:: + + SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); + +When the function *sq_newuserdata* is called, Squirrel allocates a new userdata with the +specified size, returns a pointer to his payload buffer and push the object in the stack; at +this point the application can do whatever it want with this memory chunk, the VM will +automatically take cake of the memory deallocation like for every other built-in type. +A userdata can be passed to a function or stored in a table slot. By default Squirrel +cannot manipulate directly userdata; however is possible to assign a delegate to it and +define a behavior like it would be a table. +Because the application would want to do something with the data stored in a userdata +object when it get deleted, is possible to assign a callback that will be called by the VM +just before deleting a certain userdata. +This is done through the API call *sq_setreleasehook*.:: + + typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); + + void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); + +Another kind of userdata is the userpointer; this type is not a memory chunk like the +normal userdata, but just a 'void*' pointer. It cannot have a delegate and is passed by +value, so pushing a userpointer doesn't cause any memory allocation.:: + + void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); + diff --git a/vscript/squirrel/doc/source/reference/embedding/vm_initialization.rst b/vscript/squirrel/doc/source/reference/embedding/vm_initialization.rst new file mode 100644 index 00000000..03fba06c --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding/vm_initialization.rst @@ -0,0 +1,21 @@ +.. _embedding_vm_initialization: + +============================== +Virtual Machine Initialization +============================== + +The first thing that a host application has to do, is create a virtual machine. +The host application can create any number of virtual machines through the function +*sq_open()*. +Every single VM that was created using *sq_open()* has to be released with the function *sq_close()* when it is no +longer needed.:: + + int main(int argc, char* argv[]) + { + HSQUIRRELVM v; + v = sq_open(1024); //creates a VM with initial stack size 1024 + + //do some stuff with squirrel here + + sq_close(v); + } diff --git a/vscript/squirrel/doc/source/reference/embedding_squirrel.rst b/vscript/squirrel/doc/source/reference/embedding_squirrel.rst new file mode 100644 index 00000000..dc8d7fb1 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/embedding_squirrel.rst @@ -0,0 +1,29 @@ +.. _embedding_squirrel: + +*************************** + Embedding Squirrel +*************************** + +*This section describes how to embed Squirrel in a host application, +C language knowledge is required to understand this part of the manual.* + +Because of his nature of extension language, Squirrel's compiler and virtual machine +are implemented as C library. The library exposes a set of functions to compile scripts, +call functions, manipulate data and extend the virtual machine. +All declarations needed for embedding the language in an application are in the header file 'squirrel.h'. + +.. toctree:: + embedding/memory_management.rst + embedding/build_configuration.rst + embedding/error_conventions.rst + embedding/vm_initialization.rst + embedding/the_stack.rst + embedding/runtime_error_handling.rst + embedding/compiling_a_script.rst + embedding/calling_a_function.rst + embedding/creating_a_c_function.rst + embedding/tables_and_arrays_manipulation.rst + embedding/userdata_and_userpointers.rst + embedding/the_registry_table.rst + embedding/references_from_c.rst + embedding/debug_interface.rst diff --git a/vscript/squirrel/doc/source/reference/index.rst b/vscript/squirrel/doc/source/reference/index.rst new file mode 100644 index 00000000..e2d38184 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/index.rst @@ -0,0 +1,34 @@ +.. _reference: + +################################# + Squirrel 3.1 Reference Manual +################################# + +Copyright (c) 2003-2016 Alberto Demichelis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +.. toctree:: + :maxdepth: 3 + :numbered: + + introduction.rst + language.rst + embedding_squirrel.rst + api_reference.rst diff --git a/vscript/squirrel/doc/source/reference/introduction.rst b/vscript/squirrel/doc/source/reference/introduction.rst new file mode 100644 index 00000000..bc83447f --- /dev/null +++ b/vscript/squirrel/doc/source/reference/introduction.rst @@ -0,0 +1,16 @@ +.. _introduction: + +************ +Introduction +************ + +.. index:: + single: introduction + +Squirrel is a high-level, imperative-OO programming language, designed to be a powerful +scripting tool that fits within the size, memory bandwidth, and real-time requirements of +applications like games. +Squirrel offers a wide range of features like dynamic typing, delegation, higher +order functions, generators, tail recursion, exception handling, automatic memory +management while fitting both compiler and virtual machine into about 6k lines of C++ +code. diff --git a/vscript/squirrel/doc/source/reference/language.rst b/vscript/squirrel/doc/source/reference/language.rst new file mode 100644 index 00000000..35621196 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language.rst @@ -0,0 +1,23 @@ +.. _thelanguage: + +*************************** + The language +*************************** + +.. toctree:: + language/lexical_structure.rst + language/datatypes.rst + language/execution_context.rst + language/statements.rst + language/expressions.rst + language/tables.rst + language/arrays.rst + language/functions.rst + language/classes.rst + language/generators.rst + language/constants_and_enumerations.rst + language/threads.rst + language/weak_references.rst + language/delegation.rst + language/metamethods.rst + language/builtin_functions.rst diff --git a/vscript/squirrel/doc/source/reference/language/arrays.rst b/vscript/squirrel/doc/source/reference/language/arrays.rst new file mode 100644 index 00000000..ddf5114f --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/arrays.rst @@ -0,0 +1,19 @@ +.. _arrays: + + +================= +Arrays +================= + +.. index:: + single: Arrays + +An array is a sequence of values indexed by a integer number from 0 to the size of the +array minus 1. Arrays elements can be obtained through their index.:: + + local a=["I'm a string", 123] + print(typeof a[0]) //prints "string" + print(typeof a[1]) //prints "integer" + +Resizing, insertion, deletion of arrays and arrays elements is done through a set of +standard functions (see :ref:`built-in functions `). diff --git a/vscript/squirrel/doc/source/reference/language/builtin_functions.rst b/vscript/squirrel/doc/source/reference/language/builtin_functions.rst new file mode 100644 index 00000000..2f64105b --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/builtin_functions.rst @@ -0,0 +1,693 @@ +.. _builtin_functions: + + +================== +Built-in Functions +================== + +.. index:: + single: Built-in Functions + pair: Global Symbols; Built-in Functions + + +^^^^^^^^^^^^^^ +Global Symbols +^^^^^^^^^^^^^^ + +.. js:function:: array(size,[fill]) + +creates and returns array of a specified size. If the optional parameter fill is specified its value will be used to fill the new array's slots. If the fill parameter is omitted, null is used instead. + +.. js:function:: seterrorhandler(func) + + +sets the runtime error handler + +.. js:function:: callee() + + +returns the currently running closure + +.. js:function:: setdebughook(hook_func) + + +sets the debug hook + +.. js:function:: enabledebuginfo(enable) + +enable/disable the debug line information generation at compile time. enable != null enables. enable == null disables. + +.. js:function:: getroottable() + +returns the root table of the VM. + +.. js:function:: setroottable(table) + +sets the root table of the VM. And returns the previous root table. + +.. js:function:: getconsttable() + +returns the const table of the VM. + +.. js:function:: setconsttable(table) + +sets the const table of the VM; returns the previous const table. + +.. js:function:: assert(exp, [message]) + +throws an exception if exp is null or false. Throws "assertion failed" string by default, or message if specified. + +.. js:function:: print(x) + +prints x to the standard output + +.. js:function:: error(x) + +prints x in the standard error output + +.. js:function:: compilestring(string,[buffername]) + +compiles a string containing a squirrel script into a function and returns it:: + + local compiledscript=compilestring("::print(\"ciao\")"); + //run the script + compiledscript(); + +.. js:function:: collectgarbage() + + Runs the garbage collector and returns the number of reference cycles found (and deleted). This function only works on garbage collector builds. + +.. js:function:: resurrectunreachable() + +Runs the garbage collector and returns an array containing all unreachable object found. If no unreachable object is found, null is returned instead. This function is meant to help debugging reference cycles. This function only works on garbage collector builds. + +.. js:function:: type(obj) + +return the 'raw' type of an object without invoking the metamethod '_typeof'. + +.. js:function:: getstackinfos(level) + +returns the stack informations of a given call stack level. returns a table formatted as follow: :: + + { + func="DoStuff", //function name + + src="test.nut", //source file + + line=10, //line number + + locals = { //a table containing the local variables + + a=10, + + testy="I'm a string" + } + } + +level = 0 is getstackinfos() itself! level = 1 is the current function, level = 2 is the caller of the current function, and so on. If the stack level doesn't exist the function returns null. + +.. js:function:: newthread(threadfunc) + +creates a new cooperative thread object(coroutine) and returns it + +.. js:data:: _versionnumber_ + +integer values describing the version of VM and compiler. e.g. for Squirrel 3.0.1 this value will be 301 + +.. js:data:: _version_ + +string values describing the version of VM and compiler. + +.. js:data:: _charsize_ + +size in bytes of the internal VM representation for characters(1 for ASCII builds 2 for UNICODE builds). + +.. js:data:: _intsize_ + +size in bytes of the internal VM representation for integers(4 for 32bits builds 8 for 64bits builds). + +.. js:data:: _floatsize_ + +size in bytes of the internal VM representation for floats(4 for single precision builds 8 for double precision builds). + +----------------- +Default delegates +----------------- + +Except null and userdata every squirrel object has a default delegate containing a set of functions to manipulate and retrieve information from the object itself. + +^^^^^^^^ +Integer +^^^^^^^^ + +.. js:function:: integer.tofloat() + +convert the number to float and returns it + + +.. js:function:: integer.tostring() + +converts the number to string and returns it + + +.. js:function:: integer.tointeger() + +dummy function; returns the value of the integer. + + +.. js:function:: integer.tochar() + +returns a string containing a single character represented by the integer. + + +.. js:function:: integer.weakref() + +dummy function; returns the integer itself. + +^^^^^ +Float +^^^^^ + +.. js:function:: float.tofloat() + +returns the value of the float(dummy function) + + +.. js:function:: float.tointeger() + +converts the number to integer and returns it + + +.. js:function:: float.tostring() + +converts the number to string and returns it + + +.. js:function:: float.tochar() + +returns a string containing a single character represented by the integer part of the float. + + +.. js:function:: float.weakref() + +dummy function; returns the float itself. + +^^^^ +Bool +^^^^ + +.. js:function:: bool.tofloat() + +returns 1.0 for true 0.0 for false + + +.. js:function:: bool.tointeger() + +returns 1 for true 0 for false + + +.. js:function:: bool.tostring() + +returns "true" for true and "false" for false + + +.. js:function:: bool.weakref() + +dummy function; returns the bool itself. + +^^^^^^ +String +^^^^^^ + +.. js:function:: string.len() + +returns the string length + + +.. js:function:: string.tointeger([base]) + +Converts the string to integer and returns it. An optional parameter base can be specified--if a base is not specified, it defaults to base 10. + + +.. js:function:: string.tofloat() + +converts the string to float and returns it + + +.. js:function:: string.tostring() + +returns the string (really, a dummy function) + + +.. js:function:: string.slice(start,[end]) + +returns a section of the string as new string. Copies from start to the end (not included). If start is negative the index is calculated as length + start, if end is negative the index is calculated as length + end. If end is omitted end is equal to the string length. + + +.. js:function:: string.find(substr,[startidx]) + +Searches a sub string (substr) starting from the index startidx and returns the index of its first occurrence. If startidx is omitted the search operation starts from the beginning of the string. The function returns null if substr is not found. + + +.. js:function:: string.tolower() + +returns a lowercase copy of the string. + + +.. js:function:: string.toupper() + +returns a uppercase copy of the string. + + +.. js:function:: string.weakref() + +returns a weak reference to the object. + +^^^^^ +Table +^^^^^ + +.. js:function:: table.len() + +returns the number of slots contained in a table + + +.. js:function:: table.rawget(key) + +tries to get a value from the slot 'key' without employing delegation + + +.. js:function:: table.rawset(key,val) + +Sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created. Returns table itself. + + +.. js:function:: table.rawdelete() + +Deletes the slot key without employing delegation and returns its value. If the slot does not exists, returns null. + + +.. js:function:: table.rawin(key) + +returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation. + + +.. js:function:: table.weakref() + +returns a weak reference to the object. + + +.. js:function:: table.tostring() + +Tries to invoke the _tostring metamethod. If that fails, it returns "(table : pointer)". + + +.. js:function:: table.clear() + +removes all the slots from the table. Returns table itself. + + +.. js:function:: table.setdelegate(table) + +Sets the delegate of the table. To remove a delegate, 'null' must be passed to the function. The function returns the table itself (e.g. a.setdelegate(b) -- in this case 'a' is the return value). + + +.. js:function:: table.getdelegate() + +returns the table's delegate or null if no delegate was set. + + +.. js:function:: table.filter(func(key,val)) + +Creates a new table with all values that pass the test implemented by the provided function. In detail, it creates a new table, invokes the specified function for each key-value pair in the original table; if the function returns 'true', then the value is added to the newly created table at the same key. + +.. js:function:: table.keys() + +returns an array containing all the keys of the table slots. + +.. js:function:: table.values() + +returns an array containing all the values of the table slots. + +^^^^^^ +Array +^^^^^^ + +.. js:function:: array.len() + +returns the length of the array + + +.. js:function:: array.append(val) + +appends the value 'val' at the end of the array. Returns array itself. + + +.. js:function:: array.push(val) + +appends the value 'val' at the end of the array. Returns array itself. + + +.. js:function:: array.extend(array) + +Extends the array by appending all the items in the given array. Returns array itself. + + +.. js:function:: array.pop() + +removes a value from the back of the array and returns it. + + +.. js:function:: array.top() + +returns the value of the array with the higher index + + +.. js:function:: array.insert(idx,val) + +inserts the value 'val' at the position 'idx' in the array. Returns array itself. + + +.. js:function:: array.remove(idx) + +removes the value at the position 'idx' in the array and returns its value. + + +.. js:function:: array.resize(size,[fill]) + +Resizes the array. If the optional parameter 'fill' is specified, its value will be used to fill the new array's slots when the size specified is bigger than the previous size. If the fill parameter is omitted, null is used instead. Returns array itself. + + +.. js:function:: array.sort([compare_func]) + +Sorts the array in-place. A custom compare function can be optionally passed. The function prototype as to be the following.:: + + function custom_compare(a,b) + { + if(a>b) return 1 + else if(a :: + + arr.sort(@(a,b) a <=> b); + +Returns array itself. + +.. js:function:: array.reverse() + +reverse the elements of the array in place. Returns array itself. + + +.. js:function:: array.slice(start,[end]) + +Returns a section of the array as new array. Copies from start to the end (not included). If start is negative the index is calculated as length + start, if end is negative the index is calculated as length + end. If end is omitted end is equal to the array length. + + +.. js:function:: array.weakref() + +returns a weak reference to the object. + + +.. js:function:: array.tostring() + +returns the string "(array : pointer)". + + +.. js:function:: array.clear() + +removes all the items from the array + + +.. js:function:: array.map(func(item_value, [item_index], [array_ref])) + +Creates a new array of the same size. For each element in the original array invokes the function 'func' and assigns the return value of the function to the corresponding element of the newly created array. +Provided func can accept up to 3 arguments: array item value (required), array item index (optional), reference to array itself (optional). + + +.. js:function:: array.apply(func([item_value, [item_index], [array_ref])) + +for each element in the array invokes the function 'func' and replace the original value of the element with the return value of the function. + + +.. js:function:: array.reduce(func(prevval,curval), [initializer]) + +Reduces an array to a single value. For each element in the array invokes the function 'func' passing +the initial value (or value from the previous callback call) and the value of the current element. +The return value of the function is then used as 'prevval' for the next element. +If the optional initializer is present, it is placed before the items of the array in the calculation, +and serves as a default when the sequence is empty. +If initializer is not given then for sequence contains only one item, reduce() returns the first item, +and for empty sequence returns null. + +Given an sequence with 2 or more elements (including initializer) calls the function with the first two elements as the parameters, +gets that result, then calls the function with that result and the third element, gets that result, +calls the function with that result and the fourth parameter and so on until all element have been processed. +Finally, returns the return value of the last invocation of func. + + +.. js:function:: array.filter(func(index,val)) + +Creates a new array with all elements that pass the test implemented by the provided function. In detail, it creates a new array, for each element in the original array invokes the specified function passing the index of the element and it's value; if the function returns 'true', then the value of the corresponding element is added on the newly created array. + + +.. js:function:: array.find(value) + +Performs a linear search for the value in the array. Returns the index of the value if it was found null otherwise. + +^^^^^^^^ +Function +^^^^^^^^ + +.. js:function:: function.call(_this,args...) + +calls the function with the specified environment object('this') and parameters + + +.. js:function:: function.pcall(_this,args...) + +calls the function with the specified environment object('this') and parameters, this function will not invoke the error callback in case of failure(pcall stays for 'protected call') + + +.. js:function:: function.acall(array_args) + +calls the function with the specified environment object('this') and parameters. The function accepts an array containing the parameters that will be passed to the called function.Where array_args has to contain the required 'this' object at the [0] position. + + +.. js:function:: function.pacall(array_args) + +calls the function with the specified environment object('this') and parameters. The function accepts an array containing the parameters that will be passed to the called function.Where array_args has to contain the required 'this' object at the [0] position. This function will not invoke the error callback in case of failure(pacall stays for 'protected array call') + + +.. js:function:: function.weakref() + +returns a weak reference to the object. + + +.. js:function:: function.tostring() + +returns the string "(closure : pointer)". + + +.. js:function:: function.setroot(table) + +sets the root table of a closure + + +.. js:function:: function.getroot() + +returns the root table of the closure + + +.. js:function:: function.bindenv(env) + +clones the function(aka closure) and bind the environment object to it(table,class or instance). the this parameter of the newly create function will always be set to env. Note that the created function holds a weak reference to its environment object so cannot be used to control its lifetime. + + +.. js:function:: function.getinfos() + +returns a table containing informations about the function, like parameters, name and source name; :: + + //the data is returned as a table is in form + //pure squirrel function + { + native = false + name = "zefuncname" + src = "/somthing/something.nut" + parameters = ["a","b","c"] + defparams = [1,"def"] + varargs = 2 + } + //native C function + { + native = true + name = "zefuncname" + paramscheck = 2 + typecheck = [83886082,83886384] //this is the typemask (see C defines OT_INTEGER,OT_FLOAT etc...) + } + + + +^^^^^ +Class +^^^^^ + +.. js:function:: class.instance() + +returns a new instance of the class. this function does not invoke the instance constructor. The constructor must be explicitly called (eg. class_inst.constructor(class_inst) ). + + +.. js:function:: class.getattributes(membername) + +returns the attributes of the specified member. if the parameter member is null the function returns the class level attributes. + + +.. js:function:: class.setattributes(membername,attr) + +sets the attribute of the specified member and returns the previous attribute value. if the parameter member is null the function sets the class level attributes. + + +.. js:function:: class.rawin(key) + +returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation. + + +.. js:function:: class.weakref() + +returns a weak reference to the object. + + +.. js:function:: class.tostring() + +returns the string "(class : pointer)". + + +.. js:function:: class.rawget(key) + +tries to get a value from the slot 'key' without employing delegation + + +.. js:function:: class.rawset(key,val) + +sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created. + + +.. js:function:: class.newmember(key,val,[attrs],[bstatic]) + +sets/adds the slot 'key' with the value 'val' and attributes 'attrs' and if present invokes the _newmember metamethod. If bstatic is true the slot will be added as static. If the slot does not exists , it will be created. + + +.. js:function:: class.rawnewmember(key,val,[attrs],[bstatic]) + +sets/adds the slot 'key' with the value 'val' and attributes 'attrs'. If bstatic is true the slot will be added as static. If the slot does not exist, it will be created. It doesn't invoke any metamethod. + +^^^^^^^^^^^^^^ +Class Instance +^^^^^^^^^^^^^^ + +.. js:function:: instance.getclass() + +returns the class that created the instance. + + +.. js:function:: instance.rawin(key) + + :param key: ze key + +returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation. + + +.. js:function:: instance.weakref() + +returns a weak reference to the object. + + +.. js:function:: instance.tostring() + +tries to invoke the _tostring metamethod, if failed. returns "(instance : pointer)". + + +.. js:function:: instance.rawget(key) + +tries to get a value from the slot 'key' without employing delegation + + +.. js:function:: instance.rawset(key,val) + +sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created. + +^^^^^^^^^^^^^^ +Generator +^^^^^^^^^^^^^^ + + +.. js:function:: generator.getstatus() + +returns the status of the generator as string : "running", "dead" or "suspended". + + +.. js:function:: generator.weakref() + +returns a weak reference to the object. + + +.. js:function:: generator.tostring() + +returns the string "(generator : pointer)". + +^^^^^^^^^^^^^^ +Thread +^^^^^^^^^^^^^^ + +.. js:function:: thread.call(...) + +starts the thread with the specified parameters + + +.. js:function:: thread.wakeup([wakeupval]) + +wakes up a suspended thread, accepts a optional parameter that will be used as return value for the function that suspended the thread(usually suspend()) + + +.. js:function:: thread.wakeupthrow(objtothrow,[propagateerror = true]) + +wakes up a suspended thread, throwing an exception in the awaken thread, throwing the object 'objtothrow'. + + +.. js:function:: thread.getstatus() + +returns the status of the thread ("idle","running","suspended") + + +.. js:function:: thread.weakref() + +returns a weak reference to the object. + + +.. js:function:: thread.tostring() + +returns the string "(thread : pointer)". + + +.. js:function:: thread.getstackinfos(stacklevel) + +returns the stack frame informations at the given stack level (0 is the current function 1 is the caller and so on). + +^^^^^^^^^^^^^^ +Weak Reference +^^^^^^^^^^^^^^ + +.. js:function:: weakreference.ref() + +returns the object that the weak reference is pointing at; null if the object that was point at was destroyed. + + +.. js:function:: weakreference.weakref() + +returns a weak reference to the object. + + +.. js:function:: weakreference.tostring() + +returns the string "(weakref : pointer)". diff --git a/vscript/squirrel/doc/source/reference/language/classes.rst b/vscript/squirrel/doc/source/reference/language/classes.rst new file mode 100644 index 00000000..81ee4c41 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/classes.rst @@ -0,0 +1,429 @@ +.. _classes: + + +================= +Classes +================= + +.. index:: + single: Classes + +Squirrel implements a class mechanism similar to languages like Java/C++/etc... +however because of its dynamic nature it differs in several aspects. +Classes are first class objects like integer or strings and can be stored in +table slots local variables, arrays and passed as function parameters. + +----------------- +Class Declaration +----------------- + +.. index:: + pair: declaration; Class + single: Class Declaration + +A class object is created through the keyword 'class' . The class object follows +the same declaration syntax of a table(see :ref:`Tables `) with the only difference +of using ';' as optional separator rather than ','. + +For instance: :: + + class Foo { + //constructor + constructor(a) + { + testy = ["stuff",1,2,3,a]; + } + //member function + function PrintTesty() + { + foreach(i,val in testy) + { + ::print("idx = "+i+" = "+val+" \n"); + } + } + //property + testy = null; + + } + +the previous code example is a syntactic sugar for: :: + + Foo <- class { + //constructor + constructor(a) + { + testy = ["stuff",1,2,3,a]; + } + //member function + function PrintTesty() + { + foreach(i,val in testy) + { + ::print("idx = "+i+" = "+val+" \n"); + } + } + //property + testy = null; + + } + +in order to emulate namespaces, it is also possible to declare something like this:: + + //just 2 regular nested tables + FakeNamespace <- { + Utils = {} + } + + class FakeNamespace.Utils.SuperClass { + constructor() + { + ::print("FakeNamespace.Utils.SuperClass") + } + function DoSomething() + { + ::print("DoSomething()") + } + } + + function FakeNamespace::Utils::SuperClass::DoSomethingElse() + { + ::print("FakeNamespace::Utils::SuperClass::DoSomethingElse()") + } + + local testy = FakeNamespace.Utils.SuperClass(); + testy.DoSomething(); + testy.DoSomethingElse(); + +After its declaration, methods or properties can be added or modified by following +the same rules that apply to a table(operator ``<-``).:: + + //adds a new property + Foo.stuff <- 10; + + //modifies the default value of an existing property + Foo.testy <- "I'm a string"; + + //adds a new method + function Foo::DoSomething(a,b) + { + return a+b; + } + +After a class is instantiated is no longer possible to add new properties however is possible to add or replace methods. + +^^^^^^^^^^^^^^^^ +Static variables +^^^^^^^^^^^^^^^^ + +.. index:: + pair: static variables; Class + single: Static variables + +Squirrel's classes support static member variables. A static variable shares its value +between all instances of the class. Statics are declared by prefixing the variable declaration +with the keyword ``static``; the declaration must be in the class body. + +.. note:: Statics are read-only. + +:: + + class Foo { + constructor() + { + //..stuff + } + name = "normal variable"; + //static variable + static classname = "The class name is foo"; + }; + +^^^^^^^^^^^^^^^^ +Class Attributes +^^^^^^^^^^^^^^^^ + +.. index:: + pair: attributes; Class + single: Class Attributes + +Classes allow to associate attributes to it's members. Attributes are a form of metadata +that can be used to store application specific informations, like documentations +strings, properties for IDEs, code generators etc... +Class attributes are declared in the class body by preceding the member declaration and +are delimited by the symbol ````. +Here an example: :: + + class Foo { + //attributes of PrintTesty + function PrintTesty() + { + foreach(i,val in testy) + { + ::print("idx = "+i+" = "+val+" \n"); + } + } + //attributes of testy + testy = null; + } + +Attributes are, matter of fact, a table. Squirrel uses ```` syntax +instead of curly brackets ``{}`` for the attribute declaration to increase readability. + +This means that all rules that apply to tables apply to attributes. + +Attributes can be retrieved through the built-in function ``classobj.getattributes(membername)`` (see built-in functions). +and can be modified/added through the built-in function ``classobj.setattributes(membername,val)``. + +the following code iterates through the attributes of all Foo members.:: + + foreach(member,val in Foo) + { + ::print(member+"\n"); + local attr; + if((attr = Foo.getattributes(member)) != null) { + foreach(i,v in attr) + { + ::print("\t"+i+" = "+(typeof v)+"\n"); + } + } + else { + ::print("\t\n") + } + } + +----------------- +Class Instances +----------------- + +.. index:: + pair: instances; Class + single: Class Instances + +The class objects inherits several of the table's feature with the difference that multiple instances of the +same class can be created. +A class instance is an object that share the same structure of the table that created it but +holds is own values. +Class *instantiation* uses function notation. +A class instance is created by calling a class object. Can be useful to imagine a class like a function +that returns a class instance.:: + + //creates a new instance of Foo + local inst = Foo(); + +When a class instance is created its member are initialized *with the same value* specified in the +class declaration. The values are copied verbatim, *no cloning is performed* even if the value is a container or a class instances. + +.. note:: FOR C# and Java programmers: + + Squirrel doesn't clone member's default values nor executes the member declaration for each instance(as C# or java). + + So consider this example: :: + + class Foo { + myarray = [1,2,3] + mytable = {} + } + + local a = Foo(); + local b = Foo(); + + In the snippet above both instances will refer to the same array and same table.To achieve what a C# or Java programmer would + expect, the following approach should be taken. :: + + class Foo { + myarray = null + mytable = null + constructor() + { + myarray = [1,2,3] + mytable = {} + } + } + + local a = Foo(); + local b = Foo(); + +When a class defines a method called 'constructor', the class instantiation operation will +automatically invoke it for the newly created instance. +The constructor method can have parameters, this will impact on the number of parameters +that the *instantiation operation* will require. +Constructors, as normal functions, can have variable number of parameters (using the parameter ``...``).:: + + class Rect { + constructor(w,h) + { + width = w; + height = h; + } + x = 0; + y = 0; + width = null; + height = null; + } + + //Rect's constructor has 2 parameters so the class has to be 'called' + //with 2 parameters + local rc = Rect(100,100); + +After an instance is created, its properties can be set or fetched following the +same rules that apply to tables. Methods cannot be set. + +Instance members cannot be removed. + +The class object that created a certain instance can be retrieved through the built-in function +``instance.getclass()`` (see :ref:`built-in functions `) + +The operator ``instanceof`` tests if a class instance is an instance of a certain class.:: + + local rc = Rect(100,100); + if(rc instanceof ::Rect) { + ::print("It's a rect"); + } + else { + ::print("It isn't a rect"); + } + +.. note:: Since Squirrel 3.x instanceof doesn't throw an exception if the left expression is not a class, it simply fails + +-------------- +Inheritance +-------------- + +.. index:: + pair: inheritance; Class + single: Inheritance + +Squirrel's classes support single inheritance by adding the keyword ``extends``, followed +by an expression, in the class declaration. +The syntax for a derived class is the following: :: + + class SuperFoo extends Foo { + function DoSomething() { + ::print("I'm doing something"); + } + } + +When a derived class is declared, Squirrel first copies all base's members in the +new class then proceeds with evaluating the rest of the declaration. + +A derived class inherit all members and properties of it's base, if the derived class +overrides a base function the base implementation is shadowed. +It's possible to access a overridden method of the base class by fetching the method from +through the 'base' keyword. + +Here an example: :: + + class Foo { + function DoSomething() { + ::print("I'm the base"); + } + }; + + class SuperFoo extends Foo { + //overridden method + function DoSomething() { + //calls the base method + base.DoSomething(); + ::print("I'm doing something"); + } + } + +Same rule apply to the constructor. The constructor is a regular function (apart from being automatically invoked on construction).:: + + class BaseClass { + constructor() + { + ::print("Base constructor\n"); + } + } + + class ChildClass extends BaseClass { + constructor() + { + base.constructor(); + ::print("Child constructor\n"); + } + } + + local test = ChildClass(); + +The base class of a derived class can be retrieved through the built-in method ``getbase()``.:: + + local thebaseclass = SuperFoo.getbase(); + +Note that because methods do not have special protection policies when calling methods of the same +objects, a method of a base class that calls a method of the same class can end up calling a overridden method of the derived class. + +A method of a base class can be explicitly invoked by a method of a derived class though the keyword ``base`` (as in base.MyMethod() ).:: + + class Foo { + function DoSomething() { + ::print("I'm the base"); + } + function DoIt() + { + DoSomething(); + } + }; + + class SuperFoo extends Foo { + //overridden method + function DoSomething() { + ::print("I'm the derived"); + + } + function DoIt() { + base.DoIt(); + } + } + + //creates a new instance of SuperFoo + local inst = SuperFoo(); + + //prints "I'm the derived" + inst.DoIt(); + +---------------------- +Metamethods +---------------------- + +.. index:: + pair: metamethods; Class + single: Class metamethods + +Class instances allow the customization of certain aspects of the +their semantics through metamethods(see see :ref:`Metamethods `). +For C++ programmers: "metamethods behave roughly like overloaded operators". +The metamethods supported by classes are ``_add, _sub, _mul, _div, _unm, _modulo, +_set, _get, _typeof, _nexti, _cmp, _call, _delslot, _tostring`` + +Class objects instead support only 2 metamethods : ``_newmember`` and ``_inherited`` + +the following example show how to create a class that implements the metamethod ``_add``.:: + + class Vector3 { + constructor(...) + { + if(vargv.len() >= 3) { + x = vargv[0]; + y = vargv[1]; + z = vargv[2]; + } + } + function _add(other) + { + return ::Vector3(x+other.x,y+other.y,z+other.z); + } + + x = 0; + y = 0; + z = 0; + } + + local v0 = Vector3(1,2,3) + local v1 = Vector3(11,12,13) + local v2 = v0 + v1; + ::print(v2.x+","+v2.y+","+v2.z+"\n"); + +Since version 2.1, classes support 2 metamethods ``_inherited`` and ``_newmember``. +``_inherited`` is invoked when a class inherits from the one that implements ``_inherited``. +``_newmember`` is invoked for each member that is added to the class(at declaration time). diff --git a/vscript/squirrel/doc/source/reference/language/constants_and_enumerations.rst b/vscript/squirrel/doc/source/reference/language/constants_and_enumerations.rst new file mode 100644 index 00000000..77fd9bc2 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/constants_and_enumerations.rst @@ -0,0 +1,97 @@ +.. _constants_and_enumerations: + + +======================== +Constants & Enumerations +======================== + +.. index:: + single: Constants & Enumerations + + + +Squirrel allows to bind constant values to an identifier that will be evaluated compile-time. +This is achieved though constants and Enumerations. + +--------------- +Constants +--------------- + +.. index:: + single: Constants + +Constants bind a specific value to an identifier. Constants are similar to +global values, except that they are evaluated compile time and their value cannot be changed. + +constants values can only be integers, floats or string literals. No expression are allowed. +are declared with the following syntax.:: + + const foobar = 100; + const floatbar = 1.2; + const stringbar = "I'm a constant string"; + +constants are always globally scoped, from the moment they are declared, any following code +can reference them. +Constants will shadow any global slot with the same name( the global slot will remain visible by using the ``::`` syntax).:: + + local x = foobar * 2; + +--------------- +Enumerations +--------------- + +.. index:: + single: Enumerations + +As Constants, Enumerations bind a specific value to a name. Enumerations are also evaluated at compile time +and their value cannot be changed. + +An enum declaration introduces a new enumeration into the program. +Enumeration values can only be integers, floats or string literals. No expression are allowed.:: + + enum Stuff { + first, //this will be 0 + second, //this will be 1 + third //this will be 2 + } + +or:: + + enum Stuff { + first = 10 + second = "string" + third = 1.2 + } + +An enum value is accessed in a manner that's similar to accessing a static class member. +The name of the member must be qualified with the name of the enumeration, for example ``Stuff.second`` +Enumerations will shadow any global slot with the same name( the global slot will remain visible by using the ``::`` syntax).:: + + local x = Stuff.first * 2; + +-------------------- +Implementation notes +-------------------- + +Enumerations and Constants are a compile-time feature. Only integers, string and floats can be declared as const/enum; +No expressions are allowed(because they would have to be evaluated compile time). +When a const or an enum is declared, it is added compile time to the ``consttable``. This table is stored in the VM shared state +and is shared by the VM and all its threads. +The ``consttable`` is a regular squirrel table; In the same way as the ``roottable`` +it can be modified runtime. +You can access the ``consttable`` through the built-in function ``getconsttable()`` +and also change it through the built-in function ``setconsttable()`` + +here some example: :: + + //creates a constant + getconsttable()["something"] <- 10" + //creates an enumeration + getconsttable()["somethingelse"] <- { a = "10", c = "20", d = "200"}; + //deletes the constant + delete getconsttable()["something"] + //deletes the enumeration + delete getconsttable()["somethingelse"] + +This system allows to procedurally declare constants and enumerations, it is also possible to assign any squirrel type +to a constant/enumeration(function,classes etc...). However this will make serialization of a code chunk impossible. diff --git a/vscript/squirrel/doc/source/reference/language/datatypes.rst b/vscript/squirrel/doc/source/reference/language/datatypes.rst new file mode 100644 index 00000000..843ed8b3 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/datatypes.rst @@ -0,0 +1,162 @@ +.. _datatypes_and_values: + +===================== +Values and Data types +===================== + +While Squirrel is a dynamically typed language and variables do not +have a type, different operations may interpret the variable as +containing a type. Squirrel's basic types are integer, float, string, +null, table, array, function, generator, class, instance, bool, thread +and userdata. + +.. _userdata-index: + +-------- +Integer +-------- + +An Integer represents a 32 bit (or better) signed number.:: + + local a = 123 //decimal + local b = 0x0012 //hexadecimal + local c = 075 //octal + local d = 'w' //char code + +-------- +Float +-------- + +A float represents a 32 bit (or better) floating point number.:: + + local a=1.0 + local b=0.234 + +-------- +String +-------- + +Strings are an immutable sequence of characters. In order to modify a +string is it necessary create a new one. + +Squirrel's strings are similar to strings in C or C++. They are +delimited by quotation marks(``"``) and can contain escape +sequences (``\t``, ``\a``, ``\b``, ``\n``, ``\r``, ``\v``, ``\f``, +``\\``, ``\"``, ``\'``, ``\0``, ``\x``, ``\u`` and +``\U``). + +Verbatim string literals do not interpret escape sequences. They begin +with ``@"`` and end with the matching quote. Verbatim string literals +also can extend over a line break. If they do, they include any white +space characters between the quotes: :: + + local a = "I'm a wonderful string\n" + // has a newline at the end of the string + local x = @"I'm a verbatim string\n" + // the \n is literal, similar to "\\n" in a regular string. + +However, a doubled quotation mark within a verbatim string is replaced +by a single quotation mark: :: + + local multiline = @" + this is a multiline string + it will ""embed"" all the new line + characters + " + +-------- +Null +-------- + +The null value is a primitive value that represents the null, empty, or non-existent +reference. The type Null has exactly one value, called null.:: + + local a = null + +-------- +Bool +-------- + +Bool is a double-valued (Boolean) data type. Its literals are ``true`` +and ``false``. A bool value expresses the validity of a condition +(tells whether the condition is true or false).:: + + local a = true; + +-------- +Table +-------- + +Tables are associative containers implemented as a set of key/value pairs +called slots.:: + + local t={} + local test= + { + a=10 + b=function(a) { return a+1; } + } + +-------- +Array +-------- + +Arrays are simple sequence of objects. Their size is dynamic and their index always starts from 0.:: + + local a = ["I'm","an","array"] + local b = [null] + b[0] = a[2]; + +-------- +Function +-------- + +Functions are similar to those in other C-like languages with a few key differences (see below). + +-------- +Class +-------- + +Classes are associative containers implemented as sets of key/value +pairs. Classes are created through a 'class expression' or a 'class +statement'. class members can be inherited from another class object +at creation time. After creation, members can be added until an +instance of the class is created. + +-------------- +Class Instance +-------------- + +Class instances are created by calling a *class object*. Instances, as +tables, are implemented as sets of key/value pairs. Instance members +cannot be dynamically added or removed; however the value of the +members can be changed. + +--------- +Generator +--------- + +Generators are functions that can be suspended with the statement +'yield' and resumed later (see :ref:`Generators `). + +--------- +Userdata +--------- + +Userdata objects are blobs of memory or pointers defined by the host +application but stored within Squirrel variables (See :ref:`Userdata +and UserPointers `). + +--------- +Thread +--------- + +Threads are objects representing a cooperative thread of execution, +also known as coroutines. + +-------------- +Weak Reference +-------------- + +Weak References are objects that point to another (non-scalar) object but do not own a strong reference to it. +(See :ref:`Weak References `). diff --git a/vscript/squirrel/doc/source/reference/language/delegation.rst b/vscript/squirrel/doc/source/reference/language/delegation.rst new file mode 100644 index 00000000..63607d5c --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/delegation.rst @@ -0,0 +1,35 @@ +.. _delegation: + + +======================== +Delegation +======================== + +.. index:: + single: Delegation + +Squirrel supports implicit delegation. Every table or userdata can have a parent table +(delegate). A parent table is a normal table that allows the definition of special behaviors +for his child. +When a table (or userdata) is indexed with a key that doesn't correspond to one of its +slots, the interpreter automatically delegates the get (or set) operation to its parent.:: + + Entity <- { + } + + function Entity::DoStuff() + { + ::print(_name); + } + + local newentity = { + _name="I'm the new entity" + } + newentity.setdelegate(Entity) + + newentity.DoStuff(); //prints "I'm the new entity" + +The delegate of a table can be retreived through built-in method ``table.getdelegate()``.:: + + local thedelegate = newentity.getdelegate(); + diff --git a/vscript/squirrel/doc/source/reference/language/execution_context.rst b/vscript/squirrel/doc/source/reference/language/execution_context.rst new file mode 100644 index 00000000..47ef3209 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/execution_context.rst @@ -0,0 +1,95 @@ +.. _executioncontext: + +======================= +Execution Context +======================= + +.. index:: + single: execution context + +The execution context is the union of the function stack frame and the function +environment object(this) and the function root(root table). +The stack frame is the portion of stack where the local variables declared in its body are +stored. +The environment object is an implicit parameter that is automatically passed by the +function caller (see see :ref:`functions `). +The root table is a table associated to the function during its creation. +The root table value of a function is the root table of the VM at the function creation. +The root table of function can also be changed after creation with closure.setroot(). +During the execution, the body of a function can only transparently refer to his execution +context. +This mean that a single identifier can refer to a local variable, to an environment object slot +or to the slot of the closure root table; +The environment object can be explicitly accessed by the keyword ``this``. +The closure root table can be explicitly accessed through the operator ``::`` (see :ref:`Variables `). + +.. _variables: + +----------------- +Variables +----------------- + +There are two types of variables in Squirrel, local variables and tables/arrays slots. +Because global variables(variables stored in the root of a closure) are stored in a table, they are table slots. + +A single identifier refers to a local variable or a slot in the environment object.:: + + derefexp := id; + +:: + + _table["foo"] + _array[10] + +with tables we can also use the '.' syntax:: + + derefexp := exp '.' id + +:: + + _table.foo + +Squirrel first checks if an identifier is a local variable (function arguments are local +variables) if not looks up the environment object (this) and finally looks up +to the closure root. + +For instance::: + + function testy(arg) + { + local a=10; + print(a); + return arg; + } + +in this case 'foo' will be equivalent to 'this.foo' or this["foo"]. + +Global variables are stored in a table called the root table. Usually in the global scope the +environment object is the root table, but to explicitly access the closure root of the function from +another scope, the slot name must be prefixed with ``'::'`` (``::foo``). + +For instance::: + + function testy(arg) + { + local a=10; + return arg+::foo; + } + +accesses the variable 'foo' in the closure root table. + +Since Squirrel 3.1 each function has a weak reference to a specific root table, this can differ from the current VM root table.:: + + function test() { + foo = 10; + } + +is equivalent to write:: + + function test() { + if("foo" in this) { + this.foo = 10; + }else { + ::foo = 10; + } + } diff --git a/vscript/squirrel/doc/source/reference/language/expressions.rst b/vscript/squirrel/doc/source/reference/language/expressions.rst new file mode 100644 index 00000000..9e75c7e7 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/expressions.rst @@ -0,0 +1,374 @@ +.. _expressions: + + +================= +Expressions +================= + +.. index:: + single: Expressions + +---------------- +Assignment +---------------- + +.. index:: + single: assignment(=) + single: new slot(<-) + +:: + + exp := derefexp '=' exp + exp:= derefexp '<-' exp + +squirrel implements 2 kind of assignment: the normal assignment(=):: + + a = 10; + +and the "new slot" assignment.:: + + a <- 10; + +The new slot expression allows to add a new slot into a table(see :ref:`Tables `). If the slot +already exists in the table it behaves like a normal assignment. + +---------------- +Operators +---------------- + +.. index:: + single: Operators + +^^^^^^^^^^^^^ +?: Operator +^^^^^^^^^^^^^ + +.. index:: + pair: ?: Operator; Operators + +:: + + exp := exp_cond '?' exp1 ':' exp2 + +conditionally evaluate an expression depending on the result of an expression. + +^^^^^^^^^^^^^ +Arithmetic +^^^^^^^^^^^^^ + +.. index:: + pair: Arithmetic Operators; Operators + +:: + + exp:= 'exp' op 'exp' + +Squirrel supports the standard arithmetic operators ``+, -, *, / and %``. +Other than that is also supports compact operators (``+=,-=,*=,/=,%=``) and +increment and decrement operators(++ and --);:: + + a += 2; + //is the same as writing + a = a + 2; + x++ + //is the same as writing + x = x + 1 + +All operators work normally with integers and floats; if one operand is an integer and one +is a float the result of the expression will be float. +The + operator has a special behavior with strings; if one of the operands is a string the +operator + will try to convert the other operand to string as well and concatenate both +together. For instances and tables, ``_tostring`` is invoked. + +^^^^^^^^^^^^^ +Relational +^^^^^^^^^^^^^ + +.. index:: + pair: Relational Operators; Operators + +:: + + exp:= 'exp' op 'exp' + +Relational operators in Squirrel are : ``==, <, <=, <, <=, !=`` + +These operators return true if the expression is false and a value different than true if the +expression is true. Internally the VM uses the integer 1 as true but this could change in +the future. + +^^^^^^^^^^^^^^ +3 ways compare +^^^^^^^^^^^^^^ + +.. index:: + pair: 3 ways compare operator; Operators + +:: + + exp:= 'exp' <=> 'exp' + +the 3 ways compare operator <=> compares 2 values A and B and returns an integer less than 0 +if A < B, 0 if A == B and an integer greater than 0 if A > B. + +^^^^^^^^^^^^^^ +Logical +^^^^^^^^^^^^^^ + +.. index:: + pair: Logical operators; Operators + +:: + + exp := exp op exp + exp := '!' exp + +Logical operators in Squirrel are : ``&&, ||, !`` + +The operator ``&&`` (logical and) returns null if its first argument is null, otherwise returns +its second argument. +The operator ``||`` (logical or) returns its first argument if is different than null, otherwise +returns the second argument. + +The '!' operator will return null if the given value to negate was different than null, or a +value different than null if the given value was null. + +^^^^^^^^^^^^^^^ +in operator +^^^^^^^^^^^^^^^ + +.. index:: + pair: in operator; Operators + +:: + + exp:= keyexp 'in' tableexp + +Tests the existence of a slot in a table. +Returns true if *keyexp* is a valid key in *tableexp* :: + + local t= + { + foo="I'm foo", + [123]="I'm not foo" + } + + if("foo" in t) dostuff("yep"); + if(123 in t) dostuff(); + +^^^^^^^^^^^^^^^^^^^ +instanceof operator +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: instanceof operator; Operators + +:: + + exp:= instanceexp 'instanceof' classexp + +Tests if a class instance is an instance of a certain class. +Returns true if *instanceexp* is an instance of *classexp*. + +^^^^^^^^^^^^^^^^^^^ +typeof operator +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: typeof operator; Operators + +:: + + exp:= 'typeof' exp + +returns the type name of a value as string.:: + + local a={},b="squirrel" + print(typeof a); //will print "table" + print(typeof b); //will print "string" + +^^^^^^^^^^^^^^^^^^^ +Comma operator +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: Comma operator; Operators + +:: + + exp:= exp ',' exp + +The comma operator evaluates two expression left to right, the result of the operator is +the result of the expression on the right; the result of the left expression is discarded.:: + + local j=0,k=0; + for(local i=0; i<10; i++ , j++) + { + k = i + j; + } + local a,k; + a = (k=1,k+2); //a becomes 3 + +^^^^^^^^^^^^^^^^^^^ +Bitwise Operators +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: Bitwise Operators; Operators + +:: + + exp:= 'exp' op 'exp' + exp := '~' exp + +Squirrel supports the standard C-like bitwise operators ``&, |, ^, ~, <<, >>`` plus the unsigned +right shift operator ``>>>``. The unsigned right shift works exactly like the normal right shift operator(``>>``) +except for treating the left operand as an unsigned integer, so is not affected by the sign. Those operators +only work on integer values; passing of any other operand type to these operators will +cause an exception. + +^^^^^^^^^^^^^^^^^^^^^ +Operators precedence +^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: Operators precedence; Operators + ++---------------------------------------+-----------+ +| ``-, ~, !, typeof , ++, --`` | highest | ++---------------------------------------+-----------+ +| ``/, *, %`` | ... | ++---------------------------------------+-----------+ +| ``+, -`` | | ++---------------------------------------+-----------+ +| ``<<, >>, >>>`` | | ++---------------------------------------+-----------+ +| ``<, <=, >, >=, instanceof`` | | ++---------------------------------------+-----------+ +| ``==, !=, <=>`` | | ++---------------------------------------+-----------+ +| ``&`` | | ++---------------------------------------+-----------+ +| ``^`` | | ++---------------------------------------+-----------+ +| ``&&, in`` | | ++---------------------------------------+-----------+ +| ``+=, =, -=, /=, *=, %=`` | ... | ++---------------------------------------+-----------+ +| ``, (comma operator)`` | lowest | ++---------------------------------------+-----------+ + +.. _table_contructor: + +----------------- +Table Constructor +----------------- + +.. index:: + single: Table Contructor + +:: + + tslots := ( 'id' '=' exp | '[' exp ']' '=' exp ) [','] + exp := '{' [tslots] '}' + +Creates a new table.:: + + local a = {} //create an empty table + +A table constructor can also contain slots declaration; With the syntax: :: + + local a = { + slot1 = "I'm the slot value" + } + +An alternative syntax can be:: + + '[' exp1 ']' = exp2 [','] + +A new slot with exp1 as key and exp2 as value is created:: + + local a= + { + [1]="I'm the value" + } + +Both syntaxes can be mixed:: + + local table= + { + a=10, + b="string", + [10]={}, + function bau(a,b) + { + return a+b; + } + } + +The comma between slots is optional. + +^^^^^^^^^^^^^^^^^^^^^^ +Table with JSON syntax +^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: Table with JSON syntax + +Since Squirrel 3.0 is possible to declare a table using JSON syntax(see http://www.wikipedia.org/wiki/JSON). + +the following JSON snippet: :: + + local x = { + "id": 1, + "name": "Foo", + "price": 123, + "tags": ["Bar","Eek"] + } + +is equivalent to the following squirrel code: :: + + local x = { + id = 1, + name = "Foo", + price = 123, + tags = ["Bar","Eek"] + } + +----------------- +clone +----------------- + +.. index:: + single: clone + +:: + + exp:= 'clone' exp + +Clone performs shallow copy of a table, array or class instance (copies all slots in the new object without +recursion). If the source table has a delegate, the same delegate will be assigned as +delegate (not copied) to the new table (see :ref:`Delegation `). + +After the new object is ready the "_cloned" meta method is called (see :ref:`Metamethods `). + +When a class instance is cloned the constructor is not invoked(initializations must rely on ```_cloned``` instead + +----------------- +Array contructor +----------------- + +.. index:: + single: Array constructor + +:: + + exp := '[' [explist] ']' + +Creates a new array.:: + + a <- [] //creates an empty array + +Arrays can be initialized with values during the construction:: + + a <- [1,"string!",[],{}] //creates an array with 4 elements diff --git a/vscript/squirrel/doc/source/reference/language/functions.rst b/vscript/squirrel/doc/source/reference/language/functions.rst new file mode 100644 index 00000000..f3f98c0b --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/functions.rst @@ -0,0 +1,272 @@ +.. _functions: + + +================= +Functions +================= + +.. index:: + single: Functions + +Functions are first class values like integer or strings and can be stored in table slots, +local variables, arrays and passed as function parameters. +Functions can be implemented in Squirrel or in a native language with calling conventions +compatible with ANSI C. + +-------------------- +Function declaration +-------------------- + +.. index:: + single: Function Declaration + +Functions are declared through the function expression:: + + local a = function(a, b, c) { return a + b - c; } + +or with the syntactic sugar:: + + function ciao(a,b,c) + { + return a+b-c; + } + +that is equivalent to:: + + this.ciao <- function(a,b,c) + { + return a+b-c; + } + +a local function can be declared with this syntactic sugar:: + + local function tuna(a,b,c) + { + return a+b-c; + } + +that is equivalent to:: + + local tuna = function(a,b,c) + { + return a+b-c; + } + +is also possible to declare something like:: + + T <- {} + function T::ciao(a,b,c) + { + return a+b-c; + } + + //that is equivalent to write + + T.ciao <- function(a,b,c) + { + return a+b-c; + } + + //or + + T <- { + function ciao(a,b,c) + { + return a+b-c; + } + } + +^^^^^^^^^^^^^^^^^^ +Default Paramaters +^^^^^^^^^^^^^^^^^^ + +.. index:: + single: Function Default Paramaters + +Squirrel's functions can have default parameters. + +A function with default parameters is declared as follows: :: + + function test(a,b,c = 10, d = 20) + { + .... + } + +when the function *test* is invoked and the parameter c or d are not specified, +the VM autometically assigns the default value to the unspecified parameter. A default parameter can be +any valid squirrel expression. The expression is evaluated at runtime. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Function with variable number of paramaters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: Function with variable number of paramaters + +Squirrel's functions can have variable number of parameters(varargs functions). + +A vararg function is declared by adding three dots (`...`) at the end of its parameter list. + +When the function is called all the extra parameters will be accessible through the *array* +called ``vargv``, that is passed as implicit parameter. + +``vargv`` is a regular squirrel array and can be used accordingly.:: + + function test(a,b,...) + { + for(local i = 0; i< vargv.len(); i++) + { + ::print("varparam "+i+" = "+vargv[i]+"\n"); + } + foreach(i,val in vargv) + { + ::print("varparam "+i+" = "+val+"\n"); + } + } + + test("goes in a","goes in b",0,1,2,3,4,5,6,7,8); + +--------------- +Function calls +--------------- + +.. index:: + single: Function calls + +:: + + exp:= derefexp '(' explist ')' + +The expression is evaluated in this order: derefexp after the explist (arguments) and at +the end the call. + +A function call in Squirrel passes the current environment object *this* as a hidden parameter. +But when the function was immediately indexed from an object, *this* shall be the object +which was indexed, instead. + +If we call a function with the syntax:: + + mytable.foo(x,y) + +the environment object passed to 'foo' as *this* will be 'mytable' (since 'foo' was immediately indexed from 'mytable') + +Whereas with the syntax:: + + foo(x,y) // implicitly equivalent to this.foo(x,y) + +the environment object will be the current *this* (that is, propagated from the caller's *this*). + +It may help to remember the rules in the following way: + + foo(x,y) ---> this.foo(x,y) + table.foo(x,y) ---> call foo with (table,x,y) + +It may also help to consider why it works this way: it's designed to assist with object-oriented style. +When calling 'foo(x,y)' it's assumed you're calling another member of the object (or of the file) and +so should operate on the same object. +When calling 'mytable.foo(x,y)' it's written plainly that you're calling a member of a different object. + +--------------------------------------------- +Binding an environment to a function +--------------------------------------------- + +.. index:: + single: Binding an environment to a function + +while by default a squirrel function call passes as environment object 'this', the object +where the function was indexed from. However, is also possible to statically bind an evironment to a +closure using the built-in method ``closure.bindenv(env_obj)``. +The method bindenv() returns a new instance of a closure with the environment bound to it. +When an environment object is bound to a function, every time the function is invoked, its +'this' parameter will always be the previously bound environent. +This mechanism is useful to implement callbacks systems similar to C# delegates. + +.. note:: The closure keeps a weak reference to the bound environmet object, because of this if + the object is deleted, the next call to the closure will result in a ``null`` + environment object. + +--------------------------------------------- +Lambda Expressions +--------------------------------------------- + +.. index:: + single: Lambda Expressions + +:: + + exp := '@' '(' paramlist ')' exp + +Lambda expressions are a syntactic sugar to quickly define a function that consists of a single expression. +This feature comes handy when functional programming patterns are applied, like map/reduce or passing a compare method to +array.sort(). + +here a lambda expression:: + + local myexp = @(a,b) a + b + +that is equivalent to:: + + local myexp = function(a,b) { return a + b; } + +a more useful usage could be:: + + local arr = [2,3,5,8,3,5,1,2,6]; + arr.sort(@(a,b) a <=> b); + arr.sort(@(a,b) -(a <=> b)); + +that could have been written as:: + + local arr = [2,3,5,8,3,5,1,2,6]; + arr.sort(function(a,b) { return a <=> b; } ); + arr.sort(function(a,b) { return -(a <=> b); } ); + +other than being limited to a single expression lambdas support all features of regular functions. +in fact are implemented as a compile time feature. + +--------------------------------------------- +Free Variables +--------------------------------------------- + +.. index:: + single: Free Variables + +A free variable is a variable external from the function scope as is not a local variable +or parameter of the function. +Free variables reference a local variable from a outer scope. +In the following example the variables 'testy', 'x' and 'y' are bound to the function 'foo'.:: + + local x=10,y=20 + local testy="I'm testy" + + function foo(a,b) + { + ::print(testy); + return a+b+x+y; + } + +A program can read or write a free variable. + +--------------------------------------------- +Tail Recursion +--------------------------------------------- + +.. index:: + single: Tail Recursion + +Tail recursion is a method for partially transforming a recursion in a program into an +iteration: it applies when the recursive calls in a function are the last executed +statements in that function (just before the return). +If this happenes the squirrel interpreter collapses the caller stack frame before the +recursive call; because of that very deep recursions are possible without risk of a stack +overflow.:: + + function loopy(n) + { + if(n>0){ + ::print("n="+n+"\n"); + return loopy(n-1); + } + } + + loopy(1000); + diff --git a/vscript/squirrel/doc/source/reference/language/generators.rst b/vscript/squirrel/doc/source/reference/language/generators.rst new file mode 100644 index 00000000..6c03de9a --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/generators.rst @@ -0,0 +1,51 @@ +.. _generators: + + +================= +Generators +================= + +.. index:: + single: Generators + +A function that contains a ``yield`` statement is called *'generator function'* . +When a generator function is called, it does not execute the function body, instead it +returns a new suspended generator. +The returned generator can be resumed through the resume statement while it is alive. +The yield keyword, suspends the execution of a generator and optionally returns the +result of an expression to the function that resumed the generator. +The generator dies when it returns, this can happen through an explicit return +statement or by exiting the function body; If an unhandled exception (or runtime error) +occurs while a generator is running, the generator will automatically die. A dead +generator cannot be resumed anymore.:: + + function geny(n) + { + for(local i=1;i<=n;i+=1) + yield i; + return null; + } + + local gtor=geny(10); + local x; + while(x=resume gtor) print(x+"\n"); + +the output of this program will be:: + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + +generators can also be iterated using the foreach statement. When a generator is evaluated +by ``foreach``, the generator will be resumed for each iteration until it returns. The value +returned by the ``return`` statement will be ignored. + +.. note:: A suspended generator will hold a strong reference to all the values stored in it's local variables except the ``this`` + object that is only a weak reference. A running generator hold a strong reference also to the ``this`` object. diff --git a/vscript/squirrel/doc/source/reference/language/lexical_structure.rst b/vscript/squirrel/doc/source/reference/language/lexical_structure.rst new file mode 100644 index 00000000..72e23f5c --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/lexical_structure.rst @@ -0,0 +1,154 @@ +.. _lexical_structure: + + +================= +Lexical Structure +================= + +.. index:: single: lexical structure + +----------- +Identifiers +----------- + +.. index:: single: identifiers + +Identifiers start with an alphabetic character or the symbol '_' followed by any number +of alphabetic characters, '_' or digits ([0-9]). Squirrel is a case sensitive language +meaning that the lowercase and uppercase representation of the same alphabetic +character are considered different characters. For instance, "foo", "Foo" and "fOo" are +treated as 3 distinct identifiers. + +----------- +Keywords +----------- + +.. index:: single: keywords + +The following words are reserved and cannot be used as identifiers: + ++------------+------------+-----------+------------+------------+-------------+ +| base | break | case | catch | class | clone | ++------------+------------+-----------+------------+------------+-------------+ +| continue | const | default | delete | else | enum | ++------------+------------+-----------+------------+------------+-------------+ +| extends | for | foreach | function | if | in | ++------------+------------+-----------+------------+------------+-------------+ +| local | null | resume | return | switch | this | ++------------+------------+-----------+------------+------------+-------------+ +| throw | try | typeof | while | yield | constructor | ++------------+------------+-----------+------------+------------+-------------+ +| instanceof | true | false | static | __LINE__ | __FILE__ | ++------------+------------+-----------+------------+------------+-------------+ + +Keywords are covered in detail later in this document. + +----------- +Operators +----------- + +.. index:: single: operators + +Squirrel recognizes the following operators: + ++----------+----------+----------+----------+----------+----------+----------+----------+ +| ``!`` | ``!=`` | ``||`` | ``==`` | ``&&`` | ``>=`` | ``<=`` | ``>`` | ++----------+----------+----------+----------+----------+----------+----------+----------+ +| ``<=>`` | ``+`` | ``+=`` | ``-`` | ``-=`` | ``/`` | ``/=`` | ``*`` | ++----------+----------+----------+----------+----------+----------+----------+----------+ +| ``*=`` | ``%`` | ``%=`` | ``++`` | ``--`` | ``<-`` | ``=`` | ``&`` | ++----------+----------+----------+----------+----------+----------+----------+----------+ +| ``^`` | ``|`` | ``~`` | ``>>`` | ``<<`` | ``>>>`` | | | ++----------+----------+----------+----------+----------+----------+----------+----------+ + +------------ +Other tokens +------------ + +.. index:: + single: delimiters + single: other tokens + +Other significant tokens are: + ++----------+----------+----------+----------+----------+----------+ +| ``{`` | ``}`` | ``[`` | ``]`` | ``.`` | ``:`` | ++----------+----------+----------+----------+----------+----------+ +| ``::`` | ``'`` | ``;`` | ``"`` | ``@"`` | | ++----------+----------+----------+----------+----------+----------+ + +----------- +Literals +----------- + +.. index:: + single: literals + single: string literals + single: numeric literals + +Squirrel accepts integer numbers, floating point numbers and string literals. + ++-------------------------------+------------------------------------------+ +| ``34`` | Integer number(base 10) | ++-------------------------------+------------------------------------------+ +| ``0xFF00A120`` | Integer number(base 16) | ++-------------------------------+------------------------------------------+ +| ``0753`` | Integer number(base 8) | ++-------------------------------+------------------------------------------+ +| ``'a'`` | Integer number | ++-------------------------------+------------------------------------------+ +| ``1.52`` | Floating point number | ++-------------------------------+------------------------------------------+ +| ``1.e2`` | Floating point number | ++-------------------------------+------------------------------------------+ +| ``1.e-2`` | Floating point number | ++-------------------------------+------------------------------------------+ +| ``"I'm a string"`` | String | ++-------------------------------+------------------------------------------+ +| ``@"I'm a verbatim string"`` | String | ++-------------------------------+------------------------------------------+ +| ``@" I'm a`` | | +| ``multiline verbatim string`` | | +| ``"`` | String | ++-------------------------------+------------------------------------------+ + +Pesudo BNF + +.. productionlist:: + IntegerLiteral : [1-9][0-9]* | '0x' [0-9A-Fa-f]+ | ''' [.]+ ''' | 0[0-7]+ + FloatLiteral : [0-9]+ '.' [0-9]+ + FloatLiteral : [0-9]+ '.' 'e'|'E' '+'|'-' [0-9]+ + StringLiteral: '"'[.]* '"' + VerbatimStringLiteral: '@''"'[.]* '"' + +----------- +Comments +----------- + +.. index:: single: comments + +A comment is text that the compiler ignores but that is useful for programmers. +Comments are normally used to embed annotations in the code. The compiler +treats them as white space. + +A comment can be ``/*`` (slash, asterisk) characters, followed by any +sequence of characters (including new lines), +followed by the ``*/`` characters. This syntax is the same as ANSI C.:: + + /* + this is + a multiline comment. + this lines will be ignored by the compiler + */ + +A comment can also be ``//`` (two slashes) characters, followed by any sequence of +characters. A new line not immediately preceded by a backslash terminates this form of +comment. It is commonly called a *"single-line comment."*:: + + //this is a single line comment. this line will be ignored by the compiler + +The character ``#`` is an alternative syntax for single line comment.:: + + # this is also a single line comment. + +This to facilitate the use of squirrel in UNIX-style shell scripts. diff --git a/vscript/squirrel/doc/source/reference/language/metamethods.rst b/vscript/squirrel/doc/source/reference/language/metamethods.rst new file mode 100644 index 00000000..260b0308 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/metamethods.rst @@ -0,0 +1,270 @@ +.. _metamethods: + +----------- +Metamethods +----------- + +Metamethods are a mechanism that allows the customization of certain aspects of the +language semantics. Those methods are normal functions placed in a table +parent(delegate) or class declaration; It is possible to change many aspects of a table/class instance behavior by just defining +a metamethod. Class objects (not instances) support only 2 metamethods ``_newmember, _inherited`` . + +For example when we use relational operators other than '==' on 2 tables, the VM will +check if the table has a method in his parent called '_cmp'; if so it will call it to determine +the relation between the tables.:: + + local comparable={ + _cmp = function (other) + { + if(nameother.name)return 1; + return 0; + } + } + + local a={ name="Alberto" }.setdelegate(comparable); + local b={ name="Wouter" }.setdelegate(comparable); + + if(a>b) + print("a>b") + else + print("b<=a"); + +for classes the previous code become: :: + + class Comparable { + constructor(n) + { + name = n; + } + function _cmp(other) + { + if(nameother.name) return 1; + return 0; + } + name = null; + } + + local a = Comparable("Alberto"); + local b = Comparable("Wouter"); + + if(a>b) + print("a>b") + else + print("b<=a"); + +^^^^^ +_set +^^^^^ + +:: + + _set(idx,val) + +invoked when the index idx is not present in the object or in its delegate chain. +``_set`` must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure). +This allows the program to differentiate between a runtime error and a 'index not found'. + +^^^^^ +_get +^^^^^ + +:: + + _get(idx) + +invoked when the index idx is not present in the object or in its delegate chain. +_get must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure). +This allows the program to differentiate between a runtime error and a 'index not found'. + +^^^^^^^^^ +_newslot +^^^^^^^^^ + +:: + + _newslot(key,value) + +invoked when a script tries to add a new slot in a table. + +if the slot already exists in the target table the method will not be invoked also if the +"new slot" operator is used. + +^^^^^^^^^ +_delslot +^^^^^^^^^ + +:: + + _delslot(key) + +invoked when a script deletes a slot from a table. +if the method is invoked squirrel will not try to delete the slot himself + +^^^^^^^^ +_add +^^^^^^^^ + +:: + + _add(other) + +the + operator + +returns this + other + +^^^^^^^^^^^^^^^^^^^^^^^^ +_sub +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _sub(other) + +the - operator (like _add) + +^^^^^^^^^^^^^^^^^^^^^^^^ +_mul +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _mul(other) + +the ``*`` operator (like _add) + +^^^^^^^^^^^^^^^^^^^^^^^^ +_div +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _div(other) + +the ``/`` operator (like _add) + +^^^^^^^^^^^^^^^^^^^^^^^^ +_modulo +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _modulo(other) + +the ``%`` operator (like _add) + +^^^^^^^^^ +_unm +^^^^^^^^^ + +:: + + _unm() + +the unary minus operator + +^^^^^^^^^^^^^^^^^^^^^^^^ +_typeof +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _typeof() + +invoked by the typeof operator on tables, userdata, and class instances. + +Returns the type of ``this`` as string + +^^^^^^^^^^^^^^^^^^^^^^^^ +_cmp +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _cmp(other) + +invoked to emulate the ``< > <= >=`` and ``<=>`` operators + +returns an integer as follow: + ++-----------+----------------------------+ +| returns | relationship | ++===========+============================+ +| > 0 | if ``this`` > ``other`` | ++-----------+----------------------------+ +| 0 | if ``this`` == ``other`` | ++-----------+----------------------------+ +| < 0 | if ``this`` < ``other`` | ++-----------+----------------------------+ + +^^^^^^^^^^^^^^^^^^^^^^^^ +_call +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _call(other) + +invoked when a table, userdata, or class instance is called + +^^^^^^^^^^^^^^^^^^^^^^^^ +_cloned +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _cloned(original) + +invoked when a table or class instance is cloned(in the cloned table) + +^^^^^^^^^^^^^^^^^^^^^^^^ +_nexti +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _nexti(previdx) + +invoked when a userdata or class instance is iterated by a foreach loop. + +If previdx==null it means that it is the first iteration. +The function has to return the index of the 'next' value. + +^^^^^^^^^^^^^^^^^^^^^^^^ +_tostring +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _tostring() + +Invoked when during string concatenation or when the ``print`` function prints a table, instance, or userdata. +The method is also invoked by the sq_tostring() API. + +Must return a string representation of the object. + +^^^^^^^^^^^^^^^^^^^^^^^^ +_inherited +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _inherited(attributes) + +invoked when a class object inherits from the class implementing ``_inherited``. +The ``this`` contains the new class. + +Return value is ignored. + +^^^^^^^^^^^^^^^^^^^^^^^^ +_newmember +^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + _newmember(index,value,attributes,isstatic) + +invoked for each member declared in a class body (at declaration time). + +If the function is implemented, members will not be added to the class. diff --git a/vscript/squirrel/doc/source/reference/language/statements.rst b/vscript/squirrel/doc/source/reference/language/statements.rst new file mode 100644 index 00000000..febde526 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/statements.rst @@ -0,0 +1,386 @@ +.. _statements: + + +================= +Statements +================= + +.. index:: + single: statements + +A squirrel program is a simple sequence of statements.:: + + stats := stat [';'|'\n'] stats + +Statements in squirrel are comparable to the C-Family languages (C/C++, Java, C# +etc...): assignment, function calls, program flow control structures etc.. plus some +custom statement like yield, table and array constructors (All those will be covered in detail +later in this document). +Statements can be separated with a new line or ';' (or with the keywords case or default if +inside a switch/case statement), both symbols are not required if the statement is +followed by '}'. + +------ +Block +------ + +.. index:: + pair: block; statement + +:: + + stat := '{' stats '}' + +A sequence of statements delimited by curly brackets ({ }) is called block; +a block is a statement itself. + +----------------------- +Control Flow Statements +----------------------- + +.. index:: + single: control flow statements + +squirrel implements the most common control flow statements: ``if, while, do-while, switch-case, for, foreach`` + +^^^^^^^^^^^^^^ +true and false +^^^^^^^^^^^^^^ + +.. index:: + single: true and false + single: true + single: false + +Squirrel has a boolean type (bool) however like C++ it considers null, 0(integer) and 0.0(float) +as *false*, any other value is considered *true*. + +^^^^^^^^^^^^^^^^^ +if/else statement +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: if/else; statement + pair: if; statement + pair: else; statement + +:: + + stat:= 'if' '(' exp ')' stat ['else' stat] + +Conditionally execute a statement depending on the result of an expression.:: + + if(a>b) + a=b; + else + b=a; + //// + if(a==10) + { + b=a+b; + return a; + } + +^^^^^^^^^^^^^^^^^ +while statement +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: while; statement + +:: + + stat:= 'while' '(' exp ')' stat + +Executes a statement while the condition is true.:: + + function testy(n) + { + local a=0; + while(a100) + +^^^^^^^^^^^^^^^^^ +switch statement +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: switch; statement + +:: + + stat := 'switch' ''( exp ')' '{' + 'case' case_exp ':' + stats + ['default' ':' + stats] + '}' + +Switch is a control statement allows multiple selections of code by passing control to one of the +case statements within its body. +The control is transferred to the case label whose case_exp matches with exp if none of +the case match will jump to the default label (if present). +A switch statement can contain any number if case instances, if 2 case have the same +expression result the first one will be taken in account first. The default label is only +allowed once and must be the last one. +A break statement will jump outside the switch block. + +----- +Loops +----- + +.. index:: + single: Loops + +^^^^^^^^ +for +^^^^^^^^ + +.. index:: + pair: for; statement + +:: + + stat:= 'for' '(' [initexp] ';' [condexp] ';' [incexp] ')' statement + +Executes a statement as long as a condition is different than false.:: + + for(local a=0;a<10;a+=1) + print(a+"\n"); + //or + glob <- null + for(glob=0;glob<10;glob+=1){ + print(glob+"\n"); + } + //or + for(;;){ + print(loops forever+"\n"); + } + +^^^^^^^^ +foreach +^^^^^^^^ + +.. index:: + pair: foreach; statement + +:: + + 'foreach' '(' [index_id','] value_id 'in' exp ')' stat + +Executes a statement for every element contained in an array, table, class, string or generator. +If exp is a generator it will be resumed every iteration as long as it is alive; the value will +be the result of 'resume' and the index the sequence number of the iteration starting +from 0.:: + + local a=[10,23,33,41,589,56] + foreach(idx,val in a) + print("index="+idx+" value="+val+"\n"); + //or + foreach(val in a) + print("value="+val+"\n"); + +------- +break +------- + +.. index:: + pair: break; statement + +:: + + stat := 'break' + +The break statement terminates the execution of a loop (for, foreach, while or do/while) +or jumps out of switch statement; + +--------- +continue +--------- + +.. index:: + pair: continue; statement + +:: + + stat := 'continue' + +The continue operator jumps to the next iteration of the loop skipping the execution of +the following statements. + +--------- +return +--------- + +.. index:: + pair: return; statement + +:: + + stat:= return [exp] + +The return statement terminates the execution of the current function/generator and +optionally returns the result of an expression. If the expression is omitted the function +will return null. If the return statement is used inside a generator, the generator will not +be resumable anymore. + +--------- +yield +--------- + +.. index:: + pair: yield; statement + +:: + + stat := yield [exp] + +(see :ref:`Generators `). + + +--------------------------- +Local variables declaration +--------------------------- + +.. index:: + pair: Local variables declaration; statement + +:: + + initz := id [= exp][',' initz] + stat := 'local' initz + +Local variables can be declared at any point in the program; they exist between their +declaration to the end of the block where they have been declared. +*EXCEPTION:* a local declaration statement is allowed as first expression in a for loop.:: + + for(local a=0;a<10;a+=1) + print(a); + +-------------------- +Function declaration +-------------------- + +.. index:: + pair: Function declaration; statement + +:: + + funcname := id ['::' id] + stat:= 'function' id ['::' id]+ '(' args ')' stat + +creates a new function. + +----------------- +Class declaration +----------------- + +.. index:: + pair: Class declaration; statement + +:: + + memberdecl := id '=' exp [';'] | '[' exp ']' '=' exp [';'] | functionstat | 'constructor' functionexp + stat:= 'class' derefexp ['extends' derefexp] '{' + [memberdecl] + '}' + +creates a new class. + +----------- +try/catch +----------- + +.. index:: + pair: try/catch; statement + +:: + + stat:= 'try' stat 'catch' '(' id ')' stat + +The try statement encloses a block of code in which an exceptional condition can occur, +such as a runtime error or a throw statement. The catch clause provides the exception-handling +code. When a catch clause catches an exception, its id is bound to that +exception. + +----------- +throw +----------- + +.. index:: + pair: throw; statement + +:: + + stat:= 'throw' exp + +Throws an exception. Any value can be thrown. + +-------------- +const +-------------- + +.. index:: + pair: const; statement + +:: + + stat:= 'const' id '=' 'Integer | Float | StringLiteral + +Declares a constant (see :ref:`Constants & Enumerations `). + +-------------- +enum +-------------- + +.. index:: + pair: enum; statement + +:: + + enumerations := ( 'id' '=' Integer | Float | StringLiteral ) [','] + stat:= 'enum' id '{' enumerations '}' + +Declares an enumeration (see :ref:`Constants & Enumerations `). + +-------------------- +Expression statement +-------------------- + +.. index:: + pair: Expression statement; statement + +:: + + stat := exp + +In Squirrel every expression is also allowed as statement, if so, the result of the +expression is thrown away. + diff --git a/vscript/squirrel/doc/source/reference/language/tables.rst b/vscript/squirrel/doc/source/reference/language/tables.rst new file mode 100644 index 00000000..eb80a688 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/tables.rst @@ -0,0 +1,71 @@ +.. _tables: + + +================= +Tables +================= + +.. index:: + single: Tables + +Tables are associative containers implemented as pairs of key/value (called slot); values +can be any possible type and keys any type except 'null'. +Tables are squirrel's skeleton, delegation and many other features are all implemented +through this type; even the environment, where "global" variables are stored, is a table +(known as root table). + +------------------ +Construction +------------------ + +Tables are created through the table constructor (see :ref:`Table constructor `) + +------------------ +Slot creation +------------------ + +.. index:: + single: Slot Creation(table) + +Adding a new slot in a existing table is done through the "new slot" operator ``<-``; this +operator behaves like a normal assignment except that if the slot does not exists it will +be created.:: + + local a = {} + +The following line will cause an exception because the slot named 'newslot' does not exist +in the table 'a':: + + a.newslot = 1234 + +this will succeed: :: + + a.newslot <- 1234; + +or:: + + a[1] <- "I'm the value of the new slot"; + +----------------- +Slot deletion +----------------- + +.. index:: + single: Slot Deletion(table) + + +:: + + exp:= delete derefexp + +Deletion of a slot is done through the keyword delete; the result of this expression will be +the value of the deleted slot.:: + + a <- { + test1=1234 + deleteme="now" + } + + delete a.test1 + print(delete a.deleteme); //this will print the string "now" + diff --git a/vscript/squirrel/doc/source/reference/language/threads.rst b/vscript/squirrel/doc/source/reference/language/threads.rst new file mode 100644 index 00000000..efe114ab --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/threads.rst @@ -0,0 +1,106 @@ +.. _threads: + + +======================== +Threads +======================== + +.. index:: + single: Threads + +Squirrel supports cooperative threads(also known as coroutines). +A cooperative thread is a subroutine that can suspended in mid-execution and provide a value to the +caller without returning program flow, then its execution can be resumed later from the same +point where it was suspended. +At first look a Squirrel thread can be confused with a generator, in fact their behaviour is quite similar. +However while a generator runs in the caller stack and can suspend only the local routine stack a thread +has its own execution stack, global table and error handler; This allows a thread to suspend nested calls and +have it's own error policies. + +------------------ +Using threads +------------------ + +.. index:: + single: Using Threads + +Threads are created through the built-in function 'newthread(func)'; this function +gets as parameter a squirrel function and bind it to the new thread objects (will be the thread body). +The returned thread object is initially in 'idle' state. the thread can be started with the function +'threadobj.call()'; the parameters passed to 'call' are passed to the thread function. + +A thread can be be suspended calling the function suspend(), when this happens the function +that wokeup(or started) the thread returns (If a parameter is passed to suspend() it will +be the return value of the wakeup function , if no parameter is passed the return value will be null). +A suspended thread can be resumed calling the function 'threadobj.wakeup', when this happens +the function that suspended the thread will return(if a parameter is passed to wakeup it will +be the return value of the suspend function, if no parameter is passed the return value will be null). + +A thread terminates when its main function returns or when an unhandled exception occurs during its execution.:: + + function coroutine_test(a,b) + { + ::print(a+" "+b+"\n"); + local ret = ::suspend("suspend 1"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 2"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 3"); + ::print("the coroutine says "+ret+"\n"); + return "I'm done" + } + + local coro = ::newthread(coroutine_test); + + local susparam = coro.call("test","coroutine"); //starts the coroutine + + local i = 1; + do + { + ::print("suspend passed ("+susparam+")\n") + susparam = coro.wakeup("ciao "+i); + ++i; + }while(coro.getstatus()=="suspended") + + ::print("return passed ("+susparam+")\n") + +the result of this program will be:: + + test coroutine + suspend passed (suspend 1) + the coroutine says ciao 1 + suspend passed (suspend 2) + the coroutine says ciao 2 + suspend passed (suspend 3) + the coroutine says ciao 3 + return passed (I'm done). + + +the following is an interesting example of how threads and tail recursion +can be combined.:: + + function state1() + { + ::suspend("state1"); + return state2(); //tail call + } + + function state2() + { + ::suspend("state2"); + return state3(); //tail call + } + + function state3() + { + ::suspend("state3"); + return state1(); //tail call + } + + local statethread = ::newthread(state1) + + ::print(statethread.call()+"\n"); + + for(local i = 0; i < 10000; i++) + ::print(statethread.wakeup()+"\n"); + diff --git a/vscript/squirrel/doc/source/reference/language/weak_references.rst b/vscript/squirrel/doc/source/reference/language/weak_references.rst new file mode 100644 index 00000000..5f87bc82 --- /dev/null +++ b/vscript/squirrel/doc/source/reference/language/weak_references.rst @@ -0,0 +1,61 @@ +.. _weak_references: + + +======================== +Weak References +======================== + +.. index:: + single: Weak References + + +The weak references allows the programmers to create references to objects without +influencing the lifetime of the object itself. +In squirrel Weak references are first-class objects created through the built-in method obj.weakref(). +All types except null implement the weakref() method; however in bools, integers, and floats the method +simply returns the object itself(this because this types are always passed by value). +When a weak references is assigned to a container (table slot,array,class or +instance) is treated differently than other objects; When a container slot that hold a weak +reference is fetched, it always returns the value pointed by the weak reference instead of the weak +reference object. This allow the programmer to ignore the fact that the value handled is weak. +When the object pointed by weak reference is destroyed, the weak reference is automatically set to null.:: + + local t = {} + local a = ["first","second","third"] + //creates a weakref to the array and assigns it to a table slot + t.thearray <- a.weakref(); + +The table slot 'thearray' contains a weak reference to an array. +The following line prints "first", because tables(and all other containers) always return +the object pointed by a weak ref:: + + print(t.thearray[0]); + +the only strong reference to the array is owned by the local variable 'a', so +because the following line assigns a integer to 'a' the array is destroyed.:: + + a = 123; + +When an object pointed by a weak ref is destroyed the weak ref is automatically set to null, +so the following line will print "null".:: + + ::print(typeof(t.thearray)) + +----------------------------------- +Handling weak references explicitly +----------------------------------- + +If a weak reference is assigned to a local variable, then is treated as any other value.:: + + local t = {} + local weakobj = t.weakref(); + +the following line prints "weakref".:: + + ::print(typeof(weakobj)) + +the object pointed by the weakref can be obtained through the built-in method weakref.ref(). + +The following line prints "table".:: + + ::print(typeof(weakobj.ref())) diff --git a/vscript/squirrel/doc/source/stdlib/index.rst b/vscript/squirrel/doc/source/stdlib/index.rst new file mode 100644 index 00000000..7137bdb5 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/index.rst @@ -0,0 +1,39 @@ +.. _stdlib: + +################################# + Squirrel Standard Library 3.1 +################################# + +Copyright (c) 2003-2016 Alberto Demichelis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +.. toctree:: + :maxdepth: 1 + :numbered: + + introduction.rst + stdiolib.rst + stdbloblib.rst + stdmathlib.rst + stdsystemlib.rst + stdstringlib.rst + stdauxlib.rst + diff --git a/vscript/squirrel/doc/source/stdlib/introduction.rst b/vscript/squirrel/doc/source/stdlib/introduction.rst new file mode 100644 index 00000000..171e2425 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/introduction.rst @@ -0,0 +1,22 @@ +.. _stdlib_introduction: + +============ +Introduction +============ + +The squirrel standard libraries consist in a set of modules implemented in C++. +While are not essential for the language, they provide a set of useful services that are +commonly used by a wide range of applications(file I/O, regular expressions, etc...), +plus they offer a foundation for developing additional libraries. + +All libraries are implemented through the squirrel API and the ANSI C runtime library. +The modules are organized in the following way: + +* I/O : input and output +* blob : binary buffers manipilation +* math : basic mathematical routines +* system : system access function +* string : string formatting and manipulation +* aux : auxiliary functions + +The libraries can be registered independently,except for the IO library that depends from the bloblib. diff --git a/vscript/squirrel/doc/source/stdlib/stdauxlib.rst b/vscript/squirrel/doc/source/stdlib/stdauxlib.rst new file mode 100644 index 00000000..b800c100 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdauxlib.rst @@ -0,0 +1,31 @@ +.. _stdlib_stdauxlib: + +=============== +The Aux library +=============== + +The aux library implements default handlers for compiler and runtime errors and a stack dumping. + ++++++++++++ +C API ++++++++++++ + +.. _sqstd_seterrorhandlers: + +.. c:function:: void sqstd_seterrorhandlers(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + + initialize compiler and runtime error handlers, the handlers + use the print function set through(:ref:`sq_setprintfunc `) to output + the error. + +.. _sqstd_printcallstack: + +.. c:function:: void sqstd_printcallstack(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + + prints the call stack and stack contents. the function + uses the print function set through(:ref:`sq_setprintfunc `) to output + the stack dump. diff --git a/vscript/squirrel/doc/source/stdlib/stdbloblib.rst b/vscript/squirrel/doc/source/stdlib/stdbloblib.rst new file mode 100644 index 00000000..83d34264 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdbloblib.rst @@ -0,0 +1,213 @@ +.. _stdlib_stdbloblib: + +================== +The Blob library +================== +The blob library implements binary data manipulations routines. The library is +based on `blob objects` that represent a buffer of arbitrary +binary data. + +--------------- +Squirrel API +--------------- + ++++++++++++++++ +Global symbols ++++++++++++++++ + +.. js:function:: castf2i(f) + + casts a float to a int + +.. js:function:: casti2f(n) + + casts a int to a float + +.. js:function:: swap2(n) + + swap the byte order of a number (like it would be a 16bits integer) + +.. js:function:: swap4(n) + + swap the byte order of an integer + +.. js:function:: swapfloat(n) + + swaps the byteorder of a float + +++++++++++++++++++ +The blob class +++++++++++++++++++ + +The blob object is a buffer of arbitrary binary data. The object behaves like +a file stream, it has a read/write pointer and it automatically grows if data +is written out of his boundary. +A blob can also be accessed byte by byte through the `[]` operator. + +.. js:class:: blob(size) + + :param int size: initial size of the blob + + returns a new instance of a blob class of the specified size in bytes + +.. js:function:: blob.eos() + + returns a non null value if the read/write pointer is at the end of the stream. + +.. js:function:: blob.flush() + + flushes the stream.return a value != null if succeded, otherwise returns null + +.. js:function:: blob.len() + + returns the length of the stream + +.. js:function:: blob.readblob(size) + + :param int size: number of bytes to read + + read n bytes from the stream and returns them as blob + +.. js:function:: blob.readn(type) + + :param int type: type of the number to read + + reads a number from the stream according to the type parameter. + + `type` can have the following values: + ++--------------+--------------------------------------------------------------------------------+----------------------+ +| parameter | return description | return type | ++==============+================================================================================+======================+ +| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits processors | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'i' | 32bits number | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 's' | 16bits signed integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'w' | 16bits unsigned integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'c' | 8bits signed integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'b' | 8bits unsigned integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'f' | 32bits float | float | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'd' | 64bits float | float | ++--------------+--------------------------------------------------------------------------------+----------------------+ + +.. js:function:: blob.resize(size) + + :param int size: the new size of the blob in bytes + + resizes the blob to the specified `size` + +.. js:function:: blob.seek(offset [,origin]) + + :param int offset: indicates the number of bytes from `origin`. + :param int origin: origin of the seek + + +--------------+-------------------------------------------+ + | 'b' | beginning of the stream | + +--------------+-------------------------------------------+ + | 'c' | current location | + +--------------+-------------------------------------------+ + | 'e' | end of the stream | + +--------------+-------------------------------------------+ + + Moves the read/write pointer to a specified location. + +.. note:: If origin is omitted the parameter is defaulted as 'b'(beginning of the stream). + +.. js:function:: blob.swap2() + + swaps the byte order of the blob content as it would be an array of `16bits integers` + +.. js:function:: blob.swap4() + + swaps the byte order of the blob content as it would be an array of `32bits integers` + +.. js:function:: blob.tell() + + returns the read/write pointer absolute position + +.. js:function:: blob.writeblob(src) + + :param blob src: the source blob containing the data to be written + + writes a blob in the stream + +.. js:function:: blob.writen(n, type) + + :param number n: the value to be written + :param int type: type of the number to write + + writes a number in the stream formatted according to the `type` parameter + + `type` can have the following values: + ++--------------+--------------------------------------------------------------------------------+ +| parameter | return description | ++==============+================================================================================+ +| 'i' | 32bits number | ++--------------+--------------------------------------------------------------------------------+ +| 's' | 16bits signed integer | ++--------------+--------------------------------------------------------------------------------+ +| 'w' | 16bits unsigned integer | ++--------------+--------------------------------------------------------------------------------+ +| 'c' | 8bits signed integer | ++--------------+--------------------------------------------------------------------------------+ +| 'b' | 8bits unsigned integer | ++--------------+--------------------------------------------------------------------------------+ +| 'f' | 32bits float | ++--------------+--------------------------------------------------------------------------------+ +| 'd' | 64bits float | ++--------------+--------------------------------------------------------------------------------+ + + +------ +C API +------ + +.. _sqstd_register_bloblib: + +.. c:function:: SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: an SQRESULT + :remarks: The function aspects a table on top of the stack where to register the global library functions. + + initializes and registers the blob library in the given VM. + +.. _sqstd_getblob: + +.. c:function:: SQRESULT sqstd_getblob(HSQUIRRELVM v, SQInteger idx, SQUserPointer* ptr) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: and index in the stack + :param SQUserPointer* ptr: A pointer to the userpointer that will point to the blob's payload + :returns: an SQRESULT + + retrieve the pointer of a blob's payload from an arbitrary + position in the stack. + +.. _sqstd_getblobsize: + +.. c:function:: SQInteger sqstd_getblobsize(HSQUIRRELVM v, SQInteger idx) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: and index in the stack + :returns: the size of the blob at `idx` position + + retrieves the size of a blob's payload from an arbitrary + position in the stack. + +.. _sqstd_createblob: + +.. c:function:: SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) + + :param HSQUIRRELVM v: the target VM + :param SQInteger size: the size of the blob payload that has to be created + :returns: a pointer to the newly created blob payload + + creates a blob with the given payload size and pushes it in the stack. diff --git a/vscript/squirrel/doc/source/stdlib/stdiolib.rst b/vscript/squirrel/doc/source/stdlib/stdiolib.rst new file mode 100644 index 00000000..c7de168e --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdiolib.rst @@ -0,0 +1,264 @@ +.. _stdlib_stdiolib: + +======================== +The Input/Output library +======================== + +the i/o library implements basic input/output routines. + +-------------- +Squirrel API +-------------- + +++++++++++++++ +Global Symbols +++++++++++++++ + + +.. js:function:: dofile(path, [raiseerror]) + + compiles a squirrel script or loads a precompiled one and executes it. + returns the value returned by the script or null if no value is returned. + if the optional parameter 'raiseerror' is true, the compiler error handler is invoked + in case of a syntax error. If raiseerror is omitted or set to false, the compiler + error handler is not invoked. + When squirrel is compiled in Unicode mode the function can handle different character encodings, + UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian). + If the source stream is not prefixed UTF8 encoding is used as default. + +.. js:function:: loadfile(path, [raiseerror]) + + compiles a squirrel script or loads a precompiled one an returns it as as function. + if the optional parameter 'raiseerror' is true, the compiler error handler is invoked + in case of a syntax error. If raiseerror is omitted or set to false, the compiler + error handler is not invoked. + When squirrel is compiled in Unicode mode the function can handle different character encodings, + UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian). + If the source stream is not prefixed UTF8 encoding is used as default. + +.. js:function:: writeclosuretofile(destpath, closure) + + serializes a closure to a bytecode file (destpath). The serialized file can be loaded + using loadfile() and dofile(). + + +.. js:data:: stderr + + File object bound on the os *standard error* stream + +.. js:data:: stdin + + File object bound on the os *standard input* stream + +.. js:data:: stdout + + File object bound on the os *standard output* stream + + +++++++++++++++ +The file class +++++++++++++++ + + The file object implements a stream on a operating system file. + +.. js:class:: file(path, patten) + + It's constructor imitates the behaviour of the C runtime function fopen for eg. :: + + local myfile = file("test.xxx","wb+"); + + creates a file with read/write access in the current directory. + +.. js:function:: file.close() + + closes the file. + +.. js:function:: file.eos() + + returns a non null value if the read/write pointer is at the end of the stream. + +.. js:function:: file.flush() + + flushes the stream.return a value != null if succeeded, otherwise returns null + +.. js:function:: file.len() + + returns the length of the stream + +.. js:function:: file.readblob(size) + + :param int size: number of bytes to read + + read n bytes from the stream and returns them as blob + +.. js:function:: file.readn(type) + + :param int type: type of the number to read + + reads a number from the stream according to the type parameter. + + `type` can have the following values: + ++--------------+--------------------------------------------------------------------------------+----------------------+ +| parameter | return description | return type | ++==============+================================================================================+======================+ +| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits processors | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'i' | 32bits number | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 's' | 16bits signed integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'w' | 16bits unsigned integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'c' | 8bits signed integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'b' | 8bits unsigned integer | integer | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'f' | 32bits float | float | ++--------------+--------------------------------------------------------------------------------+----------------------+ +| 'd' | 64bits float | float | ++--------------+--------------------------------------------------------------------------------+----------------------+ + +.. js:function:: file.resize(size) + + :param int size: the new size of the blob in bytes + + resizes the blob to the specified `size` + +.. js:function:: file.seek(offset [,origin]) + + :param int offset: indicates the number of bytes from `origin`. + :param int origin: origin of the seek + + +--------------+-------------------------------------------+ + | 'b' | beginning of the stream | + +--------------+-------------------------------------------+ + | 'c' | current location | + +--------------+-------------------------------------------+ + | 'e' | end of the stream | + +--------------+-------------------------------------------+ + + Moves the read/write pointer to a specified location. + +.. note:: If origin is omitted the parameter is defaulted as 'b'(beginning of the stream). + +.. js:function:: file.tell() + + returns the read/write pointer absolute position + +.. js:function:: file.writeblob(src) + + :param blob src: the source blob containing the data to be written + + writes a blob in the stream + +.. js:function:: file.writen(n, type) + + :param number n: the value to be written + :param int type: type of the number to write + + writes a number in the stream formatted according to the `type` pamraeter + + `type` can have the following values: + ++--------------+--------------------------------------------------------------------------------+ +| parameter | return description | ++==============+================================================================================+ +| 'i' | 32bits number | ++--------------+--------------------------------------------------------------------------------+ +| 's' | 16bits signed integer | ++--------------+--------------------------------------------------------------------------------+ +| 'w' | 16bits unsigned integer | ++--------------+--------------------------------------------------------------------------------+ +| 'c' | 8bits signed integer | ++--------------+--------------------------------------------------------------------------------+ +| 'b' | 8bits unsigned integer | ++--------------+--------------------------------------------------------------------------------+ +| 'f' | 32bits float | ++--------------+--------------------------------------------------------------------------------+ +| 'd' | 64bits float | ++--------------+--------------------------------------------------------------------------------+ + + +-------------- +C API +-------------- + +.. _sqstd_register_iolib: + +.. c:function:: SQRESULT sqstd_register_iolib(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: an SQRESULT + :remarks: The function aspects a table on top of the stack where to register the global library functions. + + initialize and register the io library in the given VM. + +++++++++++++++ +File Object +++++++++++++++ + +.. c:function:: SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file, SQBool owns) + + :param HSQUIRRELVM v: the target VM + :param SQFILE file: the stream that will be rapresented by the file object + :param SQBool owns: if different true the stream will be automatically closed when the newly create file object is destroyed. + :returns: an SQRESULT + + creates a file object bound to the SQFILE passed as parameter + and pushes it in the stack + +.. c:function:: SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE* file) + + :param HSQUIRRELVM v: the target VM + :param SQInteger idx: and index in the stack + :param SQFILE* file: A pointer to a SQFILE handle that will store the result + :returns: an SQRESULT + + retrieve the pointer of a stream handle from an arbitrary + position in the stack. + +++++++++++++++++++++++++++++++++ +Script loading and serialization +++++++++++++++++++++++++++++++++ + +.. c:function:: SQRESULT sqstd_loadfile(HSQUIRRELVM v, const SQChar* filename, SQBool printerror) + + :param HSQUIRRELVM v: the target VM + :param SQChar* filename: path of the script that has to be loaded + :param SQBool printerror: if true the compiler error handler will be called if a error occurs + :returns: an SQRESULT + + Compiles a squirrel script or loads a precompiled one an pushes it as closure in the stack. + When squirrel is compiled in Unicode mode the function can handle different character encodings, + UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian). + If the source stream is not prefixed UTF8 encoding is used as default. + +.. c:function:: SQRESULT sqstd_dofile(HSQUIRRELVM v, const SQChar* filename, SQBool retval, SQBool printerror) + + :param HSQUIRRELVM v: the target VM + :param SQChar* filename: path of the script that has to be loaded + :param SQBool retval: if true the function will push the return value of the executed script in the stack. + :param SQBool printerror: if true the compiler error handler will be called if a error occurs + :returns: an SQRESULT + :remarks: the function expects a table on top of the stack that will be used as 'this' for the execution of the script. The 'this' parameter is left untouched in the stack. + + Compiles a squirrel script or loads a precompiled one and executes it. + Optionally pushes the return value of the executed script in the stack. + When squirrel is compiled in unicode mode the function can handle different character encodings, + UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian). + If the source stream is not prefixed, UTF8 encoding is used as default. :: + + sq_pushroottable(v); //push the root table(were the globals of the script will are stored) + sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue);// also prints syntax errors if any + +.. c:function:: SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v, const SQChar* filename) + + :param HSQUIRRELVM v: the target VM + :param SQChar* filename: destination path of serialized closure + :returns: an SQRESULT + + serializes the closure at the top position in the stack as bytecode in + the file specified by the parameter filename. If a file with the + same name already exists, it will be overwritten. + diff --git a/vscript/squirrel/doc/source/stdlib/stdmathlib.rst b/vscript/squirrel/doc/source/stdlib/stdmathlib.rst new file mode 100644 index 00000000..5f0b8b49 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdmathlib.rst @@ -0,0 +1,111 @@ +.. _stdlib_stdmathlib: + +================ +The Math library +================ + +the math lib provides basic mathematic routines. The library mimics the +C runtime library implementation. + +------------ +Squirrel API +------------ + ++++++++++++++++ +Global Symbols ++++++++++++++++ + +.. js:function:: abs(x) + + returns the absolute value of `x` as an integer + +.. js:function:: acos(x) + + returns the arccosine of `x` + +.. js:function:: asin(x) + + returns the arcsine of `x` + +.. js:function:: atan(x) + + returns the arctangent of `x` + +.. js:function:: atan2(x,y) + + returns the arctangent of `x/y` + +.. js:function:: ceil(x) + + returns a float value representing the smallest integer that is greater than or equal to `x` + +.. js:function:: cos(x) + + returns the cosine of `x` + +.. js:function:: exp(x) + + returns the exponential value of the float parameter `x` + +.. js:function:: fabs(x) + + returns the absolute value of `x` as a float + +.. js:function:: floor(x) + + returns a float value representing the largest integer that is less than or equal to `x` + +.. js:function:: log(x) + + returns the natural logarithm of `x` + +.. js:function:: log10(x) + + returns the logarithm base-10 of `x` + +.. js:function:: pow(x,y) + + returns `x` raised to the power of `y` + +.. js:function:: rand() + + returns a pseudorandom integer in the range 0 to `RAND_MAX` + +.. js:function:: sin(x) + + rreturns the sine of `x` + +.. js:function:: sqrt(x) + + returns the square root of `x` + +.. js:function:: srand(seed) + + sets the starting point for generating a series of pseudorandom integers + +.. js:function:: tan(x) + + returns the tangent of `x` + +.. js:data:: RAND_MAX + + the maximum value that can be returned by the `rand()` function + +.. js:data:: PI + + The numeric constant pi (3.141592) is the ratio of the circumference of a circle to its diameter + +------------ +C API +------------ + +.. _sqstd_register_mathlib: + +.. c:function:: SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: an SQRESULT + :remarks: The function aspects a table on top of the stack where to register the global library functions. + + initializes and register the math library in the given VM. + diff --git a/vscript/squirrel/doc/source/stdlib/stdstringlib.rst b/vscript/squirrel/doc/source/stdlib/stdstringlib.rst new file mode 100644 index 00000000..dd929346 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdstringlib.rst @@ -0,0 +1,323 @@ +.. _stdlib_stdstringlib: + +================== +The String library +================== + +the string lib implements string formatting and regular expression matching routines. + +-------------- +Squirrel API +-------------- + +++++++++++++++ +Global Symbols +++++++++++++++ + +.. js:function:: endswith(str, cmp) + + returns `true` if the end of the string `str` matches a the string `cmp` otherwise returns `false` + +.. js:function:: escape(str) + + Returns a string with backslashes before characters that need to be escaped(`\",\a,\b,\t,\n,\v,\f,\r,\\,\",\',\0,\xnn`). + +.. js:function:: format(formatstr, ...) + + Returns a string formatted according `formatstr` and the optional parameters following it. + The format string follows the same rules as the `printf` family of + standard C functions( the "*" is not supported). :: + + e.g. + sq> print(format("%s %d 0x%02X\n","this is a test :",123,10)); + this is a test : 123 0x0A + +.. js:function:: printf(formatstr, ...) + + Just like calling `print(format(formatstr` as in the example above, but is more convenient AND more efficient. :: + + e.g. + sq> printf("%s %d 0x%02X\n","this is a test :",123,10); + this is a test : 123 0x0A + +.. js:function:: lstrip(str) + + Strips white-space-only characters that might appear at the beginning of the given string + and returns the new stripped string. + +.. js:function:: rstrip(str) + + Strips white-space-only characters that might appear at the end of the given string + and returns the new stripped string. + +.. js:function:: split(str, separators [, skipempty]) + + returns an array of strings split at each point where a separator character occurs in `str`. + The separator is not returned as part of any array element. + The parameter `separators` is a string that specifies the characters as to be used for the splitting. + The parameter `skipempty` is a boolean (default false). If `skipempty` is true, empty strings are not added to array. + + :: + + eg. + local a = split("1.2-3;;4/5",".-/;"); + // the result will be [1,2,3,,4,5] + or + local b = split("1.2-3;;4/5",".-/;",true); + // the result will be [1,2,3,4,5] + + +.. js:function:: startswith(str, cmp) + + returns `true` if the beginning of the string `str` matches the string `cmp`; otherwise returns `false` + +.. js:function:: strip(str) + + Strips white-space-only characters that might appear at the beginning or end of the given string and returns the new stripped string. + +++++++++++++++++++ +The regexp class +++++++++++++++++++ + +.. js:class:: regexp(pattern) + + The regexp object represents a precompiled regular expression pattern. The object is created + through `regexp(pattern)`. + + ++---------------------+--------------------------------------+ +| `\\` | Quote the next metacharacter | ++---------------------+--------------------------------------+ +| `^` | Match the beginning of the string | ++---------------------+--------------------------------------+ +| `.` | Match any character | ++---------------------+--------------------------------------+ +| `$` | Match the end of the string | ++---------------------+--------------------------------------+ +| `|` | Alternation | ++---------------------+--------------------------------------+ +| `(subexp)` | Grouping (creates a capture) | ++---------------------+--------------------------------------+ +| `(?:subexp)` | No Capture Grouping (no capture) | ++---------------------+--------------------------------------+ +| `[]` | Character class | ++---------------------+--------------------------------------+ + +**GREEDY CLOSURES** + ++---------------------+---------------------------------------------+ +| `*` | Match 0 or more times | ++---------------------+---------------------------------------------+ +| `+` | Match 1 or more times | ++---------------------+---------------------------------------------+ +| `?` | Match 1 or 0 times | ++---------------------+---------------------------------------------+ +| `{n}` | Match exactly n times | ++---------------------+---------------------------------------------+ +| `{n,}` | Match at least n times | ++---------------------+---------------------------------------------+ +| `{n,m}` | Match at least n but not more than m times | ++---------------------+---------------------------------------------+ + +**ESCAPE CHARACTERS** + ++---------------------+--------------------------------------+ +| `\\t` | tab (HT, TAB) | ++---------------------+--------------------------------------+ +| `\\n` | newline (LF, NL) | ++---------------------+--------------------------------------+ +| `\\r` | return (CR) | ++---------------------+--------------------------------------+ +| `\\f` | form feed (FF) | ++---------------------+--------------------------------------+ + +**PREDEFINED CLASSES** + ++---------------------+--------------------------------------+ +| `\\l` | lowercase next char | ++---------------------+--------------------------------------+ +| `\\u` | uppercase next char | ++---------------------+--------------------------------------+ +| `\\a` | letters | ++---------------------+--------------------------------------+ +| `\\A` | non letters | ++---------------------+--------------------------------------+ +| `\\w` | alphanumeric `[_0-9a-zA-Z]` | ++---------------------+--------------------------------------+ +| `\\W` | non alphanumeric `[^_0-9a-zA-Z]` | ++---------------------+--------------------------------------+ +| `\\s` | space | ++---------------------+--------------------------------------+ +| `\\S` | non space | ++---------------------+--------------------------------------+ +| `\\d` | digits | ++---------------------+--------------------------------------+ +| `\\D` | non digits | ++---------------------+--------------------------------------+ +| `\\x` | hexadecimal digits | ++---------------------+--------------------------------------+ +| `\\X` | non hexadecimal digits | ++---------------------+--------------------------------------+ +| `\\c` | control characters | ++---------------------+--------------------------------------+ +| `\\C` | non control characters | ++---------------------+--------------------------------------+ +| `\\p` | punctuation | ++---------------------+--------------------------------------+ +| `\\P` | non punctuation | ++---------------------+--------------------------------------+ +| `\\b` | word boundary | ++---------------------+--------------------------------------+ +| `\\B` | non word boundary | ++---------------------+--------------------------------------+ + + +.. js:function:: regexp.capture(str [, start]) + + returns an array of tables containing two indexes ("begin" and "end") of + the first match of the regular expression in the string `str`. + An array entry is created for each captured sub expressions. If no match occurs returns null. + The search starts from the index `start` + of the string; if `start` is omitted the search starts from the beginning of the string. + + The first element of the returned array(index 0) always contains the complete match. + + :: + + local ex = regexp(@"(\d+) ([a-zA-Z]+)(\p)"); + local string = "stuff 123 Test;"; + local res = ex.capture(string); + foreach(i,val in res) + { + print(format("match number[%02d] %s\n", + i,string.slice(val.begin,val.end))); //prints "Test" + } + + ... + will print + match number[00] 123 Test; + match number[01] 123 + match number[02] Test + match number[03] ; + +.. js:function:: regexp.match(str) + + returns a true if the regular expression matches the string + `str`, otherwise returns false. + +.. js:function:: regexp.search(str [, start]) + + returns a table containing two indexes ("begin" and "end") of the first match of the regular expression in + the string `str`, otherwise if no match occurs returns null. The search starts from the index `start` + of the string; if `start` is omitted the search starts from the beginning of the string. + + :: + + local ex = regexp("[a-zA-Z]+"); + local string = "123 Test;"; + local res = ex.search(string); + print(string.slice(res.begin,res.end)); //prints "Test" + +------------- +C API +------------- + +.. _sqstd_register_stringlib: + +.. c:function:: SQRESULT sqstd_register_stringlib(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: an SQRESULT + :remarks: The function aspects a table on top of the stack where to register the global library functions. + + initialize and register the string library in the given VM. + ++++++++++++++ +Formatting ++++++++++++++ + +.. c:function:: SQRESULT sqstd_format(HSQUIRRELVM v, SQInteger nformatstringidx, SQInteger* outlen, SQChar** output) + + :param HSQUIRRELVM v: the target VM + :param SQInteger nformatstringidx: index in the stack of the format string + :param SQInteger* outlen: a pointer to an integer that will be filled with the length of the newly created string + :param SQChar** output: a pointer to a string pointer that will receive the newly created string + :returns: an SQRESULT + :remarks: the newly created string is allocated in the scratchpad memory. + + + creates a new string formatted according to the object at position `nformatstringidx` and the optional parameters following it. + The format string follows the same rules as the `printf` family of + standard C functions( the "*" is not supported). + +++++++++++++++++++ +Regular Expessions +++++++++++++++++++ + +.. c:function:: SQRex* sqstd_rex_compile(const SQChar *pattern, const SQChar ** error) + + :param SQChar* pattern: a pointer to a zero terminated string containing the pattern that has to be compiled. + :param SQChar** error: a pointer to a string pointer that will be set with an error string in case of failure. + :returns: a pointer to the compiled pattern + + compiles an expression and returns a pointer to the compiled version. + in case of failure returns NULL.The returned object has to be deleted + through the function sqstd_rex_free(). + +.. c:function:: void sqstd_rex_free(SQRex * exp) + + :param SQRex* exp: the expression structure that has to be deleted. + + deletes a expression structure created with sqstd_rex_compile() + +.. c:function:: SQBool sqstd_rex_match(SQRex * exp,const SQChar * text) + + :param SQRex* exp: a compiled expression + :param SQChar* text: the string that has to be tested + :returns: SQTrue if successful otherwise SQFalse + + returns SQTrue if the string specified in the parameter text is an + exact match of the expression, otherwise returns SQFalse. + +.. c:function:: SQBool sqstd_rex_search(SQRex * exp, const SQChar * text, const SQChar ** out_begin, const SQChar ** out_end) + + :param SQRex* exp: a compiled expression + :param SQChar* text: the string that has to be tested + :param SQChar** out_begin: a pointer to a string pointer that will be set with the beginning of the match + :param SQChar** out_end: a pointer to a string pointer that will be set with the end of the match + :returns: SQTrue if successful otherwise SQFalse + + searches the first match of the expression in the string specified in the parameter text. + if the match is found returns SQTrue and the sets out_begin to the beginning of the + match and out_end at the end of the match; otherwise returns SQFalse. + +.. c:function:: SQBool sqstd_rex_searchrange(SQRex * exp, const SQChar * text_begin, const SQChar * text_end, const SQChar ** out_begin, const SQChar ** out_end) + + :param SQRex* exp: a compiled expression + :param SQChar* text_begin: a pointer to the beginnning of the string that has to be tested + :param SQChar* text_end: a pointer to the end of the string that has to be tested + :param SQChar** out_begin: a pointer to a string pointer that will be set with the beginning of the match + :param SQChar** out_end: a pointer to a string pointer that will be set with the end of the match + :returns: SQTrue if successful otherwise SQFalse + + searches the first match of the expression in the string delimited + by the parameter text_begin and text_end. + if the match is found returns SQTrue and sets out_begin to the beginning of the + match and out_end at the end of the match; otherwise returns SQFalse. + +.. c:function:: SQInteger sqstd_rex_getsubexpcount(SQRex * exp) + + :param SQRex* exp: a compiled expression + :returns: the number of sub expressions matched by the expression + + returns the number of sub expressions matched by the expression + +.. c:function:: SQBool sqstd_rex_getsubexp(SQRex * exp, SQInteger n, SQRexMatch *subexp) + + :param SQRex* exp: a compiled expression + :param SQInteger n: the index of the submatch(0 is the complete match) + :param SQRexMatch* a: pointer to structure that will store the result + :returns: the function returns SQTrue if n is a valid index; otherwise SQFalse. + + retrieve the begin and and pointer to the length of the sub expression indexed + by n. The result is passed through the struct SQRexMatch. diff --git a/vscript/squirrel/doc/source/stdlib/stdsystemlib.rst b/vscript/squirrel/doc/source/stdlib/stdsystemlib.rst new file mode 100644 index 00000000..5c565fd6 --- /dev/null +++ b/vscript/squirrel/doc/source/stdlib/stdsystemlib.rst @@ -0,0 +1,82 @@ +.. _stdlib_stdsystemlib: + +================== +The System library +================== + +The system library exposes operating system facilities like environment variables, +date time manipulation etc.. + +-------------- +Squirrel API +-------------- + +++++++++++++++ +Global Symbols +++++++++++++++ + +.. js:function:: clock() + + returns a float representing the number of seconds elapsed since the start of the process + +.. js:function:: date([time [, format]]) + + returns a table containing a date/time split into the slots: + ++-------------+----------------------------------------+ +| sec | Seconds after minute (0 - 59). | ++-------------+----------------------------------------+ +| min | Minutes after hour (0 - 59). | ++-------------+----------------------------------------+ +| hour | Hours since midnight (0 - 23). | ++-------------+----------------------------------------+ +| day | Day of month (1 - 31). | ++-------------+----------------------------------------+ +| month | Month (0 - 11; January = 0). | ++-------------+----------------------------------------+ +| year | Year (current year). | ++-------------+----------------------------------------+ +| wday | Day of week (0 - 6; Sunday = 0). | ++-------------+----------------------------------------+ +| yday | Day of year (0 - 365; January 1 = 0). | ++-------------+----------------------------------------+ + +if `time` is omitted the current time is used. + +if `format` can be 'l' local time or 'u' UTC time, if omitted is defaulted as 'l'(local time). + +.. js:function:: getenv(varaname) + + Returns a string containing the value of the environment variable `varname` + +.. js:function:: remove(path) + + deletes the file specified by `path` + +.. js:function:: rename(oldname, newname) + + renames the file or directory specified by `oldname` to the name given by `newname` + +.. js:function:: system(cmd) + + xecutes the string `cmd` through the os command interpreter. + +.. js:function:: time() + + returns the number of seconds elapsed since midnight 00:00:00, January 1, 1970. + + the result of this function can be formatted through the function `date()` + +-------------- +C API +-------------- + +.. _sqstd_register_systemlib: + +.. c:function:: SQRESULT sqstd_register_systemlib(HSQUIRRELVM v) + + :param HSQUIRRELVM v: the target VM + :returns: an SQRESULT + :remarks: The function aspects a table on top of the stack where to register the global library functions. + + initialize and register the system library in the given VM. diff --git a/vscript/squirrel/etc/minimal.c b/vscript/squirrel/etc/minimal.c new file mode 100644 index 00000000..0695768b --- /dev/null +++ b/vscript/squirrel/etc/minimal.c @@ -0,0 +1,78 @@ +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +#pragma comment (lib ,"squirrel.lib") +#pragma comment (lib ,"sqstdlib.lib") +#endif + +#ifdef SQUNICODE + +#define scvprintf vfwprintf +#else + +#define scvprintf vfprintf +#endif + +void printfunc(HSQUIRRELVM v,const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf(stdout, s, vl); + va_end(vl); +} + +void errorfunc(HSQUIRRELVM v,const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf(stderr, s, vl); + va_end(vl); +} + +void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) +{ + SQInteger top = sq_gettop(v); //saves the stack size before the call + sq_pushroottable(v); //pushes the global table + sq_pushstring(v,_SC("foo"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table + sq_pushroottable(v); //push the 'this' (in this case is the global table) + sq_pushinteger(v,n); + sq_pushfloat(v,f); + sq_pushstring(v,s,-1); + sq_call(v,4,SQFalse,SQTrue); //calls the function + } + sq_settop(v,top); //restores the original stack size +} + +int main(int argc, char* argv[]) +{ + HSQUIRRELVM v; + v = sq_open(1024); // creates a VM with initial stack size 1024 + + //REGISTRATION OF STDLIB + //sq_pushroottable(v); //push the root table where the std function will be registered + //sqstd_register_iolib(v); //registers a library + // ... call here other stdlibs string,math etc... + //sq_pop(v,1); //pops the root table + //END REGISTRATION OF STDLIB + + sqstd_seterrorhandlers(v); //registers the default error handlers + + sq_setprintfunc(v, printfunc,errorfunc); //sets the print function + + sq_pushroottable(v); //push the root table(were the globals of the script will be stored) + if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any + { + call_foo(v,1,2.5,_SC("teststring")); + } + + sq_pop(v,1); //pops the root table + sq_close(v); + + return 0; +} diff --git a/vscript/squirrel/etc/test.nut b/vscript/squirrel/etc/test.nut new file mode 100644 index 00000000..125df32c --- /dev/null +++ b/vscript/squirrel/etc/test.nut @@ -0,0 +1,4 @@ +function foo(i, f, s) +{ + print("Called foo(), i="+i+", f="+f+", s='"+s+"'\n"); +} diff --git a/vscript/squirrel/include/sqconfig.h b/vscript/squirrel/include/sqconfig.h new file mode 100644 index 00000000..58bc9793 --- /dev/null +++ b/vscript/squirrel/include/sqconfig.h @@ -0,0 +1,146 @@ + +#ifdef _SQ64 + +#ifdef _MSC_VER +typedef __int64 SQInteger; +typedef unsigned __int64 SQUnsignedInteger; +typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ +#else +typedef long long SQInteger; +typedef unsigned long long SQUnsignedInteger; +typedef unsigned long long SQHash; /*should be the same size of a pointer*/ +#endif +typedef int SQInt32; +typedef unsigned int SQUnsignedInteger32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + + +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else +typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + +#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. +#if defined(SQUSEDOUBLE) || defined(_SQ64) +#define SQ_ALIGNMENT 8 +#else +#define SQ_ALIGNMENT 4 +#endif +#endif + +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#ifdef SQUNICODE +#include +#include + + +typedef wchar_t SQChar; + + +#define scstrcmp wcscmp +#ifdef _WIN32 +#define scsprintf _snwprintf +#else +#define scsprintf swprintf +#endif +#define scstrlen wcslen +#define scstrtod wcstod +#ifdef _SQ64 +#define scstrtol wcstoll +#else +#define scstrtol wcstol +#endif +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scprintf wprintf + +#ifdef _WIN32 +#define WCHAR_SIZE 2 +#define WCHAR_SHIFT_MUL 1 +#define MAX_CHAR 0xFFFF +#else +#define WCHAR_SIZE 4 +#define WCHAR_SHIFT_MUL 2 +#define MAX_CHAR 0xFFFFFFFF +#endif + +#define _SC(a) L##a + + +#define scisspace iswspace +#define scisdigit iswdigit +#define scisprint iswprint +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum + + +#define sq_rsl(l) ((l)<=0) + +#ifdef __GNUC__ +# define SQ_UNUSED_ARG(x) x __attribute__((__unused__)) +#else +# define SQ_UNUSED_ARG(x) x +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/vscript/squirrel/samples/ackermann.nut b/vscript/squirrel/samples/ackermann.nut new file mode 100644 index 00000000..8b18ec21 --- /dev/null +++ b/vscript/squirrel/samples/ackermann.nut @@ -0,0 +1,23 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ + +function Ack(M, N) { + if (M == 0) return( N + 1 ); + if (N == 0) return( Ack(M - 1, 1) ); + return( Ack(M - 1, Ack(M, (N - 1))) ); +} + +local n; + +if(vargv.len()!=0) { + n = vargv[0].tointeger(); + if(n < 1) n = 1; +} else { + n = 1; +} +print("n="+n+"\n"); +print("Ack(3,"+ n+ "):"+ Ack(3, n)); + diff --git a/vscript/squirrel/samples/array.nut b/vscript/squirrel/samples/array.nut new file mode 100644 index 00000000..0102d62f --- /dev/null +++ b/vscript/squirrel/samples/array.nut @@ -0,0 +1,29 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ +local n, i, k; + +if(vargv.len()!=0) { + n = vargv[0].tointeger(); + if(n < 1) n = 1; +} else { + n = 1; +} + +local x = []; x.resize(n); +local y = []; y.resize(n); + +for (i = 0; i < n; i+=1) { + x[i] = i + 1; + y[i] = 0; +} + +for (k = 0 ; k < n; k+=1) { + for (i = n-1; i >= 0; i-=1) { + y[i] = y[i]+ x[i]; + } +} +print(y[0].tostring()+" "+y[n-1]); + diff --git a/vscript/squirrel/samples/class.nut b/vscript/squirrel/samples/class.nut new file mode 100644 index 00000000..2d924602 --- /dev/null +++ b/vscript/squirrel/samples/class.nut @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +class BaseVector { + constructor(...) + { + if(vargv.len() >= 3) { + x = vargv[0]; + y = vargv[1]; + z = vargv[2]; + } + } + + + x = 0; + y = 0; + z = 0; +} + +class Vector3 extends BaseVector { + function _add(other) + { + if(other instanceof this.getclass()) + return ::Vector3(x+other.x,y+other.y,z+other.z); + else + throw "wrong parameter"; + } + function Print() + { + ::print(x+","+y+","+z+"\n"); + } +} + +local v0 = Vector3(1,2,3) +local v1 = Vector3(11,12,13) +local v2 = v0 + v1; +v2.Print(); + +FakeNamespace <- { + Utils = {} +} + +class FakeNamespace.Utils.SuperClass { + constructor() + { + ::print("FakeNamespace.Utils.SuperClass") + } +} + +local testy = FakeNamespace.Utils.SuperClass(); diff --git a/vscript/squirrel/samples/classattributes.nut b/vscript/squirrel/samples/classattributes.nut new file mode 100644 index 00000000..4d2d078d --- /dev/null +++ b/vscript/squirrel/samples/classattributes.nut @@ -0,0 +1,35 @@ +class Foo { + //constructor + constructor(a) + { + testy = ["stuff",1,2,3]; + } + //attributes of PrintTesty + + function PrintTesty() + { + foreach(i,val in testy) + { + ::print("idx = "+i+" = "+val+" \n"); + } + } + //attributes of testy + + testy = null; + +} + +foreach(member,val in Foo) +{ + ::print(member+"\n"); + local attr; + if((attr = Foo.getattributes(member)) != null) { + foreach(i,v in attr) + { + ::print("\t"+i+" = "+(typeof v)+"\n"); + } + } + else { + ::print("\t\n") + } +} diff --git a/vscript/squirrel/samples/coroutines.nut b/vscript/squirrel/samples/coroutines.nut new file mode 100644 index 00000000..0cc19920 --- /dev/null +++ b/vscript/squirrel/samples/coroutines.nut @@ -0,0 +1,25 @@ +function coroutine_test(a,b) +{ + ::print(a+" "+b+"\n"); + local ret = ::suspend("suspend 1"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 2"); + ::print("the coroutine says "+ret+"\n"); + ret = ::suspend("suspend 3"); + ::print("the coroutine says "+ret+"\n"); + return "I'm done" +} + +local coro = ::newthread(coroutine_test); + +local susparam = coro.call("test","coroutine"); //starts the coroutine + +local i = 1; +do +{ + ::print("suspend passed ["+susparam+"]\n") + susparam = coro.wakeup("ciao "+i); + ++i; +}while(coro.getstatus()=="suspended") + +::print("return passed ["+susparam+"]\n") diff --git a/vscript/squirrel/samples/delegation.nut b/vscript/squirrel/samples/delegation.nut new file mode 100644 index 00000000..9f208dc4 --- /dev/null +++ b/vscript/squirrel/samples/delegation.nut @@ -0,0 +1,54 @@ + +PEntity <- { + name="noname" + pos={x=0,y=0,z=0} + type="entity" + //methamethod + _typeof=function() + { + return type; + } +} + +function PEntity::PrintPos() +{ + ::print("x="+pos.x+" y="+pos.y+" z="+pos.z+"\n"); +} + +function PEntity::new(name,pos) +{ + local newentity=clone ::PEntity; + if(name) + newentity.name=name; + if(pos) + newentity.pos=pos; + return newentity; +} + +PPlayer <- { + model="warrior.mdl" + weapon="fist" + health=100 + armor=0 + //overrides the parent type + type="player" +} + +function PPlayer::new(name,pos) +{ + local p = clone ::PPlayer; + local newplayer = ::PEntity.new(name,pos); + newplayer.setdelegate(p); + return newplayer; +} + +local player=PPlayer.new("godzilla",{x=10,y=20,z=30}); + +::print("PLAYER NAME"+player.name+"\n"); +::print("ENTITY TYPE"+typeof player+"\n"); + +player.PrintPos(); + +player.pos.x=123; + +player.PrintPos(); diff --git a/vscript/squirrel/samples/fibonacci.nut b/vscript/squirrel/samples/fibonacci.nut new file mode 100644 index 00000000..c722d1a1 --- /dev/null +++ b/vscript/squirrel/samples/fibonacci.nut @@ -0,0 +1,15 @@ +/* +* +* Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) +* +*/ + +function fib(n) +{ + if (n < 2) return 1 + return fib(n-2) + fib(n-1) +} + +local n = vargv.len()!=0?vargv[0].tointeger():1 + +print(fib(n)+"\n") diff --git a/vscript/squirrel/samples/flow.nut b/vscript/squirrel/samples/flow.nut new file mode 100644 index 00000000..635bc89f --- /dev/null +++ b/vscript/squirrel/samples/flow.nut @@ -0,0 +1,33 @@ +function min(x,y) + return xy?x:y; + +if(min(100,200)>max(50,20)) + print("I'm useless statement just to show up the if/else\n"); +else + print("squirrel!!\n"); + +print("\n") + +function typy(obj) +{ + switch(typeof obj) + { + case "integer": + case "float": + return "is a number"; + case "table": + case "array": + return "is a container"; + default: + return "is other stuff" + } +} + +local a=1,b={},c=function(a,b){return a+b;} + +print("a "+typy(a)+"\n"); +print("b "+typy(b)+"\n"); +print("c "+typy(c)+"\n"); diff --git a/vscript/squirrel/samples/generators.nut b/vscript/squirrel/samples/generators.nut new file mode 100644 index 00000000..eb5eef6b --- /dev/null +++ b/vscript/squirrel/samples/generators.nut @@ -0,0 +1,42 @@ +/* +*Random number function from The Great Computer Language shootout +*converted to a generator func +*/ + +function gen_random(max) { + local last=42 + local IM = 139968; + local IA = 3877; + local IC = 29573; + for(;;){ //loops forever + yield (max * (last = (last * IA + IC) % IM) / IM); + } +} + +local randtor=gen_random(100); + +print("RAND NUMBERS \n") + +for(local i=0;i<10;i+=1) + print(">"+resume randtor+"\n"); + +print("FIBONACCI \n") +function fiboz(n) +{ + local prev=0; + local curr=1; + yield 1; + + for(local i=0;i"+val+"\n"); +} diff --git a/vscript/squirrel/samples/hello.nut b/vscript/squirrel/samples/hello.nut new file mode 100644 index 00000000..f301245e --- /dev/null +++ b/vscript/squirrel/samples/hello.nut @@ -0,0 +1 @@ +print("Hello World!") diff --git a/vscript/squirrel/samples/list.nut b/vscript/squirrel/samples/list.nut new file mode 100644 index 00000000..e7cc2218 --- /dev/null +++ b/vscript/squirrel/samples/list.nut @@ -0,0 +1,40 @@ +/*translation of the list test from The Great Computer Language Shootout +*/ + +function compare_arr(a1,a2) +{ + foreach(i,val in a1) + if(val!=a2[i])return null; + return 1; +} + +function test() +{ + local size=10000 + local l1=[]; l1.resize(size); + for(local i=0;i0) + l3.append(l2.pop()); + while(l3.len()>0) + l2.append(l3.pop()); + l1.reverse(); + + if(compare_arr(l1,l2)) + return l1.len(); + return null; +} + +local n = vargv.len()!=0?vargv[0].tointeger():1 +for(local i=0;i\n"); +else + print("\n"); diff --git a/vscript/squirrel/samples/methcall.nut b/vscript/squirrel/samples/methcall.nut new file mode 100644 index 00000000..73bb2e84 --- /dev/null +++ b/vscript/squirrel/samples/methcall.nut @@ -0,0 +1,68 @@ +/*translation of the methcall test from The Great Computer Language Shootout +*/ + +class Toggle { + bool=null +} + +function Toggle::constructor(startstate) { + bool = startstate +} + +function Toggle::value() { + return bool; +} + +function Toggle::activate() { + bool = !bool; + return this; +} + +class NthToggle extends Toggle { + count_max=null + count=0 +} + +function NthToggle::constructor(start_state,max_counter) +{ + base.constructor(start_state); + count_max = max_counter +} + +function NthToggle::activate () +{ + ++count; + if (count >= count_max ) { + base.activate(); + count = 0; + } + return this; +} + + +function main() { + local n = vargv.len()!=0?vargv[0].tointeger():1 + + + + local val = 1; + local toggle = Toggle(val); + local i = n; + while(i--) { + val = toggle.activate().value(); + + } + print(toggle.value() ? "true\n" : "false\n"); + + val = 1; + local ntoggle = NthToggle(val, 3); + i = n; + while(i--) { + val = ntoggle.activate().value(); + } + print(ntoggle.value() ? "true\n" : "false\n"); + +} +local start=clock(); +main(); +print("TIME="+(clock()-start)+"\n"); diff --git a/vscript/squirrel/samples/regex.nut b/vscript/squirrel/samples/regex.nut new file mode 100644 index 00000000..fcd8e59e --- /dev/null +++ b/vscript/squirrel/samples/regex.nut @@ -0,0 +1,10 @@ +local ex = regexp("[a-zA-Z]+"); +local string = "123 Test; strlen(str);"; +local res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "Test" +print("\n"); +ex = regexp(@"\m()"); +string = "123 Test; doSomething(str, getTemp(), (a+(b/c)));"; +res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "(...)" +print("\n"); diff --git a/vscript/squirrel/samples/tailstate.nut b/vscript/squirrel/samples/tailstate.nut new file mode 100644 index 00000000..7ea06c69 --- /dev/null +++ b/vscript/squirrel/samples/tailstate.nut @@ -0,0 +1,24 @@ +function state1() +{ + ::suspend("state1"); + return state2(); +} + +function state2() +{ + ::suspend("state2"); + return state3(); +} + +function state3() +{ + ::suspend("state3"); + return state1(); +} + +local statethread = ::newthread(state1) + +::print(statethread.call()+"\n"); + +for(local i = 0; i < 10000; i++) + ::print(statethread.wakeup()+"\n"); diff --git a/vscript/squirrel/sq/CMakeLists.txt b/vscript/squirrel/sq/CMakeLists.txt new file mode 100644 index 00000000..bdea07d0 --- /dev/null +++ b/vscript/squirrel/sq/CMakeLists.txt @@ -0,0 +1,38 @@ +set(CMAKE_C_STANDARD 99) +if(NOT DISABLE_DYNAMIC) + add_executable(sq sq.c) + add_executable(squirrel::interpreter ALIAS sq) + set_target_properties(sq PROPERTIES LINKER_LANGUAGE C EXPORT_NAME interpreter) + target_link_libraries(sq squirrel sqstdlib) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS sq EXPORT squirrel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) + endif() + target_include_directories(sq PUBLIC + "$" + "$" + ) +endif() + +if(NOT DISABLE_STATIC) + add_executable(sq_static sq.c) + add_executable(squirrel::interpreter_static ALIAS sq) + set_target_properties(sq_static PROPERTIES LINKER_LANGUAGE C EXPORT_NAME interpreter_static) + target_link_libraries(sq_static squirrel_static sqstdlib_static) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS sq_static EXPORT squirrel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) + endif() + target_include_directories(sq_static PUBLIC + "$" + "$" + ) +endif() + +if(LONG_OUTPUT_NAMES) + if(NOT DISABLE_DYNAMIC) + set_target_properties(sq PROPERTIES OUTPUT_NAME squirrel3) + endif() + + if(NOT DISABLE_STATIC) + set_target_properties(sq_static PROPERTIES OUTPUT_NAME squirrel3_static) + endif() +endif() diff --git a/vscript/squirrel/sq/Makefile b/vscript/squirrel/sq/Makefile new file mode 100644 index 00000000..948fd1ea --- /dev/null +++ b/vscript/squirrel/sq/Makefile @@ -0,0 +1,21 @@ +SQUIRREL= .. + + +OUT= $(SQUIRREL)/bin/sq +INCZ= -I$(SQUIRREL)/include -I. -I$(SQUIRREL)/sqlibs +LIBZ= -L$(SQUIRREL)/lib +LIB= -lsquirrel -lsqstdlib + +OBJS= sq.o + +SRCS= sq.c + + +sq32: + g++ -O2 -fno-exceptions -fno-rtti -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) + +sqprof: + g++ -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) + +sq64: + g++ -O2 -m64 -fno-exceptions -fno-rtti -D_SQ64 -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) diff --git a/vscript/squirrel/sq/sq.c b/vscript/squirrel/sq/sq.c new file mode 100644 index 00000000..ee5eabbb --- /dev/null +++ b/vscript/squirrel/sq/sq.c @@ -0,0 +1,349 @@ +/* see copyright notice in squirrel.h */ + +#include +#include +#include +#include + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#define scfprintf fwprintf +#define scvprintf vfwprintf +#else +#define scfprintf fprintf +#define scvprintf vfprintf +#endif + + +void PrintVersionInfos(); + +#if defined(_MSC_VER) && defined(_DEBUG) +int MemAllocHook( int allocType, void *userData, size_t size, int blockType, + long requestNumber, const unsigned char *filename, int lineNumber) +{ + //if(requestNumber==769)_asm int 3; + return 1; +} +#endif + + +SQInteger quit(HSQUIRRELVM v) +{ + int *done; + sq_getuserpointer(v,-1,(SQUserPointer*)&done); + *done=1; + return 0; +} + +void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf(stdout, s, vl); + va_end(vl); +} + +void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...) +{ + va_list vl; + va_start(vl, s); + scvprintf(stderr, s, vl); + va_end(vl); +} + +void PrintVersionInfos() +{ + scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,((int)(sizeof(SQInteger)*8))); +} + +void PrintUsage() +{ + scfprintf(stderr,_SC("usage: sq .\n") + _SC("Available options are:\n") + _SC(" -c compiles the file to bytecode(default output 'out.cnut')\n") + _SC(" -o specifies output file for the -c option\n") + _SC(" -c compiles only\n") + _SC(" -d generates debug infos\n") + _SC(" -v displays version infos\n") + _SC(" -h prints help\n")); +} + +#define _INTERACTIVE 0 +#define _DONE 2 +#define _ERROR 3 +//<> this func is a mess +int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval) +{ + int i; + int compiles_only = 0; +#ifdef SQUNICODE + static SQChar temp[500]; +#endif + char * output = NULL; + *retval = 0; + if(argc>1) + { + int arg=1,exitloop=0; + + while(arg < argc && !exitloop) + { + + if(argv[arg][0]=='-') + { + switch(argv[arg][1]) + { + case 'd': //DEBUG(debug infos) + sq_enabledebuginfo(v,1); + break; + case 'c': + compiles_only = 1; + break; + case 'o': + if(arg < argc) { + arg++; + output = argv[arg]; + } + break; + case 'v': + PrintVersionInfos(); + return _DONE; + + case 'h': + PrintVersionInfos(); + PrintUsage(); + return _DONE; + default: + PrintVersionInfos(); + scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]); + PrintUsage(); + *retval = -1; + return _ERROR; + } + }else break; + arg++; + } + + // src file + + if(arg")); + for(;;) { + int c; + if(done)return; + c = getchar(); + if (c == _SC('\n')) { + if (i>0 && buffer[i-1] == _SC('\\')) + { + buffer[i-1] = _SC('\n'); + } + else if(blocks==0)break; + buffer[i++] = _SC('\n'); + } + else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;} + else if(c==_SC('{') && !string){ + blocks++; + buffer[i++] = (SQChar)c; + } + else if(c==_SC('"') || c==_SC('\'')){ + string=!string; + buffer[i++] = (SQChar)c; + } + else if (i >= MAXINPUT-1) { + scfprintf(stderr, _SC("sq : input line too long\n")); + break; + } + else{ + buffer[i++] = (SQChar)c; + } + } + buffer[i] = _SC('\0'); + + if(buffer[0]==_SC('=')){ + scsprintf(sq_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]); + memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar)); + retval=1; + } + i=scstrlen(buffer); + if(i>0){ + SQInteger oldtop=sq_gettop(v); + if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){ + sq_pushroottable(v); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){ + scprintf(_SC("\n")); + sq_pushroottable(v); + sq_pushstring(v,_SC("print"),-1); + sq_get(v,-2); + sq_pushroottable(v); + sq_push(v,-4); + sq_call(v,2,SQFalse,SQTrue); + retval=0; + scprintf(_SC("\n")); + } + } + + sq_settop(v,oldtop); + } + } +} + +int main(int argc, char* argv[]) +{ + HSQUIRRELVM v; + SQInteger retval = 0; +#if defined(_MSC_VER) && defined(_DEBUG) + _CrtSetAllocHook(MemAllocHook); +#endif + + v=sq_open(1024); + sq_setprintfunc(v,printfunc,errorfunc); + + sq_pushroottable(v); + + sqstd_register_bloblib(v); + sqstd_register_iolib(v); + sqstd_register_systemlib(v); + sqstd_register_mathlib(v); + sqstd_register_stringlib(v); + + //aux library + //sets error handlers + sqstd_seterrorhandlers(v); + + //gets arguments + switch(getargs(v,argc,argv,&retval)) + { + case _INTERACTIVE: + Interactive(v); + break; + case _DONE: + case _ERROR: + default: + break; + } + + sq_close(v); + +#if defined(_MSC_VER) && defined(_DEBUG) + _getch(); + _CrtMemDumpAllObjectsSince( NULL ); +#endif + return retval; +} + diff --git a/vscript/squirrel/sq/sq.dsp b/vscript/squirrel/sq/sq.dsp new file mode 100644 index 00000000..a632d12b --- /dev/null +++ b/vscript/squirrel/sq/sq.dsp @@ -0,0 +1,101 @@ +# Microsoft Developer Studio Project File - Name="sq" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sq - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sq.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sq.mak" CFG="sq - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sq - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sq - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sq - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /I "..\sqstdlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 squirrel.lib sqstdlib.lib /nologo /subsystem:console /machine:I386 /out:"../bin/sq.exe" /libpath:"../lib" + +!ELSEIF "$(CFG)" == "sq - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\sqstdlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 squirrel.lib sqstdlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/sq.exe" /pdbtype:sept /libpath:"../lib" + +!ENDIF + +# Begin Target + +# Name "sq - Win32 Release" +# Name "sq - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sq.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/vscript/squirrel/sqstdlib/CMakeLists.txt b/vscript/squirrel/sqstdlib/CMakeLists.txt new file mode 100644 index 00000000..34fba82f --- /dev/null +++ b/vscript/squirrel/sqstdlib/CMakeLists.txt @@ -0,0 +1,52 @@ +set(SQSTDLIB_SRC sqstdaux.cpp + sqstdblob.cpp + sqstdio.cpp + sqstdmath.cpp + sqstdrex.cpp + sqstdstream.cpp + sqstdstring.cpp + sqstdsystem.cpp) + +if(NOT DISABLE_DYNAMIC) + add_library(sqstdlib SHARED ${SQSTDLIB_SRC}) + add_library(squirrel::sqstdlib ALIAS sqstdlib) + set_property(TARGET sqstdlib PROPERTY EXPORT_NAME sqstdlib) + target_link_libraries(sqstdlib squirrel) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS sqstdlib EXPORT squirrel + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Libraries + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries NAMELINK_SKIP + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries + ) + install(TARGETS sqstdlib EXPORT squirrel + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development NAMELINK_ONLY + ) + endif() + target_include_directories(sqstdlib PUBLIC + "$" + "$" + ) +endif() + +if(NOT DISABLE_STATIC) + add_library(sqstdlib_static STATIC ${SQSTDLIB_SRC}) + add_library(squirrel::sqstdlib_static ALIAS sqstdlib_static) + set_property(TARGET sqstdlib_static PROPERTY EXPORT_NAME sqstdlib_static) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS sqstdlib_static EXPORT squirrel ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) + endif() + target_include_directories(sqstdlib_static PUBLIC + "$" + "$" + ) +endif() + +if(LONG_OUTPUT_NAMES) + if(NOT DISABLE_DYNAMIC) + set_target_properties(sqstdlib PROPERTIES OUTPUT_NAME sqstdlib3) + endif() + + if(NOT DISABLE_STATIC) + set_target_properties(sqstdlib_static PROPERTIES OUTPUT_NAME sqstdlib3_static) + endif() +endif() diff --git a/vscript/squirrel/sqstdlib/Makefile b/vscript/squirrel/sqstdlib/Makefile new file mode 100644 index 00000000..6ed1c12b --- /dev/null +++ b/vscript/squirrel/sqstdlib/Makefile @@ -0,0 +1,44 @@ +SQUIRREL= .. + + +CC?= gcc +OUT?= $(SQUIRREL)/lib/libsqstdlib.a +INCZ?= -I$(SQUIRREL)/include -I. -Iinclude +DEFS= $(CC_EXTRA_FLAGS) +LIB= + +OBJS= \ + sqstdblob.o \ + sqstdio.o \ + sqstdstream.o \ + sqstdmath.o \ + sqstdsystem.o \ + sqstdstring.o \ + sqstdaux.o \ + sqstdrex.o + +SRCS= \ + sqstdblob.cpp \ + sqstdio.cpp \ + sqstdstream.cpp \ + sqstdmath.cpp \ + sqstdsystem.cpp \ + sqstdstring.cpp \ + sqstdaux.cpp \ + sqstdrex.cpp + + +sq32: + $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sqprof: + $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sq64: + $(CC) -O2 -m64 -fno-exceptions -D_SQ64 -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o diff --git a/vscript/squirrel/sqstdlib/sqstdaux.cpp b/vscript/squirrel/sqstdlib/sqstdaux.cpp new file mode 100644 index 00000000..75c16533 --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdaux.cpp @@ -0,0 +1,151 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +void sqstd_printcallstack(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + SQStackInfos si; + SQInteger i; + SQFloat f; + const SQChar *s; + SQInteger level=1; //1 is to skip this function that is level 0 + const SQChar *name=0; + SQInteger seq=0; + pf(v,_SC("\nCALLSTACK\n")); + while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) + { + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); + level++; + } + level=0; + pf(v,_SC("\nLOCALS\n")); + + for(level=0;level<10;level++){ + seq=0; + while((name = sq_getlocal(v,level,seq))) + { + seq++; + switch(sq_gettype(v,-1)) + { + case OT_NULL: + pf(v,_SC("[%s] NULL\n"),name); + break; + case OT_INTEGER: + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %d\n"),name,i); + break; + case OT_FLOAT: + sq_getfloat(v,-1,&f); + pf(v,_SC("[%s] %.14g\n"),name,f); + break; + case OT_USERPOINTER: + pf(v,_SC("[%s] USERPOINTER\n"),name); + break; + case OT_STRING: + sq_getstring(v,-1,&s); + pf(v,_SC("[%s] \"%s\"\n"),name,s); + break; + case OT_TABLE: + pf(v,_SC("[%s] TABLE\n"),name); + break; + case OT_ARRAY: + pf(v,_SC("[%s] ARRAY\n"),name); + break; + case OT_CLOSURE: + pf(v,_SC("[%s] CLOSURE\n"),name); + break; + case OT_NATIVECLOSURE: + pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + break; + case OT_GENERATOR: + pf(v,_SC("[%s] GENERATOR\n"),name); + break; + case OT_USERDATA: + pf(v,_SC("[%s] USERDATA\n"),name); + break; + case OT_THREAD: + pf(v,_SC("[%s] THREAD\n"),name); + break; + case OT_CLASS: + pf(v,_SC("[%s] CLASS\n"),name); + break; + case OT_INSTANCE: + pf(v,_SC("[%s] INSTANCE\n"),name); + break; + case OT_WEAKREF: + pf(v,_SC("[%s] WEAKREF\n"),name); + break; + case OT_BOOL:{ + SQBool bval; + sq_getbool(v,-1,&bval); + pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false")); + } + break; + default: assert(0); break; + } + sq_pop(v,1); + } + } + } +} + +static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + const SQChar *sErr = 0; + if(sq_gettop(v)>=1) { + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} + +SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...) +{ + SQInteger n=256; + va_list args; +begin: + va_start(args,err); + SQChar *b=sq_getscratchpad(v,n); + SQInteger r=scvsprintf(b,n,err,args); + va_end(args); + if (r>=n) { + n=r+1;//required+null + goto begin; + } else if (r<0) { + return sq_throwerror(v,_SC("@failed to generate formatted error message")); + } else { + return sq_throwerror(v,b); + } +} diff --git a/vscript/squirrel/sqstdlib/sqstdblob.cpp b/vscript/squirrel/sqstdlib/sqstdblob.cpp new file mode 100644 index 00000000..776a9680 --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdblob.cpp @@ -0,0 +1,283 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SQSTD_BLOB_TYPE_TAG ((SQUnsignedInteger)(SQSTD_STREAM_TYPE_TAG | 0x00000002)) + +//Blob + + +#define SETUP_BLOB(v) \ + SQBlob *self = NULL; \ + { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ + return sq_throwerror(v,_SC("invalid type tag")); } \ + if(!self || !self->IsValid()) \ + return sq_throwerror(v,_SC("the blob is invalid")); + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger size; + sq_getinteger(v,2,&size); + if(!self->Resize(size)) + return sq_throwerror(v,_SC("resize failed")); + return 0; +} + +static void __swap_dword(unsigned int *n) +{ + *n=(unsigned int)(((*n&0xFF000000)>>24) | + ((*n&0x00FF0000)>>8) | + ((*n&0x0000FF00)<<8) | + ((*n&0x000000FF)<<24)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%4))>>2; + unsigned int *t=(unsigned int *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_dword(&t[i]); + } + return 0; +} + +static SQInteger _blob_swap2(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%2))>>1; + unsigned short *t = (unsigned short *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_word(&t[i]); + } + return 0; +} + +static SQInteger _blob__set(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx,val; + sq_getinteger(v,2,&idx); + sq_getinteger(v,3,&val); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; + sq_push(v,3); + return 1; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + + if ((sq_gettype(v, 2) & SQOBJECT_NUMERIC) == 0) + { + sq_pushnull(v); + return sq_throwobject(v); + } + sq_getinteger(v,2,&idx); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); + return 1; +} + +static SQInteger _blob__nexti(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + if(sq_gettype(v,2) == OT_NULL) { + sq_pushinteger(v, 0); + return 1; + } + SQInteger idx; + if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { + if(idx+1 < self->Len()) { + sq_pushinteger(v, idx+1); + return 1; + } + sq_pushnull(v); + return 1; + } + return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("blob"),-1); + return 1; +} + +static SQInteger _blob_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) +{ + SQBlob *self = (SQBlob*)p; + self->~SQBlob(); + sq_free(self,sizeof(SQBlob)); + return 1; +} + +static SQInteger _blob_constructor(HSQUIRRELVM v) +{ + SQInteger nparam = sq_gettop(v); + SQInteger size = 0; + if(nparam == 2) { + sq_getinteger(v, 2, &size); + } + if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); + //SQBlob *b = new SQBlob(size); + + SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); + if(SQ_FAILED(sq_setinstanceup(v,1,b))) { + b->~SQBlob(); + sq_free(b,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot create blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +static SQInteger _blob__cloned(HSQUIRRELVM v) +{ + SQBlob *other = NULL; + { + if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return SQ_ERROR; + } + //SQBlob *thisone = new SQBlob(other->Len()); + SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); + memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); + if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { + thisone->~SQBlob(); + sq_free(thisone,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot clone blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} +static const SQRegFunction _blob_methods[] = { + _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), + _DECL_BLOB_FUNC(resize,2,_SC("xn")), + _DECL_BLOB_FUNC(swap2,1,_SC("x")), + _DECL_BLOB_FUNC(swap4,1,_SC("x")), + _DECL_BLOB_FUNC(_set,3,_SC("xnn")), + _DECL_BLOB_FUNC(_get,2,_SC("x.")), + _DECL_BLOB_FUNC(_typeof,1,_SC("x")), + _DECL_BLOB_FUNC(_nexti,2,_SC("x")), + _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), + {NULL,(SQFUNCTION)0,0,NULL} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((const SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((const SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned short s = (unsigned short)i; + sq_pushinteger(v, ((s << 8) | ((s >> 8) & 0x00FFu)) & 0xFFFFu); + return 1; +} + +static SQInteger _g_blob_swap4(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned int t4 = (unsigned int)i; + __swap_dword(&t4); + sq_pushinteger(v,(SQInteger)t4); + return 1; +} + +static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + __swap_dword((unsigned int *)&f); + sq_pushfloat(v,f); + return 1; +} + +#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} +static const SQRegFunction bloblib_funcs[]={ + _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), + {NULL,(SQFUNCTION)0,0,NULL} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + *ptr = blob->GetBuf(); + return SQ_OK; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_blob"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_push(v,1); // push the this + sq_pushinteger(v,size); //size + SQBlob *blob = NULL; + if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) + && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { + sq_remove(v,-2); + return blob->GetBuf(); + } + } + sq_settop(v,top); + return NULL; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/vscript/squirrel/sqstdlib/sqstdblobimpl.h b/vscript/squirrel/sqstdlib/sqstdblobimpl.h new file mode 100644 index 00000000..bfdaddc2 --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdblobimpl.h @@ -0,0 +1,108 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +struct SQBlob : public SQStream +{ + SQBlob(SQInteger size) { + _size = size; + _allocated = size; + _buf = (unsigned char *)sq_malloc(size); + memset(_buf, 0, _size); + _ptr = 0; + _owns = true; + } + virtual ~SQBlob() { + sq_free(_buf, _allocated); + } + SQInteger Write(void *buffer, SQInteger size) { + if(!CanAdvance(size)) { + GrowBufOf(_ptr + size - _size); + } + memcpy(&_buf[_ptr], buffer, size); + _ptr += size; + return size; + } + SQInteger Read(void *buffer,SQInteger size) { + SQInteger n = size; + if(!CanAdvance(size)) { + if((_size - _ptr) > 0) + n = _size - _ptr; + else return 0; + } + memcpy(buffer, &_buf[_ptr], n); + _ptr += n; + return n; + } + bool Resize(SQInteger n) { + if(!_owns) return false; + if(n != _allocated) { + unsigned char *newbuf = (unsigned char *)sq_malloc(n); + memset(newbuf,0,n); + if(_size > n) + memcpy(newbuf,_buf,n); + else + memcpy(newbuf,_buf,_size); + sq_free(_buf,_allocated); + _buf=newbuf; + _allocated = n; + if(_size > _allocated) + _size = _allocated; + if(_ptr > _allocated) + _ptr = _allocated; + } + return true; + } + bool GrowBufOf(SQInteger n) + { + bool ret = true; + if(_size + n > _allocated) { + if(_size + n > _size * 2) + ret = Resize(_size + n); + else + ret = Resize(_size * 2); + } + _size = _size + n; + return ret; + } + bool CanAdvance(SQInteger n) { + if(_ptr+n>_size)return false; + return true; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + switch(origin) { + case SQ_SEEK_SET: + if(offset > _size || offset < 0) return -1; + _ptr = offset; + break; + case SQ_SEEK_CUR: + if(_ptr + offset > _size || _ptr + offset < 0) return -1; + _ptr += offset; + break; + case SQ_SEEK_END: + if(_size + offset > _size || _size + offset < 0) return -1; + _ptr = _size + offset; + break; + default: return -1; + } + return 0; + } + bool IsValid() { + return _size == 0 || _buf?true:false; + } + bool EOS() { + return _ptr == _size; + } + SQInteger Flush() { return 0; } + SQInteger Tell() { return _ptr; } + SQInteger Len() { return _size; } + SQUserPointer GetBuf(){ return _buf; } +private: + SQInteger _size; + SQInteger _allocated; + SQInteger _ptr; + unsigned char *_buf; + bool _owns; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/vscript/squirrel/sqstdlib/sqstdio.cpp b/vscript/squirrel/sqstdlib/sqstdio.cpp new file mode 100644 index 00000000..52cd5158 --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdio.cpp @@ -0,0 +1,489 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG ((SQUnsignedInteger)(SQSTD_STREAM_TYPE_TAG | 0x00000001)) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + return (SQFILE)_wfopen(filename,mode); +#endif +} + +SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) +{ + SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file); + return ret; +} + +SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fwrite(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) +{ + SQInteger realorigin; + switch(origin) { + case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; + case SQ_SEEK_END: realorigin = SEEK_END; break; + case SQ_SEEK_SET: realorigin = SEEK_SET; break; + default: return -1; //failed + } + return fseek((FILE *)file,(long)offset,(int)realorigin); +} + +SQInteger sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE file) +{ + return feof((FILE *)file); +} + +//File +struct SQFile : public SQStream { + SQFile() { _handle = NULL; _owns = false;} + SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} + virtual ~SQFile() { Close(); } + bool Open(const SQChar *filename ,const SQChar *mode) { + Close(); + if( (_handle = sqstd_fopen(filename,mode)) ) { + _owns = true; + return true; + } + return false; + } + void Close() { + if(_handle && _owns) { + sqstd_fclose(_handle); + _handle = NULL; + _owns = false; + } + } + SQInteger Read(void *buffer,SQInteger size) { + return sqstd_fread(buffer,1,size,_handle); + } + SQInteger Write(void *buffer,SQInteger size) { + return sqstd_fwrite(buffer,1,size,_handle); + } + SQInteger Flush() { + return sqstd_fflush(_handle); + } + SQInteger Tell() { + return sqstd_ftell(_handle); + } + SQInteger Len() { + SQInteger prevpos=Tell(); + Seek(0,SQ_SEEK_END); + SQInteger size=Tell(); + Seek(prevpos,SQ_SEEK_SET); + return size; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + return sqstd_fseek(_handle,offset,origin); + } + bool IsValid() { return _handle?true:false; } + bool EOS() { return Tell()==Len()?true:false;} + SQFILE GetHandle() {return _handle;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("file"),-1); + return 1; +} + +static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) +{ + SQFile *self = (SQFile*)p; + self->~SQFile(); + sq_free(self,sizeof(SQFile)); + return 1; +} + +static SQInteger _file_constructor(HSQUIRRELVM v) +{ + const SQChar *filename,*mode; + bool owns = true; + SQFile *f; + SQFILE newf; + if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { + sq_getstring(v, 2, &filename); + sq_getstring(v, 3, &mode); + newf = sqstd_fopen(filename, mode); + if(!newf) return sq_throwerror(v, _SC("cannot open file")); + } else if(sq_gettype(v,2) == OT_USERPOINTER) { + owns = !(sq_gettype(v,3) == OT_NULL); + sq_getuserpointer(v,2,&newf); + } else { + return sq_throwerror(v,_SC("wrong parameter")); + } + + f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); + if(SQ_FAILED(sq_setinstanceup(v,1,f))) { + f->~SQFile(); + sq_free(f,sizeof(SQFile)); + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_file_releasehook); + return 0; +} + +static SQInteger _file_close(HSQUIRRELVM v) +{ + SQFile *self = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG)) + && self != NULL) + { + self->Close(); + } + return 0; +} + +//bindings +#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} +static const SQRegFunction _file_methods[] = { + _DECL_FILE_FUNC(constructor,3,_SC("x")), + _DECL_FILE_FUNC(_typeof,1,_SC("x")), + _DECL_FILE_FUNC(close,1,_SC("x")), + {NULL,(SQFUNCTION)0,0,NULL} +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_file"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_pushroottable(v); // push the this + sq_pushuserpointer(v,file); //file + if(own){ + sq_pushinteger(v,1); //true + } + else{ + sq_pushnull(v); //false + } + if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { + sq_remove(v,-2); + return SQ_OK; + } + } + sq_settop(v,top); + return SQ_ERROR; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) +{ + SQFile *fileobj = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { + *file = fileobj->GetHandle(); + return SQ_OK; + } + return sq_throwerror(v,_SC("not a file")); +} + + + +#define IO_BUFFER_SIZE 2048 +struct IOBuffer { + unsigned char buffer[IO_BUFFER_SIZE]; + SQInteger size; + SQInteger ptr; + SQFILE file; +}; + +SQInteger _read_byte(IOBuffer *iobuffer) +{ + if(iobuffer->ptr < iobuffer->size) { + + SQInteger ret = iobuffer->buffer[iobuffer->ptr]; + iobuffer->ptr++; + return ret; + } + else { + if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) + { + SQInteger ret = iobuffer->buffer[0]; + iobuffer->ptr = 1; + return ret; + } + } + + return 0; +} + +SQInteger _read_two_bytes(IOBuffer *iobuffer) +{ + if(iobuffer->ptr < iobuffer->size) { + if(iobuffer->size < 2) return 0; + SQInteger ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]); + iobuffer->ptr += 2; + return ret; + } + else { + if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) + { + if(iobuffer->size < 2) return 0; + SQInteger ret = *((const wchar_t*)&iobuffer->buffer[0]); + iobuffer->ptr = 2; + return ret; + } + } + + return 0; +} + +static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf) +{ + IOBuffer *iobuffer = (IOBuffer *)iobuf; + return _read_byte(iobuffer); + +} + +#ifdef SQUNICODE +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf) +{ + IOBuffer *iobuffer = (IOBuffer *)iobuf; +#define READ(iobuf) \ + if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \ + return 0; + + static const SQInteger utf8_lengths[16] = + { + 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ + 0,0,0,0, /* 1000 to 1011 : not valid */ + 2,2, /* 1100, 1101 : 2 bytes */ + 3, /* 1110 : 3 bytes */ + 4 /* 1111 :4 bytes */ + }; + static const unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; + unsigned char inchar; + SQInteger c = 0; + READ(iobuffer); + c = inchar; + // + if(c >= 0x80) { + SQInteger tmp; + SQInteger codelen = utf8_lengths[c>>4]; + if(codelen == 0) + return 0; + //"invalid UTF-8 stream"; + tmp = c&byte_masks[codelen]; + for(SQInteger n = 0; n < codelen-1; n++) { + tmp<<=6; + READ(iobuffer); + tmp |= inchar & 0x3F; + } + c = tmp; + } + return c; +} +#endif + +static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer iobuf) +{ + SQInteger ret; + IOBuffer *iobuffer = (IOBuffer *)iobuf; + if( (ret = _read_two_bytes(iobuffer)) > 0 ) + return ret; + return 0; +} + +static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer iobuf) +{ + SQInteger c; + IOBuffer *iobuffer = (IOBuffer *)iobuf; + if( (c = _read_two_bytes(iobuffer)) > 0 ) { + c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); + return c; + } + return 0; +} + +SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) +{ + SQInteger ret; + if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; + return -1; +} + +SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + SQFILE file = sqstd_fopen(filename,_SC("rb")); + + SQInteger ret; + unsigned short us; + unsigned char uc; + SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; + if(file){ + ret = sqstd_fread(&us,1,2,file); + if(ret != 2) { + //probably an empty file + us = 0; + } + if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE + sqstd_fseek(file,0,SQ_SEEK_SET); + if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { + sqstd_fclose(file); + return SQ_OK; + } + } + else { //SCRIPT + + switch(us) + { + //gotta swap the next 2 lines on BIG endian machines + case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; + case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); + } + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognized encoding")); + } +#ifdef SQUNICODE + func = _io_file_lexfeed_UTF8; +#else + func = _io_file_lexfeed_PLAIN; +#endif + break;//UTF-8 ; + default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii + } + IOBuffer buffer; + buffer.ptr = 0; + buffer.size = 0; + buffer.file = file; + if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){ + sqstd_fclose(file); + return SQ_OK; + } + } + sqstd_fclose(file); + return SQ_ERROR; + } + return sq_throwerror(v,_SC("cannot open the file")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + //at least one entry must exist in order for us to push it as the environment + if(sq_gettop(v) == 0) + return sq_throwerror(v,_SC("environment table expected")); + + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { + sq_push(v,-2); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { + sq_remove(v,retval?-2:-1); //removes the closure + return 1; + } + sq_pop(v,1); //removes the closure + } + return SQ_ERROR; +} + +SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) +{ + SQFILE file = sqstd_fopen(filename,_SC("wb+")); + if(!file) return sq_throwerror(v,_SC("cannot open the file")); + if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { + sqstd_fclose(file); + return SQ_OK; + } + sqstd_fclose(file); + return SQ_ERROR; //forward the error +} + +SQInteger _g_io_loadfile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + const SQChar *filename; + sq_getstring(v,2,&filename); + if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_dofile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + sq_push(v,1); //repush the this + if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} +static const SQRegFunction iolib_funcs[]={ + _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), + {NULL,(SQFUNCTION)0,0,NULL} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + //create delegate + declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); + sq_pushstring(v,_SC("stdout"),-1); + sqstd_createfile(v,stdout,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stdin"),-1); + sqstd_createfile(v,stdin,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stderr"),-1); + sqstd_createfile(v,stderr,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_settop(v,top); + return SQ_OK; +} diff --git a/vscript/squirrel/sqstdlib/sqstdlib.dsp b/vscript/squirrel/sqstdlib/sqstdlib.dsp new file mode 100644 index 00000000..ef5b7f48 --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdlib.dsp @@ -0,0 +1,131 @@ +# Microsoft Developer Studio Project File - Name="sqstdlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=sqstdlib - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sqstdlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sqstdlib.mak" CFG="sqstdlib - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sqstdlib - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "sqstdlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sqstdlib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" + +!ELSEIF "$(CFG)" == "sqstdlib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" + +!ENDIF + +# Begin Target + +# Name "sqstdlib - Win32 Release" +# Name "sqstdlib - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sqstdblob.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdio.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdmath.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdrex.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdstream.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdstring.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdaux.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdsystem.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\sqstdblobimpl.h +# End Source File +# Begin Source File + +SOURCE=.\sqstdstream.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vscript/squirrel/sqstdlib/sqstdmath.cpp b/vscript/squirrel/sqstdlib/sqstdmath.cpp new file mode 100644 index 00000000..c41ffd5e --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdmath.cpp @@ -0,0 +1,107 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat p1,p2; \ + sq_getfloat(v,2,&p1); \ + sq_getfloat(v,3,&p2); \ + sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ + return 1; \ +} + +static SQInteger math_srand(HSQUIRRELVM v) +{ + SQInteger i; + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); + srand((unsigned int)i); + return 0; +} + +static SQInteger math_rand(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +SINGLE_ARG_FUNC(exp) + +#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} +static const SQRegFunction mathlib_funcs[] = { + _DECL_FUNC(sqrt,2,_SC(".n")), + _DECL_FUNC(sin,2,_SC(".n")), + _DECL_FUNC(cos,2,_SC(".n")), + _DECL_FUNC(asin,2,_SC(".n")), + _DECL_FUNC(acos,2,_SC(".n")), + _DECL_FUNC(log,2,_SC(".n")), + _DECL_FUNC(log10,2,_SC(".n")), + _DECL_FUNC(tan,2,_SC(".n")), + _DECL_FUNC(atan,2,_SC(".n")), + _DECL_FUNC(atan2,3,_SC(".nn")), + _DECL_FUNC(pow,3,_SC(".nn")), + _DECL_FUNC(floor,2,_SC(".n")), + _DECL_FUNC(ceil,2,_SC(".n")), + _DECL_FUNC(exp,2,_SC(".n")), + _DECL_FUNC(srand,2,_SC(".n")), + _DECL_FUNC(rand,1,NULL), + _DECL_FUNC(fabs,2,_SC(".n")), + _DECL_FUNC(abs,2,_SC(".n")), + {NULL,(SQFUNCTION)0,0,NULL} +}; +#undef _DECL_FUNC + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(mathlib_funcs[i].name!=0) { + sq_pushstring(v,mathlib_funcs[i].name,-1); + sq_newclosure(v,mathlib_funcs[i].f,0); + sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_pushstring(v,_SC("RAND_MAX"),-1); + sq_pushinteger(v,RAND_MAX); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("PI"),-1); + sq_pushfloat(v,(SQFloat)M_PI); + sq_newslot(v,-3,SQFalse); + return SQ_OK; +} diff --git a/vscript/squirrel/sqstdlib/sqstdrex.cpp b/vscript/squirrel/sqstdlib/sqstdrex.cpp new file mode 100644 index 00000000..d0583a6b --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdrex.cpp @@ -0,0 +1,666 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#include + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB"),_SC("OP_MB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) +#define OP_MB (MAX_CHAR+14) //match balanced + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'm': + { + SQChar cb, ce; //cb = character begin match ce = character end match + cb = *++exp->_p; //skip 'm' + ce = *++exp->_p; + exp->_p++; //points to the next char to be parsed + if ((!cb) || (!ce)) sqstd_rex_error(exp,_SC("balanced chars expected")); + if ( cb == ce ) sqstd_rex_error(exp,_SC("open/close char can't be the same")); + SQInteger node = sqstd_rex_newnode(exp,OP_MB); + exp->_nodes[node].left = cb; + exp->_nodes[node].right = ce; + return node; + } + case 0: + sqstd_rex_error(exp,_SC("letter expected for argument of escape sequence")); + break; + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + SQInteger tempcap = exp->_currsubexp; + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + exp->_currsubexp = tempcap; + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + if (str == exp->_eol) return NULL; + str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if (str == exp->_eol) return NULL; + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + str++; + return str; + } + return NULL; + case OP_CCLASS: + if (str == exp->_eol) return NULL; + if(sqstd_rex_matchcclass(node->left,*str)) { + str++; + return str; + } + return NULL; + case OP_MB: + { + SQInteger cb = node->left; //char that opens a balanced expression + if(*str != cb) return NULL; // string doesnt start with open char + SQInteger ce = node->right; //char that closes a balanced expression + SQInteger cont = 1; + const SQChar *streol = exp->_eol; + while (++str < streol) { + if (*str == ce) { + if (--cont == 0) { + return ++str; + } + } + else if (*str == cb) cont++; + } + } + return NULL; // string ends out of balance + default: /* char */ + if (str == exp->_eol) return NULL; + if(*str != node->type) return NULL; + str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex * volatile exp = (SQRex *)sq_malloc(sizeof(SQRex)); // "volatile" is needed for setjmp() + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef _DEBUG + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "), (SQInt32)i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "), (SQInt32)i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"), (SQInt32)exp->_nodes[i].left, (SQInt32)exp->_nodes[i].right, (SQInt32)exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/vscript/squirrel/sqstdlib/sqstdstream.cpp b/vscript/squirrel/sqstdlib/sqstdstream.cpp new file mode 100644 index 00000000..b5c47cfb --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdstream.cpp @@ -0,0 +1,336 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)))) \ + return sq_throwerror(v,_SC("invalid type tag")); \ + if(!self || !self->IsValid()) \ + return sq_throwerror(v,_SC("the stream is invalid")); + +SQInteger _stream_readblob(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQUserPointer data,blobp; + SQInteger size,res; + sq_getinteger(v,2,&size); + if(size > self->Len()) { + size = self->Len(); + } + data = sq_getscratchpad(v,size); + res = self->Read(data,size); + if(res <= 0) + return sq_throwerror(v,_SC("no data left to read")); + blobp = sqstd_createblob(v,res); + memcpy(blobp,data,res); + return 1; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format; + sq_getinteger(v, 2, &format); + switch(format) { + case 'l': { + SQInteger i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 'i': { + SQInt32 i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 's': { + short s; + SAFE_READN(&s, sizeof(short)); + sq_pushinteger(v, s); + } + break; + case 'w': { + unsigned short w; + SAFE_READN(&w, sizeof(unsigned short)); + sq_pushinteger(v, w); + } + break; + case 'c': { + char c; + SAFE_READN(&c, sizeof(char)); + sq_pushinteger(v, c); + } + break; + case 'b': { + unsigned char c; + SAFE_READN(&c, sizeof(unsigned char)); + sq_pushinteger(v, c); + } + break; + case 'f': { + float f; + SAFE_READN(&f, sizeof(float)); + sq_pushfloat(v, f); + } + break; + case 'd': { + double d; + SAFE_READN(&d, sizeof(double)); + sq_pushfloat(v, (SQFloat)d); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 1; +} + +SQInteger _stream_writeblob(HSQUIRRELVM v) +{ + SQUserPointer data; + SQInteger size; + SETUP_STREAM(v); + if(SQ_FAILED(sqstd_getblob(v,2,&data))) + return sq_throwerror(v,_SC("invalid parameter")); + size = sqstd_getblobsize(v,2); + if(self->Write(data,size) != size) + return sq_throwerror(v,_SC("io error")); + sq_pushinteger(v,size); + return 1; +} + +SQInteger _stream_writen(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format, ti; + SQFloat tf; + sq_getinteger(v, 3, &format); + switch(format) { + case 'l': { + SQInteger i; + sq_getinteger(v, 2, &ti); + i = ti; + self->Write(&i, sizeof(SQInteger)); + } + break; + case 'i': { + SQInt32 i; + sq_getinteger(v, 2, &ti); + i = (SQInt32)ti; + self->Write(&i, sizeof(SQInt32)); + } + break; + case 's': { + short s; + sq_getinteger(v, 2, &ti); + s = (short)ti; + self->Write(&s, sizeof(short)); + } + break; + case 'w': { + unsigned short w; + sq_getinteger(v, 2, &ti); + w = (unsigned short)ti; + self->Write(&w, sizeof(unsigned short)); + } + break; + case 'c': { + char c; + sq_getinteger(v, 2, &ti); + c = (char)ti; + self->Write(&c, sizeof(char)); + } + break; + case 'b': { + unsigned char b; + sq_getinteger(v, 2, &ti); + b = (unsigned char)ti; + self->Write(&b, sizeof(unsigned char)); + } + break; + case 'f': { + float f; + sq_getfloat(v, 2, &tf); + f = (float)tf; + self->Write(&f, sizeof(float)); + } + break; + case 'd': { + double d; + sq_getfloat(v, 2, &tf); + d = tf; + self->Write(&d, sizeof(double)); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 0; +} + +SQInteger _stream_seek(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger offset, origin = SQ_SEEK_SET; + sq_getinteger(v, 2, &offset); + if(sq_gettop(v) > 2) { + SQInteger t; + sq_getinteger(v, 3, &t); + switch(t) { + case 'b': origin = SQ_SEEK_SET; break; + case 'c': origin = SQ_SEEK_CUR; break; + case 'e': origin = SQ_SEEK_END; break; + default: return sq_throwerror(v,_SC("invalid origin")); + } + } + sq_pushinteger(v, self->Seek(offset, origin)); + return 1; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + + SQInteger _stream__cloned(HSQUIRRELVM v) + { + return sq_throwerror(v,_SC("this object cannot be cloned")); + } + +static const SQRegFunction _stream_methods[] = { + _DECL_STREAM_FUNC(readblob,2,_SC("xn")), + _DECL_STREAM_FUNC(readn,2,_SC("xn")), + _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), + _DECL_STREAM_FUNC(writen,3,_SC("xnn")), + _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), + _DECL_STREAM_FUNC(tell,1,_SC("x")), + _DECL_STREAM_FUNC(len,1,_SC("x")), + _DECL_STREAM_FUNC(eos,1,_SC("x")), + _DECL_STREAM_FUNC(flush,1,_SC("x")), + _DECL_STREAM_FUNC(_cloned,0,NULL), + {NULL,(SQFUNCTION)0,0,NULL} +}; + +void init_streamclass(HSQUIRRELVM v) +{ + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_FAILED(sq_get(v,-2))) { + sq_pushstring(v,_SC("std_stream"),-1); + sq_newclass(v,SQFalse); + sq_settypetag(v,-1,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)); + SQInteger i = 0; + while(_stream_methods[i].name != 0) { + const SQRegFunction &f = _stream_methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pushroottable(v); + sq_pushstring(v,_SC("stream"),-1); + sq_pushstring(v,_SC("std_stream"),-1); + sq_get(v,-4); + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + } + else { + sq_pop(v,1); //result + } + sq_pop(v,1); +} + +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals) +{ + if(sq_gettype(v,-1) != OT_TABLE) + return sq_throwerror(v,_SC("table expected")); + SQInteger top = sq_gettop(v); + //create delegate + init_streamclass(v); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_SUCCEEDED(sq_get(v,-3))) { + sq_newclass(v,SQTrue); + sq_settypetag(v,-1,typetag); + SQInteger i = 0; + while(methods[i].name != 0) { + const SQRegFunction &f = methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + + i = 0; + while(globals[i].name!=0) + { + const SQRegFunction &f = globals[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + //register the class in the target table + sq_pushstring(v,name,-1); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_get(v,-2); + sq_remove(v,-2); + sq_newslot(v,-3,SQFalse); + + sq_settop(v,top); + return SQ_OK; + } + sq_settop(v,top); + return SQ_ERROR; +} diff --git a/vscript/squirrel/sqstdlib/sqstdstream.h b/vscript/squirrel/sqstdlib/sqstdstream.h new file mode 100644 index 00000000..867c135f --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdstream.h @@ -0,0 +1,18 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/vscript/squirrel/sqstdlib/sqstdstring.cpp b/vscript/squirrel/sqstdlib/sqstdstring.cpp new file mode 100644 index 00000000..5747d8ed --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdstring.cpp @@ -0,0 +1,552 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FORMAT_LEN 20 +#define MAX_WFORMAT_LEN 3 +#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) + +static SQUserPointer rex_typetag = NULL; + +static SQBool isfmtchr(SQChar ch) +{ + switch(ch) { + case '-': case '+': case ' ': case '#': case '0': return SQTrue; + } + return SQFalse; +} + +static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) +{ + SQChar *dummy; + SQChar swidth[MAX_WFORMAT_LEN]; + SQInteger wc = 0; + SQInteger start = n; + fmt[0] = '%'; + while (isfmtchr(src[n])) n++; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("width format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width = scstrtol(swidth,&dummy,10); + } + else + width = 0; + if (src[n] == '.') { + n++; + + wc = 0; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("precision format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width += scstrtol(swidth,&dummy,10); + + } + } + if (n-start > MAX_FORMAT_LEN ) + return sq_throwerror(v,_SC("format too long")); + memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); + fmt[(n-start)+2] = '\0'; + return n; +} + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) +{ + const SQChar *format; + SQChar *dest; + SQChar fmt[MAX_FORMAT_LEN]; + const SQRESULT res = sq_getstring(v,nformatstringidx,&format); + if (SQ_FAILED(res)) { + return res; // propagate the error + } + SQInteger format_size = sq_getsize(v,nformatstringidx); + SQInteger allocated = (format_size+2)*sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; + //while(format[n] != '\0') + while(n < format_size) + { + if(format[n] != '%') { + assert(i < allocated); + dest[i++] = format[n]; + n++; + } + else if(format[n+1] == '%') { //handles %% + dest[i++] = '%'; + n += 2; + } + else { + n++; + if( nparam > sq_gettop(v) ) + return sq_throwerror(v,_SC("not enough parameters for the given format string")); + n = validate_format(v,fmt,format,n,w); + if(n < 0) return -1; + SQInteger addlen = 0; + SQInteger valtype = 0; + const SQChar *ts = NULL; + SQInteger ti = 0; + SQFloat tf = 0; + switch(format[n]) { + case 's': + if(SQ_FAILED(sq_getstring(v,nparam,&ts))) + return sq_throwerror(v,_SC("string expected for the specified format")); + addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); + valtype = 's'; + break; + case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': +#ifdef _SQ64 + { + size_t flen = scstrlen(fmt); + SQInteger fpos = flen - 1; + SQChar f = fmt[fpos]; + const SQChar *prec = (const SQChar *)_PRINT_INT_PREC; + while(*prec != _SC('\0')) { + fmt[fpos++] = *prec++; + } + fmt[fpos++] = f; + fmt[fpos++] = _SC('\0'); + } +#endif + case 'c': + if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) + return sq_throwerror(v,_SC("integer expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'i'; + break; + case 'f': case 'g': case 'G': case 'e': case 'E': + if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) + return sq_throwerror(v,_SC("float expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'f'; + break; + default: + return sq_throwerror(v,_SC("invalid format")); + } + n++; + allocated += addlen + sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + switch(valtype) { + case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break; + case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break; + case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break; + }; + nparam ++; + } + } + *outlen = i; + dest[i] = '\0'; + *output = dest; + return SQ_OK; +} + +void sqstd_pushstringf(HSQUIRRELVM v,const SQChar *s,...) +{ + SQInteger n=256; + va_list args; +begin: + va_start(args,s); + SQChar *b=sq_getscratchpad(v,n); + SQInteger r=scvsprintf(b,n,s,args); + va_end(args); + if (r>=n) { + n=r+1;//required+null + goto begin; + } else if (r<0) { + sq_pushnull(v); + } else { + sq_pushstring(v,b,r); + } +} + +static SQInteger _string_printf(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + + SQPRINTFUNCTION printfunc = sq_getprintfunc(v); + if(printfunc) printfunc(v,_SC("%s"),dest); + + return 0; +} + +static SQInteger _string_format(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + sq_pushstring(v,dest,length); + return 1; +} + +static void __strip_l(const SQChar *str,const SQChar **start) +{ + const SQChar *t = str; + while(((*t) != '\0') && scisspace(*t)){ t++; } + *start = t; +} + +static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) +{ + if(len == 0) { + *end = str; + return; + } + const SQChar *t = &str[len-1]; + while(t >= str && scisspace(*t)) { t--; } + *end = t + 1; +} + +static SQInteger _string_strip(HSQUIRRELVM v) +{ + const SQChar *str,*start,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_l(str,&start); + __strip_r(str,len,&end); + sq_pushstring(v,start,end - start); + return 1; +} + +static SQInteger _string_lstrip(HSQUIRRELVM v) +{ + const SQChar *str,*start; + sq_getstring(v,2,&str); + __strip_l(str,&start); + sq_pushstring(v,start,-1); + return 1; +} + +static SQInteger _string_rstrip(HSQUIRRELVM v) +{ + const SQChar *str,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_r(str,len,&end); + sq_pushstring(v,str,end - str); + return 1; +} + +static SQInteger _string_split(HSQUIRRELVM v) +{ + const SQChar *str,*seps; + SQInteger sepsize; + SQBool skipempty = SQFalse; + sq_getstring(v,2,&str); + sq_getstringandsize(v,3,&seps,&sepsize); + if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string")); + if(sq_gettop(v)>3) { + sq_getbool(v,4,&skipempty); + } + const SQChar *start = str; + const SQChar *end = str; + sq_newarray(v,0); + while(*end != '\0') + { + SQChar cur = *end; + for(SQInteger i = 0; i < sepsize; i++) + { + if(cur == seps[i]) + { + if(!skipempty || (end != start)) { + sq_pushstring(v,start,end-start); + sq_arrayappend(v,-2); + } + start = end + 1; + break; + } + } + end++; + } + if(end != start) + { + sq_pushstring(v,start,end-start); + sq_arrayappend(v,-2); + } + return 1; +} + +static SQInteger _string_escape(HSQUIRRELVM v) +{ + const SQChar *str; + SQChar *dest,*resstr; + SQInteger size; + sq_getstring(v,2,&str); + size = sq_getsize(v,2); + if(size == 0) { + sq_push(v,2); + return 1; + } +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 + const SQChar *escpat = _SC("\\x%04x"); + const SQInteger maxescsize = 6; +#else //WCHAR_SIZE == 4 + const SQChar *escpat = _SC("\\x%08x"); + const SQInteger maxescsize = 10; +#endif +#else + const SQChar *escpat = _SC("\\x%02x"); + const SQInteger maxescsize = 4; +#endif + SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped + resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar)); + SQChar c; + SQChar escch; + SQInteger escaped = 0; + for(int n = 0; n < size; n++){ + c = *str++; + escch = 0; + if(scisprint(c) || c == 0) { + switch(c) { + case '\a': escch = 'a'; break; + case '\b': escch = 'b'; break; + case '\t': escch = 't'; break; + case '\n': escch = 'n'; break; + case '\v': escch = 'v'; break; + case '\f': escch = 'f'; break; + case '\r': escch = 'r'; break; + case '\\': escch = '\\'; break; + case '\"': escch = '\"'; break; + case '\'': escch = '\''; break; + case 0: escch = '0'; break; + } + if(escch) { + *dest++ = '\\'; + *dest++ = escch; + escaped++; + } + else { + *dest++ = c; + } + } + else { + + dest += scsprintf(dest, destcharsize, escpat, c); + escaped++; + } + } + + if(escaped) { + sq_pushstring(v,resstr,dest - resstr); + } + else { + sq_push(v,2); //nothing escaped + } + return 1; +} + +static SQInteger _string_startswith(HSQUIRRELVM v) +{ + const SQChar *str,*cmp; + sq_getstring(v,2,&str); + sq_getstring(v,3,&cmp); + SQInteger len = sq_getsize(v,2); + SQInteger cmplen = sq_getsize(v,3); + SQBool ret = SQFalse; + if(cmplen <= len) { + ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; + } + sq_pushbool(v,ret); + return 1; +} + +static SQInteger _string_endswith(HSQUIRRELVM v) +{ + const SQChar *str,*cmp; + sq_getstring(v,2,&str); + sq_getstring(v,3,&cmp); + SQInteger len = sq_getsize(v,2); + SQInteger cmplen = sq_getsize(v,3); + SQBool ret = SQFalse; + if(cmplen <= len) { + ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; + } + sq_pushbool(v,ret); + return 1; +} + +#define SETUP_REX(v) \ + SQRex *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer *)&self,rex_typetag))) { \ + return sq_throwerror(v,_SC("invalid type tag")); \ + } + +static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) +{ + SQRex *self = ((SQRex *)p); + sqstd_rex_free(self); + return 1; +} + +static SQInteger _regexp_match(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str; + sq_getstring(v,2,&str); + if(sqstd_rex_match(self,str) == SQTrue) + { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) +{ + sq_newtable(v); + sq_pushstring(v,_SC("begin"),-1); + sq_pushinteger(v,begin - str); + sq_rawset(v,-3); + sq_pushstring(v,_SC("end"),-1); + sq_pushinteger(v,end - str); + sq_rawset(v,-3); +} + +static SQInteger _regexp_search(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + _addrexmatch(v,str,begin,end); + return 1; + } + return 0; +} + +static SQInteger _regexp_capture(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + SQInteger n = sqstd_rex_getsubexpcount(self); + SQRexMatch match; + sq_newarray(v,0); + for(SQInteger i = 0;i < n; i++) { + sqstd_rex_getsubexp(self,i,&match); + if(match.len > 0) + _addrexmatch(v,str,match.begin,match.begin+match.len); + else + _addrexmatch(v,str,str,str); //empty match + sq_arrayappend(v,-2); + } + return 1; + } + return 0; +} + +static SQInteger _regexp_subexpcount(HSQUIRRELVM v) +{ + SETUP_REX(v); + sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); + return 1; +} + +static SQInteger _regexp_constructor(HSQUIRRELVM v) +{ + SQRex *self = NULL; + if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer *)&self, rex_typetag))) { + return sq_throwerror(v, _SC("invalid type tag")); + } + if (self != NULL) { + return sq_throwerror(v, _SC("invalid regexp object")); + } + const SQChar *error,*pattern; + sq_getstring(v,2,&pattern); + SQRex *rex = sqstd_rex_compile(pattern,&error); + if(!rex) return sq_throwerror(v,error); + sq_setinstanceup(v,1,rex); + sq_setreleasehook(v,1,_rexobj_releasehook); + return 0; +} + +static SQInteger _regexp__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + return 1; +} + +#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} +static const SQRegFunction rexobj_funcs[]={ + _DECL_REX_FUNC(constructor,2,_SC(".s")), + _DECL_REX_FUNC(search,-2,_SC("xsn")), + _DECL_REX_FUNC(match,2,_SC("xs")), + _DECL_REX_FUNC(capture,-2,_SC("xsn")), + _DECL_REX_FUNC(subexpcount,1,_SC("x")), + _DECL_REX_FUNC(_typeof,1,_SC("x")), + {NULL,(SQFUNCTION)0,0,NULL} +}; +#undef _DECL_REX_FUNC + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} +static const SQRegFunction stringlib_funcs[]={ + _DECL_FUNC(format,-2,_SC(".s")), + _DECL_FUNC(printf,-2,_SC(".s")), + _DECL_FUNC(strip,2,_SC(".s")), + _DECL_FUNC(lstrip,2,_SC(".s")), + _DECL_FUNC(rstrip,2,_SC(".s")), + _DECL_FUNC(split,-3,_SC(".ssb")), + _DECL_FUNC(escape,2,_SC(".s")), + _DECL_FUNC(startswith,3,_SC(".ss")), + _DECL_FUNC(endswith,3,_SC(".ss")), + {NULL,(SQFUNCTION)0,0,NULL} +}; +#undef _DECL_FUNC + + +SQInteger sqstd_register_stringlib(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + sq_newclass(v,SQFalse); + rex_typetag = (SQUserPointer)rexobj_funcs; + sq_settypetag(v, -1, rex_typetag); + SQInteger i = 0; + while(rexobj_funcs[i].name != 0) { + const SQRegFunction &f = rexobj_funcs[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + + i = 0; + while(stringlib_funcs[i].name!=0) + { + sq_pushstring(v,stringlib_funcs[i].name,-1); + sq_newclosure(v,stringlib_funcs[i].f,0); + sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/vscript/squirrel/sqstdlib/sqstdsystem.cpp b/vscript/squirrel/sqstdlib/sqstdsystem.cpp new file mode 100644 index 00000000..d326be1a --- /dev/null +++ b/vscript/squirrel/sqstdlib/sqstdsystem.cpp @@ -0,0 +1,154 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#include +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif +#ifdef IOS + #include + extern char **environ; +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushstring(v,scgetenv(s),-1); + return 1; + } + return 0; +} + +static SQInteger _system_system(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + #ifdef IOS + pid_t pid; + posix_spawn(&pid, s, NULL, NULL, NULL, environ); + sq_pushinteger(v, 0); + #else + sq_pushinteger(v,scsystem(s)); + #endif + return 1; + } + return sq_throwerror(v,_SC("wrong param")); +} + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + SQInteger t = (SQInteger)time(NULL); + sq_pushinteger(v,t); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + const SQChar *s; + sq_getstring(v,2,&s); + if(scremove(s)==-1) + return sq_throwerror(v,_SC("remove() failed")); + return 0; +} + +static SQInteger _system_rename(HSQUIRRELVM v) +{ + const SQChar *oldn,*newn; + sq_getstring(v,2,&oldn); + sq_getstring(v,3,&newn); + if(screname(oldn,newn)==-1) + return sq_throwerror(v,_SC("rename() failed")); + return 0; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&it); + t = it; + if(sq_gettop(v) > 2) { + sq_getinteger(v,3,(SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if(format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if(!date) + return sq_throwerror(v,_SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year+1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + + + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static const SQRegFunction systemlib_funcs[]={ + _DECL_FUNC(getenv,2,_SC(".s")), + _DECL_FUNC(system,2,_SC(".s")), + _DECL_FUNC(clock,0,NULL), + _DECL_FUNC(time,1,NULL), + _DECL_FUNC(date,-1,_SC(".nn")), + _DECL_FUNC(remove,2,_SC(".s")), + _DECL_FUNC(rename,3,_SC(".ss")), + {NULL,(SQFUNCTION)0,0,NULL} +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_systemlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(systemlib_funcs[i].name!=0) + { + sq_pushstring(v,systemlib_funcs[i].name,-1); + sq_newclosure(v,systemlib_funcs[i].f,0); + sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/vscript/squirrel/squirrel-config.cmake.in b/vscript/squirrel/squirrel-config.cmake.in new file mode 100644 index 00000000..6ed4a8aa --- /dev/null +++ b/vscript/squirrel/squirrel-config.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/squirrel-config-version.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/squirrel-targets.cmake") diff --git a/vscript/squirrel/squirrel.dsw b/vscript/squirrel/squirrel.dsw new file mode 100644 index 00000000..72150910 --- /dev/null +++ b/vscript/squirrel/squirrel.dsw @@ -0,0 +1,77 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sq"=.\sq\sq.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + . + end source code control +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name sqlibs + End Project Dependency + Begin Project Dependency + Project_Dep_Name squirrel + End Project Dependency + Begin Project Dependency + Project_Dep_Name sqstdlib + End Project Dependency +}}} + +############################################################################### + +Project: "sqstdlib"=.\sqstdlib\sqstdlib.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + "$/squirrel", HAAAAAAA + . + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "squirrel"=.\squirrel\squirrel.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + "$/squirrel", HAAAAAAA + . + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ + begin source code control + "$/squirrel", HAAAAAAA + . + end source code control +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vscript/squirrel/squirrel/CMakeLists.txt b/vscript/squirrel/squirrel/CMakeLists.txt new file mode 100644 index 00000000..f96b9584 --- /dev/null +++ b/vscript/squirrel/squirrel/CMakeLists.txt @@ -0,0 +1,55 @@ +set(SQUIRREL_SRC sqapi.cpp + sqbaselib.cpp + sqclass.cpp + sqcompiler.cpp + sqdebug.cpp + sqfuncstate.cpp + sqlexer.cpp + sqmem.cpp + sqobject.cpp + sqstate.cpp + sqtable.cpp + sqvm.cpp) + +if(NOT DISABLE_DYNAMIC) + add_library(squirrel SHARED ${SQUIRREL_SRC}) + add_library(squirrel::squirrel ALIAS squirrel) + set_property(TARGET squirrel PROPERTY EXPORT_NAME squirrel) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS squirrel EXPORT squirrel + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Libraries + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries NAMELINK_SKIP + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries + ) + install(TARGETS squirrel EXPORT squirrel + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development NAMELINK_ONLY + ) + endif() + target_include_directories(squirrel PUBLIC + "$" + "$" + ) +endif() + +if(NOT DISABLE_STATIC) + add_library(squirrel_static STATIC ${SQUIRREL_SRC}) + add_library(squirrel::squirrel_static ALIAS squirrel_static) + set_property(TARGET squirrel_static PROPERTY EXPORT_NAME squirrel_static) + if(NOT SQ_DISABLE_INSTALLER) + install(TARGETS squirrel_static EXPORT squirrel ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) + endif() + target_include_directories(squirrel_static PUBLIC + "$" + "$" + ) +endif() + +if(LONG_OUTPUT_NAMES) + if(NOT DISABLE_DYNAMIC) + set_target_properties(squirrel PROPERTIES OUTPUT_NAME squirrel3) + endif() + + if(NOT DISABLE_STATIC) + set_target_properties(squirrel_static PROPERTIES OUTPUT_NAME squirrel3_static) + endif() +endif() diff --git a/vscript/squirrel/squirrel/Makefile b/vscript/squirrel/squirrel/Makefile new file mode 100644 index 00000000..2422a834 --- /dev/null +++ b/vscript/squirrel/squirrel/Makefile @@ -0,0 +1,53 @@ +SQUIRREL= .. + + +CC?= gcc +OUT?= $(SQUIRREL)/lib/libsquirrel.a +INCZ?= -I$(SQUIRREL)/include -I. -Iinclude +DEFS= $(CC_EXTRA_FLAGS) +LIB= + +OBJS= \ + sqapi.o \ + sqbaselib.o \ + sqfuncstate.o \ + sqdebug.o \ + sqlexer.o \ + sqobject.o \ + sqcompiler.o \ + sqstate.o \ + sqtable.o \ + sqmem.o \ + sqvm.o \ + sqclass.o + +SRCS= \ + sqapi.cpp \ + sqbaselib.cpp \ + sqfuncstate.cpp \ + sqdebug.cpp \ + sqlexer.cpp \ + sqobject.cpp \ + sqcompiler.cpp \ + sqstate.cpp \ + sqtable.cpp \ + sqmem.cpp \ + sqvm.cpp \ + sqclass.cpp + + + +sq32: + $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sqprof: + $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sq64: + $(CC) -O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o diff --git a/vscript/squirrel/squirrel/sqapi.cpp b/vscript/squirrel/squirrel/sqapi.cpp new file mode 100644 index 00000000..a3221503 --- /dev/null +++ b/vscript/squirrel/squirrel/sqapi.cpp @@ -0,0 +1,1631 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "squserdata.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqclass.h" + +static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) +{ + *o = &stack_get(v,idx); + if(sq_type(**o) != type){ + SQObjectPtr oval = v->PrintObjVal(**o); + v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); + return false; + } + return true; +} + +#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } + +#define sq_aux_paramscheck(v,count) \ +{ \ + if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ +} + + +SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) +{ + SQUnsignedInteger buf_size = 100 *sizeof(SQChar); + scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type)); + return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); +} + +HSQUIRRELVM sq_open(SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + sq_new(ss, SQSharedState); + ss->Init(); + v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + ss->_root_vm = v; + if(v->Init(NULL, initialstacksize)) { + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } + return v; +} + +HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + ss=_ss(friendvm); + + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + + if(v->Init(friendvm, initialstacksize)) { + friendvm->Push(v); + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } +} + +SQInteger sq_getvmstate(HSQUIRRELVM v) +{ + if(v->_suspended) + return SQ_VMSTATE_SUSPENDED; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; + else return SQ_VMSTATE_IDLE; + } +} + +void sq_seterrorhandler(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_errorhandler = o; + v->Pop(); + } +} + +void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) +{ + v->_debughook_native = hook; + v->_debughook_closure.Null(); + v->_debughook = hook?true:false; +} + +void sq_setdebughook(HSQUIRRELVM v) +{ + SQObject o = stack_get(v,-1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_debughook_closure = o; + v->_debughook_native = NULL; + v->_debughook = !sq_isnull(o); + v->Pop(); + } +} + +void sq_close(HSQUIRRELVM v) +{ + SQSharedState *ss = _ss(v); + _thread(ss->_root_vm)->Finalize(); + sq_delete(ss, SQSharedState); +} + +SQInteger sq_getversion() +{ + return SQUIRREL_VERSION_NUMBER; +} + +SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) +{ + SQObjectPtr o; +#ifndef NO_COMPILER + if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { + v->Push(SQClosure::Create(_ss(v), _funcproto(o), _table(v->_roottable)->GetWeakRef(OT_TABLE))); + return SQ_OK; + } + return SQ_ERROR; +#else + return sq_throwerror(v,_SC("this is a no compiler build")); +#endif +} + +void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_debuginfo = enable?true:false; +} + +void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_notifyallexceptions = enable?true:false; +} + +void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(sq_type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else + _ss(v)->_refs_table.AddRef(*po); +#endif +} + +SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(sq_type(*po))) return 0; +#ifdef NO_GARBAGE_COLLECTOR + return po->_unVal.pRefCounted->_uiRef; +#else + return _ss(v)->_refs_table.GetRefCount(*po); +#endif +} + +SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(sq_type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; + __Release(po->_type,po->_unVal); + return ret; //the ret val doesn't work(and cannot be fixed) +#else + return _ss(v)->_refs_table.Release(*po); +#endif +} + +SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM SQ_UNUSED_ARG(v), const HSQOBJECT *po) +{ + if (!ISREFCOUNTED(sq_type(*po))) return 0; + return po->_unVal.pRefCounted->_uiRef; +} + +const SQChar *sq_objtostring(const HSQOBJECT *o) +{ + if(sq_type(*o) == OT_STRING) { + return _stringval(*o); + } + return NULL; +} + +SQInteger sq_objtointeger(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tointeger(*o); + } + return 0; +} + +SQFloat sq_objtofloat(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tofloat(*o); + } + return 0; +} + +SQBool sq_objtobool(const HSQOBJECT *o) +{ + if(sq_isbool(*o)) { + return _integer(*o); + } + return SQFalse; +} + +SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) +{ + if(sq_isuserpointer(*o)) { + return _userpointer(*o); + } + return 0; +} + +void sq_pushnull(HSQUIRRELVM v) +{ + v->PushNull(); +} + +void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) +{ + if(s) + v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); + else v->PushNull(); +} + +void sq_pushinteger(HSQUIRRELVM v,SQInteger n) +{ + v->Push(n); +} + +void sq_pushbool(HSQUIRRELVM v,SQBool b) +{ + v->Push(b?true:false); +} + +void sq_pushfloat(HSQUIRRELVM v,SQFloat n) +{ + v->Push(n); +} + +void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) +{ + v->Push(p); +} + +void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread) +{ + v->Push(thread); +} + +SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) +{ + SQUserData *ud = SQUserData::Create(_ss(v), size + SQ_ALIGNMENT); + v->Push(ud); + return (SQUserPointer)sq_aligning(ud + 1); +} + +void sq_newtable(HSQUIRRELVM v) +{ + v->Push(SQTable::Create(_ss(v), 0)); +} + +void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) +{ + v->Push(SQTable::Create(_ss(v), initialcapacity)); +} + +void sq_newarray(HSQUIRRELVM v,SQInteger size) +{ + v->Push(SQArray::Create(_ss(v), size)); +} + +SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) +{ + SQClass *baseclass = NULL; + if(hasbase) { + SQObjectPtr &base = stack_get(v,-1); + if(sq_type(base) != OT_CLASS) + return sq_throwerror(v,_SC("invalid base type")); + baseclass = _class(base); + } + SQClass *newclass = SQClass::Create(_ss(v), baseclass); + if(baseclass) v->Pop(); + v->Push(newclass); + return SQ_OK; +} + +SQBool sq_instanceof(HSQUIRRELVM v) +{ + SQObjectPtr &inst = stack_get(v,-1); + SQObjectPtr &cl = stack_get(v,-2); + if(sq_type(inst) != OT_INSTANCE || sq_type(cl) != OT_CLASS) + return sq_throwerror(v,_SC("invalid param type")); + return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; +} + +SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v,2); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + _array(*arr)->Append(v->GetUp(-1)); + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(_array(*arr)->Size() > 0) { + if(pushval != 0){ v->Push(_array(*arr)->Top()); } + _array(*arr)->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("empty array")); +} + +SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) +{ + sq_aux_paramscheck(v,1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(newsize >= 0) { + _array(*arr)->Resize(newsize); + return SQ_OK; + } + return sq_throwerror(v,_SC("negative size")); +} + + +SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *o; + _GETSAFE_OBJ(v, idx, OT_ARRAY,o); + SQArray *arr = _array(*o); + if(arr->Size() > 0) { + SQObjectPtr t; + SQInteger size = arr->Size(); + SQInteger n = size >> 1; size -= 1; + for(SQInteger i = 0; i < n; i++) { + t = arr->_values[i]; + arr->_values[i] = arr->_values[size-i]; + arr->_values[size-i] = t; + } + return SQ_OK; + } + return SQ_OK; +} + +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + +void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) +{ + SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); + nc->_nparamscheck = 0; + for(SQUnsignedInteger i = 0; i < nfreevars; i++) { + nc->_outervalues[i] = v->Top(); + v->Pop(); + } + v->Push(SQObjectPtr(nc)); +} + +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInteger *nfreevars) +{ + SQObject o = stack_get(v, idx); + if(sq_type(o) == OT_CLOSURE) { + SQClosure *c = _closure(o); + SQFunctionProto *proto = c->_function; + *nparams = proto->_nparameters; + *nfreevars = proto->_noutervalues; + return SQ_OK; + } + else if(sq_type(o) == OT_NATIVECLOSURE) + { + SQNativeClosure *c = _nativeclosure(o); + *nparams = c->_nparamscheck; + *nfreevars = (SQInteger)c->_noutervalues; + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) +{ + SQObject o = stack_get(v, idx); + if(sq_isnativeclosure(o)) { + SQNativeClosure *nc = _nativeclosure(o); + nc->_name = SQString::Create(_ss(v),name); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a nativeclosure")); +} + +SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) +{ + SQObject o = stack_get(v, -1); + if(!sq_isnativeclosure(o)) + return sq_throwerror(v, _SC("native closure expected")); + SQNativeClosure *nc = _nativeclosure(o); + nc->_nparamscheck = nparamscheck; + if(typemask) { + SQIntVec res; + if(!CompileTypemask(res, typemask)) + return sq_throwerror(v, _SC("invalid typemask")); + nc->_typecheck.copy(res); + } + else { + nc->_typecheck.resize(0); + } + if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { + nc->_nparamscheck = nc->_typecheck.size(); + } + return SQ_OK; +} + +SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + SQObjectPtr &env = stack_get(v,-1); + if(!sq_istable(env) && + !sq_isarray(env) && + !sq_isclass(env) && + !sq_isinstance(env)) + return sq_throwerror(v,_SC("invalid environment")); + SQWeakRef *w = _refcounted(env)->GetWeakRef(sq_type(env)); + SQObjectPtr ret; + if(sq_isclosure(o)) { + SQClosure *c = _closure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + if(_closure(o)->_base) { + c->_base = _closure(o)->_base; + __ObjAddRef(c->_base); + } + ret = c; + } + else { //then must be a native closure + SQNativeClosure *c = _nativeclosure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + ret = c; + } + v->Pop(); + v->Push(ret); + return SQ_OK; +} + +SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + if(sq_isnativeclosure(o)) + { + v->Push(_nativeclosure(o)->_name); + } + else { //closure + v->Push(_closure(o)->_function->_name); + } + return SQ_OK; +} + +SQRESULT sq_setclosureroot(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &c = stack_get(v,idx); + SQObject o = stack_get(v, -1); + if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); + if(sq_istable(o)) { + _closure(c)->SetRoot(_table(o)->GetWeakRef(OT_TABLE)); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("invalid type")); +} + +SQRESULT sq_getclosureroot(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &c = stack_get(v,idx); + if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); + v->Push(_closure(c)->_root->_obj); + return SQ_OK; +} + +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(sq_type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + +void sq_pushroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); +} + +void sq_pushregistrytable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_registry); +} + +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + +SQRESULT sq_setroottable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o) || sq_isnull(o)) { + v->_roottable = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("invalid type")); +} + +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("invalid type, expected table")); +} + +void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + v->_foreignptr = p; +} + +SQUserPointer sq_getforeignptr(HSQUIRRELVM v) +{ + return v->_foreignptr; +} + +void sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + _ss(v)->_foreignptr = p; +} + +SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v) +{ + return _ss(v)->_foreignptr; +} + +void sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) +{ + v->_releasehook = hook; +} + +SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v) +{ + return v->_releasehook; +} + +void sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) +{ + _ss(v)->_releasehook = hook; +} + +SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v) +{ + return _ss(v)->_releasehook; +} + +void sq_push(HSQUIRRELVM v,SQInteger idx) +{ + v->Push(stack_get(v, idx)); +} + +SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) +{ + return sq_type(stack_get(v, idx)); +} + +SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->TypeOf(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->ToString(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + *b = SQVM::IsFalse(o)?SQFalse:SQTrue; +} + +SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *i = tointeger(o); + return SQ_OK; + } + if(sq_isbool(o)) { + *i = SQVM::IsFalse(o)?SQFalse:SQTrue; + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *f = tofloat(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isbool(o)) { + *b = _integer(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger *size) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + *size = _string(*o)->_len; + return SQ_OK; +} + +SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + return SQ_OK; +} + +SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_THREAD,o); + *thread = _thread(*o); + return SQ_OK; +} + +SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + v->PushNull(); + if(!v->Clone(o, stack_get(v, -1))){ + v->Pop(); + return SQ_ERROR; + } + return SQ_OK; +} + +SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectType type = sq_type(o); + switch(type) { + case OT_STRING: return _string(o)->_len; + case OT_TABLE: return _table(o)->CountUsed(); + case OT_ARRAY: return _array(o)->Size(); + case OT_USERDATA: return _userdata(o)->_size; + case OT_INSTANCE: return _instance(o)->_class->_udsize; + case OT_CLASS: return _class(o)->_udsize; + default: + return sq_aux_invalidtype(v, type); + } +} + +SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + return HashObj(o); +} + +SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERDATA,o); + (*p) = _userdataval(*o); + if(typetag) *typetag = _userdata(*o)->_typetag; + return SQ_OK; +} + +SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + switch(sq_type(o)) { + case OT_USERDATA: _userdata(o)->_typetag = typetag; break; + case OT_CLASS: _class(o)->_typetag = typetag; break; + default: return sq_throwerror(v,_SC("invalid object type")); + } + return SQ_OK; +} + +SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) +{ + switch(sq_type(*o)) { + case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; + case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; + case OT_CLASS: *typetag = _class(*o)->_typetag; break; + default: return SQ_ERROR; + } + return SQ_OK; +} + +SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if (SQ_FAILED(sq_getobjtypetag(&o, typetag))) + return SQ_ERROR;// this is not an error it should be a bool but would break backward compatibility + return SQ_OK; +} + +SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); + (*p) = _userpointer(*o); + return SQ_OK; +} + +SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) +{ + SQObjectPtr &o = stack_get(v,idx); + if(sq_type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + _instance(o)->_userpointer = p; + return SQ_OK; +} + +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(sq_type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + +SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(sq_type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + (*p) = _instance(o)->_userpointer; + if(typetag != 0) { + SQClass *cl = _instance(o)->_class; + do{ + if(cl->_typetag == typetag) + return SQ_OK; + cl = cl->_base; + }while(cl != NULL); + return sq_throwerror(v,_SC("invalid type tag")); + } + return SQ_OK; +} + +SQInteger sq_gettop(HSQUIRRELVM v) +{ + return (v->_top) - v->_stackbase; +} + +void sq_settop(HSQUIRRELVM v, SQInteger newtop) +{ + SQInteger top = sq_gettop(v); + if(top > newtop) + sq_pop(v, top - newtop); + else + while(top++ < newtop) sq_pushnull(v); +} + +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + +void sq_poptop(HSQUIRRELVM v) +{ + assert(v->_top >= 1); + v->Pop(); +} + + +void sq_remove(HSQUIRRELVM v, SQInteger idx) +{ + v->Remove(idx); +} + +SQInteger sq_cmp(HSQUIRRELVM v) +{ + SQInteger res; + v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); + return res; +} + +SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) +{ + sq_aux_paramscheck(v, 3); + SQObjectPtr &self = stack_get(v, idx); + if(sq_type(self) == OT_TABLE || sq_type(self) == OT_CLASS) { + SQObjectPtr &key = v->GetUp(-2); + if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); + v->Pop(2); + } + return SQ_OK; +} + +SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + SQObjectPtr res; + if(!v->DeleteSlot(*self, key, res)){ + v->Pop(); + return SQ_ERROR; + } + if(pushval) v->GetUp(-1) = res; + else v->Pop(); + return SQ_OK; +} + +SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { + v->Pop(2); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &key = v->GetUp(-2); + if(sq_type(key) == OT_NULL) { + v->Pop(2); + return sq_throwerror(v, _SC("null key")); + } + switch(sq_type(self)) { + case OT_TABLE: + _table(self)->NewSlot(key, v->GetUp(-1)); + v->Pop(2); + return SQ_OK; + break; + case OT_CLASS: + _class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false); + v->Pop(2); + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key, v->GetUp(-1))) { + v->Pop(2); + return SQ_OK; + } + break; + case OT_ARRAY: + if(v->Set(self, key, v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + break; + default: + v->Pop(2); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) +{ + SQObjectPtr &self = stack_get(v, idx); + if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); + SQObjectPtr &key = v->GetUp(-3); + if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) { + v->Pop(3); + return SQ_ERROR; + } + v->Pop(3); + return SQ_OK; +} + +SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) +{ + SQObjectPtr &self = stack_get(v, idx); + if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); + SQObjectPtr &key = v->GetUp(-3); + if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) { + v->Pop(3); + return SQ_ERROR; + } + v->Pop(3); + return SQ_OK; +} + +SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &mt = v->GetUp(-1); + SQObjectType type = sq_type(self); + switch(type) { + case OT_TABLE: + if(sq_type(mt) == OT_TABLE) { + if(!_table(self)->SetDelegate(_table(mt))) { + return sq_throwerror(v, _SC("delegate cycle")); + } + v->Pop(); + } + else if(sq_type(mt)==OT_NULL) { + _table(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v,type); + break; + case OT_USERDATA: + if(sq_type(mt)==OT_TABLE) { + _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } + else if(sq_type(mt)==OT_NULL) { + _userdata(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v, type); + break; + default: + return sq_aux_invalidtype(v, type); + break; + } + return SQ_OK; +} + +SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + SQObjectPtr t; + if(_table(*self)->Get(key,t)) { + _table(*self)->Remove(key); + } + if(pushval != 0) + v->GetUp(-1) = t; + else + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(sq_type(self)){ + case OT_TABLE: + case OT_USERDATA: + if(!_delegable(self)->_delegate){ + v->PushNull(); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); + break; + default: return sq_throwerror(v,_SC("wrong type")); break; + } + return SQ_OK; + +} + +SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr &obj = v->GetUp(-1); + if(v->Get(self,obj,obj,false,DONT_FALL_BACK)) + return SQ_OK; + v->Pop(); + return SQ_ERROR; +} + +SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr &obj = v->GetUp(-1); + switch(sq_type(self)) { + case OT_TABLE: + if(_table(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_CLASS: + if(_class(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_ARRAY:{ + if(sq_isnumeric(obj)){ + if(_array(self)->Get(tointeger(obj),obj)) { + return SQ_OK; + } + } + else { + v->Pop(); + return sq_throwerror(v,_SC("invalid index type for an array")); + } + } + break; + default: + v->Pop(); + return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); + } + v->Pop(); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) +{ + *po=stack_get(v,idx); + return SQ_OK; +} + +const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) +{ + SQUnsignedInteger cstksize=v->_callsstacksize; + SQUnsignedInteger lvl=(cstksize-level)-1; + SQInteger stackbase=v->_stackbase; + if(lvl_callsstack[(cstksize-i)-1]; + stackbase-=ci._prevstkbase; + } + SQVM::CallInfo &ci=v->_callsstack[lvl]; + if(sq_type(ci._closure)!=OT_CLOSURE) + return NULL; + SQClosure *c=_closure(ci._closure); + SQFunctionProto *func=c->_function; + if(func->_noutervalues > (SQInteger)idx) { + v->Push(*_outer(c->_outervalues[idx])->_valptr); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); + } + return NULL; +} + +void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) +{ + v->Push(SQObjectPtr(obj)); +} + +void sq_resetobject(HSQOBJECT *po) +{ + po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; +} + +SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) +{ + v->_lasterror=SQString::Create(_ss(v),err); + return SQ_ERROR; +} + +SQRESULT sq_throwobject(HSQUIRRELVM v) +{ + v->_lasterror = v->GetUp(-1); + v->Pop(); + return SQ_ERROR; +} + + +void sq_reseterror(HSQUIRRELVM v) +{ + v->_lasterror.Null(); +} + +void sq_getlasterror(HSQUIRRELVM v) +{ + v->Push(v->_lasterror); +} + +SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) +{ + if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { + if(v->_nmetamethodscall) { + return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); + } + v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); + } + return SQ_OK; +} + +SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) +{ + if (sq_type(v->GetUp(-1)) == OT_GENERATOR) + { + v->PushNull(); //retval + if (!v->Execute(v->GetUp(-2), 0, v->_top, v->GetUp(-1), raiseerror, SQVM::ET_RESUME_GENERATOR)) + {v->Raise_Error(v->_lasterror); return SQ_ERROR;} + if(!retval) + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("only generators can be resumed")); +} + +SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) +{ + SQObjectPtr res; + if(!v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + v->Pop(params); //pop args + return SQ_ERROR; + } + if(!v->_suspended) + v->Pop(params); //pop args + if(retval) + v->Push(res); // push result + return SQ_OK; +} + +SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams) +{ + SQObjectPtr &res = v->GetUp(-(nparams + 1)); + if (sq_type(res) != OT_CLOSURE) { + return sq_throwerror(v, _SC("only closure can be tail called")); + } + SQClosure *clo = _closure(res); + if (clo->_function->_bgenerator) + { + return sq_throwerror(v, _SC("generators cannot be tail called")); + } + + SQInteger stackbase = (v->_top - nparams) - v->_stackbase; + if (!v->TailCall(clo, stackbase, nparams)) { + return SQ_ERROR; + } + return SQ_TAILCALL_FLAG; +} + +SQRESULT sq_suspendvm(HSQUIRRELVM v) +{ + return v->Suspend(); +} + +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) +{ + SQObjectPtr ret; + if(!v->_suspended) + return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); + SQInteger target = v->_suspended_target; + if(wakeupret) { + if(target != -1) { + v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval + } + v->Pop(); + } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } + SQObjectPtr dummy; + if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { + return SQ_ERROR; + } + if(retval) + v->Push(ret); + return SQ_OK; +} + +void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) +{ + SQObjectPtr &ud=stack_get(v,idx); + switch(sq_type(ud) ) { + case OT_USERDATA: _userdata(ud)->_hook = hook; break; + case OT_INSTANCE: _instance(ud)->_hook = hook; break; + case OT_CLASS: _class(ud)->_hook = hook; break; + default: return; + } +} + +SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &ud=stack_get(v,idx); + switch(sq_type(ud) ) { + case OT_USERDATA: return _userdata(ud)->_hook; break; + case OT_INSTANCE: return _instance(ud)->_hook; break; + case OT_CLASS: return _class(ud)->_hook; break; + default: return NULL; + } +} + +void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) +{ + _ss(v)->_compilererrorhandler = f; +} + +SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); + unsigned short tag = SQ_BYTECODE_STREAM_TAG; + if(_closure(*o)->_function->_noutervalues) + return sq_throwerror(v,_SC("a closure with free variables bound cannot be serialized")); + if(w(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(!_closure(*o)->Save(v,up,w)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) +{ + SQObjectPtr closure; + + unsigned short tag; + if(r(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(tag != SQ_BYTECODE_STREAM_TAG) + return sq_throwerror(v,_SC("invalid stream")); + if(!SQClosure::Load(v,up,r,closure)) + return SQ_ERROR; + v->Push(closure); + return SQ_OK; +} + +SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) +{ + return _ss(v)->GetScratchPad(minsize); +} + +SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + _ss(v)->ResurrectUnreachable(v); + return SQ_OK; +#else + return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); +#endif +} + +SQInteger sq_collectgarbage(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + return _ss(v)->CollectGarbage(v); +#else + return -1; +#endif +} + +SQRESULT sq_getcallee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return SQ_OK; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + const SQChar *name = NULL; + switch(sq_type(self)) + { + case OT_CLOSURE:{ + SQClosure *clo = _closure(self); + SQFunctionProto *fp = clo->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval) { + v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); + SQOuterVar &ov = fp->_outervalues[nval]; + name = _stringval(ov._name); + } + } + break; + case OT_NATIVECLOSURE:{ + SQNativeClosure *clo = _nativeclosure(self); + if(clo->_noutervalues > nval) { + v->Push(clo->_outervalues[nval]); + name = _SC("@NATIVE"); + } + } + break; + default: break; //shutup compiler + } + return name; +} + +SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(sq_type(self)) + { + case OT_CLOSURE:{ + SQFunctionProto *fp = _closure(self)->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval){ + *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + } + break; + case OT_NATIVECLOSURE: + if(_nativeclosure(self)->_noutervalues > nval){ + _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + default: + return sq_aux_invalidtype(v, sq_type(self)); + } + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-2); + SQObjectPtr &val = stack_get(v,-1); + SQObjectPtr attrs; + if(sq_type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + _class(*o)->_attributes = val; + v->Pop(2); + v->Push(attrs); + return SQ_OK; + }else if(_class(*o)->GetAttributes(key,attrs)) { + _class(*o)->SetAttributes(key,val); + v->Pop(2); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQObjectPtr attrs; + if(sq_type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + else if(_class(*o)->GetAttributes(key,attrs)) { + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQTable *m = _class(*o)->_members; + SQObjectPtr val; + if(m->Get(key,val)) { + handle->_static = _isfield(val) ? SQFalse : SQTrue; + handle->_index = _member_idx(val); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,const HSQMEMBERHANDLE *handle,SQObjectPtr *&val) +{ + switch(sq_type(self)) { + case OT_INSTANCE: { + SQInstance *i = _instance(self); + if(handle->_static) { + SQClass *c = i->_class; + val = &c->_methods[handle->_index].val; + } + else { + val = &i->_values[handle->_index]; + + } + } + break; + case OT_CLASS: { + SQClass *c = _class(self); + if(handle->_static) { + val = &c->_methods[handle->_index].val; + } + else { + val = &c->_defaultvalues[handle->_index].val; + } + } + break; + default: + return sq_throwerror(v,_SC("wrong type(expected class or instance)")); + } + return SQ_OK; +} + +SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + v->Push(_realval(*val)); + return SQ_OK; +} + +SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr &newval = stack_get(v,-1); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + *val = newval; + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + if(_class(*o)->_base) + v->Push(SQObjectPtr(_class(*o)->_base)); + else + v->PushNull(); + return SQ_OK; +} + +SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); + v->Push(SQObjectPtr(_instance(*o)->_class)); + return SQ_OK; +} + +SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + v->Push(_class(*o)->CreateInstance()); + return SQ_OK; +} + +void sq_weakref(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + if(ISREFCOUNTED(sq_type(o))) { + v->Push(_refcounted(o)->GetWeakRef(sq_type(o))); + return; + } + v->Push(o); +} + +SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(sq_type(o) != OT_WEAKREF) { + return sq_throwerror(v,_SC("the object must be a weakref")); + } + v->Push(_weakref(o)->_obj); + return SQ_OK; +} + +SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) +{ + SQSharedState *ss = _ss(v); + switch(t) { + case OT_TABLE: v->Push(ss->_table_default_delegate); break; + case OT_ARRAY: v->Push(ss->_array_default_delegate); break; + case OT_STRING: v->Push(ss->_string_default_delegate); break; + case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; + case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; + case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; + case OT_THREAD: v->Push(ss->_thread_default_delegate); break; + case OT_CLASS: v->Push(ss->_class_default_delegate); break; + case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; + case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; + default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); + } + return SQ_OK; +} + +SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; + if(sq_type(o) == OT_GENERATOR) { + return sq_throwerror(v,_SC("cannot iterate a generator")); + } + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) + return SQ_ERROR; + if(faketojump != 666) { + v->Push(realkey); + v->Push(val); + return SQ_OK; + } + return SQ_ERROR; +} + +struct BufState{ + const SQChar *buf; + SQInteger ptr; + SQInteger size; +}; + +SQInteger buf_lexfeed(SQUserPointer file) +{ + BufState *buf=(BufState*)file; + if(buf->size<(buf->ptr+1)) + return 0; + return buf->buf[buf->ptr++]; +} + +SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { + BufState buf; + buf.buf = s; + buf.size = size; + buf.ptr = 0; + return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); +} + +void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) +{ + dest->Push(stack_get(src,idx)); +} + +void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) +{ + _ss(v)->_printfunc = printfunc; + _ss(v)->_errorfunc = errfunc; +} + +SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) +{ + return _ss(v)->_printfunc; +} + +SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) +{ + return _ss(v)->_errorfunc; +} + +void *sq_malloc(SQUnsignedInteger size) +{ + return SQ_MALLOC(size); +} + +void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) +{ + return SQ_REALLOC(p,oldsize,newsize); +} + +void sq_free(void *p,SQUnsignedInteger size) +{ + SQ_FREE(p,size); +} diff --git a/vscript/squirrel/squirrel/sqarray.h b/vscript/squirrel/squirrel/sqarray.h new file mode 100644 index 00000000..7c6c2049 --- /dev/null +++ b/vscript/squirrel/squirrel/sqarray.h @@ -0,0 +1,94 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQARRAY_H_ +#define _SQARRAY_H_ + +struct SQArray : public CHAINABLE_OBJ +{ +private: + SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} + ~SQArray() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } +public: + static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ + SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); + new (newarray) SQArray(ss,nInitialSize); + return newarray; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_ARRAY;} +#endif + void Finalize(){ + _values.resize(0); + } + bool Get(const SQInteger nidx,SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + SQObjectPtr &o = _values[nidx]; + val = _realval(o); + return true; + } + else return false; + } + bool Set(const SQInteger nidx,const SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + _values[nidx]=val; + return true; + } + else return false; + } + SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) + { + SQUnsignedInteger idx=TranslateIndex(refpos); + while(idx<_values.size()){ + //first found + outkey=(SQInteger)idx; + SQObjectPtr &o = _values[idx]; + outval = _realval(o); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; + } + SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; } + SQInteger Size() const {return _values.size();} + void Resize(SQInteger size) + { + SQObjectPtr _null; + Resize(size,_null); + } + void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } + void Reserve(SQInteger size) { _values.reserve(size); } + void Append(const SQObject &o){_values.push_back(o);} + void Extend(const SQArray *a); + SQObjectPtr &Top(){return _values.top();} + void Pop(){_values.pop_back(); ShrinkIfNeeded(); } + bool Insert(SQInteger idx,const SQObject &val){ + if(idx < 0 || idx > (SQInteger)_values.size()) + return false; + _values.insert(idx,val); + return true; + } + void ShrinkIfNeeded() { + if(_values.size() <= _values.capacity()>>2) //shrink the array + _values.shrinktofit(); + } + bool Remove(SQInteger idx){ + if(idx < 0 || idx >= (SQInteger)_values.size()) + return false; + _values.remove(idx); + ShrinkIfNeeded(); + return true; + } + void Release() + { + sq_delete(this,SQArray); + } + + SQObjectPtrVec _values; +}; +#endif //_SQARRAY_H_ diff --git a/vscript/squirrel/squirrel/sqbaselib.cpp b/vscript/squirrel/squirrel/sqbaselib.cpp new file mode 100644 index 00000000..5c03e839 --- /dev/null +++ b/vscript/squirrel/squirrel/sqbaselib.cpp @@ -0,0 +1,1376 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqclass.h" +#include +#include +#include + +static bool str2num(const SQChar *s,SQObjectPtr &res,SQInteger base) +{ + SQChar *end; + const SQChar *e = s; + bool iseintbase = base > 13; //to fix error converting hexadecimals with e like 56f0791e + bool isfloat = false; + SQChar c; + while((c = *e) != _SC('\0')) + { + if (c == _SC('.') || (!iseintbase && (c == _SC('E') || c == _SC('e')))) { //e and E is for scientific notation + isfloat = true; + break; + } + e++; + } + if(isfloat){ + SQFloat r = SQFloat(scstrtod(s,&end)); + if(s == end) return false; + res = r; + } + else{ + SQInteger r = SQInteger(scstrtol(s,&end,(int)base)); + if(s == end) return false; + res = r; + } + return true; +} + +static SQInteger base_dummy(HSQUIRRELVM SQ_UNUSED_ARG(v)) +{ + return 0; +} + +#ifndef NO_GARBAGE_COLLECTOR +static SQInteger base_collectgarbage(HSQUIRRELVM v) +{ + sq_pushinteger(v, sq_collectgarbage(v)); + return 1; +} +static SQInteger base_resurectureachable(HSQUIRRELVM v) +{ + sq_resurrectunreachable(v); + return 1; +} +#endif + +static SQInteger base_getroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); + return 1; +} + +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + +static SQInteger base_setroottable(HSQUIRRELVM v) +{ + SQObjectPtr o = v->_roottable; + if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr o = _ss(v)->_consts; + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_seterrorhandler(HSQUIRRELVM v) +{ + sq_seterrorhandler(v); + return 0; +} + +static SQInteger base_setdebughook(HSQUIRRELVM v) +{ + sq_setdebughook(v); + return 0; +} + +static SQInteger base_enabledebuginfo(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + + sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); + return 0; +} + +static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) +{ + SQStackInfos si; + SQInteger seq = 0; + const SQChar *name = NULL; + + if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) + { + const SQChar *fn = _SC("unknown"); + const SQChar *src = _SC("unknown"); + if(si.funcname)fn = si.funcname; + if(si.source)src = si.source; + sq_newtable(v); + sq_pushstring(v, _SC("func"), -1); + sq_pushstring(v, fn, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("src"), -1); + sq_pushstring(v, src, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("line"), -1); + sq_pushinteger(v, si.line); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("locals"), -1); + sq_newtable(v); + seq=0; + while ((name = sq_getlocal(v, level, seq))) { + sq_pushstring(v, name, -1); + sq_push(v, -2); + sq_newslot(v, -4, SQFalse); + sq_pop(v, 1); + seq++; + } + sq_newslot(v, -3, SQFalse); + return 1; + } + + return 0; +} +static SQInteger base_getstackinfos(HSQUIRRELVM v) +{ + SQInteger level; + sq_getinteger(v, -1, &level); + return __getcallstackinfos(v,level); +} + +static SQInteger base_assert(HSQUIRRELVM v) +{ + if(SQVM::IsFalse(stack_get(v,2))){ + SQInteger top = sq_gettop(v); + if (top>2 && SQ_SUCCEEDED(sq_tostring(v,3))) { + const SQChar *str = 0; + if (SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { + return sq_throwerror(v, str); + } + } + return sq_throwerror(v, _SC("assertion failed")); + } + return 0; +} + +static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) +{ + SQInteger top = sq_gettop(v); + sidx=0; + eidx=0; + o=stack_get(v,1); + if(top>1){ + SQObjectPtr &start=stack_get(v,2); + if(sq_type(start)!=OT_NULL && sq_isnumeric(start)){ + sidx=tointeger(start); + } + } + if(top>2){ + SQObjectPtr &end=stack_get(v,3); + if(sq_isnumeric(end)){ + eidx=tointeger(end); + } + } + else { + eidx = sq_getsize(v,1); + } + return 1; +} + +static SQInteger base_print(HSQUIRRELVM v) +{ + const SQChar *str; + if(SQ_SUCCEEDED(sq_tostring(v,2))) + { + if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { + if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); + return 0; + } + } + return SQ_ERROR; +} + +static SQInteger base_error(HSQUIRRELVM v) +{ + const SQChar *str; + if(SQ_SUCCEEDED(sq_tostring(v,2))) + { + if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { + if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); + return 0; + } + } + return SQ_ERROR; +} + +static SQInteger base_compilestring(HSQUIRRELVM v) +{ + SQInteger nargs=sq_gettop(v); + const SQChar *src=NULL,*name=_SC("unnamedbuffer"); + SQInteger size; + sq_getstring(v,2,&src); + size=sq_getsize(v,2); + if(nargs>2){ + sq_getstring(v,3,&name); + } + if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) + return 1; + else + return SQ_ERROR; +} + +static SQInteger base_newthread(HSQUIRRELVM v) +{ + SQObjectPtr &func = stack_get(v,2); + SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; + HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); + sq_move(newv,v,-2); + return 1; +} + +static SQInteger base_suspend(HSQUIRRELVM v) +{ + return sq_suspendvm(v); +} + +static SQInteger base_array(HSQUIRRELVM v) +{ + SQArray *a; + SQObject &size = stack_get(v,2); + if(sq_gettop(v) > 2) { + a = SQArray::Create(_ss(v),0); + a->Resize(tointeger(size),stack_get(v,3)); + } + else { + a = SQArray::Create(_ss(v),tointeger(size)); + } + v->Push(a); + return 1; +} + +static SQInteger base_type(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,2); + v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); + return 1; +} + +static SQInteger base_callee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return 1; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +static const SQRegFunction base_funcs[]={ + //generic + {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, + {_SC("setdebughook"),base_setdebughook,2, NULL}, + {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, + {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, + {_SC("getroottable"),base_getroottable,1, NULL}, + {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, + {_SC("assert"),base_assert,-2, NULL}, + {_SC("print"),base_print,2, NULL}, + {_SC("error"),base_error,2, NULL}, + {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, + {_SC("newthread"),base_newthread,2, _SC(".c")}, + {_SC("suspend"),base_suspend,-1, NULL}, + {_SC("array"),base_array,-2, _SC(".n")}, + {_SC("type"),base_type,2, NULL}, + {_SC("callee"),base_callee,0,NULL}, + {_SC("dummy"),base_dummy,0,NULL}, +#ifndef NO_GARBAGE_COLLECTOR + {_SC("collectgarbage"),base_collectgarbage,0, NULL}, + {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, +#endif + {NULL,(SQFUNCTION)0,0,NULL} +}; + +void sq_base_register(HSQUIRRELVM v) +{ + SQInteger i=0; + sq_pushroottable(v); + while(base_funcs[i].name!=0) { + sq_pushstring(v,base_funcs[i].name,-1); + sq_newclosure(v,base_funcs[i].f,0); + sq_setnativeclosurename(v,-1,base_funcs[i].name); + sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); + sq_newslot(v,-3, SQFalse); + i++; + } + + sq_pushstring(v,_SC("_versionnumber_"),-1); + sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_charsize_"),-1); + sq_pushinteger(v,sizeof(SQChar)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_intsize_"),-1); + sq_pushinteger(v,sizeof(SQInteger)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_newslot(v,-3, SQFalse); + sq_pop(v,1); +} + +static SQInteger default_delegate_len(HSQUIRRELVM v) +{ + v->Push(SQInteger(sq_getsize(v,1))); + return 1; +} + +static SQInteger default_delegate_tofloat(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(sq_type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res,10)){ + v->Push(SQObjectPtr(tofloat(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tofloat(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tointeger(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + SQInteger base = 10; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&base); + } + switch(sq_type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res,base)){ + v->Push(SQObjectPtr(tointeger(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tointeger(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tostring(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_tostring(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger obj_delegate_weakref(HSQUIRRELVM v) +{ + sq_weakref(v,1); + return 1; +} + +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_clear(v,-1)) ? 1 : SQ_ERROR; +} + + +static SQInteger number_delegate_tochar(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQChar c = (SQChar)tointeger(o); + v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); + return 1; +} + + + +///////////////////////////////////////////////////////////////// +//TABLE DEFAULT DELEGATE + +static SQInteger table_rawdelete(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) + return SQ_ERROR; + return 1; +} + + +static SQInteger container_rawexists(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_rawget(v,-2))) { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static SQInteger container_rawset(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawset(v,-3)) ? 1 : SQ_ERROR; +} + + +static SQInteger container_rawget(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; +} + +static SQInteger table_setdelegate(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setdelegate(v,-2))) + return SQ_ERROR; + sq_push(v,-1); // -1 because sq_setdelegate pops 1 + return 1; +} + +static SQInteger table_getdelegate(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; +} + +static SQInteger table_filter(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQTable *tbl = _table(o); + SQObjectPtr ret = SQTable::Create(_ss(v),0); + + SQObjectPtr itr, key, val; + SQInteger nitr; + while((nitr = tbl->Next(false, itr, key, val)) != -1) { + itr = (SQInteger)nitr; + + v->Push(o); + v->Push(key); + v->Push(val); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + if(!SQVM::IsFalse(v->GetUp(-1))) { + _table(ret)->NewSlot(key, val); + } + v->Pop(); + } + + v->Push(ret); + return 1; +} + +#define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \ +{ \ + SQObject &o = stack_get(v, 1); \ + SQTable *t = _table(o); \ + SQObjectPtr itr, key, val; \ + SQObjectPtr _null; \ + SQInteger nitr, n = 0; \ + SQInteger nitems = t->CountUsed(); \ + SQArray *a = SQArray::Create(_ss(v), nitems); \ + a->Resize(nitems, _null); \ + if (nitems) { \ + while ((nitr = t->Next(false, itr, key, val)) != -1) { \ + itr = (SQInteger)nitr; \ + a->Set(n, _valname_); \ + n++; \ + } \ + } \ + v->Push(a); \ + return 1; \ +} + +TABLE_TO_ARRAY_FUNC(table_keys, key) +TABLE_TO_ARRAY_FUNC(table_values, val) + + +const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("t")}, + {_SC("rawget"),container_rawget,2, _SC("t")}, + {_SC("rawset"),container_rawset,3, _SC("t")}, + {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, + {_SC("rawin"),container_rawexists,2, _SC("t")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, + {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, + {_SC("filter"),table_filter,2, _SC("tc")}, + {_SC("keys"),table_keys,1, _SC("t") }, + {_SC("values"),table_values,1, _SC("t") }, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//ARRAY DEFAULT DELEGATE/////////////////////////////////////// + +static SQInteger array_append(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arrayappend(v,-2)) ? 1 : SQ_ERROR; +} + +static SQInteger array_extend(HSQUIRRELVM v) +{ + _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); + sq_pop(v,1); + return 1; +} + +static SQInteger array_reverse(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arrayreverse(v,-1)) ? 1 : SQ_ERROR; +} + +static SQInteger array_pop(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; +} + +static SQInteger array_top(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + if(_array(o)->Size()>0){ + v->Push(_array(o)->Top()); + return 1; + } + else return sq_throwerror(v,_SC("top() on a empty array")); +} + +static SQInteger array_insert(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQObject &idx=stack_get(v,2); + SQObject &val=stack_get(v,3); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); + sq_pop(v,2); + return 1; +} + +static SQInteger array_remove(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &idx = stack_get(v, 2); + if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); + SQObjectPtr val; + if(_array(o)->Get(tointeger(idx), val)) { + _array(o)->Remove(tointeger(idx)); + v->Push(val); + return 1; + } + return sq_throwerror(v, _SC("idx out of range")); +} + +static SQInteger array_resize(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &nsize = stack_get(v, 2); + SQObjectPtr fill; + if(sq_isnumeric(nsize)) { + SQInteger sz = tointeger(nsize); + if (sz<0) + return sq_throwerror(v, _SC("resizing to negative length")); + + if(sq_gettop(v) > 2) + fill = stack_get(v, 3); + _array(o)->Resize(sz,fill); + sq_settop(v, 1); + return 1; + } + return sq_throwerror(v, _SC("size must be a number")); +} + +static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { + SQObjectPtr temp; + SQInteger size = src->Size(); + SQObject &closure = stack_get(v, 2); + v->Push(closure); + + SQInteger nArgs = 0; + if(sq_type(closure) == OT_CLOSURE) { + nArgs = _closure(closure)->_function->_nparameters; + } + else if (sq_type(closure) == OT_NATIVECLOSURE) { + SQInteger nParamsCheck = _nativeclosure(closure)->_nparamscheck; + if (nParamsCheck > 0) + nArgs = nParamsCheck; + else // push all params when there is no check or only minimal count set + nArgs = 4; + } + + for(SQInteger n = 0; n < size; n++) { + src->Get(n,temp); + v->Push(src); + v->Push(temp); + if (nArgs >= 3) + v->Push(SQObjectPtr(n)); + if (nArgs >= 4) + v->Push(src); + if(SQ_FAILED(sq_call(v,nArgs,SQTrue,SQFalse))) { + return SQ_ERROR; + } + dest->Set(n,v->GetUp(-1)); + v->Pop(); + } + v->Pop(); + return 0; +} + +static SQInteger array_map(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQInteger size = _array(o)->Size(); + SQObjectPtr ret = SQArray::Create(_ss(v),size); + if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) + return SQ_ERROR; + v->Push(ret); + return 1; +} + +static SQInteger array_apply(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + if(SQ_FAILED(__map_array(_array(o),_array(o),v))) + return SQ_ERROR; + sq_pop(v,1); + return 1; +} + +static SQInteger array_reduce(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQInteger size = a->Size(); + SQObjectPtr res; + SQInteger iterStart; + if (sq_gettop(v)>2) { + res = stack_get(v,3); + iterStart = 0; + } else if (size==0) { + return 0; + } else { + a->Get(0,res); + iterStart = 1; + } + if (size > iterStart) { + SQObjectPtr other; + v->Push(stack_get(v,2)); + for (SQInteger n = iterStart; n < size; n++) { + a->Get(n,other); + v->Push(o); + v->Push(res); + v->Push(other); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + res = v->GetUp(-1); + v->Pop(); + } + v->Pop(); + } + v->Push(res); + return 1; +} + +static SQInteger array_filter(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQObjectPtr ret = SQArray::Create(_ss(v),0); + SQInteger size = a->Size(); + SQObjectPtr val; + for(SQInteger n = 0; n < size; n++) { + a->Get(n,val); + v->Push(o); + v->Push(n); + v->Push(val); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + if(!SQVM::IsFalse(v->GetUp(-1))) { + _array(ret)->Append(val); + } + v->Pop(); + } + v->Push(ret); + return 1; +} + +static SQInteger array_find(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQObjectPtr &val = stack_get(v,2); + SQArray *a = _array(o); + SQInteger size = a->Size(); + SQObjectPtr temp; + for(SQInteger n = 0; n < size; n++) { + bool res = false; + a->Get(n,temp); + if(SQVM::IsEqual(temp,val,res) && res) { + v->Push(n); + return 1; + } + } + return 0; +} + + +static bool _sort_compare(HSQUIRRELVM v, SQArray *arr, SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +{ + if(func < 0) { + if(!v->ObjCmp(a,b,ret)) return false; + } + else { + SQInteger top = sq_gettop(v); + sq_push(v, func); + sq_pushroottable(v); + v->Push(a); + v->Push(b); + SQObjectPtr *valptr = arr->_values._vals; + SQUnsignedInteger precallsize = arr->_values.size(); + if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); + return false; + } + if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { + v->Raise_Error(_SC("numeric value expected as return value of the compare function")); + return false; + } + if (precallsize != arr->_values.size() || valptr != arr->_values._vals) { + v->Raise_Error(_SC("array resized during sort operation")); + return false; + } + sq_settop(v, top); + return true; + } + return true; +} + +static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func) +{ + SQInteger maxChild; + SQInteger done = 0; + SQInteger ret; + SQInteger root2; + while (((root2 = root * 2) <= bottom) && (!done)) + { + if (root2 == bottom) { + maxChild = root2; + } + else { + if(!_sort_compare(v,arr,arr->_values[root2],arr->_values[root2 + 1],func,ret)) + return false; + if (ret > 0) { + maxChild = root2; + } + else { + maxChild = root2 + 1; + } + } + + if(!_sort_compare(v,arr,arr->_values[root],arr->_values[maxChild],func,ret)) + return false; + if (ret < 0) { + if (root == maxChild) { + v->Raise_Error(_SC("inconsistent compare function")); + return false; // We'd be swapping ourselve. The compare function is incorrect + } + + _Swap(arr->_values[root],arr->_values[maxChild]); + root = maxChild; + } + else { + done = 1; + } + } + return true; +} + +static bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger SQ_UNUSED_ARG(l), SQInteger SQ_UNUSED_ARG(r),SQInteger func) +{ + SQArray *a = _array(arr); + SQInteger i; + SQInteger array_size = a->Size(); + for (i = (array_size / 2); i >= 0; i--) { + if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false; + } + + for (i = array_size-1; i >= 1; i--) + { + _Swap(a->_values[0],a->_values[i]); + if(!_hsort_sift_down(v,a, 0, i-1,func)) return false; + } + return true; +} + +static SQInteger array_sort(HSQUIRRELVM v) +{ + SQInteger func = -1; + SQObjectPtr &o = stack_get(v,1); + if(_array(o)->Size() > 1) { + if(sq_gettop(v) == 2) func = 2; + if(!_hsort(v, o, 0, _array(o)->Size()-1, func)) + return SQ_ERROR; + + } + sq_settop(v,1); + return 1; +} + +static SQInteger array_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(get_slice_params(v,sidx,eidx,o)==-1)return -1; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range")); + SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); + SQObjectPtr t; + SQInteger count=0; + for(SQInteger i=sidx;iGet(i,t); + arr->Set(count++,t); + } + v->Push(arr); + return 1; + +} + +const SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("a")}, + {_SC("append"),array_append,2, _SC("a")}, + {_SC("extend"),array_extend,2, _SC("aa")}, + {_SC("push"),array_append,2, _SC("a")}, + {_SC("pop"),array_pop,1, _SC("a")}, + {_SC("top"),array_top,1, _SC("a")}, + {_SC("insert"),array_insert,3, _SC("an")}, + {_SC("remove"),array_remove,2, _SC("an")}, + {_SC("resize"),array_resize,-2, _SC("an")}, + {_SC("reverse"),array_reverse,1, _SC("a")}, + {_SC("sort"),array_sort,-1, _SC("ac")}, + {_SC("slice"),array_slice,-1, _SC("ann")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("map"),array_map,2, _SC("ac")}, + {_SC("apply"),array_apply,2, _SC("ac")}, + {_SC("reduce"),array_reduce,-2, _SC("ac.")}, + {_SC("filter"),array_filter,2, _SC("ac")}, + {_SC("find"),array_find,2, _SC("a.")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//STRING DEFAULT DELEGATE////////////////////////// +static SQInteger string_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; + SQInteger slen = _string(o)->_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range")); + v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); + return 1; +} + +static SQInteger string_find(HSQUIRRELVM v) +{ + SQInteger top,start_idx=0; + const SQChar *str,*substr,*ret; + if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ + if(top>2)sq_getinteger(v,3,&start_idx); + if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ + ret=scstrstr(&str[start_idx],substr); + if(ret){ + sq_pushinteger(v,(SQInteger)(ret-str)); + return 1; + } + } + return 0; + } + return sq_throwerror(v,_SC("invalid param")); +} + +#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ +{\ + SQInteger sidx,eidx; \ + SQObjectPtr str; \ + if(SQ_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \ + SQInteger slen = _string(str)->_len; \ + if(sidx < 0)sidx = slen + sidx; \ + if(eidx < 0)eidx = slen + eidx; \ + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); \ + if(eidx > slen || sidx < 0) return sq_throwerror(v,_SC("slice out of range")); \ + SQInteger len=_string(str)->_len; \ + const SQChar *sthis=_stringval(str); \ + SQChar *snew=(_ss(v)->GetScratchPad(sq_rsl(len))); \ + memcpy(snew,sthis,sq_rsl(len));\ + for(SQInteger i=sidx;iPush(SQString::Create(_ss(v),snew,len)); \ + return 1; \ +} + + +STRING_TOFUNCZ(tolower) +STRING_TOFUNCZ(toupper) + +const SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("s")}, + {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("slice"),string_slice,-1, _SC("s n n")}, + {_SC("find"),string_find,-2, _SC("s s n")}, + {_SC("tolower"),string_tolower,-1, _SC("s n n")}, + {_SC("toupper"),string_toupper,-1, _SC("s n n")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//INTEGER DEFAULT DELEGATE////////////////////////// +const SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ + {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//CLOSURE DEFAULT DELEGATE////////////////////////// +static SQInteger closure_pcall(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; +} + +static SQInteger closure_call(HSQUIRRELVM v) +{ + SQObjectPtr &c = stack_get(v, -1); + if (sq_type(c) == OT_CLOSURE && (_closure(c)->_function->_bgenerator == false)) + { + return sq_tailcall(v, sq_gettop(v) - 1); + } + return SQ_SUCCEEDED(sq_call(v, sq_gettop(v) - 1, SQTrue, SQTrue)) ? 1 : SQ_ERROR; +} + +static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) +{ + SQArray *aparams=_array(stack_get(v,2)); + SQInteger nparams=aparams->Size(); + v->Push(stack_get(v,1)); + for(SQInteger i=0;iPush(aparams->_values[i]); + return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; +} + +static SQInteger closure_acall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQTrue); +} + +static SQInteger closure_pacall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQFalse); +} + +static SQInteger closure_bindenv(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_bindenv(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getroot(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getclosureroot(v,-1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_setroot(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setclosureroot(v,-2))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getinfos(HSQUIRRELVM v) { + SQObject o = stack_get(v,1); + SQTable *res = SQTable::Create(_ss(v),4); + if(sq_type(o) == OT_CLOSURE) { + SQFunctionProto *f = _closure(o)->_function; + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); + SQObjectPtr params = SQArray::Create(_ss(v),nparams); + SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams); + for(SQInteger n = 0; n_nparameters; n++) { + _array(params)->Set((SQInteger)n,f->_parameters[n]); + } + for(SQInteger j = 0; j_ndefaultparams; j++) { + _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]); + } + if(f->_varparams) { + _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); + } + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); + res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); + res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); + res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams); + } + else { //OT_NATIVECLOSURE + SQNativeClosure *nc = _nativeclosure(o); + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); + SQObjectPtr typecheck; + if(nc->_typecheck.size() > 0) { + typecheck = + SQArray::Create(_ss(v), nc->_typecheck.size()); + for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { + _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); + } + } + res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); + } + v->Push(res); + return 1; +} + + + +const SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ + {_SC("call"),closure_call,-1, _SC("c")}, + {_SC("pcall"),closure_pcall,-1, _SC("c")}, + {_SC("acall"),closure_acall,2, _SC("ca")}, + {_SC("pacall"),closure_pacall,2, _SC("ca")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, + {_SC("getinfos"),closure_getinfos,1, _SC("c")}, + {_SC("getroot"),closure_getroot,1, _SC("c")}, + {_SC("setroot"),closure_setroot,2, _SC("ct")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//GENERATOR DEFAULT DELEGATE +static SQInteger generator_getstatus(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + switch(_generator(o)->_state){ + case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; + case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; + } + return 1; +} + +const SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ + {_SC("getstatus"),generator_getstatus,1, _SC("g")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//THREAD DEFAULT DELEGATE +static SQInteger thread_call(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(sq_type(o) == OT_THREAD) { + SQInteger nparams = sq_gettop(v); + _thread(o)->Push(_thread(o)->_roottable); + for(SQInteger i = 2; i<(nparams+1); i++) + sq_move(_thread(o),v,i); + if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) { + sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); + return 1; + } + v->_lasterror = _thread(o)->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeup(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(sq_type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + SQInteger wakeupret = sq_gettop(v)>1?SQTrue:SQFalse; + if(wakeupret) { + sq_move(thread,v,2); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeupthrow(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(sq_type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + sq_move(thread,v,2); + sq_throwobject(thread); + SQBool rethrow_error = SQTrue; + if(sq_gettop(v) > 2) { + sq_getbool(v,3,&rethrow_error); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,SQFalse,SQTrue,SQTrue,SQTrue))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + if(rethrow_error) { + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_getstatus(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,1); + switch(sq_getvmstate(_thread(o))) { + case SQ_VMSTATE_IDLE: + sq_pushstring(v,_SC("idle"),-1); + break; + case SQ_VMSTATE_RUNNING: + sq_pushstring(v,_SC("running"),-1); + break; + case SQ_VMSTATE_SUSPENDED: + sq_pushstring(v,_SC("suspended"),-1); + break; + default: + return sq_throwerror(v,_SC("internal VM error")); + } + return 1; +} + +static SQInteger thread_getstackinfos(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(sq_type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger threadtop = sq_gettop(thread); + SQInteger level; + sq_getinteger(v,-1,&level); + SQRESULT res = __getcallstackinfos(thread,level); + if(SQ_FAILED(res)) + { + sq_settop(thread,threadtop); + if(sq_type(thread->_lasterror) == OT_STRING) { + sq_throwerror(v,_stringval(thread->_lasterror)); + } + else { + sq_throwerror(v,_SC("unknown error")); + } + } + if(res > 0) { + //some result + sq_move(v,thread,-1); + sq_settop(thread,threadtop); + return 1; + } + //no result + sq_settop(thread,threadtop); + return 0; + + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +const SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { + {_SC("call"), thread_call, -1, _SC("v")}, + {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, + {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")}, + {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +static SQInteger class_getattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; +} + +static SQInteger class_setattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; +} + +static SQInteger class_instance(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_getbase(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_newmember(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + SQBool bstatic = SQFalse; + if(top == 5) + { + sq_tobool(v,-1,&bstatic); + sq_pop(v,1); + } + + if(top < 4) { + sq_pushnull(v); + } + return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR; +} + +static SQInteger class_rawnewmember(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + SQBool bstatic = SQFalse; + if(top == 5) + { + sq_tobool(v,-1,&bstatic); + sq_pop(v,1); + } + + if(top < 4) { + sq_pushnull(v); + } + return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR; +} + +const SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { + {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, + {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, + {_SC("rawget"),container_rawget,2, _SC("y")}, + {_SC("rawset"),container_rawset,3, _SC("y")}, + {_SC("rawin"),container_rawexists,2, _SC("y")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("instance"),class_instance,1, _SC("y")}, + {_SC("getbase"),class_getbase,1, _SC("y")}, + {_SC("newmember"),class_newmember,-3, _SC("y")}, + {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + + +static SQInteger instance_getclass(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getclass(v,1))) + return 1; + return SQ_ERROR; +} + +const SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { + {_SC("getclass"), instance_getclass, 1, _SC("x")}, + {_SC("rawget"),container_rawget,2, _SC("x")}, + {_SC("rawset"),container_rawset,3, _SC("x")}, + {_SC("rawin"),container_rawexists,2, _SC("x")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +static SQInteger weakref_ref(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getweakrefval(v,1))) + return SQ_ERROR; + return 1; +} + +const SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { + {_SC("ref"),weakref_ref,1, _SC("r")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; diff --git a/vscript/squirrel/squirrel/sqclass.cpp b/vscript/squirrel/squirrel/sqclass.cpp new file mode 100644 index 00000000..53a29763 --- /dev/null +++ b/vscript/squirrel/squirrel/sqclass.cpp @@ -0,0 +1,213 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqclass.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + + + +SQClass::SQClass(SQSharedState *ss,SQClass *base) +{ + _base = base; + _typetag = 0; + _hook = NULL; + _udsize = 0; + _locked = false; + _constructoridx = -1; + if(_base) { + _constructoridx = _base->_constructoridx; + _udsize = _base->_udsize; + _defaultvalues.copy(base->_defaultvalues); + _methods.copy(base->_methods); + _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); + __ObjAddRef(_base); + } + _members = base?base->_members->Clone() : SQTable::Create(ss,0); + __ObjAddRef(_members); + + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +void SQClass::Finalize() { + _attributes.Null(); + _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); + _methods.resize(0); + _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); + __ObjRelease(_members); + if(_base) { + __ObjRelease(_base); + } +} + +SQClass::~SQClass() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + Finalize(); +} + +bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + SQObjectPtr temp; + bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic; + if(_locked && !belongs_to_static_table) + return false; //the class already has an instance so cannot be modified + if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value + { + _defaultvalues[_member_idx(temp)].val = val; + return true; + } + if (_members->CountUsed() >= MEMBER_MAX_COUNT) { + return false; + } + if(belongs_to_static_table) { + SQInteger mmidx; + if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) && + (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { + _metamethods[mmidx] = val; + } + else { + SQObjectPtr theval = val; + if(_base && sq_type(val) == OT_CLOSURE) { + theval = _closure(val)->Clone(); + _closure(theval)->_base = _base; + __ObjAddRef(_base); //ref for the closure + } + if(sq_type(temp) == OT_NULL) { + bool isconstructor; + SQVM::IsEqual(ss->_constructoridx, key, isconstructor); + if(isconstructor) { + _constructoridx = (SQInteger)_methods.size(); + } + SQClassMember m; + m.val = theval; + _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); + _methods.push_back(m); + } + else { + _methods[_member_idx(temp)].val = theval; + } + } + return true; + } + SQClassMember m; + m.val = val; + _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); + _defaultvalues.push_back(m); + return true; +} + +SQInstance *SQClass::CreateInstance() +{ + if(!_locked) Lock(); + return SQInstance::Create(_opt_ss(this),this); +} + +SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQObjectPtr oval; + SQInteger idx = _members->Next(false,refpos,outkey,oval); + if(idx != -1) { + if(_ismethod(oval)) { + outval = _methods[_member_idx(oval)].val; + } + else { + SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; + outval = _realval(o); + } + } + return idx; +} + +bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + if(_isfield(idx)) + _defaultvalues[_member_idx(idx)].attrs = val; + else + _methods[_member_idx(idx)].attrs = val; + return true; + } + return false; +} + +bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////// +void SQInstance::Init(SQSharedState *ss) +{ + _userpointer = NULL; + _hook = NULL; + __ObjAddRef(_class); + _delegate = _class->_members; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) +{ + _memsize = memsize; + _class = c; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); + } + Init(ss); +} + +SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) +{ + _memsize = memsize; + _class = i->_class; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(i->_values[n]); + } + Init(ss); +} + +void SQInstance::Finalize() +{ + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + __ObjRelease(_class); + _NULL_SQOBJECT_VECTOR(_values,nvalues); +} + +SQInstance::~SQInstance() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + if(_class){ Finalize(); } //if _class is null it was already finalized by the GC +} + +bool SQInstance::GetMetaMethod(SQVM* SQ_UNUSED_ARG(v),SQMetaMethod mm,SQObjectPtr &res) +{ + if(sq_type(_class->_metamethods[mm]) != OT_NULL) { + res = _class->_metamethods[mm]; + return true; + } + return false; +} + +bool SQInstance::InstanceOf(SQClass *trg) +{ + SQClass *parent = _class; + while(parent != NULL) { + if(parent == trg) + return true; + parent = parent->_base; + } + return false; +} diff --git a/vscript/squirrel/squirrel/sqclass.h b/vscript/squirrel/squirrel/sqclass.h new file mode 100644 index 00000000..60d3d21b --- /dev/null +++ b/vscript/squirrel/squirrel/sqclass.h @@ -0,0 +1,163 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLASS_H_ +#define _SQCLASS_H_ + +struct SQInstance; + +struct SQClassMember { + SQObjectPtr val; + SQObjectPtr attrs; + void Null() { + val.Null(); + attrs.Null(); + } +}; + +typedef sqvector SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 +#define MEMBER_MAX_COUNT 0x00FFFFFF + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +struct SQClass : public CHAINABLE_OBJ +{ + SQClass(SQSharedState *ss,SQClass *base); +public: + static SQClass* Create(SQSharedState *ss,SQClass *base) { + SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); + new (newclass) SQClass(ss, base); + return newclass; + } + ~SQClass(); + bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } + else { + val = _methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool GetConstructor(SQObjectPtr &ctor) + { + if(_constructoridx != -1) { + ctor = _methods[_constructoridx].val; + return true; + } + return false; + } + bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); + bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); + void Lock() { _locked = true; if(_base) _base->Lock(); } + void Release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, SQClass); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_CLASS;} +#endif + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + SQInstance *CreateInstance(); + SQTable *_members; + SQClass *_base; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; + SQObjectPtr _metamethods[MT_LAST]; + SQObjectPtr _attributes; + SQUserPointer _typetag; + SQRELEASEHOOK _hook; + bool _locked; + SQInteger _constructoridx; + SQInteger _udsize; +}; + +#define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) + +struct SQInstance : public SQDelegable +{ + void Init(SQSharedState *ss); + SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); +public: + static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { + + SQInteger size = calcinstancesize(theclass); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } + return newinst; + } + SQInstance *Clone(SQSharedState *ss) + { + SQInteger size = calcinstancesize(_class); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } + return newinst; + } + ~SQInstance(); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_class->_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { + SQObjectPtr idx; + if(_class->_members->Get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; + return true; + } + return false; + } + void Release() { + _uiRef++; + if (_hook) { _hook(_userpointer,0);} + _uiRef--; + if(_uiRef > 0) return; + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_INSTANCE;} +#endif + bool InstanceOf(SQClass *trg); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + + SQClass *_class; + SQUserPointer _userpointer; + SQRELEASEHOOK _hook; + SQInteger _memsize; + SQObjectPtr _values[1]; +}; + +#endif //_SQCLASS_H_ diff --git a/vscript/squirrel/squirrel/sqclosure.h b/vscript/squirrel/squirrel/sqclosure.h new file mode 100644 index 00000000..66495b94 --- /dev/null +++ b/vscript/squirrel/squirrel/sqclosure.h @@ -0,0 +1,201 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLOSURE_H_ +#define _SQCLOSURE_H_ + + +#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) + +struct SQFunctionProto; +struct SQClass; +struct SQClosure : public CHAINABLE_OBJ +{ +private: + SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;} +public: + static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){ + SQInteger size = _CALC_CLOSURE_SIZE(func); + SQClosure *nc=(SQClosure*)SQ_MALLOC(size); + new (nc) SQClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; + nc->_root = root; + __ObjAddRef(nc->_root); + _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); + _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); + return nc; + } + void Release(){ + SQFunctionProto *f = _function; + SQInteger size = _CALC_CLOSURE_SIZE(f); + _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); + _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); + __ObjRelease(_function); + this->~SQClosure(); + sq_vm_free(this,size); + } + void SetRoot(SQWeakRef *r) + { + __ObjRelease(_root); + _root = r; + __ObjAddRef(_root); + } + SQClosure *Clone() + { + SQFunctionProto *f = _function; + SQClosure * ret = SQClosure::Create(_opt_ss(this),f,_root); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); + _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); + return ret; + } + ~SQClosure(); + + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ + SQFunctionProto *f = _function; + _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); + _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); + } + SQObjectType GetType() {return OT_CLOSURE;} +#endif + SQWeakRef *_env; + SQWeakRef *_root; + SQClass *_base; + SQFunctionProto *_function; + SQObjectPtr *_outervalues; + SQObjectPtr *_defaultparams; +}; + +////////////////////////////////////////////// +struct SQOuter : public CHAINABLE_OBJ +{ + +private: + SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } + +public: + static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) + { + SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); + new (nc) SQOuter(ss, outer); + return nc; + } + ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } + + void Release() + { + this->~SQOuter(); + sq_vm_free(this,sizeof(SQOuter)); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _value.Null(); } + SQObjectType GetType() {return OT_OUTER;} +#endif + + SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ + SQInteger _idx; /* idx in stack array, for relocation */ + SQObjectPtr _value; /* value of outer after stack frame is closed */ + SQOuter *_next; /* pointer to next outer when frame is open */ +}; + +////////////////////////////////////////////// +struct SQGenerator : public CHAINABLE_OBJ +{ + enum SQGeneratorState{eRunning,eSuspended,eDead}; +private: + SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} +public: + static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ + SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); + new (nc) SQGenerator(ss,closure); + return nc; + } + ~SQGenerator() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Kill(){ + _state=eDead; + _stack.resize(0); + _closure.Null();} + void Release(){ + sq_delete(this,SQGenerator); + } + + bool Yield(SQVM *v,SQInteger target); + bool Resume(SQVM *v,SQObjectPtr &dest); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_stack.resize(0);_closure.Null();} + SQObjectType GetType() {return OT_GENERATOR;} +#endif + SQObjectPtr _closure; + SQObjectPtrVec _stack; + SQVM::CallInfo _ci; + ExceptionsTraps _etraps; + SQGeneratorState _state; +}; + +#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) + +struct SQNativeClosure : public CHAINABLE_OBJ +{ +private: + SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} +public: + static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) + { + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); + SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); + new (nc) SQNativeClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_noutervalues = nouters; + _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); + return nc; + } + SQNativeClosure *Clone() + { + SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + ret->_name = _name; + _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); + ret->_typecheck.copy(_typecheck); + ret->_nparamscheck = _nparamscheck; + return ret; + } + ~SQNativeClosure() + { + __ObjRelease(_env); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Release(){ + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); + _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); + this->~SQNativeClosure(); + sq_free(this,size); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } + SQObjectType GetType() {return OT_NATIVECLOSURE;} +#endif + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtr *_outervalues; + SQUnsignedInteger _noutervalues; + SQWeakRef *_env; + SQFUNCTION _function; + SQObjectPtr _name; +}; + + + +#endif //_SQCLOSURE_H_ diff --git a/vscript/squirrel/squirrel/sqcompiler.cpp b/vscript/squirrel/squirrel/sqcompiler.cpp new file mode 100644 index 00000000..095edd71 --- /dev/null +++ b/vscript/squirrel/squirrel/sqcompiler.cpp @@ -0,0 +1,1611 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include +#include +#include "sqopcodes.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqlexer.h" +#include "sqvm.h" +#include "sqtable.h" + +#define EXPR 1 +#define OBJECT 2 +#define BASE 3 +#define LOCAL 4 +#define OUTER 5 + +struct SQExpState { + SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ + SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ + bool donot_get; /* signal not to deref the next value */ +}; + +#define MAX_COMPILER_ERROR_LEN 256 + +struct SQScope { + SQInteger outers; + SQInteger stacksize; +}; + +#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ + _scope.outers = _fs->_outers; \ + _scope.stacksize = _fs->GetStackSize(); + +#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ + if(_fs->CountOuters(_scope.stacksize)) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } + +#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + } \ + _scope = __oldscope__; \ + } + +#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ + if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + if(oldouters != _fs->_outers) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } \ + _scope = __oldscope__; \ + } + +#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ + SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ + _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); + +#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ + __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ + if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ + if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ + _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} + +class SQCompiler +{ +public: + SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) + { + _vm=v; + _lex.Init(_ss(v), rg, up,ThrowError,this); + _sourcename = SQString::Create(_ss(v), sourcename); + _lineinfo = lineinfo;_raiseerror = raiseerror; + _scope.outers = 0; + _scope.stacksize = 0; + _compilererror[0] = _SC('\0'); + } + static void ThrowError(void *ud, const SQChar *s) { + SQCompiler *c = (SQCompiler *)ud; + c->Error(s); + } + void Error(const SQChar *s, ...) + { + va_list vl; + va_start(vl, s); + scvsprintf(_compilererror, MAX_COMPILER_ERROR_LEN, s, vl); + va_end(vl); + longjmp(_errorjmp,1); + } + void Lex(){ _token = _lex.Lex();} + SQObject Expect(SQInteger tok) + { + + if(_token != tok) { + if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { + //do nothing + } + else { + const SQChar *etypename; + if(tok > 255) { + switch(tok) + { + case TK_IDENTIFIER: + etypename = _SC("IDENTIFIER"); + break; + case TK_STRING_LITERAL: + etypename = _SC("STRING_LITERAL"); + break; + case TK_INTEGER: + etypename = _SC("INTEGER"); + break; + case TK_FLOAT: + etypename = _SC("FLOAT"); + break; + default: + etypename = _lex.Tok2Str(tok); + } + Error(_SC("expected '%s'"), etypename); + } + Error(_SC("expected '%c'"), tok); + } + } + SQObjectPtr ret; + switch(tok) + { + case TK_IDENTIFIER: + ret = _fs->CreateString(_lex._svalue); + break; + case TK_STRING_LITERAL: + ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_INTEGER: + ret = SQObjectPtr(_lex._nvalue); + break; + case TK_FLOAT: + ret = SQObjectPtr(_lex._fvalue); + break; + } + Lex(); + return ret; + } + bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } + void OptionalSemicolon() + { + if(_token == _SC(';')) { Lex(); return; } + if(!IsEndOfStatement()) { + Error(_SC("end of statement expected (; or lf)")); + } + } + void MoveIfCurrentTargetIsLocal() { + SQInteger trg = _fs->TopTarget(); + if(_fs->IsLocal(trg)) { + trg = _fs->PopTarget(); //pops the target and moves it + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); + } + } + bool Compile(SQObjectPtr &o) + { + _debugline = 1; + _debugop = 0; + + SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); + funcstate._name = SQString::Create(_ss(_vm), _SC("main")); + _fs = &funcstate; + _fs->AddParameter(_fs->CreateString(_SC("this"))); + _fs->AddParameter(_fs->CreateString(_SC("vargv"))); + _fs->_varparams = true; + _fs->_sourcename = _sourcename; + SQInteger stacksize = _fs->GetStackSize(); + if(setjmp(_errorjmp) == 0) { + Lex(); + while(_token > 0){ + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + _fs->SetStackSize(stacksize); + _fs->AddLineInfos(_lex._currentline, _lineinfo, true); + _fs->AddInstruction(_OP_RETURN, 0xFF); + _fs->SetStackSize(0); + o =_fs->BuildProto(); +#ifdef _DEBUG_DUMP + _fs->Dump(_funcproto(o)); +#endif + } + else { + if(_raiseerror && _ss(_vm)->_compilererrorhandler) { + _ss(_vm)->_compilererrorhandler(_vm, _compilererror, sq_type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), + _lex._currentline, _lex._currentcolumn); + } + _vm->_lasterror = SQString::Create(_ss(_vm), _compilererror, -1); + return false; + } + return true; + } + void Statements() + { + while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + } + void Statement(bool closeframe = true) + { + _fs->AddLineInfos(_lex._currentline, _lineinfo); + switch(_token){ + case _SC(';'): Lex(); break; + case TK_IF: IfStatement(); break; + case TK_WHILE: WhileStatement(); break; + case TK_DO: DoWhileStatement(); break; + case TK_FOR: ForStatement(); break; + case TK_FOREACH: ForEachStatement(); break; + case TK_SWITCH: SwitchStatement(); break; + case TK_LOCAL: LocalDeclStatement(); break; + case TK_RETURN: + case TK_YIELD: { + SQOpcode op; + if(_token == TK_RETURN) { + op = _OP_RETURN; + } + else { + op = _OP_YIELD; + _fs->_bgenerator = true; + } + Lex(); + if(!IsEndOfStatement()) { + SQInteger retexp = _fs->GetCurrentPos()+1; + CommaExpr(); + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); + _fs->_returnexp = retexp; + _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); + } + else{ + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); + _fs->_returnexp = -1; + _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); + } + break;} + case TK_BREAK: + if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); + if(_fs->_breaktargets.top() > 0){ + _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_CONTINUE: + if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); + if(_fs->_continuetargets.top() > 0) { + _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_FUNCTION: + FunctionStatement(); + break; + case TK_CLASS: + ClassStatement(); + break; + case TK_ENUM: + EnumStatement(); + break; + case _SC('{'):{ + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if(closeframe) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + break; + case TK_TRY: + TryCatchStatement(); + break; + case TK_THROW: + Lex(); + CommaExpr(); + _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); + break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; + default: + CommaExpr(); + _fs->DiscardTarget(); + //_fs->PopTarget(); + break; + } + _fs->SnoozeOpt(); + } + void EmitDerefOp(SQOpcode op) + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); + } + void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) + { + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); + } + void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) + { + /* Generate code depending on the expression type */ + switch(etype) { + case LOCAL:{ + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->PushTarget(p1); + //EmitCompArithLocal(tok, p1, p1, p2); + _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); + _fs->SnoozeOpt(); + } + break; + case OBJECT: + case BASE: + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ + _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); + } + break; + case OUTER: + { + SQInteger val = _fs->TopTarget(); + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, pos); + _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); + _fs->PopTarget(); + _fs->PopTarget(); + _fs->AddInstruction(_OP_SETOUTER, _fs->PushTarget(), pos, tmp); + } + break; + } + } + void CommaExpr() + { + for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); + } + void Expression() + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + LogicalOrExp(); + switch(_token) { + case _SC('='): + case TK_NEWSLOT: + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ:{ + SQInteger op = _token; + SQInteger ds = _es.etype; + SQInteger pos = _es.epos; + if(ds == EXPR) Error(_SC("can't assign expression")); + else if(ds == BASE) Error(_SC("'base' cannot be modified")); + Lex(); Expression(); + + switch(op){ + case TK_NEWSLOT: + if(ds == OBJECT || ds == BASE) + EmitDerefOp(_OP_NEWSLOT); + else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + Error(_SC("can't 'create' a local slot")); + break; + case _SC('='): //ASSIGN + switch(ds) { + case LOCAL: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->TopTarget(); + _fs->AddInstruction(_OP_MOVE, dst, src); + } + break; + case OBJECT: + case BASE: + EmitDerefOp(_OP_SET); + break; + case OUTER: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->PushTarget(); + _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); + } + } + break; + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + EmitCompoundArith(op, ds, pos); + break; + } + } + break; + case _SC('?'): { + Lex(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger trg = _fs->PushTarget(); + Expression(); + SQInteger first_exp = _fs->PopTarget(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + SQInteger endfirstexp = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_JMP, 0, 0); + Expect(_SC(':')); + SQInteger jmppos = _fs->GetCurrentPos(); + Expression(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetInstructionParam(jzpos, 1, endfirstexp - jzpos + 1); + _fs->SnoozeOpt(); + } + break; + } + _es = es; + } + template void INVOKE_EXP(T f) + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + (this->*f)(); + _es = es; + } + template void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) + { + Lex(); + INVOKE_EXP(f); + SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); + _es.etype = EXPR; + } + void LogicalOrExp() + { + LogicalAndExp(); + for(;;) if(_token == TK_OR) { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); INVOKE_EXP(&SQCompiler::LogicalOrExp); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + _es.etype = EXPR; + break; + }else return; + } + void LogicalAndExp() + { + BitwiseOrExp(); + for(;;) switch(_token) { + case TK_AND: { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); INVOKE_EXP(&SQCompiler::LogicalAndExp); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + _es.etype = EXPR; + break; + } + + default: + return; + } + } + void BitwiseOrExp() + { + BitwiseXorExp(); + for(;;) if(_token == _SC('|')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); + }else return; + } + void BitwiseXorExp() + { + BitwiseAndExp(); + for(;;) if(_token == _SC('^')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); + }else return; + } + void BitwiseAndExp() + { + EqExp(); + for(;;) if(_token == _SC('&')) + {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); + }else return; + } + void EqExp() + { + CompExp(); + for(;;) switch(_token) { + case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; + case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; + case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; + default: return; + } + } + void CompExp() + { + ShiftExp(); + for(;;) switch(_token) { + case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; + case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; + case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; + case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; + case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::ShiftExp); break; + case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::ShiftExp); break; + default: return; + } + } + void ShiftExp() + { + PlusExp(); + for(;;) switch(_token) { + case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; + case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; + case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; + default: return; + } + } + SQOpcode ChooseArithOpByToken(SQInteger tok) + { + switch(tok) { + case TK_PLUSEQ: case '+': return _OP_ADD; + case TK_MINUSEQ: case '-': return _OP_SUB; + case TK_MULEQ: case '*': return _OP_MUL; + case TK_DIVEQ: case '/': return _OP_DIV; + case TK_MODEQ: case '%': return _OP_MOD; + default: assert(0); + } + return _OP_ADD; + } + SQInteger ChooseCompArithCharByToken(SQInteger tok) + { + SQInteger oper; + switch(tok){ + case TK_MINUSEQ: oper = '-'; break; + case TK_PLUSEQ: oper = '+'; break; + case TK_MULEQ: oper = '*'; break; + case TK_DIVEQ: oper = '/'; break; + case TK_MODEQ: oper = '%'; break; + default: oper = 0; //shut up compiler + assert(0); break; + }; + return oper; + } + void PlusExp() + { + MultExp(); + for(;;) switch(_token) { + case _SC('+'): case _SC('-'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; + default: return; + } + } + + void MultExp() + { + PrefixedExpr(); + for(;;) switch(_token) { + case _SC('*'): case _SC('/'): case _SC('%'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; + default: return; + } + } + //if 'pos' != -1 the previous variable is a local variable + void PrefixedExpr() + { + SQInteger pos = Factor(); + for(;;) { + switch(_token) { + case _SC('.'): + pos = -1; + Lex(); + + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case _SC('['): + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot break deref/or comma needed after [exp]=exp slot declaration")); + Lex(); Expression(); Expect(_SC(']')); + pos = -1; + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case TK_MINUSMINUS: + case TK_PLUSPLUS: + { + if(IsEndOfStatement()) return; + SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + switch(_es.etype) + { + case EXPR: Error(_SC("can't '++' or '--' an expression")); break; + case OBJECT: + case BASE: + if(_es.donot_get == true) { Error(_SC("can't '++' or '--' an expression")); break; } //mmh dor this make sense? + Emit2ArgsOP(_OP_PINC, diff); + break; + case LOCAL: { + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); + } + break; + case OUTER: { + SQInteger tmp1 = _fs->PushTarget(); + SQInteger tmp2 = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); + _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); + _fs->PopTarget(); + } + } + } + return; + break; + case _SC('('): + switch(_es.etype) { + case OBJECT: { + SQInteger key = _fs->PopTarget(); /* location of the key */ + SQInteger table = _fs->PopTarget(); /* location of the object */ + SQInteger closure = _fs->PushTarget(); /* location for the closure */ + SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ + _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); + } + break; + case BASE: + //Emit2ArgsOP(_OP_GET); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + case OUTER: + _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + default: + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + } + _es.etype = EXPR; + Lex(); + FunctionCallArgs(); + break; + default: return; + } + } + } + SQInteger Factor() + { + //_es.etype = EXPR; + switch(_token) + { + case TK_STRING_LITERAL: + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); + Lex(); + break; + case TK_BASE: + Lex(); + _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); + _es.etype = BASE; + _es.epos = _fs->TopTarget(); + return (_es.epos); + break; + case TK_IDENTIFIER: + case TK_CONSTRUCTOR: + case TK_THIS:{ + SQObject id; + SQObject constant; + + switch(_token) { + case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; + case TK_THIS: id = _fs->CreateString(_SC("this"),4); break; + case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor"),11); break; + } + + SQInteger pos = -1; + Lex(); + if((pos = _fs->GetLocalVariable(id)) != -1) { + /* Handle a local variable (includes 'this') */ + _fs->PushTarget(pos); + _es.etype = LOCAL; + _es.epos = pos; + } + + else if((pos = _fs->GetOuterVariable(id)) != -1) { + /* Handle a free var */ + if(NeedGet()) { + _es.epos = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); + /* _es.etype = EXPR; already default value */ + } + else { + _es.etype = OUTER; + _es.epos = pos; + } + } + + else if(_fs->IsConstant(id, constant)) { + /* Handle named constant */ + SQObjectPtr constval; + SQObject constid; + if(sq_type(constant) == OT_TABLE) { + Expect('.'); + constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid, constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); + } + } + else { + constval = constant; + } + _es.epos = _fs->PushTarget(); + + /* generate direct or literal function depending on size */ + SQObjectType ctype = sq_type(constval); + switch(ctype) { + case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; + case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; + case OT_BOOL: _fs->AddInstruction(_OP_LOADBOOL, _es.epos, _integer(constval)); break; + default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; + } + _es.etype = EXPR; + } + else { + /* Handle a non-local variable, aka a field. Push the 'this' pointer on + * the virtual stack (always found in offset 0, so no instruction needs to + * be generated), and push the key next. Generate an _OP_LOAD instruction + * for the latter. If we are not using the variable as a dref expr, generate + * the _OP_GET instruction. + */ + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + return _es.epos; + } + break; + case TK_DOUBLE_COLON: // "::" + _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); + _es.etype = OBJECT; + _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ + _es.epos = -1; + return _es.epos; + break; + case TK_NULL: + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + Lex(); + break; + case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; + case TK_TRUE: case TK_FALSE: + _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); + Lex(); + break; + case _SC('['): { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); + SQInteger apos = _fs->GetCurrentPos(),key = 0; + Lex(); + while(_token != _SC(']')) { + Expression(); + if(_token == _SC(',')) Lex(); + SQInteger val = _fs->PopTarget(); + SQInteger array = _fs->TopTarget(); + _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); + key++; + } + _fs->SetInstructionParam(apos, 1, key); + Lex(); + } + break; + case _SC('{'): + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + Lex();ParseTableOrClass(_SC(','),_SC('}')); + break; + case TK_FUNCTION: FunctionExp(_token);break; + case _SC('@'): FunctionExp(_token,true);break; + case TK_CLASS: Lex(); ClassExp();break; + case _SC('-'): + Lex(); + switch(_token) { + case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; + default: UnaryOP(_OP_NEG); + } + break; + case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; + case _SC('~'): + Lex(); + if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } + UnaryOP(_OP_BWNOT); + break; + case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; + case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; + case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; + case TK_RAWCALL: Lex(); Expect('('); FunctionCallArgs(true); break; + case TK_MINUSMINUS : + case TK_PLUSPLUS :PrefixIncDec(_token); break; + case TK_DELETE : DeleteExpr(); break; + case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); + break; + case TK___LINE__: EmitLoadConstInt(_lex._currentline,-1); Lex(); break; + case TK___FILE__: _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_sourcename)); Lex(); break; + default: Error(_SC("expression expected")); + } + _es.etype = EXPR; + return -1; + } + void EmitLoadConstInt(SQInteger value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(value <= INT_MAX && value > INT_MIN) { //does it fit in 32 bits? + _fs->AddInstruction(_OP_LOADINT, target,value); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void EmitLoadConstFloat(SQFloat value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void UnaryOP(SQOpcode op) + { + PrefixedExpr(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), src); + } + bool NeedGet() + { + switch(_token) { + case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: + case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: + return false; + case TK_PLUSPLUS: case TK_MINUSMINUS: + if (!IsEndOfStatement()) { + return false; + } + break; + } + return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); + } + void FunctionCallArgs(bool rawcall = false) + { + SQInteger nargs = 1;//this + while(_token != _SC(')')) { + Expression(); + MoveIfCurrentTargetIsLocal(); + nargs++; + if(_token == _SC(',')){ + Lex(); + if(_token == ')') Error(_SC("expression expected, found ')'")); + } + } + Lex(); + if (rawcall) { + if (nargs < 3) Error(_SC("rawcall requires at least 2 parameters (callee and this)")); + nargs -= 2; //removes callee and this from count + } + for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); + SQInteger stackbase = _fs->PopTarget(); + SQInteger closure = _fs->PopTarget(); + _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + if (_token == '{') + { + SQInteger retval = _fs->TopTarget(); + SQInteger nkeys = 0; + Lex(); + while (_token != '}') { + switch (_token) { + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + default: + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + break; + } + if (_token == ',') Lex(); + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + _fs->AddInstruction(_OP_SET, 0xFF, retval, key, val); + } + Lex(); + } + } + void ParseTableOrClass(SQInteger separator,SQInteger terminator) + { + SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; + while(_token != terminator) { + bool hasattrs = false; + bool isstatic = false; + //check if is an attribute + if(separator == ';') { + if(_token == TK_ATTR_OPEN) { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); + ParseTableOrClass(',',TK_ATTR_CLOSE); + hasattrs = true; + } + if(_token == TK_STATIC) { + isstatic = true; + Lex(); + } + } + switch(_token) { + case TK_FUNCTION: + case TK_CONSTRUCTOR:{ + SQInteger tk = _token; + Lex(); + SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); + Expect(_SC('(')); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + } + break; + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + case TK_STRING_LITERAL: //JSON + if(separator == ',') { //only works for tables + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); + Expect(_SC(':')); Expression(); + break; + } + default : + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + } + if(_token == separator) Lex();//optional comma/semicolon + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger attrs = hasattrs ? _fs->PopTarget():-1; + ((void)attrs); + assert((hasattrs && (attrs == key-1)) || !hasattrs); + unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); + SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); + } + else { + _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember + } + } + if(separator == _SC(',')) //hack recognizes a table from the separator + _fs->SetInstructionParam(tpos, 1, nkeys); + Lex(); + } + void LocalDeclStatement() + { + SQObject varname; + Lex(); + if( _token == TK_FUNCTION) { + Lex(); + varname = Expect(TK_IDENTIFIER); + Expect(_SC('(')); + CreateFunction(varname,false); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + return; + } + + do { + varname = Expect(TK_IDENTIFIER); + if(_token == _SC('=')) { + Lex(); Expression(); + SQInteger src = _fs->PopTarget(); + SQInteger dest = _fs->PushTarget(); + if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); + } + else{ + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + } + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + if(_token == _SC(',')) Lex(); else break; + } while(1); + } + void IfBlock() + { + if (_token == _SC('{')) + { + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if (true) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + else { + //BEGIN_SCOPE(); + Statement(); + if (_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + //END_SCOPE(); + } + } + void IfStatement() + { + SQInteger jmppos; + bool haselse = false; + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jnepos = _fs->GetCurrentPos(); + + + + IfBlock(); + // + /*static int n = 0; + if (_token != _SC('}') && _token != TK_ELSE) { + printf("IF %d-----------------------!!!!!!!!!\n", n); + if (n == 5) + { + printf("asd"); + } + n++; + //OptionalSemicolon(); + }*/ + + + SQInteger endifblock = _fs->GetCurrentPos(); + if(_token == TK_ELSE){ + haselse = true; + //BEGIN_SCOPE(); + _fs->AddInstruction(_OP_JMP); + jmppos = _fs->GetCurrentPos(); + Lex(); + //Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon(); + IfBlock(); + //END_SCOPE(); + _fs->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + } + _fs->SetInstructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + } + void WhileStatement() + { + SQInteger jzpos, jmppos; + jmppos = _fs->GetCurrentPos(); + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + + BEGIN_BREAKBLE_BLOCK(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + jzpos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + + END_SCOPE(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(jmppos); + } + void DoWhileStatement() + { + Lex(); + SQInteger jmptrg = _fs->GetCurrentPos(); + BEGIN_BREAKBLE_BLOCK() + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + Expect(TK_WHILE); + SQInteger continuetrg = _fs->GetCurrentPos(); + Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); + _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); + END_BREAKBLE_BLOCK(continuetrg); + } + void ForStatement() + { + Lex(); + BEGIN_SCOPE(); + Expect(_SC('(')); + if(_token == TK_LOCAL) LocalDeclStatement(); + else if(_token != _SC(';')){ + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger jmppos = _fs->GetCurrentPos(); + SQInteger jzpos = -1; + if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger expstart = _fs->GetCurrentPos() + 1; + if(_token != _SC(')')) { + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(')')); + _fs->SnoozeOpt(); + SQInteger expend = _fs->GetCurrentPos(); + SQInteger expsize = (expend - expstart) + 1; + SQInstructionVec exp; + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + exp.push_back(_fs->GetInstruction(expstart + i)); + _fs->PopInstructions(expsize); + } + BEGIN_BREAKBLE_BLOCK() + Statement(); + SQInteger continuetrg = _fs->GetCurrentPos(); + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + _fs->AddInstruction(exp[i]); + } + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); + if(jzpos> 0) _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(continuetrg); + + END_SCOPE(); + } + void ForEachStatement() + { + SQObject idxname, valname; + Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); + if(_token == _SC(',')) { + idxname = valname; + Lex(); valname = Expect(TK_IDENTIFIER); + } + else{ + idxname = _fs->CreateString(_SC("@INDEX@")); + } + Expect(TK_IN); + + //save the stack size + BEGIN_SCOPE(); + //put the table in the stack(evaluate the table expression) + Expression(); Expect(_SC(')')); + SQInteger container = _fs->TopTarget(); + //push the index local var + SQInteger indexpos = _fs->PushLocalVariable(idxname); + _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); + //push the value local var + SQInteger valuepos = _fs->PushLocalVariable(valname); + _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); + //push reference index + SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible + _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); + SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); + //generate the statement code + BEGIN_BREAKBLE_BLOCK() + Statement(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetInstructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetInstructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + END_BREAKBLE_BLOCK(foreachpos - 1); + //restore the local variable stack(remove index,val and ref idx) + _fs->PopTarget(); + END_SCOPE(); + } + void SwitchStatement() + { + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + Expect(_SC('{')); + SQInteger expr = _fs->TopTarget(); + bool bfirst = true; + SQInteger tonextcondjmp = -1; + SQInteger skipcondjmp = -1; + SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); + _fs->_breaktargets.push_back(0); + while(_token == TK_CASE) { + if(!bfirst) { + _fs->AddInstruction(_OP_JMP, 0, 0); + skipcondjmp = _fs->GetCurrentPos(); + _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + } + //condition + Lex(); Expression(); Expect(_SC(':')); + SQInteger trg = _fs->PopTarget(); + SQInteger eqtarget = trg; + bool local = _fs->IsLocal(trg); + if(local) { + eqtarget = _fs->PushTarget(); //we need to allocate a extra reg + } + _fs->AddInstruction(_OP_EQ, eqtarget, trg, expr); + _fs->AddInstruction(_OP_JZ, eqtarget, 0); + if(local) { + _fs->PopTarget(); + } + + //end condition + if(skipcondjmp != -1) { + _fs->SetInstructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + } + tonextcondjmp = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + bfirst = false; + } + if(tonextcondjmp != -1) + _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + if(_token == TK_DEFAULT) { + Lex(); Expect(_SC(':')); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + } + Expect(_SC('}')); + _fs->PopTarget(); + __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; + if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); + _fs->_breaktargets.pop_back(); + } + void FunctionStatement() + { + SQObject id; + Lex(); id = Expect(TK_IDENTIFIER); + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + + while(_token == TK_DOUBLE_COLON) { + Lex(); + id = Expect(TK_IDENTIFIER); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + } + Expect(_SC('(')); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + void ClassStatement() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype == EXPR) { + Error(_SC("invalid class name")); + } + else if(_es.etype == OBJECT || _es.etype == BASE) { + ClassExp(); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + else { + Error(_SC("cannot create a class in a local with the syntax(class )")); + } + _es = es; + } + SQObject ExpectScalar() + { + SQObject val; + val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x + switch(_token) { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = _lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = _lex._fvalue; + break; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_TRUE: + case TK_FALSE: + val._type = OT_BOOL; + val._unVal.nInteger = _token == TK_TRUE ? 1 : 0; + break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer, float")); + } + break; + default: + Error(_SC("scalar expected : integer, float, or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + } + void TryCatchStatement() + { + SQObject exid; + Lex(); + _fs->AddInstruction(_OP_PUSHTRAP,0,0); + _fs->_traps++; + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; + SQInteger trappos = _fs->GetCurrentPos(); + { + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + } + _fs->_traps--; + _fs->AddInstruction(_OP_POPTRAP, 1, 0); + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; + _fs->AddInstruction(_OP_JMP, 0, 0); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->SetInstructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); + { + BEGIN_SCOPE(); + SQInteger ex_target = _fs->PushLocalVariable(exid); + _fs->SetInstructionParam(trappos, 0, ex_target); + Statement(); + _fs->SetInstructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + END_SCOPE(); + } + } + void FunctionExp(SQInteger ftype,bool lambda = false) + { + Lex(); Expect(_SC('(')); + SQObjectPtr dummy; + CreateFunction(dummy,lambda); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); + } + void ClassExp() + { + SQInteger base = -1; + SQInteger attrs = -1; + if(_token == TK_EXTENDS) { + Lex(); Expression(); + base = _fs->TopTarget(); + } + if(_token == TK_ATTR_OPEN) { + Lex(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); + attrs = _fs->TopTarget(); + } + Expect(_SC('{')); + if(attrs != -1) _fs->PopTarget(); + if(base != -1) _fs->PopTarget(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); + ParseTableOrClass(_SC(';'),_SC('}')); + } + void DeleteExpr() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) Error(_SC("can't delete an expression")); + if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_DELETE); + } + else { + Error(_SC("cannot delete an (outer) local")); + } + _es = es; + } + void PrefixIncDec(SQInteger token) + { + SQExpState es; + SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) { + Error(_SC("can't '++' or '--' an expression")); + } + else if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_INC, diff); + } + else if(_es.etype==LOCAL) { + SQInteger src = _fs->TopTarget(); + _fs->AddInstruction(_OP_INCL, src, src, 0, diff); + + } + else if(_es.etype==OUTER) { + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); + _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); + } + _es = es; + } + void CreateFunction(SQObject &name,bool lambda = false) + { + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); + funcstate->_name = name; + SQObject paramname; + funcstate->AddParameter(_fs->CreateString(_SC("this"))); + funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; + while(_token!=_SC(')')) { + if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); + funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); + funcstate->_varparams = true; + Lex(); + if(_token != _SC(')')) Error(_SC("expected ')'")); + break; + } + else { + paramname = Expect(TK_IDENTIFIER); + funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + } + Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } + + SQFuncState *currchunk = _fs; + _fs = funcstate; + if(lambda) { + Expression(); + _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} + else { + Statement(false); + } + funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); + funcstate->AddInstruction(_OP_RETURN, -1); + funcstate->SetStackSize(0); + + SQFunctionProto *func = funcstate->BuildProto(); +#ifdef _DEBUG_DUMP + funcstate->Dump(func); +#endif + _fs = currchunk; + _fs->_functions.push_back(func); + _fs->PopChildState(); + } + void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedbreaks.back(); + funcstate->_unresolvedbreaks.pop_back(); + //set the jmp instruction + funcstate->SetInstructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + ntoresolve--; + } + } + void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedcontinues.back(); + funcstate->_unresolvedcontinues.pop_back(); + //set the jmp instruction + funcstate->SetInstructionParams(pos, 0, targetpos - pos, 0); + ntoresolve--; + } + } +private: + SQInteger _token; + SQFuncState *_fs; + SQObjectPtr _sourcename; + SQLexer _lex; + bool _lineinfo; + bool _raiseerror; + SQInteger _debugline; + SQInteger _debugop; + SQExpState _es; + SQScope _scope; + SQChar _compilererror[MAX_COMPILER_ERROR_LEN]; + jmp_buf _errorjmp; + SQVM *_vm; +}; + +bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) +{ + SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); + return p.Compile(out); +} + +#endif diff --git a/vscript/squirrel/squirrel/sqcompiler.h b/vscript/squirrel/squirrel/sqcompiler.h new file mode 100644 index 00000000..e7da6423 --- /dev/null +++ b/vscript/squirrel/squirrel/sqcompiler.h @@ -0,0 +1,79 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCOMPILER_H_ +#define _SQCOMPILER_H_ + +struct SQVM; + +#define TK_IDENTIFIER 258 +#define TK_STRING_LITERAL 259 +#define TK_INTEGER 260 +#define TK_FLOAT 261 +#define TK_BASE 262 +#define TK_DELETE 263 +#define TK_EQ 264 +#define TK_NE 265 +#define TK_LE 266 +#define TK_GE 267 +#define TK_SWITCH 268 +#define TK_ARROW 269 +#define TK_AND 270 +#define TK_OR 271 +#define TK_IF 272 +#define TK_ELSE 273 +#define TK_WHILE 274 +#define TK_BREAK 275 +#define TK_FOR 276 +#define TK_DO 277 +#define TK_NULL 278 +#define TK_FOREACH 279 +#define TK_IN 280 +#define TK_NEWSLOT 281 +#define TK_MODULO 282 +#define TK_LOCAL 283 +#define TK_CLONE 284 +#define TK_FUNCTION 285 +#define TK_RETURN 286 +#define TK_TYPEOF 287 +#define TK_UMINUS 288 +#define TK_PLUSEQ 289 +#define TK_MINUSEQ 290 +#define TK_CONTINUE 291 +#define TK_YIELD 292 +#define TK_TRY 293 +#define TK_CATCH 294 +#define TK_THROW 295 +#define TK_SHIFTL 296 +#define TK_SHIFTR 297 +#define TK_RESUME 298 +#define TK_DOUBLE_COLON 299 +#define TK_CASE 300 +#define TK_DEFAULT 301 +#define TK_THIS 302 +#define TK_PLUSPLUS 303 +#define TK_MINUSMINUS 304 +#define TK_3WAYSCMP 305 +#define TK_USHIFTR 306 +#define TK_CLASS 307 +#define TK_EXTENDS 308 +#define TK_CONSTRUCTOR 310 +#define TK_INSTANCEOF 311 +#define TK_VARPARAMS 312 +#define TK___LINE__ 313 +#define TK___FILE__ 314 +#define TK_TRUE 315 +#define TK_FALSE 316 +#define TK_MULEQ 317 +#define TK_DIVEQ 318 +#define TK_MODEQ 319 +#define TK_ATTR_OPEN 320 +#define TK_ATTR_CLOSE 321 +#define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 +#define TK_RAWCALL 325 + + + +typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); +bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); +#endif //_SQCOMPILER_H_ diff --git a/vscript/squirrel/squirrel/sqdebug.cpp b/vscript/squirrel/squirrel/sqdebug.cpp new file mode 100644 index 00000000..d55b1b2e --- /dev/null +++ b/vscript/squirrel/squirrel/sqdebug.cpp @@ -0,0 +1,118 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" + +SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + if(sq_isclosure(ci._closure)) { + SQClosure *c = _closure(ci._closure); + SQFunctionProto *proto = c->_function; + fi->funcid = proto; + fi->name = sq_type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = sq_type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); + fi->line = proto->_lineinfos[0]._line; + return SQ_OK; + } + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + memset(si, 0, sizeof(SQStackInfos)); + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + switch (sq_type(ci._closure)) { + case OT_CLOSURE:{ + SQFunctionProto *func = _closure(ci._closure)->_function; + if (sq_type(func->_name) == OT_STRING) + si->funcname = _stringval(func->_name); + if (sq_type(func->_sourcename) == OT_STRING) + si->source = _stringval(func->_sourcename); + si->line = func->GetLine(ci._ip); + } + break; + case OT_NATIVECLOSURE: + si->source = _SC("NATIVE"); + si->funcname = _SC("unknown"); + if(sq_type(_nativeclosure(ci._closure)->_name) == OT_STRING) + si->funcname = _stringval(_nativeclosure(ci._closure)->_name); + si->line = -1; + break; + default: break; //shutup compiler + } + return SQ_OK; + } + return SQ_ERROR; +} + +void SQVM::Raise_Error(const SQChar *s, ...) +{ + va_list vl; + va_start(vl, s); + SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2); + scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); + va_end(vl); + _lasterror = SQString::Create(_ss(this),_spval,-1); +} + +void SQVM::Raise_Error(const SQObjectPtr &desc) +{ + _lasterror = desc; +} + +SQString *SQVM::PrintObjVal(const SQObjectPtr &o) +{ + switch(sq_type(o)) { + case OT_STRING: return _string(o); + case OT_INTEGER: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); + return SQString::Create(_ss(this), _spval); + break; + case OT_FLOAT: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); + return SQString::Create(_ss(this), _spval); + break; + default: + return SQString::Create(_ss(this), GetTypeName(o)); + } +} + +void SQVM::Raise_IdxError(const SQObjectPtr &o) +{ + SQObjectPtr oval = PrintObjVal(o); + Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); +} + +void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) +{ + SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); + Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); +} + + +void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) +{ + SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); + SQInteger found = 0; + for(SQInteger i=0; i<16; i++) + { + SQInteger mask = ((SQInteger)1) << i; + if(typemask & (mask)) { + if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); + found ++; + StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); + } + } + Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); +} diff --git a/vscript/squirrel/squirrel/sqfuncproto.h b/vscript/squirrel/squirrel/sqfuncproto.h new file mode 100644 index 00000000..546dbabb --- /dev/null +++ b/vscript/squirrel/squirrel/sqfuncproto.h @@ -0,0 +1,154 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCTION_H_ +#define _SQFUNCTION_H_ + +#include "sqopcodes.h" + +enum SQOuterType { + otLOCAL = 0, + otOUTER = 1 +}; + +struct SQOuterVar +{ + + SQOuterVar(){} + SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) + { + _name = name; + _src=src; + _type=t; + } + SQOuterVar(const SQOuterVar &ov) + { + _type=ov._type; + _src=ov._src; + _name=ov._name; + } + SQOuterType _type; + SQObjectPtr _name; + SQObjectPtr _src; +}; + +struct SQLocalVarInfo +{ + SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} + SQLocalVarInfo(const SQLocalVarInfo &lvi) + { + _name=lvi._name; + _start_op=lvi._start_op; + _end_op=lvi._end_op; + _pos=lvi._pos; + } + SQObjectPtr _name; + SQUnsignedInteger _start_op; + SQUnsignedInteger _end_op; + SQUnsignedInteger _pos; +}; + +struct SQLineInfo { SQInteger _line;SQInteger _op; }; + +typedef sqvector SQOuterVarVec; +typedef sqvector SQLocalVarInfoVec; +typedef sqvector SQLineInfoVec; + +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ + +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ + +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ + +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ + +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) + + +struct SQFunctionProto : public CHAINABLE_OBJ +{ +private: + SQFunctionProto(SQSharedState *ss); + ~SQFunctionProto(); + +public: + static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, + SQInteger nliterals,SQInteger nparameters, + SQInteger nfunctions,SQInteger noutervalues, + SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) + { + SQFunctionProto *f; + //I compact the whole class and members in a single memory allocation + f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); + new (f) SQFunctionProto(ss); + f->_ninstructions = ninstructions; + f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; + f->_nliterals = nliterals; + f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; + f->_nparameters = nparameters; + f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; + f->_nfunctions = nfunctions; + f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; + f->_noutervalues = noutervalues; + f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; + f->_nlineinfos = nlineinfos; + f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; + f->_nlocalvarinfos = nlocalvarinfos; + f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; + f->_ndefaultparams = ndefaultparams; + + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); + _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); + //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers + _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); + return f; + } + void Release(){ + _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); + _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); + _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); + _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); + //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers + _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); + SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); + this->~SQFunctionProto(); + sq_vm_free(this,size); + } + + const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); + SQInteger GetLine(SQInstruction *curr); + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } + SQObjectType GetType() {return OT_FUNCPROTO;} +#endif + SQObjectPtr _sourcename; + SQObjectPtr _name; + SQInteger _stacksize; + bool _bgenerator; + SQInteger _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; +}; + +#endif //_SQFUNCTION_H_ diff --git a/vscript/squirrel/squirrel/sqfuncstate.cpp b/vscript/squirrel/squirrel/sqfuncstate.cpp new file mode 100644 index 00000000..779b40df --- /dev/null +++ b/vscript/squirrel/squirrel/sqfuncstate.cpp @@ -0,0 +1,649 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include "sqcompiler.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqtable.h" +#include "sqopcodes.h" +#include "sqfuncstate.h" + +#ifdef _DEBUG_DUMP +SQInstructionDesc g_InstrDesc[]={ + {_SC("_OP_LINE")}, + {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, + {_SC("_OP_TAILCALL")}, + {_SC("_OP_CALL")}, + {_SC("_OP_PREPCALL")}, + {_SC("_OP_PREPCALLK")}, + {_SC("_OP_GETK")}, + {_SC("_OP_MOVE")}, + {_SC("_OP_NEWSLOT")}, + {_SC("_OP_DELETE")}, + {_SC("_OP_SET")}, + {_SC("_OP_GET")}, + {_SC("_OP_EQ")}, + {_SC("_OP_NE")}, + {_SC("_OP_ADD")}, + {_SC("_OP_SUB")}, + {_SC("_OP_MUL")}, + {_SC("_OP_DIV")}, + {_SC("_OP_MOD")}, + {_SC("_OP_BITW")}, + {_SC("_OP_RETURN")}, + {_SC("_OP_LOADNULLS")}, + {_SC("_OP_LOADROOT")}, + {_SC("_OP_LOADBOOL")}, + {_SC("_OP_DMOVE")}, + {_SC("_OP_JMP")}, + {_SC("_OP_JCMP")}, + {_SC("_OP_JZ")}, + {_SC("_OP_SETOUTER")}, + {_SC("_OP_GETOUTER")}, + {_SC("_OP_NEWOBJ")}, + {_SC("_OP_APPENDARRAY")}, + {_SC("_OP_COMPARITH")}, + {_SC("_OP_INC")}, + {_SC("_OP_INCL")}, + {_SC("_OP_PINC")}, + {_SC("_OP_PINCL")}, + {_SC("_OP_CMP")}, + {_SC("_OP_EXISTS")}, + {_SC("_OP_INSTANCEOF")}, + {_SC("_OP_AND")}, + {_SC("_OP_OR")}, + {_SC("_OP_NEG")}, + {_SC("_OP_NOT")}, + {_SC("_OP_BWNOT")}, + {_SC("_OP_CLOSURE")}, + {_SC("_OP_YIELD")}, + {_SC("_OP_RESUME")}, + {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, + {_SC("_OP_CLONE")}, + {_SC("_OP_TYPEOF")}, + {_SC("_OP_PUSHTRAP")}, + {_SC("_OP_POPTRAP")}, + {_SC("_OP_THROW")}, + {_SC("_OP_NEWSLOTA")}, + {_SC("_OP_GETBASE")}, + {_SC("_OP_CLOSE")}, +}; +#endif +void DumpLiteral(SQObjectPtr &o) +{ + switch(sq_type(o)){ + case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; + case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; + case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; + case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler + } +} + +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) +{ + _nliterals = 0; + _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); + _sharedstate = ss; + _lastline = 0; + _optimization = true; + _parent = parent; + _stacksize = 0; + _traps = 0; + _returnexp = 0; + _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + _outers = 0; + _ss = ss; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +#ifdef _DEBUG_DUMP +void SQFuncState::Dump(SQFunctionProto *func) +{ + SQUnsignedInteger n=0,i; + SQInteger si; + scprintf(_SC("SQInstruction sizeof %d\n"),(SQInt32)sizeof(SQInstruction)); + scprintf(_SC("SQObject sizeof %d\n"), (SQInt32)sizeof(SQObject)); + scprintf(_SC("--------------------------------------------------------------------\n")); + scprintf(_SC("*****FUNCTION [%s]\n"),sq_type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); + scprintf(_SC("-----LITERALS\n")); + SQObjectPtr refidx,key,val; + SQInteger idx; + SQObjectPtrVec templiterals; + templiterals.resize(_nliterals); + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + refidx=idx; + templiterals[_integer(val)]=key; + } + for(i=0;i>\n")); + n=0; + for(i=0;i<_parameters.size();i++){ + scprintf(_SC("[%d] "), (SQInt32)n); + DumpLiteral(_parameters[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----LOCALS\n")); + for(si=0;si_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; + scprintf(_SC("[%d] %s \t%d %d\n"), (SQInt32)lvi._pos,_stringval(lvi._name), (SQInt32)lvi._start_op, (SQInt32)lvi._end_op); + n++; + } + scprintf(_SC("-----LINE INFO\n")); + for(i=0;i<_lineinfos.size();i++){ + SQLineInfo li=_lineinfos[i]; + scprintf(_SC("op [%d] line [%d] \n"), (SQInt32)li._op, (SQInt32)li._line); + n++; + } + scprintf(_SC("-----dump\n")); + n=0; + for(i=0;i<_instructions.size();i++){ + SQInstruction &inst=_instructions[i]; + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + + SQInteger lidx = inst._arg1; + scprintf(_SC("[%03d] %15s %d "), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0); + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + } + if(inst.op != _OP_DLOAD) { + scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + } + else { + scprintf(_SC(" %d "),inst._arg2); + lidx = inst._arg3; + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + scprintf(_SC("\n")); + } + } + } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } + /* else if(inst.op==_OP_ARITH){ + scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + }*/ + else { + scprintf(_SC("[%03d] %15s %d %d %d %d\n"), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + } + n++; + } + scprintf(_SC("-----\n")); + scprintf(_SC("stack size[%d]\n"), (SQInt32)func->_stacksize); + scprintf(_SC("--------------------------------------------------------------------\n\n")); +} +#endif + +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetConstant(const SQObject &cons) +{ + SQObjectPtr val; + if(!_table(_literals)->Get(cons,val)) + { + val = _nliterals; + _table(_literals)->NewSlot(cons,val); + _nliterals++; + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } + } + return _integer(val); +} + +void SQFuncState::SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +{ + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); +} + +void SQFuncState::SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val) +{ + switch(arg){ + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; + }; +} + +SQInteger SQFuncState::AllocStackPos() +{ + SQInteger npos=_vlocals.size(); + _vlocals.push_back(SQLocalVarInfo()); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); + _stacksize=_vlocals.size(); + } + return npos; +} + +SQInteger SQFuncState::PushTarget(SQInteger n) +{ + if(n!=-1){ + _targetstack.push_back(n); + return n; + } + n=AllocStackPos(); + _targetstack.push_back(n); + return n; +} + +SQInteger SQFuncState::GetUpTarget(SQInteger n){ + return _targetstack[((_targetstack.size()-1)-n)]; +} + +SQInteger SQFuncState::TopTarget(){ + return _targetstack.back(); +} +SQInteger SQFuncState::PopTarget() +{ + SQUnsignedInteger npos=_targetstack.back(); + assert(npos < _vlocals.size()); + SQLocalVarInfo &t = _vlocals[npos]; + if(sq_type(t._name)==OT_NULL){ + _vlocals.pop_back(); + } + _targetstack.pop_back(); + return npos; +} + +SQInteger SQFuncState::GetStackSize() +{ + return _vlocals.size(); +} + +SQInteger SQFuncState::CountOuters(SQInteger stacksize) +{ + SQInteger outers = 0; + SQInteger k = _vlocals.size() - 1; + while(k >= stacksize) { + SQLocalVarInfo &lvi = _vlocals[k]; + k--; + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + outers++; + } + } + return outers; +} + +void SQFuncState::SetStackSize(SQInteger n) +{ + SQInteger size=_vlocals.size(); + while(size>n){ + size--; + SQLocalVarInfo lvi = _vlocals.back(); + if(sq_type(lvi._name)!=OT_NULL){ + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + _outers--; + } + lvi._end_op = GetCurrentPos(); + _localvarinfos.push_back(lvi); + } + _vlocals.pop_back(); + } +} + +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) +{ + if(stkpos>=_vlocals.size())return false; + else if(sq_type(_vlocals[stkpos]._name)!=OT_NULL)return true; + return false; +} + +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) +{ + SQInteger pos=_vlocals.size(); + SQLocalVarInfo lvi; + lvi._name=name; + lvi._start_op=GetCurrentPos()+1; + lvi._pos=_vlocals.size(); + _vlocals.push_back(lvi); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); + return pos; +} + + + +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) +{ + SQInteger locals=_vlocals.size(); + while(locals>=1){ + SQLocalVarInfo &lvi = _vlocals[locals-1]; + if(sq_type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ + return locals-1; + } + locals--; + } + return -1; +} + +void SQFuncState::MarkLocalAsOuter(SQInteger pos) +{ + SQLocalVarInfo &lvi = _vlocals[pos]; + lvi._end_op = UINT_MINUS_ONE; + _outers++; +} + +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) +{ + SQInteger outers = _outervalues.size(); + for(SQInteger i = 0; iGetLocalVariable(name); + if(pos == -1) { + pos = _parent->GetOuterVariable(name); + if(pos != -1) { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local + return _outervalues.size() - 1; + } + } + else { + _parent->MarkLocalAsOuter(pos); + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local + return _outervalues.size() - 1; + + + } + } + return -1; +} + +void SQFuncState::AddParameter(const SQObject &name) +{ + PushLocalVariable(name); + _parameters.push_back(name); +} + +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) +{ + if(_lastline!=line || force){ + SQLineInfo li; + li._line=line;li._op=(GetCurrentPos()+1); + if(lineop)AddInstruction(_OP_LINE,0,line); + if(_lastline!=line) { + _lineinfos.push_back(li); + } + _lastline=line; + } +} + +void SQFuncState::DiscardTarget() +{ + SQInteger discardedtarget = PopTarget(); + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(pi.op) { + case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: + if(pi._arg0 == discardedtarget) { + pi._arg0 = 0xFF; + } + } + } +} + +void SQFuncState::AddInstruction(SQInstruction &i) +{ + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ //simple optimizer + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(i.op) { + case _OP_JZ: + if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { + pi.op = _OP_JCMP; + pi._arg0 = (unsigned char)pi._arg1; + pi._arg1 = i._arg1; + return; + } + break; + case _OP_SET: + case _OP_NEWSLOT: + if(i._arg0 == i._arg3) { + i._arg0 = 0xFF; + } + break; + case _OP_SETOUTER: + if(i._arg0 == i._arg2) { + i._arg0 = 0xFF; + } + break; + case _OP_RETURN: + if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { + pi.op = _OP_TAILCALL; + } else if(pi.op == _OP_CLOSE){ + pi = i; + return; + } + break; + case _OP_GET: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ + pi._arg2 = (unsigned char)i._arg1; + pi.op = _OP_GETK; + pi._arg0 = i._arg0; + + return; + } + break; + case _OP_PREPCALL: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_PREPCALLK; + pi._arg0 = i._arg0; + pi._arg2 = i._arg2; + pi._arg3 = i._arg3; + return; + } + break; + case _OP_APPENDARRAY: { + SQInteger aat = -1; + switch(pi.op) { + case _OP_LOAD: aat = AAT_LITERAL; break; + case _OP_LOADINT: aat = AAT_INT; break; + case _OP_LOADBOOL: aat = AAT_BOOL; break; + case _OP_LOADFLOAT: aat = AAT_FLOAT; break; + default: break; + } + if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_APPENDARRAY; + pi._arg0 = i._arg0; + pi._arg2 = (unsigned char)aat; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + } + break; + case _OP_MOVE: + switch(pi.op) { + case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: + case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: + + if(pi._arg0 == i._arg1) + { + pi._arg0 = i._arg0; + _optimization = false; + //_result_elimination = false; + return; + } + } + + if(pi.op == _OP_MOVE) + { + pi.op = _OP_DMOVE; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_EQ:case _OP_NE: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) + { + pi.op = i.op; + pi._arg0 = i._arg0; + pi._arg2 = i._arg2; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_LOADNULLS: + if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { + + pi._arg1 = pi._arg1 + 1; + pi.op = _OP_LOADNULLS; + return; + } + break; + case _OP_LINE: + if(pi.op == _OP_LINE) { + _instructions.pop_back(); + _lineinfos.pop_back(); + } + break; + } + } + _optimization = true; + _instructions.push_back(i); +} + +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) +{ + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); + return ns; +} + +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + +SQFunctionProto *SQFuncState::BuildProto() +{ + + SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); + + SQObjectPtr refidx,key,val; + SQInteger idx; + + f->_stacksize = _stacksize; + f->_sourcename = _sourcename; + f->_bgenerator = _bgenerator; + f->_name = _name; + + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + f->_literals[_integer(val)]=key; + refidx=idx; + } + + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; + for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; + for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; + for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } +} + +#endif diff --git a/vscript/squirrel/squirrel/sqfuncstate.h b/vscript/squirrel/squirrel/sqfuncstate.h new file mode 100644 index 00000000..130aa54f --- /dev/null +++ b/vscript/squirrel/squirrel/sqfuncstate.h @@ -0,0 +1,91 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCSTATE_H_ +#define _SQFUNCSTATE_H_ +/////////////////////////////////// +#include "squtils.h" + +struct SQFuncState +{ + SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); + ~SQFuncState(); +#ifdef _DEBUG_DUMP + void Dump(SQFunctionProto *func); +#endif + void Error(const SQChar *err); + SQFuncState *PushChildState(SQSharedState *ss); + void PopChildState(); + void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} + void AddInstruction(SQInstruction &i); + void SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); + void SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val); + SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} + void PopInstructions(SQInteger size){for(SQInteger i=0;i _childstates; + SQInteger GetConstant(const SQObject &cons); +private: + CompilerErrorFunc _errfunc; + void *_errtarget; + SQSharedState *_ss; +}; + + +#endif //_SQFUNCSTATE_H_ + diff --git a/vscript/squirrel/squirrel/sqlexer.cpp b/vscript/squirrel/squirrel/sqlexer.cpp new file mode 100644 index 00000000..6a8e7c4f --- /dev/null +++ b/vscript/squirrel/squirrel/sqlexer.cpp @@ -0,0 +1,563 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqtable.h" +#include "sqstring.h" +#include "sqcompiler.h" +#include "sqlexer.h" + +#define CUR_CHAR (_currdata) +#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} +#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) +#define NEXT() {Next();_currentcolumn++;} +#define INIT_TEMP_STRING() { _longstr.resize(0);} +#define APPEND_CHAR(c) { _longstr.push_back(c);} +#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} +#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) + +SQLexer::SQLexer(){} +SQLexer::~SQLexer() +{ + _keywords->Release(); +} + +void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) +{ + _errfunc = efunc; + _errtarget = ed; + _sharedstate = ss; + _keywords = SQTable::Create(ss, 37); + ADD_KEYWORD(while, TK_WHILE); + ADD_KEYWORD(do, TK_DO); + ADD_KEYWORD(if, TK_IF); + ADD_KEYWORD(else, TK_ELSE); + ADD_KEYWORD(break, TK_BREAK); + ADD_KEYWORD(continue, TK_CONTINUE); + ADD_KEYWORD(return, TK_RETURN); + ADD_KEYWORD(null, TK_NULL); + ADD_KEYWORD(function, TK_FUNCTION); + ADD_KEYWORD(local, TK_LOCAL); + ADD_KEYWORD(for, TK_FOR); + ADD_KEYWORD(foreach, TK_FOREACH); + ADD_KEYWORD(in, TK_IN); + ADD_KEYWORD(typeof, TK_TYPEOF); + ADD_KEYWORD(base, TK_BASE); + ADD_KEYWORD(delete, TK_DELETE); + ADD_KEYWORD(try, TK_TRY); + ADD_KEYWORD(catch, TK_CATCH); + ADD_KEYWORD(throw, TK_THROW); + ADD_KEYWORD(clone, TK_CLONE); + ADD_KEYWORD(yield, TK_YIELD); + ADD_KEYWORD(resume, TK_RESUME); + ADD_KEYWORD(switch, TK_SWITCH); + ADD_KEYWORD(case, TK_CASE); + ADD_KEYWORD(default, TK_DEFAULT); + ADD_KEYWORD(this, TK_THIS); + ADD_KEYWORD(class,TK_CLASS); + ADD_KEYWORD(extends,TK_EXTENDS); + ADD_KEYWORD(constructor,TK_CONSTRUCTOR); + ADD_KEYWORD(instanceof,TK_INSTANCEOF); + ADD_KEYWORD(true,TK_TRUE); + ADD_KEYWORD(false,TK_FALSE); + ADD_KEYWORD(static,TK_STATIC); + ADD_KEYWORD(enum,TK_ENUM); + ADD_KEYWORD(const,TK_CONST); + ADD_KEYWORD(__LINE__,TK___LINE__); + ADD_KEYWORD(__FILE__,TK___FILE__); + ADD_KEYWORD(rawcall, TK_RAWCALL); + + + _readf = rg; + _up = up; + _lasttokenline = _currentline = 1; + _currentcolumn = 0; + _prevtoken = -1; + _reached_eof = SQFalse; + Next(); +} + +void SQLexer::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +void SQLexer::Next() +{ + SQInteger t = _readf(_up); + if(t > MAX_CHAR) Error(_SC("Invalid character")); + if(t != 0) { + _currdata = (LexChar)t; + return; + } + _currdata = SQUIRREL_EOB; + _reached_eof = SQTrue; +} + +const SQChar *SQLexer::Tok2Str(SQInteger tok) +{ + SQObjectPtr itr, key, val; + SQInteger nitr; + while((nitr = _keywords->Next(false,itr, key, val)) != -1) { + itr = (SQInteger)nitr; + if(((SQInteger)_integer(val)) == tok) + return _stringval(key); + } + return NULL; +} + +void SQLexer::LexBlockComment() +{ + bool done = false; + while(!done) { + switch(CUR_CHAR) { + case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; + case _SC('\n'): _currentline++; NEXT(); continue; + case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); + default: NEXT(); + } + } +} +void SQLexer::LexLineComment() +{ + do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); +} + +SQInteger SQLexer::Lex() +{ + _lasttokenline = _currentline; + while(CUR_CHAR != SQUIRREL_EOB) { + switch(CUR_CHAR){ + case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; + case _SC('\n'): + _currentline++; + _prevtoken=_curtoken; + _curtoken=_SC('\n'); + NEXT(); + _currentcolumn=1; + continue; + case _SC('#'): LexLineComment(); continue; + case _SC('/'): + NEXT(); + switch(CUR_CHAR){ + case _SC('*'): + NEXT(); + LexBlockComment(); + continue; + case _SC('/'): + LexLineComment(); + continue; + case _SC('='): + NEXT(); + RETURN_TOKEN(TK_DIVEQ); + continue; + case _SC('>'): + NEXT(); + RETURN_TOKEN(TK_ATTR_CLOSE); + continue; + default: + RETURN_TOKEN('/'); + } + case _SC('='): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } + else { NEXT(); RETURN_TOKEN(TK_EQ); } + case _SC('<'): + NEXT(); + switch(CUR_CHAR) { + case _SC('='): + NEXT(); + if(CUR_CHAR == _SC('>')) { + NEXT(); + RETURN_TOKEN(TK_3WAYSCMP); + } + RETURN_TOKEN(TK_LE) + break; + case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; + case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; + case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; + } + RETURN_TOKEN('<'); + case _SC('>'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} + else if(CUR_CHAR == _SC('>')){ + NEXT(); + if(CUR_CHAR == _SC('>')){ + NEXT(); + RETURN_TOKEN(TK_USHIFTR); + } + RETURN_TOKEN(TK_SHIFTR); + } + else { RETURN_TOKEN('>') } + case _SC('!'): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} + else { NEXT(); RETURN_TOKEN(TK_NE); } + case _SC('@'): { + SQInteger stype; + NEXT(); + if(CUR_CHAR != _SC('"')) { + RETURN_TOKEN('@'); + } + if((stype=ReadString('"',true))!=-1) { + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('"'): + case _SC('\''): { + SQInteger stype; + if((stype=ReadString(CUR_CHAR,false))!=-1){ + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): + case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): + {SQInteger ret = CUR_CHAR; + NEXT(); RETURN_TOKEN(ret); } + case _SC('.'): + NEXT(); + if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } + NEXT(); + if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } + NEXT(); + RETURN_TOKEN(TK_VARPARAMS); + case _SC('&'): + NEXT(); + if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } + else { NEXT(); RETURN_TOKEN(TK_AND); } + case _SC('|'): + NEXT(); + if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } + else { NEXT(); RETURN_TOKEN(TK_OR); } + case _SC(':'): + NEXT(); + if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } + else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } + case _SC('*'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} + else RETURN_TOKEN('*'); + case _SC('%'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} + else RETURN_TOKEN('%'); + case _SC('-'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} + else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} + else RETURN_TOKEN('-'); + case _SC('+'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} + else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} + else RETURN_TOKEN('+'); + case SQUIRREL_EOB: + return 0; + default:{ + if (scisdigit(CUR_CHAR)) { + SQInteger ret = ReadNumber(); + RETURN_TOKEN(ret); + } + else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { + SQInteger t = ReadID(); + RETURN_TOKEN(t); + } + else { + SQInteger c = CUR_CHAR; + if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); + NEXT(); + RETURN_TOKEN(c); + } + RETURN_TOKEN(0); + } + } + } + return 0; +} + +SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len) +{ + SQObjectPtr t; + if(_keywords->GetStr(s,len, t)) { + return SQInteger(_integer(t)); + } + return TK_IDENTIFIER; +} + +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 +SQInteger SQLexer::AddUTF16(SQUnsignedInteger ch) +{ + if (ch >= 0x10000) + { + SQUnsignedInteger code = (ch - 0x10000); + APPEND_CHAR((SQChar)(0xD800 | (code >> 10))); + APPEND_CHAR((SQChar)(0xDC00 | (code & 0x3FF))); + return 2; + } + else { + APPEND_CHAR((SQChar)ch); + return 1; + } +} +#endif +#else +SQInteger SQLexer::AddUTF8(SQUnsignedInteger ch) +{ + if (ch < 0x80) { + APPEND_CHAR((char)ch); + return 1; + } + if (ch < 0x800) { + APPEND_CHAR((SQChar)((ch >> 6) | 0xC0)); + APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); + return 2; + } + if (ch < 0x10000) { + APPEND_CHAR((SQChar)((ch >> 12) | 0xE0)); + APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); + APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); + return 3; + } + if (ch < 0x110000) { + APPEND_CHAR((SQChar)((ch >> 18) | 0xF0)); + APPEND_CHAR((SQChar)(((ch >> 12) & 0x3F) | 0x80)); + APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); + APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); + return 4; + } + return 0; +} +#endif + +SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits) +{ + NEXT(); + if (!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); + SQInteger n = 0; + while (isxdigit(CUR_CHAR) && n < maxdigits) { + dest[n] = CUR_CHAR; + n++; + NEXT(); + } + dest[n] = 0; + return n; +} + +SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) +{ + INIT_TEMP_STRING(); + NEXT(); + if(IS_EOB()) return -1; + for(;;) { + while(CUR_CHAR != ndelim) { + SQInteger x = CUR_CHAR; + switch (x) { + case SQUIRREL_EOB: + Error(_SC("unfinished string")); + return -1; + case _SC('\n'): + if(!verbatim) Error(_SC("newline in a constant")); + APPEND_CHAR(CUR_CHAR); NEXT(); + _currentline++; + break; + case _SC('\\'): + if(verbatim) { + APPEND_CHAR('\\'); NEXT(); + } + else { + NEXT(); + switch(CUR_CHAR) { + case _SC('x'): { + const SQInteger maxdigits = sizeof(SQChar) * 2; + SQChar temp[maxdigits + 1]; + ProcessStringHexEscape(temp, maxdigits); + SQChar *stemp; + APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); + } + break; + case _SC('U'): + case _SC('u'): { + const SQInteger maxdigits = CUR_CHAR == 'u' ? 4 : 8; + SQChar temp[8 + 1]; + ProcessStringHexEscape(temp, maxdigits); + SQChar *stemp; +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 + AddUTF16(scstrtoul(temp, &stemp, 16)); +#else + APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); +#endif +#else + AddUTF8(scstrtoul(temp, &stemp, 16)); +#endif + } + break; + case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; + case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; + case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; + case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; + case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; + case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; + case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; + case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; + case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; + case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; + case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; + default: + Error(_SC("unrecognised escaper char")); + break; + } + } + break; + default: + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + NEXT(); + if(verbatim && CUR_CHAR == '"') { //double quotation + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + else { + break; + } + } + TERMINATE_BUFFER(); + SQInteger len = _longstr.size()-1; + if(ndelim == _SC('\'')) { + if(len == 0) Error(_SC("empty constant")); + if(len > 1) Error(_SC("constant too long")); + _nvalue = _longstr[0]; + return TK_INTEGER; + } + _svalue = &_longstr[0]; + return TK_STRING_LITERAL; +} + +void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); + else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); + else { assert(0); } + } +} + +void LexInteger(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + *res = (*res)*10+((*s++)-'0'); + } +} + +SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); + else { assert(0); } + } +} + +SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + +#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +SQInteger SQLexer::ReadNumber() +{ +#define TINT 1 +#define TFLOAT 2 +#define THEX 3 +#define TSCIENTIFIC 4 +#define TOCTAL 5 + SQInteger type = TINT, firstchar = CUR_CHAR; + SQChar *sTemp; + INIT_TEMP_STRING(); + NEXT(); + if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { + if(scisodigit(CUR_CHAR)) { + type = TOCTAL; + while(scisodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); + } + else { + NEXT(); + type = THEX; + while(isxdigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); + } + } + else { + APPEND_CHAR((int)firstchar); + while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { + if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT; + if(isexponent(CUR_CHAR)) { + if(type != TFLOAT) Error(_SC("invalid numeric format")); + type = TSCIENTIFIC; + APPEND_CHAR(CUR_CHAR); + NEXT(); + if(CUR_CHAR == '+' || CUR_CHAR == '-'){ + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); + } + + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + TERMINATE_BUFFER(); + switch(type) { + case TSCIENTIFIC: + case TFLOAT: + _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); + return TK_FLOAT; + case TINT: + LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case THEX: + LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + } + return 0; +} + +SQInteger SQLexer::ReadID() +{ + SQInteger res; + INIT_TEMP_STRING(); + do { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); + TERMINATE_BUFFER(); + res = GetIDType(&_longstr[0],_longstr.size() - 1); + if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { + _svalue = &_longstr[0]; + } + return res; +} diff --git a/vscript/squirrel/squirrel/sqlexer.h b/vscript/squirrel/squirrel/sqlexer.h new file mode 100644 index 00000000..d731c20e --- /dev/null +++ b/vscript/squirrel/squirrel/sqlexer.h @@ -0,0 +1,55 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQLEXER_H_ +#define _SQLEXER_H_ + +#ifdef SQUNICODE +typedef SQChar LexChar; +#else +typedef unsigned char LexChar; +#endif + +struct SQLexer +{ + SQLexer(); + ~SQLexer(); + void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); + void Error(const SQChar *err); + SQInteger Lex(); + const SQChar *Tok2Str(SQInteger tok); +private: + SQInteger GetIDType(const SQChar *s,SQInteger len); + SQInteger ReadString(SQInteger ndelim,bool verbatim); + SQInteger ReadNumber(); + void LexBlockComment(); + void LexLineComment(); + SQInteger ReadID(); + void Next(); +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 + SQInteger AddUTF16(SQUnsignedInteger ch); +#endif +#else + SQInteger AddUTF8(SQUnsignedInteger ch); +#endif + SQInteger ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits); + SQInteger _curtoken; + SQTable *_keywords; + SQBool _reached_eof; +public: + SQInteger _prevtoken; + SQInteger _currentline; + SQInteger _lasttokenline; + SQInteger _currentcolumn; + const SQChar *_svalue; + SQInteger _nvalue; + SQFloat _fvalue; + SQLEXREADFUNC _readf; + SQUserPointer _up; + LexChar _currdata; + SQSharedState *_sharedstate; + sqvector _longstr; + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + +#endif diff --git a/vscript/squirrel/squirrel/sqmem.cpp b/vscript/squirrel/squirrel/sqmem.cpp new file mode 100644 index 00000000..378e254b --- /dev/null +++ b/vscript/squirrel/squirrel/sqmem.cpp @@ -0,0 +1,11 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS +void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } + +void *sq_vm_realloc(void *p, SQUnsignedInteger SQ_UNUSED_ARG(oldsize), SQUnsignedInteger size){ return realloc(p, size); } + +void sq_vm_free(void *p, SQUnsignedInteger SQ_UNUSED_ARG(size)){ free(p); } +#endif diff --git a/vscript/squirrel/squirrel/sqobject.cpp b/vscript/squirrel/squirrel/sqobject.cpp new file mode 100644 index 00000000..7d7f297f --- /dev/null +++ b/vscript/squirrel/squirrel/sqobject.cpp @@ -0,0 +1,677 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqarray.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqfuncproto.h" +#include "sqclass.h" +#include "sqclosure.h" + + +const SQChar *IdType2Name(SQObjectType type) +{ + switch(_RAW_TYPE(type)) + { + case _RT_NULL:return _SC("null"); + case _RT_INTEGER:return _SC("integer"); + case _RT_FLOAT:return _SC("float"); + case _RT_BOOL:return _SC("bool"); + case _RT_STRING:return _SC("string"); + case _RT_TABLE:return _SC("table"); + case _RT_ARRAY:return _SC("array"); + case _RT_GENERATOR:return _SC("generator"); + case _RT_CLOSURE: + case _RT_NATIVECLOSURE: + return _SC("function"); + case _RT_USERDATA: + case _RT_USERPOINTER: + return _SC("userdata"); + case _RT_THREAD: return _SC("thread"); + case _RT_FUNCPROTO: return _SC("function"); + case _RT_CLASS: return _SC("class"); + case _RT_INSTANCE: return _SC("instance"); + case _RT_WEAKREF: return _SC("weakref"); + case _RT_OUTER: return _SC("outer"); + default: + return NULL; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(sq_type(obj1)); +} + +SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) +{ + SQString *str=ADD_STRING(ss,s,len); + return str; +} + +void SQString::Release() +{ + REMOVE_STRING(_sharedstate,this); +} + +SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while(idx < _len){ + outkey = (SQInteger)idx; + outval = (SQInteger)((SQUnsignedInteger)_val[idx]); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; +} + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) +{ + switch(sq_type(idx)){ + case OT_NULL: + return 0; + case OT_INTEGER: + return (SQUnsignedInteger)_integer(idx); + default: assert(0); break; + } + return 0; +} + +SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) +{ + if(!_weakref) { + sq_new(_weakref,SQWeakRef); +#if defined(SQUSEDOUBLE) && !defined(_SQ64) + _weakref->_obj._unVal.raw = 0; //clean the whole union on 32 bits with double +#endif + _weakref->_obj._type = type; + _weakref->_obj._unVal.pRefCounted = this; + } + return _weakref; +} + +SQRefCounted::~SQRefCounted() +{ + if(_weakref) { + _weakref->_obj._type = OT_NULL; + _weakref->_obj._unVal.pRefCounted = NULL; + } +} + +void SQWeakRef::Release() { + if(ISREFCOUNTED(_obj._type)) { + _obj._unVal.pRefCounted->_weakref = NULL; + } + sq_delete(this,SQWeakRef); +} + +bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { + if(_delegate) { + return _delegate->Get((*_ss(v)->_metamethods)[mm],res); + } + return false; +} + +bool SQDelegable::SetDelegate(SQTable *mt) +{ + SQTable *temp = mt; + if(temp == this) return false; + while (temp) { + if (temp->_delegate == this) return false; //cycle detected + temp = temp->_delegate; + } + if (mt) __ObjAddRef(mt); + __ObjRelease(_delegate); + _delegate = mt; + return true; +} + +bool SQGenerator::Yield(SQVM *v,SQInteger target) +{ + if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} + if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } + SQInteger size = v->_top-v->_stackbase; + + _stack.resize(size); + SQObject _this = v->_stack[v->_stackbase]; + _stack._vals[0] = ISREFCOUNTED(sq_type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(sq_type(_this))) : _this; + for(SQInteger n =1; n_stack[v->_stackbase+n]; + } + for(SQInteger j =0; j < size; j++) + { + v->_stack[v->_stackbase+j].Null(); + } + + _ci = *v->ci; + _ci._generator=NULL; + for(SQInteger i=0;i<_ci._etraps;i++) { + _etraps.push_back(v->_etraps.top()); + v->_etraps.pop_back(); + // store relative stack base and size in case of resume to other _top + SQExceptionTrap &et = _etraps.back(); + et._stackbase -= v->_stackbase; + et._stacksize -= v->_stackbase; + } + _state=eSuspended; + return true; +} + +bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) +{ + if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } + if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } + SQInteger size = _stack.size(); + SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); + assert(target>=0 && target<=255); + SQInteger newbase = v->_top; + if(!v->EnterFrame(v->_top, v->_top + size, false)) + return false; + v->ci->_generator = this; + v->ci->_target = (SQInt32)target; + v->ci->_closure = _ci._closure; + v->ci->_ip = _ci._ip; + v->ci->_literals = _ci._literals; + v->ci->_ncalls = _ci._ncalls; + v->ci->_etraps = _ci._etraps; + v->ci->_root = _ci._root; + + + for(SQInteger i=0;i<_ci._etraps;i++) { + v->_etraps.push_back(_etraps.top()); + _etraps.pop_back(); + SQExceptionTrap &et = v->_etraps.back(); + // restore absolute stack base and size + et._stackbase += newbase; + et._stacksize += newbase; + } + SQObject _this = _stack._vals[0]; + v->_stack[v->_stackbase] = sq_type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; + + for(SQInteger n = 1; n_stack[v->_stackbase+n] = _stack._vals[n]; + _stack._vals[n].Null(); + } + + _state=eRunning; + if (v->_debughook) + v->CallDebugHook(_SC('c')); + + return true; +} + +void SQArray::Extend(const SQArray *a){ + SQInteger xlen; + if((xlen=a->Size())) + for(SQInteger i=0;i_values[i]); +} + +const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) +{ + SQUnsignedInteger nvars=_nlocalvarinfos; + const SQChar *res=NULL; + if(nvars>=nseq){ + for(SQUnsignedInteger i=0;i=nop) + { + if(nseq==0){ + vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); + res=_stringval(_localvarinfos[i]._name); + break; + } + nseq--; + } + } + } + return res; +} + + +SQInteger SQFunctionProto::GetLine(SQInstruction *curr) +{ + SQInteger op = (SQInteger)(curr-_instructions); + SQInteger line=_lineinfos[0]._line; + SQInteger low = 0; + SQInteger high = _nlineinfos - 1; + SQInteger mid = 0; + while(low <= high) + { + mid = low + ((high - low) >> 1); + SQInteger curop = _lineinfos[mid]._op; + if(curop > op) + { + high = mid - 1; + } + else if(curop < op) { + if(mid < (_nlineinfos - 1) + && _lineinfos[mid + 1]._op >= op) { + break; + } + low = mid + 1; + } + else { //equal + break; + } + } + + while(mid > 0 && _lineinfos[mid]._op >= op) mid--; + + line = _lineinfos[mid]._line; + + return line; +} + +SQClosure::~SQClosure() +{ + __ObjRelease(_root); + __ObjRelease(_env); + __ObjRelease(_base); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +#define _CHECK_IO(exp) { if(!exp)return false; } +bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(write(up,dest,size) != size) { + v->Raise_Error(_SC("io error (write function failure)")); + return false; + } + return true; +} + +bool SafeRead(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(size && read(up,dest,size) != size) { + v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); + return false; + } + return true; +} + +bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) +{ + return SafeWrite(v,write,up,&tag,sizeof(tag)); +} + +bool CheckTag(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) +{ + SQUnsignedInteger32 t; + _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); + if(t != tag){ + v->Raise_Error(_SC("invalid or corrupted closure stream")); + return false; + } + return true; +} + +bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type = (SQUnsignedInteger32)sq_type(o); + _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); + switch(sq_type(o)){ + case OT_STRING: + _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); + _CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len))); + break; + case OT_BOOL: + case OT_INTEGER: + _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; + case OT_FLOAT: + _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; + case OT_NULL: + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); + return false; + } + return true; +} + +bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type; + _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); + SQObjectType t = (SQObjectType)_type; + switch(t){ + case OT_STRING:{ + SQInteger len; + _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); + _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(sq_rsl(len)),sq_rsl(len))); + o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); + } + break; + case OT_INTEGER:{ + SQInteger i; + _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; + } + case OT_BOOL:{ + SQInteger i; + _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break; + } + case OT_FLOAT:{ + SQFloat f; + _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; + } + case OT_NULL: + o.Null(); + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); + return false; + } + return true; +} + +bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); + _CHECK_IO(_function->Save(v,up,write)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); + return true; +} + +bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); + SQObjectPtr func; + _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); + ret = SQClosure::Create(_ss(v),_funcproto(func),_table(v->_roottable)->GetWeakRef(OT_TABLE)); + //FIXME: load an root for this closure + return true; +} + +SQFunctionProto::SQFunctionProto(SQSharedState *ss) +{ + _stacksize=0; + _bgenerator=false; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +SQFunctionProto::~SQFunctionProto() +{ + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + SQInteger i,nliterals = _nliterals,nparameters = _nparameters; + SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; + SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; + SQInteger ndefaultparams = _ndefaultparams; + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(WriteObject(v,up,write,_sourcename)); + _CHECK_IO(WriteObject(v,up,write,_name)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); + _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); + _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); + _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); + _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); + _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); + _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); + _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;iSave(v,up,write)); + } + _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); + _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); + _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); + return true; +} + +bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + SQInteger i, nliterals,nparameters; + SQInteger noutervalues ,nlocalvarinfos ; + SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; + SQObjectPtr sourcename, name; + SQObjectPtr o; + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(ReadObject(v, up, read, sourcename)); + _CHECK_IO(ReadObject(v, up, read, name)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); + _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); + _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); + _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); + _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); + _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); + _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); + _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + + + SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, + nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); + SQObjectPtr proto = f; //gets a ref in case of failure + f->_sourcename = sourcename; + f->_name = name; + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0;i < nliterals; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_literals[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nparameters; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_parameters[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < noutervalues; i++){ + SQUnsignedInteger type; + SQObjectPtr name; + _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); + _CHECK_IO(ReadObject(v, up, read, o)); + _CHECK_IO(ReadObject(v, up, read, name)); + f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nlocalvarinfos; i++){ + SQLocalVarInfo lvi; + _CHECK_IO(ReadObject(v, up, read, lvi._name)); + _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); + f->_localvarinfos[i] = lvi; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + for(i = 0; i < nfunctions; i++){ + _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); + f->_functions[i] = o; + } + _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); + _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); + _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); + + ret = f; + return true; +} + +#ifndef NO_GARBAGE_COLLECTOR + +#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ + _uiRef|=MARK_FLAG; + +#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ + AddToChain(chain, this); } + +void SQVM::Mark(SQCollectable **chain) +{ + START_MARK() + SQSharedState::MarkObject(_lasterror,chain); + SQSharedState::MarkObject(_errorhandler,chain); + SQSharedState::MarkObject(_debughook_closure,chain); + SQSharedState::MarkObject(_roottable, chain); + SQSharedState::MarkObject(temp_reg, chain); + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); + END_MARK() +} + +void SQArray::Mark(SQCollectable **chain) +{ + START_MARK() + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); + END_MARK() +} +void SQTable::Mark(SQCollectable **chain) +{ + START_MARK() + if(_delegate) _delegate->Mark(chain); + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + SQSharedState::MarkObject(_nodes[i].key, chain); + SQSharedState::MarkObject(_nodes[i].val, chain); + } + END_MARK() +} + +void SQClass::Mark(SQCollectable **chain) +{ + START_MARK() + _members->Mark(chain); + if(_base) _base->Mark(chain); + SQSharedState::MarkObject(_attributes, chain); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::MarkObject(_defaultvalues[i].val, chain); + SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); + } + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::MarkObject(_methods[j].val, chain); + SQSharedState::MarkObject(_methods[j].attrs, chain); + } + for(SQUnsignedInteger k =0; k< MT_LAST; k++) { + SQSharedState::MarkObject(_metamethods[k], chain); + } + END_MARK() +} + +void SQInstance::Mark(SQCollectable **chain) +{ + START_MARK() + _class->Mark(chain); + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::MarkObject(_values[i], chain); + } + END_MARK() +} + +void SQGenerator::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + SQSharedState::MarkObject(_closure, chain); + END_MARK() +} + +void SQFunctionProto::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); + for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); + END_MARK() +} + +void SQClosure::Mark(SQCollectable **chain) +{ + START_MARK() + if(_base) _base->Mark(chain); + SQFunctionProto *fp = _function; + fp->Mark(chain); + for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); + END_MARK() +} + +void SQNativeClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + END_MARK() +} + +void SQOuter::Mark(SQCollectable **chain) +{ + START_MARK() + /* If the valptr points to a closed value, that value is alive */ + if(_valptr == &_value) { + SQSharedState::MarkObject(_value, chain); + } + END_MARK() +} + +void SQUserData::Mark(SQCollectable **chain){ + START_MARK() + if(_delegate) _delegate->Mark(chain); + END_MARK() +} + +void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } + +#endif + diff --git a/vscript/squirrel/squirrel/sqobject.h b/vscript/squirrel/squirrel/sqobject.h new file mode 100644 index 00000000..a2022227 --- /dev/null +++ b/vscript/squirrel/squirrel/sqobject.h @@ -0,0 +1,353 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOBJECT_H_ +#define _SQOBJECT_H_ + +#include "squtils.h" + +#ifdef _SQ64 +#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) +#else +#define UINT_MINUS_ONE (0xFFFFFFFF) +#endif + +#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) +#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) +#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) + +struct SQSharedState; + +enum SQMetaMethod{ + MT_ADD=0, + MT_SUB=1, + MT_MUL=2, + MT_DIV=3, + MT_UNM=4, + MT_MODULO=5, + MT_SET=6, + MT_GET=7, + MT_TYPEOF=8, + MT_NEXTI=9, + MT_CMP=10, + MT_CALL=11, + MT_CLONED=12, + MT_NEWSLOT=13, + MT_DELSLOT=14, + MT_TOSTRING=15, + MT_NEWMEMBER=16, + MT_INHERITED=17, + MT_LAST = 18 +}; + +#define MM_ADD _SC("_add") +#define MM_SUB _SC("_sub") +#define MM_MUL _SC("_mul") +#define MM_DIV _SC("_div") +#define MM_UNM _SC("_unm") +#define MM_MODULO _SC("_modulo") +#define MM_SET _SC("_set") +#define MM_GET _SC("_get") +#define MM_TYPEOF _SC("_typeof") +#define MM_NEXTI _SC("_nexti") +#define MM_CMP _SC("_cmp") +#define MM_CALL _SC("_call") +#define MM_CLONED _SC("_cloned") +#define MM_NEWSLOT _SC("_newslot") +#define MM_DELSLOT _SC("_delslot") +#define MM_TOSTRING _SC("_tostring") +#define MM_NEWMEMBER _SC("_newmember") +#define MM_INHERITED _SC("_inherited") + + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ + new (&ptr[n]) type(); \ + } \ +} + +#define _DESTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ + ptr[nl].~type(); \ + } \ +} + +#define _COPY_VECTOR(dest,src,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + dest[_n_] = src[_n_]; \ + } \ +} + +#define _NULL_SQOBJECT_VECTOR(vec,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + vec[_n_].Null(); \ + } \ +} + +#define MINPOWER2 4 + +struct SQRefCounted +{ + SQUnsignedInteger _uiRef; + struct SQWeakRef *_weakref; + SQRefCounted() { _uiRef = 0; _weakref = NULL; } + virtual ~SQRefCounted(); + SQWeakRef *GetWeakRef(SQObjectType type); + virtual void Release()=0; + +}; + +struct SQWeakRef : SQRefCounted +{ + void Release(); + SQObject _obj; +}; + +#define _realval(o) (sq_type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) + +struct SQObjectPtr; + +#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ + { \ + unval.pRefCounted->_uiRef++; \ + } + +#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ + { \ + unval.pRefCounted->Release(); \ + } + +#define __ObjRelease(obj) { \ + if((obj)) { \ + (obj)->_uiRef--; \ + if((obj)->_uiRef == 0) \ + (obj)->Release(); \ + (obj) = NULL; \ + } \ +} + +#define __ObjAddRef(obj) { \ + (obj)->_uiRef++; \ +} + +#define is_delegable(t) (sq_type(t)&SQOBJECT_DELEGABLE) +#define raw_type(obj) _RAW_TYPE((obj)._type) + +#define _integer(obj) ((obj)._unVal.nInteger) +#define _float(obj) ((obj)._unVal.fFloat) +#define _string(obj) ((obj)._unVal.pString) +#define _table(obj) ((obj)._unVal.pTable) +#define _array(obj) ((obj)._unVal.pArray) +#define _closure(obj) ((obj)._unVal.pClosure) +#define _generator(obj) ((obj)._unVal.pGenerator) +#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) +#define _userdata(obj) ((obj)._unVal.pUserData) +#define _userpointer(obj) ((obj)._unVal.pUserPointer) +#define _thread(obj) ((obj)._unVal.pThread) +#define _funcproto(obj) ((obj)._unVal.pFunctionProto) +#define _class(obj) ((obj)._unVal.pClass) +#define _instance(obj) ((obj)._unVal.pInstance) +#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) +#define _weakref(obj) ((obj)._unVal.pWeakRef) +#define _outer(obj) ((obj)._unVal.pOuter) +#define _refcounted(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) + +#define _stringval(obj) (obj)._unVal.pString->_val +#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) + +#define tofloat(num) ((sq_type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) +#define tointeger(num) ((sq_type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) +///////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() +#else +#define SQ_REFOBJECT_INIT() +#endif + +#define _REF_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class * x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + assert(_unVal.pTable); \ + _unVal.pRefCounted->_uiRef++; \ + } \ + inline SQObjectPtr& operator=(_class *x) \ + { \ + SQObjectType tOldType; \ + SQObjectValue unOldVal; \ + tOldType=_type; \ + unOldVal=_unVal; \ + _type = type; \ + SQ_REFOBJECT_INIT() \ + _unVal.sym = x; \ + _unVal.pRefCounted->_uiRef++; \ + __Release(tOldType,unOldVal); \ + return *this; \ + } + +#define _SCALAR_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + } \ + inline SQObjectPtr& operator=(_class x) \ + { \ + __Release(_type,_unVal); \ + _type = type; \ + SQ_OBJECT_RAWINIT() \ + _unVal.sym = x; \ + return *this; \ + } +struct SQObjectPtr : public SQObject +{ + SQObjectPtr() + { + SQ_OBJECT_RAWINIT() + _type=OT_NULL; + _unVal.pUserPointer=NULL; + } + SQObjectPtr(const SQObjectPtr &o) + { + _type = o._type; + _unVal = o._unVal; + __AddRef(_type,_unVal); + } + SQObjectPtr(const SQObject &o) + { + _type = o._type; + _unVal = o._unVal; + __AddRef(_type,_unVal); + } + _REF_TYPE_DECL(OT_TABLE,SQTable,pTable) + _REF_TYPE_DECL(OT_CLASS,SQClass,pClass) + _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance) + _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray) + _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure) + _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure) + _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter) + _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator) + _REF_TYPE_DECL(OT_STRING,SQString,pString) + _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData) + _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef) + _REF_TYPE_DECL(OT_THREAD,SQVM,pThread) + _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto) + + _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger) + _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat) + _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer) + + SQObjectPtr(bool bBool) + { + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = bBool?1:0; + } + inline SQObjectPtr& operator=(bool b) + { + __Release(_type,_unVal); + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = b?1:0; + return *this; + } + + ~SQObjectPtr() + { + __Release(_type,_unVal); + } + + inline SQObjectPtr& operator=(const SQObjectPtr& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline SQObjectPtr& operator=(const SQObject& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline void Null() + { + SQObjectType tOldType = _type; + SQObjectValue unOldVal = _unVal; + _type = OT_NULL; + _unVal.raw = (SQRawObjectVal)NULL; + __Release(tOldType ,unOldVal); + } + private: + SQObjectPtr(const SQChar *){} //safety +}; + + +inline void _Swap(SQObject &a,SQObject &b) +{ + SQObjectType tOldType = a._type; + SQObjectValue unOldVal = a._unVal; + a._type = b._type; + a._unVal = b._unVal; + b._type = tOldType; + b._unVal = unOldVal; +} + +///////////////////////////////////////////////////////////////////////////////////// +#ifndef NO_GARBAGE_COLLECTOR +#define MARK_FLAG 0x80000000 +struct SQCollectable : public SQRefCounted { + SQCollectable *_next; + SQCollectable *_prev; + SQSharedState *_sharedstate; + virtual SQObjectType GetType()=0; + virtual void Release()=0; + virtual void Mark(SQCollectable **chain)=0; + void UnMark(); + virtual void Finalize()=0; + static void AddToChain(SQCollectable **chain,SQCollectable *c); + static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); +}; + + +#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) +#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} +#define CHAINABLE_OBJ SQCollectable +#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} +#else + +#define ADD_TO_CHAIN(chain,obj) ((void)0) +#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) +#define CHAINABLE_OBJ SQRefCounted +#define INIT_CHAIN() ((void)0) +#endif + +struct SQDelegable : public CHAINABLE_OBJ { + bool SetDelegate(SQTable *m); + virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + SQTable *_delegate; +}; + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); +typedef sqvector SQObjectPtrVec; +typedef sqvector SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + + + +#endif //_SQOBJECT_H_ diff --git a/vscript/squirrel/squirrel/sqopcodes.h b/vscript/squirrel/squirrel/sqopcodes.h new file mode 100644 index 00000000..15d80e4b --- /dev/null +++ b/vscript/squirrel/squirrel/sqopcodes.h @@ -0,0 +1,132 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOPCODES_H_ +#define _SQOPCODES_H_ + +#define MAX_FUNC_STACKSIZE 0xFF +#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) + +enum BitWiseOP { + BW_AND = 0, + BW_OR = 2, + BW_XOR = 3, + BW_SHIFTL = 4, + BW_SHIFTR = 5, + BW_USHIFTR = 6 +}; + +enum CmpOP { + CMP_G = 0, + CMP_GE = 2, + CMP_L = 3, + CMP_LE = 4, + CMP_3W = 5 +}; + +enum NewObjectType { + NOT_TABLE = 0, + NOT_ARRAY = 1, + NOT_CLASS = 2 +}; + +enum AppendArrayType { + AAT_STACK = 0, + AAT_LITERAL = 1, + AAT_INT = 2, + AAT_FLOAT = 3, + AAT_BOOL = 4 +}; + +enum SQOpcode +{ + _OP_LINE= 0x00, + _OP_LOAD= 0x01, + _OP_LOADINT= 0x02, + _OP_LOADFLOAT= 0x03, + _OP_DLOAD= 0x04, + _OP_TAILCALL= 0x05, + _OP_CALL= 0x06, + _OP_PREPCALL= 0x07, + _OP_PREPCALLK= 0x08, + _OP_GETK= 0x09, + _OP_MOVE= 0x0A, + _OP_NEWSLOT= 0x0B, + _OP_DELETE= 0x0C, + _OP_SET= 0x0D, + _OP_GET= 0x0E, + _OP_EQ= 0x0F, + _OP_NE= 0x10, + _OP_ADD= 0x11, + _OP_SUB= 0x12, + _OP_MUL= 0x13, + _OP_DIV= 0x14, + _OP_MOD= 0x15, + _OP_BITW= 0x16, + _OP_RETURN= 0x17, + _OP_LOADNULLS= 0x18, + _OP_LOADROOT= 0x19, + _OP_LOADBOOL= 0x1A, + _OP_DMOVE= 0x1B, + _OP_JMP= 0x1C, + //_OP_JNZ= 0x1D, + _OP_JCMP= 0x1D, + _OP_JZ= 0x1E, + _OP_SETOUTER= 0x1F, + _OP_GETOUTER= 0x20, + _OP_NEWOBJ= 0x21, + _OP_APPENDARRAY= 0x22, + _OP_COMPARITH= 0x23, + _OP_INC= 0x24, + _OP_INCL= 0x25, + _OP_PINC= 0x26, + _OP_PINCL= 0x27, + _OP_CMP= 0x28, + _OP_EXISTS= 0x29, + _OP_INSTANCEOF= 0x2A, + _OP_AND= 0x2B, + _OP_OR= 0x2C, + _OP_NEG= 0x2D, + _OP_NOT= 0x2E, + _OP_BWNOT= 0x2F, + _OP_CLOSURE= 0x30, + _OP_YIELD= 0x31, + _OP_RESUME= 0x32, + _OP_FOREACH= 0x33, + _OP_POSTFOREACH= 0x34, + _OP_CLONE= 0x35, + _OP_TYPEOF= 0x36, + _OP_PUSHTRAP= 0x37, + _OP_POPTRAP= 0x38, + _OP_THROW= 0x39, + _OP_NEWSLOTA= 0x3A, + _OP_GETBASE= 0x3B, + _OP_CLOSE= 0x3C +}; + +struct SQInstructionDesc { + const SQChar *name; +}; + +struct SQInstruction +{ + SQInstruction(){}; + SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) + { op = (unsigned char)_op; + _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; + _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; + } + + + SQInt32 _arg1; + unsigned char op; + unsigned char _arg0; + unsigned char _arg2; + unsigned char _arg3; +}; + +#include "squtils.h" +typedef sqvector SQInstructionVec; + +#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 +#define NEW_SLOT_STATIC_FLAG 0x02 + +#endif // _SQOPCODES_H_ diff --git a/vscript/squirrel/squirrel/sqpcheader.h b/vscript/squirrel/squirrel/sqpcheader.h new file mode 100644 index 00000000..8df5ef4c --- /dev/null +++ b/vscript/squirrel/squirrel/sqpcheader.h @@ -0,0 +1,20 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQPCHEADER_H_ +#define _SQPCHEADER_H_ + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#endif + +#include +#include +#include +#include +#include +#include +//squirrel stuff +#include +#include "sqobject.h" +#include "sqstate.h" + +#endif //_SQPCHEADER_H_ diff --git a/vscript/squirrel/squirrel/sqstate.cpp b/vscript/squirrel/squirrel/sqstate.cpp new file mode 100644 index 00000000..c89bdc4a --- /dev/null +++ b/vscript/squirrel/squirrel/sqstate.cpp @@ -0,0 +1,647 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "squserdata.h" +#include "sqclass.h" + +SQSharedState::SQSharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _errorfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; + _foreignptr = NULL; + _releasehook = NULL; +} + +#define newsysstring(s) { \ + _systemstrings->push_back(SQString::Create(this,s)); \ + } + +#define newmetamethod(s) { \ + _metamethods->push_back(SQString::Create(this,s)); \ + _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ + } + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask) +{ + SQInteger i = 0; + SQInteger mask = 0; + while(typemask[i] != 0) { + switch(typemask[i]) { + case 'o': mask |= _RT_NULL; break; + case 'i': mask |= _RT_INTEGER; break; + case 'f': mask |= _RT_FLOAT; break; + case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; + case 's': mask |= _RT_STRING; break; + case 't': mask |= _RT_TABLE; break; + case 'a': mask |= _RT_ARRAY; break; + case 'u': mask |= _RT_USERDATA; break; + case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; + case 'b': mask |= _RT_BOOL; break; + case 'g': mask |= _RT_GENERATOR; break; + case 'p': mask |= _RT_USERPOINTER; break; + case 'v': mask |= _RT_THREAD; break; + case 'x': mask |= _RT_INSTANCE; break; + case 'y': mask |= _RT_CLASS; break; + case 'r': mask |= _RT_WEAKREF; break; + case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; + case ' ': i++; continue; //ignores spaces + default: + return false; + } + i++; + if(typemask[i] == '|') { + i++; + if(typemask[i] == 0) + return false; + continue; + } + res.push_back(mask); + mask = 0; + + } + return true; +} + +SQTable *CreateDefaultDelegate(SQSharedState *ss,const SQRegFunction *funcz) +{ + SQInteger i=0; + SQTable *t=SQTable::Create(ss,0); + while(funcz[i].name!=0){ + SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); + nc->_nparamscheck = funcz[i].nparamscheck; + nc->_name = SQString::Create(ss,funcz[i].name); + if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) + return NULL; + t->NewSlot(SQString::Create(ss,funcz[i].name),nc); + i++; + } + return t; +} + +void SQSharedState::Init() +{ + _scratchpad=NULL; + _scratchpadsize=0; +#ifndef NO_GARBAGE_COLLECTOR + _gc_chain=NULL; +#endif + _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); + new (_stringtable) SQStringTable(this); + sq_new(_metamethods,SQObjectPtrVec); + sq_new(_systemstrings,SQObjectPtrVec); + sq_new(_types,SQObjectPtrVec); + _metamethodsmap = SQTable::Create(this,MT_LAST-1); + //adding type strings to avoid memory trashing + //types names + newsysstring(_SC("null")); + newsysstring(_SC("table")); + newsysstring(_SC("array")); + newsysstring(_SC("closure")); + newsysstring(_SC("string")); + newsysstring(_SC("userdata")); + newsysstring(_SC("integer")); + newsysstring(_SC("float")); + newsysstring(_SC("userpointer")); + newsysstring(_SC("function")); + newsysstring(_SC("generator")); + newsysstring(_SC("thread")); + newsysstring(_SC("class")); + newsysstring(_SC("instance")); + newsysstring(_SC("bool")); + //meta methods + newmetamethod(MM_ADD); + newmetamethod(MM_SUB); + newmetamethod(MM_MUL); + newmetamethod(MM_DIV); + newmetamethod(MM_UNM); + newmetamethod(MM_MODULO); + newmetamethod(MM_SET); + newmetamethod(MM_GET); + newmetamethod(MM_TYPEOF); + newmetamethod(MM_NEXTI); + newmetamethod(MM_CMP); + newmetamethod(MM_CALL); + newmetamethod(MM_CLONED); + newmetamethod(MM_NEWSLOT); + newmetamethod(MM_DELSLOT); + newmetamethod(MM_TOSTRING); + newmetamethod(MM_NEWMEMBER); + newmetamethod(MM_INHERITED); + + _constructoridx = SQString::Create(this,_SC("constructor")); + _registry = SQTable::Create(this,0); + _consts = SQTable::Create(this,0); + _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); +} + +SQSharedState::~SQSharedState() +{ + if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } + _constructoridx.Null(); + _table(_registry)->Finalize(); + _table(_consts)->Finalize(); + _table(_metamethodsmap)->Finalize(); + _registry.Null(); + _consts.Null(); + _metamethodsmap.Null(); + while(!_systemstrings->empty()) { + _systemstrings->back().Null(); + _systemstrings->pop_back(); + } + _thread(_root_vm)->Finalize(); + _root_vm.Null(); + _table_default_delegate.Null(); + _array_default_delegate.Null(); + _string_default_delegate.Null(); + _number_default_delegate.Null(); + _closure_default_delegate.Null(); + _generator_default_delegate.Null(); + _thread_default_delegate.Null(); + _class_default_delegate.Null(); + _instance_default_delegate.Null(); + _weakref_default_delegate.Null(); + _refs_table.Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + if(t) { + t->_uiRef++; + while(t) { + t->Finalize(); + nx = t->_next; + if(nx) nx->_uiRef++; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + } + } + assert(_gc_chain==NULL); //just to proove a theory + while(_gc_chain){ + _gc_chain->_uiRef++; + _gc_chain->Release(); + } +#endif + + sq_delete(_types,SQObjectPtrVec); + sq_delete(_systemstrings,SQObjectPtrVec); + sq_delete(_metamethods,SQObjectPtrVec); + sq_delete(_stringtable,SQStringTable); + if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); +} + + +SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) +{ + if(sq_type(name) != OT_STRING) + return -1; + SQObjectPtr ret; + if(_table(_metamethodsmap)->Get(name,ret)) { + return _integer(ret); + } + return -1; +} + +#ifndef NO_GARBAGE_COLLECTOR + +void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) +{ + switch(sq_type(o)){ + case OT_TABLE:_table(o)->Mark(chain);break; + case OT_ARRAY:_array(o)->Mark(chain);break; + case OT_USERDATA:_userdata(o)->Mark(chain);break; + case OT_CLOSURE:_closure(o)->Mark(chain);break; + case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; + case OT_GENERATOR:_generator(o)->Mark(chain);break; + case OT_THREAD:_thread(o)->Mark(chain);break; + case OT_CLASS:_class(o)->Mark(chain);break; + case OT_INSTANCE:_instance(o)->Mark(chain);break; + case OT_OUTER:_outer(o)->Mark(chain);break; + case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; + default: break; //shutup compiler + } +} + +void SQSharedState::RunMark(SQVM* SQ_UNUSED_ARG(vm),SQCollectable **tchain) +{ + SQVM *vms = _thread(_root_vm); + + vms->Mark(tchain); + + _refs_table.Mark(tchain); + MarkObject(_registry,tchain); + MarkObject(_consts,tchain); + MarkObject(_metamethodsmap,tchain); + MarkObject(_table_default_delegate,tchain); + MarkObject(_array_default_delegate,tchain); + MarkObject(_string_default_delegate,tchain); + MarkObject(_number_default_delegate,tchain); + MarkObject(_generator_default_delegate,tchain); + MarkObject(_thread_default_delegate,tchain); + MarkObject(_closure_default_delegate,tchain); + MarkObject(_class_default_delegate,tchain); + MarkObject(_instance_default_delegate,tchain); + MarkObject(_weakref_default_delegate,tchain); + +} + +SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *resurrected = _gc_chain; + SQCollectable *t = resurrected; + + _gc_chain = tchain; + + SQArray *ret = NULL; + if(resurrected) { + ret = SQArray::Create(this,0); + SQCollectable *rlast = NULL; + while(t) { + rlast = t; + SQObjectType type = t->GetType(); + if(type != OT_FUNCPROTO && type != OT_OUTER) { + SQObject sqo; + sqo._type = type; + sqo._unVal.pRefCounted = t; + ret->Append(sqo); + } + t = t->_next; + n++; + } + + assert(rlast->_next == NULL); + rlast->_next = _gc_chain; + if(_gc_chain) + { + _gc_chain->_prev = rlast; + } + _gc_chain = resurrected; + } + + t = _gc_chain; + while(t) { + t->UnMark(); + t = t->_next; + } + + if(ret) { + SQObjectPtr temp = ret; + vm->Push(temp); + } + else { + vm->PushNull(); + } + return n; +} + +SQInteger SQSharedState::CollectGarbage(SQVM *vm) +{ + SQInteger n = 0; + SQCollectable *tchain = NULL; + + RunMark(vm,&tchain); + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + if(t) { + t->_uiRef++; + while(t) { + t->Finalize(); + nx = t->_next; + if(nx) nx->_uiRef++; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + n++; + } + } + + t = tchain; + while(t) { + t->UnMark(); + t = t->_next; + } + _gc_chain = tchain; + + return n; +} +#endif + +#ifndef NO_GARBAGE_COLLECTOR +void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) +{ + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; +} + +void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) +{ + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; + if(c->_next) + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; +} +#endif + +SQChar* SQSharedState::GetScratchPad(SQInteger size) +{ + SQInteger newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} + +RefTable::RefTable() +{ + AllocNodes(4); +} + +void RefTable::Finalize() +{ + RefNode *nodes = _nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + nodes->obj.Null(); + nodes++; + } +} + +RefTable::~RefTable() +{ + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); +} + +#ifndef NO_GARBAGE_COLLECTOR +void RefTable::Mark(SQCollectable **chain) +{ + RefNode *nodes = (RefNode *)_nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + if(sq_type(nodes->obj) != OT_NULL) { + SQSharedState::MarkObject(nodes->obj,chain); + } + nodes++; + } +} +#endif + +void RefTable::AddRef(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + ref->refs++; +} + +SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + return ref->refs; +} + + +SQBool RefTable::Release(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,false); + if(ref) { + if(--ref->refs == 0) { + SQObjectPtr o = ref->obj; + if(prev) { + prev->next = ref->next; + } + else { + _buckets[mainpos] = ref->next; + } + ref->next = _freelist; + _freelist = ref; + _slotused--; + ref->obj.Null(); + //<>test for shrink? + return SQTrue; + } + } + else { + assert(0); + } + return SQFalse; +} + +void RefTable::Resize(SQUnsignedInteger size) +{ + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; + SQUnsignedInteger oldnumofslots = _numofslots; + AllocNodes(size); + //rehash + SQUnsignedInteger nfound = 0; + for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { + if(sq_type(t->obj) != OT_NULL) { + //add back; + assert(t->refs != 0); + RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj.Null(); + nfound++; + } + t++; + } + assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); +} + +RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) +{ + RefNode *t = _buckets[mainpos]; + RefNode *newnode = _freelist; + newnode->obj = obj; + _buckets[mainpos] = newnode; + _freelist = _freelist->next; + newnode->next = t; + assert(newnode->refs == 0); + _slotused++; + return newnode; +} + +RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) +{ + RefNode *ref; + mainpos = ::HashObj(obj)&(_numofslots-1); + *prev = NULL; + for (ref = _buckets[mainpos]; ref; ) { + if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj)) + break; + *prev = ref; + ref = ref->next; + } + if(ref == NULL && add) { + if(_numofslots == _slotused) { + assert(_freelist == 0); + Resize(_numofslots*2); + mainpos = ::HashObj(obj)&(_numofslots-1); + } + ref = Add(mainpos,obj); + } + return ref; +} + +void RefTable::AllocNodes(SQUnsignedInteger size) +{ + RefNode **bucks; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; + SQUnsignedInteger n; + for(n = 0; n < size - 1; n++) { + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = temp+1; + temp++; + } + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = NULL; + _freelist = nodes; + _nodes = nodes; + _buckets = bucks; + _slotused = 0; + _numofslots = size; +} +////////////////////////////////////////////////////////////////////////// +//SQStringTable +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_lstring.c.html +*/ + +SQStringTable::SQStringTable(SQSharedState *ss) +{ + _sharedstate = ss; + AllocNodes(4); + _slotused = 0; +} + +SQStringTable::~SQStringTable() +{ + SQ_FREE(_strings,sizeof(SQString*)*_numofslots); + _strings = NULL; +} + +void SQStringTable::AllocNodes(SQInteger size) +{ + _numofslots = size; + _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); + memset(_strings,0,sizeof(SQString*)*_numofslots); +} + +SQString *SQStringTable::Add(const SQChar *news,SQInteger len) +{ + if(len<0) + len = (SQInteger)scstrlen(news); + SQHash newhash = ::_hashstr(news,len); + SQHash h = newhash&(_numofslots-1); + SQString *s; + for (s = _strings[h]; s; s = s->_next){ + if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len)))) + return s; //found + } + + SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString)); + new (t) SQString; + t->_sharedstate = _sharedstate; + memcpy(t->_val,news,sq_rsl(len)); + t->_val[len] = _SC('\0'); + t->_len = len; + t->_hash = newhash; + t->_next = _strings[h]; + _strings[h] = t; + _slotused++; + if (_slotused > _numofslots) /* too crowded? */ + Resize(_numofslots*2); + return t; +} + +void SQStringTable::Resize(SQInteger size) +{ + SQInteger oldsize=_numofslots; + SQString **oldtable=_strings; + AllocNodes(size); + for (SQInteger i=0; i_next; + SQHash h = p->_hash&(_numofslots-1); + p->_next = _strings[h]; + _strings[h] = p; + p = next; + } + } + SQ_FREE(oldtable,oldsize*sizeof(SQString*)); +} + +void SQStringTable::Remove(SQString *bs) +{ + SQString *s; + SQString *prev=NULL; + SQHash h = bs->_hash&(_numofslots - 1); + + for (s = _strings[h]; s; ){ + if(s == bs){ + if(prev) + prev->_next = s->_next; + else + _strings[h] = s->_next; + _slotused--; + SQInteger slen = s->_len; + s->~SQString(); + SQ_FREE(s,sizeof(SQString) + sq_rsl(slen)); + return; + } + prev = s; + s = s->_next; + } + assert(0);//if this fail something is wrong +} diff --git a/vscript/squirrel/squirrel/sqstate.h b/vscript/squirrel/squirrel/sqstate.h new file mode 100644 index 00000000..2cdc8da4 --- /dev/null +++ b/vscript/squirrel/squirrel/sqstate.h @@ -0,0 +1,136 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTATE_H_ +#define _SQSTATE_H_ + +#include "squtils.h" +#include "sqobject.h" +struct SQString; +struct SQTable; +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + +struct SQStringTable +{ + SQStringTable(SQSharedState*ss); + ~SQStringTable(); + SQString *Add(const SQChar *,SQInteger len); + void Remove(SQString *); +private: + void Resize(SQInteger size); + void AllocNodes(SQInteger size); + SQString **_strings; + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + SQSharedState *_sharedstate; +}; + +struct RefTable { + struct RefNode { + SQObjectPtr obj; + SQUnsignedInteger refs; + struct RefNode *next; + }; + RefTable(); + ~RefTable(); + void AddRef(SQObject &obj); + SQBool Release(SQObject &obj); + SQUnsignedInteger GetRefCount(SQObject &obj); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Finalize(); +private: + RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); + RefNode *Add(SQHash mainpos,SQObject &obj); + void Resize(SQUnsignedInteger size); + void AllocNodes(SQUnsignedInteger size); + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + RefNode *_nodes; + RefNode *_freelist; + RefNode **_buckets; +}; + +#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) +#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) + +struct SQObjectPtr; + +struct SQSharedState +{ + SQSharedState(); + ~SQSharedState(); + void Init(); +public: + SQChar* GetScratchPad(SQInteger size); + SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); +#ifndef NO_GARBAGE_COLLECTOR + SQInteger CollectGarbage(SQVM *vm); + void RunMark(SQVM *vm,SQCollectable **tchain); + SQInteger ResurrectUnreachable(SQVM *vm); + static void MarkObject(SQObjectPtr &o,SQCollectable **chain); +#endif + SQObjectPtrVec *_metamethods; + SQObjectPtr _metamethodsmap; + SQObjectPtrVec *_systemstrings; + SQObjectPtrVec *_types; + SQStringTable *_stringtable; + RefTable _refs_table; + SQObjectPtr _registry; + SQObjectPtr _consts; + SQObjectPtr _constructoridx; +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *_gc_chain; +#endif + SQObjectPtr _root_vm; + SQObjectPtr _table_default_delegate; + static const SQRegFunction _table_default_delegate_funcz[]; + SQObjectPtr _array_default_delegate; + static const SQRegFunction _array_default_delegate_funcz[]; + SQObjectPtr _string_default_delegate; + static const SQRegFunction _string_default_delegate_funcz[]; + SQObjectPtr _number_default_delegate; + static const SQRegFunction _number_default_delegate_funcz[]; + SQObjectPtr _generator_default_delegate; + static const SQRegFunction _generator_default_delegate_funcz[]; + SQObjectPtr _closure_default_delegate; + static const SQRegFunction _closure_default_delegate_funcz[]; + SQObjectPtr _thread_default_delegate; + static const SQRegFunction _thread_default_delegate_funcz[]; + SQObjectPtr _class_default_delegate; + static const SQRegFunction _class_default_delegate_funcz[]; + SQObjectPtr _instance_default_delegate; + static const SQRegFunction _instance_default_delegate_funcz[]; + SQObjectPtr _weakref_default_delegate; + static const SQRegFunction _weakref_default_delegate_funcz[]; + + SQCOMPILERERROR _compilererrorhandler; + SQPRINTFUNCTION _printfunc; + SQPRINTFUNCTION _errorfunc; + bool _debuginfo; + bool _notifyallexceptions; + SQUserPointer _foreignptr; + SQRELEASEHOOK _releasehook; +private: + SQChar *_scratchpad; + SQInteger _scratchpadsize; +}; + +#define _sp(s) (_sharedstate->GetScratchPad(s)) +#define _spval (_sharedstate->GetScratchPad(-1)) + +#define _table_ddel _table(_sharedstate->_table_default_delegate) +#define _array_ddel _table(_sharedstate->_array_default_delegate) +#define _string_ddel _table(_sharedstate->_string_default_delegate) +#define _number_ddel _table(_sharedstate->_number_default_delegate) +#define _generator_ddel _table(_sharedstate->_generator_default_delegate) +#define _closure_ddel _table(_sharedstate->_closure_default_delegate) +#define _thread_ddel _table(_sharedstate->_thread_default_delegate) +#define _class_ddel _table(_sharedstate->_class_default_delegate) +#define _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask); + + +#endif //_SQSTATE_H_ diff --git a/vscript/squirrel/squirrel/sqstring.h b/vscript/squirrel/squirrel/sqstring.h new file mode 100644 index 00000000..82f1cdf4 --- /dev/null +++ b/vscript/squirrel/squirrel/sqstring.h @@ -0,0 +1,31 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTRING_H_ +#define _SQSTRING_H_ + +inline SQHash _hashstr (const SQChar *s, size_t l) +{ + SQHash h = (SQHash)l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); + return h; +} + +struct SQString : public SQRefCounted +{ + SQString(){} + ~SQString(){} +public: + static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + void Release(); + SQSharedState *_sharedstate; + SQString *_next; //chain for the string table + SQInteger _len; + SQHash _hash; + SQChar _val[1]; +}; + + + +#endif //_SQSTRING_H_ diff --git a/vscript/squirrel/squirrel/sqtable.cpp b/vscript/squirrel/squirrel/sqtable.cpp new file mode 100644 index 00000000..3a89c459 --- /dev/null +++ b/vscript/squirrel/squirrel/sqtable.cpp @@ -0,0 +1,221 @@ +/* +see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + +SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) +{ + SQInteger pow2size=MINPOWER2; + while(nInitialSize>pow2size)pow2size=pow2size<<1; + AllocNodes(pow2size); + _usednodes = 0; + _delegate = NULL; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); +} + +void SQTable::Remove(const SQObjectPtr &key) +{ + + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val.Null(); + n->key.Null(); + _usednodes--; + Rehash(false); + } +} + +void SQTable::AllocNodes(SQInteger nSize) +{ + _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); + for(SQInteger i=0;i= oldsize-oldsize/4) /* using more than 3/4? */ + AllocNodes(oldsize*2); + else if (nelems <= oldsize/4 && /* less than 1/4? */ + oldsize > MINPOWER2) + AllocNodes(oldsize/2); + else if(force) + AllocNodes(oldsize); + else + return; + _usednodes = 0; + for (SQInteger i=0; ikey) != OT_NULL) + NewSlot(old->key,old->val); + } + for(SQInteger k=0;k_nodes; + _HashNode *src = _nodes; + _HashNode *dst = nt->_nodes; + SQInteger n = 0; + for(n = 0; n < _numofnodes; n++) { + dst->key = src->key; + dst->val = src->val; + if(src->next) { + assert(src->next > basesrc); + dst->next = basedst + (src->next - basesrc); + assert(dst != dst->next); + } + dst++; + src++; + } + assert(_firstfree > basesrc); + assert(_firstfree != NULL); + nt->_firstfree = basedst + (_firstfree - basesrc); + nt->_usednodes = _usednodes; +#else + SQInteger ridx=0; + SQObjectPtr key,val; + while((ridx=Next(true,ridx,key,val))!=-1){ + nt->NewSlot(key,val); + } +#endif + nt->SetDelegate(_delegate); + return nt; +} + +bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) +{ + if(sq_type(key) == OT_NULL) + return false; + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + val = _realval(n->val); + return true; + } + return false; +} +bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) +{ + assert(sq_type(key) != OT_NULL); + SQHash h = HashObj(key) & (_numofnodes - 1); + _HashNode *n = _Get(key, h); + if (n) { + n->val = val; + return false; + } + _HashNode *mp = &_nodes[h]; + n = mp; + + + //key not found I'll insert it + //main pos is not free + + if(sq_type(mp->key) != OT_NULL) { + n = _firstfree; /* get a free place */ + SQHash mph = HashObj(mp->key) & (_numofnodes - 1); + _HashNode *othern; /* main position of colliding node */ + + if (mp > n && (othern = &_nodes[mph]) != mp){ + /* yes; move colliding node into free position */ + while (othern->next != mp){ + assert(othern->next != NULL); + othern = othern->next; /* find previous */ + } + othern->next = n; /* redo the chain with `n' in place of `mp' */ + n->key = mp->key; + n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ + n->next = mp->next; + mp->key.Null(); + mp->val.Null(); + mp->next = NULL; /* now `mp' is free */ + } + else{ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + mp->key = key; + + for (;;) { /* correct `firstfree' */ + if (sq_type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { + mp->val = val; + _usednodes++; + return true; /* OK; table still has a free place */ + } + else if (_firstfree == _nodes) break; /* cannot decrement from here */ + else (_firstfree)--; + } + Rehash(true); + return NewSlot(key, val); +} + +SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while (idx < _numofnodes) { + if(sq_type(_nodes[idx].key) != OT_NULL) { + //first found + _HashNode &n = _nodes[idx]; + outkey = n.key; + outval = getweakrefs?(SQObject)n.val:_realval(n.val); + //return idx for the next iteration + return ++idx; + } + ++idx; + } + //nothing to iterate anymore + return -1; +} + + +bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) +{ + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val = val; + return true; + } + return false; +} + +void SQTable::_ClearNodes() +{ + for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); +} diff --git a/vscript/squirrel/squirrel/sqtable.h b/vscript/squirrel/squirrel/sqtable.h new file mode 100644 index 00000000..8ca3ae7c --- /dev/null +++ b/vscript/squirrel/squirrel/sqtable.h @@ -0,0 +1,110 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQTABLE_H_ +#define _SQTABLE_H_ +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_ltable.c.html +*/ + +#include "sqstring.h" + + +#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) + +inline SQHash HashObj(const SQObject &key) +{ + switch(sq_type(key)) { + case OT_STRING: return _string(key)->_hash; + case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); + case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); + default: return hashptr(key._unVal.pRefCounted); + } +} + +struct SQTable : public SQDelegable +{ +private: + struct _HashNode + { + _HashNode() { next = NULL; } + SQObjectPtr val; + SQObjectPtr key; + _HashNode *next; + }; + _HashNode *_firstfree; + _HashNode *_nodes; + SQInteger _numofnodes; + SQInteger _usednodes; + +/////////////////////////// + void AllocNodes(SQInteger nSize); + void Rehash(bool force); + SQTable(SQSharedState *ss, SQInteger nInitialSize); + void _ClearNodes(); +public: + static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) + { + SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); + new (newtable) SQTable(ss, nInitialSize); + newtable->_delegate = NULL; + return newtable; + } + void Finalize(); + SQTable *Clone(); + ~SQTable() + { + SetDelegate(NULL); + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); + SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_TABLE;} +#endif + inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) + { + _HashNode *n = &_nodes[hash]; + do{ + if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){ + return n; + } + }while((n = n->next)); + return NULL; + } + //for compiler use + inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val) + { + SQHash hash = _hashstr(key,keylen); + _HashNode *n = &_nodes[hash & (_numofnodes - 1)]; + _HashNode *res = NULL; + do{ + if(sq_type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){ + res = n; + break; + } + }while((n = n->next)); + if (res) { + val = _realval(res->val); + return true; + } + return false; + } + bool Get(const SQObjectPtr &key,SQObjectPtr &val); + void Remove(const SQObjectPtr &key); + bool Set(const SQObjectPtr &key, const SQObjectPtr &val); + //returns true if a new slot has been created false if it was already present + bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); + SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + + SQInteger CountUsed(){ return _usednodes;} + void Clear(); + void Release() + { + sq_delete(this, SQTable); + } + +}; + +#endif //_SQTABLE_H_ diff --git a/vscript/squirrel/squirrel/squirrel.dsp b/vscript/squirrel/squirrel/squirrel.dsp new file mode 100644 index 00000000..66a84f7d --- /dev/null +++ b/vscript/squirrel/squirrel/squirrel.dsp @@ -0,0 +1,302 @@ +# Microsoft Developer Studio Project File - Name="squirrel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=squirrel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "squirrel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "squirrel.mak" CFG="squirrel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "squirrel - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "squirrel - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "squirrel - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "GARBAGE_COLLECTOR" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" + +!ENDIF + +# Begin Target + +# Name "squirrel - Win32 Release" +# Name "squirrel - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sqapi.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqbaselib.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqcompiler.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqdebug.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqfuncstate.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqlexer.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqmem.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqobject.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqstate.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqtable.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqclass.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqvm.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\sqarray.h +# End Source File +# Begin Source File + +SOURCE=.\sqclosure.h +# End Source File +# Begin Source File + +SOURCE=.\sqcompiler.h +# End Source File +# Begin Source File + +SOURCE=.\sqfuncproto.h +# End Source File +# Begin Source File + +SOURCE=.\sqfuncstate.h +# End Source File +# Begin Source File + +SOURCE=.\sqlexer.h +# End Source File +# Begin Source File + +SOURCE=.\sqobject.h +# End Source File +# Begin Source File + +SOURCE=.\sqopcodes.h +# End Source File +# Begin Source File + +SOURCE=.\sqpcheader.h +# End Source File +# Begin Source File + +SOURCE=.\sqstate.h +# End Source File +# Begin Source File + +SOURCE=.\sqstring.h +# End Source File +# Begin Source File + +SOURCE=.\sqtable.h +# End Source File +# Begin Source File + +SOURCE=.\squserdata.h +# End Source File +# Begin Source File + +SOURCE=.\squtils.h +# End Source File +# Begin Source File + +SOURCE=.\sqclass.h +# End Source File +# Begin Source File + +SOURCE=.\sqvm.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vscript/squirrel/squirrel/squserdata.h b/vscript/squirrel/squirrel/squserdata.h new file mode 100644 index 00000000..ec217313 --- /dev/null +++ b/vscript/squirrel/squirrel/squserdata.h @@ -0,0 +1,40 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUSERDATA_H_ +#define _SQUSERDATA_H_ + +struct SQUserData : SQDelegable +{ + SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } + ~SQUserData() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); + SetDelegate(NULL); + } + static SQUserData* Create(SQSharedState *ss, SQInteger size) + { + SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); + new (ud) SQUserData(ss); + ud->_size = size; + ud->_typetag = 0; + return ud; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){SetDelegate(NULL);} + SQObjectType GetType(){ return OT_USERDATA;} +#endif + void Release() { + if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); + SQInteger tsize = _size; + this->~SQUserData(); + SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); + } + + + SQInteger _size; + SQRELEASEHOOK _hook; + SQUserPointer _typetag; + //SQChar _val[1]; +}; + +#endif //_SQUSERDATA_H_ diff --git a/vscript/squirrel/squirrel/squtils.h b/vscript/squirrel/squirrel/squtils.h new file mode 100644 index 00000000..f3e819a5 --- /dev/null +++ b/vscript/squirrel/squirrel/squtils.h @@ -0,0 +1,116 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUTILS_H_ +#define _SQUTILS_H_ + +void *sq_vm_malloc(SQUnsignedInteger size); +void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); +void sq_vm_free(void *p,SQUnsignedInteger size); + +#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); + +#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) + +//sqvector mini vector class, supports objects by value +template class sqvector +{ +public: + sqvector() + { + _vals = NULL; + _size = 0; + _allocated = 0; + } + sqvector(const sqvector& v) + { + copy(v); + } + void copy(const sqvector& v) + { + if(_size) { + resize(0); //destroys all previous stuff + } + //resize(v._size); + if(v._size > _allocated) { + _realloc(v._size); + } + for(SQUnsignedInteger i = 0; i < v._size; i++) { + new ((void *)&_vals[i]) T(v._vals[i]); + } + _size = v._size; + } + ~sqvector() + { + if(_allocated) { + for(SQUnsignedInteger i = 0; i < _size; i++) + _vals[i].~T(); + SQ_FREE(_vals, (_allocated * sizeof(T))); + } + } + void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } + void resize(SQUnsignedInteger newsize, const T& fill = T()) + { + if(newsize > _allocated) + _realloc(newsize); + if(newsize > _size) { + while(_size < newsize) { + new ((void *)&_vals[_size]) T(fill); + _size++; + } + } + else{ + for(SQUnsignedInteger i = newsize; i < _size; i++) { + _vals[i].~T(); + } + _size = newsize; + } + } + void shrinktofit() { if(_size > 4) { _realloc(_size); } } + T& top() const { return _vals[_size - 1]; } + inline SQUnsignedInteger size() const { return _size; } + bool empty() const { return (_size <= 0); } + inline T &push_back(const T& val = T()) + { + if(_allocated <= _size) + _realloc(_size * 2); + return *(new ((void *)&_vals[_size++]) T(val)); + } + inline void pop_back() + { + _size--; _vals[_size].~T(); + } + void insert(SQUnsignedInteger idx, const T& val) + { + resize(_size + 1); + for(SQUnsignedInteger i = _size - 1; i > idx; i--) { + _vals[i] = _vals[i - 1]; + } + _vals[idx] = val; + } + void remove(SQUnsignedInteger idx) + { + _vals[idx].~T(); + if(idx < (_size - 1)) { + memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); + } + _size--; + } + SQUnsignedInteger capacity() { return _allocated; } + inline T &back() const { return _vals[_size - 1]; } + inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } + T* _vals; +private: + void _realloc(SQUnsignedInteger newsize) + { + newsize = (newsize > 0)?newsize:4; + _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); + _allocated = newsize; + } + SQUnsignedInteger _size; + SQUnsignedInteger _allocated; +}; + +#endif //_SQUTILS_H_ diff --git a/vscript/squirrel/squirrel/sqvm.cpp b/vscript/squirrel/squirrel/sqvm.cpp new file mode 100644 index 00000000..dcf823d7 --- /dev/null +++ b/vscript/squirrel/squirrel/sqvm.cpp @@ -0,0 +1,1791 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqarray.h" +#include "sqclass.h" + +#define TOP() (_stack._vals[_top-1]) +#define TARGET _stack._vals[_stackbase+arg0] +#define STK(a) _stack._vals[_stackbase+(a)] + +bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger res; + if((sq_type(o1)| sq_type(o2)) == OT_INTEGER) + { + SQInteger i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case BW_AND: res = i1 & i2; break; + case BW_OR: res = i1 | i2; break; + case BW_XOR: res = i1 ^ i2; break; + case BW_SHIFTL: res = i1 << i2; break; + case BW_SHIFTR: res = i1 >> i2; break; + case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; + default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } + } + } + else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} + trg = res; + return true; +} + +#define _ARITH_(op,trg,o1,o2) \ +{ \ + SQInteger tmask = sq_type(o1)|sq_type(o2); \ + switch(tmask) { \ + case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +#define _ARITH_NOZERO(op,trg,o1,o2,err) \ +{ \ + SQInteger tmask = sq_type(o1)|sq_type(o2); \ + switch(tmask) { \ + case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger tmask = sq_type(o1)| sq_type(o2); + switch(tmask) { + case OT_INTEGER:{ + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if (i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + else if (i2 == -1 && i1 == INT_MIN) { Raise_Error(_SC("integer overflow")); return false; } + res = i1 / i2; + break; + case '*': res = i1 * i2; break; + case '%': if (i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + else if (i2 == -1 && i1 == INT_MIN) { res = 0; break; } + res = i1 % i2; + break; + default: res = 0xDEADBEEF; + } + trg = res; } + break; + case (OT_FLOAT|OT_INTEGER): + case (OT_FLOAT):{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); + switch(op) { + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; + } + trg = res; } + break; + default: + if(op == '+' && (tmask & _RT_STRING)){ + if(!StringCat(o1, o2, trg)) return false; + } + else if(!ArithMetaMethod(op,o1,o2,trg)) { + return false; + } + } + return true; +} + +SQVM::SQVM(SQSharedState *ss) +{ + _sharedstate=ss; + _suspended = SQFalse; + _suspended_target = -1; + _suspended_root = SQFalse; + _suspended_traps = -1; + _foreignptr = NULL; + _nnativecalls = 0; + _nmetamethodscall = 0; + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + _openouters = NULL; + ci = NULL; + _releasehook = NULL; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +void SQVM::Finalize() +{ + if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } + if(_openouters) CloseOuters(&_stack._vals[0]); + _roottable.Null(); + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + temp_reg.Null(); + _callstackdata.resize(0); + SQInteger size=_stack.size(); + for(SQInteger i=0;i_gc_chain,this); +} + +bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +{ + SQMetaMethod mm; + switch(op){ + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + default: mm = MT_ADD; assert(0); break; //shutup compiler + } + if(is_delegable(o1) && _delegable(o1)->_delegate) { + + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { + Push(o1);Push(o2); + return CallMetaMethod(closure,mm,2,dest); + } + } + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + return false; +} + +bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) +{ + + switch(sq_type(o)) { + case OT_INTEGER: + trg = -_integer(o); + return true; + case OT_FLOAT: + trg = -_float(o); + return true; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { + Push(o); + if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; + _Swap(trg,temp_reg); + return true; + + } + } + default:break; //shutup compiler + } + Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); + return false; +} + +#define _RET_SUCCEED(exp) { result = (exp); return true; } +bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) +{ + SQObjectType t1 = sq_type(o1), t2 = sq_type(o2); + if(t1 == t2) { + if(_rawval(o1) == _rawval(o2))_RET_SUCCEED(0); + SQObjectPtr res; + switch(t1){ + case OT_STRING: + _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); + case OT_INTEGER: + _RET_SUCCEED((_integer(o1)<_integer(o2))?-1:1); + case OT_FLOAT: + _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { + Push(o1);Push(o2); + if(CallMetaMethod(closure,MT_CMP,2,res)) { + if(sq_type(res) != OT_INTEGER) { + Raise_Error(_SC("_cmp must return an integer")); + return false; + } + _RET_SUCCEED(_integer(res)) + } + return false; + } + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); + } + assert(0); + //if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } + // _RET_SUCCEED(_integer(res)); + + } + else{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)){ + if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { + if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } + else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + else{ + if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } + else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + } + else if(t1==OT_NULL) {_RET_SUCCEED(-1);} + else if(t2==OT_NULL) {_RET_SUCCEED(1);} + else { Raise_CompareError(o1,o2); return false; } + + } + assert(0); + _RET_SUCCEED(0); //cannot happen +} + +bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) +{ + SQInteger r; + if(ObjCmp(o1,o2,r)) { + switch(op) { + case CMP_G: res = (r > 0); return true; + case CMP_GE: res = (r >= 0); return true; + case CMP_L: res = (r < 0); return true; + case CMP_LE: res = (r <= 0); return true; + case CMP_3W: res = r; return true; + } + assert(0); + } + return false; +} + +bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) +{ + switch(sq_type(o)) { + case OT_STRING: + res = o; + return true; + case OT_FLOAT: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_SC("%g"),_float(o)); + break; + case OT_INTEGER: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_PRINT_INT_FMT,_integer(o)); + break; + case OT_BOOL: + scsprintf(_sp(sq_rsl(6)),sq_rsl(6),_integer(o)?_SC("true"):_SC("false")); + break; + case OT_NULL: + scsprintf(_sp(sq_rsl(5)),sq_rsl(5),_SC("null")); + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { + Push(o); + if(CallMetaMethod(closure,MT_TOSTRING,1,res)) { + if(sq_type(res) == OT_STRING) + return true; + } + else { + return false; + } + } + } + default: + scsprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR)),sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); + } + res = SQString::Create(_ss(this),_spval); + return true; +} + + +bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) +{ + SQObjectPtr a, b; + if(!ToString(str, a)) return false; + if(!ToString(obj, b)) return false; + SQInteger l = _string(a)->_len , ol = _string(b)->_len; + SQChar *s = _sp(sq_rsl(l + ol + 1)); + memcpy(s, _stringval(a), sq_rsl(l)); + memcpy(s + l, _stringval(b), sq_rsl(ol)); + dest = SQString::Create(_ss(this), _spval, l + ol); + return true; +} + +bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) +{ + if(is_delegable(obj1) && _delegable(obj1)->_delegate) { + SQObjectPtr closure; + if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { + Push(obj1); + return CallMetaMethod(closure,MT_TYPEOF,1,dest); + } + } + dest = SQString::Create(_ss(this),GetTypeName(obj1)); + return true; +} + +bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) +{ + _stack.resize(stacksize); + _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); + _callsstacksize = 0; + _callsstack = &_callstackdata[0]; + _stackbase = 0; + _top = 0; + if(!friendvm) { + _roottable = SQTable::Create(_ss(this), 0); + sq_base_register(this); + } + else { + _roottable = friendvm->_roottable; + _errorhandler = friendvm->_errorhandler; + _debughook = friendvm->_debughook; + _debughook_native = friendvm->_debughook_native; + _debughook_closure = friendvm->_debughook_closure; + } + + + return true; +} + + +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) +{ + SQFunctionProto *func = closure->_function; + + SQInteger paramssize = func->_nparameters; + const SQInteger newtop = stackbase + func->_stacksize; + SQInteger nargs = args; + if(func->_varparams) + { + paramssize--; + if (nargs < paramssize) { + Raise_Error(_SC("wrong number of parameters (%d passed, at least %d required)"), + (int)nargs, (int)paramssize); + return false; + } + + //dumpstack(stackbase); + SQInteger nvargs = nargs - paramssize; + SQArray *arr = SQArray::Create(_ss(this),nvargs); + SQInteger pbase = stackbase+paramssize; + for(SQInteger n = 0; n < nvargs; n++) { + arr->_values[n] = _stack._vals[pbase]; + _stack._vals[pbase].Null(); + pbase++; + + } + _stack._vals[stackbase+paramssize] = arr; + //dumpstack(stackbase); + } + else if (paramssize != nargs) { + SQInteger ndef = func->_ndefaultparams; + SQInteger diff; + if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else { + Raise_Error(_SC("wrong number of parameters (%d passed, %d required)"), + (int)nargs, (int)paramssize); + return false; + } + } + + if(closure->_env) { + _stack._vals[stackbase] = closure->_env->_obj; + } + + if(!EnterFrame(stackbase, newtop, tailcall)) return false; + + ci->_closure = closure; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; + ci->_target = (SQInt32)target; + + if (_debughook) { + CallDebugHook(_SC('c')); + } + + if (closure->_function->_bgenerator) { + SQFunctionProto *f = closure->_function; + SQGenerator *gen = SQGenerator::Create(_ss(this), closure); + if(!gen->Yield(this,f->_stacksize)) + return false; + SQObjectPtr temp; + Return(1, target, temp); + STK(target) = gen; + } + + + return true; +} + +bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) +{ + SQBool _isroot = ci->_root; + SQInteger callerbase = _stackbase - ci->_prevstkbase; + + if (_debughook) { + for(SQInteger i=0; i_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + + SQObjectPtr *dest; + if (_isroot) { + dest = &(retval); + } else if (ci->_target == -1) { + dest = NULL; + } else { + dest = &_stack._vals[callerbase + ci->_target]; + } + if (dest) { + if(_arg0 != 0xFF) { + *dest = _stack._vals[_stackbase+_arg1]; + } + else { + dest->Null(); + } + //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; + } + LeaveFrame(); + return _isroot ? true : false; +} + +#define _RET_ON_FAIL(exp) { if(!exp) return false; } + +bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + SQObjectPtr trg; + _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); + target = a; + a = trg; + return true; +} + +bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) +{ + SQObjectPtr tmp, tself = self, tkey = key; + if (!Get(tself, tkey, tmp, 0, selfidx)) { return false; } + _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) + if (!Set(tself, tkey, target,selfidx)) { return false; } + if (postfix) target = tmp; + return true; +} + +#define arg0 (_i_._arg0) +#define sarg0 ((SQInteger)*((const signed char *)&_i_._arg0)) +#define arg1 (_i_._arg1) +#define sarg1 (*((const SQInt32 *)&_i_._arg1)) +#define arg2 (_i_._arg2) +#define arg3 (_i_._arg3) +#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3)) + +SQRESULT SQVM::Suspend() +{ + if (_suspended) + return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); + if (_nnativecalls!=2) + return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); + return SQ_SUSPEND_FLAG; +} + + +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger SQ_UNUSED_ARG(arg_2),int exitpos,int &jump) +{ + SQInteger nrefidx; + switch(sq_type(o1)) { + case OT_TABLE: + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_ARRAY: + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); + case OT_STRING: + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_CLASS: + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr itr; + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { + Push(o1); + Push(o4); + if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { + o4 = o2 = itr; + if(sq_type(itr) == OT_NULL) _FINISH(exitpos); + if(!Get(o1, itr, o3, 0, DONT_FALL_BACK)) { + Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed + return false; + } + _FINISH(1); + } + else { + return false; + } + } + Raise_Error(_SC("_nexti failed")); + return false; + } + break; + case OT_GENERATOR: + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); + if(_generator(o1)->_state == SQGenerator::eSuspended) { + SQInteger idx = 0; + if(sq_type(o4) == OT_INTEGER) { + idx = _integer(o4) + 1; + } + o2 = idx; + o4 = idx; + _generator(o1)->Resume(this, o3); + _FINISH(0); + } + default: + Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); + } + return false; //cannot be hit(just to avoid warnings) +} + +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) + +#define SQ_THROW() { goto exception_trap; } + +#define _GUARD(exp) { if(!exp) { SQ_THROW();} } + +bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) +{ + SQInteger nouters; + SQClosure *closure = SQClosure::Create(_ss(this), func,_table(_roottable)->GetWeakRef(OT_TABLE)); + if((nouters = func->_noutervalues)) { + for(SQInteger i = 0; i_outervalues[i]; + switch(v._type){ + case otLOCAL: + FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); + break; + case otOUTER: + closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; + break; + } + } + } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; + } + } + target = closure; + return true; + +} + + +bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) +{ + SQClass *base = NULL; + SQObjectPtr attrs; + if(baseclass != -1) { + if(sq_type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } + base = _class(_stack._vals[_stackbase + baseclass]); + } + if(attributes != MAX_FUNC_STACKSIZE) { + attrs = _stack._vals[_stackbase+attributes]; + } + target = SQClass::Create(_ss(this),base); + if(sq_type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { + int nparams = 2; + SQObjectPtr ret; + Push(target); Push(attrs); + if(!Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false)) { + Pop(nparams); + return false; + } + Pop(nparams); + } + _class(target)->_attributes = attrs; + return true; +} + +bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) +{ + SQObjectType t1 = sq_type(o1), t2 = sq_type(o2); + if(t1 == t2) { + if (t1 == OT_FLOAT) { + res = (_float(o1) == _float(o2)); + } + else { + res = (_rawval(o1) == _rawval(o2)); + } + } + else { + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + res = (tofloat(o1) == tofloat(o2)); + } + else { + res = false; + } + } + return true; +} + +bool SQVM::IsFalse(SQObjectPtr &o) +{ + if(((sq_type(o) & SQOBJECT_CANBEFALSE) + && ( ((sq_type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) +#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) + || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL +#else + || (((sq_type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL +#endif + { + return true; + } + return false; +} +extern SQInstructionDesc g_InstrDesc[]; +bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) +{ + if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + _nnativecalls++; + AutoDec ad(&_nnativecalls); + SQInteger traps = 0; + CallInfo *prevci = ci; + + switch(et) { + case ET_CALL: { + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { + //call the handler if there are no calls in the stack, if not relies on the previous node + if(ci == NULL) CallErrorHandler(_lasterror); + return false; + } + if(ci == prevci) { + outres = STK(_top-nargs); + return true; + } + ci->_root = SQTrue; + } + break; + case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; + case ET_RESUME_VM: + case ET_RESUME_THROW_VM: + traps = _suspended_traps; + ci->_root = _suspended_root; + _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } + break; + } + +exception_restore: + // + { + for(;;) + { + const SQInstruction &_i_ = *ci->_ip++; + //dumpstack(_stackbase); + //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-_closure(ci->_closure)->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); + switch(_i_.op) + { + case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; + case _OP_LOADINT: +#ifndef _SQ64 + TARGET = (SQInteger)arg1; continue; +#else + TARGET = (SQInteger)((SQInt32)arg1); continue; +#endif + case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue; + case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; + case _OP_TAILCALL:{ + SQObjectPtr &t = STK(arg1); + if (sq_type(t) == OT_CLOSURE + && (!_closure(t)->_function->_bgenerator)){ + SQObjectPtr clo = t; + SQInteger last_top = _top; + if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); + for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); + _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); + if (last_top >= _top) { + _top = last_top; + } + continue; + } + } + case _OP_CALL: { + SQObjectPtr clo = STK(arg1); + switch (sq_type(clo)) { + case OT_CLOSURE: + _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); + continue; + case OT_NATIVECLOSURE: { + bool suspend; + bool tailcall; + _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo, (SQInt32)sarg0, suspend, tailcall)); + if(suspend){ + _suspended = SQTrue; + _suspended_target = sarg0; + _suspended_root = ci->_root; + _suspended_traps = traps; + outres = clo; + return true; + } + if(sarg0 != -1 && !tailcall) { + STK(arg0) = clo; + } + } + continue; + case OT_CLASS:{ + SQObjectPtr inst; + _GUARD(CreateClassInstance(_class(clo),inst,clo)); + if(sarg0 != -1) { + STK(arg0) = inst; + } + SQInteger stkbase; + switch(sq_type(clo)) { + case OT_CLOSURE: + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); + break; + case OT_NATIVECLOSURE: + bool dummy; + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo, -1, dummy, dummy)); + break; + default: break; //shutup GCC 4.x + } + } + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE:{ + SQObjectPtr closure; + if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { + Push(clo); + for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); + if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); + if(sarg0 != -1) { + STK(arg0) = clo; + } + break; + } + + //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + //SQ_THROW(); + } + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + } + continue; + case _OP_PREPCALL: + case _OP_PREPCALLK: { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,0,arg2)) { + SQ_THROW(); + } + STK(arg3) = o; + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + } + continue; + case _OP_GETK: + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, 0,arg2)) { SQ_THROW();} + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_MOVE: TARGET = STK(arg1); continue; + case _OP_NEWSLOT: + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); + if(arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; + case _OP_SET: + if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } + if (arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_GET: + if (!Get(STK(arg1), STK(arg2), temp_reg, 0,arg1)) { SQ_THROW(); } + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_EQ:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = res?true:false; + }continue; + case _OP_NE:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = (!res)?true:false; + } continue; + case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; + case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; + case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; + case _OP_RETURN: + if((ci)->_generator) { + (ci)->_generator->Kill(); + } + if(Return(arg0, arg1, temp_reg)){ + assert(traps==0); + //outres = temp_reg; + _Swap(outres,temp_reg); + return true; + } + continue; + case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; + case _OP_LOADROOT: { + SQWeakRef *w = _closure(ci->_closure)->_root; + if(sq_type(w->_obj) != OT_NULL) { + TARGET = w->_obj; + } else { + TARGET = _roottable; //shoud this be like this? or null + } + } + continue; + case _OP_LOADBOOL: TARGET = arg1?true:false; continue; + case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; + case _OP_JMP: ci->_ip += (sarg1); continue; + //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_JCMP: + _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); + if(IsFalse(temp_reg)) ci->_ip+=(sarg1); + continue; + case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_GETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + TARGET = *(otr->_valptr); + } + continue; + case _OP_SETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + *(otr->_valptr) = STK(arg2); + if(arg0 != 0xFF) { + TARGET = STK(arg2); + } + } + continue; + case _OP_NEWOBJ: + switch(arg3) { + case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; + case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; + case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; + default: assert(0); continue; + } + case _OP_APPENDARRAY: + { + SQObject val; + val._unVal.raw = 0; + switch(arg2) { + case AAT_STACK: + val = STK(arg1); break; + case AAT_LITERAL: + val = ci->_literals[arg1]; break; + case AAT_INT: + val._type = OT_INTEGER; +#ifndef _SQ64 + val._unVal.nInteger = (SQInteger)arg1; +#else + val._unVal.nInteger = (SQInteger)((SQInt32)arg1); +#endif + break; + case AAT_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = *((const SQFloat *)&arg1); + break; + case AAT_BOOL: + val._type = OT_BOOL; + val._unVal.nInteger = arg1; + break; + default: val._type = OT_INTEGER; assert(0); break; + + } + _array(STK(arg0))->Append(val); continue; + } + case _OP_COMPARITH: { + SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); + _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); + } + continue; + case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; + case _OP_INCL: { + SQObjectPtr &a = STK(arg1); + if(sq_type(a) == OT_INTEGER) { + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); + _ARITH_(+,a,a,o); + } + } continue; + case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; + case _OP_PINCL: { + SQObjectPtr &a = STK(arg1); + if(sq_type(a) == OT_INTEGER) { + TARGET = a; + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); + } + + } continue; + case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; + case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, GET_FLAG_DO_NOT_RAISE_ERROR | GET_FLAG_RAW, DONT_FALL_BACK) ? true : false; continue; + case _OP_INSTANCEOF: + if(sq_type(STK(arg1)) != OT_CLASS) + {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} + TARGET = (sq_type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; + continue; + case _OP_AND: + if(IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_OR: + if(!IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; + case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; + case _OP_BWNOT: + if(sq_type(STK(arg1)) == OT_INTEGER) { + SQInteger t = _integer(STK(arg1)); + TARGET = SQInteger(~t); + continue; + } + Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); + SQ_THROW(); + case _OP_CLOSURE: { + SQClosure *c = ci->_closure._unVal.pClosure; + SQFunctionProto *fp = c->_function; + if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } + continue; + } + case _OP_YIELD:{ + if(ci->_generator) { + if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + if (_openouters) CloseOuters(&_stack._vals[_stackbase]); + _GUARD(ci->_generator->Yield(this,arg2)); + traps -= ci->_etraps; + if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; + } + else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} + if(Return(arg0, arg1, temp_reg)){ + assert(traps == 0); + outres = temp_reg; + return true; + } + + } + continue; + case _OP_RESUME: + if(sq_type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} + _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); + traps += ci->_etraps; + continue; + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + assert(sq_type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); + continue; + case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; + case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; + ci->_etraps++; + } + continue; + case _OP_POPTRAP: { + for(SQInteger i = 0; i < arg0; i++) { + _etraps.pop_back(); traps--; + ci->_etraps--; + } + } + continue; + case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; + case _OP_NEWSLOTA: + _GUARD(NewSlotA(STK(arg1),STK(arg2),STK(arg3),(arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr(),(arg0&NEW_SLOT_STATIC_FLAG)?true:false,false)); + continue; + case _OP_GETBASE:{ + SQClosure *clo = _closure(ci->_closure); + if(clo->_base) { + TARGET = clo->_base; + } + else { + TARGET.Null(); + } + continue; + } + case _OP_CLOSE: + if(_openouters) CloseOuters(&(STK(arg1))); + continue; + } + + } + } +exception_trap: + { + SQObjectPtr currerror = _lasterror; +// dumpstack(_stackbase); +// SQInteger n = 0; + SQInteger last_top = _top; + + if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); + + while( ci ) { + if(ci->_etraps > 0) { + SQExceptionTrap &et = _etraps.top(); + ci->_ip = et._ip; + _top = et._stacksize; + _stackbase = et._stackbase; + _stack._vals[_stackbase + et._extarget] = currerror; + _etraps.pop_back(); traps--; ci->_etraps--; + while(last_top >= _top) _stack._vals[last_top--].Null(); + goto exception_restore; + } + else if (_debughook) { + //notify debugger of a "return" + //even if it really an exception unwinding the stack + for(SQInteger i = 0; i < ci->_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + if(ci->_generator) ci->_generator->Kill(); + bool mustbreak = ci && ci->_root; + LeaveFrame(); + if(mustbreak) break; + } + + _lasterror = currerror; + return false; + } + assert(0); +} + +bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) +{ + inst = theclass->CreateInstance(); + if(!theclass->GetConstructor(constructor)) { + constructor.Null(); + } + return true; +} + +void SQVM::CallErrorHandler(SQObjectPtr &error) +{ + if(sq_type(_errorhandler) != OT_NULL) { + SQObjectPtr out; + Push(_roottable); Push(error); + Call(_errorhandler, 2, _top-2, out,SQFalse); + Pop(2); + } +} + + +void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) +{ + _debughook = false; + SQFunctionProto *func=_closure(ci->_closure)->_function; + if(_debughook_native) { + const SQChar *src = sq_type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; + const SQChar *fname = sq_type(func->_name) == OT_STRING?_stringval(func->_name):NULL; + SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); + _debughook_native(this,type,src,line,fname); + } + else { + SQObjectPtr temp_reg; + SQInteger nparams=5; + Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); + Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); + Pop(nparams); + } + _debughook = true; +} + +bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target,bool &suspend, bool &tailcall) +{ + SQInteger nparamscheck = nclosure->_nparamscheck; + SQInteger newtop = newbase + nargs + nclosure->_noutervalues; + + if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { + Raise_Error(_SC("Native stack overflow")); + return false; + } + + if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || + ((nparamscheck < 0) && (nargs < (-nparamscheck))))) + { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + SQInteger tcs; + SQIntVec &tc = nclosure->_typecheck; + if((tcs = tc.size())) { + for(SQInteger i = 0; i < nargs && i < tcs; i++) { + if((tc._vals[i] != -1) && !(sq_type(_stack._vals[newbase+i]) & tc._vals[i])) { + Raise_ParamTypeError(i,tc._vals[i], sq_type(_stack._vals[newbase+i])); + return false; + } + } + } + + if(!EnterFrame(newbase, newtop, false)) return false; + ci->_closure = nclosure; + ci->_target = target; + + SQInteger outers = nclosure->_noutervalues; + for (SQInteger i = 0; i < outers; i++) { + _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; + } + if(nclosure->_env) { + _stack._vals[newbase] = nclosure->_env->_obj; + } + + _nnativecalls++; + SQInteger ret = (nclosure->_function)(this); + _nnativecalls--; + + suspend = false; + tailcall = false; + if (ret == SQ_TAILCALL_FLAG) { + tailcall = true; + return true; + } + else if (ret == SQ_SUSPEND_FLAG) { + suspend = true; + } + else if (ret < 0) { + LeaveFrame(); + Raise_Error(_lasterror); + return false; + } + if(ret) { + retval = _stack._vals[_top-1]; + } + else { + retval.Null(); + } + //retval = ret ? _stack._vals[_top-1] : _null_; + LeaveFrame(); + return true; +} + +bool SQVM::TailCall(SQClosure *closure, SQInteger parambase,SQInteger nparams) +{ + SQInteger last_top = _top; + SQObjectPtr clo = closure; + if (ci->_root) + { + Raise_Error("root calls cannot invoke tailcalls"); + return false; + } + for (SQInteger i = 0; i < nparams; i++) STK(i) = STK(parambase + i); + bool ret = StartCall(closure, ci->_target, nparams, _stackbase, true); + if (last_top >= _top) { + _top = last_top; + } + return ret; +} + +#define FALLBACK_OK 0 +#define FALLBACK_NO_MATCH 1 +#define FALLBACK_ERROR 2 + +bool SQVM::Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx) +{ + switch(sq_type(self)){ + case OT_TABLE: + if(_table(self)->Get(key,dest))return true; + break; + case OT_ARRAY: + if (sq_isnumeric(key)) { if (_array(self)->Get(tointeger(key), dest)) { return true; } if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); return false; } + break; + case OT_INSTANCE: + if(_instance(self)->Get(key,dest)) return true; + break; + case OT_CLASS: + if(_class(self)->Get(key,dest)) return true; + break; + case OT_STRING: + if(sq_isnumeric(key)){ + SQInteger n = tointeger(key); + SQInteger len = _string(self)->_len; + if (n < 0) { n += len; } + if (n >= 0 && n < len) { + dest = SQInteger(_stringval(self)[n]); + return true; + } + if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); + return false; + } + break; + default:break; //shut up compiler + } + if ((getflags & GET_FLAG_RAW) == 0) { + switch(FallBackGet(self,key,dest)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(InvokeDefaultDelegate(self,key,dest)) { + return true; + } + } +//#ifdef ROOT_FALLBACK + if(selfidx == 0) { + SQWeakRef *w = _closure(ci->_closure)->_root; + if(sq_type(w->_obj) != OT_NULL) + { + if(Get(*((const SQObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) return true; + } + + } +//#endif + if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); + return false; +} + +bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + SQTable *ddel = NULL; + switch(sq_type(self)) { + case OT_CLASS: ddel = _class_ddel; break; + case OT_TABLE: ddel = _table_ddel; break; + case OT_ARRAY: ddel = _array_ddel; break; + case OT_STRING: ddel = _string_ddel; break; + case OT_INSTANCE: ddel = _instance_ddel; break; + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; + case OT_GENERATOR: ddel = _generator_ddel; break; + case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; + case OT_THREAD: ddel = _thread_ddel; break; + case OT_WEAKREF: ddel = _weakref_ddel; break; + default: return false; + } + return ddel->Get(key,dest); +} + + +SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + switch(sq_type(self)){ + case OT_TABLE: + case OT_USERDATA: + //delegation + if(_delegable(self)->_delegate) { + if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,0,DONT_FALL_BACK)) return FALLBACK_OK; + } + else { + return FALLBACK_NO_MATCH; + } + //go through + case OT_INSTANCE: { + SQObjectPtr closure; + if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { + Push(self);Push(key); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 2, _top - 2, dest, SQFalse)) { + Pop(2); + return FALLBACK_OK; + } + else { + Pop(2); + if(sq_type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) +{ + switch(sq_type(self)){ + case OT_TABLE: + if(_table(self)->Set(key,val)) return true; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key,val)) return true; + break; + case OT_ARRAY: + if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } + if(!_array(self)->Set(tointeger(key),val)) { + Raise_IdxError(key); + return false; + } + return true; + case OT_USERDATA: break; // must fall back + default: + Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); + return false; + } + + switch(FallBackSet(self,key,val)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(selfidx == 0) { + if(_table(_roottable)->Set(key,val)) + return true; + } + Raise_IdxError(key); + return false; +} + +SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) +{ + switch(sq_type(self)) { + case OT_TABLE: + if(_table(self)->_delegate) { + if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; + } + //keps on going + case OT_INSTANCE: + case OT_USERDATA:{ + SQObjectPtr closure; + SQObjectPtr t; + if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { + Push(self);Push(key);Push(val); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 3, _top - 3, t, SQFalse)) { + Pop(3); + return FALLBACK_OK; + } + else { + Pop(3); + if(sq_type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) +{ + SQObjectPtr temp_reg; + SQObjectPtr newobj; + switch(sq_type(self)){ + case OT_TABLE: + newobj = _table(self)->Clone(); + goto cloned_mt; + case OT_INSTANCE: { + newobj = _instance(self)->Clone(_ss(this)); +cloned_mt: + SQObjectPtr closure; + if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { + Push(newobj); + Push(self); + if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) + return false; + } + } + target = newobj; + return true; + case OT_ARRAY: + target = _array(self)->Clone(); + return true; + default: + Raise_Error(_SC("cloning a %s"), GetTypeName(self)); + return false; + } +} + +bool SQVM::NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw) +{ + if(sq_type(self) != OT_CLASS) { + Raise_Error(_SC("object must be a class")); + return false; + } + SQClass *c = _class(self); + if(!raw) { + SQObjectPtr &mm = c->_metamethods[MT_NEWMEMBER]; + if(sq_type(mm) != OT_NULL ) { + Push(self); Push(key); Push(val); + Push(attrs); + Push(bstatic); + return CallMetaMethod(mm,MT_NEWMEMBER,5,temp_reg); + } + } + if(!NewSlot(self, key, val,bstatic)) + return false; + if(sq_type(attrs) != OT_NULL) { + c->SetAttributes(key,attrs); + } + return true; +} + +bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + if(sq_type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } + switch(sq_type(self)) { + case OT_TABLE: { + bool rawcall = true; + if(_table(self)->_delegate) { + SQObjectPtr res; + if(!_table(self)->Get(key,res)) { + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + rawcall = false; + } + else { + rawcall = true; + } + } + } + if(rawcall) _table(self)->NewSlot(key,val); //cannot fail + + break;} + case OT_INSTANCE: { + SQObjectPtr res; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + break; + } + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + break;} + case OT_CLASS: + if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { + if(_class(self)->_locked) { + Raise_Error(_SC("trying to modify a class that has already been instantiated")); + return false; + } + else { + SQObjectPtr oval = PrintObjVal(key); + Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); + return false; + } + } + break; + default: + Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); + return false; + break; + } + return true; +} + + + +bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) +{ + switch(sq_type(self)) { + case OT_TABLE: + case OT_INSTANCE: + case OT_USERDATA: { + SQObjectPtr t; + //bool handled = false; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { + Push(self);Push(key); + return CallMetaMethod(closure,MT_DELSLOT,2,res); + } + else { + if(sq_type(self) == OT_TABLE) { + if(_table(self)->Get(key,t)) { + _table(self)->Remove(key); + } + else { + Raise_IdxError((const SQObject &)key); + return false; + } + } + else { + Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); + return false; + } + } + res = t; + } + break; + default: + Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); + return false; + } + return true; +} + +bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) +{ +#ifdef _DEBUG +SQInteger prevstackbase = _stackbase; +#endif + switch(sq_type(closure)) { + case OT_CLOSURE: + return Execute(closure, nparams, stackbase, outres, raiseerror); + break; + case OT_NATIVECLOSURE:{ + bool dummy; + return CallNative(_nativeclosure(closure), nparams, stackbase, outres, -1, dummy, dummy); + + } + break; + case OT_CLASS: { + SQObjectPtr constr; + SQObjectPtr temp; + CreateClassInstance(_class(closure),outres,constr); + SQObjectType ctype = sq_type(constr); + if (ctype == OT_NATIVECLOSURE || ctype == OT_CLOSURE) { + _stack[stackbase] = outres; + return Call(constr,nparams,stackbase,temp,raiseerror); + } + return true; + } + break; + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(closure)); + return false; + } +#ifdef _DEBUG + if(!_suspended) { + assert(_stackbase == prevstackbase); + } +#endif + return true; +} + +bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod SQ_UNUSED_ARG(mm),SQInteger nparams,SQObjectPtr &outres) +{ + //SQObjectPtr closure; + + _nmetamethodscall++; + if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { + _nmetamethodscall--; + Pop(nparams); + return true; + } + _nmetamethodscall--; + //} + Pop(nparams); + return false; +} + +void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) +{ + SQOuter **pp = &_openouters; + SQOuter *p; + SQOuter *otr; + + while ((p = *pp) != NULL && p->_valptr >= stackindex) { + if (p->_valptr == stackindex) { + target = SQObjectPtr(p); + return; + } + pp = &p->_next; + } + otr = SQOuter::Create(_ss(this), stackindex); + otr->_next = *pp; + otr->_idx = (stackindex - _stack._vals); + __ObjAddRef(otr); + *pp = otr; + target = SQObjectPtr(otr); +} + +bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) +{ + if( !tailcall ) { + if( _callsstacksize == _alloccallsstacksize ) { + GrowCallStack(); + } + ci = &_callsstack[_callsstacksize++]; + ci->_prevstkbase = (SQInt32)(newbase - _stackbase); + ci->_prevtop = (SQInt32)(_top - _stackbase); + ci->_etraps = 0; + ci->_ncalls = 1; + ci->_generator = NULL; + ci->_root = SQFalse; + } + else { + ci->_ncalls++; + } + + _stackbase = newbase; + _top = newtop; + if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { + if(_nmetamethodscall) { + Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); + return false; + } + _stack.resize(newtop + (MIN_STACK_OVERHEAD << 2)); + RelocateOuters(); + } + return true; +} + +void SQVM::LeaveFrame() { + SQInteger last_top = _top; + SQInteger last_stackbase = _stackbase; + SQInteger css = --_callsstacksize; + + /* First clean out the call stack frame */ + ci->_closure.Null(); + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + ci = (css) ? &_callsstack[css-1] : NULL; + + if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); + while (last_top >= _top) { + _stack._vals[last_top--].Null(); + } +} + +void SQVM::RelocateOuters() +{ + SQOuter *p = _openouters; + while (p) { + p->_valptr = _stack._vals + p->_idx; + p = p->_next; + } +} + +void SQVM::CloseOuters(SQObjectPtr *stackindex) { + SQOuter *p; + while ((p = _openouters) != NULL && p->_valptr >= stackindex) { + p->_value = *(p->_valptr); + p->_valptr = &p->_value; + _openouters = p->_next; + __ObjRelease(p); + } +} + +void SQVM::Remove(SQInteger n) { + n = (n >= 0)?n + _stackbase - 1:_top + n; + for(SQInteger i = n; i < _top; i++){ + _stack[i] = _stack[i+1]; + } + _stack[_top].Null(); + _top--; +} + +void SQVM::Pop() { + _stack[--_top].Null(); +} + +void SQVM::Pop(SQInteger n) { + for(SQInteger i = 0; i < n; i++){ + _stack[--_top].Null(); + } +} + +void SQVM::PushNull() { _stack[_top++].Null(); } +void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } +SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } +SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } +SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } +SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } + +#ifdef _DEBUG_DUMP +void SQVM::dumpstack(SQInteger stackbase,bool dumpall) +{ + SQInteger size=dumpall?_stack.size():_top; + SQInteger n=0; + scprintf(_SC("\n>>>>stack dump<<<<\n")); + CallInfo &ci=_callsstack[_callsstacksize-1]; + scprintf(_SC("IP: %p\n"),ci._ip); + scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); + scprintf(_SC("prev top: %d\n"),ci._prevtop); + for(SQInteger i=0;i"));else scprintf(_SC(" ")); + scprintf(_SC("[" _PRINT_INT_FMT "]:"),n); + switch(sq_type(obj)){ + case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; + case OT_INTEGER: scprintf(_SC("INTEGER " _PRINT_INT_FMT),_integer(obj));break; + case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; + case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; + case OT_NULL: scprintf(_SC("NULL")); break; + case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; + case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; + case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; + case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; + case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; + case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; + case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; + case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; + case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKREF %p"),_weakref(obj));break; + default: + assert(0); + break; + }; + scprintf(_SC("\n")); + ++n; + } +} + + + +#endif diff --git a/vscript/squirrel/squirrel/sqvm.h b/vscript/squirrel/squirrel/sqvm.h new file mode 100644 index 00000000..a75524da --- /dev/null +++ b/vscript/squirrel/squirrel/sqvm.h @@ -0,0 +1,213 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQVM_H_ +#define _SQVM_H_ + +#include "sqopcodes.h" +#include "sqobject.h" +#define MAX_NATIVE_CALLS 100 +#define MIN_STACK_OVERHEAD 15 + +#define SQ_SUSPEND_FLAG -666 +#define SQ_TAILCALL_FLAG -777 +#define DONT_FALL_BACK 666 +//#define EXISTS_FALL_BACK -1 + +#define GET_FLAG_RAW 0x00000001 +#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002 +//base lib +void sq_base_register(HSQUIRRELVM v); + +struct SQExceptionTrap{ + SQExceptionTrap() {} + SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} + SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } + SQInteger _stackbase; + SQInteger _stacksize; + SQInstruction *_ip; + SQInteger _extarget; +}; + +#define _INLINE + +typedef sqvector ExceptionsTraps; + +struct SQVM : public CHAINABLE_OBJ +{ + struct CallInfo{ + //CallInfo() { _generator = NULL;} + SQInstruction *_ip; + SQObjectPtr *_literals; + SQObjectPtr _closure; + SQGenerator *_generator; + SQInt32 _etraps; + SQInt32 _prevstkbase; + SQInt32 _prevtop; + SQInt32 _target; + SQInt32 _ncalls; + SQBool _root; + }; + +typedef sqvector CallInfoVec; +public: + void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM }; + SQVM(SQSharedState *ss); + ~SQVM(); + bool Init(SQVM *friendvm, SQInteger stacksize); + bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); + //starts a native call return when the NATIVE closure returns + bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target, bool &suspend,bool &tailcall); + bool TailCall(SQClosure *closure, SQInteger firstparam, SQInteger nparams); + //starts a SQUIRREL call in the same "Execution loop" + bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); + bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); + //call a generic closure pure SQUIRREL or NATIVE + bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); + SQRESULT Suspend(); + + void CallDebugHook(SQInteger type,SQInteger forcedline=0); + void CallErrorHandler(SQObjectPtr &e); + bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx); + SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx); + SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val); + bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); + bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw); + bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); + bool Clone(const SQObjectPtr &self, SQObjectPtr &target); + bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); + bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); + static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res); + bool ToString(const SQObjectPtr &o,SQObjectPtr &res); + SQString *PrintObjVal(const SQObjectPtr &o); + + + void Raise_Error(const SQChar *s, ...); + void Raise_Error(const SQObjectPtr &desc); + void Raise_IdxError(const SQObjectPtr &o); + void Raise_CompareError(const SQObject &o1, const SQObject &o2); + void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); + + void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); + void RelocateOuters(); + void CloseOuters(SQObjectPtr *stackindex); + + bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); + bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); + bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); + bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); + //new stuff + _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); + _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); + bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); + bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); + //return true if the loop is finished + bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); + //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0); +#ifdef _DEBUG_DUMP + void dumpstack(SQInteger stackbase=-1, bool dumpall = false); +#endif + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_THREAD;} +#endif + void Finalize(); + void GrowCallStack() { + SQInteger newsize = _alloccallsstacksize*2; + _callstackdata.resize(newsize); + _callsstack = &_callstackdata[0]; + _alloccallsstacksize = newsize; + } + bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); + void LeaveFrame(); + void Release(){ sq_delete(this,SQVM); } +//////////////////////////////////////////////////////////////////////////// + //stack functions for the api + void Remove(SQInteger n); + + static bool IsFalse(SQObjectPtr &o); + + void Pop(); + void Pop(SQInteger n); + void Push(const SQObjectPtr &o); + void PushNull(); + SQObjectPtr &Top(); + SQObjectPtr &PopGet(); + SQObjectPtr &GetUp(SQInteger n); + SQObjectPtr &GetAt(SQInteger n); + + SQObjectPtrVec _stack; + + SQInteger _top; + SQInteger _stackbase; + SQOuter *_openouters; + SQObjectPtr _roottable; + SQObjectPtr _lasterror; + SQObjectPtr _errorhandler; + + bool _debughook; + SQDEBUGHOOK _debughook_native; + SQObjectPtr _debughook_closure; + + SQObjectPtr temp_reg; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + sqvector _callstackdata; + + ExceptionsTraps _etraps; + CallInfo *ci; + SQUserPointer _foreignptr; + //VMs sharing the same state + SQSharedState *_sharedstate; + SQInteger _nnativecalls; + SQInteger _nmetamethodscall; + SQRELEASEHOOK _releasehook; + //suspend infos + SQBool _suspended; + SQBool _suspended_root; + SQInteger _suspended_target; + SQInteger _suspended_traps; +}; + +struct AutoDec{ + AutoDec(SQInteger *n) { _n = n; } + ~AutoDec() { (*_n)--; } + SQInteger *_n; +}; + +inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} + +#define _ss(_vm_) (_vm_)->_sharedstate + +#ifndef NO_GARBAGE_COLLECTOR +#define _opt_ss(_vm_) (_vm_)->_sharedstate +#else +#define _opt_ss(_vm_) NULL +#endif + +#define PUSH_CALLINFO(v,nci){ \ + SQInteger css = v->_callsstacksize; \ + if(css == v->_alloccallsstacksize) { \ + v->GrowCallStack(); \ + } \ + v->ci = &v->_callsstack[css]; \ + *(v->ci) = nci; \ + v->_callsstacksize++; \ +} + +#define POP_CALLINFO(v){ \ + SQInteger css = --v->_callsstacksize; \ + v->ci->_closure.Null(); \ + v->ci = css?&v->_callsstack[css-1]:NULL; \ +} +#endif //_SQVM_H_ diff --git a/vscript/vscript.cpp b/vscript/vscript.cpp new file mode 100644 index 00000000..af1570ad --- /dev/null +++ b/vscript/vscript.cpp @@ -0,0 +1,82 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Custom implementation of VScript in Source 2013, created from scratch +// using the Alien Swarm SDK as a reference for Valve's library. +// +// Author(s): ReDucTor (header written by Blixibon) +// +// $NoKeywords: $ +//=============================================================================// + +#include "vscript/ivscript.h" + +#include "vscript_bindings_base.h" + +#include "tier1/tier1.h" + +IScriptVM* makeSquirrelVM(); + +int vscript_token = 0; + +class CScriptManager : public CTier1AppSystem +{ +public: + virtual IScriptVM* CreateVM(ScriptLanguage_t language) override + { + IScriptVM* pScriptVM = nullptr; + if (language == SL_SQUIRREL) + { + pScriptVM = makeSquirrelVM(); + } + else + { + return nullptr; + } + + if (pScriptVM == nullptr) + { + return nullptr; + } + + if (!pScriptVM->Init()) + { + delete pScriptVM; + return nullptr; + } + + // Register base bindings for all VMs + RegisterBaseBindings( pScriptVM ); + + return pScriptVM; + } + + virtual void DestroyVM(IScriptVM * pScriptVM) override + { + if (pScriptVM) + { + pScriptVM->Shutdown(); + delete pScriptVM; + } + } + + // Mapbase moves CScriptKeyValues into the library so it could be used elsewhere + virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bAllowDestruct ) override + { + CScriptKeyValues *pSKV = new CScriptKeyValues( pKV ); + HSCRIPT hSKV = pVM->RegisterInstance( pSKV, bAllowDestruct ); + return hSKV; + } + + virtual KeyValues *GetKeyValuesFromScriptKV( IScriptVM *pVM, HSCRIPT hSKV ) override + { + CScriptKeyValues *pSKV = (hSKV ? (CScriptKeyValues*)pVM->GetInstanceValue( hSKV, GetScriptDesc( (CScriptKeyValues*)NULL ) ) : nullptr); + if (pSKV) + { + return pSKV->m_pKeyValues; + } + + return nullptr; + } +}; + +EXPOSE_SINGLE_INTERFACE(CScriptManager, IScriptManager, VSCRIPT_INTERFACE_VERSION); \ No newline at end of file diff --git a/vscript/vscript.vpc b/vscript/vscript.vpc new file mode 100644 index 00000000..425afb8a --- /dev/null +++ b/vscript/vscript.vpc @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// VSCRIPT.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR ".." + +$include "$SRCDIR\vpc_scripts\source_lib_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;.\squirrel\include" + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] + } +} + +$Project "VScript" +{ + $Folder "Source Files" + { + + $File "vscript.cpp" + $File "vscript_squirrel.cpp" + $File "vscript_squirrel.nut" + + $File "vscript_bindings_base.cpp" + $File "vscript_bindings_base.h" + $File "vscript_bindings_math.cpp" + $File "vscript_bindings_math.h" + + $Folder "squirrel" + { + $File ".\squirrel\sqstdlib\sqstdaux.cpp" \ + ".\squirrel\sqstdlib\sqstdblob.cpp" \ + ".\squirrel\sqstdlib\sqstdio.cpp" \ + ".\squirrel\sqstdlib\sqstdmath.cpp" \ + ".\squirrel\sqstdlib\sqstdrex.cpp" \ + ".\squirrel\sqstdlib\sqstdstream.cpp" \ + ".\squirrel\sqstdlib\sqstdstring.cpp" \ + ".\squirrel\sqstdlib\sqstdsystem.cpp" \ + ".\squirrel\squirrel\sqapi.cpp" \ + ".\squirrel\squirrel\sqbaselib.cpp" \ + ".\squirrel\squirrel\sqclass.cpp" \ + ".\squirrel\squirrel\sqcompiler.cpp" \ + ".\squirrel\squirrel\sqdebug.cpp" \ + ".\squirrel\squirrel\sqfuncstate.cpp" \ + ".\squirrel\squirrel\sqlexer.cpp" \ + ".\squirrel\squirrel\sqmem.cpp" \ + ".\squirrel\squirrel\sqobject.cpp" \ + ".\squirrel\squirrel\sqstate.cpp" \ + ".\squirrel\squirrel\sqtable.cpp" \ + ".\squirrel\squirrel\sqvm.cpp" + { + $Configuration + { + $Compiler + { + // Squirrel third party library is full of warnings + $AdditionalOptions "$BASE /wd4100 /wd4611 /wd4127 /wd4244 /wd4702 /wd4706 /wd4800" + $TreatWarningsAsErrors "No" + } + } + } + } + } +} diff --git a/vscript/vscript_bindings_base.cpp b/vscript/vscript_bindings_base.cpp new file mode 100644 index 00000000..4f20234a --- /dev/null +++ b/vscript/vscript_bindings_base.cpp @@ -0,0 +1,563 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript functions, constants, etc. registered within the library itself. +// +// This is for things which don't have to depend on server/client and can be accessed +// from anywhere. +// +// $NoKeywords: $ +//=============================================================================// + +#include "vscript/ivscript.h" + +#include "tier1/tier1.h" +#include "tier1/fmtstr.h" + +#include +#include "icommandline.h" +#include "worldsize.h" +#include "bspflags.h" + +#include + +#include "vscript_bindings_base.h" +#include "vscript_bindings_math.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern IScriptManager *scriptmanager; + +//============================================================================= +// +// Prints +// +//============================================================================= +static void ScriptMsg( const char *msg ) +{ + Msg( "%s", msg ); +} + +static void ScriptColorPrint( int r, int g, int b, const char *pszMsg ) +{ + const Color clr(r, g, b, 255); + ConColorMsg( clr, "%s", pszMsg ); +} + +static void ScriptColorPrintL( int r, int g, int b, const char *pszMsg ) +{ + const Color clr(r, g, b, 255); + ConColorMsg( clr, "%s\n", pszMsg ); +} + + +//============================================================================= +// +// Command Line +// +//============================================================================= +class CGlobalSys +{ +public: + const char* ScriptGetCommandLine() + { + return CommandLine()->GetCmdLine(); + } + + bool CommandLineCheck(const char* name) + { + return !!CommandLine()->FindParm(name); + } + + const char* CommandLineCheckStr(const char* name) + { + return CommandLine()->ParmValue(name); + } + + float CommandLineCheckFloat(const char* name) + { + return CommandLine()->ParmValue(name, 0); + } + + int CommandLineCheckInt(const char* name) + { + return CommandLine()->ParmValue(name, 0); + } +} g_ScriptGlobalSys; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CGlobalSys, "CGlobalSys", SCRIPT_SINGLETON "GlobalSys" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetCommandLine, "GetCommandLine", "returns the command line" ) + DEFINE_SCRIPTFUNC( CommandLineCheck, "returns true if the command line param was used, otherwise false." ) + DEFINE_SCRIPTFUNC( CommandLineCheckStr, "returns the command line param as a string." ) + DEFINE_SCRIPTFUNC( CommandLineCheckFloat, "returns the command line param as a float." ) + DEFINE_SCRIPTFUNC( CommandLineCheckInt, "returns the command line param as an int." ) +END_SCRIPTDESC(); + +// ---------------------------------------------------------------------------- +// KeyValues access - CBaseEntity::ScriptGetKeyFromModel returns root KeyValues +// ---------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance" ) + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPTFUNC_NAMED( ScriptFindKey, "FindKey", "Given a KeyValues object and a key name, find a KeyValues object associated with the key name" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFirstSubKey, "GetFirstSubKey", "Given a KeyValues object, return the first sub key object" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetNextKey, "GetNextKey", "Given a KeyValues object, return the next key object in a sub key group" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueInt, "GetKeyInt", "Given a KeyValues object and a key name, return associated integer value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueFloat, "GetKeyFloat", "Given a KeyValues object and a key name, return associated float value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBool, "GetKeyBool", "Given a KeyValues object and a key name, return associated bool value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueString, "GetKeyString", "Given a KeyValues object and a key name, return associated string value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptIsKeyValueEmpty, "IsKeyEmpty", "Given a KeyValues object and a key name, return true if key name has no value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", "Given a root KeyValues object, release its contents" ); + + DEFINE_SCRIPTFUNC( TableToSubKeys, "Converts a script table to KeyValues." ); + DEFINE_SCRIPTFUNC( SubKeysToTable, "Converts to script table." ); + + DEFINE_SCRIPTFUNC_NAMED( ScriptFindOrCreateKey, "FindOrCreateKey", "Given a KeyValues object and a key name, find or create a KeyValues object associated with the key name" ); + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetName, "GetName", "Given a KeyValues object, return its name" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetInt, "GetInt", "Given a KeyValues object, return its own associated integer value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetFloat, "GetFloat", "Given a KeyValues object, return its own associated float value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetString, "GetString", "Given a KeyValues object, return its own associated string value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptGetBool, "GetBool", "Given a KeyValues object, return its own associated bool value" ); + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueInt, "SetKeyInt", "Given a KeyValues object and a key name, set associated integer value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueFloat, "SetKeyFloat", "Given a KeyValues object and a key name, set associated float value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueBool, "SetKeyBool", "Given a KeyValues object and a key name, set associated bool value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueString, "SetKeyString", "Given a KeyValues object and a key name, set associated string value" ); + + DEFINE_SCRIPTFUNC_NAMED( ScriptSetName, "SetName", "Given a KeyValues object, set its name" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetInt, "SetInt", "Given a KeyValues object, set its own associated integer value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetFloat, "SetFloat", "Given a KeyValues object, set its own associated float value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetBool, "SetBool", "Given a KeyValues object, set its own associated bool value" ); + DEFINE_SCRIPTFUNC_NAMED( ScriptSetString, "SetString", "Given a KeyValues object, set its own associated string value" ); +END_SCRIPTDESC(); + +HSCRIPT CScriptKeyValues::ScriptFindKey( const char *pszName ) +{ + KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +HSCRIPT CScriptKeyValues::ScriptGetFirstSubKey( void ) +{ + KeyValues *pKeyValues = m_pKeyValues->GetFirstSubKey(); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +HSCRIPT CScriptKeyValues::ScriptGetNextKey( void ) +{ + KeyValues *pKeyValues = m_pKeyValues->GetNextKey(); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +int CScriptKeyValues::ScriptGetKeyValueInt( const char *pszName ) +{ + int i = m_pKeyValues->GetInt( pszName ); + return i; +} + +float CScriptKeyValues::ScriptGetKeyValueFloat( const char *pszName ) +{ + float f = m_pKeyValues->GetFloat( pszName ); + return f; +} + +const char *CScriptKeyValues::ScriptGetKeyValueString( const char *pszName ) +{ + const char *psz = m_pKeyValues->GetString( pszName ); + return psz; +} + +bool CScriptKeyValues::ScriptIsKeyValueEmpty( const char *pszName ) +{ + bool b = m_pKeyValues->IsEmpty( pszName ); + return b; +} + +bool CScriptKeyValues::ScriptGetKeyValueBool( const char *pszName ) +{ + bool b = m_pKeyValues->GetBool( pszName ); + return b; +} + +void CScriptKeyValues::ScriptReleaseKeyValues( ) +{ + m_pKeyValues->deleteThis(); + m_pKeyValues = NULL; +} + +void CScriptKeyValues::TableToSubKeys( HSCRIPT hTable ) +{ + int nIterator = -1; + ScriptVariant_t varKey, varValue; + while ((nIterator = g_pScriptVM->GetKeyValue( hTable, nIterator, &varKey, &varValue )) != -1) + { + switch (varValue.m_type) + { + case FIELD_CSTRING: m_pKeyValues->SetString( varKey.m_pszString, varValue.m_pszString ); break; + case FIELD_INTEGER: m_pKeyValues->SetInt( varKey.m_pszString, varValue.m_int ); break; + case FIELD_FLOAT: m_pKeyValues->SetFloat( varKey.m_pszString, varValue.m_float ); break; + case FIELD_BOOLEAN: m_pKeyValues->SetBool( varKey.m_pszString, varValue.m_bool ); break; + case FIELD_VECTOR: m_pKeyValues->SetString( varKey.m_pszString, CFmtStr( "%f %f %f", varValue.m_pVector->x, varValue.m_pVector->y, varValue.m_pVector->z ) ); break; + } + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } +} + +void CScriptKeyValues::SubKeysToTable( HSCRIPT hTable ) +{ + FOR_EACH_SUBKEY( m_pKeyValues, key ) + { + switch ( key->GetDataType() ) + { + case KeyValues::TYPE_STRING: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetString() ); break; + case KeyValues::TYPE_INT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetInt() ); break; + case KeyValues::TYPE_FLOAT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetFloat() ); break; + } + } +} + +HSCRIPT CScriptKeyValues::ScriptFindOrCreateKey( const char *pszName ) +{ + KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName, true); + if ( pKeyValues == NULL ) + return NULL; + + CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues ); + + // UNDONE: who calls ReleaseInstance on this?? + HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey ); + return hScriptInstance; +} + +const char *CScriptKeyValues::ScriptGetName() +{ + const char *psz = m_pKeyValues->GetName(); + return psz; +} + +int CScriptKeyValues::ScriptGetInt() +{ + int i = m_pKeyValues->GetInt(); + return i; +} + +float CScriptKeyValues::ScriptGetFloat() +{ + float f = m_pKeyValues->GetFloat(); + return f; +} + +const char *CScriptKeyValues::ScriptGetString() +{ + const char *psz = m_pKeyValues->GetString(); + return psz; +} + +bool CScriptKeyValues::ScriptGetBool() +{ + bool b = m_pKeyValues->GetBool(); + return b; +} + + +void CScriptKeyValues::ScriptSetKeyValueInt( const char *pszName, int iValue ) +{ + m_pKeyValues->SetInt( pszName, iValue ); +} + +void CScriptKeyValues::ScriptSetKeyValueFloat( const char *pszName, float flValue ) +{ + m_pKeyValues->SetFloat( pszName, flValue ); +} + +void CScriptKeyValues::ScriptSetKeyValueString( const char *pszName, const char *pszValue ) +{ + m_pKeyValues->SetString( pszName, pszValue ); +} + +void CScriptKeyValues::ScriptSetKeyValueBool( const char *pszName, bool bValue ) +{ + m_pKeyValues->SetBool( pszName, bValue ); +} + +void CScriptKeyValues::ScriptSetName( const char *pszValue ) +{ + m_pKeyValues->SetName( pszValue ); +} + +void CScriptKeyValues::ScriptSetInt( int iValue ) +{ + m_pKeyValues->SetInt( NULL, iValue ); +} + +void CScriptKeyValues::ScriptSetFloat( float flValue ) +{ + m_pKeyValues->SetFloat( NULL, flValue ); +} + +void CScriptKeyValues::ScriptSetString( const char *pszValue ) +{ + m_pKeyValues->SetString( NULL, pszValue ); +} + +void CScriptKeyValues::ScriptSetBool( bool bValue ) +{ + m_pKeyValues->SetBool( NULL, bValue ); +} + + +// constructors +CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL ) +{ + if (pKeyValues == NULL) + { + m_pKeyValues = new KeyValues("CScriptKeyValues"); + } + else + { + m_pKeyValues = pKeyValues; + } +} + +// destructor +CScriptKeyValues::~CScriptKeyValues( ) +{ + if (m_pKeyValues) + { + m_pKeyValues->deleteThis(); + } + m_pKeyValues = NULL; +} + +//============================================================================= +// +// matrix3x4_t +// +//============================================================================= +CScriptColorInstanceHelper g_ColorScriptInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT( Color, "" ) + + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPT_INSTANCE_HELPER( &g_ColorScriptInstanceHelper ) + + DEFINE_SCRIPTFUNC( SetColor, "Sets the color." ) + + DEFINE_SCRIPTFUNC( SetRawColor, "Sets the raw color integer." ) + DEFINE_SCRIPTFUNC( GetRawColor, "Gets the raw color integer." ) + + DEFINE_MEMBERVAR( "r", FIELD_CHARACTER, "Member variable for red." ) + DEFINE_MEMBERVAR( "g", FIELD_CHARACTER, "Member variable for green." ) + DEFINE_MEMBERVAR( "b", FIELD_CHARACTER, "Member variable for blue." ) + DEFINE_MEMBERVAR( "a", FIELD_CHARACTER, "Member variable for alpha. (transparency)" ) + +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- + +bool CScriptColorInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) +{ + Color *pClr = ((Color *)p); + V_snprintf( pBuf, bufSize, "(color: (%i, %i, %i, %i))", pClr->r(), pClr->g(), pClr->b(), pClr->a() ); + return true; +} + +bool CScriptColorInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Color *pClr = ((Color *)p); + if ( strlen(pszKey) == 1 ) + { + switch (pszKey[0]) + { + case 'r': + variant = pClr->r(); + return true; + case 'g': + variant = pClr->g(); + return true; + case 'b': + variant = pClr->b(); + return true; + case 'a': + variant = pClr->a(); + return true; + } + } + return false; +} + +bool CScriptColorInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Color *pClr = ((Color *)p); + if ( strlen(pszKey) == 1 ) + { + int iVal; + variant.AssignTo( &iVal ); + switch (pszKey[0]) + { + // variant.AssignTo( &(*pClr)[0] ); + case 'r': + (*pClr)[0] = iVal; + return true; + case 'g': + (*pClr)[1] = iVal; + return true; + case 'b': + (*pClr)[2] = iVal; + return true; + case 'a': + (*pClr)[3] = iVal; + return true; + } + } + return false; +} + +//============================================================================= +//============================================================================= + +void RegisterBaseBindings( IScriptVM *pVM ) +{ + ScriptRegisterFunctionNamed( pVM, ScriptMsg, "Msg", "" ); + ScriptRegisterFunctionNamed( pVM, ScriptColorPrint, "printc", "Version of print() which takes a color before the message." ); + ScriptRegisterFunctionNamed( pVM, ScriptColorPrintL, "printcl", "Version of printl() which takes a color before the message." ); + + ScriptRegisterFunction( pVM, GetCPUUsage, "Get CPU usage percentage." ); + + //----------------------------------------------------------------------------- + + pVM->RegisterInstance( &g_ScriptGlobalSys, "GlobalSys" ); + + //----------------------------------------------------------------------------- + + pVM->RegisterClass( GetScriptDescForClass( CScriptKeyValues ) ); + + pVM->RegisterClass( GetScriptDescForClass( Color ) ); + + //----------------------------------------------------------------------------- + + ScriptRegisterConstant( pVM, MAPBASE_VERSION, "The current Mapbase version according to when the VScript library was last compiled." ); + ScriptRegisterConstant( pVM, MAPBASE_VER_INT, "The current Mapbase version integer according to when the VScript library was last compiled." ); + + // + // Math/world + // + ScriptRegisterConstant( pVM, MAX_COORD_FLOAT, "Maximum float coordinate." ); + ScriptRegisterConstant( pVM, MAX_TRACE_LENGTH, "Maximum traceable distance (assumes cubic world and trace from one corner to opposite)." ); + + // + // Trace Contents/Masks + // + ScriptRegisterConstant( pVM, CONTENTS_EMPTY, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_SOLID, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_WINDOW, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_AUX, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_GRATE, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_SLIME, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_WATER, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_BLOCKLOS, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_OPAQUE, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_TESTFOGVOLUME, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_TEAM1, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_TEAM2, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_IGNORE_NODRAW_OPAQUE, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_MOVEABLE, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_AREAPORTAL, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_PLAYERCLIP, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_MONSTERCLIP, "Spatial content flags." ); + + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_0, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_90, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_180, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_270, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_UP, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_CURRENT_DOWN, "Spatial content flags." ); + + ScriptRegisterConstant( pVM, CONTENTS_ORIGIN, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_MONSTER, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_DEBRIS, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_DETAIL, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_TRANSLUCENT, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_LADDER, "Spatial content flags." ); + ScriptRegisterConstant( pVM, CONTENTS_HITBOX, "Spatial content flags." ); + + ScriptRegisterConstant( pVM, LAST_VISIBLE_CONTENTS, "Contains last visible spatial content flags." ); + ScriptRegisterConstant( pVM, ALL_VISIBLE_CONTENTS, "Contains all visible spatial content flags." ); + + ScriptRegisterConstant( pVM, MASK_SOLID, "Spatial content mask representing solid objects (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_PLAYERSOLID, "Spatial content mask representing objects solid to the player, including player clips (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_NPCSOLID, "Spatial content mask representing objects solid to NPCs, including NPC clips (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_WATER, "Spatial content mask representing water and slime solids (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME)" ); + ScriptRegisterConstant( pVM, MASK_OPAQUE, "Spatial content mask representing objects which block lighting (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE)" ); + ScriptRegisterConstant( pVM, MASK_OPAQUE_AND_NPCS, "Spatial content mask equivalent to MASK_OPAQUE, but also including NPCs (MASK_OPAQUE|CONTENTS_MONSTER)" ); + ScriptRegisterConstant( pVM, MASK_BLOCKLOS, "Spatial content mask representing objects which block LOS for AI (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS)" ); + ScriptRegisterConstant( pVM, MASK_BLOCKLOS_AND_NPCS, "Spatial content mask equivalent to MASK_BLOCKLOS, but also including NPCs (MASK_BLOCKLOS|CONTENTS_MONSTER)" ); + ScriptRegisterConstant( pVM, MASK_VISIBLE, "Spatial content mask representing objects which block LOS for players (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE)" ); + ScriptRegisterConstant( pVM, MASK_VISIBLE_AND_NPCS, "Spatial content mask equivalent to MASK_VISIBLE, but also including NPCs (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE)" ); + ScriptRegisterConstant( pVM, MASK_SHOT, "Spatial content mask representing objects solid to bullets (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX)" ); + ScriptRegisterConstant( pVM, MASK_SHOT_HULL, "Spatial content mask representing objects solid to non-raycasted weapons, including grates (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_SHOT_PORTAL, "Spatial content mask equivalent to MASK_SHOT, but excluding debris and not using expensive hitbox calculations (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER)" ); + ScriptRegisterConstant( pVM, MASK_SOLID_BRUSHONLY, "Spatial content mask equivalent to MASK_SOLID, but without NPCs (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_PLAYERSOLID_BRUSHONLY, "Spatial content mask equivalent to MASK_PLAYERSOLID, but without NPCs (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_NPCSOLID_BRUSHONLY, "Spatial content mask equivalent to MASK_NPCSOLID, but without NPCs (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_NPCWORLDSTATIC, "Spatial content mask representing objects static to NPCs, used for nodegraph rebuilding (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)" ); + ScriptRegisterConstant( pVM, MASK_SPLITAREAPORTAL, "Spatial content mask representing objects which can split areaportals (CONTENTS_WATER|CONTENTS_SLIME)" ); + + // + // Misc. General + // + ScriptRegisterConstant( pVM, FCVAR_NONE, "Empty convar flag." ); + ScriptRegisterConstant( pVM, FCVAR_UNREGISTERED, "If this convar flag is set, it isn't added to linked list, etc." ); + ScriptRegisterConstant( pVM, FCVAR_DEVELOPMENTONLY, "If this convar flag is set, it's hidden in \"retail\" DLLs." ); + ScriptRegisterConstant( pVM, FCVAR_GAMEDLL, "This convar flag is defined in server DLL convars." ); + ScriptRegisterConstant( pVM, FCVAR_CLIENTDLL, "This convar flag is defined in client DLL convars." ); + ScriptRegisterConstant( pVM, FCVAR_HIDDEN, "If this convar flag is set, it doesn't appear in the console or any searching tools, but it can still be set." ); + ScriptRegisterConstant( pVM, FCVAR_PROTECTED, "This convar flag prevents convars with secure data (e.g. passwords) from sending full data to clients, only sending 1 if non-zero and 0 otherwise." ); + ScriptRegisterConstant( pVM, FCVAR_SPONLY, "If this convar flag is set, it can't be changed by clients connected to a multiplayer server." ); + ScriptRegisterConstant( pVM, FCVAR_ARCHIVE, "If this convar flag is set, its value will be saved when the game is exited." ); + ScriptRegisterConstant( pVM, FCVAR_NOTIFY, "If this convar flag is set, it will notify players when it is changed." ); + ScriptRegisterConstant( pVM, FCVAR_CHEAT, "Only useable in singleplayer / debug / multiplayer & sv_cheats" ); + ScriptRegisterConstant( pVM, FCVAR_USERINFO, "If this convar flag is set, it will be marked as info which plays a part in how the server identifies a client." ); + ScriptRegisterConstant( pVM, FCVAR_PRINTABLEONLY, "If this convar flag is set, it cannot contain unprintable characters. Used for player name cvars, etc." ); + ScriptRegisterConstant( pVM, FCVAR_UNLOGGED, "If this convar flag is set, it will not log its changes if a log is being created." ); + ScriptRegisterConstant( pVM, FCVAR_NEVER_AS_STRING, "If this convar flag is set, it will never be printed as a string." ); + ScriptRegisterConstant( pVM, FCVAR_REPLICATED, "If this convar flag is set, it will enforce a serverside value on any clientside counterparts. (also known as FCVAR_SERVER)" ); + ScriptRegisterConstant( pVM, FCVAR_DEMO, "If this convar flag is set, it will be recorded when starting a demo file." ); + ScriptRegisterConstant( pVM, FCVAR_DONTRECORD, "If this convar flag is set, it will NOT be recorded when starting a demo file." ); + ScriptRegisterConstant( pVM, FCVAR_RELOAD_MATERIALS, "If this convar flag is set, it will force a material reload when it changes." ); + ScriptRegisterConstant( pVM, FCVAR_RELOAD_TEXTURES, "If this convar flag is set, it will force a texture reload when it changes." ); + ScriptRegisterConstant( pVM, FCVAR_NOT_CONNECTED, "If this convar flag is set, it cannot be changed by a client connected to the server." ); + ScriptRegisterConstant( pVM, FCVAR_MATERIAL_SYSTEM_THREAD, "This convar flag indicates it's read from the material system thread." ); + ScriptRegisterConstant( pVM, FCVAR_ARCHIVE_XBOX, "If this convar flag is set, it will be archived on the Xbox config." ); + ScriptRegisterConstant( pVM, FCVAR_ACCESSIBLE_FROM_THREADS, "If this convar flag is set, it will be accessible from the material system thread." ); + ScriptRegisterConstant( pVM, FCVAR_SERVER_CAN_EXECUTE, "If this convar flag is set, the server will be allowed to execute it as a client command." ); + ScriptRegisterConstant( pVM, FCVAR_SERVER_CANNOT_QUERY, "If this convar flag is set, the server will not be allowed to query its value." ); + ScriptRegisterConstant( pVM, FCVAR_CLIENTCMD_CAN_EXECUTE, "If this convar flag is set, any client will be allowed to execute this command." ); + + //----------------------------------------------------------------------------- + + RegisterMathBaseBindings( pVM ); +} diff --git a/vscript/vscript_bindings_base.h b/vscript/vscript_bindings_base.h new file mode 100644 index 00000000..2629aada --- /dev/null +++ b/vscript/vscript_bindings_base.h @@ -0,0 +1,76 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_BINDINGS_BASE +#define VSCRIPT_BINDINGS_BASE +#ifdef _WIN32 +#pragma once +#endif + +#include "vscript/ivscript.h" +#include "tier1/KeyValues.h" + +// ---------------------------------------------------------------------------- +// KeyValues access +// ---------------------------------------------------------------------------- +class CScriptKeyValues +{ +public: + CScriptKeyValues( KeyValues *pKeyValues ); + ~CScriptKeyValues( ); + + HSCRIPT ScriptFindKey( const char *pszName ); + HSCRIPT ScriptGetFirstSubKey( void ); + HSCRIPT ScriptGetNextKey( void ); + int ScriptGetKeyValueInt( const char *pszName ); + float ScriptGetKeyValueFloat( const char *pszName ); + const char *ScriptGetKeyValueString( const char *pszName ); + bool ScriptIsKeyValueEmpty( const char *pszName ); + bool ScriptGetKeyValueBool( const char *pszName ); + void ScriptReleaseKeyValues( ); + + // Functions below are new with Mapbase + void TableToSubKeys( HSCRIPT hTable ); + void SubKeysToTable( HSCRIPT hTable ); + + HSCRIPT ScriptFindOrCreateKey( const char *pszName ); + + const char *ScriptGetName(); + int ScriptGetInt(); + float ScriptGetFloat(); + const char *ScriptGetString(); + bool ScriptGetBool(); + + void ScriptSetKeyValueInt( const char *pszName, int iValue ); + void ScriptSetKeyValueFloat( const char *pszName, float flValue ); + void ScriptSetKeyValueString( const char *pszName, const char *pszValue ); + void ScriptSetKeyValueBool( const char *pszName, bool bValue ); + void ScriptSetName( const char *pszValue ); + void ScriptSetInt( int iValue ); + void ScriptSetFloat( float flValue ); + void ScriptSetString( const char *pszValue ); + void ScriptSetBool( bool bValue ); + + KeyValues *GetKeyValues() { return m_pKeyValues; } + + KeyValues *m_pKeyValues; // actual KeyValue entity +}; + +//----------------------------------------------------------------------------- +// Exposes Color to VScript +//----------------------------------------------------------------------------- +class CScriptColorInstanceHelper : public IScriptInstanceHelper +{ + bool ToString( void *p, char *pBuf, int bufSize ); + + bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ); + bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); +}; + +void RegisterBaseBindings( IScriptVM *pVM ); + +#endif diff --git a/vscript/vscript_bindings_math.cpp b/vscript/vscript_bindings_math.cpp new file mode 100644 index 00000000..cb1567d5 --- /dev/null +++ b/vscript/vscript_bindings_math.cpp @@ -0,0 +1,515 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: VScript functions, constants, etc. registered within the library itself. +// +// This is for things which don't have to depend on server/client and can be accessed +// from anywhere. +// +// $NoKeywords: $ +//=============================================================================// + +#include "vscript/ivscript.h" + +#include "tier1/tier1.h" + +#include +#include "worldsize.h" + +#include + +#include "vscript_bindings_math.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//============================================================================= +// +// matrix3x4_t +// +//============================================================================= +BEGIN_SCRIPTDESC_ROOT_NAMED( matrix3x4_t, "matrix3x4_t", "A 3x4 matrix transform." ) + + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPTFUNC( Init, "Creates a matrix where the X axis = forward, the Y axis = left, and the Z axis = up." ) + +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void ScriptConcatTransforms( HSCRIPT hMat1, HSCRIPT hMat2, HSCRIPT hOut ) +{ + if (!hMat1 || !hMat2 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + ConcatTransforms( *pMat1, *pMat2, *pOut ); +} + +void ScriptMatrixCopy( HSCRIPT hMat1, HSCRIPT hOut ) +{ + if (!hMat1 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + MatrixCopy( *pMat1, *pOut ); +} + +void ScriptMatrixInvert( HSCRIPT hMat1, HSCRIPT hOut ) +{ + if (!hMat1 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + MatrixInvert( *pMat1, *pOut ); +} + +void ScriptMatricesAreEqual( HSCRIPT hMat1, HSCRIPT hMat2 ) +{ + if (!hMat1 || !hMat2) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); + + MatricesAreEqual( *pMat1, *pMat2 ); +} + +const Vector& ScriptMatrixGetColumn( HSCRIPT hMat1, int column ) +{ + static Vector outvec; + outvec.Zero(); + if (!hMat1) + return outvec; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixGetColumn( *pMat1, column, outvec ); + return outvec; +} + +void ScriptMatrixSetColumn( const Vector& vecset, int column, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixSetColumn( vecset, column, *pMat1 ); +} + +void ScriptMatrixAngles( HSCRIPT hMat1, const QAngle& angset, const Vector& vecset ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixAngles( *pMat1, *const_cast(&angset), *const_cast(&vecset) ); +} + +void ScriptAngleMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + AngleMatrix( angset, vecset, *pMat1 ); +} + +void ScriptAngleIMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + AngleIMatrix( angset, vecset, *pMat1 ); +} + +void ScriptSetIdentityMatrix( HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + SetIdentityMatrix( *pMat1 ); +} + +void ScriptSetScaleMatrix( float x, float y, float z, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + SetScaleMatrix( x, y, z, *pMat1 ); +} + +void ScriptMatrixScaleBy( float flScale, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixScaleBy( flScale, *pMat1 ); +} + +void ScriptMatrixScaleByZero( HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixScaleByZero( *pMat1 ); +} + +const Vector& ScriptMatrixGetTranslation( HSCRIPT hMat1 ) +{ + static Vector outvec; + outvec.Zero(); + if (!hMat1) + return outvec; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixGetTranslation( *pMat1, outvec ); + return outvec; +} + +void ScriptMatrixSetTranslation( const Vector& vecset, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixSetTranslation( vecset, *pMat1 ); +} + +//============================================================================= +// +// Quaternion +// +//============================================================================= +CScriptQuaternionInstanceHelper g_QuaternionScriptInstanceHelper; + +BEGIN_SCRIPTDESC_ROOT_NAMED( Quaternion, "Quaternion", "A quaternion." ) + + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPT_INSTANCE_HELPER( &g_QuaternionScriptInstanceHelper ) + DEFINE_SCRIPTFUNC_NAMED( ScriptInit, "Init", "Creates a quaternion with the given values." ) + + DEFINE_MEMBERVAR( "x", FIELD_FLOAT, "The quaternion's i axis component." ) + DEFINE_MEMBERVAR( "y", FIELD_FLOAT, "The quaternion's j axis component." ) + DEFINE_MEMBERVAR( "z", FIELD_FLOAT, "The quaternion's k axis component." ) + DEFINE_MEMBERVAR( "w", FIELD_FLOAT, "The quaternion's scalar component." ) + +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- + +bool CScriptQuaternionInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) +{ + Quaternion *pQuat = ((Quaternion *)p); + V_snprintf( pBuf, bufSize, "(Quaternion %p [%f %f %f %f])", (void*)pQuat, pQuat->x, pQuat->y, pQuat->z, pQuat->w ); + return true; +} + +bool CScriptQuaternionInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Quaternion *pQuat = ((Quaternion *)p); + if ( strlen(pszKey) == 1 ) + { + switch (pszKey[0]) + { + case 'x': + variant = pQuat->x; + return true; + case 'y': + variant = pQuat->y; + return true; + case 'z': + variant = pQuat->z; + return true; + case 'w': + variant = pQuat->w; + return true; + } + } + return false; +} + +bool CScriptQuaternionInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant ) +{ + Quaternion *pQuat = ((Quaternion *)p); + if ( strlen(pszKey) == 1 ) + { + switch (pszKey[0]) + { + case 'x': + variant.AssignTo( &pQuat->x ); + return true; + case 'y': + variant.AssignTo( &pQuat->y ); + return true; + case 'z': + variant.AssignTo( &pQuat->z ); + return true; + case 'w': + variant.AssignTo( &pQuat->w ); + return true; + } + } + return false; +} + +ScriptVariant_t *CScriptQuaternionInstanceHelper::Add( void *p, ScriptVariant_t &variant ) +{ + Quaternion *pQuat = ((Quaternion *)p); + + float flAdd; + variant.AssignTo( &flAdd ); + + (*pQuat)[0] += flAdd; + (*pQuat)[1] += flAdd; + (*pQuat)[2] += flAdd; + (*pQuat)[3] += flAdd; + + static ScriptVariant_t result; + result = (HSCRIPT)p; + return &result; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void ScriptQuaternionAdd( HSCRIPT hQuat1, HSCRIPT hQuat2, HSCRIPT hOut ) +{ + if (!hQuat1 || !hQuat2 || !hOut) + return; + + Quaternion *pQuat1 = ToQuaternion( hQuat1 ); + Quaternion *pQuat2 = ToQuaternion( hQuat2 ); + Quaternion *pOut = ToQuaternion( hOut ); + + QuaternionAdd( *pQuat1, *pQuat2, *pOut ); +} + +void ScriptMatrixQuaternion( HSCRIPT hMat1, HSCRIPT hQuat1 ) +{ + if (!hMat1 || !hQuat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + Quaternion *pQuat1 = ToQuaternion( hQuat1 ); + + MatrixQuaternion( *pMat1, *pQuat1 ); +} + +void ScriptQuaternionMatrix( HSCRIPT hQuat1, HSCRIPT hMat1 ) +{ + if (!hQuat1 || !hMat1) + return; + + Quaternion *pQuat1 = ToQuaternion( hQuat1 ); + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + QuaternionMatrix( *pQuat1, *pMat1 ); +} + +QAngle ScriptQuaternionAngles( HSCRIPT hQuat1 ) +{ + if (!hQuat1) + return QAngle(); + + Quaternion *pQuat1 = ToQuaternion( hQuat1 ); + + QAngle angles; + QuaternionAngles( *pQuat1, angles ); + return angles; +} + +//============================================================================= +// +// Misc. Vector/QAngle functions +// +//============================================================================= + +const Vector& ScriptAngleVectors( const QAngle &angles ) +{ + static Vector forward; + AngleVectors( angles, &forward ); + return forward; +} + +const QAngle& ScriptVectorAngles( const Vector &forward ) +{ + static QAngle angles; + VectorAngles( forward, angles ); + return angles; +} + +const Vector& ScriptVectorRotate( const Vector &in, HSCRIPT hMat ) +{ + if (ToMatrix3x4(hMat) == NULL) + return vec3_origin; + + static Vector out; + VectorRotate( in, *ToMatrix3x4(hMat), out ); + return out; +} + +const Vector& ScriptVectorIRotate( const Vector &in, HSCRIPT hMat ) +{ + if (ToMatrix3x4(hMat) == NULL) + return vec3_origin; + + static Vector out; + VectorIRotate( in, *ToMatrix3x4(hMat), out ); + return out; +} + +const Vector& ScriptVectorTransform( const Vector &in, HSCRIPT hMat ) +{ + if (ToMatrix3x4(hMat) == NULL) + return vec3_origin; + + static Vector out; + VectorTransform( in, *ToMatrix3x4( hMat ), out ); + return out; +} + +const Vector& ScriptVectorITransform( const Vector &in, HSCRIPT hMat ) +{ + if (ToMatrix3x4(hMat) == NULL) + return vec3_origin; + + static Vector out; + VectorITransform( in, *ToMatrix3x4( hMat ), out ); + return out; +} + +const Vector& ScriptCalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point ) +{ + static Vector outvec; + CalcClosestPointOnAABB( mins, maxs, point, outvec ); + return outvec; +} + +const Vector& ScriptCalcClosestPointOnLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + static Vector outvec; + CalcClosestPointOnLine( point, vLineA, vLineB, outvec ); + return outvec; +} + +float ScriptCalcDistanceToLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + return CalcDistanceToLine( point, vLineA, vLineB ); +} + +const Vector& ScriptCalcClosestPointOnLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + static Vector outvec; + CalcClosestPointOnLineSegment( point, vLineA, vLineB, outvec ); + return outvec; +} + +float ScriptCalcDistanceToLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + return CalcDistanceToLineSegment( point, vLineA, vLineB ); +} + +inline float ScriptExponentialDecay( float decayTo, float decayTime, float dt ) +{ + return ExponentialDecay( decayTo, decayTime, dt ); +} + +void RegisterMathBaseBindings( IScriptVM *pVM ) +{ + ScriptRegisterConstantNamed( pVM, ((float)(180.f / M_PI_F)), "RAD2DEG", "" ); + ScriptRegisterConstantNamed( pVM, ((float)(M_PI_F / 180.f)), "DEG2RAD", "" ); + + ScriptRegisterFunction( pVM, RandomFloat, "Generate a random floating point number within a range, inclusive." ); + ScriptRegisterFunction( pVM, RandomInt, "Generate a random integer within a range, inclusive." ); + //ScriptRegisterFunction( pVM, Approach, "Returns a value which approaches the target value from the input value with the specified speed." ); + ScriptRegisterFunction( pVM, ApproachAngle, "Returns an angle which approaches the target angle from the input angle with the specified speed." ); + ScriptRegisterFunction( pVM, AngleDiff, "Returns the degrees difference between two yaw angles." ); + //ScriptRegisterFunction( pVM, AngleDistance, "Returns the distance between two angles." ); + ScriptRegisterFunction( pVM, AngleNormalize, "Clamps an angle to be in between -360 and 360." ); + ScriptRegisterFunction( pVM, AngleNormalizePositive, "Clamps an angle to be in between 0 and 360." ); + ScriptRegisterFunction( pVM, AnglesAreEqual, "Checks if two angles are equal based on a given tolerance value." ); + + // + // matrix3x4_t + // + pVM->RegisterClass( GetScriptDescForClass( matrix3x4_t ) ); + + ScriptRegisterFunctionNamed( pVM, ScriptFreeMatrixInstance, "FreeMatrixInstance", "Frees an allocated matrix instance." ); + + ScriptRegisterFunctionNamed( pVM, ScriptConcatTransforms, "ConcatTransforms", "Concatenates two transformation matrices into another matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixCopy, "MatrixCopy", "Copies a matrix to another matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixInvert, "MatrixInvert", "Inverts a matrix and copies the result to another matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatricesAreEqual, "MatricesAreEqual", "Checks if two matrices are equal." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixGetColumn, "MatrixGetColumn", "Gets the column of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixSetColumn, "MatrixSetColumn", "Sets the column of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixAngles, "MatrixAngles", "Gets the angles and position of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptAngleMatrix, "AngleMatrix", "Sets the angles and position of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptAngleIMatrix, "AngleIMatrix", "Sets the inverted angles and position of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptSetIdentityMatrix, "SetIdentityMatrix", "Turns a matrix into an identity matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptSetScaleMatrix, "SetScaleMatrix", "Builds a scale matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixScaleBy, "MatrixScaleBy", "Scales a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixScaleByZero, "MatrixScaleByZero", "Scales a matrix by zero." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixGetTranslation, "MatrixGetTranslation", "Gets a matrix's translation." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixSetTranslation, "MatrixSetTranslation", "Sets a matrix's translation." ); + + // + // Quaternion + // + pVM->RegisterClass( GetScriptDescForClass( Quaternion ) ); + + ScriptRegisterFunctionNamed( pVM, ScriptFreeQuaternionInstance, "FreeQuaternionInstance", "Frees an allocated quaternion instance." ); + + ScriptRegisterFunctionNamed( pVM, ScriptQuaternionAdd, "QuaternionAdd", "Adds two quaternions together into another quaternion." ); + ScriptRegisterFunctionNamed( pVM, ScriptMatrixQuaternion, "MatrixQuaternion", "Converts a matrix to a quaternion." ); + ScriptRegisterFunctionNamed( pVM, ScriptQuaternionMatrix, "QuaternionMatrix", "Converts a quaternion to a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptQuaternionAngles, "QuaternionAngles", "Converts a quaternion to angles." ); + + // + // Misc. Vector/QAngle functions + // + ScriptRegisterFunctionNamed( pVM, ScriptAngleVectors, "AngleVectors", "Turns an angle into a direction vector." ); + ScriptRegisterFunctionNamed( pVM, ScriptVectorAngles, "VectorAngles", "Turns a direction vector into an angle." ); + + ScriptRegisterFunctionNamed( pVM, ScriptVectorRotate, "VectorRotate", "Rotates a vector with a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptVectorIRotate, "VectorIRotate", "Rotates a vector with the inverse of a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptVectorTransform, "VectorTransform", "Transforms a vector with a matrix." ); + ScriptRegisterFunctionNamed( pVM, ScriptVectorITransform, "VectorITransform", "Transforms a vector with the inverse of a matrix." ); + + ScriptRegisterFunction( pVM, CalcSqrDistanceToAABB, "Returns the squared distance to a bounding box." ); + ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnAABB, "CalcClosestPointOnAABB", "Returns the closest point on a bounding box." ); + ScriptRegisterFunctionNamed( pVM, ScriptCalcDistanceToLine, "CalcDistanceToLine", "Returns the distance to a line." ); + ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLine, "CalcClosestPointOnLine", "Returns the closest point on a line." ); + ScriptRegisterFunctionNamed( pVM, ScriptCalcDistanceToLineSegment, "CalcDistanceToLineSegment", "Returns the distance to a line segment." ); + ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLineSegment, "CalcClosestPointOnLineSegment", "Returns the closest point on a line segment." ); + + ScriptRegisterFunction( pVM, SimpleSplineRemapVal, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" ); + ScriptRegisterFunction( pVM, SimpleSplineRemapValClamped, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" ); + ScriptRegisterFunction( pVM, Bias, "The curve is biased towards 0 or 1 based on biasAmt, which is between 0 and 1." ); + ScriptRegisterFunction( pVM, Gain, "Gain is similar to Bias, but biasAmt biases towards or away from 0.5." ); + ScriptRegisterFunction( pVM, SmoothCurve, "SmoothCurve maps a 0-1 value into another 0-1 value based on a cosine wave" ); + ScriptRegisterFunction( pVM, SmoothCurve_Tweak, "SmoothCurve peaks at flPeakPos, flPeakSharpness controls the sharpness of the peak" ); + ScriptRegisterFunctionNamed( pVM, ScriptExponentialDecay, "ExponentialDecay", "decayTo is factor the value should decay to in decayTime" ); +} diff --git a/vscript/vscript_bindings_math.h b/vscript/vscript_bindings_math.h new file mode 100644 index 00000000..c2d960b5 --- /dev/null +++ b/vscript/vscript_bindings_math.h @@ -0,0 +1,62 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ================= +// +// Purpose: Shared VScript math functions. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_BINDINGS_MATH +#define VSCRIPT_BINDINGS_MATH +#ifdef _WIN32 +#pragma once +#endif + +void RegisterMathBaseBindings( IScriptVM *pVM ); + +// Some base bindings require VM functions +extern IScriptVM *g_pScriptVM; + +//----------------------------------------------------------------------------- +// Exposes matrix3x4_t to VScript +//----------------------------------------------------------------------------- +inline matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass( hMat ); } + +static void ScriptFreeMatrixInstance( HSCRIPT hMat ) +{ + matrix3x4_t *smatrix = HScriptToClass( hMat ); + if (smatrix) + { + g_pScriptVM->RemoveInstance( hMat ); + delete smatrix; + } +} + +//----------------------------------------------------------------------------- +// Exposes Quaternion to VScript +//----------------------------------------------------------------------------- +class CScriptQuaternionInstanceHelper : public IScriptInstanceHelper +{ + bool ToString( void *p, char *pBuf, int bufSize ); + + bool Get( void *p, const char *pszKey, ScriptVariant_t &variant ); + bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); + + ScriptVariant_t *Add( void *p, ScriptVariant_t &variant ); + //ScriptVariant_t *Subtract( void *p, ScriptVariant_t &variant ); + //ScriptVariant_t *Multiply( void *p, ScriptVariant_t &variant ); + //ScriptVariant_t *Divide( void *p, ScriptVariant_t &variant ); +}; + +inline Quaternion *ToQuaternion( HSCRIPT hQuat ) { return HScriptToClass( hQuat ); } + +static void ScriptFreeQuaternionInstance( HSCRIPT hQuat ) +{ + Quaternion *squat = HScriptToClass( hQuat ); + if (squat) + { + g_pScriptVM->RemoveInstance( hQuat ); + delete squat; + } +} + +#endif diff --git a/vscript/vscript_squirrel.cpp b/vscript/vscript_squirrel.cpp new file mode 100644 index 00000000..5efb2314 --- /dev/null +++ b/vscript/vscript_squirrel.cpp @@ -0,0 +1,4080 @@ +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: Custom implementation of VScript in Source 2013, created from scratch +// using the Alien Swarm SDK as a reference for Valve's library. +// +// Author(s): ReDucTor (header written by Blixibon) +// +// $NoKeywords: $ +//=============================================================================// + +#include "vscript/ivscript.h" +#include "tier1/utlbuffer.h" +#include "tier1/utlmap.h" +#include "tier1/utlstring.h" + +#include "squirrel.h" +#include "sqstdaux.h" +//#include "sqstdblob.h" +//#include "sqstdsystem.h" +#include "sqstdtime.h" +//#include "sqstdio.h" +#include "sqstdmath.h" +#include "sqstdstring.h" + +// HACK: Include internal parts of squirrel for serialization +#include "squirrel/squirrel/sqobject.h" +#include "squirrel/squirrel/sqstate.h" +#include "squirrel/squirrel/sqtable.h" +#include "squirrel/squirrel/sqclass.h" +#include "squirrel/squirrel/sqfuncproto.h" +#include "squirrel/squirrel/sqvm.h" +#include "squirrel/squirrel/sqclosure.h" + +#include "tier1/utlbuffer.h" +#include "tier1/mapbase_con_groups.h" +#include "tier1/convar.h" + +#include "vscript_squirrel.nut" + +#include + +extern ConVar developer; + +struct WriteStateMap +{ + CUtlMap cache; + WriteStateMap() : cache(DefLessFunc(void*)) + {} + + bool CheckCache(CUtlBuffer* pBuffer, void* ptr) + { + auto idx = cache.Find(ptr); + if (idx != cache.InvalidIndex()) + { + pBuffer->PutInt(cache[idx]); + return true; + } + else + { + int newIdx = cache.Count(); + cache.Insert(ptr, newIdx); + pBuffer->PutInt(newIdx); + return false; + } + } +}; + +struct ReadStateMap +{ + CUtlMap cache; +#ifdef _DEBUG + CUtlMap allocated; +#endif + HSQUIRRELVM vm_; + ReadStateMap(HSQUIRRELVM vm) : + cache(DefLessFunc(int)), +#ifdef _DEBUG + allocated(DefLessFunc(int)), +#endif + vm_(vm) + {} + + ~ReadStateMap() + { + FOR_EACH_MAP_FAST(cache, i) + { + HSQOBJECT& obj = cache[i]; + sq_release(vm_, &obj); + } + } + + bool CheckCache(CUtlBuffer* pBuffer, HSQUIRRELVM vm, int * outmarker) + { + int marker = pBuffer->GetInt(); + + auto idx = cache.Find(marker); + +#ifdef _DEBUG + auto allocatedIdx = allocated.Find(marker); + bool hasSeen = allocatedIdx != allocated.InvalidIndex(); + if (!hasSeen) + { + allocated.Insert(marker, true); + } +#endif + + if (idx != cache.InvalidIndex()) + { + sq_pushobject(vm, cache[idx]); + return true; + } + else + { +#ifdef _DEBUG + Assert(!hasSeen); +#endif + *outmarker = marker; + return false; + } + } + + void StoreInCache(int marker, HSQOBJECT& obj) + { + cache.Insert(marker, obj); + } + + void StoreTopInCache(int marker) + { + HSQOBJECT obj; + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + cache.Insert(marker, obj); + } +}; + +class SquirrelVM : public IScriptVM +{ +public: + virtual bool Init() override; + virtual void Shutdown() override; + + virtual bool ConnectDebugger() override; + virtual void DisconnectDebugger() override; + + virtual ScriptLanguage_t GetLanguage() override; + virtual const char* GetLanguageName() override; + + virtual void AddSearchPath(const char* pszSearchPath) override; + + //-------------------------------------------------------- + + virtual bool Frame(float simTime) override; + + //-------------------------------------------------------- + // Simple script usage + //-------------------------------------------------------- + virtual ScriptStatus_t Run(const char* pszScript, bool bWait = true) override; + + //-------------------------------------------------------- + // Compilation + //-------------------------------------------------------- + virtual HSCRIPT CompileScript(const char* pszScript, const char* pszId = NULL) override; + virtual void ReleaseScript(HSCRIPT) override; + + //-------------------------------------------------------- + // Execution of compiled + //-------------------------------------------------------- + virtual ScriptStatus_t Run(HSCRIPT hScript, HSCRIPT hScope = NULL, bool bWait = true) override; + virtual ScriptStatus_t Run(HSCRIPT hScript, bool bWait) override; + + //-------------------------------------------------------- + // Scope + //-------------------------------------------------------- + virtual HSCRIPT CreateScope(const char* pszScope, HSCRIPT hParent = NULL) override; + virtual void ReleaseScope(HSCRIPT hScript) override; + + //-------------------------------------------------------- + // Script functions + //-------------------------------------------------------- + virtual HSCRIPT LookupFunction(const char* pszFunction, HSCRIPT hScope = NULL) override; + virtual void ReleaseFunction(HSCRIPT hScript) override; + + //-------------------------------------------------------- + // Script functions (raw, use Call()) + //-------------------------------------------------------- + virtual ScriptStatus_t ExecuteFunction(HSCRIPT hFunction, ScriptVariant_t* pArgs, int nArgs, ScriptVariant_t* pReturn, HSCRIPT hScope, bool bWait) override; + + //-------------------------------------------------------- + // Hooks + //-------------------------------------------------------- + virtual HScriptRaw HScriptToRaw( HSCRIPT val ) override; + virtual ScriptStatus_t ExecuteHookFunction( const char *pszEventName, ScriptVariant_t *pArgs, int nArgs, ScriptVariant_t *pReturn, HSCRIPT hScope, bool bWait ) override; + + //-------------------------------------------------------- + // External functions + //-------------------------------------------------------- + virtual void RegisterFunction(ScriptFunctionBinding_t* pScriptFunction) override; + + //-------------------------------------------------------- + // External classes + //-------------------------------------------------------- + virtual bool RegisterClass(ScriptClassDesc_t* pClassDesc) override; + + //-------------------------------------------------------- + // External constants + //-------------------------------------------------------- + virtual void RegisterConstant(ScriptConstantBinding_t *pScriptConstant) override; + + //-------------------------------------------------------- + // External enums + //-------------------------------------------------------- + virtual void RegisterEnum(ScriptEnumDesc_t *pEnumDesc) override; + + //-------------------------------------------------------- + // External hooks + //-------------------------------------------------------- + virtual void RegisterHook(ScriptHook_t *pHookDesc) override; + + //-------------------------------------------------------- + // External instances. Note class will be auto-registered. + //-------------------------------------------------------- + + virtual HSCRIPT RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct = false) override; + virtual void SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId) override; + virtual void RemoveInstance(HSCRIPT hInstance) override; + + virtual void* GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpectedType = NULL) override; + + //---------------------------------------------------------------------------- + + virtual bool GenerateUniqueKey(const char* pszRoot, char* pBuf, int nBufSize) override; + + //---------------------------------------------------------------------------- + + virtual bool ValueExists(HSCRIPT hScope, const char* pszKey) override; + + virtual bool SetValue(HSCRIPT hScope, const char* pszKey, const char* pszValue) override; + virtual bool SetValue(HSCRIPT hScope, const char* pszKey, const ScriptVariant_t& value) override; + virtual bool SetValue(HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val) override; + + virtual void CreateTable(ScriptVariant_t& Table) override; + virtual int GetNumTableEntries(HSCRIPT hScope) override; + virtual int GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey, ScriptVariant_t* pValue) override; + + virtual bool GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue) override; + virtual bool GetValue(HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue) override; + virtual void ReleaseValue(ScriptVariant_t& value) override; + + virtual bool ClearValue(HSCRIPT hScope, const char* pszKey) override; + virtual bool ClearValue( HSCRIPT hScope, ScriptVariant_t pKey ) override; + + virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override; + virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override; + + //---------------------------------------------------------------------------- + + virtual void WriteState(CUtlBuffer* pBuffer) override; + virtual void ReadState(CUtlBuffer* pBuffer) override; + virtual void RemoveOrphanInstances() override; + + virtual void DumpState() override; + + virtual void SetOutputCallback(ScriptOutputFunc_t pFunc) override; + virtual void SetErrorCallback(ScriptErrorFunc_t pFunc) override; + + //---------------------------------------------------------------------------- + + virtual bool RaiseException(const char* pszExceptionText) override; + + + void WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQInteger idx); + void ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState); + HSQUIRRELVM vm_ = nullptr; + HSQOBJECT lastError_; + HSQOBJECT vectorClass_; + HSQOBJECT regexpClass_; +}; + +static char TYPETAG_VECTOR[] = "VectorTypeTag"; + +namespace SQVector +{ + SQInteger Construct(HSQUIRRELVM vm) + { + // TODO: There must be a nicer way to store the data with the actual instance, there are + // default slots but they are really just pointers anyway and you need to hold a member + // pointer which is yet another pointer dereference + int numParams = sq_gettop(vm); + + float x = 0; + float y = 0; + float z = 0; + + if ((numParams >= 2 && SQ_FAILED(sq_getfloat(vm, 2, &x))) || + (numParams >= 3 && SQ_FAILED(sq_getfloat(vm, 3, &y))) || + (numParams >= 4 && SQ_FAILED(sq_getfloat(vm, 4, &z)))) + { + return sq_throwerror(vm, "Expected Vector(float x, float y, float z)"); + } + + SQUserPointer p; + sq_getinstanceup(vm, 1, &p, 0); + new (p) Vector(x, y, z); + + return 0; + } + + SQInteger _get(HSQUIRRELVM vm) + { + const char* key = nullptr; + sq_getstring(vm, 2, &key); + + if (key == nullptr) + { + return sq_throwerror(vm, "Expected Vector._get(string)"); + } + + if (key[0] < 'x' || key['0'] > 'z' || key[1] != '\0') + { + return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key); + } + + Vector* v = nullptr; + if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Unable to get Vector"); + } + + int idx = key[0] - 'x'; + sq_pushfloat(vm, (*v)[idx]); + return 1; + } + + SQInteger _set(HSQUIRRELVM vm) + { + const char* key = nullptr; + sq_getstring(vm, 2, &key); + + if (key == nullptr) + { + return sq_throwerror(vm, "Expected Vector._set(string)"); + } + + if (key[0] < 'x' || key['0'] > 'z' || key[1] != '\0') + { + return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key); + } + + Vector* v = nullptr; + if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Unable to get Vector"); + } + + float val = 0; + if (SQ_FAILED(sq_getfloat(vm, 3, &val))) + { + return sqstd_throwerrorf(vm, "Vector.%s expects float", key); + } + + int idx = key[0] - 'x'; + (*v)[idx] = val; + return 0; + } + + SQInteger _add(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) + (*v2)); + sq_remove(vm, -2); + + return 1; + } + + SQInteger _sub(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) - (*v2)); + sq_remove(vm, -2); + + return 1; + } + + SQInteger _multiply(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + float s = 0.0; + Vector* v2 = nullptr; + + if ( SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)) ) + { + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) * s); + sq_remove(vm, -2); + + return 1; + } + else if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)) ) + { + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) * (*v2)); + sq_remove(vm, -2); + + return 1; + } + else + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + } + + SQInteger _divide(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + float s = 0.0; + Vector* v2 = nullptr; + + if ( SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)) ) + { + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) / s); + sq_remove(vm, -2); + + return 1; + } + else if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)) ) + { + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) / (*v2)); + sq_remove(vm, -2); + + return 1; + } + else + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + } + + SQInteger _unm(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector(-v1->x, -v1->y, -v1->z); + sq_remove(vm, -2); + + return 1; + } + + SQInteger weakref(HSQUIRRELVM vm) + { + sq_weakref(vm, 1); + return 1; + } + + SQInteger getclass(HSQUIRRELVM vm) + { + sq_getclass(vm, 1); + sq_push(vm, -1); + return 1; + } + + // multi purpose - copy from input vector, or init with 3 float input + SQInteger Set(HSQUIRRELVM vm) + { + SQInteger top = sq_gettop(vm); + Vector* v1 = nullptr; + + if ( top < 2 || SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + Vector* v2 = nullptr; + + if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)) ) + { + if ( top != 2 ) + return sq_throwerror(vm, "Expected (Vector, Vector)"); + + VectorCopy( *v2, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + float x, y, z; + + if ( top == 4 && + SQ_SUCCEEDED(sq_getfloat(vm, 2, &x)) && + SQ_SUCCEEDED(sq_getfloat(vm, 3, &y)) && + SQ_SUCCEEDED(sq_getfloat(vm, 4, &z)) ) + { + v1->Init( x, y, z ); + sq_pop( vm, 3 ); + + return 1; + } + + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + SQInteger Add(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + VectorAdd( *v1, *v2, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + SQInteger Subtract(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + VectorSubtract( *v1, *v2, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + SQInteger Multiply(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + Vector* v2 = nullptr; + + if ( SQ_SUCCEEDED(sq_getinstanceup( vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR )) ) + { + VectorMultiply( *v1, *v2, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + float flInput; + + if ( SQ_SUCCEEDED(sq_getfloat( vm, 2, &flInput )) ) + { + VectorMultiply( *v1, flInput, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + SQInteger Divide(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + Vector* v2 = nullptr; + + if ( SQ_SUCCEEDED(sq_getinstanceup( vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR )) ) + { + VectorDivide( *v1, *v2, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + float flInput; + + if ( SQ_SUCCEEDED(sq_getfloat( vm, 2, &flInput )) ) + { + VectorDivide( *v1, flInput, *v1 ); + sq_remove( vm, -1 ); + + return 1; + } + + return sq_throwerror(vm, "Expected (Vector, Vector|float)"); + } + + SQInteger DistTo(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_pushfloat( vm, v1->DistTo(*v2) ); + + return 1; + } + + SQInteger DistToSqr(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_pushfloat( vm, v1->DistToSqr(*v2) ); + + return 1; + } + + SQInteger IsEqualTo(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) < 2 || // bother checking > 3? + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)) ) + { + return sq_throwerror(vm, "Expected (Vector, Vector, float)"); + } + + float tolerance = 0.0f; + sq_getfloat( vm, 3, &tolerance ); + + sq_pushbool( vm, VectorsAreEqual( *v1, *v2, tolerance ) ); + + return 1; + } + + SQInteger Length(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_pushfloat(vm, v1->Length()); + return 1; + } + + SQInteger LengthSqr(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_pushfloat(vm, v1->LengthSqr()); + return 1; + } + + SQInteger Length2D(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_pushfloat(vm, v1->Length2D()); + return 1; + } + + SQInteger Length2DSqr(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_pushfloat(vm, v1->Length2DSqr()); + return 1; + } + + SQInteger Normalized(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1).Normalized()); + sq_remove(vm, -2); + + return 1; + } + + SQInteger Norm(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + float len = v1->NormalizeInPlace(); + sq_pushfloat(vm, len); + + return 1; + } + + SQInteger Scale(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + float s = 0.0f; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_SUCCEEDED(sq_getfloat(vm, 2, &s))) + { + return sq_throwerror(vm, "Expected (Vector, float)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1) * s); + sq_remove(vm, -2); + + return 1; + } + + SQInteger Dot(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_pushfloat(vm, v1->Dot(*v2)); + return 1; + } + + SQInteger ToKVString(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sqstd_pushstringf(vm, "%f %f %f", v1->x, v1->y, v1->z); + return 1; + } + + SQInteger FromKVString(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + const char* szInput; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getstring(vm, 2, &szInput)) ) + { + return sq_throwerror(vm, "Expected (Vector, string)"); + } + + float x = 0.0f, y = 0.0f, z = 0.0f; + + if ( sscanf( szInput, "%f %f %f", &x, &y, &z ) < 3 ) + { + // Return null while invalidating the input vector. + // This allows the user to easily check for input errors without halting. + + sq_pushnull(vm); + *v1 = vec3_invalid; + + return 1; + } + + v1->x = x; + v1->y = y; + v1->z = z; + + // return input vector + sq_remove( vm, -1 ); + + return 1; + } + + SQInteger Cross(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* v2 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector)"); + } + + sq_getclass(vm, 1); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector((*v1).Cross(*v2)); + sq_remove(vm, -2); + + return 1; + } + + SQInteger WithinAABox(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + Vector* mins = nullptr; + Vector* maxs = nullptr; + + if (sq_gettop(vm) != 3 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&mins, TYPETAG_VECTOR)) || + SQ_FAILED(sq_getinstanceup(vm, 3, (SQUserPointer*)&maxs, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector, Vector, Vector)"); + } + + sq_pushbool( vm, v1->WithinAABox( *mins, *maxs ) ); + + return 1; + } + + SQInteger ToString(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 1 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + sqstd_pushstringf(vm, "(Vector %p [%f %f %f])", (void*)v1, v1->x, v1->y, v1->z); + return 1; + } + + SQInteger TypeOf(HSQUIRRELVM vm) + { + sq_pushstring(vm, "Vector", -1); + return 1; + } + + SQInteger Nexti(HSQUIRRELVM vm) + { + Vector* v1 = nullptr; + + if (sq_gettop(vm) != 2 || + SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR))) + { + return sq_throwerror(vm, "Expected (Vector)"); + } + + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm, 2, &obj); + + const char* curkey = nullptr; + + if (sq_isnull(obj)) + { + curkey = "w"; + } + else if (sq_isstring(obj)) + { + curkey = sq_objtostring(&obj); + } + else + { + return sq_throwerror(vm, "Invalid iterator"); + } + + Assert(curkey && curkey[0] >= 'w' && curkey[0] <= 'z'); + + if (curkey[0] == 'z') + { + // Reached the end + sq_pushnull(vm); + return 1; + } + + char newkey = curkey[0] + 1; + sq_pushstring(vm, &newkey, 1); + + return 1; + } + + static const SQRegFunction funcs[] = { + {_SC("constructor"), Construct,0,nullptr}, + {_SC("_get"), _get, 2, _SC(".s")}, + {_SC("_set"), _set, 3, _SC(".sn")}, + {_SC("_add"), _add, 2, _SC("..")}, + {_SC("_sub"), _sub, 2, _SC("..")}, + {_SC("_mul"), _multiply, 2, _SC("..")}, + {_SC("_div"), _divide, 2, _SC("..")}, + {_SC("_unm"), _unm, 1, _SC(".")}, + {_SC("weakref"), weakref, 1, _SC(".")}, + {_SC("getclass"), getclass, 1, _SC(".")}, + {_SC("Set"), Set, -2, _SC("..nn")}, + {_SC("Add"), Add, 2, _SC("..")}, + {_SC("Subtract"), Subtract, 2, _SC("..")}, + {_SC("Multiply"), Multiply, 2, _SC("..")}, + {_SC("Divide"), Divide, 2, _SC("..")}, + {_SC("DistTo"), DistTo, 2, _SC("..")}, + {_SC("DistToSqr"), DistToSqr, 2, _SC("..")}, + {_SC("IsEqualTo"), IsEqualTo, -2, _SC("..n")}, + {_SC("Length"), Length, 1, _SC(".")}, + {_SC("LengthSqr"), LengthSqr, 1, _SC(".")}, + {_SC("Length2D"), Length2D, 1, _SC(".")}, + {_SC("Length2DSqr"), Length2DSqr, 1, _SC(".")}, + {_SC("Normalized"), Normalized, 1, _SC(".")}, + {_SC("Norm"), Norm, 1, _SC(".")}, + {_SC("Scale"), Scale, 2, _SC(".n")}, // identical to _multiply + {_SC("Dot"), Dot, 2, _SC("..")}, + {_SC("Cross"), Cross, 2, _SC("..")}, + {_SC("WithinAABox"), WithinAABox, 3, _SC("...")}, + {_SC("ToKVString"), ToKVString, 1, _SC(".")}, + {_SC("FromKVString"), FromKVString, 2, _SC(".s")}, + {_SC("_tostring"), ToString, 1, _SC(".")}, + {_SC("_typeof"), TypeOf, 1, _SC(".")}, + {_SC("_nexti"), Nexti, 2, _SC("..")}, + + {nullptr,(SQFUNCTION)0,0,nullptr} + }; + + HSQOBJECT register_class(HSQUIRRELVM v) + { + sq_pushstring(v, _SC("Vector"), -1); + sq_newclass(v, SQFalse); + sq_settypetag(v, -1, TYPETAG_VECTOR); + sq_setclassudsize(v, -1, sizeof(Vector)); + SQInteger i = 0; + while (funcs[i].name != 0) { + const SQRegFunction& f = funcs[i]; + sq_pushstring(v, f.name, -1); + sq_newclosure(v, f.f, 0); + sq_setparamscheck(v, f.nparamscheck, f.typemask); + sq_setnativeclosurename(v, -1, f.name); + sq_newslot(v, -3, SQFalse); + i++; + } + HSQOBJECT klass; + sq_resetobject(&klass); + sq_getstackobj(v, -1, &klass); + sq_addref(v, &klass); + sq_newslot(v, -3, SQFalse); + return klass; + } +} // SQVector + +struct ClassInstanceData +{ + ClassInstanceData(void* instance, ScriptClassDesc_t* desc, const char* instanceId = nullptr, bool allowDestruct = false) : + instance(instance), + desc(desc), + instanceId(instanceId), + allowDestruct(allowDestruct) + {} + + void* instance; + ScriptClassDesc_t* desc; + CUtlString instanceId; + + // Indicates this game-created instance is a weak reference and can be destructed (Blixibon) + bool allowDestruct; +}; + +bool CreateParamCheck(const ScriptFunctionBinding_t& func, char* output) +{ + *output++ = '.'; + for (int i = 0; i < func.m_desc.m_Parameters.Count(); ++i) + { + switch (func.m_desc.m_Parameters[i]) + { + case FIELD_FLOAT: + case FIELD_INTEGER: + *output++ = 'n'; + break; + case FIELD_CSTRING: + *output++ = 's'; + break; + case FIELD_VECTOR: + *output++ = 'x'; // Generic instance, we validate on arrival + break; + case FIELD_BOOLEAN: + *output++ = 'b'; + break; + case FIELD_CHARACTER: + *output++ = 's'; + break; + case FIELD_HSCRIPT: + *output++ = '.'; + break; + default: + Assert(!"Unsupported type"); + return false; + }; + } + *output++ = 0; + return true; +} + +void PushVariant(HSQUIRRELVM vm, const ScriptVariant_t& value) +{ + switch (value.m_type) + { + case FIELD_VOID: + sq_pushnull(vm); + break; + case FIELD_FLOAT: + sq_pushfloat(vm, value); + break; + case FIELD_CSTRING: + if ( value.m_pszString ) + sq_pushstring(vm, value, -1); + else + sq_pushnull(vm); + break; + case FIELD_VECTOR: + { + SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm); + assert(pSquirrelVM); + sq_pushobject(vm, pSquirrelVM->vectorClass_); + sq_createinstance(vm, -1); + SQUserPointer p; + sq_getinstanceup(vm, -1, &p, 0); + new(p) Vector(static_cast(value)); + sq_remove(vm, -2); + break; + } + case FIELD_INTEGER: + sq_pushinteger(vm, value.m_int); + break; + case FIELD_BOOLEAN: + sq_pushbool(vm, value.m_bool); + break; + case FIELD_CHARACTER: + { + char buf[2] = { value.m_char, 0 }; + sq_pushstring(vm, buf, 1); + break; + } + case FIELD_HSCRIPT: + if (value.m_hScript) + { + sq_pushobject(vm, *((HSQOBJECT*)value.m_hScript)); + } + else + { + sq_pushnull(vm); + } + break; + } +} + +void GetVariantScriptString(const ScriptVariant_t& value, char *szValue, int iSize) +{ + switch (value.m_type) + { + case FIELD_VOID: + V_strncpy( szValue, "null", iSize ); + break; + case FIELD_FLOAT: + V_snprintf( szValue, iSize, "%f", value.m_float ); + break; + case FIELD_CSTRING: + V_snprintf( szValue, iSize, "\"%s\"", value.m_pszString ); + break; + case FIELD_VECTOR: + V_snprintf( szValue, iSize, "Vector( %f, %f, %f )", value.m_pVector->x, value.m_pVector->y, value.m_pVector->z ); + break; + case FIELD_INTEGER: + V_snprintf( szValue, iSize, "%i", value.m_int ); + break; + case FIELD_BOOLEAN: + V_snprintf( szValue, iSize, "%d", value.m_bool ); + break; + case FIELD_CHARACTER: + //char buf[2] = { value.m_char, 0 }; + V_snprintf( szValue, iSize, "\"%c\"", value.m_char ); + break; + } +} + +bool getVariant(HSQUIRRELVM vm, SQInteger idx, ScriptVariant_t& variant) +{ + switch (sq_gettype(vm, idx)) + { + case OT_NULL: + { + // TODO: Should this be (HSCRIPT)nullptr + variant.m_type = FIELD_VOID; + return true; + } + case OT_INTEGER: + { + SQInteger val; + if (SQ_FAILED(sq_getinteger(vm, idx, &val))) + { + return false; + } + variant = (int)val; + return true; + } + case OT_FLOAT: + { + SQFloat val; + if (SQ_FAILED(sq_getfloat(vm, idx, &val))) + { + return false; + } + variant = (float)val; + return true; + } + case OT_BOOL: + { + SQBool val; + if (SQ_FAILED(sq_getbool(vm, idx, &val))) + { + return false; + } + variant = val ? true : false; + return true; + } + case OT_STRING: + { + const char* val; + SQInteger size = 0; + if (SQ_FAILED(sq_getstringandsize(vm, idx, &val, &size))) + { + return false; + } + char* buffer = new char[size + 1]; + V_memcpy(buffer, val, size); + buffer[size] = 0; + variant = buffer; + variant.m_flags |= SV_FREE; + return true; + } + case OT_INSTANCE: + { + Vector* v = nullptr; + SQUserPointer tag; + if (SQ_SUCCEEDED(sq_gettypetag(vm, idx, &tag)) && + tag == TYPETAG_VECTOR && + SQ_SUCCEEDED(sq_getinstanceup(vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR))) + { + variant = new Vector(*v); + variant.m_flags |= SV_FREE; + return true; + } + // fall-through for non-vector + } + default: + { + HSQOBJECT* obj = new HSQOBJECT; + sq_resetobject(obj); + sq_getstackobj(vm, idx, obj); + sq_addref(vm, obj); + variant = (HSCRIPT)obj; + } + }; + + + return true; +} + +SQInteger function_stub(HSQUIRRELVM vm) +{ + SQInteger top = sq_gettop(vm); + + SQUserPointer userptr = nullptr; + sq_getuserpointer(vm, top, &userptr); + + Assert(userptr); + + ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr; + + auto nargs = pFunc->m_desc.m_Parameters.Count(); + + if (nargs > top) + { + // TODO: Handle optional parameters? + return sq_throwerror(vm, "Invalid number of parameters"); + } + + CUtlVector params; + params.SetCount(nargs); + + for (int i = 0; i < nargs; ++i) + { + switch (pFunc->m_desc.m_Parameters[i]) + { + case FIELD_FLOAT: + { + float val = 0.0; + if (SQ_FAILED(sq_getfloat(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected float"); + params[i] = val; + break; + } + case FIELD_CSTRING: + { + const char* val; + if (SQ_FAILED(sq_getstring(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected string"); + params[i] = val; + break; + } + case FIELD_VECTOR: + { + Vector* val; + if (SQ_FAILED(sq_getinstanceup(vm, i + 2, (SQUserPointer*)&val, TYPETAG_VECTOR))) + return sq_throwerror(vm, "Expected Vector"); + params[i] = *val; + break; + } + case FIELD_INTEGER: + { + SQInteger val = 0; + if (SQ_FAILED(sq_getinteger(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected integer"); + params[i] = (int)val; + break; + } + case FIELD_BOOLEAN: + { + SQBool val = 0; + if (SQ_FAILED(sq_getbool(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected bool"); + params[i] = val ? true : false; + break; + } + case FIELD_CHARACTER: + { + const char* val; + if (SQ_FAILED(sq_getstring(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected string"); + params[i] = val[i]; + break; + } + case FIELD_HSCRIPT: + { + HSQOBJECT val; + if (SQ_FAILED(sq_getstackobj(vm, i + 2, &val))) + return sq_throwerror(vm, "Expected handle"); + + if (sq_isnull(val)) + { + params[i] = (HSCRIPT)nullptr; + } + else + { + HSQOBJECT* pObject = new HSQOBJECT; + *pObject = val; + sq_addref(vm, pObject); + params[i] = (HSCRIPT)pObject; + } + break; + } + default: + Assert(!"Unsupported type"); + return false; + } + } + + void* instance = nullptr; + + if (pFunc->m_flags & SF_MEMBER_FUNC) + { + SQUserPointer self; + sq_getinstanceup(vm, 1, &self, nullptr); + + if (!self) + { + return sq_throwerror(vm, "Accessed null instance"); + } + + instance = ((ClassInstanceData*)self)->instance; + } + + ScriptVariant_t retval; + + SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm); + assert(pSquirrelVM); + + sq_resetobject(&pSquirrelVM->lastError_); + + (*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs, + pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &retval); + + if (!sq_isnull(pSquirrelVM->lastError_)) + { + sq_pushobject(vm, pSquirrelVM->lastError_); + sq_resetobject(&pSquirrelVM->lastError_); + return sq_throwobject(vm); + } + + PushVariant(vm, retval); + + if (retval.m_type == FIELD_VECTOR) + delete retval.m_pVector; + + return pFunc->m_desc.m_ReturnType != FIELD_VOID; +} + + +SQInteger destructor_stub(SQUserPointer p, SQInteger size) +{ + auto classInstanceData = (ClassInstanceData*)p; + + if (classInstanceData->desc->m_pfnDestruct) + classInstanceData->desc->m_pfnDestruct(classInstanceData->instance); + + classInstanceData->~ClassInstanceData(); + return 0; +} + +SQInteger destructor_stub_instance(SQUserPointer p, SQInteger size) +{ + auto classInstanceData = (ClassInstanceData*)p; + // We don't call destructor here because this is owned by the game + classInstanceData->~ClassInstanceData(); + return 0; +} + +SQInteger constructor_stub(HSQUIRRELVM vm) +{ + ScriptClassDesc_t* pClassDesc = nullptr; + sq_gettypetag(vm, 1, (SQUserPointer*)&pClassDesc); + + if (!pClassDesc->m_pfnConstruct) + { + return sqstd_throwerrorf(vm, "Unable to construct instances of %s", pClassDesc->m_pszScriptName); + } + + SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm); + assert(pSquirrelVM); + + sq_resetobject(&pSquirrelVM->lastError_); + + void* instance = pClassDesc->m_pfnConstruct(); + + if (!sq_isnull(pSquirrelVM->lastError_)) + { + sq_pushobject(vm, pSquirrelVM->lastError_); + sq_resetobject(&pSquirrelVM->lastError_); + return sq_throwobject(vm); + } + + { + SQUserPointer p; + sq_getinstanceup(vm, 1, &p, 0); + new(p) ClassInstanceData(instance, pClassDesc, nullptr, true); + } + + sq_setreleasehook(vm, 1, &destructor_stub); + + return 0; +} + +SQInteger tostring_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + char buffer[128] = ""; + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper && + classInstanceData->desc->pHelper->ToString(classInstanceData->instance, buffer, sizeof(buffer))) + { + sq_pushstring(vm, buffer, -1); + } + else if (classInstanceData) + { + sqstd_pushstringf(vm, "(%s : 0x%p)", classInstanceData->desc->m_pszScriptName, classInstanceData->instance); + } + else + { + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm, 1, &obj); + // Semi-based on SQVM::ToString default case + sqstd_pushstringf(vm, "(%s: 0x%p)", IdType2Name(obj._type), (void*)_rawval(obj)); + } + + return 1; +} + +SQInteger get_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + const char* key = nullptr; + sq_getstring(vm, 2, &key); + + if (key == nullptr) + { + return sq_throwerror(vm, "Expected _get(string)"); + } + + ScriptVariant_t var; + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper && + classInstanceData->desc->pHelper->Get(classInstanceData->instance, key, var)) + { + PushVariant(vm, var); + } + else + { + return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key); + } + + return 1; +} + +SQInteger set_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + const char* key = nullptr; + sq_getstring(vm, 2, &key); + + if (key == nullptr) + { + return sq_throwerror(vm, "Expected _set(string)"); + } + + ScriptVariant_t var; + getVariant( vm, -1, var ); + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper && + classInstanceData->desc->pHelper->Set(classInstanceData->instance, key, var)) + { + sq_pop(vm, 1); + } + else + { + sq_pop(vm, 1); + return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key); + } + + return 0; +} + +SQInteger add_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + ScriptVariant_t var; + getVariant( vm, 1, var ); + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper) + { + ScriptVariant_t *result = classInstanceData->desc->pHelper->Add( classInstanceData->instance, var ); + if (result != nullptr) + { + PushVariant( vm, *result ); + sq_pop(vm, 1); + return 1; + } + } + + sq_pop(vm, 1); + return sqstd_throwerrorf(vm, "invalid arith op +"); +} + +SQInteger sub_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + ScriptVariant_t var; + getVariant( vm, 1, var ); + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper) + { + ScriptVariant_t *result = classInstanceData->desc->pHelper->Subtract( classInstanceData->instance, var ); + if (result != nullptr) + { + PushVariant( vm, *result ); + sq_pop(vm, 1); + return 1; + } + } + + sq_pop(vm, 1); + return sqstd_throwerrorf(vm, "invalid arith op -"); +} + +SQInteger mul_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + ScriptVariant_t var; + getVariant( vm, 1, var ); + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper ) + { + ScriptVariant_t *result = classInstanceData->desc->pHelper->Add( classInstanceData->instance, var ); + if (result != nullptr) + { + PushVariant( vm, *result ); + sq_pop(vm, 1); + return 1; + } + } + + sq_pop(vm, 1); + return sqstd_throwerrorf(vm, "invalid arith op *"); +} + +SQInteger div_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + + ScriptVariant_t var; + getVariant( vm, 1, var ); + + if (classInstanceData && + classInstanceData->instance && + classInstanceData->desc->pHelper ) + { + ScriptVariant_t *result = classInstanceData->desc->pHelper->Add( classInstanceData->instance, var ); + if (result != nullptr) + { + PushVariant( vm, *result ); + sq_pop(vm, 1); + return 1; + } + } + + sq_pop(vm, 1); + return sqstd_throwerrorf(vm, "invalid arith op /"); +} + +SQInteger IsValid_stub(HSQUIRRELVM vm) +{ + ClassInstanceData* classInstanceData = nullptr; + sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0); + sq_pushbool(vm, classInstanceData != nullptr); + return 1; +} + +SQInteger weakref_stub(HSQUIRRELVM vm) +{ + sq_weakref(vm, 1); + return 1; +} + +SQInteger getclass_stub(HSQUIRRELVM vm) +{ + sq_getclass(vm, 1); + sq_push(vm, -1); + return 1; +} + +struct SquirrelSafeCheck +{ + SquirrelSafeCheck(HSQUIRRELVM vm, int outputCount = 0) : + vm_{ vm }, + top_{ sq_gettop(vm) }, + outputCount_{ outputCount } + {} + + ~SquirrelSafeCheck() + { + SQInteger curtop = sq_gettop(vm_); + SQInteger diff = curtop - outputCount_; + if ( top_ != diff ) + { + Assert(!"Squirrel VM stack is not consistent"); + Error("Squirrel VM stack is not consistent\n"); + } + + // TODO: Handle error state checks + } + + HSQUIRRELVM vm_; + SQInteger top_; + SQInteger outputCount_; +}; + + +void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...) +{ + va_list args; + char buffer[2048]; + va_start(args, format); + V_vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + CGMsg(0, CON_GROUP_VSCRIPT_PRINT, "%s", buffer); +} + +void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...) +{ + va_list args; + char buffer[2048]; + va_start(args, format); + V_vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + Warning("%s", buffer); +} + +const char * ScriptDataTypeToName(ScriptDataType_t datatype) +{ + switch (datatype) + { + case FIELD_VOID: return "void"; + case FIELD_FLOAT: return "float"; + case FIELD_CSTRING: return "string"; + case FIELD_VECTOR: return "Vector"; + case FIELD_INTEGER: return "int"; + case FIELD_BOOLEAN: return "bool"; + case FIELD_CHARACTER: return "char"; + case FIELD_HSCRIPT: return "handle"; + case FIELD_VARIANT: return "variant"; + default: return ""; + } +} + + +#define PushDocumentationRegisterFunction( szName ) \ + sq_pushroottable(vm); \ + sq_pushstring(vm, "__Documentation", -1); \ + sq_get(vm, -2); \ + sq_pushstring(vm, szName, -1); \ + sq_get(vm, -2); \ + sq_push(vm, -2); + +#define CallDocumentationRegisterFunction( paramcount ) \ + sq_call(vm, paramcount+1, SQFalse, SQFalse); \ + sq_pop(vm, 3); + +void RegisterDocumentation(HSQUIRRELVM vm, const ScriptFuncDescriptor_t& pFuncDesc, ScriptClassDesc_t* pClassDesc = nullptr) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + if (pFuncDesc.m_pszDescription && pFuncDesc.m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + char name[256] = ""; + + if (pClassDesc) + { + V_strcat_safe(name, pClassDesc->m_pszScriptName); + V_strcat_safe(name, "::"); + } + + V_strcat_safe(name, pFuncDesc.m_pszScriptName); + + + char signature[256] = ""; + V_snprintf(signature, sizeof(signature), "%s %s(", ScriptDataTypeToName(pFuncDesc.m_ReturnType), name); + + for (int i = 0; i < pFuncDesc.m_Parameters.Count(); ++i) + { + if (i != 0) + V_strcat_safe(signature, ", "); + + V_strcat_safe(signature, ScriptDataTypeToName(pFuncDesc.m_Parameters[i])); + } + + V_strcat_safe(signature, ")"); + + // RegisterHelp(name, signature, description) + PushDocumentationRegisterFunction( "RegisterHelp" ); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, signature, -1); + sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1); + CallDocumentationRegisterFunction( 3 ); +} + +void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassDesc) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + const char *name = pClassDesc->m_pszScriptName; + const char *base = ""; + if (pClassDesc->m_pBaseDesc) + { + base = pClassDesc->m_pBaseDesc->m_pszScriptName; + } + + const char *description = pClassDesc->m_pszDescription; + if (description) + { + if (description[0] == SCRIPT_HIDE[0]) + return; + if (description[0] == SCRIPT_SINGLETON[0]) + description++; + } + else + { + description = ""; + } + + // RegisterClassHelp(name, base, description) + PushDocumentationRegisterFunction( "RegisterClassHelp" ); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, base, -1); + sq_pushstring(vm, description, -1); + CallDocumentationRegisterFunction( 3 ); +} + +void RegisterEnumDocumentation(HSQUIRRELVM vm, const ScriptEnumDesc_t* pClassDesc) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + if (pClassDesc->m_pszDescription && pClassDesc->m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + const char *name = pClassDesc->m_pszScriptName; + + // RegisterEnumHelp(name, description) + PushDocumentationRegisterFunction( "RegisterEnumHelp" ); + sq_pushstring(vm, name, -1); + sq_pushinteger(vm, pClassDesc->m_ConstantBindings.Count()); + sq_pushstring(vm, pClassDesc->m_pszDescription ? pClassDesc->m_pszDescription : "", -1); + CallDocumentationRegisterFunction( 3 ); +} + +void RegisterConstantDocumentation( HSQUIRRELVM vm, const ScriptConstantBinding_t* pConstDesc, const char *pszAsString, ScriptEnumDesc_t* pEnumDesc = nullptr ) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + if (pConstDesc->m_pszDescription && pConstDesc->m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + char name[256] = ""; + + if (pEnumDesc) + { + V_strcat_safe(name, pEnumDesc->m_pszScriptName); + V_strcat_safe(name, "."); + } + + V_strcat_safe(name, pConstDesc->m_pszScriptName); + + char signature[256] = ""; + V_snprintf(signature, sizeof(signature), "%s (%s)", pszAsString, ScriptDataTypeToName(pConstDesc->m_data.m_type)); + + // RegisterConstHelp(name, signature, description) + PushDocumentationRegisterFunction( "RegisterConstHelp" ); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, signature, -1); + sq_pushstring(vm, pConstDesc->m_pszDescription ? pConstDesc->m_pszDescription : "", -1); + CallDocumentationRegisterFunction( 3 ); +} + +void RegisterHookDocumentation(HSQUIRRELVM vm, const ScriptHook_t* pHook, const ScriptFuncDescriptor_t& pFuncDesc, ScriptClassDesc_t* pClassDesc = nullptr) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + if (pFuncDesc.m_pszDescription && pFuncDesc.m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + char name[256] = ""; + + if (pClassDesc) + { + V_strcat_safe(name, pClassDesc->m_pszScriptName); + V_strcat_safe(name, " -> "); + } + + V_strcat_safe(name, pFuncDesc.m_pszScriptName); + + + char signature[256] = ""; + V_snprintf(signature, sizeof(signature), "%s %s(", ScriptDataTypeToName(pFuncDesc.m_ReturnType), name); + + for (int i = 0; i < pFuncDesc.m_Parameters.Count(); ++i) + { + if (i != 0) + V_strcat_safe(signature, ", "); + + V_strcat_safe(signature, ScriptDataTypeToName(pFuncDesc.m_Parameters[i])); + V_strcat_safe(signature, " ["); + V_strcat_safe(signature, pHook->m_pszParameterNames[i]); + V_strcat_safe(signature, "]"); + } + + V_strcat_safe(signature, ")"); + + // RegisterHookHelp(name, signature, description) + PushDocumentationRegisterFunction( "RegisterHookHelp" ); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, signature, -1); + sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1); + CallDocumentationRegisterFunction( 3 ); +} + +void RegisterMemberDocumentation(HSQUIRRELVM vm, const ScriptMemberDesc_t& pDesc, ScriptClassDesc_t* pClassDesc = nullptr) +{ + if ( !developer.GetInt() ) + return; + + SquirrelSafeCheck safeCheck(vm); + + if (pDesc.m_pszDescription && pDesc.m_pszDescription[0] == SCRIPT_HIDE[0]) + return; + + char name[256] = ""; + + if (pClassDesc) + { + V_strcat_safe(name, pClassDesc->m_pszScriptName); + V_strcat_safe(name, "."); + } + + if (pDesc.m_pszScriptName) + V_strcat_safe(name, pDesc.m_pszScriptName); + + char signature[256] = ""; + V_snprintf(signature, sizeof(signature), "%s %s", ScriptDataTypeToName(pDesc.m_ReturnType), name); + + // RegisterMemberHelp(name, signature, description) + PushDocumentationRegisterFunction( "RegisterMemberHelp" ); + sq_pushstring(vm, name, -1); + sq_pushstring(vm, signature, -1); + sq_pushstring(vm, pDesc.m_pszDescription ? pDesc.m_pszDescription : "", -1); + CallDocumentationRegisterFunction( 3 ); +} + +SQInteger GetDeveloperLevel(HSQUIRRELVM vm) +{ + sq_pushinteger( vm, developer.GetInt() ); + return 1; +} + + +bool SquirrelVM::Init() +{ + vm_ = sq_open(1024); //creates a VM with initial stack size 1024 + + if (vm_ == nullptr) + return false; + + sq_setforeignptr(vm_, this); + sq_resetobject(&lastError_); + + sq_setprintfunc(vm_, printfunc, errorfunc); + + + { + sq_pushroottable(vm_); + + sqstd_register_mathlib(vm_); + sqstd_register_stringlib(vm_); + vectorClass_ = SQVector::register_class(vm_); + + // We exclude these libraries as they create a security risk on the client even + // though I'm sure if someone tried hard enough they could achieve all sorts of + // things with the other APIs, this just makes it a little bit harder for a map + // created by someone in the community causing a bunch of security vulnerablilties. + // + // Pretty sure DoIncludeScript() is already a vulnerability vector here, however + // that also depends on compile errors not showing up and relies on IFilesystem with + // a path prefix. + // + //sqstd_register_bloblib(vm_); + //sqstd_register_iolib(vm_); + //sqstd_register_systemlib(vm_); + + // There is no vulnerability in getting time. + sqstd_register_timelib(vm_); + + + sqstd_seterrorhandlers(vm_); + + { + // Unfortunately we can not get the pattern from a regexp instance + // so we need to wrap it with our own to get it. + if (Run(R"script( + class regexp extends regexp + { + constructor(pattern) + { + base.constructor(pattern); + this.pattern_ = pattern; + } + pattern_ = ""; + } + )script") == SCRIPT_ERROR) + { + this->Shutdown(); + return false; + } + + sq_resetobject(®expClass_); + sq_pushstring(vm_, "regexp", -1); + sq_rawget(vm_, -2); + sq_getstackobj(vm_, -1, ®expClass_); + sq_addref(vm_, ®expClass_); + sq_pop(vm_, 1); + } + + sq_pushstring( vm_, "developer", -1 ); + sq_newclosure( vm_, &GetDeveloperLevel, 0 ); + //sq_setnativeclosurename( vm_, -1, "developer" ); + sq_newslot( vm_, -3, SQFalse ); + + sq_pop(vm_, 1); + } + + if (Run(g_Script_vscript_squirrel) != SCRIPT_DONE) + { + this->Shutdown(); + return false; + } + + return true; +} + +void SquirrelVM::Shutdown() +{ + if (vm_) + { + sq_release(vm_, &vectorClass_); + sq_release(vm_, ®expClass_); + + sq_close(vm_); + vm_ = nullptr; + } +} + +bool SquirrelVM::ConnectDebugger() +{ + // TODO: Debugger support + return false; +} + +void SquirrelVM::DisconnectDebugger() +{ + // TODO: Debugger support +} + +ScriptLanguage_t SquirrelVM::GetLanguage() +{ + return SL_SQUIRREL; +} + +const char* SquirrelVM::GetLanguageName() +{ + return "squirrel"; +} + +void SquirrelVM::AddSearchPath(const char* pszSearchPath) +{ + // TODO: Search path support +} + +bool SquirrelVM::Frame(float simTime) +{ + // TODO: Frame support + return false; +} + +ScriptStatus_t SquirrelVM::Run(const char* pszScript, bool bWait) +{ + SquirrelSafeCheck safeCheck(vm_); + if (SQ_FAILED(sq_compilebuffer(vm_, pszScript, strlen(pszScript), "", SQTrue))) + { + return SCRIPT_ERROR; + } + + sq_pushroottable(vm_); + if (SQ_FAILED(sq_call(vm_, 1, SQFalse, SQTrue))) + { + sq_pop(vm_, 1); + return SCRIPT_ERROR; + } + + sq_pop(vm_, 1); + return SCRIPT_DONE; +} + +HSCRIPT SquirrelVM::CompileScript(const char* pszScript, const char* pszId) +{ + SquirrelSafeCheck safeCheck(vm_); + + Assert(vm_); + if (pszId == nullptr) pszId = ""; + if (SQ_FAILED(sq_compilebuffer(vm_, pszScript, strlen(pszScript), pszId, SQTrue))) + { + return nullptr; + } + HSQOBJECT* obj = new HSQOBJECT; + sq_resetobject(obj); + sq_getstackobj(vm_, -1, obj); + sq_addref(vm_, obj); + sq_pop(vm_, 1); + + return (HSCRIPT)obj; +} + +void SquirrelVM::ReleaseScript(HSCRIPT hScript) +{ + SquirrelSafeCheck safeCheck(vm_); + if (!hScript) return; + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_release(vm_, obj); + delete obj; +} + +ScriptStatus_t SquirrelVM::Run(HSCRIPT hScript, HSCRIPT hScope, bool bWait) +{ + SquirrelSafeCheck safeCheck(vm_); + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_pushobject(vm_, *obj); + + if (hScope) + { + Assert(hScope != INVALID_HSCRIPT); + HSQOBJECT* scope = (HSQOBJECT*)hScope; + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + auto result = sq_call(vm_, 1, false, true); + sq_pop(vm_, 1); + if (SQ_FAILED(result)) + { + return SCRIPT_ERROR; + } + return SCRIPT_DONE; +} + +ScriptStatus_t SquirrelVM::Run(HSCRIPT hScript, bool bWait) +{ + SquirrelSafeCheck safeCheck(vm_); + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_pushobject(vm_, *obj); + sq_pushroottable(vm_); + auto result = sq_call(vm_, 1, false, true); + sq_pop(vm_, 1); + if (SQ_FAILED(result)) + { + return SCRIPT_ERROR; + } + return SCRIPT_DONE; +} + +HSCRIPT SquirrelVM::CreateScope(const char* pszScope, HSCRIPT hParent) +{ + SquirrelSafeCheck safeCheck(vm_); + + sq_newtable(vm_); + + if (hParent) + { + HSQOBJECT* parent = (HSQOBJECT*)hParent; + Assert(hParent != INVALID_HSCRIPT); + sq_pushobject(vm_, *parent); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszScope, -1); + sq_push(vm_, -3); + sq_rawset(vm_, -3); + + sq_pushstring(vm_, "__vname", -1); + sq_pushstring(vm_, pszScope, -1); + sq_rawset(vm_, -4); + + if (SQ_FAILED(sq_setdelegate(vm_, -2))) + { + sq_pop(vm_, 2); + return nullptr; + } + + HSQOBJECT* obj = new HSQOBJECT; + sq_resetobject(obj); + sq_getstackobj(vm_, -1, obj); + sq_addref(vm_, obj); + sq_pop(vm_, 1); + + return (HSCRIPT)obj; +} + +void SquirrelVM::ReleaseScope(HSCRIPT hScript) +{ + SquirrelSafeCheck safeCheck(vm_); + if (!hScript) return; + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_pushobject(vm_, *obj); + + sq_getdelegate(vm_, -1); + + sq_pushstring(vm_, "__vname", -1); + sq_rawdeleteslot(vm_, -2, SQFalse); + + sq_pop(vm_, 2); + + sq_release(vm_, obj); + delete obj; +} + +HSCRIPT SquirrelVM::LookupFunction(const char* pszFunction, HSCRIPT hScope) +{ + SquirrelSafeCheck safeCheck(vm_); + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + sq_pushstring(vm_, _SC(pszFunction), -1); + + HSQOBJECT obj; + sq_resetobject(&obj); + + if (sq_get(vm_, -2) == SQ_OK) + { + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + sq_pop(vm_, 1); + } + sq_pop(vm_, 1); + + if (!sq_isclosure(obj)) + { + sq_release(vm_, &obj); + return nullptr; + } + + HSQOBJECT* pObj = new HSQOBJECT; + *pObj = obj; + return (HSCRIPT)pObj; +} + +void SquirrelVM::ReleaseFunction(HSCRIPT hScript) +{ + SquirrelSafeCheck safeCheck(vm_); + if (!hScript) return; + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_release(vm_, obj); + delete obj; +} + +ScriptStatus_t SquirrelVM::ExecuteFunction(HSCRIPT hFunction, ScriptVariant_t* pArgs, int nArgs, ScriptVariant_t* pReturn, HSCRIPT hScope, bool bWait) +{ + SquirrelSafeCheck safeCheck(vm_); + if (!hFunction) + return SCRIPT_ERROR; + + if (hFunction == INVALID_HSCRIPT) + return SCRIPT_ERROR; + + HSQOBJECT* pFunc = (HSQOBJECT*)hFunction; + sq_pushobject(vm_, *pFunc); + + if (hScope) + { + Assert(hScope != INVALID_HSCRIPT); + HSQOBJECT* scope = (HSQOBJECT*)hScope; + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + for (int i = 0; i < nArgs; ++i) + { + PushVariant(vm_, pArgs[i]); + } + + bool hasReturn = pReturn != nullptr; + + if (SQ_FAILED(sq_call(vm_, nArgs + 1, hasReturn, SQTrue))) + { + sq_pop(vm_, 1); + return SCRIPT_ERROR; + } + + if (hasReturn) + { + if (!getVariant(vm_, -1, *pReturn)) + { + sq_pop(vm_, 1); + return SCRIPT_ERROR; + } + + sq_pop(vm_, 1); + } + + sq_pop(vm_, 1); + return SCRIPT_DONE; +} + +HScriptRaw SquirrelVM::HScriptToRaw( HSCRIPT val ) +{ + Assert( val ); + Assert( val != INVALID_HSCRIPT ); + + HSQOBJECT *obj = (HSQOBJECT*)val; +#if 0 + if ( sq_isweakref(*obj) ) + return obj->_unVal.pWeakRef->_obj._unVal.raw; +#endif + return obj->_unVal.raw; +} + +ScriptStatus_t SquirrelVM::ExecuteHookFunction(const char *pszEventName, ScriptVariant_t* pArgs, int nArgs, ScriptVariant_t* pReturn, HSCRIPT hScope, bool bWait) +{ + SquirrelSafeCheck safeCheck(vm_); + + HSQOBJECT* pFunc = (HSQOBJECT*)GetScriptHookManager().GetHookFunction(); + sq_pushobject(vm_, *pFunc); + + // The call environment of the Hooks::Call function does not matter + // as the function does not access any member variables. + sq_pushroottable(vm_); + + sq_pushstring(vm_, pszEventName, -1); + + if (hScope) + sq_pushobject(vm_, *((HSQOBJECT*)hScope)); + else + sq_pushnull(vm_); // global hook + + for (int i = 0; i < nArgs; ++i) + { + PushVariant(vm_, pArgs[i]); + } + + bool hasReturn = pReturn != nullptr; + + if (SQ_FAILED(sq_call(vm_, nArgs + 3, hasReturn, SQTrue))) + { + sq_pop(vm_, 1); + return SCRIPT_ERROR; + } + + if (hasReturn) + { + if (!getVariant(vm_, -1, *pReturn)) + { + sq_pop(vm_, 1); + return SCRIPT_ERROR; + } + + sq_pop(vm_, 1); + } + + sq_pop(vm_, 1); + return SCRIPT_DONE; +} + +void SquirrelVM::RegisterFunction(ScriptFunctionBinding_t* pScriptFunction) +{ + SquirrelSafeCheck safeCheck(vm_); + Assert(pScriptFunction); + + if (!pScriptFunction) + return; + + char typemask[64]; + if (!CreateParamCheck(*pScriptFunction, typemask)) + { + return; + } + + sq_pushroottable(vm_); + + sq_pushstring(vm_, pScriptFunction->m_desc.m_pszScriptName, -1); + + sq_pushuserpointer(vm_, pScriptFunction); + sq_newclosure(vm_, function_stub, 1); + + sq_setnativeclosurename(vm_, -1, pScriptFunction->m_desc.m_pszScriptName); + + sq_setparamscheck(vm_, pScriptFunction->m_desc.m_Parameters.Count() + 1, typemask); + bool isStatic = false; + sq_newslot(vm_, -3, isStatic); + + sq_pop(vm_, 1); + + RegisterDocumentation(vm_, pScriptFunction->m_desc); +} + +bool SquirrelVM::RegisterClass(ScriptClassDesc_t* pClassDesc) +{ + SquirrelSafeCheck safeCheck(vm_); + + sq_pushroottable(vm_); + sq_pushstring(vm_, pClassDesc->m_pszScriptName, -1); + + // Check if class name is already taken + if (sq_get(vm_, -2) == SQ_OK) + { + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, -1, &obj); + if (!sq_isnull(obj)) + { + sq_pop(vm_, 2); + return false; + } + + sq_pop(vm_, 1); + } + + // Register base in case it doesn't exist + if (pClassDesc->m_pBaseDesc) + { + RegisterClass(pClassDesc->m_pBaseDesc); + + // Check if the base class can be + sq_pushstring(vm_, pClassDesc->m_pBaseDesc->m_pszScriptName, -1); + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return false; + } + } + + if (SQ_FAILED(sq_newclass(vm_, pClassDesc->m_pBaseDesc ? SQTrue : SQFalse))) + { + sq_pop(vm_, 2 + (pClassDesc->m_pBaseDesc ? 1 : 0)); + return false; + } + + sq_settypetag(vm_, -1, pClassDesc); + + sq_setclassudsize(vm_, -1, sizeof(ClassInstanceData)); + + sq_pushstring(vm_, "constructor", -1); + sq_newclosure(vm_, constructor_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_tostring", -1); + sq_newclosure(vm_, tostring_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_get", -1); + sq_newclosure(vm_, get_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_set", -1); + sq_newclosure(vm_, set_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_add", -1); + sq_newclosure(vm_, add_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_sub", -1); + sq_newclosure(vm_, sub_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_mul", -1); + sq_newclosure(vm_, mul_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "_div", -1); + sq_newclosure(vm_, div_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "IsValid", -1); + sq_newclosure(vm_, IsValid_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "weakref", -1); + sq_newclosure(vm_, weakref_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + sq_pushstring(vm_, "getclass", -1); + sq_newclosure(vm_, getclass_stub, 0); + sq_newslot(vm_, -3, SQFalse); + + + for (int i = 0; i < pClassDesc->m_FunctionBindings.Count(); ++i) + { + auto& scriptFunction = pClassDesc->m_FunctionBindings[i]; + + char typemask[64]; + if (!CreateParamCheck(scriptFunction, typemask)) + { + Warning("Unable to create param check for %s.%s\n", + pClassDesc->m_pszClassname, scriptFunction.m_desc.m_pszFunction); + break; + } + + sq_pushstring(vm_, scriptFunction.m_desc.m_pszScriptName, -1); + + sq_pushuserpointer(vm_, &scriptFunction); + sq_newclosure(vm_, function_stub, 1); + + sq_setnativeclosurename(vm_, -1, scriptFunction.m_desc.m_pszScriptName); + + sq_setparamscheck(vm_, scriptFunction.m_desc.m_Parameters.Count() + 1, typemask); + bool isStatic = false; + sq_newslot(vm_, -3, isStatic); + + RegisterDocumentation(vm_, scriptFunction.m_desc, pClassDesc); + } + + for (int i = 0; i < pClassDesc->m_Hooks.Count(); ++i) + { + auto& scriptHook = pClassDesc->m_Hooks[i]; + + RegisterHookDocumentation(vm_, scriptHook, scriptHook->m_desc, pClassDesc); + } + + for (int i = 0; i < pClassDesc->m_Members.Count(); ++i) + { + auto& member = pClassDesc->m_Members[i]; + + RegisterMemberDocumentation(vm_, member, pClassDesc); + } + + sq_pushstring(vm_, pClassDesc->m_pszScriptName, -1); + sq_push(vm_, -2); + + if (SQ_FAILED(sq_newslot(vm_, -4, SQFalse))) + { + sq_pop(vm_, 4); + return false; + } + + sq_pop(vm_, 2); + + RegisterClassDocumentation(vm_, pClassDesc); + + return true; +} + +void SquirrelVM::RegisterConstant(ScriptConstantBinding_t* pScriptConstant) +{ + SquirrelSafeCheck safeCheck(vm_); + Assert(pScriptConstant); + + if (!pScriptConstant) + return; + + sq_pushconsttable(vm_); + sq_pushstring(vm_, pScriptConstant->m_pszScriptName, -1); + + PushVariant(vm_, pScriptConstant->m_data); + + sq_newslot(vm_, -3, SQFalse); + + sq_pop(vm_, 1); + + char szValue[64]; + GetVariantScriptString( pScriptConstant->m_data, szValue, sizeof(szValue) ); + RegisterConstantDocumentation(vm_, pScriptConstant, szValue); +} + +void SquirrelVM::RegisterEnum(ScriptEnumDesc_t* pEnumDesc) +{ + SquirrelSafeCheck safeCheck(vm_); + Assert(pEnumDesc); + + if (!pEnumDesc) + return; + + sq_newtableex(vm_, pEnumDesc->m_ConstantBindings.Count()); + + sq_pushconsttable(vm_); + + sq_pushstring(vm_, pEnumDesc->m_pszScriptName, -1); + sq_push(vm_, -3); + sq_rawset(vm_, -3); + + for (int i = 0; i < pEnumDesc->m_ConstantBindings.Count(); ++i) + { + auto& scriptConstant = pEnumDesc->m_ConstantBindings[i]; + + sq_pushstring(vm_, scriptConstant.m_pszScriptName, -1); + PushVariant(vm_, scriptConstant.m_data); + sq_rawset(vm_, -4); + + char szValue[64]; + GetVariantScriptString( scriptConstant.m_data, szValue, sizeof(szValue) ); + RegisterConstantDocumentation(vm_, &scriptConstant, szValue, pEnumDesc); + } + + sq_pop(vm_, 2); + + RegisterEnumDocumentation(vm_, pEnumDesc); +} + +void SquirrelVM::RegisterHook(ScriptHook_t* pHookDesc) +{ + SquirrelSafeCheck safeCheck(vm_); + Assert(pHookDesc); + + if (!pHookDesc) + return; + + RegisterHookDocumentation(vm_, pHookDesc, pHookDesc->m_desc, nullptr); +} + +HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct) +{ + SquirrelSafeCheck safeCheck(vm_); + + this->RegisterClass(pDesc); + + sq_pushroottable(vm_); + sq_pushstring(vm_, pDesc->m_pszScriptName, -1); + + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return nullptr; + } + + if (SQ_FAILED(sq_createinstance(vm_, -1))) + { + sq_pop(vm_, 2); + return nullptr; + } + + { + SQUserPointer p; + sq_getinstanceup(vm_, -1, &p, 0); + new(p) ClassInstanceData(pInstance, pDesc, nullptr, bAllowDestruct); + } + + sq_setreleasehook(vm_, -1, bAllowDestruct ? &destructor_stub : &destructor_stub_instance); + + HSQOBJECT* obj = new HSQOBJECT; + sq_resetobject(obj); + sq_getstackobj(vm_, -1, obj); + sq_addref(vm_, obj); + sq_pop(vm_, 3); + + return (HSCRIPT)obj; +} + +void SquirrelVM::SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (!hInstance) return; + HSQOBJECT* obj = (HSQOBJECT*)hInstance; + sq_pushobject(vm_, *obj); + + SQUserPointer self; + sq_getinstanceup(vm_, -1, &self, nullptr); + + auto classInstanceData = (ClassInstanceData*)self; + + classInstanceData->instanceId = pszId; + + sq_poptop(vm_); +} + +void SquirrelVM::RemoveInstance(HSCRIPT hInstance) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (!hInstance) return; + HSQOBJECT* obj = (HSQOBJECT*)hInstance; + sq_pushobject(vm_, *obj); + + SQUserPointer self; + sq_getinstanceup(vm_, -1, &self, nullptr); + + ((ClassInstanceData*)self)->~ClassInstanceData(); + + sq_setinstanceup(vm_, -1, nullptr); + sq_setreleasehook(vm_, -1, nullptr); + sq_pop(vm_, 1); + + sq_release(vm_, obj); + delete obj; +} + +void* SquirrelVM::GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpectedType) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (!hInstance) return nullptr; + HSQOBJECT* obj = (HSQOBJECT*)hInstance; + + if (pExpectedType) + { + sq_pushroottable(vm_); + sq_pushstring(vm_, pExpectedType->m_pszScriptName, -1); + + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return nullptr; + } + + sq_pushobject(vm_, *obj); + + if (sq_instanceof(vm_) != SQTrue) + { + sq_pop(vm_, 3); + return nullptr; + } + + sq_pop(vm_, 3); + } + + sq_pushobject(vm_, *obj); + SQUserPointer self; + sq_getinstanceup(vm_, -1, &self, nullptr); + sq_pop(vm_, 1); + + auto classInstanceData = (ClassInstanceData*)self; + + if (!classInstanceData) + { + return nullptr; + } + + + return classInstanceData->instance; +} + +bool SquirrelVM::GenerateUniqueKey(const char* pszRoot, char* pBuf, int nBufSize) +{ + static int keyIdx = 0; + // This gets used for script scope, still confused why it needs to be inside IScriptVM + // is it just to be a compatible name for CreateScope? + V_snprintf(pBuf, nBufSize, "%08X_%s", ++keyIdx, pszRoot); + return true; +} + +bool SquirrelVM::ValueExists(HSCRIPT hScope, const char* pszKey) +{ + SquirrelSafeCheck safeCheck(vm_); + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszKey, -1); + + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return false; + } + + sq_pop(vm_, 2); + return true; +} + +bool SquirrelVM::SetValue(HSCRIPT hScope, const char* pszKey, const char* pszValue) +{ + SquirrelSafeCheck safeCheck(vm_); + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszKey, -1); + sq_pushstring(vm_, pszValue, -1); + + sq_newslot(vm_, -3, SQFalse); + + sq_pop(vm_, 1); + return true; +} + +bool SquirrelVM::SetValue(HSCRIPT hScope, const char* pszKey, const ScriptVariant_t& value) +{ + SquirrelSafeCheck safeCheck(vm_); + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszKey, -1); + PushVariant(vm_, value); + + sq_newslot(vm_, -3, SQFalse); + + sq_pop(vm_, 1); + return true; +} + +bool SquirrelVM::SetValue( HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val ) +{ + SquirrelSafeCheck safeCheck(vm_); + HSQOBJECT obj = *(HSQOBJECT*)hScope; + if (hScope) + { + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, obj); + } + else + { + sq_pushroottable(vm_); + } + + if ( sq_isarray(obj) ) + { + Assert( key.m_type == FIELD_INTEGER ); + + sq_pushinteger(vm_, key.m_int); + PushVariant(vm_, val); + + sq_set(vm_, -3); + } + else + { + PushVariant(vm_, key); + PushVariant(vm_, val); + + sq_newslot(vm_, -3, SQFalse); + } + + sq_pop(vm_, 1); + return true; +} + +void SquirrelVM::CreateTable(ScriptVariant_t& Table) +{ + SquirrelSafeCheck safeCheck(vm_); + + sq_newtable(vm_); + + HSQOBJECT* obj = new HSQOBJECT; + sq_resetobject(obj); + sq_getstackobj(vm_, -1, obj); + sq_addref(vm_, obj); + sq_pop(vm_, 1); + + Table = (HSCRIPT)obj; +} + +// +// input table/array/class/instance/string +// +int SquirrelVM::GetNumTableEntries(HSCRIPT hScope) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (!hScope) + { + // sq_getsize returns -1 on invalid input + return -1; + } + + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + + int count = sq_getsize(vm_, -1); + + sq_pop(vm_, 1); + + return count; +} + +int SquirrelVM::GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey, ScriptVariant_t* pValue) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (hScope) + { + Assert(hScope != INVALID_HSCRIPT); + HSQOBJECT* scope = (HSQOBJECT*)hScope; + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + if (nIterator == -1) + { + sq_pushnull(vm_); + } + else + { + sq_pushinteger(vm_, nIterator); + } + + SQInteger nextiter = -1; + + if (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + if (pKey) getVariant(vm_, -2, *pKey); + if (pValue) getVariant(vm_, -1, *pValue); + + sq_getinteger(vm_, -3, &nextiter); + sq_pop(vm_, 2); + } + sq_pop(vm_, 2); + + return nextiter; +} + +bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue) +{ +#ifdef _DEBUG + AssertMsg( pszKey, "FATAL: cannot get NULL" ); + + // Don't crash on debug + if ( !pszKey ) + return GetValue( hScope, ScriptVariant_t(0), pValue ); +#endif + + SquirrelSafeCheck safeCheck(vm_); + + Assert(pValue); + if (!pValue) + { + return false; + } + + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszKey, -1); + + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return false; + } + + if (!getVariant(vm_, -1, *pValue)) + { + sq_pop(vm_, 2); + return false; + } + + sq_pop(vm_, 2); + + return true; +} + +bool SquirrelVM::GetValue( HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue ) +{ + SquirrelSafeCheck safeCheck(vm_); + + Assert(pValue); + if (!pValue) + { + return false; + } + + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + PushVariant(vm_, key); + + if (sq_get(vm_, -2) != SQ_OK) + { + sq_pop(vm_, 1); + return false; + } + + if (!getVariant(vm_, -1, *pValue)) + { + sq_pop(vm_, 2); + return false; + } + + sq_pop(vm_, 2); + + return true; +} + + +void SquirrelVM::ReleaseValue(ScriptVariant_t& value) +{ + SquirrelSafeCheck safeCheck(vm_); + if (value.m_type == FIELD_HSCRIPT) + { + HSCRIPT hScript = value; + HSQOBJECT* obj = (HSQOBJECT*)hScript; + sq_release(vm_, obj); + delete obj; + } + else + { + value.Free(); + } + + // Let's prevent this being called again and giving some UB + value.m_type = FIELD_VOID; +} + +bool SquirrelVM::ClearValue(HSCRIPT hScope, const char* pszKey) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + sq_pushstring(vm_, pszKey, -1); + if (SQ_FAILED(sq_deleteslot(vm_, -2, SQFalse))) + { + sq_pop(vm_, 1); + return false; + } + + sq_pop(vm_, 1); + return true; +} + +bool SquirrelVM::ClearValue(HSCRIPT hScope, ScriptVariant_t pKey) +{ + SquirrelSafeCheck safeCheck(vm_); + + if (hScope) + { + HSQOBJECT* scope = (HSQOBJECT*)hScope; + Assert(hScope != INVALID_HSCRIPT); + sq_pushobject(vm_, *scope); + } + else + { + sq_pushroottable(vm_); + } + + PushVariant(vm_, pKey); + if (SQ_FAILED(sq_deleteslot(vm_, -2, SQFalse))) + { + sq_pop(vm_, 1); + return false; + } + + sq_pop(vm_, 1); + return true; +} + + +void SquirrelVM::CreateArray(ScriptVariant_t &arr, int size) +{ + SquirrelSafeCheck safeCheck(vm_); + + HSQOBJECT *obj = new HSQOBJECT; + sq_resetobject(obj); + + sq_newarray(vm_,size); + sq_getstackobj(vm_, -1, obj); + sq_addref(vm_, obj); + sq_pop(vm_, 1); + + arr = (HSCRIPT)obj; +} + +bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) +{ + SquirrelSafeCheck safeCheck(vm_); + + HSQOBJECT *arr = (HSQOBJECT*)hArray; + + sq_pushobject(vm_, *arr); + PushVariant(vm_, val); + bool ret = sq_arrayappend(vm_, -2) == SQ_OK; + sq_pop(vm_, 1); + + return ret; +} + +enum ClassType +{ + VectorClassType = 0, + NativeClassType = 1, + ScriptClassType = 2 +}; + +SQInteger closure_write(SQUserPointer file, SQUserPointer p, SQInteger size) +{ + ((CUtlBuffer*)file)->Put(p, size); + return size; +} + +void SquirrelVM::WriteObject(CUtlBuffer* pBuffer, WriteStateMap& writeState, SQInteger idx) +{ + SquirrelSafeCheck safeCheck(vm_); + + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, idx, &obj); + + switch (obj._type) + { + case OT_NULL: + { + pBuffer->PutInt(OT_NULL); + break; + } + case OT_INTEGER: + { + pBuffer->PutInt(OT_INTEGER); + pBuffer->PutInt64(sq_objtointeger(&obj)); + break; + } + case OT_FLOAT: + { + pBuffer->PutInt(OT_FLOAT); + pBuffer->PutFloat(sq_objtofloat(&obj)); + break; + } + case OT_BOOL: + { + pBuffer->PutInt(OT_BOOL); + pBuffer->PutChar(sq_objtobool(&obj)); + break; + } + case OT_STRING: + { + pBuffer->PutInt(OT_STRING); + const char* val = nullptr; + SQInteger size = 0; + sq_getstringandsize(vm_, idx, &val, &size); + pBuffer->PutInt(size); + pBuffer->Put(val, size); + break; + } + case OT_TABLE: + { + pBuffer->PutInt(OT_TABLE); + if (writeState.CheckCache(pBuffer, obj._unVal.pTable)) + { + break; + } + sq_getdelegate(vm_, idx); + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); + int count = sq_getsize(vm_, idx); + sq_push(vm_, idx); + sq_pushnull(vm_); + pBuffer->PutInt(count); + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + WriteObject(pBuffer, writeState, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + --count; + } + sq_pop(vm_, 2); + Assert(count == 0); + break; + } + case OT_ARRAY: + { + pBuffer->PutInt(OT_ARRAY); + if (writeState.CheckCache(pBuffer, obj._unVal.pArray)) + { + break; + } + int count = sq_getsize(vm_, idx); + pBuffer->PutInt(count); + sq_push(vm_, idx); + sq_pushnull(vm_); + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + --count; + } + sq_pop(vm_, 2); + Assert(count == 0); + break; + } + case OT_CLOSURE: + { + pBuffer->PutInt(OT_CLOSURE); + if (writeState.CheckCache(pBuffer, obj._unVal.pClosure)) + { + break; + } + + SQInteger nparams = 0, nfreevars = 0; + sq_getclosureinfo(vm_, idx, &nparams, &nfreevars); + if (nfreevars == 0 && _closure(obj)->_function->_defaultparams == 0) + { + pBuffer->PutChar(0); + + sq_push(vm_, idx); + if (SQ_FAILED(sq_writeclosure(vm_, closure_write, pBuffer))) + { + Error("Failed to write closure"); + } + sq_pop(vm_, 1); + } + else + { + // Unfortunately we can't use sq_writeclosure because it doesn't work well with + // outer variables + + pBuffer->PutChar(1); + + if (!_closure(obj)->Save(vm_, pBuffer, closure_write)) + { + Error("Failed to write closure\n"); + } + + int noutervalues = _closure(obj)->_function->_noutervalues; + for (int i = 0; i < noutervalues; ++i) + { + sq_pushobject(vm_, _closure(obj)->_outervalues[i]); + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); + } + + int ndefaultparams = _closure(obj)->_function->_ndefaultparams; + for (int i = 0; i < ndefaultparams; ++i) + { + sq_pushobject(vm_, _closure(obj)->_defaultparams[i]); + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); + } + } + + if (_closure(obj)->_env) + { + sq_pushobject(vm_, _closure(obj)->_env->_obj); + } + else + { + sq_pushnull(vm_); + } + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); + + break; + } + case OT_NATIVECLOSURE: + { + pBuffer->PutInt(OT_NATIVECLOSURE); + sq_getclosurename(vm_, idx); + + const char* name = nullptr; + sq_getstring(vm_, -1, &name); + pBuffer->PutString(name); + + sq_pop(vm_, 1); + break; + } + case OT_CLASS: + { + pBuffer->PutInt(OT_CLASS); + if (writeState.CheckCache(pBuffer, obj._unVal.pClass)) + { + break; + } + SQUserPointer typetag = nullptr; + sq_gettypetag(vm_, idx, &typetag); + if (typetag == TYPETAG_VECTOR) + { + pBuffer->PutInt(VectorClassType); + } + else if (typetag != nullptr) + { + // Seems so dangerous to treat typetag as ScriptClassDesc_t* + // however we don't really have an option without some sort of tagged + // pointer. + pBuffer->PutInt(NativeClassType); + pBuffer->PutString(((ScriptClassDesc_t*)typetag)->m_pszScriptName); + } + else + { + // HACK: We can't easily identify when the type is a builtin to exclude + // so we just check against the only class we need to deal with at the moment + // which is "regexp" + const char* builtinName = nullptr; + if (_class(obj) == _class(regexpClass_)) + { + builtinName = "regexp"; + } + + if (builtinName) + { + pBuffer->PutInt(NativeClassType); + pBuffer->PutString(builtinName); + break; + } + + pBuffer->PutInt(ScriptClassType); + + sq_getbase(vm_, idx); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 1); + + sq_push(vm_, idx); + sq_pushnull(vm_); + sq_getattributes(vm_, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 1); + + sq_pushnull(vm_); + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + pBuffer->PutChar(1); + // TODO: Member Attributes + WriteObject(pBuffer, writeState, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + } + sq_pop(vm_, 2); + + { + // HACK: Meta-methods are not included in an iterator of OT_CLASS + SQObjectPtrVec& metamethods = *(_ss(vm_)->_metamethods); + for (int i = 0; i < MT_LAST; ++i) + { + if (sq_type(_class(obj)->_metamethods[i]) != OT_NULL) + { + pBuffer->PutChar(1); + sq_pushobject(vm_, metamethods[i]); + sq_pushobject(vm_, _class(obj)->_metamethods[i]); + WriteObject(pBuffer, writeState, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + } + } + } + + pBuffer->PutChar(0); + } + break; + } + case OT_INSTANCE: + { + pBuffer->PutInt(OT_INSTANCE); + if (writeState.CheckCache(pBuffer, obj._unVal.pInstance)) + { + break; + } + sq_getclass(vm_, idx); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 1); + + if (_instance(obj)->_class == _class(regexpClass_)) + { + sq_push(vm_, idx); + sq_pushstring(vm_, "pattern_", -1); + sq_rawget(vm_, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + break; + } + + { + // HACK: No way to get the default values part from accessing the class directly + SQUnsignedInteger nvalues = _instance(obj)->_class->_defaultvalues.size(); + for (SQUnsignedInteger n = 0; n < nvalues; n++) { + sq_pushobject(vm_, _instance(obj)->_values[n]); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 1); + } + } + + SQUserPointer typetag; + sq_gettypetag(vm_, idx, &typetag); + + if (typetag == TYPETAG_VECTOR) + { + Vector* v = nullptr; + sq_getinstanceup(vm_, idx, (SQUserPointer*)&v, TYPETAG_VECTOR); + Assert(v); + pBuffer->PutFloat(v->x); + pBuffer->PutFloat(v->y); + pBuffer->PutFloat(v->z); + } + else if (typetag) + { + ClassInstanceData* pClassInstanceData; + sq_getinstanceup(vm_, idx, (SQUserPointer*)&pClassInstanceData, typetag); + + if (pClassInstanceData) + { + if (pClassInstanceData->desc->m_pszDescription[0] == SCRIPT_SINGLETON[0]) + { + // Do nothing, singleton should be created from just the class + } + else if (!pClassInstanceData->instanceId.IsEmpty()) + { + pBuffer->PutString(pClassInstanceData->instanceId); + + pBuffer->PutChar(pClassInstanceData->allowDestruct ? 1 : 0); + } + else + { + DevWarning("SquirrelVM::WriteObject: Unable to find instanceID for object of type %s, unable to serialize\n", + pClassInstanceData->desc->m_pszClassname); + pBuffer->PutString(""); + } + } + else + { + pBuffer->PutString(""); + } + } + + break; + } + case OT_WEAKREF: + { + pBuffer->PutInt(OT_WEAKREF); + sq_getweakrefval(vm_, idx); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 1); + break; + } + case OT_FUNCPROTO: //internal usage only + { + pBuffer->PutInt(OT_FUNCPROTO); + + if (writeState.CheckCache(pBuffer, obj._unVal.pFunctionProto)) + { + break; + } + + _funcproto(obj)->Save(vm_, pBuffer, closure_write); + } + case OT_OUTER: //internal usage only + { + pBuffer->PutInt(OT_OUTER); + + if (writeState.CheckCache(pBuffer, obj._unVal.pOuter)) + { + break; + } + + sq_pushobject(vm_, *_outer(obj)->_valptr); + WriteObject(pBuffer, writeState, -1); + sq_poptop(vm_); + + break; + } + // case OT_USERDATA: + // case OT_GENERATOR: + // case OT_USERPOINTER: + // case OT_THREAD: + // + default: + Warning("SquirrelVM::WriteObject: Unexpected type %d", sq_gettype(vm_, idx)); + // Save a null instead + pBuffer->PutInt(OT_NULL); + } +} + +void SquirrelVM::WriteState(CUtlBuffer* pBuffer) +{ + SquirrelSafeCheck safeCheck(vm_); + + WriteStateMap writeState; + + sq_pushroottable(vm_); + + // Not really a check cache, but adds the root + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, -1, &obj); + writeState.CheckCache(pBuffer, _table(obj)); + + int count = sq_getsize(vm_, 1); + sq_pushnull(vm_); + pBuffer->PutInt(count); + + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + WriteObject(pBuffer, writeState, -2); + WriteObject(pBuffer, writeState, -1); + sq_pop(vm_, 2); + --count; + } + sq_pop(vm_, 2); + Assert(count == 0); +} + +SQInteger closure_read(SQUserPointer file, SQUserPointer buf, SQInteger size) +{ + CUtlBuffer* pBuffer = (CUtlBuffer*)file; + pBuffer->Get(buf, size); + return pBuffer->IsValid() ? size : -1; +} + +void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState) +{ + SquirrelSafeCheck safeCheck(vm_, 1); + + int thisType = pBuffer->GetInt(); + + switch (thisType) + { + case OT_NULL: + { + sq_pushnull(vm_); + break; + } + case OT_INTEGER: + { + sq_pushinteger(vm_, pBuffer->GetInt64()); + break; + } + case OT_FLOAT: + { + sq_pushfloat(vm_, pBuffer->GetFloat()); + break; + } + case OT_BOOL: + { + sq_pushbool(vm_, pBuffer->GetChar()); + break; + } + case OT_STRING: + { + int size = pBuffer->GetInt(); + char* buffer = new char[size + 1]; + pBuffer->Get(buffer, size); + buffer[size] = 0; + sq_pushstring(vm_, buffer, size); + delete[] buffer; + break; + } + case OT_TABLE: + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + ReadObject(pBuffer, readState); + + int count = pBuffer->GetInt(); + sq_newtableex(vm_, count); + readState.StoreTopInCache(marker); + + sq_push(vm_, -2); + sq_setdelegate(vm_, -2); + + sq_remove(vm_, -2); + + for (int i = 0; i < count; ++i) + { + ReadObject(pBuffer, readState); + ReadObject(pBuffer, readState); + sq_rawset(vm_, -3); + } + + break; + } + case OT_ARRAY: + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + int count = pBuffer->GetInt(); + sq_newarray(vm_, count); + readState.StoreTopInCache(marker); + + for (int i = 0; i < count; ++i) + { + sq_pushinteger(vm_, i); + ReadObject(pBuffer, readState); + sq_rawset(vm_, -3); + } + break; + } + case OT_CLOSURE: + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + if (pBuffer->GetChar() == 0) + { + if (SQ_FAILED(sq_readclosure(vm_, closure_read, pBuffer))) + { + Error("Failed to read closure\n"); + sq_pushnull(vm_); + break; + } + + readState.StoreTopInCache(marker); + } + else + { + SQObjectPtr ret; + if (!SQClosure::Load(vm_, pBuffer, closure_read, ret)) + { + Error("Failed to read closure\n"); + sq_pushnull(vm_); + break; + } + + vm_->Push(ret); + readState.StoreTopInCache(marker); + + int noutervalues = _closure(ret)->_function->_noutervalues; + for (int i = 0; i < noutervalues; ++i) + { + ReadObject(pBuffer, readState); + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, -1, &obj); + _closure(ret)->_outervalues[i] = obj; + sq_poptop(vm_); + } + + int ndefaultparams = _closure(ret)->_function->_ndefaultparams; + for (int i = 0; i < ndefaultparams; ++i) + { + ReadObject(pBuffer, readState); + HSQOBJECT obj; + sq_resetobject(&obj); + sq_getstackobj(vm_, -1, &obj); + _closure(ret)->_defaultparams[i] = obj; + sq_poptop(vm_); + } + } + + ReadObject(pBuffer, readState); + HSQOBJECT env; + sq_resetobject(&env); + sq_getstackobj(vm_, -1, &env); + if (!sq_isnull(env)) + { + HSQOBJECT obj; + sq_getstackobj(vm_, -2, &obj); + if (_closure(obj) == nullptr) + Warning("Closure is null\n"); + else + _closure(obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env)); + } + sq_poptop(vm_); + + break; + } + case OT_NATIVECLOSURE: + { + char closureName[128] = ""; + pBuffer->GetString(closureName, sizeof(closureName)); + + sq_pushroottable(vm_); + sq_pushstring(vm_, closureName, -1); + if (SQ_FAILED(sq_get(vm_, -2))) + { + Warning("SquirrelVM::ReadObject: Failed to find native closure\n"); + sq_pop(vm_, 1); + sq_pushnull(vm_); + } + sq_remove(vm_, -2); + + break; + } + case OT_CLASS: + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + ClassType classType = (ClassType)pBuffer->GetInt(); + + if (classType == VectorClassType) + { + sq_pushobject(vm_, vectorClass_); + readState.StoreTopInCache(marker); + } + else if (classType == NativeClassType) + { + char className[128] = ""; + pBuffer->GetString(className, sizeof(className)); + + sq_pushroottable(vm_); + sq_pushstring(vm_, className, -1); + if (SQ_FAILED(sq_get(vm_, -2))) + { + Warning("SquirrelVM::ReadObject: Failed to find native class: %s\n", className); + sq_pushnull(vm_); + } + sq_remove(vm_, -2); + readState.StoreTopInCache(marker); + } + else if (classType == ScriptClassType) + { + ReadObject(pBuffer, readState); + bool hasBase = sq_gettype(vm_, -1) != OT_NULL; + if (!hasBase) + { + sq_poptop(vm_); + } + + sq_newclass(vm_, hasBase); + readState.StoreTopInCache(marker); + + sq_pushnull(vm_); + ReadObject(pBuffer, readState); + sq_setattributes(vm_, -3); + sq_poptop(vm_); // Returns the old attributes + + while (pBuffer->GetChar()) + { + // TODO: Member Attributes + ReadObject(pBuffer, readState); + ReadObject(pBuffer, readState); + sq_newslot(vm_, -3, false); + } + } + else + { + Error("SquirrelVM::ReadObject: Unknown class type\n"); + sq_pushnull(vm_); + } + break; + } + case OT_INSTANCE: + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + ReadObject(pBuffer, readState); + + HSQOBJECT klass; + sq_resetobject(&klass); + sq_getstackobj(vm_, -1, &klass); + if (_class(klass) == _class(regexpClass_)) + { + sq_pushnull(vm_); + ReadObject(pBuffer, readState); + sq_call(vm_, 2, SQTrue, SQFalse); + + readState.StoreTopInCache(marker); + + sq_remove(vm_, -2); + + break; + } + + SQUserPointer typetag; + sq_gettypetag(vm_, -1, &typetag); + + if (typetag && typetag != TYPETAG_VECTOR && + ((ScriptClassDesc_t*)typetag)->m_pszDescription[0] == SCRIPT_SINGLETON[0]) + { + sq_poptop(vm_); + + Assert(sq_isclass(klass)); + + // singleton, lets find an equivlent in the root + bool foundSingleton = false; + sq_pushroottable(vm_); + sq_pushnull(vm_); + HSQOBJECT singleton; + sq_resetobject(&singleton); + while (SQ_SUCCEEDED(sq_next(vm_, -2))) + { + sq_getstackobj(vm_, -1, &singleton); + if (sq_isinstance(singleton) && _instance(singleton)->_class == _class(klass)) + { + foundSingleton = true; + + readState.StoreInCache(marker, singleton); + sq_addref(vm_, &singleton); + sq_pop(vm_, 2); + break; + } + sq_pop(vm_, 2); + } + sq_pop(vm_, 2); + + if (!foundSingleton) + { + Warning("SquirrelVM::ReadObject: Failed to find singleton for %s\n", + ((ScriptClassDesc_t*)typetag)->m_pszScriptName); + } + + sq_pushobject(vm_, singleton); + break; + } + + + HSQOBJECT obj; + sq_createinstance(vm_, -1); + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + readState.StoreInCache(marker, obj); + + sq_remove(vm_, -2); + + { + // HACK: No way to get the default values part from accessing the class directly + SQUnsignedInteger nvalues = _instance(obj)->_class->_defaultvalues.size(); + for (SQUnsignedInteger n = 0; n < nvalues; n++) { + ReadObject(pBuffer, readState); + HSQOBJECT val; + sq_resetobject(&val); + sq_getstackobj(vm_, -1, &val); + _instance(obj)->_values[n] = val; + sq_pop(vm_, 1); + } + } + + if (typetag == TYPETAG_VECTOR) + { + float x = pBuffer->GetFloat(); + float y = pBuffer->GetFloat(); + float z = pBuffer->GetFloat(); + SQUserPointer p; + sq_getinstanceup(vm_, -1, &p, 0); + new(p) Vector(x, y, z); + } + else if (typetag) + { + ScriptClassDesc_t* pClassDesc = (ScriptClassDesc_t*)typetag; + + char instanceName[128] = ""; + pBuffer->GetString(instanceName, sizeof(instanceName)); + + HSQOBJECT* hinstance = new HSQOBJECT; + sq_resetobject(hinstance); + sq_getstackobj(vm_, -1, hinstance); + sq_addref(vm_, hinstance); + + if (*instanceName) + { + bool allowDestruct = (pBuffer->GetChar() == 1); + + auto instance = pClassDesc->pHelper->BindOnRead((HSCRIPT)hinstance, nullptr, instanceName); + if (instance == nullptr) + { + sq_release(vm_, hinstance); + delete hinstance; + sq_poptop(vm_); + sq_pushnull(vm_); + break; + } + + { + SQUserPointer p; + sq_getinstanceup(vm_, -1, &p, 0); + new(p) ClassInstanceData(instance, pClassDesc, instanceName, allowDestruct); + } + sq_setreleasehook(vm_, -1, allowDestruct ? &destructor_stub : &destructor_stub_instance); + } + else + { + sq_setinstanceup(vm_, -1, nullptr); + } + } + + break; + } + case OT_WEAKREF: + { + ReadObject(pBuffer, readState); + sq_weakref(vm_, -1); + break; + } + case OT_FUNCPROTO: //internal usage only + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + SQObjectPtr ret; + if (!SQFunctionProto::Load(vm_, pBuffer, closure_read, ret)) + { + Error("Failed to deserialize OT_FUNCPROTO\n"); + sq_pushnull(vm_); + break; + } + + vm_->Push(ret); + readState.StoreTopInCache(marker); + } + case OT_OUTER: //internal usage only + { + int marker = 0; + if (readState.CheckCache(pBuffer, vm_, &marker)) + { + break; + } + + SQOuter* outer = SQOuter::Create(_ss(vm_), nullptr); + vm_->Push(outer); + readState.StoreTopInCache(marker); + + ReadObject(pBuffer, readState); + HSQOBJECT inner; + sq_resetobject(&inner); + sq_getstackobj(vm_, -1, &inner); + outer->_value = inner; + outer->_valptr = &(outer->_value); + sq_poptop(vm_); + + break; + } + // case OT_USERDATA: + // case OT_GENERATOR: + // case OT_USERPOINTER: + // case OT_THREAD: + // + default: + Error("SquirrelVM::ReadObject: Unexpected type %d", thisType); + } +} + +void SquirrelVM::ReadState(CUtlBuffer* pBuffer) +{ + SquirrelSafeCheck safeCheck(vm_); + + ReadStateMap readState(vm_); + + sq_pushroottable(vm_); + + HSQOBJECT obj; + int marker = 0; + readState.CheckCache(pBuffer, vm_, &marker); + sq_getstackobj(vm_, -1, &obj); + sq_addref(vm_, &obj); + readState.StoreInCache(marker, obj); + + int count = pBuffer->GetInt(); + + for (int i = 0; i < count; ++i) + { + ReadObject(pBuffer, readState); + ReadObject(pBuffer, readState); + + sq_rawset(vm_, -3); + } + + sq_pop(vm_, 1); +} + +void SquirrelVM::RemoveOrphanInstances() +{ + SquirrelSafeCheck safeCheck(vm_); + // TODO: Is this the right thing to do here? It's not really removing orphan instances + sq_collectgarbage(vm_); +} + +void SquirrelVM::DumpState() +{ + SquirrelSafeCheck safeCheck(vm_); + // TODO: Dump state +} + +void SquirrelVM::SetOutputCallback(ScriptOutputFunc_t pFunc) +{ + SquirrelSafeCheck safeCheck(vm_); + // TODO: Support output callbacks +} + +void SquirrelVM::SetErrorCallback(ScriptErrorFunc_t pFunc) +{ + SquirrelSafeCheck safeCheck(vm_); + // TODO: Support error callbacks +} + +bool SquirrelVM::RaiseException(const char* pszExceptionText) +{ + SquirrelSafeCheck safeCheck(vm_); + sq_pushstring(vm_, pszExceptionText, -1); + sq_resetobject(&lastError_); + sq_getstackobj(vm_, -1, &lastError_); + sq_addref(vm_, &lastError_); + sq_pop(vm_, 1); + return true; +} + + +IScriptVM* makeSquirrelVM() +{ + return new SquirrelVM; +} diff --git a/vscript/vscript_squirrel.nut b/vscript/vscript_squirrel.nut new file mode 100644 index 00000000..5b76bbe3 --- /dev/null +++ b/vscript/vscript_squirrel.nut @@ -0,0 +1,572 @@ +static char g_Script_vscript_squirrel[] = R"vscript( +//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// +// +// Purpose: +// +//=============================================================================// + +Warning <- error; + +function clamp( val, min, max ) +{ + if ( max < min ) + return max; + if ( val < min ) + return min; + if ( val > max ) + return max; + return val; +} + +function max( a, b ) +{ + if ( a > b ) + return a; + return b; +} + +function min( a, b ) +{ + if ( a < b ) + return a; + return b; +} + +function RemapVal( val, A, B, C, D ) +{ + if ( A == B ) + { + if ( val >= B ) + return D; + return C; + }; + return C + (D - C) * (val - A) / (B - A); +} + +function RemapValClamped( val, A, B, C, D ) +{ + if ( A == B ) + { + if ( val >= B ) + return D; + return C; + }; + + local cVal = (val - A) / (B - A); + + if ( cVal <= 0.0 ) + return C; + + if ( cVal >= 1.0 ) + return D; + + return C + (D - C) * cVal; +} + +function Approach( target, value, speed ) +{ + local delta = target - value; + + if ( delta > speed ) + return value + speed; + if ( -speed > delta ) + return value - speed; + return target; +} + +function AngleDistance( next, cur ) +{ + local delta = next - cur + + if ( delta > 180.0 ) + return delta - 360.0; + if ( -180.0 > delta ) + return delta + 360.0; + return delta; +} + +function FLerp( f1, f2, i1, i2, x ) +{ + return f1+(f2-f1)*(x-i1)/(i2-i1); +} + +function Lerp( f, A, B ) +{ + return A + ( B - A ) * f +} + +function SimpleSpline( f ) +{ + local ff = f * f; + return 3.0 * ff - 2.0 * ff * f; +} + +function printl( text ) +{ + return print(text + "\n"); +} + +class CSimpleCallChainer +{ + constructor(prefixString, scopeForThis, exactMatch) + { + prefix = prefixString; + scope = scopeForThis; + chain = []; + scope["Dispatch" + prefixString] <- Call.bindenv(this); + } + + function PostScriptExecute() + { + local func; + try { + func = scope[prefix]; + } catch(e) { + return; + } + if (typeof(func) != "function") + return; + chain.push(func); + } + + function Call() + { + foreach (func in chain) + { + func.pcall(scope); + } + } + + prefix = null; + scope = null; + chain = null; +} + +//--------------------------------------------------------- +// Hook handler +//--------------------------------------------------------- +local s_List = {} + +Hooks <- +{ + // table, string, closure, string + function Add( scope, event, callback, context ) + { + switch ( typeof scope ) + { + case "table": + case "instance": + case "class": + break; + default: + throw "invalid scope param"; + } + + if ( typeof event != "string" ) + throw "invalid event param"; + + if ( typeof callback != "function" ) + throw "invalid callback param"; + + if ( typeof context != "string" ) + throw "invalid context param"; + + if ( !(event in s_List) ) + s_List[event] <- {}; + + local t = s_List[event]; + + if ( !(scope in t) ) + t[scope] <- {}; + + t[scope][context] <- callback; + + return __UpdateHooks(); + } + + function Remove( event, context ) + { + local rem; + + if ( event ) + { + if ( event in s_List ) + { + foreach ( scope, ctx in s_List[event] ) + { + if ( context in ctx ) + { + delete ctx[context]; + } + + if ( !ctx.len() ) + { + if ( !rem ) + rem = []; + rem.append( event ); + rem.append( scope ); + } + } + } + } + else + { + foreach ( ev, t in s_List ) + { + foreach ( scope, ctx in t ) + { + if ( context in ctx ) + { + delete ctx[context]; + } + + if ( !ctx.len() ) + { + if ( !rem ) + rem = []; + rem.append( ev ); + rem.append( scope ); + } + } + } + } + + if ( rem ) + { + local c = rem.len() - 1; + for ( local i = 0; i < c; i += 2 ) + { + local ev = rem[i]; + local scope = rem[i+1]; + + if ( !s_List[ev][scope].len() ) + delete s_List[ev][scope]; + + if ( !s_List[ev].len() ) + delete s_List[ev]; + } + } + + return __UpdateHooks(); + } + + function Call( event, scope, ... ) + { + local firstReturn; + + if ( event in s_List ) + { + vargv.insert( 0, scope ); + + local t = s_List[event]; + if ( scope in t ) + { + foreach ( fn in t[scope] ) + { + //printf( "(%.4f) Calling hook %s:%s\n", Time(), event, context ); + + local r = fn.acall( vargv ); + if ( firstReturn == null ) + firstReturn = r; + } + } + else if ( !scope ) // global hook + { + foreach ( sc, ctx in t ) + { + vargv[0] = sc; + + foreach ( context, fn in ctx ) + { + //printf( "(%.4f) Calling hook (g) %s:%s\n", Time(), event, context ); + + local r = fn.acall( vargv ); + if ( firstReturn == null ) + firstReturn = r; + } + } + } + } + + return firstReturn; + } + + function __UpdateHooks() + { + return __UpdateScriptHooks( s_List ); + } +} + +//--------------------------------------------------------- +// Documentation +//--------------------------------------------------------- +__Documentation <- {} + +local developer = (delete developer)() + +if (developer) +{ + local DocumentedFuncs = {} + local DocumentedClasses = {} + local DocumentedEnums = {} + local DocumentedConsts = {} + local DocumentedHooks = {} + local DocumentedMembers = {} + + local function AddAliasedToTable(name, signature, description, table) + { + // This is an alias function, could use split() if we could guarantee + // that ':' would not occur elsewhere in the description and Squirrel had + // a convience join() function -- It has split() + local colon = description.find(":"); + if (colon == null) + colon = description.len(); + local alias = description.slice(1, colon); + description = description.slice(colon + 1); + name = alias; + signature = null; + + table[name] <- [signature, description]; + } + + function __Documentation::RegisterHelp(name, signature, description) + { + if (description.len() && description[0] == '#') + { + AddAliasedToTable(name, signature, description, DocumentedFuncs) + } + else + { + DocumentedFuncs[name] <- [signature, description]; + } + } + + function __Documentation::RegisterClassHelp(name, baseclass, description) + { + DocumentedClasses[name] <- [baseclass, description]; + } + + function __Documentation::RegisterEnumHelp(name, num_elements, description) + { + DocumentedEnums[name] <- [num_elements, description]; + } + + function __Documentation::RegisterConstHelp(name, signature, description) + { + if (description.len() && description[0] == '#') + { + AddAliasedToTable(name, signature, description, DocumentedConsts) + } + else + { + DocumentedConsts[name] <- [signature, description]; + } + } + + function __Documentation::RegisterHookHelp(name, signature, description) + { + DocumentedHooks[name] <- [signature, description]; + } + + function __Documentation::RegisterMemberHelp(name, signature, description) + { + DocumentedMembers[name] <- [signature, description]; + } + + local function printdoc( text ) + { + return ::printc(200,224,255,text); + } + + local function printdocl( text ) + { + return printdoc(text + "\n"); + } + + local function PrintClass(name, doc) + { + local text = "=====================================\n"; + text += ("Class: " + name + "\n"); + text += ("Base: " + doc[0] + "\n"); + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + text += "=====================================\n\n"; + + printdoc(text); + } + + local function PrintFunc(name, doc) + { + local text = "Function: " + name + "\n" + + if (doc[0] == null) + { + // Is an aliased function + text += ("Signature: function " + name + "("); + foreach(k,v in this[name].getinfos().parameters) + { + if (k == 0 && v == "this") continue; + if (k > 1) text += (", "); + text += (v); + } + text += (")\n"); + } + else + { + text += ("Signature: " + doc[0] + "\n"); + } + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + printdocl(text); + } + + local function PrintMember(name, doc) + { + local text = ("Member: " + name + "\n"); + text += ("Signature: " + doc[0] + "\n"); + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + printdocl(text); + } + + local function PrintEnum(name, doc) + { + local text = "=====================================\n"; + text += ("Enum: " + name + "\n"); + text += ("Elements: " + doc[0] + "\n"); + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + text += "=====================================\n\n"; + + printdoc(text); + } + + local function PrintConst(name, doc) + { + local text = ("Constant: " + name + "\n"); + if (doc[0] == null) + { + text += ("Value: null\n"); + } + else + { + text += ("Value: " + doc[0] + "\n"); + } + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + printdocl(text); + } + + local function PrintHook(name, doc) + { + local text = ("Hook: " + name + "\n"); + if (doc[0] == null) + { + // Is an aliased function + text += ("Signature: function " + name + "("); + foreach(k,v in this[name].getinfos().parameters) + { + if (k == 0 && v == "this") continue; + if (k > 1) text += (", "); + text += (v); + } + text += (")\n"); + } + else + { + text += ("Signature: " + doc[0] + "\n"); + } + if (doc[1].len()) + text += ("Description: " + doc[1] + "\n"); + printdocl(text); + } + + local function PrintMatches( pattern, docs, printfunc ) + { + local matches = []; + local always = pattern == "*"; + + foreach( name, doc in docs ) + { + if (always || name.tolower().find(pattern) != null || (doc[1].len() && doc[1].tolower().find(pattern) != null)) + { + matches.append( name ); + } + } + + if ( !matches.len() ) + return 0; + + matches.sort(); + + foreach( name in matches ) + printfunc( name, docs[name] ); + + return 1; + } + + function __Documentation::PrintHelp(pattern = "*") + { + local patternLower = pattern.tolower(); + + // Have a specific order + if (!( + PrintMatches( patternLower, DocumentedEnums, PrintEnum ) | + PrintMatches( patternLower, DocumentedConsts, PrintConst ) | + PrintMatches( patternLower, DocumentedClasses, PrintClass ) | + PrintMatches( patternLower, DocumentedFuncs, PrintFunc ) | + PrintMatches( patternLower, DocumentedMembers, PrintMember ) | + PrintMatches( patternLower, DocumentedHooks, PrintHook ) + )) + { + printdocl("Pattern " + pattern + " not found"); + } + } +} +else +{ + __Documentation.RegisterHelp <- + __Documentation.RegisterClassHelp <- + __Documentation.RegisterEnumHelp <- + __Documentation.RegisterConstHelp <- + __Documentation.RegisterHookHelp <- + __Documentation.RegisterMemberHelp <- dummy + + function __Documentation::PrintHelp( pattern = null ) + { + printcl(200, 224, 255, "Documentation is not enabled. To enable documentation, restart the server with the 'developer' cvar set to 1 or higher."); + } +} + +if (developer) +{ + __Documentation.RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." ); + __Documentation.RegisterHelp( "Vector::Length", "float Vector::Length()", "Return the vector's length." ); + __Documentation.RegisterHelp( "Vector::LengthSqr", "float Vector::LengthSqr()", "Return the vector's squared length." ); + __Documentation.RegisterHelp( "Vector::Length2D", "float Vector::Length2D()", "Return the vector's 2D length." ); + __Documentation.RegisterHelp( "Vector::Length2DSqr", "float Vector::Length2DSqr()", "Return the vector's squared 2D length." ); + + __Documentation.RegisterHelp( "Vector::Normalized", "float Vector::Normalized()", "Return a normalized version of the vector." ); + __Documentation.RegisterHelp( "Vector::Norm", "void Vector::Norm()", "Normalize the vector in place." ); + __Documentation.RegisterHelp( "Vector::Scale", "vector Vector::Scale(float)", "Scale the vector's magnitude and return the result." ); + __Documentation.RegisterHelp( "Vector::Dot", "float Vector::Dot(vector)", "Return the dot/scalar product of two vectors." ); + __Documentation.RegisterHelp( "Vector::Cross", "float Vector::Cross(vector)", "Return the vector product of two vectors." ); + + __Documentation.RegisterHelp( "Vector::ToKVString", "string Vector::ToKVString()", "Return a vector as a string in KeyValue form, without separation commas." ); + + __Documentation.RegisterMemberHelp( "Vector.x", "float Vector.x", "The vector's X coordinate on the cartesian X axis." ); + __Documentation.RegisterMemberHelp( "Vector.y", "float Vector.y", "The vector's Y coordinate on the cartesian Y axis." ); + __Documentation.RegisterMemberHelp( "Vector.z", "float Vector.z", "The vector's Z coordinate on the cartesian Z axis." ); + + __Documentation.RegisterHelp( "clamp", "float clamp(float, float, float)", "" ); + __Documentation.RegisterHelp( "max", "float max(float, float)", "" ); + __Documentation.RegisterHelp( "min", "float min(float, float)", "" ); + __Documentation.RegisterHelp( "RemapVal", "float RemapVal(float, float, float, float, float)", "" ); + __Documentation.RegisterHelp( "RemapValClamped", "float RemapValClamped(float, float, float, float, float)", "" ); + __Documentation.RegisterHelp( "Approach", "float Approach(float, float, float)", "" ); + __Documentation.RegisterHelp( "AngleDistance", "float AngleDistance(float, float)", "" ); + __Documentation.RegisterHelp( "FLerp", "float FLerp(float, float, float, float, float)", "" ); + __Documentation.RegisterHelp( "Lerp", "float Lerp(float, float, float)", "" ); + __Documentation.RegisterHelp( "SimpleSpline", "float SimpleSpline(float)", "" ); +} +)vscript"; \ No newline at end of file diff --git a/vstdlib/vstdlib_exclude.vpc b/vstdlib/vstdlib_exclude.vpc deleted file mode 100644 index 55e673c2..00000000 --- a/vstdlib/vstdlib_exclude.vpc +++ /dev/null @@ -1,18 +0,0 @@ -//----------------------------------------------------------------------------- -// vstdlib_exclude.vpc -// -// Project Script -//----------------------------------------------------------------------------- - -$MacroRequired "PLATSUBDIR" - -$Project -{ - $Folder "Link Libraries" - { - -$Implib vstdlib [$POSIX] - -$File "$SRCDIR\lib\public\$_IMPLIB_PREFIXvstdlib$_IMPLIB_EXT" [$WIN32] - -$File "$SRCDIR\lib\public$PLATSUBDIR\$_IMPLIB_PREFIXvstdlib$_IMPLIB_EXT" [$WIN64] - -$File "$SRCDIR\lib\public\vstdlib_360.lib" [$X360] - } -}